Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
485867e
Add image overlay support to possession mode lenses
Cerwym Jan 26, 2026
dd22e83
refactored to use json loading
Cerwym Jan 26, 2026
f35386e
added example mod for lens overlay
Cerwym Jan 26, 2026
03b31b7
Merge branch 'master' into pr/4506
Loobinex Jan 26, 2026
971e0cb
changed load bit flags to descriptive enums
Cerwym Jan 26, 2026
fd8420e
Merge branch 'feature/lens-overlay' of github.com:Cerwym/keeperfx int…
Cerwym Jan 26, 2026
3af40d0
corrected render order of swipe effect and lenses
Cerwym Jan 27, 2026
11ce658
thing creature view now scales lens effect for viewport area correctly
Cerwym Jan 27, 2026
d65b056
ci added properties json for vscode mingw intellisense
Cerwym Jan 30, 2026
3fe10b1
feat allowe dfor custom lens mist effects, added logic to gracefull l…
Cerwym Jan 30, 2026
8a6de5f
refactor: extract mod fallback file loading into reusable helper func…
Cerwym Jan 30, 2026
819f549
refactor: apply mod fallback helper to mist file loading
Cerwym Jan 30, 2026
f249a5f
fix: correct mod fallback helper to check mod_dir flag and file exist…
Cerwym Jan 30, 2026
edb4221
feat: added try_load_file_from_mods_with_fallback to consolidate load…
Cerwym Jan 30, 2026
008bda5
chore: log cleanup
Cerwym Jan 30, 2026
2e64ad5
fix: decoupled lens overlay data from save code
Cerwym Jan 30, 2026
bf1af73
Some documentation.
Loobinex Jan 30, 2026
f1dc88b
fix magenta 255 is now the transparent colour
Cerwym Jan 30, 2026
c2b22fa
Merge branch 'feature/lens-overlay' of github.com:Cerwym/keeperfx int…
Cerwym Jan 30, 2026
7ad9f6c
fix added pallete conversion when loading the pngs preserve greyscale
Cerwym Jan 31, 2026
b4966e3
fix clear mist flag and biffer if lens has no overlay
Cerwym Jan 31, 2026
755f43f
remove justlog
Cerwym Jan 31, 2026
c8c9859
Removed one more JUSTLOG
Loobinex Jan 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ res/keeperfx_icon.ico
/deps/*.tar.gz
/cppcheck.cache
/src/ver_defs.h
keeperfx.log
crash_log.txt
84 changes: 76 additions & 8 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,85 @@
{
"configurations": [
{
"name": "MinGW",
"name": "WSL MinGW",
"includePath": [
"${workspaceFolder}/**"
"${workspaceFolder}/src",
"${workspaceFolder}/deps/zlib/include",
"${workspaceFolder}/deps/spng/include",
"${workspaceFolder}/sdl/include",
"${workspaceFolder}/sdl/include/SDL2",
"${workspaceFolder}/deps/enet/include",
"${workspaceFolder}/deps/centijson/include",
"${workspaceFolder}/deps/astronomy/include",
"${workspaceFolder}/deps/openal/include",
"${workspaceFolder}/deps/luajit/include",
"${workspaceFolder}/deps/miniupnpc/include",
"${workspaceFolder}/deps/libnatpmp/include"
],
"defines": [],
"compilerPath": "/usr/bin/i686-w64-mingw32-gcc",
"cStandard": "c17",
"cppStandard": "gnu++17",
"defines": [
"SPNG_STATIC=1",
"AL_LIBTYPE_STATIC",
"USE_PRE_FILE=1",
"BFDEBUG_LEVEL=0"
],
"cStandard": "gnu11",
"cppStandard": "gnu++14",
"intelliSenseMode": "windows-gcc-x86",
//"configurationProvider": "ms-vscode.makefile-tools",
//"compileCommands": "${workspaceFolder}/compile_commands.json",
"compileCommands": "${workspaceFolder}/compile_commands.json"
},
{
"name": "Linux MinGW",
"includePath": [
"${workspaceFolder}/src",
"${workspaceFolder}/deps/zlib/include",
"${workspaceFolder}/deps/spng/include",
"${workspaceFolder}/sdl/include",
"${workspaceFolder}/sdl/include/SDL2",
"${workspaceFolder}/deps/enet/include",
"${workspaceFolder}/deps/centijson/include",
"${workspaceFolder}/deps/astronomy/include",
"${workspaceFolder}/deps/openal/include",
"${workspaceFolder}/deps/luajit/include",
"${workspaceFolder}/deps/miniupnpc/include",
"${workspaceFolder}/deps/libnatpmp/include"
],
"defines": [
"SPNG_STATIC=1",
"AL_LIBTYPE_STATIC",
"USE_PRE_FILE=1",
"BFDEBUG_LEVEL=0"
],
"compilerPath": "/usr/bin/i686-w64-mingw32-gcc",
"cStandard": "gnu11",
"cppStandard": "gnu++14",
"intelliSenseMode": "linux-gcc-x86"
},
{
"name": "Windows MinGW",
"includePath": [
"${workspaceFolder}/src",
"${workspaceFolder}/deps/zlib/include",
"${workspaceFolder}/deps/spng/include",
"${workspaceFolder}/sdl/include",
"${workspaceFolder}/sdl/include/SDL2",
"${workspaceFolder}/deps/enet/include",
"${workspaceFolder}/deps/centijson/include",
"${workspaceFolder}/deps/astronomy/include",
"${workspaceFolder}/deps/openal/include",
"${workspaceFolder}/deps/luajit/include",
"${workspaceFolder}/deps/miniupnpc/include",
"${workspaceFolder}/deps/libnatpmp/include"
],
"defines": [
"SPNG_STATIC=1",
"AL_LIBTYPE_STATIC",
"USE_PRE_FILE=1",
"BFDEBUG_LEVEL=0"
],
"compilerPath": "C:\\msys64\\mingw32\\bin\\gcc.exe",
"cStandard": "gnu11",
"cppStandard": "gnu++14",
"intelliSenseMode": "windows-gcc-x86"
}
],
"version": 4
Expand Down
7 changes: 5 additions & 2 deletions config/fxdata/lenses.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

; Lens definitions are now starting.
; Note that lens can't use "Mist" and "Displacement" transformation
; at the same time - don't use both of them in one lens
; at the same time - don't use both of them in one lens. Overlay and Mist may be used together.

[lens0]
Name = NULL
Expand All @@ -13,6 +13,9 @@ Name = LENS_WIBBLE
; For displacement kind=1, following parameters are:
; magnitude and period
Displacement = 1 9 10
; Overlay has two parameters: file name of a RAW texture (or name of a custom lens),
; Alpha transparency scaled 0..255, where 255 is fully opaque
; Overlay = frac00.raw 0

[lens2]
Name = FISH_EYE
Expand All @@ -26,7 +29,7 @@ Displacement = 3 1 1

[lens4]
Name = MIST_WATER
; Mist effect has three parameters: file name of a RAW texture,
; Mist effect has three parameters: file name of a RAW texture (or name of a custom lens),
; lightness scaled 0..63, and ghost position (irrelevant)
Mist = frac00.raw 0 0

Expand Down
13 changes: 12 additions & 1 deletion src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -1008,7 +1008,7 @@ void set_defaults(const struct NamedFieldSet* named_fields_set, const char *conf
named_fields_set->names[i].name = (char*)name_NamedField->field + i * named_fields_set->struct_size;
named_fields_set->names[i].num = i;
}
named_fields_set->names[named_fields_set->max_count - 1].name = NULL; // must be null for get_id
// Don't set terminator here - it will be set after parsing based on actual count, lens name lookups may depend on it
}
}

Expand Down Expand Up @@ -1047,6 +1047,17 @@ TbBool parse_named_field_blocks(char *buf, long len, const char *config_textname
parse_named_field_block(buf, len, config_textname, flags, blockname_null, named_fields_set->named_fields, named_fields_set, i);
}

// Set the terminator safely within the allocated range
if (named_fields_set->names != NULL && named_fields_set->count_field != NULL)
{
int terminator_index = *named_fields_set->count_field;
if (terminator_index >= named_fields_set->max_count)
{
terminator_index = named_fields_set->max_count - 1;
}
named_fields_set->names[terminator_index].name = NULL;
}

return true;
}

Expand Down
40 changes: 40 additions & 0 deletions src/config_lenses.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "config.h"
#include "thing_doors.h"
#include "custom_sprites.h"

#include "keeperfx.hpp"
#include "post_inc.h"
Expand All @@ -49,6 +50,7 @@ const struct ConfigFileData keeper_lenses_file_data = {
static int64_t value_mist(const struct NamedField* named_field, const char* value_text, const struct NamedFieldSet* named_fields_set, int idx, const char* src_str, unsigned char flags);
static int64_t value_pallete(const struct NamedField* named_field, const char* value_text, const struct NamedFieldSet* named_fields_set, int idx, const char* src_str, unsigned char flags);
static int64_t value_displace(const struct NamedField* named_field, const char* value_text, const struct NamedFieldSet* named_fields_set, int idx, const char* src_str, unsigned char flags);
static int64_t value_overlay(const struct NamedField* named_field, const char* value_text, const struct NamedFieldSet* named_fields_set, int idx, const char* src_str, unsigned char flags);

const struct NamedField lenses_data_named_fields[] = {
//name //pos //field //default //min //max //NamedCommand
Expand All @@ -60,6 +62,8 @@ const struct NamedField lenses_data_named_fields[] = {
{"DISPLACEMENT", 1, field(lenses_conf.lenses[0].displace_magnitude), 0, 0, 511, NULL, value_default, assign_default},
{"DISPLACEMENT", 2, field(lenses_conf.lenses[0].displace_period), 1, 0, 511, NULL, value_displace, assign_default},
{"PALETTE", 0, field(lenses_conf.lenses[0].palette), 0, 0, 0, NULL, value_pallete, assign_null},
{"OVERLAY", 0, field(lenses_conf.lenses[0].overlay_file), 0, 0, 0, NULL, value_overlay, assign_null},
{"OVERLAY", 1, field(lenses_conf.lenses[0].overlay_alpha), 128, 0, 255, NULL, value_default, assign_default},
{NULL},
};

Expand Down Expand Up @@ -107,6 +111,42 @@ static int64_t value_pallete(const struct NamedField* named_field, const char* v
return 0;
}

static int64_t value_overlay(const struct NamedField* named_field, const char* value_text, const struct NamedFieldSet* named_fields_set, int idx, const char* src_str, unsigned char flags)
{
SYNCDBG (9, "value_overlay called: argnum=%d, value='%s', lens=%d", named_field->argnum, value_text, idx);

if (value_text == NULL || value_text[0] == '\0') {
CONFWRNLOG("Empty overlay name for \"%s\" parameter in [%s%d] block of lens.cfg file.",
named_field->name, named_fields_set->block_basename, idx);
return 0;
}

lenses_conf.lenses[idx].flags |= LCF_HasOverlay;
struct LensConfig* lenscfg = &lenses_conf.lenses[idx];

// Clear mist flag and mist_file if this lens only has an overlay
// This prevents garbage mist data from previous lens configurations
lenscfg->flags &= ~LCF_HasMist;
lenscfg->mist_file[0] = '\0';

// Only store the overlay name when processing position 0 (the name field)
// Position 1 is the alpha value, handled by value_default
if (named_field->argnum == 0)
{
// Store the overlay name (a reference name from JSON)
strncpy(lenscfg->overlay_file, value_text, DISKPATH_SIZE - 1);
lenscfg->overlay_file[DISKPATH_SIZE - 1] = '\0';

SYNCDBG(9, "Registered overlay name '%s' for lens %d", value_text, idx);
}
else
{
SYNCLOG("Skipping overlay name storage for argnum=%d (alpha value)", named_field->argnum);
}

return 0;
}

static TbBool load_lenses_config_file(const char *fname, unsigned short flags)
{
SYNCDBG(0,"%s file \"%s\".",((flags & CnfLd_ListOnly) == 0)?"Reading":"Parsing",fname);
Expand Down
5 changes: 4 additions & 1 deletion src/config_lenses.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@
extern "C" {
#endif
/******************************************************************************/
#define LENS_ITEMS_MAX 32
#define LENS_ITEMS_MAX 256

enum LensConfigFlags {
LCF_HasMist = 0x01,
LCF_HasDisplace = 0x02,
LCF_HasPalette = 0x04,
LCF_HasOverlay = 0x08,
};

struct LensConfig {
Expand All @@ -47,6 +48,8 @@ struct LensConfig {
short displace_kind;
short displace_magnitude;
short displace_period;
char overlay_file[DISKPATH_SIZE];
short overlay_alpha;
};

struct LensesConfig {
Expand Down
1 change: 1 addition & 0 deletions src/creature_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ struct Thing *create_and_control_creature_as_controller(struct PlayerInfo *playe
if (thing->class_id == TCls_Creature)
{
struct CreatureModelConfig* crconf = creature_stats_get_from_thing(thing);
SYNCDBG(7,"Possessing creature '%s', eye_effect=%d", crconf->name, crconf->eye_effect);
setup_eye_lens(crconf->eye_effect);
}
}
Expand Down
Loading