Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
4 changes: 4 additions & 0 deletions config/mods/lens_overlay_test/creatrs/imp.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
; IMP with helmet visor overlay lens + mist effect

[senses]
EyeEffect = TEST_WITH_MIST
Binary file not shown.
15 changes: 15 additions & 0 deletions config/mods/lens_overlay_test/fxdata/lenses.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
; Test Lens Overlay Configuration for KeeperFX
; This demonstrates the new ZIP+JSON lens overlay system

; NEW TEST LENS WITH OVERLAY GRAPHIC ONLY
[lens15]
Name = LENS_HELMET_VISOR
; This uses the new overlay system - name references the overlay in lenses.json
OVERLAY = TUNNELER_VISOR 200
; Alpha transparency: 0-255 (0=fully transparent, 255=fully opaque)

[lens16]
Name = TEST_WITH_MIST
; You can combine overlays with mist effects
Mist = frac09.raw 4 0
OVERLAY = TUNNELER_VISOR 180
37 changes: 37 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,39 @@ 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)
{
SYNCLOG("value_overlay called: argnum=%d, value='%s', lens=%d", named_field->argnum, value_text, idx);

if (value_text == NULL || value_text[0] == '\0') {
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

value_overlay() uses SYNCLOG for routine parsing traces. This is very noisy during normal config loading; please switch these to SYNCDBG at an appropriate level (or remove once validated) so logs aren’t polluted in non-debug runs.

Copilot uses AI. Check for mistakes.
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];

// Only store the overlay name when processing position 0 (the name field), pos 1 is for alpha value
if (named_field->argnum == 0)
{
strncpy(lenscfg->overlay_file, value_text, DISKPATH_SIZE - 1);
lenscfg->overlay_file[DISKPATH_SIZE - 1] = '\0';

lenscfg->overlay_data = NULL;
lenscfg->overlay_width = 0;
lenscfg->overlay_height = 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
7 changes: 7 additions & 0 deletions src/config_lenses.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ enum LensConfigFlags {
LCF_HasMist = 0x01,
LCF_HasDisplace = 0x02,
LCF_HasPalette = 0x04,
LCF_HasOverlay = 0x08,
};

struct LensConfig {
Expand All @@ -47,6 +48,12 @@ struct LensConfig {
short displace_kind;
short displace_magnitude;
short displace_period;
char overlay_file[DISKPATH_SIZE];
char overlay_mod_dir[DISKPATH_SIZE]; // Mod directory for overlay, empty for base game
unsigned char *overlay_data;
int overlay_width;
int overlay_height;
short overlay_alpha;
};

struct LensesConfig {
Expand Down
Loading