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 ---
|
# --- EMSCRIPTEN-SPECIFIC ---
|
||||||
ifeq ($(PLATFORM), emscripten)
|
ifeq ($(PLATFORM), emscripten)
|
||||||
|
PLATFORM_CFLAGS += -s USE_SDL=2
|
||||||
LDFLAGS += -s USE_SDL=2\
|
LDFLAGS += -s USE_SDL=2\
|
||||||
-s ASYNCIFY \
|
-s ASYNCIFY \
|
||||||
-s ALLOW_MEMORY_GROWTH=1 \
|
-s ALLOW_MEMORY_GROWTH=1 \
|
||||||
|
|
|
||||||
|
|
@ -61,31 +61,6 @@ i32 screen_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) {
|
||||||
memcpy(&info[12], &screen->buffer_size, sizeof(u32));
|
memcpy(&info[12], &screen->buffer_size, sizeof(u32));
|
||||||
screen->screen_buffer = (u8*)(buffer + 16);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,59 +33,106 @@ static ScreenDeviceData screen_data = {0};
|
||||||
static MouseDeviceData mouse_data = {0};
|
static MouseDeviceData mouse_data = {0};
|
||||||
static ConsoleDeviceData console_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() {
|
void mainloop() {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
SDL_PumpEvents();
|
SDL_PumpEvents();
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
// Mouse events
|
case SDL_WINDOWEVENT:{
|
||||||
case SDL_MOUSEMOTION:
|
switch (event.window.event) {
|
||||||
mouse_data.x = event.motion.x;
|
case SDL_WINDOWEVENT_RESIZED:
|
||||||
mouse_data.y = event.motion.y;
|
screen_data.update = true;
|
||||||
break;
|
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;
|
|
||||||
}
|
}
|
||||||
|
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;
|
int cycles_this_frame = 0;
|
||||||
|
|
@ -100,8 +147,26 @@ void mainloop() {
|
||||||
|
|
||||||
if (screen_data.update) {
|
if (screen_data.update) {
|
||||||
if (screen_data.renderer && screen_data.texture) {
|
if (screen_data.renderer && screen_data.texture) {
|
||||||
SDL_RenderCopy(screen_data.renderer, screen_data.texture, NULL, NULL);
|
// Clear and render
|
||||||
SDL_RenderPresent(screen_data.renderer);
|
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;
|
screen_data.update = false;
|
||||||
}
|
}
|
||||||
|
|
@ -148,6 +213,7 @@ int main(int argc, char **argv) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
|
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
|
||||||
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
emscripten_set_canvas_element_size("#canvas", 640, 480);
|
emscripten_set_canvas_element_size("#canvas", 640, 480);
|
||||||
|
|
@ -160,9 +226,24 @@ int main(int argc, char **argv) {
|
||||||
screen_data.width = 640;
|
screen_data.width = 640;
|
||||||
screen_data.height = 480;
|
screen_data.height = 480;
|
||||||
screen_data.buffer_size = screen_data.width * screen_data.height;
|
screen_data.buffer_size = screen_data.width * screen_data.height;
|
||||||
screen_data.window = NULL;
|
screen_data.window = SDL_CreateWindow("Reality Engine VM", SDL_WINDOWPOS_CENTERED,
|
||||||
screen_data.renderer = NULL;
|
SDL_WINDOWPOS_CENTERED, 640, 480,
|
||||||
screen_data.texture = NULL;
|
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.x = 0;
|
||||||
mouse_data.y = 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,
|
vm_register_device(&vm, "/dev/term/0", "terminal", &console_data,
|
||||||
&console_device_ops, 4);
|
&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);
|
emscripten_set_main_loop(mainloop, 0, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -208,8 +208,9 @@
|
||||||
<input type="checkbox" id="resize">Resize canvas
|
<input type="checkbox" id="resize">Resize canvas
|
||||||
<input type="checkbox" id="pointerLock" checked>Lock/hide mouse pointer
|
<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)">
|
document.getElementById('resize').checked)">
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue