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