1 /*****************************************************************************\
2      Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3                 This file is licensed under the Snes9x License.
4    For further information, consult the LICENSE file in the root directory.
5 \*****************************************************************************/
6 
7 #include <math.h>
8 #include "snes9x.h"
9 #include "memmap.h"
10 
11 #define	C4_PI	3.14159265
12 
13 int16	C4WFXVal;
14 int16	C4WFYVal;
15 int16	C4WFZVal;
16 int16	C4WFX2Val;
17 int16	C4WFY2Val;
18 int16	C4WFDist;
19 int16	C4WFScale;
20 int16	C41FXVal;
21 int16	C41FYVal;
22 int16	C41FAngleRes;
23 int16	C41FDist;
24 int16	C41FDistVal;
25 
26 static double	tanval;
27 static double	c4x, c4y, c4z;
28 static double	c4x2, c4y2, c4z2;
29 
30 
C4TransfWireFrame(void)31 void C4TransfWireFrame (void)
32 {
33 	c4x = (double) C4WFXVal;
34 	c4y = (double) C4WFYVal;
35 	c4z = (double) C4WFZVal - 0x95;
36 
37 	// Rotate X
38 	tanval = -(double) C4WFX2Val * C4_PI * 2 / 128;
39 	c4y2 = c4y  *  cos(tanval) - c4z  * sin(tanval);
40 	c4z2 = c4y  *  sin(tanval) + c4z  * cos(tanval);
41 
42 	// Rotate Y
43 	tanval = -(double) C4WFY2Val * C4_PI * 2 / 128;
44 	c4x2 = c4x  *  cos(tanval) + c4z2 * sin(tanval);
45 	c4z  = c4x  * -sin(tanval) + c4z2 * cos(tanval);
46 
47 	// Rotate Z
48 	tanval = -(double) C4WFDist  * C4_PI * 2 / 128;
49 	c4x  = c4x2 *  cos(tanval) - c4y2 * sin(tanval);
50 	c4y  = c4x2 *  sin(tanval) + c4y2 * cos(tanval);
51 
52 	// Scale
53 	C4WFXVal = (int16) (c4x * (double) C4WFScale / (0x90 * (c4z + 0x95)) * 0x95);
54 	C4WFYVal = (int16) (c4y * (double) C4WFScale / (0x90 * (c4z + 0x95)) * 0x95);
55 }
56 
C4TransfWireFrame2(void)57 void C4TransfWireFrame2 (void)
58 {
59 	c4x = (double) C4WFXVal;
60 	c4y = (double) C4WFYVal;
61 	c4z = (double) C4WFZVal;
62 
63 	// Rotate X
64 	tanval = -(double) C4WFX2Val * C4_PI * 2 / 128;
65 	c4y2 = c4y  *  cos(tanval) - c4z  * sin(tanval);
66 	c4z2 = c4y  *  sin(tanval) + c4z  * cos(tanval);
67 
68 	// Rotate Y
69 	tanval = -(double) C4WFY2Val * C4_PI * 2 / 128;
70 	c4x2 = c4x  *  cos(tanval) + c4z2 * sin(tanval);
71 	c4z  = c4x  * -sin(tanval) + c4z2 * cos(tanval);
72 
73 	// Rotate Z
74 	tanval = -(double) C4WFDist  * C4_PI * 2 / 128;
75 	c4x  = c4x2 *  cos(tanval) - c4y2 * sin(tanval);
76 	c4y  = c4x2 *  sin(tanval) + c4y2 * cos(tanval);
77 
78 	// Scale
79 	C4WFXVal = (int16) (c4x * (double) C4WFScale / 0x100);
80 	C4WFYVal = (int16) (c4y * (double) C4WFScale / 0x100);
81 }
82 
C4CalcWireFrame(void)83 void C4CalcWireFrame (void)
84 {
85 	C4WFXVal = C4WFX2Val - C4WFXVal;
86 	C4WFYVal = C4WFY2Val - C4WFYVal;
87 
88 	if (abs(C4WFXVal) > abs(C4WFYVal))
89 	{
90 		C4WFDist = abs(C4WFXVal) + 1;
91 		C4WFYVal = (int16) (256 * (double) C4WFYVal / abs(C4WFXVal));
92 		if (C4WFXVal < 0)
93 			C4WFXVal = -256;
94 		else
95 			C4WFXVal =  256;
96 	}
97 	else
98 	{
99 		if (C4WFYVal != 0)
100 		{
101 			C4WFDist = abs(C4WFYVal) + 1;
102 			C4WFXVal = (int16) (256 * (double) C4WFXVal / abs(C4WFYVal));
103 			if (C4WFYVal < 0)
104 				C4WFYVal = -256;
105 			else
106 				C4WFYVal =  256;
107 		}
108 		else
109 			C4WFDist = 0;
110 	}
111 }
112 
C4Op1F(void)113 void C4Op1F (void)
114 {
115 	if (C41FXVal == 0)
116 	{
117 		if (C41FYVal > 0)
118 			C41FAngleRes = 0x80;
119 		else
120 			C41FAngleRes = 0x180;
121 	}
122 	else
123 	{
124 		tanval = (double) C41FYVal / C41FXVal;
125 		C41FAngleRes = (int16) (atan(tanval) / (C4_PI * 2) * 512);
126 		if (C41FXVal< 0)
127 			C41FAngleRes += 0x100;
128 		C41FAngleRes &= 0x1FF;
129 	}
130 }
131 
C4Op15(void)132 void C4Op15 (void)
133 {
134 	tanval = sqrt((double) C41FYVal * C41FYVal + (double) C41FXVal * C41FXVal);
135 	C41FDist = (int16) tanval;
136 }
137 
C4Op0D(void)138 void C4Op0D (void)
139 {
140 	tanval = sqrt((double) C41FYVal * C41FYVal + (double) C41FXVal * C41FXVal);
141 	tanval = C41FDistVal / tanval;
142 	C41FYVal = (int16) (C41FYVal * tanval * 0.99);
143 	C41FXVal = (int16) (C41FXVal * tanval * 0.98);
144 }
145 
S9xGetBasePointerC4(uint16 Address)146 uint8 * S9xGetBasePointerC4 (uint16 Address)
147 {
148 	if (Address >= 0x7f40 && Address <= 0x7f5e)
149 		return (NULL);
150 	return (Memory.C4RAM - 0x6000);
151 }
152 
S9xGetMemPointerC4(uint16 Address)153 uint8 * S9xGetMemPointerC4 (uint16 Address)
154 {
155 	if (Address >= 0x7f40 && Address <= 0x7f5e)
156 		return (NULL);
157 	return (Memory.C4RAM - 0x6000 + (Address & 0xffff));
158 }
159