From f516f0fbe7787fa15ae8006f51b51a9b154d1fc8 Mon Sep 17 00:00:00 2001 From: zongor Date: Sat, 14 Feb 2026 10:16:37 -0800 Subject: [PATCH] Add ability to screenshot canvas --- Makefile | 9 ++++--- src/arch/emscripten/devices.c | 26 ------------------- src/arch/emscripten/main.c | 35 ++++++++++++++++++++++---- src/arch/emscripten/shell_minimal.html | 15 +++++++++-- 4 files changed, 48 insertions(+), 37 deletions(-) diff --git a/Makefile b/Makefile index 3302df2..fd48781 100644 --- a/Makefile +++ b/Makefile @@ -39,8 +39,8 @@ endif # --- MODE & PLATFORM SPECIFIC FLAGS --- ifeq ($(BUILD_MODE), release) - CORE_CFLAGS += -Ofast -DNDEBUG - PLATFORM_CFLAGS += -Ofast -DNDEBUG + CORE_CFLAGS += -O3 -DNDEBUG + PLATFORM_CFLAGS += -O3 -DNDEBUG LDFLAGS += -s TARGET_SUFFIX := -release else @@ -58,6 +58,7 @@ endif # --- EMSCRIPTEN-SPECIFIC --- ifeq ($(PLATFORM), emscripten) + PLATFORM_CFLAGS += -s USE_SDL=2 LDFLAGS += -s USE_SDL=2\ -s ASYNCIFY \ -s ALLOW_MEMORY_GROWTH=1 \ @@ -66,8 +67,8 @@ ifeq ($(PLATFORM), emscripten) # For release: optimize, strip debug, minimize size ifeq ($(BUILD_MODE), release) - PLATFORM_CFLAGS += -O2 - LDFLAGS += -O2 + PLATFORM_CFLAGS += -O3 + LDFLAGS += -O3 endif # Output: HTML + JS + WASM diff --git a/src/arch/emscripten/devices.c b/src/arch/emscripten/devices.c index 4d667b1..7f15f2c 100644 --- a/src/arch/emscripten/devices.c +++ b/src/arch/emscripten/devices.c @@ -60,32 +60,6 @@ i32 screen_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) { memcpy(&info[8], &screen->height, sizeof(u32)); memcpy(&info[12], &screen->buffer_size, sizeof(u32)); screen->screen_buffer = (u8*)(buffer + 16); - - screen->window = - SDL_CreateWindow("Reality Engine VM", SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, screen->width, screen->height, - SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI); - - if (!screen->window) { - return -1; - } - - screen->renderer = - SDL_CreateRenderer(screen->window, -1, SDL_RENDERER_ACCELERATED); - if (!screen->renderer) { - return -1; - } - - screen->texture = SDL_CreateTexture(screen->renderer, SDL_PIXELFORMAT_RGB332, - SDL_TEXTUREACCESS_STREAMING, - screen->width, screen->height); - - if (!screen->texture) { - fprintf(stderr, "SDL_CreateTexture failed: %s\n", SDL_GetError()); - return -1; - } - - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); return 0; } diff --git a/src/arch/emscripten/main.c b/src/arch/emscripten/main.c index 3f5b882..762913e 100644 --- a/src/arch/emscripten/main.c +++ b/src/arch/emscripten/main.c @@ -2,6 +2,7 @@ #include "../../vm/vm.h" #include "devices.h" #include +#include #include #include #include @@ -147,9 +148,11 @@ int main(int argc, char **argv) { } SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0"); -#ifdef __EMSCRIPTEN__ + EmscriptenWebGLContextAttributes attributes; + attributes.preserveDrawingBuffer = true; + int handle = emscripten_webgl_create_context("#canvas", &attributes); + emscripten_webgl_make_context_current(handle); emscripten_set_canvas_element_size("#canvas", 640, 480); -#endif loadVM("paint.rom", &vm); printf("VM loaded successfully\n"); @@ -158,9 +161,31 @@ int main(int argc, char **argv) { screen_data.width = 640; screen_data.height = 480; screen_data.buffer_size = screen_data.width * screen_data.height; - screen_data.window = NULL; - screen_data.renderer = NULL; - screen_data.texture = NULL; + screen_data.window = + SDL_CreateWindow("uPaint", SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, screen_data.width, screen_data.height, + SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI); + + if (!screen_data.window) { + return -1; + } + + screen_data.renderer = + SDL_CreateRenderer(screen_data.window, -1, SDL_RENDERER_ACCELERATED); + if (!screen_data.renderer) { + return -1; + } + + screen_data.texture = SDL_CreateTexture(screen_data.renderer, SDL_PIXELFORMAT_RGB332, + SDL_TEXTUREACCESS_STREAMING, + screen_data.width, screen_data.height); + + if (!screen_data.texture) { + fprintf(stderr, "SDL_CreateTexture failed: %s\n", SDL_GetError()); + return -1; + } + + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); mouse_data.x = 0; mouse_data.y = 0; diff --git a/src/arch/emscripten/shell_minimal.html b/src/arch/emscripten/shell_minimal.html index 8a8c6db..160231b 100644 --- a/src/arch/emscripten/shell_minimal.html +++ b/src/arch/emscripten/shell_minimal.html @@ -208,8 +208,9 @@ Resize canvas Lock/hide mouse pointer     - + +
@@ -223,6 +224,16 @@ var outputElement = document.getElementById('output'); if (outputElement) outputElement.value = ''; // clear browser cache + document.getElementById('screenshot').addEventListener('click', function() { + const dataURL = canvasElement.toDataURL('image/png'); + const link = document.createElement('a'); + link.href = dataURL; + link.download = 'screenshot.png'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }); + // As a default initial behavior, pop up an alert when webgl context is lost. To make your // application robust, you may want to override this behavior before shipping! // See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2