Beispiel #1
0
// 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();
	}
}
Beispiel #2
0
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;
		}
	}
}
Beispiel #3
0
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();
	}
}
Beispiel #5
0
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);
			}
		}
	}
}
Beispiel #7
0
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();
	}
}
Beispiel #9
0
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);
}
Beispiel #11
0
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();
	}
}
Beispiel #12
0
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();
	}
}
Beispiel #17
0
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];
	}
}
Beispiel #18
0
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);
}
Beispiel #19
0
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
}
Beispiel #20
0
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");
}
Beispiel #21
0
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);
}
Beispiel #22
0
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);
}
Beispiel #23
0
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);
		}
	}
}
Beispiel #24
0
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);
}
Beispiel #25
0
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);
}
Beispiel #26
0
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));
  }
}
Beispiel #27
0
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);
	}
}
Beispiel #29
0
void DoState(PointerWrap& p)
{
  if (g_jit && p.GetMode() == PointerWrap::MODE_READ)
    g_jit->ClearCache();
}
Beispiel #30
0
	void DoState(PointerWrap &p)
	{
		if (jit && p.GetMode() == PointerWrap::MODE_READ)
			jit->GetBlockCache()->Clear();
	}