1 /* ResidualVM - A 3D game interpreter
2 *
3 * ResidualVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the AUTHORS
5 * file distributed with this source distribution.
6 *
7 * Additional copyright for this file:
8 * Copyright (C) 1999-2000 Revolution Software Ltd.
9 * This code is based on source code created by Revolution Software,
10 * used with permission.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 *
26 */
27
28 #ifndef ICB_PX_CAPRI_MATHS_PC_H
29 #define ICB_PX_CAPRI_MATHS_PC_H
30
31 #include "common/util.h"
32
33 namespace ICB {
34
35 #if (_PSX_ON_PC == 0) && !defined ICB_PX_CAPRI_MATHS_PC_H
36
37 // make our own equivalents
38 typedef struct MATRIXPC {
39 int32 m[3][3]; /* 3x3 rotation matrix */
40 int32 pad;
41 int32 t[3]; /* transfer vector */
MATRIXPCMATRIXPC42 MATRIXPC() { pad = 0; }
43 } MATRIXPC;
44
45 /* int32 word type 3D vector */
46 typedef struct VECTOR {
47 int32 vx, vy;
48 int32 vz, pad;
VECTORVECTOR49 VECTOR() { pad = 0; }
50 } VECTOR;
51
52 /* short word type 3D vector */
53 typedef struct SVECTORPC {
54 int32 vx, vy;
55 int32 vz, pad;
SVECTORPCSVECTORPC56 SVECTORPC() { pad = 0; }
57 bool operator==(const SVECTORPC &v) { return ((v.vx == vx) && (v.vy == vy) && (v.vz == vz)); }
58 } SVECTORPC;
59
60 /* short word type 3D vector */
61 typedef struct CVECTOR {
62 uint8 r, g;
63 int16 b, pad;
CVECTORCVECTOR64 CVECTOR() { pad = 0; }
65 bool operator==(const CVECTOR &v) { return ((v.r == r) && (v.g == g) && (v.b == b)); }
66 } CVECTOR;
67
68 #endif // #if (_PSX_ON_PC==0)
69
70 //-=- Definitions -=-//
71 const int32 ONE_PC_SCALE = 12;
72 const int32 ONE_PC = 1 << ONE_PC_SCALE;
73 const float myPI_PC = 3.141592654f;
74 const int32 ZSCALE = 1;
75
myNINT_PC(float f)76 inline int32 myNINT_PC(float f) {
77 if (f >= 0.0f)
78 return int(f + 0.5f);
79 else
80 return int(f - 0.5f);
81 }
82
83 //------------------------------------------------------------------------
84
85 #define VectorNormal_pc myVectorNormal_pc
86 #define ApplyMatrixLV_pc myApplyMatrixLV_pc
87 #define ApplyMatrixSV_pc myApplyMatrixSV_pc
88 #define RotMatrix_gte_pc myRotMatrix_gte_pc
89 #define gte_MulMatrix0_pc mygte_MulMatrix0_pc
90 #define gte_RotTrans_pc mygte_RotTrans_pc
91 #define gte_RotTransPers_pc mygte_RotTransPers_pc
92 #define gte_RotTransPers3_pc mygte_RotTransPers3_pc
93 #define gte_SetRotMatrix_pc mygte_SetRotMatrix_pc
94 #define gte_SetTransMatrix_pc mygte_SetTransMatrix_pc
95 #define gte_ApplyRotMatrix_pc mygte_ApplyRotMatrix_pc
96 #define gte_SetGeomScreen_pc mygte_SetGeomScreen_pc
97 #define gte_SetBackColor_pc mygte_SetBackColor_pc
98 #define gte_SetColorMatrix_pc mygte_SetColorMatrix_pc
99 #define gte_SetLightMatrix_pc mygte_SetLightMatrix_pc
100 #define gte_NormalColorCol_pc mygte_NormalColorCol_pc
101 #define gte_NormalColorCol3_pc mygte_NormalColorCol3_pc
102 #define gte_NormalClip_pc mygte_NormalClip_pc
103 #define gte_AverageZ3_pc mygte_AverageZ3_pc
104 #define gte_SetScreenScaleShift_pc mygte_SetScreenScaleShift_pc
105
106 //------------------------------------------------------------------------
107
108 extern MATRIXPC *gterot_pc;
109 extern MATRIXPC *gtetrans_pc;
110 extern MATRIXPC *gtecolour_pc;
111 extern MATRIXPC *gtelight_pc;
112 extern int32 gteback_pc[3];
113 extern int32 gtegeomscrn_pc;
114 extern int32 gtescreenscaleshift_pc;
115
116 //------------------------------------------------------------------------
117
118 inline void myApplyMatrixLV_pc(MATRIXPC *m, VECTOR *invec, VECTOR *outvec);
119
120 inline void myApplyMatrixSV_pc(MATRIXPC *m, SVECTORPC *invec, SVECTORPC *outvec);
121 inline void myApplyMatrixSV_pc(MATRIXPC *m, SVECTOR *invec, SVECTORPC *outvec);
122
123 inline int32 myVectorNormal_pc(VECTOR *in0, VECTOR *out0);
124
125 inline void mygte_MulMatrix0_pc(MATRIXPC *m1, MATRIXPC *m2, MATRIXPC *out);
126
127 inline void mygte_RotTrans_pc(SVECTORPC *in0, VECTOR *out0, int32 *flag);
128 inline void mygte_RotTrans_pc(SVECTOR *in0, VECTOR *out0, int32 *flag);
129
130 inline void mygte_RotTransPers_pc(SVECTORPC *in0, SVECTORPC *sxy0, int32 *p, int32 *flag, int32 *z);
131 inline void mygte_RotTransPers_pc(SVECTOR *in0, SVECTORPC *sxy0, int32 *p, int32 *flag, int32 *z);
132
133 inline void mygte_RotTransPers3_pc(SVECTORPC *in0, SVECTORPC *in1, SVECTORPC *in2, SVECTORPC *sxy0, SVECTORPC *sxy1, SVECTORPC *sxy2, int32 *p, int32 *flag, int32 *z);
134
135 inline void mygte_SetRotMatrix_pc(MATRIXPC *m);
136
137 inline void mygte_SetTransMatrix_pc(MATRIXPC *m);
138
139 inline void mygte_ApplyRotMatrix_pc(SVECTORPC *invec, VECTOR *outvec);
140
141 inline void myRotMatrix_gte_pc(SVECTOR *rot, MATRIXPC *m);
142
143 inline void mygte_SetColorMatrix_pc(MATRIXPC *m);
144
145 inline void mygte_SetLightMatrix_pc(MATRIXPC *m);
146
147 inline void mygte_SetGeomScreen_pc(int32 h);
148
149 inline void mygte_SetBackColor_pc(int32 r, int32 g, int32 b);
150
151 inline void mygte_SetScreenScaleShift_pc(int32 shift);
152
153 inline void mygte_NormalColorCol_pc(SVECTOR *v0, CVECTOR *in0, CVECTOR *out0);
154
155 inline void mygte_NormalColorCol3_pc(SVECTOR *v0, SVECTOR *v1, SVECTOR *v2, CVECTOR *in0, CVECTOR *out0, CVECTOR *out1, CVECTOR *out2);
156
157 inline void mygte_NormalClip_pc(SVECTORPC *sxy0, SVECTORPC *sxy1, SVECTORPC *sxy2, int32 *flag);
158 inline void mygte_NormalClip_pc(SVECTOR *sxy0, SVECTOR *sxy1, SVECTOR *sxy2, int32 *flag);
159
160 inline void mygte_AverageZ3_pc(int32 z0, int32 z1, int32 z2, int32 *sz);
161
162 //------------------------------------------------------------------------
163
myApplyMatrixLV_pc(MATRIXPC * m,VECTOR * invec,VECTOR * outvec)164 inline void myApplyMatrixLV_pc(MATRIXPC *m, VECTOR *invec, VECTOR *outvec) {
165 outvec->vx = (m->m[0][0] * invec->vx + m->m[0][1] * invec->vy + m->m[0][2] * invec->vz) / ONE_PC;
166 outvec->vy = (m->m[1][0] * invec->vx + m->m[1][1] * invec->vy + m->m[1][2] * invec->vz) / ONE_PC;
167 outvec->vz = (m->m[2][0] * invec->vx + m->m[2][1] * invec->vy + m->m[2][2] * invec->vz) / ONE_PC;
168 }
169
170 //------------------------------------------------------------------------
171
myApplyMatrixSV_pc(MATRIXPC * m,SVECTORPC * invec,SVECTORPC * outvec)172 inline void myApplyMatrixSV_pc(MATRIXPC *m, SVECTORPC *invec, SVECTORPC *outvec) {
173 outvec->vx = (int)((m->m[0][0] * invec->vx + m->m[0][1] * invec->vy + m->m[0][2] * invec->vz) / ONE_PC);
174 outvec->vy = (int)((m->m[1][0] * invec->vx + m->m[1][1] * invec->vy + m->m[1][2] * invec->vz) / ONE_PC);
175 outvec->vz = (int)((m->m[2][0] * invec->vx + m->m[2][1] * invec->vy + m->m[2][2] * invec->vz) / ONE_PC);
176 }
177
178 //------------------------------------------------------------------------
179
myApplyMatrixSV_pc(MATRIXPC * m,SVECTOR * invec,SVECTORPC * outvec)180 inline void myApplyMatrixSV_pc(MATRIXPC *m, SVECTOR *invec, SVECTORPC *outvec) {
181 outvec->vx = (int)((m->m[0][0] * (int)invec->vx + m->m[0][1] * (int)invec->vy + m->m[0][2] * (int)invec->vz) / ONE_PC);
182 outvec->vy = (int)((m->m[1][0] * (int)invec->vx + m->m[1][1] * (int)invec->vy + m->m[1][2] * (int)invec->vz) / ONE_PC);
183 outvec->vz = (int)((m->m[2][0] * (int)invec->vx + m->m[2][1] * (int)invec->vy + m->m[2][2] * (int)invec->vz) / ONE_PC);
184 }
185
186 //------------------------------------------------------------------------
187
mygte_MulMatrix0_pc(MATRIXPC * m1,MATRIXPC * m2,MATRIXPC * out)188 inline void mygte_MulMatrix0_pc(MATRIXPC *m1, MATRIXPC *m2, MATRIXPC *out) {
189 MATRIXPC local;
190 MATRIXPC *work;
191 if ((out == m1) || (out == m2))
192 work = &local;
193 else
194 work = out;
195 work->m[0][0] = (int)((m1->m[0][0] * m2->m[0][0] + m1->m[0][1] * m2->m[1][0] + m1->m[0][2] * m2->m[2][0]) / ONE_PC);
196 work->m[0][1] = (int)((m1->m[0][0] * m2->m[0][1] + m1->m[0][1] * m2->m[1][1] + m1->m[0][2] * m2->m[2][1]) / ONE_PC);
197 work->m[0][2] = (int)((m1->m[0][0] * m2->m[0][2] + m1->m[0][1] * m2->m[1][2] + m1->m[0][2] * m2->m[2][2]) / ONE_PC);
198 work->m[1][0] = (int)((m1->m[1][0] * m2->m[0][0] + m1->m[1][1] * m2->m[1][0] + m1->m[1][2] * m2->m[2][0]) / ONE_PC);
199 work->m[1][1] = (int)((m1->m[1][0] * m2->m[0][1] + m1->m[1][1] * m2->m[1][1] + m1->m[1][2] * m2->m[2][1]) / ONE_PC);
200 work->m[1][2] = (int)((m1->m[1][0] * m2->m[0][2] + m1->m[1][1] * m2->m[1][2] + m1->m[1][2] * m2->m[2][2]) / ONE_PC);
201 work->m[2][0] = (int)((m1->m[2][0] * m2->m[0][0] + m1->m[2][1] * m2->m[1][0] + m1->m[2][2] * m2->m[2][0]) / ONE_PC);
202 work->m[2][1] = (int)((m1->m[2][0] * m2->m[0][1] + m1->m[2][1] * m2->m[1][1] + m1->m[2][2] * m2->m[2][1]) / ONE_PC);
203 work->m[2][2] = (int)((m1->m[2][0] * m2->m[0][2] + m1->m[2][1] * m2->m[1][2] + m1->m[2][2] * m2->m[2][2]) / ONE_PC);
204
205 if (work != out) {
206 out->m[0][0] = work->m[0][0];
207 out->m[0][1] = work->m[0][1];
208 out->m[0][2] = work->m[0][2];
209
210 out->m[1][0] = work->m[1][0];
211 out->m[1][1] = work->m[1][1];
212 out->m[1][2] = work->m[1][2];
213
214 out->m[2][0] = work->m[2][0];
215 out->m[2][1] = work->m[2][1];
216 out->m[2][2] = work->m[2][2];
217 }
218 }
219
220 //------------------------------------------------------------------------
221
mygte_SetRotMatrix_pc(MATRIXPC * m)222 inline void mygte_SetRotMatrix_pc(MATRIXPC *m) { *gterot_pc = *m; }
223
224 //------------------------------------------------------------------------
225
mygte_SetTransMatrix_pc(MATRIXPC * m)226 inline void mygte_SetTransMatrix_pc(MATRIXPC *m) { *gtetrans_pc = *m; }
227
228 //------------------------------------------------------------------------
229
mygte_ApplyRotMatrix_pc(SVECTORPC * invec,VECTOR * outvec)230 inline void mygte_ApplyRotMatrix_pc(SVECTORPC *invec, VECTOR *outvec) {
231 outvec->vx = ((gterot_pc->m[0][0] * invec->vx + gterot_pc->m[0][1] * invec->vy + gterot_pc->m[0][2] * invec->vz) / ONE_PC);
232 outvec->vy = ((gterot_pc->m[1][0] * invec->vx + gterot_pc->m[1][1] * invec->vy + gterot_pc->m[1][2] * invec->vz) / ONE_PC);
233 outvec->vz = ((gterot_pc->m[2][0] * invec->vx + gterot_pc->m[2][1] * invec->vy + gterot_pc->m[2][2] * invec->vz) / ONE_PC);
234 }
235
236 //------------------------------------------------------------------------
237
mygte_RotTrans_pc(SVECTORPC * in0,VECTOR * out0,int32 * flag)238 inline void mygte_RotTrans_pc(SVECTORPC *in0, VECTOR *out0, int32 *flag) {
239 mygte_ApplyRotMatrix_pc(in0, out0);
240 out0->vx += gtetrans_pc->t[0];
241 out0->vy += gtetrans_pc->t[1];
242 out0->vz += gtetrans_pc->t[2];
243
244 // What GTE flags should we set ?
245 *flag = 0;
246 }
247
248 //------------------------------------------------------------------------
249
mygte_RotTrans_pc(SVECTOR * in0,VECTOR * out0,int32 * flag)250 inline void mygte_RotTrans_pc(SVECTOR *in0, VECTOR *out0, int32 *flag) {
251 SVECTORPC sv_pc;
252 sv_pc.vx = in0->vx;
253 sv_pc.vy = in0->vy;
254 sv_pc.vz = in0->vz;
255
256 mygte_ApplyRotMatrix_pc(&sv_pc, out0);
257
258 out0->vx += gtetrans_pc->t[0];
259 out0->vy += gtetrans_pc->t[1];
260 out0->vz += gtetrans_pc->t[2];
261
262 // What GTE flags should we set ?
263 *flag = 0;
264 }
265
266 //------------------------------------------------------------------------
267
mygte_RotTransPers_pc(SVECTORPC * in0,SVECTORPC * sxy0,int32 *,int32 * flag,int32 * z)268 inline void mygte_RotTransPers_pc(SVECTORPC *in0, SVECTORPC *sxy0, int32 * /* p */, int32 *flag, int32 *z) {
269 VECTOR cam;
270 cam.vx = ((gterot_pc->m[0][0] * in0->vx + gterot_pc->m[0][1] * in0->vy + gterot_pc->m[0][2] * in0->vz) / ONE_PC);
271 cam.vy = ((gterot_pc->m[1][0] * in0->vx + gterot_pc->m[1][1] * in0->vy + gterot_pc->m[1][2] * in0->vz) / ONE_PC);
272 cam.vz = ((gterot_pc->m[2][0] * in0->vx + gterot_pc->m[2][1] * in0->vy + gterot_pc->m[2][2] * in0->vz) / ONE_PC);
273 cam.vx += (gtetrans_pc->t[0] << gtescreenscaleshift_pc);
274 cam.vy += (gtetrans_pc->t[1] << gtescreenscaleshift_pc);
275 cam.vz += (gtetrans_pc->t[2] << gtescreenscaleshift_pc);
276
277 *flag = 0;
278
279 if (cam.vz != 0) {
280 sxy0->vx = (int)((cam.vx * gtegeomscrn_pc) / cam.vz);
281 sxy0->vy = (int)((cam.vy * gtegeomscrn_pc) / cam.vz);
282 } else {
283 // To force an error and hence an illegal polygon
284 sxy0->vx = 2048;
285 sxy0->vy = 2048;
286 }
287
288 cam.vz >>= gtescreenscaleshift_pc;
289 *z = cam.vz / 4;
290
291 if (abs(sxy0->vx) > 1024)
292 *flag |= 0x80000000;
293 if (abs(sxy0->vy) > 1024)
294 *flag |= 0x80000000;
295
296 // set the value of flag : closer than h/2
297 if (cam.vz < 0)
298 *flag |= 0x80000000;
299 }
300
301 //------------------------------------------------------------------------
302
mygte_RotTransPers_pc(SVECTOR * in0,SVECTORPC * sxy0,int32 *,int32 * flag,int32 * z)303 inline void mygte_RotTransPers_pc(SVECTOR *in0, SVECTORPC *sxy0, int32 * /* p */, int32 *flag, int32 *z) {
304 VECTOR cam;
305 cam.vx = ((gterot_pc->m[0][0] * (int)in0->vx + gterot_pc->m[0][1] * (int)in0->vy + gterot_pc->m[0][2] * (int)in0->vz) / ONE_PC);
306 cam.vy = ((gterot_pc->m[1][0] * (int)in0->vx + gterot_pc->m[1][1] * (int)in0->vy + gterot_pc->m[1][2] * (int)in0->vz) / ONE_PC);
307 cam.vz = ((gterot_pc->m[2][0] * (int)in0->vx + gterot_pc->m[2][1] * (int)in0->vy + gterot_pc->m[2][2] * (int)in0->vz) / ONE_PC);
308 cam.vx += (gtetrans_pc->t[0] << gtescreenscaleshift_pc);
309 cam.vy += (gtetrans_pc->t[1] << gtescreenscaleshift_pc);
310 cam.vz += (gtetrans_pc->t[2] << gtescreenscaleshift_pc);
311
312 *flag = 0;
313
314 if (cam.vz != 0) {
315 sxy0->vx = (int)((cam.vx * gtegeomscrn_pc) / cam.vz);
316 sxy0->vy = (int)((cam.vy * gtegeomscrn_pc) / cam.vz);
317 } else {
318 // To force an error and hence an illegal polygon
319 sxy0->vx = 2048;
320 sxy0->vy = 2048;
321 }
322
323 cam.vz >>= gtescreenscaleshift_pc;
324 *z = cam.vz / 4;
325
326 if (abs(sxy0->vx) > 1024)
327 *flag |= 0x80000000;
328 if (abs(sxy0->vy) > 1024)
329 *flag |= 0x80000000;
330
331 // set the value of flag : closer than h/2
332 if (cam.vz < 0)
333 *flag |= 0x80000000;
334 }
335
336 //------------------------------------------------------------------------
337
mygte_RotTransPers3_pc(SVECTORPC * in0,SVECTORPC * in1,SVECTORPC * in2,SVECTORPC * sxy0,SVECTORPC * sxy1,SVECTORPC * sxy2,int32 * p,int32 * flag,int32 * z)338 inline void mygte_RotTransPers3_pc(SVECTORPC *in0, SVECTORPC *in1, SVECTORPC *in2, SVECTORPC *sxy0, SVECTORPC *sxy1, SVECTORPC *sxy2, int32 *p, int32 *flag, int32 *z) {
339 int32 z0, z1, z2;
340 int32 p0, p1, p2;
341 int32 flag0, flag1, flag2;
342
343 mygte_RotTransPers_pc(in0, sxy0, &p0, &flag0, &z0);
344 mygte_RotTransPers_pc(in1, sxy1, &p1, &flag1, &z1);
345 mygte_RotTransPers_pc(in2, sxy2, &p2, &flag2, &z2);
346
347 // What GTE flags should we set ?
348 *flag = flag0 | flag1 | flag2;
349 *p = p2;
350 *z = z2;
351 }
352
353 //------------------------------------------------------------------------
354
myRotMatrix_gte_pc(SVECTOR * rot,MATRIXPC * m)355 inline void myRotMatrix_gte_pc(SVECTOR *rot, MATRIXPC *m) {
356 float ang0 = (float)rot->vx * 2.0f * myPI_PC / 4096;
357 MATRIXPC m0;
358 int32 c0 = myNINT_PC(ONE_PC * (float)cos(ang0));
359 int32 s0 = myNINT_PC(ONE_PC * (float)sin(ang0));
360 m0.m[0][0] = ONE_PC;
361 m0.m[0][1] = 0;
362 m0.m[0][2] = 0;
363
364 m0.m[1][0] = 0;
365 m0.m[1][1] = c0;
366 m0.m[1][2] = -s0;
367
368 m0.m[2][0] = 0;
369 m0.m[2][1] = s0;
370 m0.m[2][2] = c0;
371
372 float ang1 = (float)rot->vy * 2.0f * myPI_PC / 4096;
373 int32 c1 = myNINT_PC(ONE_PC * (float)cos(ang1));
374 int32 s1 = myNINT_PC(ONE_PC * (float)sin(ang1));
375 MATRIXPC m1;
376 m1.m[0][0] = c1;
377 m1.m[0][1] = 0;
378 m1.m[0][2] = s1;
379
380 m1.m[1][0] = 0;
381 m1.m[1][1] = ONE_PC;
382 m1.m[1][2] = 0;
383
384 m1.m[2][0] = -s1;
385 m1.m[2][1] = 0;
386 m1.m[2][2] = c1;
387
388 float ang2 = (float)rot->vz * 2.0f * myPI_PC / 4096;
389 int32 c2 = myNINT_PC(ONE_PC * (float)cos(ang2));
390 int32 s2 = myNINT_PC(ONE_PC * (float)sin(ang2));
391 MATRIXPC m2;
392
393 m2.m[0][0] = c2;
394 m2.m[0][1] = -s2;
395 m2.m[0][2] = 0;
396
397 m2.m[1][0] = s2;
398 m2.m[1][1] = c2;
399 m2.m[1][2] = 0;
400
401 m2.m[2][0] = 0;
402 m2.m[2][1] = 0;
403 m2.m[2][2] = ONE_PC;
404
405 mygte_MulMatrix0_pc(&m0, &m1, m);
406 mygte_MulMatrix0_pc(m, &m2, m);
407 }
408
409 //------------------------------------------------------------------------
410
mygte_SetBackColor_pc(int32 r,int32 g,int32 b)411 inline void mygte_SetBackColor_pc(int32 r, int32 g, int32 b) {
412 gteback_pc[0] = r;
413 gteback_pc[1] = g;
414 gteback_pc[2] = b;
415 }
416
417 //------------------------------------------------------------------------
418
mygte_SetColorMatrix_pc(MATRIXPC * m)419 inline void mygte_SetColorMatrix_pc(MATRIXPC *m) { *gtecolour_pc = *m; }
420
421 //------------------------------------------------------------------------
422
mygte_SetLightMatrix_pc(MATRIXPC * m)423 inline void mygte_SetLightMatrix_pc(MATRIXPC *m) { *gtelight_pc = *m; }
424
425 //------------------------------------------------------------------------
426
mygte_SetGeomScreen_pc(int32 h)427 inline void mygte_SetGeomScreen_pc(int32 h) { gtegeomscrn_pc = h; }
428
429 //------------------------------------------------------------------------
430
mygte_NormalColorCol_pc(SVECTOR * v0,CVECTOR * in0,CVECTOR * out0)431 inline void mygte_NormalColorCol_pc(SVECTOR *v0, CVECTOR *in0, CVECTOR *out0) {
432 SVECTORPC lightEffect;
433 // Normal line vector(local) -> light source effect
434 ApplyMatrixSV_pc(gtelight_pc, v0, &lightEffect);
435 if (lightEffect.vx < 0)
436 lightEffect.vx = 0;
437 if (lightEffect.vy < 0)
438 lightEffect.vy = 0;
439 if (lightEffect.vz < 0)
440 lightEffect.vz = 0;
441
442 // Light source effect -> Colour effect(local colour matrix+back colour)
443 SVECTORPC colourEffect;
444 ApplyMatrixSV_pc(gtecolour_pc, &lightEffect, &colourEffect);
445 if (colourEffect.vx < 0)
446 colourEffect.vx = 0;
447 if (colourEffect.vy < 0)
448 colourEffect.vy = 0;
449 if (colourEffect.vz < 0)
450 colourEffect.vz = 0;
451
452 // colourEffect is 0-ONE_PC (2^ONE_PC_SCALE)
453 // gteback is 0-255 (2^8)
454 colourEffect.vx = ((colourEffect.vx >> (ONE_PC_SCALE - 8)) + gteback_pc[0]);
455 colourEffect.vy = ((colourEffect.vy >> (ONE_PC_SCALE - 8)) + gteback_pc[1]);
456 colourEffect.vz = ((colourEffect.vz >> (ONE_PC_SCALE - 8)) + gteback_pc[2]);
457
458 // 256 = 1.0 in colourEffect
459 // 128 = 1.0 in in0
460 int32 red = ((in0->r * colourEffect.vx) >> 8);
461 int32 green = ((in0->g * colourEffect.vy) >> 8);
462 int32 blue = ((in0->b * colourEffect.vz) >> 8);
463
464 if (red > 255)
465 red = 255;
466 if (green > 255)
467 green = 255;
468 if (blue > 255)
469 blue = 255;
470
471 out0->r = (uint8)(red);
472 out0->g = (uint8)(green);
473 out0->b = (uint8)(blue);
474 }
475
476 //------------------------------------------------------------------------
477
mygte_NormalColorCol3_pc(SVECTOR * v0,SVECTOR * v1,SVECTOR * v2,CVECTOR * in0,CVECTOR * out0,CVECTOR * out1,CVECTOR * out2)478 inline void mygte_NormalColorCol3_pc(SVECTOR *v0, SVECTOR *v1, SVECTOR *v2, CVECTOR *in0, CVECTOR *out0, CVECTOR *out1, CVECTOR *out2) {
479 gte_NormalColorCol_pc(v0, in0, out0);
480 gte_NormalColorCol_pc(v1, in0, out1);
481 gte_NormalColorCol_pc(v2, in0, out2);
482 }
483
484 //------------------------------------------------------------------------
485
myVectorNormal_pc(VECTOR * in0,VECTOR * out0)486 inline int32 myVectorNormal_pc(VECTOR *in0, VECTOR *out0) {
487 int32 r2 = (in0->vx * in0->vx + in0->vy * in0->vy + in0->vz * in0->vz);
488 float r = (float)sqrt((float)r2) / (float)ONE_PC;
489
490 if (fabs(r) < 1.0e-6)
491 return 0;
492
493 out0->vx = (int32)((float)in0->vx / r);
494 out0->vy = (int32)((float)in0->vy / r);
495 out0->vz = (int32)((float)in0->vz / r);
496 return r2;
497 }
498
499 //////////////////////////////////////////////////////////////////////
500
mygte_NormalClip_pc(SVECTORPC * sxy0,SVECTORPC * sxy1,SVECTORPC * sxy2,int32 * flag)501 inline void mygte_NormalClip_pc(SVECTORPC *sxy0, SVECTORPC *sxy1, SVECTORPC *sxy2, int32 *flag) {
502 // compute the cross-product of (v1-v0) x (v2-v0)
503 int32 l0x = sxy1->vx - sxy0->vx;
504 int32 l0y = sxy1->vy - sxy0->vy;
505 int32 l1x = sxy2->vx - sxy0->vx;
506 int32 l1y = sxy2->vy - sxy0->vy;
507
508 *flag = ((l0x * l1y) - (l0y * l1x));
509 }
510
511 //------------------------------------------------------------------------
512
mygte_NormalClip_pc(SVECTOR * sxy0,SVECTOR * sxy1,SVECTOR * sxy2,int32 * flag)513 inline void mygte_NormalClip_pc(SVECTOR *sxy0, SVECTOR *sxy1, SVECTOR *sxy2, int32 *flag) {
514 // compute the cross-product of (v1-v0) x (v2-v0)
515 int32 l0x = sxy1->vx - sxy0->vx;
516 int32 l0y = sxy1->vy - sxy0->vy;
517 int32 l1x = sxy2->vx - sxy0->vx;
518 int32 l1y = sxy2->vy - sxy0->vy;
519
520 *flag = ((l0x * l1y) - (l0y * l1x));
521 }
522
523 //------------------------------------------------------------------------
524
mygte_AverageZ3_pc(int32 z0,int32 z1,int32 z2,int32 * sz)525 inline void mygte_AverageZ3_pc(int32 z0, int32 z1, int32 z2, int32 *sz) {
526 *sz = (z0 + z1 + z2) / 3;
527 *sz /= 4;
528 }
529
530 //------------------------------------------------------------------------
531
mygte_SetScreenScaleShift_pc(int32 shift)532 inline void mygte_SetScreenScaleShift_pc(int32 shift) { gtescreenscaleshift_pc = shift; }
533
534 //------------------------------------------------------------------------
535
536 } // End of namespace ICB
537
538 #endif // #ifndef __PC_CAPRI_MATHS_PC_H
539