PS2SDK
PS2 Homebrew Libraries
math3d.c
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # (c) 2005 Naomi Peori <naomi@peori.ca>
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
9 */
10 
11  #include <tamtypes.h>
12 
13  #include <graph.h>
14  #include <math3d.h>
15  #include <string.h>
16  #include <math.h>
17 
18  /* VECTOR FUNCTIONS */
19 
20  void vector_apply(VECTOR output, VECTOR input0, MATRIX input1) {
21  __asm__ __volatile__ (
22 #if __GNUC__ > 3
23  "lqc2 $vf1, 0x00(%2) \n"
24  "lqc2 $vf2, 0x10(%2) \n"
25  "lqc2 $vf3, 0x20(%2) \n"
26  "lqc2 $vf4, 0x30(%2) \n"
27  "lqc2 $vf5, 0x00(%1) \n"
28  "vmulaw $ACC, $vf4, $vf0\n"
29  "vmaddax $ACC, $vf1, $vf5\n"
30  "vmadday $ACC, $vf2, $vf5\n"
31  "vmaddz $vf6, $vf3, $vf5\n"
32  "sqc2 $vf6, 0x00(%0) \n"
33 #else
34  "lqc2 vf1, 0x00(%2) \n"
35  "lqc2 vf2, 0x10(%2) \n"
36  "lqc2 vf3, 0x20(%2) \n"
37  "lqc2 vf4, 0x30(%2) \n"
38  "lqc2 vf5, 0x00(%1) \n"
39  "vmulaw ACC, vf4, vf0 \n"
40  "vmaddax ACC, vf1, vf5 \n"
41  "vmadday ACC, vf2, vf5 \n"
42  "vmaddz vf6, vf3, vf5 \n"
43  "sqc2 vf6, 0x00(%0) \n"
44 #endif
45  : : "r" (output), "r" (input0), "r" (input1)
46  : "memory"
47  );
48  }
49 
50  void vector_clamp(VECTOR output, VECTOR input0, float min, float max) {
51  VECTOR work;
52 
53  // Copy the vector.
54  vector_copy(work, input0);
55 
56  // Clamp the minimum values.
57  if (work[0] < min) { work[0] = min; }
58  if (work[1] < min) { work[1] = min; }
59  if (work[2] < min) { work[2] = min; }
60  if (work[3] < min) { work[3] = min; }
61 
62  // Clamp the maximum values.
63  if (work[0] > max) { work[0] = max; }
64  if (work[1] > max) { work[1] = max; }
65  if (work[2] > max) { work[2] = max; }
66  if (work[3] > max) { work[3] = max; }
67 
68  // Output the result.
69  vector_copy(output, work);
70 
71  }
72 
73  void vector_copy(VECTOR output, VECTOR input0) {
74  __asm__ __volatile__ (
75 #if __GNUC__ > 3
76  "lqc2 $vf1, 0x00(%1) \n"
77  "sqc2 $vf1, 0x00(%0) \n"
78 #else
79  "lqc2 vf1, 0x00(%1) \n"
80  "sqc2 vf1, 0x00(%0) \n"
81 #endif
82  : : "r" (output), "r" (input0)
83  : "memory"
84  );
85  }
86 
87  float vector_innerproduct(VECTOR input0, VECTOR input1) {
88  VECTOR work0, work1;
89 
90  // Normalize the first vector.
91  work0[0] = (input0[0] / input0[3]);
92  work0[1] = (input0[1] / input0[3]);
93  work0[2] = (input0[2] / input0[3]);
94  work0[3] = 1.00f;
95 
96  // Normalize the second vector.
97  work1[0] = (input1[0] / input1[3]);
98  work1[1] = (input1[1] / input1[3]);
99  work1[2] = (input1[2] / input1[3]);
100  work1[3] = 1.00f;
101 
102  // Return the inner product.
103  return (work0[0] * work1[0]) + (work0[1] * work1[1]) + (work0[2] * work1[2]);
104 
105  }
106 
107  void vector_multiply(VECTOR output, VECTOR input0, VECTOR input1) {
108  VECTOR work;
109 
110  // Multiply the vectors together.
111  work[0] = input0[0] * input1[0];
112  work[1] = input0[1] * input1[1];
113  work[2] = input0[2] * input1[2];
114  work[3] = input0[3] * input1[3];
115 
116  // Output the result.
117  vector_copy(output, work);
118 
119  }
120 
121  void vector_normalize(VECTOR output, VECTOR input0) {
122  __asm__ __volatile__ (
123 #if __GNUC__ > 3
124  "lqc2 $vf1, 0x00(%1) \n"
125  "vmul.xyz $vf2, $vf1, $vf1\n"
126  "vmulax.w $ACC, $vf0, $vf2\n"
127  "vmadday.w $ACC, $vf0, $vf2\n"
128  "vmaddz.w $vf2, $vf0, $vf2\n"
129  "vrsqrt $Q, $vf0w, $vf2w\n"
130  "vsub.w $vf1, $vf0, $vf0\n"
131  "vwaitq \n"
132  "vmulq.xyz $vf1, $vf1, $Q \n"
133  "sqc2 $vf1, 0x00(%0) \n"
134 #else
135  "lqc2 vf1, 0x00(%1) \n"
136  "vmul.xyz vf2, vf1, vf1 \n"
137  "vmulax.w ACC, vf0, vf2 \n"
138  "vmadday.w ACC, vf0, vf2 \n"
139  "vmaddz.w vf2, vf0, vf2 \n"
140  "vrsqrt Q, vf0w, vf2w \n"
141  "vsub.w vf1, vf0, vf0 \n"
142  "vwaitq \n"
143  "vmulq.xyz vf1, vf1, Q \n"
144  "sqc2 vf1, 0x00(%0) \n"
145 #endif
146  : : "r" (output), "r" (input0)
147  : "memory"
148  );
149  }
150 
151  void vector_outerproduct(VECTOR output, VECTOR input0, VECTOR input1) {
152  __asm__ __volatile__ (
153 #if __GNUC__ > 3
154  "lqc2 $vf1, 0x00(%1) \n"
155  "lqc2 $vf2, 0x00(%2) \n"
156  "vopmula.xyz $ACC, $vf1, $vf2\n"
157  "vopmsub.xyz $vf2, $vf2, $vf1\n"
158  "vsub.w $vf2, $vf0, $vf0\n"
159  "sqc2 $vf2, 0x00(%0) \n"
160 #else
161  "lqc2 vf1, 0x00(%1) \n"
162  "lqc2 vf2, 0x00(%2) \n"
163  "vopmula.xyz ACC, vf1, vf2 \n"
164  "vopmsub.xyz vf2, vf2, vf1 \n"
165  "vsub.w vf2, vf0, vf0 \n"
166  "sqc2 vf2, 0x00(%0) \n"
167 #endif
168  : : "r" (output), "r" (input0), "r" (input1)
169  : "memory"
170  );
171  }
172 
173  void vector_add(VECTOR sum, VECTOR addend, VECTOR summand) {
174  VECTOR work;
175  work[0] = addend[0]+summand[0];
176  work[1] = addend[1]+summand[1];
177  work[2] = addend[2]+summand[2];
178  work[3] = addend[3]+summand[3];
179  vector_copy(sum, work);
180 }
181 
182 void vector_cross_product(VECTOR product, VECTOR multiplicand, VECTOR multiplier) {
183  VECTOR work;
184  work[0] = multiplicand[1] * multiplier[2] - multiplicand[2] * multiplier[1];
185  work[1] = multiplicand[2] * multiplier[0] - multiplicand[0] * multiplier[2];
186  work[2] = multiplicand[0] * multiplier[1] - multiplicand[1] * multiplier[0];
187  work[3] = 1.0f;
188  vector_copy(product, work);
189 }
190 
191 void vector_triangle_normal(VECTOR output, VECTOR a, VECTOR b, VECTOR c) {
192  VECTOR ac;
193  VECTOR bc;
194  VECTOR ac_bc;
195  VECTOR triangle_normal;
196 
197  vector_add(ac, a, c);
198  vector_add(bc, b, c);
199  vector_cross_product(ac_bc, ac, bc);
200  vector_normalize(triangle_normal, ac_bc);
201 
202  vector_copy(output, triangle_normal);
203 }
204 
205  /* MATRIX FUNCTIONS */
206 
207  void matrix_copy(MATRIX output, MATRIX input0) {
208  __asm__ __volatile__ (
209 #if __GNUC__ > 3
210  "lqc2 $vf1, 0x00(%1) \n"
211  "lqc2 $vf2, 0x10(%1) \n"
212  "lqc2 $vf3, 0x20(%1) \n"
213  "lqc2 $vf4, 0x30(%1) \n"
214  "sqc2 $vf1, 0x00(%0) \n"
215  "sqc2 $vf2, 0x10(%0) \n"
216  "sqc2 $vf3, 0x20(%0) \n"
217  "sqc2 $vf4, 0x30(%0) \n"
218 #else
219  "lqc2 vf1, 0x00(%1) \n"
220  "lqc2 vf2, 0x10(%1) \n"
221  "lqc2 vf3, 0x20(%1) \n"
222  "lqc2 vf4, 0x30(%1) \n"
223  "sqc2 vf1, 0x00(%0) \n"
224  "sqc2 vf2, 0x10(%0) \n"
225  "sqc2 vf3, 0x20(%0) \n"
226  "sqc2 vf4, 0x30(%0) \n"
227 #endif
228  : : "r" (output), "r" (input0)
229  : "memory"
230  );
231  }
232 
233  void matrix_inverse(MATRIX output, MATRIX input0) {
234  MATRIX work;
235 
236  // Calculate the inverse of the matrix.
237  matrix_transpose(work, input0);
238  work[0x03] = 0.00f;
239  work[0x07] = 0.00f;
240  work[0x0B] = 0.00f;
241  work[0x0C] = -(input0[0x0C] * work[0x00] + input0[0x0D] * work[0x04] + input0[0x0E] * work[0x08]);
242  work[0x0D] = -(input0[0x0C] * work[0x01] + input0[0x0D] * work[0x05] + input0[0x0E] * work[0x09]);
243  work[0x0E] = -(input0[0x0C] * work[0x02] + input0[0x0D] * work[0x06] + input0[0x0E] * work[0x0A]);
244  work[0x0F] = 1.00f;
245 
246  // Output the result.
247  matrix_copy(output, work);
248 
249  }
250 
251  void matrix_multiply(MATRIX output, MATRIX input0, MATRIX input1) {
252  __asm__ __volatile__ (
253 #if __GNUC__ > 3
254  "lqc2 $vf1, 0x00(%1) \n"
255  "lqc2 $vf2, 0x10(%1) \n"
256  "lqc2 $vf3, 0x20(%1) \n"
257  "lqc2 $vf4, 0x30(%1) \n"
258  "lqc2 $vf5, 0x00(%2) \n"
259  "lqc2 $vf6, 0x10(%2) \n"
260  "lqc2 $vf7, 0x20(%2) \n"
261  "lqc2 $vf8, 0x30(%2) \n"
262  "vmulax.xyzw $ACC, $vf5, $vf1\n"
263  "vmadday.xyzw $ACC, $vf6, $vf1\n"
264  "vmaddaz.xyzw $ACC, $vf7, $vf1\n"
265  "vmaddw.xyzw $vf1, $vf8, $vf1\n"
266  "vmulax.xyzw $ACC, $vf5, $vf2\n"
267  "vmadday.xyzw $ACC, $vf6, $vf2\n"
268  "vmaddaz.xyzw $ACC, $vf7, $vf2\n"
269  "vmaddw.xyzw $vf2, $vf8, $vf2\n"
270  "vmulax.xyzw $ACC, $vf5, $vf3\n"
271  "vmadday.xyzw $ACC, $vf6, $vf3\n"
272  "vmaddaz.xyzw $ACC, $vf7, $vf3\n"
273  "vmaddw.xyzw $vf3, $vf8, $vf3\n"
274  "vmulax.xyzw $ACC, $vf5, $vf4\n"
275  "vmadday.xyzw $ACC, $vf6, $vf4\n"
276  "vmaddaz.xyzw $ACC, $vf7, $vf4\n"
277  "vmaddw.xyzw $vf4, $vf8, $vf4\n"
278  "sqc2 $vf1, 0x00(%0) \n"
279  "sqc2 $vf2, 0x10(%0) \n"
280  "sqc2 $vf3, 0x20(%0) \n"
281  "sqc2 $vf4, 0x30(%0) \n"
282 #else
283  "lqc2 vf1, 0x00(%1) \n"
284  "lqc2 vf2, 0x10(%1) \n"
285  "lqc2 vf3, 0x20(%1) \n"
286  "lqc2 vf4, 0x30(%1) \n"
287  "lqc2 vf5, 0x00(%2) \n"
288  "lqc2 vf6, 0x10(%2) \n"
289  "lqc2 vf7, 0x20(%2) \n"
290  "lqc2 vf8, 0x30(%2) \n"
291  "vmulax.xyzw ACC, vf5, vf1 \n"
292  "vmadday.xyzw ACC, vf6, vf1 \n"
293  "vmaddaz.xyzw ACC, vf7, vf1 \n"
294  "vmaddw.xyzw vf1, vf8, vf1 \n"
295  "vmulax.xyzw ACC, vf5, vf2 \n"
296  "vmadday.xyzw ACC, vf6, vf2 \n"
297  "vmaddaz.xyzw ACC, vf7, vf2 \n"
298  "vmaddw.xyzw vf2, vf8, vf2 \n"
299  "vmulax.xyzw ACC, vf5, vf3 \n"
300  "vmadday.xyzw ACC, vf6, vf3 \n"
301  "vmaddaz.xyzw ACC, vf7, vf3 \n"
302  "vmaddw.xyzw vf3, vf8, vf3 \n"
303  "vmulax.xyzw ACC, vf5, vf4 \n"
304  "vmadday.xyzw ACC, vf6, vf4 \n"
305  "vmaddaz.xyzw ACC, vf7, vf4 \n"
306  "vmaddw.xyzw vf4, vf8, vf4 \n"
307  "sqc2 vf1, 0x00(%0) \n"
308  "sqc2 vf2, 0x10(%0) \n"
309  "sqc2 vf3, 0x20(%0) \n"
310  "sqc2 vf4, 0x30(%0) \n"
311 #endif
312  : : "r" (output), "r" (input0), "r" (input1)
313  : "memory"
314  );
315  }
316 
317  void matrix_rotate(MATRIX output, MATRIX input0, VECTOR input1) {
318  MATRIX work;
319 
320  // Apply the z-axis rotation.
321  matrix_unit(work);
322  work[0x00] = cosf(input1[2]);
323  work[0x01] = sinf(input1[2]);
324  work[0x04] = -sinf(input1[2]);
325  work[0x05] = cosf(input1[2]);
326  matrix_multiply(output, input0, work);
327 
328  // Apply the y-axis rotation.
329  matrix_unit(work);
330  work[0x00] = cosf(input1[1]);
331  work[0x02] = -sinf(input1[1]);
332  work[0x08] = sinf(input1[1]);
333  work[0x0A] = cosf(input1[1]);
334  matrix_multiply(output, output, work);
335 
336  // Apply the x-axis rotation.
337  matrix_unit(work);
338  work[0x05] = cosf(input1[0]);
339  work[0x06] = sinf(input1[0]);
340  work[0x09] = -sinf(input1[0]);
341  work[0x0A] = cosf(input1[0]);
342  matrix_multiply(output, output, work);
343 
344  }
345 
346  void matrix_scale(MATRIX output, MATRIX input0, VECTOR input1) {
347  MATRIX work;
348 
349  // Apply the scaling.
350  matrix_unit(work);
351  work[0x00] = input1[0];
352  work[0x05] = input1[1];
353  work[0x0A] = input1[2];
354  matrix_multiply(output, input0, work);
355 
356  }
357 
358  void matrix_translate(MATRIX output, MATRIX input0, VECTOR input1) {
359  MATRIX work;
360 
361  // Apply the translation.
362  matrix_unit(work);
363  work[0x0C] = input1[0];
364  work[0x0D] = input1[1];
365  work[0x0E] = input1[2];
366  matrix_multiply(output, input0, work);
367 
368  }
369 
370  void matrix_transpose(MATRIX output, MATRIX input0) {
371  MATRIX work;
372 
373  // Transpose the matrix.
374  work[0x00] = input0[0x00];
375  work[0x01] = input0[0x04];
376  work[0x02] = input0[0x08];
377  work[0x03] = input0[0x0C];
378  work[0x04] = input0[0x01];
379  work[0x05] = input0[0x05];
380  work[0x06] = input0[0x09];
381  work[0x07] = input0[0x0D];
382  work[0x08] = input0[0x02];
383  work[0x09] = input0[0x06];
384  work[0x0A] = input0[0x0A];
385  work[0x0B] = input0[0x0E];
386  work[0x0C] = input0[0x03];
387  work[0x0D] = input0[0x07];
388  work[0x0E] = input0[0x0B];
389  work[0x0F] = input0[0x0F];
390 
391  // Output the result.
392  matrix_copy(output, work);
393 
394  }
395 
396  void matrix_unit(MATRIX output) {
397 
398  // Create a unit matrix.
399  memset(output, 0, sizeof(MATRIX));
400  output[0x00] = 1.00f;
401  output[0x05] = 1.00f;
402  output[0x0A] = 1.00f;
403  output[0x0F] = 1.00f;
404 
405  }
406 
407  /* CREATE FUNCTIONS */
408 
409  void create_local_world(MATRIX local_world, VECTOR translation, VECTOR rotation) {
410 
411  // Create the local_world matrix.
412  matrix_unit(local_world);
413  matrix_rotate(local_world, local_world, rotation);
414  matrix_translate(local_world, local_world, translation);
415 
416  }
417 
418  void create_local_light(MATRIX local_light, VECTOR rotation) {
419 
420  // Create the local_light matrix.
421  matrix_unit(local_light);
422  matrix_rotate(local_light, local_light, rotation);
423 
424  }
425 
426  void create_world_view(MATRIX world_view, VECTOR translation, VECTOR rotation) {
427  VECTOR work0, work1;
428 
429  // Reverse the translation.
430  work0[0] = -translation[0];
431  work0[1] = -translation[1];
432  work0[2] = -translation[2];
433  work0[3] = translation[3];
434 
435  // Reverse the rotation.
436  work1[0] = -rotation[0];
437  work1[1] = -rotation[1];
438  work1[2] = -rotation[2];
439  work1[3] = rotation[3];
440 
441  // Create the world_view matrix.
442  matrix_unit(world_view);
443  matrix_translate(world_view, world_view, work0);
444  matrix_rotate(world_view, world_view, work1);
445 
446  }
447 
448  void create_view_screen(MATRIX view_screen, float aspect, float left, float right, float bottom, float top, float near, float far) {
449 
450  // Apply the aspect ratio adjustment.
451  left = (left * aspect); right = (right * aspect);
452 
453  // Create the view_screen matrix.
454  matrix_unit(view_screen);
455  view_screen[0x00] = (2 * near) / (right - left);
456  view_screen[0x05] = (2 * near) / (top - bottom);
457  view_screen[0x08] = (right + left) / (right - left);
458  view_screen[0x09] = (top + bottom) / (top - bottom);
459  view_screen[0x0A] = (far + near) / (far - near);
460  view_screen[0x0B] = -1.00f;
461  view_screen[0x0E] = (2 * far * near) / (far - near);
462  view_screen[0x0F] = 0.00f;
463 
464  }
465 
466  void create_local_screen(MATRIX local_screen, MATRIX local_world, MATRIX world_view, MATRIX view_screen) {
467 
468  // Create the local_screen matrix.
469  matrix_unit(local_screen);
470  matrix_multiply(local_screen, local_screen, local_world);
471  matrix_multiply(local_screen, local_screen, world_view);
472  matrix_multiply(local_screen, local_screen, view_screen);
473 
474  }
475 
476  /* CALCULATE FUNCTIONS */
477 
478  void calculate_normals(VECTOR *output, int count, VECTOR *normals, MATRIX local_light) {
479  __asm__ __volatile__ (
480 #if __GNUC__ > 3
481  "lqc2 $vf1, 0x00(%3) \n"
482  "lqc2 $vf2, 0x10(%3) \n"
483  "lqc2 $vf3, 0x20(%3) \n"
484  "lqc2 $vf4, 0x30(%3) \n"
485  "1: \n"
486  "lqc2 $vf6, 0x00(%2) \n"
487  "vmulaw $ACC, $vf4, $vf0\n"
488  "vmaddax $ACC, $vf1, $vf6\n"
489  "vmadday $ACC, $vf2, $vf6\n"
490  "vmaddz $vf7, $vf3, $vf6\n"
491  "vdiv $Q, $vf0w, $vf7w\n"
492  "vwaitq \n"
493  "vmulq.xyzw $vf7, $vf7, $Q \n"
494  "sqc2 $vf7, 0x00(%0) \n"
495  "addi %0, 0x10 \n"
496  "addi %2, 0x10 \n"
497  "addi %1, -1 \n"
498  "bne $0, %1, 1b \n"
499 #else
500  "lqc2 vf1, 0x00(%3) \n"
501  "lqc2 vf2, 0x10(%3) \n"
502  "lqc2 vf3, 0x20(%3) \n"
503  "lqc2 vf4, 0x30(%3) \n"
504  "1: \n"
505  "lqc2 vf6, 0x00(%2) \n"
506  "vmulaw ACC, vf4, vf0 \n"
507  "vmaddax ACC, vf1, vf6 \n"
508  "vmadday ACC, vf2, vf6 \n"
509  "vmaddz vf7, vf3, vf6 \n"
510  "vdiv Q, vf0w, vf7w \n"
511  "vwaitq \n"
512  "vmulq.xyzw vf7, vf7, Q \n"
513  "sqc2 vf7, 0x00(%0) \n"
514  "addi %0, 0x10 \n"
515  "addi %2, 0x10 \n"
516  "addi %1, -1 \n"
517  "bne $0, %1, 1b \n"
518 #endif
519  : "+r" (output), "+r" (count), "+r" (normals) : "r" (local_light)
520  : "memory"
521  );
522  }
523 
524  void calculate_lights(VECTOR *output, int count, VECTOR *normals, VECTOR *light_direction, VECTOR *light_colour, const int *light_type, int light_count) {
525  int loop0, loop1; float intensity;
526 
527  // Clear the output values.
528  memset(output, 0, sizeof(VECTOR) * count);
529 
530  // For each normal...
531  for (loop0=0;loop0<count;loop0++) {
532 
533  // For each light...
534  for (loop1=0;loop1<light_count;loop1++) {
535 
536  // If this is an ambient light...
537  if (light_type[loop1] == LIGHT_AMBIENT) {
538 
539  // Set the intensity to full.
540  intensity = 1.00f;
541 
542  // Else, if this is a directional light...
543  } else if (light_type[loop1] == LIGHT_DIRECTIONAL) {
544 
545  // Get the light intensity.
546  intensity = -vector_innerproduct(normals[loop0], light_direction[loop1]);
547 
548  // Clamp the minimum intensity.
549  if (intensity < 0.00f) { intensity = 0.00f; }
550 
551  // Else, this is an invalid light type.
552  } else { intensity = 0.00f; }
553 
554  // If the light has intensity...
555  if (intensity > 0.00f) {
556 
557  // Add the light value.
558  output[loop0][0] += (light_colour[loop1][0] * intensity);
559  output[loop0][1] += (light_colour[loop1][1] * intensity);
560  output[loop0][2] += (light_colour[loop1][2] * intensity);
561  output[loop0][3] = 1.00f;
562 
563  }
564 
565  }
566 
567  }
568 
569  }
570 
571  void calculate_colours(VECTOR *output, int count, VECTOR *colours, VECTOR *lights) {
572  int loop0;
573 
574  // For each colour...
575  for (loop0=0;loop0<count;loop0++) {
576 
577  // Apply the light value to the colour.
578  output[loop0][0] = (colours[loop0][0] * lights[loop0][0]);
579  output[loop0][1] = (colours[loop0][1] * lights[loop0][1]);
580  output[loop0][2] = (colours[loop0][2] * lights[loop0][2]);
581 
582  // Clamp the colour value.
583  vector_clamp(output[loop0], output[loop0], 0.00f, 1.99f);
584 
585  }
586 
587  }
588 
589  void calculate_vertices(VECTOR *output, int count, VECTOR *vertices, MATRIX local_screen) {
590  __asm__ __volatile__ (
591 #if __GNUC__ > 3
592  "lqc2 $vf1, 0x00(%3) \n"
593  "lqc2 $vf2, 0x10(%3) \n"
594  "lqc2 $vf3, 0x20(%3) \n"
595  "lqc2 $vf4, 0x30(%3) \n"
596  "1: \n"
597  "lqc2 $vf6, 0x00(%2) \n"
598  "vmulaw $ACC, $vf4, $vf0\n"
599  "vmaddax $ACC, $vf1, $vf6\n"
600  "vmadday $ACC, $vf2, $vf6\n"
601  "vmaddz $vf7, $vf3, $vf6\n"
602  "vclipw.xyz $vf7, $vf7 \n" // FIXME: Clip detection is still kinda broken.
603  "vnop \n"
604  "vnop \n"
605  "vnop \n"
606  "vnop \n"
607  "cfc2 $10, $18 \n"
608  "beq $10, $0, 3f \n"
609  "2: \n"
610  "sqc2 $0, 0x00(%0) \n"
611  "j 4f \n"
612  "3: \n"
613  "vdiv $Q, $vf0w, $vf7w\n"
614  "vwaitq \n"
615  "vmulq.xyz $vf7, $vf7, $Q \n"
616  "sqc2 $vf7, 0x00(%0) \n"
617 #else
618  "lqc2 vf1, 0x00(%3) \n"
619  "lqc2 vf2, 0x10(%3) \n"
620  "lqc2 vf3, 0x20(%3) \n"
621  "lqc2 vf4, 0x30(%3) \n"
622  "1: \n"
623  "lqc2 vf6, 0x00(%2) \n"
624  "vmulaw ACC, vf4, vf0 \n"
625  "vmaddax ACC, vf1, vf6 \n"
626  "vmadday ACC, vf2, vf6 \n"
627  "vmaddz vf7, vf3, vf6 \n"
628  "vclipw.xyz vf7, vf7 \n"
629  "vnop \n"
630  "vnop \n"
631  "vnop \n"
632  "vnop \n" // FIXME: Clip detection is still kinda broken.
633  "cfc2 $10, $18 \n"
634  "beq $10, $0, 3f \n"
635  "2: \n"
636  "sqc2 vi00, 0x00(%0) \n"
637  "j 4f \n"
638  "3: \n"
639  "vdiv Q, vf0w, vf7w \n"
640  "vwaitq \n"
641  "vmulq.xyz vf7, vf7, Q \n"
642  "sqc2 vf7, 0x00(%0) \n"
643 #endif
644  "4: \n"
645  "addi %0, 0x10 \n"
646  "addi %2, 0x10 \n"
647  "addi %1, -1 \n"
648  "bne $0, %1, 1b \n"
649  : "+r" (output), "+r" (count), "+r" (vertices) : "r" (local_screen)
650  : "$10", "memory"
651  );
652  }
vector_normalize
void vector_normalize(VECTOR output, VECTOR input0)
Definition: math3d.c:121
calculate_colours
void calculate_colours(VECTOR *output, int count, VECTOR *colours, VECTOR *lights)
Definition: math3d.c:571
create_local_screen
void create_local_screen(MATRIX local_screen, MATRIX local_world, MATRIX world_view, MATRIX view_screen)
Definition: math3d.c:466
LIGHT_AMBIENT
#define LIGHT_AMBIENT
Definition: math3d.h:115
calculate_vertices
void calculate_vertices(VECTOR *output, int count, VECTOR *vertices, MATRIX local_screen)
Definition: math3d.c:589
matrix_translate
void matrix_translate(MATRIX output, MATRIX input0, VECTOR input1)
Definition: math3d.c:358
LIGHT_DIRECTIONAL
#define LIGHT_DIRECTIONAL
Definition: math3d.h:117
vector_clamp
void vector_clamp(VECTOR output, VECTOR input0, float min, float max)
Definition: math3d.c:50
vector_apply
void vector_apply(VECTOR output, VECTOR input0, MATRIX input1)
Definition: math3d.c:20
vector_outerproduct
void vector_outerproduct(VECTOR output, VECTOR input0, VECTOR input1)
Definition: math3d.c:151
calculate_lights
void calculate_lights(VECTOR *output, int count, VECTOR *normals, VECTOR *light_directions, VECTOR *light_colours, const int *light_types, int light_count)
Definition: math3d.c:524
vector_multiply
void vector_multiply(VECTOR output, VECTOR input0, VECTOR input1)
Definition: math3d.c:107
matrix_rotate
void matrix_rotate(MATRIX output, MATRIX input0, VECTOR input1)
Definition: math3d.c:317
count
u32 count
start sector of fragmented bd/file
Definition: usbhdfsd-common.h:3
create_local_light
void create_local_light(MATRIX local_light, VECTOR rotation)
Definition: math3d.c:418
matrix_copy
void matrix_copy(MATRIX output, MATRIX input0)
Definition: math3d.c:207
vector_triangle_normal
void vector_triangle_normal(VECTOR output, VECTOR a, VECTOR b, VECTOR c)
Definition: math3d.c:191
math3d.h
vector_innerproduct
float vector_innerproduct(VECTOR input0, VECTOR input1)
Definition: math3d.c:87
tamtypes.h
matrix_inverse
void matrix_inverse(MATRIX output, MATRIX input0)
Definition: math3d.c:233
calculate_normals
void calculate_normals(VECTOR *output, int count, VECTOR *normals, MATRIX local_light)
Definition: math3d.c:478
matrix_unit
void matrix_unit(MATRIX output)
Definition: math3d.c:396
graph.h
matrix_multiply
void matrix_multiply(MATRIX output, MATRIX input0, MATRIX input1)
Definition: math3d.c:251
vector_copy
void vector_copy(VECTOR output, VECTOR input0)
Definition: math3d.c:73
create_view_screen
void create_view_screen(MATRIX view_screen, float aspect, float left, float right, float bottom, float top, float near, float far)
Definition: math3d.c:448
matrix_scale
void matrix_scale(MATRIX output, MATRIX input0, VECTOR input1)
Definition: math3d.c:346
vector_cross_product
void vector_cross_product(VECTOR product, VECTOR multiplicand, VECTOR multiplier)
Definition: math3d.c:182
create_local_world
void create_local_world(MATRIX local_world, VECTOR translation, VECTOR rotation)
Definition: math3d.c:409
create_world_view
void create_world_view(MATRIX world_view, VECTOR translation, VECTOR rotation)
Definition: math3d.c:426
vector_add
void vector_add(VECTOR sum, VECTOR addend, VECTOR summand)
Definition: math3d.c:173
matrix_transpose
void matrix_transpose(MATRIX output, MATRIX input0)
Definition: math3d.c:370