This commit is contained in:
Dennis Eichhorn 2024-11-26 01:11:10 +01:00
parent 4c7026c698
commit 2943d418e2
60 changed files with 1413 additions and 710 deletions

View File

@ -10,8 +10,6 @@
#define TOS_ASSET_H
#include "../stdlib/Types.h"
#include "../object/Vertex.h"
#include "../stdlib/HashMap.h"
#include "AssetType.h"
#define MAX_ASSET_NAME_LENGTH 32

View File

@ -10,16 +10,6 @@
#define TOS_AUDIO_H
#include "../stdlib/Types.h"
#include "../utils/StringUtils.h"
#include "../memory/RingMemory.h"
#if _WIN32
#include "../platform/win32/UtilsWin32.h"
#else
#include "../platform/linux/UtilsLinux.h"
#endif
#include "Audio.h"
struct Audio {
// bits per sample

View File

@ -15,7 +15,6 @@
#include "../stdlib/Types.h"
#include "../utils/BitUtils.h"
#include "../utils/EndianUtils.h"
#include "../utils/Utils.h"
struct HuffmanNode {
HuffmanNode* left;
@ -152,7 +151,7 @@ void huffman_dump(const Huffman* hf, byte* out)
void huffman_load(Huffman* hf, const byte* in)
{
// load the char -> code relations and convert relative indeces to pointers
// load the char -> code relations and convert relative indices to pointers
for (int32 i = 0; i < ARRAY_COUNT(hf->code); ++i) {
int64 value = SWAP_ENDIAN_LITTLE(*((int64 *) in));
in += sizeof(value);

View File

@ -51,6 +51,8 @@ enum ControllerButton {
};
struct ControllerInput {
// @todo should probably include controller_id for xinput and LPDIRECTINPUTDEVICE8 for directinput
int8 button[MAX_CONTROLLER_KEYS];
bool is_analog[MAX_CONTROLLER_KEYS]; // = uses deadzone

View File

@ -7,6 +7,8 @@
#include "Log.h"
#include "TimingStat.h"
#include "../utils/StringUtils.h"
#include "../utils/TestUtils.h"
#include "../utils/MathUtils.h"
global_persist DebugContainer* debug_container = NULL;
@ -21,7 +23,7 @@ global_persist DebugContainer* debug_container = NULL;
QueryPerformanceFrequency(&perf_counter);
debug_container->performance_count_frequency = perf_counter.QuadPart;
}
#else
#elif __linux__
void setup_performance_count() {
if (!debug_container) {
return;

View File

@ -11,9 +11,12 @@
#include "../stdlib/Types.h"
#include "DebugMemory.h"
#include "Log.h"
#include "TimingStat.h"
#if _WIN32
#include <windows.h>
#endif
struct LogMemory {
byte* memory;

View File

@ -10,17 +10,9 @@
#define TOS_LOG_H
#include <stdio.h>
#include <string.h>
#include "../stdlib/Types.h"
#include "../utils/TestUtils.h"
#include "../utils/MathUtils.h"
#include "Debug.h"
#ifdef _WIN32
#include <windows.h>
#endif
#ifndef LOG_LEVEL
#define LOG_LEVEL 0
#endif

View File

@ -10,7 +10,6 @@
#define TOS_LOG_TIMING_STAT_H
#include <stdio.h>
#include <time.h>
#include "../stdlib/Types.h"
#include "Debug.h"

View File

@ -17,12 +17,12 @@
#include "../log/DebugMemory.h"
#if _WIN32
#include "../platform/win32/Allocation.h"
#include "../platform/win32/Allocator.h"
#elif __linux__
#include "../platform/linux/Allocation.h"
#include "../platform/linux/Allocator.h"
#endif
// @question Consider to use element_alignment to automatically align/pad elmeents
// @question Consider to use element_alignment to automatically align/pad elements
struct BufferMemory {
byte* memory;
@ -59,9 +59,9 @@ void buffer_free(BufferMemory* buf)
{
DEBUG_MEMORY_DELETE((uint64) buf->memory, buf->size);
if (buf->alignment < 2) {
platform_free((void **) &buf->memory, buf->size);
platform_free((void **) &buf->memory);
} else {
platform_aligned_free((void **) &buf->memory, buf->size);
platform_aligned_free((void **) &buf->memory);
}
}
@ -86,7 +86,7 @@ void buffer_init(BufferMemory* buf, byte* data, uint64 size, int32 alignment = 6
inline
void buffer_reset(BufferMemory* buf)
{
// @bug arent we wasting element 0 (see get_memory, we are not using 0 only next element)
// @bug aren't we wasting element 0 (see get_memory, we are not using 0 only next element)
DEBUG_MEMORY_DELETE((uint64) buf->memory, buf->head - buf->memory);
buf->head = buf->memory;
}

View File

@ -18,9 +18,9 @@
#include "BufferMemory.h"
#if _WIN32
#include "../platform/win32/Allocation.h"
#include "../platform/win32/Allocator.h"
#elif __linux__
#include "../platform/linux/Allocation.h"
#include "../platform/linux/Allocator.h"
#endif
struct ChunkMemory {
@ -66,9 +66,9 @@ void chunk_free(ChunkMemory* buf)
{
DEBUG_MEMORY_DELETE((uint64) buf->memory, buf->size);
if (buf->alignment < 2) {
platform_free((void **) &buf->memory, buf->size);
platform_free((void **) &buf->memory);
} else {
platform_aligned_free((void **) &buf->memory, buf->size);
platform_aligned_free((void **) &buf->memory);
}
}

154
memory/Heap.h Normal file
View File

@ -0,0 +1,154 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MEMORY_HEAP_H
#define TOS_MEMORY_HEAP_H
#include <stdio.h>
#include <string.h>
#include "../stdlib/Types.h"
#include "../log/DebugMemory.h"
#include "BufferMemory.h"
#if _WIN32
#include "../platform/win32/Allocator.h"
#elif __linux__
#include "../platform/linux/Allocator.h"
#endif
struct Heap {
byte* elements;
byte* helper_mem;
uint32 element_size;
uint64 capacity;
uint64 size;
int32 (*compare) (const void*, const void*);
};
void heap_alloc(Heap* heap, uint32 element_size, uint64 capacity, int32 (*compare)(const void*, const void*)) {
ASSERT_SIMPLE(element_size * capacity);
heap->elements = (byte *) platform_alloc(element_size * capacity + element_size);
if (!heap->elements) {
return;
}
heap->element_size = element_size;
heap->capacity = capacity;
heap->size = 0;
heap->compare = compare;
heap->helper_mem = heap->elements + element_size;
DEBUG_MEMORY_INIT((uint64) heap->elements, element_size * capacity);
}
void heap_free(Heap* heap)
{
DEBUG_MEMORY_DELETE((uint64) heap->elements, heap->element_size * heap->capacity);
platform_free((void **) &heap->elements);
}
void heap_init(Heap* heap, BufferMemory* buf, uint32 element_size, uint64 capacity, int32 (*compare)(const void*, const void*)) {
ASSERT_SIMPLE(element_size * capacity);
heap->elements = buffer_get_memory(buf, element_size * capacity, 8, true);
if (!heap->elements) {
return;
}
heap->element_size = element_size;
heap->capacity = capacity;
heap->size = 0;
heap->compare = compare;
DEBUG_MEMORY_INIT((uint64) heap->elements, element_size * capacity);
}
void heapify_down(Heap* heap, uint64 index) {
uint64 left_child = 2 * index + 1;
uint64 right_child = left_child + 1;
uint64 largest = index;
void* largest_element = heap->elements + (largest * heap->element_size);
if (left_child < heap->size) {
void* left = heap->elements + (left_child * heap->element_size);
if (heap->compare(left, largest_element) > 0) {
largest = left_child;
}
}
if (right_child < heap->size) {
void* right = heap->elements + (right_child * heap->element_size);
void* current_largest = heap->elements + (largest * heap->element_size);
if (heap->compare(right, current_largest) > 0) {
largest = right_child;
}
}
if (largest != index) {
heap_swap(
heap->elements + (index * heap->element_size),
heap->elements + (largest * heap->element_size),
heap->element_size, heap->helper_mem
);
heapify_down(heap, largest);
}
}
void heapify_up(Heap* heap, uint64 index) {
if (index == 0) {
return; // Root node
}
uint64 parent_index = (index - 1) / 2;
void* current = heap->elements + (index * heap->element_size);
void* parent = heap->elements + (parent_index * heap->element_size);
if (heap->compare(current, parent) > 0) {
heap_swap(current, parent, heap->element_size, heap->helper_mem);
heapify_up(heap, parent_index);
}
}
void heap_push(Heap* heap, const void* element) {
if (heap->size >= heap->capacity) {
return;
}
void* target = heap->elements + (heap->size * heap->element_size);
memcpy(target, element, heap->element_size);
heapify_up(heap, heap->size);
++heap->size;
}
void heap_pop(Heap* heap, void* out) {
if (heap->size == 0) {
return;
}
memcpy(out, heap->elements, heap->element_size);
void* last_element = heap->elements + ((heap->size - 1) * heap->element_size);
memcpy(heap->elements, last_element, heap->element_size);
--heap->size;
heapify_down(heap, 0);
}
inline
void* heap_peek(Heap* heap) {
return heap->elements;
}
inline
void heap_swap(void* a, void* b, uint32 size, void* helper_mem) {
memcpy(helper_mem, a, size);
memcpy(a, b, size);
memcpy(b, helper_mem, size);
}
#endif

View File

@ -9,110 +9,73 @@
#ifndef TOS_MEMORY_QUEUE_H
#define TOS_MEMORY_QUEUE_H
#include "../stdlib/Types.h"
#include "RingMemory.h"
typedef RingMemory Queue;
inline
void queue_alloc(Queue* ring, uint64 size, int32 alignment = 64)
void queue_alloc(Queue* queue, uint64 size, uint32 element_size, int32 alignment = 64)
{
ring_alloc(ring, size, alignment);
pthread_mutex_init(&ring->mutex, NULL);
pthread_cond_init(&ring->cond, NULL);
ring_alloc(queue, size, alignment);
}
inline
void queue_init(Queue* ring, BufferMemory* buf, uint64 size, int32 alignment = 64)
void queue_init(Queue* queue, BufferMemory* buf, uint64 size, uint32 element_size, int32 alignment = 64)
{
ring_init(ring, buf, size, alignment);
pthread_mutex_init(&ring->mutex, NULL);
pthread_cond_init(&ring->cond, NULL);
ring_init(queue, buf, size, alignment);
}
inline
void queue_free(Queue* buf)
void queue_init(Queue* queue, byte* buf, uint64 size, uint32 element_size, int32 alignment = 64)
{
ring_free(buf);
ring_init(queue, buf, size, alignment);
}
inline
void queue_init(Queue* ring, byte* buf, uint64 size, int32 alignment = 64)
void queue_free(Queue* queue)
{
ring_init(ring, buf, size, alignment);
ring_free(queue);
}
// Conditional Lock
inline
void ring_enqueue(Queue* ring, byte* data, uint64 size)
void queue_enqueue(Queue* queue, byte* data, uint64 size, byte aligned = 0)
{
pthread_mutex_lock(&ring->mutex);
while (!ring_commit_safe(ring, size)) {
pthread_cond_wait(&ring->cond, &ring->mutex);
}
byte* mem = ring_get_memory(ring, size);
byte* mem = ring_get_memory_nomove(queue, size, aligned);
memcpy(mem, data, size);
pthread_cond_signal(&ring->cond);
pthread_mutex_unlock(&ring->mutex);
ring_move_pointer(queue, &queue->head, size, aligned);
}
inline
byte* ring_enqueue_start(Queue* ring, uint64 size, byte aligned = 0)
byte* queue_enqueue_start(Queue* queue, uint64 size, byte aligned = 0)
{
pthread_mutex_lock(&ring->mutex);
while (!ring_commit_safe(ring, size, aligned)) {
pthread_cond_wait(&ring->cond, &ring->mutex);
}
return ring_get_memory(ring, size, aligned);
return ring_get_memory_nomove(queue, size, aligned);
}
inline
void ring_enqueue_end(Queue* ring)
void queue_enqueue_end(Queue* queue, uint64 size, byte aligned = 0)
{
pthread_cond_signal(&ring->cond);
pthread_mutex_unlock(&ring->mutex);
ring_move_pointer(queue, &queue->head, size, aligned);
}
inline
byte* ring_dequeue(Queue* ring, byte* data, uint64 size, byte aligned = 0)
byte* queue_dequeue(Queue* queue, byte* data, uint64 size, byte aligned = 0)
{
pthread_mutex_lock(&ring->mutex);
while (ring->head == ring->tail) {
pthread_cond_wait(&ring->cond, &ring->mutex);
}
memcpy(data, ring->tail, size);
ring_move_pointer(ring, &ring->tail, size, aligned);
pthread_cond_signal(&ring->cond);
pthread_mutex_unlock(&ring->mutex);
memcpy(data, queue->tail, size);
ring_move_pointer(queue, &queue->tail, size, aligned);
}
inline
byte* ring_dequeue_start(Queue* ring)
byte* queue_dequeue_start(Queue* queue)
{
pthread_mutex_lock(&ring->mutex);
while (ring->head == ring->tail) {
pthread_cond_wait(&ring->cond, &ring->mutex);
}
return ring->tail;
return queue->tail;
}
inline
void ring_dequeue_end(Queue* ring, uint64 size, byte aligned = 0)
void queue_dequeue_end(Queue* queue, uint64 size, byte aligned = 0)
{
ring_move_pointer(ring, &ring->tail, size, aligned);
pthread_cond_signal(&ring->cond);
pthread_mutex_unlock(&ring->mutex);
ring_move_pointer(queue, &queue->tail, size, aligned);
}
#endif

View File

@ -21,11 +21,13 @@
#include "../log/DebugMemory.h"
#if _WIN32
#include "../platform/win32/Allocation.h"
#include "../platform/win32/Thread.h"
#include "../platform/win32/Allocator.h"
#include "../platform/win32/threading/ThreadDefines.h"
#include "../platform/win32/threading/Semaphore.h"
#elif __linux__
#include "../platform/linux/Allocation.h"
#include "../platform/linux/Thread.h"
#include "../platform/linux/Allocator.h"
#include "../platform/linux/threading/ThreadDefines.h"
#include "../platform/linux/threading/Semaphore.h"
#endif
struct RingMemory {
@ -34,7 +36,7 @@ struct RingMemory {
byte* head;
// This variable is usually only used by single read/write code mostly found in threads.
// This variable is usually only used by single producer/consumer code mostly found in threads.
// One thread inserts elements -> updates head
// The other thread reads elements -> updates tail
// This code itself doesn't change this variable
@ -44,8 +46,13 @@ struct RingMemory {
int32 alignment;
int32 element_alignment;
// We support both conditional locking and semaphore locking
// These values are not initialized and not used unless you use the queue
pthread_mutex_t mutex;
pthread_cond_t cond;
sem_t empty;
sem_t full;
};
// @bug alignment should also include the end point, not just the start
@ -114,9 +121,9 @@ inline
void ring_free(RingMemory* buf)
{
if (buf->alignment < 2) {
platform_free((void **) &buf->memory, buf->size);
platform_free((void **) &buf->memory);
} else {
platform_aligned_free((void **) &buf->memory, buf->size);
platform_aligned_free((void **) &buf->memory);
}
}
@ -218,6 +225,41 @@ byte* ring_get_memory(RingMemory* ring, uint64 size, byte aligned = 0, bool zero
return offset;
}
// Same as ring_get_memory but DOESN'T move the head
byte* ring_get_memory_nomove(RingMemory* ring, uint64 size, byte aligned = 0, bool zeroed = false)
{
ASSERT_SIMPLE(size <= ring->size);
if (aligned == 0) {
aligned = (byte) OMS_MAX(ring->element_alignment, 1);
}
byte* pos = ring->head;
if (aligned > 1) {
uintptr_t address = (uintptr_t) pos;
pos += (aligned - (address& (aligned - 1))) % aligned;
}
size = ROUND_TO_NEAREST(size, aligned);
if (pos + size > ring->end) {
ring_reset(ring);
if (aligned > 1) {
uintptr_t address = (uintptr_t) pos;
pos += (aligned - (address & (aligned - 1))) % aligned;
}
}
if (zeroed) {
memset((void *) pos, 0, size);
}
DEBUG_MEMORY_WRITE((uint64) pos, size);
return pos;
}
// Used if the ring only contains elements of a certain size
// This way you can get a certain element
inline

204
memory/ThreadedQueue.h Normal file
View File

@ -0,0 +1,204 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MEMORY_QUEUE_H
#define TOS_MEMORY_QUEUE_H
#include "RingMemory.h"
#if _WIN32
#include "../platform/win32/threading/Thread.h"
#include "../platform/win32/threading/Semaphore.h"
#elif __linux__
#include "../platform/linux/threading/Thread.h"
#include "../platform/linux/threading/Semaphore.h"
#endif
typedef RingMemory ThreadedQueue;
inline
void threaded_queue_alloc(ThreadedQueue* queue, uint64 size, uint32 element_count, int32 alignment = 64)
{
ring_alloc(queue, size, alignment);
pthread_mutex_init(&queue->mutex, NULL);
pthread_cond_init(&queue->cond, NULL);
sem_init(&queue->empty, element_count);
sem_init(&queue->full, 0);
}
inline
void threaded_queue_init(ThreadedQueue* queue, BufferMemory* buf, uint64 size, uint32 element_count, int32 alignment = 64)
{
ring_init(queue, buf, size, alignment);
pthread_mutex_init(&queue->mutex, NULL);
pthread_cond_init(&queue->cond, NULL);
sem_init(&queue->empty, element_count);
sem_init(&queue->full, 0);
}
inline
void threaded_queue_init(ThreadedQueue* queue, byte* buf, uint64 size, uint32 element_count, int32 alignment = 64)
{
ring_init(queue, buf, size, alignment);
pthread_mutex_init(&queue->mutex, NULL);
pthread_cond_init(&queue->cond, NULL);
sem_init(&queue->empty, element_count);
sem_init(&queue->full, 0);
}
inline
void threaded_queue_free(ThreadedQueue* queue)
{
ring_free(queue);
sem_destroy(&queue->empty);
sem_destroy(&queue->full);
pthread_mutex_destroy(&queue->mutex);
pthread_cond_destroy(&queue->cond);
}
// Conditional Lock
inline
void threaded_queue_enqueue(ThreadedQueue* queue, byte* data, uint64 size, byte aligned = 0)
{
pthread_mutex_lock(&queue->mutex);
while (!ring_commit_safe(queue, size)) {
pthread_cond_wait(&queue->cond, &queue->mutex);
}
byte* mem = ring_get_memory(queue, size, aligned);
memcpy(mem, data, size);
pthread_cond_signal(&queue->cond);
pthread_mutex_unlock(&queue->mutex);
}
inline
byte* threaded_queue_enqueue_start(ThreadedQueue* queue, uint64 size, byte aligned = 0)
{
pthread_mutex_lock(&queue->mutex);
while (!ring_commit_safe(queue, size, aligned)) {
pthread_cond_wait(&queue->cond, &queue->mutex);
}
return ring_get_memory(queue, size, aligned);
}
inline
void threaded_queue_enqueue_end(ThreadedQueue* queue)
{
pthread_cond_signal(&queue->cond);
pthread_mutex_unlock(&queue->mutex);
}
inline
byte* threaded_queue_dequeue(ThreadedQueue* queue, byte* data, uint64 size, byte aligned = 0)
{
pthread_mutex_lock(&queue->mutex);
while (queue->head == queue->tail) {
pthread_cond_wait(&queue->cond, &queue->mutex);
}
memcpy(data, queue->tail, size);
ring_move_pointer(queue, &queue->tail, size, aligned);
pthread_cond_signal(&queue->cond);
pthread_mutex_unlock(&queue->mutex);
}
inline
byte* threaded_queue_dequeue_start(ThreadedQueue* queue)
{
pthread_mutex_lock(&queue->mutex);
while (queue->head == queue->tail) {
pthread_cond_wait(&queue->cond, &queue->mutex);
}
return queue->tail;
}
inline
void threaded_queue_dequeue_end(ThreadedQueue* queue, uint64 size, byte aligned = 0)
{
ring_move_pointer(queue, &queue->tail, size, aligned);
pthread_cond_signal(&queue->cond);
pthread_mutex_unlock(&queue->mutex);
}
// Semaphore Lock
inline
void threaded_queue_enqueue_sem(ThreadedQueue* queue, byte* data, uint64 size, byte aligned = 0)
{
sem_wait(&queue->empty);
pthread_mutex_lock(&queue->mutex);
byte* mem = ring_get_memory(queue, size, aligned);
memcpy(mem, data, size);
pthread_mutex_unlock(&queue->mutex);
sem_post(&queue->full);
}
inline
byte* threaded_queue_enqueue_start_sem(ThreadedQueue* queue, uint64 size, byte aligned = 0)
{
sem_wait(&queue->empty);
pthread_mutex_lock(&queue->mutex);
return ring_get_memory(queue, size, aligned);
}
inline
void threaded_queue_enqueue_end_sem(ThreadedQueue* queue)
{
pthread_mutex_unlock(&queue->mutex);
sem_post(&queue->full);
}
inline
byte* threaded_queue_dequeue_sem(ThreadedQueue* queue, byte* data, uint64 size, byte aligned = 0)
{
sem_wait(&queue->full);
pthread_mutex_lock(&queue->mutex);
memcpy(data, queue->tail, size);
ring_move_pointer(queue, &queue->tail, size, aligned);
pthread_mutex_unlock(&queue->mutex);
sem_post(&queue->empty);
}
inline
byte* threaded_queue_dequeue_start_sem(ThreadedQueue* queue)
{
sem_wait(&queue->full);
pthread_mutex_lock(&queue->mutex);
return queue->tail;
}
inline
void threaded_queue_dequeue_end_sem(ThreadedQueue* queue, uint64 size, byte aligned = 0)
{
ring_move_pointer(queue, &queue->tail, size, aligned);
pthread_mutex_unlock(&queue->mutex);
sem_post(&queue->empty);
}
#endif

View File

@ -17,7 +17,7 @@ static const int PRIMARY_STAT_INDICES[] = {0, 1, 2, 3, 4, 5, 6, 7};
// Character stats modifiable through leveling (simple +/- buttons)
struct PrimaryStatsPoints {
uint16 stat_str; // strength : effects health + base damage
uint16 stat_int; // inteligence : effects resource + base demage
uint16 stat_int; // intelligence : effects resource + base damage
uint16 stat_acc; // accuracy : effects critical chance + base damage + miss chance
uint16 stat_agi; // agility : effects resource + base damage + dodge chance
// @todo not implemented in database

View File

@ -29,7 +29,7 @@ static const int SECONDARY_STAT_INDICES[] = {
* @todo optimize order of struct members to ensure optimal struct size
*/
// Character stats modifiable thorugh skill tree?
// Character stats modifiable through skill tree?
struct SecondaryStatsPoints {
/*
@todo
@ -45,15 +45,12 @@ struct SecondaryStatsPoints {
// This allows us to create skills with multiple additive damage types AND composite damage that has multiple types at the same time
uint16 dmg[MOB_STATS_TYPE_SIZE];
uint16 dmg_reflection;
uint16 dmg_reflection_chance;
// @question is this a damage number or is this a % number of the total damage?
uint16 dmg_crit;
uint16 dmg_crit_chance;
// @question is this similar to the different damage categories, is this a % of the total damage or should this just be a flag
uint16 dmg_pircing;
uint16 dmg_piercing;
// Health & Resource
uint16 health;
@ -85,6 +82,9 @@ struct SecondaryStatsPoints {
uint16 block_chance;
uint16 block_amount;
uint16 dmg_reflection;
uint16 dmg_reflection_chance;
uint16 dodge_chance;
uint16 cc_protection;
uint16 miss_chance;
@ -162,7 +162,7 @@ struct SecondaryStatsPoints2 {
byte dmg_crit_chance;
// @question is this similar to the different damage categories, is this a % of the total damage or should this just be a flag
byte dmg_pircing;
byte dmg_piercing;
// Health & Resource
byte health;
@ -257,7 +257,7 @@ struct SecondaryStatsRelPoints2 {
byte dmg_crit;
byte dmg_crit_chance;
byte dmg_pircing;
byte dmg_piercing;
// Health & Resource
byte health;
@ -281,7 +281,7 @@ struct SecondaryStatsRelPoints2 {
byte resource_loss_on_dmg_taken;
// Defense types
// think about it as armor and/or resistence if it helps
// think about it as armor and/or resistance if it helps
byte defense[MOB_STATS_TYPE_SIZE];
// Accuracy

View File

@ -109,7 +109,7 @@ void mesh_from_file_txt(
uint32 temp_color_count = 0;
while (*pos != '\0') {
char_skip_empty(&pos);
str_skip_empty(&pos);
if (*pos == '\0') {
break;
@ -152,11 +152,11 @@ void mesh_from_file_txt(
state = 15;
} else {
// not supported or comment
char_move_to(&pos, '\n');
str_move_to(&pos, '\n');
}
// move past keyword
char_skip_non_empty(&pos);
str_skip_non_empty(&pos);
// move past whitespaces and newline
bool is_next_line = false;

View File

@ -15,7 +15,6 @@
#include "../stdlib/Types.h"
#include "../utils/MathUtils.h"
#include "../memory/RingMemory.h"
f32 manhattan_2d(v2_f32 a, v2_f32 b) {
return fabs(a.x - b.x) + fabs(a.y - b.y);

View File

@ -12,9 +12,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "../stdlib/Types.h"
#include "../memory/RingMemory.h"
// Manhattan distance for 3D
f32 manhattan_3d(v3_f32 a, v3_f32 b) {

23
pathfinding/Path.h Normal file
View File

@ -0,0 +1,23 @@
/**
* Jingga
*
* @package Utils
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PATHFINDING_PATH_H
#define TOS_PATHFINDING_PATH_H
#include <stdio.h>
#include <stdlib.h>
#include "../stdlib/Types.h"
#include "../utils/MathUtils.h"
struct Path {
};
#endif

43
pathfinding/jps/Jps.h Normal file
View File

@ -0,0 +1,43 @@
/**
* Jingga
*
* @package Utils
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PATHFINDING_JPS_H
#define TOS_PATHFINDING_JPS_H
#include <stdio.h>
#include <stdlib.h>
#include "../../stdlib/Types.h"
#include "../../utils/MathUtils.h"
#include "JpsGrid.h"
#include "../Path.h"
void jps_find_path(
v3_int32 start, v3_int32 end,
const JpsGrid* grid, Path* path,
int32 heuristic, int32 movement
) {
JpsNode* start_node = &grid->nodes[
grid->dimension.x * grid->dimension.y * start.z
+ grid->dimension.x * start.y
+ start.x
];
JpsNode* end_node = &grid->nodes[
grid->dimension.x * grid->dimension.y * end.z
+ grid->dimension.x * end.y
+ end.x
];
if (!start_node->is_walkable || !end_node->is_walkable) {
return;
}
}
#endif

30
pathfinding/jps/JpsGrid.h Normal file
View File

@ -0,0 +1,30 @@
/**
* Jingga
*
* @package Utils
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PATHFINDING_JPS_GRID_H
#define TOS_PATHFINDING_JPS_GRID_H
#include <stdio.h>
#include <stdlib.h>
#include "../../stdlib/Types.h"
#include "../../utils/MathUtils.h"
#include "JpsNode.h"
struct JpsGrid {
// 1. left to right
// 2. then front to back
// 3. then height
JpsNode* nodes;
v3_int32 dimension;
};
#endif

23
pathfinding/jps/JpsNode.h Normal file
View File

@ -0,0 +1,23 @@
/**
* Jingga
*
* @package Utils
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PATHFINDING_JPS_NODE_H
#define TOS_PATHFINDING_JPS_NODE_H
#include <stdio.h>
#include <stdlib.h>
#include "../../stdlib/Types.h"
#include "../../utils/MathUtils.h"
struct JpsNode {
bool is_walkable;
};
#endif

View File

@ -33,7 +33,7 @@ struct NetworkInfo {
};
struct SIMDInfo {
f32 sse;
int32 sse;
int32 avx256;
int32 avx512;
int32 sve;
@ -89,8 +89,11 @@ struct SystemInfo {
GpuInfo gpu[2];
int32 gpu_count;
DisplayInfo display_primary;
DisplayInfo display[6];
int32 display_count;
int32 language;
};
#endif

View File

@ -1,61 +0,0 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PLATFORM_LINUX_ALLOCATION_H
#define TOS_PLATFORM_LINUX_ALLOCATION_H
#include <unistd.h>
#include <sys/mman.h>
inline
void aligned_free(void** ptr) {
free(*ptr);
*ptr = NULL;
}
inline
void* platform_alloc(size_t size)
{
ssize_t page_size = sysconf(_SC_PAGESIZE);
size = (size + page_size - 1) & ~(page_size - 1);
return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
}
inline
void* platform_alloc_aligned(size_t size, int32 alignment)
{
ssize_t page_size = sysconf(_SC_PAGESIZE);
if (alignment < page_size) {
alignment = page_size;
}
size = (size + alignment - 1) & ~(alignment - 1);
void* ptr = mmap(NULL, size + alignment + sizeof(void*), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
void* aligned_ptr = (void*)(((uintptr_t)ptr + alignment + sizeof(void*) - 1) & ~(alignment - 1));
((void**) aligned_ptr)[-1] = ptr;
return aligned_ptr;
}
inline
void platform_free(void** ptr, size_t size) {
munmap(*ptr, size);
*ptr = NULL;
}
inline
void platform_aligned_free(void** aligned_ptr, size_t size) {
void* ptr = ((void**) *aligned_ptr)[-1];
munmap(ptr, size + ((uintptr_t) *aligned_ptr - (uintptr_t)ptr));
*aligned_ptr = NULL;
}
#endif

132
platform/linux/Allocator.h Normal file
View File

@ -0,0 +1,132 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PLATFORM_LINUX_ALLOCATOR_H
#define TOS_PLATFORM_LINUX_ALLOCATOR_H
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include "../../stdlib/Types.h"
#include "../../utils/TestUtils.h"
// @todo Currently alignment only effects the starting position, but it should also effect the ending/size
// @todo Consider to rename file to Allocator.h
// @question Since we store at least the size of the memory in the beginning,
// does this have a negative impact on caching?
// Our Memory doesn't start at the cache line beginning but at least offset by sizeof(size_t)
inline
void* platform_alloc(size_t size)
{
ssize_t page_size = sysconf(_SC_PAGESIZE);
size = (size + sizeof(size_t) + page_size - 1) & ~(page_size - 1);
void* ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
ASSERT_SIMPLE(ptr != MAP_FAILED);
*((size_t *) ptr) = size;
return (void *) ((uintptr_t) ptr + sizeof(size_t));
}
inline
void* platform_alloc_aligned(size_t size, int32 alignment)
{
ssize_t page_size = sysconf(_SC_PAGESIZE);
if (alignment < page_size) {
alignment = page_size;
}
size += alignment - 1 + sizeof(void *) + sizeof(size_t);
void* ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
ASSERT_SIMPLE(ptr != MAP_FAILED);
// We want an aligned memory area but mmap doesn't really support that.
// That's why we have to manually offset our memory area.
// However, when freeing the pointer later on we need the actual start of the memory area, not the manually offset one.
// We do the same with the size, which is required when freeing
uintptr_t raw_address = (uintptr_t) ptr + sizeof(void *) + sizeof(size_t);
void* aligned_ptr = (void *) ((raw_address + alignment - 1) & ~(alignment - 1));
*((void **) ((uintptr_t) aligned_ptr - sizeof(void *) - sizeof(size_t))) = ptr;
*((size_t *) ((uintptr_t) aligned_ptr - sizeof(size_t))) = size;
return aligned_ptr;
}
inline
void platform_free(void** ptr) {
void* actual_ptr = (void *) ((uintptr_t) *ptr - sizeof(size_t));
munmap(actual_ptr, *((size_t *) actual_ptr));
*ptr = NULL;
}
inline
void platform_aligned_free(void** aligned_ptr) {
void* ptr = (void *) ((uintptr_t) *aligned_ptr - sizeof(void *) - sizeof(size_t));
munmap(ptr, *((size_t *) ((uintptr_t) ptr + sizeof(void *))));
*aligned_ptr = NULL;
}
inline
void* platform_shared_alloc(int32* fd, const char* name, size_t size)
{
*fd = shm_open(name, O_CREAT | O_RDWR, 0666);
ASSERT_SIMPLE(*fd != -1);
ssize_t page_size = sysconf(_SC_PAGESIZE);
size = (size + sizeof(size_t) + page_size - 1) & ~(page_size - 1);
ftruncate(*fd, size);
void* shm_ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
ASSERT_SIMPLE(shm_ptr);
*((size_t *) shm_ptr) = size;
return (void *) ((uintptr_t) shm_ptr + sizeof(size_t));
}
inline
void* platform_shared_open(int32* fd, const char* name, size_t size)
{
*fd = shm_open(name, O_RDWR, 0666);
ASSERT_SIMPLE(*fd != -1);
ssize_t page_size = sysconf(_SC_PAGESIZE);
size = (size + sizeof(size_t) + page_size - 1) & ~(page_size - 1);
void* shm_ptr = mmap(NULL, size, PROT_READ, MAP_SHARED, *fd, 0);
ASSERT_SIMPLE(shm_ptr);
*((size_t *) shm_ptr) = size;
return (void *) ((uintptr_t) shm_ptr + sizeof(size_t));
}
inline
void platform_shared_free(int32 fd, const char* name, void** ptr)
{
munmap((void *) ((uintptr_t) *ptr - sizeof(size_t)), *((size_t *) ((uintptr_t) *ptr - sizeof(size_t))));
*ptr = NULL;
shm_unlink(name);
close(fd);
}
inline
void platform_shared_close(int32 fd)
{
close(fd);
}
#endif

View File

@ -62,7 +62,7 @@ bool library_load(Library* lib)
}
lib->is_valid = true;
for (int32_t c = 0; c < lib->function_count; ++c) {
for (int32 c = 0; c < lib->function_count; ++c) {
void* function = dlsym(lib->handle, lib->function_names[c]);
if (function) {
lib->functions[c] = function;
@ -82,7 +82,7 @@ void library_unload(Library* lib)
lib->handle = NULL;
}
for (int32_t c = 0; c < lib->function_count; ++c) {
for (int32 c = 0; c < lib->function_count; ++c) {
lib->functions[c] = NULL;
}
}

View File

@ -13,7 +13,6 @@
#include <stdint.h>
#include "../../stdlib/Types.h"
#include "../../stdlib/simd/SIMD_Helper.h"
#include "../../utils/StringUtils.h"
#include "../SystemInfo.h"
#include <locale.h>

View File

@ -1,14 +0,0 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PLATFORM_LINUX_THREAD_H
#define TOS_PLATFORM_LINUX_THREAD_H
#include "ThreadDefines.h"
#endif

View File

@ -6,17 +6,11 @@
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PLATFORM_LINUX_THREAD_DEFINES_H
#define TOS_PLATFORM_LINUX_THREAD_DEFINES_H
#ifndef TOS_PLATFORM_LINUX_THREADING_ATOMIC_H
#define TOS_PLATFORM_LINUX_THREADING_ATOMIC_H
#include <pthread.h>
#include <unistd.h>
#include "../../stdlib/Types.h"
typedef void* (*ThreadJobFunc)(void*);
#define THREAD_RETURN void*
#include "../../../stdlib/Types.h"
inline
void atomic_set(volatile int32* value, int32 new_value)

View File

@ -0,0 +1,15 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PLATFORM_LINUX_THREADING_SEMAPHORE_H
#define TOS_PLATFORM_LINUX_THREADING_SEMAPHORE_H
#include <pthread.h>
#include <semaphore.h>
#endif

View File

@ -0,0 +1,27 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PLATFORM_LINUX_THREADING_SPINLOCK_H
#define TOS_PLATFORM_LINUX_THREADING_SPINLOCK_H
#include <pthread.h>
#include "../../../stdlib/Types.h"
typedef volatile int32 spinlock32;
inline
void spinlock_start(spinlock32* lock) {
while (__atomic_exchange_n(lock, 1, __ATOMIC_ACQUIRE)) {}
}
inline
void spinlock_end(spinlock32* lock) {
__atomic_store_n(lock, 0, __ATOMIC_RELEASE);
}
#endif

View File

@ -0,0 +1,21 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PLATFORM_LINUX_THREADING_THREAD_H
#define TOS_PLATFORM_LINUX_THREADING_THREAD_H
#include <unistd.h>
#include "../../../stdlib/Types.h"
#include "ThreadDefines.h"
uint32 pcthread_get_num_procs()
{
return (uint32) sysconf(_SC_NPROCESSORS_ONLN);
}
#endif

View File

@ -0,0 +1,19 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PLATFORM_LINUX_THREADING_THREAD_DEFINES_H
#define TOS_PLATFORM_LINUX_THREADING_THREAD_DEFINES_H
#include <pthread.h>
#include <unistd.h>
typedef void* (*ThreadJobFunc)(void*);
#define THREAD_RETURN void*
#endif

View File

@ -1,56 +0,0 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PLATFORM_WIN32_ALLOCATION_H
#define TOS_PLATFORM_WIN32_ALLOCATION_H
#include <malloc.h>
#include <windows.h>
#include "../../stdlib/Types.h"
inline
void* aligned_alloc(size_t alignment, size_t size) {
return _aligned_malloc(size, alignment);
}
inline
void aligned_free(void** ptr) {
_aligned_free(*ptr);
*ptr = NULL;
}
inline
void* platform_alloc(size_t size)
{
return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
}
inline
void* platform_alloc_aligned(size_t size, int32 alignment)
{
void* ptr = VirtualAlloc(NULL, size + alignment + sizeof(void*), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
void* aligned_ptr = (void*)(((uintptr_t)ptr + alignment + sizeof(void*) - 1) & ~(alignment - 1));
((void**) aligned_ptr)[-1] = ptr;
return aligned_ptr;
}
inline
void platform_free(void** ptr, size_t) {
VirtualFree(*ptr, 0, MEM_RELEASE);
*ptr = NULL;
}
inline
void platform_aligned_free(void** aligned_ptr, size_t) {
void* ptr = ((void**) *aligned_ptr)[-1];
VirtualFree(ptr, 0, MEM_RELEASE);
*aligned_ptr = NULL;
}
#endif

View File

@ -0,0 +1,92 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PLATFORM_WIN32_ALLOCATOR_H
#define TOS_PLATFORM_WIN32_ALLOCATOR_H
#include <malloc.h>
#include <windows.h>
#include "../../stdlib/Types.h"
#include "../../utils/TestUtils.h"
// @todo Currently alignment only effects the starting position, but it should also effect the ending/size
// @todo Consider to rename file to Allocator.h
inline
void* platform_alloc(size_t size)
{
return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
}
inline
void* platform_alloc_aligned(size_t size, int32 alignment)
{
void* ptr = VirtualAlloc(NULL, size + alignment + sizeof(void*), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
ASSERT_SIMPLE(ptr);
// We want an aligned memory area but mmap doesn't really support that.
// That's why we have to manually offset our memory area.
// However, when freeing the pointer later on we need the actual start of the memory area, not the manually offset one.
void* aligned_ptr = (void *) (((uintptr_t) ptr + alignment + sizeof(void*) - 1) & ~(alignment - 1));
((void**) aligned_ptr)[-1] = ptr;
return aligned_ptr;
}
inline
void platform_free(void** ptr) {
VirtualFree(*ptr, 0, MEM_RELEASE);
*ptr = NULL;
}
inline
void platform_aligned_free(void** aligned_ptr) {
void* ptr = ((void**) *aligned_ptr)[-1];
VirtualFree(ptr, 0, MEM_RELEASE);
*aligned_ptr = NULL;
}
inline
void* platform_shared_alloc(HANDLE* fd, const char* name, size_t size)
{
*fd = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, (DWORD) size, name);
ASSERT_SIMPLE(*fd);
void* shm_ptr = MapViewOfFile(*fd, FILE_MAP_ALL_ACCESS, 0, 0, size);
ASSERT_SIMPLE(shm_ptr);
return shm_ptr;
}
inline
void* platform_shared_open(HANDLE* fd, const char* name, size_t size)
{
*fd = OpenFileMappingA(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, name);
ASSERT_SIMPLE(*fd);
void* shm_ptr = MapViewOfFile(*fd, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, (DWORD) size);
ASSERT_SIMPLE(shm_ptr);
return shm_ptr;
}
inline
void platform_shared_free(HANDLE fd, const char*, void** ptr)
{
UnmapViewOfFile(*ptr);
CloseHandle(fd);
*ptr = NULL;
}
inline
void platform_shared_close(HANDLE fd)
{
CloseHandle(fd);
}
#endif

View File

@ -0,0 +1,49 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_UTILS_FAST_PIPES_H
#define TOS_UTILS_FAST_PIPES_H
#include "../stdlib/Types.h"
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "user32.lib")
#include <windows.h>
#include <io.h>
#include <fcntl.h>
#include <stdio.h>
static int ENABLE_FAST_PIPES()
{
int32 result = 0;
wchar_t pipe_name[32];
wsprintfW(pipe_name, L"\\\\.\\pipe\\fastpipe%x", GetCurrentProcessId());
HANDLE fast_pip = CreateFileW(pipe_name, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if(fast_pip != INVALID_HANDLE_VALUE) {
SetStdHandle(STD_OUTPUT_HANDLE, fast_pip);
SetStdHandle(STD_INPUT_HANDLE, fast_pip);
int32 std_out = _open_osfhandle((intptr_t) fast_pip, O_WRONLY | O_TEXT);
int32 std_in = _open_osfhandle((intptr_t) fast_pip, O_RDONLY | O_TEXT);
_dup2(std_out, _fileno(stdout));
_dup2(std_in, _fileno(stdin));
_close(std_out);
_close(std_in);
result = 1;
}
return result;
}
#endif

View File

@ -16,7 +16,6 @@
#include <winsock2.h>
#include <ws2tcpip.h>
#include "../../stdlib/Types.h"
#include "../../network/SocketConnection.h"
#include "../../utils/EndianUtils.h"

View File

@ -13,7 +13,6 @@
#include <stdint.h>
#include "../../stdlib/Types.h"
#include "../../stdlib/simd/SIMD_Helper.h"
#include "../../utils/StringUtils.h"
#include "../SystemInfo.h"
#include <psapi.h>
@ -312,8 +311,7 @@ int network_info_get(NetworkInfo* info) {
}
void cpu_info_get(CpuInfo* info) {
int32 temp;
info->simd.sse = (temp = max_sse_supported()) > 9 ? temp / 10.0f : temp;
info->simd.sse = max_sse_supported();
info->simd.avx256 = max_avx256_supported();
info->simd.avx512 = max_avx512_supported();
info->simd.sve = max_sve_supported();
@ -553,7 +551,7 @@ void system_info_render(char* buf, const SystemInfo* info) {
info->cpu.cache[1].size, info->cpu.cache[1].line_size,
info->cpu.cache[2].size, info->cpu.cache[2].line_size,
info->cpu.cache[3].size, info->cpu.cache[3].line_size,
info->cpu.simd.sse, info->cpu.simd.avx256, info->cpu.simd.avx512 > 0 ? avx512[info->cpu.simd.avx512 - 1] : "0", info->cpu.simd.sve, info->cpu.simd.neon, (int32) info->cpu.simd.abm,
info->cpu.simd.sse > 9 ? (f32) info->cpu.simd.sse / 10.0f : (f32) info->cpu.simd.sse, info->cpu.simd.avx256, info->cpu.simd.avx512 > 0 ? avx512[info->cpu.simd.avx512 - 1] : "0", info->cpu.simd.sve, info->cpu.simd.neon, (int32) info->cpu.simd.abm,
info->gpu[0].name, info->gpu[0].vram,
info->gpu_count < 2 ? "" : info->gpu[1].name, info->gpu_count < 2 ? 0 : info->gpu[1].vram,
info->display[0].name, info->display[0].width, info->display[0].height, info->display[0].hz,
@ -575,6 +573,8 @@ void system_info_get(SystemInfo* info)
ram_info_get(&info->ram);
info->gpu_count = gpu_info_get(info->gpu);
info->display_count = display_info_get(info->display);
display_info_get_primary(&info->display_primary);
info->language = system_language_code();
}
#endif

View File

@ -1,271 +0,0 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PLATFORM_WIN32_THREAD_H
#define TOS_PLATFORM_WIN32_THREAD_H
#include <time.h>
#include "../stdlib/Types.h"
#include "ThreadDefines.h"
#include <windows.h>
void ms_to_timespec(timespec *ts, uint32 ms)
{
if (ts == 0) {
return;
}
// @todo replace time() with os specifc solution
ts->tv_sec = (ms / 1000) + time(0);
ts->tv_nsec = (ms % 1000) * 1000000;
}
#ifdef _WIN32
int32 pthread_create(pthread_t* thread, void*, ThreadJobFunc start_routine, void* arg)
{
if (thread == NULL || start_routine == NULL) {
return 1;
}
*thread = CreateThread(NULL, 0, start_routine, arg, 0, NULL);
if (*thread == NULL) {
return 1;
}
return 0;
}
int32 pthread_join(pthread_t thread, void**)
{
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
return 0;
}
int32 pthread_detach(pthread_t thread)
{
CloseHandle(thread);
return 0;
}
int32 pthread_mutex_init(pthread_mutex_t* mutex, pthread_mutexattr_t*)
{
if (mutex == NULL) {
return 1;
}
InitializeCriticalSection(mutex);
return 0;
}
int32 pthread_mutex_destroy(pthread_mutex_t* mutex)
{
if (mutex == NULL) {
return 1;
}
DeleteCriticalSection(mutex);
return 0;
}
int32 pthread_mutex_lock(pthread_mutex_t* mutex)
{
if (mutex == NULL) {
return 1;
}
EnterCriticalSection(mutex);
return 0;
}
int32 pthread_mutex_unlock(pthread_mutex_t* mutex)
{
if (mutex == NULL) {
return 1;
}
LeaveCriticalSection(mutex);
return 0;
}
int32 pthread_cond_init(pthread_cond_t* cond, pthread_condattr_t*)
{
if (cond == NULL) {
return 1;
}
InitializeConditionVariable(cond);
return 0;
}
int32 pthread_cond_destroy(pthread_cond_t*)
{
/* Windows does not have a destroy for conditionals */
return 0;
}
static DWORD timespec_to_ms(const timespec* abstime)
{
if (abstime == NULL) {
return INFINITE;
}
DWORD t = (DWORD) (((abstime->tv_sec - time(0)) * 1000) + (abstime->tv_nsec / 1000000));
return t < 0 ? 1 : t;
}
int32 pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* abstime)
{
if (cond == NULL || mutex == NULL) {
return 1;
}
if (!SleepConditionVariableCS(cond, mutex, timespec_to_ms(abstime))) {
return 1;
}
return 0;
}
int32 pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex)
{
if (cond == NULL || mutex == NULL) {
return 1;
}
return pthread_cond_timedwait(cond, mutex, NULL);
}
int32 pthread_cond_signal(pthread_cond_t* cond)
{
if (cond == NULL) {
return 1;
}
WakeConditionVariable(cond);
return 0;
}
int32 pthread_cond_broadcast(pthread_cond_t* cond)
{
if (cond == NULL) {
return 1;
}
WakeAllConditionVariable(cond);
return 0;
}
int32 pthread_rwlock_init(pthread_rwlock_t* rwlock, const pthread_rwlockattr_t*)
{
if (rwlock == NULL) {
return 1;
}
InitializeSRWLock(&rwlock->lock);
rwlock->exclusive = false;
return 0;
}
int32 pthread_rwlock_destroy(pthread_rwlock_t*)
{
return 0;
}
int32 pthread_rwlock_rdlock(pthread_rwlock_t* rwlock)
{
if (rwlock == NULL) {
return 1;
}
AcquireSRWLockShared(&rwlock->lock);
return 0;
}
int32 pthread_rwlock_tryrdlock(pthread_rwlock_t* rwlock)
{
if (rwlock == NULL) {
return 1;
}
return !TryAcquireSRWLockShared(&rwlock->lock);
}
int32 pthread_rwlock_wrlock(pthread_rwlock_t* rwlock)
{
if (rwlock == NULL) {
return 1;
}
AcquireSRWLockExclusive(&rwlock->lock);
rwlock->exclusive = true;
return 0;
}
int32 pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
{
if (rwlock == NULL) {
return 1;
}
BOOLEAN ret = TryAcquireSRWLockExclusive(&rwlock->lock);
if (ret) {
rwlock->exclusive = true;
}
return ret;
}
int32 pthread_rwlock_unlock(pthread_rwlock_t* rwlock)
{
if (rwlock == NULL) {
return 1;
}
if (rwlock->exclusive) {
rwlock->exclusive = false;
ReleaseSRWLockExclusive(&rwlock->lock);
} else {
ReleaseSRWLockShared(&rwlock->lock);
}
return 0;
}
uint32 pcthread_get_num_procs()
{
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
return sysinfo.dwNumberOfProcessors;
}
#define pthread_exit(a) {return (a);}
#else
uint32 pcthread_get_num_procs()
{
return (uint32) sysconf(_SC_NPROCESSORS_ONLN);
}
#endif
#endif

View File

@ -12,6 +12,7 @@
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <time.h>
#ifdef _MSC_VER
#include <io.h>
@ -21,6 +22,7 @@
#include "../../utils/Utils.h"
#include "../../utils/TestUtils.h"
#include "../../memory/RingMemory.h"
#include "../../log/Debug.cpp"
#define strtok_r strtok_s
@ -60,9 +62,36 @@ time_t system_time()
return ((time_t) (largeInt.QuadPart / 10000000ULL)) - ((time_t) 11644473600ULL);
}
// doesn't return clock time, only to return time since program start
// -> can be used for profiling
inline
uint64 time_mu()
{
LARGE_INTEGER counter;
QueryPerformanceCounter(&counter);
return (counter.QuadPart * 1000000) / debug_container->performance_count_frequency;
}
inline
time_t unix_epoch_s()
{
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
ULARGE_INTEGER li;
li.LowPart = ft.dwLowDateTime;
li.HighPart = ft.dwHighDateTime;
time_t seconds_since_epoch = (li.QuadPart - 116444736000000000ULL) / 10000000ULL;
return seconds_since_epoch;
}
// @todo Consider to implement directly mapped files (CreateFileMapping) for certain files (e.g. map data or texture data, ...)
inline void relative_to_absolute(const char* rel, char* path)
inline
void relative_to_absolute(const char* rel, char* path)
{
char self_path[MAX_PATH];
int32 self_path_length = GetModuleFileNameA(NULL, self_path, MAX_PATH);
@ -130,21 +159,6 @@ file_size(const char* path)
return size.QuadPart;
}
inline
uint64 time_mu()
{
LARGE_INTEGER frequency;
LARGE_INTEGER counter;
if (!QueryPerformanceFrequency(&frequency)) {
return 0;
}
QueryPerformanceCounter(&counter);
return (counter.QuadPart * 1000000) / frequency.QuadPart;
}
inline
bool file_exists(const char* path)
{

View File

@ -15,7 +15,6 @@
#include "../../../stdlib/Types.h"
#include "../../../audio/AudioSetting.h"
#include "../../../utils/MathUtils.h"
#include "../../../log/Log.h"
#include "../../../audio/Audio.cpp"

View File

@ -23,7 +23,7 @@
#pragma comment(lib, "hid.lib")
#pragma comment(lib, "setupapi.lib")
void hid_init_contorllers(Input* __restrict states, int32 state_count, RingMemory* ring) {
void hid_init_controllers(Input* __restrict states, int32 state_count, RingMemory* ring) {
HANDLE* controller_handles = NULL;

View File

@ -17,10 +17,7 @@
#include "../../../input/ControllerInput.h"
#include "controller/DualShock4.h"
#include "../../../utils/TestUtils.h"
#include "../../../utils/MathUtils.h"
#include "../../../memory/RingMemory.h"
#include "../../../memory/BufferMemory.h"
#include "../../../stdlib/simd/SIMD_I8.h"
#include <winDNS.h>
#define INPUT_MOUSE_BUTTON_1 1
@ -32,7 +29,7 @@
#define INPUT_MOUSE_BUTTON_HWHEEL 7
// IMPORTANT:
// Even if it is nowhere documented (at least not to our knowledge) the GetRawInputDeviceInfoA, GetRawInputBuffer functions requried
// Even if it is nowhere documented (at least not to our knowledge) the GetRawInputDeviceInfoA, GetRawInputBuffer functions required
// aligned memory. So far we only figured out that 4 bytes works, maybe this needs to be 8 in the future?!
int rawinput_init_mousekeyboard(HWND hwnd, Input* __restrict states, RingMemory* ring)
@ -110,7 +107,7 @@ int rawinput_init_mousekeyboard(HWND hwnd, Input* __restrict states, RingMemory*
return i;
}
// WARNING: While this works we highly recommend to use hid_init_contorllers
// WARNING: While this works we highly recommend to use hid_init_controllers
int rawinput_init_controllers(HWND hwnd, Input* __restrict states, RingMemory* ring)
{
uint32 device_count;

View File

@ -12,7 +12,6 @@
#include <XInput.h>
#include <windows.h>
#include "../../../input/Input.h"
#include "../../../input/ControllerInput.h"
#include "../../../stdlib/Types.h"
#include "../../../utils/MathUtils.h"

View File

@ -6,28 +6,11 @@
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PLATFORM_WIN32_THREAD_DEFINES_H
#define TOS_PLATFORM_WIN32_THREAD_DEFINES_H
#ifndef TOS_PLATFORM_WIN32_THREADING_ATOMIC_H
#define TOS_PLATFORM_WIN32_THREADING_ATOMIC_H
#include <stdio.h>
#include <windows.h>
#include "../../stdlib/Types.h"
typedef DWORD (WINAPI *ThreadJobFunc)(void*);
typedef CRITICAL_SECTION pthread_mutex_t;
typedef void pthread_mutexattr_t;
typedef void pthread_condattr_t;
typedef void pthread_rwlockattr_t;
typedef HANDLE pthread_t;
typedef CONDITION_VARIABLE pthread_cond_t;
struct pthread_rwlock_t {
SRWLOCK lock;
bool exclusive;
};
#define THREAD_RETURN DWORD WINAPI
#include "../../../stdlib/Types.h"
inline
void atomic_set(volatile int32* value, int32 new_value)

View File

@ -0,0 +1,37 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PLATFORM_WIN32_THREADING_SEMAPHORE_H
#define TOS_PLATFORM_WIN32_THREADING_SEMAPHORE_H
#include <windows.h>
#include "../../../stdlib/Types.h"
typedef HANDLE sem_t;
void sem_init(sem_t* semaphore, int32 value)
{
*semaphore = CreateSemaphore(NULL, value, MAX_INT32, NULL);
}
void sem_destroy(sem_t* semaphore)
{
CloseHandle(*semaphore);
}
// decrement if != 0, if = 0 wait
void sem_wait(sem_t* semaphore) {
WaitForSingleObject(*semaphore, INFINITE);
}
// increment
void sem_post(sem_t* semaphore) {
ReleaseSemaphore(*semaphore, 1, NULL);
}
#endif

View File

@ -0,0 +1,26 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PLATFORM_WIN32_THREADING_SPINLOCK_H
#define TOS_PLATFORM_WIN32_THREADING_SPINLOCK_H
#include <windows.h>
typedef volatile long spinlock32;
inline
void spinlock_start(spinlock32* lock) {
while (InterlockedExchange(lock, 1) == 1) {}
}
inline
void spinlock_end(spinlock32* lock) {
InterlockedExchange(lock, 0);
}
#endif

View File

@ -0,0 +1,253 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PLATFORM_WIN32_THREADING_THREAD_H
#define TOS_PLATFORM_WIN32_THREADING_THREAD_H
#include "../../../stdlib/Types.h"
#include "../UtilsWin32.h"
#include "ThreadDefines.h"
#include <windows.h>
int32 pthread_create(pthread_t* thread, void*, ThreadJobFunc start_routine, void* arg)
{
if (thread == NULL || start_routine == NULL) {
return 1;
}
*thread = CreateThread(NULL, 0, start_routine, arg, 0, NULL);
if (*thread == NULL) {
return 1;
}
return 0;
}
int32 pthread_join(pthread_t thread, void**)
{
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
return 0;
}
int32 pthread_detach(pthread_t thread)
{
CloseHandle(thread);
return 0;
}
int32 pthread_mutex_init(pthread_mutex_t* mutex, pthread_mutexattr_t*)
{
if (mutex == NULL) {
return 1;
}
InitializeCriticalSection(mutex);
return 0;
}
int32 pthread_mutex_destroy(pthread_mutex_t* mutex)
{
if (mutex == NULL) {
return 1;
}
DeleteCriticalSection(mutex);
return 0;
}
int32 pthread_mutex_lock(pthread_mutex_t* mutex)
{
if (mutex == NULL) {
return 1;
}
EnterCriticalSection(mutex);
return 0;
}
int32 pthread_mutex_unlock(pthread_mutex_t* mutex)
{
if (mutex == NULL) {
return 1;
}
LeaveCriticalSection(mutex);
return 0;
}
int32 pthread_cond_init(pthread_cond_t* cond, pthread_condattr_t*)
{
if (cond == NULL) {
return 1;
}
InitializeConditionVariable(cond);
return 0;
}
int32 pthread_cond_destroy(pthread_cond_t*)
{
/* Windows does not have a destroy for conditionals */
return 0;
}
static DWORD timespec_to_ms(const timespec* abstime)
{
if (abstime == NULL) {
return INFINITE;
}
time_t seconds_since_epoch = unix_epoch_s();
DWORD t = (DWORD) (((abstime->tv_sec - seconds_since_epoch) * 1000) + (abstime->tv_nsec / 1000000));
return t < 0 ? 1 : t;
}
int32 pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* abstime)
{
if (cond == NULL || mutex == NULL) {
return 1;
}
if (!SleepConditionVariableCS(cond, mutex, timespec_to_ms(abstime))) {
return 1;
}
return 0;
}
int32 pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex)
{
if (cond == NULL || mutex == NULL) {
return 1;
}
return pthread_cond_timedwait(cond, mutex, NULL);
}
int32 pthread_cond_signal(pthread_cond_t* cond)
{
if (cond == NULL) {
return 1;
}
WakeConditionVariable(cond);
return 0;
}
int32 pthread_cond_broadcast(pthread_cond_t* cond)
{
if (cond == NULL) {
return 1;
}
WakeAllConditionVariable(cond);
return 0;
}
int32 pthread_rwlock_init(pthread_rwlock_t* rwlock, const pthread_rwlockattr_t*)
{
if (rwlock == NULL) {
return 1;
}
InitializeSRWLock(&rwlock->lock);
rwlock->exclusive = false;
return 0;
}
int32 pthread_rwlock_destroy(pthread_rwlock_t*)
{
return 0;
}
int32 pthread_rwlock_rdlock(pthread_rwlock_t* rwlock)
{
if (rwlock == NULL) {
return 1;
}
AcquireSRWLockShared(&rwlock->lock);
return 0;
}
int32 pthread_rwlock_tryrdlock(pthread_rwlock_t* rwlock)
{
if (rwlock == NULL) {
return 1;
}
return !TryAcquireSRWLockShared(&rwlock->lock);
}
int32 pthread_rwlock_wrlock(pthread_rwlock_t* rwlock)
{
if (rwlock == NULL) {
return 1;
}
AcquireSRWLockExclusive(&rwlock->lock);
rwlock->exclusive = true;
return 0;
}
int32 pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
{
if (rwlock == NULL) {
return 1;
}
BOOLEAN ret = TryAcquireSRWLockExclusive(&rwlock->lock);
if (ret) {
rwlock->exclusive = true;
}
return ret;
}
int32 pthread_rwlock_unlock(pthread_rwlock_t* rwlock)
{
if (rwlock == NULL) {
return 1;
}
if (rwlock->exclusive) {
rwlock->exclusive = false;
ReleaseSRWLockExclusive(&rwlock->lock);
} else {
ReleaseSRWLockShared(&rwlock->lock);
}
return 0;
}
uint32 pcthread_get_num_procs()
{
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
return sysinfo.dwNumberOfProcessors;
}
#define pthread_exit(a) {return (a);}
#endif

View File

@ -0,0 +1,30 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PLATFORM_WIN32_THREADING_THREAD_DEFINES_H
#define TOS_PLATFORM_WIN32_THREADING_THREAD_DEFINES_H
#include <stdio.h>
#include <windows.h>
typedef DWORD (WINAPI *ThreadJobFunc)(void*);
typedef CRITICAL_SECTION pthread_mutex_t;
typedef void pthread_mutexattr_t;
typedef void pthread_condattr_t;
typedef void pthread_rwlockattr_t;
typedef HANDLE pthread_t;
typedef CONDITION_VARIABLE pthread_cond_t;
struct pthread_rwlock_t {
SRWLOCK lock;
bool exclusive;
};
#define THREAD_RETURN DWORD WINAPI
#endif

View File

@ -9,11 +9,11 @@
#ifndef TOS_STDLIB_HASHMAP_H
#define TOS_STDLIB_HASHMAP_H
#include "Types.h"
#include "../hash/GeneralHash.h"
#include "../memory/RingMemory.h"
#include "../memory/BufferMemory.h"
#include "../memory/ChunkMemory.h"
#include "Types.h"
#include "../utils/StringUtils.h"
#define MAX_KEY_LENGTH 32
@ -406,7 +406,7 @@ int64 hashmap_dump(const HashMap* hm, byte* data)
*((uint64 *) data) = SWAP_ENDIAN_LITTLE(hm->buf.count);
data += sizeof(uint64);
// Dump the table content where the elements are relative indeces/pointers
// Dump the table content where the elements are relative indices/pointers
for (int32 i = 0; i < hm->buf.count; ++i) {
*((uint64 *) data) = hm->table[i]
? SWAP_ENDIAN_LITTLE((uintptr_t) hm->table[i] - (uintptr_t) hm->buf.memory)

View File

@ -15,11 +15,11 @@
#include "../stdlib/Types.h"
#if _WIN32
#include "../platform/win32/ThreadDefines.h"
#include "../platform/win32/Thread.h"
#include "../platform/win32/threading/Thread.h"
#include "../platform/win32/threading/Atomic.h"
#elif __linux__
#include "../platform/linux/ThreadDefines.h"
#include "../platform/linux/Thread.h"
#include "../platform/linux/threading/Thread.h"
#include "../platform/linux/threading/Atomic.h"
#endif
#include "ThreadJob.h"

View File

@ -15,9 +15,9 @@
#include "../stdlib/Types.h"
#if _WIN32
#include "../platform/win32/ThreadDefines.h"
#include "../platform/win32/threading/ThreadDefines.h"
#elif __linux__
#include "../platform/linux/ThreadDefines.h"
#include "../platform/linux/threading/ThreadDefines.h"
#endif
struct PoolWorker {

View File

@ -15,9 +15,9 @@
#include "../stdlib/Types.h"
#ifdef _WIN32
#include "../platform/win32/Thread.h"
#include "../platform/win32/threading/Thread.h"
#elif __linux__
#include "../platform/linux/Thread.h"
#include "../platform/linux/threading/Thread.h"
#endif
#include "ThreadJob.h"

View File

@ -105,7 +105,7 @@ int compare_by_attribute_id(const void* a, const void* b) {
// attributes ...
// attributes ...
// WARNING: theme needs to have memory already reserved and asigned to data
// WARNING: theme needs to have memory already reserved and assigned to data
void theme_from_file_txt(
UIThemeStyle* theme,
byte* data
@ -127,7 +127,7 @@ void theme_from_file_txt(
int32 temp_group_count = 0;
while (*pos != '\0') {
// Skip all white spaces
char_skip_empty(&pos);
str_skip_empty(&pos);
// Is group name
if (*pos == '#' || *pos == '.') {
@ -135,7 +135,7 @@ void theme_from_file_txt(
}
// Go to the end of the line
char_move_to(&pos, '\n');
str_move_to(&pos, '\n');
// Go to next line
if (*pos != '\0') {
@ -154,7 +154,7 @@ void theme_from_file_txt(
pos += 8; // move past version
while (*pos != '\0') {
char_skip_empty(&pos);
str_skip_empty(&pos);
if (*pos == '\n') {
++pos;
@ -173,7 +173,7 @@ void theme_from_file_txt(
last_token_newline = false;
if (!block_open) {
char_copy_move_until(&pos, block_name, " \n", sizeof(" \n") - 1);
str_copy_move_until(&pos, block_name, " \n", sizeof(" \n") - 1);
// All blocks need to start with #. In the past this wasn't the case and may not be in the future. This is why we keep this if here.
if (*block_name == '#' || *block_name == '.') {
@ -198,10 +198,10 @@ void theme_from_file_txt(
continue;
}
char_copy_move_until(&pos, attribute_name, " :\n", sizeof(" :\n") - 1);
str_copy_move_until(&pos, attribute_name, " :\n", sizeof(" :\n") - 1);
// Skip any white spaces or other delimeters
char_skip_list(&pos, " \t:", sizeof(" \t:") - 1);
str_skip_list(&pos, " \t:", sizeof(" \t:") - 1);
ASSERT_SIMPLE((*pos != '\0' && *pos != '\n'));
@ -211,7 +211,7 @@ void theme_from_file_txt(
attribute.attribute_id = UI_ATTRIBUTE_TYPE_TYPE;
char str[32];
char_copy_move_until(&pos, str, '\n');
str_copy_move_until(&pos, str, '\n');
for (int32 j = 0; j < UI_ELEMENT_TYPE_SIZE; ++j) {
if (strcmp(str, ui_element_type_to_string_const((UIElementType) j)) == 0) {
@ -225,7 +225,7 @@ void theme_from_file_txt(
} else if (strcmp(ui_attribute_type_to_string_const(UI_ATTRIBUTE_TYPE_STYLE), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_STYLE;
char_copy_move_until(&pos, attribute.value_str, '\n');
str_copy_move_until(&pos, attribute.value_str, '\n');
} else if (strcmp(ui_attribute_type_to_string_const(UI_ATTRIBUTE_TYPE_FONT_COLOR), attribute_name) == 0) {
++pos; // Skip '#'
@ -257,7 +257,7 @@ void theme_from_file_txt(
} else if (strcmp(ui_attribute_type_to_string_const(UI_ATTRIBUTE_TYPE_BACKGROUND_IMG), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BACKGROUND_IMG;
char_copy_move_until(&pos, attribute.value_str, '\n');
str_copy_move_until(&pos, attribute.value_str, '\n');
} else if (strcmp(ui_attribute_type_to_string_const(UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_OPACITY), attribute_name) == 0) {
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BACKGROUND_IMG_OPACITY;
attribute.value_float = SWAP_ENDIAN_LITTLE(strtof(pos, &pos));
@ -354,7 +354,7 @@ void theme_from_file_txt(
attribute.attribute_id = UI_ATTRIBUTE_TYPE_TRANSITION_DURATION;
attribute.value_float = strtof(pos, &pos);
} else {
char_move_to(&pos, '\n');
str_move_to(&pos, '\n');
continue;
}
@ -372,7 +372,7 @@ void theme_from_file_txt(
++temp_group->attribute_size;
}
char_move_to(&pos, '\n');
str_move_to(&pos, '\n');
}
// We still need to sort the last group

View File

@ -1,51 +0,0 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_UTILS_FAST_PIPES_H
#define TOS_UTILS_FAST_PIPES_H
// requires kernel32.lib and user32.lib
#include "../stdlib/Types.h"
#if _WIN32
#include <windows.h>
#include <io.h>
#include <fcntl.h>
#include <stdio.h>
static int ENABLE_FAST_PIPES()
{
int32 result = 0;
wchar_t pipe_name[32];
wsprintfW(pipe_name, L"\\\\.\\pipe\\fastpipe%x", GetCurrentProcessId());
HANDLE fast_pip = CreateFileW(pipe_name, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if(fast_pip != INVALID_HANDLE_VALUE) {
SetStdHandle(STD_OUTPUT_HANDLE, fast_pip);
SetStdHandle(STD_INPUT_HANDLE, fast_pip);
int32 std_out = _open_osfhandle((intptr_t) fast_pip, O_WRONLY | O_TEXT);
int32 std_in = _open_osfhandle((intptr_t) fast_pip, O_RDONLY | O_TEXT);
_dup2(std_out, _fileno(stdout));
_dup2(std_in, _fileno(stdin));
_close(std_out);
_close(std_in);
result = 1;
}
return result;
}
#else
#define ENABLE_FAST_PIPES(...) 0
#endif
#endif

View File

@ -12,12 +12,6 @@
#include <math.h>
#if ARM
#include "../stdlib/IntrinsicsArm.h"
#else
#include "../stdlib/Intrinsics.h"
#endif
#define OMS_PI 3.14159265358979323846f
#define OMS_PI_OVER_TWO (OMS_PI / 2.0f)
#define OMS_PI_OVER_FOUR (OMS_PI / 4.0f)
@ -25,7 +19,7 @@
#define OMS_MAX(a, b) ((a) > (b) ? (a) : (b))
#define OMS_MIN(a, b) ((a) > (b) ? (b) : (a))
#define OMS_CLAMP(a, b, c) (OMS_MAX(OMS_MIN((a), (b))), (c))
#define OMS_CLAMP(a, b, c) (OMS_MAX(OMS_MIN((a), (b)), (c)))
#define OMS_ABS(a) ((a) > 0 ? (a) : -(a))
#define OMS_DEG2RAD(angle) ((angle) * OMS_PI / 180.0f)
#define OMS_RAD2DEG(angle) ((angle) * 180.0f / OMS_PI)

View File

@ -136,12 +136,12 @@ int32 utf8_get_char_at(const char* in, int32 index) {
inline
void wchar_to_char(wchar_t* str)
{
char *src = (char*) str;
char *dest = (char *) src;
char* src = (char*) str;
char* dest = src;
while (*src != '\0' && src[1] != '\0') {
if (*src != '\0') {
*dest++ = (char) *src;
*dest++ = *src;
}
++src;
@ -151,16 +151,14 @@ void wchar_to_char(wchar_t* str)
}
inline
void wchar_to_char(const char* str, char* __restrict dest)
void wchar_to_char(const char* __restrict str, char* __restrict dest)
{
char *src = (char*) str;
while (*src != '\0' && src[1] != '\0') {
if (*src != '\0') {
*dest++ = (char) *src;
while (*str != '\0' && str[1] != '\0') {
if (*str != '\0') {
*dest++ = (char) *str;
}
++src;
++str;
}
*dest = '\0';
@ -189,8 +187,8 @@ int32 str_to_int(const char *str)
inline constexpr
int32 int_to_str(int64 number, char *str, const char thousands = ',') {
int32 i = 0;
int64 sign = number;
int32 digit_count = 0;
int64 sign = number;
if (number == 0) {
str[i++] = '0';
@ -243,7 +241,8 @@ size_t str_count(const char* __restrict str, const char* __restrict substr)
return count;
}
inline char* strsep(const char* *sp, const char* sep)
inline
char* strsep(const char** sp, const char* sep)
{
char* p, *s;
@ -251,7 +250,7 @@ inline char* strsep(const char* *sp, const char* sep)
return (NULL);
}
s = (char* ) *sp;
s = (char *) *sp;
p = s + strcspn(s, sep);
if (*p != '\0') {
@ -431,8 +430,7 @@ void str_replace(const char* str, const char* __restrict search, const char* __r
memcpy(result_ptr, replace, replace_len);
result_ptr += replace_len;
current += search_len;
str = current;
str = current + search_len;
}
strcpy(result_ptr, str);
@ -476,7 +474,7 @@ bool is_whitespace(char str)
}
inline
int32 chars_to_eol(const char* str)
int32 str_to_eol(const char* str)
{
int32 offset = 0;
while (!is_eol(str) && *str++ != '\0') {
@ -487,7 +485,7 @@ int32 chars_to_eol(const char* str)
}
inline
int32 chars_to(const char* str, char delim)
int32 str_to(const char* str, char delim)
{
int32 offset = 0;
while (*str != delim && *str++ != '\0') {
@ -498,7 +496,7 @@ int32 chars_to(const char* str, char delim)
}
inline
void char_move_to(char** str, const char delim)
void str_move_to(char** str, char delim)
{
while (**str != delim && **str != '\0') {
++(*str);
@ -506,7 +504,7 @@ void char_move_to(char** str, const char delim)
}
inline
void char_move_past(char** str, const char delim)
void str_move_past(char** str, char delim)
{
while (**str != delim && **str != '\0') {
++(*str);
@ -518,7 +516,7 @@ void char_move_past(char** str, const char delim)
}
inline
void char_move_past_alpha_num(char** str)
void str_move_past_alpha_num(char** str)
{
while ((**str >= 48 && **str <= 57)
|| (**str >= 65 && **str <= 90)
@ -536,7 +534,7 @@ bool str_is_comment(char* str)
}
inline
void char_skip(char** str, const char delim)
void str_skip(char** str, char delim)
{
while (**str == delim) {
++(*str);
@ -544,7 +542,7 @@ void char_skip(char** str, const char delim)
}
inline
void char_skip_whitespace(char** str)
void str_skip_whitespace(char** str)
{
while (**str == ' ' || **str == '\t') {
++(*str);
@ -552,7 +550,7 @@ void char_skip_whitespace(char** str)
}
inline
void char_skip_empty(char** str)
void str_skip_empty(char** str)
{
while (**str == ' ' || **str == '\t' || **str == '\n' || **str == '\r') {
++(*str);
@ -560,7 +558,7 @@ void char_skip_empty(char** str)
}
inline
void char_skip_non_empty(char** str)
void str_skip_non_empty(char** str)
{
while (**str != ' ' && **str != '\t' && **str != '\n' && **str != '\0') {
++(*str);
@ -568,7 +566,7 @@ void char_skip_non_empty(char** str)
}
inline
void char_skip_list(char** __restrict str, const char* __restrict delim, int32 len)
void str_skip_list(char** __restrict str, const char* __restrict delim, int32 len)
{
bool run = true;
while (run && **str != '\0') {
@ -586,7 +584,7 @@ void char_skip_list(char** __restrict str, const char* __restrict delim, int32 l
}
inline
void char_skip_until_list(char** __restrict str, const char* __restrict delim, int32 len)
void str_skip_until_list(char** __restrict str, const char* __restrict delim, int32 len)
{
while (**str != '\0') {
for (int32 i = 0; i < len; ++i) {
@ -600,7 +598,7 @@ void char_skip_until_list(char** __restrict str, const char* __restrict delim, i
}
inline
void char_copy_until(const char* __restrict src, char* __restrict dest, char delim)
void str_copy_until(const char* __restrict src, char* __restrict dest, char delim)
{
while (*src != delim && *src != '\0') {
*dest++ = *src++;
@ -610,7 +608,7 @@ void char_copy_until(const char* __restrict src, char* __restrict dest, char del
}
inline
void char_copy_until(const char* __restrict src, char* __restrict dest, const char* __restrict delim, int32 len)
void str_copy_until(const char* __restrict src, char* __restrict dest, const char* __restrict delim, int32 len)
{
while (*src != '\0') {
for (int32 i = 0; i < len; ++i) {
@ -627,9 +625,37 @@ void char_copy_until(const char* __restrict src, char* __restrict dest, const ch
}
inline
void char_copy_move_until(char** __restrict src, char* __restrict dest, char delim)
int32 str_copy_until(char* __restrict dest, const char* __restrict src, char delim)
{
while (**src != delim) {
int32 len = 0;
while (*src != delim && *src != '\0') {
*dest++ = *src++;
++len;
}
*dest = '\0';
return len;
}
inline
int32 str_copy(char* __restrict dest, const char* __restrict src, char delim)
{
int32 len = 0;
while (*src != delim) {
*dest++ = *src++;
++len;
}
*dest = '\0';
return len;
}
inline
void str_copy_move_until(char** __restrict src, char* __restrict dest, char delim)
{
while (**src != delim && **src != '\0') {
*dest++ = **src;
++(*src);
}
@ -638,7 +664,7 @@ void char_copy_move_until(char** __restrict src, char* __restrict dest, char del
}
inline
void char_copy_move_until(char** __restrict src, char* __restrict dest, const char* __restrict delim, int32 len)
void str_copy_move_until(char** __restrict src, char* __restrict dest, const char* __restrict delim, int32 len)
{
while (**src != '\0') {
for (int32 i = 0; i < len; ++i) {
@ -655,8 +681,6 @@ void char_copy_move_until(char** __restrict src, char* __restrict dest, const ch
*dest = '\0';
}
// @question Do we really need this, isn't char_copy_move_until better?
// Maybe create a copy_move_until_eol
inline
int32 strcpy_to_eol(const char* src, char* dst)
{

View File

@ -1,15 +0,0 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_UTILS_SYSTEM_UTILS_H
#define TOS_UTILS_SYSTEM_UTILS_H
#include <stdio.h>
#include <stdint.h>
#endif

View File

@ -10,7 +10,6 @@
#define TOS_UTILS_H
#include <stdlib.h>
#include <time.h>
#include "../stdlib/Types.h"