/******************************************************************** Minecraft: Pocket Edition - Decompilation Project Copyright (C) 2023 iProgramInCpp The following code is licensed under the BSD 1 clause license. SPDX-License-Identifier: BSD-1-Clause ********************************************************************/ #include #include #include #include "Mth.hpp" #define C_SIN_TABLE_MULTIPLIER (10430.0f) // (3320.0f * 3.14156f) #define ANG_TO_SIN_TABLE_INDEX(ang) ((int) ((ang) * C_SIN_TABLE_MULTIPLIER)) #define SIN_TABLE_INDEX_TO_ANG(ang) ((float)((ang) / C_SIN_TABLE_MULTIPLIER)) float g_SinTable[65536]; Random Mth::g_Random; void Mth::initMth() { for (int i = 0; i < 65536; i++) { g_SinTable[i] = sinf(SIN_TABLE_INDEX_TO_ANG(i)); // value is 10430 } } int Mth::intFloorDiv(int a2, int a3) { if (a2 < 0) return ~(~a2 / a3); return a2 / a3; } float Mth::invSqrt(float number) { // It looks familiar. With IDA I get a convoluted mess. I'm going to assume // they just stole it from Quake. int32_t i; float x2, y; const float threehalfs = 1.5F; x2 = number * 0.5F; y = number; i = * ( int32_t * ) &y; // evil floating point bit level hacking i = 0x5f3759df - ( i >> 1 ); // what the fuck? y = * ( float * ) &i; y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration // y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed return y; } float Mth::sin(float a2) { int angle = ANG_TO_SIN_TABLE_INDEX(a2) & 0xFFFF; return g_SinTable[angle]; } float Mth::cos(float a2) { int angle = (ANG_TO_SIN_TABLE_INDEX(a2) + 16384) & 0xFFFF; return g_SinTable[angle]; } float Mth::sqrt(float a2) { return sqrtf(a2); } // ported from 0.6.1 unsigned Mth::fastRandom() { int x0; static int x1, x2, x3, x4; x0 = x1; x1 = x2; x2 = x3; x3 = x4; return(x4 = x4 ^ (unsigned(x4) >> 19) ^ x0 ^ (x0 << 11) ^ ((x0 ^ unsigned(x0 << 11)) >> 8)); } int Mth::floor(float f) { int result = int(f); if (result > f) result--; return result; } float Mth::atan(float f) { return atanf(f); } float Mth::atan2(float y, float x) { return atan2f(y, x); } float Mth::Min(float a, float b) { return a < b ? a : b; } int Mth::Min(int a, int b) { return a < b ? a : b; } float Mth::Max(float a, float b) { return a > b ? a : b; } int Mth::Max(int a, int b) { return a > b ? a : b; } float Mth::abs(float f) { if (f < 0) f = -f; return f; } int Mth::abs(int d) { return Mth::abs((float)d); } float Mth::absMax(float a2, float a3) { if (a2 < 0) a2 = -a2; if (a3 < 0) a3 = -a3; if (a2 <= a3) a2 = a3; return a2; } float Mth::absMaxSigned(float a2, float a3) { if (abs(a2) <= abs(a2)) a2 = a3; return a2; } int Mth::random(int max) { return int(g_Random.nextInt(max)); } float Mth::random() { return g_Random.genrand_int32() * (1.0f / 4294967295.0f); // divided by 2^32-1 }