mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-07-20 14:01:44 +12:00
Some checks failed
Android Build / x64 (release) (push) Has been cancelled
Android Build / arm64 (release) (push) Has been cancelled
HTTP Server Build / build (push) Has been cancelled
Hydra Core Build / Windows (push) Has been cancelled
Hydra Core Build / MacOS (push) Has been cancelled
Hydra Core Build / Linux (push) Has been cancelled
Hydra Core Build / Android-x64 (push) Has been cancelled
Hydra Core Build / ARM-Libretro (push) Has been cancelled
Linux AppImage Build / build (push) Has been cancelled
Linux Build / build (push) Has been cancelled
MacOS Build / MacOS-arm64 (push) Has been cancelled
MacOS Build / MacOS-x86_64 (push) Has been cancelled
Qt Build / Windows (push) Has been cancelled
Qt Build / MacOS-arm64 (push) Has been cancelled
Qt Build / MacOS-x86_64 (push) Has been cancelled
Qt Build / Linux (push) Has been cancelled
Windows Build / build (push) Has been cancelled
iOS Simulator Build / build (push) Has been cancelled
MacOS Build / MacOS-Universal (push) Has been cancelled
Qt Build / MacOS-Universal (push) Has been cancelled
* Initial input UI draft Co-Authored-By: Paris Oplopoios <parisoplop@gmail.com> * More keybinding work Co-Authored-By: Paris Oplopoios <parisoplop@gmail.com> * Nit Co-Authored-By: Paris Oplopoios <parisoplop@gmail.com> * More nits Co-Authored-By: Paris Oplopoios <parisoplop@gmail.com> --------- Co-authored-by: Paris Oplopoios <parisoplop@gmail.com>
174 lines
4.3 KiB
C++
174 lines
4.3 KiB
C++
#pragma once
|
|
|
|
#include <SDL.h>
|
|
|
|
#include <QApplication>
|
|
#include <QMenuBar>
|
|
#include <QtWidgets>
|
|
#include <atomic>
|
|
#include <filesystem>
|
|
#include <functional>
|
|
#include <mutex>
|
|
#include <thread>
|
|
#include <vector>
|
|
|
|
#include "emulator.hpp"
|
|
#include "input_mappings.hpp"
|
|
#include "panda_qt/about_window.hpp"
|
|
#include "panda_qt/cheats_window.hpp"
|
|
#include "panda_qt/config_window.hpp"
|
|
#include "panda_qt/cpu_debugger.hpp"
|
|
#include "panda_qt/dsp_debugger.hpp"
|
|
#include "panda_qt/patch_window.hpp"
|
|
#include "panda_qt/screen.hpp"
|
|
#include "panda_qt/shader_editor.hpp"
|
|
#include "panda_qt/text_editor.hpp"
|
|
#include "panda_qt/thread_debugger.hpp"
|
|
#include "services/hid.hpp"
|
|
|
|
struct CheatMessage {
|
|
u32 handle;
|
|
std::vector<uint8_t> cheat;
|
|
std::function<void(u32)> callback;
|
|
};
|
|
|
|
class MainWindow : public QMainWindow {
|
|
Q_OBJECT
|
|
|
|
private:
|
|
// Types of messages we might send from the GUI thread to the emulator thread
|
|
enum class MessageType {
|
|
LoadROM,
|
|
Reset,
|
|
Pause,
|
|
Resume,
|
|
TogglePause,
|
|
PressKey,
|
|
ReleaseKey,
|
|
SetCirclePadX,
|
|
SetCirclePadY,
|
|
LoadLuaScript,
|
|
EditCheat,
|
|
PressTouchscreen,
|
|
ReleaseTouchscreen,
|
|
ReloadUbershader,
|
|
SetScreenSize,
|
|
UpdateConfig,
|
|
};
|
|
|
|
// Tagged union representing our message queue messages
|
|
struct EmulatorMessage {
|
|
MessageType type;
|
|
|
|
union {
|
|
struct {
|
|
std::filesystem::path* p;
|
|
} path;
|
|
|
|
struct {
|
|
u32 key;
|
|
} key;
|
|
|
|
struct {
|
|
s16 value;
|
|
} circlepad;
|
|
|
|
struct {
|
|
std::string* str;
|
|
} string;
|
|
|
|
struct {
|
|
CheatMessage* c;
|
|
} cheat;
|
|
|
|
struct {
|
|
u16 x;
|
|
u16 y;
|
|
} touchscreen;
|
|
|
|
struct {
|
|
u32 width;
|
|
u32 height;
|
|
} screenSize;
|
|
};
|
|
};
|
|
|
|
// This would normally be an std::unique_ptr but it's shared between threads so definitely not
|
|
Emulator* emu = nullptr;
|
|
std::thread emuThread;
|
|
|
|
std::atomic<bool> appRunning = true; // Is the application itself running?
|
|
// Used for synchronizing messages between the emulator and UI
|
|
std::mutex messageQueueMutex;
|
|
std::vector<EmulatorMessage> messageQueue;
|
|
|
|
QMenuBar* menuBar = nullptr;
|
|
InputMappings keyboardMappings;
|
|
ScreenWidget* screen;
|
|
AboutWindow* aboutWindow;
|
|
ConfigWindow* configWindow;
|
|
CheatsWindow* cheatsEditor;
|
|
TextEditorWindow* luaEditor;
|
|
PatchWindow* patchWindow;
|
|
ShaderEditorWindow* shaderEditor;
|
|
CPUDebugger* cpuDebugger;
|
|
DSPDebugger* dspDebugger;
|
|
ThreadDebugger* threadDebugger;
|
|
|
|
// We use SDL's game controller API since it's the sanest API that supports as many controllers as possible
|
|
SDL_GameController* gameController = nullptr;
|
|
int gameControllerID = 0;
|
|
|
|
void swapEmuBuffer();
|
|
void emuThreadMainLoop();
|
|
void selectLuaFile();
|
|
void selectROM();
|
|
void dumpDspFirmware();
|
|
void dumpRomFS();
|
|
void showAboutMenu();
|
|
void initControllers();
|
|
void pollControllers();
|
|
void setupControllerSensors(SDL_GameController* controller);
|
|
void sendMessage(const EmulatorMessage& message);
|
|
void dispatchMessage(const EmulatorMessage& message);
|
|
void loadTranslation();
|
|
|
|
void loadKeybindings();
|
|
void saveKeybindings();
|
|
|
|
// Tracks whether we are using an OpenGL-backed renderer or a Vulkan-backed renderer
|
|
bool usingGL = false;
|
|
bool usingVk = false;
|
|
bool usingMtl = false;
|
|
|
|
// Variables to keep track of whether the user is controlling the 3DS analog stick with their keyboard
|
|
// This is done so when a gamepad is connected, we won't automatically override the 3DS analog stick settings with the gamepad's state
|
|
// And so the user can still use the keyboard to control the analog
|
|
bool keyboardAnalogX = false;
|
|
bool keyboardAnalogY = false;
|
|
|
|
// Tracks if keybindings changed, in which case we should update the keybindings file when closing the emulator
|
|
bool keybindingsChanged = false;
|
|
|
|
public:
|
|
MainWindow(QApplication* app, QWidget* parent = nullptr);
|
|
~MainWindow();
|
|
|
|
void closeEvent(QCloseEvent* event) override;
|
|
void keyPressEvent(QKeyEvent* event) override;
|
|
void keyReleaseEvent(QKeyEvent* event) override;
|
|
|
|
void mousePressEvent(QMouseEvent* event) override;
|
|
void mouseReleaseEvent(QMouseEvent* event) override;
|
|
void mouseMoveEvent(QMouseEvent* event) override;
|
|
|
|
void loadLuaScript(const std::string& code);
|
|
void reloadShader(const std::string& shader);
|
|
void editCheat(u32 handle, const std::vector<uint8_t>& cheat, const std::function<void(u32)>& callback);
|
|
|
|
void handleScreenResize(u32 width, u32 height);
|
|
void handleTouchscreenPress(QMouseEvent* event);
|
|
|
|
signals:
|
|
void emulatorPaused();
|
|
};
|