From bc76c36ed4d92e4894c53cfdfa63b842f18d09ce Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Thu, 18 Jul 2024 20:24:34 +0900 Subject: [PATCH] add loadsave loadsave: only for BAT features cartidge [load|save] state: for all cartidge. It's like snapshot --- .gitignore | 1 + eui.c | 10 +++----- ev.c | 2 +- gb.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++--- gb.h | 14 +++++++--- mem.c | 1 + save.c | 14 +++++----- 7 files changed, 95 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 81af666..779fd04 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ *.obj *.elf .*.swp +*.gb # Linker output *.ilk diff --git a/eui.c b/eui.c index 877b3e6..a2bb012 100644 --- a/eui.c +++ b/eui.c @@ -9,7 +9,7 @@ u8* pic; SDL_Renderer* renderer; SDL_Texture* bitmapTex; -static void +void render() { SDL_UpdateTexture(bitmapTex, nil, pic, 160 * sizeof(u32)); @@ -29,6 +29,8 @@ joypadevent(void*_) case SDL_KEYUP: keys = 0; break; case SDL_KEYDOWN: switch (evt.key.keysym.scancode) { + case SDL_SCANCODE_F1: savereq = 1; break; + case SDL_SCANCODE_F2: loadreq = 1; break; case SDL_SCANCODE_X: keys = GB_KEY_A; break; case SDL_SCANCODE_Z: keys = GB_KEY_B; break; case SDL_SCANCODE_UP: keys = GB_KEY_UP; break; @@ -45,12 +47,6 @@ joypadevent(void*_) return; } -void -flush() -{ - render(); -} - void initwindow(int scale) { diff --git a/ev.c b/ev.c index d711036..fc18341 100644 --- a/ev.c +++ b/ev.c @@ -1,7 +1,7 @@ #include "gb.h" Event evhblank, evjoypad; -Event *events[NEVENT] = {&evhblank, &evjoypad, nil}; +Event *events[NEVENT] = {&evhblank, &evjoypad}; Event* elist; Var evvars[] = {{nil, 0, 0}}; diff --git a/gb.c b/gb.c index d2c90b0..4eda52b 100644 --- a/gb.c +++ b/gb.c @@ -1,12 +1,56 @@ #include "gb.h" #include "co/task.h" #include +#include +#include +#include +int savereq, loadreq; int cpuhalt; int backup; -int savefd = -1; +FILE *savefp; +int saveframes; +const char *romname; u8 mbc, feat, mode; +void +writeback(void) +{ + if(saveframes == 0) + saveframes = 15; +} + +void +flushback(void) +{ + if(savefp != nil) + fwrite(back, 1, nback, savefp); + saveframes = 0; +} + +static void +loadsave(const char *file) +{ + u8 *buf, *p; + + buf = xalloc(strlen(file) + 4); + strcpy(buf, file); + p = strrchr(buf, '.'); + if(p == nil) + p = buf + strlen(buf); + strcpy(p, ".sav"); + savefp = fopen(buf, "w+"); + if(savefp == 0){ + error("Can't load save file '%s'", file); + free(buf); + return; + } + back = xalloc(nback); + fwrite(back, 1, nback, savefp); + free(buf); + atexit(flushback); +} + static void loadrom(const char* file) { @@ -47,7 +91,6 @@ loadrom(const char* file) default: panic("Unkown Ram size %d\n", rom[0x149]); } } - back = xalloc(nback); if(nback == 0) nbackbank = 1; else @@ -59,6 +102,32 @@ loadrom(const char* file) } if ((rom[0x143] & 0x80) != 0 && (mode & FORCEDMG) == 0) mode = CGB | COL; + if((feat & FEATBAT) != 0) + loadsave(file); +} + +void +flush() +{ + static char *savestatename; + if (savestatename == 0){ + int len = strlen(romname); + savestatename = xalloc(len + 4); + strncpy(savestatename, romname, len); + strcpy(savestatename + len, "-state.save"); + } + + render(); + if(saveframes > 0 && -- saveframes == 0) + flushback(); + if(savereq){ + savestate(savestatename); + savereq = 0; + } + if(loadreq){ + loadstate(savestatename); + loadreq = 0; + } } static void @@ -80,8 +149,8 @@ colinit(void) void taskmain(int argc, char* argv[]) { + loadrom(romname = argv[1]); colinit(); - loadrom(argv[1]); initwindow(5); initevent(); meminit(); diff --git a/gb.h b/gb.h index eedb964..bfef481 100644 --- a/gb.h +++ b/gb.h @@ -132,7 +132,7 @@ enum GB_KEY_START = 0x80 }; -enum { NEVENT = 2 + 1}; +enum { NEVENT = 2 }; typedef uint8_t u8; typedef uint16_t u16; @@ -180,6 +180,7 @@ extern u32 white; extern u8* pic; extern int (*mapper)(int, int); extern Event *events[NEVENT]; +extern int savereq, loadreq; /* joypad */ void @@ -219,15 +220,22 @@ reset(void); /* graphic */ void -flush(); -void initwindow(int scale); +void +render(); /* save */ void putvars(Var *v); void getvars(Var *v); +void +flush(); +int +savestate(const char *fname); +int +loadstate(const char *fname); + /* error */ void error(const char*, ...); diff --git a/mem.c b/mem.c index 7701ee9..a483482 100644 --- a/mem.c +++ b/mem.c @@ -160,6 +160,7 @@ memwrite(u16 a, u8 v) eramb[a - 0xa000] = v; else mapper(a, v); + writeback(); return; case 12: case 14: wram[a & 0xFFF] = v; diff --git a/save.c b/save.c index 12ff12e..293f23d 100644 --- a/save.c +++ b/save.c @@ -14,7 +14,7 @@ putevents(void) if(elist == events[i]) /* find head */ break; if(i == NEVENT && elist != nil) - error("Unkown event in chain [%p]", e->next); + error("Unkown event in chain [%p]", elist); fputc(i, fp); for(i = 0; i < NEVENT; ++i){ e = events[i]; @@ -125,10 +125,10 @@ getevents(void) Event *e; i = fgetc(fp); - if(i > NEVENT){ - error("Unkown event index [%d]", i); + if(i >= NEVENT) elist = nil; - } + else + elist = events[i]; for(i = 0; i < NEVENT; ++i){ e = events[i]; e->time = fgetc(fp); @@ -136,12 +136,10 @@ getevents(void) e->time |= fgetc(fp) << 16; e->time |= fgetc(fp) << 24; j = fgetc(fp); - if(j >= NEVENT){ - error("Unkown event index [%d]", j); + if(j >= NEVENT) e->next = nil; - }else{ + else e->next = events[j]; - } } }