Compare commits

..

7 Commits

Author SHA1 Message Date
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
5 changed files with 62 additions and 21 deletions

View File

@ -1 +1,17 @@
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
## v1
Initial release.

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

@ -1294,7 +1294,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 +1317,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 +1493,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 +1511,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] = '/';
@ -2095,6 +2095,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 +2223,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 +3381,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 +4392,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");
if(lua_type(L, -1) == LUA_TBOOLEAN) {
mat->passes[0].alphatest = lua_toboolean(L, -1); 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) {