Cursor position in Z-code

Is the cursor position returned by @get_cursor relative to the current window’s top left corner, or to the screen’s top left corner?

In case it matters, this is about an interpreter using a regular text screen, and it’s running Z-code version 3, 4, 5 and 8 (not that v3 has that opcode).

From the Z-machine standard:

Each window remembers its own cursor position (relative to its own coordinates, so that the position (1,1) is at its top left). These can be changed using set_cursor (and it is legal to move the cursor for an unselected window).

I’d take this to mean that the arguments to set_cursor are relative to the given window’s top-left corner.

Indeed. But that text is taken from in the Z-machine specification. 8.8.* is only about Z-machine version 6.

The spec isn’t perfectly clear about this, but I just checked Frotz, Bocfel, and my own ZVM, and they all just return the cursor from the top window. In versions 4, 5, 8 the bottom window’s cursor is not accessible to the author.

1 Like

Ah, my bad, I missed a level of indentation and thought it was after the end of the 6-only stuff.

It might be helpful to look at the source code to robotfindskitten because it does a lot of cursor-addressing directly through z-machine opcodes.

Thanks. I had a look. It does all its cursor-addressing in the top window, where the window’s top left corner is the same as the screen’s top left corner.

Thanks, I think this is what I’ll go with.

I’m glad that you are here, David!

In the Z-machine standard, I read this (in the section on the screen model for version 4-8 except 6): When the upper window is selected, its cursor position can be moved with set_cursor . This position is given in characters in the form (row, column), with (1,1) at the top left. The opcode has no effect when the lower window is selected. It is illegal to move the cursor outside the current size of the upper window.

Still, from reading the source of Robot Finds Kitten, I gather that the game splits off only five lines for the upper window (window 1), and then goes on to plot player, kitten and other objects on the sixth line and all the way down to the bottom of the screen. This seems to be illegal but nevertheless it works. Well, not in Ozmoo it doesn’t, because Ozmoo hides any attempts to output text in window 1 below the top five lines.

What’s happening here?

Ah, I just found this addition at the bottom of the page in the standard:

S states that it is illegal to move the cursor outside the current size of the upper window. S gives the equivalent rule for Version 6.

Many modern games have been lax in obeying this rule; in particular some of the standard Inform menu libraries have violated it. Infocom’s Sherlock also miscalculated the size of the upper window to use for box quotes.

It is recommended that if the cursor is moved below the split position in V4/V5, interpreters should execute an implicit “split_window” to contain the requested cursor position, if possible. Diagnostics should be produced, but should be suppressable.

Well, that explains a lot.

Robotfindskitten is classified as an “abuse”, that is, doing something the Z-machine was never intended to do. So, weird stuff is to be expected.

My approach to the screen handling was to redraw the whole screen at every move and not care about windows. That’s how the original version (written in C) did things. I suppose I could rework it to do it “right”, which I may do in a year or so. I’d like to rework it anyway as an exercise in portability between Z-machine and Glulx vis-a-vis color changes.

FYI, the intro screen works fairly well in Ozmoo now. It’s just a bit too wide.

That’s because I assumed a terminal of at least 80 columns. I suppose I could detect width and go from there. There’s also a native port of robotfindskitten for the C64 available from

What keys would work best to control the robot on C64? WASD? The C64’s actual cursor keys were always a source of irritation for me.

WASD would be fine, yes. Or IJKL.

Would love to see it updated to work even better on the narrow screen.