Make window resizable and preserve aspect ratio on resize

Video now scales to fill the window while keeping its 16:9 display ratio
in both windowed and fullscreen modes. The RCO menu is scaled to fill the
window at its native 480x272 aspect ratio.
This commit is contained in:
2026-09-15 23:32:33 -04:00
parent e035d0c118
commit 7513ae3a43
2 changed files with 27 additions and 18 deletions
@@ -75,6 +75,9 @@ public final class PlayerApp extends Application {
scene.setFill(Color.BLACK); scene.setFill(Color.BLACK);
stage.setTitle("useless-umd-player"); stage.setTitle("useless-umd-player");
stage.setScene(scene); stage.setScene(scene);
stage.setResizable(true);
stage.setMinWidth(160);
stage.setMinHeight(90);
stage.show(); stage.show();
scene.setOnKeyPressed(event -> { scene.setOnKeyPressed(event -> {
@@ -274,26 +277,22 @@ public final class PlayerApp extends Application {
g.setFill(Color.BLACK); g.setFill(Color.BLACK);
g.fillRect(0, 0, canvasWidth, canvasHeight); g.fillRect(0, 0, canvasWidth, canvasHeight);
if (stage.isFullScreen()) { // Fill the window/screen while keeping the 16:9 display ratio,
// Scale up to fill the screen but keep the 16:9 display ratio. // letterboxing or pillarboxing as needed.
double aspect = 16.0 / 9.0; double aspect = 16.0 / 9.0;
double canvasAspect = canvasWidth / canvasHeight; double canvasAspect = canvasWidth / canvasHeight;
double drawW; double drawW;
double drawH; double drawH;
if (canvasAspect > aspect) { if (canvasAspect > aspect) {
drawH = canvasHeight; drawH = canvasHeight;
drawW = canvasHeight * aspect; drawW = canvasHeight * aspect;
} else {
drawW = canvasWidth;
drawH = canvasWidth / aspect;
}
double x = (canvasWidth - drawW) / 2.0;
double y = (canvasHeight - drawH) / 2.0;
g.drawImage(image, x, y, drawW, drawH);
} else { } else {
// The PSP stretches the anamorphic 720x480 frame to fill 480x272. drawW = canvasWidth;
g.drawImage(image, 0, 0, canvasWidth, canvasHeight); drawH = canvasWidth / aspect;
} }
double x = (canvasWidth - drawW) / 2.0;
double y = (canvasHeight - drawH) / 2.0;
g.drawImage(image, x, y, drawW, drawH);
}); });
} }
@@ -96,6 +96,16 @@ public final class RcoRenderer implements Display {
double h = canvas.getHeight(); double h = canvas.getHeight();
g.clearRect(0, 0, w, h); g.clearRect(0, 0, w, h);
// RCO content is authored for the PSP 480x272 screen; scale it to
// fill the window while keeping that aspect ratio.
if (w > 0 && h > 0) {
double scale = Math.min(w / 480.0, h / 272.0);
double drawW = 480.0 * scale;
double drawH = 272.0 * scale;
g.translate((w - drawW) / 2.0, (h - drawH) / 2.0);
g.scale(scale, scale);
}
for (IDisplay display : snapshot) { for (IDisplay display : snapshot) {
draw(g, display); draw(g, display);
} }