commit bcc7a806756427240bb9f33d7c89007d41b97bef
parent 64e92ec7c143e6873858dd3543bf5ade6235e14a
Author: amin <dev@aminmesbah.com>
Date: Mon, 5 Feb 2024 07:41:40 +0000
Fix wasm builds
- Get rid of bare `inline`, which has a very esoteric purpose in C, and anyway
was breaking nonoptimized builds.
- Get rid of `inline` altogether. Compilers do their own thing anyway.
- Invoke clang's public API, not the private one that breaks.
- Don't depend on math.h (how did that ever work!?)
FossilOrigin-Name: dbc8a3e3370f2feeadc8fe5920f5dfeab38423d521b4f285a14e5d1507698ab2
Diffstat:
12 files changed, 198 insertions(+), 165 deletions(-)
diff --git a/build_wasm.sh b/build_wasm.sh
@@ -15,37 +15,25 @@ cp -r shader/ $wasm_dir
cp -r assets/ $wasm_dir
clang_version=$(clang -v 2>&1 | head -1 | cut -d " " -f 3)
-clang \
- -cc1 \
- -Ofast \
- -emit-llvm-bc \
- -triple=wasm32-unknown-unknown-unknown-wasm \
- -ffreestanding \
- -fno-builtin \
- -std=c11 \
- -internal-isystem /usr/lib/clang/$clang_version/include \
- -internal-externc-isystem /usr/include \
- -DPLATFORM_WASM \
- -o $wasm_dir/wasm.bc \
+clang \
+ --no-standard-libraries \
+ --target=wasm32 \
+ -DPLATFORM_WASM \
+ -O3 \
+ -ffreestanding \
+ -std=c11 \
+ -Wl,--allow-undefined-file=src/platform_wasm_js_symbols.txt \
+ -Wl,--export=init \
+ -Wl,--export=key_callback \
+ -Wl,--export=render \
+ -Wl,--export=window_resize \
+ -Wl,--import-memory \
+ -Wl,--no-entry \
+ -o $wasm_dir/binary.wasm \
src/platform_wasm.c
-llvm-link -o $wasm_dir/wasm.bc $wasm_dir/wasm.bc
-opt -O3 -disable-simplify-libcalls $wasm_dir/wasm.bc -o $wasm_dir/wasm.bc
-llc -O3 -disable-simplify-libcalls -filetype=obj $wasm_dir/wasm.bc -o $wasm_dir/wasm.o
-
-wasm-ld \
- --no-entry $wasm_dir/wasm.o \
- -o $wasm_dir/binary.wasm \
- -allow-undefined-file src/platform_wasm_js_symbols.txt \
- --export=init \
- --export=render \
- --export=window_resize \
- --export=key_callback \
- --import-memory
-
-rm $wasm_dir/*.o
-rm $wasm_dir/*.bc
-
-current_commit=$(git rev-parse HEAD)
-echo "<!-- Source Code: https://git.amin.space/a-game/tree/?id=$current_commit -->" \
- >> $wasm_dir/index.html
+# TODO: embed the fossil/git commit like we used to back when this was hosted
+# in git.
+#current_commit=$(git rev-parse HEAD)
+#echo "<!-- Source Code: https://git.amin.space/a-game/tree/?id=$current_commit -->" \
+# >> $wasm_dir/index.html
diff --git a/src/am_math.h b/src/am_math.h
@@ -5,30 +5,30 @@
// TODO: make sure these functions are inlineable and that the compiler does
// indeed inline them.
-internal inline f32 math_min(f32 a, f32 b)
+internal f32 math_min(f32 a, f32 b)
{
f32 min = a < b ? a : b;
return min;
}
-internal inline f32 math_max(f32 a, f32 b)
+internal f32 math_max(f32 a, f32 b)
{
f32 max = a > b ? a : b;
return max;
}
-internal inline u32 math_pow_of_2(u32 exponent)
+internal u32 math_pow_of_2(u32 exponent)
{
u32 result = 1 << exponent;
return result;
}
-internal inline i32 math_round(f32 n)
+internal i32 math_round(f32 n)
{
return n < 0.0f ? n - 0.5 : n + 0.5;
}
-internal inline f32 math_wrap(f32 n, f32 min, f32 max)
+internal f32 math_wrap(f32 n, f32 min, f32 max)
{
if (n > max)
{
@@ -45,26 +45,26 @@ internal inline f32 math_wrap(f32 n, f32 min, f32 max)
}
// TODO: Test this against floorf
-internal inline f32 math_floor(f32 x)
+internal f32 math_floor(f32 x)
{
f32 result = (f32)((i32)x - (x < 0.0f));
return result;
}
// TODO: Test this against ceilf
-internal inline i32 math_ceil(f32 x)
+internal i32 math_ceil(f32 x)
{
i32 result = -math_floor(-x);
return result;
}
-internal inline bool math_f32_is_i32(f32 x)
+internal bool math_f32_is_i32(f32 x)
{
bool result = ((i32)x) == x;
return result;
}
-internal inline m4 math_m4_init_id()
+internal m4 math_m4_init_id()
{
m4 m = {0};
m.E[0][0] = 1.0f;
@@ -74,7 +74,7 @@ internal inline m4 math_m4_init_id()
return m;
}
-internal inline void math_m4_valueptr(m4 m, f32* out_valueptr)
+internal void math_m4_valueptr(m4 m, f32* out_valueptr)
{
for (u8 v = 0; v < 16; ++v)
{
@@ -84,7 +84,7 @@ internal inline void math_m4_valueptr(m4 m, f32* out_valueptr)
}
}
-internal inline bool math_m4m4_eq(m4 mat1, m4 mat2)
+internal bool math_m4m4_eq(m4 mat1, m4 mat2)
{
for (u8 i = 0; i < 4; ++i)
{
@@ -99,7 +99,7 @@ internal inline bool math_m4m4_eq(m4 mat1, m4 mat2)
return true;
}
-internal inline m4 math_m4m4_m(m4 mat1, m4 mat2)
+internal m4 math_m4m4_m(m4 mat1, m4 mat2)
{
m4 r = {
.E[0][0] = (mat1.E[0][0] * mat2.E[0][0]) + (mat1.E[0][1] * mat2.E[1][0]) + (mat1.E[0][2] * mat2.E[2][0]) + (mat1.E[0][3] * mat2.E[3][0]),
@@ -125,7 +125,7 @@ internal inline m4 math_m4m4_m(m4 mat1, m4 mat2)
return r;
}
-internal inline v4 math_m4v4_m(m4 m, v4 v)
+internal v4 math_m4v4_m(m4 m, v4 v)
{
v4 r = {
.x = (m.E[0][0] * v.x) + (m.E[0][1] * v.y) + (m.E[0][2] * v.z) + (m.E[0][3] * v.w),
@@ -136,12 +136,12 @@ internal inline v4 math_m4v4_m(m4 m, v4 v)
return r;
}
-internal inline bool math_approx(f32 n, f32 compare, f32 epsilon)
+internal bool math_approx(f32 n, f32 compare, f32 epsilon)
{
return fabsf(n - compare) <= epsilon;
}
-internal inline bool math_v2_is_nonzero(v2 v)
+internal bool math_v2_is_nonzero(v2 v)
{
// TODO: Figure out whether this epsilon is universally appropriate.
f32 epsilon = 0.000001;
@@ -151,7 +151,7 @@ internal inline bool math_v2_is_nonzero(v2 v)
);
}
-internal inline v2 math_v2_a(v2 vec1, v2 vec2)
+internal v2 math_v2_a(v2 vec1, v2 vec2)
{
v2 r = {
.x = vec1.x + vec2.x,
@@ -160,24 +160,24 @@ internal inline v2 math_v2_a(v2 vec1, v2 vec2)
return r;
}
-internal inline v2 math_v2_negate(v2 v)
+internal v2 math_v2_negate(v2 v)
{
v2 r = {-v.x, -v.y};
return r;
}
-internal inline v2 math_v2_s(v2 vec1, v2 vec2)
+internal v2 math_v2_s(v2 vec1, v2 vec2)
{
return math_v2_a(vec1, math_v2_negate(vec2));
}
-internal inline v2 math_v2f_m(v2 v, f32 s)
+internal v2 math_v2f_m(v2 v, f32 s)
{
v2 r = {v.x * s, v.y * s};
return r;
}
-internal inline f32 math_v2_length(v2 v)
+internal f32 math_v2_length(v2 v)
{
// TODO: Use inner product of v with itself
return sqrtf((v.x * v.x) + (v.y * v.y));
@@ -185,14 +185,14 @@ internal inline f32 math_v2_length(v2 v)
// TODO: handle degenerate case where l is near 0.0f
// TODO: scale by 1.0f / l
-internal inline v2 math_v2_normalize(v2 v)
+internal v2 math_v2_normalize(v2 v)
{
f32 l = math_v2_length(v);
v2 r = {v.x / l, v.y / l};
return r;
}
-internal inline f32 math_v2_dot(v2 vec1, v2 vec2)
+internal f32 math_v2_dot(v2 vec1, v2 vec2)
{
// dot product, a.k.a. inner product or scalar product
f32 dot_product = (vec1.x * vec2.x) + (vec1.y * vec2.y);
@@ -204,25 +204,25 @@ internal inline f32 math_v2_dot(v2 vec1, v2 vec2)
return dot_product;
}
-internal inline v2i math_v2i_a(v2i vec1, v2i vec2)
+internal v2i math_v2i_a(v2i vec1, v2i vec2)
{
v2i r = {vec1.x + vec2.x, vec1.y + vec2.y};
return r;
}
-internal inline bool math_v2i_eq(v2i vec1, v2i vec2)
+internal bool math_v2i_eq(v2i vec1, v2i vec2)
{
bool result = (vec1.x == vec2.x && vec1.y == vec2.y);
return result;
}
-internal inline bool math_v2u_eq(v2u vec1, v2u vec2)
+internal bool math_v2u_eq(v2u vec1, v2u vec2)
{
bool result = (vec1.x == vec2.x && vec1.y == vec2.y);
return result;
}
-internal inline v3 math_v3_cross(v3 vec1, v3 vec2)
+internal v3 math_v3_cross(v3 vec1, v3 vec2)
{
// cross product, a.k.a. outer product or vector product
v3 r = {
@@ -233,7 +233,7 @@ internal inline v3 math_v3_cross(v3 vec1, v3 vec2)
return r;
}
-internal inline f32 math_v3_length(v3 v)
+internal f32 math_v3_length(v3 v)
{
// TODO: Use inner product of v with itself
// NOTE: math_v3_dot(v, v) returns:
@@ -246,13 +246,13 @@ internal inline f32 math_v3_length(v3 v)
return sqrtf((v.x * v.x) + (v.y * v.y) + (v.z * v.z));
}
-internal inline v3 math_v3f_m(v3 v, f32 s)
+internal v3 math_v3f_m(v3 v, f32 s)
{
v3 r = {.x = v.x * s, .y = v.y * s, .z = v.z * s};
return r;
}
-internal inline v3 math_v3_negate(v3 v)
+internal v3 math_v3_negate(v3 v)
{
v3 r = {.x = -v.x, .y = -v.y, .z = -v.z};
return r;
@@ -260,14 +260,14 @@ internal inline v3 math_v3_negate(v3 v)
// TODO: handle degenerate case where l is near 0.0f
// TODO: scale by 1.0f / l
-internal inline v3 math_v3_normalize(v3 v)
+internal v3 math_v3_normalize(v3 v)
{
f32 l = math_v3_length(v);
v3 r = {v.x / l, v.y / l, v.z / l};
return r;
}
-internal inline v3 math_v3_a(v3 vec1, v3 vec2)
+internal v3 math_v3_a(v3 vec1, v3 vec2)
{
v3 r = {
.x = vec1.x + vec2.x,
@@ -277,12 +277,12 @@ internal inline v3 math_v3_a(v3 vec1, v3 vec2)
return r;
}
-internal inline v3 math_v3_s(v3 vec1, v3 vec2)
+internal v3 math_v3_s(v3 vec1, v3 vec2)
{
return math_v3_a(vec1, math_v3_negate(vec2));
}
-internal inline v3 math_v3_from_rgb(i32 rgb)
+internal v3 math_v3_from_rgb(i32 rgb)
{
v3 result = {
.x = ((rgb >> 16) & 0xFF) / 255.0f,
@@ -292,7 +292,7 @@ internal inline v3 math_v3_from_rgb(i32 rgb)
return result;
}
-internal inline bool math_v4v4_eq(v4 vec1, v4 vec2)
+internal bool math_v4v4_eq(v4 vec1, v4 vec2)
{
for (u8 i = 0; i < 4; ++i)
{
@@ -304,7 +304,7 @@ internal inline bool math_v4v4_eq(v4 vec1, v4 vec2)
return true;
}
-internal inline void math_clamp(f32 *f, f32 min, f32 max)
+internal void math_clamp(f32 *f, f32 min, f32 max)
{
if (*f < min)
{
@@ -316,23 +316,23 @@ internal inline void math_clamp(f32 *f, f32 min, f32 max)
}
}
-internal inline f32 math_deg(f32 rad)
+internal f32 math_deg(f32 rad)
{
return rad * (180.0f / M_PI);
}
-internal inline f32 math_lerpf(f32 f, f32 min, f32 max)
+internal f32 math_lerpf(f32 f, f32 min, f32 max)
{
assert(f >= 0.0f && f <= 1.0f);
return (1.0f - f) * min + f * max;
}
-internal inline f32 math_rad(f32 deg)
+internal f32 math_rad(f32 deg)
{
return deg * (M_PI / 180.0f);
}
-internal inline m4 math_rotate_x(m4 m, f32 rad)
+internal m4 math_rotate_x(m4 m, f32 rad)
{
f32 c = cosf(rad);
f32 s = sinf(rad);
@@ -348,7 +348,7 @@ internal inline m4 math_rotate_x(m4 m, f32 rad)
return math_m4m4_m(m, r);
}
-internal inline m4 math_rotate_y(m4 m, f32 rad)
+internal m4 math_rotate_y(m4 m, f32 rad)
{
f32 c = cosf(rad);
f32 s = sinf(rad);
@@ -364,7 +364,7 @@ internal inline m4 math_rotate_y(m4 m, f32 rad)
return math_m4m4_m(m, r);
}
-internal inline m4 math_rotate_z(m4 m, f32 rad)
+internal m4 math_rotate_z(m4 m, f32 rad)
{
f32 c = cosf(rad);
f32 s = sinf(rad);
@@ -380,7 +380,7 @@ internal inline m4 math_rotate_z(m4 m, f32 rad)
return math_m4m4_m(m, r);
}
-internal inline m4 math_rotate(m4 m, f32 rad, v3 axis)
+internal m4 math_rotate(m4 m, f32 rad, v3 axis)
{
axis = math_v3_normalize(axis);
@@ -404,7 +404,7 @@ internal inline m4 math_rotate(m4 m, f32 rad, v3 axis)
return math_m4m4_m(m, r);
}
-internal inline m4 math_scale(m4 m, v3 v)
+internal m4 math_scale(m4 m, v3 v)
{
m4 r = math_m4_init_id();
r.E[0][0] = v.x;
@@ -413,7 +413,7 @@ internal inline m4 math_scale(m4 m, v3 v)
return math_m4m4_m(m, r);
}
-internal inline m4 math_translate(m4 m, v3 v)
+internal m4 math_translate(m4 m, v3 v)
{
m4 r = math_m4_init_id();
r.E[0][3] = v.x;
@@ -422,7 +422,7 @@ internal inline m4 math_translate(m4 m, v3 v)
return math_m4m4_m(m, r);
}
-internal inline m4 math_projection_ortho(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far)
+internal m4 math_projection_ortho(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far)
{
// TODO: This assert fails when you minimise the window in Windows.
assert(left != right);
@@ -454,7 +454,7 @@ internal inline m4 math_projection_ortho(f32 left, f32 right, f32 bottom, f32 to
return r;
}
-internal inline m4 math_projection_perspective(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far)
+internal m4 math_projection_perspective(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far)
{
assert(left != right);
assert(bottom != top);
@@ -485,7 +485,7 @@ internal inline m4 math_projection_perspective(f32 left, f32 right, f32 bottom,
return r;
}
-internal inline m4 math_projection_perspective_fov(f32 fovy, f32 aspect, f32 near, f32 far)
+internal m4 math_projection_perspective_fov(f32 fovy, f32 aspect, f32 near, f32 far)
{
f32 half_height = tanf(fovy / 2.0f) * near;
f32 half_width = half_height * aspect;
@@ -497,7 +497,7 @@ internal inline m4 math_projection_perspective_fov(f32 fovy, f32 aspect, f32 nea
return math_projection_perspective(left, right, bottom, top, near, far);
}
-internal inline m4 math_camera_look_at(v3 camera_pos, v3 camera_target, v3 up)
+internal m4 math_camera_look_at(v3 camera_pos, v3 camera_target, v3 up)
{
v3 camera_direction = math_v3_normalize(math_v3_s(camera_pos, camera_target));
v3 camera_right = math_v3_normalize(math_v3_cross(up, camera_direction));
@@ -519,7 +519,7 @@ internal inline m4 math_camera_look_at(v3 camera_pos, v3 camera_target, v3 up)
return math_m4m4_m(look, math_translate(math_m4_init_id(), math_v3_negate(camera_pos)));
}
-internal inline bool math_intersect_aabb_aabb(rect r1, rect r2)
+internal bool math_intersect_aabb_aabb(rect r1, rect r2)
{
f32 total_w = (r1.max.x - r1.min.x) + (r2.max.x - r2.min.x);
f32 total_h = (r1.max.y - r1.min.y) + (r2.max.y - r2.min.y);
@@ -532,7 +532,7 @@ internal inline bool math_intersect_aabb_aabb(rect r1, rect r2)
return aabbs_do_indeed_intersect;
}
-internal inline rect math_minkowski_sum_rect(rect r1, v2 r2_dimensions)
+internal rect math_minkowski_sum_rect(rect r1, v2 r2_dimensions)
{
v2 r2_half = {
.width = 0.5f * r2_dimensions.width,
@@ -545,14 +545,14 @@ internal inline rect math_minkowski_sum_rect(rect r1, v2 r2_dimensions)
return sum;
}
-internal inline rect math_minkowski_diff_rect(rect r1, v2 r2_dimensions)
+internal rect math_minkowski_diff_rect(rect r1, v2 r2_dimensions)
{
v2 negated_r2_dim = math_v2_negate(r2_dimensions);
rect difference = math_minkowski_sum_rect(r1, negated_r2_dim);
return difference;
}
-internal inline rect math_rect_from_center_dim(v2 center, v2 dimensions)
+internal rect math_rect_from_center_dim(v2 center, v2 dimensions)
{
v2 half_d = {dimensions.x * 0.5f, dimensions.y * 0.5f};
rect result = {
@@ -571,7 +571,7 @@ enum MathRectEdge
MAX_RECT_EDGE,
};
-internal inline segment math_rect_get_edge(rect r, enum MathRectEdge e)
+internal segment math_rect_get_edge(rect r, enum MathRectEdge e)
{
v2 nw = {r.min.x, r.max.y};
v2 ne = r.max;
@@ -624,7 +624,7 @@ internal v2 math_rect_get_normal(enum MathRectEdge e)
return normal;
}
-internal inline bool math_in_interval_open(f32 n, f32 min, f32 max)
+internal bool math_in_interval_open(f32 n, f32 min, f32 max)
{
assert(min <= max);
bool in_open_interval = false;
@@ -632,28 +632,28 @@ internal inline bool math_in_interval_open(f32 n, f32 min, f32 max)
return in_open_interval;
}
-internal inline bool math_v2_lt(v2 v, v2 compare)
+internal bool math_v2_lt(v2 v, v2 compare)
{
bool is_lt = false;
is_lt = (v.x < compare.x && v.y < compare.y);
return is_lt;
}
-internal inline bool math_v2_le(v2 v, v2 compare)
+internal bool math_v2_le(v2 v, v2 compare)
{
bool is_le = false;
is_le = (v.x <= compare.x && v.y <= compare.y);
return is_le;
}
-internal inline bool math_v2_ge(v2 v, v2 compare)
+internal bool math_v2_ge(v2 v, v2 compare)
{
bool is_ge = false;
is_ge = (v.x >= compare.x && v.y >= compare.y);
return is_ge;
}
-internal inline i32 math_log2(u32 x)
+internal i32 math_log2(u32 x)
{
i32 result = sizeof(u32) * CHAR_BIT - intr_clz(x) - 1;
return result;
@@ -661,32 +661,32 @@ internal inline i32 math_log2(u32 x)
#define math_is_pow_2(n) ((n) & ((n) - 1)) == 0
-internal inline void math_v2_print(v2 v)
+internal void math_v2_print(v2 v)
{
printf("( %f, %f )\n", v.x, v.y);
}
-internal inline void math_v2u_print(v2u v)
+internal void math_v2u_print(v2u v)
{
printf("( %u, %u )\n", v.x, v.y);
}
-internal inline void math_v2i_print(v2i v)
+internal void math_v2i_print(v2i v)
{
printf("( %i, %i )\n", v.x, v.y);
}
-internal inline void math_v3_print(v3 v)
+internal void math_v3_print(v3 v)
{
printf("( %f, %f, %f )\n", v.x, v.y, v.z);
}
-internal inline void math_v4_print(v4 v)
+internal void math_v4_print(v4 v)
{
printf("( %f, %f, %f, %f )\n", v.x, v.y, v.z, v.w);
}
-internal inline void math_rect_print(rect r)
+internal void math_rect_print(rect r)
{
printf("rect:\n");
printf(" min: ");
@@ -695,7 +695,7 @@ internal inline void math_rect_print(rect r)
math_v2_print(r.max);
}
-internal inline void math_m4_print(m4 m)
+internal void math_m4_print(m4 m)
{
printf("[\n");
printf(" %f, %f, %f, %f\n", m.E[0][0], m.E[0][1], m.E[0][2], m.E[0][3]);
diff --git a/src/game.c b/src/game.c
@@ -14,12 +14,12 @@
#include "w_tutorial.h"
-internal inline bool timer_is_expired(struct Timer t)
+internal bool timer_is_expired(struct Timer t)
{
return t.elapsed_ms >= t.limit_ms;
}
-internal inline void timer_init(struct Timer *t, i64 limit_ms)
+internal void timer_init(struct Timer *t, i64 limit_ms)
{
*t = (struct Timer) {
.elapsed_ms = 0,
@@ -27,7 +27,7 @@ internal inline void timer_init(struct Timer *t, i64 limit_ms)
};
}
-internal inline void timer_update(struct Timer *t, i64 elapsed_ms)
+internal void timer_update(struct Timer *t, i64 elapsed_ms)
{
t->elapsed_ms += elapsed_ms;
}
diff --git a/src/game.h b/src/game.h
@@ -4,8 +4,9 @@
#include <stddef.h>
#include <stdint.h>
-// TODO: only include this in the non-wasm builds
+#if !defined(PLATFORM_WASM)
#include <math.h>
+#endif
#if !defined(PLATFORM_WASM)
#include <assert.h>
diff --git a/src/input.c b/src/input.c
@@ -1,4 +1,4 @@
-internal inline bool btn_is_down(u32 button_states, enum GameButton b)
+internal bool btn_is_down(u32 button_states, enum GameButton b)
{
assert(b < NUM_GAME_BUTTONS);
bool result = button_states & (1 << b);
diff --git a/src/intrinsics.h b/src/intrinsics.h
@@ -6,7 +6,7 @@
static_assert(__has_builtin(__builtin_clz), "No builtin clz intrinsic");
#define intr_clz(x) __builtin_clz((x))
-internal inline i32 intr_mod(i32 x, i32 y)
+internal i32 intr_mod(i32 x, i32 y)
{
// NOTE(amin): There are multiple valid definitions of an operation that
// gets the remainder of an integer division: `x / y`. Such an operation
diff --git a/src/memory.c b/src/memory.c
@@ -3,7 +3,7 @@
#define mem_move_buffer(d, s, t, c) mem_move((d), (s), sizeof(t) * (c))
// TODO: test that alignment is working properly
-internal inline uintptr_t mem_align_address(uintptr_t address, size_t alignment)
+internal uintptr_t mem_align_address(uintptr_t address, size_t alignment)
{
assert(math_is_pow_2(alignment));
// This works since we've asserted alignment is a power of 2
diff --git a/src/platform_wasm.c b/src/platform_wasm.c
@@ -4,9 +4,6 @@
#include <stddef.h>
#include <stdint.h>
-// TODO: only include this in the non-wasm builds
-#include <math.h>
-
#define static_assert _Static_assert
// Begin terrible libc substitutions
@@ -58,6 +55,33 @@ void *memmove(void *dst, const void *src, size_t n)
static_assert(__has_builtin(__builtin_sqrtf), "No builtin sqrtf builtin");
#define sqrtf(x) __builtin_sqrtf((x))
+
+float js_cosf(float);
+float js_fabsf(float);
+float js_powf(float, float);
+float js_sinf(float);
+float js_tanf(float);
+float js_cosf(float);
+
+float cosf(float x) {
+ return js_cosf(x);
+}
+
+float fabsf(float x) {
+ return js_fabsf(x);
+}
+
+float powf(float x, float y) {
+ return js_powf(x, y);
+}
+
+float sinf(float x) {
+ return js_sinf(x);
+}
+
+float tanf(float x) {
+ return js_tanf(x);
+}
// End terrible libc substitutions
#include "platform_info.h"
diff --git a/src/platform_wasm_js_symbols.txt b/src/platform_wasm_js_symbols.txt
@@ -1,8 +1,16 @@
+js_cosf
+js_fabsf
+js_get_file_size
+js_powf
+js_print
+js_read_entire_file
+js_sinf
+js_tanf
webglActiveTexture
webglAttachShader
webglBindBuffer
-webglBindVertexArray
webglBindTexture
+webglBindVertexArray
webglBlendColor
webglBlendFunc
webglBufferData
@@ -43,6 +51,3 @@ webglUniformMatrix4fv
webglUseProgram
webglVertexAttribPointer
webglViewport
-js_get_file_size
-js_read_entire_file
-js_print
diff --git a/src/platform_wasm_loader.js b/src/platform_wasm_loader.js
@@ -213,6 +213,12 @@ imports["webglVertexAttribPointer"] = function(index, size, type, normalized, st
imports["webglViewport"] = function(x, y, width, height) {
gl.viewport(x, y, width, height);
}
+imports["js_cosf"] = function(x) {
+ return Math.cos(x);
+}
+imports["js_fabsf"] = function(x) {
+ return Math.abs(x);
+}
imports["js_get_file_size"] = function(name, name_len) {
let file_name = utf8decoder.decode(memory.subarray(name, name + name_len))
let file_size = 0;
@@ -222,6 +228,13 @@ imports["js_get_file_size"] = function(name, name_len) {
}
return file_size;
}
+imports["js_powf"] = function(x, y) {
+ return Math.pow(x, y);
+}
+imports["js_print"] = function(s, len) {
+ let arr = memory.subarray(s, s + len);
+ console.log(utf8decoder.decode(arr));
+}
imports["js_read_entire_file"] = function(name, name_len, out_buf) {
let file_name = utf8decoder.decode(memory.subarray(name, name + name_len))
let file_size = 0;
@@ -235,9 +248,11 @@ imports["js_read_entire_file"] = function(name, name_len, out_buf) {
}
return success;
}
-imports["js_print"] = function(s, len) {
- let arr = memory.subarray(s, s + len);
- console.log(utf8decoder.decode(arr));
+imports["js_sinf"] = function(x) {
+ return Math.sin(x);
+}
+imports["js_tanf"] = function(x) {
+ return Math.tan(x);
}
function error_fatal(message) {
console.log(message);
diff --git a/src/webgl.h b/src/webgl.h
@@ -105,7 +105,7 @@ typedef long GLsizeiptr;
// loader)
#define WEBGL_CAST_I32(x) (i32)(x)
-static inline i32 _webgl_strlen(const char *str)
+static i32 _webgl_strlen(const char *str)
{
i32 len = 0;
while(str[len] != '\0')
@@ -115,117 +115,117 @@ static inline i32 _webgl_strlen(const char *str)
return len;
}
-void glActiveTexture(GLenum texture)
+static void glActiveTexture(GLenum texture)
{
webglActiveTexture(WEBGL_CAST_I32(texture));
}
-inline void glAttachShader(GLuint program, GLuint shader)
+static void glAttachShader(GLuint program, GLuint shader)
{
webglAttachShader(WEBGL_CAST_I32(program), WEBGL_CAST_I32(shader));
}
-inline void glBindBuffer(GLenum target, GLuint buffer)
+static void glBindBuffer(GLenum target, GLuint buffer)
{
webglBindBuffer(WEBGL_CAST_I32(target), WEBGL_CAST_I32(buffer));
}
-void glBindTexture(GLenum target, GLuint texture)
+static void glBindTexture(GLenum target, GLuint texture)
{
webglBindTexture(WEBGL_CAST_I32(target), WEBGL_CAST_I32(texture));
}
-inline void glBindVertexArray(GLuint array)
+static void glBindVertexArray(GLuint array)
{
webglBindVertexArray(WEBGL_CAST_I32(array));
}
-inline void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+static void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
webglBlendColor((f32)red, (f32)green, (f32)blue, (f32)alpha);
}
-inline void glBlendFunc(GLenum sfactor, GLenum dfactor)
+static void glBlendFunc(GLenum sfactor, GLenum dfactor)
{
webglBlendFunc(WEBGL_CAST_I32(sfactor), WEBGL_CAST_I32(dfactor));
}
-inline void glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
+static void glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
{
webglBufferData(WEBGL_CAST_I32(target), WEBGL_CAST_I32(size), WEBGL_CAST_I32(data), WEBGL_CAST_I32(usage));
}
-inline void glClear(GLbitfield mask)
+static void glClear(GLbitfield mask)
{
webglClear(WEBGL_CAST_I32(mask));
}
-inline void glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+static void glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
webglClearColor((f32)red, (f32)green, (f32)blue, (f32)alpha);
}
-inline void glCompileShader(GLuint shader)
+static void glCompileShader(GLuint shader)
{
webglCompileShader(WEBGL_CAST_I32(shader));
}
-inline GLuint glCreateProgram(void)
+static GLuint glCreateProgram(void)
{
i32 program_id = webglCreateProgram();
return (GLuint)program_id;
}
-inline GLuint glCreateShader(GLenum type)
+static GLuint glCreateShader(GLenum type)
{
return webglCreateShader(WEBGL_CAST_I32(type));
}
-inline void glDeleteBuffers(GLsizei n, const GLuint *buffers)
+static void glDeleteBuffers(GLsizei n, const GLuint *buffers)
{
assert(n == 1);
i32 the_buffer = WEBGL_CAST_I32(buffers[0]);
webglDeleteBuffer(the_buffer);
}
-inline void glDeleteShader(GLuint shader)
+static void glDeleteShader(GLuint shader)
{
webglDeleteShader(WEBGL_CAST_I32(shader));
}
-inline void glDeleteVertexArrays(GLsizei n, const GLuint *arrays)
+static void glDeleteVertexArrays(GLsizei n, const GLuint *arrays)
{
assert(n == 1);
i32 the_array = WEBGL_CAST_I32(arrays[0]);
webglDeleteVertexArray(the_array);
}
-inline void glDepthMask(GLboolean flag)
+static void glDepthMask(GLboolean flag)
{
webglDepthMask(WEBGL_CAST_I32(flag));
}
-inline void glDisable(GLenum cap)
+static void glDisable(GLenum cap)
{
webglDisable(WEBGL_CAST_I32(cap));
}
-inline void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
+static void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
{
webglDrawElements(WEBGL_CAST_I32(mode), WEBGL_CAST_I32(count), WEBGL_CAST_I32(type), WEBGL_CAST_I32(indices));
}
-inline void glEnable(GLenum cap)
+static void glEnable(GLenum cap)
{
webglEnable(WEBGL_CAST_I32(cap));
}
-inline void glEnableVertexAttribArray(GLuint index)
+static void glEnableVertexAttribArray(GLuint index)
{
webglEnableVertexAttribArray(WEBGL_CAST_I32(index));
}
-inline void glGenBuffers(GLsizei n, GLuint *buffers)
+static void glGenBuffers(GLsizei n, GLuint *buffers)
{
assert(n == 1);
i32 buffer_id = webglCreateBuffer();
@@ -233,19 +233,19 @@ inline void glGenBuffers(GLsizei n, GLuint *buffers)
*buffers = (GLuint)buffer_id;
}
-void glGenerateMipmap(GLenum target)
+static void glGenerateMipmap(GLenum target)
{
webglGenerateMipmap(WEBGL_CAST_I32(target));
}
-void glGenTextures(GLsizei n, GLuint *textures)
+static void glGenTextures(GLsizei n, GLuint *textures)
{
assert(n == 1);
i32 texture_id = webglCreateTexture();
*textures = (GLuint)texture_id;
}
-inline void glGenVertexArrays(GLsizei n, GLuint *arrays)
+static void glGenVertexArrays(GLsizei n, GLuint *arrays)
{
assert(n == 1);
i32 vao_id = webglCreateVertexArray();
@@ -253,56 +253,56 @@ inline void glGenVertexArrays(GLsizei n, GLuint *arrays)
*arrays = (GLuint)vao_id;
}
-inline void glGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog)
+static void glGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog)
{
// TODO: implement
//webglGetProgramInfoLog(WEBGL_CAST_I32(program), WEBGL_CAST_I32(bufsize), WEBGL_CAST_I32(*length), WEBGL_CAST_I32(*infoLog));
}
-inline void glGetProgramiv(GLuint program, GLenum pname, GLint *params)
+static void glGetProgramiv(GLuint program, GLenum pname, GLint *params)
{
*params = webglGetProgramParameter(WEBGL_CAST_I32(program), WEBGL_CAST_I32(pname));
}
-inline void glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog)
+static void glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog)
{
webglGetShaderInfoLog(WEBGL_CAST_I32(shader), infoLog);
}
-inline void glGetShaderiv(GLuint shader, GLenum pname, GLint *params)
+static void glGetShaderiv(GLuint shader, GLenum pname, GLint *params)
{
*params = webglGetShaderParameter(WEBGL_CAST_I32(shader), WEBGL_CAST_I32(pname));
}
-inline GLint glGetUniformLocation(GLuint program, const GLchar *name)
+static GLint glGetUniformLocation(GLuint program, const GLchar *name)
{
i32 name_len = _webgl_strlen(name);
return webglGetUniformLocation(WEBGL_CAST_I32(program), name, name_len);
}
-inline void glLinkProgram(GLuint program)
+static void glLinkProgram(GLuint program)
{
webglLinkProgram(WEBGL_CAST_I32(program));
}
-inline void glPolygonMode(GLenum face, GLenum mode)
+static void glPolygonMode(GLenum face, GLenum mode)
{
// No Op. This doesn't exist in webgl
}
-inline void glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+static void glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
{
webglScissor(WEBGL_CAST_I32(x), WEBGL_CAST_I32(y), WEBGL_CAST_I32(width), WEBGL_CAST_I32(height));
}
-inline void glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
+static void glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
{
const GLchar *s = (void *)*string;
i32 l = _webgl_strlen(s);
webglShaderSource(WEBGL_CAST_I32(shader), s, l);
}
-void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)
+static void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels)
{
webglTexImage2D(
WEBGL_CAST_I32(target),
@@ -316,7 +316,7 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei widt
WEBGL_CAST_I32(pixels));
}
-void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels)
+static void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels)
{
webglTexImage3D(
WEBGL_CAST_I32(target),
@@ -331,52 +331,52 @@ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei widt
WEBGL_CAST_I32(pixels));
}
-void glTexParameteri(GLenum target, GLenum pname, GLint param)
+static void glTexParameteri(GLenum target, GLenum pname, GLint param)
{
webglTexParameteri(WEBGL_CAST_I32(target), WEBGL_CAST_I32(pname), WEBGL_CAST_I32(param));
}
-void glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
+static void glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{
webglTexStorage3D(target, levels, internalformat, width, height, depth);
}
-void glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)
+static void glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)
{
webglTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, WEBGL_CAST_I32(pixels));
}
-inline void glUniform1f(GLint location, GLfloat v0)
+static void glUniform1f(GLint location, GLfloat v0)
{
webglUniform1f(WEBGL_CAST_I32(location), (f32)v0);
}
-inline void glUniform1i(GLint location, GLint v0)
+static void glUniform1i(GLint location, GLint v0)
{
webglUniform1i(WEBGL_CAST_I32(location), WEBGL_CAST_I32(v0));
}
-inline void glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+static void glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
{
webglUniform3f(WEBGL_CAST_I32(location), (f32)v0, (f32)v1, (f32)v2);
}
-inline void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
+static void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
webglUniformMatrix4fv(WEBGL_CAST_I32(location), WEBGL_CAST_I32(transpose), value);
}
-inline void glUseProgram(GLuint program)
+static void glUseProgram(GLuint program)
{
webglUseProgram(WEBGL_CAST_I32(program));
}
-inline void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer)
+static void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer)
{
webglVertexAttribPointer(WEBGL_CAST_I32(index), WEBGL_CAST_I32(size), WEBGL_CAST_I32(type), WEBGL_CAST_I32(normalized), WEBGL_CAST_I32(stride), WEBGL_CAST_I32(pointer));
}
-inline void glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+static void glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
{
webglViewport(x, y, WEBGL_CAST_I32(width), WEBGL_CAST_I32(height));
}
diff --git a/src/world.c b/src/world.c
@@ -29,7 +29,7 @@ internal struct AbsolutePos world_pos_recanonicalize(struct AbsolutePos p)
return p_final;
}
-internal inline v2 world_tile_get_sw_corner(v2 tile_center_pos)
+internal v2 world_tile_get_sw_corner(v2 tile_center_pos)
{
v2 tile_sw_corner = {
.x = tile_center_pos.x - (TILE_SIZE * 0.5f),
@@ -38,7 +38,7 @@ internal inline v2 world_tile_get_sw_corner(v2 tile_center_pos)
return tile_sw_corner;
}
-internal inline v2 world_tile_get_center(v2 tile_sw_corner_pos)
+internal v2 world_tile_get_center(v2 tile_sw_corner_pos)
{
v2 tile_center = {
.x = tile_sw_corner_pos.x + (TILE_SIZE * 0.5f),
@@ -63,7 +63,7 @@ internal struct AbsolutePos world_tile_pos_recanonicalize(struct AbsolutePos til
return tile_canonical_pos;
}
-internal inline v2i world_room_get_chunk_index(v2i room_i)
+internal v2i world_room_get_chunk_index(v2i room_i)
{
// NOTE(amin): truncated integer division here is intentional. We want a
// square of CHUNK_NUM_ROOMS rooms to all have the same chunk index.
@@ -175,7 +175,7 @@ internal size_t world_room_get_index_within_chunk(v2i room_i)
return room_i_within_chunk;
}
-internal inline bool world_room_is_initialized(struct Room *room)
+internal bool world_room_is_initialized(struct Room *room)
{
bool is_initialized = false;
if (room->index.y != ROOM_UNINITIALIZED_Y_VALUE)