Annotation of hatari/src/screen.c, revision 1.1.1.23

1.1       root        1: /*
1.1.1.6   root        2:   Hatari - screen.c
1.1       root        3: 
1.1.1.21  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.1.6   root        6: 
1.1.1.17  root        7:   This code converts a 1/2/4 plane ST format screen to either 8, 16 or 32-bit PC
1.1.1.11  root        8:   format. An awful lot of processing is needed to do this conversion - we
1.1.1.6   root        9:   cannot simply change palettes on  interrupts as it is possible with DOS.
                     10:   The main code processes the palette/resolution mask tables to find exactly
                     11:   which lines need to updating and the conversion routines themselves only
                     12:   update 16-pixel blocks which differ from the previous frame - this gives a
                     13:   large performance increase.
                     14:   Each conversion routine can convert any part of the source ST screen (which
                     15:   includes the overscan border, usually set to colour zero) so they can be used
                     16:   for both window and full-screen mode.
                     17:   Note that in Hi-Resolution we have no overscan and just two colors so we can
1.1.1.17  root       18:   optimise things further.
                     19:   In color mode it seems possible to display 47 lines in the bottom border
                     20:   with a second 60/50 Hz switch, but most programs consider there are 45
                     21:   visible lines in the bottom border only, which gives a total of 274 lines
                     22:   for a screen. So not displaying the last two lines fixes garbage that could
                     23:   appear in the last two lines when displaying 47 lines (Digiworld 2 by ICE,
                     24:   Tyranny by DHS).
1.1       root       25: */
1.1.1.15  root       26: 
1.1.1.17  root       27: const char Screen_fileid[] = "Hatari screen.c : " __DATE__ " " __TIME__;
1.1       root       28: 
                     29: #include <SDL.h>
1.1.1.11  root       30: #include <SDL_endian.h>
1.1       root       31: 
                     32: #include "main.h"
1.1.1.7   root       33: #include "configuration.h"
1.1.1.23! root       34: #include "avi_record.h"
1.1       root       35: #include "ikbd.h"
1.1.1.13  root       36: #include "log.h"
1.1       root       37: #include "m68000.h"
1.1.1.13  root       38: #include "paths.h"
1.1.1.23! root       39: #include "options.h"
1.1       root       40: #include "screen.h"
1.1.1.15  root       41: #include "control.h"
1.1.1.11  root       42: #include "convert/routines.h"
1.1.1.18  root       43: #include "resolution.h"
1.1       root       44: #include "sound.h"
                     45: #include "spec512.h"
1.1.1.15  root       46: #include "statusbar.h"
1.1       root       47: #include "vdi.h"
                     48: #include "video.h"
1.1.1.13  root       49: #include "falcon/videl.h"
                     50: #include "falcon/hostscreen.h"
1.1       root       51: 
1.1.1.22  root       52: #define DEBUG 0
                     53: 
                     54: #if DEBUG
                     55: # define DEBUGPRINT(x) printf x
                     56: #else
                     57: # define DEBUGPRINT(x)
                     58: #endif
1.1       root       59: 
1.1.1.13  root       60: /* extern for several purposes */
                     61: SDL_Surface *sdlscrn = NULL;                /* The SDL screen surface */
                     62: int nScreenZoomX, nScreenZoomY;             /* Zooming factors, used for scaling mouse motions */
                     63: int nBorderPixelsLeft, nBorderPixelsRight;  /* Pixels in left and right border */
1.1.1.23! root       64: static int nBorderPixelsTop, nBorderPixelsBottom;  /* Lines in top and bottom border */
1.1.1.13  root       65: 
                     66: /* extern for shortcuts and falcon/hostscreen.c */
1.1.1.17  root       67: bool bGrabMouse = false;      /* Grab the mouse cursor in the window */
                     68: bool bInFullScreen = false;   /* true if in full screen */
1.1.1.13  root       69: 
                     70: /* extern for spec512.c */
1.1.1.11  root       71: int STScreenLeftSkipBytes;
                     72: int STScreenStartHorizLine;   /* Start lines to be converted */
                     73: Uint32 STRGBPalette[16];      /* Palette buffer used in conversion routines */
                     74: Uint32 ST2RGB[4096];          /* Table to convert ST 0x777 / STe 0xfff palette to PC format RGB551 (2 pixels each entry) */
1.1.1.13  root       75: 
                     76: /* extern for video.c */
1.1.1.11  root       77: Uint8 *pSTScreen;
                     78: FRAMEBUFFER *pFrameBuffer;    /* Pointer into current 'FrameBuffer' */
                     79: 
                     80: static FRAMEBUFFER FrameBuffers[NUM_FRAMEBUFFERS]; /* Store frame buffer details to tell how to update */
                     81: static Uint8 *pSTScreenCopy;                       /* Keep track of current and previous ST screen data */
                     82: static Uint8 *pPCScreenDest;                       /* Destination PC buffer */
                     83: static int STScreenEndHorizLine;                   /* End lines to be converted */
                     84: static int PCScreenBytesPerLine;
                     85: static int STScreenWidthBytes;
1.1.1.20  root       86: static int PCScreenOffsetX;                        /* how many pixels to skip from left when drawing */
                     87: static int PCScreenOffsetY;                        /* how many pixels to skip from top when drawing */
1.1.1.15  root       88: static SDL_Rect STScreenRect;                      /* screen size without statusbar */
1.1       root       89: 
1.1.1.11  root       90: static int STScreenLineOffset[NUM_VISIBLE_LINES];  /* Offsets for ST screen lines eg, 0,160,320... */
                     91: static Uint16 HBLPalette[16], PrevHBLPalette[16];  /* Current palette for line, also copy of first line */
1.1       root       92: 
1.1.1.13  root       93: static void (*ScreenDrawFunctionsNormal[3])(void); /* Screen draw functions */
1.1.1.12  root       94: static void (*ScreenDrawFunctionsVDI[3])(void) =
1.1.1.10  root       95: {
1.1.1.13  root       96:        ConvertVDIRes_16Colour,
                     97:        ConvertVDIRes_4Colour,
                     98:        ConvertVDIRes_2Colour
1.1.1.10  root       99: };
                    100: 
1.1.1.17  root      101: static bool bScreenContentsChanged;     /* true if buffer changed and requires blitting */
                    102: static bool bScrDoubleY;                /* true if double on Y */
1.1.1.11  root      103: static int ScrUpdateFlag;               /* Bit mask of how to update screen */
                    104: 
1.1.1.10  root      105: 
1.1.1.18  root      106: static bool Screen_DrawFrame(bool bForceFlip);
                    107: 
1.1.1.23! root      108: #if WITH_SDL2
        !           109: 
        !           110: SDL_Window *sdlWindow;
        !           111: static SDL_Renderer *sdlRenderer;
        !           112: static SDL_Texture *sdlTexture;
        !           113: 
        !           114: void SDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects)
        !           115: {
        !           116:        if (sdlscrn->format->BitsPerPixel == 8)
        !           117:        {
        !           118:                sdlTexture = SDL_CreateTextureFromSurface(sdlRenderer, screen);
        !           119:        }
        !           120:        else
        !           121:        {
        !           122:                SDL_UpdateTexture(sdlTexture, NULL, screen->pixels, screen->pitch);
        !           123:        }
        !           124: 
        !           125:        SDL_RenderClear(sdlRenderer);
        !           126:        SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL);
        !           127:        SDL_RenderPresent(sdlRenderer);
        !           128: 
        !           129:        if (sdlscrn->format->BitsPerPixel == 8)
        !           130:        {
        !           131:                SDL_DestroyTexture(sdlTexture);
        !           132:                sdlTexture = NULL;
        !           133:        }
        !           134: }
        !           135: 
        !           136: void SDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Sint32 w, Sint32 h)
        !           137: {
        !           138:        SDL_Rect rect = { x, y, w, h };
        !           139:        SDL_UpdateRects(screen, 1, &rect);
        !           140: }
        !           141: 
        !           142: #endif
1.1.1.18  root      143: 
1.1.1.10  root      144: /*-----------------------------------------------------------------------*/
1.1.1.13  root      145: /**
                    146:  * Create ST 0x777 / STe 0xfff color format to 16 or 32 bits per pixel
                    147:  * conversion table. Called each time when changed resolution or to/from
                    148:  * fullscreen mode.
                    149:  */
1.1.1.10  root      150: static void Screen_SetupRGBTable(void)
                    151: {
1.1.1.13  root      152:        Uint16 STColor;
                    153:        Uint32 RGBColor;
                    154:        int r, g, b;
                    155:        int rr, gg, bb;
                    156: 
                    157:        /* Do Red, Green and Blue for all 16*16*16 = 4096 STe colors */
                    158:        for (r = 0; r < 16; r++)
                    159:        {
                    160:                for (g = 0; g < 16; g++)
                    161:                {
                    162:                        for (b = 0; b < 16; b++)
                    163:                        {
                    164:                                /* STe 0xfff format */
                    165:                                STColor = (r<<8) | (g<<4) | (b);
1.1.1.20  root      166:                                rr = ((r & 0x7) << 1) | ((r & 0x8) >> 3);
                    167:                                rr |= rr << 4;
                    168:                                gg = ((g & 0x7) << 1) | ((g & 0x8) >> 3);
                    169:                                gg |= gg << 4;
                    170:                                bb = ((b & 0x7) << 1) | ((b & 0x8) >> 3);
                    171:                                bb |= bb << 4;
1.1.1.13  root      172:                                RGBColor = SDL_MapRGB(sdlscrn->format, rr, gg, bb);
                    173:                                if (sdlscrn->format->BitsPerPixel <= 16)
                    174:                                {
                    175:                                        /* As longs, for speed (write two pixels at once) */
                    176:                                        ST2RGB[STColor] = (RGBColor<<16) | RGBColor;
                    177:                                }
                    178:                                else
                    179:                                {
                    180:                                        ST2RGB[STColor] = RGBColor;
                    181:                                }
                    182:                        }
                    183:                }
                    184:        }
1.1.1.10  root      185: }
                    186: 
1.1.1.13  root      187: 
1.1.1.10  root      188: /*-----------------------------------------------------------------------*/
1.1.1.13  root      189: /**
                    190:  * Create new palette for display.
                    191:  */
1.1.1.10  root      192: static void Screen_CreatePalette(void)
                    193: {
                    194: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1.1.1.13  root      195:        static const int endiantable[16] = {0,2,1,3,8,10,9,11,4,6,5,7,12,14,13,15};
1.1.1.10  root      196: #endif
1.1.1.13  root      197:        SDL_Color sdlColors[16];
                    198:        int i, j;
1.1.1.10  root      199: 
1.1.1.13  root      200:        if (bUseHighRes)
                    201:        {
                    202:                /* Colors for monochrome screen mode emulation */
                    203:                if (HBLPalettes[0])
                    204:                {
                    205:                        sdlColors[0].r = sdlColors[0].g = sdlColors[0].b = 255;
                    206:                        sdlColors[1].r = sdlColors[1].g = sdlColors[1].b = 0;
                    207:                }
                    208:                else
                    209:                {
                    210:                        sdlColors[0].r = sdlColors[0].g = sdlColors[0].b = 0;
                    211:                        sdlColors[1].r = sdlColors[1].g = sdlColors[1].b = 255;
                    212:                }
                    213:                SDL_SetColors(sdlscrn, sdlColors, 10, 2);
                    214:                /*SDL_SetColors(sdlscrn, sdlColors, 0, 2);*/
                    215:        }
                    216:        else
                    217:        {
                    218:                int r, g, b;
                    219:                /* Colors for STe color screen mode emulation */
                    220:                for (i = 0; i < 16; i++)
                    221:                {
1.1.1.11  root      222: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1.1.1.13  root      223:                        j = endiantable[i];
1.1.1.11  root      224: #else
1.1.1.13  root      225:                        j = i;
1.1.1.11  root      226: #endif
1.1.1.13  root      227:                        /* normalize all to 0x1e0 */
                    228:                        r = HBLPalettes[i] >> 3;
                    229:                        g = HBLPalettes[i] << 1;
                    230:                        b = HBLPalettes[i] << 5;
                    231:                        /* move top bit of 0x1e0 to lowest in 0xf0 */
1.1.1.20  root      232:                        r = (r & 0xe0) | ((r & 0x100) >> 4);
                    233:                        g = (g & 0xe0) | ((g & 0x100) >> 4);
                    234:                        b = (b & 0xe0) | ((b & 0x100) >> 4);
                    235:                        /* Set color in table */
                    236:                        sdlColors[j].r = r | (r >> 4);
                    237:                        sdlColors[j].g = g | (g >> 4);
                    238:                        sdlColors[j].b = b | (b >> 4);
1.1.1.13  root      239:                }
                    240:                SDL_SetColors(sdlscrn, sdlColors, 10, 16);
                    241:        }
1.1.1.10  root      242: }
                    243: 
                    244: 
                    245: /*-----------------------------------------------------------------------*/
1.1.1.13  root      246: /**
                    247:  * Create 8-Bit palette for display if needed.
                    248:  */
1.1.1.10  root      249: static void Screen_Handle8BitPalettes(void)
                    250: {
1.1.1.17  root      251:        bool bPaletteChanged = false;
1.1.1.13  root      252:        int i;
1.1.1.10  root      253: 
1.1.1.13  root      254:        /* Do need to check for 8-Bit palette change? Ie, update whole screen */
                    255:        /* VDI screens and monochrome modes are ALL 8-Bit at the moment! */
                    256:        if (sdlscrn->format->BitsPerPixel == 8)
                    257:        {
                    258:                /* If using HiRes palette update with full update flag */
                    259:                if (!bUseHighRes)
                    260:                {
                    261:                        /* Check if palette of 16 colours changed from previous frame */
                    262:                        for (i = 0; i < 16 && !bPaletteChanged; i++)
                    263:                        {
                    264:                                /* Check with first line palette (stored in 'Screen_ComparePaletteMask') */
                    265:                                if (HBLPalettes[i] != PrevHBLPalette[i])
1.1.1.17  root      266:                                        bPaletteChanged = true;
1.1.1.13  root      267:                        }
                    268:                }
                    269: 
                    270:                /* Did palette change or do we require a full update? */
                    271:                if (bPaletteChanged || pFrameBuffer->bFullUpdate)
                    272:                {
                    273:                        /* Create palette, for Full-Screen of Window */
                    274:                        Screen_CreatePalette();
                    275:                        /* Make sure update whole screen */
1.1.1.17  root      276:                        pFrameBuffer->bFullUpdate = true;
1.1.1.13  root      277:                }
                    278:        }
1.1.1.10  root      279: 
1.1.1.13  root      280:        /* Copy old palette for 8-Bit compare as this routine writes over it */
                    281:        memcpy(PrevHBLPalette,HBLPalettes, sizeof(Uint16)*16);
1.1.1.10  root      282: }
                    283: 
1.1       root      284: 
                    285: /*-----------------------------------------------------------------------*/
1.1.1.13  root      286: /**
                    287:  * Set screen draw functions.
                    288:  */
1.1.1.18  root      289: static void Screen_SetDrawFunctions(int nBitCount, bool bDoubleLowRes)
1.1.1.10  root      290: {
1.1.1.14  root      291:        if (nBitCount == 8)
1.1.1.13  root      292:        {
                    293:                /* Low color */
1.1.1.18  root      294:                if (bDoubleLowRes)
1.1.1.13  root      295:                        ScreenDrawFunctionsNormal[ST_LOW_RES] = ConvertLowRes_640x8Bit;
                    296:                else
                    297:                        ScreenDrawFunctionsNormal[ST_LOW_RES] = ConvertLowRes_320x8Bit;
                    298:                ScreenDrawFunctionsNormal[ST_MEDIUM_RES] = ConvertMediumRes_640x8Bit;
                    299:                ScreenDrawFunctionsNormal[ST_HIGH_RES] = ConvertHighRes_640x8Bit;
                    300:        }
                    301:        else if (nBitCount <= 16)
                    302:        {
                    303:                /* High color */
1.1.1.18  root      304:                if (bDoubleLowRes)
1.1.1.13  root      305:                        ScreenDrawFunctionsNormal[ST_LOW_RES] = ConvertLowRes_640x16Bit;
                    306:                else
                    307:                        ScreenDrawFunctionsNormal[ST_LOW_RES] = ConvertLowRes_320x16Bit;
                    308:                ScreenDrawFunctionsNormal[ST_MEDIUM_RES] = ConvertMediumRes_640x16Bit;
                    309:                ScreenDrawFunctionsNormal[ST_HIGH_RES] = ConvertHighRes_640x8Bit;
                    310:        }
                    311:        else /* Assume 32 bit drawing functions */
                    312:        {
                    313:                /* True color */
1.1.1.18  root      314:                if (bDoubleLowRes)
1.1.1.13  root      315:                        ScreenDrawFunctionsNormal[ST_LOW_RES] = ConvertLowRes_640x32Bit;
                    316:                else
                    317:                        ScreenDrawFunctionsNormal[ST_LOW_RES] = ConvertLowRes_320x32Bit;
                    318:                ScreenDrawFunctionsNormal[ST_MEDIUM_RES] = ConvertMediumRes_640x32Bit;
                    319:                ScreenDrawFunctionsNormal[ST_HIGH_RES] = ConvertHighRes_640x8Bit;
                    320:        }
1.1.1.10  root      321: }
                    322: 
                    323: 
                    324: /*-----------------------------------------------------------------------*/
1.1.1.13  root      325: /**
1.1.1.18  root      326:  * Set amount of border pixels
1.1.1.13  root      327:  */
1.1.1.18  root      328: static void Screen_SetBorderPixels(int leftX, int leftY)
1.1.1.7   root      329: {
1.1.1.23! root      330:        /* All screen widths need to be aligned to 16-bits */
        !           331:        nBorderPixelsLeft = Opt_ValueAlignMinMax(leftX/2, 16, 0, 48);
1.1.1.18  root      332:        nBorderPixelsRight = nBorderPixelsLeft;
1.1.1.7   root      333: 
1.1.1.18  root      334:        /* assertain assumption of code below */
                    335:        assert(OVERSCAN_TOP < MAX_OVERSCAN_BOTTOM);
                    336:        
                    337:        if (leftY > 2*OVERSCAN_TOP)
1.1.1.13  root      338:        {
1.1.1.18  root      339:                nBorderPixelsTop = OVERSCAN_TOP;
                    340:                if (leftY >= OVERSCAN_TOP + MAX_OVERSCAN_BOTTOM)
                    341:                        nBorderPixelsBottom = MAX_OVERSCAN_BOTTOM;
                    342:                else
                    343:                        nBorderPixelsBottom = leftY - OVERSCAN_TOP;
1.1.1.13  root      344:        }
                    345:        else
                    346:        {
1.1.1.18  root      347:                if (leftY > 0)
                    348:                        nBorderPixelsTop = nBorderPixelsBottom = leftY/2;
                    349:                else
                    350:                        nBorderPixelsTop = nBorderPixelsBottom = 0;
1.1.1.13  root      351:        }
1.1.1.18  root      352: }
                    353: 
                    354: /*-----------------------------------------------------------------------*/
                    355: /**
                    356:  * store Y offset for each horizontal line in our source ST screen for
                    357:  * reference in the convert functions.
                    358:  */
                    359: static void Screen_SetSTScreenOffsets(void)
                    360: {
                    361:        int i;
1.1.1.13  root      362: 
1.1.1.18  root      363:        /* Store offset to each horizontal line, uses
                    364:         * nBorderPixels* variables.
                    365:         */
1.1.1.13  root      366:        for (i = 0; i < NUM_VISIBLE_LINES; i++)
                    367:        {
                    368:                STScreenLineOffset[i] = i * SCREENBYTES_LINE;
                    369:        }
1.1.1.7   root      370: }
                    371: 
1.1.1.23! root      372: #if WITH_SDL2
        !           373: static void Screen_FreeSDL2Resources(void)
        !           374: {
        !           375:        if (sdlTexture)
        !           376:        {
        !           377:                SDL_DestroyTexture(sdlTexture);
        !           378:                sdlTexture = NULL;
        !           379:        }
        !           380:        if (sdlscrn)
        !           381:        {
        !           382:                SDL_FreeSurface(sdlscrn);
        !           383:                sdlscrn = NULL;
        !           384:        }
        !           385:        if (sdlRenderer)
        !           386:        {
        !           387:                SDL_DestroyRenderer(sdlRenderer);
        !           388:                sdlRenderer = NULL;
        !           389:        }
        !           390:        if (sdlWindow)
        !           391:        {
        !           392:                SDL_DestroyWindow(sdlWindow);
        !           393:                sdlWindow = NULL;
        !           394:        }
        !           395: }
        !           396: #endif
        !           397: 
        !           398: /**
        !           399:  * Change the SDL video mode.
        !           400:  * @return true if mode has been changed, false if change was not necessary
        !           401:  */
        !           402: bool Screen_SetSDLVideoSize(int width, int height, int bitdepth, bool bForceChange)
        !           403: {
        !           404:        Uint32 sdlVideoFlags;
        !           405: #if WITH_SDL2
        !           406:        static int nPrevRenderScaleQuality = 0;
        !           407:        static bool bPrevUseVsync = false;
        !           408: 
        !           409:        if (bitdepth == 0 || bitdepth == 24)
        !           410:                bitdepth = 32;
        !           411: #endif
        !           412: 
        !           413:        /* Check if we really have to change the video mode: */
        !           414:        if (sdlscrn != NULL && sdlscrn->w == width && sdlscrn->h == height
        !           415:            && sdlscrn->format->BitsPerPixel == bitdepth && !bForceChange)
        !           416:                return false;
        !           417: 
        !           418:        /* We can not continue recording with a different resolution */
        !           419:        if (Avi_AreWeRecording())
        !           420:                Avi_StopRecording();
        !           421: 
        !           422: #ifdef _MUDFLAP
        !           423:        if (sdlscrn)
        !           424:        {
        !           425:                __mf_unregister(sdlscrn->pixels, sdlscrn->pitch*sdlscrn->h, __MF_TYPE_GUESS);
        !           426:        }
        !           427: #endif
        !           428:        if (bInFullScreen)
        !           429:        {
        !           430:                /* unhide the Hatari WM window for fullscreen */
        !           431:                Control_ReparentWindow(width, height, bInFullScreen);
        !           432:        }
        !           433: 
        !           434: #if WITH_SDL2
        !           435: 
        !           436:        /* SDL Video attributes: */
        !           437:        if (bInFullScreen)
        !           438:        {
        !           439:                sdlVideoFlags  = SDL_WINDOW_FULLSCREEN_DESKTOP;
        !           440:        }
        !           441:        else
        !           442:        {
        !           443:                sdlVideoFlags  = 0;
        !           444:        }
        !           445: 
        !           446:        Screen_FreeSDL2Resources();
        !           447: 
        !           448:        /* Set SDL2 video hints */
        !           449:        if (nPrevRenderScaleQuality != ConfigureParams.Screen.nRenderScaleQuality)
        !           450:        {
        !           451:                char hint[2] = { '0' + ConfigureParams.Screen.nRenderScaleQuality, 0 };
        !           452:                SDL_SetHintWithPriority(SDL_HINT_RENDER_SCALE_QUALITY, hint, SDL_HINT_OVERRIDE);
        !           453:                nPrevRenderScaleQuality = ConfigureParams.Screen.nRenderScaleQuality;
        !           454:        }
        !           455:        if (bPrevUseVsync != ConfigureParams.Screen.bUseVsync)
        !           456:        {
        !           457:                char hint[2] = { '0' + ConfigureParams.Screen.bUseVsync, 0 };
        !           458:                SDL_SetHintWithPriority(SDL_HINT_RENDER_VSYNC, hint, SDL_HINT_OVERRIDE);
        !           459:                bPrevUseVsync = ConfigureParams.Screen.bUseVsync;
        !           460:        }
        !           461: 
        !           462:        /* Set new video mode */
        !           463:        DEBUGPRINT(("SDL screen request: %d x %d @ %d (%s)\n", width, height,
        !           464:                bitdepth, bInFullScreen?"fullscreen":"windowed"));
        !           465: 
        !           466:        sdlWindow = SDL_CreateWindow("Hatari", SDL_WINDOWPOS_UNDEFINED,
        !           467:                                     SDL_WINDOWPOS_UNDEFINED, width, height,
        !           468:                                     sdlVideoFlags);
        !           469:        sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, 0);
        !           470:        if (!sdlWindow || !sdlRenderer)
        !           471:        {
        !           472:                fprintf(stderr,"Failed to create window or renderer!\n");
        !           473:                exit(-1);
        !           474:        }
        !           475:        SDL_RenderSetLogicalSize(sdlRenderer, width, height);
        !           476:        if (bitdepth == 8)
        !           477:        {
        !           478:                SDL_Color cols[] = {    /* Colors for the sdl-gui */
        !           479:                        { 0, 0, 0, 255 }, { 64, 64, 64, 255 },
        !           480:                        { 128, 128, 128, 255 }, { 160, 160, 160, 255 },
        !           481:                        { 196, 196, 196, 255 }, { 255, 255, 255, 255 },
        !           482:                        { 0x00, 0x40, 0x00, 255 }, { 0x00, 0xc0, 0x00, 255 },
        !           483:                        { 0x00, 0xe0, 0x00, 255 }
        !           484:                };
        !           485:                sdlscrn = SDL_CreateRGBSurface(0, width, height, bitdepth,
        !           486:                                               0, 0, 0, 0);
        !           487:                if (sdlscrn)
        !           488:                        SDL_SetPaletteColors(sdlscrn->format->palette, cols,
        !           489:                                             128, ARRAYSIZE(cols));
        !           490:        }
        !           491:        else
        !           492:        {
        !           493:                int rm, bm, gm, pfmt;
        !           494:                if (bitdepth == 16)
        !           495:                {
        !           496:                        rm = 0xF800;
        !           497:                        gm = 0x07E0;
        !           498:                        bm = 0x001F;
        !           499:                        pfmt = SDL_PIXELFORMAT_RGB565;
        !           500:                }
        !           501:                else
        !           502:                {
        !           503:                        rm = 0x00FF0000;
        !           504:                        gm = 0x0000FF00;
        !           505:                        bm = 0x000000FF;
        !           506:                        pfmt = SDL_PIXELFORMAT_RGB888;
        !           507:                }
        !           508:                sdlscrn = SDL_CreateRGBSurface(0, width, height, bitdepth,
        !           509:                                               rm, gm, bm, 0);
        !           510:                sdlTexture = SDL_CreateTexture(sdlRenderer, pfmt,
        !           511:                                               SDL_TEXTUREACCESS_STREAMING,
        !           512:                                               width, height);
        !           513:                if (!sdlTexture)
        !           514:                {
        !           515:                        fprintf(stderr,"Failed to create texture!\n");
        !           516:                        exit(-3);
        !           517:                }
        !           518:        }
        !           519: 
        !           520: #else  /* WITH_SDL2 */
        !           521: 
        !           522:        /* SDL Video attributes: */
        !           523:        if (bInFullScreen)
        !           524:        {
        !           525:                sdlVideoFlags  = SDL_HWSURFACE|SDL_FULLSCREEN/*|SDL_DOUBLEBUF*/;
        !           526:                /* SDL_DOUBLEBUF helps avoiding tearing and can be faster on suitable HW,
        !           527:                 * but it doesn't work with partial screen updates done by the ST screen
        !           528:                 * update code or the Hatari GUI, so double buffering is disabled. */
        !           529:        }
        !           530:        else
        !           531:        {
        !           532:                sdlVideoFlags  = SDL_SWSURFACE;
        !           533:        }
        !           534:        if (bitdepth <= 8)
        !           535:        {
        !           536:                sdlVideoFlags |= SDL_HWPALETTE;
        !           537:        }
        !           538: 
        !           539:        /* Set new video mode */
        !           540:        DEBUGPRINT(("SDL screen request: %d x %d @ %d (%s)\n", width, h, bitdepth, bInFullScreen?"fullscreen":"windowed"));
        !           541:        sdlscrn = SDL_SetVideoMode(width, height, bitdepth, sdlVideoFlags);
        !           542: 
        !           543:        /* By default ConfigureParams.Screen.nForceBpp and therefore
        !           544:         * BitCount is zero which means "SDL color depth autodetection".
        !           545:         * In this case the SDL_SetVideoMode() call might return
        !           546:         * a 24 bpp resolution
        !           547:         */
        !           548:        if (sdlscrn && sdlscrn->format->BitsPerPixel == 24)
        !           549:        {
        !           550:                fprintf(stderr, "Unsupported color depth 24, trying 32 bpp instead...\n");
        !           551:                sdlscrn = SDL_SetVideoMode(width, height, 32, sdlVideoFlags);
        !           552:        }
        !           553: 
        !           554: #endif /* WITH_SDL2 */
        !           555: 
        !           556:        /* Exit if we can not open a screen */
        !           557:        if (!sdlscrn)
        !           558:        {
        !           559:                fprintf(stderr, "Could not set video mode:\n %s\n", SDL_GetError() );
        !           560:                SDL_Quit();
        !           561:                exit(-2);
        !           562:        }
        !           563: 
        !           564:        DEBUGPRINT(("SDL screen granted: %d x %d @ %d\n", sdlscrn->w, sdlscrn->h,
        !           565:                    sdlscrn->format->BitsPerPixel));
        !           566: 
        !           567: #ifdef _MUDFLAP
        !           568:        __mf_register(sdlscrn->pixels, sdlscrn->pitch*sdlscrn->h, __MF_TYPE_GUESS, "SDL pixels");
        !           569: #endif
        !           570: 
        !           571:        if (!bInFullScreen)
        !           572:        {
        !           573:                /* re-embed the new Hatari SDL window */
        !           574:                Control_ReparentWindow(width, height, bInFullScreen);
        !           575:        }
        !           576: 
        !           577:        return true;
        !           578: }
1.1.1.8   root      579: 
1.1.1.7   root      580: /*-----------------------------------------------------------------------*/
1.1.1.13  root      581: /**
                    582:  * Initialize SDL screen surface / set resolution.
                    583:  */
1.1.1.23! root      584: static void Screen_SetResolution(bool bForceChange)
1.1.1.11  root      585: {
1.1.1.18  root      586:        int Width, Height, nZoom, SBarHeight, BitCount, maxW, maxH;
                    587:        bool bDoubleLowRes = false;
1.1.1.13  root      588: 
                    589:        /* Bits per pixel */
1.1.1.14  root      590:        if (STRes == ST_HIGH_RES || bUseVDIRes)
1.1.1.13  root      591:        {
                    592:                BitCount = 8;
                    593:        }
                    594:        else
                    595:        {
                    596:                BitCount = ConfigureParams.Screen.nForceBpp;
                    597:        }
                    598: 
1.1.1.18  root      599:        nBorderPixelsTop = nBorderPixelsBottom = 0;
                    600:        nBorderPixelsLeft = nBorderPixelsRight = 0;
                    601: 
                    602:        nScreenZoomX = 1;
                    603:        nScreenZoomY = 1;
                    604: 
                    605:        /* Determine which resolution to use */
                    606:        if (bUseVDIRes)
1.1.1.13  root      607:        {
1.1.1.18  root      608:                Width = VDIWidth;
                    609:                Height = VDIHeight;
1.1.1.13  root      610:        }
                    611:        else
                    612:        {
1.1.1.18  root      613:                if (STRes == ST_LOW_RES)
                    614:                {
                    615:                        Width = 320;
                    616:                        Height = 200;
                    617:                        nZoom = 1;
                    618:                }
                    619:                else    /* else use 640x400, also for med-rez */
                    620:                {
                    621:                        Width = 640;
                    622:                        Height = 400;
                    623:                        nZoom = 2;
                    624:                }
                    625: 
                    626:                /* Statusbar height for doubled screen size */
                    627:                SBarHeight = Statusbar_GetHeightForSize(640, 400);
                    628: 
1.1.1.21  root      629:                Resolution_GetLimits(&maxW, &maxH, &BitCount, ConfigureParams.Screen.bKeepResolutionST);
1.1.1.18  root      630:                
                    631:                /* Zoom if necessary, factors used for scaling mouse motions */
                    632:                if (STRes == ST_LOW_RES &&
                    633:                    2*Width <= maxW && 2*Height+SBarHeight <= maxH)
                    634:                {
                    635:                        nZoom = 2;
                    636:                        Width *= 2;
                    637:                        Height *= 2;
                    638:                        nScreenZoomX = 2;
                    639:                        nScreenZoomY = 2;
                    640:                        bDoubleLowRes = true;
                    641:                }
                    642:                else if (STRes == ST_MEDIUM_RES)
                    643:                {
                    644:                        /* med-rez conversion functions want always
                    645:                         * to double vertically, they don't support
                    646:                         * skipping that (only leaving doubled lines
                    647:                         * black for the TV mode).
                    648:                         */
                    649:                        nScreenZoomX = 1;
                    650:                        nScreenZoomY = 2;
                    651:                }
                    652: 
                    653:                /* Adjust width/height for overscan borders, if mono or VDI we have no overscan */
                    654:                if (ConfigureParams.Screen.bAllowOverscan && !bUseHighRes)
                    655:                {
                    656:                        int leftX = maxW - Width;
                    657:                        int leftY = maxH - (Height + Statusbar_GetHeightForSize(Width, Height));
                    658: 
                    659:                        Screen_SetBorderPixels(leftX/nZoom, leftY/nZoom);
1.1.1.22  root      660:                        DEBUGPRINT(("resolution limit:\n\t%d x %d\nlimited resolution:\n\t", maxW, maxH));
                    661:                        DEBUGPRINT(("%d * (%d + %d + %d) x (%d + %d + %d)\n", nZoom,
                    662:                                    nBorderPixelsLeft, Width/nZoom, nBorderPixelsRight,
                    663:                                    nBorderPixelsTop, Height/nZoom, nBorderPixelsBottom));
1.1.1.18  root      664:                        Width += (nBorderPixelsRight + nBorderPixelsLeft)*nZoom;
                    665:                        Height += (nBorderPixelsTop + nBorderPixelsBottom)*nZoom;
1.1.1.22  root      666:                        DEBUGPRINT(("\t= %d x %d (+ statusbar)\n", Width, Height));
1.1.1.18  root      667:                }
1.1.1.13  root      668:        }
1.1.1.23! root      669: 
1.1.1.18  root      670:        Screen_SetSTScreenOffsets();  
                    671:        Height += Statusbar_SetHeight(Width, Height);
1.1.1.13  root      672: 
1.1.1.20  root      673:        PCScreenOffsetX = PCScreenOffsetY = 0;
                    674: 
1.1.1.23! root      675:        /* Video attributes: */
        !           676:        if (bInFullScreen && ConfigureParams.Screen.bKeepResolutionST)
1.1.1.13  root      677:        {
1.1.1.23! root      678:                /* use desktop resolution */
        !           679:                Resolution_GetDesktopSize(&maxW, &maxH);
        !           680:                SBarHeight = Statusbar_GetHeightForSize(maxW, maxH);
        !           681:                /* re-calculate statusbar height for this resolution */
        !           682:                Statusbar_SetHeight(maxW, maxH-SBarHeight);
        !           683:                /* center Atari screen to resolution */
        !           684:                PCScreenOffsetY = (maxH - Height)/2;
        !           685:                PCScreenOffsetX = (maxW - Width)/2;
        !           686:                /* and select desktop resolution */
        !           687:                Height = maxH;
        !           688:                Width = maxW;
1.1.1.13  root      689:        }
                    690: 
1.1.1.23! root      691:        if (Screen_SetSDLVideoSize(Width, Height, BitCount, bForceChange))
1.1.1.13  root      692:        {
                    693:                /* Re-init screen palette: */
1.1.1.14  root      694:                if (sdlscrn->format->BitsPerPixel == 8)
1.1.1.13  root      695:                        Screen_Handle8BitPalettes();    /* Initialize new 8 bit palette */
                    696:                else
1.1.1.21  root      697:                        Screen_SetupRGBTable();         /* Create color conversion table */
1.1.1.13  root      698: 
1.1.1.15  root      699:                Statusbar_Init(sdlscrn);
1.1.1.23! root      700: 
1.1.1.15  root      701:                /* screen area without the statusbar */
                    702:                STScreenRect.x = 0;
                    703:                STScreenRect.y = 0;
                    704:                STScreenRect.w = sdlscrn->w;
                    705:                STScreenRect.h = sdlscrn->h - Statusbar_GetHeight();
1.1.1.13  root      706:        }
                    707: 
                    708:        /* Set drawing functions */
1.1.1.18  root      709:        Screen_SetDrawFunctions(sdlscrn->format->BitsPerPixel, bDoubleLowRes);
1.1.1.13  root      710: 
                    711:        Screen_SetFullUpdate();           /* Cause full update of screen */
1.1.1.11  root      712: }
                    713: 
                    714: 
                    715: /*-----------------------------------------------------------------------*/
1.1.1.13  root      716: /**
                    717:  * Init Screen bitmap and buffers/tables needed for ST to PC screen conversion
                    718:  */
1.1       root      719: void Screen_Init(void)
                    720: {
1.1.1.13  root      721:        int i;
                    722:        SDL_Surface *pIconSurf;
                    723:        char sIconFileName[FILENAME_MAX];
                    724: 
                    725:        /* Clear frame buffer structures and set current pointer */
                    726:        memset(FrameBuffers, 0, NUM_FRAMEBUFFERS * sizeof(FRAMEBUFFER));
                    727: 
                    728:        /* Allocate previous screen check workspace. We are going to double-buffer a double-buffered screen. Oh. */
                    729:        for (i = 0; i < NUM_FRAMEBUFFERS; i++)
                    730:        {
1.1.1.21  root      731:                FrameBuffers[i].pSTScreen = malloc(MAX_VDI_BYTES);
                    732:                FrameBuffers[i].pSTScreenCopy = malloc(MAX_VDI_BYTES);
1.1.1.13  root      733:                if (!FrameBuffers[i].pSTScreen || !FrameBuffers[i].pSTScreenCopy)
                    734:                {
                    735:                        fprintf(stderr, "Failed to allocate frame buffer memory.\n");
                    736:                        exit(-1);
                    737:                }
                    738:        }
                    739:        pFrameBuffer = &FrameBuffers[0];
                    740: 
                    741:        /* Load and set icon */
                    742:        snprintf(sIconFileName, sizeof(sIconFileName), "%s%chatari-icon.bmp",
                    743:                 Paths_GetDataDir(), PATHSEP);
                    744:        pIconSurf = SDL_LoadBMP(sIconFileName);
                    745:        if (pIconSurf)
                    746:        {
1.1.1.23! root      747: #if WITH_SDL2
        !           748:                SDL_SetColorKey(pIconSurf, SDL_TRUE, SDL_MapRGB(pIconSurf->format, 255, 255, 255));
        !           749:                SDL_SetWindowIcon(sdlWindow, pIconSurf);
        !           750: #else
1.1.1.13  root      751:                SDL_SetColorKey(pIconSurf, SDL_SRCCOLORKEY, SDL_MapRGB(pIconSurf->format, 255, 255, 255));
                    752:                SDL_WM_SetIcon(pIconSurf, NULL);
1.1.1.23! root      753: #endif
1.1.1.13  root      754:                SDL_FreeSurface(pIconSurf);
                    755:        }
                    756: 
                    757:        /* Set initial window resolution */
                    758:        bInFullScreen = ConfigureParams.Screen.bFullScreen;
1.1.1.23! root      759:        Screen_SetResolution(false);
1.1.1.13  root      760: 
1.1.1.17  root      761:        if (bGrabMouse)
                    762:                SDL_WM_GrabInput(SDL_GRAB_ON);
                    763: 
1.1.1.13  root      764:        Video_SetScreenRasters();                       /* Set rasters ready for first screen */
                    765: 
                    766:        /* Configure some SDL stuff: */
                    767:        SDL_ShowCursor(SDL_DISABLE);
1.1       root      768: }
                    769: 
1.1.1.2   root      770: 
1.1       root      771: /*-----------------------------------------------------------------------*/
1.1.1.13  root      772: /**
                    773:  * Free screen bitmap and allocated resources
                    774:  */
1.1       root      775: void Screen_UnInit(void)
                    776: {
1.1.1.13  root      777:        int i;
1.1       root      778: 
1.1.1.13  root      779:        /* Free memory used for copies */
                    780:        for (i = 0; i < NUM_FRAMEBUFFERS; i++)
                    781:        {
                    782:                free(FrameBuffers[i].pSTScreen);
                    783:                free(FrameBuffers[i].pSTScreenCopy);
                    784:        }
1.1.1.23! root      785: 
        !           786: #if WITH_SDL2
        !           787:        Screen_FreeSDL2Resources();
        !           788: #endif
1.1       root      789: }
                    790: 
1.1.1.2   root      791: 
1.1       root      792: /*-----------------------------------------------------------------------*/
1.1.1.13  root      793: /**
                    794:  * Reset screen
                    795:  */
1.1       root      796: void Screen_Reset(void)
                    797: {
1.1.1.13  root      798:        /* On re-boot, always correct ST resolution for monitor, eg Colour/Mono */
                    799:        if (bUseVDIRes)
                    800:        {
                    801:                STRes = VDIRes;
                    802:        }
                    803:        else
                    804:        {
                    805:                if (bUseHighRes)
                    806:                {
                    807:                        STRes = ST_HIGH_RES;
                    808:                        TTRes = TT_HIGH_RES;
                    809:                }
                    810:                else
                    811:                {
                    812:                        STRes = ST_LOW_RES;
                    813:                        TTRes = TT_MEDIUM_RES;
                    814:                }
                    815:        }
                    816:        /* Cause full update */
1.1.1.23! root      817:        Screen_ModeChanged(false);
1.1       root      818: }
                    819: 
                    820: 
                    821: /*-----------------------------------------------------------------------*/
1.1.1.13  root      822: /**
                    823:  * Set flags so screen will be TOTALLY re-drawn (clears whole of full-screen)
                    824:  * next time around
                    825:  */
1.1       root      826: void Screen_SetFullUpdate(void)
                    827: {
1.1.1.13  root      828:        int i;
1.1       root      829: 
1.1.1.13  root      830:        /* Update frame buffers */
                    831:        for (i = 0; i < NUM_FRAMEBUFFERS; i++)
1.1.1.17  root      832:                FrameBuffers[i].bFullUpdate = true;
1.1       root      833: }
                    834: 
1.1.1.5   root      835: 
1.1       root      836: /*-----------------------------------------------------------------------*/
1.1.1.13  root      837: /**
                    838:  * Clear Window display memory
                    839:  */
1.1.1.11  root      840: static void Screen_ClearScreen(void)
                    841: {
1.1.1.15  root      842:        SDL_FillRect(sdlscrn, &STScreenRect, SDL_MapRGB(sdlscrn->format, 0, 0, 0));
1.1.1.11  root      843: }
                    844: 
1.1.1.18  root      845: 
                    846: /*-----------------------------------------------------------------------*/
                    847: /**
                    848:  * Return true if (falcon/tt) hostscreen functions need to be used
                    849:  * instead of the (st/ste) functions here.
                    850:  */
                    851: static bool Screen_UseHostScreen(void)
                    852: {
                    853:        return ((ConfigureParams.System.nMachineType == MACHINE_FALCON
                    854:                 || ConfigureParams.System.nMachineType == MACHINE_TT)
                    855:                && !bUseVDIRes);
                    856: }
                    857: 
                    858: /*-----------------------------------------------------------------------*/
                    859: /**
                    860:  * Force screen redraw.  Does the right thing regardless of whether
                    861:  * we're in ST/STe, Falcon or TT mode.  Needed when switching modes
                    862:  * while emulation is paused.
                    863:  */
                    864: static void Screen_Refresh(void)
                    865: {
                    866:        if (!bUseVDIRes)
                    867:        {
                    868:                if (ConfigureParams.System.nMachineType == MACHINE_FALCON)
                    869:                {
                    870:                        VIDEL_renderScreen();
                    871:                        return;
                    872:                }
                    873:                else if (ConfigureParams.System.nMachineType == MACHINE_TT)
                    874:                {
                    875:                        Video_RenderTTScreen();
                    876:                        return;
                    877:                }
                    878:        }
                    879:        Screen_DrawFrame(true);
                    880: }
                    881: 
                    882: 
1.1.1.11  root      883: /*-----------------------------------------------------------------------*/
1.1.1.13  root      884: /**
                    885:  * Enter Full screen mode
                    886:  */
1.1       root      887: void Screen_EnterFullScreen(void)
                    888: {
1.1.1.18  root      889:        bool bWasRunning;
                    890: 
1.1.1.13  root      891:        if (!bInFullScreen)
                    892:        {
1.1.1.18  root      893:                /* Hold things... */
                    894:                bWasRunning = Main_PauseEmulation(false);
1.1.1.17  root      895:                bInFullScreen = true;
1.1.1.2   root      896: 
1.1.1.18  root      897:                if (Screen_UseHostScreen())
1.1.1.13  root      898:                {
                    899:                        HostScreen_toggleFullScreen();
                    900:                }
                    901:                else
                    902:                {
1.1.1.23! root      903:                        Screen_SetResolution(true);
1.1.1.13  root      904:                        Screen_ClearScreen();       /* Black out screen bitmap as will be invalid when return */
                    905:                }
1.1       root      906: 
1.1.1.13  root      907:                SDL_Delay(20);                  /* To give monitor time to change to new resolution */
1.1.1.18  root      908:                
                    909:                if (bWasRunning)
                    910:                {
                    911:                        /* And off we go... */
                    912:                        Main_UnPauseEmulation();
                    913:                }
                    914:                else
                    915:                {
                    916:                        Screen_Refresh();
                    917:                }
1.1.1.13  root      918:                SDL_WM_GrabInput(SDL_GRAB_ON);  /* Grab mouse pointer in fullscreen */
                    919:        }
1.1       root      920: }
                    921: 
1.1.1.2   root      922: 
1.1       root      923: /*-----------------------------------------------------------------------*/
1.1.1.13  root      924: /**
                    925:  * Return from Full screen mode back to a window
                    926:  */
1.1       root      927: void Screen_ReturnFromFullScreen(void)
                    928: {
1.1.1.18  root      929:        bool bWasRunning;
                    930: 
1.1.1.13  root      931:        if (bInFullScreen)
                    932:        {
1.1.1.18  root      933:                /* Hold things... */
                    934:                bWasRunning = Main_PauseEmulation(false);
1.1.1.17  root      935:                bInFullScreen = false;
1.1.1.13  root      936: 
1.1.1.18  root      937:                if (Screen_UseHostScreen())
1.1.1.13  root      938:                {
                    939:                        HostScreen_toggleFullScreen();
                    940:                }
                    941:                else
                    942:                {
1.1.1.23! root      943:                        Screen_SetResolution(true);
1.1.1.13  root      944:                }
                    945:                SDL_Delay(20);                /* To give monitor time to switch resolution */
1.1.1.18  root      946: 
                    947:                if (bWasRunning)
                    948:                {
                    949:                        /* And off we go... */
                    950:                        Main_UnPauseEmulation();
                    951:                }
                    952:                else
                    953:                {
                    954:                        Screen_Refresh();
                    955:                }
1.1.1.17  root      956: 
                    957:                if (!bGrabMouse)
1.1.1.18  root      958:                {
1.1.1.17  root      959:                        /* Un-grab mouse pointer in windowed mode */
                    960:                        SDL_WM_GrabInput(SDL_GRAB_OFF);
1.1.1.18  root      961:                }
1.1.1.13  root      962:        }
                    963: }
1.1.1.2   root      964: 
                    965: 
1.1.1.13  root      966: /*-----------------------------------------------------------------------*/
                    967: /**
                    968:  * Have we changed between low/med/high res?
                    969:  */
                    970: static void Screen_DidResolutionChange(int new_res)
                    971: {
                    972:        if (new_res != STRes)
                    973:        {
                    974:                STRes = new_res;
1.1.1.23! root      975:                Screen_ModeChanged(false);
1.1.1.13  root      976:        }
                    977:        else
                    978:        {
                    979:                /* Did change overscan mode? Causes full update */
                    980:                if (pFrameBuffer->OverscanModeCopy != OverscanMode)
1.1.1.17  root      981:                        pFrameBuffer->bFullUpdate = true;
1.1.1.13  root      982:        }
1.1       root      983: }
                    984: 
1.1.1.5   root      985: 
1.1.1.2   root      986: /*-----------------------------------------------------------------------*/
1.1.1.13  root      987: /**
                    988:  * Force things associated with changing between low/medium/high res.
                    989:  */
1.1.1.23! root      990: void Screen_ModeChanged(bool bForceChange)
1.1       root      991: {
1.1.1.13  root      992:        if (!sdlscrn)
                    993:        {
                    994:                /* screen not yet initialized */
                    995:                return;
                    996:        }
                    997:        /* Don't run this function if Videl emulation is running! */
                    998:        if (ConfigureParams.System.nMachineType == MACHINE_FALCON && !bUseVDIRes)
                    999:        {
1.1.1.23! root     1000:                VIDEL_ZoomModeChanged(bForceChange);
1.1.1.13  root     1001:        }
                   1002:        else if (ConfigureParams.System.nMachineType == MACHINE_TT && !bUseVDIRes)
                   1003:        {
                   1004:                int width, height, bpp;
                   1005:                Video_GetTTRes(&width, &height, &bpp);
1.1.1.23! root     1006:                HostScreen_setWindowSize(width, height, 8, bForceChange);
1.1.1.13  root     1007:        }
1.1.1.17  root     1008:        else
                   1009:        {
                   1010:                /* Set new display mode, if differs from current */
1.1.1.23! root     1011:                Screen_SetResolution(bForceChange);
1.1.1.17  root     1012:                Screen_SetFullUpdate();
                   1013:        }
                   1014:        if (bInFullScreen || bGrabMouse)
                   1015:                SDL_WM_GrabInput(SDL_GRAB_ON);
                   1016:        else
                   1017:                SDL_WM_GrabInput(SDL_GRAB_OFF);
1.1       root     1018: }
                   1019: 
1.1.1.2   root     1020: 
                   1021: /*-----------------------------------------------------------------------*/
1.1.1.13  root     1022: /**
                   1023:  * Compare current resolution on line with previous, and set 'UpdateLine' accordingly
                   1024:  * Return if swap between low/medium resolution
                   1025:  */
1.1.1.15  root     1026: static bool Screen_CompareResolution(int y, int *pUpdateLine, int oldres)
1.1       root     1027: {
1.1.1.13  root     1028:        /* Check if wrote to resolution register */
                   1029:        if (HBLPaletteMasks[y]&PALETTEMASK_RESOLUTION)  /* See 'Intercept_ShifterMode_WriteByte' */
                   1030:        {
                   1031:                int newres = (HBLPaletteMasks[y]>>16)&ST_MEDIUM_RES_BIT;
                   1032:                /* Did resolution change? */
                   1033:                if (newres != (int)((pFrameBuffer->HBLPaletteMasks[y]>>16)&ST_MEDIUM_RES_BIT))
                   1034:                        *pUpdateLine |= PALETTEMASK_UPDATERES;
                   1035:                else
                   1036:                        *pUpdateLine &= ~PALETTEMASK_UPDATERES;
                   1037:                /* Have used any low/medium res mix? */
                   1038:                return (newres != (oldres&ST_MEDIUM_RES_BIT));
                   1039:        }
1.1.1.17  root     1040:        return false;
1.1       root     1041: }
                   1042: 
1.1.1.7   root     1043: 
1.1.1.2   root     1044: /*-----------------------------------------------------------------------*/
1.1.1.13  root     1045: /**
                   1046:  * Check to see if palette changes cause screen update and keep 'HBLPalette[]' up-to-date
                   1047:  */
1.1.1.8   root     1048: static void Screen_ComparePalette(int y, int *pUpdateLine)
1.1       root     1049: {
1.1.1.17  root     1050:        bool bPaletteChanged = false;
1.1.1.13  root     1051:        int i;
1.1       root     1052: 
1.1.1.13  root     1053:        /* Did write to palette in this or previous frame? */
                   1054:        if (((HBLPaletteMasks[y]|pFrameBuffer->HBLPaletteMasks[y])&PALETTEMASK_PALETTE)!=0)
                   1055:        {
                   1056:                /* Check and update ones which changed */
                   1057:                for (i = 0; i < 16; i++)
                   1058:                {
                   1059:                        if (HBLPaletteMasks[y]&(1<<i))        /* Update changes in ST palette */
                   1060:                                HBLPalette[i] = HBLPalettes[(y*16)+i];
                   1061:                }
                   1062:                /* Now check with same palette from previous frame for any differences(may be changing palette back) */
                   1063:                for (i = 0; (i < 16) && (!bPaletteChanged); i++)
                   1064:                {
                   1065:                        if (HBLPalette[i]!=pFrameBuffer->HBLPalettes[(y*16)+i])
1.1.1.17  root     1066:                                bPaletteChanged = true;
1.1.1.13  root     1067:                }
                   1068:                if (bPaletteChanged)
                   1069:                        *pUpdateLine |= PALETTEMASK_UPDATEPAL;
                   1070:                else
                   1071:                        *pUpdateLine &= ~PALETTEMASK_UPDATEPAL;
                   1072:        }
1.1       root     1073: }
                   1074: 
1.1.1.7   root     1075: 
1.1.1.2   root     1076: /*-----------------------------------------------------------------------*/
1.1.1.13  root     1077: /**
                   1078:  * Check for differences in Palette and Resolution from Mask table and update
                   1079:  * and store off which lines need updating and create full-screen palette.
                   1080:  * (It is very important for these routines to check for colour changes with
                   1081:  * the previous screen so only the very minimum parts are updated).
                   1082:  * Return new STRes value.
                   1083:  */
                   1084: static int Screen_ComparePaletteMask(int res)
1.1       root     1085: {
1.1.1.17  root     1086:        bool bLowMedMix = false;
1.1.1.13  root     1087:        int LineUpdate = 0;
                   1088:        int y;
                   1089: 
                   1090:        /* Set for monochrome? */
                   1091:        if (bUseHighRes)
                   1092:        {
                   1093:                OverscanMode = OVERSCANMODE_NONE;
                   1094: 
                   1095:                /* Just copy mono colours, 0x777 checked also in convert/vdi2.c */
                   1096:                if (HBLPalettes[0] & 0x777)
                   1097:                {
                   1098:                        HBLPalettes[0] = 0x777;
                   1099:                        HBLPalettes[1] = 0x000;
                   1100:                }
                   1101:                else
                   1102:                {
                   1103:                        HBLPalettes[0] = 0x000;
                   1104:                        HBLPalettes[1] = 0x777;
                   1105:                }
                   1106: 
                   1107:                /* Colors changed? */
                   1108:                if (HBLPalettes[0] != PrevHBLPalette[0])
1.1.1.17  root     1109:                        pFrameBuffer->bFullUpdate = true;
1.1.1.13  root     1110: 
                   1111:                /* Set bit to flag 'full update' */
                   1112:                if (pFrameBuffer->bFullUpdate)
                   1113:                        ScrUpdateFlag = PALETTEMASK_UPDATEFULL;
                   1114:                else
                   1115:                        ScrUpdateFlag = 0x00000000;
                   1116:        }
                   1117: 
                   1118:        /* Use VDI resolution? */
                   1119:        if (bUseVDIRes)
                   1120:        {
                   1121:                /* Force to VDI resolution screen, without overscan */
                   1122:                res = VDIRes;
                   1123: 
                   1124:                /* Colors changed? */
                   1125:                if (HBLPalettes[0] != PrevHBLPalette[0])
1.1.1.17  root     1126:                        pFrameBuffer->bFullUpdate = true;
1.1.1.13  root     1127: 
                   1128:                /* Set bit to flag 'full update' */
                   1129:                if (pFrameBuffer->bFullUpdate)
                   1130:                        ScrUpdateFlag = PALETTEMASK_UPDATEFULL;
                   1131:                else
                   1132:                        ScrUpdateFlag = 0x00000000;
                   1133:        }
                   1134:        /* Are in Mono? Force to monochrome and no overscan */
                   1135:        else if (bUseHighRes)
                   1136:        {
                   1137:                /* Force to standard hi-resolution screen, without overscan */
                   1138:                res = ST_HIGH_RES;
                   1139:        }
                   1140:        else    /* Full colour */
                   1141:        {
                   1142:                /* Get resolution */
                   1143:                //res = (HBLPaletteMasks[0]>>16)&ST_RES_MASK;
                   1144:                /* [NP] keep only low/med bit (could be hires in case of overscan on the 1st line) */
                   1145:                res = (HBLPaletteMasks[0]>>16)&ST_MEDIUM_RES_BIT;
                   1146: 
                   1147:                /* Do all lines - first is tagged as full-update */
                   1148:                for (y = 0; y < NUM_VISIBLE_LINES; y++)
                   1149:                {
                   1150:                        /* Find any resolution/palette change and update palette/mask buffer */
                   1151:                        /* ( LineUpdate has top two bits set to say if line needs updating due to palette or resolution change ) */
                   1152:                        bLowMedMix |= Screen_CompareResolution(y, &LineUpdate, res);
                   1153:                        Screen_ComparePalette(y,&LineUpdate);
                   1154:                        HBLPaletteMasks[y] = (HBLPaletteMasks[y]&(~PALETTEMASK_UPDATEMASK)) | LineUpdate;
                   1155:                        /* Copy palette and mask for next frame */
                   1156:                        memcpy(&pFrameBuffer->HBLPalettes[y*16],HBLPalette,sizeof(short int)*16);
                   1157:                        pFrameBuffer->HBLPaletteMasks[y] = HBLPaletteMasks[y];
                   1158:                }
                   1159:                /* Did mix/have medium resolution? */
                   1160:                if (bLowMedMix || (res & ST_MEDIUM_RES_BIT))
                   1161:                        res = ST_MEDIUM_RES;
                   1162:        }
                   1163: 
                   1164:        return res;
                   1165: }
                   1166: 
                   1167: 
                   1168: /*-----------------------------------------------------------------------*/
                   1169: /**
                   1170:  * Update Palette Mask to show 'full-update' required. This is usually done after a resolution change
                   1171:  * or when going between a Window and full-screen display
                   1172:  */
1.1.1.8   root     1173: static void Screen_SetFullUpdateMask(void)
1.1       root     1174: {
1.1.1.13  root     1175:        int y;
1.1       root     1176: 
1.1.1.13  root     1177:        for (y = 0; y < NUM_VISIBLE_LINES; y++)
                   1178:                HBLPaletteMasks[y] |= PALETTEMASK_UPDATEFULL;
1.1       root     1179: }
                   1180: 
1.1.1.7   root     1181: 
1.1.1.2   root     1182: /*-----------------------------------------------------------------------*/
1.1.1.13  root     1183: /**
                   1184:  * Set details for ST screen conversion.
                   1185:  */
1.1.1.10  root     1186: static void Screen_SetConvertDetails(void)
1.1       root     1187: {
1.1.1.13  root     1188:        pSTScreen = pFrameBuffer->pSTScreen;          /* Source in ST memory */
                   1189:        pSTScreenCopy = pFrameBuffer->pSTScreenCopy;  /* Previous ST screen */
                   1190:        pPCScreenDest = sdlscrn->pixels;              /* Destination PC screen */
                   1191: 
                   1192:        PCScreenBytesPerLine = sdlscrn->pitch;        /* Bytes per line */
1.1.1.20  root     1193: 
                   1194:        /* Center to available framebuffer */
                   1195:        pPCScreenDest += PCScreenOffsetY * PCScreenBytesPerLine + PCScreenOffsetX * (sdlscrn->format->BitsPerPixel/8);
                   1196: 
1.1.1.13  root     1197:        pHBLPalettes = pFrameBuffer->HBLPalettes;     /* HBL palettes pointer */
                   1198:        /* Not in TV-Mode? Then double up on Y: */
1.1.1.15  root     1199:        bScrDoubleY = !(ConfigureParams.Screen.nMonitorType == MONITOR_TYPE_TV);
1.1.1.13  root     1200: 
                   1201:        if (bUseVDIRes)
                   1202:        {
                   1203:                /* Select screen draw for standard or VDI display */
                   1204:                STScreenLeftSkipBytes = 0;
                   1205:                STScreenWidthBytes = VDIWidth * VDIPlanes / 8;
                   1206:                STScreenStartHorizLine = 0;
                   1207:                STScreenEndHorizLine = VDIHeight;
                   1208:        }
                   1209:        else
                   1210:        {
                   1211:                if (ConfigureParams.Screen.bAllowOverscan)  /* Use borders? */
                   1212:                {
                   1213:                        /* Always draw to WHOLE screen including ALL borders */
                   1214:                        STScreenLeftSkipBytes = 0;              /* Number of bytes to skip on ST screen for left (border) */
                   1215: 
                   1216:                        if (bUseHighRes)
                   1217:                        {
                   1218:                                pFrameBuffer->OverscanModeCopy = OverscanMode = OVERSCANMODE_NONE;
1.1.1.15  root     1219:                                STScreenStartHorizLine = 0;
1.1.1.13  root     1220:                                STScreenEndHorizLine = 400;
                   1221:                        }
                   1222:                        else
                   1223:                        {
                   1224:                                STScreenWidthBytes = SCREENBYTES_LINE;  /* Number of horizontal bytes in our ST screen */
1.1.1.15  root     1225:                                STScreenStartHorizLine = OVERSCAN_TOP - nBorderPixelsTop;
                   1226:                                STScreenEndHorizLine = OVERSCAN_TOP + 200 + nBorderPixelsBottom;
1.1.1.13  root     1227:                        }
                   1228:                }
                   1229:                else
                   1230:                {
                   1231:                        /* Only draw main area and centre on Y */
                   1232:                        STScreenLeftSkipBytes = SCREENBYTES_LEFT;
                   1233:                        STScreenWidthBytes = SCREENBYTES_MIDDLE;
                   1234:                        STScreenStartHorizLine = OVERSCAN_TOP;
                   1235:                        STScreenEndHorizLine = OVERSCAN_TOP + (bUseHighRes ? 400 : 200);
                   1236:                }
                   1237:        }
1.1       root     1238: }
                   1239: 
1.1.1.2   root     1240: 
                   1241: /*-----------------------------------------------------------------------*/
1.1.1.13  root     1242: /**
                   1243:  * Lock full-screen for drawing
                   1244:  */
1.1.1.15  root     1245: static bool Screen_Lock(void)
1.1       root     1246: {
1.1.1.13  root     1247:        if (SDL_MUSTLOCK(sdlscrn))
                   1248:        {
                   1249:                if (SDL_LockSurface(sdlscrn))
                   1250:                {
                   1251:                        Screen_ReturnFromFullScreen();   /* All OK? If not need to jump back to a window */
1.1.1.17  root     1252:                        return false;
1.1.1.13  root     1253:                }
                   1254:        }
1.1.1.2   root     1255: 
1.1.1.17  root     1256:        return true;
1.1       root     1257: }
                   1258: 
1.1.1.2   root     1259: /*-----------------------------------------------------------------------*/
1.1.1.13  root     1260: /**
                   1261:  * UnLock full-screen
                   1262:  */
1.1.1.8   root     1263: static void Screen_UnLock(void)
1.1       root     1264: {
1.1.1.13  root     1265:        if ( SDL_MUSTLOCK(sdlscrn) )
                   1266:                SDL_UnlockSurface(sdlscrn);
1.1       root     1267: }
                   1268: 
1.1.1.2   root     1269: 
                   1270: /*-----------------------------------------------------------------------*/
1.1.1.13  root     1271: /**
                   1272:  * Blit our converted ST screen to window/full-screen
                   1273:  */
1.1.1.22  root     1274: static void Screen_Blit(SDL_Rect *sbar_rect)
1.1       root     1275: {
1.1.1.13  root     1276:        unsigned char *pTmpScreen;
                   1277: 
1.1.1.18  root     1278: #if 0  /* double buffering cannot be used with partial screen updates */
                   1279: # if NUM_FRAMEBUFFERS > 1
                   1280:        if (bInFullScreen && (sdlscrn->flags & SDL_DOUBLEBUF))
1.1.1.13  root     1281:        {
                   1282:                /* Swap screen */
1.1.1.18  root     1283:                if (pFrameBuffer==&FrameBuffers[0])
                   1284:                        pFrameBuffer = &FrameBuffers[1];
                   1285:                else
                   1286:                        pFrameBuffer = &FrameBuffers[0];
1.1.1.15  root     1287:                SDL_Flip(sdlscrn);
1.1.1.13  root     1288:        }
                   1289:        else
1.1.1.18  root     1290: # endif
                   1291: #endif
1.1.1.13  root     1292:        {
1.1.1.22  root     1293:                int count = 1;
                   1294:                SDL_Rect rects[2];
                   1295:                rects[0] = STScreenRect;
                   1296:                if (sbar_rect)
                   1297:                {
                   1298:                        rects[1] = *sbar_rect;
                   1299:                        count = 2;
                   1300:                }
                   1301:                SDL_UpdateRects(sdlscrn, count, rects);
1.1.1.13  root     1302:        }
                   1303: 
                   1304:        /* Swap copy/raster buffers in screen. */
                   1305:        pTmpScreen = pFrameBuffer->pSTScreenCopy;
                   1306:        pFrameBuffer->pSTScreenCopy = pFrameBuffer->pSTScreen;
                   1307:        pFrameBuffer->pSTScreen = pTmpScreen;
1.1       root     1308: }
                   1309: 
1.1.1.3   root     1310: 
1.1.1.2   root     1311: /*-----------------------------------------------------------------------*/
1.1.1.13  root     1312: /**
                   1313:  * Draw ST screen to window/full-screen framebuffer
1.1.1.15  root     1314:  * @param  bForceFlip  Force screen update, even if contents did not change
1.1.1.17  root     1315:  * @return  true if screen contents changed
1.1.1.13  root     1316:  */
1.1.1.15  root     1317: static bool Screen_DrawFrame(bool bForceFlip)
1.1       root     1318: {
1.1.1.13  root     1319:        int new_res;
                   1320:        void (*pDrawFunction)(void);
1.1.1.17  root     1321:        static bool bPrevFrameWasSpec512 = false;
1.1.1.22  root     1322:        SDL_Rect *sbar_rect;
1.1.1.13  root     1323: 
                   1324:        /* Scan palette/resolution masks for each line and build up palette/difference tables */
                   1325:        new_res = Screen_ComparePaletteMask(STRes);
                   1326:        /* Do require palette? Check if changed and update */
                   1327:        Screen_Handle8BitPalettes();
                   1328:        /* Did we change resolution this frame - allocate new screen if did so */
                   1329:        Screen_DidResolutionChange(new_res);
                   1330:        /* Is need full-update, tag as such */
                   1331:        if (pFrameBuffer->bFullUpdate)
                   1332:                Screen_SetFullUpdateMask();
                   1333: 
1.1.1.15  root     1334:        /* restore area potentially left under overlay led
                   1335:         * and saved by Statusbar_OverlayBackup()
                   1336:         */
                   1337:        Statusbar_OverlayRestore(sdlscrn);
1.1.1.22  root     1338: 
                   1339:        /* Lock screen for direct screen surface format writes */
1.1.1.13  root     1340:        if (Screen_Lock())
                   1341:        {
1.1.1.17  root     1342:                bScreenContentsChanged = false;      /* Did change (ie needs blit?) */
1.1.1.15  root     1343: 
1.1.1.13  root     1344:                /* Set details */
                   1345:                Screen_SetConvertDetails();
1.1.1.15  root     1346:                
1.1.1.13  root     1347:                /* Clear screen on full update to clear out borders and also interleaved lines */
                   1348:                if (pFrameBuffer->bFullUpdate && !bUseVDIRes)
                   1349:                        Screen_ClearScreen();
1.1.1.15  root     1350:                
1.1.1.13  root     1351:                /* Call drawing for full-screen */
                   1352:                if (bUseVDIRes)
                   1353:                {
                   1354:                        pDrawFunction = ScreenDrawFunctionsVDI[VDIRes];
                   1355:                }
                   1356:                else
                   1357:                {
                   1358:                        pDrawFunction = ScreenDrawFunctionsNormal[STRes];
                   1359:                        /* Check if is Spec512 image */
                   1360:                        if (Spec512_IsImage())
                   1361:                        {
1.1.1.17  root     1362:                                bPrevFrameWasSpec512 = true;
1.1.1.13  root     1363:                                /* What mode were we in? Keep to 320xH or 640xH */
                   1364:                                if (pDrawFunction==ConvertLowRes_320x16Bit)
1.1.1.19  root     1365:                                        pDrawFunction = ConvertLowRes_320x16Bit_Spec;
1.1.1.13  root     1366:                                else if (pDrawFunction==ConvertLowRes_640x16Bit)
1.1.1.19  root     1367:                                        pDrawFunction = ConvertLowRes_640x16Bit_Spec;
1.1.1.13  root     1368:                                else if (pDrawFunction==ConvertLowRes_320x32Bit)
1.1.1.19  root     1369:                                        pDrawFunction = ConvertLowRes_320x32Bit_Spec;
1.1.1.13  root     1370:                                else if (pDrawFunction==ConvertLowRes_640x32Bit)
1.1.1.19  root     1371:                                        pDrawFunction = ConvertLowRes_640x32Bit_Spec;
                   1372:                                else if (pDrawFunction==ConvertMediumRes_640x32Bit)
                   1373:                                        pDrawFunction = ConvertMediumRes_640x32Bit_Spec;
                   1374:                                else if (pDrawFunction==ConvertMediumRes_640x16Bit)
                   1375:                                        pDrawFunction = ConvertMediumRes_640x16Bit_Spec;
1.1.1.13  root     1376:                        }
                   1377:                        else if (bPrevFrameWasSpec512)
                   1378:                        {
                   1379:                                /* If we switch back from Spec512 mode to normal
                   1380:                                 * screen rendering, we have to make sure to do
                   1381:                                 * a full update of the screen. */
                   1382:                                Screen_SetFullUpdateMask();
1.1.1.17  root     1383:                                bPrevFrameWasSpec512 = false;
1.1.1.13  root     1384:                        }
                   1385:                }
                   1386: 
                   1387:                if (pDrawFunction)
1.1.1.15  root     1388:                        CALL_VAR(pDrawFunction);
                   1389: 
                   1390:                /* Unlock screen */
                   1391:                Screen_UnLock();
1.1.1.13  root     1392: 
1.1.1.22  root     1393:                /* draw overlay led(s) or statusbar after unlock */
1.1.1.15  root     1394:                Statusbar_OverlayBackup(sdlscrn);
1.1.1.22  root     1395:                sbar_rect = Statusbar_Update(sdlscrn, false);
1.1.1.15  root     1396:                
1.1.1.13  root     1397:                /* Clear flags, remember type of overscan as if change need screen full update */
1.1.1.17  root     1398:                pFrameBuffer->bFullUpdate = false;
1.1.1.13  root     1399:                pFrameBuffer->OverscanModeCopy = OverscanMode;
                   1400: 
                   1401:                /* And show to user */
1.1.1.22  root     1402:                if (bScreenContentsChanged || bForceFlip || sbar_rect)
1.1.1.15  root     1403:                {
1.1.1.22  root     1404:                        Screen_Blit(sbar_rect);
1.1.1.15  root     1405:                }
1.1.1.13  root     1406: 
1.1.1.15  root     1407:                return bScreenContentsChanged;
1.1.1.13  root     1408:        }
1.1.1.15  root     1409: 
                   1410:        return false;
1.1       root     1411: }
                   1412: 
1.1.1.9   root     1413: 
1.1.1.2   root     1414: /*-----------------------------------------------------------------------*/
1.1.1.13  root     1415: /**
                   1416:  * Draw ST screen to window/full-screen
                   1417:  */
1.1.1.15  root     1418: bool Screen_Draw(void)
1.1       root     1419: {
1.1.1.13  root     1420:        if (!bQuitProgram && VideoBase)
                   1421:        {
                   1422:                /* And draw (if screen contents changed) */
1.1.1.15  root     1423:                return Screen_DrawFrame(false);
1.1.1.13  root     1424:        }
1.1.1.15  root     1425: 
                   1426:        return false;
1.1       root     1427: }
1.1.1.11  root     1428: 
                   1429: 
                   1430: /* -------------- screen conversion routines --------------------------------
                   1431:   Screen conversion routines. We have a number of routines to convert ST screen
                   1432:   to PC format. We split these into Low, Medium and High each with 8/16-bit
                   1433:   versions. To gain extra speed, as almost half of the processing time can be
                   1434:   spent in these routines, we check for any changes from the previously
                   1435:   displayed frame. AdjustLinePaletteRemap() sets a flag to tell the routines
                   1436:   if we need to totally update a line (ie full update, or palette/res change)
                   1437:   or if we just can do a difference check.
                   1438:   We convert each screen 16 pixels at a time by use of a couple of look-up
                   1439:   tables. These tables convert from 2-plane format to bbp and then we can add
                   1440:   two of these together to get 4-planes. This keeps the tables small and thus
                   1441:   improves speed. We then look these bbp values up as an RGB/Index value to
                   1442:   copy to the screen.
                   1443: */
                   1444: 
                   1445: 
1.1.1.13  root     1446: /*-----------------------------------------------------------------------*/
                   1447: /**
1.1.1.11  root     1448:  * Update the STRGBPalette[] array with current colours for this raster line.
                   1449:  *
                   1450:  * Return 'ScrUpdateFlag', 0x80000000=Full update, 0x40000000=Update
                   1451:  * as palette changed
                   1452:  */
                   1453: static int AdjustLinePaletteRemap(int y)
                   1454: {
                   1455: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1.1.1.13  root     1456:        static const int endiantable[16] = {0,2,1,3,8,10,9,11,4,6,5,7,12,14,13,15};
1.1.1.11  root     1457: #endif
1.1.1.13  root     1458:        Uint16 *actHBLPal;
                   1459:        int i;
1.1.1.11  root     1460: 
1.1.1.13  root     1461:        /* Copy palette and convert to RGB in display format */
                   1462:        actHBLPal = pHBLPalettes + (y<<4);    /* offset in palette */
                   1463:        for (i=0; i<16; i++)
                   1464:        {
1.1.1.11  root     1465: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1.1.1.13  root     1466:                STRGBPalette[endiantable[i]] = ST2RGB[*actHBLPal++];
1.1.1.11  root     1467: #else
1.1.1.13  root     1468:                STRGBPalette[i] = ST2RGB[*actHBLPal++];
1.1.1.11  root     1469: #endif
1.1.1.13  root     1470:        }
                   1471:        ScrUpdateFlag = HBLPaletteMasks[y];
                   1472:        return ScrUpdateFlag;
1.1.1.11  root     1473: }
                   1474: 
                   1475: 
1.1.1.13  root     1476: /*-----------------------------------------------------------------------*/
                   1477: /**
1.1.1.11  root     1478:  * Run updates to palette(STRGBPalette[]) until get to screen line
                   1479:  * we are to convert from
                   1480:  */
                   1481: static void Convert_StartFrame(void)
                   1482: {
1.1.1.13  root     1483:        int y = 0;
                   1484:        /* Get #lines before conversion starts */
                   1485:        int lines = STScreenStartHorizLine;
                   1486:        while (lines--)
                   1487:                AdjustLinePaletteRemap(y++);     /* Update palette */
1.1.1.11  root     1488: }
                   1489: 
                   1490: /* lookup tables and conversion macros */
                   1491: #include "convert/macros.h"
                   1492: 
                   1493: /* Conversion routines */
1.1.1.13  root     1494: 
1.1.1.19  root     1495: #include "convert/low320x8.c"          /* LowRes To 320xH x 8-bit color */
                   1496: #include "convert/low640x8.c"          /* LowRes To 640xH x 8-bit color */
                   1497: #include "convert/med640x8.c"          /* MediumRes To 640xH x 8-bit color */
                   1498: #include "convert/high640x8.c"         /* HighRes To 640xH x 8-bit color */
                   1499: 
                   1500: #include "convert/low320x16.c"         /* LowRes To 320xH x 16-bit color */
                   1501: #include "convert/low640x16.c"         /* LowRes To 640xH x 16-bit color */
                   1502: #include "convert/med640x16.c"         /* MediumRes To 640xH x 16-bit color */
                   1503: #include "convert/low320x16_spec.c"    /* LowRes Spectrum 512 To 320xH x 16-bit color */
                   1504: #include "convert/low640x16_spec.c"    /* LowRes Spectrum 512 To 640xH x 16-bit color */
                   1505: #include "convert/med640x16_spec.c"    /* MediumRes Spectrum 512 To 640xH x 16-bit color */
                   1506: 
                   1507: #include "convert/low320x32.c"         /* LowRes To 320xH x 32-bit color */
                   1508: #include "convert/low640x32.c"         /* LowRes To 640xH x 32-bit color */
                   1509: #include "convert/med640x32.c"         /* MediumRes To 640xH x 32-bit color */
                   1510: #include "convert/low320x32_spec.c"    /* LowRes Spectrum 512 To 320xH x 32-bit color */
                   1511: #include "convert/low640x32_spec.c"    /* LowRes Spectrum 512 To 640xH x 32-bit color */
                   1512: #include "convert/med640x32_spec.c"    /* MediumRes Spectrum 512 To 640xH x 32-bit color */
                   1513: 
                   1514: #include "convert/vdi16.c"             /* VDI x 16 color */
                   1515: #include "convert/vdi4.c"              /* VDI x 4 color */
                   1516: #include "convert/vdi2.c"              /* VDI x 2 color */

unix.superglobalmegacorp.com

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