Quixe Graphics Support

Andrew Plotkin edited this page May 31, 2015 · 1 revision

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.

Quick overview

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>

Fast Loading Scheme

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.

The New I7 Template

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.)

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.