1 /*
2  *  This file is part of Dune Legacy.
3  *
4  *  Dune Legacy 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  *  Dune Legacy 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 Dune Legacy.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <mmath.h>
19 
20 #include <Definitions.h>
21 
22 #include <stdarg.h>
23 #include <algorithm>
24 #include <limits>
25 
26 extern int currentZoomlevel;
27 
28 
getRandomInt(int min,int max)29 int getRandomInt(int min, int max)
30 {
31     max++;
32     return ((rand() % (max-min)) + min);
33 }
34 
35 
getRandomOf(int numParam,...)36 int getRandomOf(int numParam, ...) {
37     int nthParam = getRandomInt(0,numParam-1);
38 
39     va_list arg_ptr;
40     va_start(arg_ptr, numParam);
41 
42     int ret = va_arg(arg_ptr, int);
43 
44     for(int i = 1; i <= nthParam; i++) {
45         ret = va_arg(arg_ptr, int);
46     }
47     va_end(arg_ptr);
48 
49     return ret;
50 }
51 
destinationAngleRad(const Coord & p1,const Coord & p2)52 FixPoint destinationAngleRad(const Coord& p1, const Coord& p2)
53 {
54 
55     FixPoint diffX = p2.x - p1.x;
56     FixPoint diffY = -(p2.y - p1.y);    // flip y
57 
58     if(diffX == 0 && diffY == 0) {
59         return FixPt_PI/2;
60     }
61 
62     FixPoint destAngle = FixPoint::atan2(diffY, diffX);
63 
64     if(destAngle < 0) {
65         destAngle += (FixPt_PI << 1);   // add 360°
66     }
67 
68     return destAngle;
69 }
70 
71 
distanceFrom(const Coord & p1,const Coord & p2)72 FixPoint distanceFrom(const Coord& p1, const Coord& p2)
73 {
74     FixPoint first = (p1.x - p2.x);
75     FixPoint second = (p1.y - p2.y);
76 
77     FixPoint z = FixPoint::sqrt(first*first + second*second);
78 
79     return z;
80 }
81 
distanceFrom(FixPoint x,FixPoint y,FixPoint to_x,FixPoint to_y)82 FixPoint distanceFrom(FixPoint x, FixPoint y, FixPoint to_x, FixPoint to_y)
83 {
84     FixPoint first = (x - to_x);
85     FixPoint second = (y - to_y);
86 
87     FixPoint z = FixPoint::sqrt(first*first + second*second);
88 
89     return z;
90 }
91 
mirrorAngleHorizontal(int angle)92 int mirrorAngleHorizontal(int angle) {
93     switch(angle % NUM_ANGLES) {
94         case RIGHT:     return LEFT;
95         case RIGHTUP:   return LEFTUP;
96         case UP:        return UP;
97         case LEFTUP:    return RIGHTUP;
98         case LEFT:      return RIGHT;
99         case LEFTDOWN:  return RIGHTDOWN;
100         case DOWN:      return DOWN;
101         case RIGHTDOWN: return LEFTDOWN;
102         default:        return angle;
103     }
104 }
105 
106 
107 
mirrorAngleVertical(int angle)108 int mirrorAngleVertical(int angle) {
109     switch(angle % NUM_ANGLES) {
110         case RIGHT:     return RIGHT;
111         case RIGHTUP:   return RIGHTDOWN;
112         case UP:        return DOWN;
113         case LEFTUP:    return LEFTDOWN;
114         case LEFT:      return LEFT;
115         case LEFTDOWN:  return LEFTUP;
116         case DOWN:      return UP;
117         case RIGHTDOWN: return RIGHTUP;
118         default:        return angle;
119     }
120 }
121 
122 
world2zoomedWorld(int x)123 int world2zoomedWorld(int x) {
124     if(x<0) {
125         switch(currentZoomlevel) {
126             case 0:     return (x-3)/4;
127             case 1:     return (x-1)/2;
128             case 2:     return ((x-1)*3)/4;
129             case 3:
130             default:    return x;
131         }
132     } else {
133         switch(currentZoomlevel) {
134             case 0:     return x/4;
135             case 1:     return x/2;
136             case 2:     return (x*3)/4;
137             case 3:
138             default:    return x;
139         }
140     }
141 }
142 
143 
world2zoomedWorld(float x)144 int world2zoomedWorld(float x) {
145     switch(currentZoomlevel) {
146         case 0:     return lround(x*0.25f);
147         case 1:     return lround(x*0.5f);
148         case 2:     return lround(x*0.75f);
149         case 3:
150         default:    return lround(x);
151     }
152 }
153 
154 
world2zoomedWorld(const Coord & coord)155 Coord world2zoomedWorld(const Coord& coord) {
156     return Coord(world2zoomedWorld(coord.x), world2zoomedWorld(coord.y));
157 }
158 
159 
zoomedWorld2world(int x)160 int zoomedWorld2world(int x) {
161     switch(currentZoomlevel) {
162         case 0:     return x*4;
163         case 1:     return x*2;
164         case 2:     return (x*4)/3;
165         case 3:
166         default:    return x;
167     }
168 }
169 
170 
zoomedWorld2world(const Coord & coord)171 Coord zoomedWorld2world(const Coord& coord) {
172     return Coord(zoomedWorld2world(coord.x), zoomedWorld2world(coord.y));
173 }
174