7 signed int sin_table
[256];
8 signed int tan_table
[64];
15 // converts from 0-256 scale to 0-360 scale, then from degrees to radians
16 #define PIBT ((360.00f / 256.00f) * (3.14159265f / 180.00f))
18 for(degrees
=0;degrees
<256;degrees
++)
20 sin_table
[degrees
] = (int)(sin((double)degrees
* PIBT
) * (1 << CSF
));
23 for(degrees
=0;degrees
<64;degrees
++)
25 tan_table
[degrees
] = (int)(tan((double)degrees
* PIBT
) * (1 << 13));
32 /*void trig_test(void)
44 static int avsx=80<<CSF, avsy=60<<CSF;
45 static int avectx, avecty;
46 static int lx=-1,ly=-1;
47 static char firsttime = 1;
52 SDL_WarpMouse(240<<1,64<<1);
63 angle = GetAngle(x1, y1, x2, y2);
66 if (!avectx && !avecty) avtimer = 0;
67 if (x1 > x2 && avx>>CSF < x2) k++;
68 if (x1 < x2 && avx>>CSF > x2) k++;
69 if (y1 > y2 && avy>>CSF < y2) k++;
70 if (y1 < y2 && avy>>CSF > y2) k++;
71 if (k >= 2) avtimer = 0;
72 if (x1 != lx || y1 != ly) { lx=x1;ly=y1;avtimer=0; }
76 vector_from_angle(angle, 0xA0, &avectx, &avecty);
78 avx = x1<<CSF; avy = y1<<CSF;
85 PlotCircle(x1, y1, 120, 250, 120, 0, 256, 7);
86 PlotCircle(x2, y2, 200, 120, 0, 0, 256, 7);
88 fratio = ((double)ydist / (double)xdist);
89 if (fratio < 0) fratio = -fratio;
91 DrawSDLLine(x1, y1, x2, y2, 200, 120, 0);
92 DrawSDLLine(x1, y1, x1, y2, 200, 120, 0);
93 DrawSDLLine(x1, y2, x2, y2, 200, 120, 0);
94 sprintf(buf, "%d", xdist); font_draw((((x2-x1)/2)+x1)-(GetFontWidth(buf,0)/2), y2+8, buf, 0);
95 sprintf(buf, "%d", ydist); font_draw(x1+8, (((y2-y1)/2)+y1)-4, buf, 0);
96 sprintf(buf, "%d", angle); font_draw(x1-12-GetFontWidth(buf,0), y1-4, buf, 0);
97 PlotCircle(x1-8-GetFontWidth(buf,0),y1,120,250,120,128,200,6);
98 x = (x1+x2)/2; y = (y1+y2)/2; x+=4; y+=9;
99 sprintf(buf, "%.2f", fratio); font_draw(x,y,buf,0);
100 y+=8; sprintf(buf, "%04x", ratio); font_draw(x,y,buf,0);
101 PlotCircle(avx>>CSF, avy>>CSF, 200, 120, 120, 0, 256, 6);
106 void PlotCircle(int x, int y, uchar r, uchar g, uchar b, int start, int stop, int shift)
111 for(ang=start;ang<stop;ang+=2)
113 angle = ang; xa = sin_table[angle] >> shift;
114 angle += 64; ya = sin_table[angle] >> shift;
116 PlotSDLPixel(x+xa, y+ya, r, g, b);
122 // given an angle and a speed, places the X and Y speeds in xs and ys.
123 // note: the output values _ARE_ CSF'd, despite the >>= CSF done on them at the end.
124 void vector_from_angle(uint8_t angle
, int speed
, int *xs
, int *ys
)
128 *ys
= sin_table
[angle
];
129 *ys
*= speed
; *ys
>>= CSF
;
134 angle
+= 64; // wraps at 255 because it's a char
135 *xs
= sin_table
[angle
];
137 // what's going on here is that when we calculated sin_table, we could not hold the
138 // fractional (0-1.00f) values outputted from sin(), so we scaled them from 0-0x200.
139 // so now we basically are >>= CSFing the value back to it's original 0-1.00, then
140 // multiplying by speed. We're just doing it backwards so as the precision will stay.
141 // which is ok because multiplication and division are on the same level of OoO.
142 *xs
*= speed
; *xs
>>= CSF
;
146 int xinertia_from_angle(uint8_t angle
, int speed
)
149 int xs
= sin_table
[angle
];
150 xs
*= speed
; xs
>>= CSF
;
155 int yinertia_from_angle(uint8_t angle
, int speed
)
157 int ys
= sin_table
[angle
];
158 ys
*= speed
; ys
>>= CSF
;
163 // give it your position and a target position, and it tells you what angle you should travel at.
164 uint8_t GetAngle(int curx
, int cury
, int tgtx
, int tgty
)
170 xdist
= (tgtx
- curx
);
171 ydist
= (tgty
- cury
);
174 { // fixup for undefined slope
175 if (tgty
> cury
) return 0x40; // straight down
176 return 0xC0; // straight up
179 // (ydist / xdist) * 512 [scale it for integer floating point]
180 ratio
= (abs(ydist
) << 13) / abs(xdist
);
182 if (ratio
> tan_table
[63])
188 for(angle
=0;angle
<64;angle
++)
190 if (tan_table
[angle
] >= ratio
) break;
194 if (curx
> tgtx
) angle
= 0x80 - angle
;
195 if (cury
> tgty
) angle
= 0x100 - angle
;
200 void c------------------------------() {}
203 // convenience function.
204 // * spawn an object at o's action point.
205 // * launch it at the player at speed.
206 // * introduce "rand_variance" random error/variation into the launch angle.
207 void EmFireAngledShot(Object
*o
, int objtype
, int rand_variance
, int speed
)
211 shot
= SpawnObjectAtActionPoint(o
, objtype
);
212 ThrowObjectAtPlayer(shot
, rand_variance
, speed
);
216 // like EmFireAngledShot, but it's throws an already existing object
217 // instead of spawning a new one
218 void ThrowObjectAtPlayer(Object
*o
, int rand_variance
, int speed
)
220 ThrowObject(o
, player
->x
, player
->y
, rand_variance
, speed
);
223 // set the x&y inertia of object o so that it travels towards [destx,desty].
224 // rand_variance is a random amount of inaccuracy, in 0-255 degrees, to introduce
226 // speed is how quickly to throw the object, in CSF'd coordinates.
227 void ThrowObject(Object
*o
, int destx
, int desty
, int rand_variance
, int speed
)
229 uint8_t angle
= GetAngle(o
->x
, o
->y
, destx
, desty
);
232 angle
+= random(-rand_variance
, rand_variance
);
234 ThrowObjectAtAngle(o
, angle
, speed
);
237 // toss object o along angle angle at speed speed
238 void ThrowObjectAtAngle(Object
*o
, uint8_t angle
, int speed
)
240 o
->yinertia
= (sin_table
[angle
] * speed
) >> CSF
;
242 o
->xinertia
= (sin_table
[angle
] * speed
) >> CSF
;