mirror of
https://github.com/Karaka-Management/cOMS.git
synced 2026-01-11 11:18:40 +00:00
164 lines
3.2 KiB
C
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 |