// Run from the CPU thread void VideoBackendHardware::DoState(PointerWrap& p) { bool software = false; p.Do(software); if (p.GetMode() == PointerWrap::MODE_READ && software == true) { // change mode to abort load of incompatible save state. p.SetMode(PointerWrap::MODE_VERIFY); } VideoCommon_DoState(p); p.DoMarker("VideoCommon"); p.Do(s_beginFieldArgs); p.DoMarker("VideoBackendHardware"); // Refresh state. if (p.GetMode() == PointerWrap::MODE_READ) { m_invalid = true; // Clear all caches that touch RAM // (? these don't appear to touch any emulation state that gets saved. moved to on load only.) VertexLoaderManager::MarkAllDirty(); } }
static void EventDoState(PointerWrap &p, BaseEvent* ev) { p.Do(ev->time); // this is why we can't have (nice things) pointers as userdata p.Do(ev->userdata); // we can't savestate ev->type directly because events might not get registered in the same order (or at all) every time. // so, we savestate the event's type's name, and derive ev->type from that when loading. std::string name; if (p.GetMode() != PointerWrap::MODE_READ) name = event_types[ev->type].name; p.Do(name); if (p.GetMode() == PointerWrap::MODE_READ) { bool foundMatch = false; for (unsigned int i = 0; i < event_types.size(); ++i) { if (name == event_types[i].name) { ev->type = i; foundMatch = true; break; } } if (!foundMatch) { WARN_LOG(POWERPC, "Lost event from savestate because its type, \"%s\", has not been registered.", name.c_str()); ev->type = ev_lost; } } }
void DSPLLE::DoState(PointerWrap &p) { bool isHLE = false; p.Do(isHLE); if (isHLE != false && p.GetMode() == PointerWrap::MODE_READ) { Core::DisplayMessage("State is incompatible with current DSP engine. Aborting load state.", 3000); p.SetMode(PointerWrap::MODE_VERIFY); return; } p.Do(g_dsp.r); p.Do(g_dsp.pc); #if PROFILE p.Do(g_dsp.err_pc); #endif p.Do(g_dsp.cr); p.Do(g_dsp.reg_stack_ptr); p.Do(g_dsp.exceptions); p.Do(g_dsp.external_interrupt_waiting); for (int i = 0; i < 4; i++) { p.Do(g_dsp.reg_stack[i]); } p.Do(g_dsp.step_counter); p.Do(g_dsp.ifx_regs); p.Do(g_dsp.mbox[0]); p.Do(g_dsp.mbox[1]); UnWriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); p.DoArray(g_dsp.iram, DSP_IRAM_SIZE); WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); if (p.GetMode() == PointerWrap::MODE_READ) DSPHost::CodeLoaded((const u8*)g_dsp.iram, DSP_IRAM_BYTE_SIZE); p.DoArray(g_dsp.dram, DSP_DRAM_SIZE); p.Do(cyclesLeft); p.Do(init_hax); p.Do(m_cycle_count); bool prevInitMixer = m_InitMixer; p.Do(m_InitMixer); if (prevInitMixer != m_InitMixer && p.GetMode() == PointerWrap::MODE_READ) { if (m_InitMixer) { InitMixer(); AudioCommon::PauseAndLock(true); } else { AudioCommon::PauseAndLock(false); soundStream->Stop(); delete soundStream; soundStream = nullptr; } } }
void VertexShaderManager::DoState(PointerWrap &p) { p.Do(g_fProjectionMatrix); p.Do(s_viewportCorrection); p.Do(s_viewRotationMatrix); p.Do(s_viewInvRotationMatrix); p.Do(s_fViewTranslationVector); p.Do(s_fViewRotation); p.Do(nTransformMatricesChanged); p.Do(nNormalMatricesChanged); p.Do(nPostTransformMatricesChanged); p.Do(nLightsChanged); p.Do(nMaterialsChanged); p.Do(bTexMatricesChanged); p.Do(bPosNormalMatrixChanged); p.Do(bProjectionChanged); p.Do(bViewportChanged); p.Do(constants); if (p.GetMode() == PointerWrap::MODE_READ) { Dirty(); } }
void GameListItem::DoState(PointerWrap& p) { p.Do(m_valid); p.Do(m_file_name); p.Do(m_file_size); p.Do(m_volume_size); p.Do(m_names); p.Do(m_descriptions); p.Do(m_company); p.Do(m_game_id); p.Do(m_title_id); p.Do(m_region); p.Do(m_country); p.Do(m_platform); p.Do(m_blob_type); p.Do(m_revision); p.Do(m_disc_number); m_volume_banner.DoState(p); m_emu_state.DoState(p); p.Do(m_custom_name); if (p.GetMode() == PointerWrap::MODE_READ) { SetWxBannerFromRaw(m_volume_banner); } }
void CEXIChannel::DoState(PointerWrap &p) { p.DoPOD(m_Status); p.Do(m_DMAMemoryAddress); p.Do(m_DMALength); p.Do(m_Control); p.Do(m_ImmData); for (int d = 0; d < NUM_DEVICES; ++d) { IEXIDevice* pDevice = m_pDevices[d].get(); TEXIDevices type = pDevice->m_deviceType; p.Do(type); IEXIDevice* pSaveDevice = (type == pDevice->m_deviceType) ? pDevice : EXIDevice_Create(type, m_ChannelId); pSaveDevice->DoState(p); if(pSaveDevice != pDevice) { // if we had to create a temporary device, discard it if we're not loading. // also, if no movie is active, we'll assume the user wants to keep their current devices // instead of the ones they had when the savestate was created, // unless the device is NONE (since ChangeDevice sets that temporarily). if(p.GetMode() != PointerWrap::MODE_READ) { delete pSaveDevice; } else { AddDevice(pSaveDevice, d, false); } } } }
void USBHost::DoState(PointerWrap& p) { if (IsOpened() && p.GetMode() == PointerWrap::MODE_READ) { // After a state has loaded, there may be insertion hooks for devices that were // already plugged in, and which need to be triggered. UpdateDevices(true); } }
void GeometryShaderManager::DoState(PointerWrap &p) { if (p.GetMode() == PointerWrap::MODE_READ) { // Reload current state from global GPU state // NOTE: This requires that all GPU memory has been loaded already. Dirty(); } }
void DoState(PointerWrap& p) { std::lock_guard<std::mutex> lk(s_ts_write_lock); p.Do(g_slice_length); p.Do(g_global_timer); p.Do(s_idled_cycles); p.Do(s_fake_dec_start_value); p.Do(s_fake_dec_start_ticks); p.Do(g_fake_TB_start_value); p.Do(g_fake_TB_start_ticks); p.Do(s_last_OC_factor); g_last_OC_factor_inverted = 1.0f / s_last_OC_factor; p.Do(s_event_fifo_id); p.DoMarker("CoreTimingData"); MoveEvents(); p.DoEachElement(s_event_queue, [](PointerWrap& pw, Event& ev) { pw.Do(ev.time); pw.Do(ev.fifo_order); // this is why we can't have (nice things) pointers as userdata pw.Do(ev.userdata); // we can't savestate ev.type directly because events might not get registered in the same // order (or at all) every time. // so, we savestate the event's type's name, and derive ev.type from that when loading. std::string name; if (pw.GetMode() != PointerWrap::MODE_READ) name = *ev.type->name; pw.Do(name); if (pw.GetMode() == PointerWrap::MODE_READ) { auto itr = s_event_types.find(name); if (itr != s_event_types.end()) { ev.type = &itr->second; } else { WARN_LOG(POWERPC, "Lost event from savestate because its type, \"%s\", has not been registered.", name.c_str()); ev.type = s_ev_lost; } } }); p.DoMarker("CoreTimingEvents"); // When loading from a save state, we must assume the Event order is random and meaningless. // The exact layout of the heap in memory is implementation defined, therefore it is platform // and library version specific. if (p.GetMode() == PointerWrap::MODE_READ) std::make_heap(s_event_queue.begin(), s_event_queue.end(), std::greater<Event>()); }
void CWII_IPC_HLE_Device_sdio_slot0::DoState(PointerWrap& p) { DoStateShared(p); if (p.GetMode() == PointerWrap::MODE_READ) { OpenInternal(); } p.Do(m_Status); p.Do(m_BlockLength); p.Do(m_BusWidth); p.Do(m_Registers); }
void PixelShaderManager::DoState(PointerWrap &p) { p.DoArray(s_tev_color); p.DoArray(s_tev_konst_color); if (p.GetMode() == PointerWrap::MODE_READ) { // Reload current state from global GPU state // NOTE: This requires that all GPU memory has been loaded already. Dirty(); } }
void DSPLLE::DoState(PointerWrap &p) { bool is_hle = false; p.Do(is_hle); if (is_hle && p.GetMode() == PointerWrap::MODE_READ) { Core::DisplayMessage("State is incompatible with current DSP engine. Aborting load state.", 3000); p.SetMode(PointerWrap::MODE_VERIFY); return; } p.Do(g_dsp.r); p.Do(g_dsp.pc); #if PROFILE p.Do(g_dsp.err_pc); #endif p.Do(g_dsp.cr); p.Do(g_dsp.reg_stack_ptr); p.Do(g_dsp.exceptions); p.Do(g_dsp.external_interrupt_waiting); for (int i = 0; i < 4; i++) { p.Do(g_dsp.reg_stack[i]); } p.Do(g_dsp.step_counter); p.DoArray(g_dsp.ifx_regs); p.Do(g_dsp.mbox[0]); p.Do(g_dsp.mbox[1]); UnWriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); p.DoArray(g_dsp.iram, DSP_IRAM_SIZE); WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); if (p.GetMode() == PointerWrap::MODE_READ) DSPHost::CodeLoaded((const u8*)g_dsp.iram, DSP_IRAM_BYTE_SIZE); p.DoArray(g_dsp.dram, DSP_DRAM_SIZE); p.Do(g_cycles_left); p.Do(g_init_hax); p.Do(m_cycle_count); }
void CWII_IPC_HLE_Device_FileIO::DoState(PointerWrap &p) { DoStateShared(p); p.Do(m_Mode); p.Do(m_SeekPos); m_filepath = HLE_IPC_BuildFilename(m_Name); if (p.GetMode() == PointerWrap::MODE_READ) { OpenFile(); } }
void GeometryShaderManager::DoState(PointerWrap &p) { p.Do(s_projection_changed); p.Do(s_viewport_changed); p.Do(constants); if (p.GetMode() == PointerWrap::MODE_READ) { // Fixup the current state from global GPU state // NOTE: This requires that all GPU memory has been loaded already. Dirty(); } }
void PixelShaderManager::DoState(PointerWrap &p) { p.Do(s_bFogRangeAdjustChanged); p.Do(s_bViewPortChanged); p.Do(constants); if (p.GetMode() == PointerWrap::MODE_READ) { // Fixup the current state from global GPU state // NOTE: This requires that all GPU memory has been loaded already. Dirty(); } }
void VertexShaderManager::DoState(PointerWrap &p) { p.Do(g_fProjectionMatrix); p.Do(s_viewportCorrection); p.Do(s_viewRotationMatrix); p.Do(s_viewInvRotationMatrix); p.Do(s_fViewTranslationVector); p.Do(s_fViewRotation); p.Do(constants); p.Do(dirty); if (p.GetMode() == PointerWrap::MODE_READ) { Dirty(); } }
void Arm64Jit::DoState(PointerWrap &p) { auto s = p.Section("Jit", 1, 2); if (!s) return; p.Do(js.startDefaultPrefix); if (s >= 2) { p.Do(js.hasSetRounding); js.lastSetRounding = 0; } else { js.hasSetRounding = 1; } if (p.GetMode() == PointerWrap::MODE_READ) { js.currentRoundingFunc = convertS0ToSCRATCH1[(mips_->fcr31) & 3]; } }
void DoState(PointerWrap& p) { // some of this code has been disabled, because // it changes registers even in MODE_MEASURE (which is suspicious and seems like it could cause // desyncs) // and because the values it's changing have been added to CoreTiming::DoState, so it might // conflict to mess with them here. // rSPR(SPR_DEC) = SystemTimers::GetFakeDecrementer(); // *((u64 *)&TL) = SystemTimers::GetFakeTimeBase(); //works since we are little endian and TL // comes first :) p.DoArray(ppcState.gpr); p.Do(ppcState.pc); p.Do(ppcState.npc); p.DoArray(ppcState.cr_val); p.Do(ppcState.msr); p.Do(ppcState.fpscr); p.Do(ppcState.Exceptions); p.Do(ppcState.downcount); p.Do(ppcState.xer_ca); p.Do(ppcState.xer_so_ov); p.Do(ppcState.xer_stringctrl); p.DoArray(ppcState.ps); p.DoArray(ppcState.sr); p.DoArray(ppcState.spr); p.DoArray(ppcState.tlb); p.Do(ppcState.pagetable_base); p.Do(ppcState.pagetable_hashmask); ppcState.iCache.DoState(p); if (p.GetMode() == PointerWrap::MODE_READ) { IBATUpdated(); DBATUpdated(); } // SystemTimers::DecrementerSet(); // SystemTimers::TimeBaseSet(); JitInterface::DoState(p); }
static void DoState(PointerWrap &p) { u32 version = STATE_VERSION; { static const u32 COOKIE_BASE = 0xBAADBABE; u32 cookie = version + COOKIE_BASE; p.Do(cookie); version = cookie - COOKIE_BASE; } if (version != STATE_VERSION) { // if the version doesn't match, fail. // this will trigger a message like "Can't load state from other revisions" // we could use the version numbers to maintain some level of backward compatibility, but currently don't. p.SetMode(PointerWrap::MODE_MEASURE); return; } p.DoMarker("Version"); // Begin with video backend, so that it gets a chance to clear it's caches and writeback modified things to RAM g_video_backend->DoState(p); p.DoMarker("video_backend"); if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) Wiimote::DoState(p.GetPPtr(), p.GetMode()); p.DoMarker("Wiimote"); PowerPC::DoState(p); p.DoMarker("PowerPC"); HW::DoState(p); p.DoMarker("HW"); CoreTiming::DoState(p); p.DoMarker("CoreTiming"); Movie::DoState(p); p.DoMarker("Movie"); #if defined(HAVE_LIBAV) || defined (WIN32) AVIDump::DoState(); #endif }
void DoState(PointerWrap &p) { std::lock_guard<std::mutex> lk(tsWriteLock); p.Do(g_slicelength); p.Do(g_globalTimer); p.Do(idledCycles); p.Do(fakeDecStartValue); p.Do(fakeDecStartTicks); p.Do(g_fakeTBStartValue); p.Do(g_fakeTBStartTicks); p.Do(s_lastOCFactor); if (p.GetMode() == PointerWrap::MODE_READ) g_lastOCFactor_inverted = 1.0f / s_lastOCFactor; p.DoMarker("CoreTimingData"); MoveEvents(); p.DoLinkedList<BaseEvent, GetNewEvent, FreeEvent, EventDoState>(first); p.DoMarker("CoreTimingEvents"); }
void DoState(PointerWrap& p) { // some of this code has been disabled, because // it changes registers even in MODE_MEASURE (which is suspicious and seems like it could cause // desyncs) // and because the values it's changing have been added to CoreTiming::DoState, so it might // conflict to mess with them here. // rSPR(SPR_DEC) = SystemTimers::GetFakeDecrementer(); // *((u64 *)&TL) = SystemTimers::GetFakeTimeBase(); //works since we are little endian and TL // comes first :) p.DoPOD(ppcState); if (p.GetMode() == PointerWrap::MODE_READ) { IBATUpdated(); DBATUpdated(); } // SystemTimers::DecrementerSet(); // SystemTimers::TimeBaseSet(); JitInterface::DoState(p); }
void CWII_IPC_HLE_WiiMote::DoState(PointerWrap& p) { bool passthrough_bluetooth = false; p.Do(passthrough_bluetooth); if (passthrough_bluetooth && p.GetMode() == PointerWrap::MODE_READ) { Core::DisplayMessage("State needs Bluetooth passthrough to be enabled. Aborting load state.", 3000); p.SetMode(PointerWrap::MODE_VERIFY); return; } // this function is usually not called... see CWII_IPC_HLE_Device_usb_oh1_57e_305::DoState p.Do(m_ConnectionState); p.Do(m_HIDControlChannel_Connected); p.Do(m_HIDControlChannel_ConnectedWait); p.Do(m_HIDControlChannel_Config); p.Do(m_HIDControlChannel_ConfigWait); p.Do(m_HIDInterruptChannel_Connected); p.Do(m_HIDInterruptChannel_ConnectedWait); p.Do(m_HIDInterruptChannel_Config); p.Do(m_HIDInterruptChannel_ConfigWait); p.Do(m_BD); p.Do(m_ConnectionHandle); p.Do(uclass); p.Do(features); p.Do(lmp_version); p.Do(lmp_subversion); p.Do(m_LinkKey); p.Do(m_Name); p.Do(m_Channel); }
void DoState(PointerWrap &p) { p.Do(request_queue); p.Do(reply_queue); p.Do(last_reply_time); for (const auto& entry : g_DeviceMap) { if (entry.second->IsHardware()) { entry.second->DoState(p); } } if (p.GetMode() == PointerWrap::MODE_READ) { for (u32 i=0; i<IPC_MAX_FDS; i++) { u32 exists = 0; p.Do(exists); if (exists) { u32 isHw = 0; p.Do(isHw); if (isHw) { u32 hwId = 0; p.Do(hwId); g_FdMap[i] = AccessDeviceByID(hwId); } else { g_FdMap[i] = new CWII_IPC_HLE_Device_FileIO(i, ""); g_FdMap[i]->DoState(p); } } else { g_FdMap[i] = nullptr; } } for (u32 i=0; i<ES_MAX_COUNT; i++) { p.Do(es_inuse[i]); u32 handleID = es_handles[i]->GetDeviceID(); p.Do(handleID); es_handles[i] = AccessDeviceByID(handleID); } } else { for (IWII_IPC_HLE_Device*& dev : g_FdMap) { u32 exists = dev ? 1 : 0; p.Do(exists); if (exists) { u32 isHw = dev->IsHardware() ? 1 : 0; p.Do(isHw); if (isHw) { u32 hwId = dev->GetDeviceID(); p.Do(hwId); } else { dev->DoState(p); } } } for (u32 i=0; i<ES_MAX_COUNT; i++) { p.Do(es_inuse[i]); u32 handleID = es_handles[i]->GetDeviceID(); p.Do(handleID); } } }
void DSPHLE::DoState(PointerWrap &p) { bool isHLE = true; p.Do(isHLE); if (isHLE != true && p.GetMode() == PointerWrap::MODE_READ) { Core::DisplayMessage("State is incompatible with current DSP engine. Aborting load state.", 3000); p.SetMode(PointerWrap::MODE_VERIFY); return; } p.DoPOD(m_DSPControl); p.DoPOD(m_dspState); int ucode_crc = UCodeInterface::GetCRC(m_pUCode); int ucode_crc_beforeLoad = ucode_crc; int lastucode_crc = UCodeInterface::GetCRC(m_lastUCode); int lastucode_crc_beforeLoad = lastucode_crc; p.Do(ucode_crc); p.Do(lastucode_crc); // if a different type of ucode was being used when the savestate was created, // we have to reconstruct the old type of ucode so that we have a valid thing to call DoState on. UCodeInterface* ucode = (ucode_crc == ucode_crc_beforeLoad) ? m_pUCode : UCodeFactory( ucode_crc, this, m_bWii); UCodeInterface* lastucode = (lastucode_crc != lastucode_crc_beforeLoad) ? m_lastUCode : UCodeFactory(lastucode_crc, this, m_bWii); if (ucode) ucode->DoState(p); if (lastucode) lastucode->DoState(p); // if a different type of ucode was being used when the savestate was created, // discard it if we're not loading, otherwise discard the old one and keep the new one. if (ucode != m_pUCode) { if (p.GetMode() != PointerWrap::MODE_READ) { delete ucode; } else { delete m_pUCode; m_pUCode = ucode; } } if (lastucode != m_lastUCode) { if (p.GetMode() != PointerWrap::MODE_READ) { delete lastucode; } else { delete m_lastUCode; m_lastUCode = lastucode; } } m_MailHandler.DoState(p); }
void DSPHLE::DoState(PointerWrap &p) { bool prevInitMixer = m_InitMixer; p.Do(m_InitMixer); if (prevInitMixer != m_InitMixer && p.GetMode() == PointerWrap::MODE_READ) { if (m_InitMixer) { InitMixer(); AudioCommon::PauseAndLock(true); } else { AudioCommon::PauseAndLock(false); soundStream->Stop(); delete soundStream; soundStream = NULL; } } p.Do(m_DSPControl); p.Do(m_dspState); int ucode_crc = IUCode::GetCRC(m_pUCode); int ucode_crc_beforeLoad = ucode_crc; int lastucode_crc = IUCode::GetCRC(m_lastUCode); int lastucode_crc_beforeLoad = lastucode_crc; p.Do(ucode_crc); p.Do(lastucode_crc); // if a different type of ucode was being used when the savestate was created, // we have to reconstruct the old type of ucode so that we have a valid thing to call DoState on. IUCode* ucode = (ucode_crc == ucode_crc_beforeLoad) ? m_pUCode : UCodeFactory( ucode_crc, this, m_bWii); IUCode* lastucode = (lastucode_crc != lastucode_crc_beforeLoad) ? m_lastUCode : UCodeFactory(lastucode_crc, this, m_bWii); if (ucode) ucode->DoState(p); if (lastucode) lastucode->DoState(p); // if a different type of ucode was being used when the savestate was created, // discard it if we're not loading, otherwise discard the old one and keep the new one. if (ucode != m_pUCode) { if (p.GetMode() != PointerWrap::MODE_READ) delete ucode; else { delete m_pUCode; m_pUCode = ucode; } } if (lastucode != m_lastUCode) { if (p.GetMode() != PointerWrap::MODE_READ) delete lastucode; else { delete m_lastUCode; m_lastUCode = lastucode; } } m_MailHandler.DoState(p); }
void HostFileSystem::DoState(PointerWrap& p) { p.Do(m_root_path); // Temporarily close the file, to prevent any issues with the savestating of /tmp for (Handle& handle : m_handles) handle.host_file.reset(); // handle /tmp std::string Path = BuildFilename("/tmp"); if (p.GetMode() == PointerWrap::MODE_READ) { File::DeleteDirRecursively(Path); File::CreateDir(Path); // now restore from the stream while (1) { char type = 0; p.Do(type); if (!type) break; std::string file_name; p.Do(file_name); std::string name = Path + "/" + file_name; switch (type) { case 'd': { File::CreateDir(name); break; } case 'f': { u32 size = 0; p.Do(size); File::IOFile handle(name, "wb"); char buf[65536]; u32 count = size; while (count > 65536) { p.DoArray(buf); handle.WriteArray(&buf[0], 65536); count -= 65536; } p.DoArray(&buf[0], count); handle.WriteArray(&buf[0], count); break; } } } } else { // recurse through tmp and save dirs and files File::FSTEntry parent_entry = File::ScanDirectoryTree(Path, true); std::deque<File::FSTEntry> todo; todo.insert(todo.end(), parent_entry.children.begin(), parent_entry.children.end()); while (!todo.empty()) { File::FSTEntry& entry = todo.front(); std::string name = entry.physicalName; name.erase(0, Path.length() + 1); char type = entry.isDirectory ? 'd' : 'f'; p.Do(type); p.Do(name); if (entry.isDirectory) { todo.insert(todo.end(), entry.children.begin(), entry.children.end()); } else { u32 size = (u32)entry.size; p.Do(size); File::IOFile handle(entry.physicalName, "rb"); char buf[65536]; u32 count = size; while (count > 65536) { handle.ReadArray(&buf[0], 65536); p.DoArray(buf); count -= 65536; } handle.ReadArray(&buf[0], count); p.DoArray(&buf[0], count); } todo.pop_front(); } char type = 0; p.Do(type); } for (Handle& handle : m_handles) { p.Do(handle.opened); p.Do(handle.mode); p.Do(handle.wii_path); p.Do(handle.file_offset); if (handle.opened) handle.host_file = OpenHostFile(BuildFilename(handle.wii_path)); } }
void DoState(PointerWrap &p) { std::lock_guard<std::mutex> lk(s_reply_queue); p.Do(request_queue); p.Do(reply_queue); p.Do(last_reply_time); TDeviceMap::const_iterator itr; itr = g_DeviceMap.begin(); while (itr != g_DeviceMap.end()) { if (itr->second->IsHardware()) { itr->second->DoState(p); } ++itr; } if (p.GetMode() == PointerWrap::MODE_READ) { u32 i; for (i=0; i<IPC_MAX_FDS; i++) { u32 exists = 0; p.Do(exists); if (exists) { u32 isHw = 0; p.Do(isHw); if (isHw) { u32 hwId = 0; p.Do(hwId); g_FdMap[i] = AccessDeviceByID(hwId); } else { g_FdMap[i] = new CWII_IPC_HLE_Device_FileIO(i, ""); g_FdMap[i]->DoState(p); } } else { g_FdMap[i] = NULL; } } for (i=0; i<ES_MAX_COUNT; i++) { p.Do(es_inuse[i]); u32 handleID = es_handles[i]->GetDeviceID(); p.Do(handleID); es_handles[i] = AccessDeviceByID(handleID); } } else { u32 i; for (i=0; i<IPC_MAX_FDS; i++) { u32 exists = g_FdMap[i] ? 1 : 0; p.Do(exists); if (exists) { u32 isHw = g_FdMap[i]->IsHardware() ? 1 : 0; p.Do(isHw); if (isHw) { u32 hwId = g_FdMap[i]->GetDeviceID(); p.Do(hwId); } else { g_FdMap[i]->DoState(p); } } } for (i=0; i<ES_MAX_COUNT; i++) { p.Do(es_inuse[i]); u32 handleID = es_handles[i]->GetDeviceID(); p.Do(handleID); } } }
void CWII_IPC_HLE_Device_fs::DoState(PointerWrap& p) { DoStateShared(p); // handle /tmp std::string Path = File::GetUserPath(D_WIIUSER_IDX) + "tmp"; if (p.GetMode() == PointerWrap::MODE_READ) { File::DeleteDirRecursively(Path); File::CreateDir(Path.c_str()); //now restore from the stream while(1) { char type = 0; p.Do(type); if (!type) break; std::string filename; p.Do(filename); std::string name = Path + DIR_SEP + filename; switch(type) { case 'd': { File::CreateDir(name.c_str()); break; } case 'f': { u32 size = 0; p.Do(size); File::IOFile handle(name, "wb"); char buf[65536]; u32 count = size; while(count > 65536) { p.DoArray(&buf[0], 65536); handle.WriteArray(&buf[0], 65536); count -= 65536; } p.DoArray(&buf[0], count); handle.WriteArray(&buf[0], count); break; } } } } else { //recurse through tmp and save dirs and files File::FSTEntry parentEntry; File::ScanDirectoryTree(Path, parentEntry); std::deque<File::FSTEntry> todo; todo.insert(todo.end(), parentEntry.children.begin(), parentEntry.children.end()); while(!todo.empty()) { File::FSTEntry &entry = todo.front(); std::string name = entry.physicalName; name.erase(0,Path.length()+1); char type = entry.isDirectory?'d':'f'; p.Do(type); p.Do(name); if (entry.isDirectory) { todo.insert(todo.end(), entry.children.begin(), entry.children.end()); } else { u32 size = (u32)entry.size; p.Do(size); File::IOFile handle(entry.physicalName, "rb"); char buf[65536]; u32 count = size; while(count > 65536) { handle.ReadArray(&buf[0], 65536); p.DoArray(&buf[0], 65536); count -= 65536; } handle.ReadArray(&buf[0], count); p.DoArray(&buf[0], count); } todo.pop_front(); } char type = 0; p.Do(type); } }
void DoState(PointerWrap& p) { if (g_jit && p.GetMode() == PointerWrap::MODE_READ) g_jit->ClearCache(); }
void DoState(PointerWrap &p) { if (jit && p.GetMode() == PointerWrap::MODE_READ) jit->GetBlockCache()->Clear(); }