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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/real_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ 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_log10 log10f
#define GMLReal_fmax fmaxf
#define GMLReal_fmin fminf
#define GMLReal_nextafter nextafterf
Expand All @@ -48,7 +50,9 @@ 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_log10 log10
#define GMLReal_fmax fmax
#define GMLReal_fmin fmin
#define GMLReal_nextafter nextafter
Expand Down
137 changes: 137 additions & 0 deletions src/vm_builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -1946,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;
Expand Down Expand Up @@ -1987,11 +2005,28 @@ 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])));
}

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_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]);
Expand Down Expand Up @@ -2523,6 +2558,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]);
Expand Down Expand Up @@ -2614,6 +2656,51 @@ 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_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]);
Expand Down Expand Up @@ -10304,6 +10391,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;

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;

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);
}

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;
Expand Down Expand Up @@ -16195,17 +16322,23 @@ 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, "min3", builtin_min3);
VM_registerBuiltin(ctx, "mean", builtin_mean);
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, "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);
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);
Expand All @@ -16217,6 +16350,9 @@ 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, "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);
Expand Down Expand Up @@ -16781,6 +16917,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);
Expand Down
Loading