Files
nethack/sys/lib/test/test.js
Adam Powers 4ffb8c9ce3 fix naming
2020-08-30 10:46:55 -07:00

187 lines
5.6 KiB
JavaScript

const util = require("util");
// Emscripten Module config
let Module = {
// noInitialRun: true,
onRuntimeInitialized: function () {
setGraphicsCallback();
},
};
var factory = require("./src/nethack.js");
// load and run the module
factory(Module);
function setGraphicsCallback() {
console.log("setting callback function");
let cb = Module.addFunction(windowCallback, "viiii");
console.log("doing call");
Module.ccall(
"shim_graphics_set_callback", // C function name
null, // return type
["number"], // arg types
[cb], // arg values
{async: true} // options
);
/* TODO: removeFunction */
}
function windowCallback(name, retPtr, fmt, args) {
// console.log ("variadicCallback called...");
// console.log("typeof name", typeof name);
// console.log("typeof fmt", typeof fmt);
// console.log("typeof args", typeof args);
name = Module.UTF8ToString(name);
fmt = Module.UTF8ToString(fmt);
// console.log ("name:", name);
// console.log ("fmt:", fmt);
let argTypes = fmt.split("");
let retType = argTypes.shift();
// console.log ("arg count:", argTypes.length);
// console.log ("arg types:", argTypes);
// console.log ("ret type:", retType);
let jsArgs = [];
for (let i = 0; i < argTypes.length; i++) {
let ptr = args + (4*i);
let val = typeLookup(argTypes[i], ptr);
jsArgs.push(val);
}
console.log(`graphics callback: ${name} [${jsArgs}]`);
let retVal = doGraphics(name, ... jsArgs);
setReturn(name, retPtr, retType, retVal);
}
function typeLookup(type, ptr) {
switch(type) {
case "s": // string
return Module.UTF8ToString(Module.getValue(ptr, "*"));
case "p": // pointer
ptr = Module.getValue(ptr, "*");
if(!ptr) return 0; // null pointer
return Module.getValue(ptr, "*");
case "c": // char
return String.fromCharCode(Module.getValue(Module.getValue(ptr, "*"), "i8"));
case "0": /* 2^0 = 1 byte */
return Module.getValue(Module.getValue(ptr, "*"), "i8");
case "1": /* 2^1 = 2 bytes */
return Module.getValue(Module.getValue(ptr, "*"), "i16");
case "2": /* 2^2 = 4 bytes */
case "i": // integer
case "n": // number
return Module.getValue(Module.getValue(ptr, "*"), "i32");
case "f": // float
return Module.getValue(Module.getValue(ptr, "*"), "float");
case "d": // double
return Module.getValue(Module.getValue(ptr, "*"), "double");
default:
throw new TypeError ("unknown type:" + type);
}
}
function setReturn(name, ptr, type, value = 0) {
switch (type) {
case "p":
throw new Error("not implemented");
case "s":
if(typeof value !== "string")
throw new TypeError(`expected ${name} return type to be string`);
value=value?value:"(no value)";
var strPtr = Module.getValue(ptr, "i32");
Module.stringToUTF8(value, strPtr, 1024);
break;
case "i":
if(typeof value !== "number" || !Number.isInteger(value))
throw new TypeError(`expected ${name} return type to be integer`);
Module.setValue(ptr, value, "i32");
break;
case "c":
if(typeof value !== "number" || value < 0 || value > 128)
throw new TypeError(`expected ${name} return type to be integer representing an ASCII character`);
Module.setValue(ptr, value, "i8");
break;
case "f":
if(typeof value !== "number" || isFloat(value))
throw new TypeError(`expected ${name} return type to be float`);
// XXX: I'm not sure why 'double' works and 'float' doesn't
Module.setValue(ptr, value, "double");
break;
case "d":
if(typeof value !== "number" || isFloat(value))
throw new TypeError(`expected ${name} return type to be float`);
Module.setValue(ptr, value, "double");
break;
case "v":
break;
default:
throw new Error("unknown type");
}
function isFloat(n){
return n === +n && n !== (n|0) && !Number.isInteger(n);
}
}
let winCount = 0;
function doGraphics(name, ... args) {
switch(name) {
case "shim_create_nhwindow":
winCount++;
console.log("creating window", args, "returning", winCount);
return winCount;
case "shim_yn_function":
case "shim_message_menu":
return 121; // 'y'
case "shim_nhgetch":
case "shim_nh_poskey":
return 46;
default:
return 0;
}
}
// var Module = null;
// factory(Module).then((ret) => {
// if(ret !== Module) {
// console.log("ret and Module are not the same");
// } else {
// console.log("ret and Module are the same");
// }
// // console.log("Module", util.inspect(Module, {depth: null, showHidden: true}));
// // TODO:
// // shim_graphics_set_callback();
// // options:
// // https://emscripten.org/docs/api_reference/module.html
// // logReadFiles
// // printWithColors
// // noInitialRun
// // onRuntimeInitialized
// console.log("doing run");
// // Module.run();
// // // main loop
// // console.log("creating function");
// // let fn = Module.addFunction(wasmCallback, "vii");
// // console.log("doing call");
// // Module.ccall(
// // "mainloop", // C function name
// // null, // return type
// // ["number"], // arg types
// // [fn], // arg values
// // {async: true} // options
// // );
// // // TODO: removeFunction(fn)
// // var i = 0;
// // setInterval(function() {
// // console.log("interval", i++);
// // },1000);
// });