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

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

unix.superglobalmegacorp.com

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