1 #include "../copyright" 2 3 #ifndef _TILE_H_ 4 #define _TILE_H_ 5 6 #define TILE_PREAMBLE_VARS() \ 7 uint32_t l; \ 8 uint16_t *ScreenColors; \ 9 uint8_t *pCache; \ 10 uint32_t TileNumber; \ 11 uint32_t TileAddr 12 13 #define TILE_PREAMBLE_CODE() \ 14 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); \ 15 if ((Tile & 0x1ff) >= 256) \ 16 TileAddr += BG.NameSelect; \ 17 TileAddr &= 0xffff; \ 18 pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) << 6]; \ 19 if (!BG.Buffered [TileNumber]) \ 20 BG.Buffered[TileNumber] = ConvertTile (pCache, TileAddr); \ 21 if (BG.Buffered [TileNumber] == BLANK_TILE) \ 22 return; \ 23 if (BG.DirectColourMode) \ 24 { \ 25 if (IPPU.DirectColourMapsNeedRebuild) \ 26 S9xBuildDirectColourMaps (); \ 27 ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; \ 28 } \ 29 else \ 30 ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette] 31 32 #define RENDER_TILE(NORMAL, FLIPPED, N) \ 33 switch (Tile & (V_FLIP | H_FLIP)) \ 34 { \ 35 case 0: \ 36 bp = pCache + StartLine; \ 37 for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ 38 { \ 39 NORMAL (Offset, bp, ScreenColors); \ 40 NORMAL (Offset + N, bp + 4, ScreenColors); \ 41 } \ 42 break; \ 43 case H_FLIP: \ 44 bp = pCache + StartLine; \ 45 for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ 46 { \ 47 FLIPPED (Offset, bp + 4, ScreenColors); \ 48 FLIPPED (Offset + N, bp, ScreenColors); \ 49 } \ 50 break; \ 51 case H_FLIP | V_FLIP: \ 52 bp = pCache + 56 - StartLine; \ 53 for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ 54 { \ 55 FLIPPED (Offset, bp + 4, ScreenColors); \ 56 FLIPPED (Offset + N, bp, ScreenColors); \ 57 } \ 58 break; \ 59 case V_FLIP: \ 60 bp = pCache + 56 - StartLine; \ 61 for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ 62 { \ 63 NORMAL (Offset, bp, ScreenColors); \ 64 NORMAL (Offset + N, bp + 4, ScreenColors); \ 65 } \ 66 break; \ 67 default: \ 68 break; \ 69 } 70 71 #define TILE_CLIP_PREAMBLE_VARS() \ 72 uint32_t d1; \ 73 uint32_t d2 74 75 #define TILE_CLIP_PREAMBLE_CODE() \ 76 if (StartPixel < 4) \ 77 { \ 78 d1 = HeadMask [StartPixel]; \ 79 if (StartPixel + Width < 4) \ 80 d1 &= TailMask [StartPixel + Width]; \ 81 } \ 82 else \ 83 d1 = 0; \ 84 if (StartPixel + Width > 4) \ 85 { \ 86 if (StartPixel > 4) \ 87 d2 = HeadMask [StartPixel - 4]; \ 88 else \ 89 d2 = 0xffffffff; \ 90 d2 &= TailMask [(StartPixel + Width - 4)]; \ 91 } \ 92 else \ 93 d2 = 0 94 95 #define RENDER_CLIPPED_TILE_VARS() \ 96 uint32_t dd 97 98 #define RENDER_CLIPPED_TILE_CODE(NORMAL, FLIPPED, N) \ 99 switch (Tile & (V_FLIP | H_FLIP)) \ 100 { \ 101 case 0: \ 102 bp = pCache + StartLine; \ 103 for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ 104 { \ 105 /* This is perfectly OK, regardless of endianness. The tiles are \ 106 * cached in leftmost-endian order (when not horiz flipped) by \ 107 * the ConvertTile function. */ \ 108 if ((dd = (*(uint32_t *) bp) & d1)) \ 109 NORMAL (Offset, (uint8_t *) &dd, ScreenColors); \ 110 if ((dd = (*(uint32_t *) (bp + 4)) & d2)) \ 111 NORMAL (Offset + N, (uint8_t *) &dd, ScreenColors); \ 112 } \ 113 break; \ 114 case H_FLIP: \ 115 bp = pCache + StartLine; \ 116 SWAP_DWORD (d1); \ 117 SWAP_DWORD (d2); \ 118 for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ 119 { \ 120 if ((dd = *(uint32_t *) (bp + 4) & d1)) \ 121 FLIPPED (Offset, (uint8_t *) &dd, ScreenColors); \ 122 if ((dd = *(uint32_t *) bp & d2)) \ 123 FLIPPED (Offset + N, (uint8_t *) &dd, ScreenColors); \ 124 } \ 125 break; \ 126 case H_FLIP | V_FLIP: \ 127 bp = pCache + 56 - StartLine; \ 128 SWAP_DWORD (d1); \ 129 SWAP_DWORD (d2); \ 130 for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ 131 { \ 132 if ((dd = *(uint32_t *) (bp + 4) & d1)) \ 133 FLIPPED (Offset, (uint8_t *) &dd, ScreenColors); \ 134 if ((dd = *(uint32_t *) bp & d2)) \ 135 FLIPPED (Offset + N, (uint8_t *) &dd, ScreenColors); \ 136 } \ 137 break; \ 138 case V_FLIP: \ 139 bp = pCache + 56 - StartLine; \ 140 for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ 141 { \ 142 if ((dd = (*(uint32_t *) bp) & d1)) \ 143 NORMAL (Offset, (uint8_t *) &dd, ScreenColors); \ 144 if ((dd = (*(uint32_t *) (bp + 4)) & d2)) \ 145 NORMAL (Offset + N, (uint8_t *) &dd, ScreenColors); \ 146 } \ 147 break; \ 148 default: \ 149 break; \ 150 } 151 152 #define RENDER_TILE_LARGE(PIXEL, FUNCTION) \ 153 switch (Tile & (V_FLIP | H_FLIP)) \ 154 { \ 155 case H_FLIP: \ 156 StartPixel = 7 - StartPixel; \ 157 /* fallthrough for no-flip case - above was a horizontal flip */ \ 158 case 0: \ 159 if((pixel = pCache[StartLine + StartPixel])) \ 160 { \ 161 pixel = PIXEL; \ 162 for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \ 163 { \ 164 int32_t z; \ 165 for (z = Pixels - 1; z >= 0; z--) \ 166 { \ 167 if (GFX.Z1 > Depth [z]) \ 168 { \ 169 sp [z] = FUNCTION(sp + z, pixel); \ 170 Depth [z] = GFX.Z2; \ 171 }\ 172 } \ 173 } \ 174 } \ 175 break; \ 176 case H_FLIP | V_FLIP: \ 177 StartPixel = 7 - StartPixel; \ 178 /* fallthrough for V_FLIP-only case - above was a horizontal flip */ \ 179 case V_FLIP: \ 180 if((pixel = pCache[56 - StartLine + StartPixel])) \ 181 { \ 182 pixel = PIXEL; \ 183 for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \ 184 { \ 185 int32_t z; \ 186 for (z = Pixels - 1; z >= 0; z--) \ 187 { \ 188 if (GFX.Z1 > Depth [z]) \ 189 { \ 190 sp [z] = FUNCTION(sp + z, pixel); \ 191 Depth [z] = GFX.Z2; \ 192 }\ 193 } \ 194 } \ 195 } \ 196 break; \ 197 default: \ 198 break; \ 199 } 200 201 #define RENDER_TILE_LARGE_HALFWIDTH(PIXEL, FUNCTION) \ 202 switch (Tile & (V_FLIP | H_FLIP)) \ 203 { \ 204 case H_FLIP: \ 205 StartPixel = 7 - StartPixel; \ 206 /* fallthrough for no-flip case - above was a horizontal flip */ \ 207 case 0: \ 208 if((pixel = pCache[StartLine + StartPixel])) \ 209 { \ 210 pixel = PIXEL; \ 211 for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \ 212 { \ 213 int32_t z; \ 214 for (z = Pixels - 2; z >= 0; z -= 2) \ 215 { \ 216 if (GFX.Z1 > Depth [z]) \ 217 { \ 218 sp [z >> 1] = FUNCTION(sp + z, pixel); \ 219 Depth [z >> 1] = GFX.Z2; \ 220 } \ 221 } \ 222 } \ 223 } \ 224 break; \ 225 case H_FLIP | V_FLIP: \ 226 StartPixel = 7 - StartPixel; \ 227 /* fallthrough for V_FLIP-only case - above was a horizontal flip */ \ 228 case V_FLIP: \ 229 if((pixel = pCache[56 - StartLine + StartPixel])) \ 230 { \ 231 pixel = PIXEL; \ 232 for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \ 233 { \ 234 int32_t z; \ 235 for (z = Pixels - 2; z >= 0; z -= 2) \ 236 { \ 237 if (GFX.Z1 > Depth [z]) \ 238 { \ 239 sp [z >> 1] = FUNCTION(sp + z, pixel); \ 240 Depth [z >> 1] = GFX.Z2; \ 241 } \ 242 } \ 243 } \ 244 } \ 245 break; \ 246 default: \ 247 break; \ 248 } 249 #endif 250