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