From cc386e05aed0b04e32c043c06506f0c480b008f8 Mon Sep 17 00:00:00 2001 From: jberg Date: Fri, 2 Aug 2019 15:29:16 -0700 Subject: [PATCH] add more maki objects and functions for corner amp to work (#826) * add more maki objects and functions for corner amp to work * fix functions to lower case / add unimplemented warning --- experiments/modern/src/App.js | 70 ++++++++++--------- experiments/modern/src/debugger/Variable.js | 12 +++- experiments/modern/src/initialize.js | 14 ++-- .../src/maki-interpreter/virtualMachine.js | 9 ++- experiments/modern/src/runtime/GuiObject.js | 41 ++++++++++- experiments/modern/src/runtime/Layer.js | 15 ++++ experiments/modern/src/runtime/Layout.js | 9 +++ experiments/modern/src/runtime/List.js | 15 ++++ experiments/modern/src/runtime/PopupMenu.js | 28 ++++++++ experiments/modern/src/runtime/Slider.js | 15 ++++ experiments/modern/src/runtime/Status.js | 15 ++++ experiments/modern/src/runtime/System.js | 26 ++++++- experiments/modern/src/runtime/Text.js | 15 ++++ .../modern/src/runtime/ToggleButton.js | 15 ++++ experiments/modern/src/runtime/index.js | 13 +++- experiments/modern/src/utils.js | 9 ++- 16 files changed, 273 insertions(+), 48 deletions(-) create mode 100644 experiments/modern/src/runtime/Layer.js create mode 100644 experiments/modern/src/runtime/List.js create mode 100644 experiments/modern/src/runtime/PopupMenu.js create mode 100644 experiments/modern/src/runtime/Slider.js create mode 100644 experiments/modern/src/runtime/Status.js create mode 100644 experiments/modern/src/runtime/Text.js create mode 100644 experiments/modern/src/runtime/ToggleButton.js diff --git a/experiments/modern/src/App.js b/experiments/modern/src/App.js index 6ffcc86f..7e87be3d 100644 --- a/experiments/modern/src/App.js +++ b/experiments/modern/src/App.js @@ -7,33 +7,6 @@ const System = require("./runtime/System"); const runtime = require("./runtime"); const interpret = require("./maki-interpreter/interpreter"); -// const runtime = require("./maki-interpreter/runtime"); -// const System = require("./maki-interpreter/runtime/System"); -// const interpret = require("./maki-interpreter/interpreter"); - -const IGNORE_IDS = new Set([ - // The maki script shows/hides these depending on which corner you are in - "main2", - "main3", - "main4", - "Title2", - "Title3", - "Title4", - "mask2", - "mask3", - "mask4", - "placeholder", // This looks like something related to an EQ window - "Scaler", - "toggle", - "presets", - "auto", - // These need the maki script to get sized - "volumethumb", - "seekfull", - "seek1", - "Repeat", -]); - const SkinContext = React.createContext(null); async function getSkin() { @@ -49,6 +22,26 @@ async function getSkin() { return await initialize(zip, skinXml); } +function Container(props) { + const { id, children, default_x, default_y, default_visible } = props; + const style = { + position: "absolute", + }; + if (default_x !== undefined) { + style.left = Number(default_x); + } + if (default_y !== undefined) { + style.top = Number(default_y); + } + if (default_visible !== undefined) { + style.display = default_visible ? "block" : "none"; + } + return
{children}
; +} + function Layout({ id, background, @@ -105,13 +98,25 @@ function Layer({ id, image, children, x, y }) { if (y !== undefined) { params.top = Number(y); } + if (img.x !== undefined) { + params.backgroundPositionX = -Number(img.x); + } + if (img.y !== undefined) { + params.backgroundPositionY = -Number(img.y); + } + if (img.w !== undefined) { + params.width = Number(img.w); + } + if (img.h !== undefined) { + params.height = Number(img.h); + } return ( <> {children} @@ -189,6 +194,7 @@ function Group(props) { } const NODE_NAME_TO_COMPONENT = { + container: Container, layout: Layout, layer: Layer, button: Button, @@ -200,9 +206,6 @@ const NODE_NAME_TO_COMPONENT = { function XmlNode({ node }) { const attributes = node.xmlNode.attributes; const name = node.xmlNode.name; - if (attributes && IGNORE_IDS.has(attributes.id)) { - return null; - } if (name == null || name === "groupdef") { // name is null is likely a comment return null; @@ -210,7 +213,7 @@ function XmlNode({ node }) { const Component = NODE_NAME_TO_COMPONENT[name]; const childNodes = node.children || []; const children = childNodes.map((childNode, i) => ( - + childNode.visible && )); if (Component == null) { console.warn("Unknown node type", name); @@ -238,7 +241,7 @@ function App() { if (node.xmlNode.file.endsWith("standardframe.maki")) { break; } - const scriptGroup = Utils.findParentNodeOfType(node, ["group", "WinampAbstractionLayer"]); + const scriptGroup = Utils.findParentNodeOfType(node, ["group", "WinampAbstractionLayer", "WasabiXML"]); const system = new System(scriptGroup); await interpret({ runtime, data: node.xmlNode.script, system, log: false }); return node; @@ -256,6 +259,7 @@ function App() { return

Loading...

; } const { root, registry } = data; + return ( diff --git a/experiments/modern/src/debugger/Variable.js b/experiments/modern/src/debugger/Variable.js index a8317caa..77538461 100644 --- a/experiments/modern/src/debugger/Variable.js +++ b/experiments/modern/src/debugger/Variable.js @@ -7,7 +7,7 @@ function quote(str) { export default function Variable({ variable }) { let type = "UNKOWN"; switch (variable.typeName) { - case "OBJECT": + case "OBJECT": { const obj = runtime[variable.type]; if (obj == null) { type = "Unknown object"; @@ -15,6 +15,16 @@ export default function Variable({ variable }) { type = obj.getclassname(); } break; + } + case "SUBCLASS": { + const obj = runtime[variable.type.type]; + if (obj == null) { + type = "Unknown object"; + } else { + type = obj.getClassName(); + } + break; + } case "STRING": { const value = variable.getValue(); return `${variable.typeName}(${value == null ? "NULL" : quote(value)})`; diff --git a/experiments/modern/src/initialize.js b/experiments/modern/src/initialize.js index 28ea367f..6f81da2d 100644 --- a/experiments/modern/src/initialize.js +++ b/experiments/modern/src/initialize.js @@ -2,9 +2,13 @@ import * as Utils from "./utils"; const MakiObject = require("./runtime/MakiObject"); const WinampAbstractionLayer = require("./runtime/WinampAbstractionLayer"); const Layout = require('./runtime/Layout'); +const Layer = require('./runtime/Layer'); const Container = require('./runtime/Container'); const Group = require("./runtime/Group"); const Button = require("./runtime/Button"); +const ToggleButton = require("./runtime/ToggleButton"); +const Text = require("./runtime/Text"); +const Status = require("./runtime/Status"); function splitValues(str) { return str.split(",").map(parseFloat); @@ -144,7 +148,7 @@ const parsers = { return new MakiObject(node, parent); }, color: noop, - layer: noop, + layer: (node, parent) => new Layer(node, parent), layoutstatus: noop, hideobject: noop, button: (node, parent) => new Button(node, parent), @@ -199,10 +203,9 @@ const parsers = { }, truetypefont: noop, component: noop, - text: noop, - layer: noop, - togglebutton: noop, - status: noop, + text: (node, parent) => new Text(node, parent), + togglebutton: (node, parent) => new ToggleButton(node, parent), + status: (node, parent) => new Status(node, parent), slider: noop, bitmapfont: noop, vis: noop, @@ -221,7 +224,6 @@ const parsers = { nstatesbutton: noop, songticker: noop, menu: noop, - status: noop, albumart: noop, playlistplus: noop, async script(node, parent, registry, zip) { diff --git a/experiments/modern/src/maki-interpreter/virtualMachine.js b/experiments/modern/src/maki-interpreter/virtualMachine.js index 2088acd7..e716f3eb 100644 --- a/experiments/modern/src/maki-interpreter/virtualMachine.js +++ b/experiments/modern/src/maki-interpreter/virtualMachine.js @@ -138,6 +138,9 @@ function* interpret(start, program, stack = []) { methodName = methodName.toLowerCase(); const klass = classes[classesOffset]; + if (!klass) { + throw new Error("Need to add a missing class to runtime"); + } // This is a bit awkward. Because the variables are stored on the stack // before the object, we have to find the number of arguments without // actually having access to the object instance. @@ -145,10 +148,12 @@ function* interpret(start, program, stack = []) { const methodArgs = []; while (argCount--) { - methodArgs.push(stack.pop().getValue()); + const a = stack.pop(); + const aValue = a instanceof Variable ? a.getValue() : a; + methodArgs.push(aValue); } const variable = stack.pop(); - const obj = variable.getValue(); + const obj = variable instanceof Variable ? variable.getValue() : variable; stack.push(obj[methodName](...methodArgs)); break; } diff --git a/experiments/modern/src/runtime/GuiObject.js b/experiments/modern/src/runtime/GuiObject.js index 4090e8c8..4784a2b2 100644 --- a/experiments/modern/src/runtime/GuiObject.js +++ b/experiments/modern/src/runtime/GuiObject.js @@ -1,7 +1,12 @@ const MakiObject = require("./MakiObject"); -const { findDescendantByTypeAndId } = require("../utils"); +const { findDescendantByTypeAndId, unimplementedWarning } = require("../utils"); class GuiObject extends MakiObject { + constructor(node, parent) { + super(node, parent); + + this.visible = true; + } /** * getclassname() * @@ -14,6 +19,10 @@ class GuiObject extends MakiObject { findobject(id) { return findDescendantByTypeAndId(this, null, id); } + getobject(id) { + // Not sure this is correct, but it is my understanding this is just an alias + return this.findobject(id); + } init(newRoot) { newRoot.js_addChild(this); return this; @@ -32,6 +41,36 @@ class GuiObject extends MakiObject { getparent() { return this.parent; } + + show() { + this.visible = true; + } + + hide() { + this.visible = false; + } + + gettop() { + unimplementedWarning('gettop'); + return 5; + } + + getheight() { + unimplementedWarning('getheight'); + return 100; + } + + getwidth() { + unimplementedWarning('getwidth'); + return 100; + } + + resize(x, y, w, h) { + this.xmlNode.attributes.x = x; + this.xmlNode.attributes.y = y; + this.xmlNode.attributes.w = w; + this.xmlNode.attributes.h = h; + } } module.exports = GuiObject; diff --git a/experiments/modern/src/runtime/Layer.js b/experiments/modern/src/runtime/Layer.js new file mode 100644 index 00000000..3e941a59 --- /dev/null +++ b/experiments/modern/src/runtime/Layer.js @@ -0,0 +1,15 @@ +const GuiObject = require("./GuiObject"); + +class Layer extends GuiObject { + /** + * getclassname() + * + * Returns the class name for the object. + * @ret The class name. + */ + static getclassname() { + return "Layer"; + } +} + +module.exports = Layer; diff --git a/experiments/modern/src/runtime/Layout.js b/experiments/modern/src/runtime/Layout.js index 2e50ec9c..af29b29a 100644 --- a/experiments/modern/src/runtime/Layout.js +++ b/experiments/modern/src/runtime/Layout.js @@ -14,6 +14,15 @@ class Layout extends GuiObject { getcontainer() { return findParentNodeOfType(this, ["container"]);; } + + resize(x, y, w, h) { + this.xmlNode.attributes.x = x; + this.xmlNode.attributes.y = y; + this.xmlNode.attributes.minimum_w = w; + this.xmlNode.attributes.maximum_w = w; + this.xmlNode.attributes.minimum_h = h; + this.xmlNode.attributes.maximum_h = h; + } } module.exports = Layout; diff --git a/experiments/modern/src/runtime/List.js b/experiments/modern/src/runtime/List.js new file mode 100644 index 00000000..3b39b64e --- /dev/null +++ b/experiments/modern/src/runtime/List.js @@ -0,0 +1,15 @@ +const GuiObject = require("./GuiObject"); + +class List extends GuiObject { + /** + * getclassname() + * + * Returns the class name for the object. + * @ret The class name. + */ + static getclassname() { + return "List"; + } +} + +module.exports = List; diff --git a/experiments/modern/src/runtime/PopupMenu.js b/experiments/modern/src/runtime/PopupMenu.js new file mode 100644 index 00000000..c6696f32 --- /dev/null +++ b/experiments/modern/src/runtime/PopupMenu.js @@ -0,0 +1,28 @@ +const GuiObject = require("./GuiObject"); +const { unimplementedWarning } = require("../utils"); + +class PopupMenu extends GuiObject { + /** + * getclassname() + * + * Returns the class name for the object. + * @ret The class name. + */ + static getclassname() { + return "PopupMenu"; + } + addcommand(txt, id, checked, disabled) { + unimplementedWarning('addcommand'); + } + addseparator() { + unimplementedWarning('addseparator'); + } + checkcommand(id, check) { + unimplementedWarning('checkcommand'); + } + popatmouse() { + unimplementedWarning('popatmouse'); + } +} + +module.exports = PopupMenu; diff --git a/experiments/modern/src/runtime/Slider.js b/experiments/modern/src/runtime/Slider.js new file mode 100644 index 00000000..44bba6ef --- /dev/null +++ b/experiments/modern/src/runtime/Slider.js @@ -0,0 +1,15 @@ +const GuiObject = require("./GuiObject"); + +class Slider extends GuiObject { + /** + * getClassName() + * + * Returns the class name for the object. + * @ret The class name. + */ + static getClassName() { + return "Slider"; + } +} + +module.exports = Slider; diff --git a/experiments/modern/src/runtime/Status.js b/experiments/modern/src/runtime/Status.js new file mode 100644 index 00000000..4aa2b9e1 --- /dev/null +++ b/experiments/modern/src/runtime/Status.js @@ -0,0 +1,15 @@ +const GuiObject = require("./GuiObject"); + +class Status extends GuiObject { + /** + * getclassname() + * + * Returns the class name for the object. + * @ret The class name. + */ + static getclassname() { + return "Status"; + } +} + +module.exports = Status; diff --git a/experiments/modern/src/runtime/System.js b/experiments/modern/src/runtime/System.js index 8246a1a4..c4532d74 100644 --- a/experiments/modern/src/runtime/System.js +++ b/experiments/modern/src/runtime/System.js @@ -1,6 +1,6 @@ const Group = require("./Group"); const MakiObject = require("./MakiObject"); -const { findDescendantByTypeAndId } = require("../utils"); +const { findDescendantByTypeAndId, unimplementedWarning } = require("../utils"); class System extends MakiObject { constructor(scriptGroup = new Group()) { @@ -37,14 +37,38 @@ class System extends MakiObject { return "5.666"; } gettoken(str, separator, tokennum) { + unimplementedWarning('gettoken'); return "Some Token String"; } getparam() { + unimplementedWarning('getparam'); return "Some String"; } messagebox(message, msgtitle, flag, notanymoreId) { console.log({ message, msgtitle, flag, notanymoreId }); } + integertostring(value) { + return value.toString(); + } + getprivateint(section, item, defvalue) { + unimplementedWarning('getprivateint'); + return defvalue; + } + setprivateint(section, item, defvalue) { + unimplementedWarning('setprivateint'); + } + getleftvumeter() { + unimplementedWarning('getleftvumeter'); + return 0.5; + } + getrightvumeter() { + unimplementedWarning('getrightvumeter'); + return 0.5; + } + getvolume() { + unimplementedWarning('getvolume'); + return 1; + } } module.exports = System; diff --git a/experiments/modern/src/runtime/Text.js b/experiments/modern/src/runtime/Text.js new file mode 100644 index 00000000..826381b2 --- /dev/null +++ b/experiments/modern/src/runtime/Text.js @@ -0,0 +1,15 @@ +const GuiObject = require("./GuiObject"); + +class Text extends GuiObject { + /** + * getclassname() + * + * Returns the class name for the object. + * @ret The class name. + */ + static getclassname() { + return "Text"; + } +} + +module.exports = Text; diff --git a/experiments/modern/src/runtime/ToggleButton.js b/experiments/modern/src/runtime/ToggleButton.js new file mode 100644 index 00000000..c4e3ade6 --- /dev/null +++ b/experiments/modern/src/runtime/ToggleButton.js @@ -0,0 +1,15 @@ +const Button = require("./Button"); + +class ToggleButton extends Button { + /** + * getclassname() + * + * Returns the class name for the object. + * @ret The class name. + */ + static getclassname() { + return "ToggleButton"; + } +} + +module.exports = ToggleButton; diff --git a/experiments/modern/src/runtime/index.js b/experiments/modern/src/runtime/index.js index 73ee70ca..89f9754c 100644 --- a/experiments/modern/src/runtime/index.js +++ b/experiments/modern/src/runtime/index.js @@ -1,24 +1,31 @@ const System = require("./System"); const Button = require("./Button"); +const ToggleButton = require("./ToggleButton"); const Group = require("./Group"); const Layout = require('./Layout'); +const Layer = require('./Layer'); +const PopupMenu = require('./PopupMenu'); +const List = require('./List'); +const Status = require('./Status'); +const Text = require('./Text'); const Container = require('./Container'); const GuiObject = require("./GuiObject"); const MakiObject = require("./MakiObject"); -class PopupMenu {} -class List {} - const runtime = { "516549714a510d87b5a6e391e7f33532": MakiObject, d6f50f6449b793fa66baf193983eaeef: System, "45be95e5419120725fbb5c93fd17f1f9": Group, "4ee3e1994becc636bc78cd97b028869c": GuiObject, "698eddcd4fec8f1e44f9129b45ff09f9": Button, + b4dccfff4bcc81fe0f721b96ff0fbed5: ToggleButton, f4787af44ef7b2bb4be7fb9c8da8bea9: PopupMenu, e90dc47b4ae7840d0b042cb0fcf775d2: Container, "60906d4e482e537e94cc04b072568861": Layout, b2023ab54ba1434d6359aebec6f30375: List, + "5ab9fa1545579a7d5765c8aba97cc6a6": Layer, + "0f08c9404b23af39c4b8f38059bb7e8f": Status, + efaa867241fa310ea985dcb74bcb5b52: Text, }; module.exports = runtime; diff --git a/experiments/modern/src/utils.js b/experiments/modern/src/utils.js index 52ee9a7d..061db9f3 100644 --- a/experiments/modern/src/utils.js +++ b/experiments/modern/src/utils.js @@ -97,6 +97,10 @@ export async function inlineIncludes(xml, zip) { }); } +export function unimplementedWarning(name) { + console.warn(`Executing unimplemented MAKI function: ${name}`); +} + // Operations on trees export function findParentNodeOfType(node, type) { let n = node; @@ -114,10 +118,13 @@ export function findDescendantByTypeAndId(node, type, id) { return null; } + const idLC = id.toLowerCase(); for(let i = 0; i < node.children.length; i++) { const child = node.children[i]; if ((!type || child.xmlNode.name === type) && - (child.xmlNode.attributes !== undefined && child.xmlNode.attributes.id === id)) { + (child.xmlNode.attributes !== undefined && + child.xmlNode.attributes.id !== undefined && + child.xmlNode.attributes.id.toLowerCase() === idLC)) { return child; } }