Porting to 1.19
Any new project should use the getting-started guide so that they can start using contexts right way. Older projects will have to convert to contexts over a series of steps.
The old way of initializing a global state with TCOD_console_init_root() or TCODConsole::initRoot() has been deprecated. These have been replaced with a public context object.
New tileset API
You can switch away from TCOD_console_set_custom_font before using contexts by using the TCOD_set_default_tileset function.
TCOD_Error TCOD_console_init_root(int w, int h, const char *title, bool fullscreen, TCOD_renderer_t renderer)
Initialize the libtcod graphical engine.
@ TCOD_RENDERER_OPENGL2
A new OpenGL 2.0 core renderer.
Definition console_types.h:551
void TCOD_set_default_tileset(TCOD_Tileset *tileset)
Set the default tileset and update the default display to use it.
auto load_tilesheet(const std::filesystem::path &path, const std::array< int, 2 > &columns_rows, const ArrayType &charmap) -> Tileset
Load a tilesheet from a PNG file.
Definition tileset.hpp:190
Later when you upgrade to contexts you will replace TCOD_set_default_tileset with TCOD_ContextParams.
params.columns = 80;
params.rows = 25;
params.tileset = tileset.get();
params.vsync = 1;
params.sdl_window_flags = SDL_WINDOW_RESIZABLE;
params.window_title = "Window title";
auto new_context(const TCOD_ContextParams ¶ms, TCOD_Error &out_code) -> ContextPtr
Initialize and return a new libtcod context.
Definition context_init.h:77
A struct of parameters used to create a new context with TCOD_context_new.
Definition context.h:70
int tcod_version
Compiled libtcod version for ABI compatiblity with older versions of libtcod.
Definition context.h:74
#define TCOD_COMPILEDVERSION
The version of libtcod currently being compiled.
Definition version.h:60
Using the new console functions
There is less state with the new functions. Instead of setting colors before calling the print functions you now pass the colors and flags needed for each print call.
*console,
{0, 0},
WHITE,
std::nullopt,
)
*TCODConsole::root,
{0, 0, 20, 1},
0x2500,
WHITE,
bg,
)
Classic turn by turn game loop:TCODConsole::initRoot(80,50,"my game",false); while (!...
Definition console.hpp:137
void draw_rect(TCOD_Console &console, const std::array< int, 4 > &rect, int ch, std::optional< TCOD_ColorRGB > fg, std::optional< TCOD_ColorRGB > bg, TCOD_bkgnd_flag_t flag=TCOD_BKGND_SET)
Fill a region with the given graphic.
Definition console_drawing.h:182
TCOD_color_t TCOD_console_get_char_background(const TCOD_Console *con, int x, int y)
Return the background color of a console at x,y.
void print(TCOD_Console &console, const std::array< int, 2 > &xy, std::string_view str, std::optional< TCOD_ColorRGB > fg, std::optional< TCOD_ColorRGB > bg, TCOD_alignment_t alignment=TCOD_LEFT, TCOD_bkgnd_flag_t flag=TCOD_BKGND_SET)
Print a string to a console.
Definition console_printing.hpp:75
TCODLIB_END_IGNORE_DEPRECATIONS std::string stringf(const char *format, T... args)
Return a formatted string as a std::string object.
Definition console_printing.hpp:198
A C++ RGB color, used to handle conversions between color types.
Definition color.hpp:53
Adapting to contexts and a rootless console
Before initializing a context properly you can access both the context and the root console. This lets you use context methods like TCOD_Context::present easily in older code. This also lets you use the root console on functions which can't accept nullptr.
TCOD_Context * TCOD_sys_get_internal_context(void)
Return the context being used internally by the old API.
TCOD_Console * TCOD_sys_get_internal_console(void)
Return a pointer to the "root console" used internally by the old API.
A libtcod console containing a grid of tiles with {ch, fg, bg} information.
Definition console.h:125
A rendering context for libtcod.
Definition context.h:340
void present(const TCOD_Console &console, const TCOD_ViewportOptions &viewport)
Present a console to the display with the provided viewport options.
Definition context.h:365
Using the context present function like this will break some functions which say they're not compatible with contexts. Most importantly any timing-related functions will need to be updated. See Timing_ below.
The next step is to actually replace TCOD_console_init_root with contexts.
params.vsync = 1;
params.sdl_window_flags = SDL_WINDOW_RESIZABLE;
params.window_title = "Window title";
params.console = root_console.get();
A managed libtcod console containing a grid of tiles with {ch, fg, bg} information.
Definition console_types.hpp:80
Window manipulation
With the temporary context from the previous step or with TCOD_sys_get_sdl_window you can access the SDL_Window pointer. You use this to replace several window-related functions such as TCOD_console_set_fullscreen, TCOD_console_is_active or TCOD_console_set_window_title. See the SDL2 window documentation <https://wiki.libsdl.org/CategoryVideo>_ for what you can do with the SDL_Window pointer.
if (sdl_window) {
SDL_SetWindowTitle(sdl_window, "New title");
if (SDL_GetWindowFlags(sdl_window) & SDL_WINDOW_INPUT_FOCUS) {}
}
auto get_sdl_window() noexcept -> struct SDL_Window *
Return a non-owning pointer to the SDL_Window used by this context.
Definition context.h:395
Event systems
Libtcod's event systems have been deprecated in favor of using SDL2_ directly for events. TCOD_Context::convert_event_coordinates is the recommended way to convert pixel coordinates to tiles. tcod::sdl2::process_event might work better for converting old code to use the new system.
while (true) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
std::exit(EXIT_SUCCESS);
break;
case SDL_KEYDOWN: {
switch (event.key.keysym.sym) {
case SDLK_EQUALS:
if (event.key.keysym.mod & KMOD_SHIFT) {
}
break;
default:
break;
}
} break;
case SDL_MOUSEBUTTONDOWN: {
} break;
default:
break;
}
}
}
TCOD_event_t process_event(const union SDL_Event &in, TCOD_key_t &out) noexcept
Parse an SDL_Event into a key event and return the relevant TCOD_event_t.
void convert_event_coordinates(SDL_Event &event)
Convert the pixel coordinates of SDL mouse events to the tile coordinates of the current context.
Definition context.h:458
Mouse state provided by the libtcod event system.
Definition mouse_types.h:50
Timing
All of the libtcod timing functions have been deprecated. Many will stop working once you switch to using contexts. Instead you should use tcod::Timer and SDL2's timing functions. Remember that you have to add #include <libtcod/timer.hpp> to access tcod::Timer, this also requires the SDL2 headers.
int desired_fps = 30;
while (1) {
uint32_t current_time_ms = SDL_GetTicks();
float current_time = static_cast<float>(current_time_ms) / 1000.f;
float delta_time = timer.sync(desired_fps);
}
A timing class based on SDL's high performance time counter.
Definition timer.hpp:70
Switching to contexts
With all the above done you can now switch away from TCOD_console_init_root and start using TCOD_ContextParams and tcod::new_context.
#include <libtcod.hpp>
#include <SDL2.h>
int main(int argc, char* argv[]) {
params.console = root_console.get();
params.window_title = "Window title";
params.sdl_window_flags = SDL_WINDOW_RESIZABLE;
params.vsync = true;
params.argc = argc;
params.argv = argv;
params.tileset = tileset.get();
while (1) {
SDL_Event event;
while (SDL_PollEvent(&event)){
switch (event.type) {
case SDL_QUIT:
return 0;
}
}
}
}
Porting to 1.6
The largest and most influential change to libtcod, between versions 1.5.2 and 1.6.0, was the move to replace SDL with SDL2_. SDL2 made many extensive changes to concepts used in SDL. Only one of these changes, the separation of text and key events, required a change in the libtcod API requiring users to update their code in the process of updating the version of libtcod they use.
When a user presses a key, they may be pressing SHIFT and =. On some keyboards, depending on the user's language and location, this may show + on the screen. On other user's keyboards, who knows what it may show on screen. SDL2 changes the way "the text which is displayed on the user's screen" is sent in key events. This means that the key event for SHIFT and = will be what happens for presses of both + and = (for user's with applicable keyboards), and there will be a new text event that happens with the displayed +.
In libtcod 1.5.x
SDL would when sending key events, provide the unicode character for the key event, ready for use. This meant that if the user happened to be using a British keyboard (or any that are similarly laid out), and pressed SHIFT and =, the event would be for the character +.
In libtcod 1.6.x
With SDL2, the raw key-presses still occur, but they are fundamentally linked to the keyboard of the user. Now there will still be an event where it says SHIFT and = are pressed, but the event will always be for the unmodified character =. The unicode text arrives in a new kind of event, and getting it requires explicitly checking that the event is the new text event, and then looking for the value in the relevant text field for the language being used.
if (key->vk == TCODK_TEXT) {
if (key.text[0] == '+') {
}
}
Still confused?
Run your code from a terminal or DOS window and print out the event attributes/fields and look at what is going on. Have your code print out the modifiers, the keycode, the character, the text, and then run it and try pressing some keys. It will be much faster than posting "I don't understand" or "Can someone explain" somewhere and waiting for a response.
.. _SDL2: https://www.libsdl.org/index.php