-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()
{
DEBUG_LOG(POWERPC, "Idle");
//DEBUG_LOG(POWERPC, "Idle");
idledCycles += downcount;
downcount = 0;

View File

@ -31,13 +31,11 @@
CWII_IPC_HLE_Device_di::CWII_IPC_HLE_Device_di(u32 _DeviceID, const std::string& _rDeviceName )
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
, m_pVolume(NULL)
, m_pFileSystem(NULL)
, m_ErrorStatus(0)
{
m_pVolume = VolumeHandler::GetVolume();
if (m_pVolume)
m_pFileSystem = DiscIO::CreateFileSystem(m_pVolume);
if (VolumeHandler::IsValid())
m_pFileSystem = DiscIO::CreateFileSystem(VolumeHandler::GetVolume());
}
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;
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)
@ -67,10 +61,7 @@ bool CWII_IPC_HLE_Device_di::Close(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, "*******************************");
u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
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);
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);
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)
{
INFO_LOG(WII_IPC_DVD, "*******************************");
INFO_LOG(WII_IPC_DVD, "CWII_IPC_DVD_Device_di::IOCtlV");
INFO_LOG(WII_IPC_DVD, "*******************************");
SIOCtlVBuffer CommandBuffer(_CommandAddress);
@ -155,6 +144,16 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
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)
{
// DVDLowInquiry
@ -252,19 +251,40 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
break;
// DVDLowPrepareCoverRegister
// DVDLowGetCoverReg - Called by "Legend of Spyro" and MP3
// DVDLowGetCoverReg - Called by "Legend of Spyro", MP3 and Wii System Menu
case 0x7a:
{
INFO_LOG(WII_IPC_DVD, "%s executes DVDLowGetCoverReg (Buffer 0x%08x, 0x%x)",
GetDeviceName().c_str(), _BufferOut, _BufferOutSize);
u8* buffer = Memory::GetPointer(_BufferOut);
// DVD Cover Register States:
// 0x00: Unknown state (keeps checking for DVD)
// 0x01: No Disc inside
// 0xFE: Reads Disc
// --------------------------------------------------------------------
/* Hack for Legend of Spyro. Switching the 4th byte between 0 and 1 gets
// We notify the application that we ejected a disc by
// 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
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;
@ -275,9 +295,10 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
coverByte = 0;
else
coverByte = 0x01;
return 1;
*/
}
break;

View File

@ -43,7 +43,6 @@ private:
u32 ExecuteCommand(u32 BufferIn, u32 BufferInSize, u32 _BufferOut, u32 BufferOutSize);
DiscIO::IVolume* m_pVolume;
DiscIO::IFileSystem* m_pFileSystem;
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()
{
if (m_pFileHandle != NULL)
{
fclose(m_pFileHandle);
m_pFileHandle = NULL;
}
}
bool
@ -62,6 +58,12 @@ CWII_IPC_HLE_Device_FileIO::Close(u32 _CommandAddress)
u32 DeviceID = Memory::Read_U32(_CommandAddress + 8);
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
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 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;
}
}

View File

@ -27,6 +27,19 @@ DiscIO::IVolume *GetVolume() {
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)
{
if (g_pVolume)

View File

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

View File

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