mirror of
https://github.com/Karaka-Management/cOMS.git
synced 2026-01-11 03:08:41 +00:00
big rewrite, working. & started to test network connection, not working
This commit is contained in:
parent
5cc4204007
commit
b26db7a2d7
|
|
@ -132,7 +132,7 @@ uint32 lzp3_encode(const byte* in, size_t length, byte* out) {
|
|||
|
||||
int32 out_size = 0;
|
||||
|
||||
int32 i = 0;
|
||||
size_t i = 0;
|
||||
while (i < length) {
|
||||
int32 match_position = 0;
|
||||
int32 match_length = find_longest_match(window, window_start, (char *)&in[i], (int32) (length - i), &match_position);
|
||||
|
|
@ -163,7 +163,7 @@ uint32 lzp3_decode(const byte* in, size_t length, byte* out) {
|
|||
|
||||
int32 out_size = 0;
|
||||
|
||||
int32 i = 0;
|
||||
size_t i = 0;
|
||||
while (i < length) {
|
||||
if (in[i] == 0xFF) {
|
||||
int32 match_position = in[i + 1];
|
||||
|
|
|
|||
|
|
@ -456,6 +456,8 @@ void text_calculate_dimensions(
|
|||
*height = y;
|
||||
}
|
||||
|
||||
// @todo implement shadow (offset + angle + diffuse) or should this be a shader only thing? if so this would be a problem for us since we are handling text in the same shader as simple shapes
|
||||
// we might want to implement distance field font atlas
|
||||
f32 vertex_text_create(
|
||||
Vertex3DTextureColorIndex* __restrict vertices, uint32* __restrict index, f32 zindex,
|
||||
f32 x, f32 y, f32 width, f32 height, int32 align_h, int32 align_v,
|
||||
|
|
@ -543,6 +545,8 @@ f32 vertex_text_create(
|
|||
return offset_x;
|
||||
}
|
||||
|
||||
// @todo implement shadow (offset + angle + diffuse) or should this be a shader only thing? if so this would be a problem for us since we are handling text in the same shader as simple shapes
|
||||
// we might want to implement distance field font atlas
|
||||
f32 ui_text_create(
|
||||
Vertex3DTextureColorIndex* __restrict vertices, uint32* __restrict index, f32 zindex,
|
||||
UITheme* theme, UIElement* element
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ GLuint shader_make(GLenum type, const char *source, RingMemory* ring)
|
|||
|
||||
inline
|
||||
GLuint shader_load(GLenum type, const char* path, RingMemory* ring) {
|
||||
uint64 temp = ring->pos;
|
||||
byte* temp = ring->head;
|
||||
|
||||
FileBody file;
|
||||
|
||||
|
|
@ -185,7 +185,7 @@ GLuint shader_load(GLenum type, const char* path, RingMemory* ring) {
|
|||
GLuint result = shader_make(type, (const char *) file.content, ring);
|
||||
|
||||
// We can immediately dispose of it we can also reset our ring memory position
|
||||
ring->pos = temp;
|
||||
ring->head = temp;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
229
log/Debug.cpp
229
log/Debug.cpp
|
|
@ -13,12 +13,70 @@ global_persist DebugContainer* debug_container = NULL;
|
|||
#if _WIN32
|
||||
#include <windows.h>
|
||||
void setup_performance_count() {
|
||||
if (!debug_container) {
|
||||
return;
|
||||
}
|
||||
|
||||
LARGE_INTEGER perf_counter;
|
||||
QueryPerformanceFrequency(&perf_counter);
|
||||
debug_container->performance_count_frequency = perf_counter.QuadPart;
|
||||
}
|
||||
#else
|
||||
void setup_performance_count() {
|
||||
if (!debug_container) {
|
||||
return;
|
||||
}
|
||||
|
||||
FILE* fp = fopen("/proc/cpuinfo", "r");
|
||||
if (!fp) {
|
||||
return;
|
||||
}
|
||||
|
||||
char line[256];
|
||||
uint64 cpu_freq = 0;
|
||||
while (fgets(line, sizeof(line), fp)) {
|
||||
if (sscanf(line, "cpu MHz%*[^0-9]%ld", &cpu_freq) == 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
debug_container->performance_count_frequency = cpu_freq == 0 ? 1 : cpu_freq * 1000000;
|
||||
}
|
||||
#endif
|
||||
|
||||
void log_to_file()
|
||||
{
|
||||
// we don't log an empty log pool
|
||||
if (!debug_container || debug_container->log_memory.pos == 0 || !debug_container->log_fp) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if _WIN32
|
||||
DWORD written;
|
||||
if (!WriteFile(
|
||||
debug_container->log_fp, (char *) debug_container->log_memory.memory, (uint32) debug_container->log_memory.pos - 1, &written, NULL)
|
||||
) {
|
||||
CloseHandle(debug_container->log_fp);
|
||||
}
|
||||
#else
|
||||
if (debug_container->log_fp < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!write(debug_container->log_fp, (char *) debug_container->log_memory.memory, (uint32) debug_container->log_memory.pos - 1)) {
|
||||
close(debug_container->log_fp);
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(debug_container->log_memory.memory, 0, debug_container->log_memory.size);
|
||||
|
||||
// reset log position to start of memory pool
|
||||
debug_container->log_memory.pos = 0;
|
||||
debug_container->log_memory.start = 0;
|
||||
}
|
||||
|
||||
// IMPORTANT: This function should only be called when you actually use this data
|
||||
// e.g. log to display or file
|
||||
inline
|
||||
|
|
@ -33,7 +91,7 @@ void update_timing_stat(uint32 stat, const char* function)
|
|||
}
|
||||
|
||||
inline
|
||||
void update_timing_stat_start(uint32 stat, const char* function)
|
||||
void update_timing_stat_start(uint32 stat, const char*)
|
||||
{
|
||||
uint64 new_tick_count = __rdtsc();
|
||||
|
||||
|
|
@ -92,7 +150,7 @@ void log_counter(int32 id, int32 value)
|
|||
inline
|
||||
DebugMemory* debug_memory_find(uint64 start)
|
||||
{
|
||||
for (int32 i = 0; i < debug_container->dmc.memory_size; ++i) {
|
||||
for (uint64 i = 0; i < debug_container->dmc.memory_size; ++i) {
|
||||
if (debug_container->dmc.memory_stats[i].start <= start
|
||||
&& debug_container->dmc.memory_stats[i].start + debug_container->dmc.memory_stats[i].size >= start
|
||||
) {
|
||||
|
|
@ -152,7 +210,7 @@ void debug_memory_log(uint64 start, uint64 size, int32 type, const char* functio
|
|||
mem->last_action[mem->action_idx].start = start - mem->start;
|
||||
mem->last_action[mem->action_idx].size = size;
|
||||
|
||||
// @question consider to use other time_ms() since __rdtsc is variable (boost, power saving)
|
||||
// We are using rdtsc since it is faster -> less debugging overhead than using time()
|
||||
mem->last_action[mem->action_idx].time = __rdtsc();
|
||||
mem->last_action[mem->action_idx].function_name = function;
|
||||
|
||||
|
|
@ -179,7 +237,7 @@ void debug_memory_reserve(uint64 start, uint64 size, int32 type, const char* fun
|
|||
mem->reserve_action[mem->reserve_action_idx].start = start - mem->start;
|
||||
mem->reserve_action[mem->reserve_action_idx].size = size;
|
||||
|
||||
// @question consider to use other time_ms() since __rdtsc is variable (boost, power saving)
|
||||
// We are using rdtsc since it is faster -> less debugging overhead than using time()
|
||||
mem->reserve_action[mem->reserve_action_idx].time = __rdtsc();
|
||||
mem->reserve_action[mem->reserve_action_idx].function_name = function;
|
||||
|
||||
|
|
@ -195,7 +253,7 @@ void debug_memory_reset()
|
|||
|
||||
uint64 time = __rdtsc() - 1000000000;
|
||||
|
||||
for (int32 i = 0; i < debug_container->dmc.memory_element_idx; ++i) {
|
||||
for (uint64 i = 0; i < debug_container->dmc.memory_element_idx; ++i) {
|
||||
for (int32 j = 0; j < DEBUG_MEMORY_RANGE_MAX; ++j) {
|
||||
if (debug_container->dmc.memory_stats[i].last_action[j].time < time) {
|
||||
memset(&debug_container->dmc.memory_stats[i].last_action[j], 0, sizeof(DebugMemoryRange));
|
||||
|
|
@ -237,109 +295,90 @@ byte* log_get_memory(uint64 size, byte aligned = 1, bool zeroed = false)
|
|||
return offset;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void log_to_file()
|
||||
{
|
||||
// we don't log an empty log pool
|
||||
if (!debug_container || debug_container->log_memory.pos == 0 || !debug_container->log_fp || debug_container->log_fp == INVALID_HANDLE_VALUE) {
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD written;
|
||||
if (!WriteFile(debug_container->log_fp, (char *) debug_container->log_memory.memory, (uint32) debug_container->log_memory.pos - 1, &written, NULL)) {
|
||||
CloseHandle(debug_container->log_fp);
|
||||
}
|
||||
|
||||
memset(debug_container->log_memory.memory, 0, debug_container->log_memory.size);
|
||||
|
||||
// reset log position to start of memory pool
|
||||
debug_container->log_memory.pos = 0;
|
||||
debug_container->log_memory.start = 0;
|
||||
// @todo add file name, function name and function line
|
||||
void log(const char* str, bool should_log, bool save, const char* file, const char* function, int32 line)
|
||||
{
|
||||
if (!should_log || !debug_container) {
|
||||
return;
|
||||
}
|
||||
|
||||
// @todo add file name, function name and function line
|
||||
void log(const char* str, bool should_log, bool save, const char* file, const char* function, int32 line)
|
||||
{
|
||||
if (!should_log || !debug_container) {
|
||||
return;
|
||||
}
|
||||
size_t str_len = strlen(str);
|
||||
size_t file_len = strlen(file);
|
||||
size_t function_len = strlen(function);
|
||||
|
||||
size_t str_len = strlen(str);
|
||||
size_t file_len = strlen(file);
|
||||
size_t function_len = strlen(function);
|
||||
char line_str[10];
|
||||
int_to_str(line, line_str, '\0');
|
||||
|
||||
char line_str[10];
|
||||
int_to_str(line, line_str, '\0');
|
||||
size_t line_len = strlen(line_str);
|
||||
|
||||
size_t line_len = strlen(line_str);
|
||||
ASSERT_SIMPLE(str_len + file_len + function_len + line_len + 3 < MAX_LOG_LENGTH);
|
||||
|
||||
ASSERT_SIMPLE(str_len + file_len + function_len + line_len + 3 < MAX_LOG_LENGTH);
|
||||
char* temp = (char *) log_get_memory(str_len + file_len + function_len + line_len + 3 + 1);
|
||||
memcpy(temp, file, file_len);
|
||||
temp[file_len] = ';';
|
||||
|
||||
char* temp = (char *) log_get_memory(str_len + file_len + function_len + line_len + 3 + 1);
|
||||
memcpy(temp, file, file_len);
|
||||
temp[file_len] = ';';
|
||||
memcpy(&temp[file_len], function, function_len);
|
||||
temp[file_len + 1 + function_len] = ';';
|
||||
|
||||
memcpy(&temp[file_len], function, function_len);
|
||||
temp[file_len + 1 + function_len] = ';';
|
||||
memcpy(&temp[file_len + 1 + function_len], line_str, line_len);
|
||||
temp[file_len + 1 + function_len + 1 + line_len] = ';';
|
||||
|
||||
memcpy(&temp[file_len + 1 + function_len], line_str, line_len);
|
||||
temp[file_len + 1 + function_len + 1 + line_len] = ';';
|
||||
memcpy(&temp[file_len + 1 + function_len + 1 + line_len + 1], str, str_len);
|
||||
temp[file_len + 1 + function_len + 1 + line_len + 1 + str_len] = '\0';
|
||||
|
||||
memcpy(&temp[file_len + 1 + function_len + 1 + line_len + 1], str, str_len);
|
||||
temp[file_len + 1 + function_len + 1 + line_len + 1 + str_len] = '\0';
|
||||
|
||||
if (save || debug_container->log_memory.size - debug_container->log_memory.pos < MAX_LOG_LENGTH) {
|
||||
log_to_file();
|
||||
}
|
||||
|
||||
ASSERT_SIMPLE(false);
|
||||
if (save || debug_container->log_memory.size - debug_container->log_memory.pos < MAX_LOG_LENGTH) {
|
||||
log_to_file();
|
||||
}
|
||||
|
||||
void log(const char* format, LogDataType data_type, void* data, bool should_log, bool save, const char* file, const char* function, int32 line)
|
||||
{
|
||||
if (!should_log || !debug_container) {
|
||||
return;
|
||||
}
|
||||
ASSERT_SIMPLE(false);
|
||||
}
|
||||
|
||||
if (data_type == LOG_DATA_VOID) {
|
||||
log(format, should_log, save, file, function, line);
|
||||
}
|
||||
|
||||
char* temp = (char *) log_get_memory(MAX_LOG_LENGTH);
|
||||
|
||||
switch (data_type) {
|
||||
case LOG_DATA_INT32: {
|
||||
sprintf(temp, format, *((int32 *) data));
|
||||
} break;
|
||||
case LOG_DATA_UINT32: {
|
||||
sprintf(temp, format, *((uint32 *) data));
|
||||
} break;
|
||||
case LOG_DATA_INT64: {
|
||||
sprintf(temp, format, *((int64 *) data));
|
||||
} break;
|
||||
case LOG_DATA_UINT64: {
|
||||
sprintf(temp, format, *((uint64 *) data));
|
||||
} break;
|
||||
case LOG_DATA_CHAR: {
|
||||
sprintf(temp, format, *((char *) data));
|
||||
} break;
|
||||
case LOG_DATA_CHAR_STR: {
|
||||
sprintf(temp, format, *((char *) data));
|
||||
} break;
|
||||
case LOG_DATA_FLOAT32: {
|
||||
sprintf(temp, format, *((f32 *) data));
|
||||
} break;
|
||||
case LOG_DATA_FLOAT64: {
|
||||
sprintf(temp, format, *((f64 *) data));
|
||||
} break;
|
||||
}
|
||||
|
||||
if (save || debug_container->log_memory.size - debug_container->log_memory.pos < MAX_LOG_LENGTH) {
|
||||
log_to_file();
|
||||
}
|
||||
|
||||
ASSERT_SIMPLE(false);
|
||||
void log(const char* format, LogDataType data_type, void* data, bool should_log, bool save, const char* file, const char* function, int32 line)
|
||||
{
|
||||
if (!should_log || !debug_container) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data_type == LOG_DATA_VOID) {
|
||||
log(format, should_log, save, file, function, line);
|
||||
}
|
||||
|
||||
char* temp = (char *) log_get_memory(MAX_LOG_LENGTH);
|
||||
|
||||
switch (data_type) {
|
||||
case LOG_DATA_INT32: {
|
||||
sprintf(temp, format, *((int32 *) data));
|
||||
} break;
|
||||
case LOG_DATA_UINT32: {
|
||||
sprintf(temp, format, *((uint32 *) data));
|
||||
} break;
|
||||
case LOG_DATA_INT64: {
|
||||
sprintf(temp, format, *((int64 *) data));
|
||||
} break;
|
||||
case LOG_DATA_UINT64: {
|
||||
sprintf(temp, format, *((uint64 *) data));
|
||||
} break;
|
||||
case LOG_DATA_CHAR: {
|
||||
sprintf(temp, format, *((char *) data));
|
||||
} break;
|
||||
case LOG_DATA_CHAR_STR: {
|
||||
sprintf(temp, format, *((char *) data));
|
||||
} break;
|
||||
case LOG_DATA_FLOAT32: {
|
||||
sprintf(temp, format, *((f32 *) data));
|
||||
} break;
|
||||
case LOG_DATA_FLOAT64: {
|
||||
sprintf(temp, format, *((f64 *) data));
|
||||
} break;
|
||||
default: {}
|
||||
}
|
||||
|
||||
if (save || debug_container->log_memory.size - debug_container->log_memory.pos < MAX_LOG_LENGTH) {
|
||||
log_to_file();
|
||||
}
|
||||
|
||||
ASSERT_SIMPLE(false);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
13
log/Debug.h
13
log/Debug.h
|
|
@ -14,6 +14,17 @@
|
|||
#include "Log.h"
|
||||
#include "TimingStat.h"
|
||||
|
||||
struct LogMemory {
|
||||
byte* memory;
|
||||
|
||||
uint32 id;
|
||||
uint64 size;
|
||||
uint64 pos;
|
||||
int32 alignment;
|
||||
uint64 start;
|
||||
uint64 end;
|
||||
};
|
||||
|
||||
struct DebugContainer {
|
||||
DebugMemoryContainer dmc;
|
||||
|
||||
|
|
@ -31,6 +42,8 @@ struct DebugContainer {
|
|||
|
||||
#if _WIN32
|
||||
HANDLE log_fp;
|
||||
#elif __linux__
|
||||
int32 log_fp;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ struct DebugMemoryContainer {
|
|||
#if DEBUG || INTERNAL
|
||||
void debug_memory_init(uint64, uint64);
|
||||
void debug_memory_log(uint64, uint64, int32, const char*);
|
||||
void debug_memory_reserve(uint64, uint64, const char*);
|
||||
void debug_memory_reserve(uint64, uint64, int32, const char*);
|
||||
void debug_memory_reset();
|
||||
|
||||
#define DEBUG_MEMORY_INIT(start, size) debug_memory_init((start), (size))
|
||||
|
|
|
|||
13
log/Log.h
13
log/Log.h
|
|
@ -41,17 +41,6 @@ enum LogDataType {
|
|||
LOG_DATA_FLOAT64
|
||||
};
|
||||
|
||||
struct LogMemory {
|
||||
byte* memory;
|
||||
|
||||
uint32 id;
|
||||
uint64 size;
|
||||
uint64 pos;
|
||||
int32 alignment;
|
||||
uint64 start;
|
||||
uint64 end;
|
||||
};
|
||||
|
||||
void log_to_file();
|
||||
void log(const char* str, bool should_log, bool save, const char* file, const char* function, int32 line);
|
||||
void log(const char* format, LogDataType data_type, void* data, bool should_log, bool save, const char* file, const char* function, int32 line);
|
||||
|
|
@ -71,7 +60,7 @@ void log_counter(int32, int32);
|
|||
#define LOG(str, should_log, save) log((str), (should_log), (save), __FILE__, __func__, __LINE__)
|
||||
#define LOG_FORMAT(format, data_type, data, should_log, save) log((format), (data_type), (data), (should_log), (save), __FILE__, __func__, __LINE__)
|
||||
#define LOG_TO_FILE() log_to_file()
|
||||
#define LOG_INCREMENT(a) log_increment((a))
|
||||
#define LOG_INCREMENT(a) log_increment((a), 1)
|
||||
#define LOG_INCREMENT_BY(a, b) log_increment((a), (b))
|
||||
#define LOG_COUNTER(a, b) log_counter((a), (b))
|
||||
#define RESET_COUNTER(a) reset_counter((a))
|
||||
|
|
|
|||
|
|
@ -1,113 +0,0 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_MEMORY_ALLOCATION_H
|
||||
#define TOS_MEMORY_ALLOCATION_H
|
||||
|
||||
#include <malloc.h>
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.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* playform_alloc(size_t size)
|
||||
{
|
||||
return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
}
|
||||
|
||||
inline
|
||||
void* playform_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;
|
||||
}
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
inline
|
||||
void aligned_free(void** ptr) {
|
||||
free(*ptr);
|
||||
*ptr = NULL;
|
||||
}
|
||||
|
||||
inline
|
||||
void* playform_alloc(size_t size)
|
||||
{
|
||||
// Get the system page size
|
||||
size_t page_size = sysconf(_SC_PAGESIZE);
|
||||
|
||||
// Round up to the nearest page size
|
||||
size = (size + page_size - 1) & ~(page_size - 1);
|
||||
|
||||
return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
}
|
||||
|
||||
inline
|
||||
void* playform_alloc_aligned(size_t size, int32 alignment)
|
||||
{
|
||||
// Get the system page size
|
||||
size_t page_size = sysconf(_SC_PAGESIZE);
|
||||
if (alignment < page_size) {
|
||||
alignment = page_size;
|
||||
}
|
||||
|
||||
// Round up to the nearest alignment boundary
|
||||
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
|
||||
|
||||
#endif
|
||||
|
|
@ -14,16 +14,22 @@
|
|||
#include "../utils/MathUtils.h"
|
||||
#include "../utils/EndianUtils.h"
|
||||
#include "../utils/TestUtils.h"
|
||||
#include "Allocation.h"
|
||||
#include "../log/DebugMemory.h"
|
||||
|
||||
#if _WIN32
|
||||
#include "../platform/win32/Allocation.h"
|
||||
#elif __linux__
|
||||
#include "../platform/linux/Allocation.h"
|
||||
#endif
|
||||
|
||||
// @question Consider to use element_alignment to automatically align/pad elmeents
|
||||
|
||||
struct BufferMemory {
|
||||
byte* memory;
|
||||
byte* end;
|
||||
byte* head;
|
||||
|
||||
uint64 size;
|
||||
uint64 pos;
|
||||
int32 alignment;
|
||||
int32 element_alignment;
|
||||
};
|
||||
|
|
@ -34,12 +40,14 @@ void buffer_alloc(BufferMemory* buf, uint64 size, int32 alignment = 64)
|
|||
ASSERT_SIMPLE(size);
|
||||
|
||||
buf->memory = alignment < 2
|
||||
? (byte *) playform_alloc(size)
|
||||
: (byte *) playform_alloc_aligned(size, alignment);
|
||||
? (byte *) platform_alloc(size)
|
||||
: (byte *) platform_alloc_aligned(size, alignment);
|
||||
|
||||
buf->end = buf->memory + size;
|
||||
buf->head = buf->memory;
|
||||
buf->size = size;
|
||||
buf->alignment = alignment;
|
||||
buf->element_alignment = 0;
|
||||
buf->size = size;
|
||||
|
||||
memset(buf->memory, 0, buf->size);
|
||||
|
||||
|
|
@ -65,8 +73,9 @@ void buffer_init(BufferMemory* buf, byte* data, uint64 size, int32 alignment = 6
|
|||
// @bug what if an alignment is defined?
|
||||
buf->memory = data;
|
||||
|
||||
buf->end = buf->memory + size;
|
||||
buf->head = buf->memory;
|
||||
buf->size = size;
|
||||
buf->pos = 0;
|
||||
buf->alignment = alignment;
|
||||
buf->element_alignment = 0;
|
||||
|
||||
|
|
@ -78,8 +87,8 @@ inline
|
|||
void buffer_reset(BufferMemory* buf)
|
||||
{
|
||||
// @bug arent we wasting element 0 (see get_memory, we are not using 0 only next element)
|
||||
DEBUG_MEMORY_DELETE((uint64) buf->memory, buf->pos);
|
||||
buf->pos = 0;
|
||||
DEBUG_MEMORY_DELETE((uint64) buf->memory, buf->head - buf->memory);
|
||||
buf->head = buf->memory;
|
||||
}
|
||||
|
||||
inline
|
||||
|
|
@ -92,21 +101,23 @@ byte* buffer_get_memory(BufferMemory* buf, uint64 size, int32 aligned = 0, bool
|
|||
}
|
||||
|
||||
if (aligned > 1) {
|
||||
uintptr_t address = (uintptr_t) buf->memory;
|
||||
buf->pos += (aligned - ((address + buf->pos) & (aligned - 1))) % aligned;
|
||||
uintptr_t address = (uintptr_t) buf->head;
|
||||
buf->head += (aligned - (address & (aligned - 1))) % aligned;
|
||||
}
|
||||
|
||||
size = ROUND_TO_NEAREST(size, aligned);
|
||||
ASSERT_SIMPLE(buf->pos + size <= buf->size);
|
||||
ASSERT_SIMPLE(buf->head + size <= buf->end);
|
||||
|
||||
byte* offset = (byte *) (buf->memory + buf->pos);
|
||||
if (zeroed) {
|
||||
memset((void *) offset, 0, size);
|
||||
memset((void *) buf->head, 0, size);
|
||||
}
|
||||
|
||||
DEBUG_MEMORY_WRITE((uint64) offset, size);
|
||||
DEBUG_MEMORY_WRITE((uint64) buf->head, size);
|
||||
|
||||
buf->pos += size;
|
||||
byte* offset = buf->head;
|
||||
buf->head += size;
|
||||
|
||||
ASSERT_SIMPLE(offset);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
|
@ -120,9 +131,9 @@ int64 buffer_dump(const BufferMemory* buf, byte* data)
|
|||
*((uint64 *) data) = SWAP_ENDIAN_LITTLE(buf->size);
|
||||
data += sizeof(buf->size);
|
||||
|
||||
// Pos
|
||||
*((uint64 *) data) = SWAP_ENDIAN_LITTLE(buf->pos);
|
||||
data += sizeof(buf->pos);
|
||||
// head
|
||||
*((uint64 *) data) = SWAP_ENDIAN_LITTLE((uint64) (buf->head - buf->memory));
|
||||
data += sizeof(uint64);
|
||||
|
||||
// Alignment
|
||||
*((int32 *) data) = SWAP_ENDIAN_LITTLE(buf->alignment);
|
||||
|
|
@ -131,6 +142,10 @@ int64 buffer_dump(const BufferMemory* buf, byte* data)
|
|||
*((int32 *) data) = SWAP_ENDIAN_LITTLE(buf->element_alignment);
|
||||
data += sizeof(buf->element_alignment);
|
||||
|
||||
// End
|
||||
*((uint64 *) data) = SWAP_ENDIAN_LITTLE((uint64) (buf->end - buf->memory));
|
||||
data += sizeof(buf->end);
|
||||
|
||||
// All memory is handled in the buffer -> simply copy the buffer
|
||||
memcpy(data, buf->memory, buf->size);
|
||||
data += buf->size;
|
||||
|
|
@ -141,13 +156,15 @@ int64 buffer_dump(const BufferMemory* buf, byte* data)
|
|||
inline
|
||||
int64 buffer_load(BufferMemory* buf, const byte* data)
|
||||
{
|
||||
const byte* start = data;
|
||||
|
||||
// Size
|
||||
buf->size = SWAP_ENDIAN_LITTLE(*((uint64 *) data));
|
||||
data += sizeof(buf->size);
|
||||
|
||||
// Pos
|
||||
buf->pos = SWAP_ENDIAN_LITTLE(*((uint64 *) data));
|
||||
data += sizeof(buf->pos);
|
||||
// head
|
||||
buf->head = buf->memory + SWAP_ENDIAN_LITTLE(*((uint64 *) data));
|
||||
data += sizeof(uint64);
|
||||
|
||||
// Alignment
|
||||
buf->alignment = SWAP_ENDIAN_LITTLE(*((int32 *) data));
|
||||
|
|
@ -156,8 +173,14 @@ int64 buffer_load(BufferMemory* buf, const byte* data)
|
|||
buf->element_alignment = SWAP_ENDIAN_LITTLE(*((int32 *) data));
|
||||
data += sizeof(buf->element_alignment);
|
||||
|
||||
// End
|
||||
buf->end = buf->memory + SWAP_ENDIAN_LITTLE(*((uint64 *) data));
|
||||
data += sizeof(uint64);
|
||||
|
||||
memcpy(buf->memory, data, buf->size);
|
||||
data += buf->size;
|
||||
|
||||
return data - start;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -6,15 +6,22 @@
|
|||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_MEMORY_ELEMENT_MEMORY_H
|
||||
#define TOS_MEMORY_ELEMENT_MEMORY_H
|
||||
#ifndef TOS_MEMORY_CHUNK_MEMORY_H
|
||||
#define TOS_MEMORY_CHUNK_MEMORY_H
|
||||
|
||||
#include <string.h>
|
||||
#include "../stdlib/Types.h"
|
||||
#include "../utils/MathUtils.h"
|
||||
#include "../utils/TestUtils.h"
|
||||
#include "../utils/EndianUtils.h"
|
||||
#include "Allocation.h"
|
||||
#include "../log/DebugMemory.h"
|
||||
#include "BufferMemory.h"
|
||||
|
||||
#if _WIN32
|
||||
#include "../platform/win32/Allocation.h"
|
||||
#elif __linux__
|
||||
#include "../platform/linux/Allocation.h"
|
||||
#endif
|
||||
|
||||
struct ChunkMemory {
|
||||
byte* memory;
|
||||
|
|
@ -37,8 +44,8 @@ void chunk_alloc(ChunkMemory* buf, uint64 count, uint64 chunk_size, int32 alignm
|
|||
ASSERT_SIMPLE(count);
|
||||
|
||||
buf->memory = alignment < 2
|
||||
? (byte *) playform_alloc(count * chunk_size + sizeof(buf->free) * CEIL_DIV(count, 64))
|
||||
: (byte *) playform_alloc_aligned(count * chunk_size + sizeof(buf->free) * CEIL_DIV(count, 64), alignment);
|
||||
? (byte *) platform_alloc(count * chunk_size + sizeof(buf->free) * CEIL_DIV(count, 64))
|
||||
: (byte *) platform_alloc_aligned(count * chunk_size + sizeof(buf->free) * CEIL_DIV(count, 64), alignment);
|
||||
|
||||
buf->count = count;
|
||||
buf->size = count * chunk_size + sizeof(buf->free) * CEIL_DIV(count, 64);
|
||||
|
|
@ -124,6 +131,8 @@ byte* chunk_get_element(ChunkMemory* buf, uint64 element, bool zeroed = false)
|
|||
|
||||
DEBUG_MEMORY_READ((uint64) offset, buf->chunk_size);
|
||||
|
||||
ASSERT_SIMPLE(offset);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,34 +10,37 @@
|
|||
#define TOS_MEMORY_RING_MEMORY_H
|
||||
|
||||
#include <string.h>
|
||||
#include <immintrin.h>
|
||||
|
||||
#include "../stdlib/Types.h"
|
||||
#include "../utils/MathUtils.h"
|
||||
#include "../utils/EndianUtils.h"
|
||||
#include "../utils/TestUtils.h"
|
||||
|
||||
#include "Allocation.h"
|
||||
#include "BufferMemory.h"
|
||||
#include "../log/DebugMemory.h"
|
||||
|
||||
#if _WIN32
|
||||
#include "../platform/win32/Allocation.h"
|
||||
#elif __linux__
|
||||
#include "../platform/linux/Allocation.h"
|
||||
#endif
|
||||
|
||||
struct RingMemory {
|
||||
byte* memory;
|
||||
byte* end;
|
||||
|
||||
byte* head;
|
||||
|
||||
// This variable is usually only used by single read/write 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
|
||||
byte* tail;
|
||||
|
||||
uint64 size;
|
||||
uint64 pos;
|
||||
int32 alignment;
|
||||
int32 element_alignment;
|
||||
|
||||
// The following two indices are only used in special cases such as iterating through a portion
|
||||
// of the ring memory. In such cases it may be necessary to know where the start and end are.
|
||||
// Examples for such cases are if a worker thread is pulling data from this ring memory in chunks.
|
||||
|
||||
// @question Is it guaranteed that if a thread realizes end changed, that also the memory is changed
|
||||
// or is it possible that end changed but it still has old *memory in the cache?
|
||||
// if yes we need to also check and wait for *memory != NULL and obviously set the memory to NULL
|
||||
// after using it.
|
||||
uint64 start;
|
||||
uint64 end;
|
||||
};
|
||||
|
||||
inline
|
||||
|
|
@ -46,15 +49,15 @@ void ring_alloc(RingMemory* ring, uint64 size, int32 alignment = 64)
|
|||
ASSERT_SIMPLE(size);
|
||||
|
||||
ring->memory = alignment < 2
|
||||
? (byte *) playform_alloc(size)
|
||||
: (byte *) playform_alloc_aligned(size, alignment);
|
||||
? (byte *) platform_alloc(size)
|
||||
: (byte *) platform_alloc_aligned(size, alignment);
|
||||
|
||||
ring->end = ring->memory + size;;
|
||||
ring->head = ring->memory;
|
||||
ring->tail = ring->memory;
|
||||
ring->size = size;
|
||||
ring->pos = 0;
|
||||
ring->alignment = alignment;
|
||||
ring->element_alignment = 0;
|
||||
ring->start = 0;
|
||||
ring->end = 0;
|
||||
|
||||
memset(ring->memory, 0, ring->size);
|
||||
|
||||
|
|
@ -68,12 +71,12 @@ void ring_init(RingMemory* ring, BufferMemory* buf, uint64 size, int32 alignment
|
|||
|
||||
ring->memory = buffer_get_memory(buf, size, alignment, true);
|
||||
|
||||
ring->end = ring->memory + size;;
|
||||
ring->head = ring->memory;
|
||||
ring->tail = ring->memory;
|
||||
ring->size = size;
|
||||
ring->pos = 0;
|
||||
ring->alignment = alignment;
|
||||
ring->element_alignment = 0;
|
||||
ring->start = 0;
|
||||
ring->end = 0;
|
||||
|
||||
DEBUG_MEMORY_INIT((uint64) ring->memory, ring->size);
|
||||
DEBUG_MEMORY_RESERVE((uint64) ring->memory, ring->size, 187);
|
||||
|
|
@ -87,12 +90,12 @@ void ring_init(RingMemory* ring, byte* buf, uint64 size, int32 alignment = 64)
|
|||
// @bug what if an alignment is defined?
|
||||
ring->memory = buf;
|
||||
|
||||
ring->end = ring->memory + size;;
|
||||
ring->head = ring->memory;
|
||||
ring->tail = ring->memory;
|
||||
ring->size = size;
|
||||
ring->pos = 0;
|
||||
ring->alignment = alignment;
|
||||
ring->element_alignment = 0;
|
||||
ring->start = 0;
|
||||
ring->end = 0;
|
||||
|
||||
memset(ring->memory, 0, ring->size);
|
||||
|
||||
|
|
@ -111,35 +114,37 @@ void ring_free(RingMemory* buf)
|
|||
}
|
||||
|
||||
inline
|
||||
uint64 ring_calculate_position(const RingMemory* ring, uint64 pos, uint64 size, byte aligned = 0)
|
||||
byte* ring_calculate_position(const RingMemory* ring, uint64 size, byte aligned = 0)
|
||||
{
|
||||
if (aligned == 0) {
|
||||
aligned = (byte) OMS_MAX(ring->element_alignment, 1);
|
||||
}
|
||||
|
||||
if (aligned) {
|
||||
uintptr_t address = (uintptr_t) ring->memory;
|
||||
pos += (aligned - ((address + ring->pos) & (aligned - 1))) % aligned;
|
||||
byte* head = ring->head;
|
||||
|
||||
if (aligned > 1) {
|
||||
uintptr_t address = (uintptr_t) head;
|
||||
head += (aligned - (address & (aligned - 1))) % aligned;
|
||||
}
|
||||
|
||||
size = ROUND_TO_NEAREST(size, aligned);
|
||||
if (pos + size > ring->size) {
|
||||
pos = 0;
|
||||
if (head + size > ring->end) {
|
||||
head = ring->memory;
|
||||
|
||||
if (aligned > 1) {
|
||||
uintptr_t address = (uintptr_t) ring->memory;
|
||||
pos += (aligned - ((address + ring->pos) & (aligned - 1))) % aligned;
|
||||
uintptr_t address = (uintptr_t) head;
|
||||
head += (aligned - (address & (aligned - 1))) % aligned;
|
||||
}
|
||||
}
|
||||
|
||||
return pos;
|
||||
return head;
|
||||
}
|
||||
|
||||
inline
|
||||
void ring_reset(RingMemory* ring)
|
||||
{
|
||||
DEBUG_MEMORY_DELETE((uint64) ring->memory, ring->size);
|
||||
ring->pos = 0;
|
||||
ring->head = ring->memory;
|
||||
}
|
||||
|
||||
byte* ring_get_memory(RingMemory* ring, uint64 size, byte aligned = 0, bool zeroed = false)
|
||||
|
|
@ -151,28 +156,30 @@ byte* ring_get_memory(RingMemory* ring, uint64 size, byte aligned = 0, bool zero
|
|||
}
|
||||
|
||||
if (aligned > 1) {
|
||||
uintptr_t address = (uintptr_t) ring->memory;
|
||||
ring->pos += (aligned - ((address + ring->pos) & (aligned - 1))) % aligned;
|
||||
uintptr_t address = (uintptr_t) ring->head;
|
||||
ring->head += (aligned - (address& (aligned - 1))) % aligned;
|
||||
}
|
||||
|
||||
size = ROUND_TO_NEAREST(size, aligned);
|
||||
if (ring->pos + size > ring->size) {
|
||||
if (ring->head + size > ring->end) {
|
||||
ring_reset(ring);
|
||||
|
||||
if (aligned > 1) {
|
||||
uintptr_t address = (uintptr_t) ring->memory;
|
||||
ring->pos += (aligned - ((address + ring->pos) & (aligned - 1))) % aligned;
|
||||
uintptr_t address = (uintptr_t) ring->head;
|
||||
ring->head += (aligned - (address & (aligned - 1))) % aligned;
|
||||
}
|
||||
}
|
||||
|
||||
byte* offset = (byte *) (ring->memory + ring->pos);
|
||||
if (zeroed) {
|
||||
memset((void *) offset, 0, size);
|
||||
memset((void *) ring->head, 0, size);
|
||||
}
|
||||
|
||||
DEBUG_MEMORY_WRITE((uint64) offset, size);
|
||||
DEBUG_MEMORY_WRITE((uint64) ring->head, size);
|
||||
|
||||
ring->pos += size;
|
||||
byte* offset = ring->head;
|
||||
ring->head += size;
|
||||
|
||||
ASSERT_SIMPLE(offset);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
|
@ -190,34 +197,49 @@ byte* ring_get_element(const RingMemory* ring, uint64 element_count, uint64 elem
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks if one additional element can be inserted without overwriting the start index
|
||||
* Checks if one additional element can be inserted without overwriting the tail index
|
||||
*/
|
||||
inline
|
||||
bool ring_commit_safe(const RingMemory* ring, uint64 size, byte aligned = 0)
|
||||
{
|
||||
uint64 pos = ring_calculate_position(ring, ring->pos, size, aligned);
|
||||
// aligned * 2 since that should be the maximum overhead for an element
|
||||
uint64 max_mem_required = size + aligned * 2;
|
||||
|
||||
if (ring->start == ring->end && ring->pos == 0) {
|
||||
if (ring->tail < ring->head) {
|
||||
return ((uint64) (ring->end - ring->head)) > max_mem_required
|
||||
|| ((uint64) (ring->tail - ring->memory)) > max_mem_required;
|
||||
} else if (ring->tail > ring->head) {
|
||||
return ((uint64) (ring->tail - ring->head)) > max_mem_required;
|
||||
} else {
|
||||
// @question Is this really the case? What if it is completely filled?
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return ring->start < ring->pos
|
||||
? ring->start < pos
|
||||
: pos < ring->start;
|
||||
inline
|
||||
void ring_force_head_update(const RingMemory* ring)
|
||||
{
|
||||
_mm_clflush(ring->head);
|
||||
}
|
||||
|
||||
inline
|
||||
void ring_force_tail_update(const RingMemory* ring)
|
||||
{
|
||||
_mm_clflush(ring->tail);
|
||||
}
|
||||
|
||||
inline
|
||||
int64 ring_dump(const RingMemory* ring, byte* data)
|
||||
{
|
||||
byte* start = data;
|
||||
byte* tail = data;
|
||||
|
||||
// Size
|
||||
*((uint64 *) data) = SWAP_ENDIAN_LITTLE(ring->size);
|
||||
data += sizeof(ring->size);
|
||||
|
||||
// Pos
|
||||
*((uint64 *) data) = SWAP_ENDIAN_LITTLE(ring->pos);
|
||||
data += sizeof(ring->pos);
|
||||
// head
|
||||
*((uint64 *) data) = SWAP_ENDIAN_LITTLE((uint64) (ring->head - ring->memory));
|
||||
data += sizeof(ring->head);
|
||||
|
||||
// Alignment
|
||||
*((int32 *) data) = SWAP_ENDIAN_LITTLE(ring->alignment);
|
||||
|
|
@ -226,18 +248,18 @@ int64 ring_dump(const RingMemory* ring, byte* data)
|
|||
*((int32 *) data) = SWAP_ENDIAN_LITTLE(ring->element_alignment);
|
||||
data += sizeof(ring->element_alignment);
|
||||
|
||||
// Start/End
|
||||
*((uint64 *) data) = SWAP_ENDIAN_LITTLE(ring->start);
|
||||
data += sizeof(ring->start);
|
||||
// tail/End
|
||||
*((uint64 *) data) = SWAP_ENDIAN_LITTLE((uint64) (ring->tail - ring->memory));
|
||||
data += sizeof(ring->tail);
|
||||
|
||||
*((uint64 *) data) = SWAP_ENDIAN_LITTLE(ring->end);
|
||||
*((uint64 *) data) = SWAP_ENDIAN_LITTLE((uint64) (ring->end - ring->memory));
|
||||
data += sizeof(ring->end);
|
||||
|
||||
// All memory is handled in the buffer -> simply copy the buffer
|
||||
memcpy(data, ring->memory, ring->size);
|
||||
data += ring->size;
|
||||
|
||||
return data - start;
|
||||
return data - tail;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -10,715 +10,28 @@
|
|||
#define TOS_MODELS_SETTINGS_H
|
||||
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../gpuapi/AntiAliasing.h"
|
||||
#include "../chat/ChatStatus.h"
|
||||
#include "setting_types.h"
|
||||
#include "../../module/Module.h"
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#include "../../platform/win32/input/controller/ControllerHandler.h"
|
||||
#else __linux__
|
||||
#include <linux/limits.h>
|
||||
#define MAX_PATH PATH_MAX
|
||||
#include <Ws2ipdef.h>
|
||||
#elif __linux__
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifndef RENDER_CHUNK_RADIUS
|
||||
#define RENDER_CHUNK_RADIUS 10
|
||||
#endif
|
||||
|
||||
#ifndef RENDER_BLOCK_OBJECT_CHUNK_RADIUS
|
||||
#define RENDER_BLOCK_OBJECT_CHUNK_RADIUS 10
|
||||
#endif
|
||||
|
||||
#ifndef RENDER_INTERACTIVE_CHUNK_RADIUS
|
||||
#define RENDER_INTERACTIVE_CHUNK_RADIUS 1
|
||||
#endif
|
||||
|
||||
#ifndef RENDER_OBJECT_CHUNK_RADIUS
|
||||
#define RENDER_OBJECT_CHUNK_RADIUS 1
|
||||
#endif
|
||||
|
||||
#ifndef RENDER_MONSTER_CHUNK_RADIUS
|
||||
#define RENDER_MONSTER_CHUNK_RADIUS 3
|
||||
#endif
|
||||
|
||||
#ifndef RENDER_NPC_CHUNK_RADIUS
|
||||
#define RENDER_NPC_CHUNK_RADIUS 3
|
||||
#endif
|
||||
|
||||
#ifndef RENDER_PAYER_CHUNK_RADIUS
|
||||
#define RENDER_PAYER_CHUNK_RADIUS 3
|
||||
#endif
|
||||
|
||||
#define MAX_ACTIVE_EXTENSIONS 15
|
||||
|
||||
// @todo remove default values because we will load them during startup
|
||||
struct SSettings {
|
||||
char path[MAX_PATH];
|
||||
bool is_changed = false;
|
||||
byte simd_version;
|
||||
|
||||
char network_hostname[64];
|
||||
uint16 network_port;
|
||||
|
||||
byte distance_terrain = RENDER_CHUNK_RADIUS;
|
||||
byte distance_terrain_secondary = RENDER_BLOCK_OBJECT_CHUNK_RADIUS;
|
||||
byte distance_terrain_tertiary = RENDER_INTERACTIVE_CHUNK_RADIUS;
|
||||
byte distance_models = RENDER_OBJECT_CHUNK_RADIUS;
|
||||
byte distance_monster = RENDER_MONSTER_CHUNK_RADIUS;
|
||||
byte distance_npc = RENDER_NPC_CHUNK_RADIUS;
|
||||
byte distance_player = RENDER_PAYER_CHUNK_RADIUS;
|
||||
|
||||
uint32 cache_player = 8192; // = max active players on a server
|
||||
uint32 cache_monster = 8192;
|
||||
uint32 cache_npc = 8192;
|
||||
uint32 cache_guild = 128;
|
||||
uint32 cache_message = 1024;
|
||||
|
||||
uint32 interpolation_buffer;
|
||||
|
||||
bool is_auction_house_enabled = true;
|
||||
bool is_direct_trading_enabled = true;
|
||||
|
||||
// @todo add more server settings for tournaments, tournament modes
|
||||
// @todo add more server settings for raids and dungeons
|
||||
// @todo add more settings for pvp
|
||||
};
|
||||
|
||||
// Player settings that the server needs to know about
|
||||
struct PSettings {
|
||||
byte render_distance_models = RENDER_OBJECT_CHUNK_RADIUS;
|
||||
byte render_distance_monster = RENDER_MONSTER_CHUNK_RADIUS;
|
||||
byte render_distance_npc = RENDER_NPC_CHUNK_RADIUS;
|
||||
byte render_distance_player = RENDER_PAYER_CHUNK_RADIUS;
|
||||
|
||||
byte chat_status = CHAT_STATUS_OFFLINE;
|
||||
bool allow_invites = true;
|
||||
};
|
||||
|
||||
// @performance Make sure the settings used in the update and render loop are close to each other to ensure they can be loaded in one cache line
|
||||
struct CSettings {
|
||||
// Evaluated during startup
|
||||
char path[MAX_PATH];
|
||||
bool is_changed = false;
|
||||
struct SIMDSettings {
|
||||
byte simd_version;
|
||||
int32 simd_step_size;
|
||||
bool supports_abm;
|
||||
|
||||
// Network data
|
||||
char network_hostname[64];
|
||||
uint16 network_port;
|
||||
|
||||
byte gpu_api = SETTING_TYPE_GPU_API_NONE;
|
||||
byte gpu_type = SETTING_TYPE_GPU_MEDIUM;
|
||||
byte gpu_fps = SETTING_TYPE_UNLIMITED;
|
||||
byte gpu_memory; // how much vram are we using on the gpu
|
||||
byte system_ram; // how much ram are we using
|
||||
byte system_threads; // how much ram are we using
|
||||
byte system_cache; // how much hard drive cache do we want to allow? (oldest files will be deleted)
|
||||
|
||||
f32 gpu_aspect_ratio;
|
||||
byte gpu_brightness;
|
||||
byte gpu_contrast;
|
||||
byte gpu_gamma;
|
||||
f32 gpu_fov;
|
||||
int8 gpu_sync;
|
||||
|
||||
byte gpu_render_distance_terrain = 10;
|
||||
byte gpu_render_distance_terrain_secondary = 10;
|
||||
byte gpu_render_distance_terrain_tertiary = 1;
|
||||
byte gpu_render_distance_models = 1;
|
||||
byte gpu_render_distance_monster = 3;
|
||||
byte gpu_render_distance_npc = 3;
|
||||
byte gpu_render_distance_player = 3;
|
||||
|
||||
int32 gpu_render_count_mob = 1000;
|
||||
|
||||
uint32 player_cache = 512;
|
||||
uint32 monster_cache = 128;
|
||||
uint32 npc_cache = 128;
|
||||
uint32 guild_cache = 128;
|
||||
uint32 message_cache = 64;
|
||||
|
||||
byte gpu_animation_quality;
|
||||
byte gpu_attack_effect_quality;
|
||||
byte gpu_shadow_quality;
|
||||
byte gpu_terrain_quality;
|
||||
byte gpu_water_quality;
|
||||
byte gpu_grass_density;
|
||||
byte gpu_model_quality;
|
||||
byte gpu_texture_quality;
|
||||
byte gpu_foliage_distance;
|
||||
byte gpu_detail_level;
|
||||
byte gpu_reflection_quality;
|
||||
byte gpu_refraction_quality;
|
||||
byte gpu_caustics_quality;
|
||||
byte gpu_footprint_quality; // mostly used for snow, sand mud
|
||||
bool gpu_screen_effects; // e.g. water droplets/dust/freezing on screen
|
||||
|
||||
bool gpu_raytracing = false;
|
||||
bool gpu_lense_effect = true;
|
||||
bool gpu_fog_effect = true;
|
||||
bool gpu_particles_environment = true;
|
||||
bool gpu_particles_players = true;
|
||||
bool gpu_particles_monster = true;
|
||||
bool gpu_particles_ui = true;
|
||||
bool gpu_particles_skills = true;
|
||||
bool gpu_particles_weapons = true;
|
||||
|
||||
byte gpu_shadow_type = SETTING_TYPE_DISABLED; // none, baked, shadow mapping, point shadow, ray tracing
|
||||
byte gpu_light_ssao = SETTING_TYPE_DISABLED;
|
||||
byte gpu_light_bloom = SETTING_TYPE_DISABLED;
|
||||
|
||||
byte gpu_reflection_blur = SETTING_TYPE_DISABLED;
|
||||
byte gpu_motion_blur = SETTING_TYPE_DISABLED;
|
||||
byte gpu_blur = SETTING_TYPE_DISABLED;
|
||||
AntiAliasingType gpu_anti_aliasing;
|
||||
int8 gpu_anti_aliasing_detail = 0;
|
||||
byte gpu_sharpening = SETTING_TYPE_DISABLED;
|
||||
byte gpu_ambient_occlusion = SETTING_TYPE_DISABLED;
|
||||
byte gpu_color_deficiency;
|
||||
|
||||
bool gpu_gamma_correction = true;
|
||||
bool gpu_normal_mapping = true;
|
||||
bool gpu_parallax_mapping = true;
|
||||
|
||||
bool gpu_depth_of_field = true;
|
||||
bool gpu_chromatic_aberration = true;
|
||||
bool gpu_vignetting = true;
|
||||
bool gpu_light_shafts = true;
|
||||
|
||||
f32 audio_volume_master;
|
||||
f32 audio_volume_game;
|
||||
f32 audio_volume_environment;
|
||||
f32 audio_volume_music;
|
||||
f32 audio_volume_speech;
|
||||
|
||||
uint16 game_window1_dim[2];
|
||||
uint16 game_window1_pos[2];
|
||||
byte game_window1_mode = SETTING_TYPE_WINDOW_MODE_FULLSCREEN;
|
||||
|
||||
byte game_view = SETTING_TYPE_PERSPECTIVE_FIRST;
|
||||
byte game_camera_zoom;
|
||||
bool game_camera_shake = false;
|
||||
|
||||
// General game UI
|
||||
byte game_crosshair;
|
||||
|
||||
uint32 game_interpolation_buffer;
|
||||
|
||||
bool game_player_chat = false; // bubble above player
|
||||
byte game_chat_status = CHAT_STATUS_OFFLINE;
|
||||
|
||||
// Extra windows
|
||||
byte game_window2_type = SETTING_TYPE_DISABLED;
|
||||
bool game_window2_visible = false;
|
||||
uint32 game_window2_dim[2] = {1024, 768};
|
||||
uint32 game_window2_pos[2];
|
||||
|
||||
byte game_window3_type = SETTING_TYPE_DISABLED;
|
||||
bool game_window3_visible = false;
|
||||
uint32 game_window3_dim[2] = {1024, 768};
|
||||
uint32 game_window3_pos[2];
|
||||
|
||||
byte game_window4_type = SETTING_TYPE_DISABLED;
|
||||
bool game_window4_visible = false;
|
||||
uint32 game_window4_dim[2] = {1024, 768};
|
||||
uint32 game_window4_pos[2];
|
||||
|
||||
byte game_window5_type = SETTING_TYPE_DISABLED;
|
||||
bool game_window5_visible = false;
|
||||
uint32 game_window5_dim[2] = {1024, 768};
|
||||
uint32 game_window5_pos[2];
|
||||
|
||||
// @todo Consider to allow settings for chat tabs
|
||||
// define which messags go to which tab
|
||||
// define custom chat tabs
|
||||
|
||||
// UI settings
|
||||
// Themes
|
||||
char game_language[2];
|
||||
|
||||
char game_theme[32];
|
||||
|
||||
v4_f32 game_ui_dim[50];
|
||||
|
||||
// @todo replace settings below with bit flag
|
||||
// UI
|
||||
uint64 ui_visibility_flags = 0;
|
||||
uint64 game_visibility_flags = 0;
|
||||
uint64 debug_visibility_flags = 0;
|
||||
|
||||
// HUD
|
||||
bool game_hud_animated;
|
||||
|
||||
bool game_show_buffs = false;
|
||||
|
||||
byte game_minion_visibility_self = 128;
|
||||
byte game_minion_visibility_player = 128;
|
||||
|
||||
bool game_minimap_show_merchants = false;
|
||||
bool game_minimap_show_quest = false;
|
||||
bool game_minimap_show_dungeons = false;
|
||||
bool game_minimap_show_names = false;
|
||||
|
||||
bool game_map_show_merchants = false;
|
||||
bool game_map_show_quest = false;
|
||||
bool game_map_show_dungeons = false;
|
||||
bool game_map_show_names = false;
|
||||
|
||||
// Mounts
|
||||
uint32 game_default_mount = 0;
|
||||
|
||||
// Game behavior
|
||||
bool game_error_audio = true;
|
||||
bool game_error_text = true;
|
||||
bool game_block_trade = false;
|
||||
bool game_block_group_invite = false;
|
||||
bool game_block_guild_invite = false;
|
||||
bool game_block_chat_invite = false;
|
||||
bool game_block_friend_invite = false;
|
||||
bool game_automatically_track_newest_quest = false;
|
||||
|
||||
byte game_interact_radius = 1;
|
||||
|
||||
// Game pad settings
|
||||
byte input_device_types = SETTING_INPUT_DEVICE_TYPE_MOUSE_KEYBOARD;
|
||||
byte input_controller_handler = CONTROLLER_HANDLER_TYPE_AUTO;
|
||||
byte stick_left_deadzone = 0;
|
||||
byte stick_right_deadzone = 0;
|
||||
|
||||
f32 input_camera_speed;
|
||||
f32 input_look_sensitivity;
|
||||
bool input_invert_mouse = false;
|
||||
|
||||
int32 active_module_count;
|
||||
Module* active_modules;
|
||||
|
||||
// Hotkey settings
|
||||
// @todo hotkey combination e.g. alt+1
|
||||
byte hotkeys_movement_up = 0x57; // W
|
||||
byte hotkeys_movement_down = 0x53; // S
|
||||
byte hotkeys_movement_left = 0x41; // A
|
||||
byte hotkeys_movement_right = 0x44; // D
|
||||
|
||||
byte hotkeys_cancel_action = 0x44; // X
|
||||
|
||||
byte hotkeys_skill_tab_1 = 0x70; // F1
|
||||
byte hotkeys_skill_tab_2 = 0x71; // F2
|
||||
byte hotkeys_skill_tab_3 = 0x72; // F3
|
||||
|
||||
byte hotkeys_skill_1 = 0x31; // 1
|
||||
byte hotkeys_skill_2 = 0x32; // 2
|
||||
byte hotkeys_skill_3 = 0x33; // 3
|
||||
byte hotkeys_skill_4 = 0x34; // 4
|
||||
byte hotkeys_skill_5 = 0x35; // 5
|
||||
byte hotkeys_skill_6 = 0x36; // 6
|
||||
byte hotkeys_skill_7 = 0x37; // 7
|
||||
byte hotkeys_skill_8 = 0x38; // 8
|
||||
byte hotkeys_skill_9 = 0x39; // 9
|
||||
byte hotkeys_skill_10 = 0x30; // 0
|
||||
|
||||
byte hotkeys_interact = 45; // E
|
||||
byte hotkeys_jump = 0x20; // SPACE
|
||||
|
||||
byte hotkeys_dodge = 0x20; // SPACE
|
||||
byte hotkeys_crouch = 0x14; // CAP
|
||||
byte hotkeys_walk = 0x11; // CTRL (switches to walking speed, one click only)
|
||||
byte hotkeys_emote = 0x12; // LEFT_ALT
|
||||
byte hotkeys_vertical_up = 0x14; // CAPS LOCK
|
||||
byte hotkeys_vertical_down = 0x10; // SHIFT
|
||||
|
||||
byte hotkeys_view_next = 0x09; // TAB
|
||||
byte hotkeys_view_prv = 0x14; // CAPS LOCK
|
||||
byte hotkeys_compare_item = 0x11; // CTRL
|
||||
|
||||
byte hotkeys_inventory = 0x49; // I
|
||||
byte hotkeys_character = 0x43; // C
|
||||
byte hotkeys_skills = 0x53; // S
|
||||
byte hotkeys_map = 0x4D; // M
|
||||
byte hotkeys_quest = 0x51; // Q
|
||||
byte hotkeys_attack_move = 0x52; // R
|
||||
byte hotkeys_force_move = 0x46; // F
|
||||
byte hotkeys_courser_move = 0x58; // X (move to where courser is)
|
||||
|
||||
byte hotkeys_chat = 0x0D; // ENTER
|
||||
byte hotkeys_toggle_hud = 0x48; // H
|
||||
byte hotkeys_close_active_window = 0x48; // H
|
||||
byte hotkeys_toggle_all_windows = 0x48; // H
|
||||
|
||||
byte hotkeys_zoom_in = 0x21; // Page up (@todo make mouse scroll up)
|
||||
byte hotkeys_zoom_out = 0x22; // page down (@todo make mouse scroll down)
|
||||
byte hotkeys_camera_look = 0x00; // @todo make right mouse hold
|
||||
byte hotkeys_camera_fly_mode = 0x00; // @todo make right mouse hold
|
||||
|
||||
byte hotkeys_menu = 0x1B; // ESC
|
||||
|
||||
byte hotkeys_marker_1 = 0x31;
|
||||
byte hotkeys_marker_2 = 0x32;
|
||||
byte hotkeys_marker_3 = 0x33;
|
||||
byte hotkeys_marker_4 = 0x34;
|
||||
byte hotkeys_marker_5 = 0x35;
|
||||
byte hotkeys_marker_6 = 0x36;
|
||||
byte hotkeys_ping = 0x37;
|
||||
|
||||
// Camera settings/positions
|
||||
// Makes it easy to switch to customizable camera positions
|
||||
byte hotkeys_camera_1 = 0x0;
|
||||
byte hotkeys_camera_2 = 0x0;
|
||||
byte hotkeys_camera_3 = 0x0;
|
||||
|
||||
char modules[MAX_ACTIVE_EXTENSIONS * 32];
|
||||
};
|
||||
|
||||
void load_settings(CSettings* __restrict client_settings, char* data)
|
||||
{
|
||||
char* pos = data;
|
||||
char* name;
|
||||
struct NetworkSettings {
|
||||
in6_addr network_hostname;
|
||||
uint16 network_port;
|
||||
};
|
||||
|
||||
while (*pos != '\0') {
|
||||
// Skip all whitespaces and new lines
|
||||
int32 skip;
|
||||
while ((skip = (int32) is_whitespace(*pos)) || (skip = is_eol(pos))) {
|
||||
pos += skip;
|
||||
}
|
||||
struct ServerInfoSettings {
|
||||
char server_name[24];
|
||||
in6_addr server_hostname;
|
||||
uint16 server_port;
|
||||
};
|
||||
|
||||
// Skip comment
|
||||
if (*pos == '/' && pos[1] == '/') {
|
||||
while (*pos != '\n' && *pos != '\0') {
|
||||
++pos;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get name
|
||||
name = pos;
|
||||
while (!is_eol(pos) && *pos != '\0' && !is_whitespace(*pos) && *pos != '[') {
|
||||
++pos;
|
||||
}
|
||||
|
||||
// Move to value
|
||||
while (is_whitespace(*pos)) {
|
||||
++pos;
|
||||
}
|
||||
|
||||
// Is there a value?
|
||||
if (is_eol(pos) || *pos == '\0') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Parse value
|
||||
// We use grouping for faster handling
|
||||
if (strncmp(name, "gpu", sizeof("gpu") - 1) == 0) {
|
||||
name += sizeof("gpu") - 1;
|
||||
|
||||
if (strncmp(name, "_ambient_occlusion", sizeof("_ambient_occlusion") - 1) == 0) {
|
||||
} else if (strncmp(name, "_animation_quality", sizeof("_animation_quality") - 1) == 0) {
|
||||
} else if (strncmp(name, "_anti_aliasing_detail", sizeof("_anti_aliasing_detail") - 1) == 0) {
|
||||
client_settings->gpu_anti_aliasing_detail = (int8) atoi(pos);
|
||||
} else if (strncmp(name, "_anti_aliasing", sizeof("_anti_aliasing") - 1) == 0) {
|
||||
client_settings->gpu_anti_aliasing = (AntiAliasingType) atoi(pos);
|
||||
} else if (strncmp(name, "_api", sizeof("_api") - 1) == 0) {
|
||||
} else if (strncmp(name, "_aspect_ratio", sizeof("_aspect_ratio") - 1) == 0) {
|
||||
client_settings->gpu_aspect_ratio = (f32) atof(pos);
|
||||
} else if (strncmp(name, "_attack_effect_quality", sizeof("_attack_effect_quality") - 1) == 0) {
|
||||
} else if (strncmp(name, "_blur", sizeof("_blur") - 1) == 0) {
|
||||
} else if (strncmp(name, "_color_deficiency", sizeof("_color_deficiency") - 1) == 0) {
|
||||
client_settings->gpu_color_deficiency = (byte) atoi(pos);
|
||||
} else if (strncmp(name, "_brightness", sizeof("_brightness") - 1) == 0) {
|
||||
} else if (strncmp(name, "_camera_shake", sizeof("_camera_shake") - 1) == 0) {
|
||||
} else if (strncmp(name, "_caustics_quality", sizeof("_caustics_quality") - 1) == 0) {
|
||||
} else if (strncmp(name, "_chromatic_aberration", sizeof("_chromatic_aberration") - 1) == 0) {
|
||||
} else if (strncmp(name, "_contrast", sizeof("_contrast") - 1) == 0) {
|
||||
} else if (strncmp(name, "_depth_of_field", sizeof("_depth_of_field") - 1) == 0) {
|
||||
} else if (strncmp(name, "_detail_level", sizeof("_detail_level") - 1) == 0) {
|
||||
} else if (strncmp(name, "_fog_effect", sizeof("_fog_effect") - 1) == 0) {
|
||||
} else if (strncmp(name, "_foliage_distance", sizeof("_foliage_distance") - 1) == 0) {
|
||||
} else if (strncmp(name, "_footprint_quality", sizeof("_footprint_quality") - 1) == 0) {
|
||||
} else if (strncmp(name, "_fov", sizeof("_fov") - 1) == 0) {
|
||||
client_settings->gpu_fov = (f32) atof(pos);
|
||||
} else if (strncmp(name, "_fps", sizeof("_fps") - 1) == 0) {
|
||||
} else if (strncmp(name, "_gamma_correction", sizeof("_gamma_correction") - 1) == 0) {
|
||||
} else if (strncmp(name, "_gamma", sizeof("_gamma") - 1) == 0) {
|
||||
} else if (strncmp(name, "_grass_density", sizeof("_grass_density") - 1) == 0) {
|
||||
} else if (strncmp(name, "_lense_effect", sizeof("_lense_effect") - 1) == 0) {
|
||||
} else if (strncmp(name, "_light_bloom", sizeof("_light_bloom") - 1) == 0) {
|
||||
} else if (strncmp(name, "_light_shafts", sizeof("_light_shafts") - 1) == 0) {
|
||||
} else if (strncmp(name, "_light_ssao", sizeof("_light_ssao") - 1) == 0) {
|
||||
} else if (strncmp(name, "_memory", sizeof("_memory") - 1) == 0) {
|
||||
} else if (strncmp(name, "_model_quality", sizeof("_model_quality") - 1) == 0) {
|
||||
} else if (strncmp(name, "_motion_blur", sizeof("_motion_blur") - 1) == 0) {
|
||||
} else if (strncmp(name, "_normal_mapping", sizeof("_normal_mapping") - 1) == 0) {
|
||||
} else if (strncmp(name, "_parallax_mapping", sizeof("_parallax_mapping") - 1) == 0) {
|
||||
} else if (strncmp(name, "_particles_environment", sizeof("_particles_environment") - 1) == 0) {
|
||||
} else if (strncmp(name, "_particles_monster", sizeof("_particles_monster") - 1) == 0) {
|
||||
} else if (strncmp(name, "_particles_players", sizeof("_particles_players") - 1) == 0) {
|
||||
} else if (strncmp(name, "_particles_skills", sizeof("_particles_skills") - 1) == 0) {
|
||||
} else if (strncmp(name, "_particles_ui", sizeof("_particles_ui") - 1) == 0) {
|
||||
} else if (strncmp(name, "_particles_weapons", sizeof("_particles_weapons") - 1) == 0) {
|
||||
} else if (strncmp(name, "_raytracing", sizeof("_raytracing") - 1) == 0) {
|
||||
} else if (strncmp(name, "_reflection_blur", sizeof("_reflection_blur") - 1) == 0) {
|
||||
} else if (strncmp(name, "_reflection_quality", sizeof("_reflection_quality") - 1) == 0) {
|
||||
} else if (strncmp(name, "_refraction_quality", sizeof("_refraction_quality") - 1) == 0) {
|
||||
} else if (strncmp(name, "_render_count_mob", sizeof("_render_count_mob") - 1) == 0) {
|
||||
} else if (strncmp(name, "_render_distance_models", sizeof("_render_distance_models") - 1) == 0) {
|
||||
} else if (strncmp(name, "_render_distance_monster", sizeof("_render_distance_monster") - 1) == 0) {
|
||||
} else if (strncmp(name, "_render_distance_npc", sizeof("_render_distance_npc") - 1) == 0) {
|
||||
} else if (strncmp(name, "_render_distance_player", sizeof("_render_distance_player") - 1) == 0) {
|
||||
} else if (strncmp(name, "_render_distance_terrain_secondary", sizeof("_render_distance_terrain_secondary") - 1) == 0) {
|
||||
} else if (strncmp(name, "_render_distance_terrain_tertiary", sizeof("_render_distance_terrain_tertiary") - 1) == 0) {
|
||||
} else if (strncmp(name, "_render_distance_terrain", sizeof("_render_distance_terrain") - 1) == 0) {
|
||||
} else if (strncmp(name, "_screen_effects", sizeof("_screen_effects") - 1) == 0) {
|
||||
} else if (strncmp(name, "_shadow_quality", sizeof("_shadow_quality") - 1) == 0) {
|
||||
} else if (strncmp(name, "_shadow_type", sizeof("_shadow_type") - 1) == 0) {
|
||||
} else if (strncmp(name, "_sharpening", sizeof("_sharpening") - 1) == 0) {
|
||||
} else if (strncmp(name, "_sync", sizeof("_sync") - 1) == 0) {
|
||||
client_settings->gpu_sync = (int8) atoi(pos);
|
||||
} else if (strncmp(name, "_terrain_quality", sizeof("_terrain_quality") - 1) == 0) {
|
||||
} else if (strncmp(name, "_texture_quality", sizeof("_texture_quality") - 1) == 0) {
|
||||
} else if (strncmp(name, "_type", sizeof("_type") - 1) == 0) {
|
||||
} else if (strncmp(name, "_vignetting", sizeof("_vignetting") - 1) == 0) {
|
||||
} else if (strncmp(name, "_water_quality", sizeof("_water_quality") - 1) == 0) {
|
||||
}
|
||||
} else if (strncmp(name, "game", sizeof("game") - 1) == 0) {
|
||||
name += sizeof("game") - 1;
|
||||
|
||||
if (strncmp(name, "_automatically_track_newest_quest", sizeof("_automatically_track_newest_quest") - 1) == 0) {
|
||||
} else if (strncmp(name, "_block_chat_invite", sizeof("_block_chat_invite") - 1) == 0) {
|
||||
} else if (strncmp(name, "_block_friend_invite", sizeof("_block_friend_invite") - 1) == 0) {
|
||||
} else if (strncmp(name, "_block_group_invite", sizeof("_block_group_invite") - 1) == 0) {
|
||||
} else if (strncmp(name, "_block_guild_invite", sizeof("_block_guild_invite") - 1) == 0) {
|
||||
} else if (strncmp(name, "_block_trade", sizeof("_block_trade") - 1) == 0) {
|
||||
} else if (strncmp(name, "_camera_shake", sizeof("_camera_shake") - 1) == 0) {
|
||||
} else if (strncmp(name, "_camera_zoom", sizeof("_camera_zoom") - 1) == 0) {
|
||||
} else if (strncmp(name, "_chat_status", sizeof("_chat_status") - 1) == 0) {
|
||||
} else if (strncmp(name, "_crosshair", sizeof("_crosshair") - 1) == 0) {
|
||||
} else if (strncmp(name, "_default_mount", sizeof("_default_mount") - 1) == 0) {
|
||||
} else if (strncmp(name, "_hud_animated", sizeof("_hud_animated") - 1) == 0) {
|
||||
} else if (strncmp(name, "_interact_radius", sizeof("_interact_radius") - 1) == 0) {
|
||||
} else if (strncmp(name, "_language", sizeof("_language") - 1) == 0) {
|
||||
} else if (strncmp(name, "_map_show_dungeons", sizeof("_map_show_dungeons") - 1) == 0) {
|
||||
} else if (strncmp(name, "_map_show_merchants", sizeof("_map_show_merchants") - 1) == 0) {
|
||||
} else if (strncmp(name, "_map_show_names", sizeof("_map_show_names") - 1) == 0) {
|
||||
} else if (strncmp(name, "_map_show_quest", sizeof("_map_show_quest") - 1) == 0) {
|
||||
} else if (strncmp(name, "_minimap_show_dungeons", sizeof("_minimap_show_dungeons") - 1) == 0) {
|
||||
} else if (strncmp(name, "_minimap_show_merchants", sizeof("_minimap_show_merchants") - 1) == 0) {
|
||||
} else if (strncmp(name, "_minimap_show_names", sizeof("_minimap_show_names") - 1) == 0) {
|
||||
} else if (strncmp(name, "_minimap_show_quest", sizeof("_minimap_show_quest") - 1) == 0) {
|
||||
} else if (strncmp(name, "_minion_visibility_player", sizeof("_minion_visibility_player") - 1) == 0) {
|
||||
} else if (strncmp(name, "_minion_visibility_self", sizeof("_minion_visibility_self") - 1) == 0) {
|
||||
} else if (strncmp(name, "_player_chat", sizeof("_player_chat") - 1) == 0) {
|
||||
} else if (strncmp(name, "_show_buffs", sizeof("_show_buffs") - 1) == 0) {
|
||||
} else if (strncmp(name, "_show_cooldown_times", sizeof("_show_cooldown_times") - 1) == 0) {
|
||||
} else if (strncmp(name, "_show_dmg_numbers", sizeof("_show_dmg_numbers") - 1) == 0) {
|
||||
} else if (strncmp(name, "_show_dodge", sizeof("_show_dodge") - 1) == 0) {
|
||||
} else if (strncmp(name, "_show_effect_gains", sizeof("_show_effect_gains") - 1) == 0) {
|
||||
} else if (strncmp(name, "_show_health_bar_monster", sizeof("_show_health_bar_monster") - 1) == 0) {
|
||||
} else if (strncmp(name, "_show_health_bar_player", sizeof("_show_health_bar_player") - 1) == 0) {
|
||||
} else if (strncmp(name, "_show_health_bar_self", sizeof("_show_health_bar_self") - 1) == 0) {
|
||||
} else if (strncmp(name, "_show_health_numbers", sizeof("_show_health_numbers") - 1) == 0) {
|
||||
} else if (strncmp(name, "_show_name_monster", sizeof("_show_name_monster") - 1) == 0) {
|
||||
} else if (strncmp(name, "_show_name_npc", sizeof("_show_name_npc") - 1) == 0) {
|
||||
} else if (strncmp(name, "_show_name_player", sizeof("_show_name_player") - 1) == 0) {
|
||||
} else if (strncmp(name, "_show_name_self", sizeof("_show_name_self") - 1) == 0) {
|
||||
} else if (strncmp(name, "_show_resource_numbers", sizeof("_show_resource_numbers") - 1) == 0) {
|
||||
} else if (strncmp(name, "_show_subtitles", sizeof("_show_subtitles") - 1) == 0) {
|
||||
} else if (strncmp(name, "_show_title_other", sizeof("_show_title_other") - 1) == 0) {
|
||||
} else if (strncmp(name, "_show_title_self", sizeof("_show_title_self") - 1) == 0) {
|
||||
} else if (strncmp(name, "_show_xp_bar_numbers", sizeof("_show_xp_bar_numbers") - 1) == 0) {
|
||||
} else if (strncmp(name, "_ui_visibility_flags", sizeof("_ui_visibility_flags") - 1) == 0) {
|
||||
client_settings->ui_visibility_flags = strtoull(pos, &pos, 10);
|
||||
} else if (strncmp(name, "_visibility_flags", sizeof("_visibility_flags") - 1) == 0) {
|
||||
client_settings->game_visibility_flags = strtoull(pos, &pos, 10);
|
||||
} else if (strncmp(name, "_debug_visibility_flags", sizeof("_debug_visibility_flags") - 1) == 0) {
|
||||
client_settings->debug_visibility_flags = strtoull(pos, &pos, 10);
|
||||
} else if (strncmp(name, "_theme", sizeof("_theme") - 1) == 0) {
|
||||
pos += strcpy_to_eol(pos, client_settings->game_theme);
|
||||
} else if (strncmp(name, "_ui_dim", sizeof("_ui_dim") - 1) == 0) {
|
||||
int32 index = strtoul(++pos, &pos, 10);
|
||||
pos += 2;
|
||||
|
||||
client_settings->game_ui_dim[index].x = strtof(pos, &pos); ++pos;
|
||||
client_settings->game_ui_dim[index].y = strtof(pos, &pos); ++pos;
|
||||
client_settings->game_ui_dim[index].width = strtof(pos, &pos); ++pos;
|
||||
client_settings->game_ui_dim[index].height = strtof(pos, &pos);
|
||||
} else if (strncmp(name, "_ui_show_hotkeys", sizeof("_ui_show_hotkeys") - 1) == 0) {
|
||||
} else if (strncmp(name, "_view", sizeof("_view") - 1) == 0) {
|
||||
} else if (strncmp(name, "_window1_dim", sizeof("_window1_dim") - 1) == 0) {
|
||||
client_settings->game_window1_dim[0] = (uint16) strtoul(pos, &pos, 10); ++pos;
|
||||
client_settings->game_window1_dim[1] = (uint16) atoi(pos);
|
||||
} else if (strncmp(name, "_window1_pos", sizeof("_window1_pos") - 1) == 0) {
|
||||
} else if (strncmp(name, "_window2_dim", sizeof("_window2_dim") - 1) == 0) {
|
||||
} else if (strncmp(name, "_window2_pos", sizeof("_window2_pos") - 1) == 0) {
|
||||
} else if (strncmp(name, "_window3_dim", sizeof("_window3_dim") - 1) == 0) {
|
||||
} else if (strncmp(name, "_window3_pos", sizeof("_window3_pos") - 1) == 0) {
|
||||
} else if (strncmp(name, "_window4_dim", sizeof("_window4_dim") - 1) == 0) {
|
||||
} else if (strncmp(name, "_window4_pos", sizeof("_window4_pos") - 1) == 0) {
|
||||
} else if (strncmp(name, "_window5_dim", sizeof("_window5_dim") - 1) == 0) {
|
||||
} else if (strncmp(name, "_window5_pos", sizeof("_window5_pos") - 1) == 0) {
|
||||
}
|
||||
} else if (strncmp(name, "hotkeys", sizeof("hotkeys") - 1) == 0) {
|
||||
name += sizeof("hotkeys") - 1;
|
||||
|
||||
if (strncmp(name, "_camera_fly_mode", sizeof("_camera_fly_mode") - 1) == 0) {
|
||||
} else if (strncmp(name, "_camera_look", sizeof("_camera_look") - 1) == 0) {
|
||||
} else if (strncmp(name, "_zoom_in", sizeof("_zoom_in") - 1) == 0) {
|
||||
} else if (strncmp(name, "_zoom_out", sizeof("_zoom_out") - 1) == 0) {
|
||||
} else if (strncmp(name, "_attack_move", sizeof("_attack_move") - 1) == 0) {
|
||||
} else if (strncmp(name, "_auction_house", sizeof("_auction_house") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_active_1", sizeof("_bar_active_1") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_active_2", sizeof("_bar_active_2") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_active_3", sizeof("_bar_active_3") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_active_4", sizeof("_bar_active_4") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_active_5", sizeof("_bar_active_5") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_1", sizeof("_bar_global_1") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_10", sizeof("_bar_global_10") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_11", sizeof("_bar_global_11") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_12", sizeof("_bar_global_12") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_13", sizeof("_bar_global_13") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_14", sizeof("_bar_global_14") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_15", sizeof("_bar_global_15") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_16", sizeof("_bar_global_16") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_17", sizeof("_bar_global_17") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_18", sizeof("_bar_global_18") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_19", sizeof("_bar_global_19") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_2", sizeof("_bar_global_2") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_20", sizeof("_bar_global_20") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_21", sizeof("_bar_global_21") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_22", sizeof("_bar_global_22") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_23", sizeof("_bar_global_23") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_24", sizeof("_bar_global_24") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_25", sizeof("_bar_global_25") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_3", sizeof("_bar_global_3") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_4", sizeof("_bar_global_4") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_5", sizeof("_bar_global_5") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_6", sizeof("_bar_global_6") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_7", sizeof("_bar_global_7") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_8", sizeof("_bar_global_8") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_global_9", sizeof("_bar_global_9") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_tab_1", sizeof("_bar_tab_1") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_tab_2", sizeof("_bar_tab_2") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_tab_3", sizeof("_bar_tab_3") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_tab_4", sizeof("_bar_tab_4") - 1) == 0) {
|
||||
} else if (strncmp(name, "_bar_tab_5", sizeof("_bar_tab_5") - 1) == 0) {
|
||||
} else if (strncmp(name, "_camera_1", sizeof("_camera_1") - 1) == 0) {
|
||||
} else if (strncmp(name, "_camera_2", sizeof("_camera_2") - 1) == 0) {
|
||||
} else if (strncmp(name, "_camera_3", sizeof("_camera_3") - 1) == 0) {
|
||||
} else if (strncmp(name, "_cancel_action", sizeof("_cancel_action") - 1) == 0) {
|
||||
} else if (strncmp(name, "_character", sizeof("_character") - 1) == 0) {
|
||||
} else if (strncmp(name, "_chat_send", sizeof("_chat_send") - 1) == 0) {
|
||||
} else if (strncmp(name, "_close_active_window", sizeof("_close_active_window") - 1) == 0) {
|
||||
} else if (strncmp(name, "_compare_item", sizeof("_compare_item") - 1) == 0) {
|
||||
} else if (strncmp(name, "_courser_move", sizeof("_courser_move") - 1) == 0) {
|
||||
} else if (strncmp(name, "_crouch", sizeof("_crouch") - 1) == 0) {
|
||||
} else if (strncmp(name, "_dodge", sizeof("_dodge") - 1) == 0) {
|
||||
} else if (strncmp(name, "_element_down", sizeof("_element_down") - 1) == 0) {
|
||||
} else if (strncmp(name, "_element_left", sizeof("_element_left") - 1) == 0) {
|
||||
} else if (strncmp(name, "_element_next", sizeof("_element_next") - 1) == 0) {
|
||||
} else if (strncmp(name, "_element_prev", sizeof("_element_prev") - 1) == 0) {
|
||||
} else if (strncmp(name, "_element_right", sizeof("_element_right") - 1) == 0) {
|
||||
} else if (strncmp(name, "_element_up", sizeof("_element_up") - 1) == 0) {
|
||||
} else if (strncmp(name, "_emote", sizeof("_emote") - 1) == 0) {
|
||||
} else if (strncmp(name, "_force_move", sizeof("_force_move") - 1) == 0) {
|
||||
} else if (strncmp(name, "_guild", sizeof("_guild") - 1) == 0) {
|
||||
} else if (strncmp(name, "_interact", sizeof("_interact") - 1) == 0) {
|
||||
} else if (strncmp(name, "_inventory", sizeof("_inventory") - 1) == 0) {
|
||||
} else if (strncmp(name, "_jump", sizeof("_jump") - 1) == 0) {
|
||||
} else if (strncmp(name, "_map", sizeof("_map") - 1) == 0) {
|
||||
} else if (strncmp(name, "_marker_1", sizeof("_marker_1") - 1) == 0) {
|
||||
} else if (strncmp(name, "_marker_2", sizeof("_marker_2") - 1) == 0) {
|
||||
} else if (strncmp(name, "_marker_3", sizeof("_marker_3") - 1) == 0) {
|
||||
} else if (strncmp(name, "_marker_4", sizeof("_marker_4") - 1) == 0) {
|
||||
} else if (strncmp(name, "_marker_5", sizeof("_marker_5") - 1) == 0) {
|
||||
} else if (strncmp(name, "_marker_6", sizeof("_marker_6") - 1) == 0) {
|
||||
} else if (strncmp(name, "_menu", sizeof("_menu") - 1) == 0) {
|
||||
} else if (strncmp(name, "_movement_down", sizeof("_movement_down") - 1) == 0) {
|
||||
} else if (strncmp(name, "_movement_left", sizeof("_movement_left") - 1) == 0) {
|
||||
} else if (strncmp(name, "_movement_pitch_down", sizeof("_movement_pitch_down") - 1) == 0) {
|
||||
} else if (strncmp(name, "_movement_pitch_up", sizeof("_movement_pitch_up") - 1) == 0) {
|
||||
} else if (strncmp(name, "_movement_right", sizeof("_movement_right") - 1) == 0) {
|
||||
} else if (strncmp(name, "_movement_roll_left", sizeof("_movement_roll_left") - 1) == 0) {
|
||||
} else if (strncmp(name, "_movement_roll_right", sizeof("_movement_roll_right") - 1) == 0) {
|
||||
} else if (strncmp(name, "_movement_up", sizeof("_movement_up") - 1) == 0) {
|
||||
} else if (strncmp(name, "_movement_vertical_down", sizeof("_movement_vertical_down") - 1) == 0) {
|
||||
} else if (strncmp(name, "_movement_vertical_up", sizeof("_movement_vertical_up") - 1) == 0) {
|
||||
} else if (strncmp(name, "_movement_yaw_left", sizeof("_movement_yaw_left") - 1) == 0) {
|
||||
} else if (strncmp(name, "_movement_yaw_right", sizeof("_movement_yaw_right") - 1) == 0) {
|
||||
} else if (strncmp(name, "_ping", sizeof("_ping") - 1) == 0) {
|
||||
} else if (strncmp(name, "_quest", sizeof("_quest") - 1) == 0) {
|
||||
} else if (strncmp(name, "_skills", sizeof("_skills") - 1) == 0) {
|
||||
} else if (strncmp(name, "_sneak", sizeof("_sneak") - 1) == 0) {
|
||||
} else if (strncmp(name, "_toggle_all_windows", sizeof("_toggle_all_windows") - 1) == 0) {
|
||||
} else if (strncmp(name, "_toggle_hud", sizeof("_toggle_hud") - 1) == 0) {
|
||||
} else if (strncmp(name, "_view_next", sizeof("_view_next") - 1) == 0) {
|
||||
} else if (strncmp(name, "_view_prv", sizeof("_view_prv") - 1) == 0) {
|
||||
} else if (strncmp(name, "_walk", sizeof("_walk") - 1) == 0) {
|
||||
}
|
||||
} else if (strncmp(name, "input", sizeof("input") - 1) == 0) {
|
||||
name += sizeof("input") - 1;
|
||||
|
||||
if (strncmp(name, "_camera_speed", sizeof("_camera_speed") - 1) == 0) {
|
||||
client_settings->input_camera_speed = (f32) atof(pos);
|
||||
} else if (strncmp(name, "_controller1_gyro_x_deadzone", sizeof("_controller1_gyro_x_deadzone") - 1) == 0) {
|
||||
} else if (strncmp(name, "_controller1_gyro_x_zero", sizeof("_controller1_gyro_x_zero") - 1) == 0) {
|
||||
} else if (strncmp(name, "_controller1_gyro_y_deadzone", sizeof("_controller1_gyro_y_deadzone") - 1) == 0) {
|
||||
} else if (strncmp(name, "_controller1_gyro_y_zero", sizeof("_controller1_gyro_y_zero") - 1) == 0) {
|
||||
} else if (strncmp(name, "_controller1_gyro_z_deadzone", sizeof("_controller1_gyro_z_deadzone") - 1) == 0) {
|
||||
} else if (strncmp(name, "_controller1_gyro_z_zero", sizeof("_controller1_gyro_z_zero") - 1) == 0) {
|
||||
} else if (strncmp(name, "_controller1_stick_left_deadzone", sizeof("_controller1_stick_left_deadzone") - 1) == 0) {
|
||||
} else if (strncmp(name, "_controller1_stick_right_deadzone", sizeof("_controller1_stick_right_deadzone") - 1) == 0) {
|
||||
} else if (strncmp(name, "_controller1_trigger_left_deadzone", sizeof("_controller1_trigger_left_deadzone") - 1) == 0) {
|
||||
} else if (strncmp(name, "_controller1_trigger_right_deadzone", sizeof("_controller1_trigger_right_deadzone") - 1) == 0) {
|
||||
} else if (strncmp(name, "_device", sizeof("_device") - 1) == 0) {
|
||||
} else if (strncmp(name, "_invert_mouse", sizeof("_invert_mouse") - 1) == 0) {
|
||||
} else if (strncmp(name, "_look_sensitivity", sizeof("_look_sensitivity") - 1) == 0) {
|
||||
client_settings->input_look_sensitivity = (f32) atof(pos);
|
||||
}
|
||||
} else if (strncmp(name, "cache", sizeof("cache") - 1) == 0) {
|
||||
name += sizeof("cache") - 1;
|
||||
|
||||
if (strncmp(name, "_chat", sizeof("_chat") - 1) == 0) {
|
||||
} else if (strncmp(name, "_guild", sizeof("_guild") - 1) == 0) {
|
||||
} else if (strncmp(name, "_log", sizeof("_log") - 1) == 0) {
|
||||
} else if (strncmp(name, "_monster", sizeof("_monster") - 1) == 0) {
|
||||
} else if (strncmp(name, "_npc", sizeof("_npc") - 1) == 0) {
|
||||
} else if (strncmp(name, "_player", sizeof("_player") - 1) == 0) {
|
||||
}
|
||||
} else if (strncmp(name, "audio", sizeof("audio") - 1) == 0) {
|
||||
name += sizeof("audio") - 1;
|
||||
|
||||
if (strncmp(name, "_volume_environment", sizeof("_volume_environment") - 1) == 0) {
|
||||
} else if (strncmp(name, "_volume_game", sizeof("_volume_game") - 1) == 0) {
|
||||
} else if (strncmp(name, "_volume_master", sizeof("_volume_master") - 1) == 0) {
|
||||
client_settings->audio_volume_master = (f32) atof(pos);
|
||||
} else if (strncmp(name, "_volume_music", sizeof("_volume_music") - 1) == 0) {
|
||||
} else if (strncmp(name, "_volume_speech", sizeof("_volume_speech") - 1) == 0) {
|
||||
}
|
||||
} else if (strncmp(name, "network", sizeof("network") - 1) == 0) {
|
||||
name += sizeof("network") - 1;
|
||||
|
||||
if (strncmp(name, "_hostname", sizeof("_hostname") - 1) == 0) {
|
||||
} else if (strncmp(name, "_port", sizeof("_port") - 1) == 0) {
|
||||
}
|
||||
} else if (strncmp(name, "system", sizeof("system") - 1) == 0) {
|
||||
name += sizeof("system") - 1;
|
||||
|
||||
if (strncmp(name, "system_cache", sizeof("system_cache") - 1) == 0) {
|
||||
} else if (strncmp(name, "system_memory", sizeof("system_memory") - 1) == 0) {
|
||||
} else if (strncmp(name, "system_threads", sizeof("system_threads") - 1) == 0) {
|
||||
}
|
||||
} else {
|
||||
if (strncmp(name, "extension_active", sizeof("extension_active") - 1) == 0) {
|
||||
}
|
||||
}
|
||||
|
||||
// Go to end of line
|
||||
while (*pos != '\n' && *pos != '\0') {
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,11 +19,6 @@
|
|||
#define SETTING_TYPE_PERSPECTIVE_THIRD 0x01
|
||||
#define SETTING_TYPE_PERSPECTIVE_ISOMETRIC 0x02
|
||||
|
||||
#define SETTING_TYPE_ANTI_ALIASING_TAA 0x01
|
||||
#define SETTING_TYPE_ANTI_ALIASING_SSAA 0x02
|
||||
#define SETTING_TYPE_ANTI_ALIASING_MSAA 0x03
|
||||
#define SETTING_TYPE_ANTI_ALIASING_FXAA 0x04
|
||||
|
||||
#define SETTING_TYPE_SYNC_V 0x1
|
||||
#define SETTING_TYPE_SYNC_ADAPTIVE 0x2
|
||||
#define SETTING_TYPE_SYNC_FAST 0x3
|
||||
|
|
@ -67,10 +62,6 @@
|
|||
#define SETTING_TYPE_WINDOW_MODE_WINDOWED_FULLSCREEN 0x01
|
||||
#define SETTING_TYPE_WINDOW_MODE_WINDOWED 0x02
|
||||
|
||||
#define SETTING_TYPE_SIMD_128 1
|
||||
#define SETTING_TYPE_SIMD_256 2
|
||||
#define SETTING_TYPE_SIMD_512 3
|
||||
|
||||
#define SETTING_TYPE_DISABLED 0x00
|
||||
#define SETTING_TYPE_UNLIMITED 0x00
|
||||
|
||||
|
|
|
|||
|
|
@ -1,77 +0,0 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_NETWORK_CLIENT_H
|
||||
#define TOS_NETWORK_CLIENT_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "SocketConnection.h"
|
||||
#include "../stdlib/Types.h"
|
||||
#include "../memory/RingMemory.h"
|
||||
|
||||
#if _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "NetworkOSWrapper.h"
|
||||
|
||||
#ifndef MAX_STATIC_NETWORK_PACKET_SIZE
|
||||
#define MAX_STATIC_NETWORK_PACKET_SIZE 8192
|
||||
#endif
|
||||
|
||||
void socket_client_udb_connect(const char *hostname, SocketConnection* con) {
|
||||
addrinfo hints, *res, *p;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_INET6;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
|
||||
char port_str[6];
|
||||
snprintf(port_str, sizeof(port_str), "%d", con->port);
|
||||
|
||||
if (getaddrinfo(hostname, port_str, &hints, &res) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (p = res; p != NULL; p = p->ai_next) {
|
||||
if ((con->sd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy((void *) &con->server_addr, p->ai_addr, p->ai_addrlen);
|
||||
break;
|
||||
}
|
||||
|
||||
freeaddrinfo(res);
|
||||
}
|
||||
|
||||
int socket_client_send(SOCKET sd, char *data, size_t length, sockaddr_in6 *server_addr, socklen_t addr_len) {
|
||||
int sent_bytes = sendto(sd, data, (int) length, 0, (sockaddr *)server_addr, addr_len);
|
||||
if (sent_bytes == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int socket_client_disconnect(SOCKET sd)
|
||||
{
|
||||
close(sd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_NETWORK_SERVER_H
|
||||
#define TOS_NETWORK_SERVER_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "NetworkOSWrapper.h"
|
||||
#include "SocketConnection.h"
|
||||
|
||||
void socket_server_udb_create(const char *hostname, SocketConnection* con) {
|
||||
con->sd = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
|
||||
int flags;
|
||||
if ((flags = fcntl(con->sd, F_GETFL, 0)) < 0) {
|
||||
close(con->sd);
|
||||
con->sd = 0;
|
||||
}
|
||||
|
||||
if (fcntl(con->sd, F_SETFL, flags | O_NONBLOCK) < 0) {
|
||||
close(con->sd);
|
||||
con->sd = 0;
|
||||
}
|
||||
|
||||
con->server_addr.sin6_family = AF_INET6;
|
||||
con->server_addr.sin6_addr = in6addr_any;
|
||||
con->server_addr.sin6_port = htons(con->port);
|
||||
|
||||
if (bind(con->sd, (sockaddr *) &con->server_addr, sizeof(sockaddr_in6)) < 0) {
|
||||
close(con->sd);
|
||||
con->sd = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -24,11 +24,10 @@ struct SocketConnection {
|
|||
#if _WIN32
|
||||
SOCKET sd;
|
||||
#else
|
||||
int sd;
|
||||
int32 sd;
|
||||
#endif
|
||||
|
||||
sockaddr_in6 server_addr;
|
||||
socklen_t addr_len;
|
||||
sockaddr_in6 addr;
|
||||
uint16 port;
|
||||
};
|
||||
|
||||
|
|
|
|||
42
network/packet/OMSPacket.h
Normal file
42
network/packet/OMSPacket.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef TOS_NETWORK_PACKET_OMS_H
|
||||
#define TOS_NETWORK_PACKET_OMS_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../compression/LZP.h"
|
||||
#include "../../utils/EndianUtils.h"
|
||||
|
||||
#include "PacketHeader.h"
|
||||
|
||||
#if _WIN32
|
||||
#include <ws2def.h>
|
||||
#elif __linux__
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
// WARNING: Since this requires admin priviledges, this can only be used for server-server communication
|
||||
inline
|
||||
uint16 packet_oms_create_raw(
|
||||
byte* __restrict packet,
|
||||
in6_addr* __restrict ipv6_src, in6_addr* __restrict ipv6_dst,
|
||||
uint16 flow,
|
||||
byte* __restrict data, uint16 data_length
|
||||
) {
|
||||
// create ipv6 header
|
||||
HeaderIPv6Unpacked* ip6_header = (HeaderIPv6Unpacked *) packet;
|
||||
ip6_header->ip6_flow = SWAP_ENDIAN_BIG((6 << 28) | (0 << 20) | flow);
|
||||
ip6_header->ip6_plen = SWAP_ENDIAN_BIG(sizeof(UDPHeaderIPv6Unpacked) + data_length);
|
||||
ip6_header->ip6_nxt = 255;
|
||||
ip6_header->ip6_hops = 64;
|
||||
memcpy(&ip6_header->ip6_src, ipv6_src, sizeof(in6_addr));
|
||||
memcpy(&ip6_header->ip6_dst, ipv6_dst, sizeof(in6_addr));
|
||||
|
||||
// create payload
|
||||
memcpy(packet + sizeof(HeaderIPv6Unpacked), data, data_length);
|
||||
|
||||
return sizeof(HeaderIPv6Unpacked) + data_length;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
#define TOS_NETWORK_PACKET_CACHE_H
|
||||
|
||||
#include "../../memory/RingMemory.h"
|
||||
#include "../../utils/BufferMemory.h"
|
||||
#include "../../memory/BufferMemory.h"
|
||||
|
||||
#if _WIN32
|
||||
#include <winsock2.h>
|
||||
|
|
|
|||
|
|
@ -5,56 +5,33 @@
|
|||
|
||||
#include "../../stdlib/Types.h"
|
||||
|
||||
#if _WIN32
|
||||
#include <ws2def.h>
|
||||
#include <in6addr.h>
|
||||
#include <ws2tcpip.h>
|
||||
#elif __linux__
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#define HEADER_IPV6_SIZE 40
|
||||
// Size 40 bytes
|
||||
struct HeaderIPv6 {
|
||||
byte data[HEADER_IPV6_SIZE];
|
||||
};
|
||||
|
||||
// Size 42 bytes
|
||||
struct HeaderIPv6Unpacked {
|
||||
byte version;
|
||||
byte traffic_class;
|
||||
uint32 flow_label;
|
||||
// Size 40 bytes
|
||||
struct PACKED_STRUCT HeaderIPv6Unpacked {
|
||||
uint32 ip6_flow; // also contains version and traffic class
|
||||
|
||||
uint16 length;
|
||||
byte next_header;
|
||||
byte hop_limit;
|
||||
uint16 ip6_plen;
|
||||
byte ip6_nxt;
|
||||
byte ip6_hops;
|
||||
|
||||
byte src[16];
|
||||
byte dst[16];
|
||||
in6_addr ip6_src;
|
||||
in6_addr ip6_dst;
|
||||
};
|
||||
|
||||
inline
|
||||
void unpack_ipv6_header(const HeaderIPv6* ipv6, HeaderIPv6Unpacked* ipv6_unpacked)
|
||||
{
|
||||
ipv6_unpacked->version = (ipv6->data[0] >> 4) & 0x0F;
|
||||
ipv6_unpacked->traffic_class = ((ipv6->data[0] & 0x0F) << 4) | (ipv6->data[1] >> 4);
|
||||
ipv6_unpacked->flow_label = ((ipv6->data[1] & 0x0F) << 16) | (ipv6->data[2] << 8) | ipv6->data[3];
|
||||
ipv6_unpacked->length = (ipv6->data[4] << 8) | ipv6->data[5];
|
||||
ipv6_unpacked->next_header = ipv6->data[6];
|
||||
ipv6_unpacked->hop_limit = ipv6->data[7];
|
||||
|
||||
memcpy(ipv6_unpacked->src, &ipv6->data[8], 16);
|
||||
memcpy(ipv6_unpacked->dst, &ipv6->data[24], 16);
|
||||
}
|
||||
|
||||
inline
|
||||
void pack_ipv6_header(const HeaderIPv6Unpacked* ipv6_unpacked, HeaderIPv6* ipv6)
|
||||
{
|
||||
ipv6->data[0] = (ipv6_unpacked->version << 4) | (ipv6_unpacked->traffic_class >> 4);
|
||||
ipv6->data[1] = (ipv6_unpacked->traffic_class << 4) | ((ipv6_unpacked->flow_label >> 16) & 0x0F);
|
||||
ipv6->data[1] |= (ipv6_unpacked->flow_label >> 16) & 0x0F;
|
||||
ipv6->data[2] = (ipv6_unpacked->flow_label >> 8) & 0xFF;
|
||||
ipv6->data[3] = ipv6_unpacked->flow_label & 0xFF;
|
||||
ipv6->data[4] = (ipv6_unpacked->length >> 8) & 0xFF;
|
||||
ipv6->data[5] = ipv6_unpacked->length & 0xFF;
|
||||
ipv6->data[6] = ipv6_unpacked->next_header;
|
||||
ipv6->data[7] = ipv6_unpacked->hop_limit;
|
||||
|
||||
memcpy(&ipv6->data[8], ipv6_unpacked->src, 16);
|
||||
memcpy(&ipv6->data[24], ipv6_unpacked->dst, 16);
|
||||
}
|
||||
UNPACKED_STRUCT
|
||||
|
||||
#define HEADER_UDP_SIZE 8
|
||||
// Size 8 bytes
|
||||
|
|
@ -63,41 +40,38 @@ struct UDPHeaderIPv6 {
|
|||
};
|
||||
|
||||
// Size 8 bytes
|
||||
struct UDPHeaderIPv6Unpacked {
|
||||
uint16 src_port;
|
||||
uint16 dst_port;
|
||||
uint16 length;
|
||||
uint16 checksum;
|
||||
struct PACKED_STRUCT UDPHeaderIPv6Unpacked {
|
||||
uint16 source;
|
||||
uint16 dest;
|
||||
uint16 len;
|
||||
uint16 check;
|
||||
};
|
||||
UNPACKED_STRUCT
|
||||
|
||||
struct PACKED_STRUCT UDPPseudoHeaderIPv6 {
|
||||
in6_addr src;
|
||||
in6_addr dst;
|
||||
uint32 length;
|
||||
byte zero[3];
|
||||
byte next_header;
|
||||
};
|
||||
UNPACKED_STRUCT
|
||||
|
||||
inline
|
||||
void unpack_udp_header_ipv6(const UDPHeaderIPv6* ipv6, UDPHeaderIPv6Unpacked* udp_unpacked)
|
||||
void packet_create_destination_addr(sockaddr_in6* dest_addr, const char* ipv6, uint16 port)
|
||||
{
|
||||
udp_unpacked->src_port = (ipv6->data[0] << 8) | ipv6->data[1];
|
||||
udp_unpacked->dst_port = (ipv6->data[2] << 8) | ipv6->data[3];
|
||||
udp_unpacked->length = (ipv6->data[4] << 8) | ipv6->data[5];
|
||||
udp_unpacked->checksum = (ipv6->data[6] << 8) | ipv6->data[7];
|
||||
memset(dest_addr, 0, sizeof(sockaddr_in6));
|
||||
dest_addr->sin6_family = AF_INET6;
|
||||
dest_addr->sin6_port = SWAP_ENDIAN_BIG(port);
|
||||
inet_pton(AF_INET6, ipv6, &dest_addr->sin6_addr);
|
||||
}
|
||||
|
||||
inline
|
||||
void pack_udp_header_ipv6(const UDPHeaderIPv6Unpacked* udp_unpacked, UDPHeaderIPv6* ipv6)
|
||||
void packet_create_destination_addr(sockaddr_in6* dest_addr, in6_addr* ipv6, uint16 port)
|
||||
{
|
||||
ipv6->data[0] = (udp_unpacked->src_port >> 8) & 0xFF;
|
||||
ipv6->data[1] = udp_unpacked->src_port & 0xFF;
|
||||
ipv6->data[2] = (udp_unpacked->dst_port >> 8) & 0xFF;
|
||||
ipv6->data[3] = udp_unpacked->dst_port & 0xFF;
|
||||
ipv6->data[4] = (udp_unpacked->length >> 8) & 0xFF;
|
||||
ipv6->data[5] = udp_unpacked->length & 0xFF;
|
||||
ipv6->data[6] = (udp_unpacked->checksum >> 8) & 0xFF;
|
||||
ipv6->data[7] = udp_unpacked->checksum & 0xFF;
|
||||
dest_addr->sin6_family = AF_INET6;
|
||||
dest_addr->sin6_port = SWAP_ENDIAN_BIG(port);
|
||||
memcpy(&dest_addr->sin6_addr, ipv6, sizeof(in6_addr));
|
||||
}
|
||||
|
||||
// Size 7 bytes
|
||||
struct CustomHeaderUnpacked {
|
||||
uint16 msg_sequence;
|
||||
uint16 msg_ack_sequence;
|
||||
uint16 msg_ack;
|
||||
byte msg_type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,13 +1,21 @@
|
|||
#ifndef TOS_NETWORK_PACKET_H
|
||||
#define TOS_NETWORK_PACKET_H
|
||||
#ifndef TOS_NETWORK_PACKET_UDP_H
|
||||
#define TOS_NETWORK_PACKET_UDP_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../compression/LZP.h"
|
||||
#include "../../utils/EndianUtils.h"
|
||||
|
||||
#include "PacketHeader.h"
|
||||
|
||||
#if _WIN32
|
||||
#include <ws2def.h>
|
||||
#elif __linux__
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
// The message loop is as follows:
|
||||
// Game Data -> pack data
|
||||
// Game Message (packed) -> compress data
|
||||
|
|
@ -32,52 +40,116 @@ struct UDPPacketIPv6 {
|
|||
struct UDPMessageIPv6 {
|
||||
HeaderIPv6Unpacked header_ipv6;
|
||||
UDPHeaderIPv6Unpacked header_udp;
|
||||
CustomHeaderUnpacked header_custom;
|
||||
|
||||
size_t length;
|
||||
byte* data;
|
||||
};
|
||||
|
||||
/**
|
||||
* WARNING: This requires the original message to remain in memory since we are only referencing the data
|
||||
*/
|
||||
inline
|
||||
void udp_packet_to_message(const UDPPacketIPv6* packet, UDPMessageIPv6* message)
|
||||
{
|
||||
unpack_ipv6_header((const HeaderIPv6*) packet->data, &message->header_ipv6);
|
||||
unpack_udp_header_ipv6((const UDPHeaderIPv6*) (packet->data + HEADER_IPV6_SIZE), &message->header_udp);
|
||||
message->data = (byte *) (packet->data + HEADER_IPV6_SIZE + HEADER_UDP_SIZE);
|
||||
uint16 packet_udp_calculate_checksum(uint16* buf, int32 count) {
|
||||
uint32 sum = 0;
|
||||
|
||||
// @todo transform packet data to appropriate packet type
|
||||
// First we create the checksum from the ipv6 header (not all of the data is required)
|
||||
// Alternatively we would have had to create a pseudo_header and do a bunch of memcpy which we didn't want to do
|
||||
HeaderIPv6Unpacked* ipv6_header = (HeaderIPv6Unpacked *) buf;
|
||||
const byte* temp_data = ((byte *) (&ipv6_header->ip6_src));
|
||||
for (uint32 i = 0; i < sizeof(ipv6_header->ip6_src) / 2; ++i) {
|
||||
uint16 word = (uint16) temp_data[i] << 8 | (uint16) temp_data[i + 1];
|
||||
sum += word;
|
||||
}
|
||||
|
||||
temp_data = ((byte *) (&ipv6_header->ip6_dst));
|
||||
for (uint32 i = 0; i < sizeof(ipv6_header->ip6_dst) / 2; ++i) {
|
||||
uint16 word = (uint16) temp_data[i] << 8 | (uint16) temp_data[i + 1];
|
||||
sum += word;
|
||||
}
|
||||
|
||||
temp_data = ((byte *) (&ipv6_header->ip6_plen));
|
||||
for (uint32 i = 0; i < sizeof(ipv6_header->ip6_plen) / 2; ++i) {
|
||||
uint16 word = (uint16) temp_data[i] << 8 | (uint16) temp_data[i + 1];
|
||||
sum += word;
|
||||
}
|
||||
|
||||
// The next header has some 0s prefixed, this is required since the checksum works on uint16
|
||||
byte next_header[] = {0, 0, 0, ipv6_header->ip6_nxt};
|
||||
for (uint32 i = 0; i < sizeof(ipv6_header->ip6_nxt) / 2; ++i) {
|
||||
uint16 word = (uint16) next_header[i] << 8 | (uint16) next_header[i + 1];
|
||||
sum += word;
|
||||
}
|
||||
|
||||
// Now create checksum for udp header and payload/body
|
||||
while (count > 0) {
|
||||
sum += *buf++;
|
||||
--count;
|
||||
}
|
||||
|
||||
sum = (sum >> 16) + (sum & 0xFFFF);
|
||||
sum += (sum >> 16);
|
||||
|
||||
return (uint16) ~sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* The original message can be deleted since the data is copied over
|
||||
*/
|
||||
// WARNING: ports need to be already in big endian
|
||||
inline
|
||||
void message_to_udp_packet(const UDPMessageIPv6* message, UDPPacketIPv6* packet)
|
||||
{
|
||||
pack_ipv6_header(&message->header_ipv6, (HeaderIPv6 *) packet);
|
||||
uint16 packet_udp_create_raw(
|
||||
byte* __restrict packet,
|
||||
in6_addr* __restrict ipv6_src, uint16 port_src,
|
||||
in6_addr* __restrict ipv6_dst, uint16 port_dst,
|
||||
uint16 flow,
|
||||
byte* __restrict data, uint16 data_length
|
||||
) {
|
||||
// create ipv6 header
|
||||
HeaderIPv6Unpacked* ip6_header = (HeaderIPv6Unpacked *) packet;
|
||||
ip6_header->ip6_flow = SWAP_ENDIAN_BIG((6 << 28) | (0 << 20) | flow);
|
||||
ip6_header->ip6_plen = SWAP_ENDIAN_BIG((uint16) (sizeof(UDPHeaderIPv6Unpacked) + data_length));
|
||||
ip6_header->ip6_nxt = IPPROTO_UDP;
|
||||
ip6_header->ip6_hops = 64;
|
||||
memcpy(&ip6_header->ip6_src, ipv6_src, sizeof(in6_addr));
|
||||
memcpy(&ip6_header->ip6_dst, ipv6_dst, sizeof(in6_addr));
|
||||
|
||||
packet->data = packet->data + HEADER_IPV6_SIZE;
|
||||
pack_udp_header_ipv6(&message->header_udp, (UDPHeaderIPv6 *) packet);
|
||||
packet->data = packet->data - HEADER_IPV6_SIZE;
|
||||
// create udp header
|
||||
UDPHeaderIPv6Unpacked* udp_header = (UDPHeaderIPv6Unpacked *) (packet + sizeof(HeaderIPv6Unpacked));
|
||||
|
||||
memcpy(packet->data + HEADER_IPV6_SIZE + HEADER_UDP_SIZE, message->data, message->length);
|
||||
udp_header->source = port_src;
|
||||
udp_header->dest = port_dst;
|
||||
udp_header->len = ip6_header->ip6_plen;
|
||||
udp_header->check = 0;
|
||||
|
||||
// create payload
|
||||
memcpy(packet + sizeof(HeaderIPv6Unpacked) + sizeof(UDPHeaderIPv6Unpacked), data, data_length);
|
||||
|
||||
udp_header->check = SWAP_ENDIAN_BIG(packet_udp_calculate_checksum(
|
||||
(uint16 *) (packet),
|
||||
(sizeof(UDPHeaderIPv6Unpacked) + data_length) / 2
|
||||
));
|
||||
|
||||
// Raw sockets must use the entire packet size
|
||||
return sizeof(HeaderIPv6Unpacked) + sizeof(UDPHeaderIPv6Unpacked) + data_length;
|
||||
}
|
||||
|
||||
// WARNING: ports need to be already in big endian
|
||||
inline
|
||||
uint16 packet_udp_create(
|
||||
byte* __restrict packet,
|
||||
uint16 port_src, uint16 port_dst,
|
||||
byte* __restrict data, uint16 data_length
|
||||
) {
|
||||
// create udp header
|
||||
UDPHeaderIPv6Unpacked* udp_header = (UDPHeaderIPv6Unpacked *) packet;
|
||||
|
||||
udp_header->source = port_src;
|
||||
udp_header->dest = port_dst;
|
||||
udp_header->len = SWAP_ENDIAN_BIG((uint16) (sizeof(UDPHeaderIPv6Unpacked) + data_length));
|
||||
udp_header->check = 0;
|
||||
|
||||
// create payload
|
||||
memcpy(packet + sizeof(UDPHeaderIPv6Unpacked), data, data_length);
|
||||
|
||||
return data_length;
|
||||
}
|
||||
|
||||
inline
|
||||
void decompress_data(UDPMessageIPv6* message, byte* decompress_buffer)
|
||||
void packet_flowinfo_set(sockaddr_in6* dest, uint16 flow)
|
||||
{
|
||||
lzp_decode(message->data, message->length, decompress_buffer);
|
||||
message->data = decompress_buffer;
|
||||
}
|
||||
|
||||
inline
|
||||
void compress_data(UDPMessageIPv6* message, byte* compressed_buffer)
|
||||
{
|
||||
lzp_encode(message->data, message->length, compressed_buffer);
|
||||
message->data = compressed_buffer;
|
||||
dest->sin6_flowinfo = SWAP_ENDIAN_BIG((6 << 28) | (0 << 20) | flow);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -4,7 +4,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "../../../stdlib/Types.h"
|
||||
#include "../../../config.h"
|
||||
|
||||
struct ChatMessagePacket {
|
||||
byte* data; // fixed 8+2+?
|
||||
|
|
@ -14,7 +13,7 @@ struct ChatMessagePacketUnpacked {
|
|||
uint32 from;
|
||||
uint32 to;
|
||||
|
||||
byte type; // 2^3 Global, Player, Group, Guild, Local
|
||||
byte type; // 2^3 Global, Server, Player, Group, Guild, Local
|
||||
byte level; // 2^2 Normal, info (grey), important (yellow), critical (red)
|
||||
|
||||
uint16 length; // 2^9
|
||||
|
|
|
|||
11
network/packet/general/AckPacket.h
Normal file
11
network/packet/general/AckPacket.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef TOS_NETWORK_PACKET_GENERAL_PING_H
|
||||
#define TOS_NETWORK_PACKET_GENERAL_PING_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../../stdlib/Types.h"
|
||||
#include "../PacketHeader.h"
|
||||
|
||||
typedef CustomHeaderUnpacked AckPacket;
|
||||
|
||||
#endif
|
||||
19
network/packet/general/PingPacket.h
Normal file
19
network/packet/general/PingPacket.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef TOS_NETWORK_PACKET_GENERAL_PING_H
|
||||
#define TOS_NETWORK_PACKET_GENERAL_PING_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../../../stdlib/Types.h"
|
||||
|
||||
// The default ping package is an empty package
|
||||
struct PingPackage {};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct __attribute__ ((__packed__)) TimedPingPackage {
|
||||
uint8 msg_type;
|
||||
uint8 subtype;
|
||||
uint64 time;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
#include "../memory/RingMemory.h"
|
||||
#include "../stdlib/simd/SIMD_I32.h"
|
||||
#include "../utils/EndianUtils.h"
|
||||
#include "../utils/StringUtils.h"
|
||||
|
||||
#define MESH_VERSION 1
|
||||
|
||||
|
|
@ -87,7 +88,6 @@ void mesh_from_file_txt(
|
|||
|
||||
mesh->vertices = (f32 *) mesh->data;
|
||||
|
||||
|
||||
// @todo The temp memory reservation is bad, once the file format is really finalized we need to change this.
|
||||
// We can't just assume these sizes
|
||||
int32 vertex_count = 0;
|
||||
|
|
@ -109,9 +109,7 @@ void mesh_from_file_txt(
|
|||
uint32 temp_color_count = 0;
|
||||
|
||||
while (*pos != '\0') {
|
||||
while (*pos == ' ' || *pos == '\t' || *pos == '\n') {
|
||||
++pos;
|
||||
}
|
||||
char_skip_empty(&pos);
|
||||
|
||||
if (*pos == '\0') {
|
||||
break;
|
||||
|
|
@ -154,15 +152,11 @@ void mesh_from_file_txt(
|
|||
state = 15;
|
||||
} else {
|
||||
// not supported or comment
|
||||
while (*pos != '\n' && *pos != '\0') {
|
||||
++pos;
|
||||
}
|
||||
char_move_to(&pos, '\n');
|
||||
}
|
||||
|
||||
// move past keyword
|
||||
while (*pos != ' ' && *pos != '\n' && *pos != '\0') {
|
||||
++pos;
|
||||
}
|
||||
char_skip_non_empty(&pos);
|
||||
|
||||
// move past whitespaces and newline
|
||||
bool is_next_line = false;
|
||||
|
|
|
|||
39
platform/Library.h
Normal file
39
platform/Library.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_LIBRARY_H
|
||||
#define TOS_PLATFORM_LIBRARY_H
|
||||
|
||||
#include "../stdlib/Types.h"
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
struct Library {
|
||||
#if _WIN32
|
||||
HMODULE handle;
|
||||
#elif __linux__
|
||||
void* handle;
|
||||
#endif
|
||||
|
||||
bool is_valid;
|
||||
|
||||
char dir[MAX_PATH];
|
||||
char dst[64];
|
||||
|
||||
#if DEBUG
|
||||
uint64 last_load;
|
||||
#endif
|
||||
|
||||
int32 function_count;
|
||||
const char** function_names;
|
||||
void** functions;
|
||||
};
|
||||
|
||||
#endif
|
||||
92
platform/SystemInfo.h
Normal file
92
platform/SystemInfo.h
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_SYSTEM_INFO_H
|
||||
#define TOS_PLATFORM_SYSTEM_INFO_H
|
||||
|
||||
#include "../stdlib/Types.h"
|
||||
|
||||
struct CpuCacheInfo {
|
||||
int32 level;
|
||||
int32 size;
|
||||
int32 ways;
|
||||
int32 partitions;
|
||||
int32 sets;
|
||||
int32 line_size;
|
||||
};
|
||||
|
||||
// @todo add vendor name
|
||||
struct MainboardInfo {
|
||||
char name[64];
|
||||
char serial_number[64];
|
||||
};
|
||||
|
||||
// @todo add ipv6
|
||||
struct NetworkInfo {
|
||||
char slot[64];
|
||||
byte mac[8];
|
||||
};
|
||||
|
||||
struct SIMDInfo {
|
||||
f32 sse;
|
||||
int32 avx256;
|
||||
int32 avx512;
|
||||
};
|
||||
|
||||
struct CpuInfo {
|
||||
char vendor[13];
|
||||
char brand[49];
|
||||
int32 model;
|
||||
int32 family;
|
||||
int32 mhz;
|
||||
CpuCacheInfo cache[4];
|
||||
int32 page_size;
|
||||
SIMDInfo simd;
|
||||
};
|
||||
|
||||
struct OSInfo {
|
||||
char vendor[16];
|
||||
char name[64];
|
||||
int32 major;
|
||||
int32 minor;
|
||||
};
|
||||
|
||||
struct RamInfo {
|
||||
int32 memory;
|
||||
};
|
||||
|
||||
struct GpuInfo {
|
||||
char name[64];
|
||||
int32 vram;
|
||||
};
|
||||
|
||||
struct DisplayInfo {
|
||||
char name[64];
|
||||
int32 width;
|
||||
int32 height;
|
||||
int32 hz;
|
||||
};
|
||||
|
||||
struct SystemInfo {
|
||||
OSInfo os;
|
||||
MainboardInfo mainboard;
|
||||
|
||||
NetworkInfo network[4];
|
||||
int32 network_count;
|
||||
|
||||
CpuInfo cpu;
|
||||
RamInfo ram;
|
||||
|
||||
GpuInfo gpu[2];
|
||||
int32 gpu_count;
|
||||
|
||||
DisplayInfo display[6];
|
||||
int32 display_count;
|
||||
};
|
||||
|
||||
#endif
|
||||
61
platform/linux/Allocation.h
Normal file
61
platform/linux/Allocation.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* 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
|
||||
90
platform/linux/Library.h
Normal file
90
platform/linux/Library.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_LINUX_LIBRARY_H
|
||||
#define TOS_PLATFORM_LINUX_LIBRARY_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../utils/StringUtils.h"
|
||||
#include "UtilsLinux.h"
|
||||
#include "../Library.h"
|
||||
|
||||
// @todo Rename file to Library.cpp
|
||||
|
||||
inline
|
||||
bool library_load(Library* lib)
|
||||
{
|
||||
size_t path_length = strlen(lib->dir);
|
||||
|
||||
char dst[PATH_MAX];
|
||||
str_concat(
|
||||
lib->dir, path_length,
|
||||
lib->dst, strlen(lib->dst),
|
||||
dst
|
||||
);
|
||||
|
||||
#if DEBUG
|
||||
char src[PATH_MAX];
|
||||
size_t dst_len = strlen(dst);
|
||||
|
||||
memcpy(src, dst, dst_len + 1);
|
||||
|
||||
memcpy(dst + dst_len - (sizeof(".so") - 1), "_temp", sizeof("_temp") - 1);
|
||||
memcpy(dst + dst_len - (sizeof(".so") - 1) + (sizeof("_temp") - 1), ".so", sizeof(".so"));
|
||||
|
||||
lib->last_load = last_modified(src);
|
||||
file_copy(src, dst);
|
||||
#endif
|
||||
|
||||
// Unload any previous instance of the library if it’s already loaded
|
||||
if (lib->handle) {
|
||||
dlclose(lib->handle);
|
||||
lib->handle = NULL;
|
||||
usleep(100000); // 100 ms
|
||||
}
|
||||
|
||||
// @question we might want RTLD_NOW?
|
||||
lib->handle = dlopen(dst, RTLD_LAZY);
|
||||
if (!lib->handle) {
|
||||
lib->is_valid = false;
|
||||
return lib->is_valid;
|
||||
}
|
||||
|
||||
lib->is_valid = true;
|
||||
for (int32_t c = 0; c < lib->function_count; ++c) {
|
||||
void* function = dlsym(lib->handle, lib->function_names[c]);
|
||||
if (function) {
|
||||
lib->functions[c] = function;
|
||||
} else {
|
||||
lib->is_valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
return lib->is_valid;
|
||||
}
|
||||
|
||||
inline
|
||||
void library_unload(Library* lib)
|
||||
{
|
||||
if (lib->handle) {
|
||||
dlclose(lib->handle);
|
||||
lib->handle = NULL;
|
||||
}
|
||||
|
||||
for (int32_t c = 0; c < lib->function_count; ++c) {
|
||||
lib->functions[c] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
102
platform/linux/Server.h
Normal file
102
platform/linux/Server.h
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_LINUX_SERVER_H
|
||||
#define TOS_PLATFORM_LINUX_SERVER_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../network/SocketConnection.h"
|
||||
#include "../../utils/EndianUtils.h"
|
||||
|
||||
// WARNING: requires `sudo setcap cap_net_raw=eip /path/to/your_program`
|
||||
void socket_server_raw_create(const char* hostname, SocketConnection* con) {
|
||||
con->sd = socket(AF_INET6, SOCK_RAW, 255);
|
||||
|
||||
int32 flags;
|
||||
if ((flags = fcntl(con->sd, F_GETFL, 0)) < 0) {
|
||||
close(con->sd);
|
||||
con->sd = 0;
|
||||
}
|
||||
|
||||
if (fcntl(con->sd, F_SETFL, flags | O_NONBLOCK) < 0) {
|
||||
close(con->sd);
|
||||
con->sd = 0;
|
||||
}
|
||||
|
||||
con->addr.sin6_family = AF_INET6;
|
||||
con->addr.sin6_addr = in6addr_any;
|
||||
con->addr.sin6_port = SWAP_ENDIAN_BIG(con->port);
|
||||
|
||||
if (bind(con->sd, (sockaddr *) &con->addr, sizeof(con->addr)) < 0) {
|
||||
close(con->sd);
|
||||
con->sd = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// WARNING: requires `sudo setcap cap_net_raw=eip /path/to/your_program`
|
||||
void socket_server_udp_raw_create(const char* hostname, SocketConnection* con) {
|
||||
con->sd = socket(AF_INET6, SOCK_RAW, IPPROTO_UDP);
|
||||
|
||||
int32 flags;
|
||||
if ((flags = fcntl(con->sd, F_GETFL, 0)) < 0) {
|
||||
close(con->sd);
|
||||
con->sd = 0;
|
||||
}
|
||||
|
||||
if (fcntl(con->sd, F_SETFL, flags | O_NONBLOCK) < 0) {
|
||||
close(con->sd);
|
||||
con->sd = 0;
|
||||
}
|
||||
|
||||
con->addr.sin6_family = AF_INET6;
|
||||
con->addr.sin6_addr = in6addr_any;
|
||||
con->addr.sin6_port = SWAP_ENDIAN_BIG(con->port);
|
||||
|
||||
if (bind(con->sd, (sockaddr *) &con->addr, sizeof(con->addr)) < 0) {
|
||||
close(con->sd);
|
||||
con->sd = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void socket_server_udp_create(const char* hostname, SocketConnection* con) {
|
||||
con->sd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
||||
int32 flags;
|
||||
if ((flags = fcntl(con->sd, F_GETFL, 0)) < 0) {
|
||||
close(con->sd);
|
||||
con->sd = 0;
|
||||
}
|
||||
|
||||
if (fcntl(con->sd, F_SETFL, flags | O_NONBLOCK) < 0) {
|
||||
close(con->sd);
|
||||
con->sd = 0;
|
||||
}
|
||||
|
||||
con->addr.sin6_family = AF_INET6;
|
||||
con->addr.sin6_addr = in6addr_any;
|
||||
con->addr.sin6_port = SWAP_ENDIAN_BIG(con->port);
|
||||
|
||||
if (bind(con->sd, (sockaddr *) &con->addr, sizeof(con->addr)) < 0) {
|
||||
close(con->sd);
|
||||
con->sd = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -6,81 +6,36 @@
|
|||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_UTILS_SYSTEM_INFO_H
|
||||
#define TOS_UTILS_SYSTEM_INFO_H
|
||||
#ifndef TOS_PLATFORM_LINUX_SYSTEM_INFO_C
|
||||
#define TOS_PLATFORM_LINUX_SYSTEM_INFO_C
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "../stdlib/Types.h"
|
||||
#include "../stdlib/simd/SIMD_Helper.h"
|
||||
#include "StringUtils.h"
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../stdlib/simd/SIMD_Helper.h"
|
||||
#include "../../utils/StringUtils.h"
|
||||
#include "../SystemInfo.h"
|
||||
|
||||
#if _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
#include <d3d11.h>
|
||||
#include <dxgi.h>
|
||||
#include <wbemidl.h>
|
||||
#include <comdef.h>
|
||||
#include <winnls.h>
|
||||
#else
|
||||
#include <locale.h>
|
||||
#endif
|
||||
#include <locale.h>
|
||||
#include <cpuid.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#if __linux__ && (__i386__ || __x86_64__)
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
|
||||
// @todo implement for arm?
|
||||
// @todo implement for linux?
|
||||
|
||||
uint16 system_language_code()
|
||||
{
|
||||
#if _WIN32
|
||||
LANGID langID = GetUserDefaultUILanguage();
|
||||
wchar_t localeName[LOCALE_NAME_MAX_LENGTH];
|
||||
|
||||
if (!LCIDToLocaleName(langID, localeName, LOCALE_NAME_MAX_LENGTH, 0)) {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
char *localeName = setlocale(LC_ALL, "");
|
||||
#endif
|
||||
const char* localeName = setlocale(LC_ALL, "");
|
||||
|
||||
return (localeName[0] << 8) | localeName[1];
|
||||
}
|
||||
|
||||
uint16 system_country_code()
|
||||
{
|
||||
#if _WIN32
|
||||
LANGID langID = GetUserDefaultUILanguage();
|
||||
wchar_t localeName[LOCALE_NAME_MAX_LENGTH];
|
||||
|
||||
if (!LCIDToLocaleName(langID, localeName, LOCALE_NAME_MAX_LENGTH, 0)) {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
char *localeName = setlocale(LC_ALL, "");
|
||||
#endif
|
||||
const char* localeName = setlocale(LC_ALL, "");
|
||||
|
||||
return (localeName[3] << 8) | localeName[4];
|
||||
}
|
||||
|
||||
struct CpuCacheInfo {
|
||||
int32 level;
|
||||
int32 size;
|
||||
int32 ways;
|
||||
int32 partitions;
|
||||
int32 sets;
|
||||
int32 line_size;
|
||||
};
|
||||
|
||||
void cache_info_get(int32 level, CpuCacheInfo* cache) {
|
||||
uint32 eax, ebx, ecx, edx;
|
||||
int32 type;
|
||||
|
|
@ -92,20 +47,9 @@ void cache_info_get(int32 level, CpuCacheInfo* cache) {
|
|||
cache->sets = 0;
|
||||
cache->line_size = 0;
|
||||
|
||||
#if _WIN32
|
||||
int32 regs[4];
|
||||
__cpuidex(regs, 4, level);
|
||||
eax = regs[0];
|
||||
ebx = regs[1];
|
||||
ecx = regs[2];
|
||||
edx = regs[3];
|
||||
__cpuid_count(4, level, eax, ebx, ecx, edx);
|
||||
|
||||
type = (eax & 0x1F);
|
||||
#else
|
||||
__cpuid_count(4, level, eax, ebx, ecx, edx);
|
||||
|
||||
type = (eax & 0x1F);
|
||||
#endif
|
||||
type = (eax & 0x1F);
|
||||
|
||||
if (type == 0) {
|
||||
return;
|
||||
|
|
@ -118,12 +62,6 @@ void cache_info_get(int32 level, CpuCacheInfo* cache) {
|
|||
cache->size = cache->ways * cache->partitions * cache->line_size * cache->sets;
|
||||
}
|
||||
|
||||
// @todo add vendor name
|
||||
struct MainboardInfo {
|
||||
char name[64];
|
||||
char serial_number[64];
|
||||
};
|
||||
|
||||
void mainboard_info_get(MainboardInfo* info) {
|
||||
info->name[63] = '\0';
|
||||
info->serial_number[63] = '\0';
|
||||
|
|
@ -253,12 +191,6 @@ void mainboard_info_get(MainboardInfo* info) {
|
|||
CoUninitialize();
|
||||
}
|
||||
|
||||
// @todo add ipv6
|
||||
struct NetworkInfo {
|
||||
char slot[64];
|
||||
byte mac[8];
|
||||
};
|
||||
|
||||
int network_info_get(NetworkInfo* info) {
|
||||
WSADATA wsaData;
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
||||
|
|
@ -312,23 +244,6 @@ int network_info_get(NetworkInfo* info) {
|
|||
return i;
|
||||
}
|
||||
|
||||
struct SIMDInfo {
|
||||
f32 sse;
|
||||
int32 avx256;
|
||||
int32 avx512;
|
||||
};
|
||||
|
||||
struct CpuInfo {
|
||||
char vendor[13];
|
||||
char brand[49];
|
||||
int32 model;
|
||||
int32 family;
|
||||
int32 mhz;
|
||||
CpuCacheInfo cache[4];
|
||||
int32 page_size;
|
||||
SIMDInfo simd;
|
||||
};
|
||||
|
||||
void cpu_info_get(CpuInfo* info) {
|
||||
int32 temp;
|
||||
info->simd.sse = (temp = max_sse_supported()) > 9 ? temp / 10.0f : temp;
|
||||
|
|
@ -380,42 +295,16 @@ void cpu_info_get(CpuInfo* info) {
|
|||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
struct OSInfo {
|
||||
char vendor[16];
|
||||
char name[64];
|
||||
int32 major;
|
||||
int32 minor;
|
||||
};
|
||||
|
||||
void os_info_get(OSInfo* info) {
|
||||
info->vendor[15] = '\0';
|
||||
info->name[63] = '\0';
|
||||
memcpy(info->vendor, "Linux", sizeof("Linux"));
|
||||
memcpy(info->name, "Linux", sizeof("Linux"));
|
||||
info->major = 0;
|
||||
info->minor = 0;
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
OSVERSIONINFOEXW version_info;
|
||||
memset(&version_info, 0, sizeof(OSVERSIONINFOEXW));
|
||||
version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
|
||||
NTSTATUS(WINAPI *RtlGetVersion)(OSVERSIONINFOEXW*) = (NTSTATUS(WINAPI *)(OSVERSIONINFOEXW*))GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlGetVersion");
|
||||
if (RtlGetVersion != nullptr) {
|
||||
RtlGetVersion(&version_info);
|
||||
}
|
||||
|
||||
memcpy(info->vendor, "Microsoft", sizeof("Microsoft"));
|
||||
memcpy(info->name, "Windows", sizeof("Windows"));
|
||||
info->major = version_info.dwMajorVersion;
|
||||
info->minor = version_info.dwMinorVersion;
|
||||
#else
|
||||
memcpy(info->vendor, "Linux", sizeof("Linux"));
|
||||
memcpy(info->name, "Linux", sizeof("Linux"));
|
||||
info->major = 0;
|
||||
info->minor = 0;
|
||||
#endif
|
||||
info->vendor[sizeof("Linux")] = '\0';
|
||||
info->name[sizeof("Linux")] = '\0';
|
||||
}
|
||||
|
||||
struct RamInfo {
|
||||
int32 memory;
|
||||
};
|
||||
|
||||
void ram_info_get(RamInfo* info) {
|
||||
MEMORYSTATUSEX statex;
|
||||
statex.dwLength = sizeof(statex);
|
||||
|
|
@ -423,11 +312,6 @@ void ram_info_get(RamInfo* info) {
|
|||
info->memory = (int) (statex.ullTotalPhys / (1024 * 1024));
|
||||
}
|
||||
|
||||
struct GpuInfo {
|
||||
char name[64];
|
||||
int32 vram;
|
||||
};
|
||||
|
||||
uint32 gpu_info_get(GpuInfo* info) {
|
||||
IDXGIFactory *pFactory = NULL;
|
||||
IDXGIAdapter *pAdapter = NULL;
|
||||
|
|
@ -459,13 +343,6 @@ uint32 gpu_info_get(GpuInfo* info) {
|
|||
return i;
|
||||
}
|
||||
|
||||
struct DisplayInfo {
|
||||
char name[64];
|
||||
int32 width;
|
||||
int32 height;
|
||||
int32 hz;
|
||||
};
|
||||
|
||||
uint32 display_info_get(DisplayInfo* info) {
|
||||
DISPLAY_DEVICEA device;
|
||||
DEVMODEA mode;
|
||||
|
|
@ -490,23 +367,6 @@ uint32 display_info_get(DisplayInfo* info) {
|
|||
return i;
|
||||
}
|
||||
|
||||
struct SystemInfo {
|
||||
OSInfo os;
|
||||
MainboardInfo mainboard;
|
||||
|
||||
NetworkInfo network[4];
|
||||
int32 network_count;
|
||||
|
||||
CpuInfo cpu;
|
||||
RamInfo ram;
|
||||
|
||||
GpuInfo gpu[2];
|
||||
int32 gpu_count;
|
||||
|
||||
DisplayInfo display[6];
|
||||
int32 display_count;
|
||||
};
|
||||
|
||||
void system_info_render(char* buf, const SystemInfo* info) {
|
||||
const char avx512[8][12] = {
|
||||
"AVX-512F",
|
||||
|
|
@ -521,7 +381,6 @@ void system_info_render(char* buf, const SystemInfo* info) {
|
|||
|
||||
sprintf_s(
|
||||
buf,
|
||||
4096,
|
||||
"OS:\n"
|
||||
"==============\n"
|
||||
"Vendor: %s\n" "Name: %s\n" "Major: %d\n" "Minor: %d\n"
|
||||
|
|
|
|||
14
platform/linux/Thread.h
Normal file
14
platform/linux/Thread.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* 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
|
||||
18
platform/linux/ThreadDefines.h
Normal file
18
platform/linux/ThreadDefines.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_LINUX_THREAD_DEFINES_H
|
||||
#define TOS_PLATFORM_LINUX_THREAD_DEFINES_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
typedef void* (*ThreadJobFunc)(void*);
|
||||
|
||||
#define THREAD_RETURN void*
|
||||
|
||||
#endif
|
||||
|
|
@ -16,12 +16,14 @@
|
|||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/limits.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../utils/Utils.h"
|
||||
#include "../../utils/TestUtils.h"
|
||||
#include "../../memory/RingMemory.h"
|
||||
|
||||
#ifndef MAX_PATH
|
||||
#define MAX_PATH PATH_MAX
|
||||
|
|
@ -32,7 +34,6 @@ int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...) {
|
|||
va_list args;
|
||||
|
||||
if (buffer == NULL || format == NULL || sizeOfBuffer == 0) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -44,7 +45,6 @@ int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...) {
|
|||
|
||||
if (result >= 0 && (size_t)result >= sizeOfBuffer) {
|
||||
buffer[sizeOfBuffer - 1] = '\0';
|
||||
errno = 80;
|
||||
return 80;
|
||||
}
|
||||
|
||||
|
|
@ -52,37 +52,41 @@ int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...) {
|
|||
return result;
|
||||
}
|
||||
|
||||
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 = readlink("/proc/self/exe", self_path, MAX_PATH - 1);
|
||||
if (self_path_length == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char* temp = rel;
|
||||
if (temp[0] == '.' && temp[1] == '/') {
|
||||
temp += 2;
|
||||
}
|
||||
|
||||
char self_path[MAX_PATH];
|
||||
ssize_t count = readlink("/proc/self/exe", self_path, MAX_PATH - 1);
|
||||
if (count == -1) {
|
||||
return;
|
||||
}
|
||||
self_path[count] = '\0';
|
||||
|
||||
char* last = strrchr(self_path, '/');
|
||||
if (last != NULL) {
|
||||
*(last + 1) = '\0';
|
||||
char* last = self_path + self_path_length;
|
||||
while (*last != '/' && self_path_length > 0) {
|
||||
--last;
|
||||
--self_path_length;
|
||||
}
|
||||
|
||||
snprintf(path, MAX_PATH, "%s%s", self_path, temp);
|
||||
++self_path_length;
|
||||
|
||||
memcpy(path, self_path, self_path_length);
|
||||
strcpy(path + self_path_length, temp);
|
||||
}
|
||||
|
||||
// @todo implement relative path support, similar to UtilsWin32
|
||||
inline
|
||||
uint64 file_size(const char* filename) {
|
||||
struct stat st;
|
||||
if (stat(filename, &st) != 0) {
|
||||
struct stat buffer;
|
||||
if (stat(filename, &buffer) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return st.st_size;
|
||||
return buffer.st_size;
|
||||
}
|
||||
|
||||
inline
|
||||
|
|
@ -95,131 +99,171 @@ uint64 last_modified(const char* filename)
|
|||
}
|
||||
|
||||
inline
|
||||
void file_read(const char* filename, FileBody* file, RingMemory* ring = NULL)
|
||||
{
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
fseek(fp, 0, SEEK_END);
|
||||
int32 get_append_handle(const char* path) {
|
||||
int32 fp;
|
||||
if (*path == '.') {
|
||||
char full_path[MAX_PATH];
|
||||
relative_to_absolute(path, full_path);
|
||||
|
||||
file->size = ftell(fp);
|
||||
rewind(fp);
|
||||
|
||||
if (ring != NULL) {
|
||||
file->content = ring_get_memory(ring, file->size);
|
||||
fp = open(full_path, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR);
|
||||
} else {
|
||||
fp = open(path, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR);
|
||||
}
|
||||
|
||||
fread(file->content, 1, file->size, fp);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
inline
|
||||
uint64_t file_read_struct(const char* filename, void* file, uint32 size) {
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
if (!fp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t read_bytes = fread(file, 1, size, fp);
|
||||
fclose(fp);
|
||||
|
||||
return read_bytes;
|
||||
}
|
||||
|
||||
inline
|
||||
bool file_write(const char* filename, const FileBody* file) {
|
||||
FILE *fp = fopen(filename, "wb");
|
||||
if (!fp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t written = fwrite(file->content, 1, file->size, fp);
|
||||
fclose(fp);
|
||||
|
||||
return written == file->size;
|
||||
}
|
||||
|
||||
inline
|
||||
bool file_write_struct(const char* filename, const void* file, uint32_t size) {
|
||||
FILE *fp = fopen(filename, "wb");
|
||||
if (!fp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t written = fwrite(file, 1, size, fp);
|
||||
fclose(fp);
|
||||
|
||||
return written == size;
|
||||
}
|
||||
|
||||
inline
|
||||
void file_copy(const char* src, const char* dst) {
|
||||
FILE *src_fp = fopen(src, "rb");
|
||||
FILE *dst_fp = fopen(dst, "wb");
|
||||
|
||||
if (!src_fp || !dst_fp) {
|
||||
if (src_fp) fclose(src_fp);
|
||||
if (dst_fp) fclose(dst_fp);
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[4096];
|
||||
size_t bytes;
|
||||
while ((bytes = fread(buffer, 1, sizeof(buffer), src_fp)) > 0) {
|
||||
fwrite(buffer, 1, bytes, dst_fp);
|
||||
}
|
||||
|
||||
fclose(src_fp);
|
||||
fclose(dst_fp);
|
||||
}
|
||||
|
||||
inline
|
||||
FILE* get_append_handle(const char* filename) {
|
||||
FILE *fp = fopen(filename, "ab");
|
||||
if (!fp) {
|
||||
return NULL;
|
||||
}
|
||||
return fp;
|
||||
}
|
||||
|
||||
inline bool file_append(const char* filename, const char* file) {
|
||||
FILE *fp = get_append_handle(filename);
|
||||
if (!fp) {
|
||||
return false;
|
||||
inline
|
||||
bool file_exists(const char* path) {
|
||||
struct stat buffer;
|
||||
const char* full_path = path;
|
||||
char abs_path[MAX_PATH];
|
||||
|
||||
if (*path == '.') {
|
||||
relative_to_absolute(path, abs_path);
|
||||
full_path = abs_path;
|
||||
}
|
||||
|
||||
size_t length = strlen(file);
|
||||
ASSERT_SIMPLE(length < INT32_MAX);
|
||||
size_t written = fwrite(file, 1, length, fp);
|
||||
fclose(fp);
|
||||
|
||||
return written == length;
|
||||
return stat(full_path, &buffer) == 0;
|
||||
}
|
||||
|
||||
inline bool file_append(FILE* fp, const char* file) {
|
||||
if (!fp) {
|
||||
inline
|
||||
bool file_copy(const char* src, const char* dst) {
|
||||
char src_full_path[MAX_PATH];
|
||||
char dst_full_path[MAX_PATH];
|
||||
|
||||
if (*src == '.') {
|
||||
relative_to_absolute(src, src_full_path);
|
||||
src = src_full_path;
|
||||
}
|
||||
|
||||
if (*dst == '.') {
|
||||
relative_to_absolute(dst, dst_full_path);
|
||||
dst = dst_full_path;
|
||||
}
|
||||
|
||||
int32 src_fd = open(src, O_RDONLY);
|
||||
if (src_fd < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t length = strlen(file);
|
||||
ASSERT_SIMPLE(length < INT32_MAX);
|
||||
size_t written = fwrite(file, 1, length, fp);
|
||||
fclose(fp);
|
||||
int32 dst_fd = open(dst, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
if (dst_fd < 0) {
|
||||
close(src_fd);
|
||||
|
||||
return written == length;
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[8192];
|
||||
ssize_t bytes_read, bytes_written;
|
||||
bool success = true;
|
||||
|
||||
while ((bytes_read = read(src_fd, buffer, sizeof(buffer))) > 0) {
|
||||
bytes_written = write(dst_fd, buffer, bytes_read);
|
||||
if (bytes_written != bytes_read) {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bytes_read < 0) {
|
||||
success = false;
|
||||
}
|
||||
|
||||
close(src_fd);
|
||||
close(dst_fd);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
inline bool file_append(const char* filename, const FileBody* file) {
|
||||
FILE *fp = get_append_handle(filename);
|
||||
if (!fp) {
|
||||
inline
|
||||
void file_read(const char* path, FileBody* file, RingMemory* ring) {
|
||||
char full_path[MAX_PATH];
|
||||
const char* abs_path = path;
|
||||
|
||||
if (*path == '.') {
|
||||
relative_to_absolute(path, full_path);
|
||||
abs_path = full_path;
|
||||
}
|
||||
|
||||
int32 fp = open(abs_path, O_RDONLY);
|
||||
if (fp < 0) {
|
||||
file->size = 0;
|
||||
file->content = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
struct stat file_stat;
|
||||
if (fstat(fp, &file_stat) == -1) {
|
||||
close(fp);
|
||||
file->size = 0;
|
||||
file->content = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (file_stat.st_size > MAX_INT32) {
|
||||
close(fp);
|
||||
file->size = 0;
|
||||
file->content = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (ring != NULL) {
|
||||
file->content = ring_get_memory(ring, file_stat.st_size);
|
||||
}
|
||||
|
||||
ssize_t bytes_read = read(fp, file->content, file_stat.st_size);
|
||||
if (bytes_read != file_stat.st_size) {
|
||||
close(fp);
|
||||
file->content = NULL;
|
||||
file->size = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
file->content[bytes_read] = '\0';
|
||||
file->size = bytes_read;
|
||||
|
||||
close(fp);
|
||||
}
|
||||
|
||||
inline
|
||||
bool file_write(const char* path, const FileBody* file) {
|
||||
int32 fd;
|
||||
char full_path[PATH_MAX];
|
||||
|
||||
if (*path == '.') {
|
||||
relative_to_absolute(path, full_path);
|
||||
path = full_path;
|
||||
}
|
||||
|
||||
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
if (fd < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t length = file->size;
|
||||
ASSERT_SIMPLE(length < INT32_MAX);
|
||||
size_t written = fwrite(file->content, 1, length, fp);
|
||||
fclose(fp);
|
||||
ASSERT_SIMPLE(file->size < MAX_INT32);
|
||||
|
||||
return written == length;
|
||||
ssize_t written = write(fd, file->content, file->size);
|
||||
if (written < 0 || (size_t) written != file->size) {
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (close(fd) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline
|
||||
void close_handle(int32 fp)
|
||||
{
|
||||
close(fp);
|
||||
}
|
||||
|
||||
inline
|
||||
|
|
@ -232,14 +276,4 @@ void self_path(char* path) {
|
|||
}
|
||||
}
|
||||
|
||||
inline
|
||||
void strncpy_s(char *dest, size_t destsz, const char *src, size_t count) {
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < count && i < destsz - 1 && src[i] != '\0'; ++i) {
|
||||
dest[i] = src[i];
|
||||
}
|
||||
|
||||
dest[i] = '\0';
|
||||
}
|
||||
#endif
|
||||
56
platform/win32/Allocation.h
Normal file
56
platform/win32/Allocation.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* 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
|
||||
60
platform/win32/Client.h
Normal file
60
platform/win32/Client.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_WIN32_SERVER_H
|
||||
#define TOS_PLATFORM_WIN32_SERVER_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../network/SocketConnection.h"
|
||||
#include "../../utils/EndianUtils.h"
|
||||
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
|
||||
void socket_client_udp_create(SocketConnection* con, uint16 port = 0) {
|
||||
WSADATA wsaData;
|
||||
|
||||
// Initialize Winsock
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create socket
|
||||
con->sd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (con->sd == INVALID_SOCKET) {
|
||||
WSACleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
// Set socket to non-blocking mode
|
||||
u_long mode = 1;
|
||||
if (ioctlsocket(con->sd, FIONBIO, &mode) != NO_ERROR) {
|
||||
closesocket(con->sd);
|
||||
WSACleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
// Bind socket
|
||||
con->addr.sin6_family = AF_INET6;
|
||||
con->addr.sin6_addr = in6addr_any;
|
||||
con->addr.sin6_port = port; // 0 = OS decides the port
|
||||
|
||||
if (bind(con->sd, (struct sockaddr*) &con->addr, sizeof(con->addr)) == SOCKET_ERROR) {
|
||||
closesocket(con->sd);
|
||||
WSACleanup();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -16,22 +16,9 @@
|
|||
#include "../../stdlib/Types.h"
|
||||
#include "UtilsWin32.h"
|
||||
#include "../../utils/StringUtils.h"
|
||||
#include "../Library.h"
|
||||
|
||||
struct Library {
|
||||
HMODULE handle;
|
||||
bool is_valid;
|
||||
|
||||
char dir[MAX_PATH];
|
||||
char dst[64];
|
||||
|
||||
#if DEBUG
|
||||
uint64 last_load;
|
||||
#endif
|
||||
|
||||
int32 function_count;
|
||||
const char** function_names;
|
||||
void** functions;
|
||||
};
|
||||
// @todo Rename file to Library.cpp
|
||||
|
||||
inline
|
||||
bool library_load(Library* lib)
|
||||
|
|
|
|||
60
platform/win32/Server.h
Normal file
60
platform/win32/Server.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_WIN32_SERVER_H
|
||||
#define TOS_PLATFORM_WIN32_SERVER_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../network/SocketConnection.h"
|
||||
#include "../../utils/EndianUtils.h"
|
||||
|
||||
#pragma comment(lib, "Ws2_32.lib")
|
||||
|
||||
void socket_server_udp_create(const char* hostname, SocketConnection* con) {
|
||||
WSADATA wsaData;
|
||||
|
||||
// Initialize Winsock
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create socket
|
||||
con->sd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (con->sd == INVALID_SOCKET) {
|
||||
WSACleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
// Set socket to non-blocking mode
|
||||
u_long mode = 1;
|
||||
if (ioctlsocket(con->sd, FIONBIO, &mode) != NO_ERROR) {
|
||||
closesocket(con->sd);
|
||||
WSACleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
// Bind socket
|
||||
con->addr.sin6_family = AF_INET6;
|
||||
con->addr.sin6_addr = in6addr_any;
|
||||
con->addr.sin6_port = SWAP_ENDIAN_BIG(con->port);
|
||||
|
||||
if (bind(con->sd, (struct sockaddr *) &con->addr, sizeof(con->addr)) == SOCKET_ERROR) {
|
||||
closesocket(con->sd);
|
||||
WSACleanup();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -6,14 +6,15 @@
|
|||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_UTILS_SYSTEM_INFO_H
|
||||
#define TOS_UTILS_SYSTEM_INFO_H
|
||||
#ifndef TOS_PLATFORM_WIN32_SYSTEM_INFO_C
|
||||
#define TOS_PLATFORM_WIN32_SYSTEM_INFO_C
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "../../stdlib/Types.h"
|
||||
#include "../../stdlib/simd/SIMD_Helper.h"
|
||||
#include "../../utils/StringUtils.h"
|
||||
#include "../SystemInfo.h"
|
||||
|
||||
#include <psapi.h>
|
||||
#include <winsock2.h>
|
||||
|
|
@ -93,15 +94,6 @@ uint16 system_country_code()
|
|||
return (local_name[3] << 8) | local_name[4];
|
||||
}
|
||||
|
||||
struct CpuCacheInfo {
|
||||
int32 level;
|
||||
int32 size;
|
||||
int32 ways;
|
||||
int32 partitions;
|
||||
int32 sets;
|
||||
int32 line_size;
|
||||
};
|
||||
|
||||
void cache_info_get(int32 level, CpuCacheInfo* cache) {
|
||||
uint32 eax, ebx, ecx, edx;
|
||||
int32 type;
|
||||
|
|
@ -133,12 +125,6 @@ void cache_info_get(int32 level, CpuCacheInfo* cache) {
|
|||
cache->size = cache->ways * cache->partitions * cache->line_size * cache->sets;
|
||||
}
|
||||
|
||||
// @todo add vendor name
|
||||
struct MainboardInfo {
|
||||
char name[64];
|
||||
char serial_number[64];
|
||||
};
|
||||
|
||||
void mainboard_info_get(MainboardInfo* info) {
|
||||
info->name[63] = '\0';
|
||||
info->serial_number[63] = '\0';
|
||||
|
|
@ -273,12 +259,6 @@ void mainboard_info_get(MainboardInfo* info) {
|
|||
CoUninitialize();
|
||||
}
|
||||
|
||||
// @todo add ipv6
|
||||
struct NetworkInfo {
|
||||
char slot[64];
|
||||
byte mac[8];
|
||||
};
|
||||
|
||||
int network_info_get(NetworkInfo* info) {
|
||||
WSADATA wsaData;
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
|
||||
|
|
@ -332,23 +312,6 @@ int network_info_get(NetworkInfo* info) {
|
|||
return i;
|
||||
}
|
||||
|
||||
struct SIMDInfo {
|
||||
f32 sse;
|
||||
int32 avx256;
|
||||
int32 avx512;
|
||||
};
|
||||
|
||||
struct CpuInfo {
|
||||
char vendor[13];
|
||||
char brand[49];
|
||||
int32 model;
|
||||
int32 family;
|
||||
int32 mhz;
|
||||
CpuCacheInfo cache[4];
|
||||
int32 page_size;
|
||||
SIMDInfo simd;
|
||||
};
|
||||
|
||||
void cpu_info_get(CpuInfo* info) {
|
||||
int32 temp;
|
||||
info->simd.sse = (temp = max_sse_supported()) > 9 ? temp / 10.0f : temp;
|
||||
|
|
@ -400,13 +363,6 @@ void cpu_info_get(CpuInfo* info) {
|
|||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
struct OSInfo {
|
||||
char vendor[16];
|
||||
char name[64];
|
||||
int32 major;
|
||||
int32 minor;
|
||||
};
|
||||
|
||||
void os_info_get(OSInfo* info) {
|
||||
info->vendor[15] = '\0';
|
||||
info->name[63] = '\0';
|
||||
|
|
@ -432,10 +388,6 @@ void os_info_get(OSInfo* info) {
|
|||
#endif
|
||||
}
|
||||
|
||||
struct RamInfo {
|
||||
int32 memory;
|
||||
};
|
||||
|
||||
void ram_info_get(RamInfo* info) {
|
||||
MEMORYSTATUSEX statex;
|
||||
statex.dwLength = sizeof(statex);
|
||||
|
|
@ -443,11 +395,6 @@ void ram_info_get(RamInfo* info) {
|
|||
info->memory = (int) (statex.ullTotalPhys / (1024 * 1024));
|
||||
}
|
||||
|
||||
struct GpuInfo {
|
||||
char name[64];
|
||||
int32 vram;
|
||||
};
|
||||
|
||||
uint32 gpu_info_get(GpuInfo* info) {
|
||||
IDXGIFactory *pFactory = NULL;
|
||||
IDXGIAdapter *pAdapter = NULL;
|
||||
|
|
@ -479,13 +426,6 @@ uint32 gpu_info_get(GpuInfo* info) {
|
|||
return i;
|
||||
}
|
||||
|
||||
struct DisplayInfo {
|
||||
char name[64];
|
||||
int32 width;
|
||||
int32 height;
|
||||
int32 hz;
|
||||
};
|
||||
|
||||
void display_info_get_primary(DisplayInfo* info) {
|
||||
DISPLAY_DEVICEA device;
|
||||
DEVMODEA mode;
|
||||
|
|
@ -537,23 +477,6 @@ uint32 display_info_get(DisplayInfo* info) {
|
|||
return i;
|
||||
}
|
||||
|
||||
struct SystemInfo {
|
||||
OSInfo os;
|
||||
MainboardInfo mainboard;
|
||||
|
||||
NetworkInfo network[4];
|
||||
int32 network_count;
|
||||
|
||||
CpuInfo cpu;
|
||||
RamInfo ram;
|
||||
|
||||
GpuInfo gpu[2];
|
||||
int32 gpu_count;
|
||||
|
||||
DisplayInfo display[6];
|
||||
int32 display_count;
|
||||
};
|
||||
|
||||
void system_info_render(char* buf, const SystemInfo* info) {
|
||||
const char avx512[8][12] = {
|
||||
"AVX-512F",
|
||||
|
|
@ -6,22 +6,15 @@
|
|||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_THREADS_OS_WRAPPER_H
|
||||
#define TOS_THREADS_OS_WRAPPER_H
|
||||
#ifndef TOS_PLATFORM_WIN32_THREAD_H
|
||||
#define TOS_PLATFORM_WIN32_THREAD_H
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "../stdlib/Types.h"
|
||||
#include "ThreadOSDefines.h"
|
||||
#include "ThreadDefines.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "ThreadJob.h"
|
||||
#include <windows.h>
|
||||
|
||||
void ms_to_timespec(timespec *ts, uint32 ms)
|
||||
{
|
||||
|
|
@ -29,12 +22,13 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return;
|
||||
}
|
||||
|
||||
// @todo replace time() with os specifc solution
|
||||
ts->tv_sec = (ms / 1000) + time(0);
|
||||
ts->tv_nsec = (ms % 1000) * 1000000;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
int pthread_create(pthread_t* thread, void*, ThreadJobFunc start_routine, void* arg)
|
||||
int32 pthread_create(pthread_t* thread, void*, ThreadJobFunc start_routine, void* arg)
|
||||
{
|
||||
if (thread == NULL || start_routine == NULL) {
|
||||
return 1;
|
||||
|
|
@ -48,7 +42,7 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pthread_join(pthread_t thread, void**)
|
||||
int32 pthread_join(pthread_t thread, void**)
|
||||
{
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
CloseHandle(thread);
|
||||
|
|
@ -56,14 +50,14 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pthread_detach(pthread_t thread)
|
||||
int32 pthread_detach(pthread_t thread)
|
||||
{
|
||||
CloseHandle(thread);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutex_init(pthread_mutex_t* mutex, pthread_mutexattr_t*)
|
||||
int32 pthread_mutex_init(pthread_mutex_t* mutex, pthread_mutexattr_t*)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return 1;
|
||||
|
|
@ -74,7 +68,7 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutex_destroy(pthread_mutex_t* mutex)
|
||||
int32 pthread_mutex_destroy(pthread_mutex_t* mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return 1;
|
||||
|
|
@ -85,7 +79,7 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutex_lock(pthread_mutex_t* mutex)
|
||||
int32 pthread_mutex_lock(pthread_mutex_t* mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return 1;
|
||||
|
|
@ -96,7 +90,7 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutex_unlock(pthread_mutex_t* mutex)
|
||||
int32 pthread_mutex_unlock(pthread_mutex_t* mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
return 1;
|
||||
|
|
@ -107,7 +101,7 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pthread_cond_init(pthread_cond_t* cond, pthread_condattr_t*)
|
||||
int32 pthread_cond_init(pthread_cond_t* cond, pthread_condattr_t*)
|
||||
{
|
||||
if (cond == NULL) {
|
||||
return 1;
|
||||
|
|
@ -118,7 +112,7 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pthread_cond_destroy(pthread_cond_t*)
|
||||
int32 pthread_cond_destroy(pthread_cond_t*)
|
||||
{
|
||||
/* Windows does not have a destroy for conditionals */
|
||||
return 0;
|
||||
|
|
@ -135,7 +129,7 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return t < 0 ? 1 : t;
|
||||
}
|
||||
|
||||
int pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* abstime)
|
||||
int32 pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t* mutex, const timespec* abstime)
|
||||
{
|
||||
if (cond == NULL || mutex == NULL) {
|
||||
return 1;
|
||||
|
|
@ -148,7 +142,7 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex)
|
||||
int32 pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex)
|
||||
{
|
||||
if (cond == NULL || mutex == NULL) {
|
||||
return 1;
|
||||
|
|
@ -157,7 +151,7 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return pthread_cond_timedwait(cond, mutex, NULL);
|
||||
}
|
||||
|
||||
int pthread_cond_signal(pthread_cond_t* cond)
|
||||
int32 pthread_cond_signal(pthread_cond_t* cond)
|
||||
{
|
||||
if (cond == NULL) {
|
||||
return 1;
|
||||
|
|
@ -168,7 +162,7 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pthread_cond_broadcast(pthread_cond_t* cond)
|
||||
int32 pthread_cond_broadcast(pthread_cond_t* cond)
|
||||
{
|
||||
if (cond == NULL) {
|
||||
return 1;
|
||||
|
|
@ -179,7 +173,7 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pthread_rwlock_init(pthread_rwlock_t* rwlock, const pthread_rwlockattr_t*)
|
||||
int32 pthread_rwlock_init(pthread_rwlock_t* rwlock, const pthread_rwlockattr_t*)
|
||||
{
|
||||
if (rwlock == NULL) {
|
||||
return 1;
|
||||
|
|
@ -191,12 +185,12 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pthread_rwlock_destroy(pthread_rwlock_t*)
|
||||
int32 pthread_rwlock_destroy(pthread_rwlock_t*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_rwlock_rdlock(pthread_rwlock_t* rwlock)
|
||||
int32 pthread_rwlock_rdlock(pthread_rwlock_t* rwlock)
|
||||
{
|
||||
if (rwlock == NULL) {
|
||||
return 1;
|
||||
|
|
@ -207,7 +201,7 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pthread_rwlock_tryrdlock(pthread_rwlock_t* rwlock)
|
||||
int32 pthread_rwlock_tryrdlock(pthread_rwlock_t* rwlock)
|
||||
{
|
||||
if (rwlock == NULL) {
|
||||
return 1;
|
||||
|
|
@ -216,7 +210,7 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return !TryAcquireSRWLockShared(&rwlock->lock);
|
||||
}
|
||||
|
||||
int pthread_rwlock_wrlock(pthread_rwlock_t* rwlock)
|
||||
int32 pthread_rwlock_wrlock(pthread_rwlock_t* rwlock)
|
||||
{
|
||||
if (rwlock == NULL) {
|
||||
return 1;
|
||||
|
|
@ -228,7 +222,7 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
|
||||
int32 pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
|
||||
{
|
||||
if (rwlock == NULL) {
|
||||
return 1;
|
||||
|
|
@ -242,7 +236,7 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int pthread_rwlock_unlock(pthread_rwlock_t* rwlock)
|
||||
int32 pthread_rwlock_unlock(pthread_rwlock_t* rwlock)
|
||||
{
|
||||
if (rwlock == NULL) {
|
||||
return 1;
|
||||
|
|
@ -258,7 +252,7 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned int pcthread_get_num_procs()
|
||||
uint32 pcthread_get_num_procs()
|
||||
{
|
||||
SYSTEM_INFO sysinfo;
|
||||
GetSystemInfo(&sysinfo);
|
||||
|
|
@ -268,9 +262,9 @@ void ms_to_timespec(timespec *ts, uint32 ms)
|
|||
|
||||
#define pthread_exit(a) {return (a);}
|
||||
#else
|
||||
unsigned int pcthread_get_num_procs()
|
||||
uint32 pcthread_get_num_procs()
|
||||
{
|
||||
return (unsigned int) sysconf(_SC_NPROCESSORS_ONLN);
|
||||
return (uint32) sysconf(_SC_NPROCESSORS_ONLN);
|
||||
}
|
||||
#endif
|
||||
|
||||
29
platform/win32/ThreadDefines.h
Normal file
29
platform/win32/ThreadDefines.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_PLATFORM_WIN32_THREAD_DEFINES_H
|
||||
#define TOS_PLATFORM_WIN32_THREAD_DEFINES_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
|
||||
|
|
@ -23,6 +23,7 @@
|
|||
#include "../../memory/RingMemory.h"
|
||||
|
||||
#define strtok_r strtok_s
|
||||
#define usleep Sleep
|
||||
|
||||
inline
|
||||
time_t system_time()
|
||||
|
|
@ -46,7 +47,8 @@ time_t system_time()
|
|||
inline void relative_to_absolute(const char* rel, char* path)
|
||||
{
|
||||
char self_path[MAX_PATH];
|
||||
if (GetModuleFileNameA(NULL, self_path, MAX_PATH) == 0) {
|
||||
int32 self_path_length = GetModuleFileNameA(NULL, self_path, MAX_PATH);
|
||||
if (self_path_length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -55,14 +57,19 @@ inline void relative_to_absolute(const char* rel, char* path)
|
|||
temp += 2;
|
||||
}
|
||||
|
||||
char* last = strrchr(self_path, '\\');
|
||||
if (last != NULL) {
|
||||
*(last + 1) = '\0';
|
||||
char* last = self_path + self_path_length;
|
||||
while (*last != '\\' && self_path_length > 0) {
|
||||
--last;
|
||||
--self_path_length;
|
||||
}
|
||||
|
||||
snprintf(path, MAX_PATH, "%s%s", self_path, temp);
|
||||
++self_path_length;
|
||||
|
||||
memcpy(path, self_path, self_path_length);
|
||||
strcpy(path + self_path_length, temp);
|
||||
}
|
||||
|
||||
// @todo Move file code to FileUtils.h
|
||||
inline uint64
|
||||
file_size(const char* path)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -336,7 +336,7 @@ void hashmap_insert(HashMap* hm, const char* key, byte* value) {
|
|||
}
|
||||
}
|
||||
|
||||
HashEntry* hashmap_get_entry(HashMap* hm, const char* key) {
|
||||
HashEntry* hashmap_get_entry(const HashMap* hm, const char* key) {
|
||||
// @performance Do we really want to do this check every time?
|
||||
if (hm->buf.count == 0) {
|
||||
return NULL;
|
||||
|
|
@ -358,7 +358,7 @@ HashEntry* hashmap_get_entry(HashMap* hm, const char* key) {
|
|||
|
||||
// This function only saves one step (omission of the hash function)
|
||||
// The reason for this is in some cases we can use compile time hashing
|
||||
HashEntry* hashmap_get_entry(HashMap* hm, const char* key, uint64 index) {
|
||||
HashEntry* hashmap_get_entry(const HashMap* hm, const char* key, uint64 index) {
|
||||
if (hm->buf.count == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,18 +19,16 @@
|
|||
|
||||
#include "Types.h"
|
||||
|
||||
/*
|
||||
inline f32 sqrt(f32 a) { return _mm_cvtss_f32(_mm_sqrt_ss(_mm_set_ss(a))); }
|
||||
inline f64 sqrt(f64 a)
|
||||
inline f32 oms_sqrt(f32 a) { return _mm_cvtss_f32(_mm_sqrt_ss(_mm_set_ss(a))); }
|
||||
inline f64 oms_sqrt(f64 a)
|
||||
{
|
||||
__m128d temp =_mm_set_sd(a);
|
||||
|
||||
return _mm_cvtsd_f64(_mm_sqrt_sd(temp, temp));
|
||||
}
|
||||
*/
|
||||
|
||||
inline f32 rsqrt(f32 a) { return _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(a))); }
|
||||
inline f64 rsqrt(f64 a)
|
||||
inline f32 oms_rsqrt(f32 a) { return _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(a))); }
|
||||
inline f64 oms_rsqrt(f64 a)
|
||||
{
|
||||
__m128d temp =_mm_set_sd(a);
|
||||
|
||||
|
|
@ -42,7 +40,7 @@ inline f64 rsqrt(f64 a)
|
|||
);
|
||||
}
|
||||
|
||||
inline f32 round(f32 a)
|
||||
inline f32 oms_round(f32 a)
|
||||
{
|
||||
return _mm_cvtss_f32(
|
||||
_mm_round_ss(_mm_setzero_ps(), _mm_set_ss(a), (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC)));
|
||||
|
|
@ -50,9 +48,9 @@ inline f32 round(f32 a)
|
|||
|
||||
inline uint32 round_to_int(f32 a) { return (uint32) _mm_cvtss_si32(_mm_set_ss(a)); }
|
||||
|
||||
inline f32 floor(f32 a) { return _mm_cvtss_f32(_mm_floor_ss(_mm_setzero_ps(), _mm_set_ss(a))); }
|
||||
inline f32 oms_floor(f32 a) { return _mm_cvtss_f32(_mm_floor_ss(_mm_setzero_ps(), _mm_set_ss(a))); }
|
||||
|
||||
inline f32 ceil(f32 a) { return _mm_cvtss_f32(_mm_ceil_ss(_mm_setzero_ps(), _mm_set_ss(a))); }
|
||||
inline f32 oms_ceil(f32 a) { return _mm_cvtss_f32(_mm_ceil_ss(_mm_setzero_ps(), _mm_set_ss(a))); }
|
||||
|
||||
inline uint32 hash(uint64 a, uint64 b = 0)
|
||||
{
|
||||
|
|
@ -72,7 +70,7 @@ inline void atomic_increment(int32* a, int32 b) {
|
|||
}
|
||||
|
||||
inline void atomic_increment(int64* a, int64 b) {
|
||||
_aadd_i64(a, b);
|
||||
_aadd_i64((long long int *) a, (long long int) b);
|
||||
}
|
||||
|
||||
inline void atomic_decrement(int32* a, int32 b) {
|
||||
|
|
@ -80,7 +78,7 @@ inline void atomic_decrement(int32* a, int32 b) {
|
|||
}
|
||||
|
||||
inline void atomic_decrement(int64* a, int64 b) {
|
||||
_aadd_i64(a, -b);
|
||||
_aadd_i64((long long int *) a, (long long int) -b);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -11,6 +11,14 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define PACKED_STRUCT __pragma(pack(push, 1))
|
||||
#define UNPACKED_STRUCT __pragma(pack(pop))
|
||||
#else
|
||||
#define PACKED_STRUCT __attribute__((__packed__))
|
||||
#define UNPACKED_STRUCT
|
||||
#endif
|
||||
|
||||
typedef int8_t int8;
|
||||
typedef int16_t int16;
|
||||
typedef int32_t int32;
|
||||
|
|
@ -158,7 +166,17 @@ struct v3_f32 {
|
|||
struct v4_f32 {
|
||||
union {
|
||||
struct {
|
||||
f32 x, y, z, w;
|
||||
f32 x, y;
|
||||
|
||||
union {
|
||||
struct {
|
||||
f32 z, w;
|
||||
};
|
||||
|
||||
struct {
|
||||
f32 width, height;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
struct {
|
||||
|
|
@ -169,10 +187,6 @@ struct v4_f32 {
|
|||
f32 r, g, b, a;
|
||||
};
|
||||
|
||||
struct {
|
||||
f32 x, y, width, height;
|
||||
};
|
||||
|
||||
f32 vec[4];
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -18,6 +18,13 @@
|
|||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
enum SIMDVersion {
|
||||
SIMD_VERSION_NONE,
|
||||
SIMD_VERSION_128,
|
||||
SIMD_VERSION_256,
|
||||
SIMD_VERSION_512,
|
||||
};
|
||||
|
||||
// @todo implement for arm?
|
||||
|
||||
inline int32 max_sse_supported()
|
||||
|
|
|
|||
|
|
@ -12,14 +12,14 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#if _WIN32
|
||||
#include "../platform/win32/ThreadDefines.h"
|
||||
#include "../platform/win32/Thread.h"
|
||||
#elif __linux__
|
||||
#include "../platform/linux/ThreadDefines.h"
|
||||
#include "../platform/linux/Thread.h"
|
||||
#endif
|
||||
|
||||
#include "ThreadOSWrapper.h"
|
||||
#include "ThreadJob.h"
|
||||
#include "ThreadPool.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,11 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ThreadOSDefines.h"
|
||||
#if _WIN32
|
||||
#include "../platform/win32/ThreadDefines.h"
|
||||
#elif __linux__
|
||||
#include "../platform/linux/ThreadDefines.h"
|
||||
#endif
|
||||
|
||||
struct job_t {
|
||||
ThreadJobFunc func;
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
/**
|
||||
* Jingga
|
||||
*
|
||||
* @copyright Jingga
|
||||
* @license OMS License 2.0
|
||||
* @version 1.0.0
|
||||
* @link https://jingga.app
|
||||
*/
|
||||
#ifndef TOS_THREADS_OS_DEFINES_H
|
||||
#define TOS_THREADS_OS_DEFINES_H
|
||||
|
||||
#if _WIN32
|
||||
#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;
|
||||
};
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
typedef void * (*ThreadJobFunc)(void*);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -13,15 +13,19 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include "../platform/win32/Thread.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include "../platform/linux/Thread.h"
|
||||
#endif
|
||||
|
||||
#include "../stdlib/Types.h"
|
||||
#include "ThreadJob.h"
|
||||
#include "ThreadOSWrapper.h"
|
||||
|
||||
#if _WIN32
|
||||
|
||||
#elif __linux__
|
||||
#include "../platform/linux/Thread.h"
|
||||
#endif
|
||||
|
||||
struct ThreadPool {
|
||||
ThreadJob *work_first;
|
||||
|
|
|
|||
124
ui/UITheme.h
124
ui/UITheme.h
|
|
@ -4,6 +4,7 @@
|
|||
#include "../stdlib/Types.h"
|
||||
#include "../memory/RingMemory.h"
|
||||
#include "../utils/EndianUtils.h"
|
||||
#include "../utils/StringUtils.h"
|
||||
#include "../stdlib/HashMap.h"
|
||||
#include "../font/Font.h"
|
||||
|
||||
|
|
@ -126,9 +127,7 @@ void theme_from_file_txt(
|
|||
int32 temp_group_count = 0;
|
||||
while (*pos != '\0') {
|
||||
// Skip all white spaces
|
||||
while (*pos == ' ' || *pos == '\t' || *pos == '\n') {
|
||||
++pos;
|
||||
}
|
||||
char_skip_empty(&pos);
|
||||
|
||||
// Is group name
|
||||
if (*pos == '#' || *pos == '.') {
|
||||
|
|
@ -136,9 +135,7 @@ void theme_from_file_txt(
|
|||
}
|
||||
|
||||
// Go to the end of the line
|
||||
while (*pos != '\n' && *pos != '\0') {
|
||||
++pos;
|
||||
}
|
||||
char_move_to(&pos, '\n');
|
||||
|
||||
// Go to next line
|
||||
if (*pos != '\0') {
|
||||
|
|
@ -157,9 +154,7 @@ void theme_from_file_txt(
|
|||
pos += 8; // move past version
|
||||
|
||||
while (*pos != '\0') {
|
||||
while (*pos == ' ' || *pos == '\t') {
|
||||
++pos;
|
||||
}
|
||||
char_skip_empty(&pos);
|
||||
|
||||
if (*pos == '\n') {
|
||||
++pos;
|
||||
|
|
@ -178,14 +173,7 @@ void theme_from_file_txt(
|
|||
last_token_newline = false;
|
||||
|
||||
if (!block_open) {
|
||||
int32 i = 0;
|
||||
while (*pos != '\0' && *pos != ' ' && *pos != '\n' && i < 31) {
|
||||
block_name[i] = *pos;
|
||||
++pos;
|
||||
++i;
|
||||
}
|
||||
|
||||
block_name[i] = '\0';
|
||||
char_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 == '.') {
|
||||
|
|
@ -210,19 +198,10 @@ void theme_from_file_txt(
|
|||
continue;
|
||||
}
|
||||
|
||||
int32 i = 0;
|
||||
while (*pos != '\0' && *pos != ' ' && *pos != ':' && *pos != '\n' && i < 31) {
|
||||
attribute_name[i] = *pos;
|
||||
++pos;
|
||||
++i;
|
||||
}
|
||||
|
||||
attribute_name[i] = '\0';
|
||||
char_copy_move_until(&pos, attribute_name, " :\n", sizeof(" :\n") - 1);
|
||||
|
||||
// Skip any white spaces or other delimeters
|
||||
while (*pos == ' ' || *pos == '\t' || *pos == ':') {
|
||||
++pos;
|
||||
}
|
||||
char_skip_list(&pos, " \t:", sizeof(" \t:") - 1);
|
||||
|
||||
ASSERT_SIMPLE((*pos != '\0' && *pos != '\n'));
|
||||
|
||||
|
|
@ -232,12 +211,8 @@ void theme_from_file_txt(
|
|||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_TYPE;
|
||||
|
||||
char str[32];
|
||||
char* temp = str;
|
||||
while (*pos != '\n' && *pos != '\0') {
|
||||
*temp++ = *pos++;
|
||||
}
|
||||
char_copy_move_until(&pos, str, '\n');
|
||||
|
||||
*temp = '\0';
|
||||
for (int32 j = 0; j < UI_ELEMENT_TYPE_SIZE; ++j) {
|
||||
if (strcmp(str, ui_element_type_to_string_const((UIElementType) j)) == 0) {
|
||||
|
||||
|
|
@ -250,22 +225,12 @@ 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* temp = attribute.value_str;
|
||||
while (*pos != '\n' && *pos != '\0') {
|
||||
*temp++ = *pos++;
|
||||
}
|
||||
|
||||
*temp = '\0';
|
||||
char_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 '#'
|
||||
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_FONT_COLOR;
|
||||
uint32 value = (uint32) strtoul(pos, &pos, 16);
|
||||
|
||||
attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f;
|
||||
hexstr_to_rgba(&attribute.value_v4_f32, pos);
|
||||
} else if (strcmp(ui_attribute_type_to_string_const(UI_ATTRIBUTE_TYPE_FONT_SIZE), attribute_name) == 0) {
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_FONT_SIZE;
|
||||
attribute.value_float = strtof(pos, &pos);
|
||||
|
|
@ -288,21 +253,11 @@ void theme_from_file_txt(
|
|||
++pos; // Skip '#'
|
||||
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BACKGROUND_COLOR;
|
||||
uint32 value = (uint32) strtoul(pos, &pos, 16);
|
||||
|
||||
attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f;
|
||||
hexstr_to_rgba(&attribute.value_v4_f32, pos);
|
||||
} 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;
|
||||
|
||||
i = 0;
|
||||
while (*pos != '\0' && *pos != '\n') {
|
||||
attribute.value_str[i] = *pos++;
|
||||
}
|
||||
|
||||
attribute.value_str[i] = '\0';
|
||||
char_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));
|
||||
|
|
@ -319,12 +274,7 @@ void theme_from_file_txt(
|
|||
++pos; // Skip '#'
|
||||
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_COLOR;
|
||||
uint32 value = (uint32) strtoul(pos, &pos, 16);
|
||||
|
||||
attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f;
|
||||
hexstr_to_rgba(&attribute.value_v4_f32, pos);
|
||||
} else if (strcmp(ui_attribute_type_to_string_const(UI_ATTRIBUTE_TYPE_BORDER_WIDTH), attribute_name) == 0) {
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_WIDTH;
|
||||
attribute.value_int = strtoul(pos, &pos, 10);
|
||||
|
|
@ -332,12 +282,7 @@ void theme_from_file_txt(
|
|||
++pos; // Skip '#'
|
||||
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_TOP_COLOR;
|
||||
uint32 value = (uint32) strtoul(pos, &pos, 16);
|
||||
|
||||
attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f;
|
||||
hexstr_to_rgba(&attribute.value_v4_f32, pos);
|
||||
} else if (strcmp(ui_attribute_type_to_string_const(UI_ATTRIBUTE_TYPE_BORDER_TOP_WIDTH), attribute_name) == 0) {
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_TOP_WIDTH;
|
||||
attribute.value_int = strtoul(pos, &pos, 10);
|
||||
|
|
@ -345,12 +290,7 @@ void theme_from_file_txt(
|
|||
++pos; // Skip '#'
|
||||
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_RIGHT_COLOR;
|
||||
uint32 value = (uint32) strtoul(pos, &pos, 16);
|
||||
|
||||
attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f;
|
||||
hexstr_to_rgba(&attribute.value_v4_f32, pos);
|
||||
} else if (strcmp(ui_attribute_type_to_string_const(UI_ATTRIBUTE_TYPE_BORDER_RIGHT_WIDTH), attribute_name) == 0) {
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_RIGHT_WIDTH;
|
||||
attribute.value_int = strtoul(pos, &pos, 10);
|
||||
|
|
@ -358,12 +298,7 @@ void theme_from_file_txt(
|
|||
++pos; // Skip '#'
|
||||
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_BOTTOM_COLOR;
|
||||
uint32 value = (uint32) strtoul(pos, &pos, 16);
|
||||
|
||||
attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f;
|
||||
hexstr_to_rgba(&attribute.value_v4_f32, pos);
|
||||
} else if (strcmp(ui_attribute_type_to_string_const(UI_ATTRIBUTE_TYPE_BORDER_BOTTOM_WIDTH), attribute_name) == 0) {
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_BOTTOM_WIDTH;
|
||||
attribute.value_int = strtoul(pos, &pos, 10);
|
||||
|
|
@ -371,12 +306,7 @@ void theme_from_file_txt(
|
|||
++pos; // Skip '#'
|
||||
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_LEFT_COLOR;
|
||||
uint32 value = (uint32) strtoul(pos, &pos, 16);
|
||||
|
||||
attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f;
|
||||
hexstr_to_rgba(&attribute.value_v4_f32, pos);
|
||||
} else if (strcmp(ui_attribute_type_to_string_const(UI_ATTRIBUTE_TYPE_BORDER_LEFT_WIDTH), attribute_name) == 0) {
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_BORDER_LEFT_WIDTH;
|
||||
attribute.value_int = strtoul(pos, &pos, 10);
|
||||
|
|
@ -399,12 +329,7 @@ void theme_from_file_txt(
|
|||
++pos; // Skip '#'
|
||||
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_SHADOW_INNER_COLOR;
|
||||
uint32 value = (uint32) strtoul(pos, &pos, 16);
|
||||
|
||||
attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f;
|
||||
hexstr_to_rgba(&attribute.value_v4_f32, pos);
|
||||
} else if (strcmp(ui_attribute_type_to_string_const(UI_ATTRIBUTE_TYPE_SHADOW_INNER_ANGLE), attribute_name) == 0) {
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_SHADOW_INNER_ANGLE;
|
||||
attribute.value_float = strtof(pos, &pos);
|
||||
|
|
@ -415,12 +340,7 @@ void theme_from_file_txt(
|
|||
++pos; // Skip '#'
|
||||
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_SHADOW_OUTER_COLOR;
|
||||
uint32 value = (uint32) strtoul(pos, &pos, 16);
|
||||
|
||||
attribute.value_v4_f32.r = (f32) ((value >> 24) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.g = (f32) ((value >> 16) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.b = (f32) ((value >> 8) & 0xFF) / 255.0f;
|
||||
attribute.value_v4_f32.a = (f32) (value & 0xFF) / 255.0f;
|
||||
hexstr_to_rgba(&attribute.value_v4_f32, pos);
|
||||
} else if (strcmp(ui_attribute_type_to_string_const(UI_ATTRIBUTE_TYPE_SHADOW_OUTER_ANGLE), attribute_name) == 0) {
|
||||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_SHADOW_OUTER_ANGLE;
|
||||
attribute.value_float = strtof(pos, &pos);
|
||||
|
|
@ -434,9 +354,7 @@ void theme_from_file_txt(
|
|||
attribute.attribute_id = UI_ATTRIBUTE_TYPE_TRANSITION_DURATION;
|
||||
attribute.value_float = strtof(pos, &pos);
|
||||
} else {
|
||||
while (*pos != '\n' && *pos != '\0') {
|
||||
++pos;
|
||||
}
|
||||
char_move_to(&pos, '\n');
|
||||
|
||||
continue;
|
||||
}
|
||||
|
|
@ -453,6 +371,8 @@ void theme_from_file_txt(
|
|||
data_offset += sizeof(attribute);
|
||||
++temp_group->attribute_size;
|
||||
}
|
||||
|
||||
char_move_to(&pos, '\n');
|
||||
}
|
||||
|
||||
// We still need to sort the last group
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef TOS_UTILS_BIT_H
|
||||
#define TOS_UTILS_BIT_H
|
||||
|
||||
#include <intrin.h>
|
||||
//#include <intrin.h>
|
||||
#include "../stdlib/Types.h"
|
||||
|
||||
// @todo Replace many of these functions with intrinsic functions
|
||||
|
|
|
|||
|
|
@ -435,7 +435,7 @@ void print_bytes(const void* ptr, size_t size)
|
|||
for (size_t i = 0; i < size; i++) {
|
||||
++count;
|
||||
if (count == 1) {
|
||||
printf("%03lld - %03lld: %02x ", i + 1, i + 8, bytePtr[i]);
|
||||
printf("%03zd - %03zd: %02x ", i + 1, i + 8, bytePtr[i]);
|
||||
} else if (count < 8) {
|
||||
printf("%02x ", bytePtr[i]);
|
||||
} else {
|
||||
|
|
@ -474,6 +474,177 @@ int32 chars_to_eol(const char* str)
|
|||
return offset;
|
||||
}
|
||||
|
||||
inline
|
||||
int32 chars_to(const char* str, char delim)
|
||||
{
|
||||
int32 offset = 0;
|
||||
while (*str != delim && *str++ != '\0') {
|
||||
++offset;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
inline
|
||||
void char_move_to(char** str, const char delim)
|
||||
{
|
||||
while (**str != delim && **str != '\0') {
|
||||
++(*str);
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
void char_move_past(char** str, const char delim)
|
||||
{
|
||||
while (**str != delim && **str != '\0') {
|
||||
++(*str);
|
||||
}
|
||||
|
||||
if (**str == delim) {
|
||||
++(*str);
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
void char_move_past_alpha_num(char** str)
|
||||
{
|
||||
while ((**str >= 48 && **str <= 57)
|
||||
|| (**str >= 65 && **str <= 90)
|
||||
|| (**str >= 97 && **str <= 122)
|
||||
|| **str == 45 || **str == 95
|
||||
) {
|
||||
++(*str);
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
bool str_is_comment(char* str)
|
||||
{
|
||||
return (*str == '/' && str[1] == '/') || (*str == '/' && str[1] == '*');
|
||||
}
|
||||
|
||||
inline
|
||||
void char_skip(char** str, const char delim)
|
||||
{
|
||||
while (**str == delim) {
|
||||
++(*str);
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
void char_skip_whitespace(char** str)
|
||||
{
|
||||
while (**str == ' ' || **str == '\t') {
|
||||
++(*str);
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
void char_skip_empty(char** str)
|
||||
{
|
||||
while (**str == ' ' || **str == '\t' || **str == '\n' || **str == '\r') {
|
||||
++(*str);
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
void char_skip_non_empty(char** str)
|
||||
{
|
||||
while (**str != ' ' && **str != '\t' && **str != '\n' && **str != '\0') {
|
||||
++(*str);
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
void char_skip_list(char** __restrict str, const char* __restrict delim, int32 len)
|
||||
{
|
||||
bool run = true;
|
||||
while (run && **str != '\0') {
|
||||
run = false;
|
||||
|
||||
for (int32 i = 0; i < len; ++i) {
|
||||
if (**str == delim[i]) {
|
||||
run = true;
|
||||
++(*str);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
void char_skip_until_list(char** __restrict str, const char* __restrict delim, int32 len)
|
||||
{
|
||||
while (**str != '\0') {
|
||||
for (int32 i = 0; i < len; ++i) {
|
||||
if (**str == delim[i]) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
++(*str);
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
void char_copy_until(const char* __restrict src, char* __restrict dest, char delim)
|
||||
{
|
||||
while (*src != delim && *src != '\0') {
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
||||
*dest = '\0';
|
||||
}
|
||||
|
||||
inline
|
||||
void char_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) {
|
||||
if (*src == delim[i]) {
|
||||
*dest = '\0';
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*dest++ = *src++;
|
||||
}
|
||||
|
||||
*dest = '\0';
|
||||
}
|
||||
|
||||
inline
|
||||
void char_copy_move_until(char** __restrict src, char* __restrict dest, char delim)
|
||||
{
|
||||
while (**src != delim) {
|
||||
*dest++ = **src;
|
||||
++(*src);
|
||||
}
|
||||
|
||||
*dest = '\0';
|
||||
}
|
||||
|
||||
inline
|
||||
void char_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) {
|
||||
if (**src == delim[i]) {
|
||||
*dest = '\0';
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*dest++ = **src;
|
||||
++(*src);
|
||||
}
|
||||
|
||||
*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)
|
||||
{
|
||||
|
|
@ -488,4 +659,18 @@ int32 strcpy_to_eol(const char* src, char* dst)
|
|||
return offset;
|
||||
}
|
||||
|
||||
inline
|
||||
void hexstr_to_rgba(v4_f32* rgba, const char* hex)
|
||||
{
|
||||
if (*hex == '#') {
|
||||
++hex;
|
||||
}
|
||||
|
||||
uint32 value = (uint32) strtoul(hex, NULL, 16);
|
||||
rgba->r = (f32) ((value >> 24) & 0xFF) / 255.0f;
|
||||
rgba->g = (f32) ((value >> 16) & 0xFF) / 255.0f;
|
||||
rgba->b = (f32) ((value >> 8) & 0xFF) / 255.0f;
|
||||
rgba->a = (f32) (value & 0xFF) / 255.0f;
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue
Block a user