mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-01 03:57:17 +01:00
Add overlay (bezel) support
Draws a user image around or behind the PSP screen, to fill the black bars on displays whose aspect ratio doesn't match the PSP's (#20325). - Overlays are PNGs in PSP/OVERLAYS. A plain PNG there just works: it's drawn in front of the game, and its transparent hole is found by walking from the image center to each edge until a nearly opaque pixel. Existing RetroArch overlay images can be dropped in as-is. - A subfolder with an overlay.ini can define overlays with a Name, Layer (Foreground/Background) and an explicit Hole=x,y,w,h. - "Load overlay image..." in the display layout screen imports any PNG (including Android content URIs) into the overlays folder and selects it. - The overlay is fit to the screen (aspect preserved, centered). The hole is mapped with the same scale, and the game is fit into it with the normal stretch / integer scale / aspect ratio options. Offset and scale don't apply while an overlay with a hole is active. This goes through CalculateDisplayOutputRect, so touch mapping and post shaders agree. - The selection is a per-orientation, per-game DisplayLayout setting. - Disabled in VR, Cardboard, and with skip buffer effects (except software rendering), since the presentation path doesn't run there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QGBg32EFPsTXjAFu7dnTcz
This commit is contained in:
1 parent
ff3d184b43
commit
3ce3973781
18 files changed
+697
-6
No files matched your search
@@ -30,6 +30,10 @@
|
||||
#include "Common/System/NativeApp.h"
|
||||
#include "Common/VR/PPSSPPVR.h"
|
||||
#include "Common/StringUtils.h"
|
||||
#include "Common/File/FileUtil.h"
|
||||
#include "Common/System/OSD.h"
|
||||
#include "Common/System/Request.h"
|
||||
#include "Core/Util/PathUtil.h"
|
||||
|
||||
#include "Common/Data/Color/RGBAUtil.h"
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
@@ -41,6 +45,7 @@
|
||||
#include "Core/System.h"
|
||||
#include "GPU/GPUCommon.h"
|
||||
#include "GPU/Common/FramebufferManagerCommon.h"
|
||||
#include "GPU/Common/Overlay.h"
|
||||
#include "GPU/Common/PresentationCommon.h"
|
||||
|
||||
static const int leftColumnWidth = 200;
|
||||
@@ -345,6 +350,54 @@ void DisplayLayoutScreen::CreateViews() {
|
||||
if (!IsVREnabled()) {
|
||||
static const char *bufFilters[] = { "Linear", "Nearest", };
|
||||
leftColumn->Add(new PopupMultiChoice(&config.iDisplayFilter, gr->T("Screen Scaling Filter"), bufFilters, 1, ARRAY_SIZE(bufFilters), I18NCat::GRAPHICS, screenManager()));
|
||||
|
||||
// Overlays (bezels), from PSP/OVERLAYS. Rescanned each time, so new files show up without a restart.
|
||||
ReloadAllOverlayInfo();
|
||||
const std::vector<OverlayInfo> overlays = GetAllOverlayInfo();
|
||||
std::vector<std::string> overlayNames{ std::string(sy->T("Off")) };
|
||||
std::vector<std::string> overlayIds{ "" };
|
||||
bool selectedFound = config.sOverlay.empty();
|
||||
for (const auto &overlay : overlays) {
|
||||
overlayNames.push_back(overlay.name);
|
||||
overlayIds.push_back(overlay.id);
|
||||
if (overlay.id == config.sOverlay)
|
||||
selectedFound = true;
|
||||
}
|
||||
if (!selectedFound) {
|
||||
// Keep showing a selected overlay whose files went missing, so it can be turned off.
|
||||
overlayNames.push_back(config.sOverlay);
|
||||
overlayIds.push_back(config.sOverlay);
|
||||
}
|
||||
if (overlayIds.size() > 1) {
|
||||
auto overlayChoice = leftColumn->Add(new PopupMultiChoiceDynamic(&config.sOverlay, gr->T("Overlay"), overlayNames, I18NCat::NONE, screenManager(), &overlayIds));
|
||||
overlayChoice->OnChoice.Add([](UI::EventParams &) {
|
||||
// The game rect may have moved, which matters for post shaders that run at output resolution.
|
||||
NotifyPostChanges();
|
||||
});
|
||||
}
|
||||
|
||||
// Just pick any PNG: it's copied into the overlays folder and everything is auto-detected.
|
||||
Choice *browseOverlay = leftColumn->Add(new Choice(gr->T("Load overlay image...")));
|
||||
const DeviceOrientation orientation = GetDeviceOrientation();
|
||||
browseOverlay->OnClick.Add([this, orientation](UI::EventParams &) {
|
||||
auto gr = GetI18NCategory(I18NCat::GRAPHICS);
|
||||
const Path savePath = GetSysDirectory(DIRECTORY_CUSTOM_OVERLAYS) / "imported.png";
|
||||
System_BrowseForImage(GetRequesterToken(), gr->T("Load overlay image..."), savePath, [this, orientation, savePath](std::string_view value, int converted) {
|
||||
// If the platform converted the image, it's been saved to savePath already.
|
||||
const Path source = converted == 1 ? savePath : Path(value);
|
||||
std::string id;
|
||||
if (!source.empty() && ImportOverlayImage(source, &id)) {
|
||||
if (converted == 1)
|
||||
File::Delete(savePath);
|
||||
g_Config.GetDisplayLayoutConfig(orientation).sOverlay = id;
|
||||
NotifyPostChanges();
|
||||
RecreateViews();
|
||||
} else if (!value.empty() || converted == 1) {
|
||||
auto gr = GetI18NCategory(I18NCat::GRAPHICS);
|
||||
g_OSD.Show(OSDType::MESSAGE_ERROR, gr->T("Overlay images must be PNG files"));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Draw::DrawContext *draw = screenManager()->getDrawContext();
|
||||
|
||||
Reference in new issue
Block a user