Skip to content

Commit

Permalink
allow image mods for overlay image mod
Browse files Browse the repository at this point in the history
"img_mods" = "overlay|path/to/file|@disabled"
  • Loading branch information
black-sliver committed Dec 31, 2023
1 parent 37d39cb commit 41d4236
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 16 deletions.
3 changes: 2 additions & 1 deletion doc/PACKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,8 @@ a table representing an enum with the following constants: \

+ img_mods filter to be applied on the img
- `@disabled`: grey-scale
- `overlay|path/to/img.png`: draw a second image over it
- `overlay|path/to/img.png|overlay_filters...`: draw a second image over it; overlay_filters are applied to overlay (since 0.25.6)
- NOTE: order matters, applied left to right
+ inherit_codes: true will make stage3 provide codes for item, stage1, 2 and 3 (default true)

* `"toggle"`:
Expand Down
24 changes: 19 additions & 5 deletions src/ui/trackerview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include "maptooltip.h"
#include "mapwidget.h"
#include "defaults.h" // DEFAULT_FONT_*
#include <string>
#include <vector>

namespace Ui {

Expand All @@ -25,23 +27,35 @@ std::list<ImageFilter> imageModsToFilters(Tracker* tracker, const std::list<std:
{
std::list<ImageFilter> filters;
for (auto& mod: mods) {
std::string name, arg;
std::string name;
std::vector<std::string> args;
size_t p = mod.find('|');
if (p == mod.npos) name = mod;
else {
name = mod.substr(0,p);
arg = mod.substr(p+1);
while (true) {
auto q = mod.find('|', p+1);
if (q == mod.npos) {
args.push_back(mod.substr(p+1));
break;
}
args.push_back(mod.substr(p+1, q-p-1));
p = q;
}
}
if (name == "overlay") {
// read actual image data into arg instead of filename
std::string tmp = std::move(arg);
tracker->getPack()->ReadFile(tmp, arg);
std::string tmp = std::move(args[0]);
tracker->getPack()->ReadFile(tmp, args[0]);
for (size_t i=1; i<args.size(); i++)
if (args[i] == "@disable" || args[i] == "@disabled")
args[i] = "grey";
}
if (name == "@disable" || name == "@disabled")
{
name = "grey";
}
filters.push_back({name,arg});
filters.push_back({name,args});
}
return filters;
}
Expand Down
16 changes: 12 additions & 4 deletions src/uilib/imagefilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,31 @@

namespace Ui {

SDL_Surface* ImageFilter::apply(SDL_Surface *surf)
SDL_Surface* ImageFilter::apply(SDL_Surface *surf) const
{
if (!surf) return surf;

if (name=="grey" || name=="disable") {
return makeGreyscale(surf, true);
}
if (name=="overlay" && !arg.empty()) {
auto overlay = IMG_Load_RW(SDL_RWFromMem((void*)arg.c_str(), (int)arg.length()), 1);
if (name=="overlay" && !args.empty()) {
auto overlay = IMG_Load_RW(SDL_RWFromMem((void*)args[0].c_str(), (int)args[0].length()), 1);
overlay = makeTransparent(overlay, 0xff, 0x00, 0xff, false);
if (overlay) {
bool first = true;
for (const auto& arg: args) {
if (first) {
first = false; // skip the first arg (the image)
} else {
overlay = ImageFilter(arg).apply(overlay);
}
}
SDL_BlitSurface(overlay, nullptr, surf, nullptr);
SDL_FreeSurface(overlay);
}
else {
fprintf(stderr, "IMG_Load: %s\n", IMG_GetError());
}
}
}

return surf;
Expand Down
25 changes: 19 additions & 6 deletions src/uilib/imagefilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,36 @@

#include "colorhelper.h"
#include <string>
#include <vector>
#include <SDL2/SDL_image.h>


namespace Ui {

struct ImageFilter {
ImageFilter(std::string name) { this->name=name; }
ImageFilter(std::string name, std::string arg) { this->name=name; this->arg=arg; }

ImageFilter(std::string name)
: name(name)
{
}

ImageFilter(std::string name, std::string arg)
: name(name), args({arg})
{
}

ImageFilter(std::string name, std::vector<std::string>& args)
: name(name), args(args)
{
}

std::string name;
std::string arg;
std::vector<std::string> args;

SDL_Surface* apply(SDL_Surface *surf);
SDL_Surface* apply(SDL_Surface *surf) const;

bool operator==(const ImageFilter& rhs) const
{
return name == rhs.name && arg == rhs.arg;
return name == rhs.name && args == rhs.args;
}
};

Expand Down

0 comments on commit 41d4236

Please sign in to comment.