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

Aukustus

  • High Priest
  • ****
  • Posts: 431
    • View Profile
    • The Temple of Torment
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #240 on: August 02, 2017, 12:26:43 AM »
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:
Code: [Select]
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.
« Last Edit: August 02, 2017, 12:29:27 AM by Aukustus »

Aukustus

  • High Priest
  • ****
  • Posts: 431
    • View Profile
    • The Temple of Torment
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #241 on: August 02, 2017, 12:45:31 AM »
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.

Cfyz

  • Bishop
  • ***
  • Posts: 190
    • View Profile
    • Email
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #242 on: August 02, 2017, 03:25:37 PM »
Quote from: Aukustus
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:
Code: [Select]
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 =).

Quote from: Aukustus
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 to not replace tiles), there is also one less known feature that may be particularly useful here: layer crop region. 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:
Code: [Select]
Terminal.Set("window: size=" + Constants.ScreenWidth.ToString() + "x" + Constants.ScreenHeight.ToString() + "; ...");may be
Code: [Select]
Terminal.Set("window: size={0}x{1}; ...", Constants.ScreenWidth, Constants.ScreenHeight);

Aukustus

  • High Priest
  • ****
  • Posts: 431
    • View Profile
    • The Temple of Torment
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #243 on: August 02, 2017, 08:19:43 PM »
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 to not replace tiles), there is also one less known feature that may be particularly useful here: layer crop region. 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:
Code: [Select]
Terminal.Set("window: size=" + Constants.ScreenWidth.ToString() + "x" + Constants.ScreenHeight.ToString() + "; ...");may be
Code: [Select]
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.
« Last Edit: August 02, 2017, 08:26:09 PM by Aukustus »

Cfyz

  • Bishop
  • ***
  • Posts: 190
    • View Profile
    • Email
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #244 on: August 03, 2017, 05:18:15 PM »
Quote from: Aukustus
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:
Code: [Select]
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:
Code: [Select]
int previous_key = Terminal.State(Terminal.TK_EVENT);
while (Terminal.Peek() == previous_key)
    Terminal.Read();

Aukustus

  • High Priest
  • ****
  • Posts: 431
    • View Profile
    • The Temple of Torment
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #245 on: August 03, 2017, 08:03:37 PM »
Quote from: Aukustus
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:
Code: [Select]
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:
Code: [Select]
int previous_key = Terminal.State(Terminal.TK_EVENT);
while (Terminal.Peek() == previous_key)
    Terminal.Read();

Code: [Select]
            int key = Terminal.Read();

            if (Terminal.Peek() != key)
            {

Seemed to the trick. I've got no idea how it works, but it works :).