1 /*
2 C-Dogs SDL
3 A port of the legendary (and fun) action/arcade cdogs.
4 Copyright (C) 1995 Ronny Wester
5 Copyright (C) 2003 Jeremy Chin
6 Copyright (C) 2003-2007 Lucas Martin-King
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
22 This file incorporates work covered by the following copyright and
23 permission notice:
24
25 Copyright (c) 2014, 2021 Cong Xu
26 All rights reserved.
27
28 Redistribution and use in source and binary forms, with or without
29 modification, are permitted provided that the following conditions are met:
30
31 Redistributions of source code must retain the above copyright notice, this
32 list of conditions and the following disclaimer.
33 Redistributions in binary form must reproduce the above copyright notice,
34 this list of conditions and the following disclaimer in the documentation
35 and/or other materials provided with the distribution.
36
37 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
38 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
41 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
43 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
44 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
45 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
47 POSSIBILITY OF SUCH DAMAGE.
48 */
49 #include "defs.h"
50
51 #include <math.h>
52
53 #include "tile.h"
54
CmdGetReverse(int cmd)55 int CmdGetReverse(int cmd)
56 {
57 int newCmd = cmd & ~(CMD_LEFT | CMD_RIGHT | CMD_UP | CMD_DOWN);
58 if (cmd & CMD_LEFT)
59 newCmd |= CMD_RIGHT;
60 if (cmd & CMD_RIGHT)
61 newCmd |= CMD_LEFT;
62 if (cmd & CMD_UP)
63 newCmd |= CMD_DOWN;
64 if (cmd & CMD_DOWN)
65 newCmd |= CMD_UP;
66 return newCmd;
67 }
68
StrSpecialDamage(const char * s)69 special_damage_e StrSpecialDamage(const char *s)
70 {
71 S2T(SPECIAL_FLAME, "Flame");
72 S2T(SPECIAL_POISON, "Poison");
73 S2T(SPECIAL_PETRIFY, "Petrify");
74 S2T(SPECIAL_CONFUSE, "Confuse");
75 CASSERT(false, "unknown special damage type");
76 return SPECIAL_NONE;
77 }
78
79 int cmd2dir[16] = {
80 0, // Nothing
81 DIRECTION_LEFT, // CMD_LEFT
82 DIRECTION_RIGHT, // CMD_RIGHT
83 0, // CMD_LEFT + CMD_RIGHT
84 DIRECTION_UP, // CMD_UP
85 DIRECTION_UPLEFT, // CMD_UP + CMD_LEFT
86 DIRECTION_UPRIGHT, // CMD_UP + CMD_RIGHT
87 0, // CMD_UP + CMD_LEFT + CMD_RIGHT
88 DIRECTION_DOWN, // CMD_DOWN
89 DIRECTION_DOWNLEFT, // CMD_DOWN + CMD_LEFT
90 DIRECTION_DOWNRIGHT, // CMD_DOWN + CMD_RIGHT
91 0, // CMD_DOWN + CMD_LEFT + CMD_RIGHT
92 0, // CMD_UP + CMD_DOWN
93 0, // CMD_UP + CMD_DOWN + CMD_LEFT
94 0, // CMD_UP + CMD_DOWN + CMD_RIGHT
95 0 // CMD_UP + CMD_DOWN + CMD_LEFT + CMD_RIGHT
96 };
97
98 int dir2cmd[8] = {
99 CMD_UP, CMD_UP + CMD_RIGHT, CMD_RIGHT, CMD_DOWN + CMD_RIGHT,
100 CMD_DOWN, CMD_DOWN + CMD_LEFT, CMD_LEFT, CMD_UP + CMD_LEFT};
101
102 float dir2radians[8] = {
103 0, MPI * 0.25f, MPI * 0.5f, MPI * 0.75f,
104 MPI, MPI * 1.25f, MPI * 1.5f, MPI * 1.75f,
105 };
106
Vec2FromRadiansScaled(const float radians)107 struct vec2 Vec2FromRadiansScaled(const float radians)
108 {
109 return svec2(sinf(radians), -cosf(radians) * TILE_HEIGHT / TILE_WIDTH);
110 }
Vec2FromRadians(const float radians)111 struct vec2 Vec2FromRadians(const float radians)
112 {
113 struct vec2 v = svec2_rotate(svec2(0, -1), radians);
114 // Scale Y so that they match the tile ratios
115 v.y *= (float)TILE_HEIGHT / TILE_WIDTH;
116 return v;
117 }
RadiansToDirection(const double r)118 direction_e RadiansToDirection(const double r)
119 {
120 // constrain to range [0, 2PI)
121 double radians = r;
122 while (radians < 0)
123 {
124 radians += 2 * MPI;
125 }
126 while (radians >= 2 * MPI)
127 {
128 radians -= 2 * MPI;
129 }
130 int d = (int)floor((radians + MPI / 8.0) / (MPI / 4.0));
131 if (d < DIRECTION_UP)
132 {
133 d += DIRECTION_COUNT;
134 }
135 if (d >= DIRECTION_COUNT)
136 {
137 d -= DIRECTION_COUNT;
138 }
139 return (direction_e)d;
140 }
DirectionOpposite(const direction_e d)141 direction_e DirectionOpposite(const direction_e d)
142 {
143 return (direction_e)(((int)d + 4) % DIRECTION_COUNT);
144 }
DirectionMirrorX(const direction_e d)145 direction_e DirectionMirrorX(const direction_e d)
146 {
147 return (direction_e)((DIRECTION_COUNT - (int)d) % DIRECTION_COUNT);
148 }
DirectionRotate(const direction_e d,const int dClockwise)149 direction_e DirectionRotate(const direction_e d, const int dClockwise)
150 {
151 int di = (int)d + dClockwise;
152 if (di < DIRECTION_UP)
153 {
154 di += DIRECTION_COUNT;
155 }
156 if (di >= DIRECTION_COUNT)
157 {
158 di -= DIRECTION_COUNT;
159 }
160 return (direction_e)di;
161 }
162