From 0cb77776bd2b72d59d529ac304f29a7ba1682799 Mon Sep 17 00:00:00 2001 From: ayuanx Date: Thu, 28 Jan 2010 03:19:32 +0000 Subject: [PATCH] This should fix some of the crashes after loading a state for Wii games. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4975 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 10 ++++- .../Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp | 40 +++++++++++++++---- .../Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h | 3 ++ 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp index ddd76fc1e5..6b9e643fc6 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -221,10 +221,11 @@ void DoState(PointerWrap &p) else PanicAlert("WII_IPC_HLE: Save/Load State failed, Device /dev/usb/oh1/57e/305 doesn't exist!"); + TFileNameMap::const_iterator itr; if (p.GetMode() == PointerWrap::MODE_READ) { // Delete file Handles - TFileNameMap::const_iterator itr = g_FileNameMap.begin(); + itr = g_FileNameMap.begin(); while (itr != g_FileNameMap.end()) { if (g_DeviceMap[itr->first]) @@ -246,6 +247,13 @@ void DoState(PointerWrap &p) { p.Do(g_FileNameMap); } + + itr = g_FileNameMap.begin(); + while (itr != g_FileNameMap.end()) + { + g_DeviceMap[itr->first]->DoState(p); + ++itr; + } } // =================================================== diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp index 8f5d20ea79..7b75a87abd 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp @@ -18,6 +18,7 @@ #include "Common.h" #include "FileUtil.h" #include "StringUtil.h" +#include "ChunkFile.h" #include "WII_IPC_HLE_Device_fs.h" #include "WII_IPC_HLE_Device_FileIO.h" @@ -42,6 +43,8 @@ CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std: : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName, false) // not a real hardware , m_pFileHandle(NULL) , m_FileLength(0) + , m_Mode(0) + , m_Seek(0) { } @@ -59,6 +62,10 @@ bool CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress, bool _bForce) m_pFileHandle = NULL; } + m_FileLength = 0; + m_Mode = 0; + m_Seek = 0; + // Close always return 0 for success if (!_bForce) Memory::Write_U32(0, _CommandAddress + 4); @@ -68,6 +75,7 @@ bool CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress, bool _bForce) bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode) { + m_Mode = _Mode; u32 ReturnValue = 0; // close the file handle if we get a reopen @@ -111,7 +119,7 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode) if (m_pFileHandle != NULL) { m_FileLength = (u32)File::GetSize(m_Filename.c_str()); - ReturnValue = GetDeviceID(); + ReturnValue = m_DeviceID; } else if (ReturnValue == 0) { @@ -119,7 +127,8 @@ bool CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode) ReturnValue = FS_INVALID_ARGUMENT; } - Memory::Write_U32(ReturnValue, _CommandAddress+4); + if (_CommandAddress) + Memory::Write_U32(ReturnValue, _CommandAddress+4); m_Active = true; return true; } @@ -142,8 +151,6 @@ bool CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress) the filesize then? - No, that didn't work either, it seeks to 0x6000 even if I return 0x4000 from the first seek. */ - // AyuanX: this is still dubious because m_FileLength - // isn't updated on the fly when write happens s32 NewSeekPosition = SeekPosition; if (m_FileLength > 0 && SeekPosition > (s32)m_FileLength && Mode == 0) { @@ -208,10 +215,6 @@ bool CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress) size_t Result = fwrite(Memory::GetPointer(Address), Size, 1, m_pFileHandle); _dbg_assert_msg_(WII_IPC_FILEIO, Result == 1, "fwrite failed"); ReturnValue = Size; - - u32 NewPosition = (u32)ftell(m_pFileHandle); - if (NewPosition > m_FileLength) // Oops, we made the file longer... let's update m_FileLength then - m_FileLength = NewPosition; } Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); @@ -266,3 +269,24 @@ bool CWII_IPC_HLE_Device_FileIO::ReturnFileHandle() { return (m_pFileHandle) ? true : false; } + +void CWII_IPC_HLE_Device_FileIO::DoState(PointerWrap &p) +{ + if (p.GetMode() == PointerWrap::MODE_WRITE) + { + m_Seek = (m_pFileHandle) ? (s32)ftell(m_pFileHandle) : 0; + } + + p.Do(m_Mode); + p.Do(m_Seek); + + if (p.GetMode() == PointerWrap::MODE_READ) + { + if (m_Mode) + { + Open(NULL, m_Mode); + if (m_pFileHandle) + fseek(m_pFileHandle, m_Seek, SEEK_SET); + } + } +} \ No newline at end of file diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h index ade2221ac8..55fc807c19 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.h @@ -34,6 +34,7 @@ public: bool Write(u32 _CommandAddress); bool IOCtl(u32 _CommandAddress); bool ReturnFileHandle(); + void DoState(PointerWrap &p); private: enum @@ -71,6 +72,8 @@ private: FILE* m_pFileHandle; u32 m_FileLength; + u32 m_Mode; + s32 m_Seek; std::string m_Filename; };