Compare commits

...

19 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
9 changed files with 85 additions and 31 deletions

View File

@@ -14,9 +14,9 @@ jobs:
with: with:
submodules: 'true' submodules: 'true'
- run: mkdir build build/k3 build/k3/compr bin bin/assets - run: mkdir build build/k3 build/k3/compr 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: 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: 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 -include /home/git/force_link_glibc_2.20.h" 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: cp /usr/lib/gcc/i686-w64-mingw32/12-win32/libgcc_s_dw2-1.dll /usr/lib/gcc/i686-w64-mingw32/12-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/12-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: cp -r /home/git/k4templateassets/* bin/assets/
- run: mv bin k4 - run: mv bin k4
- run: zip -9r "k4${{ github.ref_name }}.zip" k4/ - run: zip -9r "k4${{ github.ref_name }}.zip" k4/

View File

@@ -10,14 +10,14 @@ k3_HDRS := $(call rwildcard,k3/src,*.h)
k3_OBJS := $(patsubst k3/src/%.c, build/k3/%.o, $(k3_SRCS)) k3_OBJS := $(patsubst k3/src/%.c, build/k3/%.o, $(k3_SRCS))
k3_DEPS := $(patsubst k3/src/%.c, build/k3/%.d, $(k3_SRCS)) k3_DEPS := $(patsubst k3/src/%.c, build/k3/%.d, $(k3_SRCS))
CFLAGS := $(CFLAGS) -D_GNU_SOURCE -D_DEFAULT_SOURCE -Ik3/src -O2 -fopenmp -flto -s 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))) 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 -Isrc $(CFLAGS) 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) 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 else
CFLAGS := -march=opteron $(SAN) -std=gnu99 -DENET_FEATURE_ADDRESS_MAPPING -fms-extensions -fno-pic -no-pie -fno-pie -Isrc $(CFLAGS) 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 -lportaudio $(LIBS) LIBS := -lglfw3 -pthread -ldl -lm -lode -lstdc++ -llua5.3 -lvorbis -lvorbisfile -logg -lasound -lfreetype -lportaudio -lz $(LIBS)
endif endif
CFLAGS := $(CFLAGS) -DLOCALHOST_ONLY CFLAGS := $(CFLAGS) -DLOCALHOST_ONLY

View File

@@ -1 +1,21 @@
Homepage: https://mid.net.ua/k4.html 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.

2
k3

Submodule k3 updated: 4d74b5e3e9...56ecba05b1

View File

@@ -1017,7 +1017,7 @@ void game_killentity(uint16_t eid) {
if(cr) { if(cr) {
if(cr->cache) { if(cr->cache) {
if(resman_rev(cr->cache)) { if(resman_rev(cr->cache)) {
resman_unref(RESMAN_MODEL, cr->cache); resman_unref_ptr(RESMAN_MODEL, cr->cache);
} }
} }

View File

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

View File

@@ -19,6 +19,7 @@
#include<GLFW/glfw3.h> #include<GLFW/glfw3.h>
#include"ssort.h" #include"ssort.h"
#include<ctype.h> #include<ctype.h>
#include<math.h>
/* /*
* This is by far the least clean or well-maintained source in the * This is by far the least clean or well-maintained source in the
@@ -341,7 +342,9 @@ static int game_addentity(lua_State *L) {
setstrstatic("mdl", c.mdl, sizeof(c.mdl)); setstrstatic("mdl", c.mdl, sizeof(c.mdl));
c.cache = k3MdlCopySubs((struct k3Mdl*) resman_ref(RESMAN_MODEL, c.mdl)); if(strlen(c.mdl)) {
c.cache = k3MdlCopySubs((struct k3Mdl*) resman_ref(RESMAN_MODEL, c.mdl));
}
game_addcomponent(render, &c); game_addcomponent(render, &c);
} }
@@ -1294,7 +1297,7 @@ static int game_get(lua_State *L) {
if(UiActive) { if(UiActive) {
struct menuitem *item = lua_newuserdata(L, sizeof(*item)); struct menuitem *item = lua_newuserdata(L, sizeof(*item));
item->type = MENUITEM_SCREEN; item->type = MENUITEM_SCREEN;
item->ptr = UiActive; item->ptr = (struct k3MObj*) UiActive;
} else { } else {
lua_pushnil(L); lua_pushnil(L);
} }
@@ -1317,16 +1320,16 @@ static int game_set(lua_State *L) {
LuaapiFar = lua_tonumber(L, 3); LuaapiFar = lua_tonumber(L, 3);
} else if(!strcmp(i, "menu")) { } else if(!strcmp(i, "menu")) {
struct menuitem *item = lua_touserdata(L, 3); struct menuitem *item = lua_touserdata(L, 3);
UiActive = item ? item->ptr : NULL; UiActive = item ? (struct k3MScreen*) item->ptr : NULL;
set_ui_mode(!!UiActive); k4_set_ui_mode(!!UiActive);
if(UiActive) { if(UiActive) {
UiActive->w = UiActive->wDesired = GameWndW; UiActive->w = UiActive->wDesired = GameWndW;
UiActive->h = UiActive->hDesired = GameWndH; UiActive->h = UiActive->hDesired = GameWndH;
k3MMeasure(UiActive); k3MMeasure((struct k3MObj*) UiActive);
k3MArrange(UiActive); k3MArrange((struct k3MObj*) UiActive);
} }
} else { } else {
lua_pushvalue(L, 2); lua_pushvalue(L, 2);
@@ -1493,7 +1496,7 @@ static int luaapi_require(lua_State *L) {
} }
for(int i = 0; i < nameLen;) { for(int i = 0; i < nameLen;) {
if(!isalpha(name[i]) && !isdigit(name[i]) && name[i] != '_' && name[i] != '-') { if(!isalpha(name[i]) && !isdigit(name[i]) && name[i] != '_' && name[i] != '-' && name[i] != '.') {
memmove(name + i + 1, name + i, --nameLen - i); memmove(name + i + 1, name + i, --nameLen - i);
} else i++; } else i++;
} }
@@ -1511,7 +1514,7 @@ static int luaapi_require(lua_State *L) {
} }
char buf[128]; char buf[128];
snprintf(buf, sizeof(buf), "%s.lua", name); snprintf(buf, sizeof(buf), "%.*s.lua", (int) nameLen, name);
buf[127] = 0; buf[127] = 0;
for(size_t i = 0; buf[i] && i < strlen(buf) - 4; i++) { for(size_t i = 0; buf[i] && i < strlen(buf) - 4; i++) {
if(buf[i] == '.') buf[i] = '/'; if(buf[i] == '.') buf[i] = '/';
@@ -1722,7 +1725,7 @@ static int dagame_mdl(lua_State *L) {
} }
lua_pop(L, 1); lua_pop(L, 1);
struct k3Mdl *mdl = k3MdlCreate(vertexCount, indexCount, 0, positions, normals, uvs, NULL, NULL, NULL, indices, NULL, NULL); struct k3Mdl *mdl = k3MdlCreate(vertexCount, indexCount, 0, positions, normals, (float*) uvs, NULL, NULL, NULL, indices, NULL, NULL);
struct k3Mdl **ud = lua_newuserdata(L, sizeof(*ud)); struct k3Mdl **ud = lua_newuserdata(L, sizeof(*ud));
*ud = mdl; *ud = mdl;
@@ -1855,7 +1858,7 @@ static int dagame_ray_get(lua_State *L) {
return 1; return 1;
} else if(!strcmp(key, "ready")) { } else if(!strcmp(key, "ready")) {
lua_pushboolean(L, !isnanf(lr->out[0])); lua_pushboolean(L, !isnan(lr->out[0]));
return 1; return 1;
} }
@@ -2095,6 +2098,17 @@ static int dagame_k3menuitem_add_child(lua_State *L) {
return 1; return 1;
} }
static int dagame_k3menuitem_remove_child(lua_State *L) {
struct menuitem *parent = lua_touserdata(L, 1);
struct menuitem *child = lua_touserdata(L, 2);
k3MRemoveChild(parent->ptr, child->ptr);
lua_pushvalue(L, 1);
return 1;
}
static bool k3menuitem_event_callback(struct k3MEvent *ev, uint8_t *ud_) { static bool k3menuitem_event_callback(struct k3MEvent *ev, uint8_t *ud_) {
void **ud = ud_; void **ud = ud_;
@@ -2212,6 +2226,8 @@ static int dagame_k3menuitem_get(lua_State *L) {
lua_pushcfunction(L, dagame_k3menuitem_set_bounds); lua_pushcfunction(L, dagame_k3menuitem_set_bounds);
} else if(!strcmp(lua_tostring(L, 2), "add_child")) { } else if(!strcmp(lua_tostring(L, 2), "add_child")) {
lua_pushcfunction(L, dagame_k3menuitem_add_child); lua_pushcfunction(L, dagame_k3menuitem_add_child);
} else if(!strcmp(lua_tostring(L, 2), "remove_child")) {
lua_pushcfunction(L, dagame_k3menuitem_remove_child);
} else if(!strcmp(lua_tostring(L, 2), "on")) { } else if(!strcmp(lua_tostring(L, 2), "on")) {
lua_pushcfunction(L, dagame_k3menuitem_on); lua_pushcfunction(L, dagame_k3menuitem_on);
} else if(!strcmp(lua_tostring(L, 2), "measure")) { } else if(!strcmp(lua_tostring(L, 2), "measure")) {
@@ -3368,13 +3384,17 @@ void luaapi_init() {
k3Log(k3_DEBUG, "Loading Lua stdlib"); k3Log(k3_DEBUG, "Loading Lua stdlib");
luaL_requiref(L, "_G", luaopen_base, 1); size_t numpkgs = 0;
luaL_requiref(L, LUA_TABLIBNAME, luaopen_table, 1); numpkgs++, luaL_requiref(L, "_G", luaopen_base, 1);
luaL_requiref(L, LUA_STRLIBNAME, luaopen_string, 1); numpkgs++, luaL_requiref(L, LUA_TABLIBNAME, luaopen_table, 1);
luaL_requiref(L, LUA_MATHLIBNAME, luaopen_math, 1); numpkgs++, luaL_requiref(L, LUA_STRLIBNAME, luaopen_string, 1);
luaL_requiref(L, LUA_DBLIBNAME, luaopen_debug, 1); numpkgs++, luaL_requiref(L, LUA_MATHLIBNAME, luaopen_math, 1);
luaL_requiref(L, LUA_UTF8LIBNAME, luaopen_utf8, 1); numpkgs++, luaL_requiref(L, LUA_DBLIBNAME, luaopen_debug, 1);
lua_pop(L, 6); numpkgs++, luaL_requiref(L, LUA_UTF8LIBNAME, luaopen_utf8, 1);
#ifdef LUAAPI_EXPOSE_PACKAGE_LIB
numpkgs++, luaL_requiref(L, "package", luaopen_package, 1);
#endif
lua_pop(L, numpkgs);
k3Log(k3_DEBUG, "Setting custom require"); k3Log(k3_DEBUG, "Setting custom require");
@@ -4375,7 +4395,11 @@ void luaapi_fillmaterial_direct(struct k3Mat *mat) {
lua_pop(L, 1); lua_pop(L, 1);
lua_getfield(L, -1, "alphatest"); lua_getfield(L, -1, "alphatest");
mat->passes[0].alphatest = lua_toboolean(L, -1); if(lua_type(L, -1) == LUA_TBOOLEAN) {
mat->passes[0].alphatest = lua_toboolean(L, -1);
} else {
mat->passes[0].alphatest = lua_tonumber(L, -1);
}
lua_pop(L, 1); lua_pop(L, 1);
lua_getfield(L, -1, "depthwrite"); lua_getfield(L, -1, "depthwrite");

View File

@@ -28,6 +28,7 @@
#include"k3font.h" #include"k3font.h"
#include"k3menu.h" #include"k3menu.h"
#include"k3bloom.h" #include"k3bloom.h"
#include"k3batch.h"
#include"resman.h" #include"resman.h"
@@ -37,6 +38,7 @@
#include"net_server.h" #include"net_server.h"
#include"net_client.h" #include"net_client.h"
#include"net_hi.h"
#include<ctype.h> #include<ctype.h>
@@ -60,7 +62,7 @@ static double LastTime;
#include"loaders.inc" #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); glfwSetInputMode(GameWnd, GLFW_CURSOR, yes ? GLFW_CURSOR_NORMAL : GLFW_CURSOR_DISABLED);
} }
@@ -130,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) { static void keycallback(GLFWwindow *GameWnd, int key, int scancode, int action, int mods) {
if(action == GLFW_RELEASE && key == GLFW_KEY_ESCAPE) { if(action == GLFW_RELEASE && key == GLFW_KEY_ESCAPE) {
luaapi_escape(); luaapi_escape();
set_ui_mode(!!UiActive); k4_set_ui_mode(!!UiActive);
} else { } else {
if(UiActive) { if(UiActive) {
struct k3MEvent ev = { struct k3MEvent ev = {
@@ -205,7 +207,7 @@ void k4k3LogCallback(enum k3LogLevel lvl, const char *str, size_t len) {
//if(lvl == k3_ERR) raise(SIGINT); //if(lvl == k3_ERR) raise(SIGINT);
fprintf(stderr, "%s : %s\n", prefixes[lvl], str); fprintf(stdout, "%s : %s\n", prefixes[lvl], str);
} }
struct k4Control { struct k4Control {
@@ -320,7 +322,7 @@ static void fix_resol() {
} }
static void eng_ui_init() { static void eng_ui_init() {
set_ui_mode(!!UiActive); k4_set_ui_mode(!!UiActive);
} }
static void fps_counter_step(double newDT) { static void fps_counter_step(double newDT) {
@@ -623,7 +625,7 @@ int main(int argc_, char **argv_) {
} }
if(!IrregularShadows) { if(!IrregularShadows) {
k3PassShadowmap(proj, cam, shadowmapOffscreen, fmaxf(k3TexSzMax() / 8, 512)); k3PassShadowmap(proj, cam, shadowmapOffscreen, 8);
} }
if(lowresOffscreen) { if(lowresOffscreen) {

View File

@@ -8,7 +8,6 @@
#else #else
#include<netdb.h> #include<netdb.h>
#include<sys/socket.h> #include<sys/socket.h>
#include<sys/random.h>
#include<arpa/inet.h> #include<arpa/inet.h>
#include<ifaddrs.h> #include<ifaddrs.h>
#endif #endif
@@ -36,6 +35,13 @@
#define RAND(b, i) RtlGenRandom(b, i) #define RAND(b, i) RtlGenRandom(b, i)
#else #else
#define RAND(b, i) getrandom(b, i, 0) #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 #endif
struct StunMsg { struct StunMsg {