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