Merge branch 'master' into open-bp-cpp

This commit is contained in:
sylvieee-iot 2024-07-15 00:33:06 +03:00 committed by GitHub
commit 13ee3a1bae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
37 changed files with 5520 additions and 92 deletions

View file

@ -176,6 +176,7 @@ namespace Audio {
// Decode an entire buffer worth of audio
void decodeBuffer(DSPSource& source);
SampleBuffer decodePCM8(const u8* data, usize sampleCount, Source& source);
SampleBuffer decodePCM16(const u8* data, usize sampleCount, Source& source);
SampleBuffer decodeADPCM(const u8* data, usize sampleCount, Source& source);

View file

@ -7,7 +7,7 @@
// Remember to initialize every field here to its default value otherwise bad things will happen
struct EmulatorConfig {
// Only enable the shader JIT by default on platforms where it's completely tested
#ifdef PANDA3DS_X64_HOST
#if defined(PANDA3DS_X64_HOST) || defined(PANDA3DS_ARM64_HOST)
static constexpr bool shaderJitDefault = true;
#else
static constexpr bool shaderJitDefault = false;

View file

@ -15,6 +15,7 @@
#include "services/service_manager.hpp"
class CPU;
struct Scheduler;
class Kernel {
std::span<u32, 16> regs;
@ -243,6 +244,7 @@ public:
}
ServiceManager& getServiceManager() { return serviceManager; }
Scheduler& getScheduler();
void sendGPUInterrupt(GPUInterrupt type) { serviceManager.sendGPUInterrupt(type); }
void clearInstructionCache();

View file

@ -60,6 +60,8 @@ struct NCCH {
CodeSetInfo text, data, rodata;
FSInfo partitionInfo;
std::optional<Crypto::AESKey> primaryKey, secondaryKey;
// Contents of the .code file in the ExeFS
std::vector<u8> codeFile;
// Contains of the cart's save data

View file

@ -0,0 +1,21 @@
#pragma once
#include <QFontMetrics>
#include <QLabel>
#include <QString>
#include <QWidget>
class ElidedLabel : public QLabel {
Q_OBJECT
public:
explicit ElidedLabel(Qt::TextElideMode elideMode = Qt::ElideLeft, QWidget* parent = nullptr);
explicit ElidedLabel(QString text, Qt::TextElideMode elideMode = Qt::ElideLeft, QWidget* parent = nullptr);
void setText(QString text);
protected:
void resizeEvent(QResizeEvent* event);
private:
void updateText();
QString m_text;
Qt::TextElideMode m_elideMode;
};

View file

@ -17,7 +17,9 @@
#include "panda_qt/about_window.hpp"
#include "panda_qt/cheats_window.hpp"
#include "panda_qt/config_window.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 "services/hid.hpp"
@ -47,6 +49,7 @@ class MainWindow : public QMainWindow {
EditCheat,
PressTouchscreen,
ReleaseTouchscreen,
ReloadUbershader,
};
// Tagged union representing our message queue messages
@ -90,13 +93,15 @@ class MainWindow : public QMainWindow {
std::mutex messageQueueMutex;
std::vector<EmulatorMessage> messageQueue;
QMenuBar* menuBar = nullptr;
InputMappings keyboardMappings;
ScreenWidget screen;
AboutWindow* aboutWindow;
ConfigWindow* configWindow;
CheatsWindow* cheatsEditor;
TextEditorWindow* luaEditor;
QMenuBar* menuBar = nullptr;
PatchWindow* patchWindow;
ShaderEditorWindow* shaderEditor;
// We use SDL's game controller API since it's the sanest API that supports as many controllers as possible
SDL_GameController* gameController = nullptr;
@ -108,8 +113,6 @@ class MainWindow : public QMainWindow {
void selectROM();
void dumpDspFirmware();
void dumpRomFS();
void openLuaEditor();
void openCheatsEditor();
void showAboutMenu();
void initControllers();
void pollControllers();
@ -136,5 +139,6 @@ class MainWindow : public QMainWindow {
void mouseReleaseEvent(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);
};

View file

@ -0,0 +1,31 @@
#pragma once
#include <QLabel>
#include <QMessageBox>
#include <QWidget>
#include <filesystem>
#include "panda_qt/elided_label.hpp"
class PatchWindow final : public QWidget {
Q_OBJECT
public:
PatchWindow(QWidget* parent = nullptr);
~PatchWindow() = default;
private:
// Show a message box
// Title: Title of the message box to display
// Message: Message to display
// Icon: The type of icon (error, warning, information, etc) to display
// IconPath: If non-null, then a path to an icon in our assets to display on the OK button
void displayMessage(
const QString& title, const QString& message, QMessageBox::Icon icon = QMessageBox::Icon::Warning, const char* iconPath = nullptr
);
std::filesystem::path inputPath = "";
std::filesystem::path patchPath = "";
ElidedLabel* inputPathLabel = nullptr;
ElidedLabel* patchPathLabel = nullptr;
};

View file

@ -0,0 +1,27 @@
#pragma once
#include <QApplication>
#include <QDialog>
#include <QWidget>
#include <string>
#include "zep.h"
#include "zep/mode_repl.h"
#include "zep/regress.h"
class ShaderEditorWindow : public QDialog {
Q_OBJECT
private:
Zep::ZepWidget_Qt zepWidget;
Zep::IZepReplProvider replProvider;
static constexpr float fontSize = 14.0f;
public:
// Whether this backend supports shader editor
bool supported = true;
ShaderEditorWindow(QWidget* parent, const std::string& filename, const std::string& initialText);
void setText(const std::string& text) { zepWidget.GetEditor().GetMRUBuffer()->SetText(text); }
void setEnable(bool enable);
};

View file

@ -1,6 +1,7 @@
#pragma once
#include <array>
#include <span>
#include <string>
#include <optional>
#include "PICA/pica_vertex.hpp"
@ -66,6 +67,13 @@ class Renderer {
// This function does things like write back or cache necessary state before we delete our context
virtual void deinitGraphicsContext() = 0;
// Functions for hooking up the renderer core to the frontend's shader editor for editing ubershaders in real time
// SupportsShaderReload: Indicates whether the backend offers ubershader reload support or not
// GetUbershader/SetUbershader: Gets or sets the renderer's current ubershader
virtual bool supportsShaderReload() { return false; }
virtual std::string getUbershader() { return ""; }
virtual void setUbershader(const std::string& shader) {}
// Functions for initializing the graphics context for the Qt frontend, where we don't have the convenience of SDL_Window
#ifdef PANDA3DS_FRONTEND_QT
virtual void initGraphicsContext(GL::Context* context) { Helpers::panic("Tried to initialize incompatible renderer with GL context"); }

View file

@ -82,12 +82,17 @@ class RendererGL final : public Renderer {
void textureCopy(u32 inputAddr, u32 outputAddr, u32 totalBytes, u32 inputSize, u32 outputSize, u32 flags) override;
void drawVertices(PICA::PrimType primType, std::span<const PICA::Vertex> vertices) override; // Draw the given vertices
void deinitGraphicsContext() override;
virtual bool supportsShaderReload() override { return true; }
virtual std::string getUbershader() override;
virtual void setUbershader(const std::string& shader) override;
std::optional<ColourBuffer> getColourBuffer(u32 addr, PICA::ColorFmt format, u32 width, u32 height, bool createIfnotFound = true);
// Note: The caller is responsible for deleting the currently bound FBO before calling this
void setFBO(uint handle) { screenFramebuffer.m_handle = handle; }
void resetStateManager() { gl.reset(); }
void initUbershader(OpenGL::Program& program);
#ifdef PANDA3DS_FRONTEND_QT
virtual void initGraphicsContext([[maybe_unused]] GL::Context* context) override { initGraphicsContextInternal(); }

View file

@ -11,7 +11,8 @@ struct Scheduler {
VBlank = 0, // End of frame event
UpdateTimers = 1, // Update kernel timer objects
RunDSP = 2, // Make the emulated DSP run for one audio frame
Panic = 3, // Dummy event that is always pending and should never be triggered (Timestamp = UINT64_MAX)
SignalY2R = 3, // Signal that a Y2R conversion has finished
Panic = 4, // Dummy event that is always pending and should never be triggered (Timestamp = UINT64_MAX)
TotalNumberOfEvents // How many event types do we have in total?
};
static constexpr usize totalNumberOfEvents = static_cast<usize>(EventType::TotalNumberOfEvents);

View file

@ -109,4 +109,5 @@ class ServiceManager {
HIDService& getHID() { return hid; }
NFCService& getNFC() { return nfc; }
DSPService& getDSP() { return dsp; }
Y2RService& getY2R() { return y2r; }
};

View file

@ -113,8 +113,12 @@ class Y2RService {
void startConversion(u32 messagePointer);
void stopConversion(u32 messagePointer);
public:
bool isBusy;
public:
Y2RService(Memory& mem, Kernel& kernel) : mem(mem), kernel(kernel) {}
void reset();
void handleSyncRequest(u32 messagePointer);
void signalConversionDone();
};