mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Add basic checkbox UI for GPI switched, add display of GPO LEDs
Try it with Parappa.
This commit is contained in:
parent
9dc8c05fae
commit
a059750f5a
10 changed files with 77 additions and 10 deletions
|
@ -852,6 +852,11 @@ void CheckBox::GetContentDimensions(const UIContext &dc, float &w, float &h) con
|
|||
w = bounds_.w;
|
||||
}
|
||||
|
||||
BitCheckBox::BitCheckBox(uint32_t *bitfield, uint32_t bit, std::string_view text, std::string_view smallText, LayoutParams *layoutParams)
|
||||
: CheckBox(nullptr, text, smallText, layoutParams), bitfield_(bitfield), bit_(bit) {
|
||||
_dbg_assert_msg_(bit != 0, "bit is a mask, not a bit index");
|
||||
}
|
||||
|
||||
void BitCheckBox::Toggle() {
|
||||
if (bitfield_) {
|
||||
*bitfield_ = *bitfield_ ^ bit_;
|
||||
|
|
|
@ -916,10 +916,8 @@ private:
|
|||
|
||||
class BitCheckBox : public CheckBox {
|
||||
public:
|
||||
BitCheckBox(uint32_t *bitfield, uint32_t bit, std::string_view text, std::string_view smallText = "", LayoutParams *layoutParams = nullptr)
|
||||
: CheckBox(nullptr, text, smallText, layoutParams), bitfield_(bitfield), bit_(bit) {
|
||||
}
|
||||
|
||||
// bit is a bitmask (should only have a single bit set), not a bit index.
|
||||
BitCheckBox(uint32_t *bitfield, uint32_t bit, std::string_view text, std::string_view smallText = "", LayoutParams *layoutParams = nullptr);
|
||||
BitCheckBox(int *bitfield, int bit, std::string_view text, std::string_view smallText = "", LayoutParams *layoutParams = nullptr) : BitCheckBox((uint32_t *)bitfield, (uint32_t)bit, text, smallText, layoutParams) {}
|
||||
|
||||
void Toggle() override;
|
||||
|
|
|
@ -306,6 +306,8 @@ static const ConfigSetting generalSettings[] = {
|
|||
ConfigSetting("IgnoreCompatSettings", &g_Config.sIgnoreCompatSettings, "", CfgFlag::PER_GAME | CfgFlag::REPORT),
|
||||
|
||||
ConfigSetting("RunBehindPauseMenu", &g_Config.bRunBehindPauseMenu, false, CfgFlag::DEFAULT),
|
||||
|
||||
ConfigSetting("ShowGPOLEDs", &g_Config.bShowGPOLEDs, false, CfgFlag::PER_GAME),
|
||||
};
|
||||
|
||||
static bool DefaultSasThread() {
|
||||
|
|
|
@ -265,6 +265,9 @@ public:
|
|||
bool bRenderDuplicateFrames;
|
||||
bool bRenderMultiThreading;
|
||||
|
||||
// HW debug
|
||||
bool bShowGPOLEDs;
|
||||
|
||||
// Sound
|
||||
bool bEnableSound;
|
||||
int iAudioBackend;
|
||||
|
|
|
@ -100,6 +100,8 @@ static bool kernelRunning = false;
|
|||
KernelObjectPool kernelObjects;
|
||||
KernelStats kernelStats;
|
||||
u32 registeredExitCbId;
|
||||
u32 g_GPOBits; // Really just 8 bits on the real hardware.
|
||||
u32 g_GPIBits; // Really just 8 bits on the real hardware.
|
||||
|
||||
void __KernelInit()
|
||||
{
|
||||
|
@ -161,6 +163,7 @@ void __KernelInit()
|
|||
__PPGeInit();
|
||||
|
||||
kernelRunning = true;
|
||||
g_GPOBits = 0;
|
||||
INFO_LOG(SCEKERNEL, "Kernel initialized.");
|
||||
}
|
||||
|
||||
|
@ -355,18 +358,19 @@ int sceKernelRegisterDefaultExceptionHandler()
|
|||
return 0;
|
||||
}
|
||||
|
||||
void sceKernelSetGPO(u32 ledAddr)
|
||||
void sceKernelSetGPO(u32 ledBits)
|
||||
{
|
||||
// Sets debug LEDs.
|
||||
// Not really interesting, and a few games really spam it
|
||||
// DEBUG_LOG(SCEKERNEL, "sceKernelSetGPO(%02x)", ledAddr);
|
||||
// Sets debug LEDs. Some games do interesting stuff with this, like a metronome in Parappa.
|
||||
// Shows up as a vertical strip of LEDs at the side of the screen, if enabled.
|
||||
g_GPOBits = ledBits;
|
||||
}
|
||||
|
||||
u32 sceKernelGetGPI()
|
||||
{
|
||||
// Always returns 0 on production systems.
|
||||
DEBUG_LOG(SCEKERNEL, "0=sceKernelGetGPI()");
|
||||
return 0;
|
||||
// On developer systems, there are 8 switches that control the lower 8 bits of the return value.
|
||||
DEBUG_LOG(SCEKERNEL, "%d=sceKernelGetGPI()", g_GPIBits);
|
||||
return g_GPIBits;
|
||||
}
|
||||
|
||||
// #define LOG_CACHE
|
||||
|
|
|
@ -569,6 +569,9 @@ struct KernelStats {
|
|||
extern KernelStats kernelStats;
|
||||
extern u32 registeredExitCbId;
|
||||
|
||||
extern u32 g_GPOBits;
|
||||
extern u32 g_GPIBits;
|
||||
|
||||
void Register_ThreadManForUser();
|
||||
void Register_ThreadManForKernel();
|
||||
void Register_LoadExecForUser();
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "Core/System.h"
|
||||
#include "Core/Reporting.h"
|
||||
#include "Core/CoreParameter.h"
|
||||
#include "Core/HLE/sceKernel.h" // GPI/GPO
|
||||
#include "Core/MIPS/MIPSTables.h"
|
||||
#include "Core/MIPS/JitCommon/JitBlockCache.h"
|
||||
#include "Core/MIPS/JitCommon/JitCommon.h"
|
||||
|
@ -141,6 +142,11 @@ void DevMenuScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
|||
|
||||
items->Add(new Choice(dev->T("Reset limited logging")))->OnClick.Handle(this, &DevMenuScreen::OnResetLimitedLogging);
|
||||
|
||||
items->Add(new Choice(dev->T("GPI/GPO switches/LEDs")))->OnClick.Add([=](UI::EventParams &e) {
|
||||
screenManager()->push(new GPIGPOScreen(dev->T("GPI/GPO switches/LEDs")));
|
||||
return UI::EVENT_DONE;
|
||||
});
|
||||
|
||||
items->Add(new Choice(dev->T("Create frame dump")))->OnClick.Add([](UI::EventParams &e) {
|
||||
GPURecord::RecordNextFrame([](const Path &dumpPath) {
|
||||
NOTICE_LOG(SYSTEM, "Frame dump created at '%s'", dumpPath.c_str());
|
||||
|
@ -213,6 +219,16 @@ void DevMenuScreen::dialogFinished(const Screen *dialog, DialogResult result) {
|
|||
// TriggerFinish(DR_OK);
|
||||
}
|
||||
|
||||
void GPIGPOScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
using namespace UI;
|
||||
auto dev = GetI18NCategory(I18NCat::DEVELOPER);
|
||||
parent->Add(new CheckBox(&g_Config.bShowGPOLEDs, dev->T("Show GPO LEDs")));
|
||||
for (int i = 0; i < 8; i++) {
|
||||
std::string name = ApplySafeSubstitutions(dev->T("GPI switch %1"), i);
|
||||
parent->Add(new BitCheckBox(&g_GPIBits, 1 << i, name));
|
||||
}
|
||||
}
|
||||
|
||||
void LogScreen::UpdateLog() {
|
||||
using namespace UI;
|
||||
RingbufferLogListener *ring = LogManager::GetInstance()->GetRingbufferListener();
|
||||
|
|
|
@ -145,6 +145,15 @@ private:
|
|||
unsigned int addr_;
|
||||
};
|
||||
|
||||
class GPIGPOScreen : public PopupScreen {
|
||||
public:
|
||||
GPIGPOScreen(std::string_view title) : PopupScreen(title, "OK") {}
|
||||
const char *tag() const override { return "GPIGPO"; }
|
||||
|
||||
protected:
|
||||
void CreatePopupContents(UI::ViewGroup *parent) override;
|
||||
};
|
||||
|
||||
class JitCompareScreen : public UIDialogScreenWithBackground {
|
||||
public:
|
||||
void CreateViews() override;
|
||||
|
|
|
@ -1521,6 +1521,8 @@ bool EmuScreen::hasVisibleUI() {
|
|||
return true;
|
||||
if (g_Config.bEnableCardboardVR || g_Config.bEnableNetworkChat)
|
||||
return true;
|
||||
if (g_Config.bShowGPOLEDs)
|
||||
return true;
|
||||
// Debug UI.
|
||||
if ((DebugOverlay)g_Config.iDebugOverlay != DebugOverlay::OFF || g_Config.bShowDeveloperMenu)
|
||||
return true;
|
||||
|
@ -1571,6 +1573,26 @@ void EmuScreen::renderUI() {
|
|||
}
|
||||
#endif
|
||||
|
||||
if (g_Config.bShowGPOLEDs) {
|
||||
// Draw a vertical strip of LEDs at the right side of the screen.
|
||||
const float ledSize = 24.0f;
|
||||
const float spacing = 4.0f;
|
||||
const float height = 8 * ledSize + 7 * spacing;
|
||||
const float x = ctx->GetBounds().w - spacing - ledSize;
|
||||
const float y = (ctx->GetBounds().h - height) * 0.5f;
|
||||
ctx->FillRect(UI::Drawable(0xFF000000), Bounds(x - spacing, y - spacing, ledSize + spacing * 2, height + spacing * 2));
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int bit = (g_GPOBits >> i) & 1;
|
||||
uint32_t color = 0xFF30FF30;
|
||||
if (!bit) {
|
||||
color = darkenColor(darkenColor(color));
|
||||
}
|
||||
Bounds ledBounds(x, y + (spacing + ledSize) * i, ledSize, ledSize);
|
||||
ctx->FillRect(UI::Drawable(color), ledBounds);
|
||||
}
|
||||
ctx->Flush();
|
||||
}
|
||||
|
||||
if (coreState == CORE_RUNTIME_ERROR || coreState == CORE_STEPPING) {
|
||||
const MIPSExceptionInfo &info = Core_GetExceptionInfo();
|
||||
if (info.type != MIPSExceptionType::NONE) {
|
||||
|
|
|
@ -1843,6 +1843,11 @@ void DeveloperToolsScreen::CreateViews() {
|
|||
|
||||
list->Add(new CheckBox(&g_Config.bShowOnScreenMessages, dev->T("Show on-screen messages")));
|
||||
|
||||
list->Add(new Choice(dev->T("GPI/GPO switches/LEDs")))->OnClick.Add([=](UI::EventParams &e) {
|
||||
screenManager()->push(new GPIGPOScreen(dev->T("GPI/GPO switches/LEDs")));
|
||||
return UI::EVENT_DONE;
|
||||
});
|
||||
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
static const char *framerateModes[] = { "Default", "Request 60Hz", "Force 60Hz" };
|
||||
PopupMultiChoice *framerateMode = list->Add(new PopupMultiChoice(&g_Config.iDisplayFramerateMode, gr->T("Framerate mode"), framerateModes, 0, ARRAY_SIZE(framerateModes), I18NCat::GRAPHICS, screenManager()));
|
||||
|
|
Loading…
Add table
Reference in a new issue