Compare commits

..

64 Commits

Author SHA1 Message Date
mid
b7c0b0780c And it all ended with a real bug to fix; how poetic
All checks were successful
k4 Build Test / do_the_build (push) Successful in 43s
2026-01-22 22:44:30 +02:00
mid
46bd5e8d5e this better be all
All checks were successful
k4 Build Test / do_the_build (push) Successful in 44s
2026-01-22 21:59:50 +02:00
mid
d614e2ced4 just use /dev/urandom
All checks were successful
k4 Build Test / do_the_build (push) Successful in 46s
2026-01-22 21:18:29 +02:00
mid
57fffeb0a3 update 12-win32 to 14-win32
All checks were successful
k4 Build Test / do_the_build (push) Successful in 34s
2026-01-21 22:52:32 +02:00
mid
def545450d add freetype and libz
Some checks failed
k4 Build Test / do_the_build (push) Failing after 24s
2026-01-21 22:49:02 +02:00
mid
9b7ecb3ae7 update k3 commit
Some checks failed
k4 Build Test / do_the_build (push) Failing after 24s
2026-01-21 22:27:45 +02:00
mid
9c2e4ffae1 can't be bothered
Some checks failed
k4 Build Test / do_the_build (push) Failing after 12s
2026-01-21 22:25:24 +02:00
mid
3e14195bf7 What about this, dumbfuck
Some checks failed
k4 Build Test / do_the_build (push) Failing after 5s
2026-01-21 22:22:54 +02:00
mid
055ff4f5ce fixes for build
Some checks failed
k4 Build Test / do_the_build (push) Failing after 4s
2026-01-21 22:20:15 +02:00
mid
4d0e043f4c use latest k3 commit
Some checks failed
k4 Build Test / do_the_build (push) Failing after 5s
2026-01-21 20:54:20 +02:00
mid
3da728c768 Try automated build on Debian 9
Some checks failed
k4 Build Test / do_the_build (push) Failing after 8s
2026-01-21 20:46:43 +02:00
mid
8857b93f90 Updated changelog 2026-01-18 13:52:01 +02:00
mid
cf0f402da3 Add changelog 2026-01-18 13:49:18 +02:00
mid
db46d5506c Many bug fixes 2026-01-18 13:43:51 +02:00
mid
e87417603e k3 interface update 2 2026-01-14 12:00:36 +02:00
mid
0f68c8c7ae k3 interface update 2026-01-14 12:00:16 +02:00
mid
2211193a96 Conditionally load Lua package library (for native libs) 2026-01-14 12:00:07 +02:00
mid
6d821cb361 Expose remove_child function 2026-01-14 11:59:35 +02:00
mid
a2039557bb Fix require filename parsing 2026-01-14 11:59:13 +02:00
mid
a1439664ca Add vsync parameter 2025-12-02 00:04:13 +02:00
mid
0453585751 Move to k3 SDF fonts 2025-12-02 00:04:05 +02:00
mid
5f6dc66a0f Update to newest k3 2025-10-12 20:47:41 +03:00
mid
2e730baf33 Scriptable near and far planes 2025-09-30 11:05:33 +03:00
mid
462412c31a Already .k3m has some legacy bullshit 2025-09-30 11:05:12 +03:00
mid
e4b5f8d361 streamloader return value 2025-09-19 23:11:42 +03:00
mid
f7a429cfbc Free font buffer 2025-09-13 12:02:27 +03:00
mid
3c372a3024 Map to newest k3 2025-09-13 12:02:15 +03:00
mid
f65891932a k3Font walls 2025-08-28 23:32:03 +03:00
mid
177d259304 Add scrollbox and image objects 2025-08-28 14:11:40 +03:00
mid
dbced43b2b Introduce animation trees, remove "standard animations" from core 2025-08-10 15:42:45 +03:00
mid
96da001734 Add game.ui.obj 2025-07-27 16:54:32 +03:00
mid
943601bc3a Introduce k3Menu properties to luaapi 2025-07-27 16:15:55 +03:00
mid
b32671567e Switch to strncasecmp
All checks were successful
k4 Build Test / do_the_build (push) Successful in 52s
2025-07-13 10:15:02 +03:00
mid
f4cf597a95 _DEFAULT_SOURCE and _GNU_SOURCE
Some checks failed
k4 Build Test / do_the_build (push) Failing after 30s
2025-07-13 09:57:52 +03:00
mid
5f2e84d8cf Support LOOPPOINT metadata field for ogg files
Some checks failed
k4 Build Test / do_the_build (push) Failing after 30s
2025-07-12 23:27:33 +03:00
mid
7754e410fd EVEN MORE STABLIER
All checks were successful
k4 Build Test / do_the_build (push) Successful in 56s
2025-07-05 14:06:07 +03:00
mid
5a3a524cb3 add libgomp
All checks were successful
k4 Build Test / do_the_build (push) Successful in 50s
2025-07-05 11:26:59 +03:00
mid
55b8e827c2 Strip
All checks were successful
k4 Build Test / do_the_build (push) Successful in 50s
2025-07-05 10:39:43 +03:00
mid
368664d246 Bug fixes
All checks were successful
k4 Build Test / do_the_build (push) Successful in 56s
2025-06-29 22:22:13 +03:00
mid
90f0e2dd42 Physics stability 2025-06-29 20:47:24 +03:00
mid
355df2ee44 Extend network traversal to local addresses 2025-06-29 20:47:14 +03:00
mid
e126db573a Change top-level dir name
All checks were successful
k4 Build Test / do_the_build (push) Successful in 58s
2025-06-28 14:01:32 +03:00
mid
ceb8ccb7d4 README.md 2025-06-28 13:20:38 +03:00
mid
e81750300d Abstract shader parameters (to make them modifiable later) 2025-06-28 13:18:58 +03:00
mid
446ff24fcf Make time per-scene 2025-06-28 13:18:24 +03:00
mid
309af8f59e stopsmooth 2025-06-28 13:17:58 +03:00
mid
7b6ce73fa5 Improve ray-based character controller 2025-06-28 13:17:20 +03:00
mid
ce465ef449 Fix ray origin 2025-06-12 12:00:16 +03:00
mid
9478bca2ad Raycasting character controller 2025-06-11 10:14:56 +03:00
mid
da59158fd1 fix 2?
All checks were successful
k4 Build Test / do_the_build (push) Successful in 53s
2025-05-11 16:22:45 +03:00
mid
ff2924a0b7 fix?
Some checks failed
k4 Build Test / do_the_build (push) Failing after 4s
2025-05-11 16:21:05 +03:00
mid
24ddb047aa Updated runner to Debian 12
All checks were successful
k4 Build Test / do_the_build (push) Successful in 1m3s
2025-05-11 15:32:58 +03:00
mid
0ba2cdee1c Remove __in6_u usage
Some checks failed
k4 Build Test / do_the_build (push) Failing after 59s
2025-05-11 15:26:25 +03:00
mid
ae4a62f584 fix k3 submodule
Some checks failed
k4 Build Test / do_the_build (push) Failing after 26s
2025-05-11 11:41:17 +03:00
mid
e43391caa3 update workflow
Some checks failed
k4 Build Test / do_the_build (push) Failing after 6s
2025-05-10 19:20:19 +03:00
mid
eb17923448 Add noise1234 source 2025-05-10 19:19:32 +03:00
mid
9cd4aee87a bugfix 2025-05-10 19:19:13 +03:00
mid
310889bd2c things 2025-05-10 19:18:58 +03:00
mid
0629b042ad Many API additions 2 2025-05-10 19:18:09 +03:00
mid
3c780c7290 Clamping texture sizes 2025-05-10 19:17:23 +03:00
mid
943a8cd1d9 Do not tanh the final audio 2025-05-10 19:16:59 +03:00
mid
2c1ee84791 Update GLAD file 2025-05-10 19:16:45 +03:00
mid
8990e415d3 Many API additions 2025-05-10 19:16:20 +03:00
mid
85d5f4f019 Makefile changes 2025-05-10 19:13:01 +03:00
26 changed files with 2838 additions and 589 deletions

View File

@@ -13,12 +13,13 @@ jobs:
uses: actions/checkout@v3
with:
submodules: 'true'
- run: mkdir build build/k3 bin bin/assets
- run: CC="i686-w64-mingw32-gcc" CFLAGS="-I/usr/i686-w64-mingw32/include -I/usr/i686-w64-mingw32/include/lua5.3 -L/usr/i686-w64-mingw32/lib -Wno-error" make -B
- run: CC="i686-linux-gnu-gcc" CFLAGS="-I/usr/i686-linux-gnu/include -I/usr/i686-linux-gnu/include/lua5.3 -L/usr/i686-linux-gnu/lib -Wno-error" make -B
- run: cp /usr/lib/gcc/i686-w64-mingw32/10-win32/libgcc_s_dw2-1.dll /usr/lib/gcc/i686-w64-mingw32/10-win32/libstdc++-6.dll /usr/i686-w64-mingw32/lib/libportaudio-2.dll /usr/i686-w64-mingw32/lib/libwinpthread-1.dll bin/
- run: mkdir build build/k3 build/k3/compr bin bin/assets
- run: LIBS="-lfreetype -l:libz.a" CC="i686-w64-mingw32-gcc" CFLAGS="-I/usr/i686-w64-mingw32/include -I/usr/i686-w64-mingw32/include/lua5.3 -L/usr/i686-w64-mingw32/lib -Wno-error" make -B
- run: cp /usr/lib/gcc/i686-w64-mingw32/14-win32/libgcc_s_dw2-1.dll /usr/lib/gcc/i686-w64-mingw32/14-win32/libstdc++-6.dll /usr/i686-w64-mingw32/lib/libportaudio-2.dll /usr/i686-w64-mingw32/lib/libwinpthread-1.dll /usr/lib/gcc/i686-w64-mingw32/14-win32/libgomp-1.dll bin/
- run: curl "http://127.0.0.1:9898/build?root=${{ github.workspace }}"
- run: cp -r /home/git/k4templateassets/* bin/assets/
- run: zip -9r "k4${{ github.ref_name }}.zip" bin/
- run: mv bin k4
- run: zip -9r "k4${{ github.ref_name }}.zip" k4/
- name: Create package
uses: akkuman/gitea-release-action@v1
with:

View File

@@ -1,24 +1,26 @@
k4_SRCS := $(wildcard src/*.c)
k4_HDRS := $(wildcard src/*.h)
rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d))
k4_SRCS := $(call rwildcard,src,*.c)
k4_HDRS := $(call rwildcard,src,*.h)
k4_OBJS := $(patsubst src/%.c, build/%.o, $(k4_SRCS))
k4_DEPS := $(patsubst src/%.c, build/%.d, $(k4_SRCS))
k3_SRCS = $(wildcard k3/src/*.c)
k3_HDRS = $(wildcard k3/src/*.h)
k3_SRCS := $(call rwildcard,k3/src,*.c)
k3_HDRS := $(call rwildcard,k3/src,*.h)
k3_OBJS := $(patsubst k3/src/%.c, build/k3/%.o, $(k3_SRCS))
k3_DEPS := $(patsubst k3/src/%.c, build/k3/%.d, $(k3_SRCS))
CFLAGS := $(CFLAGS) -Ik3/src
CFLAGS := $(CFLAGS) -D_GNU_SOURCE -D_DEFAULT_SOURCE -DGLCA_CUSTOM_GLYPH_DATA -Ik3/src -fopenmp -O2 -flto -fwhole-program -Wno-error=incompatible-pointer-types -Wno-error=int-conversion
ifneq (,$(findstring mingw,$(CC)))
CFLAGS := -static-libgcc -static-libstdc++ -std=gnu99 -march=pentium4 -D_WIN32_WINNT=0x600 -DENET_FEATURE_ADDRESS_MAPPING -fno-pic -no-pie -fms-extensions -fno-pie -O0 -g -gdwarf-2 -Isrc $(CFLAGS)
LIBS := -l:libglfw3.a -lopengl32 -pthread -lm -l:libode.a -l:libvorbisfile.a -l:libvorbis.a -l:libogg.a -lportaudio -lgdi32 -lws2_32 -lwinmm -lstdc++ -lole32 -lsetupapi -lhid -l:liblua5.3.a $(LIBS)
CFLAGS := -static-libgcc -static-libstdc++ -std=gnu99 -march=pentium4 -D_WIN32_WINNT=0x600 -DENET_FEATURE_ADDRESS_MAPPING -fno-pic -no-pie -fms-extensions -fno-pie -Isrc $(CFLAGS)
LIBS := -l:libglfw3.a -lopengl32 -pthread -lm -l:libode.a -l:libvorbisfile.a -l:libvorbis.a -l:libogg.a -lportaudio -lgdi32 -lws2_32 -lwinmm -lstdc++ -lole32 -lsetupapi -lhid -l:liblua5.3.a -liphlpapi $(LIBS)
else
CFLAGS := -march=opteron $(SAN) -std=gnu99 -DENET_FEATURE_ADDRESS_MAPPING -fms-extensions -fno-pic -no-pie -fno-pie -O0 -g -Isrc $(CFLAGS)
LIBS := -lglfw3 -pthread -ldl -lm -lode -lstdc++ -llua5.3 -lvorbis -lvorbisfile -lportaudio $(LIBS)
CFLAGS := -march=opteron $(SAN) -std=gnu99 -DENET_FEATURE_ADDRESS_MAPPING -fms-extensions -fno-pic -no-pie -fno-pie -Isrc $(CFLAGS)
LIBS := -lglfw3 -pthread -ldl -lm -lode -lstdc++ -llua5.3 -lvorbis -lvorbisfile -logg -lasound -lfreetype -lportaudio -lz $(LIBS)
endif
CFLAGS := $(CFLAGS) -DLOCALHOST_ONLY -Dk3_IRREGULAR_SHADOWS
CFLAGS := $(CFLAGS) -DLOCALHOST_ONLY
build/k3/%.o: k3/src/%.c
$(CC) $(CFLAGS) -MMD -o $@ -c $<

21
README.md Normal file
View File

@@ -0,0 +1,21 @@
Homepage: https://mid.net.ua/k4.html
## Changelog
## v2
1. k3Menu objects now have stylable properties ala CSS
2. Exposed `game.ui.obj` "base object" which allows you to create your own widgets
3. Revamped the animation system to one with blend trees
4. Added scrollboxes and image objects to k3Menu
5. Replaced the font subsystem with one that uses TrueType fonts directly, and they are drawn using signed distance fields when possible
6. Added `game.near` and `game.far` values for editing the camera planes
7. Added vsync parameter to command line
8. Graphics bug fixes
9. Improved mipmapping
10. Frustum culling
11. Added support for 32-bit indices in models
## v1
Initial release.

View File

@@ -216,7 +216,7 @@ for input_filename in sys.argv[1:]:
k3result["meshes"].append(mehs)
if len(skin.joints) > 255:
if skin and len(skin.joints) > 255:
err("Bone maximum is 255")
err_barrier()

1
k3 Submodule

Submodule k3 added at 56ecba05b1

View File

@@ -115,6 +115,8 @@ def write_some_data(context, filepath, doExportEverything):
out.write(struct.pack("4f", m.col[c][0], m.col[c][1], m.col[c][2], m.col[c][3]))
for b in dabones:
out.write(struct.pack("B", dabones.index(b.parent) if b.parent else 255))
for b in dabones:
out.write(b.name.encode("UTF-8") + b'\x00')
for v in vertdict.keys():
out.write(struct.pack("3f", v[0][0], v[0][2], -v[0][1]))

View File

@@ -5,6 +5,8 @@
#include"resman.h"
#include<cglm/vec3.h>
#define SUBFEET(cp) (cp->capsule.radius)
struct Game Game;
void game_init() {
@@ -29,8 +31,8 @@ void game_init() {
}
struct CollisionPair {
dGeomID g1; // greater
dGeomID g2; // lesser
uint16_t e1; // greater
uint16_t e2; // lesser
uint8_t x;
} __attribute__((packed));
static size_t activeCollisionCount, activeCollisionCapacity;
@@ -38,22 +40,22 @@ static struct CollisionPair *activeCollisions;
int pair_comparator(const void *a_, const void *b_) {
const struct CollisionPair *a = a_;
const struct CollisionPair *b = b_;
if(a->g1 == b->g1) {
return (uintptr_t) a->g2 - (uintptr_t) b->g2;
if(a->e1 == b->e1) {
return (intmax_t) a->e2 - (intmax_t) b->e2;
} else {
return (uintptr_t) a->g1 - (uintptr_t) b->g1;
return (intmax_t) a->e1 - (intmax_t) b->e1;
}
}
static int activate_pair(dGeomID g1, dGeomID g2) {
static int activate_pair(uint16_t e1, uint16_t e2) {
struct CollisionPair p = {
.g1 = g1 > g2 ? g1 : g2,
.g2 = g1 > g2 ? g2 : g1,
.e1 = e1 > e2 ? e1 : e2,
.e2 = e1 > e2 ? e2 : e1,
};
struct CollisionPair *peepee = bsearch(&p, activeCollisions, activeCollisionCount, sizeof(struct CollisionPair), pair_comparator);
if(peepee) {
peepee->x++;
peepee->x = 2;
return TRIGGER_EV_CONTINUOUS;
}
@@ -72,8 +74,8 @@ static int activate_pair(dGeomID g1, dGeomID g2) {
static void tick_pairs() {
for(size_t i = 0; i < activeCollisionCount;) {
if(--activeCollisions[i].x == 0) {
uint16_t e1 = (uintptr_t) dGeomGetData(activeCollisions[i].g1);
uint16_t e2 = (uintptr_t) dGeomGetData(activeCollisions[i].g2);
uint16_t e1 = activeCollisions[i].e1;
uint16_t e2 = activeCollisions[i].e2;
if(e1 != ENT_ID_INVALID) {
struct CPhysics *p1 = game_getcomponent(e1, physics);
@@ -97,10 +99,21 @@ static void tick_pairs() {
}
}
static void vec3_project_to_plane(vec3 v, vec3 n, vec3 ret) {
float scale = glm_vec3_dot(v, n) / glm_vec3_dot(n, n);
vec3 n2;
glm_vec3_scale(n, scale, n2);
glm_vec3_sub(v, n2, ret);
}
static void contact_callback(void *data, dGeomID g1, dGeomID g2) {
uint16_t e1 = (uintptr_t) dGeomGetData(g1);
uint16_t e2 = (uintptr_t) dGeomGetData(g2);
if(e1 != ENT_ID_INVALID && e1 == e2) return;
dBodyID b1 = dGeomGetBody(g1);
dBodyID b2 = dGeomGetBody(g2);
@@ -124,8 +137,6 @@ static void contact_callback(void *data, dGeomID g1, dGeomID g2) {
if(movingPlatform) {
const dReal *platvel = dBodyGetLinearVel(movingPlatform == 1 ? b1 : b2);
//if(i == 0)printf("get %f %f %f\n", platvel[0], platvel[1], platvel[2]);
contact[i].surface.mode |= dContactMotion1 | dContactMotion2 | dContactMotionN | dContactFDir1;
contact[i].surface.mode |= dContactSoftERP;
contact[i].surface.soft_erp = 0.9;
@@ -146,17 +157,42 @@ static void contact_callback(void *data, dGeomID g1, dGeomID g2) {
int ghost = 0;
if(dGeomGetCategoryBits(g1) & CATEGORY_GHOST) ghost = 1;
if(dGeomGetCategoryBits(g2) & CATEGORY_GHOST) ghost = 1;
if(numc) {
int triggerType = activate_pair(g1, g2);
int triggerType = activate_pair(e1, e2);
if(e1 != ENT_ID_INVALID) {
if(game_getcomponent(e1, physics)->dynamics & CPHYSICS_GHOST) {
struct CPhysics *cp = game_getcomponent(e1, physics);
if(!cp) {
// Entity being killed maybe
return;
}
if(cp->dynamics & CPHYSICS_GHOST) {
ghost = 1;
}
struct CMovement *cm = game_getcomponent(e1, movement);
if(cm && cm->holding != ENT_ID_INVALID && cm->holding == e2) {
ghost = 1;
}
}
if(e2 != ENT_ID_INVALID) {
if(game_getcomponent(e2, physics)->dynamics & CPHYSICS_GHOST) {
struct CPhysics *cp = game_getcomponent(e2, physics);
if(!cp) {
// Entity being killed maybe
return;
}
if(cp->dynamics & CPHYSICS_GHOST) {
ghost = 1;
}
struct CMovement *cm = game_getcomponent(e2, movement);
if(cm && cm->holding != ENT_ID_INVALID && cm->holding == e1) {
ghost = 1;
}
}
@@ -168,37 +204,6 @@ static void contact_callback(void *data, dGeomID g1, dGeomID g2) {
friction *= c->friction;
vec4 q;
if(b1) {
memcpy(q, dBodyGetQuaternion(b1), sizeof(q));
} else {
dGeomGetQuaternion(c->geom, q);
}
{
float temp = q[0];
q[0] = q[1];
q[1] = q[2];
q[2] = q[3];
q[3] = temp;
}
vec3 n = {0, 1, 0};
glm_quat_rotatev(q, n, n);
if(!ghost) for(int i = 0; i < numc; i++) {
if(glm_vec3_dot(contact[i].geom.normal, n) >= 0.7) {
struct CMovement *m = game_getcomponent(e1, movement);
if(m) {
if(m->holding != ENT_ID_INVALID && m->holding == e2) {
ghost = 1;
}
m->canJump = 1;
break;
}
}
}
if(c->trigger != TRIGGER_INVALID) {
Game.triggers[c->trigger - 1](c->trigger, e1, e2, triggerType);
}
@@ -209,37 +214,6 @@ static void contact_callback(void *data, dGeomID g1, dGeomID g2) {
friction *= c->friction;
vec4 q;
if(b2) {
memcpy(q, dBodyGetQuaternion(b2), sizeof(q));
} else {
dGeomGetQuaternion(c->geom, q);
}
{
float temp = q[0];
q[0] = q[1];
q[1] = q[2];
q[2] = q[3];
q[3] = temp;
}
vec3 n = {0, -1, 0};
glm_quat_rotatev(q, n, n);
if(!ghost) for(int i = 0; i < numc; i++) {
if(glm_vec3_dot(contact[i].geom.normal, n) >= 0.7) {
struct CMovement *m = game_getcomponent(e2, movement);
if(m) {
if(m->holding != ENT_ID_INVALID && m->holding == e1) {
ghost = 1;
}
m->canJump = 1;
break;
}
}
}
if(c->trigger != TRIGGER_INVALID) {
Game.triggers[c->trigger - 1](c->trigger, e2, e1, triggerType);
}
@@ -337,7 +311,102 @@ void game_raycast(struct LocalRay *rays, size_t count) {
}
}
static void game_character_controller_raycast_handler(void *data, dGeomID g1, dGeomID g2) {
if(dGeomGetClass(g1) != dRayClass && dGeomGetClass(g2) != dRayClass) {
return;
}
uint16_t e1 = (uintptr_t) dGeomGetData(g1);
uint16_t e2 = (uintptr_t) dGeomGetData(g2);
if(e1 == e2) {
// This means the ray is hitting the entity casting it.
return;
}
dContact contact[1];
memset(contact, 0, sizeof(contact));
int numc = dCollide(g1, g2, 1, &contact[0].geom, sizeof(dContact));
if(numc) {
vec3 n = {0, -1, 0};
struct CPhysics *cp1 = game_getcomponent(e1, physics);
struct CPhysics *cp2 = game_getcomponent(e2, physics);
if((cp2 && (cp2->dynamics & CPHYSICS_GHOST)) || (cp1 && (cp1->dynamics & CPHYSICS_GHOST))) {
return;
}
if(dGeomGetClass(g1) == dRayClass) {
dBodyID bid = dGeomGetBody(cp1->geom);
struct CMovement *cm = game_getcomponent(e1, movement);
cm->groundDepth = dGeomRayGetLength(g1) - contact[0].geom.depth;
if(glm_vec3_dot(contact[0].geom.normal, n) <= -0.7 && cm->groundDepth > SUBFEET(cp1)) {
cm->canJump = 1;
glm_vec3_scale(contact[0].geom.normal, -1, cm->groundNormal);
}
} else if(dGeomGetClass(g2) == dRayClass) {
dBodyID bid = dGeomGetBody(cp2->geom);
struct CMovement *cm = game_getcomponent(e2, movement);
cm->groundDepth = dGeomRayGetLength(g2) - contact[0].geom.depth;
if(glm_vec3_dot(contact[0].geom.normal, n) >= +0.7 && cm->groundDepth > SUBFEET(cp2)) {
cm->canJump = 1;
glm_vec3_scale(contact[0].geom.normal, +1, cm->groundNormal);
}
}
}
}
void game_character_controller_raycast() {
dGeomID rayGeoms[Game.entities.movementCount];
for(size_t i = 0; i < Game.entities.movementCount; i++) {
Game.entities.movement[i].canJump = 0;
}
for(int i = 0; i < Game.entities.movementCount; i++) {
struct CPhysics *cp = game_getcomponent(Game.entities.movement[i].entity, physics);
if(!cp || !cp->geom || cp->type != CPHYSICS_CAPSULE) {
rayGeoms[i] = NULL;
continue;
}
rayGeoms[i] = dCreateRay(Game.space, cp->capsule.length / 2 + cp->capsule.radius + SUBFEET(cp));
dGeomSetData(rayGeoms[i], (void*) (uintptr_t) Game.entities.movement[i].entity);
dGeomSetCategoryBits(rayGeoms[i], CATEGORY_RAY);
dGeomSetCollideBits(rayGeoms[i], CATEGORY_STATIC | CATEGORY_ENTITY);
dBodyID bid = dGeomGetBody(cp->geom);
const float *position = dBodyGetPosition(bid);
dGeomRaySet(rayGeoms[i], position[0], position[1], position[2], 0, -1, 0);
}
dSpaceCollide(Game.space, NULL, game_character_controller_raycast_handler);
for(int i = 0; i < Game.entities.movementCount; i++) {
if(rayGeoms[i]) {
dGeomDestroy(rayGeoms[i]);
}
}
}
void game_update() {
game_character_controller_raycast();
for(size_t i = 0; i < Game.entities.playerctrlCount; i++) {
struct CPlayerCtrl *cc = &Game.entities.playerctrl[i];
@@ -383,9 +452,18 @@ void game_update() {
if(cp && cp->geom) {
dBodyID bid = dGeomGetBody(cp->geom);
if(Game.entities.movement[i].canJump) {
dBodySetLinearVel(bid, 0, 0, 0);
if(dBodyGetLinearVel(bid)[1] <= 0) {
Game.entities.movement[i].isJumping = false;
}
if(!Game.entities.movement[i].isJumping) {
const float *pos = dBodyGetPosition(bid);
dBodySetPosition(bid, pos[0], pos[1] + Game.entities.movement[i].groundDepth - cp->capsule.radius / 2 - SUBFEET(cp), pos[2]);
dBodySetLinearVel(bid, 0, 0, 0);
}
}
dBodySetGravityMode(bid, !Game.entities.movement[i].canJump);
dBodySetGravityMode(bid, Game.entities.movement[i].canJump && !Game.entities.movement[i].isJumping ? 0 : 1);
}
}
@@ -421,14 +499,21 @@ void game_update() {
Game.entities.physics[i].box.l);
break;
case CPHYSICS_CAPSULE:
Game.entities.physics[i].geom = dCreateCapsule(Game.space,
case CPHYSICS_CAPSULE: {
dGeomID top = dCreateCapsule(Game.space,
Game.entities.physics[i].capsule.radius,
Game.entities.physics[i].capsule.length);
Game.entities.physics[i].capsule.length - Game.entities.physics[i].capsule.radius);
dGeomID feet = dCreateSphere(Game.space,
Game.entities.physics[i].capsule.radius);
Game.entities.physics[i].geom = top;
Game.entities.physics[i].geom2 = feet;
dMassSetCapsuleTotal(&mass, Game.entities.physics[i].mass, 2, Game.entities.physics[i].capsule.radius, Game.entities.physics[i].capsule.length);
break;
}
case CPHYSICS_SPHERE:
Game.entities.physics[i].geom = dCreateSphere(Game.space,
Game.entities.physics[i].sphere.radius);
@@ -442,6 +527,12 @@ void game_update() {
dGeomSetCollideBits(Game.entities.physics[i].geom, Game.entities.physics[i].collide);
dGeomSetData(Game.entities.physics[i].geom, (void*) Game.entities.physics[i].entity);
if(Game.entities.physics[i].type == CPHYSICS_CAPSULE) {
dGeomSetCategoryBits(Game.entities.physics[i].geom2, CATEGORY_ENTITY | CATEGORY_GHOST);
dGeomSetCollideBits(Game.entities.physics[i].geom2, Game.entities.physics[i].collide);
dGeomSetData(Game.entities.physics[i].geom2, (void*) Game.entities.physics[i].entity);
}
if((Game.entities.physics[i].dynamics & ~CPHYSICS_GHOST) != CPHYSICS_STATIC) {
dBodyID body = dBodyCreate(Game.phys);
@@ -452,10 +543,16 @@ void game_update() {
}
dGeomSetBody(Game.entities.physics[i].geom, body);
if(Game.entities.physics[i].geom2) {
dGeomSetBody(Game.entities.physics[i].geom2, body);
}
if(Game.entities.physics[i].type == CPHYSICS_CAPSULE) {
dBodySetMaxAngularSpeed(body, 0);
dGeomSetOffsetPosition(Game.entities.physics[i].geom, 0, Game.entities.physics[i].capsule.radius / 2, 0);
dGeomSetOffsetPosition(Game.entities.physics[i].geom2, 0, -Game.entities.physics[i].capsule.length / 2, 0);
// Rotate to Y-up
dQuaternion q;
dQFromAxisAndAngle(q, 1, 0, 0, M_PI * 0.5);
@@ -516,6 +613,10 @@ void game_update() {
if(glm_vec3_norm(wishvel) > 3) {
glm_vec3_scale_as(wishvel, 3, wishvel);
}
} else {
// We project the movement vector onto the ground plane (set by game_character_controller_raycast_handler)
// to "slide" along the ground with minimal bouncing
vec3_project_to_plane(wishvel, Game.entities.movement[mi].groundNormal, wishvel);
}
float currentspeed = glm_vec3_dot(wishvel, dBodyGetLinearVel(bid));
@@ -538,23 +639,19 @@ void game_update() {
dQFromAxisAndAngle(q, 0, 1, 0, Game.entities.movement[mi].pointing + M_PI);
dBodySetQuaternion(bid, q);
if(Game.entities.movement[mi].jump && (0||Game.entities.movement[mi].canJump)) {
Game.entities.movement[mi].canJump = 0;
dVector3 force;
dWorldImpulseToForce(Game.phys, 1.f / GAME_TPS, 0, 5, 0, force);
if(Game.entities.movement[mi].jump && Game.entities.movement[mi].canJump) {
dVector3 force = {};
dWorldImpulseToForce(Game.phys, 1.f / GAME_TPS, 0, 6.5, 0, force);
if(bid) {
dBodyAddForce(bid, force[0], force[1], force[2]);
}
Game.entities.movement[mi].isJumping = true;
}
}
}
for(size_t i = 0; i < Game.entities.movementCount; i++) {
Game.entities.movement[i].canJump = 0;
}
dSpaceCollide(Game.space, 0, &contact_callback);
tick_pairs();
@@ -588,7 +685,7 @@ void game_update() {
size_t boneCount = Game.entities.render[ci].cache ? k3MdlGetBoneCount(Game.entities.render[ci].cache) : 0;
if(boneCount) {
struct CBoned *cb = game_getcomponent(Game.entities.render[ci].entity, boned);
/*struct CBoned *cb = game_getcomponent(Game.entities.render[ci].entity, boned);
if(!cb) {
cb = game_ensurecomponent(Game.entities.render[ci].entity, boned);
@@ -644,7 +741,7 @@ void game_update() {
glm_decompose(cb->anim.cache.inter[m], cb->bones[m].translation, rot, scaleignore);
glm_mat4_quat(cb->anim.cache.inter[m], cb->bones[m].rotation);
}
}
}*/
}
dGeomID gid = cp->geom;
@@ -679,7 +776,7 @@ void game_update() {
for(size_t cm = 0; cm < Game.entities.movementCount; cm++) {
struct CBoned *cb = game_getcomponent(Game.entities.movement[cm].entity, boned);
if(cb && cb->anim.standard) {
/*if(cb && cb->anim.standard) {
struct CPhysics *cp = game_getcomponent(Game.entities.movement[cm].entity, physics);
if(cp && cp->geom) {
dBodyID bid = dGeomGetBody(cp->geom);
@@ -692,7 +789,7 @@ void game_update() {
}
}
}
}
}*/
}
for(size_t i = 0; i < Game.conveyorCount; i++) {
@@ -779,7 +876,6 @@ void game_update() {
vec3 dif;
glm_vec3_sub(conveyor->points[nextPoint], conveyor->points[currentPoint], dif);
glm_vec3_scale_as(dif, conveyor->speed * (conveyor->active <= 0 ? -1 : 1), dif);
//printf("set %f %f %f\n", dif[0], dif[1], dif[2]);
dBodySetLinearVel(bid, dif[0], dif[1], dif[2]); // doesn't affect movement, but necessary for proper collision response
}
}
@@ -853,7 +949,7 @@ void game_cleanup() {
Game.entities.renderCount = 0;
for(size_t i = 0; i < Game.entities.bonedCount; i++) {
free(Game.entities.boned[i].bones);
//free(Game.entities.boned[i].bones);
}
Game.entities.bonedCount = 0;
@@ -889,10 +985,46 @@ void game_cleanup() {
Game.phys = dWorldCreate();
dWorldSetGravity(Game.phys, 0, -15, 0);
dWorldSetCFM(Game.phys, 0.0001);
dWorldSetERP(Game.phys, 0.5);
dWorldSetCFM(Game.phys, 0.00002);
dWorldSetERP(Game.phys, 0.1);
Game.space = dHashSpaceCreate(NULL);
Game.contactgroup = dJointGroupCreate(0);
}
void game_killentity(uint16_t eid) {
// XXX: Go over ALL component types!
struct CPhysics *cp = game_getcomponent(eid, physics);
if(cp) {
dBodyID bid = dGeomGetBody(cp->geom);
if(bid) {
for(dGeomID gid = dBodyGetFirstGeom(bid); gid; gid = dBodyGetNextGeom(gid)) {
dGeomDestroy(gid);
}
dBodyDestroy(bid);
} else {
dGeomDestroy(cp->geom);
}
game_killcomponent_ptr(cp, physics);
}
struct CRender *cr = game_getcomponent(eid, render);
if(cr) {
if(cr->cache) {
if(resman_rev(cr->cache)) {
resman_unref_ptr(RESMAN_MODEL, cr->cache);
}
}
game_killcomponent_ptr(cr, render);
}
game_killcomponent(eid, movement);
game_killcomponent(eid, playerctrl);
game_killcomponent(eid, boned);
}

View File

@@ -13,6 +13,7 @@
#define CATEGORY_STATIC 1
#define CATEGORY_RAY 2
#define CATEGORY_ENTITY 4
#define CATEGORY_GHOST 8
#define TRIGGER_INVALID 0
@@ -47,7 +48,7 @@ struct TrimeshData {
#define CPHYSICS_GHOST 128
struct CPhysics {
uint16_t entity;
dGeomID geom;
dGeomID geom, geom2;
uint16_t trigger;
uint8_t type;
@@ -87,7 +88,9 @@ struct CMovement {
uint16_t entity;
vec3 dir;
float pointing;
char jump, canJump;
char jump, canJump, isJumping;
vec3 groundNormal;
float groundDepth;
uint16_t holding;
};
@@ -115,14 +118,7 @@ struct CPlayerCtrl {
struct CBoned {
uint16_t entity;
size_t size;
struct k3AnimationBone *bones;
struct {
uint16_t id;
struct k3Animator cache;
bool standard;
} anim;
struct k3Animator animator;
};
#define CONVEYOR_TYPE_LOOP 0
@@ -248,7 +244,22 @@ static inline void *game_ensurecomponent_(uint16_t eid, void *array, size_t comp
return ptr;
}
#define game_killcomponent_ptr(c, arr) do { \
size_t idx = c - Game.entities.arr; \
memmove(c, c + 1, sizeof(*c) * (Game.entities.arr##Count - idx - 1)); \
Game.entities.arr##Count--; \
} while(0);
#define game_killcomponent(eid, arr) do { \
typeof(&Game.entities.arr[0]) c = game_getcomponent(eid, arr); \
if(c) { \
game_killcomponent_ptr(c, arr); \
} \
} while(0);
// An artifact of using a third-party physics engine
void game_synccphysics();
void game_cleanup();
void game_killentity(uint16_t eid);

219
src/gl.h
View File

@@ -1,11 +1,11 @@
/**
* Loader generated by glad 2.0.8 on Sun Nov 17 08:36:10 2024
* Loader generated by glad 2.0.8 on Sun Oct 12 16:54:54 2025
*
* SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0
*
* Generator: C/C++
* Specification: gl
* Extensions: 31
* Extensions: 40
*
* APIs:
* - gl:compatibility=4.6
@@ -19,10 +19,10 @@
* - ON_DEMAND = False
*
* Commandline:
* --api='gl:compatibility=4.6' --extensions='GL_ARB_compatibility,GL_ARB_debug_output,GL_ARB_fragment_program,GL_ARB_fragment_shader,GL_ARB_framebuffer_sRGB,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_storage_buffer_object,GL_ARB_shading_language_100,GL_ARB_texture_float,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_2_10_10_10_rev,GL_EXT_direct_state_access,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_geometry_shader4,GL_EXT_gpu_shader4,GL_EXT_shader_image_load_store,GL_EXT_texture_array,GL_EXT_texture_compression_s3tc,GL_EXT_texture_integer,GL_EXT_texture_sRGB,GL_EXT_transform_feedback,GL_INTEL_conservative_rasterization,GL_NV_conservative_raster' c --header-only
* --api='gl:compatibility=4.6' --extensions='GL_ARB_compatibility,GL_ARB_debug_output,GL_ARB_direct_state_access,GL_ARB_fragment_program,GL_ARB_fragment_shader,GL_ARB_framebuffer_sRGB,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_storage_buffer_object,GL_ARB_shading_language_100,GL_ARB_texture_compression_bptc,GL_ARB_texture_float,GL_ARB_texture_rg,GL_ARB_texture_rgb10_a2ui,GL_ARB_timer_query,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_ARB_vertex_type_2_10_10_10_rev,GL_EXT_direct_state_access,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_multisample_blit_scaled,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_geometry_shader4,GL_EXT_gpu_shader4,GL_EXT_shader_image_load_store,GL_EXT_texture_array,GL_EXT_texture_compression_rgtc,GL_EXT_texture_compression_s3tc,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_integer,GL_EXT_texture_sRGB,GL_EXT_transform_feedback,GL_INTEL_conservative_rasterization,GL_KHR_debug,GL_KHR_texture_compression_astc_ldr,GL_NV_conservative_raster' c --header-only
*
* Online:
* http://glad.sh/#api=gl%3Acompatibility%3D4.6&extensions=GL_ARB_compatibility%2CGL_ARB_debug_output%2CGL_ARB_fragment_program%2CGL_ARB_fragment_shader%2CGL_ARB_framebuffer_sRGB%2CGL_ARB_shader_image_load_store%2CGL_ARB_shader_image_size%2CGL_ARB_shader_objects%2CGL_ARB_shader_storage_buffer_object%2CGL_ARB_shading_language_100%2CGL_ARB_texture_float%2CGL_ARB_texture_rg%2CGL_ARB_texture_rgb10_a2ui%2CGL_ARB_vertex_buffer_object%2CGL_ARB_vertex_program%2CGL_ARB_vertex_shader%2CGL_ARB_vertex_type_2_10_10_10_rev%2CGL_EXT_direct_state_access%2CGL_EXT_framebuffer_blit%2CGL_EXT_framebuffer_object%2CGL_EXT_framebuffer_sRGB%2CGL_EXT_geometry_shader4%2CGL_EXT_gpu_shader4%2CGL_EXT_shader_image_load_store%2CGL_EXT_texture_array%2CGL_EXT_texture_compression_s3tc%2CGL_EXT_texture_integer%2CGL_EXT_texture_sRGB%2CGL_EXT_transform_feedback%2CGL_INTEL_conservative_rasterization%2CGL_NV_conservative_raster&generator=c&options=HEADER_ONLY
* http://glad.sh/#api=gl%3Acompatibility%3D4.6&extensions=GL_ARB_compatibility%2CGL_ARB_debug_output%2CGL_ARB_direct_state_access%2CGL_ARB_fragment_program%2CGL_ARB_fragment_shader%2CGL_ARB_framebuffer_sRGB%2CGL_ARB_shader_image_load_store%2CGL_ARB_shader_image_size%2CGL_ARB_shader_objects%2CGL_ARB_shader_storage_buffer_object%2CGL_ARB_shading_language_100%2CGL_ARB_texture_compression_bptc%2CGL_ARB_texture_float%2CGL_ARB_texture_rg%2CGL_ARB_texture_rgb10_a2ui%2CGL_ARB_timer_query%2CGL_ARB_vertex_buffer_object%2CGL_ARB_vertex_program%2CGL_ARB_vertex_shader%2CGL_ARB_vertex_type_2_10_10_10_rev%2CGL_EXT_direct_state_access%2CGL_EXT_framebuffer_blit%2CGL_EXT_framebuffer_multisample%2CGL_EXT_framebuffer_multisample_blit_scaled%2CGL_EXT_framebuffer_object%2CGL_EXT_framebuffer_sRGB%2CGL_EXT_geometry_shader4%2CGL_EXT_gpu_shader4%2CGL_EXT_shader_image_load_store%2CGL_EXT_texture_array%2CGL_EXT_texture_compression_rgtc%2CGL_EXT_texture_compression_s3tc%2CGL_EXT_texture_filter_anisotropic%2CGL_EXT_texture_integer%2CGL_EXT_texture_sRGB%2CGL_EXT_transform_feedback%2CGL_INTEL_conservative_rasterization%2CGL_KHR_debug%2CGL_KHR_texture_compression_astc_ldr%2CGL_NV_conservative_raster&generator=c&options=HEADER_ONLY
*
*/
@@ -465,7 +465,9 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
#define GL_COMPRESSED_R11_EAC 0x9270
#define GL_COMPRESSED_RED 0x8225
#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD
#define GL_COMPRESSED_RED_RGTC1 0x8DBB
#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB
#define GL_COMPRESSED_RG 0x8226
#define GL_COMPRESSED_RG11_EAC 0x9272
#define GL_COMPRESSED_RGB 0x84ED
@@ -473,16 +475,35 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
#define GL_COMPRESSED_RGBA 0x84EE
#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C
#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E
#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
#define GL_COMPRESSED_RG_RGTC2 0x8DBD
#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC
#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
#define GL_COMPRESSED_SLUMINANCE 0x8C4A
@@ -490,11 +511,26 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
#define GL_COMPRESSED_SRGB 0x8C48
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
#define GL_COMPRESSED_SRGB8_ETC2 0x9275
#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
#define GL_COMPRESSED_SRGB_ALPHA 0x8C49
#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D
#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D
#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
@@ -833,6 +869,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
#define GL_FRAMEBUFFER_RENDERABLE 0x8289
@@ -1335,6 +1372,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
#define GL_MAX_SAMPLES 0x8D57
#define GL_MAX_SAMPLES_EXT 0x8D57
#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE
@@ -1370,6 +1408,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872
#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
#define GL_MAX_TEXTURE_SIZE 0x0D33
#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39
#define GL_MAX_TEXTURE_UNITS 0x84E2
@@ -1730,6 +1769,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#define GL_RENDERBUFFER_RED_SIZE 0x8D50
#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50
#define GL_RENDERBUFFER_SAMPLES 0x8CAB
#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55
#define GL_RENDERBUFFER_WIDTH 0x8D42
@@ -1864,6 +1904,8 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#define GL_SAMPLE_MASK_VALUE 0x8E52
#define GL_SAMPLE_POSITION 0x8E50
#define GL_SAMPLE_SHADING 0x8C36
#define GL_SCALED_RESOLVE_FASTEST_EXT 0x90BA
#define GL_SCALED_RESOLVE_NICEST_EXT 0x90BB
#define GL_SCISSOR_BIT 0x00080000
#define GL_SCISSOR_BOX 0x0C10
#define GL_SCISSOR_TEST 0x0C11
@@ -2174,6 +2216,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
#define GL_TEXTURE_MAG_FILTER 0x2800
#define GL_TEXTURE_MATRIX 0x0BA8
#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
#define GL_TEXTURE_MAX_LEVEL 0x813D
#define GL_TEXTURE_MAX_LOD 0x813B
#define GL_TEXTURE_MIN_FILTER 0x2801
@@ -2873,6 +2916,8 @@ GLAD_API_CALL int GLAD_GL_VERSION_4_6;
GLAD_API_CALL int GLAD_GL_ARB_compatibility;
#define GL_ARB_debug_output 1
GLAD_API_CALL int GLAD_GL_ARB_debug_output;
#define GL_ARB_direct_state_access 1
GLAD_API_CALL int GLAD_GL_ARB_direct_state_access;
#define GL_ARB_fragment_program 1
GLAD_API_CALL int GLAD_GL_ARB_fragment_program;
#define GL_ARB_fragment_shader 1
@@ -2889,12 +2934,16 @@ GLAD_API_CALL int GLAD_GL_ARB_shader_objects;
GLAD_API_CALL int GLAD_GL_ARB_shader_storage_buffer_object;
#define GL_ARB_shading_language_100 1
GLAD_API_CALL int GLAD_GL_ARB_shading_language_100;
#define GL_ARB_texture_compression_bptc 1
GLAD_API_CALL int GLAD_GL_ARB_texture_compression_bptc;
#define GL_ARB_texture_float 1
GLAD_API_CALL int GLAD_GL_ARB_texture_float;
#define GL_ARB_texture_rg 1
GLAD_API_CALL int GLAD_GL_ARB_texture_rg;
#define GL_ARB_texture_rgb10_a2ui 1
GLAD_API_CALL int GLAD_GL_ARB_texture_rgb10_a2ui;
#define GL_ARB_timer_query 1
GLAD_API_CALL int GLAD_GL_ARB_timer_query;
#define GL_ARB_vertex_buffer_object 1
GLAD_API_CALL int GLAD_GL_ARB_vertex_buffer_object;
#define GL_ARB_vertex_program 1
@@ -2907,6 +2956,10 @@ GLAD_API_CALL int GLAD_GL_ARB_vertex_type_2_10_10_10_rev;
GLAD_API_CALL int GLAD_GL_EXT_direct_state_access;
#define GL_EXT_framebuffer_blit 1
GLAD_API_CALL int GLAD_GL_EXT_framebuffer_blit;
#define GL_EXT_framebuffer_multisample 1
GLAD_API_CALL int GLAD_GL_EXT_framebuffer_multisample;
#define GL_EXT_framebuffer_multisample_blit_scaled 1
GLAD_API_CALL int GLAD_GL_EXT_framebuffer_multisample_blit_scaled;
#define GL_EXT_framebuffer_object 1
GLAD_API_CALL int GLAD_GL_EXT_framebuffer_object;
#define GL_EXT_framebuffer_sRGB 1
@@ -2919,8 +2972,12 @@ GLAD_API_CALL int GLAD_GL_EXT_gpu_shader4;
GLAD_API_CALL int GLAD_GL_EXT_shader_image_load_store;
#define GL_EXT_texture_array 1
GLAD_API_CALL int GLAD_GL_EXT_texture_array;
#define GL_EXT_texture_compression_rgtc 1
GLAD_API_CALL int GLAD_GL_EXT_texture_compression_rgtc;
#define GL_EXT_texture_compression_s3tc 1
GLAD_API_CALL int GLAD_GL_EXT_texture_compression_s3tc;
#define GL_EXT_texture_filter_anisotropic 1
GLAD_API_CALL int GLAD_GL_EXT_texture_filter_anisotropic;
#define GL_EXT_texture_integer 1
GLAD_API_CALL int GLAD_GL_EXT_texture_integer;
#define GL_EXT_texture_sRGB 1
@@ -2929,6 +2986,10 @@ GLAD_API_CALL int GLAD_GL_EXT_texture_sRGB;
GLAD_API_CALL int GLAD_GL_EXT_transform_feedback;
#define GL_INTEL_conservative_rasterization 1
GLAD_API_CALL int GLAD_GL_INTEL_conservative_rasterization;
#define GL_KHR_debug 1
GLAD_API_CALL int GLAD_GL_KHR_debug;
#define GL_KHR_texture_compression_astc_ldr 1
GLAD_API_CALL int GLAD_GL_KHR_texture_compression_astc_ldr;
#define GL_NV_conservative_raster 1
GLAD_API_CALL int GLAD_GL_NV_conservative_raster;
@@ -3949,6 +4010,7 @@ typedef GLint (GLAD_API_PTR *PFNGLRENDERMODEPROC)(GLenum mode);
typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEEXTPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
typedef void (GLAD_API_PTR *PFNGLRESUMETRANSFORMFEEDBACKPROC)(void);
typedef void (GLAD_API_PTR *PFNGLROTATEDPROC)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
typedef void (GLAD_API_PTR *PFNGLROTATEFPROC)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
@@ -6458,6 +6520,8 @@ GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT;
#define glRenderbufferStorageEXT glad_glRenderbufferStorageEXT
GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample;
#define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample
GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT;
#define glRenderbufferStorageMultisampleEXT glad_glRenderbufferStorageMultisampleEXT
GLAD_API_CALL PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback;
#define glResumeTransformFeedback glad_glResumeTransformFeedback
GLAD_API_CALL PFNGLROTATEDPROC glad_glRotated;
@@ -7472,6 +7536,7 @@ int GLAD_GL_VERSION_4_5 = 0;
int GLAD_GL_VERSION_4_6 = 0;
int GLAD_GL_ARB_compatibility = 0;
int GLAD_GL_ARB_debug_output = 0;
int GLAD_GL_ARB_direct_state_access = 0;
int GLAD_GL_ARB_fragment_program = 0;
int GLAD_GL_ARB_fragment_shader = 0;
int GLAD_GL_ARB_framebuffer_sRGB = 0;
@@ -7480,26 +7545,34 @@ int GLAD_GL_ARB_shader_image_size = 0;
int GLAD_GL_ARB_shader_objects = 0;
int GLAD_GL_ARB_shader_storage_buffer_object = 0;
int GLAD_GL_ARB_shading_language_100 = 0;
int GLAD_GL_ARB_texture_compression_bptc = 0;
int GLAD_GL_ARB_texture_float = 0;
int GLAD_GL_ARB_texture_rg = 0;
int GLAD_GL_ARB_texture_rgb10_a2ui = 0;
int GLAD_GL_ARB_timer_query = 0;
int GLAD_GL_ARB_vertex_buffer_object = 0;
int GLAD_GL_ARB_vertex_program = 0;
int GLAD_GL_ARB_vertex_shader = 0;
int GLAD_GL_ARB_vertex_type_2_10_10_10_rev = 0;
int GLAD_GL_EXT_direct_state_access = 0;
int GLAD_GL_EXT_framebuffer_blit = 0;
int GLAD_GL_EXT_framebuffer_multisample = 0;
int GLAD_GL_EXT_framebuffer_multisample_blit_scaled = 0;
int GLAD_GL_EXT_framebuffer_object = 0;
int GLAD_GL_EXT_framebuffer_sRGB = 0;
int GLAD_GL_EXT_geometry_shader4 = 0;
int GLAD_GL_EXT_gpu_shader4 = 0;
int GLAD_GL_EXT_shader_image_load_store = 0;
int GLAD_GL_EXT_texture_array = 0;
int GLAD_GL_EXT_texture_compression_rgtc = 0;
int GLAD_GL_EXT_texture_compression_s3tc = 0;
int GLAD_GL_EXT_texture_filter_anisotropic = 0;
int GLAD_GL_EXT_texture_integer = 0;
int GLAD_GL_EXT_texture_sRGB = 0;
int GLAD_GL_EXT_transform_feedback = 0;
int GLAD_GL_INTEL_conservative_rasterization = 0;
int GLAD_GL_KHR_debug = 0;
int GLAD_GL_KHR_texture_compression_astc_ldr = 0;
int GLAD_GL_NV_conservative_raster = 0;
@@ -8520,6 +8593,7 @@ PFNGLRENDERMODEPROC glad_glRenderMode = NULL;
PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL;
PFNGLRENDERBUFFERSTORAGEEXTPROC glad_glRenderbufferStorageEXT = NULL;
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample = NULL;
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT = NULL;
PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback = NULL;
PFNGLROTATEDPROC glad_glRotated = NULL;
PFNGLROTATEFPROC glad_glRotatef = NULL;
@@ -10114,6 +10188,106 @@ static void glad_gl_load_GL_ARB_debug_output( GLADuserptrloadfunc load, void* us
glad_glDebugMessageInsertARB = (PFNGLDEBUGMESSAGEINSERTARBPROC) load(userptr, "glDebugMessageInsertARB");
glad_glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC) load(userptr, "glGetDebugMessageLogARB");
}
static void glad_gl_load_GL_ARB_direct_state_access( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_GL_ARB_direct_state_access) return;
glad_glBindTextureUnit = (PFNGLBINDTEXTUREUNITPROC) load(userptr, "glBindTextureUnit");
glad_glBlitNamedFramebuffer = (PFNGLBLITNAMEDFRAMEBUFFERPROC) load(userptr, "glBlitNamedFramebuffer");
glad_glCheckNamedFramebufferStatus = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) load(userptr, "glCheckNamedFramebufferStatus");
glad_glClearNamedBufferData = (PFNGLCLEARNAMEDBUFFERDATAPROC) load(userptr, "glClearNamedBufferData");
glad_glClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATAPROC) load(userptr, "glClearNamedBufferSubData");
glad_glClearNamedFramebufferfi = (PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) load(userptr, "glClearNamedFramebufferfi");
glad_glClearNamedFramebufferfv = (PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) load(userptr, "glClearNamedFramebufferfv");
glad_glClearNamedFramebufferiv = (PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) load(userptr, "glClearNamedFramebufferiv");
glad_glClearNamedFramebufferuiv = (PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) load(userptr, "glClearNamedFramebufferuiv");
glad_glCompressedTextureSubImage1D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) load(userptr, "glCompressedTextureSubImage1D");
glad_glCompressedTextureSubImage2D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) load(userptr, "glCompressedTextureSubImage2D");
glad_glCompressedTextureSubImage3D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) load(userptr, "glCompressedTextureSubImage3D");
glad_glCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATAPROC) load(userptr, "glCopyNamedBufferSubData");
glad_glCopyTextureSubImage1D = (PFNGLCOPYTEXTURESUBIMAGE1DPROC) load(userptr, "glCopyTextureSubImage1D");
glad_glCopyTextureSubImage2D = (PFNGLCOPYTEXTURESUBIMAGE2DPROC) load(userptr, "glCopyTextureSubImage2D");
glad_glCopyTextureSubImage3D = (PFNGLCOPYTEXTURESUBIMAGE3DPROC) load(userptr, "glCopyTextureSubImage3D");
glad_glCreateBuffers = (PFNGLCREATEBUFFERSPROC) load(userptr, "glCreateBuffers");
glad_glCreateFramebuffers = (PFNGLCREATEFRAMEBUFFERSPROC) load(userptr, "glCreateFramebuffers");
glad_glCreateProgramPipelines = (PFNGLCREATEPROGRAMPIPELINESPROC) load(userptr, "glCreateProgramPipelines");
glad_glCreateQueries = (PFNGLCREATEQUERIESPROC) load(userptr, "glCreateQueries");
glad_glCreateRenderbuffers = (PFNGLCREATERENDERBUFFERSPROC) load(userptr, "glCreateRenderbuffers");
glad_glCreateSamplers = (PFNGLCREATESAMPLERSPROC) load(userptr, "glCreateSamplers");
glad_glCreateTextures = (PFNGLCREATETEXTURESPROC) load(userptr, "glCreateTextures");
glad_glCreateTransformFeedbacks = (PFNGLCREATETRANSFORMFEEDBACKSPROC) load(userptr, "glCreateTransformFeedbacks");
glad_glCreateVertexArrays = (PFNGLCREATEVERTEXARRAYSPROC) load(userptr, "glCreateVertexArrays");
glad_glDisableVertexArrayAttrib = (PFNGLDISABLEVERTEXARRAYATTRIBPROC) load(userptr, "glDisableVertexArrayAttrib");
glad_glEnableVertexArrayAttrib = (PFNGLENABLEVERTEXARRAYATTRIBPROC) load(userptr, "glEnableVertexArrayAttrib");
glad_glFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) load(userptr, "glFlushMappedNamedBufferRange");
glad_glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC) load(userptr, "glGenerateTextureMipmap");
glad_glGetCompressedTextureImage = (PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) load(userptr, "glGetCompressedTextureImage");
glad_glGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) load(userptr, "glGetNamedBufferParameteri64v");
glad_glGetNamedBufferParameteriv = (PFNGLGETNAMEDBUFFERPARAMETERIVPROC) load(userptr, "glGetNamedBufferParameteriv");
glad_glGetNamedBufferPointerv = (PFNGLGETNAMEDBUFFERPOINTERVPROC) load(userptr, "glGetNamedBufferPointerv");
glad_glGetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATAPROC) load(userptr, "glGetNamedBufferSubData");
glad_glGetNamedFramebufferAttachmentParameteriv = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load(userptr, "glGetNamedFramebufferAttachmentParameteriv");
glad_glGetNamedFramebufferParameteriv = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) load(userptr, "glGetNamedFramebufferParameteriv");
glad_glGetNamedRenderbufferParameteriv = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) load(userptr, "glGetNamedRenderbufferParameteriv");
glad_glGetQueryBufferObjecti64v = (PFNGLGETQUERYBUFFEROBJECTI64VPROC) load(userptr, "glGetQueryBufferObjecti64v");
glad_glGetQueryBufferObjectiv = (PFNGLGETQUERYBUFFEROBJECTIVPROC) load(userptr, "glGetQueryBufferObjectiv");
glad_glGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECTUI64VPROC) load(userptr, "glGetQueryBufferObjectui64v");
glad_glGetQueryBufferObjectuiv = (PFNGLGETQUERYBUFFEROBJECTUIVPROC) load(userptr, "glGetQueryBufferObjectuiv");
glad_glGetTextureImage = (PFNGLGETTEXTUREIMAGEPROC) load(userptr, "glGetTextureImage");
glad_glGetTextureLevelParameterfv = (PFNGLGETTEXTURELEVELPARAMETERFVPROC) load(userptr, "glGetTextureLevelParameterfv");
glad_glGetTextureLevelParameteriv = (PFNGLGETTEXTURELEVELPARAMETERIVPROC) load(userptr, "glGetTextureLevelParameteriv");
glad_glGetTextureParameterIiv = (PFNGLGETTEXTUREPARAMETERIIVPROC) load(userptr, "glGetTextureParameterIiv");
glad_glGetTextureParameterIuiv = (PFNGLGETTEXTUREPARAMETERIUIVPROC) load(userptr, "glGetTextureParameterIuiv");
glad_glGetTextureParameterfv = (PFNGLGETTEXTUREPARAMETERFVPROC) load(userptr, "glGetTextureParameterfv");
glad_glGetTextureParameteriv = (PFNGLGETTEXTUREPARAMETERIVPROC) load(userptr, "glGetTextureParameteriv");
glad_glGetTransformFeedbacki64_v = (PFNGLGETTRANSFORMFEEDBACKI64_VPROC) load(userptr, "glGetTransformFeedbacki64_v");
glad_glGetTransformFeedbacki_v = (PFNGLGETTRANSFORMFEEDBACKI_VPROC) load(userptr, "glGetTransformFeedbacki_v");
glad_glGetTransformFeedbackiv = (PFNGLGETTRANSFORMFEEDBACKIVPROC) load(userptr, "glGetTransformFeedbackiv");
glad_glGetVertexArrayIndexed64iv = (PFNGLGETVERTEXARRAYINDEXED64IVPROC) load(userptr, "glGetVertexArrayIndexed64iv");
glad_glGetVertexArrayIndexediv = (PFNGLGETVERTEXARRAYINDEXEDIVPROC) load(userptr, "glGetVertexArrayIndexediv");
glad_glGetVertexArrayiv = (PFNGLGETVERTEXARRAYIVPROC) load(userptr, "glGetVertexArrayiv");
glad_glInvalidateNamedFramebufferData = (PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) load(userptr, "glInvalidateNamedFramebufferData");
glad_glInvalidateNamedFramebufferSubData = (PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) load(userptr, "glInvalidateNamedFramebufferSubData");
glad_glMapNamedBuffer = (PFNGLMAPNAMEDBUFFERPROC) load(userptr, "glMapNamedBuffer");
glad_glMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGEPROC) load(userptr, "glMapNamedBufferRange");
glad_glNamedBufferData = (PFNGLNAMEDBUFFERDATAPROC) load(userptr, "glNamedBufferData");
glad_glNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGEPROC) load(userptr, "glNamedBufferStorage");
glad_glNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATAPROC) load(userptr, "glNamedBufferSubData");
glad_glNamedFramebufferDrawBuffer = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) load(userptr, "glNamedFramebufferDrawBuffer");
glad_glNamedFramebufferDrawBuffers = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) load(userptr, "glNamedFramebufferDrawBuffers");
glad_glNamedFramebufferParameteri = (PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) load(userptr, "glNamedFramebufferParameteri");
glad_glNamedFramebufferReadBuffer = (PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) load(userptr, "glNamedFramebufferReadBuffer");
glad_glNamedFramebufferRenderbuffer = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) load(userptr, "glNamedFramebufferRenderbuffer");
glad_glNamedFramebufferTexture = (PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) load(userptr, "glNamedFramebufferTexture");
glad_glNamedFramebufferTextureLayer = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) load(userptr, "glNamedFramebufferTextureLayer");
glad_glNamedRenderbufferStorage = (PFNGLNAMEDRENDERBUFFERSTORAGEPROC) load(userptr, "glNamedRenderbufferStorage");
glad_glNamedRenderbufferStorageMultisample = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) load(userptr, "glNamedRenderbufferStorageMultisample");
glad_glTextureBuffer = (PFNGLTEXTUREBUFFERPROC) load(userptr, "glTextureBuffer");
glad_glTextureBufferRange = (PFNGLTEXTUREBUFFERRANGEPROC) load(userptr, "glTextureBufferRange");
glad_glTextureParameterIiv = (PFNGLTEXTUREPARAMETERIIVPROC) load(userptr, "glTextureParameterIiv");
glad_glTextureParameterIuiv = (PFNGLTEXTUREPARAMETERIUIVPROC) load(userptr, "glTextureParameterIuiv");
glad_glTextureParameterf = (PFNGLTEXTUREPARAMETERFPROC) load(userptr, "glTextureParameterf");
glad_glTextureParameterfv = (PFNGLTEXTUREPARAMETERFVPROC) load(userptr, "glTextureParameterfv");
glad_glTextureParameteri = (PFNGLTEXTUREPARAMETERIPROC) load(userptr, "glTextureParameteri");
glad_glTextureParameteriv = (PFNGLTEXTUREPARAMETERIVPROC) load(userptr, "glTextureParameteriv");
glad_glTextureStorage1D = (PFNGLTEXTURESTORAGE1DPROC) load(userptr, "glTextureStorage1D");
glad_glTextureStorage2D = (PFNGLTEXTURESTORAGE2DPROC) load(userptr, "glTextureStorage2D");
glad_glTextureStorage2DMultisample = (PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) load(userptr, "glTextureStorage2DMultisample");
glad_glTextureStorage3D = (PFNGLTEXTURESTORAGE3DPROC) load(userptr, "glTextureStorage3D");
glad_glTextureStorage3DMultisample = (PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) load(userptr, "glTextureStorage3DMultisample");
glad_glTextureSubImage1D = (PFNGLTEXTURESUBIMAGE1DPROC) load(userptr, "glTextureSubImage1D");
glad_glTextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC) load(userptr, "glTextureSubImage2D");
glad_glTextureSubImage3D = (PFNGLTEXTURESUBIMAGE3DPROC) load(userptr, "glTextureSubImage3D");
glad_glTransformFeedbackBufferBase = (PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) load(userptr, "glTransformFeedbackBufferBase");
glad_glTransformFeedbackBufferRange = (PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) load(userptr, "glTransformFeedbackBufferRange");
glad_glUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFERPROC) load(userptr, "glUnmapNamedBuffer");
glad_glVertexArrayAttribBinding = (PFNGLVERTEXARRAYATTRIBBINDINGPROC) load(userptr, "glVertexArrayAttribBinding");
glad_glVertexArrayAttribFormat = (PFNGLVERTEXARRAYATTRIBFORMATPROC) load(userptr, "glVertexArrayAttribFormat");
glad_glVertexArrayAttribIFormat = (PFNGLVERTEXARRAYATTRIBIFORMATPROC) load(userptr, "glVertexArrayAttribIFormat");
glad_glVertexArrayAttribLFormat = (PFNGLVERTEXARRAYATTRIBLFORMATPROC) load(userptr, "glVertexArrayAttribLFormat");
glad_glVertexArrayBindingDivisor = (PFNGLVERTEXARRAYBINDINGDIVISORPROC) load(userptr, "glVertexArrayBindingDivisor");
glad_glVertexArrayElementBuffer = (PFNGLVERTEXARRAYELEMENTBUFFERPROC) load(userptr, "glVertexArrayElementBuffer");
glad_glVertexArrayVertexBuffer = (PFNGLVERTEXARRAYVERTEXBUFFERPROC) load(userptr, "glVertexArrayVertexBuffer");
glad_glVertexArrayVertexBuffers = (PFNGLVERTEXARRAYVERTEXBUFFERSPROC) load(userptr, "glVertexArrayVertexBuffers");
}
static void glad_gl_load_GL_ARB_fragment_program( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_GL_ARB_fragment_program) return;
glad_glBindProgramARB = (PFNGLBINDPROGRAMARBPROC) load(userptr, "glBindProgramARB");
@@ -10187,6 +10361,12 @@ static void glad_gl_load_GL_ARB_shader_storage_buffer_object( GLADuserptrloadfun
if(!GLAD_GL_ARB_shader_storage_buffer_object) return;
glad_glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC) load(userptr, "glShaderStorageBlockBinding");
}
static void glad_gl_load_GL_ARB_timer_query( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_GL_ARB_timer_query) return;
glad_glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC) load(userptr, "glGetQueryObjecti64v");
glad_glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC) load(userptr, "glGetQueryObjectui64v");
glad_glQueryCounter = (PFNGLQUERYCOUNTERPROC) load(userptr, "glQueryCounter");
}
static void glad_gl_load_GL_ARB_vertex_buffer_object( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_GL_ARB_vertex_buffer_object) return;
glad_glBindBufferARB = (PFNGLBINDBUFFERARBPROC) load(userptr, "glBindBufferARB");
@@ -10618,6 +10798,10 @@ static void glad_gl_load_GL_EXT_framebuffer_blit( GLADuserptrloadfunc load, void
if(!GLAD_GL_EXT_framebuffer_blit) return;
glad_glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC) load(userptr, "glBlitFramebufferEXT");
}
static void glad_gl_load_GL_EXT_framebuffer_multisample( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_GL_EXT_framebuffer_multisample) return;
glad_glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) load(userptr, "glRenderbufferStorageMultisampleEXT");
}
static void glad_gl_load_GL_EXT_framebuffer_object( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_GL_EXT_framebuffer_object) return;
glad_glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC) load(userptr, "glBindFramebufferEXT");
@@ -10707,6 +10891,20 @@ static void glad_gl_load_GL_EXT_transform_feedback( GLADuserptrloadfunc load, vo
glad_glGetTransformFeedbackVaryingEXT = (PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) load(userptr, "glGetTransformFeedbackVaryingEXT");
glad_glTransformFeedbackVaryingsEXT = (PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) load(userptr, "glTransformFeedbackVaryingsEXT");
}
static void glad_gl_load_GL_KHR_debug( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_GL_KHR_debug) return;
glad_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC) load(userptr, "glDebugMessageCallback");
glad_glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC) load(userptr, "glDebugMessageControl");
glad_glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC) load(userptr, "glDebugMessageInsert");
glad_glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC) load(userptr, "glGetDebugMessageLog");
glad_glGetObjectLabel = (PFNGLGETOBJECTLABELPROC) load(userptr, "glGetObjectLabel");
glad_glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC) load(userptr, "glGetObjectPtrLabel");
glad_glGetPointerv = (PFNGLGETPOINTERVPROC) load(userptr, "glGetPointerv");
glad_glObjectLabel = (PFNGLOBJECTLABELPROC) load(userptr, "glObjectLabel");
glad_glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC) load(userptr, "glObjectPtrLabel");
glad_glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC) load(userptr, "glPopDebugGroup");
glad_glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC) load(userptr, "glPushDebugGroup");
}
static void glad_gl_load_GL_NV_conservative_raster( GLADuserptrloadfunc load, void* userptr) {
if(!GLAD_GL_NV_conservative_raster) return;
glad_glSubpixelPrecisionBiasNV = (PFNGLSUBPIXELPRECISIONBIASNVPROC) load(userptr, "glSubpixelPrecisionBiasNV");
@@ -10808,6 +11006,7 @@ static int glad_gl_find_extensions_gl(void) {
GLAD_GL_ARB_compatibility = glad_gl_has_extension(exts, exts_i, "GL_ARB_compatibility");
GLAD_GL_ARB_debug_output = glad_gl_has_extension(exts, exts_i, "GL_ARB_debug_output");
GLAD_GL_ARB_direct_state_access = glad_gl_has_extension(exts, exts_i, "GL_ARB_direct_state_access");
GLAD_GL_ARB_fragment_program = glad_gl_has_extension(exts, exts_i, "GL_ARB_fragment_program");
GLAD_GL_ARB_fragment_shader = glad_gl_has_extension(exts, exts_i, "GL_ARB_fragment_shader");
GLAD_GL_ARB_framebuffer_sRGB = glad_gl_has_extension(exts, exts_i, "GL_ARB_framebuffer_sRGB");
@@ -10816,26 +11015,34 @@ static int glad_gl_find_extensions_gl(void) {
GLAD_GL_ARB_shader_objects = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_objects");
GLAD_GL_ARB_shader_storage_buffer_object = glad_gl_has_extension(exts, exts_i, "GL_ARB_shader_storage_buffer_object");
GLAD_GL_ARB_shading_language_100 = glad_gl_has_extension(exts, exts_i, "GL_ARB_shading_language_100");
GLAD_GL_ARB_texture_compression_bptc = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_compression_bptc");
GLAD_GL_ARB_texture_float = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_float");
GLAD_GL_ARB_texture_rg = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_rg");
GLAD_GL_ARB_texture_rgb10_a2ui = glad_gl_has_extension(exts, exts_i, "GL_ARB_texture_rgb10_a2ui");
GLAD_GL_ARB_timer_query = glad_gl_has_extension(exts, exts_i, "GL_ARB_timer_query");
GLAD_GL_ARB_vertex_buffer_object = glad_gl_has_extension(exts, exts_i, "GL_ARB_vertex_buffer_object");
GLAD_GL_ARB_vertex_program = glad_gl_has_extension(exts, exts_i, "GL_ARB_vertex_program");
GLAD_GL_ARB_vertex_shader = glad_gl_has_extension(exts, exts_i, "GL_ARB_vertex_shader");
GLAD_GL_ARB_vertex_type_2_10_10_10_rev = glad_gl_has_extension(exts, exts_i, "GL_ARB_vertex_type_2_10_10_10_rev");
GLAD_GL_EXT_direct_state_access = glad_gl_has_extension(exts, exts_i, "GL_EXT_direct_state_access");
GLAD_GL_EXT_framebuffer_blit = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_blit");
GLAD_GL_EXT_framebuffer_multisample = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_multisample");
GLAD_GL_EXT_framebuffer_multisample_blit_scaled = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_multisample_blit_scaled");
GLAD_GL_EXT_framebuffer_object = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_object");
GLAD_GL_EXT_framebuffer_sRGB = glad_gl_has_extension(exts, exts_i, "GL_EXT_framebuffer_sRGB");
GLAD_GL_EXT_geometry_shader4 = glad_gl_has_extension(exts, exts_i, "GL_EXT_geometry_shader4");
GLAD_GL_EXT_gpu_shader4 = glad_gl_has_extension(exts, exts_i, "GL_EXT_gpu_shader4");
GLAD_GL_EXT_shader_image_load_store = glad_gl_has_extension(exts, exts_i, "GL_EXT_shader_image_load_store");
GLAD_GL_EXT_texture_array = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_array");
GLAD_GL_EXT_texture_compression_rgtc = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_compression_rgtc");
GLAD_GL_EXT_texture_compression_s3tc = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_compression_s3tc");
GLAD_GL_EXT_texture_filter_anisotropic = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_filter_anisotropic");
GLAD_GL_EXT_texture_integer = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_integer");
GLAD_GL_EXT_texture_sRGB = glad_gl_has_extension(exts, exts_i, "GL_EXT_texture_sRGB");
GLAD_GL_EXT_transform_feedback = glad_gl_has_extension(exts, exts_i, "GL_EXT_transform_feedback");
GLAD_GL_INTEL_conservative_rasterization = glad_gl_has_extension(exts, exts_i, "GL_INTEL_conservative_rasterization");
GLAD_GL_KHR_debug = glad_gl_has_extension(exts, exts_i, "GL_KHR_debug");
GLAD_GL_KHR_texture_compression_astc_ldr = glad_gl_has_extension(exts, exts_i, "GL_KHR_texture_compression_astc_ldr");
GLAD_GL_NV_conservative_raster = glad_gl_has_extension(exts, exts_i, "GL_NV_conservative_raster");
glad_gl_free_extensions(exts_i);
@@ -10919,16 +11126,19 @@ int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr) {
if (!glad_gl_find_extensions_gl()) return 0;
glad_gl_load_GL_ARB_debug_output(load, userptr);
glad_gl_load_GL_ARB_direct_state_access(load, userptr);
glad_gl_load_GL_ARB_fragment_program(load, userptr);
glad_gl_load_GL_ARB_shader_image_load_store(load, userptr);
glad_gl_load_GL_ARB_shader_objects(load, userptr);
glad_gl_load_GL_ARB_shader_storage_buffer_object(load, userptr);
glad_gl_load_GL_ARB_timer_query(load, userptr);
glad_gl_load_GL_ARB_vertex_buffer_object(load, userptr);
glad_gl_load_GL_ARB_vertex_program(load, userptr);
glad_gl_load_GL_ARB_vertex_shader(load, userptr);
glad_gl_load_GL_ARB_vertex_type_2_10_10_10_rev(load, userptr);
glad_gl_load_GL_EXT_direct_state_access(load, userptr);
glad_gl_load_GL_EXT_framebuffer_blit(load, userptr);
glad_gl_load_GL_EXT_framebuffer_multisample(load, userptr);
glad_gl_load_GL_EXT_framebuffer_object(load, userptr);
glad_gl_load_GL_EXT_geometry_shader4(load, userptr);
glad_gl_load_GL_EXT_gpu_shader4(load, userptr);
@@ -10936,6 +11146,7 @@ int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr) {
glad_gl_load_GL_EXT_texture_array(load, userptr);
glad_gl_load_GL_EXT_texture_integer(load, userptr);
glad_gl_load_GL_EXT_transform_feedback(load, userptr);
glad_gl_load_GL_KHR_debug(load, userptr);
glad_gl_load_GL_NV_conservative_raster(load, userptr);

View File

@@ -6,6 +6,11 @@
#include<math.h>
#include<pthread.h>
#include<assert.h>
#include"k3.h"
#ifdef _WIN32
#define strncasecmp _strnicmp
#endif
static uint32_t FinalSampleRate;
static uint8_t FinalChannels;
@@ -19,12 +24,22 @@ struct k3MixSource {
char *filepath;
OggVorbis_File vf;
int bitstream;
size_t looppoint;
};
struct k3MixSource *k3MixSourceFile(const char *path) {
struct k3MixSource *ret = calloc(1, sizeof(*ret));
ret->filepath = strdup(path);
ov_fopen(path, &ret->vf);
ret->bitstream = 0;
ret->looppoint = 0;
for(size_t ci = 0; ci < ret->vf.vc->comments; ci++) {
if(strncasecmp(ret->vf.vc->user_comments[ci], "looppoint=", 10) == 0) {
ret->looppoint = strtol(ret->vf.vc->user_comments[ci] + 10, NULL, 0);
k3Log(k3_DEBUG, "%s has loop point %lu", path, ret->looppoint);
}
}
return ret;
}
void k3MixSourceClose(struct k3MixSource *src) {
@@ -42,7 +57,7 @@ __attribute__((optimize("Ofast"))) static intmax_t ogg_read(struct k3MixWave *th
long lastRead = ov_read_float(&od->vf, &ni, sampleCount, &od->bitstream);
if(this->loop && lastRead == 0) {
ov_pcm_seek(&od->vf, 0);
ov_pcm_seek(&od->vf, od->looppoint);
continue;
} else if(lastRead <= 0) {
this->end = true;
@@ -161,12 +176,13 @@ static void queue_clone(struct k3MixWave *this, struct k3MixWave *new) {
new->clone = queue_clone;
new->close = queue_close;
new->end = this->end;
new->loop = this->loop;
new->dam = this->dam;
new->volume = this->volume;
}
struct k3MixWave *k3MixQueue() {
struct k3MixWave *ret = malloc(sizeof(*ret));
struct k3MixWave *ret = calloc(1, sizeof(*ret));
ret->refs = 1;
ret->sampleRate = FinalSampleRate;
ret->channels = FinalChannels;
@@ -182,6 +198,7 @@ struct k3MixWave *k3MixQueue() {
ret->loop = 0;
ret->dam = 0;
ret->volume = 1;
ret->end = false;
return ret;
}
@@ -260,6 +277,7 @@ static void power_measurement_clone(struct k3MixWave *this, struct k3MixWave *ne
new->clone = power_measurement_clone;
new->close = power_measurement_close;
new->end = this->end;
new->loop = this->loop;
new->dam = this->dam;
new->volume = this->volume;
@@ -308,6 +326,10 @@ struct k3MixWave *k3MixPowerMeasurement(struct k3MixWave *child) {
static size_t playingCount, playingCapacity;
static struct k3MixWave **playings;
void k3MixStopSmooth(struct k3MixWave *wav) {
wav->fade = -0.01;
}
void k3MixStop(struct k3MixWave *wav) {
for(size_t i = 0; i < playingCount; i++) {
if(playings[i] == wav) {
@@ -346,12 +368,22 @@ __attribute__((optimize("Ofast"))) static void k3MixDoYourThang(size_t sampleCou
for(size_t i = 0; i < playingCount;) {
intmax_t read = playings[i]->read(playings[i], sampleCount, FinalData);
if(playings[i]->fade) {
playings[i]->volume += playings[i]->fade;
if(playings[i]->volume > 1) {
playings[i]->volume = 1;
playings[i]->fade = 0;
} else if(playings[i]->volume < 0) {
playings[i]->end = true;
}
}
if(playings[i]->end) {
k3MixStop(playings[i]);
} else i++;
}
for(size_t i = 0; i < sampleCount * FinalChannels; i += 4) {
/*for(size_t i = 0; i < sampleCount * FinalChannels; i += 4) {
// Compute tanh approximation x*(27+x*x)/(27+9*x*x)
float *ptr = FinalData + i;
@@ -363,7 +395,7 @@ __attribute__((optimize("Ofast"))) static void k3MixDoYourThang(size_t sampleCou
__m128 denom = _mm_add_ps(_mm_set1_ps(27), _mm_mul_ps(_mm_set1_ps(9), xx));
_mm_storeu_ps(ptr, _mm_div_ps(numer, denom));
}
}*/
// The accuracy isn't worth the function call per sample
/*for(size_t i = 0; i < sampleCount * FinalChannels; i++) {

View File

@@ -29,6 +29,7 @@ struct k3MixWave {
bool end;
uint16_t dam;
float volume;
float fade;
};
void k3MixInit(uint32_t sampleRate, uint8_t channels);
@@ -44,6 +45,7 @@ struct k3MixWave *k3MixPowerMeasurement(struct k3MixWave *child);
float k3MixPowerMeasurementGetRMS(struct k3MixWave*);
void k3MixStop(struct k3MixWave*);
void k3MixStopSmooth(struct k3MixWave*);
struct k3MixWave *k3MixPlay(struct k3MixWave*);
void k3MixPlayDirect(struct k3MixWave*);

View File

@@ -45,3 +45,5 @@ void k4_set_texture_reduction(int);
void k4_set_clipboard_text(const char *str);
const char *k4_get_clipboard_text();
void k4_set_ui_mode(bool yes);

View File

@@ -25,6 +25,9 @@ static int mdlloader(void *ud, struct ResManRes *res) {
} header;
fread(&header, 4, 4, f);
// ' ' or '1'
char version = ((char*) &header.magic)[3];
int colorsEnabled = header.flags & 1;
mat4 *invBind = _mm_malloc(sizeof(*invBind) * header.boneCount, 16);
@@ -33,6 +36,17 @@ static int mdlloader(void *ud, struct ResManRes *res) {
uint8_t *boneParents = malloc(header.boneCount);
fread(boneParents, 1, header.boneCount, f);
char boneNames[1500] = {};
size_t boneNamesLen = 0;
for(size_t b = 0; b < header.boneCount; b++) {
while(1) {
fread(boneNames + boneNamesLen, 1, 1, f);
if(boneNames[boneNamesLen++] == 0) {
break;
}
}
}
vec3 *pos = malloc(sizeof(*pos) * header.vertCount);
fread(pos, sizeof(vec3), header.vertCount, f);
@@ -59,6 +73,8 @@ static int mdlloader(void *ud, struct ResManRes *res) {
struct k3Mdl *mdl = k3MdlCreate(header.vertCount, header.indCount, header.boneCount, pos, nrm, uvs, cols, boneIDs, boneWeights, inds, invBind, boneParents);
k3MdlSetBoneNames(mdl, boneNames);
k3MdlSetDebugName(mdl, res->name);
free(pos);
@@ -70,8 +86,11 @@ static int mdlloader(void *ud, struct ResManRes *res) {
fread(&meshes, sizeof(uint16_t), 1, f);
for(uint32_t i = 0; i < meshes; i++) {
uint16_t startnum[2];
fread(startnum, sizeof(uint16_t), 2, f);
uint32_t start = 0;
uint32_t number = 0;
fread(&start, version == ' ' ? sizeof(uint16_t) : sizeof(uint32_t), 1, f);
fread(&number, version == ' ' ? sizeof(uint16_t) : sizeof(uint32_t), 1, f);
char buf[256] = {};
for(int c = 0; c < sizeof(buf) - 1; c++) {
@@ -81,28 +100,25 @@ static int mdlloader(void *ud, struct ResManRes *res) {
}
}
k3MdlAddMesh(mdl, resman_ref(RESMAN_MATERIAL, buf), startnum[0], startnum[1]);
k3MdlAddMesh(mdl, resman_ref(RESMAN_MATERIAL, buf), start, number);
}
for(size_t i = 0; i < header.animCount; i++) {
struct {
uint16_t id;
uint16_t frames;
uint16_t frameCount;
uint16_t fps;
uint16_t zero;
} info;
fread(&info, sizeof(info), 1, f);
struct k3Animation *anim = malloc(sizeof(*anim));
anim->frames = _mm_malloc(sizeof(*anim->frames) * info.frames * header.boneCount, 16);
anim->boneParents = boneParents;
anim->invBind = invBind;
struct k3AnimationFountain *anim = _mm_malloc(sizeof(*anim) + sizeof(*anim->frames) * info.frameCount * header.boneCount, 16);
anim->id = info.id;
anim->fps = info.fps;
anim->frameCount = info.frames;
anim->boneCount = header.boneCount;
anim->frameCount = info.frameCount;
anim->bones = header.boneCount;
fread(anim->frames, sizeof(*anim->frames), info.frames * header.boneCount, f);
fread(anim->frames, sizeof(*anim->frames), info.frameCount * header.boneCount, f);
k3MdlAddAnim(mdl, anim);
}
@@ -168,7 +184,7 @@ static int streamloader(void *ud, struct ResManRes *res) {
snprintf(namebuf, sizeof(namebuf), "assets/aud/%s", res->name);
res->thing = k3MixSourceFile(namebuf);
return 1;
return !!res->thing;
}
static int refresh_texture(struct ResManRes *res) {
@@ -253,15 +269,27 @@ static int refresh_texture(struct ResManRes *res) {
int w, h, origN;
unsigned char *data = stbi_load(namebuf, &w, &h, &origN, n);
int stbifree = 1;
if(TextureResolutionReduction && data) {
int newW = w >> TextureResolutionReduction;
int newH = h >> TextureResolutionReduction;
int newW = w, newH = h;
if(newW <= 4) newW = 4;
if(newH <= 4) newH = 4;
if(TextureResolutionReduction) {
newW = newW >> TextureResolutionReduction;
newH = newH >> TextureResolutionReduction;
}
if(newW > k3TexSzMax()) {
newW = k3TexSzMax();
}
if(newH > k3TexSzMax()) {
newH = k3TexSzMax();
}
if(newW < 4) {
newW = 4;
}
if(newH < 4) {
newH = 4;
}
if(newW != w || newH != h) {
unsigned char *data2 = malloc(newW * newH * n);
int success = stbir_resize_uint8_generic(data, w, h, 0, data2, newW, newH, 0, n, n == 4 ? 3 : -1, 0, STBIR_EDGE_WRAP, STBIR_FILTER_DEFAULT, gamma ? STBIR_COLORSPACE_SRGB : STBIR_COLORSPACE_LINEAR, NULL);
@@ -271,7 +299,6 @@ static int refresh_texture(struct ResManRes *res) {
w = newW;
h = newH;
data = data2;
stbifree = 0;
} else {
free(data2);
}
@@ -283,12 +310,7 @@ static int refresh_texture(struct ResManRes *res) {
if(data) {
k3TexUpdate(res->thing, type, 0, w, h, data);
if(stbifree) {
stbi_image_free(data);
} else {
free(data);
}
free(data);
}
}
@@ -311,19 +333,11 @@ static int texloader(void *ud, struct ResManRes *res) {
}
static int fontloader(void *ud, struct ResManRes *res) {
FILE *fntf = fopen(res->name, "rb");
fseek(fntf, 0, SEEK_END);
size_t fntfsz = ftell(fntf);
fseek(fntf, 0, SEEK_SET);
char *fntbuf = malloc(fntfsz);
fread(fntbuf, 1, fntfsz, fntf);
char namebuf[256];
snprintf(namebuf, sizeof(namebuf), "assets/%s", res->name);
struct k3Font *fnt = k3FontCreate();
struct k3Tex *fnttexldr(struct k3Font *fnt, const char *name) {
return resman_ref(RESMAN_TEXTURE, name);
}
k3FontLoad(fnt, fntbuf, fntfsz, fnttexldr);
k3FontLoad(fnt, namebuf);
res->thing = fnt;
return 1;

File diff suppressed because it is too large Load Diff

View File

@@ -14,6 +14,8 @@ extern int LuaapiFirstPerson;
extern double LuaapiStartTime;
extern float LuaapiFov;
extern float LuaapiNear;
extern float LuaapiFar;
extern struct k3Tex *LuaapiSkybox;
extern vec4 LuaapiSkyboxRotation;

View File

@@ -28,6 +28,7 @@
#include"k3font.h"
#include"k3menu.h"
#include"k3bloom.h"
#include"k3batch.h"
#include"resman.h"
@@ -37,15 +38,19 @@
#include"net_server.h"
#include"net_client.h"
#include"net_hi.h"
#include<ctype.h>
GLFWwindow *GameWnd;
uint16_t GameWndW;
uint16_t GameWndH;
static int TextureResolutionReduction = 0;
static int IrregularShadows = 0;
static int InstantCamShift = 5;
static float CamPitch, CamYaw;
static vec3 CamPos;
static int ThirdPerson = 1;
@@ -57,7 +62,7 @@ static double LastTime;
#include"loaders.inc"
void set_ui_mode(int yes) {
void k4_set_ui_mode(bool yes) {
glfwSetInputMode(GameWnd, GLFW_CURSOR, yes ? GLFW_CURSOR_NORMAL : GLFW_CURSOR_DISABLED);
}
@@ -69,9 +74,6 @@ static double xposold, yposold;
static void buttoncallback(GLFWwindow *GameWnd, int button, int action, int mods) {
if(button == GLFW_MOUSE_BUTTON_LEFT) {
if(UiActive) {
int ww, wh;
glfwGetWindowSize(GameWnd, &ww, &wh);
struct k3MEvent ev = {
.original = (void*) UiActive,
.target = (void*) UiActive,
@@ -79,8 +81,8 @@ static void buttoncallback(GLFWwindow *GameWnd, int button, int action, int mods
.code = action == GLFW_PRESS ? k3M_EVENT_MOUSE_PRESS : k3M_EVENT_MOUSE_RELEASE,
.mouse = {
.button = k3M_MOUSE_BUTTON_0,
.x = xposold * UiActive->w / ww,
.y = (wh - yposold - 1) * UiActive->h / wh,
.x = xposold * UiActive->w / GameWndW,
.y = yposold * UiActive->h / GameWndH,
},
};
@@ -109,11 +111,8 @@ static void motioncallback(GLFWwindow *GameWnd, double xpos, double ypos) {
first = 0;
if(UiActive) {
int ww, wh;
glfwGetWindowSize(GameWnd, &ww, &wh);
uint16_t uix = xposold * UiActive->w / ww;
uint16_t uiy = (wh - yposold - 1) * UiActive->h / wh;
uint16_t uix = xposold * UiActive->w / GameWndW;
uint16_t uiy = yposold * UiActive->h / GameWndH;
struct k3MEvent ev = {
.original = (void*) UiActive,
@@ -133,7 +132,7 @@ static void motioncallback(GLFWwindow *GameWnd, double xpos, double ypos) {
static void keycallback(GLFWwindow *GameWnd, int key, int scancode, int action, int mods) {
if(action == GLFW_RELEASE && key == GLFW_KEY_ESCAPE) {
luaapi_escape();
set_ui_mode(!!UiActive);
k4_set_ui_mode(!!UiActive);
} else {
if(UiActive) {
struct k3MEvent ev = {
@@ -169,8 +168,18 @@ static void charcallback(GLFWwindow *window, unsigned int codepoint) {
}
}
static void fix_resol();
static void resizecallback(GLFWwindow *window, int width, int height) {
k3Resize(width, height);
k3Resize(GameWndW = width, GameWndH = height);
fix_resol();
if(UiActive) {
UiActive->w = UiActive->wDesired = GameWndW;
UiActive->h = UiActive->hDesired = GameWndH;
k3MMeasure(UiActive);
k3MArrange(UiActive);
}
}
static int argc;
@@ -184,89 +193,12 @@ const char *k4_get_arg(const char *name) {
return NULL;
}
/*static void netwrap_step() {
if(NetWrap.stage && CurrentTime >= NetWrap.timeout) {
if(NetWrap.stage == 1) {
if(stoon_req(&NetWrap.stoon)) {
if(stoon_listen(&NetWrap.stoon)) {
uint8_t conndata[STOON_CONN_INFO_SIZE] = {};
stoon_serialize(&NetWrap.stoon, conndata);
char str[STOON_CONN_INFO_SIZE * 2 + 1] = {};
for(int i = 0; i < sizeof(conndata); i++) {
snprintf(str + i * 2, 3, "%02x", conndata[i]);
}
luaapi_peercode_found(str);
NetWrap.stage = 2;
} else {
k3Log(k3_INFO, "Stoon listen timeout.");
NetWrap.timeout = CurrentTime + 0.5;
}
} else {
k3Log(k3_INFO, "Stoon request failed.");
NetWrap.timeout = CurrentTime + 0.5;
}
} else if(NetWrap.stage == 2) {
stoon_keepalive(&NetWrap.stoon);
NetWrap.timeout = CurrentTime + 1;
} else if(NetWrap.stage == 3) {
if(NetWrap.isHost) {
stoon_kill(&NetWrap.stoon);
net_server_init();
NetWrap.stage = 4;
}
} else if(NetWrap.stage == 4) {
if(NetWrap.isHost) {
ENetBuffer buf = {.data = "Punch!", .dataLength = 6};
ENetHost *h = net_server_get_enethost();
for(size_t i = 0; i < NETWRAP_BACKLOG; i++) {
if(NetWrap.otherpeersActive[i]) {
ENetAddress v4 = {}, v6 = {};
stoonpeer_to_enets(NetWrap.otherpeers[i], &v4, &v6);
enet_socket_send(h->socket, &v4, &buf, 1);
enet_socket_send(h->socket, &v6, &buf, 1);
}
}
} else {
stoon_keepalive(&NetWrap.stoon);
}
NetWrap.timeout = CurrentTime + 1;
} else if(NetWrap.stage == 5) {
if(!NetWrap.isHost) {
char ip[64];
int port;
if(*(uint16_t*) (NetWrap.otherpeer + 22) == 0) {
inet_ntop(AF_INET, NetWrap.otherpeer, ip, sizeof(ip));
port = ntohs(*(uint16_t*) (NetWrap.otherpeer + 4));
} else {
inet_ntop(AF_INET6, NetWrap.otherpeer + 6, ip, sizeof(ip));
port = ntohs(*(uint16_t*) (NetWrap.otherpeer + 22));
}
printf("Trying [%s]:%u\n", ip, port);
net_client_init();
if(net_client_connect(ip, port)) {
NetWrap.stage = 5;
}
}
NetWrap.timeout = CurrentTime + 0.5;
} else {
NetWrap.timeout = CurrentTime + 1;
}
}
}*/
#include<signal.h>
void k4k3LogCallback(enum k3LogLevel lvl, const char *str, size_t len) {
if(lvl == k3_TRACE) return;
static const char *prefixes[] = {
[k3_TRACE] = "[\x1B[95mTRACE\x1B[0m]",
[k3_DEBUG] = "[\x1B[95mDEBUG\x1B[0m]",
[k3_INFO] = "[\x1B[97mINFO\x1B[0m] ",
[k3_WARN] = "[\x1B[93mWARN\x1B[0m] ",
@@ -275,7 +207,7 @@ void k4k3LogCallback(enum k3LogLevel lvl, const char *str, size_t len) {
//if(lvl == k3_ERR) raise(SIGINT);
fprintf(stderr, "%s : %s\n", prefixes[lvl], str);
fprintf(stdout, "%s : %s\n", prefixes[lvl], str);
}
struct k4Control {
@@ -295,21 +227,25 @@ static int eng_init() {
#define START_HEIGHT 540
#define START_TITLE "k4"
GameWndW = START_WIDTH;
GameWndH = START_HEIGHT;
// Prefer core
if(!k4_get_arg("core") || strcmp(k4_get_arg("core"), "0")) {
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
GameWnd = glfwCreateWindow(START_WIDTH, START_HEIGHT, START_TITLE, NULL, NULL);
GameWnd = glfwCreateWindow(GameWndW, GameWndH, START_TITLE, NULL, NULL);
}
// Attempt compatibility
if(!GameWnd) {
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 1);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
GameWnd = glfwCreateWindow(START_WIDTH, START_HEIGHT, START_TITLE, NULL, NULL);
GameWnd = glfwCreateWindow(GameWndW, GameWndH, START_TITLE, NULL, NULL);
}
k3MixInit(44100, 2);
@@ -343,8 +279,16 @@ static int eng_init() {
GLAD_GL_ARB_framebuffer_sRGB = 0;
GLAD_GL_EXT_framebuffer_object = 0;
}
if(k4_get_arg("dsa") && strtol(k4_get_arg("dsa"), NULL, 0) == 0) {
GLAD_GL_EXT_direct_state_access = 0;
GLAD_GL_ARB_direct_state_access = 0;
}
glfwSwapInterval(0);
if(k4_get_arg("vsync")) {
glfwSwapInterval(strtol(k4_get_arg("vsync"), NULL, 0));
} else {
glfwSwapInterval(0);
}
printf("GL version: %s\n", glGetString(GL_VERSION));
printf("GL renderer: %s\n", glGetString(GL_RENDERER));
@@ -352,7 +296,9 @@ static int eng_init() {
k3SetLogCallback(k4k3LogCallback);
k3Init();
k3Init(
!k4_get_arg("tc") || strtol(k4_get_arg("tc"), NULL, 0) != 0,
!k4_get_arg("mipmap") || strtol(k4_get_arg("mipmap"), NULL, 0) != 0);
k3BatchInit();
@@ -376,7 +322,7 @@ static void fix_resol() {
}
static void eng_ui_init() {
set_ui_mode(1);
k4_set_ui_mode(!!UiActive);
}
static void fps_counter_step(double newDT) {
@@ -415,6 +361,7 @@ static int gr_shadowmap_init() {
"!!ARBfp1.0\n"
"TEMP col;\n"
"TEX col, fragment.texcoord, texture[0], 2D;\n"
"MOV result.color, col;\n"
"MAD col.xyz, -col, 29.9, 30.1;\n"
"RCP col.x, col.x;\n"
"RCP col.y, col.y;\n"
@@ -459,32 +406,17 @@ static int gr_lowres(int newW, int newH) {
}
k3TexUpdate(lowresDepth, k3_DEPTH, 0, newW, newH, NULL);
lowresOffscreen = k3OffscreenCreate(lowres, lowresDepth);
lowresOffscreen = k3OffscreenCreateMultisampled(lowres, lowresDepth, 4);
}
return !!lowresOffscreen;
}
#define MAX_RAYS 64
static struct LocalRay RaysToCast[MAX_RAYS];
static size_t RaysToCastCount = 0;
struct LocalRay *request_ray(struct LocalRay *lr) {
if(RaysToCastCount == MAX_RAYS) {
return NULL;
}
memcpy(RaysToCast + RaysToCastCount, lr, sizeof(*lr));
return &RaysToCast[RaysToCastCount++];
}
int main(int argc_, char **argv_) {
argc = argc_;
argv = argv_;
eng_init();
eng_ui_init();
gr_shadowmap_init();
gr_bloom_init();
@@ -504,7 +436,7 @@ int main(int argc_, char **argv_) {
luaapi_load(k4_get_arg("script") ? k4_get_arg("script") : "init");
//
LuaapiStartTime = glfwGetTime();
eng_ui_init();
LastTime = glfwGetTime();
@@ -523,6 +455,9 @@ int main(int argc_, char **argv_) {
net_hi_update(CurrentTime);
int windowW, windowH;
glfwGetWindowSize(GameWnd, &windowW, &windowH);
float alpha = fmodf(accumulator * GAME_TPS, 1.f);
vec3 cameraForwardDir = {0, 0, -1};
@@ -557,9 +492,6 @@ int main(int argc_, char **argv_) {
}
}
game_raycast(RaysToCast, RaysToCastCount);
RaysToCastCount = 0;
while(accumulator >= 1. / GAME_TPS) {
for(size_t i = 0; i < Game.entities.renderCount; i++) {
glm_vec4_copy(Game.entities.render[i].pos, Game.entities.render[i].posLast);
@@ -586,10 +518,10 @@ int main(int argc_, char **argv_) {
glfwGetFramebufferSize(GameWnd, &width, &height);
mat4 proj;
glm_perspective(glm_rad(LuaapiFov), (float) width / height, 0.01f, 100.f, proj);
glm_perspective(glm_rad(LuaapiFov), (float) width / height, LuaapiNear, LuaapiFar, proj);
/* Third-person camera movement */
struct LocalRay camray;
struct LocalRay camray = {};
if(Game.spectated != ENT_ID_INVALID) {
struct CRender *c = game_getcomponent(Game.spectated, render);
if(c) {
@@ -610,12 +542,20 @@ int main(int argc_, char **argv_) {
}
mat4 cam;
if(InstantCamShift) {
InstantCamShift--;
}
if(LuaapiFirstPerson) {
struct CRender *c = game_getcomponent(Game.spectated, render);
struct CRender *cr = game_getcomponent(Game.spectated, render);
struct CPhysics *cp = game_getcomponent(Game.spectated, physics);
if(c) {
if(cr) {
vec3 p;
glm_vec3_lerp(c->posLast, c->pos, alpha, p);
glm_vec3_lerp(cr->posLast, cr->pos, alpha, p);
if(cp && cp->type == CPHYSICS_CAPSULE) {
p[1] += cp->capsule.length / 2;
}
mat4 view;
glm_look(p, cameraForwardDir, (vec3) {0, 1, 0}, view);
@@ -628,10 +568,15 @@ int main(int argc_, char **argv_) {
vec3 almostThere;
if(LuaapiCamFocus) {
float lerpa = InstantCamShift ? 1 : 0.1;
glm_vec3_copy(LuaapiCamFocusPos, almostThere);
glm_vec3_lerp(CamPos, almostThere, 0.1, CamPos);
glm_vec3_copy(LuaapiCamFocusPos, CamPos);
glm_look(CamPos, LuaapiCamFocusDir, (vec3) {0, 1, 0}, cam);
} else {
float lerpa = InstantCamShift ? 1 : 0.2;
vec3 dirneg;
glm_vec3_negate_to(camray.dir, dirneg);
@@ -645,6 +590,7 @@ int main(int argc_, char **argv_) {
glm_mat4_copy(cam, LuaapiCamMatrix);
k3Update();
k3SetTime(glfwGetTime());
size_t lightCount;
@@ -670,12 +616,16 @@ int main(int argc_, char **argv_) {
if(c->cache) {
struct CBoned *b = game_getcomponent(c->entity, boned);
k3Batch(c->cache, transform, b ? b->bones : NULL);
if(b && b->animator.anim) {
k3AnimatorStep(&b->animator, dt);
}
k3Batch(c->cache, transform, b ? b->animator.bones : NULL);
}
}
if(!IrregularShadows) {
k3PassShadowmap(proj, cam, shadowmapOffscreen);
k3PassShadowmap(proj, cam, shadowmapOffscreen, 8);
}
if(lowresOffscreen) {
@@ -720,13 +670,7 @@ int main(int argc_, char **argv_) {
glClear(GL_DEPTH_BUFFER_BIT);
if(!k3IsCore) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 3600, 0, 2025, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
k3BatchSetResolution(windowW, windowH);
luaapi_render2d();
@@ -745,7 +689,7 @@ int main(int argc_, char **argv_) {
// Shadowmap debugging
if(glfwGetKey(GameWnd, GLFW_KEY_F5) == GLFW_PRESS) {
k3BlitToScreen(shadowmapOffscreen, 0);
k3BlitToScreenEffect(shadowmapOffscreen, 0, k3_ARBFRAG, shadowmapDebugThing, NULL);
}
glfwSwapBuffers(GameWnd);

View File

@@ -26,11 +26,7 @@ void net_client_init() {
Game.isAuthority = 0;
}
bool net_client_connect(const char *addr, uint16_t port) {
ENetAddress eaddr;
enet_address_set_host(&eaddr, addr);
eaddr.port = port;
bool net_client_connect(ENetAddress eaddr) {
peer = enet_host_connect(host, &eaddr, 1, 0);
ENetEvent ev;
@@ -118,7 +114,7 @@ static void interpret_pkt(ENetPacket *pkt) {
c->holding = b_ru16(&b);
} if(ctype == CMD_CTYPE_BONED) {
struct CBoned *c = game_ensurecomponent(ent, boned);
c->anim.standard = b_ru8(&b);
/*c->anim.standard =*/ b_ru8(&b);
}
} else if(cmd == CMD_SC_POSUPDATE) {
uint16_t lastOurTick = b_ru16(&b);

View File

@@ -1,7 +1,9 @@
#pragma once
#include"enet.h"
void net_client_init();
bool net_client_connect(const char *addr, uint16_t port);
bool net_client_connect(ENetAddress addr);
void net_client_receive();
void net_client_update();
void net_client_dejitter();

View File

@@ -7,9 +7,15 @@
#include"net_server.h"
#include"net_client.h"
#include<math.h>
#include"k3.h"
/*
* Handles networking on a higher-level, combining hole punching with
* basic client & server interface
* */
static void *ReqPeercodeUD;
static void(*ReqPeercodeCB)(void*, const char *peercode);
static void(*ReqPeercodeCB)(void*, struct StoonPeercode *peercode);
static struct Stoon stoon;
@@ -17,11 +23,11 @@ static bool inited = false;
static bool isHost;
typedef struct {
#define MASK_IPv4 1
#define MASK_IPv6 2
int mask;
ENetAddress v4;
ENetAddress v6;
ENetAddress pv4;
ENetAddress pv6;
ENetAddress lv4;
ENetAddress lv6;
} ToPunch;
static ToPunch *topunch = NULL;
static size_t topunchCount = 0;
@@ -30,13 +36,22 @@ static double Timeout = 0;
static bool connected = false;
bool net_hi_request_peercode(void *ud, void(*callback)(void*, const char *peercode)) {
static uint16_t servport = 0;
bool net_hi_request_peercode(void *ud, void(*callback)(void*, struct StoonPeercode *peercode)) {
if(inited) return false;
ReqPeercodeUD = ud;
ReqPeercodeCB = callback;
stoon = stoon_init("stun.easybell.de", 3478, 26656);
for(size_t port = 25000; port <= 26656; port++) {
stoon = stoon_init("stun.easybell.de", 3478, port);
if(stoon.fd4 >= 0 || stoon.fd6 >= 0) {
servport = port;
break;
}
}
Timeout = 0;
@@ -52,7 +67,7 @@ bool net_hi_setup(bool host) {
isHost = host;
if(host) {
net_server_init();
net_server_init(servport);
} else {
net_client_init();
}
@@ -67,16 +82,17 @@ void net_hi_update(double now) {
if(stoon_req(&stoon)) {
if(stoon_listen(&stoon)) {
uint8_t peercode[STOON_CONN_INFO_SIZE] = {};
stoon_serialize(&stoon, peercode);
ReqPeercodeCB(ReqPeercodeUD, peercode);
ReqPeercodeCB(ReqPeercodeUD, &stoon.peercode);
ReqPeercodeCB = NULL;
} else {
k3Log(k3_INFO, "stoon_listen failure");
Timeout = now + 1;
}
} else {
k3Log(k3_INFO, "stoon_req failure");
Timeout = now + 1;
}
@@ -97,11 +113,11 @@ void net_hi_update(double now) {
for(size_t tpi = 0; tpi < topunchCount; tpi++) {
ToPunch *tp = &topunch[tpi];
if(tp->mask & MASK_IPv4) {
enet_socket_send(h->socket, &tp->v4, &buf, 1);
} else if(tp->mask & MASK_IPv6) {
enet_socket_send(h->socket, &tp->v6, &buf, 1);
}
if(tp->lv6.port) enet_socket_send(h->socket, &tp->lv6, &buf, 1);
if(tp->lv4.port) enet_socket_send(h->socket, &tp->lv4, &buf, 1);
if(tp->pv6.port) enet_socket_send(h->socket, &tp->pv6, &buf, 1);
if(tp->pv4.port) enet_socket_send(h->socket, &tp->pv4, &buf, 1);
}
}
@@ -111,55 +127,85 @@ void net_hi_update(double now) {
}
}
static void stoonpeer_to_enets(const char *peercode, ENetAddress *v4, ENetAddress *v6, int *mask) {
memset(v4->host.__in6_u.__u6_addr8, 0, 16);
v4->host.__in6_u.__u6_addr8[10] = 0xFF;
v4->host.__in6_u.__u6_addr8[11] = 0xFF;
v4->host.__in6_u.__u6_addr8[12] = peercode[0];
v4->host.__in6_u.__u6_addr8[13] = peercode[1];
v4->host.__in6_u.__u6_addr8[14] = peercode[2];
v4->host.__in6_u.__u6_addr8[15] = peercode[3];
v4->port = ntohs(*(uint16_t*) &peercode[4]);
static bool stoonpeer_to_enet4(uint8_t *publicV4, uint8_t *publicP4, ENetAddress *enet) {
memset(enet, 0, sizeof(*enet));
memcpy(v6->host.__in6_u.__u6_addr8, peercode + 6, 16);
v6->port = ntohs(*(uint16_t*) &peercode[22]);
if(*(uint32_t*) publicV4 == 0 || *(uint16_t*) publicP4 == 0) {
return false;
}
*mask = 0;
if(v4->port) {
*mask |= MASK_IPv4;
}
if(v6->port) {
*mask |= MASK_IPv6;
}
uint8_t *addr8 = (uint8_t*) &enet->host;
memset(addr8, 0, 16);
addr8[10] = 0xFF;
addr8[11] = 0xFF;
addr8[12] = publicV4[0];
addr8[13] = publicV4[1];
addr8[14] = publicV4[2];
addr8[15] = publicV4[3];
enet->port = *(uint16_t*) publicP4;
return true;
}
void net_hi_add_punch(const char *peercode) {
int mask;
ENetAddress v4 = {}, v6 = {};
stoonpeer_to_enets(peercode, &v4, &v6, &mask);
static bool stoonpeer_to_enet6(uint8_t *publicV6, uint8_t *publicP6, ENetAddress *enet) {
memset(enet, 0, sizeof(*enet));
if(*(uint32_t*) publicV6 == 0 || *(uint16_t*) publicP6 == 0) {
return false;
}
uint8_t *addr8 = (uint8_t*) &enet->host;
memcpy(addr8, publicV6, 16);
enet->port = *(uint16_t*) publicP6;
return true;
}
void net_hi_add_punch(struct StoonPeercode *peercode) {
topunch = realloc(topunch, sizeof(*topunch) * (++topunchCount));
topunch[topunchCount - 1] = (ToPunch) {
.v4 = v4,
.v6 = v6,
.mask = mask,
};
ToPunch *tp = &topunch[topunchCount - 1];
stoonpeer_to_enet4(peercode->publicV4, peercode->publicP4, &tp->pv4);
stoonpeer_to_enet6(peercode->publicV6, peercode->publicP6, &tp->pv6);
stoonpeer_to_enet4(peercode->localV4, peercode->localP4, &tp->lv4);
stoonpeer_to_enet6(peercode->localV6, peercode->localP6, &tp->lv6);
}
bool net_hi_connect(const char *peercode) {
bool net_hi_connect(struct StoonPeercode *peercode) {
if(!inited) return false;
if(connected) return false;
char ip[64];
int port;
if(*(uint16_t*) (peercode + 22) == 0) {
inet_ntop(AF_INET, peercode, ip, sizeof(ip));
port = ntohs(*(uint16_t*) (peercode + 4));
} else {
inet_ntop(AF_INET6, peercode + 6, ip, sizeof(ip));
port = ntohs(*(uint16_t*) (peercode + 22));
ENetAddress pv4, pv6;
stoonpeer_to_enet4(peercode->publicV4, peercode->publicP4, &pv4);
stoonpeer_to_enet6(peercode->publicV6, peercode->publicP6, &pv6);
ENetAddress lv4, lv6;
stoonpeer_to_enet4(peercode->localV4, peercode->localP4, &lv4);
stoonpeer_to_enet6(peercode->localV6, peercode->localP6, &lv6);
if(lv6.port && net_client_connect(lv6)) {
k3Log(k3_INFO, "Found local IPv6");
return true;
}
if(lv4.port && net_client_connect(lv4)) {
k3Log(k3_INFO, "Found local IPv4");
return true;
}
return net_client_connect(ip, port);
if(pv6.port && net_client_connect(pv6)) {
k3Log(k3_INFO, "Found remote IPv6");
return true;
}
if(pv4.port && net_client_connect(pv4)) {
k3Log(k3_INFO, "Found remote IPv4");
return true;
}
k3Log(k3_INFO, "Failed to establish connection");
return false;
}

View File

@@ -2,10 +2,12 @@
#include<stdbool.h>
bool net_hi_request_peercode(void *ud, void(*callback)(void*, const char *peercode));
struct StoonPeercode;
bool net_hi_request_peercode(void *ud, void(*callback)(void*, struct StoonPeercode *peercode));
bool net_hi_setup(bool host);
void net_hi_update(double now);
void net_hi_add_punch(const char *peercode);
void net_hi_add_punch(struct StoonPeercode *peercode);
bool net_hi_connect(const char *peercode);
bool net_hi_connect(struct StoonPeercode *peercode);

View File

@@ -18,8 +18,8 @@ struct Conn {
#define MAX_PLAYERS 64
static struct Conn conns[MAX_PLAYERS];
void net_server_init() {
host = enet_host_create(&(ENetAddress) {.host = ENET_HOST_ANY, .port = 26656}, 16, 1, 0, 0);
void net_server_init(uint16_t port) {
host = enet_host_create(&(ENetAddress) {.host = ENET_HOST_ANY, .port = port}, 16, 1, 0, 0);
Game.isMultiplayer = 1;
Game.isAuthority = 1;
@@ -121,7 +121,7 @@ static void send_full_state(ENetPeer **peers, size_t peerCount) {
b_wu16(&b, c->entity);
b_wu8(&b, c->anim.standard);
b_wu8(&b, 0/*c->anim.standard*/);
}
if(peers) {

View File

@@ -5,7 +5,7 @@
struct _ENetPeer;
struct bstr;
void net_server_init();
void net_server_init(uint16_t port);
void net_server_receive();
void net_server_update();

524
src/noise1234.c Normal file
View File

@@ -0,0 +1,524 @@
// noise1234
//
// Author: Stefan Gustavson, 2003-2005
// Contact: stefan.gustavson@liu.se
//
// This code was GPL licensed until February 2011.
// As the original author of this code, I hereby
// release it into the public domain.
// Please feel free to use it for whatever you want.
// Credit is appreciated where appropriate, and I also
// appreciate being told where this code finds any use,
// but you may do as you like.
/*
* This implementation is "Improved Noise" as presented by
* Ken Perlin at Siggraph 2002. The 3D function is a direct port
* of his Java reference code which was once publicly available
* on www.noisemachine.com (although I cleaned it up, made it
* faster and made the code more readable), but the 1D, 2D and
* 4D functions were implemented from scratch by me.
*
* This is a backport to C of my improved noise class in C++
* which was included in the Aqsis renderer project.
* It is highly reusable without source code modifications.
*
*/
#include "noise1234.h"
// This is the new and improved, C(2) continuous interpolant
#define FADE(t) ( t * t * t * ( t * ( t * 6 - 15 ) + 10 ) )
#define FASTFLOOR(x) ( ((int)(x)<(x)) ? ((int)x) : ((int)x-1 ) )
#define LERP(t, a, b) ((a) + (t)*((b)-(a)))
//---------------------------------------------------------------------
// Static data
/*
* Permutation table. This is just a random jumble of all numbers 0-255,
* repeated twice to avoid wrapping the index at 255 for each lookup.
* This needs to be exactly the same for all instances on all platforms,
* so it's easiest to just keep it as static explicit data.
* This also removes the need for any initialisation of this class.
*
* Note that making this an int[] instead of a char[] might make the
* code run faster on platforms with a high penalty for unaligned single
* byte addressing. Intel x86 is generally single-byte-friendly, but
* some other CPUs are faster with 4-aligned reads.
* However, a char[] is smaller, which avoids cache trashing, and that
* is probably the most important aspect on most architectures.
* This array is accessed a *lot* by the noise functions.
* A vector-valued noise over 3D accesses it 96 times, and a
* float-valued 4D noise 64 times. We want this to fit in the cache!
*/
unsigned char perm[] = {151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
};
//---------------------------------------------------------------------
/*
* Helper functions to compute gradients-dot-residualvectors (1D to 4D)
* Note that these generate gradients of more than unit length. To make
* a close match with the value range of classic Perlin noise, the final
* noise values need to be rescaled. To match the RenderMan noise in a
* statistical sense, the approximate scaling values (empirically
* determined from test renderings) are:
* 1D noise needs rescaling with 0.188
* 2D noise needs rescaling with 0.507
* 3D noise needs rescaling with 0.936
* 4D noise needs rescaling with 0.87
* Note that these noise functions are the most practical and useful
* signed version of Perlin noise. To return values according to the
* RenderMan specification from the SL noise() and pnoise() functions,
* the noise values need to be scaled and offset to [0,1], like this:
* float SLnoise = (noise3(x,y,z) + 1.0) * 0.5;
*/
float grad1( int hash, float x ) {
int h = hash & 15;
float grad = 1.0 + (h & 7); // Gradient value 1.0, 2.0, ..., 8.0
if (h&8) grad = -grad; // and a random sign for the gradient
return ( grad * x ); // Multiply the gradient with the distance
}
float grad2( int hash, float x, float y ) {
int h = hash & 7; // Convert low 3 bits of hash code
float u = h<4 ? x : y; // into 8 simple gradient directions,
float v = h<4 ? y : x; // and compute the dot product with (x,y).
return ((h&1)? -u : u) + ((h&2)? -2.0*v : 2.0*v);
}
float grad3( int hash, float x, float y , float z ) {
int h = hash & 15; // Convert low 4 bits of hash code into 12 simple
float u = h<8 ? x : y; // gradient directions, and compute dot product.
float v = h<4 ? y : h==12||h==14 ? x : z; // Fix repeats at h = 12 to 15
return ((h&1)? -u : u) + ((h&2)? -v : v);
}
float grad4( int hash, float x, float y, float z, float t ) {
int h = hash & 31; // Convert low 5 bits of hash code into 32 simple
float u = h<24 ? x : y; // gradient directions, and compute dot product.
float v = h<16 ? y : z;
float w = h<8 ? z : t;
return ((h&1)? -u : u) + ((h&2)? -v : v) + ((h&4)? -w : w);
}
//---------------------------------------------------------------------
/** 1D float Perlin noise, SL "noise()"
*/
float noise1( float x )
{
int ix0, ix1;
float fx0, fx1;
float s, n0, n1;
ix0 = FASTFLOOR( x ); // Integer part of x
fx0 = x - ix0; // Fractional part of x
fx1 = fx0 - 1.0f;
ix1 = ( ix0+1 ) & 0xff;
ix0 = ix0 & 0xff; // Wrap to 0..255
s = FADE( fx0 );
n0 = grad1( perm[ ix0 ], fx0 );
n1 = grad1( perm[ ix1 ], fx1 );
return 0.188f * ( LERP( s, n0, n1 ) );
}
//---------------------------------------------------------------------
/** 1D float Perlin periodic noise, SL "pnoise()"
*/
float pnoise1( float x, int px )
{
int ix0, ix1;
float fx0, fx1;
float s, n0, n1;
ix0 = FASTFLOOR( x ); // Integer part of x
fx0 = x - ix0; // Fractional part of x
fx1 = fx0 - 1.0f;
ix1 = (( ix0 + 1 ) % px) & 0xff; // Wrap to 0..px-1 *and* wrap to 0..255
ix0 = ( ix0 % px ) & 0xff; // (because px might be greater than 256)
s = FADE( fx0 );
n0 = grad1( perm[ ix0 ], fx0 );
n1 = grad1( perm[ ix1 ], fx1 );
return 0.188f * ( LERP( s, n0, n1 ) );
}
//---------------------------------------------------------------------
/** 2D float Perlin noise.
*/
float noise2( float x, float y )
{
int ix0, iy0, ix1, iy1;
float fx0, fy0, fx1, fy1;
float s, t, nx0, nx1, n0, n1;
ix0 = FASTFLOOR( x ); // Integer part of x
iy0 = FASTFLOOR( y ); // Integer part of y
fx0 = x - ix0; // Fractional part of x
fy0 = y - iy0; // Fractional part of y
fx1 = fx0 - 1.0f;
fy1 = fy0 - 1.0f;
ix1 = (ix0 + 1) & 0xff; // Wrap to 0..255
iy1 = (iy0 + 1) & 0xff;
ix0 = ix0 & 0xff;
iy0 = iy0 & 0xff;
t = FADE( fy0 );
s = FADE( fx0 );
nx0 = grad2(perm[ix0 + perm[iy0]], fx0, fy0);
nx1 = grad2(perm[ix0 + perm[iy1]], fx0, fy1);
n0 = LERP( t, nx0, nx1 );
nx0 = grad2(perm[ix1 + perm[iy0]], fx1, fy0);
nx1 = grad2(perm[ix1 + perm[iy1]], fx1, fy1);
n1 = LERP(t, nx0, nx1);
return 0.507f * ( LERP( s, n0, n1 ) );
}
//---------------------------------------------------------------------
/** 2D float Perlin periodic noise.
*/
float pnoise2( float x, float y, int px, int py )
{
int ix0, iy0, ix1, iy1;
float fx0, fy0, fx1, fy1;
float s, t, nx0, nx1, n0, n1;
ix0 = FASTFLOOR( x ); // Integer part of x
iy0 = FASTFLOOR( y ); // Integer part of y
fx0 = x - ix0; // Fractional part of x
fy0 = y - iy0; // Fractional part of y
fx1 = fx0 - 1.0f;
fy1 = fy0 - 1.0f;
ix1 = (( ix0 + 1 ) % px) & 0xff; // Wrap to 0..px-1 and wrap to 0..255
iy1 = (( iy0 + 1 ) % py) & 0xff; // Wrap to 0..py-1 and wrap to 0..255
ix0 = ( ix0 % px ) & 0xff;
iy0 = ( iy0 % py ) & 0xff;
t = FADE( fy0 );
s = FADE( fx0 );
nx0 = grad2(perm[ix0 + perm[iy0]], fx0, fy0);
nx1 = grad2(perm[ix0 + perm[iy1]], fx0, fy1);
n0 = LERP( t, nx0, nx1 );
nx0 = grad2(perm[ix1 + perm[iy0]], fx1, fy0);
nx1 = grad2(perm[ix1 + perm[iy1]], fx1, fy1);
n1 = LERP(t, nx0, nx1);
return 0.507f * ( LERP( s, n0, n1 ) );
}
//---------------------------------------------------------------------
/** 3D float Perlin noise.
*/
float noise3( float x, float y, float z )
{
int ix0, iy0, ix1, iy1, iz0, iz1;
float fx0, fy0, fz0, fx1, fy1, fz1;
float s, t, r;
float nxy0, nxy1, nx0, nx1, n0, n1;
ix0 = FASTFLOOR( x ); // Integer part of x
iy0 = FASTFLOOR( y ); // Integer part of y
iz0 = FASTFLOOR( z ); // Integer part of z
fx0 = x - ix0; // Fractional part of x
fy0 = y - iy0; // Fractional part of y
fz0 = z - iz0; // Fractional part of z
fx1 = fx0 - 1.0f;
fy1 = fy0 - 1.0f;
fz1 = fz0 - 1.0f;
ix1 = ( ix0 + 1 ) & 0xff; // Wrap to 0..255
iy1 = ( iy0 + 1 ) & 0xff;
iz1 = ( iz0 + 1 ) & 0xff;
ix0 = ix0 & 0xff;
iy0 = iy0 & 0xff;
iz0 = iz0 & 0xff;
r = FADE( fz0 );
t = FADE( fy0 );
s = FADE( fx0 );
nxy0 = grad3(perm[ix0 + perm[iy0 + perm[iz0]]], fx0, fy0, fz0);
nxy1 = grad3(perm[ix0 + perm[iy0 + perm[iz1]]], fx0, fy0, fz1);
nx0 = LERP( r, nxy0, nxy1 );
nxy0 = grad3(perm[ix0 + perm[iy1 + perm[iz0]]], fx0, fy1, fz0);
nxy1 = grad3(perm[ix0 + perm[iy1 + perm[iz1]]], fx0, fy1, fz1);
nx1 = LERP( r, nxy0, nxy1 );
n0 = LERP( t, nx0, nx1 );
nxy0 = grad3(perm[ix1 + perm[iy0 + perm[iz0]]], fx1, fy0, fz0);
nxy1 = grad3(perm[ix1 + perm[iy0 + perm[iz1]]], fx1, fy0, fz1);
nx0 = LERP( r, nxy0, nxy1 );
nxy0 = grad3(perm[ix1 + perm[iy1 + perm[iz0]]], fx1, fy1, fz0);
nxy1 = grad3(perm[ix1 + perm[iy1 + perm[iz1]]], fx1, fy1, fz1);
nx1 = LERP( r, nxy0, nxy1 );
n1 = LERP( t, nx0, nx1 );
return 0.936f * ( LERP( s, n0, n1 ) );
}
//---------------------------------------------------------------------
/** 3D float Perlin periodic noise.
*/
float pnoise3( float x, float y, float z, int px, int py, int pz )
{
int ix0, iy0, ix1, iy1, iz0, iz1;
float fx0, fy0, fz0, fx1, fy1, fz1;
float s, t, r;
float nxy0, nxy1, nx0, nx1, n0, n1;
ix0 = FASTFLOOR( x ); // Integer part of x
iy0 = FASTFLOOR( y ); // Integer part of y
iz0 = FASTFLOOR( z ); // Integer part of z
fx0 = x - ix0; // Fractional part of x
fy0 = y - iy0; // Fractional part of y
fz0 = z - iz0; // Fractional part of z
fx1 = fx0 - 1.0f;
fy1 = fy0 - 1.0f;
fz1 = fz0 - 1.0f;
ix1 = (( ix0 + 1 ) % px ) & 0xff; // Wrap to 0..px-1 and wrap to 0..255
iy1 = (( iy0 + 1 ) % py ) & 0xff; // Wrap to 0..py-1 and wrap to 0..255
iz1 = (( iz0 + 1 ) % pz ) & 0xff; // Wrap to 0..pz-1 and wrap to 0..255
ix0 = ( ix0 % px ) & 0xff;
iy0 = ( iy0 % py ) & 0xff;
iz0 = ( iz0 % pz ) & 0xff;
r = FADE( fz0 );
t = FADE( fy0 );
s = FADE( fx0 );
nxy0 = grad3(perm[ix0 + perm[iy0 + perm[iz0]]], fx0, fy0, fz0);
nxy1 = grad3(perm[ix0 + perm[iy0 + perm[iz1]]], fx0, fy0, fz1);
nx0 = LERP( r, nxy0, nxy1 );
nxy0 = grad3(perm[ix0 + perm[iy1 + perm[iz0]]], fx0, fy1, fz0);
nxy1 = grad3(perm[ix0 + perm[iy1 + perm[iz1]]], fx0, fy1, fz1);
nx1 = LERP( r, nxy0, nxy1 );
n0 = LERP( t, nx0, nx1 );
nxy0 = grad3(perm[ix1 + perm[iy0 + perm[iz0]]], fx1, fy0, fz0);
nxy1 = grad3(perm[ix1 + perm[iy0 + perm[iz1]]], fx1, fy0, fz1);
nx0 = LERP( r, nxy0, nxy1 );
nxy0 = grad3(perm[ix1 + perm[iy1 + perm[iz0]]], fx1, fy1, fz0);
nxy1 = grad3(perm[ix1 + perm[iy1 + perm[iz1]]], fx1, fy1, fz1);
nx1 = LERP( r, nxy0, nxy1 );
n1 = LERP( t, nx0, nx1 );
return 0.936f * ( LERP( s, n0, n1 ) );
}
//---------------------------------------------------------------------
/** 4D float Perlin noise.
*/
float noise4( float x, float y, float z, float w )
{
int ix0, iy0, iz0, iw0, ix1, iy1, iz1, iw1;
float fx0, fy0, fz0, fw0, fx1, fy1, fz1, fw1;
float s, t, r, q;
float nxyz0, nxyz1, nxy0, nxy1, nx0, nx1, n0, n1;
ix0 = FASTFLOOR( x ); // Integer part of x
iy0 = FASTFLOOR( y ); // Integer part of y
iz0 = FASTFLOOR( z ); // Integer part of y
iw0 = FASTFLOOR( w ); // Integer part of w
fx0 = x - ix0; // Fractional part of x
fy0 = y - iy0; // Fractional part of y
fz0 = z - iz0; // Fractional part of z
fw0 = w - iw0; // Fractional part of w
fx1 = fx0 - 1.0f;
fy1 = fy0 - 1.0f;
fz1 = fz0 - 1.0f;
fw1 = fw0 - 1.0f;
ix1 = ( ix0 + 1 ) & 0xff; // Wrap to 0..255
iy1 = ( iy0 + 1 ) & 0xff;
iz1 = ( iz0 + 1 ) & 0xff;
iw1 = ( iw0 + 1 ) & 0xff;
ix0 = ix0 & 0xff;
iy0 = iy0 & 0xff;
iz0 = iz0 & 0xff;
iw0 = iw0 & 0xff;
q = FADE( fw0 );
r = FADE( fz0 );
t = FADE( fy0 );
s = FADE( fx0 );
nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx0, fy0, fz0, fw0);
nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx0, fy0, fz0, fw1);
nxy0 = LERP( q, nxyz0, nxyz1 );
nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx0, fy0, fz1, fw0);
nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx0, fy0, fz1, fw1);
nxy1 = LERP( q, nxyz0, nxyz1 );
nx0 = LERP ( r, nxy0, nxy1 );
nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx0, fy1, fz0, fw0);
nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx0, fy1, fz0, fw1);
nxy0 = LERP( q, nxyz0, nxyz1 );
nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx0, fy1, fz1, fw0);
nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx0, fy1, fz1, fw1);
nxy1 = LERP( q, nxyz0, nxyz1 );
nx1 = LERP ( r, nxy0, nxy1 );
n0 = LERP( t, nx0, nx1 );
nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx1, fy0, fz0, fw0);
nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx1, fy0, fz0, fw1);
nxy0 = LERP( q, nxyz0, nxyz1 );
nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx1, fy0, fz1, fw0);
nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx1, fy0, fz1, fw1);
nxy1 = LERP( q, nxyz0, nxyz1 );
nx0 = LERP ( r, nxy0, nxy1 );
nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx1, fy1, fz0, fw0);
nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx1, fy1, fz0, fw1);
nxy0 = LERP( q, nxyz0, nxyz1 );
nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx1, fy1, fz1, fw0);
nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx1, fy1, fz1, fw1);
nxy1 = LERP( q, nxyz0, nxyz1 );
nx1 = LERP ( r, nxy0, nxy1 );
n1 = LERP( t, nx0, nx1 );
return 0.87f * ( LERP( s, n0, n1 ) );
}
//---------------------------------------------------------------------
/** 4D float Perlin periodic noise.
*/
float pnoise4( float x, float y, float z, float w,
int px, int py, int pz, int pw )
{
int ix0, iy0, iz0, iw0, ix1, iy1, iz1, iw1;
float fx0, fy0, fz0, fw0, fx1, fy1, fz1, fw1;
float s, t, r, q;
float nxyz0, nxyz1, nxy0, nxy1, nx0, nx1, n0, n1;
ix0 = FASTFLOOR( x ); // Integer part of x
iy0 = FASTFLOOR( y ); // Integer part of y
iz0 = FASTFLOOR( z ); // Integer part of y
iw0 = FASTFLOOR( w ); // Integer part of w
fx0 = x - ix0; // Fractional part of x
fy0 = y - iy0; // Fractional part of y
fz0 = z - iz0; // Fractional part of z
fw0 = w - iw0; // Fractional part of w
fx1 = fx0 - 1.0f;
fy1 = fy0 - 1.0f;
fz1 = fz0 - 1.0f;
fw1 = fw0 - 1.0f;
ix1 = (( ix0 + 1 ) % px ) & 0xff; // Wrap to 0..px-1 and wrap to 0..255
iy1 = (( iy0 + 1 ) % py ) & 0xff; // Wrap to 0..py-1 and wrap to 0..255
iz1 = (( iz0 + 1 ) % pz ) & 0xff; // Wrap to 0..pz-1 and wrap to 0..255
iw1 = (( iw0 + 1 ) % pw ) & 0xff; // Wrap to 0..pw-1 and wrap to 0..255
ix0 = ( ix0 % px ) & 0xff;
iy0 = ( iy0 % py ) & 0xff;
iz0 = ( iz0 % pz ) & 0xff;
iw0 = ( iw0 % pw ) & 0xff;
q = FADE( fw0 );
r = FADE( fz0 );
t = FADE( fy0 );
s = FADE( fx0 );
nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx0, fy0, fz0, fw0);
nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx0, fy0, fz0, fw1);
nxy0 = LERP( q, nxyz0, nxyz1 );
nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx0, fy0, fz1, fw0);
nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx0, fy0, fz1, fw1);
nxy1 = LERP( q, nxyz0, nxyz1 );
nx0 = LERP ( r, nxy0, nxy1 );
nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx0, fy1, fz0, fw0);
nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx0, fy1, fz0, fw1);
nxy0 = LERP( q, nxyz0, nxyz1 );
nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx0, fy1, fz1, fw0);
nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx0, fy1, fz1, fw1);
nxy1 = LERP( q, nxyz0, nxyz1 );
nx1 = LERP ( r, nxy0, nxy1 );
n0 = LERP( t, nx0, nx1 );
nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx1, fy0, fz0, fw0);
nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx1, fy0, fz0, fw1);
nxy0 = LERP( q, nxyz0, nxyz1 );
nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx1, fy0, fz1, fw0);
nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx1, fy0, fz1, fw1);
nxy1 = LERP( q, nxyz0, nxyz1 );
nx0 = LERP ( r, nxy0, nxy1 );
nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx1, fy1, fz0, fw0);
nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx1, fy1, fz0, fw1);
nxy0 = LERP( q, nxyz0, nxyz1 );
nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx1, fy1, fz1, fw0);
nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx1, fy1, fz1, fw1);
nxy1 = LERP( q, nxyz0, nxyz1 );
nx1 = LERP ( r, nxy0, nxy1 );
n1 = LERP( t, nx0, nx1 );
return 0.87f * ( LERP( s, n0, n1 ) );
}
//---------------------------------------------------------------------

41
src/noise1234.h Normal file
View File

@@ -0,0 +1,41 @@
// noise1234
//
// Author: Stefan Gustavson, 2003-2005
// Contact: stefan.gustavson@liu.se
//
// This code was GPL licensed until February 2011.
// As the original author of this code, I hereby
// release it into the public domain.
// Please feel free to use it for whatever you want.
// Credit is appreciated where appropriate, and I also
// appreciate being told where this code finds any use,
// but you may do as you like.
/*
* This implementation is "Improved Noise" as presented by
* Ken Perlin at Siggraph 2002. The 3D function is a direct port
* of his Java reference code which was once publicly available
* on www.noisemachine.com (although I cleaned it up, made it
* faster and made the code more readable), but the 1D, 2D and
* 4D functions were implemented from scratch by me.
*
* This is a backport to C of my improved noise class in C++
* which was included in the Aqsis renderer project.
* It is highly reusable without source code modifications.
*
*/
/** 1D, 2D, 3D and 4D float Perlin noise
*/
extern float noise1( float x );
extern float noise2( float x, float y );
extern float noise3( float x, float y, float z );
extern float noise4( float x, float y, float z, float w );
/** 1D, 2D, 3D and 4D float Perlin periodic noise
*/
extern float pnoise1( float x, int px );
extern float pnoise2( float x, float y, int px, int py );
extern float pnoise3( float x, float y, float z, int px, int py, int pz );
extern float pnoise4( float x, float y, float z, float w,
int px, int py, int pz, int pw );

View File

@@ -4,11 +4,12 @@
#include<winsock2.h>
#include<ws2tcpip.h>
#include<ntsecapi.h>
#include<iphlpapi.h>
#else
#include<netdb.h>
#include<sys/socket.h>
#include<sys/random.h>
#include<arpa/inet.h>
#include<ifaddrs.h>
#endif
#include<unistd.h>
#include<sys/types.h>
@@ -34,6 +35,13 @@
#define RAND(b, i) RtlGenRandom(b, i)
#else
#define RAND(b, i) getrandom(b, i, 0)
static void getrandom(void *buf, size_t amount, int flags) {
static FILE *f;
if(!f) {
f = fopen("/dev/urandom", "rb");
}
fread(buf, 1, amount, f);
}
#endif
struct StunMsg {
@@ -43,7 +51,7 @@ struct StunMsg {
uint8_t id[12];
};
static int stoon_init_mini(struct addrinfo *serv, uint16_t myport) {
static int stoon_init_mini(struct Stoon *this, struct addrinfo *serv, uint16_t myport) {
#ifdef _WIN32
errno = 0;
int fd = socket(serv->ai_family, serv->ai_socktype, serv->ai_protocol);
@@ -59,16 +67,79 @@ static int stoon_init_mini(struct addrinfo *serv, uint16_t myport) {
char p[6];
sprintf(p, "%u", myport);
struct addrinfo *myaddr;
if(getaddrinfo(NULL, p, &(struct addrinfo) {.ai_family = serv->ai_family, .ai_socktype = SOCK_DGRAM, .ai_protocol = IPPROTO_UDP, .ai_flags = AI_PASSIVE}, &myaddr)) {
struct addrinfo *myaddrinfo;
if(getaddrinfo(NULL, p, &(struct addrinfo) {.ai_family = serv->ai_family, .ai_socktype = SOCK_DGRAM, .ai_protocol = IPPROTO_UDP, .ai_flags = AI_PASSIVE}, &myaddrinfo)) {
close(fd);
return -1;
}
if(bind(fd, myaddr->ai_addr, myaddr->ai_addrlen)) {
if(bind(fd, myaddrinfo->ai_addr, myaddrinfo->ai_addrlen)) {
close(fd);
return -2;
}
freeaddrinfo(myaddr);
freeaddrinfo(myaddrinfo);
#ifdef _WIN32
size_t sz = 1024 * 64;
IP_ADAPTER_ADDRESSES *addrs = malloc(sz);
if(GetAdaptersAddresses(serv->ai_family, GAA_FLAG_SKIP_MULTICAST, NULL, addrs, &sz) == NO_ERROR) {
for(IP_ADAPTER_ADDRESSES *ifa = addrs; ifa; ifa = ifa->Next) {
if(!ifa->FirstUnicastAddress) {
continue;
}
if(serv->ai_family == AF_INET6) {
uint8_t *addr = (void*) &((struct sockaddr_in6*) ifa->FirstUnicastAddress->Address.lpSockaddr)->sin6_addr;
if(addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && addr[3] == 0 && addr[4] == 0 && addr[5] == 0 && addr[6] == 0 && addr[7] == 0 && addr[8] == 0 && addr[9] == 0 && addr[10] == 0 && addr[11] == 0 && addr[12] == 0 && addr[13] == 0 && addr[14] == 0 && (addr[15] == 0 || addr[15] == 1)) {
continue;
}
memcpy(this->peercode.localV6, addr, 16);
memcpy(this->peercode.localP6, &myport, 2);
} else {
uint8_t *addr = (void*) &((struct sockaddr_in*) ifa->FirstUnicastAddress->Address.lpSockaddr)->sin_addr;
if(addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && addr[3] == 0 || addr[0] == 127 && addr[1] == 0 && addr[2] == 0 && addr[3] == 1) {
continue;
}
memcpy(this->peercode.localV4, addr, 4);
memcpy(this->peercode.localP4, &myport, 2);
}
}
}
free(addrs);
#else
struct ifaddrs *ifaddr;
if(getifaddrs(&ifaddr) >= 0) {
for(struct ifaddrs *ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
if(!ifa->ifa_addr || ifa->ifa_addr->sa_family != serv->ai_family) {
continue;
}
if(serv->ai_family == AF_INET6) {
uint8_t *addr = (void*) &((struct sockaddr_in6*) ifa->ifa_addr)->sin6_addr;
if(addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && addr[3] == 0 && addr[4] == 0 && addr[5] == 0 && addr[6] == 0 && addr[7] == 0 && addr[8] == 0 && addr[9] == 0 && addr[10] == 0 && addr[11] == 0 && addr[12] == 0 && addr[13] == 0 && addr[14] == 0 && (addr[15] == 0 || addr[15] == 1)) {
continue;
}
memcpy(this->peercode.localV6, addr, 16);
memcpy(this->peercode.localP6, &myport, 2);
} else {
uint8_t *addr = (void*) &((struct sockaddr_in*) ifa->ifa_addr)->sin_addr;
if(addr[0] == 0 && addr[1] == 0 && addr[2] == 0 && addr[3] == 0 || addr[0] == 127 && addr[1] == 0 && addr[2] == 0 && addr[3] == 1) {
continue;
}
memcpy(this->peercode.localV4, addr, 4);
memcpy(this->peercode.localP4, &myport, 2);
}
break;
}
freeifaddrs(ifaddr);
}
#endif
return fd;
}
@@ -92,18 +163,16 @@ struct Stoon stoon_init(const char *stunhost, uint16_t stunport, uint16_t myport
}
}
struct Stoon ret;
struct Stoon ret = {};
memset(&ret.my4, 0, sizeof(ret.my4));
if(v4) {
memcpy(&ret.stu4, v4->ai_addr, v4->ai_addrlen);
ret.fd4 = stoon_init_mini(v4, myport);
ret.fd4 = stoon_init_mini(&ret, v4, myport);
} else ret.fd4 = -1;
memset(&ret.my6, 0, sizeof(ret.my6));
if(v6) {
memcpy(&ret.stu6, v6->ai_addr, v6->ai_addrlen);
ret.fd6 = stoon_init_mini(v6, myport);
ret.fd6 = stoon_init_mini(&ret, v6, myport);
} else ret.fd6 = -1;
ret.poonchstage = 0;
@@ -121,12 +190,21 @@ static int stoon_req_mini(struct Stoon *this, int *fd, struct sockaddr *serv, in
if(errno == ENETUNREACH) {
close(*fd);
*fd = -1;
return false;
}
}
return true;
}
int stoon_req(struct Stoon *this) {
if(this->fd4 >= 0) stoon_req_mini(this, &this->fd4, (struct sockaddr*) &this->stu4, sizeof(struct sockaddr_in));
if(this->fd6 >= 0) stoon_req_mini(this, &this->fd6, (struct sockaddr*) &this->stu6, sizeof(struct sockaddr_in6));
if(this->fd4 < 0 && this->fd6 < 0) {
return false;
}
return true;
}
static int stoon_listen_mini(struct Stoon *this, int fd, struct sockaddr *serv, int servlen) {
@@ -161,11 +239,10 @@ static int stoon_listen_mini(struct Stoon *this, int fd, struct sockaddr *serv,
uint16_t netfam = ntohs(((uint16_t*) d)[2]);
uint16_t publicPort = ntohs(((uint16_t*) d)[3]) ^ (STUN_MAGIC >> 16);
if(netfam == STUN_NETFAM_IPV4) {
uint32_t publicIp = ntohl(((uint32_t*) d)[2]) ^ STUN_MAGIC;
uint32_t publicIp = htonl(ntohl(((uint32_t*) d)[2]) ^ STUN_MAGIC);
this->my4.sin_family = AF_INET;
memcpy(&this->my4.sin_addr, &publicIp, 4);
this->my4.sin_port = htons(publicPort);
memcpy(this->peercode.publicV4, &publicIp, 4);
memcpy(this->peercode.publicP4, &publicPort, 2);
return 1;
} else if(netfam == STUN_NETFAM_IPV6) {
@@ -175,9 +252,8 @@ static int stoon_listen_mini(struct Stoon *this, int fd, struct sockaddr *serv,
publicIp[2] = ((uint32_t*) d)[4] ^ ((uint32_t*) res.base.id)[1];
publicIp[3] = ((uint32_t*) d)[5] ^ ((uint32_t*) res.base.id)[2];
this->my6.sin6_family = AF_INET6;
memcpy(&this->my6.sin6_addr, &publicIp, 16);
this->my6.sin6_port = htons(publicPort);
memcpy(this->peercode.publicV6, &publicIp, 16);
memcpy(this->peercode.publicP6, &publicPort, 2);
return 1;
} else {
@@ -188,12 +264,12 @@ static int stoon_listen_mini(struct Stoon *this, int fd, struct sockaddr *serv,
d += 4 + attribLen;
}
return 0;
return false;
}
int stoon_listen(struct Stoon *this) {
if(this->fd4 >= 0) if(stoon_listen_mini(this, this->fd4, (struct sockaddr*) &this->stu4, sizeof(struct sockaddr_in)) < 0) return 0;
if(this->fd6 >= 0) if(stoon_listen_mini(this, this->fd6, (struct sockaddr*) &this->stu6, sizeof(struct sockaddr_in6)) < 0) return 0;
return 1;
return true;
}
void stoon_keepalive(struct Stoon *this) {
@@ -217,31 +293,7 @@ void stoon_kill(struct Stoon *this) {
this->fd6 = -1;
}
int stoon_v4_available(struct Stoon *this) {
return this->fd4 >= 0;
}
int stoon_v6_available(struct Stoon *this) {
return this->fd6 >= 0;
}
void stoon_serialize(struct Stoon *this, uint8_t ret[static STOON_CONN_INFO_SIZE]) {
if(this->fd4 >= 0) {
memcpy(ret + 0, &this->my4.sin_addr, 4);
memcpy(ret + 4, &this->my4.sin_port, 2);
} else {
memset(ret, 0, 6);
}
if(this->fd6 >= 0) {
memcpy(ret + 6, &this->my6.sin6_addr, 16);
memcpy(ret + 22, &this->my6.sin6_port, 2);
} else {
memset(ret + 6, 0, 18);
}
}
int stoon_poonch(struct Stoon *this, const uint8_t peerdata[static STOON_CONN_INFO_SIZE]) {
/*int stoon_poonch(struct Stoon *this, const uint8_t peerdata[static STOON_CONN_INFO_SIZE]) {
struct {
uint32_t addr4;
uint16_t port4;
@@ -303,7 +355,7 @@ int stoon_poonch(struct Stoon *this, const uint8_t peerdata[static STOON_CONN_IN
}
return STOON_POONCH_NO_KNOCK;
}
}*/
#ifdef STOON_STANDALONE
int main() {

View File

@@ -6,6 +6,7 @@
#include<stddef.h>
#include<stdint.h>
#include<stdbool.h>
#ifdef _WIN32
#include<winsock2.h>
@@ -16,8 +17,6 @@
/* Standalone hole punching libary (IPv4 & IPv6 compatible) */
#define STOON_CONN_INFO_SIZE (4 + 2 + 16 + 2)
#define POONCH_MAGIC 0x504F4348
#define POONCH_STAGE_KNOCKING 0
#define POONCH_STAGE_ACK 1
@@ -26,16 +25,30 @@ struct Poonch {
uint32_t stage;
};
struct StoonPeercode {
uint8_t publicV4[4];
uint8_t publicP4[2];
uint8_t publicV6[16];
uint8_t publicP6[2];
uint8_t localV4[4];
uint8_t localP4[2];
uint8_t localV6[16];
uint8_t localP6[2];
};
struct Stoon {
struct sockaddr_in stu4;
struct sockaddr_in my4;
int fd4;
struct sockaddr_in6 stu6;
struct sockaddr_in6 my6;
int fd6;
uint8_t poonchstage;
struct StoonPeercode peercode;
};
// stunhost: Self-explanatory
@@ -53,12 +66,8 @@ void stoon_keepalive(struct Stoon*);
void stoon_kill(struct Stoon*);
int stoon_v4_available(struct Stoon*);
int stoon_v6_available(struct Stoon*);
void stoon_serialize(struct Stoon*, uint8_t ret[static STOON_CONN_INFO_SIZE]);
#define STOON_POONCH_INCOMPATIBLE_NETFAMS (-1)
/*#define STOON_POONCH_INCOMPATIBLE_NETFAMS (-1)
#define STOON_POONCH_NO_KNOCK 0
#define STOON_POONCH_ACKED 1
int stoon_poonch(struct Stoon*, const uint8_t peerdata[static STOON_CONN_INFO_SIZE]);
*/