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