diff --git a/Source/Core/DolphinWX/Src/BootManager.cpp b/Source/Core/DolphinWX/Src/BootManager.cpp new file mode 100644 index 0000000000..3de87842da --- /dev/null +++ b/Source/Core/DolphinWX/Src/BootManager.cpp @@ -0,0 +1,106 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include +#include + +#include "Globals.h" +#include "Common.h" +#include "IniFile.h" +#include "BootManager.h" +#include "ISOFile.h" +#include "Volume.h" +#include "VolumeCreator.h" +#include "Config.h" +#include "Core.h" +#include "Frame.h" +#include "CodeWindow.h" + +static std::string s_DataBasePath_EUR = "Data_EUR"; +static std::string s_DataBasePath_USA = "Data_USA"; +static std::string s_DataBasePath_JAP = "Data_JAP"; + +extern CFrame* main_frame; +extern CCodeWindow* g_pCodeWindow; + +namespace BootManager +{ +#ifdef _WIN32 +extern "C" HINSTANCE wxGetInstance(); +#endif + +bool BootCore(const std::string& _rFilename) +{ + SCoreStartupParameter StartUp = SConfig::GetInstance().m_LocalCoreStartupParameter; + + if (g_pCodeWindow) + { +// StartUp.bUseDualCore = code_frame->UseDualCore(); + StartUp.bUseJIT = !g_pCodeWindow->UseInterpreter(); + } + else + { +// StartUp.bUseDualCore = false; + StartUp.bUseJIT = true; + } + StartUp.m_BootType = SCoreStartupParameter::BOOT_ISO; + StartUp.m_strFilename = _rFilename; + StartUp.bRunCompareClient = false; + StartUp.bRunCompareServer = false; + StartUp.bEnableDebugging = g_pCodeWindow ? true : false; // RUNNING_DEBUG + std::string BaseDataPath; +#ifdef _WIN32 + StartUp.hInstance = wxGetInstance(); +#ifdef _M_X64 + StartUp.bUseFastMem = true; +#endif +#endif + + if ( !StartUp.AutoSetup(SCoreStartupParameter::BOOT_DEFAULT) ) + { + return false; + } + + // Load overrides + IniFile ini; + std::string unique_id = StartUp.GetUniqueID(); + if (unique_id.size() == 6 && ini.Load(("Patches/" + unique_id + ".ini").c_str())) + { + ini.Get("Core", "UseDualCore", &StartUp.bUseDualCore, StartUp.bUseDualCore); + ini.Get("Core", "OptimizeQuantizers", &StartUp.bOptimizeQuantizers, StartUp.bOptimizeQuantizers); + } + if(main_frame) + StartUp.hMainWindow = main_frame->GetRenderHandle(); + + // init the core + if (!Core::Init(StartUp)) + { + PanicAlert("Couldn't init the core.\nCheck your configuration."); + return(false); + } + + Core::SetState(g_pCodeWindow ? Core::CORE_PAUSE : Core::CORE_RUN); + return(true); +} + + +void Stop() +{ + Core::Stop(); +} +} // namespace + diff --git a/Source/Core/DolphinWX/Src/BootManager.h b/Source/Core/DolphinWX/Src/BootManager.h new file mode 100644 index 0000000000..1d33c16cb5 --- /dev/null +++ b/Source/Core/DolphinWX/Src/BootManager.h @@ -0,0 +1,32 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _BOOTMANAGER_H +#define _BOOTMANAGER_H + +#include + +class CISOFile; + +namespace BootManager +{ +bool BootCore(const std::string& _rFilename); + +void Stop(); +}; + +#endif diff --git a/Source/Core/DolphinWX/Src/Config.cpp b/Source/Core/DolphinWX/Src/Config.cpp new file mode 100644 index 0000000000..c26ccd5fd3 --- /dev/null +++ b/Source/Core/DolphinWX/Src/Config.cpp @@ -0,0 +1,122 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include + +#include "Globals.h" +#include "Common.h" +#include "IniFile.h" +#include "Config.h" + +SConfig SConfig::m_Instance; + + +SConfig::SConfig() +{ + LoadSettings(); +} + + +SConfig::~SConfig() +{ + SaveSettings(); +} + + +void SConfig::SaveSettings() +{ + IniFile ini; + ini.Load("Dolphin.ini"); // yes we must load first to not kill unknown stuff + + // misc + { + ini.Set("General", "LastFilename", m_LastFilename); + + // ISO folders + ini.Set("General", "GCMPathes", (int)m_ISOFolder.size()); + + for (size_t i = 0; i < m_ISOFolder.size(); i++) + { + TCHAR tmp[16]; + sprintf(tmp, "GCMPath%i", (int)i); + ini.Set("General", tmp, m_ISOFolder[i]); + } + } + + // core + { + ini.Set("Core", "GFXPlugin", m_LocalCoreStartupParameter.m_strVideoPlugin); + ini.Set("Core", "DSPPlugin", m_LocalCoreStartupParameter.m_strDSPPlugin); + ini.Set("Core", "PadPlugin", m_LocalCoreStartupParameter.m_strPadPlugin); + + ini.Set("Core", "HLEBios", m_LocalCoreStartupParameter.bHLEBios); + ini.Set("Core", "UseDynarec", m_LocalCoreStartupParameter.bUseJIT); + ini.Set("Core", "UseDualCore", m_LocalCoreStartupParameter.bUseDualCore); + ini.Set("Core", "LockThreads", m_LocalCoreStartupParameter.bLockThreads); + ini.Set("Core", "DefaultGCM", m_LocalCoreStartupParameter.m_strDefaultGCM); + ini.Set("Core", "OptimizeQuantizers", m_LocalCoreStartupParameter.bOptimizeQuantizers); + } + + ini.Save("Dolphin.ini"); +} + + +void SConfig::LoadSettings() +{ + IniFile ini; + ini.Load("Dolphin.ini"); + + // hard coded default plugin + { + ini.Get("Default", "GFXPlugin", &m_DefaultGFXPlugin); + ini.Get("Default", "DSPPlugin", &m_DefaultDSPPlugin); + ini.Get("Default", "PadPlugin", &m_DefaultPADPlugin); + } + + // misc + { + ini.Get("General", "LastFilename", &m_LastFilename); + + m_ISOFolder.clear(); + int numGCMPaths; + + if (ini.Get("General", "GCMPathes", &numGCMPaths, 0)) + { + for (int i = 0; i < numGCMPaths; i++) + { + TCHAR tmp[16]; + sprintf(tmp, "GCMPath%i", i); + std::string tmpPath; + ini.Get("General", tmp, &tmpPath, ""); + m_ISOFolder.push_back(tmpPath); + } + } + } + + // core + { + ini.Get("Core", "GFXPlugin", &m_LocalCoreStartupParameter.m_strVideoPlugin, m_DefaultGFXPlugin.c_str()); + ini.Get("Core", "DSPPlugin", &m_LocalCoreStartupParameter.m_strDSPPlugin, m_DefaultDSPPlugin.c_str()); + ini.Get("Core", "PadPlugin", &m_LocalCoreStartupParameter.m_strPadPlugin, m_DefaultPADPlugin.c_str()); + + ini.Get("Core", "HLEBios", &m_LocalCoreStartupParameter.bHLEBios, true); + ini.Get("Core", "UseDynarec", &m_LocalCoreStartupParameter.bUseJIT, true); + ini.Get("Core", "UseDualCore", &m_LocalCoreStartupParameter.bUseDualCore, false); + ini.Get("Core", "LockThreads", &m_LocalCoreStartupParameter.bLockThreads, true); + ini.Get("Core", "OptimizeQuantizers", &m_LocalCoreStartupParameter.bOptimizeQuantizers, true); + } +} diff --git a/Source/Core/DolphinWX/Src/Config.h b/Source/Core/DolphinWX/Src/Config.h new file mode 100644 index 0000000000..cdb28b2b9d --- /dev/null +++ b/Source/Core/DolphinWX/Src/Config.h @@ -0,0 +1,63 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _CONFIG_H +#define _CONFIG_H + +#include +#include + +#include "Boot/Boot.h" + +struct SConfig +{ + // default plugins ... hard coded inside the ini + std::string m_DefaultGFXPlugin; + std::string m_DefaultDSPPlugin; + std::string m_DefaultPADPlugin; + + // name of the last used filename + std::string m_LastFilename; + + // gcm folder + std::vectorm_ISOFolder; + + SCoreStartupParameter m_LocalCoreStartupParameter; + + // save settings + void SaveSettings(); + + + // load settings + void LoadSettings(); + + + static SConfig& GetInstance() {return(m_Instance);} + + + private: + + // constructor + SConfig(); + + // destructor + ~SConfig(); + + static SConfig m_Instance; +}; + +#endif diff --git a/Source/Core/DolphinWX/Src/FileSearch.cpp b/Source/Core/DolphinWX/Src/FileSearch.cpp new file mode 100644 index 0000000000..2e1448bdb5 --- /dev/null +++ b/Source/Core/DolphinWX/Src/FileSearch.cpp @@ -0,0 +1,115 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Globals.h" +#ifndef _WIN32 +#include +#include +#else +#include +#endif + +#include + +#include "FileSearch.h" + +#include "StringUtil.h" + + +CFileSearch::CFileSearch(const CFileSearch::XStringVector& _rSearchStrings, const CFileSearch::XStringVector& _rDirectories) +{ + // Reverse the loop order for speed? + for (size_t j = 0; j < _rSearchStrings.size(); j++) + { + for (size_t i = 0; i < _rDirectories.size(); i++) + { + FindFiles(_rSearchStrings[j], _rDirectories[i]); + } + } +} + + +void CFileSearch::FindFiles(const std::string& _searchString, const std::string& _strPath) +{ + std::string GCMSearchPath; + BuildCompleteFilename(GCMSearchPath, _strPath, _searchString); +#ifdef _WIN32 + WIN32_FIND_DATA findData; + HANDLE FindFirst = FindFirstFile(GCMSearchPath.c_str(), &findData); + + if (FindFirst != INVALID_HANDLE_VALUE) + { + bool bkeepLooping = true; + + while (bkeepLooping) + { + std::string strFilename; + BuildCompleteFilename(strFilename, _strPath, findData.cFileName); + + m_FileNames.push_back(strFilename); + + bkeepLooping = FindNextFile(FindFirst, &findData) ? true : false; + } + } + +#else + size_t dot_pos = _searchString.rfind("."); + + if (dot_pos == std::string::npos) + { + return; + } + + std::string ext = _searchString.substr(dot_pos); + DIR* dir = opendir(_strPath.c_str()); + + if (!dir) + { + return; + } + + dirent* dp; + + while (true) + { + dp = readdir(dir); + + if (!dp) + { + break; + } + + std::string s(dp->d_name); + + if ( (s.size() > ext.size()) && (!strcasecmp(s.substr(s.size() - ext.size()).c_str(), ext.c_str())) ) + { + std::string full_name = _strPath + "/" + s; + m_FileNames.push_back(full_name); + } + } + + closedir(dir); +#endif +} + + +const CFileSearch::XStringVector& CFileSearch::GetFileNames() const +{ + return(m_FileNames); +} + + diff --git a/Source/Core/DolphinWX/Src/FileSearch.h b/Source/Core/DolphinWX/Src/FileSearch.h new file mode 100644 index 0000000000..4f0d7f7c09 --- /dev/null +++ b/Source/Core/DolphinWX/Src/FileSearch.h @@ -0,0 +1,44 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef __FILESEARCH_H_ +#define __FILESEARCH_H_ + +#include +#include + +class CFileSearch +{ + public: + + typedef std::vectorXStringVector; + + CFileSearch(const XStringVector& _rSearchStrings, const XStringVector& _rDirectories); + + const XStringVector& GetFileNames() const; + + + private: + + void FindFiles(const std::string& _searchString, const std::string& _strPath); + + + XStringVector m_FileNames; +}; + +#endif + diff --git a/Source/Core/DolphinWX/Src/Frame.cpp b/Source/Core/DolphinWX/Src/Frame.cpp new file mode 100644 index 0000000000..a88a5b0e5c --- /dev/null +++ b/Source/Core/DolphinWX/Src/Frame.cpp @@ -0,0 +1,632 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Globals.h" +#include "Frame.h" +#include "FileUtil.h" + +#include "GameListCtrl.h" +#include "BootManager.h" + +#include "Common.h" +#include "Config.h" +#include "Core.h" +#include "State.h" +#include "PluginOptions.h" +#include "PluginManager.h" +#include "MemcardManager.h" + +#include + +// ---------------------------------------------------------------------------- +// resources +// ---------------------------------------------------------------------------- + +extern "C" { +#include "../resources/Dolphin.c" +#include "../resources/toolbar_browse.c" +#include "../resources/toolbar_file_open.c" +#include "../resources/toolbar_fullscreen.c" +#include "../resources/toolbar_help.c" +#include "../resources/toolbar_pause.c" +#include "../resources/toolbar_play.c" +#include "../resources/toolbar_play_dis.c" +#include "../resources/toolbar_plugin_dsp.c" +#include "../resources/toolbar_plugin_gfx.c" +#include "../resources/toolbar_plugin_options.c" +#include "../resources/toolbar_plugin_options_dis.c" +#include "../resources/toolbar_plugin_pad.c" +#include "../resources/toolbar_refresh.c" +#include "../resources/toolbar_stop.c" +#include "../resources/toolbar_stop_dis.c" +}; + +#define wxGetBitmapFromMemory(name) _wxGetBitmapFromMemory(name, sizeof(name)) +inline wxBitmap _wxGetBitmapFromMemory(const unsigned char* data, int length) +{ + wxMemoryInputStream is(data, length); + return(wxBitmap(wxImage(is, wxBITMAP_TYPE_ANY, -1), -1)); +} + + +// ---------------------------------------------------------------------------- +// constants +// ---------------------------------------------------------------------------- + +static const long TOOLBAR_STYLE = wxTB_FLAT | wxTB_DOCKABLE | wxTB_TEXT; + +// ---------------------------------------------------------------------------- +// event tables +// ---------------------------------------------------------------------------- + +// Notice that wxID_HELP will be processed for the 'About' menu and the toolbar +// help button. + +const wxEventType wxEVT_HOST_COMMAND = wxNewEventType(); + +BEGIN_EVENT_TABLE(CFrame, wxFrame) +EVT_MENU(wxID_OPEN, CFrame::OnOpen) +EVT_MENU(wxID_EXIT, CFrame::OnQuit) +EVT_MENU(IDM_HELPWEBSITE, CFrame::OnHelp) +EVT_MENU(IDM_HELPGOOGLECODE, CFrame::OnHelp) +EVT_MENU(IDM_HELPABOUT, CFrame::OnHelp) +EVT_MENU(wxID_REFRESH, CFrame::OnRefresh) +EVT_MENU(IDM_PLAY, CFrame::OnPlay) +EVT_MENU(IDM_STOP, CFrame::OnStop) +EVT_MENU(IDM_PLUGIN_OPTIONS, CFrame::OnPluginOptions) +EVT_MENU(IDM_CONFIG_GFX_PLUGIN, CFrame::OnPluginGFX) +EVT_MENU(IDM_CONFIG_DSP_PLUGIN, CFrame::OnPluginDSP) +EVT_MENU(IDM_CONFIG_PAD_PLUGIN, CFrame::OnPluginPAD) +EVT_MENU(IDM_BROWSE, CFrame::OnBrowse) +EVT_MENU(IDM_MEMCARD, CFrame::OnMemcard) +EVT_MENU(IDM_TOGGLE_FULLSCREEN, CFrame::OnToggleFullscreen) +EVT_MENU(IDM_TOGGLE_DUALCORE, CFrame::OnToggleDualCore) +EVT_MENU(IDM_TOGGLE_TOOLBAR, CFrame::OnToggleToolbar) +EVT_MENU(IDM_LOADSLOT1, CFrame::OnLoadState) +EVT_MENU(IDM_LOADSLOT2, CFrame::OnLoadState) +EVT_MENU(IDM_LOADSLOT3, CFrame::OnLoadState) +EVT_MENU(IDM_LOADSLOT4, CFrame::OnLoadState) +EVT_MENU(IDM_LOADSLOT5, CFrame::OnLoadState) +EVT_MENU(IDM_LOADSLOT6, CFrame::OnLoadState) +EVT_MENU(IDM_LOADSLOT7, CFrame::OnLoadState) +EVT_MENU(IDM_LOADSLOT8, CFrame::OnLoadState) +EVT_MENU(IDM_LOADSLOT9, CFrame::OnLoadState) +EVT_MENU(IDM_LOADSLOT10, CFrame::OnLoadState) +EVT_MENU(IDM_SAVESLOT1, CFrame::OnSaveState) +EVT_MENU(IDM_SAVESLOT2, CFrame::OnSaveState) +EVT_MENU(IDM_SAVESLOT3, CFrame::OnSaveState) +EVT_MENU(IDM_SAVESLOT4, CFrame::OnSaveState) +EVT_MENU(IDM_SAVESLOT5, CFrame::OnSaveState) +EVT_MENU(IDM_SAVESLOT6, CFrame::OnSaveState) +EVT_MENU(IDM_SAVESLOT7, CFrame::OnSaveState) +EVT_MENU(IDM_SAVESLOT8, CFrame::OnSaveState) +EVT_MENU(IDM_SAVESLOT9, CFrame::OnSaveState) +EVT_MENU(IDM_SAVESLOT10, CFrame::OnSaveState) +EVT_HOST_COMMAND(wxID_ANY, CFrame::OnHostMessage) +END_EVENT_TABLE() + +// ---------------------------------------------------------------------------- +// implementation +// ---------------------------------------------------------------------------- + +CFrame::CFrame(wxFrame* parent, + wxWindowID id, + const wxString& title, + const wxPoint& pos, + const wxSize& size, + long style) + : wxFrame(parent, id, title, pos, size, style) + , m_Panel(NULL) + , m_pStatusBar(NULL) + , m_pMenuBar(NULL) + , m_pBootProcessDialog(NULL) +{ + InitBitmaps(); + + // Give it an icon + wxIcon IconTemp; + IconTemp.CopyFromBitmap(wxGetBitmapFromMemory(dolphin_png)); + SetIcon(IconTemp); + + // Give it a status line + m_pStatusBar = CreateStatusBar(); + CreateMenu(); + + // this panel is the parent for rendering and it holds the gamelistctrl + { + m_Panel = new wxPanel(this); + + m_GameListCtrl = new CGameListCtrl(m_Panel, LIST_CTRL, + wxDefaultPosition, wxDefaultSize, + wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT | wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING); + + wxBoxSizer* sizerPanel = new wxBoxSizer(wxHORIZONTAL); + sizerPanel->Add(m_GameListCtrl, 2, wxEXPAND | wxALL); + m_Panel->SetSizer(sizerPanel); + + sizerPanel->SetSizeHints(m_Panel); + sizerPanel->Fit(m_Panel); + } + + // Create the toolbar + RecreateToolbar(); + + Show(); + + CPluginManager::GetInstance().ScanForPlugins(this); + + m_GameListCtrl->Update(); + + wxTheApp->Connect(wxID_ANY, wxEVT_KEY_DOWN, + wxKeyEventHandler(CFrame::OnKeyDown), + (wxObject*)0, this); + + UpdateGUI(); +} + + +void CFrame::CreateMenu() +{ + delete m_pMenuBar; + m_pMenuBar = new wxMenuBar(wxMB_DOCKABLE); + + // file menu + wxMenu* fileMenu = new wxMenu; + fileMenu->Append(wxID_OPEN, _T("&Open...\tCtrl+O")); + fileMenu->Append(wxID_REFRESH, _T("&Refresh")); + fileMenu->Append(IDM_BROWSE, _T("&Browse for ISOs...")); + + fileMenu->AppendSeparator(); + fileMenu->Append(wxID_EXIT, _T("E&xit"), _T("Alt+F4")); + m_pMenuBar->Append(fileMenu, _T("&File")); + + // emulation menu + wxMenu* emulationMenu = new wxMenu; + m_pMenuItemPlay = emulationMenu->Append(IDM_PLAY, _T("&Play")); + m_pMenuItemStop = emulationMenu->Append(IDM_STOP, _T("&Stop")); + emulationMenu->AppendSeparator(); + wxMenu *saveMenu = new wxMenu; + wxMenu *loadMenu = new wxMenu; + m_pMenuItemLoad = emulationMenu->AppendSubMenu(saveMenu, _T("&Load State")); + m_pMenuItemSave = emulationMenu->AppendSubMenu(loadMenu, _T("Sa&ve State")); + for (int i = 1; i < 10; i++) { + saveMenu->Append(IDM_LOADSLOT1 + i - 1, wxString::Format(_T("Slot %i F%i"), i, i)); + loadMenu->Append(IDM_SAVESLOT1 + i - 1, wxString::Format(_T("Slot %i Shift+F%i"), i, i)); + } + m_pMenuBar->Append(emulationMenu, _T("&Emulation")); + + // options menu + wxMenu* pOptionsMenu = new wxMenu; + m_pPluginOptions = pOptionsMenu->Append(IDM_PLUGIN_OPTIONS, _T("&Select plugins")); + pOptionsMenu->AppendSeparator(); + pOptionsMenu->Append(IDM_CONFIG_GFX_PLUGIN, _T("&GFX settings")); + pOptionsMenu->Append(IDM_CONFIG_DSP_PLUGIN, _T("&DSP settings")); + pOptionsMenu->Append(IDM_CONFIG_PAD_PLUGIN, _T("&PAD settings")); + pOptionsMenu->AppendSeparator(); + pOptionsMenu->Append(IDM_TOGGLE_FULLSCREEN, _T("&Fullscreen")); + pOptionsMenu->AppendCheckItem(IDM_TOGGLE_DUALCORE, _T("&Dual-core (unstable!)")); + pOptionsMenu->Check(IDM_TOGGLE_DUALCORE, SConfig::GetInstance().m_LocalCoreStartupParameter.bUseDualCore); + m_pMenuBar->Append(pOptionsMenu, _T("&Options")); + + // misc menu + wxMenu* miscMenu = new wxMenu; + miscMenu->Append(IDM_MEMCARD, _T("&Memcard manager")); + miscMenu->AppendCheckItem(IDM_TOGGLE_TOOLBAR, _T("&Enable toolbar")); + miscMenu->Check(IDM_TOGGLE_TOOLBAR, true); + m_pMenuBar->Append(miscMenu, _T("&Misc")); + + // help menu + wxMenu* helpMenu = new wxMenu; + /*helpMenu->Append(wxID_HELP, _T("&Help")); + re-enable when there's something useful to display*/ + helpMenu->Append(IDM_HELPWEBSITE, _T("&Dolphin web site")); + helpMenu->Append(IDM_HELPGOOGLECODE, _T("&Dolphin at Google Code")); + helpMenu->AppendSeparator(); + helpMenu->Append(IDM_HELPABOUT, _T("&About...")); + m_pMenuBar->Append(helpMenu, _T("&Help")); + + // Associate the menu bar with the frame + SetMenuBar(m_pMenuBar); +} + + +void CFrame::PopulateToolbar(wxToolBar* toolBar) +{ + int w = m_Bitmaps[Toolbar_FileOpen].GetWidth(), + h = m_Bitmaps[Toolbar_FileOpen].GetHeight(); + + toolBar->SetToolBitmapSize(wxSize(w, h)); + toolBar->AddTool(wxID_OPEN, _T("Open"), m_Bitmaps[Toolbar_FileOpen], _T("Open file...")); + toolBar->AddTool(wxID_REFRESH, _T("Refresh"), m_Bitmaps[Toolbar_Refresh], _T("Refresh")); + toolBar->AddTool(IDM_BROWSE, _T("Browse"), m_Bitmaps[Toolbar_Browse], _T("Browse for an ISO directory...")); + toolBar->AddSeparator(); + toolBar->AddTool(IDM_PLAY, _T("Play"), m_Bitmaps[Toolbar_Play], _T("Play")); + toolBar->SetToolDisabledBitmap(IDM_PLAY, m_Bitmaps[Toolbar_Play_Dis]); + toolBar->AddTool(IDM_STOP, _T("Stop"), m_Bitmaps[Toolbar_Stop], _T("Stop")); + toolBar->SetToolDisabledBitmap(IDM_STOP, m_Bitmaps[Toolbar_Stop_Dis]); + toolBar->AddTool(IDM_TOGGLE_FULLSCREEN, _T("Fullscr."), m_Bitmaps[Toolbar_FullScreen], _T("Toggle Fullscreen")); + toolBar->AddSeparator(); + toolBar->AddTool(IDM_PLUGIN_OPTIONS, _T("Plugins"), m_Bitmaps[Toolbar_PluginOptions], _T("Select plugins")); + toolBar->SetToolDisabledBitmap(IDM_PLUGIN_OPTIONS, m_Bitmaps[Toolbar_PluginOptions_Dis]); + toolBar->AddTool(IDM_CONFIG_GFX_PLUGIN, _T("GFX"), m_Bitmaps[Toolbar_PluginGFX], _T("GFX settings")); + toolBar->AddTool(IDM_CONFIG_DSP_PLUGIN, _T("DSP"), m_Bitmaps[Toolbar_PluginDSP], _T("DSP settings")); + toolBar->AddTool(IDM_CONFIG_PAD_PLUGIN, _T("PAD"), m_Bitmaps[Toolbar_PluginPAD], _T("PAD settings")); + toolBar->AddSeparator(); + toolBar->AddTool(IDM_HELPABOUT, _T("About"), m_Bitmaps[Toolbar_Help], _T("About Dolphin")); + + // after adding the buttons to the toolbar, must call Realize() to reflect + // the changes + toolBar->Realize(); +} + + +void CFrame::RecreateToolbar() +{ + // delete and recreate the toolbar + wxToolBarBase* toolBar = GetToolBar(); + long style = toolBar ? toolBar->GetWindowStyle() : TOOLBAR_STYLE; + + delete toolBar; + SetToolBar(NULL); + + style &= ~(wxTB_HORIZONTAL | wxTB_VERTICAL | wxTB_BOTTOM | wxTB_RIGHT | wxTB_HORZ_LAYOUT | wxTB_TOP); + wxToolBar* theToolBar = CreateToolBar(style, ID_TOOLBAR); + + PopulateToolbar(theToolBar); + SetToolBar(theToolBar); +} + + +void CFrame::InitBitmaps() +{ + // load orignal size 48x48 + m_Bitmaps[Toolbar_FileOpen] = wxGetBitmapFromMemory(toolbar_file_open_png); + m_Bitmaps[Toolbar_Refresh] = wxGetBitmapFromMemory(toolbar_refresh_png); + m_Bitmaps[Toolbar_Browse] = wxGetBitmapFromMemory(toolbar_browse_png); + m_Bitmaps[Toolbar_Play] = wxGetBitmapFromMemory(toolbar_play_png); + m_Bitmaps[Toolbar_Play_Dis] = wxGetBitmapFromMemory(toolbar_play_dis_png); + m_Bitmaps[Toolbar_Stop] = wxGetBitmapFromMemory(toolbar_stop_png); + m_Bitmaps[Toolbar_Stop_Dis] = wxGetBitmapFromMemory(toolbar_stop_dis_png); + m_Bitmaps[Toolbar_Pause] = wxGetBitmapFromMemory(toolbar_pause_png); + m_Bitmaps[Toolbar_PluginOptions] = wxGetBitmapFromMemory(toolbar_plugin_options_png); + m_Bitmaps[Toolbar_PluginOptions_Dis] = wxGetBitmapFromMemory(toolbar_plugin_options_dis_png); + m_Bitmaps[Toolbar_PluginGFX] = wxGetBitmapFromMemory(toolbar_plugin_gfx_png); + m_Bitmaps[Toolbar_PluginDSP] = wxGetBitmapFromMemory(toolbar_plugin_dsp_png); + m_Bitmaps[Toolbar_PluginPAD] = wxGetBitmapFromMemory(toolbar_plugin_pad_png); + m_Bitmaps[Toolbar_FullScreen] = wxGetBitmapFromMemory(toolbar_fullscreen_png); + m_Bitmaps[Toolbar_Help] = wxGetBitmapFromMemory(toolbar_help_png); + + // scale to 24x24 for toolbar + for (size_t n = Toolbar_FileOpen; n < WXSIZEOF(m_Bitmaps); n++) + { + m_Bitmaps[n] = wxBitmap(m_Bitmaps[n].ConvertToImage().Scale(24, 24)); + } +} + + +void CFrame::OnOpen(wxCommandEvent& WXUNUSED (event)) +{ + if (Core::GetState() != Core::CORE_UNINITIALIZED) + return; + wxString path = wxFileSelector( + _T("Select the file to load"), + wxEmptyString, wxEmptyString, wxEmptyString, + wxString::Format + ( + _T("All GC/Wii files (elf, dol, gcm, iso)|*.elf;*.dol;*.gcm;*.iso|All files (%s)|%s"), + wxFileSelectorDefaultWildcardStr, + wxFileSelectorDefaultWildcardStr + ), + wxFD_OPEN | wxFD_PREVIEW | wxFD_FILE_MUST_EXIST, + this); + if (!path) + { + return; + } + BootManager::BootCore(std::string(path.ToAscii())); +} + + +void CFrame::OnQuit(wxCommandEvent& WXUNUSED (event)) +{ + if (Core::GetState() != Core::CORE_UNINITIALIZED) + { + Core::Stop(); + UpdateGUI(); + } + + Close(true); +} + + +void CFrame::OnHelp(wxCommandEvent& event) +{ + switch (event.GetId()) { + case IDM_HELPABOUT: + { + wxAboutDialogInfo info; + info.AddDeveloper(_T("ector")); + info.AddDeveloper(_T("F|RES")); + info.AddDeveloper(_T("yaz0r")); + info.AddDeveloper(_T("zerofrog")); + /* info.SetLicence(wxString::FromAscii( + "Dolphin Licence 1.0" + "#include GPL.TXT")); + */ + + info.AddArtist(_T("miloszwl@miloszwl.com (miloszwl.deviantart.com)")); + + wxAboutBox(info); + break; + } + case IDM_HELPWEBSITE: + File::Launch("http://www.dolphin-emu.com/"); + break; + case IDM_HELPGOOGLECODE: + File::Launch("http://code.google.com/p/dolphin-emu/"); + break; + } +} + + +void CFrame::OnPlay(wxCommandEvent& WXUNUSED (event)) +{ + if (Core::GetState() != Core::CORE_UNINITIALIZED) + { + if (Core::GetState() == Core::CORE_RUN) + { + Core::SetState(Core::CORE_PAUSE); + } + else + { + Core::SetState(Core::CORE_RUN); + } + + UpdateGUI(); + } +} + + +void CFrame::OnStop(wxCommandEvent& WXUNUSED (event)) +{ + if (Core::GetState() != Core::CORE_UNINITIALIZED) + { + Core::Stop(); + UpdateGUI(); + } +} + + +void CFrame::OnRefresh(wxCommandEvent& WXUNUSED (event)) +{ + if (m_GameListCtrl) + { + m_GameListCtrl->Update(); + } +} + + +void CFrame::OnPluginOptions(wxCommandEvent& WXUNUSED (event)) +{ + CPluginOptions PluginOptions(this); + PluginOptions.ShowModal(); +} + + +void CFrame::OnPluginGFX(wxCommandEvent& WXUNUSED (event)) +{ + CPluginManager::GetInstance().OpenConfig( + GetHandle(), + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoPlugin + ); +} + + +void CFrame::OnPluginDSP(wxCommandEvent& WXUNUSED (event)) +{ + CPluginManager::GetInstance().OpenConfig( + GetHandle(), + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin + ); +} + + +void CFrame::OnPluginPAD(wxCommandEvent& WXUNUSED (event)) +{ + CPluginManager::GetInstance().OpenConfig( + GetHandle(), + SConfig::GetInstance().m_LocalCoreStartupParameter.m_strPadPlugin + ); +} + +void CFrame::OnBrowse(wxCommandEvent& WXUNUSED (event)) +{ + m_GameListCtrl->BrowseForDirectory(); +} + +void CFrame::OnMemcard(wxCommandEvent& WXUNUSED (event)) +{ + CMemcardManager MemcardManager(this); + MemcardManager.ShowModal(); +} + +void CFrame::OnHostMessage(wxCommandEvent& event) +{ + switch (event.GetId()) + { + case IDM_UPDATEGUI: + UpdateGUI(); + break; + + case IDM_BOOTING_STARTED: + if (m_pBootProcessDialog == NULL) + { + /* m_pBootProcessDialog = new wxProgressDialog + (_T("Booting the core"), + _T("Booting..."), + 1, // range + this, + wxPD_APP_MODAL | + // wxPD_AUTO_HIDE | -- try this as well + wxPD_ELAPSED_TIME | + wxPD_SMOOTH // - makes indeterminate mode bar on WinXP very small + );*/ + + m_pBootProcessDialog = new wxBusyInfo(wxString::FromAscii("Booting..."), this); + } + break; + + case IDM_BOOTING_ENDED: + if (m_pBootProcessDialog != NULL) + { + // m_pBootProcessDialog->Destroy(); + delete m_pBootProcessDialog; + m_pBootProcessDialog = NULL; + } + break; + + case IDM_UPDATESTATUSBAR: + if (m_pStatusBar != NULL) + { + m_pStatusBar->SetStatusText(event.GetString()); + } + break; + } +} + +void CFrame::OnToggleFullscreen(wxCommandEvent& WXUNUSED (event)) +{ + ShowFullScreen(true); + UpdateGUI(); +} + +void CFrame::OnToggleDualCore(wxCommandEvent& WXUNUSED (event)) +{ + SConfig::GetInstance().m_LocalCoreStartupParameter.bUseDualCore = !SConfig::GetInstance().m_LocalCoreStartupParameter.bUseDualCore; + SConfig::GetInstance().SaveSettings(); +} + +void CFrame::OnLoadState(wxCommandEvent& event) +{ + int id = event.GetId(); + int slot = id - IDM_LOADSLOT1 + 1; + State_Load(slot); +} + +void CFrame::OnSaveState(wxCommandEvent& event) +{ + int id = event.GetId(); + int slot = id - IDM_SAVESLOT1 + 1; + State_Save(slot); +} + +void CFrame::OnToggleToolbar(wxCommandEvent& event) +{ + wxToolBarBase* toolBar = GetToolBar(); + + if (event.IsChecked()) + { + CFrame::RecreateToolbar(); + } + else + { + delete toolBar; + SetToolBar(NULL); + } +} + +void CFrame::OnKeyDown(wxKeyEvent& event) +{ + if (((event.GetKeyCode() == WXK_RETURN) && (event.GetModifiers() == wxMOD_ALT)) || + (event.GetKeyCode() == WXK_ESCAPE)) + { + ShowFullScreen(!IsFullScreen()); + UpdateGUI(); + } + else + { + event.Skip(); + } +} + +void CFrame::UpdateGUI() +{ + // buttons + { + if (Core::GetState() == Core::CORE_UNINITIALIZED) + { + GetToolBar()->EnableTool(IDM_PLUGIN_OPTIONS, true); + m_pPluginOptions->Enable(true); + + GetToolBar()->EnableTool(IDM_STOP, false); + GetToolBar()->EnableTool(IDM_PLAY, false); + + m_pMenuItemPlay->Enable(false); + m_pMenuItemStop->Enable(false); + m_pMenuItemLoad->Enable(false); + m_pMenuItemSave->Enable(false); + } + else + { + GetToolBar()->EnableTool(IDM_PLUGIN_OPTIONS, false); + m_pPluginOptions->Enable(false); + + GetToolBar()->EnableTool(IDM_STOP, true); + GetToolBar()->EnableTool(IDM_PLAY, true); + + m_pMenuItemPlay->Enable(true); + m_pMenuItemStop->Enable(true); + m_pMenuItemLoad->Enable(true); + m_pMenuItemSave->Enable(true); + + if (Core::GetState() == Core::CORE_RUN) + { + GetToolBar()->SetToolNormalBitmap(IDM_PLAY, m_Bitmaps[Toolbar_Pause]); + GetToolBar()->SetToolShortHelp(IDM_PLAY, _T("Pause")); + + m_pMenuItemPlay->SetText(_T("Pause")); + } + else + { + GetToolBar()->SetToolNormalBitmap(IDM_PLAY, m_Bitmaps[Toolbar_Play]); + GetToolBar()->SetToolShortHelp(IDM_PLAY, _T("Play")); + + m_pMenuItemPlay->SetText(_T("Play")); + } + } + } + + // gamelistctrl + { + if (Core::GetState() == Core::CORE_UNINITIALIZED) + { + if (m_GameListCtrl && !m_GameListCtrl->IsShown()) + { + m_GameListCtrl->Enable(); + m_GameListCtrl->Show(); + } + } + else + { + if (m_GameListCtrl && m_GameListCtrl->IsShown()) + { + m_GameListCtrl->Disable(); + m_GameListCtrl->Hide(); + } + } + } +} diff --git a/Source/Core/DolphinWX/Src/Frame.h b/Source/Core/DolphinWX/Src/Frame.h new file mode 100644 index 0000000000..6b6b5d777d --- /dev/null +++ b/Source/Core/DolphinWX/Src/Frame.h @@ -0,0 +1,97 @@ +#ifndef __FRAME_H_ +#define __FRAME_H_ + +class CGameListCtrl; +class CFrame + : public wxFrame +{ + public: + + CFrame(wxFrame* parent, + wxWindowID id = wxID_ANY, + const wxString& title = _T("Dolphin"), + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxDEFAULT_FRAME_STYLE | wxCLIP_CHILDREN | wxNO_FULL_REPAINT_ON_RESIZE); + + void* GetRenderHandle() {return(m_Panel->GetHandle());} + + + private: + + CGameListCtrl* m_GameListCtrl; + wxPanel* m_Panel; + + enum EBitmaps + { + Toolbar_FileOpen, + Toolbar_Refresh, + Toolbar_Browse, + Toolbar_Play, + Toolbar_Play_Dis, + Toolbar_Stop, + Toolbar_Stop_Dis, + Toolbar_Pause, + Toolbar_PluginOptions, + Toolbar_PluginOptions_Dis, + Toolbar_PluginGFX, + Toolbar_PluginDSP, + Toolbar_PluginPAD, + Toolbar_FullScreen, + Toolbar_Help, + Bitmaps_Max + }; + + wxBitmap m_Bitmaps[Bitmaps_Max]; + wxBitmap m_BitmapsMenu[Bitmaps_Max]; + + void InitBitmaps(); + void PopulateToolbar(wxToolBar* toolBar); + void RecreateToolbar(); + void CreateMenu(); + + // event handler + void OnQuit(wxCommandEvent& event); + void OnHelp(wxCommandEvent& event); + void OnRefresh(wxCommandEvent& event); + void OnPluginOptions(wxCommandEvent& event); + void OnPluginGFX(wxCommandEvent& event); + void OnPluginDSP(wxCommandEvent& event); + void OnPluginPAD(wxCommandEvent& event); + void OnOpen(wxCommandEvent& event); + void OnPlay(wxCommandEvent& event); + void OnStop(wxCommandEvent& event); + void OnBrowse(wxCommandEvent& event); + void OnMemcard(wxCommandEvent& event); + void OnToggleFullscreen(wxCommandEvent& event); + void OnToggleDualCore(wxCommandEvent& event); + void OnToggleThrottle(wxCommandEvent& event); + void OnToggleToolbar(wxCommandEvent& event); + void OnKeyDown(wxKeyEvent& event); + void OnHostMessage(wxCommandEvent& event); + void OnLoadState(wxCommandEvent& event); + void OnSaveState(wxCommandEvent& event); + + + wxStatusBar* m_pStatusBar; + wxMenuBar* m_pMenuBar; + + wxMenuItem* m_pMenuItemPlay; + wxMenuItem* m_pMenuItemStop; + wxMenuItem* m_pPluginOptions; + + wxMenuItem* m_pMenuItemLoad; + wxMenuItem* m_pMenuItemSave; + + wxBusyInfo* m_pBootProcessDialog; + + void UpdateGUI(); + + + // old function that could be cool + + DECLARE_EVENT_TABLE(); +}; + +#endif // __FRAME_H_ + diff --git a/Source/Core/DolphinWX/Src/GameListCtrl.cpp b/Source/Core/DolphinWX/Src/GameListCtrl.cpp new file mode 100644 index 0000000000..da9da12257 --- /dev/null +++ b/Source/Core/DolphinWX/Src/GameListCtrl.cpp @@ -0,0 +1,491 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Globals.h" + +#include +#include + +#include "FileSearch.h" +#include "FileUtil.h" +#include "StringUtil.h" +#include "BootManager.h" +#include "Config.h" +#include "GameListCtrl.h" + + +#if USE_XPM_BITMAPS + #include "../resources/Flag_Europe.xpm" + #include "../resources/Flag_France.xpm" + #include "../resources/Flag_Japan.xpm" + #include "../resources/Flag_USA.xpm" +#endif // USE_XPM_BITMAPS + + +BEGIN_EVENT_TABLE(CGameListCtrl, wxListCtrl) + +EVT_SIZE(CGameListCtrl::OnSize) +EVT_RIGHT_DOWN(CGameListCtrl::OnRightClick) +EVT_LIST_COL_BEGIN_DRAG(LIST_CTRL, CGameListCtrl::OnColBeginDrag) +EVT_LIST_ITEM_SELECTED(LIST_CTRL, CGameListCtrl::OnSelected) +EVT_LIST_ITEM_ACTIVATED(LIST_CTRL, CGameListCtrl::OnActivated) +EVT_LIST_COL_END_DRAG(LIST_CTRL, CGameListCtrl::OnColEndDrag) +EVT_MENU(IDM_EDITPATCHFILE, CGameListCtrl::OnEditPatchFile) +EVT_MENU(IDM_OPENCONTAININGFOLDER, CGameListCtrl::OnOpenContainingFolder) +END_EVENT_TABLE() + + +CGameListCtrl::CGameListCtrl(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style) + : wxListCtrl(parent, id, pos, size, style) // | wxLC_VIRTUAL) +{ + InitBitmaps(); +} + + +void +CGameListCtrl::InitBitmaps() +{ + m_imageListSmall = new wxImageList(96, 32); + SetImageList(m_imageListSmall, wxIMAGE_LIST_SMALL); + m_FlagImageIndex.resize(DiscIO::IVolume::NUMBER_OF_COUNTRIES); + wxIcon iconTemp; + iconTemp.CopyFromBitmap(wxBitmap(Flag_Europe_xpm)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_EUROPE] = m_imageListSmall->Add(iconTemp); + iconTemp.CopyFromBitmap(wxBitmap(Flag_France_xpm)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_FRANCE] = m_imageListSmall->Add(iconTemp); + iconTemp.CopyFromBitmap(wxBitmap(Flag_USA_xpm)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_USA] = m_imageListSmall->Add(iconTemp); + iconTemp.CopyFromBitmap(wxBitmap(Flag_Japan_xpm)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_JAP] = m_imageListSmall->Add(iconTemp); + iconTemp.CopyFromBitmap(wxBitmap(Flag_Europe_xpm)); + m_FlagImageIndex[DiscIO::IVolume::COUNTRY_UNKNOWN] = m_imageListSmall->Add(iconTemp); +} + + +void +CGameListCtrl::BrowseForDirectory() +{ + wxString dirHome; + wxGetHomeDir(&dirHome); + + // browse + wxDirDialog dialog(this, _T("Browse directory"), dirHome, wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST); + + if (dialog.ShowModal() == wxID_OK) + { + SConfig::GetInstance().m_ISOFolder.push_back( + std::string(dialog.GetPath().ToAscii()) + ); + SConfig::GetInstance().SaveSettings(); + Update(); + } +} + + +void +CGameListCtrl::Update() +{ + Hide(); + + ScanForISOs(); + + ClearAll(); + + if (m_ISOFiles.size() != 0) + { + // add columns + InsertColumn(COLUMN_BANNER, _T("Banner")); + InsertColumn(COLUMN_TITLE, _T("Title")); + InsertColumn(COLUMN_COMPANY, _T("Company")); + InsertColumn(COLUMN_COUNTRY, _T("")); + InsertColumn(COLUMN_SIZE, _T("Size")); + InsertColumn(COLUMN_EMULATION_STATE, _T("Emulation"), wxLIST_FORMAT_LEFT); + + // add all items + for (int i = 0; i < (int)m_ISOFiles.size(); i++) + { + InsertItemInReportView(i); + } + SetItemState(0, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); + } + else + { + InsertColumn(COLUMN_BANNER, _T("No ISOs found")); + + // data + wxString buf(_T("Dolphin could not find any GC/Wii ISOs. Doubleclick here to browse for files...")); + long item = InsertItem(0, buf, -1); + SetItemFont(item, *wxITALIC_FONT); + SetColumnWidth(item, wxLIST_AUTOSIZE); + SetItemState(0, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); + } + + AutomaticColumnWidth(); + + Show(); +} + +#ifdef _WIN32 +wxColour blend50(const wxColour& c1, const wxColour& c2) +{ + return(((c1.GetPixel() & 0xFEFEFE) >> 1) + ((c2.GetPixel() & 0xFEFEFE) >> 1) + 0x010101); +} +#endif + +wxString NiceSizeFormat(s64 _size) +{ + const char* sizes[] = {"b", "KB", "MB", "GB", "TB", "PB", "EB"}; + int s = 0; + int frac = 0; + + while (_size > (s64)1024) + { + s++; + frac = (int)_size & 1023; + _size /= (s64)1024; + } + + float f = (float)_size + ((float)frac / 1024.0f); + + wxString NiceString; + char tempstr[32]; + sprintf(tempstr,"%3.1f %s", f, sizes[s]); + NiceString = wxString::FromAscii(tempstr); + return(NiceString); +} + + +void +CGameListCtrl::InsertItemInReportView(size_t _Index) +{ + CISOFile& rISOFile = m_ISOFiles[_Index]; + + int ImageIndex = -1; + + if (rISOFile.GetImage().IsOk()) + { + ImageIndex = m_imageListSmall->Add(rISOFile.GetImage()); + } + + // data + wxString buf; + long ItemIndex = InsertItem(_Index, buf, ImageIndex); +#ifdef _WIN32 + wxColour color = (_Index & 1) ? blend50(GetSysColor(COLOR_3DLIGHT), GetSysColor(COLOR_WINDOW)) : GetSysColor(COLOR_WINDOW); +#else + wxColour color = (_Index & 1) ? 0xFFFFFF : 0xEEEEEE; +#endif + // background color color + { + wxListItem item; + item.SetId(ItemIndex); + item.SetBackgroundColour(color); + SetItem(item); + } + + // title color + { + wxListItem item; + item.SetId(ItemIndex); + item.SetColumn(COLUMN_TITLE); + item.SetText(wxString::FromAscii(rISOFile.GetName().c_str())); + SetItem(item); + } + + // company color + { + wxListItem item; + item.SetId(ItemIndex); + item.SetColumn(COLUMN_COMPANY); + item.SetText(wxString::FromAscii(rISOFile.GetCompany().c_str())); + SetItem(item); + } + + // size + { + wxListItem item; + item.SetId(ItemIndex); + item.SetColumn(COLUMN_SIZE); + item.SetText(NiceSizeFormat(rISOFile.GetFileSize())); + SetItem(item); + } + +#ifndef __WXMSW__ + // country + { + // Can't do this in Windows - we use DrawSubItem instead, see below + wxListItem item; + item.m_itemId = ItemIndex; + item.SetColumn(COLUMN_COUNTRY); + item.SetBackgroundColour(color); + DiscIO::IVolume::ECountry Country = rISOFile.GetCountry(); + + if (size_t(Country) < m_FlagImageIndex.size()) + { + item.SetImage(m_FlagImageIndex[rISOFile.GetCountry()]); + } + + SetItem(item); + } +#endif // __WXMSW__ + + // item data + SetItemData(ItemIndex, _Index); +} + + +void +CGameListCtrl::ScanForISOs() +{ + m_ISOFiles.clear(); + + CFileSearch::XStringVector Directories(SConfig::GetInstance().m_ISOFolder); + + CFileSearch::XStringVector Extensions; + Extensions.push_back("*.iso"); + Extensions.push_back("*.gcm"); + Extensions.push_back("*.gcz"); + + CFileSearch FileSearch(Extensions, Directories); + const CFileSearch::XStringVector& rFilenames = FileSearch.GetFileNames(); + + if (rFilenames.size() > 0) + { + wxProgressDialog dialog(_T("Scanning for ISOs"), + _T("Scanning..."), + rFilenames.size(), // range + this, // parent + wxPD_CAN_ABORT | + wxPD_APP_MODAL | + // wxPD_AUTO_HIDE | -- try this as well + wxPD_ELAPSED_TIME | + wxPD_ESTIMATED_TIME | + wxPD_REMAINING_TIME | + wxPD_SMOOTH // - makes indeterminate mode bar on WinXP very small + ); + + dialog.CenterOnParent(); + + for (size_t i = 0; i < rFilenames.size(); i++) + { + std::string FileName; + SplitPath(rFilenames[i], NULL, &FileName, NULL); + + wxString msg; + char tempstring[128]; + sprintf(tempstring,"Scanning %s", FileName.c_str()); + msg = wxString::FromAscii(tempstring); + + bool Cont = dialog.Update(i, msg); + + if (!Cont) + { + break; + } + + CISOFile ISOFile(rFilenames[i]); + + if (ISOFile.IsValid()) + { + m_ISOFiles.push_back(ISOFile); + } + } + } + std::sort(m_ISOFiles.begin(), m_ISOFiles.end()); +} + + +void +CGameListCtrl::OnColBeginDrag(wxListEvent& event) +{ + event.Veto(); +} + + +void +CGameListCtrl::OnColEndDrag(wxListEvent& WXUNUSED (event)) +{ + AutomaticColumnWidth(); +} + + +void +CGameListCtrl::OnRightClick(wxMouseEvent& event) +{ + // Focus the clicked item. + int flags; + long item = HitTest(event.GetPosition(), flags); + if (item != wxNOT_FOUND) { + SetItemState(item, wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED, + wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED); + } + const CISOFile *selected_iso = GetSelectedISO(); + if (selected_iso) { + std::string unique_id = selected_iso->GetUniqueID(); + wxMenu popupMenu; + std::string menu_text = StringFromFormat("Edit &patch file: %s.ini", unique_id.c_str()); + popupMenu.Append(IDM_EDITPATCHFILE, wxString::FromAscii(menu_text.c_str())); //Pretty much everything in wxwidgets is a wxString, try to convert to those first! + popupMenu.Append(IDM_OPENCONTAININGFOLDER, wxString::FromAscii("Open &containing folder")); + PopupMenu(&popupMenu); + } +} + + +void +CGameListCtrl::OnActivated(wxListEvent& event) +{ + if (m_ISOFiles.size() == 0) + { + BrowseForDirectory(); + } + else + { + size_t Index = event.GetData(); + if (Index < m_ISOFiles.size()) + { + const CISOFile& rISOFile = m_ISOFiles[Index]; + BootManager::BootCore(rISOFile.GetFileName()); + } + } +} + +const CISOFile * +CGameListCtrl::GetSelectedISO() const +{ + int item = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item == -1) + return 0; + else + return &m_ISOFiles[GetItemData(item)]; +} + +void +CGameListCtrl::OnOpenContainingFolder(wxCommandEvent& WXUNUSED (event)) { + const CISOFile *iso = GetSelectedISO(); + if (!iso) + return; + std::string path; + SplitPath(iso->GetFileName(), &path, 0, 0); + File::Explore(path); +} + +void +CGameListCtrl::OnEditPatchFile(wxCommandEvent& WXUNUSED (event)) +{ + const CISOFile *iso = GetSelectedISO(); + if (!iso) + return; + std::string filename = "Patches/" + iso->GetUniqueID() + ".ini"; + if (!File::Exists(filename)) { + if (AskYesNo("%s.ini does not exist. Do you want to create it?", iso->GetUniqueID().c_str())) { + FILE *f = fopen(filename.c_str(), "w"); + fprintf(f, "# %s - %s\r\n\r\n", iso->GetUniqueID().c_str(), iso->GetName().c_str()); + fprintf(f, "[OnFrame]\r\n#Add memory patches here.\r\n\r\n"); + fprintf(f, "[ActionReplay]\r\n#Add decrypted action replay cheats here.\r\n"); + fclose(f); + } else { + return; + } + } + File::Launch(filename); +} + + +void +CGameListCtrl::OnSelected(wxListEvent& WXUNUSED (event)) +{} + + +void CGameListCtrl::OnSize(wxSizeEvent& WXUNUSED (event)) +{ + AutomaticColumnWidth(); +} + + +bool +CGameListCtrl::MSWDrawSubItem(wxPaintDC& rPaintDC, int item, int subitem) +{ + bool Result = false; +#ifdef __WXMSW__ + switch (subitem) + { + case COLUMN_COUNTRY: + { + size_t Index = GetItemData(item); + + if (Index < m_ISOFiles.size()) + { + const CISOFile& rISO = m_ISOFiles[Index]; + wxRect SubItemRect; + this->GetSubItemRect(item, subitem, SubItemRect); + m_imageListSmall->Draw(m_FlagImageIndex[rISO.GetCountry()], rPaintDC, SubItemRect.GetLeft(), SubItemRect.GetTop()); + } + } + } + + // +#endif + + return(Result); +} + + +void +CGameListCtrl::AutomaticColumnWidth() +{ + wxRect rc(GetClientRect()); + + if (GetColumnCount() == 1) + { + SetColumnWidth(0, rc.GetWidth()); + } + else if (GetColumnCount() > 4) + { + SetColumnWidth(COLUMN_COUNTRY, 32); + SetColumnWidth(COLUMN_BANNER, 106); + + // width + for (int i = 0; i < GetColumnCount() - 1; i++) + { + if ((i != COLUMN_COUNTRY) && (i != COLUMN_BANNER)) + { + SetColumnWidth(i, wxLIST_AUTOSIZE); + } + } + + + int size = 0; + + for (int i = 0; i < GetColumnCount() - 1; i++) + { + size += GetColumnWidth(i); + } + + int rest = rc.GetWidth() - size - 3; + + if (rest > 0) + { + SetColumnWidth(GetColumnCount() - 1, rest); + } + else + { + SetColumnWidth(GetColumnCount() - 1, 0); + } + } +} + + diff --git a/Source/Core/DolphinWX/Src/GameListCtrl.h b/Source/Core/DolphinWX/Src/GameListCtrl.h new file mode 100644 index 0000000000..7148027562 --- /dev/null +++ b/Source/Core/DolphinWX/Src/GameListCtrl.h @@ -0,0 +1,78 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef __GAMELIST_CTRL_H_ +#define __GAMELIST_CTRL_H_ + +#include + +#include + +#include "ISOFile.h" + +class CGameListCtrl : public wxListCtrl +{ + public: + + CGameListCtrl(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style); + void Update(); + void BrowseForDirectory(); + const CISOFile *GetSelectedISO() const; + + private: + + enum + { + COLUMN_BANNER = 0, + COLUMN_TITLE, + COLUMN_COMPANY, + COLUMN_COUNTRY, + COLUMN_SIZE, + COLUMN_EMULATION_STATE, + NUMBER_OF_COLUMN + }; + + std::vectorm_FlagImageIndex; + + bool m_test; + std::vector m_ISOFiles; + + void InitBitmaps(); + void InsertItemInReportView(size_t _Index); + void ScanForISOs(); + + DECLARE_EVENT_TABLE() + + // events + void OnRightClick(wxMouseEvent& event); + + void OnColBeginDrag(wxListEvent& event); + void OnColEndDrag(wxListEvent& event); + void OnSelected(wxListEvent& event); + void OnActivated(wxListEvent& event); + void OnSize(wxSizeEvent& event); + void OnEditPatchFile(wxCommandEvent& event); + void OnOpenContainingFolder(wxCommandEvent& event); + + virtual bool MSWDrawSubItem(wxPaintDC& rPaintDC, int item, int subitem); + + void AutomaticColumnWidth(); +}; + + +#endif + diff --git a/Source/Core/DolphinWX/Src/Globals.cpp b/Source/Core/DolphinWX/Src/Globals.cpp new file mode 100644 index 0000000000..cc5cb500cd --- /dev/null +++ b/Source/Core/DolphinWX/Src/Globals.cpp @@ -0,0 +1,18 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Globals.h" diff --git a/Source/Core/DolphinWX/Src/Globals.h b/Source/Core/DolphinWX/Src/Globals.h new file mode 100644 index 0000000000..89ff5a2176 --- /dev/null +++ b/Source/Core/DolphinWX/Src/Globals.h @@ -0,0 +1,121 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _GLOBALS_H +#define _GLOBALS_H + +enum +{ + IDM_LOADSTATE = 200, + IDM_SAVESTATE, + IDM_SAVESLOT1, + IDM_SAVESLOT2, + IDM_SAVESLOT3, + IDM_SAVESLOT4, + IDM_SAVESLOT5, + IDM_SAVESLOT6, + IDM_SAVESLOT7, + IDM_SAVESLOT8, + IDM_SAVESLOT9, + IDM_SAVESLOT10, + IDM_LOADSLOT1, + IDM_LOADSLOT2, + IDM_LOADSLOT3, + IDM_LOADSLOT4, + IDM_LOADSLOT5, + IDM_LOADSLOT6, + IDM_LOADSLOT7, + IDM_LOADSLOT8, + IDM_LOADSLOT9, + IDM_LOADSLOT10, + IDM_PLAY, + IDM_STOP, + IDM_BROWSE, + IDM_MEMCARD, + IDM_EDITPATCHFILE, + IDM_OPENCONTAININGFOLDER, + IDM_PLUGIN_OPTIONS, + IDM_CONFIG_GFX_PLUGIN, + IDM_CONFIG_DSP_PLUGIN, + IDM_CONFIG_PAD_PLUGIN, + IDM_TOGGLE_FULLSCREEN, + IDM_TOGGLE_DUALCORE, + IDM_TOGGLE_TOOLBAR, + IDM_NOTIFYMAPLOADED, + IDM_UPDATELOGDISPLAY, + IDM_UPDATEDISASMDIALOG, + IDM_UPDATEGUI, + IDM_UPDATESTATUSBAR, + IDM_UPDATEBREAKPOINTS, + IDM_HOST_MESSAGE, + IDM_BOOTING_STARTED, + IDM_BOOTING_ENDED, + IDM_HELPABOUT, + IDM_HELPWEBSITE, + IDM_HELPGOOGLECODE, + ID_TOOLBAR = 500, + LIST_CTRL = 1000 +}; + +#define wxUSE_XPM_IN_MSW 1 +#define USE_XPM_BITMAPS 1 + +// For compilers that support precompilation, includes . +//#include + +//#ifndef WX_PRECOMP +#include +//#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// define this to use XPMs everywhere (by default, BMPs are used under Win) +// BMPs use less space, but aren't compiled into the executable on other platforms + +#if USE_XPM_BITMAPS && defined (__WXMSW__) && !wxUSE_XPM_IN_MSW +#error You need to enable XPM support to use XPM bitmaps with toolbar! +#endif // USE_XPM_BITMAPS + + +// +// custom message macro +// + +#define EVT_HOST_COMMAND(id, fn) \ + DECLARE_EVENT_TABLE_ENTRY(\ + wxEVT_HOST_COMMAND, id, wxID_ANY, \ + (wxObjectEventFunction)(wxEventFunction) wxStaticCastEvent(wxCommandEventFunction, &fn), \ + (wxObject*) NULL \ + ), + +extern const wxEventType wxEVT_HOST_COMMAND; + +#endif diff --git a/Source/Core/DolphinWX/Src/ISOFile.cpp b/Source/Core/DolphinWX/Src/ISOFile.cpp new file mode 100644 index 0000000000..54a21a4c45 --- /dev/null +++ b/Source/Core/DolphinWX/Src/ISOFile.cpp @@ -0,0 +1,98 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include +#include + +#include "Globals.h" +#include "ISOFile.h" + +#include "VolumeCreator.h" +#include "Filesystem.h" +#include "BannerLoader.h" +#include "FileSearch.h" + +#define DVD_BANNER_WIDTH 96 +#define DVD_BANNER_HEIGHT 32 + +static u32 g_ImageTemp[DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT]; + +CISOFile::CISOFile(const std::string& _rFileName) + : m_FileName(_rFileName), + m_FileSize(0), + m_Valid(false) +{ + DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(_rFileName); + + if (pVolume != NULL) + { + m_Name = _rFileName; + m_Country = pVolume->GetCountry(); + m_FileSize = pVolume->GetSize(); + m_Name = pVolume->GetName(); + m_UniqueID = pVolume->GetUniqueID(); + + // check if we can get some infos from the banner file too + DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(*pVolume); + + if (pFileSystem != NULL) + { + DiscIO::IBannerLoader* pBannerLoader = DiscIO::CreateBannerLoader(*pFileSystem); + + if (pBannerLoader != NULL) + { + if (pBannerLoader->IsValid()) + { + pBannerLoader->GetName(m_Name, 0); //m_Country == DiscIO::IVolume::COUNTRY_JAP ? 1 : 0); + pBannerLoader->GetCompany(m_Company); + + if (pBannerLoader->GetBanner(g_ImageTemp)) + { + unsigned char* pImage = (unsigned char*)malloc(DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT * 3); + + for (size_t i = 0; i < DVD_BANNER_WIDTH * DVD_BANNER_HEIGHT; i++) + { + pImage[i * 3 + 0] = (g_ImageTemp[i] & 0xFF0000) >> 16; + pImage[i * 3 + 1] = (g_ImageTemp[i] & 0x00FF00) >> 8; + pImage[i * 3 + 2] = (g_ImageTemp[i] & 0x0000FF) >> 0; + } + + m_Image.Create(DVD_BANNER_WIDTH, DVD_BANNER_HEIGHT, pImage); + } + } + else + { + // default banner + } + + delete pBannerLoader; + } + + delete pFileSystem; + } + + delete pVolume; + + m_Valid = true; + } +} + + +CISOFile::~CISOFile() +{} + + diff --git a/Source/Core/DolphinWX/Src/ISOFile.h b/Source/Core/DolphinWX/Src/ISOFile.h new file mode 100644 index 0000000000..a8ff08dd7a --- /dev/null +++ b/Source/Core/DolphinWX/Src/ISOFile.h @@ -0,0 +1,68 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef __ISOFILE_H_ +#define __ISOFILE_H_ + +#include "Volume.h" + +class CISOFile +{ + public: + + CISOFile(const std::string& _rFileName); + ~CISOFile(); + + bool IsValid() const {return(m_Valid);} + + const std::string& GetFileName() const {return(m_FileName);} + + const std::string& GetName() const {return(m_Name);} + + const std::string& GetCompany() const {return(m_Company);} + + const std::string& GetUniqueID() const {return(m_UniqueID);} + + DiscIO::IVolume::ECountry GetCountry() const {return(m_Country);} + + u64 GetFileSize() const {return(m_FileSize);} + + const wxImage& GetImage() const {return(m_Image);} + + bool operator < (const CISOFile &other) const { + // HACK - they end up in reverse order in the list view + return strcmp(m_Name.c_str(), other.m_Name.c_str()) > 0; + } + + private: + + std::string m_FileName; + std::string m_Name; + std::string m_Company; + std::string m_UniqueID; + + u64 m_FileSize; + + DiscIO::IVolume::ECountry m_Country; + + wxImage m_Image; + + bool m_Valid; +}; + + +#endif diff --git a/Source/Core/DolphinWX/Src/Main.cpp b/Source/Core/DolphinWX/Src/Main.cpp new file mode 100644 index 0000000000..23da10a48e --- /dev/null +++ b/Source/Core/DolphinWX/Src/Main.cpp @@ -0,0 +1,276 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include +#include +#ifdef WIN32 + #include "svnrev.h" +#endif +#include "CPUDetect.h" +#include "Globals.h" +#include "Common.h" +#include "IniFile.h" +#include "Main.h" +#include "Frame.h" +#include "Config.h" +#include "CodeWindow.h" +#include "ExtendedTrace.h" + +IMPLEMENT_APP(DolphinApp) + +CFrame* main_frame = NULL; +CCodeWindow* g_pCodeWindow = NULL; + +#ifdef WIN32 +//Has no error handling. +//I think that if an error occurs here there's no way to handle it anyway. +LONG WINAPI MyUnhandledExceptionFilter(LPEXCEPTION_POINTERS e) { + //EnterCriticalSection(&g_uefcs); + + FILE* file=NULL; + fopen_s(&file, "exceptioninfo.txt", "a"); + fseek(file, 0, SEEK_END); + etfprint(file, "\n"); + //etfprint(file, g_buildtime); + //etfprint(file, "\n"); + //dumpCurrentDate(file); + etfprintf(file, "Unhandled Exception\n Code: 0x%08X\n", + e->ExceptionRecord->ExceptionCode); +#ifndef _M_X64 + STACKTRACE2(file, e->ContextRecord->Eip, e->ContextRecord->Esp, e->ContextRecord->Ebp); +#else + STACKTRACE2(file, e->ContextRecord->Rip, e->ContextRecord->Rsp, e->ContextRecord->Rbp); +#endif + fclose(file); + _flushall(); + + //LeaveCriticalSection(&g_uefcs); + return EXCEPTION_CONTINUE_SEARCH; +} +#endif + +// The `main program' equivalent, creating the windows and returning the +// main frame +bool DolphinApp::OnInit() +{ + DetectCPU(); +#ifndef _WIN32 +// RegisterPanicAlertHandler(&wxPanicAlert); +#endif + +#ifdef _WIN32 + EXTENDEDTRACEINITIALIZE("."); + SetUnhandledExceptionFilter(&MyUnhandledExceptionFilter); + + // TODO: if First Boot + if (!cpu_info.bSSE2) + { + MessageBox(0, _T("Hi,\n\nDolphin requires that your CPU has support for SSE2 extensions.\n" + "Unfortunately your CPU does not support them, so Dolphin will not run.\n\n" + "Sayonara!\n"), "Dolphin", MB_ICONINFORMATION); + return false; + } +#else + if (!cpu_info.bSSE2) + { + printf("%s", "Hi,\n\nDolphin requires that your CPU has support for SSE2 extensions.\n" + "Unfortunately your CPU does not support them, so Dolphin will not run.\n\n" + "Sayonara!\n"); + exit(0); + } +#endif + + bool UseDebugger = false; + +#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} + }; + + //gets the passed media files from command line + wxCmdLineParser parser(cmdLineDesc, argc, argv); + + // get filenames from the command line + if (parser.Parse() != 0) + { + return false; + } + + UseDebugger = parser.Found(_T("debugger")); +#endif + + SConfig::GetInstance().LoadSettings(); + wxInitAllImageHandlers(); + // Create the main frame window +#ifdef _WIN32 + #ifdef _DEBUG + const char *title = "Dolphin Debug SVN R " SVN_REV_STR; + #else + const char *title = "Dolphin SVN R " SVN_REV_STR; + #endif +#else + #ifdef _DEBUG + const char *title = "Dolphin Debug SVN Linux"; + #else + const char *title = "Dolphin SVN Linux"; + #endif +#endif + main_frame = new CFrame((wxFrame*) NULL, wxID_ANY, wxString::FromAscii(title), + wxPoint(100, 100), wxSize(800, 600)); + + // create debugger + if (UseDebugger) + { + g_pCodeWindow = new CCodeWindow(SConfig::GetInstance().m_LocalCoreStartupParameter, main_frame); + g_pCodeWindow->Show(true); + } + + SetTopWindow(main_frame); + return true; +} + + +void DolphinApp::OnEndSession() +{ + SConfig::GetInstance().SaveSettings(); +} + + +bool wxPanicAlert(const char* text, bool /*yes_no*/) +{ + wxMessageBox(wxString::FromAscii(text), _T("PANIC ALERT")); + return(true); +} + + +void Host_BootingStarted() +{ + wxCommandEvent event(wxEVT_HOST_COMMAND, IDM_BOOTING_STARTED); + wxPostEvent(main_frame, event); + + if (g_pCodeWindow) + { + wxPostEvent(g_pCodeWindow, event); + } +} + + +void Host_BootingEnded() +{ + wxCommandEvent event(wxEVT_HOST_COMMAND, IDM_BOOTING_ENDED); + wxPostEvent(main_frame, event); + + if (g_pCodeWindow) + { + wxPostEvent(g_pCodeWindow, event); + } +} + + +// OK, this thread boundary is DANGEROUS on linux +// wxPostEvent / wxAddPendingEvent is the solution. +void Host_NotifyMapLoaded() +{ + wxCommandEvent event(wxEVT_HOST_COMMAND, IDM_NOTIFYMAPLOADED); + wxPostEvent(main_frame, event); + + if (g_pCodeWindow) + { + wxPostEvent(g_pCodeWindow, event); + } +} + + +void Host_UpdateLogDisplay() +{ + wxCommandEvent event(wxEVT_HOST_COMMAND, IDM_UPDATELOGDISPLAY); + wxPostEvent(main_frame, event); + + if (g_pCodeWindow) + { + wxPostEvent(g_pCodeWindow, event); + } +} + + +void Host_UpdateDisasmDialog() +{ + wxCommandEvent event(wxEVT_HOST_COMMAND, IDM_UPDATEDISASMDIALOG); + wxPostEvent(main_frame, event); + if (g_pCodeWindow) + { + wxPostEvent(g_pCodeWindow, event); + } +} + + +void Host_UpdateMainFrame() +{ + wxCommandEvent event(wxEVT_HOST_COMMAND, IDM_UPDATEGUI); + wxPostEvent(main_frame, event); + + if (g_pCodeWindow) + { + wxPostEvent(g_pCodeWindow, event); + } +} + +void Host_UpdateBreakPointView() +{ + wxCommandEvent event(wxEVT_HOST_COMMAND, IDM_UPDATEBREAKPOINTS); + wxPostEvent(main_frame, event); + + if (g_pCodeWindow) + { + wxPostEvent(g_pCodeWindow, event); + } +} + + +void Host_UpdateMemoryView() +{} + + +void Host_SetDebugMode(bool) +{} + + +void Host_SetWaitCursor(bool enable) +{ +#ifdef _WIN32 + if (enable) + { + SetCursor(LoadCursor(NULL, IDC_WAIT)); + } + else + { + SetCursor(LoadCursor(NULL, IDC_ARROW)); + } +#endif + +} + +void Host_UpdateStatusBar(const char* _pText) +{ + wxCommandEvent event(wxEVT_HOST_COMMAND, IDM_UPDATESTATUSBAR); + event.SetString(wxString::FromAscii(_pText)); + + wxPostEvent(main_frame, event); +} diff --git a/Source/Core/DolphinWX/Src/Main.h b/Source/Core/DolphinWX/Src/Main.h new file mode 100644 index 0000000000..6b2659752b --- /dev/null +++ b/Source/Core/DolphinWX/Src/Main.h @@ -0,0 +1,32 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef __MAIN_H_ +#define __MAIN_H_ + +// Define a new application +class DolphinApp + : public wxApp +{ + public: + + bool OnInit(); + void OnEndSession(); +}; + + +#endif diff --git a/Source/Core/DolphinWX/Src/MainNoGUI.cpp b/Source/Core/DolphinWX/Src/MainNoGUI.cpp new file mode 100644 index 0000000000..2389cf017d --- /dev/null +++ b/Source/Core/DolphinWX/Src/MainNoGUI.cpp @@ -0,0 +1,89 @@ +#include +#include +#ifndef _WIN32 +//#include +#else +#endif + +#include "Globals.h" +#include "Common.h" +#include "ISOFile.h" +#include "CPUDetect.h" + +#include "BootManager.h" +void* g_pCodeWindow = NULL; +void* main_frame = NULL; +bool wxPanicAlert(const char* text, bool /*yes_no*/) +{ + return(true); +} + + +void Host_BootingStarted(){} + + +void Host_BootingEnded(){} + + +// OK, this thread boundary is DANGEROUS on linux +// wxPostEvent / wxAddPendingEvent is the solution. +void Host_NotifyMapLoaded(){} + + +void Host_UpdateLogDisplay(){} + + +void Host_UpdateDisasmDialog(){} + + +void Host_UpdateMainFrame(){} + +void Host_UpdateBreakPointView(){} + + +void Host_UpdateMemoryView(){} + + +void Host_SetDebugMode(bool){} + + +void Host_SetWaitCursor(bool enable){} + + +void Host_CreateDisplay(){} + + +void Host_CloseDisplay(){} + +void Host_UpdateStatusBar(const char* _pText){} + +// Include SDL header so it can hijack main(). +#include +#include "cmdline.h" + +int main(int argc, char* argv[]) +{ + gengetopt_args_info args_info; + + if (cmdline_parser (argc, argv, &args_info) != 0) + return(1); + + if (args_info.inputs_num < 1) + { + fprintf(stderr, "Please supply at least one argument - the ISO to boot.\n"); + return(1); + } + std::string bootFile(args_info.inputs[0]); + + DetectCPU(); + BootManager::BootCore(bootFile); + usleep(2000 * 1000 * 1000); +// while (!getch()) { + // usleep(20); +// } + + cmdline_parser_free (&args_info); + return(0); +} + + diff --git a/Source/Core/DolphinWX/Src/MemcardManager.cpp b/Source/Core/DolphinWX/Src/MemcardManager.cpp new file mode 100644 index 0000000000..f84dff9ed2 --- /dev/null +++ b/Source/Core/DolphinWX/Src/MemcardManager.cpp @@ -0,0 +1,313 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Globals.h" + +#include "MemcardManager.h" + +#include "wx/mstream.h" + +const u8 hdr[] = { +0x42,0x4D, +0x38,0x30,0x00,0x00, +0x00,0x00,0x00,0x00, +0x36,0x00,0x00,0x00, +0x28,0x00,0x00,0x00, +0x20,0x00,0x00,0x00, //W +0x20,0x00,0x00,0x00, //H +0x01,0x00, +0x20,0x00, +0x00,0x00,0x00,0x00, +0x02,0x30,0x00,0x00, //data size +0x12,0x0B,0x00,0x00, +0x12,0x0B,0x00,0x00, +0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00 +}; + +wxBitmap wxBitmapFromMemoryRGBA(const unsigned char* data, int width, int height) +{ + int stride = (4*width); + + int bytes = (stride*height) + sizeof(hdr); + + bytes = (bytes+3)&(~3); + + u8 *pdata = new u8[bytes]; + + memset(pdata,0,bytes); + memcpy(pdata,hdr,sizeof(hdr)); + + u8 *pixelData = pdata + sizeof(hdr); + + for(int y=0;yCopy->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + m_CopyLeft = new wxButton(this, ID_COPYLEFT, wxT("<-Copy<-"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + + m_DeleteRight = new wxButton(this, ID_DELETERIGHT, wxT("Delete->"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + m_DeleteLeft = new wxButton(this, ID_DELETELEFT, wxT("<-Delete"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + + // sizers that double as wxStaticBoxes + sMemcard1 = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Memory Card 1")); + sMemcard2 = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Memory Card 2")); + + // create the controls for both memcards + // will change Mem*.raw to *.raw, when loading invalid .raw files doesn't crash the app :/ + m_Memcard1Path = new wxFilePickerCtrl(this, ID_MEMCARD1PATH, wxEmptyString, wxT("Choose a memory card:"), + wxT("Dolphin memcards (Mem*.raw)|Mem*.raw"), wxDefaultPosition, wxDefaultSize, wxFLP_USE_TEXTCTRL|wxFLP_FILE_MUST_EXIST|wxFLP_OPEN); + m_Memcard2Path = new wxFilePickerCtrl(this, ID_MEMCARD2PATH, wxEmptyString, wxT("Choose a memory card:"), + wxT("Dolphin memcards (Mem*.raw)|Mem*.raw"), wxDefaultPosition, wxDefaultSize, wxFLP_USE_TEXTCTRL|wxFLP_FILE_MUST_EXIST|wxFLP_OPEN); + + m_MemcardList[0] = new wxListCtrl(this, ID_MEMCARD1LIST, wxDefaultPosition, wxSize(350,400), + wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT | wxLC_SINGLE_SEL); + m_MemcardList[1] = new wxListCtrl(this, ID_MEMCARD2LIST, wxDefaultPosition, wxSize(350,400), + wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT | wxLC_SINGLE_SEL); + + m_MemcardList[0]->AssignImageList(new wxImageList(96,32),wxIMAGE_LIST_SMALL); + m_MemcardList[1]->AssignImageList(new wxImageList(96,32),wxIMAGE_LIST_SMALL); + + // mmmm sizer goodness + wxBoxSizer* sButtons; + sButtons = new wxBoxSizer(wxVERTICAL); + sButtons->AddStretchSpacer(1); + sButtons->Add(m_CopyRight, 0, 0, 5); + sButtons->Add(m_CopyLeft, 0, 0, 5); + sButtons->AddStretchSpacer(2); + sButtons->Add(m_DeleteRight, 0, 0, 5); + sButtons->Add(m_DeleteLeft, 0, 0, 5); + sButtons->AddStretchSpacer(1); + + sMemcard1->Add(m_Memcard1Path, 0, wxEXPAND|wxALL, 5); + sMemcard1->Add(m_MemcardList[0], 1, wxEXPAND|wxALL, 5); + sMemcard2->Add(m_Memcard2Path, 0, wxEXPAND|wxALL, 5); + sMemcard2->Add(m_MemcardList[1], 1, wxEXPAND|wxALL, 5); + + //wxBoxSizer* sMain; + sMain = new wxBoxSizer(wxHORIZONTAL); + sMain->Add(sMemcard1, 1, wxEXPAND|wxALL, 5); + sMain->Add(sButtons, 0, wxEXPAND, 0); + sMain->Add(sMemcard2, 1, wxEXPAND|wxALL, 5); + + CenterOnParent(); + this->SetSizer(sMain); + sMain->SetSizeHints(this); +} + +void CMemcardManager::OnClose(wxCloseEvent& WXUNUSED (event)) +{ + Destroy(); +} + +void CMemcardManager::OnPathChange(wxFileDirPickerEvent& event) +{ + switch(event.GetId()) + { + case ID_MEMCARD1PATH: + ReloadMemcard(event.GetPath().mb_str(), 0); + break; + case ID_MEMCARD2PATH: + ReloadMemcard(event.GetPath().mb_str(), 1); + break; + } +} + +void CMemcardManager::CopyDeleteClick(wxCommandEvent& event) +{ + int index0 = m_MemcardList[0]->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);; + int index1 = m_MemcardList[1]->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);; + + switch(event.GetId()) + { + case ID_COPYRIGHT: + if(index0 != -1 && m_MemcardList[1]->GetItemCount() > 0) + { + memoryCard[1]->CopyFrom(*memoryCard[0], index0); + memoryCard[1]->Save(); + ReloadMemcard(m_Memcard2Path->GetPath().mb_str(), 1); + } + break; + case ID_COPYLEFT: + if(index1 != -1 && m_MemcardList[0]->GetItemCount() > 0) + { + memoryCard[0]->CopyFrom(*memoryCard[1], index1); + memoryCard[0]->Save(); + ReloadMemcard(m_Memcard1Path->GetPath().mb_str(), 0); + } + break; + case ID_DELETERIGHT: + if(index1 != -1) + { + memoryCard[1]->RemoveFile(index1); + memoryCard[1]->Save(); + ReloadMemcard(m_Memcard2Path->GetPath().mb_str(), 1); + } + break; + case ID_DELETELEFT: + if(index0 != -1) + { + memoryCard[0]->RemoveFile(index0); + memoryCard[0]->Save(); + ReloadMemcard(m_Memcard1Path->GetPath().mb_str(), 0); + } + break; + } +} + +void CMemcardManager::ReloadMemcard(const char *fileName, int card) +{ + if(memoryCard[card]) delete memoryCard[card]; + + // TODO: add error checking and banners/icons + memoryCard[card] = new GCMemcard(fileName); + + m_MemcardList[card]->Hide(); + m_MemcardList[card]->ClearAll(); + m_MemcardList[card]->InsertColumn(COLUMN_BANNER, _T("Banner")); + m_MemcardList[card]->InsertColumn(COLUMN_TITLE, _T("Title")); + m_MemcardList[card]->InsertColumn(COLUMN_COMMENT, _T("Comment")); + m_MemcardList[card]->InsertColumn(COLUMN_ICON, _T("Icon")); + + wxImageList *list=m_MemcardList[card]->GetImageList(wxIMAGE_LIST_SMALL); + list->RemoveAll(); + + int nFiles = memoryCard[card]->GetNumFiles(); + + int *images = new int[nFiles*2]; + for(int i=0;iReadAnimRGBA8(i,animData,animDelay); + + if(!memoryCard[card]->ReadBannerRGBA8(i,pxdata)) + { + memset(pxdata,0,96*32*4); + + if(numFrames>0) // just use the first one + { + u32 *icdata = animData; + + for(int y=0;y<32;y++) + { + for(int x=0;x<32;x++) + { + pxdata[y*96+x+32] = icdata[y*32+x] /* | 0xFF000000 */; + } + } + } + } + + wxBitmap map = wxBitmapFromMemoryRGBA((u8*)pxdata,96,32); + images[i*2] = list->Add(map); + + if(numFrames>0) + { + memset(pxdata,0,96*32*4); + for(int y=0;y<32;y++) + { + for(int x=0;x<32;x++) + { + pxdata[y*96+x] = animData[y*32+x]; + } + } + + wxBitmap icon = wxBitmapFromMemoryRGBA((u8*)pxdata,96,32); + images[i*2+1] = list->Add(icon); + } + } + + for(int i=0;iGetComment1(i,title)) title[0]=0; + if(!memoryCard[card]->GetComment2(i,comment)) comment[0]=0; + + int index = m_MemcardList[card]->InsertItem(i, wxString::FromAscii("row")); + m_MemcardList[card]->SetItem(index, COLUMN_BANNER, wxString::FromAscii("")); + m_MemcardList[card]->SetItem(index, COLUMN_TITLE, wxString::FromAscii(title)); + m_MemcardList[card]->SetItem(index, COLUMN_COMMENT, wxString::FromAscii(comment)); + m_MemcardList[card]->SetItem(index, COLUMN_ICON, wxString::FromAscii("")); + + if(images[i]>=0) + { + m_MemcardList[card]->SetItemImage(index, images[i*2]); + m_MemcardList[card]->SetItemColumnImage(index, COLUMN_ICON, images[i*2+1]); + } + } + m_MemcardList[card]->Show(); + + delete[] images; + + // automatic column width + for (int i = 0; i < m_MemcardList[card]->GetColumnCount(); i++) + { + m_MemcardList[card]->SetColumnWidth(i, wxLIST_AUTOSIZE); + } +} diff --git a/Source/Core/DolphinWX/Src/MemcardManager.h b/Source/Core/DolphinWX/Src/MemcardManager.h new file mode 100644 index 0000000000..f848027769 --- /dev/null +++ b/Source/Core/DolphinWX/Src/MemcardManager.h @@ -0,0 +1,91 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef __MEMCARD_MANAGER_h__ +#define __MEMCARD_MANAGER_h__ + +#include +#include +#include +#include +#include +#include + +#include "MemoryCards/GCMemcard.h" + +#undef MEMCARD_MANAGER_STYLE +#define MEMCARD_MANAGER_STYLE wxCAPTION | wxSYSTEM_MENU | wxDIALOG_NO_PARENT | wxCLOSE_BOX | wxRESIZE_BORDER | wxMAXIMIZE_BOX + +class CMemcardManager + : public wxDialog +{ + public: + + CMemcardManager(wxWindow* parent, wxWindowID id = 1, const wxString& title = wxT("Memory Card Manager WARNING-Make backups before using, will probably mangle stuff!"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = MEMCARD_MANAGER_STYLE); + virtual ~CMemcardManager(); + + private: + + DECLARE_EVENT_TABLE(); + + wxBoxSizer* sMain; + wxButton* m_CopyRight; + wxButton* m_CopyLeft; + wxButton* m_DeleteRight; + wxButton* m_DeleteLeft; + wxStaticBoxSizer* sMemcard1; + wxStaticBoxSizer* sMemcard2; + wxFilePickerCtrl* m_Memcard1Path; + wxFilePickerCtrl* m_Memcard2Path; + wxListCtrl* m_MemcardList[2]; + wxTimer* m_Timer; + + int nframe; + + enum + { + ID_COPYRIGHT = 1000, + ID_COPYLEFT, + ID_DELETERIGHT, + ID_DELETELEFT, + ID_MEMCARD1PATH, + ID_MEMCARD2PATH, + ID_MEMCARD1LIST, + ID_MEMCARD2LIST, + ID_DUMMY_VALUE_ //don't remove this value unless you have other enum values + }; + + enum + { + COLUMN_BANNER = 0, + COLUMN_TITLE, + COLUMN_COMMENT, + COLUMN_ICON, + NUMBER_OF_COLUMN + }; + + GCMemcard *memoryCard[2]; + + void CreateGUIControls(); + void OnClose(wxCloseEvent& event); + void CopyDeleteClick(wxCommandEvent& event); + void ReloadMemcard(const char *fileName, int card); + void OnPathChange(wxFileDirPickerEvent& event); + void OnTimer(wxTimerEvent& event); +}; + +#endif diff --git a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp new file mode 100644 index 0000000000..9bad19fa50 --- /dev/null +++ b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.cpp @@ -0,0 +1,655 @@ +// gcmc.cpp: define el punto de entrada de la aplicación de consola. +// +#ifdef _WIN32 +#include "stdafx.h" +#endif +#include +#include +#include + +#include "GCMemcard.h" + +void GCMemcard::calc_checksumsBE(u16 *buf, u32 num, u16 *c1, u16 *c2) +{ + *c1 = 0;*c2 = 0; + for (u32 i = 0; i < num; ++i) + { + //weird warnings here + *c1 += bswap16(buf[i]); + *c2 += bswap16((u16)(buf[i] ^ 0xffff)); + } + if (*c1 == 0xffff) + { + *c1 = 0; + } + if (*c2 == 0xffff) + { + *c2 = 0; + } +} + +u32 GCMemcard::GetNumFiles() +{ + if(!mcdFile) return 0; + + for(int i=0;i<126;i++) + { + if(BE32(dir.Dir[i].Gamecode)==0xFFFFFFFF) + return i; + } + return 127; +} + +bool GCMemcard::RemoveFile(u32 index) //index in the directory array +{ + if(!mcdFile) return false; + + //backup the directory and bat (not really needed here but meh :P + dir_backup=dir; + bat_backup=bat; + + int totalspace = (((u32)BE16(hdr.Size)*16)-5); + + //free the blocks + int blocks_left = BE16(dir.Dir[index].BlockCount); + int block = BE16(dir.Dir[index].FirstBlock); + do + { + int cbi = block-5; + int nextblock=bswap16(bat.Map[cbi]); + //assert(nextblock!=0); + if(nextblock==0) + { + nextblock = block+1; + } + + bat.Map[cbi]=0; + + block=nextblock; + blocks_left--; + } + while((block!=0xffff)&&(blocks_left>0)); + + //delete directory entry + for(int i=index;i<125;i++) + { + dir.Dir[i]=dir.Dir[i+1]; + } + memset(&(dir.Dir[125]),0xFF,sizeof(DEntry)); + + //pack blocks to remove free space partitioning, assume no fragmentation. + u8 *mc_data2 = new u8[mc_data_size]; + + int firstFree=0; + for(int i=0;i<126;i++) + { + if(BE32(dir.Dir[i].Gamecode)==0xFFFFFFFF) + { + break; + } + + int fb = BE16(dir.Dir[i].FirstBlock); + int bc = BE16(dir.Dir[i].BlockCount); + + u8* src = mc_data + (fb-5)*0x2000; + u8* dst = mc_data2 + firstFree*0x2000; + + memcpy(dst,src,bc*0x2000); + + for(int j=0;j>8); + dir.Dir[i].FirstBlock[1] = u8((firstFree+5)); + + firstFree += bc; + } + + for(int j=firstFree;j>8); + bat.LastAllocated[1] = u8(firstFree); + + delete [] mc_data; + mc_data = mc_data2; + //-- + + //update freespace counter + int freespace1 = totalspace - firstFree; + bat.FreeBlocks[0] = u8(freespace1>>8); + bat.FreeBlocks[1] = u8(freespace1); + + // ... and update counter + int updateCtr = BE16(dir.UpdateCounter)+1; + dir.UpdateCounter[0] = u8(updateCtr>>8); + dir.UpdateCounter[1] = u8(updateCtr); + + //fix checksums + u16 csum1=0,csum2=0; + calc_checksumsBE((u16*)&dir,0xFFE,&csum1,&csum2); + dir.CheckSum1[0]=u8(csum1>>8); + dir.CheckSum1[1]=u8(csum1); + dir.CheckSum2[0]=u8(csum2>>8); + dir.CheckSum2[1]=u8(csum2); + calc_checksumsBE((u16*)(((u8*)&bat)+4),0xFFE,&csum1,&csum2); + bat.CheckSum1[0]=u8(csum1>>8); + bat.CheckSum1[1]=u8(csum1); + bat.CheckSum2[0]=u8(csum2>>8); + bat.CheckSum2[1]=u8(csum2); + + dir_backup=dir; + bat_backup=bat; + + return true; +} + +u32 GCMemcard::ImportFile(DEntry& direntry, u8* contents) +{ + if(!mcdFile) return 0; + + if(BE16(bat.FreeBlocks) firstFree1) firstFree1 = firstFree2; + if(firstFree3 > firstFree1) firstFree1 = firstFree3; + + if(firstFree1>=126) + { + // TODO: show messagebox about the error + return 0; + } + + // find first free dir entry + int index=-1; + for(int i=0;i<127;i++) + { + if(BE32(dir.Dir[i].Gamecode)==0xFFFFFFFF) + { + index=i; + dir.Dir[i] = direntry; + dir.Dir[i].FirstBlock[0] = u8(firstFree1>>8); + dir.Dir[i].FirstBlock[1] = u8(firstFree1); + dir.Dir[i].CopyCounter = dir.Dir[i].CopyCounter+1; + break; + } + } + + // keep assuming no freespace fragmentation, and copy over all the data + u8*destination = mc_data + (firstFree1-5)*0x2000; + + int fileBlocks=BE16(direntry.BlockCount); + memcpy(destination,contents,0x2000*fileBlocks); + + + //update freespace counter + int freespace1 = totalspace - firstFree1; + bat.FreeBlocks[0] = u8(freespace1>>8); + bat.FreeBlocks[1] = u8(freespace1); + + // ... and update counter + int updateCtr = BE16(dir.UpdateCounter)+1; + dir.UpdateCounter[0] = u8(updateCtr>>8); + dir.UpdateCounter[1] = u8(updateCtr); + + //fix checksums + u16 csum1=0,csum2=0; + calc_checksumsBE((u16*)&dir,0xFFE,&csum1,&csum2); + dir.CheckSum1[0]=u8(csum1>>8); + dir.CheckSum1[1]=u8(csum1); + dir.CheckSum2[0]=u8(csum2>>8); + dir.CheckSum2[1]=u8(csum2); + calc_checksumsBE((u16*)(((u8*)&bat)+4),0xFFE,&csum1,&csum2); + bat.CheckSum1[0]=u8(csum1>>8); + bat.CheckSum1[1]=u8(csum1); + bat.CheckSum2[0]=u8(csum2>>8); + bat.CheckSum2[1]=u8(csum2); + + return fileBlocks; +} + +bool GCMemcard::GetFileData(u32 index, u8*dest) //index in the directory array +{ + if(!mcdFile) return false; + + int block = BE16(dir.Dir[index].FirstBlock); + assert((block!=0xFFFF)&&(block>0)); + do + { + int nextblock=bswap16(bat.Map[block-5]); + assert(nextblock>0); + + memcpy(dest,mc_data + 0x2000*(block-5),0x2000); + dest+=0x2000; + + block=nextblock; + } + while(block!=0xffff); + + return true; +} + +u32 GCMemcard::GetFileSize(u32 index) //index in the directory array +{ + if(!mcdFile) return 0; + + return BE16(dir.Dir[index].BlockCount); +} + +bool GCMemcard::GetFileInfo(u32 index, GCMemcard::DEntry& info) //index in the directory array +{ + if(!mcdFile) return false; + + info = dir.Dir[index]; + return true; +} +bool GCMemcard::GetFileName(u32 index, char *fn) //index in the directory array +{ + if(!mcdFile) return false; + + memcpy(fn,(const char*)dir.Dir[index].Filename,32); + fn[31]=0; + return true; +} + +bool GCMemcard::GetComment1(u32 index, char *fn) //index in the directory array +{ + if(!mcdFile) return false; + + u32 Comment1 =BE32(dir.Dir[index].CommentsAddr); + u32 DataBlock =BE16(dir.Dir[index].FirstBlock)-5; + if(Comment1==0xFFFFFFFF) + { + fn[0]=0; + return false; + } + + memcpy(fn,mc_data +(DataBlock*0x2000) + Comment1,32); + fn[31]=0; + return true; +} + +bool GCMemcard::GetComment2(u32 index, char *fn) //index in the directory array +{ + if(!mcdFile) return false; + + u32 Comment1 =BE32(dir.Dir[index].CommentsAddr); + u32 Comment2 =Comment1+32; + u32 DataBlock =BE16(dir.Dir[index].FirstBlock)-5; + if(Comment1==0xFFFFFFFF) + { + fn[0]=0; + return false; + } + + memcpy(fn,mc_data +(DataBlock*0x2000) + Comment2,32); + fn[31]=0; + return true; +} + +u32 decode5A3(u16 val) +{ + const int lut5to8[] = { 0x00,0x08,0x10,0x18,0x20,0x29,0x31,0x39, + 0x41,0x4A,0x52,0x5A,0x62,0x6A,0x73,0x7B, + 0x83,0x8B,0x94,0x9C,0xA4,0xAC,0xB4,0xBD, + 0xC5,0xCD,0xD5,0xDE,0xE6,0xEE,0xF6,0xFF}; + const int lut4to8[] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77, + 0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF}; + const int lut3to8[] = { 0x00,0x24,0x48,0x6D,0x91,0xB6,0xDA,0xFF}; + + + int r,g,b,a; + if ((val&0x8000)) + { + r=lut5to8[(val>>10) & 0x1f]; + g=lut5to8[(val>>5 ) & 0x1f]; + b=lut5to8[(val ) & 0x1f]; + a=0xFF; + } + else + { + a=lut3to8[(val>>12) & 0x7]; + r=lut4to8[(val>>8 ) & 0xf]; + g=lut4to8[(val>>4 ) & 0xf]; + b=lut4to8[(val ) & 0xf]; + } + return (a<<24) | (r<<16) | (g<<8) | b; +} + +void decode5A3image(u32* dst, u16* src, int width, int height) +{ + for (int y = 0; y < height; y += 4) + { + for (int x = 0; x < width; x += 4) + { + for (int iy = 0; iy < 4; iy++, src += 4) + { + for (int ix = 0; ix < 4; ix++) + { + u32 RGBA = decode5A3(bswap16(src[ix])); + dst[(y + iy) * width + (x + ix)] = RGBA; + } + } + } + } +} + +void decodeCI8image(u32* dst, u8* src, u16* pal, int width, int height) +{ + for (int y = 0; y < height; y += 4) + { + for (int x = 0; x < width; x += 8) + { + for (int iy = 0; iy < 4; iy++, src += 8) + { + u32 *tdst = dst+(y+iy)*width+x; + for (int ix = 0; ix < 8; ix++) + { + tdst[ix] = decode5A3(bswap16(pal[src[ix]])); + } + } + } + } +} + +bool GCMemcard::ReadBannerRGBA8(u32 index, u32* buffer) +{ + if(!mcdFile) return false; + + int flags = dir.Dir[index].BIFlags; + + int bnrFormat = (flags&3); + + if(bnrFormat==0) + return false; + + u32 DataOffset=BE32(dir.Dir[index].ImageOffset); + u32 DataBlock =BE16(dir.Dir[index].FirstBlock)-5; + + if(DataOffset==0xFFFFFFFF) + { + return false; + } + + const int pixels = 96*32; + + if(bnrFormat&1) + { + u8 *pxdata = (u8* )(mc_data +(DataBlock*0x2000) + DataOffset); + u16 *paldata = (u16*)(mc_data +(DataBlock*0x2000) + DataOffset + pixels); + + decodeCI8image(buffer,pxdata,paldata,96,32); + } + else + { + u16 *pxdata = (u16*)(mc_data +(DataBlock*0x2000) + DataOffset); + + decode5A3image(buffer,pxdata,96,32); + } + return true; +} + +u32 GCMemcard::ReadAnimRGBA8(u32 index, u32* buffer, u8 *delays) +{ + if(!mcdFile) return 0; + + int formats = BE16(dir.Dir[index].IconFmt); + int fdelays = BE16(dir.Dir[index].AnimSpeed); + + int flags = dir.Dir[index].BIFlags; + + int bnrFormat = (flags&3); + + u32 DataOffset=BE32(dir.Dir[index].ImageOffset); + u32 DataBlock =BE16(dir.Dir[index].FirstBlock)-5; + + if(DataOffset==0xFFFFFFFF) + { + return 0; + } + + u8* animData=(u8*)(mc_data +(DataBlock*0x2000) + DataOffset); + + switch(bnrFormat) + { + case 1: + case 3: + animData+=96*32 + 2*256; // image+palette + break; + case 2: + animData+=96*32*2; + break; + } + + int fmts[8]; + u8* data[8]; + int frames = 0; + + + for(int i=0;i<8;i++) + { + fmts[i] = (formats>>(2*i))&3; + delays[i] = ((fdelays>>(2*i))&3)<<2; + data[i] = animData; + + switch(fmts[i]) + { + case 1: // CI8 with shared palette + animData+=32*32; + frames++; + break; + case 2: // RGB5A3 + animData+=32*32*2; + frames++; + break; + case 3: // CI8 with own palette + animData+=32*32 + 2*256; + frames++; + break; + } + } + + u16* sharedPal = (u16*)(animData); + + for(int i=0;i<8;i++) + { + switch(fmts[i]) + { + case 1: // CI8 with shared palette + decodeCI8image(buffer,data[i],sharedPal,32,32); + buffer+=32*32; + break; + case 2: // RGB5A3 + decode5A3image(buffer,(u16*)(data[i]),32,32); + break; + case 3: // CI8 with own palette + u16 *paldata = (u16*)(data[i]+32*32); + decodeCI8image(buffer,data[i],paldata,32,32); + buffer+=32*32; + break; + } + } + + return frames; +} + +u32 GCMemcard::TestChecksums() +{ + if(!mcdFile) return 0xFFFFFFFF; + + u16 csum1=0,csum2=0; + + u32 results = 0; + + calc_checksumsBE((u16*)&hdr, 0xFE ,&csum1,&csum2); + if(BE16(hdr.CheckSum1)!=csum1) results |= 1; + if(BE16(hdr.CheckSum2)!=csum2) results |= 1; + + calc_checksumsBE((u16*)&dir,0xFFE,&csum1,&csum2); + if(BE16(dir.CheckSum1)!=csum1) results |= 2; + if(BE16(dir.CheckSum2)!=csum2) results |= 2; + + calc_checksumsBE((u16*)&dir_backup,0xFFE,&csum1,&csum2); + if(BE16(dir_backup.CheckSum1)!=csum1) results |= 4; + if(BE16(dir_backup.CheckSum2)!=csum2) results |= 4; + + calc_checksumsBE((u16*)(((u8*)&bat)+4),0xFFE,&csum1,&csum2); + if(BE16(bat.CheckSum1)!=csum1) results |= 8; + if(BE16(bat.CheckSum2)!=csum2) results |= 8; + + calc_checksumsBE((u16*)(((u8*)&bat_backup)+4),0xFFE,&csum1,&csum2); + if(BE16(bat_backup.CheckSum1)!=csum1) results |= 16; + if(BE16(bat_backup.CheckSum2)!=csum2) results |= 16; + + return 0; +} + +u32 GCMemcard::CopyFrom(GCMemcard& source, u32 index) +{ + if(!mcdFile) return 0; + + DEntry d; + if(!source.GetFileInfo(index,d)) return 0; + + u8 *t = new u8[source.GetFileSize(index)*0x2000]; + + if(!source.GetFileData(index,t)) return 0; + u32 ret = ImportFile(d,t); + + delete[] t; + + return ret; +} + +bool GCMemcard::Save() +{ + if(!mcdFile) return false; + + FILE *mcd=(FILE*)mcdFile; + fseek(mcd,0,SEEK_SET); + fwrite(&hdr,1,0x2000,mcd); + fwrite(&dir,1,0x2000,mcd); + fwrite(&dir_backup,1,0x2000,mcd); + fwrite(&bat,1,0x2000,mcd); + fwrite(&bat_backup,1,0x2000,mcd); + fwrite(mc_data,1,mc_data_size,mcd); + return true; +} + +bool GCMemcard::IsOpen() +{ + return (mcdFile!=NULL); +} + +GCMemcard::GCMemcard(const char *filename) +{ + FILE *mcd=fopen(filename,"r+b"); + mcdFile=mcd; + if(!mcd) return; + + fseek(mcd,0x0000,SEEK_SET); + assert(fread(&hdr, 1,0x2000,mcd)==0x2000); + assert(fread(&dir, 1,0x2000,mcd)==0x2000); + assert(fread(&dir_backup,1,0x2000,mcd)==0x2000); + assert(fread(&bat, 1,0x2000,mcd)==0x2000); + assert(fread(&bat_backup,1,0x2000,mcd)==0x2000); + + u32 csums = TestChecksums(); + + if(csums&1) + { + // header checksum error! + // TODO: fail to load + } + + if(csums&2) // directory checksum error! + { + if(csums&4) + { + // backup is also wrong! + // TODO: fail to load + } + else + { + // backup is correct, restore + dir = dir_backup; + bat = bat_backup; + + // update checksums + csums = TestChecksums(); + } + } + + if(csums&8) // BAT checksum error! + { + if(csums&16) + { + // backup is also wrong! + // TODO: fail to load + } + else + { + // backup is correct, restore + dir = dir_backup; + bat = bat_backup; + + // update checksums + csums = TestChecksums(); + } + } + + if(BE16(dir_backup.UpdateCounter) > BE16(dir.UpdateCounter)) //check if the backup is newer + { + dir = dir_backup; + bat = bat_backup; // needed? + } + + fseek(mcd,0xa000,SEEK_SET); + + mc_data_size=(((u32)BE16(hdr.Size)*16)-5)*0x2000; + mc_data = new u8[mc_data_size]; + + u32 read = fread(mc_data,1,mc_data_size,mcd); + assert(mc_data_size==read); +} + +GCMemcard::~GCMemcard() +{ + fclose((FILE*)mcdFile); +} diff --git a/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h new file mode 100644 index 0000000000..e8527f9921 --- /dev/null +++ b/Source/Core/DolphinWX/Src/MemoryCards/GCMemcard.h @@ -0,0 +1,170 @@ +#pragma once + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; + +u16 __inline bswap16(u16 s) +{ + return (s>>8) | (s<<8); +} + +u32 __inline bswap32(u32 s) +{ + return (u32)bswap16((u16)(s>>16)) | ((u32)bswap16((u16)s)<<16); +} + +#ifndef max +template +T __inline max(T a, T b) +{ + return (b>a)?b:a; +} +#endif + +#define BE16(x) ((u16((x)[0])<<8) | u16((x)[1])) +#define BE32(x) ((u32((x)[0])<<24) | (u32((x)[1])<<16) | (u32((x)[2])<<8) | u32((x)[3])) + +class GCMemcard +{ + void* mcdFile; + + u32 mc_data_size; + u8* mc_data; + + void calc_checksumsBE(u16 *buf, u32 num, u16 *c1, u16 *c2); + +public: + +#pragma pack(push,1) + struct OSTime { + u32 low; + u32 high; + }; + + struct Header { //Offset Size Description + u8 Unk[12]; //0x0000 12 ? + OSTime fmtTime; //0x000c 8 time of format (OSTime value) + u8 UID[12]; //0x0014 12 unique card id (?) + u8 Pad1[2]; //0x0020 2 padding zeroes + u8 Size[2]; //0x0022 2 size of memcard in Mbits + u8 Encoding[2]; //0x0024 2 encoding (ASCII or japanese) + u8 Unused1[468]; //0x0026 468 unused (0xff) + u8 UpdateCounter[2];//0x01fa 2 update Counter (?, probably unused) + u8 CheckSum1[2]; //0x01fc 2 Checksum 1 (?) + u8 CheckSum2[2]; //0x01fe 2 Checksum 2 (?) + u8 Unused2[7680]; //0x0200 0x1e00 unused (0xff) + } hdr; + + struct DEntry { + u8 Gamecode[4]; //0x00 0x04 Gamecode + u8 Markercode[2]; //0x04 0x02 Makercode + u8 Unused1; //0x06 0x01 reserved/unused (always 0xff, has no effect) + u8 BIFlags; //0x07 0x01 banner gfx format and icon animation (Image Key) + // bit(s) description + // 2 Icon Animation 0: forward 1: ping-pong + // 1 [--0: No Banner 1: Banner present--] WRONG! YAGCD LIES! + // 0 [--Banner Color 0: RGB5A3 1: CI8--] WRONG! YAGCD LIES! + // bits 0 and 1: image format + // 00 no banner + // 01 CI8 banner + // 01 RGB5A3 banner + // 11 ? maybe ==01? haven't seen it + // + u8 Filename[32]; //0x08 0x20 filename + u8 ModTime[4]; //0x28 0x04 Time of file's last modification in seconds since 12am, January 1st, 2000 + u8 ImageOffset[4]; //0x2c 0x04 image data offset + u8 IconFmt[2]; //0x30 0x02 icon gfx format (2bits per icon) + // bits Description + // 00 no icon + // 01 CI8 with a shared color palette after the last frame + // 10 RGB5A3 + // 11 CI8 with a unique color palette after itself + // + u8 AnimSpeed[2]; //0x32 0x02 animation speed (2bits per icon) (*1) + // bits Description + // 00 no icon + // 01 Icon lasts for 4 frames + // 10 Icon lasts for 8 frames + // 11 Icon lasts for 12 frames + // + u8 Permissions; //0x34 0x01 file-permissions + // bit permission Description + // 4 no move File cannot be moved by the IPL + // 3 no copy File cannot be copied by the IPL + // 2 public Can be read by any game + // + u8 CopyCounter; //0x35 0x01 copy counter (*2) + u8 FirstBlock[2]; //0x36 0x02 block no of first block of file (0 == offset 0) + u8 BlockCount[2]; //0x38 0x02 file-length (number of blocks in file) + u8 Unused2[2]; //0x3a 0x02 reserved/unused (always 0xffff, has no effect) + u8 CommentsAddr[4]; //0x3c 0x04 Address of the two comments within the file data (*3) + }; + + struct Directory { + DEntry Dir[127]; //0x0000 Directory Entries (max 127) + u8 Padding[0x3a]; + u8 UpdateCounter[2];//0x1ffa 2 update Counter + u8 CheckSum1[2]; //0x1ffc 2 Checksum 1 + u8 CheckSum2[2]; //0x1ffe 2 Checksum 2 + } dir, dir_backup; + + struct BlockAlloc { + u8 CheckSum1[2]; //0x0000 2 Checksum 1 + u8 CheckSum2[2]; //0x0002 2 Checksum 2 + u8 UpdateCounter[2];//0x0004 2 update Counter + u8 FreeBlocks[2]; //0x0006 2 free Blocks + u8 LastAllocated[2];//0x0008 2 last allocated Block + u16 Map[0xFFB]; //0x000a 0x1ff8 Map of allocated Blocks + } bat,bat_backup; +#pragma pack(pop) + + // constructor + GCMemcard(const char* fileName); + + // destructor + ~GCMemcard(); + + bool IsOpen(); + + u32 TestChecksums(); + + // get number of file entries in the directory + u32 GetNumFiles(); + + // read directory entry + bool GetFileInfo(u32 index, DEntry& data); + + // buffer needs to be a char[32] or bigger + bool GetFileName(u32 index, char* buffer); + + // buffer needs to be a char[32] or bigger + bool GetComment1(u32 index, char* buffer); + + // buffer needs to be a char[32] or bigger + bool GetComment2(u32 index, char* buffer); + + // get file length un bytes + u32 GetFileSize(u32 index); + + // assumes there's enough space in buffer + bool GetFileData(u32 index, u8* buffer); + + // delete a file from the directory + bool RemoveFile(u32 index); + + // adds the file to the directory and copies its contents + u32 ImportFile(DEntry& direntry, u8* contents); + + // reads a save from another memcard, and imports the data into this memcard + u32 CopyFrom(GCMemcard& source, u32 index); + + // reads the banner image + bool ReadBannerRGBA8(u32 index, u32* buffer); + + // reads the animation frames + u32 ReadAnimRGBA8(u32 index, u32* buffer, u8 *delays); + + bool Save(); + +}; diff --git a/Source/Core/DolphinWX/Src/Params.ggo b/Source/Core/DolphinWX/Src/Params.ggo new file mode 100644 index 0000000000..2cf3dc6c3f --- /dev/null +++ b/Source/Core/DolphinWX/Src/Params.ggo @@ -0,0 +1,6 @@ +package "Dolphin" +version "SVN" +purpose "A multi platform gamecube/wii emulator" + +option "debug" d "enable debug" flag off + diff --git a/Source/Core/DolphinWX/Src/PluginManager.cpp b/Source/Core/DolphinWX/Src/PluginManager.cpp new file mode 100644 index 0000000000..c94a9fbc5b --- /dev/null +++ b/Source/Core/DolphinWX/Src/PluginManager.cpp @@ -0,0 +1,153 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include +#include + +#include "Globals.h" +#include "FileSearch.h" +#include "FileUtil.h" +#include "PluginManager.h" +#include "StringUtil.h" + +CPluginManager CPluginManager::m_Instance; + + +CPluginManager::CPluginManager() +{} + + +CPluginManager::~CPluginManager() +{} + + +void +CPluginManager::ScanForPlugins(wxWindow* _wxWindow) +{ + m_PluginInfos.clear(); + + CFileSearch::XStringVector Directories; + Directories.push_back(std::string("Plugins")); + + CFileSearch::XStringVector Extensions; +#ifdef _WIN32 + Extensions.push_back("*.dll"); +#else + Extensions.push_back("*.so"); +#endif + + CFileSearch FileSearch(Extensions, Directories); + const CFileSearch::XStringVector& rFilenames = FileSearch.GetFileNames(); + + if (rFilenames.size() > 0) + { + wxProgressDialog dialog(_T("Scanning for Plugins"), + _T("Scanning..."), + (int)rFilenames.size(), // range + _wxWindow, // parent + wxPD_CAN_ABORT | + wxPD_APP_MODAL | + // wxPD_AUTO_HIDE | -- try this as well + wxPD_ELAPSED_TIME | + wxPD_ESTIMATED_TIME | + wxPD_REMAINING_TIME | + wxPD_SMOOTH // - makes indeterminate mode bar on WinXP very small + ); + dialog.CenterOnParent(); + + for (size_t i = 0; i < rFilenames.size(); i++) + { + std::string orig_name = rFilenames[i]; + std::string FileName; + + if (!SplitPath(rFilenames[i], NULL, &FileName, NULL)) + { + printf("Bad Path %s\n", rFilenames[i].c_str()); + return; + } + + wxString msg; + char temp[128]; + sprintf(temp,"Scanning %s", FileName.c_str()); + msg = wxString::FromAscii(temp); + bool Cont = dialog.Update((int)i, msg); + + if (!Cont) + { + break; + } + + CPluginInfo PluginInfo(orig_name); + if (PluginInfo.IsValid()) + { + m_PluginInfos.push_back(PluginInfo); + } + } + } +} + + +void +CPluginManager::OpenAbout(void* _Parent, const std::string& _rFilename) +{ + if (Common::CPlugin::Load(_rFilename.c_str())) + { + Common::CPlugin::About((HWND)_Parent); + Common::CPlugin::Release(); + } +} + + +void +CPluginManager::OpenConfig(void* _Parent, const std::string& _rFilename) +{ + if (Common::CPlugin::Load(_rFilename.c_str())) + { + Common::CPlugin::Config((HWND)_Parent); + Common::CPlugin::Release(); + } +} + + +CPluginInfo::CPluginInfo(const std::string& _rFileName) + : m_FileName(_rFileName) + , m_Valid(false) +{ + if (Common::CPlugin::Load(_rFileName.c_str())) + { + if (Common::CPlugin::GetInfo(m_PluginInfo)) + { + m_Valid = true; + } + else + { + PanicAlert("Could not get info about plugin %s", _rFileName.c_str()); + } + + Common::CPlugin::Release(); + } + else + { + if (!File::Exists(_rFileName)) { + PanicAlert("Could not load plugin %s - file does not exist", _rFileName.c_str()); + } else { + PanicAlert("Failed to load plugin %s - unknown error.\n", _rFileName.c_str()); + } + } +} + + diff --git a/Source/Core/DolphinWX/Src/PluginManager.h b/Source/Core/DolphinWX/Src/PluginManager.h new file mode 100644 index 0000000000..d5aa42ca5c --- /dev/null +++ b/Source/Core/DolphinWX/Src/PluginManager.h @@ -0,0 +1,80 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef __PLUGIN_MANAGER_H_ +#define __PLUGIN_MANAGER_H_ + +#include "Plugin.h" + +class CPluginInfo +{ + public: + + CPluginInfo(const std::string& _rFileName); + + bool IsValid() const {return(m_Valid);} + + + const PLUGIN_INFO& GetPluginInfo() const {return(m_PluginInfo);} + + + const std::string& GetFileName() const {return(m_FileName);} + + + private: + + PLUGIN_INFO m_PluginInfo; + + std::string m_FileName; + + bool m_Valid; +}; + +typedef std::vectorCPluginInfos; + +class CPluginManager +{ + public: + + static CPluginManager& GetInstance() {return(m_Instance);} + + + void ScanForPlugins(wxWindow* _wxWindow); + + void OpenAbout(void* _Parent, const std::string& _rFilename); + + void OpenConfig(void* _Parent, const std::string& _rFilename); + + + const CPluginInfos& GetPluginInfos() {return(m_PluginInfos);} + + + private: + + static CPluginManager m_Instance; + + bool m_Initialized; + + CPluginInfos m_PluginInfos; + + CPluginManager(); + + ~CPluginManager(); +}; + + +#endif diff --git a/Source/Core/DolphinWX/Src/PluginOptions.cpp b/Source/Core/DolphinWX/Src/PluginOptions.cpp new file mode 100644 index 0000000000..a5c6126ed4 --- /dev/null +++ b/Source/Core/DolphinWX/Src/PluginOptions.cpp @@ -0,0 +1,283 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include +#include + +#include "Globals.h" + +#include "PluginOptions.h" +#include "PluginManager.h" + +#include "Config.h" + +BEGIN_EVENT_TABLE(CPluginOptions, wxDialog) + +EVT_CLOSE(CPluginOptions::OnClose) +EVT_BUTTON(ID_OK, CPluginOptions::OKClick) +EVT_BUTTON(ID_APPLY, CPluginOptions::OKClick) +EVT_BUTTON(ID_CANCEL, CPluginOptions::OKClick) +EVT_CHOICE(ID_PAD_CB, CPluginOptions::OnSelectionChanged) +EVT_CHOICE(ID_DSP_CB, CPluginOptions::OnSelectionChanged) +EVT_CHOICE(ID_GRAPHIC_CB, CPluginOptions::OnSelectionChanged) +EVT_BUTTON(ID_PAD_ABOUT, CPluginOptions::OnAbout) +EVT_BUTTON(ID_DSP_ABOUT, CPluginOptions::OnAbout) +EVT_BUTTON(ID_GRAPHIC_ABOUT, CPluginOptions::OnAbout) +EVT_BUTTON(ID_PAD_CONFIG, CPluginOptions::OnConfig) +EVT_BUTTON(ID_DSP_CONFIG, CPluginOptions::OnConfig) +EVT_BUTTON(ID_GRAPHIC_CONFIG, CPluginOptions::OnConfig) + +END_EVENT_TABLE() + + +CPluginOptions::CPluginOptions(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& position, const wxSize& size, long style) + : wxDialog(parent, id, title, position, size, style) +{ + CreateGUIControls(); +} + + +CPluginOptions::~CPluginOptions() +{} + + +void CPluginOptions::CreateGUIControls() +{ + OK = new wxButton(this, ID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + Cancel = new wxButton(this, ID_CANCEL, wxT("Cancel"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + Apply = new wxButton(this, ID_APPLY, wxT("Apply"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + Apply->Disable(); + + GraphicSelection = new wxChoice(this, ID_GRAPHIC_CB, wxDefaultPosition, wxDefaultSize, NULL, 0, wxDefaultValidator); + GraphicAbout = new wxButton(this, ID_GRAPHIC_ABOUT, wxT("About..."), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + GraphicConfig = new wxButton(this, ID_GRAPHIC_CONFIG, wxT("Config..."), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + GraphicText = new wxStaticText(this, ID_GRAPHIC_TEXT, wxT("GFX:"), wxDefaultPosition, wxDefaultSize); + + FillChoiceBox(GraphicSelection, PLUGIN_TYPE_VIDEO, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoPlugin); + + DSPSelection = new wxChoice(this, ID_DSP_CB, wxDefaultPosition, wxDefaultSize, NULL, 0, wxDefaultValidator); + DSPAbout = new wxButton(this, ID_DSP_ABOUT, wxT("About..."), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + DSPConfig = new wxButton(this, ID_DSP_CONFIG, wxT("Config..."), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + DSPText = new wxStaticText(this, ID_DSP_TEXT, wxT("DSP:"), wxDefaultPosition, wxDefaultSize); + + FillChoiceBox(DSPSelection, PLUGIN_TYPE_DSP, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin); + + PADSelection = new wxChoice(this, ID_PAD_CB, wxDefaultPosition, wxDefaultSize, NULL, 0, wxDefaultValidator); + PADAbout = new wxButton(this, ID_PAD_ABOUT, wxT("About..."), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + PADConfig = new wxButton(this, ID_PAD_CONFIG, wxT("Config..."), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); + PADText = new wxStaticText(this, ID_PAD_TEXT, wxT("PAD:"), wxDefaultPosition, wxDefaultSize); + + FillChoiceBox(PADSelection, PLUGIN_TYPE_PAD, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strPadPlugin); + + wxGridBagSizer* sConfig; + sConfig = new wxGridBagSizer(0, 0); + sConfig->SetFlexibleDirection(wxBOTH); + sConfig->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + sConfig->Add(GraphicText, wxGBPosition(0, 0), wxGBSpan(2, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5); + sConfig->Add(GraphicSelection, wxGBPosition(0, 1), wxGBSpan(1, 2), wxEXPAND|wxALL, 5); + sConfig->Add(GraphicConfig, wxGBPosition(0, 3), wxGBSpan(1, 1), wxALL, 5); + sConfig->Add(GraphicAbout, wxGBPosition(0, 4), wxGBSpan(1, 1), wxALL, 5); + + sConfig->Add(DSPText, wxGBPosition(2, 0), wxGBSpan(2, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5); + sConfig->Add(DSPSelection, wxGBPosition(2, 1), wxGBSpan(1, 2), wxEXPAND|wxALL, 5); + sConfig->Add(DSPConfig, wxGBPosition(2, 3), wxGBSpan(1, 1), wxALL, 5); + sConfig->Add(DSPAbout, wxGBPosition(2, 4), wxGBSpan(1, 1), wxALL, 5); + + sConfig->Add(PADText, wxGBPosition(4, 0), wxGBSpan(2, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5); + sConfig->Add(PADSelection, wxGBPosition(4, 1), wxGBSpan(1, 2), wxEXPAND|wxALL, 5); + sConfig->Add(PADConfig, wxGBPosition(4, 3), wxGBSpan(1, 1), wxALL, 5); + sConfig->Add(PADAbout, wxGBPosition(4, 4), wxGBSpan(1, 1), wxALL, 5); + sConfig->Layout(); + + wxBoxSizer* sButtons; + sButtons = new wxBoxSizer(wxHORIZONTAL); + sButtons->Add(0, 0, 1, wxEXPAND, 5); + sButtons->Add(OK, 0, wxALL, 5); + sButtons->Add(Cancel, 0, wxALL, 5); + sButtons->Add(Apply, 0, wxALL, 5); + + wxBoxSizer* sMain; + sMain = new wxBoxSizer(wxVERTICAL); + sMain->Add(sConfig, 1, wxEXPAND|wxALL, 5); + sMain->Add(sButtons, 0, wxEXPAND, 5); + + Center(); + this->SetSizer(sMain); + sMain->SetSizeHints(this); +} + + +void CPluginOptions::OnClose(wxCloseEvent& WXUNUSED (event)) +{ + Destroy(); +} + + +void CPluginOptions::OKClick(wxCommandEvent& event) +{ + switch (event.GetId()) + { + case ID_OK: + DoApply(); + Destroy(); + break; + + case ID_APPLY: + DoApply(); + break; + + case ID_CANCEL: + Destroy(); + break; + } +} + + +void CPluginOptions::OnSelectionChanged(wxCommandEvent& WXUNUSED (event)) +{ + Apply->Enable(); +} + + +void CPluginOptions::OnAbout(wxCommandEvent& event) +{ + switch (event.GetId()) + { + case ID_PAD_ABOUT: + CallAbout(PADSelection); + break; + + case ID_DSP_ABOUT: + CallAbout(DSPSelection); + break; + + case ID_GRAPHIC_ABOUT: + CallAbout(GraphicSelection); + break; + } +} + + +void CPluginOptions::OnConfig(wxCommandEvent& event) +{ + switch (event.GetId()) + { + case ID_PAD_CONFIG: + CallConfig(PADSelection); + break; + + case ID_DSP_CONFIG: + CallConfig(DSPSelection); + break; + + case ID_GRAPHIC_CONFIG: + CallConfig(GraphicSelection); + break; + } +} + + +void CPluginOptions::FillChoiceBox(wxChoice* _pChoice, int _PluginType, const std::string& _SelectFilename) +{ + _pChoice->Clear(); + + int Index = -1; + const CPluginInfos& rInfos = CPluginManager::GetInstance().GetPluginInfos(); + + for (size_t i = 0; i < rInfos.size(); i++) + { + const PLUGIN_INFO& rPluginInfo = rInfos[i].GetPluginInfo(); + + if (rPluginInfo.Type == _PluginType) + { + wxString temp; + temp = wxString::FromAscii(rInfos[i].GetPluginInfo().Name); + int NewIndex = _pChoice->Append(temp, (void*)&rInfos[i]); + + if (rInfos[i].GetFileName() == _SelectFilename) + { + Index = NewIndex; + } + } + } + + _pChoice->Select(Index); +} + + +void CPluginOptions::CallConfig(wxChoice* _pChoice) +{ + int Index = _pChoice->GetSelection(); + + if (Index >= 0) + { + const CPluginInfo* pInfo = static_cast(_pChoice->GetClientData(Index)); + + if (pInfo != NULL) + { + CPluginManager::GetInstance().OpenConfig((HWND) this->GetHandle(), pInfo->GetFileName()); + } + } +} + + +void CPluginOptions::CallAbout(wxChoice* _pChoice) +{ + int Index = _pChoice->GetSelection(); + + if (Index >= 0) + { + const CPluginInfo* pInfo = static_cast(_pChoice->GetClientData(Index)); + + if (pInfo != NULL) + { + CPluginManager::GetInstance().OpenAbout((HWND) this->GetHandle(), pInfo->GetFileName()); + } + } +} + + +void CPluginOptions::DoApply() +{ + Apply->Disable(); + + GetFilename(GraphicSelection, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoPlugin); + GetFilename(DSPSelection, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin); + GetFilename(PADSelection, SConfig::GetInstance().m_LocalCoreStartupParameter.m_strPadPlugin); + + SConfig::GetInstance().SaveSettings(); +} + + +bool CPluginOptions::GetFilename(wxChoice* _pChoice, std::string& _rFilename) +{ + _rFilename.clear(); + + int Index = _pChoice->GetSelection(); + printf("%i\n", Index); + + if (Index >= 0) + { + const CPluginInfo* pInfo = static_cast(_pChoice->GetClientData(Index)); + _rFilename = pInfo->GetFileName(); + printf("%s\n", _rFilename.c_str()); + return(true); + } + + return(false); +} + diff --git a/Source/Core/DolphinWX/Src/PluginOptions.h b/Source/Core/DolphinWX/Src/PluginOptions.h new file mode 100644 index 0000000000..553727794a --- /dev/null +++ b/Source/Core/DolphinWX/Src/PluginOptions.h @@ -0,0 +1,109 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef __PLUGIN_OPTIONS_h__ +#define __PLUGIN_OPTIONS_h__ + +#include + +#undef PLUGIN_OPTIONS_STYLE +#define PLUGIN_OPTIONS_STYLE wxCAPTION | wxSYSTEM_MENU | wxDIALOG_NO_PARENT | wxMINIMIZE_BOX | wxCLOSE_BOX + +class CPluginOptions + : public wxDialog +{ + private: + + DECLARE_EVENT_TABLE(); + + public: + + CPluginOptions(wxWindow* parent, wxWindowID id = 1, const wxString& title = wxT("Plugin Selection"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = PLUGIN_OPTIONS_STYLE); + virtual ~CPluginOptions(); + void OKClick(wxCommandEvent& event); + void OnSelectionChanged(wxCommandEvent& event); + void OnAbout(wxCommandEvent& event); + void OnConfig(wxCommandEvent& event); + + + private: + + //Do not add custom control declarations between + //GUI Control Declaration Start and GUI Control Declaration End. + //wxDev-C++ will remove them. Add custom code after the block. + ////GUI Control Declaration Start + wxButton* OK; + wxButton* Cancel; + wxButton* Apply; + wxStaticText* PADText; + wxButton* PADAbout; + wxButton* PADConfig; + wxChoice* PADSelection; + wxButton* DSPAbout; + wxButton* DSPConfig; + wxStaticText* DSPText; + wxChoice* DSPSelection; + wxButton* GraphicAbout; + wxButton* GraphicConfig; + wxStaticText* GraphicText; + wxChoice* GraphicSelection; + ////GUI Control Declaration End + + private: + + //Note: if you receive any error with these enum IDs, then you need to + //change your old form code that are based on the #define control IDs. + //#defines may replace a numeric value for the enum names. + //Try copy and pasting the below block in your old form header files. + enum + { + ////GUI Enum Control ID Start + ID_CANCEL = 1034, + ID_APPLY = 1033, + ID_OK = 1032, + ID_PAD_TEXT = 1031, + ID_PAD_ABOUT = 1030, + ID_PAD_CONFIG = 1029, + ID_PAD_CB = 1028, + ID_DSP_ABOUT = 1027, + ID_DSP_CONFIG = 1026, + ID_DSP_TEXT = 1025, + ID_DSP_CB = 1024, + ID_GRAPHIC_ABOUT = 1007, + ID_GRAPHIC_CONFIG = 1006, + ID_GRAPHIC_TEXT = 1005, + ID_GRAPHIC_CB = 1003, + ////GUI Enum Control ID End + ID_DUMMY_VALUE_ //don't remove this value unless you have other enum values + }; + + private: + + void OnClose(wxCloseEvent& event); + void CreateGUIControls(); + + void FillChoiceBox(wxChoice* _pChoice, int _PluginType, const std::string& _SelectFilename); + + void CallConfig(wxChoice* _pChoice); + void CallAbout(wxChoice* _pChoice); + + void DoApply(); + + bool GetFilename(wxChoice* _pChoice, std::string& _rFilename); +}; + +#endif diff --git a/Source/Core/DolphinWX/Src/SConscript b/Source/Core/DolphinWX/Src/SConscript new file mode 100644 index 0000000000..7fe12189a8 --- /dev/null +++ b/Source/Core/DolphinWX/Src/SConscript @@ -0,0 +1,69 @@ +Import('env') +import sys + +files = [ + 'BootManager.cpp', + 'Config.cpp', + 'FileSearch.cpp', + 'Frame.cpp', + 'GameListCtrl.cpp', + 'Globals.cpp', + 'ISOFile.cpp', + 'MemcardManager.cpp', + 'MemoryCards/GCMemcard.cpp', + 'PluginManager.cpp', + 'PluginOptions.cpp', + 'stdafx.cpp', + 'cmdline.c', + ] +libs = [ + 'debwx', 'core', 'discio', 'bdisasm', 'videocommon', 'common', 'z' + ] + +wxenv = env.Copy() +wxenv.Append( + CXXFLAGS = ' ' + ' '.join([ + '`wx-config --cppflags`', + '-DUSE_XPM_BITMAPS', + '-DwxNEEDS_CHARPP', + '`sdl-config --cflags`', + ]), + LINKFLAGS = ' ' + ' '.join([ + '-L/usr/local/lib', + '-pthread', + '`wx-config --libs`', + '`sdl-config --libs`' + ]) + ) + +if sys.platform == 'darwin': + exeGUI = '../../../../Binary/mac/Dolphin.app/Contents/MacOS/Dolphin' + exeNoGUI = '../../../../Binary/mac/DolphinNoGUI' + + icon = 'Dolphin' + version = 'svn' + wxenv.Plist( + '../../../../Binary/mac/Dolphin.app/Contents/Info.plist', + Value(dict( + CFAppleHelpAnchor = 'index', + CFBundleExecutable = 'Dolphin', + CFBundleGetInfoHTML = 'Dolphin ' + version, + CFBundleIconFile = icon, + CFBundleIdentifier = 'com.dolphin-emu.dolphin', + CFBundleName = 'Dolphin', + CFBundlePackageType = 'APPL', + CFBundleShortVersionString = version, + CFBundleSignature = 'dlfn', + CFBundleVersion = version, + LSRequiresCarbon = True, + NSPrefPaneIconFile = icon, + NSPrefPaneIconLabel = 'Dolphin', + )) + ) +else: + exeGUI = '../../../../Binary/linux/Dolphin' + exeNoGUI = '../../../../Binary/linux/DolphinNoGUI' + +objects = [ wxenv.Object(srcFile) for srcFile in files ] +wxenv.Program(exeGUI, objects + [ 'Main.cpp' ], LIBS = libs) +wxenv.Program(exeNoGUI, objects + [ 'MainNoGUI.cpp' ], LIBS = libs) diff --git a/Source/Core/DolphinWX/Src/cmdline.c b/Source/Core/DolphinWX/Src/cmdline.c new file mode 100644 index 0000000000..a72c623ed5 --- /dev/null +++ b/Source/Core/DolphinWX/Src/cmdline.c @@ -0,0 +1,365 @@ +/* + File autogenerated by gengetopt version 2.21 + generated with the following command: + gengetopt --unamed-opt=ISOFILE -i Params.ggo + + The developers of gengetopt consider the fixed text that goes in all + gengetopt output files to be in the public domain: + we make no copyright claims on it. +*/ + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "getopt.h" + +#include "cmdline.h" + +const char *gengetopt_args_info_purpose = "A multi platform gamecube/wii emulator"; + +const char *gengetopt_args_info_usage = "Usage: Dolphin [OPTIONS]... [ISOFILE]..."; + +const char *gengetopt_args_info_description = ""; + +const char *gengetopt_args_info_help[] = { + " -h, --help Print help and exit", + " -V, --version Print version and exit", + " -d, --debug enable debug (default=off)", + 0 +}; + +static +void clear_given (struct gengetopt_args_info *args_info); +static +void clear_args (struct gengetopt_args_info *args_info); + +static int +cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error); + + +static char * +gengetopt_strdup (const char *s); + +static +void clear_given (struct gengetopt_args_info *args_info) +{ + args_info->help_given = 0 ; + args_info->version_given = 0 ; + args_info->debug_given = 0 ; +} + +static +void clear_args (struct gengetopt_args_info *args_info) +{ + args_info->debug_flag = 0; + +} + +static +void init_args_info(struct gengetopt_args_info *args_info) +{ + args_info->help_help = gengetopt_args_info_help[0] ; + args_info->version_help = gengetopt_args_info_help[1] ; + args_info->debug_help = gengetopt_args_info_help[2] ; + +} + +void +cmdline_parser_print_version (void) +{ + printf ("%s %s\n", CMDLINE_PARSER_PACKAGE, CMDLINE_PARSER_VERSION); +} + +void +cmdline_parser_print_help (void) +{ + int i = 0; + cmdline_parser_print_version (); + + if (strlen(gengetopt_args_info_purpose) > 0) + printf("\n%s\n", gengetopt_args_info_purpose); + + printf("\n%s\n\n", gengetopt_args_info_usage); + + if (strlen(gengetopt_args_info_description) > 0) + printf("%s\n", gengetopt_args_info_description); + + while (gengetopt_args_info_help[i]) + printf("%s\n", gengetopt_args_info_help[i++]); +} + +void +cmdline_parser_init (struct gengetopt_args_info *args_info) +{ + clear_given (args_info); + clear_args (args_info); + init_args_info (args_info); + + args_info->inputs = NULL; + args_info->inputs_num = 0; +} + +struct cmdline_parser_params * +cmdline_parser_params_init() +{ + struct cmdline_parser_params *params = + (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params)); + + if (params) + { + params->override = 0; + params->initialize = 0; + params->check_required = 0; + params->check_ambiguity = 0; + } + + return params; +} + +static void +cmdline_parser_release (struct gengetopt_args_info *args_info) +{ + + unsigned int i; + + for (i = 0; i < args_info->inputs_num; ++i) + free (args_info->inputs [i]); + + if (args_info->inputs_num) + free (args_info->inputs); + + clear_given (args_info); +} + +int +cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info) +{ + FILE *outfile; + int i = 0; + + outfile = fopen(filename, "w"); + + if (!outfile) + { + fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename); + return EXIT_FAILURE; + } + + if (args_info->help_given) { + fprintf(outfile, "%s\n", "help"); + } + if (args_info->version_given) { + fprintf(outfile, "%s\n", "version"); + } + if (args_info->debug_given) { + fprintf(outfile, "%s\n", "debug"); + } + + fclose (outfile); + + i = EXIT_SUCCESS; + return i; +} + +void +cmdline_parser_free (struct gengetopt_args_info *args_info) +{ + cmdline_parser_release (args_info); +} + + +/* gengetopt_strdup() */ +/* strdup.c replacement of strdup, which is not standard */ +char * +gengetopt_strdup (const char *s) +{ + char *result = NULL; + if (!s) + return result; + + result = (char*)malloc(strlen(s) + 1); + if (result == (char*)0) + return (char*)0; + strcpy(result, s); + return result; +} + +int +cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info) +{ + return cmdline_parser2 (argc, argv, args_info, 0, 1, 1); +} + +int +cmdline_parser_ext (int argc, char * const *argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params) +{ + int result; + result = cmdline_parser_internal (argc, argv, args_info, params, NULL); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser2 (int argc, char * const *argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) +{ + int result; + struct cmdline_parser_params params; + + params.override = override; + params.initialize = initialize; + params.check_required = check_required; + params.check_ambiguity = 0; + + result = cmdline_parser_internal (argc, argv, args_info, ¶ms, NULL); + + if (result == EXIT_FAILURE) + { + cmdline_parser_free (args_info); + exit (EXIT_FAILURE); + } + + return result; +} + +int +cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name) +{ + return EXIT_SUCCESS; +} + +int +cmdline_parser_internal (int argc, char * const *argv, struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params, const char *additional_error) +{ + int c; /* Character of the parsed option. */ + + int error = 0; + struct gengetopt_args_info local_args_info; + + int override; + int initialize; + int check_required; + int check_ambiguity; + + override = params->override; + initialize = params->initialize; + check_required = params->check_required; + check_ambiguity = params->check_ambiguity; + + if (initialize) + cmdline_parser_init (args_info); + + cmdline_parser_init (&local_args_info); + + optarg = 0; + optind = 0; + opterr = 1; + optopt = '?'; + + while (1) + { + int option_index = 0; + char *stop_char; + + static struct option long_options[] = { + { "help", 0, NULL, 'h' }, + { "version", 0, NULL, 'V' }, + { "debug", 0, NULL, 'd' }, + { NULL, 0, NULL, 0 } + }; + + stop_char = 0; + c = getopt_long (argc, argv, "hVd", long_options, &option_index); + + if (c == -1) break; /* Exit from `while (1)' loop. */ + + switch (c) + { + case 'h': /* Print help and exit. */ + cmdline_parser_print_help (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 'V': /* Print version and exit. */ + cmdline_parser_print_version (); + cmdline_parser_free (&local_args_info); + exit (EXIT_SUCCESS); + + case 'd': /* enable debug. */ + if (local_args_info.debug_given || (check_ambiguity && args_info->debug_given)) + { + fprintf (stderr, "%s: `--debug' (`-d') option given more than once%s\n", argv[0], (additional_error ? additional_error : "")); + goto failure; + } + if (args_info->debug_given && ! override) + continue; + local_args_info.debug_given = 1; + args_info->debug_given = 1; + args_info->debug_flag = !(args_info->debug_flag); + break; + + + case 0: /* Long option with no short option */ + case '?': /* Invalid option. */ + /* `getopt_long' already printed an error message. */ + goto failure; + + default: /* bug: option not considered. */ + fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : "")); + abort (); + } /* switch */ + } /* while */ + + + + + cmdline_parser_release (&local_args_info); + + if ( error ) + return (EXIT_FAILURE); + + if (optind < argc) + { + int i = 0 ; + int found_prog_name = 0; + /* whether program name, i.e., argv[0], is in the remaining args + (this may happen with some implementations of getopt, + but surely not with the one included by gengetopt) */ + + i = optind; + while (i < argc) + if (argv[i++] == argv[0]) { + found_prog_name = 1; + break; + } + i = 0; + + args_info->inputs_num = argc - optind - found_prog_name; + args_info->inputs = + (char **)(malloc ((args_info->inputs_num)*sizeof(char *))) ; + while (optind < argc) + if (argv[optind++] != argv[0]) + args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind-1]) ; + } + + return 0; + +failure: + + cmdline_parser_release (&local_args_info); + return (EXIT_FAILURE); +} diff --git a/Source/Core/DolphinWX/Src/cmdline.h b/Source/Core/DolphinWX/Src/cmdline.h new file mode 100644 index 0000000000..b6440e41a9 --- /dev/null +++ b/Source/Core/DolphinWX/Src/cmdline.h @@ -0,0 +1,152 @@ +/** @file cmdline.h + * @brief The header file for the command line option parser + * generated by GNU Gengetopt version 2.21 + * http://www.gnu.org/software/gengetopt. + * DO NOT modify this file, since it can be overwritten + * @author GNU Gengetopt by Lorenzo Bettini */ + +#ifndef CMDLINE_H +#define CMDLINE_H + +/* If we use autoconf. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifndef CMDLINE_PARSER_PACKAGE +/** @brief the program name */ +#define CMDLINE_PARSER_PACKAGE "Dolphin" +#endif + +#ifndef CMDLINE_PARSER_VERSION +/** @brief the program version */ +#define CMDLINE_PARSER_VERSION "SVN" +#endif + +/** @brief Where the command line options are stored */ +struct gengetopt_args_info +{ + const char *help_help; /**< @brief Print help and exit help description. */ + const char *version_help; /**< @brief Print version and exit help description. */ + int debug_flag; /**< @brief enable debug (default=off). */ + const char *debug_help; /**< @brief enable debug help description. */ + + int help_given ; /**< @brief Whether help was given. */ + int version_given ; /**< @brief Whether version was given. */ + int debug_given ; /**< @brief Whether debug was given. */ + + char **inputs ; /**< @brief unamed options (options without names) */ + unsigned inputs_num ; /**< @brief unamed options number */ +} ; + +/** @brief The additional parameters to pass to parser functions */ +struct cmdline_parser_params +{ + int override; /**< @brief whether to override possibly already present options (default 0) */ + int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 0) */ + int check_required; /**< @brief whether to check that all required options were provided (default 0) */ + int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */ +} ; + +/** @brief the purpose string of the program */ +extern const char *gengetopt_args_info_purpose; +/** @brief the usage string of the program */ +extern const char *gengetopt_args_info_usage; +/** @brief all the lines making the help output */ +extern const char *gengetopt_args_info_help[]; + +/** + * The command line parser + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser (int argc, char * const *argv, + struct gengetopt_args_info *args_info); + +/** + * The command line parser (version with additional parameters - deprecated) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param override whether to override possibly already present options + * @param initialize whether to initialize the option structure my_args_info + * @param check_required whether to check that all required options were provided + * @return 0 if everything went fine, NON 0 if an error took place + * @deprecated use cmdline_parser_ext() instead + */ +int cmdline_parser2 (int argc, char * const *argv, + struct gengetopt_args_info *args_info, + int override, int initialize, int check_required); + +/** + * The command line parser (version with additional parameters) + * @param argc the number of command line options + * @param argv the command line options + * @param args_info the structure where option information will be stored + * @param params additional parameters for the parser + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_ext (int argc, char * const *argv, + struct gengetopt_args_info *args_info, + struct cmdline_parser_params *params); + +/** + * Save the contents of the option struct into a (text) file. + * This file can be read by the config file parser (if generated by gengetopt) + * @param filename the file where to save + * @param args_info the option struct to save + * @return 0 if everything went fine, NON 0 if an error took place + */ +int cmdline_parser_file_save(const char *filename, + struct gengetopt_args_info *args_info); + +/** + * Print the help + */ +void cmdline_parser_print_help(void); +/** + * Print the version + */ +void cmdline_parser_print_version(void); + +/** + * Allocates dynamically a cmdline_parser_params structure and initializes + * all its fields to 0 + * @return the initialized cmdline_parser_params structure + */ +struct cmdline_parser_params *cmdline_parser_params_init(); + +/** + * Initializes the passed gengetopt_args_info structure's fields + * (also set default values for options that have a default) + * @param args_info the structure to initialize + */ +void cmdline_parser_init (struct gengetopt_args_info *args_info); +/** + * Deallocates the string fields of the gengetopt_args_info structure + * (but does not deallocate the structure itself) + * @param args_info the structure to deallocate + */ +void cmdline_parser_free (struct gengetopt_args_info *args_info); + +/** + * Checks that all the required options were specified + * @param args_info the structure to check + * @param prog_name the name of the program that will be used to print + * possible errors + * @return + */ +int cmdline_parser_required (struct gengetopt_args_info *args_info, + const char *prog_name); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* CMDLINE_H */ diff --git a/Source/Core/DolphinWX/Src/stdafx.cpp b/Source/Core/DolphinWX/Src/stdafx.cpp new file mode 100644 index 0000000000..428bdfaf8b --- /dev/null +++ b/Source/Core/DolphinWX/Src/stdafx.cpp @@ -0,0 +1,18 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "stdafx.h" diff --git a/Source/Core/DolphinWX/Src/stdafx.h b/Source/Core/DolphinWX/Src/stdafx.h new file mode 100644 index 0000000000..78628c0281 --- /dev/null +++ b/Source/Core/DolphinWX/Src/stdafx.h @@ -0,0 +1,50 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef __STDAFX_H_ +#define __STDAFX_H_ + +#ifdef _WIN32 + +// Change these values to use different versions +#define WINVER 0x0400 +#define _WIN32_WINNT 0x0501 +#define _WIN32_IE 0x0500 +#define _RICHEDIT_VER 0x0100 + + +#if defined _M_IX86 + +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") + +#elif defined _M_IA64 + +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"") + +#elif defined _M_X64 + +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") + +#else + +#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") + +#endif + +#endif + +#endif