SDL Multitouch!

This commit is contained in:
TheBrokenRail 2023-11-01 20:45:24 -04:00
parent 4ff68d1f87
commit 4830a6fcab
4 changed files with 149 additions and 70 deletions

View file

@ -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:

View file

@ -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!
};

View file

@ -14,6 +14,7 @@ typedef AppPlatform_sdl UsedAppPlatform;
#endif
#include "client/app/NinecraftApp.hpp"
#include "client/player/input/Multitouch.hpp"
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
@ -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:

View file

@ -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