1
0
Fork 0

add device scaling

This commit is contained in:
zongor 2026-02-12 23:53:38 -08:00
parent 5e73aa2cba
commit 9d60a9753e
3 changed files with 68 additions and 45 deletions

View File

@ -69,7 +69,7 @@ i32 screen_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) {
screen->window =
SDL_CreateWindow("Reality Engine VM", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, screen->width, screen->height,
SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
if (!screen->window) {
return -1;
@ -90,7 +90,6 @@ i32 screen_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) {
return -1;
}
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
return 0;
}

View File

@ -210,6 +210,29 @@ bool assembleAndSave(const char *source_file, const char *output_file, VM *vm) {
return true;
}
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;
}
i32 main(i32 argc, char *argv[]) {
bool dump_rom = false;
char *input_file = nil;
@ -294,6 +317,7 @@ i32 main(i32 argc, char *argv[]) {
return 1;
}
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
screen_data.width = 640;
screen_data.height = 480;
@ -324,53 +348,54 @@ i32 main(i32 argc, char *argv[]) {
case SDL_QUIT:
running = false;
break;
// Mouse events
case SDL_MOUSEMOTION:
mouse_data.x = event.motion.x;
mouse_data.y = event.motion.y;
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:
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: {
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;
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;
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;
// Touch events (map to mouse_data as left-click equivalent)
}
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);
f32 x = event.tfinger.x * 640;
f32 y = event.tfinger.y * 480;
u32 vm_x, vm_y;
scale_mouse_pos(touch_pixel_x, touch_pixel_y, &vm_x, &vm_y);
mouse_data.x = (i32)x;
mouse_data.y = (i32)y;
mouse_data.x = vm_x;
mouse_data.y = vm_y;
// Only treat the first finger as mouse input (ignore multi-touch
// beyond 1 finger)
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;
}
bool pressed = (event.type == SDL_FINGERDOWN || event.type == SDL_FINGERMOTION);
mouse_data.btn1 = pressed ? 1 : 0;
}
break;
}
@ -395,17 +420,17 @@ i32 main(i32 argc, char *argv[]) {
// Clear and render
SDL_RenderClear(screen_data.renderer);
SDL_Rect output_rect;
SDL_RenderGetViewport(screen_data.renderer, &output_rect);
int window_w, window_h;
SDL_GetWindowSize(screen_data.window, &window_w, &window_h);
// Calculate aspect ratio preserving scaling
f32 scale_x = (f32)output_rect.w / screen_data.width;
f32 scale_y = (f32)output_rect.h / screen_data.height;
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)((output_rect.w - screen_data.width * scale) / 2),
(i32)((output_rect.h - screen_data.height * scale) / 2),
(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)};

View File

@ -126,7 +126,6 @@ typedef struct device_ops_s {
i32 (*refresh)(void *device_data, u8 *buffer);
} DeviceOps;
typedef struct device_s {
const char *type; /* e.g., "screen", "mouse", "gpio" */
const char *path; /* "/dev/screen", "/dev/input/mouse/0", etc. */