X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=common%2Femu.c;h=7aac10b8463819f44e34da9f432111c22d90b098;hb=049a6b3e80151f6a5af726e25478ed15e111dfcc;hp=936665b5a0d2c94d39a0651b5b48d65bf92bc54e;hpb=367b6f1f939dcd7930d372aee0ca900b0b8790b1;p=libpicofe.git diff --git a/common/emu.c b/common/emu.c index 936665b..7aac10b 100644 --- a/common/emu.c +++ b/common/emu.c @@ -15,62 +15,52 @@ #include "fonts.h" #include "lprintf.h" #include "config.h" +#include "common.h" +#include "plat.h" -#include -#include +#include +#include +#include #include -#if defined(__GP2X__) - #include "../gp2x/gp2x.h" - #define SCREEN_WIDTH 320 - #define SCREEN_BUFFER gp2x_screen -#elif defined(__GIZ__) - #include "../gizmondo/giz.h" - #define SCREEN_WIDTH 321 - #define SCREEN_BUFFER giz_screen -#elif defined(PSP) - #include "../psp/psp.h" - #define SCREEN_WIDTH 512 - #define SCREEN_BUFFER psp_screen -#endif char *PicoConfigFile = "config.cfg"; currentConfig_t currentConfig, defaultConfig; -int rom_loaded = 0; -char noticeMsg[64]; +char noticeMsg[64] = { 0, }; int state_slot = 0; int config_slot = 0, config_slot_current = 0; -char lastRomFile[512]; +int kb_combo_keys = 0, kb_combo_acts = 0; // keys and actions which need button combos +int pico_inp_mode = 0; +int engineState = PGS_Menu; + +/* TODO: len checking */ +char rom_fname_reload[512] = { 0, }; +char rom_fname_loaded[512] = { 0, }; +int rom_loaded = 0; unsigned char *movie_data = NULL; static int movie_size = 0; -// provided by platform code: -extern char romFileName[]; -extern void emu_noticeMsgUpdated(void); -extern void emu_getMainDir(char *dst, int len); -extern void emu_setDefaultConfig(void); -extern void menu_romload_prepare(const char *rom_name); -extern void menu_romload_end(void); - // utilities -static void strlwr_(char* string) +static void strlwr_(char *string) { - while ( (*string++ = (char)tolower(*string)) ); + char *p; + for (p = string; *p; p++) + *p = (char)tolower(*p); } -static int try_rfn_cut(void) +static int try_rfn_cut(char *fname) { FILE *tmp; char *p; - p = romFileName + strlen(romFileName) - 1; - for (; p > romFileName; p--) + p = fname + strlen(fname) - 1; + for (; p > fname; p--) if (*p == '.') break; *p = 0; - if((tmp = fopen(romFileName, "rb"))) { + if((tmp = fopen(fname, "rb"))) { fclose(tmp); return 1; } @@ -88,8 +78,8 @@ static void get_ext(char *file, char *ext) strlwr_(ext); } -char *biosfiles_us[] = { "us_scd2_9306", "SegaCDBIOS9303", "us_scd1_9210" }; -char *biosfiles_eu[] = { "eu_mcd2_9306", "eu_mcd2_9303", "eu_mcd1_9210" }; +char *biosfiles_us[] = { "us_scd1_9210", "us_scd2_9306", "SegaCDBIOS9303" }; +char *biosfiles_eu[] = { "eu_mcd1_9210", "eu_mcd2_9306", "eu_mcd2_9303" }; char *biosfiles_jp[] = { "jp_mcd1_9112", "jp_mcd1_9111" }; int emu_findBios(int region, char **bios_file) @@ -156,34 +146,60 @@ static int emu_isBios(const char *name) static unsigned char id_header[0x100]; -/* checks if romFileName points to valid MegaCD image +/* checks if fname points to valid MegaCD image * if so, checks for suitable BIOS */ -int emu_cdCheck(int *pregion) +int emu_cdCheck(int *pregion, char *fname_in) { unsigned char buf[32]; pm_file *cd_f; - int type = 0, region = 4; // 1: Japan, 4: US, 8: Europe + int region = 4; // 1: Japan, 4: US, 8: Europe + char ext[5], *fname = fname_in; + cue_track_type type = CT_UNKNOWN; + cue_data_t *cue_data = NULL; + + get_ext(fname_in, ext); + if (strcasecmp(ext, ".cue") == 0) { + cue_data = cue_parse(fname_in); + if (cue_data != NULL) { + fname = cue_data->tracks[1].fname; + type = cue_data->tracks[1].type; + } + else + return -1; + } - cd_f = pm_open(romFileName); - if (!cd_f) return 0; // let the upper level handle this + cd_f = pm_open(fname); + if (cue_data != NULL) + cue_destroy(cue_data); + + if (cd_f == NULL) return 0; // let the upper level handle this if (pm_read(buf, 32, cd_f) != 32) { pm_close(cd_f); - return 0; + return -1; + } + + if (!strncasecmp("SEGADISCSYSTEM", (char *)buf+0x00, 14)) { + if (type && type != CT_ISO) + elprintf(EL_STATUS, ".cue has wrong type: %i", type); + type = CT_ISO; // Sega CD (ISO) + } + if (!strncasecmp("SEGADISCSYSTEM", (char *)buf+0x10, 14)) { + if (type && type != CT_BIN) + elprintf(EL_STATUS, ".cue has wrong type: %i", type); + type = CT_BIN; // Sega CD (BIN) } - 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) { + if (type == CT_UNKNOWN) { pm_close(cd_f); return 0; } - pm_seek(cd_f, (type == 1) ? 0x100 : 0x110, SEEK_SET); + pm_seek(cd_f, (type == CT_ISO) ? 0x100 : 0x110, SEEK_SET); pm_read(id_header, sizeof(id_header), cd_f); /* it seems we have a CD image here. Try to detect region now.. */ - pm_seek(cd_f, (type == 1) ? 0x100+0x10B : 0x110+0x10B, SEEK_SET); + pm_seek(cd_f, (type == CT_ISO) ? 0x100+0x10B : 0x110+0x10B, SEEK_SET); pm_read(buf, 1, cd_f); pm_close(cd_f); @@ -191,14 +207,14 @@ int emu_cdCheck(int *pregion) if (buf[0] == 0xa1) region = 1; // JAP lprintf("detected %s Sega/Mega CD image with %s region\n", - type == 2 ? "BIN" : "ISO", region != 4 ? (region == 8 ? "EU" : "JAP") : "USA"); + type == CT_BIN ? "BIN" : "ISO", region != 4 ? (region == 8 ? "EU" : "JAP") : "USA"); if (pregion != NULL) *pregion = region; return type; } -static int extract_text(char *dest, unsigned char *src, int len, int swab) +static int extract_text(char *dest, const unsigned char *src, int len, int swab) { char *p = dest; int i; @@ -231,40 +247,60 @@ static int extract_text(char *dest, unsigned char *src, int len, int swab) char *emu_makeRomId(void) { - static char id_string[3+0x11+0x11+0x30+16]; - int pos; + static char id_string[3+0xe*3+0x3*3+0x30*3+3]; + int pos, swab = 1; - if (PicoMCD & 1) - strcpy(id_string, "CD|"); + if (PicoAHW & PAHW_MCD) { + strcpy(id_string, "CD|"); + swab = 0; + } else strcpy(id_string, "MD|"); pos = 3; - pos += extract_text(id_string + pos, id_header + 0x80, 0x0e, 1); // serial + pos += extract_text(id_string + pos, id_header + 0x80, 0x0e, swab); // serial id_string[pos] = '|'; pos++; - pos += extract_text(id_string + pos, id_header + 0xf0, 0x03, 1); // region + pos += extract_text(id_string + pos, id_header + 0xf0, 0x03, swab); // region id_string[pos] = '|'; pos++; - pos += extract_text(id_string + pos, id_header + 0x50, 0x30, 1); // overseas name + pos += extract_text(id_string + pos, id_header + 0x50, 0x30, swab); // overseas name id_string[pos] = 0; return id_string; } -int emu_ReloadRom(void) +// buffer must be at least 150 byte long +void emu_getGameName(char *str150) +{ + int ret, swab = (PicoAHW & PAHW_MCD) ? 0 : 1; + char *s, *d; + + ret = extract_text(str150, id_header + 0x50, 0x30, swab); // overseas name + + for (s = d = str150 + 1; s < str150+ret; s++) + { + if (*s == 0) break; + if (*s != ' ' || d[-1] != ' ') + *d++ = *s; + } + *d = 0; +} + +// note: this function might mangle rom_fname +int emu_ReloadRom(char *rom_fname) { unsigned int rom_size = 0; - char *used_rom_name = romFileName; + char *used_rom_name = rom_fname; unsigned char *rom_data = NULL; char ext[5]; - pm_file *rom; + pm_file *rom = NULL; int ret, cd_state, cd_region, cfg_loaded = 0; - lprintf("emu_ReloadRom(%s)\n", romFileName); + lprintf("emu_ReloadRom(%s)\n", rom_fname); - get_ext(romFileName, ext); + get_ext(rom_fname, ext); // detect wrong extensions if (!strcmp(ext, ".srm") || !strcmp(ext, "s.gz") || !strcmp(ext, ".mds")) { // s.gz ~ .mds.gz - sprintf(menuErrorMsg, "Not a ROM selected."); + sprintf(menuErrorMsg, "Not a ROM/CD selected."); return 0; } @@ -275,10 +311,11 @@ int emu_ReloadRom(void) free(movie_data); movie_data = 0; } - if (!strcmp(ext, ".gmv")) { + if (!strcmp(ext, ".gmv")) + { // check for both gmv and rom int dummy; - FILE *movie_file = fopen(romFileName, "rb"); + FILE *movie_file = fopen(rom_fname, "rb"); if(!movie_file) { sprintf(menuErrorMsg, "Failed to open movie."); return 0; @@ -303,31 +340,33 @@ int emu_ReloadRom(void) sprintf(menuErrorMsg, "Invalid GMV file."); return 0; } - dummy = try_rfn_cut() || try_rfn_cut(); + dummy = try_rfn_cut(rom_fname) || try_rfn_cut(rom_fname); if (!dummy) { sprintf(menuErrorMsg, "Could't find a ROM for movie."); return 0; } - get_ext(romFileName, ext); + get_ext(rom_fname, ext); + lprintf("gmv loaded for %s\n", rom_fname); } - else if (!strcmp(ext, ".pat")) { + else if (!strcmp(ext, ".pat")) + { int dummy; - PicoPatchLoad(romFileName); - dummy = try_rfn_cut() || try_rfn_cut(); + PicoPatchLoad(rom_fname); + dummy = try_rfn_cut(rom_fname) || try_rfn_cut(rom_fname); if (!dummy) { sprintf(menuErrorMsg, "Could't find a ROM to patch."); return 0; } - get_ext(romFileName, ext); + get_ext(rom_fname, ext); } - if ((PicoMCD & 1) && Pico_mcd != NULL) - Stop_CD(); + emu_shutdownMCD(); // check for MegaCD image - cd_state = emu_cdCheck(&cd_region); - if (cd_state > 0) + cd_state = emu_cdCheck(&cd_region, rom_fname); + if (cd_state >= 0 && cd_state != CIT_NOT_CD) { + PicoAHW |= PAHW_MCD; // valid CD image, check for BIOS.. // we need to have config loaded at this point @@ -341,22 +380,27 @@ int emu_ReloadRom(void) } if (!emu_findBios(cd_region, &used_rom_name)) { // bios_help() ? + PicoAHW &= ~PAHW_MCD; return 0; } - PicoMCD |= 1; get_ext(used_rom_name, ext); } else { - if (PicoMCD & 1) Stop_CD(); - PicoMCD &= ~1; + if (PicoAHW & PAHW_MCD) Stop_CD(); + PicoAHW &= ~PAHW_MCD; } rom = pm_open(used_rom_name); if (!rom) { - sprintf(menuErrorMsg, "Failed to open rom."); - return 0; + sprintf(menuErrorMsg, "Failed to open ROM/CD image"); + goto fail; + } + + if (cd_state < 0) { + sprintf(menuErrorMsg, "Invalid CD image"); + goto fail; } menu_romload_prepare(used_rom_name); // also CD load @@ -365,25 +409,25 @@ int emu_ReloadRom(void) rom_loaded = 0; if ( (ret = PicoCartLoad(rom, &rom_data, &rom_size)) ) { - sprintf(menuErrorMsg, "PicoCartLoad() failed."); + if (ret == 2) sprintf(menuErrorMsg, "Out of memory"); + else if (ret == 3) sprintf(menuErrorMsg, "Read failed"); + else sprintf(menuErrorMsg, "PicoCartLoad() failed."); lprintf("%s\n", menuErrorMsg); - pm_close(rom); - menu_romload_end(); - return 0; + goto fail2; } pm_close(rom); + rom = NULL; // 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 || ((*(unsigned char *)(rom_data+4)<<16)|(*(unsigned short *)(rom_data+6))) >= (int)rom_size) { if (rom_data) free(rom_data); sprintf(menuErrorMsg, "Not a ROM selected."); - menu_romload_end(); - return 0; + goto fail2; } // load config for this ROM (do this before insert to get correct region) - if (!(PicoMCD&1)) + if (!(PicoAHW & PAHW_MCD)) memcpy(id_header, rom_data + 0x100, sizeof(id_header)); if (!cfg_loaded) { ret = emu_ReadConfig(1, 1); @@ -393,20 +437,16 @@ int emu_ReloadRom(void) lprintf("PicoCartInsert(%p, %d);\n", rom_data, rom_size); if (PicoCartInsert(rom_data, rom_size)) { sprintf(menuErrorMsg, "Failed to load ROM."); - menu_romload_end(); - return 0; + goto fail2; } - Pico.m.frame_count = 0; - // insert CD if it was detected - if (cd_state > 0) { - ret = Insert_CD(romFileName, cd_state == 2); + if (cd_state != CIT_NOT_CD) { + ret = Insert_CD(rom_fname, cd_state); if (ret != 0) { sprintf(menuErrorMsg, "Insert_CD() failed, invalid CD image?"); lprintf("%s\n", menuErrorMsg); - menu_romload_end(); - return 0; + goto fail2; } } @@ -418,18 +458,19 @@ int emu_ReloadRom(void) } // additional movie stuff - if (movie_data) { - if(movie_data[0x14] == '6') - PicoOpt |= 0x20; // 6 button pad - else PicoOpt &= ~0x20; - PicoOpt |= 0x10040; // accurate timing, no VDP fifo timing - if(movie_data[0xF] >= 'A') { - if(movie_data[0x16] & 0x80) { + if (movie_data) + { + if (movie_data[0x14] == '6') + PicoOpt |= POPT_6BTN_PAD; // 6 button pad + else PicoOpt &= ~POPT_6BTN_PAD; + PicoOpt |= POPT_DIS_VDP_FIFO; // no VDP fifo timing + if (movie_data[0xF] >= 'A') { + if (movie_data[0x16] & 0x80) { PicoRegionOverride = 8; } else { PicoRegionOverride = 4; } - PicoReset(0); + PicoReset(); // TODO: bits 6 & 5 } movie_data[0x18+30] = 0; @@ -437,8 +478,8 @@ int emu_ReloadRom(void) } else { - PicoOpt &= ~0x10000; - if(Pico.m.pal) { + PicoOpt &= ~POPT_DIS_VDP_FIFO; + if (Pico.m.pal) { strcpy(noticeMsg, "PAL SYSTEM / 50 FPS"); } else { strcpy(noticeMsg, "NTSC SYSTEM / 60 FPS"); @@ -447,28 +488,46 @@ int emu_ReloadRom(void) emu_noticeMsgUpdated(); // load SRAM for this ROM - if (currentConfig.EmuOpt & 1) + if (currentConfig.EmuOpt & EOPT_USE_SRAM) emu_SaveLoadGame(1, 1); - strncpy(lastRomFile, romFileName, sizeof(lastRomFile)-1); - lastRomFile[sizeof(lastRomFile)-1] = 0; + strncpy(rom_fname_loaded, rom_fname, sizeof(rom_fname_loaded)-1); + rom_fname_loaded[sizeof(rom_fname_loaded)-1] = 0; rom_loaded = 1; return 1; + +fail2: + menu_romload_end(); +fail: + if (rom != NULL) pm_close(rom); + return 0; } +void emu_shutdownMCD(void) +{ + if ((PicoAHW & PAHW_MCD) && Pico_mcd != NULL) + Stop_CD(); + PicoAHW &= ~PAHW_MCD; +} + 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++; + p = rom_fname_loaded + strlen(rom_fname_loaded) - 1; + for (; p >= rom_fname_loaded && *p != PATH_SEP_C; p--); p++; *dst = 0; if (prefix) { - strcpy(dst, prefix); - prefix_len = strlen(prefix); + int len = emu_getMainDir(dst, 512); + strcpy(dst + len, prefix); + prefix_len = len + strlen(prefix); } +#ifdef UIQ3 + else p = rom_fname_loaded; // backward compatibility +#endif strncpy(dst + prefix_len, p, 511-prefix_len); dst[511-8] = 0; if (dst[strlen(dst)-4] == '.') dst[strlen(dst)-4] = 0; @@ -476,24 +535,55 @@ static void romfname_ext(char *dst, const char *prefix, const char *ext) } +static void make_config_cfg(char *cfg) +{ + int len; + len = emu_getMainDir(cfg, 512); + strncpy(cfg + len, PicoConfigFile, 512-6-1-len); + if (config_slot != 0) + { + char *p = strrchr(cfg, '.'); + if (p == NULL) p = cfg + strlen(cfg); + sprintf(p, ".%i.cfg", config_slot); + } + cfg[511] = 0; +} + +void emu_packConfig(void) +{ + currentConfig.s_PicoOpt = PicoOpt; + currentConfig.s_PsndRate = PsndRate; + currentConfig.s_PicoRegion = PicoRegionOverride; + currentConfig.s_PicoAutoRgnOrder = PicoAutoRgnOrder; + currentConfig.s_PicoCDBuffers = PicoCDBuffers; +} + +void emu_unpackConfig(void) +{ + PicoOpt = currentConfig.s_PicoOpt; + PsndRate = currentConfig.s_PsndRate; + PicoRegionOverride = currentConfig.s_PicoRegion; + PicoAutoRgnOrder = currentConfig.s_PicoAutoRgnOrder; + PicoCDBuffers = currentConfig.s_PicoCDBuffers; +} + +static void emu_setDefaultConfig(void) +{ + memcpy(¤tConfig, &defaultConfig, sizeof(currentConfig)); + emu_unpackConfig(); +} + + int emu_ReadConfig(int game, int no_defaults) { char cfg[512]; - FILE *f; int ret; if (!game) { if (!no_defaults) emu_setDefaultConfig(); - strncpy(cfg, PicoConfigFile, 511); - if (config_slot != 0) - { - char *p = strrchr(cfg, '.'); - if (p == NULL) p = cfg + strlen(cfg); - sprintf(p, ".%i.cfg", config_slot); - } - cfg[511] = 0; + make_config_cfg(cfg); ret = config_readsect(cfg, NULL); } else @@ -506,42 +596,23 @@ int emu_ReadConfig(int game, int no_defaults) else strcpy(cfg, "game.cfg"); ret = -1; - if (config_havesect(cfg, sect)) { + if (config_havesect(cfg, sect)) + { + // read user's config + int vol = currentConfig.volume; emu_setDefaultConfig(); ret = config_readsect(cfg, sect); + currentConfig.volume = vol; // make vol global (bah) } - - if (ret != 0) + else { - // fall back to old - char extbuf[16]; - if (config_slot != 0) - sprintf(extbuf, ".%i.pbcfg", config_slot); - else strcpy(extbuf, ".pbcfg"); - romfname_ext(cfg, "cfg/", extbuf); - f = fopen(cfg, "rb"); - if (!f) { - romfname_ext(cfg, NULL, ".pbcfg"); - f = fopen(cfg, "rb"); - } - if (f) { - int bread; - fseek(f, 512, SEEK_SET); // skip unused lrom buffer - bread = fread(¤tConfig, 1, sizeof(currentConfig), f); - lprintf("emu_ReadConfig: %s %s\n", cfg, bread > 0 ? "(ok)" : "(failed)"); - fclose(f); - ret = 0; - } - - if (ret == 0) { - PicoOpt = currentConfig.s_PicoOpt; - PsndRate = currentConfig.s_PsndRate; - PicoRegionOverride = currentConfig.s_PicoRegion; - PicoAutoRgnOrder = currentConfig.s_PicoAutoRgnOrder; - PicoCDBuffers = currentConfig.s_PicoCDBuffers; - } + // read global config, and apply game_def.cfg on top + make_config_cfg(cfg); + config_readsect(cfg, NULL); + ret = config_readsect("game_def.cfg", sect); } - else + + if (ret == 0) { lprintf("loaded cfg from sect \"%s\"\n", sect); } @@ -551,6 +622,7 @@ int emu_ReadConfig(int game, int no_defaults) if (currentConfig.CPUclock < 10 || currentConfig.CPUclock > 4096) currentConfig.CPUclock = 200; #ifdef PSP if (currentConfig.gamma < -4 || currentConfig.gamma > 16) currentConfig.gamma = 0; + if (currentConfig.gamma2 < 0 || currentConfig.gamma2 > 2) currentConfig.gamma2 = 0; #else if (currentConfig.gamma < 10 || currentConfig.gamma > 300) currentConfig.gamma = 100; #endif @@ -574,14 +646,7 @@ int emu_WriteConfig(int is_game) if (!is_game) { - strncpy(cfg, PicoConfigFile, 511); - if (config_slot != 0) - { - char *p = strrchr(cfg, '.'); - if (p == NULL) p = cfg + strlen(cfg); - sprintf(p, ".%i.cfg", config_slot); - } - cfg[511] = 0; + make_config_cfg(cfg); write_lrom = 1; } else { if (config_slot != 0) @@ -604,6 +669,17 @@ int emu_WriteConfig(int is_game) } +void emu_writelrom(void) +{ + char cfg[512]; + make_config_cfg(cfg); + config_writelrom(cfg); +#ifndef NO_SYNC + sync(); +#endif +} + +#ifndef UIQ3 void emu_textOut8(int x, int y, const char *text) { int i,l,len=strlen(text); @@ -650,6 +726,54 @@ void emu_textOut16(int x, int y, const char *text) screen += 8; } } +#endif + +#ifdef PSP +#define MAX_COMBO_KEY 23 +#else +#define MAX_COMBO_KEY 31 +#endif + +void emu_findKeyBindCombos(void) +{ + int act, u; + + // find out which keys and actions are combos + kb_combo_keys = kb_combo_acts = 0; + for (act = 0; act < 32; act++) + { + int keyc = 0, keyc2 = 0; + if (act == 16 || act == 17) continue; // player2 flag + if (act > 17) + { + for (u = 0; u <= MAX_COMBO_KEY; u++) + if (currentConfig.KeyBinds[u] & (1 << act)) keyc++; + } + else + { + for (u = 0; u <= MAX_COMBO_KEY; u++) + if ((currentConfig.KeyBinds[u] & 0x30000) == 0 && // pl. 1 + (currentConfig.KeyBinds[u] & (1 << act))) keyc++; + for (u = 0; u <= MAX_COMBO_KEY; u++) + if ((currentConfig.KeyBinds[u] & 0x30000) == 1 && // pl. 2 + (currentConfig.KeyBinds[u] & (1 << act))) keyc2++; + if (keyc2 > keyc) keyc = keyc2; + } + if (keyc > 1) + { + // loop again and mark those keys and actions as combo + for (u = 0; u <= MAX_COMBO_KEY; u++) + { + if (currentConfig.KeyBinds[u] & (1 << act)) { + kb_combo_keys |= 1 << u; + kb_combo_acts |= 1 << act; + } + } + } + } + + // printf("combo keys/acts: %08x %08x\n", kb_combo_keys, kb_combo_acts); +} void emu_updateMovie(void) @@ -664,13 +788,13 @@ void emu_updateMovie(void) } else { // MXYZ SACB RLDU PicoPad[0] = ~movie_data[offs] & 0x8f; // ! SCBA RLDU - if(!(movie_data[offs] & 0x10)) PicoPad[0] |= 0x40; // A - if(!(movie_data[offs] & 0x20)) PicoPad[0] |= 0x10; // B - if(!(movie_data[offs] & 0x40)) PicoPad[0] |= 0x20; // A + if(!(movie_data[offs] & 0x10)) PicoPad[0] |= 0x40; // C + if(!(movie_data[offs] & 0x20)) PicoPad[0] |= 0x10; // A + if(!(movie_data[offs] & 0x40)) PicoPad[0] |= 0x20; // B PicoPad[1] = ~movie_data[offs+1] & 0x8f; // ! SCBA RLDU - if(!(movie_data[offs+1] & 0x10)) PicoPad[1] |= 0x40; // A - if(!(movie_data[offs+1] & 0x20)) PicoPad[1] |= 0x10; // B - if(!(movie_data[offs+1] & 0x40)) PicoPad[1] |= 0x20; // A + if(!(movie_data[offs+1] & 0x10)) PicoPad[1] |= 0x40; // C + if(!(movie_data[offs+1] & 0x20)) PicoPad[1] |= 0x10; // A + if(!(movie_data[offs+1] & 0x40)) PicoPad[1] |= 0x20; // B PicoPad[0] |= (~movie_data[offs+2] & 0x0A) << 8; // ! MZYX if(!(movie_data[offs+2] & 0x01)) PicoPad[0] |= 0x0400; // X if(!(movie_data[offs+2] & 0x04)) PicoPad[0] |= 0x0100; // Z @@ -711,11 +835,11 @@ char *emu_GetSaveFName(int load, int is_sram, int slot) if (is_sram) { - romfname_ext(saveFname, (PicoMCD&1) ? "brm/" : "srm/", (PicoMCD&1) ? ".brm" : ".srm"); + romfname_ext(saveFname, (PicoAHW&1) ? "brm"PATH_SEP : "srm"PATH_SEP, (PicoAHW&1) ? ".brm" : ".srm"); if (load) { if (try_ropen_file(saveFname)) return saveFname; // try in current dir.. - romfname_ext(saveFname, NULL, (PicoMCD&1) ? ".brm" : ".srm"); + romfname_ext(saveFname, NULL, (PicoAHW & PAHW_MCD) ? ".brm" : ".srm"); if (try_ropen_file(saveFname)) return saveFname; return NULL; // give up } @@ -724,19 +848,21 @@ char *emu_GetSaveFName(int load, int is_sram, int slot) { ext[0] = 0; if(slot > 0 && slot < 10) sprintf(ext, ".%i", slot); - strcat(ext, (currentConfig.EmuOpt & 8) ? ".mds.gz" : ".mds"); + strcat(ext, (currentConfig.EmuOpt & EOPT_GZIP_SAVES) ? ".mds.gz" : ".mds"); - romfname_ext(saveFname, "mds/", ext); + romfname_ext(saveFname, "mds" PATH_SEP, 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) { + // no gzipped states, search for non-gzipped + if (currentConfig.EmuOpt & EOPT_GZIP_SAVES) + { ext[0] = 0; if(slot > 0 && slot < 10) sprintf(ext, ".%i", slot); strcat(ext, ".mds"); - romfname_ext(saveFname, "mds/", ext); + romfname_ext(saveFname, "mds"PATH_SEP, ext); if (try_ropen_file(saveFname)) return saveFname; romfname_ext(saveFname, NULL, ext); if (try_ropen_file(saveFname)) return saveFname; @@ -793,8 +919,9 @@ int emu_SaveLoadGame(int load, int sram) int sram_size; unsigned char *sram_data; int truncate = 1; - if (PicoMCD&1) { - if (PicoOpt&0x8000) { // MCD RAM cart? + if (PicoAHW & PAHW_MCD) + { + if (PicoOpt&POPT_EN_MCD_RAMCART) { sram_size = 0x12000; sram_data = SRam.data; if (sram_data) @@ -811,12 +938,13 @@ int emu_SaveLoadGame(int load, int sram) } if (!sram_data) return 0; // SRam forcefully disabled for this game - if (load) { + if (load) + { sramFile = fopen(saveFname, "rb"); if(!sramFile) return -1; fread(sram_data, 1, sram_size, sramFile); fclose(sramFile); - if ((PicoMCD&1) && (PicoOpt&0x8000)) + if ((PicoAHW & PAHW_MCD) && (PicoOpt&POPT_EN_MCD_RAMCART)) memcpy32((int *)Pico_mcd->bram, (int *)sram_data, 0x2000/4); } else { // sram save needs some special processing @@ -865,10 +993,10 @@ int emu_SaveLoadGame(int load, int sram) } else ret = -1; if (!ret) - strcpy(noticeMsg, load ? "GAME LOADED " : "GAME SAVED "); + strcpy(noticeMsg, load ? "GAME LOADED " : "GAME SAVED "); else { - strcpy(noticeMsg, load ? "LOAD FAILED " : "SAVE FAILED "); + strcpy(noticeMsg, load ? "LOAD FAILED " : "SAVE FAILED "); ret = -1; } @@ -876,3 +1004,82 @@ int emu_SaveLoadGame(int load, int sram) return ret; } } + +void emu_changeFastForward(int set_on) +{ + static void *set_PsndOut = NULL; + static int set_Frameskip, set_EmuOpt, is_on = 0; + + if (set_on && !is_on) { + set_PsndOut = PsndOut; + set_Frameskip = currentConfig.Frameskip; + set_EmuOpt = currentConfig.EmuOpt; + PsndOut = NULL; + currentConfig.Frameskip = 8; + currentConfig.EmuOpt &= ~4; + currentConfig.EmuOpt |= 0x40000; + is_on = 1; + strcpy(noticeMsg, "FAST FORWARD "); + emu_noticeMsgUpdated(); + } + else if (!set_on && is_on) { + PsndOut = set_PsndOut; + currentConfig.Frameskip = set_Frameskip; + currentConfig.EmuOpt = set_EmuOpt; + PsndRerate(1); + is_on = 0; + } +} + +void emu_RunEventsPico(unsigned int events) +{ + if (events & (1 << 3)) { + pico_inp_mode++; + if (pico_inp_mode > 2) pico_inp_mode = 0; + switch (pico_inp_mode) { + case 2: strcpy(noticeMsg, "Input: Pen on Pad "); break; + case 1: strcpy(noticeMsg, "Input: Pen on Storyware"); break; + case 0: strcpy(noticeMsg, "Input: Joytick "); + PicoPicohw.pen_pos[0] = PicoPicohw.pen_pos[1] = 0x8000; + break; + } + emu_noticeMsgUpdated(); + } + if (events & (1 << 4)) { + PicoPicohw.page--; + if (PicoPicohw.page < 0) PicoPicohw.page = 0; + sprintf(noticeMsg, "Page %i ", PicoPicohw.page); + emu_noticeMsgUpdated(); + } + if (events & (1 << 5)) { + PicoPicohw.page++; + if (PicoPicohw.page > 6) PicoPicohw.page = 6; + sprintf(noticeMsg, "Page %i ", PicoPicohw.page); + emu_noticeMsgUpdated(); + } +} + +void emu_DoTurbo(int *pad, int acts) +{ + static int turbo_pad = 0; + static unsigned char turbo_cnt[3] = { 0, 0, 0 }; + int inc = currentConfig.turbo_rate * 2; + + if (acts & 0x1000) { + turbo_cnt[0] += inc; + if (turbo_cnt[0] >= 60) + turbo_pad ^= 0x10, turbo_cnt[0] = 0; + } + if (acts & 0x2000) { + turbo_cnt[1] += inc; + if (turbo_cnt[1] >= 60) + turbo_pad ^= 0x20, turbo_cnt[1] = 0; + } + if (acts & 0x4000) { + turbo_cnt[2] += inc; + if (turbo_cnt[2] >= 60) + turbo_pad ^= 0x40, turbo_cnt[2] = 0; + } + *pad |= turbo_pad & (acts >> 8); +} +