GL UI in Win32: Some basics work.

This commit is contained in:
Henrik Rydgard 2013-03-29 18:50:08 +01:00
parent e7989e88d8
commit 84fd5781de
24 changed files with 168 additions and 141 deletions

View File

@ -20,9 +20,10 @@
#include "IniFile.h"
#include "HLE/sceUtility.h"
SState g_State;
Config g_Config;
#define MAX_RECENT 4
Config::Config()
{
}
@ -57,6 +58,8 @@ void Config::Load(const char *iniFileName)
// "default" means let emulator decide, "" means disable.
general->Get("ReportHost", &sReportHost, "default");
general->Get("Recent", recentIsos);
if (recentIsos.size() > MAX_RECENT)
recentIsos.resize(MAX_RECENT);
IniFile::Section *cpu = iniFile.GetOrCreateSection("CPU");
cpu->Get("Jit", &bJit, true);
@ -179,10 +182,12 @@ void Config::AddRecent(const std::string &file) {
if (*str == file) {
recentIsos.erase(str);
recentIsos.insert(recentIsos.begin(), file);
if (recentIsos.size() > MAX_RECENT)
recentIsos.resize(MAX_RECENT);
return;
}
}
recentIsos.insert(recentIsos.begin(), file);
if (recentIsos.size() > 4)
recentIsos.resize(4);
if (recentIsos.size() > MAX_RECENT)
recentIsos.resize(MAX_RECENT);
}

View File

@ -23,12 +23,6 @@
extern const char *PPSSPP_GIT_VERSION;
struct SState
{
bool bEmuThreadStarted; // is anything loaded into the emulator?
bool bBooted;
};
struct Config
{
public:
@ -105,5 +99,4 @@ private:
std::string iniFilename_;
};
extern SState g_State;
extern Config g_Config;

View File

@ -15,26 +15,31 @@
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "base/NativeApp.h"
#include "base/display.h"
#include "base/mutex.h"
#include "base/timeutil.h"
#include "input/input_state.h"
#include "../Globals.h"
#include "Core.h"
#include "MemMap.h"
#include "MIPS/MIPS.h"
#include "Globals.h"
#include "Core/Core.h"
#include "Core/Config.h"
#include "Core/MemMap.h"
#include "Core/System.h"
#include "Core/MIPS/MIPS.h"
#ifdef _WIN32
#include "Windows/OpenGLBase.h"
#endif
#include "Host.h"
#include "Debugger/Breakpoints.h"
#include "Core/Debugger/Breakpoints.h"
// HANDLE m_hStepEvent;
event m_hStepEvent;
recursive_mutex m_hStepMutex;
event m_hInactiveEvent;
recursive_mutex m_hInactiveMutex;
InputState input_state;
// This can be read and written from ANYWHERE.
volatile CoreState coreState = CORE_STEPPING;
@ -93,17 +98,29 @@ void Core_WaitInactive(int milliseconds)
m_hInactiveEvent.wait_for(m_hInactiveMutex, milliseconds);
}
void UpdateScreenScale() {
dp_xres = PSP_CoreParameter().pixelWidth;
dp_yres = PSP_CoreParameter().pixelHeight;
pixel_xres = PSP_CoreParameter().pixelWidth;
pixel_yres = PSP_CoreParameter().pixelHeight;
g_dpi = 72;
g_dpi_scale = 1.0f;
pixel_in_dps = (float)pixel_xres / dp_xres;
}
void Core_RunLoop()
{
while (!coreState) {
currentMIPS->RunLoopUntil(0xFFFFFFFFFFFFFFFULL);
if (coreState == CORE_NEXTFRAME)
UpdateScreenScale();
{
#ifdef _WIN32
coreState = CORE_RUNNING;
GL_SwapBuffers();
#endif
lock_guard guard(input_state.lock);
NativeUpdate(input_state);
}
NativeRender();
// Simple throttling to not burn the GPU in the menu.
if (!PSP_CoreParameter().fileToStart.size())
Sleep(15);
GL_SwapBuffers();
}
}

View File

@ -48,5 +48,7 @@ bool Core_IsInactive();
void Core_WaitInactive();
void Core_WaitInactive(int milliseconds);
void UpdateScreenScale();
extern volatile CoreState coreState;

View File

@ -51,7 +51,6 @@ public:
//this is sent from EMU thread! Make sure that Host handles it properly!
virtual void BootDone() {}
virtual void PrepareShutdown() {}
virtual bool IsDebuggingEnabled() {return true;}
virtual bool AttemptLoadSymbolMap() {return false;}

View File

@ -22,6 +22,7 @@
#include "PSPMixer.h"
#include "HLE/__sceAudio.h"
#include "base/NativeApp.h"
int PSPMixer::Mix(short *stereoout, int numSamples)
{

View File

@ -26,6 +26,16 @@
extern MetaFileSystem pspFileSystem;
extern ParamSFOData g_paramSFO;
// To synchronize the two UIs, we need to know which state we're in.
enum UIState {
UISTATE_MENU,
UISTATE_PAUSEMENU,
UISTATE_INGAME,
};
bool PSP_Init(const CoreParameter &coreParam, std::string *error_string);
bool PSP_IsInited();
void PSP_Shutdown();

View File

@ -1,6 +1,9 @@
// NOTE: Apologies for the quality of this code, this is really from pre-opensource Dolphin - that is, 2003.
#include "base/display.h"
#include "base/timeutil.h"
#include "base/threadutil.h"
#include "base/NativeApp.h"
#include "Log.h"
#include "StringUtil.h"
#include "../Globals.h"
@ -15,25 +18,17 @@
#include <tchar.h>
#include <process.h>
char fileToStart[MAX_PATH];
static HANDLE emuThread;
HANDLE EmuThread_GetThreadHandle()
{
return emuThread;
}
DWORD TheThread(LPVOID x);
void EmuThread_Start(const char *filename)
void EmuThread_Start()
{
// _dbg_clear_();
_tcsncpy(fileToStart, filename, sizeof(fileToStart) - 1);
fileToStart[sizeof(fileToStart) - 1] = 0;
unsigned int i;
emuThread = (HANDLE)_beginthreadex(0,0,(unsigned int (__stdcall *)(void *))TheThread,(LPVOID)0,0,&i);
}
@ -49,16 +44,20 @@ void EmuThread_Stop()
host->UpdateUI();
}
char *GetCurrentFilename()
{
return fileToStart;
}
DWORD TheThread(LPVOID x) {
setCurrentThreadName("EmuThread");
g_State.bEmuThreadStarted = true;
std::string memstick, flash0;
GetSysDirectories(memstick, flash0);
// Native overwrites host. Can't allow that.
Host *oldHost = host;
UpdateScreenScale();
NativeInit(0, 0, memstick.c_str(), "C:\\", "1234");
Host *nativeHost = host;
host = oldHost;
CoreParameter coreParameter;
@ -73,57 +72,25 @@ DWORD TheThread(LPVOID x) {
goto shutdown;
}
INFO_LOG(BOOT, "Starting up hardware.");
coreParameter.fileToStart = fileToStart;
coreParameter.enableSound = true;
coreParameter.gpuCore = GPU_GLES;
coreParameter.cpuCore = g_Config.bJit ? CPU_JIT : CPU_INTERPRETER;
coreParameter.enableDebugging = true;
coreParameter.printfEmuLog = false;
coreParameter.headLess = false;
coreParameter.renderWidth = (480 * g_Config.iWindowZoom) * (g_Config.SSAntiAliasing + 1);
coreParameter.renderHeight = (272 * g_Config.iWindowZoom) * (g_Config.SSAntiAliasing + 1);
coreParameter.outputWidth = 480 * g_Config.iWindowZoom;
coreParameter.outputHeight = 272 * g_Config.iWindowZoom;
coreParameter.pixelWidth = 480 * g_Config.iWindowZoom;
coreParameter.pixelHeight = 272 * g_Config.iWindowZoom;
coreParameter.startPaused = !g_Config.bAutoRun;
coreParameter.useMediaEngine = false;
error_string = "";
if (!PSP_Init(coreParameter, &error_string))
{
ERROR_LOG(BOOT, "Error loading: %s", error_string.c_str());
goto shutdown;
}
NativeInitGraphics();
INFO_LOG(BOOT, "Done.");
_dbg_update_();
host->UpdateDisassembly();
Core_EnableStepping(coreParameter.startPaused ? TRUE : FALSE);
Core_EnableStepping(FALSE);
g_State.bBooted = true;
#ifdef _DEBUG
host->UpdateMemView();
#endif
host->BootDone();
Core_Run();
host->PrepareShutdown();
PSP_Shutdown();
shutdown:
host = nativeHost;
NativeShutdownGraphics();
NativeShutdown();
host = oldHost;
host->ShutdownGL();
//The CPU should return when a game is stopped and cleanup should be done here,
//so we can restart the plugins (or load new ones) for the next game
g_State.bEmuThreadStarted = false;
_endthreadex(0);
return 0;
}

View File

@ -1,6 +1,4 @@
#pragma once
void EmuThread_Start(const char *filename);
void EmuThread_Stop();
char *GetCurrentFilename();
void EmuThread_Start();
void EmuThread_Stop();

View File

@ -154,13 +154,8 @@ static std::string SymbolMapFilename(const char *currentFilename)
bool WindowsHost::AttemptLoadSymbolMap()
{
return symbolMap.LoadSymbolMap(SymbolMapFilename(GetCurrentFilename()).c_str());
}
void WindowsHost::PrepareShutdown()
{
// Autosaving symbolmap is no longer very useful.
// symbolMap.SaveSymbolMap(SymbolMapFilename(GetCurrentFilename()).c_str());
return false;
//return symbolMap.LoadSymbolMap(SymbolMapFilename(GetCurrentFilename()).c_str());
}
void WindowsHost::AddSymbol(std::string name, u32 addr, u32 size, int type=0)

View File

@ -46,7 +46,6 @@ public:
bool IsDebuggingEnabled();
void BootDone();
void PrepareShutdown();
bool AttemptLoadSymbolMap();
void SetWindowTitle(const char *message);

View File

@ -2,11 +2,14 @@
#include <windows.h>
#include <tchar.h>
#include "base/NativeApp.h"
#include "Globals.h"
#include "shellapi.h"
#include "commctrl.h"
#include "input/input_state.h"
#include "Core/Debugger/SymbolMap.h"
#include "Windows/OpenGLBase.h"
#include "Windows/Debugger/Debugger_Disasm.h"
@ -38,6 +41,8 @@
BOOL g_bFullScreen = FALSE;
RECT g_normalRC = {0};
extern InputState input_state;
namespace MainWindow
{
HWND hwndMain;
@ -223,11 +228,8 @@ namespace MainWindow
char ext[MAX_PATH];
_splitpath(fullpath.c_str(), drive, dir, fname, ext);
// generate the mapfilename
std::string executable = std::string(drive) + std::string(dir) + std::string(fname) + std::string(ext);
std::string mapfile = std::string(drive) + std::string(dir) + std::string(fname) + std::string(".map");
EmuThread_Start(executable.c_str());
NativeMessageReceived("run", executable.c_str());
}
}
@ -246,9 +248,33 @@ namespace MainWindow
return DefWindowProc(hWnd, message, wParam, lParam);
case WM_LBUTTONDOWN:
// Update();
{
lock_guard guard(input_state.lock);
input_state.mouse_valid = true;
input_state.pointer_down[0] = true;
input_state.pointer_x[0] = GET_X_LPARAM(lParam);
input_state.pointer_y[0] = GET_Y_LPARAM(lParam);
}
break;
case WM_MOUSEMOVE:
{
lock_guard guard(input_state.lock);
input_state.pointer_x[0] = GET_X_LPARAM(lParam);
input_state.pointer_y[0] = GET_Y_LPARAM(lParam);
}
break;
case WM_LBUTTONUP:
{
lock_guard guard(input_state.lock);
input_state.pointer_down[0] = false;
input_state.pointer_x[0] = GET_X_LPARAM(lParam);
input_state.pointer_y[0] = GET_Y_LPARAM(lParam);
}
break;
case WM_PAINT:
return DefWindowProc(hWnd, message, wParam, lParam);
default:
@ -306,15 +332,12 @@ namespace MainWindow
break;
case ID_EMULATION_RUN:
if (g_State.bEmuThreadStarted)
{
for (int i=0; i<numCPUs; i++)
if (disasmWindow[i])
SendMessage(disasmWindow[i]->GetDlgHandle(), WM_COMMAND, IDC_STOP, 0);
for (int i=0; i<numCPUs; i++)
if (disasmWindow[i])
SendMessage(disasmWindow[i]->GetDlgHandle(), WM_COMMAND, IDC_GO, 0);
}
for (int i=0; i<numCPUs; i++)
if (disasmWindow[i])
SendMessage(disasmWindow[i]->GetDlgHandle(), WM_COMMAND, IDC_STOP, 0);
for (int i=0; i<numCPUs; i++)
if (disasmWindow[i])
SendMessage(disasmWindow[i]->GetDlgHandle(), WM_COMMAND, IDC_GO, 0);
break;
case ID_EMULATION_STOP:
@ -322,8 +345,6 @@ namespace MainWindow
if (disasmWindow[i])
SendMessage(disasmWindow[i]->GetDlgHandle(), WM_COMMAND, IDC_STOP, 0);
Core_WaitInactive();
for (int i=0; i<numCPUs; i++)
if (disasmWindow[i])
SendMessage(disasmWindow[i]->GetDlgHandle(), WM_CLOSE, 0, 0);
@ -331,13 +352,16 @@ namespace MainWindow
if (memoryWindow[i])
SendMessage(memoryWindow[i]->GetDlgHandle(), WM_CLOSE, 0, 0);
EmuThread_Stop();
NativeMessageReceived("stop", "");
// EmuThread_Stop();
SetPlaying(0);
Update();
UpdateMenus();
break;
case ID_EMULATION_RESET:
/*
for (int i=0; i<numCPUs; i++)
if (disasmWindow[i])
SendMessage(disasmWindow[i]->GetDlgHandle(), WM_COMMAND, IDC_STOP, 0);
@ -351,15 +375,18 @@ namespace MainWindow
if (memoryWindow[i])
SendMessage(memoryWindow[i]->GetDlgHandle(), WM_CLOSE, 0, 0);
EmuThread_Stop();
EmuThread_Start(GetCurrentFilename());
EmuThread_Start(GetCurrentFilename());*/
break;
case ID_EMULATION_PAUSE:
for (int i=0; i<numCPUs; i++)
if (disasmWindow[i])
SendMessage(disasmWindow[i]->GetDlgHandle(), WM_COMMAND, IDC_STOP, 0);
NativeMessageReceived("pause", "");
break;
case ID_EMULATION_SPEEDLIMIT:
@ -614,16 +641,13 @@ namespace MainWindow
CCore::Start(0,filename,t);
*/
if (g_State.bEmuThreadStarted)
{
SendMessage(hWnd, WM_COMMAND, ID_EMULATION_STOP, 0);
}
SendMessage(hWnd, WM_COMMAND, ID_EMULATION_STOP, 0);
MainWindow::SetPlaying(filename);
MainWindow::Update();
MainWindow::UpdateMenus();
EmuThread_Start(filename);
NativeMessageReceived("run", filename);
}
}
break;
@ -707,11 +731,14 @@ namespace MainWindow
CHECKITEM(ID_OPTIONS_USEMEDIAENGINE, g_Config.bUseMediaEngine);
UINT enable = !Core_IsStepping() ? MF_GRAYED : MF_ENABLED;
EnableMenuItem(menu,ID_EMULATION_RUN, g_State.bEmuThreadStarted ? enable : MF_GRAYED);
EnableMenuItem(menu,ID_EMULATION_PAUSE, g_State.bEmuThreadStarted ? !enable : MF_GRAYED);
EnableMenuItem(menu,ID_EMULATION_RESET, g_State.bEmuThreadStarted ? MF_ENABLED : MF_GRAYED);
enable = g_State.bEmuThreadStarted ? MF_GRAYED : MF_ENABLED;
bool pspRunning = PSP_CoreParameter().fileToStart.size() != 0;
EnableMenuItem(menu,ID_EMULATION_RUN, pspRunning ? enable : MF_GRAYED);
EnableMenuItem(menu,ID_EMULATION_PAUSE, pspRunning ? !enable : MF_GRAYED);
EnableMenuItem(menu,ID_EMULATION_RESET, FALSE); //pspRunning ? MF_ENABLED : MF_GRAYED);
enable = pspRunning ? MF_GRAYED : MF_ENABLED;
EnableMenuItem(menu,ID_FILE_LOAD,enable);
EnableMenuItem(menu,ID_FILE_SAVESTATEFILE,!enable);
EnableMenuItem(menu,ID_FILE_LOADSTATEFILE,!enable);

View File

@ -161,9 +161,11 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin
MainWindow::SetPlaying(fileToStart);
MainWindow::Update();
MainWindow::UpdateMenus();
EmuThread_Start(fileToStart);
}
// Emu thread is always running!
EmuThread_Start();
if (g_Config.bBrowse)
MainWindow::BrowseAndBoot("");

View File

@ -205,7 +205,6 @@ BEGIN
BEGIN
MENUITEM "&Open...", ID_FILE_LOAD
MENUITEM "&Open from MS:/PSP/GAME...", ID_FILE_LOAD_MEMSTICK
MENUITEM "&Close", ID_EMULATION_STOP
MENUITEM SEPARATOR
MENUITEM "Open &Memory Stick", ID_FILE_MEMSTICK
MENUITEM SEPARATOR
@ -220,6 +219,7 @@ BEGIN
BEGIN
MENUITEM "&Run\tF7", ID_EMULATION_RUN
MENUITEM "&Pause\tF8", ID_EMULATION_PAUSE
MENUITEM "&Stop", ID_EMULATION_STOP
MENUITEM SEPARATOR
MENUITEM "R&eset", ID_EMULATION_RESET
MENUITEM SEPARATOR

View File

@ -11,6 +11,7 @@
<uses-feature android:name="android.hardware.screen.landscape" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="archos.permission.FULLSCREEN.FULL" />
<application
android:icon="@drawable/ic_launcher"

View File

@ -86,7 +86,6 @@ EmuScreen::~EmuScreen()
{
if (!invalid_) {
// If we were invalid, it would already be shutdown.
host->PrepareShutdown();
PSP_Shutdown();
}
}
@ -97,6 +96,16 @@ void EmuScreen::dialogFinished(const Screen *dialog, DialogResult result) {
}
}
void EmuScreen::sendMessage(const char *message, const char *value)
{
// External commands, like from the Windows UI.
if (!strcmp(message, "pause")) {
screenManager()->push(new PauseScreen());
} else if (!strcmp(message, "stop")) {
screenManager()->switchScreen(new MenuScreen());
}
}
inline float curve1(float x) {
const float deadzone = 0.15f;
const float factor = 1.0f / (1.0f - deadzone);
@ -171,7 +180,7 @@ void EmuScreen::update(InputState &input)
if (input.pad_buttons_down & (PAD_BUTTON_MENU | PAD_BUTTON_BACK)) {
if (g_Config.bBufferedRendering)
fbo_unbind();
screenManager()->push(new InGameMenuScreen());
screenManager()->push(new PauseScreen());
}
}

View File

@ -31,6 +31,7 @@ public:
virtual void render();
virtual void deviceLost();
virtual void dialogFinished(const Screen *dialog, DialogResult result);
virtual void sendMessage(const char *msg, const char *value);
private:
// Something invalid was loaded, don't try to emulate

View File

@ -244,13 +244,19 @@ void MenuScreen::render() {
}
void InGameMenuScreen::update(InputState &input) {
void PauseScreen::update(InputState &input) {
if (input.pad_buttons_down & PAD_BUTTON_BACK) {
screenManager()->finishDialog(this, DR_CANCEL);
}
}
void InGameMenuScreen::render() {
void PauseScreen::sendMessage(const char *msg, const char *value) {
if (!strcmp(msg, "run")) {
screenManager()->finishDialog(this, DR_CANCEL);
}
}
void PauseScreen::render() {
UIShader_Prepare();
UIBegin();
DrawBackground(1.0f);

View File

@ -51,11 +51,12 @@ private:
};
// Dialog box, meant to be pushed
class InGameMenuScreen : public Screen
class PauseScreen : public Screen
{
public:
void update(InputState &input);
void render();
virtual void sendMessage(const char *msg, const char *value);
};

View File

@ -112,7 +112,6 @@ public:
// this is sent from EMU thread! Make sure that Host handles it properly!
virtual void BootDone() {}
virtual void PrepareShutdown() {}
virtual bool IsDebuggingEnabled() {return false;}
virtual bool AttemptLoadSymbolMap() {return false;}
@ -139,25 +138,19 @@ void NativeHost::ShutdownSound()
g_mixer = 0;
}
void NativeMix(short *audio, int num_samples)
int NativeMix(short *audio, int num_samples)
{
if (g_mixer)
{
g_mixer->Mix(audio, num_samples);
return g_mixer->Mix(audio, num_samples);
}
else
{
//memset(audio, 0, numSamples * 2);
return num_samples;
}
}
int NativeMixCount(short *audio, int num_samples)
{
if (g_mixer)
return g_mixer->Mix(audio, num_samples);
return 0;
}
void NativeGetAppInfo(std::string *app_dir_name, std::string *app_nice_name, bool *landscape)
{
*app_nice_name = "PPSSPP";
@ -350,8 +343,9 @@ void NativeRender()
glClearColor(0,0,0,1);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glstate.viewport.set(0, 0, pixel_xres, pixel_yres);
glstate.Restore();
glViewport(0, 0, pixel_xres, pixel_yres);
Matrix4x4 ortho;
ortho.setOrtho(0.0f, dp_xres, dp_yres, 0.0f, -1.0f, 1.0f);
glsl_bind(UIShader_Get());
@ -364,7 +358,7 @@ void NativeUpdate(InputState &input)
{
UIUpdateMouse(0, input.pointer_x[0], input.pointer_y[0], input.pointer_down[0]);
screenManager->update(input);
}
}
void NativeDeviceLost()
{
@ -394,7 +388,7 @@ void NativeTouch(int finger, float x, float y, double time, TouchEvent event)
void NativeMessageReceived(const char *message, const char *value)
{
// Unused
screenManager->sendMessage(message, value);
}
void NativeShutdownGraphics()

View File

@ -66,8 +66,6 @@ void RunTests()
coreParam.headLess = false;
coreParam.renderWidth = 480;
coreParam.renderHeight = 272;
coreParam.outputWidth = 480;
coreParam.outputHeight = 272;
coreParam.pixelWidth = 480;
coreParam.pixelHeight = 272;
coreParam.useMediaEngine = false;

View File

@ -50,8 +50,11 @@ public:
}
};
struct InputState;
// Temporary hack around annoying linking error.
void GL_SwapBuffers() { }
void NativeUpdate(InputState &input_state) { }
void NativeRender() { }
void printUsage(const char *progname, const char *reason)
{

View File

@ -43,7 +43,6 @@ public:
// this is sent from EMU thread! Make sure that Host handles it properly
virtual void BootDone() {}
virtual void PrepareShutdown() {}
virtual bool IsDebuggingEnabled() {return false;}
virtual bool AttemptLoadSymbolMap() {return false;}

2
native

@ -1 +1 @@
Subproject commit 75e9af1379753f8654dbe2b22c70ce7481bfd012
Subproject commit a47c3b465eb2a37f817dd0950cec8cd81375a2db