1 //Copyright Paul Reiche, Fred Ford. 1992-2002
2
3 /*
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #include "velocity.h"
20
21 #include "units.h"
22 #include "libs/compiler.h"
23
24
25 #define VELOCITY_REMAINDER(v) ((v) & (VELOCITY_SCALE - 1))
26
27 void
GetCurrentVelocityComponents(VELOCITY_DESC * velocityptr,SIZE * pdx,SIZE * pdy)28 GetCurrentVelocityComponents (VELOCITY_DESC *velocityptr, SIZE *pdx, SIZE *pdy)
29 {
30 *pdx = WORLD_TO_VELOCITY (velocityptr->vector.width)
31 + (velocityptr->fract.width - (SIZE)HIBYTE (velocityptr->incr.width));
32 *pdy = WORLD_TO_VELOCITY (velocityptr->vector.height)
33 + (velocityptr->fract.height - (SIZE)HIBYTE (velocityptr->incr.height));
34 }
35
36 void
GetNextVelocityComponents(VELOCITY_DESC * velocityptr,SIZE * pdx,SIZE * pdy,COUNT num_frames)37 GetNextVelocityComponents (VELOCITY_DESC *velocityptr, SIZE *pdx, SIZE *pdy,
38 COUNT num_frames)
39 {
40 COUNT e;
41
42 e = (COUNT)((COUNT)velocityptr->error.width +
43 ((COUNT)velocityptr->fract.width * num_frames));
44 *pdx = (velocityptr->vector.width * num_frames)
45 + ((SIZE)((SBYTE)LOBYTE (velocityptr->incr.width))
46 * (e >> VELOCITY_SHIFT));
47 velocityptr->error.width = VELOCITY_REMAINDER (e);
48
49 e = (COUNT)((COUNT)velocityptr->error.height +
50 ((COUNT)velocityptr->fract.height * num_frames));
51 *pdy = (velocityptr->vector.height * num_frames)
52 + ((SIZE)((SBYTE)LOBYTE (velocityptr->incr.height))
53 * (e >> VELOCITY_SHIFT));
54 velocityptr->error.height = VELOCITY_REMAINDER (e);
55 }
56
57 void
SetVelocityVector(VELOCITY_DESC * velocityptr,SIZE magnitude,COUNT facing)58 SetVelocityVector (VELOCITY_DESC *velocityptr, SIZE magnitude, COUNT facing)
59 {
60 COUNT angle;
61 SIZE dx, dy;
62
63 angle = velocityptr->TravelAngle =
64 FACING_TO_ANGLE (NORMALIZE_FACING (facing));
65 magnitude = WORLD_TO_VELOCITY (magnitude);
66 dx = COSINE (angle, magnitude);
67 dy = SINE (angle, magnitude);
68 if (dx >= 0)
69 {
70 velocityptr->vector.width = VELOCITY_TO_WORLD (dx);
71 velocityptr->incr.width = MAKE_WORD ((BYTE)1, (BYTE)0);
72 }
73 else
74 {
75 dx = -dx;
76 velocityptr->vector.width = -VELOCITY_TO_WORLD (dx);
77 velocityptr->incr.width =
78 MAKE_WORD ((BYTE)0xFF, (BYTE)(VELOCITY_REMAINDER (dx) << 1));
79 }
80 if (dy >= 0)
81 {
82 velocityptr->vector.height = VELOCITY_TO_WORLD (dy);
83 velocityptr->incr.height = MAKE_WORD ((BYTE)1, (BYTE)0);
84 }
85 else
86 {
87 dy = -dy;
88 velocityptr->vector.height = -VELOCITY_TO_WORLD (dy);
89 velocityptr->incr.height =
90 MAKE_WORD ((BYTE)0xFF, (BYTE)(VELOCITY_REMAINDER (dy) << 1));
91 }
92
93 velocityptr->fract.width = VELOCITY_REMAINDER (dx);
94 velocityptr->fract.height = VELOCITY_REMAINDER (dy);
95 velocityptr->error.width = velocityptr->error.height = 0;
96 }
97
98 void
SetVelocityComponents(VELOCITY_DESC * velocityptr,SIZE dx,SIZE dy)99 SetVelocityComponents (VELOCITY_DESC *velocityptr, SIZE dx, SIZE dy)
100 {
101 COUNT angle;
102
103 if ((angle = ARCTAN (dx, dy)) == FULL_CIRCLE)
104 {
105 ZeroVelocityComponents (velocityptr);
106 }
107 else
108 {
109 if (dx >= 0)
110 {
111 velocityptr->vector.width = VELOCITY_TO_WORLD (dx);
112 velocityptr->incr.width = MAKE_WORD ((BYTE)1, (BYTE)0);
113 }
114 else
115 {
116 dx = -dx;
117 velocityptr->vector.width = -VELOCITY_TO_WORLD (dx);
118 velocityptr->incr.width =
119 MAKE_WORD ((BYTE)0xFF, (BYTE)(VELOCITY_REMAINDER (dx) << 1));
120 }
121 if (dy >= 0)
122 {
123 velocityptr->vector.height = VELOCITY_TO_WORLD (dy);
124 velocityptr->incr.height = MAKE_WORD ((BYTE)1, (BYTE)0);
125 }
126 else
127 {
128 dy = -dy;
129 velocityptr->vector.height = -VELOCITY_TO_WORLD (dy);
130 velocityptr->incr.height =
131 MAKE_WORD ((BYTE)0xFF, (BYTE)(VELOCITY_REMAINDER (dy) << 1));
132 }
133
134 velocityptr->fract.width = VELOCITY_REMAINDER (dx);
135 velocityptr->fract.height = VELOCITY_REMAINDER (dy);
136 velocityptr->error.width = velocityptr->error.height = 0;
137 }
138
139 velocityptr->TravelAngle = angle;
140 }
141
142 void
DeltaVelocityComponents(VELOCITY_DESC * velocityptr,SIZE dx,SIZE dy)143 DeltaVelocityComponents (VELOCITY_DESC *velocityptr, SIZE dx, SIZE dy)
144 {
145
146 dx += WORLD_TO_VELOCITY (velocityptr->vector.width)
147 + (velocityptr->fract.width - (SIZE)HIBYTE (velocityptr->incr.width));
148 dy += WORLD_TO_VELOCITY (velocityptr->vector.height)
149 + (velocityptr->fract.height - (SIZE)HIBYTE (velocityptr->incr.height));
150
151 SetVelocityComponents (velocityptr, dx, dy);
152 }
153
154