--- hatari/src/falcon/videl.c 2019/04/01 07:13:46 1.1 +++ hatari/src/falcon/videl.c 2019/04/09 08:47:21 1.1.1.4 @@ -12,7 +12,7 @@ modified to work for Hatari (but the kudos for the great Videl emulation code goes to the people from the Aranym project of course). */ -const char VIDEL_rcsid[] = "Hatari $Id: videl.c,v 1.1 2019/04/01 07:13:46 root Exp $"; +const char VIDEL_fileid[] = "Hatari videl.c : " __DATE__ " " __TIME__; #include "main.h" #include "configuration.h" @@ -39,11 +39,10 @@ const char VIDEL_rcsid[] = "Hatari $Id: #define HW 0xff8200 #define VIDEL_COLOR_REGS_BEGIN 0xff9800 -#define VIDEL_COLOR_REGS_END 0xffa200 static int width, height, bpp, since_last_change; -static BOOL hostColorsSync; +static bool hostColorsSync; /* Autozoom */ static int zoomwidth, prev_scrwidth; @@ -60,7 +59,7 @@ void VIDEL_reset(void) { since_last_change = 0; - hostColorsSync = FALSE; + hostColorsSync = false; /* Autozoom */ zoomwidth=prev_scrwidth=0; @@ -68,22 +67,26 @@ void VIDEL_reset(void) zoomxtable=NULL; zoomytable=NULL; - // default resolution to boot with + /* Default resolution to boot with */ width = 640; height = 480; - HostScreen_setWindowSize( width, height, 8 ); + HostScreen_setWindowSize(width, height, ConfigureParams.Screen.nForceBpp); + + /* Reset IO register (some are not initialized by TOS) */ + IoMem_WriteWord(0xff820e, 0); /* Line offset */ + IoMem_WriteWord(0xff8264, 0); /* Horizontal scroll */ } // monitor write access to Falcon and ST/E color palette registers void VIDEL_ColorRegsWrite(void) { - hostColorsSync = FALSE; + hostColorsSync = false; } void VIDEL_ShiftModeWriteWord(void) { Dprintf(("VIDEL f_shift: %06x = 0x%x\n", IoAccessBaseAddress, handleReadW(HW+0x66))); - bUseSTShifter = FALSE; + bUseSTShifter = false; } static long VIDEL_getVideoramAddress(void) @@ -126,13 +129,13 @@ static int VIDEL_getScreenBpp(void) static int VIDEL_getScreenWidth(void) { - return handleReadW(HW + 0x10) * 16 / VIDEL_getScreenBpp(); + return (handleReadW(HW + 0x10) & 0x03ff) * 16 / VIDEL_getScreenBpp(); } static int VIDEL_getScreenHeight(void) { - int vdb = handleReadW(HW + 0xa8); - int vde = handleReadW(HW + 0xaa); + int vdb = handleReadW(HW + 0xa8) & 0x07ff; + int vde = handleReadW(HW + 0xaa) & 0x07ff; int vmode = handleReadW(HW + 0xc2); /* visible y resolution: @@ -143,7 +146,7 @@ static int VIDEL_getScreenHeight(void) int yres = vde - vdb; if (!(vmode & 0x02)) // interlace yres >>= 1; - if (vmode & 0x01) // double + if (vmode & 0x01) // double yres >>= 1; return yres; @@ -190,18 +193,18 @@ static void VIDEL_updateColors(void) HostScreen_updatePalette(colors); } - hostColorsSync = TRUE; + hostColorsSync = true; } void VIDEL_ZoomModeChanged(void) { /* User selected another zoom mode, so set a new screen resolution now */ - HostScreen_setWindowSize(width, height, bpp >= 8 ? bpp : 8); + HostScreen_setWindowSize(width, height, bpp == 16 ? 16 : ConfigureParams.Screen.nForceBpp); } -void VIDEL_renderScreen(void) +bool VIDEL_renderScreen(void) { int vw = VIDEL_getScreenWidth(); int vh = VIDEL_getScreenHeight(); @@ -225,15 +228,15 @@ void VIDEL_renderScreen(void) } } if (since_last_change == 3) { - HostScreen_setWindowSize( width, height, bpp >= 8 ? bpp : 8 ); + HostScreen_setWindowSize(width, height, bpp == 16 ? 16 : ConfigureParams.Screen.nForceBpp); } if (since_last_change < 4) { since_last_change++; - return; + return false; } if (!HostScreen_renderBegin()) - return; + return false; if (ConfigureParams.Screen.bZoomLowRes) { VIDEL_renderScreenZoom(); @@ -243,7 +246,141 @@ void VIDEL_renderScreen(void) HostScreen_renderEnd(); - HostScreen_update1( FALSE ); + HostScreen_update1(false); + + return true; +} + + +/** + * Performs conversion from the TOS's bitplane word order (big endian) data + * into the native chunky color index. + */ +static void Videl_bitplaneToChunky(Uint16 *atariBitplaneData, Uint16 bpp, + Uint8 colorValues[16]) +{ + Uint32 a, b, c, d, x; + + /* Obviously the different cases can be broken out in various + * ways to lessen the amount of work needed for <8 bit modes. + * It's doubtful if the usage of those modes warrants it, though. + * The branches below should be ~100% correctly predicted and + * thus be more or less for free. + * Getting the palette values inline does not seem to help + * enough to worry about. The palette lookup is much slower than + * this code, though, so it would be nice to do something about it. + */ + if (bpp >= 4) { + d = *(Uint32 *)&atariBitplaneData[0]; + c = *(Uint32 *)&atariBitplaneData[2]; + if (bpp == 4) { + a = b = 0; + } else { + b = *(Uint32 *)&atariBitplaneData[4]; + a = *(Uint32 *)&atariBitplaneData[6]; + } + } else { + a = b = c = 0; + if (bpp == 2) { + d = *(Uint32 *)&atariBitplaneData[0]; + } else { +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + d = atariBitplaneData[0]<<16; +#else + d = atariBitplaneData[0]; +#endif + } + } + + x = a; + a = (a & 0xf0f0f0f0) | ((c & 0xf0f0f0f0) >> 4); + c = ((x & 0x0f0f0f0f) << 4) | (c & 0x0f0f0f0f); + x = b; + b = (b & 0xf0f0f0f0) | ((d & 0xf0f0f0f0) >> 4); + d = ((x & 0x0f0f0f0f) << 4) | (d & 0x0f0f0f0f); + + x = a; + a = (a & 0xcccccccc) | ((b & 0xcccccccc) >> 2); + b = ((x & 0x33333333) << 2) | (b & 0x33333333); + x = c; + c = (c & 0xcccccccc) | ((d & 0xcccccccc) >> 2); + d = ((x & 0x33333333) << 2) | (d & 0x33333333); + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + a = (a & 0x5555aaaa) | ((a & 0x00005555) << 17) | ((a & 0xaaaa0000) >> 17); + b = (b & 0x5555aaaa) | ((b & 0x00005555) << 17) | ((b & 0xaaaa0000) >> 17); + c = (c & 0x5555aaaa) | ((c & 0x00005555) << 17) | ((c & 0xaaaa0000) >> 17); + d = (d & 0x5555aaaa) | ((d & 0x00005555) << 17) | ((d & 0xaaaa0000) >> 17); + + colorValues[ 8] = a; + a >>= 8; + colorValues[ 0] = a; + a >>= 8; + colorValues[ 9] = a; + a >>= 8; + colorValues[ 1] = a; + + colorValues[10] = b; + b >>= 8; + colorValues[ 2] = b; + b >>= 8; + colorValues[11] = b; + b >>= 8; + colorValues[ 3] = b; + + colorValues[12] = c; + c >>= 8; + colorValues[ 4] = c; + c >>= 8; + colorValues[13] = c; + c >>= 8; + colorValues[ 5] = c; + + colorValues[14] = d; + d >>= 8; + colorValues[ 6] = d; + d >>= 8; + colorValues[15] = d; + d >>= 8; + colorValues[ 7] = d; +#else + a = (a & 0xaaaa5555) | ((a & 0x0000aaaa) << 15) | ((a & 0x55550000) >> 15); + b = (b & 0xaaaa5555) | ((b & 0x0000aaaa) << 15) | ((b & 0x55550000) >> 15); + c = (c & 0xaaaa5555) | ((c & 0x0000aaaa) << 15) | ((c & 0x55550000) >> 15); + d = (d & 0xaaaa5555) | ((d & 0x0000aaaa) << 15) | ((d & 0x55550000) >> 15); + + colorValues[ 1] = a; + a >>= 8; + colorValues[ 9] = a; + a >>= 8; + colorValues[ 0] = a; + a >>= 8; + colorValues[ 8] = a; + + colorValues[ 3] = b; + b >>= 8; + colorValues[11] = b; + b >>= 8; + colorValues[ 2] = b; + b >>= 8; + colorValues[10] = b; + + colorValues[ 5] = c; + c >>= 8; + colorValues[13] = c; + c >>= 8; + colorValues[ 4] = c; + c >>= 8; + colorValues[12] = c; + + colorValues[ 7] = d; + d >>= 8; + colorValues[15] = d; + d >>= 8; + colorValues[ 6] = d; + d >>= 8; + colorValues[14] = d; +#endif } @@ -286,8 +423,8 @@ void VIDEL_ConvertScreenNoZoom(int vw, i long atariVideoRAM = VIDEL_getVideoramAddress(); - uint16 *fvram = (uint16 *) Atari2HostAddr(atariVideoRAM); - uint8 *hvram = HostScreen_getVideoramAddress(); + Uint16 *fvram = (Uint16 *) Atari2HostAddr(atariVideoRAM); + Uint8 *hvram = HostScreen_getVideoramAddress(); int hscrolloffset = (handleRead(HW + 0x65) & 0x0f); @@ -314,36 +451,36 @@ void VIDEL_ConvertScreenNoZoom(int vw, i /* Bitplanes modes */ // The SDL colors blitting... - uint8 color[16]; + Uint8 color[16]; // FIXME: The byte swap could be done here by enrolling the loop into 2 each by 8 pixels switch ( HostScreen_getBpp() ) { case 1: { - uint16 *fvram_line = fvram; - uint8 *hvram_line = hvram; + Uint16 *fvram_line = fvram; + Uint8 *hvram_line = hvram; int h; for (h = 0; h < vh_clip; h++) { - uint16 *fvram_column = fvram_line; - uint8 *hvram_column = hvram_line; + Uint16 *fvram_column = fvram_line; + Uint8 *hvram_column = hvram_line; int w; /* First 16 pixels: */ - HostScreen_bitplaneToChunky(fvram_column, vbpp, color); + Videl_bitplaneToChunky(fvram_column, vbpp, color); memcpy(hvram_column, color+hscrolloffset, 16-hscrolloffset); hvram_column += 16-hscrolloffset; fvram_column += vbpp; /* Now the main part of the line: */ for (w = 1; w < (vw_clip+15)>>4; w++) { - HostScreen_bitplaneToChunky( fvram_column, vbpp, color ); + Videl_bitplaneToChunky( fvram_column, vbpp, color ); memcpy(hvram_column, color, 16); hvram_column += 16; fvram_column += vbpp; } /* Last pixels of the line for fine scrolling: */ if (hscrolloffset) { - HostScreen_bitplaneToChunky(fvram_column, vbpp, color); + Videl_bitplaneToChunky(fvram_column, vbpp, color); memcpy(hvram_column, color, hscrolloffset); } @@ -354,81 +491,74 @@ void VIDEL_ConvertScreenNoZoom(int vw, i break; case 2: { - uint16 *fvram_line = fvram; - uint16 *hvram_line = (uint16 *)hvram; + Uint16 *fvram_line = fvram; + Uint16 *hvram_line = (Uint16 *)hvram; int h; for (h = 0; h < vh_clip; h++) { - uint16 *fvram_column = fvram_line; - uint16 *hvram_column = hvram_line; - int w; - - for (w = 0; w < (vw_clip+15)>>4; w++) { - int j; - HostScreen_bitplaneToChunky( fvram_column, vbpp, color ); + Uint16 *fvram_column = fvram_line; + Uint16 *hvram_column = hvram_line; + int w, j; + /* First 16 pixels: */ + Videl_bitplaneToChunky(fvram_column, vbpp, color); + for (j = 0; j < 16 - hscrolloffset; j++) { + *hvram_column++ = HostScreen_getPaletteColor(color[j+hscrolloffset]); + } + fvram_column += vbpp; + /* Now the main part of the line: */ + for (w = 1; w < (vw_clip+15)>>4; w++) { + Videl_bitplaneToChunky( fvram_column, vbpp, color ); for (j=0; j<16; j++) { *hvram_column++ = HostScreen_getPaletteColor( color[j] ); } - fvram_column += vbpp; } - - hvram_line += scrpitch>>1; - fvram_line += nextline; - } - } - break; - case 3: - { - uint16 *fvram_line = fvram; - uint8 *hvram_line = hvram; - int h; - - for (h = 0; h < vh_clip; h++) { - uint16 *fvram_column = fvram_line; - uint8 *hvram_column = hvram_line; - int w; - - for (w = 0; w < (vw_clip+15)>>4; w++) { - int j; - HostScreen_bitplaneToChunky( fvram_column, vbpp, color ); - - for (j=0; j<16; j++) { - uint32 tmpColor = HostScreen_getPaletteColor( color[j] ); - putBpp24Pixel( hvram_column, tmpColor ); - hvram_column += 3; + /* Last pixels of the line for fine scrolling: */ + if (hscrolloffset) { + Videl_bitplaneToChunky(fvram_column, vbpp, color); + for (j = 0; j < hscrolloffset; j++) { + *hvram_column++ = HostScreen_getPaletteColor(color[j]); } - - fvram_column += vbpp; } - hvram_line += scrpitch; + hvram_line += scrpitch>>1; fvram_line += nextline; } } break; case 4: { - uint16 *fvram_line = fvram; - uint32 *hvram_line = (uint32 *)hvram; + Uint16 *fvram_line = fvram; + Uint32 *hvram_line = (Uint32 *)hvram; int h; for (h = 0; h < vh_clip; h++) { - uint16 *fvram_column = fvram_line; - uint32 *hvram_column = hvram_line; - int w; - - for (w = 0; w < (vw_clip+15)>>4; w++) { - int j; - HostScreen_bitplaneToChunky( fvram_column, vbpp, color ); + Uint16 *fvram_column = fvram_line; + Uint32 *hvram_column = hvram_line; + int w, j; + /* First 16 pixels: */ + Videl_bitplaneToChunky(fvram_column, vbpp, color); + for (j = 0; j < 16 - hscrolloffset; j++) { + *hvram_column++ = HostScreen_getPaletteColor(color[j+hscrolloffset]); + } + fvram_column += vbpp; + /* Now the main part of the line: */ + for (w = 1; w < (vw_clip+15)>>4; w++) { + Videl_bitplaneToChunky( fvram_column, vbpp, color ); for (j=0; j<16; j++) { *hvram_column++ = HostScreen_getPaletteColor( color[j] ); } - fvram_column += vbpp; } + /* Last pixels of the line for fine scrolling: */ + if (hscrolloffset) { + Videl_bitplaneToChunky(fvram_column, vbpp, color); + for (j = 0; j < hscrolloffset; j++) { + *hvram_column++ = HostScreen_getPaletteColor(color[j]); + } + } hvram_line += scrpitch>>2; fvram_line += nextline; @@ -444,13 +574,13 @@ void VIDEL_ConvertScreenNoZoom(int vw, i case 1: { /* FIXME: when Videl switches to 16bpp, set the palette to 3:3:2 */ - uint16 *fvram_line = fvram; - uint8 *hvram_line = hvram; + Uint16 *fvram_line = fvram; + Uint8 *hvram_line = hvram; int h; for (h = 0; h < vh_clip; h++) { - uint16 *fvram_column = fvram_line; - uint8 *hvram_column = hvram_line; + Uint16 *fvram_column = fvram_line; + Uint8 *hvram_column = hvram_line; int w, tmp; for (w = 0; w < vw_clip; w++) { @@ -472,8 +602,8 @@ void VIDEL_ConvertScreenNoZoom(int vw, i break; case 2: { - uint16 *fvram_line = fvram; - uint16 *hvram_line = (uint16 *)hvram; + Uint16 *fvram_line = fvram; + Uint16 *hvram_line = (Uint16 *)hvram; int h; for (h = 0; h < vh_clip; h++) { @@ -483,8 +613,8 @@ void VIDEL_ConvertScreenNoZoom(int vw, i memcpy(hvram_line, fvram_line, vw_clip<<1); #else int w; - uint16 *fvram_column = fvram_line; - uint16 *hvram_column = hvram_line; + Uint16 *fvram_column = fvram_line; + Uint16 *hvram_column = hvram_line; for (w = 0; w < vw_clip; w++) { // byteswap with SDL asm macros @@ -497,46 +627,15 @@ void VIDEL_ConvertScreenNoZoom(int vw, i } } break; - case 3: - { - uint16 *fvram_line = fvram; - uint8 *hvram_line = hvram; - int h; - - for (h = 0; h < vh_clip; h++) { - uint16 *fvram_column = fvram_line; - uint8 *hvram_column = hvram_line; - int w; - - for (w = 0; w < vw_clip; w++) { - int data = *fvram_column++; - - uint32 tmpColor = - HostScreen_getColor( - (uint8) (data & 0xf8), - (uint8) ( ((data & 0x07) << 5) | - ((data >> 11) & 0x3c)), - (uint8) ((data >> 5) & 0xf8)); - - putBpp24Pixel( hvram_column, tmpColor ); - - hvram_column += 3; - } - - hvram_line += scrpitch; - fvram_line += nextline; - } - } - break; case 4: { - uint16 *fvram_line = fvram; - uint32 *hvram_line = (uint32 *)hvram; + Uint16 *fvram_line = fvram; + Uint32 *hvram_line = (Uint32 *)hvram; int h; for (h = 0; h < vh_clip; h++) { - uint16 *fvram_column = fvram_line; - uint32 *hvram_column = hvram_line; + Uint16 *fvram_column = fvram_line; + Uint32 *hvram_column = hvram_line; int w; for (w = 0; w < vw_clip; w++) { @@ -544,10 +643,10 @@ void VIDEL_ConvertScreenNoZoom(int vw, i *hvram_column++ = HostScreen_getColor( - (uint8) (data & 0xf8), - (uint8) ( ((data & 0x07) << 5) | + (Uint8) (data & 0xf8), + (Uint8) ( ((data & 0x07) << 5) | ((data >> 11) & 0x3c)), - (uint8) ((data >> 5) & 0xf8)); + (Uint8) ((data >> 5) & 0xf8)); } hvram_line += scrpitch>>2; @@ -585,14 +684,14 @@ void VIDEL_ConvertScreenZoom(int vw, int { int i, j, w, h, cursrcline; - uint16 *fvram = (uint16 *) Atari2HostAddr(VIDEL_getVideoramAddress()); + Uint16 *fvram = (Uint16 *) Atari2HostAddr(VIDEL_getVideoramAddress()); /* Host screen infos */ int scrpitch = HostScreen_getPitch(); int scrwidth = HostScreen_getWidth(); int scrheight = HostScreen_getHeight(); int scrbpp = HostScreen_getBpp(); - uint8 *hvram = (uint8 *) HostScreen_getVideoramAddress(); + Uint8 *hvram = (Uint8 *) HostScreen_getVideoramAddress(); int hscrolloffset = (handleRead(HW + 0x65) & 0x0f); @@ -642,17 +741,17 @@ void VIDEL_ConvertScreenZoom(int vw, int cursrcline = -1; if (vbpp<16) { - uint8 color[16]; + Uint8 color[16]; /* Bitplanes modes */ switch(scrbpp) { case 1: { /* One complete planar 2 chunky line */ - uint8 *p2cline = malloc(sizeof(uint8)*vw); + Uint8 *p2cline = malloc(sizeof(Uint8)*vw); - uint16 *fvram_line; - uint8 *hvram_line = hvram; + Uint16 *fvram_line; + Uint8 *hvram_line = hvram; for (h = 0; h < scrheight; h++) { fvram_line = fvram + (zoomytable[h] * nextline); @@ -661,24 +760,24 @@ void VIDEL_ConvertScreenZoom(int vw, int if (zoomytable[h] == cursrcline) { memcpy(hvram_line, hvram_line-scrpitch, scrwidth*scrbpp); } else { - uint16 *fvram_column = fvram_line; - uint8 *hvram_column = p2cline; + Uint16 *fvram_column = fvram_line; + Uint8 *hvram_column = p2cline; /* First 16 pixels of a new line */ - HostScreen_bitplaneToChunky(fvram_column, vbpp, color); + Videl_bitplaneToChunky(fvram_column, vbpp, color); memcpy(hvram_column, color+hscrolloffset, 16-hscrolloffset); hvram_column += 16-hscrolloffset; fvram_column += vbpp; /* Convert main part of the new line */ for (w=1; w < (vw+15)>>4; w++) { - HostScreen_bitplaneToChunky( fvram_column, vbpp, color ); + Videl_bitplaneToChunky( fvram_column, vbpp, color ); memcpy(hvram_column, color, 16); hvram_column += 16; fvram_column += vbpp; } /* Last pixels of the line for fine scrolling: */ if (hscrolloffset) { - HostScreen_bitplaneToChunky(fvram_column, vbpp, color); + Videl_bitplaneToChunky(fvram_column, vbpp, color); memcpy(hvram_column, color, hscrolloffset); } @@ -698,10 +797,10 @@ void VIDEL_ConvertScreenZoom(int vw, int case 2: { /* One complete planar 2 chunky line */ - uint16 *p2cline = malloc(sizeof(uint16)*vw); + Uint16 *p2cline = malloc(sizeof(Uint16)*vw); - uint16 *fvram_line = fvram; - uint16 *hvram_line = (uint16 *)hvram; + Uint16 *fvram_line = fvram; + Uint16 *hvram_line = (Uint16 *)hvram; for (h = 0; h < scrheight; h++) { fvram_line = fvram + (zoomytable[h] * nextline); @@ -710,73 +809,38 @@ void VIDEL_ConvertScreenZoom(int vw, int if (zoomytable[h] == cursrcline) { memcpy(hvram_line, hvram_line-(scrpitch>>1), scrwidth*scrbpp); } else { - uint16 *fvram_column = fvram_line; - uint16 *hvram_column = p2cline; - - /* Convert a new line */ - for (w=0; w < (vw+15)>>4; w++) { - HostScreen_bitplaneToChunky( fvram_column, vbpp, color ); + Uint16 *fvram_column = fvram_line; + Uint16 *hvram_column = p2cline; + /* First 16 pixels of a new line: */ + Videl_bitplaneToChunky(fvram_column, vbpp, color); + for (j = 0; j < 16 - hscrolloffset; j++) { + *hvram_column++ = HostScreen_getPaletteColor(color[j+hscrolloffset]); + } + fvram_column += vbpp; + /* Convert the main part of the new line: */ + for (w = 1; w < (vw+15)>>4; w++) { + Videl_bitplaneToChunky( fvram_column, vbpp, color ); for (j=0; j<16; j++) { *hvram_column++ = HostScreen_getPaletteColor( color[j] ); } - fvram_column += vbpp; } - - /* Zoom a new line */ - for (w=0; w>1; - cursrcline = zoomytable[h]; - } - - free(p2cline); - } - break; - case 3: - { - /* One complete planar 2 chunky line */ - uint8 *p2cline = malloc(sizeof(uint8)*vw*3); - - uint16 *fvram_line; - uint8 *hvram_line = hvram; - - for (h = 0; h < scrheight; h++) { - fvram_line = fvram + (zoomytable[h] * nextline); - - /* Recopy the same line ? */ - if (zoomytable[h] == cursrcline) { - memcpy(hvram_line, hvram_line-scrpitch, scrwidth*scrbpp); - } else { - uint16 *fvram_column = fvram_line; - uint8 *hvram_column = p2cline; - - /* Convert a new line */ - for (w=0; w < (vw+15)>>4; w++) { - HostScreen_bitplaneToChunky( fvram_column, vbpp, color ); - - for (j=0; j<16; j++) { - uint32 tmpColor = HostScreen_getPaletteColor( color[j] ); - putBpp24Pixel( hvram_column, tmpColor ); - hvram_column += 3; + /* Last pixels of the new line for fine scrolling: */ + if (hscrolloffset) { + Videl_bitplaneToChunky(fvram_column, vbpp, color); + for (j = 0; j < hscrolloffset; j++) { + *hvram_column++ = HostScreen_getPaletteColor(color[j]); } - - fvram_column += vbpp; } - + /* Zoom a new line */ for (w=0; w>1; cursrcline = zoomytable[h]; } @@ -786,10 +850,10 @@ void VIDEL_ConvertScreenZoom(int vw, int case 4: { /* One complete planar 2 chunky line */ - uint32 *p2cline = malloc(sizeof(uint32)*vw); + Uint32 *p2cline = malloc(sizeof(Uint32)*vw); - uint16 *fvram_line; - uint32 *hvram_line = (uint32 *)hvram; + Uint16 *fvram_line; + Uint32 *hvram_line = (Uint32 *)hvram; for (h = 0; h < scrheight; h++) { fvram_line = fvram + (zoomytable[h] * nextline); @@ -798,20 +862,31 @@ void VIDEL_ConvertScreenZoom(int vw, int if (zoomytable[h] == cursrcline) { memcpy(hvram_line, hvram_line-(scrpitch>>2), scrwidth*scrbpp); } else { - uint16 *fvram_column = fvram_line; - uint32 *hvram_column = p2cline; - - /* Convert a new line */ - for (w=0; w < (vw+15)>>4; w++) { - HostScreen_bitplaneToChunky( fvram_column, vbpp, color ); + Uint16 *fvram_column = fvram_line; + Uint32 *hvram_column = p2cline; + /* First 16 pixels of a new line: */ + Videl_bitplaneToChunky(fvram_column, vbpp, color); + for (j = 0; j < 16 - hscrolloffset; j++) { + *hvram_column++ = HostScreen_getPaletteColor(color[j+hscrolloffset]); + } + fvram_column += vbpp; + /* Convert the main part of the new line: */ + for (w = 1; w < (vw+15)>>4; w++) { + Videl_bitplaneToChunky( fvram_column, vbpp, color ); for (j=0; j<16; j++) { *hvram_column++ = HostScreen_getPaletteColor( color[j] ); } - fvram_column += vbpp; } - + /* Last pixels of the new line for fine scrolling: */ + if (hscrolloffset) { + Videl_bitplaneToChunky(fvram_column, vbpp, color); + for (j = 0; j < hscrolloffset; j++) { + *hvram_column++ = HostScreen_getPaletteColor(color[j]); + } + } + /* Zoom a new line */ for (w=0; w>1), scrwidth*scrbpp); } else { for (w = 0; w < scrwidth; w++) { - uint16 srcword; + Uint16 srcword; srcword = SDL_SwapBE16(fvram_column[zoomxtable[w]]); *hvram_column++ = srcword; @@ -897,53 +972,14 @@ void VIDEL_ConvertScreenZoom(int vw, int } } break; - case 3: - { - uint16 *fvram_line; - uint8 *hvram_line = hvram; - - for (h = 0; h < scrheight; h++) { - uint16 *fvram_column; - uint8 *hvram_column; - - fvram_line = fvram + (zoomytable[h] * nextline); - fvram_column = fvram_line; - hvram_column = hvram_line; - - /* Recopy the same line ? */ - if (zoomytable[h] == cursrcline) { - memcpy(hvram_line, hvram_line-scrpitch, scrwidth*scrbpp); - } else { - for (w = 0; w < scrwidth; w++) { - uint16 srcword; - uint32 dstlong; - - srcword = fvram_column[zoomxtable[w]]; - - dstlong = HostScreen_getColor( - (uint8) (srcword & 0xf8), - (uint8) ( ((srcword & 0x07) << 5) | - ((srcword >> 11) & 0x3c)), - (uint8) ((srcword >> 5) & 0xf8)); - - putBpp24Pixel( hvram_column, dstlong ); - hvram_column += 3; - } - } - - hvram_line += scrpitch; - cursrcline = zoomytable[h]; - } - } - break; case 4: { - uint16 *fvram_line; - uint32 *hvram_line = (uint32 *)hvram; + Uint16 *fvram_line; + Uint32 *hvram_line = (Uint32 *)hvram; for (h = 0; h < scrheight; h++) { - uint16 *fvram_column; - uint32 *hvram_column; + Uint16 *fvram_column; + Uint32 *hvram_column; fvram_line = fvram + (zoomytable[h] * nextline); fvram_column = fvram_line; @@ -954,16 +990,16 @@ void VIDEL_ConvertScreenZoom(int vw, int memcpy(hvram_line, hvram_line-(scrpitch>>2), scrwidth*scrbpp); } else { for (w = 0; w < scrwidth; w++) { - uint16 srcword; + Uint16 srcword; srcword = fvram_column[zoomxtable[w]]; *hvram_column++ = HostScreen_getColor( - (uint8) (srcword & 0xf8), - (uint8) ( ((srcword & 0x07) << 5) | + (Uint8) (srcword & 0xf8), + (Uint8) ( ((srcword & 0x07) << 5) | ((srcword >> 11) & 0x3c)), - (uint8) ((srcword >> 5) & 0xf8)); + (Uint8) ((srcword >> 5) & 0xf8)); } }