Annotation of hatari/src/resolution.c, revision 1.1.1.8

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:        {
                     44:                fprintf(stderr, "SDL_GetDesktopDisplayMode failed: %s", SDL_GetError());
                     45:                DesktopWidth = 2*NUM_VISIBLE_LINE_PIXELS;
                     46:                DesktopHeight = 2*NUM_VISIBLE_LINES+STATUSBAR_MAX_HEIGHT;
                     47:        }
                     48: #else
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.2   root       61:                fprintf(stderr, "WARNING: invalid desktop size %dx%d, defaulting to %dx%d!\n",
                     62:                        info->current_w, info->current_h, DesktopWidth, DesktopHeight);
                     63:        }
1.1.1.6   root       64: #endif
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.8 ! root      142: #endif
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) {
                    214:                fprintf(stderr, "WARNING: No suitable video modes available!\n");
                    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.6   root      221: #endif
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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.