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