Elf loader etc: Added command line elf loader so I can build and run homebrew with F5, use it with -e file.elf. Made some comments towards finding why lwbt fails to complete the HCI negotiation. I found that it worked in revision 800 so I will try to figure out what broke it along the way. Made some other small changes.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1432 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
John Peterson 2008-12-08 00:25:01 +00:00
parent 7f00e271e5
commit 9e0439a193
22 changed files with 309 additions and 148 deletions

View File

@ -110,6 +110,11 @@ void DynamicLibrary::Unload()
}
#ifdef _WIN32
/* TEMPORARY SOLUTION: To prevent that Dolphin hangs when a game is stopped
or when we try to close Dolphin. It's possible that it only occur when we render
to the main window. And sometimes FreeLibrary works without any problem, so
don't remove this just because it doesn't hang once. I could not find the
actual cause of it. */
if( ! (library_file.find("OGL.") != std::string::npos) && !PowerPC::CPU_POWERDOWN)
FreeLibrary(library);
#else

View File

@ -28,10 +28,10 @@
#pragma comment( lib, "imagehlp.lib" )
#define EXTENDEDTRACEINITIALIZE( IniSymbolPath ) InitSymInfo( IniSymbolPath )
#define EXTENDEDTRACEUNINITIALIZE() UninitSymInfo()
#define STACKTRACE(file) StackTrace( GetCurrentThread(), _T(""), file)
#define EXTENDEDTRACEUNINITIALIZE() UninitSymInfo()
#define STACKTRACE(file) StackTrace( GetCurrentThread(), _T(""), file)
#define STACKTRACE2(file, eip, esp, ebp) StackTrace(GetCurrentThread(), _T(""), file, eip, esp, ebp)
class File;
//class File;
BOOL InitSymInfo( PCSTR );
BOOL UninitSymInfo();

View File

@ -17,6 +17,7 @@
#include "Common.h"
#include "StringUtil.h"
#include "FileUtil.h"
#include "../HLE/HLE.h"
@ -221,6 +222,14 @@ bool CBoot::BootUp(const SCoreStartupParameter& _StartupPara)
// ===================================================================================
case SCoreStartupParameter::BOOT_ELF:
{
if(!File::Exists(_StartupPara.m_strFilename.c_str()))
{
PanicAlert("The file you specified (%s) does not exists",
_StartupPara.m_strFilename.c_str());
return false;
}
// Check if we have gotten a Wii file or not
bool elfWii = IsElfWii(_StartupPara.m_strFilename.c_str());
if (elfWii != Core::GetStartupParameter().bWii)
{

View File

@ -24,6 +24,8 @@
bool CBoot::IsElfWii(const char *filename)
{
/* We already check if filename existed before we called this function, so
there is no need for another check, just read the file right away */
FILE *f = fopen(filename, "rb");
fseek(f, 0, SEEK_END);
u64 filesize = ftell(f);
@ -31,12 +33,12 @@ bool CBoot::IsElfWii(const char *filename)
u8 *mem = new u8[(size_t)filesize];
fread(mem, 1, filesize, f);
fclose(f);
ElfReader reader(mem);
ElfReader reader(mem);
// TODO: Find a more reliable way to distinguish.
bool isWii = reader.GetEntryPoint() >= 0x80004000;
delete [] mem;
return isWii;
}

View File

@ -56,6 +56,14 @@ bool SCoreStartupParameter::AutoSetup(EBootBios _BootBios)
{
case BOOT_DEFAULT:
{
/* Check if the file exist, we may have gotten it from a --elf command line
that gave an incorrect file name */
if (!File::Exists(m_strFilename.c_str()))
{
PanicAlert("The file you specified (%s) does not exists", m_strFilename.c_str());
return false;
}
std::string Extension;
SplitPath(m_strFilename, NULL, NULL, &Extension);
if (!strcasecmp(Extension.c_str(), ".gcm") ||

View File

@ -35,7 +35,7 @@ struct SCoreStartupParameter
void* hMainWindow;
// flags
bool bEnableDebugging;
bool bEnableDebugging; bool bAutomaticStart;
bool bUseJIT;
bool bJITUnlimitedCache, bJITOff; // JIT

View File

@ -288,7 +288,7 @@ void ExecuteCommand(u32 _Address)
else
{
LOG(WII_IPC_HLE, "IOP: Open (Device=%s, DeviceID=%08x, Mode=%i)",
pDevice->GetDeviceName().c_str(), CurrentDeviceID, Mode);
pDevice->GetDeviceName().c_str(), CurrentDeviceID, Mode);
}
}
else
@ -434,7 +434,11 @@ void ExecuteCommand(u32 _Address)
}
}
// This is called continuously and WII_IPCInterface::IsReady() is controlled from WII_IPC.cpp.
// ===================================================
/* This is called continuously from SystemTimers.cpp and WII_IPCInterface::IsReady()
is controlled from WII_IPC.cpp. */
// ----------------
void Update()
{
if (WII_IPCInterface::IsReady())

View File

@ -136,22 +136,23 @@ protected:
of 4 byte commands. */
// ----------------
void DumpCommands(u32 _CommandAddress, size_t _NumberOfCommands = 8,
int LogType = LogTypes::WII_IPC_HLE)
int LogType = LogTypes::WII_IPC_HLE, int Verbosity = 0)
{
// Because I have to use __Logv here I add this #if
#if defined(_DEBUG) || defined(DEBUGFAST)
__Logv(LogType, 0, "CommandDump of %s", GetDeviceName().c_str());
for (u32 i = 0; i < _NumberOfCommands; i++)
{
__Logv(LogType, 0, " Command%02i: 0x%08x", i, Memory::Read_U32(_CommandAddress + i*4));
}
#endif
// Because I have to use __Logv here I add this #if
#if defined(_DEBUG) || defined(DEBUGFAST)
__Logv(LogType, Verbosity, "CommandDump of %s", GetDeviceName().c_str());
for (u32 i = 0; i < _NumberOfCommands; i++)
{
__Logv(LogType, Verbosity, " Command%02i: 0x%08x", i,
Memory::Read_U32(_CommandAddress + i*4));
}
#endif
}
void DumpAsync( u32 BufferVector, u32 _CommandAddress, u32 NumberInBuffer, u32 NumberOutBuffer )
{
LOG(WII_IPC_HLE, "======= DumpAsync ======");
LOGV(WII_IPC_HLE, 1, "======= DumpAsync ======");
// write return value
u32 BufferOffset = BufferVector;
Memory::Write_U32(1, _CommandAddress + 0x4);
@ -161,7 +162,7 @@ protected:
u32 InBuffer = Memory::Read_U32(BufferOffset); BufferOffset += 4;
u32 InBufferSize = Memory::Read_U32(BufferOffset); BufferOffset += 4;
LOG(WII_IPC_HLE, "%s - IOCtlV InBuffer[%i]:", GetDeviceName().c_str(), i);
LOGV(WII_IPC_HLE, 1, "%s - IOCtlV InBuffer[%i]:", GetDeviceName().c_str(), i);
std::string Temp;
for (u32 j=0; j<InBufferSize; j++)
@ -171,24 +172,25 @@ protected:
Temp.append(Buffer);
}
LOG(WII_IPC_HLE, " Buffer: %s", Temp.c_str());
LOGV(WII_IPC_HLE, 1, " Buffer: %s", Temp.c_str());
}
for (u32 i=0; i<NumberOutBuffer; i++)
for (u32 i = 0; i < NumberOutBuffer; i++)
{
#ifdef LOGGING
u32 OutBuffer = Memory::Read_U32(BufferOffset); BufferOffset += 4;
u32 OutBufferSize = Memory::Read_U32(BufferOffset); BufferOffset += 4;
#endif
#ifdef LOGGING
u32 OutBuffer = Memory::Read_U32(BufferOffset); BufferOffset += 4;
u32 OutBufferSize = Memory::Read_U32(BufferOffset); BufferOffset += 4;
#endif
Memory::Write_U32(1, _CommandAddress + 0x4);
LOG(WII_IPC_HLE, "%s - IOCtlV OutBuffer[%i]:", GetDeviceName().c_str(), i);
LOG(WII_IPC_HLE, " OutBuffer: 0x%08x (0x%x):", OutBuffer, OutBufferSize);
#ifdef LOGGING
DumpCommands(OutBuffer, OutBufferSize);
#endif
LOGV(WII_IPC_HLE, 1, "%s - IOCtlV OutBuffer[%i]:", GetDeviceName().c_str(), i);
LOGV(WII_IPC_HLE, 1, " OutBuffer: 0x%08x (0x%x):", OutBuffer, OutBufferSize);
#ifdef LOGGING
DumpCommands(OutBuffer, OutBufferSize, LogTypes::WII_IPC_HLE, 1);
#endif
}
}

View File

@ -62,8 +62,9 @@ bool CWII_IPC_HLE_Device_di::IOCtl(u32 _CommandAddress)
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;
LOG(WII_IPC_DVD, "%s - CommandAddress(0x%08x) BufferIn(0x%08x, 0x%x) BufferOut(0x%08x, 0x%x)", GetDeviceName().c_str(), _CommandAddress, BufferIn, BufferInSize, BufferOut, BufferOutSize);
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);
u32 ReturnValue = ExecuteCommand(BufferIn, BufferInSize, BufferOut, BufferOutSize);
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);

View File

@ -165,20 +165,19 @@ public:
case IOCTL_ES_GETVIEWCNT: // 0x12 (Input: 8 bytes, Output: 4 bytes)
{
if(Buffer.NumberPayloadBuffer)
u32 OutBuffer = Memory::Read_U32(Buffer.PayloadBuffer[0].m_Address);
if(Buffer.NumberInBuffer)
u32 InBuffer = Memory::Read_U32(Buffer.InBuffer[0].m_Address);
// Should we write something here?
//Memory::Write_U32(0, Buffer.PayloadBuffer[0].m_Address);
//DumpCommands(Buffer.InBuffer[0].m_Address, Buffer.InBuffer[0].m_Size / 4,
// LogTypes::WII_IPC_NET);
}
break;
case IOCTL_ES_GETTMDVIEWCNT: // 0x14
{
if(Buffer.NumberPayloadBuffer)
u32 OutBuffer = Memory::Read_U32(Buffer.PayloadBuffer[0].m_Address);
if(Buffer.NumberInBuffer)
u32 InBuffer = Memory::Read_U32(Buffer.InBuffer[0].m_Address);
@ -188,6 +187,9 @@ public:
break;
case IOCTL_ES_GETCONSUMPTION: // (Input: 8 bytes, Output: 0 bytes, 4 bytes)
//DumpCommands(Buffer.InBuffer[0].m_Address, Buffer.InBuffer[0].m_Size / 4,
// LogTypes::WII_IPC_NET);
break;
case IOCTL_ES_DIGETTICKETVIEW: // (Input: none, Output: 216 bytes)
break;

View File

@ -77,6 +77,7 @@ public:
case IOCTL_STM_VIDIMMING: // (Input: 20 bytes, Output: 20 bytes)
LOG(WII_IPC_SD, "%s - IOCtl: \n", GetDeviceName().c_str());
LOG(WII_IPC_SD, " IOCTL_STM_VIDIMMING");
//DumpCommands(BufferIn, BufferInSize / 4, LogTypes::WII_IPC_SD);
//Memory::Write_U32(1, BufferOut);
//ReturnValue = 1;
break;

View File

@ -59,17 +59,29 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _De
CWII_IPC_HLE_Device_usb_oh1_57e_305::~CWII_IPC_HLE_Device_usb_oh1_57e_305()
{}
// ===================================================
/* Open */
// ----------------
bool CWII_IPC_HLE_Device_usb_oh1_57e_305::Open(u32 _CommandAddress, u32 _Mode)
{
Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
return true;
}
// ===================================================
/* IOCtl */
// ----------------
bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtl(u32 _CommandAddress)
{
return IOCtlV(_CommandAddress); //hack
}
// ===================================================
/* IOCtlV */
// ----------------
bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtlV(u32 _CommandAddress)
{
/*
@ -89,7 +101,6 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtlV(u32 _CommandAddress)
Memory::Write_U8(1, 0x80151FC8); // DEBUGPrint */
// even it it wasn't very useful yet...
// Memory::Write_U8(1, 0x80151488); // WPAD_LOG
// Memory::Write_U8(1, 0x801514A8); // USB_LOG
@ -97,6 +108,7 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtlV(u32 _CommandAddress)
// Memory::Write_U8(1, 0x80148E09); // HID LOG
SIOCtlVBuffer CommandBuffer(_CommandAddress);
switch(CommandBuffer.Parameter)
{
case USB_IOCTL_HCI_COMMAND_MESSAGE:
@ -222,6 +234,13 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtlV(u32 _CommandAddress)
return true;
}
// ================
// ===================================================
/* Here we handle the USB_IOCTL_BLKMSG Ioctlv */
// ----------------
void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendToDevice(u16 _ConnectionHandle, u8* _pData, u32 _Size)
{
@ -234,11 +253,14 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendToDevice(u16 _ConnectionHandle, u8
pWiiMote->SendACLFrame(_pData, _Size);
}
// ================
// ===================================================
/* Here we queue the ACL frames. They will consist of header + data. The header is
for example 07 00 41 00 which means size 0x0007 and channel 0x0041. */
/* Here we queue the ACL frames we receive from the Wiimote plugin. They will consist of
header + data. The header is for example 07 00 41 00 which means size 0x0007 and
channel 0x0041. */
// ----------------
void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLFrame(u16 _ConnectionHandle, u8* _pData, u32 _Size)
{
@ -266,6 +288,10 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLFrame(u16 _ConnectionHandle, u8
g_HCICount++;
}
// ===================================================
/* This is called from WII_IPC_HLE_Interface::Update() */
// ----------------
u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
{
if (!m_EventQueue.empty() && m_pHCIBuffer)
@ -356,16 +382,25 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
PluginWiimote::Wiimote_Update();
}
// FiRES: TODO find a good solution to do this
// --------------------------------------------------------------------
/* We wait for ScanEnable to be sent from the game through HCI_CMD_WRITE_SCAN_ENABLE
before we initiate the connection. To avoid doing this for GC games we also
want m_LocalName from CommandWriteLocalName() to be "Wii".
FiRES: TODO find a good solution to do this */
// -------------------------
static bool test = true;
// Why do we need this? 0 worked with the emulated wiimote in all games I tried
static int counter = 1000;
if (test && !stricmp(m_LocalName, "Wii") && (m_ScanEnable & 0x2))
{
counter--;
if (counter < 0)
{
test = false;
for (size_t i=0; i<m_WiiMotes.size(); i++)
for (size_t i=0; i < m_WiiMotes.size(); i++)
{
if (m_WiiMotes[i].EventPagingChanged(2))
{
@ -379,11 +414,12 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// --- events
//
// Events
// -----------------
// This is messages send from the Wiimote to the game, for example RequestConnection()
// or ConnectionComplete().
//
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -411,6 +447,7 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventCommandStatus(u16 _Opcode)
return true;
}
void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventCommandComplete(u16 _OpCode, void* _pData, u32 _DataSize)
{
_dbg_assert_(WII_IPC_WIIMOTE, (sizeof(SHCIEventCommand) - 2 + _DataSize) < 256);
@ -909,10 +946,10 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventDisconnect(u16 _connectionHan
////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// --- command dispacther
//
// Command dispacther
// -----------------
// This is called from the USB_IOCTL_HCI_COMMAND_MESSAGE Ioctlv
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1235,6 +1272,9 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadStoredLinkKey(u8* _Input)
SendEventCommandComplete(HCI_CMD_READ_STORED_LINK_KEY, &Reply, sizeof(hci_read_stored_link_key_rp));
}
// ===================================================
/* This is the last message we get from homebrew's lwbt. Why does it stop with this one? */
// ----------------
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteUnitClass(u8* _Input)
{
// command parameters
@ -1313,6 +1353,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandHostBufferSize(u8* _Input)
SendEventCommandComplete(HCI_CMD_HOST_BUFFER_SIZE, &Reply, sizeof(hci_host_buffer_size_rp));
}
// ===================================================
/* Here we normally receive the timeout interval. But not from homebrew games that use
lwbt. Why not? */
// ----------------
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWritePageTimeOut(u8* _Input)
{
#ifdef LOGGING
@ -1331,13 +1376,15 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWritePageTimeOut(u8* _Input)
SendEventCommandComplete(HCI_CMD_WRITE_PAGE_TIMEOUT, &Reply, sizeof(hci_host_buffer_size_rp));
}
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteScanEnable(u8* _Input)
{
// command parameters
// Command parameters
hci_write_scan_enable_cp* pWriteScanEnable = (hci_write_scan_enable_cp*)_Input;
m_ScanEnable = pWriteScanEnable->scan_enable;
// reply
// Reply
hci_write_scan_enable_rp Reply;
Reply.status = 0x00;
@ -1351,13 +1398,15 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteScanEnable(u8* _Input)
};
#endif
LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_WRITE_SCAN_ENABLE:");
LOG(WII_IPC_WIIMOTE, "write:");
LOG(WII_IPC_WIIMOTE, " scan_enable: %s", Scanning[pWriteScanEnable->scan_enable]);
LOGV(WII_IPC_WIIMOTE, 0, "Command: HCI_CMD_WRITE_SCAN_ENABLE:");
LOGV(WII_IPC_WIIMOTE, 0, "write:");
LOGV(WII_IPC_WIIMOTE, 0, " scan_enable: %s", Scanning[pWriteScanEnable->scan_enable]);
SendEventCommandComplete(HCI_CMD_WRITE_SCAN_ENABLE, &Reply, sizeof(hci_write_scan_enable_rp));
}
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteInquiryMode(u8* _Input)
{
#ifdef LOGGING

View File

@ -947,6 +947,8 @@ void CWII_IPC_HLE_WiiMote::SendL2capData(u16 scid, const void* _pData, u32 _Size
namespace Core
{
/* This is called continously from the Wiimote plugin as soon as it has received
a reporting mode */
void Callback_WiimoteInput(u16 _channelID, const void* _pData, u32 _Size)
{
LOGV(WII_IPC_WIIMOTE, 3, "=========================================================");

View File

@ -162,6 +162,7 @@ void RunLoop()
void Start()
{
// Select running mode for CPU.cpp
state = Core::g_CoreStartupParameter.bEnableDebugging ? CPU_RUNNINGDEBUG : CPU_RUNNING;
if (Core::bReadTrace || Core::bWriteTrace)
{

View File

@ -32,6 +32,9 @@ void 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;
}

View File

@ -92,6 +92,7 @@ BEGIN_EVENT_TABLE(CCodeWindow, wxFrame)
EVT_MENU(IDM_VIDEOWINDOW, CCodeWindow::OnToggleVideoWindow)
EVT_MENU(IDM_INTERPRETER, CCodeWindow::OnInterpreter) // CPU Mode
EVT_MENU(IDM_AUTOMATICSTART, CCodeWindow::OnAutomaticStart) // CPU Mode
EVT_MENU(IDM_JITUNLIMITED, CCodeWindow::OnJITOff)
EVT_MENU(IDM_JITOFF, CCodeWindow::OnJITOff)
EVT_MENU(IDM_JITLSOFF, CCodeWindow::OnJITOff)
@ -152,6 +153,11 @@ CCodeWindow::CCodeWindow(const SCoreStartupParameter& _LocalCoreStartupParameter
, m_MemoryWindow(NULL)
, m_JitWindow(NULL)
{
// Load ini settings
IniFile file;
file.Load(DEBUGGER_CONFIG_FILE);
this->Load_(file);
InitBitmaps();
CreateGUIControls(_LocalCoreStartupParameter);
@ -165,10 +171,6 @@ CCodeWindow::CCodeWindow(const SCoreStartupParameter& _LocalCoreStartupParameter
wxKeyEventHandler(CCodeWindow::OnKeyDown),
(wxObject*)0, this);
// Load ini...
IniFile file;
file.Load(DEBUGGER_CONFIG_FILE);
// Load settings for selectable windowses, but only if they have been created
this->Load(file);
if (m_BreakpointWindow) m_BreakpointWindow->Load(file);
@ -195,44 +197,13 @@ CCodeWindow::~CCodeWindow()
}
void CCodeWindow::Load( IniFile &file )
{
int x,y,w,h;
file.Get("Code", "x", &x, GetPosition().x);
file.Get("Code", "y", &y, GetPosition().y);
file.Get("Code", "w", &w, GetSize().GetWidth());
file.Get("Code", "h", &h, GetSize().GetHeight());
this->SetSize(x, y, w, h);
}
void CCodeWindow::Save(IniFile &file) const
{
file.Set("Code", "x", GetPosition().x);
file.Set("Code", "y", GetPosition().y);
file.Set("Code", "w", GetSize().GetWidth());
file.Set("Code", "h", GetSize().GetHeight());
}
// =======================================================================================
// I don't know when you're supposed to be able to use pRegister->Check(true) so I had
// to set these here. It kept crashing if I placed it after m_LogWindow->Show() below.
bool bLogWindow = true;
bool bRegisterWindow = true;
bool bBreakpointWindow = true;
bool bMemoryWindow = true;
bool bJitWindow = true;
bool bSoundWindow = false;
bool bVideoWindow = false;
// -------------------
void CCodeWindow::CreateGUIControls(const SCoreStartupParameter& _LocalCoreStartupParameter)
// Load before CreateGUIControls()
// --------------
void CCodeWindow::Load_( IniFile &ini )
{
// =======================================================================================
// Decide what windows to use
// --------------
IniFile ini;
ini.Load(DEBUGGER_CONFIG_FILE);
// Decide what windows to use
ini.Get("ShowOnStart", "LogWindow", &bLogWindow, true);
ini.Get("ShowOnStart", "RegisterWindow", &bRegisterWindow, true);
ini.Get("ShowOnStart", "BreakpointWindow", &bBreakpointWindow, true);
@ -242,6 +213,45 @@ void CCodeWindow::CreateGUIControls(const SCoreStartupParameter& _LocalCoreStart
ini.Get("ShowOnStart", "VideoWindow", &bVideoWindow, false);
// ===============
// Boot to pause or not
ini.Get("ShowOnStart", "AutomaticStart", &bAutomaticStart, false);
}
void CCodeWindow::Load( IniFile &ini )
{
int x,y,w,h;
ini.Get("CodeWindow", "x", &x, GetPosition().x);
ini.Get("CodeWindow", "y", &y, GetPosition().y);
ini.Get("CodeWindow", "w", &w, GetSize().GetWidth());
ini.Get("CodeWindow", "h", &h, GetSize().GetHeight());
this->SetSize(x, y, w, h);
}
void CCodeWindow::Save(IniFile &ini) const
{
ini.Set("CodeWindow", "x", GetPosition().x);
ini.Set("CodeWindow", "y", GetPosition().y);
ini.Set("CodeWindow", "w", GetSize().GetWidth());
ini.Set("CodeWindow", "h", GetSize().GetHeight());
// Boot to pause or not
ini.Set("ShowOnStart", "AutomaticStart", GetMenuBar()->IsChecked(IDM_AUTOMATICSTART));
// Save windows settings
ini.Set("ShowOnStart", "LogWindow", GetMenuBar()->IsChecked(IDM_LOGWINDOW));
ini.Set("ShowOnStart", "RegisterWindow", GetMenuBar()->IsChecked(IDM_REGISTERWINDOW));
ini.Set("ShowOnStart", "BreakpointWindow", GetMenuBar()->IsChecked(IDM_BREAKPOINTWINDOW));
ini.Set("ShowOnStart", "MemoryWindow", GetMenuBar()->IsChecked(IDM_MEMORYWINDOW));
ini.Set("ShowOnStart", "JitWindow", GetMenuBar()->IsChecked(IDM_JITWINDOW));
ini.Set("ShowOnStart", "SoundWindow", GetMenuBar()->IsChecked(IDM_SOUNDWINDOW));
ini.Set("ShowOnStart", "VideoWindow", GetMenuBar()->IsChecked(IDM_VIDEOWINDOW));
}
void CCodeWindow::CreateGUIControls(const SCoreStartupParameter& _LocalCoreStartupParameter)
{
CreateMenu(_LocalCoreStartupParameter);
// =======================================================================================
@ -338,6 +348,9 @@ void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParam
wxMenuItem* interpreter = pCoreMenu->Append(IDM_INTERPRETER, _T("&Interpreter core"), wxEmptyString, wxITEM_CHECK);
interpreter->Check(!_LocalCoreStartupParameter.bUseJIT);
pCoreMenu->AppendSeparator();
wxMenuItem* automaticstart = pCoreMenu->Append(IDM_AUTOMATICSTART, _T("&Automatic start"), wxEmptyString, wxITEM_CHECK);
automaticstart->Check(bAutomaticStart);
pCoreMenu->AppendSeparator();
#ifdef JIT_OFF_OPTIONS
jitunlimited = pCoreMenu->Append(IDM_JITUNLIMITED, _T("&Unlimited JIT Cache"), wxEmptyString, wxITEM_CHECK);
@ -437,6 +450,10 @@ bool CCodeWindow::UseInterpreter()
return GetMenuBar()->IsChecked(IDM_INTERPRETER);
}
bool CCodeWindow::AutomaticStart()
{
return GetMenuBar()->IsChecked(IDM_AUTOMATICSTART);
}
bool CCodeWindow::UseDualCore()
{
@ -458,6 +475,12 @@ void CCodeWindow::OnInterpreter(wxCommandEvent& event)
}
void CCodeWindow::OnAutomaticStart(wxCommandEvent& event)
{
bAutomaticStart = !bAutomaticStart;
}
void CCodeWindow::OnJITOff(wxCommandEvent& event)
{
if (Core::GetState() == Core::CORE_UNINITIALIZED)
@ -631,6 +654,9 @@ void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
}
}
// =======================================================================================
// The Play, Stop, Step, Skip, Go to PC and Show PC buttons all go here
// --------------
void CCodeWindow::OnCodeStep(wxCommandEvent& event)
{
switch (event.GetId())
@ -793,6 +819,10 @@ void CCodeWindow::Update()
}
UpdateButtonStates();
/* Automatically show the current PC position when a breakpoint is hit or
when we pause */
codeview->Center(PC);
}
@ -872,18 +902,10 @@ void CCodeWindow::OnSymbolListContextMenu(wxContextMenuEvent& event)
void CCodeWindow::OnToggleLogWindow(wxCommandEvent& event)
{
if (IsLoggingActivated())
{
bool show = GetMenuBar()->IsChecked(event.GetId());
// this may be a little ugly to have these here - you're more than welcome to
// turn this into the same fancy class stuff like the load windows positions
IniFile ini;
ini.Load(DEBUGGER_CONFIG_FILE);
ini.Set("ShowOnStart", "LogWindow", show);
ini.Save(DEBUGGER_CONFIG_FILE);
if (show)
{
if (!m_LogWindow)
@ -914,11 +936,6 @@ void CCodeWindow::OnToggleRegisterWindow(wxCommandEvent& event)
{
bool show = GetMenuBar()->IsChecked(event.GetId());
IniFile ini;
ini.Load(DEBUGGER_CONFIG_FILE);
ini.Set("ShowOnStart", "RegisterWindow", show);
ini.Save(DEBUGGER_CONFIG_FILE);
if (show)
{
if (!m_RegisterWindow)
@ -951,11 +968,6 @@ void CCodeWindow::OnToggleSoundWindow(wxCommandEvent& event)
{
bool show = GetMenuBar()->IsChecked(event.GetId());
IniFile ini;
ini.Load(DEBUGGER_CONFIG_FILE);
ini.Set("ShowOnStart", "SoundWindow", show);
ini.Save(DEBUGGER_CONFIG_FILE);
if (show)
{
// TODO: add some kind of if() check here to?
@ -985,11 +997,6 @@ void CCodeWindow::OnToggleVideoWindow(wxCommandEvent& event)
{
bool show = GetMenuBar()->IsChecked(event.GetId());
//GetMenuBar()->Check(event.GetId(), false); // Turn off
IniFile ini;
ini.Load(DEBUGGER_CONFIG_FILE);
ini.Set("ShowOnStart", "VideoWindow", show);
ini.Save(DEBUGGER_CONFIG_FILE);
if (show)
{
@ -1024,11 +1031,6 @@ void CCodeWindow::OnToggleJitWindow(wxCommandEvent& event)
{
bool show = GetMenuBar()->IsChecked(event.GetId());
IniFile ini;
ini.Load(DEBUGGER_CONFIG_FILE);
ini.Set("ShowOnStart", "JitWindow", show);
ini.Save(DEBUGGER_CONFIG_FILE);
if (show)
{
if (!m_JitWindow)
@ -1058,11 +1060,6 @@ void CCodeWindow::OnToggleBreakPointWindow(wxCommandEvent& event)
{
bool show = GetMenuBar()->IsChecked(event.GetId());
IniFile ini;
ini.Load(DEBUGGER_CONFIG_FILE);
ini.Set("ShowOnStart", "BreakpointWindow", show);
ini.Save(DEBUGGER_CONFIG_FILE);
if (show)
{
if (!m_BreakpointWindow)
@ -1090,11 +1087,6 @@ void CCodeWindow::OnToggleBreakPointWindow(wxCommandEvent& event)
void CCodeWindow::OnToggleMemoryWindow(wxCommandEvent& event)
{
bool show = GetMenuBar()->IsChecked(event.GetId());
IniFile ini;
ini.Load(DEBUGGER_CONFIG_FILE);
ini.Set("ShowOnStart", "MemoryWindow", show);
ini.Save(DEBUGGER_CONFIG_FILE);
if (show)
{

View File

@ -50,6 +50,7 @@ class CCodeWindow
~CCodeWindow();
void Load_(IniFile &file);
void Load(IniFile &file);
void Save(IniFile &file) const;
@ -58,6 +59,7 @@ class CCodeWindow
bool UseInterpreter();
bool AutomaticStart();
bool UseDualCore();
void JumpToAddress(u32 _Address);
@ -79,6 +81,7 @@ class CCodeWindow
IDM_CALLSLIST,
IDM_SYMBOLLIST,
IDM_INTERPRETER,
IDM_AUTOMATICSTART,
IDM_JITUNLIMITED, IDM_JITOFF, // jit
IDM_JITLSOFF, IDM_JITLSLXZOFF, IDM_JITLSLWZOFF, IDM_JITLSLBZXOFF,
@ -123,6 +126,16 @@ class CCodeWindow
Bitmaps_max
};
// Settings
bool bLogWindow;
bool bRegisterWindow;
bool bBreakpointWindow;
bool bMemoryWindow;
bool bJitWindow;
bool bSoundWindow;
bool bVideoWindow;
bool bAutomaticStart;
// sub dialogs
CLogWindow* m_LogWindow;
CRegisterWindow* m_RegisterWindow;
@ -176,6 +189,7 @@ class CCodeWindow
void OnProfilerMenu(wxCommandEvent& event);
void OnInterpreter(wxCommandEvent& event); // cpu mode menu
void OnAutomaticStart(wxCommandEvent& event);
void OnJITOff(wxCommandEvent& event);
void CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParameter);

View File

@ -57,6 +57,7 @@ bool BootCore(const std::string& _rFilename)
{
// StartUp.bUseDualCore = code_frame->UseDualCore();
StartUp.bUseJIT = !g_pCodeWindow->UseInterpreter();
StartUp.bAutomaticStart = g_pCodeWindow->AutomaticStart();
}
else
{
@ -162,7 +163,9 @@ bool BootCore(const std::string& _rFilename)
}
#if defined(HAVE_WX) && HAVE_WX
Core::SetState(g_pCodeWindow ? Core::CORE_PAUSE : Core::CORE_RUN);
// Boot to pause or not
Core::SetState((g_pCodeWindow && !StartUp.bAutomaticStart)
? Core::CORE_PAUSE : Core::CORE_RUN);
#else
Core::SetState(Core::CORE_RUN);
#endif

View File

@ -407,6 +407,9 @@ void CFrame::OnHelp(wxCommandEvent& event)
}
// =======================================================
// Play button
// -------------
void CFrame::OnPlay(wxCommandEvent& WXUNUSED (event))
{
if (Core::GetState() != Core::CORE_UNINITIALIZED)
@ -419,19 +422,28 @@ void CFrame::OnPlay(wxCommandEvent& WXUNUSED (event))
{
Core::SetState(Core::CORE_RUN);
}
UpdateGUI();
}
// Start the selected ISO
else if (m_GameListCtrl->GetSelectedISO() != 0)
{
BootManager::BootCore(m_GameListCtrl->GetSelectedISO()->GetFileName());
}
/* 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)))
{
BootManager::BootCore(SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDefaultGCM);
}
else if (!SConfig::GetInstance().m_LastFilename.empty() &&
wxFileExists(wxString(SConfig::GetInstance().m_LastFilename.c_str(), wxConvUTF8)))
wxFileExists(wxString(SConfig::GetInstance().m_LastFilename.c_str(), wxConvUTF8)))
{
BootManager::BootCore(SConfig::GetInstance().m_LastFilename);
}
}
// =============
void CFrame::OnStop(wxCommandEvent& WXUNUSED (event))

View File

@ -558,14 +558,19 @@ void CGameListCtrl::OnOpenContainingFolder(wxCommandEvent& WXUNUSED (event))
File::Explore(path.c_str());
}
// =======================================================
// Save this file as the default file
// -------------
void CGameListCtrl::OnSetDefaultGCM(wxCommandEvent& WXUNUSED (event))
{
const GameListItem *iso = GetSelectedISO();
if (!iso)
return;
if (!iso) return;
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDefaultGCM = iso->GetFileName();
SConfig::GetInstance().SaveSettings();
}
// =============
void CGameListCtrl::OnDeleteGCM(wxCommandEvent& WXUNUSED (event))
{

View File

@ -22,16 +22,21 @@
#ifdef WIN32
#include <crtdbg.h>
#endif
#include "CPUDetect.h"
#include "Globals.h"
#include "Globals.h" // Core
#include "Host.h"
#include "Common.h"
#include "Common.h" // Common
#include "CPUDetect.h"
#include "IniFile.h"
#include "Main.h"
#include "FileUtil.h"
#include "Main.h" // Local
#include "Frame.h"
#include "Config.h"
#include "CodeWindow.h"
#include "ExtendedTrace.h"
#include "BootManager.h"
IMPLEMENT_APP(DolphinApp)
@ -107,14 +112,25 @@ bool DolphinApp::OnInit()
// ============
// Check for debugger
bool UseDebugger = false;
bool LoadElf = false; wxString ElfFile;
#if wxUSE_CMDLINE_PARSER
wxCmdLineEntryDesc cmdLineDesc[] =
{
{wxCMD_LINE_SWITCH, _T("h"), _T("help"), _T("Show this help message"), wxCMD_LINE_VAL_NONE,
wxCMD_LINE_OPTION_HELP},
{wxCMD_LINE_SWITCH, _T("d"), _T("debugger"), _T("Opens the debugger")},
{wxCMD_LINE_NONE}
{
wxCMD_LINE_SWITCH, _T("h"), _T("help"), _T("Show this help message"),
wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP
},
{
wxCMD_LINE_SWITCH, _T("d"), _T("debugger"), _T("Opens the debugger")
},
{
wxCMD_LINE_OPTION, _T("e"), _T("elf"), _T("Loads an elf file"),
wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL
},
{
wxCMD_LINE_NONE
}
};
#if defined(__APPLE__)
@ -126,16 +142,21 @@ bool DolphinApp::OnInit()
}
#endif
//gets the passed media files from command line
// Gets the passed media files from command line
wxCmdLineParser parser(cmdLineDesc, argc, argv);
// get filenames from the command line
// Get filenames from the command line
if (parser.Parse() != 0)
{
return false;
}
UseDebugger = parser.Found(_T("debugger"));
LoadElf = parser.Found(_T("elf"), &ElfFile);
if( LoadElf && ElfFile == wxEmptyString )
PanicAlert("You did not specify a file name");
// ============
#endif
@ -180,8 +201,30 @@ bool DolphinApp::OnInit()
{
g_pCodeWindow = new CCodeWindow(SConfig::GetInstance().m_LocalCoreStartupParameter, main_frame);
g_pCodeWindow->Show(true);
/* If we have selected Automatic Start, start the default ISO, or if no default
ISO exists, start the last loaded ISO */
if (g_pCodeWindow->AutomaticStart())
{
if(!SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDefaultGCM.empty()
&& File::Exists(SConfig::GetInstance().m_LocalCoreStartupParameter.
m_strDefaultGCM.c_str()))
{
BootManager::BootCore(SConfig::GetInstance().m_LocalCoreStartupParameter.
m_strDefaultGCM);
}
else if(!SConfig::GetInstance().m_LastFilename.empty()
&& File::Exists(SConfig::GetInstance().m_LastFilename.c_str()))
{
BootManager::BootCore(SConfig::GetInstance().m_LastFilename);
}
}
}
if (LoadElf && ElfFile != wxEmptyString)
BootManager::BootCore(std::string(ElfFile.ToAscii()));
SetTopWindow(main_frame);
return true;
}

View File

@ -37,7 +37,7 @@
#include "../Logging/Console.h" // open and close console
extern std::vector<std::string> sMailLog, sMailTime;
extern CDebugger* m_frame;
// =======================================================================================
// Update mail window
@ -60,7 +60,10 @@ void CDebugger::DoUpdateMail()
void CDebugger::UpdateMail(wxNotebookEvent& event)
{
DoUpdateMail();
if(StoreMails) ReadDir();
/* This may be called before m_frame is fully created through the
EVT_NOTEBOOK_PAGE_CHANGED, in that case it will crash because this
is accessing members of it */
if(StoreMails && m_frame) ReadDir();
}
// Change mail from radio button change