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