int YabLoadState(const char *filename) { FILE *fp; char id[3]; u8 endian; int headerversion, version, size, chunksize, headersize; IOCheck_struct check; u8* buf; int totalsize; int outputwidth; int outputheight; int curroutputwidth; int curroutputheight; int movieposition; int temp; u32 temp32; filename = MakeMovieStateName(filename); if (!filename) return -1; if ((fp = fopen(filename, "rb")) == NULL) return -1; headersize = 0xC; // Read signature yread(&check, (void *)id, 1, 3, fp); if (strncmp(id, "YSS", 3) != 0) { fclose(fp); return -2; } // Read header yread(&check, (void *)&endian, 1, 1, fp); yread(&check, (void *)&headerversion, 4, 1, fp); yread(&check, (void *)&size, 4, 1, fp); switch(headerversion) { case 1: /* This is the "original" version of the format */ break; case 2: /* version 2 adds video recording */ yread(&check, (void *)&framecounter, 4, 1, fp); movieposition=ftell(fp); yread(&check, (void *)&movieposition, 4, 1, fp); headersize = 0x14; break; default: /* we're trying to open a save state using a future version * of the YSS format, that won't work, sorry :) */ fclose(fp); return -3; break; } #ifdef WORDS_BIGENDIAN if (endian == 1) #else if (endian == 0) #endif { // should setup reading so it's byte-swapped YabSetError(YAB_ERR_OTHER, (void *)"Load State byteswapping not supported"); fclose(fp); return -3; } // Make sure size variable matches actual size minus header fseek(fp, 0, SEEK_END); if (size != (ftell(fp) - headersize)) { fclose(fp); return -2; } fseek(fp, headersize, SEEK_SET); // Verify version here ScspMuteAudio(SCSP_MUTE_SYSTEM); if (StateCheckRetrieveHeader(fp, "CART", &version, &chunksize) != 0) { fclose(fp); // Revert back to old state here ScspUnMuteAudio(SCSP_MUTE_SYSTEM); return -3; } CartLoadState(fp, version, chunksize); if (StateCheckRetrieveHeader(fp, "CS2 ", &version, &chunksize) != 0) { fclose(fp); // Revert back to old state here ScspUnMuteAudio(SCSP_MUTE_SYSTEM); return -3; } Cs2LoadState(fp, version, chunksize); if (StateCheckRetrieveHeader(fp, "MSH2", &version, &chunksize) != 0) { fclose(fp); // Revert back to old state here ScspUnMuteAudio(SCSP_MUTE_SYSTEM); return -3; } SH2LoadState(MSH2, fp, version, chunksize); if (StateCheckRetrieveHeader(fp, "SSH2", &version, &chunksize) != 0) { fclose(fp); // Revert back to old state here ScspUnMuteAudio(SCSP_MUTE_SYSTEM); return -3; } SH2LoadState(SSH2, fp, version, chunksize); if (StateCheckRetrieveHeader(fp, "SCSP", &version, &chunksize) != 0) { fclose(fp); // Revert back to old state here ScspUnMuteAudio(SCSP_MUTE_SYSTEM); return -3; } SoundLoadState(fp, version, chunksize); if (StateCheckRetrieveHeader(fp, "SCU ", &version, &chunksize) != 0) { fclose(fp); // Revert back to old state here ScspUnMuteAudio(SCSP_MUTE_SYSTEM); return -3; } ScuLoadState(fp, version, chunksize); if (StateCheckRetrieveHeader(fp, "SMPC", &version, &chunksize) != 0) { fclose(fp); // Revert back to old state here ScspUnMuteAudio(SCSP_MUTE_SYSTEM); return -3; } SmpcLoadState(fp, version, chunksize); if (StateCheckRetrieveHeader(fp, "VDP1", &version, &chunksize) != 0) { fclose(fp); // Revert back to old state here ScspUnMuteAudio(SCSP_MUTE_SYSTEM); return -3; } Vdp1LoadState(fp, version, chunksize); if (StateCheckRetrieveHeader(fp, "VDP2", &version, &chunksize) != 0) { fclose(fp); // Revert back to old state here ScspUnMuteAudio(SCSP_MUTE_SYSTEM); return -3; } Vdp2LoadState(fp, version, chunksize); if (StateCheckRetrieveHeader(fp, "OTHR", &version, &chunksize) != 0) { fclose(fp); // Revert back to old state here ScspUnMuteAudio(SCSP_MUTE_SYSTEM); return -3; } // Other data yread(&check, (void *)BupRam, 0x10000, 1, fp); yread(&check, (void *)HighWram, 0x100000, 1, fp); yread(&check, (void *)LowWram, 0x100000, 1, fp); yread(&check, (void *)&yabsys.DecilineCount, sizeof(int), 1, fp); yread(&check, (void *)&yabsys.LineCount, sizeof(int), 1, fp); yread(&check, (void *)&yabsys.VBlankLineCount, sizeof(int), 1, fp); yread(&check, (void *)&yabsys.MaxLineCount, sizeof(int), 1, fp); yread(&check, (void *)&temp, sizeof(int), 1, fp); yread(&check, (void *)&temp, sizeof(int), 1, fp); yread(&check, (void *)&temp32, sizeof(u32), 1, fp); yread(&check, (void *)&yabsys.CurSH2FreqType, sizeof(int), 1, fp); yread(&check, (void *)&yabsys.IsPal, sizeof(int), 1, fp); YabauseChangeTiming(yabsys.CurSH2FreqType); yabsys.UsecFrac = (temp32 << YABSYS_TIMING_BITS) * temp / 10; if (headerversion > 1) { yread(&check, (void *)&outputwidth, sizeof(outputwidth), 1, fp); yread(&check, (void *)&outputheight, sizeof(outputheight), 1, fp); totalsize=outputwidth * outputheight * sizeof(u32); if ((buf = (u8 *)malloc(totalsize)) == NULL) { return -2; } yread(&check, (void *)buf, totalsize, 1, fp); YuiSwapBuffers(); #ifdef USE_OPENGL if(VIDCore->id == VIDCORE_SOFT) glRasterPos2i(0, outputheight); if(VIDCore->id == VIDCORE_OGL) glRasterPos2i(0, outputheight/2); #endif VIDCore->GetGlSize(&curroutputwidth, &curroutputheight); #ifdef USE_OPENGL glPixelZoom((float)curroutputwidth / (float)outputwidth, ((float)curroutputheight / (float)outputheight)); glDrawPixels(outputwidth, outputheight, GL_RGBA, GL_UNSIGNED_BYTE, buf); #endif YuiSwapBuffers(); fseek(fp, movieposition, SEEK_SET); MovieReadState(fp, filename); } fclose(fp); ScspUnMuteAudio(SCSP_MUTE_SYSTEM); OSDPushMessage(OSDMSG_STATUS, 150, "STATE LOADED"); return 0; }
void load_68k_data(linput_t *li) { int version; int csize; ea_t pc; if (!load_header(li)) return; if (StateCheckRetrieveHeader(li, "CART", &version, &csize) != 0) { error("Invalid CART chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "CS2 ", &version, &csize) != 0) { error("Invalid CS2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "MSH2", &version, &csize) != 0) { error("Invalid MSH2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "SSH2", &version, &csize) != 0) { error("Invalid SSH2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "SCSP", &version, &csize) != 0) { error("Invalid SCSP chunk"); return; } SoundLoadState(li, &pc, csize); if (StateCheckRetrieveHeader(li, "SCU ", &version, &csize) != 0) { error("Invalid SCU chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "SMPC", &version, &csize) != 0) { error("Invalid SMPC chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "VDP1", &version, &csize) != 0) { error("Invalid VDP1 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "VDP2", &version, &csize) != 0) { error("Invalid VDP2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "OTHR", &version, &csize) != 0) { error("Invalid OTHR chunk"); return; } for (int i = 0x000004; i < 0x0000EC; i+=4) make_vector(i, NULL); // move cursor to current 68K PC jumpto(pc); }
void load_sh2_data(linput_t *li) { int version; int csize; ea_t result; sh2regs_struct sh2regs; if (!load_header(li)) return; if (StateCheckRetrieveHeader(li, "CART", &version, &csize) != 0) { error("Invalid CART chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "CS2 ", &version, &csize) != 0) { error("Invalid CS2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "MSH2", &version, &csize) != 0) { error("Invalid MSH2 chunk"); return; } SH2LoadState(li, false, &sh2regs, csize); if (StateCheckRetrieveHeader(li, "SSH2", &version, &csize) != 0) { error("Invalid SSH2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "SCSP", &version, &csize) != 0) { error("Invalid SCSP chunk"); return; } SoundLoadState(li, NULL, csize); if (StateCheckRetrieveHeader(li, "SCU ", &version, &csize) != 0) { error("Invalid SCU chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "SMPC", &version, &csize) != 0) { error("Invalid SMPC chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "VDP1", &version, &csize) != 0) { error("Invalid VDP1 chunk"); return; } Vdp1LoadState(li, csize); if (StateCheckRetrieveHeader(li, "VDP2", &version, &csize) != 0) { error("Invalid VDP2 chunk"); return; } Vdp2LoadState(li, csize); if (StateCheckRetrieveHeader(li, "OTHR", &version, &csize) != 0) { error("Invalid OTHR chunk"); return; } qlseek(li, 0x10000, SEEK_CUR); // BUP Ram create_load_seg(li, 0x06000000, 0x06100000, 2, "HWRAM"); create_load_seg(li, 0x00200000, 0x00300000, 2, "LWRAM"); identify_vector_table(); find_bios_funcs(); find_parse_ip(0x06000C00, false); find_parse_ip(0x06002000, true); // Look for SBL/SGL and load correct sig if available if ((result = find_string("GFS_SGL ")) != BADADDR) { char version_str[512]; get_lib_version(result, 8, version_str, sizeof(version_str)); msg("SGL detected\n"); if (atof(version_str) <= 2.10) plan_to_apply_idasgn("sgl20a.sig"); else if (atof(version_str) == 2.11) { // SGL 2.1, 3.00, 3.02j plan_to_apply_idasgn("sgl302j.sig"); } else if (atof(version_str) >= 2.12) plan_to_apply_idasgn("sgl302j.sig"); if ((result = find_string("CPK Version")) != BADADDR) { get_lib_version(result, 4, version_str, sizeof(version_str)); plan_to_apply_idasgn("cpksgl.sig"); } } else if ((result = find_string("GFS_SBL ")) != BADADDR) { char version_str[512]; get_lib_version(result, 8, version_str, sizeof(version_str)); msg("SBL detected\n"); plan_to_apply_idasgn("sbl601.sig"); if ((result = find_string("CPK Version")) != BADADDR) { get_lib_version(result, 4, version_str, sizeof(version_str)); plan_to_apply_idasgn("cpksbl.sig"); } } // move cursor to current MSH2 PC jumpto(sh2regs.PC); }
void load_scudsp_data(linput_t *li) { int version; int csize; ea_t pc; if (!load_header(li)) return; if (StateCheckRetrieveHeader(li, "CART", &version, &csize) != 0) { error("Invalid CART chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "CS2 ", &version, &csize) != 0) { error("Invalid CS2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "MSH2", &version, &csize) != 0) { error("Invalid MSH2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "SSH2", &version, &csize) != 0) { error("Invalid SSH2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "SCSP", &version, &csize) != 0) { error("Invalid SCSP chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "SCU ", &version, &csize) != 0) { error("Invalid SCU chunk"); return; } ScuLoadState(li, &pc, csize); if (StateCheckRetrieveHeader(li, "SMPC", &version, &csize) != 0) { error("Invalid SMPC chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "VDP1", &version, &csize) != 0) { error("Invalid VDP1 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "VDP2", &version, &csize) != 0) { error("Invalid VDP2 chunk"); return; } qlseek(li, csize, SEEK_CUR); if (StateCheckRetrieveHeader(li, "OTHR", &version, &csize) != 0) { error("Invalid OTHR chunk"); return; } // move cursor to current SCU DSP PC jumpto(pc); }