file based save states, and improved file structure
This commit is contained in:
@ -63,6 +63,8 @@ bool cart_load(char *cart);
|
|||||||
|
|
||||||
rom_header *get_rom_header();
|
rom_header *get_rom_header();
|
||||||
|
|
||||||
|
cart_context *cart_get_context();
|
||||||
|
|
||||||
u8 cart_read(u16 address);
|
u8 cart_read(u16 address);
|
||||||
void cart_write(u16 address, u8 value);
|
void cart_write(u16 address, u8 value);
|
||||||
|
|
||||||
|
@ -22,4 +22,7 @@ typedef struct {
|
|||||||
} save_state;
|
} save_state;
|
||||||
|
|
||||||
void state_save(save_state*);
|
void state_save(save_state*);
|
||||||
void state_load(const save_state*);
|
void state_load(const save_state*);
|
||||||
|
|
||||||
|
void state_save_file(u8 slot);
|
||||||
|
void state_load_file(u8 slot);
|
19
lib/cart.c
19
lib/cart.c
@ -1,6 +1,7 @@
|
|||||||
#include <cart.h>
|
#include <cart.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
static cart_context ctx;
|
static cart_context ctx;
|
||||||
|
|
||||||
@ -372,8 +373,11 @@ void cart_write(u16 address, u8 value){
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool cart_battery_load(){
|
bool cart_battery_load(){
|
||||||
|
char *filename = strrchr(ctx.filename, '\\');
|
||||||
|
filename++;
|
||||||
char fn[1048];
|
char fn[1048];
|
||||||
sprintf(fn, "%s.battery", ctx.filename);
|
char *profile = getenv("USERPROFILE");
|
||||||
|
sprintf(fn, "%s/Documents/gbemu/saves/%s.battery", profile, filename);
|
||||||
FILE *fp = fopen(fn, "rb");
|
FILE *fp = fopen(fn, "rb");
|
||||||
|
|
||||||
if(!fp) {
|
if(!fp) {
|
||||||
@ -386,8 +390,11 @@ bool cart_battery_load(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool cart_battery_save(){
|
bool cart_battery_save(){
|
||||||
|
char *filename = strrchr(ctx.filename, '\\');
|
||||||
|
filename++;
|
||||||
char fn[1048];
|
char fn[1048];
|
||||||
sprintf(fn, "%s.battery", ctx.filename);
|
char *profile = getenv("USERPROFILE");
|
||||||
|
sprintf(fn, "%s/Documents/gbemu/saves/%s.battery", profile, filename);
|
||||||
FILE *fp = fopen(fn, "wb");
|
FILE *fp = fopen(fn, "wb");
|
||||||
|
|
||||||
if(!fp) {
|
if(!fp) {
|
||||||
@ -432,6 +439,10 @@ void cart_load_state(const cart_state* state){
|
|||||||
ctx.ram_bank = ctx.ram_banks[0];
|
ctx.ram_bank = ctx.ram_banks[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(ctx.battery) {
|
||||||
|
cart_battery_load();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cart_save_state(cart_state* state){
|
void cart_save_state(cart_state* state){
|
||||||
@ -448,4 +459,8 @@ void cart_save_state(cart_state* state){
|
|||||||
memcpy((&state->ram_banks[i]), ctx.ram_banks[i], 0x2000);
|
memcpy((&state->ram_banks[i]), ctx.ram_banks[i], 0x2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cart_context *cart_get_context(){
|
||||||
|
return &ctx;
|
||||||
}
|
}
|
@ -87,6 +87,15 @@ int emu_run(int argc, char **argv) {
|
|||||||
printf("Failed to load ROM file: %s\n", argv[1]);
|
printf("Failed to load ROM file: %s\n", argv[1]);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char fn[1048];
|
||||||
|
char *profile = getenv("USERPROFILE");
|
||||||
|
sprintf(fn, "%s\\Documents\\gbemu", profile);
|
||||||
|
CreateDirectory(fn, NULL);
|
||||||
|
sprintf(fn, "%s\\Documents\\gbemu\\saves", profile);
|
||||||
|
CreateDirectory(fn, NULL);
|
||||||
|
sprintf(fn, "%s\\Documents\\gbemu\\states", profile);
|
||||||
|
CreateDirectory(fn, NULL);
|
||||||
|
|
||||||
printf("Cart loaded..\n");
|
printf("Cart loaded..\n");
|
||||||
ctx.app_path = argv[0];
|
ctx.app_path = argv[0];
|
||||||
|
41
lib/state.c
41
lib/state.c
@ -1,4 +1,5 @@
|
|||||||
#include <state.h>
|
#include <state.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
void state_save(save_state* state) {
|
void state_save(save_state* state) {
|
||||||
printf("Saving state\n");
|
printf("Saving state\n");
|
||||||
@ -24,4 +25,44 @@ void state_load(const save_state* state) {
|
|||||||
audio_load_state(&state->audio);
|
audio_load_state(&state->audio);
|
||||||
gamepad_load_state(&state->ctlr);
|
gamepad_load_state(&state->ctlr);
|
||||||
cart_load_state(&state->cart);
|
cart_load_state(&state->cart);
|
||||||
|
}
|
||||||
|
|
||||||
|
void state_save_file(u8 slot) {
|
||||||
|
save_state* state = malloc(sizeof(*state));
|
||||||
|
state_save(state);
|
||||||
|
char *filename = strrchr(cart_get_context()->filename, '\\');
|
||||||
|
filename++;
|
||||||
|
char fn[1048];
|
||||||
|
char *profile = getenv("USERPROFILE");
|
||||||
|
sprintf(fn, "%s/Documents/gbemu/states/%s", profile, filename);
|
||||||
|
CreateDirectory(fn, NULL);
|
||||||
|
sprintf(fn, "%s/Documents/gbemu/states/%s/%d.state", profile, filename, slot);
|
||||||
|
FILE *fp = fopen(fn, "wb");
|
||||||
|
|
||||||
|
if(!fp) {
|
||||||
|
fprintf(stderr, "unable to save state %d\n", slot);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite(state, sizeof(*state), 1, fp);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void state_load_file(u8 slot) {
|
||||||
|
save_state* state = malloc(sizeof(*state));
|
||||||
|
char *filename = strrchr(cart_get_context()->filename, '\\');
|
||||||
|
filename++;
|
||||||
|
char fn[1048];
|
||||||
|
char *profile = getenv("USERPROFILE");
|
||||||
|
sprintf(fn, "%s/Documents/gbemu/states/%s/%d.state", profile, filename, slot);
|
||||||
|
FILE *fp = fopen(fn, "rb");
|
||||||
|
|
||||||
|
if(!fp) {
|
||||||
|
printf("Save slot %d doesnt exist.\n", slot);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fread(state, sizeof(*state), 1, fp);
|
||||||
|
fclose(fp);
|
||||||
|
state_load(state);
|
||||||
}
|
}
|
6
lib/ui.c
6
lib/ui.c
@ -25,12 +25,10 @@ SDL_Renderer *sdlDebugRenderer;
|
|||||||
SDL_Texture *sdlDebugTexture;
|
SDL_Texture *sdlDebugTexture;
|
||||||
SDL_Surface *debugScreen;
|
SDL_Surface *debugScreen;
|
||||||
TTF_Font *sans;
|
TTF_Font *sans;
|
||||||
save_state *state;
|
|
||||||
|
|
||||||
static int scale = 4;
|
static int scale = 4;
|
||||||
|
|
||||||
void ui_init(){
|
void ui_init(){
|
||||||
state = malloc(sizeof(*state));
|
|
||||||
SDL_Init(SDL_INIT_VIDEO);
|
SDL_Init(SDL_INIT_VIDEO);
|
||||||
printf("SDL INIT\n");
|
printf("SDL INIT\n");
|
||||||
TTF_Init();
|
TTF_Init();
|
||||||
@ -344,13 +342,13 @@ void ui_on_key(bool down, u32 key_code) {
|
|||||||
}
|
}
|
||||||
if(key_code == SDLK_s && down == true) {
|
if(key_code == SDLK_s && down == true) {
|
||||||
emu_stop();
|
emu_stop();
|
||||||
state_save(state);
|
state_save_file(0);
|
||||||
emu_start();
|
emu_start();
|
||||||
}
|
}
|
||||||
if(key_code == SDLK_l && down == true) {
|
if(key_code == SDLK_l && down == true) {
|
||||||
emu_stop();
|
emu_stop();
|
||||||
emu_reset();
|
emu_reset();
|
||||||
state_load(state);
|
state_load_file(0);
|
||||||
emu_start();
|
emu_start();
|
||||||
}
|
}
|
||||||
switch(key_code){
|
switch(key_code){
|
||||||
|
Reference in New Issue
Block a user