diff --git a/misc/web/index.html b/misc/web/index.html
index 3cd04f9..c209fb2 100644
--- a/misc/web/index.html
+++ b/misc/web/index.html
@@ -22,6 +22,10 @@
width: 100vw;
height: 100vh;
display: block;
+ touch-action: none;
+ user-select: none;
+ -webkit-user-select: none;
+ -webkit-tap-highlight-color: transparent;
}
diff --git a/src/main_glfw.h b/src/main_glfw.h
index 042c9fb..44295fd 100755
--- a/src/main_glfw.h
+++ b/src/main_glfw.h
@@ -16,7 +16,88 @@
#ifdef __EMSCRIPTEN__
#include
#endif
-static App* g_app = 0;
+static App* g_app = 0;
+
+#ifdef __EMSCRIPTEN__
+static int g_touchPointerIds[Multitouch::MAX_POINTERS];
+
+static void resetTouchPointerIds() {
+ for (int i = 0; i < Multitouch::MAX_POINTERS; ++i) {
+ g_touchPointerIds[i] = -1;
+ }
+}
+
+static int getTouchPointerSlot(int touchId) {
+ for (int i = 0; i < Multitouch::MAX_POINTERS; ++i) {
+ if (g_touchPointerIds[i] == touchId) return i;
+ }
+ return -1;
+}
+
+static int allocateTouchPointerSlot(int touchId) {
+ int slot = getTouchPointerSlot(touchId);
+ if (slot >= 0) return slot;
+
+ for (int i = 0; i < Multitouch::MAX_POINTERS; ++i) {
+ if (g_touchPointerIds[i] < 0) {
+ g_touchPointerIds[i] = touchId;
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static void releaseTouchPointerSlot(int touchId) {
+ for (int i = 0; i < Multitouch::MAX_POINTERS; ++i) {
+ if (g_touchPointerIds[i] == touchId) {
+ g_touchPointerIds[i] = -1;
+ return;
+ }
+ }
+}
+
+static EM_BOOL touch_callback(int eventType, const EmscriptenTouchEvent* touchEvent, void* userData) {
+ if (!touchEvent) return 0;
+
+ const bool isStart = eventType == EMSCRIPTEN_EVENT_TOUCHSTART;
+ const bool isMove = eventType == EMSCRIPTEN_EVENT_TOUCHMOVE;
+ const bool isEnd = eventType == EMSCRIPTEN_EVENT_TOUCHEND;
+ const bool isCancel = eventType == EMSCRIPTEN_EVENT_TOUCHCANCEL;
+
+ if (isCancel) {
+ for (int i = 0; i < Multitouch::MAX_POINTERS; ++i) {
+ if (g_touchPointerIds[i] >= 0) {
+ Multitouch::feed(1, 0, Multitouch::getX(i), Multitouch::getY(i), i);
+ g_touchPointerIds[i] = -1;
+ }
+ }
+ return 1;
+ }
+
+ for (int i = 0; i < touchEvent->numTouches; ++i) {
+ const EmscriptenTouchPoint& touch = touchEvent->touches[i];
+ if (!touch.isChanged) continue;
+
+ const int slot = isEnd ? getTouchPointerSlot(touch.identifier) : allocateTouchPointerSlot(touch.identifier);
+ if (slot < 0) continue;
+
+ const short x = (short)touch.targetX;
+ const short y = (short)touch.targetY;
+
+ if (isStart) {
+ Multitouch::feed(1, 1, x, y, slot);
+ } else if (isMove) {
+ Multitouch::feed(0, 0, x, y, slot);
+ } else if (isEnd) {
+ Multitouch::feed(1, 0, x, y, slot);
+ releaseTouchPointerSlot(touch.identifier);
+ }
+ }
+
+ return 1;
+}
+#endif
int transformKey(int glfwkey) {
if (glfwkey >= GLFW_KEY_F1 && glfwkey <= GLFW_KEY_F12) {
@@ -176,12 +257,19 @@ int main(void) {
glfwSetKeyCallback(platform->window, key_callback);
glfwSetCharCallback(platform->window, character_callback);
- glfwSetCursorPosCallback(platform->window, cursor_position_callback);
- glfwSetMouseButtonCallback(platform->window, mouse_button_callback);
- glfwSetScrollCallback(platform->window, scroll_callback);
- glfwSetWindowSizeCallback(platform->window, window_size_callback);
-
- glfwMakeContextCurrent(platform->window);
+ glfwSetCursorPosCallback(platform->window, cursor_position_callback);
+ glfwSetMouseButtonCallback(platform->window, mouse_button_callback);
+ glfwSetScrollCallback(platform->window, scroll_callback);
+ glfwSetWindowSizeCallback(platform->window, window_size_callback);
+ #ifdef __EMSCRIPTEN__
+ resetTouchPointerIds();
+ emscripten_set_touchstart_callback("#canvas", 0, 1, touch_callback);
+ emscripten_set_touchmove_callback("#canvas", 0, 1, touch_callback);
+ emscripten_set_touchend_callback("#canvas", 0, 1, touch_callback);
+ emscripten_set_touchcancel_callback("#canvas", 0, 1, touch_callback);
+ #endif
+
+ glfwMakeContextCurrent(platform->window);
#ifndef __EMSCRIPTEN__
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
glfwSwapInterval(0);