add device scaling
This commit is contained in:
parent
5e73aa2cba
commit
9d60a9753e
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)};
|
||||
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue