Jo Engine 2026.11.1
Jo Sega Saturn Engine
Loading...
Searching...
No Matches
math.h
Go to the documentation of this file.
1/*
2** Jo Sega Saturn Engine
3** Copyright (c) 2012-2026, Johannes Fetz (johannesfetz@gmail.com)
4** All rights reserved.
5**
6** Redistribution and use in source and binary forms, with or without
7** modification, are permitted provided that the following conditions are met:
8** * Redistributions of source code must retain the above copyright
9** notice, this list of conditions and the following disclaimer.
10** * Redistributions in binary form must reproduce the above copyright
11** notice, this list of conditions and the following disclaimer in the
12** documentation and/or other materials provided with the distribution.
13** * Neither the name of the Johannes Fetz nor the
14** names of its contributors may be used to endorse or promote products
15** derived from this software without specific prior written permission.
16**
17** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20** DISCLAIMED. IN NO EVENT SHALL Johannes Fetz BE LIABLE FOR ANY
21** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
34
35#ifndef __JO_MATH_H__
36# define __JO_MATH_H__
37
38/*
39███╗ ███╗ █████╗ ████████╗██╗ ██╗ ██████╗ ██████╗ ███╗ ██╗███████╗████████╗███████╗
40████╗ ████║██╔══██╗╚══██╔══╝██║ ██║ ██╔════╝██╔═══██╗████╗ ██║██╔════╝╚══██╔══╝██╔════╝
41██╔████╔██║███████║ ██║ ███████║ ██║ ██║ ██║██╔██╗ ██║███████╗ ██║ ███████╗
42██║╚██╔╝██║██╔══██║ ██║ ██╔══██║ ██║ ██║ ██║██║╚██╗██║╚════██║ ██║ ╚════██║
43██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║ ╚██████╗╚██████╔╝██║ ╚████║███████║ ██║ ███████║
44╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝ ╚═╝ ╚══════╝
45*/
46
51# define JO_PI (3.1415927f)
52
54# define JO_PI_2 (1.5707963f)
55
56/*
57███╗ ███╗██╗ ██╗██╗ ████████╗ ██╗██████╗ ██╗██╗ ██╗
58████╗ ████║██║ ██║██║ ╚══██╔══╝██╔╝██╔══██╗██║██║ ██║
59██╔████╔██║██║ ██║██║ ██║ ██╔╝ ██║ ██║██║██║ ██║
60██║╚██╔╝██║██║ ██║██║ ██║ ██╔╝ ██║ ██║██║╚██╗ ██╔╝
61██║ ╚═╝ ██║╚██████╔╝███████╗██║██╔╝ ██████╔╝██║ ╚████╔╝
62╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝╚═╝ ╚═════╝ ╚═╝ ╚═══╝
63*/
64
69# define JO_MULT_BY_2(X) ((X) << 1)
70
75# define JO_MULT_BY_4(X) ((X) << 2)
76
81# define JO_MULT_BY_8(X) ((X) << 3)
82
87# define JO_MULT_BY_16(X) ((X) << 4)
88
93# define JO_MULT_BY_32(X) ((X) << 5)
94
99# define JO_MULT_BY_64(X) ((X) << 6)
100
105# define JO_MULT_BY_128(X) ((X) << 7)
106
111# define JO_MULT_BY_256(X) ((X) << 8)
112
117# define JO_MULT_BY_512(X) ((X) << 9)
118
123# define JO_MULT_BY_1024(X) ((X) << 10)
124
129# define JO_MULT_BY_2048(X) ((X) << 11)
130
135# define JO_MULT_BY_4096(X) ((X) << 12)
136
141# define JO_MULT_BY_32768(X) ((X) << 15)
142
147# define JO_MULT_BY_65536(X) ((X) << 16)
148
153# define JO_DIV_BY_2(X) ((X) >> 1)
154
159# define JO_DIV_BY_4(X) ((X) >> 2)
160
165# define JO_DIV_BY_8(X) ((X) >> 3)
166
171# define JO_DIV_BY_16(X) ((X) >> 4)
172
177# define JO_DIV_BY_32(X) ((X) >> 5)
178
183# define JO_DIV_BY_64(X) ((X) >> 6)
184
189# define JO_DIV_BY_128(X) ((X) >> 7)
190
195# define JO_DIV_BY_256(X) ((X) >> 8)
196
201# define JO_DIV_BY_512(X) ((X) >> 9)
202
207# define JO_DIV_BY_1024(X) ((X) >> 10)
208
213# define JO_DIV_BY_32768(X) ((X) >> 15)
214
219# define JO_DIV_BY_65536(X) ((X) >> 16)
220
225# define JO_DIV_BY_2147483648(X) ((X) >> 31)
226
227/*
228████████╗ ██████╗ ██████╗ ██╗ ███████╗
229╚══██╔══╝██╔═══██╗██╔═══██╗██║ ██╔════╝
230 ██║ ██║ ██║██║ ██║██║ ███████╗
231 ██║ ██║ ██║██║ ██║██║ ╚════██║
232 ██║ ╚██████╔╝╚██████╔╝███████╗███████║
233 ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝╚══════╝
234*/
235
240# define JO_ZERO(X) X ^= X
241
247# define JO_MOD_POW2(N, M) ((N) & ((M) - 1))
248
252# define JO_IS_POW2(N) ((N) != 0 && (((N) & ((N) - 1)) == 0))
253
257# define JO_ABS(X) ((X) < 0 ? -(X) : (X))
258
262# define JO_FABS(X) ((X) < 0.0f ? -(X) : (X))
263
268# define JO_MIN(A, B) (((A) < (B)) ? (A) : (B))
269
274# define JO_MAX(A, B) (((A) > (B)) ? (A) : (B))
275
279# define JO_CHANGE_SIGN(X) (-(X))
280
282# define JO_FLOAT_EPSILON (0.00001f)
283
288# define JO_FLOAT_NEARLY_EQUALS(A, B) ((A) <= ((B) + JO_FLOAT_EPSILON) && (A) >= ((B) - JO_FLOAT_EPSILON))
289
293# define JO_IS_FLOAT_NULL(A) ((A) <= JO_FLOAT_EPSILON && (A) >= (-JO_FLOAT_EPSILON))
294
298# define JO_RAD_TO_DEG(A) ((A) * 57.295780f)
299
303# define JO_DEG_TO_RAD(A) ((A) * 0.017453292f)
304
308# define JO_IS_ODD(A) ((A) & 1)
309
315# define JO_SWAP(A, B) { __typeof__((A) + 0) __jo_swap_tmp = (A); (A) = (B); (B) = __jo_swap_tmp; }
316
323# define JO_OPAQUE(VAR) __asm__ ("" : "+r" (VAR))
324
330# define JO_PERCENT_USED(TOTAL, FREE) ((TOTAL) == 0 ? 0 : (int)((unsigned int)((TOTAL) - (FREE)) * 100u / (unsigned int)(TOTAL)))
331
335# define JO_SQUARE(A) ((A) * (A))
336
340# define JO_BCD_INT(BCD) (((BCD & 0xF0) >> 4) * 10 + (BCD & 0x0F))
341
342/*
343██████╗ ██╗ ██╗████████╗███████╗███████╗██╗███████╗██╗ ██████╗
344██╔══██╗╚██╗ ██╔╝╚══██╔══╝██╔════╝██╔════╝██║██╔════╝██║ ██╔══██╗
345██████╔╝ ╚████╔╝ ██║ █████╗ █████╗ ██║█████╗ ██║ ██║ ██║
346██╔══██╗ ╚██╔╝ ██║ ██╔══╝ ██╔══╝ ██║██╔══╝ ██║ ██║ ██║
347██████╔╝ ██║ ██║ ███████╗██║ ██║███████╗███████╗██████╔╝
348╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚══════╝╚══════╝╚═════╝
349*/
350
355# define JO_SET_FLAGS(BYTEFIELD, FLAGS) BYTEFIELD = (FLAGS)
356
360# define JO_SET_ALL_FLAGS(BYTEFIELD) BYTEFIELD = (~0)
361
366# define JO_ADD_FLAG(BYTEFIELD, FLAG) BYTEFIELD |= (FLAG)
367
372# define JO_REMOVE_FLAG(BYTEFIELD, FLAG) BYTEFIELD &= ~(FLAG)
373
377# define JO_REMOVE_ALL_FLAGS(BYTEFIELD) BYTEFIELD = 0
378
383# define JO_HAS_FLAG(BYTEFIELD, FLAG) ((BYTEFIELD & FLAG) == FLAG)
384
385/*
386███████╗██╗██╗ ██╗███████╗██████╗ ██████╗ ██████╗ ███╗ ██╗██╗ ██╗███████╗██████╗ ████████╗██╗ ██████╗ ███╗ ██╗
387██╔════╝██║╚██╗██╔╝██╔════╝██╔══██╗ ██╔════╝██╔═══██╗████╗ ██║██║ ██║██╔════╝██╔══██╗╚══██╔══╝██║██╔═══██╗████╗ ██║
388█████╗ ██║ ╚███╔╝ █████╗ ██║ ██║ ██║ ██║ ██║██╔██╗ ██║██║ ██║█████╗ ██████╔╝ ██║ ██║██║ ██║██╔██╗ ██║
389██╔══╝ ██║ ██╔██╗ ██╔══╝ ██║ ██║ ██║ ██║ ██║██║╚██╗██║╚██╗ ██╔╝██╔══╝ ██╔══██╗ ██║ ██║██║ ██║██║╚██╗██║
390██║ ██║██╔╝ ██╗███████╗██████╔╝ ╚██████╗╚██████╔╝██║ ╚████║ ╚████╔╝ ███████╗██║ ██║ ██║ ██║╚██████╔╝██║ ╚████║
391╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═══╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝
392
393 ▲ NOTE ABOUT FIXED NUMBER ▲
394 Only values between -32767.99998 and 32767.99998 can be converted to fixed number.
395
396*/
397
399# define JO_FIXED_0 (0)
401# define JO_FIXED_1_DIV_2 (32768)
403# define JO_FIXED_ALMOST_1 (65470)
405# define JO_FIXED_1 (65536)
407# define JO_FIXED_2 JO_INT_TO_FIXED(2)
409# define JO_FIXED_3 JO_INT_TO_FIXED(3)
411# define JO_FIXED_4 JO_INT_TO_FIXED(4)
413# define JO_FIXED_8 JO_INT_TO_FIXED(8)
415# define JO_FIXED_16 JO_INT_TO_FIXED(16)
417# define JO_FIXED_32 JO_INT_TO_FIXED(32)
419# define JO_FIXED_120 JO_INT_TO_FIXED(120)
421# define JO_FIXED_150 JO_INT_TO_FIXED(150)
423# define JO_FIXED_180 JO_INT_TO_FIXED(180)
425# define JO_FIXED_360 JO_INT_TO_FIXED(360)
426
428# define JO_FIXED_MIN (-2147483647)
430# define JO_FIXED_MAX (2147483647)
432# define JO_FIXED_EPSILON (1)
434# define JO_FIXED_OVERFLOW (0x80000000)
436# define JO_FIXED_PI (205887)
438# define JO_FIXED_PI_2 (411775)
440# define JO_FIXED_180_DIV_PI (3754936)
442# define JO_FIXED_PI_DIV_180 (1144)
444# define JO_FIXED_PI_DIV_2 (102944)
446# define JO_FIXED_PI_OVER_2 JO_FIXED_PI_DIV_2
448# define JO_FIXED_3_PI_OVER_2 (308331)
450# define JO_FIXED_1_DIV (1.0f / 65536.0f)
451
455# define JO_INT_TO_FIXED(X) JO_MULT_BY_65536(X)
459# define JO_FIXED_TO_INT(X) JO_DIV_BY_65536(X)
461# define JO_FIXED_DECIMAL_MASK (0xFFFF)
465# define JO_FLOAT_TO_FIXED(X) ((jo_fixed)(65536.0f * (X)))
469# define JO_DEG_TO_ANGLE(X) ((jo_angle)((65536.0 * (X)) / 360.0))
473# define JO_RAD_TO_ANGLE(X) ((jo_angle)((65536.0 * (X)) / (2.0 * 3.14159265358979)))
474
480{
481 return JO_INT_TO_FIXED(x);
482}
483
489{
490 return JO_FIXED_TO_INT(x);
491}
492
498{
499 return ((jo_fixed)(x * (float)JO_FIXED_1));
500}
501
507{
508 return ((float)x * JO_FIXED_1_DIV);
509}
510
516{
517 while (rad > JO_FIXED_PI) rad -= JO_FIXED_PI_2;
518 while (rad <= -JO_FIXED_PI) rad += JO_FIXED_PI_2;
519 return (rad);
520}
521
527{
528 while (deg > JO_FIXED_180) deg -= JO_FIXED_360;
529 while (deg <= -JO_FIXED_180) deg += JO_FIXED_360;
530 return (deg);
531}
532
539
547{
548 return ((jo_fixed)(((long long)x * y) >> 16));
549}
550
558{
559 int high;
560
561 __asm__ ("dmuls.l %1, %2\n\t"
562 "sts mach, %0"
563 : "=r" (high)
564 : "r" (x), "r" (y)
565 : "mach", "macl");
566 return (high);
567}
568
576static __jo_force_inline jo_fixed jo_fixed_dot(const jo_fixed ptA[3], const jo_fixed ptB[3])
577{
578 const jo_fixed *a;
579 const jo_fixed *b;
580 jo_fixed high;
581 jo_fixed low;
582
583 a = ptA;
584 b = ptB;
585 __asm__ ("clrmac\n\t"
586 "mac.l @%2+, @%3+\n\t"
587 "mac.l @%2+, @%3+\n\t"
588 "mac.l @%2+, @%3+\n\t"
589 "sts mach, %0\n\t"
590 "sts macl, %1\n\t"
591 "xtrct %0, %1"
592 : "=&r" (high), "=&r" (low), "+r" (a), "+r" (b)
593 : "m" (*(const jo_fixed (*)[3])ptA), "m" (*(const jo_fixed (*)[3])ptB)
594 : "mach", "macl");
595 return (low);
596}
597
605static __jo_force_inline jo_fixed jo_fixed_div(const jo_fixed dividend, const jo_fixed divisor)
606{
607 JO_SH2_DVSR = divisor;
608 // 64 bits dividend: (dividend << 16)
609 JO_SH2_DVDNTH = dividend >> 16;
610 // Writing the low part starts the division
611 JO_SH2_DVDNTL = dividend << 16;
612 return ((jo_fixed)JO_SH2_DVDNTL);
613}
614
623static __jo_force_inline int jo_int_div(const int dividend, const int divisor)
624{
625 JO_SH2_DVSR = divisor;
626 // (writing the dividend starts the division. The quotient read in DVDNTL, as jo_fixed_div(): the register saved and
627 // restored by the VBLANK interrupt)
628 JO_SH2_DVDNT = dividend;
629 return (JO_SH2_DVDNTL);
630}
631
638static __jo_force_inline int jo_shift_right8(const int x)
639{
640 return (x < 0 ? (int)~(~(unsigned int)x >> 8) : (int)((unsigned int)x >> 8));
641}
642
650{
651 return ((int)(((unsigned int)x + (1u << 23)) >> 8) - (1 << 15));
652}
653
660static __jo_force_inline void jo_fixed_div_start(const jo_fixed dividend, const jo_fixed divisor)
661{
662 JO_SH2_DVSR = divisor;
663 JO_SH2_DVDNTH = dividend >> 16;
664 JO_SH2_DVDNTL = dividend << 16;
665}
666
675
684
693
699{
700 return (x & 0xFFFF0000UL) + (x & 0x0000FFFFUL ? JO_FIXED_1 : 0);
701}
702
708{
709 return (x & 0xFFFF0000ul);
710}
711
712/*
713██████╗ █████╗ ███╗ ██╗██████╗ ██████╗ ███╗ ███╗
714██╔══██╗██╔══██╗████╗ ██║██╔══██╗██╔═══██╗████╗ ████║
715██████╔╝███████║██╔██╗ ██║██║ ██║██║ ██║██╔████╔██║
716██╔══██╗██╔══██║██║╚██╗██║██║ ██║██║ ██║██║╚██╔╝██║
717██║ ██║██║ ██║██║ ╚████║██████╔╝╚██████╔╝██║ ╚═╝ ██║
718╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═════╝ ╚═════╝ ╚═╝ ╚═╝
719*/
720
725extern int jo_random_seed;
726
732int jo_random(int max);
733
739static __jo_force_inline int jo_random_using_multiple(int max, int multiple)
740{
741 return (jo_random(max) / multiple) * multiple;
742}
743
744/*
745███████╗ ██████╗ ██████╗ ████████╗
746██╔════╝██╔═══██╗██╔══██╗╚══██╔══╝
747███████╗██║ ██║██████╔╝ ██║
748╚════██║██║▄▄ ██║██╔══██╗ ██║
749███████║╚██████╔╝██║ ██║ ██║
750╚══════╝ ╚══▀▀═╝ ╚═╝ ╚═╝ ╚═╝
751*/
752
758static __jo_force_inline unsigned int jo_highest_bit(unsigned int x)
759{
760 unsigned int bit;
761
762 bit = 0;
763 if (x & 0xffff0000)
764 {
765 bit = 16;
766 x >>= 16;
767 }
768 if (x & 0xff00)
769 {
770 bit += 8;
771 x >>= 8;
772 }
773 if (x & 0xf0)
774 {
775 bit += 4;
776 x >>= 4;
777 }
778 if (x & 0xc)
779 {
780 bit += 2;
781 x >>= 2;
782 }
783 if (x & 0x2)
784 ++bit;
785 return (bit);
786}
787
794
800unsigned int jo_sqrt(unsigned int value);
801
807static __jo_force_inline float jo_sqrtf(float value)
808{
809 // A union avoids the strict aliasing issue of *(unsigned int *)&value (undefined behavior with -O2)
810 union
811 {
812 float f;
813 unsigned int i;
814 } bits;
815
816 bits.f = value;
817 bits.i += 127 << 23;
818 bits.i >>= 1;
819 return (bits.f);
820}
821
822/*
823██╗███╗ ██╗██╗ ██╗███████╗██████╗ ███████╗███████╗ ███████╗ ██████╗ ██████╗ ████████╗
824██║████╗ ██║██║ ██║██╔════╝██╔══██╗██╔════╝██╔════╝ ██╔════╝██╔═══██╗██╔══██╗╚══██╔══╝
825██║██╔██╗ ██║██║ ██║█████╗ ██████╔╝███████╗█████╗ ███████╗██║ ██║██████╔╝ ██║
826██║██║╚██╗██║╚██╗ ██╔╝██╔══╝ ██╔══██╗╚════██║██╔══╝ ╚════██║██║▄▄ ██║██╔══██╗ ██║
827██║██║ ╚████║ ╚████╔╝ ███████╗██║ ██║███████║███████╗ ███████║╚██████╔╝██║ ██║ ██║
828╚═╝╚═╝ ╚═══╝ ╚═══╝ ╚══════╝╚═╝ ╚═╝╚══════╝╚══════╝ ╚══════╝ ╚══▀▀═╝ ╚═╝ ╚═╝ ╚═╝
829AKA RECIPROCAL SQUARE ROOT
830*/
831
837
842float jo_rsqrt(float value);
843
844/*
845███████╗ ██████╗ ██╗ ██╗███╗ ██╗████████╗███████╗██████╗ ██████╗ ██████╗
846██╔════╝██╔════╝ ██║ ██║████╗ ██║╚══██╔══╝██╔════╝██╔══██╗██╔═══██╗██╔══██╗
847███████╗██║ ███╗██║ ██║██╔██╗ ██║ ██║ █████╗ ██████╔╝██║ ██║██████╔╝
848╚════██║██║ ██║██║ ██║██║╚██╗██║ ██║ ██╔══╝ ██╔══██╗██║ ██║██╔═══╝
849███████║╚██████╔╝███████╗ ██║██║ ╚████║ ██║ ███████╗██║ ██║╚██████╔╝██║
850╚══════╝ ╚═════╝ ╚══════╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝
851
852*/
853
855# define __JO_DEG_TO_ANGLE_MAGIC (182)
856
862{
863 // One float multiplication (65536 / 360), not a double multiplication and a double division
864 return ((jo_angle)(deg * (65536.0f / 360.0f)));
865}
866
872{
873 int n;
874 int a;
875
876 // deg * 65536 / 360 = deg * 8192 / 45: multiplication by 2^32 / 45 (rounded up) instead of a division.
877 // Same result as the division for |deg| < 37000
878 n = deg < 0 ? -deg : deg;
879 a = (int)(((long long)(n * 8192) * 95443718LL) >> 32);
880 return ((jo_angle)(deg < 0 ? -a : a));
881}
882
883
889{
890 // rad * 65536 / (2 pi) without floating point: 65536 / (2 pi) = 683565276 / 2^32 (Q16.16 input)
891 return ((jo_angle)(((long long)rad * 683565276LL) >> 32));
892}
893
894
896extern const jo_fixed __jo_sin_table[1025];
897
902static __jo_force_inline jo_fixed __jo_sin_index(const unsigned int index)
903{
904 if (index < 1024)
905 return (__jo_sin_table[index]);
906 if (index < 2048)
907 return (__jo_sin_table[2048 - index]);
908 if (index < 3072)
909 return (-__jo_sin_table[index - 2048]);
910 return (-__jo_sin_table[4096 - index]);
911}
912
917static __jo_force_inline unsigned int __jo_angle_to_sin_index(const jo_angle angle)
918{
919 return (((((unsigned short)angle) + 8) >> 4) & 0xfff);
920}
921
928{
930}
931
937{
938 return (__jo_sin_index((__jo_angle_to_sin_index(angle) + 1024) & 0xfff));
939}
940
947static __jo_force_inline void jo_sincos_angle(const jo_angle angle, jo_fixed * const sin_value, jo_fixed * const cos_value)
948{
949 unsigned int index;
950
951 index = __jo_angle_to_sin_index(angle);
952 *sin_value = __jo_sin_index(index);
953 *cos_value = __jo_sin_index((index + 1024) & 0xfff);
954}
955
961{
962 // deg * 65536 / 360 without floating point: 1 / 360 = 11930465 / 2^32 (Q16.16 input)
963 return ((jo_angle)(((long long)deg * 11930465LL) >> 32));
964}
965
966/*
967███████╗██╗███╗ ██╗██╗ ██╗███████╗
968██╔════╝██║████╗ ██║██║ ██║██╔════╝
969███████╗██║██╔██╗ ██║██║ ██║███████╗
970╚════██║██║██║╚██╗██║██║ ██║╚════██║
971███████║██║██║ ╚████║╚██████╔╝███████║
972╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝
973*/
974
981{
982 return (jo_sin_angle(jo_fixed_rad2ANGLE(rad)));
983}
984
989static __jo_force_inline jo_fixed jo_sin(const int deg)
990{
991 // Table lookup, without floating point
992 return (jo_sin_angle(jo_DEGtoANG_int(deg)));
993}
994
1000static __jo_force_inline float jo_sinf(const int deg)
1001{
1002 return (jo_fixed2float(jo_sin(deg)));
1003}
1004
1011{
1012 return (jo_fixed_sin(jo_float2fixed(rad)));
1013}
1014
1020static __jo_force_inline float jo_sin_radf(const float rad)
1021{
1023}
1024
1031static __jo_force_inline int jo_sin_mult(const int value, const int deg)
1032{
1033 return (jo_fixed_mult(value, jo_sin(deg)));
1034}
1035
1041static __jo_force_inline float jo_sinf_mult(const float value, const int deg)
1042{
1043 return (value * jo_sinf(deg));
1044}
1045
1046/*
1047 ██████╗ ██████╗ ███████╗██╗███╗ ██╗██╗ ██╗███████╗
1048██╔════╝██╔═══██╗██╔════╝██║████╗ ██║██║ ██║██╔════╝
1049██║ ██║ ██║███████╗██║██╔██╗ ██║██║ ██║███████╗
1050██║ ██║ ██║╚════██║██║██║╚██╗██║██║ ██║╚════██║
1051╚██████╗╚██████╔╝███████║██║██║ ╚████║╚██████╔╝███████║
1052 ╚═════╝ ╚═════╝ ╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝
1053
1054*/
1055
1062{
1063 return (jo_cos_angle(jo_fixed_rad2ANGLE(rad)));
1064}
1065
1070static __jo_force_inline jo_fixed jo_cos(const int deg)
1071{
1072 // Table lookup, without floating point
1073 return (jo_cos_angle(jo_DEGtoANG_int(deg)));
1074}
1075
1082static __jo_force_inline void jo_sincos(const int deg, jo_fixed * const sin_value, jo_fixed * const cos_value)
1083{
1084 jo_sincos_angle(jo_DEGtoANG_int(deg), sin_value, cos_value);
1085}
1086
1092static __jo_force_inline float jo_cosf(const int deg)
1093{
1094 return (jo_fixed2float(jo_cos(deg)));
1095}
1096
1103{
1104 return (jo_fixed_cos(jo_float2fixed(rad)));
1105}
1106
1112static __jo_force_inline float jo_cos_radf(const float rad)
1113{
1115}
1116
1123static __jo_force_inline int jo_cos_mult(const int value, const int deg)
1124{
1125 return (jo_fixed_mult(value, jo_cos(deg)));
1126}
1127
1133static __jo_force_inline float jo_cosf_mult(const float value, const int deg)
1134{
1135 return (value * jo_cosf(deg));
1136}
1137
1138/*
1139████████╗ █████╗ ███╗ ██╗ ██████╗ ███████╗███╗ ██╗████████╗
1140╚══██╔══╝██╔══██╗████╗ ██║██╔════╝ ██╔════╝████╗ ██║╚══██╔══╝
1141 ██║ ███████║██╔██╗ ██║██║ ███╗█████╗ ██╔██╗ ██║ ██║
1142 ██║ ██╔══██║██║╚██╗██║██║ ██║██╔══╝ ██║╚██╗██║ ██║
1143 ██║ ██║ ██║██║ ╚████║╚██████╔╝███████╗██║ ╚████║ ██║
1144 ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝
1145
1146*/
1147
1152static __jo_force_inline jo_fixed jo_tan(const int deg)
1153{
1154 jo_fixed sin_value;
1155 jo_fixed cos_value;
1156
1157 jo_sincos(deg, &sin_value, &cos_value);
1158 return jo_fixed_div(sin_value, cos_value);
1159}
1160
1166static __jo_force_inline float jo_tanf(const float deg)
1167{
1168 return (jo_sinf(deg) / jo_cosf(deg));
1169}
1170
1177{
1178 jo_fixed sin_value;
1179 jo_fixed cos_value;
1180
1181 jo_sincos_angle(jo_fixed_rad2ANGLE(jo_float2fixed(rad)), &sin_value, &cos_value);
1182 return jo_fixed_div(sin_value, cos_value);
1183}
1184
1190static __jo_force_inline float jo_tan_radf(const float rad)
1191{
1192 return (jo_sin_radf(rad) / jo_cos_radf(rad));
1193}
1194
1195/*
1196 █████╗ ██████╗ ██████╗ ███████╗
1197██╔══██╗██╔════╝██╔═══██╗██╔════╝
1198███████║██║ ██║ ██║███████╗
1199██╔══██║██║ ██║ ██║╚════██║
1200██║ ██║╚██████╗╚██████╔╝███████║
1201╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝
1202*/
1203
1209static __jo_force_inline float jo_acos_radf(const float angle)
1210{
1211 return (1.5707963f - 1.5707963f * angle);
1212}
1213
1214/*
1215 █████╗ ████████╗ █████╗ ███╗ ██╗██████╗
1216██╔══██╗╚══██╔══╝██╔══██╗████╗ ██║╚════██╗
1217███████║ ██║ ███████║██╔██╗ ██║ █████╔╝
1218██╔══██║ ██║ ██╔══██║██║╚██╗██║██╔═══╝
1219██║ ██║ ██║ ██║ ██║██║ ╚████║███████╗
1220╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝
1221
1222*/
1223
1230float jo_atan2f_rad(const float y, const float x);
1231
1238static __jo_force_inline int jo_atan2f(const float y, const float x)
1239{
1240 return (int)JO_RAD_TO_DEG(jo_atan2f_rad(y, x));
1241}
1242
1249static __jo_force_inline jo_angle jo_atan2_angle(const float y, const float x)
1250{
1251 return ((jo_angle)(int)(jo_atan2f_rad(y, x) * (32768.0f / JO_PI)));
1252}
1253
1263
1272int jo_atan2_degrees(const jo_fixed y, const jo_fixed x);
1273
1280static __jo_force_inline int jo_turn_toward(const int angle, const int target, const int max_step)
1281{
1282 int d;
1283
1284 // Shortest difference: -180 to 179 (the modulo, a division by libgcc, only when the angles are not 0 to 359)
1285 d = target - angle;
1286 if (d >= 360 || d <= -360)
1287 d %= 360;
1288 if (d >= 180)
1289 d -= 360;
1290 else if (d < -180)
1291 d += 360;
1292 if (d > max_step)
1293 d = max_step;
1294 else if (d < -max_step)
1295 d = -max_step;
1296 d += angle;
1297 if (d >= 360 || d <= -360)
1298 d %= 360;
1299 return (d < 0 ? d + 360 : d);
1300}
1301
1302/*
1303██╗ ██╗███████╗ ██████╗████████╗ ██████╗ ██████╗
1304██║ ██║██╔════╝██╔════╝╚══██╔══╝██╔═══██╗██╔══██╗
1305██║ ██║█████╗ ██║ ██║ ██║ ██║██████╔╝
1306╚██╗ ██╔╝██╔══╝ ██║ ██║ ██║ ██║██╔══██╗
1307 ╚████╔╝ ███████╗╚██████╗ ██║ ╚██████╔╝██║ ██║
1308 ╚═══╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
1309*/
1310
1311/*
1312 _______ __ _ __ __
1313 / ____(_) _____ ____/ / / | / /_ ______ ___ / /_ ___ _____
1314 / /_ / / |/_/ _ \/ __ / / |/ / / / / __ `__ \/ __ \/ _ \/ ___/
1315 / __/ / /> </ __/ /_/ / / /| / /_/ / / / / / / /_/ / __/ /
1316/_/ /_/_/|_|\___/\__,_/ /_/ |_/\__,_/_/ /_/ /_/_.___/\___/_/
1317
1318*/
1319
1329
1336static __jo_force_inline void jo_vector_fixed_add(const jo_vector_fixed * const a, const jo_vector_fixed * const b, jo_vector_fixed * const result)
1337{
1338 result->x = a->x + b->x;
1339 result->y = a->y + b->y;
1340 result->z = a->z + b->z;
1341}
1342
1349static __jo_force_inline void jo_vector_fixed_muls(const jo_vector_fixed * const a, const jo_fixed s, jo_vector_fixed * const result)
1350{
1351 result->x = jo_fixed_mult(a->x, s);
1352 result->y = jo_fixed_mult(a->y, s);
1353 result->z = jo_fixed_mult(a->z, s);
1354}
1355
1362static __jo_force_inline void jo_vector4_fixed_add(const jo_vector4_fixed * const a, const jo_vector4_fixed * const b, jo_vector4_fixed * const result)
1363{
1364 result->x = a->x + b->x;
1365 result->y = a->y + b->y;
1366 result->z = a->z + b->z;
1367 result->w = JO_FIXED_1;
1368}
1369
1376static __jo_force_inline void jo_vector4_fixed_sub(const jo_vector4_fixed * const a, const jo_vector4_fixed * const b, jo_vector4_fixed * const result)
1377{
1378 result->x = a->x - b->x;
1379 result->y = a->y - b->y;
1380 result->z = a->z - b->z;
1381 result->w = JO_FIXED_1;
1382}
1383
1389static __jo_force_inline void jo_vector4_fixed_cross(const jo_vector4_fixed * const a, const jo_vector4_fixed * const b, jo_vector4_fixed * const result)
1390{
1391 result->x = jo_fixed_mult(a->y, b->z) - jo_fixed_mult(a->z, b->y);
1392 result->y = jo_fixed_mult(a->z, b->x) - jo_fixed_mult(a->x, b->z);
1393 result->z = jo_fixed_mult(a->x, b->y) - jo_fixed_mult(a->y, b->x);
1394 result->w = JO_FIXED_1;
1395}
1396
1403{
1404 // x, y, z are contiguous (w is ignored)
1405 return (jo_fixed_dot((const jo_fixed *)a, (const jo_fixed *)b));
1406}
1407
1413{
1414 JO_SWAP(a->x, b->x);
1415 JO_SWAP(a->y, b->y);
1416 JO_SWAP(a->z, b->z);
1417 JO_SWAP(a->w, b->w);
1418}
1419
1420/*
1421 ________ __ _ _ __ __
1422 / ____/ /___ ____ _/ /_(_)___ ____ _ / | / /_ ______ ___ / /_ ___ _____
1423 / /_ / / __ \/ __ `/ __/ / __ \/ __ `/ / |/ / / / / __ `__ \/ __ \/ _ \/ ___/
1424 / __/ / / /_/ / /_/ / /_/ / / / / /_/ / / /| / /_/ / / / / / / /_/ / __/ /
1425/_/ /_/\____/\__,_/\__/_/_/ /_/\__, / /_/ |_/\__,_/_/ /_/ /_/_.___/\___/_/
1426 /____/
1427*/
1428
1438
1445static __jo_force_inline void jo_vectorf_add(const jo_vectorf * const a, const jo_vectorf * const b, jo_vectorf * const result)
1446{
1447 result->x = a->x + b->x;
1448 result->y = a->y + b->y;
1449 result->z = a->z + b->z;
1450}
1451
1458static __jo_force_inline void jo_vectorf_adds(const jo_vectorf * const a, const float s, jo_vectorf * const result)
1459{
1460 result->x = a->x + s;
1461 result->y = a->y + s;
1462 result->z = a->z + s;
1463}
1464
1471static __jo_force_inline void jo_vectorf_sub(const jo_vectorf * const a, const jo_vectorf * const b, jo_vectorf * const result)
1472{
1473 result->x = a->x - b->x;
1474 result->y = a->y - b->y;
1475 result->z = a->z - b->z;
1476}
1477
1484static __jo_force_inline void jo_vectorf_subs(const jo_vectorf * const a, const float s, jo_vectorf * const result)
1485{
1486 result->x = a->x - s;
1487 result->y = a->y - s;
1488 result->z = a->z - s;
1489}
1490
1497static __jo_force_inline void jo_vectorf_mul(const jo_vectorf * const a, const jo_vectorf * const b, jo_vectorf * const result)
1498{
1499 result->x = a->x * b->x;
1500 result->y = a->y * b->y;
1501 result->z = a->z * b->z;
1502}
1503
1510static __jo_force_inline void jo_vectorf_muls(const jo_vectorf * const a, const float s, jo_vectorf * const result)
1511{
1512 result->x = a->x * s;
1513 result->y = a->y * s;
1514 result->z = a->z * s;
1515}
1516
1523static __jo_force_inline void jo_vectorf_div(const jo_vectorf * const a, const jo_vectorf * const b, jo_vectorf * const result)
1524{
1525 result->x = a->x / b->x;
1526 result->y = a->y / b->y;
1527 result->z = a->z / b->z;
1528}
1529
1536static __jo_force_inline void jo_vectorf_divs(const jo_vectorf * const a, const float s, jo_vectorf * const result)
1537{
1538 float inv;
1539
1540 // One division (libgcc on the SH-2) and 3 multiplications instead of 3 divisions
1541 inv = 1.0f / s;
1542 result->x = a->x * inv;
1543 result->y = a->y * inv;
1544 result->z = a->z * inv;
1545}
1546
1552{
1553 return (jo_sqrtf(JO_SQUARE(a->x) + JO_SQUARE(a->y) + JO_SQUARE(a->z)));
1554}
1555
1561static __jo_force_inline float jo_vectorf_dot(const jo_vectorf * const a, const jo_vectorf * const b)
1562{
1563 return (a->x * b->x + a->y * b->y + a->z * b->z);
1564}
1565
1571static __jo_force_inline void jo_vectorf_normalize(const jo_vectorf * const a, jo_vectorf * const result)
1572{
1573 float len = jo_vectorf_length(a);
1574 if (len > 0)
1575 {
1576 // One division (libgcc on the SH-2) and 3 multiplications instead of 3 divisions
1577 float inv = 1.0f / len;
1578 result->x = a->x * inv;
1579 result->y = a->y * inv;
1580 result->z = a->z * inv;
1581 }
1582 else
1583 {
1584 result->x = 0;
1585 result->y = 0;
1586 result->z = 0;
1587 }
1588}
1589
1595static __jo_force_inline void jo_vectorf_proj(const jo_vectorf * const v, const jo_vectorf * const onto, jo_vectorf * const result)
1596{
1597 jo_vectorf_muls(onto, jo_vectorf_dot(v, onto) / jo_vectorf_dot(onto, onto), result);
1598}
1599
1606static __jo_force_inline void jo_vectorf_cross(const jo_vectorf * const a, const jo_vectorf * const b, jo_vectorf * const result)
1607{
1608 result->x = a->y * b->z - a->z * b->y;
1609 result->y = a->z * b->x - a->x * b->z;
1610 result->z = a->x * b->y - a->y * b->x;
1611}
1612
1618static __jo_force_inline float jo_vectorf_angle_between_radf(const jo_vectorf * const a, const jo_vectorf * const b)
1619{
1620 // One square root: sqrt(|a|^2 * |b|^2) = |a| * |b|
1621 return jo_acos_radf(jo_vectorf_dot(a, b) / jo_sqrtf(jo_vectorf_dot(a, a) * jo_vectorf_dot(b, b)));
1622}
1623
1624/*
1625██╗ ██╗██╗ ██╗██╗ ██╗ ███╗ ███╗ █████╗ ████████╗██████╗ ██╗██╗ ██╗
1626██║ ██║╚██╗██╔╝██║ ██║ ████╗ ████║██╔══██╗╚══██╔══╝██╔══██╗██║╚██╗██╔╝
1627███████║ ╚███╔╝ ███████║ ██╔████╔██║███████║ ██║ ██████╔╝██║ ╚███╔╝
1628╚════██║ ██╔██╗ ╚════██║ ██║╚██╔╝██║██╔══██║ ██║ ██╔══██╗██║ ██╔██╗
1629 ██║██╔╝ ██╗ ██║ ██║ ╚═╝ ██║██║ ██║ ██║ ██║ ██║██║██╔╝ ██╗
1630 ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═╝
1631
1632*/
1633
1638{
1639 register int i;
1640
1641 for (i = 1; i < 15; ++i)
1642 JO_ZERO(result->table[i]);
1643 result->m00 = JO_FIXED_1;
1644 result->m11 = JO_FIXED_1;
1645 result->m22 = JO_FIXED_1;
1646 result->m33 = JO_FIXED_1;
1647}
1648
1653{
1654 register int i;
1655
1656 for (i = 1; i < 15; ++i)
1657 result->table[i] = 0;
1658 result->m00 = 1;
1659 result->m11 = 1;
1660 result->m22 = 1;
1661 result->m33 = 1;
1662}
1663
1668static __jo_force_inline void jo_matrix_translation(const jo_vector_fixed * const offset, jo_matrix * const result)
1669{
1670 jo_matrix_identity(result);
1671 result->m30 = offset->x;
1672 result->m31 = offset->y;
1673 result->m32 = offset->z;
1674}
1675
1680static __jo_force_inline void jo_matrixf_translation(const jo_vectorf * const offset, jo_matrixf * const result)
1681{
1682 jo_matrixf_identity(result);
1683 result->m30 = offset->x;
1684 result->m31 = offset->y;
1685 result->m32 = offset->z;
1686}
1687
1692static __jo_force_inline void jo_matrix_scaling(const jo_vector_fixed * const scale, jo_matrix * const result)
1693{
1694 jo_matrix_identity(result);
1695 result->m00 = scale->x;
1696 result->m11 = scale->y;
1697 result->m22 = scale->z;
1698}
1699
1704static __jo_force_inline void jo_matrixf_scaling(const jo_vectorf * const scale, jo_matrixf * const result)
1705{
1706 jo_matrixf_identity(result);
1707 result->m00 = scale->x;
1708 result->m11 = scale->y;
1709 result->m22 = scale->z;
1710}
1711
1716static __jo_force_inline void jo_matrix_rotation_x_rad(const float angle_in_rad, jo_matrix * const result)
1717{
1718 jo_matrix_identity(result);
1719 // The float angle is converted once (same values as jo_cos_rad() and jo_sin_rad())
1720 jo_sincos_angle(jo_fixed_rad2ANGLE(jo_float2fixed(angle_in_rad)), &result->m12, &result->m11);
1721 result->m21 = -result->m12;
1722 result->m22 = result->m11;
1723}
1724
1729static __jo_force_inline void jo_matrixf_rotation_x_rad(const float angle_in_rad, jo_matrixf * const result)
1730{
1731 jo_matrixf_identity(result);
1732 result->m11 = jo_cos_radf(angle_in_rad);
1733 result->m12 = jo_sin_radf(angle_in_rad);
1734 result->m21 = -result->m12;
1735 result->m22 = result->m11;
1736}
1737
1742static __jo_force_inline void jo_matrix_rotation_y_rad(const float angle_in_rad, jo_matrix * const result)
1743{
1744 jo_matrix_identity(result);
1745 // The float angle is converted once (same values as jo_cos_rad() and jo_sin_rad())
1746 jo_sincos_angle(jo_fixed_rad2ANGLE(jo_float2fixed(angle_in_rad)), &result->m20, &result->m00);
1747 result->m02 = -result->m20;
1748 result->m22 = result->m00;
1749}
1750
1755static __jo_force_inline void jo_matrixf_rotation_y_rad(const float angle_in_rad, jo_matrixf * const result)
1756{
1757 jo_matrixf_identity(result);
1758 result->m00 = jo_cos_radf(angle_in_rad);
1759 result->m20 = jo_sin_radf(angle_in_rad);
1760 result->m02 = -result->m20;
1761 result->m22 = result->m00;
1762}
1763
1768static __jo_force_inline void jo_matrix_rotation_z_rad(const float angle_in_rad, jo_matrix * const result)
1769{
1770 jo_matrix_identity(result);
1771 // The float angle is converted once (same values as jo_cos_rad() and jo_sin_rad())
1772 jo_sincos_angle(jo_fixed_rad2ANGLE(jo_float2fixed(angle_in_rad)), &result->m01, &result->m00);
1773 result->m10 = -result->m01;
1774 result->m11 = result->m00;
1775}
1776
1781static __jo_force_inline void jo_matrixf_rotation_z_rad(const float angle_in_rad, jo_matrixf * const result)
1782{
1783 jo_matrixf_identity(result);
1784 result->m00 = jo_cos_radf(angle_in_rad);
1785 result->m01 = jo_sin_radf(angle_in_rad);
1786 result->m10 = -result->m01;
1787 result->m11 = result->m00;
1788}
1789
1795static __jo_force_inline void jo_matrix_transpose(const jo_matrix * const matrix, jo_matrix * const result)
1796{
1797 result->m00 = matrix->m00;
1798 result->m10 = matrix->m01;
1799 result->m20 = matrix->m02;
1800 result->m30 = matrix->m03;
1801 result->m01 = matrix->m10;
1802 result->m11 = matrix->m11;
1803 result->m21 = matrix->m12;
1804 result->m31 = matrix->m13;
1805 result->m02 = matrix->m20;
1806 result->m12 = matrix->m21;
1807 result->m22 = matrix->m22;
1808 result->m32 = matrix->m23;
1809 result->m03 = matrix->m30;
1810 result->m13 = matrix->m31;
1811 result->m23 = matrix->m32;
1812 result->m33 = matrix->m33;
1813}
1814
1820static __jo_force_inline void jo_matrixf_transpose(const jo_matrixf * const matrix, jo_matrixf * const result)
1821{
1822 result->m00 = matrix->m00;
1823 result->m10 = matrix->m01;
1824 result->m20 = matrix->m02;
1825 result->m30 = matrix->m03;
1826 result->m01 = matrix->m10;
1827 result->m11 = matrix->m11;
1828 result->m21 = matrix->m12;
1829 result->m31 = matrix->m13;
1830 result->m02 = matrix->m20;
1831 result->m12 = matrix->m21;
1832 result->m22 = matrix->m22;
1833 result->m32 = matrix->m23;
1834 result->m03 = matrix->m30;
1835 result->m13 = matrix->m31;
1836 result->m23 = matrix->m32;
1837 result->m33 = matrix->m33;
1838}
1839
1846static __jo_force_inline void jo_matrix_mul_vector4(const jo_matrix * const m, const jo_vector4_fixed * const v, jo_vector4_fixed * const result)
1847{
1848 result->x = jo_fixed_mult(m->m00, v->x) + jo_fixed_mult(m->m10, v->y) + jo_fixed_mult(m->m20, v->z) + jo_fixed_mult(m->m30, v->w);
1849 result->y = jo_fixed_mult(m->m01, v->x) + jo_fixed_mult(m->m11, v->y) + jo_fixed_mult(m->m21, v->z) + jo_fixed_mult(m->m31, v->w);
1850 result->z = jo_fixed_mult(m->m02, v->x) + jo_fixed_mult(m->m12, v->y) + jo_fixed_mult(m->m22, v->z) + jo_fixed_mult(m->m32, v->w);
1851 result->w = jo_fixed_mult(m->m03, v->x) + jo_fixed_mult(m->m13, v->y) + jo_fixed_mult(m->m23, v->z) + jo_fixed_mult(m->m33, v->w);
1852}
1853
1861{
1862 const jo_fixed *a;
1863 const jo_fixed *b;
1864 jo_fixed high;
1865 jo_fixed low;
1866
1867 a = ptA;
1868 b = ptB;
1869 __asm__ ("clrmac\n\t"
1870 "mac.l @%2+, @%3+\n\t"
1871 "mac.l @%2+, @%3+\n\t"
1872 "mac.l @%2+, @%3+\n\t"
1873 "mac.l @%2+, @%3+\n\t"
1874 "sts mach, %0\n\t"
1875 "sts macl, %1\n\t"
1876 "xtrct %0, %1"
1877 : "=&r" (high), "=&r" (low), "+r" (a), "+r" (b)
1878 : "m" (*(const jo_fixed (*)[4])ptA), "m" (*(const jo_fixed (*)[4])ptB)
1879 : "mach", "macl");
1880 return (low);
1881}
1882
1891static __jo_force_inline void jo_matrix_mul(const jo_matrix * const a, const jo_matrix * const b, jo_matrix * const result)
1892{
1893 jo_matrix at;
1894 register int i;
1895 register int j;
1896
1897 // The columns of a become contiguous rows: result->m[i][j] = sum of a->m[k][j] * b->m[i][k]
1898 jo_matrix_transpose(a, &at);
1899 for (i = 0; i < 4; ++i)
1900 for (j = 0; j < 4; ++j)
1901 result->m[i][j] = __jo_fixed_dot4(at.m[j], b->m[i]);
1902}
1903
1910static __jo_force_inline void jo_matrixf_mul(const jo_matrixf * const a, const jo_matrixf * const b, jo_matrixf * const result)
1911{
1912 register int i;
1913 register int j;
1914 register int k;
1915 register float sum;
1916
1917 for (i = 0; i < 4; ++i)
1918 {
1919 for (j = 0; j < 4; ++j)
1920 {
1921 sum = 0;
1922 for (k = 0; k < 4; ++k)
1923 sum += a->m[k][j] * b->m[i][k];
1924 result->m[i][j] = sum;
1925 }
1926 }
1927}
1928
1934static __jo_force_inline void jo_matrixf_rotation(const float angle_in_rad, const jo_vectorf * const axis, jo_matrixf * const result)
1935{
1936 jo_vectorf normalized_axis;
1937
1938 jo_vectorf_normalize(axis, &normalized_axis);
1939 float c = jo_cos_radf(angle_in_rad);
1940 float s = jo_sin_radf(angle_in_rad);
1941 float a = 1 - c;
1942 jo_matrixf_identity(result);
1943 result->m00 = c + normalized_axis.x * normalized_axis.x * a;
1944 result->m10 = normalized_axis.x * normalized_axis.y * a - normalized_axis.z * s;
1945 result->m20 = normalized_axis.x * normalized_axis.z * a + normalized_axis.y * s;
1946 result->m01 = normalized_axis.y * normalized_axis.x * a + normalized_axis.z * s;
1947 result->m11 = c + normalized_axis.y * normalized_axis.y * a;
1948 result->m21 = normalized_axis.y * normalized_axis.z * a - normalized_axis.x * s;
1949 result->m02 = normalized_axis.z * normalized_axis.x * a - normalized_axis.y * s;
1950 result->m12 = normalized_axis.z * normalized_axis.y * a + normalized_axis.x * s;
1951 result->m22 = c + normalized_axis.z * normalized_axis.z * a;
1952}
1953
1963static __jo_force_inline void jo_matrixf_ortho(const float left, const float right, const float bottom, const float top,
1964 const float back, const float front, jo_matrixf * const result)
1965{
1966 jo_matrixf_identity(result);
1967 result->m00 = 2 / (right - left);
1968 result->m11 = 2 / (top - bottom);
1969 result->m22 = 2 / (back - front);
1970 result->m30 = -(right + left) / (right - left);
1971 result->m31 = -(top + bottom) / (top - bottom);
1972 result->m32 = -(back + front) / (back - front);
1973}
1974
1983static __jo_force_inline void jo_matrixf_perspective(const float vertical_field_of_view_in_deg, const float aspect_ratio,
1984 const float near_view_distance, const float far_view_distance, jo_matrixf * const result)
1985{
1986 jo_matrixf_identity(result);
1987 result->m11 = 1.0f / jo_tan_radf(vertical_field_of_view_in_deg * (JO_PI / 360.0f));
1988 result->m00 = result->m11 / aspect_ratio;
1989 result->m22 = (far_view_distance + near_view_distance) / (near_view_distance - far_view_distance);
1990 result->m32 = (2 * far_view_distance * near_view_distance) / (near_view_distance - far_view_distance);
1991 result->m23 = -1;
1992 result->m33 = 0;
1993}
1994
2001static __jo_force_inline void jo_matrixf_look_at(const jo_vectorf * const from, const jo_vectorf * const to,
2002 const jo_vectorf * const up, jo_matrixf * const result)
2003{
2004 jo_vectorf tmp;
2005 jo_vectorf x;
2006 jo_vectorf y;
2007 jo_vectorf z;
2008
2009 jo_vectorf_sub(to, from, &tmp);
2010 jo_vectorf_normalize(&tmp, &tmp);
2011 jo_vectorf_muls(&tmp, -1, &z);
2012 jo_vectorf_cross(up, &z, &tmp);
2013 jo_vectorf_normalize(&tmp, &x);
2014 jo_vectorf_cross(&z, &x, &y);
2015
2016 jo_matrixf_identity(result);
2017 result->m00 = x.x;
2018 result->m10 = x.y;
2019 result->m20 = x.z;
2020 result->m30 = -jo_vectorf_dot(from, &x);
2021 result->m01 = y.x;
2022 result->m11 = y.y;
2023 result->m21 = y.z;
2024 result->m31 = -jo_vectorf_dot(from, &y);
2025 result->m02 = z.x;
2026 result->m12 = z.y;
2027 result->m22 = z.z;
2028 result->m33 = -jo_vectorf_dot(from, &z);
2029}
2030
2035static __jo_force_inline void jo_matrixf_invert_affine(const jo_matrixf * const matrix, jo_matrixf * const result)
2036{
2037 float c00 = matrix->m11 * matrix->m22 - matrix->m12 * matrix->m21;
2038 float c10 = -(matrix->m01 * matrix->m22 - matrix->m02 * matrix->m21);
2039 float c20 = matrix->m01 * matrix->m12 - matrix->m02 * matrix->m11;
2040 float det = matrix->m00 * c00 + matrix->m10 * c10 + matrix->m20 * c20;
2041 jo_matrixf_identity(result);
2042 if (JO_FABS(det) < JO_FLOAT_EPSILON)
2043 return;
2044 float c01 = -(matrix->m10 * matrix->m22 - matrix->m12 * matrix->m20);
2045 float c11 = matrix->m00 * matrix->m22 - matrix->m02 * matrix->m20;
2046 float c21 = -(matrix->m00 * matrix->m12 - matrix->m02 * matrix->m10);
2047 float c02 = matrix->m10 * matrix->m21 - matrix->m11 * matrix->m20;
2048 float c12 = -(matrix->m00 * matrix->m21 - matrix->m01 * matrix->m20);
2049 float c22 = matrix->m00 * matrix->m11 - matrix->m01 * matrix->m10;
2050 // One division (libgcc on the SH-2) and 9 multiplications instead of 9 divisions
2051 float inv_det = 1.0f / det;
2052 float i00 = c00 * inv_det;
2053 float i10 = c01 * inv_det;
2054 float i20 = c02 * inv_det;
2055 float i01 = c10 * inv_det;
2056 float i11 = c11 * inv_det;
2057 float i21 = c12 * inv_det;
2058 float i02 = c20 * inv_det;
2059 float i12 = c21 * inv_det;
2060 float i22 = c22 * inv_det;
2061
2062 result->m00 = i00;
2063 result->m10 = i10;
2064 result->m20 = i20;
2065 result->m30 = -(i00 * matrix->m30 + i10 * matrix->m31 + i20 * matrix->m32);
2066 result->m01 = i01;
2067 result->m11 = i11;
2068 result->m21 = i21;
2069 result->m31 = -(i01 * matrix->m30 + i11 * matrix->m31 + i21 * matrix->m32);
2070 result->m02 = i02;
2071 result->m12 = i12;
2072 result->m22 = i22;
2073 result->m32 = -(i02 * matrix->m30 + i12 * matrix->m31 + i22 * matrix->m32);
2074}
2075
2081static __jo_force_inline void jo_matrixf_mul_pos(const jo_matrixf * const matrix, const jo_vectorf * const position,
2082 jo_vectorf * const result)
2083{
2084 float w = matrix->m03 * position->x + matrix->m13 * position->y + matrix->m23 * position->z + matrix->m33;
2085 result->x = matrix->m00 * position->x + matrix->m10 * position->y + matrix->m20 * position->z + matrix->m30;
2086 result->y = matrix->m01 * position->x + matrix->m11 * position->y + matrix->m21 * position->z + matrix->m31;
2087 result->z = matrix->m02 * position->x + matrix->m12 * position->y + matrix->m22 * position->z + matrix->m32;
2088 if (w != 0 && w != 1)
2089 {
2090 // One division (libgcc on the SH-2) and 3 multiplications instead of 3 divisions
2091 float inv_w = 1.0f / w;
2092 result->x *= inv_w;
2093 result->y *= inv_w;
2094 result->z *= inv_w;
2095 }
2096}
2097
2103static __jo_force_inline void jo_matrixf_mul_dir(const jo_matrixf * const matrix, const jo_vectorf * const direction,
2104 jo_vectorf * const result)
2105{
2106 float w = matrix->m03 * direction->x + matrix->m13 * direction->y + matrix->m23 * direction->z;
2107 result->x = matrix->m00 * direction->x + matrix->m10 * direction->y + matrix->m20 * direction->z;
2108 result->y = matrix->m01 * direction->x + matrix->m11 * direction->y + matrix->m21 * direction->z;
2109 result->z = matrix->m02 * direction->x + matrix->m12 * direction->y + matrix->m22 * direction->z;
2110 if (w != 0 && w != 1)
2111 {
2112 // One division (libgcc on the SH-2) and 3 multiplications instead of 3 divisions
2113 float inv_w = 1.0f / w;
2114 result->x *= inv_w;
2115 result->y *= inv_w;
2116 result->z *= inv_w;
2117 }
2118}
2119
2120/*
2121███╗ ███╗██╗███████╗ ██████╗
2122████╗ ████║██║██╔════╝██╔════╝
2123██╔████╔██║██║███████╗██║
2124██║╚██╔╝██║██║╚════██║██║
2125██║ ╚═╝ ██║██║███████║╚██████╗
2126╚═╝ ╚═╝╚═╝╚══════╝ ╚═════╝
2127
2128*/
2129
2136static __jo_force_inline jo_fixed jo_lerp(const jo_fixed v0, const jo_fixed v1, const jo_fixed t)
2137{
2138 return (jo_fixed_mult((JO_FIXED_1 - t), v0) + jo_fixed_mult(t, v1));
2139}
2140
2146{
2147 return (JO_ABS(f) < 0.00000001f);
2148}
2149
2161static __jo_force_inline bool jo_square_intersect(const int x1, const int y1, const int w1, const int h1,
2162 const int x2, const int y2, const int w2, const int h2)
2163{
2164 return ((x1 < x2 + w2) && (x2 < x1 + w1)) && ((y1 < y2 + h2) && (y2 < y1 + h1));
2165}
2166
2173int jo_gcd(int a, int b);
2174
2182void jo_planar_rotate(const jo_pos2D * const point, const jo_pos2D * const origin, const int angle, jo_pos2D * const result);
2183
2189{
2190 switch (direction)
2191 {
2192 case LEFT:
2193 return (180);
2194 case RIGHT:
2195 return (0);
2196 case UP:
2197 return (270);
2198 case DOWN:
2199 return (90);
2200 case UP_LEFT:
2201 return (225);
2202 case UP_RIGHT:
2203 return (315);
2204 case DOWN_LEFT:
2205 return (135);
2206 case DOWN_RIGHT:
2207 return (45);
2208 default:
2209 return (0);
2210 }
2211}
2212
2213#endif /* !__JO_MATH_H__ */
2214
2215/*
2216** END OF FILE
2217*/
2218
static __jo_force_inline void jo_matrixf_transpose(const jo_matrixf *const matrix, jo_matrixf *const result)
Creates transpose matrix (using floating numbers).
Definition math.h:1820
static __jo_force_inline jo_fixed jo_int2fixed(const int x)
Convert int to jo engine fixed.
Definition math.h:479
static __jo_force_inline void jo_matrix_rotation_y_rad(const float angle_in_rad, jo_matrix *const result)
Creates rotating matrix (Y axis) (using fixed numbers).
Definition math.h:1742
static __jo_force_inline jo_angle jo_DEGtoANG(const float deg)
Convert a degree to jo_angle using floating number.
Definition math.h:861
#define JO_PI
PI value.
Definition math.h:51
static __jo_force_inline void jo_matrix_mul(const jo_matrix *const a, const jo_matrix *const b, jo_matrix *const result)
Multiply 2 matrix (using fixed numbers).
Definition math.h:1891
static __jo_force_inline void jo_matrixf_rotation_z_rad(const float angle_in_rad, jo_matrixf *const result)
Creates rotating matrix (Z axis) (using floating numbers).
Definition math.h:1781
static __jo_force_inline void jo_vector4_fixed_cross(const jo_vector4_fixed *const a, const jo_vector4_fixed *const b, jo_vector4_fixed *const result)
Cross product of 2 vectors4 (using fixed numbers).
Definition math.h:1389
static __jo_force_inline void jo_matrix_rotation_z_rad(const float angle_in_rad, jo_matrix *const result)
Creates rotating matrix (Z axis) (using fixed numbers).
Definition math.h:1768
void jo_planar_rotate(const jo_pos2D *const point, const jo_pos2D *const origin, const int angle, jo_pos2D *const result)
Rotate a point on the plan with a specific origin.
static __jo_force_inline jo_angle jo_DEGtoANG_int(const int deg)
Convert a degree to jo_angle using interger.
Definition math.h:871
void jo_vector_fixed_compute_bezier_point(const jo_fixed t, jo_vector_fixed p0, jo_vector_fixed p1, jo_vector_fixed p2, jo_vector_fixed p3, jo_vector_fixed *result)
Compute cubic bezier curve point for vectors (using fixed numbers).
static __jo_force_inline jo_fixed jo_sin_rad(const float rad)
Sinus computation.
Definition math.h:1010
static __jo_force_inline jo_fixed __jo_sin_index(const unsigned int index)
Sinus of a table index (Internal usage).
Definition math.h:902
static __jo_force_inline void jo_vectorf_add(const jo_vectorf *const a, const jo_vectorf *const b, jo_vectorf *const result)
Add 2 vectors (using floating numbers).
Definition math.h:1445
unsigned int jo_sqrt(unsigned int value)
Fast square root.
jo_angle jo_atan2_fixed(const jo_fixed y, const jo_fixed x)
ATAN2 as a jo_angle without floating point (fixed numbers).
static __jo_force_inline jo_fixed jo_fixed_div_result(void)
Get the result of the division started by jo_fixed_div_start().
Definition math.h:671
static __jo_force_inline void jo_matrixf_look_at(const jo_vectorf *const from, const jo_vectorf *const to, const jo_vectorf *const up, jo_matrixf *const result)
Builds a transformation matrix for a camera (using floating numbers).
Definition math.h:2001
static __jo_force_inline void jo_matrixf_translation(const jo_vectorf *const offset, jo_matrixf *const result)
Creates translation matrix (using floating numbers).
Definition math.h:1680
static __jo_force_inline float jo_cosf_mult(const float value, const int deg)
Fast cosinus multiplication.
Definition math.h:1133
void jo_vectorf_compute_bezier_point(const float t, jo_vectorf p0, jo_vectorf p1, jo_vectorf p2, jo_vectorf p3, jo_vectorf *result)
Compute cubic bezier curve point for vectors (using floating numbers).
float jo_rsqrt(float value)
Fast Reciprocal Square root using floating number.
static __jo_force_inline void jo_matrixf_perspective(const float vertical_field_of_view_in_deg, const float aspect_ratio, const float near_view_distance, const float far_view_distance, jo_matrixf *const result)
Creates a perspective projection matrix for a camera (using floating numbers).
Definition math.h:1983
#define JO_FIXED_PI_DIV_180
Fixed value of PI/180.
Definition math.h:442
static __jo_force_inline jo_fixed __jo_fixed_dot4(const jo_fixed ptA[4], const jo_fixed ptB[4])
Dot product of 2 vectors of 4 fixed numbers (Internal usage).
Definition math.h:1860
static __jo_force_inline float jo_vectorf_angle_between_radf(const jo_vectorf *const a, const jo_vectorf *const b)
Get the angle between 2 vectors (using floating numbers).
Definition math.h:1618
static __jo_force_inline float jo_sin_radf(const float rad)
Sinus computation.
Definition math.h:1020
static __jo_force_inline void jo_matrixf_rotation_y_rad(const float angle_in_rad, jo_matrixf *const result)
Creates rotating matrix (Y axis) (using floating numbers).
Definition math.h:1755
#define JO_RAD_TO_DEG(A)
Convert radians to degrees.
Definition math.h:298
static __jo_force_inline void jo_matrixf_ortho(const float left, const float right, const float bottom, const float top, const float back, const float front, jo_matrixf *const result)
Creates an orthographic projection matrix (using floating numbers).
Definition math.h:1963
static __jo_force_inline float jo_sinf(const int deg)
Sinus computation.
Definition math.h:1000
static __jo_force_inline void jo_vectorf_proj(const jo_vectorf *const v, const jo_vectorf *const onto, jo_vectorf *const result)
Compute projection vector (using floating numbers).
Definition math.h:1595
int jo_random(int max)
Get a random number.
static __jo_force_inline void jo_vectorf_cross(const jo_vectorf *const a, const jo_vectorf *const b, jo_vectorf *const result)
Cross 2 vectors (using floating numbers).
Definition math.h:1606
static __jo_force_inline int jo_atan2f(const float y, const float x)
Fast ATAN2 computation in degree.
Definition math.h:1238
static __jo_force_inline void jo_matrix_mul_vector4(const jo_matrix *const m, const jo_vector4_fixed *const v, jo_vector4_fixed *const result)
Multiply a matrix by a vector4 (using fixed numbers).
Definition math.h:1846
static __jo_force_inline jo_fixed jo_fixed_floor(const jo_fixed x)
Returns the largest (fixed) integer value less than or equal to x.
Definition math.h:707
static __jo_force_inline void jo_matrix_translation(const jo_vector_fixed *const offset, jo_matrix *const result)
Creates translation matrix (using fixed numbers).
Definition math.h:1668
static __jo_force_inline jo_fixed jo_fixed_dot(const jo_fixed ptA[3], const jo_fixed ptB[3])
Dot product two fixed 3D points.
Definition math.h:576
int jo_gcd(int a, int b)
Get the greatest common divisor.
static __jo_force_inline unsigned int jo_highest_bit(unsigned int x)
Index of the highest bit set in a value (31 - number of leading zeros).
Definition math.h:758
static __jo_force_inline void jo_sincos(const int deg, jo_fixed *const sin_value, jo_fixed *const cos_value)
Sinus and cosinus of the same angle in degree (table lookup, fast).
Definition math.h:1082
static __jo_force_inline void jo_sincos_angle(const jo_angle angle, jo_fixed *const sin_value, jo_fixed *const cos_value)
Sinus and cosinus of the same angle (table lookup, fast).
Definition math.h:947
static __jo_force_inline void jo_matrixf_scaling(const jo_vectorf *const scale, jo_matrixf *const result)
Creates scaling matrix (using floating numbers).
Definition math.h:1704
const jo_fixed __jo_sin_table[1025]
Sinus table: sin(x) for x in [0, pi/2] (1024 steps, Q16.16) (Internal usage, see math....
static __jo_force_inline jo_fixed jo_cos_angle(const jo_angle angle)
Cosinus of an angle (table lookup, fast).
Definition math.h:936
static __jo_force_inline int jo_turn_toward(const int angle, const int target, const int max_step)
Turn an angle toward another angle, by the shortest way.
Definition math.h:1280
static __jo_force_inline int jo_fixed_mult_to_int(const jo_fixed x, const jo_fixed y)
Multiply to fixed number and keep the integer part: jo_fixed2int(jo_fixed_mult(x, y)),...
Definition math.h:557
static __jo_force_inline jo_angle jo_atan2_angle(const float y, const float x)
ATAN2 as a jo_angle (65536 per turn, like jo_sin_angle() and the rotations of the 3D).
Definition math.h:1249
#define JO_SQUARE(A)
Square computation (x²).
Definition math.h:335
static __jo_force_inline float jo_tan_radf(const float rad)
Tangent computation.
Definition math.h:1190
static __jo_force_inline jo_fixed jo_sin_angle(const jo_angle angle)
Sinus of an angle (table lookup, fast).
Definition math.h:927
static __jo_force_inline jo_fixed jo_tan(const int deg)
Fast tangent computation.
Definition math.h:1152
static __jo_force_inline void jo_vector4_fixed_sub(const jo_vector4_fixed *const a, const jo_vector4_fixed *const b, jo_vector4_fixed *const result)
Substract 2 vectors4 (using fixed numbers).
Definition math.h:1376
static __jo_force_inline void jo_matrixf_rotation(const float angle_in_rad, const jo_vectorf *const axis, jo_matrixf *const result)
Creates a matrix to rotate around an axis by a given angle in radiant (using floating numbers).
Definition math.h:1934
static __jo_force_inline void jo_vector4_fixed_add(const jo_vector4_fixed *const a, const jo_vector4_fixed *const b, jo_vector4_fixed *const result)
Add 2 vectors4 (using fixed numbers).
Definition math.h:1362
static __jo_force_inline jo_angle jo_fixed_deg2ANGLE(const jo_fixed deg)
Convert fixed degree to jo_angle.
Definition math.h:960
#define JO_SWAP(A, B)
Swap A and B values.
Definition math.h:315
#define JO_FIXED_TO_INT(X)
Convert jo_fixed to int.
Definition math.h:459
static __jo_force_inline bool jo_square_intersect(const int x1, const int y1, const int w1, const int h1, const int x2, const int y2, const int w2, const int h2)
Fast method to get if two square intersects (HitBox processing).
Definition math.h:2161
int jo_random_seed
Get or set current random seed.
static __jo_force_inline float jo_fixed2float(const jo_fixed x)
Convert jo engine fixed to float.
Definition math.h:506
static __jo_force_inline float jo_acos_radf(const float angle)
Fast Arc Cosinus computation (linear approximation).
Definition math.h:1209
static __jo_force_inline void jo_vectorf_mul(const jo_vectorf *const a, const jo_vectorf *const b, jo_vectorf *const result)
Multiply 2 vectors (using floating numbers).
Definition math.h:1497
static __jo_force_inline void jo_vector_fixed_add(const jo_vector_fixed *const a, const jo_vector_fixed *const b, jo_vector_fixed *const result)
Add 2 vectors (using fixed numbers).
Definition math.h:1336
static __jo_force_inline int jo_shift_right8_small(const int x)
Arithmetic right shift by 8 bits (x >> 8) of a value in [-2^23, 2^23) (a 16 bits value x 0 to 256 for...
Definition math.h:649
static __jo_force_inline jo_fixed jo_lerp(const jo_fixed v0, const jo_fixed v1, const jo_fixed t)
Linear interpolation which guarantees v = v1 when t = 1.
Definition math.h:2136
static __jo_force_inline void jo_vector_fixed_muls(const jo_vector_fixed *const a, const jo_fixed s, jo_vector_fixed *const result)
Multiply value to vector (using fixed numbers).
Definition math.h:1349
#define JO_FLOAT_EPSILON
Float minimum positive value.
Definition math.h:282
static __jo_force_inline int jo_shift_right8(const int x)
Arithmetic right shift by 8 bits (x >> 8, rounded toward minus infinity) of any value.
Definition math.h:638
static __jo_force_inline void jo_vectorf_adds(const jo_vectorf *const a, const float s, jo_vectorf *const result)
Add value to vector (using floating numbers).
Definition math.h:1458
static __jo_force_inline void jo_vectorf_subs(const jo_vectorf *const a, const float s, jo_vectorf *const result)
Subtract value to vector (using floating numbers).
Definition math.h:1484
static __jo_force_inline float jo_sinf_mult(const float value, const int deg)
Fast sinus multiplication.
Definition math.h:1041
static __jo_force_inline short jo_direction_to_angle(const jo_8_directions direction)
Convert jo_8_directions to angle in degree.
Definition math.h:2188
jo_fixed jo_fixed_rsqrt(jo_fixed value)
Fast Reciprocal Square root using fixed number.
static __jo_force_inline float jo_cos_radf(const float rad)
Cosinus computation.
Definition math.h:1112
jo_fixed jo_fixed_pow(jo_fixed x, jo_fixed y)
x raised to the power of the integer part of y
static __jo_force_inline jo_fixed jo_tan_rad(const float rad)
Tangent computation.
Definition math.h:1176
static __jo_force_inline jo_fixed jo_fixed_rad2deg(const jo_fixed rad)
Convert fixed radian to fixed degree.
Definition math.h:689
#define JO_FABS(X)
Get the absolute value of X.
Definition math.h:262
static __jo_force_inline jo_fixed jo_float2fixed(const float x)
Convert float to jo engine fixed (avoid usage of GCC Soft Float).
Definition math.h:497
static __jo_force_inline int jo_random_using_multiple(int max, int multiple)
Get a random number with a specific multiple.
Definition math.h:739
static __jo_force_inline void jo_vector4_swap(jo_vector4_fixed *const a, jo_vector4_fixed *const b)
Swap 2 vectors4 (using fixed numbers).
Definition math.h:1412
static __jo_force_inline int jo_fixed2int(const jo_fixed x)
Convert jo engine fixed to int.
Definition math.h:488
static __jo_force_inline void jo_matrixf_mul_dir(const jo_matrixf *const matrix, const jo_vectorf *const direction, jo_vectorf *const result)
Multiplies a 4x4 matrix with a 3D vector representing a direction in 3D space (using floating numbers...
Definition math.h:2103
static __jo_force_inline void jo_vectorf_divs(const jo_vectorf *const a, const float s, jo_vectorf *const result)
Divide value to vector (using floating numbers).
Definition math.h:1536
jo_fixed jo_fixed_sqrt(jo_fixed value)
Fast Square root using fixed number.
#define JO_ABS(X)
Get the absolute value of X.
Definition math.h:257
static __jo_force_inline float jo_cosf(const int deg)
Cosinus computation.
Definition math.h:1092
#define JO_FIXED_360
Fixed floating point value for 360.
Definition math.h:425
static __jo_force_inline jo_fixed jo_cos_rad(const float rad)
Cosinus computation.
Definition math.h:1102
static __jo_force_inline void jo_matrixf_mul_pos(const jo_matrixf *const matrix, const jo_vectorf *const position, jo_vectorf *const result)
Multiplies a 4x4 matrix with a 3D vector representing a point in 3D space (using floating numbers).
Definition math.h:2081
static __jo_force_inline void jo_matrix_scaling(const jo_vector_fixed *const scale, jo_matrix *const result)
Creates scaling matrix (using fixed numbers).
Definition math.h:1692
static __jo_force_inline jo_fixed jo_fixed_wrap_to_180(jo_fixed deg)
Wrap deg in [-180 180].
Definition math.h:526
static __jo_force_inline float jo_vectorf_dot(const jo_vectorf *const a, const jo_vectorf *const b)
Get the dot product of 2 vectors (using floating numbers).
Definition math.h:1561
static __jo_force_inline void jo_matrix_transpose(const jo_matrix *const matrix, jo_matrix *const result)
Creates transpose matrix (using fixed numbers).
Definition math.h:1795
static __jo_force_inline void jo_fixed_div_start(const jo_fixed dividend, const jo_fixed divisor)
Start a fixed-point division in the background (see jo_fixed_div_result()).
Definition math.h:660
static __jo_force_inline jo_fixed jo_fixed_cos(const jo_fixed rad)
Fast cosinus computation using fixed number.
Definition math.h:1061
int jo_atan2_degrees(const jo_fixed y, const jo_fixed x)
ATAN2 in degree without floating point (fixed numbers).
static __jo_force_inline void jo_vectorf_muls(const jo_vectorf *const a, const float s, jo_vectorf *const result)
Multiply value to vector (using floating numbers).
Definition math.h:1510
#define JO_INT_TO_FIXED(X)
Convert int to jo_fixed.
Definition math.h:455
static __jo_force_inline jo_fixed jo_fixed_sin(const jo_fixed rad)
Fast sinus computation using fixed number.
Definition math.h:980
static __jo_force_inline void jo_vectorf_div(const jo_vectorf *const a, const jo_vectorf *const b, jo_vectorf *const result)
Divide 2 vectors (using floating numbers).
Definition math.h:1523
static __jo_force_inline jo_fixed jo_fixed_mult(const jo_fixed x, const jo_fixed y)
Multiply to fixed number.
Definition math.h:546
#define JO_FIXED_180
Fixed floating point value for 180.
Definition math.h:423
static __jo_force_inline void jo_matrixf_mul(const jo_matrixf *const a, const jo_matrixf *const b, jo_matrixf *const result)
Multiply 2 matrix (using floating numbers).
Definition math.h:1910
static __jo_force_inline float jo_vectorf_length(const jo_vectorf *const a)
Get the length of a vector (using floating numbers).
Definition math.h:1551
static __jo_force_inline int jo_int_div(const int dividend, const int divisor)
Divide 2 integers (dividend / divisor, rounded toward 0 as in C).
Definition math.h:623
static __jo_force_inline void jo_matrixf_rotation_x_rad(const float angle_in_rad, jo_matrixf *const result)
Creates rotating matrix (X axis) (using floating numbers).
Definition math.h:1729
#define JO_FIXED_180_DIV_PI
Fixed value of 180/PI.
Definition math.h:440
static __jo_force_inline void jo_matrixf_identity(jo_matrixf *const result)
Creates the identity matrix (using floating numbers).
Definition math.h:1652
static __jo_force_inline unsigned int __jo_angle_to_sin_index(const jo_angle angle)
Table index of an angle (Internal usage).
Definition math.h:917
static __jo_force_inline jo_fixed jo_vector4_fixed_dot(const jo_vector4_fixed *const a, const jo_vector4_fixed *const b)
Dot product of 2 vectors4 (using fixed numbers).
Definition math.h:1402
static __jo_force_inline jo_angle jo_fixed_rad2ANGLE(const jo_fixed rad)
Convert fixed radian to jo_angle.
Definition math.h:888
#define JO_FIXED_PI
Fixed value of PI.
Definition math.h:436
static __jo_force_inline jo_fixed jo_fixed_ceil(const jo_fixed x)
Returns the smallest (fixed) integer value greater than or equal to x.
Definition math.h:698
static __jo_force_inline jo_fixed jo_fixed_deg2rad(const jo_fixed deg)
Convert fixed degree to fixed radian.
Definition math.h:680
static __jo_force_inline void jo_vectorf_normalize(const jo_vectorf *const a, jo_vectorf *const result)
Normalize a vector (using floating numbers).
Definition math.h:1571
float jo_atan2f_rad(const float y, const float x)
Fast ATAN2 computation in radian.
static __jo_force_inline jo_fixed jo_fixed_wrap_to_pi(jo_fixed rad)
Wrap rad in [−pi pi].
Definition math.h:515
static __jo_force_inline bool jo_is_float_equals_zero(const float f)
Check if float almost equals 0.
Definition math.h:2145
#define JO_FIXED_PI_2
Fixed value of 2 PI.
Definition math.h:438
static __jo_force_inline void jo_vectorf_sub(const jo_vectorf *const a, const jo_vectorf *const b, jo_vectorf *const result)
Subtract 2 vectors (using floating numbers).
Definition math.h:1471
static __jo_force_inline jo_fixed jo_sin(const int deg)
Fast sinus computation.
Definition math.h:989
static __jo_force_inline int jo_cos_mult(const int value, const int deg)
Fast cosinus multiplication.
Definition math.h:1123
static __jo_force_inline jo_fixed jo_cos(const int deg)
Fast cosinus computation.
Definition math.h:1070
static __jo_force_inline void jo_matrixf_invert_affine(const jo_matrixf *const matrix, jo_matrixf *const result)
Inverts an affine transformation matrix (using floating numbers).
Definition math.h:2035
static __jo_force_inline void jo_matrix_rotation_x_rad(const float angle_in_rad, jo_matrix *const result)
Creates rotating matrix (X axis) (using fixed numbers).
Definition math.h:1716
static __jo_force_inline int jo_sin_mult(const int value, const int deg)
Fast sinus multiplication.
Definition math.h:1031
#define JO_FIXED_1_DIV
Fixed value of 1/65536.
Definition math.h:450
static __jo_force_inline float jo_sqrtf(float value)
Fast Square root using floating number.
Definition math.h:807
static __jo_force_inline void jo_matrix_identity(jo_matrix *const result)
Creates the identity matrix (using fixed numbers).
Definition math.h:1637
#define JO_FIXED_1
Fixed floating point value for 1.
Definition math.h:405
static __jo_force_inline float jo_tanf(const float deg)
Tangent computation.
Definition math.h:1166
static __jo_force_inline jo_fixed jo_fixed_div(const jo_fixed dividend, const jo_fixed divisor)
Divide fixed-point numbers (expresses dividend / divisor).
Definition math.h:605
#define JO_ZERO(X)
Set a variable to zero.
Definition math.h:240
#define JO_SH2_DVDNTL
Division unit: dividend register low (64 bits division, writing starts the division,...
Definition sega_saturn.h:587
#define JO_SH2_DVDNT
Division unit: dividend register (32 bits division).
Definition sega_saturn.h:583
#define JO_SH2_DVSR
Division unit: divisor register.
Definition sega_saturn.h:581
#define JO_SH2_DVDNTH
Division unit: dividend register high (64 bits division).
Definition sega_saturn.h:585
float y
Definition types.h:139
jo_fixed w
Definition types.h:172
#define __jo_force_inline
force inline attribute (and prevent Doxygen prototype parsing bug)
Definition types.h:39
short jo_angle
Angle.
Definition types.h:54
float x
Definition types.h:138
float z
Definition types.h:140
int jo_fixed
Fixed point Q16.16 number.
Definition types.h:48
jo_8_directions
8 directions definition
Definition types.h:308
@ DOWN_LEFT
Definition types.h:316
@ DOWN_RIGHT
Definition types.h:317
@ UP_RIGHT
Definition types.h:315
@ DOWN
Definition types.h:313
@ UP_LEFT
Definition types.h:314
@ UP
Definition types.h:312
@ LEFT
Definition types.h:310
@ RIGHT
Definition types.h:311
2D position
Definition types.h:58
Vector4 for 3D computation using fixed number.
Definition types.h:170
Vector for 3D computation using fixed number.
Definition types.h:155
Vector for 3D computation using floating numbers.
Definition types.h:137
4x4 MATRIX for 3D computation using fixed number
Definition types.h:191
jo_fixed table[16]
Definition types.h:193
jo_fixed m[4][4]
Definition types.h:192
4x4 MATRIX for 3D computation using floating numbers
Definition types.h:177
float table[16]
Definition types.h:179
float m[4][4]
Definition types.h:178