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