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