diff --git a/core/src/main/java/dev/quoije/umd/rco/RcoFile.java b/core/src/main/java/dev/quoije/umd/rco/RcoFile.java index 8027643..a2e36f0 100644 --- a/core/src/main/java/dev/quoije/umd/rco/RcoFile.java +++ b/core/src/main/java/dev/quoije/umd/rco/RcoFile.java @@ -261,10 +261,14 @@ public final class RcoFile { int comp = read16(); int sizePacked = read32(); int imgOffset = read32(); + int sizeUnpacked = sizePacked; if (comp != COMPRESSION_NONE) { - skip(4); // sizeUnpacked + sizeUnpacked = read32(); } byte[] imgData = readImageData(imgOffset, sizePacked); + if (imgData != null && comp != COMPRESSION_NONE) { + imgData = decompressImage(imgData, comp, sizeUnpacked); + } images.put(entryOffset, new ImageObject(imgData)); } } @@ -359,6 +363,32 @@ public final class RcoFile { return data; } + private byte[] decompressImage(byte[] packed, int comp, int sizeUnpacked) { + try { + if (comp == COMPRESSION_ZLIB) { + java.util.zip.Inflater inflater = new java.util.zip.Inflater(); + inflater.setInput(packed); + byte[] out = new byte[sizeUnpacked]; + int len = inflater.inflate(out); + inflater.end(); + if (len != sizeUnpacked) { + out = java.util.Arrays.copyOf(out, len); + } + return out; + } else if (comp == COMPRESSION_RLZ) { + byte[] out = new byte[sizeUnpacked]; + int len = Lzr.decompress(out, out.length, packed); + if (len < 0) { + return null; + } + return java.util.Arrays.copyOf(out, len); + } + } catch (Exception e) { + return null; + } + return packed; + } + private String readLabel(int labelOffset) { int current = tell(); seek(pLabelData + labelOffset); diff --git a/ui/src/main/java/dev/quoije/umd/ui/RcoRenderer.java b/ui/src/main/java/dev/quoije/umd/ui/RcoRenderer.java index 2ef5a7e..4091df1 100644 --- a/ui/src/main/java/dev/quoije/umd/ui/RcoRenderer.java +++ b/ui/src/main/java/dev/quoije/umd/ui/RcoRenderer.java @@ -94,6 +94,9 @@ public final class RcoRenderer implements Display { GraphicsContext g = canvas.getGraphicsContext2D(); double w = canvas.getWidth(); double h = canvas.getHeight(); + + // Reset the transform so repeated repaints do not accumulate scale. + g.setTransform(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); g.clearRect(0, 0, w, h); // RCO content is authored for the PSP movie player framebuffer, which