Skip to content

Commit

Permalink
Merge pull request #20029 from hrydgard/misc-fixes
Browse files Browse the repository at this point in the history
Add long-requested feature to take screenshots of the raw game image instead of the processed output.
  • Loading branch information
hrydgard authored Feb 24, 2025
2 parents 1119728 + 4dba1c3 commit e8df6d4
Show file tree
Hide file tree
Showing 59 changed files with 241 additions and 144 deletions.
9 changes: 0 additions & 9 deletions Common/Input/KeyCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,15 +281,6 @@ enum InputAxis {
JOYSTICK_AXIS_DISTANCE = 24,
JOYSTICK_AXIS_TILT = 25,

// Ouya axises. Just here for reference, they map straight to regular android axises
// and will be mapped the same way.
JOYSTICK_OUYA_AXIS_L2 = 17,
JOYSTICK_OUYA_AXIS_LS_X = 0,
JOYSTICK_OUYA_AXIS_LS_Y = 1,
JOYSTICK_OUYA_AXIS_R2 = 18,
JOYSTICK_OUYA_AXIS_RS_X = 11,
JOYSTICK_OUYA_AXIS_RS_Y = 14,

// Relative mouse axis for PC.
JOYSTICK_AXIS_MOUSE_REL_X = 26,
JOYSTICK_AXIS_MOUSE_REL_Y = 27,
Expand Down
1 change: 1 addition & 0 deletions Core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ static const ConfigSetting generalSettings[] = {
ConfigSetting("DebugOverlay", &g_Config.iDebugOverlay, 0, CfgFlag::DONT_SAVE),
ConfigSetting("DefaultTab", &g_Config.iDefaultTab, 0, CfgFlag::DEFAULT),

ConfigSetting("ScreenshotMode", &g_Config.iScreenshotMode, 0, CfgFlag::DEFAULT),
ConfigSetting("ScreenshotsAsPNG", &g_Config.bScreenshotsAsPNG, false, CfgFlag::PER_GAME),
ConfigSetting("UseFFV1", &g_Config.bUseFFV1, false, CfgFlag::DEFAULT),
ConfigSetting("DumpFrames", &g_Config.bDumpFrames, false, CfgFlag::DEFAULT),
Expand Down
1 change: 1 addition & 0 deletions Core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ struct Config {
bool bUberShaderVertex;
bool bUberShaderFragment;
int iDefaultTab;
int iScreenshotMode;

std::vector<std::string> vPostShaderNames; // Off for chain end (only Off for no shader)
std::map<std::string, float> mPostShaderSetting;
Expand Down
5 changes: 5 additions & 0 deletions Core/ConfigValues.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ enum BufferFilter {
SCALE_NEAREST = 2,
};

enum class ScreenshotMode {
FinalOutput = 0,
GameImage = 1,
};

// Software is not among these because it will have one of these perform the blit to display.
enum class GPUBackend {
OPENGL = 0,
Expand Down
3 changes: 1 addition & 2 deletions Core/HLE/sceCtrl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,7 @@ void __CtrlSetAnalogY(int stick, float y) {
ctrlCurrent.analog[stick][CTRL_ANALOG_Y] = scaledY;
}

void __CtrlSetRapidFire(bool state, int interval)
{
void __CtrlSetRapidFire(bool state, int interval) {
emuRapidFire = state;
emuRapidFireToggle = true;
emuRapidFireInterval = interval;
Expand Down
8 changes: 1 addition & 7 deletions Core/KeyMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -730,8 +730,6 @@ void RestoreDefault() {
std::string name = System_GetProperty(SYSPROP_NAME);
if (IsNvidiaShield(name)) {
SetDefaultKeyMap(DEFAULT_MAPPING_SHIELD, false);
} else if (IsOuya(name)) {
SetDefaultKeyMap(DEFAULT_MAPPING_OUYA, false);
} else if (IsXperiaPlay(name)) {
SetDefaultKeyMap(DEFAULT_MAPPING_XPERIA_PLAY, false);
} else if (IsMOQII7S(name)) {
Expand Down Expand Up @@ -812,10 +810,6 @@ void ClearAllMappings() {
g_controllerMapGeneration++;
}

bool IsOuya(const std::string &name) {
return name == "OUYA:OUYA Console";
}

bool IsNvidiaShield(const std::string &name) {
return name == "NVIDIA:SHIELD";
}
Expand All @@ -839,7 +833,7 @@ bool IsMOQII7S(const std::string &name) {
}

bool HasBuiltinController(const std::string &name) {
return IsOuya(name) || IsXperiaPlay(name) || IsNvidiaShield(name) || IsMOQII7S(name) || IsRetroid(name);
return IsXperiaPlay(name) || IsNvidiaShield(name) || IsMOQII7S(name) || IsRetroid(name);
}

void NotifyPadConnected(InputDeviceID deviceId, const std::string &name) {
Expand Down
1 change: 0 additions & 1 deletion Core/KeyMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@ namespace KeyMap {
bool IsNvidiaShield(const std::string &name);
bool IsNvidiaShieldTV(const std::string &name);
bool IsXperiaPlay(const std::string &name);
bool IsOuya(const std::string &name);
bool IsMOQII7S(const std::string &name);
bool IsRetroid(const std::string &name);
bool HasBuiltinController(const std::string &name);
Expand Down
24 changes: 0 additions & 24 deletions Core/KeyMapDefaults.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,27 +301,6 @@ static const DefMappingStruct defaultPadMapIOS[] = {
{VIRTKEY_FASTFORWARD , JOYSTICK_AXIS_RTRIGGER, +1},
};

static const DefMappingStruct defaultOuyaMap[] = {
{CTRL_CROSS , NKCODE_BUTTON_A},
{CTRL_CIRCLE , NKCODE_BUTTON_B},
{CTRL_SQUARE , NKCODE_BUTTON_X},
{CTRL_TRIANGLE , NKCODE_BUTTON_Y},
{CTRL_UP , NKCODE_DPAD_UP},
{CTRL_RIGHT , NKCODE_DPAD_RIGHT},
{CTRL_DOWN , NKCODE_DPAD_DOWN},
{CTRL_LEFT , NKCODE_DPAD_LEFT},
{CTRL_START , NKCODE_BUTTON_R2},
{CTRL_SELECT , NKCODE_BUTTON_L2},
{CTRL_LTRIGGER , NKCODE_BUTTON_L1},
{CTRL_RTRIGGER , NKCODE_BUTTON_R1},
{VIRTKEY_FASTFORWARD , NKCODE_BUTTON_THUMBL},
{VIRTKEY_PAUSE , NKCODE_BUTTON_THUMBR},
{VIRTKEY_AXIS_X_MIN, JOYSTICK_AXIS_X, -1},
{VIRTKEY_AXIS_X_MAX, JOYSTICK_AXIS_X, +1},
{VIRTKEY_AXIS_Y_MIN, JOYSTICK_AXIS_Y, +1},
{VIRTKEY_AXIS_Y_MAX, JOYSTICK_AXIS_Y, -1},
};

static const DefMappingStruct defaultXperiaPlay[] = {
{CTRL_CROSS , NKCODE_BUTTON_CROSS},
{CTRL_CIRCLE , NKCODE_BUTTON_CIRCLE},
Expand Down Expand Up @@ -411,9 +390,6 @@ void SetDefaultKeyMap(DefaultMaps dmap, bool replace) {
case DEFAULT_MAPPING_IOS_PAD:
SetDefaultKeyMap(DEVICE_ID_PAD_0, defaultPadMapIOS, ARRAY_SIZE(defaultPadMapIOS), replace);
break;
case DEFAULT_MAPPING_OUYA:
SetDefaultKeyMap(DEVICE_ID_PAD_0, defaultOuyaMap, ARRAY_SIZE(defaultOuyaMap), replace);
break;
case DEFAULT_MAPPING_XPERIA_PLAY:
SetDefaultKeyMap(DEVICE_ID_DEFAULT, defaultXperiaPlay, ARRAY_SIZE(defaultXperiaPlay), replace);
break;
Expand Down
1 change: 0 additions & 1 deletion Core/KeyMapDefaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ enum DefaultMaps {
DEFAULT_MAPPING_XINPUT,
DEFAULT_MAPPING_ANDROID_XBOX, // XBox controller or similar on Android
DEFAULT_MAPPING_SHIELD,
DEFAULT_MAPPING_OUYA,
DEFAULT_MAPPING_XPERIA_PLAY,
DEFAULT_MAPPING_MOQI_I7S,
DEFAULT_MAPPING_RETROID_CONTROLLER,
Expand Down
167 changes: 84 additions & 83 deletions UI/EmuScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -787,28 +787,6 @@ void EmuScreen::onVKey(VirtKey virtualKeyCode, bool down) {
}
break;

case VIRTKEY_OPENCHAT:
if (down && g_Config.bEnableNetworkChat && !g_Config.bShowImDebugger) {
UI::EventParams e{};
OnChatMenu.Trigger(e);
controlMapper_.ForceReleaseVKey(virtualKeyCode);
}
break;

case VIRTKEY_AXIS_SWAP:
if (down) {
controlMapper_.ToggleSwapAxes();
g_OSD.Show(OSDType::MESSAGE_INFO, mc->T("AxisSwap")); // best string we have.
}
break;

case VIRTKEY_DEVMENU:
if (down) {
UI::EventParams e{};
OnDevMenu.Trigger(e);
}
break;

case VIRTKEY_RESET_EMULATION:
System_PostUIMessage(UIMessage::REQUEST_GAME_RESET);
break;
Expand Down Expand Up @@ -866,85 +844,97 @@ void EmuScreen::onVKey(VirtKey virtualKeyCode, bool down) {
System_PostUIMessage(UIMessage::SAVESTATE_DISPLAY_SLOT);
}
break;
case VIRTKEY_TOGGLE_FULLSCREEN:
case VIRTKEY_SCREENSHOT:
if (down)
System_ToggleFullscreenState("");
g_TakeScreenshot = true;
break;
case VIRTKEY_TOGGLE_TOUCH_CONTROLS:
case VIRTKEY_RAPID_FIRE:
__CtrlSetRapidFire(down, g_Config.iRapidFireInterval);
break;
default:
// To make sure we're not in an async context.
if (down) {
if (g_Config.bShowTouchControls) {
// This just messes with opacity if enabled, so you can touch the screen again to bring them back.
if (GamepadGetOpacity() < 0.01f) {
GamepadTouch();
} else {
// Reset.
GamepadTouch(true);
}
} else {
// If touch controls are disabled though, they'll get enabled.
g_Config.bShowTouchControls = true;
RecreateViews();
GamepadTouch();
}
queuedVirtKeys_.push_back(virtualKeyCode);
}
break;
case VIRTKEY_TOGGLE_MOUSE:
if (down) {
g_Config.bMouseControl = !g_Config.bMouseControl;
}
}

void EmuScreen::ProcessQueuedVKeys() {
for (auto iter : queuedVirtKeys_) {
ProcessVKey(iter);
}
queuedVirtKeys_.clear();
}

void EmuScreen::ProcessVKey(VirtKey virtKey) {
auto mc = GetI18NCategory(I18NCat::MAPPABLECONTROLS);
auto sc = GetI18NCategory(I18NCat::SCREEN);

switch (virtKey) {
case VIRTKEY_OPENCHAT:
if (g_Config.bEnableNetworkChat && !g_Config.bShowImDebugger) {
UI::EventParams e{};
OnChatMenu.Trigger(e);
controlMapper_.ForceReleaseVKey(VIRTKEY_OPENCHAT);
}
break;
case VIRTKEY_SCREENSHOT:
if (down)
g_TakeScreenshot = true;

case VIRTKEY_AXIS_SWAP:
controlMapper_.ToggleSwapAxes();
g_OSD.Show(OSDType::MESSAGE_INFO, mc->T("AxisSwap")); // best string we have.
break;

case VIRTKEY_TEXTURE_DUMP:
if (down) {
g_Config.bSaveNewTextures = !g_Config.bSaveNewTextures;
if (g_Config.bSaveNewTextures) {
g_OSD.Show(OSDType::MESSAGE_INFO, sc->T("saveNewTextures_true", "Textures will now be saved to your storage"), 2.0, "savetexturechanged");
System_PostUIMessage(UIMessage::GPU_CONFIG_CHANGED);
} else {
g_OSD.Show(OSDType::MESSAGE_INFO, sc->T("saveNewTextures_false", "Texture saving was disabled"), 2.0, "savetexturechanged");
}
case VIRTKEY_DEVMENU:
{
UI::EventParams e{};
OnDevMenu.Trigger(e);
}
break;
case VIRTKEY_TEXTURE_REPLACE:
if (down) {
g_Config.bReplaceTextures = !g_Config.bReplaceTextures;
if (g_Config.bReplaceTextures)
g_OSD.Show(OSDType::MESSAGE_INFO, sc->T("replaceTextures_true", "Texture replacement enabled"), 2.0, "replacetexturechanged");
else
g_OSD.Show(OSDType::MESSAGE_INFO, sc->T("replaceTextures_false", "Textures are no longer being replaced"), 2.0, "replacetexturechanged");

case VIRTKEY_TOGGLE_MOUSE:
g_Config.bMouseControl = !g_Config.bMouseControl;
break;

case VIRTKEY_TEXTURE_DUMP:
g_Config.bSaveNewTextures = !g_Config.bSaveNewTextures;
if (g_Config.bSaveNewTextures) {
g_OSD.Show(OSDType::MESSAGE_INFO, sc->T("saveNewTextures_true", "Textures will now be saved to your storage"), 2.0, "savetexturechanged");
System_PostUIMessage(UIMessage::GPU_CONFIG_CHANGED);
} else {
g_OSD.Show(OSDType::MESSAGE_INFO, sc->T("saveNewTextures_false", "Texture saving was disabled"), 2.0, "savetexturechanged");
}
break;
case VIRTKEY_RAPID_FIRE:
__CtrlSetRapidFire(down, g_Config.iRapidFireInterval);

case VIRTKEY_TEXTURE_REPLACE:
g_Config.bReplaceTextures = !g_Config.bReplaceTextures;
if (g_Config.bReplaceTextures)
g_OSD.Show(OSDType::MESSAGE_INFO, sc->T("replaceTextures_true", "Texture replacement enabled"), 2.0, "replacetexturechanged");
else
g_OSD.Show(OSDType::MESSAGE_INFO, sc->T("replaceTextures_false", "Textures are no longer being replaced"), 2.0, "replacetexturechanged");
System_PostUIMessage(UIMessage::GPU_CONFIG_CHANGED);
break;

case VIRTKEY_MUTE_TOGGLE:
if (down)
g_Config.bEnableSound = !g_Config.bEnableSound;
g_Config.bEnableSound = !g_Config.bEnableSound;
break;

case VIRTKEY_SCREEN_ROTATION_VERTICAL:
if (down)
g_Config.iInternalScreenRotation = ROTATION_LOCKED_VERTICAL;
g_Config.iInternalScreenRotation = ROTATION_LOCKED_VERTICAL;
break;
case VIRTKEY_SCREEN_ROTATION_VERTICAL180:
if (down)
g_Config.iInternalScreenRotation = ROTATION_LOCKED_VERTICAL180;
g_Config.iInternalScreenRotation = ROTATION_LOCKED_VERTICAL180;
break;
case VIRTKEY_SCREEN_ROTATION_HORIZONTAL:
if (down)
g_Config.iInternalScreenRotation = ROTATION_LOCKED_HORIZONTAL;
g_Config.iInternalScreenRotation = ROTATION_LOCKED_HORIZONTAL;
break;
case VIRTKEY_SCREEN_ROTATION_HORIZONTAL180:
if (down)
g_Config.iInternalScreenRotation = ROTATION_LOCKED_HORIZONTAL180;
g_Config.iInternalScreenRotation = ROTATION_LOCKED_HORIZONTAL180;
break;

case VIRTKEY_TOGGLE_WLAN:
// Let's not allow the user to toggle wlan while connected, could get confusing.
if (down && !g_netInited) {
if (!g_netInited) {
auto n = GetI18NCategory(I18NCat::NETWORKING);
auto di = GetI18NCategory(I18NCat::DIALOG);
g_Config.bEnableWlan = !g_Config.bEnableWlan;
Expand All @@ -953,17 +943,28 @@ void EmuScreen::onVKey(VirtKey virtualKeyCode, bool down) {
"%s: %s", n->T("Enable networking"), g_Config.bEnableWlan ? di->T("Enabled") : di->T("Disabled")), 2.0, "toggle_wlan");
}
break;
default:
// To make sure we're not in an async context.
if (down) {
queuedVirtKey_ = virtualKeyCode;

case VIRTKEY_TOGGLE_FULLSCREEN:
System_ToggleFullscreenState("");
break;

case VIRTKEY_TOGGLE_TOUCH_CONTROLS:
if (g_Config.bShowTouchControls) {
// This just messes with opacity if enabled, so you can touch the screen again to bring them back.
if (GamepadGetOpacity() < 0.01f) {
GamepadTouch();
} else {
// Reset.
GamepadTouch(true);
}
} else {
// If touch controls are disabled though, they'll get enabled.
g_Config.bShowTouchControls = true;
RecreateViews();
GamepadTouch();
}
break;
}
}

void EmuScreen::ProcessQueuedVKeys() {
switch (queuedVirtKey_) {
case VIRTKEY_EXIT_APP:
{
std::string confirmExitMessage = GetConfirmExitMessage();
Expand All @@ -981,10 +982,10 @@ void EmuScreen::ProcessQueuedVKeys() {
}
break;
}

default:
break;
}
queuedVirtKey_ = (VirtKey)0;
}

void EmuScreen::onVKeyAnalog(VirtKey virtualKeyCode, float value) {
Expand Down
3 changes: 2 additions & 1 deletion UI/EmuScreen.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class EmuScreen : public UIScreen {
bool checkPowerDown();

void ProcessQueuedVKeys();
void ProcessVKey(VirtKey vkey);

UI::Event OnDevMenu;
UI::Event OnChatMenu;
Expand Down Expand Up @@ -147,7 +148,7 @@ class EmuScreen : public UIScreen {

bool lastImguiEnabled_ = false;

VirtKey queuedVirtKey_ = (VirtKey)0;
std::vector<VirtKey> queuedVirtKeys_;
};

bool MustRunBehind();
Expand Down
2 changes: 2 additions & 0 deletions UI/GameSettingsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1336,6 +1336,8 @@ void GameSettingsScreen::CreateSystemSettings(UI::ViewGroup *systemSettings) {
systemSettings->Add(new CheckBox(&g_Config.bCacheFullIsoInRam, sy->T("Cache ISO in RAM", "Cache full ISO in RAM")))->SetEnabled(!PSP_IsInited());
systemSettings->Add(new CheckBox(&g_Config.bCheckForNewVersion, sy->T("VersionCheck", "Check for new versions of PPSSPP")));
systemSettings->Add(new CheckBox(&g_Config.bScreenshotsAsPNG, sy->T("Screenshots as PNG")));
static const char *screenshotModeChoices[] = { "Final processed image", "Raw game image" };
systemSettings->Add(new PopupMultiChoice(&g_Config.iScreenshotMode, sy->T("Screenshot mode"), screenshotModeChoices, 0, ARRAY_SIZE(screenshotModeChoices), I18NCat::SYSTEM, screenManager()));
// TODO: Make this setting available on Mac too.
#if PPSSPP_PLATFORM(WINDOWS)
systemSettings->Add(new CheckBox(&g_Config.bPauseOnLostFocus, sy->T("Pause when not focused")));
Expand Down
Loading

0 comments on commit e8df6d4

Please sign in to comment.