resize for web version working
This commit is contained in:
parent
9d60a9753e
commit
71f7492fe7
1
Makefile
1
Makefile
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -208,8 +208,9 @@
|
|||
<input type="checkbox" id="resize">Resize canvas
|
||||
<input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer
|
||||
|
||||
<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/>
|
||||
|
|
|
|||
Loading…
Reference in New Issue