Annotation of hatari/src/falcon/hostscreen.c, revision 1.1.1.5

1.1       root        1: /*
                      2:   Hatari - hostscreen.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:   Host video routines. This file originally came from the Aranym project but
                      8:   has been thoroughly reworked for Hatari. However, integration with the rest
                      9:   of the Hatari source code is still bad and needs a lot of improvement...
                     10: */
1.1.1.4   root       11: const char HostScreen_fileid[] = "Hatari hostscreen.c : " __DATE__ " " __TIME__;
1.1       root       12: 
                     13: #include "main.h"
                     14: #include "configuration.h"
1.1.1.2   root       15: #include "control.h"
1.1       root       16: #include "sysdeps.h"
                     17: #include "stMemory.h"
                     18: #include "ioMem.h"
                     19: #include "hostscreen.h"
1.1.1.5 ! root       20: #include "resolution.h"
1.1       root       21: #include "screen.h"
1.1.1.2   root       22: #include "statusbar.h"
1.1       root       23: 
                     24: #define VIDEL_DEBUG 0
                     25: 
                     26: #if VIDEL_DEBUG
                     27: #define Dprintf(a) printf a
                     28: #else
                     29: #define Dprintf(a)
                     30: #endif
                     31: 
                     32: 
                     33: #define RGB_BLACK     0x00000000
                     34: #define RGB_BLUE      0x000000ff
                     35: #define RGB_GREEN     0x00ff0000
                     36: #define RGB_CYAN      0x00ff00ff
                     37: #define RGB_RED       0xff000000
                     38: #define RGB_MAGENTA   0xff0000ff
                     39: #define RGB_LTGRAY    0xbbbb00bb
                     40: #define RGB_GRAY      0x88880088
                     41: #define RGB_LTBLUE    0x000000aa
                     42: #define RGB_LTGREEN   0x00aa0000
                     43: #define RGB_LTCYAN    0x00aa00aa
                     44: #define RGB_LTRED     0xaa000000
                     45: #define RGB_LTMAGENTA 0xaa0000aa
                     46: #define RGB_YELLOW    0xffff0000
                     47: #define RGB_LTYELLOW  0xaaaa0000
                     48: #define RGB_WHITE     0xffff00ff
                     49: 
                     50: 
                     51: static SDL_Surface *mainSurface;        // The main window surface
                     52: static SDL_Surface *surf;               // pointer to actual surface
                     53: 
1.1.1.5 ! root       54: /* TODO: put these hostscreen globals to some struct */
1.1.1.2   root       55: static Uint32 sdl_videoparams;
1.1.1.5 ! root       56: static int hs_width, hs_height, hs_width_req, hs_height_req, hs_bpp;
1.1.1.2   root       57: static bool   doUpdate; // the HW surface is available -> the SDL need not to update the surface after ->pixel access
1.1       root       58: 
                     59: static struct { // TOS palette (bpp < 16) to SDL color mapping
                     60:        SDL_Color       standard[256];
1.1.1.2   root       61:        Uint32          native[256];
1.1       root       62: } palette;
                     63: 
                     64: 
                     65: static const unsigned long default_palette[] = {
                     66:     RGB_WHITE, RGB_RED, RGB_GREEN, RGB_YELLOW,
                     67:     RGB_BLUE, RGB_MAGENTA, RGB_CYAN, RGB_LTGRAY,
                     68:     RGB_GRAY, RGB_LTRED, RGB_LTGREEN, RGB_LTYELLOW,
                     69:     RGB_LTBLUE, RGB_LTMAGENTA, RGB_LTCYAN, RGB_BLACK
                     70: };
                     71: 
                     72: 
1.1.1.4   root       73: void HostScreen_Init(void)
                     74: {
1.1       root       75:        int i;
                     76:        for(i=0; i<256; i++) {
                     77:                unsigned long color = default_palette[i%16];
                     78:                palette.standard[i].r = color >> 24;
                     79:                palette.standard[i].g = (color >> 16) & 0xff;
                     80:                palette.standard[i].b = color & 0xff;
                     81:        }
                     82: 
                     83:        mainSurface=NULL;
                     84: }
                     85: 
1.1.1.4   root       86: void HostScreen_UnInit(void)
                     87: {
1.1       root       88: }
                     89: 
                     90: 
                     91: void HostScreen_toggleFullScreen(void)
                     92: {
                     93:        sdl_videoparams ^= SDL_FULLSCREEN;
                     94: 
1.1.1.5 ! root       95:        HostScreen_setWindowSize(hs_width_req, hs_height_req, hs_bpp);
        !            96:        /* refresh the screen */
        !            97:        HostScreen_update1(true);
1.1       root       98: }
                     99: 
                    100: 
1.1.1.5 ! root      101: void HostScreen_setWindowSize(int width, int height, int bpp)
1.1       root      102: {
1.1.1.5 ! root      103:        int screenwidth, screenheight, maxw, maxh;
        !           104:        int scalex, scaley, sbarheight;
1.1       root      105: 
1.1.1.5 ! root      106:        if (bpp == 24)
        !           107:                bpp = 32;
1.1       root      108: 
1.1.1.5 ! root      109:        Resolution_GetLimits(&maxw, &maxh, &bpp);
1.1       root      110: 
1.1.1.5 ! root      111:        nScreenZoomX = nScreenZoomY = 1;
        !           112:        
        !           113:        if (ConfigureParams.Screen.bAspectCorrect) {
        !           114:                /* Falcon (and TT) pixel scaling factors seem to 2^x
        !           115:                 * (quarter/half pixel, interlace/double line), so
        !           116:                 * do aspect correction as 2's exponent.
        !           117:                 */
        !           118:                while (nScreenZoomX*width < height &&
        !           119:                       2*nScreenZoomX*width < maxw) {
        !           120:                        nScreenZoomX *= 2;
1.1       root      121:                }
1.1.1.5 ! root      122:                while (2*nScreenZoomY*height < width &&
        !           123:                       2*nScreenZoomY*height < maxh) {
        !           124:                        nScreenZoomY *= 2;
        !           125:                }
        !           126:                if (nScreenZoomX*nScreenZoomY > 2) {
        !           127:                        fprintf(stderr, "WARNING: strange screen size %dx%d -> aspect corrected by %dx%d!\n",
        !           128:                                width, height, nScreenZoomX, nScreenZoomY);
1.1       root      129:                }
                    130:        }
                    131: 
1.1.1.5 ! root      132:        /* then select scale as close to target size as possible
        !           133:         * without having larger size than it
        !           134:         */
        !           135:        scalex = maxw/(nScreenZoomX*width);
        !           136:        scaley = maxh/(nScreenZoomY*height);
        !           137:        if (scalex > 1 && scaley > 1) {
        !           138:                /* keep aspect ratio */
        !           139:                if (scalex < scaley) {
        !           140:                        nScreenZoomX *= scalex;
        !           141:                        nScreenZoomY *= scalex;
        !           142:                } else {
        !           143:                        nScreenZoomX *= scaley;
        !           144:                        nScreenZoomY *= scaley;
        !           145:                }
1.1       root      146:        }
                    147: 
1.1.1.5 ! root      148:        hs_width_req = width;
        !           149:        hs_height_req = height;
        !           150:        width *= nScreenZoomX;
        !           151:        height *= nScreenZoomY;
        !           152: 
        !           153:        sbarheight = Statusbar_GetHeightForSize(width, height);
        !           154:        screenheight = height + sbarheight;
        !           155:        screenwidth = width;
1.1.1.4   root      156: 
1.1.1.5 ! root      157:        // Select a correct video mode
        !           158:        Resolution_Search(&screenwidth, &screenheight, &bpp);
        !           159:        sbarheight = Statusbar_SetHeight(screenwidth, screenheight-sbarheight);
1.1.1.4   root      160: 
1.1.1.5 ! root      161:        hs_bpp = bpp;
        !           162:        /* videl.c might scale things differently in fullscreen than
        !           163:         * in windowed mode because this uses screensize instead of using
        !           164:         * the aspect scaled sizes directly, but it works better this way.
        !           165:         */
        !           166:        hs_width = screenwidth;
        !           167:        hs_height = screenheight - sbarheight;
        !           168: 
        !           169:        if (sdlscrn && (!bpp || sdlscrn->format->BitsPerPixel == bpp) &&
        !           170:            sdlscrn->w == (signed)screenwidth && sdlscrn->h == (signed)screenheight &&
        !           171:            (sdlscrn->flags&SDL_FULLSCREEN) == (sdl_videoparams&SDL_FULLSCREEN))
1.1       root      172:        {
1.1.1.5 ! root      173:                /* no time consuming host video mode change needed */
        !           174:                if (screenwidth > width || screenheight > height+sbarheight) {
        !           175:                        /* Atari screen smaller than host -> clear screen */
        !           176:                        SDL_Rect rect;
        !           177:                        rect.x = 0;
        !           178:                        rect.y = 0;
        !           179:                        rect.w = sdlscrn->w;
        !           180:                        rect.h = sdlscrn->h - sbarheight;
        !           181:                        SDL_FillRect(sdlscrn, &rect, SDL_MapRGB(sdlscrn->format, 0, 0, 0));
1.1       root      182:                }
1.1.1.5 ! root      183:                return;
1.1       root      184:        }
                    185: 
1.1.1.2   root      186:        if (bInFullScreen) {
                    187:                /* un-embed the Hatari WM window for fullscreen */
1.1.1.5 ! root      188:                Control_ReparentWindow(screenwidth, screenheight, bInFullScreen);
1.1.1.2   root      189: 
1.1       root      190:                sdl_videoparams = SDL_SWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN;
1.1.1.2   root      191:        } else {
1.1       root      192:                sdl_videoparams = SDL_SWSURFACE|SDL_HWPALETTE;
1.1.1.2   root      193:        }
1.1.1.5 ! root      194: #ifdef _MUDFLAP
        !           195:        if (sdlscrn) {
        !           196:                __mf_unregister(sdlscrn->pixels, sdlscrn->pitch*sdlscrn->h, __MF_TYPE_GUESS);
        !           197:        }
        !           198: #endif
        !           199:        mainSurface = SDL_SetVideoMode(screenwidth, screenheight, bpp, sdl_videoparams);
        !           200:        sdlscrn = surf = mainSurface;
        !           201: #ifdef _MUDFLAP
        !           202:        __mf_register(sdlscrn->pixels, sdlscrn->pitch*sdlscrn->h, __MF_TYPE_GUESS, "SDL pixels");
        !           203: #endif
1.1.1.2   root      204:        if (!bInFullScreen) {
                    205:                /* re-embed the new Hatari SDL window */
1.1.1.5 ! root      206:                Control_ReparentWindow(screenwidth, screenheight, bInFullScreen);
1.1.1.2   root      207:        }
1.1       root      208: 
                    209:        // update the surface's palette
                    210:        HostScreen_updatePalette( 256 );
                    211: 
1.1.1.5 ! root      212:        // redraw statusbar
1.1.1.2   root      213:        Statusbar_Init(mainSurface);
                    214: 
1.1       root      215:        Dprintf(("Surface Pitch = %d, width = %d, height = %d\n", surf->pitch, surf->w, surf->h));
                    216:        Dprintf(("Must Lock? %s\n", SDL_MUSTLOCK(surf) ? "YES" : "NO"));
                    217: 
                    218:        // is the SDL_update needed?
                    219:        doUpdate = ( surf->flags & SDL_HWSURFACE ) == 0;
                    220: 
                    221:        Dprintf(("Pixel format:bitspp=%d, tmasks r=%04x g=%04x b=%04x"
                    222:                        ", tshifts r=%d g=%d b=%d"
                    223:                        ", tlosses r=%d g=%d b=%d\n",
                    224:                        surf->format->BitsPerPixel,
                    225:                        surf->format->Rmask, surf->format->Gmask, surf->format->Bmask,
                    226:                        surf->format->Rshift, surf->format->Gshift, surf->format->Bshift,
                    227:                        surf->format->Rloss, surf->format->Gloss, surf->format->Bloss));
1.1.1.5 ! root      228: 
        !           229:        Main_WarpMouse(sdlscrn->w/2,sdlscrn->h/2);
1.1       root      230: }
                    231: 
                    232: 
1.1.1.2   root      233: static void HostScreen_update5(Sint32 x, Sint32 y, Sint32 w, Sint32 h, bool forced)
1.1       root      234: {
                    235:        if ( !forced && !doUpdate ) // the HW surface is available
                    236:                return;
                    237: 
                    238:        SDL_UpdateRect(mainSurface, x, y, w, h);
                    239: }
                    240: 
1.1.1.2   root      241: void HostScreen_update1(bool forced)
1.1       root      242: {
                    243:        HostScreen_update5( 0, 0, hs_width, hs_height, forced );
                    244: }
                    245: 
                    246: 
1.1.1.4   root      247: Uint32 HostScreen_getBpp(void)
1.1       root      248: {
                    249:        return surf->format->BytesPerPixel;
                    250: }
                    251: 
1.1.1.4   root      252: Uint32 HostScreen_getPitch(void)
                    253: {
1.1       root      254:        return surf->pitch;
                    255: }
                    256: 
1.1.1.4   root      257: Uint32 HostScreen_getWidth(void)
                    258: {
1.1       root      259:        return hs_width;
                    260: }
                    261: 
1.1.1.4   root      262: Uint32 HostScreen_getHeight(void)
                    263: {
1.1       root      264:        return hs_height;
                    265: }
                    266: 
1.1.1.4   root      267: Uint8 *HostScreen_getVideoramAddress(void)
                    268: {
1.1       root      269:        return surf->pixels;    /* FIXME maybe this should be mainSurface? */
                    270: }
                    271: 
1.1.1.4   root      272: void HostScreen_setPaletteColor(Uint8 idx, Uint32 red, Uint32 green, Uint32 blue)
                    273: {
1.1       root      274:        // set the SDL standard RGB palette settings
                    275:        palette.standard[idx].r = red;
                    276:        palette.standard[idx].g = green;
                    277:        palette.standard[idx].b = blue;
                    278:        // convert the color to native
                    279:        palette.native[idx] = SDL_MapRGB( surf->format, red, green, blue );
                    280: }
                    281: 
1.1.1.4   root      282: Uint32 HostScreen_getPaletteColor(Uint8 idx)
                    283: {
1.1       root      284:        return palette.native[idx];
                    285: }
                    286: 
1.1.1.4   root      287: void HostScreen_updatePalette(Uint16 colorCount)
                    288: {
1.1       root      289:        SDL_SetColors( surf, palette.standard, 0, colorCount );
                    290: }
                    291: 
1.1.1.4   root      292: Uint32 HostScreen_getColor(Uint32 red, Uint32 green, Uint32 blue)
                    293: {
1.1       root      294:        return SDL_MapRGB( surf->format, red, green, blue );
                    295: }
                    296: 
                    297: 
1.1.1.2   root      298: bool HostScreen_renderBegin(void)
                    299: {
1.1       root      300:        if (SDL_MUSTLOCK(surf))
                    301:                if (SDL_LockSurface(surf) < 0) {
                    302:                        printf("Couldn't lock surface to refresh!\n");
1.1.1.4   root      303:                        return false;
1.1       root      304:                }
                    305: 
1.1.1.4   root      306:        return true;
1.1       root      307: }
                    308: 
1.1.1.4   root      309: void HostScreen_renderEnd(void)
                    310: {
1.1       root      311:        if (SDL_MUSTLOCK(surf))
                    312:                SDL_UnlockSurface(surf);
1.1.1.2   root      313:        Statusbar_Update(surf);
1.1       root      314: }

unix.superglobalmegacorp.com

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