Temple of The Roguelike Forums
Development => Programming => Topic started by: Kirbypowered on July 20, 2014, 03:01:47 AM
-
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 (http://codeumbra.eu/complete-roguelike-tutorial-using-c-and-libtcod-part-1-setting-up)).
The first bit of code on there does not run properly for me.
Comiling this:
#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:
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:
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?
-
Try this: http://codeumbra.eu/complete-roguelike-tutorial-using-c-and-libtcod-part-1-setting-up
-
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.
-
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 (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 (http://foo.wyrd.name/en:bearlibterminal).
-
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 (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:
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
-
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'm starting to think that this is maybe a mingw thing? Here's the bit that went wrong:c:\mingw\include\io.h:301:1: error: unknown type name 'off64_t'
Indeed this was a bug in MinGW (http://sourceforge.net/p/mingw/bugs/2024/). First try to update MinGW and simply link against the regular 1.5.2 libtcod. I recommend mingw-builds (http://sourceforge.net/projects/mingwbuilds/) 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.
-
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 (http://sourceforge.net/p/mingw/bugs/2024/). First try to update MinGW and simply link against the regular 1.5.2 libtcod. I recommend mingw-builds (http://sourceforge.net/projects/mingwbuilds/) 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...
-
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:TCODConsole * TCODConsole::root = NULL;
And TCODConsole::initRoot is a very thin wrapper around C version: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.
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.
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 (http://www.mingw.org/wiki/Interoperability_of_Libraries_Created_by_Different_Compiler_Brands). 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.
-
First try to update MinGW and simply link against the regular 1.5.2 libtcod. I recommend mingw-builds (http://sourceforge.net/projects/mingwbuilds/) 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?
-
A good overview of different MinGW flavours and options can be found at Qt wiki (http://qt-project.org/wiki/MinGW-64-bit).
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).
-
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.
-
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.
-
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.
-
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.
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.
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.
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 (http://www.visualstudio.com/en-US/products/visual-studio-express-vs) (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.
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.
-
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.
You know, why not? libtcod's just been problem after problem, and I'm starting to wonder why I was so set on using it. It's a shame I didn't get it working, but I'm not too disappointed. I'd like to think I've learned quite a bit from all of this. =P
I'll take a shot at using BearLibTerminal with mingw and Code::Blocks. I've been more interested in figuring out how things actually work than just having them work, which is sort of why I do most things through the console. Once I get a proper project running, I'll probably do so with an IDE for their ability to make life simpler.
Don't worry though, I'll have some more questions and problems ready before you know it. XP
-
Okay, seems I don't know crap about general library usage. How do I use BearLibTerminal? I tried testing the example code from your site and I had strange issues relating to undefined references. I tried telling the compiler where the C header file was, and the linker where the .lib file was, but I'm not sure if that's enough. Also have the .dll in the directory. Might just be me missing important compiler commands (trying it with the console).
Edit: Okay yeah, definitely me doing something wrong with the compilation options. Got the program running through Code::Blocks. What would I be missing?
g++ bearlibtest.cpp -o bearlibtest -Iinclude -Llib
(I put BearLibTerminal.c in /include and BearLibTerminal.lib in /lib)
-
What would I be missing?
Common sense of not using IDE while it's easier than command line.
-
What would I be missing?g++ bearlibtest.cpp -o bearlibtest -Iinclude -Llib
You missed to mention the library: -lBearLibTerminal. The -I and -L switches are only telling where to look, not what to look for.
-
What would I be missing?
Common sense of not using IDE while it's easier than command line.
When trying out small code snippets It's often easier to type a single command line with few compiler switches than click your mouse to death setting up a new project in an IDE.
-
What would I be missing?g++ bearlibtest.cpp -o bearlibtest -Iinclude -Llib
You missed to mention the library: -lBearLibTerminal. The -I and -L switches are only telling where to look, not what to look for.
Ah, makes sense. I figured it was something like libtcod's -ltcod-mingw, but I didn't realize what it was doing.
What would I be missing?
Common sense of not using IDE while it's easier than command line.
Yeah yeah, you're probably right. I tend to be unreasonably opposed to common sense with a lot of things. XP But to be fair, I've only done small, basic programs up to this point where the command line was enough to easily get things running. I'm slowly making the transition to IDE, but I still like knowing how to set things up manually.
Anyhow, that should pretty much wrap up this thread. Never really did what I originally planned on, but BearLibTerminal seems good, especially since I actually got it working. =p Thanks a bunch for helping me people, especially Cfyz for putting up with my dumb questions the most.
-
Even if you don't IDE, you can tuck all the command-line corners under the edges of a makefile and then just 'make' in the directory with the makefile will remember all those corners for you.
-
but I still like knowing how to set things up manually.
I think it's better to avoid any manual or extra work unless you need to learn something. Better tools make the actual work (game design) easier.
-
but I still like knowing how to set things up manually.
I think it's better to avoid any manual or extra work unless you need to learn something. Better tools make the actual work (game design) easier.
The downside of not learning to program using tools like the OP describes is that in 20 years of getting nothing done on IDEs, you might develop a sort of self-satisfied ignorance that makes you give bad advice to people trying do things properly. Admittedly, this situation isn't that common and lots of people get a lot done using IDEs, but such examples exist.
-
people trying do things properly.
So, which one of you is trying to create a next gen major roguelike?