mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-23 16:19:44 +00:00
Working Qt interface (debuggers broken)
This commit is contained in:
parent
b5306cef03
commit
d8d1ab286f
@ -64,3 +64,5 @@ HEADERS += ../Common/ChunkFile.h \
|
||||
../Common/Timer.h \
|
||||
../Common/Crypto/*.h
|
||||
|
||||
INCLUDEPATH += ../native
|
||||
|
||||
|
401
Qt/EmuThread.cpp
401
Qt/EmuThread.cpp
@ -1,408 +1,15 @@
|
||||
#include "EmuThread.h"
|
||||
|
||||
#include <QThread>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#include "Core/HLE/sceCtrl.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Core/System.h"
|
||||
#include "Core/Host.h"
|
||||
#include "Core/Core.h"
|
||||
#include "math/lin/matrix4x4.h"
|
||||
#include "native/ui/ui.h"
|
||||
#include "UI/UIShader.h"
|
||||
#include "UI/GamepadEmu.h"
|
||||
#include "UI/ui_atlas.h"
|
||||
#include "base/NativeApp.h"
|
||||
#include "thread/threadutil.h"
|
||||
#include "gfx_es2/fbo.h"
|
||||
#include "gfx_es2/gl_state.h"
|
||||
#include "GPU/GPUState.h"
|
||||
#include "native/base/timeutil.h"
|
||||
#include "native/base/colorutil.h"
|
||||
#include "GPU/GPUState.h"
|
||||
#include "GPU/GPUInterface.h"
|
||||
|
||||
#include "qtemugl.h"
|
||||
#include "QtHost.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
static const int symbols[4] = {
|
||||
I_CROSS,
|
||||
I_CIRCLE,
|
||||
I_SQUARE,
|
||||
I_TRIANGLE
|
||||
};
|
||||
|
||||
static const uint32_t colors[4] = {
|
||||
/*
|
||||
0xFF6666FF, // blue
|
||||
0xFFFF6666, // red
|
||||
0xFFFF66FF, // pink
|
||||
0xFF66FF66, // green
|
||||
*/
|
||||
0xC0FFFFFF,
|
||||
0xC0FFFFFF,
|
||||
0xC0FFFFFF,
|
||||
0xC0FFFFFF,
|
||||
};
|
||||
|
||||
static void DrawBackground(float alpha) {
|
||||
static float xbase[100] = {0};
|
||||
static float ybase[100] = {0};
|
||||
static int old_dp_xres = dp_xres;
|
||||
// if window was resized, recalculate animation coordinates
|
||||
if (xbase[0] == 0.0f || dp_xres != old_dp_xres) {
|
||||
old_dp_xres = dp_xres;
|
||||
GMRng rng;
|
||||
for (int i = 0; i < 100; i++) {
|
||||
xbase[i] = rng.F() * dp_xres;
|
||||
ybase[i] = rng.F() * dp_yres;
|
||||
}
|
||||
}
|
||||
glClearColor(0.1f,0.2f,0.43f,1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
ui_draw2d.DrawImageStretch(I_BG, 0, 0, dp_xres, dp_yres);
|
||||
float t = time_now();
|
||||
for (int i = 0; i < 100; i++) {
|
||||
float x = xbase[i];
|
||||
float y = ybase[i] + 40*cos(i * 7.2 + t * 1.3);
|
||||
float angle = sin(i + t);
|
||||
int n = i & 3;
|
||||
ui_draw2d.DrawImageRotated(symbols[n], x, y, 1.0f, angle, colorAlpha(colors[n], alpha * 0.1f));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void EmuThread_Start(QtEmuGL* w)
|
||||
{
|
||||
//_dbg_clear_();
|
||||
glWindow = w;
|
||||
glWindow->doneCurrent();
|
||||
glWindow->start_rendering();
|
||||
}
|
||||
|
||||
void EmuThread_Stop()
|
||||
{
|
||||
if(glWindow)
|
||||
{
|
||||
glWindow->stop_rendering();
|
||||
}
|
||||
host->UpdateUI();
|
||||
}
|
||||
|
||||
void EmuThread_StartGame(QString filename)
|
||||
{
|
||||
if(glWindow)
|
||||
{
|
||||
glWindow->start_game(filename);
|
||||
}
|
||||
}
|
||||
|
||||
void EmuThread_StopGame()
|
||||
{
|
||||
if(glWindow)
|
||||
{
|
||||
glWindow->stop_game();
|
||||
}
|
||||
}
|
||||
#include <QString>
|
||||
|
||||
void EmuThread_LockDraw(bool value)
|
||||
{
|
||||
if(glWindow)
|
||||
{
|
||||
glWindow->LockDraw(value);
|
||||
}
|
||||
// left there just to avoid compilation problems, this is called a lot
|
||||
// in debuggers
|
||||
}
|
||||
|
||||
QString GetCurrentFilename()
|
||||
{
|
||||
return fileToStart;
|
||||
return QString::fromStdString(PSP_CoreParameter().fileToStart);
|
||||
}
|
||||
|
||||
|
||||
EmuThread::EmuThread()
|
||||
: running(false)
|
||||
, gameRunning(false)
|
||||
, needInitGame(false)
|
||||
, frames_(0)
|
||||
, gameMutex( new QMutex(QMutex::Recursive))
|
||||
, mutexLockNum(0)
|
||||
{
|
||||
}
|
||||
|
||||
EmuThread::~EmuThread()
|
||||
{
|
||||
delete gameMutex;
|
||||
}
|
||||
|
||||
void EmuThread::init(InputState *inputState)
|
||||
{
|
||||
input_state = inputState;
|
||||
}
|
||||
|
||||
void EmuThread::run()
|
||||
{
|
||||
running = true;
|
||||
setCurrentThreadName("EmuThread");
|
||||
|
||||
host->UpdateUI();
|
||||
host->InitGL(0);
|
||||
|
||||
EmuThread_LockDraw(true);
|
||||
|
||||
#ifndef USING_GLES2
|
||||
glewInit();
|
||||
#endif
|
||||
NativeInitGraphics();
|
||||
|
||||
INFO_LOG(BOOT, "Starting up hardware.");
|
||||
|
||||
QElapsedTimer timer;
|
||||
|
||||
EmuThread_LockDraw(false);
|
||||
|
||||
while(running) {
|
||||
//UpdateGamepad(*input_state);
|
||||
timer.start();
|
||||
|
||||
gameMutex->lock();
|
||||
bool gRun = gameRunning;
|
||||
gameMutex->unlock();
|
||||
|
||||
if(gRun)
|
||||
{
|
||||
EmuThread_LockDraw(true);
|
||||
if(needInitGame)
|
||||
{
|
||||
CoreParameter coreParameter;
|
||||
coreParameter.fileToStart = fileToStart.toStdString();
|
||||
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 = dp_xres;
|
||||
coreParameter.outputHeight = dp_yres;
|
||||
coreParameter.pixelWidth = pixel_xres;
|
||||
coreParameter.pixelHeight = pixel_yres;
|
||||
coreParameter.startPaused = !g_Config.bAutoRun;
|
||||
|
||||
std::string error_string;
|
||||
if (!PSP_Init(coreParameter, &error_string))
|
||||
{
|
||||
ERROR_LOG(BOOT, "Error loading: %s", error_string.c_str());
|
||||
FinalShutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
LayoutGamepad(dp_xres, dp_yres);
|
||||
|
||||
_dbg_update_();
|
||||
|
||||
host->UpdateDisassembly();
|
||||
Core_EnableStepping(coreParameter.startPaused ? TRUE : FALSE);
|
||||
|
||||
globalUIState = coreParameter.startPaused ? UISTATE_PAUSEMENU : UISTATE_INGAME;
|
||||
#ifdef _DEBUG
|
||||
host->UpdateMemView();
|
||||
#endif
|
||||
host->BootDone();
|
||||
needInitGame = false;
|
||||
}
|
||||
|
||||
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());
|
||||
glUniformMatrix4fv(UIShader_Get()->u_worldviewproj, 1, GL_FALSE, ortho.getReadPtr());
|
||||
|
||||
|
||||
ReapplyGfxState();
|
||||
|
||||
Core_Run();
|
||||
|
||||
// Hopefully coreState is now CORE_NEXTFRAME
|
||||
if (coreState == CORE_NEXTFRAME) {
|
||||
// set back to running for the next frame
|
||||
coreState = CORE_RUNNING;
|
||||
|
||||
qint64 time = timer.elapsed();
|
||||
const int frameTime = (1.0f/60.0f) * 1000;
|
||||
if(time < frameTime)
|
||||
{
|
||||
EmuThread_LockDraw(false);
|
||||
msleep(frameTime-time);
|
||||
EmuThread_LockDraw(true);
|
||||
}
|
||||
timer.start();
|
||||
}
|
||||
|
||||
fbo_unbind();
|
||||
|
||||
UIShader_Prepare();
|
||||
|
||||
uiTexture->Bind(0);
|
||||
|
||||
glViewport(0, 0, pixel_xres, pixel_yres);
|
||||
|
||||
ui_draw2d.Begin(UIShader_Get(), DBMODE_NORMAL);
|
||||
|
||||
//if (g_Config.bShowTouchControls)
|
||||
// DrawGamepad(ui_draw2d);
|
||||
|
||||
glsl_bind(UIShader_Get());
|
||||
ui_draw2d.End();
|
||||
ui_draw2d.Flush();
|
||||
|
||||
|
||||
// Tiled renderers like PowerVR should benefit greatly from this. However - seems I can't call it?
|
||||
#if defined(USING_GLES2)
|
||||
bool hasDiscard = false; // TODO
|
||||
if (hasDiscard) {
|
||||
//glDiscardFramebuffer(GL_COLOR_EXT | GL_DEPTH_EXT | GL_STENCIL_EXT);
|
||||
}
|
||||
#endif
|
||||
glWindow->swapBuffers();
|
||||
EmuThread_LockDraw(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmuThread_LockDraw(true);
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
time_update();
|
||||
float t = (float)frames_ / 60.0f;
|
||||
frames_++;
|
||||
|
||||
float alpha = t;
|
||||
if (t > 1.0f) alpha = 1.0f;
|
||||
float alphaText = alpha;
|
||||
//if (t > 2.0f) alphaText = 3.0f - t;
|
||||
|
||||
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());
|
||||
glUniformMatrix4fv(UIShader_Get()->u_worldviewproj, 1, GL_FALSE, ortho.getReadPtr());
|
||||
|
||||
|
||||
ReapplyGfxState();
|
||||
|
||||
UIShader_Prepare();
|
||||
glViewport(0, 0, pixel_xres, pixel_yres);
|
||||
UIBegin(UIShader_Get());
|
||||
DrawBackground(alpha);
|
||||
|
||||
ui_draw2d.SetFontScale(1.5f, 1.5f);
|
||||
ui_draw2d.DrawText(UBUNTU48, "PPSSPP", dp_xres / 2, dp_yres / 2 - 30, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER);
|
||||
ui_draw2d.SetFontScale(1.0f, 1.0f);
|
||||
ui_draw2d.DrawText(UBUNTU24, "Created by Henrik Rydg\u00E5rd", dp_xres / 2, dp_yres / 2 + 40, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER);
|
||||
ui_draw2d.DrawText(UBUNTU24, "Free Software under GPL 2.0", dp_xres / 2, dp_yres / 2 + 70, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER);
|
||||
ui_draw2d.DrawText(UBUNTU24, "www.ppsspp.org", dp_xres / 2, dp_yres / 2 + 130, colorAlpha(0xFFFFFFFF, alphaText), ALIGN_CENTER);
|
||||
|
||||
UIEnd();
|
||||
globalUIState = UISTATE_MENU;
|
||||
|
||||
glsl_bind(UIShader_Get());
|
||||
ui_draw2d.Flush();
|
||||
|
||||
glWindow->swapBuffers();
|
||||
EmuThread_LockDraw(false);
|
||||
qint64 time = timer.elapsed();
|
||||
const int frameTime = (1.0f/60.0f) * 1000;
|
||||
if(time < frameTime)
|
||||
{
|
||||
msleep(frameTime-time);
|
||||
}
|
||||
timer.start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(gameRunning)
|
||||
{
|
||||
stopGame();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void EmuThread::Shutdown()
|
||||
{
|
||||
FinalShutdown();
|
||||
}
|
||||
void EmuThread::FinalShutdown()
|
||||
{
|
||||
|
||||
host->ShutdownGL();
|
||||
|
||||
delete uiTexture;
|
||||
uiTexture = NULL;
|
||||
|
||||
UIShader_Shutdown();
|
||||
|
||||
gl_lost_manager_shutdown();
|
||||
|
||||
//_endthreadex(0);
|
||||
//return 0;
|
||||
}
|
||||
|
||||
void EmuThread::setRunning(bool value)
|
||||
{
|
||||
running = false;
|
||||
}
|
||||
|
||||
void EmuThread::startGame(QString filename)
|
||||
{
|
||||
gameMutex->lock();
|
||||
needInitGame = true;
|
||||
gameRunning = true;
|
||||
fileToStart = filename;
|
||||
gameMutex->unlock();
|
||||
|
||||
}
|
||||
|
||||
void EmuThread::stopGame()
|
||||
{
|
||||
Core_Stop();
|
||||
gameMutex->lock();
|
||||
gameRunning = false;
|
||||
|
||||
PSP_Shutdown();
|
||||
|
||||
// TODO
|
||||
//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
|
||||
frames_ = 0;
|
||||
|
||||
gameMutex->unlock();
|
||||
}
|
||||
|
||||
void EmuThread::LockGL(bool lock)
|
||||
{
|
||||
if(lock)
|
||||
{
|
||||
gameMutex->lock();
|
||||
if(mutexLockNum == 0)
|
||||
glWindow->makeCurrent();
|
||||
mutexLockNum++;
|
||||
}
|
||||
else
|
||||
{
|
||||
mutexLockNum--;
|
||||
if(mutexLockNum == 0)
|
||||
glWindow->doneCurrent();
|
||||
gameMutex->unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,38 +1,6 @@
|
||||
#pragma once
|
||||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include "input/input_state.h"
|
||||
|
||||
class QtEmuGL;
|
||||
#include <QString>
|
||||
|
||||
class EmuThread : public QThread
|
||||
{
|
||||
public:
|
||||
EmuThread();
|
||||
~EmuThread();
|
||||
void init(InputState* inputState);
|
||||
void run();
|
||||
void FinalShutdown();
|
||||
void setRunning(bool value);
|
||||
void startGame(QString filename);
|
||||
void stopGame();
|
||||
void LockGL(bool value);
|
||||
public slots:
|
||||
void Shutdown();
|
||||
private:
|
||||
InputState* input_state;
|
||||
bool running;
|
||||
bool gameRunning;
|
||||
bool needInitGame;
|
||||
int frames_;
|
||||
QMutex *gameMutex;
|
||||
int mutexLockNum;
|
||||
|
||||
};
|
||||
|
||||
void EmuThread_Start(QtEmuGL* w);
|
||||
void EmuThread_Stop();
|
||||
void EmuThread_StartGame(QString filename);
|
||||
void EmuThread_StopGame();
|
||||
void EmuThread_LockDraw(bool value);
|
||||
QString GetCurrentFilename();
|
||||
|
127
Qt/QtHost.cpp
127
Qt/QtHost.cpp
@ -2,6 +2,7 @@
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
|
||||
#include "QtHost.h"
|
||||
#include "LogManager.h"
|
||||
@ -15,6 +16,9 @@
|
||||
#include "ui/ui_context.h"
|
||||
#include "GPU/ge_constants.h"
|
||||
#include "EmuThread.h"
|
||||
#include "UI/GameInfoCache.h"
|
||||
|
||||
const char *stateToLoad = NULL;
|
||||
|
||||
std::string boot_filename = "";
|
||||
Texture *uiTexture;
|
||||
@ -27,6 +31,11 @@ std::string game_title;
|
||||
event m_hGPUStepEvent;
|
||||
recursive_mutex m_hGPUStepMutex;
|
||||
|
||||
recursive_mutex pendingMutex;
|
||||
static bool isMessagePending;
|
||||
static std::string pendingMessage;
|
||||
static std::string pendingValue;
|
||||
|
||||
QtHost::QtHost(MainWindow *mainWindow_)
|
||||
: mainWindow(mainWindow_)
|
||||
, m_GPUStep(false)
|
||||
@ -213,6 +222,106 @@ void QtHost::NextGPUStep()
|
||||
m_hGPUStepEvent.notify_one();
|
||||
}
|
||||
|
||||
void NativeInit(int argc, const char *argv[], const char *savegame_directory, const char *external_directory, const char *installID)
|
||||
{
|
||||
std::string config_filename;
|
||||
Common::EnableCrashingOnCrashes();
|
||||
isMessagePending = false;
|
||||
|
||||
std::string user_data_path = savegame_directory;
|
||||
|
||||
VFSRegister("", new DirectoryAssetReader("assets/"));
|
||||
VFSRegister("", new DirectoryAssetReader(user_data_path.c_str()));
|
||||
|
||||
config_filename = user_data_path + "ppsspp.ini";
|
||||
|
||||
g_Config.Load(config_filename.c_str());
|
||||
|
||||
const char *fileToLog = 0;
|
||||
|
||||
bool hideLog = true;
|
||||
#ifdef _DEBUG
|
||||
hideLog = false;
|
||||
#endif
|
||||
|
||||
bool gfxLog = false;
|
||||
// Parse command line
|
||||
LogTypes::LOG_LEVELS logLevel = LogTypes::LINFO;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (argv[i][0] == '-') {
|
||||
switch (argv[i][1]) {
|
||||
case 'd':
|
||||
// Enable debug logging
|
||||
logLevel = LogTypes::LDEBUG;
|
||||
break;
|
||||
case 'g':
|
||||
gfxLog = true;
|
||||
break;
|
||||
case 'j':
|
||||
g_Config.bJit = true;
|
||||
g_Config.bSaveSettings = false;
|
||||
break;
|
||||
case 'i':
|
||||
g_Config.bJit = false;
|
||||
g_Config.bSaveSettings = false;
|
||||
break;
|
||||
case 'l':
|
||||
hideLog = false;
|
||||
break;
|
||||
case 's':
|
||||
g_Config.bAutoRun = false;
|
||||
g_Config.bSaveSettings = false;
|
||||
break;
|
||||
case '-':
|
||||
if (!strcmp(argv[i], "--log") && i < argc - 1)
|
||||
fileToLog = argv[++i];
|
||||
if (!strncmp(argv[i], "--log=", strlen("--log=")) && strlen(argv[i]) > strlen("--log="))
|
||||
fileToLog = argv[i] + strlen("--log=");
|
||||
if (!strcmp(argv[i], "--state") && i < argc - 1)
|
||||
stateToLoad = argv[++i];
|
||||
if (!strncmp(argv[i], "--state=", strlen("--state=")) && strlen(argv[i]) > strlen("--state="))
|
||||
stateToLoad = argv[i] + strlen("--state=");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (fileToStart.isNull())
|
||||
{
|
||||
fileToStart = QString(argv[i]);
|
||||
if (!QFile::exists(fileToStart))
|
||||
{
|
||||
qCritical("File '%s' does not exist!", qPrintable(fileToStart));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qCritical("Can only boot one file. Ignoring file '%s'", qPrintable(fileToStart));
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Config.currentDirectory == "")
|
||||
{
|
||||
g_Config.currentDirectory = QDir::homePath().toStdString();
|
||||
}
|
||||
|
||||
g_Config.memCardDirectory = QDir::homePath().toStdString()+"/.ppsspp/";
|
||||
g_Config.flashDirectory = g_Config.memCardDirectory+"/flash/";
|
||||
|
||||
LogManager::Init();
|
||||
if (fileToLog != NULL)
|
||||
LogManager::GetInstance()->ChangeFileLog(fileToLog);
|
||||
|
||||
LogManager::GetInstance()->SetLogLevel(LogTypes::G3D, LogTypes::LERROR);
|
||||
|
||||
g_gameInfoCache.Init();
|
||||
|
||||
#if !defined(USING_GLES2)
|
||||
// Start Desktop UI
|
||||
MainWindow* mainWindow = new MainWindow();
|
||||
mainWindow->show();
|
||||
#endif
|
||||
}
|
||||
|
||||
int NativeMix(short *audio, int num_samples)
|
||||
{
|
||||
if (g_mixer)
|
||||
@ -288,8 +397,26 @@ void NativeRender()
|
||||
screenManager->render();
|
||||
}
|
||||
|
||||
void NativeMessageReceived(const char *message, const char *value)
|
||||
{
|
||||
lock_guard lock(pendingMutex);
|
||||
if (!isMessagePending) {
|
||||
pendingMessage = message;
|
||||
pendingValue = value;
|
||||
isMessagePending = true;
|
||||
}
|
||||
}
|
||||
|
||||
void NativeUpdate(InputState &input)
|
||||
{
|
||||
{
|
||||
lock_guard lock(pendingMutex);
|
||||
if (isMessagePending) {
|
||||
screenManager->sendMessage(pendingMessage.c_str(), pendingValue.c_str());
|
||||
isMessagePending = false;
|
||||
}
|
||||
}
|
||||
|
||||
UIUpdateMouse(0, input.pointer_x[0], input.pointer_y[0], input.pointer_down[0]);
|
||||
screenManager->update(input);
|
||||
}
|
||||
|
@ -20,8 +20,6 @@
|
||||
#include "QtHost.h"
|
||||
#include "EmuThread.h"
|
||||
|
||||
const char *stateToLoad = NULL;
|
||||
|
||||
// TODO: Make this class thread-aware. Can't send events to a different thread. Currently only works on X11.
|
||||
// Needs to use QueuedConnection for signals/slots.
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
@ -31,6 +29,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
dialogDisasm(0),
|
||||
memoryWindow(0),
|
||||
memoryTexWindow(0),
|
||||
timer(this),
|
||||
displaylistWindow(0)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
@ -56,17 +55,19 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
if (zoom > 4) zoom = 4;
|
||||
SetZoom(zoom);
|
||||
|
||||
EmuThread_Start(emugl);
|
||||
SetGameTitle(fileToStart);
|
||||
|
||||
if (!fileToStart.isNull())
|
||||
{
|
||||
EmuThread_StartGame(fileToStart);
|
||||
UpdateMenus();
|
||||
connect(&timer, SIGNAL(timeout()), this, SLOT(Update()));
|
||||
timer.setInterval(0);
|
||||
timer.start();
|
||||
|
||||
if (stateToLoad != NULL)
|
||||
SaveState::Load(stateToLoad);
|
||||
}
|
||||
// if (!fileToStart.isNull())
|
||||
// {
|
||||
// UpdateMenus();
|
||||
|
||||
// if (stateToLoad != NULL)
|
||||
// SaveState::Load(stateToLoad);
|
||||
// }
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
@ -74,103 +75,6 @@ MainWindow::~MainWindow()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void NativeInit(int argc, const char *argv[], const char *savegame_directory, const char *external_directory, const char *installID)
|
||||
{
|
||||
std::string config_filename;
|
||||
Common::EnableCrashingOnCrashes();
|
||||
|
||||
std::string user_data_path = savegame_directory;
|
||||
|
||||
VFSRegister("", new DirectoryAssetReader("assets/"));
|
||||
VFSRegister("", new DirectoryAssetReader(user_data_path.c_str()));
|
||||
|
||||
config_filename = user_data_path + "ppsspp.ini";
|
||||
|
||||
g_Config.Load(config_filename.c_str());
|
||||
|
||||
const char *fileToLog = 0;
|
||||
|
||||
bool hideLog = true;
|
||||
#ifdef _DEBUG
|
||||
hideLog = false;
|
||||
#endif
|
||||
|
||||
bool gfxLog = false;
|
||||
// Parse command line
|
||||
LogTypes::LOG_LEVELS logLevel = LogTypes::LINFO;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (argv[i][0] == '-') {
|
||||
switch (argv[i][1]) {
|
||||
case 'd':
|
||||
// Enable debug logging
|
||||
logLevel = LogTypes::LDEBUG;
|
||||
break;
|
||||
case 'g':
|
||||
gfxLog = true;
|
||||
break;
|
||||
case 'j':
|
||||
g_Config.bJit = true;
|
||||
g_Config.bSaveSettings = false;
|
||||
break;
|
||||
case 'i':
|
||||
g_Config.bJit = false;
|
||||
g_Config.bSaveSettings = false;
|
||||
break;
|
||||
case 'l':
|
||||
hideLog = false;
|
||||
break;
|
||||
case 's':
|
||||
g_Config.bAutoRun = false;
|
||||
g_Config.bSaveSettings = false;
|
||||
break;
|
||||
case '-':
|
||||
if (!strcmp(argv[i], "--log") && i < argc - 1)
|
||||
fileToLog = argv[++i];
|
||||
if (!strncmp(argv[i], "--log=", strlen("--log=")) && strlen(argv[i]) > strlen("--log="))
|
||||
fileToLog = argv[i] + strlen("--log=");
|
||||
if (!strcmp(argv[i], "--state") && i < argc - 1)
|
||||
stateToLoad = argv[++i];
|
||||
if (!strncmp(argv[i], "--state=", strlen("--state=")) && strlen(argv[i]) > strlen("--state="))
|
||||
stateToLoad = argv[i] + strlen("--state=");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (fileToStart.isNull())
|
||||
{
|
||||
fileToStart = QString(argv[i]);
|
||||
if (!QFile::exists(fileToStart))
|
||||
{
|
||||
qCritical("File '%s' does not exist!", qPrintable(fileToStart));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qCritical("Can only boot one file. Ignoring file '%s'", qPrintable(fileToStart));
|
||||
}
|
||||
}
|
||||
|
||||
if (g_Config.currentDirectory == "")
|
||||
{
|
||||
g_Config.currentDirectory = QDir::homePath().toStdString();
|
||||
}
|
||||
|
||||
g_Config.memCardDirectory = QDir::homePath().toStdString()+"/.ppsspp/";
|
||||
g_Config.flashDirectory = g_Config.memCardDirectory+"/flash/";
|
||||
|
||||
LogManager::Init();
|
||||
if (fileToLog != NULL)
|
||||
LogManager::GetInstance()->ChangeFileLog(fileToLog);
|
||||
|
||||
LogManager::GetInstance()->SetLogLevel(LogTypes::G3D, LogTypes::LERROR);
|
||||
|
||||
#if !defined(USING_GLES2)
|
||||
// Start Desktop UI
|
||||
MainWindow* mainWindow = new MainWindow();
|
||||
mainWindow->show();
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::ShowMemory(u32 addr)
|
||||
{
|
||||
if(memoryWindow)
|
||||
@ -179,8 +83,7 @@ void MainWindow::ShowMemory(u32 addr)
|
||||
|
||||
void MainWindow::Update()
|
||||
{
|
||||
globalUIState = UISTATE_INGAME;
|
||||
UpdateInputState(&input_state);
|
||||
emugl->updateGL();
|
||||
|
||||
for (int i = 0; i < controllistCount; i++)
|
||||
{
|
||||
@ -329,8 +232,9 @@ void MainWindow::on_action_FileLoad_triggered()
|
||||
{
|
||||
QFileInfo info(filename);
|
||||
g_Config.currentDirectory = info.absolutePath().toStdString();
|
||||
EmuThread_StartGame(filename);
|
||||
NativeMessageReceived("boot", filename.toStdString().c_str());
|
||||
}
|
||||
UpdateMenus();
|
||||
}
|
||||
|
||||
void MainWindow::on_action_FileClose_triggered()
|
||||
@ -338,10 +242,6 @@ void MainWindow::on_action_FileClose_triggered()
|
||||
if(dialogDisasm)
|
||||
dialogDisasm->Stop();
|
||||
|
||||
// This will wait for ppsspp to pause
|
||||
EmuThread_LockDraw(true);
|
||||
EmuThread_LockDraw(false);
|
||||
|
||||
if(dialogDisasm && dialogDisasm->isVisible())
|
||||
dialogDisasm->close();
|
||||
if(memoryWindow && memoryWindow->isVisible())
|
||||
@ -351,7 +251,7 @@ void MainWindow::on_action_FileClose_triggered()
|
||||
if(displaylistWindow && displaylistWindow->isVisible())
|
||||
displaylistWindow->close();
|
||||
|
||||
EmuThread_StopGame();
|
||||
NativeMessageReceived("stop", "");
|
||||
SetGameTitle("");
|
||||
UpdateMenus();
|
||||
}
|
||||
@ -412,12 +312,13 @@ void MainWindow::on_action_FileSaveStateFile_triggered()
|
||||
void MainWindow::on_action_FileExit_triggered()
|
||||
{
|
||||
on_action_FileClose_triggered();
|
||||
EmuThread_Stop();
|
||||
QApplication::exit(0);
|
||||
}
|
||||
|
||||
void MainWindow::on_action_EmulationRun_triggered()
|
||||
{
|
||||
NativeMessageReceived("run", "");
|
||||
|
||||
if(dialogDisasm)
|
||||
{
|
||||
dialogDisasm->Stop();
|
||||
@ -427,6 +328,7 @@ void MainWindow::on_action_EmulationRun_triggered()
|
||||
|
||||
void MainWindow::on_action_EmulationPause_triggered()
|
||||
{
|
||||
NativeMessageReceived("pause", "");
|
||||
if(dialogDisasm)
|
||||
dialogDisasm->Stop();
|
||||
}
|
||||
@ -436,9 +338,6 @@ void MainWindow::on_action_EmulationReset_triggered()
|
||||
if(dialogDisasm)
|
||||
dialogDisasm->Stop();
|
||||
|
||||
EmuThread_LockDraw(true);
|
||||
EmuThread_LockDraw(false);
|
||||
|
||||
if(dialogDisasm)
|
||||
dialogDisasm->close();
|
||||
if(memoryWindow)
|
||||
@ -448,9 +347,7 @@ void MainWindow::on_action_EmulationReset_triggered()
|
||||
if(displaylistWindow)
|
||||
displaylistWindow->close();
|
||||
|
||||
EmuThread_StopGame();
|
||||
|
||||
EmuThread_StartGame(GetCurrentFilename());
|
||||
NativeMessageReceived("reset", "");
|
||||
}
|
||||
|
||||
void MainWindow::on_action_EmulationRunLoad_triggered()
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QTranslator>
|
||||
|
||||
#include <QTimer>
|
||||
#include "Core/Core.h"
|
||||
#include "input/input_state.h"
|
||||
#include "debugger_disasm.h"
|
||||
@ -33,7 +33,6 @@ public:
|
||||
CoreState GetNextState() { return nextState; }
|
||||
|
||||
void ShowMemory(u32 addr);
|
||||
void Update();
|
||||
void UpdateMenus();
|
||||
|
||||
protected:
|
||||
@ -45,6 +44,7 @@ protected:
|
||||
public slots:
|
||||
void Boot();
|
||||
void CoreEmitWait(bool);
|
||||
void Update();
|
||||
|
||||
private slots:
|
||||
// File
|
||||
@ -152,6 +152,7 @@ private:
|
||||
Ui::MainWindow *ui;
|
||||
|
||||
QtEmuGL *emugl;
|
||||
QTimer timer;
|
||||
CoreState nextState;
|
||||
InputState input_state;
|
||||
|
||||
|
@ -1,72 +1,32 @@
|
||||
#include "qtemugl.h"
|
||||
|
||||
#include "base/display.h"
|
||||
#include "base/timeutil.h"
|
||||
|
||||
QtEmuGL::QtEmuGL(QWidget *parent) :
|
||||
QGLWidget(parent),
|
||||
running_(false),
|
||||
thread()
|
||||
QGLWidget(parent)
|
||||
{
|
||||
setAutoBufferSwap(false);
|
||||
}
|
||||
|
||||
void QtEmuGL::init(InputState *inputState)
|
||||
{
|
||||
thread.init(inputState);
|
||||
}
|
||||
|
||||
void QtEmuGL::SetRunning(bool value)
|
||||
{
|
||||
running_ = value;
|
||||
input_state = inputState;
|
||||
}
|
||||
|
||||
void QtEmuGL::initializeGL()
|
||||
{
|
||||
#ifndef USING_GLES2
|
||||
glewInit();
|
||||
#endif
|
||||
NativeInitGraphics();
|
||||
}
|
||||
void QtEmuGL::paintGL()
|
||||
{
|
||||
update();
|
||||
}
|
||||
NativeUpdate(*input_state);
|
||||
NativeRender();
|
||||
EndInputState(input_state);
|
||||
|
||||
void QtEmuGL::start_rendering()
|
||||
{
|
||||
thread.start();
|
||||
}
|
||||
|
||||
void QtEmuGL::stop_rendering()
|
||||
{
|
||||
thread.setRunning(false);
|
||||
thread.wait();
|
||||
thread.Shutdown();
|
||||
}
|
||||
|
||||
void QtEmuGL::start_game(QString filename)
|
||||
{
|
||||
thread.startGame(filename);
|
||||
}
|
||||
|
||||
void QtEmuGL::stop_game()
|
||||
{
|
||||
thread.stopGame();
|
||||
}
|
||||
|
||||
void QtEmuGL::LockDraw(bool value)
|
||||
{
|
||||
thread.LockGL(value);
|
||||
}
|
||||
|
||||
void QtEmuGL::resizeEvent(QResizeEvent *evt)
|
||||
{
|
||||
// TODO
|
||||
//glt.resizeViewport(evt->size());
|
||||
}
|
||||
|
||||
void QtEmuGL::paintEvent(QPaintEvent *)
|
||||
{
|
||||
}
|
||||
|
||||
void QtEmuGL::closeEvent(QCloseEvent *evt)
|
||||
{
|
||||
//TODO stopRendering();
|
||||
QGLWidget::closeEvent(evt);
|
||||
time_update();
|
||||
}
|
||||
|
||||
void QtEmuGL::mouseDoubleClickEvent(QMouseEvent *)
|
||||
|
27
Qt/qtemugl.h
27
Qt/qtemugl.h
@ -2,40 +2,29 @@
|
||||
#define QTEMUGL_H
|
||||
|
||||
#include "gfx_es2/glsl_program.h"
|
||||
#include "input/input_state.h"
|
||||
#include <QGLWidget>
|
||||
#include "EmuThread.h"
|
||||
#include "QtHost.h"
|
||||
|
||||
class QtEmuGL : public QGLWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QtEmuGL(QWidget *parent = 0);
|
||||
explicit QtEmuGL(QWidget *parent = nullptr);
|
||||
~QtEmuGL() {
|
||||
NativeShutdownGraphics();
|
||||
}
|
||||
|
||||
void init(InputState* inputState);
|
||||
|
||||
void SetRunning(bool value);
|
||||
|
||||
void start_rendering();
|
||||
void stop_rendering();
|
||||
void start_game(QString filename);
|
||||
void stop_game();
|
||||
void LockDraw(bool value);
|
||||
signals:
|
||||
void doubleClick();
|
||||
protected:
|
||||
void initializeGL();
|
||||
|
||||
void paintGL();
|
||||
void resizeEvent(QResizeEvent *evt);
|
||||
void paintEvent(QPaintEvent *);
|
||||
void closeEvent(QCloseEvent *evt);
|
||||
void mouseDoubleClickEvent(QMouseEvent *);
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
bool running_;
|
||||
EmuThread thread;
|
||||
InputState *input_state;
|
||||
};
|
||||
|
||||
#endif // QTEMUGL_H
|
||||
|
@ -82,12 +82,6 @@ static const int symbols[4] = {
|
||||
};
|
||||
|
||||
static const uint32_t colors[4] = {
|
||||
/*
|
||||
0xFF6666FF, // blue
|
||||
0xFFFF6666, // red
|
||||
0xFFFF66FF, // pink
|
||||
0xFF66FF66, // green
|
||||
*/
|
||||
0xC0FFFFFF,
|
||||
0xC0FFFFFF,
|
||||
0xC0FFFFFF,
|
||||
|
Loading…
Reference in New Issue
Block a user