1
0
Fork 0

Revert: resize for web version working

This commit is contained in:
zongor 2026-02-13 21:27:07 -08:00
parent 9d60a9753e
commit 8f55ac7c86
4 changed files with 142 additions and 79 deletions

View File

@ -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 \

View File

@ -60,32 +60,7 @@ 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;
}

View File

@ -33,59 +33,106 @@ static ScreenDeviceData screen_data = {0};
static MouseDeviceData mouse_data = {0};
static ConsoleDeviceData console_data = {0};
static bool display_size_changed = false;
// The callback:
static EM_BOOL on_web_display_size_changed( int event_type,
const EmscriptenUiEvent *event, void *user_data )
{
display_size_changed = 1; // custom global flag
return 0;
}
void scale_mouse_pos(u32 mouse_x, u32 mouse_y, u32 *vm_x, u32 *vm_y) {
int win_w, win_h;
SDL_GetWindowSize(screen_data.window, &win_w, &win_h);
f32 scale_x = (f32)win_w / screen_data.width;
f32 scale_y = (f32)win_h / screen_data.height;
f32 scale = SDL_min(scale_x, scale_y);
u32 dst_w = (u32)(screen_data.width * scale);
u32 dst_h = (u32)(screen_data.height * scale);
u32 dst_x = (win_w - dst_w) / 2;
u32 dst_y = (win_h - dst_h) / 2;
f32 rel_x = (f32)(mouse_x - dst_x);
f32 rel_y = (f32)(mouse_y - dst_y);
*vm_x = (u32)((rel_x / (f32)dst_w) * screen_data.width);
*vm_y = (u32)((rel_y / (f32)dst_h) * screen_data.height);
if (*vm_x >= screen_data.width) *vm_x = screen_data.width - 1;
if (*vm_y >= screen_data.height) *vm_y = screen_data.height - 1;
}
void mainloop() {
SDL_Event event;
SDL_PumpEvents();
while (SDL_PollEvent(&event)) {
switch (event.type) {
// Mouse events
case SDL_MOUSEMOTION:
mouse_data.x = event.motion.x;
mouse_data.y = event.motion.y;
break;
case SDL_MOUSEBUTTONDOWN:
if (event.button.button == SDL_BUTTON_LEFT)
mouse_data.btn1 = 1;
if (event.button.button == SDL_BUTTON_RIGHT)
mouse_data.btn2 = 1;
if (event.button.button == SDL_BUTTON_MIDDLE)
mouse_data.btn3 = 1;
if (event.button.button == SDL_BUTTON_X1)
mouse_data.btn4 = 1;
break;
case SDL_MOUSEBUTTONUP:
if (event.button.button == SDL_BUTTON_LEFT)
mouse_data.btn1 = 0;
if (event.button.button == SDL_BUTTON_RIGHT)
mouse_data.btn2 = 0;
if (event.button.button == SDL_BUTTON_MIDDLE)
mouse_data.btn3 = 0;
if (event.button.button == SDL_BUTTON_X1)
mouse_data.btn4 = 0;
break;
case SDL_FINGERMOTION:
case SDL_FINGERDOWN:
case SDL_FINGERUP: {
float x = event.tfinger.x * 640;
float y = event.tfinger.y * 480;
mouse_data.x = (int)x;
mouse_data.y = (int)y;
if (event.tfinger.fingerId == 0) {
if (event.type == SDL_FINGERDOWN || event.type == SDL_FINGERMOTION) {
mouse_data.btn1 = 1;
} else if (event.type == SDL_FINGERUP) {
mouse_data.btn1 = 0;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_WINDOWEVENT:{
switch (event.window.event) {
case SDL_WINDOWEVENT_RESIZED:
screen_data.update = true;
break;
}
break;
}
case SDL_MOUSEMOTION: {
u32 vm_x, vm_y;
scale_mouse_pos(event.motion.x, event.motion.y, &vm_x, &vm_y);
mouse_data.x = vm_x;
mouse_data.y = vm_y;
break;
}
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP: {
u32 vm_x, vm_y;
scale_mouse_pos(event.button.x, event.button.y, &vm_x, &vm_y);
mouse_data.x = vm_x;
mouse_data.y = vm_y;
bool pressed = (event.type == SDL_MOUSEBUTTONDOWN);
if (event.button.button == SDL_BUTTON_LEFT) mouse_data.btn1 = pressed;
if (event.button.button == SDL_BUTTON_RIGHT) mouse_data.btn2 = pressed;
if (event.button.button == SDL_BUTTON_MIDDLE) mouse_data.btn3 = pressed;
if (event.button.button == SDL_BUTTON_X1) mouse_data.btn4 = pressed;
break;
}
case SDL_FINGERMOTION:
case SDL_FINGERDOWN:
case SDL_FINGERUP: {
int win_w, win_h;
SDL_GetWindowSize(screen_data.window, &win_w, &win_h);
u32 touch_pixel_x = (u32)(event.tfinger.x * win_w);
u32 touch_pixel_y = (u32)(event.tfinger.y * win_h);
u32 vm_x, vm_y;
scale_mouse_pos(touch_pixel_x, touch_pixel_y, &vm_x, &vm_y);
mouse_data.x = vm_x;
mouse_data.y = vm_y;
if (event.tfinger.fingerId == 0) {
bool pressed = (event.type == SDL_FINGERDOWN || event.type == SDL_FINGERMOTION);
mouse_data.btn1 = pressed ? 1 : 0;
}
break;
}
}
break;
}
}
// In the emscripten_set_main_loop() callback:
if (display_size_changed)
{
double w, h;
emscripten_get_element_css_size( "#canvas", &w, &h );
SDL_SetWindowSize( screen_data.window, (int)w, (int) h );
display_size_changed = 0;
}
int cycles_this_frame = 0;
@ -100,8 +147,26 @@ void mainloop() {
if (screen_data.update) {
if (screen_data.renderer && screen_data.texture) {
SDL_RenderCopy(screen_data.renderer, screen_data.texture, NULL, NULL);
SDL_RenderPresent(screen_data.renderer);
// Clear and render
SDL_RenderClear(screen_data.renderer);
int window_w, window_h;
SDL_GetWindowSize(screen_data.window, &window_w, &window_h);
// Calculate aspect ratio preserving scaling
f32 scale_x = (f32)window_w / screen_data.width;
f32 scale_y = (f32)window_h / screen_data.height;
f32 scale = SDL_min(scale_x, scale_y);
SDL_Rect dstrect = {
(i32)((window_w - screen_data.width * scale) / 2),
(i32)((window_h - screen_data.height * scale) / 2),
(i32)(screen_data.width * scale),
(i32)(screen_data.height * scale)};
SDL_RenderCopy(screen_data.renderer, screen_data.texture, NULL,
&dstrect);
SDL_RenderPresent(screen_data.renderer);
}
screen_data.update = false;
}
@ -148,6 +213,7 @@ int main(int argc, char **argv) {
return 1;
}
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
#ifdef __EMSCRIPTEN__
emscripten_set_canvas_element_size("#canvas", 640, 480);
@ -160,9 +226,24 @@ 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("Reality Engine VM", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, 640, 480,
SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
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;
}
mouse_data.x = 0;
mouse_data.y = 0;
@ -179,6 +260,11 @@ int main(int argc, char **argv) {
vm_register_device(&vm, "/dev/term/0", "terminal", &console_data,
&console_device_ops, 4);
emscripten_set_resize_callback(
EMSCRIPTEN_EVENT_TARGET_WINDOW,
0, 0, on_web_display_size_changed
);
emscripten_set_main_loop(mainloop, 0, 1);
return 0;
}

View File

@ -208,8 +208,9 @@
<input type="checkbox" id="resize">Resize canvas
<input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer
&nbsp;&nbsp;&nbsp;
<input type="button" value="Fullscreen" onclick="Module.requestFullscreen(document.getElementById('pointerLock').checked,
<span><input type="button" value="Fullscreen" onclick="Module.canvas.requestFullscreen(document.getElementById('pointerLock').checked,
document.getElementById('resize').checked)">
</span>
</div>
<hr/>