------------------------------------- Hugo Manual Addendum - Hugo v3.0 beta by Kent Tessman ------------------------------------- This is a brief addendum to the Hugo Manual outlining the current additional features of Hugo v3.0. Since v3.0 is still officially a beta version, information in this document may be subject to revision. 1. COMPATIBILITY Generally speaking, version 3.0 and version 2.5.x (beginning with version 2.5.01) are intercompatible in terms of .HEX and .HDX files. 1.1. Engine - The v3.0 engine will run v2.5 games, and the v2.5 engine will run v3.0 games. However, v3.0-specific functionality will be degraded under v2.5 (i.e., v3.0-specific code will be executed but to no effect). For example, media types that are unsupported in v2.5 will return a NOT_SUPPORTED error in the system_status global variable when the v2.5 engine attempts to play them. 1.2. Compiler - The v3.0 compiler will produce v2.5 gamefiles using the switch '-25'. Warnings will be generated for v3.0-specific source code compiled with the '-25' switch. The v2.5 compiler cannot produce v3.0 gamefiles. The compiler will automagically #set the flag "_VERSION2" for v2.5 gamefiles, and "_VERSION3" for v3.0. 1.3. Debugger - The v3.0 debugger will run v2.5 .HDX files, the v2.5 debugger will run v3.0 .HDX files, with the same caveats as under 1.1, above. 1.4. Library - Library files are versioned for v2.5 and still include the compiler directive "#version 2.5". The v3.0 compiler will accept these as being the correct version. 2. MUSIC In addition to music modules (MOD/S3M/XM), v3.0 supports MIDI and MPEG Layer 3 (MP3). The same syntax and functionality for the 'music' command apply. 3. VIDEO Hugo is now capable of playing video in, currently, MPEG-1, MPEG-2, and AVI formats. The syntax of the command is similar to 'sound' and 'video': (***CHECK THIS) video "resourcefile", "resource" The video resource is played in the currently defined window. The playback image will be reduced to fit the window if it is smaller than the default playback image size; otherwise, it will be centered in the existing window. The Hugo Engine will wait until playback either finishes or is interrupted before continuing execution. A given implementation of the engine is, however, free to allow control over system-specific functions (as the Windows 9x/NT port does in allowing the user to position the game window, access system menus, etc.). The engine should also allow a player to interrupt video playback at any point. It is currently not mandated that a v3.0 port be capable of playing video resources at the same time as music or other sounds. (Depending on library and system implementations, it may not be practical or possible to accomplish this.) The Windows 9x/NT engine allows a currently playing music resource (or other sound resource) to continue playing when video playback begins, but this should not be assumed to be consistent behavior on all platforms. It should, however, be expected that if the engine interrupts a currently playing music or sound resource that will be continued or restarted when video playback is completed. 4. CONTEXT COMMAND MENUS The Hugo Engine allows a game to define a set of context commands. It is up to the individual port of the engine to implement access to the context commands. Under Windows 9x/NT, for example, an existing set of context commands is displayed in a menu by pressing the right mouse button. Context commands are added to the list using the statement 'addcontext', as in: addcontext "command1"[, "command2", ...] (If one of the values following 'addcontext' begins with a '-', the entry is treated as a menu separator. A blank value, "", erases the existing context command list and starts over.) When a context command is processed by the engine, it is sent to the command line as if it had been typed. If the line ends in "...", no linefeed is sent. Otherwise, it is as if Enter is pressed following the command being typed. As an example, addcontext "", "north", "east" addcontext "-", "get..." would, using the Windows 9x/NT engine, produce a context menu (starting from an empty menu instead of adding commands to an existing menu, since "" is supplied) that looks like: North East ---------- Get... If "Get..." is selected, "Get " will appear on the input line, but the engine will wait for the player to complete the line. 5. HUGO PLUGIN ARCHITECTURE (Proposal) A new idea in the design of the Hugo System is the Hugo Plugin Architecture (HPA). Since Hugo is incorporating a growing amount of multimedia support, it may be a benefit to porters to be able to make use not only of system- specific libraries but also of plugins for other applications. Of course this approach requires that a given plugin (which may be in, e.g., dynamically linked library form under Windows) have its callable functions exposed and well enough documented that another application be able to make use of them. The usefulness of this architecture would be evident if the range of media types supported by Hugo were to be considerably expanded beyond the current JPEG, WAVE, MOD/S3M/XM, MIDI, MP3, AVI, and MPEG. Ideally, Hugo would then be able to make use of whatever libraries, codecs, plugins, etc. were installed on the player's system in order to reduce the size of its own footprint. (Note that at present, the HPA isn't presently utilized either by the engine core or by any ports. It is a proposal for future implementation.) The HPA consists of two categories of objects including a PluginInterface object, and one or more Plugin objects. The PluginInterface is structured like this: struct PluginInterface { int (*AddPlugin)(Plugin *); int (*RemovePlugin)(Plugin *); // 'data' is a pointer to the byte data of the resource // 'resource type' is the engine-defined identifier Plugin (*FindPlugin)(int resource_type, void *data); int (*OpenPlugin)(Plugin *, int resource_type, void *data); int (*SuspendPlugin)(Plugin *); int (*ClosePlugin)(Plugin*); } PluginInterface; Each Plugin object then looks like: struct Plugin { int (*Add)(void); int (*Remove)(void); // 'data' is a pointer to the byte data of the resource // 'resource type' is the engine-defined identifier int (*Query)(int resource_type, void *data); int (*Open)(int resource_type, void *data); int (*Suspend)(void); int (*Close)(void); } ; At initialization, the engine enumerates the available plugins and adds each to its internal list via PluginInterface->AddPlugin() which calls the Add method for the individual Plugin. When a resource is played, the engine calls the PluginInterface to identify it using PluginInterface->FindPlugin(resource_type, data) FindPlugin calls Query on each loaded Plugin. If FindPlugin returns non-NULL, the resulting value is , i.e., a loaded plugin that can then be used for PluginInterface->OpenPlugin(, resource_type, data) FindPlugin returns NULL if it fails to find a suitable plugin. Otherwise, all control of resource playback is handled via the remaining PluginInterface methods. It is never necessary for the engine to access a Plugin object directly, or even for the Plugin to have its methods visible except to the PluginInterface.