2014-01-04 11:33:02 +00:00
// Copyright (c) 2012- PPSSPP Project.
2013-07-29 09:23:27 +00:00
// 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 or later versions.
// 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 git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
2012-11-01 15:19:01 +00:00
// NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003.
2013-07-29 09:23:27 +00:00
// It's improving slowly, though. :)
2012-11-01 15:19:01 +00:00
2013-07-29 04:01:49 +00:00
# include "Common/CommonWindows.h"
2014-06-04 16:15:41 +00:00
# include "Common/KeyMap.h"
2013-03-29 17:50:08 +00:00
2013-07-06 19:49:28 +00:00
# include <map>
2013-09-01 21:06:24 +00:00
# include <string>
2013-07-06 19:49:28 +00:00
2013-03-29 17:50:08 +00:00
# include "base/NativeApp.h"
2013-03-11 21:55:29 +00:00
# include "Globals.h"
2012-11-01 15:19:01 +00:00
# include "shellapi.h"
# include "commctrl.h"
2013-08-26 17:00:16 +00:00
# include "i18n/i18n.h"
2013-03-29 17:50:08 +00:00
# include "input/input_state.h"
2013-07-08 10:35:08 +00:00
# include "input/keycodes.h"
2014-06-29 10:53:03 +00:00
# include "thread/threadutil.h"
2013-08-26 17:00:16 +00:00
# include "util/text/utf8.h"
2013-03-11 21:55:29 +00:00
# include "Core/Debugger/SymbolMap.h"
2014-01-02 00:45:37 +00:00
# include "Windows/InputBox.h"
2013-03-11 21:55:29 +00:00
# include "Windows/OpenGLBase.h"
# include "Windows/Debugger/Debugger_Disasm.h"
# include "Windows/Debugger/Debugger_MemoryDlg.h"
2013-09-22 18:03:29 +00:00
# include "Windows/GEDebugger/GEDebugger.h"
2012-11-01 15:19:01 +00:00
# include "main.h"
2013-03-11 21:55:29 +00:00
# include "Core/Core.h"
# include "Core/MemMap.h"
# include "Core/SaveState.h"
# include "Core/System.h"
# include "Core/Config.h"
2014-12-12 23:09:37 +00:00
# include "Core/MIPS/JitCommon/NativeJit.h"
2013-12-01 02:21:47 +00:00
# include "Core/MIPS/JitCommon/JitBlockCache.h"
2014-01-02 00:45:37 +00:00
# include "Core/FileSystems/MetaFileSystem.h"
2013-03-11 21:55:29 +00:00
# include "Windows/EmuThread.h"
2012-11-01 15:19:01 +00:00
# include "resource.h"
2013-03-11 21:55:29 +00:00
# include "Windows/WndMainWindow.h"
2013-07-06 17:08:59 +00:00
# include "Windows/WindowsHost.h"
2013-03-11 21:55:29 +00:00
# include "Common/LogManager.h"
# include "Common/ConsoleListener.h"
# include "Windows/W32Util/DialogManager.h"
# include "Windows/W32Util/ShellUtil.h"
# include "Windows/W32Util/Misc.h"
2014-01-19 19:59:11 +00:00
# include "Windows/RawInput.h"
2014-01-19 21:54:49 +00:00
# include "Windows/TouchInputHandler.h"
2013-03-11 21:55:29 +00:00
# include "GPU/GPUInterface.h"
# include "GPU/GPUState.h"
2014-01-20 05:14:21 +00:00
# include "gfx_es2/gpu_features.h"
2015-01-22 18:53:32 +00:00
# include "GPU/GLES/TextureScaler.h"
2013-07-29 08:46:40 +00:00
# include "GPU/GLES/TextureCache.h"
# include "GPU/GLES/Framebuffer.h"
2013-05-22 16:00:06 +00:00
# include "UI/OnScreenDisplay.h"
2013-10-12 04:14:58 +00:00
# include "GPU/Common/PostShader.h"
2012-11-01 15:19:01 +00:00
2013-11-27 13:57:17 +00:00
# include "Core/HLE/sceUmd.h"
2012-11-01 15:19:01 +00:00
# ifdef THEMES
# include "XPTheme.h"
# endif
2014-02-24 12:28:20 +00:00
# define MOUSEEVENTF_FROMTOUCH_NOPEN 0xFF515780 //http://msdn.microsoft.com/en-us/library/windows/desktop/ms703320(v=vs.85).aspx
# define MOUSEEVENTF_MASK_PLUS_PENTOUCH 0xFFFFFF80
2014-01-23 17:05:42 +00:00
2013-12-29 23:55:09 +00:00
static const int numCPUs = 1 ;
2013-12-01 02:21:47 +00:00
int verysleepy__useSendMessage = 1 ;
const UINT WM_VERYSLEEPY_MSG = WM_APP + 0x3117 ;
// Respond TRUE to a message with this param value to indicate support.
const WPARAM VERYSLEEPY_WPARAM_SUPPORTED = 0 ;
// Respond TRUE to a message wit this param value after filling in the addr name.
const WPARAM VERYSLEEPY_WPARAM_GETADDRINFO = 1 ;
2014-06-29 20:13:53 +00:00
struct VerySleepy_AddrInfo
{
2013-12-01 02:21:47 +00:00
// Always zero for now.
int flags ;
// This is the pointer (always passed as 64 bits.)
unsigned long long addr ;
// Write the name here.
wchar_t name [ 256 ] ;
} ;
2013-07-06 19:49:28 +00:00
extern std : : map < int , int > windowsTransTable ;
2013-03-29 20:21:27 +00:00
static RECT g_normalRC = { 0 } ;
2013-09-13 19:17:55 +00:00
static std : : wstring windowTitle ;
2013-06-22 20:27:59 +00:00
extern bool g_TakeScreenshot ;
2013-03-29 17:50:08 +00:00
extern InputState input_state ;
2013-07-07 08:42:39 +00:00
2013-05-04 21:21:06 +00:00
# define TIMER_CURSORUPDATE 1
2013-06-11 18:14:53 +00:00
# define TIMER_CURSORMOVEUPDATE 2
2013-10-16 15:20:32 +00:00
# define CURSORUPDATE_INTERVAL_MS 1000
2013-06-11 18:14:53 +00:00
# define CURSORUPDATE_MOVE_TIMESPAN_MS 500
2013-04-18 09:13:00 +00:00
2014-06-29 20:13:53 +00:00
namespace MainWindow
{
2012-11-01 15:19:01 +00:00
HWND hwndMain ;
2014-06-29 20:13:53 +00:00
HWND hwndDisplay ;
HWND hwndGameList ;
2014-01-19 21:54:49 +00:00
TouchInputHandler touchHandler ;
2013-03-29 20:21:27 +00:00
static HMENU menu ;
2012-11-01 15:19:01 +00:00
2013-03-29 20:21:27 +00:00
static HINSTANCE hInst ;
2013-05-26 21:55:23 +00:00
static int cursorCounter = 0 ;
2013-06-11 18:14:53 +00:00
static int prevCursorX = - 1 ;
static int prevCursorY = - 1 ;
static bool mouseButtonDown = false ;
static bool hideCursor = false ;
2013-09-01 21:06:24 +00:00
static std : : map < int , std : : string > initialMenuKeys ;
2013-09-04 02:06:05 +00:00
static std : : vector < std : : string > countryCodes ;
2013-10-12 04:14:58 +00:00
static std : : vector < std : : string > availableShaders ;
2014-01-20 02:44:41 +00:00
static W32Util : : AsyncBrowseDialog * browseDialog ;
static bool browsePauseAfter ;
2014-06-29 19:03:24 +00:00
static bool g_inModeSwitch ; // when true, don't react to WM_SIZE
2014-07-29 22:18:57 +00:00
static int g_WindowState ;
2014-06-29 19:03:24 +00:00
2012-11-01 15:19:01 +00:00
# define MAX_LOADSTRING 100
2013-03-29 20:21:27 +00:00
const TCHAR * szTitle = TEXT ( " PPSSPP " ) ;
const TCHAR * szWindowClass = TEXT ( " PPSSPPWnd " ) ;
const TCHAR * szDisplayClass = TEXT ( " PPSSPPDisplay " ) ;
2012-11-01 15:19:01 +00:00
2013-03-17 13:46:39 +00:00
// Forward declarations of functions included in this code module:
2012-11-01 15:19:01 +00:00
LRESULT CALLBACK WndProc ( HWND , UINT , WPARAM , LPARAM ) ;
2014-06-29 20:13:53 +00:00
LRESULT CALLBACK DisplayProc ( HWND , UINT , WPARAM , LPARAM ) ;
2012-11-01 15:19:01 +00:00
LRESULT CALLBACK About ( HWND , UINT , WPARAM , LPARAM ) ;
2013-07-07 02:12:06 +00:00
HWND GetHWND ( ) {
2012-11-01 15:19:01 +00:00
return hwndMain ;
}
2014-06-29 20:13:53 +00:00
HWND GetDisplayHWND ( ) {
return hwndDisplay ;
}
2013-07-07 02:12:06 +00:00
void Init ( HINSTANCE hInstance ) {
2013-02-19 00:28:13 +00:00
# ifdef THEMES
WTL : : CTheme : : IsThemingSupported ( ) ;
2012-11-01 15:19:01 +00:00
# endif
//Register classes
WNDCLASSEX wcex ;
wcex . cbSize = sizeof ( WNDCLASSEX ) ;
2014-06-23 18:04:31 +00:00
wcex . style = CS_PARENTDC ;
2012-11-01 15:19:01 +00:00
wcex . lpfnWndProc = ( WNDPROC ) WndProc ;
wcex . cbClsExtra = 0 ;
wcex . cbWndExtra = 0 ;
wcex . hInstance = hInstance ;
wcex . hIcon = LoadIcon ( hInstance , ( LPCTSTR ) IDI_PPSSPP ) ;
wcex . hCursor = LoadCursor ( NULL , IDC_ARROW ) ;
2012-12-05 06:31:41 +00:00
wcex . hbrBackground = ( HBRUSH ) GetStockObject ( BLACK_BRUSH ) ;
2013-08-26 17:00:16 +00:00
wcex . lpszMenuName = ( LPCWSTR ) IDR_MENU1 ;
2012-11-01 15:19:01 +00:00
wcex . lpszClassName = szWindowClass ;
2014-06-23 18:04:31 +00:00
wcex . hIconSm = ( HICON ) LoadImage ( hInstance , ( LPCTSTR ) IDI_PPSSPP , IMAGE_ICON , 16 , 16 , LR_SHARED ) ;
2012-11-01 15:19:01 +00:00
RegisterClassEx ( & wcex ) ;
2014-06-29 20:13:53 +00:00
wcex . style = CS_HREDRAW | CS_VREDRAW ;
wcex . lpfnWndProc = ( WNDPROC ) DisplayProc ;
wcex . hIcon = 0 ;
wcex . hbrBackground = ( HBRUSH ) GetStockObject ( BLACK_BRUSH ) ;
wcex . lpszMenuName = 0 ;
wcex . lpszClassName = szDisplayClass ;
wcex . hIconSm = 0 ;
RegisterClassEx ( & wcex ) ;
2012-11-01 15:19:01 +00:00
}
2013-03-30 16:49:02 +00:00
void SavePosition ( ) {
2014-06-23 18:04:31 +00:00
if ( g_Config . bFullScreen )
return ;
2013-09-13 15:39:40 +00:00
2013-03-30 16:49:02 +00:00
WINDOWPLACEMENT placement ;
GetWindowPlacement ( hwndMain , & placement ) ;
if ( placement . showCmd = = SW_SHOWNORMAL ) {
RECT rc ;
GetWindowRect ( hwndMain , & rc ) ;
g_Config . iWindowX = rc . left ;
g_Config . iWindowY = rc . top ;
2013-09-10 22:19:34 +00:00
g_Config . iWindowWidth = rc . right - rc . left ;
g_Config . iWindowHeight = rc . bottom - rc . top ;
2013-03-30 16:49:02 +00:00
}
}
2014-02-12 09:36:40 +00:00
static void GetWindowRectAtResolution ( int xres , int yres , RECT & rcInner , RECT & rcOuter ) {
2013-09-10 22:19:34 +00:00
rcInner . left = 0 ;
rcInner . top = 0 ;
rcInner . right = xres ;
rcInner . bottom = yres ;
rcOuter = rcInner ;
AdjustWindowRect ( & rcOuter , WS_OVERLAPPEDWINDOW , TRUE ) ;
rcOuter . right + = g_Config . iWindowX - rcOuter . left ;
rcOuter . bottom + = g_Config . iWindowY - rcOuter . top ;
rcOuter . left = g_Config . iWindowX ;
rcOuter . top = g_Config . iWindowY ;
}
2014-02-12 09:36:40 +00:00
static void ShowScreenResolution ( ) {
I18NCategory * g = GetI18NCategory ( " Graphics " ) ;
2014-07-10 07:19:00 +00:00
std : : ostringstream messageStream ;
messageStream < < g - > T ( " Internal Resolution " ) < < " : " ;
messageStream < < PSP_CoreParameter ( ) . renderWidth < < " x " < < PSP_CoreParameter ( ) . renderHeight < < " " ;
messageStream < < g - > T ( " Window Size " ) < < " : " ;
messageStream < < PSP_CoreParameter ( ) . pixelWidth < < " x " < < PSP_CoreParameter ( ) . pixelHeight ;
osm . Show ( messageStream . str ( ) , 2.0f ) ;
2014-02-12 09:36:40 +00:00
}
2014-02-12 10:34:29 +00:00
static void UpdateRenderResolution ( ) {
2013-01-26 22:46:02 +00:00
RECT rc ;
GetClientRect ( hwndMain , & rc ) ;
2015-05-15 16:04:05 +00:00
// Actually, auto mode should be more granular...
2013-07-29 08:46:40 +00:00
// Round up to a zoom factor for the render size.
2013-09-10 22:19:34 +00:00
int zoom = g_Config . iInternalResolution ;
2015-05-15 16:04:05 +00:00
if ( zoom = = 0 ) { // auto mode
// Use the longest dimension
if ( g_Config . IsPortrait ( ) ) {
zoom = ( rc . bottom - rc . top + 479 ) / 480 ;
} else {
zoom = ( rc . right - rc . left + 479 ) / 480 ;
}
}
2014-06-24 20:32:38 +00:00
if ( zoom < = 1 )
zoom = 1 ;
2014-01-27 06:46:09 +00:00
2015-05-15 16:04:05 +00:00
if ( g_Config . IsPortrait ( ) ) {
PSP_CoreParameter ( ) . renderWidth = 480 * zoom ;
PSP_CoreParameter ( ) . renderHeight = 272 * zoom ;
} else {
PSP_CoreParameter ( ) . renderWidth = 272 * zoom ;
PSP_CoreParameter ( ) . renderHeight = 480 * zoom ;
}
}
static bool IsWindowSmall ( ) {
return g_Config . IsPortrait ( ) ? ( g_Config . iWindowHeight < 480 + 80 ) : ( g_Config . iWindowWidth < 480 + 80 ) ;
2014-02-12 10:34:29 +00:00
}
static void ResizeDisplay ( bool noWindowMovement = false ) {
2014-06-29 10:53:03 +00:00
AssertCurrentThreadName ( " Main " ) ;
2014-02-12 10:34:29 +00:00
int width = 0 , height = 0 ;
RECT rc ;
GetClientRect ( hwndMain , & rc ) ;
if ( ! noWindowMovement ) {
width = rc . right - rc . left ;
height = rc . bottom - rc . top ;
2015-05-15 16:04:05 +00:00
// Moves the internal window, not the frame. TODO: Get rid of the internal window. Tried before but Intel drivers screw up when minimizing, or something?
2014-06-29 20:13:53 +00:00
MoveWindow ( hwndDisplay , 0 , 0 , width , height , TRUE ) ;
2014-02-12 10:34:29 +00:00
// This is taken care of anyway later, but makes sure that ShowScreenResolution gets the right numbers.
// Need to clean all of this up...
PSP_CoreParameter ( ) . pixelWidth = width ;
PSP_CoreParameter ( ) . pixelHeight = height ;
}
UpdateRenderResolution ( ) ;
2013-09-26 21:46:11 +00:00
2014-02-10 15:22:16 +00:00
if ( ! noWindowMovement ) {
2015-05-15 16:04:05 +00:00
if ( UpdateScreenScale ( width , height , IsWindowSmall ( ) ) ) {
2014-12-28 21:19:19 +00:00
NativeMessageReceived ( " gpu resized " , " " ) ;
}
2014-02-10 15:22:16 +00:00
}
2013-09-10 22:19:34 +00:00
}
void SetWindowSize ( int zoom ) {
2014-06-29 11:11:06 +00:00
AssertCurrentThreadName ( " Main " ) ;
2012-11-17 16:46:05 +00:00
RECT rc , rcOuter ;
2015-05-15 16:04:05 +00:00
// Actually, auto mode should be more granular...
if ( g_Config . IsPortrait ( ) ) {
GetWindowRectAtResolution ( 272 * ( int ) zoom , 480 * ( int ) zoom , rc , rcOuter ) ;
} else {
GetWindowRectAtResolution ( 480 * ( int ) zoom , 272 * ( int ) zoom , rc , rcOuter ) ;
}
2012-11-17 16:46:05 +00:00
MoveWindow ( hwndMain , rcOuter . left , rcOuter . top , rcOuter . right - rcOuter . left , rcOuter . bottom - rcOuter . top , TRUE ) ;
2014-02-12 10:34:29 +00:00
ResizeDisplay ( false ) ;
2014-02-12 09:36:40 +00:00
ShowScreenResolution ( ) ;
2012-11-01 15:19:01 +00:00
}
2013-09-19 18:32:56 +00:00
void SetInternalResolution ( int res = - 1 ) {
2013-09-20 01:18:26 +00:00
if ( res > = 0 & & res < = RESOLUTION_MAX )
2013-09-19 18:32:56 +00:00
g_Config . iInternalResolution = res ;
else {
2013-09-20 01:18:26 +00:00
if ( + + g_Config . iInternalResolution > RESOLUTION_MAX )
2013-09-19 18:32:56 +00:00
g_Config . iInternalResolution = 0 ;
}
2013-10-11 06:49:45 +00:00
2014-01-26 13:59:40 +00:00
// Taking auto-texture scaling into account
2013-10-11 06:49:45 +00:00
if ( g_Config . iTexScalingLevel = = TEXSCALING_AUTO )
setTexScalingMultiplier ( 0 ) ;
2013-09-19 18:32:56 +00:00
2014-02-13 21:23:16 +00:00
if ( gpu )
gpu - > Resized ( ) ;
2014-02-12 10:34:29 +00:00
UpdateRenderResolution ( ) ;
2014-02-12 09:36:40 +00:00
ShowScreenResolution ( ) ;
2013-09-10 22:19:34 +00:00
}
2013-05-26 21:55:23 +00:00
void CorrectCursor ( ) {
2014-06-22 07:38:46 +00:00
bool autoHide = g_Config . bFullScreen & & ! mouseButtonDown & & GetUIState ( ) = = UISTATE_INGAME ;
2013-06-11 18:14:53 +00:00
if ( autoHide & & hideCursor ) {
2013-05-26 21:55:23 +00:00
while ( cursorCounter > = 0 ) {
cursorCounter = ShowCursor ( FALSE ) ;
}
} else {
2013-06-11 18:14:53 +00:00
hideCursor = ! autoHide ;
2013-05-26 21:55:23 +00:00
if ( cursorCounter < 0 ) {
cursorCounter = ShowCursor ( TRUE ) ;
SetCursor ( LoadCursor ( NULL , IDC_ARROW ) ) ;
}
}
}
2015-02-15 22:07:24 +00:00
void ToggleFullscreen ( HWND hWnd , bool goingFullscreen ) {
2014-06-29 19:03:24 +00:00
// Make sure no rendering is happening during the switch.
Core_NotifyWindowHidden ( true ) ;
g_inModeSwitch = true ; // Make sure WM_SIZE doesn't call Core_NotifyWindowHidden(false)...
2014-07-17 03:50:46 +00:00
DWORD dwOldStyle ;
DWORD dwNewStyle ;
2013-09-10 22:19:34 +00:00
2014-07-17 03:50:46 +00:00
if ( ! goingFullscreen ) {
// Put caption and border styles back.
dwOldStyle = : : GetWindowLong ( hWnd , GWL_STYLE ) ;
2014-07-20 15:28:25 +00:00
dwOldStyle & = ~ WS_POPUP ;
2014-07-17 03:50:46 +00:00
dwNewStyle = dwOldStyle | WS_CAPTION | WS_THICKFRAME | WS_SYSMENU ;
// Put back the menu bar.
: : SetMenu ( hWnd , menu ) ;
} else {
2014-07-29 22:18:57 +00:00
// If the window was maximized before going fullscreen, make sure to restore first
// in order not to have the taskbar show up on top of PPSSPP.
if ( g_WindowState = = SIZE_MAXIMIZED ) {
ShowWindow ( hwndMain , SW_RESTORE ) ;
}
2014-07-17 03:50:46 +00:00
// Remember the normal window rectangle.
: : GetWindowRect ( hWnd , & g_normalRC ) ;
2013-09-27 19:34:13 +00:00
2014-07-17 03:50:46 +00:00
// Remove caption and border styles.
dwOldStyle = : : GetWindowLong ( hWnd , GWL_STYLE ) ;
dwNewStyle = dwOldStyle & ~ ( WS_CAPTION | WS_THICKFRAME | WS_SYSMENU ) ;
2014-07-20 15:28:25 +00:00
// Add WS_POPUP
dwNewStyle | = WS_POPUP ;
2014-02-12 09:36:40 +00:00
}
2014-06-29 19:03:24 +00:00
2013-09-10 22:19:34 +00:00
: : SetWindowLong ( hWnd , GWL_STYLE , dwNewStyle ) ;
// Remove the menu bar.
2014-07-17 04:03:41 +00:00
: : SetMenu ( hWnd , goingFullscreen ? NULL : menu ) ;
2013-09-10 22:19:34 +00:00
2014-07-17 04:06:52 +00:00
// Resize to the appropriate view.
2014-07-29 22:18:57 +00:00
// If we're returning to window mode, re-apply the appropriate size setting.
if ( goingFullscreen ) {
ShowWindow ( hwndMain , SW_MAXIMIZE ) ;
} else {
ShowWindow ( hwndMain , g_WindowState = = SIZE_MAXIMIZED ? SW_MAXIMIZE : SW_RESTORE ) ;
}
2013-09-10 22:19:34 +00:00
2014-07-17 03:50:46 +00:00
g_Config . bFullScreen = goingFullscreen ;
2013-09-10 22:19:34 +00:00
CorrectCursor ( ) ;
2013-09-27 19:34:13 +00:00
bool showOSM = ( g_Config . iInternalResolution = = RESOLUTION_AUTO ) ;
2014-06-29 19:03:24 +00:00
ResizeDisplay ( false ) ;
2014-02-12 09:36:40 +00:00
if ( showOSM ) {
ShowScreenResolution ( ) ;
}
2014-07-17 04:03:41 +00:00
ShowOwnedPopups ( hwndMain , goingFullscreen ? FALSE : TRUE ) ;
2014-07-17 03:50:46 +00:00
W32Util : : MakeTopMost ( hwndMain , g_Config . bTopMost ) ;
2014-06-29 19:03:24 +00:00
g_inModeSwitch = false ;
Core_NotifyWindowHidden ( false ) ;
2015-02-15 22:07:24 +00:00
WindowsRawInput : : NotifyMenu ( ) ;
2013-09-10 22:19:34 +00:00
}
2013-10-15 11:10:14 +00:00
RECT DetermineWindowRectangle ( ) {
RECT rc ;
const int screenWidth = GetSystemMetrics ( SM_CXVIRTUALSCREEN ) ;
const int screenHeight = GetSystemMetrics ( SM_CYVIRTUALSCREEN ) ;
const int screenX = GetSystemMetrics ( SM_XVIRTUALSCREEN ) ;
const int screenY = GetSystemMetrics ( SM_YVIRTUALSCREEN ) ;
if ( ! g_Config . bFullScreen ) {
bool visibleHorizontally = ( ( g_Config . iWindowX + g_Config . iWindowWidth ) > = screenX ) & &
( ( g_Config . iWindowX + g_Config . iWindowWidth ) < ( screenWidth + g_Config . iWindowWidth ) ) ;
bool visibleVertically = ( ( g_Config . iWindowY + g_Config . iWindowHeight ) > = screenY ) & &
( ( g_Config . iWindowY + g_Config . iWindowHeight ) < ( screenHeight + g_Config . iWindowHeight ) ) ;
if ( ! visibleHorizontally )
g_Config . iWindowX = - 1 ;
if ( ! visibleVertically )
g_Config . iWindowY = - 1 ;
}
rc . left = g_Config . iWindowX ;
rc . top = g_Config . iWindowY ;
// First, get the w/h right.
if ( g_Config . iWindowWidth < = 0 | | g_Config . iWindowHeight < = 0 ) {
RECT rcInner = rc , rcOuter ;
2015-05-15 16:04:05 +00:00
bool portrait = g_Config . IsPortrait ( ) ;
GetWindowRectAtResolution ( 2 * ( portrait ? 272 : 480 ) , 2 * ( portrait ? 480 : 272 ) , rcInner , rcOuter ) ;
2013-10-15 11:10:14 +00:00
rc . right = rc . left + ( rcOuter . right - rcOuter . left ) ;
rc . bottom = rc . top + ( rcOuter . bottom - rcOuter . top ) ;
g_Config . iWindowWidth = rc . right - rc . left ;
g_Config . iWindowHeight = rc . bottom - rc . top ;
} else {
rc . right = rc . left + g_Config . iWindowWidth ;
rc . bottom = rc . top + g_Config . iWindowHeight ;
}
// Then center if necessary.
if ( g_Config . iWindowX = = - 1 & & g_Config . iWindowY = = - 1 ) {
// Center the window.
2013-10-16 05:02:14 +00:00
const int primaryScreenWidth = GetSystemMetrics ( SM_CXSCREEN ) ;
const int primaryScreenHeight = GetSystemMetrics ( SM_CYSCREEN ) ;
g_Config . iWindowX = ( primaryScreenWidth - g_Config . iWindowWidth ) / 2 ;
g_Config . iWindowY = ( primaryScreenHeight - g_Config . iWindowHeight ) / 2 ;
2013-10-15 11:10:14 +00:00
rc . left = g_Config . iWindowX ;
rc . top = g_Config . iWindowY ;
rc . right = rc . left + g_Config . iWindowWidth ;
rc . bottom = rc . top + g_Config . iWindowHeight ;
}
return rc ;
}
2013-09-16 22:08:09 +00:00
void SetIngameMenuItemStates ( const GlobalUIState state ) {
UINT menuEnable = state = = UISTATE_INGAME ? MF_ENABLED : MF_GRAYED ;
2013-11-27 13:57:17 +00:00
UINT umdSwitchEnable = state = = UISTATE_INGAME & & getUMDReplacePermit ( ) ? MF_ENABLED : MF_GRAYED ;
2013-09-16 22:08:09 +00:00
EnableMenuItem ( menu , ID_FILE_SAVESTATEFILE , menuEnable ) ;
EnableMenuItem ( menu , ID_FILE_LOADSTATEFILE , menuEnable ) ;
EnableMenuItem ( menu , ID_FILE_QUICKSAVESTATE , menuEnable ) ;
EnableMenuItem ( menu , ID_FILE_QUICKLOADSTATE , menuEnable ) ;
EnableMenuItem ( menu , ID_TOGGLE_PAUSE , menuEnable ) ;
EnableMenuItem ( menu , ID_EMULATION_STOP , menuEnable ) ;
EnableMenuItem ( menu , ID_EMULATION_RESET , menuEnable ) ;
2013-11-27 13:57:17 +00:00
EnableMenuItem ( menu , ID_EMULATION_SWITCH_UMD , umdSwitchEnable ) ;
2014-03-01 19:25:40 +00:00
EnableMenuItem ( menu , ID_DEBUG_LOADMAPFILE , menuEnable ) ;
EnableMenuItem ( menu , ID_DEBUG_SAVEMAPFILE , menuEnable ) ;
2014-06-29 22:02:22 +00:00
EnableMenuItem ( menu , ID_DEBUG_LOADSYMFILE , menuEnable ) ;
EnableMenuItem ( menu , ID_DEBUG_SAVESYMFILE , menuEnable ) ;
2014-03-01 19:25:40 +00:00
EnableMenuItem ( menu , ID_DEBUG_RESETSYMBOLTABLE , menuEnable ) ;
EnableMenuItem ( menu , ID_DEBUG_EXTRACTFILE , menuEnable ) ;
2013-09-16 22:08:09 +00:00
}
2013-09-10 22:19:34 +00:00
2013-09-04 12:41:57 +00:00
// These are used as an offset
// to determine which menu item to change.
// Make sure to count(from 0) the separators too, when dealing with submenus!!
2013-09-16 22:08:09 +00:00
enum MenuItemPosition {
2013-09-04 12:41:57 +00:00
// Main menus
MENU_FILE = 0 ,
MENU_EMULATION = 1 ,
MENU_DEBUG = 2 ,
MENU_OPTIONS = 3 ,
2013-11-03 00:24:19 +00:00
MENU_HELP = 4 ,
2013-09-04 12:41:57 +00:00
2013-09-07 15:29:44 +00:00
// File submenus
SUBMENU_FILE_SAVESTATE_SLOT = 6 ,
2013-09-04 12:41:57 +00:00
// Game Settings submenus
2014-01-09 13:15:46 +00:00
SUBMENU_CUSTOM_SHADERS = 10 ,
SUBMENU_RENDERING_RESOLUTION = 11 ,
SUBMENU_WINDOW_SIZE = 12 ,
2014-09-14 11:30:49 +00:00
SUBMENU_RENDERING_BACKEND = 13 ,
SUBMENU_RENDERING_MODE = 14 ,
SUBMENU_FRAME_SKIPPING = 15 ,
SUBMENU_TEXTURE_FILTERING = 16 ,
SUBMENU_BUFFER_FILTER = 17 ,
SUBMENU_TEXTURE_SCALING = 18 ,
2013-09-04 12:41:57 +00:00
} ;
2013-08-29 20:13:22 +00:00
std : : string GetMenuItemText ( int menuID ) {
MENUITEMINFO menuInfo ;
2013-08-30 13:27:16 +00:00
memset ( & menuInfo , 0 , sizeof ( menuInfo ) ) ;
2013-08-29 20:13:22 +00:00
menuInfo . cbSize = sizeof ( MENUITEMINFO ) ;
menuInfo . fMask = MIIM_STRING ;
menuInfo . dwTypeData = 0 ;
2013-08-31 05:18:37 +00:00
std : : string retVal ;
if ( GetMenuItemInfo ( menu , menuID , MF_BYCOMMAND , & menuInfo ) ! = FALSE ) {
wchar_t * buffer = new wchar_t [ + + menuInfo . cch ] ;
menuInfo . dwTypeData = buffer ;
GetMenuItemInfo ( menu , menuID , MF_BYCOMMAND , & menuInfo ) ;
retVal = ConvertWStringToUTF8 ( menuInfo . dwTypeData ) ;
delete [ ] buffer ;
}
2013-08-29 20:13:22 +00:00
return retVal ;
}
2013-09-01 21:06:24 +00:00
const std : : string & GetMenuItemInitialText ( const int menuID ) {
if ( initialMenuKeys . find ( menuID ) = = initialMenuKeys . end ( ) ) {
initialMenuKeys [ menuID ] = GetMenuItemText ( menuID ) ;
}
return initialMenuKeys [ menuID ] ;
}
2013-09-04 14:45:48 +00:00
void CreateHelpMenu ( ) {
2013-09-16 22:55:06 +00:00
I18NCategory * des = GetI18NCategory ( " DesktopUI " ) ;
2013-09-04 14:45:48 +00:00
2013-09-16 22:55:06 +00:00
const std : : wstring help = ConvertUTF8ToWString ( des - > T ( " Help " ) ) ;
const std : : wstring visitMainWebsite = ConvertUTF8ToWString ( des - > T ( " www.ppsspp.org " ) ) ;
const std : : wstring visitForum = ConvertUTF8ToWString ( des - > T ( " PPSSPP Forums " ) ) ;
const std : : wstring buyGold = ConvertUTF8ToWString ( des - > T ( " Buy Gold " ) ) ;
const std : : wstring aboutPPSSPP = ConvertUTF8ToWString ( des - > T ( " About PPSSPP... " ) ) ;
2013-09-04 14:45:48 +00:00
// Simply remove the old help menu and create a new one.
RemoveMenu ( menu , MENU_HELP , MF_BYPOSITION ) ;
2013-09-16 22:08:09 +00:00
HMENU helpMenu = CreatePopupMenu ( ) ;
2013-09-04 14:45:48 +00:00
InsertMenu ( menu , MENU_HELP , MF_POPUP | MF_STRING | MF_BYPOSITION , ( UINT_PTR ) helpMenu , help . c_str ( ) ) ;
2013-09-04 15:14:39 +00:00
AppendMenu ( helpMenu , MF_STRING | MF_BYCOMMAND , ID_HELP_OPENWEBSITE , visitMainWebsite . c_str ( ) ) ;
AppendMenu ( helpMenu , MF_STRING | MF_BYCOMMAND , ID_HELP_OPENFORUM , visitForum . c_str ( ) ) ;
2013-09-04 14:45:48 +00:00
// Repeat the process for other languages, if necessary.
2013-09-04 15:14:39 +00:00
AppendMenu ( helpMenu , MF_STRING | MF_BYCOMMAND , ID_HELP_BUYGOLD , buyGold . c_str ( ) ) ;
2013-09-04 14:45:48 +00:00
AppendMenu ( helpMenu , MF_SEPARATOR , 0 , 0 ) ;
2013-09-04 15:14:39 +00:00
AppendMenu ( helpMenu , MF_STRING | MF_BYCOMMAND , ID_HELP_ABOUT , aboutPPSSPP . c_str ( ) ) ;
2013-09-04 14:45:48 +00:00
}
2013-10-12 05:15:47 +00:00
void UpdateDynamicMenuCheckmarks ( ) {
int item = ID_SHADERS_BASE + 1 ;
2013-10-12 23:49:22 +00:00
for ( size_t i = 0 ; i < availableShaders . size ( ) ; i + + )
2013-10-12 05:15:47 +00:00
CheckMenuItem ( menu , item + + , ( ( g_Config . sPostShaderName = = availableShaders [ i ] ) ? MF_CHECKED : MF_UNCHECKED ) ) ;
}
2013-10-12 04:14:58 +00:00
void CreateShadersSubmenu ( ) {
2013-10-12 04:22:59 +00:00
I18NCategory * des = GetI18NCategory ( " DesktopUI " ) ;
2013-11-30 05:37:15 +00:00
I18NCategory * ps = GetI18NCategory ( " PostShaders " ) ;
2013-10-12 04:22:59 +00:00
const std : : wstring key = ConvertUTF8ToWString ( des - > T ( " Postprocessing Shader " ) ) ;
2013-10-12 04:14:58 +00:00
HMENU optionsMenu = GetSubMenu ( menu , MENU_OPTIONS ) ;
2013-10-12 04:22:59 +00:00
HMENU shaderMenu = CreatePopupMenu ( ) ;
RemoveMenu ( optionsMenu , SUBMENU_CUSTOM_SHADERS , MF_BYPOSITION ) ;
2013-10-12 04:14:58 +00:00
InsertMenu ( optionsMenu , SUBMENU_CUSTOM_SHADERS , MF_POPUP | MF_STRING | MF_BYPOSITION , ( UINT_PTR ) shaderMenu , key . c_str ( ) ) ;
std : : vector < ShaderInfo > info = GetAllPostShaderInfo ( ) ;
availableShaders . clear ( ) ;
2013-10-12 05:15:47 +00:00
2013-10-12 04:22:59 +00:00
int item = ID_SHADERS_BASE + 1 ;
2013-10-12 05:15:47 +00:00
int checkedStatus = - 1 ;
2013-11-29 17:51:24 +00:00
const char * translatedShaderName = nullptr ;
2013-10-12 04:14:58 +00:00
for ( auto i = info . begin ( ) ; i ! = info . end ( ) ; + + i ) {
2013-10-12 05:15:47 +00:00
checkedStatus = MF_UNCHECKED ;
2013-10-12 04:14:58 +00:00
availableShaders . push_back ( i - > section ) ;
2013-10-12 05:15:47 +00:00
if ( g_Config . sPostShaderName = = i - > section ) {
checkedStatus = MF_CHECKED ;
}
2013-11-30 05:37:15 +00:00
translatedShaderName = ps - > T ( i - > section . c_str ( ) ) ;
2013-11-29 17:51:24 +00:00
AppendMenu ( shaderMenu , MF_STRING | MF_BYPOSITION | checkedStatus , item + + , ConvertUTF8ToWString ( translatedShaderName ) . c_str ( ) ) ;
2013-10-12 04:14:58 +00:00
}
}
2013-09-16 22:08:09 +00:00
void _TranslateMenuItem ( const int menuIDOrPosition , const char * key , bool byCommand = false , const std : : wstring & accelerator = L " " , const HMENU hMenu = menu ) {
2013-09-16 22:55:06 +00:00
I18NCategory * des = GetI18NCategory ( " DesktopUI " ) ;
2013-09-13 17:06:13 +00:00
2013-09-16 22:55:06 +00:00
std : : wstring translated = ConvertUTF8ToWString ( des - > T ( key ) ) ;
2013-08-30 21:29:22 +00:00
translated . append ( accelerator ) ;
2013-09-16 22:08:09 +00:00
u32 flags = MF_STRING | ( byCommand ? MF_BYCOMMAND : MF_BYPOSITION ) ;
2013-09-13 17:06:13 +00:00
2013-09-16 22:08:09 +00:00
ModifyMenu ( hMenu , menuIDOrPosition , flags , menuIDOrPosition , translated . c_str ( ) ) ;
2013-09-13 17:06:13 +00:00
}
2013-09-16 22:08:09 +00:00
void TranslateMenuItem ( const int menuID , const std : : wstring & accelerator = L " " , const char * key = " " , const HMENU hMenu = menu ) {
if ( key = = nullptr | | ! strcmp ( key , " " ) )
_TranslateMenuItem ( menuID , GetMenuItemInitialText ( menuID ) . c_str ( ) , true , accelerator , hMenu ) ;
2013-09-13 17:06:13 +00:00
else
2013-09-16 22:08:09 +00:00
_TranslateMenuItem ( menuID , key , true , accelerator , hMenu ) ;
2013-09-13 17:06:13 +00:00
}
2013-09-16 22:08:09 +00:00
void TranslateMenu ( const char * key , const MenuItemPosition mainMenuPosition , const std : : wstring & accelerator = L " " ) {
_TranslateMenuItem ( mainMenuPosition , key , false , accelerator ) ;
2013-08-30 21:29:22 +00:00
}
2013-09-16 22:08:09 +00:00
void TranslateSubMenu ( const char * key , const MenuItemPosition mainMenuItem , const MenuItemPosition subMenuItem , const std : : wstring & accelerator = L " " ) {
_TranslateMenuItem ( subMenuItem , key , false , accelerator , GetSubMenu ( menu , mainMenuItem ) ) ;
2013-08-29 20:13:22 +00:00
}
void TranslateMenus ( ) {
2013-09-16 22:08:09 +00:00
// Menu headers and submenu headers don't have resource IDs,
// So we have to hardcode strings here, unfortunately.
TranslateMenu ( " File " , MENU_FILE ) ;
TranslateMenu ( " Emulation " , MENU_EMULATION ) ;
TranslateMenu ( " Debugging " , MENU_DEBUG ) ;
TranslateMenu ( " Game Settings " , MENU_OPTIONS ) ;
TranslateMenu ( " Help " , MENU_HELP ) ;
2013-08-29 20:13:22 +00:00
2013-10-12 04:22:59 +00:00
CreateShadersSubmenu ( ) ;
2013-08-29 20:13:22 +00:00
// File menu
2013-09-16 22:08:09 +00:00
TranslateMenuItem ( ID_FILE_LOAD ) ;
TranslateMenuItem ( ID_FILE_LOAD_DIR ) ;
TranslateMenuItem ( ID_FILE_LOAD_MEMSTICK ) ;
TranslateMenuItem ( ID_FILE_MEMSTICK ) ;
2014-06-04 19:09:04 +00:00
TranslateSubMenu ( " Savestate Slot " , MENU_FILE , SUBMENU_FILE_SAVESTATE_SLOT , L " \t F3 " ) ;
2013-09-16 22:08:09 +00:00
TranslateMenuItem ( ID_FILE_QUICKLOADSTATE , L " \t F4 " ) ;
TranslateMenuItem ( ID_FILE_QUICKSAVESTATE , L " \t F2 " ) ;
TranslateMenuItem ( ID_FILE_LOADSTATEFILE ) ;
TranslateMenuItem ( ID_FILE_SAVESTATEFILE ) ;
TranslateMenuItem ( ID_FILE_EXIT , L " \t Alt+F4 " ) ;
2013-08-29 20:13:22 +00:00
// Emulation menu
2013-09-16 22:08:09 +00:00
TranslateMenuItem ( ID_TOGGLE_PAUSE , L " \t F8 " , " Pause " ) ;
TranslateMenuItem ( ID_EMULATION_STOP , L " \t Ctrl+W " ) ;
2013-11-27 13:57:17 +00:00
TranslateMenuItem ( ID_EMULATION_RESET , L " \t Ctrl+B " ) ;
TranslateMenuItem ( ID_EMULATION_SWITCH_UMD , L " \t Ctrl+U " , " Switch UMD " ) ;
2013-09-04 02:06:05 +00:00
2013-08-29 20:13:22 +00:00
// Debug menu
2013-09-16 22:08:09 +00:00
TranslateMenuItem ( ID_DEBUG_LOADMAPFILE ) ;
TranslateMenuItem ( ID_DEBUG_SAVEMAPFILE ) ;
2014-06-29 22:02:22 +00:00
TranslateMenuItem ( ID_DEBUG_LOADSYMFILE ) ;
TranslateMenuItem ( ID_DEBUG_SAVESYMFILE ) ;
2013-09-16 22:08:09 +00:00
TranslateMenuItem ( ID_DEBUG_RESETSYMBOLTABLE ) ;
TranslateMenuItem ( ID_DEBUG_DUMPNEXTFRAME ) ;
TranslateMenuItem ( ID_DEBUG_TAKESCREENSHOT , L " \t F12 " ) ;
TranslateMenuItem ( ID_DEBUG_SHOWDEBUGSTATISTICS ) ;
TranslateMenuItem ( ID_DEBUG_IGNOREILLEGALREADS ) ;
TranslateMenuItem ( ID_DEBUG_RUNONLOAD ) ;
TranslateMenuItem ( ID_DEBUG_DISASSEMBLY , L " \t Ctrl+D " ) ;
2013-09-30 13:56:08 +00:00
TranslateMenuItem ( ID_DEBUG_GEDEBUGGER , L " \t Ctrl+G " ) ;
2014-01-04 11:33:02 +00:00
TranslateMenuItem ( ID_DEBUG_EXTRACTFILE ) ;
2013-09-16 22:08:09 +00:00
TranslateMenuItem ( ID_DEBUG_LOG , L " \t Ctrl+L " ) ;
TranslateMenuItem ( ID_DEBUG_MEMORYVIEW , L " \t Ctrl+M " ) ;
2013-08-29 20:13:22 +00:00
// Options menu
2013-11-03 00:24:19 +00:00
TranslateMenuItem ( ID_OPTIONS_LANGUAGE ) ;
2013-09-16 22:08:09 +00:00
TranslateMenuItem ( ID_OPTIONS_TOPMOST ) ;
2013-10-11 11:53:25 +00:00
TranslateMenuItem ( ID_OPTIONS_PAUSE_FOCUS ) ;
2014-01-07 21:08:11 +00:00
TranslateMenuItem ( ID_OPTIONS_IGNOREWINKEY ) ;
2013-09-16 22:08:09 +00:00
TranslateMenuItem ( ID_OPTIONS_MORE_SETTINGS ) ;
TranslateMenuItem ( ID_OPTIONS_CONTROLS ) ;
TranslateMenuItem ( ID_OPTIONS_STRETCHDISPLAY ) ;
TranslateMenuItem ( ID_OPTIONS_FULLSCREEN , L " \t Alt+Return, F11 " ) ;
TranslateMenuItem ( ID_OPTIONS_VSYNC ) ;
2013-10-12 04:22:59 +00:00
TranslateSubMenu ( " Postprocessing Shader " , MENU_OPTIONS , SUBMENU_CUSTOM_SHADERS ) ;
2013-09-16 22:08:09 +00:00
TranslateSubMenu ( " Rendering Resolution " , MENU_OPTIONS , SUBMENU_RENDERING_RESOLUTION , L " \t Ctrl+1 " ) ;
TranslateMenuItem ( ID_OPTIONS_SCREENAUTO ) ;
2013-09-11 02:20:14 +00:00
// Skip rendering resolution 2x-5x..
2013-09-16 22:08:09 +00:00
TranslateSubMenu ( " Window Size " , MENU_OPTIONS , SUBMENU_WINDOW_SIZE ) ;
2013-09-11 02:20:14 +00:00
// Skip window size 1x-4x..
2014-09-14 11:30:49 +00:00
TranslateSubMenu ( " Backend " , MENU_OPTIONS , SUBMENU_RENDERING_BACKEND ) ;
TranslateMenuItem ( ID_OPTIONS_DIRECTX ) ;
TranslateMenuItem ( ID_OPTIONS_OPENGL ) ;
2013-09-16 22:08:09 +00:00
TranslateSubMenu ( " Rendering Mode " , MENU_OPTIONS , SUBMENU_RENDERING_MODE , L " \t F5 " ) ;
TranslateMenuItem ( ID_OPTIONS_NONBUFFEREDRENDERING ) ;
TranslateMenuItem ( ID_OPTIONS_BUFFEREDRENDERING ) ;
TranslateMenuItem ( ID_OPTIONS_READFBOTOMEMORYCPU ) ;
TranslateMenuItem ( ID_OPTIONS_READFBOTOMEMORYGPU ) ;
TranslateSubMenu ( " Frame Skipping " , MENU_OPTIONS , SUBMENU_FRAME_SKIPPING , L " \t F7 " ) ;
TranslateMenuItem ( ID_OPTIONS_FRAMESKIP_AUTO ) ;
2014-01-25 16:41:39 +00:00
TranslateMenuItem ( ID_OPTIONS_FRAMESKIP_0 ) ;
2013-09-11 02:20:14 +00:00
// Skip frameskipping 1-8..
2013-09-16 22:08:09 +00:00
TranslateSubMenu ( " Texture Filtering " , MENU_OPTIONS , SUBMENU_TEXTURE_FILTERING ) ;
TranslateMenuItem ( ID_OPTIONS_TEXTUREFILTERING_AUTO ) ;
TranslateMenuItem ( ID_OPTIONS_NEARESTFILTERING ) ;
TranslateMenuItem ( ID_OPTIONS_LINEARFILTERING ) ;
TranslateMenuItem ( ID_OPTIONS_LINEARFILTERING_CG ) ;
2014-08-08 18:51:15 +00:00
TranslateSubMenu ( " Screen Scaling Filter " , MENU_OPTIONS , SUBMENU_BUFFER_FILTER ) ;
TranslateMenuItem ( ID_OPTIONS_BUFLINEARFILTER ) ;
TranslateMenuItem ( ID_OPTIONS_BUFNEARESTFILTER ) ;
2013-09-16 22:08:09 +00:00
TranslateSubMenu ( " Texture Scaling " , MENU_OPTIONS , SUBMENU_TEXTURE_SCALING ) ;
TranslateMenuItem ( ID_TEXTURESCALING_OFF ) ;
2013-08-29 21:35:01 +00:00
// Skip texture scaling 2x-5x...
2013-09-16 22:08:09 +00:00
TranslateMenuItem ( ID_TEXTURESCALING_XBRZ ) ;
TranslateMenuItem ( ID_TEXTURESCALING_HYBRID ) ;
TranslateMenuItem ( ID_TEXTURESCALING_BICUBIC ) ;
TranslateMenuItem ( ID_TEXTURESCALING_HYBRID_BICUBIC ) ;
TranslateMenuItem ( ID_TEXTURESCALING_DEPOSTERIZE ) ;
TranslateMenuItem ( ID_OPTIONS_HARDWARETRANSFORM , L " \t F6 " ) ;
TranslateMenuItem ( ID_OPTIONS_VERTEXCACHE ) ;
TranslateMenuItem ( ID_OPTIONS_SHOWFPS ) ;
TranslateMenuItem ( ID_EMULATION_SOUND ) ;
TranslateMenuItem ( ID_EMULATION_CHEATS , L " \t Ctrl+T " ) ;
2013-09-04 14:45:48 +00:00
// Help menu: it's translated in CreateHelpMenu.
CreateHelpMenu ( ) ;
2013-08-29 20:13:22 +00:00
2013-09-16 22:08:09 +00:00
// TODO: Urgh! Why do we need this here?
// The menu is supposed to enable/disable this stuff directly afterward.
2014-06-22 07:38:46 +00:00
SetIngameMenuItemStates ( GetUIState ( ) ) ;
2013-08-29 22:27:11 +00:00
2013-08-29 20:13:22 +00:00
DrawMenuBar ( hwndMain ) ;
2013-09-07 21:22:40 +00:00
UpdateMenus ( ) ;
2013-08-29 20:13:22 +00:00
}
2013-07-29 08:46:40 +00:00
void setTexScalingMultiplier ( int level ) {
2013-07-26 12:25:11 +00:00
g_Config . iTexScalingLevel = level ;
2013-10-12 17:19:23 +00:00
NativeMessageReceived ( " gpu clear cache " , " " ) ;
2013-05-01 21:55:34 +00:00
}
2013-06-30 06:48:50 +00:00
2013-07-26 12:25:11 +00:00
void setTexFiltering ( int type ) {
g_Config . iTexFiltering = type ;
2013-06-30 06:48:50 +00:00
}
2014-08-08 18:51:15 +00:00
void setBufFilter ( int type ) {
g_Config . iBufFilter = type ;
}
2013-07-26 12:25:11 +00:00
void setTexScalingType ( int type ) {
g_Config . iTexScalingType = type ;
2013-10-12 17:19:23 +00:00
NativeMessageReceived ( " gpu clear cache " , " " ) ;
2013-04-30 01:47:33 +00:00
}
2013-06-30 06:48:50 +00:00
2013-09-20 01:18:26 +00:00
void setRenderingMode ( int mode = - 1 ) {
if ( mode > = FB_NON_BUFFERED_MODE )
g_Config . iRenderingMode = mode ;
else {
if ( + + g_Config . iRenderingMode > FB_READFBOMEMORY_GPU )
g_Config . iRenderingMode = FB_NON_BUFFERED_MODE ;
}
2013-07-29 22:05:08 +00:00
I18NCategory * g = GetI18NCategory ( " Graphics " ) ;
switch ( g_Config . iRenderingMode ) {
case FB_NON_BUFFERED_MODE :
osm . Show ( g - > T ( " Non-Buffered Rendering " ) ) ;
2015-02-09 22:10:57 +00:00
g_Config . bAutoFrameSkip = false ;
2013-07-29 22:05:08 +00:00
break ;
case FB_BUFFERED_MODE :
osm . Show ( g - > T ( " Buffered Rendering " ) ) ;
break ;
case FB_READFBOMEMORY_CPU :
2015-02-10 11:16:48 +00:00
osm . Show ( g - > T ( " Read Framebuffers To Memory (CPU) " ) ) ;
2013-07-29 22:05:08 +00:00
break ;
case FB_READFBOMEMORY_GPU :
2015-02-10 11:16:48 +00:00
osm . Show ( g - > T ( " Read Framebuffers To Memory (GPU) " ) ) ;
2013-07-29 22:05:08 +00:00
break ;
}
2013-10-12 17:19:23 +00:00
NativeMessageReceived ( " gpu resized " , " " ) ;
2013-07-21 15:17:42 +00:00
}
2013-05-10 00:36:23 +00:00
void setFpsLimit ( int fps ) {
g_Config . iFpsLimit = fps ;
}
2013-06-30 06:48:50 +00:00
2013-09-20 01:18:26 +00:00
void setFrameSkipping ( int framesToSkip = - 1 ) {
if ( framesToSkip > = FRAMESKIP_OFF )
g_Config . iFrameSkip = framesToSkip ;
else {
if ( + + g_Config . iFrameSkip > FRAMESKIP_MAX )
g_Config . iFrameSkip = FRAMESKIP_OFF ;
}
2013-08-21 11:44:08 +00:00
I18NCategory * g = GetI18NCategory ( " Graphics " ) ;
2013-08-21 17:22:13 +00:00
2014-07-10 07:19:00 +00:00
std : : ostringstream messageStream ;
messageStream < < g - > T ( " Frame Skipping " ) < < " : " < < " " ;
2013-08-21 17:22:13 +00:00
2014-07-10 07:19:00 +00:00
if ( g_Config . iFrameSkip = = FRAMESKIP_OFF )
messageStream < < g - > T ( " Off " ) ;
else
messageStream < < g_Config . iFrameSkip ;
2013-08-21 17:35:26 +00:00
2014-07-10 07:19:00 +00:00
osm . Show ( messageStream . str ( ) ) ;
2013-08-21 17:35:26 +00:00
}
2013-07-26 12:25:11 +00:00
2013-07-29 19:34:30 +00:00
void enableCheats ( bool cheats ) {
2013-05-23 11:10:39 +00:00
g_Config . bEnableCheats = cheats ;
2013-05-18 22:04:01 +00:00
}
2013-04-30 01:47:33 +00:00
2013-09-13 19:17:55 +00:00
void UpdateWindowTitle ( ) {
2013-09-13 20:38:28 +00:00
// Seems to be fine to call now since we use a UNICODE build...
SetWindowText ( hwndMain , windowTitle . c_str ( ) ) ;
2013-09-13 19:17:55 +00:00
}
void SetWindowTitle ( const wchar_t * title ) {
windowTitle = title ;
}
2014-07-17 04:06:52 +00:00
BOOL Show ( HINSTANCE hInstance ) {
2013-09-22 18:44:35 +00:00
hInst = hInstance ; // Store instance handle in our global variable.
RECT rc = DetermineWindowRectangle ( ) ;
2013-03-29 20:21:27 +00:00
u32 style = WS_OVERLAPPEDWINDOW ;
2012-11-01 15:19:01 +00:00
2013-08-26 17:00:16 +00:00
hwndMain = CreateWindowEx ( 0 , szWindowClass , L " " , style ,
2013-06-08 00:32:07 +00:00
rc . left , rc . top , rc . right - rc . left , rc . bottom - rc . top , NULL , NULL , hInstance , NULL ) ;
2012-11-01 15:19:01 +00:00
if ( ! hwndMain )
return FALSE ;
2013-09-10 22:19:34 +00:00
RECT rcClient ;
GetClientRect ( hwndMain , & rcClient ) ;
2014-06-29 20:13:53 +00:00
hwndDisplay = CreateWindowEx ( 0 , szDisplayClass , L " " , WS_CHILD | WS_VISIBLE ,
0 , 0 , rcClient . right - rcClient . left , rcClient . bottom - rcClient . top , hwndMain , 0 , hInstance , 0 ) ;
if ( ! hwndDisplay )
return FALSE ;
2012-11-01 15:19:01 +00:00
menu = GetMenu ( hwndMain ) ;
2013-08-29 22:27:11 +00:00
2012-11-01 15:19:01 +00:00
# ifdef FINAL
RemoveMenu ( menu , 2 , MF_BYPOSITION ) ;
RemoveMenu ( menu , 2 , MF_BYPOSITION ) ;
# endif
MENUINFO info ;
ZeroMemory ( & info , sizeof ( MENUINFO ) ) ;
info . cbSize = sizeof ( MENUINFO ) ;
info . cyMax = 0 ;
info . dwStyle = MNS_CHECKORBMP ;
info . fMask = MIM_STYLE ;
2013-07-29 19:34:30 +00:00
for ( int i = 0 ; i < GetMenuItemCount ( menu ) ; i + + ) {
2012-11-01 15:19:01 +00:00
SetMenuInfo ( GetSubMenu ( menu , i ) , & info ) ;
}
2013-06-08 00:32:07 +00:00
UpdateMenus ( ) ;
2012-11-01 15:19:01 +00:00
2013-07-29 08:46:40 +00:00
// Accept dragged files.
2012-11-01 15:19:01 +00:00
DragAcceptFiles ( hwndMain , TRUE ) ;
2013-06-11 18:14:53 +00:00
hideCursor = true ;
2013-06-08 00:32:07 +00:00
SetTimer ( hwndMain , TIMER_CURSORUPDATE , CURSORUPDATE_INTERVAL_MS , 0 ) ;
2014-06-29 20:24:20 +00:00
2014-07-17 03:50:46 +00:00
ToggleFullscreen ( hwndMain , g_Config . bFullScreen ) ;
2013-06-08 00:32:07 +00:00
2013-07-06 17:47:37 +00:00
W32Util : : MakeTopMost ( hwndMain , g_Config . bTopMost ) ;
2014-06-29 20:13:53 +00:00
touchHandler . registerTouchWindow ( hwndDisplay ) ;
2013-04-16 19:12:55 +00:00
2014-01-19 19:59:11 +00:00
WindowsRawInput : : Init ( ) ;
2013-07-07 08:42:39 +00:00
2013-10-16 15:20:32 +00:00
SetFocus ( hwndMain ) ;
2014-03-25 00:13:35 +00:00
2012-11-01 15:19:01 +00:00
return TRUE ;
}
2013-08-26 12:19:46 +00:00
void CreateDebugWindows ( ) {
disasmWindow [ 0 ] = new CDisasm ( MainWindow : : GetHInstance ( ) , MainWindow : : GetHWND ( ) , currentDebugMIPS ) ;
DialogManager : : AddDlg ( disasmWindow [ 0 ] ) ;
disasmWindow [ 0 ] - > Show ( g_Config . bShowDebuggerOnLoad ) ;
2013-09-22 17:27:09 +00:00
geDebuggerWindow = new CGEDebugger ( MainWindow : : GetHInstance ( ) , MainWindow : : GetHWND ( ) ) ;
DialogManager : : AddDlg ( geDebuggerWindow ) ;
2013-08-26 12:19:46 +00:00
memoryWindow [ 0 ] = new CMemoryDlg ( MainWindow : : GetHInstance ( ) , MainWindow : : GetHWND ( ) , currentDebugMIPS ) ;
DialogManager : : AddDlg ( memoryWindow [ 0 ] ) ;
}
2014-02-15 05:17:36 +00:00
void DestroyDebugWindows ( ) {
DialogManager : : RemoveDlg ( disasmWindow [ 0 ] ) ;
if ( disasmWindow [ 0 ] )
delete disasmWindow [ 0 ] ;
disasmWindow [ 0 ] = 0 ;
DialogManager : : RemoveDlg ( geDebuggerWindow ) ;
if ( geDebuggerWindow )
delete geDebuggerWindow ;
geDebuggerWindow = 0 ;
DialogManager : : RemoveDlg ( memoryWindow [ 0 ] ) ;
if ( memoryWindow [ 0 ] )
delete memoryWindow [ 0 ] ;
memoryWindow [ 0 ] = 0 ;
}
2013-07-29 19:34:30 +00:00
void BrowseAndBoot ( std : : string defaultPath , bool browseDirectory ) {
2014-01-20 02:44:41 +00:00
static std : : wstring filter = L " All supported file types (*.iso *.cso *.pbp *.elf *.prx *.zip)|*.pbp;*.elf;*.iso;*.cso;*.prx;*.zip|PSP ROMs (*.iso *.cso *.pbp *.elf *.prx)|*.pbp;*.elf;*.iso;*.cso;*.prx|Homebrew/Demos installers (*.zip)|*.zip|All files (*.*)|*.*|| " ;
for ( int i = 0 ; i < ( int ) filter . length ( ) ; i + + ) {
2012-11-01 15:19:01 +00:00
if ( filter [ i ] = = ' | ' )
filter [ i ] = ' \0 ' ;
}
2014-01-20 02:44:41 +00:00
browsePauseAfter = false ;
2014-06-22 07:38:46 +00:00
if ( GetUIState ( ) = = UISTATE_INGAME ) {
2014-01-20 02:44:41 +00:00
browsePauseAfter = Core_IsStepping ( ) ;
if ( ! browsePauseAfter )
2013-07-17 05:33:26 +00:00
Core_EnableStepping ( true ) ;
}
2014-01-20 02:44:41 +00:00
W32Util : : MakeTopMost ( GetHWND ( ) , false ) ;
2013-07-29 19:34:30 +00:00
if ( browseDirectory ) {
2014-01-20 02:44:41 +00:00
browseDialog = new W32Util : : AsyncBrowseDialog ( GetHWND ( ) , WM_USER_BROWSE_BOOT_DONE , L " Choose directory " ) ;
} else {
browseDialog = new W32Util : : AsyncBrowseDialog ( W32Util : : AsyncBrowseDialog : : OPEN , GetHWND ( ) , WM_USER_BROWSE_BOOT_DONE , L " LoadFile " , ConvertUTF8ToWString ( defaultPath ) , filter , L " *.pbp;*.elf;*.iso;*.cso; " ) ;
2013-07-23 15:24:33 +00:00
}
2014-01-20 02:44:41 +00:00
}
void BrowseAndBootDone ( ) {
std : : string filename ;
if ( ! browseDialog - > GetResult ( filename ) ) {
if ( ! browsePauseAfter ) {
Core_EnableStepping ( false ) ;
}
} else {
2014-06-22 07:38:46 +00:00
if ( GetUIState ( ) = = UISTATE_INGAME | | GetUIState ( ) = = UISTATE_PAUSEMENU ) {
2013-07-17 05:33:26 +00:00
Core_EnableStepping ( false ) ;
}
2014-01-20 02:44:41 +00:00
// TODO: What is this for / what does it fix?
if ( browseDialog - > GetType ( ) ! = W32Util : : AsyncBrowseDialog : : DIR ) {
// Decode the filename with fullpath.
char drive [ MAX_PATH ] ;
char dir [ MAX_PATH ] ;
char fname [ MAX_PATH ] ;
char ext [ MAX_PATH ] ;
_splitpath ( filename . c_str ( ) , drive , dir , fname , ext ) ;
filename = std : : string ( drive ) + std : : string ( dir ) + std : : string ( fname ) + std : : string ( ext ) ;
}
filename = ReplaceAll ( filename , " \\ " , " / " ) ;
NativeMessageReceived ( " boot " , filename . c_str ( ) ) ;
2013-07-17 05:33:26 +00:00
}
2014-01-20 02:44:41 +00:00
W32Util : : MakeTopMost ( GetHWND ( ) , g_Config . bTopMost ) ;
delete browseDialog ;
browseDialog = 0 ;
2012-11-01 15:19:01 +00:00
}
2013-11-27 13:57:17 +00:00
void UmdSwitchAction ( ) {
std : : string fn ;
std : : string filter = " PSP ROMs (*.iso *.cso *.pbp *.elf)|*.pbp;*.elf;*.iso;*.cso;*.prx|All files (*.*)|*.*|| " ;
for ( int i = 0 ; i < ( int ) filter . length ( ) ; i + + ) {
if ( filter [ i ] = = ' | ' )
filter [ i ] = ' \0 ' ;
}
if ( W32Util : : BrowseForFileName ( true , GetHWND ( ) , L " Switch Umd " , 0 , ConvertUTF8ToWString ( filter ) . c_str ( ) , L " *.pbp;*.elf;*.iso;*.cso; " , fn ) ) {
fn = ReplaceAll ( fn , " \\ " , " / " ) ;
__UmdReplace ( fn ) ;
}
}
2014-06-29 20:13:53 +00:00
LRESULT CALLBACK DisplayProc ( HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam ) {
2013-09-24 03:56:32 +00:00
// Only apply a factor > 1 in windowed mode.
2015-05-15 16:04:05 +00:00
int factor = ! IsZoomed ( GetHWND ( ) ) & & ! g_Config . bFullScreen & & IsWindowSmall ( ) ? 2 : 1 ;
2014-06-23 18:04:31 +00:00
static bool firstErase = true ;
2013-09-24 03:56:32 +00:00
2013-07-29 19:34:30 +00:00
switch ( message ) {
2014-06-29 20:13:53 +00:00
case WM_ACTIVATE :
if ( wParam = = WA_ACTIVE | | wParam = = WA_CLICKACTIVE ) {
g_activeWindow = WINDOW_MAINWINDOW ;
2014-06-29 11:11:06 +00:00
}
2012-11-01 15:19:01 +00:00
break ;
2013-03-29 18:32:20 +00:00
2014-06-29 20:13:53 +00:00
case WM_SETFOCUS :
break ;
2014-06-23 18:23:11 +00:00
2012-11-01 15:19:01 +00:00
case WM_ERASEBKGND :
2014-06-23 18:04:31 +00:00
if ( firstErase ) {
firstErase = false ;
// Paint black on first erase while OpenGL stuff is loading
return DefWindowProc ( hWnd , message , wParam , lParam ) ;
}
// Then never erase, let the OpenGL drawing take care of everything.
return 1 ;
2013-03-29 18:32:20 +00:00
2013-06-01 21:34:50 +00:00
// Poor man's touch - mouse input. We send the data both as an input_state pointer,
// and as asynchronous touch events for minimal latency.
2012-11-01 15:19:01 +00:00
case WM_LBUTTONDOWN :
2014-02-24 12:28:20 +00:00
if ( ! touchHandler . hasTouch ( ) | |
( GetMessageExtraInfo ( ) & MOUSEEVENTF_MASK_PLUS_PENTOUCH ) ! = MOUSEEVENTF_FROMTOUCH_NOPEN )
2014-01-23 17:05:42 +00:00
{
2013-07-09 20:51:02 +00:00
// Hack: Take the opportunity to show the cursor.
mouseButtonDown = true ;
{
lock_guard guard ( input_state . lock ) ;
input_state . mouse_valid = true ;
input_state . pointer_down [ 0 ] = true ;
2013-04-01 02:15:59 +00:00
2013-09-24 03:56:32 +00:00
input_state . pointer_x [ 0 ] = GET_X_LPARAM ( lParam ) * factor ;
input_state . pointer_y [ 0 ] = GET_Y_LPARAM ( lParam ) * factor ;
2013-07-09 20:51:02 +00:00
}
2013-06-01 21:34:50 +00:00
TouchInput touch ;
touch . id = 0 ;
touch . flags = TOUCH_DOWN ;
2013-07-09 12:46:15 +00:00
touch . x = input_state . pointer_x [ 0 ] ;
touch . y = input_state . pointer_y [ 0 ] ;
2013-06-01 21:34:50 +00:00
NativeTouch ( touch ) ;
2013-07-09 20:51:02 +00:00
SetCapture ( hWnd ) ;
2014-02-24 12:28:20 +00:00
2013-03-29 17:50:08 +00:00
}
2013-07-29 19:34:30 +00:00
break ;
2013-03-29 17:50:08 +00:00
case WM_MOUSEMOVE :
2014-02-24 12:28:20 +00:00
if ( ! touchHandler . hasTouch ( ) | |
( GetMessageExtraInfo ( ) & MOUSEEVENTF_MASK_PLUS_PENTOUCH ) ! = MOUSEEVENTF_FROMTOUCH_NOPEN )
2013-03-29 17:50:08 +00:00
{
2013-06-11 18:14:53 +00:00
// Hack: Take the opportunity to show the cursor.
mouseButtonDown = ( wParam & MK_LBUTTON ) ! = 0 ;
int cursorX = GET_X_LPARAM ( lParam ) ;
int cursorY = GET_Y_LPARAM ( lParam ) ;
if ( abs ( cursorX - prevCursorX ) > 1 | | abs ( cursorY - prevCursorY ) > 1 ) {
hideCursor = false ;
SetTimer ( hwndMain , TIMER_CURSORMOVEUPDATE , CURSORUPDATE_MOVE_TIMESPAN_MS , 0 ) ;
}
prevCursorX = cursorX ;
prevCursorY = cursorY ;
2013-07-09 20:51:02 +00:00
{
lock_guard guard ( input_state . lock ) ;
2013-09-24 03:56:32 +00:00
input_state . pointer_x [ 0 ] = GET_X_LPARAM ( lParam ) * factor ;
input_state . pointer_y [ 0 ] = GET_Y_LPARAM ( lParam ) * factor ;
2013-07-09 20:51:02 +00:00
}
2013-06-01 21:34:50 +00:00
if ( wParam & MK_LBUTTON ) {
TouchInput touch ;
touch . id = 0 ;
touch . flags = TOUCH_MOVE ;
2013-07-09 12:46:15 +00:00
touch . x = input_state . pointer_x [ 0 ] ;
touch . y = input_state . pointer_y [ 0 ] ;
2013-06-01 21:34:50 +00:00
NativeTouch ( touch ) ;
2013-04-01 02:15:59 +00:00
}
2013-03-29 17:50:08 +00:00
}
2012-11-01 15:19:01 +00:00
break ;
2013-03-29 17:50:08 +00:00
case WM_LBUTTONUP :
2014-02-24 12:28:20 +00:00
if ( ! touchHandler . hasTouch ( ) | |
( GetMessageExtraInfo ( ) & MOUSEEVENTF_MASK_PLUS_PENTOUCH ) ! = MOUSEEVENTF_FROMTOUCH_NOPEN )
2013-03-29 17:50:08 +00:00
{
2013-07-09 20:51:02 +00:00
// Hack: Take the opportunity to hide the cursor.
mouseButtonDown = false ;
{
lock_guard guard ( input_state . lock ) ;
input_state . pointer_down [ 0 ] = false ;
2013-09-24 03:56:32 +00:00
input_state . pointer_x [ 0 ] = GET_X_LPARAM ( lParam ) * factor ;
input_state . pointer_y [ 0 ] = GET_Y_LPARAM ( lParam ) * factor ;
2013-07-09 20:51:02 +00:00
}
2013-06-01 21:34:50 +00:00
TouchInput touch ;
touch . id = 0 ;
touch . flags = TOUCH_UP ;
2013-07-09 12:46:15 +00:00
touch . x = input_state . pointer_x [ 0 ] ;
touch . y = input_state . pointer_y [ 0 ] ;
2013-06-01 21:34:50 +00:00
NativeTouch ( touch ) ;
2013-07-09 20:51:02 +00:00
ReleaseCapture ( ) ;
2013-03-29 17:50:08 +00:00
}
2013-07-29 19:34:30 +00:00
break ;
2013-03-29 17:50:08 +00:00
2013-04-16 19:12:55 +00:00
case WM_TOUCH :
{
2014-01-19 21:54:49 +00:00
touchHandler . handleTouchEvent ( hWnd , message , wParam , lParam ) ;
2014-02-24 11:11:40 +00:00
return 0 ;
2013-04-16 19:12:55 +00:00
}
2014-06-29 20:13:53 +00:00
default :
return DefWindowProc ( hWnd , message , wParam , lParam ) ;
}
return 0 ;
}
LRESULT CALLBACK WndProc ( HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam ) {
int wmId , wmEvent ;
std : : string fn ;
static bool noFocusPause = false ; // TOGGLE_PAUSE state to override pause on lost focus
switch ( message ) {
case WM_CREATE :
break ;
case WM_GETMINMAXINFO :
{
MINMAXINFO * minmax = reinterpret_cast < MINMAXINFO * > ( lParam ) ;
RECT rc = { 0 } ;
2015-05-15 16:04:05 +00:00
bool portrait = g_Config . IsPortrait ( ) ;
rc . right = portrait ? 272 : 480 ;
rc . bottom = portrait ? 480 : 272 ;
2014-06-29 20:13:53 +00:00
AdjustWindowRect ( & rc , WS_OVERLAPPEDWINDOW , TRUE ) ;
minmax - > ptMinTrackSize . x = rc . right - rc . left ;
minmax - > ptMinTrackSize . y = rc . bottom - rc . top ;
}
return 0 ;
2013-09-28 12:34:08 +00:00
case WM_ACTIVATE :
2013-10-11 11:53:25 +00:00
{
bool pause = true ;
if ( wParam = = WA_ACTIVE | | wParam = = WA_CLICKACTIVE ) {
2015-03-01 00:01:41 +00:00
WindowsRawInput : : GainFocus ( ) ;
2015-02-28 22:02:03 +00:00
InputDevice : : GainFocus ( ) ;
2013-10-11 11:53:25 +00:00
g_activeWindow = WINDOW_MAINWINDOW ;
pause = false ;
}
2014-06-22 07:38:46 +00:00
if ( ! noFocusPause & & g_Config . bPauseOnLostFocus & & GetUIState ( ) = = UISTATE_INGAME ) {
2013-10-11 11:53:25 +00:00
if ( pause ! = Core_IsStepping ( ) ) { // != is xor for bools
if ( disasmWindow [ 0 ] )
SendMessage ( disasmWindow [ 0 ] - > GetDlgHandle ( ) , WM_COMMAND , IDC_STOPGO , 0 ) ;
else
Core_EnableStepping ( pause ) ;
}
}
2013-10-30 23:34:09 +00:00
if ( wParam = = WA_INACTIVE ) {
2014-01-19 19:59:11 +00:00
WindowsRawInput : : LoseFocus ( ) ;
2015-02-28 22:02:03 +00:00
InputDevice : : LoseFocus ( ) ;
2013-10-30 23:34:09 +00:00
}
2013-09-28 12:34:08 +00:00
}
break ;
2012-11-01 15:19:01 +00:00
2014-06-29 20:13:53 +00:00
case WM_ERASEBKGND :
// This window is always covered by DisplayWindow. No reason to erase.
return 1 ;
2012-11-01 15:19:01 +00:00
case WM_MOVE :
2013-03-30 16:49:02 +00:00
SavePosition ( ) ;
2013-01-26 23:15:39 +00:00
break ;
2014-06-29 20:13:53 +00:00
case WM_SIZE :
if ( ! g_inModeSwitch ) {
switch ( wParam ) {
case SIZE_MAXIMIZED :
case SIZE_RESTORED :
Core_NotifyWindowHidden ( false ) ;
2014-06-29 22:06:47 +00:00
if ( ! g_Config . bPauseWhenMinimized ) {
NativeMessageReceived ( " window minimized " , " false " ) ;
}
2014-06-29 20:13:53 +00:00
SavePosition ( ) ;
ResizeDisplay ( ) ;
2014-07-29 22:18:57 +00:00
g_WindowState = wParam ;
2014-06-29 20:13:53 +00:00
break ;
case SIZE_MINIMIZED :
2014-06-30 17:04:44 +00:00
Core_NotifyWindowHidden ( true ) ;
2014-06-29 22:06:47 +00:00
if ( ! g_Config . bPauseWhenMinimized ) {
NativeMessageReceived ( " window minimized " , " true " ) ;
}
2014-06-29 20:13:53 +00:00
break ;
default :
break ;
}
}
2015-01-18 03:49:58 +00:00
break ;
2014-06-29 20:13:53 +00:00
case WM_TIMER :
2013-05-04 21:21:06 +00:00
// Hack: Take the opportunity to also show/hide the mouse cursor in fullscreen mode.
2013-07-29 08:46:40 +00:00
switch ( wParam ) {
2013-06-11 18:14:53 +00:00
case TIMER_CURSORUPDATE :
CorrectCursor ( ) ;
return 0 ;
2013-07-29 19:34:30 +00:00
2013-06-11 18:14:53 +00:00
case TIMER_CURSORMOVEUPDATE :
hideCursor = true ;
KillTimer ( hWnd , TIMER_CURSORMOVEUPDATE ) ;
return 0 ;
}
break ;
2013-05-04 21:21:06 +00:00
2013-07-08 10:35:08 +00:00
// For some reason, need to catch this here rather than in DisplayProc.
case WM_MOUSEWHEEL :
{
int wheelDelta = ( short ) ( wParam > > 16 ) ;
KeyInput key ;
key . deviceId = DEVICE_ID_MOUSE ;
if ( wheelDelta < 0 ) {
2013-08-04 17:31:40 +00:00
key . keyCode = NKCODE_EXT_MOUSEWHEEL_DOWN ;
2013-07-08 10:35:08 +00:00
wheelDelta = - wheelDelta ;
} else {
2013-08-04 17:31:40 +00:00
key . keyCode = NKCODE_EXT_MOUSEWHEEL_UP ;
2013-07-08 10:35:08 +00:00
}
// There's no separate keyup event for mousewheel events, let's pass them both together.
// This also means it really won't work great for key mapping :( Need to build a 1 frame delay or something.
key . flags = KEY_DOWN | KEY_UP | KEY_HASWHEELDELTA | ( wheelDelta < < 16 ) ;
NativeKey ( key ) ;
}
2013-07-29 19:34:30 +00:00
break ;
2013-07-08 10:35:08 +00:00
2012-11-01 15:19:01 +00:00
case WM_COMMAND :
2013-06-03 12:30:12 +00:00
{
2013-07-29 08:46:40 +00:00
if ( ! EmuThread_Ready ( ) )
return DefWindowProc ( hWnd , message , wParam , lParam ) ;
I18NCategory * g = GetI18NCategory ( " Graphics " ) ;
wmId = LOWORD ( wParam ) ;
wmEvent = HIWORD ( wParam ) ;
// Parse the menu selections:
switch ( wmId ) {
case ID_FILE_LOAD :
BrowseAndBoot ( " " ) ;
break ;
2013-03-28 19:26:24 +00:00
2013-07-29 08:46:40 +00:00
case ID_FILE_LOAD_DIR :
BrowseAndBoot ( " " , true ) ;
break ;
2013-07-23 15:24:33 +00:00
2013-07-29 08:46:40 +00:00
case ID_FILE_LOAD_MEMSTICK :
2013-10-15 06:03:39 +00:00
BrowseAndBoot ( GetSysDirectory ( DIRECTORY_GAME ) ) ;
2013-07-29 08:46:40 +00:00
break ;
2012-11-01 15:19:01 +00:00
2013-07-29 08:46:40 +00:00
case ID_FILE_MEMSTICK :
2014-10-19 21:20:51 +00:00
ShellExecute ( NULL , L " open " , ConvertUTF8ToWString ( g_Config . memStickDirectory ) . c_str ( ) , 0 , 0 , SW_SHOW ) ;
2013-07-29 08:46:40 +00:00
break ;
2012-11-01 15:19:01 +00:00
2013-07-29 08:46:40 +00:00
case ID_TOGGLE_PAUSE :
2014-06-22 07:38:46 +00:00
if ( GetUIState ( ) = = UISTATE_PAUSEMENU ) {
2013-08-20 15:07:01 +00:00
// Causes hang
//NativeMessageReceived("run", "");
2013-07-29 08:46:40 +00:00
if ( disasmWindow [ 0 ] )
2013-08-17 08:57:29 +00:00
SendMessage ( disasmWindow [ 0 ] - > GetDlgHandle ( ) , WM_COMMAND , IDC_STOPGO , 0 ) ;
2013-07-29 08:46:40 +00:00
}
else if ( Core_IsStepping ( ) ) { // It is paused, then continue to run.
if ( disasmWindow [ 0 ] )
2013-08-17 08:57:29 +00:00
SendMessage ( disasmWindow [ 0 ] - > GetDlgHandle ( ) , WM_COMMAND , IDC_STOPGO , 0 ) ;
2013-07-29 08:46:40 +00:00
else
Core_EnableStepping ( false ) ;
} else {
if ( disasmWindow [ 0 ] )
2013-08-17 08:57:29 +00:00
SendMessage ( disasmWindow [ 0 ] - > GetDlgHandle ( ) , WM_COMMAND , IDC_STOPGO , 0 ) ;
2013-07-29 08:46:40 +00:00
else
Core_EnableStepping ( true ) ;
}
2013-10-11 11:53:25 +00:00
noFocusPause = ! noFocusPause ; // If we pause, override pause on lost focus
2013-07-29 08:46:40 +00:00
break ;
2013-03-28 19:17:45 +00:00
2013-07-29 08:46:40 +00:00
case ID_EMULATION_STOP :
2013-12-06 06:30:24 +00:00
if ( Core_IsStepping ( ) )
Core_EnableStepping ( false ) ;
2013-10-12 09:19:35 +00:00
Core_Stop ( ) ;
2013-07-29 08:46:40 +00:00
NativeMessageReceived ( " stop " , " " ) ;
2013-10-12 09:19:35 +00:00
Core_WaitInactive ( ) ;
2013-07-29 08:46:40 +00:00
Update ( ) ;
break ;
2012-11-01 15:19:01 +00:00
2013-07-29 08:46:40 +00:00
case ID_EMULATION_RESET :
NativeMessageReceived ( " reset " , " " ) ;
2013-10-12 09:08:18 +00:00
Core_EnableStepping ( false ) ;
2013-07-29 08:46:40 +00:00
break ;
2014-06-23 18:04:31 +00:00
2013-11-27 13:57:17 +00:00
case ID_EMULATION_SWITCH_UMD :
UmdSwitchAction ( ) ;
break ;
2013-09-27 02:44:29 +00:00
2013-08-24 09:43:14 +00:00
case ID_EMULATION_CHEATS :
2013-09-02 13:33:00 +00:00
g_Config . bEnableCheats = ! g_Config . bEnableCheats ;
osm . ShowOnOff ( g - > T ( " Cheats " ) , g_Config . bEnableCheats ) ;
2013-08-24 03:28:21 +00:00
break ;
2012-11-01 15:19:01 +00:00
2013-07-29 08:46:40 +00:00
case ID_FILE_LOADSTATEFILE :
2013-08-26 19:32:05 +00:00
if ( W32Util : : BrowseForFileName ( true , hWnd , L " Load state " , 0 , L " Save States (*.ppst) \0 *.ppst \0 All files \0 *.* \0 \0 " , L " ppst " , fn ) ) {
2013-07-29 08:46:40 +00:00
SetCursor ( LoadCursor ( 0 , IDC_WAIT ) ) ;
SaveState : : Load ( fn , SaveStateActionFinished ) ;
}
break ;
2012-11-01 15:19:01 +00:00
2013-07-29 08:46:40 +00:00
case ID_FILE_SAVESTATEFILE :
2013-08-26 19:32:05 +00:00
if ( W32Util : : BrowseForFileName ( false , hWnd , L " Save state " , 0 , L " Save States (*.ppst) \0 *.ppst \0 All files \0 *.* \0 \0 " , L " ppst " , fn ) ) {
2013-07-29 08:46:40 +00:00
SetCursor ( LoadCursor ( 0 , IDC_WAIT ) ) ;
SaveState : : Save ( fn , SaveStateActionFinished ) ;
}
break ;
case ID_FILE_SAVESTATE_NEXT_SLOT :
2012-11-01 15:19:01 +00:00
{
2014-01-07 14:56:04 +00:00
SaveState : : NextSlot ( ) ;
2013-07-29 08:46:40 +00:00
break ;
2012-11-01 15:19:01 +00:00
}
2014-06-06 08:51:59 +00:00
case ID_FILE_SAVESTATE_NEXT_SLOT_HC :
{
2015-01-19 17:01:55 +00:00
if ( KeyMap : : g_controllerMap [ VIRTKEY_NEXT_SLOT ] . empty ( ) )
2014-06-06 08:51:59 +00:00
{
SaveState : : NextSlot ( ) ;
}
break ;
}
2013-09-10 22:19:34 +00:00
case ID_FILE_SAVESTATE_SLOT_1 : g_Config . iCurrentStateSlot = 0 ; break ;
case ID_FILE_SAVESTATE_SLOT_2 : g_Config . iCurrentStateSlot = 1 ; break ;
case ID_FILE_SAVESTATE_SLOT_3 : g_Config . iCurrentStateSlot = 2 ; break ;
case ID_FILE_SAVESTATE_SLOT_4 : g_Config . iCurrentStateSlot = 3 ; break ;
case ID_FILE_SAVESTATE_SLOT_5 : g_Config . iCurrentStateSlot = 4 ; break ;
2013-09-07 15:29:44 +00:00
2013-07-29 08:46:40 +00:00
case ID_FILE_QUICKLOADSTATE :
2014-06-06 08:51:59 +00:00
{
2013-07-09 20:25:29 +00:00
SetCursor ( LoadCursor ( 0 , IDC_WAIT ) ) ;
2013-09-07 15:29:44 +00:00
SaveState : : LoadSlot ( g_Config . iCurrentStateSlot , SaveStateActionFinished ) ;
2013-07-29 08:46:40 +00:00
break ;
2014-06-06 08:51:59 +00:00
}
2012-11-01 15:19:01 +00:00
2014-06-06 08:51:59 +00:00
case ID_FILE_QUICKLOADSTATE_HC :
{
2015-01-19 17:01:55 +00:00
if ( KeyMap : : g_controllerMap [ VIRTKEY_LOAD_STATE ] . empty ( ) )
2014-06-06 08:51:59 +00:00
{
SetCursor ( LoadCursor ( 0 , IDC_WAIT ) ) ;
SaveState : : LoadSlot ( g_Config . iCurrentStateSlot , SaveStateActionFinished ) ;
}
break ;
}
2013-07-29 08:46:40 +00:00
case ID_FILE_QUICKSAVESTATE :
2014-06-06 08:51:59 +00:00
{
2013-07-29 08:46:40 +00:00
SetCursor ( LoadCursor ( 0 , IDC_WAIT ) ) ;
2013-09-07 15:29:44 +00:00
SaveState : : SaveSlot ( g_Config . iCurrentStateSlot , SaveStateActionFinished ) ;
2013-07-29 08:46:40 +00:00
break ;
2014-06-06 08:51:59 +00:00
}
case ID_FILE_QUICKSAVESTATE_HC :
{
2015-01-19 17:01:55 +00:00
if ( KeyMap : : g_controllerMap [ VIRTKEY_SAVE_STATE ] . empty ( ) )
2014-06-06 08:51:59 +00:00
{
SetCursor ( LoadCursor ( 0 , IDC_WAIT ) ) ;
SaveState : : SaveSlot ( g_Config . iCurrentStateSlot , SaveStateActionFinished ) ;
break ;
}
}
2013-01-02 20:00:10 +00:00
2013-11-03 00:24:19 +00:00
case ID_OPTIONS_LANGUAGE :
NativeMessageReceived ( " language screen " , " " ) ;
break ;
2014-01-07 21:08:11 +00:00
case ID_OPTIONS_IGNOREWINKEY :
g_Config . bIgnoreWindowsKey = ! g_Config . bIgnoreWindowsKey ;
break ;
2013-09-20 03:27:25 +00:00
case ID_OPTIONS_SCREENAUTO : SetInternalResolution ( RESOLUTION_AUTO ) ; break ;
case ID_OPTIONS_SCREEN1X : SetInternalResolution ( RESOLUTION_NATIVE ) ; break ;
case ID_OPTIONS_SCREEN2X : SetInternalResolution ( RESOLUTION_2X ) ; break ;
case ID_OPTIONS_SCREEN3X : SetInternalResolution ( RESOLUTION_3X ) ; break ;
case ID_OPTIONS_SCREEN4X : SetInternalResolution ( RESOLUTION_4X ) ; break ;
case ID_OPTIONS_SCREEN5X : SetInternalResolution ( RESOLUTION_5X ) ; break ;
case ID_OPTIONS_SCREEN6X : SetInternalResolution ( RESOLUTION_6X ) ; break ;
case ID_OPTIONS_SCREEN7X : SetInternalResolution ( RESOLUTION_7X ) ; break ;
case ID_OPTIONS_SCREEN8X : SetInternalResolution ( RESOLUTION_8X ) ; break ;
case ID_OPTIONS_SCREEN9X : SetInternalResolution ( RESOLUTION_9X ) ; break ;
case ID_OPTIONS_SCREEN10X : SetInternalResolution ( RESOLUTION_MAX ) ; break ;
2013-07-29 08:46:40 +00:00
2013-09-10 22:19:34 +00:00
case ID_OPTIONS_WINDOW1X : SetWindowSize ( 1 ) ; break ;
case ID_OPTIONS_WINDOW2X : SetWindowSize ( 2 ) ; break ;
case ID_OPTIONS_WINDOW3X : SetWindowSize ( 3 ) ; break ;
case ID_OPTIONS_WINDOW4X : SetWindowSize ( 4 ) ; break ;
2013-09-11 02:20:14 +00:00
case ID_OPTIONS_RESOLUTIONDUMMY :
{
2013-09-19 18:32:56 +00:00
SetInternalResolution ( ) ;
2013-09-11 02:20:14 +00:00
break ;
}
2013-07-29 08:46:40 +00:00
case ID_OPTIONS_VSYNC :
g_Config . bVSync = ! g_Config . bVSync ;
2013-07-26 12:25:11 +00:00
break ;
2013-10-12 00:05:55 +00:00
2014-01-25 16:41:39 +00:00
case ID_OPTIONS_FRAMESKIP_AUTO :
g_Config . bAutoFrameSkip = ! g_Config . bAutoFrameSkip ;
2015-02-09 22:10:57 +00:00
if ( g_Config . bAutoFrameSkip & & g_Config . iRenderingMode = = FB_NON_BUFFERED_MODE )
g_Config . iRenderingMode = FB_BUFFERED_MODE ;
2014-01-25 16:41:39 +00:00
break ;
2013-10-11 06:49:45 +00:00
case ID_TEXTURESCALING_AUTO : setTexScalingMultiplier ( TEXSCALING_AUTO ) ; break ;
2013-09-10 22:19:34 +00:00
case ID_TEXTURESCALING_OFF : setTexScalingMultiplier ( TEXSCALING_OFF ) ; break ;
case ID_TEXTURESCALING_2X : setTexScalingMultiplier ( TEXSCALING_2X ) ; break ;
case ID_TEXTURESCALING_3X : setTexScalingMultiplier ( TEXSCALING_3X ) ; break ;
case ID_TEXTURESCALING_4X : setTexScalingMultiplier ( TEXSCALING_4X ) ; break ;
case ID_TEXTURESCALING_5X : setTexScalingMultiplier ( TEXSCALING_MAX ) ; break ;
2013-07-21 15:17:42 +00:00
2013-09-10 22:19:34 +00:00
case ID_TEXTURESCALING_XBRZ : setTexScalingType ( TextureScaler : : XBRZ ) ; break ;
case ID_TEXTURESCALING_HYBRID : setTexScalingType ( TextureScaler : : HYBRID ) ; break ;
case ID_TEXTURESCALING_BICUBIC : setTexScalingType ( TextureScaler : : BICUBIC ) ; break ;
case ID_TEXTURESCALING_HYBRID_BICUBIC : setTexScalingType ( TextureScaler : : HYBRID_BICUBIC ) ; break ;
2012-11-20 10:35:48 +00:00
2013-07-29 08:46:40 +00:00
case ID_TEXTURESCALING_DEPOSTERIZE :
g_Config . bTexDeposterize = ! g_Config . bTexDeposterize ;
2013-10-12 17:19:23 +00:00
NativeMessageReceived ( " gpu clear cache " , " " ) ;
2013-07-29 08:46:40 +00:00
break ;
2013-07-23 21:05:58 +00:00
2014-09-14 11:30:49 +00:00
case ID_OPTIONS_DIRECTX :
g_Config . iTempGPUBackend = GPU_BACKEND_DIRECT3D9 ;
g_Config . bRestartRequired = true ;
PostMessage ( MainWindow : : GetHWND ( ) , WM_CLOSE , 0 , 0 ) ;
break ;
case ID_OPTIONS_OPENGL :
g_Config . iTempGPUBackend = GPU_BACKEND_OPENGL ;
g_Config . bRestartRequired = true ;
PostMessage ( MainWindow : : GetHWND ( ) , WM_CLOSE , 0 , 0 ) ;
break ;
2013-09-10 22:19:34 +00:00
case ID_OPTIONS_NONBUFFEREDRENDERING : setRenderingMode ( FB_NON_BUFFERED_MODE ) ; break ;
case ID_OPTIONS_BUFFEREDRENDERING : setRenderingMode ( FB_BUFFERED_MODE ) ; break ;
case ID_OPTIONS_READFBOTOMEMORYCPU : setRenderingMode ( FB_READFBOMEMORY_CPU ) ; break ;
case ID_OPTIONS_READFBOTOMEMORYGPU : setRenderingMode ( FB_READFBOMEMORY_GPU ) ; break ;
2013-07-29 08:46:40 +00:00
// Dummy option to let the buffered rendering hotkey cycle through all the options.
case ID_OPTIONS_BUFFEREDRENDERINGDUMMY :
2013-09-20 01:18:26 +00:00
setRenderingMode ( ) ;
2013-07-23 21:05:58 +00:00
break ;
2013-07-29 08:46:40 +00:00
2013-09-07 15:29:44 +00:00
case ID_DEBUG_SHOWDEBUGSTATISTICS :
2013-07-29 08:46:40 +00:00
g_Config . bShowDebugStats = ! g_Config . bShowDebugStats ;
2013-11-02 20:33:27 +00:00
NativeMessageReceived ( " clear jit " , " " ) ;
2013-07-23 21:05:58 +00:00
break ;
2013-07-29 08:46:40 +00:00
case ID_OPTIONS_HARDWARETRANSFORM :
g_Config . bHardwareTransform = ! g_Config . bHardwareTransform ;
osm . ShowOnOff ( g - > T ( " Hardware Transform " ) , g_Config . bHardwareTransform ) ;
break ;
2013-07-23 21:05:58 +00:00
2013-07-29 08:46:40 +00:00
case ID_OPTIONS_STRETCHDISPLAY :
g_Config . bStretchToDisplay = ! g_Config . bStretchToDisplay ;
2013-10-12 17:19:23 +00:00
NativeMessageReceived ( " gpu resized " , " " ) ;
2013-07-29 08:46:40 +00:00
break ;
2013-07-23 21:05:58 +00:00
2013-09-10 22:19:34 +00:00
case ID_OPTIONS_FRAMESKIP_0 : setFrameSkipping ( FRAMESKIP_OFF ) ; break ;
case ID_OPTIONS_FRAMESKIP_1 : setFrameSkipping ( FRAMESKIP_1 ) ; break ;
case ID_OPTIONS_FRAMESKIP_2 : setFrameSkipping ( FRAMESKIP_2 ) ; break ;
case ID_OPTIONS_FRAMESKIP_3 : setFrameSkipping ( FRAMESKIP_3 ) ; break ;
case ID_OPTIONS_FRAMESKIP_4 : setFrameSkipping ( FRAMESKIP_4 ) ; break ;
case ID_OPTIONS_FRAMESKIP_5 : setFrameSkipping ( FRAMESKIP_5 ) ; break ;
case ID_OPTIONS_FRAMESKIP_6 : setFrameSkipping ( FRAMESKIP_6 ) ; break ;
case ID_OPTIONS_FRAMESKIP_7 : setFrameSkipping ( FRAMESKIP_7 ) ; break ;
case ID_OPTIONS_FRAMESKIP_8 : setFrameSkipping ( FRAMESKIP_MAX ) ; break ;
2013-07-26 12:25:11 +00:00
2013-07-29 08:46:40 +00:00
case ID_OPTIONS_FRAMESKIPDUMMY :
2013-09-20 01:18:26 +00:00
setFrameSkipping ( ) ;
2013-07-26 12:25:11 +00:00
break ;
2013-07-29 08:46:40 +00:00
case ID_FILE_EXIT :
2014-04-11 18:18:27 +00:00
PostMessage ( hwndMain , WM_CLOSE , 0 , 0 ) ;
2013-07-26 12:25:11 +00:00
break ;
2013-07-29 08:46:40 +00:00
2013-09-07 15:29:44 +00:00
case ID_DEBUG_RUNONLOAD :
2013-07-29 08:46:40 +00:00
g_Config . bAutoRun = ! g_Config . bAutoRun ;
2013-07-26 12:25:11 +00:00
break ;
2013-07-29 08:46:40 +00:00
case ID_DEBUG_DUMPNEXTFRAME :
2013-10-12 17:19:23 +00:00
NativeMessageReceived ( " gpu dump next frame " , " " ) ;
2013-07-26 12:25:11 +00:00
break ;
2013-07-29 08:46:40 +00:00
case ID_DEBUG_LOADMAPFILE :
2014-01-26 05:12:16 +00:00
if ( W32Util : : BrowseForFileName ( true , hWnd , L " Load .ppmap " , 0 , L " Maps \0 *.ppmap \0 All files \0 *.* \0 \0 " , L " ppmap " , fn ) ) {
2013-07-29 08:46:40 +00:00
symbolMap . LoadSymbolMap ( fn . c_str ( ) ) ;
if ( disasmWindow [ 0 ] )
disasmWindow [ 0 ] - > NotifyMapLoaded ( ) ;
if ( memoryWindow [ 0 ] )
memoryWindow [ 0 ] - > NotifyMapLoaded ( ) ;
}
2013-07-26 12:25:11 +00:00
break ;
2013-07-29 08:46:40 +00:00
case ID_DEBUG_SAVEMAPFILE :
2014-01-26 05:12:16 +00:00
if ( W32Util : : BrowseForFileName ( false , hWnd , L " Save .ppmap " , 0 , L " Maps \0 *.ppmap \0 All files \0 *.* \0 \0 " , L " ppmap " , fn ) )
2013-07-29 08:46:40 +00:00
symbolMap . SaveSymbolMap ( fn . c_str ( ) ) ;
2013-07-26 12:25:11 +00:00
break ;
2014-06-29 22:02:22 +00:00
case ID_DEBUG_LOADSYMFILE :
if ( W32Util : : BrowseForFileName ( true , hWnd , L " Load .sym " , 0 , L " Symbols \0 *.sym \0 All files \0 *.* \0 \0 " , L " sym " , fn ) ) {
symbolMap . LoadNocashSym ( fn . c_str ( ) ) ;
if ( disasmWindow [ 0 ] )
disasmWindow [ 0 ] - > NotifyMapLoaded ( ) ;
if ( memoryWindow [ 0 ] )
memoryWindow [ 0 ] - > NotifyMapLoaded ( ) ;
}
break ;
case ID_DEBUG_SAVESYMFILE :
if ( W32Util : : BrowseForFileName ( false , hWnd , L " Save .sym " , 0 , L " Symbols \0 *.sym \0 All files \0 *.* \0 \0 " , L " sym " , fn ) )
symbolMap . SaveNocashSym ( fn . c_str ( ) ) ;
break ;
2013-10-18 13:07:04 +00:00
2013-07-29 08:46:40 +00:00
case ID_DEBUG_RESETSYMBOLTABLE :
2013-10-18 13:07:04 +00:00
symbolMap . Clear ( ) ;
2013-07-29 08:46:40 +00:00
for ( int i = 0 ; i < numCPUs ; i + + )
if ( disasmWindow [ i ] )
disasmWindow [ i ] - > NotifyMapLoaded ( ) ;
for ( int i = 0 ; i < numCPUs ; i + + )
if ( memoryWindow [ i ] )
memoryWindow [ i ] - > NotifyMapLoaded ( ) ;
2013-07-26 12:25:11 +00:00
break ;
2013-07-29 08:46:40 +00:00
case ID_DEBUG_DISASSEMBLY :
2014-02-15 05:17:36 +00:00
if ( disasmWindow [ 0 ] )
disasmWindow [ 0 ] - > Show ( true ) ;
2013-07-26 12:25:11 +00:00
break ;
2013-07-29 08:46:40 +00:00
2013-09-22 17:27:09 +00:00
case ID_DEBUG_GEDEBUGGER :
2014-02-15 05:17:36 +00:00
if ( geDebuggerWindow )
geDebuggerWindow - > Show ( true ) ;
2013-09-22 17:27:09 +00:00
break ;
2013-07-29 08:46:40 +00:00
case ID_DEBUG_MEMORYVIEW :
2014-02-15 05:17:36 +00:00
if ( memoryWindow [ 0 ] )
memoryWindow [ 0 ] - > Show ( true ) ;
2013-07-26 12:25:11 +00:00
break ;
2014-01-02 00:45:37 +00:00
case ID_DEBUG_EXTRACTFILE :
{
std : : string filename ;
if ( ! InputBox_GetString ( hInst , hwndMain , L " Disc filename " , filename , filename ) ) {
break ;
}
const char * lastSlash = strrchr ( filename . c_str ( ) , ' / ' ) ;
if ( lastSlash ) {
fn = lastSlash + 1 ;
} else {
fn = " " ;
}
PSPFileInfo info = pspFileSystem . GetFileInfo ( filename ) ;
if ( ! info . exists ) {
MessageBox ( hwndMain , L " File does not exist. " , L " Sorry " , 0 ) ;
} else if ( info . type = = FILETYPE_DIRECTORY ) {
MessageBox ( hwndMain , L " Cannot extract directories. " , L " Sorry " , 0 ) ;
2014-03-01 21:31:23 +00:00
} else if ( W32Util : : BrowseForFileName ( false , hWnd , L " Save file as... " , 0 , L " All files \0 *.* \0 \0 " , L " " , fn ) ) {
2014-01-02 00:45:37 +00:00
FILE * fp = fopen ( fn . c_str ( ) , " wb " ) ;
u32 handle = pspFileSystem . OpenFile ( filename , FILEACCESS_READ , " " ) ;
u8 buffer [ 4096 ] ;
while ( pspFileSystem . ReadFile ( handle , buffer , sizeof ( buffer ) ) > 0 ) {
fwrite ( buffer , sizeof ( buffer ) , 1 , fp ) ;
}
pspFileSystem . CloseFile ( handle ) ;
fclose ( fp ) ;
}
}
break ;
2013-07-29 08:46:40 +00:00
case ID_DEBUG_LOG :
LogManager : : GetInstance ( ) - > GetConsoleListener ( ) - > Show ( LogManager : : GetInstance ( ) - > GetConsoleListener ( ) - > Hidden ( ) ) ;
break ;
2013-07-26 12:25:11 +00:00
2013-09-07 15:29:44 +00:00
case ID_DEBUG_IGNOREILLEGALREADS :
2013-07-29 08:46:40 +00:00
g_Config . bIgnoreBadMemAccess = ! g_Config . bIgnoreBadMemAccess ;
break ;
2013-02-18 23:44:22 +00:00
2013-07-29 08:46:40 +00:00
case ID_OPTIONS_FULLSCREEN :
2015-02-15 22:07:24 +00:00
PostMessage ( hWnd , WM_USER_TOGGLE_FULLSCREEN , 0 , 0 ) ;
2013-07-29 08:46:40 +00:00
break ;
2012-11-01 15:19:01 +00:00
2013-07-29 08:46:40 +00:00
case ID_OPTIONS_VERTEXCACHE :
g_Config . bVertexCache = ! g_Config . bVertexCache ;
break ;
2013-03-29 20:21:27 +00:00
2013-07-29 08:46:40 +00:00
case ID_OPTIONS_SHOWFPS :
g_Config . iShowFPSCounter = ! g_Config . iShowFPSCounter ;
break ;
2012-11-01 15:19:01 +00:00
2013-09-10 22:19:34 +00:00
case ID_OPTIONS_TEXTUREFILTERING_AUTO : setTexFiltering ( AUTO ) ; break ;
case ID_OPTIONS_NEARESTFILTERING : setTexFiltering ( NEAREST ) ; break ;
case ID_OPTIONS_LINEARFILTERING : setTexFiltering ( LINEAR ) ; break ;
case ID_OPTIONS_LINEARFILTERING_CG : setTexFiltering ( LINEARFMV ) ; break ;
2013-06-10 21:45:12 +00:00
2014-08-08 18:51:15 +00:00
case ID_OPTIONS_BUFLINEARFILTER : setBufFilter ( SCALE_LINEAR ) ; break ;
case ID_OPTIONS_BUFNEARESTFILTER : setBufFilter ( SCALE_NEAREST ) ; break ;
2013-07-29 08:46:40 +00:00
case ID_OPTIONS_TOPMOST :
g_Config . bTopMost = ! g_Config . bTopMost ;
W32Util : : MakeTopMost ( hWnd , g_Config . bTopMost ) ;
break ;
2013-07-06 17:08:59 +00:00
2013-10-11 11:53:25 +00:00
case ID_OPTIONS_PAUSE_FOCUS :
g_Config . bPauseOnLostFocus = ! g_Config . bPauseOnLostFocus ;
break ;
2013-07-29 08:46:40 +00:00
case ID_OPTIONS_CONTROLS :
2013-09-07 15:29:44 +00:00
NativeMessageReceived ( " control mapping " , " " ) ;
break ;
case ID_OPTIONS_MORE_SETTINGS :
NativeMessageReceived ( " settings " , " " ) ;
2013-07-29 08:46:40 +00:00
break ;
2013-06-15 09:40:31 +00:00
2013-07-29 08:46:40 +00:00
case ID_EMULATION_SOUND :
g_Config . bEnableSound = ! g_Config . bEnableSound ;
2013-12-11 00:31:29 +00:00
if ( g_Config . bEnableSound ) {
2013-12-11 00:24:50 +00:00
if ( PSP_IsInited ( ) & & ! IsAudioInitialised ( ) )
2013-08-14 18:36:54 +00:00
Audio_Init ( ) ;
}
2013-07-29 08:46:40 +00:00
break ;
2012-11-01 15:19:01 +00:00
2013-07-29 08:46:40 +00:00
case ID_HELP_OPENWEBSITE :
2013-08-26 17:00:16 +00:00
ShellExecute ( NULL , L " open " , L " http://www.ppsspp.org/ " , NULL , NULL , SW_SHOWNORMAL ) ;
break ;
case ID_HELP_BUYGOLD :
ShellExecute ( NULL , L " open " , L " http://central.ppsspp.org/buygold " , NULL , NULL , SW_SHOWNORMAL ) ;
2013-07-29 08:46:40 +00:00
break ;
2012-11-01 15:19:01 +00:00
2013-07-29 08:46:40 +00:00
case ID_HELP_OPENFORUM :
2013-08-26 17:00:16 +00:00
ShellExecute ( NULL , L " open " , L " http://forums.ppsspp.org/ " , NULL , NULL , SW_SHOWNORMAL ) ;
2013-07-29 08:46:40 +00:00
break ;
case ID_HELP_ABOUT :
DialogManager : : EnableAll ( FALSE ) ;
DialogBox ( hInst , ( LPCTSTR ) IDD_ABOUTBOX , hWnd , ( DLGPROC ) About ) ;
DialogManager : : EnableAll ( TRUE ) ;
break ;
case ID_DEBUG_TAKESCREENSHOT :
g_TakeScreenshot = true ;
break ;
default :
2013-09-04 02:06:05 +00:00
{
2013-10-12 04:14:58 +00:00
// Handle the dynamic shader switching here.
// The Menu ID is contained in wParam, so subtract
// ID_SHADERS_BASE and an additional 1 off it.
2013-11-03 00:24:19 +00:00
u32 index = ( wParam - ID_SHADERS_BASE - 1 ) ;
2014-02-16 17:25:42 +00:00
if ( index < availableShaders . size ( ) ) {
2013-10-12 04:14:58 +00:00
g_Config . sPostShaderName = availableShaders [ index ] ;
2013-10-12 17:19:23 +00:00
NativeMessageReceived ( " gpu resized " , " " ) ;
2013-10-12 04:14:58 +00:00
break ;
}
2013-09-04 02:06:05 +00:00
MessageBox ( hwndMain , L " Unimplemented " , L " Sorry " , 0 ) ;
}
2013-07-29 08:46:40 +00:00
break ;
}
2013-06-03 12:30:12 +00:00
}
2012-11-01 15:19:01 +00:00
break ;
2013-07-06 17:08:59 +00:00
2015-02-15 22:07:24 +00:00
case WM_USER_TOGGLE_FULLSCREEN :
ToggleFullscreen ( hwndMain , ! g_Config . bFullScreen ) ;
break ;
2013-07-07 08:42:39 +00:00
case WM_INPUT :
2014-01-19 20:11:08 +00:00
return WindowsRawInput : : Process ( hWnd , wParam , lParam ) ;
// TODO: Could do something useful with WM_INPUT_DEVICE_CHANGE?
2013-05-13 09:13:49 +00:00
2014-06-29 21:29:49 +00:00
// Not sure why we are actually getting WM_CHAR even though we use RawInput, but alright..
case WM_CHAR :
return WindowsRawInput : : ProcessChar ( hWnd , wParam , lParam ) ;
2013-12-01 02:21:47 +00:00
case WM_VERYSLEEPY_MSG :
switch ( wParam ) {
case VERYSLEEPY_WPARAM_SUPPORTED :
return TRUE ;
case VERYSLEEPY_WPARAM_GETADDRINFO :
{
VerySleepy_AddrInfo * info = ( VerySleepy_AddrInfo * ) lParam ;
const u8 * ptr = ( const u8 * ) info - > addr ;
2013-12-19 07:57:39 +00:00
std : : string name ;
2013-12-01 02:21:47 +00:00
2013-12-19 07:57:39 +00:00
if ( MIPSComp : : jit & & MIPSComp : : jit - > DescribeCodePtr ( ptr , name ) ) {
swprintf_s ( info - > name , L " Jit::%S " , name . c_str ( ) ) ;
return TRUE ;
2013-12-01 02:21:47 +00:00
}
2013-12-19 07:57:39 +00:00
if ( gpu & & gpu - > DescribeCodePtr ( ptr , name ) ) {
swprintf_s ( info - > name , L " GPU::%S " , name . c_str ( ) ) ;
return TRUE ;
2013-12-01 02:39:16 +00:00
}
2013-12-01 02:21:47 +00:00
}
return FALSE ;
default :
return FALSE ;
}
break ;
2012-11-01 15:19:01 +00:00
case WM_DROPFILES :
{
2013-06-08 00:32:07 +00:00
if ( ! EmuThread_Ready ( ) )
return DefWindowProc ( hWnd , message , wParam , lParam ) ;
2012-11-01 15:19:01 +00:00
HDROP hdrop = ( HDROP ) wParam ;
int count = DragQueryFile ( hdrop , 0xFFFFFFFF , 0 , 0 ) ;
2013-07-29 08:46:40 +00:00
if ( count ! = 1 ) {
2013-08-26 17:00:16 +00:00
MessageBox ( hwndMain , L " You can only load one file at a time " , L " Error " , MB_ICONINFORMATION ) ;
2012-11-01 15:19:01 +00:00
}
else
{
TCHAR filename [ 512 ] ;
DragQueryFile ( hdrop , 0 , filename , 512 ) ;
TCHAR * type = filename + _tcslen ( filename ) - 3 ;
2013-08-20 15:21:25 +00:00
Update ( ) ;
2012-11-01 15:19:01 +00:00
2013-08-26 17:00:16 +00:00
NativeMessageReceived ( " boot " , ConvertWStringToUTF8 ( filename ) . c_str ( ) ) ;
2013-10-16 08:19:15 +00:00
Core_EnableStepping ( false ) ;
2012-11-01 15:19:01 +00:00
}
}
break ;
case WM_CLOSE :
EmuThread_Stop ( ) ;
2014-03-24 05:18:54 +00:00
InputDevice : : StopPolling ( ) ;
2014-01-19 20:11:08 +00:00
WindowsRawInput : : Shutdown ( ) ;
2012-11-01 15:19:01 +00:00
2013-01-02 21:57:57 +00:00
return DefWindowProc ( hWnd , message , wParam , lParam ) ;
2013-01-05 18:57:06 +00:00
2012-11-01 15:19:01 +00:00
case WM_DESTROY :
2013-06-11 18:14:53 +00:00
KillTimer ( hWnd , TIMER_CURSORUPDATE ) ;
KillTimer ( hWnd , TIMER_CURSORMOVEUPDATE ) ;
2012-11-01 15:19:01 +00:00
PostQuitMessage ( 0 ) ;
break ;
2013-09-24 03:01:26 +00:00
case WM_USER + 1 :
2014-02-15 05:17:36 +00:00
if ( disasmWindow [ 0 ] )
disasmWindow [ 0 ] - > NotifyMapLoaded ( ) ;
if ( memoryWindow [ 0 ] )
memoryWindow [ 0 ] - > NotifyMapLoaded ( ) ;
2013-08-26 12:19:46 +00:00
2014-02-15 05:17:36 +00:00
if ( disasmWindow [ 0 ] )
disasmWindow [ 0 ] - > UpdateDialog ( ) ;
2012-12-22 17:21:23 +00:00
2013-04-01 01:28:13 +00:00
SetForegroundWindow ( hwndMain ) ;
2012-11-01 15:19:01 +00:00
break ;
2013-03-29 18:52:32 +00:00
2013-07-21 09:21:50 +00:00
case WM_USER_SAVESTATE_FINISH :
SetCursor ( LoadCursor ( 0 , IDC_ARROW ) ) ;
break ;
2013-03-29 18:52:32 +00:00
2013-09-01 21:06:24 +00:00
case WM_USER_UPDATE_UI :
TranslateMenus ( ) ;
Update ( ) ;
break ;
2013-09-08 04:22:38 +00:00
case WM_USER_UPDATE_SCREEN :
2014-02-12 09:36:40 +00:00
ResizeDisplay ( true ) ;
ShowScreenResolution ( ) ;
2013-09-08 04:22:38 +00:00
break ;
2013-09-13 19:17:55 +00:00
case WM_USER_WINDOW_TITLE_CHANGED :
UpdateWindowTitle ( ) ;
break ;
2014-01-20 02:44:41 +00:00
case WM_USER_BROWSE_BOOT_DONE :
BrowseAndBootDone ( ) ;
break ;
2013-03-29 18:32:20 +00:00
case WM_MENUSELECT :
2013-05-13 08:08:10 +00:00
// Unfortunately, accelerate keys (hotkeys) shares the same enabled/disabled states
// with corresponding menu items.
2013-03-29 18:32:20 +00:00
UpdateMenus ( ) ;
2014-01-20 08:57:20 +00:00
WindowsRawInput : : NotifyMenu ( ) ;
2013-03-29 18:32:20 +00:00
break ;
2012-11-01 15:19:01 +00:00
2013-05-02 18:58:10 +00:00
// Turn off the screensaver.
// Note that if there's a screensaver password, this simple method
// doesn't work on Vista or higher.
case WM_SYSCOMMAND :
{
2013-07-29 08:46:40 +00:00
switch ( wParam ) {
2013-05-02 18:58:10 +00:00
case SC_SCREENSAVE :
return 0 ;
case SC_MONITORPOWER :
return 0 ;
}
return DefWindowProc ( hWnd , message , wParam , lParam ) ;
}
2012-11-01 15:19:01 +00:00
default :
return DefWindowProc ( hWnd , message , wParam , lParam ) ;
}
return 0 ;
}
2013-07-29 08:46:40 +00:00
void UpdateMenus ( ) {
2012-11-01 15:19:01 +00:00
HMENU menu = GetMenu ( GetHWND ( ) ) ;
# define CHECKITEM(item,value) CheckMenuItem(menu,item,MF_BYCOMMAND | ((value) ? MF_CHECKED : MF_UNCHECKED));
2013-09-07 15:29:44 +00:00
CHECKITEM ( ID_DEBUG_IGNOREILLEGALREADS , g_Config . bIgnoreBadMemAccess ) ;
CHECKITEM ( ID_DEBUG_SHOWDEBUGSTATISTICS , g_Config . bShowDebugStats ) ;
2012-12-21 10:08:54 +00:00
CHECKITEM ( ID_OPTIONS_HARDWARETRANSFORM , g_Config . bHardwareTransform ) ;
2013-02-13 17:21:21 +00:00
CHECKITEM ( ID_OPTIONS_STRETCHDISPLAY , g_Config . bStretchToDisplay ) ;
2013-09-07 15:29:44 +00:00
CHECKITEM ( ID_DEBUG_RUNONLOAD , g_Config . bAutoRun ) ;
2013-01-19 16:05:08 +00:00
CHECKITEM ( ID_OPTIONS_VERTEXCACHE , g_Config . bVertexCache ) ;
2013-06-19 05:08:29 +00:00
CHECKITEM ( ID_OPTIONS_SHOWFPS , g_Config . iShowFPSCounter ) ;
2014-01-25 16:41:39 +00:00
CHECKITEM ( ID_OPTIONS_FRAMESKIP_AUTO , g_Config . bAutoFrameSkip ) ;
2013-05-02 14:48:28 +00:00
CHECKITEM ( ID_OPTIONS_FRAMESKIP , g_Config . iFrameSkip ! = 0 ) ;
2013-07-20 14:03:52 +00:00
CHECKITEM ( ID_OPTIONS_VSYNC , g_Config . bVSync ) ;
2013-06-10 21:45:12 +00:00
CHECKITEM ( ID_OPTIONS_TOPMOST , g_Config . bTopMost ) ;
2013-10-11 11:53:25 +00:00
CHECKITEM ( ID_OPTIONS_PAUSE_FOCUS , g_Config . bPauseOnLostFocus ) ;
2013-05-13 08:08:10 +00:00
CHECKITEM ( ID_EMULATION_SOUND , g_Config . bEnableSound ) ;
CHECKITEM ( ID_TEXTURESCALING_DEPOSTERIZE , g_Config . bTexDeposterize ) ;
2013-09-02 13:33:00 +00:00
CHECKITEM ( ID_EMULATION_CHEATS , g_Config . bEnableCheats ) ;
2014-01-07 21:08:11 +00:00
CHECKITEM ( ID_OPTIONS_IGNOREWINKEY , g_Config . bIgnoreWindowsKey ) ;
2013-07-28 00:47:06 +00:00
2014-03-26 00:01:37 +00:00
// Disable Vertex Cache when HW T&L is disabled.
if ( ! g_Config . bHardwareTransform ) {
EnableMenuItem ( menu , ID_OPTIONS_VERTEXCACHE , MF_GRAYED ) ;
} else {
EnableMenuItem ( menu , ID_OPTIONS_VERTEXCACHE , MF_ENABLED ) ;
}
2013-09-17 08:02:34 +00:00
static const int zoomitems [ 11 ] = {
2013-09-10 22:19:34 +00:00
ID_OPTIONS_SCREENAUTO ,
2012-11-17 16:46:05 +00:00
ID_OPTIONS_SCREEN1X ,
ID_OPTIONS_SCREEN2X ,
ID_OPTIONS_SCREEN3X ,
ID_OPTIONS_SCREEN4X ,
2013-09-10 22:19:34 +00:00
ID_OPTIONS_SCREEN5X ,
2013-09-17 08:02:34 +00:00
ID_OPTIONS_SCREEN6X ,
ID_OPTIONS_SCREEN7X ,
ID_OPTIONS_SCREEN8X ,
ID_OPTIONS_SCREEN9X ,
ID_OPTIONS_SCREEN10X ,
2012-11-17 16:46:05 +00:00
} ;
2013-09-20 01:18:26 +00:00
if ( g_Config . iInternalResolution < RESOLUTION_AUTO )
g_Config . iInternalResolution = RESOLUTION_AUTO ;
2013-07-30 07:36:32 +00:00
2013-09-20 01:18:26 +00:00
else if ( g_Config . iInternalResolution > RESOLUTION_MAX )
g_Config . iInternalResolution = RESOLUTION_MAX ;
2013-07-30 07:36:32 +00:00
2013-07-26 23:36:16 +00:00
for ( int i = 0 ; i < ARRAY_SIZE ( zoomitems ) ; i + + ) {
2013-09-10 22:19:34 +00:00
CheckMenuItem ( menu , zoomitems [ i ] , MF_BYCOMMAND | ( ( i = = g_Config . iInternalResolution ) ? MF_CHECKED : MF_UNCHECKED ) ) ;
}
static const int windowSizeItems [ 4 ] = {
ID_OPTIONS_WINDOW1X ,
ID_OPTIONS_WINDOW2X ,
ID_OPTIONS_WINDOW3X ,
ID_OPTIONS_WINDOW4X ,
} ;
RECT rc ;
GetClientRect ( GetHWND ( ) , & rc ) ;
2015-05-15 16:04:05 +00:00
int checkW = g_Config . IsPortrait ( ) ? 272 : 480 ;
int checkH = g_Config . IsPortrait ( ) ? 480 : 272 ;
2013-09-10 22:19:34 +00:00
for ( int i = 0 ; i < ARRAY_SIZE ( windowSizeItems ) ; i + + ) {
2015-05-15 16:04:05 +00:00
bool check = ( i + 1 ) * checkW = = rc . right - rc . left | | ( i + 1 ) * checkH = = rc . bottom - rc . top ;
2013-09-10 22:19:34 +00:00
CheckMenuItem ( menu , windowSizeItems [ i ] , MF_BYCOMMAND | ( check ? MF_CHECKED : MF_UNCHECKED ) ) ;
2012-11-17 16:46:05 +00:00
}
2013-04-30 01:47:33 +00:00
2013-04-30 10:14:34 +00:00
static const int texscalingitems [ ] = {
2013-10-11 06:49:45 +00:00
ID_TEXTURESCALING_AUTO ,
2013-04-30 10:14:34 +00:00
ID_TEXTURESCALING_OFF ,
2013-05-01 21:55:34 +00:00
ID_TEXTURESCALING_2X ,
ID_TEXTURESCALING_3X ,
ID_TEXTURESCALING_4X ,
ID_TEXTURESCALING_5X ,
2013-04-30 01:47:33 +00:00
} ;
2013-10-11 06:49:45 +00:00
if ( g_Config . iTexScalingLevel < TEXSCALING_AUTO )
g_Config . iTexScalingLevel = TEXSCALING_AUTO ;
2013-07-30 07:36:32 +00:00
else if ( g_Config . iTexScalingLevel > TEXSCALING_MAX )
g_Config . iTexScalingLevel = TEXSCALING_MAX ;
2013-07-26 23:36:16 +00:00
for ( int i = 0 ; i < ARRAY_SIZE ( texscalingitems ) ; i + + ) {
2013-10-11 06:49:45 +00:00
CheckMenuItem ( menu , texscalingitems [ i ] , MF_BYCOMMAND | ( ( i = = g_Config . iTexScalingLevel ) ? MF_CHECKED : MF_UNCHECKED ) ) ;
2013-05-01 21:55:34 +00:00
}
2014-01-20 05:14:21 +00:00
if ( ! gl_extensions . OES_texture_npot ) {
EnableMenuItem ( menu , ID_TEXTURESCALING_3X , MF_GRAYED ) ;
EnableMenuItem ( menu , ID_TEXTURESCALING_5X , MF_GRAYED ) ;
2014-01-20 08:42:04 +00:00
} else {
EnableMenuItem ( menu , ID_TEXTURESCALING_3X , MF_ENABLED ) ;
EnableMenuItem ( menu , ID_TEXTURESCALING_5X , MF_ENABLED ) ;
2014-01-20 05:14:21 +00:00
}
2013-05-01 21:55:34 +00:00
static const int texscalingtypeitems [ ] = {
ID_TEXTURESCALING_XBRZ ,
ID_TEXTURESCALING_HYBRID ,
2013-05-04 23:27:15 +00:00
ID_TEXTURESCALING_BICUBIC ,
ID_TEXTURESCALING_HYBRID_BICUBIC ,
2013-05-01 21:55:34 +00:00
} ;
2013-08-03 22:16:46 +00:00
if ( g_Config . iTexScalingType < TextureScaler : : XBRZ )
2013-07-30 07:36:32 +00:00
g_Config . iTexScalingType = TextureScaler : : XBRZ ;
2013-08-03 22:16:46 +00:00
else if ( g_Config . iTexScalingType > TextureScaler : : HYBRID_BICUBIC )
g_Config . iTexScalingType = TextureScaler : : HYBRID_BICUBIC ;
2013-07-26 23:36:16 +00:00
for ( int i = 0 ; i < ARRAY_SIZE ( texscalingtypeitems ) ; i + + ) {
2013-05-01 21:55:34 +00:00
CheckMenuItem ( menu , texscalingtypeitems [ i ] , MF_BYCOMMAND | ( ( i = = g_Config . iTexScalingType ) ? MF_CHECKED : MF_UNCHECKED ) ) ;
2013-04-30 01:47:33 +00:00
}
2013-05-13 08:08:10 +00:00
2013-06-30 06:48:50 +00:00
static const int texfilteringitems [ ] = {
2013-07-01 19:42:45 +00:00
ID_OPTIONS_TEXTUREFILTERING_AUTO ,
2013-06-30 06:48:50 +00:00
ID_OPTIONS_NEARESTFILTERING ,
ID_OPTIONS_LINEARFILTERING ,
ID_OPTIONS_LINEARFILTERING_CG ,
} ;
2013-07-30 07:36:32 +00:00
if ( g_Config . iTexFiltering < AUTO )
g_Config . iTexFiltering = AUTO ;
else if ( g_Config . iTexFiltering > LINEARFMV )
g_Config . iTexFiltering = LINEARFMV ;
2013-07-26 23:36:16 +00:00
for ( int i = 0 ; i < ARRAY_SIZE ( texfilteringitems ) ; i + + ) {
2013-10-06 02:59:40 +00:00
CheckMenuItem ( menu , texfilteringitems [ i ] , MF_BYCOMMAND | ( ( i + 1 ) = = g_Config . iTexFiltering ? MF_CHECKED : MF_UNCHECKED ) ) ;
2013-06-30 06:48:50 +00:00
}
2014-08-08 18:51:15 +00:00
static const int bufferfilteritems [ ] = {
ID_OPTIONS_BUFLINEARFILTER ,
ID_OPTIONS_BUFNEARESTFILTER ,
} ;
if ( g_Config . iBufFilter < SCALE_LINEAR )
g_Config . iBufFilter = SCALE_LINEAR ;
else if ( g_Config . iBufFilter > SCALE_NEAREST )
g_Config . iBufFilter = SCALE_NEAREST ;
for ( int i = 0 ; i < ARRAY_SIZE ( bufferfilteritems ) ; i + + ) {
CheckMenuItem ( menu , bufferfilteritems [ i ] , MF_BYCOMMAND | ( ( i + 1 ) = = g_Config . iBufFilter ? MF_CHECKED : MF_UNCHECKED ) ) ;
}
2013-07-21 15:17:42 +00:00
static const int renderingmode [ ] = {
ID_OPTIONS_NONBUFFEREDRENDERING ,
ID_OPTIONS_BUFFEREDRENDERING ,
ID_OPTIONS_READFBOTOMEMORYCPU ,
2013-07-21 23:33:18 +00:00
ID_OPTIONS_READFBOTOMEMORYGPU ,
2013-07-21 15:17:42 +00:00
} ;
2013-08-03 22:16:46 +00:00
if ( g_Config . iRenderingMode < FB_NON_BUFFERED_MODE )
2013-07-30 07:36:32 +00:00
g_Config . iRenderingMode = FB_NON_BUFFERED_MODE ;
2013-08-03 22:16:46 +00:00
else if ( g_Config . iRenderingMode > FB_READFBOMEMORY_GPU )
g_Config . iRenderingMode = FB_READFBOMEMORY_GPU ;
2013-07-26 23:36:16 +00:00
for ( int i = 0 ; i < ARRAY_SIZE ( renderingmode ) ; i + + ) {
2013-10-06 02:00:19 +00:00
CheckMenuItem ( menu , renderingmode [ i ] , MF_BYCOMMAND | ( ( i = = g_Config . iRenderingMode ) ? MF_CHECKED : MF_UNCHECKED ) ) ;
2013-07-21 15:17:42 +00:00
}
2013-07-26 12:25:11 +00:00
static const int frameskipping [ ] = {
ID_OPTIONS_FRAMESKIP_0 ,
2013-09-05 00:37:41 +00:00
ID_OPTIONS_FRAMESKIP_1 ,
2013-07-26 12:25:11 +00:00
ID_OPTIONS_FRAMESKIP_2 ,
ID_OPTIONS_FRAMESKIP_3 ,
ID_OPTIONS_FRAMESKIP_4 ,
ID_OPTIONS_FRAMESKIP_5 ,
ID_OPTIONS_FRAMESKIP_6 ,
ID_OPTIONS_FRAMESKIP_7 ,
ID_OPTIONS_FRAMESKIP_8 ,
} ;
2013-08-03 22:16:46 +00:00
if ( g_Config . iFrameSkip < FRAMESKIP_OFF )
2013-07-30 07:36:32 +00:00
g_Config . iFrameSkip = FRAMESKIP_OFF ;
2013-07-30 07:38:11 +00:00
2013-08-03 22:16:46 +00:00
else if ( g_Config . iFrameSkip > FRAMESKIP_MAX )
g_Config . iFrameSkip = FRAMESKIP_MAX ;
2013-07-26 23:36:16 +00:00
for ( int i = 0 ; i < ARRAY_SIZE ( frameskipping ) ; i + + ) {
2013-10-06 02:00:19 +00:00
CheckMenuItem ( menu , frameskipping [ i ] , MF_BYCOMMAND | ( ( i = = g_Config . iFrameSkip ) ? MF_CHECKED : MF_UNCHECKED ) ) ;
2013-09-07 15:29:44 +00:00
}
static const int savestateSlot [ ] = {
ID_FILE_SAVESTATE_SLOT_1 ,
ID_FILE_SAVESTATE_SLOT_2 ,
ID_FILE_SAVESTATE_SLOT_3 ,
ID_FILE_SAVESTATE_SLOT_4 ,
ID_FILE_SAVESTATE_SLOT_5 ,
} ;
if ( g_Config . iCurrentStateSlot < 0 )
g_Config . iCurrentStateSlot = 0 ;
else if ( g_Config . iCurrentStateSlot > = SaveState : : SAVESTATESLOTS )
g_Config . iCurrentStateSlot = SaveState : : SAVESTATESLOTS - 1 ;
for ( int i = 0 ; i < ARRAY_SIZE ( savestateSlot ) ; i + + ) {
2013-10-06 01:49:58 +00:00
CheckMenuItem ( menu , savestateSlot [ i ] , MF_BYCOMMAND | ( ( i = = g_Config . iCurrentStateSlot ) ? MF_CHECKED : MF_UNCHECKED ) ) ;
2013-07-26 12:25:11 +00:00
}
2014-09-14 11:30:49 +00:00
if ( g_Config . iGPUBackend = = GPU_BACKEND_DIRECT3D9 ) {
EnableMenuItem ( menu , ID_OPTIONS_DIRECTX , MF_GRAYED ) ;
CheckMenuItem ( menu , ID_OPTIONS_DIRECTX , MF_CHECKED ) ;
EnableMenuItem ( menu , ID_OPTIONS_OPENGL , MF_ENABLED ) ;
} else {
EnableMenuItem ( menu , ID_OPTIONS_OPENGL , MF_GRAYED ) ;
CheckMenuItem ( menu , ID_OPTIONS_OPENGL , MF_CHECKED ) ;
EnableMenuItem ( menu , ID_OPTIONS_DIRECTX , MF_ENABLED ) ;
}
2013-10-12 05:15:47 +00:00
UpdateDynamicMenuCheckmarks ( ) ;
2013-05-13 08:08:10 +00:00
UpdateCommands ( ) ;
}
2013-08-30 18:15:13 +00:00
2013-07-29 08:46:40 +00:00
void UpdateCommands ( ) {
2013-05-13 08:08:10 +00:00
static GlobalUIState lastGlobalUIState = UISTATE_PAUSEMENU ;
static CoreState lastCoreState = CORE_ERROR ;
2014-06-22 07:38:46 +00:00
if ( lastGlobalUIState = = GetUIState ( ) & & lastCoreState = = coreState )
2013-05-13 08:08:10 +00:00
return ;
lastCoreState = coreState ;
2014-06-22 07:38:46 +00:00
lastGlobalUIState = GetUIState ( ) ;
2013-05-13 08:08:10 +00:00
HMENU menu = GetMenu ( GetHWND ( ) ) ;
2014-06-22 07:38:46 +00:00
bool isPaused = Core_IsStepping ( ) & & GetUIState ( ) = = UISTATE_INGAME ;
2013-09-16 22:08:09 +00:00
TranslateMenuItem ( ID_TOGGLE_PAUSE , L " \t F8 " , isPaused ? " Run " : " Pause " ) ;
2013-05-13 08:08:10 +00:00
2014-06-22 07:38:46 +00:00
SetIngameMenuItemStates ( GetUIState ( ) ) ;
2013-08-08 15:05:01 +00:00
EnableMenuItem ( menu , ID_DEBUG_LOG , ! g_Config . bEnableLogging ) ;
2012-11-01 15:19:01 +00:00
}
// Message handler for about box.
2013-07-29 08:46:40 +00:00
LRESULT CALLBACK About ( HWND hDlg , UINT message , WPARAM wParam , LPARAM lParam ) {
switch ( message ) {
2012-11-01 15:19:01 +00:00
case WM_INITDIALOG :
2013-03-11 21:55:29 +00:00
{
2013-07-29 08:46:40 +00:00
W32Util : : CenterWindow ( hDlg ) ;
2013-03-11 21:55:29 +00:00
HWND versionBox = GetDlgItem ( hDlg , IDC_VERSION ) ;
2014-07-10 07:19:00 +00:00
std : : string windowText = " PPSSPP " ;
windowText . append ( PPSSPP_GIT_VERSION ) ;
SetWindowText ( versionBox , ConvertUTF8ToWString ( windowText ) . c_str ( ) ) ;
2013-03-11 21:55:29 +00:00
}
2012-11-01 15:19:01 +00:00
return TRUE ;
case WM_COMMAND :
if ( LOWORD ( wParam ) = = IDOK | | LOWORD ( wParam ) = = IDCANCEL )
{
EndDialog ( hDlg , LOWORD ( wParam ) ) ;
return TRUE ;
}
break ;
}
return FALSE ;
}
2013-07-29 08:46:40 +00:00
void Update ( ) {
2014-06-29 20:13:53 +00:00
InvalidateRect ( hwndDisplay , 0 , 0 ) ;
UpdateWindow ( hwndDisplay ) ;
2012-11-01 15:19:01 +00:00
SendMessage ( hwndMain , WM_SIZE , 0 , 0 ) ;
}
2013-07-29 08:46:40 +00:00
void Redraw ( ) {
2014-06-29 20:13:53 +00:00
InvalidateRect ( hwndDisplay , 0 , 0 ) ;
2012-11-01 15:19:01 +00:00
}
2013-03-29 20:21:27 +00:00
2013-07-29 08:46:40 +00:00
void SaveStateActionFinished ( bool result , void * userdata ) {
2013-07-21 09:21:50 +00:00
PostMessage ( hwndMain , WM_USER_SAVESTATE_FINISH , 0 , 0 ) ;
2012-12-28 21:50:59 +00:00
}
2013-07-29 08:46:40 +00:00
HINSTANCE GetHInstance ( ) {
2012-11-01 15:19:01 +00:00
return hInst ;
}
2013-10-13 18:14:28 +00:00
2013-10-13 18:25:59 +00:00
void ToggleDebugConsoleVisibility ( ) {
2013-10-13 18:14:28 +00:00
if ( ! g_Config . bEnableLogging ) {
LogManager : : GetInstance ( ) - > GetConsoleListener ( ) - > Show ( false ) ;
EnableMenuItem ( menu , ID_DEBUG_LOG , MF_GRAYED ) ;
}
else {
LogManager : : GetInstance ( ) - > GetConsoleListener ( ) - > Show ( true ) ;
EnableMenuItem ( menu , ID_DEBUG_LOG , MF_ENABLED ) ;
}
}
2012-11-01 15:19:01 +00:00
}