cfad47cfa3/tads3/vmmain.h
Commiter: Nikos Chantziaras
Author: Nikos Chantziaras
Revision: cfad47cfa3
File Size: 12 KB
(June 01, 2009 20:54 UTC) Almost 3 years ago
Initial commit.
/* $Header$ */
/*
* Copyright (c) 1999, 2002 Michael J. Roberts. All Rights Reserved.
*
* Please see the accompanying license file, LICENSE.TXT, for information
* on using and copying this software.
*/
/*
Name
vmmain.h - main entrypoint to run a T3 image file
Function
Notes
Modified
10/07/99 MJRoberts - Creation
*/
#ifndef VMMAIN_H
#define VMMAIN_H
#include "vmglob.h"
/*
* Parse a command line to determine the name of the game file specified by
* the arguments. If we can find a game file specification, we'll fill in
* 'buf' with the filename and return true; if there's no file name
* specified, we'll return false.
*
* Note that our parsing will work for TADS 2 or TADS 3 interpreter command
* lines, so this routine can be used to extract the filename from an
* ambiguous command line in order to check the file for its type and
* thereby resolve which interpreter to use.
*
* Note that the filename might not come directly from the command
* arguments, since it might be implied. If there's no game file directly
* specified, but there is an explicit "-r" option to restore a saved game,
* we'll pull the game filename out of the saved game file if possible.
* Saved game files in both TADS 2 and TADS 3 can store the original game
* file name that was being executed at the time the game was saved.
*/
int vm_get_game_arg(int argc, const char *const *argv,
char *buf, size_t buflen);
/*
* Given a game file argument, determine which engine (TADS 2 or TADS 3)
* should be used to run the game.
*
* We'll first check to see if the given file exists. If it does, we'll
* read header information from the file to try to identify the game. If
* the file does not exist, we will proceed to check default suffixes, if
* the suffix arguments are non-null.
*
* If defexts is not null, it gives an array of default filename suffix
* strings, suitable for use with os_defext(). When the name as given
* doesn't refer to an existing file, we'll try looking for files with
* these suffixes, one at a time.
*
* Returns one of the VM_GGT_xxx codes.
*
* If the return value is 2 or 3, we'll fill in the actual_filename buffer
* with the full name of the file; if we added a default suffix, the
* suffix will be included in this result.
*/
int vm_get_game_type(const char *filename,
char *actual_filename,
size_t actual_filename_buffer_length,
const char *const *defexts, size_t defext_count);
/*
* Returns codes for vm_get_game_type()
*/
/* game type is TADS 2 */
#define VM_GGT_TADS2 2
/* game type is TADS 3 */
#define VM_GGT_TADS3 3
/* game file not found (even after trying default extensions) */
#define VM_GGT_NOT_FOUND (-1)
/* game file exists but isn't a valid tads 2 or tads 3 game */
#define VM_GGT_INVALID (-2)
/*
* ambiguous filename - the exact filename doesn't exist, and more than
* one default suffix version exists
*/
#define VM_GGT_AMBIG (-3)
/*
* determine if a VM_GGT_xxx code refers to a valid engine version:
* returns true if the code is an engine version, false if the code is an
* error indication
*/
#define vm_ggt_is_valid(code) ((code) > 0)
/*
* Execute an image file. We'll return zero on success, or a VM error code
* on failure. If an error occurs, we'll fill in 'errbuf' with the text of
* a message describing the problem.
*
* If 'load_from_exe' is true, the image filename given is actually the
* name of the native executable file that we're running, and we should
* load the image file that's attached to the native executable file via
* the system-specific os_exeseek() mechanism.
*
* If 'script_file' is not null, we'll read console input from the given
* file. If 'log_file' is not null, we'll log console output to the given
* file. If 'cmd_log_file' is not null, we'll log each line we read from
* the console to the given command logging file.
*
* 'charset' optionally selects a character set to use for text displayed
* to or read from the user interface. If this is null, we'll use the
* current system character set as indicated by the osifc layer. 'charset'
* should usually be null unless explicitly specified by the user.
*/
int vm_run_image(class CVmMainClientIfc *clientifc,
const char *image_file_name,
class CVmHostIfc *hostifc,
const char *const *prog_argv, int prog_argc,
const char *script_file, int script_quiet,
const char *log_file, const char *cmd_log_file,
int load_from_exe, int show_banner,
const char *charset, const char *log_charset,
const char *saved_state, const char *res_dir);
/*
* Execute an image file using argc/argv conventions. We'll parse the
* command line and invoke the program.
*
* The 'executable_name' is the name of the host program; this is used to
* prepare "usage" messages.
*
* If 'defext' is true, we'll try adding a default extension ("t3",
* formerly "t3x") to the name of the image file we find if the given
* filename doesn't exist. We'll always check to see if the file exists
* with the exact given name before we do this, so that we don't add an
* extension where none is needed. If the caller doesn't want us to try
* adding an extension at all, pass in 'defext' as false.
*
* If 'test_mode' is true, we'll make some small changes to the program
* invocation protocol appropriate to running system tests. In
* particular, we'll build the program argument list with only the root
* name of the image file, not the full path - this allows the program to
* display the argument list without any dependencies on local path name
* conventions or the local directory structure, allowing for more easily
* portable test scripts.
*
* If 'hostifc' is null, we'll provide our own default interface. The
* caller can provide a custom host interface by passing in a non-null
* 'hostifc' value.
*/
int vm_run_image_main(class CVmMainClientIfc *clientifc,
const char *executable_name,
int argc, char **argv, int defext, int test_mode,
class CVmHostIfc *hostifc);
/*
* VM Main client services interface. Callers of the vm_run_image
* functions must provide an implementation of this interface.
*/
class CVmMainClientIfc
{
public:
/*
* Set "plain" mode. This should set the console to plain ASCII output
* mode, if appropriate. Note that this can be called before
* client_init(), and no globals are generally present at this point.
*
* In most cases, this can make a call to os_plain() to set the
* OS-level console to plain mode. Non-console applications generally
* need not do anything here at all.
*/
virtual void set_plain_mode() = 0;
/*
* Create the main system console, if desired. This is called during
* VM initialization, so it is called prior to client_init(). Returns
* the main console object, if desired. If no main console is desired
* for this application, return null.
*/
virtual class CVmConsoleMain *create_console(
struct vm_globals *globals) = 0;
/*
* Delete the console, if we created one. This is called during VM
* termination, so it's called after client_terminate(). If
* create_console() doesn't create a console, this routine need do
* nothing.
*/
virtual void delete_console(struct vm_globals *globals,
class CVmConsoleMain *console) = 0;
/*
* Initialization - we'll invoke this immediately after initializing
* the VM (via vm_initialize), so the client can perform any global
* initialization desired. The globals are valid at this point because
* we have completed VM initialization.
*
* If script_file is non-null, it gives the name of a file to use as
* the source of console input. The client implementation should set
* up accordingly; if the standard console (G_console) is being used,
* the client can simply use G_console->open_script_file() to set up
* scripting.
*
* If log_file is non-null, it gives the name of a file to use to log
* console output. The client shoudl set up logging; if the standard
* console if being used, G_console->open_log_file() will do the trick.
*
* If cmd_log_file is non-null, it gives the name of a file to use to
* log commands read from the input (i.e., only command input should be
* logged, not other console output). If the standard console is being
* used, G_console->open_command_log() will set things up properly.
*
* If banner_str is non-null, it gives a VM banner string that should
* be displayed to the user. If the standard console is being used,
* this can be displayed using G_console->format_text().
*
* The parameters (script_file, log_file, cmd_log_file, and the
* presence or absence of banner_str) are taken from the startup
* parameters. For a command-line version, for example, these come
* from command line options. So, these are necessarily passed down in
* some form from the client to begin with; so a client that never
* passes these to vm_run_image() or vm_run_image_main() doesn't need
* to handle these parameters at all here.
*/
virtual void client_init(struct vm_globals *globals,
const char *script_file, int script_quiet,
const char *log_file,
const char *cmd_log_file,
const char *banner_str) = 0;
/*
* Termination - we'll invoke this immediately before terminating the
* VM (via vm_terminate). Globals are still valid at this point, but
* will be destroyed after this returns.
*/
virtual void client_terminate(struct vm_globals *globals) = 0;
/*
* pre-execution notification - we'll invoke this function just before
* starting execution in the loaded image
*/
virtual void pre_exec(struct vm_globals *globals) = 0;
/*
* terminate - we'll invoke this just after execution in the loaded
* image terminates
*/
virtual void post_exec(struct vm_globals *globals) = 0;
/*
* Terminate with error - we'll invoke this upon catching an
* exception that the image file doesn't handle and which thus
* terminates execution. Note that if this is called, post_exec()
* will not be called; however, if post_exec() itself throws an
* exception, we'll invoke this routine.
*/
virtual void post_exec_err(struct vm_globals *globals) = 0;
/*
* Display an error message. We'll call this with a complete error
* message to display. Note that we won't add a newline at the end of
* the message, so if the message is to be displayed on a stdio-style
* terminal, this routine should display a newline after the message.
*
* If the implementation normally writes the text to the main output
* console (G_console), it must take into the account the possibility
* that we have not opened a system console at all (i.e., G_console
* could be null), or have not allocated any globals at all (i.e.,
* 'globals' could be null).
*
* If 'add_blank_line' is true, the implementation should add a blank
* line after the error, if appropriate for the display device. If
* we're displaying the message in an alert box on a GUI, for example,
* this can be ignored.
*/
virtual void display_error(struct vm_globals *globals,
const char *msg, int add_blank_line) = 0;
};
#endif /* VMMAIN_H */
|