Make converter plugin work
This commit is contained in:
@@ -9,68 +9,354 @@ plugin_notify_on_ui(plugin, function() {
|
||||
ui_files_show("arm", false, true, function(path) {
|
||||
let b = data_get_blob(path);
|
||||
let parsed = armpack_decode(b);
|
||||
let out = sys_string_to_buffer(JSON.stringify(parsed, function(key, value) {
|
||||
if (value.constructor.name === "Float32Array") {
|
||||
let ar = Array.from(value);
|
||||
ar.unshift(0); // Annotate array type
|
||||
return ar;
|
||||
}
|
||||
else if (value.constructor.name === "Uint32Array") {
|
||||
let ar = Array.from(value);
|
||||
ar.unshift(1);
|
||||
return ar;
|
||||
}
|
||||
else if (value.constructor.name === "Int16Array") {
|
||||
let ar = Array.from(value);
|
||||
ar.unshift(2);
|
||||
return ar;
|
||||
}
|
||||
return value;
|
||||
}, " "));
|
||||
let out = string_to_buffer(JSON.stringify(parsed, null, " "));
|
||||
krom_file_save_bytes(path.substr(0, path.length - 3) + "json", out);
|
||||
});
|
||||
}
|
||||
if (zui_button(".json to .arm")) {
|
||||
ui_files_show("json", false, true, function(path) {
|
||||
let b = data_get_blob(path);
|
||||
let parsed = json_parse(sys_buffer_to_string(b));
|
||||
function iterate(d) {
|
||||
for (const n of ReflectFields(d)) {
|
||||
let v = ReflectField(d, n);
|
||||
if (v.constructor.name === "Array") {
|
||||
if (v[0].constructor.name === "Number") {
|
||||
let ar = null;
|
||||
if (v[0] === 0) {
|
||||
ar = new Float32Array(v.length - 1);
|
||||
}
|
||||
else if (v[0] === 1) {
|
||||
ar = new Uint32Array(v.length - 1);
|
||||
}
|
||||
else if (v[0] === 2) {
|
||||
ar = new Int16Array(v.length - 1);
|
||||
}
|
||||
for (let i = 0; i < v.length - 1; ++i) {
|
||||
ar[i] = v[i + 1];
|
||||
}
|
||||
ReflectSetField(d, n, ar);
|
||||
}
|
||||
else {
|
||||
for (const e of v) {
|
||||
if (typeof e === 'object') {
|
||||
iterate(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (typeof v === 'object') {
|
||||
iterate(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
iterate(parsed);
|
||||
let parsed = JSON.parse(buffer_to_string(b));
|
||||
let out = armpack_encode(parsed);
|
||||
krom_file_save_bytes(path.substr(0, path.length - 4) + "arm", out, out.byteLength + 1);
|
||||
krom_file_save_bytes(path.substr(0, path.length - 4) + "arm", out);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function buffer_to_string(b) {
|
||||
let str = "";
|
||||
let u8a = new Uint8Array(b);
|
||||
for (let i = 0; i < u8a.length; ++i) {
|
||||
str += String.fromCharCode(u8a[i]);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function string_to_buffer(str) {
|
||||
let u8a = new Uint8Array(str.length);
|
||||
for (let i = 0; i < str.length; ++i) {
|
||||
u8a[i] = str.charCodeAt(i);
|
||||
}
|
||||
return u8a.buffer;
|
||||
}
|
||||
|
||||
let pos = 0;
|
||||
let k_type = "";
|
||||
|
||||
function armpack_decode(b) {
|
||||
pos = 0;
|
||||
return read(new DataView(b));
|
||||
}
|
||||
|
||||
function read_u8(v) {
|
||||
let i = v.getUint8(pos);
|
||||
pos++;
|
||||
return i;
|
||||
}
|
||||
|
||||
function read_i16(v) {
|
||||
let i = v.getInt16(pos, true);
|
||||
pos += 2;
|
||||
return i;
|
||||
}
|
||||
|
||||
function read_i32(v) {
|
||||
let i = v.getInt32(pos, true);
|
||||
pos += 4;
|
||||
return i;
|
||||
}
|
||||
|
||||
function read_u32(v) {
|
||||
let i = v.getUint32(pos, true);
|
||||
pos += 4;
|
||||
return i;
|
||||
}
|
||||
|
||||
function read_f32(v) {
|
||||
let f = v.getFloat32(pos, true);
|
||||
pos += 4;
|
||||
return f;
|
||||
}
|
||||
|
||||
function read_string(v, len) {
|
||||
let s = "";
|
||||
for (let i = 0; i < len; ++i) {
|
||||
s += String.fromCharCode(read_u8(v));
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
function read(v) {
|
||||
let b = read_u8(v);
|
||||
switch (b) {
|
||||
case 0xc0: return null;
|
||||
case 0xc2: return false;
|
||||
case 0xc3: return true;
|
||||
case 0xca: { k_type = "__f32"; return read_f32(v); }
|
||||
case 0xd2: return read_i32(v);
|
||||
case 0xdb: return read_string(v, read_u32(v));
|
||||
case 0xdd: return read_array(v, read_i32(v));
|
||||
case 0xdf: return read_map(v, read_i32(v));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function read_array(v, length) {
|
||||
let b = read_u8(v);
|
||||
|
||||
if (b == 0xca) { // Typed f32
|
||||
let a = new Array(length);
|
||||
for (let x = 0; x < length; ++x) a[x] = read_f32(v);
|
||||
k_type = "__f32";
|
||||
return a;
|
||||
}
|
||||
else if (b == 0xd2) { // Typed i32
|
||||
let a = new Array(length);
|
||||
for (let x = 0; x < length; ++x) a[x] = read_i32(v);
|
||||
k_type = "__i32";
|
||||
return a;
|
||||
}
|
||||
else if (b == 0xd1) { // Typed i16
|
||||
let a = new Array(length);
|
||||
for (let x = 0; x < length; ++x) a[x] = read_i16(v);
|
||||
k_type = "__i16";
|
||||
return a;
|
||||
}
|
||||
else if (b == 0xc4) { // Typed u8
|
||||
let a = new Array(length);
|
||||
for (let x = 0; x < length; ++x) a[x] = read_u8(v);
|
||||
k_type = "__u8";
|
||||
return a;
|
||||
}
|
||||
else { // Dynamic type-value
|
||||
pos--;
|
||||
let a = new Array(length);
|
||||
for (let x = 0; x < length; ++x) a[x] = read(v);
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
function read_map(v, length) {
|
||||
let out = {};
|
||||
for (let n = 0; n < length; ++n) {
|
||||
let k = read(v);
|
||||
k_type = "";
|
||||
let val = read(v);
|
||||
k += k_type;
|
||||
k_type = "";
|
||||
out[k] = val;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function armpack_encode(d) {
|
||||
pos = 0;
|
||||
write_dummy(d);
|
||||
console.log(pos);
|
||||
let b = new ArrayBuffer(pos);
|
||||
let v = new DataView(b);
|
||||
pos = 0;
|
||||
write(v, d);
|
||||
console.log(b.byteLength);
|
||||
return b;
|
||||
}
|
||||
|
||||
function write_u8(v, i) {
|
||||
v.setUint8(pos, i);
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
function write_i16(v, i) {
|
||||
v.setInt16(pos, i, true);
|
||||
pos += 2;
|
||||
}
|
||||
|
||||
function write_i32(v, i) {
|
||||
v.setInt32(pos, i, true);
|
||||
pos += 4;
|
||||
}
|
||||
|
||||
function write_f32(v, f) {
|
||||
v.setFloat32(pos, f, true);
|
||||
pos += 4;
|
||||
}
|
||||
|
||||
function write_string(v, str) {
|
||||
for (let i = 0; i < str.length; ++i) {
|
||||
write_u8(v, str.charCodeAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
function write(v, d) {
|
||||
if (d == null) {
|
||||
write_u8(v, 0xc0);
|
||||
}
|
||||
else if (typeof d == "boolean") {
|
||||
write_u8(v, d ? 0xc3 : 0xc2);
|
||||
}
|
||||
else if (typeof d == "number") {
|
||||
if (Number.isInteger(d) && k_type != "__f32") {
|
||||
write_u8(v, 0xd2);
|
||||
write_i32(v, d);
|
||||
}
|
||||
else {
|
||||
write_u8(v, 0xca);
|
||||
write_f32(v, d);
|
||||
}
|
||||
}
|
||||
else if (typeof d == "string") {
|
||||
write_u8(v, 0xdb);
|
||||
write_i32(v, d.length);
|
||||
write_string(v, d);
|
||||
}
|
||||
else if (Array.isArray(d)) {
|
||||
write_u8(v, 0xdd);
|
||||
write_i32(v, d.length);
|
||||
if (k_type == "__u8") {
|
||||
write_u8(v, 0xc4);
|
||||
for (let i = 0; i < d.length; ++i) {
|
||||
write_u8(v, d[i]);
|
||||
}
|
||||
}
|
||||
else if (k_type == "__i16") {
|
||||
write_u8(v, 0xd1);
|
||||
for (let i = 0; i < d.length; ++i) {
|
||||
write_i16(v, d[i]);
|
||||
}
|
||||
}
|
||||
else if (k_type == "__f32") {
|
||||
write_u8(v, 0xca);
|
||||
for (let i = 0; i < d.length; ++i) {
|
||||
write_f32(v, d[i]);
|
||||
}
|
||||
}
|
||||
else if (k_type == "__i32") {
|
||||
write_u8(v, 0xd2);
|
||||
for (let i = 0; i < d.length; ++i) {
|
||||
write_i32(v, d[i]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < d.length; ++i) {
|
||||
write(v, d[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
write_object(v, d);
|
||||
}
|
||||
}
|
||||
|
||||
function write_object(v, d) {
|
||||
let f = Object.keys(d);
|
||||
write_u8(v, 0xdf);
|
||||
write_i32(v, f.length);
|
||||
for (let i = 0; i < f.length; ++i) {
|
||||
let k = f[i];
|
||||
|
||||
k_type = "";
|
||||
if (k.endsWith("__f32")) {
|
||||
k_type = "__f32";
|
||||
}
|
||||
else if (k.endsWith("__i32")) {
|
||||
k_type = "__i32";
|
||||
}
|
||||
else if (k.endsWith("__i16")) {
|
||||
k_type = "__i16";
|
||||
}
|
||||
else if (k.endsWith("__u8")) {
|
||||
k_type = "__u8";
|
||||
}
|
||||
|
||||
write_u8(v, 0xdb);
|
||||
write_i32(v, k.length - k_type.length);
|
||||
|
||||
write_string(v, k.substring(0, k.length - k_type.length));
|
||||
write(v, d[k]);
|
||||
k_type = "";
|
||||
}
|
||||
}
|
||||
|
||||
function write_dummy(d) {
|
||||
if (d == null) {
|
||||
pos += 1;
|
||||
}
|
||||
else if (typeof d == "boolean") {
|
||||
pos += 1;
|
||||
}
|
||||
else if (typeof d == "number") {
|
||||
pos += 1;
|
||||
pos += 4;
|
||||
}
|
||||
else if (typeof d == "string") {
|
||||
pos += 1;
|
||||
pos += 4;
|
||||
pos += d.length;
|
||||
}
|
||||
else if (Array.isArray(d)) {
|
||||
pos += 1;
|
||||
pos += 4;
|
||||
if (k_type == "__u8") {
|
||||
pos += 1;
|
||||
for (let i = 0; i < d.length; ++i) {
|
||||
pos += 1;
|
||||
}
|
||||
}
|
||||
else if (k_type == "__i16") {
|
||||
pos += 1;
|
||||
for (let i = 0; i < d.length; ++i) {
|
||||
pos += 2;
|
||||
}
|
||||
}
|
||||
else if (k_type == "__f32") {
|
||||
pos += 1;
|
||||
for (let i = 0; i < d.length; ++i) {
|
||||
pos += 4;
|
||||
}
|
||||
}
|
||||
else if (k_type == "__i32") {
|
||||
pos += 1;
|
||||
for (let i = 0; i < d.length; ++i) {
|
||||
pos += 4;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < d.length; ++i) {
|
||||
write_dummy(d[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
write_object_dummy(d);
|
||||
}
|
||||
}
|
||||
|
||||
function write_object_dummy(d) {
|
||||
let f = Object.keys(d);
|
||||
pos += 1;
|
||||
pos += 4;
|
||||
for (let i = 0; i < f.length; ++i) {
|
||||
let k = f[i];
|
||||
pos += 1;
|
||||
pos += 4;
|
||||
|
||||
k_type = "";
|
||||
if (k.endsWith("__f32")) {
|
||||
k_type = "__f32";
|
||||
}
|
||||
else if (k.endsWith("__i32")) {
|
||||
k_type = "__i32";
|
||||
}
|
||||
else if (k.endsWith("__i16")) {
|
||||
k_type = "__i16";
|
||||
}
|
||||
else if (k.endsWith("__u8")) {
|
||||
k_type = "__u8";
|
||||
}
|
||||
|
||||
pos += k.length - k_type.length;
|
||||
write_dummy(d[k]);
|
||||
k_type = "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,16 @@ MAKE_FN(data_get_blob) {
|
||||
return val;
|
||||
}
|
||||
|
||||
void *krom_file_save_bytes(char *s, buffer_t *b, int l);
|
||||
MAKE_FN(krom_file_save_bytes) {
|
||||
char *to = (char *)JS_ToCString(ctx, argv[0]);
|
||||
int64_t len;
|
||||
void *ab = JS_GetArrayBuffer(ctx, &len, argv[1]);
|
||||
buffer_t b = { .buffer = ab, .length = len, .capacity = len };
|
||||
krom_file_save_bytes(to, &b, len);
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
MAKE_FN(zui_handle_create) {
|
||||
int64_t result = (int64_t)zui_handle_create();
|
||||
return JS_NewInt64(ctx, result);
|
||||
@@ -187,6 +197,7 @@ void plugin_api_init() {
|
||||
BIND_FN(plugin_notify_on_ui, 2);
|
||||
BIND_FN(ui_files_show, 4);
|
||||
BIND_FN(data_get_blob, 1);
|
||||
BIND_FN(krom_file_save_bytes, 3);
|
||||
|
||||
BIND_FN(zui_handle_create, 0);
|
||||
BIND_FN(zui_panel, 2);
|
||||
|
||||
Reference in New Issue
Block a user