I7 - Glimmr sizing and alignment standards?

For a while I was having a hard time getting elements of a GUI appear in the right “graphics windows” using Glimmr. After getting that done, I have a new problem. How portable is a story that uses a lot of Glimmr stuff? I’m finding that loading my story in different versions of Gargoyle provides different results, and I suspect other glitches with other devices and interpreters.

Here is a summary and visualizations of my issue…

http://jizaboz.blogspot.com/2011/05/glimmr-ui-progress-problems.html

Any thoughts?

You are comparing the 2010 release of Gargoyle on Windows to the 2009 release for Linux. The more recent version contains numerous fixes for graphics and performance, most of which were a direct result of Erik’s input.

Any given build of Gargoyle should display text and graphics the same way regardless of platform. The only platform-specific differences come in the file browser (for save/restore) and keyboard/mouse input (for Unicode characters and clipboard ops).

You will see some differences between the Glk libraries - garglk, WinGlk, and cocoaglk - but for the most part these variations will be legal according to the API spec, if not necessarily convenient for your purposes.

I don’t know what’s going on in your second screenshot but it looks very odd. You might need to post some code so Erik can tell us who owns the bug.

I actually don’t think the issues you identified on your blog are related to different versions of the interpreter, or to Glimmr code. But first, to address the more general concern about portability: As Ben said, we* found and squashed bugs and performance issues in most of the major interpreters/Glk libraries while working on Glimmr. You should get pretty reliable behavior across interpreters if you are using the latest versions of Gargoyle, Windows Glulxe, or Windows Git. Zoom is almost there, but a long-standing bug with color remains to be fixed (your blue boxes will be drawn in red even in the latest version of Zoom). I haven’t tested much with Filfre, but hope to some day soon.

Coming back to your game’s UI: It looks to me like, while the right-hand window uses Glimmr Canvas-Based Drawing’s drawing rule, you have written your own window-drawing rule for the upper window. If that diagnosis is right, you have two options: You can fix your custom rule, or you can just use the Canvas-Based Drawing rule in the upper window. I’d highly recommend the latter option, as it will be quite a bit easier–Glimmr Canvas-Based Drawing automates all of the scaling and redrawing for you, and it can be a challenge to get that stuff right for a bunch of objects otherwise.

Using Canvas-Based Drawing will involve declaring a few different “g-element” objects, associating them with the canvas of the upper window, and specifying their coordinates on that canvas. The drawing rule will then take care of centering the canvas in the window, scaling it to the right size, and ensuring that graphics aren’t repeated. See the Canvas-Based Drawing extension documentation for more info.

Hope that helps!

–Erik

  • By “we”, I mean I reported some bugs, and smarter people than me, like Ben, David Kinder, and Andrew Hunter, fixed those bugs (and more).

Two additional thoughts:

  • The compass rose tutorial on the Glimmr blog (link below) might be a quicker introduction to the way that Canvas-Based Drawing works, if you just want to see whether you want to adopt that approach.

  • You might want to try to add your blog to the Planet IF aggregator–more IF folks are likely to see it that way!

–Erik

Oh, this does help. Thanks guys. I’ve already squashed the graphic window resizing glitch by just making the figure jpeg load as the background of the upper window. I removed most of the simple-graphics window example code I had in; most of which referred to resizing. I’m using 640x480 as the resolution for every scenic picture and just allowing it to resize accordingly so far.

Now comes figuring out where to plug my bars in. “scenic window” is the name of the window above. I’ve created it very much like the “graphics-window” from the compass example. This is the code for the bars which I’m trying to get drawn in that window:

draw a box (r 0 g 0 b 200) in the scenic-window from {160, 10} to {170, 80} with 2 pixel line-weight; draw a box (r 0 g 0 b 200) in the scenic-window from {470, 10} to {480, 80} with 2 pixel line-weight; paint a bitmap text (color g-White) of "LUCIDITY" in the scenic-window at { 133, 90} using Glimmr C&C with dot size 2 px; paint a bitmap text (color g-White) of "ANXIETY" in the scenic-window at { 444, 90} using Glimmr C&C with dot size 2 px;

After reading your posts and doing the changes, I temporarily threw the above code into “When play begins”, but it doesn’t display unless I restart. Plus, one bar still gets over-lapped when resizing. I’ll mess around with that a little more tonight before dinner. I don’t completely understand the g-element concept quite yet, and so far my only instance of it is “The associated canvas of a g-element is usually the graphics-canvas.” which was included in the compass tutorial. At this point I’m scratching my head as to how I add my bars as elements of their own.

Erik, I apologize for not grasping some basic concepts of your system, but I think it’s a great system and I’m slowly but surely learning :sunglasses:

No problem–Glimmr is a complex modular system where each component builds on the next, so it’s not necessarily the easiest beast to approach. I think the fact that you started out using Glimmr Drawing Commands has made learning it harder on you. Glimmr Drawing Commands is for experts only, and to use it independently of Canvas-Based Drawing, you would need to understand both Flexible Windows and the Glulx screen model pretty darn well. To quote from the Glimmr Drawing Commands documentation:

The code you posted is running head-on into the difficulties mentioned in those three points. First, you are mixing direct drawing instructions with automated centering and scaling. This means that, while your scenery images are automatically scaled and centered in the window, your direct drawing instructions are not. The simple coordinates being passed to the box-drawing commands mean that those elements will always display in the same place no matter how the screen is resized. So, while the location image gets centered and scaled, allowing it to look good no matter how the game window is resized, the boxes and bitmaps are always drawn at the same coordinates and at the same size–they do not move or scale. They can be cut off or overlapped when the window is smaller than the size you wrote them for (both of which can be seen in one of your sample screenshots).

Another problem is that you are placing your drawing instructions inside “every turn” and “when play begins” rules. This won’t work as expected–these instructions need to be in Flexible Windows’s “window-drawing” rulebook to function properly. A Glulx window needs to be able to redraw itself whenever the window size changes, whether that’s due to the user changing the size of the game window, or to the screen resolution changing, or to some other factor. If some of the instructions are hidden inside other rules, then the game won’t have access to them when it tries to redraw the window. This is why putting drawing commands in “when play begins” fails miserably–most interpreters automatically redraw windows at least once when there are multiple windows to be laid out. When your drawing commands are in a when play begins rule, they fire once and then are immediately cleared when the window redraws.

What Glimmr Canvas-Based Drawing does is introduce the concept of the “canvas”, which is essentially a separate coordinate system that can be stretched and centered to best fit in the shape and size of the graphics window. CBD also uses an object-oriented strategy to define the what gets drawn; instead of writing “draw a box…”, you define a box object (a g-element) and define it using properties of the element. I think this system is fairly well described by the documentation for the CBD extension as well as the compass rose tutorial on the blog, so I won’t elaborate beyond giving a little example, showing how to present the meters and the scenery image. Before trying this, get rid of your existing drawing instructions, and remove the image as the canvas background (the canvas background actually defines the size of the canvas, which isn’t what’s needed here). I haven’t tested this, so there may be some issues, but it should give you an idea of how the code will be structured:

[code]The scenic-canvas is a g-canvas. The canvas-width of the scenic-canvas is 640. The canvas-height of the scenic-canvas is 190.

Table of Common Color Values (continued)
glulx color value assigned number
meter-box-blue 200

A meter-box is a kind of box primitive. The associated canvas of a meter-box is the scenic-canvas. Some meter-boxes are defined by the Table of Meters.

Table of Meters
box primitive origin endpoint tint line-weight
Lucidity_box {160, 10} {170, 80} meter-box-blue 2
Anxiety_box {470, 10} {480, 80} meter-box-blue 2

The scenery-container is a sprite. The associated canvas is the scenic-canvas. The origin is {195, 0}. The image-ID is Figure of Bridge. [The size of the image file should be 250 pixels wide for this example to work.][/code]

Again, CBD will automatically scale and draw the elements to the window in proper relation to each other, no matter how the window is resized. Note, though, that you do need to define when it should be redrawn, e.g. “Every turn: refresh windows” or “Every turn: follow the window-drawing rules for the scenic-window.”

To make changes to the elements, change their properties, then redraw the window, e.g.:

[code]After looking:
now the image-ID of the scenery-container is the location-image of the location.

Every turn:
refresh windows.[/code]

–Erik

Alright, here’s a screen shot of how it looks now:
http://imageshack.us/m/96/9964/screentgw.jpg

I pretty much re-wrote the code since my last post with the tips given, and works it great! I think I get the mechanics better now, and I’ll worry about repositioning the bars later. The scenic image doesn’t glitch when resizing either. Awesome.

I’m afraid I’m going to need a bit more help though. I’m trying to get the words into it using the same template as the box table. The problem is that I really am not sure how to refer to the painting of the bitmap text. I tried using “A stat-word is a kind of bitmap text.” and it didn’t accept that. Then, I removed the word “text” and it compiled, but from there I don’t know exactly what to put in my table.

When attempting something like:

[code]A stat-word is a kind of bitmap. The associated canvas of stat-word is the scenic-canvas. Some stat-words are defined by the Table of Stats.

Table of Stats
bitmap text origin tint line-weight
Lucidity_text {500, 10} lucid-blue 2
Anxiety_text {500, 80} lucid-blue 2
[/code]

I end up with this:

[code]*** Couldn’t read from entry 1 of a list which is empty ***

*** Run-time problem P50: Attempt to use list item which does not exist.

*** Couldn’t read from entry 1 of a list which is empty ***
[/code]

I think if I just knew what variables I should be using I’ll be OK. Or, perhaps I’m going about adding this text completely wrong!

Thanks again for your help, Erik.

Glad to hear you’re on the move again!

You are looking for a “bitmap-rendered string”, which is a painted text rendered that uses a bitmap for each letter. A “bitmap,” as you hit on by trail and error, is not text-painting–a bitmap is a pixel-by-pixel rendering. Your table, because it refers to “bitmap texts”, doesn’t actually define the bitmaps, and so you get errors. Here’s the right set-up:

[code]A stat-word is a kind of bitmap-rendered string. The associated canvas of a stat-word is the scenic-canvas. [The associated font of a stat-word is Glimmr C&C.[If you’ve only included the one font extension (Glimmr Bitmap Font), you shouldn’t need to specify this.]] Some stat-words are defined by the Table of Stats.

Table of Stats
bitmap-rendered string origin tint bit-size text-string
Lucidity_text {500, 10} lucid-blue 2 “Lucidity”
Anxiety_text {500, 80} lucid-blue 2 “Anxiety”[/code]

But there’s no reason to try to do this using trial-and-error! Glimmr Canvas-Based Drawing, like all the other Glimmr extensions, comes with extensive documentation that explains the kinds of graphic elements and their properties. In the Documentation tab in the IDE, look right below the table of contents for the Writing with Inform manual, look for the link to “Installed Extensions”. Click on that, scroll down to the Erik Temple section, and finally click on Glimmr Canvas-Based Drawing link. The table of contents there indicates that Chapter 4 is the place to look for descriptions of all the graphic elements. Here’s the section that introduces rendered strings:

Chapter 11 of the documentation provides a complete reference to all of the properties of each type. I’ve spoilered the sections on bitmap rendered texts here to save space:

[spoiler]Section 11.9: Summary of the properties of rendered strings

This section presents a list of the properties associated with rendered strings. Properties which the extension uses internally, and should not be referred to by the author, are marked with a double asterisk (**). All rendered strings also inherit the properties common to the g-element kind (see above for those properties).

Note that the alignment property functions differently for rendered strings than for other g-elements. For center-aligned and right-aligned rendered strings, the origin is always located along the upper edge of the element; not at the center or the bottom edge.

associated font - a font object, which is the font that should be used to draw the rendered text element. A bitmap-rendered text must use a bitmap font, and an image-rendered font an image font.
text-string - an indexed text containing the string to be rendered by the element. Default value: “” (empty string, no output)
tint - a glulx color value (see the Glulx Text Effects extension) that defines the color of the letterforms and cursor of a bitmap-rendered string; defines only the cursor color of an image-rendered string. Default value: g-White
background tint - a glulx color value (see the Glulx Text Effects extension) that defines the color of the background of the rendered string element. Will be drawn as a single block of color behind the letterforms. Default value: g-PlaceNullCol (null, no background will appear)
cursor - a number defining the position of the cursor in the display of the rendered string. The cursor is only displayed when this property is 0 or higher. The cursor wil placed immediately after the string position; i.e., when cursor is 1, the cursor will be positioned immediately after the first character in the string. Default value: -99 (no cursor displayed)

Section 11.10: Summary of the properties of bitmap-rendered strings

This section presents a list of the properties associated with bitmap-rendered strings. These are more or less equivalent to the properties of bitmap elements. Properties which the extension uses internally, and should not be referred to by the author, are marked with a double asterisk (**). All bitmap-rendered strings also inherit the properties common to the g-element and rendered string kinds (see above for those properties).

bit-size - the size, relative to the canvas, of each bit in the bitmaps of the associated font’s letterforms. For example, a bit-size of 2 will be two units wide and two units high. The bit-size is subject to scaling both by the scaling factor (or x-scaling factor) of the rendered-string, and by the window scaling factor. Default value: 1
dot-size** - the final display size of each bit in the bitmaps of the associated font’s letterforms, measured in pixels as output on-screen. Default value: 1[/spoiler]

Finally, the examples show the different types of g-element in action: “Simpler Buttons” and “Deal Me In” both use bitmap-rendered strings.

–Erik

Ah, “bitmap-rendered string”! Great, good to know I wasn’t too far off from the right idea. You’re right, trying “bitmap” didn’t feel right at all. When I think of a bitmap, I think of the old days of drawing sprites for doom characters. I was just sort of stabbing in the dark with that one.

I have been looking at your extensive documentation from the beginning actually, I guess it’s just that there’s a lot to take in. Which is good though, slowly learning how things work is a lot more fun and productive than just plugging my own input into numerous examples.

However, that being said, I hope this thread ends up being a good example for future users of your system to understand setting up a basic gui better! The code you posted instantly worked by the way, it displays both words to the right in the window. I will be working some more on polishing this in the next few days and update my blog with the results. I appreciate your help in getting this solved.

Yes, with 11 extensions (and another one on the way) I’m sure that Glimmr is a bit difficult to approach. I know I found Eric Eve’s Conversation framework a bit confusing when I first looked at, and it only has 4! (Believe it or not, the original plan for Glimmr called for there to be nearly 20 extensions, with the core functionality divided up among multiple extensions.) Just FYI: for the most part, only the first few sections of the docs for each extension are intended to be must-reads; you can then just browse as needed to answer questions. It seems that most people are learning from the examples, which is pretty much what I expected.

Anyway, I’m glad you’ve got things a-rolling!

–Erik

Yes sir, thanks!

Just wanted to add that today I went back to this and have got rectangle primitives added to the meters within the scenic-canvas and they are being properly manipulated by commands within the game :smiley:

I’ll update my blog later after I add a few more elements and start finishing things with the GUI…

OK, so this question isn’t exactly about sizing and alignment but it does still deal with Glimmr in general.

I seems like by default, the “out” exit isn’t listed when the player is inside of a vehicle. Also, “in” is not displayed when the player is outside of a vehicle. I suspect that somewhere in this chunk of code I could possibly work that out:

Carry out looking (this is the compass rose updating rule): repeat with heading running through directions: let place be the room heading from the location; if place is a room and place is compass-ready: if place is unvisited: now the image-ID of the dir-sprite of the heading is the unvisited image of the dir-sprite of the heading; otherwise: now the image-ID of the dir-sprite of the heading is the visited image of the dir-sprite of the heading; activate the dir-sprite of the heading; otherwise: deactivate the dir-sprite of the heading; follow the window-drawing rules for the graphics-window.

I just have nothing but guesses as to what I should add or change for checking exits when the player is in the vehicle. This doesn’t necessarily have to apply to every vehicle, but I need it to apply to one for puzzle purposes.

Actually, this doesn’t really have anything to do with Glimmr. Vehicles are containers, not rooms, so they don’t have any directional connection at all, including “in” and “out”; in other words, they are totally independent of the compass. The exiting action does get remapped from the going action when the player is in a container. However, “in” does not similarly map to the action of entering a container, because that would override any use of the true “inside” compass direction.

And that’s what you’ll need to do to get this working: redirect “go inside” to “enter”. One way:

Check an actor going inside: if the SPORTS CAR is in the location and the actor is not in the SPORTS CAR: try the actor entering the SPORTS CAR instead.

Note that this will make it impossible to use inside as a direction from any location where the vehicle is, since that will remap to entering the vehicle. Be sure that your vehicle can’t enter any rooms where there is an “inside” map connection.

You’ll also need to modify the compass code that you identified, to hard-code a check for whether the player is inside/outside the vehicle:

[code]Carry out looking (this is the new compass rose updating rule):
repeat with heading running through directions:
let place be the room heading from the location;
if place is a room and place is compass-ready:
if place is unvisited:
now the image-ID of the dir-sprite of the heading is the unvisited image of the dir-sprite of the heading;
otherwise:
now the image-ID of the dir-sprite of the heading is the visited image of the dir-sprite of the heading;
activate the dir-sprite of the heading;
otherwise:
deactivate the dir-sprite of the heading;
if the player can touch the SPORTS CAR:
let heading be outside;
if the player is not in the SPORTS CAR:
let heading be inside;
now the image-ID of the dir-sprite of the heading is the unvisited image of the dir-sprite of the heading;
follow the window-drawing rules for the graphics-window.

The new compass rose updating rule is listed instead of the compass rose updating rule in the carry out looking rules.[/code]

–Erik

I was afraid of that. :blush:

Yup, for this case I do not have to worry about that at all. Thanks again Erik.

EDIT: Haven’t got this to work yet. At first I tried to just add the sports car checks (not noticing the declaration of a new rule) and nothing happened differently. Then I added that declaration, and compile fails on In ‘The new compass rose updating rule is listed instead of the compass rose updating rule in the carry out looking rules’ , you gave ‘the compass rose updating rule’ where a rule was required.

Sorry to keep this dragging along, but I’m still fairly confused. As noted above, I couldn’t get the code to compile right. But I don’t think that matters a lot when I don’t even completely understand what’s going on.

Are you saying here that ‘out’ should actually already be appearing as a direction to move on the compass? The only way I’ve ever made it appear is to create an actual room that’s ‘out’ from another room. I can’t get it to do it with a vehicle or an “enterable container”.

On “In”: I forgot that the command used by default is actually ‘enter’. For what I’m trying to do right now, I don’t need ‘in’ at all to apply to vehicles.

You can just change the original code directly; you don’t have to replace the rule as I suggested.

Yeah, that sentence wasn’t as clear as it could have been. What I was getting at is that the typed command “out” is redirected when the player is in a container, to the exiting action. (If the player were not in a container, it would be interpreted as the going action.) There is no map connection The reverse does not happen with “in”.

In that case, you can reduce the code I added to the compass rose updating rule to just this:

if the player is in the SPORTS CAR: now the image-ID of the dir-sprite of outside is the visited image of the dir-sprite of outside;

Obviously, you can use either the visited or unvisited image, as it suits you.

–Erik

I’ve spent an hour and a half trying to get this to work… and it just won’t. I’ve changed nothing in the compass code except for the following after “deactivate the dir-sprite of the heading;”:

Carry out looking (this is the compass rose updating rule): repeat with heading running through directions: let place be the room heading from the location; if place is a room and place is compass-ready: if place is unvisited: now the image-ID of the dir-sprite of the heading is the unvisited image of the dir-sprite of the heading; otherwise: now the image-ID of the dir-sprite of the heading is the visited image of the dir-sprite of the heading; activate the dir-sprite of the heading; otherwise: deactivate the dir-sprite of the heading; if the player is in the sports car: now the image-ID of the dir-sprite of outside is the unvisited image of the dir-sprite of outside; follow the window-drawing rules for the graphics-window.

Should this code not work? If it should, perhaps you could confirm in an example project if/when you have time.

I changed the code around to put the sports car before this. I tried other various things such as plugging in ‘now the heading is…’ just playing around to see if it would work. I just can’t get it. :neutral_face:

Check the code I originally posted. The stuff about the car is not part of the loop. It has to come after the loop, so that it can overwrite what the loop decides on for the outside connection.

Carry out looking (this is the compass rose updating rule): repeat with heading running through directions: let place be the room heading from the location; if place is a room and place is compass-ready: if place is unvisited: now the image-ID of the dir-sprite of the heading is the unvisited image of the dir-sprite of the heading; otherwise: now the image-ID of the dir-sprite of the heading is the visited image of the dir-sprite of the heading; activate the dir-sprite of the heading; otherwise: deactivate the dir-sprite of the heading; if the player is in the sports car: now the image-ID of the dir-sprite of outside is the unvisited image of the dir-sprite of outside; follow the window-drawing rules for the graphics-window.

–Erik

Oops–the code is missing a command to activate the sprite:

Carry out looking (this is the compass rose updating rule): repeat with heading running through directions: let place be the room heading from the location; if place is a room and place is compass-ready: if place is unvisited: now the image-ID of the dir-sprite of the heading is the unvisited image of the dir-sprite of the heading; otherwise: now the image-ID of the dir-sprite of the heading is the visited image of the dir-sprite of the heading; activate the dir-sprite of the heading; otherwise: deactivate the dir-sprite of the heading; if the player is in the sports car: now the image-ID of the dir-sprite of outside is the unvisited image of the dir-sprite of outside; activate the dir-sprite of outside; follow the window-drawing rules for the graphics-window.

That should do it.

–Erik

I did have it the right way in one of my attempts, but not in the code I posted. Sorry about that.

Ah-ha! That explains it. Good news, it compiles! Bad news… it still does not display “out” as a direction when inside of the sports car. I have no idea why… I used the quote button here on the boards to grab your last code and post it into my project to prevent spacing errors or typos. My object is named exactly how yours is… “sports car”. It just refuses to display the direction.

Any ideas? I’m sorry to keep pressing on with this small detail or feature, but it’s fairly important to a scene/puzzle in my game.

EDIT: A friend of mine I was talking about this with suggested a work-around of just creating a “temp room” in place of the car (since at this point the car is immobile). I’m thinking with enough tinkering I could make something like that work if all else fails… but getting the direction sprites to appear at will would be the most satisfying.