melonDS/src/frontend/qt_sdl/EmuThread.h

204 lines
4.4 KiB
C++

/*
Copyright 2016-2024 melonDS team
This file is part of melonDS.
melonDS 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, either version 3 of the License, or (at your option)
any later version.
melonDS 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 for more details.
You should have received a copy of the GNU General Public License along
with melonDS. If not, see http://www.gnu.org/licenses/.
*/
#ifndef EMUTHREAD_H
#define EMUTHREAD_H
#include <QThread>
#include <QMutex>
#include <QSemaphore>
#include <QQueue>
#include <QVariant>
#include <atomic>
#include <variant>
#include <optional>
#include <list>
#include "NDSCart.h"
#include "GBACart.h"
namespace melonDS
{
class NDS;
}
class EmuInstance;
class MainWindow;
class ScreenPanelGL;
class EmuThread : public QThread
{
Q_OBJECT
void run() override;
public:
explicit EmuThread(EmuInstance* inst, QObject* parent = nullptr);
void attachWindow(MainWindow* window);
void detachWindow(MainWindow* window);
enum MessageType
{
msg_Exit,
msg_EmuRun,
msg_EmuPause,
msg_EmuUnpause,
msg_EmuStop,
msg_EmuFrameStep,
msg_EmuReset,
msg_InitGL,
msg_DeInitGL,
msg_BootROM,
msg_BootFirmware,
msg_InsertCart,
msg_EjectCart,
msg_InsertGBACart,
msg_InsertGBAAddon,
msg_EjectGBACart,
msg_LoadState,
msg_SaveState,
msg_UndoStateLoad,
msg_ImportSavefile,
msg_EnableCheats,
};
struct Message
{
MessageType type;
QVariant param;
};
void sendMessage(Message msg);
void waitMessage(int num = 1);
void waitAllMessages();
void sendMessage(MessageType type)
{
return sendMessage({.type = type});
}
void changeWindowTitle(char* title);
// to be called from the UI thread
void emuRun();
void emuPause(bool broadcast = true);
void emuUnpause(bool broadcast = true);
void emuTogglePause(bool broadcast = true);
void emuStop(bool external);
void emuExit();
void emuFrameStep();
void emuReset();
int bootROM(const QStringList& filename, QString& errorstr);
int bootFirmware(QString& errorstr);
int insertCart(const QStringList& filename, bool gba, QString& errorstr);
void ejectCart(bool gba);
int insertGBAAddon(int type, QString& errorstr);
int saveState(const QString& filename);
int loadState(const QString& filename);
int undoStateLoad();
int importSavefile(const QString& filename);
void enableCheats(bool enable);
bool emuIsRunning();
bool emuIsActive();
void initContext(int win);
void deinitContext(int win);
void updateVideoSettings() { videoSettingsDirty = true; }
void updateVideoRenderer() { videoSettingsDirty = true; lastVideoRenderer = -1; }
int frontBuffer = 0;
QMutex frontBufferLock;
signals:
void windowUpdate();
void windowTitleChange(QString title);
void windowEmuStart();
void windowEmuStop();
void windowEmuPause(bool pause);
void windowEmuReset();
void windowLimitFPSChange();
void autoScreenSizingChange(int sizing);
void windowFullscreenToggle();
void swapScreensToggle();
void screenEmphasisToggle();
void syncVolumeLevel();
void signalLuaUpdate();
private:
void handleMessages();
void updateRenderer();
void compileShaders();
enum EmuStatusKind
{
emuStatus_Exit,
emuStatus_Running,
emuStatus_Paused,
emuStatus_FrameStep,
};
EmuStatusKind prevEmuStatus;
EmuStatusKind emuStatus;
bool emuActive;
constexpr static int emuPauseStackRunning = 0;
constexpr static int emuPauseStackPauseThreshold = 1;
int emuPauseStack;
int msgResult = 0;
QString msgError;
QMutex msgMutex;
QSemaphore msgSemaphore;
QQueue<Message> msgQueue;
EmuInstance* emuInstance;
int autoScreenSizing;
int lastVideoRenderer = -1;
double perfCountsSec;
bool useOpenGL;
int videoRenderer;
bool videoSettingsDirty;
};
#endif // EMUTHREAD_H