Author Topic: BearLibTerminal: a pseudo-terminal window library for roguelike  (Read 283552 times)

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
BearLibTerminal: a pseudo-terminal window library for roguelike
« 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. 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:
Code: ("c") [Select]
#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;
}



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 =)
« Last Edit: February 27, 2014, 08:26:17 AM by Cfyz »

koiwai

  • Rogueliker
  • ***
  • Posts: 99
  • Karma: +0/-0
    • View Profile
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #1 on: February 27, 2014, 05:39:37 AM »
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)
Code: [Select]
/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.

Quendus

  • Rogueliker
  • ***
  • Posts: 447
  • Karma: +0/-0
  • $@ \in \{1,W\} \times \{1,H\}$
    • View Profile
    • Klein Roguelikes
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #2 on: February 27, 2014, 07:50:25 AM »
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.

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #3 on: February 27, 2014, 08:21:42 AM »
Quote from: koiwai
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.

Quote from: koiwai
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.

Quote from: koiwai
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.

Quote from: koiwai
I did not find anything specific about the license, but it's good to have one.
Quote from: Quendus
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.

Quendus

  • Rogueliker
  • ***
  • Posts: 447
  • Karma: +0/-0
  • $@ \in \{1,W\} \times \{1,H\}$
    • View Profile
    • Klein Roguelikes
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #4 on: February 27, 2014, 08:30:41 AM »
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?

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #5 on: February 27, 2014, 08:49:30 AM »
Quote from: Quendus
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 be
Code: [Select]
terminal_set("input.events=keypress+keyrelease+mousescroll");and the event itself is TK_MOUSE_SCROLL.
« Last Edit: February 27, 2014, 08:52:10 AM by Cfyz »

Z

  • Rogueliker
  • ***
  • Posts: 905
  • Karma: +0/-0
    • View Profile
    • Z's Roguelike Stuff
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #6 on: February 27, 2014, 02:37:58 PM »
Is there any relation to Bear who was a long time rgrd regular (I don't know if he is still posting there) and a RogueTemple poster?

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #7 on: February 27, 2014, 03:25:06 PM »
Quote from: Z
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.

koiwai

  • Rogueliker
  • ***
  • Posts: 99
  • Karma: +0/-0
    • View Profile
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #8 on: February 27, 2014, 04:54:08 PM »
Thank you for the clarification regarding the license.

Quote from: koiwai
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.

Quendus

  • Rogueliker
  • ***
  • Posts: 447
  • Karma: +0/-0
  • $@ \in \{1,W\} \times \{1,H\}$
    • View Profile
    • Klein Roguelikes
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #9 on: February 27, 2014, 07:37:24 PM »
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:
Code: [Select]
bl::terminal_refresh();
blt::terminal_refresh();
bl::refresh();
blt::refresh();

Quendus

  • Rogueliker
  • ***
  • Posts: 447
  • Karma: +0/-0
  • $@ \in \{1,W\} \times \{1,H\}$
    • View Profile
    • Klein Roguelikes
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #10 on: February 28, 2014, 11:14:09 AM »
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. 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).

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #11 on: March 01, 2014, 12:21:22 AM »
Updated the library to version 0.9.8: 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.

Quote from: Quendus
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).

Quote from: Quendus
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.

Quote from: Quendus
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).

Quote from: Quendus
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:
Code: [Select]
terminal_setf("window: size=%dx%d, cellsize=%dx%d, title='%s'", TERM_WIDTH, TERM_HEIGHT, CHAR_WIDTH, CHAR_HEIGHT, TITLE_STR.c_str());
Quote
// 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.
« Last Edit: March 01, 2014, 12:24:43 AM by Cfyz »

Quendus

  • Rogueliker
  • ***
  • Posts: 447
  • Karma: +0/-0
  • $@ \in \{1,W\} \times \{1,H\}$
    • View Profile
    • Klein Roguelikes
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #12 on: March 01, 2014, 05:07:28 AM »
Thanks for the comments. I didn't see terminal_setf when I looked at the API and samples. It's a much better solution.

Quendus

  • Rogueliker
  • ***
  • Posts: 447
  • Karma: +0/-0
  • $@ \in \{1,W\} \times \{1,H\}$
    • View Profile
    • Klein Roguelikes
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #13 on: March 07, 2014, 01:11:06 AM »
Is there any possibility of compiling this for mac as well? Would any changes to the source code be required?

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #14 on: March 07, 2014, 11:35:28 AM »
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 =)