- Updated to the latest pwxRandom and pwxDefaultDefines. pwxRandom has an implementation of Ken Perlins Simplex Noise, which will be used to substitute (some!) usages of hi Classic Noise where appropriate, because Simplex is alot faster than Classic Noise.
- external sources are now in the folder src/extern
1.1 --- a/src/Makefile Tue Sep 29 18:04:04 2009 +0200
1.2 +++ b/src/Makefile Mon Oct 05 09:44:14 2009 +0200
1.3 @@ -54,8 +54,6 @@
1.4 game.cpp: game.h
1.5 physobj.h: main.h virtobj.h globaldata.h
1.6 player.h: main.h menu.h
1.7 -pwxRandom.h: pwxDefines.h
1.8 -pwxSinCosTables.h: pwxDefines.h
1.9 fade.cpp: globaldata.h main.h
1.10 files.cpp: player.h files.h main.h
1.11 missile.cpp: environment.h globaldata.h explosion.h missile.h decor.h tank.h
1.12 @@ -69,7 +67,7 @@
1.13 button.cpp: button.h
1.14 satellite.h: environment.h globaldata.h virtobj.h
1.15 floattext.h: virtobj.h main.h environment.h
1.16 -main.h: imagedefs.h pwxRandom.h pwxSinCosTables.h externs.h
1.17 +main.h: imagedefs.h externs.h
1.18 tank.h: physobj.h
1.19 teleport.h: main.h virtobj.h
1.20 virtobj.h: main.h player.h
2.1 --- a/src/atanks.cpp Tue Sep 29 18:04:04 2009 +0200
2.2 +++ b/src/atanks.cpp Mon Oct 05 09:44:14 2009 +0200
2.3 @@ -358,8 +358,8 @@
2.4 global->numPermanentPlayers = 0;
2.5 while (!bIsFinished && (count < max) && (bResult = popData(chArea, bIsData, ifsFile)) )
2.6 {
2.7 - if (!bIsData && streq(chArea, FILEPART_ENDSECT)) bIsFinished = true;
2.8 - else if (streq(chArea, "PermanentPlayers"))
2.9 + if (!bIsData && STREQ(chArea, FILEPART_ENDSECT)) bIsFinished = true;
2.10 + else if (STREQ(chArea, "PermanentPlayers"))
2.11 {
2.12 bResult = popData(global->numPermanentPlayers, ifsFile);
2.13 max = global->numPermanentPlayers;
2.14 @@ -372,7 +372,7 @@
2.15 exit(1);
2.16 }
2.17 }
2.18 - else if (streq(chArea, "PlayerNumber"))
2.19 + else if (STREQ(chArea, "PlayerNumber"))
2.20 {
2.21 // The first ever Entry for players is the PlayerNumber
2.22 if ( (bResult = popData(count, ifsFile)) )
2.23 @@ -3408,10 +3408,10 @@
2.24 {
2.25 while (!bIsFinished && (bResult = popData(chArea, bIsData, ifsFile)) )
2.26 {
2.27 - if (streq(chArea, FILEPART_ENDFILE)) bIsFinished = true;
2.28 - else if (streq(chArea, FILEPART_GLOBALS)) bResult = global->loadFromFile(ifsFile);
2.29 - else if (streq(chArea, FILEPART_ENVIRON)) bResult = env->loadFromFile (ifsFile);
2.30 - else if (streq(chArea, FILEPART_PLAYERS)) bResult = loadPlayers(global, env, ifsFile);
2.31 + if (STREQ(chArea, FILEPART_ENDFILE)) bIsFinished = true;
2.32 + else if (STREQ(chArea, FILEPART_GLOBALS)) bResult = global->loadFromFile(ifsFile);
2.33 + else if (STREQ(chArea, FILEPART_ENVIRON)) bResult = env->loadFromFile (ifsFile);
2.34 + else if (STREQ(chArea, FILEPART_PLAYERS)) bResult = loadPlayers(global, env, ifsFile);
2.35 }
2.36 ifsFile.close();
2.37 }
2.38 @@ -3703,17 +3703,17 @@
2.39
2.40 while (!bIsFinished && (bResult = popData(chArea, bIsData, configFile)) )
2.41 {
2.42 - if (!bIsData && streq(chArea, FILEPART_ENDFILE)) bIsFinished = true;
2.43 - else if (streq(chArea, FILEPART_GLOBALS))
2.44 + if (!bIsData && STREQ(chArea, FILEPART_ENDFILE)) bIsFinished = true;
2.45 + else if (STREQ(chArea, FILEPART_GLOBALS))
2.46 {
2.47 if (load_config_file) bResult = global->loadFromFile(configFile);
2.48 if (bResult) env = init_game_settings (global);
2.49 if ((int)global->os_mouse)
2.50 show_os_cursor(MOUSE_CURSOR_ARROW);
2.51 }
2.52 - else if (streq(chArea, FILEPART_ENVIRON) && load_config_file)
2.53 + else if (STREQ(chArea, FILEPART_ENVIRON) && load_config_file)
2.54 bResult = env->loadFromFile (configFile);
2.55 - else if (streq(chArea, FILEPART_PLAYERS)) bResult = loadPlayers (global, env, configFile);
2.56 + else if (STREQ(chArea, FILEPART_PLAYERS)) bResult = loadPlayers (global, env, configFile);
2.57 }
2.58 configFile.close();
2.59
2.60 @@ -4087,7 +4087,7 @@
2.61 if (ofsFile.is_open())
2.62 {
2.63 ofsFile << aData << endl;
2.64 - if (streq(aData, FILEPART_ENDSECT) || streq(aData, FILEPART_ENDPLYR))
2.65 + if (STREQ(aData, FILEPART_ENDSECT) || STREQ(aData, FILEPART_ENDPLYR))
2.66 ofsFile << endl; // An additional empty line makes the files mor (human) readable.
2.67 if (ofsFile.good())
2.68 bResult = true;
3.1 --- a/src/environment.cpp Tue Sep 29 18:04:04 2009 +0200
3.2 +++ b/src/environment.cpp Mon Oct 05 09:44:14 2009 +0200
3.3 @@ -181,26 +181,26 @@
3.4
3.5 while (!bIsFinished && (bResult = popData(chArea, bIsData, ifsFile)))
3.6 {
3.7 - if (!bIsData && streq(chArea, FILEPART_ENDSECT)) bIsFinished = true;
3.8 - else if (streq(chArea, "Wind Strength ")) bResult = popData(windstrength, ifsFile);
3.9 - else if (streq(chArea, "Wind Variation ")) bResult = popData(windvariation, ifsFile);
3.10 - else if (streq(chArea, "Viscosity ")) bResult = popData(viscosity, ifsFile);
3.11 - else if (streq(chArea, "Gravity ")) bResult = popData(gravity, ifsFile);
3.12 - else if (streq(chArea, "Weapon Tech Level")) bResult = popData(weapontechLevel, ifsFile);
3.13 - else if (streq(chArea, "Item Tech Level ")) bResult = popData(itemtechLevel, ifsFile);
3.14 - else if (streq(chArea, "Meteors ")) bResult = popData(meteors, ifsFile);
3.15 - else if (streq(chArea, "Lightning ")) bResult = popData(lightning, ifsFile);
3.16 - else if (streq(chArea, "Satellite ")) bResult = popData(satellite, ifsFile);
3.17 - else if (streq(chArea, "Fog ")) bResult = popData(fog, ifsFile);
3.18 - else if (streq(chArea, "Land Type ")) bResult = popData(landType, ifsFile);
3.19 - else if (streq(chArea, "Land Slide Type ")) bResult = popData(landSlideType, ifsFile);
3.20 - else if (streq(chArea, "Land Slide Delay ")) bResult = popData(landSlideDelay, ifsFile);
3.21 - else if (streq(chArea, "Falling Dirt Ball")) bResult = popData(falling_dirt_balls, ifsFile);
3.22 - else if (streq(chArea, "Wall Type ")) bResult = popData(wallType, ifsFile);
3.23 - else if (streq(chArea, "Boxed Mode ")) bResult = popData(dBoxedMode, ifsFile);
3.24 - else if (streq(chArea, "Fading Text ")) bResult = popData(dFadingText, ifsFile);
3.25 - else if (streq(chArea, "Shadowed Text ")) bResult = popData(dShadowedText, ifsFile);
3.26 - else if (streq(chArea, "Custom Background")) bResult = popData(custom_background, ifsFile);
3.27 + if (!bIsData && STREQ(chArea, FILEPART_ENDSECT)) bIsFinished = true;
3.28 + else if (STREQ(chArea, "Wind Strength ")) bResult = popData(windstrength, ifsFile);
3.29 + else if (STREQ(chArea, "Wind Variation ")) bResult = popData(windvariation, ifsFile);
3.30 + else if (STREQ(chArea, "Viscosity ")) bResult = popData(viscosity, ifsFile);
3.31 + else if (STREQ(chArea, "Gravity ")) bResult = popData(gravity, ifsFile);
3.32 + else if (STREQ(chArea, "Weapon Tech Level")) bResult = popData(weapontechLevel, ifsFile);
3.33 + else if (STREQ(chArea, "Item Tech Level ")) bResult = popData(itemtechLevel, ifsFile);
3.34 + else if (STREQ(chArea, "Meteors ")) bResult = popData(meteors, ifsFile);
3.35 + else if (STREQ(chArea, "Lightning ")) bResult = popData(lightning, ifsFile);
3.36 + else if (STREQ(chArea, "Satellite ")) bResult = popData(satellite, ifsFile);
3.37 + else if (STREQ(chArea, "Fog ")) bResult = popData(fog, ifsFile);
3.38 + else if (STREQ(chArea, "Land Type ")) bResult = popData(landType, ifsFile);
3.39 + else if (STREQ(chArea, "Land Slide Type ")) bResult = popData(landSlideType, ifsFile);
3.40 + else if (STREQ(chArea, "Land Slide Delay ")) bResult = popData(landSlideDelay, ifsFile);
3.41 + else if (STREQ(chArea, "Falling Dirt Ball")) bResult = popData(falling_dirt_balls, ifsFile);
3.42 + else if (STREQ(chArea, "Wall Type ")) bResult = popData(wallType, ifsFile);
3.43 + else if (STREQ(chArea, "Boxed Mode ")) bResult = popData(dBoxedMode, ifsFile);
3.44 + else if (STREQ(chArea, "Fading Text ")) bResult = popData(dFadingText, ifsFile);
3.45 + else if (STREQ(chArea, "Shadowed Text ")) bResult = popData(dShadowedText, ifsFile);
3.46 + else if (STREQ(chArea, "Custom Background")) bResult = popData(custom_background, ifsFile);
3.47 else if (!bIsFinished && bIsData)
3.48 bResult = popData(dData, ifsFile); // Something we do not know (any more/yet), so dump it!
3.49 }
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/src/extern/pwxDefaultDefines/defines.h Mon Oct 05 09:44:14 2009 +0200
4.3 @@ -0,0 +1,116 @@
4.4 +#ifndef _PWX_DEFINES_H_INCLUDED
4.5 +#define _PWX_DEFINES_H_INCLUDED
4.6 +
4.7 +#pragma once // some profilers and ides (eclipse cdt) need that!
4.8 +/* defines.h
4.9 + * ------------------
4.10 + * (c) 2007-2008 PrydeWorX
4.11 + * @Author: Sven Eden, PrydeWorX - Hamburg, Germany
4.12 + *
4.13 + * This file is provided as is and published under GPL license.
4.14 + * Do, whatever you feel like doeing with it, but please mention
4.15 + * me somewhere within the documentation of your project if you
4.16 + * find this usefull enough to actually use it. OpenSource4Ever!
4.17 + *
4.18 + * Documentation:
4.19 + * --------------
4.20 + * This file does only add some defines for visibilities and stuff.
4.21 + * nothing to worry about!
4.22 + *
4.23 + * History:
4.24 + * --------
4.25 + * 21.12.2007 SE, PrydeWorX First Design
4.26 + * 22.12.2007 SE, PrydeWorX initial release
4.27 + * 01.02.2008 SE, PrydeWorX added some method and function helpers
4.28 + * 14.07.2008 SE, PrydeWorX added NULL and PI
4.29 + * 21.09.2009 SE, PrydeWorX added mathematical and string helpers
4.30 + * 25.09.2009 SE, PrydeWorX added FLOOR(), CEIL(), STRCEQ() and STRCNE()
4.31 + */
4.32 +
4.33 +#define _PWXDEFINES_VERSION "1.2.1"
4.34 +
4.35 +#include <cmath>
4.36 +// #include <cstring>
4.37 +
4.38 +// Visibilities
4.39 +#ifndef _PWX_INTERNAL
4.40 +#define _PWX_INTERNAL __attribute__ ((visibility ("internal")))
4.41 +#endif // _PWX_INTERNAL
4.42 +#ifndef _PWX_VISIBLE
4.43 +#define _PWX_VISIBLE __attribute__ ((visibility ("default")))
4.44 +#endif // _PWX_VISIBLE externally_visible
4.45 +#ifndef _PWX_EXTERNVISIBLE
4.46 +#define _PWX_EXTERNVISIBLE __attribute__ ((externally_visible))
4.47 +#endif // _PWX_EXTERNVISIBLE
4.48 +
4.49 +// vars && functions
4.50 +#ifndef _PWX_VIRTUAL_PURE
4.51 +#define _PWX_VIRTUAL_PURE =0
4.52 +#endif // _PWX_VIRTUAL_PURE
4.53 +#ifndef _PWX_PURE
4.54 +#define _PWX_PURE __attribute__ ((pure))
4.55 +#endif // _PWX_PURE
4.56 +#ifndef _PWX_UNUSED
4.57 +#define _PWX_UNUSED __attribute__ ((unused))
4.58 +#endif // _PWX_UNUSED
4.59 +#ifndef _PWX_USED
4.60 +#define _PWX_USED __attribute__ ((used))
4.61 +#endif // _PWX_VAR_USED
4.62 +#ifndef _PWX_WARNUNUSED
4.63 +#define _PWX_WARNUNUSED __attribute__ ((warn_unused_result))
4.64 +#endif // _PWX_WARNUNUSED
4.65 +#ifndef _PWX_FORCEINLINE
4.66 +#define _PWX_FORCEINLINE __attribute__ ((always_inline))
4.67 +#endif // _PWX_WARNUNUSED
4.68 +
4.69 +// NULL
4.70 +#ifndef NULL
4.71 +#define NULL 0
4.72 +#endif // NULL
4.73 +
4.74 +//PI
4.75 +#ifndef PI
4.76 +#define PI 3.1415926535897932384626433832795029L
4.77 +#endif // PI
4.78 +
4.79 +// mathematical helpers
4.80 +#ifndef MIN
4.81 +#define MIN(x,y) (((x) < (y)) ? (x) : (y))
4.82 +#endif // MIN
4.83 +#ifndef MAX
4.84 +#define MAX(x,y) (((x) > (y)) ? (x) : (y))
4.85 +#endif // MAX
4.86 +#ifndef MID
4.87 +#define MID(x,y,z) MAX((x), MIN((y), (z)))
4.88 +#endif // MID
4.89 +#ifndef SIGN
4.90 +#define SIGN(x) (((x) >= 0) ? 1 : -1)
4.91 +#endif // SIGN
4.92 +#ifndef FLOOR
4.93 +#define FLOOR(x) (((x) >= 0) ? (int)(x) : (int)((x) - 1))
4.94 +#endif // FLOOR
4.95 +#ifndef CEIL
4.96 +#define CEIL(x) (((x) < 0) ? (int)(x) : (int)((x) + 1))
4.97 +#endif // CEIL
4.98 +#ifndef ABSDISTANCE
4.99 +#define ABSDISTANCE(x1,y1,x2,y2) abs((int)sqrt((double)pow(((double)x2) - ((double)x1), 2) + (double)pow(((double)y2) - ((double)y1), 2)))
4.100 +#endif // ABSDISTANCE (result is int)
4.101 +#ifndef FABSDISTANCE
4.102 +#define FABSDISTANCE(x1,y1,x2,y2) abs((double)sqrt((double)pow(((double)x2) - ((double)x1), 2) + (double)pow(((double)y2) - ((double)y1), 2)))
4.103 +#endif // FABSDISTANCE (result is double)
4.104 +
4.105 +// string helpers
4.106 +#ifndef STRCEQ
4.107 +#define STRCEQ(a,b) (strcasecmp(a,b) == 0)
4.108 +#endif // STCREQ (ignore case)
4.109 +#ifndef STRCNE
4.110 +#define STRCNE(a,b) (strcasecmp(a,b) != 0)
4.111 +#endif // STCRNE (ignore case)
4.112 +#ifndef STREQ
4.113 +#define STREQ(a,b) (strcmp(a,b) == 0)
4.114 +#endif // STREQ (case sensitive)
4.115 +#ifndef STRNE
4.116 +#define STRNE(a,b) (strcmp(a,b) != 0)
4.117 +#endif // STRNE (case sensitive)
4.118 +
4.119 +#endif // _PWX_DEFINES_H_INCLUDED
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/src/extern/pwxRandom/pwxRandom.h Mon Oct 05 09:44:14 2009 +0200
5.3 @@ -0,0 +1,996 @@
5.4 +#ifndef PWXRANDOM_H_INCLUDED
5.5 +#define PWXRANDOM_H_INCLUDED
5.6 +
5.7 +#pragma once
5.8 +/* pwxRandom.h
5.9 + * ------------------
5.10 + * (c) 2007 - 2009 PrydeWorX
5.11 + * @Author: Sven Eden, PrydeWorX - Hamburg, Germany
5.12 + *
5.13 + * This file is provided as is and published under GPL license.
5.14 + * Do, whatever you feel like doeing with it, but please mention
5.15 + * me somewhere within the documentation of your project if you
5.16 + * find this usefull enough to actually use it. OpenSource4Ever!
5.17 + *
5.18 + * History:
5.19 + * --------
5.20 + * 21.12.2007 SE, PrydeWorX First Design
5.21 + * 09.04.2008 SE, PrydeWorX initial release
5.22 + * 11.11.2008 SE, PrydeWorX added documentation and long int/double versions
5.23 + * 04.04.2009 SE, PrydeWorX forced all methods to be inlined with newer gcc
5.24 + * 31.07.2009 SE, PrydeWorX some optimizations to favour mod instead of division
5.25 + * 20.09.2009 SE, PrydeWorX restructured for a cleaner Class Body and seperate implementation
5.26 + * 21.09.2009 SE, PrydeWorX Some optimizations by using some new tools in pwxDefaultDefines
5.27 + * 22.09.2009 SE, PrydeWorX Added hash() and noise() functions
5.28 + * 23.09.2009 SE, PrydeWorX Added Simplex Noise by Ken Perlin
5.29 + * 25.09.2009 SE, PrydeWorX Simplified Simplex by using members for data instead of local vars
5.30 + * 29.09.2009 SE, PrydeWorX Optimized and tested Simplex Noise - Re-organized The Class a bit.
5.31 + * 05.10.2009 SE, PrydeWorX Refined simplex1D.
5.32 + */
5.33 +
5.34 +#include <cstdlib>
5.35 +#include <cmath>
5.36 +#include <cassert>
5.37 +#include <ctime>
5.38 +
5.39 +namespace pwx
5.40 +{
5.41 +#include "pwxDefaultDefines/defines.h"
5.42 +
5.43 +// This is a gradient tab, made to be usable for all 4 dimensional possibilities
5.44 +const int iSpxGrTab[32][4] =
5.45 +{
5.46 + { 1, 1, 0, 1}, { 1, -1, 0, 1}, {-1, 1, 0, 1}, {-1, -1, 0, 1}, // Last Index for 1D: 3 (Mod 4)
5.47 + { 0, 1, 1, 1}, { 0, -1, 1, 1}, { 1, 0, 1, 1}, {-1, 0, 1, 1}, // Last Index for 2D: 7 (Mod 8)
5.48 + { 0, 1, -1, 1}, { 0, -1, -1, 1}, { 1, 0, -1, 1}, {-1, 0, -1, 1}, // Last Index for 3D: 11 (Mod 12)
5.49 + { 1, 1, 0, -1}, {-1, 1, 0, -1}, { 1, -1, 0, -1}, {-1, -1, 0, -1}, { 0, 1, 1, -1}, { 0, -1, 1, -1},
5.50 + { 1, 0, 1, -1}, {-1, 0, 1, -1}, { 0, 1, -1, -1}, { 0, -1, -1, -1}, { 1, 0, -1, -1}, {-1, 0, -1, -1},
5.51 + { 1, 1, 1, 0}, { 1, 1, -1, 0}, { 1, -1, 1, 0}, { 1, -1, -1, 0}, {-1, 1, 1, 0}, {-1, 1, -1, 0},
5.52 + {-1, -1, 1, 0}, {-1, -1, -1, 0} // Last Index for 4D: 31 (Mod 32)
5.53 +};
5.54 +
5.55 +// This is a traversal grid for converting 4D shapes into a form that is usable
5.56 +// Many indices will never occur, since e.g. x>y>z>w makes x<z, y<w and x<w
5.57 +// impossible. Only the 24 indices which have non-zero entries make any sense.
5.58 +const int iSpxTrTab[64][4] =
5.59 +{
5.60 + {0, 1, 2, 3}, {0, 1, 3, 2}, {0, 0, 0, 0}, {0, 2, 3, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {1, 2, 3, 0},
5.61 + {0, 2, 1, 3}, {0, 0, 0, 0}, {0, 3, 1, 2}, {0, 3, 2, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {1, 3, 2, 0},
5.62 + {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
5.63 + {1, 2, 0, 3}, {0, 0, 0, 0}, {1, 3, 0, 2}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {2, 3, 0, 1}, {2, 3, 1, 0},
5.64 + {1, 0, 2, 3}, {1, 0, 3, 2}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {2, 0, 3, 1}, {0, 0, 0, 0}, {2, 1, 3, 0},
5.65 + {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
5.66 + {2, 0, 1, 3}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {3, 0, 1, 2}, {3, 0, 2, 1}, {0, 0, 0, 0}, {3, 1, 2, 0},
5.67 + {2, 1, 0, 3}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {3, 1, 0, 2}, {0, 0, 0, 0}, {3, 2, 0, 1}, {3, 2, 1, 0}
5.68 +};
5.69 +
5.70 +// These are skewing factors for 2D, 3D and 4D transformations:
5.71 +const double dSpxSkew[3][2] =
5.72 +{
5.73 + {0.36602540378443859658830206171842, 0.21132486540518713447056597942719}, // 2D
5.74 + {0.32258064516129031362723367237777, 0.16393442622950821219163231035054}, // 3D
5.75 + {0.30901699437494745126286943559535, 0.13819660112501050419631098975515} // 4D
5.76 +};
5.77 +
5.78 +/** @brief Static class to produce unique or pseudo random numbers.
5.79 + *
5.80 + * This class produces a static instance called pwx::RNG, meaning
5.81 + * "Random Number Generator" and provides the following sets of
5.82 + * functions:
5.83 + *
5.84 + * A) random()
5.85 + *
5.86 + * These return random numbers as int, long int, float, double and
5.87 + * long double, having their arguments, max for zero to max and
5.88 + * min/max for min to max values, of the same type.
5.89 + *
5.90 + * B) hash()
5.91 + * Hashing functions for integer arguments, mostly taken from:
5.92 + * http://www.burtleburtle.net/bob/hash/index.html (Robert Jenkins)
5.93 + * http://www.cris.com/~Ttwang/tech/inthash.htm (Thomas Wang)
5.94 + *
5.95 + * C) noise()
5.96 + * These are not the classic perlin noise functions, but simple
5.97 + * wrappers that transform hash() results into a -1.0 to 1.0 float
5.98 + * range.
5.99 + *
5.100 + * D) simplex()
5.101 + * This set of functions produce pseudo random numbers using
5.102 + * Simplex Noise (2D, 3D and 4D) by Ken Perlin, and are called
5.103 + * simplex().
5.104 + * http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
5.105 + * (Stefan Gustavson)
5.106 + */
5.107 +class _PWX_INTERNAL Random
5.108 +{
5.109 +
5.110 +protected:
5.111 +private:
5.112 + // --- attributes ---
5.113 + double dSpxCorn[5]; //!< The Corners contributing to a simplex noise. (1D: 2, 4D: 5 corners)#
5.114 + double dSpxDist[5][4]; //!< Simplex distance of a point to the simplex' corners
5.115 + int iLastValue; //!< The last by rand() generated value
5.116 + int iSpxGrads[5]; //!< Gradient table indices for the simplex corners
5.117 + int iSpxNorms[4]; //!< Normalized Coordinates for x, y, z, w
5.118 + int iSpxOffs[3][4]; //!< Offsets for determining which vertice a dot is in
5.119 + int iSpxPerms[4]; //!< Permutation table indices for x, y, z, w
5.120 + int iSpxSeed; //!< Simplex Noise Seed, can be changed with setSimplexSeed
5.121 + int iSpxTab[512]; //!< A permutation table for simplex noise
5.122 +
5.123 + // --- methods ---
5.124 + inline double _PWX_INTERNAL getSimpDot(int iIndex, double x) _PWX_FORCEINLINE;
5.125 + inline double _PWX_INTERNAL getSimpDot(int iIndex, double x, double y) _PWX_FORCEINLINE;
5.126 + inline double _PWX_INTERNAL getSimpDot(int iIndex, double x, double y, double z) _PWX_FORCEINLINE;
5.127 + inline double _PWX_INTERNAL getSimpDot(int iIndex, double x, double y, double z, double w) _PWX_FORCEINLINE;
5.128 + /* Note: These are four functions, because using 1 with default values would cause alot of overhead with 0
5.129 + multiplication. Testing 10M Iterations with 2 dimensions was 500ms slower with such an "universal"
5.130 + getSimpDot() method. */
5.131 +public:
5.132 + // --- ctors/dtors ---
5.133 + /** @brief default ctor
5.134 + *
5.135 + * Initializes the random number generator and assignes a first random value
5.136 + * to iLastValue. Simplex Seed and Simplex data are initialized as well.
5.137 + */
5.138 + Random(void):iLastValue(0),iSpxSeed(0)
5.139 + {
5.140 + srand(time(NULL));
5.141 + iLastValue = rand();
5.142 + setSimpSeed(time(NULL));
5.143 + for(int i = 0; i < 5; i++)
5.144 + {
5.145 + dSpxCorn[i] = 0.0;
5.146 + iSpxGrads[i] = 0;
5.147 + for(int j= 0; j < 4; j++)
5.148 + dSpxDist[i][j] = 0.0;
5.149 +
5.150 + if (i < 4)
5.151 + {
5.152 + iSpxNorms[i] = 0;
5.153 + iSpxPerms[i] = 0;
5.154 + }
5.155 +
5.156 + if (i < 3)
5.157 + {
5.158 + for(int j= 0; j < 4; j++)
5.159 + iSpxOffs[i][j] = 0;
5.160 + }
5.161 + }
5.162 + }
5.163 +
5.164 + // --- methods ---
5.165 + inline int _PWX_VISIBLE getSimpSeed() _PWX_FORCEINLINE;
5.166 + inline int _PWX_VISIBLE hash (int key) _PWX_FORCEINLINE;
5.167 + inline unsigned int _PWX_VISIBLE hash (unsigned int key) _PWX_FORCEINLINE;
5.168 + inline long int _PWX_VISIBLE hash (long int key) _PWX_FORCEINLINE;
5.169 + inline double _PWX_VISIBLE noise (int x) _PWX_FORCEINLINE;
5.170 + inline double _PWX_VISIBLE noise (int x, int y) _PWX_FORCEINLINE;
5.171 + inline double _PWX_VISIBLE noise (int x, int y, int z) _PWX_FORCEINLINE;
5.172 + inline int _PWX_VISIBLE random (int max = RAND_MAX);
5.173 + inline int _PWX_VISIBLE random (int min, int max);
5.174 + inline long int _PWX_VISIBLE random (long int max);
5.175 + inline long int _PWX_VISIBLE random (long int min, long int max);
5.176 + inline float _PWX_VISIBLE random (float max);
5.177 + inline float _PWX_VISIBLE random (float min, float max);
5.178 + inline double _PWX_VISIBLE random (double max);
5.179 + inline double _PWX_VISIBLE random (double min, double max);
5.180 + inline long double _PWX_VISIBLE random (long double max);
5.181 + inline long double _PWX_VISIBLE random (long double min, long double max);
5.182 + inline void _PWX_VISIBLE setSimpSeed(int aNewSeed) _PWX_FORCEINLINE;
5.183 + inline double _PWX_VISIBLE simplex1D (double x, double zoom = 1.0, double smooth = 1.0);
5.184 + inline double _PWX_VISIBLE simplex2D (double x, double y, double zoom = 1.0, double smooth = 1.0);
5.185 + inline double _PWX_VISIBLE simplex3D (double x, double y, double z, double zoom = 1.0, double smooth = 1.0);
5.186 + inline double _PWX_VISIBLE simplex4D (double x, double y, double z, double w, double zoom = 1.0, double smooth = 1.0);
5.187 +};
5.188 +
5.189 +
5.190 +
5.191 +/*--------------------------------------------------*/
5.192 +/* ---------------- Public Methods ---------------- */
5.193 +/*--------------------------------------------------*/
5.194 +/** @brief getSimpSeed
5.195 + *
5.196 + * @todo: document this function
5.197 + */
5.198 +int Random::getSimpSeed()
5.199 +{
5.200 + return(iSpxSeed);
5.201 +}
5.202 +
5.203 +
5.204 +
5.205 +/** @brief hash32shift
5.206 + *
5.207 + * This is hash32shift() like described by Thomas Wang, 01/2007
5.208 + */
5.209 +int Random::hash(int key)
5.210 +{
5.211 + key = (~key) + (key << 15);
5.212 + key ^= (key & 0x7fffffff) >> 12;
5.213 + key += key << 2;
5.214 + key ^= (key & 0x7fffffff) >> 4;
5.215 + key *= 2057;
5.216 + key ^= (key & 0x7fffffff) >> 16;
5.217 + return(key);
5.218 +}
5.219 +
5.220 +
5.221 +/** @brief hash
5.222 + *
5.223 + * This is hash() like described by Robert Jenkins, 6-shift version
5.224 + */
5.225 +unsigned int Random::hash(unsigned int key)
5.226 +{
5.227 + key = (key+0x7ed55d16) + (key<<12);
5.228 + key = (key^0xc761c23c) ^ (key>>19);
5.229 + key = (key+0x165667b1) + (key<<5);
5.230 + key = (key+0xd3a2646c) ^ (key<<9);
5.231 + key = (key+0xfd7046c5) + (key<<3);
5.232 + key = (key^0xb55a4f09) ^ (key>>16);
5.233 + return(key & 0x7fffffff);
5.234 +}
5.235 +
5.236 +
5.237 +/** @brief hash64shift
5.238 + *
5.239 + * This is hash64shift() like described by Thomas Wang, 01/2007
5.240 + */
5.241 +long int Random::hash(long int key)
5.242 +{
5.243 + key = (~key) + (key << 21);
5.244 + key ^= (key & 0x7fffffffffffffff) >> 24;
5.245 + key *= 265;
5.246 + key ^= (key & 0x7fffffffffffffff) >> 14;
5.247 + key *= 21;
5.248 + key ^= (key & 0x7fffffffffffffff) >> 28;
5.249 + key += key << 31;
5.250 + return(key);
5.251 +}
5.252 +
5.253 +
5.254 +/** @brief noise with one dimension
5.255 + *
5.256 + * This method converts the result of hash(x) into a -1.0 to 1.0 double!
5.257 + */
5.258 +double Random::noise(int x)
5.259 +{
5.260 + return (1.0 - ((double)((hash(x)) & 0x7fffffff) / 1073741824.0));
5.261 +}
5.262 +
5.263 +
5.264 +/** @brief noise with two dimensions
5.265 + *
5.266 + * This method converts the result of (hash(x) + hash(y)) into a -1.0 to 1.0 double!
5.267 + */
5.268 +double Random::noise(int x, int y)
5.269 +{
5.270 + return (1.0 - ((double)((hash(x) + hash(y) + 1376312589) & 0x7fffffff) / 1073741824.0));
5.271 +}
5.272 +
5.273 +
5.274 +/** @brief noise with three dimensions
5.275 + *
5.276 + * This method converts the result of (hash(x * y) + hash(z)) into a -1.0 to 1.0 double!
5.277 + */
5.278 +double Random::noise(int x, int y, int z)
5.279 +{
5.280 + return (1.0 - ((double)((hash((long int)(x * y)) + hash(z)) & 0x7fffffff) / 1073741824.0 ));
5.281 +}
5.282 +
5.283 +
5.284 +/** @brief Generate a random value of int between 0 and max.
5.285 + *
5.286 + * This is the simplest method, which, when used without an argument,
5.287 + * behaves exactly like rand() would, but ensures, that the return
5.288 + * value is another one than the one returned the last time any of
5.289 + * the random methods was used.<BR>
5.290 + *
5.291 + * if a negative max is submitted, the result will be max <= result <= 0.
5.292 + *
5.293 + * @param max Specifies the desired maximum value (default is RAND_MAX).
5.294 + * @return A random value between 0 and max.
5.295 + */
5.296 +int Random::random(int max)
5.297 +{
5.298 + if (max == 0)
5.299 + return(0);
5.300 + else
5.301 + {
5.302 + int xResult = rand();
5.303 + int xMax = abs(max); // To ensure that xMax is positive
5.304 +
5.305 + while (xResult == iLastValue)
5.306 + xResult = rand();
5.307 + iLastValue = xResult; // Last rand() result saved!
5.308 +
5.309 + if (xMax < RAND_MAX)
5.310 + // Now the result has to be recalculated into 0<=result<=max
5.311 + xResult %= xMax + 1; // + 1 to include xMax
5.312 +
5.313 + return(xResult * SIGN(max));
5.314 + }
5.315 +}
5.316 +
5.317 +
5.318 +/** @brief Generate a random value of int between min and max.
5.319 + *
5.320 + * This method returns a value between min and max if either
5.321 + * min < max, or max is negative and max < min.<BR>
5.322 + * if a negative max is submitted, the result will be max <= result <= min.
5.323 + * This might be looking odd, but min <= result <= max with negative min and
5.324 + * max is possible, too. It is just a convenience.
5.325 + *
5.326 + * @param min Specifies the desired minimum value.
5.327 + * @param max Specifies the desired maximum value.
5.328 + * @return A random value between 0 and max.
5.329 + */
5.330 +int Random::random(int min, int max)
5.331 +{
5.332 + if (max == min)
5.333 + return(max);
5.334 + else
5.335 + {
5.336 + int xMin = MIN(min, max);
5.337 +
5.338 + // As the result is an int, we can use random()
5.339 + return (random(MAX(min, max) - xMin) + xMin);
5.340 + }
5.341 +}
5.342 +
5.343 +/** @brief Generate a random value of long int between 0 and max.
5.344 + *
5.345 + * This one should be used with care! As rand() returns values between
5.346 + * 0 and the maximum number an int can hold, recalculating the result
5.347 + * into a long int with a maximum higher than INT_MAX *will* eliminate
5.348 + * various numbers which can not be returned.<BR>
5.349 + * Example:<BR>
5.350 + * If you get a random number between 0 and 10, and then recalculate it
5.351 + * to be between 0 and 20, all odd numbers will be eliminated. So your
5.352 + * result *will* be even, no matter what you try!
5.353 + *
5.354 + * @param max Specifies the desired maximum value.
5.355 + * @return A random value between 0 and max.
5.356 + */
5.357 +long int Random::random(long int max)
5.358 +{
5.359 + if (max == 0)
5.360 + return(0);
5.361 + else
5.362 + {
5.363 + /* There are two possibilities:
5.364 + * 1.: max <= RAND_MAX
5.365 + * Then just return the result of the integer version.
5.366 + * 2.: max > RAND_MAX
5.367 + * Return the result of the integer version, multiplied by
5.368 + * the difference factor between max and RAND_MAX
5.369 + */
5.370 + if (abs(max) <= RAND_MAX)
5.371 + // First Situation:
5.372 + return((long int)random((int)max));
5.373 + else
5.374 + {
5.375 + // Second Situation:
5.376 + long int xResult = (long int)random();
5.377 + long double xFactor = abs((long double)max / (long double)RAND_MAX);
5.378 + return((long int)round(xResult * xFactor * SIGN(max)));
5.379 + }
5.380 + }
5.381 +}
5.382 +
5.383 +/** @brief Generate a random value of long int between min and max.
5.384 + *
5.385 + * Use this method if you need a random value between min and max,
5.386 + * but have a max that is larger than INT_MAX.
5.387 + *
5.388 + * @param min Specifies the desired minimum value.
5.389 + * @param max Specifies the desired maximum value.
5.390 + * @return A random value between min and max.
5.391 + */
5.392 +long int Random::random(long int min, long int max)
5.393 +{
5.394 + if (max == min)
5.395 + return(max);
5.396 + else
5.397 + {
5.398 + long int xMin = MIN(min, max);
5.399 + long int xMax = MAX(min, max);
5.400 +
5.401 + // Can we use random(max) ?
5.402 + if (xMin == 0L)
5.403 + return(xMax);
5.404 + // Can we use random(min) ?
5.405 + else if (xMax == 0L)
5.406 + return(xMin);
5.407 + else
5.408 + return(random(xMax - xMin) + xMin);
5.409 + }
5.410 +}
5.411 +
5.412 +/** @brief Generate a random value of float between 0 and max.
5.413 + *
5.414 + * @param max Specifies the desired maximum value.
5.415 + * @return A random value between 0 and max.
5.416 + */
5.417 +float Random::random(float max)
5.418 +{
5.419 + if (max == 0.0)
5.420 + return(0.0);
5.421 + else
5.422 + {
5.423 + int iRand = random();
5.424 + return(max * (float)((float)iRand / (float)RAND_MAX));
5.425 + }
5.426 +}
5.427 +
5.428 +/** @brief Generate a random value of float between min and max.
5.429 + *
5.430 + * @param min Specifies the desired minimum value.
5.431 + * @param max Specifies the desired maximum value.
5.432 + * @return A random value between min and max.
5.433 + */
5.434 +float Random::random(float min, float max)
5.435 +{
5.436 + if (max == min)
5.437 + return(max);
5.438 + else
5.439 + {
5.440 + float xMin = MIN(min, max);
5.441 + float xMax = MAX(min, max);
5.442 +
5.443 + // Can we use random(float max) ?
5.444 + if (xMin == 0.0)
5.445 + return(random(xMax));
5.446 + // Can we use random(float min ?
5.447 + else if (xMax == 0.0)
5.448 + return(random(xMin));
5.449 + else
5.450 + return (random(xMax - xMin) + xMin);
5.451 + }
5.452 +}
5.453 +
5.454 +/** @brief Generate a random value of double between 0 and max.
5.455 + *
5.456 + * @param max Specifies the desired maximum value.
5.457 + * @return A random value between 0 and max.
5.458 + */
5.459 +double Random::random(double max)
5.460 +{
5.461 + if (max == 0.0)
5.462 + return(0.0);
5.463 + else
5.464 + {
5.465 + int iRand = random();
5.466 + return(max * (double)((double)iRand / (double)RAND_MAX));
5.467 + }
5.468 +}
5.469 +
5.470 +/** @brief Generate a random value of double between min and max.
5.471 + *
5.472 + * @param min Specifies the desired minimum value.
5.473 + * @param max Specifies the desired maximum value.
5.474 + * @return A random value between min and max.
5.475 + */
5.476 +double Random::random(double min, double max)
5.477 +{
5.478 + if (max == min)
5.479 + return(max);
5.480 + else
5.481 + {
5.482 + double xMin = MIN(min, max);
5.483 + double xMax = MAX(min, max);
5.484 +
5.485 + // Can we use random(double max) ?
5.486 + if (xMin == 0.0)
5.487 + return(random(xMax));
5.488 + // Can we use random(double min ?
5.489 + else if (xMax == 0.0)
5.490 + return(random(xMin));
5.491 + else
5.492 + return (random(xMax - xMin) + xMin);
5.493 + }
5.494 +}
5.495 +
5.496 +/** @brief Generate a random value of long double between 0 and max.
5.497 + *
5.498 + * @param max Specifies the desired maximum value.
5.499 + * @return A random value between 0 and max.
5.500 + */
5.501 +long double Random::random(long double max)
5.502 +{
5.503 + if (max == 0.0)
5.504 + return(max);
5.505 + else
5.506 + {
5.507 + int iRand = random();
5.508 + return(max * (long double)((long double)iRand / (long double)RAND_MAX));
5.509 + }
5.510 +}
5.511 +
5.512 +/** @brief Generate a random value of long double between min and max.
5.513 + *
5.514 + * @param min Specifies the desired minimum value.
5.515 + * @param max Specifies the desired maximum value.
5.516 + * @return A randomvalue between min and max.
5.517 + */
5.518 +long double Random::random(long double min, long double max)
5.519 +{
5.520 + if (max == min)
5.521 + return(max);
5.522 + else
5.523 + {
5.524 + long double xMin = MIN(min, max);
5.525 + long double xMax = MAX(min, max);
5.526 +
5.527 + // Can we use random(long double max) ?
5.528 + if (xMin == 0.0)
5.529 + return(random(xMax));
5.530 + // Can we use random(long double min ?
5.531 + else if (xMax == 0.0)
5.532 + return(random(xMin));
5.533 + else
5.534 + return (random(xMax - xMin) + xMin);
5.535 + }
5.536 +}
5.537 +
5.538 +
5.539 +/** @brief set Simplex Seed
5.540 + *
5.541 + * Set a new simplex seed which will cause the simplex table to be
5.542 + * reinitialized.
5.543 + */
5.544 +void Random::setSimpSeed(int aNewSeed)
5.545 +{
5.546 + aNewSeed &= 0x00ffffff;
5.547 + if (aNewSeed != iSpxSeed)
5.548 + {
5.549 + iSpxSeed = aNewSeed;
5.550 + for (int i = 0; i < 256; i++)
5.551 + {
5.552 + iSpxTab[i] = abs(hash(iSpxSeed + i)) % 255;
5.553 + iSpxTab[i + 256] = iSpxTab[i];
5.554 + }
5.555 + }
5.556 +}
5.557 +
5.558 +
5.559 +/** @brief simplex noise 1D
5.560 + *
5.561 + * Simplex noise for one dimensions This method is influenced by
5.562 + * iSpxSeed and the return value is a noise value between -1.0 and 1.0
5.563 + *
5.564 + * @param x X-Coordinate of the simplex point
5.565 + * @param zoom Scales the coordinates, making them zoom into or out of the grid. Defaults to 1.0
5.566 + * @param smooth The higher this value, the flatter the result towards 0.0 from both sides. Defaults to a minimum of 1.0
5.567 + * @return Noise value between -1.0 and 1.0
5.568 + */
5.569 +double Random::simplex1D(double x, double zoom, double smooth)
5.570 +{
5.571 + double dContrib;
5.572 +
5.573 + // Apply seed
5.574 + x = (x / zoom) + iSpxSeed;
5.575 +
5.576 + // Be sure smooth is sane:
5.577 + if (smooth < 1.0) smooth = 1.0;
5.578 +
5.579 +
5.580 + iSpxNorms[0] = FLOOR(x); // Normalized X-Coordinate
5.581 + iSpxPerms[0] = iSpxNorms[0] & 0x000000ff; // X-Coordinate factor for Permutation Table
5.582 +
5.583 + // Distances from left and right edge
5.584 + dSpxDist[0][0] = x - iSpxNorms[0];
5.585 + dSpxDist[1][0] = 1.0 - dSpxDist[0][0];
5.586 +
5.587 + // Permutated numbers, normalized to a range of 0 to 3
5.588 + iSpxGrads[0] = iSpxTab[iSpxPerms[0]] % 4;
5.589 + iSpxGrads[1] = iSpxTab[iSpxPerms[0] + 1] % 4;
5.590 +
5.591 + // Calculate the contribution from the two edges
5.592 + dContrib = 0.75 - pow(dSpxDist[0][0], 2);
5.593 + dSpxCorn[0] = (dContrib > 0.0) ? pow(dContrib, 4) * getSimpDot(iSpxGrads[0], noise(x)) : 0.0;
5.594 + dContrib = 0.75 - pow(dSpxDist[1][0], 2);
5.595 + dSpxCorn[1] = (dContrib > 0.0) ? pow(dContrib, 4) * getSimpDot(iSpxGrads[1], noise(x + 1)) : 0.0;
5.596 +
5.597 +
5.598 + // Add contributions from each corner to get the final noise value.
5.599 + // The result is a value in the interval [-1,1].
5.600 + return(3.16049383304737219191338226664811 * (dSpxCorn[0] + dSpxCorn[1]) / smooth);
5.601 + // Note: This factor has been found by searching the factor needed
5.602 + // To get 1.0 with the largest result out of 100M iterations
5.603 +}
5.604 +
5.605 +
5.606 +/** @brief simplex noise 2D
5.607 + *
5.608 + * Simplex noise for two dimensions. This method is influenced by
5.609 + * iSpxSeed and the return value is a noise value between -1.0 and 1.0
5.610 + *
5.611 + * @param x X-Coordinate of the simplex point
5.612 + * @param y Y-Coordinate of the simplex point
5.613 + * @param zoom Scales the coordinates, making them zoom into or out of the grid. Defaults to 1.0
5.614 + * @param smooth The higher this value, the flatter the result towards 0.0 from both sides. Defaults to a minimum of 1.0
5.615 + * @return Noise value between -1.0 and 1.0
5.616 + */
5.617 +double Random::simplex2D(double x, double y, double zoom, double smooth)
5.618 +{
5.619 + double dContrib;
5.620 +
5.621 + // Apply Seed:
5.622 + x = (x / zoom) + iSpxSeed;
5.623 + y = (y / zoom) + iSpxSeed;
5.624 +
5.625 + // Be sure smooth is sane:
5.626 + if (smooth < 1.0) smooth = 1.0;
5.627 +
5.628 + dContrib = x + ((x + y) * dSpxSkew[0][0]);
5.629 + iSpxNorms[0] = FLOOR(dContrib); // Normalized X-Coordinate
5.630 + dContrib = y + ((x + y) * dSpxSkew[0][0]);
5.631 + iSpxNorms[1] = FLOOR(dContrib); // Normalized Y-Coordinate
5.632 + iSpxPerms[0] = iSpxNorms[0] & 0x000000ff; // X-Coordinate factor for Permutation Table
5.633 + iSpxPerms[1] = iSpxNorms[1] & 0x000000ff; // Y-Coordinate factor for Permutation Table
5.634 +
5.635 + // Distances from corners, middle and last corner are filled when offsets are clear
5.636 + dSpxDist[0][0] = x - (iSpxNorms[0] - ((iSpxNorms[0] + iSpxNorms[1]) * dSpxSkew[0][1]));
5.637 + dSpxDist[0][1] = y - (iSpxNorms[1] - ((iSpxNorms[0] + iSpxNorms[1]) * dSpxSkew[0][1]));
5.638 +
5.639 + iSpxOffs[0][0] = (dSpxDist[0][0] > dSpxDist[0][1]) ? 1 : 0; // Upper triangle (1, 0),
5.640 + iSpxOffs[0][1] = (dSpxDist[0][0] > dSpxDist[0][1]) ? 0 : 1; // Lower triangle (0, 1).
5.641 +
5.642 + // Distance from middle corner
5.643 + dSpxDist[1][0] = dSpxDist[0][0] - iSpxOffs[0][0] + dSpxSkew[0][1];
5.644 + dSpxDist[1][1] = dSpxDist[0][1] - iSpxOffs[0][1] + dSpxSkew[0][1];
5.645 +
5.646 + // Distance from last corner
5.647 + dSpxDist[2][0] = dSpxDist[0][0] - 1.0 + (2.0 * dSpxSkew[0][1]);
5.648 + dSpxDist[2][1] = dSpxDist[0][1] - 1.0 + (2.0 * dSpxSkew[0][1]);
5.649 +
5.650 + // Permutated numbers, normalized to a range of 0 to 7
5.651 + iSpxGrads[0] = iSpxTab[iSpxPerms[0] + iSpxTab[iSpxPerms[1]]] % 8;
5.652 + iSpxGrads[1] = iSpxTab[iSpxPerms[0] + iSpxOffs[0][0] + iSpxTab[iSpxPerms[1] + iSpxOffs[0][1]]] % 8;
5.653 + iSpxGrads[2] = iSpxTab[iSpxPerms[0] + 1 + iSpxTab[iSpxPerms[1] + 1]] % 8;
5.654 +
5.655 + // Calculate the contribution from the three corners
5.656 + dContrib = 0.5 - pow(dSpxDist[0][0], 2) - pow(dSpxDist[0][1], 2);
5.657 + dSpxCorn[0] = (dContrib > 0.0) ? pow(dContrib, 4) * getSimpDot(iSpxGrads[0], dSpxDist[0][0], dSpxDist[0][1]) : 0.0;
5.658 + dContrib = 0.5 - pow(dSpxDist[1][0], 2) - pow(dSpxDist[1][1], 2);
5.659 + dSpxCorn[1] = (dContrib > 0.0) ? pow(dContrib, 4) * getSimpDot(iSpxGrads[1], dSpxDist[1][0], dSpxDist[1][1]) : 0.0;
5.660 + dContrib = 0.5 - pow(dSpxDist[2][0], 2) - pow(dSpxDist[2][1], 2);
5.661 + dSpxCorn[2] = (dContrib > 0.0) ? pow(dContrib, 4) * getSimpDot(iSpxGrads[2], dSpxDist[2][0], dSpxDist[2][1]) : 0.0;
5.662 + // Note: This is not looped, because the loop would produce more overhead than it is worth to just have 3 less lines.
5.663 +
5.664 + // Add contributions from each corner to get the final noise value.
5.665 + // The result is scaled to return values in the interval [-1,1].
5.666 + return((70.14805770653948968629 * (dSpxCorn[0] + dSpxCorn[1] + dSpxCorn[2])) / smooth);
5.667 + // Note: This factor has been found by searching the factor needed
5.668 + // To get 1.0 with the largest result out of 100M iterations
5.669 +}
5.670 +
5.671 +
5.672 +/** @brief simplex noise 3D
5.673 + *
5.674 + * Simplex noise for three dimensions. This method is influenced by
5.675 + * iSpxSeed and the return value is a noise value between -1.0 and 1.0
5.676 + *
5.677 + * @param x X-Coordinate of the simplex point
5.678 + * @param y Y-Coordinate of the simplex point
5.679 + * @param z Z-Coordinate of the simplex point
5.680 + * @param zoom Scales the coordinates, making them zoom into or out of the grid. Defaults to 1.0
5.681 + * @param smooth The higher this value, the flatter the result towards 0.0 from both sides. Defaults to a minimum of 1.0
5.682 + * @return Noise value between -1.0 and 1.0
5.683 + */
5.684 +double Random::simplex3D(double x, double y, double z, double zoom, double smooth)
5.685 +{
5.686 + double dContrib;
5.687 +
5.688 + // Apply Seed:
5.689 + x = (x / zoom) + iSpxSeed;
5.690 + y = (y / zoom) + iSpxSeed;
5.691 + z = (z / zoom) + iSpxSeed;
5.692 +
5.693 + // Be sure smooth is sane:
5.694 + if (smooth < 1.0) smooth = 1.0;
5.695 +
5.696 + dContrib = x + ((x + y + z) * dSpxSkew[1][0]);
5.697 + iSpxNorms[0] = FLOOR(dContrib); // Normalized X-Coordinate
5.698 + dContrib = y + ((x + y + z) * dSpxSkew[1][0]);
5.699 + iSpxNorms[1] = FLOOR(dContrib); // Normalized Y-Coordinate
5.700 + dContrib = z + ((x + y + z) * dSpxSkew[1][0]);
5.701 + iSpxNorms[2] = FLOOR(dContrib); // Normalized Z-Coordinate
5.702 + iSpxPerms[0] = iSpxNorms[0] & 0x000000ff; // X-Coordinate factor for Permutation Table
5.703 + iSpxPerms[1] = iSpxNorms[1] & 0x000000ff; // Y-Coordinate factor for Permutation Table
5.704 + iSpxPerms[2] = iSpxNorms[2] & 0x000000ff; // Z-Coordinate factor for Permutation Table
5.705 +
5.706 + // Distances from corners, second, third and last corner are filled when offsets are clear
5.707 + dSpxDist[0][0] = x - (iSpxNorms[0] - ((iSpxNorms[0] + iSpxNorms[1] + iSpxNorms[2]) * dSpxSkew[1][1]));
5.708 + dSpxDist[0][1] = y - (iSpxNorms[1] - ((iSpxNorms[0] + iSpxNorms[1] + iSpxNorms[2]) * dSpxSkew[1][1]));
5.709 + dSpxDist[0][2] = z - (iSpxNorms[2] - ((iSpxNorms[0] + iSpxNorms[1] + iSpxNorms[2]) * dSpxSkew[1][1]));
5.710 +
5.711 + // For the 3D case, the simplex shape is a slightly irregular tetrahedron.
5.712 + // Determine which simplex we are in.
5.713 + if (dSpxDist[0][0] >= dSpxDist[0][1])
5.714 + {
5.715 + if (dSpxDist[0][1] >= dSpxDist[0][2])
5.716 + {
5.717 + // X Y Z order
5.718 + iSpxOffs[0][0] = 1;
5.719 + iSpxOffs[0][1] = 0;
5.720 + iSpxOffs[0][2] = 0;
5.721 + iSpxOffs[1][0] = 1;
5.722 + iSpxOffs[1][1] = 1;
5.723 + iSpxOffs[1][2] = 0;
5.724 + }
5.725 + else if (dSpxDist[0][0] >= dSpxDist[0][2])
5.726 + {
5.727 + // X Z Y order
5.728 + iSpxOffs[0][0] = 1;
5.729 + iSpxOffs[0][1] = 0;
5.730 + iSpxOffs[0][2] = 0;
5.731 + iSpxOffs[1][0] = 1;
5.732 + iSpxOffs[1][1] = 0;
5.733 + iSpxOffs[1][2] = 1;
5.734 + }
5.735 + else
5.736 + {
5.737 + // Z X Y order
5.738 + iSpxOffs[0][0] = 0;
5.739 + iSpxOffs[0][1] = 0;
5.740 + iSpxOffs[0][2] = 1;
5.741 + iSpxOffs[1][0] = 1;
5.742 + iSpxOffs[1][1] = 0;
5.743 + iSpxOffs[1][2] = 1;
5.744 + }
5.745 + }
5.746 + else // dSpxDist[0][0] < dSpxDist[0][1]
5.747 + {
5.748 + if (dSpxDist[0][1] < dSpxDist[0][2])
5.749 + {
5.750 + // Z Y X order
5.751 + iSpxOffs[0][0] = 0;
5.752 + iSpxOffs[0][1] = 0;
5.753 + iSpxOffs[0][2] = 1;
5.754 + iSpxOffs[1][0] = 0;
5.755 + iSpxOffs[1][1] = 1;
5.756 + iSpxOffs[1][2] = 1;
5.757 + }
5.758 + else if (dSpxDist[0][0] < dSpxDist[0][2])
5.759 + {
5.760 + // Y Z X order
5.761 + iSpxOffs[0][0] = 0;
5.762 + iSpxOffs[0][1] = 1;
5.763 + iSpxOffs[0][2] = 0;
5.764 + iSpxOffs[1][0] = 0;
5.765 + iSpxOffs[1][1] = 1;
5.766 + iSpxOffs[1][2] = 1;
5.767 + }
5.768 + else
5.769 + {
5.770 + // Y X Z order
5.771 + iSpxOffs[0][0] = 0;
5.772 + iSpxOffs[0][1] = 1;
5.773 + iSpxOffs[0][2] = 0;
5.774 + iSpxOffs[1][0] = 1;
5.775 + iSpxOffs[1][1] = 1;
5.776 + iSpxOffs[1][2] = 0;
5.777 + }
5.778 + }
5.779 +
5.780 + // Distance from second corner
5.781 + dSpxDist[1][0] = dSpxDist[0][0] - iSpxOffs[0][0] + dSpxSkew[1][1];
5.782 + dSpxDist[1][1] = dSpxDist[0][1] - iSpxOffs[0][1] + dSpxSkew[1][1];
5.783 + dSpxDist[1][2] = dSpxDist[0][2] - iSpxOffs[0][2] + dSpxSkew[1][1];
5.784 +
5.785 + // Distance from third corner
5.786 + dSpxDist[2][0] = dSpxDist[0][0] - iSpxOffs[1][0] + (2.0 * dSpxSkew[1][1]);
5.787 + dSpxDist[2][1] = dSpxDist[0][1] - iSpxOffs[1][1] + (2.0 * dSpxSkew[1][1]);
5.788 + dSpxDist[2][2] = dSpxDist[0][2] - iSpxOffs[1][2] + (2.0 * dSpxSkew[1][1]);
5.789 +
5.790 + // Distance from last corner
5.791 + dSpxDist[3][0] = dSpxDist[0][0] - 1.0 + (3.0 * dSpxSkew[1][1]);
5.792 + dSpxDist[3][1] = dSpxDist[0][1] - 1.0 + (3.0 * dSpxSkew[1][1]);
5.793 + dSpxDist[3][2] = dSpxDist[0][2] - 1.0 + (3.0 * dSpxSkew[1][1]);
5.794 +
5.795 + // Permutated numbers, normalized to a range of 0 to 11
5.796 + iSpxGrads[0] = iSpxTab[iSpxPerms[0] + iSpxTab[iSpxPerms[1] + iSpxTab[iSpxPerms[2]]]] % 12;
5.797 + iSpxGrads[1] = iSpxTab[iSpxPerms[0] + iSpxTab[iSpxPerms[1] + iSpxTab[iSpxPerms[2] + iSpxOffs[0][2]] + iSpxOffs[0][1]] + iSpxOffs[0][0]] % 12;
5.798 + iSpxGrads[2] = iSpxTab[iSpxPerms[0] + iSpxTab[iSpxPerms[1] + iSpxTab[iSpxPerms[2] + iSpxOffs[1][2]] + iSpxOffs[1][1]] + iSpxOffs[1][0]] % 12;
5.799 + iSpxGrads[3] = iSpxTab[iSpxPerms[0] + iSpxTab[iSpxPerms[1] + iSpxTab[iSpxPerms[2] + 1] + 1] + 1] % 12;
5.800 +
5.801 + // Calculate the contribution from the four corners
5.802 + dContrib = 0.6 - pow(dSpxDist[0][0], 2) - pow(dSpxDist[0][1], 2) - pow(dSpxDist[0][2], 2);
5.803 + dSpxCorn[0] = (dContrib > 0.0) ? pow(dContrib, 4) * getSimpDot(iSpxGrads[0], dSpxDist[0][0], dSpxDist[0][1], dSpxDist[0][2]) : 0.0;
5.804 + dContrib = 0.6 - pow(dSpxDist[1][0], 2) - pow(dSpxDist[1][1], 2) - pow(dSpxDist[1][2], 2);
5.805 + dSpxCorn[1] = (dContrib > 0.0) ? pow(dContrib, 4) * getSimpDot(iSpxGrads[1], dSpxDist[1][0], dSpxDist[1][1], dSpxDist[1][2]) : 0.0;
5.806 + dContrib = 0.6 - pow(dSpxDist[2][0], 2) - pow(dSpxDist[2][1], 2) - pow(dSpxDist[2][2], 2);
5.807 + dSpxCorn[2] = (dContrib > 0.0) ? pow(dContrib, 4) * getSimpDot(iSpxGrads[2], dSpxDist[2][0], dSpxDist[2][1], dSpxDist[2][2]) : 0.0;
5.808 + dContrib = 0.6 - pow(dSpxDist[3][0], 2) - pow(dSpxDist[3][1], 2) - pow(dSpxDist[3][2], 2);
5.809 + dSpxCorn[3] = (dContrib > 0.0) ? pow(dContrib, 4) * getSimpDot(iSpxGrads[3], dSpxDist[3][0], dSpxDist[3][1], dSpxDist[3][2]) : 0.0;
5.810 +
5.811 + // Add contributions from each corner to get the final noise value.
5.812 + // The result is scaled to return values in the interval [-1,1].
5.813 + return((36.11293688087369702088 * (dSpxCorn[0] + dSpxCorn[1] + dSpxCorn[2] + dSpxCorn[3])) / smooth);
5.814 + // Note: This factor has been found by searching the factor needed
5.815 + // To get 1.0 with the largest result out of 100M iterations
5.816 +}
5.817 +
5.818 +
5.819 +/** @brief simplex noise 4D
5.820 + *
5.821 + * Simplex noise for four dimensions. This method is influenced by
5.822 + * iSpxSeed and the return value is a noise value between -1.0 and 1.0
5.823 + *
5.824 + * @param x X-Coordinate of the simplex point
5.825 + * @param y Y-Coordinate of the simplex point
5.826 + * @param z Z-Coordinate of the simplex point
5.827 + * @param w W-Coordinate of the simplex point
5.828 + * @param zoom Scales the coordinates, making them zoom into or out of the grid. Defaults to 1.0
5.829 + * @param smooth The higher this value, the flatter the result towards 0.0 from both sides. Defaults to a minimum of 1.0
5.830 + * @return Noise value between -1.0 and 1.0
5.831 + */
5.832 +double Random::simplex4D(double x, double y, double z, double w, double zoom, double smooth)
5.833 +{
5.834 + double dContrib;
5.835 + int iTraverse;
5.836 +
5.837 + // Apply Seed:
5.838 + x = (x / zoom) + iSpxSeed;
5.839 + y = (y / zoom) + iSpxSeed;
5.840 + z = (z / zoom) + iSpxSeed;
5.841 + w = (w / zoom) + iSpxSeed;
5.842 +
5.843 + // Be sure smooth is sane:
5.844 + if (smooth < 1.0) smooth = 1.0;
5.845 +
5.846 + dContrib = x + ((x + y + z + w) * dSpxSkew[2][0]);
5.847 + iSpxNorms[0] = FLOOR(dContrib); // Normalized X-Coordinate
5.848 + dContrib = y + ((x + y + z + w) * dSpxSkew[2][0]);
5.849 + iSpxNorms[1] = FLOOR(dContrib); // Normalized X-Coordinate
5.850 + dContrib = z + ((x + y + z + w) * dSpxSkew[2][0]);
5.851 + iSpxNorms[2] = FLOOR(dContrib); // Normalized X-Coordinate
5.852 + dContrib = w + ((x + y + z + w) * dSpxSkew[2][0]);
5.853 + iSpxNorms[3] = FLOOR(dContrib); // Normalized X-Coordinate
5.854 +
5.855 + iSpxPerms[0] = iSpxNorms[0] & 0x000000ff; // X-Coordinate factor for Permutation Table
5.856 + iSpxPerms[1] = iSpxNorms[1] & 0x000000ff; // Y-Coordinate factor for Permutation Table
5.857 + iSpxPerms[2] = iSpxNorms[2] & 0x000000ff; // Z-Coordinate factor for Permutation Table
5.858 + iSpxPerms[3] = iSpxNorms[3] & 0x000000ff; // W-Coordinate factor for Permutation Table
5.859 +
5.860 + // Distances from corners, second, third and last corner are filled when offsets are clear
5.861 + dSpxDist[0][0] = x - (iSpxNorms[0] - ((iSpxNorms[0] + iSpxNorms[1] + iSpxNorms[2] + iSpxNorms[3]) * dSpxSkew[2][1]));
5.862 + dSpxDist[0][1] = y - (iSpxNorms[1] - ((iSpxNorms[0] + iSpxNorms[1] + iSpxNorms[2] + iSpxNorms[3]) * dSpxSkew[2][1]));
5.863 + dSpxDist[0][2] = z - (iSpxNorms[2] - ((iSpxNorms[0] + iSpxNorms[1] + iSpxNorms[2] + iSpxNorms[3]) * dSpxSkew[2][1]));
5.864 + dSpxDist[0][3] = w - (iSpxNorms[3] - ((iSpxNorms[0] + iSpxNorms[1] + iSpxNorms[2] + iSpxNorms[3]) * dSpxSkew[2][1]));
5.865 +
5.866 + // For the 4D case, the simplex is a 4D shape.
5.867 + // The method below is a good way of finding the ordering of x,y,z,w and
5.868 + // then find the correct traversal order for the simplex we’re in.
5.869 + // First, six pair-wise comparisons are performed between each possible pair
5.870 + // of the four coordinates, and the results are used to add up binary bits
5.871 + // for an integer index.
5.872 + iTraverse = ((dSpxDist[0][0] > dSpxDist[0][1]) ? 32 : 0)
5.873 + + ((dSpxDist[0][0] > dSpxDist[0][2]) ? 16 : 0)
5.874 + + ((dSpxDist[0][1] > dSpxDist[0][2]) ? 8 : 0)
5.875 + + ((dSpxDist[0][0] > dSpxDist[0][3]) ? 4 : 0)
5.876 + + ((dSpxDist[0][1] > dSpxDist[0][3]) ? 2 : 0)
5.877 + + ((dSpxDist[0][2] > dSpxDist[0][3]) ? 1 : 0);
5.878 +
5.879 + // Now we can use iSpxTrTab to set the coordinates in turn from the largest magnitude.
5.880 + // The number 3 is at the position of the largest coordinate.
5.881 + iSpxOffs[0][0] = iSpxTrTab[iTraverse][0]>=3 ? 1 : 0;
5.882 + iSpxOffs[0][1] = iSpxTrTab[iTraverse][1]>=3 ? 1 : 0;
5.883 + iSpxOffs[0][2] = iSpxTrTab[iTraverse][2]>=3 ? 1 : 0;
5.884 + iSpxOffs[0][3] = iSpxTrTab[iTraverse][3]>=3 ? 1 : 0;
5.885 + // The number 2 is at the second largest coordinate.
5.886 + iSpxOffs[1][0] = iSpxTrTab[iTraverse][0]>=2 ? 1 : 0;
5.887 + iSpxOffs[1][1] = iSpxTrTab[iTraverse][1]>=2 ? 1 : 0;
5.888 + iSpxOffs[1][2] = iSpxTrTab[iTraverse][2]>=2 ? 1 : 0;
5.889 + iSpxOffs[1][3] = iSpxTrTab[iTraverse][3]>=2 ? 1 : 0;
5.890 + // The number 1 is at the second smallest coordinate.
5.891 + iSpxOffs[2][0] = iSpxTrTab[iTraverse][0]>=1 ? 1 : 0;
5.892 + iSpxOffs[2][1] = iSpxTrTab[iTraverse][1]>=1 ? 1 : 0;
5.893 + iSpxOffs[2][2] = iSpxTrTab[iTraverse][2]>=1 ? 1 : 0;
5.894 + iSpxOffs[2][3] = iSpxTrTab[iTraverse][3]>=1 ? 1 : 0;
5.895 + // The fifth corner has all coordinate offsets = 1, so no need to look that up.
5.896 +
5.897 + // Distance from second corner
5.898 + dSpxDist[1][0] = dSpxDist[0][0] - iSpxOffs[0][0] + dSpxSkew[2][1];
5.899 + dSpxDist[1][1] = dSpxDist[0][1] - iSpxOffs[0][1] + dSpxSkew[2][1];
5.900 + dSpxDist[1][2] = dSpxDist[0][2] - iSpxOffs[0][2] + dSpxSkew[2][1];
5.901 + dSpxDist[1][3] = dSpxDist[0][3] - iSpxOffs[0][3] + dSpxSkew[2][1];
5.902 +
5.903 + // Distance from third corner
5.904 + dSpxDist[2][0] = dSpxDist[0][0] - iSpxOffs[1][0] + (2.0 * dSpxSkew[2][1]);
5.905 + dSpxDist[2][1] = dSpxDist[0][1] - iSpxOffs[1][1] + (2.0 * dSpxSkew[2][1]);
5.906 + dSpxDist[2][2] = dSpxDist[0][2] - iSpxOffs[1][2] + (2.0 * dSpxSkew[2][1]);
5.907 + dSpxDist[2][3] = dSpxDist[0][3] - iSpxOffs[1][3] + (2.0 * dSpxSkew[2][1]);
5.908 +
5.909 + // Distance from fourth corner
5.910 + dSpxDist[3][0] = dSpxDist[0][0] - iSpxOffs[2][0] + (3.0 * dSpxSkew[2][1]);
5.911 + dSpxDist[3][1] = dSpxDist[0][1] - iSpxOffs[2][1] + (3.0 * dSpxSkew[2][1]);
5.912 + dSpxDist[3][2] = dSpxDist[0][2] - iSpxOffs[2][2] + (3.0 * dSpxSkew[2][1]);
5.913 + dSpxDist[3][3] = dSpxDist[0][3] - iSpxOffs[2][3] + (3.0 * dSpxSkew[2][1]);
5.914 +
5.915 + // Distance from last corner
5.916 + dSpxDist[4][0] = dSpxDist[0][0] - 1.0 + (4.0 * dSpxSkew[2][1]);
5.917 + dSpxDist[4][1] = dSpxDist[0][1] - 1.0 + (4.0 * dSpxSkew[2][1]);
5.918 + dSpxDist[4][2] = dSpxDist[0][2] - 1.0 + (4.0 * dSpxSkew[2][1]);
5.919 + dSpxDist[4][3] = dSpxDist[0][3] - 1.0 + (4.0 * dSpxSkew[2][1]);
5.920 +
5.921 + // Permutated numbers, normalized to a range of 0 to 32
5.922 + iSpxGrads[0] = iSpxTab[iSpxPerms[0] + iSpxTab[iSpxPerms[1] + iSpxTab[iSpxPerms[2] + iSpxTab[iSpxPerms[3]]]]] % 32;
5.923 + iSpxGrads[1] = iSpxTab[iSpxPerms[0] + iSpxTab[iSpxPerms[1] + iSpxTab[iSpxPerms[2] + iSpxTab[iSpxPerms[3] + iSpxOffs[0][3]] + iSpxOffs[0][2]] + iSpxOffs[0][1]] + iSpxOffs[0][0]] % 32;
5.924 + iSpxGrads[2] = iSpxTab[iSpxPerms[0] + iSpxTab[iSpxPerms[1] + iSpxTab[iSpxPerms[2] + iSpxTab[iSpxPerms[3] + iSpxOffs[1][3]] + iSpxOffs[1][2]] + iSpxOffs[1][1]] + iSpxOffs[1][0]] % 32;
5.925 + iSpxGrads[3] = iSpxTab[iSpxPerms[0] + iSpxTab[iSpxPerms[1] + iSpxTab[iSpxPerms[2] + iSpxTab[iSpxPerms[3] + iSpxOffs[2][3]] + iSpxOffs[2][2]] + iSpxOffs[2][1]] + iSpxOffs[2][0]] % 32;
5.926 + iSpxGrads[4] = iSpxTab[iSpxPerms[0] + iSpxTab[iSpxPerms[1] + iSpxTab[iSpxPerms[2] + iSpxTab[iSpxPerms[3] + 1] + 1] + 1] + 1] % 32;
5.927 +
5.928 + // Calculate the contribution from the four corners
5.929 + dContrib = 0.6 - pow(dSpxDist[0][0], 2) - pow(dSpxDist[0][1], 2) - pow(dSpxDist[0][2], 2) - pow(dSpxDist[0][3], 2);
5.930 + dSpxCorn[0] = (dContrib > 0.0) ? pow(dContrib, 4) * getSimpDot(iSpxGrads[0], dSpxDist[0][0], dSpxDist[0][1], dSpxDist[0][2], dSpxDist[0][3]) : 0.0;
5.931 + dContrib = 0.6 - pow(dSpxDist[1][0], 2) - pow(dSpxDist[1][1], 2) - pow(dSpxDist[1][2], 2) - pow(dSpxDist[1][3], 2);
5.932 + dSpxCorn[1] = (dContrib > 0.0) ? pow(dContrib, 4) * getSimpDot(iSpxGrads[1], dSpxDist[1][0], dSpxDist[1][1], dSpxDist[1][2], dSpxDist[1][3]) : 0.0;
5.933 + dContrib = 0.6 - pow(dSpxDist[2][0], 2) - pow(dSpxDist[2][1], 2) - pow(dSpxDist[2][2], 2) - pow(dSpxDist[2][3], 2);
5.934 + dSpxCorn[2] = (dContrib > 0.0) ? pow(dContrib, 4) * getSimpDot(iSpxGrads[2], dSpxDist[2][0], dSpxDist[2][1], dSpxDist[2][2], dSpxDist[2][3]) : 0.0;
5.935 + dContrib = 0.6 - pow(dSpxDist[3][0], 2) - pow(dSpxDist[3][1], 2) - pow(dSpxDist[3][2], 2) - pow(dSpxDist[3][3], 2);
5.936 + dSpxCorn[3] = (dContrib > 0.0) ? pow(dContrib, 4) * getSimpDot(iSpxGrads[3], dSpxDist[3][0], dSpxDist[3][1], dSpxDist[3][2], dSpxDist[3][3]) : 0.0;
5.937 +
5.938 + // Add contributions from each corner to get the final noise value.
5.939 + // The result is scaled to return values in the interval [-1,1].
5.940 + return((31.91239940056049206873467483092098 * (dSpxCorn[0] + dSpxCorn[1] + dSpxCorn[2] + dSpxCorn[3])) / smooth);
5.941 + // Note: This factor has been found by searching the factor needed
5.942 + // To get 1.0 with the largest result out of 100M iterations
5.943 +
5.944 +}
5.945 +
5.946 +
5.947 +/*---------------------------------------------------*/
5.948 +/* ---------------- Private Methods ---------------- */
5.949 +/*---------------------------------------------------*/
5.950 +/** @brief get Simplex Dot for one dimension
5.951 + */
5.952 +double Random::getSimpDot(int iIndex, double x)
5.953 +{
5.954 + assert((iIndex >= 0) && (iIndex < 4));
5.955 + return( (iSpxGrTab[iIndex][0] * x));
5.956 +}
5.957 +
5.958 +
5.959 +/** @brief get Simplex Dot for second dimension
5.960 + */
5.961 +double Random::getSimpDot(int iIndex, double x, double y)
5.962 +{
5.963 + assert((iIndex >= 0) && (iIndex < 8));
5.964 + return( (iSpxGrTab[iIndex][0] * x)
5.965 + +(iSpxGrTab[iIndex][1] * y));
5.966 +}
5.967 +
5.968 +
5.969 +/** @brief get Simplex Dot for third dimension
5.970 + */
5.971 +double Random::getSimpDot(int iIndex, double x, double y, double z)
5.972 +{
5.973 + assert((iIndex >= 0) && (iIndex < 12));
5.974 + return( (iSpxGrTab[iIndex][0] * x)
5.975 + +(iSpxGrTab[iIndex][1] * y)
5.976 + +(iSpxGrTab[iIndex][2] * z));
5.977 +}
5.978 +
5.979 +
5.980 +/** @brief get Simplex Dot for fourth dimension
5.981 + */
5.982 +double Random::getSimpDot(int iIndex, double x, double y, double z, double w)
5.983 +{
5.984 + assert((iIndex >= 0) && (iIndex < 32));
5.985 + return( (iSpxGrTab[iIndex][0] * x)
5.986 + +(iSpxGrTab[iIndex][1] * y)
5.987 + +(iSpxGrTab[iIndex][2] * z)
5.988 + +(iSpxGrTab[iIndex][3] * w));
5.989 +}
5.990 +
5.991 +
5.992 +/*---------------------------------------------------*/
5.993 +/* ---------------- Static Instance ---------------- */
5.994 +/*---------------------------------------------------*/
5.995 +static Random RNG; //!< Static instance of Random to be used
5.996 +
5.997 +} // namespace pwx
5.998 +
5.999 +#endif // PWXRANDOM_H_INCLUDED
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/src/extern/pwxSinCosTables/pwxSinCosTables.h Mon Oct 05 09:44:14 2009 +0200
6.3 @@ -0,0 +1,241 @@
6.4 +#pragma once
6.5 +#ifndef PWXSINCOSTABLES_H_INCLUDED
6.6 +#define PWXSINCOSTABLES_H_INCLUDED 1
6.7 +
6.8 +/* pwxSinCosTables.h
6.9 + * ------------------
6.10 + * (c) 2007-2009 PrydeWorX
6.11 + * @Author: Sven Eden, PrydeWorX - Hamburg, Germany
6.12 + *
6.13 + * This file is provided as is and published under GPL license.
6.14 + * Do, whatever you feel like doeing with it, but please mention
6.15 + * me somewhere within the documentation of your project if you
6.16 + * find this usefull enough to actually use it. OpenSource4Ever!
6.17 + *
6.18 + * History:
6.19 + * --------
6.20 + * 14.02.2008 SE, PrydeWorX changed to be a class rather than global arrays
6.21 + * 20.02.2008 SE, PrydeWorX added sincos()
6.22 + * 16.01.2009 SE, PrydeWorX added life calculation for _PWX_SCTPREC == 0
6.23 + * 09.06.2009 SE, PrydeWorX some optimizations and new forcing of inlining
6.24 + */
6.25 +
6.26 +#ifndef _PWX_SCTPREC
6.27 +//! Define the depth of the arrays
6.28 +#define _PWX_SCTPREC 1000
6.29 +#endif // _PWX_SCTPREC
6.30 +#ifndef _PWX_SCTSIZE
6.31 +#define _PWX_SCTSIZE (360 * _PWX_SCTPREC)
6.32 +#endif // _PWX_SCTSIZE
6.33 +
6.34 +#ifndef _PWX_SCTOUTPUT
6.35 +//! Define whether or not to initialize with output
6.36 +#define _PWX_SCTOUTPUT false
6.37 +#endif // _PWX_SCTOUTPUT
6.38 +
6.39 +#include <cmath>
6.40 +#include <iostream>
6.41 +
6.42 +#ifndef M_PIl
6.43 +//! On some (non GNU) systems, the long version of M_PI is not defined, thus we do that here
6.44 +#define M_PIl 3.1415926535897932384626433832795029L /* pi */
6.45 +#endif // M_PIl
6.46 +
6.47 +namespace pwx
6.48 + {
6.49 +#include "pwxDefaultDefines/defines.h"
6.50 + /** @brief Provides pre-calculated(*) sine and cosine tables
6.51 + *
6.52 + * Calculating sine and cosine values does not take much time
6.53 + * nowadays as FPUs get stronger every other day. On the other
6.54 + * hand, if you need these values for on-the-fly calculations
6.55 + * of something CPU-consuming like the display of 3D objects,
6.56 + * this little bit of CPU/FPU resources might better be saved.
6.57 + * Sin-/Cos-Tables with a precision of 3 take up about 8MB
6.58 + * (total), and this is not very much either.
6.59 + *
6.60 + * Tests show, that a Sin-/Cos-Tables with a precision of 3,
6.61 + * meaning 2 x 360,000 values in two arrays, do not differ from
6.62 + * on-the-fly calculation until the (worst case!) 6th digit.
6.63 + * (normally the first 7-8 digits are equal, which should be
6.64 + * enough for most applications. See the Test program (main.cpp)
6.65 + * for the tests!)<BR>
6.66 + *
6.67 + * (*) If you set _PWX_SCTPREC to 0 (zero), there will be no pre-defined
6.68 + * tables, but all sine and cosine values calculated life. You still do
6.69 + * not have to care about the range of your angles, and do not need to
6.70 + * transform angles to radiants.
6.71 + *
6.72 + * Usage:
6.73 + * <OL><LI>Alter _PWX_SCTPREC if you'd like to use a different
6.74 + * precision but 3, or define it yourself before including
6.75 + * this file. The default of 1000 means a precision of 3.</LI>
6.76 + * <LI>Set _PWX_SCTPREC to 0 if you prefer life calculations over
6.77 + * pre-calculated tables.</LI>
6.78 + * <LI>Normally the initialization is done silent. But if you need
6.79 + * a console output, when using a higher _PWX_SCTPREC for instance,
6.80 + * you can predefine _PWX_SCTOUTPUT to be true instead of false.</LI>
6.81 + * <LI>The file provides a static and initialized instance
6.82 + * of the class: pwx::SCT</LI>
6.83 + * <LI>Use the following functions to get the values:
6.84 + * <UL><LI>For Sine call pwx::SCT.sin (long double degree)</LI>
6.85 + * <LI>For Cosine call pwx::SCT.cos (long double degree)</LI>
6.86 + * <LI>For both call pwx::SCT.sincos(long double degree, long double
6.87 + * &sin, long double &cos)</LI></UL></OL>
6.88 + */
6.89 + class _PWX_INTERNAL SinCosTables
6.90 + {
6.91 + public:
6.92 + // --- attributes ---
6.93 + // --- virtual methods ---
6.94 + // --- functions ---
6.95 + /** @brief get cosine
6.96 + * This method gives the precalculated cosine of aDegree back.
6.97 + * Degrees < 0.0 or > 360.0 are adapted to be within the circles
6.98 + * range.
6.99 + * @param aDegree long double degree to be calculated.
6.100 + * @return The corresponding cosine.
6.101 + */
6.102 + inline long double _PWX_VISIBLE cos(long double aDegree) _PWX_USED _PWX_FORCEINLINE
6.103 + {
6.104 +#if (_PWX_SCTPREC > 0)
6.105 + int xIndex = getNormalizedDegree(aDegree);
6.106 + return(CosTable[xIndex]);
6.107 +#else
6.108 + long double ldDegree = getNormalizedDegree(aDegree);
6.109 + return(std::cos((ldDegree * M_Pil) / 180.0L));
6.110 +#endif // if (_PWX_SCTPREC > 0)
6.111 + }
6.112 +
6.113 + /** @brief get sine
6.114 + * This method gives the precalculated sine of aDegree back.
6.115 + * Degrees < 0.0 or > 360.0 are adapted to be within the circles
6.116 + * range.
6.117 + * @param aDegree long double degree to be calculated.
6.118 + * @return The corresponding sine.
6.119 + */
6.120 + inline long double _PWX_VISIBLE sin(long double aDegree) _PWX_USED _PWX_FORCEINLINE
6.121 + {
6.122 +#if (_PWX_SCTPREC > 0)
6.123 + int xIndex = getNormalizedDegree(aDegree);
6.124 + return(SinTable[xIndex]);
6.125 +#else
6.126 + long double ldDegree = getNormalizedDegree(aDegree);
6.127 + return(std::sin((ldDegree * M_Pil) / 180.0L));
6.128 +#endif // if (_PWX_SCTPREC > 0)
6.129 + }
6.130 + // --- procedures ---
6.131 + /** @brief get both, sine and cosine
6.132 + * This method gives the precalculated sine and cosine of aDegree
6.133 + * back by filling the provided references.<BR>
6.134 + * Degrees < 0.0 or > 360.0 are adapted to be within the circles
6.135 + * range.
6.136 + * @param aDegree long double degree to be calculated.
6.137 + * @param aSin Reference of a long double to get the corresponding sine
6.138 + * @param aCos Reference of a long double to get the corresponding cosine
6.139 + */
6.140 + inline void _PWX_VISIBLE sincos(long double aDegree,
6.141 + long double &aSin, long double &aCos) _PWX_USED _PWX_FORCEINLINE
6.142 + {
6.143 +#if (_PWX_SCTPREC > 0)
6.144 + int xIndex = getNormalizedDegree(aDegree);
6.145 + aSin = SinTable[xIndex];
6.146 + aCos = CosTable[xIndex];
6.147 +#else
6.148 + long double ldDegree = getNormalizedDegree(aDegree);
6.149 + long double ldRadian = (ldDegree * M_Pil) / 180.0L;
6.150 + aSin = std::sin(ldRadian);
6.151 + aCos = std::cos(ldRadian);
6.152 +#endif // if (_PWX_SCTPREC > 0)
6.153 + }
6.154 +
6.155 + /** @brief default ctor
6.156 + * Initializes the arrays. Predefine _PWX_SCTOUTPUT to be true prior
6.157 + * including this file to get a console output while initializing.
6.158 + * @param aWithOutput Defaults to false and is defined by _PWX_SCTOUTPUT
6.159 + */
6.160 + SinCosTables(bool aWithOutput = false)
6.161 + {
6.162 +#if (_PWX_SCTPREC > 0)
6.163 + unsigned int i = 0;
6.164 + long double xRadiant = 0.0;
6.165 +
6.166 + while ( i < _PWX_SCTSIZE )
6.167 + {
6.168 + /* sin() and cos() use radiant, so we have to recalc:
6.169 + * 360° = 2PI rad
6.170 + * => 1° = PI/180 rad
6.171 + * => x° = (x * PI)/180 rad
6.172 + */
6.173 + xRadiant = ( ( ( long double ) i / ( long double ) _PWX_SCTPREC ) * M_PIl ) / 180.0L;
6.174 + SinTable[i] = std::sin ( xRadiant );
6.175 + CosTable[i] = std::cos ( xRadiant );
6.176 + i++;
6.177 + if ( ( i % ( _PWX_SCTPREC * 36 ) == 0 ) && aWithOutput )
6.178 + {
6.179 + std::cout << " " << ( ( i / ( _PWX_SCTPREC * 36 ) ) *10 ) << "%";
6.180 + std::cout.flush();
6.181 + }
6.182 + }
6.183 + if (aWithOutput)
6.184 + {
6.185 + std::cout << endl << "SinCosTables initialized!";
6.186 + std::cout.flush();
6.187 + }
6.188 +#else
6.189 + if (aWithOutput)
6.190 + {
6.191 + std::cout << "SinCosTables omited, SCT configured for life calculations!";
6.192 + std::cout.flush();
6.193 + }
6.194 +#endif // if (_PWX_SCTPREC > 0)
6.195 + if (aWithOutput)
6.196 + {
6.197 + std::cout << endl;
6.198 + std::cout.flush();
6.199 + }
6.200 + }
6.201 + // --- operators ---
6.202 + protected:
6.203 + // --- attributes ---
6.204 + // --- virtual methods ---
6.205 + // --- functions ---
6.206 + // --- procedures ---
6.207 + // --- operators ---
6.208 + private:
6.209 + // --- attributes ---
6.210 +#if (_PWX_SCTPREC > 0)
6.211 + long double SinTable[_PWX_SCTSIZE]; //!< Internal array with precalculated sine values
6.212 + long double CosTable[_PWX_SCTSIZE]; //!< Internal array with precalculated cosine values
6.213 +#endif // if (_PWX_SCTPREC > 0)
6.214 + // --- virtual methods ---
6.215 + // --- functions ---
6.216 +#if (_PWX_SCTPREC > 0)
6.217 + inline int getNormalizedDegree(long double aDegree) _PWX_INTERNAL _PWX_FORCEINLINE
6.218 + {
6.219 + int iDegree = (int)round(aDegree * _PWX_SCTPREC);
6.220 + int iMaxSize= _PWX_SCTSIZE * 10;
6.221 + while (abs(iDegree) >= iMaxSize) iDegree /= 10;
6.222 + while (iDegree >= _PWX_SCTSIZE) iDegree -= _PWX_SCTSIZE;
6.223 + while (iDegree < 0) iDegree += _PWX_SCTSIZE;
6.224 + return (iDegree);
6.225 + }
6.226 +#else
6.227 + inline long double getNormalizedDegree(long double aDegree) _PWX_INTERNAL _PWX_FORCEINLINE
6.228 + {
6.229 + long double ldDegree = (long double)round(aDegree * (long double)_PWX_SCTPREC);
6.230 + while (fabs(ldDegree) >= 3600.0L) ldDegree /= 10.0L;
6.231 + while (ldDegree >= 360.0L) ldDegree -= 360.0L;
6.232 + while (ldDegree < 0.0L) ldDegree += 360.0L;
6.233 + return (ldDegree);
6.234 + }
6.235 +#endif // if (_PWX_SCTPREC > 0)
6.236 + // --- procedures ---
6.237 + // --- operators ---
6.238 + };
6.239 +
6.240 + static SinCosTables SCT(_PWX_SCTOUTPUT); //!< Static instance of SinCosTables to be used
6.241 +
6.242 + } // namespace
6.243 +
6.244 +#endif // PWXSINCOSTABLES_H_INCLUDED
7.1 --- a/src/files.cpp Tue Sep 29 18:04:04 2009 +0200
7.2 +++ b/src/files.cpp Mon Oct 05 09:44:14 2009 +0200
7.3 @@ -216,41 +216,41 @@
7.4 // if everything worked, the .sav can be loaded
7.5 while (!bIsFinished && (player_count < max_players) && (bResult = popData(chArea, bIsData, ifsFile)))
7.6 {
7.7 - if (!bIsData && streq(chArea, FILEPART_ENDFILE)) bIsFinished = true;
7.8 - else if (!bIsData && streq(chArea, FILEPART_ENDPLYR))
7.9 + if (!bIsData && STREQ(chArea, FILEPART_ENDFILE)) bIsFinished = true;
7.10 + else if (!bIsData && STREQ(chArea, FILEPART_ENDPLYR))
7.11 {
7.12 // Next Player will come!
7.13 player_number = 0;
7.14 player_count++;
7.15 }
7.16 - else if (streq(chArea, "MaxRounds ")) bResult = popData(global->rounds, ifsFile);
7.17 - else if (streq(chArea, "CurrRound ")) bResult = popData(global->currentround, ifsFile);
7.18 - else if (streq(chArea, "Campaign ")) bResult = popData(global->campaign_mode, ifsFile);
7.19 - else if (streq(chArea, "PlayerCount")) bResult = popData(max_players, ifsFile);
7.20 - else if (streq(chArea, "PlayerNumber") && (bResult = popData(player_number, ifsFile)) )
7.21 + else if (STREQ(chArea, "MaxRounds ")) bResult = popData(global->rounds, ifsFile);
7.22 + else if (STREQ(chArea, "CurrRound ")) bResult = popData(global->currentround, ifsFile);
7.23 + else if (STREQ(chArea, "Campaign ")) bResult = popData(global->campaign_mode, ifsFile);
7.24 + else if (STREQ(chArea, "PlayerCount")) bResult = popData(max_players, ifsFile);
7.25 + else if (STREQ(chArea, "PlayerNumber") && (bResult = popData(player_number, ifsFile)) )
7.26 {
7.27 global->addPlayer( global->allPlayers[player_number] );
7.28 global->players[player_count]->initialise();
7.29 }
7.30 - else if (streq(chArea, "Score ")) bResult = popData(global->players[player_count]->score, ifsFile);
7.31 - else if (streq(chArea, "Money ")) bResult = popData(global->players[player_count]->money, ifsFile);
7.32 - else if (streq(chArea, "PlayerType ")) bResult = popData(global->players[player_count]->type, ifsFile);
7.33 - else if (streq(chArea, "TypeSaved ")) bResult = popData(global->players[player_count]->type_saved, ifsFile);
7.34 - else if (streq(chArea, "Revengee Nr ")) bResult = popData(revengees[player_count], ifsFile);
7.35 - else if (streq(chArea, "Kills ")) bResult = popData(global->players[player_count]->kills, ifsFile);
7.36 - else if (streq(chArea, "Deaths ")) bResult = popData(global->players[player_count]->killed, ifsFile);
7.37 + else if (STREQ(chArea, "Score ")) bResult = popData(global->players[player_count]->score, ifsFile);
7.38 + else if (STREQ(chArea, "Money ")) bResult = popData(global->players[player_count]->money, ifsFile);
7.39 + else if (STREQ(chArea, "PlayerType ")) bResult = popData(global->players[player_count]->type, ifsFile);
7.40 + else if (STREQ(chArea, "TypeSaved ")) bResult = popData(global->players[player_count]->type_saved, ifsFile);
7.41 + else if (STREQ(chArea, "Revengee Nr ")) bResult = popData(revengees[player_count], ifsFile);
7.42 + else if (STREQ(chArea, "Kills ")) bResult = popData(global->players[player_count]->kills, ifsFile);
7.43 + else if (STREQ(chArea, "Deaths ")) bResult = popData(global->players[player_count]->killed, ifsFile);
7.44 else if (bIsData)
7.45 {
7.46 // weapon or item data
7.47 count = 0;
7.48 while (!bIsFinished && ((count < WEAPONS) || (count < ITEMS)))
7.49 {
7.50 - if ((count < WEAPONS) && streq(chArea, weapon[count].name))
7.51 + if ((count < WEAPONS) && STREQ(chArea, weapon[count].name))
7.52 {
7.53 bResult = popData(global->players[player_count]->nm[count], ifsFile);
7.54 bIsFinished = true;
7.55 }
7.56 - if ((count < ITEMS) && streq(chArea, item[count].name))
7.57 + if ((count < ITEMS) && STREQ(chArea, item[count].name))
7.58 {
7.59 bResult = popData(global->players[player_count]->ni[count], ifsFile);
7.60 bIsFinished = true;
8.1 --- a/src/globaldata.cpp Tue Sep 29 18:04:04 2009 +0200
8.2 +++ b/src/globaldata.cpp Mon Oct 05 09:44:14 2009 +0200
8.3 @@ -195,33 +195,33 @@
8.4
8.5 while (!bIsFinished && (bResult = popData(chArea, bIsData, ifsFile)))
8.6 {
8.7 - if (!bIsData && streq(chArea, FILEPART_ENDSECT)) bIsFinished = true;
8.8 - else if (streq(chArea, "Check For Updates ")) bResult = popData(dCheckUpdates, ifsFile);
8.9 - else if (streq(chArea, "Dither Gradient ")) bResult = popData(ditherGradients, ifsFile);
8.10 - else if (streq(chArea, "Detail Landscape ")) bResult = popData(detailedLandscape, ifsFile);
8.11 - else if (streq(chArea, "Detail Sky ")) bResult = popData(detailedSky, ifsFile);
8.12 - else if (streq(chArea, "Show AI Thinking ")) bResult = popData(dShowAIMove, ifsFile);
8.13 - else if (streq(chArea, "Show FPS ")) bResult = popData(dShowFPS, ifsFile);
8.14 - else if (streq(chArea, "Interest ")) bResult = popData(interest, ifsFile);
8.15 - else if (streq(chArea, "Score Round Win ")) bResult = popData(scoreRoundWinBonus, ifsFile);
8.16 - else if (streq(chArea, "Score Unit Hit ")) bResult = popData(scoreHitUnit, ifsFile);
8.17 - else if (streq(chArea, "Score Unit Destroy")) bResult = popData(scoreUnitDestroyBonus, ifsFile);
8.18 - else if (streq(chArea, "Score Self Destroy")) bResult = popData(scoreUnitSelfDestroy, ifsFile);
8.19 - else if (streq(chArea, "Sell Ratio ")) bResult = popData(sellpercent, ifsFile);
8.20 - else if (streq(chArea, "Start Money ")) bResult = popData(startmoney, ifsFile);
8.21 - else if (streq(chArea, "Teams Share Money ")) bResult = popData(dTeamShare, ifsFile);
8.22 - else if (streq(chArea, "Turn Type ")) bResult = popData(turntype, ifsFile);
8.23 - else if (streq(chArea, "Skip Computer Play")) bResult = popData(skipComputerPlay, ifsFile);
8.24 - else if (streq(chArea, "Sound ")) bResult = popData(sound, ifsFile);
8.25 - else if (streq(chArea, "Screen Width ")) bResult = popData(screenWidth, ifsFile);
8.26 - else if (streq(chArea, "Screen Height ")) bResult = popData(screenHeight, ifsFile);
8.27 - else if (streq(chArea, "OS Mouse ")) bResult = popData(os_mouse, ifsFile);
8.28 - else if (streq(chArea, "Permanent Players ")) bResult = popData(numPermanentPlayers, ifsFile);
8.29 - else if (streq(chArea, "Language ")) bResult = popData(language, ifsFile);
8.30 - else if (streq(chArea, "Color Theme ")) bResult = popData(colour_theme, ifsFile);
8.31 - else if (streq(chArea, "Frames Per Second ")) bResult = popData(frames_per_second, ifsFile);
8.32 - else if (streq(chArea, "Violent Death ")) bResult = popData(violent_death, ifsFile);
8.33 - else if (streq(chArea, "Max Fire Time ")) bResult = popData(max_fire_time, ifsFile);
8.34 + if (!bIsData && STREQ(chArea, FILEPART_ENDSECT)) bIsFinished = true;
8.35 + else if (STREQ(chArea, "Check For Updates ")) bResult = popData(dCheckUpdates, ifsFile);
8.36 + else if (STREQ(chArea, "Dither Gradient ")) bResult = popData(ditherGradients, ifsFile);
8.37 + else if (STREQ(chArea, "Detail Landscape ")) bResult = popData(detailedLandscape, ifsFile);
8.38 + else if (STREQ(chArea, "Detail Sky ")) bResult = popData(detailedSky, ifsFile);
8.39 + else if (STREQ(chArea, "Show AI Thinking ")) bResult = popData(dShowAIMove, ifsFile);
8.40 + else if (STREQ(chArea, "Show FPS ")) bResult = popData(dShowFPS, ifsFile);
8.41 + else if (STREQ(chArea, "Interest ")) bResult = popData(interest, ifsFile);
8.42 + else if (STREQ(chArea, "Score Round Win ")) bResult = popData(scoreRoundWinBonus, ifsFile);
8.43 + else if (STREQ(chArea, "Score Unit Hit ")) bResult = popData(scoreHitUnit, ifsFile);
8.44 + else if (STREQ(chArea, "Score Unit Destroy")) bResult = popData(scoreUnitDestroyBonus, ifsFile);
8.45 + else if (STREQ(chArea, "Score Self Destroy")) bResult = popData(scoreUnitSelfDestroy, ifsFile);
8.46 + else if (STREQ(chArea, "Sell Ratio ")) bResult = popData(sellpercent, ifsFile);
8.47 + else if (STREQ(chArea, "Start Money ")) bResult = popData(startmoney, ifsFile);
8.48 + else if (STREQ(chArea, "Teams Share Money ")) bResult = popData(dTeamShare, ifsFile);
8.49 + else if (STREQ(chArea, "Turn Type ")) bResult = popData(turntype, ifsFile);
8.50 + else if (STREQ(chArea, "Skip Computer Play")) bResult = popData(skipComputerPlay, ifsFile);
8.51 + else if (STREQ(chArea, "Sound ")) bResult = popData(sound, ifsFile);
8.52 + else if (STREQ(chArea, "Screen Width ")) bResult = popData(screenWidth, ifsFile);
8.53 + else if (STREQ(chArea, "Screen Height ")) bResult = popData(screenHeight, ifsFile);
8.54 + else if (STREQ(chArea, "OS Mouse ")) bResult = popData(os_mouse, ifsFile);
8.55 + else if (STREQ(chArea, "Permanent Players ")) bResult = popData(numPermanentPlayers, ifsFile);
8.56 + else if (STREQ(chArea, "Language ")) bResult = popData(language, ifsFile);
8.57 + else if (STREQ(chArea, "Color Theme ")) bResult = popData(colour_theme, ifsFile);
8.58 + else if (STREQ(chArea, "Frames Per Second ")) bResult = popData(frames_per_second, ifsFile);
8.59 + else if (STREQ(chArea, "Violent Death ")) bResult = popData(violent_death, ifsFile);
8.60 + else if (STREQ(chArea, "Max Fire Time ")) bResult = popData(max_fire_time, ifsFile);
8.61 else if (!bIsFinished && bIsData)
8.62 bResult = popData(dData, ifsFile); // Something we do not know (any more/yet), so dump it!
8.63 }
9.1 --- a/src/main.h Tue Sep 29 18:04:04 2009 +0200
9.2 +++ b/src/main.h Mon Oct 05 09:44:14 2009 +0200
9.3 @@ -89,8 +89,8 @@
9.4
9.5 //-------------
9.6 // These two classes are reused from PrydeWorX C++ Library Project:
9.7 -#include "pwxRandom.h"
9.8 -#include "pwxSinCosTables.h"
9.9 +#include "extern/pwxRandom/pwxRandom.h"
9.10 +#include "extern/pwxSinCosTables/pwxSinCosTables.h"
9.11
9.12 using pwx::RNG;
9.13 using pwx::SCT;
9.14 @@ -123,8 +123,9 @@
9.15 // #define PI 3.14
9.16 #define MAXUPDATES 256 // This one needs to be watched! If the display goes bye bye, reduce the value!
9.17 #define MAX_OVERSHOOT 10000
9.18 -#define ABSDISTANCE(x1,y1,x2,y2) abs((int)sqrt((long double)pow(((long double)x2) - ((long double)x1), 2) + (long double)pow(((long double)y2) - ((long double)y1), 2)))
9.19 -#define FABSDISTANCE(x1,y1,x2,y2) abs(sqrt((long double)pow(((long double)x2) - ((long double)x1), 2) + (long double)pow(((long double)y2) - ((long double)y1), 2)))
9.20 +//#define ABSDISTANCE(x1,y1,x2,y2) abs((int)sqrt((long double)pow(((long double)x2) - ((long double)x1), 2) + (long double)pow(((long double)y2) - ((long double)y1), 2)))
9.21 +//#define FABSDISTANCE(x1,y1,x2,y2) abs(sqrt((long double)pow(((long double)x2) - ((long double)x1), 2) + (long double)pow(((long double)y2) - ((long double)y1), 2)))
9.22 +/// Now included in pwxDefaultDefines
9.23 /* An ellipse with the centre of 0,0 and a major axis equaling the x-axis has all points
9.24 * on it's edge described by:
9.25 * x² y²
9.26 @@ -441,7 +442,8 @@
9.27 #define FILEPART_ENDFILE "[EndFile]"
9.28
9.29 // this one improves readability:
9.30 -#define streq(a,b) (strcasecmp(a,b) == 0)
9.31 +//#define STREQ(a,b) (strcasecmp(a,b) == 0)
9.32 +/// Now included in pwxDefaultDefines
9.33
9.34 /** methods to handle loading and saving of data **/
9.35 /* --- take data out of filestream -- */
10.1 --- a/src/player.cpp Tue Sep 29 18:04:04 2009 +0200
10.2 +++ b/src/player.cpp Mon Oct 05 09:44:14 2009 +0200
10.3 @@ -459,37 +459,37 @@
10.4
10.5 while (!bIsFinished && (bResult = popData(chArea, bIsData, ifsFile)))
10.6 {
10.7 - if (!bIsData && streq(chArea, FILEPART_ENDPLYR)) bIsFinished = true;
10.8 + if (!bIsData && STREQ(chArea, FILEPART_ENDPLYR)) bIsFinished = true;
10.9 else if (!bIsData) strncpy(_name, chArea, NAME_LENGTH);
10.10 - else if (streq(chArea, "Vengefullness ")) bResult = popData(sAIData.iVengeful, ifsFile);
10.11 - else if (streq(chArea, "VengeThreshold ")) bResult = popData(sAIData.dVengThres, ifsFile);
10.12 - else if (streq(chArea, "Player Type ")) bResult = popData(type, ifsFile);
10.13 - else if (streq(chArea, "Type Saved ")) bResult = popData(type_saved, ifsFile);
10.14 - else if (streq(chArea, "Color 1 ")) bResult = popColo(color, ifsFile);
10.15 - else if (streq(chArea, "Color 2 ")) bResult = popColo(color2, ifsFile);
10.16 - else if (streq(chArea, "Rounds Played ")) bResult = popData(played, ifsFile);
10.17 - else if (streq(chArea, "Rounds Won ")) bResult = popData(won, ifsFile);
10.18 - else if (streq(chArea, "Preference Type")) bResult = popData(preftype, ifsFile);
10.19 - else if (streq(chArea, "Self-Preservatn")) bResult = popData(sAIData.dSelfPreservation, ifsFile);
10.20 - else if (streq(chArea, "Pain Sensitive ")) bResult = popData(sAIData.dPainSensitivity, ifsFile);
10.21 - else if (streq(chArea, "Defensiveness ")) bResult = popData(sAIData.dDefensiveness, ifsFile);
10.22 - else if (streq(chArea, "Tank Bitmap ")) bResult = popData(tank_bitmap, ifsFile);
10.23 - else if (streq(chArea, "Team ")) bResult = popData(team , ifsFile);
10.24 - else if (streq(chArea, "Kills ")) bResult = popData(kills, ifsFile);
10.25 - else if (streq(chArea, "Deaths ")) bResult = popData(killed, ifsFile);
10.26 - else if (streq(chArea, "One Hit Wonders")) bResult = popData(sAIData.iOHWCount, ifsFile);
10.27 + else if (STREQ(chArea, "Vengefullness ")) bResult = popData(sAIData.iVengeful, ifsFile);
10.28 + else if (STREQ(chArea, "VengeThreshold ")) bResult = popData(sAIData.dVengThres, ifsFile);
10.29 + else if (STREQ(chArea, "Player Type ")) bResult = popData(type, ifsFile);
10.30 + else if (STREQ(chArea, "Type Saved ")) bResult = popData(type_saved, ifsFile);
10.31 + else if (STREQ(chArea, "Color 1 ")) bResult = popColo(color, ifsFile);
10.32 + else if (STREQ(chArea, "Color 2 ")) bResult = popColo(color2, ifsFile);
10.33 + else if (STREQ(chArea, "Rounds Played ")) bResult = popData(played, ifsFile);
10.34 + else if (STREQ(chArea, "Rounds Won ")) bResult = popData(won, ifsFile);
10.35 + else if (STREQ(chArea, "Preference Type")) bResult = popData(preftype, ifsFile);
10.36 + else if (STREQ(chArea, "Self-Preservatn")) bResult = popData(sAIData.dSelfPreservation, ifsFile);
10.37 + else if (STREQ(chArea, "Pain Sensitive ")) bResult = popData(sAIData.dPainSensitivity, ifsFile);
10.38 + else if (STREQ(chArea, "Defensiveness ")) bResult = popData(sAIData.dDefensiveness, ifsFile);
10.39 + else if (STREQ(chArea, "Tank Bitmap ")) bResult = popData(tank_bitmap, ifsFile);
10.40 + else if (STREQ(chArea, "Team ")) bResult = popData(team , ifsFile);
10.41 + else if (STREQ(chArea, "Kills ")) bResult = popData(kills, ifsFile);
10.42 + else if (STREQ(chArea, "Deaths ")) bResult = popData(killed, ifsFile);
10.43 + else if (STREQ(chArea, "One Hit Wonders")) bResult = popData(sAIData.iOHWCount, ifsFile);
10.44 else
10.45 {
10.46 // two possibilities: a) weapon preferences, b) item preferences
10.47 count = 0;
10.48 while (!bIsFinished && ((count < WEAPONS) || (count < ITEMS)))
10.49 {
10.50 - if ((count < WEAPONS) && streq(chArea, weapon[count].name))
10.51 + if ((count < WEAPONS) && STREQ(chArea, weapon[count].name))
10.52 {
10.53 bResult = popData(_weaponPreference[count], ifsFile);
10.54 bIsFinished = true;
10.55 }
10.56 - if ((count < ITEMS) && streq(chArea, item[count].name))
10.57 + if ((count < ITEMS) && STREQ(chArea, item[count].name))
10.58 {
10.59 bResult = popData(_weaponPreference[count + WEAPONS], ifsFile);
10.60 bIsFinished = true;
11.1 --- a/src/pwxDefines.h Tue Sep 29 18:04:04 2009 +0200
11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
11.3 @@ -1,57 +0,0 @@
11.4 -#ifndef _PWX_DEFINES_H_INCLUDED
11.5 -#define _PWX_DEFINES_H_INCLUDED
11.6 -
11.7 -#pragma once // some profilers and ides (eclipse cdt) need that!
11.8 -/* defines.h
11.9 - * ------------------
11.10 - * (c) 2007-2008 PrydeWorX
11.11 - * @Author: Sven Eden, PrydeWorX - Hamburg, Germany
11.12 - *
11.13 - * This file is provided as is and published under GPL license.
11.14 - * Do, whatever you feel like doeing with it, but please mention
11.15 - * me somewhere within the documentation of your project if you
11.16 - * find this usefull enough to actually use it. OpenSource4Ever!
11.17 - *
11.18 - * Documentation:
11.19 - * --------------
11.20 - * This file does only add some defines for visibilities and stuff.
11.21 - * nothing to worry about!
11.22 - */
11.23 -
11.24 -// Visibilities
11.25 -#ifndef _PWX_INTERNAL
11.26 -#define _PWX_INTERNAL __attribute__ ((visibility ("internal")))
11.27 -#endif // _PWX_INTERNAL
11.28 -#ifndef _PWX_VISIBLE
11.29 -#define _PWX_VISIBLE __attribute__ ((visibility ("default")))
11.30 -#endif // _PWX_VISIBLE externally_visible
11.31 -#ifndef _PWX_EXTERNVISIBLE
11.32 -#define _PWX_EXTERNVISIBLE __attribute__ ((externally_visible))
11.33 -#endif // _PWX_EXTERNVISIBLE
11.34 -
11.35 -// vars && functions
11.36 -#ifndef _PWX_VIRTUAL_PURE
11.37 -#define _PWX_VIRTUAL_PURE =0
11.38 -#endif // _PWX_VIRTUAL_PURE
11.39 -#ifndef _PWX_PURE
11.40 -#define _PWX_PURE __attribute__ ((pure))
11.41 -#endif // _PWX_PURE
11.42 -#ifndef _PWX_UNUSED
11.43 -#define _PWX_UNUSED __attribute__ ((unused))
11.44 -#endif // _PWX_UNUSED
11.45 -#ifndef _PWX_USED
11.46 -#define _PWX_USED __attribute__ ((used))
11.47 -#endif // _PWX_VAR_USED
11.48 -#ifndef _PWX_WARNUNUSED
11.49 -#define _PWX_WARNUNUSED __attribute__ ((warn_unused_result))
11.50 -#endif // _PWX_WARNUNUSED
11.51 -#ifndef _PWX_FORCEINLINE
11.52 -#define _PWX_FORCEINLINE __attribute__ ((always_inline))
11.53 -#endif // _PWX_WARNUNUSED
11.54 -
11.55 -// NULL
11.56 -#ifndef NULL
11.57 -#define NULL 0
11.58 -#endif // NULL
11.59 -
11.60 -#endif // _PWX_DEFINES_H_INCLUDED
12.1 --- a/src/pwxRandom.h Tue Sep 29 18:04:04 2009 +0200
12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
12.3 @@ -1,329 +0,0 @@
12.4 -#ifndef PWXRANDOM_H_INCLUDED
12.5 -#define PWXRANDOM_H_INCLUDED
12.6 -
12.7 -#pragma once
12.8 -/* pwxRandom.h
12.9 - * ------------------
12.10 - * (c) 2007 - 2009 PrydeWorX
12.11 - * @Author: Sven Eden, PrydeWorX - Hamburg, Germany
12.12 - *
12.13 - * This file is provided as is and published under GPL license.
12.14 - * Do, whatever you feel like doeing with it, but please mention
12.15 - * me somewhere within the documentation of your project if you
12.16 - * find this usefull enough to actually use it. OpenSource4Ever!
12.17 - *
12.18 - * History:
12.19 - * --------
12.20 - * 21.12.2007 SE, PrydeWorX First Design
12.21 - * 09.04.2008 SE, PrydeWorX initial release
12.22 - * 11.11.2008 SE, PrydeWorX added documentation and long int/double versions
12.23 - * 04.04.2009 SE, PrydeWorX forced all methods to be inlined with newer gcc
12.24 - * 31.07.2009 SE, PrydeWorX some optimizations to favour mod instead of division
12.25 - */
12.26 -
12.27 -#include <cstdlib>
12.28 -#include <cmath>
12.29 -
12.30 -namespace pwx
12.31 - {
12.32 -//#include "pwxDefaultDefines/defines.h"
12.33 -// changed locally for atomic tanks project
12.34 -#include "pwxDefines.h"
12.35 -
12.36 - /** @brief Static class to produce unique random numbers.
12.37 - *
12.38 - * This class has been created, because I am fed up with
12.39 - * rand() giving back the same random number if it is called
12.40 - * too fast again after one use.
12.41 - *
12.42 - * The next thing I do not like is, that rand() only generates
12.43 - * numbers between zero and RAND_MAX, which is defined as being
12.44 - * INT_MAX.
12.45 - *
12.46 - * This class produces a static instance called pwx::RNG, meaning
12.47 - * "Random Number Generator" and provides functions which return
12.48 - * random numbers as int, long int, float, double and long double,
12.49 - * having their arguments being of the same type. Additionally
12.50 - * all functions come in two flavours:
12.51 - *
12.52 - * 1.: One argument max, resulting in 0 <= result <= max <BR>
12.53 - * 2.: Two arguments, min and max, resulting in min <= result <= max
12.54 - */
12.55 - class _PWX_INTERNAL Random
12.56 - {
12.57 - public:
12.58 - // --- attributes ---
12.59 - // --- virtual methods ---
12.60 - // --- functions ---
12.61 - /** @brief Generate a random value of int between 0 and max.
12.62 - *
12.63 - * This is the simplest method, which, when used without an argument,
12.64 - * behaves exactly like rand() would, but ensures, that the return
12.65 - * value is another one than the one returned the last time any of
12.66 - * the RNG methods was used.<BR>
12.67 - * if a negative max is submitted, the result will be max <= result <= 0.
12.68 - * @param max Specifies the desired maximum value (default is RAND_MAX).
12.69 - * @return A random value between 0 and max.
12.70 - */
12.71 - inline int _PWX_VISIBLE random(int max = RAND_MAX) _PWX_VISIBLE _PWX_FORCEINLINE
12.72 - {
12.73 - if (max == 0)
12.74 - return(0);
12.75 - else
12.76 - {
12.77 - int xModFactor = max > 0 ? 1 : -1;
12.78 - int xResult = rand();
12.79 - int xMax = abs(max); // To ensure that xMax is positive
12.80 -
12.81 - while (xResult == cLastValue) xResult = rand();
12.82 - cLastValue = xResult; // Last rand() result saved!
12.83 -
12.84 - if (xMax < RAND_MAX)
12.85 - // Now the result has to be recalculated into 0<=result<=max
12.86 - xResult %= xMax + 1; // + 1 to include xMax
12.87 -
12.88 - return(xResult * xModFactor);
12.89 - }
12.90 - }
12.91 -
12.92 - /** @brief Generate a random value of int between min and max.
12.93 - *
12.94 - * This method returns a value between min and max if either
12.95 - * min < max, or max is negative and max < min.<BR>
12.96 - * if a negative max is submitted, the result will be max <= result <= min.
12.97 - * This might be look odd, but min <= result <= max with negative min and
12.98 - * max is possible, too. It is just a convenience.
12.99 - * @param min Specifies the desired minimum value.
12.100 - * @param max Specifies the desired maximum value.
12.101 - * @return A random value between 0 and max.
12.102 - */
12.103 - inline int _PWX_VISIBLE random(int min, int max) _PWX_VISIBLE _PWX_FORCEINLINE
12.104 - {
12.105 - if (max == min)
12.106 - return(max);
12.107 - else
12.108 - {
12.109 - int xMin = abs(max) > abs(min) ? min : max;
12.110 - int xMax = abs(min) < abs(max) ? max : min;
12.111 -
12.112 - // As the result is an int, we can use random()
12.113 - return (random(xMax - xMin) + xMin);
12.114 - }
12.115 - }
12.116 -
12.117 - /** @brief Generate a random value of long int between 0 and max.
12.118 - *
12.119 - * This one should be used with care! As rand() returns values between
12.120 - * 0 and the maximum number an int can hold, recalculating the result
12.121 - * into a long int with a maximum higher than INT_MAX *will* eliminate
12.122 - * various numbers which can not be returned.<BR>
12.123 - * Example:<BR>
12.124 - * If you get a random number between 0 and 10, and then recalculate it
12.125 - * to be between 0 and 20, all odd numbers will be eliminated. So your
12.126 - * result *will* be even, no matter what you try!
12.127 - * @param max Specifies the desired maximum value.
12.128 - * @return A random value between 0 and max.
12.129 - */
12.130 - inline long int _PWX_VISIBLE random(long int max) _PWX_VISIBLE _PWX_FORCEINLINE
12.131 - {
12.132 - if (max == 0)
12.133 - return(0);
12.134 - else
12.135 - {
12.136 - /* There are two possibilities:
12.137 - * 1.: max <= RAND_MAX
12.138 - * Then just return the result of the integer version.
12.139 - * 2.: max > RAND_MAX
12.140 - * Return the result of the integer version, multiplied by
12.141 - * the difference factor between max and RAND_MAX
12.142 - */
12.143 - if (abs(max) <= RAND_MAX)
12.144 - // First Situation:
12.145 - return((long int)random((int)max));
12.146 - else
12.147 - // Second Situation:
12.148 - {
12.149 - long int xResult = (long int)random();
12.150 - long double xFactor = abs((long double)max / (long double)RAND_MAX);
12.151 - return((long int)round(xResult * xFactor));
12.152 - }
12.153 - }
12.154 - }
12.155 -
12.156 - /** @brief Generate a random value of long int between min and max.
12.157 - *
12.158 - * Use this method if you need a random value between min and max,
12.159 - * but have a max that is larger than INT_MAX.
12.160 - * @param min Specifies the desired minimum value.
12.161 - * @param max Specifies the desired maximum value.
12.162 - * @return A random value between min and max.
12.163 - */
12.164 - inline long int _PWX_VISIBLE random(long int min, long int max) _PWX_VISIBLE _PWX_FORCEINLINE
12.165 - {
12.166 - if (max == min)
12.167 - return(max);
12.168 - else
12.169 - {
12.170 - // Can we use random(max) ?
12.171 - if ((min == 0L) || (max == 0L))
12.172 - return(random(min == 0L ? max : min));
12.173 - else
12.174 - {
12.175 - long int xMin = abs(max) > abs(min) ? min : max;
12.176 - long int xMax = abs(min) < abs(max) ? max : min;
12.177 - return(random(xMax - xMin) + xMin);
12.178 - }
12.179 - }
12.180 - }
12.181 -
12.182 - /** @brief Generate a random value of float between 0 and max.
12.183 - *
12.184 - * @param max Specifies the desired maximum value.
12.185 - * @return A random value between 0 and max.
12.186 - */
12.187 - inline float _PWX_VISIBLE random(float max) _PWX_VISIBLE _PWX_FORCEINLINE
12.188 - {
12.189 - if ( (max >= -0.0001) && (max <= 0.0001))
12.190 - return(0.0);
12.191 - else
12.192 - {
12.193 - int iRand = random();
12.194 - return(max * (float)((float)iRand / (float)RAND_MAX));
12.195 - }
12.196 - }
12.197 -
12.198 - /** @brief Generate a random value of float between min and max.
12.199 - *
12.200 - * @param min Specifies the desired minimum value.
12.201 - * @param max Specifies the desired maximum value.
12.202 - * @return A random value between min and max.
12.203 - */
12.204 - inline float _PWX_VISIBLE random(float min, float max) _PWX_VISIBLE _PWX_FORCEINLINE
12.205 - {
12.206 - if (max == min)
12.207 - return(max);
12.208 - else
12.209 - {
12.210 - // Can we use random(float max) ?
12.211 - if ((min == 0.0) || (max == 0.0))
12.212 - return(random(min == 0 ? max : min));
12.213 - else
12.214 - {
12.215 - float xMin = abs(max) > abs(min) ? min : max;
12.216 - float xMax = abs(min) < abs(max) ? max : min;
12.217 - return (random(xMax - xMin) + xMin);
12.218 - }
12.219 - }
12.220 - }
12.221 -
12.222 - /** @brief Generate a random value of double between 0 and max.
12.223 - *
12.224 - * @param max Specifies the desired maximum value.
12.225 - * @return A random value between 0 and max.
12.226 - */
12.227 - inline double _PWX_VISIBLE random(double max) _PWX_VISIBLE _PWX_FORCEINLINE
12.228 - {
12.229 - if ( (max >= -0.0001) && (max <= 0.0001))
12.230 - return(0.0);
12.231 - else
12.232 - {
12.233 - int iRand = random();
12.234 - return(max * (double)((double)iRand / (double)RAND_MAX));
12.235 - }
12.236 - }
12.237 -
12.238 - /** @brief Generate a random value of double between min and max.
12.239 - *
12.240 - * @param min Specifies the desired minimum value.
12.241 - * @param max Specifies the desired maximum value.
12.242 - * @return A random value between min and max.
12.243 - */
12.244 - inline double _PWX_VISIBLE random(double min, double max) _PWX_VISIBLE _PWX_FORCEINLINE
12.245 - {
12.246 - if (max == min)
12.247 - return(max);
12.248 - else
12.249 - {
12.250 - // Can we use random(double max) ?
12.251 - if ((min == 0.0) || (max == 0.0))
12.252 - return(random(min == 0 ? max : min));
12.253 - else
12.254 - {
12.255 - double xMin = abs(max) > abs(min) ? min : max;
12.256 - double xMax = abs(min) < abs(max) ? max : min;
12.257 - return (random(xMax - xMin) + xMin);
12.258 - }
12.259 - }
12.260 - }
12.261 -
12.262 - /** @brief Generate a random value of long double between 0 and max.
12.263 - *
12.264 - * @param max Specifies the desired maximum value.
12.265 - * @return A random value between 0 and max.
12.266 - */
12.267 - inline long double _PWX_VISIBLE random(long double max) _PWX_VISIBLE _PWX_FORCEINLINE
12.268 - {
12.269 - if ( (max >= -0.0001) && (max <= 0.0001))
12.270 - return(0.0);
12.271 - else
12.272 - {
12.273 - int iRand = random();
12.274 - return(max * (long double)((long double)iRand / (long double)RAND_MAX));
12.275 - }
12.276 - }
12.277 -
12.278 - /** @brief Generate a random value of long double between min and max.
12.279 - *
12.280 - * @param min Specifies the desired minimum value.
12.281 - * @param max Specifies the desired maximum value.
12.282 - * @return A random value between min and max.
12.283 - */
12.284 - inline long double _PWX_VISIBLE random(long double min, long double max) _PWX_VISIBLE _PWX_FORCEINLINE
12.285 - {
12.286 - if (max == min)
12.287 - return(max);
12.288 - else
12.289 - {
12.290 - // Can we use random(long double max) ?
12.291 - if ((min == 0.0) || (max == 0.0))
12.292 - return(random(min == 0 ? max : min));
12.293 - else
12.294 - {
12.295 - long double xMin = abs(max) > abs(min) ? min : max;
12.296 - long double xMax = abs(min) < abs(max) ? max : min;
12.297 - return (random(xMax - xMin) + xMin);
12.298 - }
12.299 - }
12.300 - }
12.301 -
12.302 - // --- procedures ---
12.303 - /** @brief default ctor
12.304 - * Initializes the random number generator and assignes a first random value
12.305 - * to cLastValue.
12.306 - */
12.307 - Random(void)
12.308 - {
12.309 - srand(time(NULL));
12.310 - cLastValue = rand();
12.311 - }
12.312 - // --- operators ---
12.313 - protected:
12.314 - // --- attributes ---
12.315 - // --- virtual methods ---
12.316 - // --- functions ---
12.317 - // --- procedures ---
12.318 - // --- operators ---
12.319 - private:
12.320 - // --- attributes ---
12.321 - int cLastValue; //!< The last by rand() generated value
12.322 - // --- virtual methods ---
12.323 - // --- functions ---
12.324 - // --- procedures ---
12.325 - // --- operators ---
12.326 - };
12.327 -
12.328 - static Random RNG; //!< Static instance of Random to be used
12.329 -
12.330 - } // namespace pwx
12.331 -
12.332 -#endif // PWXRANDOM_H_INCLUDED
13.1 --- a/src/pwxSinCosTables.h Tue Sep 29 18:04:04 2009 +0200
13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
13.3 @@ -1,244 +0,0 @@
13.4 -#pragma once
13.5 -#ifndef PWXSINCOSTABLES_H_INCLUDED
13.6 -#define PWXSINCOSTABLES_H_INCLUDED 1
13.7 -
13.8 -/* pwxSinCosTables.h
13.9 - * ------------------
13.10 - * (c) 2007-2009 PrydeWorX
13.11 - * @Author: Sven Eden, PrydeWorX - Hamburg, Germany
13.12 - *
13.13 - * This file is provided as is and published under GPL license.
13.14 - * Do, whatever you feel like doeing with it, but please mention
13.15 - * me somewhere within the documentation of your project if you
13.16 - * find this usefull enough to actually use it. OpenSource4Ever!
13.17 - *
13.18 - * History:
13.19 - * --------
13.20 - * 14.02.2008 SE, PrydeWorX changed to be a class rather than global arrays
13.21 - * 20.02.2008 SE, PrydeWorX added sincos()
13.22 - * 16.01.2009 SE, PrydeWorX added life calculation for _PWX_SCTPREC == 0
13.23 - * 09.06.2009 SE, PrydeWorX some optimizations and new forcing of inlining
13.24 - */
13.25 -
13.26 -#ifndef _PWX_SCTPREC
13.27 -//! Define the depth of the arrays
13.28 -#define _PWX_SCTPREC 1000
13.29 -#endif // _PWX_SCTPREC
13.30 -#ifndef _PWX_SCTSIZE
13.31 -#define _PWX_SCTSIZE (360 * _PWX_SCTPREC)
13.32 -#endif // _PWX_SCTSIZE
13.33 -
13.34 -#ifndef _PWX_SCTOUTPUT
13.35 -//! Define whether or not to initialize with output
13.36 -#define _PWX_SCTOUTPUT false
13.37 -#endif // _PWX_SCTOUTPUT
13.38 -
13.39 -#include <cmath>
13.40 -#include <iostream>
13.41 -
13.42 -#ifndef M_PIl
13.43 -//! On some (non GNU) systems, the long version of M_PI is not defined, thus we do that here
13.44 -#define M_PIl 3.1415926535897932384626433832795029L /* pi */
13.45 -#endif // M_PIl
13.46 -
13.47 -namespace pwx
13.48 - {
13.49 -// #include "pwxDefaultDefines/defines.h"
13.50 -// changed locally for "Atomic Tanks"
13.51 -#include "pwxDefines.h"
13.52 -
13.53 - /** @brief Provides pre-calculated(*) sine and cosine tables
13.54 - *
13.55 - * Calculating sine and cosine values does not take much time
13.56 - * nowadays as FPUs get stronger every other day. On the other
13.57 - * hand, if you need these values for on-the-fly calculations
13.58 - * of something CPU-consuming like the display of 3D objects,
13.59 - * this little bit of CPU/FPU resources might better be saved.
13.60 - * Sin-/Cos-Tables with a precision of 3 take up about 8MB
13.61 - * (total), and this is not very much either.
13.62 - *
13.63 - * Tests show, that a Sin-/Cos-Tables with a precision of 3,
13.64 - * meaning 2 x 360,000 values in two arrays, do not differ from
13.65 - * on-the-fly calculation until the (worst case!) 6th digit.
13.66 - * (normally the first 7-8 digits are equal, which should be
13.67 - * enough for most applications. See the Test program (main.cpp)
13.68 - * for the tests!)<BR>
13.69 - *
13.70 - * (*) If you set _PWX_SCTPREC to 0 (zero), there will be no pre-defined
13.71 - * tables, but all sine and cosine values calculated life. You still do
13.72 - * not have to care about the range of your angles, and do not need to
13.73 - * transform angles to radiants.
13.74 - *
13.75 - * Usage:
13.76 - * <OL><LI>Alter _PWX_SCTPREC if you'd like to use a different
13.77 - * precision but 3, or define it yourself before including
13.78 - * this file. The default of 1000 means a precision of 3.</LI>
13.79 - * <LI>Set _PWX_SCTPREC to 0 if you prefer life calculations over
13.80 - * pre-calculated tables.</LI>
13.81 - * <LI>Normally the initialization is done silent. But if you need
13.82 - * a console output, when using a higher _PWX_SCTPREC for instance,
13.83 - * you can predefine _PWX_SCTOUTPUT to be true instead of false.</LI>
13.84 - * <LI>The file provides a static and initialized instance
13.85 - * of the class: pwx::SCT</LI>
13.86 - * <LI>Use the following functions to get the values:
13.87 - * <UL><LI>For Sine call pwx::SCT.sin (long double degree)</LI>
13.88 - * <LI>For Cosine call pwx::SCT.cos (long double degree)</LI>
13.89 - * <LI>For both call pwx::SCT.sincos(long double degree, long double
13.90 - * &sin, long double &cos)</LI></UL></OL>
13.91 - */
13.92 - class _PWX_INTERNAL SinCosTables
13.93 - {
13.94 - public:
13.95 - // --- attributes ---
13.96 - // --- virtual methods ---
13.97 - // --- functions ---
13.98 - /** @brief get cosine
13.99 - * This method gives the precalculated cosine of aDegree back.
13.100 - * Degrees < 0.0 or > 360.0 are adapted to be within the circles
13.101 - * range.
13.102 - * @param aDegree long double degree to be calculated.
13.103 - * @return The corresponding cosine.
13.104 - */
13.105 - inline long double _PWX_VISIBLE cos(long double aDegree) _PWX_USED _PWX_FORCEINLINE
13.106 - {
13.107 -#if (_PWX_SCTPREC > 0)
13.108 - int xIndex = getNormalizedDegree(aDegree);
13.109 - return(CosTable[xIndex]);
13.110 -#else
13.111 - long double ldDegree = getNormalizedDegree(aDegree);
13.112 - return(std::cos((ldDegree * M_Pil) / 180.0L));
13.113 -#endif // if (_PWX_SCTPREC > 0)
13.114 - }
13.115 -
13.116 - /** @brief get sine
13.117 - * This method gives the precalculated sine of aDegree back.
13.118 - * Degrees < 0.0 or > 360.0 are adapted to be within the circles
13.119 - * range.
13.120 - * @param aDegree long double degree to be calculated.
13.121 - * @return The corresponding sine.
13.122 - */
13.123 - inline long double _PWX_VISIBLE sin(long double aDegree) _PWX_USED _PWX_FORCEINLINE
13.124 - {
13.125 -#if (_PWX_SCTPREC > 0)
13.126 - int xIndex = getNormalizedDegree(aDegree);
13.127 - return(SinTable[xIndex]);
13.128 -#else
13.129 - long double ldDegree = getNormalizedDegree(aDegree);
13.130 - return(std::sin((ldDegree * M_Pil) / 180.0L));
13.131 -#endif // if (_PWX_SCTPREC > 0)
13.132 - }
13.133 - // --- procedures ---
13.134 - /** @brief get both, sine and cosine
13.135 - * This method gives the precalculated sine and cosine of aDegree
13.136 - * back by filling the provided references.<BR>
13.137 - * Degrees < 0.0 or > 360.0 are adapted to be within the circles
13.138 - * range.
13.139 - * @param aDegree long double degree to be calculated.
13.140 - * @param aSin Reference of a long double to get the corresponding sine
13.141 - * @param aCos Reference of a long double to get the corresponding cosine
13.142 - */
13.143 - inline void _PWX_VISIBLE sincos(long double aDegree,
13.144 - long double &aSin, long double &aCos) _PWX_USED _PWX_FORCEINLINE
13.145 - {
13.146 -#if (_PWX_SCTPREC > 0)
13.147 - int xIndex = getNormalizedDegree(aDegree);
13.148 - aSin = SinTable[xIndex];
13.149 - aCos = CosTable[xIndex];
13.150 -#else
13.151 - long double ldDegree = getNormalizedDegree(aDegree);
13.152 - long double ldRadian = (ldDegree * M_Pil) / 180.0L;
13.153 - aSin = std::sin(ldRadian);
13.154 - aCos = std::cos(ldRadian);
13.155 -#endif // if (_PWX_SCTPREC > 0)
13.156 - }
13.157 -
13.158 - /** @brief default ctor
13.159 - * Initializes the arrays. Predefine _PWX_SCTOUTPUT to be true prior
13.160 - * including this file to get a console output while initializing.
13.161 - * @param aWithOutput Defaults to false and is defined by _PWX_SCTOUTPUT
13.162 - */
13.163 - SinCosTables(bool aWithOutput = false)
13.164 - {
13.165 -#if (_PWX_SCTPREC > 0)
13.166 - unsigned int i = 0;
13.167 - long double xRadiant = 0.0;
13.168 -
13.169 - while ( i < _PWX_SCTSIZE )
13.170 - {
13.171 - /* sin() and cos() use radiant, so we have to recalc:
13.172 - * 360° = 2PI rad
13.173 - * => 1° = PI/180 rad
13.174 - * => x° = (x * PI)/180 rad
13.175 - */
13.176 - xRadiant = ( ( ( long double ) i / ( long double ) _PWX_SCTPREC ) * M_PIl ) / 180.0L;
13.177 - SinTable[i] = std::sin ( xRadiant );
13.178 - CosTable[i] = std::cos ( xRadiant );
13.179 - i++;
13.180 - if ( ( i % ( _PWX_SCTPREC * 36 ) == 0 ) && aWithOutput )
13.181 - {
13.182 - std::cout << " " << ( ( i / ( _PWX_SCTPREC * 36 ) ) *10 ) << "%";
13.183 - std::cout.flush();
13.184 - }
13.185 - }
13.186 - if (aWithOutput)
13.187 - {
13.188 - std::cout << endl << "SinCosTables initialized!";
13.189 - std::cout.flush();
13.190 - }
13.191 -#else
13.192 - if (aWithOutput)
13.193 - {
13.194 - std::cout << "SinCosTables omited, SCT configured for life calculations!";
13.195 - std::cout.flush();
13.196 - }
13.197 -#endif // if (_PWX_SCTPREC > 0)
13.198 - if (aWithOutput)
13.199 - {
13.200 - std::cout << endl;
13.201 - std::cout.flush();
13.202 - }
13.203 - }
13.204 - // --- operators ---
13.205 - protected:
13.206 - // --- attributes ---
13.207 - // --- virtual methods ---
13.208 - // --- functions ---
13.209 - // --- procedures ---
13.210 - // --- operators ---
13.211 - private:
13.212 - // --- attributes ---
13.213 -#if (_PWX_SCTPREC > 0)
13.214 - long double SinTable[_PWX_SCTSIZE]; //!< Internal array with precalculated sine values
13.215 - long double CosTable[_PWX_SCTSIZE]; //!< Internal array with precalculated cosine values
13.216 -#endif // if (_PWX_SCTPREC > 0)
13.217 - // --- virtual methods ---
13.218 - // --- functions ---
13.219 -#if (_PWX_SCTPREC > 0)
13.220 - inline int getNormalizedDegree(long double aDegree) _PWX_INTERNAL _PWX_FORCEINLINE
13.221 - {
13.222 - int iDegree = (int)round(aDegree * _PWX_SCTPREC);
13.223 - int iMaxSize= _PWX_SCTSIZE * 10;
13.224 - while (abs(iDegree) >= iMaxSize) iDegree /= 10;
13.225 - while (iDegree >= _PWX_SCTSIZE) iDegree -= _PWX_SCTSIZE;
13.226 - while (iDegree < 0) iDegree += _PWX_SCTSIZE;
13.227 - return (iDegree);
13.228 - }
13.229 -#else
13.230 - inline long double getNormalizedDegree(long double aDegree) _PWX_INTERNAL _PWX_FORCEINLINE
13.231 - {
13.232 - long double ldDegree = (long double)round(aDegree * (long double)_PWX_SCTPREC);
13.233 - while (fabs(ldDegree) >= 3600.0L) ldDegree /= 10.0L;
13.234 - while (ldDegree >= 360.0L) ldDegree -= 360.0L;
13.235 - while (ldDegree < 0.0L) ldDegree += 360.0L;
13.236 - return (ldDegree);
13.237 - }
13.238 -#endif // if (_PWX_SCTPREC > 0)
13.239 - // --- procedures ---
13.240 - // --- operators ---
13.241 - };
13.242 -
13.243 - static SinCosTables SCT(_PWX_SCTOUTPUT); //!< Static instance of SinCosTables to be used
13.244 -
13.245 - } // namespace
13.246 -
13.247 -#endif // PWXSINCOSTABLES_H_INCLUDED