From b18e8447dc917a281978f5c76e94524450f91950 Mon Sep 17 00:00:00 2001 From: Mathieu Moran Date: Tue, 15 Sep 2026 22:54:46 -0400 Subject: [PATCH] Add RCO object model and expose the menu object tree - Type system: BaseType (+Int/Float/Unknown) and BaseReferenceType (+Event/Image/Text/Ref/Object/Model) for typed record fields. - Object model: BaseObject/BasePositionObject and all 25 object classes (Page, Plane, Button, UButton, Text, Model, Icon, Group, Action, XMenu/XMList/XList/XItem, MList/MItem, LList/LItem, IList/IItem, Progress, Scroll, Spin, ItemSpin, Edit, Clock) with reflection-based field deserialization. - ObjectFactory + RcoContext materialize 89 objects and 81 images from the RCO; RcoFile resolves references and wires entry.obj/vsmxObject. - Resource builds the live pagetable/animtable/soundtable/texturetable into the VSMX tree; Controller tracks input focus. - Validated on Batman Begins: onAutoPlay still drives playback (stream 00003) with the object tree populated. --- .../main/java/dev/quoije/umd/cli/Main.java | 5 +- .../dev/quoije/umd/rco/ObjectFactory.java | 67 +++++++ .../main/java/dev/quoije/umd/rco/RcoFile.java | 42 ++++- .../quoije/umd/rco/object/ActionObject.java | 11 ++ .../dev/quoije/umd/rco/object/BaseObject.java | 4 +- .../umd/rco/object/BasePositionObject.java | 167 ++++++++++++++++++ .../quoije/umd/rco/object/ButtonObject.java | 68 +++++++ .../quoije/umd/rco/object/ClockObject.java | 29 +++ .../dev/quoije/umd/rco/object/EditObject.java | 28 +++ .../quoije/umd/rco/object/GroupObject.java | 6 + .../quoije/umd/rco/object/IItemObject.java | 12 ++ .../quoije/umd/rco/object/IListObject.java | 16 ++ .../dev/quoije/umd/rco/object/IconObject.java | 18 ++ .../quoije/umd/rco/object/ItemSpinObject.java | 30 ++++ .../quoije/umd/rco/object/LItemObject.java | 14 ++ .../quoije/umd/rco/object/LListObject.java | 25 +++ .../quoije/umd/rco/object/MItemObject.java | 14 ++ .../quoije/umd/rco/object/MListObject.java | 30 ++++ .../quoije/umd/rco/object/ModelObject.java | 11 ++ .../dev/quoije/umd/rco/object/PageObject.java | 31 ++++ .../quoije/umd/rco/object/PlaneObject.java | 18 ++ .../quoije/umd/rco/object/ProgressObject.java | 17 ++ .../quoije/umd/rco/object/ScrollObject.java | 20 +++ .../dev/quoije/umd/rco/object/SpinObject.java | 25 +++ .../dev/quoije/umd/rco/object/TextObject.java | 45 +++++ .../quoije/umd/rco/object/UButtonObject.java | 63 +++++++ .../quoije/umd/rco/object/XItemObject.java | 15 ++ .../quoije/umd/rco/object/XListObject.java | 19 ++ .../quoije/umd/rco/object/XMListObject.java | 15 ++ .../quoije/umd/rco/object/XMenuObject.java | 17 ++ .../umd/rco/vsmx/objects/Controller.java | 28 +++ .../quoije/umd/rco/vsmx/objects/Resource.java | 62 ++++++- 32 files changed, 961 insertions(+), 11 deletions(-) create mode 100644 core/src/main/java/dev/quoije/umd/rco/ObjectFactory.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/ActionObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/BasePositionObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/ButtonObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/ClockObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/EditObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/GroupObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/IItemObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/IListObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/IconObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/ItemSpinObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/LItemObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/LListObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/MItemObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/MListObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/ModelObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/PageObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/PlaneObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/ProgressObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/ScrollObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/SpinObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/TextObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/UButtonObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/XItemObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/XListObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/XMListObject.java create mode 100644 core/src/main/java/dev/quoije/umd/rco/object/XMenuObject.java diff --git a/cli/src/main/java/dev/quoije/umd/cli/Main.java b/cli/src/main/java/dev/quoije/umd/cli/Main.java index 785992b..e90f5bb 100644 --- a/cli/src/main/java/dev/quoije/umd/cli/Main.java +++ b/cli/src/main/java/dev/quoije/umd/cli/Main.java @@ -406,7 +406,8 @@ public final class Main { } RcoFile rco = new RcoFile(data); - System.out.printf("%s: valid=%b compression=%d%n", rcoPath, rco.isValid(), rco.compression()); + System.out.printf("%s: valid=%b compression=%d objects=%d images=%d%n", + rcoPath, rco.isValid(), rco.compression(), rco.objects().size(), rco.images().size()); System.out.printf("events (%d):%n", rco.events().size()); for (Map.Entry event : rco.events().entrySet()) { @@ -466,7 +467,7 @@ public final class Main { VsmxNativeObject globals = GlobalVariables.create(interpreter, 854, 480); VsmxNativeObject controller = Controller.create(interpreter, menuHost, resourceName); VsmxNativeObject movieplayer = MoviePlayer.create(interpreter, menuHost, controller); - VsmxNativeObject resource = Resource.create(interpreter); + VsmxNativeObject resource = Resource.create(interpreter, null, controller, rco); VsmxNativeObject math = dev.quoije.umd.rco.vsmx.objects.Math.create(interpreter); globals.setPropertyValue(Controller.objectName, controller); globals.setPropertyValue(MoviePlayer.objectName, movieplayer); diff --git a/core/src/main/java/dev/quoije/umd/rco/ObjectFactory.java b/core/src/main/java/dev/quoije/umd/rco/ObjectFactory.java new file mode 100644 index 0000000..2ddd0fe --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/ObjectFactory.java @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco; + +import dev.quoije.umd.rco.object.ActionObject; +import dev.quoije.umd.rco.object.BaseObject; +import dev.quoije.umd.rco.object.ButtonObject; +import dev.quoije.umd.rco.object.ClockObject; +import dev.quoije.umd.rco.object.EditObject; +import dev.quoije.umd.rco.object.GroupObject; +import dev.quoije.umd.rco.object.IItemObject; +import dev.quoije.umd.rco.object.IListObject; +import dev.quoije.umd.rco.object.IconObject; +import dev.quoije.umd.rco.object.ItemSpinObject; +import dev.quoije.umd.rco.object.LItemObject; +import dev.quoije.umd.rco.object.LListObject; +import dev.quoije.umd.rco.object.MItemObject; +import dev.quoije.umd.rco.object.MListObject; +import dev.quoije.umd.rco.object.ModelObject; +import dev.quoije.umd.rco.object.PageObject; +import dev.quoije.umd.rco.object.PlaneObject; +import dev.quoije.umd.rco.object.ProgressObject; +import dev.quoije.umd.rco.object.ScrollObject; +import dev.quoije.umd.rco.object.SpinObject; +import dev.quoije.umd.rco.object.TextObject; +import dev.quoije.umd.rco.object.UButtonObject; +import dev.quoije.umd.rco.object.XItemObject; +import dev.quoije.umd.rco.object.XListObject; +import dev.quoije.umd.rco.object.XMenuObject; +import dev.quoije.umd.rco.object.XMListObject; + +/** Creates RCO object records by type id. */ +public final class ObjectFactory { + + private ObjectFactory() { + } + + public static BaseObject newObject(int type) { + return switch (type) { + case 1 -> new PageObject(); + case 2 -> new PlaneObject(); + case 3 -> new ButtonObject(); + case 4 -> new XMenuObject(); + case 5 -> new XMListObject(); + case 6 -> new XListObject(); + case 7 -> new ProgressObject(); + case 8 -> new ScrollObject(); + case 9 -> new MListObject(); + case 10 -> new MItemObject(); + case 12 -> new XItemObject(); + case 13 -> new TextObject(); + case 14 -> new ModelObject(); + case 15 -> new SpinObject(); + case 16 -> new ActionObject(); + case 17 -> new ItemSpinObject(); + case 18 -> new GroupObject(); + case 19 -> new LListObject(); + case 20 -> new LItemObject(); + case 21 -> new EditObject(); + case 22 -> new ClockObject(); + case 23 -> new IListObject(); + case 24 -> new IItemObject(); + case 25 -> new IconObject(); + case 26 -> new UButtonObject(); + default -> null; + }; + } +} 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 58ed06f..7739765 100644 --- a/core/src/main/java/dev/quoije/umd/rco/RcoFile.java +++ b/core/src/main/java/dev/quoije/umd/rco/RcoFile.java @@ -1,7 +1,10 @@ // SPDX-License-Identifier: GPL-3.0-or-later package dev.quoije.umd.rco; +import dev.quoije.umd.rco.object.BaseObject; +import dev.quoije.umd.rco.object.ImageObject; import dev.quoije.umd.rco.vsmx.Vsmx; +import dev.quoije.umd.rco.vsmx.interpreter.VsmxBaseObject; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -55,6 +58,8 @@ public final class RcoFile { public final List subEntries = new ArrayList<>(); public byte[] data; public String[] texts; + public BaseObject obj; + public VsmxBaseObject vsmxObject; public String tableName() { return RcoFile.tableName(id); @@ -66,6 +71,8 @@ public final class RcoFile { private final Entry mainTable; private final byte[] vsmxData; private final Map events = new LinkedHashMap<>(); + private final Map images = new LinkedHashMap<>(); + private final Map objects = new LinkedHashMap<>(); private final byte[] buffer; private int offset; @@ -95,6 +102,11 @@ public final class RcoFile { .map(e -> e.data) .findFirst() .orElse(null); + + RcoContext initContext = new RcoContext(null, 0, events, images, objects); + for (BaseObject object : objects.values()) { + object.init(initContext); + } ok = true; } catch (RuntimeException e) { ok = false; @@ -126,6 +138,14 @@ public final class RcoFile { return events; } + public Map images() { + return images; + } + + public Map objects() { + return objects; + } + public static String tableName(int id) { return switch (id) { case TABLE_MAIN -> "MAIN"; @@ -221,11 +241,23 @@ public final class RcoFile { skip(alignUp(lengthVSMX, 4) - lengthVSMX); } } - case TABLE_IMG, TABLE_MODEL -> { + case TABLE_IMG -> { if (entry.type == 1) { skip(2); // format int comp = read16(); - int sizePacked = read32(); + skip(4); // sizePacked + skip(4); // offset + if (comp != COMPRESSION_NONE) { + skip(4); // sizeUnpacked + } + images.put(entryOffset, new ImageObject(null)); + } + } + case TABLE_MODEL -> { + if (entry.type == 1) { + skip(2); // format + int comp = read16(); + skip(4); // sizePacked skip(4); // offset if (comp != COMPRESSION_NONE) { skip(4); // sizeUnpacked @@ -253,6 +285,12 @@ public final class RcoFile { int dataLength = entryDataLength(entry, RcoEntrySizes.objectSize(entry.type)); if (dataLength > 0) { entry.data = readBytes(dataLength); + BaseObject obj = ObjectFactory.newObject(entry.type); + if (obj != null) { + obj.read(new RcoContext(entry.data, 0, events, images, objects)); + objects.put(entryOffset, obj); + entry.obj = obj; + } } } case TABLE_ANIM -> { diff --git a/core/src/main/java/dev/quoije/umd/rco/object/ActionObject.java b/core/src/main/java/dev/quoije/umd/rco/object/ActionObject.java new file mode 100644 index 0000000..dd6a0fa --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/ActionObject.java @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.RefType; + +/** An action object. */ +public class ActionObject extends BaseObject { + + @ObjectField(order = 1) public RefType unknownRef0; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/BaseObject.java b/core/src/main/java/dev/quoije/umd/rco/object/BaseObject.java index 522353d..872d0e8 100644 --- a/core/src/main/java/dev/quoije/umd/rco/object/BaseObject.java +++ b/core/src/main/java/dev/quoije/umd/rco/object/BaseObject.java @@ -2,6 +2,7 @@ package dev.quoije.umd.rco.object; import dev.quoije.umd.rco.Display; +import dev.quoije.umd.rco.IDisplay; import dev.quoije.umd.rco.ObjectField; import dev.quoije.umd.rco.RcoContext; import dev.quoije.umd.rco.RcoFile; @@ -133,7 +134,8 @@ public abstract class BaseObject extends BaseNativeObject implements IDisplay { } } - protected void onDisplayUpdated() { + @Override + public void onDisplayUpdated() { if (display != null) { display.repaint(); } diff --git a/core/src/main/java/dev/quoije/umd/rco/object/BasePositionObject.java b/core/src/main/java/dev/quoije/umd/rco/object/BasePositionObject.java new file mode 100644 index 0000000..90328b2 --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/BasePositionObject.java @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.EventType; +import dev.quoije.umd.rco.type.FloatType; +import dev.quoije.umd.rco.type.IntType; +import dev.quoije.umd.rco.vsmx.interpreter.VsmxArray; +import dev.quoije.umd.rco.vsmx.interpreter.VsmxBaseObject; +import dev.quoije.umd.rco.vsmx.interpreter.VsmxInterpreter; +import dev.quoije.umd.rco.vsmx.interpreter.VsmxNumber; + +/** + * Base of positionable RCO objects: adds position, scale, colour, and size + * fields plus script-facing accessors. + */ +public class BasePositionObject extends BaseObject { + + @ObjectField(order = 101) public FloatType posX; + @ObjectField(order = 102) public FloatType posY; + @ObjectField(order = 103) public FloatType posZ; + @ObjectField(order = 104) public FloatType redScale; + @ObjectField(order = 105) public FloatType greenScale; + @ObjectField(order = 106) public FloatType blueScale; + @ObjectField(order = 107) public FloatType alphaScale; + @ObjectField(order = 108) public FloatType width; + @ObjectField(order = 109) public FloatType height; + @ObjectField(order = 110) public FloatType depth; + @ObjectField(order = 111) public FloatType scaleWidth; + @ObjectField(order = 112) public FloatType scaleHeight; + @ObjectField(order = 113) public FloatType scaleDepth; + @ObjectField(order = 114) public IntType iconOffset; + @ObjectField(order = 115) public EventType onInit; + + @Override + public int getX() { + int parentX = 0; + if (getParent() instanceof BasePositionObject positionParent) { + parentX = positionParent.getX(); + } + return parentX + posX.getIntValue(); + } + + @Override + public int getY() { + int parentY = 0; + if (getParent() instanceof BasePositionObject positionParent) { + parentY = positionParent.getY(); + } + return parentY + posY.getIntValue(); + } + + @Override + public int getWidth() { + float w = width.getFloatValue(); + if (w == 0f) { + Object image = getImage(); + if (image == null) { + w = 0f; + } + } + return Math.round(w * scaleWidth.getFloatValue()); + } + + @Override + public int getHeight() { + float h = height.getFloatValue(); + if (h == 0f) { + Object image = getImage(); + if (image == null) { + h = 0f; + } + } + return Math.round(h * scaleHeight.getFloatValue()); + } + + @Override + public float getAlpha() { + return alphaScale.getFloatValue(); + } + + @Override + public Object getImage() { + return null; + } + + @Override + public void setFocus() { + if (display != null) { + display.setFocus(this); + } + if (controller != null) { + controller.setFocus(this); + } + } + + public void setPos(VsmxBaseObject object, VsmxBaseObject x, VsmxBaseObject y) { + posX.setFloatValue(x.getFloatValue()); + posY.setFloatValue(y.getFloatValue()); + onDisplayUpdated(); + } + + public void setPos(VsmxBaseObject object, VsmxBaseObject x, VsmxBaseObject y, VsmxBaseObject z) { + posX.setFloatValue(x.getFloatValue()); + posY.setFloatValue(y.getFloatValue()); + posZ.setFloatValue(z.getFloatValue()); + onDisplayUpdated(); + } + + public VsmxBaseObject getPos(VsmxBaseObject object) { + VsmxInterpreter interpreter = object.getInterpreter(); + VsmxArray pos = new VsmxArray(interpreter, 3); + pos.setPropertyValue(0, new VsmxNumber(interpreter, posX.getFloatValue())); + pos.setPropertyValue(1, new VsmxNumber(interpreter, posY.getFloatValue())); + pos.setPropertyValue(2, new VsmxNumber(interpreter, posZ.getFloatValue())); + return pos; + } + + public void setSize(VsmxBaseObject object, VsmxBaseObject w, VsmxBaseObject h, VsmxBaseObject d) { + width.setFloatValue(w.getFloatValue()); + height.setFloatValue(h.getFloatValue()); + depth.setFloatValue(d.getFloatValue()); + onDisplayUpdated(); + } + + public void setScale(VsmxBaseObject object, VsmxBaseObject w, VsmxBaseObject h, VsmxBaseObject d) { + onDisplayUpdated(); + } + + public VsmxBaseObject getColor(VsmxBaseObject object) { + VsmxInterpreter interpreter = object.getInterpreter(); + VsmxArray color = new VsmxArray(interpreter, 4); + color.setPropertyValue(0, new VsmxNumber(interpreter, redScale.getFloatValue())); + color.setPropertyValue(1, new VsmxNumber(interpreter, greenScale.getFloatValue())); + color.setPropertyValue(2, new VsmxNumber(interpreter, blueScale.getFloatValue())); + color.setPropertyValue(3, new VsmxNumber(interpreter, alphaScale.getFloatValue())); + return color; + } + + public void setColor(VsmxBaseObject object, VsmxBaseObject red, VsmxBaseObject green, VsmxBaseObject blue, VsmxBaseObject alpha) { + redScale.setFloatValue(red.getFloatValue()); + greenScale.setFloatValue(green.getFloatValue()); + blueScale.setFloatValue(blue.getFloatValue()); + alphaScale.setFloatValue(alpha.getFloatValue()); + onDisplayUpdated(); + } + + public void setRotate(VsmxBaseObject object, VsmxBaseObject x, VsmxBaseObject y, VsmxBaseObject rotationRads) { + onDisplayUpdated(); + } + + public void animColor(VsmxBaseObject object, VsmxBaseObject red, VsmxBaseObject green, VsmxBaseObject blue, VsmxBaseObject alpha, VsmxBaseObject duration) { + setColor(object, red, green, blue, alpha); + } + + public void animScale(VsmxBaseObject object, VsmxBaseObject w, VsmxBaseObject h, VsmxBaseObject d, VsmxBaseObject duration) { + setScale(object, w, h, d); + } + + public void animPos(VsmxBaseObject object, VsmxBaseObject x, VsmxBaseObject y, VsmxBaseObject z, VsmxBaseObject duration) { + setPos(object, x, y, z); + } + + public void animRotate(VsmxBaseObject object, VsmxBaseObject x, VsmxBaseObject y, VsmxBaseObject rotationRads, VsmxBaseObject duration) { + setRotate(object, x, y, rotationRads); + } +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/ButtonObject.java b/core/src/main/java/dev/quoije/umd/rco/object/ButtonObject.java new file mode 100644 index 0000000..f8763d8 --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/ButtonObject.java @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +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.type.TextType; + +/** A button object. */ +public class ButtonObject extends BasePositionObject { + + @ObjectField(order = 201) public ImageType image; + @ObjectField(order = 202) public ImageType shadow; + @ObjectField(order = 203) public ImageType focus; + @ObjectField(order = 204) public TextType text; + @ObjectField(order = 205) public EventType onPush; + @ObjectField(order = 206) public EventType onFocusIn; + @ObjectField(order = 207) public EventType onFocusOut; + @ObjectField(order = 208) public EventType onFocusLeft; + @ObjectField(order = 209) public EventType onFocusRight; + @ObjectField(order = 210) public EventType onFocusUp; + @ObjectField(order = 211) public EventType onFocusDown; + @ObjectField(order = 212) public EventType onContextMenu; + @ObjectField(order = 213) public IntType unknownInt40; + + @Override + public Object getImage() { + return image.getImage() == null ? null : image.getImage().getImage(); + } + + @Override + public void setFocus() { + trigger(onFocusIn); + super.setFocus(); + } + + @Override + public void focusOut() { + trigger(onFocusOut); + super.focusOut(); + } + + @Override + public void onPush() { + trigger(onPush); + } + + @Override + public void onUp() { + trigger(onFocusUp); + } + + @Override + public void onDown() { + trigger(onFocusDown); + } + + @Override + public void onLeft() { + trigger(onFocusLeft); + } + + @Override + public void onRight() { + trigger(onFocusRight); + } +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/ClockObject.java b/core/src/main/java/dev/quoije/umd/rco/object/ClockObject.java new file mode 100644 index 0000000..4f83cb7 --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/ClockObject.java @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.EventType; +import dev.quoije.umd.rco.type.FloatType; +import dev.quoije.umd.rco.type.IntType; +import dev.quoije.umd.rco.type.RefType; +import dev.quoije.umd.rco.type.TextType; + +/** A clock object. */ +public class ClockObject extends BasePositionObject { + + @ObjectField(order = 201) public IntType unknownInt16; + @ObjectField(order = 202) public FloatType unknownFloat17; + @ObjectField(order = 203) public TextType unknownText18; + @ObjectField(order = 204) public TextType unknownText20; + @ObjectField(order = 205) public RefType unknownRef22; + @ObjectField(order = 206) public RefType unknownRef24; + @ObjectField(order = 207) public EventType onDecide; + @ObjectField(order = 208) public EventType onCancel; + @ObjectField(order = 209) public EventType onFocusIn; + @ObjectField(order = 210) public EventType onFocusOut; + @ObjectField(order = 211) public EventType onFocusLeft; + @ObjectField(order = 212) public EventType onFocusRight; + @ObjectField(order = 213) public EventType onFocusUp; + @ObjectField(order = 214) public EventType onFocusDown; + @ObjectField(order = 215) public EventType onDigitalSwitch; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/EditObject.java b/core/src/main/java/dev/quoije/umd/rco/object/EditObject.java new file mode 100644 index 0000000..9f8e6ec --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/EditObject.java @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.EventType; +import dev.quoije.umd.rco.type.ObjectType; +import dev.quoije.umd.rco.type.RefType; +import dev.quoije.umd.rco.type.UnknownType; + +/** An edit field object. */ +public class EditObject extends BasePositionObject { + + @ObjectField(order = 201) public UnknownType unknown16; + @ObjectField(order = 202) public UnknownType unknown17; + @ObjectField(order = 203) public UnknownType unknown18; + @ObjectField(order = 204) public UnknownType unknown19; + @ObjectField(order = 205) public RefType unknownRef20; + @ObjectField(order = 206) public RefType unknownRef22; + @ObjectField(order = 207) public EventType unknownEvent24; + @ObjectField(order = 208) public RefType unknownRef26; + @ObjectField(order = 209) public RefType unknownRef28; + @ObjectField(order = 210) public RefType unknownRef30; + @ObjectField(order = 211) public EventType unknownEvent32; + @ObjectField(order = 212) public EventType unknownEvent34; + @ObjectField(order = 213) public ObjectType unknownObject36; + @ObjectField(order = 214) public ObjectType unknownObject38; + @ObjectField(order = 215) public RefType unknownRef40; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/GroupObject.java b/core/src/main/java/dev/quoije/umd/rco/object/GroupObject.java new file mode 100644 index 0000000..065ddf7 --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/GroupObject.java @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +/** A group object (position container with no extra fields). */ +public class GroupObject extends BasePositionObject { +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/IItemObject.java b/core/src/main/java/dev/quoije/umd/rco/object/IItemObject.java new file mode 100644 index 0000000..86dab8a --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/IItemObject.java @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.TextType; + +/** An input list item. */ +public class IItemObject extends BaseObject { + + @ObjectField(order = 1) public TextType textDefault; + @ObjectField(order = 2) public TextType textError; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/IListObject.java b/core/src/main/java/dev/quoije/umd/rco/object/IListObject.java new file mode 100644 index 0000000..c106703 --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/IListObject.java @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.EventType; +import dev.quoije.umd.rco.type.FloatType; + +/** An input list object. */ +public class IListObject extends BasePositionObject { + + @ObjectField(order = 201) public FloatType unknownFloat16; + @ObjectField(order = 202) public EventType onFocusIn; + @ObjectField(order = 203) public EventType onFocusOut; + @ObjectField(order = 204) public EventType onFocusLeft; + @ObjectField(order = 205) public EventType onFocusRight; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/IconObject.java b/core/src/main/java/dev/quoije/umd/rco/object/IconObject.java new file mode 100644 index 0000000..c493d15 --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/IconObject.java @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.ImageType; + +/** An icon object. */ +public class IconObject extends BasePositionObject { + + @ObjectField(order = 201) public ImageType unknownImage16; + @ObjectField(order = 202) public ImageType unknownImage18; + @ObjectField(order = 203) public ImageType unknownImage20; + + @Override + public Object getImage() { + return unknownImage16.getImage() == null ? null : unknownImage16.getImage().getImage(); + } +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/ItemSpinObject.java b/core/src/main/java/dev/quoije/umd/rco/object/ItemSpinObject.java new file mode 100644 index 0000000..4b2f2e4 --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/ItemSpinObject.java @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.EventType; +import dev.quoije.umd.rco.type.FloatType; +import dev.quoije.umd.rco.type.IntType; +import dev.quoije.umd.rco.type.ObjectType; +import dev.quoije.umd.rco.type.RefType; + +/** An item spin object. */ +public class ItemSpinObject extends BasePositionObject { + + @ObjectField(order = 201) public IntType unknownInt16; + @ObjectField(order = 202) public IntType unknownInt17; + @ObjectField(order = 203) public IntType unknownInt18; + @ObjectField(order = 204) public IntType unknownInt19; + @ObjectField(order = 205) public IntType unknownInt20; + @ObjectField(order = 206) public FloatType unknownFloat21; + @ObjectField(order = 207) public RefType unknownRef22; + @ObjectField(order = 208) public RefType unknownRef24; + @ObjectField(order = 209) public EventType unknownEvent26; + @ObjectField(order = 210) public EventType unknownEvent28; + @ObjectField(order = 211) public RefType unknownRef30; + @ObjectField(order = 212) public RefType unknownRef32; + @ObjectField(order = 213) public RefType unknownRef34; + @ObjectField(order = 214) public RefType unknownRef36; + @ObjectField(order = 215) public ObjectType objPrev; + @ObjectField(order = 216) public ObjectType objNext; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/LItemObject.java b/core/src/main/java/dev/quoije/umd/rco/object/LItemObject.java new file mode 100644 index 0000000..b57c4aa --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/LItemObject.java @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.RefType; +import dev.quoije.umd.rco.type.TextType; + +/** A list item (variant). */ +public class LItemObject extends BaseObject { + + @ObjectField(order = 1) public TextType text; + @ObjectField(order = 2) public RefType unknownRef2; + @ObjectField(order = 3) public RefType unknownRef4; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/LListObject.java b/core/src/main/java/dev/quoije/umd/rco/object/LListObject.java new file mode 100644 index 0000000..8596c8c --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/LListObject.java @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.EventType; +import dev.quoije.umd.rco.type.FloatType; +import dev.quoije.umd.rco.type.IntType; +import dev.quoije.umd.rco.type.RefType; +import dev.quoije.umd.rco.type.UnknownType; + +/** A list object (variant). */ +public class LListObject extends BasePositionObject { + + @ObjectField(order = 201) public IntType unknownInt16; + @ObjectField(order = 202) public UnknownType unknown17; + @ObjectField(order = 203) public FloatType unknownFloat18; + @ObjectField(order = 204) public RefType unknownRef19; + @ObjectField(order = 205) public RefType unknownRef21; + @ObjectField(order = 206) public RefType unknownRef23; + @ObjectField(order = 207) public RefType unknownRef25; + @ObjectField(order = 208) public RefType unknownRef27; + @ObjectField(order = 209) public RefType unknownRef29; + @ObjectField(order = 210) public EventType unknownEvent31; + @ObjectField(order = 211) public RefType unknownRef33; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/MItemObject.java b/core/src/main/java/dev/quoije/umd/rco/object/MItemObject.java new file mode 100644 index 0000000..a4fe20d --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/MItemObject.java @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.RefType; +import dev.quoije.umd.rco.type.TextType; + +/** A list item. */ +public class MItemObject extends BaseObject { + + @ObjectField(order = 1) public TextType text; + @ObjectField(order = 2) public TextType altText; + @ObjectField(order = 3) public RefType unknownRef4; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/MListObject.java b/core/src/main/java/dev/quoije/umd/rco/object/MListObject.java new file mode 100644 index 0000000..ccff4c0 --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/MListObject.java @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.EventType; +import dev.quoije.umd.rco.type.FloatType; +import dev.quoije.umd.rco.type.IntType; +import dev.quoije.umd.rco.type.RefType; +import dev.quoije.umd.rco.type.UnknownType; + +/** A list object. */ +public class MListObject extends BasePositionObject { + + @ObjectField(order = 201) public IntType numVisibleElements; + @ObjectField(order = 202) public UnknownType unknown17; + @ObjectField(order = 203) public IntType initTopPadding; + @ObjectField(order = 204) public FloatType unknownFloat19; + @ObjectField(order = 205) public FloatType itemSpacing; + @ObjectField(order = 206) public RefType unknownRef21; + @ObjectField(order = 207) public EventType onPush; + @ObjectField(order = 208) public EventType onCursorMove; + @ObjectField(order = 209) public EventType onFocusIn; + @ObjectField(order = 210) public EventType onFocusOut; + @ObjectField(order = 211) public EventType onFocusLeft; + @ObjectField(order = 212) public EventType onFocusRight; + @ObjectField(order = 213) public EventType onFocusUp; + @ObjectField(order = 214) public EventType onFocusDown; + @ObjectField(order = 215) public EventType onScrollIn; + @ObjectField(order = 216) public EventType onScrollOut; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/ModelObject.java b/core/src/main/java/dev/quoije/umd/rco/object/ModelObject.java new file mode 100644 index 0000000..89fdf83 --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/ModelObject.java @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.ModelType; + +/** A 3D model object. */ +public class ModelObject extends BasePositionObject { + + @ObjectField(order = 201) public ModelType model; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/PageObject.java b/core/src/main/java/dev/quoije/umd/rco/object/PageObject.java new file mode 100644 index 0000000..4795197 --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/PageObject.java @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.EventType; +import dev.quoije.umd.rco.type.IntType; +import dev.quoije.umd.rco.vsmx.interpreter.VsmxBaseObject; + +/** A menu page. */ +public class PageObject extends BaseObject { + + @ObjectField(order = 1) public IntType unknownInt0; + @ObjectField(order = 2) public EventType onInit; + @ObjectField(order = 3) public EventType onCancel; + @ObjectField(order = 4) public EventType onContextMenu; + @ObjectField(order = 5) public EventType onActivate; + + public VsmxBaseObject open(VsmxBaseObject object) { + trigger(onInit); + return object; + } + + public VsmxBaseObject activate(VsmxBaseObject object) { + trigger(onActivate); + return object; + } + + public void close(VsmxBaseObject object) { + trigger(onCancel); + } +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/PlaneObject.java b/core/src/main/java/dev/quoije/umd/rco/object/PlaneObject.java new file mode 100644 index 0000000..78e8044 --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/PlaneObject.java @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +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; + +/** A plane (textured rectangle). */ +public class PlaneObject extends BasePositionObject { + + @ObjectField(order = 201) public ImageType image; + @ObjectField(order = 202) public IntType unknownInt18; + + @Override + public Object getImage() { + return image.getImage() == null ? null : image.getImage().getImage(); + } +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/ProgressObject.java b/core/src/main/java/dev/quoije/umd/rco/object/ProgressObject.java new file mode 100644 index 0000000..8a7460a --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/ProgressObject.java @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.FloatType; +import dev.quoije.umd.rco.type.RefType; +import dev.quoije.umd.rco.type.UnknownType; + +/** A progress bar object. */ +public class ProgressObject extends BasePositionObject { + + @ObjectField(order = 201) public FloatType unknownFloat16; + @ObjectField(order = 202) public UnknownType unknown17; + @ObjectField(order = 203) public RefType unknownRef18; + @ObjectField(order = 204) public RefType unknownRef20; + @ObjectField(order = 205) public RefType unknownRef22; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/ScrollObject.java b/core/src/main/java/dev/quoije/umd/rco/object/ScrollObject.java new file mode 100644 index 0000000..6e6a584 --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/ScrollObject.java @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.FloatType; +import dev.quoije.umd.rco.type.RefType; +import dev.quoije.umd.rco.type.UnknownType; + +/** A scroll bar object. */ +public class ScrollObject extends BasePositionObject { + + @ObjectField(order = 201) public FloatType unknownFloat16; + @ObjectField(order = 202) public FloatType unknownFloat17; + @ObjectField(order = 203) public UnknownType unknown18; + @ObjectField(order = 204) public RefType unknownRef19; + @ObjectField(order = 205) public RefType unknownRef21; + @ObjectField(order = 206) public RefType unknownRef23; + @ObjectField(order = 207) public RefType unknownRef25; + @ObjectField(order = 208) public RefType unknownRef27; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/SpinObject.java b/core/src/main/java/dev/quoije/umd/rco/object/SpinObject.java new file mode 100644 index 0000000..062c27c --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/SpinObject.java @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.EventType; +import dev.quoije.umd.rco.type.IntType; +import dev.quoije.umd.rco.type.RefType; +import dev.quoije.umd.rco.type.UnknownType; + +/** A spin (numeric stepper) object. */ +public class SpinObject extends BasePositionObject { + + @ObjectField(order = 201) public UnknownType unknown16; + @ObjectField(order = 202) public IntType unknownInt17; + @ObjectField(order = 203) public RefType unknownRef18; + @ObjectField(order = 204) public RefType unknownRef20; + @ObjectField(order = 205) public EventType unknownEvent22; + @ObjectField(order = 206) public EventType unknownEvent24; + @ObjectField(order = 207) public EventType unknownEvent26; + @ObjectField(order = 208) public RefType unknownRef28; + @ObjectField(order = 209) public RefType unknownRef30; + @ObjectField(order = 210) public RefType unknownRef32; + @ObjectField(order = 211) public RefType unknownRef34; + @ObjectField(order = 212) public RefType unknownRef36; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/TextObject.java b/core/src/main/java/dev/quoije/umd/rco/object/TextObject.java new file mode 100644 index 0000000..2288d0a --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/TextObject.java @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.FloatType; +import dev.quoije.umd.rco.type.IntType; +import dev.quoije.umd.rco.type.RefType; +import dev.quoije.umd.rco.type.TextType; +import dev.quoije.umd.rco.type.UnknownType; + +/** A text object. */ +public class TextObject extends BasePositionObject { + + @ObjectField(order = 201) public TextType text; + @ObjectField(order = 202) public RefType unknownRef18; + @ObjectField(order = 203) public IntType unknownInt20; + @ObjectField(order = 204) public IntType unknownInt21; + @ObjectField(order = 205) public FloatType size; + @ObjectField(order = 206) public FloatType topRed; + @ObjectField(order = 207) public FloatType topGreen; + @ObjectField(order = 208) public FloatType topBlue; + @ObjectField(order = 209) public FloatType bottomRed; + @ObjectField(order = 210) public FloatType bottomGreen; + @ObjectField(order = 211) public FloatType bottomBlue; + @ObjectField(order = 212) public FloatType spacingHorizontal; + @ObjectField(order = 213) public UnknownType unknown30; + @ObjectField(order = 214) public UnknownType unknown31; + @ObjectField(order = 215) public UnknownType unknown32; + @ObjectField(order = 216) public FloatType spacingVertical; + @ObjectField(order = 217) public FloatType shadowX; + @ObjectField(order = 218) public FloatType shadowY; + @ObjectField(order = 219) public FloatType shadowPerspective; + @ObjectField(order = 220) public FloatType shadowRed; + @ObjectField(order = 221) public FloatType shadowGreen; + @ObjectField(order = 222) public FloatType shadowBlue; + @ObjectField(order = 223) public FloatType shadowAlpha; + @ObjectField(order = 224) public UnknownType unknown41; + @ObjectField(order = 225) public UnknownType unknown42; + @ObjectField(order = 226) public UnknownType unknown43; + @ObjectField(order = 227) public FloatType unknownFloat44; + @ObjectField(order = 228) public FloatType unknownFloat45; + @ObjectField(order = 229) public FloatType unknownFloat46; + @ObjectField(order = 230) public FloatType unknownFloat47; + @ObjectField(order = 231) public UnknownType unknown48; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/UButtonObject.java b/core/src/main/java/dev/quoije/umd/rco/object/UButtonObject.java new file mode 100644 index 0000000..38016f5 --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/UButtonObject.java @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +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; + +/** A user button object (navigation with onLeft/onRight/onUp/onDown events). */ +public class UButtonObject extends BasePositionObject { + + @ObjectField(order = 201) public ImageType image; + @ObjectField(order = 202) public EventType onPush; + @ObjectField(order = 203) public EventType onFocusIn; + @ObjectField(order = 204) public EventType onFocusOut; + @ObjectField(order = 205) public EventType onLeft; + @ObjectField(order = 206) public EventType onRight; + @ObjectField(order = 207) public EventType onUp; + @ObjectField(order = 208) public EventType onDown; + @ObjectField(order = 209) public IntType unknownInt32; + + @Override + public Object getImage() { + return image.getImage() == null ? null : image.getImage().getImage(); + } + + @Override + public void setFocus() { + trigger(onFocusIn); + super.setFocus(); + } + + @Override + public void focusOut() { + trigger(onFocusOut); + super.focusOut(); + } + + @Override + public void onPush() { + trigger(onPush); + } + + @Override + public void onUp() { + trigger(onUp); + } + + @Override + public void onDown() { + trigger(onDown); + } + + @Override + public void onLeft() { + trigger(onLeft); + } + + @Override + public void onRight() { + trigger(onRight); + } +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/XItemObject.java b/core/src/main/java/dev/quoije/umd/rco/object/XItemObject.java new file mode 100644 index 0000000..cf4ad05 --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/XItemObject.java @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +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.RefType; +import dev.quoije.umd.rco.type.TextType; + +/** An XMB item. */ +public class XItemObject extends BaseObject { + + @ObjectField(order = 1) public ImageType image; + @ObjectField(order = 2) public TextType text; + @ObjectField(order = 3) public RefType unknownRef4; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/XListObject.java b/core/src/main/java/dev/quoije/umd/rco/object/XListObject.java new file mode 100644 index 0000000..6d0508b --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/XListObject.java @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.EventType; +import dev.quoije.umd.rco.type.IntType; + +/** An XMB item list. */ +public class XListObject extends BasePositionObject { + + @ObjectField(order = 201) public IntType unknownInt16; + @ObjectField(order = 202) public EventType onCursorMove; + @ObjectField(order = 203) public EventType onScrollIn; + @ObjectField(order = 204) public EventType onScrollOut; + @ObjectField(order = 205) public EventType onPush; + @ObjectField(order = 206) public EventType onContextMenu; + @ObjectField(order = 207) public EventType onFocusLeft; + @ObjectField(order = 208) public EventType onFocusRight; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/XMListObject.java b/core/src/main/java/dev/quoije/umd/rco/object/XMListObject.java new file mode 100644 index 0000000..27da69d --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/XMListObject.java @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +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.RefType; +import dev.quoije.umd.rco.type.UnknownType; + +/** An XMB list. */ +public class XMListObject extends BaseObject { + + @ObjectField(order = 1) public UnknownType unknown0; + @ObjectField(order = 2) public ImageType image; + @ObjectField(order = 3) public RefType unknownRef3; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/object/XMenuObject.java b/core/src/main/java/dev/quoije/umd/rco/object/XMenuObject.java new file mode 100644 index 0000000..9aba18e --- /dev/null +++ b/core/src/main/java/dev/quoije/umd/rco/object/XMenuObject.java @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +package dev.quoije.umd.rco.object; + +import dev.quoije.umd.rco.ObjectField; +import dev.quoije.umd.rco.type.EventType; +import dev.quoije.umd.rco.type.IntType; + +/** An XMB-style menu (cross media bar). */ +public class XMenuObject extends BasePositionObject { + + @ObjectField(order = 201) public IntType itemsCount; + @ObjectField(order = 202) public EventType onPush; + @ObjectField(order = 203) public EventType onContextMenu; + @ObjectField(order = 204) public EventType onCursorMove; + @ObjectField(order = 205) public EventType onScrollIn; + @ObjectField(order = 206) public EventType onScrollOut; +} diff --git a/core/src/main/java/dev/quoije/umd/rco/vsmx/objects/Controller.java b/core/src/main/java/dev/quoije/umd/rco/vsmx/objects/Controller.java index bbaf73b..759c311 100644 --- a/core/src/main/java/dev/quoije/umd/rco/vsmx/objects/Controller.java +++ b/core/src/main/java/dev/quoije/umd/rco/vsmx/objects/Controller.java @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later package dev.quoije.umd.rco.vsmx.objects; +import dev.quoije.umd.rco.object.BasePositionObject; import dev.quoije.umd.rco.vsmx.interpreter.VsmxArray; import dev.quoije.umd.rco.vsmx.interpreter.VsmxBaseObject; import dev.quoije.umd.rco.vsmx.interpreter.VsmxBoolean; @@ -18,6 +19,7 @@ public class Controller extends BaseNativeObject { private final MenuHost menuHost; private VsmxBaseObject userData; private String resource; + private BasePositionObject focus; public static VsmxNativeObject create(VsmxInterpreter interpreter, MenuHost menuHost, String resource) { Controller controller = new Controller(interpreter, menuHost); @@ -66,18 +68,44 @@ public class Controller extends BaseNativeObject { return VsmxBoolean.getValue(true); } + public void setFocus(BasePositionObject newFocus) { + if (focus != null) { + focus.focusOut(); + } + focus = newFocus; + } + + public BasePositionObject getFocus() { + return focus; + } + public void onUp() { + if (focus != null) { + focus.onUp(); + } } public void onDown() { + if (focus != null) { + focus.onDown(); + } } public void onLeft() { + if (focus != null) { + focus.onLeft(); + } } public void onRight() { + if (focus != null) { + focus.onRight(); + } } public void onPush() { + if (focus != null) { + focus.onPush(); + } } } diff --git a/core/src/main/java/dev/quoije/umd/rco/vsmx/objects/Resource.java b/core/src/main/java/dev/quoije/umd/rco/vsmx/objects/Resource.java index 95bea60..2bd7a61 100644 --- a/core/src/main/java/dev/quoije/umd/rco/vsmx/objects/Resource.java +++ b/core/src/main/java/dev/quoije/umd/rco/vsmx/objects/Resource.java @@ -1,13 +1,15 @@ // SPDX-License-Identifier: GPL-3.0-or-later package dev.quoije.umd.rco.vsmx.objects; +import dev.quoije.umd.rco.Display; +import dev.quoije.umd.rco.RcoFile; +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; /** * The resource native object, exposing the RCO object tables to the script. - * The object tree population is layered in with the renderer. */ public class Resource extends BaseNativeObject { @@ -16,16 +18,64 @@ public class Resource extends BaseNativeObject { public static final String childrenName = "children"; public static final String textureName = "texture"; - public static VsmxNativeObject create(VsmxInterpreter interpreter) { + public static VsmxNativeObject create(VsmxInterpreter interpreter, Display display, + VsmxNativeObject vsmxController, RcoFile rco) { Resource resource = new Resource(); VsmxNativeObject object = new VsmxNativeObject(interpreter, resource); resource.setObject(object); - object.setPropertyValue("pagetable", new VsmxObject(interpreter, null)); - object.setPropertyValue("animtable", new VsmxObject(interpreter, null)); - object.setPropertyValue("soundtable", new VsmxObject(interpreter, null)); - object.setPropertyValue("texturetable", new VsmxObject(interpreter, null)); + Controller controller = (Controller) vsmxController.getObject(); + RcoFile.Entry mainTable = rco.mainTable(); + if (mainTable != null) { + createTable(interpreter, display, controller, object, mainTable, RcoFile.TABLE_OBJ, "pagetable"); + createTable(interpreter, display, controller, object, mainTable, RcoFile.TABLE_ANIM, "animtable"); + createTable(interpreter, display, controller, object, mainTable, RcoFile.TABLE_SOUND, "soundtable"); + createTable(interpreter, display, controller, object, mainTable, RcoFile.TABLE_IMG, "texturetable"); + } return object; } + + private Resource() { + } + + private static RcoFile.Entry[] findEntries(RcoFile.Entry mainTable, int id) { + for (RcoFile.Entry entry : mainTable.subEntries) { + if (entry.id == id) { + return entry.subEntries.toArray(RcoFile.Entry[]::new); + } + } + return null; + } + + private static void createObjectFromEntry(VsmxInterpreter interpreter, Display display, Controller controller, + VsmxBaseObject parent, RcoFile.Entry entry) { + if (entry.obj == null) { + return; + } + entry.obj.setDisplay(display); + entry.obj.setController(controller); + VsmxBaseObject object = entry.obj.createVsmxObject(interpreter, parent, entry); + + if (!entry.subEntries.isEmpty()) { + VsmxObject children = new VsmxObject(interpreter, null); + object.setPropertyValue(childrenName, children); + for (RcoFile.Entry child : entry.subEntries) { + createObjectFromEntry(interpreter, display, controller, children, child); + } + } + } + + private static void createTable(VsmxInterpreter interpreter, Display display, Controller controller, + VsmxObject parent, RcoFile.Entry mainTable, int id, String name) { + VsmxObject table = new VsmxObject(interpreter, null); + parent.setPropertyValue(name, table); + + RcoFile.Entry[] entries = findEntries(mainTable, id); + if (entries != null) { + for (RcoFile.Entry entry : entries) { + createObjectFromEntry(interpreter, display, controller, table, entry); + } + } + } }