--- hatari/src/convert/macros.h 2019/04/01 07:13:53 1.1.1.3 +++ hatari/src/convert/macros.h 2019/04/09 08:57:09 1.1.1.8 @@ -3,19 +3,13 @@ Lookup tables and macros for screen conversion routines. - This file is distributed under the GNU Public License, version 2 or at your - option any later version. Read the file gpl.txt for details. + This file is distributed under the GNU General Public License, version 2 + or at your option any later version. Read the file gpl.txt for details. */ #ifndef HATARI_CONVERTMACROS_H #define HATARI_CONVERTMACROS_H -/* For palette we don't go from colour '0' as the whole background - * would change, so go from this value - */ -#define BASECOLOUR 0x0A -#define BASECOLOUR_LONG 0x0A0A0A0A - /* Remap tables to convert from plane format to byte-per-pixel * (Upper is for 4-Planes so if shifted by 2) */ @@ -89,11 +83,14 @@ static const Uint32 Remap_2_Planes_Upper 0x0808080C, 0x0C08080C, 0x080C080C, 0x0C0C080C, 0x08080C0C, 0x0C080C0C, 0x080C0C0C, 0x0C0C0C0C, }; -static const Uint32 Remap_1_Plane[16] = { - 0x00000000+BASECOLOUR_LONG, 0x01000000+BASECOLOUR_LONG, 0x00010000+BASECOLOUR_LONG, 0x01010000+BASECOLOUR_LONG, 0x00000100+BASECOLOUR_LONG, 0x01000100+BASECOLOUR_LONG, 0x00010100+BASECOLOUR_LONG, 0x01010100+BASECOLOUR_LONG, - 0x00000001+BASECOLOUR_LONG, 0x01000001+BASECOLOUR_LONG, 0x00010001+BASECOLOUR_LONG, 0x01010001+BASECOLOUR_LONG, 0x00000101+BASECOLOUR_LONG, 0x01000101+BASECOLOUR_LONG, 0x00010101+BASECOLOUR_LONG, 0x01010101+BASECOLOUR_LONG, -}; +/*----------------------------------------------------------------------*/ +/* Macros to convert from Atari's planar mode to chunky mode + * (1 byte per pixel). Convert by blocks of 4 pixels. + * 16 low res pixels -> 4 planes of 16 bits + * 16 med res pixels -> 2 planes of 16 bits + * 16 hi res pixels -> 1 plane of 16 bits + */ #define LOW_BUILD_PIXELS_0 \ { \ @@ -153,27 +150,14 @@ static const Uint32 Remap_1_Plane[16] = } -/* Routines to create 'ecx' pixels - MUST be called in this order */ -#define HIGH_BUILD_PIXELS_0 \ -{ \ - eax = (ebx & 0x0000000f); \ -} - -#define HIGH_BUILD_PIXELS_1 \ -{ \ - eax = (ebx >> 4) & 0x0000000f;\ -} - -#define HIGH_BUILD_PIXELS_2 \ -{ \ - eax = (ebx >> 8) & 0x0000000f;\ -} - -#define HIGH_BUILD_PIXELS_3 \ -{ \ - eax = (ebx >> 12) & 0x0000000f;\ -} +/*----------------------------------------------------------------------*/ +/* Macros to plot Atari's pixels in the emulator's buffer + * (the buffer can be 32, 16 or 8 bits per pixel) + */ +/* + * 32 bit screen format + */ /* Plot Low Resolution (320xH) 32-Bit pixels */ #define PLOT_LOW_320_32BIT(offset) \ @@ -240,7 +224,7 @@ static const Uint32 Remap_1_Plane[16] = } /* Plot Spectrum512 Resolution (320xH) 32-Bit pixels */ -#define PLOT_SPEC512_MID_320_32BIT PLOT_MED_640_32BIT +#define PLOT_SPEC512_MID_320_32BIT PLOT_LOW_320_32BIT /* Plot Spectrum512 Resolution(320xH) 32-Bit pixels */ #define PLOT_SPEC512_END_LOW_320_32BIT(offset) \ @@ -275,10 +259,10 @@ static const Uint32 Remap_1_Plane[16] = esi[offset] = esi[offset+1] = STRGBPalette[ecx & 0x000000ff]; \ } -/* Plot Spectrum512 Resolution (640xH) 16-Bit pixels (Double on Y) */ +/* Plot Spectrum512 Resolution (640xH) 32-Bit pixels (Double on Y) */ #define PLOT_SPEC512_MID_640_32BIT_DOUBLE_Y PLOT_LOW_640_32BIT_DOUBLE_Y -/* Plot Spectrum512 Resolution (640xH) 16-Bit pixels (Double on Y) */ +/* Plot Spectrum512 Resolution (640xH) 32-Bit pixels (Double on Y) */ #define PLOT_SPEC512_END_LOW_640_32BIT_DOUBLE_Y(offset) \ { \ ebx = STRGBPalette[ecx & 0x000000ff]; \ @@ -293,41 +277,48 @@ static const Uint32 Remap_1_Plane[16] = } -/* Plot Low Resolution (320xH) 16-Bit pixels */ -#define PLOT_LOW_320_16BIT(offset) \ +/* Plot Spectrum512 Medium Resolution (640xH) 32-Bit pixels */ +#define PLOT_SPEC512_LEFT_MED_640_32BIT PLOT_SPEC512_LEFT_LOW_320_32BIT + +#define PLOT_SPEC512_MID_MED_640_32BIT PLOT_SPEC512_MID_320_32BIT + +#define PLOT_SPEC512_END_MED_640_32BIT PLOT_SPEC512_END_LOW_320_32BIT + + +/* Plot Spectrum512 Medium Resolution (640xH) 32-Bit pixels (Double on Y) */ +#define PLOT_SPEC512_LEFT_MED_640_32BIT_DOUBLE_Y(offset) \ { \ - esi[offset] = (Uint16)STRGBPalette[ecx & 0x00ff]; \ - esi[offset+1] = (Uint16)STRGBPalette[(ecx >> 8) & 0x00ff]; \ - esi[offset+2] = (Uint16)STRGBPalette[(ecx >> 16) & 0x00ff]; \ - esi[offset+3] = (Uint16)STRGBPalette[(ecx >> 24) & 0x00ff]; \ + esi[offset+Screen4BytesPerLine] = esi[offset] = STRGBPalette[ecx & 0x000000ff]; \ } -/* Plot Low Resolution (320xH) 8-Bit pixels */ -#define PLOT_LOW_320_8BIT(offset) \ +#define PLOT_SPEC512_MID_MED_640_32BIT_DOUBLE_Y(offset) \ { \ - esi[offset] = SDL_SwapLE32(ecx + BASECOLOUR_LONG); \ + esi[offset+0+Screen4BytesPerLine] = esi[offset+0] = STRGBPalette[ecx & 0x000000ff]; \ + esi[offset+1+Screen4BytesPerLine] = esi[offset+1] = STRGBPalette[(ecx >> 8) & 0x000000ff]; \ + esi[offset+2+Screen4BytesPerLine] = esi[offset+2] = STRGBPalette[(ecx >> 16) & 0x000000ff]; \ + esi[offset+3+Screen4BytesPerLine] = esi[offset+3] = STRGBPalette[(ecx >> 24) & 0x000000ff]; \ } -/* Plot Low Resolution (640xH) 8-Bit pixels */ -#define PLOT_LOW_640_8BIT(offset) \ +#define PLOT_SPEC512_END_MED_640_32BIT_DOUBLE_Y(offset) \ { \ - ebpp = ecx + BASECOLOUR_LONG; \ - ecx = ((ebpp & 0x0000ff00) << 8) | (ebpp & 0x000000ff); \ - esi[offset] = SDL_SwapLE32((ecx << 8) | ecx); \ - ecx = ((ebpp & 0x00ff0000) >> 8) | (ebpp & 0xff000000); \ - esi[offset+1] = SDL_SwapLE32((ecx >> 8) | ecx); \ + esi[offset+0+Screen4BytesPerLine] = esi[offset+0] = STRGBPalette[ecx & 0x000000ff]; \ + esi[offset+1+Screen4BytesPerLine] = esi[offset+1] = STRGBPalette[(ecx >> 8) & 0x000000ff]; \ + esi[offset+2+Screen4BytesPerLine] = esi[offset+2] = STRGBPalette[(ecx >> 16) & 0x000000ff]; \ } -/* Plot Low Resolution (640xH) 8-Bit pixels (double on Y) */ -#define PLOT_LOW_640_8BIT_DOUBLE_Y(offset) \ + + +/* + * 16 bit screen format + */ + +/* Plot Low Resolution (320xH) 16-Bit pixels */ +#define PLOT_LOW_320_16BIT(offset) \ { \ - ebpp = ecx + BASECOLOUR_LONG; \ - ecx = ((ebpp & 0x0000ff00) << 8) | (ebpp & 0x000000ff); \ - esi[offset+Screen4BytesPerLine] = \ - esi[offset] = SDL_SwapLE32((ecx << 8) | ecx); \ - ecx = ((ebpp & 0x00ff0000) >> 8) | (ebpp & 0xff000000); \ - esi[offset+1+Screen4BytesPerLine] = \ - esi[offset+1] = SDL_SwapLE32((ecx >> 8) | ecx); \ + esi[offset] = (Uint16)STRGBPalette[ecx & 0x00ff]; \ + esi[offset+1] = (Uint16)STRGBPalette[(ecx >> 8) & 0x00ff]; \ + esi[offset+2] = (Uint16)STRGBPalette[(ecx >> 16) & 0x00ff]; \ + esi[offset+3] = (Uint16)STRGBPalette[(ecx >> 24) & 0x00ff]; \ } /* Plot Low Resolution (640xH) 16-Bit pixels */ @@ -353,19 +344,6 @@ static const Uint32 Remap_1_Plane[16] = } -/* Plot Medium Resolution (640xH) 8-Bit pixels */ -#define PLOT_MED_640_8BIT(offset) \ -{ \ - esi[offset] = SDL_SwapLE32(ecx + BASECOLOUR_LONG); \ -} - -/* Plot Medium Resolution (640xH) 8-Bit pixels (Double on Y) */ -#define PLOT_MED_640_8BIT_DOUBLE_Y(offset) \ -{ \ - esi[offset] = esi[offset+Screen4BytesPerLine] =\ - SDL_SwapLE32(ecx + BASECOLOUR_LONG); \ -} - /* Plot Medium Resolution(640xH) 16-Bit pixels */ #define PLOT_MED_640_16BIT(offset) \ { \ @@ -389,13 +367,6 @@ static const Uint32 Remap_1_Plane[16] = } -/* Plot High Resolution (640xH) 8-Bit pixels */ -#define PLOT_HIGH_640_8BIT(offset) \ -{ \ - esi[offset] = SDL_SwapLE32(Remap_1_Plane[eax]); \ -} - - /* Plot Spectrum512 Resolution(320xH) 16-Bit pixels */ #define PLOT_SPEC512_LEFT_LOW_320_16BIT(offset) \ { \ @@ -403,7 +374,7 @@ static const Uint32 Remap_1_Plane[16] = } /* Plot Spectrum512 Resolution(320xH) 16-Bit pixels */ -#define PLOT_SPEC512_MID_320_16BIT PLOT_MED_640_16BIT +#define PLOT_SPEC512_MID_320_16BIT PLOT_LOW_640_16BIT /* Plot Spectrum512 Resolution(320xH) 16-Bit pixels */ #define PLOT_SPEC512_END_LOW_320_16BIT(offset) \ @@ -452,4 +423,44 @@ static const Uint32 Remap_1_Plane[16] = esi[offset+2] = esi[offset+2+Screen4BytesPerLine] = ebx; \ } + +/* Plot Spectrum512 Medium Resolution (640xH) 16-Bit pixels */ +#define PLOT_SPEC512_LEFT_MED_640_16BIT PLOT_SPEC512_LEFT_LOW_320_16BIT + +#define PLOT_SPEC512_MID_MED_640_16BIT PLOT_SPEC512_MID_320_16BIT + +#define PLOT_SPEC512_END_MED_640_16BIT PLOT_SPEC512_END_LOW_320_16BIT + + +/* Plot Spectrum512 Medium Resolution (640xH) 16-Bit pixels (Double on Y) */ +#define PLOT_SPEC512_LEFT_MED_640_16BIT_DOUBLE_Y PLOT_SPEC512_LEFT_MED_640_32BIT_DOUBLE_Y + +#define PLOT_SPEC512_MID_MED_640_16BIT_DOUBLE_Y PLOT_SPEC512_MID_MED_640_32BIT_DOUBLE_Y + +#define PLOT_SPEC512_END_MED_640_16BIT_DOUBLE_Y PLOT_SPEC512_END_MED_640_32BIT_DOUBLE_Y + + + +/* Get Spec512 pixels which are offset by 1 pixel */ +#if defined(__i386__) // Unaligned direct access is only supported on i86 platforms + +/* on AMD XP, first one is 1/3 faster than aligned access, and + * final pixels access ~15% faster than aligned operation below + */ +# define GET_SPEC512_OFFSET_PIXELS(pixels, x) \ + (*(Uint32 *)(((Uint8 *)pixels) + x)) +# define GET_SPEC512_OFFSET_FINAL_PIXELS(pixels) \ + (*(Uint32 *)(((Uint8 *)pixels) + 13)) + +#else + +# define GET_SPEC512_OFFSET_PIXELS(pixels, x) \ + (((*(Uint32 *)(((Uint8 *)pixels) + x-1)) >> 8) \ + | ((*(Uint32 *)(((Uint8 *)pixels) + x+3)) << 24)) +# define GET_SPEC512_OFFSET_FINAL_PIXELS(pixels) \ + ((*(Uint32 *)(((Uint8 *)pixels) + 12)) >> 8) + +#endif /* __i386__ */ + + #endif /* HATARI_CONVERTMACROS_H */