diff --git a/src/modules/event/sdl/Event.cpp b/src/modules/event/sdl/Event.cpp index 52caa11ca..7296c9359 100644 --- a/src/modules/event/sdl/Event.cpp +++ b/src/modules/event/sdl/Event.cpp @@ -31,6 +31,7 @@ #include "common/Exception.h" #include "audio/Audio.h" #include "common/config.h" +#include "timer/Timer.h" #include @@ -146,7 +147,7 @@ void Event::clear() love::event::Event::clear(); } -Message *Event::convert(const SDL_Event &e) const +Message *Event::convert(const SDL_Event &e) { Message *msg = nullptr; @@ -243,31 +244,7 @@ Message *Event::convert(const SDL_Event &e) const break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: - { - // SDL uses button index 3 for the right mouse button, but we use - // index 2. - int button = e.button.button; - switch (button) - { - case SDL_BUTTON_RIGHT: - button = 2; - break; - case SDL_BUTTON_MIDDLE: - button = 3; - break; - } - - double x = (double) e.button.x; - double y = (double) e.button.y; - windowToPixelCoords(&x, &y); - vargs.emplace_back(x); - vargs.emplace_back(y); - vargs.emplace_back((double) button); - vargs.emplace_back(e.button.which == SDL_TOUCH_MOUSEID); - msg = new Message((e.type == SDL_MOUSEBUTTONDOWN) ? - "mousepressed" : "mousereleased", - vargs); - } + msg = convertMouseButtonEvent(e); break; case SDL_MOUSEWHEEL: vargs.emplace_back((double) e.wheel.x); @@ -385,7 +362,69 @@ Message *Event::convert(const SDL_Event &e) const return msg; } -Message *Event::convertJoystickEvent(const SDL_Event &e) const +Message *Event::convertMouseButtonEvent(const SDL_Event &e) +{ + bool down = e.type == SDL_MOUSEBUTTONDOWN; + + std::vector vargs; + vargs.reserve(5); + + // SDL uses button index 3 for the right mouse button, but we use index 2. + int button = e.button.button; + switch (button) + { + case SDL_BUTTON_RIGHT: + button = 2; + break; + case SDL_BUTTON_MIDDLE: + button = 3; + break; + } + + double px = (double) e.button.x; + double py = (double) e.button.y; + windowToPixelCoords(&px, &py); + vargs.emplace_back(px); + vargs.emplace_back(py); + vargs.emplace_back((double) button); + vargs.emplace_back(e.button.which == SDL_TOUCH_MOUSEID); + +#if SDL_VERSION_ATLEAST(2,0,4) + SDL_version version; + SDL_GetVersion(&version); + if (version.major >= 2 && (version.minor > 0 || version.patch >= 4)) + vargs.emplace_back((double) e.button.clicks); + else +#endif + { + ClickState state = clickCounts[e.button.which]; + + // Matches the behaviour of SDL 2.0.4's click count tracking code when + // it doesn't know any OS-specific information. + if (down) + { + double now = timer::Timer::getTime(); + int diffX = abs(e.button.x - state.lastX); + int diffY = abs(e.button.y - state.lastY); + + if ((now - state.time) >= 0.5 || diffX > 1 || diffY > 1) + state.count = 0; + + state.count++; + state.lastX = e.button.x; + state.lastY = e.button.y; + state.time = now; + + clickCounts[e.button.which] = state; + } + + vargs.emplace_back((double) state.count); + } + + return new Message(down ? "mousepressed" : "mousereleased", vargs); +} + +Message *Event::convertJoystickEvent(const SDL_Event &e) { auto joymodule = Module::getInstance(Module::M_JOYSTICK); if (!joymodule) @@ -510,7 +549,7 @@ Message *Event::convertJoystickEvent(const SDL_Event &e) const return msg; } -Message *Event::convertWindowEvent(const SDL_Event &e) const +Message *Event::convertWindowEvent(const SDL_Event &e) { Message *msg = nullptr; diff --git a/src/modules/event/sdl/Event.h b/src/modules/event/sdl/Event.h index 9ab44174e..40f53a444 100644 --- a/src/modules/event/sdl/Event.h +++ b/src/modules/event/sdl/Event.h @@ -68,9 +68,20 @@ public: private: - Message *convert(const SDL_Event &e) const; - Message *convertJoystickEvent(const SDL_Event &e) const; - Message *convertWindowEvent(const SDL_Event &e) const; + struct ClickState + { + int count; + int lastX; + int lastY; + double time; + }; + + Message *convert(const SDL_Event &e); + Message *convertMouseButtonEvent(const SDL_Event &e); + Message *convertJoystickEvent(const SDL_Event &e); + Message *convertWindowEvent(const SDL_Event &e); + + std::map clickCounts; static std::map createKeyMap(); static std::map keys; diff --git a/src/scripts/boot.lua b/src/scripts/boot.lua index 162bfd29b..98c2c9129 100644 --- a/src/scripts/boot.lua +++ b/src/scripts/boot.lua @@ -169,11 +169,11 @@ function love.createhandlers() mousemoved = function (x,y,dx,dy,t) if love.mousemoved then return love.mousemoved(x,y,dx,dy,t) end end, - mousepressed = function (x,y,b,t) - if love.mousepressed then return love.mousepressed(x,y,b,t) end + mousepressed = function (x,y,b,t,c) + if love.mousepressed then return love.mousepressed(x,y,b,t,c) end end, - mousereleased = function (x,y,b,t) - if love.mousereleased then return love.mousereleased(x,y,b,t) end + mousereleased = function (x,y,b,t,c) + if love.mousereleased then return love.mousereleased(x,y,b,t,c) end end, wheelmoved = function (x,y) if love.wheelmoved then return love.wheelmoved(x,y) end diff --git a/src/scripts/boot.lua.h b/src/scripts/boot.lua.h index e24110a4c..8f499c12a 100644 --- a/src/scripts/boot.lua.h +++ b/src/scripts/boot.lua.h @@ -294,18 +294,20 @@ const unsigned char boot_lua[] = 0x64, 0x78, 0x2c, 0x64, 0x79, 0x2c, 0x74, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x09, 0x09, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, - 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x78, 0x2c, 0x79, 0x2c, 0x62, 0x2c, 0x74, 0x29, 0x0a, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x78, 0x2c, 0x79, 0x2c, 0x62, 0x2c, 0x74, 0x2c, 0x63, + 0x29, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x28, - 0x78, 0x2c, 0x79, 0x2c, 0x62, 0x2c, 0x74, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x78, 0x2c, 0x79, 0x2c, 0x62, 0x2c, 0x74, 0x2c, 0x63, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x09, 0x09, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, - 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x78, 0x2c, 0x79, 0x2c, 0x62, 0x2c, 0x74, 0x29, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x78, 0x2c, 0x79, 0x2c, 0x62, 0x2c, 0x74, 0x2c, + 0x63, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, - 0x64, 0x28, 0x78, 0x2c, 0x79, 0x2c, 0x62, 0x2c, 0x74, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, + 0x64, 0x28, 0x78, 0x2c, 0x79, 0x2c, 0x62, 0x2c, 0x74, 0x2c, 0x63, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a, 0x09, 0x09, 0x77, 0x68, 0x65, 0x65, 0x6c, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x78, 0x2c, 0x79, 0x29, 0x0a,