diff --git a/src/platform/sdl2/build.sh b/src/platform/sdl2/build.sh index 9686898..56ce0c0 100755 --- a/src/platform/sdl2/build.sh +++ b/src/platform/sdl2/build.sh @@ -4,6 +4,4 @@ set -e g++ -DSDL2_GLES -std=c++11 `sdl2-config --cflags` -O3 -fno-exceptions -fno-rtti -ffunction-sections -fdata-sections -Wl,--gc-sections -DNDEBUG -D__SDL2__ main.cpp ../../libs/stb_vorbis/stb_vorbis.c ../../libs/minimp3/minimp3.cpp ../../libs/tinf/tinflate.c -I../../ -o OpenLara `sdl2-config --libs` -lGLESv2 -lEGL -lm -lrt -lpthread -lasound -ludev # Use this compilation line to build SDL2/OpenGL version -g++ -std=c++11 `sdl2-config --cflags` -O3 -fno-exceptions -fno-rtti -ffunction-sections -fdata-sections -Wl,--gc-sections -DNDEBUG -D__SDL2__ main.cpp ../../libs/stb_vorbis/stb_vorbis.c ../../libs/minimp3/minimp3.cpp ../../libs/tinf/tinflate.c -I../../ -o OpenLara `sdl2-config --libs` -lGL -lm -lrt -lpthread -lasound -ludev - -#strip ../../../bin/OpenLara --strip-all --remove-section=.comment --remove-section=.note \ No newline at end of file +#g++ -std=c++11 `sdl2-config --cflags` -O3 -fno-exceptions -fno-rtti -ffunction-sections -fdata-sections -Wl,--gc-sections -DNDEBUG -D__SDL2__ main.cpp ../../libs/stb_vorbis/stb_vorbis.c ../../libs/minimp3/minimp3.cpp ../../libs/tinf/tinflate.c -I../../ -o OpenLara `sdl2-config --libs` -lGL -lm -lrt -lpthread -lasound -ludev \ No newline at end of file diff --git a/src/platform/sdl2/main.cpp b/src/platform/sdl2/main.cpp index b05fe39..454c304 100644 --- a/src/platform/sdl2/main.cpp +++ b/src/platform/sdl2/main.cpp @@ -1,14 +1,8 @@ #include #include #include -#include -#include #include #include -//#include -#include -#include -#include #include // SDL2 include stuff @@ -106,12 +100,9 @@ void sndFree() { } // Input -#define MAX_INPUT_DEVICES 16 -int inputDevices[MAX_INPUT_DEVICES]; - -udev *udevObj; -udev_monitor *udevMon; -int udevMon_fd; +SDL_GameController *sdl_gamecontroller; +SDL_Joystick *sdl_joystick; +bool using_old_joystick_interface; vec2 joyL, joyR; @@ -126,61 +117,57 @@ void osJoyVibrate(int index, float L, float R) { InputKey codeToInputKey(int code) { switch (code) { // keyboard - case KEY_LEFT : return ikLeft; - case KEY_RIGHT : return ikRight; - case KEY_UP : return ikUp; - case KEY_DOWN : return ikDown; - case KEY_SPACE : return ikSpace; - case KEY_TAB : return ikTab; - case KEY_ENTER : return ikEnter; - case KEY_ESC : return ikEscape; - case KEY_LEFTSHIFT : - case KEY_RIGHTSHIFT : return ikShift; - case KEY_LEFTCTRL : - case KEY_RIGHTCTRL : return ikCtrl; - case KEY_LEFTALT : - case KEY_RIGHTALT : return ikAlt; - case KEY_0 : return ik0; - case KEY_1 : return ik1; - case KEY_2 : return ik2; - case KEY_3 : return ik3; - case KEY_4 : return ik4; - case KEY_5 : return ik5; - case KEY_6 : return ik6; - case KEY_7 : return ik7; - case KEY_8 : return ik8; - case KEY_9 : return ik9; - case KEY_A : return ikA; - case KEY_B : return ikB; - case KEY_C : return ikC; - case KEY_D : return ikD; - case KEY_E : return ikE; - case KEY_F : return ikF; - case KEY_G : return ikG; - case KEY_H : return ikH; - case KEY_I : return ikI; - case KEY_J : return ikJ; - case KEY_K : return ikK; - case KEY_L : return ikL; - case KEY_M : return ikM; - case KEY_N : return ikN; - case KEY_O : return ikO; - case KEY_P : return ikP; - case KEY_Q : return ikQ; - case KEY_R : return ikR; - case KEY_S : return ikS; - case KEY_T : return ikT; - case KEY_U : return ikU; - case KEY_V : return ikV; - case KEY_W : return ikW; - case KEY_X : return ikX; - case KEY_Y : return ikY; - case KEY_Z : return ikZ; - case KEY_HOMEPAGE : return ikEscape; - // mouse - case BTN_LEFT : return ikMouseL; - case BTN_RIGHT : return ikMouseR; - case BTN_MIDDLE : return ikMouseM; + case SDL_SCANCODE_LEFT : return ikLeft; + case SDL_SCANCODE_RIGHT : return ikRight; + case SDL_SCANCODE_UP : return ikUp; + case SDL_SCANCODE_DOWN : return ikDown; + case SDL_SCANCODE_SPACE : return ikSpace; + case SDL_SCANCODE_TAB : return ikTab; + case SDL_SCANCODE_RETURN : return ikEnter; + case SDL_SCANCODE_ESCAPE : return ikEscape; + case SDL_SCANCODE_LSHIFT : + case SDL_SCANCODE_RSHIFT : return ikShift; + case SDL_SCANCODE_LCTRL : + case SDL_SCANCODE_RCTRL : return ikCtrl; + case SDL_SCANCODE_LALT : + case SDL_SCANCODE_RALT : return ikAlt; + case SDL_SCANCODE_0 : return ik0; + case SDL_SCANCODE_1 : return ik1; + case SDL_SCANCODE_2 : return ik2; + case SDL_SCANCODE_3 : return ik3; + case SDL_SCANCODE_4 : return ik4; + case SDL_SCANCODE_5 : return ik5; + case SDL_SCANCODE_6 : return ik6; + case SDL_SCANCODE_7 : return ik7; + case SDL_SCANCODE_8 : return ik8; + case SDL_SCANCODE_9 : return ik9; + case SDL_SCANCODE_A : return ikA; + case SDL_SCANCODE_B : return ikB; + case SDL_SCANCODE_C : return ikC; + case SDL_SCANCODE_D : return ikD; + case SDL_SCANCODE_E : return ikE; + case SDL_SCANCODE_F : return ikF; + case SDL_SCANCODE_G : return ikG; + case SDL_SCANCODE_H : return ikH; + case SDL_SCANCODE_I : return ikI; + case SDL_SCANCODE_J : return ikJ; + case SDL_SCANCODE_K : return ikK; + case SDL_SCANCODE_L : return ikL; + case SDL_SCANCODE_M : return ikM; + case SDL_SCANCODE_N : return ikN; + case SDL_SCANCODE_O : return ikO; + case SDL_SCANCODE_P : return ikP; + case SDL_SCANCODE_Q : return ikQ; + case SDL_SCANCODE_R : return ikR; + case SDL_SCANCODE_S : return ikS; + case SDL_SCANCODE_T : return ikT; + case SDL_SCANCODE_U : return ikU; + case SDL_SCANCODE_V : return ikV; + case SDL_SCANCODE_W : return ikW; + case SDL_SCANCODE_X : return ikX; + case SDL_SCANCODE_Y : return ikY; + case SDL_SCANCODE_Z : return ikZ; + case SDL_SCANCODE_AC_HOME : return ikEscape; } return ikNone; } @@ -188,89 +175,44 @@ InputKey codeToInputKey(int code) { JoyKey codeToJoyKey(int code) { switch (code) { // gamepad - case BTN_A : return jkA; - case BTN_B : return jkB; - case BTN_X : return jkX; - case BTN_Y : return jkY; - case BTN_TL : return jkLB; - case BTN_TR : return jkRB; - case BTN_SELECT : return jkSelect; - case BTN_START : return jkStart; - case BTN_THUMBL : return jkL; - case BTN_THUMBR : return jkR; - case BTN_TL2 : return jkLT; - case BTN_TR2 : return jkRT; + case SDL_CONTROLLER_BUTTON_A : return jkA; + case SDL_CONTROLLER_BUTTON_B : return jkB; + case SDL_CONTROLLER_BUTTON_X : return jkX; + case SDL_CONTROLLER_BUTTON_Y : return jkY; + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER : return jkLB; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER : return jkRB; + case SDL_CONTROLLER_BUTTON_BACK : return jkSelect; + case SDL_CONTROLLER_BUTTON_START : return jkStart; + case SDL_CONTROLLER_BUTTON_LEFTSTICK : return jkL; + case SDL_CONTROLLER_BUTTON_RIGHTSTICK : return jkR; } return jkNone; } -int inputDevIndex(const char *node) { - const char *str = strstr(node, "/event"); - if (str) - return atoi(str + 6); - return -1; -} - -void inputDevAdd(const char *node) { - int index = inputDevIndex(node); - if (index != -1) { - inputDevices[index] = open(node, O_RDONLY | O_NONBLOCK); - ioctl(inputDevices[index], EVIOCGRAB, 1); - //LOG("input: add %s\n", node); - } -} - -void inputDevRemove(const char *node) { - int index = inputDevIndex(node); - if (index != -1 && inputDevices[index] != -1) { - close(inputDevices[index]); - //LOG("input: remove %s\n", node); - } -} - bool inputInit() { - joyL = joyR = vec2(0); - - for (int i = 0; i < MAX_INPUT_DEVICES; i++) - inputDevices[i] = -1; - - udevObj = udev_new(); - if (!udevObj) - return false; - - udevMon = udev_monitor_new_from_netlink(udevObj, "udev"); - udev_monitor_filter_add_match_subsystem_devtype(udevMon, "input", NULL); - udev_monitor_enable_receiving(udevMon); - udevMon_fd = udev_monitor_get_fd(udevMon); - - udev_enumerate *e = udev_enumerate_new(udevObj); - udev_enumerate_add_match_subsystem(e, "input"); - udev_enumerate_scan_devices(e); - udev_list_entry *devices = udev_enumerate_get_list_entry(e); - - udev_list_entry *entry; - udev_list_entry_foreach(entry, devices) { - const char *path, *node; - udev_device *device; - - path = udev_list_entry_get_name(entry); - device = udev_device_new_from_syspath(udevObj, path); - node = udev_device_get_devnode(device); - - if (node) - inputDevAdd(node); + sdl_gamecontroller = NULL; + sdl_joystick = NULL; + if (SDL_NumJoysticks() > 0) { + if(SDL_IsGameController(0)) { + sdl_gamecontroller = SDL_GameControllerOpen(0); + } + else { + sdl_joystick = SDL_JoystickOpen(0); + using_old_joystick_interface = true; + } } - udev_enumerate_unref(e); - return true; } void inputFree() { - for (int i = 0; i < MAX_INPUT_DEVICES; i++) - if (inputDevices[i] != -1) - close(inputDevices[i]); - udev_monitor_unref(udevMon); - udev_unref(udevObj); + if (sdl_gamecontroller != NULL) { + SDL_GameControllerClose(sdl_gamecontroller); + sdl_gamecontroller = NULL; + } + if (sdl_joystick != NULL) { + SDL_JoystickClose(sdl_joystick); + sdl_joystick = NULL; + } } #define JOY_DEAD_ZONE_STICK 8192 @@ -292,94 +234,76 @@ vec2 joyDir(const vec2 &value) { void inputUpdate() { // get input events - input_event events[16]; - for (int i = 0; i < MAX_INPUT_DEVICES; i++) { - if (inputDevices[i] == -1) continue; - int rb = read(inputDevices[i], events, sizeof(events)); + int joyIndex = 0; // TODO: joy index - int joyIndex = 0; // TODO: joy index - - input_event *e = events; - while (rb > 0) { - switch (e->type) { - case EV_KEY : { - InputKey key = codeToInputKey(e->code); - if (key != ikNone) { - if (key == ikMouseL || key == ikMouseR || key == ikMouseM) - Input::setPos(key, Input::mouse.pos); - Input::setDown(key, e->value != 0); - } else { - JoyKey key = codeToJoyKey(e->code); - Input::setJoyDown(joyIndex, key, e->value != 0); - } - break; + SDL_Event event; + while (SDL_PollEvent(&event) == 1) { // while there are still events to be processed + switch (event.type) { + case SDL_KEYDOWN: { + int scancode = event.key.keysym.scancode; + InputKey key = codeToInputKey(scancode); + if (key != ikNone) { + Input::setDown(key, 1); + } + break; + } + case SDL_KEYUP: { + int scancode = event.key.keysym.scancode; + InputKey key = codeToInputKey(scancode); + if (key != ikNone) { + Input::setDown(key, 0); } - case EV_REL : { - vec2 delta(0); - delta[e->code] = float(e->value); - Input::setPos(ikMouseL, Input::mouse.pos + delta); - break; - } - case EV_ABS : { - switch (e->code) { - // Left stick - case ABS_X : joyL.x = joyAxisValue(e->value); break; - case ABS_Y : joyL.y = joyAxisValue(e->value); break; - // Right stick - case ABS_RX : joyR.x = joyAxisValue(e->value); break; - case ABS_RY : joyR.y = joyAxisValue(e->value); break; - // Left trigger - case ABS_Z : Input::setJoyPos(joyIndex, jkLT, joyTrigger(e->value)); break; - // Right trigger - case ABS_RZ : Input::setJoyPos(joyIndex, jkRT, joyTrigger(e->value)); break; - // D-PAD - case ABS_HAT0X : - case ABS_THROTTLE : - Input::setJoyDown(joyIndex, jkLeft, e->value < 0); - Input::setJoyDown(joyIndex, jkRight, e->value > 0); - break; - case ABS_HAT0Y : - case ABS_RUDDER : - Input::setJoyDown(joyIndex, jkUp, e->value < 0); - Input::setJoyDown(joyIndex, jkDown, e->value > 0); - break; - } - - Input::setJoyPos(joyIndex, jkL, joyDir(joyL)); - Input::setJoyPos(joyIndex, jkR, joyDir(joyR)); - } - } - //LOG("input: type = %d, code = %d, value = %d\n", int(e->type), int(e->code), int(e->value)); - e++; - rb -= sizeof(events[0]); + break; + } + case SDL_CONTROLLERBUTTONDOWN: { + JoyKey key = codeToJoyKey(event.cbutton.button); + Input::setJoyDown(joyIndex, key, 1); + break; + } + case SDL_CONTROLLERBUTTONUP: { + JoyKey key = codeToJoyKey(event.cbutton.button); + Input::setJoyDown(joyIndex, key, 0); + break; + } + case SDL_CONTROLLERAXISMOTION: { + switch (event.caxis.axis) { + case SDL_CONTROLLER_AXIS_LEFTX: + if (event.caxis.value < 0) { + Input::setJoyDown(joyIndex, jkLeft, 1); + Input::setJoyDown(joyIndex, jkRight, 0); + } + if (event.caxis.value > 0) { + Input::setJoyDown(joyIndex, jkRight, 1); + Input::setJoyDown(joyIndex, jkLeft, 0); + } + if (event.caxis.value == 0) { + Input::setJoyDown(joyIndex, jkRight, 0); + Input::setJoyDown(joyIndex, jkLeft, 0); + } + break; + case SDL_CONTROLLER_AXIS_LEFTY: + if (event.caxis.value < 0) { + Input::setJoyDown(joyIndex, jkUp, 1); + Input::setJoyDown(joyIndex, jkDown, 0); + } + if (event.caxis.value > 0) { + Input::setJoyDown(joyIndex, jkUp, 0); + Input::setJoyDown(joyIndex, jkDown, 1); + } + if (event.caxis.value == 0) { + Input::setJoyDown(joyIndex, jkUp, 0); + Input::setJoyDown(joyIndex, jkDown, 0); + } + break; + } + break; + } } - } -// monitoring plug and unplug input devices - fd_set fds; - FD_ZERO(&fds); - FD_SET(udevMon_fd, &fds); - - timeval tv; - tv.tv_sec = 0; - tv.tv_usec = 0; - - if (select(udevMon_fd + 1, &fds, NULL, NULL, &tv) > 0 && FD_ISSET(udevMon_fd, &fds)) { - udev_device *device = udev_monitor_receive_device(udevMon); - if (device) { - const char *node = udev_device_get_devnode(device); - if (node) { - const char *action = udev_device_get_action(device); - if (!strcmp(action, "add")) - inputDevAdd(node); - if (!strcmp(action, "remove")) - inputDevRemove(node); - } - udev_device_unref(device); - } else - LOG("! input: receive_device\n"); - } + Input::setJoyPos(joyIndex, jkL, joyDir(joyL)); + Input::setJoyPos(joyIndex, jkR, joyDir(joyR)); + } } int main(int argc, char **argv) { @@ -387,7 +311,8 @@ int main(int argc, char **argv) { int w, h; SDL_DisplayMode current; - SDL_Init(SDL_INIT_VIDEO); + + SDL_Init(SDL_INIT_VIDEO|SDL_INIT_EVENTS|SDL_INIT_GAMECONTROLLER); SDL_GetCurrentDisplayMode(0, ¤t); @@ -397,7 +322,8 @@ int main(int argc, char **argv) { // We start in fullscreen mode using the vide mode currently in use, to avoid video mode changes. SDL_Window *window = SDL_CreateWindow(WND_TITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - current.w, current.h, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN_DESKTOP); + //current.w, current.h, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN_DESKTOP); + 640, 480, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); // We try to use the current video mode, but we inform the core of whatever mode SDL2 gave us in the end. SDL_GetWindowSize(window, &w, &h); @@ -432,12 +358,12 @@ int main(int argc, char **argv) { sndInit(); + inputInit(); + char *lvlName = argc > 1 ? argv[1] : NULL; Game::init(lvlName); - inputInit(); // initialize and grab input devices - while (!Core::isQuit) { inputUpdate(); @@ -448,8 +374,6 @@ int main(int argc, char **argv) { } }; - inputFree(); - sndFree(); Game::deinit();