| e8555c89 Andy McCall |
1 |
#include "catch.hpp" |
| 2 |
#include "BooleanInput.hh" |
| 3 |
|
| 4 |
#include <SDL.h> |
| 5 |
|
| 6 |
using namespace openmsx; |
| 7 |
|
| 8 |
TEST_CASE("BooleanInput: toString, parse") |
| 9 |
{ |
| 10 |
auto compare = [](const BooleanInput& input, const std::string& str) { |
| 11 |
auto str2 = toString(input); |
| 12 |
CHECK(str2 == str); |
| 13 |
|
| 14 |
auto input2 = parseBooleanInput(str); |
| 15 |
CHECK(input2); |
| 16 |
CHECK(*input2 == input); |
| 17 |
}; |
| 18 |
using ID = JoystickId; |
| 19 |
|
| 20 |
SECTION("keyboard") { |
| 21 |
compare(BooleanKeyboard(SDLK_a), "keyb A"); |
| 22 |
compare(BooleanKeyboard(SDLK_LALT), "keyb Left Alt"); |
| 23 |
|
| 24 |
|
| 25 |
auto k1 = parseBooleanInput("keyb PrintSCreen"); |
| 26 |
REQUIRE(k1); |
| 27 |
auto k2 = parseBooleanInput("keyb PRINT"); |
| 28 |
REQUIRE(k2); |
| 29 |
CHECK(*k1 == *k2); |
| 30 |
CHECK(*k2 == BooleanKeyboard(SDLK_PRINTSCREEN)); |
| 31 |
CHECK(toString(*k2) == "keyb PrintScreen"); |
| 32 |
} |
| 33 |
SECTION("mouse button") { |
| 34 |
compare(BooleanMouseButton( 2), "mouse button2"); |
| 35 |
compare(BooleanMouseButton(11), "mouse button11"); |
| 36 |
} |
| 37 |
SECTION("joystick button") { |
| 38 |
compare(BooleanJoystickButton(ID(0), 2), "joy1 button2"); |
| 39 |
compare(BooleanJoystickButton(ID(1), 4), "joy2 button4"); |
| 40 |
} |
| 41 |
SECTION("joystick hat") { |
| 42 |
compare(BooleanJoystickHat(ID(0), 1, BooleanJoystickHat::Direction::UP), "joy1 hat1 up"); |
| 43 |
compare(BooleanJoystickHat(ID(3), 5, BooleanJoystickHat::Direction::DOWN), "joy4 hat5 down"); |
| 44 |
compare(BooleanJoystickHat(ID(2), 4, BooleanJoystickHat::Direction::LEFT), "joy3 hat4 left"); |
| 45 |
compare(BooleanJoystickHat(ID(1), 2, BooleanJoystickHat::Direction::RIGHT), "joy2 hat2 right"); |
| 46 |
} |
| 47 |
SECTION("joystick axis") { |
| 48 |
compare(BooleanJoystickAxis(ID(0), 1, BooleanJoystickAxis::Direction::POS), "joy1 +axis1"); |
| 49 |
compare(BooleanJoystickAxis(ID(3), 2, BooleanJoystickAxis::Direction::NEG), "joy4 -axis2"); |
| 50 |
} |
| 51 |
SECTION("parse error") { |
| 52 |
CHECK(!parseBooleanInput("")); |
| 53 |
CHECK(!parseBooleanInput("bla")); |
| 54 |
|
| 55 |
CHECK(!parseBooleanInput("keyb")); |
| 56 |
CHECK(!parseBooleanInput("keyb invalid-key")); |
| 57 |
CHECK(!parseBooleanInput("keyb A too-many-args")); |
| 58 |
CHECK( parseBooleanInput("keyb B")); |
| 59 |
|
| 60 |
CHECK(!parseBooleanInput("mouse")); |
| 61 |
CHECK(!parseBooleanInput("mouse buttonA")); |
| 62 |
CHECK(!parseBooleanInput("mouse button1 too-many-args")); |
| 63 |
CHECK( parseBooleanInput("mouse button1")); |
| 64 |
|
| 65 |
CHECK(!parseBooleanInput("joy")); |
| 66 |
CHECK(!parseBooleanInput("joyZ")); |
| 67 |
CHECK(!parseBooleanInput("joy1")); |
| 68 |
CHECK(!parseBooleanInput("joy2 button")); |
| 69 |
CHECK(!parseBooleanInput("joy3 buttonA")); |
| 70 |
CHECK(!parseBooleanInput("joy4 button2 too-many-args")); |
| 71 |
CHECK( parseBooleanInput("joy4 button2")); |
| 72 |
|
| 73 |
CHECK(!parseBooleanInput("joy2 hat")); |
| 74 |
CHECK(!parseBooleanInput("joy2 hatA")); |
| 75 |
CHECK(!parseBooleanInput("joy2 hat3")); |
| 76 |
CHECK(!parseBooleanInput("joy2 hat3 bla")); |
| 77 |
CHECK(!parseBooleanInput("joy2 hat3 up too-many-args")); |
| 78 |
CHECK( parseBooleanInput("joy2 hat3 up")); |
| 79 |
|
| 80 |
CHECK(!parseBooleanInput("joy2 axis3")); |
| 81 |
CHECK(!parseBooleanInput("joy2 +axis")); |
| 82 |
CHECK(!parseBooleanInput("joy2 +axis@")); |
| 83 |
CHECK( parseBooleanInput("joy2 +axis2")); |
| 84 |
} |
| 85 |
} |
| 86 |
|
| 87 |
TEST_CASE("BooleanInput: capture") |
| 88 |
{ |
| 89 |
auto getJoyDeadThreshold = [](JoystickId ) { return 8192; }; |
| 90 |
auto check = [&](const Event& event, std::string_view expected) { |
| 91 |
auto input = captureBooleanInput(event, getJoyDeadThreshold); |
| 92 |
if (expected.empty()) { |
| 93 |
CHECK(!input); |
| 94 |
} else { |
| 95 |
CHECK(toString(*input) == expected); |
| 96 |
} |
| 97 |
}; |
| 98 |
|
| 99 |
SDL_Event sdl = {}; |
| 100 |
|
| 101 |
SECTION("keyboard") { |
| 102 |
check(KeyDownEvent::create(SDLK_h), "keyb H"); |
| 103 |
check(KeyUpEvent ::create(SDLK_h), ""); |
| 104 |
} |
| 105 |
SECTION("mouse") { |
| 106 |
sdl.button = SDL_MouseButtonEvent{}; |
| 107 |
sdl.button.type = SDL_MOUSEBUTTONDOWN; |
| 108 |
sdl.button.button = 2; |
| 109 |
check(MouseButtonDownEvent(sdl), "mouse button2"); |
| 110 |
sdl.button.type = SDL_MOUSEBUTTONUP; |
| 111 |
check(MouseButtonUpEvent(sdl), ""); |
| 112 |
|
| 113 |
sdl.motion = SDL_MouseMotionEvent{}; |
| 114 |
sdl.motion.type = SDL_MOUSEMOTION; |
| 115 |
sdl.motion.xrel = 10; |
| 116 |
sdl.motion.yrel = 20; |
| 117 |
sdl.motion.x = 30; |
| 118 |
sdl.motion.y = 40; |
| 119 |
check(MouseMotionEvent(sdl), ""); |
| 120 |
|
| 121 |
sdl.wheel = SDL_MouseWheelEvent{}; |
| 122 |
sdl.wheel.type = SDL_MOUSEWHEEL; |
| 123 |
sdl.wheel.x = 2; |
| 124 |
sdl.wheel.y = 4; |
| 125 |
check(MouseWheelEvent(sdl), ""); |
| 126 |
} |
| 127 |
SECTION("joystick") { |
| 128 |
sdl.jbutton = SDL_JoyButtonEvent{}; |
| 129 |
sdl.jbutton.type = SDL_JOYBUTTONDOWN; |
| 130 |
sdl.jbutton.which = 0; |
| 131 |
sdl.jbutton.button = 3; |
| 132 |
check(JoystickButtonDownEvent(sdl), "joy1 button3"); |
| 133 |
sdl.jbutton.type = SDL_JOYBUTTONUP; |
| 134 |
check(JoystickButtonUpEvent(sdl), ""); |
| 135 |
|
| 136 |
sdl.jhat = SDL_JoyHatEvent{}; |
| 137 |
sdl.jhat.type = SDL_JOYHATMOTION; |
| 138 |
sdl.jhat.which = 1; |
| 139 |
sdl.jhat.hat = 1; |
| 140 |
sdl.jhat.value = SDL_HAT_LEFT; |
| 141 |
check(JoystickHatEvent(sdl), "joy2 hat1 left"); |
| 142 |
sdl.jhat.value = SDL_HAT_CENTERED; |
| 143 |
check(JoystickHatEvent(sdl), ""); |
| 144 |
sdl.jhat.value = SDL_HAT_LEFTDOWN; |
| 145 |
check(JoystickHatEvent(sdl), ""); |
| 146 |
|
| 147 |
sdl.jaxis = SDL_JoyAxisEvent{}; |
| 148 |
sdl.jaxis.type = SDL_JOYAXISMOTION; |
| 149 |
sdl.jaxis.which = 2; |
| 150 |
sdl.jaxis.axis = 1; |
| 151 |
sdl.jaxis.value = 32000; |
| 152 |
check(JoystickAxisMotionEvent(sdl), "joy3 +axis1"); |
| 153 |
sdl.jaxis.value = -32000; |
| 154 |
check(JoystickAxisMotionEvent(sdl), "joy3 -axis1"); |
| 155 |
sdl.jaxis.value = 2000; |
| 156 |
check(JoystickAxisMotionEvent(sdl), ""); |
| 157 |
} |
| 158 |
SECTION("other SDL") { |
| 159 |
sdl.window = SDL_WindowEvent{}; |
| 160 |
sdl.window.type = SDL_WINDOWEVENT; |
| 161 |
check(WindowEvent(sdl), ""); |
| 162 |
} |
| 163 |
SECTION("other") { |
| 164 |
check(FileDropEvent("file.ext"), ""); |
| 165 |
check(BootEvent{}, ""); |
| 166 |
} |
| 167 |
} |
| 168 |
|
| 169 |
TEST_CASE("BooleanInput: match") |
| 170 |
{ |
| 171 |
|
| 172 |
auto keyDownA = KeyDownEvent::create(SDLK_a); |
| 173 |
auto keyDownB = KeyDownEvent::create(SDLK_b); |
| 174 |
auto keyUpA = KeyUpEvent::create(SDLK_a); |
| 175 |
auto keyUpB = KeyUpEvent::create(SDLK_b); |
| 176 |
|
| 177 |
SDL_Event sdl; |
| 178 |
sdl.button = SDL_MouseButtonEvent{}; |
| 179 |
sdl.button.type = SDL_MOUSEBUTTONDOWN; |
| 180 |
sdl.button.button = 1; |
| 181 |
auto mouseDown1 = MouseButtonDownEvent(sdl); |
| 182 |
sdl.button.button = 2; |
| 183 |
auto mouseDown2 = MouseButtonDownEvent(sdl); |
| 184 |
|
| 185 |
sdl.button.type = SDL_MOUSEBUTTONUP; |
| 186 |
sdl.button.button = 1; |
| 187 |
auto mouseUp1 = MouseButtonUpEvent(sdl); |
| 188 |
sdl.button.button = 2; |
| 189 |
auto mouseUp2 = MouseButtonUpEvent(sdl); |
| 190 |
|
| 191 |
sdl.wheel = SDL_MouseWheelEvent{}; |
| 192 |
sdl.wheel.type = SDL_MOUSEWHEEL; |
| 193 |
sdl.wheel.x = 2; |
| 194 |
sdl.wheel.y = 4; |
| 195 |
auto mouseWheel = MouseWheelEvent(sdl); |
| 196 |
|
| 197 |
sdl.jbutton = SDL_JoyButtonEvent{}; |
| 198 |
sdl.jbutton.type = SDL_JOYBUTTONDOWN; |
| 199 |
sdl.jbutton.which = 0; |
| 200 |
sdl.jbutton.button = 2; |
| 201 |
auto joy1button2Down = JoystickButtonDownEvent(sdl); |
| 202 |
sdl.jbutton.type = SDL_JOYBUTTONUP; |
| 203 |
auto joy1button2Up = JoystickButtonUpEvent(sdl); |
| 204 |
|
| 205 |
sdl.jbutton.type = SDL_JOYBUTTONDOWN; |
| 206 |
sdl.jbutton.which = 0; |
| 207 |
sdl.jbutton.button = 3; |
| 208 |
auto joy1button3Down = JoystickButtonDownEvent(sdl); |
| 209 |
sdl.jbutton.type = SDL_JOYBUTTONUP; |
| 210 |
auto joy1button3Up = JoystickButtonUpEvent(sdl); |
| 211 |
|
| 212 |
sdl.jbutton.type = SDL_JOYBUTTONDOWN; |
| 213 |
sdl.jbutton.which = 1; |
| 214 |
sdl.jbutton.button = 2; |
| 215 |
auto joy2button2Down = JoystickButtonDownEvent(sdl); |
| 216 |
sdl.type = SDL_JOYBUTTONUP; |
| 217 |
auto joy2button2Up = JoystickButtonUpEvent(sdl); |
| 218 |
|
| 219 |
sdl.jhat = SDL_JoyHatEvent{}; |
| 220 |
sdl.jhat.type = SDL_JOYHATMOTION; |
| 221 |
sdl.jhat.which = 0; |
| 222 |
sdl.jhat.hat = 1; |
| 223 |
sdl.jhat.value = SDL_HAT_LEFT; |
| 224 |
auto joy1hat1left = JoystickHatEvent(sdl); |
| 225 |
sdl.jhat.value = SDL_HAT_LEFTDOWN; |
| 226 |
auto joy1hat1leftDown = JoystickHatEvent(sdl); |
| 227 |
sdl.jhat.value = SDL_HAT_DOWN; |
| 228 |
auto joy1hat1down = JoystickHatEvent(sdl); |
| 229 |
|
| 230 |
sdl.jhat.type = SDL_JOYHATMOTION; |
| 231 |
sdl.jhat.which = 0; |
| 232 |
sdl.jhat.hat = 2; |
| 233 |
sdl.jhat.value = SDL_HAT_LEFT; |
| 234 |
auto joy1hat2left = JoystickHatEvent(sdl); |
| 235 |
sdl.jhat.value = SDL_HAT_LEFTDOWN; |
| 236 |
auto joy1hat2leftDown = JoystickHatEvent(sdl); |
| 237 |
sdl.jhat.value = SDL_HAT_DOWN; |
| 238 |
auto joy1hat2down = JoystickHatEvent(sdl); |
| 239 |
|
| 240 |
sdl.jhat.type = SDL_JOYHATMOTION; |
| 241 |
sdl.jhat.which = 1; |
| 242 |
sdl.jhat.hat = 1; |
| 243 |
sdl.jhat.value = SDL_HAT_LEFT; |
| 244 |
auto joy2hat1left = JoystickHatEvent(sdl); |
| 245 |
sdl.jhat.value = SDL_HAT_LEFTDOWN; |
| 246 |
auto joy2hat1leftDown = JoystickHatEvent(sdl); |
| 247 |
sdl.jhat.value = SDL_HAT_DOWN; |
| 248 |
auto joy2hat1down = JoystickHatEvent(sdl); |
| 249 |
|
| 250 |
sdl.jaxis = SDL_JoyAxisEvent{}; |
| 251 |
sdl.jaxis.type = SDL_JOYAXISMOTION; |
| 252 |
sdl.jaxis.which = 0; |
| 253 |
sdl.jaxis.axis = 1; |
| 254 |
sdl.jaxis.value = 32000; |
| 255 |
auto joy1axis1P32000 = JoystickAxisMotionEvent(sdl); |
| 256 |
sdl.jaxis.value = 123; |
| 257 |
auto joy1axis1P123 = JoystickAxisMotionEvent(sdl); |
| 258 |
sdl.jaxis.value = -27000; |
| 259 |
auto joy1axis1M27000 = JoystickAxisMotionEvent(sdl); |
| 260 |
|
| 261 |
sdl.jaxis.type = SDL_JOYAXISMOTION; |
| 262 |
sdl.jaxis.which = 0; |
| 263 |
sdl.jaxis.axis = 2; |
| 264 |
sdl.jaxis.value = 32000; |
| 265 |
auto joy1axis2P32000 = JoystickAxisMotionEvent(sdl); |
| 266 |
sdl.jaxis.value = 123; |
| 267 |
auto joy1axis2P123 = JoystickAxisMotionEvent(sdl); |
| 268 |
sdl.jaxis.value = -27000; |
| 269 |
auto joy1axis2M27000 = JoystickAxisMotionEvent(sdl); |
| 270 |
|
| 271 |
sdl.jaxis.type = SDL_JOYAXISMOTION; |
| 272 |
sdl.jaxis.which = 1; |
| 273 |
sdl.jaxis.axis = 1; |
| 274 |
sdl.jaxis.value = 32000; |
| 275 |
auto joy2axis1P32000 = JoystickAxisMotionEvent(sdl); |
| 276 |
sdl.jaxis.value = 123; |
| 277 |
auto joy2axis1P123 = JoystickAxisMotionEvent(sdl); |
| 278 |
sdl.jaxis.value = -27000; |
| 279 |
auto joy2axis1M27000 = JoystickAxisMotionEvent(sdl); |
| 280 |
|
| 281 |
|
| 282 |
auto getJoyDeadThreshold = [](JoystickId ) { return 8192; }; |
| 283 |
auto check = [&](const std::optional<BooleanInput>& binding, const Event& event, std::optional<bool> expected) { |
| 284 |
REQUIRE(binding); |
| 285 |
CHECK(match(*binding, event, getJoyDeadThreshold) == expected); |
| 286 |
}; |
| 287 |
|
| 288 |
auto bKeyA = parseBooleanInput("keyb A"); |
| 289 |
check(bKeyA, keyDownA, true); |
| 290 |
check(bKeyA, keyUpA, false); |
| 291 |
check(bKeyA, keyDownB, {}); |
| 292 |
check(bKeyA, keyUpB, {}); |
| 293 |
check(bKeyA, joy1button2Down, {}); |
| 294 |
check(bKeyA, mouseWheel, {}); |
| 295 |
|
| 296 |
auto bMouseButton1 = parseBooleanInput("mouse button1"); |
| 297 |
check(bMouseButton1, mouseDown1, true); |
| 298 |
check(bMouseButton1, mouseUp1, false); |
| 299 |
check(bMouseButton1, mouseDown2, {}); |
| 300 |
check(bMouseButton1, mouseUp2, {}); |
| 301 |
check(bMouseButton1, keyDownA, {}); |
| 302 |
check(bMouseButton1, mouseWheel, {}); |
| 303 |
|
| 304 |
auto bJoy1Button2 = parseBooleanInput("joy1 button2"); |
| 305 |
check(bJoy1Button2, joy1button2Down, true); |
| 306 |
check(bJoy1Button2, joy1button2Up, false); |
| 307 |
check(bJoy1Button2, joy1button3Down, {}); |
| 308 |
check(bJoy1Button2, joy1button3Up, {}); |
| 309 |
check(bJoy1Button2, joy2button2Down, {}); |
| 310 |
check(bJoy1Button2, joy2button2Up, {}); |
| 311 |
check(bJoy1Button2, mouseUp2, {}); |
| 312 |
check(bJoy1Button2, mouseWheel, {}); |
| 313 |
|
| 314 |
auto bJoy1Hat1Left = parseBooleanInput("joy1 hat1 left"); |
| 315 |
check(bJoy1Hat1Left, joy1hat1left, true); |
| 316 |
check(bJoy1Hat1Left, joy1hat1leftDown, true); |
| 317 |
check(bJoy1Hat1Left, joy1hat1down, false); |
| 318 |
check(bJoy1Hat1Left, joy1hat2left, {}); |
| 319 |
check(bJoy1Hat1Left, joy1hat2leftDown, {}); |
| 320 |
check(bJoy1Hat1Left, joy1hat2down, {}); |
| 321 |
check(bJoy1Hat1Left, joy2hat1left, {}); |
| 322 |
check(bJoy1Hat1Left, joy2hat1leftDown, {}); |
| 323 |
check(bJoy1Hat1Left, joy2hat1down, {}); |
| 324 |
check(bJoy1Hat1Left, joy1button2Down, {}); |
| 325 |
check(bJoy1Hat1Left, mouseWheel, {}); |
| 326 |
|
| 327 |
auto bJoy1Axis1P = parseBooleanInput("joy1 +axis1"); |
| 328 |
check(bJoy1Axis1P, joy1axis1P32000, true); |
| 329 |
check(bJoy1Axis1P, joy1axis1P123, false); |
| 330 |
check(bJoy1Axis1P, joy1axis1M27000, false); |
| 331 |
check(bJoy1Axis1P, joy1axis2P32000, {}); |
| 332 |
check(bJoy1Axis1P, joy1axis2P123, {}); |
| 333 |
check(bJoy1Axis1P, joy1axis2M27000, {}); |
| 334 |
check(bJoy1Axis1P, joy2axis1P32000, {}); |
| 335 |
check(bJoy1Axis1P, joy2axis1P123, {}); |
| 336 |
check(bJoy1Axis1P, joy2axis1M27000, {}); |
| 337 |
check(bJoy1Axis1P, joy1hat1left, {}); |
| 338 |
check(bJoy1Axis1P, mouseWheel, {}); |
| 339 |
} |