math.inc 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. (*
  2. $Id: math.inc 25 2007-12-10 21:06:46Z p4p3r0 $
  3. ------------------------------------------------------------------------------
  4. Copyright (C) 2005
  5. Jason Rogers (dovoto)
  6. Dave Murphy (WinterMute)
  7. This software is provided 'as-is', without any express or implied
  8. warranty. In no event will the authors be held liable for any
  9. damages arising from the use of this software.
  10. Permission is granted to anyone to use this software for any
  11. purpose, including commercial applications, and to alter it and
  12. redistribute it freely, subject to the following restrictions:
  13. 1. The origin of this software must not be misrepresented; you
  14. must not claim that you wrote the original software. If you use
  15. this software in a product, an acknowledgment in the product
  16. documentation would be appreciated but is not required.
  17. 2. Altered source versions must be plainly marked as such, and
  18. must not be misrepresented as being the original software.
  19. 3. This notice may not be removed or altered from any source
  20. distribution.
  21. ------------------------------------------------------------------------------
  22. Conversion by Legolas (http://itaprogaming.free.fr) for freepascal compiler
  23. (http://www.freepascal.org)
  24. Copyright (C) 2006 Francesco Lombardi
  25. Check http://sourceforge.net/projects/libndsfpc for updates
  26. ------------------------------------------------------------------------------
  27. $Log$
  28. *)
  29. {$ifdef NDS_INTERFACE}
  30. // Math coprocessor register definitions
  31. const
  32. DIV_CR : pcuint16 = pointer($04000280);
  33. DIV_NUMERATOR64 : pcint64 = pointer($04000290);
  34. DIV_NUMERATOR32 : pcint32 = pointer($04000290);
  35. DIV_DENOMINATOR64 : pcint64 = pointer($04000298);
  36. DIV_DENOMINATOR32 : pcint32 = pointer($04000298);
  37. DIV_RESULT64 : pcint64 = pointer($040002A0);
  38. DIV_RESULT32 : pcint32 = pointer($040002A0);
  39. DIV_REMAINDER64 : pcint64 = pointer($040002A8);
  40. DIV_REMAINDER32 : pcint32 = pointer($040002A8);
  41. SQRT_CR : pcuint16 = pointer($040002B0);
  42. SQRT_PARAM64 : pcint64 = pointer($040002B8);
  43. SQRT_RESULT32 : pcint32 = pointer($040002B4);
  44. SQRT_PARAM32 : pcint32 = pointer($040002B8);
  45. // Math coprocessor modes
  46. DIV_64_64 = 2;
  47. DIV_64_32 = 1;
  48. DIV_32_32 = 0;
  49. DIV_BUSY = (1 shl 15);
  50. SQRT_64 = 1;
  51. SQRT_32 = 0;
  52. SQRT_BUSY = (1 shl 15);
  53. {$endif NDS_INTERFACE}
  54. {$ifdef NDS_IMPLEMENTATION}
  55. function divf32(num: cint32; den: cint32): cint32; inline;
  56. begin
  57. DIV_CR^ := DIV_64_32;
  58. while (DIV_CR^ and DIV_BUSY) <> 0 do;
  59. DIV_NUMERATOR64^ := cint64(num) shl 12;
  60. DIV_DENOMINATOR32^ := den;
  61. while (DIV_CR^ and DIV_BUSY) <> 0 do;
  62. divf32 := DIV_RESULT32^;
  63. end;
  64. function mulf32(a, b: cint32): cint32; inline;
  65. var
  66. rslt: clonglong;
  67. begin
  68. rslt := clonglong(a) * clonglong(b);
  69. mulf32 := cint32(rslt shr 12);
  70. end;
  71. // Fixed point square root
  72. // Takes 1.19.12 fixed point value and
  73. // returns the fixed point result
  74. function sqrtf32(a: cint32): cint32; inline;
  75. begin
  76. SQRT_CR^ := SQRT_64;
  77. while (SQRT_CR^ and SQRT_BUSY) <> 0 do;
  78. SQRT_PARAM64^ := cint64(a) shl 12;
  79. while (SQRT_CR^ and SQRT_BUSY) <> 0 do;
  80. sqrtf32 := SQRT_RESULT32^;
  81. end;
  82. // Integer versions
  83. // Integer divide
  84. // Takes a 32 bit numerator and 32 bit
  85. // denominator and returns 32 bit result
  86. function div32(num, den: cint32): cint32; inline;
  87. begin
  88. DIV_CR^ := DIV_32_32;
  89. while (DIV_CR^ and DIV_BUSY) <> 0 do;
  90. DIV_NUMERATOR32^ := num;
  91. DIV_DENOMINATOR32^ := den;
  92. while (DIV_CR^ and DIV_BUSY) <> 0 do;
  93. div32 := DIV_RESULT32^;
  94. end;
  95. // Integer divide
  96. // Takes a 32 bit numerator and 32 bit
  97. // denominator and returns 32 bit result
  98. function mod32(num, den: cint32): cint32; inline;
  99. begin
  100. DIV_CR^ := DIV_32_32;
  101. while (DIV_CR^ and DIV_BUSY) <> 0 do;
  102. DIV_NUMERATOR32^ := num;
  103. DIV_DENOMINATOR32^ := den;
  104. while (DIV_CR^ and DIV_BUSY) <> 0 do;
  105. mod32 := DIV_REMAINDER32^;
  106. end;
  107. // Integer divide
  108. // Takes a 64 bit numerator and 32 bit
  109. // denominator are returns 32 bit result
  110. function div64(num: cint64; den: cint32): cint32; inline;
  111. begin
  112. DIV_CR^ := DIV_64_32;
  113. while (DIV_CR^ and DIV_BUSY) <> 0 do;
  114. DIV_NUMERATOR64^ := num;
  115. DIV_DENOMINATOR32^ := den;
  116. while (DIV_CR^ and DIV_BUSY) <> 0 do;
  117. div64 := DIV_RESULT32^;
  118. end;
  119. // Integer divide
  120. // Takes a 64 bit numerator and 32 bit
  121. // denominator are returns 32 bit result
  122. function mod64(num: cint64; den: cint32): cint32; inline;
  123. begin
  124. DIV_CR^ := DIV_64_32;
  125. while (DIV_CR^ and DIV_BUSY) <> 0 do;
  126. DIV_NUMERATOR64^ := num;
  127. DIV_DENOMINATOR32^ := den;
  128. while (DIV_CR^ and DIV_BUSY) <> 0 do;
  129. mod64 := DIV_REMAINDER32^;
  130. end;
  131. // Integer square root
  132. // takes a 32 bit integer and returns
  133. // 32 bit result
  134. function sqrt32(a: cint32): cint32; inline;
  135. begin
  136. SQRT_CR^ := SQRT_32;
  137. while(SQRT_CR^ and SQRT_BUSY) <> 0 do;
  138. SQRT_PARAM32^ := a;
  139. while(SQRT_CR^ and SQRT_BUSY) <> 0 do;
  140. sqrt32 := SQRT_RESULT32^;
  141. end;
  142. // Trig Functions 1.19.12 fixed point
  143. // Cross product
  144. // x = Ay * Bz - By * Az
  145. // y = Az * Bx - Bz * Ax
  146. // z = Ax * By - Bx * Ay
  147. procedure crossf32(a: pcint32; b: pcint32; res: pcint32); inline;
  148. begin
  149. res[0] := mulf32(a[1], b[2]) - mulf32(b[1], a[2]);
  150. res[1] := mulf32(a[2], b[0]) - mulf32(b[2], a[0]);
  151. res[2] := mulf32(a[0], b[1]) - mulf32(b[0], a[1]);
  152. end;
  153. // Dot Product
  154. // result = Ax * Bx + Ay * By + Az * Bz
  155. function dotf32(a, b: pcint32): cint32; inline;
  156. begin
  157. dotf32 := mulf32(a[0], b[0]) + mulf32(a[1], b[1]) + mulf32(a[2], b[2]);
  158. end;
  159. // Normalize
  160. // Ax = Ax / mag
  161. // Ay = Ay / mag
  162. // Az = Az / mag
  163. procedure normalizef32(a: pcint32); inline;
  164. var
  165. magnitude: cint32;
  166. begin
  167. // magnitude = sqrt ( Ax^2 + Ay^2 + Az^2 )
  168. magnitude := sqrtf32( mulf32(a[0], a[0]) + mulf32(a[1], a[1]) + mulf32(a[2], a[2]) );
  169. a[0] := divf32(a[0], magnitude);
  170. a[1] := divf32(a[1], magnitude);
  171. a[2] := divf32(a[2], magnitude);
  172. end;
  173. {$endif NDS_IMPLEMENTATION}
  174. {$ifdef NDS_INTERFACE}
  175. function divf32(num: cint32; den: cint32): cint32; inline;
  176. function mulf32(a, b: cint32): cint32; inline;
  177. function sqrtf32(a: cint32): cint32; inline;
  178. function div32(num, den: cint32): cint32; inline;
  179. function mod32(num, den: cint32): cint32; inline;
  180. function div64(num: cint64; den: cint32): cint32; inline;
  181. function mod64(num: cint64; den: cint32): cint32; inline;
  182. function sqrt32(a: cint32): cint32; inline;
  183. procedure crossf32(a: pcint32; b: pcint32; res: pcint32); inline;
  184. function dotf32(a, b: pcint32): cint32; inline;
  185. procedure normalizef32(a: pcint32); inline;
  186. {$endif NDS_INTERFACE}