Skip to content

Commit

Permalink
Merge pull request #766 from yamt/glfw
Browse files Browse the repository at this point in the history
Revive and fix glfw for macOS
  • Loading branch information
aduros authored Oct 5, 2024
2 parents 0795bd9 + a896573 commit 35cfb6f
Show file tree
Hide file tree
Showing 8 changed files with 1,742 additions and 31 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
[submodule "runtimes/native/vendor/wasm3"]
path = runtimes/native/vendor/wasm3
url = https://github.com/wasm3/wasm3
[submodule "runtimes/native/vendor/glfw"]
path = runtimes/native/vendor/glfw
url = https://github.com/glfw/glfw
[submodule "runtimes/native/vendor/minifb"]
path = runtimes/native/vendor/minifb
url = https://github.com/emoon/minifb
Expand Down
62 changes: 39 additions & 23 deletions runtimes/native/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 3.7)
project(WASM4)

set(WASM_BACKEND "wasm3" CACHE STRING "webassembly runtime")
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
set(WINDOW_BACKEND "glfw" CACHE STRING "window backend")
else ()
set(WINDOW_BACKEND "minifb" CACHE STRING "window backend")
endif ()

set (WASM3 OFF)
set (TOYWASM OFF)
Expand All @@ -13,6 +18,16 @@ else ()
message (FATAL_ERROR "Unrecognized WASM_BACKEND value: ${WASM_BACKEND}")
endif ()

set (MINIFB OFF)
set (GLFW OFF)
if (WINDOW_BACKEND STREQUAL "minifb")
set (MINIFB ON)
elseif (WINDOW_BACKEND STREQUAL "glfw")
set (GLFW ON)
else ()
message (FATAL_ERROR "Unrecognized WINDOW_BACKEND value: ${WINDOW_BACKEND}")
endif ()

# Prevent BUILD_SHARED_LIBS and other options from being cleared by vendor CMakeLists
# https://stackoverflow.com/a/66342383
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
Expand Down Expand Up @@ -94,8 +109,14 @@ if (LIBRETRO)
endif ()

if (NOT LIBRETRO)
# add_subdirectory(vendor/glfw)
if (GLFW)
set (GLFW_BUILD_DOCS OFF)
set (GLFW_INSTALL OFF)
add_subdirectory(vendor/glfw)
endif ()
if (MINIFB)
add_subdirectory(vendor/minifb)
endif ()
add_subdirectory(vendor/cubeb)
endif ()

Expand All @@ -111,28 +132,41 @@ endif ()
if (NOT LIBRETRO)

#
# Desktop (minifb + cubeb) backend
# Desktop ([minifb|glfw] + cubeb) backend
#

set(MINIFB_SOURCES
set(MAIN_SOURCES
src/backend/main.c
)

set(MINIFB_SOURCES
src/backend/window_minifb.c
)

add_executable(wasm4 ${COMMON_SOURCES} ${MINIFB_SOURCES}
set(GLFW_SOURCES
src/backend/window_glfw.c
vendor/glad/src/glad.c
)

add_executable(wasm4 ${COMMON_SOURCES} ${MAIN_SOURCES}
$<$<BOOL:${MINIFB}>:${MINIFB_SOURCES}>
$<$<BOOL:${GLFW}>:${GLFW_SOURCES}>
$<$<BOOL:${WASM3}>:${WASM3_SOURCES}>
$<$<BOOL:${TOYWASM}>:${TOYWASM_SOURCES}>)
if (TOYWASM)
add_dependencies(wasm4 toywasm)
endif ()

target_include_directories(wasm4 PRIVATE
$<$<BOOL:${GLFW}>:${CMAKE_SOURCE_DIR}/vendor/glad/include>
$<$<BOOL:${WASM3}>:${CMAKE_SOURCE_DIR}/vendor/wasm3/source>
$<$<BOOL:${TOYWASM}>:${toywasm_tmp_install}/include>)
target_link_directories(wasm4 PRIVATE
$<$<BOOL:${TOYWASM}>:${toywasm_tmp_install}/lib>)

target_link_libraries(wasm4 minifb cubeb
target_link_libraries(wasm4 cubeb
$<$<BOOL:${MINIFB}>:minifb>
$<$<BOOL:${GLFW}>:glfw>
$<$<BOOL:${TOYWASM}>:toywasm-core>)
set_target_properties(wasm4 PROPERTIES C_STANDARD 99)
install(TARGETS wasm4)
Expand All @@ -153,24 +187,6 @@ if (WASMER_DIR)
install(TARGETS wasm4_wasmer)
endif ()

# #
# # Desktop (glfw + cubeb) backend
# #
#
# set(GLFW_SOURCES
# src/backend/main.c
# src/backend/wasm_wasm3.c
# src/backend/window_glfw.c
# vendor/glad/src/glad.c
# )
# add_executable(wasm4_glfw)
# target_sources(wasm4_glfw PRIVATE ${COMMON_SOURCES} ${GLFW_SOURCES} ${M3_SOURCES})
# target_include_directories(wasm4_glfw PRIVATE "${CMAKE_SOURCE_DIR}/vendor/wasm3/source")
# target_include_directories(wasm4_glfw PRIVATE "${CMAKE_SOURCE_DIR}/vendor/glad/include")
# target_link_libraries(wasm4_glfw glfw cubeb)
# set_target_properties(wasm4_glfw PROPERTIES C_STANDARD 99)
# install(TARGETS wasm4_glfw)

#
# Libretro backend
#
Expand Down
19 changes: 19 additions & 0 deletions runtimes/native/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,25 @@ cmake --build build
[wasm3]: https://github.com/wasm3/wasm3
[toywasm]: https://github.com/yamt/toywasm

Also, you can select the window backend by setting
the `WINDOW_BACKEND` cmake option:

```shell
cmake -B build -DWINDOW_BACKEND=minifb
cmake --build build
```

```shell
cmake -B build -DWINDOW_BACKEND=glfw
cmake --build build
```

On macOS, the default is [glfw].
On the other platforms, the default is [minifb].

[minifb]: https://github.com/emoon/minifb
[glfw]: https://www.glfw.org/

Running:

```shell
Expand Down
49 changes: 41 additions & 8 deletions runtimes/native/src/backend/window_glfw.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

Expand All @@ -13,7 +14,16 @@ static GLuint paletteLocation;

// Position and size of the viewport within the window, which may be smaller than the window size if
// the window was forced to a non-square resolution
static int contentX, contentY, contentSize;
static int contentX = 0;
static int contentY = 0;
static int contentSizeX = 3 * 160;
static int contentSizeY = 3 * 160;
static bool update_viewport;
static int viewportX;
static int viewportY;
static int viewportSize;

static bool should_close = false;

static void initLookupTable () {
// Create a lookup table for each byte mapping to 4 bytes:
Expand Down Expand Up @@ -130,11 +140,18 @@ static void onFramebufferResized (GLFWwindow* window, int width, int height) {
int size = (width < height) ? width : height;
int x = width/2 - size/2;
int y = height/2 - size/2;
glViewport(x, y, size, size);

contentX = x;
contentY = y;
contentSize = size;
viewportX = x;
viewportY = y;
viewportSize = size;
update_viewport = true;

float xscale, yscale;
glfwGetWindowContentScale(window, &xscale, &yscale);
contentX = x / xscale;
contentY = y / yscale;
contentSizeX = size / xscale;
contentSizeY = size / yscale;
}

static void onGlfwError(int error, const char* description)
Expand Down Expand Up @@ -165,6 +182,10 @@ static void update (GLFWwindow* window) {
}
w4_runtimeSetGamepad(0, gamepad);

if (glfwGetKey(window, GLFW_KEY_ESCAPE)) {
should_close = true;
}

// Mouse handling
double mouseX, mouseY;
uint8_t mouseButtons = 0;
Expand All @@ -178,7 +199,7 @@ static void update (GLFWwindow* window) {
if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_MIDDLE)) {
mouseButtons |= W4_MOUSE_MIDDLE;
}
w4_runtimeSetMouse(160*(mouseX-contentX)/contentSize, 160*(mouseY-contentY)/contentSize, mouseButtons);
w4_runtimeSetMouse(160*(mouseX-contentX)/contentSizeX, 160*(mouseY-contentY)/contentSizeY, mouseButtons);

w4_runtimeUpdate();
}
Expand All @@ -191,7 +212,7 @@ void w4_windowBoot (const char* title) {

glfwSetErrorCallback(onGlfwError);

GLFWwindow* window = glfwCreateWindow(2*160, 2*160, title, NULL, NULL);
GLFWwindow* window = glfwCreateWindow(3*160, 3*160, title, NULL, NULL);
glfwSetFramebufferSizeCallback(window, onFramebufferResized);
glfwSetWindowAspectRatio(window, 1, 1);
glfwSetInputMode(window, GLFW_STICKY_KEYS, GLFW_TRUE);
Expand All @@ -204,9 +225,21 @@ void w4_windowBoot (const char* title) {
initOpenGL();
initLookupTable();

while (!glfwWindowShouldClose(window)) {
while (!glfwWindowShouldClose(window) && !should_close) {
double timeStart = glfwGetTime();
double timeEnd = timeStart + 1.0/60.0;
if (update_viewport) {
glViewport(viewportX, viewportY, viewportSize, viewportSize);
/*
* for macOS, keep updating the viewport to workaround a bug.
* cf.
* https://github.com/glfw/glfw/issues/2251
* https://github.com/glfw/glfw/issues/80
*/
#if !defined(__APPLE__)
update_viewport = false;
#endif
}

update(window);
glfwSwapBuffers(window);
Expand Down
Loading

0 comments on commit 35cfb6f

Please sign in to comment.