From 5bd3b8d6afa9b3d27bf499a52bd5da37906615b8 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Fri, 20 Nov 2015 19:41:27 +0000 Subject: [PATCH] Implement util_rand due to rand having a poor range on some platforms --- src/audio/audio.c | 2 +- src/network/network.cpp | 2 +- src/rct2.c | 3 ++- src/title.c | 10 ++++---- src/util/util.c | 18 ++++++++++++++ src/util/util.h | 3 +++ src/windows/editor_inventions_list.c | 3 ++- src/windows/guest.c | 3 ++- src/windows/mapgen.c | 5 ++-- src/windows/top_toolbar.c | 11 +++++---- src/world/balloon.c | 3 ++- src/world/climate.c | 3 ++- src/world/mapgen.c | 37 ++++++++++++++-------------- src/world/particle.c | 13 +++++----- 14 files changed, 73 insertions(+), 43 deletions(-) diff --git a/src/audio/audio.c b/src/audio/audio.c index 02f67c061e..a70b6da527 100644 --- a/src/audio/audio.c +++ b/src/audio/audio.c @@ -177,7 +177,7 @@ void start_title_music() musicPathId = PATH_ID_CSS17; break; case 3: - if (rand() & 1) + if (util_rand() & 1) musicPathId = PATH_ID_CSS50; else musicPathId = PATH_ID_CSS17; diff --git a/src/network/network.cpp b/src/network/network.cpp index d4f2e2923a..0d67273cd1 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -832,7 +832,7 @@ std::string Network::GenerateAdvertiseKey() static char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; char key[17]; for (int i = 0; i < 16; i++) { - int hexCharIndex = rand() % countof(hexChars); + int hexCharIndex = util_rand() % countof(hexChars); key[i] = hexChars[hexCharIndex]; } key[countof(key) - 1] = 0; diff --git a/src/rct2.c b/src/rct2.c index 560db3ab9a..571a7e696a 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -47,6 +47,7 @@ #include "ride/track.h" #include "scenario.h" #include "title.h" +#include "util/util.h" #include "world/map.h" #include "world/park.h" #include "world/climate.h" @@ -79,7 +80,7 @@ int rct2_init() RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, uint32) = 0; RCT2_GLOBAL(0x009AC310, char*) = RCT2_GLOBAL(RCT2_ADDRESS_CMDLINE, char*); get_system_time(); - srand((unsigned int)time(0)); + util_srand((unsigned int)time(0)); RCT2_GLOBAL(0x009DEA69, short) = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_DAY, short); RCT2_GLOBAL(0x009DEA6B, short) = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_MONTH, short); if (!rct2_init_directories()) diff --git a/src/title.c b/src/title.c index 1b8abc325a..0bd9c0c6d9 100644 --- a/src/title.c +++ b/src/title.c @@ -524,24 +524,24 @@ static uint8 *generate_random_script() int i, j; const int views = 16; - srand((unsigned int)time(NULL)); + util_srand((unsigned int)time(NULL)); uint8 *script = malloc(views * 8 + 2); i = 0; script[i++] = TITLE_SCRIPT_LOAD; for (j = 0; j < views; j++) { script[i++] = TITLE_SCRIPT_LOCATION; - script[i++] = 64 + (rand() % 128); - script[i++] = 64 + (rand() % 128); + script[i++] = 64 + (util_rand() % 128); + script[i++] = 64 + (util_rand() % 128); - int rotationCount = rand() % 4; + int rotationCount = util_rand() % 4; if (rotationCount > 0) { script[i++] = TITLE_SCRIPT_ROTATE; script[i++] = rotationCount; } script[i++] = TITLE_SCRIPT_WAIT; - script[i++] = 8 + (rand() % 6); + script[i++] = 8 + (util_rand() % 6); } script[i] = TITLE_SCRIPT_RESTART; diff --git a/src/util/util.c b/src/util/util.c index bfccdfa706..890423e0fd 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -220,3 +220,21 @@ bool str_is_null_or_empty(const char *str) { return str == NULL || str[0] == 0; } + +uint32 srand0, srand1, srand2, srand3; + +void util_srand(int source) { + srand0 = source; + srand1 = srand0 ^ (source >> 24); + srand2 = srand1 ^ (source >> 16); + srand3 = srand2 ^ (source >> 8); +} + +uint32 util_rand() { + uint32 temp = srand0 ^ (srand0 << 11); + srand0 = srand1; + srand1 = srand2; + srand2 = srand3; + srand3 = srand3 ^ (srand3 >> 19) ^ temp ^ (temp >> 8); + return srand3; +} \ No newline at end of file diff --git a/src/util/util.h b/src/util/util.h index 8eba3a2b3f..23ea66c2d2 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -44,4 +44,7 @@ char *safe_strncpy(char * destination, const char * source, size_t num); bool utf8_is_bom(const char *str); bool str_is_null_or_empty(const char *str); +void util_srand(int source); +uint32 util_rand(); + #endif diff --git a/src/windows/editor_inventions_list.c b/src/windows/editor_inventions_list.c index c88b5ae741..a8396b77d1 100644 --- a/src/windows/editor_inventions_list.c +++ b/src/windows/editor_inventions_list.c @@ -29,6 +29,7 @@ #include "../world/scenery.h" #include "../interface/themes.h" #include "../rct1.h" +#include "../util/util.h" #pragma region Widgets @@ -344,7 +345,7 @@ static void research_items_shuffle() // Shuffle list for (i = 0; i < numNonResearchedItems; i++) { - ri = rand() % numNonResearchedItems; + ri = util_rand() % numNonResearchedItems; if (ri == i) continue; diff --git a/src/windows/guest.c b/src/windows/guest.c index 3c5870e649..2a9eb29bdd 100644 --- a/src/windows/guest.c +++ b/src/windows/guest.c @@ -35,6 +35,7 @@ #include "../interface/viewport.h" #include "../interface/widget.h" #include "../interface/window.h" +#include "../util/util.h" #include "../world/footpath.h" #include "../world/map.h" #include "../world/sprite.h" @@ -1089,7 +1090,7 @@ void window_guest_overview_update(rct_window* w){ // Create the "I have the strangest feeling I am being watched thought" if ((w->var_494 & 0xFFFF) >= 3840) { if (!(w->var_494 & 0x3FF)) { - int random = rand() & 0xFFFF; + int random = util_rand() & 0xFFFF; if (random <= 0x2AAA) { rct_peep* peep = GET_PEEP(w->number); peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_WATCHED, 0xFF); diff --git a/src/windows/mapgen.c b/src/windows/mapgen.c index 2c46c69e47..03cb6a5e18 100644 --- a/src/windows/mapgen.c +++ b/src/windows/mapgen.c @@ -25,6 +25,7 @@ #include "../interface/viewport.h" #include "../interface/window.h" #include "../sprites.h" +#include "../util/util.h" #include "../world/mapgen.h" #include "../world/scenery.h" #include "dropdown.h" @@ -716,8 +717,8 @@ static void window_mapgen_random_mouseup(rct_window *w, int widgetIndex) mapgenSettings.wall = _randomTerrrain ? -1 : _wallTexture; mapgenSettings.trees = _placeTrees; - mapgenSettings.simplex_low = rand() % 4; - mapgenSettings.simplex_high = 12 + (rand() % (32 - 12)); + mapgenSettings.simplex_low = util_rand() % 4; + mapgenSettings.simplex_high = 12 + (util_rand() % (32 - 12)); mapgenSettings.simplex_base_freq = 1.75f; mapgenSettings.simplex_octaves = 6; diff --git a/src/windows/top_toolbar.c b/src/windows/top_toolbar.c index 0d8f55b6da..ec8aa31f61 100644 --- a/src/windows/top_toolbar.c +++ b/src/windows/top_toolbar.c @@ -34,6 +34,7 @@ #include "../network/network.h" #include "../network/twitch.h" #include "../scenario.h" +#include "../util/util.h" #include "../world/scenery.h" #include "../world/banner.h" #include "dropdown.h" @@ -1116,7 +1117,7 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin uint8 rotation = window_scenery_rotation; if (!(scenery->small_scenery.flags & SMALL_SCENERY_FLAG4)){ - rotation = rand() & 0xFF; + rotation = util_rand() & 0xFF; } rotation -= get_current_rotation(); @@ -1194,7 +1195,7 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin uint8 rotation = window_scenery_rotation; if (!(scenery->small_scenery.flags & SMALL_SCENERY_FLAG4)){ - rotation = rand() & 0xFF; + rotation = util_rand() & 0xFF; } rotation -= get_current_rotation(); @@ -1440,11 +1441,11 @@ static void window_top_toolbar_scenery_tool_down(short x, short y, rct_window *w if (window_scenery_is_build_cluster_tool_on){ if (!(scenery->small_scenery.flags & SMALL_SCENERY_FLAG_FULL_TILE)){ parameter_2 &= 0xFF00; - parameter_2 |= rand() & 3; + parameter_2 |= util_rand() & 3; } - cur_grid_x += ((rand() % 16) - 8) * 32; - cur_grid_y += ((rand() % 16) - 8) * 32; + cur_grid_x += ((util_rand() % 16) - 8) * 32; + cur_grid_y += ((util_rand() % 16) - 8) * 32; if (!(scenery->small_scenery.flags & SMALL_SCENERY_FLAG4)){ RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_ROTATION, uint16)++; diff --git a/src/world/balloon.c b/src/world/balloon.c index 62de010dfe..6db5b5a0a0 100644 --- a/src/world/balloon.c +++ b/src/world/balloon.c @@ -1,5 +1,6 @@ #include "../audio/audio.h" #include "../scenario.h" +#include "../util/util.h" #include "sprite.h" /** @@ -68,7 +69,7 @@ void balloon_press(rct_balloon *balloon) if (balloon->popped == 1) return; - uint32 random = rand(); + uint32 random = util_rand(); if ((balloon->var_0A & 7) || (random & 0xFFFF) < 0x2000) { balloon_pop(balloon); return; diff --git a/src/world/climate.c b/src/world/climate.c index 5692acb13b..5448e8b27f 100644 --- a/src/world/climate.c +++ b/src/world/climate.c @@ -27,6 +27,7 @@ #include "../localisation/date.h" #include "../scenario.h" #include "../interface/window.h" +#include "../util/util.h" #include "climate.h" enum { @@ -115,7 +116,7 @@ void climate_reset(int climate) _rainVolume = 1; } - climate_determine_future_weather(rand()); + climate_determine_future_weather(util_rand()); } sint8 step_weather_level(sint8 cur_weather_level, sint8 next_weather_level) { diff --git a/src/world/mapgen.c b/src/world/mapgen.c index 6d89306220..4650b4307e 100644 --- a/src/world/mapgen.c +++ b/src/world/mapgen.c @@ -21,6 +21,7 @@ #include #include "../addresses.h" #include "../object.h" +#include "../util/util.h" #include "map.h" #include "map_helpers.h" #include "mapgen.h" @@ -126,7 +127,7 @@ void mapgen_generate(mapgen_settings *settings) int x, y, mapSize, floorTexture, wallTexture, waterLevel; rct_map_element *mapElement; - srand((unsigned int)time(NULL)); + util_srand((unsigned int)time(NULL)); mapSize = settings->mapSize; floorTexture = settings->floor; @@ -134,7 +135,7 @@ void mapgen_generate(mapgen_settings *settings) waterLevel = settings->waterLevel; if (floorTexture == -1) - floorTexture = BaseTerrain[rand() % countof(BaseTerrain)]; + floorTexture = BaseTerrain[util_rand() % countof(BaseTerrain)]; if (wallTexture == -1) { // Base edge type on surface type @@ -172,7 +173,7 @@ void mapgen_generate(mapgen_settings *settings) if (1) { mapgen_simplex(settings); - mapgen_smooth_height(2 + (rand() % 6)); + mapgen_smooth_height(2 + (util_rand() % 6)); } else { // Keep overwriting the map with rough cicular blobs of different sizes and heights. // This procedural method can produce intersecting contour like land and lakes. @@ -200,7 +201,7 @@ void mapgen_generate(mapgen_settings *settings) // Add sandy beaches int beachTexture = floorTexture; if (settings->floor == -1 && floorTexture == TERRAIN_GRASS) { - switch (rand() % 4) { + switch (util_rand() % 4) { case 0: beachTexture = TERRAIN_SAND; break; @@ -235,7 +236,7 @@ static void mapgen_place_tree(int type, int x, int y) mapElement = map_element_insert(x, y, surfaceZ, (1 | 2 | 4 | 8)); mapElement->clearance_height = surfaceZ + (sceneryEntry->small_scenery.height >> 3); - mapElement->type = MAP_ELEMENT_TYPE_SCENERY | (rand() % 3); + mapElement->type = MAP_ELEMENT_TYPE_SCENERY | (util_rand() % 3); mapElement->properties.scenery.type = type; mapElement->properties.scenery.age = 0; mapElement->properties.scenery.colour_1 = 26; @@ -310,7 +311,7 @@ static void mapgen_place_trees() // Shuffle list for (i = 0; i < availablePositionsCount; i++) { - rindex = rand() % availablePositionsCount; + rindex = util_rand() % availablePositionsCount; if (rindex == i) continue; @@ -320,7 +321,7 @@ static void mapgen_place_trees() } // Place trees - float treeToLandRatio = (10 + (rand() % 30)) / 100.0f; + float treeToLandRatio = (10 + (util_rand() % 30)) / 100.0f; int numTrees = max(4, (int)(availablePositionsCount * treeToLandRatio)); mapSize = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, sint16); @@ -336,7 +337,7 @@ static void mapgen_place_trees() if (numGrassTreeIds == 0) break; - type = grassTreeIds[rand() % numGrassTreeIds]; + type = grassTreeIds[util_rand() % numGrassTreeIds]; break; case TERRAIN_SAND: @@ -345,15 +346,15 @@ static void mapgen_place_trees() if (numDesertTreeIds == 0) break; - if (rand() % 4 == 0) - type = desertTreeIds[rand() % numDesertTreeIds]; + if (util_rand() % 4 == 0) + type = desertTreeIds[util_rand() % numDesertTreeIds]; break; case TERRAIN_ICE: if (numSnowTreeIds == 0) break; - type = snowTreeIds[rand() % numSnowTreeIds]; + type = snowTreeIds[util_rand() % numSnowTreeIds]; break; } @@ -392,15 +393,15 @@ static void mapgen_blobs(int count, int lowSize, int highSize, int lowHeight, in int sizeRange = highSize - lowSize; int heightRange = highHeight - lowHeight; - int border = 2 + (rand() % 24); + int border = 2 + (util_rand() % 24); int borderRange = _heightSize - (border * 2); for (i = 0; i < count; i++) { - int radius = lowSize + (rand() % sizeRange); + int radius = lowSize + (util_rand() % sizeRange); mapgen_blob( - border + (rand() % borderRange), - border + (rand() % borderRange), + border + (util_rand() % borderRange), + border + (util_rand() % borderRange), (int)(M_PI * radius * radius), - lowHeight + (rand() % heightRange) + lowHeight + (util_rand() % heightRange) ); } } @@ -506,7 +507,7 @@ static void mapgen_blob(int cx, int cy, int size, int height) set_height(x, y, BLOB_HEIGHT); while (currentSize < size) { - if (rand() % 2 == 0) { + if (util_rand() % 2 == 0) { set_height(x, y, BLOB_HEIGHT); currentSize++; } @@ -655,7 +656,7 @@ static uint8 perm[512]; static void noise_rand() { for (int i = 0; i < countof(perm); i++) - perm[i] = rand() & 0xFF; + perm[i] = util_rand() & 0xFF; } static float fractal_noise(int x, int y, float frequency, int octaves, float lacunarity, float persistence) diff --git a/src/world/particle.c b/src/world/particle.c index 1636b3ac42..0b754193cd 100644 --- a/src/world/particle.c +++ b/src/world/particle.c @@ -1,4 +1,5 @@ #include "../audio/audio.h" +#include "../util/util.h" #include "sprite.h" /** @@ -18,12 +19,12 @@ void crashed_vehicle_particle_create(rct_vehicle_colour colours, int x, int y, i sprite_move(x, y, z + 4, (rct_sprite*)sprite); sprite->misc_identifier = SPRITE_MISC_CRASHED_VEHICLE_PARTICLE; - sprite->var_26 = (rand() & 0xFF) * 12; - sprite->var_24 = (rand() & 0x7F) + 140; - sprite->var_2E = ((rand() & 0xFF) * 5) >> 8; - sprite->acceleration_x = (rand() & 0xFFFF) * 4; - sprite->acceleration_y = (rand() & 0xFFFF) * 4; - sprite->acceleration_z = (rand() & 0xFFFF) * 4 + 0x10000; + sprite->var_26 = (util_rand() & 0xFF) * 12; + sprite->var_24 = (util_rand() & 0x7F) + 140; + sprite->var_2E = ((util_rand() & 0xFF) * 5) >> 8; + sprite->acceleration_x = (util_rand() & 0xFFFF) * 4; + sprite->acceleration_y = (util_rand() & 0xFFFF) * 4; + sprite->acceleration_z = (util_rand() & 0xFFFF) * 4 + 0x10000; sprite->velocity_x = 0; sprite->velocity_y = 0; sprite->velocity_z = 0;