2019-02-12 10:30:24 +00:00
|
|
|
|
2015-08-29 18:23:16 +00:00
|
|
|
#if defined(USE_SDL)
|
2019-02-07 22:44:30 +00:00
|
|
|
#include <map>
|
2015-08-29 18:23:16 +00:00
|
|
|
#include "types.h"
|
|
|
|
#include "cfg/cfg.h"
|
|
|
|
#include "linux-dist/main.h"
|
|
|
|
#include "sdl/sdl.h"
|
2019-02-07 15:59:24 +00:00
|
|
|
#include "rend/gui.h"
|
2015-10-11 16:06:06 +00:00
|
|
|
#ifndef GLES
|
|
|
|
#include "khronos/GL3/gl3w.h"
|
2015-09-12 18:19:28 +00:00
|
|
|
#endif
|
2015-08-29 18:23:16 +00:00
|
|
|
#endif
|
2019-02-12 14:56:44 +00:00
|
|
|
#include "hw/maple/maple_devs.h"
|
2019-02-12 10:30:24 +00:00
|
|
|
#include "sdl_gamepad.h"
|
|
|
|
#include "sdl_keyboard.h"
|
2015-08-29 18:23:16 +00:00
|
|
|
|
2015-10-11 16:06:06 +00:00
|
|
|
static SDL_Window* window = NULL;
|
|
|
|
static SDL_GLContext glcontext;
|
|
|
|
|
2015-08-29 18:23:16 +00:00
|
|
|
#ifdef TARGET_PANDORA
|
|
|
|
#define WINDOW_WIDTH 800
|
|
|
|
#else
|
|
|
|
#define WINDOW_WIDTH 640
|
|
|
|
#endif
|
|
|
|
#define WINDOW_HEIGHT 480
|
|
|
|
|
2019-02-21 21:39:26 +00:00
|
|
|
static std::shared_ptr<SDLMouseGamepadDevice> sdl_mouse_gamepad;
|
|
|
|
static std::shared_ptr<SDLKbGamepadDevice> sdl_kb_gamepad;
|
2019-02-12 10:30:24 +00:00
|
|
|
static SDLKeyboardDevice* sdl_keyboard = NULL;
|
2015-08-29 18:23:16 +00:00
|
|
|
|
2019-02-25 16:52:53 +00:00
|
|
|
extern void dc_exit();
|
2015-08-29 18:23:16 +00:00
|
|
|
|
|
|
|
#ifdef TARGET_PANDORA
|
|
|
|
extern char OSD_Info[128];
|
|
|
|
extern int OSD_Delay;
|
|
|
|
extern char OSD_Counters[256];
|
|
|
|
extern int OSD_Counter;
|
|
|
|
#endif
|
|
|
|
|
2019-02-07 22:44:30 +00:00
|
|
|
extern u32 mo_buttons;
|
|
|
|
extern s32 mo_x_abs;
|
|
|
|
extern s32 mo_y_abs;
|
2019-02-24 12:19:50 +00:00
|
|
|
extern f32 mo_x_delta;
|
|
|
|
extern f32 mo_y_delta;
|
|
|
|
extern f32 mo_wheel_delta;
|
2015-08-29 18:23:16 +00:00
|
|
|
|
2019-02-12 10:30:24 +00:00
|
|
|
extern int screen_width, screen_height;
|
2015-08-29 18:23:16 +00:00
|
|
|
|
2019-02-12 14:56:44 +00:00
|
|
|
static void sdl_open_joystick(int index)
|
|
|
|
{
|
|
|
|
SDL_Joystick *pJoystick = SDL_JoystickOpen(index);
|
2015-08-29 18:23:16 +00:00
|
|
|
|
2019-02-12 14:56:44 +00:00
|
|
|
if (pJoystick == NULL)
|
|
|
|
{
|
|
|
|
printf("SDL: Cannot open joystick %d\n", index + 1);
|
|
|
|
return;
|
|
|
|
}
|
2019-02-21 13:49:27 +00:00
|
|
|
std::shared_ptr<SDLGamepadDevice> gamepad = std::make_shared<SDLGamepadDevice>(index < MAPLE_PORTS ? index : -1, pJoystick);
|
|
|
|
SDLGamepadDevice::AddSDLGamepad(gamepad);
|
2019-02-12 14:56:44 +00:00
|
|
|
}
|
2015-08-29 18:23:16 +00:00
|
|
|
|
2019-02-12 14:56:44 +00:00
|
|
|
static void sdl_close_joystick(SDL_JoystickID instance)
|
|
|
|
{
|
2019-02-21 13:49:27 +00:00
|
|
|
std::shared_ptr<SDLGamepadDevice> gamepad = SDLGamepadDevice::GetSDLGamepad(instance);
|
|
|
|
if (gamepad != NULL)
|
2019-02-23 00:06:10 +00:00
|
|
|
gamepad->close();
|
2019-02-12 14:56:44 +00:00
|
|
|
}
|
2019-01-16 19:48:32 +00:00
|
|
|
|
2015-08-29 18:23:16 +00:00
|
|
|
void input_sdl_init()
|
|
|
|
{
|
|
|
|
if (SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
|
|
|
|
{
|
2018-09-03 17:23:22 +00:00
|
|
|
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
|
2015-08-29 18:23:16 +00:00
|
|
|
{
|
2019-01-16 19:48:32 +00:00
|
|
|
die("SDL: error initializing Joystick subsystem");
|
2015-08-29 18:23:16 +00:00
|
|
|
}
|
|
|
|
}
|
2019-02-23 00:06:10 +00:00
|
|
|
if (SDL_WasInit(SDL_INIT_HAPTIC) == 0)
|
|
|
|
SDL_InitSubSystem(SDL_INIT_HAPTIC);
|
2019-01-16 19:48:32 +00:00
|
|
|
|
2019-02-07 22:44:30 +00:00
|
|
|
SDL_SetRelativeMouseMode(SDL_FALSE);
|
2019-01-16 19:48:32 +00:00
|
|
|
|
2019-02-16 12:52:38 +00:00
|
|
|
sdl_keyboard = new SDLKeyboardDevice(0);
|
2019-02-21 21:39:26 +00:00
|
|
|
sdl_kb_gamepad = std::make_shared<SDLKbGamepadDevice>(0);
|
|
|
|
GamepadDevice::Register(sdl_kb_gamepad);
|
|
|
|
sdl_mouse_gamepad = std::make_shared<SDLMouseGamepadDevice>(0);
|
|
|
|
GamepadDevice::Register(sdl_mouse_gamepad);
|
2019-02-07 22:44:30 +00:00
|
|
|
}
|
2015-09-12 18:19:28 +00:00
|
|
|
|
2019-02-24 12:19:50 +00:00
|
|
|
static int mouse_prev_x = -1;
|
|
|
|
static int mouse_prev_y = -1;
|
2015-08-29 18:23:16 +00:00
|
|
|
|
2019-02-07 22:44:30 +00:00
|
|
|
static void set_mouse_position(int x, int y)
|
|
|
|
{
|
|
|
|
int width, height;
|
|
|
|
SDL_GetWindowSize(window, &width, &height);
|
|
|
|
if (width != 0 && height != 0)
|
2015-08-29 18:23:16 +00:00
|
|
|
{
|
2019-02-07 22:44:30 +00:00
|
|
|
float scale = 480.f / height;
|
|
|
|
mo_x_abs = (x - (width - 640.f / scale) / 2.f) * scale;
|
|
|
|
mo_y_abs = y * scale;
|
2019-02-24 12:19:50 +00:00
|
|
|
if (mouse_prev_x != -1)
|
2015-08-29 18:23:16 +00:00
|
|
|
{
|
2019-02-24 12:19:50 +00:00
|
|
|
mo_x_delta += (f32)(x - mouse_prev_x) * settings.input.MouseSensitivity / 100.f;
|
|
|
|
mo_y_delta += (f32)(y - mouse_prev_y) * settings.input.MouseSensitivity / 100.f;
|
2015-08-29 18:23:16 +00:00
|
|
|
}
|
2019-02-24 12:19:50 +00:00
|
|
|
mouse_prev_x = x;
|
|
|
|
mouse_prev_y = y;
|
2019-02-07 22:44:30 +00:00
|
|
|
}
|
2015-08-29 18:23:16 +00:00
|
|
|
}
|
|
|
|
|
2019-02-21 13:49:27 +00:00
|
|
|
// FIXME this shouldn't be done by port. Need something like: handle_events() then get_port(0), get_port(2), ...
|
2015-08-29 18:23:16 +00:00
|
|
|
void input_sdl_handle(u32 port)
|
|
|
|
{
|
2019-02-23 00:06:10 +00:00
|
|
|
if (port == 0) // FIXME hack
|
|
|
|
SDLGamepadDevice::UpdateRumble();
|
|
|
|
|
2018-09-03 17:23:22 +00:00
|
|
|
#define SET_FLAG(field, mask, expr) field =((expr) ? (field & ~mask) : (field | mask))
|
2015-08-29 18:23:16 +00:00
|
|
|
SDL_Event event;
|
|
|
|
while (SDL_PollEvent(&event))
|
|
|
|
{
|
|
|
|
switch (event.type)
|
|
|
|
{
|
|
|
|
case SDL_QUIT:
|
2019-02-25 16:52:53 +00:00
|
|
|
dc_exit();
|
2018-09-03 17:23:22 +00:00
|
|
|
break;
|
2015-08-29 18:23:16 +00:00
|
|
|
case SDL_KEYDOWN:
|
|
|
|
case SDL_KEYUP:
|
2019-02-12 10:30:24 +00:00
|
|
|
sdl_kb_gamepad->gamepad_btn_input(event.key.keysym.sym, event.type == SDL_KEYDOWN);
|
2019-02-07 22:44:30 +00:00
|
|
|
{
|
2019-02-12 10:30:24 +00:00
|
|
|
int modifier_keys = 0;
|
|
|
|
if (event.key.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT))
|
|
|
|
SET_FLAG(modifier_keys, (0x02 | 0x20), event.type == SDL_KEYUP);
|
|
|
|
if (event.key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL))
|
|
|
|
SET_FLAG(modifier_keys, (0x01 | 0x10), event.type == SDL_KEYUP);
|
|
|
|
sdl_keyboard->keyboard_input(event.key.keysym.sym, event.type == SDL_KEYDOWN, modifier_keys);
|
2015-08-29 18:23:16 +00:00
|
|
|
}
|
|
|
|
break;
|
2019-02-24 12:19:50 +00:00
|
|
|
case SDL_TEXTINPUT:
|
|
|
|
for (int i = 0; event.text.text[i] != '\0'; i++)
|
|
|
|
sdl_keyboard->keyboard_character(event.text.text[i]);
|
|
|
|
break;
|
|
|
|
|
2015-08-29 18:23:16 +00:00
|
|
|
case SDL_JOYBUTTONDOWN:
|
|
|
|
case SDL_JOYBUTTONUP:
|
|
|
|
{
|
2019-02-21 13:49:27 +00:00
|
|
|
std::shared_ptr<SDLGamepadDevice> device = SDLGamepadDevice::GetSDLGamepad((SDL_JoystickID)event.jbutton.which);
|
2019-02-12 14:56:44 +00:00
|
|
|
if (device != NULL)
|
|
|
|
device->gamepad_btn_input(event.jbutton.button, event.type == SDL_JOYBUTTONDOWN);
|
2015-08-29 18:23:16 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SDL_JOYAXISMOTION:
|
|
|
|
{
|
2019-02-21 13:49:27 +00:00
|
|
|
std::shared_ptr<SDLGamepadDevice> device = SDLGamepadDevice::GetSDLGamepad((SDL_JoystickID)event.jaxis.which);
|
2019-02-12 14:56:44 +00:00
|
|
|
if (device != NULL)
|
|
|
|
device->gamepad_axis_input(event.jaxis.axis, event.jaxis.value);
|
2015-08-29 18:23:16 +00:00
|
|
|
}
|
|
|
|
break;
|
2018-09-03 17:23:22 +00:00
|
|
|
|
2015-08-29 18:23:16 +00:00
|
|
|
case SDL_MOUSEMOTION:
|
2019-02-07 22:44:30 +00:00
|
|
|
set_mouse_position(event.motion.x, event.motion.y);
|
|
|
|
SET_FLAG(mo_buttons, 1 << 2, event.motion.state & SDL_BUTTON_LMASK);
|
|
|
|
SET_FLAG(mo_buttons, 1 << 1, event.motion.state & SDL_BUTTON_RMASK);
|
|
|
|
SET_FLAG(mo_buttons, 1 << 3, event.motion.state & SDL_BUTTON_MMASK);
|
2015-08-29 18:23:16 +00:00
|
|
|
break;
|
2019-01-16 19:48:32 +00:00
|
|
|
|
2019-02-07 22:44:30 +00:00
|
|
|
case SDL_MOUSEBUTTONDOWN:
|
|
|
|
case SDL_MOUSEBUTTONUP:
|
|
|
|
set_mouse_position(event.button.x, event.button.y);
|
|
|
|
switch (event.button.button)
|
|
|
|
{
|
|
|
|
case SDL_BUTTON_LEFT:
|
|
|
|
SET_FLAG(mo_buttons, 1 << 2, event.button.state == SDL_PRESSED);
|
|
|
|
break;
|
|
|
|
case SDL_BUTTON_RIGHT:
|
|
|
|
SET_FLAG(mo_buttons, 1 << 1, event.button.state == SDL_PRESSED);
|
|
|
|
break;
|
|
|
|
case SDL_BUTTON_MIDDLE:
|
|
|
|
SET_FLAG(mo_buttons, 1 << 3, event.button.state == SDL_PRESSED);
|
|
|
|
break;
|
|
|
|
}
|
2019-02-12 10:30:24 +00:00
|
|
|
sdl_mouse_gamepad->gamepad_btn_input(event.button.button, event.button.state == SDL_PRESSED);
|
2015-08-29 18:23:16 +00:00
|
|
|
break;
|
2019-01-16 19:48:32 +00:00
|
|
|
|
2019-02-24 12:19:50 +00:00
|
|
|
case SDL_MOUSEWHEEL:
|
|
|
|
mo_wheel_delta -= event.wheel.y * 35;
|
|
|
|
break;
|
2019-01-16 19:48:32 +00:00
|
|
|
|
2019-02-12 14:56:44 +00:00
|
|
|
case SDL_JOYDEVICEADDED:
|
|
|
|
sdl_open_joystick(event.jdevice.which);
|
|
|
|
break;
|
2019-01-16 19:48:32 +00:00
|
|
|
|
2019-02-12 14:56:44 +00:00
|
|
|
case SDL_JOYDEVICEREMOVED:
|
|
|
|
sdl_close_joystick((SDL_JoystickID)event.jdevice.which);
|
|
|
|
break;
|
2015-08-29 18:23:16 +00:00
|
|
|
}
|
|
|
|
}
|
2019-01-16 19:48:32 +00:00
|
|
|
}
|
|
|
|
|
2015-08-29 18:23:16 +00:00
|
|
|
void sdl_window_set_text(const char* text)
|
|
|
|
{
|
|
|
|
#ifdef TARGET_PANDORA
|
|
|
|
strncpy(OSD_Counters, text, 256);
|
|
|
|
#else
|
2015-10-11 16:06:06 +00:00
|
|
|
if(window)
|
|
|
|
{
|
|
|
|
SDL_SetWindowTitle(window, text); // *TODO* Set Icon also...
|
|
|
|
}
|
2015-08-29 18:23:16 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void sdl_window_create()
|
|
|
|
{
|
|
|
|
if (SDL_WasInit(SDL_INIT_VIDEO) == 0)
|
|
|
|
{
|
|
|
|
if(SDL_InitSubSystem(SDL_INIT_VIDEO) != 0)
|
|
|
|
{
|
|
|
|
die("error initializing SDL Joystick subsystem");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int window_width = cfgLoadInt("x11","width", WINDOW_WIDTH);
|
|
|
|
int window_height = cfgLoadInt("x11","height", WINDOW_HEIGHT);
|
2015-09-12 18:19:28 +00:00
|
|
|
|
2015-10-11 16:06:06 +00:00
|
|
|
int flags = SDL_WINDOW_OPENGL;
|
2015-08-29 18:23:16 +00:00
|
|
|
#ifdef TARGET_PANDORA
|
2015-10-11 16:06:06 +00:00
|
|
|
flags |= SDL_FULLSCREEN;
|
2015-08-29 18:23:16 +00:00
|
|
|
#else
|
2019-02-07 22:44:30 +00:00
|
|
|
flags |= SDL_SWSURFACE | SDL_WINDOW_RESIZABLE;
|
2015-08-29 18:23:16 +00:00
|
|
|
#endif
|
2015-09-12 18:19:28 +00:00
|
|
|
|
2015-10-11 16:06:06 +00:00
|
|
|
#ifdef GLES
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
|
|
|
#else
|
2015-09-12 18:19:28 +00:00
|
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
2018-10-04 11:37:45 +00:00
|
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
2015-10-11 16:06:06 +00:00
|
|
|
#endif
|
2015-09-12 18:19:28 +00:00
|
|
|
|
2015-10-11 16:06:06 +00:00
|
|
|
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
|
|
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
2015-09-12 18:19:28 +00:00
|
|
|
|
2019-06-20 21:46:20 +00:00
|
|
|
window = SDL_CreateWindow("Flycast", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, window_width, window_height, flags);
|
2015-10-11 16:06:06 +00:00
|
|
|
if (!window)
|
|
|
|
{
|
|
|
|
die("error creating SDL window");
|
|
|
|
}
|
|
|
|
|
|
|
|
glcontext = SDL_GL_CreateContext(window);
|
|
|
|
if (!glcontext)
|
|
|
|
{
|
|
|
|
die("Error creating SDL GL context");
|
|
|
|
}
|
|
|
|
SDL_GL_MakeCurrent(window, NULL);
|
2015-09-12 18:19:28 +00:00
|
|
|
|
2019-02-12 10:30:24 +00:00
|
|
|
SDL_GL_GetDrawableSize(window, &screen_width, &screen_height);
|
|
|
|
|
|
|
|
float ddpi, hdpi, vdpi;
|
|
|
|
if (!SDL_GetDisplayDPI(SDL_GetWindowDisplayIndex(window), &ddpi, &hdpi, &vdpi))
|
|
|
|
screen_dpi = (int)roundf(max(hdpi, vdpi));
|
|
|
|
|
2015-09-12 18:19:28 +00:00
|
|
|
printf("Created SDL Window (%ix%i) and GL Context successfully\n", window_width, window_height);
|
2015-08-29 18:23:16 +00:00
|
|
|
}
|
2015-09-12 18:19:28 +00:00
|
|
|
|
2015-10-11 16:06:06 +00:00
|
|
|
bool gl_init(void* wind, void* disp)
|
|
|
|
{
|
|
|
|
SDL_GL_MakeCurrent(window, glcontext);
|
|
|
|
#ifdef GLES
|
|
|
|
return true;
|
|
|
|
#else
|
2015-09-12 18:19:28 +00:00
|
|
|
return gl3wInit() != -1 && gl3wIsSupported(3, 1);
|
2015-10-11 16:06:06 +00:00
|
|
|
#endif
|
|
|
|
}
|
2015-09-12 18:19:28 +00:00
|
|
|
|
2015-10-11 16:06:06 +00:00
|
|
|
void gl_swap()
|
|
|
|
{
|
|
|
|
SDL_GL_SwapWindow(window);
|
2015-09-12 18:19:28 +00:00
|
|
|
|
2015-10-11 16:06:06 +00:00
|
|
|
/* Check if drawable has been resized */
|
2019-02-12 10:30:24 +00:00
|
|
|
SDL_GL_GetDrawableSize(window, &screen_width, &screen_height);
|
2015-10-11 16:06:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void gl_term()
|
|
|
|
{
|
|
|
|
SDL_GL_DeleteContext(glcontext);
|
|
|
|
}
|