diff --git a/platforms/sdl/AppPlatform_sdlbase.cpp b/platforms/sdl/AppPlatform_sdlbase.cpp index 64ad06e..b1ec354 100644 --- a/platforms/sdl/AppPlatform_sdlbase.cpp +++ b/platforms/sdl/AppPlatform_sdlbase.cpp @@ -16,17 +16,17 @@ void AppPlatform_sdlbase::_init(std::string storageDir, SDL_Window *window) { - _storageDir = storageDir; - _window = window; - - _iconTexture = nullptr; - _icon = nullptr; - - m_bShiftPressed[0] = false; - m_bShiftPressed[1] = false; + _storageDir = storageDir; + _window = window; + + _iconTexture = nullptr; + _icon = nullptr; + + m_bShiftPressed[0] = false; + m_bShiftPressed[1] = false; + + ensureDirectoryExists(_storageDir.c_str()); - ensureDirectoryExists(_storageDir.c_str()); - m_pLogger = new Logger; m_pSoundSystem = nullptr; } @@ -52,11 +52,11 @@ void AppPlatform_sdlbase::setIcon(const Texture& icon) SAFE_DELETE(_iconTexture); if (_icon) SDL_FreeSurface(_icon); - _iconTexture = new Texture(icon); - _icon = getSurfaceForTexture(_iconTexture); - - if (_icon) - SDL_SetWindowIcon(_window, _icon); + _iconTexture = new Texture(icon); + _icon = getSurfaceForTexture(_iconTexture); + + if (_icon) + SDL_SetWindowIcon(_window, _icon); } AppPlatform_sdlbase::~AppPlatform_sdlbase() @@ -65,29 +65,29 @@ AppPlatform_sdlbase::~AppPlatform_sdlbase() SAFE_DELETE(_iconTexture); SAFE_DELETE(m_pSoundSystem); - + // DELETE THIS LAST SAFE_DELETE(m_pLogger); } SDL_Surface* AppPlatform_sdlbase::getSurfaceForTexture(const Texture* const texture) { - if (!texture) return nullptr; - - void * const pixels = texture->m_pixels; - const int width = texture->m_width; - const int height = texture->m_height; - const int depth = 32; // Color depth (32-bit by default) - SDL_Surface* surface = SDL_CreateRGBSurfaceFrom( - pixels, width, height, depth, - width * 4, // Pitch - 0x000000FF, 0x0000FF00, 0x00FF0000, - 0xFF000000 - ); - if (!surface) - LOG_E("Failed loading SDL_Surface from Texture: %s", SDL_GetError()); - - return surface; + if (!texture) return nullptr; + + void * const pixels = texture->m_pixels; + const int width = texture->m_width; + const int height = texture->m_height; + const int depth = 32; // Color depth (32-bit by default) + SDL_Surface* surface = SDL_CreateRGBSurfaceFrom( + pixels, width, height, depth, + width * 4, // Pitch + 0x000000FF, 0x0000FF00, 0x00FF0000, + 0xFF000000 + ); + if (!surface) + LOG_E("Failed loading SDL_Surface from Texture: %s", SDL_GetError()); + + return surface; } int AppPlatform_sdlbase::checkLicense() @@ -98,7 +98,7 @@ int AppPlatform_sdlbase::checkLicense() const char* const AppPlatform_sdlbase::getWindowTitle() const { - return SDL_GetWindowTitle(_window); + return SDL_GetWindowTitle(_window); } int AppPlatform_sdlbase::getScreenWidth() const @@ -185,11 +185,15 @@ bool AppPlatform_sdlbase::GetMouseButtonState(SDL_Event event) { short wheelDelta = event.wheel.y; if (wheelDelta > 0) + { // "A positive value indicates that the wheel was rotated forward, away from the user." result = false; + } else + { // "A negative value indicates that the wheel was rotated backward, toward the user." result = true; + } break; } default: diff --git a/platforms/sdl/AppPlatform_sdlbase.hpp b/platforms/sdl/AppPlatform_sdlbase.hpp index 1d6423e..2ee9ced 100644 --- a/platforms/sdl/AppPlatform_sdlbase.hpp +++ b/platforms/sdl/AppPlatform_sdlbase.hpp @@ -12,12 +12,12 @@ class AppPlatform_sdlbase : public AppPlatform { public: - void _init(std::string storageDir, SDL_Window *window); - AppPlatform_sdlbase(std::string storageDir, SDL_Window *window) - { - _init(storageDir, window); - } - ~AppPlatform_sdlbase(); + void _init(std::string storageDir, SDL_Window *window); + AppPlatform_sdlbase(std::string storageDir, SDL_Window *window) + { + _init(storageDir, window); + } + ~AppPlatform_sdlbase(); void initSoundSystem() override; @@ -44,23 +44,23 @@ public: static Keyboard::KeyState GetKeyState(SDL_Event event); private: SDL_Window *_window; - - const Texture *_iconTexture; - SDL_Surface *_icon; + + const Texture *_iconTexture; + SDL_Surface *_icon; bool m_bShiftPressed[2]; int xrel; int yrel; - + Logger* m_pLogger; SoundSystem* m_pSoundSystem; - - static SDL_Surface* getSurfaceForTexture(const Texture* const texture); + + static SDL_Surface* getSurfaceForTexture(const Texture* const texture); protected: - std::string _storageDir; + std::string _storageDir; virtual void ensureDirectoryExists(const char* path) { } - + void setIcon(const Texture& icon); // note: this takes ownership of the texture, so no memory leaks! }; diff --git a/platforms/sdl/main.cpp b/platforms/sdl/main.cpp index 1099339..b17be6b 100644 --- a/platforms/sdl/main.cpp +++ b/platforms/sdl/main.cpp @@ -14,6 +14,7 @@ typedef AppPlatform_sdl UsedAppPlatform; #endif #include "client/app/NinecraftApp.hpp" +#include "client/player/input/Multitouch.hpp" #ifdef __EMSCRIPTEN__ #include @@ -54,6 +55,60 @@ static int TranslateSDLKeyCodeToVirtual(int sdlCode) return SDLVK_UNKNOWN; } +// Touch +#define TOUCH_IDS_SIZE (MAX_TOUCHES - 1) // ID 0 Is Reserved For The Mouse +struct touch_id_data { + bool active = false; + int id; +}; +static touch_id_data touch_ids[TOUCH_IDS_SIZE]; +static char get_touch_id(int device, int finger) { + int real_id = (device * 100) + finger; + for (int i = 0; i < TOUCH_IDS_SIZE; i++) { + touch_id_data &data = touch_ids[i]; + if (data.active && data.id == real_id) { + return i + 1; + } + } + // Not Found + for (int i = 0; i < TOUCH_IDS_SIZE; i++) { + // Find First Inactive ID, And Activate It + touch_id_data &data = touch_ids[i]; + if (!data.active) { + data.active = true; + data.id = real_id; + return i + 1; + } + } + // Fail + return 0; +} +static void drop_touch_id(int id) { + touch_ids[id - 1].active = false; +} +static void handle_touch(int x, int y, int type, char id) { + if (id == 0) { + return; + } + switch (type) { + case SDL_FINGERDOWN: + case SDL_FINGERUP: { + bool data = type == SDL_FINGERUP ? 0 : 1; + Mouse::feed(BUTTON_LEFT, data, x, y); + Multitouch::feed(BUTTON_LEFT, data, x, y, id); + if (type == SDL_FINGERUP) { + drop_touch_id(id); + } + break; + } + case SDL_FINGERMOTION: { + Mouse::feed(BUTTON_NONE, 0, x, y); + Multitouch::feed(BUTTON_NONE, 0, x, y, id); + break; + } + } +} + // Resize From JS #ifdef __EMSCRIPTEN__ extern "C" void resize_from_js(int new_width, int new_height) @@ -98,22 +153,42 @@ static void handle_events() case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: { - const float scale = g_fPointToPixelScale; - Mouse::feed(AppPlatform_sdlbase::GetMouseButtonType(event), AppPlatform_sdlbase::GetMouseButtonState(event), event.button.x * scale, event.button.y * scale); + if (event.button.which != SDL_TOUCH_MOUSEID) { + const float scale = g_fPointToPixelScale; + MouseButtonType type = AppPlatform_sdlbase::GetMouseButtonType(event); + bool state = AppPlatform_sdlbase::GetMouseButtonState(event); + float x = event.button.x * scale; + float y = event.button.y * scale; + Mouse::feed(type, state, x, y); + Multitouch::feed(type, state, x, y, 0); + } break; } case SDL_MOUSEMOTION: { - float scale = g_fPointToPixelScale; - float x = event.motion.x * scale; - float y = event.motion.y * scale; - Mouse::feed(BUTTON_NONE, false, x, y); - g_pAppPlatform->setMouseDiff(event.motion.xrel * scale, event.motion.yrel * scale); + if (event.button.which != SDL_TOUCH_MOUSEID) { + float scale = g_fPointToPixelScale; + float x = event.motion.x * scale; + float y = event.motion.y * scale; + Multitouch::feed(BUTTON_NONE, 0, x, y, 0); + Mouse::feed(BUTTON_NONE, false, x, y); + g_pAppPlatform->setMouseDiff(event.motion.xrel * scale, event.motion.yrel * scale); + } break; } case SDL_MOUSEWHEEL: { - Mouse::feed(BUTTON_SCROLLWHEEL, AppPlatform_sdlbase::GetMouseButtonState(event), Mouse::getX(), Mouse::getY()); + if (event.button.which != SDL_TOUCH_MOUSEID) { + Mouse::feed(BUTTON_SCROLLWHEEL, AppPlatform_sdlbase::GetMouseButtonState(event), Mouse::getX(), Mouse::getY()); + } + break; + } + case SDL_FINGERDOWN: + case SDL_FINGERUP: + case SDL_FINGERMOTION: { + float x = event.tfinger.x * Minecraft::width; + float y = event.tfinger.y * Minecraft::height; + handle_touch(x, y, event.type, get_touch_id(event.tfinger.touchId, event.tfinger.fingerId)); break; } case SDL_TEXTINPUT: diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 3f3c970..6916b8c 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -90,22 +90,22 @@ add_library(reminecraftpe-core STATIC client/player/input/MouseTurnInput.cpp client/player/input/KeyboardInput.cpp client/player/input/ITurnInput.cpp - client/player/input/IBuildInput.cpp - client/player/input/IncludeExcludeArea.cpp - client/player/input/MouseHandler.cpp - client/player/input/PolygonArea.cpp - client/player/input/RectangleArea.cpp - client/player/input/MouseDevice.cpp - client/player/input/Multitouch.cpp - client/player/input/CustomInputHolder.cpp - client/player/input/IInputHolder.cpp - client/player/input/IMoveInput.cpp - client/player/input/ITouchScreenModel.cpp - client/player/input/TouchAreaModel.cpp - client/player/input/TouchInputHolder.cpp - client/player/input/TouchscreenInput_TestFps.cpp - client/player/input/UnifiedTurnBuild.cpp client/network/ClientSideNetworkHandler.cpp + client/player/input/IBuildInput.cpp + client/player/input/IncludeExcludeArea.cpp + client/player/input/MouseHandler.cpp + client/player/input/PolygonArea.cpp + client/player/input/RectangleArea.cpp + client/player/input/MouseDevice.cpp + client/player/input/Multitouch.cpp + client/player/input/CustomInputHolder.cpp + client/player/input/IInputHolder.cpp + client/player/input/IMoveInput.cpp + client/player/input/ITouchScreenModel.cpp + client/player/input/TouchAreaModel.cpp + client/player/input/TouchInputHolder.cpp + client/player/input/TouchscreenInput_TestFps.cpp + client/player/input/UnifiedTurnBuild.cpp network/packets/UpdateBlockPacket.cpp network/packets/RequestChunkPacket.cpp network/packets/PlayerEquipmentPacket.cpp