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