Temple of The Roguelike Forums
Development => Programming => Topic started by: Cfyz on February 27, 2014, 01:31:51 AM
-
With mixed feelings of pride and uncertainty I present you a project I've been working on for some time. This is a library aimed to simplify the interface part of a roguelike development. Something along the lines of libtcod but focused primarily on output, maybe ncurses will be a closer example.
(Yup, I am no native English speaker so please bear with me =_=.)
The library is available from http://foo.wyrd.name/en:bearlibterminal (http://foo.wyrd.name/en:bearlibterminal). The documentation is also there, though somewhat incomplete. However, the rest will follow in time and the library itself is practically done, so I believe there is no point to delay its "international" release any longer.
This library provides you with a window and allows for easy tile and tileset manipulation while keeping pretense that the scene is mainly text or pseudographics. Quick example:
#include "BearLibTerminal.h"
int main()
{
terminal_open();
terminal_set("window: size=32x8");
terminal_set("font: UbuntuMono-R.ttf, size=12");
terminal_print("Hello, ωōrlд!"); // UTF-8
terminal_refresh();
terminal_read();
terminal_close();
return 0;
}
(http://foo.wyrd.name/_media/en:bearlibterminal:example_helloworld.png)
The library is not for C/C++ only. As it is a dynamic-link library, it also has bindings for C#, Pascal, Lua and Ruby, which should make it suitable for rapid prototyping. It also runs on Windows and Linux.
There is a showcase named "SampleOmni" included in the download archive. You may be surprised at how much can be squeezed from the measely 20 functions of the library API.
Well, I hope it helps someone =)
-
Looks neat. I read the original forum briefly, the library was in development for quite a while. And it looks versatile and crossplatform. The examples with layers resemble Cairo documentation, btw. I tried to compile the source code on my 64bit Linux, and it failed at libfreetype2. (Unless I did something wrong with cmake)
/usr/bin/ld: ../Dependencies/FreeType/libfreetype2-minimal-static.a(ftbase.c.o): relocation R_X86_64_32 against `.text' can not be used when making a shared object; recompile with -fPIC
../Dependencies/FreeType/libfreetype2-minimal-static.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
Terminal/CMakeFiles/BearLibTerminal.dir/build.make:790: recipe for target 'Output/libBearLibTerminal.so' failed
make[2]: *** [Output/libBearLibTerminal.so] Error 1
CMakeFiles/Makefile2:128: recipe for target 'Terminal/CMakeFiles/BearLibTerminal.dir/all' failed
make[1]: *** [Terminal/CMakeFiles/BearLibTerminal.dir/all] Error 2
Makefile:75: recipe for target 'all' failed
But it seems that FreeType2 is available for my distribution, and most likely for other distributions too. Maybe, I can use my native library to build BeaR on a 64bit system?
Another question. Is the library designed to be simply copied in your project directory, and distributed together with the source code of the game (if I make my code open source)?
Also, I suppose that the library is distributed under some unspecified free / open source conditions, right? ;D I did not find anything specific about the license, but it's good to have one.
-
This looks very useful. Having a license would be a good idea. If it's a permissive license I may use it instead of NotEye for this year's 7DRL. Also I'd recommend distributing as .zip or .tar.gz; not everyone has 7-zip installed.
Edit: looking at the source code, it seems to be distributed under the MIT license. I haven't checked all the source files for it and there doesn't seem to be a license file applying to the whole library.
-
I tried to compile the source code on my 64bit Linux, and it failed at libfreetype2. (Unless I did something wrong with cmake)
It's unlikely to be your fault, the 64bit builds are just not tested yet. The code should be okay though, it mostly build configuration problem. I'll try to fix this soon.
However, do note that code relies on C++11 features, which essentially requires GCC 4.8+. I'll probably try to make it more compiler-friendly, as lower GCC versions had pretty good C++11 support and MSVC is improved greatly with VS2013 release, but for now it is not supposed to be a part of a project source. Instead, if there is no suitable build yet, compile it separately and include the binary in the project.
Maybe, I can use my native library to build BeaR on a 64bit system?
You should be, by replacing include_directories and target_link_libraries in the ./Terminal/CMakeLists.txt file. The intention behind including a copy of freetype2 code is to make sure the game will rasterize TrueType identically down to the pixels on every platform. It is important when mixing TrueType main font with bitmap tilesets.
Is the library designed to be simply copied in your project directory, and distributed together with the source code of the game (if I make my code open source)?
Not sure I understood you here. The library binary is supposed to be distributed along with an application, but mostly because I do not imagine it in installer form =). The location of sources is up to you.
I did not find anything specific about the license, but it's good to have one.
If it's a permissive license I may use it instead of NotEye for this year's 7DRL.
The library is licensed under MIT. It is stated so in every source file, headers and bindings included =). Shoud have mentioned that on the site too, probably.
-
Brilliant )))
A license file inside the source distribution would also help to make it clear.
The mouse input sample behaves strangely for me. When I scroll nothing happens, but if I then click, rhe scroll state updates. Would it be possible for the scroll wheel to emit an event (with the change in the scroll state) instead?
-
The mouse input sample behaves strangely for me. When I scroll nothing happens, but if I then click, rhe scroll state updates. Would it be possible for the scroll wheel to emit an event (with the change in the scroll state) instead?
It can emit an event. In the demo there is a list of input mask flags at the top-left corner, you can select "mouse scroll" there. By default only key presses and releases produce the events but mouse movement (cell or pixel-level) and mouse wheel scrolls may be included there as well. The configuration string would beterminal_set("input.events=keypress+keyrelease+mousescroll");
and the event itself is TK_MOUSE_SCROLL.
-
Is there any relation to Bear (http://forums.roguetemple.com/index.php?topic=4.170) who was a long time rgrd regular (I don't know if he is still posting there) and a RogueTemple poster?
-
Is there any relation to Bear who was a long time rgrd regular
No =) "bear" here is a reference to the "BeaRLibrary" collection of roguelike-oriented libraries from the russian rlgclub.ru forum (like, russia = bears >_<). There are at least separate BearLibMG (map generation) and BearLibPF (pathfinding) libraries, though I have no connection to them.
-
Thank you for the clarification regarding the license.
Is the library designed to be simply copied in your project directory, and distributed together with the source code of the game (if I make my code open source)?
Not sure I understood you here. The library binary is supposed to be distributed along with an application, but mostly because I do not imagine it in installer form =). The location of sources is up to you.
My question was mostly about packaging BearLibTerminal for Linux: A library can be installed as a separate package (like ncurses or SDL do, for example). Alternatively, I can simply copy BearLibTerminal source code in my source code, and distribute them both as a single piece. One more approach, when building from sources, is to fetch both my code and BearLibTerminal code from their repositories, build together at the user's machene and install the game.
Sorry for compicating things, but when developing an open source game, I want to be sure that a user will be able to build the game without much hassle.
-
I used cmake to generate a VS2013 project for SampleOmni. It compiles and it can find the BearLibTerminal.dll file, but it crashes when main() starts. Maybe I configured it wrong.
However, I compiled the small example program and it runs fine. I'm playing with terminal_put_ext() now. I'll resist the temptation to put Cyrillic monsters in my 7DRL!
I think Python is very popular with roguelike developers, so a python binding would probably add a lot of potential users.
Also, it would be nice for code completion if the api functions and constants were in a namespace, like one of these:
bl::terminal_refresh();
blt::terminal_refresh();
bl::refresh();
blt::refresh();
-
I've made a simple example of smooth movement using exponential decay. You can find the code at https://dl.dropboxusercontent.com/u/6433222/bear_term_smooth.cpp (https://dl.dropboxusercontent.com/u/6433222/bear_term_smooth.cpp). It's public domain, so you're free to add it to OmniSample or do whatever you want with it. I expect you'll want to change the way I wrote the terminal_set() commands.
When you use a movement command, the character's map position changes, but its offset dx,dy is changed so that the screen position stays the same. Every frame, dx and dy decay towards 0 with a custom half-life (in milliseconds).
-
Updated the library to version 0.9.8: http://foo.wyrd.name/en:bearlibterminal#download (http://foo.wyrd.name/en:bearlibterminal#download)
koiwai, I fixed the project a bit and now it should compile fine on 64-bit systems. Also I've changed CMake project structure for easier incorporation into another project's source tree. Now entire library source with all its dependencies is under ./Terminal directory (so the root CMakeLists.txt and this directory is all you need) and ./Samples is now optional. If you remove samples directory before CMake generation, it won't complain about that and will build just the library.
it would be nice for code completion if the api functions and constants were in a namespace
Well, the problem is that C++ header is also header for C which do not have namespaces. Where it is not a case (e. g. C# or Ruby) API functions are indeed grouped under some namespace. Also I'm not sure what you mean by "code completion", as IDEs auto-complete current variant just fine (checked MSVS and Eclipse).
I used cmake to generate a VS2013 project for SampleOmni. It compiles and it can find the BearLibTerminal.dll file, but it crashes when main() starts. Maybe I configured it wrong.
Whoa. I have not had my hands on VS2013 yet and given how different GCC and MSVC are I expected it to fail right from the start =) Looks like they did a good job fixing C++11 support. I will make library compileable by MSVC later, but for now you should either build it with MinGW or just use a prebuilt binary. Not that I discourage you from experimenting =)
If it crashes in terminal_open, it might not be MSVC's fault, as there was a mistake in calling convention of OpenGL extension function. Whether it will crash or not somehow depended on compiler optimization options and usually it was ok. Fixed now.
I'll resist the temptation to put Cyrillic monsters in my 7DRL!
Angry ё (like e but with eyes open), spider Ж, butterfly Ф, paired monsters Я and R. Well, there is not much actually, I think Greek is better material as it is generally more familiar (think math). My favourite one is Ω, which is, of course, a wind spirit (see fūjin (http://en.wikipedia.org/wiki/F%C5%ABjin)).
I've made a simple example of smooth movement using exponential decay.
Nice one. I think I'll include it into samples though most likely edit it beyond any recognition >_<. And I have some comments about the code If you don't mind...
It might be a matter of preference but I thing constructing configuration string that way is rather cryptic. There is a printf-like version of set:
terminal_setf("window: size=%dx%d, cellsize=%dx%d, title='%s'", TERM_WIDTH, TERM_HEIGHT, CHAR_WIDTH, CHAR_HEIGHT, TITLE_STR.c_str());
// what do I do if I want to use argc, argv?
Well, then you just do not use TERMINAL_TAKE_CARE_OF_WINMAIN macro and declare main yourself. It's just a bit of sugar to get rid of all those HINSTANCE and Windows.h include as most of the time graphical applications do not take command-line arguments anyway.
-
Thanks for the comments. I didn't see terminal_setf when I looked at the API and samples. It's a much better solution.
-
Is there any possibility of compiling this for mac as well? Would any changes to the source code be required?
-
Right now it is impossible to compile it on Mac. The library creates a UI window on its own via OS API calls and that requires platform-specific code. Such code is isolated by implementing a subclass of the BearLibTerminal::Window, e. g. X11Window or WinApiWindow. However, after that the rest will require just a few simple tweaks. Mac is very close to Linux but interacting with OS requires Objective-C and right now I have zero experience with that. I do plan to port it to Mac, just can't say when =(
As a relatively quick hack I can try to make 'generic' window implementation via SDL. This will obviously introduce a library dependency, but can help with portability as the rest of the code is mostly platform-agnostic.
By the way, I lowered compiler requirement to GCC 4.6.3, which comes with much more distros than 4.8. Trying to support even lower versions will require rewriting a lot so I stop here for now. As for MSVC, VS2013 is pretty good, I'll make library code support it shortly. And actually Windows is more lenient here as one can use VS2013 to compile a binary that will run on any sensible Windows version, i. e. from XP to 8. In Linux 64-bit version can't link statically to libstdc++ thus for library to run on different distros, it have to use the lowest possible version of libstdc++.
Also, about compiling SampleOmni with VS2013. I've found a rather shameful mistake in sample code. In WindowsGlyphList.cpp the list of ranges was initialized from references to temporaries rather than actual objects, fixed now. Well, working okay with some particular compiler also falls under UB =)
-
Contrary to how it might look, the project is alive. Not very popular though, but oh well.
Version 0.10: http://foo.wyrd.name/en:bearlibterminal#download (http://foo.wyrd.name/en:bearlibterminal#download)
I did try to make SDL-based window implementation but somehow it resulted into a mess. SDL is good, robust library when you start from it and build your app around its infrequient quirks. However, integrating it into project (half of which functionality is window management) halfway is not as simple as it seems. I've found myself working more against SDL than with it. Therefore, Mac port is delayed for now.
Instead I've refactored the input subsystem (which was a mess by itself) a bit and implemented a couple of new features. Nothing really breaking, though.
1. Minor adjustments in constants naming like TK_PAGEUP or TK_MOUSE_LEFT instead of WinAPI-legacy TK_PRIOR and TK_LBUTTON. Constants related to mouse or numpad are now grouped together: TK_MOUSE_xxx, TK_KP_xxx.
2. Input event categories are removed. There was an input.events option before which allowed to 'subscribe' on keypresses or keyreleases or mouse with somewhat inconsistent mechanics. For example, TK_CLOSE is better not to be ignored (what category it is?), same with TK_RESIZED. And actually there is no real difference between keypress and keyrelease for application as user always can press a whole lot of random buttons you will have to ignore anyway. So now the read function does read everything (like GetMessage, ha), you just have to handle only those events you're interested in.
3. Next is read_ext. A thing with somewhat obscure logic. It was introduced because it was necessary to read both event scancode and character code produced by that event: terminal_read_ext(TK_READ_CHAR). Ugh, somehow it did not fazed me in the slightest that there was already mouse events where you can read both the event and mouse properties at the same time: via terminal_state(TK_MOUSE_xxx). Therefore, the read_ext is removed and two new states are introduced: TK_CHAR and TK_WCHAR. They simply return the code of a character produced by the latest read input event, or zero if none was produced: int key = terminal_read();
if (key == TK_ESCAPE)
{
return;
}
else if (terminal_state(TK_WCHAR) > 0)
{
str += (wchar_t)terminal_state(TK_WCHAR);
}
TK_WCHAR returns an Unicode codepoint of the character and TK_CHAR return an ASCII/ANSI codepoint translated accordingly to the codepage selected with the terminal.encoding option.
There was also non-blocking input via read_ext but it can easly implemented without additional API methods:// Both literally,
int key = terminal_has_input()? terminal_read(): 0;
// ...and logically
while (terminal_has_input()) {
int key = terminal_read();
...
}
Oh, there is also TK_EVENT that will return a scancode of the last dequeued input event.
4. Mouse input has been extended. There are new TK_MOUSE_X1 and TK_MOUSE_X2 buttons which are additional buttons on some mouse models. There is new TK_MOUSE_CLICKS state that return a number of fast consecutive clicks by the time of the last dequeued mouse button event. E. g. terminal_state(TK_MOUSE_CLICKS) == 2 indicated that this TK_MOUSE_LEFT event is the second one in double-click action.
Also, TK_MOUSE_WHEEL now returns scroll delta instead of some global counter.
5. You can press Alt+Enter to switch between windowed and fullscreen mode (with no display resolution change). The window.fullscreen option may be used to force the fullscreen mode programmaticaly.
6. You can press Alt+[plus/minus] to scale the window up and down. This may be useful if some application uses tiny tileset and you want to run it on FullHD+ display. For now it is done via simple OpenGL scene scaling. Later I'll try to take advantage of shaders where they are supported. But you cannot scale resizeable window (window.resizeable option) as it would allow for a number of difficult configuration cases I'm not yet sure how to deal with.
7. There is also a couple of debug key combinations: Alt+G will turn on cell grid and Alt+A will dump the texture atlas on disk.
The up-to-date reference on the input subsystem is located here: http://foo.wyrd.name/en:bearlibterminal:reference:input (http://foo.wyrd.name/en:bearlibterminal:reference:input)
-
Another update: v0.11.1: http://foo.wyrd.name/en:bearlibterminal#download (http://foo.wyrd.name/en:bearlibterminal#download)
'print' function now allows for text alignment and autowrap. This is done via formatting tags.
T.print_(40, 12, "[align=bottom-right]Spike Vixen\nGrease Monk")
(https://dl.dropboxusercontent.com/u/3661545/BearLib/2014-08-13/align-bottom-right.png)
T.print_(40, 12, "[bbox=30x10]Void Initiate: gain 1 rune. "
"You may banish a card in your hand or "
"discard pile.")
(https://dl.dropboxusercontent.com/u/3661545/BearLib/2014-08-13/bbox.png)
Dimensions of an autowrapped string may be calculated without printing with the 'measure' function:
int height = terminal_measuref(L“[bbox=%d]%ls”, width, ws.c_str());
Using simple in-text iconographics or alternative fonts is a bit easier now:
terminal_print(“One [font=0xE000]Two”);
(https://dl.dropboxusercontent.com/u/3661545/BearLib/2014-08-13/fonts.png)
T.print_(2, 1, "This spell requires: 2[0xE004] 3[0xE022]")
T.print_(2, 3, "The scroll says \"[font=0xE100]whatewer[/font]\"")
(https://dl.dropboxusercontent.com/u/3661545/BearLib/2014-08-13/fonts-mixing.png)
By combining these features it is fairly easy to implement text output with basic formatting, scrolling dynamically adjustable output area. It is demonstrated in SampleOmni showcase. I would add a picture here but it is big and I can't find a spoiler tag =_=.
And there is now a Python wrapper which works with 2.x and 3.x versions:
import PyBearLibTerminal as T
T.open()
T.print_(2, 1, “Hello, wordl”)
while True:
T.refresh()
key = T.read()
if key == T.TK_CLOSE or key == T.TK_ESCAPE:
break
T.close()
#bearlibterminal #nobodycares #everyonereadsthetags
-
Wow, played around with this over the weekend, and it seems to be almost exactly what I am looking for - very nicely done! Makes me want to abandon my current project and start a new one using this. I like libtcod, but I only want that display functions and not all the other stuff it brings along (along with a bit of a learning curve.)
3 quick questions:
1) Do you plan on including any basic drawing functionality? We're just talking simple colored lines, or maybe an ellipse function. (For drawing UI borders and such.)
2) When using composition to stack tiles on the same location on the same layer, is there any way to make a copy of the composed tile and save it off as a temporary (or even permanent) tile that can be reused, or would I always need to rebuild (recompose) the tile each move?
3) Similar to question 2, is there a function to simply copy an area of the screen and paste it somewhere else? (It wouldn't need to retain all the layers; purely just a pixel copy of a designated space, placed into it's own layer in a different spot.)
Sorry if these question are already answered - I have been reading the API reference on your webpage, and I have a feeling they are already answered and I am just not searching for my answers with the right phrase.
Again, very nice library - please continue to develop it :)
-
Thanks for your feedback =)
Do you plan on including any basic drawing functionality? We're just talking simple colored lines, or maybe an ellipse function. (For drawing UI borders and such.)
Not sure. Such "classic" drawing primitives do not combine well with cells/characters architecture. The library does not draw tiles the moment you issue 'put' or 'print' command but constructs a 'scene description' for later render. This allows more 'terminal'-way operation where you can replace some of the characters while leaving everything else intact. This also allows library to redraw the scene all by itself if necessary. Lines and circles are rather foreign to characters-based modifiable scene structure, and I do not see a way to make a clear API with those.
I had considered going all the way to the optional 'custom' output via some callbacks hooked into a scene (e. g. to a layer). Inside callback you would have a different drawing context where you can do things differently because it does not buffer drawing commands. And from the API perspective it becomes very clear that mechanics are different because mode change is intentional and obvious. However, it has a whole new lot of problems not completely thought out yet so the priority of this is fairly low.
As for UI, wouldn't it be enough to just prepare a few tiles for borders and corners?
When using composition to stack tiles on the same location on the same layer, is there any way to make a copy of the composed tile and save it off as a temporary (or even permanent) tile that can be reused, or would I always need to rebuild (recompose) the tile each move?
Right now the only option is to reconstruct them every time. Given the scene architecture it is not as straightforward as copying pixels, but I think its possible to allow to save an output string (which usually goes to 'print' and supports combining via formatting) as a precomputed template, e. g. like this:
terminal_set("0xE100: 'a[+][color=red]/'");
terminal_put(2, 1, 0xE100);
Though it will take a decent amount of coding =).
Similar to question 2, is there a function to simply copy an area of the screen and paste it somewhere else? (It wouldn't need to retain all the layers; purely just a pixel copy of a designated space, placed into it's own layer in a different spot.)
As I mentioned above, pixel copy is almost impossible and layers do make a problem. However, it indeed may be a useful feature, will think about it. What do you intend to use it for exactly?
-
I had considered going all the way to the optional 'custom' output via some callbacks hooked into a scene (e. g. to a layer). Inside callback you would have a different drawing context where you can do things differently because it does not buffer drawing commands. And from the API perspective it becomes very clear that mechanics are different because mode change is intentional and obvious. However, it has a whole new lot of problems not completely thought out yet so the priority of this is fairly low.
As for UI, wouldn't it be enough to just prepare a few tiles for borders and corners?
Yeah, I could just use tiles to make the border and other effects....especially if I could scale and rotate the tiles ;)
Similar to question 2, is there a function to simply copy an area of the screen and paste it somewhere else? (It wouldn't need to retain all the layers; purely just a pixel copy of a designated space, placed into it's own layer in a different spot.)
As I mentioned above, pixel copy is almost impossible and layers do make a problem. However, it indeed may be a useful feature, will think about it. What do you intend to use it for exactly?
I was just thinking in terms of performance, which probably isn't an issue :) If you have 10 enemies and the player, and each is composed of 10 layered tiles (body, armor, boots, cloak, weapon, helmet, effects, etc), along with other layered/composed parts of the scene... If you could save each off beforehand you could just redraw a single tile reducing the number of tile look-ups/copies by a factor of 10.
Again, this was just me thinking through a future problem - the reality is I probably would get to the point I described above and find the performance almost completely identical in both cases.
Either way, still very well done - whatever the ultimate answer is, it won't deter me from checking this out and seeing what I can do with it.
Thank you again for your hard work, and please keep at it - even if people don't seem to respond or give much feedback, there are some of us who still are very grateful for your efforts.
-
A newbie's question: any tutorial on using this work of art hehe?
-
Sorry but there is no such thing yet. For now there are only a function reference (http://foo.wyrd.name/en:bearlibterminal:reference) and a number of short C++ examples (https://bitbucket.org/cfyzium/bearlibterminal/src/d798f8cec2301ccbef75858009e27c8e3cfa784a/Samples/Omni/Source/?at=default). I'd like to say I'm working on it but sadly I'm a bit busy right now =|. I do plan to make a regular tutorial though. Probably based off one already popular like libtcod's or something =).
However, I'll answer any questions. It would help to at least know what language and platform you are using so I'll be able to take those into account later.
-
Ah thanks a lot! So far I'll be playing with the reference and samples to see what I can do. I'm using C++ with MinGW GCC 4.8 (I think) or the latest regular Clang from 27.10.2014. (whichever I feel like I guess) on Win7 Ultimate 64-bit.
-
#bearlibterminal #nobodycares #everyonereadsthetags
I care! BLT is my first choice for a roguelike display/input library at the moment. It has much more flexibility as a display system than libtcod, and isn't bloated with mapgen/fov features. Text alignment/wrapping, inline icons, and Python support are great additions.
I haven't written any games since the March 7DRLC (health problems), but when I start again I'll be very pleased to continue using BearLibTerm.
-
Been a while hehe but I've gotten round to playing with it again and, well, got this thingy here --- "error: 'terminal_delay' was not declared in this scope". Every other thing I've used works so it's not bad linking, and I copied it off the API reference a couple of times just to make sure I wasn't doing something bad. Oversight?
-
Sorry for the delay, was somewhat busy =_=.
got this thingy here --- "error: 'terminal_delay' was not declared in this scope". <...> I copied it off the API reference a couple of times just to make sure I wasn't doing something bad. Oversight?
Pretty much. I've updated the library but got distracted, messed up the links and did not post about it >_<. Try redownload the 0.11.3 version.
The 0.11.3 update:
* terminal_pick* (http://foo.wyrd.name/en:bearlibterminal:reference#pick) functions to examine cell contents.
* terminal_peek (http://foo.wyrd.name/en:bearlibterminal:reference#peek) to preview an input event.
* terminal_delay (http://foo.wyrd.name/en:bearlibterminal:reference#delay) to pause the execution a bit.
* There is no input.sticky-close option anymore (it has introduced more problems than it solved).
* Input filtering added. By setting the input.filter (http://foo.wyrd.name/en:bearlibterminal:reference:input#input_options) option one can select which events will be returned by terminal_read (e. g. keyboard keypresses only) and which will be ignored.
-
Made a brainfuck interpreter in the library for general practice :D
Might be offtopic, but the library is fast enough to make it viable!
Edit: hey, I'm gettin bits of issues: when I run the .exe normally it sets itself up OK but when I run it with cmd.exe it doesn't set up the font. Any ideas why?
-
This is quite nice. I've got it working with C# already, I have dungeon generation ported in from an earlier game project, and the API of BearLibTerminal seems quite well-thought-out. Kudos! I'm just not sure how to use a custom codepage. If I have an image like https://dl.dropboxusercontent.com/u/11914692/Zodiac-Narrow.png (https://dl.dropboxusercontent.com/u/11914692/Zodiac-Narrow.png), where the first row corresponds to Unicode U+0000-U+007F, and the second row to U+2500-U+257F , how would I get the codepage to load? I've already tried making a file, custom.txt , with the text "U+0000-U+007F, U+2500-U+257F" like the encodings in BLT's source use, but every glyph displays as a box (the not-found glyph). Does the file have to be an embedded resource? The image isn't...
-
when I run the .exe normally it sets itself up OK but when I run it with cmd.exe it doesn't set up the font. Any ideas why?
Somehow I did not receive any forums notifications and notice this question only now =/. As for the library behaviour, it most likely attributes to possibly different working directories when run in different ways. Try to look for bearlibterminal.log, the library will complain there if it can't find the file.
I've already tried making a file, custom.txt , with the text "U+0000-U+007F, U+2500-U+257F" like the encodings in BLT's source use, but every glyph displays as a box (the not-found glyph).
Hmm, every glyph? I've tried using your image:
T.set("font: ./Zodiac-Narrow.png, size=12x24, codepage=./Zodiac-Narrow.txt")
T.print(2, 1, "Hello, world! [U+256C] [U+2573]")
U+0000-U+007F, U+2500-U+257F
And its mostly working. The regular text (U+0000-U+007F, "hello world" part) is output in the correct font. With the U+25xx glyphs there is a bug, though. The library has built-in generator for Box Drawing and Block Elements unicode ranges in case the font doesn't have those -- or if it is a TrueType font which rarely have useful Box Drawing characters. Bitmap fonts should have higher priority but I've made a mistake there. I'll upload a fixed version later today.
Even with this bug you should not be getting glyph-not-found boxes.
-
My source is here, in case there's something obviously wrong: https://github.com/tommyettinger/DungeonRising (https://github.com/tommyettinger/DungeonRising). The code starts in DungeonRising/Entry.cs (here https://github.com/tommyettinger/DungeonRising/blob/master/DungeonRising/Entry.cs#L81 (https://github.com/tommyettinger/DungeonRising/blob/master/DungeonRising/Entry.cs#L81)); it calls Terminal.Put(int, int, char) each time it wants to render something.
-
I'll upload a fixed version later today.
Here it is, 0.11.4 (http://foo.wyrd.name/en:bearlibterminal#download).
My source is here, in case there's something obviously wrong
Well, this gets weirder. I've downloaded the source, opened it in VS2013, switched startup project to 'Runner32' and hit 'Run': screenshot (https://dl.dropboxusercontent.com/u/3661545/dungeon-rising-1.png).
Try setting 'log.level' option before other configuration, i. e.Terminal.Set("log: level=trace");
Terminal.Set("window: title='Dungeon Rising', size=110x45; font: Zodiac-Narrow-6x12.png, size=6x12;");
Post a screenshot and generated 'bearlibterminal.log', maybe that will give me some clue.
-
I haven't tested noto's code so I don't have a clue what I'm talking about, but is it possible that the issue is with the working directory not being the same as the directory with the font image?
VS seems to have a habit of making the working directory different from the executable directory, and this has stung me before when using eg. libtcod.
-
Yeah, I posted a working version to Github, the line I highlighted didn't have a codepage set. If you still have the project, change the only line that calls Terminal.Set (it's in Entry.cs, method Run) to:
Terminal.Set("window: title='Dungeon Rising', size=110x45; font: ./Zodiac-Narrow-6x12.png, size=6x12, codepage=./custom.txt;");
I've set it to copy custom.txt (in each of the Runner projects) to the output directory, same as the png. cfyz, I'll try 0.11.4 now, could you maybe fiddle with the codepage settings in that line?
-
I just posted an update to GitHub, using 0.11.4, and I have a screenshot, log, and debug build.
Log:
09:39:39.901 [Info] Trying to set "window: title='Dungeon Rising', size=110x45; font: ./Zodiac-Narrow-6x12.png, size=6x12, codepage=./custom.txt;"
09:39:39.904 [Debug] Group "window":
09:39:39.904 [Debug] * "size" = "110x45"
09:39:39.905 [Debug] * "title" = "Dungeon Rising"
09:39:39.905 [Debug] Group "font":
09:39:39.906 [Debug] * "codepage" = "./custom.txt"
09:39:39.906 [Debug] * "name" = "./Zodiac-Narrow-6x12.png"
09:39:39.907 [Debug] * "size" = "6x12"
09:39:39.907 [Debug] Tileset resource name "./Zodiac-Narrow-6x12.png" is recognized as a name of a bitmap resource
09:39:39.908 [Debug] Bitmap tileset: failed to parse guessed tile size, not an error
09:39:39.909 [Debug] Requested resource "./custom.txt" with possible prefix "codepage-"
09:39:39.909 [Debug] Requested resource "./Zodiac-Narrow-6x12.png" with possible prefix "tileset-"
09:39:39.911 [Trace] Loaded PNG image, 768x24
09:39:39.911 [Debug] Tileset has 128x2 tiles
09:39:39.912 [Debug] Successfully loaded a tileset for base code 0
09:39:39.912 [Debug] Reloaded the tileset with base code 0
09:39:39.913 [Trace] Scheduling texture #103078664 for removal
09:39:39.914 [Trace] Added tile texture #103078664
09:39:39.914 [Info] Added Unicode replacement character tile (6x12)
09:39:39.915 [Debug] SetOptions: new cell size is 6x12
09:39:39.915 [Debug] SetOptions: new window size is 110x45
Screenshot:
(https://dl.dropboxusercontent.com/u/11914692/DungeonRising_BoxProblem.PNG)
Debug Build: x86 https://dl.dropboxusercontent.com/u/11914692/DungeonRisingDebugBoxProblem_x86.zip (https://dl.dropboxusercontent.com/u/11914692/DungeonRisingDebugBoxProblem_x86.zip)
and x64 https://dl.dropboxusercontent.com/u/11914692/DungeonRisingDebugBoxProblem_x64.zip (https://dl.dropboxusercontent.com/u/11914692/DungeonRisingDebugBoxProblem_x64.zip)
Quendus, your answer seems likely, given the log; it mentions loading the png but not the codepage.
-
Figured this out, after a bit of meditation over two identical .txt files, one working as a codepage and one not. I do not see UTF-8 files with BOMs (http://en.wikipedia.org/wiki/Byte_order_mark) often, so my own tests did not catch that. And the ad-hoc parser used for codepages turned out to be too simple to handle it.
For now you should just remove the BOM (File -> Advanced Save Options -> UTF-8 without signature). I'll release another bugfix shortly =_=.
-
Yep, that was it. I committed the 2-character change and now it works. You're a master! Now I just need to make a game...
-
Here's a fairly simple and complete BOM detector I wrote awhile back in D, should be easy to port or at least give an idea. https://gist.github.com/Brian61/298fba834f851bf95be2 (https://gist.github.com/Brian61/298fba834f851bf95be2).
Switched to C# in my latest project and spent yesterday creating the interface between my new project and BearLibTerminal :)
Quick questions:
In the string passed to set, is whitespace necessary between the separators (':',',',';')? Also is extra whitespace permissible at end of string, and lastly are embedded line endings allowed?
And another :)
If you attempt to get a char value via: Terminal.State(Terminal.TK_CHAR) during a non printable char event (mouse for ex), do you just get 0? (Update: went source diving and it looks to be the case.)
Finally, a suggestion: For some uses in C#, the list of const int TK_XXX symbols in BearLibTerminal.cs would be much better represented as a public enum outside the Terminal class, say as public enum TerminalKeys {...}. Its not a huge deal since you can do as I've done and just cut-n-paste the list of symbol = value, pairs.
-
Here's a fairly simple and complete BOM detector I wrote awhile back in D, should be easy to port or at least give an idea.
That's a nice snippet, gonna save it. I'm not sure about such variety of encodings in this case though, I thought ANSI/UTF-8 would be enough for external text files. Do you think UTF-16/32 encoded files should also be supported? (since it will be a bit of a hassle).
In the string passed to set, is whitespace necessary between the separators (':',',',';')? Also is extra whitespace permissible at end of string, and lastly are embedded line endings allowed?
No, whitespaces are cosmetic there, extra ',' and ';' are also ignored and trailing ';' is optional. As for newlines, it is an oversight and it may or may not work depending on where you place that newline. I'll fix and document this in the next update.
If you attempt to get a char value via: Terminal.State(Terminal.TK_CHAR) during a non printable char event (mouse for ex), do you just get 0? (Update: went source diving and it looks to be the case.)
Yes, you figured it out correctly. The idea is that value of TK_CHAR may be used to determine whether last stroke was textual or not.
For some uses in C#, the list of const int TK_XXX symbols in BearLibTerminal.cs would be much better represented as a public enum outside the Terminal class, say as public enum TerminalKeys {...}.
A lot of constants represent both an input event and a state, e. g. TK_A which may be returned by Read and also may be tested by State/Check. It's either using one single enum or duplicate a lot of constants in separate enums. And one huge list just does not look like enum since its values not equally meaningful within same context. C# is not my area of expertise, so I may miss some fundamental feature or strict community preferences here, but this list of constants does not seem that bad =_=.
-
Do you think UTF-16/32 encoded files should also be supported? (since it will be a bit of a hassle).
No, but it may be worth detecting them and throwing/returning an error to the user.
As for newlines, it is an oversight and it may or may not work depending on where you place that newline. I'll fix and document this in the next update.
Cool :) I'm loading the initial settings from an external file, while I can strip the line endings, it'd be nice I think for future users if it wasn't necessary.
The idea is that value of TK_CHAR may be used to determine whether last stroke was textual or not.
Good. I'm processing the input and sometimes grabbing the value when I don't really need it just to simplify the code, was more worried about causing an internal error accidentally.
For some uses in C#, the list of const int TK_XXX symbols in BearLibTerminal.cs would be much better represented as a public enum outside the Terminal class, say as public enum TerminalKeys {...}.
A lot of constants represent both an input event and a state, e. g. TK_A which may be returned by Read and also may be tested by State/Check. It's either using one single enum or duplicate a lot of constants in separate enums. And one huge list just does not look like enum since its values not equally meaningful within same context. C# is not my area of expertise, so I may miss some fundamental feature or strict community preferences here, but this list of constants does not seem that bad =_=.
While I wouldn't call it bad in this case, I believe it is considered 'C# best practice' to use enums instead of lists of constants. In my particular use case, I'm making use of the ability to get a string name from the enum by its value. I turn the input events into string descriptors (plus extra data for char value, mouse position, etc) which then is used in a user configurable command table. It allows an easy to implement key map file with lines of the form: "T.CONTROL = JUMP_SIDEWAYS".
Being able to use the enum to turn the integer value into a string ("TK_T" in this case) and then strip the "TK_", add the ".CONTROL" if the control key state is true, etc. Having the values of a long list in a C# enum saves a lot of typing which could potentially introduce errors. Its not a major issue since you can do as I've done and simply cut and paste the list of integer constants into an enum, but that is a potential maintenance problem if the constants are expanded or changed - probably not much of a chance of that in this case.
Anyhow, thanks for doing this library :) It fits in quite well with the data structures I'm using and since I had a 'layers' variable for the imaging already, its nice to be able to use it for something other than a sort order key! Also the guy that's been doing artwork for me will be glad to hear that he can stack tiles and layers since that seems to be the common practice in the portion of the graphics industry he works in.
-
In my particular use case, I'm making use of the ability to get a string name from the enum by its value.
http://ideone.com/Ah494k (http://ideone.com/Ah494k)
I did it mostly for lulz but if your main concern is type conversion, it might actually help to get rid of some copy-paste.
-
OK, Terminal.PutExt is just awesome. I have creatures vibrating wildly within their cell for a moment when damaged, and it was extremely easy to add with BearLibTerminal. Brief video preview: http://a.pomf.se/kmyrvl.webm (http://a.pomf.se/kmyrvl.webm). I'm going to try to port BearLibTerminal to Mac OSX soon (a friend who looked into the code told me that the same X11 window API used on Linux should mostly work on OSX), but first I am having trouble building the lib on Windows -- I posted an issue on BitBucket. I'm really hoping that the Mac port is feasible and can be incorporated into the main code, at least, if I ever get it to work. Cfyz, are you opposed to using a cross-platform library that handles windowing on the (perfectly reasonable) grounds of not wanting a sizable extra dependency, or is there some technical aspect of BearLibTerminal that makes SFML, GLFW, or similar libraries unusable with it?
-
Cfyz, are you opposed to using a cross-platform library that handles windowing on the (perfectly reasonable) grounds of not wanting a sizable extra dependency, or is there some technical aspect of BearLibTerminal that makes SFML, GLFW, or similar libraries unusable with it?
No, I do not oppose this. Whatever the reasons for using homebrew window implementations once were, they do not stand now. Not only OS X, there are also Wayland and various EGL flavours and reimplementing the wheel becomes clearly counterproductive. Ability to change icon in runtime or to resize window in discrete steps just not worth it.
I do plan to delegate windowing to GLFW. In the very near future. This, however, will require some work: current BearLibTerminal uses two threads with rendering in background, which is ok under Windows (which gave me a false impression) and somehow works under most of Linux, but as it turns out it is not guaranteed to work reliably or work at all. Making BearLibTerminal single-threaded will not require any changes in its API (probably, no one will even notice) but this will be a big overhaul in the code. I really appreciate your willingness to contribute but it looks like I'll have to clean up this mess myself.
OK, Terminal.PutExt is just awesome.
I wonder if anyone using corner-coloring in put_ext. I hope no one is. It does not work uniformly (with final result depending strongly on particular hardware, ugh) and restricts some possible optimizations, so I plan to remove it.
-
Here comes a new update
of questionable nature. It fixes a few things like UTF-8 BOM handling in external text files and X11 window title modification, but the main addition is the configuration file.
The idea to add some alternate configuration mechanism came from inability to configure logging options before the library is initialized, which effectively prohibits useful verbose output during the initialization step. The most obvious way would be to allow library configuration before initialization. Using the same terminal_set mechanism, but before terminal_open, is hacky and still requires application modification to switch log verbosity. Meh. Therefore, I decided to add a configuration file in a simplest INI format, which somehow went out of control.
Not only logging, but all library options might be specified in the configuration file, even fonts/tilesets. Furthermore, only the "BearLibTerminal" section is used for initial library configuration and all other sections in the file are left for the application. By utilizing omnipotent terminal_set and newly added terminal_get it is possible to read, add, modify and remove properties in the file:
terminal_set("ini.settings.window-size=80x25"); // Save preferred interface size.
int tile_size = terminal_get<int>("ini.settings.tile-size", 16); // Read requested tileset size.
See API / configuration (http://foo.wyrd.name/en:bearlibterminal:reference:configuration) page for more detailed information.
Downloads are here (http://foo.wyrd.name/en:bearlibterminal#download).
-
You sir, are awesome :)
-
Just tried it out... this library is amazing! I really like how the API is less verbose than libtcod. Definitely my preferred choice now.
-
I don't know if this is exactly the right place to post this, but there aren't any other BearLibTerminal forums as far as I can tell, so might as well. I seem to be having some issues with this library. I created a small main.cpp that just opens and closes the terminal to make sure the library works, but when I try to link it with the library, I keep getting "undefined reference to '_imp__terminal_open()' and '_imp__terminal_close()'". I think the prefix is just name mangling, so I'm not concerned with that, but whatever I do, I can't get the linker to find definitions for the functions. The command I used was "g++ main.cpp -L. -I. BearLibTerminal -lBearlibTerminal -o main" along with several variants of that which changed orders, added extra -l s or .lib s or almost anything else. Everything gives the same error. Also of note, I am using Mingw64 with the MSYS2 shell, if that's at all relevant. Any help with this would be great, as I'm really excited about BearLibTerminal and want to use it if at all possible.
-
Yes, this is the right place, the amount of discussion/issues does not justify a dedicated forum (hmm, yet?). On another thought, issues should go to issue tracker (https://bitbucket.org/cfyzium/bearlibterminal/issues?status=new&status=open) of the repository. Always forget there is one.
The problem with linking is that MinGW linker does not seem to understand Windows import libraries (the .lib accompanying .dll, usual for MSVC), but it considers such library first while searching. So it finds BearLibTerminal.lib, tries to link against it and complains there is still no implementation. MinGW, however, is fully capable to link against .dll, so you just need to remove the .lib file. The working command is pretty much what you've used:
g++ -I. main.cpp -L. -lBearLibTerminal -o main
Noted this down, such nuances really should be documented =_=.
-
Hmm...
I tried that command. It now says "./BearLibTerminal.dll: file format not recognized." I also tried it on another MinGW(normal, not 64) shell and a Cygwin shell that I had lying around, and both did the same thing. I thought DLLs were pretty much the standard for windows external libraries, so I don't really understand how this could be the case. Are my toolchains set up incorrectly?
-
This most likely means compiler and library do have different bitness. It sometimes not obvious: rare compiler build shows what its available/target bitnesses are. Requesting the mode manually usually helps identify the problem.
For example, using 32-bit TDM-GCC and 64-bit .dll:
g++ main.cpp -L. -lBearLibTerminal -o main
./BearLibTerminal.dll: file not recognized: File format not recognized
collect2.exe: error: ld returned 1 exit status
Now explicitly specifying I want it to be 64-bit (to match the library):
g++ -m64 main.cpp -L. -lBearLibTerminal -o main
main.cpp:1:0: sorry, unimplemented: 64-bit mode not compiled in
Now replacing the library with 32-bit version does help.
Btw, MSYS/Cygwin are unnecessary here as BearLibTerminal.dll is a regular Windows library.
-
Ah! That's done it!
32bit version of the library works for me. It's weird though that MinGW64 didn't work with a 64bit library though...
In any case, thank you so much Cfyz! Now to make a game!
-
So, trying to use this in VS2012 for C# I'm getting this http://puu.sh/jh89p/d6c2d8767b.png
When I looked up what to do I found that I had to run some kind of tool, which I tried and got this http://puu.sh/jh8bD/5518b8ff84.png
Not sure what's going on, but apparently it's because this wasn't compiled with .NET?
EDIT: I also tried just adding the DLL, same error I was getting before. It can't find the DLL to actually use it so it crashes at runtime.
-
You do not need to reference the library binary in any way. The .dll piece is pure native code with plain C interface. However, you will obviously need to place it in 'working directory' of the application (usually just besides the application executable; this is true for VS2015 at least, not sure about other VSs and it may be overrided in project settings).
The .\Include\C#\BearLibTerminal.cs file is the one that needed to be included in the project (there is a bunch of DllImports in there). You will also need System.Drawing assembly referenced.
-
So I did all of that and it works now, but the 64bit dll still crashes. At least I've got functionality though, thanks man. Also the default C# console stays open even when the terminal is open, I'm assuming that's normal.
-
Most likely 64-bit dll 'crashes' because the application is 32-bit. You cannot use 64-bit libraries from 32-bit application and vice versa. Even though your application is .NET, it all comes down to native code instructions at some point. Hence the 'Build' -> 'Platform Target' / 'Prefer 32-bit' options in project settings. I do not know of a way around this short of rewriting the whole Terminal in C#. And 32-bit works everywhere anyway.
Default console is there because of application type ('Application' -> 'Output Type' in project settings), switch it to 'Windows Application'. You could have created windows project instead but then MSVS would generate an unnecessary window form, switching one option is easier.
-
Looks interesting, Ill check it out.
-
Hey! Your library looks great, and I'm trying to make a roguelike with it. However, as usual, I get stuck at the beginning. Namely, it seems that terminal_set() does absolutely nothing in my game. It doesn't change the window size, font, or anything. I am using Windows 8.1 64-bit Pro, with MinGW 4.8.
I compile it with
g++ map.cpp -L. -lBearLibTerminal -o map.exe -static-libgcc -static-libstdc++
Could you please help me out?
-
Look if there is bearlibterminal.log being generated near your executable (or in the directory you run the program from); if there are issues with configuration string, the library will complain there. If the situation not becoming clearer, post the code sample with your terminal_set call, it will help diagnosing the problem.
-
Here's a paste of my code.
http://pastebin.com/NaWYrqNk
-
Now, this one was easy. Somehow documentation was missing the fact that before terminal_open no other library call will do anything, my bad.
So just swap open and set around.
-
Dead simple. Thanks! Also, on the topic of documentation, reading through the replies of this thread, I notice that certain tricks and interesting things aren't mentioned in the API reference. Things like the various tags that can be used in print functions and such. It'd be great if you could expand the documentation in that direction.
-
How well suited would BearLibTerminal be for developing a MUD?
EDIT: For example, the implementation of a scrollback buffer?
-
How well suited would BearLibTerminal be for developing a MUD? EDIT: For example, the implementation of a scrollback buffer?
Well, the library is built around a grid of cells, so there is no built-in scrolling buffer. But take a look at example #9 "formatted log" in SampleOmni. The library supports formatted output with wrapping and cropping, which should make implementing scrollable buffer easy.
I notice that certain tricks and interesting things aren't mentioned in the API reference. Things like the various tags that can be used in print functions and such. It'd be great if you could expand the documentation in that direction.
Somehow missed your post. Hm, string formatting is documented (see terminal_print (http://foo.wyrd.name/en:bearlibterminal:reference#print) function). I agree that less obvious features and techniques should be pointed out and explained, though.
-
Is there a bug in the Python binding, in color_from_argb?
I've tried to recreate the Basic Output sample, and the color-shifting has thrown me:
for i in range(long_word_len):
factor = i/long_word_len
red = (1 - factor) * 255
green = factor * 255
terminal.color(terminal.color_from_argb(255, red, green, 0))
terminal.put(2+n+i, 1, long_word[i])
results in a value of `4294901760.0` being sent to `_library.terminal_color()`, which results in a `ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type. I don't know much about bitwise operations, but does
def color_from_argb(a, r, g, b):
result = a
result = result * 256 + r
result = result * 256 + g
result = result * 256 + b
return result
return the same result as
TERMINAL_INLINE color_t color_from_argb(uint8_t a, uint8_t r, uint8_t g, uint8_t b)
{
return ((color_t)a << 24) | (r << 16) | (g << 8) | b;
}
?
Have I made a gross mistake in my for-loop?
Thanks either way! This library looks great, once I figure this out.
EDIT:
Fixed the problem! I changed the "return result" to be "return int(result)" so the program now runs, but it's displaying the colors differently than the provided compiled exe:
(http://i.imgur.com/wyD8lkp.png)
Left is provided exe, right is my Python test. Is one of them wrong? Is the sample code more recent than the sample exe? Either way, thanks!
-
In Python 2,
factor = i/long_word_len
sets factor = 0 each time. In Python 3, the same code sets factor equal to a floating point value each time. I assume you're using Python 3. Then
red = (1 - factor) * 255
green = factor * 255
sets red and green equal to floating-point values, which you pass into BLT's color_from_argb(), which returns a floating-point value. BLT's color() only accepts integer values.
Hopefully this should be fixable by just using int(red) and int(green) when calling BLT's color_from_argb().
-
I've been toying with this library for the past month or so and I have to say I'm really loving it. I'm using it to build a roguelike project, but it's also been my go-to whenever I need to write up a school project and don't want to deal with Curses. It's a shame I haven't seen more completed projects out there, considering how much time and love has obviously gone into the project.
Figured I would link something simple I made, hopefully to get the ball rolling a bit!
Conway's game of life, written in C.
https://github.com/SceptreData/cLife (https://github.com/SceptreData/cLife)
-
Running into a strange bug with png fonts. If I use set inside the program, I can set the font without any problems. However, if I use the equivalent config file, I get a message: [error] Failed to set some options: Tileset::Create: main value attribute is missing.
Weird thing is, all the other settings in the config file are read without problem and apply just as if I'd used set in the program. Only the font is a problem.
Otherwise, everything I need seems to be working quite fine.
Thanks again,
Brian aka Omnivore
PS: this is with the 0121 version, using 32 bit dll with Python v2.7.9 (32 bit) on Windows 8.1 (64 bit) platform.
-
If I use set inside the program, I can set the font without any problems. However, if I use the equivalent config file, I get a message: [error] Failed to set some options: Tileset::Create: main value attribute is missing.
Yep, there was a bug. Fix is already pushed to the repository (https://bitbucket.org/cfyzium/bearlibterminal) and I'll update binaries soon.
-
Nice :)
Is there any way to specify a path for the font/tile files? In an os independant manner? I'd like to stick them in a 'data' or 'resources' folder/subdir.
Thanks once again,
Brian aka Omnivore
-
Is there any way to specify a path for the font/tile files? In an os independant manner? I'd like to stick them in a 'data' or 'resources' folder/subdir.
Yes. 'SampleOmni' does exactly that, keeping media files in ../Media directory. You should use Unix path separators (forward slashes) and Windows version will replace them with backslashes when opening a file.
-
Nice work. Does BLT support building with VS2015?
-
Also I can't for the life of me get it to work on CLion/Cygwin. I'm fairly inexperienced with CMake, though.
-
Does BLT support building with VS2015? <...> Also I can't for the life of me get it to work on CLion/Cygwin. I'm fairly inexperienced with CMake, though.
I have not paid much attention to building the library with different compilers/IDEs. Yet.
The idea was that binaries are fairly compiler and language-independent and there is no significant need to rebuild frequently (or as a part of a bigger project, even), just use a suitable header/binding. Right now if you do not trust provided binaries (this is Internet, after all) you can build BearLibTerminal standalone way from a command line (or CMake GUI) and then use it as a regular third-party dynamic-link library. This way you'll only need a recent CMake and a sane MinGW with POSIX threading model, i recommend TDM-GCC (http://tdm-gcc.tdragon.net/) or mingw-builds (http://mingw-w64.org/doku.php/download/mingw-builds).
I said 'yet' because sooner or later I'll make sure it works with popular IDEs, I'd just like to finish some refactoring before that.
-
I must say that I tried this with both C# and Python and I really liked this. If I had the energy I'd rewrite the rendering of The Temple of Torment into this one surely :).
It was pretty hard to get started with it though, it required some experimentation, for example in getting multiple font files to work. It was mostly "hmm, lets see what happens if I do this", for the most part it worked as I expected though a good tutorial would have helped.
It would be pretty awesome if the RogueBasin's Python tutorial was modified by someone to use this for rendering and the libtcod would be used for the pathfinding and other utilities.
-
<...> in getting multiple font files to work. It was mostly "hmm, lets see what happens if I do this", for the most part it worked as I expected though a good tutorial would have helped.
This is one of the aspects I'm trying to fix =|.
While we are on this topic, I'll outline the things I'd like to address soon. Comments are welcome.
1. Multiple fonts seems to be useful (nice feature overall) but implementation is more of a hack around forward-backward codepage mapping. I plan to make fonts named so that one will be able to use a configuration like
font: UbuntuMono-R.ttf, size=12
bold font: UbuntuMono-B.ttf, size=12
icons font: Icons.ttf, size=14, spacing=2x1
And then
terminal_printf(x, y+0, "[font=bold]AARGH[/font]");
terminal_printf(x, y+1, "Requires 2 [font=icons]*[/font] and 3 [font=icons][U+2345][/font]");
There is also a 64k codepoints restriction. It would be nice to support full Unicode codepoint space, there are TrueType fonts with ranges beyond BMP.
2. There is one very internal thing. I've tried to make the library at least halfway thread-safe so as long as you do not call functions concurrently, which thread they are called from does not matter. This was achieved by running input and rendering from a separate hidden thread. However, on some platforms (e. g. OS X) you just cannot work with windows (i. e. input) from non-main thread and on some others (e .g. X11) things are not guaranteed to work reliably, though they usually does. This will not require to alter the API but some functions would be restricted to be run from the main thread (open/close, set, has_input, peek, read, read_str). You'll still be able to invoke all other functions (including refresh) from whatever thread. I just wonder how many people even thought about multi-threaded interface processing in terminal-like application >_< it's possible no one will even notice.
3. And after that, it would be possible to write some technique articles/examples as the feature/quirk set should hopefully be completed =_=.
-
It would be pretty awesome if the RogueBasin's Python tutorial was modified by someone to use this for rendering and the libtcod would be used for the pathfinding and other utilities.
I'm working on my own roguelike, and once I'm at a place I feel comfortable sharing, I'm going to iterate over it in a tutorial fashion, and then post it up on RogueBasin. Which is to say, give me a month! :-D
-
2. There is one very internal thing. I've tried to make the library at least halfway thread-safe so as long as you do not call functions concurrently, which thread they are called from does not matter. This was achieved by running input and rendering from a separate hidden thread. However, on some platforms (e. g. OS X) you just cannot work with windows (i. e. input) from non-main thread and on some others (e .g. X11) things are not guaranteed to work reliably, though they usually does. This will not require to alter the API but some functions would be restricted to be run from the main thread (open/close, set, has_input, peek, read, read_str). You'll still be able to invoke all other functions (including refresh) from whatever thread. I just wonder how many people even thought about multi-threaded interface processing in terminal-like application >_< it's possible no one will even notice.
Ah, this explains the delayed shutdown. I'd been wondering why the process sticks around for half a minute after the window closes.
Frankly, it's over-engineering, in my opinion. Most UI frameworks I've worked with in the past have required access through only the main thread for a variety of reasons. I suspect that anyone considering the use of multi-threading would expect that and be aware of the workarounds.
For a roguelike, I believe multithreading is overkill. I've run tests on some of the heaviest algorithms in use for roguelikes and they really don't benefit from parallelization (via multithreading or otherwise) at the present time. Context switch cost along with data exchange cost just destroys any performance gain. If someone is multithreading for other reasons, most languages today have some form of lightweight thread-like mechanism available that mostly alleviates the need.
The only case that immediately springs to mind where multithreading might conceivably be worth the headache would be in procedural generation of maps. Even then, it is quite possible to use lightweight mechanisms to emulate the desired behavior. In any case, I can't see any reason why such a background task would need to communicate with the UI.
As the adage goes, if you think you have a problem that will be solved by multiple threads, you now have two problems.
Just my 2c worth,
Brian aka Omnivore
-
Ah, this explains the delayed shutdown. I'd been wondering why the process sticks around for half a minute after the window closes.
Wait, what? The window with all its resources (thread included) should be completely released after terminal_close. Do you have some scenario reproducing this behavior?
Frankly, it's over-engineering, in my opinion.
Indeed it is, I just thought I would be able to cover a few more cases at some reasonable cost and it turned out the cost is big. As for parallelization, what I meant was more in the direction of rendering offload, when world processing (model) is done separately from drawing its state (view). There is even an example of it in this very thread (notostraca's test a few pages ago). It is fairly common approach in more complex games or visualization applications, not sure to which extent it applies to roguelikes. Probably some sandbox-style game with lots of actors (with their own task queues) would benefit from this.
Most of the tasks I can come up with to run in parallel do not interact with rendering/interface directly. As you mentioned, it's hard to parallelize efficiently usual algorithms so I'd offload something more high-level like chunked world generation for seamless travel or continuous processing of world objects while they are out of sight.
-
Ah, this explains the delayed shutdown. I'd been wondering why the process sticks around for half a minute after the window closes.
Wait, what? The window with all its resources (thread included) should be completely released after terminal_close. Do you have some scenario reproducing this behavior?
Windows 8.1, 64bit OS, 32bit Python 2.7.9, BearLibTerminal_0121 32bit dll, simple script just loading fonts, displaying a screen, and the normal event loop that falls through to close() after receiving TK_CLOSE event from read(). Script ends, nothing special after calling close(). The terminal window closes promptly, but process hangs around for around 30 seconds before returning to the command prompt.
Hope that helps,
Brian aka Omnivore
-
I have a small, but I believe important request. When setting the window size, IE. to 120x60, could you make it so that it doesn't create a [60][120] arrangement, but a [120][60] one, since it's more natural because of arrays. That is to say, you don't address column, then row, but rather row and then column as is the case with arrays.
Thanks!
-
LisacPisac, sorry but I don't understand what you're talking about. With simple put(x, y, c) and print(x, y, s) functions you can't even see if there is any underlying array, let alone how it is allocated. You can fill cells in any order you want.
-
Right, but what if I am using a standard array to store data about the map? The array uses a [row][column] format, where as the terminal itself uses a [column][row] format. And so, if I am to translate data from the array into the terminal in the right order, using two for loops using counters 'i' and 'j', I address my array as array[j]. Which is counter intuitive.
Okay, granted, perhaps I am doing something TERRIBLY WRONG and don't realise :P
-
There's no fundamental reason, for a rogue-like, to use row, column format storage arrays. Your data accesses will tend to be rectangular - changing in both x and y so there's no real speed or cache difference between x, y and y, x formats. If it is causing you problems, switch your storage array to use a [column][row] format.
More and more these days, I don't even use arrays for map data storage. I suspect I'm not alone. Hash maps, sets, and simple lists using immutable coordinate keys and object ids are a solid alternative. Particularly with layered output, the 'map' never exists as a singular entity until it hits the screen.
Hope this helps,
Brian aka Omnivore - and Happy Holidays to all :)
-
OK, Terminal.PutExt is just awesome.
I wonder if anyone using corner-coloring in put_ext. I hope no one is. It does not work uniformly (with final result depending strongly on particular hardware, ugh) and restricts some possible optimizations, so I plan to remove it.
Is this still going to happen? I wouldn't miss the corner-colouring feature at all, because its main effect is to make me use an array of four copies of a single colour whenever I use put_ext. A single colour argument would be much preferable.
-
its main effect is to make me use an array of four copies of a single colour whenever I use put_ext. A single colour argument would be much preferable.
But you can pass NULL there to use the current foreground color...
-
When drawing tile maps, I prefer to specify each tile's colour in the call to put_ext. It just feels neater (even with the weird requirement to make an array of colours). I would do the same with layer if it was an optional parameter in put_ext.
Leaving the foreground colour alone also means I don't have to worry about accidentally drawing strings in the wrong colour (as old versions of DoomRL, NPPAngband(?), et al did). Colour as a global persistent state variable just feels like an unnecessary legacy from ncurses.
-
When I said remove I meant for good. Output attributes as non-persistent parameters is understandable idea and helps performance (about 30% actually). But there are several attributes: foreground and background colors, layer index and replace/combine 'composition' flag. Adding everything to the function looks clunky, put_ext then will have nine arguments! But leaving one or two of them will look inconsistent. Why only foreground color? Why there is no such color argument in the regular put then? I don't see a clear solution for this.
Personally I'd just wrap it in the two-line function. This won't help with miscoloring but that itself is arguable as it's better to always set every relevant state before a logically separate action.
-
Not sure the complexity it worth it as it can just as easily be done in user code, but... you could define a state structure and, to avoid headaches in passing structures back and forth- add a set of state management functions. create_state, select_state as a minimum. Then the user would create a state for a given type of operation and select that state during the op. Could have select_state return the current 'old' state, then the user could just swap contexts. Its similar to how GDI in Windows is managed in some frameworks. Each state would hold everything except the character/symbol information.
From my perspective, I'm just as happy to roll my own user side state management - if I need it.
Hope this helps,
Brian aka Omnivore
PS: Could go as far as: put_ext(x, y, char, state_token); the create_state call could copy the current state so the user would only change what differs in the new state. Sounds simple, I'm probably overlooking something!
-
Here we go, version number thirteen, codenamed "better late than never". OS X is supported now.
As it was mentioned before, OS X support necessitated some changes so library is now single-threaded and must be used from the main thread only. I do have a solution to make drawing possible to be used from another thread (nope, not a global lock :-)), but it will introduce slight overhead in library operation and I am not sure if this feature even needed. Most of the time the code can be easily pseudo-parallelized anyway. For now, attempt to call some key functions from a non-main thread will result in window closing (mostly correctly though abruptly) and a relevant message in the log.
Windows (http://foo.wyrd.name/_media/en:bearlibterminal:bearlibterminal_0132.zip) and Linux (http://foo.wyrd.name/_media/en:bearlibterminal:bearlibterminal_0132.tar.bz2) versions do not change much (aside from threading) and OS X (http://foo.wyrd.name/_media/en:bearlibterminal:bearlibterminal_0132_osx.zip) version archive includes a dylib with library_name=@executable_path and an awkward SampleOmni.app bundle.
Next is full unicode codespace and a sane additional font management.
-
It's great that BLT games can be run on OSX now. Thanks for all your hard work.
I've found a few issues while testing it on an OSX virtualbox:
* PyBearLibTerminal.py hasn't been updated to find the .dylib file.
* Keyboard input pages in SampleOmni is quite strange - it seems to read several keys (arrows, shift, w, a?) as being held down. This could be due to problems in virtualbox, though.
* In the previous version, I remember mouse events being passed to read() by default. Either this default has changed or mouse input doesn't work (but this could be virtualbox)
* While experimenting in the Python repl, I was able to read the correct value from state(TK_SHIFT). However, state(TK_CONTROL) was always 0, whether I held down the control key or the windows/apple key. Again, it might be due to problems in virtualbox. However, it does raise the issue of how BLT should respond to the apple key. I see that the windows and alt keys are ignored by design - on OSX, it might make more sense to ignore the control and alt keys.
-
* PyBearLibTerminal.py hasn't been updated to find the .dylib file
Whoops. Fixed than for Python and Ruby wrappers.
I'm thinking about making a pip package for python, one that will include library binary as well. Did you know that not long ago they made it possible to include linux binaries in python wheels? What I'm not sure about is what package-module structure to use. Namespaced packages which would allow "from bearlib import terminal" (leaving a chance to add another BearLibSomething, particularly map generation) are cool but reported to be fragile (pip issue #3 (https://github.com/pypa/pip/issues/3) -- does this matter? I do not use Python enough to be sure). The other choice is 'from bearlibterminal import terminal' which is just a bit clunky.
* In the previous version, I remember mouse events being passed to read() by default. Either this default has changed or mouse input doesn't work (but this could be virtualbox)
Yeah, I went and changed the defaults which was a bit hasty and wasn't even mentioned, sorry; reverted, reuploaded, 0.13.1. I do think input filter should have a default value, though. A lot of the time you need keypresses only and filtering everything out makes input logic cleaner in simple cases (e. g. sketching or beginners' programs).
* Keyboard input pages in SampleOmni is quite strange - it seems to read several keys (arrows, shift, w, a?) as being held down. This could be due to problems in virtualbox, though.
* While experimenting in the Python repl, I was able to read the correct value from state(TK_SHIFT). However, state(TK_CONTROL) was always 0, whether I held down the control key or the windows/apple key.
Please check the fixed version; at the very least, SampleOmni might've looked like some keys have been stuck because it wasn't getting keyup events. I do not see any problems with keyboard input in my VMWare virtual machine though (even reading the state of Ctrl from Python), will try to run on a real Mac.
However, it does raise the issue of how BLT should respond to the apple key. I see that the windows and alt keys are ignored by design - on OSX, it might make more sense to ignore the control and alt keys.
It does look like the library should provide Cmd key access as it is seems to be what Ctrl is to Windows. I do not think ignoring Ctrl is correct though, it will make porting apps harder.
Also, Omnivore, are you here? I've meant my response on bitbucket as an invitation to discussion. Can you provide some examples of what are trying to do? Maybe there are even some conventions about keys and shortcuts in cross-platform applications on Mac?
-
I always use "import PyBearLibTerminal as blt", which lets me write things like blt.put_ext() clearly and quickly. I'm not sure what the benefits of that pull request (https://bitbucket.org/cfyzium/bearlibterminal/pull-requests/3/updated-python-bindings-to-match-other/diff) are supposed to be. A pip package would be wonderful, no matter whether the names are global or not.
I'm not too bothered about whether mouse events are included in the default filter or not, as long as it's easy to change.
It takes a few hours for virtualbox to log in, but if no-one tries it on a real mac soon, I'll test 0.13.1's keyboard input.
As far as I know the standard for shortcut keys on cross-platform applications is to use Command in place of Control in all cases. Exceptions are either quick-and-dirty ports of linux apps, or terminal applications for which shortcuts using the Command key are sent to the terminal rather than the application.
-
One disadvantage to the new single-threaded architecture: I often develop interactively (using the Python REPL or IPython (https://ipython.org/)). When I leave the window open without regularly calling read(), Windows greys out the BLT window and marks it as not responding. I guess this is unavoidable?
-
When I leave the window open without regularly calling read(), Windows greys out the BLT window and marks it as not responding. I guess this is unavoidable?
Fortunately, it is fixable. Though there nothing can be done about necessity to call some methods regularly (event polling), the problem can be worked around with a bit of support from the interactive shell. Python conveniently provides a hook for polling GUI during it's interactive input. I've updated the Python wrapper adding such hook, it relies on ipython package being installed.
I've also found and fixed a bug in the Windows' event polling code which could cause the library to hang (running through the hook increased the chances enough to notice that). Please download the next 0.13.2 version.
-
I'm using 0.13.2, and I've checked that the relevant line has run, but the window's behaviour in IPython hasn't changed.
-
Hmm, that's strange. Does shell stay responsive when the window is grayed out?
Actually, how do you use it?
$ ipython
<...>
In [1]: import PyBearLibTerminal as T
In [2]: T.open()
Out[2]: True
In [3]: T.refresh()
Out[3]: 1
In [4]:
This would be the minimal test case. You don't even need ipython shell, this works in regular python interactive shell as well (the hook itself is Python feature, ipython dependency is for convenient IPython.lib.inputhook module).
I get consistent results on a wide variety of platforms: Windows XP, Windows 7, Ubuntu, OS X (WMVare), 32 bit and 64 bit, Python 2.7 and 3.5 (this looked fairly platform-specific so I checked a lot of them but behavior is almost identical) and everything matches the documentation (http://ipython.readthedocs.org/en/stable/config/eventloops.html?highlight=Integrating%20with%20GUI%20event%20loops) well.
-
Sorry, I should have been clear that I was talking about IPython notebook. I just tried the minimal test case in the Python and IPython consoles, and it works as intended (though I now have to call close() to get a clean exit).
In IPython notebook, the same code leaves the BLT window unresponsive.
-
There you go: PyBearLibTerminal.py (https://bitbucket.org/cfyzium/bearlibterminal/src/f14cd7e885c2aa21dc5f927b5b9c0d425c7b7300/Terminal/Include/Python/PyBearLibTerminal.py?at=default&fileviewer=file-view-default) (relevant diff (https://bitbucket.org/cfyzium/bearlibterminal/commits/695f481c777de9683b93df3a13fa323bbb96d89f?at=default)). You need to manually enable integration by "%gui blt" command in ipython notebook.
Cute how all this very environment-specific machinery added to the wrapper introduces literally zero overhead unless actually run from an interactive shell or notebook.
-
Perfect. Thanks so much!
Here's a BearLibTerminal sandwich for you:
(http://joesdining.com/wp-content/uploads/2012/05/BLT-Sandwich.jpg)
-
BearLibTerminal is really nice! I was looking for a long time for a way to make roguelikes in TrueType fonts, so I am glad I found it!
I learned a lot from Jotaf's libtcod python tutorial, and to educate myself on BLT, I modified the tutorial game for BLT display. It was suggested here before, but I don't know, whether anybody did this already...
Anyway, if someone is interested, here is the download link for the source code .py file and the Win32 package for running the game by an executable.
https://sites.google.com/site/iolx3home/TOMBS_BLT.rar?attredirects=0&d=1 (https://sites.google.com/site/iolx3home/TOMBS_BLT.rar?attredirects=0&d=1)
I hope this helps someone, at least it was great fun for me. It is not at all perfect code, but it should give ideas. I will consider BLT for sure in future projects.
However, quick comment: It would be really great to have background (or transparent flag when needed) on additional layers. Libtcod consoles are a little easier here (menu covers the screen below).
-
However, quick comment: It would be really great to have background (or transparent flag when needed) on additional layers. Libtcod consoles are a little easier here (menu covers the screen below).
One way to simulate background above layer 0 is to use the unicode block drawing characters, in particular the full block (http://www.fileformat.info/info/unicode/char/2588/index.htm). This fails if the font size doesn't match the cell size, so you might prefer to use a plain white tile from a spritesheet instead. You can use alternate layers for foreground tiles and background blocks, or just turn on composition and put them on the same layer.
-
Hi,
just discovered BearLibTerminal. looks great ! :D
is there Lua use documentation or a small example somewhere..?
Thanks.
ffred
[Edit:]
sorry, first post here and already replying to myself..
after a few tests, here is my simple Lua "Hello World". (but of course, if someone got a link to doc or bigger example, still interested)
local T = require "BearLibTerminal"
T.open()
T.print(2, 1, "Hello, world!")
T.refresh()
T.read()
-
It would be really great to have background (or transparent flag when needed) on additional layers.
One way to simulate background above layer 0 is to use the unicode block drawing characters, in particular the full block.
Using special characters is more or less the right way. Cell background color is a very basic feature and if you are doing something advanced like floating menus and windows, you may as well use more versatile 'tools'. Like this (Python source (http://pastebin.com/fVWfTicT)):
(http://foo.wyrd.name/_media/wiki:bearlib:advanced-window.png)
Btw, there is a bug (half of it is in the library, another half is was in the Python wrapper; I wonder when they will stop appearing) preventing put() from working with non-ascii characters like 0x2588. Please get the fixed PyBearLibTerminal.py (https://bitbucket.org/cfyzium/bearlibterminal/src/2488e95f9ce3265d17d10b87240ccf92a9f95f3d/Terminal/Include/Python/PyBearLibTerminal.py?at=default&fileviewer=file-view-default) from repository.
This fails if the font size doesn't match the cell size
Good catch. Looks like library should generate these characters for cell size, not for the font size. Can't think of a situation one will need Box Drawing / Block Elements symbols not matching the size of a cell.
Edit: this case still won't work with bitmap fonts that provide their own borders/blocks symbols (e. g. Dwarf Fortress (http://dwarffortresswiki.org/Tileset_repository) fonts) since handpicked bitmap tiles have priority over auto-generated ones.
is there Lua use documentation or a small example somewhere..?
Reference documentation (http://foo.wyrd.name/en:bearlibterminal:reference) is virtually the same for all languages, just function/const names change slightly, e. g. terminal_state(TK_SHIFT) vs BLT.state(BLT.TK_SHIFT). So all examples (e. g. C++ ones (https://bitbucket.org/cfyzium/bearlibterminal/src/f14cd7e885c2aa21dc5f927b5b9c0d425c7b7300/Samples/Omni/Source/?at=default)) should translate from one language to another fairly easily. Sadly there are no proper language-specific tutorials yet.
-
ok, thanks..
-
Also, Omnivore, are you here? I've meant my response on bitbucket as an invitation to discussion. Can you provide some examples of what are trying to do? Maybe there are even some conventions about keys and shortcuts in cross-platform applications on Mac?
Oops, I seem to have missed this earlier.
I simply do not believe an I/O library should be making UI decisions for me. How any particular OS or GUI implementation handles ALT keys is really not the point. Fact is, no other I/O library that I have used or can remember examining discards ALT key presses and ALT key state. Also, IIRC, your response on bitbucket indicated you were going to embed certain alt-key presses in the lib for uses such as full-screen switch. I am totally opposed to hard-wired UI behaviors in an I/O library.
It is, of course, your library, however given your response to the bitbucket issue I raised and my disagreement with your stated intentions, I've moved on to other solutions. There was one other issue I was going to raise that I consider equal in importance to the ALT key handling, but have not raised it previously since I've moved on. I'll raise it below just in case other users may find it of interest.
The other issue is that I desire a solution that is compatible with either or both resource streams and PhysicsFS https://icculus.org/physfs/ (https://icculus.org/physfs/) type file systems. Both of these solutions allow single file binary distributions of both DLLs and media as part of an executable or plugin. The major change to BearLibTerminal would be to allow loading of media as byte buffers as an alternative to files. A minor change might be required for some wrappers in order to allow dynamic loading of the BearLibTerminal DLL itself.
I would still recommend BearLibTerminal to anyone who doesn't desire ALT-key handling and/or no install, single file, distributions.
Hope this helps,
Brian aka Omnivore
-
Whoa. Do I sound that firm in my argumentation? >_<
Just a bit more about my point of view: I feel that as a pseudo-terminal library, BearLibTerminal may behave a bit like other real terminal windows, e. g. gnome-terminal or PuTTY which handle or ignore a lot by themselves and no one find that strange, e. g. zooming, clipboard, etc. Or Alt+Enter toggling fullscreen which is a very common combination that does exactly the same thing everywhere it is implemented, so why not enable it by default? Strict comparison with other I/O libraries is not fair since those libraries are general-purpose, while here I trying to be a bit specific in scope.
That said, wouldn't everything be OK if BearLibTerminal had these UI shortcuts simply enabled by default with an option to disable them? Like "input.alt-functions=false" and then you are on your own with that key? All these shortcuts are just conveniences, not a core feature. My previous questions (what are you doing and why) were to find out if there is something that might be better accounted for or integrated into these library tricks. If what you need is some 'raw access', then why not?
Support for streamed/archived resources is something I lazily thought of (mostly because no one voiced it before) but there is some support already as BearLibTerminal can load images from in-memory buffers (look at relevant line in the sample (https://bitbucket.org/cfyzium/bearlibterminal/src/2488e95f9ce3265d17d10b87240ccf92a9f95f3d/Samples/Omni/Source/DynamicSprites.cpp?at=default&fileviewer=file-view-default#DynamicSprites.cpp-117)). This is not complete: you cannot load TrueType fonts or text files (codepages) from memory =/. It would be nice to make possible to load resources from streams but I just cannot figure out how API for that should look like.
With all due respect, sir, I accuse you in being silent.
-
With all due respect, sir, I accuse you in being silent.
Guilty through pessimism, my apologies.
That said, wouldn't everything be OK if BearLibTerminal had these UI shortcuts simply enabled by default with an option to disable them? Like "input.alt-functions=false" and then you are on your own with that key? All these shortcuts are just conveniences, not a core feature. My previous questions (what are you doing and why) were to find out if there is something that might be better accounted for or integrated into these library tricks. If what you need is some 'raw access', then why not?
Yes that would work. Best would be if the default mapped functions could be accessed individually when the "input.alt-functions=false". In other words, rather than alt-enter (assumed default) switching full-screen, the same switch could be accessed via a menu in the application's UI.
An example of a custom mapping might be: CTRL-(1-9) sets a 'recall' position, ALT-(1-9) teleports to that position. Another might be a plugin that enables some plugin-defined behavior with a multiple SHIFT-ALT-(some key) sequence, or a user remapping of keybindings. Also, in a left-hand on keyboard, right-hand on mouse setup, the ALT-key is, at least on some keyboards, adjacent to the spacebar and easily thumb-accessible while other fingers are on 'main' keys (qwer-asdf-zxcv). In games (example ASCII-Sector) which combine both turn-based and real-time play (depending on mode), the difference between easy to reach ALT and (relatively) hard to reach CTRL may be significant.
If some mode allows ALT key both as key press and key modifier to be accessed then such custom mappings can easily be accomplished. ALT key as modifier being the most important for general use I believe. Would there be any harm in allowing ALT key as key press/key modifier even when input.alt-functions=true ?
Support for streamed/archived resources is something I lazily thought of (mostly because no one voiced it before) but there is some support already as BearLibTerminal can load images from in-memory buffers (look at relevant line in the sample (https://bitbucket.org/cfyzium/bearlibterminal/src/2488e95f9ce3265d17d10b87240ccf92a9f95f3d/Samples/Omni/Source/DynamicSprites.cpp?at=default&fileviewer=file-view-default#DynamicSprites.cpp-117)). This is not complete: you cannot load TrueType fonts or text files (codepages) from memory =/. It would be nice to make possible to load resources from streams but I just cannot figure out how API for that should look like.
Oops, I missed that usage of terminal_setf. If I'm reading that sample correctly, then loading from stream to memory and then making the terminal_setf call would handle most reasonably sized bitmap files assuming the pixels are in the correct color format. Does that call result in the lib making an internal copy of the passed data, or does the application need to hold that data in memory after the call?
For TTF, there is a version of the FT_New_Memory_Face call that accepts a memory buffer address, so that may give an alternative entry point. Not sure about the code page text files although, given that they are likely to be a small file, a kludge fix might be to copy to a temp file and load that. Of course the same kludge could be done with TTF fonts.
For streams, yeah the interface would be a problem, especially given the multiple language mappings. Frankly I'd be happy with just using memory buffers as long as the expected format of the byte buffer and call are well defined. It would also be preferable I think if the lib made a copy of the passed buffers so that the caller could discard the buffer after the call to terminal_setf.
I'll try to be less silent in the future, maybe a bit more optimistic :)
Thanks,
Brian aka Omnivore
-
Best would be if the default mapped functions could be accessed individually when the "input.alt-functions=false". In other words, rather than alt-enter (assumed default) switching full-screen, the same switch could be accessed via a menu in the application's UI.
Yes. Actually, while you cannot disable Alt+Enter in the current build, you still can manually set "window.fullscreen" option and inspect the current TK_FULLSCREEN state from the code.
Would there be any harm in allowing ALT key as key press/key modifier even when input.alt-functions=true ?
Can't think of anything 'harmful' but that will leave things a bit fragile. A simple example would be zooming which is commonly bound to plus(in)/minus(out)/zero(reset) so default shortcut will overlap with hypothetical Alt+0 'teleport to position' command.
Does that call result in the lib making an internal copy of the passed data, or does the application need to hold that data in memory after the call?
Yes, a copy is made. Memory is not precious enough to make user juggle with buffers lifetimes =).
As you can see, not much of in-memory loading is supported right now, only raw BGRA bitmaps. It was more like a proof-of-concept for low-level library API (you can pass a System.Drawing.Bitmap object into Terminal.Set function in C#, a table of pixels in Lua, etc. =_=). Looks like I'll have to expand this functionality soon.
-
Would there be any harm in allowing ALT key as key press/key modifier even when input.alt-functions=true ?
Can't think of anything 'harmful' but that will leave things a bit fragile. A simple example would be zooming which is commonly bound to plus(in)/minus(out)/zero(reset) so default shortcut will overlap with hypothetical Alt+0 'teleport to position' command.
Wouldn't any custom CTRL-[0=-] bindings also make CTRL fragile in this case?
[EDIT] Assuming the zoom functions were bound to unmodified [+-0], obviously CTRL bindings are non-fragile if zoom is ALT-[+-0].[/EDIT]
I know its popular these days to protect programmers from themselves, but given good documentation, overlapping a non-disabled default binding with a custom binding would, to me, be programmer error on the part of the library user.
Does that call result in the lib making an internal copy of the passed data, or does the application need to hold that data in memory after the call?
Yes, a copy is made. Memory is not precious enough to make user juggle with buffers lifetimes =).
As you can see, not much of in-memory loading is supported right now, only raw BGRA bitmaps. It was more like a proof-of-concept for low-level library API (you can pass a System.Drawing.Bitmap object into Terminal.Set function in C#, a table of pixels in Lua, etc. =_=). Looks like I'll have to expand this functionality soon.
Personally, for purposes of loading bitmap data, raw BGRA format is fine. If necessary can always do format conversions either pre-build or inline in the source language of the app. For TTF, most languages should provide some method of loading a binary file as a byte array which could then be passed with no format changes. I'm unsure of what would be required for CP files.
Since you already have the capability for raw bitmap data loading, I don't know if I'd consider the addition of the TTF/CP/other bitmap format handling to be a high priority. It is always possible to use the kludge of copying to temp file as an interim workaround in the app language source. Of course, that depends upon the usage patterns, where for my needs seem to be perhaps a half dozen to a dozen bitmap files, one TTF file, and at most one CP file. Not sure if that is typical.
In any case, thanks :)
Brian aka Omnivore
-
An update. Say, 0.14 (http://foo.wyrd.name/en:bearlibterminal#download) (these numbers were mostly arbitrary right from the start).
1. Alt key issue should have been resolved. I've added the TK_ALT keycode with corresponding input event and state always available. By default the library will intercept some key combinations, but this can be turned off with 'input.alt-functions' option.
2. Resource loading has been cleaned up a bit. Now anything can be loaded from a memory buffer by specifying <address>:<size> pair instead of a filename, like this:
terminal_setf("font: %p:%d, size=8x16, codepage=437", buffer, size);
terminal_setf("0xE000: %p:%d, raw-size=%dx%d", pixels, W*H*4, W, H);
Because consistency. Also why decode embedded images to pixels when library can do that already.
Note that 'raw-size' is a required option for raw bitmaps now, since library need to know that is is not a file somehow. More or less documented (http://foo.wyrd.name/en:bearlibterminal:reference:configuration#font_and_tileset_management).
3. Extra fonts management looks decent at last. Extra/alternative fonts is when you can use additional styles alongside the main one, like italic for emphasis or some ornate square one for menu.
It should be very straightforward now:
terminal_set("font: UbuntuMono-R.ttf, size=12");
terminal_set("italic font: UbuntuMono-I.ttf, size=12");
terminal_print(2, 1, "Its eyes are [font=italic]glowing[/font].");
-
Hey,
I'm trying to add BearLibTerminal to PyCharm in Linux, but I'm not meeting much success. I'm not even sure how to get the system to use the shared object (if python even uses it?). I get this error:
"RuntimeError: BearLibTerminal library cannot be loaded."
Do you have any advice on what I should do?
PS: Honestly, it'd be great if you could create a pip package that we could easily install.
-
This happens because libBearLibTerminal.so is not in the place the wrapper looks in. With default PyBearLibTerminal.py wrapper, the library binary may be either in default system path, or in the same directory as wrapper. The easiest way to fix that is to copy the .so to the source directory. If you want to have it somewhere else (e. g. /src and /bin separate) then you may add a new path directly to the wrapper (_possible_library_names variable).
Indeed, pip package should fix that as the binary (installed with the package) will have a well defined location. I'm working on that.
Why does PyCharm show members starting from _ in its intellisense? Aren't they considered hidden by convention?
-
The __ members are useful meta variables that have their place in the python langauge and are supposed to be used, as they add new options to developers.
-
pip install bearlibterminal
Another step to enlightenment. Works (or should work) on Windows and Linux, 32 and 64 bit. OS X package is not built yet, my virtual machine with OS X is such a pain.
Use it like this:
from bearlibterminal import terminal
The __ members are useful meta variables that have their place in the python langauge
I was talking about single-underscored members of a module. Like terminal._library which should be considered internal:
(http://i.imgur.com/EyhGx2S.png)
-
pip install bearlibterminal
Another step to enlightenment. Works (or should work) on Windows and Linux, 32 and 64 bit. OS X package is not built yet, my virtual machine with OS X is such a pain.
Use it like this:
from bearlibterminal import terminal
Yes! Excellent. That makes distribution without py2exe much easier.
Edit: Actually, the command isn't working for me (Windows, 32-bit Python 3.4.2):
Downloading/unpacking bearlibterminal
Could not find any downloads that satisfy the requirement bearlibterminal
Cleaning up...
No distributions at all found for bearlibterminal
Storing debug log for failure in C:\Users\***\pip\pip.log
I just installed coverage without issue, so it's probably not a problem with pip.
Further info:
------------------------------------------------------------
C:\Python34\Scripts\pip run on 07/07/16 10:19:47
Downloading/unpacking bearlibterminal
Getting page https://pypi.python.org/simple/bearlibterminal/
URLs to search for versions for bearlibterminal:
* https://pypi.python.org/simple/bearlibterminal/
Analyzing links from page https://pypi.python.org/simple/bearlibterminal/
Skipping https://pypi.python.org/packages/41/b4/d6a4adbc6e55a6de2da4a19ecde5754b2751afb0a2343b27825bcff8b263/bearlibterminal-0.14.1-py2.py3-none-manylinux1_x86_64.whl#md5=b13677b4d7684c647f0cc6ac6edb8826 (from https://pypi.python.org/simple/bearlibterminal/) because it is not compatible with this Python
Skipping https://pypi.python.org/packages/92/6c/31ba239c46aed3f9646aa5933b34c248518bf81ac849a008d9130b9f45bd/bearlibterminal-0.14.1-py2.py3-none-win_amd64.whl#md5=39041b4b091a07506796a024db280a47 (from https://pypi.python.org/simple/bearlibterminal/) because it is not compatible with this Python
Skipping https://pypi.python.org/packages/b3/68/42e384a8aaaa947444860a14e72c631c307c03b021ae2f28ed81a07d88bf/bearlibterminal-0.14.1-py2.py3-none-win32.whl#md5=5751a886a02ed66ccff8dde7167dfc2f (from https://pypi.python.org/simple/bearlibterminal/) because it is not compatible with this Python
Skipping https://pypi.python.org/packages/e3/a5/ecdffa53ddea705c0e5300cec3d156d66eef7f7a3a352223adcf62c887b5/bearlibterminal-0.14.1-py2.py3-none-manylinux1_i686.whl#md5=5882658e846bfbd5d3cc32a5a1862da1 (from https://pypi.python.org/simple/bearlibterminal/) because it is not compatible with this Python
Could not find any downloads that satisfy the requirement bearlibterminal
Cleaning up...
Removing temporary dir C:\Users\***\AppData\Local\Temp\pip_build_***...
No distributions at all found for bearlibterminal
Exception information:
Traceback (most recent call last):
File "C:\Python34\lib\site-packages\pip\basecommand.py", line 122, in main
status = self.run(options, args)
File "C:\Python34\lib\site-packages\pip\commands\install.py", line 278, in run
requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
File "C:\Python34\lib\site-packages\pip\req.py", line 1177, in prepare_files
url = finder.find_requirement(req_to_install, upgrade=self.upgrade)
File "C:\Python34\lib\site-packages\pip\index.py", line 277, in find_requirement
raise DistributionNotFound('No distributions at all found for %s' % req)
pip.exceptions.DistributionNotFound: No distributions at all found for bearlibterminal
It looks like "https://pypi.python.org/packages/b3/68/42e384a8aaaa947444860a14e72c631c307c03b021ae2f28ed81a07d88bf/bearlibterminal-0.14.1-py2.py3-none-win32.whl#md5=5751a886a02ed66ccff8dde7167dfc2f" should have been identified as compatible with my python version.
-
Looks like your Python somehow does not accept a fairly generic 'py3-none-win32' tag. Can you show me what does it print for:
import pip
print(pip.pep425tags.get_supported())
-
[('cp34', 'none', 'win32'), ('cp34', 'none', 'any'), ('cp3', 'none', 'any'), ('cp33', 'none', 'any'),
('cp32', 'none', 'any'), ('cp31', 'none', 'any'), ('cp30', 'none', 'any'), ('py34', 'none', 'any'),
('py3', 'none', 'any'), ('py33', 'none', 'any'), ('py32', 'none', 'any'), ('py31', 'none', 'any'),
('py30', 'none', 'any')]
-
Edited out.
-
From the current pip code (here (https://github.com/pypa/pip/blob/master/pip/pep425tags.py#L330)) it looks like pip must list py3-none-win32 as supported. Is your pip outdated by any chance? There was a relevant bug two years ago (https://github.com/pypa/pip/issues/1850).
-
Updating pip fixed the problem. Thanks!
-
Been working on a project using your terminal. Everything works great, except one little thing. I think it's due to the way I've written my code. When I run my game, the BearLib Terminal window pops up blank, and stays blank until there is some kind of input.
The basic structure of my code is:
brlb.open()
brlb.set('window.title={d}; font: roguelike_font.ttf, size=12; window.size={w}x{h};').format(d=self.dungeon.name, w=self.screen_x, h=self.screen_y))
brlb.refresh()
closed = False
while closed == False:
brlb.refresh()
if brlb.has_input():
closed = self.on_move_events() #handles input, updates screen, and returns True if the window should be closed
Am I doing something in the wrong order here that is causing that to happen? Not a huge annoyance, as the game appears as soon as you move your mouse, but I would like to fix it. Thanks again for making an awesome API!
-
self.on_move_events() is the only function in that code that draws on the terminal, it isn't called until brlb.has_input() returns True. To fix this you should call your screen update function before the first time brlb.refresh() is called.
-
As Quendus has pointed out, it is a matter of instructions order.
You can probably simplify the logic a bit by inverting the process of reading and drawing, i. e. if some function would render current state first, then wait for input and process it:
def process_everything():
self.on_draw()
brlb.refresh()
return self.on_input()
while not self.process_everything():
pass
Note that if you do not have animations, you do not really need to redraw when there is no input. As long as library is waiting internally (e. g. read or delay), it will refresh the screen itself if necessary.
-
A little bird told me on Reddit that BearLib has a Lua wrapper built in.
Is it true? Are there any tutorials on how to use it?
I'm looking to move my Lua game to some other display library (without changing the language) and I'm torn between this and libtcod. Which is easier to set up and get going?
-
I really thought I've already written some instructions already, but cannot find it now =|. Using the library with Lua should be really simple: en:bearlibterminal:using:lua (http://foo.wyrd.name/en:bearlibterminal:using:lua). Essentialy, you just have to place the binary near the main script and load the module with 'require'.
Only I somehow missed Lua 5.3 which has a slightly different binary interface and therefore not compatible with the current BearLibTerminal binaries. I'll fix that shortly.
-
Thanks for the speedy fix.
The documentation is top-notch and I already have figured out how to print tiles and text to screen.
I have a problem with an input loop, however. All the examples are in C and I am still bad at loops :(
Can anyone help?
-
I really thought I've already written some instructions already, but cannot find it now =|. Using the library with Lua should be really simple: en:bearlibterminal:using:lua (http://foo.wyrd.name/en:bearlibterminal:using:lua). Essentialy, you just have to place the binary near the main script and load the module with 'require'.
Only I somehow missed Lua 5.3 which has a slightly different binary interface and therefore not compatible with the current BearLibTerminal binaries. I'll fix that shortly.
If you've added that "using lua" section, maybe you should link it somewhere from the API reference, because it seems to me that, even if the articles exists somewhere, they are unreachable apat from guessing links. Parts of the documentation have been lying dormant for a while now.
@Zireael
make a while loop that takes input from the keyboard. Ala
while (key != terminal.TK_Q)
key = terminal.read()
if key == terminal.TK_KP_4
// Something, etc
-
I have a problem with an input loop, however. All the examples are in C and I am still bad at loops :( Can anyone help?
I'll help of course. Though there is so many use-cases and so many ways to implement them that I do not think there is some universal example. Better if you share what input logic you're trying to use: simple read and execute, continuous redrawing or something else.
LisacPisac gave one example, though I would have probably wrote it in a do-while way:
repeat
key = terminal.read()
if key == terminal.TK_KP_4 then
-- do smth
end
until (key == terminal.TK_Q)
If you've added that "using lua" section, maybe you should link it somewhere from the API reference, because it seems to me that, even if the articles exists somewhere, they are unreachable apat from guessing links. Parts of the documentation have been lying dormant for a while now.
It is on of its kind, the first article in the 'using' series and the only unreachable one >_<. I'll make the necessary links.
-
I was looking at the source code for Omni or whatever the example is, and trying to figure out how you navigate between the screens, and how you move the viewport in the minimap example.
All I see is some sort of while proceed= true do stuff loop followed by terminal.close()
And from what I see, every screen is a separate function, and every one of those has some sort of a input handling function.
Once I have the input working, I could get the game going, but without input all I have is a static screen.
-
Oh damn. Sample program had way more complex input loops than necessary. Try to look at the newly committed ones.
The reason for this is before introducing input filtering read() function was returning all input events: presses, releases, mouse movement. Especially mouse was a problem. The library uses vsync (by default, may be turned off) which is generally a good thing but limits refresh rate to something around 60 fps. With mouse movement it is rather easy to wave mouse around (and register corresponding events) faster than 60 text cells per second. This means that if you read input and redraw the screen after every read, then output will not keep up with input and there will be a noticeable lag. To work around that previous input loops were reading all available/buffered input every 'frame', hence the loop inside the loop.
You can see the same two-loop flow structure is still used in the mouse-specific samples ('mouse' and 'input filtering'). No real way around it, turning vsync off is not a decent solution because that would mean just meaninglessly redrawing/updating the screen.
Another case is animations. For example 'Extended ...' samples produce an animated output so they cannot hang on read() until some input available. They loop continuously, check for input availability via has_input() and call read() only when there is some.
You do not need all that in a simple case. As long as you have neither mouse nor animation, just a simple do-while loop should do. By default read() function returns only key presses so it pretty safe to update after every read.
I might take that even further. One of the possible future features is animated tiles. If those are implemented, even simple animations (like when monsters/torches/etc have a few frames of animation played continuously and synchronously) would not require any fancy input handling.
-
Thanks for that simplifying update, Cfyz!
Mouse support is in the cards, but for now I will focus on getting the basics going. I spent most of today grappling with my Lua libraries and then trying to figure out how to implement classes in Lua - I was so used to them I never realized they aren't there out of the box!
Now that the hurdle is over, I will see how quickly I can implement all of the things I had in T-Engine. I guess it's going to be really quick, since T-Engine is open-source and I have long been hacking it's source (and I don't need to bring EVERYTHING over since I don't need the notion of modules, for instance, or the main menu being a completely separate module).
The only problem I can foresee right now is the ASCII/tiles switch, since it's gonna essentially double on the number of code points I'll need... unless I can
if mode = ASCII then
terminal.print([0x5E])
else
terminal.set("0x5E:tile.png")
terminal print([0x5E)
???
-
I seem to be having a tiny problem. I am specifying image paths in my Lua code, so I use the / kind of slash. However BearLib can't find the images because it seems to want a \ slash, which is an escape character in Lua.
I can load the pictures fine if they sit in the main folder, but this will quickly become unmanageable...
-
The library considers forward slash '/' universal and replace it with backslash '\' on Windows. I. e. forward slashes should work everywhere. Like this (https://bitbucket.org/cfyzium/bearlibterminal/src/0435b883c30adc5eba64364c5abdb779c4103a7e/Samples/Omni/Source/Sprites.cpp?at=default&fileviewer=file-view-default#Sprites.cpp-14).
The problem is probably related to current working directory, with interpreted applications there are more ways to end up with some unusual cwd. To check this, try to supply an absolute path. If absolute paths work, then we'll have to figure out some way to address resources relatively =|. The most reliable way would be to get the full path to the main script file and then derive resource paths from it.
-
The library considers forward slash '/' universal and replace it with backslash '\' on Windows.
Isn't the case, at least in my Lua code.
I'm using lfs.currentdir() to determine the current directory and printing it to console - it's the correct one.
I'm getting the tile to be used via
player = Actor.new()
terminal.set("U+E000: "..player.image)
where image is a string stored in the Actor class. Printing it to console to verify I'm getting the correct thing.
This is the entirety of my Actor class so far:
lfs = require 'lfs'
local game_dir = lfs.currentdir()
print("Current dir is: "..game_dir)
package.path = game_dir.."/engine/class.lua"
require 'class'
module("Actor", package.seeall, class.make)
function _M:init()
self.display = "@"
--self.image = game_dir.."/gfx/player/racial_dolls/human_m.png"
self.image = "human_m.png"
end
The class and module calls are there to allow me to call things via self:blah() but you could change it to Actor:init() function Actor:init()
If I use game_dir, what I see in the console is:F:\roguelike\test/gfx/player/racial_dolls/human_m.png
And the bt.log says:
12:46:10.124 [info] Trying to set "U+E000: F:\roguelike\test/gfx/player/racial_dolls/human_m.png"
12:46:10.125 [debug] Group "U+E000":
12:46:10.126 [debug] * "_" = "F:\roguelike\test/gfx/player/racial_dolls/human_m.png"
12:46:10.126 [debug] Requested resource "F:\roguelike\test/gfx/player/racial_dolls/human_m.png" with possible prefix "tileset-"
12:46:10.126 [debug] Loading resource from memory 'F:\roguelike\test/gfx/player/racial_dolls/human_m.png'
12:46:10.127 [error] Failed to set some options: Resource::Open: failed to parse memory address (F:\roguelike\test/gfx/player/racial_dolls/human_m.png)
So as you see, the slashes vary.
-
This is a rather serious mistake on my part. I'll fix it right away, but I won't be able to recompile and upload binaries till the end of the day.
The problem lies with the path being mistaken for an 'addr:size' memory address because of the colon after the drive letter. Meaning, absolute paths on Windows were broken since 0.14.0 =(
[Edit]
Uploaded a new 0.14.7
-
The only problem I can foresee right now is the ASCII/tiles switch, since it's gonna essentially double on the number of code points I'll need... unless I can
[Personal opinion ahead] I think using tiles is a qualitative change from using purely ASCII output. While the 'A' tile for an ant monster may look like the 'A' letter, they are not the same. Letter tiles should use a normal font optimized for reading, while monster tiles may be from a more fancy font. Map/monsters/etc. tiles generally look better when they are square, while text is much more readable when it is something 1:2 like 8x16. With this I think it is justified to have a separate tile set even for an ASCII theme. And there is no shortage in code points, there is a whole Basic Multilingual Plane (https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane) worth of them in the terminal.
[Edit]unless I canterminal.set("0x5E:tile.png")
You can change tiles on individual basis, exactly as you've written. Though it may interfere with regular text as print() will use the same code points and same tiles.
-
If anyone is interested, I ported the Omni samples to Python. I just updated them for 0.14.8. Most of the time, the translation from C++ is quite literal. It runs in both Python 2.7 and 3.5 (and probably others). And also on pypy 5.3, although it's very slow on pypy because of ctypes...
Here is the link: https://github.com/ibatugow/blt_samples (https://github.com/ibatugow/blt_samples)
You should be able to just download or clone the repository and run the samples in the Python directory. You can either run each sample individually or sample_omni.py for the whole thing.
-
For archlinux users, there is now an easy way to install the library (https://aur.archlinux.org/packages/bearlibterminal-hg/).
-
Great program, but I seem to have trouble printing unicode characters (ex. β) in Python. Could anyone give me an example of how I would get the terminal to print unicode characters as well as ASCII? I am using DejaVu fonts so they support unicode.
-
It should work as long as Python does not lose unicode along the way:
- make sure the source code is saved in suitable encoding, e. g. utf-8
- make sure that encoding is conveyed to Python with 'coding' comment
- in Python2 use unicode strings
# -*- coding: utf-8 -*-
from bearlibterminal import terminal
terminal.open()
terminal.set('font: ./DejaVuSansMono.ttf, size=16')
terminal.printf(2, 1, 'β') # would be u'β' if Python2
terminal.put(2, 2, 'β')
terminal.refresh()
terminal.read()
terminal.close()
-
Hey all, it's been a little while.
I'm trying to build a small roguelike using the Python wrapper, and I can't seem to get key releases to register. Any ideas how I've messed this up?
import PyBearLibTerminal as terminal
terminal.open()
terminal.printf(2, 1, 'β')
terminal.put(2, 2, 'β')
terminal.refresh()
while True:
if terminal.has_input():
key = terminal.read()
print(key)
if key == terminal.TK_Q | terminal.TK_KEY_RELEASED:
print('released')
break
elif key == terminal.TK_Q:
break
terminal.close()
produces
.../Programming/Python/roguelike python3 test.py
4
22
7
44
20
.../Programming/Python/roguelike
Has anyone experienced this before? Have I done something wrong or set something up wrong? I haven't tried this on my Windows machine, but I'll be sad if I can only access key releases on Windows.
-
I can't seem to get key releases to register.
This is intended. To mimic the most basic terminal input, by default the library reports key presses only. If you need some extra (key releases, mouse), you have to enable that via 'input.filter' option, e. g.terminal.set('input.filter=[keyboard+]')
It is documented at reference/input/input.filter (http://foo.wyrd.name/en:bearlibterminal:reference:input#inputfilter).
The "[keyboard+, mouse]" notation feels a bit clunky, but I just can't think up a better one.
-
A-ha! Finally, an answer. Thanks for pointing that out; shoulda read the spec closer!
-
Hi, I'm starting a new project using bearlibterminal and python, and its going awesome so far! Thanks for this wonderful library
-
I'm converting a project from libtcod to bearlibterminal because of various features I liked. Everything seems to be going well except for keyboard inputs. It appears as though an extremely large buffer of input commands are being kept when a user holds down a key. Is there a way to avoid this behavior? or to delete the queue on demand?
Ive tried using the non-blocking terminal.has_input() prior to calling terminal.return. But i get the same input lag no matter how I do it.
def read_key_int():
while terminal.has_input():
return terminal.read()
return None
Any help would be greatly appreciated.
Thanks!
-
Hmm. BearLibTerminal does not do anything out of ordinary here. It accepts input at the same rate it comes from the OS and keeps it until it is read, pretty much just like any other app would. You shouldn't be able to enqueue a significant amount of keystrokes unless the application is particularily lazy with input. Even if you redraw a whole screen every read, it should not be noticeable until you are consistently generate more that 60-80 keypresses per second =).
Do you have a minimal working example illustrating your problem?
The non-blocking read code you posted will not help clearing the queue: it won't read more or faster than a regular read would (but it will exit faster and more frequently). If you want to flush the input, you need a proper cycle:def clear_input():
while terminal.has_input():
terminal.read()
Obviously this will lose all those buffered keystrokes.
Most of the time you should not have to clear anything, though. Losing input is not good and it's more robust to shape the control flow so that a sudden bunch of keypresses do not surprise the program that much.
-
That clear function solved my issue. Its not the prettiest solution, but it works for now as there appears to be no noticeable input loss from the user.
It might have something to do with how time/turns are handled in my scheduler func.
Thanks for the quick reply!
Also:
Is there a way to write to the states?
For example if I want to move the mouse cursor to a cell with a line of code.
in libtcod there is:
libtcod.mouse_move(x, y)
that moves it to certain pixel coords.
-
When I was doing a tile game in Java, I would get the input and put it in a que.
So multiple clicks might be in the que after a unit is done moving.
But then the next unit would use them, we dont want that.
So I always clear the que at the end of a units turn.
-
But then the next unit would use them, we dont want that. So I always clear the que at the end of a units turn.
Yep, discarding input is okay when you're doing it deliberately. But by that time you already know what is what.
Nuance is, clearing input just to make the whole thing work may indicate a flaw in control flow. Or may not, but my experience says chances are high.
A simple (maybe too simple, but obvious) example would be accidentally doing things in draw-read-refresh order. It displays the scene one frame late and does introduce a visible lag.
Is there a way to write to the states?
No, those states are intended to be, well, just the current state of things. Modifying is done through terminal_set -- or a separate function if the action is frequent and important enough (e. g. terminal_layer).
Setting mouse position is a questionable action. For once, I'd never do that in my own program because as a user I'd really hate for mouse to jump on screen out of my control. I might add the functionality just for completeness sake but it has quite a low priority. Unless you provide a compelling use case =).
-
I've been fiddling with bitmap fonts in C# and there's a fairly interesting effect when using bitmap font without specifying size. It opens a white full screen sized window and nothing else.
Also, are http://roguecentral.org/doryen/data/libtcod/doc/1.5.1/html2/console_set_custom_font.html?c=false&cpp=true&cs=false&py=false&lua=false TCOD layouted fonts supported?
-
The use case was for ranged combat:
User pressed "f" to enter Fire-Mode.
Program figures out closest targetable monster.
Reticle is placed over that monster.
If user presses "f" mode, targets will cycle between those available.
But use can "free-aim" by using the mouse, when user moves mouse reticle and firing line follows mouse in circle.
(NOTE: it felt more natural to move the cursor to the reticle than to have it just follow relatively. This was a minor thing, so I took it out)
NOTE: in the python bindings i'm using: TK_MOUSE_MOVE state is ALWAYS 0. (using check, its always False. Found that odd. all other mouse states appear to be working correctly.
Additionally i'm not sure how to get bearlib to read the "box drawing acsii" from my PNG file instead of the default. Even using your yoshi_island font the boxes draw standard when addressing them via unicode (ex: 0x2502 prints a |, regardless of the glyph in the .PNG)
Enjoy my barrage of ?'s!!
-
there's a fairly interesting effect when using bitmap font without specifying size. It opens a white full screen sized window and nothing else.
Oh >_<. When the 'size' of bitmap font/tileset is omitted, image is treated as a single sprite. And then library uses this sprite as a character tile and adjust the size of a cell and a window accordingly. Well, tries to. With 256x256 image library will try to resize the window to 80x25 * 256x256 = 20480x6400 pixels which is probably beyond reason and breaks a few things.
Since not specifying a size for a font makes no sense, I'll just make it fail (and roll back) in this case.
Also, are TCOD layouted fonts supported?
About two thirds? ASCII_INROW is codepage '437', TCOD is, well, 'tcod' and ASCII_INCOL is just too weird.
Terminal.Set("font: consolas12x12_gs_tc.png, size=12x12, codepage=tcod");
Nuances are:
1. Most of tcod font images are non-transparent (fully opaque background) and their tiles will not overlay nicely. Might not be a problem. I have an idea how to fix that on-the-fly.
2. I've just noticed that CP437 (https://en.wikipedia.org/wiki/Code_page_437) does actually contain various icons and arrows at 0x01-0x1F in contrast with other ANSI codepages. I'll fix that in the next release.
3. Looks like there is a bug in handling box drawing characters. Working on it.
Technically, BearLibTerminal supports any layout. Instead of a predefined built-in name, you can specify a filename in the 'codepage' parameter:
Terminal.Set("font: image.png, size=16x16, codepage=my_codepage.txt");
With file containing a list of Unicode codepoints for each tile consecutively, left-to-right, top-to-bottom:U+0020-U+003F, U+0040, U+005B-U+0060, U+007B-U+007E, U+2591-U+2593,
U+2502, U+2500, U+253C, U+2524, U+2534, U+251C, U+252C, U+2514, U+250C, U+2510, U+2518,
...
The use case was for ranged combat: <...>
Why do you need to move the mouse though? Not sure I understood your note, but placing/cycling the reticle over the targets via keyboard and then moving it under the mouse on the mouse movement looks more natural. Mouse does not move when you use keyboard to navigate the text in an editor or file icons in an explorer, yet you can always 'override' the cursor (selection) position by moving/clicking the mouse.
NOTE: in the python bindings i'm using: TK_MOUSE_MOVE state is ALWAYS 0.
TK_MOUSE_MOVE is an event, not a state (and listed so in the docs, so my conscience is clear here =)), so it will be read zero as any other invalid state code. There are no separate lists of constants because almost every other event is also a state.
Additionally i'm not sure how to get bearlib to read the "box drawing acsii" from my PNG file instead of the default. Even using your yoshi_island font the boxes draw standard when addressing them via unicode (ex: 0x2502 prints a |, regardless of the glyph in the .PNG)
Yup, that's looks like a bug. Bitmap fonts should override box drawing characters. Will look into it shortly. Not sure what yoshi_island is, though =/.
-----
Edit: well, most of issues are minor code-wise, expect an update in about a day.
-
More mouse questions:
I'm having trouble with differentiating between mouse clicks.
Example:
1) User presses key to open a Pop-Up window with a 'close' button.
2) User clicks on 'close' button with mouse.
3) Game closes Pop-Up, but also attempts to Pathfind to X, Y location (also activated by clicking)
Since I don't see a "TK_MOUSE_LEFT_UP" or "TK_MOUSE_LEFT_RELEASED". I tried using TK_MOUSE_CLICKS but that still shows 'True' while its being held. which is being seen by my other event handlers.
In addition to this issue it appears there is no state difference between HOLDING down a button and CLICKING IT rapidly (well you would get an occasional False from MOUSE_LEFT, but not sure if thats useful in this case).
-
I'm having trouble with differentiating between mouse clicks. Example: <...>
Erm, are you using terminal_read or terminal_state? Runtime state is not the right tool for this task. There should not be any problems with basic mouse handling when reading its events. The first TK_MOUSE_LEFT closes popup and the next TK_MOUSE_LEFT (which would trigger pathfinding) won't come until another actual mouse click.
To use mouse (read any mouse-related events from terminal_read) you need to explicitly enable it by setting input.filter option, see docs (http://foo.wyrd.name/en:bearlibterminal:reference:input#inputfilter).
Also, take a look at "Input 2: mouse" in SampleOmni (event counter, states and behavior) and it's source code (https://bitbucket.org/cfyzium/bearlibterminal/src/b115a1b3875d09139475cfb325c132cefef5a838/Samples/Omni/Source/Mouse.cpp?at=default&fileviewer=file-view-default).
-
Figured it out.
I had two different functions polling for inputs. So each mouse event was registering in each one. Fixed that and VOILA!.
-
Okay, here is an update: 0.14.12 (Windows (http://foo.wyrd.name/_media/en:bearlibterminal:bearlibterminal_0.14.12.zip) / Linux (http://foo.wyrd.name/_media/en:bearlibterminal:bearlibterminal_0.14.12.tar.bz2) / OS X (http://foo.wyrd.name/_media/en:bearlibterminal:bearlibterminal_0.14.12_osx.zip) / PyPi (https://pypi.python.org/pypi/bearlibterminal))
* First ~32 symbols of CP437 (xxx_ro.png from tcod are this) are properly mapped onto the Unicode now (kind of missed that before).
* Grayscale fonts (.png w/o transparency) are properly supported.
* Box Drawing elements from bitmap fonts are not overrided by auto-generated tiles anymore.
This also means libtcod fonts (except ASCII_INCOL layout) are fully useable now.
* The library will not accept a font tileset without a 'size' parameter.
It's now a bit harder to break things accidentally.
* C# wrapper: added some Point/Rectangle function overloads.
* C# wrapper: Set() and Get() support formatting and parsing System.Drawing.Size type (I mean, in library-recognizable format):
Size custom_size = Terminal.Get<Size>("ini.settings.custom-size", new Size(80, 25));
Terminal.Set("window.size={0}", custom_size);
* Python wrapper: added atexit cleanup handler that closes the library if Python exits due to exception.
-
Is it possible to have a single font (ttf or bitmap) but print chars from it different sizes? I've been planning an ascii system that has double sized chars in the game screen but regular in the text.
-
It is possible. But technically it is not the same font with different sizes, they are different tilesets loaded from the same source with different parameters. Which may be done in a few ways.
Let me provide an example of various font configurations:
(http://i.imgur.com/oexp1Wf.png)
There are two groups, blue is UbuntuMono-R.ttf, green is terminal10x18_gs_ro.png.
1. First line is the basic font loaded with a bare minimum of options.
2. Second line is the same font but spaced to make it fit [almost] square map cells. The 'spacing' parameter controls how a character is centered relative to its origin cell and how much cells Print() function should advance.
3. Third line illustrates what will happen if characters are resized to some arbitrary size irrelevant to the base cell size.
4. Fourth line is pretty much the same as the second one.
For truetype tilesets 'size' directly specifies the target size. For bitmap tilesets 'size' is a size of a tile in source image and target size is overriden by 'resize' parameter. Spacing is the same for both.
You may have several different fonts at once. In the example above there are eight different fonts loaded like this:
Terminal.Set("twice font: UbuntuMono-R.ttf, size=20x36, spacing=4x2");
Such extra fonts are used like this:
Terminal.Print(2, 1, "[font=twice]Abc 123");
But there is a limitation: you cannot address individual tiles from extra font with Put() since it does not have a font name argument. You have to use Print() with 'font' formatting tag.
Instead of loading alternative character configurations as fonts you can also load them as generic tilesets:
Terminal.Set("0xE000: terminal10x18_gs_ro.png, size=10x18, resize=20x36, resize-filter=nearest, spacing=4x2");
This will place twice-size character tiles into codepoints 0xE000..0xE0FF. You won't be able to Print() with them since those are not character codes anymore but you'll be able to Put() them:
Terminal.Put(2, 1, 0xE040); // @
But there is a gotcha, 'codepage' has a very different meaning when loading tilesets vs. loading fonts. Most of the time you do not need one though because usually you want a whole tileset loaded straight consecutively.
I probably need to write a nice long article about how all of this works. The system is flexible enough to become confusing.
P. S. And I've immediately found a new thing to fix. When a truetype font is loaded with size that is not the same aspect ratio as the base cell size (e. g. 18x18 vs 10x18), its characters are not aligned correctly within tiles. Aargh!
-
Would anyone be interested in D bindings? I'm learning D right now, and had been going to write an RL in it with bearlib. If anyone wanted, I could probably formalize it all into a library.
-
It seems that bearlibterm leaks memory? Just running the example C program, valgrind reports:
definitely lost: 520 bytes in 2 blocks
indirectly lost: 1,661 bytes in 14 blocks
Full valgrind log: http://lpaste.net/350473 (http://lpaste.net/350473)
-
It seems that bearlibterm leaks memory?
Oh, thanks for pointing that out. There is also a small leak in TrueType tileset. Overall it is just a few bytes once a process, so I will not re-upload right away and incorporate the fixes into the next update.
Incidentally, how do you name a size structure (usual width, height) using lowercase when the 'size_t' name is underhandedly taken by the standard library?
-
Some unicode doesn't seem to be supported. The ╱ character, for example, which is supported by the font I'm using (I've verified this with SDL-TTF) just shows up as a black box in bearlibterminal. Any fix?
-
Actually, no symbol out of Box Drawing (0x2500-0x257F) (https://en.wikipedia.org/wiki/Box_Drawing) range is being taken from any TrueType font, these characters are automatically generated by the library. This is how it happened:
* Most TrueType fonts provide only a small subset of Box Drawing character range. Using half native, half auto-generated produces a shabby image.
* Those characters that actually provided are often do not align well even within the font itself.
* Even if the font is good, it is hard to align there characters when rasterized which produce unseemly patterns of various visibility (e. g. a pixel missing every tile in a wall).
* More so if the cell size is not native to the font, e. g. manually set to be 10x20 for design purposes when the font is more like 10x18.5 at that specific size.
So in the end I just went with auto generating these instead of using ones from the font. Also, same goes for Block Elements (0x2580-0x259F) (https://en.wikipedia.org/wiki/Block_Elements) range. Note that bitmap fonts is a very different case and theirs version of characters are used normally.
But seven characters (0x256D-0x2573, and ╱ is there) turned out to be not so easy to generate nicely and ended up as no-characters to this day.
Looking at this again, I probably should just allow the user to use font's characters if he wants to, e. g. by an additional 'use-box-drawing=true' font parameter. I'll include that into the next update. And I need to support those seven characters, but this is not as easy.
Meanwhile there is a rather ugly hack to still use these font's characters right now by loading a subset of a font to some other unused code points, e. g. 0xE000-0xE07F, so that 0x2571 (╱) would be availables as 0xE071. Tell me if you really want to see this =/.
-
When terminal.read_str() accepting input from the keyboard, is there a way to allow the use of the NUMPAD numbers? Cannot seem to enable this.
Thanks, as always.
-
Thanks for continuing to develop this library :)
More than once when working with bearlibterminal I've needed to implement maps that scroll smoothly. The included demo application also has a smooth-scrolling sample. The problem with implementing this in BLT is that when the display is offset by a fraction of a tile, there are more tiles to be drawn than there are slots in the terminal. There are two ways around this:
- Use composition, put all the tiles at (0,0), use the pixel offset to control where they appear.
- Use composition, put most of the tiles in the correct slots with uniform pixel offsets, put one row and one column in the wrong slots with different pixel offsets.
Both methods "work" and don't seem to have any performance implications, but from the perspective of code readability I would prefer to be able to put each tile in its own slot. That's not currently possible because characters can only be put inside the terminal's boundaries.
Would it be possible to extend the terminal storage, writing, and drawing outside the bounds imposed by TK_WIDTH and TK_HEIGHT? Just one row and one column would be enough for this purpose, but another option would be to have a configurable number of extra rows and columns on each side. This could be helpful when drawing 2.5D terrain where tiles could be N rows off the bottom of the terminal but still be high enough that they should appear on the display.
Here's a discrete dimetric heightmap drawn with BLT. It probably would have been easier with a configurable number of extra rows on the top and bottom.
(http://i.imgur.com/aBbXAZ8.png)
-
Update time: 0.15.0 (Windows (http://foo.wyrd.name/_media/en:bearlibterminal:bearlibterminal_0.15.0.zip) / Linux (http://foo.wyrd.name/_media/en:bearlibterminal:bearlibterminal_0.15.0.tar.bz2) / OS X (http://foo.wyrd.name/_media/en:bearlibterminal:bearlibterminal_0.15.0_osx.zip) / PyPi (https://pypi.python.org/pypi/bearlibterminal))
The main (but still minor) version bump comes from a slight change in printing function. Not sure what had I been under while first implementing that, but until now text wrapping/aligning was done via in-text formatting tags:
terminal_printf(2, 1, "[bbox=%dx%d][align=center]%s", w, h, str);
To make things even messier, print() was returning either width or height of a string depending on the presence of bbox. While there is some logic, the overall it is just... ugh.
Now print() (or a variant of it if no overloading available for the language) accepts width, height and alignment parameters explicitly and always returns both dimensions:
y += terminal_print_ext(x, y, width, 0, TK_ALIGN_DEFAULT, message).height;
And same goes for measure().
By the way, it was quite a quest to update all seven (sic!) wrappers for various languages. I've initially tried a naive approach with simply returning a struct, but quickly discovered that doesn't work across multiple languages -- apparently there is no standard to how cdecl handles return values larger than a scalar.
Another change I need to illustrate is 'dead-center' alignment mode for tiles. It essentially ignores any typographic values for the tileset:
(http://i.imgur.com/sPMKB57.png)
This might be useful for map/level elements since that will align the good old ASCII in the map cells rather neatly.
Other than that, changes include:
* New 'use-box-drawing=true' and 'use-block-elements=true' truetype font parameters to force the library to use in-font glyphs if you really want. It still will auto-generate the missing ones.
* Keypad keys update TK_CHAR/WCHAR states now so they can be used for text input (e. g. read_str() function).
* Querying library version via terminal_get("version"), it will return a string like "0.15.0".
* A few fixes here and there.
Also, I've changed the Python wrapper structure a tiny bit. Instead of a lone .py file there is a Python package/module skeleton now. See the README.md (https://bitbucket.org/cfyzium/bearlibterminal/src/8dcc701a7d28853dab965c9f38a4cdc3aed9b978/Terminal/Include/Python/README.md?at=default&fileviewer=file-view-default) in the corresponding directory for some notes about it. Having a 'bearlibterminal' module directory instead of a single PyBearLibTerminal.py in the project allows easier switching between an installed package and a local copy (import statement is identical, no changes to source needed).
When terminal.read_str() accepting input from the keyboard, is there a way to allow the use of the NUMPAD numbers? Cannot seem to enable this.
That should be fixed in this update, see above.
Would it be possible to extend the terminal storage, writing, and drawing outside the bounds imposed by TK_WIDTH and TK_HEIGHT?
Well, I'll probably implement that one way or another. This would help tiles which are bigger than a cell like square map tiles, it is currently hard to place them above or to the left of the viewport even if you do not need any pixel offsets.
That said, personally I do not think that putting tiles into (0, 0) makes things messier. It could be easily wrapped into something like
def put_freely(x, y, dx, dy, c):
terminal.put(0, 0, x*cell_width + dx, y*cell_height + dy, c)
to make intent clear in the source code.
The most messy part is that offsets themselves are a hack to the pseudo-terminal ideology. It is fine for a tile or two but for the whole scene there is almost no support, you have to recalculate and readd every tile. It would be nice to have scrolling viewport and cells with different geometry but devising a sane API for that seems close to impossible.
-
Hi; perhaps this is the wrong place for this, but..
I'm done the roguelike tutorial, and I've ported it all into the bearlibterminal for the graphical aspect. I am simply wondering how to make my window resizeable?
I read the documentation, but it's not working and I don't know why. Example code plz?
-
I am simply wondering how to make my window resizeable?
Resizing a window may mean a few things.
1. Resizing a window so that there will be more (or less) cells available: you need to set 'window.resizeable' option and then handle TK_RESIZED input event from read(), e. g. assuming Python:
terminal.set('window.resizeable=true')
...
while True:
key = terminal.read()
if key == terminal.TK_RESIZED:
new_columns = terminal.state(terminal.TK_WIDTH)
new_rows = terminal.state(terminal.TK_HEIGHT)
...
elif key == terminal.TK_CLOSE:
break
...
TK_RESIZED is just a notification, though. The scene is already a new size by the time it was read.
2. User scaling the window (and its contents): it is done in some discrete steps by pressing Alt+Plus/Minus. There is no arbitrary scaling like in Caves of Qud, yet.
3. Program scaling the window (and its contents): there is no direct way for this, yet. You can achieve this by setting/resizing a different font size.
-
Hi, I've been checking out bearlibterminal, and I seem to be having trouble with ttf rendering. Check the attached image, and note the exclamation mark on the left. Is there something I might be doing wrong?
Thanks!
(http://i.imgur.com/WCexwE2.png)
-
Thanks a lot, Cfyz!
So I have it working as per your first example with variable cell sizes; however the whole screen goes black while it's being resized, and only upon movement does it render the screen again. Is this normal?
-
I seem to be having trouble with ttf rendering. Check the attached image, and note the exclamation mark on the left. Is there something I might be doing wrong?
Looks like auto-hinter in freetype library produces subpar results for some fonts. I'll look into it and probably release a fix shortly.
however the whole screen goes black while it's being resized, and only upon movement does it render the screen again. Is this normal?
Does it go black while resizing or after you release the mouse button and until some other input? The latter is normal since scene contents are cleared when it is resized, you need to recalculate the layout and redraw the scene for a new size.
-
Found an odd issue with [wrap] / [align] tags.
If you install BearLibTerminal via pip. The tags do NOT function properly. As in they do not no aligning or wrapping at all.
BUT
If you use PyBearLibTerminal and BearLibTerminal.dll from the "blt-samples" master, they work just fine.
Is there an issue with the PIP package? or am I doing something wrong?
P.S. Really close to finishing a python class called "bltColor" that brings all the libtcod color functions to blt and more! (testing this is how I discovered the wrap issue)
-
If you install BearLibTerminal via pip. The tags do NOT function properly. As in they do not no aligning or wrapping at all.
As I mentioned a few posts above, in the latest update 'wrap' and 'align' tags were removed in favor of proper function arguments. E. g.
terminal.print(2, 1, some_str, width=10, height=5, align=terminal.TK_ALIGN_RIGHT);
This actually shuffled things a bit for python print function =|. Originally there was printf because you can't use print identifier in Python 2 and print_ looks weird. So I went with printf as a workaround and obviously had to make it support formatting to match the name. But when I tried to add optional keyword arguments for area and alignment, it did not work with formatting part. Turns out, you can't have a signature like
def printf(x, y, s, *args, width=0, height=0, alignment=0):
Only **kwargs may come after *args. And making optional arguments nameless hurts the usability.
Since formatting was never an objective (unlike C++, Python has good string formatting out of the box), I changed string output function name to puts. Like put for putting characters/tiles and puts for putting stirngs, with print_ and print (in Python3) aliases. The printf was left for some compatibility (I would mark it as deprecated if I knew how) but for reasons stated above it does not have wrapping and alignment support anymore.
BUT If you use PyBearLibTerminal and BearLibTerminal.dll from the "blt-samples" master, they work just fine.
That's because it is a separate repository and probably has a previous library version. Should do something about it.
-
Not sure how I missed that. Thanks.
-
however the whole screen goes black while it's being resized, and only upon movement does it render the screen again. Is this normal?
Does it go black while resizing or after you release the mouse button and until some other input? The latter is normal since scene contents are cleared when it is resized, you need to recalculate the layout and redraw the scene for a new size.
[/quote]
Before another input is entered. Would I be able to make it recalculate and redraw the layout based on releasing the mouse button or somesuch?
Is there a general command to redraw the screen, as I'm also having the same issues after exiting any other screen such as inventory, character class, and etc, that only the objects and items are drawn before I move, not the background tiles at all.
-
I've been using BearLibTerminal and I love it (I've extensively used libtcod in the past and BLT is just so much simpler).
Well, I was wondering Cfyz.. do you plan to add support for animated tiles? I have a game I'm working on with drawn tiles and I'd really love to have them be animated. I couldn't see any way to do this currently, so do point out if I'm wrong here. :)
Anyways, thanks for the awesome library!
-
Another small update: 0.15.1 (Windows (http://foo.wyrd.name/_media/en:bearlibterminal:bearlibterminal_0.15.1.zip) / Linux (http://foo.wyrd.name/_media/en:bearlibterminal:bearlibterminal_0.15.1.tar.bz2) / OS X (http://foo.wyrd.name/_media/en:bearlibterminal:bearlibterminal_0.15.1_osx.zip) / PyPi (https://pypi.python.org/pypi/bearlibterminal))
* TrueType fonts/tilesets use font's native hinting now instead of TrueType's automatic. It is also possible now to choose the hinter manually via 'hinting' tileset attribute.
* Python wrapper searches both module directory and application directory for library binary.
I seem to be having trouble with ttf rendering. Check the attached image, and note the exclamation mark on the left. Is there something I might be doing wrong?
That's what hinting changes are about, should be working correctly now.
Before another input is entered. Would I be able to make it recalculate and redraw the layout based on releasing the mouse button or somesuch?
Is there a general command to redraw the screen, as I'm also having the same issues after exiting any other screen such as inventory, character class, and etc, that only the objects and items are drawn before I move, not the background tiles at all.
This looks like it heavily depends on your code logic. It is hard to say what and when you should call without looking at the code.
The only command to redraw the screen is terminal_refresh() but the problem is after resizing dimensions are different and library cannot just redraw by itself anymore since it has no idea about your application's layout. Once you've received TK_RESIZED, you need to recalculate new positions and sizes of map, objects, UI, etc. accounting for the new viewport size. This may be done in various ways depending on the input and rendering logic. Some applications calculate and redraw everything every frame and then it's enough to make it run a one more cycle. Some applications separate scene in layers/modal dialogs and then you need a method to invalidate and reconstruct everything at any given time. Not every logic incorporates scene resize easily. Usually it is best to design the loops and logic with resizing in mind right from the start.
Well, I was wondering Cfyz.. do you plan to add support for animated tiles? I have a game I'm working on with drawn tiles and I'd really love to have them be animated. I couldn't see any way to do this currently, so do point out if I'm wrong here. :)
Yep, there is no support for that right now. If you need animations you have to loop and redraw manually =/.
I've thought (still thinking?) about animated tiles and the biggest obstacle is that library does not know anything about the objects in a scene. It might be okay for something nailed to a screen but if you try to move/scroll things, the mapping is lost. The animation is either twitching (if cell changes restart it) or continuing in the wrong place (if some cells move simultaneously and the new content is indistinguishable from the previous one at the same coordinates). The only one that looked fine in my mockups is a very simple several-frames simultaneous animation like in DawnLike (http://opengameart.org/sites/default/files/Mine.gif) tileset.
-
Well, I was wondering Cfyz.. do you plan to add support for animated tiles? I have a game I'm working on with drawn tiles and I'd really love to have them be animated. I couldn't see any way to do this currently, so do point out if I'm wrong here. :)
Yep, there is no support for that right now. If you need animations you have to loop and redraw manually =/.
I've thought (still thinking?) about animated tiles and the biggest obstacle is that library does not know anything about the objects in a scene. It might be okay for something nailed to a screen but if you try to move/scroll things, the mapping is lost. The animation is either twitching (if cell changes restart it) or continuing in the wrong place (if some cells move simultaneously and the new content is indistinguishable from the previous one at the same coordinates). The only one that looked fine in my mockups is a very simple several-frames simultaneous animation like in DawnLike (http://opengameart.org/sites/default/files/Mine.gif) tileset.
Thanks for your response!
After reading your reply, much to my own surprise I managed to get animation working with a very minor change to my code. Basically in the code each object in a scene keeps track of the character that represents itself. For some of my objects, this is now a list with multiple characters, and in the draw code, if it sees that it's a list instead of a single character, it chooses a random entry in that list and uses that to draw with on the current redraw call. It allows for only simple two or three frame animation (something like Ultima 5 for example) but that's precisely what I was going for!
I'm going to need to make some tweaks for animations that need to be consistent (such as water tiles) but I definitely wasn't expecting to be able to get animations working so soon, so I'm quite pleased.
Thanks again for your reply because it inspired me to poke at my code and get animation working. :)
-
https://github.com/joekane/bltColor (https://github.com/joekane/bltColor)
(http://bit.ly/2iWtsYE)
bltColor
A color Class for BearLibTerminal that adds libtcod-like color functions.
Features:
- Set alpha of a color.
- Multiply by float.
- Multiply two colors.
- Add two colors.
- Subtract two colors.
- Blend two colors with a bias.
- Generate a custom gradient using color_map
This class is fully compatible with any function that BLT wants a color parameter, including [color] formatting tags.
-
I seem to be having trouble with ttf rendering. Check the attached image, and note the exclamation mark on the left. Is there something I might be doing wrong?
That's what hinting changes are about, should be working correctly now.
Yeah, looks better now. Thanks!
-
So I downloaded the new bearlibterminal after seeing your comment in my thread, and now when I import it, I'm getting strange errors.
Now when I try to run my program I get;
Traceback (most recent call last):
File "gritandsteel.py", line 6, in <module>
import PyBearLibTerminal as bear
File "C:\Python27\Grit\PyBearLibTerminal.py", line 70, in <module>
_wprint = _library.terminal_print16
File "C:\Python27\lib\ctypes\__init__.py", line 375, in __getattr__
func = self.__getitem__(name)
File "C:\Python27\lib\ctypes\__init__.py", line 380, in __getitem__
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'terminal_print16' not found
I have no idea what this means, or why your code looks like this.
-
and now when I import it, I'm getting strange errors.
This is because wrapper (.py) and binary (.dll) do not match. Specifically, you import the old wrapper since there is no such lines in the new one. There is no PyBearLibTerminal.py anymore either (see this (https://bitbucket.org/cfyzium/bearlibterminal/src/7c6713fee9a875c8cac232e80516ac338d716862/Terminal/Include/Python/?at=default)), so you probably just copied the new dll only without updating the wrapper/repacking the app.
When I bundle the script with py2exe, it notices the 'from bearlibterminal' import clause and copies the module files (module installed by pip) into the bundle so there is no need to have an additional PyBearLibTerminal.py in your source. The .dll is another story, no bundler seems to be capable to auto-include binaries, so you have to copy this one manually to the exe directory.
-
This is typically what makes me lose interest in Python; I can never get all the dependencies right. I'm not able to pip anything; what should a folder with this working contain?
EDIT:
Nevermind, thanks Cfyz, I've got it working again.
-
I've been working on a project using this library (very happy with it!), and I'm planning for the future - specifically, if I want to do more advanced graphics than just what is included in the library.
For example, if I wanted a little orb to be circling around a character, I might use BearLibTerminal for placing all the tiles and sprites, but then do some graphics coding of my own for the orbiting orb.
Don't suppose there's any easy way to getting at the OpenGL so I can implement my own additional graphical effects on top of what's rendered, is there? Or would I have to fork, modify, and compile the library on my own?
Edit:
Project is in C++, by the way.
-
Don't suppose there's any easy way to getting at the OpenGL so I can implement my own additional graphical effects on top of what's rendered, is there? Or would I have to fork, modify, and compile the library on my own?
Indeed, there is currently no way to do custom rendering. Reliable custom rendering requires support and guarantees from the library, which is far from its focus of abstracting the output.
That said, I do try to make the library capable to perform various tricks without diving into relatively low-level stuff. For example, a circling orb may be implemented via overlayed tile with offset. Take a look at "Extended 1: basics" (https://bitbucket.org/cfyzium/bearlibterminal/src/7c6713fee9a875c8cac232e80516ac338d716862/Samples/Omni/Source/ExtendedBasics.cpp?at=default&fileviewer=file-view-default) (lines 42-49) entry in SampleOmni, those circling characters are flying around one spot.
-
Just figured out that you made BaerLibTerminal bindings for Go. It's awesome, I'll check it in the near future, but - already, thank you very much :)
-
Hi, is it possible to make it so that the cursor doesn't blink at all? I tried setting terminal.set("input.cursor-blink-rate=0");, but that only made the cursor blink as fast as it could. Can you special-case 0 so that the cursor doesn't blink at all when you set the cursor-blink-rate to 0; or set another boolean value, input.cursor-blink?
-
I made a set of D bindings! Now guaranteed not to segfault: http://code.dlang.org/packages/bearlibterminal (http://code.dlang.org/packages/bearlibterminal)
-
Can you special-case 0 so that the cursor doesn't blink at all when you set the cursor-blink-rate to 0
Good idea. I was about to suggest using some really large number as a workaround in the meantime, but noticed you've done exactly that =).
I made a set of D bindings! Now guaranteed not to segfault
Ah, in the end I was not fast enough =|. Good in any case!
-
I made a set of D bindings! Now guaranteed not to segfault
Ah, in the end I was not fast enough =|. Good in any case!
Heh. Yeah, it turned out that I just didn't know how to allocate memory properly. I was going to write an sfml gui for my game, but then I decided I'd take just *one* more shot at getting bearlibterminal to work...and it did!
-
So, can someone share a code snippet of a simple menu program in python with a title and 2 options; one to print something and the other to exit the window? I was unable to find much info about the Python bindings. Thanks!
-
The 'official' python binding (https://pypi.python.org/pypi/bearlibterminal) follows the library API (http://foo.wyrd.name/en:bearlibterminal:reference) fairly closely. The simple snippet would probably be something along the lines:
from bearlibterminal import terminal
terminal.open()
while True:
terminal.clear()
terminal.puts(2, 1, 'Choose wisely:\n1. Print something\n2. Exit')
terminal.refresh()
key = terminal.read()
if key == terminal.TK_1:
terminal.clear()
terminal.puts(2, 1, 'something')
terminal.refresh()
terminal.read()
elif key in [terminal.TK_2, terminal.TK_CLOSE]:
break
terminal.close()
The clear+puts+refresh+read combination is a generic 'wipe clean, print some text and wait for any keypress' routine.
There are also some more sophisticated samples transcribed to Python available: https://github.com/ibatugow/blt_samples
-
Don't suppose there's any easy way to getting at the OpenGL so I can implement my own additional graphical effects on top of what's rendered, is there? Or would I have to fork, modify, and compile the library on my own?
Indeed, there is currently no way to do custom rendering. Reliable custom rendering requires support and guarantees from the library, which is far from its focus of abstracting the output.
That said, I do try to make the library capable to perform various tricks without diving into relatively low-level stuff. For example, a circling orb may be implemented via overlayed tile with offset. Take a look at "Extended 1: basics" (https://bitbucket.org/cfyzium/bearlibterminal/src/7c6713fee9a875c8cac232e80516ac338d716862/Samples/Omni/Source/ExtendedBasics.cpp?at=default&fileviewer=file-view-default) (lines 42-49) entry in SampleOmni, those circling characters are flying around one spot.
OK, that makes sense. I'm considering grabbing the source code of the library, and trying to modify it just so I can slide some of my own draw calls in before BearLibTerminal refreshes.
Any suggestions on where to start with that (or if it's even feasible)?
-
Any suggestions on where to start with that (or if it's even feasible)?
If you're doing this for your own project, it is actually very easy. After all, the overall scope is limited and you do not have to care about future compatibility that much.
At the very bottom of Terminal.cpp there is a small Terminal::Render (https://bitbucket.org/cfyzium/bearlibterminal/src/f1e876f8824cc67b3fbce57986a3ec9722f77e3f/Terminal/Source/Terminal.cpp?at=default&fileviewer=file-view-default#Terminal.cpp-2394) function. Which invokes a full redraw+flush. The point between Redraw() and SwapBuffers() is probably the best place to insert any custom on-top rendering (or a callback to it). Currently there is little caching is done and no fancy features are used, so it is fairly safe, just do not mess with any global state like viewport or matrices. The projection matrix is configured to pixel coordinates suitable for using glVertex2i to draw 2D figures. Resources (textures, buffers) may be initialized pretty much anytime after terminal_open() since everything is already set up after that call.
The OpenGL version is not enforced in any way meaning you may end up with as little as OpenGL 1.2 but no higher that 2.x (the old fixed pipeline is used). This will break somewhat when I add support for OpenGL ES (which does not have fixed pipeline). Everything remotely complex (from mere NPOTD textures to shaders) must be tested for availability and loaded manually before using.
-
...custom on-top rendering (or a callback to it)...
Awesome, I'll look into that! It sounds like interacting with BearLib's layers would be more difficult and involved?
And what you're saying is the OpenGL I use will need to be functions available below version 2? I'm curious as to why you chose such an older version to work with - I admittedly don't know that much about the different OpenGL versions.
-
It sounds like interacting with BearLib's layers would be more difficult and involved?
A bit. The Terminal.cpp, line 2054 (https://bitbucket.org/cfyzium/bearlibterminal/src/f1e876f8824cc67b3fbce57986a3ec9722f77e3f/Terminal/Source/Terminal.cpp?at=default&fileviewer=file-view-default#Terminal.cpp-2054) is where layers are drawn and same file, around line 2102 (https://bitbucket.org/cfyzium/bearlibterminal/src/f1e876f8824cc67b3fbce57986a3ec9722f77e3f/Terminal/Source/Terminal.cpp?at=default&fileviewer=file-view-default#Terminal.cpp-2102) is a probable place to insert custom inter-layer rendering. The nuance is that textures are not switched/restored between layers unless necessary so you need to be careful here and restore texture state if changes were made.
I'm curious as to why you chose such an older version to work with
The answer is simple: to cover as much hardware and platforms as possible. For example, low-end hardware like EEE PC or virtual machines with severely limited graphics support. OpenGL 1.2 is enough for core functionality. This is what I meant by extra library support necessary to provide full-featured custom rendering -- the library would need to provide means to select/assert OpenGL versions and fallbacks across multiple platforms.
I plan to use some of the newer functionality, e. g. framebuffers and shaders for better scaling/filtering or cleartype-like glyph rendering, but this will be strictly optional.
-
I'm curious as to why you chose such an older version to work with - I admittedly don't know that much about the different OpenGL versions.
While I've mentioned OpenGL 1.2 above, the real cutoff point is OpenGL 3.1 which drops fixed pipeline support (https://www.khronos.org/opengl/wiki/Fixed_Function_Pipeline) (means it need a separate rendering code). Most of the time you'll get at least OpenGL 1.4 context with a lot of relevant extensions (e. g. shaders) available, usually 2.x or even 3.0. You can use something like GLEW (http://glew.sourceforge.net/basic.html) to manage available extensions. Your code just have to be ready for features not being there, like any other graphics application.
-
So, this function doesn't seems to work in bearlib, I can't move the '@' this way. Any tips?
def addchar():
char = '@'
x,y = 0,0
terminal.refresh()
terminal.put(x, y, char)
keymove = terminal.read()
if keymove == terminal.TK_UP:
x -= 1
elif keymove == terminal.TK_DOWN:
x += 1
elif keymove == terminal.TK_LEFT:
y -= 1
elif keymove == terminal.TK_RIGHT:
y += 1
return;
-
So, this function doesn't seems to work in bearlib, I can't move the '@' this way. Any tips?
Is it supposed to move the '@' according to arrow keys every time it is called?
1. The 'x' and 'y' are re-assigned to (0, 0) every time. The '@' will always be in the same place. Move those variables out of the function and do not forget to use global statement (http://stackoverflow.com/questions/13881395/in-python-what-is-a-global-statement).
2. Output is done before input, so even if 'x' and 'y' are correctly global, output would still be one step late. Read and update first, then draw and refresh. Since input won't work without a window on screen (my guess at why refresh got before read), you may need to call refresh once during initialization (before starting updating/moving anything) just to bring the window on screen.
3. X axis is usually horizontal, Y is vertical. The keys and variables are mixed up.
-
Dangit, I'm so bad at this haha :-\ And all I want is a simple roguelike base so I can work around it...
-
If someone could hand me their roguelike code I would be happy! (Using only bearlib)
-
Two questions:
1) When using a codepage to map Unicode code points, is it possible to skip rows?
I have the Dawnlike tileset, and it has a ton of images I won't use, so I would like to map small codepages to the 0xE000-0xF8FF Unicode space tightly. For example, the GUI tileset has things like hearts in the first few rows that I won't be using in my game, but I like the GUI windows. I only need the nine tiles that make up the borders, edges, and fill.
2) I'm unsure of how to use differently sized fonts. Each letter takes up a whole tile regardless, and I'd like for my UI text to look more natural and be smaller than the 20x20 image tiles I am using. I looked at the source of the OmniSample, but that did not seem to have the desired effect for me.
-
When using a codepage to map Unicode code points, is it possible to skip rows?
It should have been possible, but damn. At least it will not be hard to fix.
Each letter takes up a whole tile regardless, and I'd like for my UI text to look more natural and be smaller than the 20x20 image tiles I am using.
Isn't DawnLike 16x16? Well, you can't have truly arbitrary font sizes. Since we are talking about pseudoterminal output, everything should be aligned to cells. How would you address those tiles otherwise? Therefore characters should be 1x1, 1x2, 2x2, etc. cells in size. Indeed, this limits the range of fonts that may be used simultaneously.
There is a hacky workaround: it is possible to force cell size (window.cellsize) to some common denominator, e. g. 4x4, and use a bit more fine-grained font sizes, e. g. 8x16 (2x4 cells), 12x24 (3x6 cells), etc. Or the other way around, adjust cell size to the font for easier text output and place image tiles by their pixel coordinates like this (https://bitbucket.org/cfyzium/bearlibterminal/src/f1e876f8824cc67b3fbce57986a3ec9722f77e3f/Samples/Omni/Source/ExtendedSmoothScroll.cpp?at=default&fileviewer=file-view-default#ExtendedSmoothScroll.cpp-72).
-
Dawnlike is 16x16 that I resize to 20x20 in the config options because my vision is poor.
Also, I think the cellsize trick might work for my purposes. I'll experiment with this - thanks.
-
Is there a way to make blt interpret keyups as their own events? The C header suggests that this is already the case by default, that when you press 'a', you get two events: 'a' and 'a'|TK_KEY_RELEASED:
/*
* If key was released instead of pressed, it's code will be OR'ed with TK_KEY_RELEASED:
* a) pressed 'A': 0x04
* b) released 'A': 0x04|VK_KEY_RELEASED = 0x104
*/
#define TK_KEY_RELEASED 0x100
However, pressing and releasing 'a' seems to just be one event, and I can't find anything about it on the configuration page. I ask specifically because I'm writing key-reading code, and basically I want to get the keypress into a struct like struct KeyPress { bool ctrl, alt; char ch; }. Here's my current code http://vpaste.net/U2ZeG (http://vpaste.net/U2ZeG), but it doesn't work well, obviously. I think I need to read keyup and keydown events separately, unless there's a better way. How do?
-
Whoa, the 'input.filter' option
is was completely missing from the table at the configuration page >_<. The relevant option is mentioned on the separate page: reference:input#input.filter (http://foo.wyrd.name/en:bearlibterminal:reference:input#inputfilter). Essentially, you need to add a plus sign to the list of events to enable their key-releases, e. g. input.filter='keyboard+'. The overall rationale is to behave similar to 'getch()' by default.
Honestly, the notation is quite meh. I would be glad if anyone came up with a better one.
-
Update time: 0.15.0 (Windows (http://foo.wyrd.name/_media/en:bearlibterminal:bearlibterminal_0.15.0.zip) / Linux (http://foo.wyrd.name/_media/en:bearlibterminal:bearlibterminal_0.15.0.tar.bz2) / OS X (http://foo.wyrd.name/_media/en:bearlibterminal:bearlibterminal_0.15.0_osx.zip) / PyPi (https://pypi.python.org/pypi/bearlibterminal))
The main (but still minor) version bump comes from a slight change in printing function. Not sure what had I been under while first implementing that, but until now text wrapping/aligning was done via in-text formatting tags:
terminal_printf(2, 1, "[bbox=%dx%d][align=center]%s", w, h, str);
To make things even messier, print() was returning either width or height of a string depending on the presence of bbox. While there is some logic, the overall it is just... ugh.
Now print() (or a variant of it if no overloading available for the language) accepts width, height and alignment parameters explicitly and always returns both dimensions:
y += terminal_print_ext(x, y, width, 0, TK_ALIGN_DEFAULT, message).height;
And same goes for measure().
Could you update http://foo.wyrd.name/en:bearlibterminal:reference#print with the new print() signature? It still talks about the "[bbox=*]" syntax, without giving any examples, so it's quite misleading.
-
I'm experiencing a couple of problems. First is that setting terminal_set("window.fullscreen = true"); doesn't do anything. The second is that although if you set the window to be resizeable, you can resize it, if you try to get the terminal size you just get the original size. Any workaround? Are these known problems?
-
setting terminal_set("window.fullscreen = true"); doesn't do anything. <...> you can resize it, if you try to get the terminal size you just get the original size
Besides fullscreen not being implemented for macOS yet (>_<), everything else seems to work fine. I've checked setting fullscreen in Ubuntu and Windows, and you can also check resize yourself by running second-to-last entry in SampleOmni which illustrates reading new dimensions after a resize.
If the problem persists, please share the environment info, code snipped being used and a log file with 'log.level=trace'.
-
Setting log.level = trace still didn't produce any output. I'm on linux, btw. Here's my snippet:
#include "Include/C/BearLibTerminal.h"
int main(void) {
terminal_open();
terminal_set("window.fullscreen = true");
terminal_set("log.level = trace");
terminal_refresh();
terminal_read();
terminal_close();
}
Here's my env:
FVWM_DATADIR=/usr/share/fvwm
_=/usr/bin/env
LANG=en_US.UTF-8
DISPLAY=:0
OLDPWD=/home/elronnd
MOZ_PLUGIN_PATH=/usr/lib/mozilla/plugins
XDG_VTNR=1
HG=/usr/bin/hg
XDG_SESSION_ID=c1
USER=elronnd
PWD=/home/elronnd/BearLibTerminal_0.15.1
MANPAGER=less
HOME=/home/elronnd
GTK_MODULES=canberra-gtk-module
MAIL=/var/spool/mail/elronnd
WINDOWPATH=1
TERM=xterm-256color
SHELL=/usr/bin/zsh
HOSTDISPLAY=localhost:0
SHLVL=4
XDG_SEAT=seat0
MAVEN_OPTS=-Xmx512m
LOGNAME=elronnd
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
XDG_RUNTIME_DIR=/run/user/1000
FVWM_USERDIR=/home/elronnd/.fvwm
PATH=/home/elronnd/.cargo/bin:/home/elronnd/bin:/home/elronnd/.cargo/bin:/home/elronnd/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
FVWM_MODULEDIR=/usr/lib/fvwm/2.6.7
LD_LIBRARY_PATH=Linux64
-
What i meant by "environment" was general info like OS and distro, bitness, how it is run, etc. I got most of it, but exact distro name may prove to be useful. My intuition is saying it is related to FVWM (though it shouldn't be happening either way, I am using fairly standard X11 mechanisms), I will look into it. Does the "window resizing" from SampleOmni not working properly either?
As for the log level, the point was to enable it before everything else to see the process of switching to fullscreen.
-
Alright, I set the log level right after terminal_open() and got this:
14:16:50.451 [info] Trying to set "window.fullscreen = true"
14:16:50.451 [debug] Group "window":
14:16:50.451 [debug] * "fullscreen" = "true"
Interestingly enough, if I alt+enter while within the window, it fullscreens fine. Even more interestingly, if I set window.fullscreen = true, while the window doesn't get fullscreened, I can then resize it even though I haven't set window.resizeable to true. I'm on 64-bit arch linux, fvwm, I get the same output on both gcc and clang. If it's relevant, my command line is gcc -std=c11 -LLinux64/ -lBearLibTerminal -o test test.c.
-
Hello!
I am experienced programmer, but complete newbie in C++. I'm trying to learn C++ by building a simple game using BearLibTerminal, but I'm completely lost with CMake.
My folder structure is:
learn
bin
libBearLibTerminal.so
lib
BearLibTerminal.h
src
main.cpp
CMakeLists.txt
My CMakeLists file is:
cmake_minimum_required(VERSION 3.7)
project(learn)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/bin)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR})
set(SOURCE_FILES src/main.cpp)
include_directories(${CMAKE_SOURCE_DIR}/lib)
add_executable(learn ${SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${CMAKE_BINARY_DIR}/libBearLibTerminal.so)
I'm trying to make my executable depend on libBearLibTerminal.so in the same directory, so I can zip them together, unzip on other Linux machine and run executable. But it sems that my executable depends on .../learn/bin/libBearLibTerminal.so, and not on the file in the current executable directory!
Being a complete newbie, I broke my head trying to make my executable be portable. So, I beg you to help - please, explain to me, how I can make libBearLibTerminal.so be shippable with main game file!..
-
I'm trying to make my executable depend on libBearLibTerminal.so in the same directory, so I can zip them together, unzip on other Linux machine and run executable. But it sems that my executable depends on .../learn/bin/libBearLibTerminal.so, and not on the file in the current executable directory!
In Linux application dependencies (shared .so libraries) are not searched for in the same directory with application executable. By default only a few select system directories (e. g. /usr/lib64) are considered. It is possible to add extra paths to this list while linking the executable, this is what 'rpath' is (https://en.wikipedia.org/wiki/Rpath). CMake automatically adds paths to the libraries from nonstandard locations to the application's rpath, which is why your executable looks for the libBearLibTerminal in the ../learn/bin. It does not depends on that exact file, it depends simply on 'libBearLibTerminal.so', but that path is the only path from the search list where such file is present.
Therefore if you want to mimic Windows behavior of loading libraries from the same folder, you need to manually add the '.' path to rpath of your executable. In CMake it is something along the lines of
cmake_minimum_required(VERSION 3.7)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH ".")
project(learn)
...
Though I'm writing mostly from memory.
Another common approach on the Linux is to wrap the application binary in the script which sets LD_LIBRARY_PATH environment variable before launching executable. This environment variable also provides extra search paths for dependencies.
-
First is that setting terminal_set("window.fullscreen = true"); doesn't do anything. The second is that although if you set the window to be resizeable, you can resize it, if you try to get the terminal size you just get the original size. <...> Interestingly enough, if I alt+enter while within the window, it fullscreens fine. Even more interestingly, if I set window.fullscreen = true, while the window doesn't get fullscreened, I can then resize it even though I haven't set window.resizeable to true.
I've tested a few combinations of distros, desktop managers and windowing libraries (SDL, GLFW, SFML and my own implementation) and can only conclude that it is a complete and utter mess =(. On the same OS but different DM and vice versa the same X11 app may or may not resize and fullscreen properly. Sometimes it is clear who is wrong, sometimes not. Out of the libraries, SDL is the winner though sometimes even it is powerless.
I've honestly thought I would be able to provide a window implementation which, while not being as feature-rich as others, would be more compact (e. g. SDL is many megabytes in size) and more tuned to the exact situation (e. g. resizing in steps to match cell size). Yep, nope.
I've taken a deeper look at the SDL code and I can downsize it to something reasonable. Believe me, it is not as simple as --disable-everything in ./configure, you can disable almost nothing this way in the current SDL codebase. I've even tried to discuss this on their mailing lists but couldn't get through moderation (wtf?). I probably should file a bug.
-
Understood, thank you!
Another question.
learn.ini:
[Game]
speed = 1
main.cpp:
std::cout << terminal_get("ini.Game.speed", "10"); // prints 10
Other values, like terminal window name, are loading perfectly. How can I make it fetch custom values?
-
Other values, like terminal window name, are loading perfectly. How can I make it fetch custom values?
Hmm, should have worked. Do you call terminal_get after terminal_open? Try to run the app from a console with BEARLIB_LOGLEVEL environment variable, e. g.
~/test$ BEARLIB_LOGLEVEL=trace ./SampleOmni
This will force the library to pring debug info about what configuration file it is using and what properties it has found.
-
Is there a way to underline text or make it blink? I can sort of make stuff underline by switching to another layer and printing ___, but there's a small gap in between them, and sometimes they overlap with the text in a way that's less than pleasing. Also, is there a way to get bold or italic text other than loading an alternate font?
-
Is there a way to underline text or make it blink? I can sort of make stuff underline by switching to another layer and printing ___, but there's a small gap in between them, and sometimes they overlap with the text in a way that's less than pleasing.
No, currently there is no such functionality. Underlining is theoretically possible (truetype fonts have some information and for bitmap fonts the library might try to do an educated guess).
Also, is there a way to get bold or italic text other than loading an alternate font?
Again, currently no. If you are talking about automatically producing bold/italic variations from a single font, it is technically possible to implement (thickening or shearing the tile) but I think it would look pretty ugly. Ultimately the library would need to operate on relatively small bitmap tiles and geometric transformations of small bitmap images had never produced anything pretty.
-
Is there a way to underline text or make it blink? I can sort of make stuff underline by switching to another layer and printing ___, but there's a small gap in between them, and sometimes they overlap with the text in a way that's less than pleasing.
No, currently there is no such functionality. Underlining is theoretically possible (truetype fonts have some information and for bitmap fonts the library might try to do an educated guess).
Awww. In that case, how does the cursor blink work?
-
In that case, how does the cursor blink work?
The library cheats by using an internal read with timeout, flipping the cursor visibility every time it, ugh, times out. I've been thinking about blinking and it feels like blinking is just a case of simple animation. It would be nice to solve both at once.
Btw, just a bit better pseudo-underline might be produced by overlaying 0x2581 (Lower One Eighth Block) instead of underscores.
-
Update 0.15.3 with various fixes: Windows (http://foo.wyrd.name/_media/en:bearlibterminal:bearlibterminal_0.15.3.zip) / Linux (http://foo.wyrd.name/_media/en:bearlibterminal:bearlibterminal_0.15.3.tar.bz2) / OS X (http://foo.wyrd.name/_media/en:bearlibterminal:bearlibterminal_0.15.3_osx.zip) / PyPi (https://pypi.python.org/pypi/bearlibterminal)
- Add font() function (select the current font by name, closes issue #33 (https://bitbucket.org/cfyzium/bearlibterminal/issues/33/function-for-setting-font)).
- Fix adding sprite tiles to an atlas (closes issue #30 (https://bitbucket.org/cfyzium/bearlibterminal/issues/30/sprites-throw-an-error-when-they-exceed-a)).
- Fix excess generation of 'character replacement' tiles.
- Fix dynamic tile generation (individual to a font, closes issue #32 (https://bitbucket.org/cfyzium/bearlibterminal/issues/32/block-drawing-chars-weird-for-fonts-with)).
- Fix configuring several fonts in one set() call (closes issue #34 (https://bitbucket.org/cfyzium/bearlibterminal/issues/34/configuring-a-bunch-of-fonts-in-the)).
- Retrieve clipboard contents via terminal_get("clipboard").
- Fix bitmap tileset reverse codepage (sparse tileset) handling.
- input.cursor-blink-rate=0 disables cursor blinking in terminal_read_str().
- Fix printing tab characters (configured by output.tab-width option).
- Fix app hanging on reopening terminal in macOS (see issue #23 (https://bitbucket.org/cfyzium/bearlibterminal/issues/23/reopening-a-closed-terminal-hangs-forever)).
And TODO list is like a few miles long >_<.
-
Hey, I've been enjoying the library but I have a quick question:
I have a square grid, say 12x12, and I'd like to overlay a thinner font for text on it, say 8x12. I've found that I can do this with put_ext, incrementing my dx by 8 for every character:
for (i,char) in enumerate(text):
terminal.put_ext(x,y,i*8, 0, ord(char))
But this is rather less than ideal: it means lots of slow looping in python, and prevents me from using the nice annotation syntax (e.g., for color) that exists for print. Is there a way to accomplish this same purpose with the print function?
-
You could use a grid with 4x12 cells, and configure the font with "size=16x16, spacing=2x1". Then square symbols would need 3x1 spacing.
-
Thanks for the response. That approach works in this example because they have a nice common denominator, but this isn't always the case for how I'm scaling things. I suppose the more precise use case here is to easily use separate font scales for the UI from the game's grid -- without the requirement for nice integer ratios between them.
-
I suppose the more precise use case here is to easily use separate font scales for the UI from the game's grid -- without the requirement for nice integer ratios between them.
Well, this comes up from time to time... The main obstacle is that text in pseudo-terminal output is not a separate entity, it is the same as other tiles (and vice-versa) and must abide the same rules. When you try to detach text from the grid, different nuances arise. How to remove that text from screen when you can't address it by x, y cell anymore? What z-order does it take, always above the grid? And between each other text piece?
-
If you have two kinds of display elements, their grid spacings are coprime, and you don't want to use a 1x1 cell size, then you can draw one kind of display element (text) grid-aligned using print() and the other kind (graphics) all at (0,0) with composition and pixel offsets.
I don't think there are any benefits to making text and graphics so mismatched in a terminal game, though.
-
Is there a way to get FPS when using Bearlib?
(I'm redoing Veins in Python as an exercise and Pygame performance sucks when partially transparent pictures are involved, such as isometric tiles).
Also is there a list of games using bearlib anywhere? So far I only know of unlichtwesen...
-
I know about Jan's (so, that guy who created Unlichtwesen) adaptation roguebasin python+libtcod tutorial to BearLibTerminal (https://sites.google.com/site/iolx3home/TOMBS_BLT.rar?attredirects=0&d=1). This archive is sometimes detected as virus, but I'm pretty sure it's false positive. If you want to be 100% sure, you'd need to delete executable file that is detected as malware, python files are clean.
7DRL Poarchers will be decapitated also use BLT for display, but the official link is invalid. So, I reuploaded binaries via dropbox. (https://www.dropbox.com/s/1gkvj03cr71mbpx/Poachers%20Will%20Be%20Decapitated%20%28SRD%29%20%5Bwin%5D%5Bdoc%5D.zip?dl=0)
There is also small game Tiny Gatherer (https://bitbucket.org/VedVid/tinygatherer) that use BLT; it's written in Go.
-
(I'm redoing Veins in Python as an exercise and Pygame performance sucks when partially transparent pictures are involved, such as isometric tiles).
You're not forgetting to run Surface.convert_alpha() after loading the tiles, are you? (Probably not, but I'll mention it just in case.) In my experience, python+pygame can get a bit slow, but I never had any trouble related to just loading and blitting sprites.
As always,
Minotauros
-
Is there a way to get FPS when using Bearlib?
Well, since BearLibTerminal uses explicit refresh (does not draw continuosly by itself, only redraws if necessary) I did not thought much about displaying FPS. Values like 0.1 would look weird =). Essentially, how frequent you call terminal.refresh() would be the FPS.
Though I do calculate it in the 'speed' entry of the SampleOmni and so does the Python port (https://github.com/ibatugow/blt_samples/blob/master/Python/speed.py#L74) of the sample. Note that vsync is enabled by default and you need to disable it (the 'output.vsync' option) if you want more than 60-80 FPS.
-
Rolling along happily with BLT+Python.
One report: The default tile alignment is “center”
(from the wiki page) doesn't seem to be true anymore, at least for the version I have via pip. I was having the tiles offset until I explicitly centered all of them.
-
I really enjoy using your terminal so far, however I recently stumbled upon a possible bug. I am using the python version 0.15.3 of bearlibterminal. In my game, you move around using the numpad keys (terminal.TK_KP_1, terminal.TK_KP_2, ... terminal.TK_KP_9) to allow 8-directional movement. Today I tried to implement a sprinting mechanic, where you can hold shift to sprint and move faster. This requires calling the terminal.check(terminal.TK_SHIFT) function to check if the shift key is being held down along with the movement key. However, the function returns False regardless of whether or not the shift key is held down. This is odd, because the function works correctly along with almost all other keys (including the conventional 4-direction arrow keys). Here is a short python code to test yourself.
from bearlibterminal import terminal
if __name__ == "__main__":
terminal.open()
terminal.set("window: size=100x50")
while True:
terminal.refresh()
key = terminal.read()
if terminal.check(terminal.TK_SHIFT):
print 'shift held'
else:
print 'shift not held'
if key == terminal.TK_ESCAPE:
break
terminal.close()
On my computer, the program prints 'shift not held' when I hold down shift and then press a numpad key, but prints 'shift held' when I hold down shift and press almost any other key (I haven't tested every key).
EDIT:
Upon digging a bit further, I realize that the function works when I set number lock off, but doesn't work when number lock is on.
-
However, the function returns False regardless of whether or not the shift key is held down. <...> the function works when I set number lock off, but doesn't work when number lock is on.
I've looked into it a bit and was quite surprised by what they call Shift overriding NumLock (https://blogs.msdn.microsoft.com/oldnewthing/20040906-00/?p=37953). When you press Shift+4 you get the same scancode as when you press 4 without Shift, and what character is produced depends on the keystroke as a whole. However Shift+Numpad4 with NumLock on does not produce the scancode of the numpad key. Instead it imitates pressing the single left-arrow key by un-pressing the Shift key, sending an arrow keypress and restoring the Shift back to its original pressed state. And the system events that simulate this temporary Shift release are indistinguishable from the real key release and key press =|.
The only hint about the nature of Shift events is the inhuman speed they happen at: the Shift is released 0-2 ms before the corresponding arrow key event. Maybe I'll be able to filter the events based on that.
P.S. I am away for about two weeks, so unfortunately I won't be able to test or fix anything in the meantime.
-
Howdy - I'm new to the forums as well as bearlibterminal.
I'm trying to figure out if there is a way to call terminal_read_str and obfuscate the input, for creating something like a password input field.
I know I don't have to use terminal_read_str but I do like the cursor functionality that it exposes.
Ideally I'd like the text to appear as ***** as it's being typed, since I'm attempting to create a password field with this functionality.
Is this possible?
Thanks!
-Zachary Carter
-
Idly wondering if it'd be possible to combine bearlibterminal with PyQt?
-
Hi!
I am registerd just to ask: is mouse supported by BearLib terminal in Linux?
By default documentation says that I should see mouse cursor, but it isn't displayed, and also no mouse events captured in events cycle of my test program.
-
@denizzka well, I didn't try to code it myself, but mouse examples from omni-samples works flawless on Ubuntu 16.10 32bit.
@Cfyz I remember that you are planning to switch to use SDL for bearlibterminal. Does it mean that you are going to drop support for true/open type fonts?
-
@denizzka well, I didn't try to code it myself, but mouse examples from omni-samples works flawless on Ubuntu 16.10 32bit.
Maybe mouse events should be enabled before it can be catched?
-
And I am back. Mostly. Okay, in chronological order:
I'm trying to figure out if there is a way to call terminal_read_str and obfuscate the input, for creating something like a password input field. <...> I know I don't have to use terminal_read_str but I do like the cursor functionality that it exposes.
No, the terminal_read_str function is a fairly simple wrapper over standard library input/output and its functionality is very limited. The only thing that is not directly available in API is a timed read which it uses to animate the cursor. I'll consider input obfuscation, but in the meantime it should be quite easy to write a custom read_str. Here (http://foo.wyrd.name/en:bearlibterminal:reference:input#tk_char_tk_wchar_states) is a simple outline for a custom read_str but without a cursor. For that you'll need to wrap the call to terminal_read, something along the lines of
int terminal_read_timeout(int timeout)
{
for (int i = 0; i < timeout; i++)
{
if (terminal_has_input())
return terminal_read();
else
terminal_delay(1);
}
return -1;
}
And flip the cursor every read that timed out.
Idly wondering if it'd be possible to combine bearlibterminal with PyQt?
It is hard to integrate any fairly complex custom input/output into a GUI framework, be it Qt or another one. Usually it is easier to completely rewrite one side to match the other =/.
I am registerd just to ask: is mouse supported by BearLib terminal in Linux? <...> Maybe mouse events should be enabled before it can be catched?
Yes, you have to enable it explicitly. Specifically:
terminal_set("input.filter={keyboard, mouse}");
Yep, not the most intuitive part =/.
I remember that you are planning to switch to use SDL for bearlibterminal. Does it mean that you are going to drop support for true/open type fonts?
Nothing of the sort. The only thing I need from SDL is its cross-platform window and context management (I'll try to cut everything else away). From the user perspective transition to SDL should not even be noticeable at first. It is more about portability/stability and management costs.
-
I am registerd just to ask: is mouse supported by BearLib terminal in Linux? <...> Maybe mouse events should be enabled before it can be catched?
Yes, you have to enable it explicitly. Specifically:
terminal_set("input.filter={keyboard, mouse}");
Yep, not the most intuitive part =/.
Works! Thanks!
-
I'm not sure if this has been talked earlier, but it seems that there's some "bleeding" through layers with fonts.
Image of the problem: https://www.dropbox.com/s/3qemusoa3khsipt/BLTBleeding.png?dl=0
So what I've done: For a smooth movement there's a "buffer" of one extra row of tiles each direction that are rendered under the UI so that when I move, I use the gradually increasing offset to display them appearing smoothly from behind the UI.
To not display them above the UI, I've got a empty tile in my tileset that I've rendered above the buffer row. However, when I print text to the message log area, the buffer map row is shown only under the text.
In general, it seems that words printed displays everything under it. I've got a png bitmap font that's not even transparent as there's a black layer behind the font file. In addition I've specified the font to be not transparent:
Terminal.Set("window: size=" + Constants.ScreenWidth.ToString() + "x" + Constants.ScreenHeight.ToString() + "; font: Cheepicus.png, transparent=black, size=16x16; input.filter={keyboard, mouse}");
The same effect comes with my mouse hover that displays the name of the object below it. The font is clearly transparent still: https://www.dropbox.com/s/j1vuzpshzni4ue3/BLTBleeding2.png?dl=0
Any idea how to fix this, or is this a bug? I don't want my font to be transparent at all when it is printed in the message log.
-
Okay, a slight update: I changed transparent=red and it works, it's not even red at all anywhere, but now the black layer in the font file is deemed as non-transparent.
-
I've got a png bitmap font that's not even transparent as there's a black layer behind the font file. In addition I've specified the font to be not transparent:
font: Cheepicus.png, transparent=black, ...
Actually, it is exactly how you make it transparent, you specify a color which is to be treated as transparent. I probably need to formulate it more clearly in docs. Indeed, specifying some random color like red will force the entire tileset to remain opaque.
Though while there may be different cases, usually you want the font to be transparent. It is more flexible, e. g. printing over various backgrounds, compositing over tiles, etc. The library tries to make font transparent and I've made it quite automatic over time, so the question how to switch it off instead actually made me lost for a few moments =).
To not display them above the UI, I've got a empty tile in my tileset that I've rendered above the buffer row. However, when I print text to the message log area, the buffer map row is shown only under the text. In general, it seems that words printed displays everything under it.
Do you put those empty tiles and then print text in the same layer? By default, the library operates in 'replacement' mode in which tiles/characters replace previous ones (in that place within the same layer). If my guess is correct, the log is simply replaces empty tiles you've used to cover the map tiles making them visible again.
Besides more or less obvious solutions (making font opaque or switching to composition (http://foo.wyrd.name/en:bearlibterminal:reference#composition) to not replace tiles), there is also one less known feature that may be particularly useful here: layer crop region (http://foo.wyrd.name/en:bearlibterminal:reference#crop). It instructs the library to show only a portion of a layer, kind of cutting away the rest. It was introduced precisely for such situations where it may be hard to hide extra portions of some complex scene with offset and overlayed tiles.
Btw, the Set method supports string formatting:
Terminal.Set("window: size=" + Constants.ScreenWidth.ToString() + "x" + Constants.ScreenHeight.ToString() + "; ...");
may be
Terminal.Set("window: size={0}x{1}; ...", Constants.ScreenWidth, Constants.ScreenHeight);
-
Do you put those empty tiles and then print text in the same layer? By default, the library operates in 'replacement' mode in which tiles/characters replace previous ones (in that place within the same layer). If my guess is correct, the log is simply replaces empty tiles you've used to cover the map tiles making them visible again.
Ah, this was it :). I did print the tiles and the messages in the same layer. I didn't think print would be in replacement mode, but I guess it's only logical because "print" works like "put" behind the scenes, if I recall correctly. Now the messages are on a layer above the empty tiles and it works!
Besides more or less obvious solutions (making font opaque or switching to composition (http://foo.wyrd.name/en:bearlibterminal:reference#composition) to not replace tiles), there is also one less known feature that may be particularly useful here: layer crop region (http://foo.wyrd.name/en:bearlibterminal:reference#crop). It instructs the library to show only a portion of a layer, kind of cutting away the rest. It was introduced precisely for such situations where it may be hard to hide extra portions of some complex scene with offset and overlayed tiles.
I need to look into this cropping definitely.
Btw, the Set method supports string formatting:
Terminal.Set("window: size=" + Constants.ScreenWidth.ToString() + "x" + Constants.ScreenHeight.ToString() + "; ...");
may be
Terminal.Set("window: size={0}x{1}; ...", Constants.ScreenWidth, Constants.ScreenHeight);
Awesome :).
I must say, your library is pretty much *the* graphical library when making roguelikes :).
EDIT: Also, is there a way to empty the queue of input keys or does the library support preventing the following thing? I've noticed that if I've got a long lasting for loop, it registers and queues all the key inputs during the loops execution time. When I press a long time a movement key, it begins the movement but if I don't take my finger off the key, it puts the movement key into the queue like a hundred times, and it keeps unloading the queue so it is stuck until all the key presses are removed from the queue. This is because I've got my smooth movement implemented by a for loop and it renders the character at different offsets, so while it is moving one tile, all the keys are registered that are pressed during the movement.
-
Also, is there a way to empty the queue of input keys or does the library support preventing the following thing?
Yes, you can drain the input queue quite easily:
while (Terminal.HasInput())
Terminal.Read();
Personally, I don't like the idea of just skipping the events. Simply dropping them may lose input randomly. Imagine the user pressing a movement key and then some key combination. If you happen to drain the queue at a wrong time, you may be left with only a part of a combination which can drastically change the meaning (though it is hard to lose a simple state like Shift/Ctrl modifiers since BearLibTerminal keeps them available through Terminal.State).
Maybe a bit more robust solution would be to filter out only the repeats? Something like this:
int previous_key = Terminal.State(Terminal.TK_EVENT);
while (Terminal.Peek() == previous_key)
Terminal.Read();
-
Also, is there a way to empty the queue of input keys or does the library support preventing the following thing?
Yes, you can drain the input queue quite easily:
while (Terminal.HasInput())
Terminal.Read();
Personally, I don't like the idea of just skipping the events. Simply dropping them may lose input randomly. Imagine the user pressing a movement key and then some key combination. If you happen to drain the queue at a wrong time, you may be left with only a part of a combination which can drastically change the meaning (though it is hard to lose a simple state like Shift/Ctrl modifiers since BearLibTerminal keeps them available through Terminal.State).
Maybe a bit more robust solution would be to filter out only the repeats? Something like this:
int previous_key = Terminal.State(Terminal.TK_EVENT);
while (Terminal.Peek() == previous_key)
Terminal.Read();
int key = Terminal.Read();
if (Terminal.Peek() != key)
{
Seemed to the trick. I've got no idea how it works, but it works :).
-
Hello!
Is there a way to use fonts of two different pixel sizes as ttf imports, without converting one of them in .png? If yes, how codepoints are shared between them?
-
In general, using several different fonts at one is rather straightforward and mostly trouble-free, but I don't get what *exactly* are you asking for.
-
Is there a way to use fonts of two different pixel sizes as ttf imports, without converting one of them in .png? If yes, how codepoints are shared between them?
Well it is indeed hard to guess what exactly do you have trouble with, but probably you're trying to put both fonts in a single codespace, i. e. make the them all have different code points similar to font + tiles. BearLibTerminal support multiple codespaces for this purpose exactly, to have two (or more) separate fonts, with each one using the same (yet their own) code points for the same characters/tiles:
terminal.set('font: one.ttf, size=8x16')
terminal.set('another font: two.ttf, size=10x20')
Where 'another' is an arbitrary name to your liking. And then there are two ways to use it:
# Inline string formatting
terminal.puts(2, 1, 'Hello, [font=another]World')
# Global state
terminal.puts(2, 2, 'Hello, ')
terminal.font('another')
terminal.puts(2+7, 2, 'World')
-
BearLibTerminal support multiple codespaces for this purpose exactly, to have two (or more) separate fonts, with each one using the same (yet their own) code points for the same characters/tiles:
Got it, thanks! From reading documentation I got strange idea that two fonts share the same codepoints.
Another question. I have some problems that were reported earlier by Elronnd in this thread - namely, "window.fullscreen = true" not working and strange behaviour of "window: resizeable=true" (with this enabled, window can be resized by clicking the square button in the title, but not by dragging corners). I'm using Arch too.
Is there a way to somehow fix this problem?..
-
I'm attempting to use a font with a spacing greater than 1x1. While setting the character works as expected, when attempting to set background color, only the upperleft-most grid square is given the background color information. See the example image below.
I realize that, in the worst case, I can brute force this by decomposing each print call into two separate print calls (a 1x1 spaced font in layer 1, which only contains background information and my 3x3 spaced font in layer 2, with only the character information), but it seems like this might be a feature worth baking into the font configuration.
Thanks for the help, and the great library.
https://imgur.com/a/6HF5g (https://imgur.com/a/6HF5g)
-
when attempting to set background color, only the upperleft-most grid square is given the background color information.
Looks like a bug =/. Expect it to be fixed soon in a few days.
Another question. I have some problems that were reported earlier by Elronnd in this thread <...> I'm using Arch too.
Is there a way to somehow fix this problem?..
Sorry, missed the message. As I've mentioned before, I'm switching to SDL in attempt to fix these bugs. I've tested several things and if SDL won't help, probably nothing will. However, the process gradually turning into total refactoring and starting to take some time. Probably I'll take the current code and make a version that just uses SDL for windowing to test this approach.
-
I've tested out the new build and it fixes the background color issue; thanks! This allowed me to move my cell size from 12x12 to 4x4, but then I encountered another issue -- there's a hard-coded check that window.size < 256, which, with a 4x4 grid, only gives you 1024 pixels to work with. Is this a constraint that can be relaxed?
Another (I think) bug. I was messing around with font settings and found that:
size-reference=0x40 works fine but
size-reference=@
gives me:
[error] Failed to set some options: TrueTypeTileset: can't parse 'size-reference' attribute
-
Is this a constraint that can be relaxed?
It is a simple protection from accidental inadequate values like few millions by few millions. I agree that 256x256 is a bit small, so I've just replaced one hard-coded value 256 with another, 1024. This should be enough for now >_< (btw, lifting this further and playing with a FullHD worth of 1x1 pixel cells may be a good stress test for data structures involved).
TrueTypeTileset: can't parse 'size-reference' attribute
The correct format should have been
size-reference='@'
i. e. with quotes -- but nope, settings parser eats those quotes somewhere along the way. You can trick it by
size-reference=['@']
but the bug is definitely there. I assume it is not a big deal so I'll fix that sometime later.
-
Has anyone use Code::Blocks with BearLibTerminal successful? I am working on how to make it work.
-
I was able to get the BearLibTerminal to work with Larazus. The BearLibTerminal.pas file need one small additional. Add this "{$mode objfpc}" in before {$H+} on line 22. After this, it works beautiful. Will test it with Free Pascal and Delphi 10.2 (32 bit only since I got it free). For some reason I cannot explain why, perhaps someone can, I had to use the 64 bits BearLibTerminal.dll.
Will keep it post of my research results.
-
Is there a way to use fonts of two different pixel sizes as ttf imports, without converting one of them in .png? If yes, how codepoints are shared between them?
Well it is indeed hard to guess what exactly do you have trouble with, but probably you're trying to put both fonts in a single codespace, i. e. make the them all have different code points similar to font + tiles. BearLibTerminal support multiple codespaces for this purpose exactly, to have two (or more) separate fonts, with each one using the same (yet their own) code points for the same characters/tiles:
terminal.set('font: one.ttf, size=8x16')
terminal.set('another font: two.ttf, size=10x20')
Would it be possible to load the same font twice (the default one shipped with BLT), but with one of them having the codepoints overriden by tiles and the other not? Or does it have to be two different .ttf files?
Where 'another' is an arbitrary name to your liking. And then there are two ways to use it:
# Inline string formatting
terminal.puts(2, 1, 'Hello, [font=another]World')
# Global state
terminal.puts(2, 2, 'Hello, ')
terminal.font('another')
terminal.puts(2+7, 2, 'World')
-
What is the best way to start printing where the last print left off? I've been using the measure function but things aren't lining up properly. I think I'm just not using it properly. Here's an example of how I've been trying to use it.
#define TEXT_WIDTH 60
#define TEXT_HEIGHT 30
#define TEXT_X ((SCREEN_WIDTH / 2) - (TEXT_WIDTH / 2))
#define TEXT_Y 2
char *awesomeText= "I don't know anything about anything. In fact, I can't even say for sure if what I just said is true; and truth be told, I'm not even sure if I can or cannot say anything for sure. I think - not know - that you should, perhaps, ignore me, maybe.";
terminal_print_ext(TEXT_X, TEXT_Y, TEXT_WIDTH, 0, 0, awesomeText);
dimensions_t mark = terminal_measure_ext(TEXT_WIDTH, TEXT_HEIGHT, awesomeText);
terminal_print_ext(mark.width, mark.height, 0, 0, 0, "[color=red]@");
When I do this, the aweomseText is wrapped correctly but the red @ is printed on the second - at "I think - not know -", rather than the end of the string.
-
A somewhat related question. My "game" has color themes that the user can choose from. So for example, I do things like
terminal_bkcolor(activeTheme->bkColor);
Say I wanted to change the color of one of the words in awesomeText to a custom color (activeTheme->crazyColor). What would be the best way to do it?
-
Contrary to how it may look, I am not dead, yet =|.
What is the best way to start printing where the last print left off?
If you want to print phrase by phrase (actually more like paragraph by paragraph), then it is easy to do with measuring. Just remember that dimensions_t returned from print/measure is a size, not coordinates, so you have to add it to the last printing position. Note that print function also returns dimensions_t, you do not need a separate measure call if you've already printed the text.
However, if you want to literally continue printing, i. e. from the place of the last output symbol, there is no exact way. But I think there is no need. You can just concatenate the strings and print them in one go.
Say I wanted to change the color of one of the words in awesomeText to a custom color (activeTheme->crazyColor). What would be the best way to do it?
You can use some formatting tags in the string, e. g.
terminal_printf(x, y, "Some text with a [color=%d]word[/color] in another color", crazyColor); // choose %d or %s depending on the way you store the color (color_t or char*)
See terminal_print (http://foo.wyrd.name/en:bearlibterminal:reference#print) reference.
-
Just remember that dimensions_t returned from print/measure is a size, not coordinates, so you have to add it to the last printing position.
What is the proper way to do this for wrapped text? Everything I've tried has been off so far and I can't figure out why.
It's true that I might not need to do this anymore, now that you made me aware of string formatting + concatenate. It would be nice to know, just in case.
Thanks for the help, and thanks for bearlibterminal. It's great.
-
When I toggle into full screen, the lines for drawn boxes become really thin. Is there anyway to prevent that?
-
I have started to write a tutorial for using bearlibterminal to make a roguelike using python. https://costumeverse.com/Tutorial/BearLibRoguelike/
Please check it out and tell me what you all think.
-
Just realized I've been using BearLibTerminal for three years now and I couldn't be happier. It feels like I've really escaped a lot of the limitations that other pseudoterminal libraries put on me.
Thank you so much for everything you do, Cfyz.
-
I’ve been using it for The Red Prison for a few months now after being a libtcod devotee for years. I had a few tough days transitioning over but it’s been fantastic overall. Now that I’ve got it working, it feels easy to use and has everything I could need for a roguelike.
-
I'm converting my game from libtcod to bearlibterm (python), and I've run into an issue. Is there a function in bearlibterm to return the keycode or character associated with a keystroke, similar to what I can do with chr(event.sym) in tcod? Seems super tedious to build a function to convert all of the bearlibterm constants back into keycodes, but I can't figure out another way to do it.
In case it matters, I'm using a CP437 font (though it seems like that's an output issue and shouldn't matter for detecting input).
-
If I understand your question properly, this is what my code on that point looks like:
key = blt.read()
if blt.check(blt.TK_CHAR):
key_char = chr(blt.state(blt.TK_CHAR))
else:
key_char = None
And then I test the key and key_char variables like this:
if key == blt.TK_KP_1 or key_char == 'b':
-
If I understand your question properly, this is what my code on that point looks like:
key = blt.read()
if blt.check(blt.TK_CHAR):
key_char = chr(blt.state(blt.TK_CHAR))
else:
key_char = None
And then I test the key and key_char variables like this:
if key == blt.TK_KP_1 or key_char == 'b':
Yep, that's exactly what I was looking for, thanks so much!
-
I'm getting a weird issue with blt in python where my fonts are basically just blocks of color. Here's an example:
(https://i.ibb.co/4Fj4HKR/blt.png) (https://imgbb.com/)
(https://i.ibb.co/Pj8km06/tcod.png) (https://imgbb.com/)
The one just showing blocks of white is blt, the other is the same code (more or less) in libtcod. I've tried setting background and foreground manually and also using puts instead of printf. Nothing changes unless I change the fireground color, and then I get a new colored block instead of white. As an example, here's the block of code used to render the top line of both images:
BLT:
terminal.printf(ox, oy, '[color=white][bg_color=black]Hit Location')
terminal.printf(ox+15, oy, 'DERM')
terminal.printf(ox+20, oy, 'TIS')
terminal.printf(ox+25, oy, 'BONE')
Libtcod:
libtcodpy.console_print_ex(con, log.x, 0, libtcodpy.BKGND_NONE, libtcodpy.LEFT, 'Hit Location')
libtcodpy.console_print_ex(con, log.x+15, 0, libtcodpy.BKGND_NONE, libtcodpy.LEFT, 'DERM')
libtcodpy.console_print_ex(con, log.x+20, 0, libtcodpy.BKGND_NONE, libtcodpy.LEFT, 'TIS')
libtcodpy.console_print_ex(con, log.x+25, 0, libtcodpy.BKGND_NONE, libtcodpy.LEFT, 'BONE')
Any help is greatly appreciated. I feel like I'm having a heck of a time figuring out how to do some fairly basic things in BLT.
-
Have you tried playing around with layers and composition? It can often be easier to turn composition off to make things simpler and I know that it was the cause of a few problems for me and I only turned it back on once I had specific plans for it. One potential issue you might have is that you’re effectively overwriting characters but it’s a bit hard to tell from what you’ve posted.
-
Have you tried playing around with layers and composition? It can often be easier to turn composition off to make things simpler and I know that it was the cause of a few problems for me and I only turned it back on once I had specific plans for it. One potential issue you might have is that you’re effectively overwriting characters but it’s a bit hard to tell from what you’ve posted.
Thanks. I'm using the default values (according to docs 'TK_OFF'), but I explicitly set it and checked it as well in my init code and it does appear to be off:
def create_terminal(w,h) -> object:
term = terminal.open()
terminal.set('window: size='+str(w)+'x'+str(h)+',title=Crimson Sands; font: fonts\\cp437_8x8.png, size=8x8, codepage=437')
terminal.composition(terminal.TK_OFF)
terminal.refresh()
if terminal.state(terminal.composition) == terminal.TK_OFF: print('Comp Off')
return term
-
OK, I figured it out, and the reason is so weird (to me, anyway) that I'm posting it in case others run into it. What I was doing was instantiating and running two separate terminals while I converted, one through libtcod and one through blt, using the same inputs but different functions. Why this would interfere with each other, I do not know, but it does. If I comment out the 'render all' function for either one, the other works perfectly.
-
Back after 3 years!
Just a note if you are using BearLibTerminal in Python and the PyCharm IDE:
If you add BearLibTerminal to your Python 3.x installation via 'python -m pip install BearLibTerminal'
you'll find some oddball behavior in importing it especially in a PyCharm project. The easiest fix
I've found is simply to use the following import statement:
from bearlibterminal import terminal as blt
and then if/when PyCharm shows an error on terminal, just right click and tell it to ignore it.
I believe the problem is with PyCharm's overly strict interpretation of Python syntax and import behavior.
Hope this helps,
Brian aka Omnivore
PS: I was being an idiot - had multiple possible imports from old install and used Pascal casing *gah*
-
Has anyone done a CFFI wrapper for BearLibTerminal with PyPy?
The ctypes interface is rather slow with the PyPy JIT. I'm doing a variant on the Python Roguelike Tutorial and at equivalent of step 3 in the libtcod tutorial, repeat key can outrun the game loop and fill the input to where you get a bunch of moves after you release the movement key.
Haven't profiled it yet, nor taken steps to remove unnecessary calls to (for example) terminal.color or buffered rows as text with color markers, etc - all of which would help if ctypes is indeed the culprit and a CFFI wrapper isn't commonly available.
Of course all this assumes I finish writing the tutorial- for personal use an existing CFFI wrapper would save me some time and most likely a bit of head scratching.
Thanks,
Omnivore
-
Has anyone done a CFFI wrapper for BearLibTerminal with PyPy?
Sorry for the late reply. I did a CFFI wrapper for bearlibterminal a while ago, but never published it. I just uploaded it, if you want to try it out.
https://github.com/ibatugow/blt_samples/blob/master/Python/bearlibterminal/terminal-cffi.py (https://github.com/ibatugow/blt_samples/blob/master/Python/bearlibterminal/terminal-cffi.py)
Just replace terminal.py with the cffi version and it should work. It's only a little faster in CPython, but vastly faster in pypy.
-
Is there any possibility of compiling this for mac as well? Would any changes to the source code be required?
help to see my profile http://27.124.27.111/ (http://27.124.27.111/) ;D ;D ;D ;D
-
This may be a strange question, but hopefully someone can give me a hand. I am currently using bearlibterminal to create a game, but I'm not making a roguelike game. I want to make a text based adventure game, and i really like blt's user input handling and it's simplicity. But I was wondering if there was a way to draw more than just tile- or cell-based objects like characters and sprites.
TL;DR
Is there was a way to output more complicated shapes, such as sine waves or circles, to the terminal?
I understand that this probably wasn't the intented use for blt, but I thought it was worth a shot to ask.
-
It's probably not easily suited to that but there's two possible ways:
1. Implement a font made up of a wide range of pieces which could be put together by the game to resemble that data. That might work for circles and static content like that but it would have some real problems with things like sine waves and at best you'd probably have to only display an approximation of the data. I don't think this would be the best approach.
2. Implement a font made up of a single large character and update this every time you need it to display a custom image. For instance, I use this approach for my mini map - I build an x, y array of pixels based off my map data and what's been explored by the player, write that array to a png file every turn, update the custom font every turn and then display that large single character as the map. It's not the most efficient method but it works. I do a similar thing for my title screen where I display an image which covers the whole screen.