diff --git a/src/rcore.c b/src/rcore.c index 59308442..60828b82 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -628,11 +628,13 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) #endif #if defined(PLATFORM_WEB) +static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *event, void *userData); +static EM_BOOL EmscriptenWindowResizedCallback(int eventType, const EmscriptenUiEvent *event, void *userData); +static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *event, void *userData); + static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData); static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData); static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData); -static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *e, void *userData); - #endif #if defined(PLATFORM_RPI) || defined(PLATFORM_DRM) @@ -861,13 +863,18 @@ void InitWindow(int width, int height, const char *title) #endif #if defined(PLATFORM_WEB) + // Setup callback funtions for the DOM events + emscripten_set_fullscreenchange_callback("#canvas", NULL, 1, EmscriptenFullscreenChangeCallback); + + // WARNING: Below resize code was breaking fullscreen mode for sample games and examples, it needs review // Check fullscreen change events(note this is done on the window since most browsers don't support this on #canvas) //emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback); // Check Resize event (note this is done on the window since most browsers don't support this on #canvas) - emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback); + //emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback); // Trigger this once to get initial window sizing - EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL); - // Support keyboard events + //EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL); + + // Support keyboard events -> Not used, GLFW.JS takes care of that //emscripten_set_keypress_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback); //emscripten_set_keydown_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback); @@ -1193,6 +1200,7 @@ void ToggleFullscreen(void) if (CORE.Window.flags & FLAG_VSYNC_HINT) glfwSwapInterval(1); #endif #if defined(PLATFORM_WEB) +/* EM_ASM ( // This strategy works well while using raylib minimal web shell for emscripten, @@ -1200,14 +1208,17 @@ void ToggleFullscreen(void) // is a good strategy but maybe games prefer to keep current canvas resolution and // display it in fullscreen, adjusting monitor resolution if possible if (document.fullscreenElement) document.exitFullscreen(); - else Module.requestFullscreen(false, true); + else Module.requestFullscreen(true, true); //false, true); ); - +*/ + //EM_ASM(Module.requestFullscreen(false, false);); /* if (!CORE.Window.fullscreen) { // Option 1: Request fullscreen for the canvas element - // This option does not seem to work at all + // This option does not seem to work at all: + // emscripten_request_pointerlock() and emscripten_request_fullscreen() are affected by web security, + // the user must click once on the canvas to hide the pointer or transition to full screen //emscripten_request_fullscreen("#canvas", false); // Option 2: Request fullscreen for the canvas element with strategy @@ -1236,20 +1247,25 @@ void ToggleFullscreen(void) int width, height; emscripten_get_canvas_element_size("#canvas", &width, &height); TRACELOG(LOG_WARNING, "Emscripten: Enter fullscreen: Canvas size: %i x %i", width, height); + + CORE.Window.fullscreen = true; // Toggle fullscreen flag + CORE.Window.flags |= FLAG_FULLSCREEN_MODE; } else { //emscripten_exit_fullscreen(); - emscripten_exit_soft_fullscreen(); + //emscripten_exit_soft_fullscreen(); int width, height; emscripten_get_canvas_element_size("#canvas", &width, &height); TRACELOG(LOG_WARNING, "Emscripten: Exit fullscreen: Canvas size: %i x %i", width, height); + + CORE.Window.fullscreen = false; // Toggle fullscreen flag + CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE; } */ CORE.Window.fullscreen = !CORE.Window.fullscreen; // Toggle fullscreen flag - CORE.Window.flags ^= FLAG_FULLSCREEN_MODE; #endif #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM) TRACELOG(LOG_WARNING, "SYSTEM: Failed to toggle to windowed mode"); @@ -4099,11 +4115,13 @@ static bool InitGraphicsDevice(int width, int height) #else TRACELOG(LOG_INFO, "DISPLAY: No graphic card set, trying platform-gpu-card"); CORE.Window.fd = open("/dev/dri/by-path/platform-gpu-card", O_RDWR); // VideoCore VI (Raspberry Pi 4) + if ((-1 == CORE.Window.fd) || (drmModeGetResources(CORE.Window.fd) == NULL)) { TRACELOG(LOG_INFO, "DISPLAY: Failed to open platform-gpu-card, trying card1"); CORE.Window.fd = open("/dev/dri/card1", O_RDWR); // Other Embedded } + if ((-1 == CORE.Window.fd) || (drmModeGetResources(CORE.Window.fd) == NULL)) { TRACELOG(LOG_INFO, "DISPLAY: Failed to open graphic card1, trying card0"); @@ -5022,39 +5040,6 @@ static void ErrorCallback(int error, const char *description) TRACELOG(LOG_WARNING, "GLFW: Error: %i Description: %s", error, description); } -#if defined(PLATFORM_WEB) -EM_JS(int, GetCanvasWidth, (), { return canvas.clientWidth; }); -EM_JS(int, GetCanvasHeight, (), { return canvas.clientHeight; }); - -static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *e, void *userData) -{ - // Don't resize non-resizeable windows - if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) == 0) return 1; - - // This event is called whenever the window changes sizes, - // so the size of the canvas object is explicitly retrieved below - int width = GetCanvasWidth(); - int height = GetCanvasHeight(); - emscripten_set_canvas_element_size("#canvas",width,height); - - SetupViewport(width, height); // Reset viewport and projection matrix for new size - - CORE.Window.currentFbo.width = width; - CORE.Window.currentFbo.height = height; - CORE.Window.resizedLastFrame = true; - - if (IsWindowFullscreen()) return 1; - - // Set current screen size - CORE.Window.screen.width = width; - CORE.Window.screen.height = height; - - // NOTE: Postprocessing texture is not scaled to new size - - return 0; -} -#endif - // GLFW3 WindowSize Callback, runs when window is resizedLastFrame // NOTE: Window resizing not allowed by default static void WindowSizeCallback(GLFWwindow *window, int width, int height) @@ -5544,11 +5529,82 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) #endif #if defined(PLATFORM_WEB) +// Register fullscreen change events +static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *event, void *userData) +{ + // TODO. + + return 1; // The event was consumed by the callback handler +} + +// Register window resize event +static EM_BOOL EmscriptenWindowResizedCallback(int eventType, const void *reserved, void *userData) +{ + // TODO. + + return 1; // The event was consumed by the callback handler +} + +EM_JS(int, GetCanvasWidth, (), { return canvas.clientWidth; }); +EM_JS(int, GetCanvasHeight, (), { return canvas.clientHeight; }); + +// Register DOM element resize event +static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *event, void *userData) +{ + // Don't resize non-resizeable windows + if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) == 0) return 1; + + // This event is called whenever the window changes sizes, + // so the size of the canvas object is explicitly retrieved below + int width = GetCanvasWidth(); + int height = GetCanvasHeight(); + emscripten_set_canvas_element_size("#canvas",width,height); + + SetupViewport(width, height); // Reset viewport and projection matrix for new size + + CORE.Window.currentFbo.width = width; + CORE.Window.currentFbo.height = height; + CORE.Window.resizedLastFrame = true; + + if (IsWindowFullscreen()) return 1; + + // Set current screen size + CORE.Window.screen.width = width; + CORE.Window.screen.height = height; + + // NOTE: Postprocessing texture is not scaled to new size + + return 0; +} + // Register mouse input events static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData) { // This is only for registering mouse click events with emscripten and doesn't need to do anything - return 0; + + return 1; // The event was consumed by the callback handler +} + +// Register connected/disconnected gamepads events +static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData) +{ + /* + TRACELOGD("%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"", + eventType != 0? emscripten_event_type_to_string(eventType) : "Gamepad state", + gamepadEvent->timestamp, gamepadEvent->connected, gamepadEvent->index, gamepadEvent->numAxes, gamepadEvent->numButtons, gamepadEvent->id, gamepadEvent->mapping); + + for (int i = 0; i < gamepadEvent->numAxes; ++i) TRACELOGD("Axis %d: %g", i, gamepadEvent->axis[i]); + for (int i = 0; i < gamepadEvent->numButtons; ++i) TRACELOGD("Button %d: Digital: %d, Analog: %g", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]); + */ + + if ((gamepadEvent->connected) && (gamepadEvent->index < MAX_GAMEPADS)) + { + CORE.Input.Gamepad.ready[gamepadEvent->index] = true; + sprintf(CORE.Input.Gamepad.name[gamepadEvent->index],"%s",gamepadEvent->id); + } + else CORE.Input.Gamepad.ready[gamepadEvent->index] = false; + + return 1; // The event was consumed by the callback handler } // Register touch input events @@ -5601,29 +5657,7 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent ProcessGestureEvent(gestureEvent); #endif - return 1; -} - -// Register connected/disconnected gamepads events -static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData) -{ - /* - TRACELOGD("%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"", - eventType != 0? emscripten_event_type_to_string(eventType) : "Gamepad state", - gamepadEvent->timestamp, gamepadEvent->connected, gamepadEvent->index, gamepadEvent->numAxes, gamepadEvent->numButtons, gamepadEvent->id, gamepadEvent->mapping); - - for (int i = 0; i < gamepadEvent->numAxes; ++i) TRACELOGD("Axis %d: %g", i, gamepadEvent->axis[i]); - for (int i = 0; i < gamepadEvent->numButtons; ++i) TRACELOGD("Button %d: Digital: %d, Analog: %g", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]); - */ - - if ((gamepadEvent->connected) && (gamepadEvent->index < MAX_GAMEPADS)) - { - CORE.Input.Gamepad.ready[gamepadEvent->index] = true; - sprintf(CORE.Input.Gamepad.name[gamepadEvent->index],"%s",gamepadEvent->id); - } - else CORE.Input.Gamepad.ready[gamepadEvent->index] = false; - - return 0; + return 1; // The event was consumed by the callback handler } #endif