fix booting with a disc inserted

make disc changing a scheduled affair
fix some breakage from removal of mappedfile
cleanup

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3488 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Shawn Hoffman 2009-06-18 08:22:02 +00:00
parent 24192ab23c
commit b6bdc29935
9 changed files with 304 additions and 322 deletions

View File

@ -140,7 +140,6 @@ bool CBoot::LoadMapFromFilename(const std::string &_rFilename, const char *_game
//////////////////////////////////////////////////////////////////////////////////////////
// Load a GC or Wii BIOS file
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
bool CBoot::Load_BIOS(const std::string& _rBiosFilename)
{
bool bResult = false;
@ -148,16 +147,13 @@ bool CBoot::Load_BIOS(const std::string& _rBiosFilename)
if (!File::ReadFileToString(false, _rBiosFilename.c_str(), data))
return false;
Memory::WriteBigEData((const u8*)data.data(), 0x81300000, data.size());
Memory::WriteBigEData((const u8*)data.data() + 0x820, 0x81300000, data.size() - 0x820);
PC = 0x81300000;
return true;
}
/////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Third boot step after BootManager and Core. See Call schedule in BootManager.cpp
// ¯¯¯¯¯¯¯¯¯¯¯¯¯
bool CBoot::BootUp()
{
const bool bDebugIsoBootup = false;
@ -193,7 +189,7 @@ bool CBoot::BootUp()
VideoInterface::SetRegionReg((char)VolumeHandler::GetVolume()->GetUniqueID().at(3));
DVDInterface::SetDiscInside(true);
DVDInterface::SetDiscInside(VolumeHandler::IsValid());
// Use HLE BIOS or not
if (_StartupPara.bHLEBios)
@ -259,6 +255,8 @@ bool CBoot::BootUp()
}
}
DVDInterface::SetDiscInside(VolumeHandler::IsValid());
CDolLoader dolLoader(_StartupPara.m_strFilename.c_str());
PC = dolLoader.GetEntryPoint();
#ifdef _DEBUG
@ -274,7 +272,7 @@ bool CBoot::BootUp()
{
if(!File::Exists(_StartupPara.m_strFilename.c_str()))
{
PanicAlert("The file you specified (%s) does not exists",
PanicAlert("The file you specified (%s) does not exist",
_StartupPara.m_strFilename.c_str());
return false;
}
@ -327,6 +325,15 @@ bool CBoot::BootUp()
if (LoadMapFromFilename(_StartupPara.m_strFilename))
HLE::PatchFunctions();
// load default image or create virtual drive from directory
if (!_StartupPara.m_strDVDRoot.empty())
VolumeHandler::SetVolumeDirectory(_StartupPara.m_strDVDRoot, true);
else if (!_StartupPara.m_strDefaultGCM.empty())
VolumeHandler::SetVolumeName(_StartupPara.m_strDefaultGCM);
DVDInterface::SetDiscInside(VolumeHandler::IsValid());
break;
@ -334,7 +341,7 @@ bool CBoot::BootUp()
// ===================================================================================
case SCoreStartupParameter::BOOT_BIOS:
{
DVDInterface::SetDiscInside(false);
DVDInterface::SetDiscInside(VolumeHandler::IsValid());
if (Load_BIOS(_StartupPara.m_strBios))
{
if (LoadMapFromFilename(_StartupPara.m_strFilename))

View File

@ -171,7 +171,7 @@ bool SCoreStartupParameter::AutoSetup(EBootBios _BootBios)
bNTSC = false;
bWii = true;
Region = EUR_DIR;
Region = EUR_DIR;
m_BootType = BOOT_WII_NAND;
if (pVolume)

View File

@ -17,6 +17,8 @@
#include "Common.h" // Common
#include "ChunkFile.h"
#include "../ConfigManager.h"
#include "../CoreTiming.h"
#include "StreamADPCM.H" // Core
#include "DVDInterface.h"
@ -197,6 +199,9 @@ bool g_bDiscInside = false;
Common::CriticalSection dvdread_section;
static int changeDisc;
void ChangeDiscCallback(u64 userdata, int cyclesLate);
void DoState(PointerWrap &p)
{
p.Do(dvdMem);
@ -224,7 +229,7 @@ void Init()
dvdMem.AudioPos = 0;
dvdMem.AudioLength = 0;
// SetLidOpen(true);
changeDisc = CoreTiming::RegisterEvent("ChangeDisc", ChangeDiscCallback);
}
void Shutdown()
@ -237,22 +242,65 @@ void SetDiscInside(bool _DiscInside)
g_bDiscInside = _DiscInside;
}
bool IsDiscInside()
{
return g_bDiscInside;
}
// Take care of all logic of "swapping discs"
// We want this in the "backend", NOT the gui
void ChangeDiscCallback(u64 userdata, int cyclesLate)
{
std::string FileName((const char*)userdata);
SetDiscInside(false);
SetLidOpen();
std::string& SavedFileName = SConfig::GetInstance().m_LocalCoreStartupParameter.m_strFilename;
if (FileName.empty())
{
// Empty the drive
VolumeHandler::EjectVolume();
}
else if (VolumeHandler::SetVolumeName(FileName))
{
// Save the new ISO file name
SavedFileName = FileName;
}
else
{
PanicAlert("Invalid file");
// Put back the old one
VolumeHandler::SetVolumeName(SavedFileName);
}
SetLidOpen(false);
SetDiscInside(VolumeHandler::IsValid());
}
void ChangeDisc(const char* _FileName)
{
const char* NoDisc = "";
CoreTiming::ScheduleEvent_Threadsafe(0, changeDisc, (u64)NoDisc);
CoreTiming::ScheduleEvent_Threadsafe(500000000, changeDisc, (u64)_FileName);
}
void SetLidOpen(bool _bOpen)
{
if (_bOpen)
dvdMem.CoverReg.CVR = 1;
else
dvdMem.CoverReg.CVR = 0;
dvdMem.CoverReg.CVR = _bOpen ? 1 : 0;
GenerateDVDInterrupt(INT_CVRINT);
}
bool IsLidOpen()
{
if (dvdMem.CoverReg.CVR)
return true;
else
return false;
return (dvdMem.CoverReg.CVR == 1);
}
void ClearCoverInterrupt()
{
dvdMem.CoverReg.CVRINT = 0;
}
bool DVDRead(u32 _iDVDOffset, u32 _iRamAddress, u32 _iLength)
@ -457,7 +505,7 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
// 0004-0007 releaseDate
// 0008-001F padding(0)
//=========================================================================================================
case 0x12:
case DVDLowInquiry:
{
// small safety check, dunno if it's needed
if ((dvdMem.Command[1] == 0) && (dvdMem.DMALength.Length == 0x20))
@ -494,7 +542,7 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
// Command2 <- Address in ram of the buffer
//=========================================================================================================
case 0xA8:
{
{
if (g_bDiscInside)
{
u32 iDVDOffset = dvdMem.Command[1] << 2;
@ -515,7 +563,7 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
_DMAControlReg.TSTART = 0;
dvdMem.DMALength.Length = 0;
GenerateDVDInterrupt(INT_DEINT);
g_ErrorCode = 0x03023A00;
g_ErrorCode = ERROR_NO_DISK | ERROR_COVER_H;
return;
}
}
@ -526,7 +574,7 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
// Command/Subcommand/Padding <- AB000000
// Command0 <- Position on DVD shr 2
//=========================================================================================================
case 0xAB:
case DVDLowSeek:
{
#if MAX_LOGLEVEL >= DEBUG_LEVEL
u32 offset = dvdMem.Command[1] << 2;
@ -535,14 +583,15 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
}
break;
case DVDLowOffset:
DEBUG_LOG(DVDINTERFACE, "DVDLowOffset: ignoring...");
break;
//=========================================================================================================
// REQUEST ERROR (Immediate)
// Command/Subcommand/Padding <- E0000000
//=========================================================================================================
case 0xD9:
INFO_LOG(DVDINTERFACE, "DVD: command 0xD9, called by gcos multigame discs\n Report if you are running anything else");
break;
case 0xE0:
case DVDLowRequestError:
ERROR_LOG(DVDINTERFACE, "Requesting error");
dvdMem.Immediate = g_ErrorCode;
break;
@ -587,7 +636,7 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
//=========================================================================================================
case 0xE2:
{
/**/ if (m_bStream)
if (m_bStream)
dvdMem.Immediate = 1;
else
dvdMem.Immediate = 0;
@ -599,7 +648,7 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
// STOP MOTOR (Immediate)
// Command/Subcommand/Padding <- E3000000
//=========================================================================================================
case 0xE3:
case DVDLowStopMotor:
DEBUG_LOG(DVDINTERFACE, "Stop motor");
break;
@ -608,8 +657,8 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg)
// Command/Subcommand/Padding <- E4000000 (disable)
// Command/Subcommand/Padding <- E4010000 (enable)
//=========================================================================================================
case 0xE4:
/**/ if (((dvdMem.Command[0] & 0x00FF0000) >> 16) == 1)
case DVDLowAudioBufferConfig:
if (((dvdMem.Command[0] & 0x00FF0000) >> 16) == 1)
{
m_bStream = true;
DEBUG_LOG(DVDINTERFACE, "DVD(Audio): Audio enabled");

View File

@ -28,13 +28,18 @@ void Init();
void Shutdown();
void DoState(PointerWrap &p);
// Disc detection and swapping
void SetDiscInside(bool _DiscInside);
void SwapDisc(const char * fileName);
bool IsDiscInside();
void ChangeDisc(const char* _FileName);
// Lid Functions
void SetLidOpen(bool open = true);
void SetLidOpen(bool _bOpen = true);
bool IsLidOpen();
// Used as low level control by WII_IPC_HLE_Device_DI
void ClearCoverInterrupt();
// DVD Access Functions
bool DVDRead(u32 _iDVDOffset, u32 _iRamAddress, u32 _iLength);
bool DVDReadADPCM(u8* _pDestBuffer, u32 _iNumSamples);
@ -46,6 +51,71 @@ void Read32(u32& _uReturnValue, const u32 _iAddress);
// Write32
void Write32(const u32 _iValue, const u32 _iAddress);
// Not sure about endianness here. I'll just name them like this...
enum DIErrorLow
{
ERROR_READY = 0x00000000, // Ready.
ERROR_COVER_L = 0x01000000, // Cover is opened.
ERROR_CHANGE_DISK = 0x02000000, // Disk change.
ERROR_NO_DISK = 0x03000000, // No Disk.
ERROR_MOTOR_STOP_L = 0x04000000, // Motor stop.
ERROR_NO_DISKID_L = 0x05000000 // Disk ID not read.
};
enum DIErrorHigh
{
ERROR_NONE = 0x000000, // No error.
ERROR_MOTOR_STOP_H = 0x020400, // Motor stopped.
ERROR_NO_DISKID_H = 0x020401, // Disk ID not read.
ERROR_COVER_H = 0x023a00, // Medium not present / Cover opened.
ERROR_SEEK_NDONE = 0x030200, // No Seek complete.
ERROR_READ = 0x031100, // UnRecoverd read error.
ERROR_PROTOCOL = 0x040800, // Transfer protocol error.
ERROR_INV_CMD = 0x052000, // Invalid command operation code.
ERROR_AUDIO_BUF = 0x052001, // Audio Buffer not set.
ERROR_BLOCK_OOB = 0x052100, // Logical block address out of bounds.
ERROR_INV_FIELD = 0x052400, // Invalid Field in command packet.
ERROR_INV_AUDIO = 0x052401, // Invalid audio command.
ERROR_INV_PERIOD = 0x052402, // Configuration out of permitted period.
ERROR_END_USR_AREA = 0x056300, // End of user area encountered on this track.
ERROR_MEDIUM = 0x062800, // Medium may have changed.
ERROR_MEDIUM_REQ = 0x0b5a01 // Operator medium removal request.
};
enum DICommand
{
DVDLowInquiry = 0x12,
DVDLowReadDiskID = 0x70,
DVDLowRead = 0x71,
DVDLowWaitForCoverClose = 0x79,
DVDLowGetCoverReg = 0x7a, // DVDLowPrepareCoverRegister?
DVDLowNotifyReset = 0x7e,
DVDLowReadDvdPhysical = 0x80,
DVDLowReadDvdCopyright = 0x81,
DVDLowReadDvdDiscKey = 0x82,
DVDLowClearCoverInterrupt = 0x86,
DVDLowGetCoverStatus = 0x88,
DVDLowReset = 0x8a,
DVDLowOpenPartition = 0x8b,
DVDLowClosePartition = 0x8c,
DVDLowUnencryptedRead = 0x8d,
DVDLowEnableDvdVideo = 0x8e,
DVDLowReportKey = 0xa4,
DVDLowSeek = 0xab,
DVDLowReadDvd = 0xd0,
DVDLowReadDvdConfig = 0xd1,
DVDLowStopLaser = 0xd2,
DVDLowOffset = 0xd9,
DVDLowReadDiskBca = 0xda,
DVDLowRequestDiscStatus = 0xdb,
DVDLowRequestRetryNumber = 0xdc,
DVDLowSetMaximumRotation = 0xdd,
DVDLowSerMeasControl = 0xdf,
DVDLowRequestError = 0xe0,
DVDLowStopMotor = 0xe3,
DVDLowAudioBufferConfig = 0xe4
};
} // end of namespace DVDInterface
#endif

View File

@ -19,6 +19,7 @@
#include "WII_IPC_HLE_Device_DI.h"
#include "../HW/DVDInterface.h"
#include "../HW/CPU.h"
#include "../HW/Memmap.h"
#include "../Core.h"
@ -28,6 +29,8 @@
#include "VolumeCreator.h"
#include "Filesystem.h"
using namespace DVDInterface;
CWII_IPC_HLE_Device_di::CWII_IPC_HLE_Device_di(u32 _DeviceID, const std::string& _rDeviceName )
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
@ -61,21 +64,16 @@ bool CWII_IPC_HLE_Device_di::Close(u32 _CommandAddress)
bool CWII_IPC_HLE_Device_di::IOCtl(u32 _CommandAddress)
{
INFO_LOG(WII_IPC_DVD, "CWII_IPC_DVD_Device_di::IOCtl");
u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14);
u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
u32 Command = Memory::Read_U32(BufferIn) >> 24;
DEBUG_LOG(WII_IPC_DVD, "%s - Command(0x%08x) BufferIn(0x%08x, 0x%x) BufferOut(0x%08x, 0x%x)",
GetDeviceName().c_str(), Command, BufferIn, BufferInSize, BufferOut, BufferOutSize);
DEBUG_LOG(WII_IPC_DVD, "IOCtl Command(0x%08x) BufferIn(0x%08x, 0x%x) BufferOut(0x%08x, 0x%x)",
Command, BufferIn, BufferInSize, BufferOut, BufferOutSize);
if (Command == 0x7a)
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);
return true;
@ -83,8 +81,6 @@ bool CWII_IPC_HLE_Device_di::IOCtl(u32 _CommandAddress)
bool CWII_IPC_HLE_Device_di::IOCtlV(u32 _CommandAddress)
{
INFO_LOG(WII_IPC_DVD, "CWII_IPC_DVD_Device_di::IOCtlV");
SIOCtlVBuffer CommandBuffer(_CommandAddress);
// Prepare the out buffer(s) with zeros as a safety precaution
@ -98,33 +94,29 @@ bool CWII_IPC_HLE_Device_di::IOCtlV(u32 _CommandAddress)
u32 ReturnValue = 0;
switch (CommandBuffer.Parameter)
{
// DVDLowOpenPartition
case 0x8b:
case DVDLowOpenPartition:
{
_dbg_assert_msg_(WII_IPC_DVD, CommandBuffer.InBuffer[1].m_Address == 0, "DVDLowOpenPartition with ticket");
_dbg_assert_msg_(WII_IPC_DVD, CommandBuffer.InBuffer[2].m_Address == 0, "DVDLowOpenPartition with cert chain");
u8 partition = Memory::Read_U32(CommandBuffer.m_Address + 4);
INFO_LOG(WII_IPC_DVD, "DVD IOCtlV: DVDLowOpenPartition %i", partition);
bool readOK = false;
u64 TMDOffset = 0;
readOK |= VolumeHandler::GetTMDOffset(partition, TMDOffset);
// Get TMD offset for requested partition...
u64 TMDOffset = ((u64)Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address + 4) << 2 ) + 0x2c0;
INFO_LOG(WII_IPC_DVD, "DVDLowOpenPartition: TMDOffset 0x%016llx", TMDOffset);
// Read TMD to the buffer
readOK |= VolumeHandler::RAWReadToPtr(Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address),
TMDOffset, CommandBuffer.PayloadBuffer[0].m_Size);
// Second outbuffer is error, we can ignore it
ReturnValue = readOK ? 1 : 0;
}
break;
default:
ERROR_LOG(WII_IPC_DVD, "DVD IOCtlV: %i", CommandBuffer.Parameter);
_dbg_assert_msg_(WII_IPC_DVD, 0, "DVD IOCtlV: %i", CommandBuffer.Parameter);
ERROR_LOG(WII_IPC_DVD, "IOCtlV: %i", CommandBuffer.Parameter);
_dbg_assert_msg_(WII_IPC_DVD, 0, "IOCtlV: %i", CommandBuffer.Parameter);
break;
}
@ -149,15 +141,15 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
m_pFileSystem = DiscIO::CreateFileSystem(VolumeHandler::GetVolume());
// De-initializing a filesystem if the volume was unmounted
if(m_pFileSystem && !VolumeHandler::IsValid()) {
if(m_pFileSystem && !VolumeHandler::IsValid())
{
delete m_pFileSystem;
m_pFileSystem = NULL;
}
switch (Command)
{
// DVDLowInquiry
case 0x12:
case DVDLowInquiry:
{
u8* buffer = Memory::GetPointer(_BufferOut);
@ -184,27 +176,21 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
buffer[7] = 0x02;
buffer[8] = 0x61; // version
DEBUG_LOG(WII_IPC_DVD, "%s executes DVDLowInquiry (Buffer 0x%08x, 0x%x)",
GetDeviceName().c_str(), _BufferOut, _BufferOutSize);
return 1;
INFO_LOG(WII_IPC_DVD, "DVDLowInquiry (Buffer 0x%08x, 0x%x)",
_BufferOut, _BufferOutSize);
}
break;
// DVDLowReadDiskID
case 0x70:
case DVDLowReadDiskID:
{
VolumeHandler::RAWReadToPtr(Memory::GetPointer(_BufferOut), 0, _BufferOutSize);
DEBUG_LOG(WII_IPC_DVD, "DVDLowReadDiskID %s",
INFO_LOG(WII_IPC_DVD, "DVDLowReadDiskID %s",
ArrayToString(Memory::GetPointer(_BufferOut), _BufferOutSize, 0, _BufferOutSize).c_str());
return 1;
}
break;
// DVDLowRead
case 0x71:
case DVDLowRead:
{
if (_BufferOut == 0)
{
@ -217,12 +203,12 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
const char *pFilename = m_pFileSystem->GetFileName(DVDAddress);
if (pFilename != NULL)
{
INFO_LOG(WII_IPC_DVD, " DVDLowRead: %s (0x%x) - (DVDAddr: 0x%x, Size: 0x%x)",
INFO_LOG(WII_IPC_DVD, "DVDLowRead: %s (0x%x) - (DVDAddr: 0x%x, Size: 0x%x)",
pFilename, m_pFileSystem->GetFileSize(pFilename), DVDAddress, Size);
}
else
{
INFO_LOG(WII_IPC_DVD, " DVDLowRead: file unkw - (DVDAddr: 0x%x, Size: 0x%x)",
INFO_LOG(WII_IPC_DVD, "DVDLowRead: file unkw - (DVDAddr: 0x%x, Size: 0x%x)",
DVDAddress, Size);
}
@ -236,133 +222,78 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
{
PanicAlert("Cant read from DVD_Plugin - DVD-Interface: Fatal Error");
}
return 1;
}
break;
// DVDLowWaitForCoverClose
case 0x79:
case DVDLowWaitForCoverClose:
{
INFO_LOG(WII_IPC_DVD, "%s executes DVDLowWaitForCoverClose (Buffer 0x%08x, 0x%x)",
GetDeviceName().c_str(), _BufferOut, _BufferOutSize);
return 4;
INFO_LOG(WII_IPC_DVD, "DVDLowWaitForCoverClose (Buffer 0x%08x, 0x%x)",
_BufferOut, _BufferOutSize);
return 4; // ???
}
break;
// DVDLowPrepareCoverRegister
// DVDLowGetCoverReg - Called by "Legend of Spyro", MP3 and Wii System Menu
case 0x7a:
{
u8* buffer = Memory::GetPointer(_BufferOut);
// DVD Cover Register States:
// 0x00: Unknown state (keeps checking for DVD)
// 0x01: No Disc inside
// 0xFE: Reads Disc
case DVDLowGetCoverReg:
// DVD Cover Register States:
// 0x00: Unknown state (keeps checking for DVD)
// 0x01: No Disc inside
// 0xFE: Read Disc
// 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;
// TODO: Make user-generated ejection mechanism recognized.
// (Currently eject only works if DVDLowReset is called)
if(m_pFileSystem)
buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0xFE;
// Test cases for this command: Legend of Spyro, MP3, WiiMenu
// WiiMenu currently will stop polling /dev/di if no disc is inserted on boot
// This makes me think it is wanting some interrupt when a disc is inserted
// However, DVDInterface::ChangeDisc does not accomplish this...needs investigation!
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());
if (IsDiscInside())
Memory::Write_U32(0xfe, _BufferOut);
else if (IsLidOpen())
Memory::Write_U32(0x00, _BufferOut);
else
Memory::Write_U32(0x01, _BufferOut);
/*
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
/*
static u8 coverByte = 0;
u8* buffer = Memory::GetPointer(_BufferOut);
buffer[3] = coverByte;
if(coverByte)
coverByte = 0;
else
coverByte = 0x01;
return 1;
*/
}
break;
// DVDLowNotifyReset
case 0x7e:
ERROR_LOG(WII_IPC_DVD, "DVDLowNotifyReset");
INFO_LOG(WII_IPC_DVD, "DVDLowGetCoverReg 0x%08x", Memory::Read_U32(_BufferOut));
break;
// DVDLowReadDvdPhysical
case 0x80:
ERROR_LOG(WII_IPC_DVD, "DVDLowReadDvdPhysical");
case DVDLowNotifyReset:
PanicAlert("DVDLowNotifyReset");
break;
// DVDLowReadDvdCopyright
case 0x81:
ERROR_LOG(WII_IPC_DVD, "DVDLowReadDvdCopyright");
case DVDLowReadDvdPhysical:
PanicAlert("DVDLowReadDvdPhysical");
break;
// DVDLowReadDvdDiscKey
case 0x82:
ERROR_LOG(WII_IPC_DVD, "DVDLowReadDvdDiscKey");
case DVDLowReadDvdCopyright:
PanicAlert("DVDLowReadDvdCopyright");
break;
// DVDLowClearCoverInterrupt
case 0x86:
{
INFO_LOG(WII_IPC_DVD, "%s executes DVDLowClearCoverInterrupt (Buffer 0x%08x, 0x%x)",
GetDeviceName().c_str(), _BufferOut, _BufferOutSize);
return 1;
}
case DVDLowReadDvdDiscKey:
PanicAlert("DVDLowReadDvdDiscKey");
break;
// DVDLowGetCoverStatus
case 0x88:
{
INFO_LOG(WII_IPC_DVD, "%s executes DVDLowGetCoverStatus (Buffer 0x%08x, 0x%x)",
GetDeviceName().c_str(), _BufferOut, _BufferOutSize);
return 1;
}
case DVDLowClearCoverInterrupt:
// TODO: check (seems to work ok)
INFO_LOG(WII_IPC_DVD, "DVDLowClearCoverInterrupt");
ClearCoverInterrupt();
break;
// DVDLowReset
case 0x8a:
{
INFO_LOG(WII_IPC_DVD, "%s executes DVDLowReset (Buffer 0x%08x, 0x%x)",
GetDeviceName().c_str(), _BufferOut, _BufferOutSize);
return 1;
}
case DVDLowGetCoverStatus:
// TODO: check (haven't tested yet)
Memory::Write_U32(IsDiscInside() ? 2 : 0, _BufferOut);
INFO_LOG(WII_IPC_DVD, "DVDLowGetCoverStatus %i", IsDiscInside() ? 2 : 0);
break;
// DVDLowOpenPartition
case 0x8b:
ERROR_LOG(WII_IPC_DVD, "DVDLowOpenPartition");
return 1;
case DVDLowReset:
INFO_LOG(WII_IPC_DVD, "DVDLowReset");
break;
// DVDLowClosePartition
case 0x8c:
DEBUG_LOG(WII_IPC_DVD, "DVDLowClosePartition");
return 1;
case DVDLowClosePartition:
INFO_LOG(WII_IPC_DVD, "DVDLowClosePartition");
break;
// DVDLowUnencryptedRead
case 0x8d:
case DVDLowUnencryptedRead:
{
if (_BufferOut == 0)
{
@ -385,8 +316,8 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
|| (((DVDAddress32 + Size) > 0x7ed40000) && (DVDAddress32 + Size) < 0x7ed40008)
))
{
INFO_LOG(WII_IPC_DVD, "DVDLowUnencryptedRead: trying to read out of bounds @ %x", DVDAddress32);
m_ErrorStatus = 0x52100; // Logical block address out of range
WARN_LOG(WII_IPC_DVD, "DVDLowUnencryptedRead: trying to read out of bounds @ %x", DVDAddress32);
m_ErrorStatus = ERROR_READY | ERROR_BLOCK_OOB;
// Should cause software to call DVDLowRequestError
return 2;
}
@ -405,108 +336,109 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
{
PanicAlert("Cant read from DVD_Plugin - DVD-Interface: Fatal Error");
}
return 1;
}
break;
// DVDLowEnableDvdVideo
case 0x8e:
case DVDLowEnableDvdVideo:
ERROR_LOG(WII_IPC_DVD, "DVDLowEnableDvdVideo");
break;
// DVDLowReportKey
case 0xa4:
case DVDLowReportKey:
INFO_LOG(WII_IPC_DVD, "DVDLowReportKey");
// Does not work on commercial discs
m_ErrorStatus = 0x052000; // Invalid command operation code
// Does not work on retail discs/drives
// Retail games send this command to see if they are running on real retail hw
m_ErrorStatus = ERROR_READY | ERROR_INV_CMD;
return 2;
break;
// DVDLowSeek
case 0xab:
ERROR_LOG(WII_IPC_DVD, "DVDLowSeek");
case DVDLowSeek:
{
u64 DVDAddress = Memory::Read_U32(_BufferIn + 0x4) << 2;
const char *pFilename = m_pFileSystem->GetFileName(DVDAddress);
if (pFilename != NULL)
{
INFO_LOG(WII_IPC_DVD, "DVDLowSeek: %s (0x%x) - (DVDAddr: 0x%x)",
pFilename, m_pFileSystem->GetFileSize(pFilename), DVDAddress);
}
else
{
INFO_LOG(WII_IPC_DVD, "DVDLowSeek: file unkw - (DVDAddr: 0x%x)",
DVDAddress);
}
}
break;
// Apparently Dx commands have never been seen in dolphin? *shrug*
// DVDLowReadDvd
case 0xd0:
case DVDLowReadDvd:
ERROR_LOG(WII_IPC_DVD, "DVDLowReadDvd");
break;
// DVDLowReadDvdConfig
case 0xd1:
case DVDLowReadDvdConfig:
ERROR_LOG(WII_IPC_DVD, "DVDLowReadDvdConfig");
break;
// DVDLowStopLaser
case 0xd2:
case DVDLowStopLaser:
ERROR_LOG(WII_IPC_DVD, "DVDLowStopLaser");
break;
// DVDLowOffset
case 0xd9:
case DVDLowOffset:
ERROR_LOG(WII_IPC_DVD, "DVDLowOffset");
break;
// DVDLowReadDiskBca
case 0xda:
case DVDLowReadDiskBca:
ERROR_LOG(WII_IPC_DVD, "DVDLowReadDiskBca");
break;
// DVDLowRequestDiscStatus
case 0xdb:
case DVDLowRequestDiscStatus:
ERROR_LOG(WII_IPC_DVD, "DVDLowRequestDiscStatus");
break;
// DVDLowRequestRetryNumber
case 0xdc:
case DVDLowRequestRetryNumber:
ERROR_LOG(WII_IPC_DVD, "DVDLowRequestRetryNumber");
break;
// DVDLowSetMaximumRotation
case 0xdd:
case DVDLowSetMaximumRotation:
ERROR_LOG(WII_IPC_DVD, "DVDLowSetMaximumRotation");
break;
// DVDLowSerMeasControl
case 0xdf:
case DVDLowSerMeasControl:
ERROR_LOG(WII_IPC_DVD, "DVDLowSerMeasControl");
break;
// DVDLowRequestError
case 0xe0:
case DVDLowRequestError:
// Identical to the error codes found in yagcd section 5.7.3.5.1 (so far)
WARN_LOG(WII_IPC_DVD, "DVDLowRequestError status = 0x%08x", m_ErrorStatus);
Memory::Write_U32(m_ErrorStatus, _BufferOut);
// When does error status get reset?
break;
// Ex commands are immediate and respond with 4 bytes
// DVDLowStopMotor
case 0xe3:
case DVDLowStopMotor:
{
u32 eject = Memory::Read_U32(_BufferIn + 0x04);
u32 eject = Memory::Read_U32(_BufferIn + 4);
// Drive won't do anything till reset is issued. I think it replies like nothing is wrong though?
u32 kill = Memory::Read_U32(_BufferIn + 8);
INFO_LOG(WII_IPC_DVD, "%s executes DVDLowStopMotor eject = %s",
GetDeviceName().c_str(), eject ? "true" : "false");
INFO_LOG(WII_IPC_DVD, "DVDLowStopMotor %s %s",
eject ? "eject" : "", kill ? "kill!" : "");
if (eject)
{
// TODO: eject the disc
SetLidOpen(true);
SetDiscInside(false);
}
}
break;
// DVDLowAudioBufferConfig
case 0xe4:
case DVDLowAudioBufferConfig:
ERROR_LOG(WII_IPC_DVD, "DVDLowAudioBufferConfig");
break;
default:
ERROR_LOG(WII_IPC_DVD, "%s executes unknown cmd 0x%08x (Buffer 0x%08x, 0x%x)",
GetDeviceName().c_str(), Command, _BufferOut, _BufferOutSize);
ERROR_LOG(WII_IPC_DVD, "unknown cmd 0x%08x (Buffer 0x%08x, 0x%x)",
Command, _BufferOut, _BufferOutSize);
PanicAlert("%s executes unknown cmd 0x%08x", GetDeviceName().c_str(), Command);
PanicAlert("unknown cmd 0x%08x", Command);
break;
}

View File

@ -44,10 +44,6 @@ bool SetVolumeName(const std::string& _rFullPath)
{
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;
}
@ -114,27 +110,4 @@ bool IsWii()
return false;
}
bool GetTMDOffset(u32 _Partition, u64& _Offset)
{
bool ret = false;
if (IsWii())
{
// Get the info table
u32 pInfoTableOffset = 0;
ret |= RAWReadToPtr((u8*)&pInfoTableOffset, 0x40004, 4);
u64 InfoTableOffset = (u64)Common::swap32(pInfoTableOffset) << 2;
// Get the offset of the partition
u32 pInfoTableEntryOffset = 0;
ret |= RAWReadToPtr((u8*)&pInfoTableEntryOffset, InfoTableOffset + (_Partition * 8), 4);
u64 PartitionOffset = (u64)Common::swap32(pInfoTableEntryOffset) << 2;
_Offset = PartitionOffset + 0x2c0;
}
return ret;
}
} // namespace

View File

@ -35,8 +35,6 @@ u32 Read32(u64 _Offset);
bool ReadToPtr(u8* ptr, u64 _dwOffset, u64 _dwLength);
bool RAWReadToPtr(u8* ptr, u64 _dwOffset, u64 _dwLength);
bool GetTMDOffset(u32 _Partition, u64& _Offset);
bool IsValid();
bool IsWii();

View File

@ -34,14 +34,11 @@ inline wxBitmap _wxGetBitmapFromMemory(const unsigned char* data, int length)
wxMemoryInputStream is(data, length);
return(wxBitmap(wxImage(is, wxBITMAP_TYPE_ANY, -1), -1));
}
////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// Class declarations
// ¯¯¯¯¯¯¯¯¯¯
class CGameListCtrl;
class CLogWindow;
class CFrame : public wxFrame
{
public:
@ -76,7 +73,6 @@ class CFrame : public wxFrame
// ---------------------------------------
// Wiimote leds
// ---------------
void ModifyStatusBar();
void CreateDestroy(int Case);
void CreateLeds(); void CreateSpeakers();
@ -156,7 +152,8 @@ class CFrame : public wxFrame
void OnQuit(wxCommandEvent& event);
void OnHelp(wxCommandEvent& event);
void OnOpen(wxCommandEvent& event); void DoOpen(bool Boot); // File menu
void OnOpen(wxCommandEvent& event); // File menu
void DoOpen(bool Boot);
void OnRefresh(wxCommandEvent& event);
void OnBrowse(wxCommandEvent& event);
void OnBootDrive(wxCommandEvent& event);
@ -184,8 +181,10 @@ class CFrame : public wxFrame
void OnToggleStatusbar(wxCommandEvent& event);
void OnToggleLogWindow(wxCommandEvent& event);
void OnToggleConsole(wxCommandEvent& event);
void OnKeyDown(wxKeyEvent& event); void OnKeyUp(wxKeyEvent& event);
void OnDoubleClick(wxMouseEvent& event); void OnMotion(wxMouseEvent& event);
void OnKeyDown(wxKeyEvent& event);
void OnKeyUp(wxKeyEvent& event);
void OnDoubleClick(wxMouseEvent& event);
void OnMotion(wxMouseEvent& event);
void OnHostMessage(wxCommandEvent& event);
@ -223,7 +222,5 @@ class CFrame : public wxFrame
// Event table
DECLARE_EVENT_TABLE();
};
////////////////////////////////
#endif // __FRAME_H_

View File

@ -16,9 +16,6 @@
// http://code.google.com/p/dolphin-emu/
// Windows
/*
CFrame is the main parent window. Inside CFrame there is m_Panel which is the
parent for the rendering window (when we render to the main window). In Windows
@ -28,7 +25,6 @@ window handle that is returned by CreateWindow() can be accessed from
Core::GetWindowHandle().
*/
// FIXME: why doesn't it work on windows???
#ifndef _WIN32
#include "Common.h"
@ -67,10 +63,7 @@ Core::GetWindowHandle().
#include <wx/datetime.h> // wxWidgets
// ----------------------------------------------------------------------------
// Resources
// ----------------------------------------------------------------------------
extern "C" {
#include "../resources/Dolphin.c" // Dolphin icon
#include "../resources/toolbar_browse.c"
@ -130,7 +123,7 @@ void CFrame::CreateMenu()
// Emulation menu
wxMenu* emulationMenu = new wxMenu;
emulationMenu->Append(IDM_PLAY, _T("&Play"));
emulationMenu->Append(IDM_CHANGEDISC, _T("Load Disc"));
emulationMenu->Append(IDM_CHANGEDISC, _T("Change Disc"));
emulationMenu->Append(IDM_STOP, _T("&Stop"));
emulationMenu->AppendSeparator();
wxMenu *saveMenu = new wxMenu;
@ -272,13 +265,14 @@ void CFrame::RecreateToolbar()
SetToolBar(TheToolBar);
UpdateGUI();
}
void CFrame::InitBitmaps()
{
// Get selected theme
int Theme = SConfig::GetInstance().m_LocalCoreStartupParameter.iTheme;
/* Save memory by only having one set of bitmaps loaded at any time. I mean, they are still
in the exe, which is in memory, but at least we wont make another copy of all of them. */
// Save memory by only having one set of bitmaps loaded at any time. I mean, they are still
// in the exe, which is in memory, but at least we wont make another copy of all of them. */
switch (Theme)
{
case BOOMY:
@ -374,9 +368,7 @@ void CFrame::InitBitmaps()
}
//////////////////////////////////////////////////////////////////////////////////////
// Start the game or change the disc
// -------------
void CFrame::BootGame()
{
// Rerecording
@ -401,8 +393,8 @@ void CFrame::BootGame()
{
BootManager::BootCore(m_GameListCtrl->GetSelectedISO()->GetFileName());
}
/* Start the default ISO, or if we don't have a default ISO, start the last
started ISO */
// Start the default ISO, or if we don't have a default ISO, start the last
// started ISO
else if (!SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDefaultGCM.empty() &&
wxFileExists(wxString(SConfig::GetInstance().m_LocalCoreStartupParameter.
m_strDefaultGCM.c_str(), wxConvUTF8)))
@ -416,13 +408,9 @@ void CFrame::BootGame()
}
}
// Open file to boot or for changing disc
// Open file to boot
void CFrame::OnOpen(wxCommandEvent& WXUNUSED (event))
{
// Don't allow this for an initialized core
//if (Core::GetState() != Core::CORE_UNINITIALIZED)
// return;
DoOpen(true);
}
@ -441,60 +429,36 @@ void CFrame::DoOpen(bool Boot)
),
wxFD_OPEN | wxFD_PREVIEW | wxFD_FILE_MUST_EXIST,
this);
if (!path)
{
return;
}
bool fileChosen = path ? true : false;
std::string currentDir2 = File::GetCurrentDirectory();
if (currentDir != currentDir2)
{
PanicAlert("Current dir changed has been changeg from %s to %s after wxFileSelector!",currentDir.c_str(),currentDir2.c_str());
PanicAlert("Current dir changed from %s to %s after wxFileSelector!",currentDir.c_str(),currentDir2.c_str());
File::SetCurrentDirectory(currentDir.c_str());
}
// Should we boot a new game or just change the disc?
if(Boot)
if (Boot)
{
if (!fileChosen)
return;
BootManager::BootCore(std::string(path.ToAscii()));
}
else
{
// Get the current ISO name
std::string OldName = SConfig::GetInstance().m_LocalCoreStartupParameter.m_strFilename;
// Change the iso and make sure it's a valid file
if(!VolumeHandler::SetVolumeName(std::string(path.ToAscii())))
{
PanicAlert("The file you selected is not a valid ISO file. Please try again.");
// Put back the old one
VolumeHandler::SetVolumeName(OldName);
}
// Yes it is a valid ISO file
else
{
// Save the new ISO file name
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strFilename = std::string(path.ToAscii());
}
if (!fileChosen)
path = wxT("");
DVDInterface::ChangeDisc(path.c_str());
}
}
void CFrame::OnChangeDisc(wxCommandEvent& WXUNUSED (event))
{
if(VolumeHandler::IsValid()) {
VolumeHandler::EjectVolume();
GetMenuBar()->FindItem(IDM_CHANGEDISC)->SetText(wxT("Load Disc"));
return;
}
DVDInterface::SetLidOpen(true);
DoOpen(false);
DVDInterface::SetLidOpen(false);
DVDInterface::SetDiscInside(true);
GetMenuBar()->FindItem(IDM_CHANGEDISC)->SetText(wxT("Eject"));
}
void CFrame::OnPlay(wxCommandEvent& WXUNUSED (event))
@ -507,12 +471,7 @@ void CFrame::OnBootDrive(wxCommandEvent& event)
BootManager::BootCore(drives[event.GetId()-IDM_DRIVE1]);
}
////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
// Refresh the file list and browse for a favorites directory
// -------------
void CFrame::OnRefresh(wxCommandEvent& WXUNUSED (event))
{
if (m_GameListCtrl)
@ -570,14 +529,15 @@ void CFrame::DoStop()
Core::Stop();
/* This is needed together with the option to not "delete g_EmuThread" in Core.cpp, because then
we have to wait a moment before GetState() == CORE_UNINITIALIZED so that UpdateGUI() works.
It's also needed when a WaitForSingleObject() has timed out so that the ShutDown() process
has continued without all threads having come to a rest. It's not compatible with the
SETUP_TIMER_WAITING option (because the Stop returns before it's finished).
Without this we just see the gray CPanel background because the ISO list will not be displayed.
*/
/*
This is needed together with the option to not "delete g_EmuThread" in Core.cpp, because then
we have to wait a moment before GetState() == CORE_UNINITIALIZED so that UpdateGUI() works.
It's also needed when a WaitForSingleObject() has timed out so that the ShutDown() process
has continued without all threads having come to a rest. It's not compatible with the
SETUP_TIMER_WAITING option (because the Stop returns before it's finished).
Without this we just see the gray CPanel background because the ISO list will not be displayed.
*/
#ifndef SETUP_TIMER_WAITING
if (bRenderToMain)
while(Core::GetState() != Core::CORE_UNINITIALIZED) SLEEP(10);
@ -591,8 +551,6 @@ void CFrame::OnStop(wxCommandEvent& WXUNUSED (event))
{
DoStop();
}
////////////////////////////////////////////////////
void CFrame::OnConfigMain(wxCommandEvent& WXUNUSED (event))
{
@ -601,7 +559,6 @@ void CFrame::OnConfigMain(wxCommandEvent& WXUNUSED (event))
m_GameListCtrl->Update();
}
void CFrame::OnPluginGFX(wxCommandEvent& WXUNUSED (event))
{
CPluginManager::GetInstance().OpenConfig(
@ -690,8 +647,8 @@ void CFrame::OnLoadWiiMenu(wxCommandEvent& WXUNUSED (event))
BootManager::BootCore(FULL_WII_MENU_DIR);
}
/* Toogle fullscreen. In Windows the fullscreen mode is accomplished by expanding the m_Panel to cover
the entire screen (when we render to the main window). */
// Toogle fullscreen. In Windows the fullscreen mode is accomplished by expanding the m_Panel to cover
// the entire screen (when we render to the main window).
void CFrame::OnToggleFullscreen(wxCommandEvent& WXUNUSED (event))
{
ShowFullScreen(true);
@ -928,4 +885,3 @@ void CFrame::GameListChanged(wxCommandEvent& event)
m_GameListCtrl->Update();
}
}