Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support loading tileset images from memory. #69

Open
jaldhar opened this issue Jul 10, 2020 · 5 comments
Open

Support loading tileset images from memory. #69

jaldhar opened this issue Jul 10, 2020 · 5 comments
Assignees

Comments

@jaldhar
Copy link

jaldhar commented Jul 10, 2020

I wanted to embed the tileset into my executable rather than load it from an external file. Although libtcod doesn't support this directly, lodepng which it uses internally does. So I created a function like this:

(font.h)

#include <libtcod/tileset/tilesheet.h>

namespace tcod {
    namespace tileset {
        Tilesheet local_LoadTilesheet();
    }
}

(font.cc)

#include <vector>
#include <libtcod/libtcod_int.h>
#include "font.h"
#include "lodepng.h"

static unsigned img_width = 320;
static unsigned img_height = 80;

// data for dejavu10x10_gs_tc.png goes here; an array of bytes and an integer size.

namespace tcod {
namespace tileset {

Tilesheet local_LoadTilesheet() {
    TilesheetLayout layout{10, 10, 32, 8};  // just hardcode layout for dejavu10x10_gs_tc.png for now
    std::vector<unsigned char> img_data;

    if (lodepng::decode(img_data, img_width, img_height,
     ___images_dejavu10x10_gs_tc_png, ___images_dejavu10x10_gs_tc_png_len)) {
         return Tilesheet();
    }
    tcod::image::Image canvas(img_width, img_height);
    std::vector<unsigned char>::iterator img_iter = img_data.begin();
    for (int y = 0; y < canvas.height(); ++y) {
        for (int x = 0; y < canvas.width(); ++x) {
            canvas.atf(x, y) = tcod::ColorRGBA{img_iter[0], img_iter[1], img_iter[2], img_iter[3]};
            img_iter += 4;
        }
    }

    return Tilesheet(canvas, layout);
}

}
}

This compiles but produces linker errors like this:

/usr/bin/ld: /tmp/fnaf.5uZ9Mt.ltrans0.ltrans.o: in function `GameView::GameViewImpl::GameViewImpl(char const*)':
/home/jaldhar/src/github/fivenightsatfrodos/debug/../src/gameview.cc:59: undefined reference to `tcod::tileset::Tilesheet::~Tilesheet()'
/usr/bin/ld: /home/jaldhar/src/github/fivenightsatfrodos/debug/../src/gameview.cc:59: undefined reference to `tcod::tileset::Tilesheet::~Tilesheet()'
/usr/bin/ld: /tmp/fnaf.5uZ9Mt.ltrans0.ltrans.o: in function `tcod::tileset::local_LoadTilesheet()':
/home/jaldhar/src/github/fivenightsatfrodos/debug/../src/font.cc:738: undefined reference to `tcod::tileset::Tilesheet::Tilesheet()'
/usr/bin/ld: /home/jaldhar/src/github/fivenightsatfrodos/debug/../src/font.cc:751: undefined reference to `tcod::tileset::Tilesheet::Tilesheet(tcod::Vector2<tcod::ColorRGBA> const&, tcod::tileset::TilesheetLayout const&)'
collect2: error: ld returned 1 exit status

I don't understand what's going wrong. Can you enlighten me?

@jaldhar
Copy link
Author

jaldhar commented Jul 10, 2020

Oh I neglected to mention this is with 1.15.1 on Ubuntu on WSL with g++ 9.3.0.

@HexDecimal
Copy link
Collaborator

You're using an old version. The latest versions moved to a C API which hasn't been ported to C++ yet.

This version is likely missing the TCODLIB_API attribute for the class. Which is why you'd have trouble linking it externally.

@HexDecimal
Copy link
Collaborator

It wouldn't be hard to add support for this. You want to load a PNG file from memory?

@jaldhar
Copy link
Author

jaldhar commented Jul 10, 2020

Thanks. How stable is the API in the latest versions? If you're still adjusting things I'd rather wait until you are done and try and fix up my 1.15.1.

I like to compile all my games resources into the executable so the player doesn't have to worry about installing lots of fiddly files all over the place. So if you could add this feature it would be greatly appreciated.

HexDecimal added a commit that referenced this issue Jul 10, 2020
Made the character mappings public so that the new tileset API is
realistically usable.

Should help with issue #69.
@HexDecimal
Copy link
Collaborator

The alpha versions have important bugfixes not in 1.15.1. Since they're minor version alphas they don't break the existing API, only the API that've been added in the alphas or what's been previously declared as provisional might break.

I've added changes to the develop branch. You can load a PNG file from memory with something similar to this:

static unsigned char png_data[];  // dejavu10x10_gs_tc.png

TCOD_Tileset* tileset = TCOD_tileset_load_mem(
  sizeof(png_data),
  png_data,
  32,
  8,
  sizeof(TCOD_CHARMAP_TCOD) / sizeof(*TCOD_CHARMAP_TCOD),
  TCOD_CHARMAP_TCOD);
assert(tileset != NULL);
TCOD_set_default_tileset(tileset);
TCOD_tileset_delete(tileset);
// Then run TCOD_console_init_root, or the C++ version of that.

It isn't tested yet but it shares most of its code with the existing loader. I just needed to swap lodepng_decode32_file with lodepng_decode32.

This is the basic minimum, but I can work on the C++ API if you want something safer to use.

@HexDecimal HexDecimal self-assigned this Jul 10, 2020
@HexDecimal HexDecimal changed the title Unable to link tcod::tileset::Tilesheet Support loading tileset images from memory. Jul 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants