workaround a problem with the harmattan gcc
[drnoksnes] / dsp1emu.c
1 //Copyright (C) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com )
2 //
3 //This program is free software; you can redistribute it and/or
4 //modify it under the terms of the GNU General Public License
5 //as published by the Free Software Foundation; either
6 //version 2 of the License, or (at your option) any later
7 //version.
8 //
9 //This program is distributed in the hope that it will be useful,
10 //but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //GNU General Public License for more details.
13 //
14 //You should have received a copy of the GNU General Public License
15 //along with this program; if not, write to the Free Software
16 //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 //#define __ZSNES__
19
20 #if (defined __ZSNES__ && __LINUX__)
21 #include "../gblhdr.h"
22 #else
23
24 #include <stdio.h>
25 #include <stdarg.h>
26 #include <math.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #endif
30 //#define DebugDSP1
31
32 // uncomment some lines to test
33 //#define printinfo
34 //#define debug06
35
36 #define __OPT__
37 #define __OPT06__
38
39 #ifdef DebugDSP1
40
41 FILE * LogFile = NULL;
42
43 void Log_Message (char *Message, ...)
44 {
45         char Msg[400];
46         va_list ap;
47
48    va_start(ap,Message);
49    vsprintf(Msg,Message,ap );
50    va_end(ap);
51         
52    strcat(Msg,"\r\n\0");
53    fwrite(Msg,strlen(Msg),1,LogFile);
54    fflush (LogFile);
55 }
56
57 void Start_Log (void)
58 {
59         char LogFileName[255];
60 //  [4/15/2001] char *p;
61
62    strcpy(LogFileName,"dsp1emu.log\0");
63         
64    LogFile = fopen(LogFileName,"wb");
65 }
66
67 void Stop_Log (void)
68 {
69    if (LogFile)
70    {
71       fclose(LogFile);
72       LogFile = NULL;
73         }
74 }
75
76 #endif
77
78 const unsigned short DSP1ROM[1024] = {
79         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
80         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
81         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
82         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
83         0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 
84         0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 
85         0x4000, 0x7fff, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 
86         0x0100, 0x0080, 0x0040, 0x0020, 0x0001, 0x0008, 0x0004, 0x0002, 
87         0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
88         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
89         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
90         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
91         0x0000, 0x0000, 0x8000, 0xffe5, 0x0100, 0x7fff, 0x7f02, 0x7e08, 
92         0x7d12, 0x7c1f, 0x7b30, 0x7a45, 0x795d, 0x7878, 0x7797, 0x76ba, 
93         0x75df, 0x7507, 0x7433, 0x7361, 0x7293, 0x71c7, 0x70fe, 0x7038, 
94         0x6f75, 0x6eb4, 0x6df6, 0x6d3a, 0x6c81, 0x6bca, 0x6b16, 0x6a64, 
95         0x69b4, 0x6907, 0x685b, 0x67b2, 0x670b, 0x6666, 0x65c4, 0x6523, 
96         0x6484, 0x63e7, 0x634c, 0x62b3, 0x621c, 0x6186, 0x60f2, 0x6060, 
97         0x5fd0, 0x5f41, 0x5eb5, 0x5e29, 0x5d9f, 0x5d17, 0x5c91, 0x5c0c, 
98         0x5b88, 0x5b06, 0x5a85, 0x5a06, 0x5988, 0x590b, 0x5890, 0x5816, 
99         0x579d, 0x5726, 0x56b0, 0x563b, 0x55c8, 0x5555, 0x54e4, 0x5474, 
100         0x5405, 0x5398, 0x532b, 0x52bf, 0x5255, 0x51ec, 0x5183, 0x511c, 
101         0x50b6, 0x5050, 0x4fec, 0x4f89, 0x4f26, 0x4ec5, 0x4e64, 0x4e05, 
102         0x4da6, 0x4d48, 0x4cec, 0x4c90, 0x4c34, 0x4bda, 0x4b81, 0x4b28, 
103         0x4ad0, 0x4a79, 0x4a23, 0x49cd, 0x4979, 0x4925, 0x48d1, 0x487f, 
104         0x482d, 0x47dc, 0x478c, 0x473c, 0x46ed, 0x469f, 0x4651, 0x4604, 
105         0x45b8, 0x456c, 0x4521, 0x44d7, 0x448d, 0x4444, 0x43fc, 0x43b4, 
106         0x436d, 0x4326, 0x42e0, 0x429a, 0x4255, 0x4211, 0x41cd, 0x4189, 
107         0x4146, 0x4104, 0x40c2, 0x4081, 0x4040, 0x3fff, 0x41f7, 0x43e1, 
108         0x45bd, 0x478d, 0x4951, 0x4b0b, 0x4cbb, 0x4e61, 0x4fff, 0x5194, 
109         0x5322, 0x54a9, 0x5628, 0x57a2, 0x5914, 0x5a81, 0x5be9, 0x5d4a, 
110         0x5ea7, 0x5fff, 0x6152, 0x62a0, 0x63ea, 0x6530, 0x6672, 0x67b0, 
111         0x68ea, 0x6a20, 0x6b53, 0x6c83, 0x6daf, 0x6ed9, 0x6fff, 0x7122, 
112         0x7242, 0x735f, 0x747a, 0x7592, 0x76a7, 0x77ba, 0x78cb, 0x79d9, 
113         0x7ae5, 0x7bee, 0x7cf5, 0x7dfa, 0x7efe, 0x7fff, 0x0000, 0x0324, 
114         0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, 0x18f8, 0x1c0b, 
115         0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, 0x30fb, 0x33de, 
116         0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, 0x471c, 0x49b4, 
117         0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, 0x5a82, 0x5cb4, 
118         0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, 0x6a6d, 0x6c24, 
119         0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504, 0x7641, 0x776c, 
120         0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, 0x7d8a, 0x7e1d, 
121         0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6, 0x7fff, 0x7ff6, 
122         0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3, 
123         0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504, 
124         0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6, 
125         0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842, 
126         0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a, 
127         0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11, 
128         0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2, 
129         0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x7fff, 0x7ff6, 
130         0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3, 
131         0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504, 
132         0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6, 
133         0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842, 
134         0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a, 
135         0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11, 
136         0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2, 
137         0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x0000, 0xfcdc, 
138         0xf9b9, 0xf696, 0xf375, 0xf055, 0xed38, 0xea1e, 0xe708, 0xe3f5, 
139         0xe0e7, 0xdddd, 0xdad8, 0xd7da, 0xd4e1, 0xd1ef, 0xcf05, 0xcc22, 
140         0xc946, 0xc674, 0xc3aa, 0xc0e9, 0xbe32, 0xbb86, 0xb8e4, 0xb64c, 
141         0xb3c1, 0xb141, 0xaecd, 0xac65, 0xaa0b, 0xa7be, 0xa57e, 0xa34c, 
142         0xa129, 0x9f14, 0x9d0e, 0x9b18, 0x9931, 0x975a, 0x9593, 0x93dc, 
143         0x9236, 0x90a1, 0x8f1e, 0x8dab, 0x8c4b, 0x8afc, 0x89bf, 0x8894, 
144         0x877c, 0x8676, 0x8583, 0x84a3, 0x83d7, 0x831d, 0x8276, 0x81e3, 
145         0x8163, 0x80f7, 0x809e, 0x8059, 0x8028, 0x800a, 0x6488, 0x0080, 
146         0x03ff, 0x0116, 0x0002, 0x0080, 0x4000, 0x3fd7, 0x3faf, 0x3f86, 
147         0x3f5d, 0x3f34, 0x3f0c, 0x3ee3, 0x3eba, 0x3e91, 0x3e68, 0x3e40, 
148         0x3e17, 0x3dee, 0x3dc5, 0x3d9c, 0x3d74, 0x3d4b, 0x3d22, 0x3cf9, 
149         0x3cd0, 0x3ca7, 0x3c7f, 0x3c56, 0x3c2d, 0x3c04, 0x3bdb, 0x3bb2, 
150         0x3b89, 0x3b60, 0x3b37, 0x3b0e, 0x3ae5, 0x3abc, 0x3a93, 0x3a69, 
151         0x3a40, 0x3a17, 0x39ee, 0x39c5, 0x399c, 0x3972, 0x3949, 0x3920, 
152         0x38f6, 0x38cd, 0x38a4, 0x387a, 0x3851, 0x3827, 0x37fe, 0x37d4, 
153         0x37aa, 0x3781, 0x3757, 0x372d, 0x3704, 0x36da, 0x36b0, 0x3686, 
154         0x365c, 0x3632, 0x3609, 0x35df, 0x35b4, 0x358a, 0x3560, 0x3536, 
155         0x350c, 0x34e1, 0x34b7, 0x348d, 0x3462, 0x3438, 0x340d, 0x33e3, 
156         0x33b8, 0x338d, 0x3363, 0x3338, 0x330d, 0x32e2, 0x32b7, 0x328c, 
157         0x3261, 0x3236, 0x320b, 0x31df, 0x31b4, 0x3188, 0x315d, 0x3131, 
158         0x3106, 0x30da, 0x30ae, 0x3083, 0x3057, 0x302b, 0x2fff, 0x2fd2, 
159         0x2fa6, 0x2f7a, 0x2f4d, 0x2f21, 0x2ef4, 0x2ec8, 0x2e9b, 0x2e6e, 
160         0x2e41, 0x2e14, 0x2de7, 0x2dba, 0x2d8d, 0x2d60, 0x2d32, 0x2d05, 
161         0x2cd7, 0x2ca9, 0x2c7b, 0x2c4d, 0x2c1f, 0x2bf1, 0x2bc3, 0x2b94, 
162         0x2b66, 0x2b37, 0x2b09, 0x2ada, 0x2aab, 0x2a7c, 0x2a4c, 0x2a1d, 
163         0x29ed, 0x29be, 0x298e, 0x295e, 0x292e, 0x28fe, 0x28ce, 0x289d, 
164         0x286d, 0x283c, 0x280b, 0x27da, 0x27a9, 0x2777, 0x2746, 0x2714, 
165         0x26e2, 0x26b0, 0x267e, 0x264c, 0x2619, 0x25e7, 0x25b4, 0x2581, 
166         0x254d, 0x251a, 0x24e6, 0x24b2, 0x247e, 0x244a, 0x2415, 0x23e1, 
167         0x23ac, 0x2376, 0x2341, 0x230b, 0x22d6, 0x229f, 0x2269, 0x2232, 
168         0x21fc, 0x21c4, 0x218d, 0x2155, 0x211d, 0x20e5, 0x20ad, 0x2074, 
169         0x203b, 0x2001, 0x1fc7, 0x1f8d, 0x1f53, 0x1f18, 0x1edd, 0x1ea1, 
170         0x1e66, 0x1e29, 0x1ded, 0x1db0, 0x1d72, 0x1d35, 0x1cf6, 0x1cb8, 
171         0x1c79, 0x1c39, 0x1bf9, 0x1bb8, 0x1b77, 0x1b36, 0x1af4, 0x1ab1, 
172         0x1a6e, 0x1a2a, 0x19e6, 0x19a1, 0x195c, 0x1915, 0x18ce, 0x1887, 
173         0x183f, 0x17f5, 0x17ac, 0x1761, 0x1715, 0x16c9, 0x167c, 0x162e, 
174         0x15df, 0x158e, 0x153d, 0x14eb, 0x1497, 0x1442, 0x13ec, 0x1395, 
175         0x133c, 0x12e2, 0x1286, 0x1228, 0x11c9, 0x1167, 0x1104, 0x109e, 
176         0x1036, 0x0fcc, 0x0f5f, 0x0eef, 0x0e7b, 0x0e04, 0x0d89, 0x0d0a, 
177         0x0c86, 0x0bfd, 0x0b6d, 0x0ad6, 0x0a36, 0x098d, 0x08d7, 0x0811, 
178         0x0736, 0x063e, 0x0519, 0x039a, 0x0000, 0x7fff, 0x0100, 0x0080, 
179         0x021d, 0x00c8, 0x00ce, 0x0048, 0x0a26, 0x277a, 0x00ce, 0x6488, 
180         0x14ac, 0x0001, 0x00f9, 0x00fc, 0x00ff, 0x00fc, 0x00f9, 0xffff, 
181         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
182         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
183         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
184         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
185         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
186         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
187         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
188         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
189         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
190         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
191         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
192         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
193         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
194         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
195         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
196         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
197         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
198         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
199         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
200         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
201         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
202         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
203         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
204         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
205         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
206         0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
207
208 /***************************************************************************\
209 *  Math tables                                                              *
210 \***************************************************************************/
211
212 #define INCR 2048
213 #define Angle(x) (((x)/(65536/INCR)) & (INCR-1))
214 #define Cos(x) ((double) CosTable2[x])
215 #define Sin(x) ((double) SinTable2[x])
216 #ifdef PI
217 #undef PI
218 #endif
219 #define PI 3.1415926535897932384626433832795
220 double CosTable2[INCR];
221 double SinTable2[INCR];
222
223
224 double Atan(double x)
225 {
226         if ((x>=1) || (x<=1)) 
227                 return (x/(1+0.28*x*x));
228         else
229                 return (PI/2 - Atan(1/x));
230 }
231
232 #ifdef __ZSNES__
233 /***************************************************************************\
234 *  C4 C code                                                                *
235 \***************************************************************************/
236
237 short C4WFXVal;
238 short C4WFYVal;
239 short C4WFZVal;
240 short C4WFX2Val;
241 short C4WFY2Val;
242 short C4WFDist;
243 short C4WFScale;
244 double tanval;
245 double c4x,c4y,c4z;
246 double c4x2,c4y2,c4z2;
247
248 void C4TransfWireFrame()
249 {
250   c4x=(double)C4WFXVal;
251   c4y=(double)C4WFYVal;
252   c4z=(double)C4WFZVal-0x95;
253
254   // Rotate X
255   tanval=-(double)C4WFX2Val*PI*2/128;
256   c4y2=c4y*cos(tanval)-c4z*sin(tanval);
257   c4z2=c4y*sin(tanval)+c4z*cos(tanval);
258
259   // Rotate Y
260   tanval=-(double)C4WFY2Val*PI*2/128;
261   c4x2=c4x*cos(tanval)+c4z2*sin(tanval);
262   c4z=c4x*-sin(tanval)+c4z2*cos(tanval);
263
264   // Rotate Z
265   tanval=-(double)C4WFDist*PI*2/128;
266   c4x=c4x2*cos(tanval)-c4y2*sin(tanval);
267   c4y=c4x2*sin(tanval)+c4y2*cos(tanval);
268
269   // Scale
270   C4WFXVal=(short)(c4x*C4WFScale/(0x90*(c4z+0x95))*0x95);
271   C4WFYVal=(short)(c4y*C4WFScale/(0x90*(c4z+0x95))*0x95);
272 }
273
274 void C4TransfWireFrame2()
275 {
276   c4x=(double)C4WFXVal;
277   c4y=(double)C4WFYVal;
278   c4z=(double)C4WFZVal;
279
280   // Rotate X
281   tanval=-(double)C4WFX2Val*PI*2/128;
282   c4y2=c4y*cos(tanval)-c4z*sin(tanval);
283   c4z2=c4y*sin(tanval)+c4z*cos(tanval);
284
285   // Rotate Y
286   tanval=-(double)C4WFY2Val*PI*2/128;
287   c4x2=c4x*cos(tanval)+c4z2*sin(tanval);
288   c4z=c4x*-sin(tanval)+c4z2*cos(tanval);
289
290   // Rotate Z
291   tanval=-(double)C4WFDist*PI*2/128;
292   c4x=c4x2*cos(tanval)-c4y2*sin(tanval);
293   c4y=c4x2*sin(tanval)+c4y2*cos(tanval);
294
295   // Scale
296   C4WFXVal=(short)(c4x*C4WFScale/0x100);
297   C4WFYVal=(short)(c4y*C4WFScale/0x100);
298 }
299
300 void C4CalcWireFrame()
301 {
302   C4WFXVal=C4WFX2Val-C4WFXVal;
303   C4WFYVal=C4WFY2Val-C4WFYVal;
304   if (abs(C4WFXVal)>abs(C4WFYVal)){
305     C4WFDist=abs(C4WFXVal)+1;
306     C4WFYVal=(256*(long)C4WFYVal)/abs(C4WFXVal);
307     if (C4WFXVal<0) C4WFXVal=-256;
308     else C4WFXVal=256;
309   }
310   else
311   if (C4WFYVal!=0) {
312     C4WFDist=abs(C4WFYVal)+1;
313     C4WFXVal=(256*(long)C4WFXVal)/abs(C4WFYVal);
314     if (C4WFYVal<0) C4WFYVal=-256;
315     else C4WFYVal=256;
316   }
317   else C4WFDist=0;
318 }
319
320 short C41FXVal;
321 short C41FYVal;
322 short C41FAngleRes;
323 short C41FDist;
324 short C41FDistVal;
325
326 void C4Op1F()
327 {
328   if (C41FXVal == 0) {
329     if (C41FYVal>0) C41FAngleRes=0x80;
330       else C41FAngleRes=0x180;
331   }
332   else {
333     tanval = ((double)C41FYVal)/((double)C41FXVal);
334     C41FAngleRes=(short)(atan(tanval)/(PI*2)*512);
335     C41FAngleRes=C41FAngleRes;
336     if (C41FXVal<0) C41FAngleRes+=0x100;
337     C41FAngleRes&=0x1FF;
338   }
339 }
340
341 void C4Op15()
342 {
343   tanval=sqrt(((double)C41FYVal)*((double)C41FYVal)+((double)C41FXVal)*
344     ((double)C41FXVal));
345   C41FDist=(short)tanval;
346 }
347
348 void C4Op0D()
349 {
350   tanval=sqrt(((double)C41FYVal)*((double)C41FYVal)+((double)C41FXVal)*
351     ((double)C41FXVal));
352   tanval=(double)C41FDistVal/tanval;
353   C41FYVal=(short)(((double)C41FYVal*tanval)*0.99);
354   C41FXVal=(short)(((double)C41FXVal*tanval)*0.98);
355 }
356 #endif
357
358 /***************************************************************************\
359 *  DSP1 code                                                                *
360 \***************************************************************************/
361
362 void InitDSP(void)
363 {
364 #ifdef __OPT__
365         unsigned int i;
366         for (i=0; i<INCR; i++){
367                 CosTable2[i] = (cos((double)(2*PI*i/INCR)));
368                 SinTable2[i] = (sin((double)(2*PI*i/INCR)));
369         }
370 #endif
371 #ifdef DebugDSP1
372         Start_Log();
373 #endif
374 }
375
376
377 short Op00Multiplicand;
378 short Op00Multiplier;
379 short Op00Result;
380
381 void DSPOp00()
382 {
383    Op00Result= Op00Multiplicand * Op00Multiplier >> 15;
384
385    #ifdef DebugDSP1
386       Log_Message("OP00 MULT %d*%d/32768=%d",Op00Multiplicand,Op00Multiplier,Op00Result);
387    #endif
388 }
389
390 short Op20Multiplicand;
391 short Op20Multiplier;
392 short Op20Result;
393
394 void DSPOp20()
395 {
396    Op20Result= Op20Multiplicand * Op20Multiplier >> 15;
397    Op20Result++;
398
399    #ifdef DebugDSP1
400       Log_Message("OP20 MULT %d*%d/32768=%d",Op20Multiplicand,Op20Multiplier,Op20Result);
401    #endif
402 }
403
404 signed short Op10Coefficient;
405 signed short Op10Exponent;
406 signed short Op10CoefficientR;
407 signed short Op10ExponentR;
408
409 void DSP1_Inverse(short Coefficient, short Exponent, short *iCoefficient, short *iExponent)
410 {
411         // Step One: Division by Zero
412         if (Coefficient == 0x0000)
413         {
414                 *iCoefficient = 0x7fff;
415                 *iExponent = 0x002f;
416         }
417         else
418         {
419                 short Sign = 1;
420
421                 // Step Two: Remove Sign
422                 if (Coefficient < 0)
423                 {               
424                         if (Coefficient < -32767) Coefficient = -32767;
425                         Coefficient = -Coefficient;
426                         Sign = -1;
427                 }
428                 
429                 // Step Three: Normalize
430                 while (Coefficient < 0x4000)
431                 {
432                         Coefficient <<= 1;
433                         Exponent--;
434                 }
435
436                 // Step Four: Special Case
437                 if (Coefficient == 0x4000)
438                         if (Sign == 1) *iCoefficient = 0x7fff;
439                         else  {
440                                 *iCoefficient = -0x4000;
441                                 Exponent--;
442                         }
443                 else {
444                         // Step Five: Initial Guess
445                         short i = DSP1ROM[((Coefficient - 0x4000) >> 7) + 0x0065];
446
447                         // Step Six: Iterate "estimated" Newton's Method
448                         i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1;
449                         i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1;
450
451                         *iCoefficient = i * Sign;
452                 }
453
454                 *iExponent = 1 - Exponent;
455         }
456 }
457
458 void DSPOp10()
459 {
460         DSP1_Inverse(Op10Coefficient, Op10Exponent, &Op10CoefficientR, &Op10ExponentR);
461         #ifdef DebugDSP1
462         Log_Message("OP10 INV %d*2^%d = %d*2^%d", Op10Coefficient, Op10Exponent, Op10CoefficientR, Op10ExponentR);
463         #endif
464 }
465
466 short Op04Angle;
467 short Op04Radius;
468 short Op04Sin;
469 short Op04Cos;
470
471 const short DSP1_MulTable[256] = {
472           0x0000,  0x0003,  0x0006,  0x0009,  0x000c,  0x000f,  0x0012,  0x0015,
473           0x0019,  0x001c,  0x001f,  0x0022,  0x0025,  0x0028,  0x002b,  0x002f,
474           0x0032,  0x0035,  0x0038,  0x003b,  0x003e,  0x0041,  0x0045,  0x0048,
475           0x004b,  0x004e,  0x0051,  0x0054,  0x0057,  0x005b,  0x005e,  0x0061,
476           0x0064,  0x0067,  0x006a,  0x006d,  0x0071,  0x0074,  0x0077,  0x007a,
477           0x007d,  0x0080,  0x0083,  0x0087,  0x008a,  0x008d,  0x0090,  0x0093,
478           0x0096,  0x0099,  0x009d,  0x00a0,  0x00a3,  0x00a6,  0x00a9,  0x00ac,
479           0x00af,  0x00b3,  0x00b6,  0x00b9,  0x00bc,  0x00bf,  0x00c2,  0x00c5,
480           0x00c9,  0x00cc,  0x00cf,  0x00d2,  0x00d5,  0x00d8,  0x00db,  0x00df,
481           0x00e2,  0x00e5,  0x00e8,  0x00eb,  0x00ee,  0x00f1,  0x00f5,  0x00f8,
482           0x00fb,  0x00fe,  0x0101,  0x0104,  0x0107,  0x010b,  0x010e,  0x0111,
483           0x0114,  0x0117,  0x011a,  0x011d,  0x0121,  0x0124,  0x0127,  0x012a,
484           0x012d,  0x0130,  0x0133,  0x0137,  0x013a,  0x013d,  0x0140,  0x0143,
485           0x0146,  0x0149,  0x014d,  0x0150,  0x0153,  0x0156,  0x0159,  0x015c,
486           0x015f,  0x0163,  0x0166,  0x0169,  0x016c,  0x016f,  0x0172,  0x0175,
487           0x0178,  0x017c,  0x017f,  0x0182,  0x0185,  0x0188,  0x018b,  0x018e,
488           0x0192,  0x0195,  0x0198,  0x019b,  0x019e,  0x01a1,  0x01a4,  0x01a8,
489           0x01ab,  0x01ae,  0x01b1,  0x01b4,  0x01b7,  0x01ba,  0x01be,  0x01c1,
490           0x01c4,  0x01c7,  0x01ca,  0x01cd,  0x01d0,  0x01d4,  0x01d7,  0x01da,
491           0x01dd,  0x01e0,  0x01e3,  0x01e6,  0x01ea,  0x01ed,  0x01f0,  0x01f3,
492           0x01f6,  0x01f9,  0x01fc,  0x0200,  0x0203,  0x0206,  0x0209,  0x020c,
493           0x020f,  0x0212,  0x0216,  0x0219,  0x021c,  0x021f,  0x0222,  0x0225,
494           0x0228,  0x022c,  0x022f,  0x0232,  0x0235,  0x0238,  0x023b,  0x023e,
495           0x0242,  0x0245,  0x0248,  0x024b,  0x024e,  0x0251,  0x0254,  0x0258,
496           0x025b,  0x025e,  0x0261,  0x0264,  0x0267,  0x026a,  0x026e,  0x0271,
497           0x0274,  0x0277,  0x027a,  0x027d,  0x0280,  0x0284,  0x0287,  0x028a,
498           0x028d,  0x0290,  0x0293,  0x0296,  0x029a,  0x029d,  0x02a0,  0x02a3,
499           0x02a6,  0x02a9,  0x02ac,  0x02b0,  0x02b3,  0x02b6,  0x02b9,  0x02bc,
500           0x02bf,  0x02c2,  0x02c6,  0x02c9,  0x02cc,  0x02cf,  0x02d2,  0x02d5,
501           0x02d8,  0x02db,  0x02df,  0x02e2,  0x02e5,  0x02e8,  0x02eb,  0x02ee,
502           0x02f1,  0x02f5,  0x02f8,  0x02fb,  0x02fe,  0x0301,  0x0304,  0x0307,
503           0x030b,  0x030e,  0x0311,  0x0314,  0x0317,  0x031a,  0x031d,  0x0321};
504
505 const short DSP1_SinTable[256] = {
506           0x0000,  0x0324,  0x0647,  0x096a,  0x0c8b,  0x0fab,  0x12c8,  0x15e2,
507           0x18f8,  0x1c0b,  0x1f19,  0x2223,  0x2528,  0x2826,  0x2b1f,  0x2e11,
508           0x30fb,  0x33de,  0x36ba,  0x398c,  0x3c56,  0x3f17,  0x41ce,  0x447a,
509           0x471c,  0x49b4,  0x4c3f,  0x4ebf,  0x5133,  0x539b,  0x55f5,  0x5842,
510           0x5a82,  0x5cb4,  0x5ed7,  0x60ec,  0x62f2,  0x64e8,  0x66cf,  0x68a6,
511           0x6a6d,  0x6c24,  0x6dca,  0x6f5f,  0x70e2,  0x7255,  0x73b5,  0x7504,
512           0x7641,  0x776c,  0x7884,  0x798a,  0x7a7d,  0x7b5d,  0x7c29,  0x7ce3,
513           0x7d8a,  0x7e1d,  0x7e9d,  0x7f09,  0x7f62,  0x7fa7,  0x7fd8,  0x7ff6,
514           0x7fff,  0x7ff6,  0x7fd8,  0x7fa7,  0x7f62,  0x7f09,  0x7e9d,  0x7e1d,
515           0x7d8a,  0x7ce3,  0x7c29,  0x7b5d,  0x7a7d,  0x798a,  0x7884,  0x776c,
516           0x7641,  0x7504,  0x73b5,  0x7255,  0x70e2,  0x6f5f,  0x6dca,  0x6c24,
517           0x6a6d,  0x68a6,  0x66cf,  0x64e8,  0x62f2,  0x60ec,  0x5ed7,  0x5cb4,
518           0x5a82,  0x5842,  0x55f5,  0x539b,  0x5133,  0x4ebf,  0x4c3f,  0x49b4,
519           0x471c,  0x447a,  0x41ce,  0x3f17,  0x3c56,  0x398c,  0x36ba,  0x33de,
520           0x30fb,  0x2e11,  0x2b1f,  0x2826,  0x2528,  0x2223,  0x1f19,  0x1c0b,
521           0x18f8,  0x15e2,  0x12c8,  0x0fab,  0x0c8b,  0x096a,  0x0647,  0x0324,
522          -0x0000, -0x0324, -0x0647, -0x096a, -0x0c8b, -0x0fab, -0x12c8, -0x15e2,
523          -0x18f8, -0x1c0b, -0x1f19, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11,
524          -0x30fb, -0x33de, -0x36ba, -0x398c, -0x3c56, -0x3f17, -0x41ce, -0x447a,
525          -0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842,
526          -0x5a82, -0x5cb4, -0x5ed7, -0x60ec, -0x62f2, -0x64e8, -0x66cf, -0x68a6,
527          -0x6a6d, -0x6c24, -0x6dca, -0x6f5f, -0x70e2, -0x7255, -0x73b5, -0x7504,
528          -0x7641, -0x776c, -0x7884, -0x798a, -0x7a7d, -0x7b5d, -0x7c29, -0x7ce3,
529          -0x7d8a, -0x7e1d, -0x7e9d, -0x7f09, -0x7f62, -0x7fa7, -0x7fd8, -0x7ff6,
530          -0x7fff, -0x7ff6, -0x7fd8, -0x7fa7, -0x7f62, -0x7f09, -0x7e9d, -0x7e1d,
531          -0x7d8a, -0x7ce3, -0x7c29, -0x7b5d, -0x7a7d, -0x798a, -0x7884, -0x776c,
532          -0x7641, -0x7504, -0x73b5, -0x7255, -0x70e2, -0x6f5f, -0x6dca, -0x6c24,
533          -0x6a6d, -0x68a6, -0x66cf, -0x64e8, -0x62f2, -0x60ec, -0x5ed7, -0x5cb4,
534          -0x5a82, -0x5842, -0x55f5, -0x539b, -0x5133, -0x4ebf, -0x4c3f, -0x49b4,
535          -0x471c, -0x447a, -0x41ce, -0x3f17, -0x3c56, -0x398c, -0x36ba, -0x33de,
536          -0x30fb, -0x2e11, -0x2b1f, -0x2826, -0x2528, -0x2223, -0x1f19, -0x1c0b,
537          -0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324};
538
539 // Here be dragons if you touch any of the following functions; they tend
540 // to break cs2005q3 gcc in random ways.
541
542 short DSP1_Sin(short Angle)
543 {
544         if (Angle == -32768) return 0;
545         if (Angle < 0) return -DSP1_Sin(-Angle);
546         
547         int S = DSP1_SinTable[Angle >> 8] + (DSP1_MulTable[Angle & 0xff] * DSP1_SinTable[0x40 + (Angle >> 8)] >> 15);
548         if (S > 32767) S = 32767;
549         return (short) S;
550 }
551
552 short DSP1_Cos(short Angle)
553 {
554         if (Angle == -32768) return -32768;
555         if (Angle < 0) Angle = -Angle;
556         
557         int S = DSP1_SinTable[0x40 + (Angle >> 8)] - (DSP1_MulTable[Angle & 0xff] * DSP1_SinTable[Angle >> 8] >> 15);
558         if (S < -32768) S = -32767;
559         return (short) S;
560 }
561
562 void DSP1_Normalize(short m, short *Coefficient, short *Exponent)
563 {
564         short i = 0x4000;
565         short e = 0;
566
567         if (m < 0)
568                 while ((m & i) && i) {
569                         i >>= 1;
570                         e++;
571                 }
572         else
573                 while (!(m & i) && i) {
574                         i >>= 1;
575                         e++;
576                 }
577
578         if (e > 0)
579                 *Coefficient = m * DSP1ROM[0x21 + e] << 1;
580         else
581                 *Coefficient = m;
582
583         *Exponent -= e;
584 }
585
586 void DSP1_NormalizeDouble(int Product, short *Coefficient, short *Exponent)
587 {
588         short n = Product & 0x7fff;
589         short m = Product >> 15;
590         short i = 0x4000;
591         short e = 0;
592
593         if (m < 0)
594                 while ((m & i) && i) {
595                         i >>= 1;
596                         e++;
597                 }
598         else
599                 while (!(m & i) && i) {
600                         i >>= 1;
601                         e++;
602                 }
603
604         if (e > 0)
605         {
606                 *Coefficient = m * DSP1ROM[0x0021 + e] << 1;
607
608                 if (e < 15)
609                         *Coefficient += n * DSP1ROM[0x0040 - e] >> 15;
610                 else
611                 {
612                         i = 0x4000;
613
614                         if (m < 0)
615                                 while ((n & i) && i) {
616                                         i >>= 1;
617                                         e++;
618                                 }
619                         else
620                                 while (!(n & i) && i) {
621                                         i >>= 1;
622                                         e++;
623                                 }
624
625                         if (e > 15)
626                                 *Coefficient = n * DSP1ROM[0x0012 + e] << 1;
627                         else
628                                 *Coefficient += n;
629                 }
630         }
631         else
632                 *Coefficient = m;
633
634         *Exponent = e;
635 }
636
637 short DSP1_Truncate(short C, short E)
638 {
639         if (E > 0) {
640                 if (C > 0) return 32767; else if (C < 0) return -32767;
641         } else {
642                 if (E < 0) return C * DSP1ROM[0x0031 + E] >> 15;
643         }
644         return C;
645 }
646
647 void DSPOp04()
648 {
649         Op04Sin = DSP1_Sin(Op04Angle) * Op04Radius >> 15;
650         Op04Cos = DSP1_Cos(Op04Angle) * Op04Radius >> 15;
651 }
652
653 short Op0CA;
654 short Op0CX1;
655 short Op0CY1;
656 short Op0CX2;
657 short Op0CY2;
658
659 void DSPOp0C()
660 {
661         Op0CX2 = (Op0CY1 * DSP1_Sin(Op0CA) >> 15) + (Op0CX1 * DSP1_Cos(Op0CA) >> 15);
662         Op0CY2 = (Op0CY1 * DSP1_Cos(Op0CA) >> 15) - (Op0CX1 * DSP1_Sin(Op0CA) >> 15);
663 }
664
665 short CentreX;
666 short CentreY;
667 short VOffset;
668
669 short VPlane_C;
670 short VPlane_E;
671
672 // Azimuth and Zenith angles
673 short SinAas;
674 short CosAas;
675 short SinAzs;
676 short CosAzs;
677
678 // Clipped Zenith angle
679 short SinAZS; 
680 short CosAZS;
681 short SecAZS_C1;
682 short SecAZS_E1;
683 short SecAZS_C2;
684 short SecAZS_E2;
685
686 const short MaxAZS_Exp[16] = {
687         0x38b4, 0x38b7, 0x38ba, 0x38be, 0x38c0, 0x38c4, 0x38c7, 0x38ca, 
688         0x38ce, 0x38d0, 0x38d4, 0x38d7, 0x38da, 0x38dd, 0x38e0, 0x38e4
689 };
690
691 void DSP1_Parameter(short Fx, short Fy, short Fz, short Lfe, short Les, short Aas, short Azs, short *Vof, short *Vva, short *Cx, short *Cy)
692 {
693         short CSec, C, E;
694
695         // Copy Zenith angle for clipping
696         short AZS = Azs;
697
698         // Store Sin and Cos of Azimuth and Zenith angles
699         SinAas = DSP1_Sin(Aas);
700         CosAas = DSP1_Cos(Aas);
701         SinAzs = DSP1_Sin(Azs);
702         CosAzs = DSP1_Cos(Azs);
703
704         // Center of Projection
705         CentreX = Fx + (Lfe * (SinAzs * -SinAas >> 15) >> 15);
706         CentreY = Fy + (Lfe * (SinAzs * CosAas >> 15) >> 15);
707
708         E = 0;
709         DSP1_Normalize(Fz + (Lfe * (CosAzs * 0x7fff >> 15) >> 15), &C, &E);
710
711         VPlane_C = C;
712         VPlane_E = E;
713
714         // Determine clip boundary and clip Zenith angle if necessary
715         short MaxAZS = MaxAZS_Exp[-E];
716
717         if (AZS < 0) {
718                 MaxAZS = -MaxAZS;
719                 if (AZS < MaxAZS + 1) AZS = MaxAZS + 1;
720         } else {
721                 if (AZS > MaxAZS) AZS = MaxAZS;
722         }
723
724         // Store Sin and Cos of clipped Zenith angle
725         SinAZS = DSP1_Sin(AZS);
726         CosAZS = DSP1_Cos(AZS);
727
728         DSP1_Inverse(CosAZS, 0, &SecAZS_C1, &SecAZS_E1);
729         DSP1_Normalize(C * SecAZS_C1 >> 15, &C, &E);
730         E += SecAZS_E1;
731
732         C = DSP1_Truncate(C, E) * SinAZS >> 15;
733
734         CentreX += C * SinAas >> 15;
735         CentreY -= C * CosAas >> 15;
736
737         *Cx = CentreX;
738         *Cy = CentreY;
739
740         // Raster number of imaginary center and horizontal line
741         *Vof = 0;
742
743         if ((Azs != AZS) || (Azs == MaxAZS)) 
744         {
745                 if (Azs == -32768) Azs = -32767;
746
747                 C = Azs - MaxAZS;
748                 if (C >= 0) C--;
749                 short Aux = ~(C << 2);
750
751                 C = Aux * DSP1ROM[0x0328] >> 15;
752                 C = (C * Aux >> 15) + DSP1ROM[0x0327];
753                 *Vof -= (C * Aux >> 15) * Les >> 15;
754
755                 C = Aux * Aux >> 15;
756                 Aux = (C * DSP1ROM[0x0324] >> 15) + DSP1ROM[0x0325];
757                 CosAZS += (C * Aux >> 15) * CosAZS >> 15;
758         }
759
760         VOffset = Les * CosAZS >> 15;
761
762         DSP1_Inverse(SinAZS, 0, &CSec, &E);
763         DSP1_Normalize(VOffset, &C, &E);
764         DSP1_Normalize(C * CSec >> 15, &C, &E);
765
766         if (C == -32768) { C >>= 1; E++; }
767
768         *Vva = DSP1_Truncate(-C, E);
769
770         // Store Sec of clipped Zenith angle
771         DSP1_Inverse(CosAZS, 0, &SecAZS_C2, &SecAZS_E2);
772 }
773
774 void DSP1_Raster(short Vs, short *An, short *Bn, short *Cn, short *Dn)
775 {
776         short C, E, C1, E1;
777
778         DSP1_Inverse((Vs * SinAzs >> 15) + VOffset, 7, &C, &E);
779         E += VPlane_E;
780
781         C1 = C * VPlane_C >> 15;
782         E1 = E + SecAZS_E2;
783
784         DSP1_Normalize(C1, &C, &E);
785
786         C = DSP1_Truncate(C, E);
787
788         *An = C * CosAas >> 15;
789         *Cn = C * SinAas >> 15;
790
791         DSP1_Normalize(C1 * SecAZS_C2 >> 15, &C, &E1);
792
793         C = DSP1_Truncate(C, E1);
794
795         *Bn = C * -SinAas >> 15;
796         *Dn = C * CosAas >> 15;
797 }
798
799 short Op02FX;
800 short Op02FY;
801 short Op02FZ;
802 short Op02LFE;
803 short Op02LES;
804 short Op02AAS;
805 short Op02AZS;
806 short Op02VOF;
807 short Op02VVA;
808 short Op02CX;
809 short Op02CY;
810
811 void DSPOp02()
812 {
813         DSP1_Parameter(Op02FX, Op02FY, Op02FZ, Op02LFE, Op02LES, Op02AAS, Op02AZS, &Op02VOF, &Op02VVA, &Op02CX, &Op02CY);
814 }
815
816 short Op0AVS;
817 short Op0AA;
818 short Op0AB;
819 short Op0AC;
820 short Op0AD;
821
822 void DSPOp0A()
823 {
824         DSP1_Raster(Op0AVS, &Op0AA, &Op0AB, &Op0AC, &Op0AD);
825         Op0AVS++;
826 }
827
828 short Op06X;
829 short Op06Y;
830 short Op06Z;
831 short Op06H;
832 short Op06V;
833 unsigned short Op06S;
834
835 double ObjPX;
836 double ObjPY;
837 double ObjPZ;
838 double ObjPX1;
839 double ObjPY1;
840 double ObjPZ1;
841 double ObjPX2;
842 double ObjPY2;
843 double ObjPZ2;
844 double DivideOp06;
845 int Temp;
846 int tanval2;
847
848 #ifdef __OPT06__
849 void DSPOp06()
850 {
851    ObjPX=Op06X-Op02FX;
852    ObjPY=Op06Y-Op02FY;
853    ObjPZ=Op06Z-Op02FZ;
854
855    // rotate around Z
856    tanval2 = Angle(-Op02AAS+32768);
857 //   tanval2 = (-Op02AAS+32768)/(65536/INCR);
858    ObjPX1=(ObjPX*Cos(tanval2)+ObjPY*-Sin(tanval2));
859    ObjPY1=(ObjPX*Sin(tanval2)+ObjPY*Cos(tanval2));
860    ObjPZ1=ObjPZ;
861
862    // rotate around X
863 //   tanval2 = (-Op02AZS/(65536/INCR)) & 1023;
864    tanval2 = Angle(-Op02AZS);
865 //   tanval2 = (-Op02AZS)/256;
866    ObjPX2=ObjPX1;
867    ObjPY2=(ObjPY1*Cos(tanval2)+ObjPZ1*-Sin(tanval2));
868    ObjPZ2=(ObjPY1*Sin(tanval2)+ObjPZ1*Cos(tanval2));
869
870    #ifdef debug06
871    Log_Message("ObjPX2: %f ObjPY2: %f ObjPZ2: %f\n",ObjPX2,ObjPY2,ObjPZ2);
872    #endif
873
874    ObjPZ2=ObjPZ2-Op02LFE;
875
876    if (ObjPZ2<0)
877    {
878       double d;
879       Op06H=(short)(-ObjPX2*Op02LES/-(ObjPZ2)); //-ObjPX2*256/-ObjPZ2;
880       Op06V=(short)(-ObjPY2*Op02LES/-(ObjPZ2)); //-ObjPY2*256/-ObjPZ2;
881       d=(double)Op02LES;
882           d*=256.0;
883           d/=(-ObjPZ2);
884           if(d>65535.0)
885                   d=65535.0;
886           else if(d<0.0)
887                   d=0.0;
888           Op06S=(unsigned short)d;
889           //Op06S=(unsigned short)(256*(double)Op02LES/-ObjPZ2);
890       //Op06S=(unsigned short)((double)(256.0*((double)Op02LES)/(-ObjPZ2)));
891    }
892    else
893    {
894       Op06H=0;
895       Op06V=14*16;
896       Op06S=0xFFFF;
897    }
898
899
900    #ifdef DebugDSP1
901       Log_Message("OP06 X:%d Y:%d Z:%d",Op06X,Op06Y,Op06Z);
902       Log_Message("OP06 H:%d V:%d S:%d",Op06H,Op06V,Op06S);
903    #endif
904 }
905 #else
906
907 void DSPOp06()
908 {
909    ObjPX=Op06X-Op02FX;
910    ObjPY=Op06Y-Op02FY;
911    ObjPZ=Op06Z-Op02FZ;
912
913    // rotate around Z
914    tanval = (-Op02AAS+32768)/65536.0*6.2832;
915    ObjPX1=(ObjPX*cos(tanval)+ObjPY*-sin(tanval));
916    ObjPY1=(ObjPX*sin(tanval)+ObjPY*cos(tanval));
917    ObjPZ1=ObjPZ;
918
919    #ifdef debug06
920    Log_Message("Angle : %f", tanval);
921    Log_Message("ObjPX1: %f ObjPY1: %f ObjPZ1: %f\n",ObjPX1,ObjPY1,ObjPZ1);
922    Log_Message("cos(tanval) : %f  sin(tanval) : %f", cos(tanval), sin(tanval));
923    #endif
924
925    // rotate around X
926    tanval = (-Op02AZS)/65536.0*6.2832;
927    ObjPX2=ObjPX1;
928    ObjPY2=(ObjPY1*cos(tanval)+ObjPZ1*-sin(tanval));
929    ObjPZ2=(ObjPY1*sin(tanval)+ObjPZ1*cos(tanval));
930
931    #ifdef debug06
932    Log_Message("ObjPX2: %f ObjPY2: %f ObjPZ2: %f\n",ObjPX2,ObjPY2,ObjPZ2);
933    #endif
934
935    ObjPZ2=ObjPZ2-Op02LFE;
936
937    if (ObjPZ2<0)
938    {
939       Op06H=(short)(-ObjPX2*Op02LES/-(ObjPZ2)); //-ObjPX2*256/-ObjPZ2;
940       Op06V=(short)(-ObjPY2*Op02LES/-(ObjPZ2)); //-ObjPY2*256/-ObjPZ2;
941       double d=(double)Op02LES;
942           d*=256.0;
943           d/=(-ObjPZ2);
944           if(d>65535.0)
945                   d=65535.0;
946           else if(d<0.0)
947                   d=0.0;
948           Op06S=(unsigned short)d;
949 //        Op06S=(unsigned short)(256*(double)Op02LES/-ObjPZ2);
950    }
951    else
952    {
953       Op06H=0;
954       Op06V=14*16;
955       Op06S=0xFFFF;
956    }
957
958    #ifdef DebugDSP1
959       Log_Message("OP06 X:%d Y:%d Z:%d",Op06X,Op06Y,Op06Z);
960       Log_Message("OP06 H:%d V:%d S:%d",Op06H,Op06V,Op06S);
961    #endif
962 }
963 #endif 
964
965
966 short matrixC[3][3];
967 short matrixB[3][3];
968 short matrixA[3][3];
969
970 short Op01m;
971 short Op01Zr;
972 short Op01Xr;
973 short Op01Yr;
974 short Op11m;
975 short Op11Zr;
976 short Op11Xr;
977 short Op11Yr;
978 short Op21m;
979 short Op21Zr;
980 short Op21Xr;
981 short Op21Yr;
982
983 void DSPOp01()
984 {
985         short SinAz = DSP1_Sin(Op01Zr);
986         short CosAz = DSP1_Cos(Op01Zr);
987         short SinAy = DSP1_Sin(Op01Yr);
988         short CosAy = DSP1_Cos(Op01Yr);
989         short SinAx = DSP1_Sin(Op01Xr);
990         short CosAx = DSP1_Cos(Op01Xr);
991
992         Op01m >>= 1;
993
994         matrixA[0][0] = (Op01m * CosAz >> 15) * CosAy >> 15;
995         matrixA[0][1] = -((Op01m * SinAz >> 15) * CosAy >> 15);
996         matrixA[0][2] = Op01m * SinAy >> 15;
997
998         matrixA[1][0] = ((Op01m * SinAz >> 15) * CosAx >> 15) + (((Op01m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15);
999         matrixA[1][1] = ((Op01m * CosAz >> 15) * CosAx >> 15) - (((Op01m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15);
1000         matrixA[1][2] = -((Op01m * SinAx >> 15) * CosAy >> 15);
1001
1002         matrixA[2][0] = ((Op01m * SinAz >> 15) * SinAx >> 15) - (((Op01m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15);
1003         matrixA[2][1] = ((Op01m * CosAz >> 15) * SinAx >> 15) + (((Op01m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15);
1004         matrixA[2][2] = (Op01m * CosAx >> 15) * CosAy >> 15;
1005 }
1006
1007 void DSPOp11()
1008 {
1009         short SinAz = DSP1_Sin(Op11Zr);
1010         short CosAz = DSP1_Cos(Op11Zr);
1011         short SinAy = DSP1_Sin(Op11Yr);
1012         short CosAy = DSP1_Cos(Op11Yr);
1013         short SinAx = DSP1_Sin(Op11Xr);
1014         short CosAx = DSP1_Cos(Op11Xr);
1015
1016         Op11m >>= 1;
1017
1018         matrixB[0][0] = (Op11m * CosAz >> 15) * CosAy >> 15;
1019         matrixB[0][1] = -((Op11m * SinAz >> 15) * CosAy >> 15);
1020         matrixB[0][2] = Op11m * SinAy >> 15;
1021
1022         matrixB[1][0] = ((Op11m * SinAz >> 15) * CosAx >> 15) + (((Op11m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15);
1023         matrixB[1][1] = ((Op11m * CosAz >> 15) * CosAx >> 15) - (((Op11m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15);
1024         matrixB[1][2] = -((Op11m * SinAx >> 15) * CosAy >> 15);
1025
1026         matrixB[2][0] = ((Op11m * SinAz >> 15) * SinAx >> 15) - (((Op11m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15);
1027         matrixB[2][1] = ((Op11m * CosAz >> 15) * SinAx >> 15) + (((Op11m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15);
1028         matrixB[2][2] = (Op11m * CosAx >> 15) * CosAy >> 15;
1029 }
1030
1031 void DSPOp21()
1032 {
1033         short SinAz = DSP1_Sin(Op21Zr);
1034         short CosAz = DSP1_Cos(Op21Zr);
1035         short SinAy = DSP1_Sin(Op21Yr);
1036         short CosAy = DSP1_Cos(Op21Yr);
1037         short SinAx = DSP1_Sin(Op21Xr);
1038         short CosAx = DSP1_Cos(Op21Xr);
1039
1040         Op21m >>= 1;
1041
1042         matrixC[0][0] = (Op21m * CosAz >> 15) * CosAy >> 15;
1043         matrixC[0][1] = -((Op21m * SinAz >> 15) * CosAy >> 15);
1044         matrixC[0][2] = Op21m * SinAy >> 15;
1045
1046         matrixC[1][0] = ((Op21m * SinAz >> 15) * CosAx >> 15) + (((Op21m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15);
1047         matrixC[1][1] = ((Op21m * CosAz >> 15) * CosAx >> 15) - (((Op21m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15);
1048         matrixC[1][2] = -((Op21m * SinAx >> 15) * CosAy >> 15);
1049
1050         matrixC[2][0] = ((Op21m * SinAz >> 15) * SinAx >> 15) - (((Op21m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15);
1051         matrixC[2][1] = ((Op21m * CosAz >> 15) * SinAx >> 15) + (((Op21m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15);
1052         matrixC[2][2] = (Op21m * CosAx >> 15) * CosAy >> 15;
1053 }
1054
1055 short Op0DX;
1056 short Op0DY;
1057 short Op0DZ;
1058 short Op0DF;
1059 short Op0DL;
1060 short Op0DU;
1061 short Op1DX;
1062 short Op1DY;
1063 short Op1DZ;
1064 short Op1DF;
1065 short Op1DL;
1066 short Op1DU;
1067 short Op2DX;
1068 short Op2DY;
1069 short Op2DZ;
1070 short Op2DF;
1071 short Op2DL;
1072 short Op2DU;
1073
1074 void DSPOp0D()
1075 {
1076     Op0DF = (Op0DX * matrixA[0][0] >> 15) + (Op0DY * matrixA[0][1] >> 15) + (Op0DZ * matrixA[0][2] >> 15);
1077         Op0DL = (Op0DX * matrixA[1][0] >> 15) + (Op0DY * matrixA[1][1] >> 15) + (Op0DZ * matrixA[1][2] >> 15);
1078         Op0DU = (Op0DX * matrixA[2][0] >> 15) + (Op0DY * matrixA[2][1] >> 15) + (Op0DZ * matrixA[2][2] >> 15);
1079
1080         #ifdef DebugDSP1
1081                 Log_Message("OP0D X: %d Y: %d Z: %d / F: %d L: %d U: %d",Op0DX,Op0DY,Op0DZ,Op0DF,Op0DL,Op0DU);
1082         #endif
1083 }
1084
1085 void DSPOp1D()
1086 {
1087         Op1DF = (Op1DX * matrixB[0][0] >> 15) + (Op1DY * matrixB[0][1] >> 15) + (Op1DZ * matrixB[0][2] >> 15);
1088         Op1DL = (Op1DX * matrixB[1][0] >> 15) + (Op1DY * matrixB[1][1] >> 15) + (Op1DZ * matrixB[1][2] >> 15);
1089         Op1DU = (Op1DX * matrixB[2][0] >> 15) + (Op1DY * matrixB[2][1] >> 15) + (Op1DZ * matrixB[2][2] >> 15);
1090
1091         #ifdef DebugDSP1
1092                 Log_Message("OP1D X: %d Y: %d Z: %d / F: %d L: %d U: %d",Op1DX,Op1DY,Op1DZ,Op1DF,Op1DL,Op1DU);
1093         #endif
1094 }
1095
1096 void DSPOp2D()
1097 {
1098         Op2DF = (Op2DX * matrixC[0][0] >> 15) + (Op2DY * matrixC[0][1] >> 15) + (Op2DZ * matrixC[0][2] >> 15);
1099         Op2DL = (Op2DX * matrixC[1][0] >> 15) + (Op2DY * matrixC[1][1] >> 15) + (Op2DZ * matrixC[1][2] >> 15);
1100         Op2DU = (Op2DX * matrixC[2][0] >> 15) + (Op2DY * matrixC[2][1] >> 15) + (Op2DZ * matrixC[2][2] >> 15);
1101
1102         #ifdef DebugDSP1
1103                 Log_Message("OP2D X: %d Y: %d Z: %d / F: %d L: %d U: %d",Op2DX,Op2DY,Op2DZ,Op2DF,Op2DL,Op2DU);
1104         #endif
1105 }
1106
1107 short Op03F;
1108 short Op03L;
1109 short Op03U;
1110 short Op03X;
1111 short Op03Y;
1112 short Op03Z;
1113 short Op13F;
1114 short Op13L;
1115 short Op13U;
1116 short Op13X;
1117 short Op13Y;
1118 short Op13Z;
1119 short Op23F;
1120 short Op23L;
1121 short Op23U;
1122 short Op23X;
1123 short Op23Y;
1124 short Op23Z;
1125
1126 void DSPOp03()
1127 {
1128         Op03X = (Op03F * matrixA[0][0] >> 15) + (Op03L * matrixA[1][0] >> 15) + (Op03U * matrixA[2][0] >> 15);
1129         Op03Y = (Op03F * matrixA[0][1] >> 15) + (Op03L * matrixA[1][1] >> 15) + (Op03U * matrixA[2][1] >> 15);
1130         Op03Z = (Op03F * matrixA[0][2] >> 15) + (Op03L * matrixA[1][2] >> 15) + (Op03U * matrixA[2][2] >> 15);
1131
1132         #ifdef DebugDSP1
1133                 Log_Message("OP03 F: %d L: %d U: %d / X: %d Y: %d Z: %d",Op03F,Op03L,Op03U,Op03X,Op03Y,Op03Z);
1134         #endif
1135 }
1136
1137 void DSPOp13()
1138 {
1139         Op13X = (Op13F * matrixB[0][0] >> 15) + (Op13L * matrixB[1][0] >> 15) + (Op13U * matrixB[2][0] >> 15);
1140         Op13Y = (Op13F * matrixB[0][1] >> 15) + (Op13L * matrixB[1][1] >> 15) + (Op13U * matrixB[2][1] >> 15);
1141         Op13Z = (Op13F * matrixB[0][2] >> 15) + (Op13L * matrixB[1][2] >> 15) + (Op13U * matrixB[2][2] >> 15);
1142
1143         #ifdef DebugDSP1
1144                 Log_Message("OP13 F: %d L: %d U: %d / X: %d Y: %d Z: %d",Op13F,Op13L,Op13U,Op13X,Op13Y,Op13Z);
1145         #endif
1146 }
1147
1148 void DSPOp23()
1149 {
1150         Op23X = (Op23F * matrixC[0][0] >> 15) + (Op23L * matrixC[1][0] >> 15) + (Op23U * matrixC[2][0] >> 15);
1151         Op23Y = (Op23F * matrixC[0][1] >> 15) + (Op23L * matrixC[1][1] >> 15) + (Op23U * matrixC[2][1] >> 15);
1152         Op23Z = (Op23F * matrixC[0][2] >> 15) + (Op23L * matrixC[1][2] >> 15) + (Op23U * matrixC[2][2] >> 15);
1153
1154         #ifdef DebugDSP1
1155                 Log_Message("OP23 F: %d L: %d U: %d / X: %d Y: %d Z: %d",Op23F,Op23L,Op23U,Op23X,Op23Y,Op23Z);
1156         #endif
1157 }
1158
1159 short Op14Zr;
1160 short Op14Xr;
1161 short Op14Yr;
1162 short Op14U;
1163 short Op14F;
1164 short Op14L;
1165 short Op14Zrr;
1166 short Op14Xrr;
1167 short Op14Yrr;
1168
1169 void DSPOp14()
1170 {
1171         short CSec, ESec, CTan, CSin, C, E;
1172                 
1173         DSP1_Inverse(DSP1_Cos(Op14Xr), 0, &CSec, &ESec);
1174         
1175         // Rotation Around Z
1176         DSP1_NormalizeDouble(Op14U * DSP1_Cos(Op14Yr) - Op14F * DSP1_Sin(Op14Yr), &C, &E);
1177         
1178         E = ESec - E;
1179         
1180         DSP1_Normalize(C * CSec >> 15, &C, &E);
1181         
1182         Op14Zrr = Op14Zr + DSP1_Truncate(C, E);
1183
1184         // Rotation Around X
1185         Op14Xrr = Op14Xr + (Op14U * DSP1_Sin(Op14Yr) >> 15) + (Op14F * DSP1_Cos(Op14Yr) >> 15);
1186
1187         // Rotation Around Y
1188         DSP1_NormalizeDouble(Op14U * DSP1_Cos(Op14Yr) + Op14F * DSP1_Sin(Op14Yr), &C, &E);
1189
1190         E = ESec - E;
1191
1192         DSP1_Normalize(DSP1_Sin(Op14Xr), &CSin, &E);
1193
1194         CTan = CSec * CSin >> 15;
1195
1196         DSP1_Normalize(-(C * CTan >> 15), &C, &E);
1197         
1198         Op14Yrr = Op14Yr + DSP1_Truncate(C, E) + Op14L;
1199 }
1200
1201 void DSP1_Target(short H, short V, short *X, short *Y)
1202 {
1203         short C, E, C1, E1;
1204
1205         DSP1_Inverse((V * SinAzs >> 15) + VOffset, 8, &C, &E);
1206         E += VPlane_E;
1207
1208         C1 = C * VPlane_C >> 15;
1209         E1 = E + SecAZS_E1;
1210
1211         H <<= 8;
1212
1213         DSP1_Normalize(C1, &C, &E);
1214
1215         C = DSP1_Truncate(C, E) * H >> 15;
1216
1217         *X = CentreX + (C * CosAas >> 15);
1218         *Y = CentreY - (C * SinAas >> 15);
1219
1220         V <<= 8;
1221
1222         DSP1_Normalize(C1 * SecAZS_C1 >> 15, &C, &E1);
1223
1224         C = DSP1_Truncate(C, E1) * V >> 15;
1225
1226         *X += C * -SinAas >> 15;
1227         *Y += C * CosAas >> 15;
1228 }
1229
1230 short Op0EH;
1231 short Op0EV;
1232 short Op0EX;
1233 short Op0EY;
1234
1235 void DSPOp0E()
1236 {
1237         DSP1_Target(Op0EH, Op0EV, &Op0EX, &Op0EY);
1238 }
1239
1240 short Op0BX;
1241 short Op0BY;
1242 short Op0BZ;
1243 short Op0BS;
1244 short Op1BX;
1245 short Op1BY;
1246 short Op1BZ;
1247 short Op1BS;
1248 short Op2BX;
1249 short Op2BY;
1250 short Op2BZ;
1251 short Op2BS;
1252
1253 void DSPOp0B()
1254 {
1255     Op0BS = (Op0BX * matrixA[0][0] + Op0BY * matrixA[0][1] + Op0BZ * matrixA[0][2]) >> 15;
1256
1257         #ifdef DebugDSP1
1258                 Log_Message("OP0B");
1259         #endif
1260 }
1261
1262 void DSPOp1B()
1263 {   
1264     Op1BS = (Op1BX * matrixB[0][0] + Op1BY * matrixB[0][1] + Op1BZ * matrixB[0][2]) >> 15;
1265
1266         #ifdef DebugDSP1
1267                 Log_Message("OP1B X: %d Y: %d Z: %d S: %d",Op1BX,Op1BY,Op1BZ,Op1BS);
1268                 Log_Message("     MX: %d MY: %d MZ: %d Scale: %d",(short)(matrixB[0][0]*100),(short)(matrixB[0][1]*100),(short)(matrixB[0][2]*100),(short)(sc2*100));
1269         #endif
1270 }
1271
1272 void DSPOp2B()
1273 {
1274     Op2BS = (Op2BX * matrixC[0][0] + Op2BY * matrixC[0][1] + Op2BZ * matrixC[0][2]) >> 15;
1275
1276         #ifdef DebugDSP1
1277                 Log_Message("OP2B");
1278         #endif
1279 }
1280
1281 short Op08X,Op08Y,Op08Z,Op08Ll,Op08Lh;
1282
1283 void DSPOp08()
1284 {
1285         int Op08Size = (Op08X * Op08X + Op08Y * Op08Y + Op08Z * Op08Z) << 1;
1286         Op08Ll = Op08Size & 0xffff;
1287         Op08Lh = (Op08Size >> 16) & 0xffff;
1288
1289         #ifdef DebugDSP1
1290                 Log_Message("OP08 %d,%d,%d",Op08X,Op08Y,Op08Z);
1291                 Log_Message("OP08 ((Op08X^2)+(Op08Y^2)+(Op08X^2))=%x",Op08Size );
1292         #endif
1293 }
1294
1295 short Op18X,Op18Y,Op18Z,Op18R,Op18D;
1296
1297 void DSPOp18()
1298 {
1299    Op18D = (Op18X * Op18X + Op18Y * Op18Y + Op18Z * Op18Z - Op18R * Op18R) >> 15;
1300
1301    #ifdef DebugDSP1
1302       Log_Message("Op18 X: %d Y: %d Z: %d R: %D DIFF %d",Op18X,Op18Y,Op38Z,Op18D);
1303    #endif
1304 }
1305
1306 short Op38X,Op38Y,Op38Z,Op38R,Op38D;
1307
1308 void DSPOp38()
1309 {
1310    Op38D = (Op38X * Op38X + Op38Y * Op38Y + Op38Z * Op38Z - Op38R * Op38R) >> 15;
1311    Op38D++;
1312
1313    #ifdef DebugDSP1
1314       Log_Message("OP38 X: %d Y: %d Z: %d R: %D DIFF %d",Op38X,Op38Y,Op38Z,Op38D);
1315    #endif
1316 }
1317
1318 short Op28X;
1319 short Op28Y;
1320 short Op28Z;
1321 short Op28R;
1322
1323 void DSPOp28()
1324 {
1325         int Radius = Op28X * Op28X + Op28Y * Op28Y + Op28Z * Op28Z;
1326
1327         if (Radius == 0) Op28R = 0;
1328         else
1329         {
1330                 short C, E;
1331                 DSP1_NormalizeDouble(Radius, &C, &E);
1332                 if (E & 1) C = C * 0x4000 >> 15;
1333
1334                 short Pos = C * 0x0040 >> 15;
1335
1336                 short Node1 = DSP1ROM[0x00d5 + Pos];
1337                 short Node2 = DSP1ROM[0x00d6 + Pos];
1338
1339                 Op28R = ((Node2 - Node1) * (C & 0x1ff) >> 9) + Node1;
1340                 Op28R >>= (E >> 1);
1341         }
1342
1343    #ifdef DebugDSP1
1344       Log_Message("OP28 X:%d Y:%d Z:%d",Op28X,Op28Y,Op28Z);
1345       Log_Message("OP28 Vector Length %d",Op28R);
1346    #endif
1347 }
1348
1349 short Op1CX,Op1CY,Op1CZ;
1350 short Op1CXBR,Op1CYBR,Op1CZBR,Op1CXAR,Op1CYAR,Op1CZAR;
1351 short Op1CX1;
1352 short Op1CY1;
1353 short Op1CZ1;
1354 short Op1CX2;
1355 short Op1CY2;
1356 short Op1CZ2;
1357
1358 void DSPOp1C()
1359 {
1360         // Rotate Around Op1CZ1
1361         Op1CX1 = (Op1CYBR * DSP1_Sin(Op1CZ) >> 15) + (Op1CXBR * DSP1_Cos(Op1CZ) >> 15);
1362         Op1CY1 = (Op1CYBR * DSP1_Cos(Op1CZ) >> 15) - (Op1CXBR * DSP1_Sin(Op1CZ) >> 15);
1363         Op1CXBR = Op1CX1; Op1CYBR = Op1CY1;
1364
1365         // Rotate Around Op1CY1
1366         Op1CZ1 = (Op1CXBR * DSP1_Sin(Op1CY) >> 15) + (Op1CZBR * DSP1_Cos(Op1CY) >> 15);
1367         Op1CX1 = (Op1CXBR * DSP1_Cos(Op1CY) >> 15) - (Op1CZBR * DSP1_Sin(Op1CY) >> 15);
1368         Op1CXAR = Op1CX1; Op1CZBR = Op1CZ1;
1369
1370         // Rotate Around Op1CX1 
1371         Op1CY1 = (Op1CZBR * DSP1_Sin(Op1CX) >> 15) + (Op1CYBR * DSP1_Cos(Op1CX) >> 15);
1372         Op1CZ1 = (Op1CZBR * DSP1_Cos(Op1CX) >> 15) - (Op1CYBR * DSP1_Sin(Op1CX) >> 15);
1373         Op1CYAR = Op1CY1; Op1CZAR = Op1CZ1;
1374
1375         #ifdef DebugDSP1
1376                 Log_Message("OP1C Apply Matrix CX:%d CY:%d CZ",Op1CXAR,Op1CYAR,Op1CZAR);
1377         #endif
1378 }
1379
1380 unsigned short Op0FRamsize;
1381 unsigned short Op0FPass;
1382
1383 void DSPOp0F()
1384 {
1385    Op0FPass = 0x0000;
1386
1387    #ifdef DebugDSP1
1388       Log_Message("OP0F RAM Test Pass:%d", Op0FPass);
1389    #endif
1390 }
1391
1392 short Op2FUnknown;
1393 short Op2FSize;
1394
1395 void DSPOp2F()
1396 {
1397         Op2FSize=0x100;
1398 }