plugins: move to minic

This commit is contained in:
luboslenco
2026-03-23 23:20:02 +01:00
parent d668fb1943
commit dd0fc333d1
60 changed files with 650 additions and 1744 deletions
+4 -4
View File
@@ -204,10 +204,10 @@ if (flags.with_audio) {
if (flags.with_eval) {
project.add_define("WITH_EVAL");
project.add_cfiles("sources/libs/quickjs-amalgam.c");
project.add_define("QJS_BUILD_LIBC");
// project.add_cfiles("tools/amake/alang.c");
// project.add_cfiles("tools/amake/alang_eval.c");
project.add_cfiles("sources/libs/minic.c");
project.add_cfiles("sources/libs/minic_ext.c");
project.add_cfiles("sources/libs/minic_api.c");
project.add_cfiles("sources/libs/minic_tests.c");
}
if (flags.with_gamepad) {
+4 -1
View File
@@ -6,7 +6,6 @@
#include "iron_armpack.h"
#include "iron_array.h"
#include "iron_draw.h"
#include "iron_eval.h"
#include "iron_file.h"
#include "iron_gc.h"
#include "iron_gpu.h"
@@ -20,6 +19,7 @@
#include "iron_system.h"
#include "iron_thread.h"
#include "iron_ui.h"
#include "libs/minic.h"
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
@@ -823,6 +823,9 @@ gpu_texture_t *gpu_create_texture_from_encoded_bytes(buffer_t *data, char *forma
if (data == NULL || data->length == 0) {
return NULL;
}
if (ends_with(format, "txt")) { // plugin
return NULL;
}
gpu_texture_t *texture = (gpu_texture_t *)malloc(sizeof(gpu_texture_t));
texture->buffer = NULL;
unsigned char *texture_data;
-124
View File
@@ -1,124 +0,0 @@
#include "iron_eval.h"
#include <stdlib.h>
#ifdef WITH_EVAL
#include "quickjs-libc.h"
#include "quickjs.h"
JSRuntime *js_runtime = NULL;
JSContext *js_ctx;
#ifdef WITH_PLUGINS
void plugin_api_init();
#endif
void console_trace(char *s);
extern int _argc;
extern char **_argv;
void js_init() {
js_runtime = JS_NewRuntime();
js_ctx = JS_NewContext(js_runtime);
js_std_add_helpers(js_ctx, _argc, _argv);
js_init_module_std(js_ctx, "std");
js_init_module_os(js_ctx, "os");
#ifdef WITH_PLUGINS
plugin_api_init();
#endif
}
// float alang_eval(char *data);
float js_eval(const char *js) {
// return alang_eval(js);
if (js_runtime == NULL) {
js_init();
}
JSValue ret = JS_Eval(js_ctx, js, strlen(js), "iron", JS_EVAL_TYPE_GLOBAL);
if (JS_IsException(ret)) {
JSValue exc = JS_GetException(js_ctx);
const char *error_msg = JS_ToCString(js_ctx, exc);
console_trace(error_msg);
JS_FreeCString(js_ctx, error_msg);
if (JS_IsError(exc)) {
JSValue stack = JS_GetPropertyStr(js_ctx, exc, "stack");
const char *stack_msg = JS_ToCString(js_ctx, stack);
console_trace(stack_msg);
JS_FreeCString(js_ctx, stack_msg);
JS_FreeValue(js_ctx, stack);
}
JS_FreeValue(js_ctx, exc);
JS_ResetUncatchableError(js_ctx);
return 0.0;
}
double d;
JS_ToFloat64(js_ctx, &d, ret);
JS_RunGC(js_runtime);
if (d != d) { // nan
d = 0.0;
}
return d;
}
JSValue js_call_arg(void *p, int argc, JSValue *argv) {
if (js_runtime == NULL) {
js_init();
}
JSValue fn = *(JSValue *)p;
JSValue global_obj = JS_GetGlobalObject(js_ctx);
JSValue js_call_result = JS_Call(js_ctx, fn, global_obj, argc, argv);
if (JS_IsException(js_call_result)) {
js_std_dump_error(js_ctx);
JS_ResetUncatchableError(js_ctx);
}
JS_FreeValue(js_ctx, global_obj);
return js_call_result;
}
char *js_call_ptr(void *p, void *arg) {
JSValue argv[] = {JS_NewBigUint64(js_ctx, (uint64_t)arg)};
return (char *)JS_ToCString(js_ctx, js_call_arg(p, 1, argv));
}
char *js_call_ptr_str(void *p, void *arg0, char *arg1) {
JSValue argv[] = {JS_NewBigUint64(js_ctx, (uint64_t)arg0), JS_NewString(js_ctx, arg1)};
return (char *)JS_ToCString(js_ctx, js_call_arg(p, 2, argv));
}
void *js_pcall_str(void *p, char *arg0) {
JSValue argv[] = {JS_NewString(js_ctx, arg0)};
uint64_t result;
JS_ToBigUint64(js_ctx, &result, js_call_arg(p, 1, argv));
return (void *)result;
}
char *js_call(void *p) {
return (char *)JS_ToCString(js_ctx, js_call_arg(p, 0, NULL));
}
#else
void js_init() {}
float js_eval(const char *js) {
return 0.0;
}
void js_call_arg(void *p, int argc, void *argv) {}
char *js_call_ptr(void *p, void *arg) {
return NULL;
}
char *js_call_ptr_str(void *p, void *arg0, char *arg1) {
return NULL;
}
void *js_pcall_str(void *p, char *arg0) {
return NULL;
}
char *js_call(void *p) {
return NULL;
}
#endif
-26
View File
@@ -1,26 +0,0 @@
#pragma once
#ifdef WITH_EVAL
#include "quickjs-libc.h"
#include "quickjs.h"
void js_init();
float js_eval(const char *js);
JSValue js_call_arg(void *p, int argc, JSValue *argv);
char *js_call_ptr(void *p, void *arg);
char *js_call_ptr_str(void *p, void *arg0, char *arg1);
void *js_pcall_str(void *p, char *arg0);
char *js_call(void *p);
#else
void js_init();
float js_eval(const char *js);
void js_call_arg(void *p, int argc, void *argv);
char *js_call_ptr(void *p, void *arg);
char *js_call_ptr_str(void *p, void *arg0, char *arg1);
void *js_pcall_str(void *p, char *arg0);
char *js_call(void *p);
#endif
-7
View File
@@ -35,19 +35,12 @@ size_t iron_file_reader_size(iron_file_reader_t *reader);
size_t iron_file_reader_pos(iron_file_reader_t *reader);
bool iron_file_reader_seek(iron_file_reader_t *reader, size_t pos);
float iron_read_f32le(uint8_t *data);
float iron_read_f32be(uint8_t *data);
uint64_t iron_read_u64le(uint8_t *data);
uint64_t iron_read_u64be(uint8_t *data);
int64_t iron_read_s64le(uint8_t *data);
int64_t iron_read_s64be(uint8_t *data);
uint32_t iron_read_u32le(uint8_t *data);
uint32_t iron_read_u32be(uint8_t *data);
int32_t iron_read_s32le(uint8_t *data);
int32_t iron_read_s32be(uint8_t *data);
uint16_t iron_read_u16le(uint8_t *data);
uint16_t iron_read_u16be(uint8_t *data);
int16_t iron_read_s16le(uint8_t *data);
int16_t iron_read_s16be(uint8_t *data);
uint8_t iron_read_u8(uint8_t *data);
int8_t iron_read_s8(uint8_t *data);
+3 -8
View File
@@ -252,7 +252,7 @@ bool path_is_project(char *path) {
bool path_is_plugin(char *path) {
char *p = to_lower_case(path);
return ends_with(p, ".js");
return ends_with(p, ".c");
}
bool path_is_json(char *path) {
@@ -265,19 +265,14 @@ bool path_is_text(char *path) {
return ends_with(p, ".txt");
}
bool path_is_gimp_color_palette(char *path) {
char *p = to_lower_case(path);
return ends_with(p, ".gpl");
}
bool path_is_ext_format(char *path) {
char *p = to_lower_case(path);
return ends_with(p, ".fbx") || ends_with(p, ".gltf") || ends_with(p, ".glb") || ends_with(p, ".stl") || ends_with(p, ".svg");
return ends_with(p, ".stl") || ends_with(p, ".svg");
}
bool path_is_known(char *path) {
return path_is_mesh(path) || path_is_texture(path) || path_is_font(path) || path_is_project(path) || path_is_plugin(path) || path_is_text(path) ||
path_is_gimp_color_palette(path) || path_is_ext_format(path);
path_is_ext_format(path);
}
bool path_check_ext(char *p, string_array_t *exts) {
-1
View File
@@ -30,7 +30,6 @@ bool path_is_project(char *path);
bool path_is_plugin(char *path);
bool path_is_json(char *path);
bool path_is_text(char *path);
bool path_is_gimp_color_palette(char *path);
bool path_is_ext_format(char *path);
bool path_is_known(char *path);
bool path_is_base_color_tex(char *p);
+4 -2
View File
@@ -34,7 +34,7 @@ bool ui_is_paste = false;
void (*ui_on_border_hover)(ui_handle_t *, int) = NULL; // Mouse over window border, use for resizing
void (*ui_on_tab_drop)(ui_handle_t *, int, ui_handle_t *, int) = NULL; // Tab reorder via drag and drop
#ifdef WITH_EVAL
float js_eval(char *str);
#include "libs/minic.h"
#endif
f32_array_t *_ui_row2 = NULL;
@@ -2280,7 +2280,9 @@ float ui_slider(ui_handle_t *handle, char *text, float from, float to, bool fill
if (current->submit_text_handle == handle) {
ui_submit_text_edit();
#ifdef WITH_EVAL
handle->f = js_eval(handle->text);
minic_ctx_t *_ctx = minic_eval(string("float main() { return %s; }", handle->text));
handle->f = minic_ctx_result(_ctx);
minic_ctx_free(_ctx);
#else
handle->f = atof(handle->text);
#endif
-1
View File
@@ -377,7 +377,6 @@ float UI_SCROLL_W();
float UI_TEXT_OFFSET();
float UI_TAB_W();
float UI_HEADER_DRAG_H();
float UI_FLASH_SPEED();
float UI_TOOLTIP_DELAY();
extern bool ui_touch_control;
-623
View File
@@ -1,623 +0,0 @@
#include "plugin_api.h"
#include "iron_armpack.h"
#include "iron_array.h"
#include "iron_map.h"
#include "iron_math.h"
#include "iron_obj.h"
#include "iron_ui.h"
void plugin_embed();
// ██╗ ██╗██████╗
// ██║ ██║██╔══██╗
// ██║ ██║██████╔╝
// ██║ ██║██╔══██╗
// ███████╗██║██████╔╝
// ╚══════╝╚═╝╚═════╝
const char *lib = "\
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);\
let b = new ArrayBuffer(pos);\
let v = new DataView(b);\
pos = 0;\
write(v, d);\
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 = \"\";\
}\
}\
\
globalThis.armpack_encode = armpack_encode;\
globalThis.armpack_decode = armpack_decode;\
globalThis.string_to_buffer = string_to_buffer;\
globalThis.buffer_to_string = buffer_to_string;\
";
// ██████╗ ██╗███╗ ██╗██████╗ ██╗███╗ ██╗ ██████╗ ███████╗
// ██╔══██╗██║████╗ ██║██╔══██╗██║████╗ ██║██╔════╝ ██╔════╝
// ██████╔╝██║██╔██╗ ██║██║ ██║██║██╔██╗ ██║██║ ███╗███████╗
// ██╔══██╗██║██║╚██╗██║██║ ██║██║██║╚██╗██║██║ ██║╚════██║
// ██████╔╝██║██║ ╚████║██████╔╝██║██║ ╚████║╚██████╔╝███████║
// ╚═════╝ ╚═╝╚═╝ ╚═══╝╚═════╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝
any_array_t *plugin_gc;
void gc_root(void *ptr);
void gc_run();
// These could be auto-generated by alang
VOID_FN(gc_run)
void *data_get_blob(char *s);
FN(data_get_blob) {
char *s = (char *)JS_ToCString(ctx, argv[0]);
buffer_t *b = data_get_blob(s);
JSValue val = JS_NewArrayBuffer(ctx, b->buffer, b->length, NULL, NULL, 0);
return val;
}
void *data_delete_blob(char *s);
FN(data_delete_blob) {
char *s = (char *)JS_ToCString(ctx, argv[0]);
data_delete_blob(s);
return JS_UNDEFINED;
}
void *iron_file_save_bytes(char *s, buffer_t *b, int l);
FN(iron_file_save_bytes) {
char *to = (char *)JS_ToCString(ctx, argv[0]);
size_t len;
void *ab = JS_GetArrayBuffer(ctx, &len, argv[1]);
buffer_t b = {.buffer = ab, .length = len, .capacity = len};
iron_file_save_bytes(to, &b, len);
return JS_UNDEFINED;
}
void *gpu_create_texture_from_bytes(void *p, int w, int h, int format);
FN(gpu_create_texture_from_bytes) {
size_t len;
void *ab = JS_GetArrayBuffer(ctx, &len, argv[0]);
buffer_t b = {.buffer = ab, .length = len, .capacity = len};
int64_t w;
JS_ToInt64(ctx, &w, argv[1]);
int64_t h;
JS_ToInt64(ctx, &h, argv[2]);
int64_t format = 0;
if (argc > 3) {
JS_ToInt64(ctx, &format, argv[3]);
}
uint64_t result = (uint64_t)gpu_create_texture_from_bytes(&b, w, h, format);
return JS_NewBigUint64(ctx, result);
}
FN(ui_handle_create) {
uint64_t result = (uint64_t)ui_handle_create();
any_array_push(plugin_gc, (void *)result);
return JS_NewBigUint64(ctx, result);
}
FN(ui_handle_set_value) {
uint64_t p;
JS_ToBigUint64(ctx, &p, argv[0]);
ui_handle_t *h = (ui_handle_t *)p;
double d;
JS_ToFloat64(ctx, &d, argv[1]);
h->f = d;
return JS_UNDEFINED;
}
FN(ui_handle_get_value) {
uint64_t p;
JS_ToBigUint64(ctx, &p, argv[0]);
ui_handle_t *h = (ui_handle_t *)p;
return JS_NewFloat64(ctx, h->f);
}
FN(ui_panel) {
uint64_t p;
JS_ToBigUint64(ctx, &p, argv[0]);
char *s = (char *)JS_ToCString(ctx, argv[1]);
bool result = ui_panel((void *)p, s, false, false, false);
return JS_NewBool(ctx, result);
}
FN(ui_button) {
char *s = (char *)JS_ToCString(ctx, argv[0]);
bool result = ui_button(s, UI_ALIGN_CENTER, "");
return JS_NewBool(ctx, result);
}
FN(ui_text) {
char *s = (char *)JS_ToCString(ctx, argv[0]);
ui_text(s, UI_ALIGN_LEFT, 0);
return JS_UNDEFINED;
}
FN(ui_text_input) {
uint64_t p;
JS_ToBigUint64(ctx, &p, argv[0]);
char *s = (char *)JS_ToCString(ctx, argv[1]);
ui_text_input((void *)p, s, UI_ALIGN_LEFT, true, false);
return JS_UNDEFINED;
}
FN(ui_slider) {
uint64_t p;
JS_ToBigUint64(ctx, &p, argv[0]);
char *s = (char *)JS_ToCString(ctx, argv[1]);
double from = 0.0;
double to = 1.0;
bool filled = true;
double prec = 100.0;
if (argc > 2) {
JS_ToFloat64(ctx, &from, argv[2]);
}
if (argc > 3) {
JS_ToFloat64(ctx, &to, argv[3]);
}
if (argc > 4) {
filled = JS_ToBool(ctx, argv[4]);
}
if (argc > 5) {
JS_ToFloat64(ctx, &prec, argv[5]);
}
ui_slider((void *)p, s, from, to, filled, prec, true, UI_ALIGN_LEFT, true);
return JS_UNDEFINED;
}
FN(ui_check) {
uint64_t p;
JS_ToBigUint64(ctx, &p, argv[0]);
char *s = (char *)JS_ToCString(ctx, argv[1]);
ui_check((void *)p, s, "");
return JS_UNDEFINED;
}
FN(ui_radio) {
uint64_t p;
JS_ToBigUint64(ctx, &p, argv[0]);
int32_t pos;
JS_ToInt32(ctx, &pos, argv[1]);
char *s = (char *)JS_ToCString(ctx, argv[2]);
ui_radio((void *)p, pos, s, "");
return JS_UNDEFINED;
}
FN(ui_row) {
JSValue val_len = JS_GetPropertyStr(ctx, argv[0], "length");
int len;
JS_ToInt32(ctx, &len, val_len);
f32_array_t *ratios = f32_array_create(len);
for (int i = 0; i < len; ++i) {
JSValue val = JS_GetPropertyUint32(ctx, argv[0], i);
double f;
JS_ToFloat64(ctx, &f, val);
ratios->buffer[i] = f;
}
ui_row(ratios);
return JS_UNDEFINED;
}
FN(ui_combo) {
uint64_t p;
JS_ToBigUint64(ctx, &p, argv[0]);
JSValue val_len = JS_GetPropertyStr(ctx, argv[1], "length");
int len;
JS_ToInt32(ctx, &len, val_len);
string_array_t *texts = any_array_create(len);
for (int i = 0; i < len; ++i) {
JSValue val = JS_GetPropertyUint32(ctx, argv[1], i);
char *s = (char *)JS_ToCString(ctx, val);
texts->buffer[i] = s;
}
char *label = (char *)JS_ToCString(ctx, argv[2]);
ui_combo((void *)p, texts, label, true, UI_ALIGN_LEFT, true);
return JS_UNDEFINED;
}
FN(plugin_api_make_raw_mesh) {
raw_mesh_t *mesh = calloc(sizeof(raw_mesh_t), 1);
mesh->name = (char *)JS_ToCString(ctx, argv[0]);
size_t len;
void *ab = JS_GetArrayBuffer(ctx, &len, argv[1]);
mesh->posa = malloc(sizeof(i16_array_t));
mesh->posa->buffer = malloc(len);
memcpy(mesh->posa->buffer, ab, len);
mesh->posa->length = len / 2;
ab = JS_GetArrayBuffer(ctx, &len, argv[2]);
mesh->nora = malloc(sizeof(i16_array_t));
mesh->nora->buffer = malloc(len);
memcpy(mesh->nora->buffer, ab, len);
mesh->nora->length = len / 2;
ab = JS_GetArrayBuffer(ctx, &len, argv[3]);
mesh->inda = malloc(sizeof(u32_array_t));
mesh->inda->buffer = malloc(len);
memcpy(mesh->inda->buffer, ab, len);
mesh->inda->length = len / 4;
double d;
JS_ToFloat64(ctx, &d, argv[4]);
mesh->scale_pos = d;
mesh->scale_tex = 1.0;
return JS_NewBigUint64(ctx, (uint64_t)mesh);
}
void transform_rotate(void *raw, vec4_t axis, float f);
FN(transform_rotate) {
uint64_t p;
JS_ToBigUint64(ctx, &p, argv[0]);
vec4_t axis;
axis.x = 0.0;
axis.y = 0.0;
axis.z = 1.0;
double d;
JS_ToFloat64(ctx, &d, argv[1]);
transform_rotate((void *)p, axis, d);
return JS_UNDEFINED;
}
void plugin_api_init() {
JSValue global_obj = JS_GetGlobalObject(js_ctx);
js_eval(lib);
plugin_gc = any_array_create(0);
gc_root(plugin_gc);
BIND(gc_run, 0);
BIND(data_get_blob, 1);
BIND(data_delete_blob, 1);
BIND(iron_file_save_bytes, 3);
BIND(gpu_create_texture_from_bytes, 4);
BIND(ui_handle_create, 0);
BIND(ui_handle_set_value, 2);
BIND(ui_handle_get_value, 1);
BIND(ui_panel, 2);
BIND(ui_button, 1);
BIND(ui_text, 1);
BIND(ui_text_input, 2);
BIND(ui_slider, 5);
BIND(ui_check, 2);
BIND(ui_radio, 3);
BIND(ui_row, 1);
BIND(ui_combo, 3);
BIND(plugin_api_make_raw_mesh, 5);
BIND(transform_rotate, 3);
plugin_embed();
JS_FreeValue(js_ctx, global_obj);
}
-81
View File
@@ -1,81 +0,0 @@
#pragma once
#include "quickjs-libc.h"
#include "quickjs.h"
#include <stdbool.h>
#include <string.h>
extern JSRuntime *js_runtime;
extern JSContext *js_ctx;
float js_eval(const char *s);
char *js_call(void *p);
JSValue js_call_arg(void *p, int argc, void *argv);
// ██████╗ ███████╗███████╗██╗███╗ ██╗███████╗███████╗
// ██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝██╔════╝
// ██║ ██║█████╗ █████╗ ██║██╔██╗ ██║█████╗ ███████╗
// ██║ ██║██╔══╝ ██╔══╝ ██║██║╚██╗██║██╔══╝ ╚════██║
// ██████╔╝███████╗██║ ██║██║ ╚████║███████╗███████║
// ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝╚══════╝
#define FN(name) static JSValue js_##name(JSContext *ctx, JSValue this_val, int argc, JSValue *argv)
#define VOID_FN(name) \
void name(); \
FN(name) { \
name(); \
return JS_UNDEFINED; \
}
#define PTR_FN(name) \
void *name(); \
FN(name) { \
uint64_t result = (uint64_t)name(); \
return JS_NewBigUint64(ctx, result); \
}
#define VOID_FN_STR(name) \
void name(char *s); \
FN(name) { \
char *s = (char *)JS_ToCString(ctx, argv[0]); \
name(s); \
return JS_UNDEFINED; \
}
#define VOID_FN_PTR_STR(name) \
void name(void *p, char *s); \
FN(name) { \
uint64_t p; \
JS_ToBigUint64(ctx, &p, argv[0]); \
char *s = (char *)JS_ToCString(ctx, argv[1]); \
name((void *)p, s); \
return JS_UNDEFINED; \
}
#define VOID_FN_CB(name) \
void name(void *p); \
FN(name) { \
JSValue dup = JS_DupValue(ctx, argv[0]); \
if (JS_IsNull(dup)) { \
name(NULL); \
return JS_UNDEFINED; \
} \
JSValue *p = malloc(sizeof(JSValue)); \
memcpy(p, &dup, sizeof(JSValue)); \
name(p); \
return JS_UNDEFINED; \
}
#define VOID_FN_PTR_CB(name) \
void name(void *p0, void *p1); \
FN(name) { \
uint64_t p0; \
JS_ToBigUint64(ctx, &p0, argv[0]); \
JSValue *p1 = malloc(sizeof(JSValue)); \
JSValue dup = JS_DupValue(ctx, argv[1]); \
memcpy(p1, &dup, sizeof(JSValue)); \
name((void *)p0, p1); \
return JS_UNDEFINED; \
}
#define BIND(name, argc) JS_SetPropertyStr(js_ctx, global_obj, #name, JS_NewCFunction(js_ctx, js_##name, #name, argc))
+36
View File
@@ -0,0 +1,36 @@
#include "global.h"
void *plugin;
ui_handle_t *h1;
ui_handle_t *h2;
float timer = 0.0;
void on_ui() {
if (ui_panel(h1, "Auto Save")) {
ui_slider(h2, "min", 1, 15, false, 1, true, UI_ALIGN_LEFT, true);
}
}
void on_update() {
if (string_equals(project_filepath_get(), "")) {
return;
}
timer += sys_real_delta();
if (timer >= h2->f * 60.0) {
timer = 0.0;
project_save(false);
}
}
void main() {
plugin = plugin_create();
h1 = ui_handle_create();
h2 = ui_handle_create();
h2->f = 5.0;
gc_root(plugin);
gc_root(h1);
gc_root(h2);
plugin_notify_on_ui(plugin, on_ui);
plugin_notify_on_update(plugin, on_update);
}
-24
View File
@@ -1,24 +0,0 @@
let plugin = plugin_create();
let h1 = ui_handle_create();
let h2 = ui_handle_create();
ui_handle_set_value(h2, 5.0);
let timer = 0.0;
plugin_notify_on_ui(plugin, function() {
if (ui_panel(h1, "Auto Save")) {
ui_slider(h2, "min", 1, 15, false, 1);
}
});
plugin_notify_on_update(plugin, function() {
if (project_filepath_get() == "") {
return;
}
timer += 1 / 60;
if (timer >= ui_handle_get_value(h2) * 60) {
timer = 0.0;
project_save();
}
});
+50
View File
@@ -0,0 +1,50 @@
#include "global.h"
void *plugin;
ui_handle_t *h1;
void on_arm_to_json(char *path) {
buffer_t *b = data_get_blob(path);
any_map_t *parsed = armpack_decode_to_map(b);
json_encode_begin();
json_encode_map(parsed);
char *s = json_encode_end();
buffer_t *out = sys_string_to_buffer(s);
char *p = substring(path, 0, string_length(path) - 3);
p = string("%sjson", p);
iron_file_save_bytes(p, out, 0);
}
void on_json_to_arm(char *path) {
buffer_t *b = data_get_blob(path);
// void *parsed = json_parse(sys_buffer_to_string(b));
// let out = armpack_encode(parsed);
char *p = substring(path, 0, string_length(path) - 4);
p = string("%sarm", p);
// iron_file_save_bytes(p, out, 0);
}
void on_ui() {
if (ui_panel(h1, "Converter", false, false, false)) {
ui_row2();
if (ui_button(".arm to .json", UI_ALIGN_CENTER, "")) {
ui_files_show2("arm", false, true, on_arm_to_json);
}
if (ui_button(".json to .arm", UI_ALIGN_CENTER, "")) {
ui_files_show2("json", false, true, on_json_to_arm);
}
}
};
void main() {
plugin = plugin_create();
h1 = ui_handle_create();
gc_root(plugin);
gc_root(h1);
plugin_notify_on_ui(plugin, on_ui);
}
-25
View File
@@ -1,25 +0,0 @@
let plugin = plugin_create();
let h1 = ui_handle_create();
plugin_notify_on_ui(plugin, function() {
if (ui_panel(h1, "Converter")) {
ui_row([1 / 2, 1 / 2]);
if (ui_button(".arm to .json")) {
ui_files_show("arm", false, true, function(path) {
let b = data_get_blob(path);
let parsed = armpack_decode(b);
let out = string_to_buffer(JSON.stringify(parsed, null, " "));
iron_file_save_bytes(path.substr(0, path.length - 3) + "json", out);
});
}
if (ui_button(".json to .arm")) {
ui_files_show("json", false, true, function(path) {
let b = data_get_blob(path);
let parsed = JSON.parse(buffer_to_string(b));
let out = armpack_encode(parsed);
iron_file_save_bytes(path.substr(0, path.length - 4) + "arm", out);
});
}
}
});
-24
View File
@@ -1,24 +0,0 @@
function export_gpl(path, name, swatches) {
let o = "";
o += "GIMP Palette\\n";
o += "Name: " + name + "\\n";
o += "# armorpaint.org\\n";
o += "#\\n";
for (let i = 0; i < swatches.length; ++i) {
let swatch = swatches[i];
let rb = color_get_rb(swatch.base);
let gb = color_get_gb(swatch.base);
let bb = color_get_bb(swatch.base);
o += rb + " " + gb + " " + bb + "\\n";
}
iron_file_save_bytes(path, sys_string_to_buffer(o), o.length);
}
let plugin = plugin_create();
// path_swatch_exporters_set("gpl", export_gpl);
plugin_notify_on_delete(plugin, function() {
// path_swatch_exporters_delete("gpl");
});
+106
View File
@@ -0,0 +1,106 @@
#include "global.h"
void *plugin;
char *category_name = "My Nodes";
char *node_name = "Hello World";
char *node_type = "HELLO_WORLD";
char *custom_node(ui_node_t *node, char *socket_name) {
void *kong = plugin_material_kong_get();
any_array_t *ar = node->inputs;
ui_node_socket_t *soc = ar->buffer[0];
// ui_node_socket_t *soc = node->inputs->buffer[0];
char *scale = parser_material_parse_value_input(soc, false);
// char *scale = parser_material_parse_value_input(node->inputs->buffer[0], false);
char *my_out = "my_out";
node_shader_write_frag(kong,
string("var %s: float = cos(sin(tex_coord.x * 200.0 * %s) + cos(tex_coord.y * 200.0 * %s));", my_out, scale, scale)
);
if (string_equals(socket_name, "Color")) {
return string("float3(%s, %s, %s)", my_out, my_out, my_out);
}
else if (string_equals(socket_name, "Factor")) {
return my_out;
}
}
void on_delete() {
plugin_material_custom_nodes_remove(node_type);
plugin_material_category_remove(category_name);
}
void main() {
plugin = plugin_create();
gc_root(plugin);
// Create new node category
any_array_t *node_list = any_array_create(0);
// ui_node_t *n = gc_alloc(sizeof(ui_node_t));
ui_node_t *n = gc_alloc(72);
any_array_push(node_list, n);
n->id = 0;
n->name = node_name;
n->type = node_type;
n->x = 0;
n->y = 0;
n->color = 0xffb34f5a;
n->inputs = any_array_create(0);
// ui_node_socket_t *s = gc_alloc(sizeof(ui_node_socket_t));
ui_node_socket_t *s = gc_alloc(56);
any_array_push(n->inputs, s);
s->id = 0;
s->node_id = 0;
s->name = "Scale";
s->type = "VALUE";
s->color = 0xffa1a1a1;
s->default_value = f32_array_create_x(1.0);
s->min = 0.0;
s->max = 5.0;
s->precision = 100.0;
s->display = 0;
n->outputs = any_array_create(0);
// s = gc_alloc(sizeof(ui_node_socket_t));
s = gc_alloc(56);
any_array_push(n->outputs, s);
s->id = 0;
s->node_id = 0;
s->name = "Color";
s->type = "RGBA";
s->color = 0xffc7c729;
s->default_value = f32_array_create_xyzw(0.8, 0.8, 0.8, 1.0);
s->min = 0.0;
s->max = 1.0;
s->precision = 100.0;
s->display = 0;
// s = gc_alloc(sizeof(ui_node_socket_t));
s = gc_alloc(56);
any_array_push(n->outputs, s);
s->id = 1;
s->node_id = 0;
s->name = "Factor";
s->type = "VALUE";
s->color = 0xffa1a1a1;
s->default_value = f32_array_create_x(1.0);
s->min = 0.0;
s->max = 1.0;
s->precision = 100.0;
s->display = 0;
n->buttons = any_array_create(0);
n->width = 0;
n->flags = 0;
plugin_material_category_add(category_name, node_list);
// Node shader
plugin_material_custom_nodes_set(node_type, custom_node);
// Cleanup
plugin_notify_on_delete(plugin, on_delete);
}
-87
View File
@@ -1,87 +0,0 @@
let plugin = plugin_create();
let category_name = "My Nodes";
let node_name = "Hello World";
let node_type = "HELLO_WORLD";
// Create new node category
let node_list = [
{
id: 0,
name: node_name,
type: node_type,
x: 0,
y: 0,
color: 0xffb34f5a,
inputs: [
{
id: 0,
node_id: 0,
name: "Scale",
type: "VALUE",
color: 0xffa1a1a1,
default_value__f32: [1.0],
min__f32: 0.0,
max__f32: 5.0,
precision__f32: 100.0,
display: 0
}
],
outputs: [
{
id: 0,
node_id: 0,
name: "Color",
type: "RGBA",
color: 0xffc7c729,
default_value__f32: [0.8, 0.8, 0.8, 1.0],
min__f32: 0.0,
max__f32: 1.0,
precision__f32: 100.0,
display: 0
},
{
id: 1,
node_id: 0,
name: "Factor",
type: "VALUE",
color: 0xffa1a1a1,
default_value__f32: [1.0],
min__f32: 0.0,
max__f32: 1.0,
precision__f32: 100.0,
display: 0
}
],
buttons: [],
width: 0,
flags: 0
}
];
nodes_material_category_add(category_name, armpack_encode(node_list));
// Node shader
parser_material_custom_nodes_set(node_type, function(node, socket_name) {
let kong = parser_material_kong_get();
let scale = parser_material_parse_value_input(node, 0);
let my_out = "my_out";
node_shader_write_frag(kong,
"var " + my_out + ": float = cos(sin(tex_coord.x * 200.0 * " + scale + ") + cos(tex_coord.y * 200.0 * " + scale + "));"
);
if (socket_name == "Color") {
return "float3(" + my_out + ", " + my_out + ", " + my_out + ")";
}
else if (socket_name == "Factor") {
return my_out;
}
});
// Cleanup
plugin_notify_on_delete(plugin, function() {
parser_material_custom_nodes_delete(node_type);
nodes_material_category_remove(category_name);
});
+75
View File
@@ -0,0 +1,75 @@
#include "global.h"
void *plugin;
char *category_name = "My Nodes";
char *node_name = "Hello World";
char *node_type = "HELLO_WORLD";
float custom_node(logic_node_t *node, int from) {
return sin(sys_time() * node->inputs->buffer[0]->get(0));
}
void on_delete() {
plugin_brush_custom_nodes_remove(node_type);
plugin_brush_category_remove(category_name);
}
void main() {
plugin = plugin_create();
gc_root(plugin);
// Create new node category
any_array_t *node_list = any_array_create(0);
// ui_node_t *n = gc_alloc(sizeof(ui_node_t));
ui_node_t *n = gc_alloc(72);
any_array_push(node_list, n);
n->id = 0;
n->name = node_name;
n->type = node_type;
n->x = 0;
n->y = 0;
n->color = 0xffb34f5a;
n->inputs = any_array_create(0);
// ui_node_socket_t *s = gc_alloc(sizeof(ui_node_socket_t));
ui_node_socket_t *s = gc_alloc(56);
any_array_push(n->inputs, s);
s->id = 0;
s->node_id = 0;
s->name = "Scale";
s->type = "VALUE";
s->color = 0xffa1a1a1;
s->default_value = f32_array_create_x(1.0);
s->min = 0.0;
s->max = 5.0;
s->precision = 100.0;
s->display = 0;
n->outputs = any_array_create(0);
// s = gc_alloc(sizeof(ui_node_socket_t));
s = gc_alloc(56);
any_array_push(n->outputs, s);
s->id = 0;
s->node_id = 0;
s->name = "Value";
s->type = "VALUE";
s->color = 0xffc7c729;
s->default_value = f32_array_create_x(1.0);
s->min = 0.0;
s->max = 5.0;
s->precision = 100.0;
s->display = 0;
n->buttons = any_array_create(0);
n->width = 0;
n->flags = 0;
plugin_brush_category_add(category_name, node_list);
// Brush node
plugin_brush_custom_nodes_set(node_type, custom_node);
// Cleanup
plugin_notify_on_delete(plugin, on_delete);
}
-62
View File
@@ -1,62 +0,0 @@
let plugin = plugin_create();
let category_name = "My Nodes";
let node_name = "Hello World";
let node_type = "HELLO_WORLD";
// Create new node category
let node_list = [
{
id: 0,
name: node_name,
type: node_type,
x: 0,
y: 0,
color: 0xffb34f5a,
inputs: [
{
id: 0,
node_id: 0,
name: "Scale",
type: "VALUE",
color: 0xffa1a1a1,
default_value__f32: [1.0],
min__f32: 0.0,
max__f32: 5.0,
precision__f32: 100.0,
display: 0
}
],
outputs: [
{
id: 0,
node_id: 0,
name: "Value",
type: "VALUE",
color: 0xffc7c729,
default_value__f32: [1.0],
min__f32: 0.0,
max__f32: 5.0,
precision__f32: 100.0,
display: 0
}
],
buttons: [],
width: 0,
flags: 0
}
];
nodes_brush_category_add(category_name, armpack_encode(node_list));
// Brush node
parser_logic_custom_nodes_set(node_type, function(node, from) {
return Math.sin(sys_time() * node.inputs[0].get(0));
});
// Cleanup
plugin_notify_on_delete(plugin, function() {
parser_logic_custom_nodes_delete(node_type);
nodes_brush_category_remove(category_name);
});
+62
View File
@@ -0,0 +1,62 @@
#include "global.h"
void *plugin;
ui_handle_t *h0;
ui_handle_t *h1;
ui_handle_t *h2;
ui_handle_t *h3;
ui_handle_t *h4;
ui_handle_t *h5;
ui_handle_t *h6;
void on_ui() {
if (ui_panel(h0, "My Plugin", false, false, false)) {
ui_text("Label", 0, 0);
ui_text_input(h1, "Text Input", UI_ALIGN_LEFT, true, false);
if (ui_button("Button", UI_ALIGN_CENTER, "")) {
console_info("Hello");
}
f32_array_t *row = f32_array_create(2);
row->buffer[0] = 1.0 / 2.0;
row->buffer[1] = 1.0 / 2.0;
ui_row(row);
ui_button("Button A", UI_ALIGN_CENTER, "");
ui_button("Button B", UI_ALIGN_CENTER, "");
string_array_t *items = string_array_create(2);
items->buffer[0] = "Item 1";
items->buffer[1] = "Item 2";
ui_combo(h2, items, "Combo", true, UI_ALIGN_LEFT, true);
ui_row2();
ui_slider(h3, "Slider", 0, 1, true, 100, true, UI_ALIGN_LEFT, true);
ui_slider(h4, "Slider", 0, 1, true, 100, true, UI_ALIGN_LEFT, true);
ui_check(h5, "Check", "");
ui_radio(h6, 0, "Radio 1", "");
ui_radio(h6, 1, "Radio 2", "");
ui_radio(h6, 2, "Radio 3", "");
}
}
void main() {
plugin = plugin_create();
h0 = ui_handle_create();
h1 = ui_handle_create();
h2 = ui_handle_create();
h3 = ui_handle_create();
h4 = ui_handle_create();
h5 = ui_handle_create();
h6 = ui_handle_create();
gc_root(plugin);
gc_root(h0);
gc_root(h1);
gc_root(h2);
gc_root(h3);
gc_root(h4);
gc_root(h5);
gc_root(h6);
plugin_notify_on_ui(plugin, on_ui);
}
-31
View File
@@ -1,31 +0,0 @@
let plugin = plugin_create();
let h0 = ui_handle_create();
let h1 = ui_handle_create();
let h2 = ui_handle_create();
let h3 = ui_handle_create();
let h4 = ui_handle_create();
let h5 = ui_handle_create();
let h6 = ui_handle_create();
plugin_notify_on_ui(plugin, function() {
if (ui_panel(h0, "My Plugin")) {
ui_text("Label");
ui_text_input(h1, "Text Input");
if (ui_button("Button")) {
console_info("Hello");
}
ui_row([1 / 2, 1 / 2]);
ui_button("Button A");
ui_button("Button B");
ui_combo(h2, ["Item 1", "Item 2"], "Combo");
ui_row([1 / 2, 1 / 2]);
ui_slider(h3, "Slider", 0, 1, true);
ui_slider(h4, "Slider", 0, 1, true);
ui_check(h5, "Check");
ui_radio(h6, 0, "Radio 1");
ui_radio(h6, 1, "Radio 2");
ui_radio(h6, 2, "Radio 3");
}
});
-12
View File
@@ -1,12 +0,0 @@
function import_exr(path) {
let b = data_get_blob(path);
data_delete_blob(path);
return io_exr_parse(b);
}
let plugin = plugin_create();
path_texture_importers_set("exr", import_exr);
plugin_notify_on_delete(plugin, function() {
path_texture_importers_delete("exr");
});
-12
View File
@@ -1,12 +0,0 @@
function import_fbx(path) {
let b = data_get_blob(path);
data_delete_blob(path);
return io_fbx_parse(b);
}
let plugin = plugin_create();
path_mesh_importers_set("fbx", import_fbx);
plugin_notify_on_delete(plugin, function() {
path_mesh_importers_delete("fbx");
});
-14
View File
@@ -1,14 +0,0 @@
function import_gltf_glb(path) {
let b = data_get_blob(path);
data_delete_blob(path);
return io_gltf_parse(b, path);
}
let plugin = plugin_create();
path_mesh_importers_set("gltf", import_gltf_glb);
path_mesh_importers_set("glb", import_gltf_glb);
plugin_notify_on_delete(plugin, function() {
path_mesh_importers_delete("gltf");
path_mesh_importers_delete("glb");
});
-47
View File
@@ -1,47 +0,0 @@
function import_gpl(path, replace_existing) {
let b = data_get_blob(path);
// let swatches: TSwatchColor[] = [];
// let str: string = sys_buffer_to_string(b);
// let lines: string[] = string_split(str, "\\n");
// // GIMP's color palette importer: https://gitlab.gnome.org/GNOME/gimp/-/blob/gimp-2-10/app/core/gimppalette-load.c#L39
// if (!starts_with(lines[0], "GIMP Palette")) {
// console_error(tr("Not a valid GIMP color palette"));
// return;
// }
// let delimiter: string = ~/\s+/ig;
// for (let line of lines) {
// if (starts_with(line, "Name:")) continue;
// else if (starts_with(line, "Columns:")) continue;
// else if (starts_with(line, "#")) continue;
// else {
// let tokens: string[] = string_split(delimiter, line);
// if (tokens.length < 3) continue;
// let swatch: TSwatchColor = makeSwatch(Color.fromBytes(tokens[0], tokens[1], tokens[2]));
// array_push(swatches, swatch);
// }
// }
// if (replaceExisting) {
// raw.swatches = [];
// if (swatches.length == 0) { // No swatches contained
// array_push(raw.swatches, makeSwatch());
// }
// }
// if (swatches.length > 0) {
// for (let s of swatches) {
// array_push(raw.swatches, s);
// }
// }
}
let plugin = plugin_create();
// path_swatch_importers_set("gpl", import_gpl);
plugin_notify_on_delete(plugin, function() {
// path_swatch_importers_delete("gpl");
});
+85
View File
@@ -0,0 +1,85 @@
#include "global.h"
void *plugin;
void *import_stl(char *path) {
buffer_t *b = data_get_blob(path);
int pos = 80; // skip header
int faces = buffer_get_i32(b, pos);
pos += 4;
f32_array_t *pos_temp = f32_array_create(faces * 9);
f32_array_t *nor_temp = f32_array_create(faces * 3);
for (int i = 0; i < faces; ++i) {
int i3 = i * 3;
nor_temp->buffer[i3 ] = buffer_get_f32(b, pos); pos += 4;
nor_temp->buffer[i3 + 1] = buffer_get_f32(b, pos); pos += 4;
nor_temp->buffer[i3 + 2] = buffer_get_f32(b, pos); pos += 4;
int i9 = i * 9;
pos_temp->buffer[i9 ] = buffer_get_f32(b, pos); pos += 4;
pos_temp->buffer[i9 + 1] = buffer_get_f32(b, pos); pos += 4;
pos_temp->buffer[i9 + 2] = buffer_get_f32(b, pos); pos += 4;
pos_temp->buffer[i9 + 3] = buffer_get_f32(b, pos); pos += 4;
pos_temp->buffer[i9 + 4] = buffer_get_f32(b, pos); pos += 4;
pos_temp->buffer[i9 + 5] = buffer_get_f32(b, pos); pos += 4;
pos_temp->buffer[i9 + 6] = buffer_get_f32(b, pos); pos += 4;
pos_temp->buffer[i9 + 7] = buffer_get_f32(b, pos); pos += 4;
pos_temp->buffer[i9 + 8] = buffer_get_f32(b, pos); pos += 4;
pos += 2; // skip attribute
}
float scale_pos = 0.0;
for (int i = 0; i < pos_temp->length; ++i) {
float f = pos_temp->buffer[i];
if (f < 0.0) f = -f;
if (scale_pos < f) scale_pos = f;
}
float inv = 32767.0 * (1.0 / scale_pos);
int verts = faces * 3;
i16_array_t *posa = i16_array_create(verts * 4);
i16_array_t *nora = i16_array_create(verts * 2);
u32_array_t *inda = u32_array_create(verts);
for (int i = 0; i < verts; ++i) {
int f = (i / 3) * 3; // face normal base index
// posa->buffer[i * 4 ] = (int)( pos_temp->buffer[i * 3 ] * inv);
// posa->buffer[i * 4 + 1] = (int)(-pos_temp->buffer[i * 3 + 2] * inv);
// posa->buffer[i * 4 + 2] = (int)( pos_temp->buffer[i * 3 + 1] * inv);
// nora->buffer[i * 2 ] = (int)( nor_temp->buffer[f ] * 32767.0);
// nora->buffer[i * 2 + 1] = (int)(-nor_temp->buffer[f + 2] * 32767.0);
// posa->buffer[i * 4 + 3] = (int)( nor_temp->buffer[f + 1] * 32767.0);
buffer_set_i16(posa, (i * 4) * 2, pos_temp->buffer[i * 3 ] * inv);
buffer_set_i16(posa, (i * 4 + 1) * 2, -pos_temp->buffer[i * 3 + 2] * inv);
buffer_set_i16(posa, (i * 4 + 2) * 2, pos_temp->buffer[i * 3 + 1] * inv);
buffer_set_i16(nora, (i * 2) * 2, nor_temp->buffer[f ] * 32767.0);
buffer_set_i16(nora, (i * 2 + 1) * 2, -nor_temp->buffer[f + 2] * 32767.0);
buffer_set_i16(posa, (i * 4 + 3) * 2, nor_temp->buffer[f + 1] * 32767.0);
inda->buffer[i] = i;
}
data_delete_blob(path);
string_array_t *a = string_split(path, "\\\\");
char *s = array_pop(a);
a = string_split(s, "/");
s = array_pop(a);
a = string_split(s, ".");
char *name = a->buffer[0];
return plugin_make_raw_mesh(name, posa, nora, inda, scale_pos);
}
void on_delete() {
plugin_unregister_mesh("stl");
}
void main() {
plugin = plugin_create();
gc_root(plugin);
plugin_notify_on_delete(plugin, on_delete);
plugin_register_mesh("stl", import_stl);
}
-80
View File
@@ -1,80 +0,0 @@
let pos = 0;
function read_i16(view) {
let i = view.getInt16(pos, true);
pos += 2;
return i;
}
function read_i32(view) {
let i = view.getInt32(pos, true);
pos += 4;
return i;
}
function read_f32(view) {
let f = view.getFloat32(pos, true);
pos += 4;
return f;
}
function import_stl(path) {
let b = data_get_blob(path);
let view = new DataView(b);
pos = 0;
pos += 80; // header
let faces = read_i32(view);
let pos_temp = new Float32Array(faces * 9);
let nor_temp = new Float32Array(faces * 3);
for (let i = 0; i < faces; ++i) {
let i3 = i * 3;
nor_temp[i3 ] = read_f32(view);
nor_temp[i3 + 1] = read_f32(view);
nor_temp[i3 + 2] = read_f32(view);
let i9 = i * 9;
pos_temp[i9 ] = read_f32(view);
pos_temp[i9 + 1] = read_f32(view);
pos_temp[i9 + 2] = read_f32(view);
pos_temp[i9 + 3] = read_f32(view);
pos_temp[i9 + 4] = read_f32(view);
pos_temp[i9 + 5] = read_f32(view);
pos_temp[i9 + 6] = read_f32(view);
pos_temp[i9 + 7] = read_f32(view);
pos_temp[i9 + 8] = read_f32(view);
read_i16(view); // attribute
}
let scale_pos = 0.0;
for (let i = 0; i < pos_temp.length; ++i) {
let f = Math.abs(pos_temp[i]);
if (scale_pos < f) {
scale_pos = f;
}
}
let inv = 32767 * (1 / scale_pos);
let verts = pos_temp.length / 3;
let posa = new Int16Array(verts * 4);
let nora = new Int16Array(verts * 2);
let inda = new Uint32Array(verts);
for (let i = 0; i < verts; ++i) {
posa[i * 4 ] = pos_temp[i * 3 ] * inv;
posa[i * 4 + 1] = -pos_temp[i * 3 + 2] * inv;
posa[i * 4 + 2] = pos_temp[i * 3 + 1] * inv;
nora[i * 2 ] = nor_temp[i ] * 32767;
nora[i * 2 + 1] = -nor_temp[i + 2] * 32767;
posa[i * 4 + 3] = nor_temp[i + 1] * 32767;
inda[i] = i;
}
data_delete_blob(path);
let name = path.split("\\\\").pop().split("/").pop().split(".").shift();
return plugin_api_make_raw_mesh(name, posa.buffer, nora.buffer, inda.buffer, scale_pos);
}
let plugin = plugin_create();
path_mesh_importers_set("stl", import_stl);
plugin_notify_on_delete(plugin, function() {
path_mesh_importers_delete("stl");
});
-12
View File
@@ -1,12 +0,0 @@
function import_svg(path) {
let b = data_get_blob(path);
data_delete_blob(path);
return io_svg_parse(b);
}
let plugin = plugin_create();
path_texture_importers_set("svg", import_svg);
plugin_notify_on_delete(plugin, function() {
path_texture_importers_delete("svg");
});
+28
View File
@@ -0,0 +1,28 @@
#include "global.h"
void *plugin;
void *import_txt(char *path) {
void *b = data_get_blob(path);
string_array_t *a = string_split(path, "\\\\");
char *s = array_pop(a);
a = string_split(s, "/");
s = array_pop(a);
char *filename = s;
ui_box_show_message(filename, sys_buffer_to_string(b), true);
data_delete_blob(path);
return NULL;
}
void on_delete() {
plugin_unregister_texture("txt", import_txt);
}
void main() {
plugin = plugin_create();
gc_root(plugin);
plugin_notify_on_delete(plugin, on_delete);
plugin_register_texture("txt", import_txt);
}
-13
View File
@@ -1,13 +0,0 @@
function import_txt(path) {
let b = data_get_blob(path);
let filename = path.split("\\\\").pop().split("/").pop();
ui_box_show_message(filename, buffer_to_string(b));
data_delete_blob(path);
}
let plugin = plugin_create();
path_texture_importers_set("txt", import_txt);
plugin_notify_on_delete(plugin, function() {
path_texture_importers_delete("txt");
});
-20
View File
@@ -1,20 +0,0 @@
let plugin = plugin_create();
function unwrap_mesh(mesh) {
proc_uv_unwrap(mesh);
}
let h1 = ui_handle_create();
plugin_notify_on_ui(plugin, function() {
if (ui_panel(h1, "UV Unwrap")) {
if (ui_button("Unwrap Mesh")) {
plugin_uv_unwrap_button();
}
}
});
util_mesh_unwrappers_set("uv_unwrap.js", unwrap_mesh);
plugin_notify_on_delete(plugin, function() {
util_mesh_unwrappers_delete("uv_unwrap.js");
});
+24
View File
@@ -0,0 +1,24 @@
#include "global.h"
void *plugin;
// Register custom viewport shader
void viewport_shader(void *shader) {
node_shader_write_frag(shader, " \
var light_dir: float3 = float3(0.5, 0.5, -0.5);\
var dotnl: float = max(dot(n, light_dir), 0.0); \
output_color = basecol * step(0.5, dotnl) + basecol; \
");
};
void on_delete() {
context_set_viewport_shader(NULL);
}
void main() {
plugin = plugin_create();
gc_root(plugin);
context_set_viewport_shader(viewport_shader);
plugin_notify_on_delete(plugin, on_delete);
}
-16
View File
@@ -1,16 +0,0 @@
let plugin = plugin_create();
// Register custom viewport shader
context_set_viewport_shader(function(shader) {
// node_shader_add_constant(shader, "light_dir: float3", "_light_dir");
node_shader_write_frag(shader, " \
var light_dir: float3 = float3(0.5, 0.5, -0.5);\
var dotnl: float = max(dot(n, light_dir), 0.0); \
output_color = basecol * step(0.5, dotnl) + basecol; \
");
});
plugin_notify_on_delete(plugin, function() {
context_set_viewport_shader(null);
});
+57 -285
View File
@@ -1,304 +1,76 @@
#include "../../../base/sources/plugins/plugin_api.h"
#ifdef WITH_PLUGINS
#include "iron_array.h"
#include "iron_map.h"
#include "iron_ui.h"
void proc_uv_unwrap(void *mesh);
FN(proc_uv_unwrap) {
uint64_t mesh;
JS_ToBigUint64(ctx, &mesh, argv[0]);
proc_uv_unwrap((void *)mesh);
return JS_UNDEFINED;
}
void plugin_uv_unwrap_button();
FN(plugin_uv_unwrap_button) {
plugin_uv_unwrap_button();
return JS_UNDEFINED;
}
#include "engine.h"
void *io_svg_parse(char *buf);
FN(io_svg_parse) {
size_t len;
void *ab = JS_GetArrayBuffer(ctx, &len, argv[0]);
return JS_NewBigUint64(ctx, (uint64_t)io_svg_parse(ab));
}
void *io_exr_parse(char *buf, size_t len);
FN(io_exr_parse) {
size_t len;
void *ab = JS_GetArrayBuffer(ctx, &len, argv[0]);
return JS_NewBigUint64(ctx, (uint64_t)io_exr_parse(ab, len));
}
void *io_tiff_parse(uint8_t *buf, size_t len);
void *io_gltf_parse(char *buf, size_t size, const char *path);
FN(io_gltf_parse) {
size_t len;
void *ab = JS_GetArrayBuffer(ctx, &len, argv[0]);
const char *path = JS_ToCString(ctx, argv[1]);
return JS_NewBigUint64(ctx, (uint64_t)io_gltf_parse(ab, len, path));
}
void *io_fbx_parse(char *buf, size_t size);
FN(io_fbx_parse) {
size_t len;
void *ab = JS_GetArrayBuffer(ctx, &len, argv[0]);
return JS_NewBigUint64(ctx, (uint64_t)io_fbx_parse(ab, len));
}
VOID_FN_STR(console_log)
VOID_FN_STR(console_info)
PTR_FN(plugin_create)
VOID_FN_PTR_CB(plugin_notify_on_ui)
VOID_FN_PTR_CB(plugin_notify_on_update)
VOID_FN_PTR_CB(plugin_notify_on_delete)
static JSObject *ui_files_cb;
static void ui_files_done(char *path) {
JSValue path_val = JS_NewString(js_ctx, path);
JSValue argv[] = {path_val};
js_call_arg(ui_files_cb, 1, argv);
}
void ui_files_show(char *s, bool b0, bool b1, void (*f)(char *));
FN(ui_files_show) {
char *filters = (char *)JS_ToCString(ctx, argv[0]);
bool is_save = JS_ToBool(ctx, argv[1]);
bool open_multiple = JS_ToBool(ctx, argv[2]);
ui_files_cb = malloc(sizeof(JSValue));
JSValue dup = JS_DupValue(ctx, argv[3]);
memcpy(ui_files_cb, &dup, sizeof(JSValue));
ui_files_show(filters, is_save, open_multiple, ui_files_done);
return JS_UNDEFINED;
}
void ui_box_show_message(char *s0, char *s1, bool b);
extern bool ui_box_click_to_hide;
FN(ui_box_show_message) {
char *title = (char *)JS_ToCString(ctx, argv[0]);
char *message = (char *)JS_ToCString(ctx, argv[1]);
ui_box_show_message(title, message, true);
ui_box_click_to_hide = false;
return JS_UNDEFINED;
}
VOID_FN_CB(context_set_viewport_shader)
void node_shader_add_constant(void *p, char *s0, char *s1, bool b);
FN(node_shader_add_constant) {
uint64_t p;
JS_ToBigUint64(ctx, &p, argv[0]);
char *s0 = (char *)JS_ToCString(ctx, argv[1]);
char *s1 = (char *)JS_ToCString(ctx, argv[2]);
node_shader_add_constant((void *)p, s0, s1, false);
return JS_UNDEFINED;
}
VOID_FN_PTR_STR(node_shader_write_frag)
extern char *project_filepath;
FN(project_filepath_get) {
return JS_NewString(ctx, project_filepath);
}
void project_save(bool b);
FN(project_save) {
project_save(false);
return JS_UNDEFINED;
}
extern any_array_t *nodes_material_categories;
extern any_array_t *nodes_material_list;
FN(nodes_material_category_add) {
char *category_name = (char *)JS_ToCString(ctx, argv[0]);
any_array_push(nodes_material_categories, category_name);
size_t len;
void *ab = JS_GetArrayBuffer(ctx, &len, argv[1]);
buffer_t b = {.buffer = ab, .length = len, .capacity = len};
any_array_push(nodes_material_list, armpack_decode(&b));
return JS_UNDEFINED;
}
FN(nodes_material_category_remove) {
char *category_name = (char *)JS_ToCString(ctx, argv[0]);
int i = array_index_of(nodes_material_categories, category_name);
array_splice(nodes_material_list, i, 1);
array_splice(nodes_material_categories, i, 1);
return JS_UNDEFINED;
}
extern any_map_t *parser_material_custom_nodes;
FN(parser_material_custom_nodes_set) {
char *node_type = (char *)JS_ToCString(ctx, argv[0]);
JSValue *p = malloc(sizeof(JSValue));
JSValue dup = JS_DupValue(ctx, argv[1]);
memcpy(p, &dup, sizeof(JSValue));
any_map_set(parser_material_custom_nodes, node_type, p);
return JS_UNDEFINED;
}
FN(parser_material_custom_nodes_delete) {
char *node_type = (char *)JS_ToCString(ctx, argv[0]);
map_delete(parser_material_custom_nodes, node_type);
return JS_UNDEFINED;
}
extern void *parser_material_kong;
FN(parser_material_kong_get) {
return JS_NewBigUint64(ctx, (uint64_t)parser_material_kong);
}
char *parser_material_parse_value_input(void *inp, bool vector_as_grayscale);
FN(parser_material_parse_value_input) {
uint64_t *node;
JS_ToBigUint64(ctx, &node, argv[0]);
int64_t i;
JS_ToInt64(ctx, &i, argv[1]);
char *s = parser_material_parse_value_input(((ui_node_t *)node)->inputs->buffer[i], false);
return JS_NewString(ctx, s);
}
extern any_array_t *nodes_brush_categories;
extern any_array_t *nodes_brush_list;
void nodes_brush_list_init();
FN(nodes_brush_category_add) {
char *category_name = (char *)JS_ToCString(ctx, argv[0]);
any_array_push(nodes_brush_categories, category_name);
size_t len;
void *ab = JS_GetArrayBuffer(ctx, &len, argv[1]);
buffer_t b = {.buffer = ab, .length = len, .capacity = len};
nodes_brush_list_init();
any_array_push(nodes_brush_list, armpack_decode(&b));
return JS_UNDEFINED;
}
FN(nodes_brush_category_remove) {
char *category_name = (char *)JS_ToCString(ctx, argv[0]);
int i = array_index_of(nodes_brush_categories, category_name);
array_splice(nodes_brush_list, i, 1);
array_splice(nodes_brush_categories, i, 1);
return JS_UNDEFINED;
}
extern any_map_t *parser_logic_custom_nodes;
FN(parser_logic_custom_nodes_set) {
char *node_type = (char *)JS_ToCString(ctx, argv[0]);
JSValue *p = malloc(sizeof(JSValue));
JSValue dup = JS_DupValue(ctx, argv[1]);
memcpy(p, &dup, sizeof(JSValue));
any_map_set(parser_logic_custom_nodes, node_type, p);
return JS_UNDEFINED;
}
FN(parser_logic_custom_nodes_delete) {
char *node_type = (char *)JS_ToCString(ctx, argv[0]);
map_delete(parser_logic_custom_nodes, node_type);
return JS_UNDEFINED;
}
extern any_map_t *util_mesh_unwrappers;
FN(util_mesh_unwrappers_set) {
char *plugin_name = (char *)JS_ToCString(ctx, argv[0]);
JSValue *p = malloc(sizeof(JSValue));
JSValue dup = JS_DupValue(ctx, argv[1]);
memcpy(p, &dup, sizeof(JSValue));
any_map_set(util_mesh_unwrappers, plugin_name, p);
return JS_UNDEFINED;
}
FN(util_mesh_unwrappers_delete) {
char *plugin_name = (char *)JS_ToCString(ctx, argv[0]);
map_delete(util_mesh_unwrappers, plugin_name);
return JS_UNDEFINED;
}
void proc_uv_unwrap(void *mesh);
extern any_map_t *import_mesh_importers;
extern string_array_t *_path_mesh_formats;
string_array_t *path_mesh_formats(void);
FN(path_mesh_importers_set) {
char *format_name = (char *)JS_ToCString(ctx, argv[0]);
JSValue *p = malloc(sizeof(JSValue));
JSValue dup = JS_DupValue(ctx, argv[1]);
memcpy(p, &dup, sizeof(JSValue));
any_map_set(import_mesh_importers, format_name, p);
path_mesh_formats(); // Init array
any_array_push(_path_mesh_formats, format_name);
return JS_UNDEFINED;
}
FN(path_mesh_importers_delete) {
char *format_name = (char *)JS_ToCString(ctx, argv[0]);
map_delete(import_mesh_importers, format_name);
path_mesh_formats(); // Init array
array_splice(_path_mesh_formats, string_array_index_of(_path_mesh_formats, format_name), 1);
return JS_UNDEFINED;
}
extern any_map_t *import_texture_importers;
extern string_array_t *_path_texture_formats;
string_array_t *path_texture_formats(void);
FN(path_texture_importers_set) {
char *format_name = (char *)JS_ToCString(ctx, argv[0]);
JSValue *p = malloc(sizeof(JSValue));
JSValue dup = JS_DupValue(ctx, argv[1]);
memcpy(p, &dup, sizeof(JSValue));
any_map_set(import_texture_importers, format_name, p);
extern any_map_t *util_mesh_unwrappers;
static void *import_exr(char *path) {
buffer_t *b = data_get_blob(path);
data_delete_blob(path);
return io_exr_parse((char *)b->buffer, b->length);
}
static void *import_tiff(char *path) {
buffer_t *b = data_get_blob(path);
data_delete_blob(path);
return io_tiff_parse((uint8_t *)b->buffer, b->length);
}
static void *import_svg(char *path) {
buffer_t *b = data_get_blob(path);
data_delete_blob(path);
return io_svg_parse((char *)b->buffer);
}
static void *import_gltf_glb(char *path) {
buffer_t *b = data_get_blob(path);
data_delete_blob(path);
return io_gltf_parse((char *)b->buffer, b->length, path);
}
static void *import_fbx(char *path) {
buffer_t *b = data_get_blob(path);
data_delete_blob(path);
return io_fbx_parse((char *)b->buffer, b->length);
}
void plugins_init() {
path_texture_formats(); // Init array
any_array_push(_path_texture_formats, format_name);
return JS_UNDEFINED;
any_map_set(import_texture_importers, "exr", import_exr);
any_array_push(_path_texture_formats, "exr");
any_map_set(import_texture_importers, "svg", import_svg);
any_array_push(_path_texture_formats, "svg");
any_map_set(import_texture_importers, "tiff", import_tiff);
any_array_push(_path_texture_formats, "tiff");
any_map_set(import_texture_importers, "tif", import_tiff);
any_array_push(_path_texture_formats, "tif");
path_mesh_formats(); // Init array
any_map_set(import_mesh_importers, "gltf", import_gltf_glb);
any_array_push(_path_mesh_formats, "gltf");
any_map_set(import_mesh_importers, "glb", import_gltf_glb);
any_array_push(_path_mesh_formats, "glb");
any_map_set(import_mesh_importers, "fbx", import_fbx);
any_array_push(_path_mesh_formats, "fbx");
any_map_set(util_mesh_unwrappers, "uv_unwrap", proc_uv_unwrap);
}
FN(path_texture_importers_delete) {
char *format_name = (char *)JS_ToCString(ctx, argv[0]);
map_delete(import_texture_importers, format_name);
path_texture_formats(); // Init array
array_splice(_path_texture_formats, string_array_index_of(_path_texture_formats, format_name), 1);
return JS_UNDEFINED;
}
void plugin_embed() {
JSValue global_obj = JS_GetGlobalObject(js_ctx);
BIND(proc_uv_unwrap, 1);
BIND(plugin_uv_unwrap_button, 0);
BIND(io_svg_parse, 1);
BIND(io_exr_parse, 1);
BIND(io_gltf_parse, 2);
BIND(io_fbx_parse, 1);
BIND(console_log, 1);
BIND(console_info, 1);
BIND(plugin_create, 0);
BIND(plugin_notify_on_ui, 2);
BIND(plugin_notify_on_update, 2);
BIND(plugin_notify_on_delete, 2);
BIND(ui_files_show, 4);
BIND(ui_box_show_message, 2);
BIND(context_set_viewport_shader, 1);
BIND(node_shader_add_constant, 3);
BIND(node_shader_write_frag, 2);
BIND(project_filepath_get, 0);
BIND(project_save, 0);
BIND(nodes_material_category_add, 2);
BIND(nodes_material_category_remove, 1);
BIND(parser_material_custom_nodes_set, 2);
BIND(parser_material_custom_nodes_delete, 1);
BIND(parser_material_kong_get, 0);
BIND(parser_material_parse_value_input, 2);
BIND(nodes_brush_category_add, 2);
BIND(nodes_brush_category_remove, 1);
BIND(parser_logic_custom_nodes_set, 2);
BIND(parser_logic_custom_nodes_delete, 1);
BIND(util_mesh_unwrappers_set, 2);
BIND(util_mesh_unwrappers_delete, 1);
BIND(path_mesh_importers_set, 2);
BIND(path_mesh_importers_delete, 1);
BIND(path_texture_importers_set, 2);
BIND(path_texture_importers_delete, 1);
JS_FreeValue(js_ctx, global_obj);
}
#endif
+1
View File
@@ -6,5 +6,6 @@ project.add_cfiles("io_svg/**");
project.add_cfiles("io_exr/**");
project.add_cfiles("io_gltf/**");
project.add_cfiles("io_fbx/**");
project.add_cfiles("io_tiff/**");
return project;
+1 -1
View File
@@ -942,7 +942,7 @@ void ui_base_update(void *_) {
for (i32 i = 0; i < keys->length; ++i) {
plugin_t *p = any_map_get(plugin_map, keys->buffer[i]);
if (p->on_update != NULL) {
js_call(p->on_update);
minic_ctx_call_fn(p->ctx, p->on_update, NULL, 0);
}
}
+9 -9
View File
@@ -829,9 +829,9 @@ void box_preferences_model_panel(neural_node_model_t *m) {
}
void box_preferences_plugins_tab_plugin_menu_export(char *dest) {
if (!ends_with(ui_files_filename, ".js")) {
if (!ends_with(ui_files_filename, ".c")) {
gc_unroot(ui_files_filename);
ui_files_filename = string("%s.js", ui_files_filename);
ui_files_filename = string("%s.c", ui_files_filename);
gc_root(ui_files_filename);
}
char *path = string("%s%splugins%s%s", path_data(), PATH_SEP, PATH_SEP, _box_preferences_f);
@@ -850,7 +850,7 @@ void box_preferences_plugins_tab_plugin_menu() {
console_info(tr("Script opened"));
}
if (ui_menu_button(tr("Export"), "", ICON_EXPORT)) {
ui_files_show("js", true, false, &box_preferences_plugins_tab_plugin_menu_export);
ui_files_show("c", true, false, &box_preferences_plugins_tab_plugin_menu_export);
}
if (ui_menu_button(tr("Delete"), "", ICON_DELETE)) {
if (string_array_index_of(config_raw->plugins, _box_preferences_f) >= 0) {
@@ -884,8 +884,8 @@ plugin_notify_on_ui(plugin, function() {\
}\
});\
";
if (!ends_with(plugin_name, ".js")) {
plugin_name = string("%s.js", plugin_name);
if (!ends_with(plugin_name, ".c")) {
plugin_name = string("%s.c", plugin_name);
}
char *path = string("%s%splugins%s%s", path_data(), PATH_SEP, PATH_SEP, plugin_name);
iron_file_save_bytes(path, sys_string_to_buffer(template), 0);
@@ -910,7 +910,7 @@ void box_preferences_plugins_tab() {
ui_box_show_custom(&box_preferences_plugins_tab_new_box, 400, 200, NULL, true, tr("New Plugin"));
}
if (ui_icon_button(tr("Import"), ICON_IMPORT, UI_ALIGN_CENTER)) {
ui_files_show("js,zip", false, false, &box_preferences_plugins_tab_import);
ui_files_show("c,zip", false, false, &box_preferences_plugins_tab_import);
}
ui_end_sticky();
@@ -927,13 +927,13 @@ void box_preferences_plugins_tab() {
}
for (i32 i = 0; i < box_preferences_files_plugin->length; ++i) {
char *f = box_preferences_files_plugin->buffer[i];
bool is_js = ends_with(f, ".js");
if (!is_js) {
bool is_c = ends_with(f, ".c");
if (!is_c) {
continue;
}
bool enabled = string_array_index_of(config_raw->plugins, f) >= 0;
h->b = enabled;
char *tag = is_js ? string_split(f, ".")->buffer[0] : f;
char *tag = is_c ? string_split(f, ".")->buffer[0] : f;
ui_check(h, tag, "");
if (h->changed && h->b != enabled) {
h->b ? config_enable_plugin(f) : config_disable_plugin(f);
+8 -4
View File
@@ -482,13 +482,17 @@ void config_load_theme(char *theme, bool tag_redraw) {
}
void config_enable_plugin(char *f) {
any_array_push(config_raw->plugins, f);
plugin_start(f);
if (string_array_index_of(config_raw->plugins, f) == -1) {
any_array_push(config_raw->plugins, f);
plugin_start(f);
}
}
void config_disable_plugin(char *f) {
string_array_remove(config_raw->plugins, f);
plugin_stop(f);
if (string_array_index_of(config_raw->plugins, f) > -1) {
string_array_remove(config_raw->plugins, f);
plugin_stop(f);
}
}
#ifdef IRON_IOS
+4 -8
View File
@@ -21,7 +21,7 @@ void console_toast(char *s) {
bool in_use = gpu_in_use;
if (in_use)
draw_end();
console_trace(s);
console_log(s);
console_draw_toast(s);
if (in_use)
draw_begin(current, false, 0);
@@ -40,7 +40,7 @@ void console_progress(char *s) {
sys_notify_on_render(console_draw_progress, NULL);
}
if (s != NULL) {
console_trace(s);
console_log(s);
}
gc_unroot(console_progress_text);
console_progress_text = string_copy(s);
@@ -61,7 +61,7 @@ void console_info(char *s) {
gc_root(console_message);
console_message_color = 0x00000000;
base_redraw_status();
console_trace(s);
console_log(s);
}
void console_error(char *s) {
@@ -71,14 +71,10 @@ void console_error(char *s) {
gc_root(console_message);
console_message_color = 0xffaa0000;
base_redraw_status();
console_trace(s);
console_log(s);
}
void console_log(char *s) {
console_trace(s);
}
void console_trace(char *s) {
iron_log(s);
base_redraw_console();
string_array_push(console_last_traces, string_copy(s));
+1 -1
View File
@@ -492,7 +492,7 @@ void context_update_envmap() {
}
}
void context_set_viewport_shader(void *viewport_shader) { // JSValue * -> (ns: node_shader_t)=>void
void context_set_viewport_shader(void *viewport_shader) {
context_raw->viewport_shader = viewport_shader;
context_set_render_path();
}
-1
View File
@@ -756,7 +756,6 @@ void console_progress(char *s);
void console_info(char *s);
void console_error(char *s);
void console_log(char *s);
void console_trace(char *s);
void export_mesh_run(char *path, mesh_object_t_array_t *paint_objects, bool apply_disp, bool merge_vertices);
void export_player_run(char *path);
void camera_init();
+4 -4
View File
@@ -107,7 +107,7 @@ i32 pipes_cursor_tint;
i32 pipes_cursor_gbufferd;
i32 pipes_offset;
char *_import_blend_material_path;
any_map_t *import_texture_importers; // JSValue -> (s: string)=>gpu_texture_t
any_map_t *import_texture_importers;
#ifdef IRON_WINDOWS
char *ui_files_default_path = "C:\\Users";
@@ -211,7 +211,7 @@ ui_handle_t *tab_scripts_hscript;
ui_text_coloring_t *tab_scripts_text_coloring = NULL;
bool import_mesh_clear_layers = true;
any_array_t *import_mesh_meshes_to_unwrap = NULL;
any_map_t *import_mesh_importers; // JSValue -> (s: string)=>raw_mesh_t
any_map_t *import_mesh_importers;
i32 ui_menubar_default_w = 406;
ui_handle_t *ui_menubar_hwnd;
ui_handle_t *ui_menubar_menu_handle;
@@ -343,7 +343,7 @@ char *parser_material_tex_coord = "tex_coord";
f32 parser_material_eps = 0.000001;
any_map_t *parser_material_node_values;
any_map_t *parser_material_node_vectors;
any_map_t *parser_material_custom_nodes; // JSValue -> (n: ui_node_t, s: string)=>string
any_map_t *parser_material_custom_nodes;
bool parser_material_parse_surface = true;
bool parser_material_parse_opacity = true;
bool parser_material_parse_height = false;
@@ -394,7 +394,7 @@ char *tab_browser_last_path = "";
char *_tab_browser_draw_file;
char *_tab_browser_draw_b;
bool tab_browser_refresh = false;
any_map_t *util_mesh_unwrappers; // JSValue * -> ((a: raw_mesh_t)=>void)
any_map_t *util_mesh_unwrappers;
i16_array_t *util_mesh_va0;
i32_array_t *util_mesh_quantized;
i32 ui_header_default_h = 30;
-3
View File
@@ -69,9 +69,6 @@ void import_asset_run(char *path, f32 drop_x, f32 drop_y, bool show_box, bool hd
else if (path_is_plugin(path)) {
import_plugin_run(path);
}
else if (path_is_gimp_color_palette(path)) {
// import_gpl_run(path, false);
}
else if (path_is_font(path)) {
import_font_run(path);
}
+5 -4
View File
@@ -23,9 +23,10 @@ void import_mesh_run(char *path, bool _clear_layers, bool replace_existing) {
import_blend_mesh_run(path, replace_existing);
}
else {
char *ext = substring(path, string_last_index_of(path, ".") + 1, string_length(path));
void *importer = any_map_get(import_mesh_importers, ext); // JSValue -> (s: string)=>raw_mesh_t
raw_mesh_t *mesh = js_pcall_str(importer, path);
char *ext = substring(path, string_last_index_of(path, ".") + 1, string_length(path));
raw_mesh_t *(*importer)(char *path) = any_map_get(import_mesh_importers, ext);
raw_mesh_t *mesh = importer(path);
if (string_equals(mesh->name, "")) {
mesh->name = string_copy(path_base_name(path));
}
@@ -34,7 +35,7 @@ void import_mesh_run(char *path, bool _clear_layers, bool replace_existing) {
bool has_next = mesh->has_next;
while (has_next) {
raw_mesh_t *mesh = js_pcall_str(importer, path);
raw_mesh_t *mesh = importer(path);
if (string_equals(mesh->name, "")) {
mesh->name = string_copy(path_base_name(path));
}
+5 -4
View File
@@ -28,15 +28,16 @@ void import_texture_run(char *path, bool hdr_as_envmap) {
}
}
char *ext = substring(path, string_last_index_of(path, ".") + 1, string_length(path));
void *importer = any_map_get(import_texture_importers, ext); // JSValue -> (s: string)=>gpu_texture_t
bool cached = any_map_get(data_cached_images, path) != NULL; // Already loaded or pink texture for missing file
char *ext = substring(path, string_last_index_of(path, ".") + 1, string_length(path));
gpu_texture_t *(*importer)(char *path) = any_map_get(import_texture_importers, ext);
bool cached = any_map_get(data_cached_images, path) != NULL; // Already loaded or pink texture for missing file
gpu_texture_t *image;
if (importer == NULL || cached) {
image = import_texture_default_importer(path);
}
else {
image = js_pcall_str(importer, path);
image = importer(path);
}
if (image == NULL) {
+10
View File
@@ -2,6 +2,10 @@
#include "global.h"
#ifdef WITH_PLUGINS
void plugins_init();
#endif
void _kickstart() {
_render_path_cached_shader_contexts = any_map_create();
gc_root(_render_path_cached_shader_contexts);
@@ -218,6 +222,7 @@ void _kickstart() {
util_mesh_unwrappers = any_map_create();
gc_root(util_mesh_unwrappers);
ui_header_h = ui_header_default_h;
ui_header_handle = ui_handle_create();
@@ -5023,6 +5028,11 @@ void _kickstart() {
render_path_commands = render_path_deferred_commands;
gc_root(render_path_commands);
}
#ifdef WITH_PLUGINS
plugins_init();
#endif
base_init();
iron_start();
}
+2 -1
View File
@@ -417,7 +417,8 @@ node_shader_context_t *make_mesh_run(material_t *data, i32 layer_pass) {
if (context_raw->viewport_shader != NULL) {
node_shader_write_frag(kong, "var output_color: float3;");
js_call_ptr(context_raw->viewport_shader, kong);
minic_val_t args[1] = {minic_val_ptr(kong)};
minic_call_fn(context_raw->viewport_shader, args, 1);
node_shader_write_frag(kong, "output[1] = float4(output_color, 1.0);");
}
else if (config_raw->render_mode == RENDER_MODE_FORWARD && context_raw->viewport_mode != VIEWPORT_MODE_PATH_TRACE) {
+5 -3
View File
@@ -392,8 +392,9 @@ char *parser_material_parse_vector(ui_node_t *node, ui_node_socket_t *socket) {
return parser_material_parse_group_input(node, socket);
}
else if (any_map_get(parser_material_custom_nodes, node->type) != NULL) {
void *cb = any_map_get(parser_material_custom_nodes, node->type); // JSValue -> (n: ui_node_t, s: string)=>string
return js_call_ptr_str(cb, node, socket->name);
void *cb = any_map_get(parser_material_custom_nodes, node->type);
minic_val_t args[2] = {minic_val_ptr(node), minic_val_ptr(socket->name)};
return minic_call_fn(cb, args, 2).p;
}
return "float3(0.0, 0.0, 0.0)";
}
@@ -453,7 +454,8 @@ char *parser_material_parse_value(ui_node_t *node, ui_node_socket_t *socket) {
}
else if (any_map_get(parser_material_custom_nodes, node->type) != NULL) {
void *cb = any_map_get(parser_material_custom_nodes, node->type);
return js_call_ptr_str(cb, node, socket->name);
minic_val_t args[2] = {minic_val_ptr(node), minic_val_ptr(socket->name)};
return minic_call_fn(cb, args, 2).p;
}
return "0.0";
}
+1 -1
View File
@@ -24,7 +24,7 @@ void sim_update() {
char *s = any_map_get(sim_object_script_map, o);
char *addr = i64_to_string((i64)(o->transform));
s = string("{let transform=%s;%s}", addr, s);
js_eval(s);
// minic_eval(s);
}
physics_world_t *world = physics_world_active;
+7 -2
View File
@@ -13,15 +13,20 @@ void plugin_start(char *plugin) {
gc_unroot(_plugin_name);
_plugin_name = string_copy(plugin);
gc_root(_plugin_name);
js_eval(string("(1, eval)(`%s`)", sys_buffer_to_string(blob)));
minic_ctx_t *ctx = minic_eval(sys_buffer_to_string(blob));
data_delete_blob(string("plugins/%s", plugin));
// Store context on the plugin so callbacks can use it and it can be freed on stop
plugin_t *p = any_map_get(plugin_map, plugin);
p->ctx = ctx;
}
void plugin_stop(char *plugin) {
plugin_t *p = any_map_get(plugin_map, plugin);
if (p->on_delete != NULL) {
js_call(p->on_delete);
minic_ctx_call_fn(p->ctx, p->on_delete, NULL, 0);
}
minic_ctx_free(p->ctx);
p->ctx = NULL;
map_delete(plugin_map, plugin);
}
+11 -32
View File
@@ -419,16 +419,6 @@ void project_import_mesh(bool replace_existing, void (*done)(void)) {
_project_import_mesh_done = done;
gc_root(_project_import_mesh_done);
char *formats = string_array_join(path_mesh_formats(), ",");
if (string_index_of(formats, "fbx") == -1) {
// Show .fbx in the file picker even when fbx plugin is not yet enabled
formats = string("%s,fbx", formats);
}
if (string_index_of(formats, "gltf") == -1) {
formats = string("%s,gltf", formats);
}
if (string_index_of(formats, "glb") == -1) {
formats = string("%s,glb", formats);
}
ui_files_show(formats, false, false, &project_import_mesh_on_file_picked);
}
@@ -517,12 +507,15 @@ string_t_array_t *project_get_unwrap_plugins() {
if (box_preferences_files_plugin == NULL) {
box_preferences_fetch_plugins();
}
#ifdef WITH_PLUGINS
for (i32 i = 0; i < box_preferences_files_plugin->length; ++i) {
char *f = box_preferences_files_plugin->buffer[i];
if (string_index_of(f, "uv_unwrap") >= 0 && ends_with(f, ".js")) {
if (string_index_of(f, "uv_unwrap") >= 0 && ends_with(f, ".c")) {
any_array_push(unwrap_plugins, f);
}
}
any_array_push(unwrap_plugins, "uv_unwrap");
#endif
any_array_push(unwrap_plugins, "equirect");
return unwrap_plugins;
}
@@ -572,13 +565,9 @@ void project_unwrap_mesh(raw_mesh_t *mesh, void (*done)(raw_mesh_t *)) {
util_mesh_equirect_unwrap(mesh);
}
else {
char *f = unwrap_plugins->buffer[_project_unwrap_by];
if (string_array_index_of(config_raw->plugins, f) == -1) {
config_enable_plugin(f);
console_info(string("%s %s", f, tr("plugin enabled")));
}
void *cb = any_map_get(util_mesh_unwrappers, f); // JSValue * -> (a: raw_mesh_t)=>void
js_call_ptr(cb, mesh);
char *f = unwrap_plugins->buffer[_project_unwrap_by];
void (*cb)(void *mesh) = any_map_get(util_mesh_unwrappers, f);
cb(mesh);
}
done(mesh);
}
@@ -598,17 +587,12 @@ void project_import_asset(char *filters, bool hdr_as_envmap) {
}
void project_import_swatches_on_file_picked(char *path) {
if (path_is_gimp_color_palette(path)) {
// import_gpl_run(path, _project_import_swatches_replace_existing);
}
else {
import_arm_run_swatches(path, _project_import_swatches_replace_existing);
}
import_arm_run_swatches(path, _project_import_swatches_replace_existing);
}
void project_import_swatches(bool replace_existing) {
_project_import_swatches_replace_existing = replace_existing;
ui_files_show("arm,gpl", false, false, &project_import_swatches_on_file_picked);
ui_files_show("arm", false, false, &project_import_swatches_on_file_picked);
}
void project_reimport_textures() {
@@ -728,16 +712,11 @@ void project_export_swatches_on_file_picked(char *path) {
if (string_equals(f, "")) {
f = string_copy(tr("untitled"));
}
if (path_is_gimp_color_palette(f)) {
// export_gpl_run(path + PATH_SEP + f, substring(f, 0, string_last_index_of(f, ".")), project_raw.swatches);
}
else {
export_arm_run_swatches(string("%s%s%s", path, PATH_SEP, f));
}
export_arm_run_swatches(string("%s%s%s", path, PATH_SEP, f));
}
void project_export_swatches() {
ui_files_show("arm,gpl", true, false, &project_export_swatches_on_file_picked);
ui_files_show("arm", true, false, &project_export_swatches_on_file_picked);
}
swatch_color_t *project_make_swatch(i32 base) {
+1 -1
View File
@@ -83,7 +83,7 @@ void tab_console_draw(ui_handle_t *htab) {
ui->font_size = _font_size;
if (ui_icon_button(tr("Run"), ICON_PLAY, UI_ALIGN_CENTER)) {
js_eval(h_input->text);
minic_ctx_free(minic_eval(string("float main() { %s }", h_input->text)));
h_input->text = "";
}
}
+2 -4
View File
@@ -84,13 +84,11 @@ void tab_meshes_draw_edit() {
ui_menu_sub_end();
}
#ifdef WITH_PLUGINS
if (ui_menu_button(tr("UV Unwrap"), "", ICON_NONE)) {
char *f = "uv_unwrap.js";
if (string_array_index_of(config_raw->plugins, f) == -1) {
config_enable_plugin(f);
}
plugin_uv_unwrap_button();
}
#endif
if (config_raw->experimental && ui_menu_button(tr("Decimate"), "", ICON_NONE)) {
util_mesh_decimate(0.5);
+5 -3
View File
@@ -24,7 +24,7 @@ void tab_plugins_draw(ui_handle_t *htab) {
for (i32 i = 0; i < keys->length; ++i) {
plugin_t *p = any_map_get(plugin_map, keys->buffer[i]);
if (p->on_ui != NULL) {
js_call(p->on_ui);
minic_ctx_call_fn(p->ctx, p->on_ui, NULL, 0);
}
}
@@ -40,14 +40,15 @@ void tab_plugins_draw(ui_handle_t *htab) {
}
}
#ifdef WITH_PLUGINS
void proc_uv_unwrap(void *mesh);
void plugin_uv_unwrap_button() {
void *cb = any_map_get(util_mesh_unwrappers, "uv_unwrap.js"); // JSValue * -> (a: raw_mesh_t)=>void
for (i32 i = 0; i < project_paint_objects->length; ++i) {
mesh_data_t *md = project_paint_objects->buffer[i]->data;
raw_mesh_t *mesh =
GC_ALLOC_INIT(raw_mesh_t,
{.posa = md->vertex_arrays->buffer[0]->values, .nora = md->vertex_arrays->buffer[1]->values, .texa = NULL, .inda = md->index_array});
js_call_ptr(cb, mesh);
proc_uv_unwrap(mesh);
md->vertex_arrays->buffer[0]->values = mesh->posa;
md->vertex_arrays->buffer[1]->values = mesh->nora;
md->vertex_arrays->buffer[2]->values = mesh->texa;
@@ -56,3 +57,4 @@ void plugin_uv_unwrap_button() {
}
util_mesh_merge(NULL);
}
#endif
+12 -6
View File
@@ -8,8 +8,8 @@ void tab_scripts_draw_export(char *path) {
f = string_copy(tr("untitled"));
}
path = string("%s%s%s", path, PATH_SEP, f);
if (!ends_with(path, ".js")) {
path = string("%s.js", path);
if (!ends_with(path, ".c")) {
path = string("%s.c", path);
}
iron_file_save_bytes(path, sys_string_to_buffer(str), 0);
}
@@ -25,10 +25,10 @@ void tab_scripts_draw_edit() {
tab_scripts_hscript->text = "";
}
if (ui_menu_button(tr("Import"), "", ICON_IMPORT)) {
ui_files_show("js", false, false, &tab_scripts_draw_import);
ui_files_show("c", false, false, &tab_scripts_draw_import);
}
if (ui_menu_button(tr("Export"), "", ICON_EXPORT)) {
ui_files_show("js", true, false, &tab_scripts_draw_export);
ui_files_show("c", true, false, &tab_scripts_draw_export);
}
}
@@ -46,7 +46,7 @@ void tab_scripts_draw(ui_handle_t *htab) {
ui_row(row);
if (ui_icon_button(tr("Run"), ICON_PLAY, UI_ALIGN_CENTER)) {
js_eval(tab_scripts_hscript->text);
minic_ctx_free(minic_eval(tab_scripts_hscript->text));
}
if (ui_icon_button(tr("Edit"), ICON_EDIT, UI_ALIGN_CENTER)) {
@@ -55,12 +55,18 @@ void tab_scripts_draw(ui_handle_t *htab) {
string_t_array_t *ar = any_array_create_from_raw(
(void *[]){
"script.js",
"script.c",
},
1);
ui_handle_t *file_handle = ui_handle(__ID__);
ui_combo(file_handle, ar, tr("File"), false, UI_ALIGN_LEFT, true);
#ifdef is_debug
if (ui_icon_button("Run Tests", ICON_PLAY, UI_ALIGN_CENTER)) {
minic_tests();
}
#endif
ui_end_sticky();
draw_font_t *_font = ui->ops->font;
+9 -7
View File
@@ -2,6 +2,7 @@
#pragma once
#include "enums.h"
#include "minic.h"
typedef struct mat4_box {
mat4_t v;
@@ -227,7 +228,7 @@ typedef struct context {
split_type_t split_by;
f32 select_time;
viewport_mode_t viewport_mode;
void *viewport_shader; // JSValue * -> (ns: node_shader_t)=>void;
void *viewport_shader;
bool hscale_was_changed;
mesh_format_t export_mesh_format;
i32 export_mesh_index;
@@ -607,12 +608,13 @@ typedef struct shader_out {
} shader_out_t;
typedef struct plugin {
void *on_ui; // JSValue *
void *on_draw; // JSValue *
void *on_update; // JSValue *
void *on_delete; // JSValue *
char *version;
char *name;
void *on_ui;
void *on_draw;
void *on_update;
void *on_delete;
char *version;
char *name;
minic_ctx_t *ctx;
} plugin_t;
typedef struct rect {
+4 -2
View File
@@ -356,8 +356,10 @@ char *ui_files_file_browser(ui_handle_t *handle, bool drag_files, char *search,
any_map_set(ui_files_icon_map, shandle, empty);
gpu_texture_t *image = data_get_image(shandle);
ui_files_make_icon_t *args = GC_ALLOC_INIT(ui_files_make_icon_t, {.image = image, .shandle = shandle, .w = w});
sys_notify_on_next_frame(ui_files_make_icon, args);
if (image != NULL) {
ui_files_make_icon_t *args = GC_ALLOC_INIT(ui_files_make_icon_t, {.image = image, .shandle = shandle, .w = w});
sys_notify_on_next_frame(ui_files_make_icon, args);
}
}
if (icon != NULL) {
if (i == ui_files_selected) {
+3 -1
View File
@@ -150,7 +150,9 @@ f32 uniforms_ext_f32_link(object_t *object, material_data_t *mat, char *link) {
char *script = any_map_get(parser_material_script_links, key);
f32 result = NAN;
if (!string_equals(script, "")) {
result = js_eval(script);
minic_ctx_t *_ctx = minic_eval(string("float main() { return %s; }", script));
result = minic_ctx_result(_ctx);
minic_ctx_free(_ctx);
}
return result;
}
+2
View File
@@ -577,7 +577,9 @@ void util_mesh_decimate(f32 strength) {
mesh_data_t *new_data = mesh_data_create(raw);
o->data = new_data;
util_mesh_calc_normals(true);
#ifdef WITH_PLUGINS
plugin_uv_unwrap_button();
#endif
}
i32 _util_mesh_unique_data_count() {