-Wii System Menu now recognizes DVDs using the Load Disc/Eject feature!

Games hang though (probably due to unknown ES call)
-/dev/di IPC: Cleaned up code and fixed a bug (which I used to accidentally find out what I did), added Volume eject feature for VolumeHandler. 
-Partially documented Wii DVD cover flags.
-Files opened in Wii Read-Write mode are now set to append.
-Removed annoying overhead-ish "Idle" log message.

As for /dev/di: Someone clearly didn't know what he was doing in that file. Someone freed memory which didn't belong to that file and then complained about a crash. Needless to say the problem is now solved.

Big TODO on the /dev/di code though, ExecuteCommand is practically doing nothing but reading.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3365 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
XTra.KrazzY 2009-06-08 00:14:48 +00:00
parent c9b5fbd9bd
commit c779f95b87
7 changed files with 75 additions and 31 deletions

View File

@ -404,7 +404,7 @@ void LogPendingEvents()
void Idle() void Idle()
{ {
DEBUG_LOG(POWERPC, "Idle"); //DEBUG_LOG(POWERPC, "Idle");
idledCycles += downcount; idledCycles += downcount;
downcount = 0; downcount = 0;

View File

@ -31,13 +31,11 @@
CWII_IPC_HLE_Device_di::CWII_IPC_HLE_Device_di(u32 _DeviceID, const std::string& _rDeviceName ) CWII_IPC_HLE_Device_di::CWII_IPC_HLE_Device_di(u32 _DeviceID, const std::string& _rDeviceName )
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
, m_pVolume(NULL)
, m_pFileSystem(NULL) , m_pFileSystem(NULL)
, m_ErrorStatus(0) , m_ErrorStatus(0)
{ {
m_pVolume = VolumeHandler::GetVolume(); if (VolumeHandler::IsValid())
if (m_pVolume) m_pFileSystem = DiscIO::CreateFileSystem(VolumeHandler::GetVolume());
m_pFileSystem = DiscIO::CreateFileSystem(m_pVolume);
} }
CWII_IPC_HLE_Device_di::~CWII_IPC_HLE_Device_di() CWII_IPC_HLE_Device_di::~CWII_IPC_HLE_Device_di()
@ -47,10 +45,6 @@ CWII_IPC_HLE_Device_di::~CWII_IPC_HLE_Device_di()
delete m_pFileSystem; delete m_pFileSystem;
m_pFileSystem = NULL; m_pFileSystem = NULL;
} }
// This caused the crash in VolumeHandler.cpp, setting m_pVolume = NULL; didn't help
// it still makes VolumeHandler.cpp have a non-NULL pointer with no content so that
// delete crashes
//if(m_pVolume) { delete m_pVolume; m_pVolume = NULL; }
} }
bool CWII_IPC_HLE_Device_di::Open(u32 _CommandAddress, u32 _Mode) bool CWII_IPC_HLE_Device_di::Open(u32 _CommandAddress, u32 _Mode)
@ -67,10 +61,7 @@ bool CWII_IPC_HLE_Device_di::Close(u32 _CommandAddress)
bool CWII_IPC_HLE_Device_di::IOCtl(u32 _CommandAddress) bool CWII_IPC_HLE_Device_di::IOCtl(u32 _CommandAddress)
{ {
INFO_LOG(WII_IPC_DVD, "*******************************");
INFO_LOG(WII_IPC_DVD, "CWII_IPC_DVD_Device_di::IOCtl"); INFO_LOG(WII_IPC_DVD, "CWII_IPC_DVD_Device_di::IOCtl");
INFO_LOG(WII_IPC_DVD, "*******************************");
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);
@ -82,7 +73,7 @@ bool CWII_IPC_HLE_Device_di::IOCtl(u32 _CommandAddress)
GetDeviceName().c_str(), Command, BufferIn, BufferInSize, BufferOut, BufferOutSize); GetDeviceName().c_str(), Command, BufferIn, BufferInSize, BufferOut, BufferOutSize);
if (Command == 0x7a) if (Command == 0x7a)
DumpCommands(_CommandAddress, 8, LogTypes::WII_IPC_DVD, LogTypes::LWARNING); DumpCommands(_CommandAddress, 8, LogTypes::WII_IPC_DVD, LogTypes::LINFO);
u32 ReturnValue = ExecuteCommand(BufferIn, BufferInSize, BufferOut, BufferOutSize); u32 ReturnValue = ExecuteCommand(BufferIn, BufferInSize, BufferOut, BufferOutSize);
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
@ -92,9 +83,7 @@ bool CWII_IPC_HLE_Device_di::IOCtl(u32 _CommandAddress)
bool CWII_IPC_HLE_Device_di::IOCtlV(u32 _CommandAddress) bool CWII_IPC_HLE_Device_di::IOCtlV(u32 _CommandAddress)
{ {
INFO_LOG(WII_IPC_DVD, "*******************************");
INFO_LOG(WII_IPC_DVD, "CWII_IPC_DVD_Device_di::IOCtlV"); INFO_LOG(WII_IPC_DVD, "CWII_IPC_DVD_Device_di::IOCtlV");
INFO_LOG(WII_IPC_DVD, "*******************************");
SIOCtlVBuffer CommandBuffer(_CommandAddress); SIOCtlVBuffer CommandBuffer(_CommandAddress);
@ -155,6 +144,16 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
Memory::Memset(_BufferOut, 0, _BufferOutSize); Memory::Memset(_BufferOut, 0, _BufferOutSize);
} }
// Initializing a filesystem if it was just loaded
if(!m_pFileSystem && VolumeHandler::IsValid())
m_pFileSystem = DiscIO::CreateFileSystem(VolumeHandler::GetVolume());
// De-initializing a filesystem if the volume was unmounted
if(m_pFileSystem && !VolumeHandler::IsValid()) {
delete m_pFileSystem;
m_pFileSystem = NULL;
}
switch (Command) switch (Command)
{ {
// DVDLowInquiry // DVDLowInquiry
@ -252,19 +251,40 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
break; break;
// DVDLowPrepareCoverRegister // DVDLowPrepareCoverRegister
// DVDLowGetCoverReg - Called by "Legend of Spyro" and MP3 // DVDLowGetCoverReg - Called by "Legend of Spyro", MP3 and Wii System Menu
case 0x7a: case 0x7a:
{ {
INFO_LOG(WII_IPC_DVD, "%s executes DVDLowGetCoverReg (Buffer 0x%08x, 0x%x)", u8* buffer = Memory::GetPointer(_BufferOut);
GetDeviceName().c_str(), _BufferOut, _BufferOutSize);
// DVD Cover Register States:
// 0x00: Unknown state (keeps checking for DVD)
// 0x01: No Disc inside
// 0xFE: Reads Disc
// -------------------------------------------------------------------- // We notify the application that we ejected a disc by
/* Hack for Legend of Spyro. Switching the 4th byte between 0 and 1 gets // replacing the Change Disc menu button with "Eject" which
// in turn makes volume handler invalid for at least one
// ioctl and then the user has enough time to load another
// disc.
// TODO: Make ejection mechanism recognized. (Currently eject
// only works if DVDLowReset is called)
buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0x00;
if(m_pFileSystem)
buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0xFE;
INFO_LOG(WII_IPC_DVD, "%s executes DVDLowGetCoverReg (Buffer 0x%08x, 0x%x) %s",
GetDeviceName().c_str(), _BufferOut, _BufferOutSize,
ArrayToString(buffer, _BufferOutSize, 0, _BufferOutSize).c_str());
/*
Hack for Legend of Spyro. Switching the 4th byte between 0 and 1 gets
through this check. The out buffer address remains the same all the through this check. The out buffer address remains the same all the
time so we don't have to bother making a global function. time so we don't have to bother making a global function.
TODO: Make this compatible with MP3 */ TODO: Make this compatible with MP3
// -------------------------
/* /*
static u8 coverByte = 0; static u8 coverByte = 0;
@ -275,9 +295,10 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
coverByte = 0; coverByte = 0;
else else
coverByte = 0x01; coverByte = 0x01;
return 1; return 1;
*/ */
} }
break; break;

View File

@ -43,7 +43,6 @@ private:
u32 ExecuteCommand(u32 BufferIn, u32 BufferInSize, u32 _BufferOut, u32 BufferOutSize); u32 ExecuteCommand(u32 BufferIn, u32 BufferInSize, u32 _BufferOut, u32 BufferOutSize);
DiscIO::IVolume* m_pVolume;
DiscIO::IFileSystem* m_pFileSystem; DiscIO::IFileSystem* m_pFileSystem;
u32 m_ErrorStatus; u32 m_ErrorStatus;
}; };

View File

@ -49,11 +49,7 @@ CWII_IPC_HLE_Device_FileIO::CWII_IPC_HLE_Device_FileIO(u32 _DeviceID, const std:
CWII_IPC_HLE_Device_FileIO::~CWII_IPC_HLE_Device_FileIO() CWII_IPC_HLE_Device_FileIO::~CWII_IPC_HLE_Device_FileIO()
{ {
if (m_pFileHandle != NULL)
{
fclose(m_pFileHandle);
m_pFileHandle = NULL;
}
} }
bool bool
@ -62,6 +58,12 @@ CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress)
u32 DeviceID = Memory::Read_U32(_CommandAddress + 8); u32 DeviceID = Memory::Read_U32(_CommandAddress + 8);
INFO_LOG(WII_IPC_FILEIO, "FileIO: Close %s (DeviceID=%08x)", GetDeviceName().c_str(), DeviceID); INFO_LOG(WII_IPC_FILEIO, "FileIO: Close %s (DeviceID=%08x)", GetDeviceName().c_str(), DeviceID);
if (m_pFileHandle != NULL)
{
fclose(m_pFileHandle);
m_pFileHandle = NULL;
}
// Close always return 0 for success // Close always return 0 for success
Memory::Write_U32(0, _CommandAddress + 4); Memory::Write_U32(0, _CommandAddress + 4);
@ -101,7 +103,7 @@ CWII_IPC_HLE_Device_FileIO::Open(u32 _CommandAddress, u32 _Mode)
{ {
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(), "a+b"); break;
default: PanicAlert("CWII_IPC_HLE_Device_FileIO: unknown open mode"); break; default: PanicAlert("CWII_IPC_HLE_Device_FileIO: unknown open mode"); break;
} }
} }

View File

@ -27,6 +27,19 @@ DiscIO::IVolume *GetVolume() {
return g_pVolume; return g_pVolume;
} }
void EjectVolume()
{
if (g_pVolume)
{
// This code looks scary. Can the try/catch stuff be removed?
// This cause a "Unhandled exception ... Access violation
// reading location ..." after you have started and stopped two
// or three games
delete g_pVolume;
g_pVolume = NULL;
}
}
bool SetVolumeName(const std::string& _rFullPath) bool SetVolumeName(const std::string& _rFullPath)
{ {
if (g_pVolume) if (g_pVolume)

View File

@ -42,6 +42,8 @@ bool IsWii();
DiscIO::IVolume *GetVolume(); DiscIO::IVolume *GetVolume();
void EjectVolume();
} // namespace } // namespace
#endif #endif

View File

@ -131,7 +131,7 @@ void CFrame::CreateMenu()
// Emulation menu // Emulation menu
wxMenu* emulationMenu = new wxMenu; wxMenu* emulationMenu = new wxMenu;
emulationMenu->Append(IDM_PLAY, _T("&Play")); emulationMenu->Append(IDM_PLAY, _T("&Play"));
emulationMenu->Append(IDM_CHANGEDISC, _T("Change Disc")); emulationMenu->Append(IDM_CHANGEDISC, _T("Load Disc"));
emulationMenu->Append(IDM_STOP, _T("&Stop")); emulationMenu->Append(IDM_STOP, _T("&Stop"));
emulationMenu->AppendSeparator(); emulationMenu->AppendSeparator();
wxMenu *saveMenu = new wxMenu; wxMenu *saveMenu = new wxMenu;
@ -485,10 +485,17 @@ void CFrame::DoOpen(bool Boot)
void CFrame::OnChangeDisc(wxCommandEvent& WXUNUSED (event)) void CFrame::OnChangeDisc(wxCommandEvent& WXUNUSED (event))
{ {
if(VolumeHandler::IsValid()) {
VolumeHandler::EjectVolume();
GetMenuBar()->FindItem(IDM_CHANGEDISC)->SetText("Load Disc");
return;
}
DVDInterface::SetLidOpen(true); DVDInterface::SetLidOpen(true);
DoOpen(false); DoOpen(false);
DVDInterface::SetLidOpen(false); DVDInterface::SetLidOpen(false);
DVDInterface::SetDiscInside(true); DVDInterface::SetDiscInside(true);
GetMenuBar()->FindItem(IDM_CHANGEDISC)->SetText("Eject");
} }
void CFrame::OnPlay(wxCommandEvent& WXUNUSED (event)) void CFrame::OnPlay(wxCommandEvent& WXUNUSED (event))