ToME 2.4.0-ah released

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • AnonymousHero
    Veteran
    • Jun 2007
    • 1393

    #46
    Originally posted by t4nk
    Code:
    void al_set_target_bitmap(ALLEGRO_BITMAP *bitmap);
    "This function selects the bitmap to which all subsequent drawing operations in the calling thread will draw to. To return to drawing to a display, set the backbuffer of the display as the target bitmap, using al_get_backbuffer. As a convenience, you may also use al_set_target_backbuffer."
    That's how it's done in low level APIs (OpenGL, DirectX). Of course, it's not the only possible way of doing things, but it's pretty standard and it doesn't seem overly crazy to me.
    ... but in e.g. Allegro (which is obviously built on top of whatever the platform supports, in my case OpenGL) they do kind of the same, but there's actually a good reason for it, namely that all high-performance graphics APIs are done that way. Why? Well, graphics hardware functions very differently to a regular computer and you (the programmer) really need to be aware of that and think in terms of the underlying mechanism -- if you e.g. try to blit from several hundred character-sized textures to the display, then you're going to have a bad time. (What you must do is create a "font atlas" which contains all the characters and use that for blitting from. Etc. Generally speaking 'switching states' is slow on GPUs because of very high latency. You really just want to fill the pipeline.)

    The problem is much lesser in programming graphics because the "display list" only sticks around for a single frame and then you start over. (Also known as "immediate mode".) For a game like Angband, that's pretty simple to manage because the scope is very limited -- I think the entirety of the code which does this in my T2 branch is about 50-100 lines? I'm pretty sure I can eventually get rid of the "damage" tracking that the term structure does -- leaving me with a simple 2D array of char+attribute... which might as well be inside the frontend code. (In fact the frontend code already has such a structure because I want it to be able to redraw without having to call back into the term code.)

    Just to be clear: There are much better ways to manage the global drawing context which al_set_target_bitmap or whatever just hide under the carpet, such that you could actually have the compiler check your work, but they require pretty advanced type systems which C in the very least doesn't really support. They'd also get pretty hairy in C++, I imagine. Since most of the graphics APIs target C or C++, that's what we get.

    Originally posted by t4nk
    When working on textui2, I came to the conclusion that it's useful to divide the Terms into two kinds; permanent (map, messages, sidebar, monster list) and temporary (inventory, options, knowledge menu - the stuff that goes away when the user presses ESC). Organizing temporary terms as a stack, with the top of the stack being the current target of rendering operations, is very convenient (and there were no problems with using this architecture while writing ncurses frontend). OTOH, permanent terms don't need to be on the stack.
    Interesting -- I hadn't thought of doing it this way, but I think I'm going for a design where there's no "current target". All drawing methods must have an explicit target term where they will draw. (That will usually come from a formal function parameter, but obviously there will a top-level dispatching coming from the "window options", e.g. "what do I draw in which window".)

    Originally posted by t4nk
    I'm actually (very slowly) writing an Angband-insired roguelike (in D ). So I've been thinking quite a bit about the architecture of the IO subsistem lately. The Term as an ADT (a two dimensional array of colored characters that keeps track of their updates since the last render) is surely worth keeping, and so is the stack of Terms. Anyway, hopefully you'll proceed with your ideas - I'm adding your TOME repo to bookmarks
    I'm not saying that the "2D grid" is a bad abstraction -- it's the intermingling of concerns of the event loop, drawing to the screen and keyboard input into one big ball of mud where it's really unclear what's responsible for what (and how 'many' there are of each).

    I'm not convinced in any way that tracking "damage" at a single-character level is a useful thing -- just redraw from scratch for every frame[1]. An even reasonably modern GPU should be able to draw Angband at several hundred (if not thousands) of FPS.

    (The exceptions here would be old frameworks where this type of drawing is not really supported very well. My experiences in SDL2.x and Allegro 5 suggest that at least there's no problem there.)

    [1] Here's another mismatch between that UI code and the modern world. You really want do just draw on every frame (if there have been any changes) and the Angband/T2 code contains sleep, etc. in various places in the code. These could end up being pretty non-trivial to avoid because changing the structure around an event loop might end up being difficult... I'm not quite giving up yet because it might be reasonable to with coroutines or similar.

    EDIT: Anyway, this is ranting at this point... .

    Comment

    • Nick
      Vanilla maintainer
      • Apr 2007
      • 9639

      #47
      Originally posted by t4nk
      When working on textui2,
      Veering temporarily off-topic (sorry AH), I'm really sorry that is not incorporated in V yet - both takkaria and I have thought about it and got no further than that. I'm tempted to say I'll add that to the list of things for the next version...
      One for the Dark Lord on his dark throne
      In the Land of Mordor where the Shadows lie.

      Comment

      • AnonymousHero
        Veteran
        • Jun 2007
        • 1393

        #48
        @Nick Heh, I think it's just descended into ranting at this point, so a break from that is nice .

        I definitely agree about textui2, btw. It looked really nice.

        Comment

        • t4nk
          Swordsman
          • May 2016
          • 336

          #49
          I'm not saying that the "2D grid" is a bad abstraction -- it's the intermingling of concerns of the event loop, drawing to the screen and keyboard input into one big ball of mud where it's really unclear what's responsible for what (and how 'many' there are of each).
          Well, one thing to note is that there are only two situations when the screen must be redrawn:
          1) When the game is waiting for user input (so the user should see the latest state of the game)
          2) When some animation is played

          Overly frequent screen redraws is the number one cause of slowdowns in textui1 (and requires hacks to work around), since most displays can be redrawn no more than 60 times per second. Thus, there is some synchronization between handling events and drawing to the screen.

          I'm not convinced in any way that tracking "damage" at a single-character level is a useful thing -- just redraw from scratch for every frame[1]. An even reasonably modern GPU should be able to draw Angband at several hundred (if not thousands) of FPS.
          It depends. SDL2's high-level API is too slow for that (and I did use font atlases - see main2-sdl2:make_font_cache()). You might also want to (eventually) write a frontend for terminal emulator using termbox or some such... Anyway, z-term.c's approach to that is a bit too complicated, I currently use
          Code:
          struct TermCell
          {
              dchar codepoint = 0;
              RGBA foreground = Color.white;
          
              // Hack - the biggest codepoint is 0x10_FFFF, which is 21 bits;
              // that leaves 11 more bits in a dchar, which we use for bitflags.
              // The flags are used only in this module; don't forget to clear them.
          
          private:
          
              enum _Mask : uint
              {
                  dirty = 1 << 31,
                  clear = 0x1F_FFFF,
              }
          
              TermCell dirty() const pure
              {
                  return TermCell(this.codepoint | _Mask.dirty,
                                  this.foreground);
              }
          
              TermCell clear() const pure
              {
                  return TermCell(this.codepoint & _Mask.clear,
                                  this.foreground);
              }
          
              bool isDirty() const pure { return this.codepoint & _Mask.dirty; }
              bool isClear() const pure { return (this.codepoint & _Mask.clear) == this.codepoint; }
          }
          Veering temporarily off-topic (sorry AH), I'm really sorry that is not incorporated in V yet - both takkaria and I have thought about it and got no further than that. I'm tempted to say I'll add that to the list of things for the next version...
          Well, ping me if you decide to do that I recall there were some updates to ui-display.c and some other things. Anyway, textui2 didn't go to waste after all - I'm now finding it useful for remembering how SDL2 works

          Comment

          • Gwarl
            Administrator
            • Jan 2017
            • 1025

            #50
            Bump. If we can get user directory command line arguments back this week, we'll have a competition next month.

            Comment

            • AnonymousHero
              Veteran
              • Jun 2007
              • 1393

              #51
              Originally posted by Gwarl
              Bump. If we can get user directory command line arguments back this week, we'll have a competition next month.
              Unfortunately, I'm way too busy at the moment .

              I've added an issue for now, though: https://github.com/tome2/tome2/issues/30

              Comment

              • Cuboideb
                Adept
                • May 2020
                • 196

                #52
                Hello, I have many requests for porting ToME to android. Do I need some kind of authorization from darkgod or the team that created 2.4.0 ? I wrote to darkgod in the tome 4 page and the forums, but got no response.

                BTW, thank you for upgrading the code. It seems that you did a lot of work!

                Comment

                • KesTheHammer
                  Apprentice
                  • Feb 2021
                  • 50

                  #53
                  Originally posted by Cuboideb
                  Hello, I have many requests for porting ToME to android. Do I need some kind of authorization from darkgod or the team that created 2.4.0 ? I wrote to darkgod in the tome 4 page and the forums, but got no response.

                  BTW, thank you for upgrading the code. It seems that you did a lot of work!
                  Any chance of playing this through Termux?

                  I've played frog through Termux - but I am not a Linux user, so trying to figure out how to install it is beyond my capabilities.

                  Comment

                  • fiery_mews
                    Scout
                    • Sep 2020
                    • 26

                    #54
                    Originally posted by KesTheHammer
                    Any chance of playing this through Termux?

                    I've played frog through Termux - but I am not a Linux user, so trying to figure out how to install it is beyond my capabilities.
                    Yes, it works in Termux - IIRC I submitted a (very small) patch at one point to ensure this. For a while I regularly played ToME 2 on a Pixel C.

                    Edit: You'll want to install a compiler (probably clang), make, cmake, boost, and ncurses. (Be warned that boost takes up a LOT of space.) After that you can follow the build instructions on the Github page as usual. Note that some of the controls may be a bit hinky if you're used to the Win32 or X11 interfaces.

                    Comment

                    Working...
                    😀
                    😂
                    🥰
                    😘
                    🤢
                    😎
                    😞
                    😡
                    👍
                    👎