Angband Code Interface to GUI

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • takkaria
    Veteran
    • Apr 2007
    • 1951

    #46
    Originally posted by meeshoo
    Well, looks like I just found myself in front of an impenetrable wall . Making the application a multithreading one and synchronizing threads is a huge pain, and it's quite impossible to make because multithreading is quite platform specific. The problem here is that the main loop of the game is not done in the main function of each platform but rather in the play_game() within dungeon.c. That cuts access to anything after the "while(TRUE)" section is entered, basically reducing all communication to input and some events to update the output screen buffer.

    Here is the solution I thought of (as a first step):

    The play_game() function is formed of 3 main parts: the initialization part, where the user starts the game and so on, the main loop part for playing the game and the last part (smaller) containing the cleanup code.

    The solution would be to split the play_game into 3 different methods:

    init() - do the initialization stuff
    play_game_round() - one iteration, basically the code from the while(TRUE) loop
    destroy() - do the cleanup stuff.

    Then, from all platform-specific main functions we replace

    [snip]
    What do you think about such a change, would it be difficult to implement (in terms of dungeon.c)?
    Sounds fine. I'd rather keep a play_game_text() function which does everything play_game() does (e.g. init(), plays rounds, destroys), to make updating all the non-3d ports UIs less of a hassle, though.

    Also, play_game()'s loop is not actually the inner loop of the game. dungeon() is where input/update is dealt with turn-on-turn,. I'll be working on refactoring this myself at some point, but any patches would be appreciated.
    takkaria whispers something about options. -more-

    Comment

    • meeshoo
      Scout
      • Jan 2009
      • 27

      #47
      Originally posted by takkaria
      Sounds fine. I'd rather keep a play_game_text() function which does everything play_game() does (e.g. init(), plays rounds, destroys), to make updating all the non-3d ports UIs less of a hassle, though.

      Also, play_game()'s loop is not actually the inner loop of the game. dungeon() is where input/update is dealt with turn-on-turn,. I'll be working on refactoring this myself at some point, but any patches would be appreciated.
      Well, I could just let play_game as it is (without changing names) and just add the other functions, no problem from that point of view.

      What exactly does the play_game() function if it is not the main loop, it is just a state machine that gets the user to start the game and then checks for any player events to handle? Anyway, I'll take a closer look at dungeon.c as it looks it's the place where all "interesting things" happen

      Comment

      • meeshoo
        Scout
        • Jan 2009
        • 27

        #48
        Ok, I've split all the functions above and the game still works , and I was able to move the main loop into the "main" function of the game, using both a split version of dungeon() and play() game (nested "while cycles").

        But now another question here: How often does the original "while(TRUE)" section within dungeon() function is executed? Does it run in real time or it's just once per turn or how does it work? Because if that loop is a "lazy" one and does not work in real time I will still have to turn back to a multithreading system, and if there is any possibility I don't want to go there, because usually multithreading always results in synchronization problems headaches.

        After I get rendering in 3d in realtime while playing the game in the original window I will send you the modified dungeon.c file, but for now I'm not sure my changes there are over because the 3d window updates only now and then, which led me to the question above.

        Comment

        • takkaria
          Veteran
          • Apr 2007
          • 1951

          #49
          Originally posted by meeshoo
          Ok, I've split all the functions above and the game still works , and I was able to move the main loop into the "main" function of the game, using both a split version of dungeon() and play() game (nested "while cycles").

          But now another question here: How often does the original "while(TRUE)" section within dungeon() function is executed? Does it run in real time or it's just once per turn or how does it work? Because if that loop is a "lazy" one and does not work in real time I will still have to turn back to a multithreading system, and if there is any possibility I don't want to go there, because usually multithreading always results in synchronization problems headaches.
          Well, it waits for input when something calls inkey()—so yeah, it's a "lazy" loop. Though if you register event handlers, then you get updates from inside the loop.
          takkaria whispers something about options. -more-

          Comment

          • meeshoo
            Scout
            • Jan 2009
            • 27

            #50
            Hello there, back again with some more questions

            I have made some progress overall, I have designed the messages list (expandable, scrollable and with an interesting way of viewing them) and now I'm looking forward to how I should bring input from the 3d window to the game. Giving the fact that now I have a split game loop I plan to do the following:

            All input in the 3d window will be queued in a buffer. Angband should query this queue and take data for processing every now and then, or just wait until there is something in the queue. Any idea how can I do this?

            What I have now in main-win.cpp is:
            Code:
                start(); // init ogre
            
                /* Play the game */
            	//play_game();
            
                play_game_init(); //character creation and stuff
            
                //start the rendering thread
                HANDLE hThread = CreateThread(NULL, 0, renderLoop, NULL, 0, NULL);
            
                do
                {
                    //initialization part of the dungeon
                    dungeon_init();
                    //loop through the main game loop (once for each while cycle)
                    while(dungeon_loop())
                    {
                   
                    }
                }while(play_game_round());
            
                play_game_close();
            
                stop();
            
                WaitForSingleObject(hThread, 0);
                CloseHandle(hThread);
            Now from what I've seen, the dungeon_loop (which is one cycle of the while(TRUE) loop in dungeon() function) calls for some player processing that uses inkey (which I believe is waiting in turn for input). Do I have to split that too and put it here in order to take the control over the input process?
            (some more deep info about the input system will be also very helpful).

            Thanks

            Comment

            • takkaria
              Veteran
              • Apr 2007
              • 1951

              #51
              Originally posted by meeshoo
              Hello there, back again with some more questions

              I have made some progress overall, I have designed the messages list (expandable, scrollable and with an interesting way of viewing them) and now I'm looking forward to how I should bring input from the 3d window to the game. Giving the fact that now I have a split game loop I plan to do the following:

              All input in the 3d window will be queued in a buffer. Angband should query this queue and take data for processing every now and then, or just wait until there is something in the queue. Any idea how can I do this?

              What I have now in main-win.cpp is:
              Code:
                  start(); // init ogre
              
                  /* Play the game */
              	//play_game();
              
                  play_game_init(); //character creation and stuff
              
                  //start the rendering thread
                  HANDLE hThread = CreateThread(NULL, 0, renderLoop, NULL, 0, NULL);
              
                  do
                  {
                      //initialization part of the dungeon
                      dungeon_init();
                      //loop through the main game loop (once for each while cycle)
                      while(dungeon_loop())
                      {
                     
                      }
                  }while(play_game_round());
              
                  play_game_close();
              
                  stop();
              
                  WaitForSingleObject(hThread, 0);
                  CloseHandle(hThread);
              Now from what I've seen, the dungeon_loop (which is one cycle of the while(TRUE) loop in dungeon() function) calls for some player processing that uses inkey (which I believe is waiting in turn for input). Do I have to split that too and put it here in order to take the control over the input process?
              (some more deep info about the input system will be also very helpful).

              Thanks
              The best deep info you can get about the input system is just to read through the input system. It's quite icky in places and messy but that's the best place to get information. However...

              You can't really split out inkey(), since the game just isn't modelled in that way. inkey() calls Term_inkey(), though, which then calls the platform-specific "xtra" hook. That's where you can inject keypresses.
              takkaria whispers something about options. -more-

              Comment

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