Sunday, 15 July 2012

Compiling Brogue v1.6.4 with MinGW

Brogue is a very user friendly roguelike.  It implements a lot of the things that I have always wanted whenever I play a "tile-based" text game of this kind.  That includes support for mouse over events, and giving visual indications of where on the map the selected item is, and the like..

It comes with source code, which should allow me to make my own changes, but unfortunately with programming.. it's never that simple.
In an ideal world, I could just create a new project in Visual Studio, but the code is not platform independent and requires dirent.h and associated functionality.  太麻烦了... so MinGW it is.  The option of using the Code Blocks IDE and it's version of MingW is present, but that's just more complication of a different kind.
  1. Have a MinGW/msys compilation environment set up.
  2. Open a MinGW shell.
  3. Go to the "Brogue Source" directory that comes with the Windows Brogue binaries.
  4. Download and extract: (from here).  It is already compiled.
  5. Download and extract: SDL-devel-1.2.14-mingw32.tar.gz (from here).  It is not necessary to compile it as the headers are all that are required.
  6. Apply patch below for "tcod-platform.c".
  7. Edit "makefile".
  8. Line 3: Correct CFLAGS with -DBROGUE_TCOD instead of -DBROGUE-TCOD.
  9. Line 23: Add the missing "line continuation" character '\'.
  10. Line 32: Correct the g++ linking command modifying "-lSDL.dll" to be "-lSDL".
  11. Line 32: Correct the g++ linking command adding "-L$(LIBTCODDIR)/" so that g++ can find "SDL.dll" and "libtcod-mingw.dll".
  12. Line 32:  Extend the g++ linking command adding "-static-libgcc -static-libstdc++" so that the compiled executable can be run without a dialog box saying "The program can't start because libgcc_s_dw2-1.dll is missing from you computer. Try reinstalling the program to fix this problem.".
This gives you a replacement "brogue.exe" binary which can be copied up to the outer "Brogue v1.6.4" directory, and does not have any further cumbersome MinGW dependencies.

Patch for "tcod-platform.c":
< #include <SDL/SDL.h>
> #include <SDL.h>
<               bufferedKey = TCOD_console_check_for_keypress(TCOD_KEY_PRESSED);
>               TCOD_sys_check_for_event(TCOD_EVENT_KEY_PRESS | TCOD_EVENT_MOUSE, &bufferedKey, &mouse);
>       } else {
>               TCOD_sys_check_for_event(TCOD_EVENT_MOUSE, &bufferedKey, &mouse);
<               key = TCOD_console_check_for_keypress(TCOD_KEY_PRESSED);
>               TCOD_sys_check_for_event(TCOD_EVENT_KEY_PRESS | TCOD_EVENT_MOUSE, &key, &mouse);

The patch makes up for what seems like custom changes to the libtcod DLL that comes with Brogue.  Out of the box, libtcod does not update the last known mouse state unless the using application polls mouse state.

Edit: Added all the other extra steps I had forgotten to mention, as I have gone through this process many times now.