Author Topic: Getting C++ working with libtcod (now with BearLibTerminal)  (Read 29910 times)

Kirbypowered

  • Newcomer
  • Posts: 14
  • Karma: +0/-0
    • View Profile
    • Email
Sorry if I'm doing something wrong with this thread, I haven't done much on these forums as of yet and am vaguely tired, and thus likely to do things without much thought. Anyhow:

To begin, I have slightly above minimal knowledge in programming. I've gone through a year long class on Java, and have been learning C++ on my own since before then. Running on Windows 7 (64-bit, if that's important).

After convincing myself that I have enough knowledge to make some form of a game, I've began my trek to try and make a roguelike. This has led me to the idea of external libraries, and libtcod in particular. I want to do it in C++ because I've always had an unexplainable interest in the language. Serendipitously, there is a tutorial on the internet for making roguelikes in C++ using libtcod (here).

The first bit of code on there does not run properly for me.

Comiling this:

Code: [Select]
#include "libtcod.hpp"
int main() {
    TCODConsole::initRoot(80,50,"libtcod C++ tutorial",false);
    while ( !TCODConsole::isWindowClosed() ) {
        TCODSystem::checkForEvent(TCOD_EVENT_KEY_PRESS,NULL,NULL);
        TCODConsole::root->clear();
        TCODConsole::root->putChar(40,25,'@');
        TCODConsole::flush();
    }
    return 0;
}

using this in the console:

Code: [Select]
g++ src\*.cpp -o tuto -Iinclude -Llib -ltcod-mingw-de
bug -static-libgcc -static-libstdc++ -Wall -g

and running it with gdb tells me this:

Code: [Select]
Starting program: C:\Users\Soulusk\gameplace\tuto.exe
[New Thread 3440.0xfac]
[New Thread 3440.0x12e8]
24 bits font.
key color : 0 0 0
character for ascii code 255 is colored
Using SDL renderer...

Program received signal SIGSEGV, Segmentation fault.
0x65e70d9f in TCODConsole::clear (this=0x1) at src/console.cpp:196
196     src/console.cpp: No such file or directory.

The last three lines are the important bit, I'm guessing.

So...I really don't know what this is telling me. Is the program unable to find src/console.cpp? I've been able to run some other programs using libtcod without the clear and putChar functions in it, and they worked fine, confusing me even more.

Anyone with actually experience willing to help me figure this nonsense out so I can get back to the roguelike thing?
« Last Edit: July 23, 2014, 02:31:01 AM by Kirbypowered »

Aukustus

  • Rogueliker
  • ***
  • Posts: 440
  • Karma: +0/-0
    • View Profile
    • The Temple of Torment

Kirbypowered

  • Newcomer
  • Posts: 14
  • Karma: +0/-0
    • View Profile
    • Email
Re: Getting C++ working with libtcod
« Reply #2 on: July 20, 2014, 03:15:37 PM »
Try this: http://codeumbra.eu/complete-roguelike-tutorial-using-c-and-libtcod-part-1-setting-up
That's the tutorial I've been following...I linked to that exact page, thought the link is admittedly hidden away nicely in my post.  There's perhaps a good chance that I missed something crucial from it, but I can't seem to figure out what that is. It feels like I might just not have some files where they should be.

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: Getting C++ working with libtcod
« Reply #3 on: July 21, 2014, 01:03:01 AM »
Quote from: Kirbypowered
Code: [Select]
0x65e70d9f in TCODConsole::clear (this=0x1) at src/console.cpp:196
196     src/console.cpp: No such file or directory.
TCODConsole::clear method is located at line 196 in libtcod version 1.5.1, so the binary (.dll) library must be from 1.5.1 release. However, that release does not include MinGW libraries (libtcod-mingw[-debug]). Yet gdb cannot find src/console.cpp file implying you did not compile those libraries yourself. Which becomes really confusing: where did you get your libtcod-mingw-debug.dll from? Also, "this = 0x1" indicates  that TCODConsole::clear has recevied totally wrong object pointer. Usually it happens when you call a method on non-exising object (which should not be the case here) or when linking against a library has gone haywire.

I suggest you delete your current libtcod (and all traces of it) and try to unpack a clean 1.5.2 release. If that will not help, try to build the library as described here:
http://doryen.eptalys.net/data/libtcod/doc/1.5.2/html2/compile_libtcod_mingw.html
Note that you do not have to use the exact MinGW version mentioned on that page. When you're compiling library yourself you are fine as long as you're using the same version for everything.

On a side note and as an act of self-advertisement, I think you may find interesting an alternative output library called BearLibTerminal.

Kirbypowered

  • Newcomer
  • Posts: 14
  • Karma: +0/-0
    • View Profile
    • Email
Re: Getting C++ working with libtcod
« Reply #4 on: July 21, 2014, 04:43:14 AM »
I suggest you delete your current libtcod (and all traces of it) and try to unpack a clean 1.5.2 release. If that will not help, try to build the library as described here:
http://doryen.eptalys.net/data/libtcod/doc/1.5.2/html2/compile_libtcod_mingw.html
Note that you do not have to use the exact MinGW version mentioned on that page. When you're compiling library yourself you are fine as long as you're using the same version for everything.
Okay, removed all traces of my version 1.5.1 of libtcod and downloaded 1.5.2. Recreated the tutorial directories and main.cpp, tried compiling it, got the same problems. Tried following the tutorial on compiling libtcod on windows...and got more errors. I'm starting to think that this is maybe a mingw thing? Here's the bit that went wrong:

Code: [Select]
Compiling zlib src/zlib/trees.c
Compiling zlib src/zlib/zutil.c
In files included from c:\mingw\include\fcntl.h:37:0,
                          from src/zlib/gzguts.h:28,
                          from src/zlib/zutil.c:10:
c:\mingw\include\io.h:301:1: error: unknown type name 'off64_t'
 __CRT_INLINE off64_t lseek64 (int, off64_t, int);
 ^
c:\mingw\include\io.h:301:36: error: unknown type name 'off64_t'
 __CRT_INLINE off64_t lseek64 (int, off64_t, int);
 ^
c:\mingw\include\io.h:302:1: error: unknown type name 'off64_t'
 __CRT_INLINE off64_t lseek64 (int fd, off64_t offset, int whence);
 ^
c:\mingw\include\io.h:302:39: error: unknown type name 'off64_t'
 __CRT_INLINE off64_t lseek64 (int fd, off64_t offset, int whence);
 ^
make: *** [/tmp/libtcod/zlib/zutil.o] Error 1

Any idea what's causing the problem here?

Edit: Took a peek at BearLibTerminal and it seems like it could be interesting. I've been more interested in doing most of the game-y coding myself, and I was honestly looking to libtcod for the simple ability to move characters around on the screen. I continue to have very little knowledge of how to work with libraries, but yours sounds like it might suit my interests better.

I still would like to figure out my problem with libtcod though. =p
« Last Edit: July 21, 2014, 05:12:46 AM by Kirbypowered »

TheCreator

  • Rogueliker
  • ***
  • Posts: 370
  • Karma: +0/-0
    • View Profile
    • Fame
    • Email
Re: Getting C++ working with libtcod
« Reply #5 on: July 21, 2014, 05:21:20 AM »
Did you try to understand why this "root" thing is not initialized properly? That's where you should start from, because the code is apparently calling a method through a null pointer as Cfyz already pointed out. (By the way, this also indicates that the tutorial you're using may not be that good.)
« Last Edit: July 21, 2014, 05:27:05 AM by TheCreator »
Fame (Untitled) - my game. Everything is a roguelike.

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: Getting C++ working with libtcod
« Reply #6 on: July 21, 2014, 10:29:26 AM »
Quote from: Kirbypowered
I'm starting to think that this is maybe a mingw thing? Here's the bit that went wrong:
Code: [Select]
c:\mingw\include\io.h:301:1: error: unknown type name 'off64_t'
Indeed this was a bug in MinGW. First try to update MinGW and simply link against the regular 1.5.2 libtcod. I recommend mingw-builds releases.

That might not work though. The point about recompiling libtcod is that with C++ it is often important to use same compiler version and build for both application and libraries it is linking against. Usually it is easier to just recompile everything with your own compiler than keep matching library builds. Note that recompiling libtcod from the code repository (because regular release archives do not include makefiles) will get you the 'trunk' version, not 1.5.2 (but should not matter).

I can confirm it is possible to compile that tutorial, albeit with some nuances. I've used MinGW 4.8.1 from mingw32-builds and libtcod code right from the repository, but had to modify the makefile a bit:
1. Change 'CC' and 'CPP' variables from 'mingw32-gcc' and 'mingw32-g++' to simple 'gcc' and 'g++' because that is how compiler binaries are named (are these longer names from the old Cygwin packages?).
2. Manually specify 'TEMP' variable because 'make' from my Cygwin installation failed to create files in /tmp folder (what the?).
After that libtcod and tutorial are compiling and executing okay.
« Last Edit: July 21, 2014, 10:32:18 AM by Cfyz »

Kirbypowered

  • Newcomer
  • Posts: 14
  • Karma: +0/-0
    • View Profile
    • Email
Re: Getting C++ working with libtcod
« Reply #7 on: July 21, 2014, 01:39:16 PM »
Did you try to understand why this "root" thing is not initialized properly? That's where you should start from, because the code is apparently calling a method through a null pointer as Cfyz already pointed out. (By the way, this also indicates that the tutorial you're using may not be that good.)
I tried for a little while, but I think I need to learn a bit more about classes and objects in C++, as I only had a vague idea of where things were coming from...TCODConsole::root appears to be given an address to point to, but I only slightly recognize what's going on there. Heh, might just be I need to learn more general C++ before going much further with this.

Indeed this was a bug in MinGW. First try to update MinGW and simply link against the regular 1.5.2 libtcod. I recommend mingw-builds releases.

That might not work though. The point about recompiling libtcod is that with C++ it is often important to use same compiler version and build for both application and libraries it is linking against. Usually it is easier to just recompile everything with your own compiler than keep matching library builds. Note that recompiling libtcod from the code repository (because regular release archives do not include makefiles) will get you the 'trunk' version, not 1.5.2 (but should not matter).
So, recompiling libtcod myself is unlikely to fix my problem, but I should update mingw to deal with that bug either way? Also, are you saying that having a library that's compiled with a different version of the same compiler that you're using will often cause problems? That really sounds like it could be a hassle...

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: Getting C++ working with libtcod
« Reply #8 on: July 21, 2014, 02:28:38 PM »
Quote from: Kirbypowered
as I only had a vague idea of where things were coming from...TCODConsole::root appears to be given an address to point to, but I only slightly recognize what's going on there.
There is a static variable defined at the top of the src/console.cpp:
Code: [Select]
TCODConsole * TCODConsole::root = NULL;And TCODConsole::initRoot is a very thin wrapper around C version:
Code: [Select]
void TCODConsole::initRoot(int w, int h, const char *title, bool fullscreen, TCOD_renderer_t renderer) {
TCODConsole *con=new TCODConsole();
TCOD_console_init_root(w,h,title,fullscreen,renderer);
con->data=TCOD_ctx.root;
TCODConsole::root=con;
}
It just allocates a new TCODConsole instance and assigns its address to the static 'TCODConsole::root' variable mentioned above. Which makes calling the TCODConsole::clear method on NULL pointer virtually impossible. Even if a logic error happens during console initialization, that root variable will still be assigned some valid memory address.

Quote from: Kirbypowered
So, recompiling libtcod myself is unlikely to fix my problem, but I should update mingw to deal with that bug either way?
There are two mostly unrelated problems. First one (SIGSEGV while running a compiled application) is IMO caused by some compiler/library incompatibility. The other one (unknown type name 'off64_t' while compiling libtcod) is clearly a MinGW bug and it has been fixed for a while now. It is good idea to update compiler anyway. And no, I believe recompiling libtcod should fix your original problem.

Quote from: Kirbypowered
Also, are you saying that having a library that's compiled with a different version of the same compiler that you're using will often cause problems? That really sounds like it could be a hassle...
Yes, it is a hassle indeed. There is a brief explanation on MinGW wiki. Note that this problem (mostly) does not exist for C. If you use C version of libtcod API, you should be okay. BearLibTerminal API was also deliberately kept to a bare minimum (a few C calls) so that interoperability will not become a problem.

Kirbypowered

  • Newcomer
  • Posts: 14
  • Karma: +0/-0
    • View Profile
    • Email
Re: Getting C++ working with libtcod
« Reply #9 on: July 21, 2014, 05:21:23 PM »
First try to update MinGW and simply link against the regular 1.5.2 libtcod. I recommend mingw-builds releases.
Mind explaining some of the installation options for mingw-builds? In Threads there are the options posix and win32, and in Exception there are dwarf and sjlj. Anything important I should know about these settings?

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: Getting C++ working with libtcod
« Reply #10 on: July 21, 2014, 07:58:39 PM »
A good overview of different MinGW flavours and options can be found at Qt wiki.

I think you should pick any of EH variants (does not make much difference for simple programs; I use SJLJ) and posix thread model (because C++11 is awesome).
« Last Edit: July 21, 2014, 09:51:58 PM by Cfyz »

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: Getting C++ working with libtcod
« Reply #11 on: July 21, 2014, 08:23:19 PM »
I've tried to link that tutorial against libraries included in 1.5.2 release archive using several of MinGW builds (somehow I've collected quite a number of them). All of the attempts (mingw-builds or TDM, 32 bit or cross-64 bit, sjlj or dw2) gave the same result as your first one: segfault on TCODConsole::clear. Linking against manually compiled libtcod works fine though.

Kirbypowered

  • Newcomer
  • Posts: 14
  • Karma: +0/-0
    • View Profile
    • Email
Re: Getting C++ working with libtcod
« Reply #12 on: July 21, 2014, 09:51:04 PM »
I've tried to link that tutorial against libraries included in 1.5.2 release archive using several of MinGW builds (somehow I've collected quite a number of them). All of the attempts (mingw-builds or TDM, 32 bit or cross-64 bit, sjlj or dw2) gave the same result as your first one: segfault on TCODConsole::clear. Linking against manually compiled libtcod works fine though.
Ah, thanks for checking that out for me. Good to know it's not just me. =)

So I guess my next (and perhaps last) problem is figuring out how mingw-builds works. Does my choice between 32 and 64 bit make a significant difference? I'm always tempted to choose 64-bit options, but sometimes that seems to cause issues. Will the installation from that alone be enough for a fully functional mingw? I tried using it with MSYS grabbed from the older mingw folder, but it seemed to be missing important things.

Sorry for the constant, likely obvious questions I keep having. Everything at this point is seemingly new and unfamiliar to me.

Krice

  • (Banned)
  • Rogueliker
  • ***
  • Posts: 2316
  • Karma: +0/-2
    • View Profile
    • Email
Re: Getting C++ working with libtcod
« Reply #13 on: July 22, 2014, 07:32:03 AM »
So I guess my next (and perhaps last) problem is figuring out how mingw-builds works.

Don't make it too complicated. Install Code::Blocks with mingw (you should learn to use IDE) or Visual C++ free edition. Then, if some crappy library doesn't work, don't use it.

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: Getting C++ working with libtcod
« Reply #14 on: July 22, 2014, 10:59:25 AM »
Quote from: Kirbypowered
Does my choice between 32 and 64 bit make a significant difference? I'm always tempted to choose 64-bit options, but sometimes that seems to cause issues.
Does not matter nowadays. All of the modern MinGW builds are dual "multilib" and capable of producing both 32 and 64-bit executable. Bitness of MinGW build indicates which one is default but you always can force another by adding -m32/-m64 compiler switch to the command line.

Quote from: Kirbypowered
Will the installation from that alone be enough for a fully functional mingw?
Normal MinGW installation should be self-sufficient. However, try not to keep multiple copies unless you know what you are doing. MinGW installation is perfectly usable as long as its 'bin' subfolder is in the PATH, but having multiple compiler builds in the PATH at the same time may screw things up.

Edit: a fully functional MinGW will not be enough to build libtcod, you will also need Cygwin.

Quote from: Kirbypowered
I tried using it with MSYS grabbed from the older mingw folder, but it seemed to be missing important things.
I'm not sure what you call MSYS exactly (the definition of this component is a bit vague) but I strongly suggest you do not mix parts of different builds. If not sure, remove everything and unpack a fresh copy.

Quote from: Krice
Don't make it too complicated. Install Code::Blocks with mingw (you should learn to use IDE) or Visual C++ free edition.
Code::Blocks does not rely on compiler to be bundled with it. It has builds with MinGW included (right now it is TDM 4.7.1 and 4.8.1) but I think knowing the line between the IDE and the compiler may help a lot. As far as I can tell, we are not doing "hello world" here.

Visual Studio Express for Windows Desktop (that is how free Visual C++ is called nowadays) is a valid choice too. If anything, it has awesomely integrated debugger. It is very different though, with its own rules, quirks and bugs. And I may be a bit on the subjective side, but I believe that starting from Dev-C++/Code::Blocks/Eclipse + GCC will be better in the long run.

However, none of the alternatives mentioned above would fix the original problem about linking with libtcod. Yet they might have made fixing it harder. Maybe I'm missing something, but as far as I can see libtcod has very unfriendly building mechanics. It practically requires MinGW with Cygwin, because versions newer than 1.5.1 have only makefiles and those makefiles rely on unix utilities.

Quote from: Krice
Then, if some crappy library doesn't work, don't use it.
Yeah, use BearLibTerminal: linking is trivial, supports both MinGW and Visual C++ and does not require any recompiling :-P.
« Last Edit: July 22, 2014, 11:16:56 AM by Cfyz »