Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Cfyz

Pages: 1 [2] 3 4 ... 13
16
Quote from: The Saber Cat
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. 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
Code: [Select]
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.

17
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.

18
Quote from: Elronnd
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'.

19
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. 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.

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

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

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

22
Quote from: Saafris
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 (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 to manage available extensions. Your code just have to be ready for features not being there, like any other graphics application.

23
Quote from: Saafris
It sounds like interacting with BearLib's layers would be more difficult and involved?
A bit. The Terminal.cpp, line 2054 is where layers are drawn and same file, around line 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.

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

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


25
The 'official' python binding follows the library API fairly closely. The simple snippet would probably be something along the lines:
Code: [Select]
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

26
Quote from: Elronnd
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 =).

Quote from: Elronnd
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!

27
Programming / Re: Screen Not Refreshing upon Menu Close
« on: February 05, 2017, 11:21:06 PM »
Okay, I've looked over the code and I can point out the source of refreshing problem.

First, there is an unnecessary terminal.read() at the end of handle_keys(). It does not break things explicitly, but forces an additional keypress without any visual feedback after non-move action (e. g. inventory), which is wrong and makes behaviour non-intuitive (and probably making it look like setting fov_recompute not always works).

The menu() function uses layer #2 for its output and clears this layer at the start. I do not know if its intentional, but it also clears walls on the map (which also mostly uses layer #2). But neither of menu-popping actions set fov_recompute flag, therefore next render_all() skips drawing walls entirely and only objects are drawn. This leads to walls not being restored after any menu action until any move action (which does set fov_recompute) is taken.

A few other points:
1. Layering is excessive and inconsistent. Very distinct UI elements like map and menu dialog use the same layer which inevitably leads to collisions. On the other hand really similar elements like map and different objects use several different layers. Why do you even need to put the object in a different layer, whether it is fighter or not? >_<
2. Map drawing in render_all() selects a layer only under a certain condition inside the loop. This will put some of the tiles in whatever layer was selected before, which is fragile.
3. The menu() function uses libtcod.console_get_height_rect() to calculate a size of a string, while output is performed via BLT. This is not correct and is not guaranteed to work as they are totally separate functions of different libraries. BearLibTerminal has its own facilities to measure and auto-wrap text:
Code: [Select]
_, header_height = terminal.measure(header, width=width)  # measure returns a (w, h) tuple
...
terminal.print_(x, y, header, width=width)

I suggest to clean up the layering. Layers are to help with logical grouping of output, not to make it messier >_<, there is no need to put everything in different layers. Probably just three will suffice: #0 for in-game objects (ground, walls, objects, etc.), #1 for basic UI (bars and statuses which are always over the map) and #2 for temporary popups like menus. It would also help to give some meaningful names to layers via constants.

As for TK_RESIZED, there is no easy way to introduce screen resizing with the current loop structure. Since user may resize the window in any moment, the application must be ready to handle the new size and update the whole screen in every game state and every dialog, e. g. in the inventory menu. Which will not work since modal menu() can't update the map layout. The easiest way would be to completely separate rendering from input processing so that the whole screen (map, general UI and dialogs) could be redrawn at any time, even during popup processing. But you'll probably have to rewrite from scratch the whole loop/dialog structure.

28
Quote from: Saafris
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" (lines 42-49) entry in SampleOmni, those circling characters are flying around one spot.

29
Programming / Re: How to handle targets?
« on: January 31, 2017, 02:56:40 PM »
a) You are already trying to do something like that (automatic lifetime management) with your idea of reverse references. But smart pointers are well-tested core part of the language.
b) No one has to be notified. A weak_ptr instance shares reference counter with the original shared_ptr so you always can check if that counter has already hit zero.
Once more, there is no need to actively notify anyone. When you will need the information about target being present or not (when you finally get to updating the NPC), the information is already there in the form of an empty pointer.

30
Programming / Re: How to handle targets?
« on: January 30, 2017, 04:50:48 PM »
That does not look like a question anymore. If you already have a solution and proud of it and it even works, okay, use it. If you want to discuss something instead, please pay attention. (Well, who am I kidding here.)

So the situation is, objects may disappear abruptly so you made a list of reverse references back to actors to inform those actors about disappearences, right? And now you wonder if it is efficient to keep these references thing in every object and asking whether there is a more efficient way to notify actors that their target has expired.

I suggest to take a step back and take another look at the source of the problem: actors noticing that object they are interested in has disappeared. Reverse references is not the only way. If you keep a simple forward reference in a form of a weak_ptr in the actor to the target, your actor NPC will know that the object has disappeared right at its next update step. Without any extra machinery involved.

The passage about IRL was to hint that there is no need to anything inform anyone to notice changes. You just notice changes next time you pay attention to something and see that weak_ptr has expired the object is not where it was.

Pages: 1 [2] 3 4 ... 13