add loadsave

loadsave: only for BAT features cartidge
[load|save] state: for all cartidge. It's like snapshot
This commit is contained in:
Hojun-Cho 2024-07-18 20:24:34 +09:00
parent 4661fc35bb
commit bc76c36ed4
7 changed files with 95 additions and 22 deletions

1
.gitignore vendored
View File

@ -7,6 +7,7 @@
*.obj
*.elf
.*.swp
*.gb
# Linker output
*.ilk

10
eui.c
View File

@ -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)
{

2
ev.c
View File

@ -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}};

75
gb.c
View File

@ -1,12 +1,56 @@
#include "gb.h"
#include "co/task.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
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();

14
gb.h
View File

@ -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*, ...);

1
mem.c
View File

@ -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;

14
save.c
View File

@ -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,13 +136,11 @@ 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];
}
}
}
int