void savestates_load() { char *filename, buf[1024]; gzFile f; int len, i; int filename_f = 0; savestates_job_success = TRUE; if (slot <= 9) { filename = (char*)malloc(strlen(get_savespath())+ strlen(ROM_SETTINGS.goodname)+4+1); strcpy(filename, get_savespath()); strcat(filename, ROM_SETTINGS.goodname); strcat(filename, ".st"); sprintf(buf, "%d", slot); strcat(filename, buf); } else { filename = (char*)malloc(strlen(fname)+1); strcpy(filename, fname); slot -= 10; filename_f = 1; } { char str [256]; if(filename_f) sprintf(str, "loading %-200s", filename); else sprintf(str, "loading slot %d", slot); display_status(str); } f = gzopen(filename, "rb"); if (f == NULL) { printf("Savestate \"%s\" not found.\n", filename); free(filename); warn_savestate_not_exist(); savestates_job_success = FALSE; return; } free(filename); gzread(f, buf, 32); if (memcmp(buf, ROM_SETTINGS.MD5, 32)) { warn_savestate_from_another_rom(); gzclose(f); savestates_job_success = FALSE; return; } gzread(f, &rdram_register, sizeof(RDRAM_register)); gzread(f, &MI_register, sizeof(mips_register)); gzread(f, &pi_register, sizeof(PI_register)); gzread(f, &sp_register, sizeof(SP_register)); gzread(f, &rsp_register, sizeof(RSP_register)); gzread(f, &si_register, sizeof(SI_register)); gzread(f, &vi_register, sizeof(VI_register)); gzread(f, &ri_register, sizeof(RI_register)); gzread(f, &ai_register, sizeof(AI_register)); gzread(f, &dpc_register, sizeof(DPC_register)); gzread(f, &dps_register, sizeof(DPS_register)); gzread(f, rdram, 0x800000); gzread(f, SP_DMEM, 0x1000); gzread(f, SP_IMEM, 0x1000); gzread(f, PIF_RAM, 0x40); gzread(f, buf, 24); load_flashram_infos(buf); gzread(f, tlb_LUT_r, 0x400000); gzread(f, tlb_LUT_w, 0x400000); gzread(f, &llbit, 4); gzread(f, reg, 32*8); for (i=0; i<32; i++) { gzread(f, reg_cop0+i, 4); gzread(f, buf, 4); // for compatibility with old versions purpose } gzread(f, &lo, 8); gzread(f, &hi, 8); gzread(f, reg_cop1_fgr_64, 32*8); gzread(f, &FCR0, 4); gzread(f, &FCR31, 4); gzread(f, tlb_e, 32*sizeof(tlb)); if (!dynacore && interpcore) gzread(f, &interp_addr, 4); else { int i; gzread(f, &len, 4); for (i=0; i<0x100000; i++) invalid_code[i] = 1; jump_to(len); } gzread(f, &next_interupt, 4); gzread(f, &next_vi, 4); gzread(f, &vi_field, 4); len = 0; while(1) { gzread(f, buf+len, 4); if (*((unsigned long*)&buf[len]) == 0xFFFFFFFF) break; gzread(f, buf+len+4, 4); len += 8; } load_eventqueue_infos(buf); BOOL movieSnapshot; gzread(f, &movieSnapshot, sizeof(movieSnapshot)); if(VCR_isActive() && !movieSnapshot) { fprintf(stderr, "Can't load a non-movie snapshot while a movie is active.\n"); savestates_job_success = FALSE; goto failedLoad; } if(movieSnapshot) // even if a movie isn't active we still want to parse through this in case other stuff is added later on in the save format { unsigned long movieInputDataSize = 0; gzread(f, &movieInputDataSize, sizeof(movieInputDataSize)); char* local_movie_data = (char*)malloc(movieInputDataSize * sizeof(char)); int readBytes = gzread(f, local_movie_data, movieInputDataSize); if(readBytes != movieInputDataSize) { fprintf(stderr, "Corrupt movie snapshot.\n"); if(local_movie_data) free(local_movie_data); savestates_job_success = FALSE; goto failedLoad; } int code = VCR_movieUnfreeze(local_movie_data, movieInputDataSize); if(local_movie_data) free(local_movie_data); if(code != SUCCESS && !VCR_isIdle()) { char errStr [1024]; strcpy(errStr, "Failed to load movie snapshot\n"); switch(code) { case NOT_FROM_THIS_MOVIE: strcat(errStr, ";\nSnapshot not from this movie"); break; case NOT_FROM_A_MOVIE: strcat(errStr, ";\nNot a movie snapshot"); break;// shouldn't get here... case INVALID_FRAME: strcat(errStr, ";\nInvalid frame number"); break; case WRONG_FORMAT: strcat(errStr, ";\nWrong format"); break; } strcat(errStr, "."); fprintf(stderr, "%s\n", errStr); #ifdef __WIN32__ void ShowInfo(char *Str, ...); ShowInfo(errStr); #endif savestates_job_success = FALSE; goto failedLoad; } } else // loading a non-movie snapshot from a movie { if(VCR_isActive()) { #ifdef __WIN32__ MessageBox(NULL, "The movie has been stopped to load this non-movie snapshot.", "Warning", MB_OK | MB_ICONWARNING); #else printf("[VCR]: Warning: The movie has been stopped to load this non-movie snapshot.\n"); #endif if(VCR_isPlaying()) VCR_stopPlayback(); else VCR_stopRecord(); } } failedLoad: gzclose(f); if (!dynacore && interpcore) last_addr = interp_addr; else last_addr = PC->addr; }
void savestates_load() { char *filename, buf[1024]; gzFile f; int len, i; if (slot <= 9) { filename = malloc(strlen(get_savespath())+ strlen(ROM_SETTINGS.goodname)+4+1); strcpy(filename, get_savespath()); strcat(filename, ROM_SETTINGS.goodname); strcat(filename, ".st"); sprintf(buf, "%d", slot); strcat(filename, buf); } else { filename = malloc(strlen(fname)+1); strcpy(filename, fname); slot -= 10; } f = gzopen(filename, "rb"); free(filename); if (f == NULL) { warn_savestate_not_exist(); return; } gzread(f, buf, 32); if (memcmp(buf, ROM_SETTINGS.MD5, 32)) { warn_savestate_from_another_rom(); gzclose(f); return; } gzread(f, &rdram_register, sizeof(RDRAM_register)); gzread(f, &MI_register, sizeof(mips_register)); gzread(f, &pi_register, sizeof(PI_register)); gzread(f, &sp_register, sizeof(SP_register)); gzread(f, &rsp_register, sizeof(RSP_register)); gzread(f, &si_register, sizeof(SI_register)); gzread(f, &vi_register, sizeof(VI_register)); gzread(f, &ri_register, sizeof(RI_register)); gzread(f, &ai_register, sizeof(AI_register)); gzread(f, &dpc_register, sizeof(DPC_register)); gzread(f, &dps_register, sizeof(DPS_register)); gzread(f, rdram, 0x800000); gzread(f, SP_DMEM, 0x1000); gzread(f, SP_IMEM, 0x1000); gzread(f, PIF_RAM, 0x40); gzread(f, buf, 24); load_flashram_infos(buf); gzread(f, tlb_LUT_r, 0x100000); gzread(f, tlb_LUT_w, 0x100000); gzread(f, &llbit, 4); gzread(f, reg, 32*8); for (i=0; i<32; i++) { gzread(f, reg_cop0+i, 4); gzread(f, buf, 4); // for compatibility with old versions purpose } gzread(f, &lo, 8); gzread(f, &hi, 8); gzread(f, reg_cop1_fgr_64, 32*8); gzread(f, &FCR0, 4); gzread(f, &FCR31, 4); gzread(f, tlb_e, 32*sizeof(tlb)); if (!dynacore && interpcore) gzread(f, &interp_addr, 4); else { int i; gzread(f, &len, 4); for (i=0; i<0x100000; i++) invalid_code[i] = 1; jump_to(len); } gzread(f, &next_interupt, 4); gzread(f, &next_vi, 4); gzread(f, &vi_field, 4); len = 0; while(1) { gzread(f, buf+len, 4); if (*((unsigned long*)&buf[len]) == 0xFFFFFFFF) break; gzread(f, buf+len+4, 4); len += 8; } load_eventqueue_infos(buf); gzclose(f); if (!dynacore && interpcore) last_addr = interp_addr; else last_addr = PC->addr; }