diff --git a/src/CRE/effect.cpp b/src/CRE/effect.cpp index bcc1b2f2..c0962b4c 100644 --- a/src/CRE/effect.cpp +++ b/src/CRE/effect.cpp @@ -2591,7 +2591,7 @@ void EffectFogRing::draw_static(render_data_context& rend_data_ctx, void* data, } float_t EffectFogRing::ptcl_random(float_t value) { - return (float_t)(rand_state_array_get_int(4) % 10000) * 0.0001f * value * 2.0f - value; + return (float_t)(Random(RANDOM_TYPE_GLOBAL) % 10000) * 0.0001f * value * 2.0f - value; } void EffectFogRing::sub_140347B40(float_t delta_time) { @@ -3470,10 +3470,10 @@ void EffectRipple::sub_140358690() { v1.data.color = field_50.color; for (int32_t i = 0; i < 16; i++) { - v1.data.position[i].x = rand_state_array_get_float(4) * 1.8f - 0.9f; - v1.data.position[i].y = rand_state_array_get_float(4) * 1.8f - 0.9f; - rand_state_array_get_int(0x03, 0x07, 4); - v1.data.position[i].z = (float_t)rand_state_array_get_int(0x20, 0xA0, 4); + v1.data.position[i].x = RandomF(RANDOM_TYPE_GLOBAL) * 1.8f - 0.9f; + v1.data.position[i].y = RandomF(RANDOM_TYPE_GLOBAL) * 1.8f - 0.9f; + Random(0x03, 0x07, RANDOM_TYPE_GLOBAL); + v1.data.position[i].z = (float_t)Random(0x20, 0xA0, RANDOM_TYPE_GLOBAL); } v1.data.count = 16; @@ -3560,23 +3560,23 @@ void EffectRipple::sub_14035AAE0() { min_value = min_def(min_value, 126); for (int32_t i = 0; i < rain_ripple_num; i++) { - v1.data.position[i].x = (float_t)(rand_state_array_get_int(4) % 1000) * 0.001f * 2.0f - 1.0f; + v1.data.position[i].x = (float_t)(Random(RANDOM_TYPE_GLOBAL) % 1000) * 0.001f * 2.0f - 1.0f; v1.data.position[i].y = 0.0f; - v1.data.position[i].y = (float_t)(rand_state_array_get_int(4) % 1000) * 0.001f * 2.0f - 1.0f; + v1.data.position[i].y = (float_t)(Random(RANDOM_TYPE_GLOBAL) % 1000) * 0.001f * 2.0f - 1.0f; v1.data.color[i] = { 0x00, 0x00, 0x00, - (uint8_t)(0x7F - rand_state_array_get_int(4) % max_value - min_value) }; + (uint8_t)(0x7F - Random(RANDOM_TYPE_GLOBAL) % max_value - min_value) }; v1.data.count++; } } for (size_t i = 0; i < emitter_num; i++) { float_t v10 = emitter_list[i].z; - v1.data.position[i].x = ((rand_state_array_get_float(4) - 0.5f) + v1.data.position[i].x = ((RandomF(RANDOM_TYPE_GLOBAL) - 0.5f) * v10 + emitter_list[i].x) * emit_pos_scale; v1.data.position[i].y = 0.0f; - v1.data.position[i].z = ((rand_state_array_get_float(4) - 0.5f) + v1.data.position[i].z = ((RandomF(RANDOM_TYPE_GLOBAL) - 0.5f) * v10 + emitter_list[i].y) * emit_pos_scale; - v1.data.color[i] = rand_state_array_get_float(4) < 0.5f + v1.data.color[i] = RandomF(RANDOM_TYPE_GLOBAL) < 0.5f ? color4u8(0x00, 0x00, 0x00, 0xFF) : color4u8(0x00); v1.data.count++; } @@ -3625,10 +3625,10 @@ void EffectRipple::sub_14035AED0() { if (use_float_ripplemap) sub_1403587C0(pos, rob_colli.old_pos, scale, v2.data, v3.data); else if (v2.data.count < 16) { - v2.data.position[v2.data.count].x = ((rand_state_array_get_float(4) - 0.5f) + v2.data.position[v2.data.count].x = ((RandomF(RANDOM_TYPE_GLOBAL) - 0.5f) * 0.02f + pos.x) * emit_pos_scale + emit_pos_ofs_x; v2.data.position[v2.data.count].y = pos.y; - v2.data.position[v2.data.count].z = ((rand_state_array_get_float(4) - 0.5f) + v2.data.position[v2.data.count].z = ((RandomF(RANDOM_TYPE_GLOBAL) - 0.5f) * 0.02f + pos.z) * emit_pos_scale + emit_pos_ofs_z; v2.data.color[v2.data.count] = { 0x00, 0x00, 0x00, 0x00 }; v2.data.count++; @@ -5023,17 +5023,17 @@ static bool effect_array_parse_stage_param_data_star(stage_param_star* star, int void leaf_particle_data::init() { stage_param_leaf* leaf = stage_param_data_leaf_current; - position.x = rand_state_array_get_float(4); - position.y = rand_state_array_get_float(4); - position.z = rand_state_array_get_float(4); + position.x = RandomF(RANDOM_TYPE_GLOBAL); + position.y = RandomF(RANDOM_TYPE_GLOBAL); + position.z = RandomF(RANDOM_TYPE_GLOBAL); position = (position * vec3(2.0f, 1.0f, 2.0f) - vec3(1.0f, 0.0f, 1.0f)) * leaf->range + leaf->offset; direction = vec3(0.0f, -1.0f, 0.0f); normal = vec3(0.0f, 0.0f, 1.0f); - rotation.x = rand_state_array_get_float(4) * 6.28f; - rotation.y = rand_state_array_get_float(4) * 6.28f; + rotation.x = RandomF(RANDOM_TYPE_GLOBAL) * 6.28f; + rotation.y = RandomF(RANDOM_TYPE_GLOBAL) * 6.28f; rotation.z = 0.0f; - rotation_add.x = (rand_state_array_get_float(4) + 1.0f) * 3.0f; - rotation_add.y = (rand_state_array_get_float(4) + 1.0f) * 3.0f; + rotation_add.x = (RandomF(RANDOM_TYPE_GLOBAL) + 1.0f) * 3.0f; + rotation_add.y = (RandomF(RANDOM_TYPE_GLOBAL) + 1.0f) * 3.0f; rotation_add.z = 10.0f; type = 1; size = leaf->psize; @@ -6271,16 +6271,16 @@ static void particle_event(particle_event_data* event_data) { break; data->position = pos; - data->rotation.x = rand_state_array_get_float(4) * 6.28f; - data->rotation.y = rand_state_array_get_float(4) * 6.28f; + data->rotation.x = RandomF(RANDOM_TYPE_GLOBAL) * 6.28f; + data->rotation.y = RandomF(RANDOM_TYPE_GLOBAL) * 6.28f; vec3 direction = vec3(cosf(data->rotation.x), 0.0f, sinf(data->rotation.x)); - data->direction = direction * (rand_state_array_get_float(4) * force); + data->direction = direction * (RandomF(RANDOM_TYPE_GLOBAL) * force); data->normal = vec3(0.0f, 0.0f, 1.0f); - data->rotation_add.x = (rand_state_array_get_float(4) + 1.0f) * 5.0f; - data->rotation_add.y = (rand_state_array_get_float(4) + 1.0f) * 2.5f; + data->rotation_add.x = (RandomF(RANDOM_TYPE_GLOBAL) + 1.0f) * 5.0f; + data->rotation_add.y = (RandomF(RANDOM_TYPE_GLOBAL) + 1.0f) * 2.5f; data->rotation_add.z = 20.0f; - int32_t color_rand = rand_state_array_get_int(0, 2, 4); + int32_t color_rand = Random(0, 2, RANDOM_TYPE_GLOBAL); data->color = color[color_rand]; data->type = type; data->life_time = 10.0f; @@ -6288,8 +6288,8 @@ static void particle_event(particle_event_data* event_data) { } } else if (type == 2.0f) { - float_t v13 = rand_state_array_get_float(4) * (float_t)(M_PI * 2.0); - float_t v14 = rand_state_array_get_float(4) * (float_t)(144.0 * DEG_TO_RAD); + float_t v13 = RandomF(RANDOM_TYPE_GLOBAL) * (float_t)(M_PI * 2.0); + float_t v14 = RandomF(RANDOM_TYPE_GLOBAL) * (float_t)(144.0 * DEG_TO_RAD); float_t v15 = sinf(v14); vec3 direction; @@ -6304,11 +6304,11 @@ static void particle_event(particle_event_data* event_data) { data->position = pos; data->normal = vec3(0.0f, 0.0f, 1.0f); - data->rotation.x = rand_state_array_get_float(4) * 6.28f; - data->rotation.y = rand_state_array_get_float(4) * 6.28f; - data->direction = direction * ((rand_state_array_get_float(4) + 1.0f) * force); - data->rotation_add.x = (rand_state_array_get_float(4) + 1.0f) * 5.0f; - data->rotation_add.y = (rand_state_array_get_float(4) + 1.0f) * 2.5f; + data->rotation.x = RandomF(RANDOM_TYPE_GLOBAL) * 6.28f; + data->rotation.y = RandomF(RANDOM_TYPE_GLOBAL) * 6.28f; + data->direction = direction * ((RandomF(RANDOM_TYPE_GLOBAL) + 1.0f) * force); + data->rotation_add.x = (RandomF(RANDOM_TYPE_GLOBAL) + 1.0f) * 5.0f; + data->rotation_add.y = (RandomF(RANDOM_TYPE_GLOBAL) + 1.0f) * 2.5f; data->rotation_add.z = 20.0f; data->color.x = 5.0; data->color.y = 4.5; @@ -6360,9 +6360,9 @@ static void rain_particle_init(bool change_stage) { data.alpha = 1.0f; data.life_time = 1; vec3 _velocity; - _velocity.x = rand_state_array_get_float(4); - _velocity.y = rand_state_array_get_float(4); - _velocity.z = rand_state_array_get_float(4); + _velocity.x = RandomF(RANDOM_TYPE_GLOBAL); + _velocity.y = RandomF(RANDOM_TYPE_GLOBAL); + _velocity.z = RandomF(RANDOM_TYPE_GLOBAL); data.velocity = (_velocity - 0.5f) * vel_range + velocity; } @@ -6374,9 +6374,9 @@ static void rain_particle_init(bool change_stage) { vec3* vtx_data = prj::MemoryManager::alloc(prj::MemCTemp, rain_ptcl_count, "init_rain"); for (int32_t i = 0; i < rain_ptcl_count; i++) { vec3 position; - position.x = rand_state_array_get_float(4); - position.y = rand_state_array_get_float(4); - position.z = rand_state_array_get_float(4); + position.x = RandomF(RANDOM_TYPE_GLOBAL); + position.y = RandomF(RANDOM_TYPE_GLOBAL); + position.z = RandomF(RANDOM_TYPE_GLOBAL); *vtx_data++ = position; } @@ -6472,29 +6472,29 @@ static void snow_particle_init(bool change_stage) { particle_data* snow_ptcl = snow_ptcl_data; for (int32_t i = ((stage_param_data_snow_current->num_snow - 1) >> 1) + 1; i; i--, snow_ptcl += 2) { vec3 position; - position.x = rand_state_array_get_float(4) - 0.5f; - position.y = rand_state_array_get_float(4); - position.z = rand_state_array_get_float(4) - 0.5f; + position.x = RandomF(RANDOM_TYPE_GLOBAL) - 0.5f; + position.y = RandomF(RANDOM_TYPE_GLOBAL); + position.z = RandomF(RANDOM_TYPE_GLOBAL) - 0.5f; snow_ptcl[0].position = position * range + offset; - snow_ptcl[0].size = rand_state_array_get_float(4) * 0.4f + 0.3f; - snow_ptcl[0].alpha = rand_state_array_get_float(4) * 0.5f + 0.4f; + snow_ptcl[0].size = RandomF(RANDOM_TYPE_GLOBAL) * 0.4f + 0.3f; + snow_ptcl[0].alpha = RandomF(RANDOM_TYPE_GLOBAL) * 0.5f + 0.4f; snow_ptcl[0].life_time = 1; vec3 _velocity; - _velocity.x = rand_state_array_get_float(4); - _velocity.y = rand_state_array_get_float(4); - _velocity.z = rand_state_array_get_float(4); + _velocity.x = RandomF(RANDOM_TYPE_GLOBAL); + _velocity.y = RandomF(RANDOM_TYPE_GLOBAL); + _velocity.z = RandomF(RANDOM_TYPE_GLOBAL); snow_ptcl[0].velocity = (_velocity - 0.5f) * vel_range + velocity; snow_ptcl[0].direction = 0.0f; - snow_ptcl[1].size = ((rand_state_array_get_float(4) * 0.5f) + 0.3f) * snow_ptcl[0].size; - snow_ptcl[1].alpha = (rand_state_array_get_float(4) + 1.0f) * 0.3f; + snow_ptcl[1].size = ((RandomF(RANDOM_TYPE_GLOBAL) * 0.5f) + 0.3f) * snow_ptcl[0].size; + snow_ptcl[1].alpha = (RandomF(RANDOM_TYPE_GLOBAL) + 1.0f) * 0.3f; - _velocity.x = rand_state_array_get_float(4); - _velocity.y = rand_state_array_get_float(4); - _velocity.z = rand_state_array_get_float(4); + _velocity.x = RandomF(RANDOM_TYPE_GLOBAL); + _velocity.y = RandomF(RANDOM_TYPE_GLOBAL); + _velocity.z = RandomF(RANDOM_TYPE_GLOBAL); snow_ptcl[1].velocity = (_velocity - 0.5f) * 0.035f * (snow_ptcl[1].size + snow_ptcl[0].size); snow_ptcl[0].size = snow_particle_size_mid * snow_ptcl[0].size; @@ -6513,9 +6513,9 @@ static void snow_particle_init(bool change_stage) { i.life_time = 1; vec3 _velocity; - _velocity.x = rand_state_array_get_float(4); - _velocity.y = rand_state_array_get_float(4); - _velocity.z = rand_state_array_get_float(4); + _velocity.x = RandomF(RANDOM_TYPE_GLOBAL); + _velocity.y = RandomF(RANDOM_TYPE_GLOBAL); + _velocity.z = RandomF(RANDOM_TYPE_GLOBAL); i.velocity = (_velocity - 0.5f) * vel_range + velocity; i.direction = 0.0f; } @@ -6540,10 +6540,10 @@ static void snow_particle_init(bool change_stage) { snow_particle_gpu_vertex_data* vtx_data = force_malloc(snow_ptcl_count); for (int32_t i = 0; i < snow_ptcl_count; i++, vtx_data++) { - vtx_data->position.x = rand_state_array_get_float(4); - vtx_data->position.y = rand_state_array_get_float(4); - vtx_data->position.z = rand_state_array_get_float(4); - vtx_data->size = (rand_state_array_get_float(4) * 0.5f + 0.4f) * snow_particle_size_mid; + vtx_data->position.x = RandomF(RANDOM_TYPE_GLOBAL); + vtx_data->position.y = RandomF(RANDOM_TYPE_GLOBAL); + vtx_data->position.z = RandomF(RANDOM_TYPE_GLOBAL); + vtx_data->size = (RandomF(RANDOM_TYPE_GLOBAL) * 0.5f + 0.4f) * snow_particle_size_mid; } vtx_data -= snow_ptcl_count; @@ -6589,7 +6589,7 @@ static void snow_particle_ctrl() { if (--snow_ptcl[0].life_time > 0) direction = snow_ptcl[0].direction; else { - snow_ptcl[0].life_time = rand_state_array_get_int(15, 35, 4); + snow_ptcl[0].life_time = Random(15, 35, RANDOM_TYPE_GLOBAL); direction = snow_particle_get_random_velocity(); snow_ptcl[0].direction = direction; } @@ -6620,7 +6620,7 @@ static void snow_particle_ctrl() { if (--i.life_time > 0) direction = i.direction; else { - i.life_time = rand_state_array_get_int(0xFu, 0x23u, 4); + i.life_time = Random(15, 35, RANDOM_TYPE_GLOBAL); direction = snow_particle_get_random_velocity(); i.direction = direction; } @@ -6684,10 +6684,10 @@ static void snow_particle_data_emit_fallen(particle_data* data) { if (!d) break; - d->position.x = (rand_state_array_get_float(4) - 0.5f) * 0.05f + data->position.x; + d->position.x = (RandomF(RANDOM_TYPE_GLOBAL) - 0.5f) * 0.05f + data->position.x; d->position.y = data->position.y; - d->position.z = (rand_state_array_get_float(4) - 0.5f) * 0.05f + data->position.z; - d->size = (rand_state_array_get_float(4) * 0.5f + 0.2f) * data->size; + d->position.z = (RandomF(RANDOM_TYPE_GLOBAL) - 0.5f) * 0.05f + data->position.z; + d->size = (RandomF(RANDOM_TYPE_GLOBAL) * 0.5f + 0.2f) * data->size; d->velocity = 0.0f; d->alpha = data->alpha * 0.60f; } @@ -6705,17 +6705,17 @@ static void snow_particle_data_kill_fallen(particle_data* data, bool kill) { static void snow_particle_data_reset(particle_data* data) { stage_param_snow* snow = stage_param_data_snow_current; vec3 position; - position.x = rand_state_array_get_float(4) - 0.5f; + position.x = RandomF(RANDOM_TYPE_GLOBAL) - 0.5f; position.y = 1.0f; - position.z = rand_state_array_get_float(4) - 0.5f; + position.z = RandomF(RANDOM_TYPE_GLOBAL) - 0.5f; data->position = position * snow->range + snow->offset; data->life_time = 1; vec3 velocity; - velocity.x = rand_state_array_get_float(4); - velocity.y = rand_state_array_get_float(4); - velocity.z = rand_state_array_get_float(4); + velocity.x = RandomF(RANDOM_TYPE_GLOBAL); + velocity.y = RandomF(RANDOM_TYPE_GLOBAL); + velocity.z = RandomF(RANDOM_TYPE_GLOBAL); data->velocity = (velocity - 0.5f) * snow->vel_range + snow->velocity; data->direction = 0.0f; } @@ -6752,9 +6752,9 @@ static particle_data* snow_particle_emit_fallen() { static vec3 snow_particle_get_random_velocity() { stage_param_snow* snow = stage_param_data_snow_current; vec3 velocity; - velocity.x = rand_state_array_get_float(4); - velocity.y = rand_state_array_get_float(4); - velocity.z = rand_state_array_get_float(4); + velocity.x = RandomF(RANDOM_TYPE_GLOBAL); + velocity.y = RandomF(RANDOM_TYPE_GLOBAL); + velocity.z = RandomF(RANDOM_TYPE_GLOBAL); return (velocity - 0.5f) * snow->vel_range + snow->velocity; } diff --git a/src/CRE/random.cpp b/src/CRE/random.cpp index 34be867e..bd9ad237 100644 --- a/src/CRE/random.cpp +++ b/src/CRE/random.cpp @@ -23,81 +23,227 @@ class MtRandom { public: - uint32_t state_array[n]; - uint32_t state_index; - int32_t field_9CC; - int32_t field_9D0; - int8_t field_9D4; + uint32_t mt[n]; + int32_t index; MtRandom(); virtual ~MtRandom(); - uint32_t rand(); - void seed(uint32_t seed); + void Init(uint32_t seed); + void InitByArray(const uint32_t* key, int32_t key_length); + uint32_t Rand(); }; struct RandState { - MtRandom mt_rand; + MtRandom mtrand; + uint32_t seed; + bool seed_init; RandState(); virtual ~RandState(); }; -static RandState* rand_state_array; +static RandState* rand_state; -static RandState* rand_state_array_get(int32_t id); +static RandState* get_random_state(RandomType type); +static uint32_t sub_1405000B0(); -void rand_state_array_init() { - rand_state_array = new RandState[5]; +// 0x1404FFB20 +void DestRandom() { + if (rand_state) { + delete[] rand_state; + rand_state = 0; + } } -float_t rand_state_array_get_float(int32_t id) { - RandState* rand_state = rand_state_array_get(id); +// 0x1404FFB70 +uint32_t GetRandomSeed(RandomType type) { + RandState* rand_state = get_random_state(type); if (rand_state) - return (float_t)(rand_state->mt_rand.rand() >> 8) * (float_t)(1.0 / (double_t)0x1000000); + return rand_state->seed; + return 0; +} + +// 0x1404FFB90 +void InitRandom() { + if (!rand_state) { + rand_state = new RandState[RANDOM_TYPE_MAX]; + + InitRandomStateForBoot(RANDOM_TYPE_0); + for (int32_t i = RANDOM_TYPE_1; i < RANDOM_TYPE_MAX; i++) + InitRandomState(Random(RANDOM_TYPE_0), (RandomType)i); + } +} + +// 0x1404FFC30 +void InitRandomState(uint32_t seed, RandomType type) { + RandState* rand_state = get_random_state(type); + if (rand_state) { + rand_state->seed = seed; + rand_state->seed_init = true; + rand_state->mtrand.Init(seed); + } +} + +// 0x1404FFC70 +void InitRandomStateForBoot(RandomType type) { + uint32_t key[3]; + key[0] = sub_1405000B0(); + key[1] = sub_1405000B0(); + key[2] = sub_1405000B0(); + + RandState* rand_state = get_random_state(type); + if (rand_state) { + rand_state->seed = 0; + rand_state->seed_init = 0; + rand_state->mtrand.InitByArray(key, 3); + } +} + +// 0x1404FFCF0 +bool Probability(uint64_t rate, RandomType type) { + RandState* rand_state = get_random_state(type); + if (rand_state) + return rate > rand_state->mtrand.Rand(); + return false; +} + +// 0x1404FFD30 +bool ProbabilityF(float_t rate, RandomType type) { + RandState* rand_state = get_random_state(type); + if (rand_state) + return rate > (float_t)(rand_state->mtrand.Rand() >> 8) * (float_t)(1.0 / (double_t)0x1000000); + return false; +} + +// 0x1404FFD80 +uint32_t Random(uint32_t in_min, uint32_t in_max, RandomType type) { + uint64_t _min = in_min; + uint64_t _max = in_max; + RandState* rand_state = get_random_state(type); + if (rand_state && _min <= _max) + return (uint32_t)(_min + (((_max - _min + 1) * (uint64_t)rand_state->mtrand.Rand()) >> 32)); + return 0; +} + +// 0x1404FFDE0 +uint32_t Random(RandomType type) { + RandState* rand_state = get_random_state(type); + if (rand_state) + return rand_state->mtrand.Rand(); + return 0; +} + +// 0x1404FFE00 +double_t RandomD(RandomType type) { + RandState* rand_state = get_random_state(type); + if (rand_state) + return (double_t)(int64_t)rand_state->mtrand.Rand() / (double_t)0; // WHAT?! + return 0.0; +} + +// 0x1404FFE60 +float_t RandomF(RandomType type) { + RandState* rand_state = get_random_state(type); + if (rand_state) + return (float_t)(rand_state->mtrand.Rand() >> 8) * (float_t)(1.0 / (double_t)0x1000000); return 0.0f; } -uint32_t rand_state_array_get_int(int32_t id) { - RandState* rand_state = rand_state_array_get(id); - if (rand_state) - return rand_state->mt_rand.rand(); - return 0; +// 0x1404FFEA0 +bool SafeProbability(uint64_t rate, RandomType type) { + RandState* rand_state = get_random_state(type); + if (rand_state && rate) + return (rand_state->mtrand.Rand() + 1ULL) % rate == 0; + return false; } -uint32_t rand_state_array_get_int(uint32_t min, uint32_t max, int32_t id) { - uint64_t _min = min; - uint64_t _max = max; - RandState* rand_state = rand_state_array_get(id); - if (rand_state && min <= max) - return (uint32_t)(_min + (((_max - _min + 1) * (uint64_t)rand_state->mt_rand.rand()) >> 32)); - return 0; +// 0x1404FFEF0 +uint32_t Share(const float_t* arr, int32_t num, RandomType type) { + uint32_t v5 = 0; + float_t v6 = RandomF(type); + float_t v7 = 0.0f; + if (arr && num) { + for (uint32_t i = num - 1; i; i--) { + v7 += *arr; + if (v6 < v7) + break; + + v5++; + arr++; + } + } + return v5; } -void rand_state_array_set_seed(uint32_t val, int32_t id) { - RandState* rand_state = rand_state_array_get(id); - if (rand_state) - rand_state->mt_rand.seed(val); +// 0x1404FFFF0 +uint32_t Share(const uint64_t* arr, uint32_t num, RandomType type) { + uint32_t v5 = 0; + uint32_t v6 = Random(type); + uint64_t v7 = 0; + if (arr && num) { + for (uint32_t i = num - 1; i; i--) { + v7 += *arr; + if (v6 < v7) + break; + + v5++; + arr++; + } + } + return v5; } -void rand_state_array_4_set_seed_1393939() { - rand_state_array_set_seed(1393939, 4); -} - -void rand_state_array_free() { - delete[] rand_state_array; -} - -MtRandom::MtRandom() : field_9CC(), field_9D0(), field_9D4() { - seed(0x12BD6AA); +MtRandom::MtRandom() { + Init(0x12BD6AA); } MtRandom::~MtRandom() { } -uint32_t MtRandom::rand() { - int32_t index = state_index; +void MtRandom::Init(uint32_t seed) { + mt[0] = seed; + for (int32_t i = 1; i < n; i++) + mt[i] = f * (mt[i - 1] ^ (mt[i - 1] >> (w - 2))) + i; + index = 0; +} + +void MtRandom::InitByArray(const uint32_t* key, int32_t key_length) { + Init(0x12BD6AA); + + int32_t i = 1; + int32_t j = 0; + int32_t k = max_def(n, key_length); + for (; k; k--) { + mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 0x19660D)) + key[j] + j; + i++; + j++; + + if (i >= n) { + mt[0] = mt[n - 1]; + i = 1; + } + + if (j >= key_length) + j = 0; + } + + for (k = n - 1; k; k--) { + mt[i] = (mt[i] ^ ((mt[i - 1] ^ (mt[i - 1] >> 30)) * 0x5D588B65)) - i; + i++; + + if (i >= n) { + mt[0] = mt[n - 1]; + i = 1; + } + } + + mt[0] = 0x80000000; +} + +uint32_t MtRandom::Rand() { + int32_t index = this->index; int32_t shift_index = index + m; int32_t next_index = index + 1; if (shift_index >= n) { @@ -106,11 +252,11 @@ uint32_t MtRandom::rand() { next_index = 0; } - uint32_t& state = state_array[index]; - uint32_t mt_value = state ^ (state ^ state_array[next_index]) & LMASK; - mt_value = state_array[shift_index] ^ ((uint32_t)-((int32_t)mt_value & 0x01) & a) ^ (mt_value >> 1); + uint32_t& state = mt[index]; + uint32_t mt_value = state ^ (state ^ mt[next_index]) & LMASK; + mt_value = mt[shift_index] ^ ((uint32_t)-((int32_t)mt_value & 0x01) & a) ^ (mt_value >> 1); state = mt_value; - state_index = next_index; + this->index = next_index; mt_value ^= mt_value >> u; mt_value ^= (mt_value & SHIFT_VAL(b, s, w)) << s; @@ -119,14 +265,7 @@ uint32_t MtRandom::rand() { return mt_value; } -void MtRandom::seed(uint32_t val) { - state_array[0] = val; - for (int32_t i = 1; i < n; i++) - state_array[i] = f * (state_array[i - 1] ^ (state_array[i - 1] >> (w - 2))) + i; - state_index = 0; -} - -RandState::RandState() { +RandState::RandState() : seed(), seed_init() { } @@ -134,8 +273,16 @@ RandState::~RandState() { } -static RandState* rand_state_array_get(int32_t id) { - if (id > -1 && id < 5) - return &rand_state_array[id]; +// 0x140500090 +static RandState* get_random_state(RandomType type) { + if (type >= 0 && type < RANDOM_TYPE_MAX) + return &rand_state[type]; return 0; } + +// 0x1405000B0 +static uint32_t sub_1405000B0() { + LARGE_INTEGER large_int; + QueryPerformanceCounter(&large_int); + return large_int.LowPart ^ 0xA306103A; +} diff --git a/src/CRE/random.hpp b/src/CRE/random.hpp index df096825..49bdcd2b 100644 --- a/src/CRE/random.hpp +++ b/src/CRE/random.hpp @@ -7,10 +7,25 @@ #include "../KKdLib/default.hpp" -extern void rand_state_array_init(); -extern float_t rand_state_array_get_float(int32_t id); -extern uint32_t rand_state_array_get_int(int32_t id); -extern uint32_t rand_state_array_get_int(uint32_t min, uint32_t max, int32_t id); -extern void rand_state_array_set_seed(uint32_t val, int32_t id); -extern void rand_state_array_4_set_seed_1393939(); -extern void rand_state_array_free(); +enum RandomType { + RANDOM_TYPE_0 = 0, + RANDOM_TYPE_1, + RANDOM_TYPE_2, + RANDOM_TYPE_3, + RANDOM_TYPE_GLOBAL, + RANDOM_TYPE_MAX, +}; + +extern void DestRandom(); +extern uint32_t GetRandomSeed(RandomType type); +extern void InitRandom(); +extern void InitRandomState(uint32_t seed, RandomType type); +extern void InitRandomStateForBoot(RandomType type); +extern bool Probability(uint64_t rate, RandomType type); +extern uint32_t Random(uint32_t min, uint32_t max, RandomType type); +extern uint32_t Random(RandomType type); +extern double_t RandomD(RandomType type); +extern float_t RandomF(RandomType type); +extern bool SafeProbability(uint64_t rate, RandomType type); +extern uint32_t Share(const float_t* arr, int32_t num, RandomType type); +extern uint32_t Share(const uint64_t* arr, uint32_t num, RandomType type); diff --git a/src/CRE/rob/rob.cpp b/src/CRE/rob/rob.cpp index 0355ee5e..ef6183e6 100644 --- a/src/CRE/rob/rob.cpp +++ b/src/CRE/rob/rob.cpp @@ -7508,7 +7508,7 @@ LABEL_8: return; if (v23.size() > 1) { - uint32_t v15 = rand_state_array_get_int(1) % v8; + uint32_t v15 = Random(RANDOM_TYPE_1) % v8; for (const std::pair& i : v23) if (v15 < i.second) { mhadr = i.first; @@ -8554,7 +8554,7 @@ static void sub_140555F70(rob_chara* rob_chr, const motion_database* mot_db) { sub_1405500F0(rob_chr); if (!(rob_chr->rob_base.robmot.flag.u32 & 0x020000) && rob_chr->rob_base.robmot.flag.bit.ext_frame_req) { - rob_chr->rob_base.robmot.field_150.time += rand_state_array_get_float(1) + rob_chr->rob_base.robmot.field_150.time += RandomF(RANDOM_TYPE_1) * rob_chr->frame_speed * 2.0f * (float_t)(1.0 / 60.0); if (rob_chr->rob_base.robmot.field_150.time >= 5.0f) { rob_chr->set_eyelid_mottbl_motion_from_face(1, 3.0f, -1.0f, 1.0f, mot_db); diff --git a/src/CRE/shader_ft.cpp b/src/CRE/shader_ft.cpp index 45711ef5..e48cd4d7 100644 --- a/src/CRE/shader_ft.cpp +++ b/src/CRE/shader_ft.cpp @@ -2828,8 +2828,8 @@ static void glass_eye_calc(glass_eye_struct* glass_eye) { glass_eye->frame = frame; if (frame == (frame / 90) * 90) { - glass_eye->tex_offset.x = (rand_state_array_get_float(0) - 0.5f) * 0.015f; - glass_eye->tex_offset.y = (rand_state_array_get_float(0) - 0.5f) * 0.015f; + glass_eye->tex_offset.x = (RandomF(RANDOM_TYPE_0) - 0.5f) * 0.015f; + glass_eye->tex_offset.y = (RandomF(RANDOM_TYPE_0) - 0.5f) * 0.015f; } float_t phase = (float_t)(uint8_t)frame * (float_t)(M_PI * (1.0 / 128.0)); diff --git a/src/ReDIVA/app.cpp b/src/ReDIVA/app.cpp index e9cd1840..79e6fe0a 100644 --- a/src/ReDIVA/app.cpp +++ b/src/ReDIVA/app.cpp @@ -816,7 +816,7 @@ static render_context* render_context_load(const wchar_t* config_path) { stage_param_data_init(); pv_expression_file_storage_init(); item_table_handler_array_init(); - rand_state_array_init(); + InitRandom(); rob_init(); task_wind_init(); @@ -1449,7 +1449,7 @@ static void render_context_dispose(render_context* rctx) { task_wind_free(); rob_free(); - rand_state_array_free(); + DestRandom(); item_table_handler_array_free(); pv_expression_file_storage_free(); stage_param_data_free(); diff --git a/src/ReDIVA/pv_game/pv_game.cpp b/src/ReDIVA/pv_game/pv_game.cpp index 8e7d4f20..3576d629 100644 --- a/src/ReDIVA/pv_game/pv_game.cpp +++ b/src/ReDIVA/pv_game/pv_game.cpp @@ -575,7 +575,7 @@ PROCESS_TARGET: if ((unsigned int)(v44 - 8) > 1) continue; - int32_t v45 = rand_state_array_get_int(0, v42, 0); + int32_t v45 = Random(0, v42, RANDOM_TYPE_0); int32_t v46 = 1; int32_t v47 = 0; int32_t v48 = 0; @@ -1186,7 +1186,7 @@ void pv_game::change_field(size_t field, ssize_t dsc_time, ssize_t curr_time) { aet_database* aft_aet_db = &aft_data->data_ft.aet_db; if (!data.task_effect_init && (dsc_time > -1 || curr_time > -1)) { - rand_state_array_4_set_seed_1393939(); + pv_init_random_state(); effect_manager_reset(); data.task_effect_init = true; } @@ -2918,7 +2918,7 @@ bool pv_game::load() { state = 8; } return false; case 6: { - rand_state_array_4_set_seed_1393939(); + pv_init_random_state(); if (task_stage_open("PV_STAGE")) return false; @@ -3919,7 +3919,7 @@ bool pv_game::load() { } break; case 25: { //sub_14013C8F0->sub_14012BDA0(); - rand_state_array_4_set_seed_1393939(); + pv_init_random_state(); reset_field(); data.edit_effect.data.reset(); data.play_data.init_aet_edit_effect(-1, "eff", false, false); @@ -5776,6 +5776,10 @@ bool pv_game_free() { return true; } +void pv_init_random_state() { + InitRandomState(1393939, RANDOM_TYPE_GLOBAL); +} + bool task_pv_game_open(TaskPvGame::Args& args) { if (!task_pv_game) task_pv_game = new TaskPvGame; diff --git a/src/ReDIVA/pv_game/pv_game.hpp b/src/ReDIVA/pv_game/pv_game.hpp index 44cd05a4..8a92737f 100644 --- a/src/ReDIVA/pv_game/pv_game.hpp +++ b/src/ReDIVA/pv_game/pv_game.hpp @@ -896,6 +896,8 @@ extern bool pv_game_init(); extern pv_game* pv_game_get(); extern bool pv_game_free(); +extern void pv_init_random_state(); + extern bool task_pv_game_open(TaskPvGame::Args& args); extern bool task_pv_game_check_alive(); extern bool task_pv_game_close(); diff --git a/src/ReDIVA/x_pv_game.cpp b/src/ReDIVA/x_pv_game.cpp index 97f68feb..8bfbb39b 100644 --- a/src/ReDIVA/x_pv_game.cpp +++ b/src/ReDIVA/x_pv_game.cpp @@ -9295,13 +9295,13 @@ void obj_set_reflect::pack_file(void** data, size_t* size, bool mmp, uint8_t* iv = section_data + section_size + 0x20; time_t t; - rand_state_array_set_seed((uint32_t)time(&t), 4); + InitRandomState((uint32_t)time(&t), RANDOM_TYPE_GLOBAL); for (uint32_t i = 0; i < 0x20; i += sizeof(uint32_t)) - *(uint32_t*)(key + i) = rand_state_array_get_int(4); + *(uint32_t*)(key + i) = Random(RANDOM_TYPE_GLOBAL); for (uint32_t i = 0; i < 0x10; i += sizeof(uint32_t)) - *(uint32_t*)(iv + i) = rand_state_array_get_int(4); + *(uint32_t*)(iv + i) = Random(RANDOM_TYPE_GLOBAL); prj::Rijndael rijndael(prj::Rijndael_Nb, prj::Rijndael_Nk128, key); @@ -10097,7 +10097,8 @@ static void x_pv_game_item_alpha_callback(void* data, ROB_ID rob_id, int32_t typ static void x_pv_game_change_field(x_pv_game* xpvgm, int32_t field, int64_t dsc_time, int64_t curr_time) { if (!xpvgm->task_effect_init && (dsc_time > -1 || curr_time > -1)) { - rand_state_array_4_set_seed_1393939(); + extern void pv_init_random_state(); + pv_init_random_state(); effect_manager_reset(); xpvgm->task_effect_init = true; }