2
Copyright (C) 2003 Rice1964
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.
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.
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.
24
//////////////////////////////////////////////////////////
25
//////////////////////////////////////////////////////////
27
//////////////////////////////////////////////////////////
28
//////////////////////////////////////////////////////////
29
#define MAX_UCODE_INFO 16
30
UcodeInfo ucodeInfo[MAX_UCODE_INFO];
32
RDPInstruction LoadedUcodeMap[256];
33
char* LoadedUcodeNameMap[256];
35
OSTask *g_pOSTask = NULL;
36
UcodeInfo lastUcodeInfo;
37
UcodeInfo UsedUcodes[MAX_UCODE_INFO];
38
const uint32 maxUsedUcodes = sizeof(UsedUcodes)/sizeof(UcodeInfo);
40
//////////////////////////////////////////////////////////
41
//////////////////////////////////////////////////////////
43
//////////////////////////////////////////////////////////
44
//////////////////////////////////////////////////////////
46
UcodeMap *ucodeMaps[] =
48
&ucodeMap0, // ucode 0 - Mario
49
&ucodeMap1, // ucode 1 - GBI1
50
NULL, // ucode 2 - Golden Eye
51
&ucodeMap3, // ucode 3 - S2DEX GBI2
52
NULL, // ucode 4 - Wave Racer
53
&ucodeMap5, // ucode 5 - BGI2
54
NULL, // ucode 6 - DKR
55
&ucodeMap7, // ucode 7 - S2DEX
56
NULL, // ucode 8 - ucode 0 with sprite2D, for Demo Puzzle Master 64
57
NULL, // ucode 9 - Perfect Dark
58
NULL, // ucode 10 - Conker
59
NULL, // ucode 11 - Gemini
60
NULL, // ucode 12 - Silicon Valley, Spacestation
61
NULL, // ucode 13 - modified ucode S2DEX
62
NULL, // ucode 14 - OgreBattle Background
63
NULL, // ucode 15 - ucode 0 with sprite2D
64
NULL, // ucode 16 - Star War, Shadow of Empire
65
NULL, // ucode 17 - Star Wars - Rogue Squadron,
66
NULL, // ucode 18 - World Driver Championship
67
NULL, // ucode 19 - Last Legion UX
68
&ucodeMap1, // ucode 20 - ZSortp
71
uint32 vertexMultVals[] =
73
10, // ucode 0 - Mario
75
10, // ucode 2 - Golden Eye
76
2, // ucode 3 - S2DEX GBI2
77
5, // ucode 4 - Wave Racer
81
10, // ucode 8 - ucode 0 with sprite2D, for Demo Puzzle Master 64
82
10, // ucode 9 - Perfect Dark
83
2, // ucode 10 - Conker
84
10, // ucode 11 - Gemini
85
2, // ucode 12 - Silicon Valley, Spacestation
86
2, // ucode 13 - modified ucode S2DEX
87
2, // ucode 14 - OgreBattle Background
88
10, // ucode 15 - ucode 0 with sprite2D
89
5, // ucode 16 - Star War, Shadow of Empire
91
2, // ucode 17 - Star Wars - Rogue Squadron,
92
2, // ucode 18 - World Driver Championship, check me here
93
2, // ucode 19 - Last Legion UX, check me here
94
2, // ucode 20 - ZSortp
97
CHAR gLastMicrocodeString[ 300 ] = "";
99
//*****************************************************************************
101
//*****************************************************************************
102
static UcodeData g_UcodeData[] =
106
{0, 0x150c3ce8, 0x150c3ce8, (CHAR*)"RSP SW Version: 2.0D, 04-01-96",}, // Super Mario 64
107
{4, 0x2b94276f, 0x2b94276f, (CHAR*)"RSP SW Version: 2.0D, 04-01-96",}, // Wave Race 64 (v1.0)
108
{16,0xb1870454, 0xb1870454, (CHAR*)"RSP SW Version: 2.0D, 04-01-96",}, // Star Wars - Shadows of the Empire (v1.0),
109
{0, 0x51671ae4, 0x51671ae4, (CHAR*)"RSP SW Version: 2.0D, 04-01-96",}, // Pilot Wings 64,
110
{0, 0x67b5ac55, 0x67b5ac55, (CHAR*)"RSP SW Version: 2.0D, 04-01-96",}, // Wibble,
111
{0, 0x64dc8104, 0x64dc8104, (CHAR*)"RSP SW Version: 2.0D, 04-01-96",}, // Dark Rift,
112
{0, 0x309f363d, 0x309f363d, (CHAR*)"RSP SW Version: 2.0D, 04-01-96",}, // Killer Instinct Gold,
113
{0, 0xfcb57e57, 0xfcb57e57, (CHAR*)"RSP SW Version: 2.0D, 04-01-96",}, // Blast Corps,
114
{0, 0xb420f35a, 0xb420f35a, (CHAR*)"RSP SW Version: 2.0D, 04-01-96",}, // Blast Corps,
115
{0, 0x6e26c1df, 0x7c98e9c2, (CHAR*)"RSP SW Version: 2.0D, 04-01-96",},
116
{2, 0xc02ac7bc, 0xc02ac7bc, (CHAR*)"RSP SW Version: 2.0G, 09-30-96",}, // GoldenEye 007,
117
{0, 0xe5fee3bc, 0xe5fee3bc, (CHAR*)"RSP SW Version: 2.0G, 09-30-96",}, // Aero Fighters Assault,
118
{8, 0xe4bb5ad8, 0x80129845, (CHAR*)"RSP SW Version: 2.0G, 09-30-96",}, // Puzzle Master 64,
119
{0, 0x72109ec6, 0x72109ec6, (CHAR*)"RSP SW Version: 2.0H, 02-12-97",}, // Duke Nukem 64,
120
{0, 0xf24a9a04, 0xf24a9a04, (CHAR*)"RSP SW Version: 2.0H, 02-12-97",}, // Tetrisphere,
121
{15,0x700de42e, 0x700de42e, (CHAR*)"RSP SW Version: 2.0H, 02-12-97",}, // Wipeout 64 (uses GBI1 too!),
122
{15,0x1b304a74, 0x1b304a74, (CHAR*)"RSP SW Version: 2.0H, 02-12-97",}, // Flying Dragon,
123
{15,0xe4bb5ad8, 0xa7b2f704, (CHAR*)"RSP SW Version: 2.0H, 02-12-97",}, // Silicon Valley,
124
{15,0xe4bb5ad8, 0x88202781, (CHAR*)"RSP SW Version: 2.0H, 02-12-97",}, // Glover,
125
{0, 0xe466b5bd, 0xe466b5bd, (CHAR*)"Unknown 0xe466b5bd, 0xe466b5bd",}, // Dark Rift,
126
{9, 0x7064a163, 0x7064a163, (CHAR*)"Unknown 0x7064a163, 0x7064a163",}, // Perfect Dark (v1.0),
127
{0, 0x6522df69, 0x71bd078d, (CHAR*)"Unknown 0x6522df69, 0x71bd078d",}, // Tetris
128
{0, 0x6522df69, 0x1b0c23a8, (CHAR*)"Unknown 0x6522df69, 0x1b0c23a8",}, // Pachinko Nichi
132
{1, 0x45ca328e, 0x45ca328e, (CHAR*)"RSP Gfx ucode F3DLX 0.95 Yoshitaka Yasumoto Nintendo.",}, // Mario Kart 64,
133
{1, 0x98e3b909, 0x98e3b909, (CHAR*)"RSP Gfx ucode F3DEX 0.95 Yoshitaka Yasumoto Nintendo.",}, // Mario Kart 64
134
{1, 0x5d446090, 0x5d446090, (CHAR*)"RSP Gfx ucode F3DLP.Rej 0.96 Yoshitaka Yasumoto Nintendo.",0,1}, // Jikkyou J. League Perfect Striker,
135
{1, 0x244f5ca3, 0x244f5ca3, (CHAR*)"RSP Gfx ucode F3DEX 1.00 Yoshitaka Yasumoto Nintendo.",}, // F-1 Pole Position 64,
136
{1, 0x6a022585, 0x6a022585, (CHAR*)"RSP Gfx ucode F3DEX.NoN 1.00 Yoshitaka Yasumoto Nintendo.",1}, // Turok - The Dinosaur Hunter (v1.0),
137
{1, 0x150706be, 0x150706be, (CHAR*)"RSP Gfx ucode F3DLX.NoN 1.00 Yoshitaka Yasumoto Nintendo.",1}, // Extreme-G,
138
{1, 0x503f2c53, 0x503f2c53, (CHAR*)"RSP Gfx ucode F3DEX.NoN 1.21 Yoshitaka Yasumoto Nintendo.",1}, // Bomberman 64,
139
{1, 0xc705c37c, 0xc705c37c, (CHAR*)"RSP Gfx ucode F3DLX 1.21 Yoshitaka Yasumoto Nintendo.",}, // Fighting Force 64, Wipeout 64
140
{1, 0xa2146075, 0xa2146075, (CHAR*)"RSP Gfx ucode F3DLX.NoN 1.21 Yoshitaka Yasumoto Nintendo.",1}, // San Francisco Rush - Extreme Racing,
141
{1, 0xb65aa2da, 0xb65aa2da, (CHAR*)"RSP Gfx ucode L3DEX 1.21 Yoshitaka Yasumoto Nintendo.",}, // Wipeout 64,
142
{1, 0x0c8e5ec9, 0x0c8e5ec9, (CHAR*)"RSP Gfx ucode F3DEX 1.21 Yoshitaka Yasumoto Nintendo.",}, //
143
{1, 0xe30795f2, 0xa53df3c4, (CHAR*)"RSP Gfx ucode F3DLP.Rej 1.21 Yoshitaka Yasumoto Nintendo.",0,1},
145
{1, 0xaebeda7d, 0xaebeda7d, (CHAR*)"RSP Gfx ucode F3DLX.Rej 1.21 Yoshitaka Yasumoto Nintendo.",0,1}, // Jikkyou World Soccer 3,
146
{1, 0x0c8e5ec9, 0x0c8e5ec9, (CHAR*)"RSP Gfx ucode F3DEX 1.23 Yoshitaka Yasumoto Nintendo" ,}, // Wave Race 64 (Rev. 2) - Shindou Rumble Edition (JAP)
147
{1, 0xc705c37c, 0xc705c37c, (CHAR*)"RSP Gfx ucode F3DLX 1.23 Yoshitaka Yasumoto Nintendo.",}, // GT
148
{1, 0x2a61350d, 0x2a61350d, (CHAR*)"RSP Gfx ucode F3DLX 1.23 Yoshitaka Yasumoto Nintendo.",}, // Toy Story2
149
{1, 0x0c8e5ec9, 0x0c8e5ec9, (CHAR*)"RSP Gfx ucode F3DEX 1.23 Yoshitaka Yasumoto Nintendo.",}, // Wave Race 64 Shindou Edition
150
{12,0xfc6529aa, 0xfc6529aa, (CHAR*)"RSP Gfx ucode F3DEX 1.23 Yoshitaka Yasumoto Nintendo.",}, // Superman - The Animated Series,
151
{1, 0xa56cf996, 0xa56cf996, (CHAR*)"RSP Gfx ucode L3DEX 1.23 Yoshitaka Yasumoto Nintendo.",}, // Flying Dragon,
152
{1, 0xcc83b43f, 0xcc83b43f, (CHAR*)"RSP Gfx ucode F3DEX.NoN 1.23 Yoshitaka Yasumoto Nintendo.",1}, // AeroGauge,
153
{1, 0xca8927a0, 0xca8927a0, (CHAR*)"RSP Gfx ucode F3DLX.Rej 1.23 Yoshitaka Yasumoto Nintendo.",0,1}, // Puzzle Bobble 64,
154
{1, 0x25689c75, 0xbe481ae8, (CHAR*)"RSP Gfx ucode F3DLP.Rej 1.23 Yoshitaka Yasumoto Nintendo.",0,1},
155
{1, 0xd2d747b7, 0xd2d747b7, (CHAR*)"RSP Gfx ucode F3DLX.NoN 1.23 Yoshitaka Yasumoto Nintendo.",1}, // Penny Racers,
156
{1, 0xa849c858, 0x5bd32b5a, (CHAR*)"RSP Gfx ucode F3DTEX/A 1.23 Yoshitaka Yasumoto Nintendo.",}, // Tamagotchi
158
{7, 0xecd8b772, 0xecd8b772, (CHAR*)"RSP Gfx ucode S2DEX 1.06 Yoshitaka Yasumoto Nintendo.",}, // Yoshi's Story,
159
{7, 0xf59132f5, 0xf59132f5, (CHAR*)"RSP Gfx ucode S2DEX 1.07 Yoshitaka Yasumoto Nintendo.",}, // Bakuretsu Muteki Bangaioh,
160
{7, 0x961dd811, 0x961dd811, (CHAR*)"RSP Gfx ucode S2DEX 1.03 Yoshitaka Yasumoto Nintendo.",}, // GT
162
{5, 0x3e083afa, 0x722f97cc, (CHAR*)"RSP Gfx ucode F3DEX.NoN fifo 2.03 Yoshitaka Yasumoto 1998 Nintendo.",1}, // F-Zero X,
163
{5, 0xa8050bd1, 0xa8050bd1, (CHAR*)"RSP Gfx ucode F3DEX fifo 2.03 Yoshitaka Yasumoto 1998 Nintendo.",}, // F-Zero X,
164
{5, 0x4e8055f0, 0x4e8055f0, (CHAR*)"RSP Gfx ucode F3DLX.Rej fifo 2.03 Yoshitaka Yasumoto 1998 Nintendo.",0,1}, // F-Zero X,
165
{5, 0xabf001f5, 0xabf001f5, (CHAR*)"RSP Gfx ucode F3DFLX.Rej fifo 2.03F Yoshitaka Yasumoto 1998 Nintendo.",0,1}, // F-Zero X,
166
{5, 0xadb4b686, 0xadb4b686, (CHAR*)"RSP Gfx ucode F3DEX fifo 2.04 Yoshitaka Yasumoto 1998 Nintendo.",}, // Top Gear Rally 2,
167
{5, 0x779e2a9b, 0x779e2a9b, (CHAR*)"RSP Gfx ucode F3DEX.NoN fifo 2.04 Yoshitaka Yasumoto 1998 Nintendo.",1}, // California Speed,
168
{5, 0xa8cb3e09, 0xa8cb3e09, (CHAR*)"RSP Gfx ucode L3DEX fifo 2.04 Yoshitaka Yasumoto 1998 Nintendo.",}, // In-Fisherman Bass Hunter 64,
169
{5, 0x2a1341d6, 0x2a1341d6, (CHAR*)"RSP Gfx ucode F3DEX fifo 2.04H Yoshitaka Yasumoto 1998 Nintendo.",}, // Kirby 64 - The Crystal Shards,
170
{5, 0x3e083afa, 0x89a8e0ed, (CHAR*)"RSP Gfx ucode F3DEX.NoN fifo 2.05 Yoshitaka Yasumoto 1998 Nintendo.",1}, // Carmageddon 64 (uncensored),
171
{5, 0x4964b75d, 0x4964b75d, (CHAR*)"RSP Gfx ucode F3DEX.NoN fifo 2.05 Yoshitaka Yasumoto 1998 Nintendo.",1},
172
{5, 0x39e3e95a, 0x39e3e95a, (CHAR*)"RSP Gfx ucode F3DEX fifo 2.05 Yoshitaka Yasumoto 1998 Nintendo."}, // Knife Edge - Nose Gunner,
173
{5, 0xd2913522, 0xd2913522, (CHAR*)"RSP Gfx ucode F3DAM fifo 2.05 Yoshitaka Yasumoto 1998 Nintendo."}, // Hey You, Pikachu!,
174
{5, 0x3e083afa, 0xc998443f, (CHAR*)"RSP Gfx ucode F3DEX xbus 2.05 Yoshitaka Yasumoto 1998 Nintendo."}, //Triple play
175
{5, 0xf4184a7d, 0xf4184a7d, (CHAR*)"RSP Gfx ucode F3DEX fifo 2.06 Yoshitaka Yasumoto 1998 Nintendo.",}, // Hey You, Pikachu!,
176
{5, 0x595a88de, 0x595a88de, (CHAR*)"RSP Gfx ucode F3DEX.Rej fifo 2.06 Yoshitaka Yasumoto 1998 Nintendo.",0,1}, // Bio Hazard 2,
177
{5, 0x0259f764, 0x0259f764, (CHAR*)"RSP Gfx ucode F3DLX.Rej fifo 2.06 Yoshitaka Yasumoto 1998 Nintendo.",0,1}, // Mario Party,
178
{5, 0xe1a5477a, 0xe1a5477a, (CHAR*)"RSP Gfx ucode F3DEX.NoN xbus 2.06 Yoshitaka Yasumoto 1998 Nintendo.",1}, // Command & Conquer,
179
{5, 0x4cfa0a19, 0x4cfa0a19, (CHAR*)"RSP Gfx ucode F3DZEX.NoN fifo 2.06H Yoshitaka Yasumoto 1998 Nintendo.",1}, // The Legend of Zelda - Ocarina of Time (v1.0),
180
{5, 0x2cbd9514, 0x5f40b9f5, (CHAR*)"RSP Gfx ucode F3DZEX.NoN fifo 2.06H Yoshitaka Yasumoto 1998 Nintendo.",1},
182
{5, 0x3e083afa, 0x882680f4, (CHAR*)"RSP Gfx ucode L3DEX fifo 2.07 Yoshitaka Yasumoto 1998 Nintendo."}, // Polaris Sno
184
{5, 0xdeb1cac0, 0xdeb1cac0, (CHAR*)"RSP Gfx ucode F3DEX.NoN fifo 2.07 Yoshitaka Yasumoto 1998 Nintendo.",1}, // Knockout Kings 2000,
185
{5, 0xf4184a7d, 0xf4184a7d, (CHAR*)"RSP Gfx ucode F3DEX fifo 2.07 Yoshitaka Yasumoto 1998 Nintendo.",}, // Xena Warrior Princess - Talisman of Fate, Army Men - Air Combat, Destruction Derby
186
{5, 0x4b013e60, 0x4b013e60, (CHAR*)"RSP Gfx ucode F3DEX xbus 2.07 Yoshitaka Yasumoto 1998 Nintendo.",}, // Lode Runner 3-D,
187
{5, 0xd1a63836, 0xd1a63836, (CHAR*)"RSP Gfx ucode L3DEX fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // Hey You, Pikachu!,
188
{5, 0x97193667, 0x97193667, (CHAR*)"RSP Gfx ucode F3DEX fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // Top Gear Hyper-Bike,
189
{5, 0x92149ba8, 0x92149ba8, (CHAR*)"RSP Gfx ucode F3DEX fifo 2.08 Yoshitaka Yasumoto/Kawasedo 1999.",}, // Paper Mario,
190
{5, 0xae0fb88f, 0xae0fb88f, (CHAR*)"RSP Gfx ucode F3DEX xbus 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // WWF WrestleMania 2000,
191
{5, 0xc572f368, 0xc572f368, (CHAR*)"RSP Gfx ucode F3DLX.Rej xbus 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // WWF No Mercy,
192
{5, 0x3e083afa, 0x74252492, (CHAR*)"RSP Gfx ucode F3DEX.NoN xbus 2.08 Yoshitaka Yasumoto 1999 Nintendo.",1},
194
{5, 0x9c2edb70, 0xea98e740, (CHAR*)"RSP Gfx ucode F3DEX.NoN fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",1}, // LEGO Racers,
195
{5, 0x79e004a6, 0x79e004a6, (CHAR*)"RSP Gfx ucode F3DLX.Rej fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",0,1}, // Mario Party 2,
196
{5, 0xaa6ab3ca, 0xaa6ab3ca, (CHAR*)"RSP Gfx ucode F3DEX.Rej fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",0,1}, // V-Rally Edition 99,
197
{5, 0x2c597e0f, 0x2c597e0f, (CHAR*)"RSP Gfx ucode F3DEX fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // Cruis'n Exotica,
198
{10, 0x4e5f3e3b, 0x4e5f3e3b,(CHAR*)"RSP Gfx ucode F3DEXBG.NoN fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",1}, // Conker The Bad Fur Day
199
{5, 0x61f31862, 0x61f31862, (CHAR*)"RSP Gfx ucode F3DEX.NoN fifo 2.08H Yoshitaka Yasumoto 1999 Nintendo.",1}, // Pokemon Snap,
200
{5, 0x005f5b71, 0x005f5b71, (CHAR*)"RSP Gfx ucode F3DZEX.NoN fifo 2.08I Yoshitaka Yasumoto/Kawasedo 1999.",1}, // The Legend of Zelda 2 - Majora's Mask,
202
{3, 0x41839d1e, 0x41839d1e, (CHAR*)"RSP Gfx ucode S2DEX fifo 2.05 Yoshitaka Yasumoto 1998 Nintendo.",}, // Chou Snobow Kids,
203
{3, 0x2cbd9514, 0xc639dbb9, (CHAR*)"RSP Gfx ucode S2DEX xbus 2.06 Yoshitaka Yasumoto 1998 Nintendo.",},
204
{3, 0xec89e273, 0xec89e273, (CHAR*)"RSP Gfx ucode S2DEX fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // V-Rally Edition 99,
205
{3, 0x9429b7d6, 0x9429b7d6, (CHAR*)"RSP Gfx ucode S2DEX xbus 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // Star Craft,
206
//{14,0x5a72397b, 0xec89e273, "RSP Gfx ucode S2DEX fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // OgreBattle Background,
207
{3, 0x2cbd9514, 0xec89e273, (CHAR*)"RSP Gfx ucode S2DEX fifo 2.08 Yoshitaka Yasumoto 1999 Nintendo.",}, // Zelda MM,
209
{6, 0x6aef74f8, 0x6aef74f8, (CHAR*)"Unknown 0x6aef74f8, 0x6aef74f8",}, // Diddy Kong Racing (v1.0),
210
{6, 0x4c4eead8, 0x4c4eead8, (CHAR*)"Unknown 0x4c4eead8, 0x4c4eead8",}, // Diddy Kong Racing (v1.1),
212
{1, 0xed421e9a, 0xed421e9a, (CHAR*)"Unknown 0xed421e9a, 0xed421e9a",}, // Kuiki Uhabi Suigo,
213
{5, 0x37751932, 0x55c0fd25, (CHAR*)"Unknown 0x37751932, 0x55c0fd25",}, // Bio Hazard 2,
214
{11,0xbe0b83e7, 0xbe0b83e7,(CHAR*)"Unknown 0xbe0b83e7, 0xbe0b83e7",}, // Jet Force Gemini,
216
{17, 0x02e882cf, 0x2ad17281, (CHAR*)"Unknown 0x02e882cf, 0x2ad17281",}, // Indiana Jones,
217
{17, 0x1f7d9118, 0xdab2199b, (CHAR*)"Unknown 0x1f7d9118, 0xdab2199b",}, // Battle Naboo,
218
{17, 0x74583614, 0x74583614, (CHAR*)"Unknown 0x74583614, 0x74583614",}, // Star Wars - Rogue Squadron,
219
{17, 0xe37e2f49, 0x1eb63fd8, (CHAR*)"Unknown 0xe37e2f49, 0x1eb63fd8",}, // Star Wars - Rogue Squadron,
220
{17, 0x8ce1af3d, 0xb2760ea2, (CHAR*)"Unknown 0x8ce1af3d, 0xb2760ea2",}, // Star Wars - Rogue Squadron,
222
{18, 0x7b685972, 0x57b8095a, (CHAR*)"Unknown 0x7b685972, 0x57b8095a",}, // World Driver Championship
223
{18, 0xe92dbb9b, 0x57b8095a, (CHAR*)"Unknown 0xe92dbb9b, 0x57b8095a",}, // World Driver Championship
224
{18, 0xe6c9acc1, 0x65f80845, (CHAR*)"Unknown 0xe6c9acc1, 0x65f80845",}, // World Driver Championship
225
{18, 0x6522df69, 0x720b88a0, (CHAR*)"Unknown 0x6522df69, 0x720b88a0",}, // World Driver Championship
226
{18, 0x6522df69, 0xf1e8ba9e, (CHAR*)"Unknown 0x6522df69, 0xf1e8ba9e",}, // World Driver Championship
228
{19, 0xa486bed3, 0xa486bed3, (CHAR*)"Unknown 0xa486bed3, 0xa486bed3",}, // Last Legion UX,
229
{19, 0x6b519381, 0xfebacfd8, (CHAR*)"Unknown in Toukan Road",}, // I don't know which ucode
231
{20, 0x6d2a01b1, 0x6d2a01b1, (CHAR*)"RSP Gfx ucode ZSortp 0.33 Yoshitaka Yasumoto Nintendo.",}, // Mia Hamm Soccer 64,
234
FiddledVtx * g_pVtxBase=NULL;
236
SetImgInfo g_TI = { TXT_FMT_RGBA, TXT_SIZE_16b, 1, 0 };
237
SetImgInfo g_CI = { TXT_FMT_RGBA, TXT_SIZE_16b, 1, 0 };
238
SetImgInfo g_ZI = { TXT_FMT_RGBA, TXT_SIZE_16b, 1, 0 };
239
RenderTextureInfo g_ZI_saves[2];
241
DListStack gDlistStack[MAX_DL_STACK_SIZE];
242
int gDlistStackPointer= -1;
244
TMEMLoadMapInfo g_tmemLoadAddrMap[0x200]; // Totally 4KB TMEM
245
TMEMLoadMapInfo g_tmemInfo0; // Info for Tmem=0
246
TMEMLoadMapInfo g_tmemInfo1; // Info for Tmem=0x100
248
const char *pszImgSize[4] = {"4", "8", "16", "32"};
249
const char *textluttype[4] = {"RGB16", "I16?", "RGBA16", "IA16"};
250
uint16 g_wRDPTlut[0x200];
251
uint32 g_dwRDPPalCrc[16];
253
#include "FrameBuffer.h"
254
#include "RSP_GBI0.h"
255
#include "RSP_GBI1.h"
256
#include "RSP_GBI2.h"
257
#include "RSP_GBI2_ext.h"
258
#include "RSP_GBI_Others.h"
259
#include "RSP_GBI_Sprite2D.h"
260
#include "RDP_Texture.h"
262
//////////////////////////////////////////////////////////
263
//////////////////////////////////////////////////////////
265
//////////////////////////////////////////////////////////
266
//////////////////////////////////////////////////////////
273
status.gDlistCount = 0;
274
status.gUcodeCount = 0;
275
status.frameReadByCPU = FALSE;
276
status.frameWriteByCPU = FALSE;
277
status.SPCycleCount = 0;
278
status.DPCycleCount = 0;
279
status.bN64IsDrawingTextureBuffer = false;
280
status.bDirectWriteIntoRDRAM = false;
281
status.bHandleN64RenderTexture = false;
283
status.bUcodeIsKnown = FALSE;
284
status.lastPurgeTimeTime = status.gRDPTime;
286
status.curRenderBuffer = 0;
287
status.curDisplayBuffer = 0;
288
status.curVIOriginReg = 0;
290
status.primitiveType = PRIM_TRI1;
292
status.lastPurgeTimeTime = 0; // Time textures were last purged
294
status.UseLargerTile[0] = status.UseLargerTile[0] = false;
295
status.LargerTileRealLeft[0] = status.LargerTileRealLeft[1] = 0;
296
memset(&g_ZI_saves, 0, sizeof(RenderTextureInfo)*2);
300
memset(&gRDP.tiles[i], 0, sizeof(Tile));
302
memset(g_tmemLoadAddrMap, 0, sizeof(g_tmemLoadAddrMap));
304
for( i=0; i<MAX_UCODE_INFO; i++ )
306
memset(&ucodeInfo[i], 0, sizeof(UcodeInfo));
309
status.bUseModifiedUcodeMap = false;
310
status.ucodeHasBeenSet = false;
311
status.bAllowLoadFromTMEM = true;
314
strcpy(name, (char*)g_curRomInfo.szGameName);
316
memset(&lastUcodeInfo, 0, sizeof(UcodeInfo));
317
memset(&UsedUcodes, 0, sizeof(UsedUcodes));
318
memset(&g_TmemFlag, 0, sizeof(g_TmemFlag));
319
memset(&g_RecentCIInfo, 0, sizeof(RecentCIInfo)*5);
320
memset(&g_RecentVIOriginInfo, 0, sizeof(RecentViOriginInfo)*5);
321
memset(&g_ZI_saves, 0, sizeof(RenderTextureInfo)*2);
322
memset(&g_ZI, 0, sizeof(SetImgInfo));
323
memset(&g_CI, 0, sizeof(SetImgInfo));
324
memset(&g_TI, 0, sizeof(SetImgInfo));
326
status.UseLargerTile[0] = status.UseLargerTile[1] = false;
327
status.LargerTileRealLeft[0] = status.LargerTileRealLeft[1] = 0;
333
gDlistStackPointer=-1;
334
status.bUcodeIsKnown = FALSE;
335
gTextureManager.RecycleAllTextures();
341
if( status.bHandleN64RenderTexture )
343
g_pFrameBufferManager->CloseRenderTexture(false);
347
void RDP_SetUcodeMap(int ucode)
349
status.bUseModifiedUcodeMap = false;
352
case 0: // Mario and demos
354
case 1: // F3DEX GBI1
357
case 2: // Golden Eye
358
memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap));
359
//LoadedUcodeMap[9]=RSP_GBI1_Sprite2DBase;
360
//LoadedUcodeMap[0xaf]=RSP_GBI1_LoadUCode;
361
//LoadedUcodeMap[0xb0]=RSP_GBI1_BranchZ;
362
LoadedUcodeMap[0xb4]=DLParser_RDPHalf_1_0xb4_GoldenEye;
363
status.bUseModifiedUcodeMap = true;
365
case 3: // S2DEX GBI2
368
memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap));
369
LoadedUcodeMap[4]=RSP_Vtx_WRUS;
370
LoadedUcodeMap[0xb1]=RSP_GBI1_Tri2;
371
//LoadedUcodeMap[9]=RSP_GBI1_Sprite2DBase;
372
//LoadedUcodeMap[0xaf]=RSP_GBI1_LoadUCode;
373
//LoadedUcodeMap[0xb0]=RSP_GBI1_BranchZ;
374
//LoadedUcodeMap[0xb2]=RSP_GBI1_ModifyVtx;
375
status.bUseModifiedUcodeMap = true;
377
case 5: // F3DEX GBI2
379
case 6: // DKR, Jet Force Gemini, Mickey
380
case 11: // DKR, Jet Force Gemini, Mickey
381
memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap));
382
LoadedUcodeMap[1]=RSP_Mtx_DKR;
383
LoadedUcodeMap[4]=RSP_Vtx_DKR;
384
if( ucode == 11 ) LoadedUcodeMap[4]=RSP_Vtx_Gemini;
385
LoadedUcodeMap[5]=RSP_DMA_Tri_DKR;
386
LoadedUcodeMap[7]=RSP_DL_In_MEM_DKR;
387
LoadedUcodeMap[0xbc]=RSP_MoveWord_DKR;
388
LoadedUcodeMap[0xbf]=DLParser_Set_Addr_Ucode6;
389
//LoadedUcodeMap[9]=RSP_GBI1_Sprite2DBase;
390
//LoadedUcodeMap[0xb0]=RSP_GBI1_BranchZ;
391
//LoadedUcodeMap[0xb2]=RSP_GBI1_ModifyVtx;
392
status.bUseModifiedUcodeMap = true;
394
case 7: // S2DEX GBI1
396
case 8: // Ucode 0 with Sprite2D, Puzzle Master 64
397
memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap));
398
LoadedUcodeMap[RSP_SPRITE2D_BASE] = RSP_GBI_Sprite2D_PuzzleMaster64;
399
LoadedUcodeMap[RSP_SPRITE2D_SCALEFLIP] = RSP_GBI1_Sprite2DScaleFlip;
400
LoadedUcodeMap[RSP_SPRITE2D_DRAW] = RSP_GBI0_Sprite2DDraw;
401
status.bUseModifiedUcodeMap = true;
403
case 9: // Perfect Dark
404
memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap));
405
LoadedUcodeMap[4]=RSP_Vtx_PD;
406
LoadedUcodeMap[7]=RSP_Set_Vtx_CI_PD;
407
LoadedUcodeMap[0xb1]=RSP_Tri4_PD;
408
LoadedUcodeMap[0xb4]=DLParser_RDPHalf_1_0xb4_GoldenEye;
409
status.bUseModifiedUcodeMap = true;
411
case 10: // Conker BFD
412
memcpy( &LoadedUcodeMap, &ucodeMap5, sizeof(UcodeMap));
413
LoadedUcodeMap[1]=RSP_Vtx_Conker;
414
LoadedUcodeMap[0x10]=DLParser_Tri4_Conker;
415
LoadedUcodeMap[0x11]=DLParser_Tri4_Conker;
416
LoadedUcodeMap[0x12]=DLParser_Tri4_Conker;
417
LoadedUcodeMap[0x13]=DLParser_Tri4_Conker;
418
LoadedUcodeMap[0x14]=DLParser_Tri4_Conker;
419
LoadedUcodeMap[0x15]=DLParser_Tri4_Conker;
420
LoadedUcodeMap[0x16]=DLParser_Tri4_Conker;
421
LoadedUcodeMap[0x17]=DLParser_Tri4_Conker;
422
LoadedUcodeMap[0x18]=DLParser_Tri4_Conker;
423
LoadedUcodeMap[0x19]=DLParser_Tri4_Conker;
424
LoadedUcodeMap[0x1a]=DLParser_Tri4_Conker;
425
LoadedUcodeMap[0x1b]=DLParser_Tri4_Conker;
426
LoadedUcodeMap[0x1c]=DLParser_Tri4_Conker;
427
LoadedUcodeMap[0x1d]=DLParser_Tri4_Conker;
428
LoadedUcodeMap[0x1e]=DLParser_Tri4_Conker;
429
LoadedUcodeMap[0x1f]=DLParser_Tri4_Conker;
430
LoadedUcodeMap[0xdb]=DLParser_MoveWord_Conker;
431
LoadedUcodeMap[0xdc]=DLParser_MoveMem_Conker;
432
status.bUseModifiedUcodeMap = true;
434
case 12: // Silicon Velley, Space Station
435
memcpy( &LoadedUcodeMap, &ucodeMap1, sizeof(UcodeMap));
436
LoadedUcodeMap[0x01]=RSP_GBI0_Mtx;
437
status.bUseModifiedUcodeMap = true;
439
case 13: // modified S2DEX
440
memcpy( &LoadedUcodeMap, &ucodeMap7, sizeof(UcodeMap));
441
//LoadedUcodeMap[S2DEX_BG_1CYC] = ucodeMap1[S2DEX_BG_1CYC];
442
LoadedUcodeMap[S2DEX_OBJ_RECTANGLE] = ucodeMap1[S2DEX_OBJ_RECTANGLE];
443
LoadedUcodeMap[S2DEX_OBJ_SPRITE] = ucodeMap1[S2DEX_OBJ_SPRITE];
444
//LoadedUcodeMap[S2DEX_OBJ_RENDERMODE] = ucodeMap1[S2DEX_OBJ_RENDERMODE];
445
//LoadedUcodeMap[S2DEX_OBJ_RECTANGLE_R] = ucodeMap1[S2DEX_OBJ_RECTANGLE_R];
446
LoadedUcodeMap[S2DEX_RDPHALF_0] = ucodeMap1[S2DEX_RDPHALF_0];
447
status.bUseModifiedUcodeMap = true;
449
case 14: // OgreBattle Background
450
memcpy( &LoadedUcodeMap, &ucodeMap5, sizeof(UcodeMap));
451
LoadedUcodeMap[0xda] = DLParser_OgreBatter64BG;
452
LoadedUcodeMap[0xdc] = RSP_S2DEX_OBJ_MOVEMEM;
453
status.bUseModifiedUcodeMap = true;
455
case 15: // Ucode 0 with Sprite2D
456
memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap));
457
LoadedUcodeMap[RSP_SPRITE2D_BASE] = RSP_GBI_Sprite2DBase;
458
LoadedUcodeMap[RSP_SPRITE2D_SCALEFLIP] = RSP_GBI1_Sprite2DScaleFlip;
459
LoadedUcodeMap[RSP_SPRITE2D_DRAW] = RSP_GBI0_Sprite2DDraw;
460
status.bUseModifiedUcodeMap = true;
462
case 16: // Star War, Shadow Of Empire
463
memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap));
464
LoadedUcodeMap[4]=RSP_Vtx_ShadowOfEmpire;
465
status.bUseModifiedUcodeMap = true;
467
case 17: //Indiana Jones, does not work anyway
468
memcpy( &LoadedUcodeMap, &ucodeMap1, sizeof(UcodeMap));
469
LoadedUcodeMap[0]=DLParser_Ucode8_0x0;
470
//LoadedUcodeMap[1]=RSP_RDP_Nothing;
471
LoadedUcodeMap[2]=DLParser_RS_Color_Buffer;
472
LoadedUcodeMap[3]=DLParser_RS_MoveMem;
473
LoadedUcodeMap[4]=DLParser_RS_Vtx_Buffer;
474
LoadedUcodeMap[5]=DLParser_Ucode8_0x05;
475
LoadedUcodeMap[6]=DLParser_Ucode8_DL;
476
LoadedUcodeMap[7]=DLParser_Ucode8_JUMP;
477
LoadedUcodeMap[8]=RSP_RDP_Nothing;
478
LoadedUcodeMap[9]=RSP_RDP_Nothing;
479
LoadedUcodeMap[10]=RSP_RDP_Nothing;
480
LoadedUcodeMap[11]=RSP_RDP_Nothing;
481
LoadedUcodeMap[0x80]=DLParser_RS_Block;
482
LoadedUcodeMap[0xb4]=DLParser_Ucode8_0xb4;
483
LoadedUcodeMap[0xb5]=DLParser_Ucode8_0xb5;
484
LoadedUcodeMap[0xb8]=DLParser_Ucode8_EndDL;
485
LoadedUcodeMap[0xbc]=DLParser_Ucode8_0xbc;
486
LoadedUcodeMap[0xbd]=DLParser_Ucode8_0xbd;
487
LoadedUcodeMap[0xbe]=DLParser_RS_0xbe;
488
LoadedUcodeMap[0xbF]=DLParser_Ucode8_0xbf;
489
LoadedUcodeMap[0xe4]=DLParser_TexRect_Last_Legion;
490
status.bUseModifiedUcodeMap = true;
492
case 18: // World Driver Championship
493
memcpy( &LoadedUcodeMap, &ucodeMap1, sizeof(UcodeMap));
494
LoadedUcodeMap[0xe]=DLParser_RSP_DL_WorldDriver;
495
LoadedUcodeMap[0x2]=DLParser_RSP_Pop_DL_WorldDriver;
496
LoadedUcodeMap[0xdf]=DLParser_RSP_Pop_DL_WorldDriver;
497
LoadedUcodeMap[0x6]=RSP_RDP_Nothing;
498
status.bUseModifiedUcodeMap = true;
500
case 19: // Last Legion UX
501
memcpy( &LoadedUcodeMap, &ucodeMap1, sizeof(UcodeMap));
502
LoadedUcodeMap[0x80]=DLParser_RSP_Last_Legion_0x80;
503
LoadedUcodeMap[0x00]=DLParser_RSP_Last_Legion_0x00;
504
LoadedUcodeMap[0xe4]=DLParser_TexRect_Last_Legion;
505
status.bUseModifiedUcodeMap = true;
508
memcpy( &LoadedUcodeMap, &ucodeMap5, sizeof(UcodeMap));
509
status.bUseModifiedUcodeMap = true;
515
TRACE1("Using ucode %d", ucode);
519
void RSP_SetUcode(int ucode, uint32 ucStart, uint32 ucDStart, uint32 ucSize)
521
if( status.ucodeHasBeenSet && gRSP.ucode == ucode )
524
status.ucodeHasBeenSet = true;
529
RDP_SetUcodeMap(ucode);
530
if( status.bUseModifiedUcodeMap )
532
currentUcodeMap = &LoadedUcodeMap[0];
536
currentUcodeMap = *ucodeMaps[ucode];
539
gRSP.vertexMult = vertexMultVals[ucode];
541
//if( gRSP.ucode != ucode ) DebuggerAppendMsg("Set to ucode: %d", ucode);
544
lastUcodeInfo.used = true;
547
lastUcodeInfo.ucStart = g_pOSTask->t.ucode;
548
lastUcodeInfo.ucDStart = g_pOSTask->t.ucode_data;
549
lastUcodeInfo.ucSize = g_pOSTask->t.ucode_size;
553
lastUcodeInfo.ucStart = ucStart;
554
lastUcodeInfo.ucDStart = ucDStart;
555
lastUcodeInfo.ucSize = ucSize;
559
//*****************************************************************************
561
//*****************************************************************************
562
static uint32 DLParser_IdentifyUcodeFromString( const CHAR * str_ucode )
564
const CHAR str_ucode0[] = "RSP SW Version: 2.0";
565
const CHAR str_ucode1[] = "RSP Gfx ucode ";
567
if ( strncasecmp( (char*)str_ucode, (char*)str_ucode0, strlen((char*)str_ucode0) ) == 0 )
572
if ( strncasecmp( (char*)str_ucode, (char*)str_ucode1, strlen((char*)str_ucode1) ) == 0 )
574
if( strstr((char*)str_ucode,"1.") != 0 )
576
if( strstr((char*)str_ucode,"S2DEX") != 0 )
583
else if( strstr((char*)str_ucode,"2.") != 0 )
585
if( strstr((char*)str_ucode,"S2DEX") != 0 )
597
//*****************************************************************************
599
//*****************************************************************************
600
static uint32 DLParser_IdentifyUcode( uint32 crc_size, uint32 crc_800, char* str )
602
for ( uint32 i = 0; i < sizeof(g_UcodeData)/sizeof(UcodeData); i++ )
605
if ( crc_800 == g_UcodeData[i].crc_800 )
607
if( strlen(str)==0 || strcmp((const char *) g_UcodeData[i].ucode_name, str) == 0 )
609
TRACE0((const char *) g_UcodeData[i].ucode_name);
613
DebuggerAppendMsg("Incorrect description for this ucode:\n%x, %x, %s",crc_800, crc_size, str);
615
status.bUcodeIsKnown = TRUE;
616
gRSP.bNearClip = !g_UcodeData[i].non_nearclip;
617
gRSP.bRejectVtx = g_UcodeData[i].reject;
618
DebuggerAppendMsg("Identify ucode = %d, crc = %08X, %s", g_UcodeData[i].ucode, crc_800, str);
619
return g_UcodeData[i].ucode;
622
if ( crc_800 == g_UcodeData[i].crc_800 )
624
status.bUcodeIsKnown = TRUE;
625
gRSP.bNearClip = !g_UcodeData[i].non_nearclip;
626
gRSP.bRejectVtx = g_UcodeData[i].reject;
627
return g_UcodeData[i].ucode;
634
static bool warned = false;
635
if( warned == false )
638
TRACE0("Can not identify ucode for this game");
642
gRSP.bNearClip = false;
643
gRSP.bRejectVtx = false;
644
status.bUcodeIsKnown = FALSE;
648
uint32 DLParser_CheckUcode(uint32 ucStart, uint32 ucDStart, uint32 ucSize, uint32 ucDSize)
650
if( options.enableHackForGames == HACK_FOR_ROGUE_SQUADRON )
655
// Check the used ucode table first
656
int usedUcodeIndex = 0;
657
for( usedUcodeIndex=0; (unsigned int)usedUcodeIndex<maxUsedUcodes; usedUcodeIndex++ )
659
if( UsedUcodes[usedUcodeIndex].used == false )
664
if( UsedUcodes[usedUcodeIndex].ucStart == ucStart && UsedUcodes[usedUcodeIndex].ucSize == ucSize &&
665
UsedUcodes[usedUcodeIndex].ucDStart == ucDStart /*&& UsedUcodes[usedUcodeIndex].ucDSize == ucDSize*/ )
668
if(gRSP.ucode != (int)UsedUcodes[usedUcodeIndex].ucode && logMicrocode)
670
DebuggerAppendMsg("Check, ucode = %d, crc = %08X, %s", UsedUcodes[usedUcodeIndex].ucode,
671
UsedUcodes[usedUcodeIndex].crc_800 , UsedUcodes[usedUcodeIndex].rspstr);
674
lastUcodeInfo.ucStart = ucStart;
675
lastUcodeInfo.used = true;
676
lastUcodeInfo.ucDStart = ucDStart;
677
lastUcodeInfo.ucSize = ucSize;
678
return UsedUcodes[usedUcodeIndex].ucode;
682
uint32 base = ucDStart & 0x1fffffff;
684
if( base < g_dwRamSize+0x1000 )
686
for ( uint32 i = 0; i < 0x1000; i++ )
689
if ( g_pRDRAMs8[ base + ((i+0) ^ 3) ] == 'R' &&
690
g_pRDRAMs8[ base + ((i+1) ^ 3) ] == 'S' &&
691
g_pRDRAMs8[ base + ((i+2) ^ 3) ] == 'P' )
694
while ( g_pRDRAMs8[ base + (i ^ 3) ] >= ' ')
696
*p++ = g_pRDRAMs8[ base + (i ^ 3) ];
705
//if ( strcmp( str, gLastMicrocodeString ) != 0 )
707
//uint32 size = ucDSize;
708
base = ucStart & 0x1fffffff;
710
uint32 crc_size = ComputeCRC32( 0, &g_pRDRAMu8[ base ], 8);//size );
711
uint32 crc_800 = ComputeCRC32( 0, &g_pRDRAMu8[ base ], 0x800 );
713
ucode = DLParser_IdentifyUcode( crc_size, crc_800, (char*)str );
714
if ( (int)ucode == ~0 )
717
static bool warned=false;
718
//if( warned == false )
722
sprintf(message, "Unable to find ucode to use for\n\n"
724
"CRCSize: 0x%08x\n\n"
726
"Please mail rice1964@yahoo.com with the contents of c:\\ucodes.txt",
727
str, crc_size, crc_800);
733
ucode = DLParser_IdentifyUcodeFromString(str);
734
if ( (int)ucode == ~0 )
740
//DLParser_SetuCode( ucode );
744
static bool warned=false;
745
if( warned == false )
748
if( strlen((char *) str) == 0 )
749
DebuggerAppendMsg("Can not find RSP string in the DLIST, CRC800: 0x%08x, CRCSize: 0x%08x", crc_800, crc_size);
751
TRACE0((char *) str);
755
strcpy( (char*)gLastMicrocodeString, (char*)str );
757
if( usedUcodeIndex >= MAX_UCODE_INFO )
759
usedUcodeIndex = rand()%MAX_UCODE_INFO;
762
UsedUcodes[usedUcodeIndex].ucStart = ucStart;
763
UsedUcodes[usedUcodeIndex].ucSize = ucSize;
764
UsedUcodes[usedUcodeIndex].ucDStart = ucDStart;
765
UsedUcodes[usedUcodeIndex].ucDSize = ucDSize;
766
UsedUcodes[usedUcodeIndex].ucode = ucode;
767
UsedUcodes[usedUcodeIndex].crc_800 = crc_800;
768
UsedUcodes[usedUcodeIndex].crc_size = crc_size;
769
UsedUcodes[usedUcodeIndex].used = true;
770
strcpy( UsedUcodes[usedUcodeIndex].rspstr, (char*)str );
772
TRACE2("New ucode has been detected:\n%s, ucode=%d", str, ucode);
778
extern int dlistMtxCount;
779
extern bool bHalfTxtScale;
781
void DLParser_Process(OSTask * pTask)
783
static int skipframe=0;
784
//BOOL menuWaiting = FALSE;
787
bHalfTxtScale = false;
789
if ( CRender::g_pRender == NULL)
791
TriggerDPInterrupt();
792
TriggerSPInterrupt();
796
status.bScreenIsDrawn = true;
797
if( options.bSkipFrame )
802
TriggerDPInterrupt();
803
TriggerSPInterrupt();
808
if( currentRomOptions.N64RenderToTextureEmuType != TXT_BUF_NONE && defaultRomOptions.bSaveVRAM )
810
g_pFrameBufferManager->CheckRenderTextureCRCInRDRAM();
815
DebuggerPauseCountN( NEXT_DLIST );
817
gettimeofday(&tv, 0);
818
status.gRDPTime = tv.tv_usec;
820
status.gDlistCount++;
822
if ( lastUcodeInfo.ucStart != (uint32)(pTask->t.ucode) )
824
uint32 ucode = DLParser_CheckUcode(pTask->t.ucode, pTask->t.ucode_data, pTask->t.ucode_size, pTask->t.ucode_data_size);
825
RSP_SetUcode(ucode, pTask->t.ucode, pTask->t.ucode_data, pTask->t.ucode_size);
826
DEBUGGER_PAUSE_AND_DUMP(NEXT_SWITCH_UCODE,{DebuggerAppendMsg("Pause at switching ucode");});
830
status.bN64FrameBufferIsUsed = false;
831
gDlistStackPointer=0;
832
gDlistStack[gDlistStackPointer].pc = (uint32)pTask->t.data_ptr;
833
gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT;
834
DEBUGGER_PAUSE_AT_COND_AND_DUMP_COUNT_N((gDlistStack[gDlistStackPointer].pc == 0 && pauseAtNext && eventToPause==NEXT_UNKNOWN_OP),
835
{DebuggerAppendMsg("Start Task without DLIST: ucode=%08X, data=%08X", (uint32)pTask->t.ucode, (uint32)pTask->t.ucode_data);});
838
// Check if we need to purge
839
if (status.gRDPTime - status.lastPurgeTimeTime > 5000)
841
gTextureManager.PurgeOldTextures();
842
status.lastPurgeTimeTime = status.gRDPTime;
845
status.dwNumDListsCulled = 0;
846
status.dwNumTrisRendered = 0;
847
status.dwNumTrisClipped = 0;
848
status.dwNumVertices = 0;
849
status.dwBiggestVertexIndex = 0;
851
if( g_curRomInfo.bForceScreenClear && CGraphicsContext::needCleanScene )
853
CRender::g_pRender->ClearBuffer(true,true);
854
CGraphicsContext::needCleanScene = false;
858
CRender::g_pRender->RenderReset();
859
CRender::g_pRender->BeginRendering();
860
CRender::g_pRender->SetViewport(0, 0, windowSetting.uViWidth, windowSetting.uViHeight, 0x3FF);
861
CRender::g_pRender->SetFillMode(options.bWinFrameMode? RICE_FILLMODE_WINFRAME : RICE_FILLMODE_SOLID);
866
while( gDlistStackPointer >= 0 )
869
DEBUGGER_PAUSE_COUNT_N(NEXT_UCODE);
873
CRender::g_pRender->SetFillMode(options.bWinFrameMode? RICE_FILLMODE_WINFRAME : RICE_FILLMODE_SOLID);
876
if (gDlistStack[gDlistStackPointer].pc > g_dwRamSize)
878
DebuggerAppendMsg("Error: dwPC is %08X", gDlistStack[gDlistStackPointer].pc );
883
status.gUcodeCount++;
885
Gfx *pgfx = (Gfx*)&g_pRDRAMu32[(gDlistStack[gDlistStackPointer].pc>>2)];
887
LOG_UCODE("0x%08x: %08x %08x %-10s",
888
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)]);
890
gDlistStack[gDlistStackPointer].pc += 8;
891
currentUcodeMap[pgfx->words.w0 >>24](pgfx);
893
if ( gDlistStackPointer >= 0 && --gDlistStack[gDlistStackPointer].countdown < 0 )
895
LOG_UCODE("**EndDLInMem");
896
gDlistStackPointer--;
903
TRACE0("Unknown exception happens in ProcessDList");
904
TriggerDPInterrupt();
907
CRender::g_pRender->EndRendering();
909
if( gRSP.ucode >= 17)
910
TriggerDPInterrupt();
911
TriggerSPInterrupt();
914
//////////////////////////////////////////////////////////
915
//////////////////////////////////////////////////////////
917
//////////////////////////////////////////////////////////
918
//////////////////////////////////////////////////////////
920
void RDP_NOIMPL_Real(const char* op, uint32 word0, uint32 word1)
925
TRACE0("Stack Trace");
926
for( int i=0; i<gDlistStackPointer; i++ )
928
DebuggerAppendMsg(" %08X", gDlistStack[i].pc);
930
uint32 dwPC = gDlistStack[gDlistStackPointer].pc-8;
931
DebuggerAppendMsg("PC=%08X",dwPC);
932
DebuggerAppendMsg(op, word0, word1);
934
DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_UNKNOWN_OP, {TRACE0("Paused at unimplemented ucode\n");})
938
void RDP_NOIMPL_WARN(const char* op)
949
void RSP_GBI1_Noop(Gfx *gfx)
956
LOG_UCODE("Returning from DisplayList: level=%d", gDlistStackPointer+1);
957
LOG_UCODE("############################################");
958
LOG_UCODE("/\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\");
961
gDlistStackPointer--;
964
uint32 CalcalateCRC(uint32* srcPtr, uint32 srcSize)
967
for( uint32 i=0; i<srcSize; i++ )
975
void RSP_GFX_InitGeometryMode()
977
bool bCullFront = (gRDP.geometryMode & G_CULL_FRONT) ? true : false;
978
bool bCullBack = (gRDP.geometryMode & G_CULL_BACK) ? true : false;
979
if( bCullFront && bCullBack ) // should never cull front
983
CRender::g_pRender->SetCullMode(bCullFront, bCullBack);
985
BOOL bShade = (gRDP.geometryMode & G_SHADE) ? TRUE : FALSE;
986
BOOL bShadeSmooth = (gRDP.geometryMode & G_SHADING_SMOOTH) ? TRUE : FALSE;
987
if (bShade && bShadeSmooth) CRender::g_pRender->SetShadeMode( SHADE_SMOOTH );
988
else CRender::g_pRender->SetShadeMode( SHADE_FLAT );
990
CRender::g_pRender->SetFogEnable( gRDP.geometryMode & G_FOG ? true : false );
991
SetTextureGen((gRDP.geometryMode & G_TEXTURE_GEN) ? true : false );
992
SetLighting( (gRDP.geometryMode & G_LIGHTING ) ? true : false );
993
CRender::g_pRender->ZBufferEnable( gRDP.geometryMode & G_ZBUFFER );
996
//////////////////////////////////////////////////////////
997
//////////////////////////////////////////////////////////
999
//////////////////////////////////////////////////////////
1000
//////////////////////////////////////////////////////////
1002
void DLParser_SetKeyGB(Gfx *gfx)
1004
DP_Timing(DLParser_SetKeyGB);
1006
gRDP.keyB = ((gfx->words.w1)>>8)&0xFF;
1007
gRDP.keyG = ((gfx->words.w1)>>24)&0xFF;
1008
gRDP.keyA = (gRDP.keyR+gRDP.keyG+gRDP.keyB)/3;
1009
gRDP.fKeyA = gRDP.keyA/255.0f;
1011
void DLParser_SetKeyR(Gfx *gfx)
1013
DP_Timing(DLParser_SetKeyR);
1015
gRDP.keyR = ((gfx->words.w1)>>8)&0xFF;
1016
gRDP.keyA = (gRDP.keyR+gRDP.keyG+gRDP.keyB)/3;
1017
gRDP.fKeyA = gRDP.keyA/255.0f;
1020
int g_convk0,g_convk1,g_convk2,g_convk3,g_convk4,g_convk5;
1021
float g_convc0,g_convc1,g_convc2,g_convc3,g_convc4,g_convc5;
1022
void DLParser_SetConvert(Gfx *gfx)
1024
DP_Timing(DLParser_SetConvert);
1028
temp = ((gfx->words.w0)>>13)&0x1FF;
1029
g_convk0 = temp>0xFF ? -(temp-0x100) : temp;
1031
temp = ((gfx->words.w0)>>4)&0x1FF;
1032
g_convk1 = temp>0xFF ? -(temp-0x100) : temp;
1034
temp = (gfx->words.w0)&0xF;
1035
temp = (temp<<5)|(((gfx->words.w1)>>27)&0x1F);
1036
g_convk2 = temp>0xFF ? -(temp-0x100) : temp;
1038
temp = ((gfx->words.w1)>>18)&0x1FF;
1039
g_convk3 = temp>0xFF ? -(temp-0x100) : temp;
1041
temp = ((gfx->words.w1)>>9)&0x1FF;
1042
g_convk4 = temp>0xFF ? -(temp-0x100) : temp;
1044
temp = (gfx->words.w1)&0x1FF;
1045
g_convk5 = temp>0xFF ? -(temp-0x100) : temp;
1047
g_convc0 = g_convk5/255.0f+1.0f;
1048
g_convc1 = g_convk0/255.0f*g_convc0;
1049
g_convc2 = g_convk1/255.0f*g_convc0;
1050
g_convc3 = g_convk2/255.0f*g_convc0;
1051
g_convc4 = g_convk3/255.0f*g_convc0;
1053
void DLParser_SetPrimDepth(Gfx *gfx)
1055
DP_Timing(DLParser_SetPrimDepth);
1056
uint32 dwZ = ((gfx->words.w1) >> 16) & 0xFFFF;
1057
uint32 dwDZ = ((gfx->words.w1) ) & 0xFFFF;
1059
LOG_UCODE("SetPrimDepth: 0x%08x 0x%08x - z: 0x%04x dz: 0x%04x",
1060
gfx->words.w0, gfx->words.w1, dwZ, dwDZ);
1062
SetPrimitiveDepth(dwZ, dwDZ);
1063
DEBUGGER_PAUSE(NEXT_SET_PRIM_COLOR);
1066
void DLParser_RDPSetOtherMode(Gfx *gfx)
1068
DP_Timing(DLParser_RDPSetOtherMode);
1069
gRDP.otherMode._u32[1] = (gfx->words.w0); // High
1070
gRDP.otherMode._u32[0] = (gfx->words.w1); // Low
1072
if( gRDP.otherModeH != ((gfx->words.w0) & 0x0FFFFFFF) )
1074
gRDP.otherModeH = ((gfx->words.w0) & 0x0FFFFFFF);
1076
uint32 dwTextFilt = (gRDP.otherModeH>>RSP_SETOTHERMODE_SHIFT_TEXTFILT)&0x3;
1077
CRender::g_pRender->SetTextureFilter(dwTextFilt<<RSP_SETOTHERMODE_SHIFT_TEXTFILT);
1080
if( gRDP.otherModeL != (gfx->words.w1) )
1082
if( (gRDP.otherModeL&ZMODE_DEC) != ((gfx->words.w1)&ZMODE_DEC) )
1084
if( ((gfx->words.w1)&ZMODE_DEC) == ZMODE_DEC )
1085
CRender::g_pRender->SetZBias( 2 );
1087
CRender::g_pRender->SetZBias( 0 );
1090
gRDP.otherModeL = (gfx->words.w1);
1092
BOOL bZCompare = (gRDP.otherModeL & Z_COMPARE) ? TRUE : FALSE;
1093
BOOL bZUpdate = (gRDP.otherModeL & Z_UPDATE) ? TRUE : FALSE;
1095
CRender::g_pRender->SetZCompare( bZCompare );
1096
CRender::g_pRender->SetZUpdate( bZUpdate );
1098
uint32 dwAlphaTestMode = (gRDP.otherModeL >> RSP_SETOTHERMODE_SHIFT_ALPHACOMPARE) & 0x3;
1100
if ((dwAlphaTestMode) != 0)
1101
CRender::g_pRender->SetAlphaTestEnable( TRUE );
1103
CRender::g_pRender->SetAlphaTestEnable( FALSE );
1106
uint16 blender = gRDP.otherMode.blender;
1107
RDP_BlenderSetting &bl = *(RDP_BlenderSetting*)(&(blender));
1108
if( bl.c1_m1a==3 || bl.c1_m2a == 3 || bl.c2_m1a == 3 || bl.c2_m2a == 3 )
1110
gRDP.bFogEnableInBlender = true;
1114
gRDP.bFogEnableInBlender = false;
1120
void DLParser_RDPLoadSync(Gfx *gfx)
1122
DP_Timing(DLParser_RDPLoadSync);
1123
LOG_UCODE("LoadSync: (Ignored)");
1126
void DLParser_RDPPipeSync(Gfx *gfx)
1128
DP_Timing(DLParser_RDPPipeSync);
1129
LOG_UCODE("PipeSync: (Ignored)");
1131
void DLParser_RDPTileSync(Gfx *gfx)
1133
DP_Timing(DLParser_RDPTileSync);
1134
LOG_UCODE("TileSync: (Ignored)");
1137
void DLParser_RDPFullSync(Gfx *gfx)
1139
DP_Timing(DLParser_RDPFullSync);
1140
TriggerDPInterrupt();
1143
void DLParser_SetScissor(Gfx *gfx)
1145
DP_Timing(DLParser_SetScissor);
1147
ScissorType tempScissor;
1148
// The coords are all in 8:2 fixed point
1149
tempScissor.x0 = ((gfx->words.w0)>>12)&0xFFF;
1150
tempScissor.y0 = ((gfx->words.w0)>>0 )&0xFFF;
1151
tempScissor.mode = ((gfx->words.w1)>>24)&0x03;
1152
tempScissor.x1 = ((gfx->words.w1)>>12)&0xFFF;
1153
tempScissor.y1 = ((gfx->words.w1)>>0 )&0xFFF;
1155
tempScissor.left = tempScissor.x0/4;
1156
tempScissor.top = tempScissor.y0/4;
1157
tempScissor.right = tempScissor.x1/4;
1158
tempScissor.bottom = tempScissor.y1/4;
1160
if( options.bEnableHacks )
1162
if( g_CI.dwWidth == 0x200 && tempScissor.right == 0x200 )
1164
uint32 width = *g_GraphicsInfo.VI_WIDTH_REG & 0xFFF;
1166
if( width != 0x200 )
1169
tempScissor.bottom = tempScissor.right*tempScissor.bottom/width;
1170
tempScissor.right = width;
1176
if( gRDP.scissor.left != tempScissor.left || gRDP.scissor.top != tempScissor.top ||
1177
gRDP.scissor.right != tempScissor.right || gRDP.scissor.bottom != tempScissor.bottom ||
1178
gRSP.real_clip_scissor_left != tempScissor.left || gRSP.real_clip_scissor_top != tempScissor.top ||
1179
gRSP.real_clip_scissor_right != tempScissor.right || gRSP.real_clip_scissor_bottom != tempScissor.bottom)
1181
memcpy(&(gRDP.scissor), &tempScissor, sizeof(ScissorType) );
1182
if( !status.bHandleN64RenderTexture )
1185
if( options.enableHackForGames == HACK_FOR_SUPER_BOWLING && g_CI.dwAddr%0x100 != 0 )
1187
// right half screen
1188
gRDP.scissor.left += 160;
1189
gRDP.scissor.right += 160;
1190
CRender::g_pRender->SetViewport(160, 0, 320, 240, 0xFFFF);
1193
CRender::g_pRender->UpdateClipRectangle();
1194
CRender::g_pRender->UpdateScissor();
1195
CRender::g_pRender->SetViewportRender();
1198
LOG_UCODE("SetScissor: x0=%d y0=%d x1=%d y1=%d mode=%d",
1199
gRDP.scissor.left, gRDP.scissor.top,
1200
gRDP.scissor.right, gRDP.scissor.bottom,
1203
///TXTRBUF_DETAIL_DUMP(DebuggerAppendMsg("SetScissor: x0=%d y0=%d x1=%d y1=%d mode=%d", gRDP.scissor.left, gRDP.scissor.top,
1204
//gRDP.scissor.right, gRDP.scissor.bottom, gRDP.scissor.mode););
1208
void DLParser_FillRect(Gfx *gfx)
1210
DP_Timing(DLParser_FillRect); // fix me
1211
status.primitiveType = PRIM_FILLRECT;
1213
if( status.bN64IsDrawingTextureBuffer && frameBufferOptions.bIgnore )
1218
if( options.enableHackForGames == HACK_FOR_MARIO_TENNIS )
1220
uint32 dwPC = gDlistStack[gDlistStackPointer].pc; // This points to the next instruction
1221
uint32 w2 = *(uint32 *)(g_pRDRAMu8 + dwPC);
1222
if( (w2>>24) == RDP_FILLRECT )
1224
// Mario Tennis, a lot of FillRect ucodes, skip all of them
1225
while( (w2>>24) == RDP_FILLRECT )
1228
w2 = *(uint32 *)(g_pRDRAMu8 + dwPC);
1231
gDlistStack[gDlistStackPointer].pc = dwPC;
1236
uint32 x0 = (((gfx->words.w1)>>12)&0xFFF)/4;
1237
uint32 y0 = (((gfx->words.w1)>>0 )&0xFFF)/4;
1238
uint32 x1 = (((gfx->words.w0)>>12)&0xFFF)/4;
1239
uint32 y1 = (((gfx->words.w0)>>0 )&0xFFF)/4;
1241
// Note, in some modes, the right/bottom lines aren't drawn
1243
LOG_UCODE(" (%d,%d) (%d,%d)", x0, y0, x1, y1);
1245
if( gRDP.otherMode.cycle_type >= CYCLE_TYPE_COPY )
1251
//TXTRBUF_DETAIL_DUMP(DebuggerAppendMsg("FillRect: X0=%d, Y0=%d, X1=%d, Y1=%d, Color=0x%08X", x0, y0, x1, y1, gRDP.originalFillColor););
1253
if( status.bHandleN64RenderTexture && options.enableHackForGames == HACK_FOR_BANJO_TOOIE )
1259
if (IsUsedAsDI(g_CI.dwAddr))
1261
// Clear the Z Buffer
1262
if( x0!=0 || y0!=0 || windowSetting.uViWidth-x1>1 || windowSetting.uViHeight-y1>1)
1264
if( options.enableHackForGames == HACK_FOR_GOLDEN_EYE )
1266
// GoldenEye is using double zbuffer
1267
if( g_CI.dwAddr == g_ZI.dwAddr )
1269
// The zbuffer is the upper screen
1270
COORDRECT rect={int(x0*windowSetting.fMultX),int(y0*windowSetting.fMultY),int(x1*windowSetting.fMultX),int(y1*windowSetting.fMultY)};
1271
CRender::g_pRender->ClearBuffer(false,true,rect); //Check me
1272
LOG_UCODE(" Clearing ZBuffer");
1276
// The zbuffer is the lower screen
1277
int h = (g_CI.dwAddr-g_ZI.dwAddr)/g_CI.dwWidth/2;
1278
COORDRECT rect={int(x0*windowSetting.fMultX),int((y0+h)*windowSetting.fMultY),int(x1*windowSetting.fMultX),int((y1+h)*windowSetting.fMultY)};
1279
CRender::g_pRender->ClearBuffer(false,true,rect); //Check me
1280
LOG_UCODE(" Clearing ZBuffer");
1285
COORDRECT rect={int(x0*windowSetting.fMultX),int(y0*windowSetting.fMultY),int(x1*windowSetting.fMultX),int(y1*windowSetting.fMultY)};
1286
CRender::g_pRender->ClearBuffer(false,true,rect); //Check me
1287
LOG_UCODE(" Clearing ZBuffer");
1292
CRender::g_pRender->ClearBuffer(false,true); //Check me
1293
LOG_UCODE(" Clearing ZBuffer");
1296
DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_FLUSH_TRI,{TRACE0("Pause after FillRect: ClearZbuffer\n");});
1297
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);
1298
DebuggerAppendMsg("Pause after ClearZbuffer: Color=%08X\n", gRDP.originalFillColor);});
1300
if( g_curRomInfo.bEmulateClear )
1302
// Emulating Clear, by write the memory in RDRAM
1303
uint16 color = (uint16)gRDP.originalFillColor;
1304
uint32 pitch = g_CI.dwWidth<<1;
1305
long base = (long) (g_pRDRAMu8 + g_CI.dwAddr);
1306
for( uint32 i =y0; i<y1; i++ )
1308
for( uint32 j=x0; j<x1; j++ )
1310
*(uint16*)((base+pitch*i+j)^2) = color;
1315
else if( status.bHandleN64RenderTexture )
1317
if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer();
1319
status.leftRendered = status.leftRendered<0 ? x0 : min((int)x0,status.leftRendered);
1320
status.topRendered = status.topRendered<0 ? y0 : min((int)y0,status.topRendered);
1321
status.rightRendered = status.rightRendered<0 ? x1 : max((int)x1,status.rightRendered);
1322
status.bottomRendered = status.bottomRendered<0 ? y1 : max((int)y1,status.bottomRendered);
1324
g_pRenderTextureInfo->maxUsedHeight = max(g_pRenderTextureInfo->maxUsedHeight,(int)y1);
1326
if( status.bDirectWriteIntoRDRAM || ( x0==0 && y0==0 && (x1 == g_pRenderTextureInfo->N64Width || x1 == g_pRenderTextureInfo->N64Width-1 ) ) )
1328
if( g_pRenderTextureInfo->CI_Info.dwSize == TXT_SIZE_16b )
1330
uint16 color = (uint16)gRDP.originalFillColor;
1331
uint32 pitch = g_pRenderTextureInfo->N64Width<<1;
1332
long base = (long) (g_pRDRAMu8 + g_pRenderTextureInfo->CI_Info.dwAddr);
1333
for( uint32 i =y0; i<y1; i++ )
1335
for( uint32 j=x0; j<x1; j++ )
1337
*(uint16*)((base+pitch*i+j)^2) = color;
1343
uint8 color = (uint8)gRDP.originalFillColor;
1344
uint32 pitch = g_pRenderTextureInfo->N64Width;
1345
long base = (long) (g_pRDRAMu8 + g_pRenderTextureInfo->CI_Info.dwAddr);
1346
for( uint32 i=y0; i<y1; i++ )
1348
for( uint32 j=x0; j<x1; j++ )
1350
*(uint8*)((base+pitch*i+j)^3) = color;
1355
status.bFrameBufferDrawnByTriangles = false;
1359
status.bFrameBufferDrawnByTriangles = true;
1361
status.bFrameBufferDrawnByTriangles = true;
1363
if( !status.bDirectWriteIntoRDRAM )
1365
status.bFrameBufferIsDrawn = true;
1367
//if( x0==0 && y0==0 && (x1 == g_pRenderTextureInfo->N64Width || x1 == g_pRenderTextureInfo->N64Width-1 ) && gRDP.fillColor == 0)
1369
// CRender::g_pRender->ClearBuffer(true,false);
1373
if( gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL )
1375
CRender::g_pRender->FillRect(x0, y0, x1, y1, gRDP.fillColor);
1379
COLOR primColor = GetPrimitiveColor();
1380
CRender::g_pRender->FillRect(x0, y0, x1, y1, primColor);
1385
DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_FLUSH_TRI,{TRACE0("Pause after FillRect\n");});
1386
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);
1387
DebuggerAppendMsg("Pause after FillRect: Color=%08X\n", gRDP.originalFillColor);});
1391
LOG_UCODE(" Filling Rectangle");
1392
if( frameBufferOptions.bSupportRenderTextures || frameBufferOptions.bCheckBackBufs )
1394
if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer();
1396
status.leftRendered = status.leftRendered<0 ? x0 : min((int)x0,status.leftRendered);
1397
status.topRendered = status.topRendered<0 ? y0 : min((int)y0,status.topRendered);
1398
status.rightRendered = status.rightRendered<0 ? x1 : max((int)x1,status.rightRendered);
1399
status.bottomRendered = status.bottomRendered<0 ? y1 : max((int)y1,status.bottomRendered);
1402
if( gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL )
1404
if( !status.bHandleN64RenderTexture || g_pRenderTextureInfo->CI_Info.dwSize == TXT_SIZE_16b )
1406
CRender::g_pRender->FillRect(x0, y0, x1, y1, gRDP.fillColor);
1411
COLOR primColor = GetPrimitiveColor();
1412
//if( RGBA_GETALPHA(primColor) != 0 )
1414
CRender::g_pRender->FillRect(x0, y0, x1, y1, primColor);
1417
DEBUGGER_PAUSE_AND_DUMP_COUNT_N( NEXT_FLUSH_TRI,{TRACE0("Pause after FillRect\n");});
1418
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);
1419
DebuggerAppendMsg("Pause after FillRect: Color=%08X\n", gRDP.originalFillColor);});
1424
#define STORE_CI {g_CI.dwAddr = dwNewAddr;g_CI.dwFormat = dwFmt;g_CI.dwSize = dwSiz;g_CI.dwWidth = dwWidth;g_CI.bpl=dwBpl;}
1426
void DLParser_SetCImg(Gfx *gfx)
1428
uint32 dwFmt = gfx->setimg.fmt;
1429
uint32 dwSiz = gfx->setimg.siz;
1430
uint32 dwWidth = gfx->setimg.width + 1;
1431
uint32 dwNewAddr = RSPSegmentAddr((gfx->setimg.addr)) & 0x00FFFFFF ;
1432
uint32 dwBpl = dwWidth << dwSiz >> 1;
1434
TXTRBUF_DETAIL_DUMP(DebuggerAppendMsg("SetCImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", dwNewAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth););
1436
if( dwFmt == TXT_FMT_YUV || dwFmt == TXT_FMT_IA )
1438
WARNING(TRACE4("Check me: SetCImg Addr=0x%08X, Fmt:%s-%sb, Width=%d\n",
1439
g_CI.dwAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth));
1442
LOG_UCODE(" Image: 0x%08x", RSPSegmentAddr(gfx->words.w1));
1443
LOG_UCODE(" Fmt: %s Size: %s Width: %d",
1444
pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth);
1446
if( g_CI.dwAddr == dwNewAddr && g_CI.dwFormat == dwFmt && g_CI.dwSize == dwSiz && g_CI.dwWidth == dwWidth )
1448
TXTRBUF_OR_CI_DETAIL_DUMP({
1449
TRACE0("Set CIMG to the same address, no change, skipped");
1450
DebuggerAppendMsg("Pause after SetCImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n",
1451
g_CI.dwAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth);
1456
if( status.bVIOriginIsUpdated == true && currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_AT_1ST_CI_CHANGE )
1458
status.bVIOriginIsUpdated=false;
1459
CGraphicsContext::Get()->UpdateFrame();
1460
TXTRBUF_OR_CI_DETAIL_DUMP(TRACE0("Screen Update at 1st CI change"););
1463
if( options.enableHackForGames == HACK_FOR_SUPER_BOWLING )
1465
if( dwNewAddr%0x100 == 0 )
1470
gRDP.scissor.left = 0;
1471
gRDP.scissor.right = 160;
1472
CRender::g_pRender->SetViewport(0, 0, 160, 240, 0xFFFF);
1473
CRender::g_pRender->UpdateClipRectangle();
1474
CRender::g_pRender->UpdateScissor();
1478
gRDP.scissor.left = 0;
1479
gRDP.scissor.right = 320;
1480
CRender::g_pRender->SetViewport(0, 0, 320, 240, 0xFFFF);
1481
CRender::g_pRender->UpdateClipRectangle();
1482
CRender::g_pRender->UpdateScissor();
1487
// right half screen
1488
gRDP.scissor.left = 160;
1489
gRDP.scissor.right = 320;
1490
gRSP.nVPLeftN = 160;
1491
gRSP.nVPRightN = 320;
1492
CRender::g_pRender->UpdateClipRectangle();
1493
CRender::g_pRender->UpdateScissor();
1494
CRender::g_pRender->SetViewport(160, 0, 320, 240, 0xFFFF);
1499
if( !frameBufferOptions.bUpdateCIInfo )
1502
status.bCIBufferIsRendered = false;
1503
status.bN64IsDrawingTextureBuffer = false;
1505
TXTRBUF_DUMP(TRACE4("SetCImg : Addr=0x%08X, Fmt:%s-%sb, Width=%d\n",
1506
g_CI.dwAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth));
1508
DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_SET_CIMG,
1510
DebuggerAppendMsg("Pause after SetCImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n",
1511
dwNewAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth);
1519
newCI.dwAddr = dwNewAddr;
1520
newCI.dwFormat = dwFmt;
1521
newCI.dwSize = dwSiz;
1522
newCI.dwWidth = dwWidth;
1524
g_pFrameBufferManager->Set_CI_addr(newCI);
1527
void DLParser_SetZImg(Gfx *gfx)
1529
DP_Timing(DLParser_SetZImg);
1530
LOG_UCODE(" Image: 0x%08x", RSPSegmentAddr(gfx->words.w1));
1532
uint32 dwFmt = gfx->setimg.fmt;
1533
uint32 dwSiz = gfx->setimg.siz;
1534
uint32 dwWidth = gfx->setimg.width + 1;
1535
uint32 dwAddr = RSPSegmentAddr((gfx->setimg.addr));
1537
if( dwAddr != g_ZI_saves[0].CI_Info.dwAddr )
1539
g_ZI_saves[1].CI_Info.dwAddr = g_ZI.dwAddr;
1540
g_ZI_saves[1].CI_Info.dwFormat = g_ZI.dwFormat;
1541
g_ZI_saves[1].CI_Info.dwSize = g_ZI.dwSize;
1542
g_ZI_saves[1].CI_Info.dwWidth = g_ZI.dwWidth;
1543
g_ZI_saves[1].updateAtFrame = g_ZI_saves[0].updateAtFrame;
1545
g_ZI_saves[0].CI_Info.dwAddr = g_ZI.dwAddr = dwAddr;
1546
g_ZI_saves[0].CI_Info.dwFormat = g_ZI.dwFormat = dwFmt;
1547
g_ZI_saves[0].CI_Info.dwSize = g_ZI.dwSize = dwSiz;
1548
g_ZI_saves[0].CI_Info.dwWidth = g_ZI.dwWidth = dwWidth;
1549
g_ZI_saves[0].updateAtFrame = status.gDlistCount;
1553
g_ZI.dwAddr = dwAddr;
1554
g_ZI.dwFormat = dwFmt;
1555
g_ZI.dwSize = dwSiz;
1556
g_ZI.dwWidth = dwWidth;
1559
DEBUGGER_IF_DUMP((pauseAtNext) ,
1560
{DebuggerAppendMsg("SetZImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n",
1561
g_ZI.dwAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth);}
1564
DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_SET_CIMG,
1566
DebuggerAppendMsg("Pause after SetZImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n",
1567
g_ZI.dwAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth);
1572
bool IsUsedAsDI(uint32 addr)
1574
if( addr == g_ZI_saves[0].CI_Info.dwAddr )
1576
else if( addr == g_ZI_saves[1].CI_Info.dwAddr && status.gDlistCount - g_ZI_saves[1].updateAtFrame < 10
1577
&& g_ZI_saves[1].CI_Info.dwAddr != 0 )
1583
void DLParser_SetCombine(Gfx *gfx)
1585
DP_Timing(DLParser_SetCombine);
1586
uint32 dwMux0 = (gfx->words.w0)&0x00FFFFFF;
1587
uint32 dwMux1 = (gfx->words.w1);
1588
CRender::g_pRender->SetMux(dwMux0, dwMux1);
1591
void DLParser_SetFillColor(Gfx *gfx)
1593
DP_Timing(DLParser_SetFillColor);
1594
gRDP.fillColor = Convert555ToRGBA(gfx->setcolor.fillcolor);
1595
gRDP.originalFillColor = (gfx->setcolor.color);
1597
LOG_UCODE(" Color5551=0x%04x = 0x%08x", (uint16)gfx->words.w1, gRDP.fillColor);
1601
void DLParser_SetFogColor(Gfx *gfx)
1603
DP_Timing(DLParser_SetFogColor);
1604
CRender::g_pRender->SetFogColor( gfx->setcolor.r, gfx->setcolor.g, gfx->setcolor.b, gfx->setcolor.a );
1605
FOG_DUMP(TRACE1("Set Fog color: %08X", gfx->setcolor.color));
1608
void DLParser_SetBlendColor(Gfx *gfx)
1610
DP_Timing(DLParser_SetBlendColor);
1611
CRender::g_pRender->SetAlphaRef(gfx->setcolor.a);
1615
void DLParser_SetPrimColor(Gfx *gfx)
1617
DP_Timing(DLParser_SetPrimColor);
1618
SetPrimitiveColor( COLOR_RGBA(gfx->setcolor.r, gfx->setcolor.g, gfx->setcolor.b, gfx->setcolor.a),
1619
gfx->setcolor.prim_min_level, gfx->setcolor.prim_level);
1622
void DLParser_SetEnvColor(Gfx *gfx)
1624
DP_Timing(DLParser_SetEnvColor);
1625
SetEnvColor( COLOR_RGBA(gfx->setcolor.r, gfx->setcolor.g, gfx->setcolor.b, gfx->setcolor.a) );
1629
void RDP_DLParser_Process(void)
1632
gettimeofday(&tv, 0);
1633
status.gRDPTime = tv.tv_usec;
1635
status.gDlistCount++;
1637
uint32 start = *(g_GraphicsInfo.DPC_START_REG);
1638
uint32 end = *(g_GraphicsInfo.DPC_END_REG);
1640
gDlistStackPointer=0;
1641
gDlistStack[gDlistStackPointer].pc = start;
1642
gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT;
1644
// Check if we need to purge
1645
if (status.gRDPTime - status.lastPurgeTimeTime > 5000)
1647
gTextureManager.PurgeOldTextures();
1648
status.lastPurgeTimeTime = status.gRDPTime;
1651
// Lock the graphics context here.
1652
CRender::g_pRender->SetFillMode(RICE_FILLMODE_SOLID);
1656
CRender::g_pRender->RenderReset();
1657
CRender::g_pRender->BeginRendering();
1658
CRender::g_pRender->SetViewport(0, 0, windowSetting.uViWidth, windowSetting.uViHeight, 0x3FF);
1660
while( gDlistStack[gDlistStackPointer].pc < end )
1662
Gfx *pgfx = (Gfx*)&g_pRDRAMu32[(gDlistStack[gDlistStackPointer].pc>>2)];
1663
gDlistStack[gDlistStackPointer].pc += 8;
1664
currentUcodeMap[pgfx->words.w0 >>24](pgfx);
1667
CRender::g_pRender->EndRendering();
1670
void RDP_TriFill(Gfx *gfx)
1674
void RDP_TriFillZ(Gfx *gfx)
1678
void RDP_TriTxtr(Gfx *gfx)
1682
void RDP_TriTxtrZ(Gfx *gfx)
1686
void RDP_TriShade(Gfx *gfx)
1690
void RDP_TriShadeZ(Gfx *gfx)
1694
void RDP_TriShadeTxtr(Gfx *gfx)
1698
void RDP_TriShadeTxtrZ(Gfx *gfx)
1702
static int crc_table_empty = 1;
1703
static ULONG crc_table[256];
1704
static void make_crc_table(void);
1706
static void make_crc_table()
1710
ULONG poly; /* polynomial exclusive-or pattern */
1711
/* terms of polynomial defining this crc (except x^32): */
1712
static const uint8 p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
1714
/* make exclusive-or pattern from polynomial (0xedb88320L) */
1716
for (n = 0; (unsigned int)n < sizeof(p)/sizeof(uint8); n++)
1717
poly |= 1L << (31 - p[n]);
1719
for (n = 0; n < 256; n++)
1722
for (k = 0; k < 8; k++)
1723
c = (c & 1) ? (poly ^ (c >> 1)) : c >> 1;
1726
crc_table_empty = 0;
1729
/* ========================================================================= */
1730
#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
1731
#define DO2(buf) DO1(buf); DO1(buf);
1732
#define DO4(buf) DO2(buf); DO2(buf);
1733
#define DO8(buf) DO4(buf); DO4(buf);
1735
/* ========================================================================= */
1736
ULONG ComputeCRC32(ULONG crc, const uint8 *buf, UINT len)
1738
if (buf == NULL) return 0L;
1740
if (crc_table_empty)
1743
crc = crc ^ 0xffffffffL;
1752
return crc ^ 0xffffffffL;
1756
void LoadMatrix(uint32 addr)
1758
const float fRecip = 1.0f / 65536.0f;
1759
if (addr + 64 > g_dwRamSize)
1761
TRACE1("Mtx: Address invalid (0x%08x)", addr);
1767
for (i = 0; i < 4; i++)
1769
for (j = 0; j < 4; j++)
1771
int hi = *(short *)(g_pRDRAMu8 + ((addr+(i<<3)+(j<<1) )^0x2));
1772
int lo = *(unsigned short *)(g_pRDRAMu8 + ((addr+(i<<3)+(j<<1) + 32)^0x2));
1773
matToLoad.m[i][j] = (float)((hi<<16) | lo) * fRecip;
1780
" %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n"
1781
" %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n"
1782
" %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n"
1783
" %#+12.5f %#+12.5f %#+12.5f %#+12.5f\r\n",
1784
matToLoad.m[0][0], matToLoad.m[0][1], matToLoad.m[0][2], matToLoad.m[0][3],
1785
matToLoad.m[1][0], matToLoad.m[1][1], matToLoad.m[1][2], matToLoad.m[1][3],
1786
matToLoad.m[2][0], matToLoad.m[2][1], matToLoad.m[2][2], matToLoad.m[2][3],
1787
matToLoad.m[3][0], matToLoad.m[3][1], matToLoad.m[3][2], matToLoad.m[3][3]);