X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=platform%2Fgp2x%2Femu.c;h=3d6cd3a2ca94d1959a1ab500b549a9e5eaec985c;hb=83bd0b76aba19ff62368cfee76089e15579e3b7c;hp=a5a46eac1dc276328fb4dc76f7723fe148662584;hpb=cea6590346640236914eeff840401c55db8a77ce;p=picodrive.git diff --git a/platform/gp2x/emu.c b/platform/gp2x/emu.c index a5a46ea..3d6cd3a 100644 --- a/platform/gp2x/emu.c +++ b/platform/gp2x/emu.c @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include #include #include @@ -19,8 +21,9 @@ #include "asmutils.h" #include "cpuctrl.h" -#include "Pico/PicoInt.h" -#include "zlib/zlib.h" +#include +#include +#include #ifdef BENCHMARK @@ -166,31 +169,31 @@ int find_bios(int region, char **bios_file) /* checks if romFileName points to valid MegaCD image * if so, checks for suitable BIOS */ -static int cd_check(char *ext, char **bios_file) +static int cd_check(char **bios_file) { unsigned char buf[32]; - FILE *cd_f; + pm_file *cd_f; int type = 0, region = 4; // 1: Japan, 4: US, 8: Europe - cd_f = fopen(romFileName, "rb"); + cd_f = pm_open(romFileName); if (!cd_f) return 0; // let the upper level handle this - if (fread(buf, 1, 32, cd_f) != 32) { - fclose(cd_f); + if (pm_read(buf, 32, cd_f) != 32) { + pm_close(cd_f); return 0; } if (!strncasecmp("SEGADISCSYSTEM", (char *)buf+0x00, 14)) type = 1; // Sega CD (ISO) if (!strncasecmp("SEGADISCSYSTEM", (char *)buf+0x10, 14)) type = 2; // Sega CD (BIN) if (type == 0) { - fclose(cd_f); + pm_close(cd_f); return 0; } /* it seems we have a CD image here. Try to detect region and load a suitable BIOS now.. */ - fseek(cd_f, (type == 1) ? 0x100+0x10B : 0x110+0x10B, SEEK_SET); - fread(buf, 1, 1, cd_f); - fclose(cd_f); + pm_seek(cd_f, (type == 1) ? 0x100+0x10B : 0x110+0x10B, SEEK_SET); + pm_read(buf, 1, cd_f); + pm_close(cd_f); if (buf[0] == 0x64) region = 8; // EU if (buf[0] == 0xa1) region = 1; // JAP @@ -214,7 +217,7 @@ int emu_ReloadRom(void) unsigned int rom_size = 0; char *used_rom_name = romFileName; char ext[5]; - FILE *rom; + pm_file *rom; int ret, cd_state; printf("emu_ReloadRom(%s)\n", romFileName); @@ -227,6 +230,8 @@ int emu_ReloadRom(void) return 0; } + PicoPatchUnload(); + // check for movie file if(movie_data) { free(movie_data); @@ -267,9 +272,19 @@ int emu_ReloadRom(void) } get_ext(romFileName, ext); } + else if (!strcmp(ext, ".pat")) { + int dummy; + PicoPatchLoad(romFileName); + dummy = try_rfn_cut() || try_rfn_cut(); + if (!dummy) { + sprintf(menuErrorMsg, "Could't find a ROM to patch."); + return 0; + } + get_ext(romFileName, ext); + } // check for MegaCD image - cd_state = cd_check(ext, &used_rom_name); + cd_state = cd_check(&used_rom_name); if (cd_state > 0) { PicoMCD |= 1; get_ext(used_rom_name, ext); @@ -281,7 +296,7 @@ int emu_ReloadRom(void) PicoMCD &= ~1; } - rom = fopen(used_rom_name, "rb"); + rom = pm_open(used_rom_name); if(!rom) { sprintf(menuErrorMsg, "Failed to open rom."); return 0; @@ -293,25 +308,13 @@ int emu_ReloadRom(void) rom_size = 0; } - // zipfile support - if(!strcasecmp(ext, ".zip")) { - fclose(rom); - ret = CartLoadZip(used_rom_name, &rom_data, &rom_size); - if(ret) { - if (ret == 4) strcpy(menuErrorMsg, "No ROMs found in zip."); - else sprintf(menuErrorMsg, "Unzip failed with code %i", ret); - printf("%s\n", menuErrorMsg); - return 0; - } - } else { - if( (ret = PicoCartLoad(rom, &rom_data, &rom_size)) ) { - sprintf(menuErrorMsg, "PicoCartLoad() failed."); - printf("%s\n", menuErrorMsg); - fclose(rom); - return 0; - } - fclose(rom); + if( (ret = PicoCartLoad(rom, &rom_data, &rom_size)) ) { + sprintf(menuErrorMsg, "PicoCartLoad() failed."); + printf("%s\n", menuErrorMsg); + pm_close(rom); + return 0; } + pm_close(rom); // detect wrong files (Pico crashes on very small files), also see if ROM EP is good if(rom_size <= 0x200 || strncmp((char *)rom_data, "Pico", 4) == 0 || @@ -349,6 +352,11 @@ int emu_ReloadRom(void) strncpy(currentConfig.lastRomFile, romFileName, sizeof(currentConfig.lastRomFile)-1); currentConfig.lastRomFile[sizeof(currentConfig.lastRomFile)-1] = 0; + if (PicoPatches) { + PicoPatchPrepare(); + PicoPatchApply(); + } + // additional movie stuff if(movie_data) { if(movie_data[0x14] == '6') @@ -394,22 +402,34 @@ void emu_Init(void) printf("framebuff == 0\n"); } + // make dirs for saves, cfgs, etc. + mkdir("mds", 0777); + mkdir("srm", 0777); + mkdir("brm", 0777); + mkdir("cfg", 0777); + PicoInit(); // 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; + int prefix_len = 0; // make save filename 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; - if(dst[strlen(dst)-4] == '.') dst[strlen(dst)-4] = 0; - strcat(dst, ext); + if (dst[strlen(dst)-4] == '.') dst[strlen(dst)-4] = 0; + if (ext) strcat(dst, ext); } @@ -479,7 +499,10 @@ int emu_ReadConfig(int game) strncpy(cfg, PicoConfigFile, 511); cfg[511] = 0; } 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); @@ -522,7 +545,7 @@ int emu_WriteConfig(int game) strncpy(cfg, PicoConfigFile, 511); cfg[511] = 0; } else { - romfname_ext(cfg, ".pbcfg"); + romfname_ext(cfg, "cfg", ".pbcfg"); } printf("emu_WriteConfig: %s ", cfg); @@ -564,7 +587,7 @@ void emu_Deinit(void) } -void osd_text(int x, int y, char *text) +void osd_text(int x, int y, const char *text) { int len = strlen(text)*8; @@ -637,7 +660,7 @@ static int EmuScan8(unsigned int num, void *sdata) int localPal[0x100]; static void (*vidCpyM2)(void *dest, void *src) = NULL; -static void blit(char *fps, char *notice) +static void blit(const char *fps, const char *notice) { int emu_opt = currentConfig.EmuOpt; @@ -745,30 +768,17 @@ static void vidResetMode(void) } -static int check_save_file(void) +static void emu_state_cb(const char *str) { - 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; + clearArea(0); + blit("", str); } static void RunEvents(unsigned int which) { if(which & 0x1800) { // save or load (but not both) 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; blit("", "OVERWRITE SAVE? (Y=yes, X=no)"); while( !((keys = gp2x_joystick_read(1)) & (GP2X_X|GP2X_Y)) ) @@ -777,8 +787,11 @@ static void RunEvents(unsigned int which) clearArea(0); } if (do_it) { - blit("", (which & 0x1000) ? "LOADING GAME" : "SAVING GAME"); - emu_SaveLoadGame(which & 0x1000, 0); + osd_text(4, 232, (which & 0x1000) ? "LOADING GAME" : "SAVING GAME"); + PicoStateProgressCB = emu_state_cb; + gp2x_memcpy_all_buffers(gp2x_screen, 0, 320*240*2); + emu_SaveLoadGame((which & 0x1000) >> 12, 0); + PicoStateProgressCB = NULL; } reset_timing = 1; @@ -808,7 +821,7 @@ static void RunEvents(unsigned int which) state_slot += 1; 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); } if(which & 0x0080) { @@ -955,6 +968,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_32col; + clearArea(1); + } else vidCpyM2 = vidCpyM2_40col; + + 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) { struct timeval tval; @@ -1224,19 +1255,17 @@ if (Pico.m.frame_count == 31563) { // save SRAM if((currentConfig.EmuOpt & 1) && SRam.changed) { - blit("", "Writing SRAM/BRAM.."); + osd_text(4, 232, "Writing SRAM/BRAM.."); emu_SaveLoadGame(0, 1); SRam.changed = 0; } // if in 16bit mode, generate 8it image for menu background - if (!(PicoOpt&0x10) && (currentConfig.EmuOpt&0x80)) { - PicoOpt |= 0x10; - Pico.m.dirtyPal = 1; - PicoFrameFull(); - blit("", NULL); blit("", NULL); blit("", NULL); blit("", NULL); // be sure buffer3 gets updated - PicoOpt &= ~0x10; - } + if (!(PicoOpt&0x10) && (currentConfig.EmuOpt&0x80)) + emu_forced_frame(); + + // for menu bg + gp2x_memcpy_buffers((1<<2), gp2x_screen, 0, 320*240*2); } @@ -1258,18 +1287,97 @@ size_t gzWrite2(void *p, size_t _size, size_t _n, void *file) 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 ret = 0; - char saveFname[512]; + char *saveFname; // make save filename - romfname_ext(saveFname, ""); - if(sram) strcat(saveFname, (PicoMCD&1) ? ".brm" : ".srm"); - else { - if(state_slot > 0 && state_slot < 10) sprintf(saveFname, "%s.%i", saveFname, state_slot); - strcat(saveFname, ".mds"); + saveFname = emu_GetSaveFName(load, sram, state_slot); + if (saveFname == NULL) { + if (!sram) { + strcpy(noticeMsg, load ? "LOAD FAILED (missing file)" : "SAVE FAILED "); + gettimeofday(¬iceMsgTime, 0); + } + return -1; } printf("saveLoad (%i, %i): %s\n", load, sram, saveFname); @@ -1312,31 +1420,21 @@ int emu_SaveLoadGame(int load, int sram) else { void *PmovFile = NULL; - // try gzip first - if(currentConfig.EmuOpt & 8) { - strcat(saveFname, ".gz"); + if (strcmp(saveFname + strlen(saveFname) - 3, ".gz") == 0) { if( (PmovFile = gzopen(saveFname, load ? "rb" : "wb")) ) { - areaRead = gzRead2; - areaWrite = gzWrite2; - areaEof = (areaeof *) gzeof; - areaSeek = (areaseek *) gzseek; + emu_set_save_cbs(1); 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")) ) { - areaRead = (arearw *) fread; - areaWrite = (arearw *) fwrite; - areaEof = (areaeof *) feof; - areaSeek = (areaseek *) fseek; + emu_set_save_cbs(0); } } if(PmovFile) { ret = PmovState(load ? 6 : 5, PmovFile); - if(areaRead == gzRead2) - gzclose(PmovFile); - else fclose ((FILE *) PmovFile); + areaClose(PmovFile); PmovFile = 0; if (!load) sync(); else Pico.m.dirtyPal=1;