X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=common%2Femu.c;h=ae1a6383e2d5fdb2d7e1a4fcd69646bb26102982;hb=e9a133657214b3568bbac68eb4a0b4f521354745;hp=1bbdf35f72a3432b41539a14c1bebe2a5e6553e0;hpb=1ceda4176ff86029e143802e2b5999dd2d091e9c;p=libpicofe.git diff --git a/common/emu.c b/common/emu.c index 1bbdf35..ae1a638 100644 --- a/common/emu.c +++ b/common/emu.c @@ -18,6 +18,7 @@ #include #include +#include #include #if defined(__GP2X__) @@ -42,6 +43,7 @@ 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; unsigned char *movie_data = NULL; static int movie_size = 0; @@ -163,31 +165,54 @@ int emu_cdCheck(int *pregion) { unsigned char buf[32]; pm_file *cd_f; - int type = 0, region = 4; // 1: Japan, 4: US, 8: Europe - char ext[5]; + int region = 4; // 1: Japan, 4: US, 8: Europe + char ext[5], *fname = romFileName; + cue_track_type type = CT_UNKNOWN; + cue_data_t *cue_data = NULL; get_ext(romFileName, ext); + if (strcasecmp(ext, ".cue") == 0) { + cue_data = cue_parse(romFileName); + if (cue_data != NULL) { + fname = cue_data->tracks[1].fname; + type = cue_data->tracks[1].type; + } + else + return -1; + } + + cd_f = pm_open(fname); + if (cue_data != NULL) + cue_destroy(cue_data); - cd_f = pm_open(romFileName); - if (!cd_f) return 0; // let the upper level handle this + 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); @@ -195,14 +220,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; @@ -261,7 +286,7 @@ int emu_ReloadRom(void) char *used_rom_name = romFileName; 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); @@ -270,7 +295,7 @@ int emu_ReloadRom(void) // 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; } @@ -333,7 +358,7 @@ int emu_ReloadRom(void) // check for MegaCD image cd_state = emu_cdCheck(&cd_region); - if (cd_state != CIT_NOT_CD) + if (cd_state >= 0 && cd_state != CIT_NOT_CD) { PicoAHW |= PAHW_MCD; // valid CD image, check for BIOS.. @@ -363,8 +388,13 @@ int emu_ReloadRom(void) 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 @@ -375,19 +405,17 @@ int emu_ReloadRom(void) if ( (ret = PicoCartLoad(rom, &rom_data, &rom_size)) ) { 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) @@ -401,20 +429,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 != CIT_NOT_CD) { ret = Insert_CD(romFileName, cd_state); if (ret != 0) { sprintf(menuErrorMsg, "Insert_CD() failed, invalid CD image?"); lprintf("%s\n", menuErrorMsg); - menu_romload_end(); - return 0; + goto fail2; } } @@ -426,13 +450,14 @@ int emu_ReloadRom(void) } // additional movie stuff - if (movie_data) { - if(movie_data[0x14] == '6') + 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|POPT_ACC_TIMING; // accurate timing, no VDP fifo timing - if(movie_data[0xF] >= 'A') { - if(movie_data[0x16] & 0x80) { + PicoOpt |= POPT_DIS_VDP_FIFO; // no VDP fifo timing + if (movie_data[0xF] >= 'A') { + if (movie_data[0x16] & 0x80) { PicoRegionOverride = 8; } else { PicoRegionOverride = 4; @@ -446,7 +471,7 @@ int emu_ReloadRom(void) else { PicoOpt &= ~POPT_DIS_VDP_FIFO; - if(Pico.m.pal) { + if (Pico.m.pal) { strcpy(noticeMsg, "PAL SYSTEM / 50 FPS"); } else { strcpy(noticeMsg, "NTSC SYSTEM / 60 FPS"); @@ -462,6 +487,12 @@ int emu_ReloadRom(void) lastRomFile[sizeof(lastRomFile)-1] = 0; rom_loaded = 1; return 1; + +fail2: + menu_romload_end(); +fail: + if (rom != NULL) pm_close(rom); + return 0; } @@ -939,10 +970,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; } @@ -951,3 +982,81 @@ int emu_SaveLoadGame(int load, int sram) } } +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); +} +