Wire RCO texture property to the renderer; fix group parent positions
- Expose the RCO image table as resource.texturetable[label] - Route native-object property assignment through set<Name>(BaseNativeObject) reflection so 'plane.texture = image' reaches PlaneObject.setTexture - Plane/UButton/Button/Icon draw their runtime texture in preference to the static image, and seed the texture property from the static image - Store the RCO entry's VSMX object so group children inherit parent position
This commit is contained in:
@@ -15,3 +15,4 @@ Thumbs.db
|
||||
|
||||
# Disc images
|
||||
*.iso
|
||||
reference/
|
||||
|
||||
@@ -58,6 +58,7 @@ public final class RcoFile {
|
||||
public final List<Entry> subEntries = new ArrayList<>();
|
||||
public byte[] data;
|
||||
public String[] texts;
|
||||
public ImageObject image;
|
||||
public BaseObject obj;
|
||||
public VsmxBaseObject vsmxObject;
|
||||
|
||||
@@ -269,7 +270,9 @@ public final class RcoFile {
|
||||
if (imgData != null && comp != COMPRESSION_NONE) {
|
||||
imgData = decompressImage(imgData, comp, sizeUnpacked);
|
||||
}
|
||||
images.put(entryOffset, new ImageObject(imgData));
|
||||
ImageObject imageObject = new ImageObject(imgData);
|
||||
images.put(entryOffset, imageObject);
|
||||
entry.image = imageObject;
|
||||
}
|
||||
}
|
||||
case TABLE_MODEL -> {
|
||||
|
||||
@@ -97,6 +97,18 @@ public abstract class BaseObject extends BaseNativeObject implements IDisplay {
|
||||
public VsmxBaseObject createVsmxObject(VsmxInterpreter interpreter, VsmxBaseObject parent, RcoFile.Entry entry) {
|
||||
VsmxNativeObject object = new VsmxNativeObject(interpreter, this);
|
||||
setObject(object);
|
||||
entry.vsmxObject = object;
|
||||
|
||||
// Seed the "texture" property with this object's static image so the
|
||||
// script can read or replace it. Assignment is routed through the
|
||||
// native setTexture setter, when one exists.
|
||||
Object staticImage = getImage();
|
||||
if (staticImage instanceof ImageObject imageObject) {
|
||||
VsmxNativeObject textureObject = new VsmxNativeObject(interpreter, imageObject);
|
||||
imageObject.setObject(textureObject);
|
||||
object.setPropertyValue("texture", textureObject);
|
||||
}
|
||||
|
||||
if (entry.label != null) {
|
||||
name = entry.label;
|
||||
object.setPropertyValue("name", new VsmxString(interpreter, entry.label));
|
||||
|
||||
@@ -6,6 +6,7 @@ import dev.quoije.umd.rco.type.EventType;
|
||||
import dev.quoije.umd.rco.type.ImageType;
|
||||
import dev.quoije.umd.rco.type.IntType;
|
||||
import dev.quoije.umd.rco.type.TextType;
|
||||
import dev.quoije.umd.rco.vsmx.objects.BaseNativeObject;
|
||||
|
||||
/** A button object. */
|
||||
public class ButtonObject extends BasePositionObject {
|
||||
@@ -24,11 +25,25 @@ public class ButtonObject extends BasePositionObject {
|
||||
@ObjectField(order = 212) public EventType onContextMenu;
|
||||
@ObjectField(order = 213) public IntType unknownInt40;
|
||||
|
||||
/** Runtime texture assigned by the script; overrides the static image. */
|
||||
private ImageObject texture;
|
||||
|
||||
@Override
|
||||
public Object getImage() {
|
||||
if (texture != null) {
|
||||
return texture;
|
||||
}
|
||||
return image.getImage();
|
||||
}
|
||||
|
||||
/** Called via the VSMX {@code texture} property setter. */
|
||||
public void setTexture(BaseNativeObject texture) {
|
||||
if (texture instanceof ImageObject imageObject) {
|
||||
this.texture = imageObject;
|
||||
}
|
||||
onDisplayUpdated();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getFocusImage() {
|
||||
return focus.getImage();
|
||||
|
||||
@@ -3,6 +3,7 @@ package dev.quoije.umd.rco.object;
|
||||
|
||||
import dev.quoije.umd.rco.ObjectField;
|
||||
import dev.quoije.umd.rco.type.ImageType;
|
||||
import dev.quoije.umd.rco.vsmx.objects.BaseNativeObject;
|
||||
|
||||
/** An icon object. */
|
||||
public class IconObject extends BasePositionObject {
|
||||
@@ -11,8 +12,22 @@ public class IconObject extends BasePositionObject {
|
||||
@ObjectField(order = 202) public ImageType unknownImage18;
|
||||
@ObjectField(order = 203) public ImageType unknownImage20;
|
||||
|
||||
/** Runtime texture assigned by the script; overrides the static image. */
|
||||
private ImageObject texture;
|
||||
|
||||
@Override
|
||||
public Object getImage() {
|
||||
if (texture != null) {
|
||||
return texture;
|
||||
}
|
||||
return unknownImage16.getImage();
|
||||
}
|
||||
|
||||
/** Called via the VSMX {@code texture} property setter. */
|
||||
public void setTexture(BaseNativeObject texture) {
|
||||
if (texture instanceof ImageObject imageObject) {
|
||||
this.texture = imageObject;
|
||||
}
|
||||
onDisplayUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
package dev.quoije.umd.rco.object;
|
||||
|
||||
import dev.quoije.umd.rco.vsmx.objects.BaseNativeObject;
|
||||
|
||||
/** An image entry from the RCO IMG table (raw bytes until decoded by the UI). */
|
||||
public final class ImageObject {
|
||||
public class ImageObject extends BaseNativeObject {
|
||||
|
||||
private final byte[] data;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ package dev.quoije.umd.rco.object;
|
||||
import dev.quoije.umd.rco.ObjectField;
|
||||
import dev.quoije.umd.rco.type.ImageType;
|
||||
import dev.quoije.umd.rco.type.IntType;
|
||||
import dev.quoije.umd.rco.vsmx.objects.BaseNativeObject;
|
||||
|
||||
/** A plane (textured rectangle). */
|
||||
public class PlaneObject extends BasePositionObject {
|
||||
@@ -11,8 +12,22 @@ public class PlaneObject extends BasePositionObject {
|
||||
@ObjectField(order = 201) public ImageType image;
|
||||
@ObjectField(order = 202) public IntType unknownInt18;
|
||||
|
||||
/** Runtime texture assigned by the script; overrides the static image. */
|
||||
private ImageObject texture;
|
||||
|
||||
@Override
|
||||
public Object getImage() {
|
||||
if (texture != null) {
|
||||
return texture;
|
||||
}
|
||||
return image.getImage();
|
||||
}
|
||||
|
||||
/** Called via the VSMX {@code texture} property setter. */
|
||||
public void setTexture(BaseNativeObject texture) {
|
||||
if (texture instanceof ImageObject imageObject) {
|
||||
this.texture = imageObject;
|
||||
}
|
||||
onDisplayUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import dev.quoije.umd.rco.ObjectField;
|
||||
import dev.quoije.umd.rco.type.EventType;
|
||||
import dev.quoije.umd.rco.type.ImageType;
|
||||
import dev.quoije.umd.rco.type.IntType;
|
||||
import dev.quoije.umd.rco.vsmx.objects.BaseNativeObject;
|
||||
|
||||
/** A user button object (navigation with onLeft/onRight/onUp/onDown events). */
|
||||
public class UButtonObject extends BasePositionObject {
|
||||
@@ -19,11 +20,25 @@ public class UButtonObject extends BasePositionObject {
|
||||
@ObjectField(order = 208) public EventType onDown;
|
||||
@ObjectField(order = 209) public IntType unknownInt32;
|
||||
|
||||
/** Runtime texture assigned by the script; overrides the static image. */
|
||||
private ImageObject texture;
|
||||
|
||||
@Override
|
||||
public Object getImage() {
|
||||
if (texture != null) {
|
||||
return texture;
|
||||
}
|
||||
return image.getImage();
|
||||
}
|
||||
|
||||
/** Called via the VSMX {@code texture} property setter. */
|
||||
public void setTexture(BaseNativeObject texture) {
|
||||
if (texture instanceof ImageObject imageObject) {
|
||||
this.texture = imageObject;
|
||||
}
|
||||
onDisplayUpdated();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFocus() {
|
||||
trigger(onFocusIn);
|
||||
|
||||
@@ -3,6 +3,8 @@ package dev.quoije.umd.rco.vsmx.interpreter;
|
||||
|
||||
import dev.quoije.umd.rco.vsmx.objects.BaseNativeObject;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/** A VSMX object wrapping a native Java object. */
|
||||
public class VsmxNativeObject extends VsmxObject {
|
||||
|
||||
@@ -17,6 +19,27 @@ public class VsmxNativeObject extends VsmxObject {
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigning a native object to a property is routed through a matching
|
||||
* {@code set<Name>(BaseNativeObject)} method when the wrapped object
|
||||
* declares one. This is how {@code plane.texture = image} reaches
|
||||
* {@code PlaneObject.setTexture}.
|
||||
*/
|
||||
@Override
|
||||
public void setPropertyValue(String name, VsmxBaseObject value) {
|
||||
if (object != null && name != null && !name.isEmpty() && value instanceof VsmxNativeObject nativeValue) {
|
||||
String setterName = "set" + Character.toUpperCase(name.charAt(0)) + name.substring(1);
|
||||
try {
|
||||
Method setter = object.getClass().getMethod(setterName, BaseNativeObject.class);
|
||||
setter.invoke(object, nativeValue.getObject());
|
||||
return;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
// No matching setter; fall back to storing the property.
|
||||
}
|
||||
}
|
||||
super.setPropertyValue(name, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return object == null ? super.toString() : object.toString() + super.toString();
|
||||
|
||||
@@ -7,6 +7,7 @@ import dev.quoije.umd.rco.vsmx.interpreter.VsmxBaseObject;
|
||||
import dev.quoije.umd.rco.vsmx.interpreter.VsmxInterpreter;
|
||||
import dev.quoije.umd.rco.vsmx.interpreter.VsmxNativeObject;
|
||||
import dev.quoije.umd.rco.vsmx.interpreter.VsmxObject;
|
||||
import dev.quoije.umd.rco.vsmx.interpreter.VsmxString;
|
||||
|
||||
/**
|
||||
* The resource native object, exposing the RCO object tables to the script.
|
||||
@@ -50,6 +51,15 @@ public class Resource extends BaseNativeObject {
|
||||
|
||||
private static void createObjectFromEntry(VsmxInterpreter interpreter, Display display, Controller controller,
|
||||
VsmxBaseObject parent, RcoFile.Entry entry) {
|
||||
if (entry.image != null) {
|
||||
VsmxNativeObject object = new VsmxNativeObject(interpreter, entry.image);
|
||||
entry.image.setObject(object);
|
||||
if (entry.label != null) {
|
||||
object.setPropertyValue("name", new VsmxString(interpreter, entry.label));
|
||||
parent.setPropertyValue(entry.label, object);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (entry.obj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user