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

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: */
                     11: const char HostScreen_rcsid[] = "Hatari $Id: hostscreen.c,v 1.13 2007/04/04 15:23:58 thothy Exp $";
                     12: 
                     13: #include "main.h"
                     14: #include "configuration.h"
                     15: #include "sysdeps.h"
                     16: #include "stMemory.h"
                     17: #include "ioMem.h"
                     18: #include "hostscreen.h"
                     19: #include "screen.h"
                     20: 
                     21: #define VIDEL_DEBUG 0
                     22: 
                     23: #if VIDEL_DEBUG
                     24: #define Dprintf(a) printf a
                     25: #else
                     26: #define Dprintf(a)
                     27: #endif
                     28: 
                     29: 
                     30: #define RGB_BLACK     0x00000000
                     31: #define RGB_BLUE      0x000000ff
                     32: #define RGB_GREEN     0x00ff0000
                     33: #define RGB_CYAN      0x00ff00ff
                     34: #define RGB_RED       0xff000000
                     35: #define RGB_MAGENTA   0xff0000ff
                     36: #define RGB_LTGRAY    0xbbbb00bb
                     37: #define RGB_GRAY      0x88880088
                     38: #define RGB_LTBLUE    0x000000aa
                     39: #define RGB_LTGREEN   0x00aa0000
                     40: #define RGB_LTCYAN    0x00aa00aa
                     41: #define RGB_LTRED     0xaa000000
                     42: #define RGB_LTMAGENTA 0xaa0000aa
                     43: #define RGB_YELLOW    0xffff0000
                     44: #define RGB_LTYELLOW  0xaaaa0000
                     45: #define RGB_WHITE     0xffff00ff
                     46: 
                     47: 
                     48: static SDL_Surface *mainSurface;        // The main window surface
                     49: static SDL_Surface *surf;               // pointer to actual surface
                     50: 
                     51: 
                     52: static SDL_mutex   *screenLock;
                     53: static uint32 sdl_videoparams;
                     54: static uint32 hs_width, hs_height, hs_bpp;
                     55: static BOOL   doUpdate; // the HW surface is available -> the SDL need not to update the surface after ->pixel access
                     56: 
                     57: static struct { // TOS palette (bpp < 16) to SDL color mapping
                     58:        SDL_Color       standard[256];
                     59:        uint32          native[256];
                     60: } palette;
                     61: 
                     62: 
                     63: static const unsigned long default_palette[] = {
                     64:     RGB_WHITE, RGB_RED, RGB_GREEN, RGB_YELLOW,
                     65:     RGB_BLUE, RGB_MAGENTA, RGB_CYAN, RGB_LTGRAY,
                     66:     RGB_GRAY, RGB_LTRED, RGB_LTGREEN, RGB_LTYELLOW,
                     67:     RGB_LTBLUE, RGB_LTMAGENTA, RGB_LTCYAN, RGB_BLACK
                     68: };
                     69: 
                     70: static int HostScreen_selectVideoMode(SDL_Rect **modes, uint32 *width, uint32 *height);
                     71: static void HostScreen_searchVideoMode( uint32 *width, uint32 *height, uint32 *bpp );
                     72: 
                     73: 
                     74: void HostScreen_Init(void) {
                     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:        screenLock = SDL_CreateMutex();
                     84: 
                     85:        mainSurface=NULL;
                     86: }
                     87: 
                     88: void HostScreen_UnInit(void) {
                     89:        SDL_DestroyMutex(screenLock);
                     90: }
                     91: 
                     92: 
                     93: void HostScreen_toggleFullScreen(void)
                     94: {
                     95:        sdl_videoparams ^= SDL_FULLSCREEN;
                     96:        if(SDL_WM_ToggleFullScreen(mainSurface) == 0) {
                     97:                // SDL_WM_ToggleFullScreen() did not work.
                     98:                // We have to change video mode "by hand".
                     99:                SDL_Surface *temp = SDL_ConvertSurface(mainSurface, mainSurface->format,
                    100:                                                       mainSurface->flags);
                    101:                Dprintf(("toggleFullScreen: SDL_WM_ToggleFullScreen() not supported"
                    102:                         " -> using SDL_SetVideoMode()"));
                    103:                if (temp == NULL)
                    104:                        bug("toggleFullScreen: Unable to save screen content.");
                    105: 
                    106: #if 1
                    107:                HostScreen_setWindowSize(hs_width, hs_height, hs_bpp);
                    108: #else
                    109:                mainSurface = SDL_SetVideoMode(width, height, bpp, sdl_videoparams);
                    110:                if (mainSurface == NULL)
                    111:                        bug("toggleFullScreen: Unable to set new video mode.");
                    112:                if (mainSurface->format->BitsPerPixel <= 8)
                    113:                        SDL_SetColors(mainSurface, temp->format->palette->colors, 0,
                    114:                                      temp->format->palette->ncolors);
                    115: #endif
                    116: 
                    117:                if (SDL_BlitSurface(temp, NULL, mainSurface, NULL) != 0)
                    118:                        bug("toggleFullScreen: Unable to restore screen content.");
                    119:                SDL_FreeSurface(temp);
                    120: 
                    121:                /* refresh the screen */
                    122:                HostScreen_update1(TRUE);
                    123:        }
                    124: }
                    125: 
                    126: static int HostScreen_selectVideoMode(SDL_Rect **modes, uint32 *width, uint32 *height)
                    127: {
                    128:        int i, bestw, besth;
                    129: 
                    130:        /* Search the smallest nearest mode */
                    131:        bestw = modes[0]->w;
                    132:        besth = modes[0]->h;
                    133:        for (i=0;modes[i]; ++i) {
                    134:                if ((modes[i]->w >= *width) && (modes[i]->h >= *height)) {
                    135:                        if ((modes[i]->w < bestw) || (modes[i]->h < besth)) {
                    136:                                bestw = modes[i]->w;
                    137:                                besth = modes[i]->h;
                    138:                        }                       
                    139:                }
                    140:        }
                    141: 
                    142:        *width = bestw;
                    143:        *height = besth;
                    144:        Dprintf(("hostscreen: video mode found: %dx%d\n",*width,*height));
                    145: 
                    146:        return 1;
                    147: }
                    148: 
                    149: static void HostScreen_searchVideoMode( uint32 *width, uint32 *height, uint32 *bpp )
                    150: {
                    151:        SDL_Rect **modes;
                    152:        SDL_PixelFormat pixelformat;
                    153:        int modeflags;
                    154: 
                    155:        /* Search in available modes the best suited */
                    156:        Dprintf(("hostscreen: video mode asked: %dx%dx%d\n",*width,*height,*bpp));
                    157: 
                    158:        if ((*width == 0) || (*height == 0)) {
                    159:                *width = 640;
                    160:                *height = 480;
                    161:        }
                    162: 
                    163:        /* Read available video modes */
                    164:        modeflags = 0 /*SDL_HWSURFACE | SDL_HWPALETTE*/;
                    165:        if (bInFullScreen)
                    166:                modeflags |= SDL_FULLSCREEN;
                    167: 
                    168:        /*--- Search a video mode with asked bpp ---*/
                    169:        if (*bpp != 0) {
                    170:                pixelformat.BitsPerPixel = *bpp;
                    171:                modes = SDL_ListModes(&pixelformat, modeflags);
                    172:                if ((modes != (SDL_Rect **) 0) && (modes != (SDL_Rect **) -1)) {
                    173:                        Dprintf(("hostscreen: searching a good video mode (any bpp)\n"));
                    174:                        if (HostScreen_selectVideoMode(modes,width,height)) {
                    175:                                Dprintf(("hostscreen: video mode selected: %dx%dx%d\n",*width,*height,*bpp));
                    176:                                return;
                    177:                        }
                    178:                }
                    179:        }
                    180: 
                    181:        /*--- Search a video mode with any bpp ---*/
                    182:        modes = SDL_ListModes(NULL, modeflags);
                    183:        if ((modes != (SDL_Rect **) 0) && (modes != (SDL_Rect **) -1)) {
                    184:                Dprintf(("hostscreen: searching a good video mode\n"));
                    185:                if (HostScreen_selectVideoMode(modes,width,height)) {
                    186:                        Dprintf(("hostscreen: video mode selected: %dx%dx%d\n",*width,*height,*bpp));
                    187:                        return;
                    188:                }
                    189:        }
                    190: 
                    191:        if (modes == (SDL_Rect **) 0) {
                    192:                Dprintf(("hostscreen: No modes available\n"));
                    193:        }
                    194: 
                    195:        if (modes == (SDL_Rect **) -1) {
                    196:                /* Any mode available */
                    197:                Dprintf(("hostscreen: Any modes available\n"));
                    198:        }
                    199: 
                    200:        Dprintf(("hostscreen: video mode selected: %dx%dx%d\n",*width,*height,*bpp));
                    201: }
                    202: 
                    203: void HostScreen_setWindowSize( uint32 width, uint32 height, uint32 bpp )
                    204: {
                    205:        nScreenZoomX = 1;
                    206:        nScreenZoomY = 1;
                    207:        if (ConfigureParams.Screen.bZoomLowRes)
                    208:        {
                    209:                /* Ugly: 400x300 threshold is currently hard-coded. */
                    210:                /* Should rather be selectable by the user! */  
                    211:                if (width <= 400)
                    212:                {
                    213:                        nScreenZoomX = (800/width);
                    214:                        width *= nScreenZoomX; 
                    215:                }
                    216:                if (height <= 300)
                    217:                {
                    218:                        nScreenZoomY = (550/height);
                    219:                        height *= nScreenZoomY;
                    220:                }
                    221:        }
                    222: 
                    223:        // Select a correct video mode
                    224:        HostScreen_searchVideoMode(&width, &height, &bpp);      
                    225: 
                    226:        hs_width         = width;
                    227:        hs_height = height;
                    228:        hs_bpp = bpp;
                    229: 
                    230:        // SelectVideoMode();
                    231:        if (bInFullScreen)
                    232:                sdl_videoparams = SDL_SWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN;
                    233:        else
                    234:                sdl_videoparams = SDL_SWSURFACE|SDL_HWPALETTE;
                    235: 
                    236:        mainSurface = SDL_SetVideoMode(width, height, bpp, sdl_videoparams);
                    237: 
                    238:        sdlscrn = surf = mainSurface;
                    239: 
                    240:        // update the surface's palette
                    241:        HostScreen_updatePalette( 256 );
                    242: 
                    243:        Dprintf(("Surface Pitch = %d, width = %d, height = %d\n", surf->pitch, surf->w, surf->h));
                    244:        Dprintf(("Must Lock? %s\n", SDL_MUSTLOCK(surf) ? "YES" : "NO"));
                    245: 
                    246:        // is the SDL_update needed?
                    247:        doUpdate = ( surf->flags & SDL_HWSURFACE ) == 0;
                    248: 
                    249:        HostScreen_renderBegin();
                    250: 
                    251: //     VideoRAMBaseHost = (uint8 *) surf->pixels;
                    252: //     InitVMEMBaseDiff(VideoRAMBaseHost, VideoRAMBase);
                    253: //     Dprintf(("VideoRAM starts at %p (%08x)\n", VideoRAMBaseHost, VideoRAMBase));
                    254:        Dprintf(("surf->pixels = %p, getVideoSurface() = %p\n",
                    255:                        surf->pixels, SDL_GetVideoSurface()->pixels));
                    256: 
                    257:        HostScreen_renderEnd();
                    258: 
                    259:        Dprintf(("Pixel format:bitspp=%d, tmasks r=%04x g=%04x b=%04x"
                    260:                        ", tshifts r=%d g=%d b=%d"
                    261:                        ", tlosses r=%d g=%d b=%d\n",
                    262:                        surf->format->BitsPerPixel,
                    263:                        surf->format->Rmask, surf->format->Gmask, surf->format->Bmask,
                    264:                        surf->format->Rshift, surf->format->Gshift, surf->format->Bshift,
                    265:                        surf->format->Rloss, surf->format->Gloss, surf->format->Bloss));
                    266: }
                    267: 
                    268: 
                    269: static void HostScreen_update5( int32 x, int32 y, int32 w, int32 h, BOOL forced )
                    270: {
                    271:        if ( !forced && !doUpdate ) // the HW surface is available
                    272:                return;
                    273: 
                    274:        //      SDL_UpdateRect(SDL_GetVideoSurface(), 0, 0, width, height);
                    275:        // SDL_UpdateRect(surf, x, y, w, h);
                    276:        SDL_UpdateRect(mainSurface, x, y, w, h);
                    277: }
                    278: 
                    279: void HostScreen_update1( BOOL forced )
                    280: {
                    281:        HostScreen_update5( 0, 0, hs_width, hs_height, forced );
                    282: }
                    283: 
                    284: void HostScreen_update0()
                    285: {
                    286:        HostScreen_update5( 0, 0, hs_width, hs_height, FALSE );
                    287: }
                    288: 
                    289: 
                    290: uint32 HostScreen_getBitsPerPixel(void)
                    291: {
                    292:        return surf->format->BitsPerPixel;
                    293: }
                    294: 
                    295: 
                    296: #if 0
                    297: void HostScreen_gfxFastPixelColorNolock(int16 x, int16 y, uint32 color)
                    298: {
                    299:        int bpp;
                    300:        uint8 *p;
                    301: 
                    302:        /* Get destination format */
                    303:        bpp = surf->format->BytesPerPixel;
                    304:        p = (uint8 *)surf->pixels + y * surf->pitch + x * bpp;
                    305:        switch(bpp) {
                    306:                case 1:
                    307:                        *p = color;
                    308:                        break;
                    309:                case 2:
                    310:                        *(uint16 *)p = color;
                    311:                        break;
                    312:                case 3:
                    313:                        putBpp24Pixel( p, color );
                    314:                        break;
                    315:                case 4:
                    316:                        *(uint32 *)p = color;
                    317:                        break;
                    318:        } /* switch */
                    319: }
                    320: #endif
                    321: 
                    322: #if 0
                    323: uint32 HostScreen_gfxGetPixel( int16 x, int16 y )
                    324: {
                    325:        int bpp;
                    326:        uint8 *p;
                    327: 
                    328:        /* Get destination format */
                    329:        bpp = surf->format->BytesPerPixel;
                    330:        p = (uint8 *)surf->pixels + y * surf->pitch + x * bpp;
                    331:        switch(bpp) {
                    332:                case 1:
                    333:                        return (uint32)(*(uint8 *)p);
                    334:                case 2:
                    335:                        return (uint32)(*(uint16 *)p);
                    336:                case 3:
                    337:                        // FIXME maybe some & problems? and endian
                    338:                        return getBpp24Pixel( p );
                    339:                case 4:
                    340:                        return *(uint32 *)p;
                    341:        } /* switch */
                    342:        return 0;       // should never happen
                    343: }
                    344: #endif
                    345: 
                    346: uint32 HostScreen_getBpp()
                    347: {
                    348:        return surf->format->BytesPerPixel;
                    349: }
                    350: 
                    351: uint32 HostScreen_getPitch() {
                    352:        return surf->pitch;
                    353: }
                    354: 
                    355: uint32 HostScreen_getWidth() {
                    356:        return hs_width;
                    357: }
                    358: 
                    359: uint32 HostScreen_getHeight() {
                    360:        return hs_height;
                    361: }
                    362: 
                    363: uint8 *HostScreen_getVideoramAddress() {
                    364:        return surf->pixels;    /* FIXME maybe this should be mainSurface? */
                    365: }
                    366: 
                    367: void HostScreen_setPaletteColor( uint8 idx, uint32 red, uint32 green, uint32 blue ) {
                    368:        // set the SDL standard RGB palette settings
                    369:        palette.standard[idx].r = red;
                    370:        palette.standard[idx].g = green;
                    371:        palette.standard[idx].b = blue;
                    372:        // convert the color to native
                    373:        palette.native[idx] = SDL_MapRGB( surf->format, red, green, blue );
                    374: }
                    375: 
                    376: uint32 HostScreen_getPaletteColor( uint8 idx ) {
                    377:        return palette.native[idx];
                    378: }
                    379: 
                    380: void HostScreen_updatePalette( uint16 colorCount ) {
                    381:        SDL_SetColors( surf, palette.standard, 0, colorCount );
                    382: }
                    383: 
                    384: uint32 HostScreen_getColor( uint32 red, uint32 green, uint32 blue ) {
                    385:        return SDL_MapRGB( surf->format, red, green, blue );
                    386: }
                    387: 
                    388: #if 0
                    389: void HostScreen_lock(void) {
                    390:        while (SDL_mutexP(screenLock)==-1) {
                    391:                SDL_Delay(20);
                    392:                fprintf(stderr, "Couldn't lock mutex\n");
                    393:        }
                    394: }
                    395: 
                    396: void HostScreen_unlock(void) {
                    397:        while (SDL_mutexV(screenLock)==-1) {
                    398:                SDL_Delay(20);
                    399:                fprintf(stderr, "Couldn't unlock mutex\n");
                    400:        }
                    401: }
                    402: #endif
                    403: 
                    404: BOOL HostScreen_renderBegin(void) {
                    405:        if (SDL_MUSTLOCK(surf))
                    406:                if (SDL_LockSurface(surf) < 0) {
                    407:                        printf("Couldn't lock surface to refresh!\n");
                    408:                        return FALSE;
                    409:                }
                    410: 
                    411:        return TRUE;
                    412: }
                    413: 
                    414: void HostScreen_renderEnd() {
                    415:        if (SDL_MUSTLOCK(surf))
                    416:                SDL_UnlockSurface(surf);
                    417: }
                    418: 
                    419: 
                    420: 
                    421: /**
                    422:  * Performs conversion from the TOS's bitplane word order (big endian) data
                    423:  * into the native chunky color index.
                    424:  */
                    425: void HostScreen_bitplaneToChunky( uint16 *atariBitplaneData, uint16 bpp, uint8 colorValues[16] )
                    426: {
                    427:        uint32 a, b, c, d, x;
                    428: 
                    429:        /* Obviously the different cases can be broken out in various
                    430:         * ways to lessen the amount of work needed for <8 bit modes.
                    431:         * It's doubtful if the usage of those modes warrants it, though.
                    432:         * The branches below should be ~100% correctly predicted and
                    433:         * thus be more or less for free.
                    434:         * Getting the palette values inline does not seem to help
                    435:         * enough to worry about. The palette lookup is much slower than
                    436:         * this code, though, so it would be nice to do something about it.
                    437:         */
                    438:        if (bpp >= 4) {
                    439:                d = *(uint32 *)&atariBitplaneData[0];
                    440:                c = *(uint32 *)&atariBitplaneData[2];
                    441:                if (bpp == 4) {
                    442:                        a = b = 0;
                    443:                } else {
                    444:                        b = *(uint32 *)&atariBitplaneData[4];
                    445:                        a = *(uint32 *)&atariBitplaneData[6];
                    446:                }
                    447:        } else {
                    448:                a = b = c = 0;
                    449:                if (bpp == 2) {
                    450:                        d = *(uint32 *)&atariBitplaneData[0];
                    451:                } else {
                    452: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
                    453:                        d = atariBitplaneData[0]<<16;
                    454: #else
                    455:                        d = atariBitplaneData[0];
                    456: #endif
                    457:                }
                    458:        }
                    459: 
                    460:        x = a;
                    461:        a =  (a & 0xf0f0f0f0)       | ((c & 0xf0f0f0f0) >> 4);
                    462:        c = ((x & 0x0f0f0f0f) << 4) |  (c & 0x0f0f0f0f);
                    463:        x = b;
                    464:        b =  (b & 0xf0f0f0f0)       | ((d & 0xf0f0f0f0) >> 4);
                    465:        d = ((x & 0x0f0f0f0f) << 4) |  (d & 0x0f0f0f0f);
                    466: 
                    467:        x = a;
                    468:        a =  (a & 0xcccccccc)       | ((b & 0xcccccccc) >> 2);
                    469:        b = ((x & 0x33333333) << 2) |  (b & 0x33333333);
                    470:        x = c;
                    471:        c =  (c & 0xcccccccc)       | ((d & 0xcccccccc) >> 2);
                    472:        d = ((x & 0x33333333) << 2) |  (d & 0x33333333);
                    473: 
                    474: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
                    475:        a = (a & 0x5555aaaa) | ((a & 0x00005555) << 17) | ((a & 0xaaaa0000) >> 17);
                    476:        b = (b & 0x5555aaaa) | ((b & 0x00005555) << 17) | ((b & 0xaaaa0000) >> 17);
                    477:        c = (c & 0x5555aaaa) | ((c & 0x00005555) << 17) | ((c & 0xaaaa0000) >> 17);
                    478:        d = (d & 0x5555aaaa) | ((d & 0x00005555) << 17) | ((d & 0xaaaa0000) >> 17);
                    479:        
                    480:        colorValues[ 8] = a;
                    481:        a >>= 8;
                    482:        colorValues[ 0] = a;
                    483:        a >>= 8;
                    484:        colorValues[ 9] = a;
                    485:        a >>= 8;
                    486:        colorValues[ 1] = a;
                    487:        
                    488:        colorValues[10] = b;
                    489:        b >>= 8;
                    490:        colorValues[ 2] = b;
                    491:        b >>= 8;
                    492:        colorValues[11] = b;
                    493:        b >>= 8;
                    494:        colorValues[ 3] = b;
                    495:        
                    496:        colorValues[12] = c;
                    497:        c >>= 8;
                    498:        colorValues[ 4] = c;
                    499:        c >>= 8;
                    500:        colorValues[13] = c;
                    501:        c >>= 8;
                    502:        colorValues[ 5] = c;
                    503:        
                    504:        colorValues[14] = d;
                    505:        d >>= 8;
                    506:        colorValues[ 6] = d;
                    507:        d >>= 8;
                    508:        colorValues[15] = d;
                    509:        d >>= 8;
                    510:        colorValues[ 7] = d;
                    511: #else
                    512:        a = (a & 0xaaaa5555) | ((a & 0x0000aaaa) << 15) | ((a & 0x55550000) >> 15);
                    513:        b = (b & 0xaaaa5555) | ((b & 0x0000aaaa) << 15) | ((b & 0x55550000) >> 15);
                    514:        c = (c & 0xaaaa5555) | ((c & 0x0000aaaa) << 15) | ((c & 0x55550000) >> 15);
                    515:        d = (d & 0xaaaa5555) | ((d & 0x0000aaaa) << 15) | ((d & 0x55550000) >> 15);
                    516: 
                    517:        colorValues[ 1] = a;
                    518:        a >>= 8;
                    519:        colorValues[ 9] = a;
                    520:        a >>= 8;
                    521:        colorValues[ 0] = a;
                    522:        a >>= 8;
                    523:        colorValues[ 8] = a;
                    524: 
                    525:        colorValues[ 3] = b;
                    526:        b >>= 8;
                    527:        colorValues[11] = b;
                    528:        b >>= 8;
                    529:        colorValues[ 2] = b;
                    530:        b >>= 8;
                    531:        colorValues[10] = b;
                    532: 
                    533:        colorValues[ 5] = c;
                    534:        c >>= 8;
                    535:        colorValues[13] = c;
                    536:        c >>= 8;
                    537:        colorValues[ 4] = c;
                    538:        c >>= 8;
                    539:        colorValues[12] = c;
                    540: 
                    541:        colorValues[ 7] = d;
                    542:        d >>= 8;
                    543:        colorValues[15] = d;
                    544:        d >>= 8;
                    545:        colorValues[ 6] = d;
                    546:        d >>= 8;
                    547:        colorValues[14] = d;
                    548: #endif
                    549: }

unix.superglobalmegacorp.com

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