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

1.1       root        1: /*
1.1.1.6   root        2:   Hatari - screen.c
1.1       root        3: 
1.1.1.6   root        4:   This file is distributed under the GNU Public License, version 2 or at your
                      5:   option any later version. Read the file gpl.txt for details.
                      6: 
                      7:   This code converts a 1/2/4 plane ST format screen to either 8 or 16-bit PC
                      8:   format. An awful lost of processing is needed to do this conversion - we
                      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
                     18:   optimise things further. Also when running in maximum speed we make sure we
                     19:   only convert the screen every 50 times a second - inbetween frames are not
                     20:   processed.
1.1       root       21: */
1.1.1.7 ! root       22: static char rcsid[] = "Hatari $Id: screen.c,v 1.27 2003/06/17 18:03:22 thothy Exp $";
1.1       root       23: 
                     24: #include <SDL.h>
                     25: 
                     26: #include "main.h"
1.1.1.7 ! root       27: #include "configuration.h"
1.1       root       28: #include "ikbd.h"
                     29: #include "m68000.h"
                     30: #include "memAlloc.h"
                     31: #include "misc.h"
                     32: #include "printer.h"
                     33: #include "screen.h"
                     34: #include "screenConvert.h"
                     35: #include "screenDraw.h"
                     36: #include "screenSnapShot.h"
                     37: #include "sound.h"
                     38: #include "spec512.h"
                     39: #include "vdi.h"
                     40: #include "video.h"
                     41: 
1.1.1.7 ! root       42: /* SDL Video attributes for fullscreen */
        !            43: const unsigned int sdlvmode = SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN|SDL_HWPALETTE;
1.1       root       44: 
                     45: SCREENDRAW ScreenDrawWindow[4];                   /* Set up with details of drawing functions for ST_xxx_RES */
                     46: SCREENDRAW ScreenDrawFullScreen[4];               /* And for full-screen */
                     47: SCREENDRAW ScreenDrawVDIWindow[4];
                     48: SCREENDRAW ScreenDrawVDIFullScreen[4];            /* And for full-screen */
                     49: FRAMEBUFFER FrameBuffers[NUM_FRAMEBUFFERS];       /* Store frame buffer details to tell how to update */
                     50: FRAMEBUFFER *pFrameBuffer;                        /* Pointer into current 'FrameBuffer' */
                     51: unsigned char *pScreenBitmap=NULL;                /* Screen pixels in PC RGB format, allocated with 'CreateDIBSection' */
                     52: unsigned char *pSTScreen,*pSTScreenCopy;          /* Keep track of current and previous ST screen data */
                     53: unsigned char *pPCScreenDest;                     /* Destination PC buffer */
                     54: int STScreenStartHorizLine,STScreenEndHorizLine;  /* Start/End lines to be converted */
1.1.1.5   root       55: int PCScreenBytesPerLine, STScreenWidthBytes, STScreenLeftSkipBytes;
1.1       root       56: BOOL bInFullScreen=FALSE;                         /* TRUE if in full screen */
                     57: BOOL bFullScreenHold = FALSE;                     /* TRUE if hold display while full screen */
                     58: BOOL bScreenContentsChanged;                      /* TRUE if buffer changed and requires blitting */
1.1.1.2   root       59: int STRes=ST_LOW_RES, PrevSTRes=ST_LOW_RES;       /* Current and previous ST resolutions */
1.1       root       60: int nDroppedFrames=0;                             /* Number of dropped frames during emulation run */
                     61: 
                     62: int STScreenLineOffset[NUM_VISIBLE_LINES];        /* Offsets for ST screen lines eg, 0,160,320... */
                     63: unsigned long STRGBPalette[16];                   /* Palette buffer used in assembler conversion routines */
                     64: unsigned long ST2RGB[2048];                       /* Table to convert ST Palette 0x777 to PC format RGB551(2 pixels each entry) */
                     65: unsigned short int HBLPalette[16], PrevHBLPalette[16];  /* Current palette for line, also copy of first line */
                     66: 
1.1.1.3   root       67: SDL_Surface *sdlscrn;                             /* The SDL screen surface */
1.1.1.5   root       68: BOOL bGrabMouse = FALSE;                          /* Grab the mouse cursor in the window */
1.1       root       69: 
                     70: 
                     71: /*-----------------------------------------------------------------------*/
                     72: /*
1.1.1.7 ! root       73:   Set window size
        !            74: */
        !            75: static void Screen_SetWindowRes()
        !            76: {
        !            77:   int Width, Height, BitCount;
        !            78: 
        !            79:   if (bUseVDIRes) {
        !            80:     Width = VDIWidth;
        !            81:     Height = VDIHeight;
        !            82:   } else
        !            83:     switch(STRes)
        !            84:       {
        !            85:       case ST_LOW_RES:
        !            86:        if (ConfigureParams.Screen.ChosenDisplayMode == 0 ||
        !            87:            ConfigureParams.Screen.ChosenDisplayMode == 3) {
        !            88:          Width = 320;
        !            89:          Height = 200;
        !            90:          break;
        !            91:        }
        !            92:        // else use 640x400
        !            93:       default:
        !            94:        Width = 640;
        !            95:        Height = 400;
        !            96:        break;
        !            97:       }
        !            98: 
        !            99:   /* Adjust width/height for overscan borders, if mono or VDI we have no overscan */
        !           100: 
        !           101:   if ( !(bUseVDIRes || bUseHighRes) &&
        !           102:        ConfigureParams.Screen.bAllowOverscan)
        !           103:   {
        !           104:     /* If using 640 pixel wide screen, double overscan */
        !           105:     if (Width==640)
        !           106:     {
        !           107:       Width += OVERSCAN_LEFT+OVERSCAN_RIGHT;
        !           108:       Height += OVERSCAN_TOP+OVERSCAN_BOTTOM;
        !           109:     }
        !           110:     /* Add in overscan borders(if 640x200 bitmap is double on Y) */
        !           111:     Width += OVERSCAN_LEFT+OVERSCAN_RIGHT;
        !           112:     Height += OVERSCAN_TOP+OVERSCAN_BOTTOM;
        !           113:   }
        !           114: 
        !           115:   /* Bits per pixel */
        !           116:   if(ConfigureParams.Screen.ChosenDisplayMode <= DISPLAYMODE_16COL_FULL
        !           117:      || STRes == ST_HIGH_RES || bUseVDIRes)
        !           118:   {
        !           119:     BitCount = 8;
        !           120:   }
        !           121:   else
        !           122:   {
        !           123:     BitCount = 16;
        !           124:   }
        !           125: 
        !           126:   sdlscrn=SDL_SetVideoMode(Width, Height, BitCount, SDL_SWSURFACE|SDL_HWPALETTE);
        !           127:   if( sdlscrn==NULL )
        !           128:   {
        !           129:     fprintf(stderr, "Could not set video mode:\n %s\n", SDL_GetError() );
        !           130:     SDL_Quit();
        !           131:     exit(-2);
        !           132:   }
        !           133:   pScreenBitmap=sdlscrn->pixels;
        !           134: 
        !           135:   if(BitCount==8)
        !           136:   {
        !           137:     Screen_Handle8BitPalettes();
        !           138:   }
        !           139:   else
        !           140:   {
        !           141:     Screen_SetupRGBTable();
        !           142:   }
        !           143: 
        !           144:   if(!bGrabMouse)
        !           145:   {
        !           146:     SDL_WM_GrabInput(SDL_GRAB_OFF);  /* Un-grab mouse pointer in windowed mode */
        !           147:   }
        !           148:   Screen_SetDrawModes();        /* Set draw modes(store which modes to use!) */
        !           149: }
        !           150: 
        !           151: /*-----------------------------------------------------------------------*/
        !           152: /*
1.1       root      153:   Init Screen bitmap and buffers/tables needed for ST to PC screen conversion
                    154: */
                    155: void Screen_Init(void)
                    156: {
                    157:   int i;
                    158: 
                    159:   /* Clear frame buffer structures and set current pointer */
1.1.1.7 ! root      160:   Memory_Clear(FrameBuffers, NUM_FRAMEBUFFERS * sizeof(FRAMEBUFFER));
1.1       root      161: 
                    162:   /* Allocate previous screen check workspace. We are going to double-buffer a double-buffered screen. Oh. */
1.1.1.5   root      163:   for(i=0; i<NUM_FRAMEBUFFERS; i++)
                    164:   {
1.1       root      165:     FrameBuffers[i].pSTScreen = (unsigned char *)Memory_Alloc(((MAX_VDI_WIDTH*MAX_VDI_PLANES)/8)*MAX_VDI_HEIGHT);
                    166:     FrameBuffers[i].pSTScreenCopy = (unsigned char *)Memory_Alloc(((MAX_VDI_WIDTH*MAX_VDI_PLANES)/8)*MAX_VDI_HEIGHT);
                    167:   }
                    168:   pFrameBuffer = &FrameBuffers[0];
                    169: 
1.1.1.7 ! root      170:   Screen_SetWindowRes();
1.1       root      171: 
                    172:   Video_SetScreenRasters();                       /* Set rasters ready for first screen */
                    173: 
                    174:   Screen_SetScreenLineOffsets();                  /* Store offset to each horizontal line */
                    175:   Screen_SetDrawModes();                          /* Set draw modes */
1.1.1.5   root      176:   Screen_SetupRGBTable();                         /* Create color convertion table */
1.1       root      177:   Screen_SetFullUpdate();                         /* Cause full update of screen */
                    178: 
1.1.1.2   root      179:   /* Configure some SDL stuff: */
1.1       root      180:   SDL_WM_SetCaption(PROG_NAME, "Hatari");
                    181:   SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
                    182:   SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_ENABLE);
                    183:   SDL_EventState(SDL_MOUSEBUTTONUP, SDL_ENABLE);
1.1.1.4   root      184:   SDL_ShowCursor(SDL_DISABLE);
1.1       root      185: }
                    186: 
1.1.1.2   root      187: 
1.1       root      188: /*-----------------------------------------------------------------------*/
                    189: /*
                    190:   Free screen bitmap and allocated resources
                    191: */
                    192: void Screen_UnInit(void)
                    193: {
                    194:   int i;
                    195: 
1.1.1.3   root      196:   /* Free memory used for copies */
1.1.1.7 ! root      197:   for(i=0; i<NUM_FRAMEBUFFERS; i++)
        !           198:   {
1.1       root      199:     Memory_Free(FrameBuffers[i].pSTScreen);
                    200:     Memory_Free(FrameBuffers[i].pSTScreenCopy);
                    201:   }
                    202: }
                    203: 
1.1.1.2   root      204: 
1.1       root      205: /*-----------------------------------------------------------------------*/
                    206: /*
                    207:   Reset screen
                    208: */
                    209: void Screen_Reset(void)
                    210: {
                    211:   /* On re-boot, always correct ST resolution for monitor, eg Colour/Mono */
1.1.1.5   root      212:   if (bUseVDIRes)
                    213:   {
1.1       root      214:     STRes = VDIRes;
                    215:   }
1.1.1.5   root      216:   else
                    217:   {
1.1       root      218:     if (bUseHighRes)
                    219:       STRes = ST_HIGH_RES;
                    220:     else
                    221:       STRes = ST_LOW_RES;
                    222:   }
                    223:   PrevSTRes = -1;
                    224:   /* Cause full update */
                    225:   Screen_SetFullUpdate();
                    226: }
                    227: 
                    228: /*-----------------------------------------------------------------------*/
                    229: /*
                    230:   Store Y offset for each horizontal line in our source ST screen for each reference in assembler(no multiply)
                    231: */
                    232: void Screen_SetScreenLineOffsets(void)
                    233: {
                    234:   int i;
                    235: 
                    236:   for(i=0; i<NUM_VISIBLE_LINES; i++)
                    237:     STScreenLineOffset[i] = i * SCREENBYTES_LINE;
                    238: }
                    239: 
                    240: 
                    241: /*-----------------------------------------------------------------------*/
                    242: /*
1.1.1.5   root      243:   Set flags so screen will be TOTALLY re-drawn (clears whole of full-screen)
                    244:   next time around
1.1       root      245: */
                    246: void Screen_SetFullUpdate(void)
                    247: {
                    248:   int i;
                    249: 
                    250:   /* Update frame buffers */
                    251:   for(i=0; i<NUM_FRAMEBUFFERS; i++)
                    252:     FrameBuffers[i].bFullUpdate = TRUE;
                    253: }
                    254: 
1.1.1.5   root      255: 
1.1       root      256: /*-----------------------------------------------------------------------*/
                    257: /*
1.1.1.5   root      258:   Create ST 777 colour format to 16-bits per pixel - call each time change
                    259:   resolution or to/from Window display
1.1       root      260: */
1.1.1.5   root      261: void Screen_SetupRGBTable(void)
1.1       root      262: {
1.1.1.5   root      263:   unsigned int STColour, RGBColour;
                    264:   unsigned int r, g, b;
1.1       root      265: 
                    266:   /* Do Red,Green and Blue for all 512 ST colours */
1.1.1.5   root      267:   for(r=0; r<8; r++)
                    268:   {
                    269:     for(g=0; g<8; g++)
                    270:     {
                    271:       for(b=0; b<8; b++)
1.1.1.7 ! root      272:       {
1.1       root      273:         STColour = (r<<8) | (g<<4) | (b);      /* ST format 0x777 */
                    274: 
                    275:         /*RGBColour = (r<<12) | (g<<7) | (b<<2);*/  /* format 0x1555 */
                    276:         RGBColour = SDL_MapRGB(sdlscrn->format, (r<<5), (g<<5), (b<<5));
                    277: 
                    278:         ST2RGB[STColour] = (RGBColour<<16) | RGBColour;  /* As long's, for speed(write two pixels at once) */
                    279:       }
                    280:     }
                    281:   }
                    282: }
                    283: 
1.1.1.5   root      284: 
1.1       root      285: /*-----------------------------------------------------------------------*/
                    286: /*
                    287:   Enter Full screen mode
                    288: */
1.1.1.7 ! root      289: 
        !           290: static SDL_Surface *set_new_sdl_fsmode() {
        !           291:   SDL_Surface *newsdlscrn;
        !           292:   if (bUseVDIRes) {
        !           293:     newsdlscrn = SDL_SetVideoMode(ScreenDrawVDIFullScreen[STRes].Width, ScreenDrawVDIFullScreen[STRes].Height,
        !           294:                                  ScreenDrawVDIFullScreen[STRes].BitDepth, sdlvmode);
        !           295:   } else {
        !           296:     int Width = ScreenDrawFullScreen[STRes].Width,
        !           297:       Height = ScreenDrawFullScreen[STRes].Height;
        !           298:     if ( !bUseHighRes && ConfigureParams.Screen.bAllowOverscan ) {
        !           299:       /* If using 640 pixel wide screen, double overscan */
        !           300:       if (Width==640)
        !           301:        {
        !           302:          Width += OVERSCAN_LEFT+OVERSCAN_RIGHT;
        !           303:          Height += OVERSCAN_TOP+OVERSCAN_BOTTOM;
        !           304:        }
        !           305:       /* Add in overscan borders(if 640x200 bitmap is double on Y) */
        !           306:       Width += OVERSCAN_LEFT+OVERSCAN_RIGHT;
        !           307:       Height += OVERSCAN_TOP+OVERSCAN_BOTTOM;
        !           308:     }
        !           309: 
        !           310:     newsdlscrn = SDL_SetVideoMode(Width, Height,
        !           311:                                  ScreenDrawFullScreen[STRes].BitDepth, sdlvmode);
        !           312:   }
        !           313:   return newsdlscrn;
        !           314: }
        !           315: 
1.1       root      316: void Screen_EnterFullScreen(void)
                    317: {
1.1.1.2   root      318:   SDL_Surface *newsdlscrn;
1.1       root      319: 
1.1.1.5   root      320:   if (!bInFullScreen)
                    321:   {
1.1       root      322:     Main_PauseEmulation();        /* Hold things... */
1.1.1.2   root      323:     SDL_Delay(20);                /* To give sound time to clear! */
                    324: 
                    325:     Screen_SetDrawModes();        /* Set draw modes(store which modes to use!) */
1.1       root      326: 
1.1.1.7 ! root      327:     newsdlscrn = set_new_sdl_fsmode();
1.1.1.2   root      328: 
                    329:     if( newsdlscrn==NULL )
1.1.1.5   root      330:     {
1.1.1.2   root      331:       fprintf(stderr, "Could not set video mode:\n %s\n", SDL_GetError() );
1.1.1.5   root      332:     }
                    333:     else
                    334:     {
1.1.1.2   root      335:       sdlscrn = newsdlscrn;
                    336:       pScreenBitmap = newsdlscrn->pixels;
                    337:       bInFullScreen = TRUE;
                    338: 
1.1.1.7 ! root      339:       Screen_SetFullUpdate();           /* Cause full update of screen */
        !           340:       /* Re-init screen palette: */
        !           341:       if(sdlscrn->format->BitsPerPixel == 8)
        !           342:         Screen_Handle8BitPalettes();    /* Initialize new 8 bit palette */
        !           343:       else
        !           344:         Screen_SetupRGBTable();         /* Set fullscreen RGB table*/
        !           345:       Screen_ClearScreen();         /* Black out screen bitmap as will be invalid when return */
1.1.1.5   root      346:     }
1.1       root      347:     Main_UnPauseEmulation();        /* And off we go... */
1.1.1.3   root      348: 
1.1.1.4   root      349:     SDL_WM_GrabInput(SDL_GRAB_ON);  /* Grab mouse pointer in fullscreen */
1.1       root      350:   }
                    351: }
                    352: 
1.1.1.2   root      353: 
1.1       root      354: /*-----------------------------------------------------------------------*/
                    355: /*
                    356:   Return from Full screen mode back to a window
                    357: */
                    358: void Screen_ReturnFromFullScreen(void)
                    359: {
1.1.1.7 ! root      360:   if (bInFullScreen)
        !           361:   {
1.1.1.2   root      362:     Main_PauseEmulation();        /* Hold things... */
                    363:     SDL_Delay(20);                /* To give sound time to clear! */
                    364: 
                    365:     bInFullScreen = FALSE;
                    366: 
1.1.1.7 ! root      367:     Screen_SetWindowRes();
1.1.1.2   root      368: 
1.1.1.5   root      369:     Screen_SetupRGBTable();           /* Set window RGB */
1.1.1.2   root      370:     Screen_SetFullUpdate();           /* Cause full update of screen */
                    371: 
                    372:     Main_UnPauseEmulation();          /* And off we go... */
1.1       root      373:   }
                    374: }
                    375: 
1.1.1.5   root      376: 
1.1.1.2   root      377: /*-----------------------------------------------------------------------*/
1.1       root      378: /*
                    379:   Clear Window display memory
                    380: */
1.1.1.2   root      381: void Screen_ClearScreen(void)
1.1       root      382: {
1.1.1.2   root      383:   SDL_FillRect(sdlscrn,NULL, SDL_MapRGB(sdlscrn->format, 0, 0, 0) );
1.1       root      384: }
                    385: 
                    386: 
1.1.1.2   root      387: /*-----------------------------------------------------------------------*/
1.1       root      388: /*
                    389:   Set ScreenDrawFullScreen[] and ScreenDrawWindow[] arrays with information for chosen display modes
                    390: */
                    391: void Screen_SetDrawModes(void)
                    392: {
                    393:   SCREENDRAW_DISPLAYOPTIONS *pScreenDisplay;
                    394: 
                    395:   /* Clear out */
                    396:   Memory_Clear(ScreenDrawWindow,sizeof(SCREENDRAW)*4);
                    397:   Memory_Clear(ScreenDrawFullScreen,sizeof(SCREENDRAW)*4);
                    398:   Memory_Clear(ScreenDrawVDIWindow,sizeof(SCREENDRAW)*4);
                    399:   Memory_Clear(ScreenDrawVDIFullScreen,sizeof(SCREENDRAW)*4);
                    400: 
                    401:   /* First, store Window details(set for 16-bit Windows desktop) */
                    402:   ScreenDrawWindow[ST_LOW_RES].pDrawFunction = ConvertLowRes_320x16Bit;
                    403:   ScreenDrawWindow[ST_LOW_RES].Width = 320;     ScreenDrawWindow[ST_LOW_RES].Height = 200;     ScreenDrawWindow[ST_LOW_RES].BitDepth = 16;
                    404: 
                    405:   ScreenDrawWindow[ST_MEDIUM_RES].pDrawFunction = ConvertMediumRes_640x16Bit;
                    406:   ScreenDrawWindow[ST_MEDIUM_RES].Width = 640;  ScreenDrawWindow[ST_MEDIUM_RES].Height = 200;  ScreenDrawWindow[ST_MEDIUM_RES].BitDepth = 16;
1.1.1.3   root      407: 
1.1       root      408:   ScreenDrawWindow[ST_HIGH_RES].pDrawFunction = ConvertHighRes_640x8Bit;
                    409:   ScreenDrawWindow[ST_HIGH_RES].Width = 640;    ScreenDrawWindow[ST_HIGH_RES].Height = 400;    ScreenDrawWindow[ST_HIGH_RES].BitDepth = 8;
                    410: 
                    411:   /* (NOTE this is irrelevant as is directed to low/medium when starts) */
                    412:   ScreenDrawWindow[ST_LOWMEDIUM_MIX_RES].pDrawFunction = ConvertLowRes_640x16Bit;
                    413:   ScreenDrawWindow[ST_LOWMEDIUM_MIX_RES].Width = 640;  ScreenDrawWindow[ST_LOWMEDIUM_MIX_RES].Height = 200;  ScreenDrawWindow[ST_LOWMEDIUM_MIX_RES].BitDepth = 16;
                    414: 
1.1.1.5   root      415:   /* And for VDI screens (set for 8-bit) */
1.1       root      416:   ScreenDrawVDIWindow[ST_LOW_RES].pDrawFunction = ConvertVDIRes_16Colour;
                    417:   ScreenDrawVDIWindow[ST_LOW_RES].Width = VDIWidth;  ScreenDrawVDIWindow[ST_LOW_RES].Height = VDIHeight;  ScreenDrawVDIWindow[ST_LOW_RES].BitDepth = 8;
                    418:   ScreenDrawVDIWindow[ST_MEDIUM_RES].pDrawFunction = ConvertVDIRes_4Colour;
                    419:   ScreenDrawVDIWindow[ST_MEDIUM_RES].Width = VDIWidth;  ScreenDrawVDIWindow[ST_MEDIUM_RES].Height = VDIHeight;  ScreenDrawVDIWindow[ST_MEDIUM_RES].BitDepth = 8;
1.1.1.5   root      420:   ScreenDrawVDIWindow[ST_HIGH_RES].pDrawFunction = ConvertVDIRes_2Colour;
                    421:   ScreenDrawVDIWindow[ST_HIGH_RES].Width = VDIWidth;  ScreenDrawVDIWindow[ST_HIGH_RES].Height = VDIHeight;  ScreenDrawVDIWindow[ST_HIGH_RES].BitDepth = 8;
1.1       root      422: 
                    423:   /* And full-screen, select from Overscan/Non-Overscan */
1.1.1.7 ! root      424:   if (ConfigureParams.Screen.bAllowOverscan) {
1.1       root      425:     pScreenDisplay = &ScreenDisplayOptions[ConfigureParams.Screen.ChosenDisplayMode];
1.1.1.7 ! root      426:   } else {
1.1.1.2   root      427:     pScreenDisplay = &ScreenDisplayOptions_NoOverscan[ConfigureParams.Screen.ChosenDisplayMode];
1.1.1.7 ! root      428:   }
1.1       root      429: 
                    430:   /* Assign full-screen draw modes from chosen option under dialog */
                    431:   ScreenDrawFullScreen[ST_LOW_RES] = *pScreenDisplay->pLowRes;
                    432:   ScreenDrawFullScreen[ST_MEDIUM_RES] = *pScreenDisplay->pMediumRes;
                    433:   ScreenDrawFullScreen[ST_HIGH_RES] = *pScreenDisplay->pHighRes;
                    434:   ScreenDrawFullScreen[ST_LOWMEDIUM_MIX_RES] = *pScreenDisplay->pLowMediumMixRes;
1.1.1.2   root      435: 
1.1       root      436:   /* And VDI(8-bit), according to select resolution */
1.1.1.7 ! root      437:   switch(VDIWidth)
        !           438:   {
1.1       root      439:     case 640:
                    440:       ScreenDrawVDIFullScreen[ST_LOW_RES] = VDIScreenDraw_640x480[0];
                    441:       ScreenDrawVDIFullScreen[ST_MEDIUM_RES] = VDIScreenDraw_640x480[1];
                    442:       ScreenDrawVDIFullScreen[ST_HIGH_RES] = VDIScreenDraw_640x480[2];
                    443:       break;
                    444:     case 800:
                    445:       ScreenDrawVDIFullScreen[ST_LOW_RES] = VDIScreenDraw_800x600[0];
                    446:       ScreenDrawVDIFullScreen[ST_MEDIUM_RES] = VDIScreenDraw_800x600[1];
                    447:       ScreenDrawVDIFullScreen[ST_HIGH_RES] = VDIScreenDraw_800x600[2];
                    448:       break;
                    449:     case 1024:
                    450:       ScreenDrawVDIFullScreen[ST_LOW_RES] = VDIScreenDraw_1024x768[0];
                    451:       ScreenDrawVDIFullScreen[ST_MEDIUM_RES] = VDIScreenDraw_1024x768[1];
                    452:       ScreenDrawVDIFullScreen[ST_HIGH_RES] = VDIScreenDraw_1024x768[2];
                    453:       break;
                    454:   }
                    455: }
                    456: 
1.1.1.2   root      457: /*-----------------------------------------------------------------------*/
1.1       root      458: /*
                    459:   Have we changes beteen low/medium/high res?
                    460: */
                    461: void Screen_DidResolutionChange(void)
                    462: {
1.1.1.2   root      463:   /* Did change res? */
1.1.1.5   root      464:   if (STRes!=PrevSTRes)
                    465:   {
1.1.1.2   root      466:     /* Set new fullscreen display mode, if differs from current */
1.1.1.5   root      467:     if (bInFullScreen)
                    468:     {
1.1.1.2   root      469:       SDL_Surface *newsdlscrn;
1.1.1.7 ! root      470: 
        !           471:       newsdlscrn = set_new_sdl_fsmode();
        !           472: 
1.1.1.2   root      473:       if( newsdlscrn )
1.1.1.5   root      474:       {
1.1.1.2   root      475:         sdlscrn = newsdlscrn;
1.1.1.7 ! root      476:         /* Re-init screen palette: */
        !           477:         if(sdlscrn->format->BitsPerPixel == 8)
        !           478:           Screen_Handle8BitPalettes();  /* Initialize new 8 bit palette */
        !           479:         else
        !           480:           Screen_SetupRGBTable();       /* Set fullscreen RGB table */
1.1.1.5   root      481:       }
                    482:       else
                    483:       {
1.1.1.2   root      484:         bInFullScreen = FALSE;
1.1.1.5   root      485:       }
1.1       root      486:     }
1.1.1.2   root      487: 
1.1.1.5   root      488:     if( !bInFullScreen )
                    489:     {
1.1.1.7 ! root      490:       Screen_SetWindowRes();
1.1       root      491:     }
                    492: 
                    493:     PrevSTRes = STRes;
                    494:     Screen_SetFullUpdate();
                    495:   }
                    496: 
1.1.1.2   root      497:   /* Did change overscan mode? Causes full update */
1.1       root      498:   if (pFrameBuffer->OverscanModeCopy!=OverscanMode)
                    499:     pFrameBuffer->bFullUpdate = TRUE;
                    500: }
                    501: 
1.1.1.2   root      502: 
                    503: /*-----------------------------------------------------------------------*/
1.1       root      504: /*
                    505:   Compare current resolution on line with previous, and set 'UpdateLine' accordingly
                    506:   Also check if swap between low/medium resolution and return in 'bLowMedMix'
                    507: */
                    508: void Screen_CompareResolution(int y, int *pUpdateLine, BOOL *pbLowMedMix)
                    509: {
                    510:   int Resolution;
                    511: 
1.1.1.2   root      512:   /* Check if wrote to resolution register */
1.1.1.7 ! root      513:   if (HBLPaletteMasks[y]&PALETTEMASK_RESOLUTION)  /* See 'Intercept_ShifterMode_WriteByte' */
        !           514:   {
1.1       root      515:     Resolution = (HBLPaletteMasks[y]>>16)&0x1;
1.1.1.2   root      516:     /* Have used any low/medium res mix? */
1.1       root      517:     if (Resolution!=(STRes&0x1))
                    518:       *pbLowMedMix = TRUE;
1.1.1.2   root      519:     /* Did change resolution */
1.1       root      520:     if (Resolution!=(int)((pFrameBuffer->HBLPaletteMasks[y]>>16)&0x1))
                    521:       *pUpdateLine |= PALETTEMASK_UPDATERES;
                    522:     else
                    523:       *pUpdateLine &= ~PALETTEMASK_UPDATERES;
                    524:   }
                    525: }
                    526: 
1.1.1.7 ! root      527: 
1.1.1.2   root      528: /*-----------------------------------------------------------------------*/
1.1       root      529: /*
                    530:   Check to see if palette changes cause screen update and keep 'HBLPalette[]' up-to-date
                    531: */
                    532: void Screen_ComparePalette(int y, int *pUpdateLine)
                    533: {
                    534:   BOOL bPaletteChanged = FALSE;
                    535:   int i;
                    536: 
1.1.1.2   root      537:   /* Did write to palette in this or previous frame? */
1.1.1.7 ! root      538:   if (((HBLPaletteMasks[y]|pFrameBuffer->HBLPaletteMasks[y])&PALETTEMASK_PALETTE)!=0)
        !           539:   {
1.1.1.2   root      540:     /* Check and update ones which changed */
1.1.1.7 ! root      541:     for(i=0; i<16; i++)
        !           542:     {
1.1.1.2   root      543:       if (HBLPaletteMasks[y]&(1<<i))        /* Update changes in ST palette */
1.1       root      544:         HBLPalette[i] = HBLPalettes[(y*16)+i];
                    545:     }
1.1.1.2   root      546:     /* Now check with same palette from previous frame for any differences(may be changing palette back) */
1.1.1.7 ! root      547:     for(i=0; (i<16) && (!bPaletteChanged); i++)
        !           548:     {
1.1       root      549:       if (HBLPalette[i]!=pFrameBuffer->HBLPalettes[(y*16)+i])
                    550:         bPaletteChanged = TRUE;
                    551:     }
                    552:     if (bPaletteChanged)
                    553:       *pUpdateLine |= PALETTEMASK_UPDATEPAL;
                    554:     else
                    555:       *pUpdateLine &= ~PALETTEMASK_UPDATEPAL;
                    556:   }
                    557: }
                    558: 
1.1.1.7 ! root      559: 
1.1.1.2   root      560: /*-----------------------------------------------------------------------*/
1.1       root      561: /*
                    562:   Check for differences in Palette and Resolution from Mask table and update and
                    563:   store off which lines need updating and create full-screen palette.
                    564:   (It is very important for these routines to check for colour changes with the previous
                    565:   screen so only the very minimum parts are updated)
                    566: */
                    567: int Screen_ComparePaletteMask(void)
                    568: {
                    569:   BOOL bLowMedMix=FALSE;
                    570:   int LineUpdate = 0;
                    571:   int y;
                    572: 
                    573:   /* Set for monochrome? */
1.1.1.7 ! root      574:   if (bUseHighRes)
        !           575:   {
1.1       root      576:     OverscanMode = OVERSCANMODE_NONE;
                    577: 
                    578:     /* Just copy mono colours */
1.1.1.7 ! root      579:     if (HBLPalettes[0]&0x777)
        !           580:     {
1.1       root      581:       HBLPalettes[0] = 0x777;  HBLPalettes[1] = 0x000;
                    582:     }
1.1.1.7 ! root      583:     else
        !           584:     {
1.1       root      585:       HBLPalettes[0] = 0x000;  HBLPalettes[1] = 0x777;
                    586:     }
                    587: 
1.1.1.7 ! root      588:     /* Colors changed? */
        !           589:     if (HBLPalettes[0] != PrevHBLPalette[0])
        !           590:       pFrameBuffer->bFullUpdate = TRUE;
        !           591: 
1.1       root      592:     /* Set bit to flag 'full update' */
                    593:     if (pFrameBuffer->bFullUpdate)
                    594:       ScrUpdateFlag = PALETTEMASK_UPDATEFULL;
                    595:     else
                    596:       ScrUpdateFlag = 0x00000000;
                    597:   }
                    598: 
                    599:   /* Use VDI resolution? */
1.1.1.7 ! root      600:   if (bUseVDIRes)
        !           601:   {
1.1       root      602:     /* Force to VDI resolution screen, without overscan */
                    603:     STRes = VDIRes;
                    604: 
1.1.1.7 ! root      605:     /* Colors changed? */
1.1       root      606:     if (HBLPalettes[0]!=PrevHBLPalette[0])
                    607:       pFrameBuffer->bFullUpdate = TRUE;
                    608: 
                    609:     /* Set bit to flag 'full update' */
                    610:     if (pFrameBuffer->bFullUpdate)
                    611:       ScrUpdateFlag = PALETTEMASK_UPDATEFULL;
                    612:     else
                    613:       ScrUpdateFlag = 0x00000000;
                    614:   }
                    615:   /* Are in Mono? Force to monochrome and no overscan */
1.1.1.7 ! root      616:   else if (bUseHighRes)
        !           617:   {
1.1       root      618:     /* Force to standard hi-resolution screen, without overscan */
                    619:     STRes = ST_HIGH_RES;
                    620:   }
1.1.1.7 ! root      621:   else    /* Full colour */
        !           622:   {
1.1       root      623:     /* Get resolution */
                    624:     STRes = (HBLPaletteMasks[0]>>16)&0x3;
                    625:     /* Do all lines - first is tagged as full-update */
1.1.1.7 ! root      626:     for(y=0; y<NUM_VISIBLE_LINES; y++)
        !           627:     {
1.1       root      628:       /* Find any resolution/palette change and update palette/mask buffer */
                    629:       /* ( LineUpdate has top two bits set to say if line needs updating due to palette or resolution change ) */
                    630:       Screen_CompareResolution(y,&LineUpdate,&bLowMedMix);
                    631:       Screen_ComparePalette(y,&LineUpdate);
                    632:       HBLPaletteMasks[y] = (HBLPaletteMasks[y]&(~PALETTEMASK_UPDATEMASK)) | LineUpdate;
                    633:       /* Copy palette and mask for next frame */
                    634:       memcpy(&pFrameBuffer->HBLPalettes[y*16],HBLPalette,sizeof(short int)*16);
                    635:       pFrameBuffer->HBLPaletteMasks[y] = HBLPaletteMasks[y];
                    636:     }
                    637:     /* Did mix resolution? */
                    638:     if (bLowMedMix)
                    639:       STRes = ST_LOWMEDIUM_MIX_RES;
                    640:   }
                    641: 
                    642:   return(STRes);
                    643: }
                    644: 
1.1.1.3   root      645: 
1.1.1.2   root      646: /*-----------------------------------------------------------------------*/
1.1       root      647: /*
                    648:   Create 8-Bit palette for display if needed
                    649: */
                    650: void Screen_CreatePalette(void)
                    651: {
1.1.1.5   root      652: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
                    653:   static const int endiantable[16] = {0,2,1,3,8,10,9,11,4,6,5,7,12,14,13,15};
                    654: #endif
                    655:   SDL_Color sdlColors[16];
                    656:   int i, j;
                    657: 
                    658:   if(bUseHighRes)
                    659:   {
                    660:     /* Colors for monochrome screen mode emulation */
1.1.1.7 ! root      661:     if(HBLPalettes[0])
        !           662:     {
        !           663:       sdlColors[0].r = sdlColors[0].g = sdlColors[0].b = 255;
        !           664:       sdlColors[1].r = sdlColors[1].g = sdlColors[1].b = 0;
        !           665:     }
        !           666:     else
        !           667:     {
        !           668:       sdlColors[0].r = sdlColors[0].g = sdlColors[0].b = 0;
        !           669:       sdlColors[1].r = sdlColors[1].g = sdlColors[1].b = 255;
        !           670:     }
1.1.1.5   root      671:     SDL_SetColors(sdlscrn, sdlColors, 10, 2);
1.1.1.7 ! root      672:     /*SDL_SetColors(sdlscrn, sdlColors, 0, 2);*/
1.1       root      673:   }
1.1.1.5   root      674:   else
                    675:   {
                    676:     /* Colors for color screen mode emulation */
                    677:     for(i=0; i<16; i++)
                    678:     {
                    679: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
                    680:       j = endiantable[i];
                    681: #else
                    682:       j = i;
                    683: #endif
                    684:       sdlColors[j].r = ((HBLPalettes[i]>>8)&0x7)<<5;
                    685:       sdlColors[j].g = ((HBLPalettes[i]>>4)&0x7)<<5;
                    686:       sdlColors[j].b = (HBLPalettes[i]&0x7)<<5;
1.1       root      687:     }
1.1.1.5   root      688:     SDL_SetColors(sdlscrn, sdlColors, 10, 16);
1.1       root      689:   }
                    690: }
                    691: 
1.1.1.5   root      692: 
1.1.1.2   root      693: /*-----------------------------------------------------------------------*/
1.1       root      694: /*
1.1.1.5   root      695:   Create 8-Bit palette for display if needed.
1.1       root      696: */
                    697: void Screen_Handle8BitPalettes(void)
                    698: {
1.1.1.5   root      699:   BOOL bPaletteChanged=FALSE;
1.1       root      700:   int i;
                    701: 
                    702:   /* Do need to check for 8-Bit palette change? Ie, update whole screen */
1.1.1.5   root      703:   /* VDI screens and monochrome modes are ALL 8-Bit at the moment! */
1.1.1.6   root      704:   if(sdlscrn->format->BitsPerPixel == 8)
1.1.1.5   root      705:   {
1.1       root      706:     /* If using HiRes palette update with full update flag */
1.1.1.5   root      707:     if (!bUseHighRes)
                    708:     {
1.1       root      709:       /* Check if palette of 16 colours changed from previous frame */
1.1.1.5   root      710:       for(i=0; (i<16) && (!bPaletteChanged); i++)
                    711:       {
1.1       root      712:         /* Check with first line palette(stored in 'Screen_ComparePaletteMask') */
                    713:         if (HBLPalettes[i]!=PrevHBLPalette[i])
                    714:           bPaletteChanged = TRUE;
                    715:       }
                    716:     }
                    717: 
                    718:     /* Did palette change or do we require a full update? */
1.1.1.5   root      719:     if ( (bPaletteChanged) || (pFrameBuffer->bFullUpdate) )
                    720:     {
1.1       root      721:       /* Create palette, for Full-Screen of Window */
                    722:       Screen_CreatePalette();
                    723:       /* Make sure update whole screen */
                    724:       pFrameBuffer->bFullUpdate = TRUE;
                    725:     }
                    726:   }
                    727: 
                    728:   /* Copy old palette for 8-Bit compare as this routine writes over it */
                    729:   memcpy(PrevHBLPalette,HBLPalettes,sizeof(short int)*16);
                    730: }
                    731: 
1.1.1.7 ! root      732: 
1.1.1.2   root      733: /*-----------------------------------------------------------------------*/
1.1       root      734: /*
                    735:   Update Palette Mask to show 'full-update' required. This is usually done after a resolution change
                    736:   or when going between a Window and full-screen display
                    737: */
                    738: void Screen_SetFullUpdateMask(void)
                    739: {
                    740:   int y;
                    741: 
                    742:   for(y=0; y<NUM_VISIBLE_LINES; y++)
                    743:     HBLPaletteMasks[y] |= PALETTEMASK_UPDATEFULL;
                    744: }
                    745: 
1.1.1.7 ! root      746: 
1.1.1.2   root      747: /*-----------------------------------------------------------------------*/
1.1       root      748: /*
                    749:   Set details for ST screen conversion(Window version)
                    750: */
                    751: void Screen_SetWindowConvertDetails(void)
                    752: {
1.1.1.2   root      753:   /* Reset Double Y, used for Window medium res' and in full screen */
1.1       root      754:   bScrDoubleY = FALSE;
1.1.1.3   root      755: 
                    756:   pSTScreen = pFrameBuffer->pSTScreen;          /* Source in ST memory */
                    757:   pSTScreenCopy = pFrameBuffer->pSTScreenCopy;  /* Previous ST screen */
                    758:   pPCScreenDest = pScreenBitmap;                /* Destination PC screen */
                    759: 
1.1.1.5   root      760:   STScreenStartHorizLine = 0;                   /* Full height */
                    761: 
                    762:   if (ConfigureParams.Screen.bUseHighRes && !bUseVDIRes)
                    763:   {
1.1       root      764:     pFrameBuffer->OverscanModeCopy = OverscanMode = OVERSCANMODE_NONE;
1.1.1.3   root      765:     STScreenEndHorizLine = 400;
1.1       root      766:   }
                    767:   else
                    768:   {
1.1.1.2   root      769:     /* Always draw to WHOLE screen including ALL borders */
                    770:     STScreenLeftSkipBytes = 0;                  /* Number of bytes to skip on ST screen for left(border) */
                    771:     STScreenWidthBytes = SCREENBYTES_LINE;      /* Number of horizontal bytes in our ST screen */
1.1       root      772: 
                    773:     STScreenEndHorizLine = NUM_VISIBLE_LINES;
                    774: 
                    775:     if (bUseVDIRes)
1.1.1.5   root      776:     {
1.1       root      777:       PCScreenBytesPerLine = VDIWidth;
1.1.1.5   root      778:     }
                    779:     else
                    780:     {
1.1.1.7 ! root      781:       PCScreenBytesPerLine = sdlscrn->pitch;
        !           782: /*       PCScreenBytesPerLine = (SCREENBYTES_LINE*2)*sizeof(short int); */
        !           783: /*       if (STRes!=ST_LOW_RES)                    /\* Bytes per line in PC screen are DOUBLE when in medium/mix *\/ */
        !           784: /*         PCScreenBytesPerLine <<= 1; */
1.1       root      785:     }
1.1.1.7 ! root      786: 
1.1       root      787:     pHBLPalettes = pFrameBuffer->HBLPalettes;
                    788:   }
                    789: 
1.1.1.7 ! root      790:   if (!ConfigureParams.Screen.bInterlacedScreen)
        !           791:   {
1.1       root      792:     bScrDoubleY = TRUE;
1.1.1.7 ! root      793:   }
1.1       root      794: }
                    795: 
1.1.1.2   root      796: /*-----------------------------------------------------------------------*/
1.1       root      797: /*
1.1.1.7 ! root      798:   Set details for ST screen conversion (Full-Screen version)
1.1       root      799: */
                    800: void Screen_SetFullScreenConvertDetails(void)
                    801: {
                    802:   SCREENDRAW *pScreenDraw;
                    803: 
1.1.1.2   root      804:   /* Reset Double Y, used for window medium res' and in full screen */
1.1       root      805:   bScrDoubleY = FALSE;
                    806: 
1.1.1.7 ! root      807:   /* Select screen draw for standard or VDI display */
        !           808:   if (bUseVDIRes)
        !           809:     pScreenDraw = &ScreenDrawVDIFullScreen[VDIRes];
        !           810:   else
        !           811:     pScreenDraw = &ScreenDrawFullScreen[STRes];
1.1       root      812: 
1.1.1.7 ! root      813:   /* Only draw what can fit into full-screen and centre on Y */
        !           814:   STScreenLeftSkipBytes = pScreenDraw->Overscan[OverscanMode].STScreenLeftSkipBytes;
        !           815:   STScreenWidthBytes = pScreenDraw->Overscan[OverscanMode].STScreenWidthBytes;
        !           816: 
        !           817:   STScreenStartHorizLine = pScreenDraw->Overscan[OverscanMode].STScreenStartHorizLine;
        !           818:   STScreenEndHorizLine = pScreenDraw->Overscan[OverscanMode].STScreenEndHorizLine;
1.1       root      819: 
1.1.1.7 ! root      820:   pSTScreen = pFrameBuffer->pSTScreen;          /* Source in ST memory */
        !           821:   pSTScreenCopy = pFrameBuffer->pSTScreenCopy;  /* Previous ST screen */
        !           822:   PCScreenBytesPerLine = sdlscrn->pitch;
        !           823:   pPCScreenDest = (unsigned char *)sdlscrn->pixels;  /* Destination PC screen */
        !           824:   /* Get start of line on screen according to overscan (scale if double line mode) */
        !           825:   pPCScreenDest += pScreenDraw->Overscan[OverscanMode].PCStartHorizLine
        !           826:       * pScreenDraw->VertPixelsPerLine*PCScreenBytesPerLine;
        !           827:   /* And offset on X */
        !           828:   pPCScreenDest += pScreenDraw->Overscan[OverscanMode].PCStartXOffset;
        !           829:   pHBLPalettes = pFrameBuffer->HBLPalettes;
        !           830: 
        !           831:   /* Is non-interlaced? May need to double up on Y */
        !           832:   if (!ConfigureParams.Screen.bInterlacedScreen)
        !           833:   {
        !           834:     bScrDoubleY = TRUE;
1.1       root      835:   }
                    836: }
                    837: 
1.1.1.2   root      838: 
                    839: /*-----------------------------------------------------------------------*/
1.1       root      840: /*
                    841:   Lock full-screen for drawing
                    842: */
                    843: BOOL Screen_Lock(void)
                    844: {
1.1.1.7 ! root      845:   if(SDL_MUSTLOCK(sdlscrn))
        !           846:   {
        !           847:     if(SDL_LockSurface(sdlscrn))
        !           848:     {
1.1.1.2   root      849:       Screen_ReturnFromFullScreen();   /* All OK? If not need to jump back to a window */
1.1       root      850:       return(FALSE);
                    851:     }
                    852:   }
1.1.1.2   root      853: 
1.1       root      854:   return(TRUE);
                    855: }
                    856: 
1.1.1.2   root      857: /*-----------------------------------------------------------------------*/
1.1       root      858: /*
                    859:   UnLock full-screen
                    860: */
                    861: void Screen_UnLock(void)
                    862: {
1.1.1.2   root      863:   if( SDL_MUSTLOCK(sdlscrn) )
1.1.1.3   root      864:     SDL_UnlockSurface(sdlscrn);
1.1       root      865: }
                    866: 
1.1.1.2   root      867: 
                    868: /*-----------------------------------------------------------------------*/
1.1       root      869: /*
                    870:   Blit our converted ST screen to window/full-screen
1.1.1.3   root      871:   Note that our source image includes all borders so if have them disabled simply blit a smaller source rectangle!
1.1       root      872: */
                    873: void Screen_Blit(BOOL bSwapScreen)
                    874: {
1.1.1.3   root      875:   /* Rectangle areas to Blit according to if overscan is enabled or not (source always includes all borders) */
1.1.1.7 ! root      876: /*   static SDL_Rect SrcWindowBitmapSizes[] = */
        !           877: /*   { */
        !           878: /*     { OVERSCAN_LEFT,OVERSCAN_TOP, 320,200 },                /\* ST_LOW_RES *\/ */
        !           879: /*     { (OVERSCAN_LEFT<<1),(OVERSCAN_TOP<<1), 640,400 },      /\* ST_MEDIUM_RES *\/ */
        !           880: /*     { 0,0, 640,400 },                                       /\* ST_HIGH_RES *\/ */
        !           881: /*     { (OVERSCAN_LEFT<<1),(OVERSCAN_BOTTOM<<1), 640,400 },   /\* ST_LOWMEDIUM_MIX_RES *\/ */
        !           882: /*   }; */
        !           883:   static SDL_Rect SrcWindowBitmapSizes[] =
        !           884:   {
        !           885:     { 0,0, 320,200 },                /* ST_LOW_RES */
        !           886:     { 0,0, 640,400 },      /* ST_MEDIUM_RES */
1.1.1.5   root      887:     { 0,0, 640,400 },                                       /* ST_HIGH_RES */
1.1.1.7 ! root      888:     { 0,0, 640,400 },   /* ST_LOWMEDIUM_MIX_RES */
1.1       root      889:   };
1.1.1.7 ! root      890: 
        !           891:   static SDL_Rect SrcWindowOverscanBitmapSizes[] =
        !           892:   {
1.1.1.5   root      893:     { 0,0, OVERSCAN_LEFT+320+OVERSCAN_RIGHT,OVERSCAN_TOP+200+OVERSCAN_BOTTOM },
                    894:     { 0,0, (OVERSCAN_LEFT<<1)+640+(OVERSCAN_RIGHT<<1),(OVERSCAN_TOP<<1)+400+(OVERSCAN_BOTTOM<<1) },
                    895:     { 0,0, 640,400 },
                    896:     { 0,0, (OVERSCAN_LEFT<<1)+640+(OVERSCAN_RIGHT<<1),(OVERSCAN_TOP<<1)+400+(OVERSCAN_BOTTOM<<1) },
1.1       root      897:   };
1.1.1.3   root      898: 
1.1       root      899:   unsigned char *pSTScreen;
1.1.1.3   root      900:   SDL_Rect *SrcRect;
1.1       root      901: 
1.1.1.3   root      902:   /* Blit to full screen or window? */
1.1.1.7 ! root      903:   if (bInFullScreen)
        !           904:   {
1.1.1.3   root      905:     /* Swap screen */
1.1       root      906:     if (bSwapScreen)
1.1.1.3   root      907:       SDL_Flip(sdlscrn);
1.1       root      908:   }
1.1.1.7 ! root      909:   else
        !           910:   {
1.1.1.3   root      911:     /* VDI resolution? */
1.1.1.7 ! root      912:     if (bUseVDIRes || ConfigureParams.Screen.bUseHighRes)
        !           913:     {
1.1.1.3   root      914:       /* Show VDI or mono resolution, no overscan */
                    915:       SDL_UpdateRect(sdlscrn, 0,0,0,0);
1.1       root      916:     }
1.1.1.7 ! root      917:     else
        !           918:     {
        !           919:       /* Find rectangle to draw from... */
        !           920:       if (ConfigureParams.Screen.bAllowOverscan)
        !           921:         SrcRect = &SrcWindowOverscanBitmapSizes[STRes];
        !           922:       else
        !           923:         SrcRect = &SrcWindowBitmapSizes[STRes];
        !           924: 
        !           925:       /* Blit image */
        !           926:       SDL_UpdateRect(sdlscrn, 0,0,0,0);
        !           927:       //SDL_UpdateRects(sdlscrn, 1, SrcRect);
1.1       root      928:     }
                    929:   }
                    930: 
1.1.1.3   root      931:   /* Swap copy/raster buffers in screen. */
1.1       root      932:   pSTScreen = pFrameBuffer->pSTScreenCopy;
                    933:   pFrameBuffer->pSTScreenCopy = pFrameBuffer->pSTScreen;
                    934:   pFrameBuffer->pSTScreen = pSTScreen;
                    935: }
                    936: 
1.1.1.3   root      937: 
1.1.1.2   root      938: /*-----------------------------------------------------------------------*/
1.1       root      939: /*
                    940:   Swap ST Buffers, used for full-screen where have double-buffering
                    941: */
                    942: void Screen_SwapSTBuffers(void)
                    943: {
1.1.1.7 ! root      944: #if NUM_FRAMEBUFFERS > 1
        !           945:   if (bInFullScreen)
        !           946:   {
1.1       root      947:     if (pFrameBuffer==&FrameBuffers[0])
                    948:       pFrameBuffer = &FrameBuffers[1];
                    949:     else
                    950:       pFrameBuffer = &FrameBuffers[0];
                    951:   }
1.1.1.7 ! root      952: #endif
1.1       root      953: }
                    954: 
                    955: 
1.1.1.2   root      956: /*-----------------------------------------------------------------------*/
1.1       root      957: /*
                    958:   Draw ST screen to window/full-screen framebuffer
                    959: */
                    960: void Screen_DrawFrame(BOOL bForceFlip)
                    961: {
                    962:   void *pDrawFunction;
1.1.1.7 ! root      963:   static void *last;
1.1       root      964: 
1.1.1.2   root      965:   /* Scan palette/resolution masks for each line and build up palette/difference tables */
1.1       root      966:   STRes = Screen_ComparePaletteMask();
1.1.1.2   root      967:   /* Do require palette? Check if changed and update */
1.1       root      968:   Screen_Handle8BitPalettes();
1.1.1.2   root      969:   /* Did we change resolution this frame - allocate new screen if did so */
1.1       root      970:   Screen_DidResolutionChange();
1.1.1.2   root      971:   /* Is need full-update, tag as such */
1.1       root      972:   if (pFrameBuffer->bFullUpdate)
                    973:     Screen_SetFullUpdateMask();
                    974: 
                    975:   /* Lock screen ready for drawing */
                    976:   if (Screen_Lock()) {
1.1.1.2   root      977:     bScreenContentsChanged = FALSE;      /* Did change(ie needs blit?) */
1.1.1.7 ! root      978:     /* Set details */
        !           979:     if (ConfigureParams.Screen.bAllowOverscan)
        !           980:     {
        !           981:       Screen_SetWindowConvertDetails();
        !           982:       pPCScreenDest = (unsigned char *)sdlscrn->pixels;  /* Destination PC screen */
        !           983:     }
        !           984:     else
        !           985:     {
1.1       root      986:       Screen_SetFullScreenConvertDetails();
1.1.1.7 ! root      987:     }
        !           988:     /* Clear screen on full update to clear out borders and also interlaced lines */
        !           989:     if (pFrameBuffer->bFullUpdate && !bUseVDIRes)
        !           990:       Screen_ClearScreen();
        !           991:     /* Call drawing for full-screen */
        !           992:     if (bUseVDIRes)  {
        !           993:       pDrawFunction = ScreenDrawVDIFullScreen[VDIRes].pDrawFunction;
1.1       root      994:     }
                    995:     else {
1.1.1.7 ! root      996:       pDrawFunction = ScreenDrawFullScreen[STRes].pDrawFunction;
        !           997:       /* Check if is Spec512 image */
        !           998:       if (Spec512_IsImage()) {
        !           999:        /* What mode were we in? Keep to 320xH or 640xH */
        !          1000:        if (pDrawFunction==ConvertLowRes_320x16Bit)
        !          1001:          pDrawFunction = ConvertSpec512_320x16Bit;
        !          1002:        else if (pDrawFunction==ConvertLowRes_640x16Bit)
        !          1003:          pDrawFunction = ConvertSpec512_640x16Bit;
1.1       root     1004:       }
                   1005:     }
                   1006: 
1.1.1.7 ! root     1007:     if (pDrawFunction)
        !          1008:       CALL_VAR(pDrawFunction)
        !          1009: 
1.1.1.2   root     1010:     /* Unlock screen */
1.1       root     1011:     Screen_UnLock();
1.1.1.2   root     1012:     /* Clear flags, remember type of overscan as if change need screen full update */
1.1       root     1013:     pFrameBuffer->bFullUpdate = FALSE;
                   1014:     pFrameBuffer->OverscanModeCopy = OverscanMode;
                   1015: 
1.1.1.2   root     1016:     /* And show to user */
1.1       root     1017:     if (bScreenContentsChanged || bForceFlip) {
                   1018:       if (bInFullScreen)
                   1019:         Screen_SwapSTBuffers();
                   1020:       Screen_Blit(TRUE);
                   1021:     }
                   1022: 
1.1.1.3   root     1023:     /* Grab any animation */
                   1024:     if(bRecordingAnimation)
1.1       root     1025:       ScreenSnapShot_RecordFrame(bScreenContentsChanged);
                   1026:   }
                   1027: }
                   1028: 
1.1.1.2   root     1029: /*-----------------------------------------------------------------------*/
1.1       root     1030: /*
                   1031:   Draw ST screen to window/full-screen
                   1032: */
                   1033: void Screen_Draw(void)
                   1034: {
                   1035:   /* Are we holding screen? Ie let user choose options while in full-screen mode using GDI */
1.1.1.5   root     1036:   if (bInFullScreen && bFullScreenHold)
                   1037:   {
1.1.1.2   root     1038:     /* Just update status bar */
1.1.1.4   root     1039:     /*StatusBar_UpdateIcons();*/ /* No statusbar in Hatari */
1.1       root     1040:     return;
                   1041:   }
                   1042: 
1.1.1.5   root     1043:   if (!bQuitProgram)
                   1044:   {
1.1       root     1045: #if 0
1.1.1.4   root     1046:     /* Wait for next display(at 50fps), is ignored if running max speed */
1.1.1.7 ! root     1047:     if ( !(ConfigureParams.Screen.bSyncToRetrace && bInFullScreen) )
1.1.1.5   root     1048:     {
1.1.1.2   root     1049:       /* If in Max speed mode, just get on with it, or else wait for VBL timer */
1.1.1.5   root     1050:       if (ConfigureParams.Configure.nMinMaxSpeed!=MINMAXSPEED_MAX)
                   1051:       {
1.1       root     1052:         /* Has VBL already occured? Means we can't keep 50fps to warn user */
1.1.1.5   root     1053:         if (Main_AlreadyWaitingVBLEvent())
                   1054:         {
1.1       root     1055:           /* Increase counter for number of consecutive dropped frames */
                   1056:           nDroppedFrames++;
                   1057:           /* If emulation has gone slow for 1/2 second or more, inform user */
1.1.1.4   root     1058:           /*if (nDroppedFrames>=25)
                   1059:             StatusBar_SetIcon(STATUS_ICON_FRAMERATE,ICONSTATE_UPDATE);*/ /* No statusbar in Hatari yet */
1.1       root     1060:         }
                   1061:         else
                   1062:           nDroppedFrames = 0;
                   1063:         /* Wait for VBL event */
                   1064:         Main_WaitVBLEvent();
                   1065:       }
                   1066:     }
1.1.1.4   root     1067: #endif
1.1       root     1068: 
1.1.1.5   root     1069:     if(VideoBase)
1.1       root     1070:     {
                   1071:       /* And draw(if screen contents changed) */
                   1072:       Screen_DrawFrame(FALSE);
                   1073: 
                   1074:       /* And status bar */
1.1.1.4   root     1075:       /*StatusBar_UpdateIcons();*/ /* Sorry - no statusbar in Hatari yet */
1.1       root     1076:     }
                   1077: 
1.1.1.2   root     1078:     /* Check printer status */
1.1       root     1079:     Printer_CheckIdleStatus();
                   1080:   }
                   1081: 
                   1082: }

unix.superglobalmegacorp.com

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