|
|
1.1 root 1: /*
2: Hatari - resolution.c
3:
1.1.1.4 root 4: This file is distributed under the GNU General Public License, version 2
5: or at your option any later version. Read the file gpl.txt for details.
1.1 root 6:
7: SDL resolution limitation and selection routines.
8: */
9: const char Resolution_fileid[] = "Hatari resolution.c : " __DATE__ " " __TIME__;
10:
11: #include <SDL.h>
12: #include "main.h"
13: #include "configuration.h"
1.1.1.8 root 14: #include "log.h"
1.1 root 15: #include "resolution.h"
1.1.1.6 root 16: #include "statusbar.h"
1.1 root 17: #include "screen.h"
18:
1.1.1.5 root 19: #define DEBUG 0
1.1 root 20:
1.1.1.5 root 21: #if DEBUG
22: # define DEBUGPRINT(x) printf x
1.1 root 23: #else
1.1.1.5 root 24: # define DEBUGPRINT(x)
1.1 root 25: #endif
26:
1.1.1.2 root 27: static int DesktopWidth, DesktopHeight;
28:
29: /**
30: * Initilizes resolution settings (gets current desktop
31: * resolution, sets max Falcon/TT Videl zooming resolution).
32: */
33: void Resolution_Init(void)
34: {
1.1.1.6 root 35: #if WITH_SDL2
36: SDL_DisplayMode dm;
37: if (SDL_GetDesktopDisplayMode(0, &dm) == 0)
38: {
39: DesktopWidth = dm.w;
40: DesktopHeight = dm.h;
41: }
42: else
43: {
1.1.1.9 ! root 44: Log_Printf(LOG_ERROR, "SDL_GetDesktopDisplayMode failed: %s", SDL_GetError());
1.1.1.6 root 45: DesktopWidth = 2*NUM_VISIBLE_LINE_PIXELS;
46: DesktopHeight = 2*NUM_VISIBLE_LINES+STATUSBAR_MAX_HEIGHT;
47: }
1.1.1.9 ! root 48: #else /* !WITH_SDL2 */
1.1.1.2 root 49: /* Needs to be called after SDL video and configuration
50: * initialization, but before Hatari Screen init is called
51: * for the first time!
52: */
53: const SDL_VideoInfo* info = SDL_GetVideoInfo();
54: if (info->current_w >= 640 && info->current_h >= 400) {
55: DesktopWidth = info->current_w;
56: DesktopHeight = info->current_h;
57: } else {
58: /* target 800x600 screen with statusbar out of screen */
1.1.1.6 root 59: DesktopWidth = 2*NUM_VISIBLE_LINE_PIXELS;
60: DesktopHeight = 2*NUM_VISIBLE_LINES+STATUSBAR_MAX_HEIGHT;
1.1.1.9 ! root 61: Log_Printf(LOG_WARN, "invalid desktop size %dx%d, defaulting to %dx%d!\n",
! 62: info->current_w, info->current_h, DesktopWidth, DesktopHeight);
1.1.1.2 root 63: }
1.1.1.9 ! root 64: #endif /* !WITH_SDL2 */
1.1.1.2 root 65: /* if user hasn't set own max zoom size, use desktop size */
66: if (!(ConfigureParams.Screen.nMaxWidth &&
67: ConfigureParams.Screen.nMaxHeight)) {
68: ConfigureParams.Screen.nMaxWidth = DesktopWidth;
69: ConfigureParams.Screen.nMaxHeight = DesktopHeight;
70: }
1.1.1.5 root 71: DEBUGPRINT(("Desktop resolution: %dx%d\n",DesktopWidth, DesktopHeight));
1.1.1.8 root 72: Log_Printf(LOG_DEBUG, "Configured max Hatari resolution = %dx%d, optimal for ST = %dx%d\n",
1.1.1.6 root 73: ConfigureParams.Screen.nMaxWidth, ConfigureParams.Screen.nMaxHeight,
74: 2*NUM_VISIBLE_LINE_PIXELS, 2*NUM_VISIBLE_LINES+STATUSBAR_MAX_HEIGHT);
1.1.1.2 root 75: }
76:
77: /**
78: * Get current desktop resolution
79: */
80: void Resolution_GetDesktopSize(int *width, int *height)
81: {
1.1.1.5 root 82: DEBUGPRINT(("resolution: limit to desktop size\n"));
1.1.1.2 root 83: *width = DesktopWidth;
84: *height = DesktopHeight;
85: }
1.1 root 86:
87: /**
1.1.1.3 root 88: * Get max resolution
89: */
90: static void Resolution_GetMaxSize(int *width, int *height)
91: {
1.1.1.5 root 92: DEBUGPRINT(("resolution: force to specified max size\n"));
1.1.1.3 root 93: *width = ConfigureParams.Screen.nMaxWidth;
94: *height = ConfigureParams.Screen.nMaxHeight;
95: }
96:
97: /**
1.1 root 98: * Select best resolution from given SDL video modes.
99: * - If width and height are given, select the smallest mode larger
100: * or equal to requested size
101: * - Otherwise select the largest available mode
102: * return true for success and false if no matching mode was found.
103: */
1.1.1.8 root 104: #if !WITH_SDL2
105: static bool Resolution_Select(SDL_Rect **modes, int *width, int *height)
1.1 root 106: {
107: #define TOO_LARGE 0x7fff
108: int i, bestw, besth;
109:
110: if (!(*width && *height)) {
111: /* search the largest mode (prefer wider ones) */
112: for (i = 0; modes[i]; i++) {
113: if ((modes[i]->w > *width) && (modes[i]->h >= *height)) {
114: *width = modes[i]->w;
115: *height = modes[i]->h;
116: }
117: }
1.1.1.5 root 118: DEBUGPRINT(("resolution: largest found video mode: %dx%d\n",*width,*height));
1.1 root 119: return true;
120: }
121:
122: /* Search the smallest mode larger or equal to requested size */
123: bestw = TOO_LARGE;
124: besth = TOO_LARGE;
125: for (i = 0; modes[i]; i++) {
126: if ((modes[i]->w >= *width) && (modes[i]->h >= *height)) {
127: if ((modes[i]->w < bestw) || (modes[i]->h < besth)) {
128: bestw = modes[i]->w;
129: besth = modes[i]->h;
130: }
131: }
132: }
133: if (bestw == TOO_LARGE || besth == TOO_LARGE) {
134: return false;
135: }
136: *width = bestw;
137: *height = besth;
1.1.1.5 root 138: DEBUGPRINT(("resolution: video mode found: %dx%d\n",*width,*height));
1.1 root 139: return true;
140: #undef TOO_LARGE
141: }
1.1.1.9 ! root 142: #endif /* !WITH_SDL2 */
1.1 root 143:
144:
145: /**
146: * Search video mode size that best suits the given width/height/bpp
147: * constraints and set them into given arguments. With zeroed arguments,
1.1.1.5 root 148: * set largest video mode.
149: *
150: * Return true if mode is forced (shouldn't be further limited).
1.1 root 151: */
1.1.1.5 root 152: bool Resolution_Search(int *width, int *height, int *bpp, bool keep)
1.1 root 153: {
1.1.1.6 root 154: #if !WITH_SDL2
1.1 root 155: SDL_Rect **modes;
156: SDL_PixelFormat pixelformat;
1.1.1.6 root 157: Uint32 modeflags = 0 /*SDL_HWSURFACE | SDL_HWPALETTE*/;
158: #endif
1.1 root 159:
160: /* Search in available modes the best suited */
1.1.1.5 root 161: DEBUGPRINT(("resolution: video mode asked: %dx%dx%d (%s)\n",
162: *width, *height, *bpp, bInFullScreen ? "fullscreen" : "windowed"));
1.1.1.3 root 163:
1.1.1.6 root 164: if (bInFullScreen)
165: {
1.1.1.2 root 166: /* resolution change not allowed? */
1.1.1.6 root 167: if (keep)
168: {
1.1.1.2 root 169: Resolution_GetDesktopSize(width, height);
1.1.1.7 root 170: #if WITH_SDL2
171: return false;
172: #else
1.1.1.5 root 173: return true;
1.1.1.7 root 174: #endif
1.1.1.2 root 175: }
176: }
1.1.1.6 root 177: if (ConfigureParams.Screen.bForceMax)
178: {
1.1.1.3 root 179: /* force given max size */
180: Resolution_GetMaxSize(width, height);
1.1.1.5 root 181: return true;
1.1.1.3 root 182: }
183:
1.1.1.6 root 184: #if !WITH_SDL2
185: if (bInFullScreen)
186: modeflags |= SDL_FULLSCREEN;
1.1 root 187:
188: /*--- Search a video mode with asked bpp ---*/
189: if (*bpp != 0) {
190: pixelformat.BitsPerPixel = *bpp;
191: modes = SDL_ListModes(&pixelformat, modeflags);
192: if ((modes != (SDL_Rect **) 0) && (modes != (SDL_Rect **) -1)) {
1.1.1.5 root 193: DEBUGPRINT(("resolution: searching a good video mode (given bpp)\n"));
1.1 root 194: if (Resolution_Select(modes, width, height)) {
1.1.1.5 root 195: DEBUGPRINT(("resolution: video mode selected: %dx%dx%d\n",
1.1 root 196: *width, *height, *bpp));
1.1.1.5 root 197: return false;
1.1 root 198: }
199: }
200: }
201:
202: /*--- Search a video mode with any bpp ---*/
203: modes = SDL_ListModes(NULL, modeflags);
204: if ((modes != (SDL_Rect **) 0) && (modes != (SDL_Rect **) -1)) {
1.1.1.5 root 205: DEBUGPRINT(("resolution: searching a good video mode (any bpp)\n"));
1.1 root 206: if (Resolution_Select(modes, width, height)) {
1.1.1.5 root 207: DEBUGPRINT(("resolution: video mode selected: %dx%dx%d\n",
1.1 root 208: *width, *height, *bpp));
1.1.1.5 root 209: return false;
1.1 root 210: }
211: }
212:
213: if (modes == (SDL_Rect **) 0) {
1.1.1.9 ! root 214: Log_Printf(LOG_WARN, "no suitable video modes available!\n");
1.1 root 215: }
216:
217: if (modes == (SDL_Rect **) -1) {
218: /* Any mode available */
1.1.1.5 root 219: DEBUGPRINT(("resolution: All resolutions available.\n"));
1.1 root 220: }
1.1.1.9 ! root 221: #endif /* !WITH_SDL2 */
1.1 root 222:
1.1.1.5 root 223: DEBUGPRINT(("resolution: video mode selected: %dx%dx%d\n",
1.1 root 224: *width, *height, *bpp));
1.1.1.5 root 225: return false;
1.1 root 226: }
227:
228:
229: /**
1.1.1.2 root 230: * Set given width & height arguments to maximum size allowed in the
231: * configuration, or if that's too large for the requested bit depth,
232: * to the largest available video mode size.
1.1 root 233: */
1.1.1.4 root 234: void Resolution_GetLimits(int *width, int *height, int *bpp, bool keep)
1.1 root 235: {
236: *width = *height = 0;
1.1.1.5 root 237:
1.1 root 238: /* constrain max size to what HW/SDL offers */
1.1.1.5 root 239: DEBUGPRINT(("resolution: request limits for: %dx%dx%d\n", *width, *height, *bpp));
240:
241: /* forced resolution? */
242: if (Resolution_Search(width, height, bpp, keep)) {
1.1.1.3 root 243: return;
244: }
245:
1.1.1.2 root 246: if (!(*width && *height) ||
1.1 root 247: (ConfigureParams.Screen.nMaxWidth < *width &&
248: ConfigureParams.Screen.nMaxHeight < *height)) {
1.1.1.5 root 249: DEBUGPRINT(("resolution: limit to user configured max\n"));
1.1 root 250: *width = ConfigureParams.Screen.nMaxWidth;
251: *height = ConfigureParams.Screen.nMaxHeight;
252: }
253: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.