Mercurial > repos > blastem
comparison render_sdl.c @ 2308:b7768c58f0da
Initial stab at DPI scaling support
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 26 Mar 2023 22:39:18 -0700 |
parents | c79896ff1a2d |
children | b67e4e930fa4 |
comparison
equal
deleted
inserted
replaced
2307:a8080240cb92 | 2308:b7768c58f0da |
---|---|
295 render_config_updated(); | 295 render_config_updated(); |
296 } | 296 } |
297 } | 297 } |
298 } | 298 } |
299 | 299 |
300 static int tex_width, tex_height; | |
300 #ifndef DISABLE_OPENGL | 301 #ifndef DISABLE_OPENGL |
301 static GLuint textures[3], buffers[2], vshader, fshader, program, un_textures[2], un_width, un_height, un_texsize, at_pos; | 302 static GLuint textures[3], buffers[2], vshader, fshader, program, un_textures[2], un_width, un_height, un_texsize, at_pos; |
302 static int tex_width, tex_height; | |
303 | 303 |
304 static GLfloat vertex_data_default[] = { | 304 static GLfloat vertex_data_default[] = { |
305 -1.0f, -1.0f, | 305 -1.0f, -1.0f, |
306 1.0f, -1.0f, | 306 1.0f, -1.0f, |
307 -1.0f, 1.0f, | 307 -1.0f, 1.0f, |
808 handle_joy_added(joystick); | 808 handle_joy_added(joystick); |
809 } | 809 } |
810 return desired_index; | 810 return desired_index; |
811 } | 811 } |
812 | 812 |
813 static float ui_scale_x = 1.0f, ui_scale_y = 1.0f; | |
814 int render_ui_to_pixels_x(int ui) | |
815 { | |
816 return ui * ui_scale_x + 0.5f; | |
817 } | |
818 | |
819 int render_ui_to_pixels_y(int ui) | |
820 { | |
821 return ui * ui_scale_y + 0.5f; | |
822 } | |
823 | |
813 static int32_t handle_event(SDL_Event *event) | 824 static int32_t handle_event(SDL_Event *event) |
814 { | 825 { |
815 if (custom_event_handler) { | 826 if (custom_event_handler) { |
816 custom_event_handler(event); | 827 custom_event_handler(event); |
817 } | 828 } |
866 debug_message("Failed to find removed joystick with instance ID: %d\n", index); | 877 debug_message("Failed to find removed joystick with instance ID: %d\n", index); |
867 } | 878 } |
868 break; | 879 break; |
869 } | 880 } |
870 case SDL_MOUSEMOTION: | 881 case SDL_MOUSEMOTION: |
871 handle_mouse_moved(event->motion.which, event->motion.x, event->motion.y + overscan_top[video_standard], event->motion.xrel, event->motion.yrel); | 882 handle_mouse_moved(event->motion.which, event->motion.x * ui_scale_x + 0.5f, event->motion.y * ui_scale_y + 0.5f + overscan_top[video_standard], event->motion.xrel, event->motion.yrel); |
872 break; | 883 break; |
873 case SDL_MOUSEBUTTONDOWN: | 884 case SDL_MOUSEBUTTONDOWN: |
874 handle_mousedown(event->button.which, event->button.button); | 885 handle_mousedown(event->button.which, event->button.button); |
875 break; | 886 break; |
876 case SDL_MOUSEBUTTONUP: | 887 case SDL_MOUSEBUTTONUP: |
881 { | 892 { |
882 case SDL_WINDOWEVENT_SIZE_CHANGED: | 893 case SDL_WINDOWEVENT_SIZE_CHANGED: |
883 if (!main_window) { | 894 if (!main_window) { |
884 break; | 895 break; |
885 } | 896 } |
886 main_width = event->window.data1; | |
887 main_height = event->window.data2; | |
888 need_ui_fb_resize = 1; | 897 need_ui_fb_resize = 1; |
889 update_aspect(); | |
890 #ifndef DISABLE_OPENGL | 898 #ifndef DISABLE_OPENGL |
891 if (render_gl) { | 899 if (render_gl) { |
892 if (on_context_destroyed) { | 900 if (on_context_destroyed) { |
893 on_context_destroyed(); | 901 on_context_destroyed(); |
894 } | 902 } |
895 gl_teardown(); | 903 gl_teardown(); |
896 SDL_GL_DeleteContext(main_context); | 904 SDL_GL_DeleteContext(main_context); |
897 main_context = SDL_GL_CreateContext(main_window); | 905 main_context = SDL_GL_CreateContext(main_window); |
906 SDL_GL_GetDrawableSize(main_window, &main_width, &main_height); | |
907 update_aspect(); | |
898 gl_setup(); | 908 gl_setup(); |
899 if (on_context_created) { | 909 if (on_context_created) { |
900 on_context_created(); | 910 on_context_created(); |
901 } | 911 } |
902 } | 912 } else { |
903 #endif | 913 #endif |
914 SDL_GetRendererOutputSize(main_renderer, &main_width, &main_height); | |
915 update_aspect(); | |
916 #ifndef DISABLE_OPENGL | |
917 } | |
918 #endif | |
919 if (main_width != event->window.data1 || main_height != event->window.data2) { | |
920 debug_message("Window resized - UI units %dx%d, pixels %dx%d\n", event->window.data1, event->window.data2, main_width, main_height); | |
921 } else { | |
922 debug_message("Window resized: %dx%d\n", main_width, main_height); | |
923 } | |
924 ui_scale_x = (float)main_width / (float)event->window.data1; | |
925 ui_scale_y = (float)main_height / (float)event->window.data2; | |
904 break; | 926 break; |
905 case SDL_WINDOWEVENT_CLOSE: | 927 case SDL_WINDOWEVENT_CLOSE: |
906 if (main_window && SDL_GetWindowID(main_window) == event->window.windowID) { | 928 if (main_window && SDL_GetWindowID(main_window) == event->window.windowID) { |
907 exit(0); | 929 exit(0); |
908 } else { | 930 } else { |
1000 render_audio_initialized(format, actual.freq, actual.channels, actual.samples, SDL_AUDIO_BITSIZE(actual.format) / 8); | 1022 render_audio_initialized(format, actual.freq, actual.channels, actual.samples, SDL_AUDIO_BITSIZE(actual.format) / 8); |
1001 } | 1023 } |
1002 | 1024 |
1003 void window_setup(void) | 1025 void window_setup(void) |
1004 { | 1026 { |
1005 uint32_t flags = SDL_WINDOW_RESIZABLE; | 1027 uint32_t flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; |
1006 if (is_fullscreen) { | 1028 if (is_fullscreen) { |
1007 flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; | 1029 flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; |
1008 } | 1030 } |
1009 | 1031 |
1010 tern_val def = {.ptrval = "audio"}; | 1032 tern_val def = {.ptrval = "audio"}; |
1087 #endif | 1109 #endif |
1088 main_window = SDL_CreateWindow(caption, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, main_width, main_height, flags); | 1110 main_window = SDL_CreateWindow(caption, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, main_width, main_height, flags); |
1089 if (!main_window) { | 1111 if (!main_window) { |
1090 fatal_error("Unable to create SDL window: %s\n", SDL_GetError()); | 1112 fatal_error("Unable to create SDL window: %s\n", SDL_GetError()); |
1091 } | 1113 } |
1114 SDL_GetWindowSize(main_window, &main_width, &main_height); | |
1115 debug_message("Window created with size: %d x %d\n", main_width, main_height); | |
1116 int orig_width = main_width, orig_height = main_height; | |
1092 #ifndef DISABLE_OPENGL | 1117 #ifndef DISABLE_OPENGL |
1093 if (gl_enabled) | 1118 if (gl_enabled) |
1094 { | 1119 { |
1095 main_context = SDL_GL_CreateContext(main_window); | 1120 main_context = SDL_GL_CreateContext(main_window); |
1096 #ifdef USE_GLES | 1121 #ifdef USE_GLES |
1121 #else | 1146 #else |
1122 warning("Failed to set vsync to %s: %s\n", vsync, SDL_GetError()); | 1147 warning("Failed to set vsync to %s: %s\n", vsync, SDL_GetError()); |
1123 #endif | 1148 #endif |
1124 } | 1149 } |
1125 } | 1150 } |
1151 SDL_GL_GetDrawableSize(main_window, &main_width, &main_height); | |
1126 } else { | 1152 } else { |
1127 warning("OpenGL 2.0 is unavailable, falling back to SDL2 renderer\n"); | 1153 warning("OpenGL 2.0 is unavailable, falling back to SDL2 renderer\n"); |
1128 } | 1154 } |
1129 } | 1155 } |
1130 if (!render_gl) { | 1156 if (!render_gl) { |
1136 main_renderer = SDL_CreateRenderer(main_window, -1, flags); | 1162 main_renderer = SDL_CreateRenderer(main_window, -1, flags); |
1137 | 1163 |
1138 if (!main_renderer) { | 1164 if (!main_renderer) { |
1139 fatal_error("unable to create SDL renderer: %s\n", SDL_GetError()); | 1165 fatal_error("unable to create SDL renderer: %s\n", SDL_GetError()); |
1140 } | 1166 } |
1167 SDL_GetRendererOutputSize(main_renderer, &main_width, &main_height); | |
1141 SDL_RendererInfo rinfo; | 1168 SDL_RendererInfo rinfo; |
1142 SDL_GetRendererInfo(main_renderer, &rinfo); | 1169 SDL_GetRendererInfo(main_renderer, &rinfo); |
1143 debug_message("SDL2 Render Driver: %s\n", rinfo.name); | 1170 debug_message("SDL2 Render Driver: %s\n", rinfo.name); |
1144 main_clip.x = main_clip.y = 0; | 1171 main_clip.x = main_clip.y = 0; |
1145 main_clip.w = main_width; | 1172 main_clip.w = main_width; |
1146 main_clip.h = main_height; | 1173 main_clip.h = main_height; |
1147 #ifndef DISABLE_OPENGL | 1174 #ifndef DISABLE_OPENGL |
1148 } | 1175 } |
1149 #endif | 1176 #endif |
1150 | 1177 |
1151 SDL_GetWindowSize(main_window, &main_width, &main_height); | 1178 if (main_width != orig_width || main_height != orig_height) { |
1152 debug_message("Window created with size: %d x %d\n", main_width, main_height); | 1179 debug_message("True window resolution %d x %d\n", main_width, main_height); |
1180 } | |
1181 ui_scale_x = (float)main_width / (float)orig_width; | |
1182 ui_scale_y = (float)main_height / (float)orig_height; | |
1183 | |
1184 | |
1153 update_aspect(); | 1185 update_aspect(); |
1154 render_alloc_surfaces(); | 1186 render_alloc_surfaces(); |
1155 def.ptrval = "off"; | 1187 def.ptrval = "off"; |
1156 scanlines = !strcmp(tern_find_path_default(config, "video\0scanlines\0", def, TVAL_PTR).ptrval, "on"); | 1188 scanlines = !strcmp(tern_find_path_default(config, "video\0scanlines\0", def, TVAL_PTR).ptrval, "on"); |
1157 } | 1189 } |
1158 | 1190 |
1159 void render_init(int width, int height, char * title, uint8_t fullscreen) | 1191 void render_init(int width, int height, char * title, uint8_t fullscreen) |
1160 { | 1192 { |
1193 #ifdef SDL_HINT_WINDOWS_DPI_SCALING | |
1194 //In some ways, the other DPI scaling option for SDL2 on Windows is better for BlastEm's needs, | |
1195 //but setting this makes it more consistent with how high DPI support works on other platforms | |
1196 SDL_SetHint(SDL_HINT_WINDOWS_DPI_SCALING, "1"); | |
1197 #endif | |
1161 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0) { | 1198 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0) { |
1162 fatal_error("Unable to init SDL: %s\n", SDL_GetError()); | 1199 fatal_error("Unable to init SDL: %s\n", SDL_GetError()); |
1163 } | 1200 } |
1164 atexit(SDL_Quit); | 1201 atexit(SDL_Quit); |
1165 if (height <= 0) { | 1202 if (height <= 0) { |