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) {