292f9317 |
1 | /* |
2 | Copyright (C) 2003 Rice1964 |
3 | |
4 | This program is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU General Public License |
6 | as published by the Free Software Foundation; either version 2 |
7 | of the License, or (at your option) any later version. |
8 | |
9 | This program is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | GNU General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU General Public License |
15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
17 | |
18 | */ |
19 | |
20 | #include <algorithm> |
21 | #include <SDL.h> |
22 | |
23 | #include "ConvertImage.h" |
24 | #include "GraphicsContext.h" |
25 | #include "Render.h" |
26 | #include "RenderTexture.h" |
27 | #include "Video.h" |
28 | #include "ucode.h" |
29 | #include <time.h> |
30 | |
31 | ////////////////////////////////////////////////////////// |
32 | ////////////////////////////////////////////////////////// |
33 | // uCode Config // |
34 | ////////////////////////////////////////////////////////// |
35 | ////////////////////////////////////////////////////////// |
36 | #define MAX_UCODE_INFO 16 |
37 | UcodeInfo ucodeInfo[MAX_UCODE_INFO]; |
38 | |
39 | RDPInstruction LoadedUcodeMap[256]; |
40 | char* LoadedUcodeNameMap[256]; |
41 | |
42 | OSTask *g_pOSTask = NULL; |
43 | UcodeInfo lastUcodeInfo; |
44 | UcodeInfo UsedUcodes[MAX_UCODE_INFO]; |
45 | const uint32 maxUsedUcodes = sizeof(UsedUcodes)/sizeof(UcodeInfo); |
46 | |
47 | ////////////////////////////////////////////////////////// |
48 | ////////////////////////////////////////////////////////// |
49 | // Ucodes // |
50 | ////////////////////////////////////////////////////////// |
51 | ////////////////////////////////////////////////////////// |
52 | |
53 | UcodeMap *ucodeMaps[] = |
54 | { |
55 | &ucodeMap0, // ucode 0 - Mario |
56 | &ucodeMap1, // ucode 1 - GBI1 |
57 | NULL, // ucode 2 - Golden Eye |
58 | &ucodeMap3, // ucode 3 - S2DEX GBI2 |
59 | NULL, // ucode 4 - Wave Racer |
60 | &ucodeMap5, // ucode 5 - BGI2 |
61 | NULL, // ucode 6 - DKR |
62 | &ucodeMap7, // ucode 7 - S2DEX |
63 | NULL, // ucode 8 - ucode 0 with sprite2D, for Demo Puzzle Master 64 |
64 | NULL, // ucode 9 - Perfect Dark |
65 | NULL, // ucode 10 - Conker |
66 | NULL, // ucode 11 - Gemini |
67 | NULL, // ucode 12 - Silicon Valley, Spacestation |
68 | NULL, // ucode 13 - modified ucode S2DEX |
69 | NULL, // ucode 14 - OgreBattle Background |
70 | NULL, // ucode 15 - ucode 0 with sprite2D |
71 | NULL, // ucode 16 - Star War, Shadow of Empire |
72 | NULL, // ucode 17 - Star Wars - Rogue Squadron, |
73 | NULL, // ucode 18 - World Driver Championship |
74 | NULL, // ucode 19 - Last Legion UX |
75 | &ucodeMap1, // ucode 20 - ZSortp |
76 | }; |
77 | |
78 | uint32 vertexMultVals[] = |
79 | { |
80 | 10, // ucode 0 - Mario |
81 | 2, // ucode 1 - GBI1 |
82 | 10, // ucode 2 - Golden Eye |
83 | 2, // ucode 3 - S2DEX GBI2 |
84 | 5, // ucode 4 - Wave Racer |
85 | 2, // ucode 5 - BGI2 |
86 | 10, // ucode 6 - DKR |
87 | 2, // ucode 7 - S2DEX |
88 | 10, // ucode 8 - ucode 0 with sprite2D, for Demo Puzzle Master 64 |
89 | 10, // ucode 9 - Perfect Dark |
90 | 2, // ucode 10 - Conker |
91 | 10, // ucode 11 - Gemini |
92 | 2, // ucode 12 - Silicon Valley, Spacestation |
93 | 2, // ucode 13 - modified ucode S2DEX |
94 | 2, // ucode 14 - OgreBattle Background |
95 | 10, // ucode 15 - ucode 0 with sprite2D |
96 | 5, // ucode 16 - Star War, Shadow of Empire |
97 | |
98 | 2, // ucode 17 - Star Wars - Rogue Squadron, |
99 | 2, // ucode 18 - World Driver Championship, check me here |
100 | 2, // ucode 19 - Last Legion UX, check me here |
101 | 2, // ucode 20 - ZSortp |
102 | }; |
103 | |
104 | unsigned char gLastMicrocodeString[ 300 ] = ""; |
105 | |
106 | //***************************************************************************** |
107 | // |
108 | //***************************************************************************** |
109 | static UcodeData g_UcodeData[] = |
110 | { |
111 | //crc_size, crc_800; |
112 | |
113 | {0, 0x150c3ce8, 0x150c3ce8, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, // Super Mario 64 |
114 | {4, 0x2b94276f, 0x2b94276f, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, // Wave Race 64 (v1.0) |
115 | {16,0xb1870454, 0xb1870454, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, // Star Wars - Shadows of the Empire (v1.0), |
116 | {0, 0x51671ae4, 0x51671ae4, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, // Pilot Wings 64, |
117 | {0, 0x67b5ac55, 0x67b5ac55, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, // Wibble, |
118 | {0, 0x64dc8104, 0x64dc8104, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, // Dark Rift, |
119 | {0, 0x309f363d, 0x309f363d, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, // Killer Instinct Gold, |
120 | {0, 0xfcb57e57, 0xfcb57e57, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, // Blast Corps, |
121 | {0, 0xb420f35a, 0xb420f35a, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, // Blast Corps, |
122 | {0, 0x6e26c1df, 0x7c98e9c2, (unsigned char*)"RSP SW Version: 2.0D, 04-01-96",}, |
123 | {2, 0xc02ac7bc, 0xc02ac7bc, (unsigned char*)"RSP SW Version: 2.0G, 09-30-96",}, // GoldenEye 007, |
124 | {0, 0xe5fee3bc, 0xe5fee3bc, (unsigned char*)"RSP SW Version: 2.0G, 09-30-96",}, // Aero Fighters Assault, |
125 | {8, 0xe4bb5ad8, 0x80129845, (unsigned char*)"RSP SW Version: 2.0G, 09-30-96",}, // Puzzle Master 64, |
126 | {0, 0x72109ec6, 0x72109ec6, (unsigned char*)"RSP SW Version: 2.0H, 02-12-97",}, // Duke Nukem 64, |
127 | {0, 0xf24a9a04, 0xf24a9a04, (unsigned char*)"RSP SW Version: 2.0H, 02-12-97",}, // Tetrisphere, |
128 | {15,0x700de42e, 0x700de42e, (unsigned char*)"RSP SW Version: 2.0H, 02-12-97",}, // Wipeout 64 (uses GBI1 too!), |
129 | {15,0x1b304a74, 0x1b304a74, (unsigned char*)"RSP SW Version: 2.0H, 02-12-97",}, // Flying Dragon, |
130 | {15,0xe4bb5ad8, 0xa7b2f704, (unsigned char*)"RSP SW Version: 2.0H, 02-12-97",}, // Silicon Valley, |
131 | {15,0xe4bb5ad8, 0x88202781, (unsigned char*)"RSP SW Version: 2.0H, 02-12-97",}, // Glover, |
132 | {0, 0xe466b5bd, 0xe466b5bd, (unsigned char*)"Unknown 0xe466b5bd, 0xe466b5bd",}, // Dark Rift, |
133 | {9, 0x7064a163, 0x7064a163, (unsigned char*)"Unknown 0x7064a163, 0x7064a163",}, // Perfect Dark (v1.0), |
134 | {0, 0x6522df69, 0x71bd078d, (unsigned char*)"Unknown 0x6522df69, 0x71bd078d",}, // Tetris |
135 | {0, 0x6522df69, 0x1b0c23a8, (unsigned char*)"Unknown 0x6522df69, 0x1b0c23a8",}, // Pachinko Nichi |
136 | |
137 | // GBI1 |
138 | |
139 | {1, 0x45ca328e, 0x45ca328e, (unsigned char*)"RSP Gfx ucode F3DLX 0.95 Yoshitaka Yasumoto Nintendo.",}, // Mario Kart 64, |
140 | {1, 0x98e3b909, 0x98e3b909, (unsigned char*)"RSP Gfx ucode F3DEX 0.95 Yoshitaka Yasumoto Nintendo.",}, // Mario Kart 64 |
141 | {1, 0x5d446090, 0x5d446090, (unsigned char*)"RSP Gfx ucode F3DLP.Rej 0.96 Yoshitaka Yasumoto Nintendo.",0,1}, // Jikkyou J. League Perfect Striker, |
142 | {1, 0x244f5ca3, 0x244f5ca3, (unsigned char*)"RSP Gfx ucode F3DEX 1.00 Yoshitaka Yasumoto Nintendo.",}, // F-1 Pole Position 64, |
143 | {1, 0x6a022585, 0x6a022585, (unsigned char*)"RSP Gfx ucode F3DEX.NoN 1.00 Yoshitaka Yasumoto Nintendo.",1}, // Turok - The Dinosaur Hunter (v1.0), |
144 | {1, 0x150706be, 0x150706be, (unsigned char*)"RSP Gfx ucode F3DLX.NoN 1.00 Yoshitaka Yasumoto Nintendo.",1}, // Extreme-G, |
145 | {1, 0x503f2c53, 0x503f2c53, (unsigned char*)"RSP Gfx ucode F3DEX.NoN 1.21 Yoshitaka Yasumoto Nintendo.",1}, // Bomberman 64, |
146 | {1, 0xc705c37c, 0xc705c37c, (unsigned char*)"RSP Gfx ucode F3DLX 1.21 Yoshitaka Yasumoto Nintendo.",}, // Fighting Force 64, Wipeout 64 |
147 | {1, 0xa2146075, 0xa2146075, (unsigned char*)"RSP Gfx ucode F3DLX.NoN 1.21 Yoshitaka Yasumoto Nintendo.",1}, // San Francisco Rush - Extreme Racing, |
148 | {1, 0xb65aa2da, 0xb65aa2da, (unsigned char*)"RSP Gfx ucode L3DEX 1.21 Yoshitaka Yasumoto Nintendo.",}, // Wipeout 64, |
149 | {1, 0x0c8e5ec9, 0x0c8e5ec9, (unsigned char*)"RSP Gfx ucode F3DEX 1.21 Yoshitaka Yasumoto Nintendo.",}, // |
150 | {1, 0xe30795f2, 0xa53df3c4, (unsigned char*)"RSP Gfx ucode F3DLP.Rej 1.21 Yoshitaka Yasumoto Nintendo.",0,1}, |
151 | |
152 | {1, 0xaebeda7d, 0xaebeda7d, (unsigned char*)"RSP Gfx ucode F3DLX.Rej 1.21 Yoshitaka Yasumoto Nintendo.",0,1}, // Jikkyou World Soccer 3, |
153 | {1, 0x0c8e5ec9, 0x0c8e5ec9, (unsigned char*)"RSP Gfx ucode F3DEX 1.23 Yoshitaka Yasumoto Nintendo" ,}, // Wave Race 64 (Rev. 2) - Shindou Rumble Edition (JAP) |
154 | {1, 0xc705c37c, 0xc705c37c, (unsigned char*)"RSP Gfx ucode F3DLX 1.23 Yoshitaka Yasumoto Nintendo.",}, // GT |
155 | {1, 0x2a61350d, 0x2a61350d, (unsigned char*)"RSP Gfx ucode F3DLX 1.23 Yoshitaka Yasumoto Nintendo.",}, // Toy Story2 |
156 | {1, 0x0c8e5ec9, 0x0c8e5ec9, (unsigned char*)"RSP Gfx ucode F3DEX 1.23 Yoshitaka Yasumoto Nintendo.",}, // Wave Race 64 Shindou Edition |
157 | {12,0xfc6529aa, 0xfc6529aa, (unsigned char*)"RSP Gfx ucode F3DEX 1.23 Yoshitaka Yasumoto Nintendo.",}, // Superman - The Animated Series, |
158 | {1, 0xa56cf996, 0xa56cf996, (unsigned char*)"RSP Gfx ucode L3DEX 1.23 Yoshitaka Yasumoto Nintendo.",}, // Flying Dragon, |
159 | {1, 0xcc83b43f, 0xcc83b43f, (unsigned char*)"RSP Gfx ucode F3DEX.NoN 1.23 Yoshitaka Yasumoto Nintendo.",1}, // AeroGauge, |
160 | {1, 0xca8927a0, 0xca8927a0, (unsigned char*)"RSP Gfx ucode F3DLX.Rej 1.23 Yoshitaka Yasumoto Nintendo.",0,1}, // Puzzle Bobble 64, |
161 | {1, 0x25689c75, 0xbe481ae8, (unsigned char*)"RSP Gfx ucode F3DLP.Rej 1.23 Yoshitaka Yasumoto Nintendo.",0,1}, |
162 | {1, 0xd2d747b7, 0xd2d747b7, (unsigned char*)"RSP Gfx ucode F3DLX.NoN 1.23 Yoshitaka Yasumoto Nintendo.",1}, // Penny Racers, |
163 | {1, 0xa849c858, 0x5bd32b5a, (unsigned char*)"RSP Gfx ucode F3DTEX/A 1.23 Yoshitaka Yasumoto Nintendo.",}, // Tamagotchi |
164 | |
165 | {7, 0xecd8b772, 0xecd8b772, (unsigned char*)"RSP Gfx ucode S2DEX 1.06 Yoshitaka Yasumoto Nintendo.",}, // Yoshi's Story, |
166 | {7, 0xf59132f5, 0xf59132f5, (unsigned char*)"RSP Gfx ucode S2DEX 1.07 Yoshitaka Yasumoto Nintendo.",}, // Bakuretsu Muteki Bangaioh, |
167 | {7, 0x961dd811, 0x961dd811, (unsigned char*)"RSP Gfx ucode S2DEX 1.03 Yoshitaka Yasumoto Nintendo.",}, // GT |
168 | |
169 | {5, 0x3e083afa, 0x722f97cc, (unsigned char*)"RSP Gfx ucode F3DEX.NoN fifo 2.03 Yoshitaka Yasumoto 1998 Nintendo.",1}, // F-Zero X, |
170 | {5, 0xa8050bd1, 0xa8050bd1, (unsigned char*)"RSP Gfx ucode F3DEX fifo 2.03 Yoshitaka Yasumoto 1998 Nintendo.",}, // F-Zero X, |
171 | {5, 0x4e8055f0, 0x4e8055f0, (unsigned char*)"RSP Gfx ucode F3DLX.Rej fifo 2.03 Yoshitaka Yasumoto 1998 Nintendo.",0,1}, // F-Zero X, |
172 | {5, 0xabf001f5, 0xabf001f5, (unsigned char*)"RSP Gfx ucode F3DFLX.Rej fifo 2.03F Yoshitaka Yasumoto 1998 Nintendo.",0,1}, // F-Zero X, |
173 | {5, 0xadb4b686, 0xadb4b686, (unsigned char*)"RSP Gfx ucode F3DEX fifo 2.04 Yoshitaka Yasumoto 1998 Nintendo.",}, // Top Gear Rally 2, |
174 | {5, 0x779e2a9b, 0x779e2a9b, (unsigned char*)"RSP Gfx ucode F3DEX.NoN fifo 2.04 Yoshitaka Yasumoto 1998 Nintendo.",1}, // California Speed, |
175 | {5, 0xa8cb3e09, 0xa8cb3e09, (unsigned char*)"RSP Gfx ucode L3DEX fifo 2.04 Yoshitaka Yasumoto 1998 Nintendo.",}, // In-Fisherman Bass Hunter 64, |
176 | {5, 0x2a1341d6, 0x2a1341d6, (unsigned char*)"RSP Gfx ucode F3DEX fifo 2.04H Yoshitaka Yasumoto 1998 Nintendo.",}, // Kirby 64 - The Crystal Shards, |
177 | {5, 0x3e083afa, 0x89a8e0ed, (unsigned char*)"RSP Gfx ucode F3DEX.NoN fifo 2.05 Yoshitaka Yasumoto 1998 Nintendo.",1}, // Carmageddon 64 (uncensored), |
178 | {5, 0x4964b75d, 0x4964b75d, (unsigned char*)"RSP Gfx ucode F3DEX.NoN fifo 2.05 Yoshitaka Yasumoto 1998 Nintendo.",1}, |
179 | {5, 0x39e3e95a, 0x39e3e95a, (unsigned char*)"RSP Gfx ucode F3DEX fifo 2.05 Yoshitaka Yasumoto 1998 Nintendo."}, // Knife Edge - Nose Gunner, |
180 | {5, 0xd2913522, 0xd2913522, (unsigned char*)"RSP Gfx ucode F3DAM fifo 2.05 Yoshitaka Yasumoto 1998 Nintendo."}, // Hey You, Pikachu!, |
181 | {5, 0x3e083afa, 0xc998443f, (unsigned char*)"RSP Gfx ucode F3DEX xbus 2.05 Yoshitaka Yasumoto 1998 Nintendo."}, //Triple play |
182 | {5, 0xf4184a7d, 0xf4184a7d, (unsigned char*)"RSP Gfx ucode F3DEX fifo 2.06 Yoshitaka Yasumoto 1998 Nintendo.",}, // Hey You, Pikachu!, |
183 | {5, 0x595a88de, 0x595a88de, (unsigned char*)"RSP Gfx ucode F3DEX.Rej fifo 2.06 Yoshitaka Yasumoto 1998 Nintendo.",0,1}, // Bio Hazard 2, |
184 | {5, 0x0259f764, 0x0259f764, (unsigned char*)"RSP Gfx ucode F3DLX.Rej fifo 2.06 Yoshitaka Yasumoto 1998 Nintendo.",0,1}, // Mario Party, |
185 | {5, 0xe1a5477a, 0xe1a5477a, (unsigned char*)"RSP Gfx ucode F3DEX.NoN xbus 2.06 Yoshitaka Yasumoto 1998 Nintendo.",1}, // Command & Conquer, |
186 | {5, 0x4cfa0a19, 0x4cfa0a19, (unsigned char*)"RSP Gfx ucode F3DZEX.NoN fifo 2.06H Yoshitaka Yasumoto 1998 Nintendo.",1}, // The Legend of Zelda - Ocarina of Time (v1.0), |
187 | {5, 0x2cbd9514, 0x5f40b9f5, (unsigned char*)"RSP Gfx ucode F3DZEX.NoN fifo 2.06H Yoshitaka Yasumoto 1998 Nintendo.",1}, |
188 | |
189 | {5, 0x3e083afa, 0x882680f4, (unsigned char*)"RSP Gfx ucode L3DEX fifo 2.07 Yoshitaka Yasumoto 1998 Nintendo."}, // Polaris Sno |
190 | |
191 | {5, 0xdeb1cac0, 0xdeb1cac0, (unsigned char*)"RSP Gfx ucode F3DEX.NoN fifo 2.07 Yoshitaka Yasumoto 1998 Nintendo.",1}, // Knockout Kings 2000, |
192 | {5, 0xf4184a7d, 0xf4184a7d, (unsigned char*)"RSP Gfx ucode F3DEX fifo 2.07 Yoshitaka Yasumoto 1998 Nintendo.",}, // Xena Warrior Princess - Talisman of Fate, Army Men - Air Combat, Destruction Derby |
193 | {5, 0x4b013e60, 0x4b013e60, (unsigned char*)"RSP Gfx ucode F3DEX xbus 2.07 Yoshitaka Yasumoto 1998 Nintendo.",}, // Lode Runner 3-D, |
194 | {5, 0xd1a63836, 0xd1a63836, (unsigned char*)"RSP Gfx ucode L3DEX fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // Hey You, Pikachu!, |
195 | {5, 0x97193667, 0x97193667, (unsigned char*)"RSP Gfx ucode F3DEX fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // Top Gear Hyper-Bike, |
196 | {5, 0x92149ba8, 0x92149ba8, (unsigned char*)"RSP Gfx ucode F3DEX fifo 2.08 Yoshitaka Yasumoto/Kawasedo 1999.",}, // Paper Mario, |
197 | {5, 0xae0fb88f, 0xae0fb88f, (unsigned char*)"RSP Gfx ucode F3DEX xbus 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // WWF WrestleMania 2000, |
198 | {5, 0xc572f368, 0xc572f368, (unsigned char*)"RSP Gfx ucode F3DLX.Rej xbus 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // WWF No Mercy, |
199 | {5, 0x3e083afa, 0x74252492, (unsigned char*)"RSP Gfx ucode F3DEX.NoN xbus 2.08 Yoshitaka Yasumoto 1999 Nintendo.",1}, |
200 | |
201 | {5, 0x9c2edb70, 0xea98e740, (unsigned char*)"RSP Gfx ucode F3DEX.NoN fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",1}, // LEGO Racers, |
202 | {5, 0x79e004a6, 0x79e004a6, (unsigned char*)"RSP Gfx ucode F3DLX.Rej fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",0,1}, // Mario Party 2, |
203 | {5, 0xaa6ab3ca, 0xaa6ab3ca, (unsigned char*)"RSP Gfx ucode F3DEX.Rej fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",0,1}, // V-Rally Edition 99, |
204 | {5, 0x2c597e0f, 0x2c597e0f, (unsigned char*)"RSP Gfx ucode F3DEX fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // Cruis'n Exotica, |
205 | {10, 0x4e5f3e3b, 0x4e5f3e3b,(unsigned char*)"RSP Gfx ucode F3DEXBG.NoN fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",1}, // Conker The Bad Fur Day |
206 | {5, 0x61f31862, 0x61f31862, (unsigned char*)"RSP Gfx ucode F3DEX.NoN fifo 2.08H Yoshitaka Yasumoto 1999 Nintendo.",1}, // Pokemon Snap, |
207 | {5, 0x005f5b71, 0x005f5b71, (unsigned char*)"RSP Gfx ucode F3DZEX.NoN fifo 2.08I Yoshitaka Yasumoto/Kawasedo 1999.",1}, // The Legend of Zelda 2 - Majora's Mask, |
208 | |
209 | {3, 0x41839d1e, 0x41839d1e, (unsigned char*)"RSP Gfx ucode S2DEX fifo 2.05 Yoshitaka Yasumoto 1998 Nintendo.",}, // Chou Snobow Kids, |
210 | {3, 0x2cbd9514, 0xc639dbb9, (unsigned char*)"RSP Gfx ucode S2DEX xbus 2.06 Yoshitaka Yasumoto 1998 Nintendo.",}, |
211 | {3, 0xec89e273, 0xec89e273, (unsigned char*)"RSP Gfx ucode S2DEX fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // V-Rally Edition 99, |
212 | {3, 0x9429b7d6, 0x9429b7d6, (unsigned char*)"RSP Gfx ucode S2DEX xbus 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // Star Craft, |
213 | //{14,0x5a72397b, 0xec89e273, "RSP Gfx ucode S2DEX fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // OgreBattle Background, |
214 | {3, 0x2cbd9514, 0xec89e273, (unsigned char*)"RSP Gfx ucode S2DEX fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // Zelda MM, |
215 | |
216 | {6, 0x6aef74f8, 0x6aef74f8, (unsigned char*)"Unknown 0x6aef74f8, 0x6aef74f8",}, // Diddy Kong Racing (v1.0), |
217 | {6, 0x4c4eead8, 0x4c4eead8, (unsigned char*)"Unknown 0x4c4eead8, 0x4c4eead8",}, // Diddy Kong Racing (v1.1), |
218 | |
219 | {1, 0xed421e9a, 0xed421e9a, (unsigned char*)"Unknown 0xed421e9a, 0xed421e9a",}, // Kuiki Uhabi Suigo, |
220 | {5, 0x37751932, 0x55c0fd25, (unsigned char*)"Unknown 0x37751932, 0x55c0fd25",}, // Bio Hazard 2, |
221 | {11,0xbe0b83e7, 0xbe0b83e7,(unsigned char*)"Unknown 0xbe0b83e7, 0xbe0b83e7",}, // Jet Force Gemini, |
222 | |
223 | {17, 0x02e882cf, 0x2ad17281, (unsigned char*)"Unknown 0x02e882cf, 0x2ad17281",}, // Indiana Jones, |
224 | {17, 0x1f7d9118, 0xdab2199b, (unsigned char*)"Unknown 0x1f7d9118, 0xdab2199b",}, // Battle Naboo, |
225 | {17, 0x74583614, 0x74583614, (unsigned char*)"Unknown 0x74583614, 0x74583614",}, // Star Wars - Rogue Squadron, |
226 | {17, 0xe37e2f49, 0x1eb63fd8, (unsigned char*)"Unknown 0xe37e2f49, 0x1eb63fd8",}, // Star Wars - Rogue Squadron, |
227 | {17, 0x8ce1af3d, 0xb2760ea2, (unsigned char*)"Unknown 0x8ce1af3d, 0xb2760ea2",}, // Star Wars - Rogue Squadron, |
228 | |
229 | {18, 0x7b685972, 0x57b8095a, (unsigned char*)"Unknown 0x7b685972, 0x57b8095a",}, // World Driver Championship |
230 | {18, 0xe92dbb9b, 0x57b8095a, (unsigned char*)"Unknown 0xe92dbb9b, 0x57b8095a",}, // World Driver Championship |
231 | {18, 0xe6c9acc1, 0x65f80845, (unsigned char*)"Unknown 0xe6c9acc1, 0x65f80845",}, // World Driver Championship |
232 | {18, 0x6522df69, 0x720b88a0, (unsigned char*)"Unknown 0x6522df69, 0x720b88a0",}, // World Driver Championship |
233 | {18, 0x6522df69, 0xf1e8ba9e, (unsigned char*)"Unknown 0x6522df69, 0xf1e8ba9e",}, // World Driver Championship |
234 | |
235 | {19, 0xa486bed3, 0xa486bed3, (unsigned char*)"Unknown 0xa486bed3, 0xa486bed3",}, // Last Legion UX, |
236 | {19, 0x6b519381, 0xfebacfd8, (unsigned char*)"Unknown in Toukan Road",}, // I don't know which ucode |
237 | |
238 | {20, 0x6d2a01b1, 0x6d2a01b1, (unsigned char*)"RSP Gfx ucode ZSortp 0.33 Yoshitaka Yasumoto Nintendo.",}, // Mia Hamm Soccer 64, |
239 | }; |
240 | |
241 | FiddledVtx * g_pVtxBase=NULL; |
242 | |
243 | SetImgInfo g_TI = { TXT_FMT_RGBA, TXT_SIZE_16b, 1, 0 }; |
244 | SetImgInfo g_CI = { TXT_FMT_RGBA, TXT_SIZE_16b, 1, 0 }; |
245 | SetImgInfo g_ZI = { TXT_FMT_RGBA, TXT_SIZE_16b, 1, 0 }; |
246 | RenderTextureInfo g_ZI_saves[2]; |
247 | |
248 | DListStack gDlistStack[MAX_DL_STACK_SIZE]; |
249 | int gDlistStackPointer= -1; |
250 | |
251 | TMEMLoadMapInfo g_tmemLoadAddrMap[0x200]; // Totally 4KB TMEM |
252 | TMEMLoadMapInfo g_tmemInfo0; // Info for Tmem=0 |
253 | TMEMLoadMapInfo g_tmemInfo1; // Info for Tmem=0x100 |
254 | |
255 | const char *pszImgSize[4] = {"4", "8", "16", "32"}; |
256 | const char *textluttype[4] = {"RGB16", "I16?", "RGBA16", "IA16"}; |
257 | uint16 g_wRDPTlut[0x200]; |
258 | uint32 g_dwRDPPalCrc[16]; |
259 | |
260 | #include "FrameBuffer.h" |
261 | #include "RSP_GBI0.h" |
262 | #include "RSP_GBI1.h" |
263 | #include "RSP_GBI2.h" |
264 | #include "RSP_GBI2_ext.h" |
265 | #include "RSP_GBI_Others.h" |
266 | #include "RSP_GBI_Sprite2D.h" |
267 | #include "RDP_Texture.h" |
268 | |
269 | ////////////////////////////////////////////////////////// |
270 | ////////////////////////////////////////////////////////// |
271 | // Init and Reset // |
272 | ////////////////////////////////////////////////////////// |
273 | ////////////////////////////////////////////////////////// |
274 | |
275 | void DLParser_Init() |
276 | { |
277 | int i; |
278 | |
279 | status.gRDPTime = 0; |
280 | status.gDlistCount = 0; |
281 | status.gUcodeCount = 0; |
282 | status.frameReadByCPU = FALSE; |
283 | status.frameWriteByCPU = FALSE; |
284 | status.SPCycleCount = 0; |
285 | status.DPCycleCount = 0; |
286 | status.bN64IsDrawingTextureBuffer = false; |
287 | status.bDirectWriteIntoRDRAM = false; |
288 | status.bHandleN64RenderTexture = false; |
289 | |
290 | status.bUcodeIsKnown = FALSE; |
291 | status.lastPurgeTimeTime = status.gRDPTime; |
292 | |
293 | status.curRenderBuffer = 0; |
294 | status.curDisplayBuffer = 0; |
295 | status.curVIOriginReg = 0; |
296 | |
297 | status.primitiveType = PRIM_TRI1; |
298 | |
299 | status.lastPurgeTimeTime = 0; // Time textures were last purged |
300 | |
301 | status.UseLargerTile[0] = false; |
302 | status.LargerTileRealLeft[0] = status.LargerTileRealLeft[1] = 0; |
303 | memset(&g_ZI_saves, 0, sizeof(RenderTextureInfo)*2); |
304 | |
305 | for( i=0; i<8; i++ ) |
306 | { |
307 | memset(&gRDP.tiles[i], 0, sizeof(Tile)); |
308 | } |
309 | memset(g_tmemLoadAddrMap, 0, sizeof(g_tmemLoadAddrMap)); |
310 | |
311 | for( i=0; i<MAX_UCODE_INFO; i++ ) |
312 | { |
313 | memset(&ucodeInfo[i], 0, sizeof(UcodeInfo)); |
314 | } |
315 | |
316 | status.bUseModifiedUcodeMap = false; |
317 | status.ucodeHasBeenSet = false; |
318 | status.bAllowLoadFromTMEM = true; |
319 | |
320 | char name[200]; |
321 | strcpy(name, (char*)g_curRomInfo.szGameName); |
322 | |
323 | memset(&lastUcodeInfo, 0, sizeof(UcodeInfo)); |
324 | memset(&UsedUcodes, 0, sizeof(UsedUcodes)); |
325 | memset(&g_TmemFlag, 0, sizeof(g_TmemFlag)); |
326 | memset(&g_RecentCIInfo, 0, sizeof(RecentCIInfo)*5); |
327 | memset(&g_RecentVIOriginInfo, 0, sizeof(RecentViOriginInfo)*5); |
328 | memset(&g_ZI_saves, 0, sizeof(RenderTextureInfo)*2); |
329 | memset(&g_ZI, 0, sizeof(SetImgInfo)); |
330 | memset(&g_CI, 0, sizeof(SetImgInfo)); |
331 | memset(&g_TI, 0, sizeof(SetImgInfo)); |
332 | |
333 | status.UseLargerTile[0] = status.UseLargerTile[1] = false; |
334 | status.LargerTileRealLeft[0] = status.LargerTileRealLeft[1] = 0; |
335 | } |
336 | |
337 | |
338 | void RDP_GFX_Reset() |
339 | { |
340 | gDlistStackPointer=-1; |
341 | status.bUcodeIsKnown = FALSE; |
342 | gTextureManager.RecycleAllTextures(); |
343 | } |
344 | |
345 | |
346 | void RDP_Cleanup() |
347 | { |
348 | if( status.bHandleN64RenderTexture ) |
349 | { |
350 | g_pFrameBufferManager->CloseRenderTexture(false); |
351 | } |
352 | } |
353 | |
354 | void RDP_SetUcodeMap(int ucode) |
355 | { |
356 | status.bUseModifiedUcodeMap = false; |
357 | switch( ucode ) |
358 | { |
359 | case 0: // Mario and demos |
360 | break; |
361 | case 1: // F3DEX GBI1 |
362 | case 20: |
363 | break; |
364 | case 2: // Golden Eye |
365 | memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap)); |
366 | //LoadedUcodeMap[9]=RSP_GBI1_Sprite2DBase; |
367 | //LoadedUcodeMap[0xaf]=RSP_GBI1_LoadUCode; |
368 | //LoadedUcodeMap[0xb0]=RSP_GBI1_BranchZ; |
369 | LoadedUcodeMap[0xb4]=DLParser_RDPHalf_1_0xb4_GoldenEye; |
370 | status.bUseModifiedUcodeMap = true; |
371 | break; |
372 | case 3: // S2DEX GBI2 |
373 | break; |
374 | case 4: |
375 | memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap)); |
376 | LoadedUcodeMap[4]=RSP_Vtx_WRUS; |
377 | LoadedUcodeMap[0xb1]=RSP_GBI1_Tri2; |
378 | //LoadedUcodeMap[9]=RSP_GBI1_Sprite2DBase; |
379 | //LoadedUcodeMap[0xaf]=RSP_GBI1_LoadUCode; |
380 | //LoadedUcodeMap[0xb0]=RSP_GBI1_BranchZ; |
381 | //LoadedUcodeMap[0xb2]=RSP_GBI1_ModifyVtx; |
382 | status.bUseModifiedUcodeMap = true; |
383 | break; |
384 | case 5: // F3DEX GBI2 |
385 | break; |
386 | case 6: // DKR, Jet Force Gemini, Mickey |
387 | case 11: // DKR, Jet Force Gemini, Mickey |
388 | memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap)); |
389 | LoadedUcodeMap[1]=RSP_Mtx_DKR; |
390 | LoadedUcodeMap[4]=RSP_Vtx_DKR; |
391 | if( ucode == 11 ) LoadedUcodeMap[4]=RSP_Vtx_Gemini; |
392 | LoadedUcodeMap[5]=RSP_DMA_Tri_DKR; |
393 | LoadedUcodeMap[7]=RSP_DL_In_MEM_DKR; |
394 | LoadedUcodeMap[0xbc]=RSP_MoveWord_DKR; |
395 | LoadedUcodeMap[0xbf]=DLParser_Set_Addr_Ucode6; |
396 | //LoadedUcodeMap[9]=RSP_GBI1_Sprite2DBase; |
397 | //LoadedUcodeMap[0xb0]=RSP_GBI1_BranchZ; |
398 | //LoadedUcodeMap[0xb2]=RSP_GBI1_ModifyVtx; |
399 | status.bUseModifiedUcodeMap = true; |
400 | break; |
401 | case 7: // S2DEX GBI1 |
402 | break; |
403 | case 8: // Ucode 0 with Sprite2D, Puzzle Master 64 |
404 | memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap)); |
405 | LoadedUcodeMap[RSP_SPRITE2D_BASE] = RSP_GBI_Sprite2D_PuzzleMaster64; |
406 | LoadedUcodeMap[RSP_SPRITE2D_SCALEFLIP] = RSP_GBI1_Sprite2DScaleFlip; |
407 | LoadedUcodeMap[RSP_SPRITE2D_DRAW] = RSP_GBI0_Sprite2DDraw; |
408 | status.bUseModifiedUcodeMap = true; |
409 | break; |
410 | case 9: // Perfect Dark |
411 | memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap)); |
412 | LoadedUcodeMap[4]=RSP_Vtx_PD; |
413 | LoadedUcodeMap[7]=RSP_Set_Vtx_CI_PD; |
414 | LoadedUcodeMap[0xb1]=RSP_Tri4_PD; |
415 | LoadedUcodeMap[0xb4]=DLParser_RDPHalf_1_0xb4_GoldenEye; |
416 | status.bUseModifiedUcodeMap = true; |
417 | break; |
418 | case 10: // Conker BFD |
419 | memcpy( &LoadedUcodeMap, &ucodeMap5, sizeof(UcodeMap)); |
420 | LoadedUcodeMap[1]=RSP_Vtx_Conker; |
421 | LoadedUcodeMap[0x10]=DLParser_Tri4_Conker; |
422 | LoadedUcodeMap[0x11]=DLParser_Tri4_Conker; |
423 | LoadedUcodeMap[0x12]=DLParser_Tri4_Conker; |
424 | LoadedUcodeMap[0x13]=DLParser_Tri4_Conker; |
425 | LoadedUcodeMap[0x14]=DLParser_Tri4_Conker; |
426 | LoadedUcodeMap[0x15]=DLParser_Tri4_Conker; |
427 | LoadedUcodeMap[0x16]=DLParser_Tri4_Conker; |
428 | LoadedUcodeMap[0x17]=DLParser_Tri4_Conker; |
429 | LoadedUcodeMap[0x18]=DLParser_Tri4_Conker; |
430 | LoadedUcodeMap[0x19]=DLParser_Tri4_Conker; |
431 | LoadedUcodeMap[0x1a]=DLParser_Tri4_Conker; |
432 | LoadedUcodeMap[0x1b]=DLParser_Tri4_Conker; |
433 | LoadedUcodeMap[0x1c]=DLParser_Tri4_Conker; |
434 | LoadedUcodeMap[0x1d]=DLParser_Tri4_Conker; |
435 | LoadedUcodeMap[0x1e]=DLParser_Tri4_Conker; |
436 | LoadedUcodeMap[0x1f]=DLParser_Tri4_Conker; |
437 | LoadedUcodeMap[0xdb]=DLParser_MoveWord_Conker; |
438 | LoadedUcodeMap[0xdc]=DLParser_MoveMem_Conker; |
439 | status.bUseModifiedUcodeMap = true; |
440 | break; |
441 | case 12: // Silicon Velley, Space Station |
442 | memcpy( &LoadedUcodeMap, &ucodeMap1, sizeof(UcodeMap)); |
443 | LoadedUcodeMap[0x01]=RSP_GBI0_Mtx; |
444 | status.bUseModifiedUcodeMap = true; |
445 | break; |
446 | case 13: // modified S2DEX |
447 | memcpy( &LoadedUcodeMap, &ucodeMap7, sizeof(UcodeMap)); |
448 | //LoadedUcodeMap[S2DEX_BG_1CYC] = ucodeMap1[S2DEX_BG_1CYC]; |
449 | LoadedUcodeMap[S2DEX_OBJ_RECTANGLE] = ucodeMap1[S2DEX_OBJ_RECTANGLE]; |
450 | LoadedUcodeMap[S2DEX_OBJ_SPRITE] = ucodeMap1[S2DEX_OBJ_SPRITE]; |
451 | //LoadedUcodeMap[S2DEX_OBJ_RENDERMODE] = ucodeMap1[S2DEX_OBJ_RENDERMODE]; |
452 | //LoadedUcodeMap[S2DEX_OBJ_RECTANGLE_R] = ucodeMap1[S2DEX_OBJ_RECTANGLE_R]; |
453 | LoadedUcodeMap[S2DEX_RDPHALF_0] = ucodeMap1[S2DEX_RDPHALF_0]; |
454 | status.bUseModifiedUcodeMap = true; |
455 | break; |
456 | case 14: // OgreBattle Background |
457 | memcpy( &LoadedUcodeMap, &ucodeMap5, sizeof(UcodeMap)); |
458 | LoadedUcodeMap[0xda] = DLParser_OgreBatter64BG; |
459 | LoadedUcodeMap[0xdc] = RSP_S2DEX_OBJ_MOVEMEM; |
460 | status.bUseModifiedUcodeMap = true; |
461 | break; |
462 | case 15: // Ucode 0 with Sprite2D |
463 | memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap)); |
464 | LoadedUcodeMap[RSP_SPRITE2D_BASE] = RSP_GBI_Sprite2DBase; |
465 | LoadedUcodeMap[RSP_SPRITE2D_SCALEFLIP] = RSP_GBI1_Sprite2DScaleFlip; |
466 | LoadedUcodeMap[RSP_SPRITE2D_DRAW] = RSP_GBI0_Sprite2DDraw; |
467 | status.bUseModifiedUcodeMap = true; |
468 | break; |
469 | case 16: // Star War, Shadow Of Empire |
470 | memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap)); |
471 | LoadedUcodeMap[4]=RSP_Vtx_ShadowOfEmpire; |
472 | status.bUseModifiedUcodeMap = true; |
473 | break; |
474 | case 17: //Indiana Jones, does not work anyway |
475 | memcpy( &LoadedUcodeMap, &ucodeMap1, sizeof(UcodeMap)); |
476 | LoadedUcodeMap[0]=DLParser_Ucode8_0x0; |
477 | //LoadedUcodeMap[1]=RSP_RDP_Nothing; |
478 | LoadedUcodeMap[2]=DLParser_RS_Color_Buffer; |
479 | LoadedUcodeMap[3]=DLParser_RS_MoveMem; |
480 | LoadedUcodeMap[4]=DLParser_RS_Vtx_Buffer; |
481 | LoadedUcodeMap[5]=DLParser_Ucode8_0x05; |
482 | LoadedUcodeMap[6]=DLParser_Ucode8_DL; |
483 | LoadedUcodeMap[7]=DLParser_Ucode8_JUMP; |
484 | LoadedUcodeMap[8]=RSP_RDP_Nothing; |
485 | LoadedUcodeMap[9]=RSP_RDP_Nothing; |
486 | LoadedUcodeMap[10]=RSP_RDP_Nothing; |
487 | LoadedUcodeMap[11]=RSP_RDP_Nothing; |
488 | LoadedUcodeMap[0x80]=DLParser_RS_Block; |
489 | LoadedUcodeMap[0xb4]=DLParser_Ucode8_0xb4; |
490 | LoadedUcodeMap[0xb5]=DLParser_Ucode8_0xb5; |
491 | LoadedUcodeMap[0xb8]=DLParser_Ucode8_EndDL; |
492 | LoadedUcodeMap[0xbc]=DLParser_Ucode8_0xbc; |
493 | LoadedUcodeMap[0xbd]=DLParser_Ucode8_0xbd; |
494 | LoadedUcodeMap[0xbe]=DLParser_RS_0xbe; |
495 | LoadedUcodeMap[0xbF]=DLParser_Ucode8_0xbf; |
496 | LoadedUcodeMap[0xe4]=DLParser_TexRect_Last_Legion; |
497 | status.bUseModifiedUcodeMap = true; |
498 | break; |
499 | case 18: // World Driver Championship |
500 | memcpy( &LoadedUcodeMap, &ucodeMap1, sizeof(UcodeMap)); |
501 | LoadedUcodeMap[0xe]=DLParser_RSP_DL_WorldDriver; |
502 | LoadedUcodeMap[0x2]=DLParser_RSP_Pop_DL_WorldDriver; |
503 | LoadedUcodeMap[0xdf]=DLParser_RSP_Pop_DL_WorldDriver; |
504 | LoadedUcodeMap[0x6]=RSP_RDP_Nothing; |
505 | status.bUseModifiedUcodeMap = true; |
506 | break; |
507 | case 19: // Last Legion UX |
508 | memcpy( &LoadedUcodeMap, &ucodeMap1, sizeof(UcodeMap)); |
509 | LoadedUcodeMap[0x80]=DLParser_RSP_Last_Legion_0x80; |
510 | LoadedUcodeMap[0x00]=DLParser_RSP_Last_Legion_0x00; |
511 | LoadedUcodeMap[0xe4]=DLParser_TexRect_Last_Legion; |
512 | status.bUseModifiedUcodeMap = true; |
513 | break; |
514 | default: |
515 | memcpy( &LoadedUcodeMap, &ucodeMap5, sizeof(UcodeMap)); |
516 | status.bUseModifiedUcodeMap = true; |
517 | break; |
518 | } |
519 | |
520 | #ifdef DEBUGGER |
521 | if( logMicrocode ) |
522 | TRACE1("Using ucode %d", ucode); |
523 | #endif |
524 | } |
525 | |
526 | void RSP_SetUcode(int ucode, uint32 ucStart, uint32 ucDStart, uint32 ucSize) |
527 | { |
528 | if( status.ucodeHasBeenSet && gRSP.ucode == ucode ) |
529 | return; |
530 | |
531 | status.ucodeHasBeenSet = true; |
532 | |
533 | if( ucode < 0 ) |
534 | ucode = 5; |
535 | |
536 | RDP_SetUcodeMap(ucode); |
537 | if( status.bUseModifiedUcodeMap ) |
538 | { |
539 | currentUcodeMap = &LoadedUcodeMap[0]; |
540 | } |
541 | else |
542 | { |
543 | currentUcodeMap = *ucodeMaps[ucode]; |
544 | } |
545 | |
546 | gRSP.vertexMult = vertexMultVals[ucode]; |
547 | |
548 | //if( gRSP.ucode != ucode ) DebuggerAppendMsg("Set to ucode: %d", ucode); |
549 | gRSP.ucode = ucode; |
550 | |
551 | lastUcodeInfo.used = true; |
552 | if( ucStart == 0 ) |
553 | { |
554 | lastUcodeInfo.ucStart = g_pOSTask->t.ucode; |
555 | lastUcodeInfo.ucDStart = g_pOSTask->t.ucode_data; |
556 | lastUcodeInfo.ucSize = g_pOSTask->t.ucode_size; |
557 | } |
558 | else |
559 | { |
560 | lastUcodeInfo.ucStart = ucStart; |
561 | lastUcodeInfo.ucDStart = ucDStart; |
562 | lastUcodeInfo.ucSize = ucSize; |
563 | } |
564 | } |
565 | |
566 | //***************************************************************************** |
567 | // |
568 | //***************************************************************************** |
569 | static uint32 DLParser_IdentifyUcodeFromString( const unsigned char * str_ucode ) |
570 | { |
571 | const unsigned char str_ucode0[] = "RSP SW Version: 2.0"; |
572 | const unsigned char str_ucode1[] = "RSP Gfx ucode "; |
573 | |
574 | if ( strncasecmp( (char*)str_ucode, (char*)str_ucode0, strlen((char*)str_ucode0) ) == 0 ) |
575 | { |
576 | return 0; |
577 | } |
578 | |
579 | if ( strncasecmp( (char*)str_ucode, (char*)str_ucode1, strlen((char*)str_ucode1) ) == 0 ) |
580 | { |
581 | if( strstr((char*)str_ucode,"1.") != 0 ) |
582 | { |
583 | if( strstr((char*)str_ucode,"S2DEX") != 0 ) |
584 | { |
585 | return 7; |
586 | } |
587 | else |
588 | return 1; |
589 | } |
590 | else if( strstr((char*)str_ucode,"2.") != 0 ) |
591 | { |
592 | if( strstr((char*)str_ucode,"S2DEX") != 0 ) |
593 | { |
594 | return 3; |
595 | } |
596 | else |
597 | return 5; |
598 | } |
599 | } |
600 | |
601 | return 5; |
602 | } |
603 | |
604 | //***************************************************************************** |
605 | // |
606 | //***************************************************************************** |
607 | static uint32 DLParser_IdentifyUcode( uint32 crc_size, uint32 crc_800, char* str ) |
608 | { |
609 | for ( uint32 i = 0; i < sizeof(g_UcodeData)/sizeof(UcodeData); i++ ) |
610 | { |
611 | #ifdef DEBUGGER |
612 | if ( crc_800 == g_UcodeData[i].crc_800 ) |
613 | { |
614 | if( strlen(str)==0 || strcmp((const char *) g_UcodeData[i].ucode_name, str) == 0 ) |
615 | { |
616 | TRACE0((const char *) g_UcodeData[i].ucode_name); |
617 | } |
618 | else |
619 | { |
620 | DebuggerAppendMsg("Incorrect description for this ucode:\n%x, %x, %s",crc_800, crc_size, str); |
621 | } |
622 | status.bUcodeIsKnown = TRUE; |
623 | gRSP.bNearClip = !g_UcodeData[i].non_nearclip; |
624 | gRSP.bRejectVtx = g_UcodeData[i].reject; |
625 | DebuggerAppendMsg("Identify ucode = %d, crc = %08X, %s", g_UcodeData[i].ucode, crc_800, str); |
626 | return g_UcodeData[i].ucode; |
627 | } |
628 | #else |
629 | if ( crc_800 == g_UcodeData[i].crc_800 ) |
630 | { |
631 | status.bUcodeIsKnown = TRUE; |
632 | gRSP.bNearClip = !g_UcodeData[i].non_nearclip; |
633 | gRSP.bRejectVtx = g_UcodeData[i].reject; |
634 | return g_UcodeData[i].ucode; |
635 | } |
636 | #endif |
637 | } |
638 | |
639 | #ifdef DEBUGGER |
640 | { |
641 | static bool warned = false; |
642 | if( warned == false ) |
643 | { |
644 | warned = true; |
645 | TRACE0("Can not identify ucode for this game"); |
646 | } |
647 | } |
648 | #endif |
649 | gRSP.bNearClip = false; |
650 | gRSP.bRejectVtx = false; |
651 | status.bUcodeIsKnown = FALSE; |
652 | return ~0; |
653 | } |
654 | |
655 | uint32 DLParser_CheckUcode(uint32 ucStart, uint32 ucDStart, uint32 ucSize, uint32 ucDSize) |
656 | { |
657 | if( options.enableHackForGames == HACK_FOR_ROGUE_SQUADRON ) |
658 | { |
659 | return 17; |
660 | } |
661 | |
662 | // Check the used ucode table first |
663 | int usedUcodeIndex = 0; |
664 | for( usedUcodeIndex=0; (unsigned int)usedUcodeIndex<maxUsedUcodes; usedUcodeIndex++ ) |
665 | { |
666 | if( UsedUcodes[usedUcodeIndex].used == false ) |
667 | { |
668 | break; |
669 | } |
670 | |
671 | if( UsedUcodes[usedUcodeIndex].ucStart == ucStart && UsedUcodes[usedUcodeIndex].ucSize == ucSize && |
672 | UsedUcodes[usedUcodeIndex].ucDStart == ucDStart /*&& UsedUcodes[usedUcodeIndex].ucDSize == ucDSize*/ ) |
673 | { |
674 | #ifdef DEBUGGER |
675 | if(gRSP.ucode != (int)UsedUcodes[usedUcodeIndex].ucode && logMicrocode) |
676 | { |
677 | DebuggerAppendMsg("Check, ucode = %d, crc = %08X, %s", UsedUcodes[usedUcodeIndex].ucode, |
678 | UsedUcodes[usedUcodeIndex].crc_800 , UsedUcodes[usedUcodeIndex].rspstr); |
679 | } |
680 | #endif |
681 | lastUcodeInfo.ucStart = ucStart; |
682 | lastUcodeInfo.used = true; |
683 | lastUcodeInfo.ucDStart = ucDStart; |
684 | lastUcodeInfo.ucSize = ucSize; |
685 | return UsedUcodes[usedUcodeIndex].ucode; |
686 | } |
687 | } |
688 | |
689 | uint32 base = ucDStart & 0x1fffffff; |
690 | unsigned char str[300] = ""; |
691 | if( base < g_dwRamSize+0x1000 ) |
692 | { |
693 | for ( uint32 i = 0; i < 0x1000; i++ ) |
694 | { |
695 | if ( g_pRDRAMs8[ base + ((i+0) ^ 3) ] == 'R' && |
696 | g_pRDRAMs8[ base + ((i+1) ^ 3) ] == 'S' && |
697 | g_pRDRAMs8[ base + ((i+2) ^ 3) ] == 'P' ) |
698 | { |
699 | unsigned char * p = str; |
700 | while ( g_pRDRAMs8[ base + (i ^ 3) ] >= ' ') |
701 | { |
702 | *p++ = g_pRDRAMs8[ base + (i ^ 3) ]; |
703 | i++; |
704 | } |
705 | *p++ = 0; |
706 | break; |
707 | } |
708 | } |
709 | } |
710 | |
711 | //if ( strcmp( str, gLastMicrocodeString ) != 0 ) |
712 | { |
713 | //uint32 size = ucDSize; |
714 | base = ucStart & 0x1fffffff; |
715 | |
716 | uint32 crc_size = ComputeCRC32( 0, &g_pRDRAMu8[ base ], 8);//size ); |
717 | uint32 crc_800 = ComputeCRC32( 0, &g_pRDRAMu8[ base ], 0x800 ); |
718 | uint32 ucode; |
719 | ucode = DLParser_IdentifyUcode( crc_size, crc_800, (char*)str ); |
720 | if ( (int)ucode == ~0 ) |
721 | { |
722 | #ifdef DEBUGGER |
723 | static bool warned=false; |
724 | //if( warned == false ) |
725 | { |
726 | char message[300]; |
727 | |
728 | sprintf(message, "Unable to find ucode to use for '%s' CRCSize: 0x%08x CRC800: 0x%08x", |
729 | str, crc_size, crc_800); |
730 | TRACE0(message); |
731 | DebugMessage(M64MSG_ERROR, message); |
732 | warned = true; |
733 | } |
734 | #endif |
735 | ucode = DLParser_IdentifyUcodeFromString(str); |
736 | if ( (int)ucode == ~0 ) |
737 | { |
738 | ucode=5; |
739 | } |
740 | } |
741 | |
742 | //DLParser_SetuCode( ucode ); |
743 | |
744 | #ifdef DEBUGGER |
745 | { |
746 | static bool warned=false; |
747 | if( warned == false ) |
748 | { |
749 | warned = true; |
750 | if( strlen((char *) str) == 0 ) |
751 | DebuggerAppendMsg("Can not find RSP string in the DLIST, CRC800: 0x%08x, CRCSize: 0x%08x", crc_800, crc_size); |
752 | else |
753 | TRACE0((char *) str); |
754 | } |
755 | } |
756 | #endif |
757 | strcpy( (char*)gLastMicrocodeString, (char*)str ); |
758 | |
759 | if( usedUcodeIndex >= MAX_UCODE_INFO ) |
760 | { |
761 | usedUcodeIndex = rand()%MAX_UCODE_INFO; |
762 | } |
763 | |
764 | UsedUcodes[usedUcodeIndex].ucStart = ucStart; |
765 | UsedUcodes[usedUcodeIndex].ucSize = ucSize; |
766 | UsedUcodes[usedUcodeIndex].ucDStart = ucDStart; |
767 | UsedUcodes[usedUcodeIndex].ucDSize = ucDSize; |
768 | UsedUcodes[usedUcodeIndex].ucode = ucode; |
769 | UsedUcodes[usedUcodeIndex].crc_800 = crc_800; |
770 | UsedUcodes[usedUcodeIndex].crc_size = crc_size; |
771 | UsedUcodes[usedUcodeIndex].used = true; |
772 | strcpy( UsedUcodes[usedUcodeIndex].rspstr, (char*)str ); |
773 | |
774 | TRACE2("New ucode has been detected:\n%s, ucode=%d", str, ucode); |
775 | |
776 | return ucode; |
777 | } |
778 | } |
779 | |
780 | extern int dlistMtxCount; |
781 | extern bool bHalfTxtScale; |
782 | |
ca22e7b7 |
783 | extern float mspervi; |
784 | extern float numvi; |
785 | static int skipframe=0; |
786 | static unsigned int oldtick=0; |
787 | static int oldskip=0; |
788 | extern bool skipping; |
789 | |
292f9317 |
790 | void DLParser_Process(OSTask * pTask) |
791 | { |
792 | static int skipframe=0; |
793 | //BOOL menuWaiting = FALSE; |
794 | |
795 | dlistMtxCount = 0; |
796 | bHalfTxtScale = false; |
797 | |
798 | if ( CRender::g_pRender == NULL) |
799 | { |
800 | TriggerDPInterrupt(); |
801 | TriggerSPInterrupt(); |
802 | return; |
803 | } |
804 | |
805 | status.bScreenIsDrawn = true; |
ca22e7b7 |
806 | /* if( options.bSkipFrame ) |
292f9317 |
807 | { |
808 | skipframe++; |
809 | if(skipframe%2) |
810 | { |
811 | TriggerDPInterrupt(); |
812 | TriggerSPInterrupt(); |
813 | return; |
814 | } |
815 | } |
ca22e7b7 |
816 | */ |
292f9317 |
817 | if( currentRomOptions.N64RenderToTextureEmuType != TXT_BUF_NONE && defaultRomOptions.bSaveVRAM ) |
818 | { |
819 | g_pFrameBufferManager->CheckRenderTextureCRCInRDRAM(); |
820 | } |
821 | |
ca22e7b7 |
822 | unsigned int newtick=0; |
823 | static int count = 0; |
824 | if( options.bSkipFrame ) |
825 | { |
826 | skipping=false; |
827 | newtick = SDL_GetTicks(); |
828 | if (newtick-oldtick>400 || skipframe>4 || numvi==0) { |
829 | oldtick=newtick; // too long frame delay, something must have gone wrong |
830 | skipping=false; |
831 | } else |
832 | if ((float)(newtick-oldtick)>=mspervi*numvi+3.0f) { |
833 | skipping=true; |
834 | } |
835 | // don't jump frameskipping... |
836 | if (skipping) { |
837 | //want to skip, be progress slowly... |
838 | if (skipframe>oldskip+1) |
839 | skipping = false; |
840 | } |
841 | if (skipping) { |
842 | skipframe++; |
843 | status.bScreenIsDrawn = false; |
844 | TriggerDPInterrupt(); |
845 | TriggerSPInterrupt(); |
846 | return; |
847 | } |
848 | oldskip = skipframe; |
849 | skipframe=0; |
850 | oldtick=newtick; |
851 | numvi=0; |
852 | } |
853 | |
292f9317 |
854 | g_pOSTask = pTask; |
855 | |
856 | DebuggerPauseCountN( NEXT_DLIST ); |
857 | status.gRDPTime = (uint32) SDL_GetTicks(); |
858 | |
859 | status.gDlistCount++; |
860 | |
861 | if ( lastUcodeInfo.ucStart != (uint32)(pTask->t.ucode) ) |
862 | { |
863 | uint32 ucode = DLParser_CheckUcode(pTask->t.ucode, pTask->t.ucode_data, pTask->t.ucode_size, pTask->t.ucode_data_size); |
864 | RSP_SetUcode(ucode, pTask->t.ucode, pTask->t.ucode_data, pTask->t.ucode_size); |
865 | DEBUGGER_PAUSE_AND_DUMP(NEXT_SWITCH_UCODE,{DebuggerAppendMsg("Pause at switching ucode");}); |
866 | } |
867 | |
868 | // Initialize stack |
869 | status.bN64FrameBufferIsUsed = false; |
870 | gDlistStackPointer=0; |
871 | gDlistStack[gDlistStackPointer].pc = (uint32)pTask->t.data_ptr; |
872 | gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT; |
873 | DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N((gDlistStack[gDlistStackPointer].pc == 0 && pauseAtNext && eventToPause==NEXT_UNKNOWN_OP), |
874 | {DebuggerAppendMsg("Start Task without DLIST: ucode=%08X, data=%08X", (uint32)pTask->t.ucode, (uint32)pTask->t.ucode_data);}); |
875 | |
876 | |
877 | // Check if we need to purge (every 5 milliseconds) |
878 | if (status.gRDPTime - status.lastPurgeTimeTime > 5) |
879 | { |
880 | gTextureManager.PurgeOldTextures(); |
881 | status.lastPurgeTimeTime = status.gRDPTime; |
882 | } |
883 | |
884 | status.dwNumDListsCulled = 0; |
885 | status.dwNumTrisRendered = 0; |
886 | status.dwNumTrisClipped = 0; |
887 | status.dwNumVertices = 0; |
888 | status.dwBiggestVertexIndex = 0; |
889 | |
890 | if( g_curRomInfo.bForceScreenClear && CGraphicsContext::needCleanScene ) |
891 | { |
892 | CRender::g_pRender->ClearBuffer(true,true); |
893 | CGraphicsContext::needCleanScene = false; |
894 | } |
895 | |
896 | SetVIScales(); |
897 | CRender::g_pRender->RenderReset(); |
898 | CRender::g_pRender->BeginRendering(); |
899 | CRender::g_pRender->SetViewport(0, 0, windowSetting.uViWidth, windowSetting.uViHeight, 0x3FF); |
900 | CRender::g_pRender->SetFillMode(options.bWinFrameMode? RICE_FILLMODE_WINFRAME : RICE_FILLMODE_SOLID); |
901 | |
902 | try |
903 | { |
904 | // The main loop |
905 | while( gDlistStackPointer >= 0 ) |
906 | { |
907 | #ifdef DEBUGGER |
908 | DEBUGGER_PAUSE_COUNT_N(NEXT_UCODE); |
909 | if( debuggerPause ) |
910 | { |
911 | DebuggerPause(); |
912 | CRender::g_pRender->SetFillMode(options.bWinFrameMode? RICE_FILLMODE_WINFRAME : RICE_FILLMODE_SOLID); |
913 | } |
914 | |
915 | if (gDlistStack[gDlistStackPointer].pc > g_dwRamSize) |
916 | { |
917 | DebuggerAppendMsg("Error: dwPC is %08X", gDlistStack[gDlistStackPointer].pc ); |
918 | break; |
919 | } |
920 | #endif |
921 | |
922 | status.gUcodeCount++; |
923 | |
924 | Gfx *pgfx = (Gfx*)&g_pRDRAMu32[(gDlistStack[gDlistStackPointer].pc>>2)]; |
925 | #ifdef DEBUGGER |
926 | LOG_UCODE("0x%08x: %08x %08x %-10s", |
927 | gDlistStack[gDlistStackPointer].pc, pgfx->words.w0, pgfx->words.w1, (gRSP.ucode!=5&&gRSP.ucode!=10)?ucodeNames_GBI1[(pgfx->words.w0>>24)]:ucodeNames_GBI2[(pgfx->words.w0>>24)]); |
928 | #endif |
929 | gDlistStack[gDlistStackPointer].pc += 8; |
930 | currentUcodeMap[pgfx->words.w0 >>24](pgfx); |
931 | |
932 | if ( gDlistStackPointer >= 0 && --gDlistStack[gDlistStackPointer].countdown < 0 ) |
933 | { |
934 | LOG_UCODE("**EndDLInMem"); |
935 | gDlistStackPointer--; |
936 | } |
937 | } |
938 | |
939 | } |
940 | catch(...) |
941 | { |
942 | TRACE0("Unknown exception happens in ProcessDList"); |
943 | TriggerDPInterrupt(); |
944 | } |
945 | |
946 | CRender::g_pRender->EndRendering(); |
947 | |
948 | if( gRSP.ucode >= 17) |
949 | TriggerDPInterrupt(); |
950 | TriggerSPInterrupt(); |
951 | } |
952 | |
953 | ////////////////////////////////////////////////////////// |
954 | ////////////////////////////////////////////////////////// |
955 | // Util Functions // |
956 | ////////////////////////////////////////////////////////// |
957 | ////////////////////////////////////////////////////////// |
958 | |
959 | void RDP_NOIMPL_Real(const char* op, uint32 word0, uint32 word1) |
960 | { |
961 | #ifdef DEBUGGER |
962 | if( logWarning ) |
963 | { |
964 | TRACE0("Stack Trace"); |
965 | for( int i=0; i<gDlistStackPointer; i++ ) |
966 | { |
967 | DebuggerAppendMsg(" %08X", gDlistStack[i].pc); |
968 | } |
969 | uint32 dwPC = gDlistStack[gDlistStackPointer].pc-8; |
970 | DebuggerAppendMsg("PC=%08X",dwPC); |
971 | DebuggerAppendMsg(op, word0, word1); |
972 | } |
973 | DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_UNKNOWN_OP, {TRACE0("Paused at unimplemented ucode\n");}) |
974 | #endif |
975 | } |
976 | |
977 | void RDP_NOIMPL_WARN(const char* op) |
978 | { |
979 | #ifdef DEBUGGER |
980 | if(logWarning) |
981 | { |
982 | TRACE0(op); |
983 | } |
984 | #endif |
985 | } |
986 | |
987 | |
988 | void RSP_GBI1_Noop(Gfx *gfx) |
989 | { |
990 | } |
991 | |
992 | |
993 | void RDP_GFX_PopDL() |
994 | { |
995 | LOG_UCODE("Returning from DisplayList: level=%d", gDlistStackPointer+1); |
996 | LOG_UCODE("############################################"); |
997 | LOG_UCODE("/\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\"); |
998 | LOG_UCODE(""); |
999 | |
1000 | gDlistStackPointer--; |
1001 | } |
1002 | |
1003 | uint32 CalcalateCRC(uint32* srcPtr, uint32 srcSize) |
1004 | { |
1005 | uint32 crc=0; |
1006 | for( uint32 i=0; i<srcSize; i++ ) |
1007 | { |
1008 | crc += srcPtr[i]; |
1009 | } |
1010 | return crc; |
1011 | } |
1012 | |
1013 | |
1014 | void RSP_GFX_InitGeometryMode() |
1015 | { |
1016 | bool bCullFront = (gRDP.geometryMode & G_CULL_FRONT) ? true : false; |
1017 | bool bCullBack = (gRDP.geometryMode & G_CULL_BACK) ? true : false; |
1018 | if( bCullFront && bCullBack ) // should never cull front |
1019 | { |
1020 | bCullFront = false; |
1021 | } |
1022 | CRender::g_pRender->SetCullMode(bCullFront, bCullBack); |
1023 | |
1024 | BOOL bShade = (gRDP.geometryMode & G_SHADE) ? TRUE : FALSE; |
1025 | BOOL bShadeSmooth = (gRDP.geometryMode & G_SHADING_SMOOTH) ? TRUE : FALSE; |
1026 | if (bShade && bShadeSmooth) CRender::g_pRender->SetShadeMode( SHADE_SMOOTH ); |
1027 | else CRender::g_pRender->SetShadeMode( SHADE_FLAT ); |
1028 | |
1029 | CRender::g_pRender->SetFogEnable( gRDP.geometryMode & G_FOG ? true : false ); |
1030 | SetTextureGen((gRDP.geometryMode & G_TEXTURE_GEN) ? true : false ); |
1031 | SetLighting( (gRDP.geometryMode & G_LIGHTING ) ? true : false ); |
1032 | CRender::g_pRender->ZBufferEnable( gRDP.geometryMode & G_ZBUFFER ); |
1033 | } |
1034 | |
1035 | ////////////////////////////////////////////////////////// |
1036 | ////////////////////////////////////////////////////////// |
1037 | // DP Ucodes // |
1038 | ////////////////////////////////////////////////////////// |
1039 | ////////////////////////////////////////////////////////// |
1040 | |
1041 | void DLParser_SetKeyGB(Gfx *gfx) |
1042 | { |
1043 | DP_Timing(DLParser_SetKeyGB); |
1044 | |
1045 | gRDP.keyB = ((gfx->words.w1)>>8)&0xFF; |
1046 | gRDP.keyG = ((gfx->words.w1)>>24)&0xFF; |
1047 | gRDP.keyA = (gRDP.keyR+gRDP.keyG+gRDP.keyB)/3; |
1048 | gRDP.fKeyA = gRDP.keyA/255.0f; |
1049 | } |
1050 | void DLParser_SetKeyR(Gfx *gfx) |
1051 | { |
1052 | DP_Timing(DLParser_SetKeyR); |
1053 | |
1054 | gRDP.keyR = ((gfx->words.w1)>>8)&0xFF; |
1055 | gRDP.keyA = (gRDP.keyR+gRDP.keyG+gRDP.keyB)/3; |
1056 | gRDP.fKeyA = gRDP.keyA/255.0f; |
1057 | } |
1058 | |
1059 | int g_convk0,g_convk1,g_convk2,g_convk3,g_convk4,g_convk5; |
1060 | float g_convc0,g_convc1,g_convc2,g_convc3,g_convc4,g_convc5; |
1061 | void DLParser_SetConvert(Gfx *gfx) |
1062 | { |
1063 | DP_Timing(DLParser_SetConvert); |
1064 | |
1065 | int temp; |
1066 | |
1067 | temp = ((gfx->words.w0)>>13)&0x1FF; |
1068 | g_convk0 = temp>0xFF ? -(temp-0x100) : temp; |
1069 | |
1070 | temp = ((gfx->words.w0)>>4)&0x1FF; |
1071 | g_convk1 = temp>0xFF ? -(temp-0x100) : temp; |
1072 | |
1073 | temp = (gfx->words.w0)&0xF; |
1074 | temp = (temp<<5)|(((gfx->words.w1)>>27)&0x1F); |
1075 | g_convk2 = temp>0xFF ? -(temp-0x100) : temp; |
1076 | |
1077 | temp = ((gfx->words.w1)>>18)&0x1FF; |
1078 | g_convk3 = temp>0xFF ? -(temp-0x100) : temp; |
1079 | |
1080 | temp = ((gfx->words.w1)>>9)&0x1FF; |
1081 | g_convk4 = temp>0xFF ? -(temp-0x100) : temp; |
1082 | |
1083 | temp = (gfx->words.w1)&0x1FF; |
1084 | g_convk5 = temp>0xFF ? -(temp-0x100) : temp; |
1085 | |
1086 | g_convc0 = g_convk5/255.0f+1.0f; |
1087 | g_convc1 = g_convk0/255.0f*g_convc0; |
1088 | g_convc2 = g_convk1/255.0f*g_convc0; |
1089 | g_convc3 = g_convk2/255.0f*g_convc0; |
1090 | g_convc4 = g_convk3/255.0f*g_convc0; |
1091 | } |
1092 | void DLParser_SetPrimDepth(Gfx *gfx) |
1093 | { |
1094 | DP_Timing(DLParser_SetPrimDepth); |
1095 | uint32 dwZ = ((gfx->words.w1) >> 16) & 0xFFFF; |
1096 | uint32 dwDZ = ((gfx->words.w1) ) & 0xFFFF; |
1097 | |
1098 | LOG_UCODE("SetPrimDepth: 0x%08x 0x%08x - z: 0x%04x dz: 0x%04x", |
1099 | gfx->words.w0, gfx->words.w1, dwZ, dwDZ); |
1100 | |
1101 | SetPrimitiveDepth(dwZ, dwDZ); |
1102 | DEBUGGER_PAUSE(NEXT_SET_PRIM_COLOR); |
1103 | } |
1104 | |
1105 | void DLParser_RDPSetOtherMode(Gfx *gfx) |
1106 | { |
1107 | DP_Timing(DLParser_RDPSetOtherMode); |
1108 | gRDP.otherMode._u32[1] = (gfx->words.w0); // High |
1109 | gRDP.otherMode._u32[0] = (gfx->words.w1); // Low |
1110 | |
1111 | if( gRDP.otherModeH != ((gfx->words.w0) & 0x0FFFFFFF) ) |
1112 | { |
1113 | gRDP.otherModeH = ((gfx->words.w0) & 0x0FFFFFFF); |
1114 | |
1115 | uint32 dwTextFilt = (gRDP.otherModeH>>RSP_SETOTHERMODE_SHIFT_TEXTFILT)&0x3; |
1116 | CRender::g_pRender->SetTextureFilter(dwTextFilt<<RSP_SETOTHERMODE_SHIFT_TEXTFILT); |
1117 | } |
1118 | |
1119 | if( gRDP.otherModeL != (gfx->words.w1) ) |
1120 | { |
1121 | if( (gRDP.otherModeL&ZMODE_DEC) != ((gfx->words.w1)&ZMODE_DEC) ) |
1122 | { |
1123 | if( ((gfx->words.w1)&ZMODE_DEC) == ZMODE_DEC ) |
1124 | CRender::g_pRender->SetZBias( 2 ); |
1125 | else |
1126 | CRender::g_pRender->SetZBias( 0 ); |
1127 | } |
1128 | |
1129 | gRDP.otherModeL = (gfx->words.w1); |
1130 | |
1131 | BOOL bZCompare = (gRDP.otherModeL & Z_COMPARE) ? TRUE : FALSE; |
1132 | BOOL bZUpdate = (gRDP.otherModeL & Z_UPDATE) ? TRUE : FALSE; |
1133 | |
1134 | CRender::g_pRender->SetZCompare( bZCompare ); |
1135 | CRender::g_pRender->SetZUpdate( bZUpdate ); |
1136 | |
1137 | uint32 dwAlphaTestMode = (gRDP.otherModeL >> RSP_SETOTHERMODE_SHIFT_ALPHACOMPARE) & 0x3; |
1138 | |
1139 | if ((dwAlphaTestMode) != 0) |
1140 | CRender::g_pRender->SetAlphaTestEnable( TRUE ); |
1141 | else |
1142 | CRender::g_pRender->SetAlphaTestEnable( FALSE ); |
1143 | } |
1144 | |
1145 | uint16 blender = gRDP.otherMode.blender; |
1146 | RDP_BlenderSetting &bl = *(RDP_BlenderSetting*)(&(blender)); |
1147 | if( bl.c1_m1a==3 || bl.c1_m2a == 3 || bl.c2_m1a == 3 || bl.c2_m2a == 3 ) |
1148 | { |
1149 | gRDP.bFogEnableInBlender = true; |
1150 | } |
1151 | else |
1152 | { |
1153 | gRDP.bFogEnableInBlender = false; |
1154 | } |
1155 | } |
1156 | |
1157 | |
1158 | |
1159 | void DLParser_RDPLoadSync(Gfx *gfx) |
1160 | { |
1161 | DP_Timing(DLParser_RDPLoadSync); |
1162 | LOG_UCODE("LoadSync: (Ignored)"); |
1163 | } |
1164 | |
1165 | void DLParser_RDPPipeSync(Gfx *gfx) |
1166 | { |
1167 | DP_Timing(DLParser_RDPPipeSync); |
1168 | LOG_UCODE("PipeSync: (Ignored)"); |
1169 | } |
1170 | void DLParser_RDPTileSync(Gfx *gfx) |
1171 | { |
1172 | DP_Timing(DLParser_RDPTileSync); |
1173 | LOG_UCODE("TileSync: (Ignored)"); |
1174 | } |
1175 | |
1176 | void DLParser_RDPFullSync(Gfx *gfx) |
1177 | { |
1178 | DP_Timing(DLParser_RDPFullSync); |
1179 | TriggerDPInterrupt(); |
1180 | } |
1181 | |
1182 | void DLParser_SetScissor(Gfx *gfx) |
1183 | { |
1184 | DP_Timing(DLParser_SetScissor); |
1185 | |
1186 | ScissorType tempScissor; |
1187 | // The coords are all in 8:2 fixed point |
1188 | tempScissor.x0 = ((gfx->words.w0)>>12)&0xFFF; |
1189 | tempScissor.y0 = ((gfx->words.w0)>>0 )&0xFFF; |
1190 | tempScissor.mode = ((gfx->words.w1)>>24)&0x03; |
1191 | tempScissor.x1 = ((gfx->words.w1)>>12)&0xFFF; |
1192 | tempScissor.y1 = ((gfx->words.w1)>>0 )&0xFFF; |
1193 | |
1194 | tempScissor.left = tempScissor.x0/4; |
1195 | tempScissor.top = tempScissor.y0/4; |
1196 | tempScissor.right = tempScissor.x1/4; |
1197 | tempScissor.bottom = tempScissor.y1/4; |
1198 | |
1199 | if( options.bEnableHacks ) |
1200 | { |
1201 | if( g_CI.dwWidth == 0x200 && tempScissor.right == 0x200 ) |
1202 | { |
1203 | uint32 width = *g_GraphicsInfo.VI_WIDTH_REG & 0xFFF; |
1204 | |
1205 | if( width != 0x200 ) |
1206 | { |
1207 | // Hack for RE2 |
1208 | tempScissor.bottom = tempScissor.right*tempScissor.bottom/width; |
1209 | tempScissor.right = width; |
1210 | } |
1211 | |
1212 | } |
1213 | } |
1214 | |
1215 | if( gRDP.scissor.left != tempScissor.left || gRDP.scissor.top != tempScissor.top || |
1216 | gRDP.scissor.right != tempScissor.right || gRDP.scissor.bottom != tempScissor.bottom || |
1217 | gRSP.real_clip_scissor_left != tempScissor.left || gRSP.real_clip_scissor_top != tempScissor.top || |
1218 | gRSP.real_clip_scissor_right != tempScissor.right || gRSP.real_clip_scissor_bottom != tempScissor.bottom) |
1219 | { |
1220 | memcpy(&(gRDP.scissor), &tempScissor, sizeof(ScissorType) ); |
1221 | if( !status.bHandleN64RenderTexture ) |
1222 | SetVIScales(); |
1223 | |
1224 | if( options.enableHackForGames == HACK_FOR_SUPER_BOWLING && g_CI.dwAddr%0x100 != 0 ) |
1225 | { |
1226 | // right half screen |
1227 | gRDP.scissor.left += 160; |
1228 | gRDP.scissor.right += 160; |
1229 | CRender::g_pRender->SetViewport(160, 0, 320, 240, 0xFFFF); |
1230 | } |
1231 | |
1232 | CRender::g_pRender->UpdateClipRectangle(); |
1233 | CRender::g_pRender->UpdateScissor(); |
1234 | CRender::g_pRender->SetViewportRender(); |
1235 | } |
1236 | |
1237 | LOG_UCODE("SetScissor: x0=%d y0=%d x1=%d y1=%d mode=%d", |
1238 | gRDP.scissor.left, gRDP.scissor.top, |
1239 | gRDP.scissor.right, gRDP.scissor.bottom, |
1240 | gRDP.scissor.mode); |
1241 | |
1242 | ///TXTRBUF_DETAIL_DUMP(DebuggerAppendMsg("SetScissor: x0=%d y0=%d x1=%d y1=%d mode=%d", gRDP.scissor.left, gRDP.scissor.top, |
1243 | //gRDP.scissor.right, gRDP.scissor.bottom, gRDP.scissor.mode);); |
1244 | } |
1245 | |
1246 | |
1247 | void DLParser_FillRect(Gfx *gfx) |
1248 | { |
1249 | DP_Timing(DLParser_FillRect); // fix me |
1250 | status.primitiveType = PRIM_FILLRECT; |
1251 | |
1252 | if( status.bN64IsDrawingTextureBuffer && frameBufferOptions.bIgnore ) |
1253 | { |
1254 | return; |
1255 | } |
1256 | |
1257 | if( options.enableHackForGames == HACK_FOR_MARIO_TENNIS ) |
1258 | { |
1259 | uint32 dwPC = gDlistStack[gDlistStackPointer].pc; // This points to the next instruction |
1260 | uint32 w2 = *(uint32 *)(g_pRDRAMu8 + dwPC); |
1261 | if( (w2>>24) == RDP_FILLRECT ) |
1262 | { |
1263 | // Mario Tennis, a lot of FillRect ucodes, skip all of them |
1264 | while( (w2>>24) == RDP_FILLRECT ) |
1265 | { |
1266 | dwPC += 8; |
1267 | w2 = *(uint32 *)(g_pRDRAMu8 + dwPC); |
1268 | } |
1269 | |
1270 | gDlistStack[gDlistStackPointer].pc = dwPC; |
1271 | return; |
1272 | } |
1273 | } |
1274 | |
1275 | uint32 x0 = (((gfx->words.w1)>>12)&0xFFF)/4; |
1276 | uint32 y0 = (((gfx->words.w1)>>0 )&0xFFF)/4; |
1277 | uint32 x1 = (((gfx->words.w0)>>12)&0xFFF)/4; |
1278 | uint32 y1 = (((gfx->words.w0)>>0 )&0xFFF)/4; |
1279 | |
1280 | // Note, in some modes, the right/bottom lines aren't drawn |
1281 | |
1282 | LOG_UCODE(" (%d,%d) (%d,%d)", x0, y0, x1, y1); |
1283 | |
1284 | if( gRDP.otherMode.cycle_type >= CYCLE_TYPE_COPY ) |
1285 | { |
1286 | x1++; |
1287 | y1++; |
1288 | } |
1289 | |
1290 | //TXTRBUF_DETAIL_DUMP(DebuggerAppendMsg("FillRect: X0=%d, Y0=%d, X1=%d, Y1=%d, Color=0x%08X", x0, y0, x1, y1, gRDP.originalFillColor);); |
1291 | |
1292 | if( status.bHandleN64RenderTexture && options.enableHackForGames == HACK_FOR_BANJO_TOOIE ) |
1293 | { |
1294 | // Skip this |
1295 | return; |
1296 | } |
1297 | |
1298 | if (IsUsedAsDI(g_CI.dwAddr)) |
1299 | { |
1300 | // Clear the Z Buffer |
1301 | if( x0!=0 || y0!=0 || windowSetting.uViWidth-x1>1 || windowSetting.uViHeight-y1>1) |
1302 | { |
1303 | if( options.enableHackForGames == HACK_FOR_GOLDEN_EYE ) |
1304 | { |
1305 | // GoldenEye is using double zbuffer |
1306 | if( g_CI.dwAddr == g_ZI.dwAddr ) |
1307 | { |
1308 | // The zbuffer is the upper screen |
1309 | COORDRECT rect={int(x0*windowSetting.fMultX),int(y0*windowSetting.fMultY),int(x1*windowSetting.fMultX),int(y1*windowSetting.fMultY)}; |
1310 | CRender::g_pRender->ClearBuffer(false,true,rect); //Check me |
1311 | LOG_UCODE(" Clearing ZBuffer"); |
1312 | } |
1313 | else |
1314 | { |
1315 | // The zbuffer is the lower screen |
1316 | int h = (g_CI.dwAddr-g_ZI.dwAddr)/g_CI.dwWidth/2; |
1317 | COORDRECT rect={int(x0*windowSetting.fMultX),int((y0+h)*windowSetting.fMultY),int(x1*windowSetting.fMultX),int((y1+h)*windowSetting.fMultY)}; |
1318 | CRender::g_pRender->ClearBuffer(false,true,rect); //Check me |
1319 | LOG_UCODE(" Clearing ZBuffer"); |
1320 | } |
1321 | } |
1322 | else |
1323 | { |
1324 | COORDRECT rect={int(x0*windowSetting.fMultX),int(y0*windowSetting.fMultY),int(x1*windowSetting.fMultX),int(y1*windowSetting.fMultY)}; |
1325 | CRender::g_pRender->ClearBuffer(false,true,rect); //Check me |
1326 | LOG_UCODE(" Clearing ZBuffer"); |
1327 | } |
1328 | } |
1329 | else |
1330 | { |
1331 | CRender::g_pRender->ClearBuffer(false,true); //Check me |
1332 | LOG_UCODE(" Clearing ZBuffer"); |
1333 | } |
1334 | |
1335 | DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_FLUSH_TRI,{TRACE0("Pause after FillRect: ClearZbuffer\n");}); |
1336 | DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_FILLRECT, {DebuggerAppendMsg("ClearZbuffer: X0=%d, Y0=%d, X1=%d, Y1=%d, Color=0x%08X", x0, y0, x1, y1, gRDP.originalFillColor); |
1337 | DebuggerAppendMsg("Pause after ClearZbuffer: Color=%08X\n", gRDP.originalFillColor);}); |
1338 | |
1339 | if( g_curRomInfo.bEmulateClear ) |
1340 | { |
1341 | // Emulating Clear, by write the memory in RDRAM |
1342 | uint16 color = (uint16)gRDP.originalFillColor; |
1343 | uint32 pitch = g_CI.dwWidth<<1; |
1344 | long long base = (long long) (g_pRDRAMu8 + g_CI.dwAddr); |
1345 | for( uint32 i =y0; i<y1; i++ ) |
1346 | { |
1347 | for( uint32 j=x0; j<x1; j++ ) |
1348 | { |
1349 | *(uint16*)((base+pitch*i+j)^2) = color; |
1350 | } |
1351 | } |
1352 | } |
1353 | } |
1354 | else if( status.bHandleN64RenderTexture ) |
1355 | { |
1356 | if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer(); |
1357 | |
1358 | status.leftRendered = status.leftRendered<0 ? x0 : min((int)x0,status.leftRendered); |
1359 | status.topRendered = status.topRendered<0 ? y0 : min((int)y0,status.topRendered); |
1360 | status.rightRendered = status.rightRendered<0 ? x1 : max((int)x1,status.rightRendered); |
1361 | status.bottomRendered = status.bottomRendered<0 ? y1 : max((int)y1,status.bottomRendered); |
1362 | |
1363 | g_pRenderTextureInfo->maxUsedHeight = max(g_pRenderTextureInfo->maxUsedHeight,(int)y1); |
1364 | |
1365 | if( status.bDirectWriteIntoRDRAM || ( x0==0 && y0==0 && (x1 == g_pRenderTextureInfo->N64Width || x1 == g_pRenderTextureInfo->N64Width-1 ) ) ) |
1366 | { |
1367 | if( g_pRenderTextureInfo->CI_Info.dwSize == TXT_SIZE_16b ) |
1368 | { |
1369 | uint16 color = (uint16)gRDP.originalFillColor; |
1370 | uint32 pitch = g_pRenderTextureInfo->N64Width<<1; |
1371 | long long base = (long long) (g_pRDRAMu8 + g_pRenderTextureInfo->CI_Info.dwAddr); |
1372 | for( uint32 i =y0; i<y1; i++ ) |
1373 | { |
1374 | for( uint32 j=x0; j<x1; j++ ) |
1375 | { |
1376 | *(uint16*)((base+pitch*i+j)^2) = color; |
1377 | } |
1378 | } |
1379 | } |
1380 | else |
1381 | { |
1382 | uint8 color = (uint8)gRDP.originalFillColor; |
1383 | uint32 pitch = g_pRenderTextureInfo->N64Width; |
1384 | long long base = (long long) (g_pRDRAMu8 + g_pRenderTextureInfo->CI_Info.dwAddr); |
1385 | for( uint32 i=y0; i<y1; i++ ) |
1386 | { |
1387 | for( uint32 j=x0; j<x1; j++ ) |
1388 | { |
1389 | *(uint8*)((base+pitch*i+j)^3) = color; |
1390 | } |
1391 | } |
1392 | } |
1393 | |
1394 | status.bFrameBufferDrawnByTriangles = false; |
1395 | } |
1396 | else |
1397 | { |
1398 | status.bFrameBufferDrawnByTriangles = true; |
1399 | } |
1400 | status.bFrameBufferDrawnByTriangles = true; |
1401 | |
1402 | if( !status.bDirectWriteIntoRDRAM ) |
1403 | { |
1404 | status.bFrameBufferIsDrawn = true; |
1405 | |
1406 | //if( x0==0 && y0==0 && (x1 == g_pRenderTextureInfo->N64Width || x1 == g_pRenderTextureInfo->N64Width-1 ) && gRDP.fillColor == 0) |
1407 | //{ |
1408 | // CRender::g_pRender->ClearBuffer(true,false); |
1409 | //} |
1410 | //else |
1411 | { |
1412 | if( gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL ) |
1413 | { |
1414 | CRender::g_pRender->FillRect(x0, y0, x1, y1, gRDP.fillColor); |
1415 | } |
1416 | else |
1417 | { |
1418 | COLOR primColor = GetPrimitiveColor(); |
1419 | CRender::g_pRender->FillRect(x0, y0, x1, y1, primColor); |
1420 | } |
1421 | } |
1422 | } |
1423 | |
1424 | DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_FLUSH_TRI,{TRACE0("Pause after FillRect\n");}); |
1425 | DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_FILLRECT, {DebuggerAppendMsg("FillRect: X0=%d, Y0=%d, X1=%d, Y1=%d, Color=0x%08X", x0, y0, x1, y1, gRDP.originalFillColor); |
1426 | DebuggerAppendMsg("Pause after FillRect: Color=%08X\n", gRDP.originalFillColor);}); |
1427 | } |
1428 | else |
1429 | { |
1430 | LOG_UCODE(" Filling Rectangle"); |
1431 | if( frameBufferOptions.bSupportRenderTextures || frameBufferOptions.bCheckBackBufs ) |
1432 | { |
1433 | if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer(); |
1434 | |
1435 | status.leftRendered = status.leftRendered<0 ? x0 : min((int)x0,status.leftRendered); |
1436 | status.topRendered = status.topRendered<0 ? y0 : min((int)y0,status.topRendered); |
1437 | status.rightRendered = status.rightRendered<0 ? x1 : max((int)x1,status.rightRendered); |
1438 | status.bottomRendered = status.bottomRendered<0 ? y1 : max((int)y1,status.bottomRendered); |
1439 | } |
1440 | |
1441 | if( gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL ) |
1442 | { |
1443 | if( !status.bHandleN64RenderTexture || g_pRenderTextureInfo->CI_Info.dwSize == TXT_SIZE_16b ) |
1444 | { |
1445 | CRender::g_pRender->FillRect(x0, y0, x1, y1, gRDP.fillColor); |
1446 | } |
1447 | } |
1448 | else |
1449 | { |
1450 | COLOR primColor = GetPrimitiveColor(); |
1451 | //if( RGBA_GETALPHA(primColor) != 0 ) |
1452 | { |
1453 | CRender::g_pRender->FillRect(x0, y0, x1, y1, primColor); |
1454 | } |
1455 | } |
1456 | DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_FLUSH_TRI,{TRACE0("Pause after FillRect\n");}); |
1457 | DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_FILLRECT, {DebuggerAppendMsg("FillRect: X0=%d, Y0=%d, X1=%d, Y1=%d, Color=0x%08X", x0, y0, x1, y1, gRDP.originalFillColor); |
1458 | DebuggerAppendMsg("Pause after FillRect: Color=%08X\n", gRDP.originalFillColor);}); |
1459 | } |
1460 | } |
1461 | |
1462 | |
1463 | #define STORE_CI {g_CI.dwAddr = dwNewAddr;g_CI.dwFormat = dwFmt;g_CI.dwSize = dwSiz;g_CI.dwWidth = dwWidth;g_CI.bpl=dwBpl;} |
1464 | |
1465 | void DLParser_SetCImg(Gfx *gfx) |
1466 | { |
1467 | uint32 dwFmt = gfx->setimg.fmt; |
1468 | uint32 dwSiz = gfx->setimg.siz; |
1469 | uint32 dwWidth = gfx->setimg.width + 1; |
1470 | uint32 dwNewAddr = RSPSegmentAddr((gfx->setimg.addr)) & 0x00FFFFFF ; |
1471 | uint32 dwBpl = dwWidth << dwSiz >> 1; |
1472 | |
1473 | TXTRBUF_DETAIL_DUMP(DebuggerAppendMsg("SetCImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", dwNewAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth);); |
1474 | |
1475 | if( dwFmt == TXT_FMT_YUV || dwFmt == TXT_FMT_IA ) |
1476 | { |
1477 | WARNING(TRACE4("Check me: SetCImg Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", |
1478 | g_CI.dwAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth)); |
1479 | } |
1480 | |
1481 | LOG_UCODE(" Image: 0x%08x", RSPSegmentAddr(gfx->words.w1)); |
1482 | LOG_UCODE(" Fmt: %s Size: %s Width: %d", |
1483 | pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth); |
1484 | |
1485 | if( g_CI.dwAddr == dwNewAddr && g_CI.dwFormat == dwFmt && g_CI.dwSize == dwSiz && g_CI.dwWidth == dwWidth ) |
1486 | { |
1487 | TXTRBUF_OR_CI_DETAIL_DUMP({ |
1488 | TRACE0("Set CIMG to the same address, no change, skipped"); |
1489 | DebuggerAppendMsg("Pause after SetCImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", |
1490 | g_CI.dwAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth); |
1491 | }); |
1492 | return; |
1493 | } |
1494 | |
1495 | if( status.bVIOriginIsUpdated == true && currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_AT_1ST_CI_CHANGE ) |
1496 | { |
1497 | status.bVIOriginIsUpdated=false; |
1498 | CGraphicsContext::Get()->UpdateFrame(); |
1499 | TXTRBUF_OR_CI_DETAIL_DUMP(TRACE0("Screen Update at 1st CI change");); |
1500 | } |
1501 | |
1502 | if( options.enableHackForGames == HACK_FOR_SUPER_BOWLING ) |
1503 | { |
1504 | if( dwNewAddr%0x100 == 0 ) |
1505 | { |
1506 | if( dwWidth < 320 ) |
1507 | { |
1508 | // Left half screen |
1509 | gRDP.scissor.left = 0; |
1510 | gRDP.scissor.right = 160; |
1511 | CRender::g_pRender->SetViewport(0, 0, 160, 240, 0xFFFF); |
1512 | CRender::g_pRender->UpdateClipRectangle(); |
1513 | CRender::g_pRender->UpdateScissor(); |
1514 | } |
1515 | else |
1516 | { |
1517 | gRDP.scissor.left = 0; |
1518 | gRDP.scissor.right = 320; |
1519 | CRender::g_pRender->SetViewport(0, 0, 320, 240, 0xFFFF); |
1520 | CRender::g_pRender->UpdateClipRectangle(); |
1521 | CRender::g_pRender->UpdateScissor(); |
1522 | } |
1523 | } |
1524 | else |
1525 | { |
1526 | // right half screen |
1527 | gRDP.scissor.left = 160; |
1528 | gRDP.scissor.right = 320; |
1529 | gRSP.nVPLeftN = 160; |
1530 | gRSP.nVPRightN = 320; |
1531 | CRender::g_pRender->UpdateClipRectangle(); |
1532 | CRender::g_pRender->UpdateScissor(); |
1533 | CRender::g_pRender->SetViewport(160, 0, 320, 240, 0xFFFF); |
1534 | } |
1535 | } |
1536 | |
1537 | |
1538 | if( !frameBufferOptions.bUpdateCIInfo ) |
1539 | { |
1540 | STORE_CI; |
1541 | status.bCIBufferIsRendered = false; |
1542 | status.bN64IsDrawingTextureBuffer = false; |
1543 | |
1544 | TXTRBUF_DUMP(TRACE4("SetCImg : Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", |
1545 | g_CI.dwAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth)); |
1546 | |
1547 | DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_SET_CIMG, |
1548 | { |
1549 | DebuggerAppendMsg("Pause after SetCImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", |
1550 | dwNewAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth); |
1551 | } |
1552 | ); |
1553 | return; |
1554 | } |
1555 | |
1556 | SetImgInfo newCI; |
1557 | newCI.bpl = dwBpl; |
1558 | newCI.dwAddr = dwNewAddr; |
1559 | newCI.dwFormat = dwFmt; |
1560 | newCI.dwSize = dwSiz; |
1561 | newCI.dwWidth = dwWidth; |
1562 | |
1563 | g_pFrameBufferManager->Set_CI_addr(newCI); |
1564 | } |
1565 | |
1566 | void DLParser_SetZImg(Gfx *gfx) |
1567 | { |
1568 | DP_Timing(DLParser_SetZImg); |
1569 | LOG_UCODE(" Image: 0x%08x", RSPSegmentAddr(gfx->words.w1)); |
1570 | |
1571 | uint32 dwFmt = gfx->setimg.fmt; |
1572 | uint32 dwSiz = gfx->setimg.siz; |
1573 | uint32 dwWidth = gfx->setimg.width + 1; |
1574 | uint32 dwAddr = RSPSegmentAddr((gfx->setimg.addr)); |
1575 | |
1576 | if( dwAddr != g_ZI_saves[0].CI_Info.dwAddr ) |
1577 | { |
1578 | g_ZI_saves[1].CI_Info.dwAddr = g_ZI.dwAddr; |
1579 | g_ZI_saves[1].CI_Info.dwFormat = g_ZI.dwFormat; |
1580 | g_ZI_saves[1].CI_Info.dwSize = g_ZI.dwSize; |
1581 | g_ZI_saves[1].CI_Info.dwWidth = g_ZI.dwWidth; |
1582 | g_ZI_saves[1].updateAtFrame = g_ZI_saves[0].updateAtFrame; |
1583 | |
1584 | g_ZI_saves[0].CI_Info.dwAddr = g_ZI.dwAddr = dwAddr; |
1585 | g_ZI_saves[0].CI_Info.dwFormat = g_ZI.dwFormat = dwFmt; |
1586 | g_ZI_saves[0].CI_Info.dwSize = g_ZI.dwSize = dwSiz; |
1587 | g_ZI_saves[0].CI_Info.dwWidth = g_ZI.dwWidth = dwWidth; |
1588 | g_ZI_saves[0].updateAtFrame = status.gDlistCount; |
1589 | } |
1590 | else |
1591 | { |
1592 | g_ZI.dwAddr = dwAddr; |
1593 | g_ZI.dwFormat = dwFmt; |
1594 | g_ZI.dwSize = dwSiz; |
1595 | g_ZI.dwWidth = dwWidth; |
1596 | } |
1597 | |
1598 | DEBUGGER_IF_DUMP((pauseAtNext) , |
1599 | {DebuggerAppendMsg("SetZImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", |
1600 | g_ZI.dwAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth);} |
1601 | ); |
1602 | |
1603 | DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_SET_CIMG, |
1604 | { |
1605 | DebuggerAppendMsg("Pause after SetZImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", |
1606 | g_ZI.dwAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth); |
1607 | } |
1608 | ); |
1609 | } |
1610 | |
1611 | bool IsUsedAsDI(uint32 addr) |
1612 | { |
1613 | if( addr == g_ZI_saves[0].CI_Info.dwAddr ) |
1614 | return true; |
1615 | else if( addr == g_ZI_saves[1].CI_Info.dwAddr && status.gDlistCount - g_ZI_saves[1].updateAtFrame < 10 |
1616 | && g_ZI_saves[1].CI_Info.dwAddr != 0 ) |
1617 | return true; |
1618 | else |
1619 | return false; |
1620 | } |
1621 | |
1622 | void DLParser_SetCombine(Gfx *gfx) |
1623 | { |
1624 | DP_Timing(DLParser_SetCombine); |
1625 | uint32 dwMux0 = (gfx->words.w0)&0x00FFFFFF; |
1626 | uint32 dwMux1 = (gfx->words.w1); |
1627 | CRender::g_pRender->SetMux(dwMux0, dwMux1); |
1628 | } |
1629 | |
1630 | void DLParser_SetFillColor(Gfx *gfx) |
1631 | { |
1632 | DP_Timing(DLParser_SetFillColor); |
1633 | gRDP.fillColor = Convert555ToRGBA(gfx->setcolor.fillcolor); |
1634 | gRDP.originalFillColor = (gfx->setcolor.color); |
1635 | |
1636 | LOG_UCODE(" Color5551=0x%04x = 0x%08x", (uint16)gfx->words.w1, gRDP.fillColor); |
1637 | |
1638 | } |
1639 | |
1640 | void DLParser_SetFogColor(Gfx *gfx) |
1641 | { |
1642 | DP_Timing(DLParser_SetFogColor); |
1643 | CRender::g_pRender->SetFogColor( gfx->setcolor.r, gfx->setcolor.g, gfx->setcolor.b, gfx->setcolor.a ); |
1644 | FOG_DUMP(TRACE1("Set Fog color: %08X", gfx->setcolor.color)); |
1645 | } |
1646 | |
1647 | void DLParser_SetBlendColor(Gfx *gfx) |
1648 | { |
1649 | DP_Timing(DLParser_SetBlendColor); |
1650 | CRender::g_pRender->SetAlphaRef(gfx->setcolor.a); |
1651 | } |
1652 | |
1653 | |
1654 | void DLParser_SetPrimColor(Gfx *gfx) |
1655 | { |
1656 | DP_Timing(DLParser_SetPrimColor); |
1657 | SetPrimitiveColor( COLOR_RGBA(gfx->setcolor.r, gfx->setcolor.g, gfx->setcolor.b, gfx->setcolor.a), |
1658 | gfx->setcolor.prim_min_level, gfx->setcolor.prim_level); |
1659 | } |
1660 | |
1661 | void DLParser_SetEnvColor(Gfx *gfx) |
1662 | { |
1663 | DP_Timing(DLParser_SetEnvColor); |
1664 | SetEnvColor( COLOR_RGBA(gfx->setcolor.r, gfx->setcolor.g, gfx->setcolor.b, gfx->setcolor.a) ); |
1665 | } |
1666 | |
1667 | |
1668 | void RDP_DLParser_Process(void) |
1669 | { |
1670 | status.gRDPTime = (uint32) SDL_GetTicks(); |
1671 | |
1672 | status.gDlistCount++; |
1673 | |
1674 | uint32 start = *(g_GraphicsInfo.DPC_START_REG); |
1675 | uint32 end = *(g_GraphicsInfo.DPC_END_REG); |
1676 | |
1677 | gDlistStackPointer=0; |
1678 | gDlistStack[gDlistStackPointer].pc = start; |
1679 | gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT; |
1680 | |
1681 | // Check if we need to purge (every 5 milliseconds) |
1682 | if (status.gRDPTime - status.lastPurgeTimeTime > 5) |
1683 | { |
1684 | gTextureManager.PurgeOldTextures(); |
1685 | status.lastPurgeTimeTime = status.gRDPTime; |
1686 | } |
1687 | |
1688 | // Lock the graphics context here. |
1689 | CRender::g_pRender->SetFillMode(RICE_FILLMODE_SOLID); |
1690 | |
1691 | SetVIScales(); |
1692 | |
1693 | CRender::g_pRender->RenderReset(); |
1694 | CRender::g_pRender->BeginRendering(); |
1695 | CRender::g_pRender->SetViewport(0, 0, windowSetting.uViWidth, windowSetting.uViHeight, 0x3FF); |
1696 | |
1697 | while( gDlistStack[gDlistStackPointer].pc < end ) |
1698 | { |
1699 | Gfx *pgfx = (Gfx*)&g_pRDRAMu32[(gDlistStack[gDlistStackPointer].pc>>2)]; |
1700 | gDlistStack[gDlistStackPointer].pc += 8; |
1701 | currentUcodeMap[pgfx->words.w0 >>24](pgfx); |
1702 | } |
1703 | |
1704 | CRender::g_pRender->EndRendering(); |
1705 | } |
1706 | |
1707 | void RDP_TriFill(Gfx *gfx) |
1708 | { |
1709 | } |
1710 | |
1711 | void RDP_TriFillZ(Gfx *gfx) |
1712 | { |
1713 | } |
1714 | |
1715 | void RDP_TriTxtr(Gfx *gfx) |
1716 | { |
1717 | } |
1718 | |
1719 | void RDP_TriTxtrZ(Gfx *gfx) |
1720 | { |
1721 | } |
1722 | |
1723 | void RDP_TriShade(Gfx *gfx) |
1724 | { |
1725 | } |
1726 | |
1727 | void RDP_TriShadeZ(Gfx *gfx) |
1728 | { |
1729 | } |
1730 | |
1731 | void RDP_TriShadeTxtr(Gfx *gfx) |
1732 | { |
1733 | } |
1734 | |
1735 | void RDP_TriShadeTxtrZ(Gfx *gfx) |
1736 | { |
1737 | } |
1738 | |
1739 | static int crc_table_empty = 1; |
1740 | static unsigned int crc_table[256]; |
1741 | static void make_crc_table(void); |
1742 | |
1743 | static void make_crc_table() |
1744 | { |
1745 | unsigned int c; |
1746 | int n, k; |
1747 | unsigned int poly; /* polynomial exclusive-or pattern */ |
1748 | /* terms of polynomial defining this crc (except x^32): */ |
1749 | static const uint8 p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; |
1750 | |
1751 | /* make exclusive-or pattern from polynomial (0xedb88320L) */ |
1752 | poly = 0L; |
1753 | for (n = 0; (unsigned int)n < sizeof(p)/sizeof(uint8); n++) |
1754 | poly |= 1L << (31 - p[n]); |
1755 | |
1756 | for (n = 0; n < 256; n++) |
1757 | { |
1758 | c = (unsigned int)n; |
1759 | for (k = 0; k < 8; k++) |
1760 | c = (c & 1) ? (poly ^ (c >> 1)) : c >> 1; |
1761 | crc_table[n] = c; |
1762 | } |
1763 | crc_table_empty = 0; |
1764 | } |
1765 | |
1766 | /* ========================================================================= */ |
1767 | #define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); |
1768 | #define DO2(buf) DO1(buf); DO1(buf); |
1769 | #define DO4(buf) DO2(buf); DO2(buf); |
1770 | #define DO8(buf) DO4(buf); DO4(buf); |
1771 | |
1772 | /* ========================================================================= */ |
1773 | unsigned int ComputeCRC32(unsigned int crc, const uint8 *buf, unsigned int len) |
1774 | { |
1775 | if (buf == NULL) |
1776 | return 0L; |
1777 | |
1778 | if (crc_table_empty) |
1779 | make_crc_table(); |
1780 | |
1781 | crc = crc ^ 0xffffffffL; |
1782 | while (len >= 8) |
1783 | { |
1784 | DO8(buf); |
1785 | len -= 8; |
1786 | } |
1787 | if (len) do { |
1788 | DO1(buf); |
1789 | } while (--len); |
1790 | return crc ^ 0xffffffffL; |
1791 | } |
1792 | |
1793 | Matrix matToLoad; |
1794 | void LoadMatrix(uint32 addr) |
1795 | { |
1796 | const float fRecip = 1.0f / 65536.0f; |
1797 | if (addr + 64 > g_dwRamSize) |
1798 | { |
1799 | TRACE1("Mtx: Address invalid (0x%08x)", addr); |
1800 | return; |
1801 | } |
1802 | |
1803 | for (int i = 0; i < 4; i++) |
1804 | { |
1805 | for (int j = 0; j < 4; j++) |
1806 | { |
1807 | int hi = *(short *)(g_pRDRAMu8 + ((addr+(i<<3)+(j<<1) )^0x2)); |
1808 | int lo = *(unsigned short *)(g_pRDRAMu8 + ((addr+(i<<3)+(j<<1) + 32)^0x2)); |
1809 | matToLoad.m[i][j] = (float)((hi<<16) | lo) * fRecip; |
1810 | } |
1811 | } |
1812 | |
1813 | |
1814 | #ifdef DEBUGGER |
1815 | LOG_UCODE( |
1816 | " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n" |
1817 | " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n" |
1818 | " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n" |
1819 | " %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n", |
1820 | matToLoad.m[0][0], matToLoad.m[0][1], matToLoad.m[0][2], matToLoad.m[0][3], |
1821 | matToLoad.m[1][0], matToLoad.m[1][1], matToLoad.m[1][2], matToLoad.m[1][3], |
1822 | matToLoad.m[2][0], matToLoad.m[2][1], matToLoad.m[2][2], matToLoad.m[2][3], |
1823 | matToLoad.m[3][0], matToLoad.m[3][1], matToLoad.m[3][2], matToLoad.m[3][3]); |
1824 | #endif // DEBUGGER |
1825 | } |
1826 | |