cOMS/utils/Utils.h
2024-09-11 05:56:09 +02:00

164 lines
3.2 KiB
C

/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_UTILS_H
#define TOS_UTILS_H
#include "../stdlib/Types.h"
#define sizeof_array(a) (sizeof(a) / sizeof((a)[0]))
struct FileBody {
uint64 size = 0; // doesn't include null termination (same as strlen)
byte* content;
};
global_persist uint32 fast_seed;
#define FAST_RAND_MAX 32767
inline
uint32 fast_rand1(void) {
fast_seed = (214013 * fast_seed + 2531011);
return (fast_seed >> 16) & 0x7FFF;
}
uint32 fast_rand2(uint32* state) {
uint32 x = *state;
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
*state = x;
return x;
}
inline
f32 fast_rand_percentage(void) {
return (f32) fast_rand1() / (f32) FAST_RAND_MAX;
}
inline
bool is_bit_set(byte data, int bit)
{
return data & (1 << bit);
}
inline
bool is_bit_set(int data, int bit)
{
return data & (1 << bit);
}
inline
bool is_bit_set(uint32 data, int bit)
{
return data & (1 << bit);
}
inline
byte get_bits(byte data, int bits_to_read, int start_pos)
{
byte mask = (1 << bits_to_read) - 1;
return (data >> (8 - start_pos - bits_to_read)) & mask;
}
inline
uint64 get_bits(const byte* data, int bits_to_read, int start_pos)
{
if (bits_to_read <= 0 || bits_to_read > sizeof(uint64)) {
return 0;
}
int byte_index = start_pos / 8;
int bit_offset = start_pos % 8;
uint64_t mask = (1ULL << bits_to_read) - 1;
uint64_t result = 0;
int bits_read = 0;
while (bits_read < bits_to_read) {
int bits_in_current_byte = 8 - bit_offset;
int bits_to_take = bits_to_read - bits_read;
if (bits_to_take > bits_in_current_byte) {
bits_to_take = bits_in_current_byte;
}
uint8_t current_byte = data[byte_index];
current_byte >>= bit_offset;
current_byte &= (1 << bits_to_take) - 1;
result |= ((uint64_t)current_byte << bits_read);
bits_read += bits_to_take;
bit_offset = 0;
byte_index++;
}
result &= mask;
return result;
}
inline
uint32 reverse_bits(uint32 data, uint32 count)
{
uint32 reversed = 0;
for (uint32 i = 0; i <= (count / 2); ++i) {
uint32 inv = count - i - 1;
reversed |= ((data >> i) & 0x1) << inv;
reversed |= ((data >> inv) & 0x1) << i;
}
return reversed;
}
/**
* Picks n random elements from end and stores them in begin.
*/
inline
void random_unique(int* array, int size) {
for (int i = size - 1; i > 0; --i) {
int j = rand() % (i + 1);
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
/**
* Gets random index based value probability
*/
int random_weighted_index(int* arr, int array_count)
{
uint32 prob_sum = 0;
for (int i = 0; i < array_count; ++i) {
prob_sum += arr[i];
}
uint32 random_prob = rand() % (prob_sum + 1);
uint32 current_rarity = 0;
int item_rarity = array_count - 1;
for (int i = 0; i < array_count - 1; ++i) {
current_rarity += arr[i];
if (current_rarity < random_prob) {
item_rarity = i;
break;
}
}
return item_rarity;
}
#endif