~ubuntu-branches/ubuntu/precise/mupen64plus/precise

« back to all changes in this revision

Viewing changes to rice_video/RSP_Parser.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Sven Eckelmann
  • Date: 2009-09-08 22:17:00 UTC
  • Revision ID: james.westby@ubuntu.com-20090908221700-yela0ckgc1xwiqtn
Tags: upstream-1.5+dfsg1
ImportĀ upstreamĀ versionĀ 1.5+dfsg1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "stdafx.h"
 
21
#include "ucode.h"
 
22
#include <sys/time.h>
 
23
 
 
24
//////////////////////////////////////////////////////////
 
25
//////////////////////////////////////////////////////////
 
26
//                    uCode Config                      //
 
27
//////////////////////////////////////////////////////////
 
28
//////////////////////////////////////////////////////////
 
29
#define MAX_UCODE_INFO  16
 
30
UcodeInfo ucodeInfo[MAX_UCODE_INFO];
 
31
 
 
32
RDPInstruction LoadedUcodeMap[256];
 
33
char* LoadedUcodeNameMap[256];
 
34
 
 
35
OSTask *g_pOSTask = NULL;
 
36
UcodeInfo lastUcodeInfo;
 
37
UcodeInfo UsedUcodes[MAX_UCODE_INFO];
 
38
const uint32 maxUsedUcodes = sizeof(UsedUcodes)/sizeof(UcodeInfo);
 
39
 
 
40
//////////////////////////////////////////////////////////
 
41
//////////////////////////////////////////////////////////
 
42
//                     Ucodes                           //
 
43
//////////////////////////////////////////////////////////
 
44
//////////////////////////////////////////////////////////
 
45
 
 
46
UcodeMap *ucodeMaps[] = 
 
47
{
 
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
 
69
};
 
70
 
 
71
uint32 vertexMultVals[] =
 
72
{
 
73
    10, // ucode 0 - Mario
 
74
    2,  // ucode 1 - GBI1
 
75
    10, // ucode 2 - Golden Eye
 
76
    2,  // ucode 3 - S2DEX GBI2
 
77
    5,  // ucode 4 - Wave Racer
 
78
    2,  // ucode 5 - BGI2
 
79
    10, // ucode 6 - DKR
 
80
    2,  // ucode 7 - S2DEX
 
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
 
90
 
 
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
 
95
};
 
96
 
 
97
CHAR gLastMicrocodeString[ 300 ] = "";
 
98
 
 
99
//*****************************************************************************
 
100
//
 
101
//*****************************************************************************
 
102
static UcodeData g_UcodeData[] = 
 
103
{
 
104
    //crc_size, crc_800;
 
105
 
 
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 
 
129
 
 
130
    // GBI1
 
131
    
 
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},
 
144
 
 
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 
 
157
 
 
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
 
161
 
 
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}, 
 
181
 
 
182
    {5, 0x3e083afa, 0x882680f4, (CHAR*)"RSP Gfx ucode L3DEX       fifo 2.07  Yoshitaka Yasumoto 1998 Nintendo."},   // Polaris Sno
 
183
 
 
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}, 
 
193
 
 
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, 
 
201
 
 
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, 
 
208
 
 
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), 
 
211
 
 
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, 
 
215
 
 
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, 
 
221
 
 
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
 
227
 
 
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
 
230
 
 
231
    {20, 0x6d2a01b1, 0x6d2a01b1, (CHAR*)"RSP Gfx ucode ZSortp 0.33 Yoshitaka Yasumoto Nintendo.",}, // Mia Hamm Soccer 64, 
 
232
};
 
233
 
 
234
FiddledVtx * g_pVtxBase=NULL;
 
235
 
 
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];
 
240
 
 
241
DListStack  gDlistStack[MAX_DL_STACK_SIZE];
 
242
int     gDlistStackPointer= -1;
 
243
 
 
244
TMEMLoadMapInfo g_tmemLoadAddrMap[0x200];   // Totally 4KB TMEM
 
245
TMEMLoadMapInfo g_tmemInfo0;                // Info for Tmem=0
 
246
TMEMLoadMapInfo g_tmemInfo1;                // Info for Tmem=0x100
 
247
 
 
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];
 
252
 
 
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"
 
261
 
 
262
//////////////////////////////////////////////////////////
 
263
//////////////////////////////////////////////////////////
 
264
//                  Init and Reset                      //
 
265
//////////////////////////////////////////////////////////
 
266
//////////////////////////////////////////////////////////
 
267
 
 
268
void DLParser_Init()
 
269
{
 
270
    int i;
 
271
 
 
272
    status.gRDPTime = 0;
 
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;
 
282
 
 
283
    status.bUcodeIsKnown = FALSE;
 
284
    status.lastPurgeTimeTime = status.gRDPTime;
 
285
 
 
286
    status.curRenderBuffer = 0;
 
287
    status.curDisplayBuffer = 0;
 
288
    status.curVIOriginReg = 0;
 
289
 
 
290
    status.primitiveType = PRIM_TRI1;
 
291
 
 
292
    status.lastPurgeTimeTime = 0;       // Time textures were last purged
 
293
 
 
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);
 
297
 
 
298
    for( i=0; i<8; i++ )
 
299
    {
 
300
        memset(&gRDP.tiles[i], 0, sizeof(Tile));
 
301
    }
 
302
    memset(g_tmemLoadAddrMap, 0, sizeof(g_tmemLoadAddrMap));
 
303
 
 
304
    for( i=0; i<MAX_UCODE_INFO; i++ )
 
305
    {
 
306
        memset(&ucodeInfo[i], 0, sizeof(UcodeInfo));
 
307
    }
 
308
 
 
309
    status.bUseModifiedUcodeMap = false;
 
310
    status.ucodeHasBeenSet = false;
 
311
    status.bAllowLoadFromTMEM = true;
 
312
    
 
313
    char name[200];
 
314
    strcpy(name, (char*)g_curRomInfo.szGameName);
 
315
 
 
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));
 
325
 
 
326
    status.UseLargerTile[0] = status.UseLargerTile[1] = false;
 
327
    status.LargerTileRealLeft[0] = status.LargerTileRealLeft[1] = 0;
 
328
}
 
329
 
 
330
 
 
331
void RDP_GFX_Reset()
 
332
{
 
333
    gDlistStackPointer=-1;
 
334
    status.bUcodeIsKnown = FALSE;
 
335
    gTextureManager.RecycleAllTextures();
 
336
}
 
337
 
 
338
 
 
339
void RDP_Cleanup()
 
340
{
 
341
    if( status.bHandleN64RenderTexture )
 
342
    {
 
343
        g_pFrameBufferManager->CloseRenderTexture(false);
 
344
    }
 
345
}
 
346
 
 
347
void RDP_SetUcodeMap(int ucode)
 
348
{
 
349
    status.bUseModifiedUcodeMap = false;
 
350
    switch( ucode )
 
351
    {
 
352
    case 0: // Mario and demos
 
353
        break;
 
354
    case 1: // F3DEX GBI1
 
355
    case 20:
 
356
        break;
 
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;
 
364
        break;
 
365
    case 3: // S2DEX GBI2
 
366
        break;
 
367
    case 4:
 
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;
 
376
        break;
 
377
    case 5: // F3DEX GBI2
 
378
        break;
 
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;
 
393
        break;
 
394
    case 7: // S2DEX GBI1
 
395
        break;
 
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;
 
402
        break;
 
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;
 
410
        break;
 
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;
 
433
        break;
 
434
    case 12: // Silicon Velley, Space Station
 
435
        memcpy( &LoadedUcodeMap, &ucodeMap1, sizeof(UcodeMap));
 
436
        LoadedUcodeMap[0x01]=RSP_GBI0_Mtx;
 
437
        status.bUseModifiedUcodeMap = true;
 
438
        break;
 
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;
 
448
        break;
 
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;
 
454
        break;
 
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;
 
461
        break;
 
462
    case 16: // Star War, Shadow Of Empire
 
463
        memcpy( &LoadedUcodeMap, &ucodeMap0, sizeof(UcodeMap));
 
464
        LoadedUcodeMap[4]=RSP_Vtx_ShadowOfEmpire;
 
465
        status.bUseModifiedUcodeMap = true;
 
466
        break;
 
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;
 
491
        break;
 
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;
 
499
        break;
 
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;
 
506
        break;
 
507
    default:
 
508
        memcpy( &LoadedUcodeMap, &ucodeMap5, sizeof(UcodeMap));
 
509
        status.bUseModifiedUcodeMap = true;
 
510
        break;
 
511
    }
 
512
 
 
513
#ifdef _DEBUG
 
514
    if( logMicrocode )
 
515
        TRACE1("Using ucode %d", ucode);
 
516
#endif
 
517
}
 
518
 
 
519
void RSP_SetUcode(int ucode, uint32 ucStart, uint32 ucDStart, uint32 ucSize)
 
520
{
 
521
    if( status.ucodeHasBeenSet && gRSP.ucode == ucode )
 
522
        return;
 
523
 
 
524
    status.ucodeHasBeenSet = true;
 
525
 
 
526
    if( ucode < 0 )
 
527
        ucode = 5;
 
528
 
 
529
    RDP_SetUcodeMap(ucode);
 
530
    if( status.bUseModifiedUcodeMap )
 
531
    {
 
532
        currentUcodeMap = &LoadedUcodeMap[0];
 
533
    }
 
534
    else
 
535
    {
 
536
        currentUcodeMap = *ucodeMaps[ucode];
 
537
    }
 
538
 
 
539
    gRSP.vertexMult = vertexMultVals[ucode];
 
540
 
 
541
    //if( gRSP.ucode != ucode ) DebuggerAppendMsg("Set to ucode: %d", ucode);
 
542
    gRSP.ucode = ucode;
 
543
 
 
544
    lastUcodeInfo.used = true;
 
545
    if( ucStart == 0 )
 
546
    {
 
547
        lastUcodeInfo.ucStart = g_pOSTask->t.ucode;
 
548
        lastUcodeInfo.ucDStart = g_pOSTask->t.ucode_data;
 
549
        lastUcodeInfo.ucSize = g_pOSTask->t.ucode_size;
 
550
    }
 
551
    else
 
552
    {
 
553
        lastUcodeInfo.ucStart = ucStart;
 
554
        lastUcodeInfo.ucDStart = ucDStart;
 
555
        lastUcodeInfo.ucSize = ucSize;
 
556
    }
 
557
}
 
558
 
 
559
//*****************************************************************************
 
560
//
 
561
//*****************************************************************************
 
562
static uint32 DLParser_IdentifyUcodeFromString( const CHAR * str_ucode )
 
563
{
 
564
    const CHAR str_ucode0[] = "RSP SW Version: 2.0";
 
565
    const CHAR str_ucode1[] = "RSP Gfx ucode ";
 
566
 
 
567
    if ( strncasecmp( (char*)str_ucode, (char*)str_ucode0, strlen((char*)str_ucode0) ) == 0 )
 
568
    {
 
569
        return 0;
 
570
    }
 
571
 
 
572
    if ( strncasecmp( (char*)str_ucode, (char*)str_ucode1, strlen((char*)str_ucode1) ) == 0 )
 
573
    {
 
574
        if( strstr((char*)str_ucode,"1.") != 0 )
 
575
        {
 
576
            if( strstr((char*)str_ucode,"S2DEX") != 0 )
 
577
            {
 
578
                return 7;
 
579
            }
 
580
            else
 
581
                return 1;
 
582
        }
 
583
        else if( strstr((char*)str_ucode,"2.") != 0 )
 
584
        {
 
585
            if( strstr((char*)str_ucode,"S2DEX") != 0 )
 
586
            {
 
587
                return 3;
 
588
            }
 
589
            else
 
590
                return 5;
 
591
        }
 
592
    }
 
593
 
 
594
    return 5;
 
595
}
 
596
 
 
597
//*****************************************************************************
 
598
//
 
599
//*****************************************************************************
 
600
static uint32 DLParser_IdentifyUcode( uint32 crc_size, uint32 crc_800, char* str )
 
601
{
 
602
    for ( uint32 i = 0; i < sizeof(g_UcodeData)/sizeof(UcodeData); i++ )
 
603
    {
 
604
#ifdef _DEBUG
 
605
        if ( crc_800 == g_UcodeData[i].crc_800 )
 
606
        {
 
607
            if( strlen(str)==0 || strcmp((const char *) g_UcodeData[i].ucode_name, str) == 0 ) 
 
608
            {
 
609
                TRACE0((const char *) g_UcodeData[i].ucode_name);
 
610
            }
 
611
            else
 
612
            {
 
613
                DebuggerAppendMsg("Incorrect description for this ucode:\n%x, %x, %s",crc_800, crc_size, str);
 
614
            }
 
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;
 
620
        }
 
621
#else
 
622
        if ( crc_800 == g_UcodeData[i].crc_800 )
 
623
        {
 
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;
 
628
        }
 
629
#endif
 
630
    }
 
631
 
 
632
#ifdef _DEBUG
 
633
    {
 
634
        static bool warned = false;
 
635
        if( warned == false )
 
636
        {
 
637
            warned = true;
 
638
            TRACE0("Can not identify ucode for this game");
 
639
        }
 
640
    }
 
641
#endif
 
642
    gRSP.bNearClip = false;
 
643
    gRSP.bRejectVtx = false;
 
644
    status.bUcodeIsKnown = FALSE;
 
645
    return ~0;
 
646
}
 
647
 
 
648
uint32 DLParser_CheckUcode(uint32 ucStart, uint32 ucDStart, uint32 ucSize, uint32 ucDSize)
 
649
{
 
650
    if( options.enableHackForGames == HACK_FOR_ROGUE_SQUADRON )
 
651
    {
 
652
        return 17;
 
653
    }
 
654
 
 
655
    // Check the used ucode table first
 
656
    int usedUcodeIndex = 0;
 
657
    for( usedUcodeIndex=0; (unsigned int)usedUcodeIndex<maxUsedUcodes; usedUcodeIndex++ )
 
658
    {
 
659
        if( UsedUcodes[usedUcodeIndex].used == false )
 
660
        {
 
661
            break;
 
662
        }
 
663
 
 
664
        if( UsedUcodes[usedUcodeIndex].ucStart == ucStart && UsedUcodes[usedUcodeIndex].ucSize == ucSize &&
 
665
            UsedUcodes[usedUcodeIndex].ucDStart == ucDStart /*&& UsedUcodes[usedUcodeIndex].ucDSize == ucDSize*/ )
 
666
        {
 
667
#ifdef _DEBUG
 
668
            if(gRSP.ucode != (int)UsedUcodes[usedUcodeIndex].ucode && logMicrocode)
 
669
            {
 
670
                DebuggerAppendMsg("Check, ucode = %d, crc = %08X, %s", UsedUcodes[usedUcodeIndex].ucode, 
 
671
                    UsedUcodes[usedUcodeIndex].crc_800 , UsedUcodes[usedUcodeIndex].rspstr);
 
672
            }
 
673
#endif
 
674
            lastUcodeInfo.ucStart = ucStart;
 
675
            lastUcodeInfo.used = true;
 
676
            lastUcodeInfo.ucDStart = ucDStart;
 
677
            lastUcodeInfo.ucSize = ucSize;
 
678
            return UsedUcodes[usedUcodeIndex].ucode;
 
679
        }
 
680
    }
 
681
 
 
682
    uint32 base = ucDStart & 0x1fffffff;
 
683
    CHAR str[300] = "";
 
684
    if( base < g_dwRamSize+0x1000 )
 
685
    {
 
686
        for ( uint32 i = 0; i < 0x1000; i++ )
 
687
        {
 
688
 
 
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' )
 
692
            {
 
693
                CHAR * p = str;
 
694
                while ( g_pRDRAMs8[ base + (i ^ 3) ] >= ' ')
 
695
                {
 
696
                    *p++ = g_pRDRAMs8[ base + (i ^ 3) ];
 
697
                    i++;
 
698
                }
 
699
                *p++ = 0;
 
700
                break;
 
701
            }
 
702
        }
 
703
    }
 
704
 
 
705
    //if ( strcmp( str, gLastMicrocodeString ) != 0 )
 
706
    {
 
707
        //uint32 size = ucDSize;
 
708
        base = ucStart & 0x1fffffff;
 
709
 
 
710
        uint32 crc_size = ComputeCRC32( 0, &g_pRDRAMu8[ base ], 8);//size );
 
711
        uint32 crc_800 = ComputeCRC32( 0, &g_pRDRAMu8[ base ], 0x800 );
 
712
        uint32 ucode;
 
713
        ucode = DLParser_IdentifyUcode( crc_size, crc_800, (char*)str );
 
714
        if ( (int)ucode == ~0 )
 
715
        {
 
716
#ifdef _DEBUG
 
717
            static bool warned=false;
 
718
            //if( warned == false )
 
719
            {
 
720
                char message[300];
 
721
 
 
722
                sprintf(message, "Unable to find ucode to use for\n\n"
 
723
                                  "%s\n"
 
724
                                  "CRCSize: 0x%08x\n\n"
 
725
                                  "CRC800: 0x%08x\n"
 
726
                                  "Please mail rice1964@yahoo.com with the contents of c:\\ucodes.txt",
 
727
                        str, crc_size, crc_800);
 
728
                TRACE0(message);
 
729
                ErrorMsg(message);
 
730
                warned = true;
 
731
            }
 
732
#endif
 
733
            ucode = DLParser_IdentifyUcodeFromString(str);
 
734
            if ( (int)ucode == ~0 )
 
735
            {
 
736
                ucode=5;
 
737
            }
 
738
        }
 
739
 
 
740
        //DLParser_SetuCode( ucode );
 
741
        
 
742
#ifdef _DEBUG
 
743
        {
 
744
            static bool warned=false;
 
745
            if( warned == false )
 
746
            {
 
747
                warned = true;
 
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);
 
750
                else
 
751
                    TRACE0((char *) str);
 
752
            }
 
753
        }
 
754
#endif
 
755
        strcpy( (char*)gLastMicrocodeString, (char*)str );
 
756
 
 
757
        if( usedUcodeIndex >= MAX_UCODE_INFO )
 
758
        {
 
759
            usedUcodeIndex = rand()%MAX_UCODE_INFO;
 
760
        }
 
761
 
 
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 );
 
771
 
 
772
        TRACE2("New ucode has been detected:\n%s, ucode=%d", str, ucode);
 
773
    
 
774
        return ucode;
 
775
    }
 
776
}
 
777
 
 
778
extern int dlistMtxCount;
 
779
extern bool bHalfTxtScale;
 
780
 
 
781
void DLParser_Process(OSTask * pTask)
 
782
{
 
783
    static int skipframe=0;
 
784
    //BOOL menuWaiting = FALSE;
 
785
 
 
786
    dlistMtxCount = 0;
 
787
    bHalfTxtScale = false;
 
788
 
 
789
    if ( CRender::g_pRender == NULL)
 
790
    {
 
791
        TriggerDPInterrupt();
 
792
        TriggerSPInterrupt();
 
793
        return;
 
794
    }
 
795
 
 
796
    status.bScreenIsDrawn = true;
 
797
    if( options.bSkipFrame )
 
798
    {
 
799
        skipframe++;
 
800
        if(skipframe%2)
 
801
        {
 
802
            TriggerDPInterrupt();
 
803
            TriggerSPInterrupt();
 
804
            return;
 
805
        }
 
806
    }
 
807
 
 
808
    if( currentRomOptions.N64RenderToTextureEmuType != TXT_BUF_NONE && defaultRomOptions.bSaveVRAM )
 
809
    {
 
810
        g_pFrameBufferManager->CheckRenderTextureCRCInRDRAM();
 
811
    }
 
812
 
 
813
    g_pOSTask = pTask;
 
814
    
 
815
    DebuggerPauseCountN( NEXT_DLIST );
 
816
    struct timeval tv;
 
817
    gettimeofday(&tv, 0);
 
818
    status.gRDPTime = tv.tv_usec;
 
819
 
 
820
    status.gDlistCount++;
 
821
 
 
822
    if ( lastUcodeInfo.ucStart != (uint32)(pTask->t.ucode) )
 
823
    {
 
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");});
 
827
    }
 
828
 
 
829
    // Initialize stack
 
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);});
 
836
 
 
837
 
 
838
    // Check if we need to purge
 
839
    if (status.gRDPTime - status.lastPurgeTimeTime > 5000)
 
840
    {
 
841
        gTextureManager.PurgeOldTextures();
 
842
        status.lastPurgeTimeTime = status.gRDPTime;
 
843
    }
 
844
 
 
845
    status.dwNumDListsCulled = 0;
 
846
    status.dwNumTrisRendered = 0;
 
847
    status.dwNumTrisClipped = 0;
 
848
    status.dwNumVertices = 0;
 
849
    status.dwBiggestVertexIndex = 0;
 
850
 
 
851
    if( g_curRomInfo.bForceScreenClear && CGraphicsContext::needCleanScene )
 
852
    {
 
853
        CRender::g_pRender->ClearBuffer(true,true);
 
854
        CGraphicsContext::needCleanScene = false;
 
855
    }
 
856
 
 
857
    SetVIScales();
 
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);
 
862
 
 
863
    try
 
864
    {
 
865
        // The main loop
 
866
        while( gDlistStackPointer >= 0 )
 
867
        {
 
868
#ifdef _DEBUG
 
869
            DEBUGGER_PAUSE_COUNT_N(NEXT_UCODE);
 
870
            if( debuggerPause )
 
871
            {
 
872
                DebuggerPause();
 
873
                CRender::g_pRender->SetFillMode(options.bWinFrameMode? RICE_FILLMODE_WINFRAME : RICE_FILLMODE_SOLID);
 
874
            }
 
875
 
 
876
            if (gDlistStack[gDlistStackPointer].pc > g_dwRamSize)
 
877
            {
 
878
                DebuggerAppendMsg("Error: dwPC is %08X", gDlistStack[gDlistStackPointer].pc );
 
879
                break;
 
880
            }
 
881
#endif
 
882
 
 
883
            status.gUcodeCount++;
 
884
 
 
885
            Gfx *pgfx = (Gfx*)&g_pRDRAMu32[(gDlistStack[gDlistStackPointer].pc>>2)];
 
886
#ifdef _DEBUG
 
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)]);
 
889
#endif
 
890
            gDlistStack[gDlistStackPointer].pc += 8;
 
891
            currentUcodeMap[pgfx->words.w0 >>24](pgfx);
 
892
 
 
893
            if ( gDlistStackPointer >= 0 && --gDlistStack[gDlistStackPointer].countdown < 0 )
 
894
            {
 
895
                LOG_UCODE("**EndDLInMem");
 
896
                gDlistStackPointer--;
 
897
            }
 
898
        }
 
899
 
 
900
    }
 
901
    catch(...)
 
902
    {
 
903
        TRACE0("Unknown exception happens in ProcessDList");
 
904
        TriggerDPInterrupt();
 
905
    }
 
906
 
 
907
    CRender::g_pRender->EndRendering();
 
908
 
 
909
    if( gRSP.ucode >= 17)
 
910
        TriggerDPInterrupt();
 
911
    TriggerSPInterrupt();
 
912
}
 
913
 
 
914
//////////////////////////////////////////////////////////
 
915
//////////////////////////////////////////////////////////
 
916
//                   Util Functions                     //
 
917
//////////////////////////////////////////////////////////
 
918
//////////////////////////////////////////////////////////
 
919
 
 
920
void RDP_NOIMPL_Real(const char* op, uint32 word0, uint32 word1) 
 
921
{
 
922
#ifdef _DEBUG
 
923
    if( logWarning )
 
924
    {
 
925
        TRACE0("Stack Trace");
 
926
        for( int i=0; i<gDlistStackPointer; i++ )
 
927
        {
 
928
            DebuggerAppendMsg("  %08X", gDlistStack[i].pc);
 
929
        }
 
930
        uint32 dwPC = gDlistStack[gDlistStackPointer].pc-8;
 
931
        DebuggerAppendMsg("PC=%08X",dwPC);
 
932
        DebuggerAppendMsg(op, word0, word1);
 
933
    }
 
934
    DEBUGGER_PAUSE_AND_DUMP_COUNT_N(NEXT_UNKNOWN_OP, {TRACE0("Paused at unimplemented ucode\n");})
 
935
#endif
 
936
}
 
937
 
 
938
void RDP_NOIMPL_WARN(const char* op)
 
939
{
 
940
#ifdef _DEBUG
 
941
    if(logWarning)
 
942
    {
 
943
        TRACE0(op);
 
944
    }
 
945
#endif
 
946
}
 
947
 
 
948
 
 
949
void RSP_GBI1_Noop(Gfx *gfx)
 
950
{
 
951
}
 
952
 
 
953
 
 
954
void RDP_GFX_PopDL()
 
955
{
 
956
    LOG_UCODE("Returning from DisplayList: level=%d", gDlistStackPointer+1);
 
957
    LOG_UCODE("############################################");
 
958
    LOG_UCODE("/\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\ /\\");
 
959
    LOG_UCODE("");
 
960
 
 
961
    gDlistStackPointer--;
 
962
}
 
963
 
 
964
uint32 CalcalateCRC(uint32* srcPtr, uint32 srcSize)
 
965
{
 
966
    uint32 crc=0;
 
967
    for( uint32 i=0; i<srcSize; i++ )
 
968
    {
 
969
        crc += srcPtr[i];
 
970
    }
 
971
    return crc;
 
972
}
 
973
 
 
974
 
 
975
void RSP_GFX_InitGeometryMode()
 
976
{
 
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
 
980
    {
 
981
        bCullFront = false;
 
982
    }
 
983
    CRender::g_pRender->SetCullMode(bCullFront, bCullBack);
 
984
    
 
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 );
 
989
    
 
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 );
 
994
}
 
995
 
 
996
//////////////////////////////////////////////////////////
 
997
//////////////////////////////////////////////////////////
 
998
//                   DP Ucodes                          //
 
999
//////////////////////////////////////////////////////////
 
1000
//////////////////////////////////////////////////////////
 
1001
 
 
1002
void DLParser_SetKeyGB(Gfx *gfx)
 
1003
{
 
1004
    DP_Timing(DLParser_SetKeyGB);
 
1005
 
 
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;
 
1010
}
 
1011
void DLParser_SetKeyR(Gfx *gfx)
 
1012
{
 
1013
    DP_Timing(DLParser_SetKeyR);
 
1014
 
 
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;
 
1018
}
 
1019
 
 
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)
 
1023
{
 
1024
    DP_Timing(DLParser_SetConvert);
 
1025
 
 
1026
    int temp;
 
1027
 
 
1028
    temp = ((gfx->words.w0)>>13)&0x1FF;
 
1029
    g_convk0 = temp>0xFF ? -(temp-0x100) : temp;
 
1030
 
 
1031
    temp = ((gfx->words.w0)>>4)&0x1FF;
 
1032
    g_convk1 = temp>0xFF ? -(temp-0x100) : temp;
 
1033
 
 
1034
    temp = (gfx->words.w0)&0xF;
 
1035
    temp = (temp<<5)|(((gfx->words.w1)>>27)&0x1F);
 
1036
    g_convk2 = temp>0xFF ? -(temp-0x100) : temp;
 
1037
 
 
1038
    temp = ((gfx->words.w1)>>18)&0x1FF;
 
1039
    g_convk3 = temp>0xFF ? -(temp-0x100) : temp;
 
1040
 
 
1041
    temp = ((gfx->words.w1)>>9)&0x1FF;
 
1042
    g_convk4 = temp>0xFF ? -(temp-0x100) : temp;
 
1043
 
 
1044
    temp = (gfx->words.w1)&0x1FF;
 
1045
    g_convk5 = temp>0xFF ? -(temp-0x100) : temp;
 
1046
 
 
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;
 
1052
}
 
1053
void DLParser_SetPrimDepth(Gfx *gfx)
 
1054
{
 
1055
    DP_Timing(DLParser_SetPrimDepth);
 
1056
    uint32 dwZ  = ((gfx->words.w1) >> 16) & 0xFFFF;
 
1057
    uint32 dwDZ = ((gfx->words.w1)      ) & 0xFFFF;
 
1058
 
 
1059
    LOG_UCODE("SetPrimDepth: 0x%08x 0x%08x - z: 0x%04x dz: 0x%04x",
 
1060
        gfx->words.w0, gfx->words.w1, dwZ, dwDZ);
 
1061
    
 
1062
    SetPrimitiveDepth(dwZ, dwDZ);
 
1063
    DEBUGGER_PAUSE(NEXT_SET_PRIM_COLOR);
 
1064
}
 
1065
 
 
1066
void DLParser_RDPSetOtherMode(Gfx *gfx)
 
1067
{
 
1068
    DP_Timing(DLParser_RDPSetOtherMode);
 
1069
    gRDP.otherMode._u32[1] = (gfx->words.w0);   // High
 
1070
    gRDP.otherMode._u32[0] = (gfx->words.w1);   // Low
 
1071
 
 
1072
    if( gRDP.otherModeH != ((gfx->words.w0) & 0x0FFFFFFF) )
 
1073
    {
 
1074
        gRDP.otherModeH = ((gfx->words.w0) & 0x0FFFFFFF);
 
1075
 
 
1076
        uint32 dwTextFilt  = (gRDP.otherModeH>>RSP_SETOTHERMODE_SHIFT_TEXTFILT)&0x3;
 
1077
        CRender::g_pRender->SetTextureFilter(dwTextFilt<<RSP_SETOTHERMODE_SHIFT_TEXTFILT);
 
1078
    }
 
1079
 
 
1080
    if( gRDP.otherModeL != (gfx->words.w1) )
 
1081
    {
 
1082
        if( (gRDP.otherModeL&ZMODE_DEC) != ((gfx->words.w1)&ZMODE_DEC) )
 
1083
        {
 
1084
            if( ((gfx->words.w1)&ZMODE_DEC) == ZMODE_DEC )
 
1085
                CRender::g_pRender->SetZBias( 2 );
 
1086
            else
 
1087
                CRender::g_pRender->SetZBias( 0 );
 
1088
        }
 
1089
 
 
1090
        gRDP.otherModeL = (gfx->words.w1);
 
1091
 
 
1092
        BOOL bZCompare      = (gRDP.otherModeL & Z_COMPARE)         ? TRUE : FALSE;
 
1093
        BOOL bZUpdate       = (gRDP.otherModeL & Z_UPDATE)          ? TRUE : FALSE;
 
1094
 
 
1095
        CRender::g_pRender->SetZCompare( bZCompare );
 
1096
        CRender::g_pRender->SetZUpdate( bZUpdate );
 
1097
 
 
1098
        uint32 dwAlphaTestMode = (gRDP.otherModeL >> RSP_SETOTHERMODE_SHIFT_ALPHACOMPARE) & 0x3;
 
1099
 
 
1100
        if ((dwAlphaTestMode) != 0)
 
1101
            CRender::g_pRender->SetAlphaTestEnable( TRUE );
 
1102
        else
 
1103
            CRender::g_pRender->SetAlphaTestEnable( FALSE );
 
1104
    }
 
1105
 
 
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 )
 
1109
    {
 
1110
        gRDP.bFogEnableInBlender = true;
 
1111
    }
 
1112
    else
 
1113
    {
 
1114
        gRDP.bFogEnableInBlender = false;
 
1115
    }
 
1116
}
 
1117
 
 
1118
 
 
1119
 
 
1120
void DLParser_RDPLoadSync(Gfx *gfx) 
 
1121
 
1122
    DP_Timing(DLParser_RDPLoadSync);
 
1123
    LOG_UCODE("LoadSync: (Ignored)"); 
 
1124
}
 
1125
 
 
1126
void DLParser_RDPPipeSync(Gfx *gfx) 
 
1127
 
1128
    DP_Timing(DLParser_RDPPipeSync);
 
1129
    LOG_UCODE("PipeSync: (Ignored)"); 
 
1130
}
 
1131
void DLParser_RDPTileSync(Gfx *gfx) 
 
1132
 
1133
    DP_Timing(DLParser_RDPTileSync);
 
1134
    LOG_UCODE("TileSync: (Ignored)"); 
 
1135
}
 
1136
 
 
1137
void DLParser_RDPFullSync(Gfx *gfx)
 
1138
 
1139
    DP_Timing(DLParser_RDPFullSync);
 
1140
    TriggerDPInterrupt();
 
1141
}
 
1142
 
 
1143
void DLParser_SetScissor(Gfx *gfx)
 
1144
{
 
1145
    DP_Timing(DLParser_SetScissor);
 
1146
 
 
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;
 
1154
 
 
1155
    tempScissor.left    = tempScissor.x0/4;
 
1156
    tempScissor.top     = tempScissor.y0/4;
 
1157
    tempScissor.right   = tempScissor.x1/4;
 
1158
    tempScissor.bottom  = tempScissor.y1/4;
 
1159
 
 
1160
    if( options.bEnableHacks )
 
1161
    {
 
1162
        if( g_CI.dwWidth == 0x200 && tempScissor.right == 0x200 )
 
1163
        {
 
1164
            uint32 width = *g_GraphicsInfo.VI_WIDTH_REG & 0xFFF;
 
1165
 
 
1166
            if( width != 0x200 )
 
1167
            {
 
1168
                // Hack for RE2
 
1169
                tempScissor.bottom = tempScissor.right*tempScissor.bottom/width;
 
1170
                tempScissor.right = width;
 
1171
            }
 
1172
 
 
1173
        }
 
1174
    }
 
1175
 
 
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)
 
1180
    {
 
1181
        memcpy(&(gRDP.scissor), &tempScissor, sizeof(ScissorType) );
 
1182
        if( !status.bHandleN64RenderTexture )
 
1183
            SetVIScales();
 
1184
 
 
1185
        if(  options.enableHackForGames == HACK_FOR_SUPER_BOWLING && g_CI.dwAddr%0x100 != 0 )
 
1186
        {
 
1187
            // right half screen
 
1188
            gRDP.scissor.left += 160;
 
1189
            gRDP.scissor.right += 160;
 
1190
            CRender::g_pRender->SetViewport(160, 0, 320, 240, 0xFFFF);
 
1191
        }
 
1192
 
 
1193
        CRender::g_pRender->UpdateClipRectangle();
 
1194
        CRender::g_pRender->UpdateScissor();
 
1195
        CRender::g_pRender->SetViewportRender();
 
1196
    }
 
1197
 
 
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,
 
1201
        gRDP.scissor.mode);
 
1202
 
 
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););
 
1205
}
 
1206
 
 
1207
 
 
1208
void DLParser_FillRect(Gfx *gfx)
 
1209
 
1210
    DP_Timing(DLParser_FillRect);   // fix me
 
1211
    status.primitiveType = PRIM_FILLRECT;
 
1212
 
 
1213
    if( status.bN64IsDrawingTextureBuffer && frameBufferOptions.bIgnore )
 
1214
    {
 
1215
        return;
 
1216
    }
 
1217
 
 
1218
    if( options.enableHackForGames == HACK_FOR_MARIO_TENNIS )
 
1219
    {
 
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 )
 
1223
        {
 
1224
            // Mario Tennis, a lot of FillRect ucodes, skip all of them
 
1225
            while( (w2>>24) == RDP_FILLRECT )
 
1226
            {
 
1227
                dwPC += 8;
 
1228
                w2 = *(uint32 *)(g_pRDRAMu8 + dwPC);
 
1229
            }
 
1230
 
 
1231
            gDlistStack[gDlistStackPointer].pc = dwPC;
 
1232
            return;
 
1233
        }
 
1234
    }
 
1235
 
 
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;
 
1240
 
 
1241
    // Note, in some modes, the right/bottom lines aren't drawn
 
1242
 
 
1243
    LOG_UCODE("    (%d,%d) (%d,%d)", x0, y0, x1, y1);
 
1244
 
 
1245
    if( gRDP.otherMode.cycle_type >= CYCLE_TYPE_COPY )
 
1246
    {
 
1247
        x1++;
 
1248
        y1++;
 
1249
    }
 
1250
 
 
1251
    //TXTRBUF_DETAIL_DUMP(DebuggerAppendMsg("FillRect: X0=%d, Y0=%d, X1=%d, Y1=%d, Color=0x%08X", x0, y0, x1, y1, gRDP.originalFillColor););
 
1252
 
 
1253
    if( status.bHandleN64RenderTexture && options.enableHackForGames == HACK_FOR_BANJO_TOOIE )
 
1254
    {
 
1255
        // Skip this
 
1256
        return;
 
1257
    }
 
1258
 
 
1259
    if (IsUsedAsDI(g_CI.dwAddr))
 
1260
    {
 
1261
        // Clear the Z Buffer
 
1262
        if( x0!=0 || y0!=0 || windowSetting.uViWidth-x1>1 || windowSetting.uViHeight-y1>1)
 
1263
        {
 
1264
            if( options.enableHackForGames == HACK_FOR_GOLDEN_EYE )
 
1265
            {
 
1266
                // GoldenEye is using double zbuffer
 
1267
                if( g_CI.dwAddr == g_ZI.dwAddr )
 
1268
                {
 
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");
 
1273
                }
 
1274
                else
 
1275
                {
 
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");
 
1281
                }
 
1282
            }
 
1283
            else
 
1284
            {
 
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");
 
1288
            }
 
1289
        }
 
1290
        else
 
1291
        {
 
1292
            CRender::g_pRender->ClearBuffer(false,true);    //Check me
 
1293
            LOG_UCODE("    Clearing ZBuffer");
 
1294
        }
 
1295
 
 
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);});
 
1299
 
 
1300
        if( g_curRomInfo.bEmulateClear )
 
1301
        {
 
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++ )
 
1307
            {
 
1308
                for( uint32 j=x0; j<x1; j++ )
 
1309
                {
 
1310
                    *(uint16*)((base+pitch*i+j)^2) = color;
 
1311
                }
 
1312
            }
 
1313
        }
 
1314
    }
 
1315
    else if( status.bHandleN64RenderTexture )
 
1316
    {
 
1317
        if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer();
 
1318
 
 
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);
 
1323
 
 
1324
        g_pRenderTextureInfo->maxUsedHeight = max(g_pRenderTextureInfo->maxUsedHeight,(int)y1);
 
1325
 
 
1326
        if( status.bDirectWriteIntoRDRAM || ( x0==0 && y0==0 && (x1 == g_pRenderTextureInfo->N64Width || x1 == g_pRenderTextureInfo->N64Width-1 ) ) )
 
1327
        {
 
1328
            if( g_pRenderTextureInfo->CI_Info.dwSize == TXT_SIZE_16b )
 
1329
            {
 
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++ )
 
1334
                {
 
1335
                    for( uint32 j=x0; j<x1; j++ )
 
1336
                    {
 
1337
                        *(uint16*)((base+pitch*i+j)^2) = color;
 
1338
                    }
 
1339
                }
 
1340
            }
 
1341
            else
 
1342
            {
 
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++ )
 
1347
                {
 
1348
                    for( uint32 j=x0; j<x1; j++ )
 
1349
                    {
 
1350
                        *(uint8*)((base+pitch*i+j)^3) = color;
 
1351
                    }
 
1352
                }
 
1353
            }
 
1354
 
 
1355
            status.bFrameBufferDrawnByTriangles = false;
 
1356
        }
 
1357
        else
 
1358
        {
 
1359
            status.bFrameBufferDrawnByTriangles = true;
 
1360
        }
 
1361
        status.bFrameBufferDrawnByTriangles = true;
 
1362
 
 
1363
        if( !status.bDirectWriteIntoRDRAM )
 
1364
        {
 
1365
            status.bFrameBufferIsDrawn = true;
 
1366
 
 
1367
            //if( x0==0 && y0==0 && (x1 == g_pRenderTextureInfo->N64Width || x1 == g_pRenderTextureInfo->N64Width-1 ) && gRDP.fillColor == 0)
 
1368
            //{
 
1369
            //  CRender::g_pRender->ClearBuffer(true,false);
 
1370
            //}
 
1371
            //else
 
1372
            {
 
1373
                if( gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL )
 
1374
                {
 
1375
                    CRender::g_pRender->FillRect(x0, y0, x1, y1, gRDP.fillColor);
 
1376
                }
 
1377
                else
 
1378
                {
 
1379
                    COLOR primColor = GetPrimitiveColor();
 
1380
                    CRender::g_pRender->FillRect(x0, y0, x1, y1, primColor);
 
1381
                }
 
1382
            }
 
1383
        }
 
1384
 
 
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);});
 
1388
    }
 
1389
    else
 
1390
    {
 
1391
        LOG_UCODE("    Filling Rectangle");
 
1392
        if( frameBufferOptions.bSupportRenderTextures || frameBufferOptions.bCheckBackBufs )
 
1393
        {
 
1394
            if( !status.bCIBufferIsRendered ) g_pFrameBufferManager->ActiveTextureBuffer();
 
1395
 
 
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);
 
1400
        }
 
1401
 
 
1402
        if( gRDP.otherMode.cycle_type == CYCLE_TYPE_FILL )
 
1403
        {
 
1404
            if( !status.bHandleN64RenderTexture || g_pRenderTextureInfo->CI_Info.dwSize == TXT_SIZE_16b )
 
1405
            {
 
1406
                CRender::g_pRender->FillRect(x0, y0, x1, y1, gRDP.fillColor);
 
1407
            }
 
1408
        }
 
1409
        else
 
1410
        {
 
1411
            COLOR primColor = GetPrimitiveColor();
 
1412
            //if( RGBA_GETALPHA(primColor) != 0 )
 
1413
            {
 
1414
                CRender::g_pRender->FillRect(x0, y0, x1, y1, primColor);
 
1415
            }
 
1416
        }
 
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);});
 
1420
    }
 
1421
}
 
1422
 
 
1423
 
 
1424
#define STORE_CI    {g_CI.dwAddr = dwNewAddr;g_CI.dwFormat = dwFmt;g_CI.dwSize = dwSiz;g_CI.dwWidth = dwWidth;g_CI.bpl=dwBpl;}
 
1425
 
 
1426
void DLParser_SetCImg(Gfx *gfx)
 
1427
{
 
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;
 
1433
 
 
1434
    TXTRBUF_DETAIL_DUMP(DebuggerAppendMsg("SetCImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", dwNewAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth););
 
1435
 
 
1436
    if( dwFmt == TXT_FMT_YUV || dwFmt == TXT_FMT_IA )
 
1437
    {
 
1438
        WARNING(TRACE4("Check me:  SetCImg Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", 
 
1439
            g_CI.dwAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth));
 
1440
    }
 
1441
 
 
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);
 
1445
 
 
1446
    if( g_CI.dwAddr == dwNewAddr && g_CI.dwFormat == dwFmt && g_CI.dwSize == dwSiz && g_CI.dwWidth == dwWidth )
 
1447
    {
 
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);
 
1452
        });
 
1453
        return;
 
1454
    }
 
1455
 
 
1456
    if( status.bVIOriginIsUpdated == true && currentRomOptions.screenUpdateSetting==SCREEN_UPDATE_AT_1ST_CI_CHANGE )
 
1457
    {
 
1458
        status.bVIOriginIsUpdated=false;
 
1459
        CGraphicsContext::Get()->UpdateFrame();
 
1460
        TXTRBUF_OR_CI_DETAIL_DUMP(TRACE0("Screen Update at 1st CI change"););
 
1461
    }
 
1462
 
 
1463
    if( options.enableHackForGames == HACK_FOR_SUPER_BOWLING )
 
1464
    {
 
1465
        if( dwNewAddr%0x100 == 0 )
 
1466
        {
 
1467
            if( dwWidth < 320 )
 
1468
            {
 
1469
                // Left half screen
 
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();
 
1475
            }
 
1476
            else
 
1477
            {
 
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();
 
1483
            }
 
1484
        }
 
1485
        else
 
1486
        {
 
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);
 
1495
        }
 
1496
    }
 
1497
 
 
1498
 
 
1499
    if( !frameBufferOptions.bUpdateCIInfo )
 
1500
    {
 
1501
        STORE_CI;
 
1502
        status.bCIBufferIsRendered = false;
 
1503
        status.bN64IsDrawingTextureBuffer = false;
 
1504
 
 
1505
        TXTRBUF_DUMP(TRACE4("SetCImg : Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", 
 
1506
            g_CI.dwAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth));
 
1507
 
 
1508
        DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_SET_CIMG, 
 
1509
        {
 
1510
            DebuggerAppendMsg("Pause after SetCImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", 
 
1511
                dwNewAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth);
 
1512
        }
 
1513
        );
 
1514
        return;
 
1515
    }
 
1516
 
 
1517
    SetImgInfo newCI;
 
1518
    newCI.bpl = dwBpl;
 
1519
    newCI.dwAddr = dwNewAddr;
 
1520
    newCI.dwFormat = dwFmt;
 
1521
    newCI.dwSize = dwSiz;
 
1522
    newCI.dwWidth = dwWidth;
 
1523
 
 
1524
    g_pFrameBufferManager->Set_CI_addr(newCI);
 
1525
}
 
1526
 
 
1527
void DLParser_SetZImg(Gfx *gfx)
 
1528
{
 
1529
    DP_Timing(DLParser_SetZImg);
 
1530
    LOG_UCODE("    Image: 0x%08x", RSPSegmentAddr(gfx->words.w1));
 
1531
 
 
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));
 
1536
 
 
1537
    if( dwAddr != g_ZI_saves[0].CI_Info.dwAddr )
 
1538
    {
 
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;
 
1544
 
 
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;
 
1550
    }
 
1551
    else
 
1552
    {
 
1553
        g_ZI.dwAddr = dwAddr;
 
1554
        g_ZI.dwFormat = dwFmt;
 
1555
        g_ZI.dwSize = dwSiz;
 
1556
        g_ZI.dwWidth    = dwWidth;
 
1557
    }
 
1558
 
 
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);}
 
1562
    );
 
1563
 
 
1564
    DEBUGGER_PAUSE_AND_DUMP_NO_UPDATE(NEXT_SET_CIMG, 
 
1565
        {
 
1566
            DebuggerAppendMsg("Pause after SetZImg: Addr=0x%08X, Fmt:%s-%sb, Width=%d\n", 
 
1567
                g_ZI.dwAddr, pszImgFormat[dwFmt], pszImgSize[dwSiz], dwWidth);
 
1568
        }
 
1569
    );
 
1570
}
 
1571
 
 
1572
bool IsUsedAsDI(uint32 addr)
 
1573
{
 
1574
    if( addr == g_ZI_saves[0].CI_Info.dwAddr )
 
1575
        return true;
 
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 )
 
1578
        return true;
 
1579
    else
 
1580
        return false;
 
1581
}
 
1582
 
 
1583
void DLParser_SetCombine(Gfx *gfx)
 
1584
{
 
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);
 
1589
}
 
1590
 
 
1591
void DLParser_SetFillColor(Gfx *gfx)
 
1592
{
 
1593
    DP_Timing(DLParser_SetFillColor);
 
1594
    gRDP.fillColor = Convert555ToRGBA(gfx->setcolor.fillcolor);
 
1595
    gRDP.originalFillColor = (gfx->setcolor.color);
 
1596
 
 
1597
    LOG_UCODE("    Color5551=0x%04x = 0x%08x", (uint16)gfx->words.w1, gRDP.fillColor);
 
1598
 
 
1599
}
 
1600
 
 
1601
void DLParser_SetFogColor(Gfx *gfx)
 
1602
{
 
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));
 
1606
}
 
1607
 
 
1608
void DLParser_SetBlendColor(Gfx *gfx)
 
1609
{
 
1610
    DP_Timing(DLParser_SetBlendColor);
 
1611
    CRender::g_pRender->SetAlphaRef(gfx->setcolor.a);
 
1612
}
 
1613
 
 
1614
 
 
1615
void DLParser_SetPrimColor(Gfx *gfx)
 
1616
{
 
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);
 
1620
}
 
1621
 
 
1622
void DLParser_SetEnvColor(Gfx *gfx)
 
1623
{
 
1624
    DP_Timing(DLParser_SetEnvColor);
 
1625
    SetEnvColor( COLOR_RGBA(gfx->setcolor.r, gfx->setcolor.g, gfx->setcolor.b, gfx->setcolor.a) );
 
1626
}
 
1627
 
 
1628
 
 
1629
void RDP_DLParser_Process(void)
 
1630
{
 
1631
    struct timeval tv;
 
1632
    gettimeofday(&tv, 0);
 
1633
    status.gRDPTime = tv.tv_usec;
 
1634
 
 
1635
    status.gDlistCount++;
 
1636
 
 
1637
    uint32 start = *(g_GraphicsInfo.DPC_START_REG);
 
1638
    uint32 end = *(g_GraphicsInfo.DPC_END_REG);
 
1639
 
 
1640
    gDlistStackPointer=0;
 
1641
    gDlistStack[gDlistStackPointer].pc = start;
 
1642
    gDlistStack[gDlistStackPointer].countdown = MAX_DL_COUNT;
 
1643
 
 
1644
    // Check if we need to purge
 
1645
    if (status.gRDPTime - status.lastPurgeTimeTime > 5000)
 
1646
    {
 
1647
        gTextureManager.PurgeOldTextures();
 
1648
        status.lastPurgeTimeTime = status.gRDPTime;
 
1649
    }
 
1650
    
 
1651
    // Lock the graphics context here.
 
1652
    CRender::g_pRender->SetFillMode(RICE_FILLMODE_SOLID);
 
1653
 
 
1654
    SetVIScales();
 
1655
 
 
1656
    CRender::g_pRender->RenderReset();
 
1657
    CRender::g_pRender->BeginRendering();
 
1658
    CRender::g_pRender->SetViewport(0, 0, windowSetting.uViWidth, windowSetting.uViHeight, 0x3FF);
 
1659
 
 
1660
    while( gDlistStack[gDlistStackPointer].pc < end )
 
1661
    {
 
1662
        Gfx *pgfx = (Gfx*)&g_pRDRAMu32[(gDlistStack[gDlistStackPointer].pc>>2)];
 
1663
        gDlistStack[gDlistStackPointer].pc += 8;
 
1664
        currentUcodeMap[pgfx->words.w0 >>24](pgfx);
 
1665
    }
 
1666
 
 
1667
    CRender::g_pRender->EndRendering();
 
1668
}
 
1669
 
 
1670
void RDP_TriFill(Gfx *gfx)
 
1671
{
 
1672
}
 
1673
 
 
1674
void RDP_TriFillZ(Gfx *gfx)
 
1675
{
 
1676
}
 
1677
 
 
1678
void RDP_TriTxtr(Gfx *gfx)
 
1679
{
 
1680
}
 
1681
 
 
1682
void RDP_TriTxtrZ(Gfx *gfx)
 
1683
{
 
1684
}
 
1685
 
 
1686
void RDP_TriShade(Gfx *gfx)
 
1687
{
 
1688
}
 
1689
 
 
1690
void RDP_TriShadeZ(Gfx *gfx)
 
1691
{
 
1692
}
 
1693
 
 
1694
void RDP_TriShadeTxtr(Gfx *gfx)
 
1695
{
 
1696
}
 
1697
 
 
1698
void RDP_TriShadeTxtrZ(Gfx *gfx)
 
1699
{
 
1700
}
 
1701
 
 
1702
static int crc_table_empty = 1;
 
1703
static ULONG crc_table[256];
 
1704
static void make_crc_table(void);
 
1705
 
 
1706
static void make_crc_table()
 
1707
{
 
1708
  ULONG c;
 
1709
  int n, k;
 
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};
 
1713
 
 
1714
  /* make exclusive-or pattern from polynomial (0xedb88320L) */
 
1715
  poly = 0L;
 
1716
  for (n = 0; (unsigned int)n < sizeof(p)/sizeof(uint8); n++)
 
1717
    poly |= 1L << (31 - p[n]);
 
1718
 
 
1719
  for (n = 0; n < 256; n++)
 
1720
  {
 
1721
    c = (ULONG)n;
 
1722
    for (k = 0; k < 8; k++)
 
1723
      c = (c & 1) ? (poly ^ (c >> 1)) : c >> 1;
 
1724
    crc_table[n] = c;
 
1725
  }
 
1726
  crc_table_empty = 0;
 
1727
}
 
1728
 
 
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);
 
1734
 
 
1735
/* ========================================================================= */
 
1736
ULONG ComputeCRC32(ULONG crc, const uint8 *buf, UINT len)
 
1737
{
 
1738
    if (buf == NULL) return 0L;
 
1739
 
 
1740
    if (crc_table_empty)
 
1741
      make_crc_table();
 
1742
 
 
1743
    crc = crc ^ 0xffffffffL;
 
1744
    while (len >= 8)
 
1745
    {
 
1746
      DO8(buf);
 
1747
      len -= 8;
 
1748
    }
 
1749
    if (len) do {
 
1750
      DO1(buf);
 
1751
    } while (--len);
 
1752
    return crc ^ 0xffffffffL;
 
1753
}
 
1754
 
 
1755
Matrix matToLoad;
 
1756
void LoadMatrix(uint32 addr)
 
1757
{
 
1758
    const float fRecip = 1.0f / 65536.0f;
 
1759
    if (addr + 64 > g_dwRamSize)
 
1760
    {
 
1761
        TRACE1("Mtx: Address invalid (0x%08x)", addr);
 
1762
        return;
 
1763
    }
 
1764
 
 
1765
    int i, j;
 
1766
 
 
1767
    for (i = 0; i < 4; i++)
 
1768
    {
 
1769
        for (j = 0; j < 4; j++) 
 
1770
        {
 
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;
 
1774
        }
 
1775
    }
 
1776
 
 
1777
 
 
1778
#ifdef _DEBUG
 
1779
    LOG_UCODE(
 
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]);
 
1788
#endif // _DEBUG
 
1789
}
 
1790