Wii IOS FileIO: Fixed bug "NewSeekPosition = 0" to "NewSeekPosition = SeekPosition", now Zelda TP savegames should work as well as other games
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1981 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
e332e18ce6
commit
d7fe42d069
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
|
#include "StringUtil.h"
|
||||||
|
|
||||||
#include "WII_IPC_HLE_Device_FileIO.h"
|
#include "WII_IPC_HLE_Device_FileIO.h"
|
||||||
|
|
||||||
|
@ -39,19 +40,19 @@ std::string HLE_IPC_BuildFilename(const char* _pFilename, int _size)
|
||||||
}
|
}
|
||||||
|
|
||||||
CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName )
|
CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std::string& _rDeviceName )
|
||||||
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
|
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
|
||||||
, m_pFileHandle(NULL)
|
, m_pFileHandle(NULL)
|
||||||
, m_FileLength(0)
|
, m_FileLength(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CWII_IPC_HLE_Device_FileIO::~CWII_IPC_HLE_Device_FileIO()
|
CWII_IPC_HLE_Device_FileIO::~CWII_IPC_HLE_Device_FileIO()
|
||||||
{
|
{
|
||||||
if (m_pFileHandle != NULL)
|
if (m_pFileHandle != NULL)
|
||||||
{
|
{
|
||||||
fclose(m_pFileHandle);
|
fclose(m_pFileHandle);
|
||||||
m_pFileHandle = NULL;
|
m_pFileHandle = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -92,7 +93,7 @@ CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
||||||
{
|
{
|
||||||
switch(_Mode)
|
switch(_Mode)
|
||||||
{
|
{
|
||||||
// Do "r+b" for all writing to avoid truncating the file
|
// Do "r+b" for all writing to avoid truncating the file
|
||||||
case 0x01: m_pFileHandle = fopen(m_Filename.c_str(), "rb"); break;
|
case 0x01: m_pFileHandle = fopen(m_Filename.c_str(), "rb"); break;
|
||||||
case 0x02: //m_pFileHandle = fopen(m_Filename.c_str(), "wb"); break;
|
case 0x02: //m_pFileHandle = fopen(m_Filename.c_str(), "wb"); break;
|
||||||
case 0x03: m_pFileHandle = fopen(m_Filename.c_str(), "r+b"); break;
|
case 0x03: m_pFileHandle = fopen(m_Filename.c_str(), "r+b"); break;
|
||||||
|
@ -101,19 +102,19 @@ CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 ReturnValue = 0;
|
u32 ReturnValue = 0;
|
||||||
if (m_pFileHandle != NULL)
|
if (m_pFileHandle != NULL)
|
||||||
{
|
{
|
||||||
m_FileLength = File::GetSize(m_Filename.c_str());
|
m_FileLength = File::GetSize(m_Filename.c_str());
|
||||||
ReturnValue = GetDeviceID();
|
ReturnValue = GetDeviceID();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG(WII_IPC_FILEIO, " failed - File doesn't exist");
|
LOG(WII_IPC_FILEIO, " failed - File doesn't exist");
|
||||||
ReturnValue = -106;
|
ReturnValue = -106;
|
||||||
}
|
}
|
||||||
|
|
||||||
Memory::Write_U32(ReturnValue, _CommandAddress+4);
|
Memory::Write_U32(ReturnValue, _CommandAddress+4);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -123,58 +124,79 @@ CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
||||||
u32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC);
|
u32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC);
|
||||||
u32 Mode = Memory::Read_U32(_CommandAddress +0x10);
|
u32 Mode = Memory::Read_U32(_CommandAddress +0x10);
|
||||||
|
|
||||||
LOG(WII_IPC_FILEIO, "FileIO: Seek Pos: %i, Mode: %i (Device=%s)", SeekPosition, Mode, GetDeviceName().c_str());
|
LOG(WII_IPC_FILEIO, "FileIO: Old Seek Pos: %s, Mode: %i (Device=%s, FileSize=%s)", ThS(SeekPosition).c_str(), Mode, GetDeviceName().c_str(), ThS(m_FileLength).c_str());
|
||||||
|
|
||||||
|
/* Zelda - TP Fix: It doesn't make much sense but it works in Zelda - TP and
|
||||||
|
it's probably better than trying to read outside the file (it seeks to 0x6000 instead
|
||||||
|
of the correct 0x2000 for the second half of the file). Could this be right
|
||||||
|
or has it misunderstood the filesize somehow? My guess is that the filesize is
|
||||||
|
hardcoded in to the game, and it never checks the filesize, so I don't know.
|
||||||
|
Maybe it's wrong to return the seekposition when it's zero? Perhaps it wants
|
||||||
|
the filesize then? - No, that didn't work either, it seeks to 0x6000 even if I return
|
||||||
|
0x4000 from the first seek. */
|
||||||
|
u32 NewSeekPosition = SeekPosition;
|
||||||
|
if (m_FileLength > 0 && SeekPosition > m_FileLength && Mode == 0)
|
||||||
|
{
|
||||||
|
NewSeekPosition = SeekPosition % m_FileLength;
|
||||||
|
LOG(WII_IPC_FILEIO, "***********************************:");
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(WII_IPC_FILEIO, "FileIO: New Seek Pos: %s, Mode: %i (Device=%s)", ThS(NewSeekPosition).c_str(), Mode, GetDeviceName().c_str());
|
||||||
|
|
||||||
|
// Set seek mode
|
||||||
int seek_mode[3] = {SEEK_SET, SEEK_CUR, SEEK_END};
|
int seek_mode[3] = {SEEK_SET, SEEK_CUR, SEEK_END};
|
||||||
|
|
||||||
if (Mode >= 0 && Mode <= 2) {
|
if (Mode >= 0 && Mode <= 2)
|
||||||
if (fseek(m_pFileHandle, SeekPosition, seek_mode[Mode]) == 0) {
|
{
|
||||||
|
if (fseek(m_pFileHandle, NewSeekPosition, seek_mode[Mode]) == 0)
|
||||||
|
{
|
||||||
// Seek always return the seek position for success
|
// Seek always return the seek position for success
|
||||||
// Not sure if it's right in all modes though.
|
// Not sure if it's right in all modes though.
|
||||||
ReturnValue = SeekPosition;
|
// What should we return for Zelda, the new correct or old incorrect seek position?
|
||||||
} else {
|
ReturnValue = SeekPosition;
|
||||||
LOG(WII_IPC_FILEIO, "FILEIO: Seek failed");
|
} else {
|
||||||
}
|
LOG(WII_IPC_FILEIO, "FILEIO: Seek failed");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
PanicAlert("CWII_IPC_HLE_Device_FileIO unsupported seek mode %i", Mode);
|
PanicAlert("CWII_IPC_HLE_Device_FileIO unsupported seek mode %i", Mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
|
CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
|
||||||
{
|
{
|
||||||
u32 ReturnValue = 0;
|
u32 ReturnValue = 0;
|
||||||
u32 Address = Memory::Read_U32(_CommandAddress +0xC);
|
u32 Address = Memory::Read_U32(_CommandAddress +0xC); // Read to this memory address
|
||||||
u32 Size = Memory::Read_U32(_CommandAddress +0x10);
|
u32 Size = Memory::Read_U32(_CommandAddress +0x10);
|
||||||
|
|
||||||
if (m_pFileHandle != NULL)
|
if (m_pFileHandle != NULL)
|
||||||
{
|
{
|
||||||
size_t readItems = fread(Memory::GetPointer(Address), 1, Size, m_pFileHandle);
|
LOG(WII_IPC_FILEIO, "FileIO: Read 0x%x bytes to 0x%08x from %s", Size, Address, GetDeviceName().c_str());
|
||||||
ReturnValue = (u32)readItems;
|
size_t readItems = fread(Memory::GetPointer(Address), 1, Size, m_pFileHandle);
|
||||||
LOG(WII_IPC_FILEIO, "FileIO reads from %s (Addr=0x%08x Size=0x%x)", GetDeviceName().c_str(), Address, Size);
|
ReturnValue = (u32)readItems;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG(WII_IPC_FILEIO, "FileIO failed to read from %s (Addr=0x%08x Size=0x%x) - file not open", GetDeviceName().c_str(), Address, Size);
|
LOG(WII_IPC_FILEIO, "FileIO failed to read from %s (Addr=0x%08x Size=0x%x) - file not open", GetDeviceName().c_str(), Address, Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
|
CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
|
||||||
{
|
{
|
||||||
u32 ReturnValue = 0;
|
u32 ReturnValue = 0;
|
||||||
u32 Address = Memory::Read_U32(_CommandAddress +0xC);
|
u32 Address = Memory::Read_U32(_CommandAddress +0xC); // Write data from this memory address
|
||||||
u32 Size = Memory::Read_U32(_CommandAddress +0x10);
|
u32 Size = Memory::Read_U32(_CommandAddress +0x10);
|
||||||
|
|
||||||
LOG(WII_IPC_FILEIO, "FileIO: Write Addr: 0x%08x Size: %i (Device=%s)", Address, Size, GetDeviceName().c_str());
|
LOG(WII_IPC_FILEIO, "FileIO: Write 0x%04x bytes to 0x%08x from %s", Size, Address, GetDeviceName().c_str());
|
||||||
|
|
||||||
if (m_pFileHandle)
|
if (m_pFileHandle)
|
||||||
{
|
{
|
||||||
|
@ -184,52 +206,52 @@ CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
|
||||||
ReturnValue = Size;
|
ReturnValue = Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
|
CWII_IPC_HLE_Device_FileIO::IOCtl(u32 _CommandAddress)
|
||||||
{
|
{
|
||||||
LOG(WII_IPC_FILEIO, "FileIO: IOCtl (Device=%s)", GetDeviceName().c_str());
|
LOG(WII_IPC_FILEIO, "FileIO: IOCtl (Device=%s)", GetDeviceName().c_str());
|
||||||
DumpCommands(_CommandAddress);
|
DumpCommands(_CommandAddress);
|
||||||
|
|
||||||
u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC);
|
u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC);
|
||||||
|
|
||||||
// u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
|
// u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
|
||||||
// u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14);
|
// u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14);
|
||||||
// u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
|
// u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
|
||||||
// u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
|
// u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
|
||||||
|
|
||||||
switch(Parameter)
|
switch(Parameter)
|
||||||
{
|
{
|
||||||
case ISFS_IOCTL_GETFILESTATS:
|
case ISFS_IOCTL_GETFILESTATS:
|
||||||
{
|
{
|
||||||
u32 Position = (u32)ftell(m_pFileHandle);
|
u32 Position = (u32)ftell(m_pFileHandle);
|
||||||
|
|
||||||
u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
|
u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
|
||||||
LOG(WII_IPC_FILEIO, "FileIO: ISFS_IOCTL_GETFILESTATS");
|
LOG(WII_IPC_FILEIO, "FileIO: ISFS_IOCTL_GETFILESTATS");
|
||||||
LOG(WII_IPC_FILEIO, " Length: %i Seek: %i", m_FileLength, Position);
|
LOG(WII_IPC_FILEIO, " Length: %i Seek: %i", m_FileLength, Position);
|
||||||
|
|
||||||
Memory::Write_U32((u32)m_FileLength, BufferOut);
|
Memory::Write_U32((u32)m_FileLength, BufferOut);
|
||||||
Memory::Write_U32(Position, BufferOut+4);
|
Memory::Write_U32(Position, BufferOut+4);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
PanicAlert("CWII_IPC_HLE_Device_FileIO: Parameter %i", Parameter);
|
PanicAlert("CWII_IPC_HLE_Device_FileIO: Parameter %i", Parameter);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return Value
|
// Return Value
|
||||||
u32 ReturnValue = 0; // no error
|
u32 ReturnValue = 0; // no error
|
||||||
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
Loading…
Reference in New Issue