Fix white screen, center video, and advance after playback

- Rejoin whitespace-split program args so ISO paths with spaces work
  (Gradle --args splits on spaces, which caused a silent load failure
  and a blank white window).
- Black scene background and black video canvas fill; scale video to
  fit and center it instead of drawing top-left at native size.
- Playback completion now invokes MoviePlayer.onPlayListEnd so the menu
  advances past the anti-piracy warning instead of freezing.
This commit is contained in:
2026-09-15 23:21:46 -04:00
parent a4f0d5992b
commit d4d3378b31
@@ -21,9 +21,12 @@ import javafx.application.Application;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.canvas.Canvas; import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.PixelFormat; import javafx.scene.image.PixelFormat;
import javafx.scene.image.WritableImage;
import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCode;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage; import javafx.stage.Stage;
import java.io.IOException; import java.io.IOException;
@@ -39,16 +42,21 @@ public final class PlayerApp extends Application {
private Canvas videoCanvas; private Canvas videoCanvas;
private RcoRenderer renderer; private RcoRenderer renderer;
private volatile Controller controller; private volatile Controller controller;
private volatile MoviePlayer moviePlayer;
@Override @Override
public void start(Stage stage) { public void start(Stage stage) {
String isoPath = getParameters().getRaw().isEmpty() ? null : getParameters().getRaw().get(0); // Gradle's --args splits on whitespace; rejoin so paths with spaces work.
String isoPath = getParameters().getRaw().isEmpty()
? null
: String.join(" ", getParameters().getRaw());
menuCanvas = new Canvas(WIDTH, HEIGHT); menuCanvas = new Canvas(WIDTH, HEIGHT);
videoCanvas = new Canvas(WIDTH, HEIGHT); videoCanvas = new Canvas(WIDTH, HEIGHT);
StackPane root = new StackPane(videoCanvas, menuCanvas); StackPane root = new StackPane(videoCanvas, menuCanvas);
Scene scene = new Scene(root, WIDTH, HEIGHT); Scene scene = new Scene(root, WIDTH, HEIGHT);
scene.setFill(Color.BLACK);
stage.setTitle("useless-umd-player"); stage.setTitle("useless-umd-player");
stage.setScene(scene); stage.setScene(scene);
stage.show(); stage.show();
@@ -105,7 +113,7 @@ public final class PlayerApp extends Application {
int audioFlag, int subtitleNumber, int subtitleFlag) { int audioFlag, int subtitleNumber, int subtitleFlag) {
Playlist.Stream stream = playlist.streamForPlayListNumber(playListNumber); Playlist.Stream stream = playlist.streamForPlayListNumber(playListNumber);
if (stream != null) { if (stream != null) {
startPlayback(isoPath, stream.name()); startPlayback(isoPath, stream.name(), playListNumber);
} }
} }
@@ -130,13 +138,14 @@ public final class PlayerApp extends Application {
interpreter.run(globals); interpreter.run(globals);
controller = (Controller) controllerObject.getObject(); controller = (Controller) controllerObject.getObject();
moviePlayer = (MoviePlayer) movieplayer.getObject();
controller.callCallback(interpreter, "onAutoPlay", null); controller.callCallback(interpreter, "onAutoPlay", null);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
private void startPlayback(String isoPath, String streamName) { private void startPlayback(String isoPath, String streamName, int playListNumber) {
Thread player = new Thread(() -> { Thread player = new Thread(() -> {
try (UmdIsoReader iso = new UmdIsoReader(Path.of(isoPath)); try (UmdIsoReader iso = new UmdIsoReader(Path.of(isoPath));
PlaybackEngine engine = PlaybackEngine.open(iso, streamName, 0)) { PlaybackEngine engine = PlaybackEngine.open(iso, streamName, 0)) {
@@ -164,6 +173,11 @@ public final class PlayerApp extends Application {
Thread.sleep(millis, nanos); Thread.sleep(millis, nanos);
} }
} }
MoviePlayer mp = moviePlayer;
if (mp != null) {
mp.onPlayListEnd(playListNumber);
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -173,10 +187,23 @@ public final class PlayerApp extends Application {
} }
private void blitVideo(int[] argb, int width, int height) { private void blitVideo(int[] argb, int width, int height) {
WritableImage image = new WritableImage(width, height);
image.getPixelWriter().setPixels(0, 0, width, height, PixelFormat.getIntArgbInstance(), argb, 0, width);
Platform.runLater(() -> { Platform.runLater(() -> {
videoCanvas.getGraphicsContext2D() GraphicsContext g = videoCanvas.getGraphicsContext2D();
.getPixelWriter() double canvasWidth = videoCanvas.getWidth();
.setPixels(0, 0, width, height, PixelFormat.getIntArgbInstance(), argb, 0, width); double canvasHeight = videoCanvas.getHeight();
g.setFill(Color.BLACK);
g.fillRect(0, 0, canvasWidth, canvasHeight);
double scale = java.lang.Math.min(canvasWidth / image.getWidth(), canvasHeight / image.getHeight());
double drawWidth = image.getWidth() * scale;
double drawHeight = image.getHeight() * scale;
double x = (canvasWidth - drawWidth) / 2;
double y = (canvasHeight - drawHeight) / 2;
g.drawImage(image, x, y, drawWidth, drawHeight);
}); });
} }