summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c148
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;