summaryrefslogtreecommitdiff
path: root/render_sdl.c
diff options
context:
space:
mode:
Diffstat (limited to 'render_sdl.c')
-rwxr-xr-xrender_sdl.c742
1 files changed, 417 insertions, 325 deletions
diff --git a/render_sdl.c b/render_sdl.c
index 629b6bb..3406675 100755
--- a/render_sdl.c
+++ b/render_sdl.c
@@ -48,6 +48,7 @@ struct audio_source {
SDL_cond *cond;
int16_t *front;
int16_t *back;
+ double dt;
uint64_t buffer_fraction;
uint64_t buffer_inc;
uint32_t buffer_pos;
@@ -257,8 +258,8 @@ audio_source *render_audio_source(uint64_t master_clock, uint64_t sample_divider
render_audio_adjust_clock(ret, master_clock, sample_divider);
double lowpass_cutoff = get_lowpass_cutoff(config);
double rc = (1.0 / lowpass_cutoff) / (2.0 * M_PI);
- double dt = 1.0 / ((double)master_clock / (double)(sample_divider));
- double alpha = dt / (dt + rc);
+ ret->dt = 1.0 / ((double)master_clock / (double)(sample_divider));
+ double alpha = ret->dt / (ret->dt + rc);
ret->lowpass_alpha = (int32_t)(((double)0x10000) * alpha);
ret->buffer_pos = 0;
ret->buffer_fraction = 0;
@@ -524,10 +525,9 @@ static void gl_setup()
}
#endif
+static uint8_t texture_init;
static void render_alloc_surfaces()
{
- static uint8_t texture_init;
-
if (texture_init) {
return;
}
@@ -550,18 +550,26 @@ static void render_alloc_surfaces()
#endif
}
-static char * caption = NULL;
-static char * fps_caption = NULL;
-
-static void render_quit()
+static void free_surfaces(void)
{
- render_close_audio();
for (int i = 0; i < num_textures; i++)
{
if (sdl_textures[i]) {
SDL_DestroyTexture(sdl_textures[i]);
}
}
+ free(sdl_textures);
+ sdl_textures = NULL;
+ texture_init = 0;
+}
+
+static char * caption = NULL;
+static char * fps_caption = NULL;
+
+static void render_quit()
+{
+ render_close_audio();
+ free_surfaces();
}
static float config_aspect()
@@ -621,55 +629,317 @@ static void update_aspect()
}
}
+static ui_render_fun on_context_destroyed, on_context_created;
+void render_set_gl_context_handlers(ui_render_fun destroy, ui_render_fun create)
+{
+ on_context_destroyed = destroy;
+ on_context_created = create;
+}
+
+static uint8_t scancode_map[SDL_NUM_SCANCODES] = {
+ [SDL_SCANCODE_A] = 0x1C,
+ [SDL_SCANCODE_B] = 0x32,
+ [SDL_SCANCODE_C] = 0x21,
+ [SDL_SCANCODE_D] = 0x23,
+ [SDL_SCANCODE_E] = 0x24,
+ [SDL_SCANCODE_F] = 0x2B,
+ [SDL_SCANCODE_G] = 0x34,
+ [SDL_SCANCODE_H] = 0x33,
+ [SDL_SCANCODE_I] = 0x43,
+ [SDL_SCANCODE_J] = 0x3B,
+ [SDL_SCANCODE_K] = 0x42,
+ [SDL_SCANCODE_L] = 0x4B,
+ [SDL_SCANCODE_M] = 0x3A,
+ [SDL_SCANCODE_N] = 0x31,
+ [SDL_SCANCODE_O] = 0x44,
+ [SDL_SCANCODE_P] = 0x4D,
+ [SDL_SCANCODE_Q] = 0x15,
+ [SDL_SCANCODE_R] = 0x2D,
+ [SDL_SCANCODE_S] = 0x1B,
+ [SDL_SCANCODE_T] = 0x2C,
+ [SDL_SCANCODE_U] = 0x3C,
+ [SDL_SCANCODE_V] = 0x2A,
+ [SDL_SCANCODE_W] = 0x1D,
+ [SDL_SCANCODE_X] = 0x22,
+ [SDL_SCANCODE_Y] = 0x35,
+ [SDL_SCANCODE_Z] = 0x1A,
+ [SDL_SCANCODE_1] = 0x16,
+ [SDL_SCANCODE_2] = 0x1E,
+ [SDL_SCANCODE_3] = 0x26,
+ [SDL_SCANCODE_4] = 0x25,
+ [SDL_SCANCODE_5] = 0x2E,
+ [SDL_SCANCODE_6] = 0x36,
+ [SDL_SCANCODE_7] = 0x3D,
+ [SDL_SCANCODE_8] = 0x3E,
+ [SDL_SCANCODE_9] = 0x46,
+ [SDL_SCANCODE_0] = 0x45,
+ [SDL_SCANCODE_RETURN] = 0x5A,
+ [SDL_SCANCODE_ESCAPE] = 0x76,
+ [SDL_SCANCODE_SPACE] = 0x29,
+ [SDL_SCANCODE_TAB] = 0x0D,
+ [SDL_SCANCODE_BACKSPACE] = 0x66,
+ [SDL_SCANCODE_MINUS] = 0x4E,
+ [SDL_SCANCODE_EQUALS] = 0x55,
+ [SDL_SCANCODE_LEFTBRACKET] = 0x54,
+ [SDL_SCANCODE_RIGHTBRACKET] = 0x5B,
+ [SDL_SCANCODE_BACKSLASH] = 0x5D,
+ [SDL_SCANCODE_SEMICOLON] = 0x4C,
+ [SDL_SCANCODE_APOSTROPHE] = 0x52,
+ [SDL_SCANCODE_GRAVE] = 0x0E,
+ [SDL_SCANCODE_COMMA] = 0x41,
+ [SDL_SCANCODE_PERIOD] = 0x49,
+ [SDL_SCANCODE_SLASH] = 0x4A,
+ [SDL_SCANCODE_CAPSLOCK] = 0x58,
+ [SDL_SCANCODE_F1] = 0x05,
+ [SDL_SCANCODE_F2] = 0x06,
+ [SDL_SCANCODE_F3] = 0x04,
+ [SDL_SCANCODE_F4] = 0x0C,
+ [SDL_SCANCODE_F5] = 0x03,
+ [SDL_SCANCODE_F6] = 0x0B,
+ [SDL_SCANCODE_F7] = 0x83,
+ [SDL_SCANCODE_F8] = 0x0A,
+ [SDL_SCANCODE_F9] = 0x01,
+ [SDL_SCANCODE_F10] = 0x09,
+ [SDL_SCANCODE_F11] = 0x78,
+ [SDL_SCANCODE_F12] = 0x07,
+ [SDL_SCANCODE_LCTRL] = 0x14,
+ [SDL_SCANCODE_LSHIFT] = 0x12,
+ [SDL_SCANCODE_LALT] = 0x11,
+ [SDL_SCANCODE_RCTRL] = 0x18,
+ [SDL_SCANCODE_RSHIFT] = 0x59,
+ [SDL_SCANCODE_RALT] = 0x17,
+ [SDL_SCANCODE_INSERT] = 0x81,
+ [SDL_SCANCODE_PAUSE] = 0x82,
+ [SDL_SCANCODE_PRINTSCREEN] = 0x84,
+ [SDL_SCANCODE_SCROLLLOCK] = 0x7E,
+ [SDL_SCANCODE_DELETE] = 0x85,
+ [SDL_SCANCODE_LEFT] = 0x86,
+ [SDL_SCANCODE_HOME] = 0x87,
+ [SDL_SCANCODE_END] = 0x88,
+ [SDL_SCANCODE_UP] = 0x89,
+ [SDL_SCANCODE_DOWN] = 0x8A,
+ [SDL_SCANCODE_PAGEUP] = 0x8B,
+ [SDL_SCANCODE_PAGEDOWN] = 0x8C,
+ [SDL_SCANCODE_RIGHT] = 0x8D,
+ [SDL_SCANCODE_NUMLOCKCLEAR] = 0x77,
+ [SDL_SCANCODE_KP_DIVIDE] = 0x80,
+ [SDL_SCANCODE_KP_MULTIPLY] = 0x7C,
+ [SDL_SCANCODE_KP_MINUS] = 0x7B,
+ [SDL_SCANCODE_KP_PLUS] = 0x79,
+ [SDL_SCANCODE_KP_ENTER] = 0x19,
+ [SDL_SCANCODE_KP_1] = 0x69,
+ [SDL_SCANCODE_KP_2] = 0x72,
+ [SDL_SCANCODE_KP_3] = 0x7A,
+ [SDL_SCANCODE_KP_4] = 0x6B,
+ [SDL_SCANCODE_KP_5] = 0x73,
+ [SDL_SCANCODE_KP_6] = 0x74,
+ [SDL_SCANCODE_KP_7] = 0x6C,
+ [SDL_SCANCODE_KP_8] = 0x75,
+ [SDL_SCANCODE_KP_9] = 0x7D,
+ [SDL_SCANCODE_KP_0] = 0x70,
+ [SDL_SCANCODE_KP_PERIOD] = 0x71,
+};
+
+static drop_handler drag_drop_handler;
+void render_set_drag_drop_handler(drop_handler handler)
+{
+ drag_drop_handler = handler;
+}
+
+static event_handler custom_event_handler;
+void render_set_event_handler(event_handler handler)
+{
+ custom_event_handler = handler;
+}
+
+static int find_joystick_index(SDL_JoystickID instanceID)
+{
+ for (int i = 0; i < MAX_JOYSTICKS; i++) {
+ if (joysticks[i] && SDL_JoystickInstanceID(joysticks[i]) == instanceID) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+static int lowest_unused_joystick_index()
+{
+ for (int i = 0; i < MAX_JOYSTICKS; i++) {
+ if (!joysticks[i]) {
+ return i;
+ }
+ }
+ return -1;
+}
+
static uint32_t overscan_top[NUM_VID_STD] = {2, 21};
static uint32_t overscan_bot[NUM_VID_STD] = {1, 17};
static uint32_t overscan_left[NUM_VID_STD] = {13, 13};
static uint32_t overscan_right[NUM_VID_STD] = {14, 14};
static vid_std video_standard = VID_NTSC;
+
+static int32_t handle_event(SDL_Event *event)
+{
+ if (custom_event_handler) {
+ custom_event_handler(event);
+ }
+ switch (event->type) {
+ case SDL_KEYDOWN:
+ handle_keydown(event->key.keysym.sym, scancode_map[event->key.keysym.scancode]);
+ break;
+ case SDL_KEYUP:
+ handle_keyup(event->key.keysym.sym, scancode_map[event->key.keysym.scancode]);
+ break;
+ case SDL_JOYBUTTONDOWN:
+ handle_joydown(find_joystick_index(event->jbutton.which), event->jbutton.button);
+ break;
+ case SDL_JOYBUTTONUP:
+ handle_joyup(find_joystick_index(event->jbutton.which), event->jbutton.button);
+ break;
+ case SDL_JOYHATMOTION:
+ handle_joy_dpad(find_joystick_index(event->jbutton.which), event->jhat.hat, event->jhat.value);
+ break;
+ case SDL_JOYAXISMOTION:
+ handle_joy_axis(find_joystick_index(event->jaxis.which), event->jaxis.axis, event->jaxis.value);
+ break;
+ case SDL_JOYDEVICEADDED:
+ if (event->jdevice.which < MAX_JOYSTICKS) {
+ int index = lowest_unused_joystick_index();
+ if (index >= 0) {
+ SDL_Joystick * joy = joysticks[index] = SDL_JoystickOpen(event->jdevice.which);
+ joystick_sdl_index[index] = event->jdevice.which;
+ if (joy) {
+ printf("Joystick %d added: %s\n", index, SDL_JoystickName(joy));
+ printf("\tNum Axes: %d\n\tNum Buttons: %d\n\tNum Hats: %d\n", SDL_JoystickNumAxes(joy), SDL_JoystickNumButtons(joy), SDL_JoystickNumHats(joy));
+ handle_joy_added(index);
+ }
+ }
+ }
+ break;
+ case SDL_JOYDEVICEREMOVED: {
+ int index = find_joystick_index(event->jdevice.which);
+ if (index >= 0) {
+ SDL_JoystickClose(joysticks[index]);
+ joysticks[index] = NULL;
+ printf("Joystick %d removed\n", index);
+ } else {
+ printf("Failed to find removed joystick with instance ID: %d\n", index);
+ }
+ break;
+ }
+ case SDL_MOUSEMOTION:
+ handle_mouse_moved(event->motion.which, event->motion.x, event->motion.y + overscan_top[video_standard], event->motion.xrel, event->motion.yrel);
+ break;
+ case SDL_MOUSEBUTTONDOWN:
+ handle_mousedown(event->button.which, event->button.button);
+ break;
+ case SDL_MOUSEBUTTONUP:
+ handle_mouseup(event->button.which, event->button.button);
+ break;
+ case SDL_WINDOWEVENT:
+ switch (event->window.event)
+ {
+ case SDL_WINDOWEVENT_SIZE_CHANGED:
+ main_width = event->window.data1;
+ main_height = event->window.data2;
+ update_aspect();
+#ifndef DISABLE_OPENGL
+ if (render_gl) {
+ if (on_context_destroyed) {
+ on_context_destroyed();
+ }
+ SDL_GL_DeleteContext(main_context);
+ main_context = SDL_GL_CreateContext(main_window);
+ gl_setup();
+ if (on_context_created) {
+ on_context_created();
+ }
+ }
+#endif
+ break;
+ }
+ break;
+ case SDL_DROPFILE:
+ if (drag_drop_handler) {
+ drag_drop_handler(event->drop.file);
+ }
+ SDL_free(event->drop.file);
+ break;
+ case SDL_QUIT:
+ puts("");
+ exit(0);
+ }
+ return 0;
+}
+
+static void drain_events()
+{
+ SDL_Event event;
+ while(SDL_PollEvent(&event))
+ {
+ handle_event(&event);
+ }
+}
+
static char *vid_std_names[NUM_VID_STD] = {"ntsc", "pal"};
static int display_hz;
static int source_hz;
static int source_frame;
static int source_frame_count;
static int frame_repeat[60];
-void render_init(int width, int height, char * title, uint8_t fullscreen)
+
+static void init_audio()
{
- if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0) {
- fatal_error("Unable to init SDL: %s\n", SDL_GetError());
+ SDL_AudioSpec desired, actual;
+ char * rate_str = tern_find_path(config, "audio\0rate\0", TVAL_PTR).ptrval;
+ int rate = rate_str ? atoi(rate_str) : 0;
+ if (!rate) {
+ rate = 48000;
+ }
+ desired.freq = rate;
+ desired.format = AUDIO_S16SYS;
+ desired.channels = 2;
+ char * samples_str = tern_find_path(config, "audio\0buffer\0", TVAL_PTR).ptrval;
+ int samples = samples_str ? atoi(samples_str) : 0;
+ if (!samples) {
+ samples = 512;
+ }
+ printf("config says: %d\n", samples);
+ desired.samples = samples*2;
+ desired.callback = sync_to_audio ? audio_callback : audio_callback_drc;
+ desired.userdata = NULL;
+
+ if (SDL_OpenAudio(&desired, &actual) < 0) {
+ fatal_error("Unable to open SDL audio: %s\n", SDL_GetError());
}
- atexit(SDL_Quit);
- if (height <= 0) {
- float aspect = config_aspect() > 0.0f ? config_aspect() : 4.0f/3.0f;
- height = ((float)width / aspect) + 0.5f;
+ buffer_samples = actual.samples;
+ sample_rate = actual.freq;
+ printf("Initialized audio at frequency %d with a %d sample buffer, ", actual.freq, actual.samples);
+ if (actual.format == AUDIO_S16SYS) {
+ puts("signed 16-bit int format");
+ mix = mix_s16;
+ } else if (actual.format == AUDIO_F32SYS) {
+ puts("32-bit float format");
+ mix = mix_f32;
+ } else {
+ printf("unsupported format %X\n", actual.format);
+ warning("Unsupported audio sample format: %X\n", actual.format);
+ mix = mix_null;
}
- printf("width: %d, height: %d\n", width, height);
- windowed_width = width;
- windowed_height = height;
-
- uint32_t flags = SDL_WINDOW_RESIZABLE;
-
- SDL_DisplayMode mode;
- //TODO: Explicit multiple monitor support
- SDL_GetCurrentDisplayMode(0, &mode);
- display_hz = mode.refresh_rate;
+}
- if (fullscreen) {
+void window_setup(void)
+{
+ uint32_t flags = SDL_WINDOW_RESIZABLE;
+ if (is_fullscreen) {
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
- //the SDL2 migration guide suggests setting width and height to 0 when using SDL_WINDOW_FULLSCREEN_DESKTOP
- //but that doesn't seem to work right when using OpenGL, at least on Linux anyway
- width = mode.w;
- height = mode.h;
}
- main_width = width;
- main_height = height;
- is_fullscreen = fullscreen;
tern_val def = {.ptrval = "video"};
char *sync_src = tern_find_path_default(config, "system\0sync_source\0", def, TVAL_PTR).ptrval;
sync_to_audio = !strcmp(sync_src, "audio");
-
- render_gl = 0;
- char *vsync;
+
+ const char *vsync;
if (sync_to_audio) {
def.ptrval = "off";
vsync = tern_find_path_default(config, "video\0vsync\0", def, TVAL_PTR).ptrval;
@@ -703,7 +973,7 @@ void render_init(int width, int height, char * title, uint8_t fullscreen)
}
}
}
-
+
#ifndef DISABLE_OPENGL
char *gl_enabled_str = tern_find_path_default(config, "video\0gl\0", def, TVAL_PTR).ptrval;
uint8_t gl_enabled = strcmp(gl_enabled_str, "off") != 0;
@@ -717,7 +987,7 @@ void render_init(int width, int height, char * title, uint8_t fullscreen)
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
}
#endif
- main_window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, flags);
+ main_window = SDL_CreateWindow(caption, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, main_width, main_height, flags);
if (!main_window) {
fatal_error("Unable to create SDL window: %s\n", SDL_GetError());
}
@@ -761,8 +1031,8 @@ void render_init(int width, int height, char * title, uint8_t fullscreen)
fatal_error("unable to create SDL renderer: %s\n", SDL_GetError());
}
main_clip.x = main_clip.y = 0;
- main_clip.w = width;
- main_clip.h = height;
+ main_clip.w = main_width;
+ main_clip.h = main_height;
#ifndef DISABLE_OPENGL
}
#endif
@@ -773,48 +1043,45 @@ void render_init(int width, int height, char * title, uint8_t fullscreen)
render_alloc_surfaces();
def.ptrval = "off";
scanlines = !strcmp(tern_find_path_default(config, "video\0scanlines\0", def, TVAL_PTR).ptrval, "on");
+}
+void render_init(int width, int height, char * title, uint8_t fullscreen)
+{
+ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0) {
+ fatal_error("Unable to init SDL: %s\n", SDL_GetError());
+ }
+ atexit(SDL_Quit);
+ if (height <= 0) {
+ float aspect = config_aspect() > 0.0f ? config_aspect() : 4.0f/3.0f;
+ height = ((float)width / aspect) + 0.5f;
+ }
+ printf("width: %d, height: %d\n", width, height);
+ windowed_width = width;
+ windowed_height = height;
+
+ SDL_DisplayMode mode;
+ //TODO: Explicit multiple monitor support
+ SDL_GetCurrentDisplayMode(0, &mode);
+ display_hz = mode.refresh_rate;
+
+ if (fullscreen) {
+ //the SDL2 migration guide suggests setting width and height to 0 when using SDL_WINDOW_FULLSCREEN_DESKTOP
+ //but that doesn't seem to work right when using OpenGL, at least on Linux anyway
+ width = mode.w;
+ height = mode.h;
+ }
+ main_width = width;
+ main_height = height;
+ is_fullscreen = fullscreen;
+
caption = title;
+
+ window_setup();
audio_mutex = SDL_CreateMutex();
audio_ready = SDL_CreateCond();
-
- SDL_AudioSpec desired, actual;
- char * rate_str = tern_find_path(config, "audio\0rate\0", TVAL_PTR).ptrval;
- int rate = rate_str ? atoi(rate_str) : 0;
- if (!rate) {
- rate = 48000;
- }
- desired.freq = rate;
- desired.format = AUDIO_S16SYS;
- desired.channels = 2;
- char * samples_str = tern_find_path(config, "audio\0buffer\0", TVAL_PTR).ptrval;
- int samples = samples_str ? atoi(samples_str) : 0;
- if (!samples) {
- samples = 512;
- }
- printf("config says: %d\n", samples);
- desired.samples = samples*2;
- desired.callback = sync_to_audio ? audio_callback : audio_callback_drc;
- desired.userdata = NULL;
-
- if (SDL_OpenAudio(&desired, &actual) < 0) {
- fatal_error("Unable to open SDL audio: %s\n", SDL_GetError());
- }
- buffer_samples = actual.samples;
- sample_rate = actual.freq;
- printf("Initialized audio at frequency %d with a %d sample buffer, ", actual.freq, actual.samples);
- if (actual.format == AUDIO_S16SYS) {
- puts("signed 16-bit int format");
- mix = mix_s16;
- } else if (actual.format == AUDIO_F32SYS) {
- puts("32-bit float format");
- mix = mix_f32;
- } else {
- printf("unsupported format %X\n", actual.format);
- warning("Unsupported audio sample format: %X\n", actual.format);
- mix = mix_null;
- }
+
+ init_audio();
uint32_t db_size;
char *db_data = read_bundled_file("gamecontrollerdb.txt", &db_size);
@@ -830,6 +1097,78 @@ void render_init(int width, int height, char * title, uint8_t fullscreen)
atexit(render_quit);
}
+#include<unistd.h>
+static int in_toggle;
+void render_config_updated(void)
+{
+ uint8_t old_sync_to_audio = sync_to_audio;
+
+ free_surfaces();
+#ifndef DISABLE_OPENGL
+ if (render_gl) {
+ if (on_context_destroyed) {
+ on_context_destroyed();
+ }
+ SDL_GL_DeleteContext(main_context);
+ } else {
+#endif
+ SDL_DestroyRenderer(main_renderer);
+#ifndef DISABLE_OPENGL
+ }
+#endif
+ in_toggle = 1;
+ SDL_DestroyWindow(main_window);
+ drain_events();
+
+ char *config_width = tern_find_path(config, "video\0width\0", TVAL_PTR).ptrval;
+ if (config_width) {
+ windowed_width = atoi(config_width);
+ }
+ char *config_height = tern_find_path(config, "video\0height\0", TVAL_PTR).ptrval;
+ if (config_height) {
+ windowed_height = atoi(config_height);
+ } else {
+ float aspect = config_aspect() > 0.0f ? config_aspect() : 4.0f/3.0f;
+ windowed_height = ((float)windowed_width / aspect) + 0.5f;
+ }
+ char *config_fullscreen = tern_find_path(config, "video\0fullscreen\0", TVAL_PTR).ptrval;
+ is_fullscreen = config_fullscreen && !strcmp("on", config_fullscreen);
+ if (is_fullscreen) {
+ SDL_DisplayMode mode;
+ //TODO: Multiple monitor support
+ SDL_GetCurrentDisplayMode(0, &mode);
+ main_width = mode.w;
+ main_height = mode.h;
+ } else {
+ main_width = windowed_width;
+ main_height = windowed_height;
+ }
+
+ window_setup();
+ update_aspect();
+#ifndef DISABLE_OPENGL
+ //need to check render_gl again after window_setup as render option could have changed
+ if (render_gl && on_context_created) {
+ on_context_created();
+ }
+#endif
+
+ SDL_CloseAudio();
+ init_audio();
+
+ double lowpass_cutoff = get_lowpass_cutoff(config);
+ double rc = (1.0 / lowpass_cutoff) / (2.0 * M_PI);
+ lock_audio();
+ for (uint8_t i = 0; i < num_audio_sources; i++)
+ {
+ double alpha = audio_sources[i]->dt / (audio_sources[i]->dt + rc);
+ int32_t lowpass_alpha = (int32_t)(((double)0x10000) * alpha);
+ audio_sources[i]->lowpass_alpha = lowpass_alpha;
+ }
+ unlock_audio();
+ drain_events();
+ in_toggle = 0;
+}
SDL_Window *render_get_window(void)
{
@@ -1211,26 +1550,6 @@ void render_wait_quit(vdp_context * context)
}
}
-static int find_joystick_index(SDL_JoystickID instanceID)
-{
- for (int i = 0; i < MAX_JOYSTICKS; i++) {
- if (joysticks[i] && SDL_JoystickInstanceID(joysticks[i]) == instanceID) {
- return i;
- }
- }
- return -1;
-}
-
-static int lowest_unused_joystick_index()
-{
- for (int i = 0; i < MAX_JOYSTICKS; i++) {
- if (!joysticks[i]) {
- return i;
- }
- }
- return -1;
-}
-
int32_t render_translate_input_name(int32_t controller, char *name, uint8_t is_axis)
{
static tern_node *button_lookup, *axis_lookup;
@@ -1318,232 +1637,6 @@ int32_t render_axis_part(int32_t input)
return input & 0xFFFFFFF;
}
-static uint8_t scancode_map[SDL_NUM_SCANCODES] = {
- [SDL_SCANCODE_A] = 0x1C,
- [SDL_SCANCODE_B] = 0x32,
- [SDL_SCANCODE_C] = 0x21,
- [SDL_SCANCODE_D] = 0x23,
- [SDL_SCANCODE_E] = 0x24,
- [SDL_SCANCODE_F] = 0x2B,
- [SDL_SCANCODE_G] = 0x34,
- [SDL_SCANCODE_H] = 0x33,
- [SDL_SCANCODE_I] = 0x43,
- [SDL_SCANCODE_J] = 0x3B,
- [SDL_SCANCODE_K] = 0x42,
- [SDL_SCANCODE_L] = 0x4B,
- [SDL_SCANCODE_M] = 0x3A,
- [SDL_SCANCODE_N] = 0x31,
- [SDL_SCANCODE_O] = 0x44,
- [SDL_SCANCODE_P] = 0x4D,
- [SDL_SCANCODE_Q] = 0x15,
- [SDL_SCANCODE_R] = 0x2D,
- [SDL_SCANCODE_S] = 0x1B,
- [SDL_SCANCODE_T] = 0x2C,
- [SDL_SCANCODE_U] = 0x3C,
- [SDL_SCANCODE_V] = 0x2A,
- [SDL_SCANCODE_W] = 0x1D,
- [SDL_SCANCODE_X] = 0x22,
- [SDL_SCANCODE_Y] = 0x35,
- [SDL_SCANCODE_Z] = 0x1A,
- [SDL_SCANCODE_1] = 0x16,
- [SDL_SCANCODE_2] = 0x1E,
- [SDL_SCANCODE_3] = 0x26,
- [SDL_SCANCODE_4] = 0x25,
- [SDL_SCANCODE_5] = 0x2E,
- [SDL_SCANCODE_6] = 0x36,
- [SDL_SCANCODE_7] = 0x3D,
- [SDL_SCANCODE_8] = 0x3E,
- [SDL_SCANCODE_9] = 0x46,
- [SDL_SCANCODE_0] = 0x45,
- [SDL_SCANCODE_RETURN] = 0x5A,
- [SDL_SCANCODE_ESCAPE] = 0x76,
- [SDL_SCANCODE_SPACE] = 0x29,
- [SDL_SCANCODE_TAB] = 0x0D,
- [SDL_SCANCODE_BACKSPACE] = 0x66,
- [SDL_SCANCODE_MINUS] = 0x4E,
- [SDL_SCANCODE_EQUALS] = 0x55,
- [SDL_SCANCODE_LEFTBRACKET] = 0x54,
- [SDL_SCANCODE_RIGHTBRACKET] = 0x5B,
- [SDL_SCANCODE_BACKSLASH] = 0x5D,
- [SDL_SCANCODE_SEMICOLON] = 0x4C,
- [SDL_SCANCODE_APOSTROPHE] = 0x52,
- [SDL_SCANCODE_GRAVE] = 0x0E,
- [SDL_SCANCODE_COMMA] = 0x41,
- [SDL_SCANCODE_PERIOD] = 0x49,
- [SDL_SCANCODE_SLASH] = 0x4A,
- [SDL_SCANCODE_CAPSLOCK] = 0x58,
- [SDL_SCANCODE_F1] = 0x05,
- [SDL_SCANCODE_F2] = 0x06,
- [SDL_SCANCODE_F3] = 0x04,
- [SDL_SCANCODE_F4] = 0x0C,
- [SDL_SCANCODE_F5] = 0x03,
- [SDL_SCANCODE_F6] = 0x0B,
- [SDL_SCANCODE_F7] = 0x83,
- [SDL_SCANCODE_F8] = 0x0A,
- [SDL_SCANCODE_F9] = 0x01,
- [SDL_SCANCODE_F10] = 0x09,
- [SDL_SCANCODE_F11] = 0x78,
- [SDL_SCANCODE_F12] = 0x07,
- [SDL_SCANCODE_LCTRL] = 0x14,
- [SDL_SCANCODE_LSHIFT] = 0x12,
- [SDL_SCANCODE_LALT] = 0x11,
- [SDL_SCANCODE_RCTRL] = 0x18,
- [SDL_SCANCODE_RSHIFT] = 0x59,
- [SDL_SCANCODE_RALT] = 0x17,
- [SDL_SCANCODE_INSERT] = 0x81,
- [SDL_SCANCODE_PAUSE] = 0x82,
- [SDL_SCANCODE_PRINTSCREEN] = 0x84,
- [SDL_SCANCODE_SCROLLLOCK] = 0x7E,
- [SDL_SCANCODE_DELETE] = 0x85,
- [SDL_SCANCODE_LEFT] = 0x86,
- [SDL_SCANCODE_HOME] = 0x87,
- [SDL_SCANCODE_END] = 0x88,
- [SDL_SCANCODE_UP] = 0x89,
- [SDL_SCANCODE_DOWN] = 0x8A,
- [SDL_SCANCODE_PAGEUP] = 0x8B,
- [SDL_SCANCODE_PAGEDOWN] = 0x8C,
- [SDL_SCANCODE_RIGHT] = 0x8D,
- [SDL_SCANCODE_NUMLOCKCLEAR] = 0x77,
- [SDL_SCANCODE_KP_DIVIDE] = 0x80,
- [SDL_SCANCODE_KP_MULTIPLY] = 0x7C,
- [SDL_SCANCODE_KP_MINUS] = 0x7B,
- [SDL_SCANCODE_KP_PLUS] = 0x79,
- [SDL_SCANCODE_KP_ENTER] = 0x19,
- [SDL_SCANCODE_KP_1] = 0x69,
- [SDL_SCANCODE_KP_2] = 0x72,
- [SDL_SCANCODE_KP_3] = 0x7A,
- [SDL_SCANCODE_KP_4] = 0x6B,
- [SDL_SCANCODE_KP_5] = 0x73,
- [SDL_SCANCODE_KP_6] = 0x74,
- [SDL_SCANCODE_KP_7] = 0x6C,
- [SDL_SCANCODE_KP_8] = 0x75,
- [SDL_SCANCODE_KP_9] = 0x7D,
- [SDL_SCANCODE_KP_0] = 0x70,
- [SDL_SCANCODE_KP_PERIOD] = 0x71,
-};
-
-static drop_handler drag_drop_handler;
-void render_set_drag_drop_handler(drop_handler handler)
-{
- drag_drop_handler = handler;
-}
-
-static ui_render_fun on_context_destroyed, on_context_created;
-void render_set_gl_context_handlers(ui_render_fun destroy, ui_render_fun create)
-{
- on_context_destroyed = destroy;
- on_context_created = create;
-}
-
-static event_handler custom_event_handler;
-void render_set_event_handler(event_handler handler)
-{
- custom_event_handler = handler;
-}
-
-static int32_t handle_event(SDL_Event *event)
-{
- if (custom_event_handler) {
- custom_event_handler(event);
- }
- switch (event->type) {
- case SDL_KEYDOWN:
- handle_keydown(event->key.keysym.sym, scancode_map[event->key.keysym.scancode]);
- break;
- case SDL_KEYUP:
- handle_keyup(event->key.keysym.sym, scancode_map[event->key.keysym.scancode]);
- break;
- case SDL_JOYBUTTONDOWN:
- handle_joydown(find_joystick_index(event->jbutton.which), event->jbutton.button);
- break;
- case SDL_JOYBUTTONUP:
- handle_joyup(find_joystick_index(event->jbutton.which), event->jbutton.button);
- break;
- case SDL_JOYHATMOTION:
- handle_joy_dpad(find_joystick_index(event->jbutton.which), event->jhat.hat, event->jhat.value);
- break;
- case SDL_JOYAXISMOTION:
- handle_joy_axis(find_joystick_index(event->jaxis.which), event->jaxis.axis, event->jaxis.value);
- break;
- case SDL_JOYDEVICEADDED:
- if (event->jdevice.which < MAX_JOYSTICKS) {
- int index = lowest_unused_joystick_index();
- if (index >= 0) {
- SDL_Joystick * joy = joysticks[index] = SDL_JoystickOpen(event->jdevice.which);
- joystick_sdl_index[index] = event->jdevice.which;
- if (joy) {
- printf("Joystick %d added: %s\n", index, SDL_JoystickName(joy));
- printf("\tNum Axes: %d\n\tNum Buttons: %d\n\tNum Hats: %d\n", SDL_JoystickNumAxes(joy), SDL_JoystickNumButtons(joy), SDL_JoystickNumHats(joy));
- handle_joy_added(index);
- }
- }
- }
- break;
- case SDL_JOYDEVICEREMOVED: {
- int index = find_joystick_index(event->jdevice.which);
- if (index >= 0) {
- SDL_JoystickClose(joysticks[index]);
- joysticks[index] = NULL;
- printf("Joystick %d removed\n", index);
- } else {
- printf("Failed to find removed joystick with instance ID: %d\n", index);
- }
- break;
- }
- case SDL_MOUSEMOTION:
- handle_mouse_moved(event->motion.which, event->motion.x, event->motion.y + overscan_top[video_standard], event->motion.xrel, event->motion.yrel);
- break;
- case SDL_MOUSEBUTTONDOWN:
- handle_mousedown(event->button.which, event->button.button);
- break;
- case SDL_MOUSEBUTTONUP:
- handle_mouseup(event->button.which, event->button.button);
- break;
- case SDL_WINDOWEVENT:
- switch (event->window.event)
- {
- case SDL_WINDOWEVENT_SIZE_CHANGED:
- main_width = event->window.data1;
- main_height = event->window.data2;
- update_aspect();
-#ifndef DISABLE_OPENGL
- if (render_gl) {
- if (on_context_destroyed) {
- on_context_destroyed();
- }
- SDL_GL_DeleteContext(main_context);
- main_context = SDL_GL_CreateContext(main_window);
- gl_setup();
- if (on_context_created) {
- on_context_created();
- }
- }
-#endif
- break;
- }
- break;
- case SDL_DROPFILE:
- if (drag_drop_handler) {
- drag_drop_handler(event->drop.file);
- }
- SDL_free(event->drop.file);
- break;
- case SDL_QUIT:
- puts("");
- exit(0);
- }
- return 0;
-}
-
-static void drain_events()
-{
- SDL_Event event;
- while(SDL_PollEvent(&event))
- {
- handle_event(&event);
- }
-}
-
void process_events()
{
if (events_processed > MAX_EVENT_POLL_PER_FRAME) {
@@ -1556,7 +1649,6 @@ void process_events()
#define TOGGLE_MIN_DELAY 250
void render_toggle_fullscreen()
{
- static int in_toggle;
//protect against event processing causing us to attempt to toggle while still toggling
if (in_toggle) {
return;