Mercurial > repos > blastem
comparison render_sdl.c @ 2093:46ee354f29bd
Hack fix for audio deadlock issue
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 06 Feb 2022 23:25:23 -0800 |
parents | 0757da8ee702 |
children | f11f4399d64b |
comparison
equal
deleted
inserted
replaced
2092:8665d8da0e1c | 2093:46ee354f29bd |
---|---|
212 if (current_system && sync_src == SYNC_AUDIO_THREAD) { | 212 if (current_system && sync_src == SYNC_AUDIO_THREAD) { |
213 system_request_exit(current_system, 0); | 213 system_request_exit(current_system, 0); |
214 } | 214 } |
215 } | 215 } |
216 | 216 |
217 uint8_t audio_deadlock_hack(void); | |
218 | |
217 void render_do_audio_ready(audio_source *src) | 219 void render_do_audio_ready(audio_source *src) |
218 { | 220 { |
219 if (sync_src == SYNC_AUDIO_THREAD) { | 221 if (sync_src == SYNC_AUDIO_THREAD) { |
220 int16_t *tmp = src->front; | 222 int16_t *tmp = src->front; |
221 src->front = src->back; | 223 src->front = src->back; |
226 //we've emulated far enough to fill the current buffer | 228 //we've emulated far enough to fill the current buffer |
227 system_request_exit(current_system, 0); | 229 system_request_exit(current_system, 0); |
228 } | 230 } |
229 } else if (sync_src == SYNC_AUDIO) { | 231 } else if (sync_src == SYNC_AUDIO) { |
230 SDL_LockMutex(audio_mutex); | 232 SDL_LockMutex(audio_mutex); |
233 if (src->front_populated) { | |
234 if (audio_deadlock_hack()) { | |
235 SDL_CondSignal(audio_ready); | |
236 } | |
237 } | |
231 while (src->front_populated) { | 238 while (src->front_populated) { |
232 SDL_CondWait(src->opaque, audio_mutex); | 239 SDL_CondWait(src->opaque, audio_mutex); |
233 } | 240 } |
234 int16_t *tmp = src->front; | 241 int16_t *tmp = src->front; |
235 src->front = src->back; | 242 src->front = src->back; |
347 fsize = fsize32; | 354 fsize = fsize32; |
348 #ifndef __ANDROID__ | 355 #ifndef __ANDROID__ |
349 } | 356 } |
350 #endif | 357 #endif |
351 text[fsize] = 0; | 358 text[fsize] = 0; |
352 | 359 |
353 if (strncmp(text, "#version", strlen("#version"))) { | 360 if (strncmp(text, "#version", strlen("#version"))) { |
354 GLchar *tmp = text; | 361 GLchar *tmp = text; |
355 text = alloc_concat(shader_prefix, tmp); | 362 text = alloc_concat(shader_prefix, tmp); |
356 free(tmp); | 363 free(tmp); |
357 fsize += strlen(shader_prefix); | 364 fsize += strlen(shader_prefix); |
997 { | 1004 { |
998 uint32_t flags = SDL_WINDOW_RESIZABLE; | 1005 uint32_t flags = SDL_WINDOW_RESIZABLE; |
999 if (is_fullscreen) { | 1006 if (is_fullscreen) { |
1000 flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; | 1007 flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; |
1001 } | 1008 } |
1002 | 1009 |
1003 tern_val def = {.ptrval = "audio"}; | 1010 tern_val def = {.ptrval = "audio"}; |
1004 if (external_sync) { | 1011 if (external_sync) { |
1005 sync_src = SYNC_EXTERNAL; | 1012 sync_src = SYNC_EXTERNAL; |
1006 } else { | 1013 } else { |
1007 char *sync_src_str = tern_find_path_default(config, "system\0sync_source\0", def, TVAL_PTR).ptrval; | 1014 char *sync_src_str = tern_find_path_default(config, "system\0sync_source\0", def, TVAL_PTR).ptrval; |
1011 sync_src = SYNC_AUDIO_THREAD; | 1018 sync_src = SYNC_AUDIO_THREAD; |
1012 } else { | 1019 } else { |
1013 sync_src = SYNC_VIDEO; | 1020 sync_src = SYNC_VIDEO; |
1014 } | 1021 } |
1015 } | 1022 } |
1016 | 1023 |
1017 if (!num_buffers && (sync_src == SYNC_AUDIO_THREAD || sync_src == SYNC_EXTERNAL)) { | 1024 if (!num_buffers && (sync_src == SYNC_AUDIO_THREAD || sync_src == SYNC_EXTERNAL)) { |
1018 frame_mutex = SDL_CreateMutex(); | 1025 frame_mutex = SDL_CreateMutex(); |
1019 free_buffer_mutex = SDL_CreateMutex(); | 1026 free_buffer_mutex = SDL_CreateMutex(); |
1020 frame_ready = SDL_CreateCond(); | 1027 frame_ready = SDL_CreateCond(); |
1021 buffer_storage = 4; | 1028 buffer_storage = 4; |
1022 frame_buffers = calloc(buffer_storage, sizeof(uint32_t*)); | 1029 frame_buffers = calloc(buffer_storage, sizeof(uint32_t*)); |
1023 frame_buffers[0] = texture_buf; | 1030 frame_buffers[0] = texture_buf; |
1024 num_buffers = 1; | 1031 num_buffers = 1; |
1025 } | 1032 } |
1026 | 1033 |
1027 const char *vsync; | 1034 const char *vsync; |
1028 if (sync_src == SYNC_AUDIO) { | 1035 if (sync_src == SYNC_AUDIO) { |
1029 def.ptrval = "off"; | 1036 def.ptrval = "off"; |
1030 vsync = tern_find_path_default(config, "video\0vsync\0", def, TVAL_PTR).ptrval; | 1037 vsync = tern_find_path_default(config, "video\0vsync\0", def, TVAL_PTR).ptrval; |
1031 } else { | 1038 } else { |
1032 vsync = "on"; | 1039 vsync = "on"; |
1033 } | 1040 } |
1034 | 1041 |
1035 tern_node *video = tern_find_node(config, "video"); | 1042 tern_node *video = tern_find_node(config, "video"); |
1036 if (video) | 1043 if (video) |
1037 { | 1044 { |
1038 for (int i = 0; i < NUM_VID_STD; i++) | 1045 for (int i = 0; i < NUM_VID_STD; i++) |
1039 { | 1046 { |
1057 } | 1064 } |
1058 } | 1065 } |
1059 } | 1066 } |
1060 } | 1067 } |
1061 render_gl = 0; | 1068 render_gl = 0; |
1062 | 1069 |
1063 #ifndef DISABLE_OPENGL | 1070 #ifndef DISABLE_OPENGL |
1064 char *gl_enabled_str = tern_find_path_default(config, "video\0gl\0", def, TVAL_PTR).ptrval; | 1071 char *gl_enabled_str = tern_find_path_default(config, "video\0gl\0", def, TVAL_PTR).ptrval; |
1065 uint8_t gl_enabled = strcmp(gl_enabled_str, "off") != 0; | 1072 uint8_t gl_enabled = strcmp(gl_enabled_str, "off") != 0; |
1066 if (gl_enabled) | 1073 if (gl_enabled) |
1067 { | 1074 { |
1160 height = ((float)width / aspect) + 0.5f; | 1167 height = ((float)width / aspect) + 0.5f; |
1161 } | 1168 } |
1162 debug_message("width: %d, height: %d\n", width, height); | 1169 debug_message("width: %d, height: %d\n", width, height); |
1163 windowed_width = width; | 1170 windowed_width = width; |
1164 windowed_height = height; | 1171 windowed_height = height; |
1165 | 1172 |
1166 SDL_DisplayMode mode; | 1173 SDL_DisplayMode mode; |
1167 //TODO: Explicit multiple monitor support | 1174 //TODO: Explicit multiple monitor support |
1168 SDL_GetCurrentDisplayMode(0, &mode); | 1175 SDL_GetCurrentDisplayMode(0, &mode); |
1169 display_hz = mode.refresh_rate; | 1176 display_hz = mode.refresh_rate; |
1170 | 1177 |
1175 height = mode.h; | 1182 height = mode.h; |
1176 } | 1183 } |
1177 main_width = width; | 1184 main_width = width; |
1178 main_height = height; | 1185 main_height = height; |
1179 is_fullscreen = fullscreen; | 1186 is_fullscreen = fullscreen; |
1180 | 1187 |
1181 caption = title; | 1188 caption = title; |
1182 | 1189 |
1183 window_setup(); | 1190 window_setup(); |
1184 | 1191 |
1185 audio_mutex = SDL_CreateMutex(); | 1192 audio_mutex = SDL_CreateMutex(); |
1186 audio_ready = SDL_CreateCond(); | 1193 audio_ready = SDL_CreateCond(); |
1187 | 1194 |
1188 init_audio(); | 1195 init_audio(); |
1189 | 1196 |
1190 uint32_t db_size; | 1197 uint32_t db_size; |
1191 char *db_data = read_bundled_file("gamecontrollerdb.txt", &db_size); | 1198 char *db_data = read_bundled_file("gamecontrollerdb.txt", &db_size); |
1192 if (db_data) { | 1199 if (db_data) { |
1193 int added = SDL_GameControllerAddMappingsFromRW(SDL_RWFromMem(db_data, db_size), 1); | 1200 int added = SDL_GameControllerAddMappingsFromRW(SDL_RWFromMem(db_data, db_size), 1); |
1194 free(db_data); | 1201 free(db_data); |
1195 debug_message("Added %d game controller mappings from gamecontrollerdb.txt\n", added); | 1202 debug_message("Added %d game controller mappings from gamecontrollerdb.txt\n", added); |
1196 } | 1203 } |
1197 | 1204 |
1198 controller_add_mappings(); | 1205 controller_add_mappings(); |
1199 | 1206 |
1200 SDL_JoystickEventState(SDL_ENABLE); | 1207 SDL_JoystickEventState(SDL_ENABLE); |
1201 | 1208 |
1202 render_set_video_standard(VID_NTSC); | 1209 render_set_video_standard(VID_NTSC); |
1203 | 1210 |
1204 atexit(render_quit); | 1211 atexit(render_quit); |
1205 } | 1212 } |
1206 | 1213 |
1236 #endif | 1243 #endif |
1237 in_toggle = 1; | 1244 in_toggle = 1; |
1238 SDL_DestroyWindow(main_window); | 1245 SDL_DestroyWindow(main_window); |
1239 main_window = NULL; | 1246 main_window = NULL; |
1240 drain_events(); | 1247 drain_events(); |
1241 | 1248 |
1242 char *config_width = tern_find_path(config, "video\0width\0", TVAL_PTR).ptrval; | 1249 char *config_width = tern_find_path(config, "video\0width\0", TVAL_PTR).ptrval; |
1243 if (config_width) { | 1250 if (config_width) { |
1244 windowed_width = atoi(config_width); | 1251 windowed_width = atoi(config_width); |
1245 } | 1252 } |
1246 char *config_height = tern_find_path(config, "video\0height\0", TVAL_PTR).ptrval; | 1253 char *config_height = tern_find_path(config, "video\0height\0", TVAL_PTR).ptrval; |
1263 main_height = windowed_height; | 1270 main_height = windowed_height; |
1264 } | 1271 } |
1265 if (on_ui_fb_resized) { | 1272 if (on_ui_fb_resized) { |
1266 on_ui_fb_resized(); | 1273 on_ui_fb_resized(); |
1267 } | 1274 } |
1268 | 1275 |
1269 window_setup(); | 1276 window_setup(); |
1270 update_aspect(); | 1277 update_aspect(); |
1271 #ifndef DISABLE_OPENGL | 1278 #ifndef DISABLE_OPENGL |
1272 //need to check render_gl again after window_setup as render option could have changed | 1279 //need to check render_gl again after window_setup as render option could have changed |
1273 if (render_gl && on_context_created) { | 1280 if (render_gl && on_context_created) { |
1278 uint8_t was_paused = SDL_GetAudioStatus() == SDL_AUDIO_PAUSED; | 1285 uint8_t was_paused = SDL_GetAudioStatus() == SDL_AUDIO_PAUSED; |
1279 render_close_audio(); | 1286 render_close_audio(); |
1280 quitting = 0; | 1287 quitting = 0; |
1281 init_audio(); | 1288 init_audio(); |
1282 render_set_video_standard(video_standard); | 1289 render_set_video_standard(video_standard); |
1283 | 1290 |
1284 drain_events(); | 1291 drain_events(); |
1285 in_toggle = 0; | 1292 in_toggle = 0; |
1286 if (!was_paused) { | 1293 if (!was_paused) { |
1287 SDL_PauseAudio(0); | 1294 SDL_PauseAudio(0); |
1288 } | 1295 } |
1362 if (!extra_windows[i]) { | 1369 if (!extra_windows[i]) { |
1363 win_idx = i; | 1370 win_idx = i; |
1364 break; | 1371 break; |
1365 } | 1372 } |
1366 } | 1373 } |
1367 | 1374 |
1368 if (win_idx == 0xFF) { | 1375 if (win_idx == 0xFF) { |
1369 num_textures++; | 1376 num_textures++; |
1370 sdl_textures = realloc(sdl_textures, num_textures * sizeof(*sdl_textures)); | 1377 sdl_textures = realloc(sdl_textures, num_textures * sizeof(*sdl_textures)); |
1371 extra_windows = realloc(extra_windows, (num_textures - FRAMEBUFFER_USER_START) * sizeof(*extra_windows)); | 1378 extra_windows = realloc(extra_windows, (num_textures - FRAMEBUFFER_USER_START) * sizeof(*extra_windows)); |
1372 extra_renderers = realloc(extra_renderers, (num_textures - FRAMEBUFFER_USER_START) * sizeof(*extra_renderers)); | 1379 extra_renderers = realloc(extra_renderers, (num_textures - FRAMEBUFFER_USER_START) * sizeof(*extra_renderers)); |
1386 if (!sdl_textures[texture_idx]) { | 1393 if (!sdl_textures[texture_idx]) { |
1387 goto fail_texture; | 1394 goto fail_texture; |
1388 } | 1395 } |
1389 close_handlers[win_idx] = close_handler; | 1396 close_handlers[win_idx] = close_handler; |
1390 return texture_idx; | 1397 return texture_idx; |
1391 | 1398 |
1392 fail_texture: | 1399 fail_texture: |
1393 SDL_DestroyRenderer(extra_renderers[win_idx]); | 1400 SDL_DestroyRenderer(extra_renderers[win_idx]); |
1394 fail_renderer: | 1401 fail_renderer: |
1395 SDL_DestroyWindow(extra_windows[win_idx]); | 1402 SDL_DestroyWindow(extra_windows[win_idx]); |
1396 fail_window: | 1403 fail_window: |
1402 { | 1409 { |
1403 uint8_t win_idx = which - FRAMEBUFFER_USER_START; | 1410 uint8_t win_idx = which - FRAMEBUFFER_USER_START; |
1404 //Destroying the renderers also frees the textures | 1411 //Destroying the renderers also frees the textures |
1405 SDL_DestroyRenderer(extra_renderers[win_idx]); | 1412 SDL_DestroyRenderer(extra_renderers[win_idx]); |
1406 SDL_DestroyWindow(extra_windows[win_idx]); | 1413 SDL_DestroyWindow(extra_windows[win_idx]); |
1407 | 1414 |
1408 extra_renderers[win_idx] = NULL; | 1415 extra_renderers[win_idx] = NULL; |
1409 extra_windows[win_idx] = NULL; | 1416 extra_windows[win_idx] = NULL; |
1410 } | 1417 } |
1411 | 1418 |
1412 uint32_t *locked_pixels; | 1419 uint32_t *locked_pixels; |
1492 } | 1499 } |
1493 source_frame_count = frame_repeat[source_frame]; | 1500 source_frame_count = frame_repeat[source_frame]; |
1494 //TODO: Figure out what to do about SDL Render API texture locking | 1501 //TODO: Figure out what to do about SDL Render API texture locking |
1495 return; | 1502 return; |
1496 } | 1503 } |
1497 | 1504 |
1498 last_width = width; | 1505 last_width = width; |
1499 uint32_t height = which <= FRAMEBUFFER_EVEN | 1506 uint32_t height = which <= FRAMEBUFFER_EVEN |
1500 ? (video_standard == VID_NTSC ? 243 : 294) - (overscan_top[video_standard] + overscan_bot[video_standard]) | 1507 ? (video_standard == VID_NTSC ? 243 : 294) - (overscan_top[video_standard] + overscan_bot[video_standard]) |
1501 : 240; | 1508 : 240; |
1502 FILE *screenshot_file = NULL; | 1509 FILE *screenshot_file = NULL; |
1503 uint32_t shot_height, shot_width; | 1510 uint32_t shot_height, shot_width; |
1504 char *ext; | 1511 char *ext; |
1522 #ifndef DISABLE_OPENGL | 1529 #ifndef DISABLE_OPENGL |
1523 if (render_gl && which <= FRAMEBUFFER_EVEN) { | 1530 if (render_gl && which <= FRAMEBUFFER_EVEN) { |
1524 SDL_GL_MakeCurrent(main_window, main_context); | 1531 SDL_GL_MakeCurrent(main_window, main_context); |
1525 glBindTexture(GL_TEXTURE_2D, textures[which]); | 1532 glBindTexture(GL_TEXTURE_2D, textures[which]); |
1526 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, LINEBUF_SIZE, height, SRC_FORMAT, GL_UNSIGNED_BYTE, buffer + overscan_left[video_standard] + LINEBUF_SIZE * overscan_top[video_standard]); | 1533 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, LINEBUF_SIZE, height, SRC_FORMAT, GL_UNSIGNED_BYTE, buffer + overscan_left[video_standard] + LINEBUF_SIZE * overscan_top[video_standard]); |
1527 | 1534 |
1528 if (screenshot_file) { | 1535 if (screenshot_file) { |
1529 //properly supporting interlaced modes here is non-trivial, so only save the odd field for now | 1536 //properly supporting interlaced modes here is non-trivial, so only save the odd field for now |
1530 #ifndef DISABLE_ZLIB | 1537 #ifndef DISABLE_ZLIB |
1531 if (!strcasecmp(ext, "png")) { | 1538 if (!strcasecmp(ext, "png")) { |
1532 free(ext); | 1539 free(ext); |
1644 frames_to_problem < BUFFER_FRAMES_THRESHOLD | 1651 frames_to_problem < BUFFER_FRAMES_THRESHOLD |
1645 || (average_change < 0 && local_cur_min < 3*min_buffered / 4) | 1652 || (average_change < 0 && local_cur_min < 3*min_buffered / 4) |
1646 || (average_change >0 && local_cur_min > 5 * min_buffered / 4) | 1653 || (average_change >0 && local_cur_min > 5 * min_buffered / 4) |
1647 || cur_min_buffered < 0 | 1654 || cur_min_buffered < 0 |
1648 ) { | 1655 ) { |
1649 | 1656 |
1650 if (cur_min_buffered < 0) { | 1657 if (cur_min_buffered < 0) { |
1651 adjust_ratio = max_adjust; | 1658 adjust_ratio = max_adjust; |
1652 SDL_PauseAudio(1); | 1659 SDL_PauseAudio(1); |
1653 last_buffered = NO_LAST_BUFFERED; | 1660 last_buffered = NO_LAST_BUFFERED; |
1654 cur_min_buffered = 0; | 1661 cur_min_buffered = 0; |
1663 adjust_ratio = max_adjust; | 1670 adjust_ratio = max_adjust; |
1664 } | 1671 } |
1665 if (adjust_ratio != 0.0f) { | 1672 if (adjust_ratio != 0.0f) { |
1666 average_change = 0; | 1673 average_change = 0; |
1667 render_audio_adjust_speed(adjust_ratio); | 1674 render_audio_adjust_speed(adjust_ratio); |
1668 | 1675 |
1669 } | 1676 } |
1670 while (source_frame_count > 0) | 1677 while (source_frame_count > 0) |
1671 { | 1678 { |
1672 render_update_display(); | 1679 render_update_display(); |
1673 source_frame_count--; | 1680 source_frame_count--; |
1751 } | 1758 } |
1752 if (SDL_GetAudioStatus() != SDL_AUDIO_PLAYING) { | 1759 if (SDL_GetAudioStatus() != SDL_AUDIO_PLAYING) { |
1753 break; | 1760 break; |
1754 } | 1761 } |
1755 } | 1762 } |
1756 | 1763 |
1757 SDL_UnlockMutex(frame_mutex); | 1764 SDL_UnlockMutex(frame_mutex); |
1758 } | 1765 } |
1759 | 1766 |
1760 static ui_render_fun render_ui; | 1767 static ui_render_fun render_ui; |
1761 void render_set_ui_render_fun(ui_render_fun fun) | 1768 void render_set_ui_render_fun(ui_render_fun fun) |
1789 | 1796 |
1790 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); | 1797 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); |
1791 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void *)0); | 1798 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void *)0); |
1792 | 1799 |
1793 glDisableVertexAttribArray(at_pos); | 1800 glDisableVertexAttribArray(at_pos); |
1794 | 1801 |
1795 if (render_ui) { | 1802 if (render_ui) { |
1796 render_ui(); | 1803 render_ui(); |
1797 } | 1804 } |
1798 | 1805 |
1799 SDL_GL_SwapWindow(main_window); | 1806 SDL_GL_SwapWindow(main_window); |
1900 { | 1907 { |
1901 tern_node *button_lookup, *axis_lookup; | 1908 tern_node *button_lookup, *axis_lookup; |
1902 if (controller > MAX_JOYSTICKS || !joysticks[controller]) { | 1909 if (controller > MAX_JOYSTICKS || !joysticks[controller]) { |
1903 return RENDER_NOT_PLUGGED_IN; | 1910 return RENDER_NOT_PLUGGED_IN; |
1904 } | 1911 } |
1905 | 1912 |
1906 if (!SDL_IsGameController(joystick_sdl_index[controller])) { | 1913 if (!SDL_IsGameController(joystick_sdl_index[controller])) { |
1907 return RENDER_NOT_MAPPED; | 1914 return RENDER_NOT_MAPPED; |
1908 } | 1915 } |
1909 SDL_GameController *control = SDL_GameControllerOpen(joystick_sdl_index[controller]); | 1916 SDL_GameController *control = SDL_GameControllerOpen(joystick_sdl_index[controller]); |
1910 if (!control) { | 1917 if (!control) { |
1911 warning("Failed to open game controller %d: %s\n", controller, SDL_GetError()); | 1918 warning("Failed to open game controller %d: %s\n", controller, SDL_GetError()); |
1912 return RENDER_NOT_PLUGGED_IN; | 1919 return RENDER_NOT_PLUGGED_IN; |
1913 } | 1920 } |
1914 | 1921 |
1915 SDL_GameControllerButtonBind cbind; | 1922 SDL_GameControllerButtonBind cbind; |
1916 int32_t is_positive = RENDER_AXIS_POS; | 1923 int32_t is_positive = RENDER_AXIS_POS; |
1917 if (is_axis) { | 1924 if (is_axis) { |
1918 | 1925 |
1919 int sdl_axis = render_lookup_axis(name); | 1926 int sdl_axis = render_lookup_axis(name); |
1920 if (sdl_axis == SDL_CONTROLLER_AXIS_INVALID) { | 1927 if (sdl_axis == SDL_CONTROLLER_AXIS_INVALID) { |
1921 SDL_GameControllerClose(control); | 1928 SDL_GameControllerClose(control); |
1922 return RENDER_INVALID_NAME; | 1929 return RENDER_INVALID_NAME; |
1923 } | 1930 } |
1977 //protect against event processing causing us to attempt to toggle while still toggling | 1984 //protect against event processing causing us to attempt to toggle while still toggling |
1978 if (in_toggle) { | 1985 if (in_toggle) { |
1979 return; | 1986 return; |
1980 } | 1987 } |
1981 in_toggle = 1; | 1988 in_toggle = 1; |
1982 | 1989 |
1983 //toggling too fast seems to cause a deadlock | 1990 //toggling too fast seems to cause a deadlock |
1984 static uint32_t last_toggle; | 1991 static uint32_t last_toggle; |
1985 uint32_t cur = SDL_GetTicks(); | 1992 uint32_t cur = SDL_GetTicks(); |
1986 if (last_toggle && cur - last_toggle < TOGGLE_MIN_DELAY) { | 1993 if (last_toggle && cur - last_toggle < TOGGLE_MIN_DELAY) { |
1987 in_toggle = 0; | 1994 in_toggle = 0; |
1988 return; | 1995 return; |
1989 } | 1996 } |
1990 last_toggle = cur; | 1997 last_toggle = cur; |
1991 | 1998 |
1992 drain_events(); | 1999 drain_events(); |
1993 is_fullscreen = !is_fullscreen; | 2000 is_fullscreen = !is_fullscreen; |
1994 if (is_fullscreen) { | 2001 if (is_fullscreen) { |
1995 SDL_DisplayMode mode; | 2002 SDL_DisplayMode mode; |
1996 //TODO: Multiple monitor support | 2003 //TODO: Multiple monitor support |
2050 return FRAMEBUFFER_ODD; | 2057 return FRAMEBUFFER_ODD; |
2051 } | 2058 } |
2052 for (int i = 0; i < num_textures - 2; i++) | 2059 for (int i = 0; i < num_textures - 2; i++) |
2053 { | 2060 { |
2054 if (extra_windows[i] && (SDL_GetWindowFlags(extra_windows[i]) & SDL_WINDOW_INPUT_FOCUS)) { | 2061 if (extra_windows[i] && (SDL_GetWindowFlags(extra_windows[i]) & SDL_WINDOW_INPUT_FOCUS)) { |
2055 return FRAMEBUFFER_USER_START + i; | 2062 return FRAMEBUFFER_USER_START + i; |
2056 } | 2063 } |
2057 } | 2064 } |
2058 return 0xFF; | 2065 return 0xFF; |
2059 } | 2066 } |
2060 | 2067 |