Replace Tmem_nasm.asm with C++ code. Patch by pyro.
[Glide64.git] / ucode01.h
blob75fba4ac0b797e97a5b571abb9ffb48e46f3bf96
1 /*
2 * Glide64 - Glide video plugin for Nintendo 64 emulators.
3 * Copyright (c) 2002 Dave2001
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 //****************************************************************
22 // Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
23 // Project started on December 29th, 2001
25 // To modify Glide64:
26 // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
27 // * Do NOT send me the whole project or file that you modified. Take out your modified code sections, and tell me where to put them. If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
29 // Official Glide64 development channel: #Glide64 on EFnet
31 // Original author: Dave2001 (Dave2999@hotmail.com)
32 // Other authors: Gonetz, Gugaman
34 //****************************************************************
37 // vertex - loads vertices
40 static void uc1_vertex()
42 DWORD addr = segoffset(rdp.cmd1) & 0x00FFFFFF;
43 int v0, i, n;
44 float x, y, z;
46 rdp.v0 = v0 = (rdp.cmd0 >> 17) & 0x7F; // Current vertex
47 rdp.vn = n = (WORD)(rdp.cmd0 >> 10) & 0x3F; // Number to copy
49 // This is special, not handled in update(), but here
50 // * Matrix Pre-multiplication idea by Gonetz (Gonetz@ngs.ru)
51 if (rdp.update & UPDATE_MULT_MAT)
53 rdp.update ^= UPDATE_MULT_MAT;
54 MulMatrices(rdp.model, rdp.proj, rdp.combined);
56 // *
58 // This is special, not handled in update()
59 if (rdp.update & UPDATE_LIGHTS)
61 rdp.update ^= UPDATE_LIGHTS;
63 // Calculate light vectors
64 for (DWORD l=0; l<rdp.num_lights; l++)
66 InverseTransformVector(&rdp.light[l].dir_x, rdp.light_vector[l], rdp.model);
67 NormalizeVector (rdp.light_vector[l]);
71 FRDP ("uc1:vertex v0:%d, n:%d, from: %08lx\n", v0, n, addr);
73 for (i=0; i < (n<<4); i+=16)
75 VERTEX *v = &rdp.vtx[v0 + (i>>4)];
76 x = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 0)^1];
77 y = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 1)^1];
78 z = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 2)^1];
79 v->flags = ((WORD*)gfx.RDRAM)[(((addr+i) >> 1) + 3)^1];
80 v->ou = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 4)^1] * rdp.tiles[rdp.cur_tile].s_scale;
81 v->ov = (float)((short*)gfx.RDRAM)[(((addr+i) >> 1) + 5)^1] * rdp.tiles[rdp.cur_tile].t_scale;
82 v->a = ((BYTE*)gfx.RDRAM)[(addr+i + 15)^3];
84 v->x = x*rdp.combined[0][0] + y*rdp.combined[1][0] + z*rdp.combined[2][0] + rdp.combined[3][0];
85 v->y = x*rdp.combined[0][1] + y*rdp.combined[1][1] + z*rdp.combined[2][1] + rdp.combined[3][1];
86 v->z = x*rdp.combined[0][2] + y*rdp.combined[1][2] + z*rdp.combined[2][2] + rdp.combined[3][2];
87 v->w = x*rdp.combined[0][3] + y*rdp.combined[1][3] + z*rdp.combined[2][3] + rdp.combined[3][3];
90 v->oow = 1.0f / v->w;
91 v->x_w = v->x * v->oow;
92 v->y_w = v->y * v->oow;
93 v->z_w = v->z * v->oow;
94 CalculateFog (v);
96 v->uv_calculated = 0xFFFFFFFF;
97 v->screen_translated = 0;
98 v->shade_mods_allowed = 1;
99 v->uv_fixed = 0;
101 v->scr_off = 0;
102 if (v->x < -v->w) v->scr_off |= 1;
103 if (v->x > v->w) v->scr_off |= 2;
104 if (v->y < -v->w) v->scr_off |= 4;
105 if (v->y > v->w) v->scr_off |= 8;
106 if (v->w < 0.1f) v->scr_off |= 16;
108 if (rdp.geom_mode & 0x00020000)
110 v->vec[0] = ((char*)gfx.RDRAM)[(addr+i + 12)^3];
111 v->vec[1] = ((char*)gfx.RDRAM)[(addr+i + 13)^3];
112 v->vec[2] = ((char*)gfx.RDRAM)[(addr+i + 14)^3];
113 if (rdp.geom_mode & 0x80000)
114 calc_linear (v);
115 else if (rdp.geom_mode & 0x40000)
116 calc_sphere (v);
117 NormalizeVector (v->vec);
119 calc_light (v);
121 else
123 v->r = ((BYTE*)gfx.RDRAM)[(addr+i + 12)^3];
124 v->g = ((BYTE*)gfx.RDRAM)[(addr+i + 13)^3];
125 v->b = ((BYTE*)gfx.RDRAM)[(addr+i + 14)^3];
127 #ifdef EXTREME_LOGGING
128 FRDP ("v%d - x: %f, y: %f, z: %f, w: %f, u: %f, v: %f\n", i>>4, v->x, v->y, v->z, v->w, v->ou, v->ov);
129 #endif
135 // tri1 - renders a triangle
138 static void uc1_tri1()
140 if (rdp.skip_drawing)
142 RDP("uc1:tri1. skipped\n");
143 return;
145 FRDP("uc1:tri1 #%d - %d, %d, %d - %08lx - %08lx\n", rdp.tri_n,
146 ((rdp.cmd1 >> 17) & 0x7F),
147 ((rdp.cmd1 >> 9) & 0x7F),
148 ((rdp.cmd1 >> 1) & 0x7F), rdp.cmd0, rdp.cmd1);
150 VERTEX *v[3] = {
151 &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F],
152 &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F],
153 &rdp.vtx[(rdp.cmd1 >> 1) & 0x7F]
156 if (cull_tri(v))
157 rdp.tri_n ++;
158 else
160 update ();
162 DrawTri (v);
163 rdp.tri_n ++;
167 static void uc1_tri2 ()
169 if (rdp.skip_drawing)
171 RDP("uc1:tri2. skipped\n");
172 return;
174 RDP ("uc1:tri2");
176 FRDP(" #%d, #%d - %d, %d, %d - %d, %d, %d\n", rdp.tri_n, rdp.tri_n+1,
177 ((rdp.cmd0 >> 17) & 0x7F),
178 ((rdp.cmd0 >> 9) & 0x7F),
179 ((rdp.cmd0 >> 1) & 0x7F),
180 ((rdp.cmd1 >> 17) & 0x7F),
181 ((rdp.cmd1 >> 9) & 0x7F),
182 ((rdp.cmd1 >> 1) & 0x7F));
184 VERTEX *v[6] = {
185 &rdp.vtx[(rdp.cmd0 >> 17) & 0x7F],
186 &rdp.vtx[(rdp.cmd0 >> 9) & 0x7F],
187 &rdp.vtx[(rdp.cmd0 >> 1) & 0x7F],
188 &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F],
189 &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F],
190 &rdp.vtx[(rdp.cmd1 >> 1) & 0x7F]
193 BOOL updated = 0;
195 if (cull_tri(v))
196 rdp.tri_n ++;
197 else
199 updated = 1;
200 update ();
201 DrawTri (v);
202 rdp.tri_n ++;
205 if (cull_tri(v+3))
206 rdp.tri_n ++;
207 else
209 if (!updated)
210 update ();
211 DrawTri (v+3);
212 rdp.tri_n ++;
216 static void uc1_line3d()
218 if (((rdp.cmd1&0xFF000000) == 0) && ((rdp.cmd0&0x00FFFFFF) == 0))
220 WORD width = (WORD)(rdp.cmd1&0xFF) + 1;
222 FRDP("uc1:line3d #%d, #%d - %d, %d\n", rdp.tri_n, rdp.tri_n+1,
223 (rdp.cmd1 >> 17) & 0x7F,
224 (rdp.cmd1 >> 9) & 0x7F);
226 VERTEX *v[3] = {
227 &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F],
228 &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F],
229 &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F]
232 if (cull_tri(v))
233 rdp.tri_n ++;
234 else
236 update ();
237 DrawTri (v, width);
238 rdp.tri_n ++;
241 else
243 FRDP("uc1:quad3d #%d, #%d\n", rdp.tri_n, rdp.tri_n+1);
245 VERTEX *v[6] = {
246 &rdp.vtx[(rdp.cmd1 >> 25) & 0x7F],
247 &rdp.vtx[(rdp.cmd1 >> 17) & 0x7F],
248 &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F],
249 &rdp.vtx[(rdp.cmd1 >> 1) & 0x7F],
250 &rdp.vtx[(rdp.cmd1 >> 25) & 0x7F],
251 &rdp.vtx[(rdp.cmd1 >> 9) & 0x7F]
254 BOOL updated = 0;
256 if (cull_tri(v))
257 rdp.tri_n ++;
258 else
260 updated = 1;
261 update ();
263 DrawTri (v);
264 rdp.tri_n ++;
267 if (cull_tri(v+3))
268 rdp.tri_n ++;
269 else
271 if (!updated)
272 update ();
274 DrawTri (v+3);
275 rdp.tri_n ++;
280 DWORD branch_dl = 0;
282 static void uc1_rdphalf_1()
284 RDP ("uc1:rdphalf_1\n");
285 branch_dl = rdp.cmd1;
288 static void uc1_branch_z()
290 DWORD addr = segoffset(branch_dl);
291 FRDP ("uc1:branch_less_z, addr: %08lx\n", addr);
292 DWORD vtx = (rdp.cmd0 & 0xFFF) >> 1;
293 if( fabs(rdp.vtx[vtx].z) <= (rdp.cmd1/*&0xFFFF*/) )
295 rdp.pc[rdp.pc_i] = addr;