mirror of
https://github.com/RaySollium99/libpicofe.git
synced 2025-09-05 14:57:46 -04:00
savestate loader in menu
git-svn-id: file:///home/notaz/opt/svn/PicoDrive/platform@56 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
d55c53ab56
commit
4ffd28584e
5 changed files with 302 additions and 75 deletions
196
gp2x/emu.c
196
gp2x/emu.c
|
@ -6,6 +6,8 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -394,22 +396,36 @@ void emu_Init(void)
|
||||||
printf("framebuff == 0\n");
|
printf("framebuff == 0\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make dirs for saves, cfgs, etc.
|
||||||
|
mkdir("mds", 0777);
|
||||||
|
mkdir("srm", 0777);
|
||||||
|
mkdir("brm", 0777);
|
||||||
|
mkdir("cfg", 0777);
|
||||||
|
|
||||||
PicoInit();
|
PicoInit();
|
||||||
|
|
||||||
// logf = fopen("log.txt", "w");
|
// logf = fopen("log.txt", "w");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void romfname_ext(char *dst, char *ext)
|
static void romfname_ext(char *dst, const char *prefix, const char *ext)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
|
int prefix_len = 0;
|
||||||
|
|
||||||
// make save filename
|
// make save filename
|
||||||
for (p = romFileName+strlen(romFileName)-1; p >= romFileName && *p != '/'; p--); p++;
|
for (p = romFileName+strlen(romFileName)-1; p >= romFileName && *p != '/'; p--); p++;
|
||||||
strncpy(dst, p, 511);
|
*dst = 0;
|
||||||
|
if (prefix) {
|
||||||
|
strcpy(dst, prefix);
|
||||||
|
prefix_len = strlen(prefix);
|
||||||
|
}
|
||||||
|
strncpy(dst + prefix_len, p, 511-prefix_len);
|
||||||
dst[511-8] = 0;
|
dst[511-8] = 0;
|
||||||
if (dst[strlen(dst)-4] == '.') dst[strlen(dst)-4] = 0;
|
if (dst[strlen(dst)-4] == '.') dst[strlen(dst)-4] = 0;
|
||||||
strcat(dst, ext);
|
if (ext) strcat(dst, ext);
|
||||||
|
|
||||||
|
printf("romfname_ext: %s\n", dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -479,7 +495,10 @@ int emu_ReadConfig(int game)
|
||||||
strncpy(cfg, PicoConfigFile, 511);
|
strncpy(cfg, PicoConfigFile, 511);
|
||||||
cfg[511] = 0;
|
cfg[511] = 0;
|
||||||
} else {
|
} else {
|
||||||
romfname_ext(cfg, ".pbcfg");
|
romfname_ext(cfg, "cfg/", ".pbcfg");
|
||||||
|
f = fopen(cfg, "rb");
|
||||||
|
if (!f) romfname_ext(cfg, NULL, ".pbcfg");
|
||||||
|
else fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("emu_ReadConfig: %s ", cfg);
|
printf("emu_ReadConfig: %s ", cfg);
|
||||||
|
@ -522,7 +541,7 @@ int emu_WriteConfig(int game)
|
||||||
strncpy(cfg, PicoConfigFile, 511);
|
strncpy(cfg, PicoConfigFile, 511);
|
||||||
cfg[511] = 0;
|
cfg[511] = 0;
|
||||||
} else {
|
} else {
|
||||||
romfname_ext(cfg, ".pbcfg");
|
romfname_ext(cfg, "cfg", ".pbcfg");
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("emu_WriteConfig: %s ", cfg);
|
printf("emu_WriteConfig: %s ", cfg);
|
||||||
|
@ -745,25 +764,6 @@ static void vidResetMode(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int check_save_file(void)
|
|
||||||
{
|
|
||||||
char saveFname[512];
|
|
||||||
char ext[16];
|
|
||||||
FILE *f;
|
|
||||||
|
|
||||||
ext[0] = 0;
|
|
||||||
if(state_slot > 0 && state_slot < 10) sprintf(ext, ".%i", state_slot);
|
|
||||||
strcat(ext, ".mds");
|
|
||||||
if(currentConfig.EmuOpt & 8) strcat(ext, ".gz");
|
|
||||||
|
|
||||||
romfname_ext(saveFname, ext);
|
|
||||||
if ((f = fopen(saveFname, "rb"))) {
|
|
||||||
fclose(f);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void emu_state_cb(const char *str)
|
static void emu_state_cb(const char *str)
|
||||||
{
|
{
|
||||||
clearArea(0);
|
clearArea(0);
|
||||||
|
@ -774,7 +774,7 @@ static void RunEvents(unsigned int which)
|
||||||
{
|
{
|
||||||
if(which & 0x1800) { // save or load (but not both)
|
if(which & 0x1800) { // save or load (but not both)
|
||||||
int do_it = 1;
|
int do_it = 1;
|
||||||
if (!(which & 0x1000) && (currentConfig.EmuOpt & 0x200) && check_save_file()) {
|
if (!(which & 0x1000) && (currentConfig.EmuOpt & 0x200) && emu_check_save_file(state_slot)) {
|
||||||
unsigned long keys;
|
unsigned long keys;
|
||||||
blit("", "OVERWRITE SAVE? (Y=yes, X=no)");
|
blit("", "OVERWRITE SAVE? (Y=yes, X=no)");
|
||||||
while( !((keys = gp2x_joystick_read(1)) & (GP2X_X|GP2X_Y)) )
|
while( !((keys = gp2x_joystick_read(1)) & (GP2X_X|GP2X_Y)) )
|
||||||
|
@ -817,7 +817,7 @@ static void RunEvents(unsigned int which)
|
||||||
state_slot += 1;
|
state_slot += 1;
|
||||||
if(state_slot > 9) state_slot = 0;
|
if(state_slot > 9) state_slot = 0;
|
||||||
}
|
}
|
||||||
sprintf(noticeMsg, "SAVE SLOT %i [%s]", state_slot, check_save_file() ? "USED" : "FREE");
|
sprintf(noticeMsg, "SAVE SLOT %i [%s]", state_slot, emu_check_save_file(state_slot) ? "USED" : "FREE");
|
||||||
gettimeofday(¬iceMsgTime, 0);
|
gettimeofday(¬iceMsgTime, 0);
|
||||||
}
|
}
|
||||||
if(which & 0x0080) {
|
if(which & 0x0080) {
|
||||||
|
@ -964,6 +964,24 @@ static void SkipFrame(int do_sound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void emu_forced_frame(void)
|
||||||
|
{
|
||||||
|
int po_old = PicoOpt;
|
||||||
|
|
||||||
|
PicoOpt |= 0x10;
|
||||||
|
PicoFrameFull();
|
||||||
|
PicoOpt = po_old;
|
||||||
|
|
||||||
|
if (!(Pico.video.reg[12]&1)) {
|
||||||
|
vidCpyM2 = vidCpyM2_40col;
|
||||||
|
clearArea(1);
|
||||||
|
} else vidCpyM2 = vidCpyM2_32col;
|
||||||
|
|
||||||
|
vidCpyM2((unsigned char *)gp2x_screen+320*8, framebuff+328*8);
|
||||||
|
vidConvCpyRGB32(localPal, Pico.cram, 0x40);
|
||||||
|
gp2x_video_setpalette(localPal, 0x40);
|
||||||
|
}
|
||||||
|
|
||||||
static void simpleWait(int thissec, int lim_time)
|
static void simpleWait(int thissec, int lim_time)
|
||||||
{
|
{
|
||||||
struct timeval tval;
|
struct timeval tval;
|
||||||
|
@ -1239,18 +1257,11 @@ if (Pico.m.frame_count == 31563) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// if in 16bit mode, generate 8it image for menu background
|
// if in 16bit mode, generate 8it image for menu background
|
||||||
if (!(PicoOpt&0x10) && (currentConfig.EmuOpt&0x80)) {
|
if (!(PicoOpt&0x10) && (currentConfig.EmuOpt&0x80))
|
||||||
PicoOpt |= 0x10;
|
emu_forced_frame();
|
||||||
if (!(Pico.video.reg[12]&1)) clearArea(1);
|
|
||||||
PicoFrameFull();
|
|
||||||
vidCpyM2((unsigned char *)gp2x_screen+320*8, framebuff+328*8);
|
|
||||||
vidConvCpyRGB32(localPal, Pico.cram, 0x40);
|
|
||||||
gp2x_video_setpalette(localPal, 0x40);
|
|
||||||
PicoOpt &= ~0x10;
|
|
||||||
}
|
|
||||||
|
|
||||||
// for menu bg
|
// for menu bg
|
||||||
gp2x_memcpy_all_buffers(gp2x_screen, 0, 320*240*2);
|
gp2x_memcpy_buffers((1<<2), gp2x_screen, 0, 320*240*2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1272,18 +1283,95 @@ size_t gzWrite2(void *p, size_t _size, size_t _n, void *file)
|
||||||
return gzwrite(file, p, _n);
|
return gzwrite(file, p, _n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int try_ropen_file(const char *fname)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
f = fopen(fname, "rb");
|
||||||
|
if (f) {
|
||||||
|
fclose(f);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *emu_GetSaveFName(int load, int is_sram, int slot)
|
||||||
|
{
|
||||||
|
static char saveFname[512];
|
||||||
|
char ext[16];
|
||||||
|
|
||||||
|
if (is_sram)
|
||||||
|
{
|
||||||
|
romfname_ext(saveFname, (PicoMCD&1) ? "brm/" : "srm/", (PicoMCD&1) ? ".brm" : ".srm");
|
||||||
|
if (load) {
|
||||||
|
if (try_ropen_file(saveFname)) return saveFname;
|
||||||
|
// try in current dir..
|
||||||
|
romfname_ext(saveFname, NULL, (PicoMCD&1) ? ".brm" : ".srm");
|
||||||
|
if (try_ropen_file(saveFname)) return saveFname;
|
||||||
|
return NULL; // give up
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ext[0] = 0;
|
||||||
|
if(slot > 0 && slot < 10) sprintf(ext, ".%i", slot);
|
||||||
|
strcat(ext, (currentConfig.EmuOpt & 8) ? ".mds.gz" : ".mds");
|
||||||
|
|
||||||
|
romfname_ext(saveFname, "mds/", ext);
|
||||||
|
if (load) {
|
||||||
|
if (try_ropen_file(saveFname)) return saveFname;
|
||||||
|
romfname_ext(saveFname, NULL, ext);
|
||||||
|
if (try_ropen_file(saveFname)) return saveFname;
|
||||||
|
if (currentConfig.EmuOpt & 8) {
|
||||||
|
ext[0] = 0;
|
||||||
|
if(slot > 0 && slot < 10) sprintf(ext, ".%i", slot);
|
||||||
|
strcat(ext, ".mds");
|
||||||
|
|
||||||
|
romfname_ext(saveFname, "mds/", ext);
|
||||||
|
if (try_ropen_file(saveFname)) return saveFname;
|
||||||
|
romfname_ext(saveFname, NULL, ext);
|
||||||
|
if (try_ropen_file(saveFname)) return saveFname;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return saveFname;
|
||||||
|
}
|
||||||
|
|
||||||
|
int emu_check_save_file(int slot)
|
||||||
|
{
|
||||||
|
return emu_GetSaveFName(1, 0, slot) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void emu_set_save_cbs(int gz)
|
||||||
|
{
|
||||||
|
if (gz) {
|
||||||
|
areaRead = gzRead2;
|
||||||
|
areaWrite = gzWrite2;
|
||||||
|
areaEof = (areaeof *) gzeof;
|
||||||
|
areaSeek = (areaseek *) gzseek;
|
||||||
|
areaClose = (areaclose *) gzclose;
|
||||||
|
} else {
|
||||||
|
areaRead = (arearw *) fread;
|
||||||
|
areaWrite = (arearw *) fwrite;
|
||||||
|
areaEof = (areaeof *) feof;
|
||||||
|
areaSeek = (areaseek *) fseek;
|
||||||
|
areaClose = (areaclose *) fclose;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int emu_SaveLoadGame(int load, int sram)
|
int emu_SaveLoadGame(int load, int sram)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
char saveFname[512];
|
char *saveFname;
|
||||||
|
|
||||||
// make save filename
|
// make save filename
|
||||||
romfname_ext(saveFname, "");
|
saveFname = emu_GetSaveFName(load, sram, state_slot);
|
||||||
if(sram) strcat(saveFname, (PicoMCD&1) ? ".brm" : ".srm");
|
if (saveFname == NULL) {
|
||||||
else {
|
strcpy(noticeMsg, load ? "LOAD FAILED (missing file)" : "SAVE FAILED ");
|
||||||
if(state_slot > 0 && state_slot < 10) sprintf(saveFname, "%s.%i", saveFname, state_slot);
|
gettimeofday(¬iceMsgTime, 0);
|
||||||
strcat(saveFname, ".mds");
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("saveLoad (%i, %i): %s\n", load, sram, saveFname);
|
printf("saveLoad (%i, %i): %s\n", load, sram, saveFname);
|
||||||
|
@ -1326,31 +1414,21 @@ int emu_SaveLoadGame(int load, int sram)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
void *PmovFile = NULL;
|
void *PmovFile = NULL;
|
||||||
// try gzip first
|
if (strcmp(saveFname + strlen(saveFname) - 3, ".gz") == 0) {
|
||||||
if(currentConfig.EmuOpt & 8) {
|
|
||||||
strcat(saveFname, ".gz");
|
|
||||||
if( (PmovFile = gzopen(saveFname, load ? "rb" : "wb")) ) {
|
if( (PmovFile = gzopen(saveFname, load ? "rb" : "wb")) ) {
|
||||||
areaRead = gzRead2;
|
emu_set_save_cbs(1);
|
||||||
areaWrite = gzWrite2;
|
|
||||||
areaEof = (areaeof *) gzeof;
|
|
||||||
areaSeek = (areaseek *) gzseek;
|
|
||||||
if(!load) gzsetparams(PmovFile, 9, Z_DEFAULT_STRATEGY);
|
if(!load) gzsetparams(PmovFile, 9, Z_DEFAULT_STRATEGY);
|
||||||
} else
|
|
||||||
saveFname[strlen(saveFname)-3] = 0;
|
|
||||||
}
|
}
|
||||||
if(!PmovFile) { // gzip failed or was disabled
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if( (PmovFile = fopen(saveFname, load ? "rb" : "wb")) ) {
|
if( (PmovFile = fopen(saveFname, load ? "rb" : "wb")) ) {
|
||||||
areaRead = (arearw *) fread;
|
emu_set_save_cbs(0);
|
||||||
areaWrite = (arearw *) fwrite;
|
|
||||||
areaEof = (areaeof *) feof;
|
|
||||||
areaSeek = (areaseek *) fseek;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(PmovFile) {
|
if(PmovFile) {
|
||||||
ret = PmovState(load ? 6 : 5, PmovFile);
|
ret = PmovState(load ? 6 : 5, PmovFile);
|
||||||
if(areaRead == gzRead2)
|
areaClose(PmovFile);
|
||||||
gzclose(PmovFile);
|
|
||||||
else fclose ((FILE *) PmovFile);
|
|
||||||
PmovFile = 0;
|
PmovFile = 0;
|
||||||
if (!load) sync();
|
if (!load) sync();
|
||||||
else Pico.m.dirtyPal=1;
|
else Pico.m.dirtyPal=1;
|
||||||
|
|
|
@ -46,5 +46,9 @@ void emu_Loop(void);
|
||||||
void emu_ResetGame(void);
|
void emu_ResetGame(void);
|
||||||
int emu_ReadConfig(int game);
|
int emu_ReadConfig(int game);
|
||||||
int emu_WriteConfig(int game);
|
int emu_WriteConfig(int game);
|
||||||
|
char *emu_GetSaveFName(int load, int is_sram, int slot);
|
||||||
|
int emu_check_save_file(int slot);
|
||||||
|
void emu_set_save_cbs(int gz);
|
||||||
|
void emu_forced_frame(void);
|
||||||
int find_bios(int region, char **bios_file);
|
int find_bios(int region, char **bios_file);
|
||||||
|
|
||||||
|
|
14
gp2x/gp2x.c
14
gp2x/gp2x.c
|
@ -145,12 +145,18 @@ void gp2x_video_wait_vsync(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void gp2x_memcpy_buffers(int buffers, void *data, int offset, int len)
|
||||||
|
{
|
||||||
|
if (buffers & (1<<0)) memcpy((char *)gp2x_screens[0] + offset, data, len);
|
||||||
|
if (buffers & (1<<1)) memcpy((char *)gp2x_screens[1] + offset, data, len);
|
||||||
|
if (buffers & (1<<2)) memcpy((char *)gp2x_screens[2] + offset, data, len);
|
||||||
|
if (buffers & (1<<3)) memcpy((char *)gp2x_screens[3] + offset, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void gp2x_memcpy_all_buffers(void *data, int offset, int len)
|
void gp2x_memcpy_all_buffers(void *data, int offset, int len)
|
||||||
{
|
{
|
||||||
memcpy((char *)gp2x_screens[0] + offset, data, len);
|
gp2x_memcpy_buffers(0xf, data, offset, len);
|
||||||
memcpy((char *)gp2x_screens[1] + offset, data, len);
|
|
||||||
memcpy((char *)gp2x_screens[2] + offset, data, len);
|
|
||||||
memcpy((char *)gp2x_screens[3] + offset, data, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ void gp2x_video_changemode2(int bpp);
|
||||||
void gp2x_video_setpalette(int *pal, int len);
|
void gp2x_video_setpalette(int *pal, int len);
|
||||||
void gp2x_video_RGB_setscaling(int W, int H);
|
void gp2x_video_RGB_setscaling(int W, int H);
|
||||||
void gp2x_video_wait_vsync(void);
|
void gp2x_video_wait_vsync(void);
|
||||||
|
void gp2x_memcpy_buffers(int buffers, void *data, int offset, int len);
|
||||||
void gp2x_memcpy_all_buffers(void *data, int offset, int len);
|
void gp2x_memcpy_all_buffers(void *data, int offset, int len);
|
||||||
void gp2x_memset_all_buffers(int offset, int byte, int len);
|
void gp2x_memset_all_buffers(int offset, int byte, int len);
|
||||||
void gp2x_pd_clone_buffer2(void);
|
void gp2x_pd_clone_buffer2(void);
|
||||||
|
|
160
gp2x/menu.c
160
gp2x/menu.c
|
@ -18,6 +18,7 @@
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
#include "Pico/PicoInt.h"
|
#include "Pico/PicoInt.h"
|
||||||
|
#include "zlib/zlib.h"
|
||||||
|
|
||||||
#ifndef _DIRENT_HAVE_D_TYPE
|
#ifndef _DIRENT_HAVE_D_TYPE
|
||||||
#error "need d_type for file browser
|
#error "need d_type for file browser
|
||||||
|
@ -390,6 +391,139 @@ static char *romsel_loop(char *curr_path)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------ savestate loader ------------
|
||||||
|
|
||||||
|
static void menu_prepare_bg(void);
|
||||||
|
|
||||||
|
static int state_slot_flags = 0;
|
||||||
|
|
||||||
|
static void state_check_slots(void)
|
||||||
|
{
|
||||||
|
int slot;
|
||||||
|
|
||||||
|
state_slot_flags = 0;
|
||||||
|
|
||||||
|
for (slot = 0; slot < 10; slot++)
|
||||||
|
{
|
||||||
|
if (emu_check_save_file(slot))
|
||||||
|
{
|
||||||
|
state_slot_flags |= 1 << slot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw_savestate_bg(int slot)
|
||||||
|
{
|
||||||
|
struct PicoVideo tmp_pv;
|
||||||
|
unsigned short tmp_cram[0x40];
|
||||||
|
unsigned short tmp_vsram[0x40];
|
||||||
|
void *tmp_vram, *file;
|
||||||
|
char *fname;
|
||||||
|
|
||||||
|
fname = emu_GetSaveFName(1, 0, slot);
|
||||||
|
if (!fname) return;
|
||||||
|
|
||||||
|
tmp_vram = malloc(sizeof(Pico.vram));
|
||||||
|
if (tmp_vram == NULL) return;
|
||||||
|
|
||||||
|
memcpy(tmp_vram, Pico.vram, sizeof(Pico.vram));
|
||||||
|
memcpy(tmp_cram, Pico.cram, sizeof(Pico.cram));
|
||||||
|
memcpy(tmp_vsram, Pico.vsram, sizeof(Pico.vsram));
|
||||||
|
memcpy(&tmp_pv, &Pico.video, sizeof(Pico.video));
|
||||||
|
|
||||||
|
if (strcmp(fname + strlen(fname) - 3, ".gz") == 0) {
|
||||||
|
file = gzopen(fname, "rb");
|
||||||
|
emu_set_save_cbs(1);
|
||||||
|
} else {
|
||||||
|
file = fopen(fname, "rb");
|
||||||
|
emu_set_save_cbs(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
if (PicoMCD & 1) {
|
||||||
|
PicoCdLoadStateGfx(file);
|
||||||
|
} else {
|
||||||
|
areaSeek(file, 0x10020, SEEK_SET); // skip header and RAM in state file
|
||||||
|
areaRead(Pico.vram, 1, sizeof(Pico.vram), file);
|
||||||
|
areaSeek(file, 0x2000, SEEK_CUR);
|
||||||
|
areaRead(Pico.cram, 1, sizeof(Pico.cram), file);
|
||||||
|
areaRead(Pico.vsram, 1, sizeof(Pico.vsram), file);
|
||||||
|
areaSeek(file, 0x221a0, SEEK_SET);
|
||||||
|
areaRead(&Pico.video, 1, sizeof(Pico.video), file);
|
||||||
|
}
|
||||||
|
areaClose(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
emu_forced_frame();
|
||||||
|
gp2x_memcpy_buffers((1<<2), gp2x_screen, 0, 320*240*2);
|
||||||
|
menu_prepare_bg();
|
||||||
|
|
||||||
|
memcpy(Pico.vram, tmp_vram, sizeof(Pico.vram));
|
||||||
|
memcpy(Pico.cram, tmp_cram, sizeof(Pico.cram));
|
||||||
|
memcpy(Pico.vsram, tmp_vsram, sizeof(Pico.vsram));
|
||||||
|
memcpy(&Pico.video, &tmp_pv, sizeof(Pico.video));
|
||||||
|
free(tmp_vram);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw_savestate_menu(int menu_sel, int is_loading)
|
||||||
|
{
|
||||||
|
int tl_x = 25, tl_y = 60, y, i;
|
||||||
|
|
||||||
|
if (state_slot_flags & (1 << menu_sel))
|
||||||
|
draw_savestate_bg(menu_sel);
|
||||||
|
gp2x_pd_clone_buffer2();
|
||||||
|
|
||||||
|
gp2x_text_out8(tl_x, 30, is_loading ? "Load state" : "Save state");
|
||||||
|
|
||||||
|
/* draw all 10 slots */
|
||||||
|
y = tl_y;
|
||||||
|
for (i = 0; i < 10; i++, y+=10)
|
||||||
|
{
|
||||||
|
gp2x_text_out8(tl_x, y, "SLOT %i (%s)", i, (state_slot_flags & (1 << i)) ? "USED" : "free");
|
||||||
|
}
|
||||||
|
gp2x_text_out8(tl_x, y, "back");
|
||||||
|
|
||||||
|
// draw cursor
|
||||||
|
gp2x_text_out8(tl_x - 16, tl_y + menu_sel*10, ">");
|
||||||
|
|
||||||
|
gp2x_video_flip2();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int savestate_menu_loop(int is_loading)
|
||||||
|
{
|
||||||
|
int menu_sel = 10, menu_sel_max = 10;
|
||||||
|
unsigned long inp = 0;
|
||||||
|
|
||||||
|
state_check_slots();
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
draw_savestate_menu(menu_sel, is_loading);
|
||||||
|
inp = wait_for_input(GP2X_UP|GP2X_DOWN|GP2X_B|GP2X_X);
|
||||||
|
if(inp & GP2X_UP ) {
|
||||||
|
do {
|
||||||
|
menu_sel--; if (menu_sel < 0) menu_sel = menu_sel_max;
|
||||||
|
} while (!(state_slot_flags & (1 << menu_sel)) && menu_sel != menu_sel_max && is_loading);
|
||||||
|
}
|
||||||
|
if(inp & GP2X_DOWN) {
|
||||||
|
do {
|
||||||
|
menu_sel++; if (menu_sel > menu_sel_max) menu_sel = 0;
|
||||||
|
} while (!(state_slot_flags & (1 << menu_sel)) && menu_sel != menu_sel_max && is_loading);
|
||||||
|
}
|
||||||
|
if(inp & GP2X_B) { // save/load
|
||||||
|
if (menu_sel < 10) {
|
||||||
|
state_slot = menu_sel;
|
||||||
|
if (emu_SaveLoadGame(is_loading, 0)) {
|
||||||
|
strcpy(menuErrorMsg, is_loading ? "Load failed" : "Save failed");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
} else return 1;
|
||||||
|
}
|
||||||
|
if(inp & GP2X_X) return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// -------------- key config --------------
|
// -------------- key config --------------
|
||||||
|
|
||||||
static char *usb_joy_key_name(int joy, int num)
|
static char *usb_joy_key_name(int joy, int num)
|
||||||
|
@ -1018,20 +1152,16 @@ static void menu_loop_root(void)
|
||||||
break;
|
break;
|
||||||
case 1: // save state
|
case 1: // save state
|
||||||
if (rom_data) {
|
if (rom_data) {
|
||||||
if(emu_SaveLoadGame(0, 0)) {
|
if(savestate_menu_loop(0))
|
||||||
strcpy(menuErrorMsg, "save failed");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
engineState = PGS_Running;
|
engineState = PGS_Running;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: // load state
|
case 2: // load state
|
||||||
if (rom_data) {
|
if (rom_data) {
|
||||||
if(emu_SaveLoadGame(1, 0)) {
|
if(savestate_menu_loop(1))
|
||||||
strcpy(menuErrorMsg, "load failed");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
engineState = PGS_Running;
|
engineState = PGS_Running;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1074,21 +1204,29 @@ static void menu_loop_root(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void menu_gfx_prepare(void)
|
static void menu_prepare_bg(void)
|
||||||
{
|
{
|
||||||
extern int localPal[0x100];
|
extern int localPal[0x100];
|
||||||
int i;
|
int c, i;
|
||||||
|
|
||||||
// don't clear old palette just for fun (but make it dark)
|
// don't clear old palette just for fun (but make it dark)
|
||||||
for (i = 0x100-1; i >= 0; i--)
|
for (i = 0x100-1; i >= 0; i--) {
|
||||||
localPal[i] = (localPal[i] >> 2) & 0x003f3f3f;
|
c = localPal[i];
|
||||||
|
localPal[i] = ((c >> 1) & 0x007f7f7f) - ((c >> 3) & 0x001f1f1f);
|
||||||
|
}
|
||||||
localPal[0xe0] = 0x00000000; // reserved pixels for OSD
|
localPal[0xe0] = 0x00000000; // reserved pixels for OSD
|
||||||
localPal[0xf0] = 0x00ffffff;
|
localPal[0xf0] = 0x00ffffff;
|
||||||
|
|
||||||
|
gp2x_video_setpalette(localPal, 0x100);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void menu_gfx_prepare(void)
|
||||||
|
{
|
||||||
|
menu_prepare_bg();
|
||||||
|
|
||||||
// switch to 8bpp
|
// switch to 8bpp
|
||||||
gp2x_video_changemode2(8);
|
gp2x_video_changemode2(8);
|
||||||
gp2x_video_RGB_setscaling(320, 240);
|
gp2x_video_RGB_setscaling(320, 240);
|
||||||
gp2x_video_setpalette(localPal, 0x100);
|
|
||||||
gp2x_video_flip2();
|
gp2x_video_flip2();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue