Ejemplo n.º 1
0
	void SetInternalResolution(int res) {
		if (res >= 0 && res <= RESOLUTION_MAX)
			g_Config.iInternalResolution = res;
		else {
			if (++g_Config.iInternalResolution > RESOLUTION_MAX)
				g_Config.iInternalResolution = 0;
		}
		
		// Taking auto-texture scaling into account
		if (g_Config.iTexScalingLevel == TEXSCALING_AUTO)
			setTexScalingMultiplier(0);

		NativeMessageReceived("gpu_resized", "");
	}
Ejemplo n.º 2
0
	void SetInternalResolution(int res) {
		if (res >= 0 && res <= RESOLUTION_MAX)
			g_Config.iInternalResolution = res;
		else {
			if (++g_Config.iInternalResolution > RESOLUTION_MAX)
				g_Config.iInternalResolution = 0;
		}
		
		// Taking auto-texture scaling into account
		if (g_Config.iTexScalingLevel == TEXSCALING_AUTO)
			setTexScalingMultiplier(0);

		if (gpu)
			gpu->Resized();

		UpdateRenderResolution();
		ShowScreenResolution();
	}
Ejemplo n.º 3
0
	LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)	{
		int wmId, wmEvent;
		std::string fn;

		switch (message) {
		case WM_CREATE:
			break;

		case WM_MOVE:
			SavePosition();
			ResizeDisplay();
			break;

		case WM_SIZE:
			SavePosition();
			ResizeDisplay();
			break;

		case WM_TIMER:
			// Hack: Take the opportunity to also show/hide the mouse cursor in fullscreen mode.
			switch (wParam) {
			case TIMER_CURSORUPDATE:
				CorrectCursor();
				return 0;

			case TIMER_CURSORMOVEUPDATE:
				hideCursor = true;
				KillTimer(hWnd, TIMER_CURSORMOVEUPDATE);
				return 0;
			}
			break;

		// 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) {
					key.keyCode = NKCODE_EXT_MOUSEWHEEL_DOWN;
					wheelDelta = -wheelDelta;
				} else {
					key.keyCode = NKCODE_EXT_MOUSEWHEEL_UP;
				}
				// 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);
			}
			break;

		case WM_COMMAND:
			{
				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;

				case ID_FILE_LOAD_DIR:
					BrowseAndBoot("",true);
					break;

				case ID_FILE_LOAD_MEMSTICK:
					{
						std::string memStickDir, flash0dir;
						GetSysDirectories(memStickDir, flash0dir);
						memStickDir += "PSP\\GAME\\";
						BrowseAndBoot(memStickDir);
					}
					break;

				case ID_FILE_MEMSTICK:
					{
						std::string memStickDir, flash0dir;
						GetSysDirectories(memStickDir, flash0dir);
						ShellExecuteA(NULL, "open", memStickDir.c_str(), 0, 0, SW_SHOW);
					}
					break;

				case ID_TOGGLE_PAUSE:
					if (globalUIState == UISTATE_PAUSEMENU) {
						NativeMessageReceived("run", "");
						if (disasmWindow[0])
							SendMessage(disasmWindow[0]->GetDlgHandle(), WM_COMMAND, IDC_STOPGO, 0);
					}
					else if (Core_IsStepping()) { // It is paused, then continue to run.
						if (disasmWindow[0])
							SendMessage(disasmWindow[0]->GetDlgHandle(), WM_COMMAND, IDC_STOPGO, 0);
						else
							Core_EnableStepping(false);
					} else {
						if (disasmWindow[0])
							SendMessage(disasmWindow[0]->GetDlgHandle(), WM_COMMAND, IDC_STOPGO, 0);
						else
							Core_EnableStepping(true);
					}
					break;

				case ID_EMULATION_STOP:
					if (memoryWindow[0]) {
						SendMessage(memoryWindow[0]->GetDlgHandle(), WM_CLOSE, 0, 0);
					}
					if (disasmWindow[0]) {
						SendMessage(disasmWindow[0]->GetDlgHandle(), WM_CLOSE, 0, 0);
					}
					if (Core_IsStepping()) {
						Core_EnableStepping(false);
					}
					NativeMessageReceived("stop", "");
					SetPlaying(0);
					Update();
					break;

				case ID_EMULATION_RESET:
					NativeMessageReceived("reset", "");
					break;

				case ID_EMULATION_SPEEDLIMIT:
					g_Config.bSpeedLimit = !g_Config.bSpeedLimit;
					break;

				case ID_EMULATION_RENDER_MODE_OGL:
					g_Config.bSoftwareRendering = false;
					break;

				case ID_EMULATION_RENDER_MODE_SOFT:
					g_Config.bSoftwareRendering = true;
					break;

				case ID_FILE_LOADSTATEFILE:
					if (W32Util::BrowseForFileName(true, hWnd, "Load state",0,"Save States (*.ppst)\0*.ppst\0All files\0*.*\0\0","ppst",fn)) {
						SetCursor(LoadCursor(0, IDC_WAIT));
						SaveState::Load(fn, SaveStateActionFinished);
					}
					break;

				case ID_FILE_SAVESTATEFILE:
					if (W32Util::BrowseForFileName(false, hWnd, "Save state",0,"Save States (*.ppst)\0*.ppst\0All files\0*.*\0\0","ppst",fn)) {
						SetCursor(LoadCursor(0, IDC_WAIT));
						SaveState::Save(fn, SaveStateActionFinished);
					}
					break;

				// TODO: Improve UI for multiple slots
				case ID_FILE_SAVESTATE_NEXT_SLOT:
				{
					currentSavestateSlot = (currentSavestateSlot + 1)%SaveState::SAVESTATESLOTS;
					char msg[30];
					sprintf(msg, "Using save state slot %d.", currentSavestateSlot + 1);
					osm.Show(msg);
					break;
				}

				case ID_FILE_QUICKLOADSTATE:
					SetCursor(LoadCursor(0, IDC_WAIT));
					SaveState::LoadSlot(currentSavestateSlot, SaveStateActionFinished);
					break;

				case ID_FILE_QUICKSAVESTATE:
					SetCursor(LoadCursor(0, IDC_WAIT));
					SaveState::SaveSlot(currentSavestateSlot, SaveStateActionFinished);
					break;

				case ID_OPTIONS_SCREEN1X:
					setZoom(ZOOM_NATIVE);
					break;

				case ID_OPTIONS_SCREEN2X:
					setZoom(ZOOM_2X);
					break;

				case ID_OPTIONS_SCREEN3X:
					setZoom(ZOOM_3X);
					break;

				case ID_OPTIONS_SCREEN4X:
					setZoom(ZOOM_MAX);
					break;

				case ID_OPTIONS_SCREENDUMMY:
					g_Config.iWindowZoom = ++g_Config.iWindowZoom > ZOOM_MAX ? ZOOM_NATIVE : g_Config.iWindowZoom;

					setZoom(g_Config.iWindowZoom);
					break;

				case ID_OPTIONS_MIPMAP:
					g_Config.bMipMap = !g_Config.bMipMap;
					break;

				case ID_OPTIONS_VSYNC:
					g_Config.bVSync = !g_Config.bVSync;
					break;

				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;

				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;

				case ID_TEXTURESCALING_DEPOSTERIZE:
					g_Config.bTexDeposterize = !g_Config.bTexDeposterize;
					if(gpu) gpu->ClearCacheNextFrame();
					break;

				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;

				// Dummy option to let the buffered rendering hotkey cycle through all the options.
				case ID_OPTIONS_BUFFEREDRENDERINGDUMMY:
					g_Config.iRenderingMode = ++g_Config.iRenderingMode > FB_READFBOMEMORY_GPU ? FB_NON_BUFFERED_MODE : g_Config.iRenderingMode;

					setRenderingMode(g_Config.iRenderingMode);
					break;

				case ID_OPTIONS_SHOWDEBUGSTATISTICS:
					g_Config.bShowDebugStats = !g_Config.bShowDebugStats;
					break;

				case ID_OPTIONS_HARDWARETRANSFORM:
					g_Config.bHardwareTransform = !g_Config.bHardwareTransform;
					osm.ShowOnOff(g->T("Hardware Transform"), g_Config.bHardwareTransform);
					break;

				case ID_OPTIONS_STRETCHDISPLAY:
					g_Config.bStretchToDisplay = !g_Config.bStretchToDisplay;
					if (gpu)
						gpu->Resized();  // Easy way to force a clear...
					break;

				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_8);
					break;

				case ID_OPTIONS_FRAMESKIP_9:
					setFrameSkipping(FRAMESKIP_MAX);
					break;

				case ID_OPTIONS_FRAMESKIPDUMMY:
					g_Config.iFrameSkip = ++g_Config.iFrameSkip > FRAMESKIP_MAX ? FRAMESKIP_OFF : g_Config.iFrameSkip;

					setFrameSkipping(g_Config.iFrameSkip);
					break;

				case ID_FILE_EXIT:
					DestroyWindow(hWnd);
					break;

				case ID_CPU_DYNAREC:
					g_Config.bJit = true;
					osm.ShowOnOff(g->T("Dynarec", "Dynarec (JIT)"), g_Config.bJit);
					break;

				case ID_CPU_INTERPRETER:
					g_Config.bJit = false;
					break;

				case ID_CPU_MULTITHREADED:
					g_Config.bSeparateCPUThread = !g_Config.bSeparateCPUThread;
					break;

				case ID_IO_MULTITHREADED:
					g_Config.bSeparateIOThread = !g_Config.bSeparateIOThread;
					break;

				case ID_EMULATION_RUNONLOAD:
					g_Config.bAutoRun = !g_Config.bAutoRun;
					break;

				case ID_DEBUG_DUMPNEXTFRAME:
					if (gpu)
						gpu->DumpNextFrame();
					break;

				case ID_DEBUG_LOADMAPFILE:
					if (W32Util::BrowseForFileName(true, hWnd, "Load .MAP",0,"Maps\0*.map\0All files\0*.*\0\0","map",fn)) {
						symbolMap.LoadSymbolMap(fn.c_str());

						if (disasmWindow[0])
							disasmWindow[0]->NotifyMapLoaded();

						if (memoryWindow[0])
							memoryWindow[0]->NotifyMapLoaded();
					}
					break;

				case ID_DEBUG_SAVEMAPFILE:
					if (W32Util::BrowseForFileName(false, hWnd, "Save .MAP",0,"Maps\0*.map\0All files\0*.*\0\0","map",fn))
						symbolMap.SaveSymbolMap(fn.c_str());
					break;
		
				case ID_DEBUG_RESETSYMBOLTABLE:
					symbolMap.ResetSymbolMap();

					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();
					break;

				case ID_DEBUG_DISASSEMBLY:
					if (disasmWindow[0])
						disasmWindow[0]->Show(true);
					break;

				case ID_DEBUG_MEMORYVIEW:
					if (memoryWindow[0])
						memoryWindow[0]->Show(true);
					break;

				case ID_DEBUG_LOG:
					LogManager::GetInstance()->GetConsoleListener()->Show(LogManager::GetInstance()->GetConsoleListener()->Hidden());
					break;

				case ID_OPTIONS_IGNOREILLEGALREADS:
					g_Config.bIgnoreBadMemAccess = !g_Config.bIgnoreBadMemAccess;
					break;

				case ID_OPTIONS_FULLSCREEN:
					g_Config.bFullScreen = !g_Config.bFullScreen ;
					if(g_bFullScreen) {
						_ViewNormal(hWnd); 
					} else {
						_ViewFullScreen(hWnd);
					}
					break;

				case ID_OPTIONS_VERTEXCACHE:
					g_Config.bVertexCache = !g_Config.bVertexCache;
					break;

				case ID_OPTIONS_SHOWFPS:
					g_Config.iShowFPSCounter = !g_Config.iShowFPSCounter;
					break;

				case ID_OPTIONS_FASTMEMORY:
					g_Config.bFastMemory = !g_Config.bFastMemory;
					break;

				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;

				case ID_OPTIONS_TOPMOST:
					g_Config.bTopMost = !g_Config.bTopMost;
					W32Util::MakeTopMost(hWnd, g_Config.bTopMost);
					break;

				case ID_OPTIONS_ANTIALIASING:
					g_Config.bAntiAliasing = !g_Config.bAntiAliasing;
					ResizeDisplay(true);
					break;

				case ID_OPTIONS_CONTROLS:
					MessageBox(hWnd, "Control mapping has been moved to the in-window Settings menu.\n", "Sorry", 0);
					break;

				case ID_EMULATION_SOUND:
					g_Config.bEnableSound = !g_Config.bEnableSound;
					if(!g_Config.bEnableSound) {
						EnableMenuItem(menu, ID_EMULATION_ATRAC3_SOUND, MF_GRAYED);
						if(!IsAudioInitialised())
							Audio_Init();
					} else {
						if(Atrac3plus_Decoder::IsInstalled())
							EnableMenuItem(menu, ID_EMULATION_ATRAC3_SOUND, MF_ENABLED);
					}
					break;

				case ID_EMULATION_ATRAC3_SOUND:
					g_Config.bEnableAtrac3plus = !g_Config.bEnableAtrac3plus;

					if(Atrac3plus_Decoder::IsInstalled()) {
						if(g_Config.bEnableAtrac3plus)
							Atrac3plus_Decoder::Init();
						else Atrac3plus_Decoder::Shutdown();
					} else {
						EnableMenuItem(menu, ID_EMULATION_ATRAC3_SOUND, MF_GRAYED);
					}
					break;

				case ID_HELP_OPENWEBSITE:
					ShellExecute(NULL, "open", "http://www.ppsspp.org/", NULL, NULL, SW_SHOWNORMAL);
					break;

				case ID_HELP_OPENFORUM:
					ShellExecute(NULL, "open", "http://forums.ppsspp.org/", NULL, NULL, SW_SHOWNORMAL);
					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:
					MessageBox(hwndMain,"Unimplemented","Sorry",0);
					break;
				}
			}
			break;

		case WM_INPUT:
			{
				UINT dwSize;
				GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
				if (!rawInputBuffer) {
					rawInputBuffer = malloc(dwSize);
					rawInputBufferSize = dwSize;
				}
				if (dwSize > rawInputBufferSize) {
					rawInputBuffer = realloc(rawInputBuffer, dwSize);
				}
				GetRawInputData((HRAWINPUT)lParam, RID_INPUT, rawInputBuffer, &dwSize, sizeof(RAWINPUTHEADER));
				RAWINPUT* raw = (RAWINPUT*)rawInputBuffer;
				if (raw->header.dwType == RIM_TYPEKEYBOARD) {
					KeyInput key;
					key.deviceId = DEVICE_ID_KEYBOARD;
					if (raw->data.keyboard.Message == WM_KEYDOWN || raw->data.keyboard.Message == WM_SYSKEYDOWN) {
						key.flags = KEY_DOWN;
						key.keyCode = windowsTransTable[GetTrueVKey(raw->data.keyboard)];
						if (key.keyCode) {
							NativeKey(key);
						}
					} else if (raw->data.keyboard.Message == WM_KEYUP) {
						key.flags = KEY_UP;
						key.keyCode = windowsTransTable[GetTrueVKey(raw->data.keyboard)];
						if (key.keyCode) {
							NativeKey(key);	
						}
					}
				} else if (raw->header.dwType == RIM_TYPEMOUSE) {
					mouseDeltaX += raw->data.mouse.lLastX;
					mouseDeltaY += raw->data.mouse.lLastY;

					// TODO : Smooth and translate to an axis every frame.
					// NativeAxis()
				}
			}
			return 0;

		case WM_DROPFILES:
			{
				if (!EmuThread_Ready())
					return DefWindowProc(hWnd, message, wParam, lParam);

				HDROP hdrop = (HDROP)wParam;
				int count = DragQueryFile(hdrop,0xFFFFFFFF,0,0);
				if (count != 1) {
					MessageBox(hwndMain,"You can only load one file at a time","Error",MB_ICONINFORMATION);
				}
				else
				{
					TCHAR filename[512];
					DragQueryFile(hdrop,0,filename,512);
					TCHAR *type = filename+_tcslen(filename)-3;

					SendMessage(hWnd, WM_COMMAND, ID_EMULATION_STOP, 0);
					// Ugly, need to wait for the stop message to process in the EmuThread.
					Sleep(20);
					
					MainWindow::SetPlaying(filename);
					MainWindow::Update();

					NativeMessageReceived("boot", filename);
				}
			}
			break;

		case WM_CLOSE:
			EmuThread_Stop();

			return DefWindowProc(hWnd,message,wParam,lParam);

		case WM_DESTROY:
			KillTimer(hWnd, TIMER_CURSORUPDATE);
			KillTimer(hWnd, TIMER_CURSORMOVEUPDATE);
			PostQuitMessage(0);
			break;

		case WM_USER+1:
			if (disasmWindow[0])
				SendMessage(disasmWindow[0]->GetDlgHandle(), WM_CLOSE, 0, 0);
			if (memoryWindow[0])
				SendMessage(memoryWindow[0]->GetDlgHandle(), WM_CLOSE, 0, 0);

			disasmWindow[0] = new CDisasm(MainWindow::GetHInstance(), MainWindow::GetHWND(), currentDebugMIPS);
			DialogManager::AddDlg(disasmWindow[0]);
			disasmWindow[0]->Show(g_Config.bShowDebuggerOnLoad);
			if (g_Config.bFullScreen)
				_ViewFullScreen(hWnd);
			memoryWindow[0] = new CMemoryDlg(MainWindow::GetHInstance(), MainWindow::GetHWND(), currentDebugMIPS);
			DialogManager::AddDlg(memoryWindow[0]);
			if (disasmWindow[0])
				disasmWindow[0]->NotifyMapLoaded();
			if (memoryWindow[0])
				memoryWindow[0]->NotifyMapLoaded();

			SetForegroundWindow(hwndMain);
			break;

		case WM_USER_SAVESTATE_FINISH:
			SetCursor(LoadCursor(0, IDC_ARROW));
			break;

		case WM_USER_LOG_STATUS_CHANGED:
			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);
			}
			break;

		case WM_USER_ATRAC_STATUS_CHANGED:
			if(g_Config.bEnableAtrac3plus && Atrac3plus_Decoder::IsInstalled())
				EnableMenuItem(menu, ID_EMULATION_ATRAC3_SOUND, MF_ENABLED);
			else
				EnableMenuItem(menu, ID_EMULATION_ATRAC3_SOUND, MF_GRAYED);
			break;

		case WM_MENUSELECT:
			// Unfortunately, accelerate keys (hotkeys) shares the same enabled/disabled states
			// with corresponding menu items.
			UpdateMenus();
			break;

		// 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:
			{
				switch (wParam) {
				case SC_SCREENSAVE:  
					return 0;
				case SC_MONITORPOWER:
					return 0;      
				}
				return DefWindowProc(hWnd, message, wParam, lParam);
			}

		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		return 0;
	}