X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=platform%2Fgp2x%2Femu.c;h=24496fd458f08b59d8957b587d9186b5798dfe9c;hb=fa1e5e2948e9b06dec3353081081173f7ae4d742;hp=6e0021b1cb541aa96e43fd638f5947c9e8c0e850;hpb=8c1952f0d742014666df8ec2191458d9117625b5;p=picodrive.git diff --git a/platform/gp2x/emu.c b/platform/gp2x/emu.c index 6e0021b..24496fd 100644 --- a/platform/gp2x/emu.c +++ b/platform/gp2x/emu.c @@ -48,6 +48,7 @@ unsigned char *rom_data = NULL; extern int crashed_940; +static short sndBuffer[2*44100/50]; static char noticeMsg[64]; // notice msg to draw static struct timeval noticeMsgTime = { 0, 0 }; // when started showing static int reset_timing, osd_fps_x; @@ -79,14 +80,15 @@ static void strlwr(char* string) while ( (*string++ = (char)tolower(*string)) ); } -static int try_rfn_ext(char *ext) +static int try_rfn_cut(void) { FILE *tmp; char *p; - p = romFileName + strlen(romFileName) - 4; - if (p < romFileName) p = romFileName; - strcpy(p, ext); + p = romFileName + strlen(romFileName) - 1; + for (; p > romFileName; p--) + if (*p == '.') break; + *p = 0; if((tmp = fopen(romFileName, "rb"))) { fclose(tmp); @@ -95,29 +97,131 @@ static int try_rfn_ext(char *ext) return 0; } -static void get_ext(char *ext) +static void get_ext(char *file, char *ext) { char *p; - p = romFileName + strlen(romFileName) - 4; - if (p < romFileName) p = romFileName; + p = file + strlen(file) - 4; + if (p < file) p = file; strncpy(ext, p, 4); ext[4] = 0; 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_jp[] = { "jp_mcd1_9112", "jp_mcd1_9111" }; + +extern char **g_argv; + +int find_bios(int region, char **bios_file) +{ + static char bios_path[1024]; + int i, j, count; + char **files; + FILE *f = NULL; + + if (region == 4) { // US + files = biosfiles_us; + count = sizeof(biosfiles_us) / sizeof(char *); + } else if (region == 8) { // EU + files = biosfiles_eu; + count = sizeof(biosfiles_eu) / sizeof(char *); + } else if (region == 1 || region == 2) { + files = biosfiles_jp; + count = sizeof(biosfiles_jp) / sizeof(char *); + } else { + return 0; + } + + for (i = 0; i < count; i++) + { + strncpy(bios_path, g_argv[0], 1023); + bios_path[1024-32] = 0; + for (j = strlen(bios_path); j > 0; j--) + if (bios_path[j] == '/') { bios_path[j+1] = 0; break; } + strcat(bios_path, files[i]); + strcat(bios_path, ".bin"); + f = fopen(bios_path, "rb"); + if (f) break; + + bios_path[strlen(bios_path) - 4] = 0; + strcat(bios_path, ".zip"); + f = fopen(bios_path, "rb"); + if (f) break; + } + + if (f) { + printf("using bios: %s\n", bios_path); + fclose(f); + if (bios_file) *bios_file = bios_path; + return 1; + } else { + sprintf(menuErrorMsg, "no %s BIOS files found, read docs", + region != 4 ? (region == 8 ? "EU" : "JAP") : "USA"); + printf("%s\n", menuErrorMsg); + return 0; + } +} + +/* checks if romFileName points to valid MegaCD image + * if so, checks for suitable BIOS */ +static int cd_check(char *ext, char **bios_file) +{ + unsigned char buf[32]; + FILE *cd_f; + int type = 0, region = 4; // 1: Japan, 4: US, 8: Europe + + cd_f = fopen(romFileName, "rb"); + if (!cd_f) return 0; // let the upper level handle this + + if (fread(buf, 1, 32, cd_f) != 32) { + fclose(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); + 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); + + if (buf[0] == 0x64) region = 8; // EU + if (buf[0] == 0xa1) region = 1; // JAP + + printf("detected %s Sega/Mega CD image with %s region\n", + type == 2 ? "BIN" : "ISO", region != 4 ? (region == 8 ? "EU" : "JAP") : "USA"); + + if (PicoRegionOverride) { + region = PicoRegionOverride; + printf("overrided region to %s\n", region != 4 ? (region == 8 ? "EU" : "JAP") : "USA"); + } + + if(find_bios(region, bios_file)) + return type; // CD and BIOS detected + + return -1; // CD detected but load failed +} + int emu_ReloadRom(void) { unsigned int rom_size = 0; + char *used_rom_name = romFileName; char ext[5]; FILE *rom; - int ret; + int ret, cd_state; printf("emu_ReloadRom(%s)\n", romFileName); - // detect wrong extensions - get_ext(ext); + get_ext(romFileName, 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."); return 0; @@ -156,16 +260,28 @@ int emu_ReloadRom(void) sprintf(menuErrorMsg, "Invalid GMV file."); return 0; } - dummy = try_rfn_ext(".zip") || try_rfn_ext(".bin") || - try_rfn_ext(".smd") || try_rfn_ext(".gen"); + dummy = try_rfn_cut() || try_rfn_cut(); if (!dummy) { sprintf(menuErrorMsg, "Could't find a ROM for movie."); return 0; } - get_ext(ext); + get_ext(romFileName, ext); } - rom = fopen(romFileName, "rb"); + // check for MegaCD image + cd_state = cd_check(ext, &used_rom_name); + if (cd_state > 0) { + PicoMCD |= 1; + get_ext(used_rom_name, ext); + } else if (cd_state == -1) { + // bios_help() ? + return 0; + } else { + if (PicoMCD & 1) PicoExitMCD(); + PicoMCD &= ~1; + } + + rom = fopen(used_rom_name, "rb"); if(!rom) { sprintf(menuErrorMsg, "Failed to open rom."); return 0; @@ -180,9 +296,9 @@ int emu_ReloadRom(void) // zipfile support if(!strcasecmp(ext, ".zip")) { fclose(rom); - ret = CartLoadZip(romFileName, &rom_data, &rom_size); + ret = CartLoadZip(used_rom_name, &rom_data, &rom_size); if(ret) { - if (ret == 4) strcpy(menuErrorMsg, "No ROMs in zip found."); + 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; @@ -206,16 +322,28 @@ int emu_ReloadRom(void) return 0; } + // load config for this ROM (do this before insert to get correct region) + ret = emu_ReadConfig(1); + if (!ret) + emu_ReadConfig(0); + printf("PicoCartInsert(%p, %d);\n", rom_data, rom_size); if(PicoCartInsert(rom_data, rom_size)) { sprintf(menuErrorMsg, "Failed to load ROM."); return 0; } - // load config for this ROM - ret = emu_ReadConfig(1); - if (!ret) - emu_ReadConfig(0); + Pico.m.frame_count = 0; + + // insert CD if it was detected + if (cd_state > 0) { + ret = Insert_CD(romFileName, cd_state == 2); + if (ret != 0) { + sprintf(menuErrorMsg, "Insert_CD() failed, invalid CD image?"); + printf("%s\n", menuErrorMsg); + return 0; + } + } // emu_ReadConfig() might have messed currentConfig.lastRomFile strncpy(currentConfig.lastRomFile, romFileName, sizeof(currentConfig.lastRomFile)-1); @@ -253,8 +381,6 @@ int emu_ReloadRom(void) if(currentConfig.EmuOpt & 1) emu_SaveLoadGame(1, 1); - Pico.m.frame_count = 0; - return 1; } @@ -328,10 +454,11 @@ int emu_ReadConfig(int game) // set default config memset(¤tConfig, 0, sizeof(currentConfig)); currentConfig.lastRomFile[0] = 0; - currentConfig.EmuOpt = 0x1f; - currentConfig.PicoOpt = 0x0f; - currentConfig.PsndRate = 22050; + currentConfig.EmuOpt = 0x1f | 0x400; // | cd_leds + currentConfig.PicoOpt = 0x0f | 0xe00; // | use_940 | cd_pcm | cd_cdda + currentConfig.PsndRate = 22050; // 44100; currentConfig.PicoRegion = 0; // auto + currentConfig.PicoAutoRgnOrder = 0x184; // US, EU, JP currentConfig.Frameskip = -1; // auto currentConfig.CPUclock = 200; currentConfig.volume = 50; @@ -366,6 +493,7 @@ int emu_ReadConfig(int game) PicoOpt = currentConfig.PicoOpt; PsndRate = currentConfig.PsndRate; PicoRegionOverride = currentConfig.PicoRegion; + PicoAutoRgnOrder = currentConfig.PicoAutoRgnOrder; if (PicoOpt & 0x20) { actionNames[ 8] = "Z"; actionNames[ 9] = "Y"; actionNames[10] = "X"; actionNames[11] = "MODE"; @@ -403,6 +531,7 @@ int emu_WriteConfig(int game) currentConfig.PicoOpt = PicoOpt; currentConfig.PsndRate = PsndRate; currentConfig.PicoRegion = PicoRegionOverride; + currentConfig.PicoAutoRgnOrder = PicoAutoRgnOrder; bwrite = fwrite(¤tConfig, 1, sizeof(currentConfig), f); fflush(f); fclose(f); @@ -435,24 +564,19 @@ 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; if ((PicoOpt&0x10)||!(currentConfig.EmuOpt&0x80)) { - int *p, i, h, black, white; - if (PicoOpt&0x10) { - black = 0x40404040; white = 0x41; - } else { - black = 0xe0e0e0e0; white = 0xf0; - } + int *p, i, h; x &= ~3; // align x len = (len+3) >> 2; for (h = 0; h < 8; h++) { p = (int *) ((unsigned char *) gp2x_screen+x+320*(y+h)); - for (i = len; i; i--, p++) *p = black; + for (i = len; i; i--, p++) *p = 0xe0e0e0e0; } - gp2x_text_out8_2(x, y, text, white); + gp2x_text_out8_2(x, y, text, 0xf0); } else { int *p, i, h; x &= ~1; // align x @@ -465,6 +589,35 @@ void osd_text(int x, int y, char *text) } } +static void cd_leds(void) +{ + // mmu problems? +// static + int old_reg; +// if (!((Pico_mcd->s68k_regs[0] ^ old_reg) & 3)) return; // no change + old_reg = Pico_mcd->s68k_regs[0]; + + if ((PicoOpt&0x10)||!(currentConfig.EmuOpt&0x80)) { + // 8-bit modes + unsigned int col_g = (old_reg & 2) ? 0xc0c0c0c0 : 0xe0e0e0e0; + unsigned int col_r = (old_reg & 1) ? 0xd0d0d0d0 : 0xe0e0e0e0; + *(unsigned int *)((char *)gp2x_screen + 320*2+ 4) = + *(unsigned int *)((char *)gp2x_screen + 320*3+ 4) = + *(unsigned int *)((char *)gp2x_screen + 320*4+ 4) = col_g; + *(unsigned int *)((char *)gp2x_screen + 320*2+12) = + *(unsigned int *)((char *)gp2x_screen + 320*3+12) = + *(unsigned int *)((char *)gp2x_screen + 320*4+12) = col_r; + } else { + // 16-bit modes + unsigned int *p = (unsigned int *)((short *)gp2x_screen + 320*2+4); + unsigned int col_g = (old_reg & 2) ? 0x06000600 : 0; + unsigned int col_r = (old_reg & 1) ? 0xc000c000 : 0; + *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; p += 320/2 - 12/2; + *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; p += 320/2 - 12/2; + *p++ = col_g; *p++ = col_g; p+=2; *p++ = col_r; *p++ = col_r; p += 320/2 - 12/2; + } +} + static int EmuScan16(unsigned int num, void *sdata) { if (!(Pico.video.reg[1]&8)) num += 8; @@ -481,11 +634,13 @@ static int EmuScan8(unsigned int num, void *sdata) return 0; } -static int localPal[0x100]; +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; + if (PicoOpt&0x10) { // 8bit fast renderer if (Pico.m.dirtyPal) { @@ -495,7 +650,7 @@ static void blit(char *fps, char *notice) gp2x_video_setpalette(localPal, 0x40); } vidCpyM2((unsigned char *)gp2x_screen+320*8, framebuff+328*8); - } else if (!(currentConfig.EmuOpt&0x80)) { + } else if (!(emu_opt&0x80)) { // 8bit accurate renderer if (Pico.m.dirtyPal) { Pico.m.dirtyPal = 0; @@ -504,6 +659,8 @@ static void blit(char *fps, char *notice) vidConvCpyRGB32sh(localPal+0x40, Pico.cram, 0x40); vidConvCpyRGB32hi(localPal+0x80, Pico.cram, 0x40); blockcpy(localPal+0xc0, localPal+0x40, 0x40*4); + localPal[0xc0] = 0x0000c000; + localPal[0xd0] = 0x00c00000; localPal[0xe0] = 0x00000000; // reserved pixels for OSD localPal[0xf0] = 0x00ffffff; gp2x_video_setpalette(localPal, 0x100); @@ -520,8 +677,10 @@ static void blit(char *fps, char *notice) } if (notice) osd_text(4, 232, notice); - if (currentConfig.EmuOpt & 2) + if (emu_opt & 2) osd_text(osd_fps_x, 232, fps); + if ((emu_opt & 0x400) && (PicoMCD & 1)) + cd_leds(); //gp2x_video_wait_vsync(); gp2x_video_flip(); @@ -543,18 +702,14 @@ static void blit(char *fps, char *notice) // clears whole screen or just the notice area (in all buffers) static void clearArea(int full) { - if (PicoOpt&0x10) { - // 8bit fast renderer - if (full) gp2x_memset_all_buffers(0, 0x40, 320*240); - else gp2x_memset_all_buffers(320*232, 0x40, 320*8); - } else if (currentConfig.EmuOpt&0x80) { + if ((PicoOpt&0x10)||!(currentConfig.EmuOpt&0x80)) { + // 8-bit renderers + if (full) gp2x_memset_all_buffers(0, 0xe0, 320*240); + else gp2x_memset_all_buffers(320*232, 0xe0, 320*8); + } else { // 16bit accurate renderer if (full) gp2x_memset_all_buffers(0, 0, 320*240*2); else gp2x_memset_all_buffers(320*232*2, 0, 320*8*2); - } else { - // 8bit accurate renderer - if (full) gp2x_memset_all_buffers(0, 0xe0, 320*240); - else gp2x_memset_all_buffers(320*232, 0xe0, 320*8); } } @@ -562,27 +717,27 @@ static void clearArea(int full) static void vidResetMode(void) { if (PicoOpt&0x10) { - localPal[0x40] = 0; - localPal[0x41] = 0x00ffffff; gp2x_video_changemode(8); - gp2x_video_setpalette(localPal, 0x42); - gp2x_memset_all_buffers(0, 0x40, 320*240); - gp2x_video_flip(); } else if (currentConfig.EmuOpt&0x80) { gp2x_video_changemode(15); PicoDrawSetColorFormat(1); PicoScan = EmuScan16; PicoScan(0, 0); } else { + gp2x_video_changemode(8); + PicoDrawSetColorFormat(2); + PicoScan = EmuScan8; + PicoScan(0, 0); + } + if ((PicoOpt&0x10)||!(currentConfig.EmuOpt&0x80)) { + // setup pal for 8-bit modes + localPal[0xc0] = 0x0000c000; // MCD LEDs + localPal[0xd0] = 0x00c00000; localPal[0xe0] = 0x00000000; // reserved pixels for OSD localPal[0xf0] = 0x00ffffff; - gp2x_video_changemode(8); gp2x_video_setpalette(localPal, 0x100); gp2x_memset_all_buffers(0, 0xe0, 320*240); gp2x_video_flip(); - PicoDrawSetColorFormat(2); - PicoScan = EmuScan8; - PicoScan(0, 0); } Pico.m.dirtyPal = 1; // reset scaling @@ -609,6 +764,12 @@ static int check_save_file(void) return 0; } +static void emu_state_cb(const char *str) +{ + clearArea(0); + blit("", str); +} + static void RunEvents(unsigned int which) { if(which & 0x1800) { // save or load (but not both) @@ -622,10 +783,11 @@ static void RunEvents(unsigned int which) clearArea(0); } if (do_it) { - blit("", (which & 0x1000) ? "LOADING GAME" : "SAVING GAME"); - if(movie_data) { - } - 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; @@ -775,24 +937,10 @@ static void updateKeys(void) prevEvents = (allActions[0] | allActions[1]) >> 16; } -static int snd_excess_add = 0, snd_excess_cnt = 0; // hack -static void updateSound(void) +static void updateSound(int len) { - int len = (PicoOpt&8)?PsndLen*2:PsndLen; - - snd_excess_cnt += snd_excess_add; - if (snd_excess_cnt >= 0x10000) { - snd_excess_cnt -= 0x10000; - if (PicoOpt&8) { - PsndOut[len] = PsndOut[len-2]; - PsndOut[len+1] = PsndOut[len-1]; - len+=2; - } else { - PsndOut[len] = PsndOut[len-1]; - len++; - } - } + if (PicoOpt&8) len<<=1; gp2x_sound_write(PsndOut, len<<1); } @@ -862,6 +1010,7 @@ void emu_Loop(void) // make sure we are in correct mode vidResetMode(); + Pico.m.dirtyPal = 1; oldmodes = ((Pico.video.reg[12]&1)<<2) ^ 0xc; find_combos(); @@ -872,22 +1021,23 @@ void emu_Loop(void) // prepare sound stuff if(currentConfig.EmuOpt & 4) { + int snd_excess_add; if(PsndRate != PsndRate_old || (PicoOpt&0x20b) != (PicoOpt_old&0x20b) || Pico.m.pal != pal_old || crashed_940) { /* if 940 is turned off, we need it to be put back to sleep */ if (!(PicoOpt&0x200) && ((PicoOpt^PicoOpt_old)&0x200)) { - Reset940(1); + Reset940(1, 2); Pause940(1); } - sound_rerate(); + sound_rerate(1); } //excess_samples = PsndRate - PsndLen*target_fps; - snd_excess_cnt = 0; snd_excess_add = ((PsndRate - PsndLen*target_fps)<<16) / target_fps; printf("starting audio: %i len: %i (ex: %04x) stereo: %i, pal: %i\n", PsndRate, PsndLen, snd_excess_add, (PicoOpt&8)>>3, Pico.m.pal); gp2x_start_sound(PsndRate, 16, (PicoOpt&8)>>3); gp2x_sound_volume(currentConfig.volume, currentConfig.volume); PicoWriteSound = updateSound; - PsndOut = calloc((PicoOpt&8) ? (PsndLen*4+4) : (PsndLen*2+2), 1); + memset(sndBuffer, 0, sizeof(sndBuffer)); + PsndOut = sndBuffer; PsndRate_old = PsndRate; PsndLen_real = PsndLen; PicoOpt_old = PicoOpt; @@ -1083,14 +1233,23 @@ if (Pico.m.frame_count == 31563) { // save SRAM if((currentConfig.EmuOpt & 1) && SRam.changed) { + osd_text(4, 232, "Writing SRAM/BRAM.."); emu_SaveLoadGame(0, 1); SRam.changed = 0; } - if (PsndOut != 0) { - free(PsndOut); - PsndOut = 0; + // if in 16bit mode, generate 8it image for menu background + if (!(PicoOpt&0x10) && (currentConfig.EmuOpt&0x80)) { + PicoOpt |= 0x10; + 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 + gp2x_memcpy_all_buffers(gp2x_screen, 0, 320*240*2); } @@ -1112,7 +1271,6 @@ size_t gzWrite2(void *p, size_t _size, size_t _n, void *file) return gzwrite(file, p, _n); } -typedef unsigned int (*STATE_SL_FUNC)(void *, unsigned int, unsigned int, void *); int emu_SaveLoadGame(int load, int sram) { @@ -1121,7 +1279,7 @@ int emu_SaveLoadGame(int load, int sram) // make save filename romfname_ext(saveFname, ""); - if(sram) strcat(saveFname, ".srm"); + 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"); @@ -1131,30 +1289,41 @@ int emu_SaveLoadGame(int load, int sram) if(sram) { FILE *sramFile; - int sram_size = SRam.end-SRam.start+1; - if(SRam.reg_back & 4) sram_size=0x2000; - if(!SRam.data) return 0; // SRam forcefully disabled for this game + int sram_size; + unsigned char *sram_data; + if (PicoMCD&1) { + sram_size = 0x2000; + sram_data = Pico_mcd->bram; + } else { + sram_size = SRam.end-SRam.start+1; + if(SRam.reg_back & 4) sram_size=0x2000; + sram_data = SRam.data; + } + if(!sram_data) return 0; // SRam forcefully disabled for this game + if(load) { sramFile = fopen(saveFname, "rb"); if(!sramFile) return -1; - fread(SRam.data, 1, sram_size, sramFile); + fread(sram_data, 1, sram_size, sramFile); fclose(sramFile); } else { // sram save needs some special processing // see if we have anything to save for(; sram_size > 0; sram_size--) - if(SRam.data[sram_size-1]) break; + if(sram_data[sram_size-1]) break; if(sram_size) { sramFile = fopen(saveFname, "wb"); - ret = fwrite(SRam.data, 1, sram_size, sramFile); + ret = fwrite(sram_data, 1, sram_size, sramFile); ret = (ret != sram_size) ? -1 : 0; fclose(sramFile); sync(); } } return ret; - } else { + } + else + { void *PmovFile = NULL; // try gzip first if(currentConfig.EmuOpt & 8) { @@ -1162,26 +1331,34 @@ int emu_SaveLoadGame(int load, int sram) if( (PmovFile = gzopen(saveFname, load ? "rb" : "wb")) ) { areaRead = gzRead2; areaWrite = gzWrite2; + areaEof = (areaeof *) gzeof; + areaSeek = (areaseek *) gzseek; if(!load) gzsetparams(PmovFile, 9, Z_DEFAULT_STRATEGY); } else saveFname[strlen(saveFname)-3] = 0; } if(!PmovFile) { // gzip failed or was disabled if( (PmovFile = fopen(saveFname, load ? "rb" : "wb")) ) { - areaRead = (STATE_SL_FUNC) fread; - areaWrite = (STATE_SL_FUNC) fwrite; + areaRead = (arearw *) fread; + areaWrite = (arearw *) fwrite; + areaEof = (areaeof *) feof; + areaSeek = (areaseek *) fseek; } } if(PmovFile) { - PmovState(load ? 6 : 5, PmovFile); - strcpy(noticeMsg, load ? "GAME LOADED " : "GAME SAVED "); + ret = PmovState(load ? 6 : 5, PmovFile); if(areaRead == gzRead2) gzclose(PmovFile); else fclose ((FILE *) PmovFile); PmovFile = 0; if (!load) sync(); else Pico.m.dirtyPal=1; - } else { + } + else ret = -1; + if (!ret) + strcpy(noticeMsg, load ? "GAME LOADED " : "GAME SAVED "); + else + { strcpy(noticeMsg, load ? "LOAD FAILED " : "SAVE FAILED "); ret = -1; }