Replace Tmem_nasm.asm with C++ code. Patch by pyro.
[Glide64.git] / ucode04.h
blob572fb8a1142358088fa3045e110d6c365d2ab7b6
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 //****************************************************************
36 //****************************************************************
37 // uCode 4 - RSP SW 2.0D EXT
38 //****************************************************************
40 static void uc4_vertex()
42 DWORD addr = segoffset(rdp.cmd1) & 0x00FFFFFF;
43 int v0, i, n;
44 float x, y, z;
46 rdp.v0 = v0 = 0; // Current vertex
47 rdp.vn = n = ((rdp.cmd0 >> 4) & 0xFFF) / 33 + 1; // Number of vertices to copy
49 FRDP("uc4:vertex: v0: %d, n: %d\n", v0, n);
51 // This is special, not handled in update(), but here
52 // * Matrix Pre-multiplication idea by Gonetz (Gonetz@ngs.ru)
53 if (rdp.update & UPDATE_MULT_MAT)
55 rdp.update ^= UPDATE_MULT_MAT;
56 MulMatrices(rdp.model, rdp.proj, rdp.combined);
58 // *
60 // This is special, not handled in update()
61 if (rdp.update & UPDATE_LIGHTS)
63 rdp.update ^= UPDATE_LIGHTS;
65 // Calculate light vectors
66 for (DWORD l=0; l<rdp.num_lights; l++)
68 InverseTransformVector(&rdp.light[l].dir_x, rdp.light_vector[l], rdp.model);
69 NormalizeVector (rdp.light_vector[l]);
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];
89 v->oow = 1.0f / v->w;
90 v->x_w = v->x * v->oow;
91 v->y_w = v->y * v->oow;
92 v->z_w = v->z * v->oow;
93 CalculateFog (v);
95 v->uv_calculated = 0xFFFFFFFF;
96 v->screen_translated = 0;
97 v->shade_mods_allowed = 1;
99 v->scr_off = 0;
100 if (v->x < -v->w) v->scr_off |= 1;
101 if (v->x > v->w) v->scr_off |= 2;
102 if (v->y < -v->w) v->scr_off |= 4;
103 if (v->y > v->w) v->scr_off |= 8;
104 if (v->w < 0.1f) v->scr_off |= 16;
106 if (rdp.geom_mode & 0x00020000)
108 v->vec[0] = ((char*)gfx.RDRAM)[(addr+i + 12)^3];
109 v->vec[1] = ((char*)gfx.RDRAM)[(addr+i + 13)^3];
110 v->vec[2] = ((char*)gfx.RDRAM)[(addr+i + 14)^3];
112 if (rdp.geom_mode & 0x80000)
113 calc_linear (v);
114 else if (rdp.geom_mode & 0x40000)
115 calc_sphere (v);
117 NormalizeVector (v->vec);
118 calc_light (v);
120 else
122 v->r = ((BYTE*)gfx.RDRAM)[(addr+i + 12)^3];
123 v->g = ((BYTE*)gfx.RDRAM)[(addr+i + 13)^3];
124 v->b = ((BYTE*)gfx.RDRAM)[(addr+i + 14)^3];
129 static void uc4_tri1()
131 int v1 = ((rdp.cmd1 >> 16) & 0xFF) / 5;
132 int v2 = ((rdp.cmd1 >> 8) & 0xFF) / 5;
133 int v3 = (rdp.cmd1 & 0xFF) / 5;
134 FRDP("uc4:tri1 #%d - %d, %d, %d\n", rdp.tri_n,
135 v1, v2, v3);
137 VERTEX *v[3] = {
138 &rdp.vtx[v1],
139 &rdp.vtx[v2],
140 &rdp.vtx[v3]
143 if (cull_tri(v))
144 rdp.tri_n ++;
145 else
147 update ();
149 DrawTri (v);
150 rdp.tri_n ++;
154 static void uc4_quad3d()
156 FRDP("uc4:quad3d #%d, #%d\n", rdp.tri_n, rdp.tri_n+1);
158 VERTEX *v[6] = {
159 &rdp.vtx[((rdp.cmd1 >> 24) & 0xFF) / 5],
160 &rdp.vtx[((rdp.cmd1 >> 16) & 0xFF) / 5],
161 &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF) / 5],
162 &rdp.vtx[((rdp.cmd1 >> 24) & 0xFF) / 5],
163 &rdp.vtx[((rdp.cmd1 >> 8) & 0xFF) / 5],
164 &rdp.vtx[(rdp.cmd1 & 0xFF) / 5]
167 BOOL updated = 0;
169 if (cull_tri(v))
170 rdp.tri_n ++;
171 else
173 updated = 1;
174 update ();
176 DrawTri (v);
177 rdp.tri_n ++;
180 if (cull_tri(v+3))
181 rdp.tri_n ++;
182 else
184 if (!updated)
185 update ();
187 DrawTri (v+3);
188 rdp.tri_n ++;