Life is not perfect, and neither are our toys. In a world of perfect toys, a Glk program could compile with any Glk library and run without human intervention. Guess what.
One large grey area is starting up, startup files, and other program options. It is easy to assume that all C programs run with the (argc, argv)
model — that all the information they need comes as an array of strings at startup time. This is sometimes true. But in a GUI system, files are often opened by clicking, options are specified in dialog boxes, and so on; and this does not necessarily happen at the beginning of main()
.
Therefore, Glk does not try to pass an (argc, argv)
list to your glk_main()
. Nor does it provide a portable API for startup files and options.
Doing that well would require API calls to parse command-line arguments of various types, and then also design and handle dialog boxes. It would go far beyond the level of complexity which Glk aspires to.
Instead, startup files and options are handled in an entirely platform-dependent manner. You, as the author of a Glk program, must describe how your program should behave. As your program is ported to various Glk libraries, each porter must decide how to implement that behavior on the platform in question. The library should store the options and files in global variables, where your glk_main()
routine can read them.
It is reasonable to modularize this code, and call it the “startup code”.
But the startup code is not necessarily a single function, and it certainly does not have well-defined arguments such as an (argc, argv)
list.
You can consider that your startup behavior is divided into the messy part, which is nonportable and goes in the startup code, and the clean part, which is entirely Glk-portable and goes at the beginning of glk_main()
.
This is not as much of a mess as it sounds. Many programs, and almost all IF programs, follow one of a few simple models.
The simple model: There are no startup files. The program just starts running when invoked.
The game-file model: The program begins running when it is handed a single file of a particular type. On command-line systems, this comes as a filename in a command-line option. On GUI systems, it will usually be a platform-native event which contains a file reference.
Any Glk library will be able to support these two models, probably through compile-time options. The details will vary.
For one notable case, the Mac Glk library has two possible behaviors when compiled with the game-file model. If the player double-clicks a game file, the library calls glk_main()
immediately. If the player double-clicks the application icon, the library allows the player to wait, perhaps adjusting preferences; it only calls glk_main()
after the game file is selected through a file dialog.
In fact, if life were this simple, it would be worth adding these models to the Glk API somehow. Unfortunately, it's not. Consider AGT: the “game file” is actually about ten separate files with related filenames, in the same directory. Glk does not contain API calls to do precise file and pathname manipulation; it is too complicated an area to support. So this situation must be handled non-portably.
More complicated models are also possible. You might want to accept files through GUI events at any time, not just at startup. This could be handled by defining a new Glk event type, and having the library send such an event when a platform-native icon-click is detected. You would then have to decide how the situation should be handled in a command-line Glk library. But that is inherent in your task as a program author.
Options and preferences are a separate problem. Most often, a command-line library will handle them with command-line arguments, and a GUI library will handle them with a dialog box. Ideally, you should describe how both cases should behave — list the command-line arguments, and perhaps how they could be labelled in a dialog.
This is unlikely to be very complicated. Although who knows.
Remember that the Glk library is likely to have some options of its own — matters of display styles and so on. A command-line library will probably have a simple API to extract its own options and pass the rest on to the startup code.