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