Interface and general: Fixed the hangings and crashes that would occur from repeated Start and Stop, added optional toolbar themes, made the fullscreen mode in the OpenGL plugin more user friendly for Windows users

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1770 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
John Peterson
2009-01-04 21:53:41 +00:00
parent 1ed27a4fc1
commit eb2ce16a6c
31 changed files with 11580 additions and 1104 deletions

View File

@ -142,10 +142,16 @@ void UpdateFPSDisplay(const char *text)
OpenGL_SetWindowText(temp);
}
// =======================================================================================
// Create window. Called from main.cpp
// Create rendering window.
// Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize()
// ------------------
bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight)
{
// --------------------------------------------
// Check for fullscreen mode
// ---------------
int _twidth, _theight;
if (g_Config.bFullscreen)
{
@ -171,9 +177,12 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
_theight = _iheight;
}
}
#if defined(_WIN32)
EmuWindow::SetSize(_twidth, _theight);
#endif
#if defined(_WIN32)
EmuWindow::SetSize(_twidth, _theight);
#endif
// ----------------------------
// ---------------------------------------------------------------------------------------
// Control window size and picture scaling
@ -247,8 +256,14 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
GLWin.glCanvas->SetCurrent(*GLWin.glCtxt);
// GLWin.glCtxt->SetCurrent(*GLWin.glCanvas);
#elif defined(_WIN32)
// create the window
// ---------------------------------------------------------------------------------------
// Create rendering window in Windows
// ----------------------
// Create the window
if (!g_Config.renderToMainframe || g_VideoInitialize.pWindowHandle == NULL)
{
g_VideoInitialize.pWindowHandle = (void*)EmuWindow::Create(NULL, g_hInstance, "Please wait...");
@ -257,6 +272,8 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
{
g_VideoInitialize.pWindowHandle = (void*)EmuWindow::Create((HWND)g_VideoInitialize.pWindowHandle, g_hInstance, "Please wait...");
}
// Show the window
EmuWindow::Show();
if (g_VideoInitialize.pWindowHandle == NULL)
@ -359,6 +376,7 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
MessageBox(NULL,"(4) Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return false;
}
// --------------------------------------
#elif defined(HAVE_X11) && HAVE_X11
XVisualInfo *vi;

View File

@ -36,7 +36,6 @@ BEGIN_EVENT_TABLE(ConfigDialog,wxDialog)
EVT_CHECKBOX(ID_FORCEFILTERING, ConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(ID_STRETCHTOFIT, ConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(ID_KEEPAR, ConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(ID_HIDECURSOR, ConfigDialog::GeneralSettingsChanged)
EVT_CHECKBOX(ID_WIREFRAME, ConfigDialog::AdvancedSettingsChanged)
EVT_CHECKBOX(ID_SHOWFPS, ConfigDialog::AdvancedSettingsChanged)
EVT_CHECKBOX(ID_STATISTICS, ConfigDialog::AdvancedSettingsChanged)
@ -109,8 +108,6 @@ void ConfigDialog::CreateGUIControls()
m_StretchToFit->SetValue(g_Config.bStretchToFit);
m_KeepAR = new wxCheckBox(m_PageGeneral, ID_KEEPAR, wxT("Keep 4:3 aspect ratio"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_KeepAR->SetValue(g_Config.bKeepAR);
m_HideCursor = new wxCheckBox(m_PageGeneral, ID_HIDECURSOR, wxT("Hide mouse cursor"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_HideCursor->SetValue(g_Config.bHideCursor);
wxStaticText *FSText = new wxStaticText(m_PageGeneral, ID_FSTEXT, wxT("Fullscreen video mode:"), wxDefaultPosition, wxDefaultSize, 0);
m_FullscreenCB = new wxComboBox(m_PageGeneral, ID_FULLSCREENCB, wxEmptyString, wxDefaultPosition, wxDefaultSize, arrayStringFor_FullscreenCB, 0, wxDefaultValidator);
@ -152,13 +149,12 @@ void ConfigDialog::CreateGUIControls()
sBasic->Add(m_RenderToMainWindow, wxGBPosition(1, 0), wxGBSpan(1, 2), wxALL, 5);
sBasic->Add(m_StretchToFit, wxGBPosition(2, 0), wxGBSpan(1, 2), wxALL, 5);
sBasic->Add(m_KeepAR, wxGBPosition(3, 0), wxGBSpan(1, 2), wxALL, 5);
sBasic->Add(m_HideCursor, wxGBPosition(4, 0), wxGBSpan(1, 2), wxALL, 5);
sBasic->Add(FSText, wxGBPosition(5, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
sBasic->Add(m_FullscreenCB, wxGBPosition(5, 1), wxGBSpan(1, 1), wxALL, 5);
sBasic->Add(WMText, wxGBPosition(6, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
sBasic->Add(m_WindowResolutionCB, wxGBPosition(6, 1), wxGBSpan(1, 1), wxALL, 5);
sBasic->Add(BEText, wxGBPosition(7, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
sBasic->Add(m_RenderBackend, wxGBPosition(7, 1), wxGBSpan(1, 1), wxALL, 5);
sBasic->Add(FSText, wxGBPosition(4, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
sBasic->Add(m_FullscreenCB, wxGBPosition(4, 1), wxGBSpan(1, 1), wxALL, 5);
sBasic->Add(WMText, wxGBPosition(5, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
sBasic->Add(m_WindowResolutionCB, wxGBPosition(5, 1), wxGBSpan(1, 1), wxALL, 5);
sBasic->Add(BEText, wxGBPosition(6, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
sBasic->Add(m_RenderBackend, wxGBPosition(6, 1), wxGBSpan(1, 1), wxALL, 5);
sbBasic->Add(sBasic);
sGeneral->Add(sbBasic, 0, wxEXPAND|wxALL, 5);
@ -219,7 +215,7 @@ void ConfigDialog::CreateGUIControls()
m_EFBToTextureDisable->Enable(true);
m_EFBToTextureDisable->SetValue(g_Config.bEFBToTextureDisable);
m_EFBToTextureDisableHotKey = new wxCheckBox(m_PageAdvanced,
ID_EFBTOTEXTUREDISABLEHOTKEY, wxT("with hotkey E"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
ID_EFBTOTEXTUREDISABLEHOTKEY, wxT("With hotkey E"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_EFBToTextureDisableHotKey->SetToolTip(wxT("Use the E key to turn this option on and off"));
#ifndef _WIN32
// JPeterson set the hot key to be Win32-specific
@ -341,9 +337,6 @@ void ConfigDialog::GeneralSettingsChanged(wxCommandEvent& event)
case ID_KEEPAR:
g_Config.bKeepAR = m_KeepAR->IsChecked();
break;
case ID_HIDECURSOR:
g_Config.bHideCursor = m_HideCursor->IsChecked();
break;
case ID_FULLSCREENCB:
strcpy(g_Config.iFSResolution, m_FullscreenCB->GetValue().mb_str() );
break;

View File

@ -72,7 +72,6 @@ class ConfigDialog : public wxDialog
wxCheckBox *m_RenderToMainWindow;
wxCheckBox *m_StretchToFit;
wxCheckBox *m_KeepAR;
wxCheckBox *m_HideCursor;
wxArrayString arrayStringFor_FullscreenCB;
wxComboBox *m_FullscreenCB;
wxArrayString arrayStringFor_WindowResolutionCB;

View File

@ -16,6 +16,10 @@
// http://code.google.com/p/dolphin-emu/
//////////////////////////////////////////////////////////////////////////////////////////
// Include
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include <windows.h>
#include <wx/wx.h>
@ -24,15 +28,19 @@
#include <wx/dialog.h>
#include <wx/aboutdlg.h>
#include "../Globals.h"
#include "../Globals.h" // Local
#include "../Config.h"
#include "main.h"
#include "Win32.h"
#include "Render.h" // for AddMessage
#include "StringUtil.h" // for StringFromFormat
#include "StringUtil.h" // Common: For StringFromFormat
//////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Declarations and definitions
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void OpenConsole();
void CloseConsole();
@ -81,14 +89,23 @@ BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle
void DoDllDebugger();
extern bool gShowDebugger;
//////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// The rendering window
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
namespace EmuWindow
{
HWND m_hWnd = NULL;
HWND m_hParent = NULL;
HWND m_hWnd = NULL; // The new window that is created here
HWND m_hParent = NULL, m_hMain = NULL; // The main CPanel
HINSTANCE m_hInstance = NULL;
WNDCLASSEX wndClass;
const TCHAR m_szClassName[] = "DolphinEmuWnd";
int g_winstyle;
// ------------------------------------------
/* Invisible cursor option. In the lack of a predefined IDC_BLANK we make
@ -116,11 +133,15 @@ namespace EmuWindow
}
LRESULT CALLBACK WndProc( HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam )
{
{
HDC hdc;
PAINTSTRUCT ps;
switch( iMsg )
{
case WM_CREATE:
PostMessage(m_hMain, WM_USER, 15, (int)m_hParent); // 15 = WM_USER_CREATE, make enum table if it's confusing
break;
case WM_PAINT:
hdc = BeginPaint( hWnd, &ps );
EndPaint( hWnd, &ps );
@ -129,12 +150,26 @@ namespace EmuWindow
case WM_KEYDOWN:
switch( LOWORD( wParam ))
{
case VK_ESCAPE: /* Pressing esc quits */
case VK_ESCAPE: // Pressing Esc Stop or Maximize
//DestroyWindow(hWnd);
//PostQuitMessage(0);
/* The fullscreen option for Windows users is not very user friendly. With this the user
can only get out of the fullscreen mode by pressing Esc or Alt + F4. But that also
closes*/
//if(m_hParent == NULL) ExitProcess(0);
if(m_hParent == NULL)
{
if (g_Config.bFullscreen)
PostMessage(m_hMain, WM_USER, 5, 0); // Stop
else
// Toggle maximize and restore
if (IsZoomed(hWnd)) ShowWindow(hWnd, SW_RESTORE); else ShowWindow(hWnd, SW_MAXIMIZE);
return 0;
}
break;
/*
case MY_KEYS:
case MY_KEYS:
hypotheticalScene->sendMessage(KEYDOWN...);
*/
case 'E': // EFB hotkey
@ -155,23 +190,65 @@ namespace EmuWindow
because SetCursor is not supposed to actually change the cursor if it's the
same as the one before. */
case WM_MOUSEMOVE:
if(g_Config.bHideCursor)
SetCursor(hCursorBlank);
/* Check rendering mode; child or parent. Then post the mouse moves to the main window
it's nessesary for both the chil dwindow and separate rendering window because
moves over the rendering window do not reach the main program then. */
if (GetParentWnd() == NULL) // Separate rendering window
PostMessage(m_hMain, iMsg, wParam, -1);
else
SetCursor(hCursor);
PostMessage(GetParentWnd(), iMsg, wParam, lParam);
break;
case WM_CLOSE:
ExitProcess(0);
/* To support the separate window rendering we get the message back here. So we basically
only let it pass through DolphinWX > Frame.cpp to determine if it should be on or off
and coordinate it with the other settings if nessesary */
case WM_USER:
/* I set wParam to 10 just in case there are other WM_USER events. If we want more
WM_USER cases we would start making wParam or lParam cases */
if(wParam == 10)
{
if(lParam)
SetCursor(hCursor);
else
SetCursor(hCursorBlank);
}
break;
//Core::SetState(Core::CORE_UNINITIALIZED);
return 0;
/* Post thes mouse events to the main window, it's nessesary becase in difference to the
keyboard inputs these events only appear here, not in the main WndProc() */
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_LBUTTONDBLCLK:
PostMessage(GetParentWnd(), iMsg, wParam, lParam);
break;
// This is called when we close the window when we render to a separate window
case WM_CLOSE:
if(m_hParent == NULL)
{
ExitProcess(0);
//Core::SetState(Core::CORE_UNINITIALIZED);
/* Attempt to only Stop when we close the separate window. But it didn't work, it hanged.
It may need some more coordination with the Stop code in the Core */
//PostMessage(m_hMain, WM_USER, 5, 0);
return 0;
}
/* This is called from the Core when we Stop, but currently we only use DefWindowProc(),
whatever that does with it, if any */
//case WM_QUIT:
//Video_Shutdown();
// ExitProcess(0);
// return 0;
case WM_DESTROY:
//Shutdown();
//PostQuitMessage( 0 );
//PostQuitMessage( 0 ); // Call WM_QUIT
break;
// Called when a screensaver wants to show up while this window is active
case WM_SYSCOMMAND:
switch (wParam)
{
@ -186,6 +263,7 @@ namespace EmuWindow
}
// This is called from
HWND OpenWindow(HWND parent, HINSTANCE hInstance, int width, int height, const TCHAR *title)
{
wndClass.cbSize = sizeof( wndClass );
@ -196,7 +274,7 @@ namespace EmuWindow
wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
//wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
wndClass.hCursor = NULL; // to interfer less with SetCursor() later
wndClass.hCursor = NULL; // To interfer less with SetCursor() later
wndClass.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = m_szClassName;
@ -207,17 +285,20 @@ namespace EmuWindow
CreateCursors(m_hInstance);
// Create child window
if (parent)
{
m_hParent = m_hMain = parent;
m_hWnd = CreateWindow(m_szClassName, title,
WS_CHILD,
CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,
parent, NULL, hInstance, NULL );
m_hParent = parent;
ShowWindow(m_hWnd, SW_SHOWMAXIMIZED);
}
// Create new separate window
else
{
DWORD style = g_Config.bFullscreen ? WS_POPUP : WS_OVERLAPPEDWINDOW;
@ -233,6 +314,8 @@ namespace EmuWindow
rc.top = (1024 - h)/2;
rc.bottom = rc.top + h;
// I save this to m_hMain instead of m_hParent because it casused problems otherwise
m_hMain = (HWND)g_VideoInitialize.pWindowHandle;
m_hWnd = CreateWindow(m_szClassName, title,
style,
@ -241,7 +324,6 @@ namespace EmuWindow
g_winstyle = GetWindowLong( m_hWnd, GWL_STYLE );
g_winstyle &= ~WS_MAXIMIZE & ~WS_MINIMIZE; // remove minimize/maximize style
}
return m_hWnd;
@ -290,4 +372,6 @@ namespace EmuWindow
rc.bottom = rc.top + h;
::MoveWindow(m_hWnd, rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top, TRUE);
}
}
} // EmuWindow
////////////////////////////////////

View File

@ -55,7 +55,9 @@ SVideoInitialize g_VideoInitialize;
if the OpenGL plugin was loaded before. I'll try to fix that. Currently you may have to
clsoe the window if it has auto started, and then restart it after the dll has loaded
for the purpose of the game. At that point there is no need to use the same dll instance
as the one that is rendering the game. However, that could be done. */
as the one that is rendering the game. However, that could be done.
Update: This crash seems to be gone for now. */
#if defined(HAVE_WX) && HAVE_WX
CDebugger* m_frame;
@ -195,36 +197,43 @@ void DllConfig(HWND _hParent)
#endif
}
//////////////////////////////////////////////////////////////////////////////////////////
// Initialize video
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void Video_Initialize(SVideoInitialize* _pVideoInitialize)
{
if (_pVideoInitialize == NULL)
return;
// When will this happen?
if (_pVideoInitialize == NULL) return;
#ifdef _WIN32
// OpenConsole();
#endif
/* Dolphin currently crashes if the dll is loaded when a game is started so we clsoe the
debugger and open it again after loading */
// --------------------------------------------------
/* Dolphin currently crashes if the dll is loaded when a game is started so we close the
debugger and open it again after loading
Status: Currently it's working so no need for this */
/*
if(m_frame)
{
m_frame->EndModal(0); wxEntryCleanup();
}//use wxUninitialize() if you don't want GUI
*/
// --------------------------------------------------
frameCount = 0;
g_VideoInitialize = *_pVideoInitialize;
g_VideoInitialize = *_pVideoInitialize; // Create a shortcut to _pVideoInitialize that can also update it
InitLUTs();
InitXFBConvTables();
g_Config.Load();
if (!OpenGL_Create(g_VideoInitialize, 640, 480)) { //640x480 will be the default if all else fails//
if (!OpenGL_Create(g_VideoInitialize, 640, 480)) // 640x480 will be the default if all else fails
{
g_VideoInitialize.pLog("Renderer::Create failed\n", TRUE);
return;
}
_pVideoInitialize->pPeekMessages = g_VideoInitialize.pPeekMessages;
_pVideoInitialize->pUpdateFPSDisplay = g_VideoInitialize.pUpdateFPSDisplay;
// Now the window handle is written
_pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle;
Renderer::AddMessage("Dolphin OpenGL Video Plugin" ,5000);