diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 148 |
1 files changed, 110 insertions, 38 deletions
diff --git a/src/main.c b/src/main.c index 345f6fb..7afd152 100644 --- a/src/main.c +++ b/src/main.c @@ -4,6 +4,8 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <inttypes.h> +#include <errno.h> #include "input.h" #include "loader.h" @@ -21,7 +23,8 @@ SDL_Window *window = NULL; SDL_Renderer *renderer = NULL; enum game_state game_state = STATE_PLAYING; -char *game_next_level; +char *game_level, *game_next_level; +char *save_file_name; static void *particle_tex = NULL; @@ -192,12 +195,9 @@ int game_update(void) { void game_render(SDL_Texture *framebuffer, int x, int y) { SDL_SetRenderTarget(renderer, framebuffer); tilemap_background(tilemap, x, y, WINDOW_WIDTH, WINDOW_HEIGHT); - entities.player[0].draw(entities.player, x, y); - for (int i = 0, e = 0; i < 64 && e < entities.enemies; i++) { - if (entities.enemy[i].state) { - e++; - entities.enemy[i].draw(entities.enemy + i, x, y); - } + for (int i = 0; i < entities.particles; i++) { + struct particle *self = entities.particle + i; + SDL_RenderCopy(renderer, particle_tex, &self->rect, &(SDL_Rect) {from_fixed(self->x) - x, from_fixed(self->y) - y, self->rect.w, self->rect.h}); } for (int i = 0, e = 0; i < 64 && e < entities.projectiles; i++) { if (entities.projectile[i].state) { @@ -205,11 +205,50 @@ void game_render(SDL_Texture *framebuffer, int x, int y) { entities.projectile[i].draw(entities.projectile + i, x, y); } } - for (int i = 0; i < entities.particles; i++) { - struct particle *self = entities.particle + i; - SDL_RenderCopy(renderer, particle_tex, &self->rect, &(SDL_Rect) {from_fixed(self->x) - x, from_fixed(self->y) - y, self->rect.w, self->rect.h}); + for (int i = 0, e = 0; i < 64 && e < entities.enemies; i++) { + if (entities.enemy[i].state) { + e++; + entities.enemy[i].draw(entities.enemy + i, x, y); + } } + entities.player[0].draw(entities.player, x, y); tilemap_foreground(tilemap, x, y, WINDOW_WIDTH, WINDOW_HEIGHT); + // hacky hp render + if (entities.player[0].hp) { + SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); + for (int i = 0; i < entities.player[0].hp; i++) { + SDL_RenderFillRect(renderer, &(SDL_Rect) {1, 1 + i * 5, 4, 4}); + } + } +} + +int game_load_level(char *level) { + struct blob blob = res_get_map(level); + next_tilemap = tilemap_load(blob.data, blob.size); + if (next_tilemap != NULL) { + if (entities_load(&next_entities, blob.data, blob.size, next_tilemap->input_bytes)) { + tilemap_free(next_tilemap); + } else { + tilemap_free(tilemap); + tilemap = next_tilemap; + game_level = level; + entities_free(&entities); + memcpy(&entities, &next_entities, sizeof (entities)); + + game_state = STATE_FADE_OUT; + int x = (entities.player[0].x / 16) - (WINDOW_WIDTH / 2); + int y = (entities.player[0].y / 16) - (WINDOW_HEIGHT / 2); + if (x < 0) {x = 0;} else if (x + WINDOW_WIDTH > tilemap->width * 8) {x = tilemap->width * 8 - WINDOW_WIDTH;} + if (y < 0) {y = 0;} else if (y + WINDOW_HEIGHT > tilemap->height * 8) {y = tilemap->height * 8 - WINDOW_HEIGHT;} + + game_render(framebuffer, x, y); + SDL_SetRenderTarget(renderer, NULL); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); + SDL_RenderClear(renderer); + return 0; + } + } + return 1; } void game_render_flush(SDL_Texture *framebuffer) { @@ -222,6 +261,9 @@ void game_render_flush(SDL_Texture *framebuffer) { } int main(int const argc, char *const *const argv) { + save_file_name = SDL_GetPrefPath("sylvie", "game"); + save_file_name = SDL_realloc(save_file_name, strlen(save_file_name) + strlen("save.sav") + 1); + strcat(save_file_name, "save.sav"); struct option opts[] = { {"help", 0, NULL, 'h'}, {"scale", 1, NULL, 's'}, @@ -364,6 +406,44 @@ int main(int const argc, char *const *const argv) { particle_tex = res_get_texture("particles").data; + player_new(&next_entities); + FILE *file = fopen(save_file_name, "rb"); + if (file == NULL) { + if (errno != ENOENT) { + perror(save_file_name); + goto end; + } + player_property(next_entities.player, "x", "40"); + player_property(next_entities.player, "y", "64"); + game_load_level("untitled"); + } else { + size_t filesize, len; + char *filedata = util_loadFile(file, &filesize); // hack: we leak a tiny bit of memory here + fclose(file); + char *level = filedata; + len = strnlen(filedata, filesize); + if (len == filesize) { + fputs("invalid save format\n", stderr); + goto end; + } + filedata += len + 1; + len = strnlen(filedata, filesize); + if (len == filesize) { + fputs("invalid save format\n", stderr); + goto end; + } + player_property(next_entities.player, "x", filedata); + filedata += len + 1; + len = strnlen(filedata, filesize); + if (len == filesize) { + fputs("invalid save format\n", stderr); + goto end; + } + player_property(next_entities.player, "y", filedata); + level = realloc(level, strlen(level) + 1); + game_load_level(level); + } + #if 0 struct blob blob = res_get_map("untitled"); next_tilemap = tilemap_load(blob.data, blob.size); if (next_tilemap == NULL) { @@ -376,6 +456,7 @@ int main(int const argc, char *const *const argv) { goto end; } tilemap = next_tilemap; + #endif } /* unsigned error; // identical variable is declared higher up */ @@ -397,10 +478,6 @@ int main(int const argc, char *const *const argv) { SDL_ShowWindow(window); - player_new(&next_entities); - player_property(next_entities.player, "x", "40"); - player_property(next_entities.player, "y", "64"); - memcpy(&entities, &next_entities, sizeof (entities)); #if defined(__EMSCRIPTEN__) emscripten_set_main_loop(main_loop, 60, 0); // TODO: how do i query the framerate if i set it to 0? return 0; @@ -413,11 +490,11 @@ int main(int const argc, char *const *const argv) { return 0; } -int x = 0, y = 0, fade = 0; +int x = 0, y = 0, fade = 255; void main_loop(void) { #else - int x = 0, y = 0, fade = 0; + int x = 0, y = 0, fade = 255; while (1) { #endif input_pressed = input_held; @@ -432,10 +509,12 @@ void main_loop(void) { if (evt.key.repeat) break; + #if !defined(__EMSCRIPTEN__) // check for ^Q and exit if pressed if (evt.key.state == SDL_PRESSED && evt.key.keysym.sym == SDLK_q && evt.key.keysym.mod & KMOD_CTRL) { goto end; } + #endif //static_assert(INPUT_LENGTH <= sizeof(input_held) * CHAR_BIT); // if this trips up, scope creep happened for (unsigned key = 0, bit = 1; key < INPUT_LENGTH; key++, bit <<= 1) { @@ -473,8 +552,12 @@ void main_loop(void) { case SDL_FINGERDOWN: i = evt.tfinger.fingerId; if (i >= touch.allocated) { + size_t const start = touch.allocated; touch.allocated = i + 1; touch.positions = realloc(touch.positions, sizeof (struct touch_vec) * touch.allocated); + for (size_t index = start; index < i - 1; index++) { + touch.positions[index].active = 0; + } } touch.positions[i].active = 1; case SDL_FINGERMOTION: @@ -588,29 +671,18 @@ void main_loop(void) { SDL_RenderFillRect(renderer, &(SDL_Rect) {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT}); SDL_RenderPresent(renderer); if (fade == 255) { - struct blob blob = res_get_map(game_next_level); - next_tilemap = tilemap_load(blob.data, blob.size); - if (next_tilemap != NULL) { - if (entities_load(&next_entities, blob.data, blob.size, next_tilemap->input_bytes)) { - tilemap_free(next_tilemap); - } else { - tilemap_free(tilemap); - tilemap = next_tilemap; - entities_free(&entities); - memcpy(&entities, &next_entities, sizeof (entities)); - } + if (game_load_level(game_next_level)) { + game_state = STATE_FADE_OUT; + x = (entities.player[0].x / 16) - (WINDOW_WIDTH / 2); + y = (entities.player[0].y / 16) - (WINDOW_HEIGHT / 2); + if (x < 0) {x = 0;} else if (x + WINDOW_WIDTH > tilemap->width * 8) {x = tilemap->width * 8 - WINDOW_WIDTH;} + if (y < 0) {y = 0;} else if (y + WINDOW_HEIGHT > tilemap->height * 8) {y = tilemap->height * 8 - WINDOW_HEIGHT;} + + game_render(framebuffer, x, y); + SDL_SetRenderTarget(renderer, NULL); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); + SDL_RenderClear(renderer); } - game_state = STATE_FADE_OUT; - - x = (entities.player[0].x / 16) - (WINDOW_WIDTH / 2); - y = (entities.player[0].y / 16) - (WINDOW_HEIGHT / 2); - if (x < 0) {x = 0;} else if (x + WINDOW_WIDTH > tilemap->width * 8) {x = tilemap->width * 8 - WINDOW_WIDTH;} - if (y < 0) {y = 0;} else if (y + WINDOW_HEIGHT > tilemap->height * 8) {y = tilemap->height * 8 - WINDOW_HEIGHT;} - - game_render(framebuffer, x, y); - SDL_SetRenderTarget(renderer, NULL); - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); - SDL_RenderClear(renderer); } break; |