OSDN Git Service

Year update
[skyscrapersim/skyscraper.git] / src / sbs / globals.cpp
1 /* $Id$ */
2
3 /*
4         Scalable Building Simulator - Global Functions
5         The Skyscraper Project - Version 1.10 Alpha
6         Copyright (C)2004-2016 Ryan Thoryk
7         http://www.skyscrapersim.com
8         http://sourceforge.net/projects/skyscraper
9         Contact - ryan@tliquest.net
10
11         This program is free software; you can redistribute it and/or
12         modify it under the terms of the GNU General Public License
13         as published by the Free Software Foundation; either version 2
14         of the License, or (at your option) any later version.
15
16         This program is distributed in the hope that it will be useful,
17         but WITHOUT ANY WARRANTY; without even the implied warranty of
18         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19         GNU General Public License for more details.
20
21         You should have received a copy of the GNU General Public License
22         along with this program; if not, write to the Free Software
23         Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24 */
25
26 #include <algorithm>
27 #include <string>
28 #include <ctype.h>
29 #include <stdlib.h>
30 #include <errno.h>
31 #include <limits.h>
32 #include <math.h>
33 #include <OgreString.h>
34 #include <OgreStringConverter.h>
35 #include "unix.h"
36 #include "globals.h"
37
38 namespace SBS {
39
40 bool IsEven(int Number)
41 {
42         //Determine if the passed number is even.
43         //If number divides evenly, return true
44
45         if (((float)Number / 2) == int((float)Number / 2))
46                 return true;
47         else
48                 return false;
49 }
50
51 bool IsNumeric(char character)
52 {
53         //test to see if a character is numeric
54
55         if (character > 47 && character < 58)
56                 return true;
57         return false;
58 }
59
60 bool IsNumeric(const std::string &string)
61 {
62         //test to see if a string is numeric
63
64         float num = 0;
65         return IsNumeric(string, num);
66 }
67
68 bool IsNumeric(const std::string &string, int &number)
69 {
70         //test to see if a string is numeric, and return number as integer
71
72         float num = 0;
73         bool result = IsNumeric(string, num);
74         number = (int)num;
75         return result;
76 }
77
78 bool IsNumeric(const std::string &string, float &number)
79 {
80         //test to see if a string is numeric, and return number as float
81
82         char* end = 0;
83
84 #ifdef _WIN32
85         number = (float)std::strtod(string.c_str(), &end);
86 #else
87         number = std::strtof(string.c_str(), &end);
88 #endif
89
90         return end != 0 && *end == 0;
91 }
92
93 bool IsNumeric(const std::string &string, double &number)
94 {
95         //test to see if a string is numeric, and return number as float
96
97         char* end = 0;
98
99         number = std::strtod(string.c_str(), &end);
100
101         return end != 0 && *end == 0;
102 }
103
104 std::string BoolToString(bool item)
105 {
106         if (item == true)
107                 return "true";
108         else
109                 return "false";
110 }
111
112 float RadiansToDegrees(float radians)
113 {
114         //convert from radians to degrees
115         return radians * (180 / pi);
116 }
117
118 float DegreesToRadians(float degrees)
119 {
120         //convert from degrees to radians
121         return degrees * (pi / 180);
122 }
123
124 float Min3(float a, float b, float c)
125 {
126         //return smallest value
127         if (a <= b && a <= c)
128                 return a;
129         if (b <= a && b <= c)
130                 return b;
131         return c;
132 }
133
134 float Max3(float a, float b, float c)
135 {
136         //return largest value
137         if (a >= b && a >= c)
138                 return a;
139         if (b >= a && b >= c)
140                 return b;
141         return c;
142 }
143
144 float Min4(float a, float b, float c, float d)
145 {
146         //return smallest value
147         if (a <= b && a <= c && a <= d)
148                 return a;
149         if (b <= a && b <= c && b <= d)
150                 return b;
151         if (c <= a && c <= b && c <= d)
152                 return c;
153         return d;
154 }
155
156 float Max4(float a, float b, float c, float d)
157 {
158         //return largest value
159         if (a >= b && a >= c && a >= d)
160                 return a;
161         if (b >= a && b >= c && b >= d)
162                 return b;
163         if (c >= a && c >= b && c >= d)
164                 return c;
165         return d;
166 }
167
168 std::string SetCaseCopy(std::string string, bool uppercase)
169 {
170         //change case of a string
171         SetCase(string, uppercase);
172         return string;
173 }
174
175 void SetCase(std::string &string, bool uppercase)
176 {
177         //change case of a string
178         if (uppercase == true)
179                 std::transform(string.begin(), string.end(), string.begin(), ::toupper);
180         else
181                 std::transform(string.begin(), string.end(), string.begin(), ::tolower);
182 }
183
184 int FindWithCase(const std::string &string, bool uppercase, const std::string &key, int offset)
185 {
186         //change case of a string, and return location of search key
187         std::string newstring = SetCaseCopy(string, uppercase);
188         int loc = (int)newstring.find(key, offset);
189         if (loc == std::string::npos)
190                 return -1;
191         else
192                 return loc;
193 }
194
195 void TrimString(std::string &string)
196 {
197         //trim whitespace from string
198         Ogre::StringUtil::trim(string, true, true);
199 }
200
201 std::string TrimStringCopy(std::string string)
202 {
203         //trim whitespace from string
204         Ogre::StringUtil::trim(string, true, true);
205         return string;
206 }
207
208 void ReplaceAll(std::string &string, const std::string &original, const std::string &replacement)
209 {
210         //replace all occurrences of "original" with "replacement"
211
212         size_t position = 0;
213
214         while(true)
215         {
216                 position = string.find(original, position);
217                 if (position == string.npos)
218                         break;
219                 string.replace(position, strlen(original.c_str()), replacement);
220         }
221 }
222
223 bool StartsWith(const std::string &string, const std::string &check_string, bool ignore_case)
224 {
225         //check if a string starts with the contents of "check_string"
226
227         int result;
228
229         if (ignore_case == true)
230                 result = FindWithCase(string, false, check_string, 0);
231         else
232                 result = (int)string.find(check_string, 0);
233
234         if (result == 0)
235                 return true;
236         return false;
237 }
238
239 void SplitString(std::vector<std::string> &dest_array, const std::string &original_string, char separator)
240 {
241         //split a string into an array of strings, divided by "separator"
242
243         int startpos = 0;
244         int endpos = 0;
245         std::string newstring;
246
247         dest_array.clear();
248         std::string original = original_string;
249         TrimString(original);
250
251         endpos = (int)original.find_first_of(separator, startpos);
252         if (endpos == -1)
253         {
254                 newstring = original.substr(startpos, endpos - startpos);
255                 TrimString(newstring);
256                 dest_array.push_back(newstring);
257         }
258
259         while (endpos != -1)
260         {
261                 newstring = original.substr(startpos, endpos - startpos);
262                 TrimString(newstring);
263                 dest_array.push_back(newstring); //add to vector
264                 startpos = endpos + 1; //jump past separator
265                 endpos = (int)original.find_first_of(separator, startpos); //find next
266                 if(endpos == -1)
267                 {
268                         //last one, so no 2nd param required to go to end of string
269                         newstring = original.substr(startpos);
270                         TrimString(newstring);
271                         dest_array.push_back(newstring);
272                 }
273         }
274 }
275
276 std::string ToString(int number)
277 {
278         char buffer[50];
279 #if defined(__VISUALC__)
280         _snprintf_s(buffer, sizeof(buffer), 13, "%d", number);
281 #else
282         snprintf(buffer, sizeof(buffer), "%d", number);
283 #endif
284         return buffer;
285 }
286
287 std::string ToString(float number)
288 {
289         char buffer[50];
290 #if defined(__VISUALC__)
291         _snprintf_s(buffer, sizeof(buffer), 13, "%g", number);
292 #else
293         snprintf(buffer, sizeof(buffer), "%g", (double)number);
294 #endif
295         return buffer;
296 }
297
298 std::string ToString(double number)
299 {
300         char buffer[50];
301 #if defined(__VISUALC__)
302         _snprintf_s(buffer, sizeof(buffer), 13, "%g", number);
303 #else
304         snprintf(buffer, sizeof(buffer), "%g", number);
305 #endif
306         return buffer;
307 }
308
309 float Log2(float number)
310 {
311         return logf(number) / logf(2.0f);
312 }
313
314 float Round(float number, int decimal_places)
315 {
316         //round float to specified decimal places
317
318         if (decimal_places <= 0)
319                 return floorf(number + 0.5f);
320
321         float multiplier = powf(10.0f, (float)decimal_places);
322         float rounded = floorf((number * multiplier) + 0.5f) / multiplier;
323         return rounded;
324 }
325
326 Ogre::Vector3 Round(const Ogre::Vector3 &value, int decimal_places)
327 {
328         //round a 3D vector to specified decimal places
329
330         Ogre::Vector3 result;
331         result.x = Round(value.x, decimal_places);
332         result.y = Round(value.y, decimal_places);
333         result.z = Round(value.z, decimal_places);
334         return result;
335 }
336
337 Ogre::Vector2 Round(const Ogre::Vector2 &value, int decimal_places)
338 {
339         //round a 2D vector to specified decimal places
340
341         Ogre::Vector2 result;
342         result.x = Round(value.x, decimal_places);
343         result.y = Round(value.y, decimal_places);
344         return result;
345 }
346
347 bool IsBoolean(std::string string)
348 {
349         SetCase(string, false);
350         return (string == "true" || string == "false");
351 }
352
353 float ToFloat(const std::string &string)
354 {
355         return (float)atof(string.c_str());
356 }
357
358 int ToInt(const std::string &string)
359 {
360         return atoi(string.c_str());
361 }
362
363 bool ToBool(std::string string)
364 {
365         SetCase(string, false);
366
367         if (string == "true")
368                 return true;
369         return false;
370 }
371
372 std::string TruncateNumber(float value, int decimals)
373 {
374         //truncates the numeric value to the specified number of decimal places (does not round)
375
376         if ((int)value == value)
377                 decimals = 0; //value is an integer
378
379         std::stringstream buffer;
380         buffer.precision(decimals);
381         buffer << std::fixed << value;
382
383         return buffer.str();
384 }
385
386 std::string TruncateNumber(double value, int decimals)
387 {
388         //truncates the numeric value to the specified number of decimal places (does not round)
389
390         if ((int)value == value)
391                 decimals = 0; //value is an integer
392
393         std::stringstream buffer;
394         buffer.precision(decimals);
395         buffer << std::fixed << value;
396
397         return buffer.str();
398 }
399
400 std::string TruncateNumber(const std::string &value, int decimals)
401 {
402         //truncates the numeric value to the specified number of decimal places (does not round)
403         std::string number = value;
404
405         if (decimals < 1)
406                 return number;
407         number.erase((int)number.find(".") + decimals + 1);
408         if (number.at(number.length() - 1) == '.')
409                 number = number.substr(0, number.length() - 1); //strip of extra decimal point if even
410         return number;
411 }
412
413 void Swap(int &first, int &second)
414 {
415         //swap values
416
417         int temp = first;
418         first = second;
419         second = temp;
420 }
421
422 void Swap(float &first, float &second)
423 {
424         //swap values
425
426         float temp = first;
427         first = second;
428         second = temp;
429 }
430
431 }