|
|
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
1.1.1.11 root 8: format. An awful lot of processing is needed to do this conversion - we
1.1.1.6 root 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.13! root 22: const char Screen_rcsid[] = "Hatari $Id: screen.c,v 1.76 2008/03/11 14:31:13 thothy Exp $";
1.1 root 23:
24: #include <SDL.h>
1.1.1.11 root 25: #include <SDL_endian.h>
1.1 root 26:
27: #include "main.h"
1.1.1.7 root 28: #include "configuration.h"
1.1 root 29: #include "ikbd.h"
1.1.1.13! root 30: #include "log.h"
1.1 root 31: #include "m68000.h"
32: #include "misc.h"
1.1.1.13! root 33: #include "paths.h"
1.1 root 34: #include "screen.h"
1.1.1.11 root 35: #include "convert/routines.h"
1.1 root 36: #include "screenSnapShot.h"
37: #include "sound.h"
38: #include "spec512.h"
39: #include "vdi.h"
40: #include "video.h"
1.1.1.13! root 41: #include "falcon/videl.h"
! 42: #include "falcon/hostscreen.h"
1.1 root 43:
44:
1.1.1.13! root 45: /* extern for several purposes */
! 46: SDL_Surface *sdlscrn = NULL; /* The SDL screen surface */
! 47: int nScreenZoomX, nScreenZoomY; /* Zooming factors, used for scaling mouse motions */
! 48: int nBorderPixelsLeft, nBorderPixelsRight; /* Pixels in left and right border */
! 49: int nBorderPixelsBottom; /* Lines in bottom border */
! 50:
! 51: /* extern for shortcuts and falcon/hostscreen.c */
1.1.1.11 root 52: BOOL bGrabMouse = FALSE; /* Grab the mouse cursor in the window */
1.1.1.13! root 53: BOOL bInFullScreen = FALSE; /* TRUE if in full screen */
! 54:
! 55: /* extern for spec512.c */
1.1.1.11 root 56: int STScreenLeftSkipBytes;
57: int STScreenStartHorizLine; /* Start lines to be converted */
58: Uint32 STRGBPalette[16]; /* Palette buffer used in conversion routines */
59: Uint32 ST2RGB[4096]; /* Table to convert ST 0x777 / STe 0xfff palette to PC format RGB551 (2 pixels each entry) */
1.1.1.13! root 60:
! 61: /* extern for video.c */
1.1.1.11 root 62: Uint8 *pSTScreen;
63: FRAMEBUFFER *pFrameBuffer; /* Pointer into current 'FrameBuffer' */
64:
65: static FRAMEBUFFER FrameBuffers[NUM_FRAMEBUFFERS]; /* Store frame buffer details to tell how to update */
66: static Uint8 *pSTScreenCopy; /* Keep track of current and previous ST screen data */
67: static Uint8 *pPCScreenDest; /* Destination PC buffer */
68: static int STScreenEndHorizLine; /* End lines to be converted */
69: static int PCScreenBytesPerLine;
70: static int STScreenWidthBytes;
1.1 root 71:
1.1.1.11 root 72: static int STScreenLineOffset[NUM_VISIBLE_LINES]; /* Offsets for ST screen lines eg, 0,160,320... */
73: static Uint16 HBLPalette[16], PrevHBLPalette[16]; /* Current palette for line, also copy of first line */
1.1 root 74:
1.1.1.13! root 75: static void (*ScreenDrawFunctionsNormal[3])(void); /* Screen draw functions */
1.1.1.12 root 76: static void (*ScreenDrawFunctionsVDI[3])(void) =
1.1.1.10 root 77: {
1.1.1.13! root 78: ConvertVDIRes_16Colour,
! 79: ConvertVDIRes_4Colour,
! 80: ConvertVDIRes_2Colour
1.1.1.10 root 81: };
82:
1.1.1.11 root 83: static BOOL bScreenContentsChanged; /* TRUE if buffer changed and requires blitting */
84: static BOOL bScrDoubleY; /* TRUE if double on Y */
85: static int ScrUpdateFlag; /* Bit mask of how to update screen */
86:
1.1.1.10 root 87:
88: /*-----------------------------------------------------------------------*/
1.1.1.13! root 89: /**
! 90: * Create ST 0x777 / STe 0xfff color format to 16 or 32 bits per pixel
! 91: * conversion table. Called each time when changed resolution or to/from
! 92: * fullscreen mode.
! 93: */
1.1.1.10 root 94: static void Screen_SetupRGBTable(void)
95: {
1.1.1.13! root 96: Uint16 STColor;
! 97: Uint32 RGBColor;
! 98: int r, g, b;
! 99: int rr, gg, bb;
! 100:
! 101: /* Do Red, Green and Blue for all 16*16*16 = 4096 STe colors */
! 102: for (r = 0; r < 16; r++)
! 103: {
! 104: for (g = 0; g < 16; g++)
! 105: {
! 106: for (b = 0; b < 16; b++)
! 107: {
! 108: /* STe 0xfff format */
! 109: STColor = (r<<8) | (g<<4) | (b);
! 110: rr = ((r & 0x7) << 5) | ((r & 0x8) << 1);
! 111: gg = ((g & 0x7) << 5) | ((g & 0x8) << 1);
! 112: bb = ((b & 0x7) << 5) | ((b & 0x8) << 1);
! 113: RGBColor = SDL_MapRGB(sdlscrn->format, rr, gg, bb);
! 114: if (sdlscrn->format->BitsPerPixel <= 16)
! 115: {
! 116: /* As longs, for speed (write two pixels at once) */
! 117: ST2RGB[STColor] = (RGBColor<<16) | RGBColor;
! 118: }
! 119: else
! 120: {
! 121: ST2RGB[STColor] = RGBColor;
! 122: }
! 123: }
! 124: }
! 125: }
1.1.1.10 root 126: }
127:
1.1.1.13! root 128:
1.1.1.10 root 129: /*-----------------------------------------------------------------------*/
1.1.1.13! root 130: /**
! 131: * Create new palette for display.
! 132: */
1.1.1.10 root 133: static void Screen_CreatePalette(void)
134: {
135: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1.1.1.13! root 136: static const int endiantable[16] = {0,2,1,3,8,10,9,11,4,6,5,7,12,14,13,15};
1.1.1.10 root 137: #endif
1.1.1.13! root 138: SDL_Color sdlColors[16];
! 139: int i, j;
1.1.1.10 root 140:
1.1.1.13! root 141: if (bUseHighRes)
! 142: {
! 143: /* Colors for monochrome screen mode emulation */
! 144: if (HBLPalettes[0])
! 145: {
! 146: sdlColors[0].r = sdlColors[0].g = sdlColors[0].b = 255;
! 147: sdlColors[1].r = sdlColors[1].g = sdlColors[1].b = 0;
! 148: }
! 149: else
! 150: {
! 151: sdlColors[0].r = sdlColors[0].g = sdlColors[0].b = 0;
! 152: sdlColors[1].r = sdlColors[1].g = sdlColors[1].b = 255;
! 153: }
! 154: SDL_SetColors(sdlscrn, sdlColors, 10, 2);
! 155: /*SDL_SetColors(sdlscrn, sdlColors, 0, 2);*/
! 156: }
! 157: else
! 158: {
! 159: int r, g, b;
! 160: /* Colors for STe color screen mode emulation */
! 161: for (i = 0; i < 16; i++)
! 162: {
1.1.1.11 root 163: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1.1.1.13! root 164: j = endiantable[i];
1.1.1.11 root 165: #else
1.1.1.13! root 166: j = i;
1.1.1.11 root 167: #endif
1.1.1.13! root 168: /* normalize all to 0x1e0 */
! 169: r = HBLPalettes[i] >> 3;
! 170: g = HBLPalettes[i] << 1;
! 171: b = HBLPalettes[i] << 5;
! 172: /* move top bit of 0x1e0 to lowest in 0xf0 */
! 173: sdlColors[j].r = (r & 0xe0) | ((r & 0x100) >> 4);
! 174: sdlColors[j].g = (g & 0xe0) | ((g & 0x100) >> 4);
! 175: sdlColors[j].b = (b & 0xe0) | ((b & 0x100) >> 4);
! 176: }
! 177: SDL_SetColors(sdlscrn, sdlColors, 10, 16);
! 178: }
1.1.1.10 root 179: }
180:
181:
182: /*-----------------------------------------------------------------------*/
1.1.1.13! root 183: /**
! 184: * Create 8-Bit palette for display if needed.
! 185: */
1.1.1.10 root 186: static void Screen_Handle8BitPalettes(void)
187: {
1.1.1.13! root 188: BOOL bPaletteChanged=FALSE;
! 189: int i;
1.1.1.10 root 190:
1.1.1.13! root 191: /* Do need to check for 8-Bit palette change? Ie, update whole screen */
! 192: /* VDI screens and monochrome modes are ALL 8-Bit at the moment! */
! 193: if (sdlscrn->format->BitsPerPixel == 8)
! 194: {
! 195: /* If using HiRes palette update with full update flag */
! 196: if (!bUseHighRes)
! 197: {
! 198: /* Check if palette of 16 colours changed from previous frame */
! 199: for (i = 0; i < 16 && !bPaletteChanged; i++)
! 200: {
! 201: /* Check with first line palette (stored in 'Screen_ComparePaletteMask') */
! 202: if (HBLPalettes[i] != PrevHBLPalette[i])
! 203: bPaletteChanged = TRUE;
! 204: }
! 205: }
! 206:
! 207: /* Did palette change or do we require a full update? */
! 208: if (bPaletteChanged || pFrameBuffer->bFullUpdate)
! 209: {
! 210: /* Create palette, for Full-Screen of Window */
! 211: Screen_CreatePalette();
! 212: /* Make sure update whole screen */
! 213: pFrameBuffer->bFullUpdate = TRUE;
! 214: }
! 215: }
1.1.1.10 root 216:
1.1.1.13! root 217: /* Copy old palette for 8-Bit compare as this routine writes over it */
! 218: memcpy(PrevHBLPalette,HBLPalettes, sizeof(Uint16)*16);
1.1.1.10 root 219: }
220:
1.1 root 221:
222: /*-----------------------------------------------------------------------*/
1.1.1.13! root 223: /**
! 224: * Set screen draw functions.
! 225: */
! 226: static void Screen_SetDrawFunctions(int nBitCount)
1.1.1.10 root 227: {
1.1.1.13! root 228: if (ConfigureParams.Screen.nForceBpp == 8)
! 229: {
! 230: /* Low color */
! 231: if (ConfigureParams.Screen.bZoomLowRes)
! 232: ScreenDrawFunctionsNormal[ST_LOW_RES] = ConvertLowRes_640x8Bit;
! 233: else
! 234: ScreenDrawFunctionsNormal[ST_LOW_RES] = ConvertLowRes_320x8Bit;
! 235: ScreenDrawFunctionsNormal[ST_MEDIUM_RES] = ConvertMediumRes_640x8Bit;
! 236: ScreenDrawFunctionsNormal[ST_HIGH_RES] = ConvertHighRes_640x8Bit;
! 237: }
! 238: else if (nBitCount <= 16)
! 239: {
! 240: /* High color */
! 241: if (ConfigureParams.Screen.bZoomLowRes)
! 242: ScreenDrawFunctionsNormal[ST_LOW_RES] = ConvertLowRes_640x16Bit;
! 243: else
! 244: ScreenDrawFunctionsNormal[ST_LOW_RES] = ConvertLowRes_320x16Bit;
! 245: ScreenDrawFunctionsNormal[ST_MEDIUM_RES] = ConvertMediumRes_640x16Bit;
! 246: ScreenDrawFunctionsNormal[ST_HIGH_RES] = ConvertHighRes_640x8Bit;
! 247: }
! 248: else /* Assume 32 bit drawing functions */
! 249: {
! 250: /* True color */
! 251: if (ConfigureParams.Screen.bZoomLowRes)
! 252: ScreenDrawFunctionsNormal[ST_LOW_RES] = ConvertLowRes_640x32Bit;
! 253: else
! 254: ScreenDrawFunctionsNormal[ST_LOW_RES] = ConvertLowRes_320x32Bit;
! 255: ScreenDrawFunctionsNormal[ST_MEDIUM_RES] = ConvertMediumRes_640x32Bit;
! 256: ScreenDrawFunctionsNormal[ST_HIGH_RES] = ConvertHighRes_640x8Bit;
! 257: }
1.1.1.10 root 258: }
259:
260:
261: /*-----------------------------------------------------------------------*/
1.1.1.13! root 262: /**
! 263: * Set amount of border pixels for windowed and full-screen mode and
! 264: * store Y offset for each horizontal line in our source ST screen for
! 265: * reference in tje convert functions.
! 266: */
! 267: static void Screen_SetSTScreenOffsets(void)
1.1.1.7 root 268: {
1.1.1.13! root 269: int i;
1.1.1.7 root 270:
1.1.1.13! root 271: /* Determine border pixels */
! 272: if (bInFullScreen)
! 273: {
! 274: nBorderPixelsLeft = ConfigureParams.Screen.nFullScreenBorderPixelsLeft;
! 275: nBorderPixelsRight = ConfigureParams.Screen.nFullScreenBorderPixelsRight;
! 276: nBorderPixelsBottom = ConfigureParams.Screen.nFullScreenBorderPixelsBottom;
! 277: }
! 278: else
! 279: {
! 280: nBorderPixelsLeft = ConfigureParams.Screen.nWindowBorderPixelsLeft;
! 281: nBorderPixelsRight = ConfigureParams.Screen.nWindowBorderPixelsRight;
! 282: nBorderPixelsBottom = ConfigureParams.Screen.nWindowBorderPixelsBottom;
! 283: }
! 284:
! 285: /* Store offset to each horizontal line */
! 286: for (i = 0; i < NUM_VISIBLE_LINES; i++)
! 287: {
! 288: STScreenLineOffset[i] = i * SCREENBYTES_LINE;
! 289: }
1.1.1.7 root 290: }
291:
1.1.1.8 root 292:
1.1.1.7 root 293: /*-----------------------------------------------------------------------*/
1.1.1.13! root 294: /**
! 295: * Initialize SDL screen surface / set resolution.
! 296: */
! 297: static void Screen_SetResolution(void)
1.1.1.11 root 298: {
1.1.1.13! root 299: int Width, Height, BitCount;
! 300: unsigned int sdlVideoFlags;
! 301:
! 302: Screen_SetSTScreenOffsets();
1.1.1.11 root 303:
1.1.1.13! root 304: /* Determine which resolution to use */
! 305: if (bUseVDIRes)
! 306: {
! 307: Width = VDIWidth;
! 308: Height = VDIHeight;
! 309: }
! 310: else
! 311: {
! 312: if (STRes == ST_LOW_RES && !ConfigureParams.Screen.bZoomLowRes)
! 313: {
! 314: Width = 320;
! 315: Height = 200;
! 316: }
! 317: else /* else use 640x400 */
! 318: {
! 319: Width = 640;
! 320: Height = 400;
! 321: }
! 322:
! 323: /* Adjust width/height for overscan borders, if mono or VDI we have no overscan */
! 324: if (ConfigureParams.Screen.bAllowOverscan && !bUseHighRes)
! 325: {
! 326: int nZoom = ((Width == 640) ? 2 : 1);
! 327: /* Add in overscan borders (if 640x200 bitmap is double on Y) */
! 328: Width += (nBorderPixelsLeft+nBorderPixelsRight) * nZoom;
! 329: Height += (OVERSCAN_TOP+nBorderPixelsBottom) * nZoom;
! 330: }
! 331: }
! 332:
! 333: /* Bits per pixel */
! 334: if (ConfigureParams.Screen.nForceBpp == 8 || STRes == ST_HIGH_RES || bUseVDIRes)
! 335: {
! 336: BitCount = 8;
! 337: }
! 338: else
! 339: {
! 340: BitCount = ConfigureParams.Screen.nForceBpp;
! 341: }
! 342:
! 343: /* Set zoom factors, used for scaling mouse motions */
! 344: if (STRes == ST_LOW_RES && ConfigureParams.Screen.bZoomLowRes && !bUseVDIRes)
! 345: {
! 346: nScreenZoomX = 2;
! 347: nScreenZoomY = 2;
! 348: }
! 349: else if (STRes == ST_MEDIUM_RES && !bUseVDIRes)
! 350: {
! 351: nScreenZoomX = 1;
! 352: nScreenZoomY = 2;
! 353: }
! 354: else
! 355: {
! 356: nScreenZoomX = 1;
! 357: nScreenZoomY = 1;
! 358: }
! 359:
! 360: /* SDL Video attributes: */
! 361: if (bInFullScreen)
! 362: {
! 363: sdlVideoFlags = SDL_HWSURFACE|SDL_FULLSCREEN|SDL_HWPALETTE/*|SDL_DOUBLEBUF*/;
! 364: /* SDL_DOUBLEBUF is a good idea, but the GUI doesn't work with double buffered
! 365: * screens yet, so double buffering is currently disabled. */
! 366: }
! 367: else
! 368: {
! 369: sdlVideoFlags = SDL_SWSURFACE|SDL_HWPALETTE;
! 370: }
! 371:
! 372: /* Check if we really have to change the video mode: */
! 373: if (!sdlscrn || sdlscrn->w != Width || sdlscrn->h != Height
! 374: || sdlscrn->format->BitsPerPixel != BitCount
! 375: || (sdlscrn->flags&SDL_FULLSCREEN) != (sdlVideoFlags&SDL_FULLSCREEN))
! 376: {
! 377: /* Set new video mode */
! 378: //fprintf(stderr,"Requesting video mode %i %i %i\n", Width, Height, BitCount);
! 379: sdlscrn = SDL_SetVideoMode(Width, Height, BitCount, sdlVideoFlags);
! 380: //fprintf(stderr,"Got video mode %i %i %i\n", sdlscrn->w, sdlscrn->h, sdlscrn->format->BitsPerPixel);
! 381: /* We do not support 24 bpp (yet) */
! 382: if (sdlscrn && sdlscrn->format->BitsPerPixel == 24)
! 383: {
! 384: fprintf(stderr, "Unsupported color depth 24, trying 32 bpp instead...\n");
! 385: sdlscrn = SDL_SetVideoMode(Width, Height, 32, sdlVideoFlags);
! 386: }
! 387: /* Exit if we can not open a screen */
! 388: if (!sdlscrn)
! 389: {
! 390: fprintf(stderr, "Could not set video mode:\n %s\n", SDL_GetError() );
! 391: SDL_Quit();
! 392: exit(-2);
! 393: }
! 394:
! 395: /* Re-init screen palette: */
! 396: if (BitCount == 8)
! 397: Screen_Handle8BitPalettes(); /* Initialize new 8 bit palette */
! 398: else
! 399: Screen_SetupRGBTable(); /* Create color convertion table */
! 400:
! 401: /* Un-grab mouse pointer in windowed mode: */
! 402: if (!bGrabMouse)
! 403: SDL_WM_GrabInput(SDL_GRAB_OFF);
! 404: }
! 405:
! 406: /* Set drawing functions */
! 407: Screen_SetDrawFunctions(sdlscrn->format->BitsPerPixel);
! 408:
! 409: Screen_SetFullUpdate(); /* Cause full update of screen */
1.1.1.11 root 410: }
411:
412:
413: /*-----------------------------------------------------------------------*/
1.1.1.13! root 414: /**
! 415: * Init Screen bitmap and buffers/tables needed for ST to PC screen conversion
! 416: */
1.1 root 417: void Screen_Init(void)
418: {
1.1.1.13! root 419: int i;
! 420: SDL_Surface *pIconSurf;
! 421: char sIconFileName[FILENAME_MAX];
! 422:
! 423: /* Clear frame buffer structures and set current pointer */
! 424: memset(FrameBuffers, 0, NUM_FRAMEBUFFERS * sizeof(FRAMEBUFFER));
! 425:
! 426: /* Allocate previous screen check workspace. We are going to double-buffer a double-buffered screen. Oh. */
! 427: for (i = 0; i < NUM_FRAMEBUFFERS; i++)
! 428: {
! 429: FrameBuffers[i].pSTScreen = malloc(((MAX_VDI_WIDTH*MAX_VDI_PLANES)/8)*MAX_VDI_HEIGHT);
! 430: FrameBuffers[i].pSTScreenCopy = malloc(((MAX_VDI_WIDTH*MAX_VDI_PLANES)/8)*MAX_VDI_HEIGHT);
! 431: if (!FrameBuffers[i].pSTScreen || !FrameBuffers[i].pSTScreenCopy)
! 432: {
! 433: fprintf(stderr, "Failed to allocate frame buffer memory.\n");
! 434: exit(-1);
! 435: }
! 436: }
! 437: pFrameBuffer = &FrameBuffers[0];
! 438:
! 439: /* Load and set icon */
! 440: snprintf(sIconFileName, sizeof(sIconFileName), "%s%chatari-icon.bmp",
! 441: Paths_GetDataDir(), PATHSEP);
! 442: pIconSurf = SDL_LoadBMP(sIconFileName);
! 443: if (pIconSurf)
! 444: {
! 445: SDL_SetColorKey(pIconSurf, SDL_SRCCOLORKEY, SDL_MapRGB(pIconSurf->format, 255, 255, 255));
! 446: SDL_WM_SetIcon(pIconSurf, NULL);
! 447: SDL_FreeSurface(pIconSurf);
! 448: }
! 449:
! 450: /* Set initial window resolution */
! 451: bInFullScreen = ConfigureParams.Screen.bFullScreen;
! 452: Screen_SetResolution();
! 453:
! 454: Video_SetScreenRasters(); /* Set rasters ready for first screen */
! 455:
! 456: /* Configure some SDL stuff: */
! 457: SDL_WM_SetCaption(PROG_NAME, "Hatari");
! 458: SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
! 459: SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_ENABLE);
! 460: SDL_EventState(SDL_MOUSEBUTTONUP, SDL_ENABLE);
! 461: SDL_ShowCursor(SDL_DISABLE);
1.1 root 462: }
463:
1.1.1.2 root 464:
1.1 root 465: /*-----------------------------------------------------------------------*/
1.1.1.13! root 466: /**
! 467: * Free screen bitmap and allocated resources
! 468: */
1.1 root 469: void Screen_UnInit(void)
470: {
1.1.1.13! root 471: int i;
1.1 root 472:
1.1.1.13! root 473: /* Free memory used for copies */
! 474: for (i = 0; i < NUM_FRAMEBUFFERS; i++)
! 475: {
! 476: free(FrameBuffers[i].pSTScreen);
! 477: free(FrameBuffers[i].pSTScreenCopy);
! 478: }
1.1 root 479: }
480:
1.1.1.2 root 481:
1.1 root 482: /*-----------------------------------------------------------------------*/
1.1.1.13! root 483: /**
! 484: * Reset screen
! 485: */
1.1 root 486: void Screen_Reset(void)
487: {
1.1.1.13! root 488: /* On re-boot, always correct ST resolution for monitor, eg Colour/Mono */
! 489: if (bUseVDIRes)
! 490: {
! 491: STRes = VDIRes;
! 492: }
! 493: else
! 494: {
! 495: if (bUseHighRes)
! 496: {
! 497: STRes = ST_HIGH_RES;
! 498: TTRes = TT_HIGH_RES;
! 499: }
! 500: else
! 501: {
! 502: STRes = ST_LOW_RES;
! 503: TTRes = TT_MEDIUM_RES;
! 504: }
! 505: }
! 506: /* Cause full update */
! 507: Screen_ModeChanged();
1.1 root 508: }
509:
510:
511: /*-----------------------------------------------------------------------*/
1.1.1.13! root 512: /**
! 513: * Set flags so screen will be TOTALLY re-drawn (clears whole of full-screen)
! 514: * next time around
! 515: */
1.1 root 516: void Screen_SetFullUpdate(void)
517: {
1.1.1.13! root 518: int i;
1.1 root 519:
1.1.1.13! root 520: /* Update frame buffers */
! 521: for (i = 0; i < NUM_FRAMEBUFFERS; i++)
! 522: FrameBuffers[i].bFullUpdate = TRUE;
1.1 root 523: }
524:
1.1.1.5 root 525:
1.1 root 526: /*-----------------------------------------------------------------------*/
1.1.1.13! root 527: /**
! 528: * Clear Window display memory
! 529: */
1.1.1.11 root 530: static void Screen_ClearScreen(void)
531: {
1.1.1.13! root 532: SDL_FillRect(sdlscrn,NULL, SDL_MapRGB(sdlscrn->format, 0, 0, 0) );
1.1.1.11 root 533: }
534:
535: /*-----------------------------------------------------------------------*/
1.1.1.13! root 536: /**
! 537: * Enter Full screen mode
! 538: */
1.1 root 539: void Screen_EnterFullScreen(void)
540: {
1.1.1.13! root 541: if (!bInFullScreen)
! 542: {
! 543: Main_PauseEmulation(); /* Hold things... */
! 544: bInFullScreen = TRUE;
1.1.1.2 root 545:
1.1.1.13! root 546: if ((ConfigureParams.System.nMachineType == MACHINE_FALCON
! 547: || ConfigureParams.System.nMachineType == MACHINE_TT) && !bUseVDIRes)
! 548: {
! 549: HostScreen_toggleFullScreen();
! 550: }
! 551: else
! 552: {
! 553: Screen_SetResolution();
! 554: Screen_ClearScreen(); /* Black out screen bitmap as will be invalid when return */
! 555: }
1.1 root 556:
1.1.1.13! root 557: SDL_Delay(20); /* To give monitor time to change to new resolution */
! 558: Main_UnPauseEmulation(); /* And off we go... */
1.1.1.2 root 559:
1.1.1.13! root 560: SDL_WM_GrabInput(SDL_GRAB_ON); /* Grab mouse pointer in fullscreen */
! 561: }
1.1 root 562: }
563:
1.1.1.2 root 564:
1.1 root 565: /*-----------------------------------------------------------------------*/
1.1.1.13! root 566: /**
! 567: * Return from Full screen mode back to a window
! 568: */
1.1 root 569: void Screen_ReturnFromFullScreen(void)
570: {
1.1.1.13! root 571: if (bInFullScreen)
! 572: {
! 573: Main_PauseEmulation(); /* Hold things... */
! 574: bInFullScreen = FALSE;
! 575:
! 576: if ((ConfigureParams.System.nMachineType == MACHINE_FALCON
! 577: || ConfigureParams.System.nMachineType == MACHINE_TT) && !bUseVDIRes)
! 578: {
! 579: HostScreen_toggleFullScreen();
! 580: if (!bGrabMouse)
! 581: SDL_WM_GrabInput(SDL_GRAB_OFF); /* Un-grab mouse pointer in windowed mode */
! 582: }
! 583: else
! 584: {
! 585: Screen_SetResolution();
! 586: }
! 587:
! 588: SDL_Delay(20); /* To give monitor time to switch resolution */
! 589: Main_UnPauseEmulation(); /* And off we go... */
! 590: }
! 591: }
1.1.1.2 root 592:
593:
1.1.1.13! root 594: /*-----------------------------------------------------------------------*/
! 595: /**
! 596: * Have we changed between low/med/high res?
! 597: */
! 598: static void Screen_DidResolutionChange(int new_res)
! 599: {
! 600: if (new_res != STRes)
! 601: {
! 602: STRes = new_res;
! 603: Screen_ModeChanged();
! 604: }
! 605: else
! 606: {
! 607: /* Did change overscan mode? Causes full update */
! 608: if (pFrameBuffer->OverscanModeCopy != OverscanMode)
! 609: pFrameBuffer->bFullUpdate = TRUE;
! 610: }
1.1 root 611: }
612:
1.1.1.5 root 613:
1.1.1.2 root 614: /*-----------------------------------------------------------------------*/
1.1.1.13! root 615: /**
! 616: * Force things associated with changing between low/medium/high res.
! 617: */
! 618: void Screen_ModeChanged(void)
1.1 root 619: {
1.1.1.13! root 620: if (!sdlscrn)
! 621: {
! 622: /* screen not yet initialized */
! 623: return;
! 624: }
! 625: /* Don't run this function if Videl emulation is running! */
! 626: if (ConfigureParams.System.nMachineType == MACHINE_FALCON && !bUseVDIRes)
! 627: {
! 628: VIDEL_ZoomModeChanged();
! 629: return;
! 630: }
! 631: else if (ConfigureParams.System.nMachineType == MACHINE_TT && !bUseVDIRes)
! 632: {
! 633: int width, height, bpp;
! 634: Video_GetTTRes(&width, &height, &bpp);
! 635: HostScreen_setWindowSize(width, height, 8);
! 636: return;
! 637: }
! 638: /* Set new display mode, if differs from current */
! 639: Screen_SetResolution();
! 640: Screen_SetFullUpdate();
1.1 root 641: }
642:
1.1.1.2 root 643:
644: /*-----------------------------------------------------------------------*/
1.1.1.13! root 645: /**
! 646: * Compare current resolution on line with previous, and set 'UpdateLine' accordingly
! 647: * Return if swap between low/medium resolution
! 648: */
! 649: static BOOL Screen_CompareResolution(int y, int *pUpdateLine, int oldres)
1.1 root 650: {
1.1.1.13! root 651: /* Check if wrote to resolution register */
! 652: if (HBLPaletteMasks[y]&PALETTEMASK_RESOLUTION) /* See 'Intercept_ShifterMode_WriteByte' */
! 653: {
! 654: int newres = (HBLPaletteMasks[y]>>16)&ST_MEDIUM_RES_BIT;
! 655: /* Did resolution change? */
! 656: if (newres != (int)((pFrameBuffer->HBLPaletteMasks[y]>>16)&ST_MEDIUM_RES_BIT))
! 657: *pUpdateLine |= PALETTEMASK_UPDATERES;
! 658: else
! 659: *pUpdateLine &= ~PALETTEMASK_UPDATERES;
! 660: /* Have used any low/medium res mix? */
! 661: return (newres != (oldres&ST_MEDIUM_RES_BIT));
! 662: }
! 663: return FALSE;
1.1 root 664: }
665:
1.1.1.7 root 666:
1.1.1.2 root 667: /*-----------------------------------------------------------------------*/
1.1.1.13! root 668: /**
! 669: * Check to see if palette changes cause screen update and keep 'HBLPalette[]' up-to-date
! 670: */
1.1.1.8 root 671: static void Screen_ComparePalette(int y, int *pUpdateLine)
1.1 root 672: {
1.1.1.13! root 673: BOOL bPaletteChanged = FALSE;
! 674: int i;
1.1 root 675:
1.1.1.13! root 676: /* Did write to palette in this or previous frame? */
! 677: if (((HBLPaletteMasks[y]|pFrameBuffer->HBLPaletteMasks[y])&PALETTEMASK_PALETTE)!=0)
! 678: {
! 679: /* Check and update ones which changed */
! 680: for (i = 0; i < 16; i++)
! 681: {
! 682: if (HBLPaletteMasks[y]&(1<<i)) /* Update changes in ST palette */
! 683: HBLPalette[i] = HBLPalettes[(y*16)+i];
! 684: }
! 685: /* Now check with same palette from previous frame for any differences(may be changing palette back) */
! 686: for (i = 0; (i < 16) && (!bPaletteChanged); i++)
! 687: {
! 688: if (HBLPalette[i]!=pFrameBuffer->HBLPalettes[(y*16)+i])
! 689: bPaletteChanged = TRUE;
! 690: }
! 691: if (bPaletteChanged)
! 692: *pUpdateLine |= PALETTEMASK_UPDATEPAL;
! 693: else
! 694: *pUpdateLine &= ~PALETTEMASK_UPDATEPAL;
! 695: }
1.1 root 696: }
697:
1.1.1.7 root 698:
1.1.1.2 root 699: /*-----------------------------------------------------------------------*/
1.1.1.13! root 700: /**
! 701: * Check for differences in Palette and Resolution from Mask table and update
! 702: * and store off which lines need updating and create full-screen palette.
! 703: * (It is very important for these routines to check for colour changes with
! 704: * the previous screen so only the very minimum parts are updated).
! 705: * Return new STRes value.
! 706: */
! 707: static int Screen_ComparePaletteMask(int res)
1.1 root 708: {
1.1.1.13! root 709: BOOL bLowMedMix = FALSE;
! 710: int LineUpdate = 0;
! 711: int y;
! 712:
! 713: /* Set for monochrome? */
! 714: if (bUseHighRes)
! 715: {
! 716: OverscanMode = OVERSCANMODE_NONE;
! 717:
! 718: /* Just copy mono colours, 0x777 checked also in convert/vdi2.c */
! 719: if (HBLPalettes[0] & 0x777)
! 720: {
! 721: HBLPalettes[0] = 0x777;
! 722: HBLPalettes[1] = 0x000;
! 723: }
! 724: else
! 725: {
! 726: HBLPalettes[0] = 0x000;
! 727: HBLPalettes[1] = 0x777;
! 728: }
! 729:
! 730: /* Colors changed? */
! 731: if (HBLPalettes[0] != PrevHBLPalette[0])
! 732: pFrameBuffer->bFullUpdate = TRUE;
! 733:
! 734: /* Set bit to flag 'full update' */
! 735: if (pFrameBuffer->bFullUpdate)
! 736: ScrUpdateFlag = PALETTEMASK_UPDATEFULL;
! 737: else
! 738: ScrUpdateFlag = 0x00000000;
! 739: }
! 740:
! 741: /* Use VDI resolution? */
! 742: if (bUseVDIRes)
! 743: {
! 744: /* Force to VDI resolution screen, without overscan */
! 745: res = VDIRes;
! 746:
! 747: /* Colors changed? */
! 748: if (HBLPalettes[0] != PrevHBLPalette[0])
! 749: pFrameBuffer->bFullUpdate = TRUE;
! 750:
! 751: /* Set bit to flag 'full update' */
! 752: if (pFrameBuffer->bFullUpdate)
! 753: ScrUpdateFlag = PALETTEMASK_UPDATEFULL;
! 754: else
! 755: ScrUpdateFlag = 0x00000000;
! 756: }
! 757: /* Are in Mono? Force to monochrome and no overscan */
! 758: else if (bUseHighRes)
! 759: {
! 760: /* Force to standard hi-resolution screen, without overscan */
! 761: res = ST_HIGH_RES;
! 762: }
! 763: else /* Full colour */
! 764: {
! 765: /* Get resolution */
! 766: //res = (HBLPaletteMasks[0]>>16)&ST_RES_MASK;
! 767: /* [NP] keep only low/med bit (could be hires in case of overscan on the 1st line) */
! 768: res = (HBLPaletteMasks[0]>>16)&ST_MEDIUM_RES_BIT;
! 769:
! 770: /* Do all lines - first is tagged as full-update */
! 771: for (y = 0; y < NUM_VISIBLE_LINES; y++)
! 772: {
! 773: /* Find any resolution/palette change and update palette/mask buffer */
! 774: /* ( LineUpdate has top two bits set to say if line needs updating due to palette or resolution change ) */
! 775: bLowMedMix |= Screen_CompareResolution(y, &LineUpdate, res);
! 776: Screen_ComparePalette(y,&LineUpdate);
! 777: HBLPaletteMasks[y] = (HBLPaletteMasks[y]&(~PALETTEMASK_UPDATEMASK)) | LineUpdate;
! 778: /* Copy palette and mask for next frame */
! 779: memcpy(&pFrameBuffer->HBLPalettes[y*16],HBLPalette,sizeof(short int)*16);
! 780: pFrameBuffer->HBLPaletteMasks[y] = HBLPaletteMasks[y];
! 781: }
! 782: /* Did mix/have medium resolution? */
! 783: if (bLowMedMix || (res & ST_MEDIUM_RES_BIT))
! 784: res = ST_MEDIUM_RES;
! 785: }
! 786:
! 787: return res;
! 788: }
! 789:
! 790:
! 791: /*-----------------------------------------------------------------------*/
! 792: /**
! 793: * Update Palette Mask to show 'full-update' required. This is usually done after a resolution change
! 794: * or when going between a Window and full-screen display
! 795: */
1.1.1.8 root 796: static void Screen_SetFullUpdateMask(void)
1.1 root 797: {
1.1.1.13! root 798: int y;
1.1 root 799:
1.1.1.13! root 800: for (y = 0; y < NUM_VISIBLE_LINES; y++)
! 801: HBLPaletteMasks[y] |= PALETTEMASK_UPDATEFULL;
1.1 root 802: }
803:
1.1.1.7 root 804:
1.1.1.2 root 805: /*-----------------------------------------------------------------------*/
1.1.1.13! root 806: /**
! 807: * Set details for ST screen conversion.
! 808: */
1.1.1.10 root 809: static void Screen_SetConvertDetails(void)
1.1 root 810: {
1.1.1.13! root 811: pSTScreen = pFrameBuffer->pSTScreen; /* Source in ST memory */
! 812: pSTScreenCopy = pFrameBuffer->pSTScreenCopy; /* Previous ST screen */
! 813: pPCScreenDest = sdlscrn->pixels; /* Destination PC screen */
! 814:
! 815: PCScreenBytesPerLine = sdlscrn->pitch; /* Bytes per line */
! 816: pHBLPalettes = pFrameBuffer->HBLPalettes; /* HBL palettes pointer */
! 817: /* Not in TV-Mode? Then double up on Y: */
! 818: bScrDoubleY = !(ConfigureParams.Screen.MonitorType == MONITOR_TYPE_TV);
! 819:
! 820: if (bUseVDIRes)
! 821: {
! 822: /* Select screen draw for standard or VDI display */
! 823: STScreenLeftSkipBytes = 0;
! 824: STScreenWidthBytes = VDIWidth * VDIPlanes / 8;
! 825: STScreenStartHorizLine = 0;
! 826: STScreenEndHorizLine = VDIHeight;
! 827: }
! 828: else
! 829: {
! 830: if (ConfigureParams.Screen.bAllowOverscan) /* Use borders? */
! 831: {
! 832: /* Always draw to WHOLE screen including ALL borders */
! 833: STScreenLeftSkipBytes = 0; /* Number of bytes to skip on ST screen for left (border) */
! 834: STScreenStartHorizLine = 0; /* Full height */
! 835:
! 836: if (bUseHighRes)
! 837: {
! 838: pFrameBuffer->OverscanModeCopy = OverscanMode = OVERSCANMODE_NONE;
! 839: STScreenEndHorizLine = 400;
! 840: }
! 841: else
! 842: {
! 843: STScreenWidthBytes = SCREENBYTES_LINE; /* Number of horizontal bytes in our ST screen */
! 844: STScreenEndHorizLine = NUM_VISIBLE_LINES;
! 845: }
! 846: }
! 847: else
! 848: {
! 849: /* Only draw main area and centre on Y */
! 850: STScreenLeftSkipBytes = SCREENBYTES_LEFT;
! 851: STScreenWidthBytes = SCREENBYTES_MIDDLE;
! 852: STScreenStartHorizLine = OVERSCAN_TOP;
! 853: STScreenEndHorizLine = OVERSCAN_TOP + (bUseHighRes ? 400 : 200);
! 854: }
! 855: }
1.1 root 856: }
857:
1.1.1.2 root 858:
859: /*-----------------------------------------------------------------------*/
1.1.1.13! root 860: /**
! 861: * Lock full-screen for drawing
! 862: */
1.1.1.8 root 863: static BOOL Screen_Lock(void)
1.1 root 864: {
1.1.1.13! root 865: if (SDL_MUSTLOCK(sdlscrn))
! 866: {
! 867: if (SDL_LockSurface(sdlscrn))
! 868: {
! 869: Screen_ReturnFromFullScreen(); /* All OK? If not need to jump back to a window */
! 870: return(FALSE);
! 871: }
! 872: }
1.1.1.2 root 873:
1.1.1.13! root 874: return TRUE;
1.1 root 875: }
876:
1.1.1.2 root 877: /*-----------------------------------------------------------------------*/
1.1.1.13! root 878: /**
! 879: * UnLock full-screen
! 880: */
1.1.1.8 root 881: static void Screen_UnLock(void)
1.1 root 882: {
1.1.1.13! root 883: if ( SDL_MUSTLOCK(sdlscrn) )
! 884: SDL_UnlockSurface(sdlscrn);
1.1 root 885: }
886:
1.1.1.2 root 887:
888: /*-----------------------------------------------------------------------*/
1.1.1.13! root 889: /**
! 890: * Swap ST Buffers, used for full-screen where have double-buffering
! 891: */
1.1.1.11 root 892: static void Screen_SwapSTBuffers(void)
893: {
894: #if NUM_FRAMEBUFFERS > 1
1.1.1.13! root 895: if (sdlscrn->flags & SDL_DOUBLEBUF)
! 896: {
! 897: if (pFrameBuffer==&FrameBuffers[0])
! 898: pFrameBuffer = &FrameBuffers[1];
! 899: else
! 900: pFrameBuffer = &FrameBuffers[0];
! 901: }
1.1.1.11 root 902: #endif
903: }
904:
905:
906: /*-----------------------------------------------------------------------*/
1.1.1.13! root 907: /**
! 908: * Blit our converted ST screen to window/full-screen
! 909: * Note that our source image includes all borders so if have them disabled simply blit a smaller source rectangle!
! 910: */
1.1.1.11 root 911: static void Screen_Blit(BOOL bSwapScreen)
1.1 root 912: {
1.1.1.13! root 913: unsigned char *pTmpScreen;
! 914:
! 915: /* Blit to full screen or window? */
! 916: if (bInFullScreen)
! 917: {
! 918: Screen_SwapSTBuffers();
! 919: /* Swap screen */
! 920: if (bSwapScreen)
! 921: SDL_Flip(sdlscrn);
! 922: }
! 923: else
! 924: {
! 925: /* Blit image */
! 926: SDL_UpdateRect(sdlscrn, 0,0,0,0);
! 927: }
! 928:
! 929: /* Swap copy/raster buffers in screen. */
! 930: pTmpScreen = pFrameBuffer->pSTScreenCopy;
! 931: pFrameBuffer->pSTScreenCopy = pFrameBuffer->pSTScreen;
! 932: pFrameBuffer->pSTScreen = pTmpScreen;
1.1 root 933: }
934:
1.1.1.3 root 935:
1.1.1.2 root 936: /*-----------------------------------------------------------------------*/
1.1.1.13! root 937: /**
! 938: * Draw ST screen to window/full-screen framebuffer
! 939: */
1.1.1.11 root 940: static void Screen_DrawFrame(BOOL bForceFlip)
1.1 root 941: {
1.1.1.13! root 942: int new_res;
! 943: void (*pDrawFunction)(void);
! 944: static BOOL bPrevFrameWasSpec512 = FALSE;
! 945:
! 946: /* Scan palette/resolution masks for each line and build up palette/difference tables */
! 947: new_res = Screen_ComparePaletteMask(STRes);
! 948: /* Do require palette? Check if changed and update */
! 949: Screen_Handle8BitPalettes();
! 950: /* Did we change resolution this frame - allocate new screen if did so */
! 951: Screen_DidResolutionChange(new_res);
! 952: /* Is need full-update, tag as such */
! 953: if (pFrameBuffer->bFullUpdate)
! 954: Screen_SetFullUpdateMask();
! 955:
! 956: /* Lock screen ready for drawing */
! 957: if (Screen_Lock())
! 958: {
! 959: bScreenContentsChanged = FALSE; /* Did change (ie needs blit?) */
! 960: /* Set details */
! 961: Screen_SetConvertDetails();
! 962: /* Clear screen on full update to clear out borders and also interleaved lines */
! 963: if (pFrameBuffer->bFullUpdate && !bUseVDIRes)
! 964: Screen_ClearScreen();
! 965: /* Call drawing for full-screen */
! 966: if (bUseVDIRes)
! 967: {
! 968: pDrawFunction = ScreenDrawFunctionsVDI[VDIRes];
! 969: }
! 970: else
! 971: {
! 972: pDrawFunction = ScreenDrawFunctionsNormal[STRes];
! 973: /* Check if is Spec512 image */
! 974: if (Spec512_IsImage())
! 975: {
! 976: bPrevFrameWasSpec512 = TRUE;
! 977: /* What mode were we in? Keep to 320xH or 640xH */
! 978: if (pDrawFunction==ConvertLowRes_320x16Bit)
! 979: pDrawFunction = ConvertSpec512_320x16Bit;
! 980: else if (pDrawFunction==ConvertLowRes_640x16Bit)
! 981: pDrawFunction = ConvertSpec512_640x16Bit;
! 982: else if (pDrawFunction==ConvertLowRes_320x32Bit)
! 983: pDrawFunction = ConvertSpec512_320x32Bit;
! 984: else if (pDrawFunction==ConvertLowRes_640x32Bit)
! 985: pDrawFunction = ConvertSpec512_640x32Bit;
! 986: }
! 987: else if (bPrevFrameWasSpec512)
! 988: {
! 989: /* If we switch back from Spec512 mode to normal
! 990: * screen rendering, we have to make sure to do
! 991: * a full update of the screen. */
! 992: Screen_SetFullUpdateMask();
! 993: bPrevFrameWasSpec512 = FALSE;
! 994: }
! 995: }
! 996:
! 997: if (pDrawFunction)
! 998: CALL_VAR(pDrawFunction)
! 999:
! 1000: /* Unlock screen */
! 1001: Screen_UnLock();
! 1002: /* Clear flags, remember type of overscan as if change need screen full update */
! 1003: pFrameBuffer->bFullUpdate = FALSE;
! 1004: pFrameBuffer->OverscanModeCopy = OverscanMode;
! 1005:
! 1006: /* And show to user */
! 1007: if (bScreenContentsChanged || bForceFlip)
! 1008: Screen_Blit(TRUE);
! 1009:
! 1010: /* Grab any animation */
! 1011: if (bRecordingAnimation)
! 1012: ScreenSnapShot_RecordFrame(bScreenContentsChanged);
! 1013: }
1.1 root 1014: }
1015:
1.1.1.9 root 1016:
1.1.1.2 root 1017: /*-----------------------------------------------------------------------*/
1.1.1.13! root 1018: /**
! 1019: * Draw ST screen to window/full-screen
! 1020: */
1.1 root 1021: void Screen_Draw(void)
1022: {
1.1.1.13! root 1023: if (!bQuitProgram && VideoBase)
! 1024: {
! 1025: /* And draw (if screen contents changed) */
! 1026: Screen_DrawFrame(FALSE);
! 1027: }
1.1 root 1028: }
1.1.1.11 root 1029:
1030:
1031: /* -------------- screen conversion routines --------------------------------
1032: Screen conversion routines. We have a number of routines to convert ST screen
1033: to PC format. We split these into Low, Medium and High each with 8/16-bit
1034: versions. To gain extra speed, as almost half of the processing time can be
1035: spent in these routines, we check for any changes from the previously
1036: displayed frame. AdjustLinePaletteRemap() sets a flag to tell the routines
1037: if we need to totally update a line (ie full update, or palette/res change)
1038: or if we just can do a difference check.
1039: We convert each screen 16 pixels at a time by use of a couple of look-up
1040: tables. These tables convert from 2-plane format to bbp and then we can add
1041: two of these together to get 4-planes. This keeps the tables small and thus
1042: improves speed. We then look these bbp values up as an RGB/Index value to
1043: copy to the screen.
1044: */
1045:
1046:
1.1.1.13! root 1047: /*-----------------------------------------------------------------------*/
! 1048: /**
1.1.1.11 root 1049: * Update the STRGBPalette[] array with current colours for this raster line.
1050: *
1051: * Return 'ScrUpdateFlag', 0x80000000=Full update, 0x40000000=Update
1052: * as palette changed
1053: */
1054: static int AdjustLinePaletteRemap(int y)
1055: {
1056: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1.1.1.13! root 1057: static const int endiantable[16] = {0,2,1,3,8,10,9,11,4,6,5,7,12,14,13,15};
1.1.1.11 root 1058: #endif
1.1.1.13! root 1059: Uint16 *actHBLPal;
! 1060: int i;
1.1.1.11 root 1061:
1.1.1.13! root 1062: /* Copy palette and convert to RGB in display format */
! 1063: actHBLPal = pHBLPalettes + (y<<4); /* offset in palette */
! 1064: for (i=0; i<16; i++)
! 1065: {
1.1.1.11 root 1066: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1.1.1.13! root 1067: STRGBPalette[endiantable[i]] = ST2RGB[*actHBLPal++];
1.1.1.11 root 1068: #else
1.1.1.13! root 1069: STRGBPalette[i] = ST2RGB[*actHBLPal++];
1.1.1.11 root 1070: #endif
1.1.1.13! root 1071: }
! 1072: ScrUpdateFlag = HBLPaletteMasks[y];
! 1073: return ScrUpdateFlag;
1.1.1.11 root 1074: }
1075:
1076:
1.1.1.13! root 1077: /*-----------------------------------------------------------------------*/
! 1078: /**
1.1.1.11 root 1079: * Run updates to palette(STRGBPalette[]) until get to screen line
1080: * we are to convert from
1081: */
1082: static void Convert_StartFrame(void)
1083: {
1.1.1.13! root 1084: int y = 0;
! 1085: /* Get #lines before conversion starts */
! 1086: int lines = STScreenStartHorizLine;
! 1087: while (lines--)
! 1088: AdjustLinePaletteRemap(y++); /* Update palette */
1.1.1.11 root 1089: }
1090:
1091: /* lookup tables and conversion macros */
1092: #include "convert/macros.h"
1093:
1094: /* Conversion routines */
1.1.1.13! root 1095:
! 1096: #include "convert/low320x8.c" /* LowRes To 320xH x 8-bit color */
! 1097: #include "convert/low640x8.c" /* LowRes To 640xH x 8-bit color */
! 1098: #include "convert/med640x8.c" /* MediumRes To 640xH x 8-bit color */
! 1099: #include "convert/high640x8.c" /* HighRes To 640xH x 8-bit color */
! 1100:
! 1101: #include "convert/low320x16.c" /* LowRes To 320xH x 16-bit color */
! 1102: #include "convert/low640x16.c" /* LowRes To 640xH x 16-bit color */
! 1103: #include "convert/med640x16.c" /* MediumRes To 640xH x 16-bit color */
! 1104: #include "convert/spec320x16.c" /* Spectrum 512 To 320xH x 16-bit color */
! 1105: #include "convert/spec640x16.c" /* Spectrum 512 To 640xH x 16-bit color */
! 1106:
! 1107: #include "convert/low320x32.c" /* LowRes To 320xH x 32-bit color */
! 1108: #include "convert/low640x32.c" /* LowRes To 640xH x 32-bit color */
! 1109: #include "convert/med640x32.c" /* MediumRes To 640xH x 32-bit color */
! 1110: #include "convert/spec320x32.c" /* Spectrum 512 To 320xH x 32-bit color */
! 1111: #include "convert/spec640x32.c" /* Spectrum 512 To 640xH x 32-bit color */
! 1112:
! 1113: #include "convert/vdi16.c" /* VDI x 16 color */
! 1114: #include "convert/vdi4.c" /* VDI x 4 color */
! 1115: #include "convert/vdi2.c" /* VDI x 2 color */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.