From 26f6ba56e97050d267a4435cbbb16a1984a7d241 Mon Sep 17 00:00:00 2001 From: veclavtlica Date: Mon, 14 Sep 2026 02:04:16 +0300 Subject: [PATCH] web? --- .gitignore | 1 + Common/bits.h | 1 - Common/def.h | 13 ++++++ Common/fix.c | 9 ++++- Common/fix.h | 1 - Common/gem.h | 3 +- Common/lzw.c | 8 +++- Common/mat.h | 1 - Common/std.h | 4 ++ Player/Display/x11.c | 58 +-------------------------- Player/{main.c => Main/linux.c} | 2 +- Player/Makefile | 21 +++++++--- Player/amalgam.c | 8 ++++ Player/draw.c | 70 +++++++++++++++++++++++++++++++++ Player/draw.h | 8 ++++ Player/index.html | 42 ++++++++++++++++++++ 16 files changed, 178 insertions(+), 72 deletions(-) create mode 100644 Common/std.h rename Player/{main.c => Main/linux.c} (73%) create mode 100644 Player/amalgam.c create mode 100644 Player/draw.c create mode 100644 Player/draw.h create mode 100644 Player/index.html diff --git a/.gitignore b/.gitignore index 7b75259..f506ee1 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ *.sublime-* Player/player +Player/player.wasm Master/master diff --git a/Common/bits.h b/Common/bits.h index 8ba5c87..ae84e6a 100644 --- a/Common/bits.h +++ b/Common/bits.h @@ -2,7 +2,6 @@ #define COM_BITS_H #include "def.h" -#include #include /* How many bits needed to represent a given number */ diff --git a/Common/def.h b/Common/def.h index 993d6a1..5545557 100644 --- a/Common/def.h +++ b/Common/def.h @@ -10,6 +10,19 @@ #define COM_DEF_COMPILE_MODERN 1 #endif +#define COM_DEF_TARGET_NATIVE 0 +#define COM_DEF_TARGET_WASM 1 + +#if defined(__wasm__) +#define COM_DEF_NOSTD 1 +#define COM_DEF_TARGET COM_DEF_TARGET_WASM +/* TODO: Move to std.h instead, forbid stdlib on any platform. */ +#define assert(m_t) (m_t) +#define printf(...) ((void)0) +#else +#define COM_DEF_TARGET COM_DEF_TARGET_NATIVE +#endif + /* TODO: uppercase? */ #ifdef COM_DEF_COMPILE_MODERN #define com_def_alignedas(v_as) _Alignas(v_as) diff --git a/Common/fix.c b/Common/fix.c index f68ad92..73cefc0 100644 --- a/Common/fix.c +++ b/Common/fix.c @@ -3,14 +3,17 @@ https://github.com/howerj/q/blob/master/q.c */ +#include "fix.h" #include "Timer/timer.h" #include "def.h" -#include "fix.h" -#include #include #include + +#ifndef COM_DEF_NOSTD +#include #include #include +#endif // 4-bit LUT (16 entries) for the normalized range [0.5, 2.0) // It stores the initial guess scaled to Q16.16. @@ -130,6 +133,7 @@ void com_fix_run_bench(void) { } void com_fix_run_tests(void) { +#ifndef COM_DEF_NOSTD { double max_sqrt_deviation = 0.0f; com_fix_t sqrt_accumulator = 0; @@ -196,4 +200,5 @@ void com_fix_run_tests(void) { printf("max sincos deviations: %f %f\n", max_sin_deviation, max_cos_deviation); } +#endif } diff --git a/Common/fix.h b/Common/fix.h index 1f4ba9e..db55000 100644 --- a/Common/fix.h +++ b/Common/fix.h @@ -7,7 +7,6 @@ #define COM_FIX_H #include -#include #define COM_FIX_FRACBITS 16 #define COM_FIX_FRACUNIT (1 << COM_FIX_FRACBITS) diff --git a/Common/gem.h b/Common/gem.h index 49e5963..84611d6 100644 --- a/Common/gem.h +++ b/Common/gem.h @@ -50,7 +50,7 @@ static inline com_vec_t com_gem_vec_project_clip(com_mat_t a, com_vec_t b) { * outside of view. Bit test against those per component. This is needed for * determining new view-lying clipped triangles. */ static inline uint8_t com_gem_clip_vis_project(com_vec_t a, com_pnt_t *out) { - uint8_t mask; + uint8_t mask = 0; if (a.s.x < -a.s.z || a.s.x > a.s.z) mask ^= COM_GEM_VERTEX_CLIPPED_X; if (a.s.y < -a.s.z || a.s.y > a.s.z) @@ -77,7 +77,6 @@ static inline void com_gem_draw_triangle(com_pnt_t v0, com_pnt_t v1, // If the point is inside or on all edges, draw the pixel // (Assumes Clockwise vertex ordering) if (ws.a[0] >= 0 && ws.a[1] >= 0 && ws.a[2] >= 0) { - printf("%i, %i\n", y, x); out[(y * 640 + x) * 4 + 0] = 125; out[(y * 640 + x) * 4 + 1] = 125; out[(y * 640 + x) * 4 + 2] = 125; diff --git a/Common/lzw.c b/Common/lzw.c index 25cb062..80faf62 100644 --- a/Common/lzw.c +++ b/Common/lzw.c @@ -5,12 +5,16 @@ #include "lzw.h" #include "bits.h" -#include #include #include #include -#include + +#ifndef COM_DEF_NOSTD +#include #include +#else +#include "std.h" +#endif /* References: */ /* https://www.w3.org/Graphics/GIF/spec-gif89a.txt */ diff --git a/Common/mat.h b/Common/mat.h index 85c0195..d4082e7 100644 --- a/Common/mat.h +++ b/Common/mat.h @@ -20,7 +20,6 @@ #include "fix.h" #include "vec.h" #include -#include typedef union { com_def_alignedas(64) com_def_vector(com_fix_t, a, 4 * 4); diff --git a/Common/std.h b/Common/std.h new file mode 100644 index 0000000..670d47e --- /dev/null +++ b/Common/std.h @@ -0,0 +1,4 @@ + +/* TODO: Actually implement. */ +#define realloc(m_p, m_b) (NULL) +#define free(m_p) ((void)0) diff --git a/Player/Display/x11.c b/Player/Display/x11.c index f012a43..aff1d1c 100644 --- a/Player/Display/x11.c +++ b/Player/Display/x11.c @@ -7,9 +7,9 @@ #include #include -#include "../../Common/gem.h" #include "../../Common/lzw.h" #include "../../Common/mat.h" +#include "../draw.h" #include "display.h" bool quited = false; @@ -121,62 +121,8 @@ extern int plr_display_x11_main(int argc, char *argv[]) { case Expose: frame += 2; - // Fill buffer with a simple color gradient - for (int y = 0; y < HEIGHT; y++) { - for (int x = 0; x < WIDTH; x++) { - int pixel_index = (y * WIDTH + x) * bytes_per_pixel; - // Assuming standard Little-Endian 32-bit BGRA format - pixel_buffer[pixel_index + 0] = (x + frame) % 256; // Blue - pixel_buffer[pixel_index + 1] = (y + frame) % 256; // Green - pixel_buffer[pixel_index + 2] = (x + y - frame) % 256; // Red - pixel_buffer[pixel_index + 3] = 0; // Alpha/Padding - } - } - - com_mat_t proj = com_mat_perspective(640, 480, 1, 100 * COM_FIX_FRACUNIT, - COM_FIX_PIHALF); - com_mat_t view = com_mat_look_at(com_vec_from(0, 0, 0), - com_vec_from(0, COM_FIX_FRACUNIT, 0), - com_vec_from(-COM_FIX_FRACUNIT, 0, 0)); - com_mat_t mvp = com_mat_reoder(com_mat_mul(proj, view)); - - com_vec_t v0 = - com_vec_from(5 * COM_FIX_FRACUNIT, 0, 2 * COM_FIX_FRACUNIT); - com_vec_t v1 = com_vec_from(5 * COM_FIX_FRACUNIT, 1 * COM_FIX_FRACUNIT, - 4 * COM_FIX_FRACUNIT); - com_vec_t v2 = com_vec_from(5 * COM_FIX_FRACUNIT, 4 * COM_FIX_FRACUNIT, - 4 * COM_FIX_FRACUNIT); - - com_pnt_t uv0 = com_pnt_from(0 * COM_FIX_FRACUNIT, 0 * COM_FIX_FRACUNIT); - com_pnt_t uv1 = com_pnt_from(1 * COM_FIX_FRACUNIT, 0 * COM_FIX_FRACUNIT); - com_pnt_t uv2 = com_pnt_from(1 * COM_FIX_FRACUNIT, 1 * COM_FIX_FRACUNIT); - - com_vec_t c0 = com_gem_vec_project_clip(mvp, v0); - com_vec_t c1 = com_gem_vec_project_clip(mvp, v1); - com_vec_t c2 = com_gem_vec_project_clip(mvp, v2); - - com_pnt_t p0, p1, p2; - uint8_t cc0 = com_gem_clip_vis_project(c0, &p0); - uint8_t cc1 = com_gem_clip_vis_project(c1, &p1); - uint8_t cc2 = com_gem_clip_vis_project(c2, &p2); - - com_pnt_print(p0); - com_pnt_print(p1); - com_pnt_print(p2); - - uint8_t tex[32 * 32 * 3] = {0}; - for (int y = 0; y < 32; ++y) { - for (int x = 0; x < 32; ++x) { - tex[(y * 32 + x) * 3 + 0] = (x / 2 + y / 2) % 2 == 0 ? 175 : 0; - tex[(y * 32 + x) * 3 + 1] = (x / 2 + y / 2) % 2 == 0 ? 0 : 0; - tex[(y * 32 + x) * 3 + 2] = (x / 2 + y / 2) % 2 == 0 ? 175 : 0; - } - } - - com_gem_draw_triangle_textured(p0, p1, p2, (uint8_t *)pixel_buffer, uv0, - uv1, uv2, tex); - // com_gem_draw_triangle(p0, p1, p2, (uint8_t *)pixel_buffer); + plr_draw_screen((uint8_t *)pixel_buffer); // Draw the complete image onto the window when exposed XPutImage(display, diff --git a/Player/main.c b/Player/Main/linux.c similarity index 73% rename from Player/main.c rename to Player/Main/linux.c index 0110ad1..98e0d78 100644 --- a/Player/main.c +++ b/Player/Main/linux.c @@ -1,4 +1,4 @@ -#include "Display/display.h" +#include "../Display/display.h" extern int main(int argc, char *argv[]) { return plr_display_x11_main(argc, argv); diff --git a/Player/Makefile b/Player/Makefile index 03531a6..3753c97 100644 --- a/Player/Makefile +++ b/Player/Makefile @@ -1,20 +1,29 @@ -CC=clang +CC = clang # todo: Only link to libm on debug. -CFLAGS=-lX11 -Wall -std=c99 -g3 -O3 -msse2 -lm +CFLAGS = -Wall -std=c99 -g3 -O3 DEPS = ../Common/lzw.h ../Common/mat.h ../Common/vec.h ../Common/fix.h ../Common/def.h ../Common/bits.h \ ../Common/gem.h \ ../Common/Timer/timer.h \ - ./Display/display.h -OBJ = ../Common/lzw.o ../Common/fix.o ../Common/mat.o -LINUX = main.o Display/x11.o ../Common/Timer/unix.o + ./Display/display.h \ + ./draw.h +SRC = ../Common/lzw.c ../Common/fix.c ../Common/mat.c ./draw.c +OBJ = ../Common/lzw.o ../Common/fix.o ../Common/mat.o ./draw.o +LINUX = ./Main/linux.o ./amalgam.o Display/x11.o ../Common/Timer/unix.o +WASM = ./amalgam.c DOS = maindos.c Display/dos.c %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) -linux: $(LINUX) $(OBJ) +linux: CFLAGS += -msse2 -lm -lX11 +linux: $(LINUX) | $(SRC) $(CC) -o player $^ $(CFLAGS) +# Note: lld package might need to be downloaded. +wasm: CFLAGS += --target=wasm32 -nostdlib -Wl,--no-entry +wasm: + $(CC) -o player.wasm $(WASM) $(CFLAGS) + dos: $(DOS) $(DEPS) wcl386 -bt=dos4g -ox -l=dos4g $(DOS) diff --git a/Player/amalgam.c b/Player/amalgam.c new file mode 100644 index 0000000..4c15404 --- /dev/null +++ b/Player/amalgam.c @@ -0,0 +1,8 @@ +/* + Amalgamation file, compiling all in single unit. +*/ + +#include "../Common/fix.c" +#include "../Common/lzw.c" +#include "../Common/mat.c" +#include "./draw.c" diff --git a/Player/draw.c b/Player/draw.c new file mode 100644 index 0000000..ff29427 --- /dev/null +++ b/Player/draw.c @@ -0,0 +1,70 @@ + +#include "../Common/def.h" +#include "../Common/gem.h" +#include + +#if COM_DEF_TARGET == COM_DEF_TARGET_WASM +uint8_t plr_draw_buffer[640 * 480 * 4]; + +__attribute__((export_name("plr_draw_get_pixel_buffer"))) uint8_t * +plr_draw_get_pixel_buffer(void) { + return plr_draw_buffer; +} +#endif + +__attribute__((export_name("plr_draw_screen"))) void +plr_draw_screen(uint8_t *pixel_buffer) { + for (int y = 0; y < 480; y++) { + for (int x = 0; x < 640; x++) { + int pixel_index = (y * 640 + x) * 4; + + // Assuming standard Little-Endian 32-bit BGRA format + pixel_buffer[pixel_index + 0] = (x) % 256; // Blue + pixel_buffer[pixel_index + 1] = (y) % 256; // Green + pixel_buffer[pixel_index + 2] = (x + y) % 256; // Red + pixel_buffer[pixel_index + 3] = 255; // Alpha/Padding + } + } + + com_mat_t proj = + com_mat_perspective(640, 480, 1, 100 * COM_FIX_FRACUNIT, COM_FIX_PIHALF); + com_mat_t view = com_mat_look_at(com_vec_from(0, 0, 0), + com_vec_from(0, COM_FIX_FRACUNIT, 0), + com_vec_from(-COM_FIX_FRACUNIT, 0, 0)); + com_mat_t mvp = com_mat_reoder(com_mat_mul(proj, view)); + + com_vec_t v0 = com_vec_from(5 * COM_FIX_FRACUNIT, 0, 2 * COM_FIX_FRACUNIT); + com_vec_t v1 = com_vec_from(5 * COM_FIX_FRACUNIT, 1 * COM_FIX_FRACUNIT, + 4 * COM_FIX_FRACUNIT); + com_vec_t v2 = com_vec_from(5 * COM_FIX_FRACUNIT, 4 * COM_FIX_FRACUNIT, + 4 * COM_FIX_FRACUNIT); + + com_pnt_t uv0 = com_pnt_from(0 * COM_FIX_FRACUNIT, 0 * COM_FIX_FRACUNIT); + com_pnt_t uv1 = com_pnt_from(1 * COM_FIX_FRACUNIT, 0 * COM_FIX_FRACUNIT); + com_pnt_t uv2 = com_pnt_from(1 * COM_FIX_FRACUNIT, 1 * COM_FIX_FRACUNIT); + + com_vec_t c0 = com_gem_vec_project_clip(mvp, v0); + com_vec_t c1 = com_gem_vec_project_clip(mvp, v1); + com_vec_t c2 = com_gem_vec_project_clip(mvp, v2); + + com_pnt_t p0, p1, p2; + uint8_t cc0 = com_gem_clip_vis_project(c0, &p0); + uint8_t cc1 = com_gem_clip_vis_project(c1, &p1); + uint8_t cc2 = com_gem_clip_vis_project(c2, &p2); + + com_pnt_print(p0); + com_pnt_print(p1); + com_pnt_print(p2); + + uint8_t tex[32 * 32 * 3] = {0}; + for (int y = 0; y < 32; ++y) { + for (int x = 0; x < 32; ++x) { + tex[(y * 32 + x) * 3 + 0] = (x / 2 + y / 2) % 2 == 0 ? 175 : 0; + tex[(y * 32 + x) * 3 + 1] = (x / 2 + y / 2) % 2 == 0 ? 0 : 0; + tex[(y * 32 + x) * 3 + 2] = (x / 2 + y / 2) % 2 == 0 ? 175 : 0; + } + } + + com_gem_draw_triangle_textured(p0, p1, p2, (uint8_t *)pixel_buffer, uv0, uv1, + uv2, tex); +} diff --git a/Player/draw.h b/Player/draw.h new file mode 100644 index 0000000..c7bb5f0 --- /dev/null +++ b/Player/draw.h @@ -0,0 +1,8 @@ +#ifndef PLR_DRAW_H +#define PLR_DRAW_H + +#include + +extern void plr_draw_screen(uint8_t *pixel_buffer); + +#endif diff --git a/Player/index.html b/Player/index.html new file mode 100644 index 0000000..2547474 --- /dev/null +++ b/Player/index.html @@ -0,0 +1,42 @@ + + + + + Brightstone + + + + + + +