2 * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
4 * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and
5 * Jerremy Koot (jkoot@snes9x.com)
7 * Super FX C emulator code
8 * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and
10 * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
12 * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson.
13 * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_.
14 * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com).
16 * DOS port code contains the works of other authors. See headers in
19 * Snes9x homepage: http://www.snes9x.com
21 * Permission to use, copy, modify and distribute Snes9x in both binary and
22 * source form, for non-commercial purposes, is hereby granted without fee,
23 * providing that this license information and copyright notice appear with
24 * all copies and any derived work.
26 * This software is provided 'as-is', without any express or implied
27 * warranty. In no event shall the authors be held liable for any damages
28 * arising from the use of this software.
30 * Snes9x is freeware for PERSONAL USE only. Commercial users should
31 * seek permission of the copyright holders first. Commercial use includes
32 * charging money for Snes9x or software derived from Snes9x.
34 * The copyright holders request that bug fixes and improvements to the code
35 * should be forwarded to them so everyone can benefit from the modifications
38 * Super NES and Super Nintendo Entertainment System are trademarks of
39 * Nintendo Co., Limited and its subsidiary companies.
44 #define TILE_PREAMBLE \
47 uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); \
48 if ((Tile & 0x1ff) >= 256) \
49 TileAddr += BG.NameSelect; \
54 pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) << 6]; \
56 if (!BG.Buffered [TileNumber]) \
57 BG.Buffered[TileNumber] = ConvertTile (pCache, TileAddr); \
59 if (BG.Buffered [TileNumber] == BLANK_TILE) \
63 if (BG.DirectColourMode) \
65 if (IPPU.DirectColourMapsNeedRebuild) \
66 S9xBuildDirectColourMaps (); \
67 gfx->ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; \
70 gfx->ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette];
72 #define RENDER_TILE(NORMAL, FLIPPED, N) \
73 if (!(Tile & (V_FLIP | H_FLIP))) \
75 bp = pCache + StartLine; \
76 for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \
79 NORMAL (Offset, bp, gfx); \
80 if (*(uint32 *) (bp + 4)) \
81 NORMAL (Offset + N, bp + 4, gfx); \
85 if (!(Tile & V_FLIP)) \
87 bp = pCache + StartLine; \
88 for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \
90 if (*(uint32 *) (bp + 4)) \
91 FLIPPED (Offset, bp + 4, gfx); \
93 FLIPPED (Offset + N, bp, gfx); \
99 bp = pCache + 56 - StartLine; \
100 for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \
102 if (*(uint32 *) (bp + 4)) \
103 FLIPPED (Offset, bp + 4, gfx); \
104 if (*(uint32 *) bp) \
105 FLIPPED (Offset + N, bp, gfx); \
110 bp = pCache + 56 - StartLine; \
111 for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \
113 if (*(uint32 *) bp) \
114 NORMAL (Offset, bp, gfx); \
115 if (*(uint32 *) (bp + 4)) \
116 NORMAL (Offset + N, bp + 4, gfx); \
120 #define TILE_CLIP_PREAMBLE \
125 if (StartPixel < 4) \
127 d1 = HeadMask [StartPixel]; \
128 if (StartPixel + Width < 4) \
129 d1 &= TailMask [StartPixel + Width]; \
134 if (StartPixel + Width > 4) \
136 if (StartPixel > 4) \
137 d2 = HeadMask [StartPixel - 4]; \
141 d2 &= TailMask [(StartPixel + Width - 4)]; \
147 #define RENDER_CLIPPED_TILE(NORMAL, FLIPPED, N) \
148 if (!(Tile & (V_FLIP | H_FLIP))) \
150 bp = pCache + StartLine; \
151 for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \
153 if ((dd = (*(uint32 *) bp) & d1)) \
154 NORMAL (Offset, (uint8 *) &dd, gfx); \
155 if ((dd = (*(uint32 *) (bp + 4)) & d2)) \
156 NORMAL (Offset + N, (uint8 *) &dd, gfx); \
160 if (!(Tile & V_FLIP)) \
162 bp = pCache + StartLine; \
165 for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \
167 if ((dd = *(uint32 *) (bp + 4) & d1)) \
168 FLIPPED (Offset, (uint8 *) &dd, gfx); \
169 if ((dd = *(uint32 *) bp & d2)) \
170 FLIPPED (Offset + N, (uint8 *) &dd, gfx); \
176 bp = pCache + 56 - StartLine; \
179 for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \
181 if ((dd = *(uint32 *) (bp + 4) & d1)) \
182 FLIPPED (Offset, (uint8 *) &dd, gfx); \
183 if ((dd = *(uint32 *) bp & d2)) \
184 FLIPPED (Offset + N, (uint8 *) &dd, gfx); \
189 bp = pCache + 56 - StartLine; \
190 for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \
192 if ((dd = (*(uint32 *) bp) & d1)) \
193 NORMAL (Offset, (uint8 *) &dd, gfx); \
194 if ((dd = (*(uint32 *) (bp + 4)) & d2)) \
195 NORMAL (Offset + N, (uint8 *) &dd, gfx); \
199 #define RENDER_TILE_LARGE(PIXEL, FUNCTION) \
200 if (!(Tile & (V_FLIP | H_FLIP))) \
202 if ((pixel = *(pCache + StartLine + StartPixel))) \
205 for (l = LineCount; l != 0; l--, sp += gfx->PPL, Depth += gfx->PPL) \
207 for (int z = Pixels - 1; z >= 0; z--) \
208 if (gfx->Z1 > Depth [z]) \
210 sp [z] = FUNCTION(sp + z, pixel); \
211 Depth [z] = gfx->Z2; \
217 if (!(Tile & V_FLIP)) \
219 StartPixel = 7 - StartPixel; \
220 if ((pixel = *(pCache + StartLine + StartPixel))) \
223 for (l = LineCount; l != 0; l--, sp += gfx->PPL, Depth += gfx->PPL) \
225 for (int z = Pixels - 1; z >= 0; z--) \
226 if (gfx->Z1 > Depth [z]) \
228 sp [z] = FUNCTION(sp + z, pixel); \
229 Depth [z] = gfx->Z2; \
237 StartPixel = 7 - StartPixel; \
238 if ((pixel = *(pCache + 56 - StartLine + StartPixel))) \
241 for (l = LineCount; l != 0; l--, sp += gfx->PPL, Depth += gfx->PPL) \
243 for (int z = Pixels - 1; z >= 0; z--) \
244 if (gfx->Z1 > Depth [z]) \
246 sp [z] = FUNCTION(sp + z, pixel); \
247 Depth [z] = gfx->Z2; \
254 if ((pixel = *(pCache + 56 - StartLine + StartPixel))) \
257 for (l = LineCount; l != 0; l--, sp += gfx->PPL, Depth += gfx->PPL) \
259 for (int z = Pixels - 1; z >= 0; z--) \
260 if (gfx->Z1 > Depth [z]) \
262 sp [z] = FUNCTION(sp + z, pixel); \
263 Depth [z] = gfx->Z2; \
269 #define RENDER_TILEHI(NORMAL, FLIPPED, N) \
270 if (!(Tile & (V_FLIP | H_FLIP))) \
272 bp = pCache + StartLine; \
273 for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \
275 /*if (*(uint32 *) bp)*/if (((uint32)bp[0])|((uint32)bp[2])|((uint32)bp[4])|((uint32)bp[6])) \
276 NORMAL (Offset, bp); \
280 if (!(Tile & V_FLIP)) \
282 bp = pCache + StartLine; \
283 for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \
285 /*if (*(uint32 *) (bp + 4))*/if (((uint32)bp[0])|((uint32)bp[2])|((uint32)bp[4])|((uint32)bp[6])) \
286 FLIPPED (Offset, bp); \
292 bp = pCache + 56 - StartLine; \
293 for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \
295 /*if (*(uint32 *) (bp + 4))*/if (((uint32)bp[0])|((uint32)bp[2])|((uint32)bp[4])|((uint32)bp[6])) \
296 FLIPPED (Offset, bp); \
301 bp = pCache + 56 - StartLine; \
302 for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \
304 /*if (*(uint32 *) bp)*/if (((uint32)bp[0])|((uint32)bp[2])|((uint32)bp[4])|((uint32)bp[6])) \
305 NORMAL (Offset, bp); \
311 #define RENDER_CLIPPED_TILEHI(NORMAL, FLIPPED, N) \
312 d1=(d1&0xFF)|((d1&0xFF0000)>>8)|((d2&0xFF)<<16)|((d2&0xFF0000)<<8);\
313 if (!(Tile & (V_FLIP | H_FLIP))) \
315 bp = pCache + StartLine; \
316 for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \
318 /*if ((dd = (*(uint32 *) bp) & d1))*/if ((dd = (((((uint32)bp[6])<<24)|(((uint32)bp[4])<<16)|(((uint32)bp[2])<<8)|((uint32)bp[0]))&d1))) \
319 NORMAL (Offset, (uint8 *) &dd); \
323 if (!(Tile & V_FLIP)) \
325 bp = pCache + StartLine; \
327 /*SWAP_DWORD (d2);*/ \
328 for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \
330 /*if ((dd = *(uint32 *) (bp + 4) & d1))*/if ((dd = (((((uint32)bp[6])<<24)|(((uint32)bp[4])<<16)|(((uint32)bp[2])<<8)|((uint32)bp[0]))&d1))) \
331 FLIPPED (Offset, (uint8 *) &dd); \
337 bp = pCache + 56 - StartLine; \
339 /*SWAP_DWORD (d2);*/ \
340 for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \
342 /*if ((dd = *(uint32 *) (bp + 4) & d1))*/if ((dd = (((((uint32)bp[6])<<24)|(((uint32)bp[4])<<16)|(((uint32)bp[2])<<8)|((uint32)bp[0]))&d1))) \
343 FLIPPED (Offset, (uint8 *) &dd); \
348 bp = pCache + 56 - StartLine; \
349 for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \
351 /*if ((dd = (*(uint32 *) bp) & d1))*/ if ((dd = (((((uint32)bp[6])<<24)|(((uint32)bp[4])<<16)|(((uint32)bp[2])<<8)|((uint32)bp[0]))&d1))) \
352 NORMAL (Offset, (uint8 *) &dd); \