vfpu.c

00001 /*
00002 
00003   Velocity  v1.5
00004   Copyright 2006, 2007 Gabriel Anderson
00005 
00006   This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019 
00020 */
00021 
00022 //---------------------------------------------------------------------------------//
00023 // Includes                                                                        //
00024 //---------------------------------------------------------------------------------//
00025 
00026 #include "vlib.h"
00027 
00028 //---------------------------------------------------------------------------------//
00029 // VFPU                                                                          //
00030 //---------------------------------------------------------------------------------//
00031 
00032 // Simple math functions
00033 float vfpu_sinf ( float rad ) {
00034   float result = 0;
00035   __asm__ volatile (
00036       "mtv  %1, S000\n"
00037       "vcst.s S001, VFPU_2_PI\n"
00038       "vmul.s S000, S000, S001\n"
00039       "vsin.s S000, S000\n"
00040       "mfv  %0, S000\n"
00041     : "=r" ( result ) : "r" ( rad ) );
00042   return result;
00043 }
00044 
00045 float vfpu_cosf ( float rad ) {
00046   float result = 0;
00047   __asm__ volatile (
00048       "mtv  %1, S000\n"
00049       "vcst.s S001, VFPU_2_PI\n"
00050       "vmul.s S000, S000, S001\n"
00051       "vcos.s S000, S000\n"
00052       "mfv  %0, S000\n"
00053     : "=r" ( result ) : "r" ( rad ) );
00054   return result;
00055 }
00056 
00057 float vfpu_tanf ( float x ) {
00058   float result;
00059   // result = sin(x)/cos(x);
00060   __asm__ volatile (
00061       "mtv      %1, S000\n"
00062       "vcst.s   S001, VFPU_2_PI\n"
00063       "vmul.s   S000, S000, S001\n"
00064       "vrot.p   C002, S000, [s, c]\n"
00065       "vdiv.s   S000, S002, S003\n"
00066       "mfv      %0, S000\n"
00067     : "=r" ( result ) : "r" ( x ) );
00068   return result;
00069 }
00070 
00071 float vfpu_sqrtf ( float x ) {
00072   float result = 0;
00073   __asm__ volatile (
00074       "mtv   %1, S000\n"
00075       "vsqrt.s S000, S000\n"
00076       "mfv   %0, S000\n"
00077     : "=r" ( result ) : "r" ( x ) );
00078   return result;
00079 }
00080 
00081 // Some functions for controlling the matrices
00082 // Need to finish these, test, and finally release a new vLib once these are pretty stable!
00083 void vfpu_identity_m ( ScePspFMatrix4 *m ) {
00084   __asm__ volatile (
00085       "vmidt.q  M000\n"
00086       "sv.q   C000, 0  + %0\n"
00087       "sv.q   C010, 16 + %0\n"
00088       "sv.q   C020, 32 + %0\n"
00089       "sv.q   C030, 48 + %0\n"
00090     : "=m" ( *m ) );
00091 }
00092 
00093 void vfpu_translate_m ( ScePspFMatrix4 *m, float x, float y, float z ) {
00094   __asm__ volatile (
00095       "mtv        %1, S030\n"
00096       "mtv        %2, S031\n"
00097       "mtv        %3, S032\n"
00098       "lv.q C100,  0 + %0\n"
00099       "lv.q C110, 16 + %0\n"
00100       "lv.q C120, 32 + %0\n"
00101       "lv.q C130, 48 + %0\n"
00102 
00103       "vscl.q C000, C100, S030\n"
00104       "vscl.q C010, C110, S031\n"
00105       "vscl.q C020, C120, S032\n"
00106 
00107       "vadd.q C130, C130, C000\n"
00108       "vadd.q C130, C130, C010\n"
00109       "vadd.q C130, C130, C020\n"
00110 
00111       "sv.q C130, 48 + %0\n"
00112     : "+m" ( *m ) : "r" ( x ), "r" ( y ), "r" ( z ) );
00113 }
00114 
00115 void vfpu_rotateX_m ( ScePspFMatrix4 *m, float x ) {
00116   __asm__ volatile (
00117       "lv.q    C200, 0  + %0\n"
00118       "lv.q    C210, 16 + %0\n"
00119       "lv.q    C220, 32 + %0\n"
00120       "lv.q    C230, 48 + %0\n"
00121       "mtv     %1, S130\n"
00122       "vmidt.q M000\n"
00123       "vcst.s  S101, VFPU_2_PI\n"
00124       "vmul.s  S130, S130, S101\n"
00125       "vrot.q  C010, S130, [ 0, c, s, 0]\n"
00126       "vrot.q  C020, S130, [ 0,-s, c, 0]\n"
00127       "vmmul.q M100, M200, M000\n"
00128       "sv.q    C100, 0  + %0\n"
00129       "sv.q    C110, 16 + %0\n"
00130       "sv.q    C120, 32 + %0\n"
00131       "sv.q    C130, 48 + %0\n"
00132     : "+m" ( *m ) : "r" ( x ) );
00133 }
00134 
00135 void vfpu_rotateY_m ( ScePspFMatrix4 *m, float y ) {
00136   __asm__ volatile (
00137       "lv.q    C200, 0  + %0\n"
00138       "lv.q    C210, 16 + %0\n"
00139       "lv.q    C220, 32 + %0\n"
00140       "lv.q    C230, 48 + %0\n"
00141       "mtv     %1, S130\n"
00142       "vmidt.q M000\n"
00143       "vcst.s  S101, VFPU_2_PI\n"
00144       "vmul.s  S130, S130, S101\n"
00145       "vrot.q  C000, S130, [ c, 0,-s, 0]\n"
00146       "vrot.q  C020, S130, [ s, 0, c, 0]\n"
00147       "vmmul.q M100, M200, M000\n"
00148       "sv.q    C100, 0  + %0\n"
00149       "sv.q    C110, 16 + %0\n"
00150       "sv.q    C120, 32 + %0\n"
00151       "sv.q    C130, 48 + %0\n"
00152     : "+m" ( *m ) : "r" ( y ) );
00153 }
00154 
00155 void vfpu_rotateZ_m ( ScePspFMatrix4 *m, float z ) {
00156   __asm__ volatile (
00157       "lv.q    C200, 0  + %0\n"
00158       "lv.q    C210, 16 + %0\n"
00159       "lv.q    C220, 32 + %0\n"
00160       "lv.q    C230, 48 + %0\n"
00161       "mtv     %1, S130\n"
00162       "vmidt.q M000\n"
00163       "vcst.s  S101, VFPU_2_PI\n"
00164       "vmul.s  S130, S130, S101\n"
00165       "vrot.q  C000, S130, [ c, s, 0, 0]\n"
00166       "vrot.q  C010, S130, [-s, c, 0, 0]\n"
00167       "vmmul.q M100, M200, M000\n"
00168       "sv.q    C100, 0  + %0\n"
00169       "sv.q    C110, 16 + %0\n"
00170       "sv.q    C120, 32 + %0\n"
00171       "sv.q    C130, 48 + %0\n"
00172     : "+m" ( *m ) : "r" ( z ) );
00173 }
00174 
00175 void vfpu_rotateXYZ_m ( ScePspFMatrix4 *m, float x, float y, float z ) {
00176   /*__asm__ volatile (
00177          "mtv     %1, S030\n"
00178          "vcst.s  S001, VFPU_2_PI\n"
00179          "vmul.s  S030, S030, S001\n"
00180          "vrot.q  C000, S030, [ c, s, 0, 0]\n"
00181          "vrot.q  C010, S030, [-s, c, 0, 0]\n"
00182          "sv.q    C000, 0  + %0\n"
00183          "sv.q    C010, 16 + %0\n"
00184          "sv.q    C020, 32 + %0\n"
00185          "sv.q    C030, 48 + %0\n"
00186          : "=m"(*m) : "r"(z));*/
00187 }
00188 
00189 void vfpu_rotateZYX_m ( ScePspFMatrix4 *m, float z, float y, float x ) {
00190   /*__asm__ volatile (
00191          "mtv     %1, S030\n"
00192          "vcst.s  S001, VFPU_2_PI\n"
00193          "vmul.s  S030, S030, S001\n"
00194          "vrot.q  C000, S030, [ c, s, 0, 0]\n"
00195          "vrot.q  C010, S030, [-s, c, 0, 0]\n"
00196          "sv.q    C000, 0  + %0\n"
00197          "sv.q    C010, 16 + %0\n"
00198          "sv.q    C020, 32 + %0\n"
00199          "sv.q    C030, 48 + %0\n"
00200          : "=m"(*m) : "r"(z));*/
00201 }
00202 
00203 void vfpu_scale_m ( ScePspFMatrix4 *m, float x, float y, float z ) {
00204   /*m->x.x *= x; m->x.y *= y; m->x.z *= z;
00205   m->y.x *= x; m->y.y *= y; m->y.z *= z;
00206   m->z.x *= x; m->z.y *= y; m->z.z *= z;
00207 
00208   __asm__ volatile (
00209     "vmidt.q M000\n"
00210     "mtv        %1, S030\n"
00211     "mtv        %2, S031\n"
00212     "mtv        %3, S032\n"
00213     "sv.q C000,  0 + %0\n"
00214     "sv.q C010, 16 + %0\n"
00215     "sv.q C020, 32 + %0\n"
00216     "sv.q C030, 48 + %0\n"
00217     : "=m"(*m) : "r"(x), "r"(y), "r"(z));*/
00218 }
00219 
00220 void vfpu_lookAt_m ( ScePspFMatrix4 *m, ScePspFVector3* eye, ScePspFVector3* center, ScePspFVector3* up ) {
00221   __asm__ volatile (
00222       "vmidt.q M100\n"
00223       // load eye, center, up vectors
00224       "ulv.q    C000, %0\n"
00225       "ulv.q    C010, %1\n"
00226       "ulv.q    C020, %2\n"
00227 
00228       // forward = center - eye
00229       "vsub.t  R102, C010, C000\n"
00230 
00231       // normalize forward
00232       "vdot.t  S033, R102, R102\n"
00233       "vrsq.s  S033, S033\n"
00234       "vscl.t  R102, R102, S033\n"
00235 
00236       // side = forward cross up
00237       "vcrsp.t R100, R102, C020\n"
00238       "vdot.t  S033, R100, R100\n"
00239       "vrsq.s  S033, S033\n"
00240       "vscl.t  R100, R100, S033\n"
00241 
00242       // lup = side cross forward
00243       "vcrsp.t R101, R100, R102\n"
00244       "vneg.t  R102, R102\n"
00245 
00246       "vmidt.q M000\n"
00247       "vneg.t  C230, C000\n"
00248       "vmmul.q M300, M100, M200\n"
00249     : : "m" ( *eye ), "m" ( *center ), "m" ( *up ) );
00250 }
00251 
00252 void vfpu_perspective_m ( ScePspFMatrix4 *m, float fovy, float aspect, float near, float far ) {
00253   __asm__ volatile (
00254       "vmzero.q M100\n"         // set M100 to all zeros
00255       "mtv     %1, S000\n"        // S000 = fovy
00256       "viim.s  S001, 90\n"        // S002 = 90.0f
00257       "vrcp.s  S001, S001\n"        // S002 = 1/90
00258       "vmul.s  S000, S000, S000[1/2]\n" // S000 = fovy * 0.5 = fovy/2
00259       "vmul.s  S000, S000, S001\n"    // S000 = (fovy/2)/90
00260       "vrot.p  C002, S000, [c, s]\n"    // S002 = cos(angle), S003 = sin(angle)
00261       "vdiv.s  S100, S002, S003\n"    // S100 = m->x.x = cotangent = cos(angle)/sin(angle)
00262       "mtv     %3, S001\n"        // S001 = near
00263       "mtv     %4, S002\n"        // S002 = far
00264       "vsub.s  S003, S001, S002\n"    // S003 = deltaz = near-far
00265       "vrcp.s  S003, S003\n"        // S003 = 1/deltaz
00266       "mtv     %2, S000\n"        // S000 = aspect
00267       "vmov.s  S111, S100\n"        // S111 = m->y.y = cotangent
00268       "vdiv.s  S100, S100, S000\n"    // S100 = m->x.x = cotangent / aspect
00269       "vadd.s  S122, S001, S002\n"        // S122 = m->z.z = far + near
00270       "vmul.s  S122, S122, S003\n"    // S122 = m->z.z = (far+near)/deltaz
00271       "vmul.s  S132, S001, S002\n"        // S132 = m->w.z = far * near
00272       "vmul.s  S132, S132, S132[2]\n"     // S132 = m->w.z = 2 * (far*near)
00273       "vmul.s  S132, S132, S003\n"        // S132 = m->w.z = 2 * (far*near) / deltaz
00274       "vsub.s   S123, S123, S123[1]\n"  // S123 = m->z.w = -1.0
00275       "sv.q  C100, 0  + %0\n"
00276       "sv.q  C110, 16 + %0\n"
00277       "sv.q  C120, 32 + %0\n"
00278       "sv.q  C130, 48 + %0\n"
00279     : "=m" ( *m ) : "r" ( fovy ), "r" ( aspect ), "r" ( near ), "r" ( far ) );
00280 }
00281 
00282 void vfpu_ortho_m ( ScePspFMatrix4 *m, float left, float right, float bottom, float top, float near, float far ) {
00283   __asm__ volatile (
00284       "vmidt.q M100\n"            // set M100 to identity
00285       "mtv     %2, S000\n"          // C000 = [right, ?,      ?,  ]
00286       "mtv     %4, S001\n"          // C000 = [right, top,    ?,  ]
00287       "mtv     %6, S002\n"          // C000 = [right, top,    far ]
00288       "mtv     %1, S010\n"          // C010 = [left,  ?,      ?,  ]
00289       "mtv     %3, S011\n"          // C010 = [left,  bottom, ?,  ]
00290       "mtv     %5, S012\n"                  // C010 = [left,  bottom, near]
00291       "vsub.t  C020, C000, C010\n"      // C020 = [  dx,   dy,   dz]
00292       "vrcp.t  C020, C020\n"                // C020 = [1/dx, 1/dy, 1/dz]
00293       "vmul.s  S100, S100[2], S020\n"       // S100 = m->x.x = 2.0 / dx
00294       "vmul.s  S111, S111[2], S021\n"       // S110 = m->y.y = 2.0 / dy
00295       "vmul.s  S122, S122[2], S022[-x]\n"   // S122 = m->z.z = -2.0 / dz
00296       "vsub.t  C130, C000[-x,-y,-z], C010\n"  // C130 = m->w[x, y, z] = [-(right+left), -(top+bottom), -(far+near)]
00297       // we do vsub here since -(a+b) => (-1*a) + (-1*b) => -a - b
00298       "vmul.t  C130, C130, C020\n"      // C130 = [-(right+left)/dx, -(top+bottom)/dy, -(far+near)/dz]
00299       "sv.q    C100, 0  + %0\n"
00300       "sv.q    C110, 16 + %0\n"
00301       "sv.q    C120, 32 + %0\n"
00302       "sv.q    C130, 48 + %0\n"
00303     : "=m" ( *m ) : "r" ( left ), "r" ( right ), "r" ( bottom ), "r" ( top ), "r" ( near ), "r" ( far ) );
00304 }

Generated on Tue Mar 20 23:01:06 2007 for vLib by  doxygen 1.4.7