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;
}
}