Compare commits
74 Commits
da5fce383d
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
874b2b59f7
|
|||
|
dbff261805
|
|||
|
8363560fd2
|
|||
|
31863b0d31
|
|||
| 7f77d7ad52 | |||
|
df2c02a6a9
|
|||
|
f18d9d2b0e
|
|||
|
59f643b72c
|
|||
|
c01a6be4e5
|
|||
|
f93b543924
|
|||
|
72a86ddb41
|
|||
|
680d375b8c
|
|||
|
87d3c9087e
|
|||
|
0c33944721
|
|||
|
c1fb705f68
|
|||
|
be49003a8d
|
|||
|
7b7f088116
|
|||
|
d9957eead1
|
|||
|
cb10bd10b6
|
|||
|
a6577f520b
|
|||
| d54b4df4c2 | |||
| fcc7adfb22 | |||
|
c4cf8f532b
|
|||
|
8a360df98a
|
|||
|
3a84947750
|
|||
|
3e527f473b
|
|||
|
ab8301f475
|
|||
|
08cbfaeb71
|
|||
|
2f52bb3097
|
|||
|
a9612b2d57
|
|||
| 139b14ed71 | |||
|
c721839dfa
|
|||
| 24e9b472c3 | |||
| b09bdc6209 | |||
|
64a84e3a8d
|
|||
|
319bb441ed
|
|||
|
3eb8683ce3
|
|||
|
eb3c81cd04
|
|||
|
635e7b1c1e
|
|||
|
b8f47b8f61
|
|||
|
e20e537e97
|
|||
|
98095c907f
|
|||
|
8dc0ac1d3e
|
|||
|
222575b318
|
|||
| 9a46a802e0 | |||
| 628a6c5ade | |||
| c8dfcd857e | |||
|
394366480b
|
|||
|
8f148b6894
|
|||
|
7306c8fba4
|
|||
|
5cabf845b6
|
|||
|
1d70f3ae20
|
|||
|
5d48ed9c19
|
|||
|
1f97d81133
|
|||
|
1757fc4b96
|
|||
|
3b8c50a361
|
|||
|
2c67896cf2
|
|||
|
175f4da59b
|
|||
|
50efa6d8c0
|
|||
|
ab96fa3eeb
|
|||
|
55c1adba40
|
|||
|
dd316664f6
|
|||
|
e4c1bc0a1c
|
|||
|
187359f747
|
|||
|
249109f117
|
|||
|
d0d79d0551
|
|||
|
b1a805cea8
|
|||
| a6266a336b | |||
|
7a27309c5b
|
|||
|
a9f12532b4
|
|||
|
7d55b16c8e
|
|||
|
14321c71b8
|
|||
| d99da864da | |||
|
5f07239374
|
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
build/
|
||||
code/compile_commands.json
|
||||
code/.cache
|
||||
.vscode
|
||||
|
||||
BIN
assets/barrel.png
Normal file
|
After Width: | Height: | Size: 590 B |
BIN
assets/can.png
Normal file
|
After Width: | Height: | Size: 168 B |
BIN
assets/candle.png
Normal file
|
After Width: | Height: | Size: 176 B |
BIN
assets/clock.png
Normal file
|
After Width: | Height: | Size: 584 B |
BIN
assets/heart.png
Normal file
|
After Width: | Height: | Size: 289 B |
BIN
assets/house.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
assets/house_int.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
assets/hunter.png
Normal file
|
After Width: | Height: | Size: 730 B |
BIN
assets/log_pile.png
Normal file
|
After Width: | Height: | Size: 519 B |
BIN
assets/nightstand.png
Normal file
|
After Width: | Height: | Size: 244 B |
BIN
assets/npc_00.png
Normal file
|
After Width: | Height: | Size: 801 B |
BIN
assets/npc_back_base_0.png
Normal file
|
After Width: | Height: | Size: 650 B |
BIN
assets/npc_back_base_1.png
Normal file
|
After Width: | Height: | Size: 677 B |
BIN
assets/npc_back_face_1.png
Normal file
|
After Width: | Height: | Size: 232 B |
BIN
assets/npc_back_face_2.png
Normal file
|
After Width: | Height: | Size: 204 B |
BIN
assets/npc_back_hair_1.png
Normal file
|
After Width: | Height: | Size: 483 B |
BIN
assets/npc_back_hair_2.png
Normal file
|
After Width: | Height: | Size: 395 B |
BIN
assets/npc_back_hair_3.png
Normal file
|
After Width: | Height: | Size: 243 B |
BIN
assets/npc_back_hat_1.png
Normal file
|
After Width: | Height: | Size: 319 B |
BIN
assets/npc_back_hat_2.png
Normal file
|
After Width: | Height: | Size: 298 B |
BIN
assets/npc_back_shirt_0.png
Normal file
|
After Width: | Height: | Size: 560 B |
BIN
assets/npc_back_shirt_1.png
Normal file
|
After Width: | Height: | Size: 521 B |
BIN
assets/npc_back_shoes_0.png
Normal file
|
After Width: | Height: | Size: 274 B |
BIN
assets/npc_back_trousers_0.png
Normal file
|
After Width: | Height: | Size: 337 B |
BIN
assets/npc_back_trousers_1.png
Normal file
|
After Width: | Height: | Size: 325 B |
BIN
assets/npc_front_base_0.png
Normal file
|
After Width: | Height: | Size: 732 B |
BIN
assets/npc_front_base_1.png
Normal file
|
After Width: | Height: | Size: 737 B |
BIN
assets/npc_front_eyes_0.png
Normal file
|
After Width: | Height: | Size: 232 B |
BIN
assets/npc_front_eyes_1.png
Normal file
|
After Width: | Height: | Size: 207 B |
BIN
assets/npc_front_eyes_2.png
Normal file
|
After Width: | Height: | Size: 217 B |
BIN
assets/npc_front_eyes_closed.png
Normal file
|
After Width: | Height: | Size: 127 B |
BIN
assets/npc_front_face_1.png
Normal file
|
After Width: | Height: | Size: 227 B |
BIN
assets/npc_front_face_2.png
Normal file
|
After Width: | Height: | Size: 186 B |
BIN
assets/npc_front_face_3.png
Normal file
|
After Width: | Height: | Size: 157 B |
BIN
assets/npc_front_face_4.png
Normal file
|
After Width: | Height: | Size: 191 B |
BIN
assets/npc_front_hair_1.png
Normal file
|
After Width: | Height: | Size: 393 B |
BIN
assets/npc_front_hair_2.png
Normal file
|
After Width: | Height: | Size: 334 B |
BIN
assets/npc_front_hair_3.png
Normal file
|
After Width: | Height: | Size: 191 B |
BIN
assets/npc_front_hat_1.png
Normal file
|
After Width: | Height: | Size: 326 B |
BIN
assets/npc_front_hat_2.png
Normal file
|
After Width: | Height: | Size: 300 B |
BIN
assets/npc_front_shirt_0.png
Normal file
|
After Width: | Height: | Size: 528 B |
BIN
assets/npc_front_shirt_1.png
Normal file
|
After Width: | Height: | Size: 479 B |
BIN
assets/npc_front_shoes_0.png
Normal file
|
After Width: | Height: | Size: 273 B |
BIN
assets/npc_front_trousers_0.png
Normal file
|
After Width: | Height: | Size: 361 B |
BIN
assets/npc_front_trousers_1.png
Normal file
|
After Width: | Height: | Size: 354 B |
BIN
assets/npc_side_base_0.png
Normal file
|
After Width: | Height: | Size: 636 B |
BIN
assets/npc_side_base_1.png
Normal file
|
After Width: | Height: | Size: 639 B |
BIN
assets/npc_side_eyes_0.png
Normal file
|
After Width: | Height: | Size: 199 B |
BIN
assets/npc_side_eyes_1.png
Normal file
|
After Width: | Height: | Size: 191 B |
BIN
assets/npc_side_eyes_2.png
Normal file
|
After Width: | Height: | Size: 176 B |
BIN
assets/npc_side_eyes_closed.png
Normal file
|
After Width: | Height: | Size: 124 B |
BIN
assets/npc_side_face_1.png
Normal file
|
After Width: | Height: | Size: 257 B |
BIN
assets/npc_side_face_2.png
Normal file
|
After Width: | Height: | Size: 242 B |
BIN
assets/npc_side_face_3.png
Normal file
|
After Width: | Height: | Size: 135 B |
BIN
assets/npc_side_face_4.png
Normal file
|
After Width: | Height: | Size: 133 B |
BIN
assets/npc_side_hair_1.png
Normal file
|
After Width: | Height: | Size: 346 B |
BIN
assets/npc_side_hair_2.png
Normal file
|
After Width: | Height: | Size: 329 B |
BIN
assets/npc_side_hair_3.png
Normal file
|
After Width: | Height: | Size: 235 B |
BIN
assets/npc_side_hat_1.png
Normal file
|
After Width: | Height: | Size: 321 B |
BIN
assets/npc_side_hat_2.png
Normal file
|
After Width: | Height: | Size: 328 B |
BIN
assets/npc_side_shirt_0.png
Normal file
|
After Width: | Height: | Size: 448 B |
BIN
assets/npc_side_shirt_1.png
Normal file
|
After Width: | Height: | Size: 403 B |
BIN
assets/npc_side_shoes_0.png
Normal file
|
After Width: | Height: | Size: 259 B |
BIN
assets/npc_side_trousers_0.png
Normal file
|
After Width: | Height: | Size: 421 B |
BIN
assets/npc_side_trousers_1.png
Normal file
|
After Width: | Height: | Size: 393 B |
BIN
assets/oath_corner_inner.png
Normal file
|
After Width: | Height: | Size: 409 B |
BIN
assets/outside_ambience.wav
Normal file
BIN
assets/path_corner.png
Normal file
|
After Width: | Height: | Size: 520 B |
BIN
assets/path_middle.png
Normal file
|
After Width: | Height: | Size: 483 B |
BIN
assets/path_middle_edge.png
Normal file
|
After Width: | Height: | Size: 453 B |
BIN
assets/pool_table.png
Normal file
|
After Width: | Height: | Size: 846 B |
BIN
assets/poster.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
assets/rug0.png
Normal file
|
After Width: | Height: | Size: 634 B |
BIN
assets/rug1.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/saloon_ext.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
assets/saloon_int.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
assets/saloon_outside.wav
Normal file
BIN
assets/skull.png
Normal file
|
After Width: | Height: | Size: 555 B |
BIN
assets/table.png
Normal file
|
After Width: | Height: | Size: 1012 B |
BIN
assets/tile_detail_0.png
Normal file
|
After Width: | Height: | Size: 208 B |
BIN
assets/tile_detail_1.png
Normal file
|
After Width: | Height: | Size: 329 B |
BIN
assets/tile_detail_2.png
Normal file
|
After Width: | Height: | Size: 358 B |
BIN
assets/tile_detail_3.png
Normal file
|
After Width: | Height: | Size: 351 B |
BIN
assets/tile_detail_4.png
Normal file
|
After Width: | Height: | Size: 223 B |
BIN
assets/tile_detail_5.png
Normal file
|
After Width: | Height: | Size: 368 B |
BIN
assets/tile_detail_6.png
Normal file
|
After Width: | Height: | Size: 317 B |
BIN
assets/tile_dirt_0.png
Normal file
|
After Width: | Height: | Size: 462 B |
BIN
assets/tile_dirt_1.png
Normal file
|
After Width: | Height: | Size: 494 B |
24
code/.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug 'main.c' Project",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/../build/ldebug",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"preLaunchTask": "Build"
|
||||
}
|
||||
]
|
||||
}
|
||||
20
code/.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Build",
|
||||
"type": "shell",
|
||||
"command": "/home/matt/Repos/ld58/linux",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "never"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
91
code/core/arena.h
Normal file
@@ -0,0 +1,91 @@
|
||||
#if !defined(LD_CORE_ARENA_H_)
|
||||
#define LD_CORE_ARENA_H_
|
||||
|
||||
#define AlignUp(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
|
||||
#define AlignDown(x, a) (((x)) & ~((a) - 1))
|
||||
|
||||
#define KB(x) ((U64) (x) << 10)
|
||||
#define MB(x) ((U64) (x) << 20)
|
||||
#define GB(x) ((U64) (x) << 30)
|
||||
|
||||
#if !defined(M_ARENA_CHAIN_RESERVE)
|
||||
#define M_ARENA_CHAIN_RESERVE MB(4)
|
||||
#endif
|
||||
|
||||
function void *M_ZeroSize(void *base, U64 size);
|
||||
function void *M_CopySize(void *dst, void *src, U64 size);
|
||||
|
||||
typedef U32 M_ArenaFlags;
|
||||
enum {
|
||||
// Arena is fixed size, so will not chain
|
||||
M_ARENA_FIXED_SIZE = (1 << 0),
|
||||
// Don't clear allocation
|
||||
M_ARENA_NO_ZERO = (1 << 1)
|
||||
|
||||
};
|
||||
|
||||
typedef union M_Arena M_Arena;
|
||||
union M_Arena {
|
||||
struct {
|
||||
M_Arena *current;
|
||||
M_Arena *prev;
|
||||
|
||||
U64 base;
|
||||
U64 limit;
|
||||
U64 offset;
|
||||
|
||||
U64 committed;
|
||||
U64 increment;
|
||||
|
||||
M_ArenaFlags flags;
|
||||
};
|
||||
|
||||
U8 __pad[64];
|
||||
};
|
||||
|
||||
typedef struct M_ArenaOpts M_ArenaOpts;
|
||||
struct M_ArenaOpts {
|
||||
U64 initial;
|
||||
U64 increment;
|
||||
|
||||
M_ArenaFlags flags;
|
||||
};
|
||||
|
||||
typedef struct M_ArenaPushOpts M_ArenaPushOpts;
|
||||
struct M_ArenaPushOpts {
|
||||
U64 count;
|
||||
U64 align;
|
||||
|
||||
M_ArenaFlags flags;
|
||||
};
|
||||
|
||||
function M_Arena *_M_ArenaAlloc(U64 limit, M_ArenaOpts *opts);
|
||||
function void *_M_ArenaPush(M_Arena *arena, U64 esize, M_ArenaPushOpts *opts);
|
||||
function void *_M_ArenaPushCopy(M_Arena *arena, void *src, U64 esize, M_ArenaPushOpts *opts);
|
||||
|
||||
#define M_ArenaAlloc(limit, ...) _M_ArenaAlloc(limit, &(M_ArenaOpts) { .initial = MB(1), .increment = KB(64), ##__VA_ARGS__ })
|
||||
#define M_ArenaPush(arena, T, ...) (T *) _M_ArenaPush(arena, sizeof(T), &(M_ArenaPushOpts) { .count = 1, .align = Alignof(T), ##__VA_ARGS__ })
|
||||
#define M_ArenaPushCopy(arena, T, src, ...) (T *) _M_ArenaPush(arena, src, sizeof(T), &(M_ArenaPushOpts) { .count = 1, .align = Alignof(T), ##__VA_ARGS__ })
|
||||
|
||||
function void M_ArenaReset(M_Arena *arena);
|
||||
function void M_ArenaRelease(M_Arena *arena);
|
||||
|
||||
function U64 M_ArenaOffset(M_Arena *arena);
|
||||
|
||||
function void M_ArenaPop(M_Arena *arena, U64 offset);
|
||||
function void M_ArenaPopSize(M_Arena *arena, U64 size);
|
||||
|
||||
// Temporary memory
|
||||
|
||||
typedef struct M_Temp M_Temp;
|
||||
struct M_Temp {
|
||||
M_Arena *arena;
|
||||
U64 offset;
|
||||
};
|
||||
|
||||
function M_Temp M_TempAcquire(U64 count, M_Arena **conflicts);
|
||||
function void M_TempRelease(M_Temp temp);
|
||||
|
||||
#define M_TempScope(n, c) for (M_Temp temp = M_TempAcquire(n, c); temp.arena != 0; M_TempRelease(temp), temp.arena = 0)
|
||||
|
||||
#endif // LD_CORE_ARENA_H_
|
||||
3
code/core/core.c
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "impl/arena.c"
|
||||
#include "impl/string.c"
|
||||
#include "impl/math.c"
|
||||
11
code/core/core.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#if !defined(LD_CORE_CORE_H_)
|
||||
#define LD_CORE_CORE_H_
|
||||
|
||||
#include "types.h"
|
||||
#include "platform.h"
|
||||
#include "macros.h"
|
||||
#include "arena.h"
|
||||
#include "string.h"
|
||||
#include "math.h"
|
||||
|
||||
#endif // LD_CORE_CORE_H_
|
||||
210
code/core/impl/arena.c
Normal file
@@ -0,0 +1,210 @@
|
||||
void *M_ZeroSize(void *base, U64 size) {
|
||||
U8 *bytes = (U8 *) base;
|
||||
|
||||
while (size--) {
|
||||
*bytes++ = 0;
|
||||
}
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
void *M_CopySize(void *dst, void *src, U64 size) {
|
||||
U8 *se = (U8 *) src + (size - 1);
|
||||
U8 *de = (U8 *) dst + (size - 1);
|
||||
|
||||
while (size--) {
|
||||
*de-- = *se--;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
M_Arena *_M_ArenaAlloc(U64 limit, M_ArenaOpts *opts) {
|
||||
M_Arena *result = 0;
|
||||
|
||||
local_persist M_ArenaOpts _opts;
|
||||
if (!opts) {
|
||||
opts = &_opts;
|
||||
}
|
||||
|
||||
U64 page_size = VM_PageSize();
|
||||
U64 granularity = VM_AllocationGranularity();
|
||||
|
||||
U64 reserve = Max(AlignUp(limit, granularity), granularity);
|
||||
U64 initial = Clamp(page_size, AlignUp(opts->initial, page_size), reserve);
|
||||
|
||||
void *base = VM_Reserve(reserve);
|
||||
if (base != 0) {
|
||||
if (VM_Commit(base, initial)) {
|
||||
result = cast(M_Arena *) base;
|
||||
|
||||
result->current = result;
|
||||
result->prev = 0;
|
||||
|
||||
result->base = 0;
|
||||
result->offset = sizeof(M_Arena);
|
||||
result->limit = reserve;
|
||||
|
||||
result->committed = initial;
|
||||
result->increment = Max(AlignUp(opts->increment, page_size), page_size);
|
||||
|
||||
result->flags = opts->flags;
|
||||
}
|
||||
else {
|
||||
VM_Release(base, reserve);
|
||||
}
|
||||
}
|
||||
|
||||
Assert(result != 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void *_M_ArenaPush(M_Arena *arena, U64 esize, M_ArenaPushOpts *opts) {
|
||||
void *result = 0;
|
||||
|
||||
local_persist M_ArenaPushOpts _opts = { .count = 1, .align = 8 };
|
||||
if (!opts) {
|
||||
opts = &_opts;
|
||||
}
|
||||
|
||||
U64 alignment = Clamp(1, opts->align, 4096);
|
||||
M_Arena *current = arena->current;
|
||||
|
||||
U64 total = esize * opts->count;
|
||||
U64 offset = AlignUp(current->offset, alignment);
|
||||
U64 end = offset + total;
|
||||
|
||||
if (end > current->limit) {
|
||||
// Not enough space, chain a new arena if flags allow
|
||||
if ((arena->flags & M_ARENA_FIXED_SIZE) == 0) {
|
||||
U64 reserve = Min(total + sizeof(M_Arena), M_ARENA_CHAIN_RESERVE);
|
||||
M_Arena *next = M_ArenaAlloc(reserve, .flags = arena->flags);
|
||||
|
||||
next->base = current->base + current->limit;
|
||||
|
||||
SLL_PushN(arena->current, next, prev);
|
||||
|
||||
current = next;
|
||||
offset = AlignUp(current->offset, alignment);
|
||||
end = offset + total;
|
||||
}
|
||||
}
|
||||
|
||||
if (end > current->committed) {
|
||||
// Not enough committed, commit more memory
|
||||
U64 commit_offset = AlignUp(end, current->increment);
|
||||
U64 commit_limit = Min(commit_offset, current->limit);
|
||||
|
||||
U8 *commit_base = cast(U8 *) current + current->committed;
|
||||
U64 commit_size = commit_limit - current->committed;
|
||||
|
||||
if (VM_Commit(commit_base, commit_size)) {
|
||||
current->committed = commit_limit;
|
||||
}
|
||||
}
|
||||
|
||||
if (end <= current->committed) {
|
||||
// Successfully got enough memory, push the allocation
|
||||
result = cast(U8 *) current + offset;
|
||||
current->offset = end;
|
||||
|
||||
if (((opts->flags | arena->flags) & M_ARENA_NO_ZERO) == 0){
|
||||
M_ZeroSize(result, total);
|
||||
}
|
||||
}
|
||||
|
||||
Assert(result != 0);
|
||||
Assert(((U64) result & (alignment - 1)) == 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void *_M_ArenaPushCopy(M_Arena *arena, void *from, U64 size, M_ArenaPushOpts *opts) {
|
||||
void *result = M_CopySize(_M_ArenaPush(arena, size, opts), from, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
void M_ArenaReset(M_Arena *arena) {
|
||||
M_Arena *base = arena->current;
|
||||
while (base->base != 0) {
|
||||
M_Arena *prev = base->prev;
|
||||
|
||||
VM_Release(base, base->limit);
|
||||
base = prev;
|
||||
}
|
||||
|
||||
Assert(arena == base);
|
||||
|
||||
// @Todo: We could decommit some of the memory in the base arena, do we want to give a
|
||||
// parameter to choose how much :decommit
|
||||
base->offset = sizeof(M_Arena);
|
||||
arena->current = base;
|
||||
}
|
||||
|
||||
void M_ArenaRelease(M_Arena *arena) {
|
||||
M_ArenaReset(arena);
|
||||
VM_Release(arena, arena->limit);
|
||||
}
|
||||
|
||||
U64 M_ArenaOffset(M_Arena *arena) {
|
||||
U64 result = arena->current->base + arena->current->offset;
|
||||
return result;
|
||||
}
|
||||
|
||||
void M_ArenaPop(M_Arena *arena, U64 offset) {
|
||||
M_Arena *base = arena->current;
|
||||
while (base->base > offset) {
|
||||
M_Arena *prev = base->prev;
|
||||
|
||||
VM_Release(base, base->limit);
|
||||
base = prev;
|
||||
}
|
||||
|
||||
// :decommit
|
||||
arena->current = base;
|
||||
base->offset = Max(offset - base->base, sizeof(M_Arena));
|
||||
}
|
||||
|
||||
void M_ArenaPopSize(M_Arena *arena, U64 size) {
|
||||
U64 offset = M_ArenaOffset(arena);
|
||||
offset -= Min(offset, size);
|
||||
|
||||
M_ArenaPop(arena, offset);
|
||||
}
|
||||
|
||||
#define M_TEMP_ARENA_LIMIT GB(4)
|
||||
static thread_var M_Arena *__tls_temp[2];
|
||||
|
||||
M_Temp M_TempAcquire(U64 count, M_Arena **conflicts) {
|
||||
M_Temp result = { 0 };
|
||||
|
||||
for (U32 it = 0; it < ArraySize(__tls_temp); ++it) {
|
||||
if (!__tls_temp[it]) {
|
||||
__tls_temp[it] = M_ArenaAlloc(M_TEMP_ARENA_LIMIT, .initial = MB(1), .increment = MB(1));
|
||||
}
|
||||
|
||||
result.arena = __tls_temp[it];
|
||||
|
||||
for (U32 c = 0; c < count; ++c) {
|
||||
if (__tls_temp[it] == conflicts[c]) {
|
||||
result.arena = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result.arena) {
|
||||
result.offset = M_ArenaOffset(result.arena);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Assert(result.arena != 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void M_TempRelease(M_Temp temp) {
|
||||
M_ArenaPop(temp.arena, temp.offset);
|
||||
}
|
||||
|
||||
238
code/core/impl/math.c
Normal file
@@ -0,0 +1,238 @@
|
||||
#include <math.h>
|
||||
V2f V2F(F32 x, F32 y) {
|
||||
V2f result = { x, y };
|
||||
return result;
|
||||
}
|
||||
|
||||
function V2f V2f_Scale(V2f x, F32 scale) {
|
||||
return V2F(x.x * scale, x.y * scale);
|
||||
}
|
||||
|
||||
V2f NormaliseV2F(V2f x) {
|
||||
F32 magnitude = sqrtf((x.x * x.x) + (x.y * x.y));
|
||||
if(magnitude > 0.0){
|
||||
F32 inverse = 1.0f/magnitude;
|
||||
return V2F(x.x*inverse, x.y*inverse);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
V3f V3F(F32 x, F32 y, F32 z) {
|
||||
V3f result = { x, y, z };
|
||||
return result;
|
||||
}
|
||||
|
||||
V4f V4F(F32 x, F32 y, F32 z, F32 w) {
|
||||
V4f result = { x, y, z, w };
|
||||
return result;
|
||||
}
|
||||
|
||||
R2f R2F(V2f min, V2f max) {
|
||||
R2f result = { min, max };
|
||||
return result;
|
||||
}
|
||||
|
||||
V3f V3f_Neg(V3f x) {
|
||||
V3f result = { -x.x, -x.y, -x.z };
|
||||
return result;
|
||||
}
|
||||
|
||||
V3f V3f_Scale(V3f x, F32 s) {
|
||||
V3f result = { s * x.x, s * x.y, s * x.z };
|
||||
return result;
|
||||
}
|
||||
|
||||
V3f V3f_Sub(V3f a, V3f b) {
|
||||
V3f result = { a.x - b.x, a.y - b.y, a.z - b.z };
|
||||
return result;
|
||||
}
|
||||
|
||||
F32 V2f_Dot(V2f a, V2f b) {
|
||||
F32 result = (a.x * b.x) + (a.y * b.y);
|
||||
return result;
|
||||
}
|
||||
|
||||
F32 V3f_Dot(V3f a, V3f b) {
|
||||
F32 result = (a.x * b.x) + (a.y * b.y) + (a.z * b.z);
|
||||
return result;
|
||||
}
|
||||
|
||||
F32 V4f_Dot(V4f a, V4f b) {
|
||||
F32 result = (a.x * b.x) + (a.y * b.y) + (a.z * b.z) + (a.w * b.w);
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat4x4F M4x4F_Rows(V3f x, V3f y, V3f z) {
|
||||
Mat4x4F result = {
|
||||
x.x, x.y, x.z, 0,
|
||||
y.x, y.y, y.z, 0,
|
||||
z.x, z.y, z.z, 0,
|
||||
0, 0, 0, 1
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat4x4F M4x4F_Columns(V3f x, V3f y, V3f z) {
|
||||
Mat4x4F result = {
|
||||
x.x, y.x, z.x, 0,
|
||||
x.y, y.y, z.y, 0,
|
||||
x.z, y.z, z.z, 0,
|
||||
0, 0, 0, 1
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat4x4F M4x4F_Mul(Mat4x4F a, Mat4x4F b) {
|
||||
Mat4x4F result;
|
||||
|
||||
for (U32 r = 0; r < 4; ++r) {
|
||||
for (U32 c = 0; c < 4; ++c) {
|
||||
result.m[r][c] =
|
||||
(a.m[r][0] * b.m[0][c]) + (a.m[r][1] * b.m[1][c]) +
|
||||
(a.m[r][2] * b.m[2][c]) + (a.m[r][3] * b.m[3][c]);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
V4f M4x4F_VMul4(Mat4x4F m, V4f v) {
|
||||
V4f result;
|
||||
result.x = V4f_Dot(m.r[0], v);
|
||||
result.y = V4f_Dot(m.r[1], v);
|
||||
result.z = V4f_Dot(m.r[2], v);
|
||||
result.w = V4f_Dot(m.r[3], v);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
V3f M4x4F_VMul3(Mat4x4F m, V3f v) {
|
||||
V4f tx;
|
||||
tx.xyz = v;
|
||||
tx.w = 1.0f;
|
||||
|
||||
V3f result = M4x4F_VMul4(m, tx).xyz;
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat4x4FInv M4x4F_Perspective(F32 fov, F32 aspect, F32 nearp, F32 farp) {
|
||||
F32 focal_length = 1.0f / tanf(0.5f * (PI_F32 * (fov / 360.0f)));
|
||||
|
||||
F32 a = focal_length;
|
||||
F32 b = focal_length * aspect;
|
||||
|
||||
F32 c = -(nearp + farp) / (farp - nearp);
|
||||
F32 d = -(2.0f * nearp * farp) / (farp - nearp);
|
||||
|
||||
Mat4x4FInv result = {
|
||||
// fwd
|
||||
{
|
||||
a, 0, 0, 0,
|
||||
0, b, 0, 0,
|
||||
0, 0, c, d,
|
||||
0, 0, -1, 0
|
||||
},
|
||||
// inv
|
||||
{
|
||||
(1 / a), 0, 0, 0,
|
||||
0, (1 / b), 0, 0,
|
||||
0, 0, 0, -1,
|
||||
0, 0, (1/ d), (c / d)
|
||||
}
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Mat4x4FInv M4x4F_CameraView(V3f x, V3f y, V3f z, V3f p) {
|
||||
Mat4x4FInv result;
|
||||
|
||||
// Construct orthonomal basis from axes
|
||||
//
|
||||
result.fwd = M4x4F_Rows(x, y, z);
|
||||
V3f txp = V3f_Neg(M4x4F_VMul3(result.fwd, p));
|
||||
|
||||
// Translate by txp
|
||||
//
|
||||
result.fwd.r[0].w += txp.x;
|
||||
result.fwd.r[1].w += txp.y;
|
||||
result.fwd.r[2].w += txp.z;
|
||||
|
||||
// Calculate inverse axes
|
||||
//
|
||||
V3f ix = V3f_Scale(x, 1.0f / V3f_Dot(x, x));
|
||||
V3f iy = V3f_Scale(y, 1.0f / V3f_Dot(y, y));
|
||||
V3f iz = V3f_Scale(z, 1.0f / V3f_Dot(z, z));
|
||||
|
||||
// Calculate inverse position
|
||||
//
|
||||
V3f ip;
|
||||
ip.x = (txp.x * ix.x) + (txp.y * iy.x) + (txp.z * iz.x);
|
||||
ip.y = (txp.x * ix.y) + (txp.y * iy.y) + (txp.z * iz.y);
|
||||
ip.z = (txp.x * ix.z) + (txp.y * iy.z) + (txp.z * iz.z);
|
||||
|
||||
result.inv = M4x4F_Columns(ix, iy, iz);
|
||||
|
||||
// Translate by ip
|
||||
//
|
||||
result.inv.r[0].w -= ip.x;
|
||||
result.inv.r[1].w -= ip.y;
|
||||
result.inv.r[2].w -= ip.z;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Random
|
||||
|
||||
Random Random_Seed(U64 seed) {
|
||||
Random result = { seed };
|
||||
return result;
|
||||
}
|
||||
|
||||
U64 Random_Next(Random *rnd) {
|
||||
U64 result = rnd->state;
|
||||
|
||||
result ^= (result << 13);
|
||||
result ^= (result >> 7);
|
||||
result ^= (result << 17);
|
||||
|
||||
rnd->state = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
F32 Random_F32(Random *rnd, F32 min, F32 max) {
|
||||
F32 result = min + (Random_Unilateral(rnd) * (max - min));
|
||||
return result;
|
||||
}
|
||||
|
||||
F64 Random_F64(Random *rnd, F64 min, F64 max) {
|
||||
F64 result = min + (Random_Unilateral(rnd) * (max - min));
|
||||
return result;
|
||||
}
|
||||
|
||||
U32 Random_U32(Random *rnd, U32 min, U32 max) {
|
||||
U32 result = min + (U32) (Random_Unilateral(rnd) * (max - min));
|
||||
return result;
|
||||
}
|
||||
|
||||
F32 Random_Unilateral(Random *rnd) {
|
||||
F32 result = Random_Next(rnd) / (F32) U64_MAX;
|
||||
return result;
|
||||
}
|
||||
|
||||
F32 Random_Bilateral(Random *rnd) {
|
||||
F32 result = -1.0f + (2.0f * Random_Unilateral(rnd));
|
||||
return result;
|
||||
}
|
||||
|
||||
V2f V2f_Clip(V2f screen_xy, V2f screen_size) {
|
||||
V2f result;
|
||||
result.x = ((screen_xy.x / screen_size.w) * 2.0f) - 1.0f;
|
||||
result.y = ((screen_xy.y / screen_size.h) * 2.0f) - 1.0f;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
164
code/core/impl/string.c
Normal file
@@ -0,0 +1,164 @@
|
||||
Str8 Str8_Wrap(S64 count, U8 *data) {
|
||||
Str8 result;
|
||||
result.data = data;
|
||||
result.count = count;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Str8 Str8_WrapRange(U8 *start, U8 *end) {
|
||||
Str8 result;
|
||||
result.data = start;
|
||||
result.count = cast(S64) (end - start);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal S64 Str8_CountZ(U8 *data) {
|
||||
S64 result = 0;
|
||||
while (data[result] != 0) { result += 1; }
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Str8 Str8_WrapZ(U8 *data) {
|
||||
Str8 result;
|
||||
result.data = data;
|
||||
result.count = Str8_CountZ(data);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define FNV_OFFSET_BIAS ((U64) 0xCBF29CE484222325)
|
||||
#define FNV_PRIME ((U64) 0x100000001B3)
|
||||
|
||||
U64 Str8_Hash(Str8 v) {
|
||||
U64 result = FNV_OFFSET_BIAS;
|
||||
|
||||
for (S64 it = 0; it < v.count; ++it) {
|
||||
result ^= v.data[it];
|
||||
result *= FNV_PRIME;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Str8 Str8_Copy(M_Arena *arena, Str8 s) {
|
||||
Str8 result;
|
||||
result.count = s.count;
|
||||
result.data = M_ArenaPush(arena, U8, .count = s.count + 1);
|
||||
|
||||
M_CopySize(result.data, s.data, s.count);
|
||||
return result;
|
||||
}
|
||||
|
||||
Str8 Str8_Format(M_Arena *arena, const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
Str8 result = Str8_FormatArgs(arena, format, args);
|
||||
va_end(args);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal S64 Str8_ProcessFormat(Str8 out, const char *format, va_list args) {
|
||||
S64 result = vsnprintf((char *) out.data, (int) out.count, format, args);
|
||||
return result;
|
||||
}
|
||||
|
||||
Str8 Str8_FormatArgs(M_Arena *arena, const char *format, va_list args) {
|
||||
Str8 result;
|
||||
|
||||
va_list copy;
|
||||
va_copy(copy, args);
|
||||
|
||||
U64 offset = M_ArenaOffset(arena);
|
||||
|
||||
result.count = KB(1);
|
||||
result.data = M_ArenaPush(arena, U8, .count = result.count);
|
||||
|
||||
S64 needed = Str8_ProcessFormat(result, format, args);
|
||||
if (needed >= result.count) {
|
||||
M_ArenaPop(arena, offset);
|
||||
|
||||
result.count = needed;
|
||||
result.data = M_ArenaPush(arena, U8, .count = result.count + 1);
|
||||
|
||||
Str8_ProcessFormat(result, format, copy);
|
||||
}
|
||||
else {
|
||||
U64 size = result.count - needed - 1;
|
||||
M_ArenaPopSize(arena, size);
|
||||
|
||||
result.count = needed;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
B32 Str8_Equal(Str8 a, Str8 b, Str8_EqualFlags flags) {
|
||||
B32 result = (a.count == b.count);
|
||||
|
||||
if (result) {
|
||||
B32 ignore_case = (flags & STR8_EQUAL_IGNORE_CASE) != 0;
|
||||
|
||||
for (S64 it = 0; it < a.count; ++it) {
|
||||
U8 ac = ignore_case ? Chr_ToLowercase(a.data[it]) : a.data[it];
|
||||
U8 bc = ignore_case ? Chr_ToLowercase(b.data[it]) : b.data[it];
|
||||
|
||||
if (ac != bc) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Str8 Str8_Prefix(Str8 s, S64 count) {
|
||||
Str8 result;
|
||||
result.data = s.data;
|
||||
result.count = Min(s.count, count);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Str8 Str8_Suffix(Str8 s, S64 count) {
|
||||
Str8 result;
|
||||
result.count = Min(s.count, count);
|
||||
result.data = s.data + (s.count - result.count);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Str8 Str8_RemoveAfterLast(Str8 s, U8 c) {
|
||||
Str8 result;
|
||||
result.data = s.data;
|
||||
result.count = s.count;
|
||||
|
||||
for (S64 it = s.count - 1; it >= 0; --it) {
|
||||
if (result.data[it] == c) {
|
||||
result.count = it;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
B32 Str8_EndsWith(Str8 s, Str8 suffix) {
|
||||
B32 result = Str8_Equal(Str8_Suffix(s, suffix.count), suffix, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
U8 Chr_ToUppercase(U8 c) {
|
||||
U8 result = (c >= 'a' && c <= 'z') ? (c - ('a' - 'A')) : c;
|
||||
return result;
|
||||
}
|
||||
|
||||
U8 Chr_ToLowercase(U8 c) {
|
||||
U8 result = (c >= 'A' && c <= 'Z') ? (c + ('a' - 'A')) : c;
|
||||
return result;
|
||||
}
|
||||
@@ -1,9 +1,18 @@
|
||||
#if !defined(LD_CORE_MACROS_H_)
|
||||
#define LD_CORE_MACROS_H_
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#define Assert(exp) assert(exp)
|
||||
#define StaticAssert(exp) static_assert(exp, #exp)
|
||||
|
||||
#define ArraySize(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#define Min(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define Max(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define Clamp(min, x, max) (Min(Max(min, x), max))
|
||||
#define Clamp01(x) Clamp(0, x, 1)
|
||||
|
||||
#define cast(x) (x)
|
||||
|
||||
#define _Glue(a, b) a##b
|
||||
#define _Stringify(x) #x
|
||||
@@ -11,5 +20,37 @@
|
||||
#define Glue(a, b) _Glue(a, b)
|
||||
#define Stringify(x) _Stringify(x)
|
||||
|
||||
#if LANG_CPP
|
||||
#define Alignof(x) alignof(x)
|
||||
#else
|
||||
#define Alignof(x) _Alignof(x)
|
||||
#endif
|
||||
|
||||
// Singly linked lists (named members)
|
||||
//
|
||||
#define SLL_EnqueueN(h, t, n, next) (((h) == 0) ? ((h) = (t) = (n), (n)->next = 0) : ((t)->next = (n), (t) = (n), (n)->next = 0))
|
||||
#define SLL_EnqueueFrontN(h, t, n, next) (((h) == 0) ? ((h) = (t) = (n), (n)->next = 0) : ((n)->next = (h), (h) = (n)))
|
||||
#define SLL_DequeueN(h, t, next) ((h) == (t) ? ((h) = 0, (t) = 0) : ((h) = (h)->next))
|
||||
|
||||
#define SLL_PushN(h, n, next) ((n)->next = (h), (h) = (n))
|
||||
#define SLL_PopN(h, next) (((h) != 0) ? (h) = (h)->next : 0)
|
||||
|
||||
#define SLL_Enqueue(h, t, n) SLL_EnqueueN(h, t, n, next)
|
||||
#define SLL_EnqueueFront(h, t, n) SLL_EnqueueFrontN(h, t, n, next)
|
||||
#define SLL_Dequeue(h, t) SLL_DequeueN(h, t, next)
|
||||
|
||||
#define SLL_Push(h, n) SLL_PushN(h, n, next)
|
||||
#define SLL_Pop(h) (((h) != 0) ? (h) = (h)->next : 0)
|
||||
|
||||
#define function static
|
||||
#define internal static
|
||||
#define global_var static
|
||||
#define local_persist static
|
||||
|
||||
#if COMPILER_CL
|
||||
#define thread_var __declspec(thread)
|
||||
#else
|
||||
#define thread_var __thread
|
||||
#endif
|
||||
|
||||
#endif // LD_CORE_MACROS_H_
|
||||
|
||||
153
code/core/math.h
Normal file
@@ -0,0 +1,153 @@
|
||||
#if !defined(LD_CORE_MATH_H_)
|
||||
#define LD_CORE_MATH_H_
|
||||
|
||||
#define PI_F32 (3.14159265358979323846264338f)
|
||||
#define TAU_F32 (2.0f * PI_F32)
|
||||
|
||||
#define Abs(x) (((x) < 0 ? -(x) : (x)))
|
||||
|
||||
typedef struct Random Random;
|
||||
struct Random {
|
||||
U64 state;
|
||||
};
|
||||
|
||||
typedef union V2f V2f;
|
||||
union V2f {
|
||||
struct {
|
||||
F32 x, y;
|
||||
};
|
||||
|
||||
struct {
|
||||
F32 u, v;
|
||||
};
|
||||
|
||||
struct {
|
||||
F32 w, h;
|
||||
};
|
||||
|
||||
F32 e[2];
|
||||
};
|
||||
|
||||
typedef union V2i V2i;
|
||||
union V2i {
|
||||
struct {
|
||||
U32 x, y;
|
||||
};
|
||||
|
||||
struct {
|
||||
U32 w, h;
|
||||
};
|
||||
|
||||
U32 e[2];
|
||||
};
|
||||
|
||||
typedef union V3f V3f;
|
||||
union V3f {
|
||||
struct {
|
||||
F32 x, y, z;
|
||||
};
|
||||
|
||||
struct {
|
||||
F32 r, g, b;
|
||||
};
|
||||
|
||||
struct {
|
||||
F32 w, h, d;
|
||||
};
|
||||
|
||||
struct {
|
||||
V2f xy;
|
||||
F32 _z;
|
||||
};
|
||||
|
||||
F32 e[3];
|
||||
};
|
||||
|
||||
typedef union V4f V4f;
|
||||
union V4f {
|
||||
struct {
|
||||
F32 x, y, z, w;
|
||||
};
|
||||
|
||||
struct {
|
||||
F32 r, g, b, a;
|
||||
};
|
||||
|
||||
struct {
|
||||
V3f xyz;
|
||||
F32 _w;
|
||||
};
|
||||
|
||||
F32 e[4];
|
||||
};
|
||||
|
||||
typedef union Mat4x4F Mat4x4F;
|
||||
union Mat4x4F {
|
||||
F32 m[4][4];
|
||||
F32 e[16];
|
||||
V4f r[4];
|
||||
};
|
||||
|
||||
typedef struct Mat4x4FInv Mat4x4FInv;
|
||||
struct Mat4x4FInv {
|
||||
Mat4x4F fwd;
|
||||
Mat4x4F inv;
|
||||
};
|
||||
|
||||
typedef struct R2f R2f;
|
||||
struct R2f {
|
||||
V2f min;
|
||||
V2f max;
|
||||
};
|
||||
|
||||
typedef struct R3f R3f;
|
||||
struct R3f {
|
||||
V3f min;
|
||||
V3f max;
|
||||
};
|
||||
|
||||
function V2f V2F(F32 x, F32 y);
|
||||
function V3f V3F(F32 x, F32 y, F32 z);
|
||||
function V4f V4F(F32 x, F32 y, F32 z, F32 w);
|
||||
|
||||
function R2f R2F(V2f min, V2f max);
|
||||
|
||||
function V2f V2f_Scale(V2f x, F32 s);
|
||||
|
||||
function V3f V3f_Neg(V3f x);
|
||||
function V3f V3f_Scale(V3f x, F32 s);
|
||||
function V3f V3f_Sub(V3f a, V3f b);
|
||||
|
||||
function F32 V2f_Dot(V2f a, V2f b);
|
||||
function F32 V3f_Dot(V3f a, V3f b);
|
||||
function F32 V4f_Dot(V4f a, V4f b);
|
||||
|
||||
function Mat4x4F M4x4F_Rows(V3f x, V3f y, V3f z);
|
||||
function Mat4x4F M4x4F_Columns(V3f x, V3f y, V3f z);
|
||||
|
||||
function V4f M4x4F_VMul4(Mat4x4F m, V4f v);
|
||||
function V3f M4x4F_VMul3(Mat4x4F m, V3f v);
|
||||
|
||||
function Mat4x4FInv M4x4F_Perspective(F32 fov, F32 aspect, F32 nearp, F32 farp);
|
||||
function Mat4x4FInv M4x4F_CameraView(V3f x, V3f y, V3f z, V3f p);
|
||||
|
||||
function V2f NormaliseV2F(V2f x);
|
||||
function V2f V2f_Scale(V2f x, F32 scale);
|
||||
|
||||
// Random
|
||||
|
||||
function Random Random_Seed(U64 seed);
|
||||
|
||||
function U64 Random_Next(Random *rnd);
|
||||
|
||||
function F32 Random_F32(Random *rnd, F32 min, F32 max);
|
||||
function F64 Random_F64(Random *rnd, F64 min, F64 max);
|
||||
|
||||
function U32 Random_U32(Random *rnd, U32 min, U32 max);
|
||||
|
||||
function F32 Random_Unilateral(Random *rnd);
|
||||
function F32 Random_Bilateral(Random *rnd);
|
||||
|
||||
V2f V2f_Clip(V2f screen_xy, V2f screen_size);
|
||||
|
||||
#endif // LD_CORE_MATH_H_
|
||||
@@ -68,8 +68,17 @@
|
||||
#if OS_WINDOWS
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#include <windows.h>
|
||||
#include <shlobj_core.h>
|
||||
#pragma warning(disable : 4201)
|
||||
#elif OS_LINUX
|
||||
#include <sys/types.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#endif // LD_CORE_PLATFORM_H_
|
||||
|
||||