-
Notifications
You must be signed in to change notification settings - Fork 33
Quixe Graphics Support
The 2.1.0 release of Quixe adds support for image display (drawing images in text and graphics windows).
This leaves us with a problem. The game code specifies images by number; the image data must be pulled from another source. How does this work?
If Quixe loads the game from a Blorb file, the image data is also encoded in the Blorb, so the problem solves itself. However, Blorb extraction in Javascript is very slow! And it uses a lot of memory.
I7's "release along with an interpreter" feature is already Blorb-free, for just those reasons. It loads the game from a static file (wrapped in Javascript so that Quixe can understand it). We would like to extend this to load image data from static files as well.
I7 generates its playable game using a template file called i7-manifest.txt
. This contains HTML/JS blocks which go into the generated HTML file. It also describes how to create the wrapped game file (more JS blocks, wrapped around base64-encoded Glulx data).
Footnote: the generated file is named game.gblorb.js
, but this is misleading. The contents are Glulx, not Blorb-wrapped Glulx.
The block that goes into play.html
looks like this:
<link rel="stylesheet" href="interpreter/glkote.css" type="text/css">
<link rel="stylesheet" href="interpreter/dialog.css" type="text/css">
<script src="interpreter/jquery-1.11.2.min.js" type="text/javascript"></script>
<script src="interpreter/glkote.min.js" type="text/javascript"></script>
<script src="interpreter/quixe.min.js" type="text/javascript"></script>
<script type="text/javascript">
game_options = {
use_query_story: false,
set_page_title: false,
inspacing: 0, // gap between windows
outspacing: 0 // gap between windows and edge of gameport
};
</script>
<script src="interpreter/[ENCODEDSTORYFILE]" type="text/javascript"></script>
Quixe 2.1.0 will use fast image loading if there is an image_info_map
entry in game_options
. This entry should be a Javascript object which describes all the available images.
(It can also be a string containing the name of a globally-readable object. That is, if you define a global ObjMap
, then image_info_map
can either be the ObjMap
itself or the string "ObjMap"
. The string option can avoid Javascript loading order problems.)
The map object should have integer keys (Glk image numbers). These should map to Javascript objects which look like:
{
"image": INT,
"url": URLSTRING,
"alttext": STRING,
"width": INT,
"height": INT
}
The image
number must match the key. (Yes, it's redundant, just do it.) The alttext
is an optional string describing the image (for non-graphical displays and visually impaired users.) The width
and height
are the image size -- these fields are required! And the url
should be a URL from which the image resource can be loaded. This may be an absolute URL, or relative to play.html
.
Footnote: To calculate the image size of a PNG or JPEG file, you can use the standard libpng and libjpeg libraries. Alternatively, see the implementation of parse_png()
and parse_jpeg()
in blorbtool.py. They're quite simple.
We make use of the new scheme by updating the text block in i7-manifest.txt
:
<link rel="stylesheet" href="interpreter/glkote.css" type="text/css">
<link rel="stylesheet" href="interpreter/dialog.css" type="text/css">
<script src="interpreter/jquery-1.11.2.min.js" type="text/javascript"></script>
<script src="interpreter/glkote.min.js" type="text/javascript"></script>
<script src="interpreter/quixe.min.js" type="text/javascript"></script>
<script src="interpreter/resourcemap.js" type="text/javascript"></script>
<script type="text/javascript">
game_options = {
image_info_map: 'StaticImageInfo', // image data is here, not in blorb
use_query_story: false,
set_page_title: false,
inspacing: 0, // gap between windows
outspacing: 0 // gap between windows and edge of gameport
};
</script>
<script src="interpreter/[ENCODEDSTORYFILE]" type="text/javascript"></script>
The template package includes a resourcemap.js
file which contains an empty StaticImageInfo
object. In the future, I7 will update this to include the image data. But at present, it must be filled in by hand.
The blorbtool.py script now provides a semi-convenient way to do this:
python blorbtool.py GAME.materials/Release/GAME.gblorb giload GAME.materials/Release/interpreter interpreter
This will parse out the resources from the blorb file and write them into the GAME.materials/Release/interpreter
directory as plain image files (named pict-1.jpeg
, pict-2.png
, etc.). It will also replace the resourcemap.js
in that directory with the correct data.
(It will also create a file named game.ulx.js
. This is functionally identical to the GAME.gblorb.js
which I7 generates. game.ulx.js
can be ignored or deleted.)