initial upstream import
[drnoksnes] / tile.h
1 /*
2  * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3  *
4  * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and
5  *                           Jerremy Koot (jkoot@snes9x.com)
6  *
7  * Super FX C emulator code 
8  * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and
9  *                           Gary Henderson.
10  * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_.
11  *
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).
15  *
16  * DOS port code contains the works of other authors. See headers in
17  * individual files.
18  *
19  * Snes9x homepage: http://www.snes9x.com
20  *
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.
25  *
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.
29  *
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.
33  *
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
36  * in future versions.
37  *
38  * Super NES and Super Nintendo Entertainment System are trademarks of
39  * Nintendo Co., Limited and its subsidiary companies.
40  */
41 #ifndef _TILE_H_
42 #define _TILE_H_
43
44 #define TILE_PREAMBLE \
45     uint8 *pCache; \
46 \
47     uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); \
48     if ((Tile & 0x1ff) >= 256) \
49         TileAddr += BG.NameSelect; \
50 \
51     TileAddr &= 0xffff; \
52 \
53     uint32 TileNumber; \
54     pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) << 6]; \
55 \
56     if (!BG.Buffered [TileNumber]) \
57         BG.Buffered[TileNumber] = ConvertTile (pCache, TileAddr); \
58 \
59     if (BG.Buffered [TileNumber] == BLANK_TILE) \
60         return; \
61 \
62     register uint32 l; \
63     if (BG.DirectColourMode) \
64     { \
65         if (IPPU.DirectColourMapsNeedRebuild) \
66             S9xBuildDirectColourMaps (); \
67         gfx->ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; \
68     } \
69     else \
70         gfx->ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette];
71
72 #define RENDER_TILE(NORMAL, FLIPPED, N) \
73     if (!(Tile & (V_FLIP | H_FLIP))) \
74     { \
75         bp = pCache + StartLine; \
76         for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \
77         { \
78             if (*(uint32 *) bp) \
79                 NORMAL (Offset, bp, gfx); \
80             if (*(uint32 *) (bp + 4)) \
81                 NORMAL (Offset + N, bp + 4, gfx); \
82         } \
83     } \
84     else \
85     if (!(Tile & V_FLIP)) \
86     { \
87         bp = pCache + StartLine; \
88         for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \
89         { \
90             if (*(uint32 *) (bp + 4)) \
91                 FLIPPED (Offset, bp + 4, gfx); \
92             if (*(uint32 *) bp) \
93                 FLIPPED (Offset + N, bp, gfx); \
94         } \
95     } \
96     else \
97     if (Tile & H_FLIP) \
98     { \
99         bp = pCache + 56 - StartLine; \
100         for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \
101         { \
102             if (*(uint32 *) (bp + 4)) \
103                 FLIPPED (Offset, bp + 4, gfx); \
104             if (*(uint32 *) bp) \
105                 FLIPPED (Offset + N, bp, gfx); \
106         } \
107     } \
108     else \
109     { \
110         bp = pCache + 56 - StartLine; \
111         for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \
112         { \
113             if (*(uint32 *) bp) \
114                 NORMAL (Offset, bp, gfx); \
115             if (*(uint32 *) (bp + 4)) \
116                 NORMAL (Offset + N, bp + 4, gfx); \
117         } \
118     }
119
120 #define TILE_CLIP_PREAMBLE \
121     uint32 dd; \
122     uint32 d1; \
123     uint32 d2; \
124 \
125     if (StartPixel < 4) \
126     { \
127         d1 = HeadMask [StartPixel]; \
128         if (StartPixel + Width < 4) \
129             d1 &= TailMask [StartPixel + Width]; \
130     } \
131     else \
132         d1 = 0; \
133 \
134     if (StartPixel + Width > 4) \
135     { \
136         if (StartPixel > 4) \
137             d2 = HeadMask [StartPixel - 4]; \
138         else \
139             d2 = 0xffffffff; \
140 \
141         d2 &= TailMask [(StartPixel + Width - 4)]; \
142     } \
143     else \
144         d2 = 0;
145
146
147 #define RENDER_CLIPPED_TILE(NORMAL, FLIPPED, N) \
148     if (!(Tile & (V_FLIP | H_FLIP))) \
149     { \
150         bp = pCache + StartLine; \
151         for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \
152         { \
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); \
157         } \
158     } \
159     else \
160     if (!(Tile & V_FLIP)) \
161     { \
162         bp = pCache + StartLine; \
163         SWAP_DWORD (d1); \
164         SWAP_DWORD (d2); \
165         for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \
166         { \
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); \
171         } \
172     } \
173     else \
174     if (Tile & H_FLIP) \
175     { \
176         bp = pCache + 56 - StartLine; \
177         SWAP_DWORD (d1); \
178         SWAP_DWORD (d2); \
179         for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \
180         { \
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); \
185         } \
186     } \
187     else \
188     { \
189         bp = pCache + 56 - StartLine; \
190         for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \
191         { \
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); \
196         } \
197     }
198
199 #define RENDER_TILE_LARGE(PIXEL, FUNCTION) \
200     if (!(Tile & (V_FLIP | H_FLIP))) \
201     { \
202         if ((pixel = *(pCache + StartLine + StartPixel))) \
203         { \
204             pixel = PIXEL; \
205             for (l = LineCount; l != 0; l--, sp += gfx->PPL, Depth += gfx->PPL) \
206             { \
207                 for (int z = Pixels - 1; z >= 0; z--) \
208                     if (gfx->Z1 > Depth [z]) \
209                     { \
210                         sp [z] = FUNCTION(sp + z, pixel); \
211                         Depth [z] = gfx->Z2; \
212                     }\
213             } \
214         } \
215     } \
216     else \
217     if (!(Tile & V_FLIP)) \
218     { \
219         StartPixel = 7 - StartPixel; \
220         if ((pixel = *(pCache + StartLine + StartPixel))) \
221         { \
222             pixel = PIXEL; \
223             for (l = LineCount; l != 0; l--, sp += gfx->PPL, Depth += gfx->PPL) \
224             { \
225                 for (int z = Pixels - 1; z >= 0; z--) \
226                     if (gfx->Z1 > Depth [z]) \
227                     { \
228                         sp [z] = FUNCTION(sp + z, pixel); \
229                         Depth [z] = gfx->Z2; \
230                     }\
231             } \
232         } \
233     } \
234     else \
235     if (Tile & H_FLIP) \
236     { \
237         StartPixel = 7 - StartPixel; \
238         if ((pixel = *(pCache + 56 - StartLine + StartPixel))) \
239         { \
240             pixel = PIXEL; \
241             for (l = LineCount; l != 0; l--, sp += gfx->PPL, Depth += gfx->PPL) \
242             { \
243                 for (int z = Pixels - 1; z >= 0; z--) \
244                     if (gfx->Z1 > Depth [z]) \
245                     { \
246                         sp [z] = FUNCTION(sp + z, pixel); \
247                         Depth [z] = gfx->Z2; \
248                     }\
249             } \
250         } \
251     } \
252     else \
253     { \
254         if ((pixel = *(pCache + 56 - StartLine + StartPixel))) \
255         { \
256             pixel = PIXEL; \
257             for (l = LineCount; l != 0; l--, sp += gfx->PPL, Depth += gfx->PPL) \
258             { \
259                 for (int z = Pixels - 1; z >= 0; z--) \
260                     if (gfx->Z1 > Depth [z]) \
261                     { \
262                         sp [z] = FUNCTION(sp + z, pixel); \
263                         Depth [z] = gfx->Z2; \
264                     }\
265             } \
266         } \
267     }
268         
269 #define RENDER_TILEHI(NORMAL, FLIPPED, N) \
270     if (!(Tile & (V_FLIP | H_FLIP))) \
271     { \
272         bp = pCache + StartLine; \
273         for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \
274         { \
275             /*if (*(uint32 *) bp)*/if (((uint32)bp[0])|((uint32)bp[2])|((uint32)bp[4])|((uint32)bp[6])) \
276                 NORMAL (Offset, bp); \
277         } \
278     } \
279     else \
280     if (!(Tile & V_FLIP)) \
281     { \
282         bp = pCache + StartLine; \
283         for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \
284         { \
285             /*if (*(uint32 *) (bp + 4))*/if (((uint32)bp[0])|((uint32)bp[2])|((uint32)bp[4])|((uint32)bp[6])) \
286                 FLIPPED (Offset, bp); \
287         } \
288     } \
289     else \
290     if (Tile & H_FLIP) \
291     { \
292         bp = pCache + 56 - StartLine; \
293         for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \
294         { \
295             /*if (*(uint32 *) (bp + 4))*/if (((uint32)bp[0])|((uint32)bp[2])|((uint32)bp[4])|((uint32)bp[6]))  \
296                 FLIPPED (Offset, bp); \
297         } \
298     } \
299     else \
300     { \
301         bp = pCache + 56 - StartLine; \
302         for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \
303         { \
304             /*if (*(uint32 *) bp)*/if (((uint32)bp[0])|((uint32)bp[2])|((uint32)bp[4])|((uint32)bp[6])) \
305                 NORMAL (Offset, bp); \
306         } \
307     }
308     
309     
310     
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))) \
314     { \
315         bp = pCache + StartLine; \
316         for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \
317         { \
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); \
320         } \
321     } \
322     else \
323     if (!(Tile & V_FLIP)) \
324     { \
325         bp = pCache + StartLine; \
326         SWAP_DWORD (d1); \
327         /*SWAP_DWORD (d2);*/ \
328         for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \
329         { \
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); \
332         } \
333     } \
334     else \
335     if (Tile & H_FLIP) \
336     { \
337         bp = pCache + 56 - StartLine; \
338         SWAP_DWORD (d1); \
339         /*SWAP_DWORD (d2);*/ \
340         for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \
341         { \
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); \
344         } \
345     } \
346     else \
347     { \
348         bp = pCache + 56 - StartLine; \
349         for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \
350         { \
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); \
353         } \
354     }    
355
356 #endif