346 lines
13 KiB
C
346 lines
13 KiB
C
/*
|
|
Copyright (C) 1997-2005 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach )
|
|
|
|
http://www.zsnes.com
|
|
http://sourceforge.net/projects/zsnes
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later
|
|
version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#ifdef __LINUX__
|
|
#include "../gblhdr.h"
|
|
#else
|
|
#include <math.h>
|
|
#endif
|
|
|
|
#ifdef PI
|
|
#undef PI
|
|
#endif
|
|
#define PI 3.1415926535897932384626433832795
|
|
#define Cos(a) ((double) CosTable[a])
|
|
#define Sin(a) ((double) SinTable[a])
|
|
#define Tan(a) (CosTable[a]?((((int)SinTable[a])<<16)/CosTable[a]):0x80000000)
|
|
|
|
short SinTable[512] = {
|
|
0, 402, 804, 1206, 1607, 2009, 2410, 2811,
|
|
3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997,
|
|
6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126,
|
|
9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167,
|
|
12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090,
|
|
15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869,
|
|
18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475,
|
|
20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884,
|
|
23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073,
|
|
25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020,
|
|
27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707,
|
|
28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117,
|
|
30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237,
|
|
31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057,
|
|
32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568,
|
|
32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765,
|
|
32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647,
|
|
32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214,
|
|
32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471,
|
|
31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425,
|
|
30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086,
|
|
28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466,
|
|
27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583,
|
|
25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453,
|
|
23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097,
|
|
20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537,
|
|
18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800,
|
|
15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910,
|
|
12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896,
|
|
9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786,
|
|
6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611,
|
|
3211, 2811, 2410, 2009, 1607, 1206, 804, 402,
|
|
0, -402, -804, -1206, -1607, -2009, -2410, -2811,
|
|
-3211, -3611, -4011, -4409, -4808, -5205, -5602, -5997,
|
|
-6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126,
|
|
-9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167,
|
|
-12539, -12910, -13278, -13645, -14010, -14372, -14732, -15090,
|
|
-15446, -15800, -16151, -16499, -16846, -17189, -17530, -17869,
|
|
-18204, -18537, -18868, -19195, -19519, -19841, -20159, -20475,
|
|
-20787, -21097, -21403, -21706, -22005, -22301, -22594, -22884,
|
|
-23170, -23453, -23732, -24007, -24279, -24547, -24812, -25073,
|
|
-25330, -25583, -25832, -26077, -26319, -26557, -26790, -27020,
|
|
-27245, -27466, -27684, -27897, -28106, -28310, -28511, -28707,
|
|
-28898, -29086, -29269, -29447, -29621, -29791, -29956, -30117,
|
|
-30273, -30425, -30572, -30714, -30852, -30985, -31114, -31237,
|
|
-31357, -31471, -31581, -31685, -31785, -31881, -31971, -32057,
|
|
-32138, -32214, -32285, -32351, -32413, -32469, -32521, -32568,
|
|
-32610, -32647, -32679, -32706, -32728, -32745, -32758, -32765,
|
|
-32767, -32765, -32758, -32745, -32728, -32706, -32679, -32647,
|
|
-32610, -32568, -32521, -32469, -32413, -32351, -32285, -32214,
|
|
-32138, -32057, -31971, -31881, -31785, -31685, -31581, -31471,
|
|
-31357, -31237, -31114, -30985, -30852, -30714, -30572, -30425,
|
|
-30273, -30117, -29956, -29791, -29621, -29447, -29269, -29086,
|
|
-28898, -28707, -28511, -28310, -28106, -27897, -27684, -27466,
|
|
-27245, -27020, -26790, -26557, -26319, -26077, -25832, -25583,
|
|
-25330, -25073, -24812, -24547, -24279, -24007, -23732, -23453,
|
|
-23170, -22884, -22594, -22301, -22005, -21706, -21403, -21097,
|
|
-20787, -20475, -20159, -19841, -19519, -19195, -18868, -18537,
|
|
-18204, -17869, -17530, -17189, -16846, -16499, -16151, -15800,
|
|
-15446, -15090, -14732, -14372, -14010, -13645, -13278, -12910,
|
|
-12539, -12167, -11793, -11416, -11039, -10659, -10278, -9896,
|
|
-9512, -9126, -8739, -8351, -7961, -7571, -7179, -6786,
|
|
-6392, -5997, -5602, -5205, -4808, -4409, -4011, -3611,
|
|
-3211, -2811, -2410, -2009, -1607, -1206, -804, -402
|
|
};
|
|
|
|
short CosTable[512] = {
|
|
32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647,
|
|
32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214,
|
|
32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471,
|
|
31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425,
|
|
30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086,
|
|
28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466,
|
|
27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583,
|
|
25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453,
|
|
23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097,
|
|
20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537,
|
|
18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800,
|
|
15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910,
|
|
12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896,
|
|
9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786,
|
|
6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611,
|
|
3211, 2811, 2410, 2009, 1607, 1206, 804, 402,
|
|
0, -402, -804, -1206, -1607, -2009, -2410, -2811,
|
|
-3211, -3611, -4011, -4409, -4808, -5205, -5602, -5997,
|
|
-6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126,
|
|
-9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167,
|
|
-12539, -12910, -13278, -13645, -14010, -14372, -14732, -15090,
|
|
-15446, -15800, -16151, -16499, -16846, -17189, -17530, -17869,
|
|
-18204, -18537, -18868, -19195, -19519, -19841, -20159, -20475,
|
|
-20787, -21097, -21403, -21706, -22005, -22301, -22594, -22884,
|
|
-23170, -23453, -23732, -24007, -24279, -24547, -24812, -25073,
|
|
-25330, -25583, -25832, -26077, -26319, -26557, -26790, -27020,
|
|
-27245, -27466, -27684, -27897, -28106, -28310, -28511, -28707,
|
|
-28898, -29086, -29269, -29447, -29621, -29791, -29956, -30117,
|
|
-30273, -30425, -30572, -30714, -30852, -30985, -31114, -31237,
|
|
-31357, -31471, -31581, -31685, -31785, -31881, -31971, -32057,
|
|
-32138, -32214, -32285, -32351, -32413, -32469, -32521, -32568,
|
|
-32610, -32647, -32679, -32706, -32728, -32745, -32758, -32765,
|
|
-32767, -32765, -32758, -32745, -32728, -32706, -32679, -32647,
|
|
-32610, -32568, -32521, -32469, -32413, -32351, -32285, -32214,
|
|
-32138, -32057, -31971, -31881, -31785, -31685, -31581, -31471,
|
|
-31357, -31237, -31114, -30985, -30852, -30714, -30572, -30425,
|
|
-30273, -30117, -29956, -29791, -29621, -29447, -29269, -29086,
|
|
-28898, -28707, -28511, -28310, -28106, -27897, -27684, -27466,
|
|
-27245, -27020, -26790, -26557, -26319, -26077, -25832, -25583,
|
|
-25330, -25073, -24812, -24547, -24279, -24007, -23732, -23453,
|
|
-23170, -22884, -22594, -22301, -22005, -21706, -21403, -21097,
|
|
-20787, -20475, -20159, -19841, -19519, -19195, -18868, -18537,
|
|
-18204, -17869, -17530, -17189, -16846, -16499, -16151, -15800,
|
|
-15446, -15090, -14732, -14372, -14010, -13645, -13278, -12910,
|
|
-12539, -12167, -11793, -11416, -11039, -10659, -10278, -9896,
|
|
-9512, -9126, -8739, -8351, -7961, -7571, -7179, -6786,
|
|
-6392, -5997, -5602, -5205, -4808, -4409, -4011, -3611,
|
|
-3211, -2811, -2410, -2009, -1607, -1206, -804, -402,
|
|
0, 402, 804, 1206, 1607, 2009, 2410, 2811,
|
|
3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997,
|
|
6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126,
|
|
9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167,
|
|
12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090,
|
|
15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869,
|
|
18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475,
|
|
20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884,
|
|
23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073,
|
|
25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020,
|
|
27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707,
|
|
28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117,
|
|
30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237,
|
|
31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057,
|
|
32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568,
|
|
32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765
|
|
};
|
|
|
|
short C4WFXVal;
|
|
short C4WFYVal;
|
|
short C4WFZVal;
|
|
short C4WFX2Val;
|
|
short C4WFY2Val;
|
|
short C4WFDist;
|
|
short C4WFScale;
|
|
double tanval;
|
|
double c4x,c4y,c4z;
|
|
double c4x2,c4y2,c4z2;
|
|
|
|
void C4TransfWireFrame()
|
|
{
|
|
c4x=(double)C4WFXVal;
|
|
c4y=(double)C4WFYVal;
|
|
c4z=(double)C4WFZVal-0x95;
|
|
|
|
// Rotate X
|
|
tanval=-(double)C4WFX2Val*PI*2/128;
|
|
c4y2=c4y*cos(tanval)-c4z*sin(tanval);
|
|
c4z2=c4y*sin(tanval)+c4z*cos(tanval);
|
|
|
|
// Rotate Y
|
|
tanval=-(double)C4WFY2Val*PI*2/128;
|
|
c4x2=c4x*cos(tanval)+c4z2*sin(tanval);
|
|
c4z=c4x*-sin(tanval)+c4z2*cos(tanval);
|
|
|
|
// Rotate Z
|
|
tanval=-(double)C4WFDist*PI*2/128;
|
|
c4x=c4x2*cos(tanval)-c4y2*sin(tanval);
|
|
c4y=c4x2*sin(tanval)+c4y2*cos(tanval);
|
|
|
|
// Scale
|
|
C4WFXVal=(short)(c4x*C4WFScale/(0x90*(c4z+0x95))*0x95);
|
|
C4WFYVal=(short)(c4y*C4WFScale/(0x90*(c4z+0x95))*0x95);
|
|
}
|
|
|
|
void C4TransfWireFrame2()
|
|
{
|
|
c4x=(double)C4WFXVal;
|
|
c4y=(double)C4WFYVal;
|
|
c4z=(double)C4WFZVal;
|
|
|
|
// Rotate X
|
|
tanval=-(double)C4WFX2Val*PI*2/128;
|
|
c4y2=c4y*cos(tanval)-c4z*sin(tanval);
|
|
c4z2=c4y*sin(tanval)+c4z*cos(tanval);
|
|
|
|
// Rotate Y
|
|
tanval=-(double)C4WFY2Val*PI*2/128;
|
|
c4x2=c4x*cos(tanval)+c4z2*sin(tanval);
|
|
c4z=c4x*-sin(tanval)+c4z2*cos(tanval);
|
|
|
|
// Rotate Z
|
|
tanval=-(double)C4WFDist*PI*2/128;
|
|
c4x=c4x2*cos(tanval)-c4y2*sin(tanval);
|
|
c4y=c4x2*sin(tanval)+c4y2*cos(tanval);
|
|
|
|
// Scale
|
|
C4WFXVal=(short)(c4x*C4WFScale/0x100);
|
|
C4WFYVal=(short)(c4y*C4WFScale/0x100);
|
|
}
|
|
|
|
void C4CalcWireFrame()
|
|
{
|
|
C4WFXVal=C4WFX2Val-C4WFXVal;
|
|
C4WFYVal=C4WFY2Val-C4WFYVal;
|
|
if (abs(C4WFXVal)>abs(C4WFYVal)){
|
|
C4WFDist=abs(C4WFXVal)+1;
|
|
C4WFYVal=(256*(long)C4WFYVal)/abs(C4WFXVal);
|
|
if (C4WFXVal<0) C4WFXVal=-256;
|
|
else C4WFXVal=256;
|
|
}
|
|
else
|
|
if (C4WFYVal!=0) {
|
|
C4WFDist=abs(C4WFYVal)+1;
|
|
C4WFXVal=(256*(long)C4WFXVal)/abs(C4WFYVal);
|
|
if (C4WFYVal<0) C4WFYVal=-256;
|
|
else C4WFYVal=256;
|
|
}
|
|
else C4WFDist=0;
|
|
}
|
|
|
|
short C41FXVal;
|
|
short C41FYVal;
|
|
short C41FAngleRes;
|
|
short C41FDist;
|
|
short C41FDistVal;
|
|
|
|
void C4Op1F()
|
|
{
|
|
if (C41FXVal == 0) {
|
|
if (C41FYVal>0) C41FAngleRes=0x80;
|
|
else C41FAngleRes=0x180;
|
|
}
|
|
else {
|
|
tanval = ((double)C41FYVal)/((double)C41FXVal);
|
|
C41FAngleRes=(short)(atan(tanval)/(PI*2)*512);
|
|
C41FAngleRes=C41FAngleRes;
|
|
if (C41FXVal<0) C41FAngleRes+=0x100;
|
|
C41FAngleRes&=0x1FF;
|
|
}
|
|
}
|
|
|
|
void C4Op15()
|
|
{
|
|
tanval=sqrt(((double)C41FYVal)*((double)C41FYVal)+((double)C41FXVal)*
|
|
((double)C41FXVal));
|
|
C41FDist=(short)tanval;
|
|
}
|
|
|
|
void C4Op0D()
|
|
{
|
|
tanval=sqrt(((double)C41FYVal)*((double)C41FYVal)+((double)C41FXVal)*
|
|
((double)C41FXVal));
|
|
tanval=(double)C41FDistVal/tanval;
|
|
C41FYVal=(short)(((double)C41FYVal*tanval)*0.99);
|
|
C41FXVal=(short)(((double)C41FXVal*tanval)*0.98);
|
|
}
|
|
|
|
#define READ_WORD(s) (*(unsigned short *) (s))
|
|
void C4Op22()
|
|
{
|
|
extern unsigned char *C4Ram;
|
|
short angle1 = READ_WORD(C4Ram+0x1f8c) & 0x1ff;
|
|
short angle2 = READ_WORD(C4Ram+0x1f8f) & 0x1ff;
|
|
int tan1 = Tan(angle1);
|
|
int tan2 = Tan(angle2);
|
|
short y = READ_WORD(C4Ram+0x1f83) - READ_WORD(C4Ram+0x1f89);
|
|
short left, right;
|
|
|
|
int j;
|
|
for (j = 0; j < 225; j++, y++)
|
|
{
|
|
if (y >= 0)
|
|
{
|
|
left = (((int)tan1*y) >> 16) - READ_WORD(C4Ram+0x1f80) + READ_WORD(C4Ram+0x1f86);
|
|
right = (((int)tan2*y) >> 16) - READ_WORD(C4Ram+0x1f80) + READ_WORD(C4Ram+0x1f86) + READ_WORD(C4Ram+0x1f93);
|
|
|
|
if(left<0 && right<0)
|
|
{
|
|
left = 1;
|
|
right = 0;
|
|
}
|
|
else if (left < 0)
|
|
{
|
|
left = 0;
|
|
}
|
|
else if (right < 0)
|
|
{
|
|
right = 0;
|
|
}
|
|
if (left > 255 && right > 255)
|
|
{
|
|
left = 255;
|
|
right = 254;
|
|
}
|
|
else if (left > 255)
|
|
{
|
|
left = 255;
|
|
}
|
|
else if (right > 255)
|
|
{
|
|
right = 255;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
left = 1;
|
|
right = 0;
|
|
}
|
|
C4Ram[j+0x800] = (unsigned char)left;
|
|
C4Ram[j+0x900] = (unsigned char)right;
|
|
}
|
|
}
|