summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/disk.c118
-rw-r--r--src/flier.c1
-rw-r--r--src/main.c48
-rw-r--r--src/main.h1
-rw-r--r--src/save.c137
-rw-r--r--src/save.h4
-rw-r--r--src/util.h1
7 files changed, 182 insertions, 128 deletions
diff --git a/src/disk.c b/src/disk.c
new file mode 100644
index 0000000..a6e3d80
--- /dev/null
+++ b/src/disk.c
@@ -0,0 +1,118 @@
+#include "main.h"
+#include "entity.h"
+#include "loader.h"
+#include "tilemap.h"
+#include "input.h"
+#include "util.h"
+#include "save.h"
+#include <string.h>
+#include <stdio.h>
+
+enum {
+	SAVE_A_IDLE,
+	SAVE_A_SPIN,
+	SAVE_A_SPIN2,
+	SAVE_A_SPIN3,
+	SAVE_A_SHAKE,
+	SAVE_A_SHAKE2,
+	SAVE_A_SHAKE3,
+};
+
+struct anim save_anims[] = {
+	{SAVE_A_IDLE, {0, 0, 16, 16}, 300},
+	{SAVE_A_SPIN2, {16, 0, 16, 16}, 5},
+	{SAVE_A_SPIN3, {32, 0, 16, 16}, 5},
+	{SAVE_A_IDLE, {16, 0, 16, 16}, 5},
+	{SAVE_A_SHAKE2, {1, 0, 16, 16}, 5},
+	{SAVE_A_SHAKE3, {-1, 0, 16, 16}, 5},
+	{SAVE_A_IDLE, {1, 0, 16, 16}, 5},
+};
+
+static void save_free(struct entity *self) {
+	self->state = 0;
+	free(self->ext), self->ext = NULL;
+}
+
+static int save_update(struct entity *self) {
+	if (self->timer > 0) {
+		self->timer--;
+	}
+	if (
+		self->hitbox.left < entities.player[0].hitbox.right &&
+		self->hitbox.right > entities.player[0].hitbox.left &&
+		self->hitbox.top < entities.player[0].hitbox.bottom &&
+		self->hitbox.bottom > entities.player[0].hitbox.top &&
+		input_s(input_pressed) && self->timer == 0
+	) {
+		self->timer = 20;
+		self->anim = save_anims[SAVE_A_SHAKE];
+		FILE *file = fopen(save_file_name, "wb");
+		if (file == NULL) {
+			perror(save_file_name);
+			goto no_save;
+		}
+		if (game_save(file)) {
+			goto no_save;
+		}
+		self->anim = save_anims[SAVE_A_SPIN];
+	}
+	no_save:
+	self->anim.length--;
+	if (self->anim.length == 0) {
+		self->anim = save_anims[self->anim.frame];
+	}
+	return 0;
+}
+
+static int save_hurt(struct entity *self, int damage) {
+	return 0;
+}
+
+static int save_draw(struct entity *self, int camX, int camY) {
+	SDL_Rect rect = self->anim.rect;
+	SDL_RenderCopy(renderer, self->texture, &rect, &(SDL_Rect) {from_fixed(self->x) - camX - 8, from_fixed(self->y) - camY - 16, 16, 16});
+	if (self->ext != NULL) {
+		rect.y += 16;
+		struct color const *const color = self->ext;
+		SDL_SetTextureColorMod(self->texture, color->r, color->g, color->b);
+		SDL_RenderCopy(renderer, self->texture, &rect, &(SDL_Rect) {from_fixed(self->x) - camX - 8, from_fixed(self->y) - camY - 16, 16, 16});
+		SDL_SetTextureColorMod(self->texture, 255, 255, 255);
+	}
+	return 0;
+}
+
+struct entity *save_new(struct entities *entities) {
+	struct entity *self = entities->enemy + entities->enemies;
+	*self = (struct entity) {
+		.update = save_update,
+		.hurt = save_hurt,
+		.draw = save_draw,
+		.free = save_free,
+		.x = 0, .y = 0,
+		.state = 1,
+		.timer = 0,
+		.ext = NULL,
+	};
+	self->anim = save_anims[SAVE_A_SPIN];
+	self->texture = res_get_texture("save").data;
+	entities->enemies++;
+	return self;
+}
+
+int save_property(struct entity *const restrict self, char const *const restrict property, char const *const restrict value) {
+	if (strcmp(property, "x") == 0) {
+		self->x = to_fixed(atoi(value));
+	} else if (strcmp(property, "y") == 0) {
+		self->y = to_fixed(atoi(value));
+	} else if (strcmp(property, "color") == 0) {
+		free(self->ext);
+		self->ext = malloc(sizeof (struct color));
+		if (util_stringToColor(self->ext, value)) {
+			return 1;
+		}
+	} else {
+		return 1;
+	}
+	self->hitbox = (struct hitbox) {.left = from_fixed(self->x) - 8, .top = from_fixed(self->y) - 16, .right = from_fixed(self->x) + 8, .bottom = from_fixed(self->y)};
+	return 0;
+}
diff --git a/src/flier.c b/src/flier.c
index f51a8a1..f5d33e4 100644
--- a/src/flier.c
+++ b/src/flier.c
@@ -4,6 +4,7 @@
 #include "tilemap.h"
 #include <stdbool.h>
 #include <math.h>
+#include <string.h>
 
 #define SIZE 4
 #define ACCELERATION 1
diff --git a/src/main.c b/src/main.c
index 7afd152..9c40876 100644
--- a/src/main.c
+++ b/src/main.c
@@ -10,6 +10,7 @@
 #include "input.h"
 #include "loader.h"
 #include "util.h"
+#include "save.h"
 
 #include "tilemap.h"
 
@@ -222,6 +223,8 @@ void game_render(SDL_Texture *framebuffer, int x, int y) {
 	}
 }
 
+int fade = 255;
+
 int game_load_level(char *level) {
 	struct blob blob = res_get_map(level);
 	next_tilemap = tilemap_load(blob.data, blob.size);
@@ -236,6 +239,7 @@ int game_load_level(char *level) {
 			memcpy(&entities, &next_entities, sizeof (entities));
 
 			game_state = STATE_FADE_OUT;
+			fade = 255;
 			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;}
@@ -417,31 +421,7 @@ int main(int const argc, char *const *const argv) {
 			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);
+			game_load(file);
 		}
 		#if 0
 		struct blob blob = res_get_map("untitled");
@@ -490,11 +470,11 @@ int main(int const argc, char *const *const argv) {
 	return 0;
 }
 
-int x = 0, y = 0, fade = 255;
+int x = 0, y = 0;
 
 void main_loop(void) {
 #else
-	int x = 0, y = 0, fade = 255;
+	int x = 0, y = 0;
 	while (1) {
 #endif
 		input_pressed = input_held;
@@ -649,7 +629,19 @@ void main_loop(void) {
 			case STATE_PLAYING:
 				//SDL_RenderCopy(renderer, tilemap->wang_tileset, &(SDL_Rect) {0, 0, 128, 90}, &(SDL_Rect) {0, 0, 128, 90});
 				if (game_update()) {
-					goto end; // TODO: game over state
+					//goto end; // TODO: game over state
+					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 {
+						game_load(file);
+					}
 				}
 				
 				x = (entities.player[0].x / 16) - (WINDOW_WIDTH / 2);
diff --git a/src/main.h b/src/main.h
index 88e1c13..ecd8250 100644
--- a/src/main.h
+++ b/src/main.h
@@ -30,3 +30,4 @@ extern char *save_file_name;
 
 void entities_free(struct entities *entities);
 int entities_load(struct entities *entities, char *data, size_t size, size_t input_bytes);
+int game_load_level(char *level);
diff --git a/src/save.c b/src/save.c
index 577ec61..0264dfa 100644
--- a/src/save.c
+++ b/src/save.c
@@ -1,110 +1,47 @@
+#include <stdio.h>
+#include <stdlib.h>
 #include "main.h"
-#include "entity.h"
-#include "loader.h"
-#include "tilemap.h"
-#include "input.h"
 #include "util.h"
-#include <string.h>
-#include <stdio.h>
-
-enum {
-	SAVE_A_IDLE,
-	SAVE_A_SPIN,
-	SAVE_A_SPIN2,
-	SAVE_A_SPIN3,
-};
-
-struct anim save_anims[] = {
-	{SAVE_A_IDLE, {0, 0, 16, 16}, 300},
-	{SAVE_A_SPIN2, {16, 0, 16, 16}, 5},
-	{SAVE_A_SPIN3, {32, 0, 16, 16}, 5},
-	{SAVE_A_IDLE, {16, 0, 16, 16}, 5},
-};
-
-static void save_free(struct entity *self) {
-	self->state = 0;
-	free(self->ext), self->ext = NULL;
-}
-
-static int save_update(struct entity *self) {
-	if (self->timer > 0) {
-		self->timer--;
-	}
-	if (
-		self->hitbox.left < entities.player[0].hitbox.right &&
-		self->hitbox.right > entities.player[0].hitbox.left &&
-		self->hitbox.top < entities.player[0].hitbox.bottom &&
-		self->hitbox.bottom > entities.player[0].hitbox.top &&
-		input_s(input_pressed) && self->timer == 0
-	) {
-		printf("%s %u %u\n", game_level, from_fixed(entities.player[0].x), from_fixed(entities.player[0].y));
-		self->timer = 20;
-		self->anim = save_anims[SAVE_A_SPIN];
-		FILE *file = fopen(save_file_name, "wb");
-		fwrite(game_level, 1, strlen(game_level) + 1, file);
-		char buf[12] = {0};
-		snprintf(buf, sizeof (buf) - 1, "%i", from_fixed(entities.player[0].x));
-		fwrite(buf, 1, strlen(buf) + 1, file);
-		snprintf(buf, sizeof (buf) - 1, "%i", from_fixed(entities.player[0].y));
-		fwrite(buf, 1, strlen(buf) + 1, file);
-		fclose(file);
-	}
-	self->anim.length--;
-	if (self->anim.length == 0) {
-		self->anim = save_anims[self->anim.frame];
-	}
-	return 0;
-}
+#include "util.h"
 
-static int save_hurt(struct entity *self, int damage) {
+void *player_new(struct entities *entities);
+int player_property(void *const restrict entity, char const *const restrict property, char const *const restrict value);
+
+int game_save(FILE *file) {
+	fwrite(game_level, 1, strlen(game_level) + 1, file);
+	char buf[12] = {0};
+	snprintf(buf, sizeof (buf) - 1, "%i", from_fixed(entities.player[0].x));
+	fwrite(buf, 1, strlen(buf) + 1, file);
+	snprintf(buf, sizeof (buf) - 1, "%i", from_fixed(entities.player[0].y));
+	fwrite(buf, 1, strlen(buf) + 1, file);
+	fclose(file);
 	return 0;
 }
 
-static int save_draw(struct entity *self, int camX, int camY) {
-	SDL_Rect rect = self->anim.rect;
-	SDL_RenderCopy(renderer, self->texture, &rect, &(SDL_Rect) {from_fixed(self->x) - camX - 8, from_fixed(self->y) - camY - 16, 16, 16});
-	if (self->ext != NULL) {
-		rect.y += 16;
-		struct color const *const color = self->ext;
-		SDL_SetTextureColorMod(self->texture, color->r, color->g, color->b);
-		SDL_RenderCopy(renderer, self->texture, &rect, &(SDL_Rect) {from_fixed(self->x) - camX - 8, from_fixed(self->y) - camY - 16, 16, 16});
-		SDL_SetTextureColorMod(self->texture, 255, 255, 255);
+int game_load(FILE *file) {
+	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);
+		return 1;
 	}
-	return 0;
-}
-
-struct entity *save_new(struct entities *entities) {
-	struct entity *self = entities->enemy + entities->enemies;
-	*self = (struct entity) {
-		.update = save_update,
-		.hurt = save_hurt,
-		.draw = save_draw,
-		.free = save_free,
-		.x = 0, .y = 0,
-		.state = 1,
-		.timer = 0,
-		.ext = NULL,
-	};
-	self->anim = save_anims[SAVE_A_SPIN];
-	self->texture = res_get_texture("save").data;
-	entities->enemies++;
-	return self;
-}
-
-int save_property(struct entity *const restrict self, char const *const restrict property, char const *const restrict value) {
-	if (strcmp(property, "x") == 0) {
-		self->x = to_fixed(atoi(value));
-	} else if (strcmp(property, "y") == 0) {
-		self->y = to_fixed(atoi(value));
-	} else if (strcmp(property, "color") == 0) {
-		free(self->ext);
-		self->ext = malloc(sizeof (struct color));
-		if (util_stringToColor(self->ext, value)) {
-			return 1;
-		}
-	} else {
+	filedata += len + 1;
+	len = strnlen(filedata, filesize);
+	if (len == filesize) {
+		fputs("invalid save format\n", stderr);
 		return 1;
 	}
-	self->hitbox = (struct hitbox) {.left = from_fixed(self->x) - 8, .top = from_fixed(self->y) - 16, .right = from_fixed(self->x) + 8, .bottom = from_fixed(self->y)};
-	return 0;
+	player_property(next_entities.player, "x", filedata);
+	filedata += len + 1;
+	len = strnlen(filedata, filesize);
+	if (len == filesize) {
+		fputs("invalid save format\n", stderr);
+		return 1;
+	}
+	player_property(next_entities.player, "y", filedata);
+	level = realloc(level, strlen(level) + 1);
+	return game_load_level(level);
 }
diff --git a/src/save.h b/src/save.h
new file mode 100644
index 0000000..c4e9cf8
--- /dev/null
+++ b/src/save.h
@@ -0,0 +1,4 @@
+// save state to disk
+int game_save(FILE *file);
+// load state from disk
+int game_load(FILE *file);
diff --git a/src/util.h b/src/util.h
index 3aafc66..bb8e147 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,4 +1,5 @@
 #pragma once
+#include <stdio.h>
 
 struct color {
 	unsigned char r, g, b, a;