Deepening the status line troubles

Yeah, that is what I did. I changed printing.i6 to that. With the changed code, saying ‘deepen the status line to whatever’ makes it grow to whatever, then it snaps back to 1 again right after. Basically a default of 1 remains in place and actually takes over whatever depth you ask it for.

  • Wade

Okay, now I’ll have to try actually testing a suggestion, rather than guessing from the code (this may take a few days) …

Oops, silly mistake. Drop the curly brackets:

glk_window_open(win.ref_number, GetPos(pos,win), statuswin_cursize, wintype_TextGrid, GG_STATUSWIN_ROCK);

Curly brackets are only needed when passing a variable from I7 to I6. I’m not sure how they ended up in the I6 code block. Also, use this call:

To initialize/initialise the/-- status window with parent (win - a g-window) position (pos - g-window-position) : (- InitStatusGWindow({win}, {pos} ); -)

(Fixes some silly little typing errors.)

–Erik

Well sir, you have achieved the g-windowising of the status line! The latest code works and you can put the status line above another g-window.

Unfortunately, ‘deepen the status line’ no longer functions after doing this, so the status line is stuck at a height of 1 :laughing:

  • Wade

That’s odd, the code uses the same “statuswin_size” and “statuswin_cursize” variables that the library uses, and it doesn’t change anything about the status window other than its parent, so it ought to work the same way as the standard status line does.

I’m even more puzzled after a cursory (emphasis on cursory) glance at the code. VM_StatusLineHeight sets statuswin_cursize but not statuswin_size. Emily’s “deepen the status line” phrase doesn’t use either variable directly, but does set statuswin_cursize indirectly via VM_StatusLineHeight(). Maybe you should be passing statuswin_cursize into the VM_StatusLineHeight call in Printing.i6t…?

–Erik

Funnily enough I think I already tried that last night when I just mucking around with anything that looked like it might work. But I can verify, in making that change again right now and trying it, that it also gives the outcome of a 1 line status bar which doesn’t respond to ‘deepen’.

  • Wade

As far as I can see, nothing sets statuswin_size. It’s always 1.

Okay, I went back and had a proper look at this, rather than just guessing from the code. I haven’t had time to thoroughly test what I’ve done, but it seems to work …

It seemed best to go back to first principles and try to solve the status line issues with a simple test project, rather than suggesting things for Wade to try on his mega project, where you never quite know what will interfere with what we’re trying to do. The attached should be the source and compiled Glulx game file for a test that starts with an initial status line of 3 lines, which can be changed by entering "status ", where is a number.

Anyway, the source of the original problem is that the status line height is being reset when the status line is updated, which happens in the I6 template routine DrawStatusLine(). In the attached source I’ve copied that out as an I6 inclusion, and simply removed the call to VM_StatusLineHeight(). This isn’t pretty, but at least it seems to work. That will stop the flickering Wade gets, I hope.

While the above should fix the flickering, the next problem is that now the status line starts at 0 lines deep. To get round that, I initialize the I6 variable statuswin_size, which is used when constructing the Glulx status line height to set the initial height. This should be done early enough, as it’s in the “Before starting the virtual machine” rule.

Finally, there’s an action to change the status line height, only called when needed, that ends up calling VM_StatusLineHeight() to change the status line. Since the bogus call to VM_StatusLineHeight() in DrawStatusLine() is gone, the new height specified by this call “sticks”.

Wade, would you check that this works for you on the interpreters that show flickering? If it’s okay it should be possible to figure out how to combine this with Erik’s work to sort the whole mess out.
StatusLine.zip (143 KB)

Hi David. Thanks a lot for doing that. This example runs fine with no flickering and does what it says it will do.

  • Wade

Just realised that we aren’t completely done with this … Wade, what is needed to fix your problems in your actual game? Is importing the replacement DrawStatusLine() from my example to your game enough? Or do I need to get the example working with a status bar generated via Flexible Windows first?

The code I provided uses the standard status line window object, but allows it to be initialized using Flexible Windows wrappers for I6 glk objects and constants (specifically, window references and window-placement constants). It uses statuswin_size to set the depth. So it shouldn’t be necessary to do anything in particular with Flexible Windows, but it might be necessary to tweak the code I provided, or the execution order via your code…

Hi again guys.

I tried combining David’s new code with Erik’s g-windowiser and it seems to hurt the function of both of them.

I’ve put the two together, added a couple of other things and distilled it into a test case demo. If we can make this demo behave (which it certainly isn’t doing at the moment) I should then be able to make the same things work in my big game.

The demo is attached, both source as .txt and a compiled glulx version.

statusline02.zip (190 KB)

The comment for what I’m trying to get the demo to do is at the bottom of the source.

I reckon all the parts are in here now, but there may be ordering troubles and i6 incompatibilities (maybe also including Basic Screen Effects).

  • Wade

Oh my. There are quite a few problems to work through here, I can see. :slight_smile:

Rather than try to sort out Wade’s test project in one go, I’m sticking to my principle of starting with a working project and extending it one step at a time - that way if something doesn’t work I know it’s the last thing I added. Once a project has developed multiple problems I find it very hard to tell if I’m making progress or not in sorting them out.

Anyway, attached is how far I got on the train into work this morning. My example now uses Flexible Windows and Glulx Status Window to give a status line with white text on a green background. In doing this I realised that Erik’s code did need a small tweak:

glk_window_open(win.ref_number, GetPos(pos,win), statuswin_cursize, wintype_TextGrid, GG_STATUSWIN_ROCK); should be

glk_window_open(win.ref_number, GetPos(pos,win) + winmethod_Fixed, statuswin_cursize, wintype_TextGrid, GG_STATUSWIN_ROCK);

Without that extra “winmethod_Fixed”, the call to open a window is interpreted as a status bar 3% of the total window height high, not three text lines high.

The next problem to sort out is to add your “status anchor” window back in. I can see what’s wrong, I just need to think about how to fix it and, rather harder, explain why it doesn’t work at the moment. More to follow …
StatusLine.zip (185 KB)

Haha!

Thanks again. Also now I’m living one of my dreams involving other people working on things for me while on a train.

  • Wade

Okay, I think we’re just about there - see the attached I7 source and compiled Glulx game. In the game you can enter “status n” where n is 1, 2 or 3 (anything else is interpreted as 3) and “toggle” to turn the status line off (if it’s on) or back on (if it’s off). I haven’t tested this with many different interpreters (and embarrassingly it’s shown up some problems in the Windows I7 front-end’s Game tab’s handling of colours) so please check that it works for you.

Right, so what did I change?

The first thing was the order in which windows were being opened. You had the “statusanchor” window as the parent of the status window, but at the same time wanted the statusanchor and status windows to have fixed heights, with the main text window occupying the rest. That’s not going to work, due to how Glk handles window splitting and sizing, which is a rather elegant and powerful system, but not exactly easy to explain. It’s covered in detail in sections 3.1 and 3.2 of Zarf’s Glk specification (see http://www.eblong.com/zarf/glk/glk-spec-074_3.html) and I’ve tried to write a few paragraphs that explains it more simply, but I haven’t succeeded.

Your code started from the main window: it split that to add the statusanchor window above it, and then split the statusanchor window to add the status window above that. The problem with doing it like that is that that first split, adding the statusanchor window, fixes how the space will be shared between the main text window and whatever is above it: the result is that both the statusanchor window and the status window end up having to occupy the 20 pixels specified in the first split which is, in short, not enough. One way to think about it would be to imagine drawing the splits on a blank piece of paper, starting from an empty rectangle: each time we open a new window we’re choosing a window to split, and then drawing a vertical or horizontal split to divide up its space, but we are not stealing space from any other window.

The solution is to change the order of these window splits: split the status window from the main text window, then the statusanchor window from the main text window, and finally the textmap window from the main text window. This does affect opening and closing the status window (which we’ll get to) but does mean that the windows arrange in the desired way. As I say, I wish I could explain why more simply than the Glk specification, but … Anyway, doing that gives us windows that appear in the correct positions and relationships.

The next thing to be looked at is the use of Basic Screen Effects to populate the status line (“Rule for constructing the status line: …”). There’s nothing wrong with using Basic Screen Effects for this, but the important thing to understand is that when this rule calls “fill the status bar with …” it will always reset the status window height to however many rows are in the supplied table. This is why when you used this in your example code, it overwrote any status window height that had been set by a call to VM_StatusLineHeight().

To get round this, I’ve assumed that what you intend to do is to switch between three tables for the status window, each with a different number of rows. My code has a number variable called “status-depth”, and this is used in the status line construction rule to decide which table to use. Since we’re using this to set the status window height, all the junk in the example calling VM_StatusLineHeight() has been deleted.

The final thing was your desire to turn the status window on and off. The only problem here is that my re-ordering of how the windows are created means that the status window cannot be re-opened by splitting from either the statusanchor window or the main text window: instead it must be split from the “pair window” that contains both of those two windows. Again, the reason for this is obvious if you understand section 3 of the Glk specification, and not otherwise. Fortunately we can easily handle this by tweaking Erik’s code from “Glulx Status Window Control”, which in my example is the I6 method InitCustomStatusWindow() and the rule that calls it. This relies on the fact that, due to where we want the status bar to be, it’s always opened or re-opened by splitting the root Glk window, which we get with the Glk call glk_window_get_root().

I think that covers everything. Phew!

It was either that or write a design document for work …
StatusLine.zip (187 KB)

Thanks David. I tried your test and you have solved all of the problems.

I was aware that the “fill the status bar” routine included the “deepen the status line” routine, and had modified that in the big project, but I just took the code back to a simpler state for the demonstration project.

I also understood the windows slicing stuff in general thanks to the explanation in Flexible Windows, though it didn’t get into this issue of the Pair Window you brought up, which turns out to be part of the solution here.

Again, massive thanks, and to Erik. I could never have sorted all this out on my own, though I gave it a redhot go.

-Wade

Glad to hear it works :slight_smile: