From 313a715202338deb357e8a09829a0c3c4344ea09 Mon Sep 17 00:00:00 2001 From: cobaltgit Date: Sun, 5 Jul 2026 15:36:51 +0100 Subject: [PATCH 01/10] arctan2 --- src/vm_builtins.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 07d4a389..c66aa963 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -2523,6 +2523,13 @@ static RValue builtin_arctan(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t return RValue_makeReal(GMLReal_atan(y)); } +static RValue builtin_arctan2(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t argCount) { + if (2 > argCount) return RValue_makeReal(0.0); + GMLReal y = RValue_toReal(args[0]); + GMLReal x = RValue_toReal(args[1]); + return RValue_makeReal(GMLReal_atan2(y, x)); +} + static RValue builtin_darctan(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t argCount) { if (1 > argCount) return RValue_makeReal(0.0); GMLReal y = RValue_toReal(args[0]); @@ -16206,6 +16213,7 @@ void VMBuiltins_registerAll(VMContext* ctx) { VM_registerBuiltin(ctx, "arccos", builtin_arccos); VM_registerBuiltin(ctx, "arcsin", builtin_arcsin); VM_registerBuiltin(ctx, "arctan", builtin_arctan); + VM_registerBuiltin(ctx, "arctan2", builtin_arctan2); VM_registerBuiltin(ctx, "cos", builtin_cos); VM_registerBuiltin(ctx, "dsin", builtin_dsin); VM_registerBuiltin(ctx, "dcos", builtin_dcos); From b971fda9739a4a18fb95955b4427cdaa5f60a151 Mon Sep 17 00:00:00 2001 From: cobaltgit Date: Sun, 5 Jul 2026 15:41:05 +0100 Subject: [PATCH 02/10] dot_product_3d --- src/vm_builtins.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/vm_builtins.c b/src/vm_builtins.c index c66aa963..719cd68a 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -2621,6 +2621,17 @@ static RValue builtin_dot_product(MAYBE_UNUSED VMContext* ctx, RValue* args, int return RValue_makeReal(x1 * x2 + y1 * y2); } +static RValue builtin_dot_product_3d(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t argCount) { + if (6 > argCount) return RValue_makeReal(0.0); + GMLReal x1 = RValue_toReal(args[0]); + GMLReal y1 = RValue_toReal(args[1]); + GMLReal z1 = RValue_toReal(args[2]); + GMLReal x2 = RValue_toReal(args[3]); + GMLReal y2 = RValue_toReal(args[4]); + GMLReal z2 = RValue_toReal(args[5]); + return RValue_makeReal(x1 * x2 + y1 * y2 + z1 * z2); +} + static RValue builtin_point_distance(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t argCount) { if (4 > argCount) return RValue_makeReal(0.0); GMLReal dx = RValue_toReal(args[2]) - RValue_toReal(args[0]); @@ -16225,6 +16236,7 @@ void VMBuiltins_registerAll(VMContext* ctx) { VM_registerBuiltin(ctx, "lerp", builtin_lerp); VM_registerBuiltin(ctx, "tan", builtin_tan); VM_registerBuiltin(ctx, "dot_product", builtin_dot_product); + VM_registerBuiltin(ctx, "dot_product_3d", builtin_dot_product_3d); VM_registerBuiltin(ctx, "point_distance", builtin_point_distance); VM_registerBuiltin(ctx, "point_in_rectangle", builtin_point_in_rectangle); VM_registerBuiltin(ctx, "point_in_circle", builtin_point_in_circle); From aee6deb435d9d1f2294c6230b1cfd2ed12c458f6 Mon Sep 17 00:00:00 2001 From: cobaltgit Date: Sun, 5 Jul 2026 15:43:37 +0100 Subject: [PATCH 03/10] dot_product_(3d_)normalised --- src/vm_builtins.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 719cd68a..17af1d2b 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -2632,6 +2632,40 @@ static RValue builtin_dot_product_3d(MAYBE_UNUSED VMContext* ctx, RValue* args, return RValue_makeReal(x1 * x2 + y1 * y2 + z1 * z2); } +static RValue builtin_dot_product_3d_normalised(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t argCount) { + if (6 > argCount) return RValue_makeReal(0.0); + GMLReal x1 = RValue_toReal(args[0]); + GMLReal y1 = RValue_toReal(args[1]); + GMLReal z1 = RValue_toReal(args[2]); + GMLReal x2 = RValue_toReal(args[3]); + GMLReal y2 = RValue_toReal(args[4]); + GMLReal z2 = RValue_toReal(args[5]); + + GMLReal len1 = GMLReal_sqrt(x1 * x1 + y1 * y1 + z1 * z1); + GMLReal len2 = GMLReal_sqrt(x2 * x2 + y2 * y2 + z2 * z2); + + if (len1 == 0.0 || len2 == 0.0) return RValue_makeReal(0.0); + + GMLReal dot = x1 * x2 + y1 * y2 + z1 * z2; + return RValue_makeReal(dot / (len1 * len2)); +} + +static RValue builtin_dot_product_normalised(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t argCount) { + if (4 > argCount) return RValue_makeReal(0.0); + GMLReal x1 = RValue_toReal(args[0]); + GMLReal y1 = RValue_toReal(args[1]); + GMLReal x2 = RValue_toReal(args[2]); + GMLReal y2 = RValue_toReal(args[3]); + + GMLReal len1 = GMLReal_sqrt(x1 * x1 + y1 * y1); + GMLReal len2 = GMLReal_sqrt(x2 * x2 + y2 * y2); + + if (len1 == 0.0 || len2 == 0.0) return RValue_makeReal(0.0); + + GMLReal dot = x1 * x2 + y1 * y2; + return RValue_makeReal(dot / (len1 * len2)); +} + static RValue builtin_point_distance(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t argCount) { if (4 > argCount) return RValue_makeReal(0.0); GMLReal dx = RValue_toReal(args[2]) - RValue_toReal(args[0]); @@ -16237,6 +16271,8 @@ void VMBuiltins_registerAll(VMContext* ctx) { VM_registerBuiltin(ctx, "tan", builtin_tan); VM_registerBuiltin(ctx, "dot_product", builtin_dot_product); VM_registerBuiltin(ctx, "dot_product_3d", builtin_dot_product_3d); + VM_registerBuiltin(ctx, "dot_product_3d_normalised", builtin_dot_product_3d_normalised); + VM_registerBuiltin(ctx, "dot_product_normalised", builtin_dot_product_normalised); VM_registerBuiltin(ctx, "point_distance", builtin_point_distance); VM_registerBuiltin(ctx, "point_in_rectangle", builtin_point_in_rectangle); VM_registerBuiltin(ctx, "point_in_circle", builtin_point_in_circle); From 7377494bf1e24c327cb2f093acee91b99eca5bbb Mon Sep 17 00:00:00 2001 From: cobaltgit Date: Sun, 5 Jul 2026 16:10:17 +0100 Subject: [PATCH 04/10] draw_arrow --- src/vm_builtins.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 17af1d2b..8c867b5e 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -10356,6 +10356,46 @@ static RValue builtin_draw_triangle_color(VMContext* ctx, RValue* args, MAYBE_UN return RValue_makeUndefined(); } +// draw_arrow(x1, y1, x2, y2, size) +static RValue builtin_draw_arrow(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t argCount) { + if (argCount < 5) return RValue_makeUndefined(); + Runner* runner = ctx->runner; + + float x1 = (float) RValue_toReal(args[0]); + float y1 = (float) RValue_toReal(args[1]); + float x2 = (float) RValue_toReal(args[2]); + float y2 = (float) RValue_toReal(args[3]); + float size = (float) RValue_toReal(args[4]); + + float dx = x2 - x1; + float dy = y2 - y1; + float dd = (float) GMLReal_sqrt(dx * dx + dy * dy); + + if (dd != 0.0) { + if (size > dd) { + size = dd; + } + + float xx = size * dx / dd; + float yy = size * dy / dd; + uint32_t color = runner->renderer->drawColor; + float alpha = runner->renderer->drawAlpha; + + runner->renderer->vtable->drawLine(runner->renderer, x1, y1, x2, y2, color, color, alpha); + + float tx1 = x2 - xx - yy / 3.0; + float ty1 = y2 - yy + xx / 3.0; + float tx2 = x2; + float ty2 = y2; + float tx3 = x2 - xx + yy / 3.0; + float ty3 = y2 - yy - xx / 3.0; + + runner->renderer->vtable->drawTriangle(runner->renderer, tx1, ty1, tx2, ty2, tx3, ty3, color, color, color, alpha, false); + } + + return RValue_makeUndefined(); +} + // draw_circle(x, y, r, outline) static RValue builtin_draw_circle(VMContext* ctx, RValue* args, MAYBE_UNUSED int32_t argCount) { Runner* runner = ctx->runner; @@ -16837,6 +16877,7 @@ void VMBuiltins_registerAll(VMContext* ctx) { VM_registerBuiltin(ctx, "draw_triangle", builtin_draw_triangle); VM_registerBuiltin(ctx, "draw_triangle_colour", builtin_draw_triangle_color); VM_registerBuiltin(ctx, "draw_triangle_color", builtin_draw_triangle_color); + VM_registerBuiltin(ctx, "draw_arrow", builtin_draw_arrow); VM_registerBuiltin(ctx, "draw_circle", builtin_draw_circle); VM_registerBuiltin(ctx, "draw_circle_colour", builtin_draw_circle_color); VM_registerBuiltin(ctx, "draw_circle_color", builtin_draw_circle_color); From 0acd9c93a15026e2891ececc72b13f180580ea28 Mon Sep 17 00:00:00 2001 From: cobaltgit Date: Sun, 5 Jul 2026 16:16:34 +0100 Subject: [PATCH 05/10] calculate arrowhead before drawing line --- src/vm_builtins.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 8c867b5e..4fdb615b 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -10378,10 +10378,6 @@ static RValue builtin_draw_arrow(MAYBE_UNUSED VMContext* ctx, RValue* args, int3 float xx = size * dx / dd; float yy = size * dy / dd; - uint32_t color = runner->renderer->drawColor; - float alpha = runner->renderer->drawAlpha; - - runner->renderer->vtable->drawLine(runner->renderer, x1, y1, x2, y2, color, color, alpha); float tx1 = x2 - xx - yy / 3.0; float ty1 = y2 - yy + xx / 3.0; @@ -10390,6 +10386,10 @@ static RValue builtin_draw_arrow(MAYBE_UNUSED VMContext* ctx, RValue* args, int3 float tx3 = x2 - xx + yy / 3.0; float ty3 = y2 - yy - xx / 3.0; + uint32_t color = runner->renderer->drawColor; + float alpha = runner->renderer->drawAlpha; + + runner->renderer->vtable->drawLine(runner->renderer, x1, y1, x2, y2, color, color, alpha); runner->renderer->vtable->drawTriangle(runner->renderer, tx1, ty1, tx2, ty2, tx3, ty3, color, color, color, alpha, false); } From b6549c17ec4336b1db37c21c47f20bd6a1b7af27 Mon Sep 17 00:00:00 2001 From: cobaltgit Date: Sun, 5 Jul 2026 19:41:32 +0100 Subject: [PATCH 06/10] ln --- src/real_type.h | 2 ++ src/vm_builtins.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/real_type.h b/src/real_type.h index c6547455..5acc33f3 100644 --- a/src/real_type.h +++ b/src/real_type.h @@ -24,6 +24,7 @@ typedef float GMLReal; #define GMLReal_ceil ceilf #define GMLReal_round roundf #define GMLReal_pow powf +#define GMLReal_log logf #define GMLReal_log2 log2f #define GMLReal_fmax fmaxf #define GMLReal_fmin fminf @@ -48,6 +49,7 @@ typedef double GMLReal; #define GMLReal_ceil ceil #define GMLReal_round round #define GMLReal_pow pow +#define GMLReal_log log #define GMLReal_log2 log2 #define GMLReal_fmax fmax #define GMLReal_fmin fmin diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 4fdb615b..fddbd76e 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -1987,6 +1987,11 @@ static RValue builtin_sqrt(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t ar return RValue_makeReal(GMLReal_sqrt(RValue_toReal(args[0]))); } +static RValue builtin_ln(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t argCount) { + if (1 > argCount) return RValue_makeReal(0.0); + return RValue_makeReal(GMLReal_log(RValue_toReal(args[0]))); +} + static RValue builtin_log2(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t argCount) { if (1 > argCount) return RValue_makeReal(0.0); return RValue_makeReal(GMLReal_log2(RValue_toReal(args[0]))); @@ -16292,6 +16297,7 @@ void VMBuiltins_registerAll(VMContext* ctx) { VM_registerBuiltin(ctx, "median", builtin_median); VM_registerBuiltin(ctx, "power", builtin_power); VM_registerBuiltin(ctx, "sqrt", builtin_sqrt); + VM_registerBuiltin(ctx, "ln", builtin_ln); VM_registerBuiltin(ctx, "log2", builtin_log2); VM_registerBuiltin(ctx, "sqr", builtin_sqr); VM_registerBuiltin(ctx, "sin", builtin_sin); From 7f838c00fd9474d2e5088d7abec85e2df47795ae Mon Sep 17 00:00:00 2001 From: cobaltgit Date: Sun, 5 Jul 2026 19:42:11 +0100 Subject: [PATCH 07/10] log10 --- src/real_type.h | 2 ++ src/vm_builtins.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/real_type.h b/src/real_type.h index 5acc33f3..c44bc792 100644 --- a/src/real_type.h +++ b/src/real_type.h @@ -26,6 +26,7 @@ typedef float GMLReal; #define GMLReal_pow powf #define GMLReal_log logf #define GMLReal_log2 log2f +#define GMLReal_log10 log10f #define GMLReal_fmax fmaxf #define GMLReal_fmin fminf #define GMLReal_nextafter nextafterf @@ -51,6 +52,7 @@ typedef double GMLReal; #define GMLReal_pow pow #define GMLReal_log log #define GMLReal_log2 log2 +#define GMLReal_log10 log10 #define GMLReal_fmax fmax #define GMLReal_fmin fmin #define GMLReal_nextafter nextafter diff --git a/src/vm_builtins.c b/src/vm_builtins.c index fddbd76e..15809789 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -1997,6 +1997,11 @@ static RValue builtin_log2(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t ar return RValue_makeReal(GMLReal_log2(RValue_toReal(args[0]))); } +static RValue builtin_log10(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t argCount) { + if (1 > argCount) return RValue_makeReal(0.0); + return RValue_makeReal(GMLReal_log10(RValue_toReal(args[0]))); +} + static RValue builtin_sqr(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t argCount) { if (1 > argCount) return RValue_makeReal(0.0); GMLReal val = RValue_toReal(args[0]); @@ -16299,6 +16304,7 @@ void VMBuiltins_registerAll(VMContext* ctx) { VM_registerBuiltin(ctx, "sqrt", builtin_sqrt); VM_registerBuiltin(ctx, "ln", builtin_ln); VM_registerBuiltin(ctx, "log2", builtin_log2); + VM_registerBuiltin(ctx, "log10", builtin_log10); VM_registerBuiltin(ctx, "sqr", builtin_sqr); VM_registerBuiltin(ctx, "sin", builtin_sin); VM_registerBuiltin(ctx, "arccos", builtin_arccos); From ac815e38e7d32da8f2dfd39fcddd5388f5b1ec70 Mon Sep 17 00:00:00 2001 From: cobaltgit Date: Sun, 5 Jul 2026 19:43:26 +0100 Subject: [PATCH 08/10] logn --- src/vm_builtins.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 15809789..7eb12302 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -2002,6 +2002,13 @@ static RValue builtin_log10(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t a return RValue_makeReal(GMLReal_log10(RValue_toReal(args[0]))); } +static RValue builtin_logn(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t argCount) { + if (2 > argCount) return RValue_makeReal(0.0); + GMLReal base = RValue_toReal(args[0]); + GMLReal val = RValue_toReal(args[1]); + return RValue_makeReal(GMLReal_log(val) / GMLReal_log(base)); +} + static RValue builtin_sqr(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t argCount) { if (1 > argCount) return RValue_makeReal(0.0); GMLReal val = RValue_toReal(args[0]); @@ -16305,6 +16312,7 @@ void VMBuiltins_registerAll(VMContext* ctx) { VM_registerBuiltin(ctx, "ln", builtin_ln); VM_registerBuiltin(ctx, "log2", builtin_log2); VM_registerBuiltin(ctx, "log10", builtin_log10); + VM_registerBuiltin(ctx, "logn", builtin_logn); VM_registerBuiltin(ctx, "sqr", builtin_sqr); VM_registerBuiltin(ctx, "sin", builtin_sin); VM_registerBuiltin(ctx, "arccos", builtin_arccos); From 90a03df2827d8fc2899e9ba4aeac752913f9b79b Mon Sep 17 00:00:00 2001 From: cobaltgit Date: Sun, 5 Jul 2026 19:47:12 +0100 Subject: [PATCH 09/10] max3 --- src/vm_builtins.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 7eb12302..d6ab29c3 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -1936,6 +1936,15 @@ static RValue builtin_max(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t arg return RValue_makeReal(result); } +static RValue builtin_max3(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t argCount) { + if (3 > argCount) return RValue_makeReal(0.0); + GMLReal x = RValue_toReal(args[0]); + GMLReal y = RValue_toReal(args[1]); + GMLReal z = RValue_toReal(args[2]); + GMLReal result = (x > y) ? ((x > z) ? x : z) : ((y > z) ? y : z); + return RValue_makeReal(result); +} + static RValue builtin_min(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t argCount) { if (1 > argCount) return RValue_makeReal(0.0); GMLReal result = INFINITY; @@ -16304,6 +16313,7 @@ void VMBuiltins_registerAll(VMContext* ctx) { VM_registerBuiltin(ctx, "frac", builtin_frac); VM_registerBuiltin(ctx, "sign", builtin_sign); VM_registerBuiltin(ctx, "max", builtin_max); + VM_registerBuiltin(ctx, "max3", builtin_max3); VM_registerBuiltin(ctx, "min", builtin_min); VM_registerBuiltin(ctx, "mean", builtin_mean); VM_registerBuiltin(ctx, "median", builtin_median); From a901b733728e4bf52bcc0c6800501158f5974c23 Mon Sep 17 00:00:00 2001 From: cobaltgit Date: Sun, 5 Jul 2026 19:57:28 +0100 Subject: [PATCH 10/10] min3 --- src/vm_builtins.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/vm_builtins.c b/src/vm_builtins.c index d6ab29c3..e0837476 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -1955,6 +1955,15 @@ static RValue builtin_min(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t arg return RValue_makeReal(result); } +static RValue builtin_min3(MAYBE_UNUSED VMContext* ctx, RValue* args, int32_t argCount) { + if (3 > argCount) return RValue_makeReal(0.0); + GMLReal x = RValue_toReal(args[0]); + GMLReal y = RValue_toReal(args[1]); + GMLReal z = RValue_toReal(args[2]); + GMLReal result = (x < y) ? ((x < z) ? x : z) : ((y < z) ? y : z); + return RValue_makeReal(result); +} + static int compareReals(const void* a, const void* b) { GMLReal lhs = *(const GMLReal*) a; GMLReal rhs = *(const GMLReal*) b; @@ -16315,6 +16324,7 @@ void VMBuiltins_registerAll(VMContext* ctx) { VM_registerBuiltin(ctx, "max", builtin_max); VM_registerBuiltin(ctx, "max3", builtin_max3); VM_registerBuiltin(ctx, "min", builtin_min); + VM_registerBuiltin(ctx, "min3", builtin_min3); VM_registerBuiltin(ctx, "mean", builtin_mean); VM_registerBuiltin(ctx, "median", builtin_median); VM_registerBuiltin(ctx, "power", builtin_power);