|
|
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.5 root 167: return true;
1.1.1.2 root 168: }
169: }
1.1.1.6 ! root 170: if (ConfigureParams.Screen.bForceMax)
! 171: {
1.1.1.3 root 172: /* force given max size */
173: Resolution_GetMaxSize(width, height);
1.1.1.5 root 174: return true;
1.1.1.3 root 175: }
176:
1.1.1.6 ! root 177: #if !WITH_SDL2
! 178: if (bInFullScreen)
! 179: modeflags |= SDL_FULLSCREEN;
1.1 root 180:
181: /*--- Search a video mode with asked bpp ---*/
182: if (*bpp != 0) {
183: pixelformat.BitsPerPixel = *bpp;
184: modes = SDL_ListModes(&pixelformat, modeflags);
185: if ((modes != (SDL_Rect **) 0) && (modes != (SDL_Rect **) -1)) {
1.1.1.5 root 186: DEBUGPRINT(("resolution: searching a good video mode (given bpp)\n"));
1.1 root 187: if (Resolution_Select(modes, width, height)) {
1.1.1.5 root 188: DEBUGPRINT(("resolution: video mode selected: %dx%dx%d\n",
1.1 root 189: *width, *height, *bpp));
1.1.1.5 root 190: return false;
1.1 root 191: }
192: }
193: }
194:
195: /*--- Search a video mode with any bpp ---*/
196: modes = SDL_ListModes(NULL, modeflags);
197: if ((modes != (SDL_Rect **) 0) && (modes != (SDL_Rect **) -1)) {
1.1.1.5 root 198: DEBUGPRINT(("resolution: searching a good video mode (any bpp)\n"));
1.1 root 199: if (Resolution_Select(modes, width, height)) {
1.1.1.5 root 200: DEBUGPRINT(("resolution: video mode selected: %dx%dx%d\n",
1.1 root 201: *width, *height, *bpp));
1.1.1.5 root 202: return false;
1.1 root 203: }
204: }
205:
206: if (modes == (SDL_Rect **) 0) {
207: fprintf(stderr, "WARNING: No suitable video modes available!\n");
208: }
209:
210: if (modes == (SDL_Rect **) -1) {
211: /* Any mode available */
1.1.1.5 root 212: DEBUGPRINT(("resolution: All resolutions available.\n"));
1.1 root 213: }
1.1.1.6 ! root 214: #endif
1.1 root 215:
1.1.1.5 root 216: DEBUGPRINT(("resolution: video mode selected: %dx%dx%d\n",
1.1 root 217: *width, *height, *bpp));
1.1.1.5 root 218: return false;
1.1 root 219: }
220:
221:
222: /**
1.1.1.2 root 223: * Set given width & height arguments to maximum size allowed in the
224: * configuration, or if that's too large for the requested bit depth,
225: * to the largest available video mode size.
1.1 root 226: */
1.1.1.4 root 227: void Resolution_GetLimits(int *width, int *height, int *bpp, bool keep)
1.1 root 228: {
229: *width = *height = 0;
1.1.1.5 root 230:
1.1 root 231: /* constrain max size to what HW/SDL offers */
1.1.1.5 root 232: DEBUGPRINT(("resolution: request limits for: %dx%dx%d\n", *width, *height, *bpp));
233:
234: /* forced resolution? */
235: if (Resolution_Search(width, height, bpp, keep)) {
1.1.1.3 root 236: return;
237: }
238:
1.1.1.2 root 239: if (!(*width && *height) ||
1.1 root 240: (ConfigureParams.Screen.nMaxWidth < *width &&
241: ConfigureParams.Screen.nMaxHeight < *height)) {
1.1.1.5 root 242: DEBUGPRINT(("resolution: limit to user configured max\n"));
1.1 root 243: *width = ConfigureParams.Screen.nMaxWidth;
244: *height = ConfigureParams.Screen.nMaxHeight;
245: }
246: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.