Mario Kart Wii now works if you use an old save file
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1318 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
ca68a6f168
commit
1bc53f87dc
|
@ -163,6 +163,7 @@ IWII_IPC_HLE_Device* CreateDevice(u32 _DeviceID, const std::string& _rDeviceName
|
|||
}
|
||||
else
|
||||
{
|
||||
LOGV(WII_IPC_FILEIO, 0, "FS: New pDevice %s", _rDeviceName.c_str());
|
||||
pDevice = new CWII_IPC_HLE_Device_FileIO(_DeviceID, _rDeviceName);
|
||||
}
|
||||
|
||||
|
@ -228,7 +229,15 @@ void ExecuteCommand(u32 _Address)
|
|||
|
||||
u32 Mode = Memory::Read_U32(_Address+0x10);
|
||||
u32 DeviceID = GetDeviceIDByName(DeviceName);
|
||||
if (DeviceID == 0)
|
||||
|
||||
/* TEMPORARY SOLUTION: For some reason no file was written after a ReOpen in
|
||||
Mario Galaxy and Mario Kart Wii so I had to do a Open instead */
|
||||
if (DeviceID == 0
|
||||
|| DeviceName.find(".bin") != std::string::npos // Do Open instead for common
|
||||
|| DeviceName.find(".dat") != std::string::npos // save game file types
|
||||
|| DeviceName.find(".vff") != std::string::npos
|
||||
|| DeviceName.find(".mod") != std::string::npos
|
||||
)
|
||||
{
|
||||
// create the new device
|
||||
// alternatively we could pre create all devices and put them in a directory tree structure
|
||||
|
|
|
@ -61,14 +61,16 @@ CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress)
|
|||
{
|
||||
LOG(WII_IPC_FILEIO, "FileIO: Close %s", GetDeviceName().c_str());
|
||||
|
||||
Memory::Write_U32(0, _CommandAddress+4);
|
||||
// Close always return 0 for success
|
||||
Memory::Write_U32(0, _CommandAddress + 4);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
||||
{
|
||||
LOG(WII_IPC_FILEIO, "FileIO::Open=======================================================");
|
||||
LOG(WII_IPC_FILEIO, "===================================================================");
|
||||
|
||||
u32 ReturnValue = 0;
|
||||
|
||||
|
@ -88,8 +90,9 @@ CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
|
|||
{
|
||||
switch(_Mode)
|
||||
{
|
||||
// Do "r+b" for all writing to avoid truncating the file
|
||||
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;
|
||||
default: PanicAlert("CWII_IPC_HLE_Device_FileIO: unknown open mode"); break;
|
||||
}
|
||||
|
@ -118,16 +121,17 @@ bool
|
|||
CWII_IPC_HLE_Device_FileIO::Seek(u32 _CommandAddress)
|
||||
{
|
||||
u32 ReturnValue = 0;
|
||||
u32 SeekPosition = Memory::Read_U32(_CommandAddress +0xC);
|
||||
u32 SeekPosition = Memory::Read_U32(_CommandAddress + 0xC);
|
||||
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: Seek Pos: %i, Mode: %i (Device=%s)", SeekPosition, Mode, GetDeviceName().c_str());
|
||||
|
||||
switch(Mode)
|
||||
{
|
||||
case 0:
|
||||
fseek(m_pFileHandle, SeekPosition, SEEK_SET);
|
||||
ReturnValue = 0;
|
||||
// Seek always return the seek position for success
|
||||
ReturnValue = SeekPosition;
|
||||
break;
|
||||
|
||||
case 1: // cur
|
||||
|
@ -147,7 +151,7 @@ CWII_IPC_HLE_Device_FileIO::Read(u32 _CommandAddress)
|
|||
{
|
||||
u32 ReturnValue = 0;
|
||||
u32 Address = Memory::Read_U32(_CommandAddress +0xC);
|
||||
u32 Size = Memory::Read_U32(_CommandAddress +0x10);
|
||||
u32 Size = Memory::Read_U32(_CommandAddress +0x10);
|
||||
|
||||
if (m_pFileHandle != NULL)
|
||||
{
|
||||
|
@ -177,6 +181,8 @@ CWII_IPC_HLE_Device_FileIO::Write(u32 _CommandAddress)
|
|||
if (m_pFileHandle)
|
||||
{
|
||||
fwrite(Memory::GetPointer(Address), Size, 1, m_pFileHandle);
|
||||
|
||||
// Write always return the written bytes for success
|
||||
ReturnValue = Size;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,9 +74,34 @@ public:
|
|||
|
||||
virtual bool IOCtlV(u32 _CommandAddress)
|
||||
{
|
||||
LOG(WII_IPC_HLE, "%s", GetDeviceName().c_str());
|
||||
|
||||
SIOCtlVBuffer Buffer(_CommandAddress);
|
||||
|
||||
LOG(WII_IPC_ES, "%s (0x%x)", GetDeviceName().c_str(), Buffer.Parameter);
|
||||
|
||||
/* Extended logs
|
||||
//if(Buffer.Parameter == IOCTL_ES_GETTITLEDIR || Buffer.Parameter == IOCTL_ES_GETTITLEID ||
|
||||
// Buffer.Parameter == IOCTL_ES_GETVIEWCNT || Buffer.Parameter == IOCTL_ES_GETTMDVIEWCNT)
|
||||
{
|
||||
u32 OutBuffer = Memory::Read_U32(Buffer.PayloadBuffer[0].m_Address | 0x80000000);
|
||||
if(Buffer.NumberInBuffer > 0)
|
||||
{
|
||||
u32 InBuffer = Memory::Read_U32(Buffer.InBuffer[0].m_Address | 0x80000000);
|
||||
LOG(WII_IPC_ES, "ES Parameter: 0x%x (In: %i, Out:%i) (In 0x%08x = 0x%08x %i) (Out 0x%08x = 0x%08x %i)",
|
||||
Buffer.Parameter,
|
||||
Buffer.NumberInBuffer, Buffer.NumberPayloadBuffer,
|
||||
Buffer.InBuffer[0].m_Address, InBuffer, Buffer.InBuffer[0].m_Size,
|
||||
Buffer.PayloadBuffer[0].m_Address, OutBuffer, Buffer.PayloadBuffer[0].m_Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WII_IPC_ES, "ES Parameter: 0x%x (In: %i, Out:%i) (Out 0x%08x = 0x%08x %i)",
|
||||
Buffer.Parameter,
|
||||
Buffer.NumberInBuffer, Buffer.NumberPayloadBuffer,
|
||||
Buffer.PayloadBuffer[0].m_Address, OutBuffer, Buffer.PayloadBuffer[0].m_Size);
|
||||
}
|
||||
//DumpCommands(_CommandAddress, 8);
|
||||
}*/
|
||||
|
||||
switch(Buffer.Parameter)
|
||||
{
|
||||
case IOCTL_ES_GETTITLEDIR: // ES_GetDataDir in DevKitPro
|
||||
|
@ -94,7 +119,7 @@ public:
|
|||
}
|
||||
break;
|
||||
|
||||
case IOCTL_ES_GETTITLEID:
|
||||
case IOCTL_ES_GETTITLEID: // ES_GetTitleID in DevKitPro
|
||||
{
|
||||
u32 OutBuffer = Memory::Read_U32(Buffer.PayloadBuffer[0].m_Address);
|
||||
|
||||
|
@ -102,6 +127,7 @@ public:
|
|||
if (TitleID == 0)
|
||||
TitleID = 0xF00DBEEF;
|
||||
|
||||
// Write the Title ID to 0x00000000
|
||||
Memory::Write_U32(TitleID, OutBuffer);
|
||||
|
||||
LOG(WII_IPC_ES, "ES: IOCTL_ES_GETTITLEID: 0x%x", TitleID);
|
||||
|
@ -117,7 +143,7 @@ public:
|
|||
u32 InBuffer = Memory::Read_U32(Buffer.InBuffer[0].m_Address);
|
||||
|
||||
// Should we write something here?
|
||||
//Memory::Write_U32(0, Buffer.PayloadBuffer[0].m_Address);
|
||||
Memory::Write_U32(0, Buffer.PayloadBuffer[0].m_Address);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -129,7 +155,7 @@ public:
|
|||
u32 InBuffer = Memory::Read_U32(Buffer.InBuffer[0].m_Address);
|
||||
|
||||
// Should we write something here?
|
||||
//Memory::Write_U32(0, Buffer.PayloadBuffer[0].m_Address);
|
||||
Memory::Write_U32(0, Buffer.PayloadBuffer[0].m_Address);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -161,32 +187,8 @@ public:
|
|||
break;
|
||||
}
|
||||
|
||||
/* Extended logs
|
||||
//if(Buffer.Parameter == IOCTL_ES_GETTITLEDIR || Buffer.Parameter == IOCTL_ES_GETTITLEID ||
|
||||
// Buffer.Parameter == IOCTL_ES_GETVIEWCNT || Buffer.Parameter == IOCTL_ES_GETTMDVIEWCNT)
|
||||
{
|
||||
u32 OutBuffer = Memory::Read_U32(Buffer.PayloadBuffer[0].m_Address);
|
||||
if(Buffer.NumberInBuffer > 0)
|
||||
{
|
||||
u32 InBuffer = Memory::Read_U32(Buffer.InBuffer[0].m_Address);
|
||||
LOG(WII_IPC_ES, "ES Parameter: 0x%x (In: %i, Out:%i) (In 0x%08x = 0x%08x %i) (Out 0x%08x = 0x%08x %i)",
|
||||
Buffer.Parameter,
|
||||
Buffer.NumberInBuffer, Buffer.NumberPayloadBuffer,
|
||||
Buffer.InBuffer[0].m_Address, InBuffer, Buffer.InBuffer[0].m_Size,
|
||||
Buffer.PayloadBuffer[0].m_Address, OutBuffer, Buffer.PayloadBuffer[0].m_Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WII_IPC_ES, "ES Parameter: 0x%x (In: %i, Out:%i) (Out 0x%08x = 0x%08x %i)",
|
||||
Buffer.Parameter,
|
||||
Buffer.NumberInBuffer, Buffer.NumberPayloadBuffer,
|
||||
Buffer.PayloadBuffer[0].m_Address, OutBuffer, Buffer.PayloadBuffer[0].m_Size);
|
||||
}
|
||||
//DumpCommands(_CommandAddress, 8);
|
||||
} */
|
||||
|
||||
// write return value
|
||||
Memory::Write_U32(0, _CommandAddress + 0x4);
|
||||
// Write return value (0 means OK)
|
||||
Memory::Write_U32(0, _CommandAddress + 0x4);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -100,11 +100,14 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
|
|||
|
||||
LOG(WII_IPC_FILEIO, "FS: IOCTL_READ_DIR %s", Filename.c_str());
|
||||
|
||||
// check if this is really a directory
|
||||
if (!File::IsDirectory(Filename.c_str()))
|
||||
/* Check if this is really a directory. Or a file, because it seems like Mario Kart
|
||||
did a IOCTL_READ_DIR on the save file to check if it existed before deleting it,
|
||||
and if I returned a -something it never deleted the file presumably because it
|
||||
thought it didn't exist. So this solution worked for Mario Kart. */
|
||||
if (!File::Exists(Filename.c_str()) && !File::IsDirectory(Filename.c_str()))
|
||||
{
|
||||
LOG(WII_IPC_FILEIO, " Not a directory - return -6 (dunno if this is a correct return value)", Filename.c_str());
|
||||
ReturnValue = -6;
|
||||
LOG(WII_IPC_FILEIO, " No file and not a directory - return -6 (dunno if this is a correct return value)", Filename.c_str());
|
||||
ReturnValue = -6;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -127,8 +130,6 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
memset(Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address), 0, CommandBuffer.PayloadBuffer[0].m_Size);
|
||||
|
||||
size_t numFile = FileSearch.GetFileNames().size();
|
||||
|
@ -167,7 +168,7 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
|
|||
u32 fsBlock = 0;
|
||||
u32 iNodes = 0;
|
||||
|
||||
LOG(WII_IPC_FILEIO, "FS: IOCTL_GETUSAGE %s", Filename.c_str());
|
||||
LOGV(WII_IPC_FILEIO, 1, "FS: IOCTL_GETUSAGE %s", Filename.c_str());
|
||||
if (File::IsDirectory(Filename.c_str()))
|
||||
{
|
||||
// make a file search
|
||||
|
@ -190,14 +191,14 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress)
|
|||
|
||||
ReturnValue = 0;
|
||||
|
||||
LOG(WII_IPC_FILEIO, " fsBlock: %i, iNodes: %i", fsBlock, iNodes);
|
||||
LOGV(WII_IPC_FILEIO, 1, " fsBlock: %i, iNodes: %i", fsBlock, iNodes);
|
||||
}
|
||||
else
|
||||
{
|
||||
fsBlock = 0;
|
||||
iNodes = 0;
|
||||
ReturnValue = 0;
|
||||
LOG(WII_IPC_FILEIO, " error: not executed on a valid directoy: %s", Filename.c_str());
|
||||
LOGV(WII_IPC_FILEIO, 1, " error: not executed on a valid directoy: %s", Filename.c_str());
|
||||
}
|
||||
|
||||
Memory::Write_U32(fsBlock, CommandBuffer.PayloadBuffer[0].m_Address);
|
||||
|
|
|
@ -58,26 +58,31 @@ bool CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress)
|
|||
|
||||
s32 CWII_IPC_HLE_Device_net_kd_request::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize)
|
||||
{
|
||||
// Requests are made in this order by these games
|
||||
// Mario Kart: 2, 1, f, 3
|
||||
// SSBB: 2, 3
|
||||
// -----------------------
|
||||
/* Requests are made in this order by these games
|
||||
Mario Kart: 2, 1, f, 3
|
||||
SSBB: 2, 3
|
||||
|
||||
For Mario Kart I had to return -1 from at least 2, f and 3 to convince it that the network
|
||||
was unavaliable and prevent if from looking for shared2/wc24 files (and do a PPCHalt when
|
||||
it failed) */
|
||||
// -------
|
||||
|
||||
/* Extended logs
|
||||
//if(_Parameter == 2 || _Parameter == 3)
|
||||
if(true)
|
||||
{
|
||||
u32 OutBuffer = Memory::Read_U32(_BufferOut);
|
||||
if(_BufferInSize > 0)
|
||||
{
|
||||
u32 InBuffer = Memory::Read_U32(_BufferIn);
|
||||
LOG(WII_IPC_ES, "NET_KD_REQ: IOCtl Parameter: 0x%x (In 0x%08x = 0x%08x %i) (Out 0x%08x = 0x%08x %i)",
|
||||
LOG(WII_IPC_NET, "NET_KD_REQ: IOCtl Parameter: 0x%x (In 0x%08x = 0x%08x %i) (Out 0x%08x = 0x%08x %i)",
|
||||
_Parameter,
|
||||
_BufferIn, InBuffer, _BufferInSize,
|
||||
_BufferOut, OutBuffer, _BufferOutSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WII_IPC_ES, "NET_KD_REQ: IOCtl Parameter: 0x%x (Out 0x%08x = 0x%08x %i)",
|
||||
LOG(WII_IPC_NET, "NET_KD_REQ: IOCtl Parameter: 0x%x (Out 0x%08x = 0x%08x %i)",
|
||||
_Parameter,
|
||||
_BufferOut, OutBuffer, _BufferOutSize);
|
||||
}
|
||||
|
@ -86,17 +91,21 @@ s32 CWII_IPC_HLE_Device_net_kd_request::ExecuteCommand(u32 _Parameter, u32 _Buff
|
|||
switch(_Parameter)
|
||||
{
|
||||
case 1: // SuspendScheduler (Input: none, Output: 32 bytes)
|
||||
Memory::Write_U32(0, _BufferOut);
|
||||
//Memory::Write_U32(0, _BufferOut);
|
||||
return -1;
|
||||
break;
|
||||
case 2: /* ExecTrySuspendScheduler (Input: 32 bytes, Output: 32 bytes). Sounds like it will check
|
||||
if it should suspend the updates scheduler or not. */
|
||||
Memory::Write_U32(1, _BufferOut);
|
||||
//Memory::Write_U32(0, _BufferOut);
|
||||
return -1;
|
||||
break;
|
||||
case 3: // ?
|
||||
Memory::Write_U32(0, _BufferOut);
|
||||
//Memory::Write_U32(0, _BufferOut);
|
||||
return -1;
|
||||
break;
|
||||
case 0xf: // NWC24iRequestGenerateUserId (Input: none, Output: 32 bytes)
|
||||
Memory::Write_U32(0, _BufferOut);
|
||||
//Memory::Write_U32(0, _BufferOut);
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
_dbg_assert_msg_(WII_IPC_NET, 0, "/dev/net/kd/request::IOCtl request 0x%x (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
|
||||
|
@ -104,7 +113,7 @@ s32 CWII_IPC_HLE_Device_net_kd_request::ExecuteCommand(u32 _Parameter, u32 _Buff
|
|||
break;
|
||||
}
|
||||
|
||||
// Should we always return 0?
|
||||
// We return a success for any potential unknown requests
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -135,8 +144,8 @@ bool CWII_IPC_HLE_Device_net_ncd_manage::IOCtlV(u32 _CommandAddress)
|
|||
switch(CommandBuffer.Parameter)
|
||||
{
|
||||
default:
|
||||
LOG(WII_IPC_NET, "CWII_IPC_HLE_Device_fs::IOCtlV: %i", CommandBuffer.Parameter);
|
||||
_dbg_assert_msg_(WII_IPC_NET, 0, "CWII_IPC_HLE_Device_fs::IOCtlV: %i", CommandBuffer.Parameter);
|
||||
LOG(WII_IPC_NET, "NET_NCD_MANAGE IOCtlV: %i", CommandBuffer.Parameter);
|
||||
_dbg_assert_msg_(WII_IPC_NET, 0, "NET_NCD_MANAGE IOCtlV: %i", CommandBuffer.Parameter);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -301,6 +301,10 @@ void LogManager::Log(LogTypes::LOG_TYPE _type, const char *_fmt, ...)
|
|||
&& m_LogSettings->bWriteMaster)
|
||||
fprintf(m_Log[ver*100 + LogTypes::MASTER_LOG]->m_pFile, "%s", Msg2);
|
||||
|
||||
// Write now. Is this slower than caching it?
|
||||
//fflush(m_Log[id]->m_pFile);
|
||||
//fflush(m_Log[ver*100 + LogTypes::MASTER_LOG]->m_pFile);
|
||||
|
||||
printf("%s", Msg2); // write to console screen
|
||||
|
||||
// this limits the memory space used for the memory logs to MAX_MESSAGES rows
|
||||
|
@ -329,6 +333,10 @@ void LogManager::Log(LogTypes::LOG_TYPE _type, const char *_fmt, ...)
|
|||
&& m_LogSettings->bWriteMaster)
|
||||
fprintf(m_Log[i*100 + LogTypes::MASTER_LOG]->m_pFile, "%s", Msg2);
|
||||
|
||||
// Write now. Is this slower than caching it?
|
||||
//fflush(m_Log[id]->m_pFile);
|
||||
//fflush(m_Log[i*100 + LogTypes::MASTER_LOG]->m_pFile);
|
||||
|
||||
printf("%s", Msg2); // write to console screen
|
||||
|
||||
// this limits the memory space used for the memory logs to MAX_MESSAGES rows
|
||||
|
|
Loading…
Reference in New Issue