A game engine for top-down 2D RPG games.
rpg game-engine raylib c99

Finally finish actor (de)serialization!

Changed files
+63 -44
include
src
+1
include/keraforge.h
··· 18 18 #include <keraforge/player.h> 19 19 #include <keraforge/sprites.h> 20 20 #include <keraforge/state.h> 21 + #include <keraforge/string.h> 21 22 #include <keraforge/time.h> 22 23 #include <keraforge/ui.h> 23 24 #include <keraforge/world.h>
+1 -3
include/keraforge/actor.h
··· 38 38 /* Represents any kinematic body in the world (players, NPCs, etc). */ 39 39 struct kf_actor 40 40 { 41 - /* Unique string identifier for this actor. */ 42 - char *key; 43 - /* Unique integer identifier for this actor, comes from kf_actorregistry. */ 41 + /* Integer identifier for this actor, comes from kf_actorregistry. */ 44 42 int id; 45 43 /* The actor's position. */ 46 44 struct kf_vec2(f32) pos;
+1 -7
include/keraforge/state.h
··· 8 8 #define KF_NPCPOOL_SIZE 1024 9 9 10 10 11 - /* Stores global variables to be saved alongside the world. Use this for save data. 12 - Do not use pointers here! This gets transmuted into a u8 array for serialization. */ 11 + /* Stores global variables to be saved alongside the world. Use this for save data. */ 13 12 struct kf_state 14 13 { 15 14 /* Do not modify this and do not relocate it. See kf_world for an explanation. */ 16 15 u16 revision; 17 - /* Player data */ 18 - struct { 19 - struct kf_vec2(f32) pos; 20 - } player; 21 - // struct kf_actor npc[KF_NPCPOOL_SIZE]; 22 16 }; 23 17 24 18
+11
include/keraforge/string.h
··· 1 + #ifndef __kf_string__ 2 + #define __kf_string__ 3 + 4 + 5 + #include <keraforge/_header.h> 6 + 7 + 8 + char *kf_strdup(char *str); 9 + 10 + 11 + #endif
+23 -17
src/actor.c
··· 28 28 } 29 29 30 30 actor->id = kf_actor_getregistryid(key); 31 - actor->key = key; 32 31 actor->size.x = 10; 33 32 actor->size.y = 10; 34 33 actor->collide = true; ··· 206 205 207 206 int kf_saveactors(void) 208 207 { 209 - size_t nactors = 0; 210 - 211 208 struct bini_stream *bs = bini_new(); 212 209 213 210 /* kf_actor_count includes unserialized actors, so we have to manually count. */ 211 + size_t nactors = 0; 214 212 for (struct kf_actor *actor = kf_actors ; actor != NULL ; actor = actor->next) 215 213 { 216 - if (!actor->key) 217 - continue; 218 - int id = kf_actor_getregistryid(actor->key); 219 - if (id == -1) 214 + if (actor->id == -1) 220 215 continue; 221 216 nactors++; 222 217 } 223 218 bini_wlu(bs, nactors); 219 + kf_logdbg("expecting to save %lu actors", nactors); 224 220 225 221 for (struct kf_actor *actor = kf_actors ; actor != NULL ; actor = actor->next) 226 222 { 227 - if (!actor->key) 228 - continue; 229 - int id = kf_actor_getregistryid(actor->key); 230 - if (id == -1) 223 + if (actor->id == -1) 231 224 continue; 232 - bini_wstr(bs, actor->key); 233 - kf_actorregistry.serialize[id](actor, bs); 225 + bini_wstr(bs, kf_actorregistry.key[actor->id]); 226 + kf_actorregistry.serialize[actor->id](actor, bs); 234 227 } 235 228 236 229 kf_logdbg("serialized %d actors (%lu bytes)", nactors, bs->len); ··· 248 241 // char *infile = compress ? _KF_ACTORFILE_TMP : _KF_ACTORFILE; 249 242 char *infile = _KF_ACTORFILE; 250 243 244 + if (!kf_exists(infile)) 245 + { 246 + kf_logdbg("actors.bin nonexistent, creating..."); 247 + kf_saveactors(); 248 + return 1; 249 + } 250 + 251 251 size_t len = 0; 252 252 struct bini_stream bs = { 253 253 .mode = BINI_STREAM, ··· 260 260 kf_logdbg("loaded actors into binary stream: len=%lu", len); 261 261 262 262 const size_t nactors = bini_rlu(&bs); 263 + kf_logdbg("expecting to load %lu actors", nactors); 263 264 264 265 for (size_t i = 0 ; i < nactors ; i++) 265 266 { 266 - char key[4096] = {0}; 267 - bini_rstr(&bs, key); 268 - int id = kf_actor_getregistryid(key); 267 + kf_logdbg("loading actor #%lu", i); 268 + char key[4096]; 269 + size_t n = bini_rstr(&bs, key); 270 + key[n] = '\0'; 271 + char *keycpy = kf_strdup(key); 272 + kf_logdbg(" key: %s", keycpy); 273 + int id = kf_actor_getregistryid(keycpy); 274 + kf_logdbg(" id: %d", id); 269 275 if (id == -1) 270 276 continue; 271 - struct kf_actor *actor = kf_actor_new(key); 277 + struct kf_actor *actor = kf_actor_new(keycpy); 272 278 kf_actorregistry.deserialize[id](actor, &bs); 273 279 } 274 280
+12 -17
src/graphics.c
··· 44 44 45 45 struct kf_state *state = NULL; 46 46 int is_new_state = kf_state_load(&state); 47 + (void)is_new_state; 47 48 kf_window.state = state; 48 49 49 50 struct kf_world *world = NULL; ··· 64 65 kf_actorregistry.tick[idplayer2] = kf_player_tick; 65 66 kf_actorregistry.draw[idplayer2] = kf_player_draw; 66 67 67 - if (is_new_state) 68 + if (!kf_exists("data/actors.bin")) 68 69 { 69 - struct kf_actor *player = kf_actors; /* player should always be the first actor. */ 70 + struct kf_actor *player = kf_actor_new("player"); 71 + player->controlled = true; 72 + player->pos.x = world->width * KF_TILE_SIZE_PX / 2.0f; 73 + player->pos.y = world->width * KF_TILE_SIZE_PX / 2.0f; 70 74 71 - state->player.pos.x = world->width * KF_TILE_SIZE_PX / 2.0f; 72 - state->player.pos.y = world->width * KF_TILE_SIZE_PX / 2.0f; 75 + struct kf_actor *player2 = kf_actor_new("player2"); 76 + player2->pos.x = world->width * KF_TILE_SIZE_PX / 2.0f; 77 + player2->pos.y = (world->width * KF_TILE_SIZE_PX / 2.0f) - 32; 73 78 74 79 kf_timeit("save actors", kf_saveactors()); 75 80 } ··· 78 83 kf_timeit("load actors", kf_loadactors()); 79 84 } 80 85 81 - struct kf_actor *player = kf_actors; /* player should always be the first actor. */ 82 - kf_window.player = player; 83 - 84 - struct kf_actor *player2 = kf_actor_new("player2"); 85 - player2->size.x = 10; 86 - player2->size.y = 10; 87 - player2->collide = false; 88 - player2->sizeoffset.y = 6; 89 - player2->pos.x = player->pos.x; 90 - player2->pos.y = player->pos.y - 24; 86 + kf_window.player = kf_actors; /* player should always be the first actor. */ 91 87 92 - kf_window.cam.target.x = player->pos.x + (player->size.x / 2); 93 - kf_window.cam.target.y = player->pos.y + (player->size.y / 2); 88 + kf_window.cam.target.x = kf_window.player->pos.x + (kf_window.player->size.x / 2); 89 + kf_window.cam.target.y = kf_window.player->pos.y + (kf_window.player->size.y / 2); 94 90 kf_window.cam.zoom = 2; 95 91 96 92 kf_setmodal(&kf_modal_play); ··· 145 141 146 142 kf_saveactors(); 147 143 148 - kf_window.state->player.pos = kf_window.player->pos; 149 144 kf_state_save(kf_window.state); 150 145 151 146 free(kf_window.player);
+1
src/player.c
··· 93 93 { 94 94 self->pos.x = bini_rf(bs); 95 95 self->pos.y = bini_rf(bs); 96 + self->controlled = bini_rb(bs); 96 97 }
+13
src/string.c
··· 1 + #include <keraforge.h> 2 + 3 + #include <string.h> 4 + 5 + 6 + char *kf_strdup(char *str) 7 + { 8 + size_t n = strlen(str); 9 + char *s = malloc(n + 1); 10 + strcpy(s, str); 11 + s[n] = '\0'; 12 + return s; 13 + }