mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-07-14 03:07:08 +12:00
Update home menu branch (#759)
* Fix typo (#680) Co-authored-by: Noumi <139501014+noumidev@users.noreply.github.com> * More PTM stuff Co-Authored-By: Noumi <139501014+noumidev@users.noreply.github.com> * Make system language configurable * Fix building crypto++ for x64 target on Apple silicon MacOS * Attempt to switch to M1 runners again * Prevent selecting Vulkan renderer in Qt frontend and present a message * Libretro: Add system language option * Only enable audio by default on libretro for now * CMake: Bump version * Store configuration file in AppData root if not in working directory (#693) * Store configuration file in AppData root if not in working directory This fixes MacOS app bundles, as the emulator cannot write the config file into the app bundle. * Remove duplicate fs calls * I'm an idiot sandwich --------- Co-authored-by: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> * GL: Add usingGLES to driverInfo struct (#694) * Wayland fixes part 1 * Support GLES on desktop * Qt: Fix Wayland support Qt will only create a Wayland surface when show() is called on the main window and on the ScreenWidget. Thus, call the function before creating the GL context. Doesn't cause regressions on XWayland, untested in other platforms. Fixes #586 * No need to call screen->show() twice * Fix disabling Wayland & building on some distros (#700) * GLES: Properly stub out logic ops * Fix git versioning * Android_Build: Implement ccache (#703) * Android_Build: Implement ccache * Update Android_Build.yml * Update Android_Build.yml --------- Co-authored-by: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> * Removed dead Citra link in readme (#706) * CRO: Lighter icache flushes * Implement Luma icache SVCs * Add missing SVC logs * GPU: Add sw texture copies * Use vk::detail::DynamicLoader instead of vk::DynamicLoader (#710) * Use vk::detail::DynamicLoader instead of vk::DynamicLoader * Update renderer_vk.cpp * Vk: Fix typo * Vk: Lock CI runners to SDK version 1.3.301 temporarily * Vk: Fixing CI pt 2 * Vulkan: Fixing CI pt 3 * Vk: Fix typo * Temporarily give 80MB to all processes (#715) * Try to cross-compile Libretro core for arm64 (#717) * Try to cross-compile Libretro core for arm64 * Bonk * Update Hydra_Build.yml * [WIP] Libretro: Add audio support (#714) * Libretro: Add audio support * Adding audio interface part 1 * Audio device pt 2 * More audio device * More audio device * Morea uudi odevice * More audio device * More audio device * More audio device --------- Co-authored-by: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com> * Libretro audio device: Fix frame count * Mark audio devices as final * Add toggle for libretro audio device (#719) * Very important work (#720) * Very important work * Most important fix * Add more HLE service calls for eshop (#721) * CI: Fix Vulkan SDK action (#723) * GPU registers: Fix writes to some registers ignoring the mask (#725) Co-authored-by: henry <23128103+atem2069@users.noreply.github.com> * OLED theme * OLED theme config fix (#736) Co-authored-by: smiRaphi <neogt404@gmail.com> * Adding Swedish translation * Fix Metal renderer compilation on iOS * [Core] Improve iOS compilation workflow * [Qt] Hook Swedish to UI * AppDataDocumentProvider: Typo (#740) * More iOS work * More iOS progress * More iOS work * AppDataDocumentProvider: Add missing ``COLUMN_FLAGS`` in the default document projectation (#741) Fixes unable to copy files from device to app's internal storage problem * More iOS work * ios: Simplify MTKView interface (still doesn't work though) * ios: Pass CAMetalLayer instead of void* to Obj-C++ bridging header * Fix bridging cast * FINALLY IOS GRAPHICS * ios: Remove printf spam * Metal: Reimplement some texture formats on iOS * metal: implement texture decoder * metal: check for format support * metal: implement texture swizzling * metal: remove unused texture functions * Shadergen types: Add Metal & MSL * Format * Undo submodule changes * Readme: Add Chonkystation 3 * Metal: Use std::unique_ptr for texture decode * AppDataDocumentProvider: Allow to remove documents (#744) * AppDataDocumentProvider: Allow to remove documents * Typo * Metal renderer fixes for iOS * iOS driver: Add doc comments * iOS: Add frontend & frontend build files (#746) * iOS: Add SwiftUI part to repo * Add iOS build script * Update SDL2 submodule * Fix iOS build script * CI: Update xcode tools for iOS * Update iOS_Build.yml * Update iOS build * Lower XCode version * A * Update project.pbxproj * Update iOS_Build.yml * Update iOS_Build.yml * Update build.sh * iOS: Fail on build error * iOS: Add file picker (#747) * iOS: Add file picker * Fix lock placement * Qt: Add runpog icon (#752) * Update discord-rpc submodule (#753) * Remove cryptoppwin submodule (#754) * Add optional texture hashing * Fix build on new Vk SDK (#757) Co-authored-by: Nadia Holmquist Pedersen <893884+nadiaholmquist@users.noreply.github.com> * CI: Use new Vulkan SDK --------- Co-authored-by: Noumi <139501014+noumidev@users.noreply.github.com> Co-authored-by: Thomas <thomas@thomasw.dev> Co-authored-by: Thomas <twvd@users.noreply.github.com> Co-authored-by: Daniel López Guimaraes <danielectra@outlook.com> Co-authored-by: Jonian Guveli <jonian@hardpixel.eu> Co-authored-by: Ishan09811 <156402647+Ishan09811@users.noreply.github.com> Co-authored-by: Auxy6858 <71662994+Auxy6858@users.noreply.github.com> Co-authored-by: Paris Oplopoios <parisoplop@gmail.com> Co-authored-by: henry <23128103+atem2069@users.noreply.github.com> Co-authored-by: smiRaphi <neogt404@gmail.com> Co-authored-by: smiRaphi <87574679+smiRaphi@users.noreply.github.com> Co-authored-by: Daniel Nylander <po@danielnylander.se> Co-authored-by: Samuliak <samuliak77@gmail.com> Co-authored-by: Albert <45282415+ggrtk@users.noreply.github.com> Co-authored-by: Nadia Holmquist Pedersen <893884+nadiaholmquist@users.noreply.github.com>
This commit is contained in:
parent
d5506f311f
commit
082b6216b3
302 changed files with 55525 additions and 747 deletions
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace PICA::ShaderGen {
|
||||
// Graphics API this shader is targetting
|
||||
enum class API { GL, GLES, Vulkan };
|
||||
enum class API { GL, GLES, Vulkan, Metal };
|
||||
|
||||
// Shading language to use (Only GLSL for the time being)
|
||||
enum class Language { GLSL };
|
||||
} // namespace PICA::ShaderGen
|
||||
// Shading language to use
|
||||
enum class Language { GLSL, MSL };
|
||||
} // namespace PICA::ShaderGen
|
||||
|
|
9
include/audio/audio_device.hpp
Normal file
9
include/audio/audio_device.hpp
Normal file
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#if defined(__LIBRETRO__) && defined(USE_LIBRETRO_AUDIO_DEVICE)
|
||||
#include "audio/libretro_audio_device.hpp"
|
||||
using AudioDevice = LibretroAudioDevice;
|
||||
#else
|
||||
#include "audio/miniaudio_device.hpp"
|
||||
using AudioDevice = MiniAudioDevice;
|
||||
#endif
|
36
include/audio/audio_device_interface.hpp
Normal file
36
include/audio/audio_device_interface.hpp
Normal file
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
#include <array>
|
||||
|
||||
#include "config.hpp"
|
||||
#include "helpers.hpp"
|
||||
#include "ring_buffer.hpp"
|
||||
|
||||
class AudioDeviceInterface {
|
||||
protected:
|
||||
static constexpr usize maxFrameCount = 0x2000;
|
||||
|
||||
using Samples = Common::RingBuffer<s16, maxFrameCount * 2>;
|
||||
using RenderBatchCallback = usize (*)(const s16*, usize);
|
||||
|
||||
Samples* samples = nullptr;
|
||||
|
||||
const AudioDeviceConfig& audioSettings;
|
||||
// Store the last stereo sample we output. We play this when underruning to avoid pops.
|
||||
std::array<s16, 2> lastStereoSample{};
|
||||
|
||||
public:
|
||||
AudioDeviceInterface(Samples* samples, const AudioDeviceConfig& audioSettings) : samples(samples), audioSettings(audioSettings) {}
|
||||
|
||||
bool running = false;
|
||||
Samples* getSamples() { return samples; }
|
||||
|
||||
// If safe is on, we create a null audio device
|
||||
virtual void init(Samples& samples, bool safe = false) = 0;
|
||||
virtual void close() = 0;
|
||||
|
||||
virtual void start() = 0;
|
||||
virtual void stop() = 0;
|
||||
|
||||
// Only used for audio devices that render multiple audio frames in one go, eg the libretro audio device.
|
||||
virtual void renderBatch(RenderBatchCallback callback) {}
|
||||
};
|
61
include/audio/libretro_audio_device.hpp
Normal file
61
include/audio/libretro_audio_device.hpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
#pragma once
|
||||
#include <cstring>
|
||||
|
||||
#include "audio/audio_device_interface.hpp"
|
||||
|
||||
class LibretroAudioDevice final : public AudioDeviceInterface {
|
||||
bool initialized = false;
|
||||
|
||||
public:
|
||||
LibretroAudioDevice(const AudioDeviceConfig& audioSettings) : AudioDeviceInterface(nullptr, audioSettings), initialized(false) {
|
||||
running = false;
|
||||
}
|
||||
|
||||
void init(Samples& samples, bool safe = false) override {
|
||||
this->samples = &samples;
|
||||
|
||||
initialized = true;
|
||||
running = false;
|
||||
}
|
||||
|
||||
void close() override {
|
||||
initialized = false;
|
||||
running = false;
|
||||
};
|
||||
|
||||
void start() override { running = true; }
|
||||
void stop() override { running = false; };
|
||||
|
||||
void renderBatch(RenderBatchCallback callback) override {
|
||||
if (running) {
|
||||
static constexpr usize sampleRate = 32768; // 3DS samples per second
|
||||
static constexpr usize frameCount = sampleRate / 60; // 3DS samples per video frame
|
||||
static constexpr usize channelCount = 2;
|
||||
static s16 audioBuffer[frameCount * channelCount];
|
||||
|
||||
usize samplesWritten = 0;
|
||||
samplesWritten += samples->pop(audioBuffer, frameCount * channelCount);
|
||||
|
||||
// Get the last sample for underrun handling
|
||||
if (samplesWritten != 0) {
|
||||
std::memcpy(&lastStereoSample[0], &audioBuffer[(samplesWritten - 1) * 2], sizeof(lastStereoSample));
|
||||
}
|
||||
|
||||
// If underruning, copy the last output sample
|
||||
{
|
||||
s16* pointer = &audioBuffer[samplesWritten * 2];
|
||||
s16 l = lastStereoSample[0];
|
||||
s16 r = lastStereoSample[1];
|
||||
|
||||
for (usize i = samplesWritten; i < frameCount; i++) {
|
||||
*pointer++ = l;
|
||||
*pointer++ = r;
|
||||
}
|
||||
}
|
||||
|
||||
callback(audioBuffer, sizeof(audioBuffer) / (channelCount * sizeof(s16)));
|
||||
}
|
||||
}
|
||||
|
||||
bool isInitialized() const { return initialized; }
|
||||
};
|
|
@ -3,39 +3,31 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "config.hpp"
|
||||
#include "helpers.hpp"
|
||||
#include "audio/audio_device_interface.hpp"
|
||||
#include "miniaudio.h"
|
||||
#include "ring_buffer.hpp"
|
||||
|
||||
class MiniAudioDevice {
|
||||
using Samples = Common::RingBuffer<ma_int16, 0x2000 * 2>;
|
||||
class MiniAudioDevice final : public AudioDeviceInterface {
|
||||
static constexpr ma_uint32 sampleRate = 32768; // 3DS sample rate
|
||||
static constexpr ma_uint32 channelCount = 2; // Audio output is stereo
|
||||
|
||||
bool initialized = false;
|
||||
|
||||
ma_device device;
|
||||
ma_context context;
|
||||
ma_device_config deviceConfig;
|
||||
Samples* samples = nullptr;
|
||||
|
||||
const AudioDeviceConfig& audioSettings;
|
||||
|
||||
bool initialized = false;
|
||||
bool running = false;
|
||||
|
||||
// Store the last stereo sample we output. We play this when underruning to avoid pops.
|
||||
std::array<s16, 2> lastStereoSample;
|
||||
std::vector<std::string> audioDevices;
|
||||
|
||||
public:
|
||||
MiniAudioDevice(const AudioDeviceConfig& audioSettings);
|
||||
|
||||
// If safe is on, we create a null audio device
|
||||
void init(Samples& samples, bool safe = false);
|
||||
void close();
|
||||
void init(Samples& samples, bool safe = false) override;
|
||||
void close() override;
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
void start() override;
|
||||
void stop() override;
|
||||
|
||||
bool isInitialized() const { return initialized; }
|
||||
};
|
|
@ -5,6 +5,7 @@
|
|||
#include "audio/dsp_core.hpp"
|
||||
#include "frontend_settings.hpp"
|
||||
#include "renderer.hpp"
|
||||
#include "services/region_codes.hpp"
|
||||
|
||||
struct AudioDeviceConfig {
|
||||
// Audio curve to use for volumes between 0-100
|
||||
|
@ -48,9 +49,26 @@ struct EmulatorConfig {
|
|||
#endif
|
||||
static constexpr bool accelerateShadersDefault = true;
|
||||
|
||||
#if defined(__LIBRETRO__)
|
||||
static constexpr bool audioEnabledDefault = true;
|
||||
#else
|
||||
static constexpr bool audioEnabledDefault = false;
|
||||
#endif
|
||||
|
||||
// We default to OpenGL on all platforms other than iOS
|
||||
#if defined(PANDA3DS_IOS)
|
||||
static constexpr RendererType rendererDefault = RendererType::Metal;
|
||||
#else
|
||||
static constexpr RendererType rendererDefault = RendererType::OpenGL;
|
||||
#endif
|
||||
|
||||
static constexpr bool hashTexturesDefault = true;
|
||||
|
||||
bool shaderJitEnabled = shaderJitDefault;
|
||||
bool useUbershaders = ubershaderDefault;
|
||||
bool accelerateShaders = accelerateShadersDefault;
|
||||
bool hashTextures = hashTexturesDefault;
|
||||
|
||||
bool accurateShaderMul = false;
|
||||
bool discordRpcEnabled = false;
|
||||
|
||||
|
@ -58,14 +76,14 @@ struct EmulatorConfig {
|
|||
bool forceShadergenForLights = true;
|
||||
int lightShadergenThreshold = 1;
|
||||
|
||||
RendererType rendererType = RendererType::OpenGL;
|
||||
RendererType rendererType = rendererDefault;
|
||||
Audio::DSPCore::Type dspType = Audio::DSPCore::Type::HLE;
|
||||
|
||||
bool sdCardInserted = true;
|
||||
bool sdWriteProtected = false;
|
||||
bool usePortableBuild = false;
|
||||
|
||||
bool audioEnabled = false;
|
||||
bool audioEnabled = audioEnabledDefault;
|
||||
bool vsyncEnabled = true;
|
||||
bool aacEnabled = true; // Enable AAC audio?
|
||||
|
||||
|
@ -77,6 +95,8 @@ struct EmulatorConfig {
|
|||
// Default to 3% battery to make users suffer
|
||||
int batteryPercentage = 3;
|
||||
|
||||
LanguageCodes systemLanguage = LanguageCodes::English;
|
||||
|
||||
// Default ROM path to open in Qt and misc frontends
|
||||
std::filesystem::path defaultRomPath = "";
|
||||
std::filesystem::path filePath;
|
||||
|
@ -104,4 +124,7 @@ struct EmulatorConfig {
|
|||
EmulatorConfig(const std::filesystem::path& path);
|
||||
void load();
|
||||
void save();
|
||||
|
||||
static LanguageCodes languageCodeFromString(std::string inString);
|
||||
static const char* languageCodeToString(LanguageCodes code);
|
||||
};
|
|
@ -181,5 +181,7 @@ class CPU {
|
|||
void addTicks(u64 ticks) { env.AddTicks(ticks); }
|
||||
|
||||
void clearCache() { jit->ClearCache(); }
|
||||
void clearCacheRange(u32 start, u32 size) { jit->InvalidateCacheRange(start, size); }
|
||||
|
||||
void runFrame();
|
||||
};
|
|
@ -7,8 +7,8 @@
|
|||
#include <span>
|
||||
|
||||
#include "PICA/gpu.hpp"
|
||||
#include "audio/audio_device.hpp"
|
||||
#include "audio/dsp_core.hpp"
|
||||
#include "audio/miniaudio_device.hpp"
|
||||
#include "cheats.hpp"
|
||||
#include "config.hpp"
|
||||
#include "cpu.hpp"
|
||||
|
@ -48,14 +48,14 @@ class Emulator {
|
|||
Scheduler scheduler;
|
||||
|
||||
Crypto::AESEngine aesEngine;
|
||||
MiniAudioDevice audioDevice;
|
||||
AudioDevice audioDevice;
|
||||
Cheats cheats;
|
||||
|
||||
public:
|
||||
static constexpr u32 width = 400;
|
||||
static constexpr u32 height = 240 * 2; // * 2 because 2 screens
|
||||
ROMType romType = ROMType::None;
|
||||
bool running = false; // Is the emulator running a game?
|
||||
bool running = false; // Is the emulator running a game?
|
||||
|
||||
private:
|
||||
#ifdef PANDA3DS_ENABLE_HTTP_SERVER
|
||||
|
@ -89,7 +89,6 @@ class Emulator {
|
|||
~Emulator();
|
||||
|
||||
void step();
|
||||
void render();
|
||||
void reset(ReloadOption reload);
|
||||
void runFrame();
|
||||
// Poll the scheduler for events
|
||||
|
@ -127,6 +126,7 @@ class Emulator {
|
|||
LuaManager& getLua() { return lua; }
|
||||
Scheduler& getScheduler() { return scheduler; }
|
||||
Memory& getMemory() { return memory; }
|
||||
AudioDeviceInterface& getAudioDevice() { return audioDevice; }
|
||||
|
||||
RendererType getRendererType() const { return config.rendererType; }
|
||||
Renderer* getRenderer() { return gpu.getRenderer(); }
|
||||
|
|
|
@ -11,6 +11,7 @@ struct FrontendSettings {
|
|||
Dark = 2,
|
||||
GreetingsCat = 3,
|
||||
Cream = 4,
|
||||
Oled = 5,
|
||||
};
|
||||
|
||||
// Different panda-themed window icons
|
||||
|
@ -20,6 +21,7 @@ struct FrontendSettings {
|
|||
Rnap = 2,
|
||||
Rcow = 3,
|
||||
SkyEmu = 4,
|
||||
Runpog = 5,
|
||||
};
|
||||
|
||||
Theme theme = Theme::Dark;
|
||||
|
|
7
include/ios_driver.h
Normal file
7
include/ios_driver.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
|
||||
void iosCreateEmulator();
|
||||
void iosLoadROM(NSString* pathNS);
|
||||
void iosRunFrame(CAMetalLayer* layer);
|
|
@ -5,7 +5,7 @@ namespace IPC {
|
|||
namespace BufferType {
|
||||
enum : std::uint32_t {
|
||||
Send = 1,
|
||||
Receive,
|
||||
Receive = 2,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ namespace KernelHandles {
|
|||
CFG_U, // CFG service (Console & region info)
|
||||
CFG_I,
|
||||
CFG_S, // Used by most system apps in lieu of cfg:u
|
||||
CFG_NOR, // Used by system settings app
|
||||
CSND, // Plays audio directly from PCM samples
|
||||
DLP_SRVR, // Download Play: Server. Used for network play.
|
||||
DSP, // DSP service (Used for audio decoding and output)
|
||||
|
@ -39,9 +40,10 @@ namespace KernelHandles {
|
|||
NIM_U, // Updates
|
||||
NDM, // ?????
|
||||
NS_S, // Nintendo Shell service
|
||||
NWM_EXT, // ?????
|
||||
NWM_UDS, // Local multiplayer
|
||||
NEWS_S, // news:u on steroids
|
||||
NEWS_U, // This service literally has 1 command (AddNotification) and I don't even understand what it does
|
||||
NEWS_U, // This service literally has 1 command (AddNotification)
|
||||
PTM_U, // PTM service (Used for accessing various console info, such as battery, shell and pedometer state)
|
||||
PTM_SYSM, // PTM system service
|
||||
PTM_PLAY, // PTM Play service, used for retrieving play history
|
||||
|
@ -85,6 +87,8 @@ namespace KernelHandles {
|
|||
case CECD: return "CECD";
|
||||
case CFG_U: return "CFG:U";
|
||||
case CFG_I: return "CFG:I";
|
||||
case CFG_S: return "CFG:S";
|
||||
case CFG_NOR: return "CFG:NOR";
|
||||
case CSND: return "CSND";
|
||||
case DSP: return "DSP";
|
||||
case DLP_SRVR: return "DLP::SRVR";
|
||||
|
@ -102,6 +106,7 @@ namespace KernelHandles {
|
|||
case NDM: return "NDM";
|
||||
case NEWS_S: return "NEWS_S";
|
||||
case NEWS_U: return "NEWS_U";
|
||||
case NWM_EXT: return "nwm::EXT";
|
||||
case NWM_UDS: return "nwm::UDS";
|
||||
case NFC: return "NFC";
|
||||
case NIM_AOC: return "NIM:AOC";
|
||||
|
@ -109,6 +114,7 @@ namespace KernelHandles {
|
|||
case PTM_U: return "PTM:U";
|
||||
case PTM_SYSM: return "PTM:SYSM";
|
||||
case PTM_PLAY: return "PTM:PLAY";
|
||||
case PTM_GETS: return "PTM:GETS";
|
||||
case SOC: return "SOC";
|
||||
case SSL: return "SSL";
|
||||
case Y2R: return "Y2R";
|
||||
|
|
|
@ -175,6 +175,8 @@ public:
|
|||
void svcSignalEvent();
|
||||
void svcSetTimer();
|
||||
void svcSleepThread();
|
||||
void svcInvalidateInstructionCacheRange();
|
||||
void svcInvalidateEntireInstructionCache();
|
||||
void connectToPort();
|
||||
void outputDebugString();
|
||||
void waitSynchronization1();
|
||||
|
@ -250,4 +252,6 @@ public:
|
|||
|
||||
void sendGPUInterrupt(GPUInterrupt type) { serviceManager.sendGPUInterrupt(type); }
|
||||
void clearInstructionCache();
|
||||
void clearInstructionCacheRange(u32 start, u32 size);
|
||||
u32 getSharedFontVaddr();
|
||||
};
|
|
@ -19,7 +19,7 @@ struct ResourceLimitValues {
|
|||
// APPLICATION resource limit
|
||||
static constexpr ResourceLimitValues appResourceLimits = {
|
||||
.maxPriority = 0x18,
|
||||
.maxCommit = 0x4000000,
|
||||
.maxCommit = 64_MB + 16_MB, // We're currently giving 80MB to all apps. TODO: Implement extended memory properly
|
||||
.maxThreads = 0x20,
|
||||
.maxEvents = 0x20,
|
||||
.maxMutexes = 0x20,
|
||||
|
@ -33,7 +33,7 @@ static constexpr ResourceLimitValues appResourceLimits = {
|
|||
// SYS_APPLET resource limit
|
||||
static constexpr ResourceLimitValues sysAppletResourceLimits = {
|
||||
.maxPriority = 0x4,
|
||||
.maxCommit = 0x5E00000,
|
||||
.maxCommit = 0x5E00000 - 16_MB,
|
||||
.maxThreads = 0x1D,
|
||||
.maxEvents = 0xB,
|
||||
.maxMutexes = 0x8,
|
||||
|
|
|
@ -132,7 +132,7 @@ public:
|
|||
static constexpr u32 totalPageCount = 1 << (32 - pageShift);
|
||||
|
||||
static constexpr u32 FCRAM_SIZE = u32(128_MB);
|
||||
static constexpr u32 FCRAM_APPLICATION_SIZE = u32(64_MB);
|
||||
static constexpr u32 FCRAM_APPLICATION_SIZE = u32(80_MB);
|
||||
static constexpr u32 FCRAM_PAGE_COUNT = FCRAM_SIZE / pageSize;
|
||||
static constexpr u32 FCRAM_APPLICATION_PAGE_COUNT = FCRAM_APPLICATION_SIZE / pageSize;
|
||||
|
||||
|
|
|
@ -51,8 +51,12 @@ class Renderer {
|
|||
u32 outputWindowWidth = 400;
|
||||
u32 outputWindowHeight = 240 * 2;
|
||||
|
||||
// Should hw renderers hash textures? Stored separately from emulatorConfig because we'll be accessing it constantly, might be merged eventually
|
||||
bool hashTextures = false;
|
||||
|
||||
EmulatorConfig* emulatorConfig = nullptr;
|
||||
|
||||
void doSoftwareTextureCopy(u32 inputAddr, u32 outputAddr, u32 copySize, u32 inputWidth, u32 inputGap, u32 outputWidth, u32 outputGap);
|
||||
public:
|
||||
Renderer(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs);
|
||||
virtual ~Renderer();
|
||||
|
@ -81,6 +85,14 @@ class Renderer {
|
|||
virtual std::string getUbershader() { return ""; }
|
||||
virtual void setUbershader(const std::string& shader) {}
|
||||
|
||||
// Only relevant for OpenGL renderer and other OpenGL-based backends (eg software)
|
||||
// Called to notify the core to use OpenGL ES and not desktop GL
|
||||
virtual void setupGLES() {}
|
||||
|
||||
// Only relevant for Metal renderer on iOS
|
||||
// Passes a SwiftUI MTKView's layer (CAMetalLayer) to the renderer
|
||||
virtual void setMTKLayer(void* layer) {};
|
||||
|
||||
// This function is called on every draw call before parsing vertex data.
|
||||
// It is responsible for things like looking up which vertex/fragment shaders to use, recompiling them if they don't exist, choosing between
|
||||
// ubershaders and shadergen, and so on.
|
||||
|
@ -114,4 +126,5 @@ class Renderer {
|
|||
}
|
||||
|
||||
void setConfig(EmulatorConfig* config) { emulatorConfig = config; }
|
||||
void setHashTextures(bool setting) { hashTextures = setting; }
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
// Stuff like whether specific extensions are supported, and potentially things like OpenGL context information
|
||||
namespace OpenGL {
|
||||
struct Driver {
|
||||
bool usingGLES = false;
|
||||
bool supportsExtFbFetch = false;
|
||||
bool supportsArmFbFetch = false;
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class RendererGL final : public Renderer {
|
|||
OpenGL::VertexArray hwShaderVAO;
|
||||
OpenGL::VertexBuffer vbo;
|
||||
|
||||
// Data
|
||||
// Data
|
||||
struct {
|
||||
// TEV configuration uniform locations
|
||||
GLint textureEnvSourceLoc = -1;
|
||||
|
@ -157,6 +157,7 @@ class RendererGL final : public Renderer {
|
|||
void initGraphicsContextInternal();
|
||||
|
||||
void accelerateVertexUpload(ShaderUnit& shaderUnit, PICA::DrawAcceleration* accel);
|
||||
void compileDisplayShader();
|
||||
|
||||
public:
|
||||
RendererGL(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs)
|
||||
|
@ -169,14 +170,15 @@ class RendererGL final : public Renderer {
|
|||
void clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 control) override; // Clear a GPU buffer in VRAM
|
||||
void displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, u32 outputSize, u32 flags) override; // Perform display transfer
|
||||
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 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;
|
||||
virtual bool prepareForDraw(ShaderUnit& shaderUnit, PICA::DrawAcceleration* accel) override;
|
||||
|
||||
virtual void setupGLES() 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
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
#include "PICA/pica_hash.hpp"
|
||||
#include "PICA/regs.hpp"
|
||||
#include "boost/icl/interval.hpp"
|
||||
#include "helpers.hpp"
|
||||
|
@ -11,55 +13,55 @@ template <typename T>
|
|||
using Interval = boost::icl::right_open_interval<T>;
|
||||
|
||||
struct Texture {
|
||||
u32 location;
|
||||
u32 config; // Magnification/minification filter, wrapping configs, etc
|
||||
PICA::TextureFmt format;
|
||||
OpenGL::uvec2 size;
|
||||
bool valid;
|
||||
using Hash = PICAHash::HashType;
|
||||
|
||||
// Range of VRAM taken up by buffer
|
||||
Interval<u32> range;
|
||||
// OpenGL resources allocated to buffer
|
||||
OpenGL::Texture texture;
|
||||
u32 location;
|
||||
u32 config; // Magnification/minification filter, wrapping configs, etc
|
||||
Hash hash = Hash(0);
|
||||
|
||||
Texture() : valid(false) {}
|
||||
PICA::TextureFmt format;
|
||||
OpenGL::uvec2 size;
|
||||
bool valid;
|
||||
|
||||
Texture(u32 loc, PICA::TextureFmt format, u32 x, u32 y, u32 config, bool valid = true)
|
||||
: location(loc), format(format), size({x, y}), config(config), valid(valid) {
|
||||
// Range of VRAM taken up by buffer
|
||||
Interval<u32> range;
|
||||
// OpenGL resources allocated to buffer
|
||||
OpenGL::Texture texture;
|
||||
|
||||
u64 endLoc = (u64)loc + sizeInBytes();
|
||||
// Check if start and end are valid here
|
||||
range = Interval<u32>(loc, (u32)endLoc);
|
||||
}
|
||||
Texture() : valid(false) {}
|
||||
|
||||
// For 2 textures to "match" we only care about their locations, formats, and dimensions to match
|
||||
// For other things, such as filtering mode, etc, we can just switch the attributes of the cached texture
|
||||
bool matches(Texture& other) {
|
||||
return location == other.location && format == other.format &&
|
||||
size.x() == other.size.x() && size.y() == other.size.y();
|
||||
}
|
||||
Texture(u32 loc, PICA::TextureFmt format, u32 x, u32 y, u32 config, bool valid = true)
|
||||
: location(loc), format(format), size({x, y}), config(config), valid(valid) {
|
||||
u64 endLoc = (u64)loc + sizeInBytes();
|
||||
// Check if start and end are valid here
|
||||
range = Interval<u32>(loc, (u32)endLoc);
|
||||
}
|
||||
|
||||
void allocate();
|
||||
void setNewConfig(u32 newConfig);
|
||||
void decodeTexture(std::span<const u8> data);
|
||||
void free();
|
||||
u64 sizeInBytes();
|
||||
// For 2 textures to "match" we only care about their locations, formats, and dimensions to match
|
||||
// For other things, such as filtering mode, etc, we can just switch the attributes of the cached texture
|
||||
bool matches(Texture& other) {
|
||||
return location == other.location && hash == other.hash && format == other.format && size.x() == other.size.x() && size.y() == other.size.y();
|
||||
}
|
||||
|
||||
u32 decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, std::span<const u8> data);
|
||||
void allocate();
|
||||
void setNewConfig(u32 newConfig);
|
||||
void decodeTexture(std::span<const u8> data);
|
||||
void free();
|
||||
u64 sizeInBytes();
|
||||
|
||||
// Get the morton interleave offset of a texel based on its U and V values
|
||||
static u32 mortonInterleave(u32 u, u32 v);
|
||||
// Get the byte offset of texel (u, v) in the texture
|
||||
static u32 getSwizzledOffset(u32 u, u32 v, u32 width, u32 bytesPerPixel);
|
||||
static u32 getSwizzledOffset_4bpp(u32 u, u32 v, u32 width);
|
||||
u32 decodeTexel(u32 u, u32 v, PICA::TextureFmt fmt, std::span<const u8> data);
|
||||
|
||||
// Returns the format of this texture as a string
|
||||
std::string_view formatToString() {
|
||||
return PICA::textureFormatToString(format);
|
||||
}
|
||||
// Get the morton interleave offset of a texel based on its U and V values
|
||||
static u32 mortonInterleave(u32 u, u32 v);
|
||||
// Get the byte offset of texel (u, v) in the texture
|
||||
static u32 getSwizzledOffset(u32 u, u32 v, u32 width, u32 bytesPerPixel);
|
||||
static u32 getSwizzledOffset_4bpp(u32 u, u32 v, u32 width);
|
||||
|
||||
// Returns the texel at coordinates (u, v) of an ETC1(A4) texture
|
||||
// TODO: Make hasAlpha a template parameter
|
||||
u32 getTexelETC(bool hasAlpha, u32 u, u32 v, u32 width, std::span<const u8> data);
|
||||
u32 decodeETC(u32 alpha, u32 u, u32 v, u64 colourData);
|
||||
// Returns the format of this texture as a string
|
||||
std::string_view formatToString() { return PICA::textureFormatToString(format); }
|
||||
|
||||
// Returns the texel at coordinates (u, v) of an ETC1(A4) texture
|
||||
// TODO: Make hasAlpha a template parameter
|
||||
u32 getTexelETC(bool hasAlpha, u32 u, u32 v, u32 width, std::span<const u8> data);
|
||||
u32 decodeETC(u32 alpha, u32 u, u32 v, u64 colourData);
|
||||
};
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace Metal {
|
|||
} else if (std::is_same<Format_t, PICA::DepthFmt>::value) {
|
||||
pixelFormat = PICA::toMTLPixelFormatDepth((PICA::DepthFmt)format);
|
||||
} else {
|
||||
panic("Invalid format type");
|
||||
Helpers::panic("Invalid format type");
|
||||
}
|
||||
|
||||
MTL::TextureDescriptor* descriptor = MTL::TextureDescriptor::alloc()->init();
|
||||
|
|
|
@ -4,22 +4,28 @@
|
|||
#include <array>
|
||||
#include <string>
|
||||
|
||||
#include "PICA/pica_hash.hpp"
|
||||
#include "PICA/regs.hpp"
|
||||
#include "boost/icl/interval.hpp"
|
||||
#include "helpers.hpp"
|
||||
#include "math_util.hpp"
|
||||
#include "opengl.hpp"
|
||||
#include "renderer_mtl/pica_to_mtl.hpp"
|
||||
// TODO: remove dependency on OpenGL
|
||||
#include "opengl.hpp"
|
||||
|
||||
template <typename T>
|
||||
using Interval = boost::icl::right_open_interval<T>;
|
||||
|
||||
namespace Metal {
|
||||
struct Texture {
|
||||
using Hash = PICAHash::HashType;
|
||||
|
||||
MTL::Device* device;
|
||||
|
||||
u32 location;
|
||||
u32 config; // Magnification/minification filter, wrapping configs, etc
|
||||
Hash hash = Hash(0);
|
||||
|
||||
PICA::TextureFmt format;
|
||||
OpenGL::uvec2 size;
|
||||
bool valid;
|
||||
|
@ -27,7 +33,8 @@ namespace Metal {
|
|||
// Range of VRAM taken up by buffer
|
||||
Interval<u32> range;
|
||||
|
||||
PICA::PixelFormatInfo formatInfo;
|
||||
PICA::MTLPixelFormatInfo formatInfo;
|
||||
MTL::Texture* base = nullptr;
|
||||
MTL::Texture* texture = nullptr;
|
||||
MTL::SamplerState* sampler = nullptr;
|
||||
|
||||
|
@ -43,7 +50,8 @@ namespace Metal {
|
|||
// For 2 textures to "match" we only care about their locations, formats, and dimensions to match
|
||||
// For other things, such as filtering mode, etc, we can just switch the attributes of the cached texture
|
||||
bool matches(Texture& other) {
|
||||
return location == other.location && format == other.format && size.x() == other.size.x() && size.y() == other.size.y();
|
||||
return location == other.location && hash == other.hash && format == other.format && size.x() == other.size.x() &&
|
||||
size.y() == other.size.y();
|
||||
}
|
||||
|
||||
void allocate();
|
||||
|
@ -52,22 +60,7 @@ namespace Metal {
|
|||
void free();
|
||||
u64 sizeInBytes();
|
||||
|
||||
u8 decodeTexelU8(u32 u, u32 v, PICA::TextureFmt fmt, std::span<const u8> data);
|
||||
u16 decodeTexelU16(u32 u, u32 v, PICA::TextureFmt fmt, std::span<const u8> data);
|
||||
u32 decodeTexelU32(u32 u, u32 v, PICA::TextureFmt fmt, std::span<const u8> data);
|
||||
|
||||
// Get the morton interleave offset of a texel based on its U and V values
|
||||
static u32 mortonInterleave(u32 u, u32 v);
|
||||
// Get the byte offset of texel (u, v) in the texture
|
||||
static u32 getSwizzledOffset(u32 u, u32 v, u32 width, u32 bytesPerPixel);
|
||||
static u32 getSwizzledOffset_4bpp(u32 u, u32 v, u32 width);
|
||||
|
||||
// Returns the format of this texture as a string
|
||||
std::string_view formatToString() { return PICA::textureFormatToString(format); }
|
||||
|
||||
// Returns the texel at coordinates (u, v) of an ETC1(A4) texture
|
||||
// TODO: Make hasAlpha a template parameter
|
||||
u32 getTexelETC(bool hasAlpha, u32 u, u32 v, u32 width, std::span<const u8> data);
|
||||
u32 decodeETC(u32 alpha, u32 u, u32 v, u64 colourData);
|
||||
};
|
||||
} // namespace Metal
|
||||
|
|
|
@ -3,31 +3,28 @@
|
|||
#include <Metal/Metal.hpp>
|
||||
|
||||
#include "PICA/regs.hpp"
|
||||
// TODO: remove dependency on OpenGL
|
||||
#include "opengl.hpp"
|
||||
|
||||
namespace PICA {
|
||||
struct PixelFormatInfo {
|
||||
struct MTLPixelFormatInfo {
|
||||
MTL::PixelFormat pixelFormat;
|
||||
size_t bytesPerTexel;
|
||||
void (*decoder)(OpenGL::uvec2, u32, u32, std::span<const u8>, u8*);
|
||||
|
||||
bool needsSwizzle = false;
|
||||
MTL::TextureSwizzleChannels swizzle{
|
||||
.red = MTL::TextureSwizzleRed,
|
||||
.green = MTL::TextureSwizzleGreen,
|
||||
.blue = MTL::TextureSwizzleBlue,
|
||||
.alpha = MTL::TextureSwizzleAlpha,
|
||||
};
|
||||
};
|
||||
|
||||
constexpr PixelFormatInfo pixelFormatInfos[14] = {
|
||||
{MTL::PixelFormatRGBA8Unorm, 4}, // RGBA8
|
||||
{MTL::PixelFormatRGBA8Unorm, 4}, // RGB8
|
||||
{MTL::PixelFormatBGR5A1Unorm, 2}, // RGBA5551
|
||||
{MTL::PixelFormatB5G6R5Unorm, 2}, // RGB565
|
||||
{MTL::PixelFormatABGR4Unorm, 2}, // RGBA4
|
||||
{MTL::PixelFormatRGBA8Unorm, 4}, // IA8
|
||||
{MTL::PixelFormatRG8Unorm, 2}, // RG8
|
||||
{MTL::PixelFormatRGBA8Unorm, 4}, // I8
|
||||
{MTL::PixelFormatA8Unorm, 1}, // A8
|
||||
{MTL::PixelFormatABGR4Unorm, 2}, // IA4
|
||||
{MTL::PixelFormatABGR4Unorm, 2}, // I4
|
||||
{MTL::PixelFormatA8Unorm, 1}, // A4
|
||||
{MTL::PixelFormatRGBA8Unorm, 4}, // ETC1
|
||||
{MTL::PixelFormatRGBA8Unorm, 4}, // ETC1A4
|
||||
};
|
||||
extern MTLPixelFormatInfo mtlPixelFormatInfos[14];
|
||||
|
||||
inline PixelFormatInfo getPixelFormatInfo(TextureFmt format) { return pixelFormatInfos[static_cast<int>(format)]; }
|
||||
void checkForMTLPixelFormatSupport(MTL::Device* device);
|
||||
inline MTLPixelFormatInfo getMTLPixelFormatInfo(TextureFmt format) { return mtlPixelFormatInfos[static_cast<int>(format)]; }
|
||||
|
||||
inline MTL::PixelFormat toMTLPixelFormatColor(ColorFmt format) {
|
||||
switch (format) {
|
||||
|
@ -35,7 +32,11 @@ namespace PICA {
|
|||
case ColorFmt::RGB8: return MTL::PixelFormatRGBA8Unorm;
|
||||
case ColorFmt::RGBA5551: return MTL::PixelFormatRGBA8Unorm; // TODO: use MTL::PixelFormatBGR5A1Unorm?
|
||||
case ColorFmt::RGB565: return MTL::PixelFormatRGBA8Unorm; // TODO: use MTL::PixelFormatB5G6R5Unorm?
|
||||
#ifdef PANDA3DS_IOS
|
||||
case ColorFmt::RGBA4: return MTL::PixelFormatRGBA8Unorm; // IOS + Metal doesn't support AGBR4 properly, at least on simulator
|
||||
#else
|
||||
case ColorFmt::RGBA4: return MTL::PixelFormatABGR4Unorm;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,11 +42,13 @@ class RendererMTL final : public Renderer {
|
|||
virtual void initGraphicsContext([[maybe_unused]] GL::Context* context) override {}
|
||||
#endif
|
||||
|
||||
private:
|
||||
CA::MetalLayer* metalLayer;
|
||||
virtual void setMTKLayer(void* layer) override;
|
||||
|
||||
MTL::Device* device;
|
||||
MTL::CommandQueue* commandQueue;
|
||||
private:
|
||||
CA::MetalLayer* metalLayer = nullptr;
|
||||
|
||||
MTL::Device* device = nullptr;
|
||||
MTL::CommandQueue* commandQueue = nullptr;
|
||||
|
||||
Metal::CommandEncoder commandEncoder;
|
||||
|
||||
|
@ -98,6 +100,7 @@ class RendererMTL final : public Renderer {
|
|||
void endRenderPass() {
|
||||
if (renderCommandEncoder) {
|
||||
renderCommandEncoder->endEncoding();
|
||||
renderCommandEncoder->release();
|
||||
renderCommandEncoder = nullptr;
|
||||
}
|
||||
}
|
||||
|
|
24
include/renderer_mtl/texture_decoder.hpp
Normal file
24
include/renderer_mtl/texture_decoder.hpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
#include "helpers.hpp"
|
||||
// TODO: remove dependency on OpenGL
|
||||
#include "opengl.hpp"
|
||||
|
||||
void decodeTexelABGR8ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelBGR8ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelA1BGR5ToBGR5A1(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelA1BGR5ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelB5G6R5ToB5G6R5(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelB5G6R5ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelABGR4ToABGR4(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelABGR4ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelAI8ToRG8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelGR8ToRG8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelI8ToR8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelA8ToA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelAI4ToABGR4(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelAI4ToRG8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelI4ToR8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelA4ToA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelETC1ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
||||
void decodeTexelETC1A4ToRGBA8(OpenGL::uvec2 size, u32 u, u32 v, std::span<const u8> inData, u8* outData);
|
|
@ -9,8 +9,8 @@
|
|||
namespace Vulkan {
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback(
|
||||
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* callbackData, void* userData
|
||||
vk::DebugUtilsMessageSeverityFlagBitsEXT messageSeverity, vk::DebugUtilsMessageTypeFlagsEXT messageType,
|
||||
const vk::DebugUtilsMessengerCallbackDataEXT* callbackData, void* userData
|
||||
);
|
||||
|
||||
void setObjectName(vk::Device device, vk::ObjectType objectType, const void* objectHandle, const char* format, ...);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include <cstring>
|
||||
|
||||
#include "config.hpp"
|
||||
#include "helpers.hpp"
|
||||
#include "logger.hpp"
|
||||
#include "memory.hpp"
|
||||
|
@ -11,6 +12,8 @@ class CFGService {
|
|||
using Handle = HorizonHandle;
|
||||
|
||||
Memory& mem;
|
||||
const EmulatorConfig& settings;
|
||||
|
||||
CountryCodes country = CountryCodes::US; // Default to USA
|
||||
MAKE_LOG_FUNCTION(log, cfgLogger)
|
||||
|
||||
|
@ -18,8 +21,9 @@ class CFGService {
|
|||
|
||||
// Service functions
|
||||
void getConfigInfoBlk2(u32 messagePointer);
|
||||
void getConfigInfoBlk8(u32 messagePointer);
|
||||
void getConfigInfoBlk8(u32 messagePointer, u32 commandWord);
|
||||
void getCountryCodeID(u32 messagePointer);
|
||||
void getCountryCodeString(u32 messagePointer);
|
||||
void getLocalFriendCodeSeed(u32 messagePointer);
|
||||
void getRegionCanadaUSA(u32 messagePointer);
|
||||
void getSystemModel(u32 messagePointer);
|
||||
|
@ -29,6 +33,11 @@ class CFGService {
|
|||
void setConfigInfoBlk4(u32 messagePointer);
|
||||
void updateConfigNANDSavegame(u32 messagePointer);
|
||||
void translateCountryInfo(u32 messagePointer);
|
||||
void isFangateSupported(u32 messagePointer);
|
||||
|
||||
// cfg:nor functions
|
||||
void norInitialize(u32 messagePointer);
|
||||
void norReadData(u32 messagePointer);
|
||||
|
||||
void getConfigInfo(u32 output, u32 blockID, u32 size, u32 permissionMask);
|
||||
|
||||
|
@ -40,7 +49,7 @@ class CFGService {
|
|||
NOR, // cfg:nor
|
||||
};
|
||||
|
||||
CFGService(Memory& mem) : mem(mem) {}
|
||||
CFGService(Memory& mem, const EmulatorConfig& settings) : mem(mem), settings(settings) {}
|
||||
void reset();
|
||||
void handleSyncRequest(u32 messagePointer, Type type);
|
||||
};
|
|
@ -121,4 +121,4 @@ class GPUService {
|
|||
std::memset(ptr, 0, 0x1000);
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
|
@ -6,9 +6,6 @@
|
|||
#include "result/result.hpp"
|
||||
|
||||
class LCDService {
|
||||
using Handle = HorizonHandle;
|
||||
|
||||
Handle handle = KernelHandles::LCD;
|
||||
Memory& mem;
|
||||
MAKE_LOG_FUNCTION(log, gspLCDLogger)
|
||||
|
||||
|
|
|
@ -6,20 +6,20 @@
|
|||
#include "result/result.hpp"
|
||||
|
||||
class NSService {
|
||||
Memory& mem;
|
||||
Memory& mem;
|
||||
MAKE_LOG_FUNCTION(log, nsLogger)
|
||||
|
||||
// Service commands
|
||||
void launchTitle(u32 messagePointer);
|
||||
// Service commands
|
||||
void launchTitle(u32 messagePointer);
|
||||
|
||||
public:
|
||||
enum class Type {
|
||||
S, // ns:s
|
||||
P, // ns:p
|
||||
C, // ns:c
|
||||
};
|
||||
public:
|
||||
enum class Type {
|
||||
S, // ns:s
|
||||
P, // ns:p
|
||||
C, // ns:c
|
||||
};
|
||||
|
||||
NSService(Memory& mem) : mem(mem) {}
|
||||
void reset();
|
||||
NSService(Memory& mem) : mem(mem) {}
|
||||
void reset();
|
||||
void handleSyncRequest(u32 messagePointer, Type type);
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue