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

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 #120 on: August 08, 2016, 03:16:00 PM »
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.

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #121 on: August 08, 2016, 05:34:18 PM »
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:
Code: [Select]
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.
« Last Edit: August 08, 2016, 05:37:55 PM by Cfyz »

Zireael

  • Rogueliker
  • ***
  • Posts: 604
  • Karma: +0/-0
    • View Profile
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #122 on: August 29, 2016, 05:50:21 PM »
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?

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #123 on: August 29, 2016, 06:14:08 PM »
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. 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.

Zireael

  • Rogueliker
  • ***
  • Posts: 604
  • Karma: +0/-0
    • View Profile
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #124 on: August 30, 2016, 09:11:37 AM »
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?

LisacPisac

  • Newcomer
  • Posts: 9
  • Karma: +0/-0
    • View Profile
    • Email
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #125 on: August 30, 2016, 10:16:22 AM »
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. 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
Code: [Select]
while (key != terminal.TK_Q)
    key = terminal.read()
    if key == terminal.TK_KP_4
        // Something, etc

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #126 on: August 30, 2016, 10:44:54 AM »
Quote from: Zireael
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:
Code: (lua) [Select]
repeat
    key = terminal.read()
    if key == terminal.TK_KP_4 then
        -- do smth
    end
until (key == terminal.TK_Q)

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

« Last Edit: August 30, 2016, 10:47:08 AM by Cfyz »

Zireael

  • Rogueliker
  • ***
  • Posts: 604
  • Karma: +0/-0
    • View Profile
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #127 on: August 30, 2016, 11:03:23 AM »
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.

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #128 on: August 30, 2016, 01:49:23 PM »
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.

Zireael

  • Rogueliker
  • ***
  • Posts: 604
  • Karma: +0/-0
    • View Profile
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #129 on: August 30, 2016, 07:28:12 PM »
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

Code: [Select]
if mode = ASCII then
terminal.print([0x5E])
else
terminal.set("0x5E:tile.png")
terminal print([0x5E)

 ???
« Last Edit: August 31, 2016, 07:55:26 AM by Zireael »

Zireael

  • Rogueliker
  • ***
  • Posts: 604
  • Karma: +0/-0
    • View Profile
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #130 on: August 31, 2016, 07:57:53 AM »
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...

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #131 on: August 31, 2016, 10:09:50 AM »
The library considers forward slash '/' universal and replace it with backslash '\' on Windows. I. e. forward slashes should work everywhere. Like this.

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.

Zireael

  • Rogueliker
  • ***
  • Posts: 604
  • Karma: +0/-0
    • View Profile
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #132 on: August 31, 2016, 10:49:44 AM »
Quote
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
 
Code: [Select]
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:
Code: [Select]
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
Code: [Select]
Actor:init() function Actor:init()
If I use game_dir, what I see in the console is:
Code: [Select]
F:\roguelike\test/gfx/player/racial_dolls/human_m.png
And the bt.log says:
Quote
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.

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #133 on: August 31, 2016, 11:36:29 AM »
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
« Last Edit: September 01, 2016, 08:51:56 AM by Cfyz »

Cfyz

  • Rogueliker
  • ***
  • Posts: 194
  • Karma: +0/-0
    • View Profile
    • Email
Re: BearLibTerminal: a pseudo-terminal window library for roguelike
« Reply #134 on: August 31, 2016, 01:00:19 PM »
Quote from: Zireael
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 worth of them in the terminal.

[Edit]
Quote from: Zireael
unless I can
Code: [Select]
terminal.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.
« Last Edit: September 01, 2016, 08:54:33 AM by Cfyz »