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
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
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;
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
);
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];
91 v
->x_w
= v
->x
* v
->oow
;
92 v
->y_w
= v
->y
* v
->oow
;
93 v
->z_w
= v
->z
* v
->oow
;
96 v
->uv_calculated
= 0xFFFFFFFF;
97 v
->screen_translated
= 0;
98 v
->shade_mods_allowed
= 1;
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)
115 else if (rdp
.geom_mode
& 0x40000)
117 NormalizeVector (v
->vec
);
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
);
135 // tri1 - renders a triangle
138 static void uc1_tri1()
140 if (rdp
.skip_drawing
)
142 RDP("uc1:tri1. skipped\n");
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
);
151 &rdp
.vtx
[(rdp
.cmd1
>> 17) & 0x7F],
152 &rdp
.vtx
[(rdp
.cmd1
>> 9) & 0x7F],
153 &rdp
.vtx
[(rdp
.cmd1
>> 1) & 0x7F]
167 static void uc1_tri2 ()
169 if (rdp
.skip_drawing
)
171 RDP("uc1:tri2. skipped\n");
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));
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]
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);
227 &rdp
.vtx
[(rdp
.cmd1
>> 17) & 0x7F],
228 &rdp
.vtx
[(rdp
.cmd1
>> 9) & 0x7F],
229 &rdp
.vtx
[(rdp
.cmd1
>> 9) & 0x7F]
243 FRDP("uc1:quad3d #%d, #%d\n", rdp
.tri_n
, rdp
.tri_n
+1);
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]
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
;