1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - FX - src
3 File: fx_asinacosidx.c
4
5 Copyright 2007-2008 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Date:: 2008-09-18#$
14 $Rev: 8573 $
15 $Author: okubata_ryoma $
16
17 *---------------------------------------------------------------------------*/
18
19 #include <nitro/fx/fx_trig.h>
20 #include <nitro/fx/fx_cp.h>
21 #include <nitro/fx/fx_const.h>
22
23 /* Size of array */
24 #define ARRAY_SIZE_90 1024
25 #define ARRAY_SIZE_180 2048
26 #define ARRAY_SIZE_270 3072
27 #define ARRAY_SIZE_360 4096
28
29 #define SINCOS_TABLE_SIZE (4096 * 2)
30
31 /*---------------------------------------------------------------------------*
32 Name: FX_AsinIdx
33
34 Description: Gets approximation of arc sine by table reference.
35
36 Arguments: x: Y/X in fx32 format
37
38 Returns: Result in u16 format (0 - 16384, 49152 - 65535).
39 *---------------------------------------------------------------------------*/
FX_AsinIdx(fx32 x)40 u16 FX_AsinIdx(fx32 x)
41 {
42 int left; /* Start key of index */
43 int right; /* End key of index */
44 int mid; /* Middle key of index */
45 fx16 value; /* Search value */
46 int tmp = 0;
47
48 SDK_MINMAX_ASSERT(x, FX32_SIN270, FX32_SIN90);
49
50 /* If x is positive, do a binary search from 0-90. */
51 if (x >= 0)
52 {
53 left = 0;
54 right = ARRAY_SIZE_90;
55 }
56 /* If x is negative, do a binary search from 270-360. */
57 else
58 {
59 left = ARRAY_SIZE_270;
60 right = ARRAY_SIZE_360;
61 }
62
63 value = (fx16)x;
64
65 /* Binary search */
66 while (left <= right)
67 {
68 mid = (left + right) / 2; /* Calc of middle key */
69 if (FX_SinCosTable_[mid * 2] == value)
70 {
71 break;
72 }
73 else if (FX_SinCosTable_[mid * 2] < value)
74 {
75 left = mid + 1; /* Adjustment of left(start) key */
76 }
77 else
78 {
79 right = mid - 1; /* Adjustment of right(end) key */
80 }
81 }
82 tmp = (mid * 2) * 65536 / SINCOS_TABLE_SIZE;
83 return (u16)tmp;
84 }
85
86 /*---------------------------------------------------------------------------*
87 Name: FX_AcosIdx
88
89 Description: Gets approximation of arc cosine by table reference.
90
91 Arguments: x: Y/X in fx32 format
92
93 Returns: Result in u16 format (0 - 32768).
94 *---------------------------------------------------------------------------*/
FX_AcosIdx(fx32 x)95 u16 FX_AcosIdx(fx32 x)
96 {
97 int left;
98 int right;
99 int mid;
100 fx16 value;
101 int tmp = 0;
102
103 SDK_MINMAX_ASSERT(x, FX32_COS180, FX32_COS0);
104
105 /* If x is positive, do a binary search from 0-90. */
106 if (x >= 0)
107 {
108 left = 0;
109 right = ARRAY_SIZE_90;
110 }
111 /* If x is negative, do a binary search from 90-180. */
112 else
113 {
114 left = ARRAY_SIZE_90;
115 right = ARRAY_SIZE_180;
116 }
117
118 value = (fx16)x;
119
120 /* Binary search */
121 while (left <= right)
122 {
123 mid = (left + right) / 2;
124 if (FX_SinCosTable_[mid * 2 + 1] == value)
125 {
126 break;
127 }
128 else if (FX_SinCosTable_[mid * 2 + 1] < value)
129 {
130 right = mid - 1;
131 }
132 else
133 {
134 left = mid + 1;
135 }
136 }
137 tmp = (mid * 2 + 1) * 65536 / SINCOS_TABLE_SIZE;
138 return (u16)tmp;
139 }
140