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