Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions makefile.emscripten
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,10 @@ OBJS_BULLET_DYNAMICS = \
src/hsp3dish/extlib/src/BulletDynamics/Vehicle/btRaycastVehicle.gpjs.o \
src/hsp3dish/extlib/src/BulletDynamics/Vehicle/btWheelInfo.gpjs.o

JS_LILBS = \
src/hsp3/emscripten/utils.js \
src/hsp3dish/emscripten/license.js \

LIBS =
LIBS_GP = \
libgameplay.js.a \
Expand All @@ -413,12 +417,14 @@ all: $(TARGETS)

.SUFFIXES: .cpp

hsp3dish.js: $(OBJS) src/hsp3dish/emscripten/license.js
hsp3dish.js: $(OBJS) $(JS_LILBS)
$(CXX) $(CFLAGS) $(LINK_FLAGS) $(OBJS) -o $@ $(LIBS) \
--post-js src/hsp3/emscripten/utils.js \
--extern-pre-js src/hsp3dish/emscripten/license.js

hsp3dish-gp.js: $(OBJS_GP) $(LIBS_GP) src/hsp3dish/emscripten/license.js
hsp3dish-gp.js: $(OBJS_GP) $(LIBS_GP) $(JS_LILBS)
$(CXX) $(CFLAGS_GP) $(LINK_FLAGS_GP) $(OBJS_GP) $(LIBS_GP) -o hsp3dish-gp.js \
--post-js src/hsp3/emscripten/utils.js \
--extern-pre-js src/hsp3dish/emscripten/license.js

libgameplay.js.a: $(OBJS_GAMEPLAY)
Expand Down
34 changes: 34 additions & 0 deletions sample/hsp3dish/js_interop1.hsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "hsp3dish.as"

exec {"
let textbox = document.createElement("textarea");
textbox.id = 'textbox1';
textbox.rows = 5;
textbox.cols = 80;
document.body.appendChild(textbox);
"}

sec = 0
ms = 0
sdim s, 1024
s = "Hello"

*main
exec {"
const now = new Date();
hsp3.lpoke("} + varptr(sec) + {", now.getSeconds());
hsp3.lpoke("} + varptr(ms) + {", now.getMilliseconds());
let textbox = document.getElementById("textbox1");
hsp3.write_str("} + varptr(s) + {", textbox.value, 1024);
"}

redraw 0
color 255, 255, 255 : boxf : pos 0,0
color 0, 0, 0
mes "now " + sec + ":" + ms
mes "text:" + s

redraw 1
await 33
goto *main

180 changes: 180 additions & 0 deletions src/hsp3/emscripten/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
var hsp3;

(function (hsp3) {
// Read / Write memory

/**
* Writes a byte value to the specified memory address.
* @param {number} ptr - The memory address.
* @param {number} value - The byte value to write.
*/
hsp3.poke = function (ptr, value) {
Module.HEAPU8[ptr] = value;
};

/**
* Writes a word (2 bytes) value to the specified memory address.
* @param {number} ptr - The memory address.
* @param {number} value - The word value to write.
*/
hsp3.wpoke = function (ptr, value) {
Module.HEAPU8[ptr] = value & 0xff;
Module.HEAPU8[ptr + 1] = (value >> 8) & 0xff;
};

/**
* Writes a long (4 bytes) value to the specified memory address.
* @param {number} ptr - The memory address.
* @param {number} value - The long value to write.
*/
hsp3.lpoke = function (ptr, value) {
Module.HEAPU8[ptr] = value & 0xff;
Module.HEAPU8[ptr + 1] = (value >> 8) & 0xff;
Module.HEAPU8[ptr + 2] = (value >> 16) & 0xff;
Module.HEAPU8[ptr + 3] = (value >> 24) & 0xff;
};

/**
* Writes a float value to the specified memory address.
* @param {number} ptr - The memory address.
* @param {number} value - The float value to write.
* @throws {Error} If the pointer is not aligned to 4 bytes.
*/
hsp3.fpoke = function (ptr, value) {
if (ptr & 3) {
throw new Error("fpoke: unaligned pointer");
}
Module.HEAPF32[ptr >> 2] = value;
};

/**
* Writes a double value to the specified memory address.
* @param {number} ptr - The memory address.
* @param {number} value - The double value to write.
* @throws {Error} If the pointer is not aligned to 8 bytes.
*/
hsp3.dpoke = function (ptr, value) {
if (ptr & 7) {
throw new Error("dpoke: unaligned pointer");
}
Module.HEAPF64[ptr >> 3] = value;
};

/**
* Reads a byte value from the specified memory address.
* @param {number} ptr - The memory address.
* @returns {number} The byte value read.
*/
hsp3.peek = function (ptr) {
return Module.HEAPU8[ptr];
};

/**
* Reads a word (2 bytes) value from the specified memory address.
* @param {number} ptr - The memory address.
* @returns {number} The word value read.
*/
hsp3.wpeek = function (ptr) {
return Module.HEAPU8[ptr] | (Module.HEAPU8[ptr + 1] << 8);
};

/**
* Reads a long (4 bytes) value from the specified memory address.
* @param {number} ptr - The memory address.
* @returns {number} The long value read.
*/
hsp3.lpeek = function (ptr) {
return (
Module.HEAPU8[ptr] |
(Module.HEAPU8[ptr + 1] << 8) |
(Module.HEAPU8[ptr + 2] << 16) |
(Module.HEAPU8[ptr + 3] << 24)
);
};

/**
* Reads a float value from the specified memory address.
* @param {number} ptr - The memory address.
* @returns {number} The float value read.
* @throws {Error} If the pointer is not aligned to 4 bytes.
*/
hsp3.fpeek = function (ptr) {
if (ptr & 3) {
throw new Error("fpeek: unaligned pointer");
}
return Module.HEAPF32[ptr >> 2];
};

/**
* Reads a double value from the specified memory address.
* @param {number} ptr - The memory address.
* @returns {number} The double value read.
* @throws {Error} If the pointer is not aligned to 8 bytes.
*/
hsp3.dpeek = function (ptr) {
if (ptr & 7) {
throw new Error("dpeek: unaligned pointer");
}
return Module.HEAPF64[ptr >> 3];
};

/**
* Writes a string to the specified memory address.
* @param {number} ptr - The memory address.
* @param {string} str - The string to copy.
* @param {number} max_bytes - The maximum bytes of the string
* @throws {Error} If the arguments are invalid.
*/
hsp3.write_str = function (ptr, str, max_bytes) {
if (typeof ptr !== "number") {
throw new Error("strcpy: invalid argument");
}
if (typeof str !== "string") {
throw new Error("strcpy: invalid argument");
}
if (typeof max_bytes !== "number") {
throw new Error("strcpy: invalid argument");
}
stringToUTF8(str, ptr, max_bytes);
};

/**
* Reads a string from the specified memory address.
* @param {number} ptr - The memory address.
* @returns {string} The string read.
*/
hsp3.read_str = function (ptr) {
return UTF8ToString(ptr);
};

// File I/O

/**
* Writes data to a file at the specified path.
* @param {string} path - The file path.
* @param {Uint8Array} data - The data to write.
*/
hsp3.write_file = function (path, data) {
let dirs = path.split("/");
if (dirs.length > 1) {
for (let i = 1; i < dirs.length; i++) {
if (dirs[i - 1] === "") continue;
let dir = dirs.slice(0, i).join("/");
if (!FS.analyzePath(dir).exists) {
console.log("mkdir", dir);
FS.mkdir(dir);
}
}
}
FS.writeFile(path, data);
};

/**
* Reads data from a file at the specified path.
* @param {string} path - The file path.
* @returns {Uint8Array} The data read from the file.
*/
hsp3.read_file = function (path) {
return FS.readFile(path);
};
})(hsp3 || (hsp3 = {}));