aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/include
diff options
context:
space:
mode:
authorJordi Vilalta Prat2009-02-15 06:10:59 +0000
committerJordi Vilalta Prat2009-02-15 06:10:59 +0000
commitfa6e10e9cec163845aa29e7940c86e9c9ab8a2bc (patch)
treece87338830cc8c149e1de545246bcefe4f45da00 /engines/sci/include
parent7c148ddf021c990fa866b7600f979aac9a5b26c9 (diff)
downloadscummvm-rg350-fa6e10e9cec163845aa29e7940c86e9c9ab8a2bc.tar.gz
scummvm-rg350-fa6e10e9cec163845aa29e7940c86e9c9ab8a2bc.tar.bz2
scummvm-rg350-fa6e10e9cec163845aa29e7940c86e9c9ab8a2bc.zip
Import the SCI engine sources from the FreeSCI Glutton branch (it doesn't compile yet)
svn-id: r38192
Diffstat (limited to 'engines/sci/include')
-rw-r--r--engines/sci/include/Makefile.am19
-rw-r--r--engines/sci/include/aatree.h85
-rw-r--r--engines/sci/include/beos/Makefile.am1
-rw-r--r--engines/sci/include/beos/collsyms.h129
-rw-r--r--engines/sci/include/beos/fnmatch.h49
-rw-r--r--engines/sci/include/conf_driver.h204
-rw-r--r--engines/sci/include/conf_extension.h71
-rw-r--r--engines/sci/include/conf_parse.h108
-rw-r--r--engines/sci/include/conf_subsystems.h80
-rw-r--r--engines/sci/include/conf_summary.h106
-rw-r--r--engines/sci/include/console.h254
-rw-r--r--engines/sci/include/engine.h306
-rw-r--r--engines/sci/include/event.h15
-rw-r--r--engines/sci/include/game_select.h38
-rw-r--r--engines/sci/include/gfx_driver.h438
-rw-r--r--engines/sci/include/gfx_operations.h733
-rw-r--r--engines/sci/include/gfx_options.h86
-rw-r--r--engines/sci/include/gfx_res_options.h134
-rw-r--r--engines/sci/include/gfx_resmgr.h354
-rw-r--r--engines/sci/include/gfx_resource.h440
-rw-r--r--engines/sci/include/gfx_state_internal.h238
-rw-r--r--engines/sci/include/gfx_system.h445
-rw-r--r--engines/sci/include/gfx_tools.h293
-rw-r--r--engines/sci/include/gfx_widgets.h548
-rw-r--r--engines/sci/include/hashmap.h132
-rw-r--r--engines/sci/include/heapmgr.h120
-rw-r--r--engines/sci/include/int_hashmap.h63
-rw-r--r--engines/sci/include/kdebug.h121
-rw-r--r--engines/sci/include/kernel.h403
-rw-r--r--engines/sci/include/list.h162
-rw-r--r--engines/sci/include/listener.h38
-rw-r--r--engines/sci/include/menubar.h219
-rw-r--r--engines/sci/include/modules.h84
-rw-r--r--engines/sci/include/old_objects.h54
-rw-r--r--engines/sci/include/reg_t_hashmap.h71
-rw-r--r--engines/sci/include/resource.h510
-rw-r--r--engines/sci/include/sbtree.h114
-rw-r--r--engines/sci/include/sci_conf.h187
-rw-r--r--engines/sci/include/sci_dos.h174
-rw-r--r--engines/sci/include/sci_memory.h381
-rw-r--r--engines/sci/include/sci_midi.h53
-rw-r--r--engines/sci/include/sci_widgets.h211
-rw-r--r--engines/sci/include/sciresource.h538
-rw-r--r--engines/sci/include/scitypes.h155
-rw-r--r--engines/sci/include/script.h214
-rw-r--r--engines/sci/include/seg_manager.h627
-rw-r--r--engines/sci/include/sfx_core.h40
-rw-r--r--engines/sci/include/sfx_engine.h179
-rw-r--r--engines/sci/include/sfx_iterator.h353
-rw-r--r--engines/sci/include/sfx_iterator_internal.h238
-rw-r--r--engines/sci/include/sfx_pcm.h235
-rw-r--r--engines/sci/include/sfx_player.h166
-rw-r--r--engines/sci/include/sfx_songlib.h200
-rw-r--r--engines/sci/include/sfx_time.h93
-rw-r--r--engines/sci/include/sfx_timer.h96
-rw-r--r--engines/sci/include/sys_strings.h80
-rw-r--r--engines/sci/include/uinput.h130
-rw-r--r--engines/sci/include/util.h108
-rw-r--r--engines/sci/include/versions.h169
-rw-r--r--engines/sci/include/vm.h843
-rw-r--r--engines/sci/include/vm_types.h71
-rw-r--r--engines/sci/include/vocabulary.h424
-rw-r--r--engines/sci/include/win32/Makefile.am1
-rw-r--r--engines/sci/include/win32/getopt.h127
-rw-r--r--engines/sci/include/win32/sci_win32.h37
-rw-r--r--engines/sci/include/win32/usleep.h2
66 files changed, 13397 insertions, 0 deletions
diff --git a/engines/sci/include/Makefile.am b/engines/sci/include/Makefile.am
new file mode 100644
index 0000000000..316690244c
--- /dev/null
+++ b/engines/sci/include/Makefile.am
@@ -0,0 +1,19 @@
+SUBDIRS = win32 beos
+EXTRA_DIST = old_objects.h kernel.h event.h \
+ kdebug.h sci_conf.h resource.h script.h \
+ vocabulary.h uinput.h console.h script.h vm.h \
+ engine.h util.h menubar.h versions.h sci_dos.h \
+ gfx_driver.h gfx_operations.h gfx_options.h \
+ gfx_resmgr.h gfx_resource.h gfx_widgets.h \
+ gfx_state_internal.h gfx_system.h gfx_tools.h \
+ sci_widgets.h scitypes.h sbtree.h \
+ sciresource.h modules.h sci_memory.h \
+ hashmap.h int_hashmap.h sys_strings.h heapmgr.h \
+ sfx_iterator.h sfx_songlib.h \
+ sfx_engine.h vm_types.h seg_manager.h \
+ sfx_timer.h sfx_player.h gfx_res_options.h \
+ sfx_time.h sci_midi.h \
+ sfx_core.h sfx_pcm.h listener.h \
+ sfx_iterator_internal.h game_select.h \
+ reg_t_hashmap.h list.h aatree.h
+
diff --git a/engines/sci/include/aatree.h b/engines/sci/include/aatree.h
new file mode 100644
index 0000000000..1f16d2391b
--- /dev/null
+++ b/engines/sci/include/aatree.h
@@ -0,0 +1,85 @@
+/***************************************************************************
+ aatree.h Copyright (C) 2006 Walter van Niftrik
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Walter van Niftrik [w.f.b.w.v.niftrik@stud.tue.nl]
+
+***************************************************************************/
+
+#ifndef _SCI_AATREE_H
+#define _SCI_AATREE_H
+
+/* Andersson tree implementation. Stores data pointers in a balanced binary
+** tree. A user-supplied comparison function defines the ordering. For the
+** semantics of this function see qsort(3)
+*/
+
+typedef struct aatree aatree_t;
+
+/* Left child */
+#define AATREE_WALK_LEFT 0
+/* Right child */
+#define AATREE_WALK_RIGHT 1
+
+aatree_t *aatree_new();
+/* Allocates a new aatree
+** Parameters: (void)
+** Returns : (aatree_t *) A newly allocated aatree
+*/
+
+void aatree_free(aatree_t *t);
+/* Deallocates an aatree
+** Parameters: (aatree_t *) t: The aatree
+** Returns : (void)
+*/
+
+int aatree_delete(void *x, aatree_t **t, int (*compar)(const void *, const void *));
+/* Deletes a data element from an aatree
+** Parameters: (void *) x: The data element to delete
+** (aatree_t **) t: The aatree
+** compar: The comparison function
+** Returns : (int) 0 on success, -1 if x wasn't found in t
+*/
+
+int aatree_insert(void *x, aatree_t **t, int (*compar)(const void *, const void *));
+/* Inserts a data element into an aatree
+** Parameters: (void *) x: The data element to insert
+** (aatree_t **) t: The aatree
+** compar: The comparison function
+** Returns : (int) 0 on success, -1 if x already exists in t
+*/
+
+aatree_t *aatree_walk(aatree_t *t, int direction);
+/* Walks to either the left or right child of a node
+** Parameters: (aatree_t *) t: The node
+** (int) direction: AATREE_WALK_LEFT or AATREE_WALK_RIGHT
+** Returns : (aatree_t *) The requested child of t or NULL if it doesn't
+** exist
+*/
+
+void *aatree_get_data(aatree_t *t);
+/* Returns the data element of a node
+** Parameters: (aatree_t *) t: The node
+** Returns : (void *) The data element
+*/
+
+#endif /* !_SCI_AATREE_H */
diff --git a/engines/sci/include/beos/Makefile.am b/engines/sci/include/beos/Makefile.am
new file mode 100644
index 0000000000..d449e08e0a
--- /dev/null
+++ b/engines/sci/include/beos/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = collsyms.h fnmatch.h \ No newline at end of file
diff --git a/engines/sci/include/beos/collsyms.h b/engines/sci/include/beos/collsyms.h
new file mode 100644
index 0000000000..7ef0906879
--- /dev/null
+++ b/engines/sci/include/beos/collsyms.h
@@ -0,0 +1,129 @@
+/* collsyms.h -- collating symbol names and their corresponding characters
+ (in ascii) as given by POSIX.2 in table 2.8. */
+
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+
+ This file is part of GNU Bash, the Bourne Again SHell.
+
+ Bash is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 2, or (at your option) any later
+ version.
+
+ Bash is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with Bash; see the file COPYING. If not, write to the Free Software
+ Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#ifndef _COLLSYMS_H_
+# define _COLLSYSMS_H_
+
+/* The upper-case letters, lower-case letters, and digits are omitted from
+ this table. The digits are not included in the table in the POSIX.2
+ spec. The upper and lower case letters are translated by the code
+ in fnmatch.c:collsym(). */
+
+typedef struct _collsym {
+ char *name;
+ char code;
+} COLLSYM;
+
+static COLLSYM posix_collsyms[] =
+{
+ "NUL", '\0',
+ "SOH", '\001',
+ "STX", '\002',
+ "ETX", '\003',
+ "EOT", '\004',
+ "ENQ", '\005',
+ "ACK", '\006',
+#ifdef __STDC__
+ "alert", '\a',
+#else
+ "alert", '\007',
+#endif
+ "backspace", '\b',
+ "tab", '\t',
+ "newline", '\n',
+ "vertical-tab", '\v',
+ "form-feed", '\f',
+ "carriage-return", '\r',
+ "SO", '\016',
+ "SI", '\017',
+ "DLE", '\020',
+ "DC1", '\021',
+ "DC2", '\022',
+ "DC3", '\023',
+ "DC4", '\024',
+ "NAK", '\025',
+ "SYN", '\026',
+ "ETB", '\027',
+ "CAN", '\030',
+ "EM", '\031',
+ "SUB", '\032',
+ "ESC", '\033',
+ "IS4", '\034',
+ "IS3", '\035',
+ "IS2", '\036',
+ "IS1", '\037',
+ "space", ' ',
+ "exclamation-mark", '!',
+ "quotation-mark", '"',
+ "number-sign", '#',
+ "dollar-sign", '$',
+ "percent-sign", '%',
+ "ampersand", '&',
+ "apostrophe", '\'',
+ "left-parenthesis", '(',
+ "right-parenthesis", ')',
+ "asterisk", '*',
+ "plus-sign", '+',
+ "comma", ',',
+ "hyphen", '-',
+ "minus", '-', /* extension from POSIX.2 */
+ "dash", '-', /* extension from POSIX.2 */
+ "period", '.',
+ "slash", '/',
+ "solidus", '/', /* extension from POSIX.2 */
+ "zero", '0',
+ "one", '1',
+ "two", '2',
+ "three", '3',
+ "four", '4',
+ "five", '5',
+ "six", '6',
+ "seven", '7',
+ "eight", '8',
+ "nine", '9',
+ "colon", ':',
+ "semicolon", ';',
+ "less-than-sign", '<',
+ "equals-sign", '=',
+ "greater-than-sign", '>',
+ "question-mark", '?',
+ "commercial-at", '@',
+ /* upper-case letters omitted */
+ "left-square-bracket",'[',
+ "backslash", '\\',
+ "reverse-solidus", '\\',
+ "right-square-bracket", ']',
+ "circumflex", '^',
+ "circumflex-accent", '^', /* extension from POSIX.2 */
+ "underscore", '_',
+ "grave-accent", '`',
+ /* lower-case letters omitted */
+ "left-brace", '{', /* extension from POSIX.2 */
+ "left-curly-bracket", '{',
+ "vertical-line", '|',
+ "right-brace", '}', /* extension from POSIX.2 */
+ "right-curly-bracket", '}',
+ "tilde", '~',
+ "DEL", '\177',
+ 0, 0,
+};
+
+#endif
diff --git a/engines/sci/include/beos/fnmatch.h b/engines/sci/include/beos/fnmatch.h
new file mode 100644
index 0000000000..7aa1164236
--- /dev/null
+++ b/engines/sci/include/beos/fnmatch.h
@@ -0,0 +1,49 @@
+/* Copyright (C) 1991 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+
+#ifndef _FNMATCH_H
+#define _FNMATCH_H 1
+
+/* #include "stdc.h" */
+
+/* We #undef these before defining them because some losing systems
+ (HP-UX A.08.07 for example) define these in <unistd.h>. */
+#undef FNM_PATHNAME
+#undef FNM_NOESCAPE
+#undef FNM_PERIOD
+
+/* Bits set in the FLAGS argument to `fnmatch'. */
+/* standard flags */
+#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
+#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
+#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
+
+/* extended flags */
+#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
+#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
+#define FNM_EXTMATCH (1 << 5) /* Use ksh-like extended matching. */
+
+/* Value returned by `fnmatch' if STRING does not match PATTERN. */
+#define FNM_NOMATCH 1
+
+/* Match STRING against the filename pattern PATTERN,
+ returning zero if it matches, FNM_NOMATCH if not. */
+/* extern int fnmatch __P((char *, char *, int)); */
+extern int fnmatch (char *, char *, int);
+
+#endif /* _FNMATCH_H */
diff --git a/engines/sci/include/conf_driver.h b/engines/sci/include/conf_driver.h
new file mode 100644
index 0000000000..a415adf396
--- /dev/null
+++ b/engines/sci/include/conf_driver.h
@@ -0,0 +1,204 @@
+/***************************************************************************
+ conf_driver.h Copyright (C) 2007 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef CONF_DRIVER_H_
+#define CONF_DRIVER_H_
+
+
+/* Possible values for enum types */
+typedef struct {
+ char *name;
+ int value;
+} conf_value_t;
+
+typedef struct {
+ char *name;
+ char *description;
+ unsigned int type;
+ unsigned int flags;
+ union { char * str;
+ int nr } default; /* Optional default value */
+ int min; /* For subrange types */
+ int max; /* For subrange types; for enum types */
+ conf_value_t *values; /* For enum types; NULL-terminated */
+ void *data; /* User data */
+} conf_option_t;
+
+#define CONF_OPTION_TYPE_INT 0
+#define CONF_OPTION_TYPE_SUBRANGE 1 /* ``interval'' type, i.e. bounded int */
+#define CONF_OPTION_TYPE_STRING 2
+#define CONF_OPTION_TYPE_BOOL 3 /* special built-in enum */
+#define CONF_OPTION_TYPE_ENUM 4
+
+#define CONF_OPTION_FLAG_MANDATORY (1<<0) /* Option MUST be set */
+#define CONF_OPTION_FLAG_HAS_DEFAULT (1<<1) /* Option has a default value */
+#define CONF_OPTION_FLAG_DYNAMIC (1<<2) /* Option may be altered after initialisation */
+
+
+#define CONF_DRIVER_FAIL 1
+#define CONF_DRIVER_SUCCESS 0
+
+typedef struct conf_header {
+ char [16] magic; /* MUST be CONF_DRIVER_MAGIC */
+ int freesci_version; /* MUST be CONF_DRIVER_VERSION */
+ int subsystem_id; /* CONF_SUBSYSTEM_*, if appropriate */
+ int subsystem_version;
+ char *name; /* Long driver name */
+ char *version; /* Long driver version */
+ unsigned int dependencies; /* CONF_DRIVER_DEPENDENCY_* */
+ conf_option_t *options; /* Last option has name of NULL */
+ char * (*set_option)(void * self, /* points to base struct */
+ conf_option_t *,
+ union { char *str;
+ int nr }); /* Set option, return static error (if applicable) or NULL on success */
+} conf_header_t; /* Universal driver header */
+
+struct conf_driver;
+struct conf_subsystem;
+struct conf_main;
+
+#define CONF_SUBSYSTEM_GFX 0
+#define CONF_SUBSYSTEM_SOUND 1 /* The sfx/player subsystem */
+#define CONF_SUBSYSTEM_PCM_DEVICE 2
+#define CONF_SUBSYSTEM_MIXER 3
+#define CONF_SUBSYSTEM_SEQ 4 /* HW sequencer or generic softseq interface */
+#define CONF_SUBSYSTEM_SOFTSEQ 5
+#define CONF_SUBSYSTEM_TIMER 6
+
+#define CONF_SUBSYSTEMS_NR 7
+
+typedef struct conf_driver {
+ conf_header_t header;
+ char * (*init)(struct conf_driver *self,
+ struct conf_subsystem *owner); /* Initialise, return static error message on error or NULL on success.
+ ** The owner is guaranteed to have been configured and guaranteed NOT to have
+ ** been initialised. */
+
+ void (*exit)(void);
+} conf_driver_t;
+
+typedef struct conf_subsystem {
+ conf_header_t header;
+ char * (*init)(struct conf_subsystem *self,
+ struct conf_main *main,
+ struct conf_driver *driver); /* Initialise, return static error message on error or NULL on success.
+ ** The driver is configured and initialised, the main reference configured but
+ ** not initialised. */
+ void (*exit)(void);
+ char *(*get_default_driver)(struct conf_subsystem *self,
+ int index); /* Get the nth default driver name, or NULL if there is none. These are tried in order if
+ ** there is no explicit choice. */
+ conf_driver_t **builtin_drivers; /* NULL terminated list of built-in drivers */
+ char *dynamic_driver_prefix; /* string prefix to dynamically loaded drivers for this subsystem */
+} conf_subsystem_t;
+
+
+typedef struct conf_main {
+ conf_header_t header;
+ conf_subsystem_t *[CONF_SUBSYSTEMS_NR];
+ char **dynamic_driver_locations; /* NULL terminated list of locations to check for dynamically loadable drivers */
+ char * (*init)(struct conf_main *self); /* Return static error message, or NULL on success. */
+ void (*exit)(void);
+} conf_main_t;
+
+
+#define CONF_DRIVER_MAGIC "FreeSCI driver"
+
+#define CONF_DRIVER_VERSION 1
+
+/* Dependency flags */
+#define CONF_DRIVER_DEPENDENCY_GFX (1 << CONF_SUBSYSTEM_GFX)
+#define CONF_DRIVER_DEPENDENCY_SOUND (1 << CONF_SUBSYSTEM_SOUND)
+#define CONF_DRIVER_DEPENDENCY_PCM_DEVICE (1 << CONF_SUBSYSTEM_PCM_DEVICE)
+#define CONF_DRIVER_DEPENDENCY_MIXER (1 << CONF_SUBSYSTEM_MIXER)
+#define CONF_DRIVER_DEPENDENCY_SEQ (1 << CONF_SUBSYSTEM_SEQ)
+#define CONF_DRIVER_DEPENDENCY_SOFTSEQ (1 << CONF_SUBSYSTEM_SOFTSEQ)
+#define CONF_DRIVER_DEPENDENCY_TIMER (1 << CONF_SUBSYSTEM_TIMER)
+
+#define CONF_BUILTIN_DEPENDENCIES (CONF_DRIVER_DEPENDENCY_GFX | CONF_DRIVER_DEPENDENCY_SOUND)
+
+/* ---------------------------------------------- */
+/* -- convenience macros for driver developers -- */
+/* ---------------------------------------------- */
+
+
+char *
+conf_default_set_option(void * self, conf_option_t *option,
+ union { char *str;
+ int nr } value);
+/* Default implementation of the option setting function
+** Parameters: (void *) self: Reference to the structure we should be accessing
+** (conf_option_t *) option: The option to set
+** (char * | nr) value: The value to set
+** Returns : (char *) NULL on success, a static error string otherwise
+*/
+
+
+#define CONF_MK_HEADER(NAME, VERSION, SUBSYSTEM, DEPENDENCIES, OPTIONS, SETOPTION) \
+ { \
+ CONF_DRIVER_MAGIC, \
+ CONF_DRIVER_VERSION, \
+ SUBSYSTEM, \
+ 0, \
+ NAME, \
+ VERSION, \
+ DEPENDENCIES, \
+ OPTIONS, \
+ SETOPTION }
+
+#define CONF_OPT_ANY(STRUCTURE, FIELD, NAME, TYPE, DEFAULT, MIN, MAX, VALUES, FLAGS, DESCRIPTION) \
+ { \
+ NAME, \
+ DESCRIPTION, \
+ TYPE, \
+ FLAGS, \
+ DEFAULT, \
+ MIN, \
+ MAX, \
+ VALUES, \
+ (void *)(offsetof (STRUCTURE, FIELD)) \
+ }
+
+#define CONF_OPT_INT(S, F, NAME, DEFAULT, FLAGS, DESCR) CONF_OPT_ANY(S, F, NAME, CONF_OPTION_TYPE_INT, {.nr = DEFAULT}, 0, 0, NULL, (FLAGS) | CONF_OPTION_HAS_DEFAULT, DESCR)
+#define CONF_OPT_INT_NODEFAULT(S, F, NAME, FLAGS, DESCR) CONF_OPT_ANY(S, F, NAME, CONF_OPTION_TYPE_INT, {.nr = 0}, 0, 0, NULL, (FLAGS), DESCR)
+
+#define CONF_OPT_SUBRANGE(S, F, NAME, DEFAULT, MIN, MAX, FLAGS, DESCR) CONF_OPT_ANY(S, F, NAME, CONF_OPTION_TYPE_SUBRANGE, {.nr = DEFAULT}, MIN, MAX, NULL, (FLAGS) | CONF_OPTION_HAS_DEFAULT, DESCR)
+#define CONF_OPT_SUBRANGE_NODEFAULT(S, F, NAME, MIN, MAX, FLAGS, DESCR) CONF_OPT_ANY(S, F, NAME, CONF_OPTION_TYPE_SUBRANGE, {.nr = 0}, MIN, MAX, NULL, (FLAGS), DESCR)
+
+#define CONF_OPT_STRING(S, F, NAME, DEFAULT, FLAGS, DESCR) CONF_OPT_ANY(S, F, NAME, CONF_OPTION_TYPE_STRING, {.str = DEFAULT}, 0, 0, NULL, (FLAGS) | CONF_OPTION_HAS_DEFAULT, DESCR)
+#define CONF_OPT_STRING_NODEFAULT(S, F, NAME, FLAGS, DESCR) CONF_OPT_ANY(S, F, NAME, CONF_OPTION_TYPE_STRING, {.str = NULL}, 0, 0, NULL, (FLAGS), DESCR)
+
+#define CONF_OPT_BOOL(S, F, NAME, DEFAULT, FLAGS, DESCR) CONF_OPT_ANY(S, F, NAME, CONF_OPTION_TYPE_INT, {.nr = DEFAULT}, 0, 0, NULL, (FLAGS) | CONF_OPTION_HAS_DEFAULT, DESCR)
+#define CONF_OPT_BOOL_NODEFAULT(S, F, NAME, FLAGS, DESCR) CONF_OPT_ANY(S, F, NAME, CONF_OPTION_TYPE_INT, {.nr = 0}, 0, 0, NULL, (FLAGS), DESCR)
+
+#define CONF_OPT_ENUM(S, F, NAME, DEFAULT, CHOICES, FLAGS, DESCR) CONF_OPT_ANY(S, F, NAME, CONF_OPTION_TYPE_INT, {.nr = DEFAULT}, 0, 0, CHOICES, (FLAGS) | CONF_OPTION_HAS_DEFAULT, DESCR)
+#define CONF_OPT_ENUM_NODEFAULT(S, F, NAME, CHOICES, FLAGS, DESCR) CONF_OPT_ANY(S, F, NAME, CONF_OPTION_TYPE_INT, {.nr = 0}, 0, 0, CHOICES, (FLAGS), DESCR)
+
+#define CONF_LAST_OPTION { NULL, NULL, -1, 0, 0, 0, 0, NULL }
+
+
+#endif /* !defined(CONF_DRIVER_H_) */
diff --git a/engines/sci/include/conf_extension.h b/engines/sci/include/conf_extension.h
new file mode 100644
index 0000000000..768e8f28c3
--- /dev/null
+++ b/engines/sci/include/conf_extension.h
@@ -0,0 +1,71 @@
+/***************************************************************************
+ Copyright (C) 2008 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantability,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+/* Config extensions handle special-purpose configuration options such as the
+** graphics operations. To add new special-purpose operations, modify this file,
+** the lexer, and conf_extensions.c.
+*/
+
+#ifndef CONF_EXTENSION_H_
+#define CONF_EXTENSION_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define CONF_EXT_TYPE_INVALID -1
+#define CONF_EXT_TYPE_GFX 0
+
+typedef struct {
+ int type; /* CONF_EXT_TYPE_* */
+ void *data;
+} conf_extension_t;
+
+
+
+int
+conf_extension_supercedes(conf_extension_t *a, conf_extension_t *b);
+/* Determines whether conf extension b shadows extension a
+** Parameters: (conf_extension_t *) a: The ``earlier'' extension
+** (conf_extension_t *) b: The ``later'' extension
+** Returns : nonzero iff shadowing does occur
+*/
+
+void
+conf_extension_print(FILE *file, conf_extension_t *a);
+/* Prints out a config extension
+** Parameters: (FILE *) file: The file to print to
+** (conf_extension_t *) a: The extension to print out
+*/
+
+void
+conf_extension_free(conf_extension_t *a);
+/* Frees up all data associated with a conf extension
+** Parameters: (conf_extension_t *) a: The extension to free
+** This also frees up a itself.
+*/
+
+#endif /* !defined CONF_EXTENSION_H_ */
diff --git a/engines/sci/include/conf_parse.h b/engines/sci/include/conf_parse.h
new file mode 100644
index 0000000000..d5ffd5b9da
--- /dev/null
+++ b/engines/sci/include/conf_parse.h
@@ -0,0 +1,108 @@
+/***************************************************************************
+ conf_parse.h Copyright (C) 2007 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+/* RAW parse (config layers zero and one) */
+
+#ifndef CONF_PARSE_H_
+#define CONF_PARSE_H_
+#include <conf_extension.h>
+
+#define CONF_PARSE_TYPE_WHITESPACE 1 /* Whitespace, comments */
+#define CONF_PARSE_TYPE_SUBSECTION 2 /* Subsection division */
+#define CONF_PARSE_TYPE_OPTION 3 /* Option or driver assignment */
+#define CONF_PARSE_TYPE_INCLUDE 4 /* External include file */
+#define CONF_PARSE_TYPE_EXTENSION 5 /* An ``extension'' */
+#define CONF_PARSE_TYPE_LEXERROR 255 /* Something lexically broken (stored in ``whitespace'') */
+
+/* Base options */
+#define CONF_PARSE_BASEOPTION_VERSION 0
+#define CONF_PARSE_BASEOPTION_RESOURCEDIR 1
+#define CONF_PARSE_BASEOPTION_DEBUGMODE 2
+
+typedef struct _conf_parse_struct {
+ int type; /* c. CONF_PARSE_TYPE */
+ int line_nr; /* Line number in the current input file */
+
+ struct _conf_parse_struct *prev;
+ struct _conf_parse_struct *next;
+ struct _conf_parse_struct *overridden; /* In case we overrode something */
+
+ union {
+ char *whitespace;
+ struct {
+ char *subsystem; /* may be NULL if driver==NULL */
+ char *driver; /* may be NULL */
+ char *option;
+ char *centre_whitespace;
+ char *value;
+ char *terminal_whitespace;
+ } assignment; /* driver assignment, option */
+ struct {
+ char *pre_whitespace;
+ char *name;
+ char *post_whitespace;
+ } subsection;
+ struct {
+ char *include_prefix; /* NULL for system includes */
+ char *filename; /* Extracted from include_stmt, also a copy */
+ char *include_suffix; /* NULL for system includes */
+ int modifiable; /* May we write to this file? */
+ struct _conf_parse_struct *options_head;
+ struct _conf_parse_struct *options_end;
+ } include;
+ conf_extension_t *extension; /* Extended information, cf. conf_extension.h */
+ } data;
+} conf_parse_t;
+
+
+
+conf_parse_t *
+conf_read_file(char *config_file_name, int modifiable, conf_parse_t *previous);
+/* Read configuration file
+** Parameters: (char *) config_file_name: File name for the source config file
+** (int) modifiable: Whether to treat the result as modifiable
+** (conf_parse_t *) previous: Head of the previous configuration, or NULL if none
+** Returns : (conf_parse_t *) Head of the combined config parse, or NULL on failure
+** Effects : (stderr) Error message if the specified file was found but parsing failed
+*/
+
+void
+conf_free_parse(conf_parse_t *raw_config);
+/* Deallocates a conf_parse_t
+** Parameters: (conf_parse_t *) raw_config: The raw parse to deallocate
+** Returns : usually.
+*/
+
+void
+conf_write_parse(conf_parse_t *raw_config);
+/* Writes out all writeable parts of the configuration parse to the source files, if writeable
+** Parameters: (conf_parse_t *) raw_config
+** Effects : (stderr) Prints error message if ``modifiable'' file could not be written to
+** (filesystem) All ``modifiable'' config files are overwritten
+*/
+
+#endif /* !defined (CONF_PARSE_H_) */
diff --git a/engines/sci/include/conf_subsystems.h b/engines/sci/include/conf_subsystems.h
new file mode 100644
index 0000000000..a2cfe0c42d
--- /dev/null
+++ b/engines/sci/include/conf_subsystems.h
@@ -0,0 +1,80 @@
+/***************************************************************************
+ Copyright (C) 2007 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef CONF_SUBSYSTEMS_H_
+#define CONF_SUBSYSTEMS_H_
+
+#include "conf_parse.h"
+#include "conf_driver.h"
+
+conf_parse_t *
+conf_validate(conf_main_t *main, conf_parse_t *raw_config);
+/* Validates raw configuration data (including subsections) and fills in ``overridden'' and ``prev'' pointers
+** Parameters: (conf_parse_t *) raw_config: The raw config data
+** Returns : (conf_parse_t *) The updated raw_config on success, or NULL if validation failed
+** (raw_config is not freed in that case)
+** Effects : (stderr) Error message(s) if validation failed
+*/
+
+int
+conf_init(conf_main_t *main, conf_parse_t *config, const char *id);
+/* Validates all parameters, sets all parameters, loads modules, initialises drivers and subsystems and the main module
+** Parameters: (conf_main_t *) The main config element
+** (conf_parse_t *) The parse
+** (char *) id: The game ID to choose for initialisation, or NULL for default
+** Effects : (stderr) Error message(s) if validation failed
+*/
+
+char *
+conf_set_main_option(conf_main_t *main, const char *option, const char *value);
+/* Sets a value for the main module
+** Parameters: (char *) option: Name of the option to set
+** (char *) value: Value to set
+** Returns : (char *) NULL on success, an error message otherwise
+*/
+
+char *
+conf_set_subsystem_option(conf_main_t *main, const char *subsystem, const char *option, const char *value);
+/* Sets a value for the main module
+** Parameters: (char *) option: Name of the option to set
+** (char *) value: Value to set
+** (char *) subsystem: Name of the subsystem to manipulate
+** Returns : (char *) NULL on success, an error message otherwise
+*/
+
+char *
+conf_set_driver_option(conf_main_t *main, const char *subsystem, const char *driver, const char *option, const char *value);
+/* Sets a value for the main module
+** Parameters: (char *) option: Name of the option to set
+** (char *) value: Value to set
+** (char *) subsystem: Name of the subsystem to manipulate
+** (char *) driver: Name of the driver to manipulate
+** Returns : (char *) NULL on success, an error message otherwise
+** Automatically loads the driver, if neccessary
+*/
+
+#endif /* !defined(CONF_SUBSYSTEMS_H_) */
diff --git a/engines/sci/include/conf_summary.h b/engines/sci/include/conf_summary.h
new file mode 100644
index 0000000000..c2a1f8e16e
--- /dev/null
+++ b/engines/sci/include/conf_summary.h
@@ -0,0 +1,106 @@
+/***************************************************************************
+ conf_summary.h Copyright (C) 2007 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef CONF_SUMMARY_H_
+#define CONF_SUMMARY_H_
+
+#include<conf_parse.h>
+#include<conf_driver.h>
+
+typedef struct {
+ conf_option_t *option; /* NULL if this is a terminator */
+ conf_parse_t *parse; /* Source location we got this information from,
+ ** or NULL for command-line or default */
+ union { char *str;
+ int nr } choice;
+ int origin;
+ int flags;
+} conf_option_choice_t;
+
+#define CONF_CHOICE_ORIGIN_DEFAULT 0 /* Built-in default */
+#define CONF_CHOICE_ORIGIN_CONFDEFAULT 1 /* Config file option */
+#define CONF_CHOICE_ORIGIN_CONFGAME 2 /* Game-specific option */
+#define CONF_CHOICE_ORIGIN_COMMANDLINE 3
+
+#define CONF_CHOICE_FLAG_WRITEABLE (1<<0) /* 'parse' can be written to */
+#define CONF_CHOICE_FLAG_DISABLED (1<<1) /* Option isn't set, only listed for completeness */
+
+typedef struct {
+ conf_option_choice_t *options; /* Driver-specific */
+ conf_driver_t *driver;
+} conf_driver_choice_t;
+
+typedef struct {
+ conf_option_choice_t *options; /* Subsystem-specific */
+ int driver_origin; /* CONF_CHOICE_ORIGIN_* */
+ conf_driver_choice_t *driver; /* The particular driver selected */
+ conf_driver_choice_t *drivers; /* All available drivers, with their options */
+} conf_subsystem_choice_t;
+
+typedef struct {
+ char *game_id; /* NULL for default */
+ conf_option_choice_t *options; /* Global */
+ int flags;
+ conf_parse_t **append_location; /* Into here we can add new configuration options to override */
+
+ conf_subsystem_choice_t[CONF_SUBSYSTEMS_NR] subsystems;
+} conf_game_choice_t;
+
+#define CONF_GAME_CHOICE_FLAG_OVERRIDE_IN_SECTION (1<<0) /* Override section already exists, need not be re-created */
+
+typedef struct {
+ conf_game_choice_t *default;
+
+ int game_choices_nr;
+ conf_game_choice_t *game_choices;
+} conf_summary_t;
+
+
+conf_summary_t *
+conf_summary(conf_parse_t *raw_config);
+/* Summarises a config parse in a conf_summary_t
+** Parameters: (conf_parse_t *) raw_config: The parse to summarise
+** Returns : (conf_summary_t *) A summarised configuration
+** The summary includes (default) values for all driver/subsystem options
+*/
+
+void
+conf_free_summary(conf_summary_t *summary);
+/* Deallocates a configuration summary
+** Parameters: (conf_summary_t *) summary: The summary to deallocate
+** This only affects the summary, not the underlying parse.
+*/
+
+conf_game_choice_t *
+conf_find_choice(conf_summary_t *choices, char *game_id);
+/* Finds the correct game choice by game ID
+** Parameters: (conf_summary_t *) summary: The summary to peruse
+** (char *) game_id: Identified game ID.
+** We search by exact match or otherwise default.
+*/
+
+#endif /* !defined (CONF_SUMMARY_H_) */
diff --git a/engines/sci/include/console.h b/engines/sci/include/console.h
new file mode 100644
index 0000000000..fafa276298
--- /dev/null
+++ b/engines/sci/include/console.h
@@ -0,0 +1,254 @@
+/***************************************************************************
+ console.h Copyright (C) 1999,2000,01 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CJR) [creichen@rbg.informatik.tu-darmstadt.de]
+
+***************************************************************************/
+/* Header file for the SCI console.
+** Please note that the console does not use the priority field; the console
+** should therefore be drawn after everything else has been drawn (with the
+** possible exception of the mouse pointer).
+*/
+
+#ifndef _SCI_CONSOLE_H_
+#define _SCI_CONSOLE_H_
+
+#include <sci_memory.h>
+#include <resource.h>
+#include <vm_types.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#ifdef _DOS
+#include <sci_dos.h>
+#endif
+
+#define SCI_CONSOLE
+#include <gfx_operations.h>
+
+
+extern DLLEXTERN int con_passthrough;
+/* Echo all sciprintf() stuff to the text console */
+extern FILE *con_file;
+/* Echo all sciprintf() output to a text file. Note: clients of freesci.dll
+** should use open_console_file and close_console_file, rather than refer
+** directly to the con_file variable.
+*/
+
+struct _state; /* state_t later on */
+
+typedef union {
+ long val;
+ char *str;
+ reg_t reg;
+} cmd_param_t;
+
+extern unsigned int cmd_paramlength;
+/* The number of parameters passed to a function called from the parser */
+
+extern cmd_param_t *cmd_params;
+/* The parameters passed to a function called by the parser */
+
+extern struct _state *con_gamestate;
+/* The game state as used by some of the console commands */
+
+
+/*** FUNCTION DEFINITIONS ***/
+
+void
+con_set_string_callback(void(*callback)(char *));
+/* Sets the console string callback
+** Parameters: (void -> char *) callback: The closure to invoke after
+** a string for sciprintf() has been generated
+** This sets a single callback function to be used after sciprintf()
+** is used.
+*/
+
+void
+con_set_pixmap_callback(void(*callback)(gfx_pixmap_t *));
+/* Sets the console pixmap callback
+** Parameters: (void -> gfx_pixmap_t *) callback: The closure to invoke after
+** a pixmap has been provided to be
+** published in the on-screen console
+** This sets a single callback function to be used after sciprintf()
+** is used.
+*/
+
+void
+con_init(void);
+/* Initializes the command parser
+** Parameters: (void)
+** Returns : (void)
+** This function will initialize hook up a few commands to the parser.
+** It must be called before cmdParse() is used.
+*/
+
+
+void
+con_parse(struct _state *s, const char *command);
+/* Parses a command and summons appropriate facilities to handle it
+** Parameters: (state_t *) s: The state_t to use
+** command: The command to execute
+** Returns : (void)
+*/
+
+
+int
+con_hook_command(int command(struct _state *s), const char *name, const char *param, const char *description);
+/* Adds a command to the parser's command list
+** Parameters: command: The command to add
+** name: The command's name
+** param: A description of the parameters it takes
+** description: A short description of what it does
+** Returns : 0 if successful, 1 if appending failed because
+** of an incorrect *param string, 'command'==0, or
+** 'name' already being in use.
+** A valid param string is either empty (no parameters allowed)
+** or contains one of the following tokens:
+** ! Special token: state_t* must be set for this function to be called
+** i (an int)
+** s (a 'string' (char *))
+** h (a byte, described in hexadecimal digits)
+** a (a heap address, register or object name)
+** r (any register value)
+** x* (an arbitrary (possibly 0) number of 'x' tokens)
+** The '*' token may only be used as the last token of the list.
+** Another way to specify optional parameters is by means of the
+** '-opt:t' notation, which allows an optional parameter of type 't'
+** to be specified as 'opt:<value>' when calling. See also the
+** con_hasopt() and con_getopt() calls.
+**
+** Please note that the 'h' type does accept hexadecimal numbers greater
+** than 0xff and less than 0x00, but clips them to this range.
+**
+** Example: "isi*" would define the function to take an int, a
+** string, and an arbitrary number of ints as parameters (in that sequence).
+**
+** When the function is called, it can retrieve its parameters from cmd_params;
+** the actual number of parameters is stored in cmd_paramlength.
+** It is allowed to modify the char*s from a cmd_params[] element, as long
+** as no element beyond strlen(cmd_params[x].str)+1 is accessed.
+*/
+
+cmd_param_t
+con_getopt(char *opt);
+/* Retreives the specified optional parameter
+** -- for use within console functions only --
+** Parameters: (char *) opt: The optional parameter to retreive
+** Returns : (cmd_param_t) The corresponding parameter
+** Should only be used if con_hasopt() reports its presence.
+*/
+
+int
+con_hasopt(char *opt);
+/* Checks whether an optional parameter was specified
+** -- for use within console functions only --
+** Parameters: (char *) opt: The optional parameter to check for
+** Returns : (int) non-zero iff the parameter was specified
+*/
+
+int
+con_can_handle_pixmaps(void);
+/* Determines whether the console supports pixmap inserts
+** Returns : (int) non-zero iff pixmap inserts are supported
+*/
+
+int
+con_insert_pixmap(gfx_pixmap_t *pixmap);
+/* Inserts a pixmap into the console history buffer
+** Parameters: (gfx_pixmap_t *) pixmap: The pixmap to insert
+** Returns : (int) 0 on success, non-zero if no receiver for
+** the pixmap could not be found
+** The pixmap must be unique; it is freed by the console on demand.
+** Use gfx_clone_pixmap() if neccessary.
+** If the pixmap could not be inserted, the called must destroy it
+*/
+
+int
+con_hook_page(const char *topic, const char *body);
+/* Hooks a general information page to the manual page system
+** Parameters: (const char *) topic: The topic name
+** (const char *) body: The text body to assign to the topic
+** Returns : (int) 0 on success
+*/
+
+int
+con_hook_int(int *pointer, const char *name, const char *description);
+/* Adds an int to the list of modifyable ints.
+** Parameters: pointer: Pointer to the int to add to the list
+** name: Name for this value
+** description: A short description for the value
+** Returns : 0 on success, 1 if either value has already been added
+** or if name is already being used for a different value.
+** The internal list of int references is used by some of the basic commands.
+*/
+
+
+void
+con_gfx_init(void);
+/* Initializes the gfx console
+*/
+
+void
+con_gfx_show(gfx_state_t *state);
+/* Enters on-screen console mode
+** Parameters: (gfx_state_t *state): The graphics state to use for interaction
+** Returns : (void)
+*/
+
+char *
+con_gfx_read(gfx_state_t *state);
+/* Reads a single line from the on-screen console, if it is open
+** Parameters: (gfx_state_t *state): The graphics state to use for interaction
+** Returns : (char *) The input, in a static buffer
+*/
+
+void
+con_gfx_hide(gfx_state_t *stae);
+/* Closes the on-screen console
+** Parameters: (gfx_state_t *state): The graphics state to use for interaction
+** Returns : (void)
+*/
+
+
+int
+sci_hexdump(byte *data, int length, int offsetplus);
+
+void
+open_console_file(char *filename);
+/* Opens the file to which the console output is echoed. If a file was opened
+** before, closes it.
+** Parameters: filename - name of the file
+** Returns : (void)
+*/
+
+void
+close_console_file(void);
+/* Closes the console output file.
+** Parameters: (void)
+** Returns : (void)
+*/
+
+#endif /* _SCI_CONSOLE_H_ */
diff --git a/engines/sci/include/engine.h b/engines/sci/include/engine.h
new file mode 100644
index 0000000000..08a26fe98b
--- /dev/null
+++ b/engines/sci/include/engine.h
@@ -0,0 +1,306 @@
+/***************************************************************************
+ engine.h Copyright (C) 1999,2000,01 Christoph Reichenbach
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CJR) [creichen@rbg.informatik.tu-darmstadt.de]
+
+***************************************************************************/
+#ifndef _SCI_ENGINE_H
+#define _SCI_ENGINE_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <resource.h>
+#include <sciresource.h>
+#include <script.h>
+#include <vocabulary.h>
+#include <console.h>
+#include <vm.h>
+#include <menubar.h>
+#include <time.h>
+#include <versions.h>
+#include <kernel.h>
+#include <gfx_state_internal.h>
+#include <sfx_engine.h>
+
+#define FREESCI_CURRENT_SAVEGAME_VERSION 7
+#define FREESCI_MINIMUM_SAVEGAME_VERSION 7
+
+#ifdef WIN32
+# define FREESCI_GAMEDIR "FreeSCI"
+# define STRLEN_FREESCI_GAMEDIR 7
+#else
+# define FREESCI_GAMEDIR ".freesci"
+# define STRLEN_FREESCI_GAMEDIR 8
+#endif
+
+#define FREESCI_CONFFILE "config"
+#define FREESCI_SAVEDIR_PREFIX "save_"
+#define FREESCI_CONFFILE_DOS "freesci.cfg"
+#define FREESCI_GAMES_DIR "games"
+
+#define FREESCI_FILE_STATE "state"
+#define FREESCI_ID_SUFFIX ".id"
+/* Used for <gamename>.id files ("real" save games) */
+
+#define MAX_GAMEDIR_SIZE 32 /* Used for subdirectory inside of "~/.freesci/" */
+#define MAX_SAVEGAME_NR 20 /* Maximum number of savegames */
+
+#define MAX_SAVE_DIR_SIZE MAX_HOMEDIR_SIZE + STRLEN_FREESCI_GAMEDIR + MAX_GAMEDIR_SIZE + 4
+/* +4 for the three slashes and trailing \0 */
+
+/* values for state_t.restarting_flag */
+#define SCI_GAME_IS_NOT_RESTARTING 0
+#define SCI_GAME_WAS_RESTARTED 1
+#define SCI_GAME_IS_RESTARTING_NOW 2
+#define SCI_GAME_WAS_RESTARTED_AT_LEAST_ONCE 4
+
+typedef struct {
+ int nr;
+ int palette;
+} drawn_pic_t;
+
+typedef struct _state
+{
+ int savegame_version;
+
+ int widget_serial_counter; /* Used for savegames */
+
+ char *resource_dir; /* Directory the resource files are kept in */
+ char *work_dir; /* Directory the game metadata should be written to */
+ resource_mgr_t *resmgr; /* The resource manager */
+
+ char *game_name; /* Designation of the primary object (which inherits from Game) */
+ char *game_version;
+
+ /* Non-VM information */
+
+ gfx_state_t *gfx_state; /* Graphics state and driver */
+ gfx_pixmap_t *old_screen; /* Old screen content: Stored during kDrawPic() for kAnimate() */
+
+ sfx_state_t sound; /* sound subsystem */
+ int sfx_init_flags; /* flags the sfx subsystem was initialised with */
+ unsigned int sound_volume; /* 0x0 -> 0xf Current volume of sound system */
+ unsigned int sound_mute; /* 0 = not, else == saved value */
+
+ byte restarting_flags; /* Flags used for restarting */
+ byte have_mouse_flag; /* Do we have a hardware pointing device? */
+
+ byte pic_not_valid; /* Is 0 if the background picture is "valid" */
+ byte pic_is_new; /* New pic was loaded or port was opened */
+ byte onscreen_console; /* Use the onscreen console for debugging */
+ byte *osc_backup; /* Backup of the pre-onscreen console screen data */
+
+ int *pic_priority_table; /* 16 entries with priorities or NULL if not present */
+
+ char *status_bar_text; /* Text on the status bar, or NULL if the title bar is blank */
+
+ int status_bar_foreground, status_bar_background;
+
+ long game_time; /* Counted at 60 ticks per second, reset during start time */
+
+ reg_t save_dir_copy; /* Last copy of the save dir */
+ int save_dir_edit_offset; /* For kEdit(): Display offset for editing the savedir */
+ char *save_dir_copy_buf; /* Temp savedir buffer for kEdit() */
+
+ int mouse_pointer_view; /* Mouse pointer resource, or -1 if disabled */
+ int mouse_pointer_loop; /* Mouse pointer resource, or -1 if disabled */
+ int mouse_pointer_cel; /* Mouse pointer resource, or -1 if disabled */
+ int save_mouse_pointer_view; /* Temporary storage for mouse pointer resource, when the pointer is hidden */
+ int save_mouse_pointer_loop; /* Temporary storage for mouse pointer resource, when the pointer is hidden */
+ int save_mouse_pointer_cel; /* Temporary storage for mouse pointer resource, when the pointer is hidden */
+
+ int port_serial; /* Port serial number, for save/restore */
+ gfxw_port_t *port; /* The currently active port */
+
+ gfx_color_t ega_colors[16]; /* The 16 EGA colors- for SCI0(1) */
+
+ gfxw_visual_t *visual; /* A visual widget, containing all ports */
+
+ gfxw_port_t *titlebar_port; /* Title bar viewport (0,0,9,319) */
+ gfxw_port_t *wm_port; /* window manager viewport and designated &heap[0] view (10,0,199,319) */
+ gfxw_port_t *picture_port; /* The background picture viewport (10,0,199,319) */
+ gfxw_port_t *iconbar_port; /* Full-screen port used for non-clipped icon bar draw in SCI1 */
+
+ gfx_map_mask_t pic_visible_map; /* The number of the map to display in update commands */
+ int pic_animate; /* The animation used by Animate() to display the picture */
+
+ int dyn_views_list_serial; /* Used for save/restore */
+ gfxw_list_t *dyn_views; /* Pointers to pic and dynamic view lists */
+
+ int drop_views_list_serial; /* Used for save/restore */
+ gfxw_list_t *drop_views; /* A list Animate() can dump dropped dynviews into */
+
+ long animation_delay; /* A delay factor for pic opening animations. Defaults to 500. */
+ int animation_granularity; /* Number of animation steps to perform betwen updates for transition animations */
+
+ menubar_t *menubar; /* The menu bar */
+
+ int priority_first; /* The line where priority zone 0 ends */
+ int priority_last; /* The line where the highest priority zone starts */
+
+ int pics_drawn_nr;
+ int pics_nr;
+ drawn_pic_t *pics;
+
+ GTimeVal game_start_time; /* The time at which the interpreter was started */
+ GTimeVal last_wait_time; /* The last time the game invoked Wait() */
+
+ byte version_lock_flag; /* Set to 1 to disable any autodetection mechanisms */
+ sci_version_t version; /* The approximated patchlevel of the version to emulate */
+ sci_version_t max_version, min_version; /* Used for autodetect sanity checks */
+
+ unsigned int kernel_opt_flags; /* Kernel optimization flags- used for performance tweaking */
+
+ /* Kernel File IO stuff */
+
+ int file_handles_nr; /* maximum numer of allowed file handles */
+ FILE **file_handles; /* Array of file handles. Dynamically increased if required. */
+
+ reg_t dirseeker_outbuffer;
+ sci_dir_t dirseeker;
+
+ /* VM Information */
+
+ exec_stack_t *execution_stack; /* The execution stack */
+ int execution_stack_size; /* Number of stack frames allocated */
+ int execution_stack_pos; /* Position on the execution stack */
+ int execution_stack_base; /* When called from kernel functions, the vm
+ ** is re-started recursively on the same stack.
+ ** This variable contains the stack base for the
+ ** current vm.
+ */
+ int execution_stack_pos_changed; /* Set to 1 if the execution stack position
+ ** should be re-evaluated by the vm
+ */
+
+ reg_t r_acc; /* Accumulator */
+ unsigned int r_amp_rest; /* &rest register (only used for save games) */
+ reg_t r_prev; /* previous comparison result */
+
+ seg_id_t stack_segment; /* Heap area for the stack to use */
+ stack_ptr_t stack_base; /* Pointer to the least stack element */
+ stack_ptr_t stack_top; /* First invalid stack element */
+
+ seg_id_t parser_segment; /* A heap area used by the parser for error reporting */
+ reg_t parser_base; /* Base address for the parser error reporting mechanism */
+ reg_t parser_event; /* The event passed to Parse() and later used by Said() */
+ seg_id_t script_000_segment;
+ script_t *script_000; /* script 000, e.g. for globals */
+
+ int parser_lastmatch_word; /* Position of the input word the parser last matched on, or SAID_NO_MATCH */
+
+ /* Debugger data: */
+ breakpoint_t *bp_list; /* List of breakpoints */
+ int have_bp; /* Bit mask specifying which types of breakpoints are used in bp_list */
+ unsigned int debug_mode; /* Contains flags for the various debug modes */
+
+ /* System strings */
+ seg_id_t sys_strings_segment;
+ sys_strings_t *sys_strings;
+
+ /* Parser data: */
+ word_t **parser_words;
+ int parser_words_nr;
+ suffix_t **parser_suffices;
+ int parser_suffices_nr;
+ parse_tree_branch_t *parser_branches;
+ parse_rule_list_t *parser_rules; /* GNF rules used in the parser algorithm */
+ int parser_branches_nr;
+ parse_tree_node_t parser_nodes[VOCAB_TREE_NODES]; /* The parse tree */
+
+ int parser_valid; /* If something has been correctly parsed */
+
+ synonym_t *synonyms; /* The list of synonyms */
+ int synonyms_nr;
+
+ reg_t game_obj; /* Pointer to the game object */
+
+ int classtable_size; /* Number of classes in the table- for debugging */
+ class_t *classtable; /* Table of all classes */
+
+ seg_manager_t seg_manager;
+ int gc_countdown; /* Number of kernel calls until next gc */
+
+ int selector_names_nr; /* Number of selector names */
+ char **selector_names; /* Zero-terminated selector name list */
+ int kernel_names_nr; /* Number of kernel function names */
+ char **kernel_names; /* List of kernel names */
+
+ kfunct_sig_pair_t *kfunct_table; /* Table of kernel functions */
+ int kfunct_nr; /* Number of mapped kernel functions; may be more than
+ ** kernel_names_nr */
+
+ opcode *opcodes;
+
+ selector_map_t selector_map; /* Shortcut list for important selectors */
+
+ /* Backwards compatibility crap */
+ int port_ID;
+
+ struct _state *successor; /* Successor of this state: Used for restoring */
+
+} state_t;
+
+
+#define STATE_T_DEFINED
+
+int
+gamestate_save(state_t *s, char *dirname);
+/* Saves a game state to the hard disk in a portable way
+** Parameters: (state_t *) s: The state to save
+** (char *) dirname: The subdirectory to store it in
+** Returns : (int) 0 on success, 1 otherwise
+*/
+
+state_t *
+gamestate_restore(state_t *s, char *dirname);
+/* Restores a game state from a directory
+** Parameters: (state_t *) s: An older state from the same game
+** (char *) dirname: The subdirectory to restore from
+** Returns : (state_t *) NULL on failure, a pointer to a valid state_t otherwise
+*/
+
+gfx_pixmap_color_t *
+get_pic_color(state_t *s, int color);
+/* Retrieves the gfx_pixmap_color_t associated with a game color index
+** Parameters: (state_t *) s: The game state
+** (int) color: The color to look up
+** Returns : (gfx_pixmap_color_t *) The requested color.
+*/
+
+void
+other_libs_exit(void);
+/* Called directly before FreeSCI ends to allow libraries to clean up
+*/
+
+static inline
+reg_t not_register(state_t *s, reg_t r)
+{
+ if (s->version >= SCI_VERSION_FTU_INVERSE_CANBEHERE)
+ return make_reg(0, !r.offset); else
+ return r;
+
+}
+
+#endif /* !_SCI_ENGINE_H */
diff --git a/engines/sci/include/event.h b/engines/sci/include/event.h
new file mode 100644
index 0000000000..aea54b1af2
--- /dev/null
+++ b/engines/sci/include/event.h
@@ -0,0 +1,15 @@
+#ifndef EVENT_H
+#define EVENT_H
+
+#include <uinput.h>
+
+struct _state;
+
+sci_event_t getEvent (struct _state *s);
+/* Returns the next SCI_EV_* event
+** Parameters: (struct state *) Current game state
+** Returns : (sci_event_t) The next event, which may be any of the
+** existing events.
+*/
+
+#endif
diff --git a/engines/sci/include/game_select.h b/engines/sci/include/game_select.h
new file mode 100644
index 0000000000..91b3d957f6
--- /dev/null
+++ b/engines/sci/include/game_select.h
@@ -0,0 +1,38 @@
+#include "list.h"
+
+#ifndef _SCI_GAME_SELECT_H
+#define _SCI_GAME_SELECT_H
+
+typedef struct game
+{
+ char *name;
+ char dir[PATH_MAX];
+ int conf_nr;
+} game_t;
+
+typedef struct games_list
+{
+ LIST_ENTRY(games_list) entries;
+
+ game_t game;
+} games_list_t;
+
+typedef LIST_HEAD(games_list_head, games_list) games_list_head_t;
+
+int game_select_gfxop_init_default(gfx_state_t *state, gfx_options_t *options, void *misc_info);
+
+int game_select_gfxop_init(gfx_state_t *state, int xfact, int yfact, gfx_color_mode_t bpp, gfx_options_t *options, void *misc_info);
+
+int
+game_select_display(gfx_driver_t *gfx_driver, game_t* game_list, int game_count, gfx_bitmap_font_t* font_default, gfx_bitmap_font_t* font_small);
+
+void game_select_scan_info(gfx_driver_t *gfx_driver, gfx_bitmap_font_t* font_default, gfx_bitmap_font_t* font_small, char *name, int total);
+
+
+#if 0
+/* this can be used to generate code that creates a particular font at runtime */
+/* this is meant to be used as a development tool */
+void save_font(int id, gfx_bitmap_font_t* font)
+#endif
+
+#endif /* _SCI_GAME_SELECT_H */
diff --git a/engines/sci/include/gfx_driver.h b/engines/sci/include/gfx_driver.h
new file mode 100644
index 0000000000..9903208988
--- /dev/null
+++ b/engines/sci/include/gfx_driver.h
@@ -0,0 +1,438 @@
+/***************************************************************************
+ gfx_driver.h Copyright (C) 2000 Christoph Reichenbach
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef _SCI_GFX_DRIVER_H_
+#define _SCI_GFX_DRIVER_H_
+
+#include <gfx_system.h>
+#include <uinput.h>
+
+
+typedef enum {
+ GFX_BUFFER_FRONT = 0,
+ GFX_BUFFER_BACK = 1,
+ GFX_BUFFER_STATIC = 2
+} gfx_buffer_t;
+
+
+/* graphics driver hints */
+#define GFX_CAPABILITY_SHADING (1<<0)
+#define GFX_CAPABILITY_MOUSE_POINTER (1<<1)
+#define GFX_CAPABILITY_COLOR_MOUSE_POINTER (1<<2)
+#define GFX_CAPABILITY_PIXMAP_REGISTRY (1<<3)
+#define GFX_CAPABILITY_SCALEABLE_PIXMAPS (1<<4)
+#define GFX_CAPABILITY_STIPPLED_LINES (1<<6)
+#define GFX_CAPABILITY_MOUSE_SUPPORT (1<<7)
+#define GFX_CAPABILITY_POINTER_PIXMAP_REGISTRY (1<<8)
+#define GFX_CAPABILITY_FINE_LINES (1<<9)
+#define GFX_CAPABILITY_WINDOWED (1<<10)
+#define GFX_CAPABILITY_KEYTRANSLATE (1<<11)
+
+#define GFX_DEBUG_POINTER (1<<0)
+#define GFX_DEBUG_UPDATES (1<<1)
+#define GFX_DEBUG_PIXMAPS (1<<2)
+#define GFX_DEBUG_BASIC (1<<3) /* Basic geometric ops (lines, boxes, etc) */
+
+/* Principial graphics driver architecture
+** ---------------------------------------
+**
+** All graphics drivers must provide
+** - One visual front buffer (the actually visible thing)
+** - Two dynamic back buffers:
+** + visual
+** + priority
+** - Two static buffers (containing the background image and picviews):
+** + visual
+** + priority
+**
+** The control buffer is handled outside the graphics driver architecture.
+** Graphics are drawn by first setting the static buffers, then updating
+** the back buffers (from the static buffers), adding all picviews and other
+** widgets, and finally updating the front buffer.
+**
+** All coordinates refer to the scaled coordinate system.
+** Invalid parameters should produce an error message.
+** Support for some valid parameter values is optional (like different line
+** modes). If an unsupported but valid parameter is specified, the function
+** must use a reasonable default value.
+*/
+
+#define SCI_GFX_DRIVER_VERSION 0
+#define SCI_GFX_DRIVER_MAGIC 0xf001337
+
+typedef struct _gfx_driver { /* Graphics driver */
+
+ const char *name; /* Graphics driver name. Unique identifier, should consist of
+ ** lower-case (where applicable) alphanumerics
+ */
+
+ const char *version; /* Free-form version description (for informative purposes
+ ** only)
+ */
+
+ int sci_driver_magic; /* SCI_GFX_DRIVER_MAGIC */
+ int sci_driver_version; /* SCI_GFX_DRIVER_VERSION */
+
+ gfx_mode_t *mode; /* Currently active mode, NULL if no mode is active */
+
+ int pointer_x, pointer_y; /* Mouse pointer position */
+
+ int capabilities; /* The driver's capabilities: A list of flags that may
+ ** be pre-defined or set after a successful initialization.
+ */
+ /* Capability flags:
+ **
+ ** The words MUST, SHOULD and MAY are to be interpreted as described in
+ ** the IETF RFC 1123.
+ **
+ ** GFX_CAPABILITY_SHADING: draw_filled_rect() supports drawing shaded
+ ** rectangles.
+ ** GFX_CAPABILITY_MOUSE_POINTER: The driver has built-in support for mouse
+ ** pointers (monochrome or colored).
+ ** GFX_CAPABILITY_COLOR_MOUSE_POINTER: The driver has built-in support for
+ ** colored mouse pointers.
+ ** GFX_CAPABILITY_PIXMAP_REGISTRY: System provides a pixmap registry. The
+ ** invoking functions will assume that all pixmaps MUST be registered;
+ ** if this flag is not set, it assumes that pixmaps MUST NOT be
+ ** registered. Note that this excludes pointer pixmaps (see below)
+ ** GFX_CAPABILITY_POINTER_PIXMAP_REGISTRY: The system provides a pixmap
+ ** registry which mouse pointers have to be registered in explicitly.
+ ** This MUST be used only if the registry is identical to the 'normal' pixmap
+ ** registry. Otherwise, it MUST be handled manually by the driver,
+ ** unless pointer support is disabled completely.
+ ** GFX_CAPABILITY_SCALEABLE_PIXMAPS: Pixmap scaling is fully supported.
+ ** If this capability is flag is set, all pixmaps passed to the driver
+ ** will be unscaled.
+ ** GFX_CAPABILITY_STIPPLED_LINES: The driver is able to draw stippled lines
+ ** horizontally and vertically (xl = 0 or yl = 0).
+ ** GFX_CAPABILITY_MOUSE_SUPPORT: There is some support for mouse (or similar)
+ ** input. Note that this flag may be disabled by external code after
+ ** initialization time, if no support for mouse pointer /drawing/ is
+ ** available.
+ ** GFX_CAPABILITY_FINE_LINES: Should be set IFF the driver supports drawing
+ ** fine (width 1) lines
+ ** GFX_CAPABILITY_WINDOWED: Driver runs in a window and supports a debug
+ ** console running on stdin/stdout
+ ** GFX_CAPABILITY_KEYTRANSLATE: The driver's input layer automatically
+ ** handles 'shifted' keys (i.e. turning shift-'a' to 'A' etc.).
+ ** Drivers only need to handle this if they desire to support
+ ** non-US keyboard layouts, usually by localisation methods
+ ** provided by the underlying windowing or operating system.
+ */
+
+ unsigned int debug_flags; /* Driver debug flags */
+
+
+ /*** Initialization ***/
+
+ int (*set_parameter) (struct _gfx_driver *drv, char *attribute, char *value);
+ /* Sets a driver-specific parameter
+ ** Parameters: (gfx_driver_t *) drv: Pointer to the affected driver
+ ** (char *) attribute: Name of the attribute/parameter to set
+ ** (char *) value: The value to set, or NULL to query the value
+ ** Returns : (int) GFX_OK or GFX_FATAL, which signals a fatal error
+ ** condition.
+ ** This function should make extensive use of sciprintf() to signal invalid
+ ** values or unapplicable attributes.
+ ** Note that it may be called either before initialization (to interpret
+ ** config file or command line parameters) or afterwars (from the command
+ ** console).
+ */
+
+ int (*init_specific) (struct _gfx_driver *drv, int xres, int yres,
+ int bytespp);
+ /* Attempts to initialize a specific graphics mode
+ ** Parameters: (gfx_driver_t *) drv: The affected driver
+ ** (int x int) xres, yres: Horizontal and vertical scaling
+ ** factors
+ ** (int) bytespp: Any of GFX_COLOR_MODE_*. GFX_COLOR_MODE_INDEX
+ ** implies color index mode.
+ ** Returns : (int) GFX_OK on success, GFX_ERROR if the mode could not be
+ ** set, or GFX_FATAL if the graphics target is unuseable.
+ ** The scaling factors apply to the standard SCI resolution of 320x200 pixels
+ ** and is used for internal representation of graphical data. The physical
+ ** resolution set by the graphics driver may be different for practical
+ ** reasons.
+ ** Must also set drv->mode, preferably with the gfx_new_mode() function
+ ** specified in gfx_tools.h.
+ */
+
+ int (*init) (struct _gfx_driver *drv);
+ /* Initialize any graphics mode
+ ** Parameters: (gfx_driver_t *) drv: The affected driver
+ ** Returns : (int) GFX_OK on success, GFX_FATAL otherwise.
+ ** This function attempts to set /any/ graphics mode, starting with the one
+ ** most 'natural' to the graphics target. Target implementors have relatively
+ ** free reign in choosing the heuristics used to determine the resulting
+ ** mode.
+ ** Must also set drv->mode, preferably with the gfx_new_mode() function
+ ** specified in gfx_tools.h.
+ */
+
+ void (*exit) (struct _gfx_driver *drv);
+ /* Uninitializes the current graphics mode
+ ** Paramters: (gfx_driver_t *) drv: The driver to uninitialize
+ ** Return : (void)
+ ** This function frees all memory allocated by the graphics driver,
+ ** including mode and palette information, uninstalls all console commands
+ ** introduced by preceeding init() or init_specific() commands, and does any
+ ** clean-up work (like closing visuals or returning to text mode) required by
+ ** the graphics infrastructure used.
+ */
+
+
+ /*** Drawing operations ***/
+
+ int (*draw_line) (struct _gfx_driver *drv,
+ point_t start, point_t end,
+ gfx_color_t color,
+ gfx_line_mode_t line_mode, gfx_line_style_t line_style);
+ /* Draws a single line to the back buffer.
+ ** Parameters: (gfx_driver_t *) drv: The driver affected
+ ** (point_t) start: Starting point of the line to draw
+ ** (point_t) end: End point of the line to draw
+ ** (gfx_color_t *) color: The color to draw with
+ ** (int) line_mode: Any of the line modes
+ ** (int) line_style: Any of the line styles
+ ** Returns : (int) GFX_OK or GFX_FATAL
+ ** Note that color.priority is relevant and must be drawn if
+ ** (color.mask & GFX_MASK_PRIORITY).
+ ** Support for line modes other than GFX_LINE_MODE_FAST is optional.
+ ** For non-fine lines, the coordinates provided describe the upper left
+ ** corner of the pixels of the line to draw.
+ ** line_style support is optional, if GFX_CAPABILITY_STIPPLED_LINES is not
+ ** set.
+ */
+
+ int (*draw_filled_rect) (struct _gfx_driver *drv, rect_t rect,
+ gfx_color_t color1, gfx_color_t color2,
+ gfx_rectangle_fill_t shade_mode);
+ /* Draws a single filled and possibly shaded rectangle to the back buffer.
+ ** Parameters: (gfx_driver_t *) drv: The driver affected
+ ** (rect_t *) rect: The rectangle to draw
+ ** (gfx_color_t *) color1, color2: The colors to draw with
+ ** (int) shade_mode: Any of GFX_SHADE_*.
+ ** Returns : (int) GFX_OK or GFX_FATAL
+ ** Note that color.priority is relevant and must be drawn if
+ ** (color.mask & GFX_MASK_PRIORITY).
+ ** color2 is relevant only if shade_mode is not GFX_SHADE_FLAT.
+ ** Support for shade modes other than GFX_SHADE_FLAT is optional.
+ */
+
+ /*** Pixmap operations ***/
+
+ int (*register_pixmap) (struct _gfx_driver *drv, gfx_pixmap_t *pxm);
+ /* Registers a pixmap with the driver.
+ ** Parameters: (gfx_driver_t *) drv: The driver
+ ** (gfx_pixmap_t *) pxm: The pixmap to register
+ ** Returns : GFX_OK or GFX_FATAL
+ ** This function may be NULL if GFX_CAPABILITY_PIXMAP_REGISTRY is not
+ ** set.
+ ** pxm->internal may be used to store any handle or meta information.
+ */
+
+ int (*unregister_pixmap) (struct _gfx_driver *drv, gfx_pixmap_t *pxm);
+ /* Unregisters a pixmap previously registered with register_pixmap()
+ ** Parameters: (gfx_driver_t *) drv: The driver
+ ** (gfx_pixmap_t *) pxm: The pixmap to register
+ ** Returns : (int) GFX_OK or GFX_FATAL, or GFX_ERROR if pxm was
+ ** not registered
+ ** Just like register_pixmap(), this function may be NULL unless
+ ** GFX_CAPABILITY_PIXMAP_REGISTRY is set.
+ */
+
+ int (*draw_pixmap) (struct _gfx_driver *drv, gfx_pixmap_t *pxm, int priority,
+ rect_t src, rect_t dest, gfx_buffer_t buffer);
+ /* Draws part of a pixmap to the static or back buffer
+ ** Parameters: (gfx_driver_t *) drv: The affected driver
+ ** (gfx_pixmap_t *) pxm: The pixmap to draw
+ ** (int) priority: The priority to draw with, or GFX_NO_PRIORITY
+ ** to draw on top of everything without setting the
+ ** priority back buffer
+ ** (rect_t) src: The pixmap-relative source rectangle
+ ** (rect_t) dest: The destination rectangle
+ ** (int) buffer: One of GFX_BUFFER_STATIC and GFX_BUFFER_BACK
+ ** Returns : (int) GFX_OK or GFX_FATAL, or GFX_ERROR if pxm was not
+ ** (but should have been) registered.
+ ** dest.xl and dest.yl must be evaluated and used for scaling if
+ ** GFX_CAPABILITY_SCALEABLE_PIXMAPS is supported.
+ */
+
+ int (*grab_pixmap) (struct _gfx_driver *drv, rect_t src, gfx_pixmap_t *pxm,
+ gfx_map_mask_t map);
+ /* Grabs an image from the visual or priority back buffer
+ ** Parameters: (gfx_driver_t *) drv: The affected driver
+ ** (rect_t) src: The rectangle to grab
+ ** (gfx_pixmap_t *) pxm: The pixmap structure the data is to
+ ** be written to
+ ** (int) map: GFX_MASK_VISUAL or GFX_MASK_PRIORITY
+ ** Returns : (int) GFX_OK, GFX_FATAL, or GFX_ERROR for invalid map values
+ ** pxm may be assumed to be empty and pre-allocated with an appropriate
+ ** memory size.
+ ** This function is now mandatory.
+ */
+
+
+ /*** Buffer operations ***/
+
+ int (*update) (struct _gfx_driver *drv, rect_t src, point_t dest,
+ gfx_buffer_t buffer);
+ /* Updates the front buffer or the back buffers
+ ** Parameters: (gfx_driver_t *) drv: The affected driver
+ ** (rect_t) src: Source rectangle
+ ** (point_t) dest: Destination point
+ ** (int) buffer: One of GFX_BUFFER_FRONT or GFX_BUFFER_BACK
+ ** Returns : (int) GFX_OK, GFX_ERROR or GFX_FATAL
+ ** This function updates either the visual front buffer, or the two back
+ ** buffers, by copying the specified source region to the destination
+ ** region.
+ ** For heuristical reasons, it may be assumed that the x and y fields of
+ ** src and dest will be identical in /most/ cases.
+ ** If they aren't, the priority map will not be required to be copied.
+ */
+
+ int (*set_static_buffer) (struct _gfx_driver *drv, gfx_pixmap_t *pic,
+ gfx_pixmap_t *priority);
+ /* Sets the contents of the static visual and priority buffers
+ ** Parameters: (gfx_driver_t *) drv: The affected driver
+ ** (gfx_pixmap_t *) pic: The image defining the new content
+ ** of the visual back buffer
+ ** (gfx_pixmap_t *) priority: The priority map containing
+ ** the new content of the priority back buffer
+ ** in the index buffer
+ ** Returns : (int) GFX_OK or GFX_FATAL
+ ** pic and priority may be modified or written to freely. They may also be
+ ** used as the actual static buffers, since they are not freed and re-
+ ** allocated between calls to set_static_buffer() and update(), unless
+ ** exit() was called in between.
+ ** Note that later version of the driver interface may disallow modifying
+ ** pic and priority.
+ ** pic and priority are always scaled to the appropriate resolution, even
+ ** if GFX_CAPABILITY_SCALEABLE_PIXMAPS is set.
+ */
+
+
+ /*** Mouse pointer operations ***/
+
+ int (*set_pointer) (struct _gfx_driver *drv, gfx_pixmap_t *pointer);
+ /* Sets a new mouse pointer.
+ ** Parameters: (gfx_driver_t *) drv: The driver to modify
+ ** (gfx_pixmap_t *) pointer: The pointer to set, or NULL to set
+ ** no pointer
+ ** Returns : (int) GFX_OK or GFX_FATAL
+ ** This function may be NULL if GFX_CAPABILITY_MOUSE_POINTER is not set.
+ ** If pointer is not NULL, it will have been scaled to the appropriate
+ ** size and registered as a pixmap (if neccessary) beforehand.
+ ** If this function is called for a target that supports only two-color
+ ** pointers, the image is a color index image, where only color index values
+ ** 0, 1, and GFX_COLOR_INDEX_TRANSPARENT are used.
+ */
+
+
+ /*** Palette operations ***/
+
+ int (*set_palette) (struct _gfx_driver *drv, int index, byte red, byte green,
+ byte blue);
+ /* Manipulates a palette index in the hardware palette
+ ** Parameters: (gfx_driver_t *) drv: The driver affected
+ ** (int) index: The index of the palette entry to modify
+ ** (int x int x int) red, green, blue: The RGB intensities to
+ ** set for the specified index. The minimum
+ ** intensity is 0, maximum is 0xff.
+ ** Returns : (int) GFX_OK, GFX_ERROR or GFX_FATAL
+ ** This function does not need to update mode->palette, as this is done
+ ** by the calling code.
+ ** set_palette() is only required for targets supporting color index mode.
+ */
+
+
+ /*** Event management ***/
+
+ sci_event_t (*get_event) (struct _gfx_driver *drv);
+ /* Returns the next event in the event queue for this driver
+ ** Parameters: (gfx_driver_t *) drv: The driver to query
+ ** Returns : (sci_event_t) The oldest event still in the driver's event
+ ** queue, or the null event if there is none.
+ */
+
+ int (*usec_sleep) (struct _gfx_driver *drv, long usecs);
+ /* Sleeps the specified amount of microseconds, or until the mouse moves
+ ** Parameters: (gfx_driver_t *) drv: The relevant driver
+ ** (long) usecs: Amount of microseconds to sleep
+ ** Returns : (int) GFX_OK or GFX_FATAL
+ ** This function returns when the specified amount of microseconds has
+ ** elapsed, or when the mouse pointer has been moved and needs to be redrawn.
+ ** Only targets that can handle colored mouse pointers may choose to handle
+ ** all mouse management internally.
+ */
+
+ void *state; /* Reserved for internal use */
+
+} gfx_driver_t;
+
+
+
+gfx_driver_t *
+gfx_find_driver(char *, char *name);
+/* Attempts to match a graphics driver to a name
+** Parameters: (char *) path: The path to search in
+** (char *) name: The name of the graphics driver to look for
+** or NULL for the default driver
+** Returns : (gfx_driver_t *) The resulting driver, or NULL if none
+** was found
+*/
+
+const char *
+gfx_get_driver_name(int nr);
+/* Retreives the name of the driver with the specified number
+** Parameters: (int) nr: Number of the driver
+** (char *) The driver's name
+** Note that this function only makes sense within a loop or if nr=0, since
+** the result value is valid iff nr >= 0 AND there does not exist an nr'
+** with 0 <= nr' < nr so that gfx_get_driver_name(nr') == NULL.
+*/
+
+/*** Utility functions for set_parameter implementations */
+
+int
+string_truep(char *value);
+/* Tests whether a string expresses truth
+** Parameters: (char *) value: The value to test
+** Returns : non-zero iff 'value' contans a string expressing something
+** along the lines of "yes"
+*/
+
+int
+string_falsep(char *value);
+/* Tests whether a string expresses falsehood
+** Parameters: (char *) value: The value to test
+** Returns : non-zero iff 'value' contans a string expressing something
+** along the lines of "no"
+*/
+
+
+
+#endif /* !_SCI_GFX_DRIVER_H_ */
diff --git a/engines/sci/include/gfx_operations.h b/engines/sci/include/gfx_operations.h
new file mode 100644
index 0000000000..6e94523da8
--- /dev/null
+++ b/engines/sci/include/gfx_operations.h
@@ -0,0 +1,733 @@
+/***************************************************************************
+ gfx_operations.h Copyright (C) 2000,01 Christoph Reichenbach
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+/* Graphical operations, called from the widget state manager */
+
+#ifndef _GFX_OPERATIONS_H_
+#define _GFX_OPERATIONS_H_
+
+#include <gfx_resmgr.h>
+#include <gfx_tools.h>
+#include <gfx_options.h>
+#include <gfx_system.h>
+#include <uinput.h>
+
+#define GFXOP_NO_POINTER -1
+
+/* Threshold in color index mode to differentiate between visible and non-visible stuff.
+** GFXOP_ALPHA_THRESHOLD itself should be treated as non-visible.
+*/
+#define GFXOP_ALPHA_THRESHOLD 0xff
+
+typedef struct {
+ char *text; /* Copy of the actual text */
+
+ int lines_nr;
+ int line_height;
+ text_fragment_t *lines; /* Text offsets */
+ gfx_bitmap_font_t *font;
+ gfx_pixmap_t **text_pixmaps;
+
+ int width, height;
+
+ int priority, control;
+ gfx_alignment_t halign, valign;
+} gfx_text_handle_t;
+
+/* Unless individually stated otherwise, the following applies:
+** All operations herein apply to the standard 320x200 coordinate system.
+** All operations perform clipping relative to state->clip_zone.
+*/
+
+typedef enum {
+ GFX_BOX_SHADE_FLAT,
+ GFX_BOX_SHADE_RIGHT,
+ GFX_BOX_SHADE_LEFT,
+ GFX_BOX_SHADE_DOWN,
+ GFX_BOX_SHADE_UP
+#if 0
+ /* possible with alphaing, but there is no way to check for
+ ** alpha capability of gfx_driver->draw_filled_rect() yet
+ */
+ ,GFX_BOX_SHADE_RIGHT_DOWN,
+ GFX_BOX_SHADE_LEFT_DOWN,
+ GFX_BOX_SHADE_RIGHT_UP,
+ GFX_BOX_SHADE_LEFT_UP
+#endif
+} gfx_box_shade_t;
+
+
+typedef struct _dirty_rect {
+ rect_t rect;
+ struct _dirty_rect *next;
+} gfx_dirty_rect_t;
+
+
+typedef struct _gfx_event {
+ sci_event_t event;
+ struct _gfx_event *next;
+} gfx_input_event_t;
+
+typedef struct {
+ int version; /* Interpreter version */
+
+ gfx_options_t *options;
+
+ point_t pointer_pos; /* Mouse pointer coordinates */
+
+ rect_t clip_zone_unscaled; /* The current UNSCALED clipping zone */
+ rect_t clip_zone; /* The current SCALED clipping zone; a cached scaled version of clip_zone_unscaled */
+
+ gfx_driver_t *driver;
+ gfx_pixmap_color_t *static_palette; /* Null for dynamic palettes */
+ int static_palette_entries;
+
+ int visible_map;
+
+ gfx_resstate_t *resstate; /* Resource state */
+
+ gfx_pixmap_t *priority_map; /* back buffer priority map (unscaled) */
+ gfx_pixmap_t *static_priority_map; /* static buffer priority map (unscaled) */
+ gfx_pixmap_t *control_map; /* back buffer control map (only exists unscaled in the first place) */
+
+
+ int mouse_pointer_visible; /* Whether the pointer is drawn right now */
+ point_t old_pointer_draw_pos; /* Mouse pointer draw coordinates */
+ rect_t pointer_bg_zone; /* old-pointer-draw-pos relative zone inside the pointer
+ ** pixmap that was drawn */
+
+ int mouse_pointer_in_hw; /* Current pointer is being handled in hardware */
+
+ gfx_pixmap_t *mouse_pointer; /* Only set when drawing the mouse manually */
+ gfx_pixmap_t *mouse_pointer_bg; /* Background under the pointer */
+
+ int tag_mode; /* Set to 1 after a new pic is drawn and the resource manager
+ ** has tagged all resources. Reset after the next front buffer
+ ** update is done, when all resources that are still tagged are
+ ** flushed. */
+
+ int disable_dirty; /* Set to 1 to disable dirty rect accounting */
+
+ int pic_nr; /* Number of the current pic */
+ int palette_nr; /* Palette number of the current pic */
+
+ gfx_input_event_t *events;
+
+ gfx_pixmap_t *fullscreen_override; /* An optional override picture which must have unscaled
+ ** full-screen size, which overrides all other visibility, and
+ ** which is generally slow */
+
+ gfxr_pic_t *pic, *pic_unscaled; /* The background picture and its unscaled equivalent */
+
+ struct _dirty_rect *dirty_rects; /* Dirty rectangles */
+
+ void *internal_state; /* Internal interpreter information */
+
+} gfx_state_t;
+
+
+/**************************/
+/* Fundamental operations */
+/**************************/
+
+int
+gfxop_init_default(gfx_state_t *state, gfx_options_t *options, void *misc_info);
+/* Initializes a graphics mode suggested by the graphics driver
+** Parameters: (gfx_state_ t *) state: The state to initialize in that mode
+** (gfx_options_t *) options: Rendering options
+** (void *) misc_info: Additional information for the interpreter
+** part of the resource loader
+** Returns : (int) GFX_OK on success, GFX_FATAL otherwise
+*/
+
+int
+gfxop_init(gfx_state_t *state, int xfact, int yfact, gfx_color_mode_t bpp,
+ gfx_options_t *options, void *misc_info);
+/* Initializes a custom graphics mode
+** Parameters: (gfx_state_t *) state: The state to initialize
+** (int x int) xfact, yfact: Horizontal and vertical scale factors
+** (gfx_color_mode_t) bpp: Bytes per pixel to initialize with, or
+** 0 (GFX_COLOR_MODE_AUTO) to auto-detect
+** (gfx_options_t *) options: Rendering options
+** (void *) misc_info: Additional information for the interpreter
+** part of the resource loader
+** Returns : (int) GFX_OK on success, GFX_ERROR if that particular mode is
+** unavailable, or GFX_FATAL if the graphics driver is unable
+** to provide any useful graphics support
+*/
+
+int
+gfxop_set_parameter(gfx_state_t *state, char *attribute, char *value);
+/* Sets a driver-specific parameter
+** Parameters: (gfx_state_t *) state: The state, encapsulating the driver object to manipulate
+** (char *) attribute: The attribute to set
+** (char *) value: The value the attribute should be set to
+** Returns : (int) GFX_OK on success, GFX_FATAL on fatal error conditions triggered
+** by the command
+*/
+
+int
+gfxop_exit(gfx_state_t *state);
+/* Deinitializes a currently active driver
+** Parameters: (gfx_state_t *) state: The state encapsulating the driver in question
+** Returns : (int) GFX_OK
+*/
+
+int
+gfxop_scan_bitmask(gfx_state_t *state, rect_t area, gfx_map_mask_t map);
+/* Calculates a bit mask calculated from some pixels on the specified map
+** Parameters: (gfx_state_t *) state: The state containing the pixels to scan
+** (rect_t) area: The area to check
+** (gfx_map_mask_t) map: The GFX_MASKed map(s) to test
+** Returns : (int) An integer value where, for each 0<=i<=15, bit #i is set
+** iff there exists a map for which the corresponding bit was set
+** in the 'map' parameter and for which there exists a pixel within
+** the specified area so that the pixel's lower 4 bits, interpreted
+** as an integer value, equal i.
+** (Short version: This is an implementation of "on_control()").
+*/
+
+int
+gfxop_set_visible_map(gfx_state_t *state, gfx_map_mask_t map);
+/* Sets the currently visible map
+** Parameters: (gfx_state_t *) state: The state to modify
+** (gfx_map_mask_t) map: The GFX_MASK to set
+** Returns : (int) GFX_OK, or GFX_ERROR if map was invalid
+** 'visible_map' can be any of GFX_MASK_VISUAL, GFX_MASK_PRIORITY and GFX_MASK_CONTROL; the appropriate
+** map (as far as its contents are known to the graphics subsystem) is then subsequently drawn to the
+** screen at each update. If this is set to anything other than GFX_MASK_VISUAL, slow full-screen updates
+** are performed. Mostly useful for debugging.
+** The screen needs to be updated for the changes to take effect.
+*/
+
+int
+gfxop_set_clip_zone(gfx_state_t *state, rect_t zone);
+/* Sets a new clipping zone
+** Parameters: (gfx_state_t *) state: The affected state
+** (rect_t) zone: The new clipping zone
+** Returns : (int) GFX_OK
+*/
+
+int
+gfxop_have_mouse(gfx_state_t *state);
+/* Determines whether a pointing device is attached
+** Parameters: (gfx_state_t *) state: The state to inspect
+** Returns : (int) zero iff no pointing device is attached
+*/
+
+
+/******************************/
+/* Generic drawing operations */
+/******************************/
+
+int
+gfxop_draw_line(gfx_state_t *state,
+ point_t start, point_t end,
+ gfx_color_t color, gfx_line_mode_t line_mode,
+ gfx_line_style_t line_style);
+/* Renders a clipped line to the back buffer
+** Parameters: (gfx_state_t *) state: The state affected
+** (point_t) start: Starting point of the line
+** (point_t) end: End point of the line
+** (gfx_color_t) color: The color to use for drawing
+** (gfx_line_mode_t) line_mode: Any valid line mode to use
+** (gfx_line_style_t) line_style: The line style to use
+** Returns : (int) GFX_OK or GFX_FATAL
+*/
+
+int
+gfxop_draw_rectangle(gfx_state_t *state, rect_t rect, gfx_color_t color, gfx_line_mode_t line_mode,
+ gfx_line_style_t line_style);
+/* Draws a non-filled rectangular box to the back buffer
+** Parameters: (gfx_state_t *) state: The affected state
+** (rect_t) rect: The rectangular area the box is drawn to
+** (gfx_color_t) color: The color the box is to be drawn in
+** (gfx_line_mode_t) line_mode: The line mode to use
+** (gfx_line_style_t) line_style: The line style to use for the box
+** Returns : (int) GFX_OK or GFX_FATAL
+** Boxes drawn in thin lines will surround the minimal area described by rect.
+*/
+
+int
+gfxop_draw_box(gfx_state_t *state, rect_t box, gfx_color_t color1, gfx_color_t color2,
+ gfx_box_shade_t shade_type);
+/* Draws a filled box to the back buffer
+** Parameters: (gfx_state_t *) state: The affected state
+** (rect_t) box: The area to draw to
+** (gfx_color_t) color1: The primary color to use for drawing
+** (gfx_color_t) color2: The secondary color to draw in
+** (gfx_box_shade_t) shade_type: The shading system to use
+** (e.g. GFX_BOX_SHADE_FLAT)
+** Returns : (int) GFX_OK or GFX_FATAL
+** The draw mask, control, and priority values are derived from color1.
+*/
+
+int
+gfxop_fill_box(gfx_state_t *state, rect_t box, gfx_color_t color);
+/* Fills a box in the back buffer with a specific color
+** Parameters: (gfx_state_t *) state: The state to draw to
+** (rect_t) box: The box to fill
+** (gfx_color_t) color: The color to use for filling
+** Returns : (int) GFX_OK or GFX_FATAL
+** This is a simple wrapper function for gfxop_draw_box
+*/
+
+int
+gfxop_clear_box(gfx_state_t *state, rect_t box);
+/* Copies a box from the static buffer to the back buffer
+** Parameters: (gfx_state_t *) state: The affected state
+** (rect_t) box: The box to propagate from the static buffer
+** Returns : (int) GFX_OK or GFX_FATAL
+*/
+
+
+int
+gfxop_update(gfx_state_t *state);
+/* Updates all dirty rectangles
+** Parameters: (gfx_state_t) *state: The relevant state
+** Returns : (int) GFX_OK or GFX_FATAL if reported by the driver
+** In order to track dirty rectangles, they must be enabled in the options.
+** This function instructs the resource manager to free all tagged data
+** on certain occasions (see gfxop_new_pic).
+*/
+
+
+int
+gfxop_update_box(gfx_state_t *state, rect_t box);
+/* Propagates a box from the back buffer to the front (visible) buffer
+** Parameters: (gfx_state_t *) state: The affected state
+** (rect_t) box: The box to propagate to the front buffer
+** Returns : (int) GFX_OK or GFX_FATAL
+** This function instructs the resource manager to free all tagged data
+** on certain occasions (see gfxop_new_pic).
+** When called with dirty rectangle management enabled, it will automatically
+** propagate all dirty rectangles as well, UNLESS dirty frame accounting has
+** been disabled explicitly.
+*/
+
+int
+gfxop_enable_dirty_frames(gfx_state_t *state);
+/* Enables dirty frame accounting
+** Parameters: (gfx_state_t *) state: The state dirty frame accounting is to be enabled in
+** Returns : (int) GFX_OK or GFX_ERROR if state was invalid
+** Dirty frame accounting is enabled by default.
+*/
+
+int
+gfxop_disable_dirty_frames(gfx_state_t *state);
+/* Disables dirty frame accounting
+** Parameters: (gfx_state_t *) state: The state dirty frame accounting is to be disabled in
+** Returns : (int) GFX_OK or GFX_ERROR if state was invalid
+*/
+
+
+/********************/
+/* Color operations */
+/********************/
+
+int
+gfxop_set_color(gfx_state_t *state, gfx_color_t *color, int r, int g, int b, int a,
+ int priority, int control);
+/* Maps an r/g/b value to a color and sets a gfx_color_t structure
+** Parameters: (gfx_state_t *) state: The current state
+** (gfx_color_t *) color: Pointer to the structure to write to
+** (int x int x int) r,g,b: The red/green/blue color intensity values
+** of the result color (0x00 (minimum) to 0xff (max))
+** If any of these values is less than zero, the
+** resulting color will not affect the visual map when
+** used for drawing
+** (int) a: The alpha (transparency) value, with 0x00 meaning absolutely
+** opaque and 0xff meaning fully transparent. Alpha blending support
+** is optional for drivers, so these are the only two values that
+** are guaranteed to work as intended. Any value in between them
+** must guarantee the following opaqueness:
+** opaqueness(x-1) >= opaqueness(x) >= opaqueness (x+1)
+** (i.e. ([0,255], less-transparent-than) must define a partial order)
+** (int) priority: The priority to use for drawing, or -1 for none
+** (int) control: The control to use for drawing, or -1 to disable drawing to the
+** control map
+** Returns : (int) GFX_OK or GFX_ERROR if state is invalid
+** In palette mode, this may allocate a new color. Use gfxop_free_color() described below to
+** free that color.
+*/
+
+int
+gfxop_set_system_color(gfx_state_t *state, gfx_color_t *color);
+/* Designates a color as a 'system color'
+** Parameters: (gfx_state_t *) state: The affected state
+** (gfx_color_t *) color: The color to designate as a system color
+** Returns : (int) GFX_OK or GFX_ERROR if state is invalid
+** System colors are permanent colors that cannot be deallocated. As such, they must be used
+** with caution.
+*/
+
+int
+gfxop_free_color(gfx_state_t *state, gfx_color_t *color);
+/* Frees a color allocated by gfxop_set_color()
+** Parmaeters: (gfx_state_t *) state: The state affected
+** (gfx_color_t *) color: The color to de-allocate
+** Returns : (int) GFX_OK or GFX_ERROR if state is invalid
+** This function is a no-op in non-index mode, or if color is a system color.
+*/
+
+
+/**********************/
+/* Pointer and IO ops */
+/**********************/
+
+int
+gfxop_usleep(gfx_state_t *state, long usecs);
+/* Suspends program execution for the specified amount of microseconds
+** Parameters: (gfx_state_t *) state: The state affected
+** (long) usecs: The amount of microseconds to wait
+** Returns : (int) GFX_OK or GFX_ERROR
+** The mouse pointer will be redrawn continually, if applicable
+*/
+
+int
+gfxop_set_pointer_cursor(gfx_state_t *state, int nr);
+/* Sets the mouse pointer to a cursor resource
+** Parameters: (gfx_state_t *) state: The affected state
+** (int) nr: Number of the cursor resource to use
+** Returns : (int) GFX_OK, GFX_ERROR if the resource did not
+** exist and was not GFXOP_NO_POINTER, or GFX_FATAL on
+** fatal error conditions.
+** Use nr = GFX_NO_POINTER to disable the mouse pointer (default).
+*/
+
+int
+gfxop_set_pointer_view(gfx_state_t *state, int nr, int loop, int cel, point_t *hotspot);
+/* Sets the mouse pointer to a view resource
+** Parameters: (gfx_state_t *) state: The affected state
+** (int) nr: Number of the view resource to use
+** (int) loop: View loop to use
+** (int) cel: View cel to use
+** (point_t *) hotspot: Manually set hotspot to use, or NULL for default.
+** Returns : (int) GFX_OK or GFX_FATAL
+** Use gfxop_set_pointer_cursor(state, GFXOP_NO_POINTER) to disable the
+** pointer.
+*/
+
+int
+gfxop_set_pointer_position(gfx_state_t *state, point_t pos);
+/* Teleports the mouse pointer to a specific position
+** Parameters: (gfx_state_t *) state: The state the pointer is in
+** (point_t) pos: The position to teleport it to
+** Returns : (int) Any error code or GFX_OK
+** Depending on the graphics driver, this operation may be without
+** any effect
+*/
+
+sci_event_t
+gfxop_get_event(gfx_state_t *state, unsigned int mask);
+/* Retreives the next input event from the driver
+** Parameters: (gfx_state_t *) state: The affected state
+** (int) mask: The event mask to poll from (see uinput.h)
+** Returns : (sci_event_t) The next event in the driver's event queue, or
+** a NONE event if no event matching the mask was found.
+*/
+
+
+/*******************/
+/* View operations */
+/*******************/
+
+int
+gfxop_lookup_view_get_loops(gfx_state_t *state, int nr);
+/* Determines the number of loops associated with a view
+** Parameters: (gfx_state_t *) state: The state to use
+** (int) nr: Number of the view to investigate
+** Returns : (int) The number of loops, or GFX_ERROR if the view didn't exist
+*/
+
+int
+gfxop_lookup_view_get_cels(gfx_state_t *state, int nr, int loop);
+/* Determines the number of cels associated stored in a loop
+** Parameters: (gfx_state_t *) state: The state to look up in
+** (int) nr: Number of the view to look up in
+** (int) loop: Number of the loop the number of cels of
+** are to be investigated
+** Returns : (int) The number of cels in that loop, or GFX_ERROR if either
+** the view or the loop didn't exist
+*/
+
+int
+gfxop_check_cel(gfx_state_t *state, int nr, int *loop, int *cel);
+/* Clips the view/loop/cel position of a cel
+** Parameters: (gfx_state_t *) state: The state to use
+** (int) nr: Number of the view to use
+** (int *) loop: Pointer to the variable storing the loop
+** number to verify
+** (int *) cel: Pointer to the variable storing the cel
+** number to check
+** Returns : (int) GFX_OK or GFX_ERROR if the view didn't exist
+** *loop is clipped first, then *cel. The resulting setup will be a valid
+** view configuration.
+*/
+
+int
+gfxop_overflow_cel(gfx_state_t *state, int nr, int *loop, int *cel);
+/* Resets loop/cel values to zero if they have become invalid
+** Parameters: (gfx_state_t *) state: The state to use
+** (int) nr: Number of the view to use
+** (int *) loop: Pointer to the variable storing the loop
+** number to verify
+** (int *) cel: Pointer to the variable storing the cel
+** number to check
+** Returns : (int) GFX_OK or GFX_ERROR if the view didn't exist
+** *loop is clipped first, then *cel. The resulting setup will be a valid
+** view configuration.
+*/
+
+int
+gfxop_get_cel_parameters(gfx_state_t *state, int nr, int loop, int cel,
+ int *width, int *height, point_t *offset);
+/* Retreives the width and height of a cel
+** Parameters: (gfx_state_t *) state: The state to use
+** (int) nr: Number of the view
+** (int) loop: Loop number to examine
+** (int) cel: The cel (inside the loop) to look up
+** (int *) width: The variable the width will be stored in
+** (int *) height: The variable the height will be stored in
+** (point_t *) offset: The variable the cel's x/y offset will be stored in
+** Returns : (int) GFX_OK if the lookup succeeded, GFX_ERROR if the nr/loop/cel
+** combination was invalid
+*/
+
+int
+gfxop_draw_cel(gfx_state_t *state, int nr, int loop, int cel, point_t pos,
+ gfx_color_t color, int palette);
+/* Draws (part of) a cel to the back buffer
+** Parameters: (gfx_state_t *) state: The state encapsulating the driver to draw with
+** (int) nr: Number of the view to draw
+** (int) loop: Loop of the cel to draw
+** (int) cel: The cel number of the cel to draw
+** (point_t) pos: The positino the cel is to be drawn to
+** (gfx_color_t color): The priority and control values to use for drawing
+** (int) palette: The palette to use
+** Returns : (int) GFX_OK or GFX_FATAL
+*/
+
+
+int
+gfxop_draw_cel_static(gfx_state_t *state, int nr, int loop, int cel, point_t pos,
+ gfx_color_t color, int palette);
+/* Draws a cel to the static buffer; no clipping is performed
+** Parameters: (gfx_state_t *) state: The state encapsulating the driver to draw with
+** (int) nr: Number of the view to draw
+** (int) loop: Loop of the cel to draw
+** (int) cel: The cel number of the cel to draw
+** (point_t) pos: The positino the cel is to be drawn to
+** (gfx_color_t color): The priority and control values to use for drawing
+** (int) palette: The palette to use
+** Returns : (int) GFX_OK or GFX_FATAL
+** Let me repeat, no clipping (except for the display borders) is performed.
+*/
+
+
+int
+gfxop_draw_cel_static_clipped(gfx_state_t *state, int nr, int loop, int cel, point_t pos,
+ gfx_color_t color, int palette);
+/* Draws (part of) a clipped cel to the static buffer
+** Parameters: (gfx_state_t *) state: The state encapsulating the driver to draw with
+** (int) nr: Number of the view to draw
+** (int) loop: Loop of the cel to draw
+** (int) cel: The cel number of the cel to draw
+** (point_t) pos: The positino the cel is to be drawn to
+** (gfx_color_t color): The priority and control values to use for drawing
+** (int) palette: The palette to use
+** Returns : (int) GFX_OK or GFX_FATAL
+** This function does clip.
+*/
+
+
+/******************/
+/* Pic operations */
+/******************/
+/* These operations are exempt from clipping */
+
+int
+gfxop_new_pic(gfx_state_t *state, int nr, int flags, int default_palette);
+/* Draws a pic and writes it over the static buffer
+** Parameters: (gfx_state_t *) state: The state affected
+** (int) nr: Number of the pic to draw
+** (int) flags: Interpreter-dependant flags to use for drawing
+** (int) default_palette: The default palette for drawing
+** Returns : (int) GFX_OK or GFX_FATAL
+** This function instructs the resource manager to tag all data as "unused".
+** See the resource manager tag functions for a full description.
+*/
+
+void *
+gfxop_get_pic_metainfo(gfx_state_t *state);
+/* Retreives all meta-information assigned to the current pic
+** Parameters: (gfx_state_t *) state: The state affected
+** Returns : (void *) NULL if the pic doesn't exist or has no meta-information,
+** the meta-info otherwise
+** This meta-information is referred to as 'internal data' in the pic code
+*/
+
+int
+gfxop_add_to_pic(gfx_state_t *state, int nr, int flags, int default_palette);
+/* Adds a pic to the static buffer
+** Parameters: (gfx_state_t *) state: The state affected
+** (int) nr: Number of the pic to add
+** (int) flags: Interpreter-dependant flags to use for drawing
+** (int) default_palette: The default palette for drawing
+** Returns : (int) GFX_OK or GFX_FATAL
+*/
+
+
+
+
+/*******************/
+/* Text operations */
+/*******************/
+
+
+int
+gfxop_get_font_height(gfx_state_t *state, int font_nr);
+/* Returns the fixed line height for one specified font
+** Parameters: (gfx_state_t *) state: The state to work on
+** (int) font_nr: Number of the font to inspect
+** Returns : (int) GFX_ERROR, GFX_FATAL, or the font line height
+*/
+
+int
+gfxop_get_text_params(gfx_state_t *state, int font_nr, const char *text,
+ int maxwidth, int *width, int *height, int flags,
+ int *lines_nr, int *lineheight, int *lastline_width);
+/* Calculates the width and height of a specified text in a specified font
+** Parameters: (gfx_state_t *) state: The state to use
+** (int) font_nr: Font number to use for the calculation
+** (const char *) text: The text to examine
+** (int) flags: ORred GFXR_FONT_FLAGs
+** (int) maxwidth: The maximum pixel width to allow for the text
+** Returns : (int) GFX_OK or GFX_ERROR if the font didn't exist
+** (int) *width: The resulting width
+** (int) *height: The resulting height
+** (int) *lines_nr: Number of lines used in the text
+** (int) *lineheight: Pixel height (SCI scale) of each text line
+** (int) *lastline_wdith: Pixel offset (SCI scale) of the space
+** after the last character in the last line
+*/
+
+gfx_text_handle_t *
+gfxop_new_text(gfx_state_t *state, int font_nr, char *text, int maxwidth,
+ gfx_alignment_t halign, gfx_alignment_t valign,
+ gfx_color_t color1, gfx_color_t color2, gfx_color_t bg_color,
+ int flags);
+/* Generates a new text handle that can be used to draw any text
+** Parameters: (gfx_state_t *) state: The state to use
+** (int) font_nr: Font number to use for the calculation
+** (char *) text: The text to examine
+** (int) maxwidth: The maximum pixel width to allow for the text
+** (gfx_alignment_t) halign: The horizontal text alignment
+** (gfx_alignment_t) valign: The vertical text alignment
+** (gfx_color_t x gfx_color_t) color1, color2: The text's foreground colors
+** (the function will dither between those two)
+** (gfx_color_t) bg_color: The background color
+** (int) flags: ORred GFXR_FONT_FLAGs
+** Returns : (gfx_text_handle_t *) A newly allocated gfx_text_handle_t, or
+** NULL if font_nr was invalid
+** The control and priority values for the text will be extracted from color1.
+** Note that the colors must have been allocated properly, or the text may display in
+** incorrect colors.
+*/
+
+int
+gfxop_free_text(gfx_state_t *state, gfx_text_handle_t *handle);
+/* Frees a previously allocated text handle and all related resources
+** Parameters: (gfx_state_t *) state: The state to use
+** (gfx_text_handle_t *) handle: The handle to free
+** Returns : (int) GFX_OK
+*/
+
+int
+gfxop_draw_text(gfx_state_t *state, gfx_text_handle_t *handle, rect_t zone);
+/* Draws text stored in a text handle
+** Parameters: (gfx_state_t *) state: The target state
+** (gfx_text_handle_t *) handle: The text handle to use for drawing
+** (rect_t) zone: The rectangular box to draw to. In combination with
+** halign and valign, this defines where the text is
+** drawn to.
+** Returns : (int) GFX_OK or GFX_FATAL
+*/
+
+
+/****************************/
+/* Manual pixmap operations */
+/****************************/
+
+gfx_pixmap_t *
+gfxop_grab_pixmap(gfx_state_t *state, rect_t area);
+/* Grabs a screen section from the back buffer and stores it in a pixmap
+** Parameters: (gfx_state_t *) state: The affected state
+** (rect_t) area: The area to grab
+** Returns : (gfx_pixmap_t *) A result pixmap, or NULL on error
+** Obviously, this only affects the visual map
+*/
+
+int
+gfxop_draw_pixmap(gfx_state_t *state, gfx_pixmap_t *pxm, rect_t zone, point_t pos);
+/* Draws part of a pixmap to the screen
+** Parameters: (gfx_state_t *) state: The affected state
+** (gfx_pixmap_t *) pxm: The pixmap to draw
+** (rect_t) zone: The segment of the pixmap to draw
+** (point_t) pos: The position the pixmap should be drawn to
+** Returns : (int) GFX_OK or any error code
+*/
+
+int
+gfxop_free_pixmap(gfx_state_t *state, gfx_pixmap_t *pxm);
+/* Frees a pixmap returned by gfxop_grab_pixmap()
+** Parameters: (gfx_state_t *) state: The affected state
+** (gfx_pixmap_t *) pxm: The pixmap to free
+** Returns : (int) GFX_OK, or GFX_ERROR if the state was invalid
+*/
+
+/******************************/
+/* Dirty rectangle operations */
+/******************************/
+
+gfx_dirty_rect_t *
+gfxdr_add_dirty(gfx_dirty_rect_t *base, rect_t box, int strategy);
+/* Adds a dirty rectangle to 'base' according to a strategy
+** Parameters: (gfx_dirty_rect_t *) base: The base rectangle to add to, or NULL
+** (rect_t) box: The dirty frame to add
+** (int) strategy: The dirty frame heuristic to use (see gfx_options.h)
+** Returns : (gfx_dirty_rect_t *) an appropriate singly-linked dirty rectangle
+** result cluster
+*/
+
+int
+_gfxop_clip(rect_t *rect, rect_t clipzone);
+/* Clips a rectangle against another one
+** Parameters: (rect_t *) rect: The rectangle to clip
+** (rect_t) clipzone: The outer bounds rect must be in
+** Reuturns : (int) 1 if rect is empty now, 0 otherwise
+*/
+
+#endif /* !_GFX_OPERATIONS_H_ */
diff --git a/engines/sci/include/gfx_options.h b/engines/sci/include/gfx_options.h
new file mode 100644
index 0000000000..51b31f794c
--- /dev/null
+++ b/engines/sci/include/gfx_options.h
@@ -0,0 +1,86 @@
+/***************************************************************************
+ gfx_options.h Copyright (C) 2000 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+
+#ifndef _GFX_OPTIONS_H_
+#define _GFX_OPTIONS_H_
+
+#include <gfx_resource.h>
+#include <gfx_tools.h>
+#include <gfx_res_options.h>
+
+/* Dirty rectangle heuristics: */
+
+/* One: Redraw one rectangle surrounding the dirty area (insert is O(1)) */
+#define GFXOP_DIRTY_FRAMES_ONE 1
+
+/* Clusters: Accumulate dirty rects, merging those that overlap (insert is O(n)) */
+#define GFXOP_DIRTY_FRAMES_CLUSTERS 2
+
+
+typedef struct _gfx_options {
+ /* gfx_options_t: Contains all user options to the rendering pipeline */
+ /* See note in sci_conf.h for config_entry_t before changing types of
+ ** variables */
+
+ int buffer_pics_nr; /* Number of unused pics to buffer */
+
+ int correct_rendering; /* Whether to render slow, but correct (rather than
+ ** fast and almost correct) */
+
+ /* SCI0 pic resource options */
+ int pic0_unscaled; /* Don't draw scaled SCI0 pics */
+
+ int pic0_dither_mode; /* Defined in gfx_resource.h */
+ int pic0_dither_pattern; /* Defined in gfx_resource.h */
+
+ gfx_brush_mode_t pic0_brush_mode;
+ gfx_line_mode_t pic0_line_mode;
+
+ gfx_xlate_filter_t cursor_xlate_filter;
+ gfx_xlate_filter_t view_xlate_filter;
+ gfx_xlate_filter_t pic_xlate_filter; /* Only relevant if (pic0_unscaled) */
+ gfx_xlate_filter_t text_xlate_filter;
+ gfxr_font_scale_filter_t fixed_font_xlate_filter; /* Scale filter for systems that provide font support which isn't scaled */
+
+ gfxr_antialiasing_t pic0_antialiasing;
+
+ gfx_res_fullconf_t res_conf; /* Resource customisation: Per-resource palettes etc. */
+
+ int dirty_frames;
+
+ int workarounds; /* Workaround flags- see below */
+
+ rect_t pic_port_bounds;
+} gfx_options_t;
+
+/* SQ3 counts whitespaces towards the total text size, as does gfxop_get_text_params() if this is set: */
+#define GFX_WORKAROUND_WHITESPACE_COUNT (1<<0)
+
+
+#endif /* !_GFX_OPTIONS_H_ */
+
diff --git a/engines/sci/include/gfx_res_options.h b/engines/sci/include/gfx_res_options.h
new file mode 100644
index 0000000000..54138a8813
--- /dev/null
+++ b/engines/sci/include/gfx_res_options.h
@@ -0,0 +1,134 @@
+/***************************************************************************
+ gfx_res_options.h Copyright (C) 2002 Christoph Reichenbach
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public Licence as
+ published by the Free Software Foundaton; either version 2 of the
+ Licence, or (at your option) any later version.
+
+ It is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ merchantibility or fitness for a particular purpose. See the
+ GNU General Public Licence for more details.
+
+ You should have received a copy of the GNU General Public Licence
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+
+ Please contact the maintainer for any program-related bug reports or
+ inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+/* Configuration options for per-resource customisations */
+
+#ifndef _GFX_RES_OPTIONS_H_
+#define _GFX_RES_OPTIONS_H_
+
+#include <gfx_resource.h>
+#include <gfx_resmgr.h>
+
+#define GFX_RES_PATTERN_MIN 0
+#define GFX_RES_PATTERN_MAX 65535
+
+typedef struct _gfx_res_pattern {
+ int min, max;
+} gfx_res_pattern_t;
+
+typedef struct _gfx_res_pattern_list {
+ gfx_res_pattern_t pattern;
+ struct _gfx_res_pattern_list *next;
+} gfx_res_pattern_list_t;
+
+
+/* GFX resource assignments */
+
+#define GFX_RES_ASSIGN_TYPE_PALETTE 0 /* Assign a palette */
+
+typedef struct {
+ short type; /* GFX_RES_ASSIGN_TYPE_* */
+
+ union {
+ struct {
+ int colors_nr;
+ gfx_pixmap_color_t *colors;
+ } palette;
+ } assign;
+} gfx_res_assign_t;
+
+
+/* GFX resource modifications */
+
+#define GFX_RES_MULTIPLY_FIXED 0 /* Linear palette update */
+
+typedef struct {
+ short type; /* GFX_RES_ASSIGN_TYPE_* */
+
+ union {
+ byte factor[3]; /* divide by 16 to retreive factor */
+ } mod;
+} gfx_res_mod_t;
+
+
+typedef struct _gfx_res_conf {
+ int type; /* Resource type-- only one allowed */
+
+ /* If any of the following is 0, it means that there is no restriction.
+ ** Otherwise, one of the patterns associated with them must match. */
+ int patterns_nr; /* Number of patterns (only 'view' patterns for views) */
+ int loops_nr, cels_nr; /* Number of loop/cel patterns, for views only.
+ ** For pics, loops_nr identifies the palette. */
+
+ gfx_res_pattern_t *patterns;
+
+ union {
+ gfx_res_assign_t assign;
+ gfx_res_mod_t mod;
+ } conf; /* The actual configuration */
+
+ struct _gfx_res_conf *next;
+} gfx_res_conf_t;
+
+
+typedef gfx_res_conf_t *gfx_res_conf_p_t;
+
+typedef struct {
+ gfx_res_conf_p_t assign[GFX_RESOURCE_TYPES_NR];
+ gfx_res_conf_p_t mod[GFX_RESOURCE_TYPES_NR];
+} gfx_res_fullconf_t;
+
+
+struct _gfx_options;
+
+int
+gfx_update_conf(struct _gfx_options *options,
+ char *line);
+/* Updates the configuration
+** Parameters: (gfx_options_t *) options: The options list to update
+** (char *) line: The text line to parse
+** Modifies : (gfx_options_t *) options
+** Returns : (int) 0 on success, 1 if an error occured
+** The line passed to it should begin with the resource type and be
+** terminated by a semicolon.
+*/
+
+int
+gfx_get_res_config(struct _gfx_options *options,
+ gfx_pixmap_t *pxm);
+/* Configures a graphical pixmap according to config options
+** Parameters: (gfx_options_t *) options: The options according to which
+** configuration should be performed
+** (gfx_resource_type_t) pxm: The pixmap to configure
+** Returns : (int) 0 on success, non-zero otherwise
+** Modifies pxm as considered appropriate by configuration options. Does
+** not do anything in colour index mode.
+*/
+
+#endif /* !_GFX_RES_OPTIONS_H_ */
diff --git a/engines/sci/include/gfx_resmgr.h b/engines/sci/include/gfx_resmgr.h
new file mode 100644
index 0000000000..f6a476b76f
--- /dev/null
+++ b/engines/sci/include/gfx_resmgr.h
@@ -0,0 +1,354 @@
+/***************************************************************************
+ gfx_resmgr.h Copyright (C) 2000 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef _GFX_RESMGR_H_
+#define _GFX_RESMGR_H_
+
+#include <gfx_resource.h>
+#include <sbtree.h>
+
+typedef enum {
+ GFX_RESOURCE_TYPE_VIEW = 0,
+ GFX_RESOURCE_TYPE_PIC,
+ GFX_RESOURCE_TYPE_FONT,
+ GFX_RESOURCE_TYPE_CURSOR,
+ GFX_RESOURCE_TYPE_PALETTE,
+ /* FIXME: Add PAL resource */
+
+ GFX_RESOURCE_TYPES_NR /* Number of resource types that are to be supported */
+} gfx_resource_type_t;
+
+#define GFX_RESOURCE_TYPE_0 GFX_RESOURCE_TYPE_VIEW
+
+#define GFXR_RES_ID(type, index) ((type) << 16 | (index))
+#define GFXR_RES_TYPE(id) (id >> 16)
+#define GFXR_RES_NR(id) (id & 0xffff)
+
+
+typedef struct gfx_resource_struct {
+ int ID; /* Resource ID */
+ int lock_sequence_nr; /* See description of lock_counter in gfx_resstate_t */
+ int mode; /* A mode type hash */
+
+ union {
+ gfx_pixmap_t *pointer;
+ gfxr_view_t *view;
+ gfx_bitmap_font_t *font;
+ gfxr_pic_t *pic;
+ } scaled_data;
+
+ union {
+ gfx_pixmap_t *pointer;
+ gfxr_view_t *view;
+ gfx_bitmap_font_t *font;
+ gfxr_pic_t *pic;
+ } unscaled_data;
+
+} gfx_resource_t;
+
+
+struct _gfx_options;
+
+typedef struct {
+ int version; /* Interpreter version */
+ struct _gfx_options *options;
+ gfx_driver_t *driver;
+ gfx_pixmap_color_t *static_palette;
+ int static_palette_entries;
+ int lock_counter; /* Global lock counter; increased for each new resource allocated.
+ ** The newly allocated resource will then be assigned the new value
+ ** of the lock_counter, as will any resources referenced afterwards.
+ */
+ int tag_lock_counter; /* lock counter value at tag time */
+
+ sbtree_t *resource_trees[GFX_RESOURCE_TYPES_NR];
+ void *misc_payload;
+} gfx_resstate_t;
+
+
+
+gfx_resstate_t *
+gfxr_new_resource_manager(int version, struct _gfx_options *options,
+ gfx_driver_t *driver, void *misc_payload);
+/* Allocates and initializes a new resource manager
+** Parameters: (int) version: Interpreter version
+** (gfx_options_t *): Pointer to all relevant drawing options
+** (gfx_driver_t *): The graphics driver (needed for capability flags and the mode
+** structure)
+** (void *) misc_payload: Additional information for the interpreter's
+** resource loaders
+** Returns : (gfx_resstate_t *): A newly allocated resource manager
+** The options are considered to be read-only, as they belong to the overlying state object.
+*/
+
+void
+gfxr_free_resource_manager(gfx_driver_t *driver, gfx_resstate_t *state);
+/* Frees a previously allocated resource manager, and all allocated resources.
+** Parameters: (gfx_driver_t *) driver: The graphics driver; used to free pixmaps that
+** are installed in a driver-specific registry
+** (gfx_resstate_t *) state: The state manager to free
+** Return : (void)
+*/
+
+void
+gfxr_free_all_resources(gfx_driver_t *driver, gfx_resstate_t *state);
+/* Frees all resources currently allocated
+** Parameter: (gfx_driver_t *) driver: The driver to free with
+** (gfx_resstate_t *) state: The state to do this on
+** Returns : (void)
+** This function is intended to be used primarily for debugging.
+*/
+
+void
+gfxr_tag_resources(gfx_resstate_t *state);
+/* 'Tags' all resources for deletion
+** Paramters: (gfx_resstate_t *) state: The resource state to modify
+** Returns : (void)
+** Tagged resources are untagged if they are referenced.
+*/
+
+void
+gfxr_free_tagged_resources(gfx_driver_t *driver, gfx_resstate_t *state);
+/* Frees all tagged resources.
+** Parameters: (gfx_driver_t *) driver: The graphics driver the pixmaps are potentially
+** registered in
+** (gfx_resstate_t *) state: The state to alter
+** Returns : (void)
+** Resources are tagged by calling gfx_tag_resources(), and untagged by calling the
+** approprate dereferenciation function.
+** Note that this function currently only affects view resources, as pic resources are
+** treated differently, while font and cursor resources are relatively rare.
+*/
+
+
+gfxr_pic_t *
+gfxr_get_pic(gfx_resstate_t *state, int nr, int maps, int flags,
+ int default_palette, int scaled);
+/* Retreives a displayable (translated) pic resource
+** Parameters: (gfx_resstate_t *) state: The resource state
+** (int) nr: Number of the pic resource
+** (int) maps: The maps to translate (ORred GFX_MASK_*)
+** (int) flags: Interpreter-dependant pic flags
+** (int) default_palette: The default palette to use for drawing (if applicable)
+** (int) scaled: Whether to return the scaled maps, or the unscaled
+** ones (which may be identical) for some special operations.
+** Returns : (gfx_pic_t *) The appropriate pic resource with all maps as index (but not
+** neccessarily translated) data.
+*/
+
+gfxr_pic_t *
+gfxr_add_to_pic(gfx_resstate_t *state, int old_nr, int new_nr, int maps, int flags,
+ int old_default_palette, int default_palette, int scaled);
+/* Retreives a displayable (translated) pic resource written ontop of an existing pic
+** Parameters: (gfx_resstate_t *) state: The resource state
+** (int) old_nr: Number of the pic resource to write on
+** (int) new_nr: Number of the pic resource that is to be added
+** (int) maps: The maps to translate (ORred GFX_MASK_*)
+** (int) flags: Interpreter-dependant pic flags
+** (int) default_palette: The default palette to use for drawing (if applicable)
+** (int) scaled: Whether to return the scaled maps, or the unscaled
+** ones (which may be identical) for some special operations.
+** Returns : (gfx_pic_t *) The appropriate pic resource with all maps as index (but not
+** neccessarily translated) data.
+** This function invalidates the cached pic pointed to by old_nr in the cache. While subsequent
+** gfxr_add_to_pic() writes will still modify the 'invalidated' pic, gfxr_get_pic() operations will
+** cause it to be removed from the cache and to be replaced by a clean version.
+*/
+
+gfxr_view_t *
+gfxr_get_view(gfx_resstate_t *state, int nr, int *loop, int *cel, int palette);
+/* Retreives a translated view cel
+** Parameters: (gfx_resstate_t *) state: The resource state
+** (int) nr: The view number
+** (int *) loop: Pointer to a variable containing the loop number
+** (int *) cel: Pointer to a variable containing the cel number
+** (int) palette: The palette to use
+** Returns : (gfx_view_t *) The relevant view, or NULL if nr was invalid
+** loop and cel are given as pointers in order to allow the underlying variables to be
+** modified if they are invalid (this is relevant for SCI version 0, where invalid
+** loop and cel numbers have to be interpreted as 'maximum' or 'minimum' by the interpreter)
+*/
+
+gfx_bitmap_font_t *
+gfxr_get_font(gfx_resstate_t *state, int nr, int scaled);
+/* Retreives a font
+** Parameters: (gfx_resstate_t *) state: The relevant resource state
+** (int) nr: The font number
+** (int) scaled: Whether the font should be font-scaled
+** Returns : (gfx_font_t *) The appropriate font, or NULL on error
+*/
+
+gfx_pixmap_t *
+gfxr_get_cursor(gfx_resstate_t *state, int nr);
+/* Retreives an SCI0/SCI01 mouse cursor
+** Parameters: (gfx_resstate_t *) state: The resource state
+** (int) nr: The cursour number
+** Returns : (gfx_font_t *) The approprate cursor as a pixmap, or NULL on error
+*/
+
+gfx_pixmap_color_t *
+gfxr_get_palette(gfx_resstate_t *state, int nr);
+/* Retreives a palette
+** Parameters: (gfx_resstate_t *) state: The resource state
+** (int) nr: The cursour number
+** Returns : (gfx_font_t *) The approprate cursor as a pixmap, or NULL on error
+*/
+
+
+/* =========================== */
+/* Interpreter-dependant stuff */
+/* =========================== */
+
+
+int
+gfxr_interpreter_options_hash(gfx_resource_type_t type, int version,
+ struct _gfx_options *options, void *internal, int palette);
+/* Calculates a unique hash value for the specified options/type setup
+** Parameters: (gfx_resource_type_t) type: The type the hash is to be generated for
+** (int) version: The interpreter type and version
+** (gfx_options_t *) options: The options to hashify
+** (void *) internal: Internal information provided by the interpreter
+** (int) palette: The palette to use (FIXME: should this be here?)
+** Returns : (int) A hash over the values of the options entries, covering entries iff
+** they are relevant for the specified type
+** Covering more entries than relevant may slow down the system when options are changed,
+** while covering less may result in invalid cached data being used.
+** Only positive values may be returned, as negative values are used internally by the generic
+** resource manager code.
+** Also, only the lower 20 bits are available to the interpreter.
+** (Yes, this isn't really a "hash" in the traditional sense...)
+*/
+
+int *
+gfxr_interpreter_get_resources(gfx_resstate_t *state, gfx_resource_type_t type,
+ int version, int *entries_nr, void *internal);
+/* Retreives all resources of a specified type that are available from the interpreter
+** Parameters: (gfx_resstate_t *) state: The relevant resource state
+** (gfx_respirce_type_t) type: The resource type to query
+** (int) version: The interpreter type and version
+** (int *) entries_nr: The variable the number of entries will eventually be stored in
+** (void *) internal: Internal information provided by the interpreter
+** Returns : (int *) An array of resource numbers
+** Unsupported/non-existing resources should return NULL here; this is equivalent to supported
+** resources of which zero are available.
+** The returned structure (if non-zero) must be freed by the querying code (the resource manager).
+*/
+
+gfxr_pic_t *
+gfxr_interpreter_init_pic(int version, gfx_mode_t *mode, int ID, void *internal);
+/* Initializes a pic
+** Parameters: (int) version: Interpreter version to use
+** (gfx_mode_t *) mode: The graphics mode the pic will be using
+** (int) ID: The ID to assign to the gfxr_pic_t structure
+** (void *) internal: Internal information provided by the interpreter
+** Returns : (gfxr_pic_t *) A newly allocated pic
+** This function is typically called befode gfxr_interpreter_clear_pic().
+** Must remember to initialize 'internal' to NULL or a malloc()'d area.
+*/
+
+void
+gfxr_interpreter_clear_pic(int version, gfxr_pic_t *pic, void *internal);
+/* Clears a previously allocated pic
+** Parameters: (int) version: Interpreter version
+** (gfxr_pic_t *) pic: The pic to clear
+** (void *) internal: Internal information provided by the interpreter
+** Returns : (void)
+** This function is called in preparation for the pic to be drawn with gfxr_interpreter_calculate_pic.
+*/
+
+int
+gfxr_interpreter_calculate_pic(gfx_resstate_t *state, gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic,
+ int flags, int default_palette, int nr, void *internal);
+/* Instructs the interpreter-specific code to calculate a picture
+** Parameters: (gfx_resstate_t *) state: The resource state, containing options and version information
+** (gfxr_pic_t *) scaled_pic: The pic structure that is to be written to
+** (gfxr_pic_t *) unscaled_pic: The pic structure the unscaled pic is to be written to,
+** or NULL if it isn't needed.
+** (int) flags: Pic drawing flags (interpreter dependant)
+** (int) default_palette: The default palette to use for pic drawing (interpreter dependant)
+** (int) nr: pic resource number
+** (void *) internal: Internal information provided by the interpreter
+** Returns : (int) GFX_ERROR if the resource could not be found, GFX_OK otherwise
+*/
+
+gfxr_view_t *
+gfxr_interpreter_get_view(gfx_resstate_t *state, int nr, void *internal, int palette);
+/* Instructs the interpreter-specific code to calculate a view
+** Parameters: (gfx_resstate_t *) state: The resource manager state
+** (int) nr: The view resource number
+** (void *) internal: Internal information provided by the interpreter
+** Returns : (gfx_view_t *) The appropriate view, or NULL on error
+*/
+
+gfx_bitmap_font_t *
+gfxr_interpreter_get_font(gfx_resstate_t *state, int nr, void *internal);
+/* Instructs the interpreter-specific code to calculate a font
+** Parameters: (gfx_resstate_t *) state: The resource manager state
+** (int) nr: The font resource number
+** (void *) internal: Internal information provided by the interpreter
+** Returns : (gfx_font_t *) The newly calculated font, or NULL on error
+*/
+
+gfx_pixmap_t *
+gfxr_interpreter_get_cursor(gfx_resstate_t *state, int nr, void *internal);
+/* Instructs the interpreter-specific code to calculate a cursor
+** Paramaters: (gfx_resstate_t *) state: The resource manager state
+** (int nr): The cursor resource number
+** (void *) internal: Internal information provided by the interpreter
+** Returns : (gfx_pixmap_t *) The cursor pixmap, or NULL on error
+*/
+
+gfx_pixmap_color_t *
+gfxr_interpreter_get_static_palette(gfx_resstate_t *state, int version, int *colors_nr, void *internal);
+/* Retreives the static palette from the interpreter-specific code
+** Parameters: (int) version: Interpreter version to use
+** (int *) colors_nr: Number of colors to use
+** (void *) internal: Internal information provided by the interpreter
+** Returns : (gfx_pixmap_color_t *) *colors_nr static color entries
+** if a static palette must be used, NULL otherwise
+*/
+
+gfx_pixmap_color_t *
+gfxr_interpreter_get_palette(gfx_resstate_t *state, int version, int *colors_nr, void *internal, int nr);
+/* Retreives the static palette from the interpreter-specific code
+** Parameters: (int) version: Interpreter version to use
+** (int *) colors_nr: Number of colors to use
+** (void *) internal: Internal information provided by the interpreter
+** Returns : (gfx_pixmap_color_t *) *colors_nr static color entries
+** if a static palette must be used, NULL otherwise
+*/
+
+int
+gfxr_interpreter_needs_multicolored_pointers(int version, void *internal);
+/* Determines whether support for pointers with more than two colors is required
+** Parameters: (int) version: Interpreter version to test for
+** (void *) internal: Internal information provided by the interpreter
+** Returns : (int) 0 if no support for multi-colored pointers is required, non-0
+** otherwise
+*/
+
+#endif /* !_GFX_RSMGR_H_ */
diff --git a/engines/sci/include/gfx_resource.h b/engines/sci/include/gfx_resource.h
new file mode 100644
index 0000000000..34160c5d5d
--- /dev/null
+++ b/engines/sci/include/gfx_resource.h
@@ -0,0 +1,440 @@
+/***************************************************************************
+ gfx_resource.h Copyright (C) 2000 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+/* SCI Resource library */
+
+#ifndef _GFX_RESOURCE_H_
+#define _GFX_RESOURCE_H_
+
+#include <gfx_system.h>
+#include <gfx_driver.h>
+
+/*** Styles for pic0 drawing ***/
+/* Dithering modes */
+#define GFXR_DITHER_MODE_D16 0 /* Sierra SCI style */
+#define GFXR_DITHER_MODE_F256 1 /* Flat color interpolation */
+#define GFXR_DITHER_MODE_D256 2 /* 256 color dithering */
+/* Dithering patterns */
+#define GFXR_DITHER_PATTERN_SCALED 0 /* Dither per pixel on the 320x200 grid */
+#define GFXR_DITHER_PATTERN_1 1 /* Dither per pixel on the target */
+
+#define SCI_TITLEBAR_SIZE 10
+
+#define DRAWPIC01_FLAG_FILL_NORMALLY 1
+#define DRAWPIC01_FLAG_OVERLAID_PIC 2
+
+#define GFXR_AUX_MAP_SIZE (320*200)
+
+
+#define GFX_SCI0_IMAGE_COLORS_NR 16
+#define GFX_SCI0_PIC_COLORS_NR 256
+
+#define GFX_SCI1_AMIGA_COLORS_NR 32
+
+extern int sci0_palette;
+
+/* (gfx_pic_0.c) The 16 EGA base colors */
+extern gfx_pixmap_color_t gfx_sci0_image_colors[][16];
+
+/* (gfx_pic_0.c) The 256 interpolated colors (initialized when
+** gfxr_init_pic() is called for the first time, or when gfxr_init_static_palette() is called)
+*/
+extern gfx_pixmap_color_t gfx_sci0_pic_colors[];
+
+
+typedef struct {
+ gfx_line_mode_t line_mode; /* one of GFX_LINE_MODE_* */
+ gfx_brush_mode_t brush_mode;
+ rect_t pic_port_bounds;
+} gfxr_pic0_params_t;
+
+typedef struct {
+ int ID; /* pic number (NOT resource ID, just number) */
+ gfx_mode_t *mode;
+ gfx_pixmap_t *visual_map;
+ gfx_pixmap_t *priority_map;
+ gfx_pixmap_t *control_map;
+
+ byte aux_map[GFXR_AUX_MAP_SIZE];
+
+/* Auxiliary map details:
+** Bit 0: Vis
+** Bit 1: Pri
+** Bit 2: Ctrl
+** Bit 3-5: 'filled' (all three bits are set to 1)
+*/
+
+ rect_t bounds;
+
+ void *undithered_buffer; /* copies visual_map->index_data before dithering */
+ int undithered_buffer_size;
+
+ void *internal; /* Interpreter information, or NULL. Will be freed
+ ** automatically when the pic is freed! */
+
+} gfxr_pic_t;
+
+
+typedef struct {
+ int cels_nr;
+ gfx_pixmap_t **cels;
+} gfxr_loop_t;
+
+
+typedef struct {
+ int ID;
+
+ int flags;
+ int colors_nr;
+ gfx_pixmap_color_t *colors;
+
+ int loops_nr;
+ gfxr_loop_t *loops;
+
+ int translation[GFX_SCI0_IMAGE_COLORS_NR];
+} gfxr_view_t;
+
+
+typedef enum {
+ GFXR_FONT_SCALE_FILTER_NONE
+} gfxr_font_scale_filter_t;
+
+
+typedef struct {
+ const char *offset;
+ int length;
+} text_fragment_t;
+
+/* unscaled color index mode: Used in addition to a scaled mode
+** to render the pic resource twice. See gfxr_remove_artifacts_pic0().
+*/
+extern gfx_mode_t mode_1x1_color_index;
+
+void
+gfxr_init_static_palette(void);
+/* Initializes the static 256 color palette
+** Parameters: (void)
+** Returns : (void)
+*/
+
+gfxr_pic_t *
+gfxr_init_pic(gfx_mode_t *mode, int ID, int sci1);
+/* Initializes a gfxr_pic_t for a specific mode
+** Parameters: (gfx_mode_t *) mode: The specific graphics mode
+** (int) ID: The ID to assign to the resulting pixmaps
+** Returns : (gfxr_pic_t *) The allocated pic resource, or NULL on error.
+** This function allocates memory for use by resource drawer functions.
+*/
+
+void
+gfxr_free_pic(gfx_driver_t *driver, gfxr_pic_t *pic);
+/* Uninitializes a pic resource
+** Parameters: (gfx_driver_t *) driver: The driver the pic should be removed from
+** (gfxr_pic_t *) pic: The pic to free
+** Returns : (void)
+*/
+
+void
+gfxr_free_view(gfx_driver_t *driver, gfxr_view_t *view);
+/* Frees all memory associated with a view
+** Paremeters: (gfx_driver_t *) driver: The driver the view should be removed from
+** (gfxr_view_t *) view: The view to free
+** Returns : (void)
+*/
+
+
+/*******************/
+/* Font operations */
+/*******************/
+/* SCI0, SCI01 and SCI1 all use the same font format. */
+
+/* SQ3 uses a somewhat different scheme for calculating text sizes: it counts
+** whitespace while calculating the text size. */
+#define GFXR_FONT_FLAG_COUNT_WHITESPACE (1<<0)
+/* Don't give newline characters special semantics */
+#define GFXR_FONT_FLAG_NO_NEWLINES (1<<1)
+/* Interpret CR LF sequences as a single newline, rather than two of them */
+#define GFXR_FONT_FLAG_EAT_TRAILING_LF (1<<2)
+
+
+gfx_bitmap_font_t *
+gfxr_read_font(int id, byte *resource, int size);
+/* Geneartes a bitmap font data structure from a resource
+** Parameters: (int) id: Resource ID of the resulting font
+** (byte *) resource: Pointer to the resource data
+** (int) size: Size of the resource block
+** Returns : (gfx_bitmap_font_t *) The resulting font structure, or
+** NULL on error
+*/
+
+void
+gfxr_free_font(gfx_bitmap_font_t *font);
+/* Frees a previously allocated font structure
+** Parameters: (gfx_bitmap_font_t *) font: The font to free
+** Returns : (void)
+*/
+
+gfx_bitmap_font_t *
+gfxr_scale_font(gfx_bitmap_font_t *font, gfx_mode_t *mode, gfxr_font_scale_filter_t filter);
+/* Scales a font resource
+** Parameters: (gfx_bitmap_font_t *) font: The font to scale
+** (gfx_mode_t *) mode: The graphics mode to scale it for
+** (gfxr_font_scale_filter_t) filter: A filter to use
+** Returns : (gfx_bitmap_font_t *) A scaled font, or NULL on error
+*/
+
+text_fragment_t *
+gfxr_font_calculate_size(gfx_bitmap_font_t *font, int max_width, const char *text,
+ int *width, int *height,
+ int *lines, int *line_height, int *last_offset,
+ int flags);
+/* Calculates the size that would be occupied by drawing a specified text
+** Parameters: (gfx_bitmap_font_t *) font: The font to calculate with
+** (int) max_width: Maximum pixel width allowed for the output
+** (const char *) text: The text to calculate for
+** (int) flags: Any text formatting flags
+** Returns : (text_fragment *) a newly allocated array of text_fragments,
+** containing the start and size of each string
+** segment
+** (int) *width: The resulting width
+** (int) *height: The resulting height
+** (int) *lines: Number of lines used
+** (int) *line_height: Pixel height of a single line of text
+** (int) *last_offset: Pixel offset after the last drawn line
+** This function assumes 320x200 mode.
+*/
+
+gfx_pixmap_t *
+gfxr_draw_font(gfx_bitmap_font_t *font, const char *text, int characters,
+ gfx_pixmap_color_t *fg0, gfx_pixmap_color_t *fg1, gfx_pixmap_color_t *bg);
+/* Draws text in a specific font to a pixmap
+** Parameters: (gfx_bitmap_font_t *) font: The font to use for drawing
+** (char *) text: The start of the text to draw
+** (int) characters: The number of characters to draw
+** (gfx_pixmap_color_t *) fg0: The first foreground color
+** (gfx_pixmap_color_t *) fg1: The second foreground color
+** (gfx_pixmap_color_t *) bg: The background color
+** Returns : (gfx_pixmap_t *) The result pixmap, or NULL on error
+** The results are written to the pixmap's index buffer. Contents of the
+** foreground and background fields are copied into a newly allocated font
+** structure, so that the pixmap may be translated directly.
+** If any of the colors is null, it will be assumed to be transparent.
+** In color index mode, the specified colors have to be preallocated.
+*/
+
+
+/*********************/
+/* SCI0 operations */
+/*********************/
+
+
+void
+gfxr_clear_pic0(gfxr_pic_t *pic, int sci_titlebar_size);
+/* Clears all pic buffers of one pic
+** Parameters: (gfxr_pic_t) pic: The picture to clear
+** (int) sci_titlebar_size: How much space to reserve for the title bar
+** Returns : (void)
+** This function should be called before gfxr_draw_pic0, unless cumulative
+** drawing is intended
+*/
+
+
+void
+gfxr_draw_pic01(gfxr_pic_t *pic, int fill_normally, int default_palette,
+ int size, byte *resource, gfxr_pic0_params_t *style, int resid, int sci1,
+ gfx_pixmap_color_t *static_pal, int static_pal_nr);
+/* Draws a pic resource (all formats prior to SCI1.1)
+** Parameters: (gfxr_pic_t *) pic: The pic to draw to
+** (int) fill_normally: If 1, the pic is drawn normally; if 0, all
+** fill operations will fill with black
+** (int) default_palette: The default palette to use for drawing
+** (int) size: Resource size
+** (byte *) resource: Pointer to the resource data
+** (gfxr_pic0_params_t *) style: The drawing style
+** (int) resid: The resource ID
+** (int) sci1: Nonzero if SCI1
+** (gfx_pixmap_color_t *) static_pal: The static palette
+** (int) static_pal_nr: Number of entries in static palette
+** Returns : (void)
+** The result is stored in gfxr_visual_map, gfxr_priority_map, and gfxr_control_map.
+** The palette entry of gfxr_visual_map is never used.
+** Note that the picture will not be drawn dithered; use gfxr_dither_pic0 for that.
+*/
+
+void
+gfxr_draw_pic11(gfxr_pic_t *pic, int fill_normally, int default_palette,
+ int size, byte *resource, gfxr_pic0_params_t *style, int resid,
+ gfx_pixmap_color_t *static_pal, int static_pal_nr);
+/* Draws a pic resource (SCI1.1)
+** Parameters: (gfxr_pic_t *) pic: The pic to draw to
+** (int) fill_normally: If 1, the pic is drawn normally; if 0, all
+** fill operations will fill with black
+** (int) default_palette: The default palette to use for drawing
+** (int) size: Resource size
+** (byte *) resource: Pointer to the resource data
+** (gfxr_pic0_params_t *) style: The drawing style
+** (int) resid: The resource ID
+** (gfx_pixmap_color_t *) static_pal: The static palette
+** (int) static_pal_nr: Number of entries in static palette
+** Returns : (void)
+** The result is stored in gfxr_visual_map, gfxr_priority_map, and gfxr_control_map.
+** The palette entry of gfxr_visual_map is never used.
+** Note that the picture will not be drawn dithered; use gfxr_dither_pic0 for that.
+*/
+
+void
+gfxr_remove_artifacts_pic0(gfxr_pic_t *dest, gfxr_pic_t *src);
+/* Removes artifacts from a scaled pic
+** Parameters: (gfxr_pic_t *) dest: The scaled pic
+** (gfxr_pic_t *) src: An unscaled pic
+** Returns : (void)
+** Using information from the (correctly rendered) src pic, this function implements
+** some heuristics to remove artifacts from dest. Must be used before dither_pic0 is
+** called, because it operates on the index buffer.
+*/
+
+void
+gfxr_dither_pic0(gfxr_pic_t *pic, int mode, int pattern);
+/* Dithers a gfxr_visual_map
+** Parameters: (gfxr_pic_t *) pic: The pic to dither
+** (int) mode: One of GFXR_DITHER_MODE
+** (int) pattern: One of GFXR_DITHER_PATTERN
+** Returns : (void)
+*/
+
+gfxr_view_t *
+gfxr_draw_view0(int id, byte *resource, int size, int palette);
+/* Calculates an SCI0 view
+** Parameters: (int) id: Resource ID of the view
+** (byte *) resource: Pointer to the resource to read
+** (int) size: Size of the resource
+** (int) palette: The palette to use
+** Returns : (gfxr_view_t *) The resulting view
+*/
+
+gfx_pixmap_t *
+gfxr_draw_cursor0(int id, byte *resource, int size);
+/* Calculates an SCI0 cursor
+** Parameters: (int) id: The cursor's resource ID
+** (byte *) resource: Pointer to the resource data
+** (int) size: Resource size
+** Returns : (gfx_pixmap_t *) A newly allocated pixmap storing the cursor
+*/
+
+/**********************/
+/* SCI01 operations */
+/**********************/
+
+gfx_pixmap_t *
+gfxr_draw_cursor01(int id, byte *resource, int size);
+/* Calculates an SCI01 cursor
+** Parameters: (int) id: The cursor's resource ID
+** (byte *) resource: Pointer to the resource data
+** (int) size: Resource size
+** Returns : (gfx_pixmap_t *) A newly allocated pixmap containing an index
+** color representation of the cursor
+*/
+
+
+/*********************/
+/* SCI1 operations */
+/*********************/
+
+gfx_pixmap_color_t *
+gfxr_read_pal1(int id, int *colors_nr, byte *resource, int size);
+/* Reads an SCI1 palette
+** Parameters: (int) id: Resource ID for the palette (or the view it was found in)
+** (int *) colors_nr: Pointer to the variable the number of colors
+** will be stored in
+** (byte *) resource: Source data
+** (int) size: Size of the memory block pointed to by resource
+** Returns : (gfx_pixmap_color_t *) *colors_nr color_t entries with the colors
+*/
+
+gfx_pixmap_color_t *
+gfxr_read_pal1_amiga(int *colors_nr, FILE *f);
+/* Reads an SCI1 palette
+** Parameters: (int *) colors_nr: Pointer to the variable the number of colors
+** will be stored in
+** (FILE *) f: Palette file
+** Returns : (gfx_pixmap_color_t *) *colors_nr color_t entries with the colors
+*/
+
+gfx_pixmap_color_t *
+gfxr_read_pal11(int id, int *colors_nr, byte *resource, int size);
+/* Reads an SCI1.1 palette
+** Parameters: (int) id: Resource ID for the palette (or the view it was found in)
+** (int *) colors_nr: Pointer to the variable the number of colors
+** will be stored in
+** (byte *) resource: Source data
+** (int) size: Size of the memory block pointed to by resource
+** Returns : (gfx_pixmap_color_t *) *colors_nr color_t entries with the colors
+*/
+
+gfxr_view_t *
+gfxr_draw_view1(int id, byte *resource, int size, gfx_pixmap_color_t *static_pal,
+ int static_pal_nr);
+/* Calculates an SCI1 view
+** Parameters: (int) id: Resource ID of the view
+** (byte *) resource: Pointer to the resource to read
+** (int) size: Size of the resource
+** (gfx_pixmap_color_t *) static_pal: The static palette
+** (int) static_pal_nr: Number of entries in static palette
+** Returns : (gfxr_view_t *) The resulting view
+*/
+
+gfx_pixmap_t *
+gfxr_draw_cel11(int id, int loop, int cel, int mirrored, byte *resource_base, byte *cel_base, int size, gfxr_view_t *view);
+
+
+gfx_pixmap_t *
+gfxr_endianness_adjust(gfx_pixmap_t *pixmap, gfx_mode_t *mode);
+/* Endianness-adjusts a pixmap, if neccessary
+** Parameters: (gfx_pixmap_t *) pixmap: The pixmap to adjust
+** (gfx_mode_t *) mode: The mode to adjust it for
+** Returns : (gfx_pixmap_t *) pixmap, or NULL on error
+** The pixmap is adjusted iff the mode signals that this is
+** required (by means of setting the appropriate flag), and
+** the mode has a byte depth of more than 1.
+*/
+
+
+static inline int
+get_uint_16(byte *offset)
+{
+ return ((unsigned int) offset[0] | (((unsigned int) offset[1]) << 8));
+}
+
+static inline int
+get_int_16(byte *offset)
+{
+ return ((int) offset[0] | (((int) offset[1]) << 8));
+}
+
+
+#endif /* !_GFX_RESOURCE_H_ */
+
diff --git a/engines/sci/include/gfx_state_internal.h b/engines/sci/include/gfx_state_internal.h
new file mode 100644
index 0000000000..dc12e3c8b9
--- /dev/null
+++ b/engines/sci/include/gfx_state_internal.h
@@ -0,0 +1,238 @@
+/***************************************************************************
+ gfx_state_internal.h Copyright (C) 2000,01 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef _GFX_STATE_INTERNAL_H_
+#define _GFX_STATE_INTERNAL_H_
+
+#include <gfx_tools.h>
+#include <gfx_options.h>
+#include <gfx_operations.h>
+#include <gfx_resmgr.h>
+#include <gfx_system.h>
+
+
+#define GFXW_FLAG_VISIBLE (1<<0)
+#define GFXW_FLAG_OPAQUE (1<<1)
+#define GFXW_FLAG_CONTAINER (1<<2)
+#define GFXW_FLAG_DIRTY (1<<3)
+#define GFXW_FLAG_TAGGED (1<<4)
+#define GFXW_FLAG_MULTI_ID (1<<5) /* Means that the ID used herein may be used more than once, i.e. is not unique */
+#define GFXW_FLAG_IMMUNE_TO_SNAPSHOTS (1<<6) /* Snapshot restoring doesn't kill this widget, and +5 bonus to saving throws vs. Death Magic */
+#define GFXW_FLAG_NO_IMPLICIT_SWITCH (1<<7) /* Ports: Don't implicitly switch to this port when disposing windows */
+
+typedef struct {
+ int serial; /* The first serial number to kill */
+ rect_t area;
+} gfxw_snapshot_t;
+
+typedef enum {
+ GFXW_, /* Base widget */
+
+ GFXW_BOX,
+ GFXW_RECT,
+ GFXW_LINE, /* For lines, the bounding rectangle's xl, yl determine the line's expansion:
+ ** (x2, y2) = (x+xl, y+yl) */
+ GFXW_INVERSE_LINE,
+ GFXW_VIEW,
+ GFXW_STATIC_VIEW,
+ GFXW_DYN_VIEW,
+ GFXW_PIC_VIEW,
+ GFXW_TEXT,
+
+ GFXW_CONTAINER,
+
+ GFXW_LIST,
+ GFXW_SORTED_LIST,
+ GFXW_VISUAL,
+ GFXW_PORT
+
+} gfxw_widget_type_t;
+
+
+#define GFXW_MAGIC_VALID 0xC001
+#define GFXW_MAGIC_INVALID 0xbad
+
+#define GFXW_NO_ID -1
+
+struct _gfxw_widget;
+struct _gfxw_container_widget;
+struct _gfxw_visual;
+
+typedef int gfxw_point_op(struct _gfxw_widget *, point_t);
+typedef int gfxw_visual_op(struct _gfxw_widget *, struct _gfxw_visual *);
+typedef int gfxw_op(struct _gfxw_widget *);
+typedef int gfxw_op_int(struct _gfxw_widget *, int);
+typedef int gfxw_bin_op(struct _gfxw_widget *, struct _gfxw_widget *);
+
+#define WIDGET_COMMON \
+ int magic; /* Extra check after typecasting */ \
+ int serial; /* Serial number */ \
+ int flags; /* Widget flags */ \
+ gfxw_widget_type_t type; \
+ rect_t bounds; /* Boundaries */ \
+ struct _gfxw_widget *next; /* Next widget in widget list */ \
+ int ID; /* Unique ID or GFXW_NO_ID */ \
+ int subID; /* A 'sub-ID', or GFXW_NO_ID */ \
+ struct _gfxw_container_widget *parent; /* The parent widget, or NULL if not owned */ \
+ struct _gfxw_visual *visual; /* The owner visual */ \
+ int widget_priority; /* Drawing priority, or -1 */ \
+ gfxw_point_op *draw; /* Draw widget (if dirty) and anything else required for the display to be consistant */ \
+ gfxw_op *widfree; /* Remove widget (and any sub-widgets it may contain) */ \
+ gfxw_op *tag; /* Tag the specified widget */ \
+ gfxw_op_int *print; /* Prints the widget's contents, using sciprintf. Second parameter is indentation. */ \
+ gfxw_bin_op *compare_to; /* a.compare_to(a, b) returns <0 if a<b, =0 if a=b and >0 if a>b */ \
+ gfxw_bin_op *equals; /* a equals b if both cause the same data to be displayed */ \
+ gfxw_bin_op *should_replace; /* (only if a equals b) Whether b should replace a even though they are equivalent */ \
+ gfxw_bin_op *superarea_of; /* a superarea_of b <=> for each pixel of b there exists an opaque pixel in a at the same location */ \
+ gfxw_visual_op *set_visual /* Sets the visual the widget belongs to */
+
+typedef struct _gfxw_widget {
+ WIDGET_COMMON;
+} gfxw_widget_t;
+
+
+#define GFXW_IS_BOX(widget) ((widget)->type == GFXW_BOX)
+typedef struct {
+ WIDGET_COMMON;
+ gfx_color_t color1, color2;
+ gfx_box_shade_t shade_type;
+} gfxw_box_t;
+
+
+#define GFXW_IS_PRIMITIVE(widget) ((widget)->type == GFXW_RECT || (widget)->type == GFXW_LINE || (widget->type == GFXW_INVERSE_LINE))
+typedef struct {
+ WIDGET_COMMON;
+ gfx_color_t color;
+ gfx_line_mode_t line_mode;
+ gfx_line_style_t line_style;
+} gfxw_primitive_t;
+
+
+
+#define VIEW_COMMON \
+ WIDGET_COMMON; \
+ point_t pos; /* Implies the value of 'bounds' in WIDGET_COMMON */ \
+ gfx_color_t color; \
+ int view, loop, cel; \
+ int palette
+
+#define GFXW_IS_VIEW(widget) ((widget)->type == GFXW_VIEW || (widget)->type == GFXW_STATIC_VIEW \
+ || (widget)->type == GFXW_DYN_VIEW || (widget)->type == GFXW_PIC_VIEW)
+typedef struct {
+ VIEW_COMMON;
+} gfxw_view_t;
+
+#define GFXW_IS_DYN_VIEW(widget) ((widget)->type == GFXW_DYN_VIEW || (widget)->type == GFXW_PIC_VIEW)
+typedef struct {
+ VIEW_COMMON;
+ /* fixme: This code is specific to SCI */
+ rect_t draw_bounds; /* The correct position to draw to */
+ void *under_bitsp, *signalp;
+ int under_bits, signal;
+ int z; /* The z coordinate: Added to y, but used for sorting */
+ int sequence; /* Sequence number: For sorting */
+ int force_precedence; /* Precedence enforcement variable for sorting- defaults to 0 */
+} gfxw_dyn_view_t;
+
+
+
+#define GFXW_IS_TEXT(widget) ((widget)->type == GFXW_TEXT)
+typedef struct {
+ WIDGET_COMMON;
+ int font_nr;
+ int lines_nr, lineheight, lastline_width;
+ char *text;
+ gfx_alignment_t halign, valign;
+ gfx_color_t color1, color2, bgcolor;
+ int text_flags;
+ int width, height; /* Real text width and height */
+ gfx_text_handle_t *text_handle;
+} gfxw_text_t;
+
+
+/* Container widgets */
+
+typedef int gfxw_unary_container_op(struct _gfxw_container_widget *);
+typedef int gfxw_container_op(struct _gfxw_container_widget *, gfxw_widget_t *);
+typedef int gfxw_rect_op(struct _gfxw_container_widget *, rect_t, int);
+
+#define WIDGET_CONTAINER \
+ WIDGET_COMMON; \
+ rect_t zone; /* The writeable zone (absolute) for contained objects */ \
+ gfx_dirty_rect_t *dirty; /* List of dirty rectangles */ \
+ gfxw_widget_t *contents; \
+ gfxw_widget_t **nextpp; /* Pointer to the 'next' pointer in the last entry in contents */ \
+ gfxw_unary_container_op *free_tagged; /* Free all tagged contained widgets */ \
+ gfxw_unary_container_op *free_contents; /* Free all contained widgets */ \
+ gfxw_rect_op *add_dirty_abs; /* Add an absolute dirty rectangle */ \
+ gfxw_rect_op *add_dirty_rel; /* Add a relative dirty rectangle */ \
+ gfxw_container_op *add /* Append widget to an appropriate position (for view and control lists) */
+
+
+typedef struct _gfxw_container_widget {
+ WIDGET_CONTAINER;
+} gfxw_container_t;
+
+
+#define GFXW_IS_CONTAINER(widget) ((widget)->type == GFXW_PORT || (widget)->type == GFXW_VISUAL || \
+ (widget)->type == GFXW_SORTED_LIST || (widget)->type == GFXW_LIST)
+
+#define GFXW_IS_LIST(widget) ((widget)->type == GFXW_LIST || (widget)->type == GFXW_SORTED_LIST)
+#define GFXW_IS_SORTED_LIST(widget) ((widget)->type == GFXW_SORTED_LIST)
+typedef gfxw_container_t gfxw_list_t;
+
+#define GFXW_IS_VISUAL(widget) ((widget)->type == GFXW_VISUAL)
+typedef struct _gfxw_visual {
+ WIDGET_CONTAINER;
+ struct _gfxw_port **port_refs; /* References to ports */
+ int port_refs_nr;
+ int font_nr; /* Default font */
+ gfx_state_t *gfx_state;
+} gfxw_visual_t;
+
+#define GFXW_IS_PORT(widget) ((widget)->type == GFXW_PORT)
+typedef struct _gfxw_port {
+ WIDGET_CONTAINER;
+
+ gfxw_list_t *decorations; /* optional window decorations- drawn before the contents */
+ gfxw_widget_t *port_bg; /* Port background widget or NULL */
+ gfx_color_t color, bgcolor;
+ int chrono_port;
+ int font_nr;
+ point_t draw_pos; /* Drawing position */
+ gfxw_snapshot_t *restore_snap; /* Snapshot to be restored automagically,
+ experimental feature used in the PQ3 interpreter */
+ int port_flags; /* interpreter-dependant flags */
+ const char *title_text;
+ byte gray_text; /* Whether text is 'grayed out' (dithered) */
+} gfxw_port_t;
+
+#undef WIDGET_COMMON
+#undef WIDGET_CONTAINER
+
+#endif /* !_GFX_STATE_INTERNAL_H_ */
+
diff --git a/engines/sci/include/gfx_system.h b/engines/sci/include/gfx_system.h
new file mode 100644
index 0000000000..e83f39fb8e
--- /dev/null
+++ b/engines/sci/include/gfx_system.h
@@ -0,0 +1,445 @@
+/***************************************************************************
+ gfx_system.h Copyright (C) 2000,01 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef _SCI_GFX_SYSTEM_
+#define _SCI_GFX_SYSTEM_
+
+#include <sci_memory.h>
+#include <resource.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#define GFX_DEBUG
+
+/* General output macros */
+#ifdef __GNUC__
+# define GFXERROR gfxprintf("GFX Error: %s, %s() L%d:", __FILE__, __FUNCTION__, __LINE__); sciprintf
+# define GFXWARN gfxprintf("GFX Warning: %s, %s() L%d:", __FILE__, __FUNCTION__, __LINE__); sciprintf
+# ifdef GFX_DEBUG
+# define GFXDEBUG gfxprintf("GFX-debug: %s, %s() L%d:", __FILE__, __FUNCTION__, __LINE__); sciprintf
+# else /* !GFX_DEBUG */
+# define GFXDEBUG if (0) printf
+# endif /* !GFX_DEBUG */
+#else /* !__GNUC__ */
+# define GFXERROR gfxprintf("GFX Error: %s, L%d:", __FILE__, __LINE__); sciprintf
+# define GFXWARN gfxprintf("GFX Warning: %s, L%d:", __FILE__, __LINE__); sciprintf
+# ifdef GFX_DEBUG
+# define GFXDEBUG gfxprintf("GFX-debug: %s, L%d:", __FILE__, __LINE__); sciprintf
+# else /* !GFX_DEBUG */
+# define GFXDEBUG if (0) printf
+# endif /* !GFX_DEBUG */
+#endif /* !__GNUC__ */
+
+/***********************/
+/*** Data structures ***/
+/***********************/
+
+#define GFX_COLOR_SYSTEM -1
+
+
+typedef struct { /* gfx_palette_color_t: Palette color description */
+
+ int lockers; /* Number of pixmaps holding a lock on that color.
+ ** 0 means that the color is unused, -1 means that it is
+ ** "system allocated" and may not be freed. */
+ byte r,g,b; /* Red, green, blue; intensity varies from 0 (min) to 255 (max) */
+
+} gfx_palette_color_t;
+
+
+
+typedef struct { /* gfx_palette_t: Palette description for color index modes */
+
+ int max_colors_nr; /* Maximum number of allocated colors */
+ gfx_palette_color_t *colors; /* Actual colors, malloc()d as a block */
+} gfx_palette_t;
+
+
+
+#define GFX_MODE_IS_UNSCALED(mode) (((mode)->xfact == 1) && ((mode)->yfact == 1))
+
+/* Reverse-endian: Target display has non-native endianness
+** (BE if local is LE or the other way 'round */
+#define GFX_MODE_FLAG_REVERSE_ENDIAN (1<<0)
+/* Reverse Alpha: Alpha values 0 mean "transparent" if this is
+** enabled */
+#define GFX_MODE_FLAG_REVERSE_ALPHA (1<<1)
+
+typedef struct { /* gfx_mode_t: Graphics mode description */
+
+ int xfact, yfact; /* Horizontal and vertical scaling factors */
+ int bytespp; /* Bytes per pixel */
+
+ unsigned int flags; /* GFX_MODE_FLAG_* Flags- see above */
+
+
+ gfx_palette_t *palette; /* Palette or NULL to indicate non-palette mode.
+ ** Palette (color-index) mode is only supported
+ ** for bytespp=1. */
+
+ /* Color masks */
+ unsigned int red_mask, green_mask, blue_mask, alpha_mask;
+ short red_shift, green_shift, blue_shift, alpha_shift;
+
+ /* Each of the mask/shift pairs describe where the corresponding color
+ ** values are stored for the described mode. Internally, color
+ ** calculations are done by using 32 bit values for r, g, b, a. After
+ ** the internal values have been calculated, they are shifted RIGHT
+ ** by the xxx_shift amount described above, then ANDed with the
+ ** corresponding color mask; finally, all three results are ORred to-
+ ** gether. The alpha values are used as appropriate; if alpha_mask is
+ ** zero, then images use a special alpha map. */
+
+} gfx_mode_t;
+
+
+
+#define GFX_COLOR_INDEX_UNMAPPED -1
+
+typedef struct { /* gfx_pixmap_color_t: Pixmap-specific color entries */
+ int global_index; /* Global index color or GFX_COLOR_INDEX_UNMAPPED. */
+ guint8 r, g, b; /* Real color */
+} gfx_pixmap_color_t;
+
+
+
+typedef struct { /* gfx_color_t: Full color */
+ gfx_pixmap_color_t visual;
+ guint8 alpha; /* transparency = (1-opacity) */
+ byte priority, control;
+ byte mask; /* see mask values below */
+} gfx_color_t;
+
+
+
+typedef struct { /* rect_t: Rectangle description */
+ int x, y;
+ int xl, yl; /* width, height: (x,y,xl,yl)=(5,5,1,1) occupies 1 pixel */
+} rect_t;
+
+
+/* Generates a rect_t from index data
+** Parameters: (int x int) x,y: Upper left point of the rectangle
+** (int x int) xl, yl: Horizontal and vertical extension of the rectangle
+** Returns : (rect_t) A rectangle matching the supplied parameters
+*/
+static inline rect_t
+gfx_rect(int x, int y, int xl, int yl)
+{
+ rect_t rect;
+
+ rect.x = x;
+ rect.y = y;
+ rect.xl = xl;
+ rect.yl = yl;
+
+ return rect;
+}
+
+#define GFX_PRINT_RECT(rect) (rect).x, (rect).y, (rect).xl, (rect).yl
+
+#define OVERLAP(a, b, z, zl) (a.z >= b.z && a.z < (b.z + b.zl))
+
+/* Determines whether two rects overlap
+** Parameters: (rect_t x rect_t) a,b: The two rect_ts to check for overlap
+** Returns : (int) 1 if they overlap, 0 otherwise
+*/
+static inline int
+gfx_rects_overlap(rect_t a, rect_t b)
+{
+ return (OVERLAP(a, b, x, xl) || OVERLAP(b, a, x, xl))
+ && (OVERLAP(a, b, y, yl) || OVERLAP(b, a, y, yl));
+}
+
+#undef OVERLAP
+
+#define MERGE_PARTIAL(z, zl) \
+if (a.z < b.z) SUBMERGE_PARTIAL(a, b, z, zl) \
+else SUBMERGE_PARTIAL(b, a, z, zl)
+
+#define SUBMERGE_PARTIAL(a, b, z, zl) \
+{ \
+ retval.z = a.z; \
+ retval.zl = a.zl; \
+ if (b.z + b.zl > a.z + a.zl) \
+ retval.zl = (b.z + b.zl - a.z); \
+}
+
+
+
+#define RECT(a) a.x, a.y, a.xl, a.yl
+
+/* Merges two rects
+** Parameters: (rect_t x rect_t) a,b: The two rects to merge
+** Returns : (rect_t) The smallest rect containing both a and b
+*/
+static inline rect_t
+gfx_rects_merge(rect_t a, rect_t b)
+{
+ rect_t retval;
+ MERGE_PARTIAL(x, xl);
+ MERGE_PARTIAL(y, yl);
+ return retval;
+}
+#undef MERGE_PARTIAL
+#undef SUBMERGE_PARTIAL
+
+
+/* Subset predicate for rectangles
+** Parameters: (rect_t) a, b: The two rects to compare
+** Returns : non-zero iff for each pixel p in a the following holds: p is in b.
+*/
+static inline int
+gfx_rect_subset(rect_t a, rect_t b)
+{
+ return ((a.x >= b.x) && (a.y >= b.y)
+ && ((a.x + a.xl) <= (b.x + b.xl))
+ && ((a.y + a.yl) <= (b.y + b.yl)));
+}
+
+
+/* Equality predicate for rects
+** Parameters: (rect_t) a, b
+** Returns : (int) gfx_rect_subset(a,b) AND gfx_rect_subset(b,a)
+*/
+static inline int
+gfx_rect_equals(rect_t a, rect_t b)
+{
+ return (a.x == b.x
+ && a.xl == b.xl
+ && a.y == b.y
+ && a.yl == b.yl);
+}
+
+
+/* gfx_rect_fullscreen is declared in gfx/gfx_tools.c */
+extern rect_t gfx_rect_fullscreen;
+
+/*** points ***/
+
+typedef struct {
+ int x, y;
+} point_t;
+
+#define GFX_PRINT_POINT(p) (p).x, (p).y
+
+/* Generates a point_t from index data
+** Parameters: (int x int) x,y: Indicated point
+** Returns : (point_t) The resulting structure
+*/
+static inline point_t
+gfx_point(int x, int y)
+{
+ point_t point;
+
+ point.x = x;
+ point.y = y;
+
+ return point;
+}
+
+/* Translation operation for rects
+** Parameters: (rect_t) rect: The rect to translate
+** (point_t) offset: The offset to translate it by
+** Returns : (rect_t) The translated rect
+*/
+static inline rect_t
+gfx_rect_translate(rect_t rect, point_t offset)
+{
+ rect.x += offset.x;
+ rect.y += offset.y;
+
+ return rect;
+}
+
+#define GFX_RESID_NONE -1
+
+#define GFX_PIC_COLORS 256
+
+#define GFX_PIXMAP_FLAG_SCALED_INDEX (1<<0) /* Index data is scaled already */
+#define GFX_PIXMAP_FLAG_EXTERNAL_PALETTE (1<<1) /* The colors pointer points to an external palette */
+#define GFX_PIXMAP_FLAG_INSTALLED (1<<2) /* Pixmap has been registered */
+#define GFX_PIXMAP_FLAG_PALETTE_ALLOCATED (1<<3) /* Palette has been allocated */
+#define GFX_PIXMAP_FLAG_PALETTE_SET (1<<4) /* Palette has been propagated to the driver */
+#define GFX_PIXMAP_FLAG_DONT_UNALLOCATE_PALETTE (1<<5) /* Used by text, which uses preallocated colors */
+#define GFX_PIXMAP_FLAG_PALETTIZED (1<<6) /* Indicates a palettized view */
+
+#define GFX_PIXMAP_COLOR_KEY_NONE -1 /* No transpacency colour key */
+
+typedef struct { /* gfx_pixmap_t: Pixel map */
+
+ /*** Meta information ***/
+ int ID; /* Resource ID, or GFX_RESID_NONE for anonymous graphical data */
+ short loop, cel; /* loop and cel number for views */
+
+
+ /*** Color map ***/
+ int colors_nr;
+ gfx_pixmap_color_t *colors; /* colors_nr color entries, or NULL if the
+ ** default palette is to be used.
+ ** A maximum of 255 colors is allowed; color
+ ** index 0xff is reserved for transparency.
+ ** As a special exception, 256 colors are
+ ** allowed for background pictures (which do
+ ** not use transparency)
+ */
+ unsigned int flags;
+
+ /*** Hot spot ***/
+ int xoffset, yoffset; /* x and y coordinates of the 'hot spot' (unscaled) */
+
+ /*** Index data ***/
+ int index_xl, index_yl; /* width and height of the indexed original image */
+ byte *index_data; /* Color-index data, or NULL if read from an
+ ** external source
+ */
+
+ /*** Drawable data ***/
+ int xl, yl; /* width and height of the actual image */
+ int data_size; /* Amount of allocated memory */
+ byte *data; /* Drawable data, or NULL if not converted. */
+
+ byte *alpha_map; /* Byte map with alpha values. It is used only if the
+ ** graphics mode's alpha_mask is zero.
+ */
+
+ int color_key;
+
+ /*** Data reserved for gfx_driver use ***/
+ struct pixmap_internal { /* Internal state management data for use by drivers */
+ int handle; /* initialized to 0 */
+ void *info; /* initialized to NULL */
+ } internal;
+
+} gfx_pixmap_t;
+
+
+#define GFX_FONT_BUILTIN_5x8 -1
+#define GFX_FONT_BUILTIN_6x10 -2
+
+typedef struct { /* gfx_bitmap_font_t: Bitmap font information */
+ int ID; /* Unique resource ID */
+
+ int chars_nr; /* Numer of available characters */
+
+ int *widths; /* chars_nr character widths, in pixels */
+
+ int row_size; /* Byte size of each pixel row. For unscaled fonts, this is
+ ** always 1, 2, or 4. Otherwise, it's a multiple of 4.
+ */
+
+ int line_height; /* Height of each text line (usually identical to height) */
+ int height; /* Height for all characters, in pixel rows */
+ int char_size; /* Amount of memory occupied by one character in data */
+
+ byte *data; /* Font data, consisting of 'chars_nr' entries of 'height' rows
+ ** of 'row_size' bytes. For each character ch, its first byte
+ ** (the topmost row) is located at (data + (charsize * ch)), and
+ ** its pixel width is widths[ch], provided that (ch < chars_nr).
+ */
+
+} gfx_bitmap_font_t;
+
+
+
+/***********************/
+/*** Constant values ***/
+/***********************/
+
+/* Default palettes */
+extern gfx_pixmap_color_t gfx_sci0_image_colors[][16];
+extern gfx_pixmap_color_t gfx_sci0_pic_colors[256];
+
+/* Return values */
+enum gfx_return_value_t {
+ GFX_OK = 0, /* Indicates "operation successful" */
+ GFX_ERROR = -1, /* Indicates "operation failed" */
+ GFX_FATAL = -2
+/* Fatal error: Used by graphics drivers to indicate that they were unable to
+** do anything useful
+*/
+};
+
+
+typedef enum {/* Map masks */
+ GFX_MASK_NONE = 0,
+ GFX_MASK_VISUAL = 1,
+ GFX_MASK_PRIORITY = 2,
+ GFX_MASK_CONTROL = 4
+} gfx_map_mask_t;
+
+/* 'no priority' mode */
+#define GFX_NO_PRIORITY -1
+
+/* Text alignment values */
+
+typedef enum {
+ ALIGN_RIGHT = -1,
+ ALIGN_TOP = -1,
+ ALIGN_CENTER = 1,
+ ALIGN_LEFT = 0,
+ ALIGN_BOTTOM = 0
+} gfx_alignment_t;
+
+
+typedef enum {
+ GFX_LINE_MODE_CORRECT, /* Scaled separately */
+ GFX_LINE_MODE_FAST, /* Scaled by (xfact+yfact)/2 */
+ GFX_LINE_MODE_FINE /* Always drawn at width 1 */
+} gfx_line_mode_t;
+
+typedef enum {
+ GFX_BRUSH_MODE_SCALED, /* Just scale the brush pixels */
+ GFX_BRUSH_MODE_ELLIPSES, /* Replace pixels with ellipses */
+ GFX_BRUSH_MODE_RANDOM_ELLIPSES, /* Replace pixels with ellipses moved and re-scaled randomly */
+ GFX_BRUSH_MODE_MORERANDOM /* Distribute randomly */
+} gfx_brush_mode_t;
+
+
+typedef enum {
+ GFX_LINE_STYLE_NORMAL,
+ GFX_LINE_STYLE_STIPPLED
+} gfx_line_style_t;
+
+
+typedef enum {
+ GFX_SHADE_FLAT, /* Don't shade */
+ GFX_SHADE_VERTICALLY, /* Shade vertically */
+ GFX_SHADE_HORIZONTALLY /* Shade horizontally */
+} gfx_rectangle_fill_t;
+
+
+typedef enum {
+ GFX_COLOR_MODE_AUTO = 0, /* Auto-detect- handled by the gfxop library */
+ GFX_COLOR_MODE_INDEX = 1, /* Index mode */
+ GFX_COLOR_MODE_HIGH = 2, /* High color mode (15bpp or 16 bpp) */
+ GFX_COLOR_MODE_TRUE = 4 /* True color mode (24 bpp padded to 32 bpp) */
+} gfx_color_mode_t;
+
+#endif /* !_SCI_GFX_SYSTEM_ */
diff --git a/engines/sci/include/gfx_tools.h b/engines/sci/include/gfx_tools.h
new file mode 100644
index 0000000000..65fc5cba72
--- /dev/null
+++ b/engines/sci/include/gfx_tools.h
@@ -0,0 +1,293 @@
+/***************************************************************************
+ gfx_tools.h Copyright (C) 2000 Christoph Reichenbach
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+/* FreeSCI 0.3.1+ graphics subsystem helper functions */
+
+
+#ifndef _GFX_TOOLS_H_
+#define _GFX_TOOLS_H_
+
+#include <gfx_system.h>
+#include <gfx_driver.h>
+
+typedef enum {
+ GFX_XLATE_FILTER_NONE,
+ GFX_XLATE_FILTER_LINEAR,
+ GFX_XLATE_FILTER_TRILINEAR
+} gfx_xlate_filter_t;
+
+typedef enum {
+ GFXR_ANTIALIASING_NONE,
+ GFXR_ANTIALIASING_SIMPLE
+} gfxr_antialiasing_t;
+
+
+extern DLLEXTERN int gfx_crossblit_alpha_threshold; /* Crossblitting functions use this value as threshold
+ ** for distinguishing between transparent and opaque
+ ** wrt alpha values */
+
+gfx_mode_t *
+gfx_new_mode(int xfact, int yfact, int bytespp, unsigned int red_mask, unsigned int green_mask,
+ unsigned int blue_mask, unsigned int alpha_mask, int red_shift, int green_shift,
+ int blue_shift, int alpha_shift, int palette, int flags);
+/* Allocates a new gfx_mode_t structure with the specified parameters
+** Parameters: (int x int) xfact x yfact: Horizontal and vertical scaling factors
+** (int) bytespp: Bytes per pixel
+** (unsigned int) red_mask: Red bit mask
+** (unsigned int) green_mask: Green bit mask
+** (unsigned int) blue_mask: Blue bit mask
+** (unsigned int) Alpha_mask: Alpha bit mask, or 0 if the alpha channel is not supported
+** (int) red_shift: Red shift value
+** (int) green_shift: Green shift value
+** (int) blue_shift: Blue shift value
+** (int) alpha_shift: Alpha shift value
+** (int) palette: Number of palette colors, 0 if we're not in palette mode
+** (int) flags: GFX_MODE_FLAG_* values ORred together, or just 0
+** Returns : (gfx_mode_t *) A newly allocated gfx_mode_t structure
+*/
+
+
+void
+gfx_clip_box_basic(rect_t *box, int maxx, int maxy);
+/* Clips a rect_t
+** Parameters: (rect_t *) box: Pointer to the box to clip
+** (int x int) maxx, maxy: Maximum allowed width and height
+** Returns : (void)
+*/
+
+
+void
+gfx_free_mode(gfx_mode_t *mode);
+/* Frees all memory allocated by a mode structure
+** Parameters: (gfx_mode_t *) mode: The mode to free
+** Returns : (void)
+*/
+
+
+gfx_pixmap_t *
+gfx_new_pixmap(int xl, int yl, int resid, int loop, int cel);
+/* Creates a new pixmap structure
+** Parameters: (int x int) xl x yl: The dimensions (in SCI coordinates) of the pixmap
+** (int) resid: The pixmap's resource ID, or GFX_RESID_NONE
+** (int) loop: For views: The pixmap's loop number
+** (int) cel: For cels: The pixmap's cel number
+** Returns : (gfx_pixmap_t *) The newly allocated pixmap
+** The following fiels are initialized:
+** ID, loop, cel, index_xl, index_yl, xl, yl, data <- NULL,
+** alpha_map <- NULL, internal.handle <- 0, internal.info <- NULL, colors <- NULL,
+** index_scaled <- 0
+*/
+
+gfx_pixmap_t *
+gfx_clone_pixmap(gfx_pixmap_t *pixmap, gfx_mode_t *mode);
+/* Clones a pixmap, minus its index data, palette and driver-specific handles
+** Parameters: (gfx_pixmap_t *) pixmap: The pixmap to clone
+** (gfx_mode_t *) mode: The mode to be applied to the pixmap
+** Returns : (gfx_pixmap_t *) The clone
+*/
+
+
+gfx_pixmap_t *
+gfx_pixmap_alloc_index_data(gfx_pixmap_t *pixmap);
+/* Allocates the index_data field of a pixmap
+** Parameters: (gfx_pixmap_t *) pixmap: The pixmap to allocate for
+** Returns : (gfx_pixmap_t *) pixmap
+*/
+
+gfx_pixmap_t *
+gfx_pixmap_free_index_data(gfx_pixmap_t *pixmap);
+/* Frees the index_data field of a pixmap
+** Parameters: (gfx_pixmap_t *) pixmap: The pixmap to modify
+** Returns : (gfx_pixmap_t *) pixmap
+*/
+
+gfx_pixmap_t *
+gfx_pixmap_alloc_data(gfx_pixmap_t *pixmap, gfx_mode_t *mode);
+/* Allocates the data field of a pixmap
+** Parameters: (gfx_pixmap_t *) pixmap: The pixmap to allocate for
+** (gfx_mode_t *) mode: The mode the memory is to be allocated for
+** Returns : (gfx_pixmap_t *) pixmap
+*/
+
+gfx_pixmap_t *
+gfx_pixmap_free_data(gfx_pixmap_t *pixmap);
+/* Frees the memory allocated for a pixmap's data field
+** Parameters: (gfx_pixmap_t *) pixmap: The pixmap to modify
+** Returns : (gfx_pixmap_t *) pixmap
+*/
+
+void
+gfx_free_pixmap(gfx_driver_t *driver, gfx_pixmap_t *pxm);
+/* Frees all memory associated with a pixmap
+** Parameters: (gfx_driver_t *) driver: The driver the pixmap is to be removed from
+** (gfx_pixmap_t *) pxm: The pixmap to free
+** Returns : (void)
+*/
+
+void
+gfx_draw_line_pixmap_i(gfx_pixmap_t *pxm, point_t start, point_t end, int color);
+/* Draws a line to a pixmap's index data buffer
+** Parameters: (gfx_pixmap_t *) pxm: The pixmap to draw to
+** (point_t) start: Starting point of the line to draw
+** (point_t) end: End point of the line to draw
+** (int) color: The byte value to write
+** Returns : (void)
+** Remember, this only draws to the /index/ buffer, not to the drawable buffer.
+** The line is not clipped. Invalid x, y, x1, y1 values will result in memory corruption.
+*/
+
+void
+gfx_draw_line_buffer(byte *buffer, int linewidth, int pixelwidth,
+ point_t start, point_t end, unsigned int color);
+/* Draws a line to a linear pixel buffer
+** Parameters: (byte *) buffer: Pointer to the start of the buffer to draw to
+** (int) linewidth: Number of bytes per pixel line in the buffer
+** (int) pixelwidth: Number of bytes per pixel
+** (point_t) start: Starting point of the line to draw
+** (point_t) end: End point of the line to draw
+** (rect_t) Coordinates: the line should be drawn to (must be clipped already)
+** xl and yl describe relative offsets, as usual.
+** (unsigned int) color: The color to draw (only the lowest 8 * pixelwidth bits are relevant)
+** Returns : (void)
+** This function assumes 1 <= pixelwidth <= 4
+*/
+
+void
+gfx_draw_box_pixmap_i(gfx_pixmap_t *pxm, rect_t box, int color);
+/* Draws a filled rectangular area to a pixmap's index buffer
+** Parameters: (gfx_pixmap_t *) pxm: The pixmap to draw to
+** (rect_t) box: The box to fill
+** (int) color: The color to use for drawing
+** Returns : (void)
+** This function only draws to the index buffer.
+*/
+
+void
+gfx_copy_pixmap_box_i(gfx_pixmap_t *dest, gfx_pixmap_t *src, rect_t box);
+/* Copies part of a pixmap to another pixmap, with clipping
+** Parameters: (gfx_pixmap_t *) dest: The destination pixmap
+** (gfx_pixmap_t *) src: The source pixmap
+** (rect_t) box: The area to copy
+** Returns : (void)
+*/
+
+void
+gfx_xlate_pixmap(gfx_pixmap_t *pxm, gfx_mode_t *mode, gfx_xlate_filter_t filter);
+/* Translates a pixmap's index data to drawable graphics data
+** Parameters: (gfx_pixmap_t *) pxm: The pixmap to translate
+** (gfx_mode_t *) mode: The mode according which to scale
+** (gfx_xlate_filter_t) filter: How to filter the data
+** Returns : (void)
+*/
+
+void
+gfxr_antialiase(gfx_pixmap_t *pixmap, gfx_mode_t *mode, gfxr_antialiasing_t type);
+/* Performs antialiasing on a pixmap
+** Parameters: (gfx_pixmap_t *) pixmap: The pixmap to antialiase
+** (gfx_mode_t *) mode: The current mode
+** (gfxr_antialiasing_t) type: Antialiasing algorithm to use
+** Returns : (void)
+*/
+
+#define GFX_CROSSBLIT_FLAG_DATA_IS_HOMED (1<<0)
+/* Means that the first byte in the visual data refers to the
+** point corresponding to (dest.x, dest.y) */
+
+int
+gfx_crossblit_pixmap(gfx_mode_t *mode, gfx_pixmap_t *pxm, int priority,
+ rect_t src_coords, rect_t dest_coords, byte *dest,
+ int dest_line_width, byte *priority_dest,
+ int priority_line_width, int priority_skip,
+ int flags);
+/* Transfers the non-transparent part of a pixmap to a linear pixel buffer
+** Parameters: (gfx_mode_t *) mode: The graphics mode of the target buffer
+** (gfx_pixmap_t *) pxm: The pixmap to transfer
+** (int priority): The pixmap's priority
+** (rect_t) src_coords: The source coordinates within the pixmap
+** (rect_t) dest_coords: The destination coordinates (no scaling)
+** (byte *) dest: Memory position of the upper left pixel of the
+** linear pixel buffer
+** (int) dest_line_width: Byte offset of the very first pixel in the
+** second line of the linear pixel buffer,
+** relative to dest.
+** (byte *) priority_dest: Destination buffer for the pixmap's priority
+** values
+** (int) priority_line_width: Byte offset of the first pixel in the
+** second line of the priority buffer
+** (int) priority_skip: Amount of bytes allocated by each priority value
+** (int) flags: Any crossblit flags
+** Returns : (int) GFX_OK, or GFX_ERROR if the specified mode was invalid or unsupported
+** A 'linear buffer' in this context means a data buffer containing an entire
+** screen (visual or priority), with fixed offsets between each data row, and
+** linear access.
+*/
+
+int
+gfx_alloc_color(gfx_palette_t *pal, gfx_pixmap_color_t *color);
+/* Allocates a color entry for the specified pixmap color
+** Parameters: (gfx_palette_t *) pal: The palette structure the color should be allocated in
+** (gfx_pixmap_color_t *) color: The color to allocate
+** Returns : (int) GFX_ERROR if any error occured, GFX_OK if the color could be mapped to an
+** existing color or a positive value if a new color was allocated in the
+** palette.
+*/
+
+int
+gfx_free_color(gfx_palette_t *pal, gfx_pixmap_color_t *color);
+/* Frees the color entry allocated for the specified pixmap color
+** Parameters: (gfx_palette_t *) pal: The palette structure the color was previously allocated in
+** (gfx_pixmap_color_t *) color: The color to free
+** Returns : (int) GFX_ERROR if any error occured, GFX_OK otherwise
+*/
+
+gfx_pixmap_t *
+gfx_pixmap_scale_index_data(gfx_pixmap_t *pixmap, gfx_mode_t *mode);
+/* Scales the index data associated with a pixmap
+** Parameters: (gfx_pixmap_t *) pixmap: The pixmap whose index data should be scaled
+** (gfx_mode_t *) mode: The mode to scale it to
+** Returns : (gfx_pixmap_t *) pixmap
+*/
+
+
+#ifdef HAVE_ALPHA_EV6_SUPPORT
+
+extern int axp_have_mvi; /* set to 1 iff the local system has the MVI instruction set extension */
+
+void
+alpha_mvi_crossblit_32(byte *dest, byte *src, int bytes_per_dest_line, int bytes_per_src_line,
+ int xl, int yl, byte *alpha, int bytes_per_alpha_line, int bytes_per_alpha_pixel,
+ unsigned int alpha_test_mask, int alpha_shift);
+/* Internal function for accellerated 32 bit cross-blitting on Alpha hardware */
+
+void
+alpha_mvi_crossblit_32_P(byte *dest, byte *src, int bytes_per_dest_line, int bytes_per_src_line,
+ int xl, int yl, byte *alpha, int bytes_per_alpha_line, int bytes_per_alpha_pixel,
+ unsigned int alpha_test_mask, int alpha_shift,
+ byte *priority_pos, int bytes_per_priority_line, int bytes_per_priority_pixel, int priority);
+/* Internal function for accellerated 32 bit cross-blitting on Alpha hardware (with priority) */
+#endif /* __alpha__ */
+
+
+#endif /* !_GFX_TOOLS_H_ */
diff --git a/engines/sci/include/gfx_widgets.h b/engines/sci/include/gfx_widgets.h
new file mode 100644
index 0000000000..9ea9352971
--- /dev/null
+++ b/engines/sci/include/gfx_widgets.h
@@ -0,0 +1,548 @@
+/***************************************************************************
+ gfx_widgets.h Copyright (C) 2000 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+/* Graphical state management */
+
+#ifndef _GFX_WIDGETS_H_
+#define _GFX_WIDGETS_H_
+
+#include <gfx_state_internal.h>
+
+/* Enable the next line to keep a list of pointers to all widgets, with up to the specified amount
+** of members (/SLOW/) */
+/* #define GFXW_DEBUG_WIDGETS 2048 */
+
+/* Our strategy for dirty rectangle management */
+#define GFXW_DIRTY_STRATEGY GFXOP_DIRTY_FRAMES_CLUSTERS
+
+/* Properly belongs in sci_widgets.h, but we need it here */
+#define WINDOW_FLAG_AUTO_RESTORE 0x2000000
+
+/* Indicates that a Chrono-Port should not be created even if it doesn't exist. */
+#define GFXW_CHRONO_NO_CREATE 1
+
+/* Indicates that non-topmost ports should be scanned for a Chrono-Port. */
+#define GFXW_CHRONO_NON_TOPMOST 2
+
+/* Terminology
+**
+** Two special terms are used in here: /equivalent/ and /clear/. Their meanings
+** in this context are as follows:
+**
+** /clear/: Clearing a widget means overwriting the space it occupies in the back
+** buffer with data from the static buffer. This affects both the visual and the
+** priority buffer, the static buffer (and any effect the widget may have had on
+** it) is not touched.
+**
+** /equivalent/: Two Widgets A and B are equivalent if and only if either of the
+** following conditions is met:
+** a) Both A and B are text widgets, and they occupy the same bounding rectangle.
+** b) Both A and B are dynview widgets, and they have the same unique ID
+** Note that /equivalent/ is not really an equivalence relation- while it is ob-
+** viously transitive and symmetrical, it is not reflexive (e.g. a box widget
+** is not /equivalent/ to itself), although this might be a nice addition for the
+** future.
+*/
+
+
+/*********************************/
+/* Fundamental widget operations */
+/*********************************/
+
+
+#define GFXW(foo) ((gfxw_widget_t *) foo)
+/* Typecast an arbitrary widget to gfxw_widget_t*. Might eventually be changed to do tests as well. */
+
+#define GFXWC(foo) ((gfxw_container_t *) foo)
+/* Typecasts a container widget to gfxw_container_widget_t *. */
+
+/* gfxw_point_zero is declared in gfx/widgets.c */
+extern point_t gfxw_point_zero;
+
+/*********************/
+/* Widget operations */
+/*********************/
+
+/* These are for documentation purposes only. The actual declarations are in
+** gfx_state_internal.h.
+**
+**
+**
+** -- draw(gfxw_widget_t *self, point_t pos)
+** Draws the widget.
+** Parameters: (gfxw_widget_t *) self: self reference
+** (point_t) pos: The position to draw to (added to the widget's
+** internal position)
+** Returns : (int) 0
+** The widget is drawn iff it is flagged as dirty. Invoking this operation on
+** a container widget will recursively draw all of its contents.
+**
+**
+** -- widfree(gfxw_widget_t *self)
+** Frees all memory associated to the widget
+** Parameters: (gfxw_widget_t *) self: self reference
+** Returns : (int) 0
+** The widget automatically removes itself from its owner, if it has one.
+** Invoking this operation on a container will recursively free all of its
+** contents.
+**
+**
+** -- tag(gfxw_widget_t *self)
+** Tags the specified widget
+** Parameters: (gfxw_widget_t *) self: self reference
+** Returns : (int) 0
+** If invoked on a container widget, this will also tag all of the container's
+** contents (but not the contents' contents!)
+**
+**
+** -- print(gfxw_widget_t *self, int indentation)
+** Prints a string representation of the widget with sciprintf
+** Parameters: (gfxw_widget_t *) self: self reference
+** (int) indentation: Number of double spaces to indent
+** Returns ; (int) 0
+** Will recursively print all of the widget's contents if the widget contains
+** further sub-widgets
+**
+**
+** -- compare_to(gfxw_widget_t *self, gfxw_widget_t *other)
+** Compares two compareable widgets by their screen position
+** Parameters: (gfxw_widget_t *) self: self reference
+** (gfxw_widget_t *) other: other widget
+** Returns : (int) <0, 0, or >0 if other is, respectively, less than, equal
+** to, or greater than self
+** This comparison only applies to some widgets; compare_to(a,a)=0 is not
+** guaranteed. It may be used for sorting for all widgets.
+**
+**
+** -- equals(gfxw_widget_t *self, gfxw_widget_t *other)
+** Compares two compareable widgets for equality
+** Parameters: (gfxw_widget_t *) self: self reference
+** (gfxw_widget_t *) other: other widget
+** Returns : (int) 0 if the widgets are not equal, != 0 if they match
+** This operation checks whether two widgets describe the same graphical data.
+** It is used to determine whether a new widget should be discarded because it
+** describes the same graphical data as an old widget that has already been
+** drawn. For lists, it also checks whether all contents are in an identical
+** order.
+**
+**
+** -- should_replace(gfxw_widget_t *self, gfxw_widget_t *other)
+** Compares two compareable widgets for equality
+** Parameters: (gfxw_widget_t *) self: self reference
+** (gfxw_widget_t *) other: other widget
+** Returns : (int) 0 if 'self' should be kept, != 0 if it should be replaced
+** by the 'other'
+** When 'equals' returns true, this means that no new widget will be added.
+** However, in some cases newer widgets may contain information that should
+** cause the older widget to be removed nonetheless; this is indicated by this
+** function.
+**
+**
+** -- superarea_of(gfxw_widget_t *self, gfxw_widget_t *other)
+** Tests whether drawing self after other would reduce all traces of other
+** Parameters: (gfxw_widget_t *) self: self reference
+** (gxfw_widget_t *) other: The widget to compare for containment
+** Returns : (int) 1 if self is superarea_of other, 0 otherwise
+**
+**
+** -- set_visual(gfxw_widget_t *self)
+** Sets the visual for the widget
+** Parameters: (gfxw_widget_t *) self: self reference
+** Returns : (int) 0
+** This function is called by container->add() and need not be invoked explicitly.
+** It also makes sure that dirty rectangles are passed to parent containers.
+**
+**
+**
+** **************************
+** ** Container operations **
+** **************************
+**
+**
+** -- free_tagged(gfxw_container_t *self)
+** Frees all tagged resources in the container
+** Parameters: (gfxw_container_t *) self: self reference
+** Returns : (int) 0
+** The container itself is never freed in this way.
+**
+**
+** -- free_contents(gfxw_container_t *self)
+** Frees all resources contained in the container
+** Parameters: (gfxw_container_t *) self: self reference
+** Returns : (int) 0
+**
+**
+** -- add_dirty_abs(gfxw_container_t *self, rect_t dirty, int propagate)
+** Adds a dirty rectangle to the container's list of dirty rects
+** Parameters: (gfxw_container_t *) self: self reference
+** (rect_t) dirty: The rectangular screen area that is to be flagged
+** as dirty, absolute to the screen
+** (int) propagate: Whether the dirty rect should be propagated to the
+** widget's parents
+** Returns : (int) 0
+** Transparent containers will usually pass this value to their next ancestor,
+** because areas below them might have to be redrawn.
+** The dirty rectangle management strategy is defined in this file in
+** GFXW_DIRTY_STRATEGY.
+**
+**
+** -- add_dirty_rel(gfxw_container_t *self, rect_t dirty, int propagate)
+** Adds a dirty rectangle to the container's list of dirty rects
+** Parameters: (gfxw_container_t *) self: self reference
+** (rect_t) dirty: The rectangular screen area that is to be flagged
+** as dirty, relative to the widget
+** (int) propagate: Whether the dirty rect should be propagated to the
+** widget's parents
+** Returns : (int) 0
+** Transparent containers will usually pass this value to their next ancestor,
+** because areas below them might have to be redrawn.
+** The dirty rectangle management strategy is defined in this file in
+** GFXW_DIRTY_STRATEGY.
+**
+**
+** -- add(gfxw_container_t *self, gfxw_widget_t *widget)
+** Adds a widget to the list of contained widgets
+** Parameters: (gfxw_container_t *) self: self reference
+** (gfxw_widget_t *) widget: The widget to add
+** Returns : (int) 0
+** Sorted lists sort their content into the list rather than adding it to the
+** end.
+*/
+
+
+/***************************/
+/* Basic widget generation */
+/***************************/
+
+/*-- Primitive types --*/
+
+gfxw_box_t *
+gfxw_new_box(gfx_state_t *state, rect_t area, gfx_color_t color1, gfx_color_t color2, gfx_box_shade_t shade_type);
+/* Creates a new box
+** Parameters: (gfx_state_t *) state: The (optional) state
+** (rect_t) area: The box's dimensions, relative to its container widget
+** (gfx_color_t) color1: The primary color
+** (gfx_color_t) color1: The secondary color (ignored if shading is disabled)
+** (gfx_box_shade_t) shade_type: The shade type for the box
+** Returns : (gfxw_box_t *) The resulting box widget
+** The graphics state- if non-NULL- is used here for some optimizations.
+*/
+
+gfxw_primitive_t *
+gfxw_new_rect(rect_t rect, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style);
+/* Creates a new rectangle
+** Parameters: (rect_t) rect: The rectangle area
+** (gfx_color_t) color: The rectangle's color
+** (gfx_line_mode_t) line_mode: The line mode for the lines that make up the rectangle
+** (gfx_line_style_t) line_style: The rectangle's lines' style
+** Returns : (gfxw_primitive_t *) The newly allocated rectangle widget (a Primitive)
+*/
+
+gfxw_primitive_t *
+gfxw_new_line(point_t start, point_t end, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style);
+/* Creates a new line
+** Parameters: (point_t * point_t) (start, line): The line origin and end point
+** (gfx_color_t) color: The line's color
+** (gfx_line_mode_t) line_mode: The line mode to use for drawing
+** (gfx_line_style_t) line_style: The line style
+** Returns : (gfxw_primitive_t *) The newly allocated line widget (a Primitive)
+*/
+
+
+/* Whether the view should be static */
+#define GFXW_VIEW_FLAG_STATIC (1 << 0)
+
+/* Whether the view should _not_ apply its x/y offset modifyers */
+#define GFXW_VIEW_FLAG_DONT_MODIFY_OFFSET (1 << 1)
+
+gfxw_view_t *
+gfxw_new_view(gfx_state_t *state, point_t pos, int view, int loop, int cel, int palette, int priority, int control,
+ gfx_alignment_t halign, gfx_alignment_t valign, int flags);
+/* Creates a new view (a cel, actually)
+** Parameters: (gfx_state_t *) state: The graphics state
+** (point_t) pos: The position to place the view at
+** (int x int x int) view, loop, cel: The global cel ID
+** (int) priority: The priority to use for drawing, or -1 for none
+** (int) control: The value to write to the control map, or -1 for none
+** (gfx_alignment_t x gfx_alignment_t) halign, valign: Horizontal and vertical
+** cel alignment
+** (int) flags: Any combination of GFXW_VIEW_FLAGs
+** Returns : (gfxw_cel_t *) A newly allocated cel according to the specs
+*/
+
+gfxw_dyn_view_t *
+gfxw_new_dyn_view(gfx_state_t *state, point_t pos, int z, int view, int loop, int cel, int palette,
+ int priority, int control, gfx_alignment_t halign, gfx_alignment_t valign,
+ int sequence);
+/* Creates a new dyn view
+** Parameters: (gfx_state_t *) state: The graphics state
+** (point_t) pos: The position to place the dynamic view at
+** (int) z: The z coordinate
+** (int x int x int) view, loop, cel: The global cel ID
+** (int) priority: The priority to use for drawing, or -1 for none
+** (int) control: The value to write to the control map, or -1 for none
+** (gfx_alignment_t x gfx_alignment_t) halign, valign: Horizontal and vertical
+** cel alignment
+** (int) sequence: Sequence number: When sorting dynviews, this number is
+** considered last for sorting (ascending order)
+** Returns : (gfxw_cel_t *) A newly allocated cel according to the specs
+** Dynamic views are non-pic views with a unique global identifyer. This allows for drawing
+** optimizations when they move or change shape.
+*/
+
+gfxw_text_t *
+gfxw_new_text(gfx_state_t *state, rect_t area, int font, const char *text, gfx_alignment_t halign,
+ gfx_alignment_t valign, gfx_color_t color1, gfx_color_t color2,
+ gfx_color_t bgcolor, int flags);
+/* Creates a new text widget
+** Parameters: (gfx_state_t *) state: The state the text is to be calculated from
+** (rect_t) area: The area the text is to be confined to (the yl value is only
+** relevant for text aligment, though)
+** (int) font: The number of the font to use
+** (gfx_alignment_t x gfx_alignment_t) halign, valign: Horizontal and
+** vertical text alignment
+** (gfx_color_t x gfx_color_t) color1, color2: Text foreground colors (if not equal,
+** The foreground is dithered between them)
+** (gfx_color_t) bgcolor: Text background color
+** (int) flags: GFXR_FONT_FLAGs, orred together (see gfx_resource.h)
+** Returns : (gfxw_text_t *) The resulting text widget
+*/
+
+void
+gfxw_text_info(gfx_state_t *state, gfxw_text_t *text, int *lines_nr,
+ int *lineheight, int *offset);
+/* Determines text widget meta-information
+** Parameters: (gfx_state_t *) state: The state to operate on
+** (gfx_text_t *) text: The widget to query
+** Returns : (int) lines_nr: Number of lines used in the text
+** (int) lineheight: Pixel height (SCI scale) of each text line
+** (int) offset: Pixel offset (SCI scale) of the space after the
+** last character in the last line
+*/
+
+gfxw_widget_t *
+gfxw_set_id(gfxw_widget_t *widget, int ID, int subID);
+/* Sets a widget's ID
+** Parmaeters: (gfxw_widget_t *) widget: The widget whose ID should be set
+** (int x int) ID, subID: The ID to set
+** Returns : (gfxw_widget_t *) widget
+** A widget ID is unique within the container it is stored in, if and only if it was
+** added to that container with gfxw_add().
+** This function handles widget = NULL gracefully (by doing nothing and returning NULL).
+*/
+
+gfxw_widget_t *
+gfxw_remove_id(gfxw_container_t *container, int ID, int subID);
+/* Finds a widget with a specific ID in a container and removes it from there
+** Parameters: (gfxw_container_t *) container: The container to search in
+** (int) ID: The ID to look for
+** (int) subID: The subID to look for, or GFXW_NO_ID for any
+** Returns : (gfxw_widget_t *) The resulting widget or NULL if no match was found
+** Search is non-recursive; widgets with IDs hidden in subcontainers will not be found.
+*/
+
+
+gfxw_dyn_view_t *
+gfxw_dyn_view_set_params(gfxw_dyn_view_t *widget, int under_bits, void *under_bitsp, int signal, void *signalp);
+/* Initializes a dyn view's interpreter attributes
+** Parameters: (gfxw_dyn_view_t *) widget: The widget affected
+** (int x void * x int x void *) under_bits, inder_bitsp, signal, signalp: Interpreter-dependant data
+** Returns : (gfxw_dyn_view_t *) widget
+*/
+
+gfxw_widget_t *
+gfxw_hide_widget(gfxw_widget_t *widget);
+/* Makes a widget invisible without removing it from the list of widgets
+** Parameters: (gfxw_widget_t *) widget: The widget to invisibilize
+** Returns : (gfxw_widget_t *) widget
+** Has no effect on invisible widgets
+*/
+
+gfxw_widget_t *
+gfxw_show_widget(gfxw_widget_t *widget);
+/* Makes an invisible widget reappear
+** Parameters: (gfxw_widget_t *) widget: The widget to show again
+** Returns : (gfxw_widget_t *) widget
+** Does not affect visible widgets
+*/
+
+gfxw_widget_t *
+gfxw_abandon_widget(gfxw_widget_t *widget);
+/* Marks a widget as "abandoned"
+** Parameters: (gfxw_widget_t *) widget: The widget to abandon
+** Returns : (gfxw_widget_t *) widget
+*/
+
+/*-- Container types --*/
+
+#define GFXW_LIST_UNSORTED 0
+#define GFXW_LIST_SORTED 1
+
+gfxw_list_t *
+gfxw_new_list(rect_t area, int sorted);
+/* Creates a new list widget
+** Parameters: (rect_t) area: The area covered by the list (absolute position)
+** (int) sorted: Whether the list should be a sorted list
+** Returns : (gfxw_list_t *) A newly allocated list widget
+** List widgets are also referred to as Display Lists.
+*/
+
+gfxw_visual_t *
+gfxw_new_visual(gfx_state_t *state, int font);
+/* Creates a new visual widget
+** Parameters: (gfx_state_t *) state: The graphics state
+** (int) font: The default font number for contained ports
+** Returns : (gfxw_list_t *) A newly allocated visual widget
+** Visual widgets are containers for port widgets.
+*/
+
+
+gfxw_port_t *
+gfxw_new_port(gfxw_visual_t *visual, gfxw_port_t *predecessor, rect_t area, gfx_color_t fgcolor, gfx_color_t bgcolor);
+/* Creates a new port widget with the default settings
+** Paramaters: (gfxw_visual_t *) visual: The visual the port is added to
+** (gfxw_port_t *) predecessor: The port's predecessor
+** (rect_t) area: The screen area covered by the port (absolute position)
+** (gfx_color_t) fgcolor: Foreground drawing color
+** (gfx_color_t) bgcolor: Background color
+** Returns : (gfxw_port_t *) A newly allocated port widget
+** A port differentiates itself from a list in that it contains additional information,
+** and an optional title (stored in a display list).
+** Ports are assigned implicit IDs identifying their position within the port stack.
+*/
+
+gfxw_port_t *
+gfxw_find_port(gfxw_visual_t *visual, int ID);
+/* Retrieves a port with the specified ID
+** Parameters: (gfxw_visual_t *) visual: The visual the port is to be retreived from
+** (int) ID: The port's ID
+** Returns : (gfxw_port_t *) The requested port, or NULL if it didn't exist
+** This function is O(1).
+*/
+
+gfxw_port_t *
+gfxw_find_default_port(gfxw_visual_t *visual);
+/* Retreives the default port from a visual
+** Parameters: (gfxw_visual_t *) visual: The visual the port should be retreived from
+** Returns : (gfxw_port_t *) The default port, or NULL if no port is present
+** The 'default port' is the last port to be instantiated; usually the topmost
+** or highest-ranking port.
+*/
+
+void
+gfxw_port_set_auto_restore(gfxw_visual_t *visual, gfxw_port_t *window, rect_t auto_rect);
+/* Sets rectangle to be restored upon port removal
+** Parameters: (state_t *) s: The state to operate on
+ (gfxw_port_t *) window: The affected window
+** (rect_t) auto_rect: The area to restore
+** Returns : (void)
+*/
+
+gfxw_port_t *
+gfxw_remove_port(gfxw_visual_t *visual, gfxw_port_t *port);
+/* Removes a port from a visual
+** Parameters: (gfxw_visual_t *) visual: The visual the port should be removed from
+** (gfxw_port_t *) port: The port to remove
+** Returns : (gfxw_port_t *) port's parent port, or NULL if it had none
+*/
+
+void
+gfxw_remove_widget_from_container(gfxw_container_t *container, gfxw_widget_t *widget);
+/* Removes the widget from the specified port
+** Parameters: (gfxw_container_t *) container: The container it should be removed from
+** (gfxw_widget_t *) widget: The widget to remove
+** Returns : (void)
+*/
+
+gfxw_snapshot_t *
+gfxw_make_snapshot(gfxw_visual_t *visual, rect_t area);
+/* Makes a "snapshot" of a visual
+** Parameters: (gfxw_visual_t *) visual: The visual a snapshot is to be taken of
+** (rect_t) area: The area a snapshot should be taken of
+** Returns : (gfxw_snapshot_t *) The resulting, newly allocated snapshot
+** It's not really a full qualified snaphot, though. See gfxw_restore_snapshot
+** for a full discussion.
+** This operation also increases the global serial number counter by one.
+*/
+
+int
+gfxw_widget_matches_snapshot(gfxw_snapshot_t *snapshot, gfxw_widget_t *widget);
+/* Predicate to test whether a widget would be destroyed by applying a snapshot
+** Parameters: (gfxw_snapshot_t *) snapshot: The snapshot to test against
+** (gfxw_widget_t *) widget: The widget to test
+** Retunrrs : (int) An appropriate boolean value
+*/
+
+gfxw_snapshot_t *
+gfxw_restore_snapshot(gfxw_visual_t *visual, gfxw_snapshot_t *snapshot);
+/* Restores a snapshot to a visual
+** Parameters: (gfxw_visual_t *) visual: The visual to operate on
+** (gfxw_snapshot_t *) snapshot: The snapshot to restore
+** Returns : (gfxw_snapshot_t *) snapshot (still needs to be freed)
+** The snapshot is not really restored; only more recent widgets touching
+** the snapshotted area are destroyed.
+*/
+
+void
+gfxw_annihilate(gfxw_widget_t *widget);
+/* As widget->widfree(widget), but destroys all overlapping widgets
+** Parameters: (gfxw_widget_t *) widget: The widget to use
+** Returns : (void)
+** This operation calls widget->widfree(widget), but it also destroys
+** all widgets with a higher or equal priority drawn after this widget.
+*/
+
+gfxw_dyn_view_t *
+gfxw_picviewize_dynview(gfxw_dyn_view_t *dynview);
+/* Turns a dynview into a picview
+** Parameters: (gfxw_dyn_view_t *) dynview: The victim
+** Returns : (gfxw_dyn_view_t *) The victim, after his transformation
+** The only changes are in function and type variables, actually.
+*/
+
+void
+gfxw_port_auto_restore_background(gfxw_visual_t *visual, gfxw_port_t *window, rect_t auto_rect);
+/* Tags a window widget as automatically restoring the visual background upon removal
+** Parameters: (gfx_visual_t *) visual: The base visual
+** (gfxw_port_t *) window: The window to tag
+** (rect_t) auto_rect: The background to remember
+** Also records the specified background rectangle, for later recovery
+*/
+
+
+gfxw_port_t *
+gfxw_get_chrono_port(gfxw_visual_t *visual, gfxw_list_t **temp_widgets_list, int flags);
+
+void
+gfxw_add_to_chrono(gfxw_visual_t *visual, gfxw_widget_t *widget);
+
+void
+gfxw_widget_reparent_chrono(gfxw_visual_t *visual, gfxw_widget_t *view, gfxw_list_t *target);
+
+void
+gfxw_widget_kill_chrono(gfxw_visual_t *visual, int window);
+
+#endif /* !_GFX_WIDGETS_H_ */
diff --git a/engines/sci/include/hashmap.h b/engines/sci/include/hashmap.h
new file mode 100644
index 0000000000..f9130c4493
--- /dev/null
+++ b/engines/sci/include/hashmap.h
@@ -0,0 +1,132 @@
+/***************************************************************************
+ hashmap.h Copyright (C) 2001 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+/* Defines a hash map that maps values to small integers.
+** Preprocessor parameters:
+** TYPE: The type to hash
+** HASH_MAX: Maximum hash value
+** HASH(x): Hashes a value of type TYPE to an int from 0 to HASH_MAX
+** COMP(x, y): Compares x, y, returns zero(!) iff they are equal
+** MUST_FREE: Define if 'lost' values are simple pointers and should be freed
+** DUPLICATOR: Usually needed when MUST_FREE is being used, means that
+** new values must be dup'd before being added.
+** Define it to the name of the function to use for duplication
+** (e.g. '#define DUPLICATOR strdup').
+*/
+
+ /**-- WARNING!!! --**/
+
+/* This file uses a lot of dark magic (aka preprocessor macros) to define
+** its semantics. It is not to be taken lightly. It is not to be taken
+** as an example for good programming. Most importantly, it is not to
+** be read by mere mortals, except for the author and other people who
+** have undergone appropriate psychological preparation. Keep out of
+** reach of small children. Do not shake. Do not put in a microwave. Do
+** not feed to animals.
+*/
+
+/* OK, it's not that bad. */
+
+
+#ifndef HASH_MAX
+# error "Must define the maximum hash value (HASH_MAX) before including hashmap.h!"
+#endif
+
+#ifndef HASH
+# error "Must define the hash function (HASH) before including hashmap.h!"
+#endif
+
+#ifndef COMP
+# error "Must define a comparison function (COMP) before including hashmap.h!"
+#endif
+
+
+#define DECLARE_STRUCTS(TYPE) \
+typedef struct _##TYPE##_hash_map_node { \
+ TYPE name; \
+ int value; \
+ struct _##TYPE##_hash_map_node *next; \
+} TYPE##_hash_map_node_t; \
+ \
+ \
+typedef struct { \
+ int base_value; /* Starts at zero, counts upwards */ \
+ TYPE##_hash_map_node_t *nodes[HASH_MAX+1]; \
+ TYPE##_hash_map_node_t *holes; /* List of freed entries to minimize \
+ ** memory operations and modifications \
+ ** to base_value */ \
+} TYPE##_hash_map_t, *TYPE##_hash_map_ptr;
+
+
+#define DECLARE_FUNCTIONS(TYPE) \
+ \
+TYPE##_hash_map_t * \
+new_##TYPE##_hash_map(void); \
+/* Creates a new hash map for the specified TYPE \
+** Parameters: (void) \
+** Returns : (TYPE##_hash_map_t *) The newly allocated hash map \
+*/ \
+ \
+void \
+free_##TYPE##_hash_map(TYPE##_hash_map_ptr map); \
+/* Frees the specified hash map \
+** Parameters: (TYPE##_hash_map_t *) map: The map to free \
+** Returns : (void) \
+*/ \
+ \
+void \
+apply_to_##TYPE##_hash_map(TYPE##_hash_map_ptr map, void *param, void (*note) (void *param, TYPE name, int value)); \
+/* Iterates over all entries in the hash map and invokes 'note' \
+** Parameters: (TYPE##_hash_map_t *) map: The map to iterate over \
+** (void *) param: Some parameter to pass to 'note' \
+** ((voidptr * TYPE * value) -> void) note: The callback to invoke for each entry \
+*/ \
+ \
+int \
+TYPE##_hash_map_check_value(TYPE##_hash_map_ptr map, TYPE value, char add, char *was_added); \
+/* Checks whether a value is in the map, adds it if neccessary \
+** Parameters: (TYPE##_hash_map_t *) map: The map to look in/modify \
+** (TYPE) value: The value to check for/add \
+** (char) add: Whether to add the value if it's not in there \
+** (char *) was_added: Set to non-zero iff the value is new \
+** Ignored if NULL. \
+** Returns : (int) The new (or old) index, or -1 if add was zero and \
+** the value couldn't be found \
+** If MUST_FREE is defined and add is set but the value was already in \
+** there, the value is freed. \
+*/ \
+ \
+int \
+TYPE##_hash_map_remove_value(TYPE##_hash_map_ptr map, TYPE value); \
+/* Removes a value from the hash map \
+** Parameters: (TYPE##_hash_map_t *) map: The map to remove from \
+** (TYPE) value: The value to remove \
+** Returns : (int) The ID of the value, or -1 if it wasn't presen \
+*/
+
+
+
+
diff --git a/engines/sci/include/heapmgr.h b/engines/sci/include/heapmgr.h
new file mode 100644
index 0000000000..77583e1f39
--- /dev/null
+++ b/engines/sci/include/heapmgr.h
@@ -0,0 +1,120 @@
+/***************************************************************************
+ heapmgr.h Copyright (C) 2002 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+/* Heap-like managed structure */
+
+#ifndef _FREESCI_HEAPMGR_H_
+#define _FREESCI_HEAPMGR_H_
+
+#include <resource.h>
+#include <sci_memory.h>
+
+#define HEAPENTRY_INVALID -1
+
+#define ENTRY_IS_VALID(t, i) ((i) >= 0 && (i) < (t)->max_entry && (t)->table[(i)].next_free == (i))
+
+#define DECLARE_HEAPENTRY(ENTRY) \
+typedef struct { \
+ int next_free; /* Only used for free entries */ \
+ ENTRY##_t entry; \
+} ENTRY##_entry_t; \
+ \
+typedef struct { \
+ int entries_nr; /* Number of entries allocated */ \
+ int first_free; /* Beginning of a singly linked list for entries */ \
+ int entries_used; /* Statistical information */ \
+ int max_entry; /* Highest entry used */ \
+ ENTRY##_entry_t *table; \
+} ENTRY##_table_t; \
+ \
+void \
+init_##ENTRY##_table(ENTRY##_table_t *table); \
+int \
+alloc_##ENTRY##_entry(ENTRY##_table_t *table); \
+void \
+free_##ENTRY##_entry(ENTRY##_table_t *table, int index);
+
+
+
+#define DEFINE_HEAPENTRY_WITH_CLEANUP(ENTRY, INITIAL, INCREMENT, CLEANUP_FN) \
+void \
+init_##ENTRY##_table(ENTRY##_table_t *table) \
+{ \
+ table->entries_nr = INITIAL; \
+ table->max_entry = 0; \
+ table->entries_used = 0; \
+ table->first_free = HEAPENTRY_INVALID; \
+ table->table = (ENTRY##_entry_t*)sci_malloc(sizeof(ENTRY##_entry_t) * INITIAL);\
+ memset(table->table, 0, sizeof(ENTRY##_entry_t) * INITIAL); \
+} \
+ \
+void \
+free_##ENTRY##_entry(ENTRY##_table_t *table, int index) \
+{ \
+ ENTRY##_entry_t *e = table->table + index; \
+ \
+ if (index < 0 || index >= table->max_entry) { \
+ fprintf(stderr, "heapmgr: Attempt to release" \
+ " invalid table index %d!\n", index); \
+ BREAKPOINT(); \
+ } \
+ CLEANUP_FN(&(e->entry)); \
+ \
+ e->next_free = table->first_free; \
+ table->first_free = index; \
+ table->entries_used--; \
+} \
+ \
+int \
+alloc_##ENTRY##_entry(ENTRY##_table_t *table) \
+{ \
+ table->entries_used++; \
+ if (table->first_free != HEAPENTRY_INVALID) { \
+ int oldff = table->first_free; \
+ table->first_free = table->table[oldff].next_free; \
+ \
+ table->table[oldff].next_free = oldff; \
+ return oldff; \
+ } else { \
+ if (table->max_entry == table->entries_nr) { \
+ table->entries_nr += INCREMENT; \
+ \
+ table->table = (ENTRY##_entry_t*)sci_realloc(table->table,\
+ sizeof(ENTRY##_entry_t) \
+ * table->entries_nr); \
+ memset(&table->table[table->entries_nr-INCREMENT], \
+ 0, INCREMENT*sizeof(ENTRY##_entry_t)); \
+ } \
+ table->table[table->max_entry].next_free = \
+ table->max_entry; /* Tag as 'valid' */ \
+ return table->max_entry++; \
+ } \
+}
+
+#define _HEAPENTRY_IGNORE_ME(x)
+#define DEFINE_HEAPENTRY(e, i, p) DEFINE_HEAPENTRY_WITH_CLEANUP(e, i, p, _HEAPENTRY_IGNORE_ME)
+
+#endif /* !_FREESCI_HEAPMGR_H_ */
diff --git a/engines/sci/include/int_hashmap.h b/engines/sci/include/int_hashmap.h
new file mode 100644
index 0000000000..12630b6198
--- /dev/null
+++ b/engines/sci/include/int_hashmap.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ int_hashmap.h Copyright (C) 2001 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef _INT_HASHMAP_H_
+#define _INT_HASHMAP_H_
+
+/* Assumes that the ints are relatively evenly distributed */
+
+#define DCS_INT_HASH_MAX 255
+
+#define HASH_MAX DCS_INT_HASH_MAX
+#define COMP(x, y) ((x)-(y))
+#define HASH(x) (x & 0xff)
+#undef MUST_FREE
+
+#include "hashmap.h"
+DECLARE_STRUCTS(int)
+DECLARE_FUNCTIONS(int)
+
+#ifndef BUILD_MAP_FUNCTIONS
+# undef HASH_MAX
+# undef COMP
+# undef HASH
+#endif
+
+/* see hashmap.h for descriptions of these functions */
+int_hash_map_ptr
+new_int_hash_map(void);
+
+void
+free_int_hash_map(int_hash_map_ptr);
+
+int
+int_hash_map_check_value(int_hash_map_ptr, int value, char add_p, char *added);
+
+int
+int_hash_map_remove_value(int_hash_map_ptr, int value);
+
+#endif /* _INT_HASHMAP_H_ */
diff --git a/engines/sci/include/kdebug.h b/engines/sci/include/kdebug.h
new file mode 100644
index 0000000000..9c69126e41
--- /dev/null
+++ b/engines/sci/include/kdebug.h
@@ -0,0 +1,121 @@
+/***************************************************************************
+ kdebug.h Copyright (C) 1999,2000,01 Christoph Reichenbach, TU Darmstadt
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CJR) [jameson@linuxgames.com]
+
+***************************************************************************/
+/* Kernel debug defines */
+
+#ifndef _SCI_KDEBUG_H_
+#define _SCI_KDEBUG_H_
+
+struct _state;
+#define SCIk_DEBUG_MODES 18
+
+#define SCIkERROR_NR -2
+#define SCIkWARNING_NR -1
+#define SCIkSTUB_NR 0
+#define SCIkFUNCCHK_NR 5
+#define SCIkSOUNDCHK_NR 7
+#define SCIkGFXDRIVER_NR 8
+#define SCIkBASESETTER_NR 9
+#define SCIkPARSER_NR 10
+#define SCIkAVOIDPATH_NR 17
+
+#define SCIkERROR s, __FILE__, __LINE__, SCIkERROR_NR
+#define SCIkWARNING s, __FILE__, __LINE__, SCIkWARNING_NR
+#define SCIkSTUB s, __FILE__, __LINE__, SCIkSTUB_NR
+#define SCIkNODES s, __FILE__, __LINE__, 1
+#define SCIkGRAPHICS s, __FILE__, __LINE__, 2
+#define SCIkSTRINGS s, __FILE__, __LINE__, 3
+#define SCIkMEM s, __FILE__, __LINE__, 4
+#define SCIkFUNCCHK s, __FILE__, __LINE__, SCIkFUNCCHK_NR
+#define SCIkBRESEN s, __FILE__, __LINE__, 6
+#define SCIkSOUND s, __FILE__, __LINE__, SCIkSOUNDCHK_NR
+#define SCIkGFXDRIVER s, __FILE__, __LINE__, SCIkGFXDRIVER_NR
+#define SCIkBASESETTER s, __FILE__, __LINE__, SCIkBASESETTER_NR
+#define SCIkPARSER s, __FILE__, __LINE__, SCIkPARSER_NR
+#define SCIkMENU s, __FILE__, __LINE__, 11
+#define SCIkSAID s, __FILE__, __LINE__, 12
+#define SCIkFILE s, __FILE__, __LINE__, 13
+#define SCIkTIME s, __FILE__, __LINE__, 14
+#define SCIkROOM s, __FILE__, __LINE__, 15
+#define SCIkEMU s, __FILE__, __LINE__, 16
+#define SCIkAVOIDPATH s, __FILE__, __LINE__, SCIkAVOIDPATH_NR
+
+#define SCI_KERNEL_DEBUG
+
+#ifdef SCI_KERNEL_DEBUG
+
+#ifdef __GNUC__
+
+#define SCIkdebug(arguments...) _SCIGNUkdebug(__PRETTY_FUNCTION__, ## arguments)
+
+#else /* !__GNUC__ */
+
+#define SCIkdebug _SCIkdebug
+
+#endif /* !__GNUC__ */
+
+#else /* !SCI_KERNEL_DEBUG */
+
+#define SCIkdebug 1? (void)0 : _SCIkdebug
+
+#endif /* !SCI_KERNEL_DEBUG */
+
+
+
+#ifdef __GNUC__
+
+#define SCIkwarn(arguments...) _SCIGNUkdebug(__PRETTY_FUNCTION__, ## arguments)
+
+#else /* !__GNUC__ */
+
+#define SCIkwarn _SCIkwarn
+
+#endif /* !__GNUC__ */
+
+/* Internal functions */
+void
+_SCIkwarn(struct _state *s, const char *file, int line, int area, const char *format, ...);
+void
+_SCIkdebug(struct _state *s, const char *file, int line, int area, const char *format, ...);
+void
+_SCIGNUkdebug(const char *funcname, struct _state *s, const char *file, int line, int area, const char *format, ...);
+
+/* If mode=1, enables debugging for specified areas. If mode=0, disables
+** debugging for specified areas.
+** Valid area characters: ulgcmfbad
+*/
+
+void
+set_debug_mode (struct _state *s, int mode, const char *areas);
+
+extern int sci_debug_flags;
+
+/* Debug flags */
+#define _DEBUG_FLAG_LOGGING 1 /* Log each command executed */
+#define _DEBUG_FLAG_BREAK_ON_WARNINGS 2 /* Break on warnings */
+
+
+#endif
diff --git a/engines/sci/include/kernel.h b/engines/sci/include/kernel.h
new file mode 100644
index 0000000000..3b675dac65
--- /dev/null
+++ b/engines/sci/include/kernel.h
@@ -0,0 +1,403 @@
+/***************************************************************************
+ kernel.h Copyright (C) 1999..2002 Christoph Reichenbach
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CJR) [jameson@linuxgames.com]
+
+***************************************************************************/
+
+#ifndef _SCI_KERNEL_H_
+#define _SCI_KERNEL_H_
+
+#include <math.h>
+#include <ctype.h>
+#include <kdebug.h>
+#include <uinput.h>
+#include <event.h>
+#include <console.h> /* sciprintf() */
+
+#ifdef HAVE_FNMATCH_H
+#include <fnmatch.h>
+#endif /* HAVE_FNMATCH_H */
+
+#ifdef _MSC_VER
+# include <direct.h>
+# include <ctype.h>
+#endif
+
+#ifndef PI
+# define PI 3.14159265358979323846
+#endif /* !PI */
+
+extern int _kdebug_cheap_event_hack;
+extern int _kdebug_cheap_soundcue_hack;
+extern int stop_on_event;
+
+extern DLLEXTERN int _debug_seeking;
+extern DLLEXTERN int _debug_step_running;
+
+#define AVOIDPATH_DYNMEM_STRING "AvoidPath polyline"
+
+
+typedef struct {
+ int x, y, xend, yend;
+} abs_rect_t;
+
+/* Formerly, the heap macros were here; they have been deprecated, however. */
+
+/******************** Selector functionality ********************/
+
+#define GET_SEL32(_o_, _slc_) read_selector(s, _o_, s->selector_map._slc_, __FILE__, __LINE__)
+#define GET_SEL32V(_o_, _slc_) (GET_SEL32(_o_, _slc_).offset)
+#define GET_SEL32SV(_o_, _slc_) ((gint16)(GET_SEL32(_o_, _slc_).offset))
+/* Retrieves a selector from an object
+** Parameters: (reg_t) object: The address of the object which the selector should be read from
+** (selector_name) selector: The selector to read
+** Returns : (gint16/guint16/reg_t) The selector value
+** This macro halts on error. 'selector' must be a selector name registered in vm.h's
+** selector_map_t and mapped in script.c.
+*/
+
+#define PUT_SEL32(_o_, _slc_, _val_) write_selector(s, _o_, s->selector_map._slc_, _val_, __FILE__, __LINE__)
+#define PUT_SEL32V(_o_, _slc_, _val_) write_selector(s, _o_, s->selector_map._slc_, make_reg(0, _val_), __FILE__, __LINE__)
+/* Writes a selector value to an object
+** Parameters: (reg_t) object: The address of the object which the selector should be written to
+** (selector_name) selector: The selector to read
+** (gint16) value: The value to write
+** Returns : (void)
+** This macro halts on error. 'selector' must be a selector name registered in vm.h's
+** selector_map_t and mapped in script.c.
+*/
+
+
+#define INV_SEL(_object_, _selector_, _noinvalid_) \
+ s, _object_, s->selector_map._selector_, _noinvalid_, funct_nr, argv, argc, __FILE__, __LINE__
+/* Kludge for use with invoke_selector(). Used for compatibility with compilers that can't
+** handle vararg macros.
+*/
+
+
+reg_t
+read_selector(struct _state *s, reg_t object, selector_t selector_id, const char *fname, int line);
+void
+write_selector(struct _state *s, reg_t object, selector_t selector_id, reg_t value,
+ const char *fname, int line);
+int
+invoke_selector(struct _state *s, reg_t object, int selector_id, int noinvalid, int kfunct,
+ stack_ptr_t k_argp, int k_argc, const char *fname, int line, int argc, ...);
+
+
+
+
+/******************** Text functionality ********************/
+char *
+kernel_lookup_text(struct _state *s, reg_t address, int index);
+/* Looks up text referenced by scripts
+** Parameters: (state_t *s): The current state
+** (reg_t) address: The address to look up
+** (int) index: The relative index
+** Returns : (char *): The referenced text, or NULL on error.
+** SCI uses two values to reference to text: An address, and an index. The address
+** determines whether the text should be read from a resource file, or from the heap,
+** while the index either refers to the number of the string in the specified source,
+** or to a relative position inside the text.
+*/
+
+
+
+/******************** Debug functionality ********************/
+#define KERNEL_OOPS(reason) kernel_oops(s, __FILE__, __LINE__, reason)
+
+/* Non-fatal assertion */
+#define SCIkASSERT(a) if (!(a)) { \
+ SCIkwarn(SCIkERROR, "Assertion " #a " failed in " __FILE__ " line %d\n", __LINE__); \
+ return; \
+}
+
+#ifdef SCI_KERNEL_DEBUG
+
+#define CHECK_THIS_KERNEL_FUNCTION if (s->debug_mode & (1 << SCIkFUNCCHK_NR)) {\
+ int i;\
+ sciprintf("Kernel CHECK: %s[%x](", s->kernel_names[funct_nr], funct_nr); \
+ for (i = 0; i < argc; i++) { \
+ sciprintf("%04x", 0xffff & UKPV(i)); \
+ if (i+1 < argc) sciprintf(", "); \
+ } \
+ sciprintf(")\n"); \
+} \
+
+#else /* !SCI_KERNEL_DEBUG */
+
+#define CHECK_THIS_KERNEL_FUNCTION
+
+#endif /* !SCI_KERNEL_DEBUG */
+
+
+int
+listp(struct _state *s, reg_t address);
+/* Determines whether the object at <address> is a list
+** Parameters: (state_t *) s: The state to use
+** (reg_t) address: The address to check
+** Returns : (int) 0 if not, non-zero if it is a list.
+*/
+
+int
+is_object(struct _state *s, reg_t obj);
+/* Checks whether a heap address contains an object
+** Parameters: (state_t *) s: The current state
+** (reg_t) obj: The address to check
+** Returns : (int) 1 if it is an object, 0 otherwise
+*/
+
+
+/* Functions for internal macro use */
+void
+_SCIkvprintf(FILE *file, const char *format, va_list args);
+void
+_SCIkprintf(FILE *file, const char *format, ...);
+
+
+
+
+
+/******************** Kernel function parameter macros ********************/
+
+/* Returns the parameter value or (alt) if not enough parameters were supplied */
+
+
+#define KP_ALT(x, alt) ((x < argc)? argv[x] : (alt))
+#define KP_UINT(x) ((guint16) x.offset)
+#define KP_SINT(x) ((gint16) x.offset)
+
+
+#define SKPV(x) KP_SINT(argv[x])
+#define UKPV(x) KP_UINT(argv[x])
+#define SKPV_OR_ALT(x,a) KP_SINT(KP_ALT(x, make_reg(0, a)))
+#define UKPV_OR_ALT(x,a) KP_UINT(KP_ALT(x, make_reg(0, a)))
+
+reg_t *
+kernel_dereference_reg_pointer(struct _state *s, reg_t pointer, int entries);
+byte *
+kernel_dereference_bulk_pointer(struct _state *s, reg_t pointer, int entries);
+#define kernel_dereference_char_pointer(state, pointer, entries) (char*)kernel_dereference_bulk_pointer(state, pointer, entries)
+/* Dereferences a heap pointer
+** Parameters: (state_t *) s: The state to operate on
+** (reg_t ) pointer: The pointer to dereference
+** (int) entries: The number of values expected (for checking)
+** (use 0 for strings)
+** Returns : (reg_t/char *): A physical reference to the address pointed
+** to, or NULL on error or if not enugh entries
+** were available
+** reg_t dereferenciation also assures alignedness of data.
+*/
+
+/******************** Resource Macros ********************/
+
+/* Returns the composite resource ID: */
+#define RESOURCE_ID(type, number) (number) | ((type) << 11)
+#define RESOURCE_NUMBER(resid) ((resid) & 0x7ff)
+#define RESOURCE_TYPE(resid) ((resid) >> 11)
+
+
+
+
+
+int
+kernel_oops(struct _state *s, const char *file, int line, const char *reason);
+/* Halts script execution and informs the user about an internal kernel error or failed assertion
+** Paramters: (state_t *) s: The state to use
+** (const char *) file: The file the oops occured in
+** (int) line: The line the oops occured in
+** (const char *) reason: Reason for the kernel oops
+*/
+
+
+
+
+/******************** Priority macros/functions ********************/
+
+struct _state;
+
+extern int sci01_priority_table_flags; /* 1: delete, 2: print */
+
+int
+_find_priority_band(struct _state *s, int band);
+/* Finds the position of the priority band specified
+** Parameters: (state_t *) s: State to search in
+** (int) band: Band to look for
+** Returns : (int) Offset at which the band starts
+*/
+
+int
+_find_view_priority(struct _state *s, int y);
+/* Does the opposite of _find_priority_band
+** Parameters: (state_t *) s: State
+** (int) y: Coordinate to check
+** Returns : (int) The priority band y belongs to
+*/
+
+#define SCI0_VIEW_PRIORITY_14_ZONES(y) (((y) < s->priority_first)? 0 : (((y) >= s->priority_last)? 14 : 1\
+ + ((((y) - s->priority_first) * 14) / (s->priority_last - s->priority_first))))
+
+#define SCI0_PRIORITY_BAND_FIRST_14_ZONES(nr) ((((nr) == 0)? 0 : \
+ ((s->priority_first) + (((nr)-1) * (s->priority_last - s->priority_first)) / 14)))
+
+#define SCI0_VIEW_PRIORITY(y) (((y) < s->priority_first)? 0 : (((y) >= s->priority_last)? 14 : 1\
+ + ((((y) - s->priority_first) * 15) / (s->priority_last - s->priority_first))))
+
+#define SCI0_PRIORITY_BAND_FIRST(nr) ((((nr) == 0)? 0 : \
+ ((s->priority_first) + (((nr)-1) * (s->priority_last - s->priority_first)) / 15)))
+
+#define VIEW_PRIORITY(y) _find_view_priority(s, y)
+#define PRIORITY_BAND_FIRST(nr) _find_priority_band(s, nr)
+
+
+
+
+
+/******************** Dynamic view list functions ********************/
+
+abs_rect_t
+set_base(struct _state *s, reg_t object);
+/* Determines the base rectangle of the specified view object
+** Parameters: (state_t *) s: The state to use
+** (reg_t) object: The object to set
+** Returns : (abs_rect) The absolute base rectangle
+*/
+
+extern abs_rect_t
+get_nsrect(struct _state *s, reg_t object, byte clip);
+/* Determines the now-seen rectangle of a view object
+** Parameters: (state_t *) s: The state to use
+** (reg_t) object: The object to check
+** (byte) clip: Flag to determine wheter priority band
+** clipping should be performed
+** Returns : (abs_rect) The absolute rectangle describing the
+** now-seen area.
+*/
+
+void
+_k_dyn_view_list_prepare_change(struct _state *s);
+ /* Removes all views in anticipation of a new window or text */
+void
+_k_dyn_view_list_accept_change(struct _state *s);
+ /* Redraws all views after a new window or text was added */
+
+
+
+
+/******************** Misc functions ********************/
+
+void
+process_sound_events(struct _state *s); /* Get all sound events, apply their changes to the heap */
+
+#define LOOKUP_NODE(addr) lookup_node(s, (addr), __FILE__, __LINE__)
+#define LOOKUP_LIST(addr) lookup_list(s, addr, __FILE__, __LINE__)
+
+node_t *
+lookup_node(struct _state *s, reg_t addr, const char *file, int line);
+/* Resolves an address into a list node
+** Parameters: (state_t *) s: The state to operate on
+** (reg_t) addr: The address to resolve
+** (const char *) file: The file the function was called from
+** (int) line: The line number the function was called from
+** Returns : (node_t *) The list node referenced, or NULL on error
+*/
+
+
+list_t *
+lookup_list(struct _state *s, reg_t addr, const char *file, int line);
+/* Resolves a list pointer to a list
+** Parameters: (state_t *) s: The state to operate on
+** (reg_t) addr: The address to resolve
+** (const char *) file: The file the function was called from
+** (int) line: The line number the function was called from
+** Returns : (list_t *) The list referenced, or NULL on error
+*/
+
+
+
+/******************** Constants ********************/
+
+/* Maximum length of a savegame name (including terminator character) */
+#define SCI_MAX_SAVENAME_LENGTH 0x24
+
+/* Flags for the signal selector */
+#define _K_VIEW_SIG_FLAG_STOP_UPDATE 0x0001
+#define _K_VIEW_SIG_FLAG_UPDATED 0x0002
+#define _K_VIEW_SIG_FLAG_NO_UPDATE 0x0004
+#define _K_VIEW_SIG_FLAG_HIDDEN 0x0008
+#define _K_VIEW_SIG_FLAG_FIX_PRI_ON 0x0010
+#define _K_VIEW_SIG_FLAG_ALWAYS_UPDATE 0x0020
+#define _K_VIEW_SIG_FLAG_FORCE_UPDATE 0x0040
+#define _K_VIEW_SIG_FLAG_REMOVE 0x0080
+#define _K_VIEW_SIG_FLAG_FROZEN 0x0100
+#define _K_VIEW_SIG_FLAG_IS_EXTRA 0x0200
+#define _K_VIEW_SIG_FLAG_HIT_OBSTACLE 0x0400
+#define _K_VIEW_SIG_FLAG_DOESNT_TURN 0x0800
+#define _K_VIEW_SIG_FLAG_NO_CYCLER 0x1000
+#define _K_VIEW_SIG_FLAG_IGNORE_HORIZON 0x2000
+#define _K_VIEW_SIG_FLAG_IGNORE_ACTOR 0x4000
+#define _K_VIEW_SIG_FLAG_DISPOSE_ME 0x8000
+
+#define _K_VIEW_SIG_FLAG_FREESCI_STOPUPD 0x20000000 /* View has been stop-updated */
+
+
+/* Sound status */
+#define _K_SOUND_STATUS_STOPPED 0
+#define _K_SOUND_STATUS_INITIALIZED 1
+#define _K_SOUND_STATUS_PAUSED 2
+#define _K_SOUND_STATUS_PLAYING 3
+
+
+
+/* Kernel optimization flags */
+#define KERNEL_OPT_FLAG_GOT_EVENT (1<<0)
+#define KERNEL_OPT_FLAG_GOT_2NDEVENT (1<<1)
+
+
+/******************** Kernel functions ********************/
+
+/* Generic description: */
+typedef reg_t kfunct(struct _state *s, int funct_nr, int argc, reg_t *argv);
+
+#define FREESCI_KFUNCT_GLUTTON 1
+
+typedef struct {
+ kfunct *fun; /* The actual function */
+ const char *signature; /* kfunct signature */
+ const char *orig_name; /* Original name, in case we couldn't map it */
+} kfunct_sig_pair_t;
+
+#define KF_OLD 0
+#define KF_NEW 1
+#define KF_NONE -1 /* No mapping, but name is known */
+#define KF_TERMINATOR -42 /* terminates kfunct_mappers */
+
+typedef struct {
+ int type; /* KF_* */
+ const char *name;
+ kfunct_sig_pair_t new;
+} sci_kernel_function_t;
+
+extern sci_kernel_function_t kfunct_mappers[];
+
+#endif /* _SCI_KERNEL_H_ */
diff --git a/engines/sci/include/list.h b/engines/sci/include/list.h
new file mode 100644
index 0000000000..d53b87f491
--- /dev/null
+++ b/engines/sci/include/list.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)queue.h 8.5 (Berkeley) 8/20/94
+ */
+
+/* 2006-04-21 Modified by Walter van Niftrik. */
+
+#include <stdlib.h>
+
+#ifndef _SCI_LIST_H
+#define _SCI_LIST_H
+
+/* List definitions. */
+#define LIST_HEAD(name, type) \
+struct name { \
+ struct type *lh_first; /* first element */ \
+}
+
+#define LIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define LIST_ENTRY(type) \
+struct { \
+ struct type *le_next; /* next element */ \
+ struct type **le_prev; /* address of previous next element */ \
+}
+
+#define LIST_INIT(head) do { \
+ (head)->lh_first = NULL; \
+} while (0)
+
+#define LIST_INSERT_AFTER(listelm, elm, field) do { \
+ if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
+ (listelm)->field.le_next->field.le_prev = \
+ &(elm)->field.le_next; \
+ (listelm)->field.le_next = (elm); \
+ (elm)->field.le_prev = &(listelm)->field.le_next; \
+} while (0)
+
+#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
+ (elm)->field.le_prev = (listelm)->field.le_prev; \
+ (elm)->field.le_next = (listelm); \
+ *(listelm)->field.le_prev = (elm); \
+ (listelm)->field.le_prev = &(elm)->field.le_next; \
+} while (0)
+
+#define LIST_INSERT_HEAD(head, elm, field) do { \
+ if (((elm)->field.le_next = (head)->lh_first) != NULL) \
+ (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
+ (head)->lh_first = (elm); \
+ (elm)->field.le_prev = &(head)->lh_first; \
+} while (0)
+
+#define LIST_REMOVE(elm, field) do { \
+ if ((elm)->field.le_next != NULL) \
+ (elm)->field.le_next->field.le_prev = \
+ (elm)->field.le_prev; \
+ *(elm)->field.le_prev = (elm)->field.le_next; \
+} while (0)
+
+#define LIST_FOREACH(var, head, field) \
+ for ((var) = ((head)->lh_first); \
+ (var); \
+ (var) = ((var)->field.le_next))
+
+/* List access methods. */
+#define LIST_EMPTY(head) ((head)->lh_first == NULL)
+#define LIST_FIRST(head) ((head)->lh_first)
+#define LIST_NEXT(elm, field) ((elm)->field.le_next)
+
+/* Circular list definitions. */
+
+#define CLIST_HEAD(name, type) \
+struct name { \
+ struct type *clh_first; /* first element. */ \
+}
+
+#define CLIST_HEAD_INITIALIZER(head) \
+ { NULL }
+
+#define CLIST_ENTRY(type) \
+struct { \
+ struct type *cle_next; /* next element. */ \
+ struct type *cle_prev; /* previous element */ \
+}
+
+#define CLIST_INIT(head) do { \
+ (head)->clh_first = NULL; \
+} while (0)
+
+#define CLIST_INSERT_HEAD(head, elm, field) do { \
+ if ((head)->clh_first == NULL) \
+ (elm)->field.cle_next = (elm)->field.cle_prev = (elm); \
+ else { \
+ (elm)->field.cle_next = (head)->clh_first; \
+ (elm)->field.cle_prev = \
+ (head)->clh_first->field.cle_prev; \
+ (head)->clh_first->field.cle_prev = (elm); \
+ (elm)->field.cle_prev->field.cle_next = (elm); \
+ } \
+ (head)->clh_first = (elm); \
+} while (0)
+
+#define CLIST_INSERT_AFTER(listelm, elm, field) do { \
+ (elm)->field.cle_prev = (listelm); \
+ (elm)->field.cle_next = (listelm)->field.cle_next; \
+ (listelm)->field.cle_next->field.cle_prev = (elm); \
+ (listelm)->field.cle_next = (elm); \
+} while (0)
+
+#define CLIST_REMOVE(head, elm, field) do { \
+ if ((elm)->field.cle_next == (elm)) \
+ (head)->clh_first = NULL; \
+ else { \
+ if ((head)->clh_first == (elm)) \
+ (head)->clh_first = (elm)->field.cle_next; \
+ (elm)->field.cle_prev->field.cle_next = \
+ (elm)->field.cle_next; \
+ (elm)->field.cle_next->field.cle_prev = \
+ (elm)->field.cle_prev; \
+ } \
+} while (0)
+
+#define CLIST_FOREACH(var, head, field) \
+ for ((var) = (head)->clh_first; \
+ (var); \
+ (var) = ((var)->field.cle_next == (head)->clh_first ? \
+ NULL : (var)->field.cle_next))
+
+/* Circular list access methods. */
+#define CLIST_EMPTY(head) ((head)->clh_first == NULL)
+#define CLIST_FIRST(head) ((head)->clh_first)
+#define CLIST_NEXT(elm, field) ((elm)->field.cle_next)
+#define CLIST_PREV(elm, field) ((elm)->field.cle_prev)
+
+#endif /* !_SCI_LIST_H */
diff --git a/engines/sci/include/listener.h b/engines/sci/include/listener.h
new file mode 100644
index 0000000000..5e01696c30
--- /dev/null
+++ b/engines/sci/include/listener.h
@@ -0,0 +1,38 @@
+/***************************************************************************
+ listener.h Copyright (C) 2003 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef _LISTENER_H_
+# define _LISTENER_H_
+
+/* Event listener interface */
+
+typedef struct {
+ void (*notify)(void *self, void *notifier);
+ void *self;
+} listener_t;
+
+#endif
diff --git a/engines/sci/include/menubar.h b/engines/sci/include/menubar.h
new file mode 100644
index 0000000000..b66b43230a
--- /dev/null
+++ b/engines/sci/include/menubar.h
@@ -0,0 +1,219 @@
+/***************************************************************************
+ menubar.h Copyright (C) 1999,2000,01 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CJR) [jameson@linuxgames.com]
+
+***************************************************************************/
+/* Header for SCI0 menu bar management */
+
+#ifndef _SCI_MENUBAR_H_
+#define _SCI_MENUBAR_H_
+
+#include <gfx_operations.h>
+#include <gfx_widgets.h>
+
+struct _state;
+
+#define MENU_FREESCI_BLATANT_PLUG 0xfff0
+/* This adds an "About FreeSCI" menu option to the first menu */
+
+
+#define MENU_HBAR_STRING_1 "--!"
+#define MENU_HBAR_STRING_2 "-!"
+#define MENU_HBAR_STRING_3 "!--"
+/* These strings are used in SCI to determine an empty menu line */
+
+#define MENU_BORDER_SIZE 0
+/* The number of pixels added to the left and right to the text of a menu on the menu bar */
+
+#define MENU_LEFT_BORDER 5
+/* The number of pixels added to the left of the first menu */
+
+#define MENU_BOX_CENTER_PADDING 10
+/* Number of pixels to leave in between the left and the right centered text content in boxes
+** that use right centered content
+*/
+
+#define MENU_BOX_LEFT_PADDING 0
+/* Number of pixels to pad to the left */
+#define MENU_BOX_RIGHT_PADDING 2
+/* Number of pixels to pad to the right */
+
+#define MENU_BAR_HEIGHT 10
+
+
+#define MENU_TYPE_NORMAL 0
+#define MENU_TYPE_HBAR 1 /* Horizontal bar */
+
+/* Special characters used while building the menu bar */
+#define SCI_SPECIAL_CHAR_FUNCTION 'F'
+#define SCI_SPECIAL_CHAR_CTRL 3
+#define SCI_SPECIAL_CHAR_ALT 2
+
+/* Maximum number of bytes per SAID spec */
+#define MENU_SAID_SPEC_SIZE 64
+
+#define MENU_ATTRIBUTE_SAID 0x6d
+#define MENU_ATTRIBUTE_TEXT 0x6e
+#define MENU_ATTRIBUTE_KEY 0x6f
+#define MENU_ATTRIBUTE_ENABLED 0x70
+#define MENU_ATTRIBUTE_TAG 0x71
+
+/* Those flags determine whether the corresponding menu_item_t entries are valid */
+#define MENU_ATTRIBUTE_FLAGS_KEY 0x01
+#define MENU_ATTRIBUTE_FLAGS_SAID 0x02
+
+typedef struct {
+ int type; /* Normal or hbar */
+ char *keytext; /* right-centered part of the text (the key) */
+ int keytext_size; /* Width of the right-centered text */
+
+ int flags;
+ byte said[MENU_SAID_SPEC_SIZE]; /* Said spec for this item */
+ reg_t said_pos;
+ char *text;
+ reg_t text_pos;
+ int modifiers, key; /* Hotkey for this item */
+ int enabled;
+ int tag;
+
+} menu_item_t;
+
+
+typedef struct {
+ char *title;
+
+ int title_width; /* Width of the title in pixels */
+ int width; /* Pixel width of the menu window */
+
+ int items_nr; /* Window height equals to intems_nr * 10 */
+ menu_item_t *items; /* Actual entries into the menu */
+
+} menu_t;
+
+
+
+typedef struct {
+
+ int menus_nr;
+ menu_t *menus; /* The actual menus */
+
+} menubar_t;
+
+struct gfx_port;
+struct gfx_picture; /* forward declarations for graphics.h */
+
+
+/********** function definitions *********/
+
+menubar_t *
+menubar_new(void);
+/* Creates a new menubar struct
+** Parameters: (void)
+** Returns : (menubar_t *) A pointer to the new menubar entity
+** To free the entity, call menubar_free.
+*/
+
+
+void
+menubar_free(menubar_t *menubar);
+/* Frees all memory associated with a menubar
+** Parameters: (menubar_t *) menubar: The menubar to free
+** Returns : (void)
+*/
+
+
+void
+menubar_add_menu(gfx_state_t *state, menubar_t *menubar, char *title, char *entries, int font, reg_t entries_base);
+/* Adds a menu to the menubar.
+** Parameters: (gfx_state_t *) state: The state the fonts are stored in
+** (menubar_t *) menubar: The menubar to operate on
+** (char *) title: The menu title
+** (char *) entries: A string of menu entries
+** (int) font: The font which is to be used for drawing
+** (reg_t) entries_base: Segmented VM address of the entries string
+** Returns : (void)
+** The menu entries use the following special characters:
+** '`' : Right justify the following part
+** ':' : End of this entry
+** '#' : Function key (replaced by 'F')
+** '^' : Control key (replaced by \002, which looks like "CTRL")
+** '=' : Initial tag value
+** and the special string "--!", which represents a horizontal bar in the menu.
+**
+** If MENU_FREESCI_BLATANT_PLUG is defined, an additional option "About FreeSCI" will be
+** added if this was the first menu to be added to the menu bar.
+*/
+
+
+int
+menubar_set_attribute(struct _state *s, int menu, int item, int attribute, reg_t value);
+/* Sets the (currently unidentified) foo and bar values.
+** Parameters: (state_t *) s: The current state
+** (int) menu: The menu number to edit
+** (int) item: The menu item to change
+** (int) attribute: The attribute to modify
+** (int) value: The value the attribute should be set to
+** Returns : (int) 0 on success, 1 if either menu or item were invalid
+*/
+
+
+reg_t
+menubar_get_attribute(struct _state *s, int menu, int item, int attribute);
+/* Sets the (currently unidentified) foo and bar values.
+** Parameters: (state_t *) s: The current state
+** (int) menu: The menu number
+** (int) item: The menu item to read
+** (int) attribute: The attribute to read from
+** Returns : (int) The attribute value, or -1 on error
+*/
+
+
+int
+menubar_item_valid(struct _state *s, int menu, int item);
+/* Determines whether the specified menu entry may be activated
+** Parameters: (state_t *) s: The current state
+** (int x int) (menu, item): The menu item to check
+** Returns : (int) 1 if the menu item may be selected, 0 otherwise
+*/
+
+
+int
+menubar_map_pointer(struct _state *s, int *menu_nr, int *item_nr, gfxw_port_t *port);
+/* Maps the pointer position to a (menu,item) tuple.
+** Parameters: (state_t *) s: The current state
+** ((int *) x (int *)) (menu_nr, item_nr): Pointers to the current menu/item tuple
+** (port_t *) port: The port of the currently active menu (if any)
+** Returns : (int) 1 if the pointer is outside a valid port, 0 otherwise.
+*/
+
+int
+menubar_match_key(menu_item_t *item, int message, int modifiers);
+/* Determines whether a message/modifiers key pair matches a menu item's key parameters
+** Parameters: (menu_item_t *) item: The menu item to match
+** (int x int) message, modifiers: The input to compare
+** Returns : (int) 1 on match, 0 otherwise
+*/
+
+#endif /* !_SCI_MENUBAR_H_ */
+
diff --git a/engines/sci/include/modules.h b/engines/sci/include/modules.h
new file mode 100644
index 0000000000..9a64956326
--- /dev/null
+++ b/engines/sci/include/modules.h
@@ -0,0 +1,84 @@
+/***************************************************************************
+ modules.h Copyright (C) 2001 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef _FREESCI_MODULES_H_
+#define _FREESCI_MODULES_H_
+
+#include <sciresource.h>
+
+#ifdef _WIN32
+# define MODULE_NAME_SUFFIX ".dll"
+#else
+# define MODULE_NAME_SUFFIX ".so"
+#endif
+
+
+/* Modules must sub-type this structure. Oh, wait, C doesn't do sub-typing.
+** Well, they have to start the same, anyway... */
+typedef struct {
+ char *module_name; /* Module name */
+ char *module_version; /* Module version */
+ int class_magic; /* Magic ID to identify drivers of certain types */
+ int class_version; /* Version of that particular driver class */
+
+ /* More entries might be added later, but won't be checked if magic or
+ ** version don't match. */
+
+} sci_module_t;
+
+
+void *
+sci_find_module(char *path, char *name, char *type, char *struct_prefix,
+ char *file_suffix, int magic, int version, void **handle);
+/* Attempts to open a module with the specified parameters in the path
+** Parameters: (char *) path: The path to look in; supports several directories
+** (char *) name: Module name
+** (char *) type: Module type string (see below)
+** (char *) struct_prefix: see below
+** (char *) file_suffix: see below
+** (int) magic: Magic number to identify the module type
+** (int) version: The only version to support
+** (void **) handle: Pointer to a void * which a handle is written
+** to (for use with sci_close_module()).
+** Returns : (void *) NULL if no module was found, a pointer to the structure
+** otherwise
+** This function looks for the structure 'struct_prefix + name' in a file called
+** 'name + file_suffix + MODULE_NAME_SUFFIX' in the 'type' subdirectory.
+** It only success if both the magic and the version number match.
+*/
+
+void
+sci_close_module(void *module, char *type, char *name);
+/* Closes a previously found module
+** Parameters: (void *) module: Reference to the module to close
+** (char *) type: Type of the module (for debugging)
+** (char *) name: Module name (for debugging)
+** Returns : (void)
+*/
+
+
+#endif /* !_FREESCI_MODULES_H_ */
diff --git a/engines/sci/include/old_objects.h b/engines/sci/include/old_objects.h
new file mode 100644
index 0000000000..850e489a83
--- /dev/null
+++ b/engines/sci/include/old_objects.h
@@ -0,0 +1,54 @@
+#ifndef OLD_OBJECTS_H
+#define OLD_OBJECTS_H
+
+#include <sciresource.h>
+#include <util.h>
+
+#ifdef __cplusplus
+# define new new_
+# define delete delete_
+# define class class_
+#endif /* __cplusplus */
+
+typedef FLEXARRAY(script_opcode,int number;) script_method;
+
+typedef struct object_
+{
+ /*These are based on cached selector values, and set to the values
+ *the selectors had at load time. If the selectors are changed in
+ *instances, inconsistency will follow*/
+ struct object_* parent;
+ const char* name;
+
+ FLEXARRAY_NOEXTRA(struct object_*) children;
+
+ /*No flexarray, size the size is known from the start*/
+ script_method** methods;
+ int method_count;
+
+ int selector_count;
+ int* selector_numbers;
+} object;
+
+typedef struct
+{
+ int id;
+ object* class;
+ byte* heap;
+ int offset;
+} instance;
+
+extern object **object_map, *object_root;
+extern int max_object;
+
+#define SCRIPT_PRINT_METHODS 1
+#define SCRIPT_PRINT_CHILDREN 2
+#define SCRIPT_PRINT_SELECTORS 3
+void printObject(object* obj, int flags);
+
+int loadObjects(resource_mgr_t *resmgr);
+void freeObject(object*);
+
+extern const char* globals[];
+
+#endif
diff --git a/engines/sci/include/reg_t_hashmap.h b/engines/sci/include/reg_t_hashmap.h
new file mode 100644
index 0000000000..0bd89fe8f2
--- /dev/null
+++ b/engines/sci/include/reg_t_hashmap.h
@@ -0,0 +1,71 @@
+/***************************************************************************
+ int_hashmap.h Copyright (C) 2001 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef _REG_T_HASHMAP_H_
+#define _REG_T_HASHMAP_H_
+
+#define DCS_REGT_HASH_MAX 512
+
+#include "vm.h"
+#ifdef HASH_MAX
+# undef HASH_MAX
+# undef COMP
+# undef HASH
+#endif
+
+#define HASH_MAX DCS_REGT_HASH_MAX
+#define COMP(x, y) compare_reg_t(x, y)
+#define HASH(x) (((x.segment << 3) | x.offset) & 0x1ff)
+#undef MUST_FREE
+
+#include "hashmap.h"
+DECLARE_STRUCTS(reg_t)
+DECLARE_FUNCTIONS(reg_t)
+
+#ifndef BUILD_MAP_FUNCTIONS
+# undef HASH_MAX
+# undef COMP
+# undef HASH
+#endif
+
+/* see hashmap.h for descriptions of these functions */
+reg_t_hash_map_ptr
+new_reg_t_hash_map(void);
+
+void
+free_reg_t_hash_map(reg_t_hash_map_ptr);
+
+int
+reg_t_hash_map_check_value(reg_t_hash_map_ptr, reg_t value, char add_p, char *added);
+
+int
+reg_t_hash_map_remove_value(reg_t_hash_map_ptr, reg_t value);
+
+void
+apply_to_reg_t_hash_map(reg_t_hash_map_ptr map, void *param, void (*note) (void *param, reg_t name, int value));
+
+#endif /* _INT_HASHMAP_H_ */
diff --git a/engines/sci/include/resource.h b/engines/sci/include/resource.h
new file mode 100644
index 0000000000..cbb333f574
--- /dev/null
+++ b/engines/sci/include/resource.h
@@ -0,0 +1,510 @@
+/***************************************************************************
+ resource.h Copyright (C) 1999,2000,01,02 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) [creichen@rbg.informatik.tu-darmstadt.de]
+
+ History:
+
+ 990327 - created (CR)
+
+***************************************************************************/
+
+#ifndef FREESCI_PRIMARY_RESOURCE_H_
+#define FREESCI_PRIMARY_RESOURCE_H_
+
+/** This header file defines (mostly) generic tools and utility functions.
+ ** It also handles portability stuff, in cooperation with scitypes.h
+ ** (which specializes in primitive data types).
+ ** Most implementations of the functions found here are in
+ ** $(SRCDIR)/src/scicore/tools.c
+ **
+ ** -- Christoph Reichenbach
+ **/
+
+#define SCI_INVALID_FD -1
+#define IS_VALID_FD(a) ((a) != SCI_INVALID_FD) /* Tests validity of a file descriptor */
+
+#ifdef _WIN32
+# ifndef _Win32
+# define _Win32
+/* Work around problem with some versions of flex */
+# endif
+#endif
+
+/*#define _SCI_RESOURCE_DEBUG */
+/*#define _SCI_DECOMPRESS_DEBUG*/
+#ifndef WITH_DMALLOC
+# define SCI_SAFE_ALLOC /* Undefine for debugging */
+#endif
+
+#ifdef SCUMMVM
+//TODO: Remove these defines by replacing their functionality by their ScummVM counterparts
+#define HAVE_ISBLANK
+#define HAVE_UNISTD_H
+#define HAVE_FCNTL_H
+#define HAVE_UNLINK
+#define HAVE_RMDIR
+#define HAVE_MEMCHR
+#define HAVE_FNMATCH_H
+#define HAVE_SYS_TIME_H
+#define HAVE_GETTIMEOFDAY
+#define VERSION "0.6.4"
+#endif // SCUMMVM
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifndef __unix__
+# if defined(__OpenBSD__) || defined(__NetBSD__)
+# define __unix__
+# endif
+#endif
+
+#if defined(HAVE_FORK) && !defined(__BEOS__)
+# define HAVE_SYSV_IPC
+#else
+# undef HAVE_SYSV_IPC
+#endif
+
+#ifdef __DECC
+# include <c_asm.h>
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#ifdef WITH_DMALLOC
+# include <dmalloc.h>
+#endif
+
+#include <scitypes.h>
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifdef _WIN32
+# include <io.h>
+# include <sci_win32.h>
+#else /* !_WIN32 */
+# define DLLEXTERN
+#endif /* !_WIN32 */
+
+#ifdef __BEOS__
+# include <kernel/OS.h>
+# define usleep snooze
+#endif
+
+#ifdef _MSC_VER
+# include <sys/timeb.h>
+# include <fcntl.h>
+# include <windows.h>
+#endif
+
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#include <errno.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#include <assert.h>
+#ifdef _DOS
+# include <sci_dos.h>
+#endif
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+
+#ifdef _MSC_VER
+# ifdef FREESCI_EXPORTS
+# define DLLEXTERN
+# else
+# define DLLEXTERN __declspec(dllimport)
+#endif
+#else
+# define DLLEXTERN
+#endif
+
+#if _MSC_VER || _DOS
+# define G_DIR_SEPARATOR_S "\\"
+# define G_DIR_SEPARATOR '\\'
+#else
+# define G_DIR_SEPARATOR_S "/"
+# define G_DIR_SEPARATOR '/'
+#endif
+
+#if defined(__MORPHOS__) || defined(_MSC_VER) || defined(ARM_WINCE) || defined(__amigaos4__)
+# define PATH_MAX 255
+#endif
+
+#ifndef MIN
+# define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+#ifndef MAX
+# define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif /* HP-UX defines both */
+
+
+#define GUINT16_SWAP_LE_BE_CONSTANT(val) ((((val) & 0x00ff) << 8) | (((val) & 0xff00) >> 8))
+
+#define GUINT32_SWAP_LE_BE_CONSTANT(val) ( \
+ (((val) & 0xff000000) >> 24) \
+ | (((val) & 0x00ff0000) >> 8) \
+ | (((val) & 0x0000ff00) << 8) \
+ | (((val) & 0x000000ff) << 24))
+
+#define SCI_MAX_RESOURCE_SIZE 0x0400000
+/* The maximum allowed size for a compressed or decompressed resource */
+
+
+
+#define MAX_HOMEDIR_SIZE 255
+
+#ifdef _WIN32
+# define FO_BINARY "b"
+#else
+# define FO_BINARY ""
+#endif
+
+#ifdef _WIN32
+# define FO_TEXT "t"
+#else
+# define FO_TEXT ""
+#endif
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+/**** FUNCTION DECLARATIONS ****/
+
+#ifdef _WIN32
+# define scimkdir(arg1,arg2) mkdir(arg1)
+#else
+# define scimkdir(arg1,arg2) mkdir(arg1,arg2)
+#endif
+
+#ifndef _GET_INT_16
+#define _GET_INT_16
+
+static inline gint16
+getInt16(byte *d)
+{
+ return (gint16)(*d | (d[1] << 8));
+}
+
+#define getUInt16(d) (guint16)(getInt16(d))
+#endif
+/* Turns a little endian 16 bit value into a machine-dependant 16 bit value
+** Parameters: d: Pointer to the memory position from which to read
+** Returns : (gint16) The (possibly converted) 16 bit value
+** getUInt16 returns the int unsigned.
+*/
+
+static inline void
+putInt16(byte* dest, int src)
+{
+ dest[0]=(byte)src&0xff;
+ dest[1]=(byte)(src>>8)&0xff;
+}
+/* Converse of getInt16()
+** Parameters: (byte *) dest: The position to write to
+** (int) src: value to write
+*/
+
+#ifndef HAVE_ISBLANK
+static inline int
+isblank(int foo)
+{
+ return (foo == ' ') || (foo == '\t');
+}
+#endif
+
+#ifdef _cplusplus
+# define delete _freesci_cplusplus_workaround_delete
+# define new _freesci_cplusplus_workaround_new
+#endif
+
+#define SCI_MEMTEST memtest(__FILE__, __LINE__)
+
+/*-- queues --*/
+
+typedef struct _sci_queue_node {
+ void *data;
+ int type;
+ struct _sci_queue_node *next;
+} sci_queue_node_t;
+
+typedef struct {
+ sci_queue_node_t *start; /* Where things go in */
+ sci_queue_node_t *end; /* Where they come out */
+} sci_queue_t;
+
+sci_queue_t *
+sci_init_queue(sci_queue_t *queue);
+/* Initializes an SCI queue
+** Parameters: (sci_queue_t *) queue: Pointer to the queue to initialize
+** Returns : (sci_queue_t *) queue
+*/
+
+sci_queue_t *
+sci_add_to_queue(sci_queue_t *queue, void *data, int type);
+/* Adds an entry to an initialized SCI queue
+** Parameters: (sci_queue_t *) queue: The queue to add to
+** (void *) data: The data to contain
+** (int) type: Some metadata, e.g. size of the data block
+** Returns : (sci_queue_t *) queue
+** The meaning of the 'type' field may be determined individually.
+*/
+
+void *
+sci_get_from_queue(sci_queue_t *queue, int *type);
+/* Reads an entry from an SCI queue
+** Parameters: (sci_queue_t *) queue: The queue to remove from
+** (int *) type: A pointer to a variable to write the metadata
+** into, or NULL to omit this step
+** Returns : (void *) The data block contained, or NULL if none was inside
+*/
+
+/* --- */
+
+int
+memtest(const char *file, int line);
+/* Allocates, manipulates, and frees some memory
+** Parameters: (const char *) file: The file name to print when starting the
+** tests
+** (int) line: The line number to claim it was executed on
+** Returns : (int) 0
+** This function calls malloc(), free(), and memfrob() or memset()
+** to provocate segmentation faults caused by dynamic allocation bugs
+** in previous parts of the code.
+*/
+
+void
+sci_gettime(long *seconds, long *useconds);
+/* Calculates the current time in seconds and microseconds
+** Parameters: (long *) seconds: Pointer to the variable the seconds part of the
+** current time will be stored in
+** (long *) useconds: Pointer to the variable the microseconds part
+** of the current time will be stored in
+** Returns : (void)
+** The resulting values must be relative to an arbitrary fixed point in time
+** (typically 01/01/1970 on *NIX systems).
+*/
+
+void
+sci_get_current_time(GTimeVal *val);
+/* GTimeVal version of sci_gettime()
+** Parameters: (GTimeVal *) val: Pointer to the structure the values will be stored in
+** Returns : (void)
+*/
+
+void
+sci_init_dir(sci_dir_t *dirent);
+/* Initializes an sci directory search structure
+** Parameters: (sci_dir_t *) dirent: The entity to initialize
+** Returns : (void)
+** The entity is initialized to "empty" values, meaning that it can be
+** used in subsequent sci_find_first/sci_find_next constructs. In no
+** event should this function be used upon a structure which has been
+** subjected to any of the other dirent calls.
+*/
+
+char *
+sci_find_first(sci_dir_t *dirent, const char *mask);
+/* Finds the first file matching the specified file mask
+** Parameters: (sci_dir_t *) dirent: Pointer to an unused dirent structure
+** (const char *) mask: File mask to apply
+** Returns : (char *) Name of the first matching file found, or NULL
+*/
+
+char *
+sci_find_next(sci_dir_t *dirent);
+/* Finds the next file specified by an sci_dir initialized by sci_find_first()
+** Parameters: (sci_dir_t *) dirent: Pointer to SCI dir entity
+** Returns : (char *) Name of the next matching file, or NULL
+*/
+
+void
+sci_finish_find(sci_dir_t *dirent);
+/* Completes an 'sci_find_first/next' procedure
+** Parameters: (sci_dir_t *) dirent: Pointer to the dirent used
+** Returns : (void)
+** In the operation sequences
+** sci_init_dir(x); sci_finish_find(x);
+** and
+** sci_finish_find(x); sci_finish_find(x);
+** the second operation is guaranteed to be a no-op.
+*/
+
+FILE *
+sci_fopen(const char *fname, const char *mode);
+/* Opens a FILE* case-insensitively
+** Parameters: (const char *) fname: Name of the file to open
+** (const char *) mode: Mode to open it with
+** Returns : (FILE *) A valid file handle, or NULL on failure
+** Always refers to the cwd, cannot address subdirectories
+*/
+
+int
+sci_open(const char *fname, int flags);
+/* Opens a file descriptor case-insensitively
+** Parameters: (const char *) fname: Name of the file to open
+** (int) flags: open(2) flags for the file
+** Returns : (int) a file descriptor of the open file,
+** or SCI_INVALID_FD on failure
+** Always refers to the cwd, cannot address subdirectories
+*/
+
+
+int
+sciprintf(const char *fmt, ...);
+#define gfxprintf sciprintf
+/* Prints a string to the console stack
+** Parameters: fmt: a printf-style format string
+** ...: Additional parameters as defined in fmt
+** Returns : (int) 1
+** Implementation is in src/scicore/console.c
+*/
+
+char *
+sci_getcwd(void);
+/* Returns the current working directory, malloc'd.
+** Parameters: (void)
+** Returns : (char *) a malloc'd cwd, or NULL if it couldn't be determined.
+*/
+
+
+char *
+sci_get_homedir(void);
+/* Returns the user's home directory
+** Parameters: (void)
+** Returns : (char *) Pointer to a static buffer containing the user's home,
+** or NULL if there is no such thing.
+*/
+
+int
+sci_mkpath(const char *path);
+/* Asserts that the specified path is available
+** Parameters: (const char *) path: Path to verify/create
+** Returns : (int) 0 on success, <0 on error
+** This function will create any directories that couldn't be found
+*/
+
+int
+sci_fd_size(int fd);
+/* Returns the filesize of an open file
+** Parameters: (int) fd: File descriptor of open file
+** Returns : (int) filesize of file pointed to by fd, -1 on error
+*/
+
+int
+sci_file_size(const char *fname);
+/* Returns the filesize of a file
+** Parameters: (const char *) fname: Name of file to get filesize of
+** Returns : (int) filesize of the file, -1 on error
+*/
+
+char *
+_fcaseseek(const char *fname, sci_dir_t *dir);
+/* Returns the case-sensitive filename of a file.
+** Expects *dir to be uninitialized and the caller to free it afterwards.
+** Parameters: (const char *) fname: Name of file to get case-sensitive.
+** (sci_dir_t *) dir: Directory to find file within.
+** Returns : (char *) Case-sensitive filename of the file.
+*/
+
+/* Simple heuristic to work around array handling peculiarity in SQ4:
+It uses StrAt() to read the individual elements, so we must determine
+whether a string is really a string or an array. */
+int is_print_str(char *str);
+
+#ifdef HAVE_UNLINK
+# define sci_unlink unlink
+#else /* !HAVE_UNLINK */
+# error "Please provide an int sci_unlink(const char *) for removing filesystem entries"
+#endif /* !HAVE_UNLINK */
+
+#ifdef HAVE_RMDIR
+# define sci_rmdir rmdir
+#else /* !HAVE_RMDIR */
+# ifdef WIN32
+# define sci_rmdir _rmdir
+# else
+# error "Please provide an int sci_rmdir(const char *) for removing directories"
+# endif
+#endif /* !HAVE_RMDIR */
+
+#ifndef HAVE_FFS
+int sci_ffs(int _mask);
+#else
+#define sci_ffs ffs
+#endif
+
+
+void
+sci_sched_yield(void);
+/* Yields the running process/thread to the scheduler
+** Parameters: (void)
+** Returns : after a while.
+*/
+
+/* The following was originally based on glib.h code, which was
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ */
+#if defined (__GNUC__) && __GNUC__ >= 2
+# if defined (__i386__)
+# define BREAKPOINT() {__asm__ __volatile__ ("int $03"); }
+# elif defined(__alpha__)
+# define BREAKPOINT() {__asm__ __volatile__ ("call_pal 0x80"); }
+# endif /* !__i386__ && !__alpha__ */
+#elif defined (_MSC_VER)
+# if defined (_M_IX86)
+# define BREAKPOINT() { __asm { int 03 } }
+# elif defined(_M_ALPHA)
+# define BREAKPOINT() { __asm { bpt } }
+# endif /* !_M_IX86 && !_M_ALPHA */
+#elif defined (__DECC)
+# if defined(__alpha__)
+# define BREAKPOINT() {asm ("call_pal 0x80"); }
+# endif /* !__i386__ && !__alpha__ */
+#endif
+#ifndef BREAKPOINT
+# define BREAKPOINT() { fprintf(stderr, "Missed breakpoint in %s, line %d\n", __FILE__, __LINE__); *((int *) NULL) = 42; }
+#endif /* !BREAKPOINT() */
+
+#define WARNING(foo) {char i; i = 500;}
+
+#endif
+
+
+
+
+
+
diff --git a/engines/sci/include/sbtree.h b/engines/sci/include/sbtree.h
new file mode 100644
index 0000000000..38f8a71ba1
--- /dev/null
+++ b/engines/sci/include/sbtree.h
@@ -0,0 +1,114 @@
+/***************************************************************************
+ sbtree.h Copyright (C) 2000 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+/* Static binary tree header file */
+
+/* Static binary trees are used to link ints to pointers. They are not capable
+** of resizing after being initialized.
+*/
+
+#ifndef _SBTREE_H_
+#define _SBTREE_H_
+
+#ifdef SBTREE_DEBUG
+# include <stdio.h>
+#endif
+
+
+typedef struct {
+ int entries_nr;
+ int min_entry;
+ int max_entry;
+ int levels;
+ int alloced_entries;
+ void *data;
+} sbtree_t;
+
+
+sbtree_t *
+sbtree_new(int size, int *keys);
+/* Generates a new sbtree with the specified key set
+** Parameters: (int) size: Number of entries in 'keys'
+** (int *) keys: Array of 'size' integer keys
+** Returns : (sbtree_t *) A new sbtree
+** Only positive keys are allowed. Duplicates are not detected and will
+** cause additional memory usage and slower access times if not removed
+** beforehand.
+*/
+
+void
+sbtree_free(sbtree_t *tree);
+/* Frees an sbtree
+** Parameters: (sbtree_t *) tree: The tree to free
+** Returns : (void) Nothing at all
+*/
+
+int
+sbtree_set(sbtree_t *tree, int key, void *value);
+/* Sets a key to a value
+** Parameters: (sbtree_t *) tree: The tree to modify
+** (int) key: The key to set
+** (void *) value: The value part of the (key,value) tuple
+** Returns : (int) 0 if everything went OK, -1 if the key was invalid
+** value may, of course, be NULL here.
+*/
+
+void *
+sbtree_get(sbtree_t *tree, int key);
+/* Retreives a key
+** Parameters: (sbtree_t *) tree: The tree to search in
+** (int) key: The key to retreive
+** Returns : (void *) The value mapped to the key
+** If key was not found/invalid, NULL is returned. Note that there is no
+** way of distinguishing between keys mapped to NULL and invalid keys,
+** short of attempting to set that key.
+*/
+
+void
+sbtree_foreach(sbtree_t *tree, void *args, void *(*operation)(sbtree_t *, const int,
+ const void *, void *));
+/* Operates once on each entry in the tree
+** Parameters: (sbtree_t *) tree: The tree to operate on
+** (void *) arguments: Additional arguments to pass to 'operation'
+** (int (int, void *, void *)) operation: The operation to execute
+** Returns : (void)
+** The parameters of the function that is to be executed are as follows:
+** operation (sbtree_t *tree, int key, void *value, void *args)
+** Parameters: (sbtree_t *) tree: The tree the operation was executed on
+** (int) key: Key of the entry the operation was invoked on
+** (void *) value: Value of the entry the operation was invoked on
+** (void *) args: The 'args' parameter passed to sbtree_foreach()
+** Returns : (void *) The new value of this entry
+** This function will only work properly the original data contained no duplicate keys.
+*/
+
+
+#endif /* !_SBTREE_H_ */
+
+
+
+
+
diff --git a/engines/sci/include/sci_conf.h b/engines/sci/include/sci_conf.h
new file mode 100644
index 0000000000..da411226ed
--- /dev/null
+++ b/engines/sci/include/sci_conf.h
@@ -0,0 +1,187 @@
+/***************************************************************************
+ sci_conf.h Copyright (C) 1999,2000,01 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CJR) [jameson@linuxgames.com]
+
+***************************************************************************/
+/* Configuration and setup stuff for FreeSCI */
+
+#ifndef _SCI_CONFIG_H_
+#define _SCI_CONFIG_H_
+
+#include <versions.h>
+#include <gfx_options.h>
+
+#define FREESCI_DRIVER_SUBSYSTEMS_NR 1
+
+#define FREESCI_DRIVER_SUBSYSTEM_GFX 0
+#define FREESCI_DRIVER_SUBSYSTEM_PCM 1
+#define FREESCI_DRIVER_SUBSYSTEM_MIDIOUT 2
+
+#ifdef _WIN32
+# define SCI_DEFAULT_MODULE_PATH "."
+#else
+# define SCI_DEFAULT_MODULE_PATH "/usr/local/lib/freesci/:/usr/lib/freesci/"
+#endif
+
+typedef struct _driver_option {
+ char *option;
+ char *value;
+ struct _driver_option *next;
+} driver_option_t;
+
+typedef struct _subsystem_options {
+ char *name; /* Driver name */
+ driver_option_t *options;
+ struct _subsystem_options *next; /* next driver */
+} subsystem_options_t;
+
+typedef struct {
+ /* IMPORTANT: these values correspond directly to what's specified in
+ ** config.l. Where an option is of type OPTION_TYPE_NVP or
+ ** OPTION_TYPE_INVERSE_NVP, it is cast as an _integer_. Therefore it
+ ** should not be any other type except for int here.
+ */
+
+ char *name; /* Game identifier */
+ sci_version_t version; /* The version to emulate */
+
+ gfx_options_t gfx_options;
+
+ subsystem_options_t *driver_options[FREESCI_DRIVER_SUBSYSTEMS_NR];
+
+ int x_scale, y_scale, scale, color_depth; /* GFX subsystem initialization values */
+
+ int animation_delay; /* Number of microseconds to wait between each pic transition animation cycle */
+ int animation_granularity; /* Granularity for pic transition animations */
+ int alpha_threshold; /* Crossblitting alpha threshold */
+ int unknown_count; /* The number of "unknown" kernel functions */
+ char *resource_dir; /* Resource directory */
+ char *gfx_driver_name; /* The graphics driver to use */
+ char *console_log; /* The file to which console output should be echoed */
+ char *menu_dir; /* Directory where the game menu searches for games */
+ char debug_mode [80]; /* Characters specifying areas for which debug output should be enabled */
+ int mouse; /* Whether the mouse should be active */
+ int reverse_stereo;
+ int res_version;
+
+#ifdef __GNUC__
+# warning "Re-enable sound stuff"
+#endif
+#if 0
+ midiout_driver_t *midiout_driver; /* the midiout method to use */
+ midi_device_t *midi_device; /* the midi device to use */
+
+ pcmout_driver_t *pcmout_driver; /* the pcm driver to use */
+ sound_server_t *sound_server; /* The sound server */
+#endif
+ guint16 pcmout_rate; /* Sample rate */
+ guint8 pcmout_stereo; /* Stereo? */
+
+ char *module_path; /* path to directories modules are loaded from */
+ void *dummy; /* This is sad... */
+} config_entry_t;
+
+int
+config_init(config_entry_t **conf, char *conffil);
+/* Initializes the config entry structurre based on information found in the config file.
+** Parameters: (config_entry_t **) conf: See below
+** (char *) conffile: Filename of the config file, or NULL to use the default name
+** Returns : (int) The number of config file entries found
+** This function reads the ~/.freesci/config file, parses it, and inserts the appropriate
+** data into *conf. *conf will be malloc'd to be an array containing default information in [0]
+** and game-specific data in each of the subsequent record entries.
+** Not threadsafe. Uses flex-generated code.
+*/
+
+void
+config_free(config_entry_t **conf, int entries);
+/* Frees a config entry structure
+** Parameters: (config_entry_t **) conf: Pointer to the pointer to the first entry of the list
+** (int) entries: Number of entries to free
+** Returns : (void)
+*/
+
+
+void *
+parse_gfx_driver(char *driver_name);
+/* Parses a string and looks up an appropriate driver structure
+** Parameters: (char *) driver_name: Name of the driver to look up
+** Returns : (void *) A matching driver, or NULL on failure
+*/
+
+void *
+parse_midiout_driver(char *driver_name);
+/* Parses a string and looks up an appropriate driver structure
+** Parameters: (char *) driver_name: Name of the driver to look up
+** Returns : (void *) A matching driver, or NULL on failure
+*/
+
+void *
+parse_midi_device(char *driver_name);
+/* Parses a string and looks up an appropriate driver structure
+** Parameters: (char *) driver_name: Name of the driver to look up
+** Returns : (void *) A matching driver, or NULL on failure
+*/
+
+void *
+parse_pcmout_driver(char *driver_name);
+/* Parses a string and looks up an appropriate driver structure
+** Parameters: (char *) driver_name: Name of the driver to look up
+** Returns : (void *) A matching driver, or NULL on failure
+*/
+
+void *
+parse_sound_server(char *driver_name);
+/* Parses a string and looks up an appropriate driver structure
+** Parameters: (char *) driver_name: Name of the driver to look up
+** Returns : (void *) A matching sound server, or NULL on failure
+*/
+
+driver_option_t *
+get_driver_options(config_entry_t *config, int subsystem, const char *name);
+/* Retreives the driver options for one specific driver in a subsystem
+** Parameters: (config_entry_t *) config: The config entry to search in
+** (int) subsystem: Any of the FREESCI_DRIVER_SUBSYSTEMs
+** (const char *) name: Name of the driver to look for
+** Returns : (driver_option_t *) A pointer to the first option in
+** a singly-linked list of options, or NULL if none was
+** found
+*/
+
+#if 0
+void *
+find_module(char *path, char *module_name, char *module_suffix);
+/* Tries to find a module in the specified path
+** Parameters: (char *) path: The path to search in (specified in config)
+** (char *) module_name: Name of the module to look for
+** (char *) module_suffix: Module structure to look for
+** More precisely, the module "module_name" + MODULE_NAME_SUFFIX is
+** looked for in all members of the path. If it is found,
+
+** FIXME: First need to add generic module architecture
+
+*/
+#endif
+
+#endif /* !_SCI_CONFIG_H */
diff --git a/engines/sci/include/sci_dos.h b/engines/sci/include/sci_dos.h
new file mode 100644
index 0000000000..69e8803e29
--- /dev/null
+++ b/engines/sci/include/sci_dos.h
@@ -0,0 +1,174 @@
+/***************************************************************************
+ sci_dos.h Copyright (C) 1999 Rink Springer
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Rink Springer [rink@springer.cx]
+
+***************************************************************************/
+
+#ifndef _SCI_DOS_H_
+#define _SCI_DOS_H_
+
+#include <stdarg.h>
+
+#ifndef HAVE_DIRENT_H
+#define HAVE_DIRENT_H
+#endif
+
+#define TRUE (!FALSE)
+#define FALSE (0)
+
+typedef signed char gint8;
+typedef signed short gint16;
+typedef signed long gint32;
+
+typedef unsigned char guint8;
+typedef unsigned short guint16;
+typedef unsigned long guint32;
+
+typedef char gchar;
+typedef unsigned char guchar;
+typedef int gint;
+typedef unsigned int guint;
+typedef long glong;
+typedef unsigned long gulong;
+
+typedef gint gboolean;
+
+typedef void* gpointer;
+
+#define g_new0(type, count) ((type*)g_malloc0((unsigned)sizeof(type) * (count)))
+#define g_new(type, count) ((type*)sci_malloc((unsigned)sizeof(type) * (count)))
+
+#define g_malloc(x) sci_malloc(x)
+#define g_free(x) sci_free(x)
+#define g_realloc(x,y) sci_realloc(x,y)
+
+extern gpointer g_malloc0(guint32 size);
+
+/* Name of package */
+#define PACKAGE "freesci"
+
+/* Version number of package */
+#define VERSION "0.3.0"
+
+/* directory separator */
+#define G_DIR_SEPARATOR_S "/"
+
+/* paths longer than 128 chars? nah... */
+#define PATH_MAX 128
+
+#define SSIZE_MAX 1024
+
+#define g_get_current_time(x) gettimeofday(x,NULL)
+
+#define g_strcasecmp(x,y) strcasecmp(x,y)
+#define g_strncasecmp(x,y,z) strncasecmp(x,y,z)
+
+extern gint g_vsnprintf(gchar*,gulong,gchar const*,va_list);
+extern gpointer g_memdup (gpointer mem, guint byte_size);
+
+#define DGFX_KEYUP 72
+#define DGFX_KEYDOWN 80
+#define DGFX_KEYLEFT 75
+#define DGFX_KEYRIGHT 77
+#define DGFX_KEYSTOP 76 /* numberic 5 */
+
+#define DGFX_KEY_ESCAPE 1 /* escape */
+#define DGFX_KEY_1 2 /* 1 */
+#define DGFX_KEY_2 3 /* 2 */
+#define DGFX_KEY_3 4 /* 3 */
+#define DGFX_KEY_4 5 /* 4 */
+#define DGFX_KEY_5 6 /* 5 */
+#define DGFX_KEY_6 7 /* 6 */
+#define DGFX_KEY_7 8 /* 7 */
+#define DGFX_KEY_8 9 /* 8 */
+#define DGFX_KEY_9 10 /* 9 */
+#define DGFX_KEY_0 11 /* 0 */
+#define DGFX_KEY_MINUS 12 /* -/_ */
+#define DGFX_KEY_EQUAL 13 /* =/+ */
+#define DGFX_KEY_BSPACE 14 /* backspace */
+#define DGFX_KEY_TAB 15 /* enter */
+#define DGFX_KEY_Q 16 /* q */
+#define DGFX_KEY_W 17 /* w */
+#define DGFX_KEY_E 18 /* e */
+#define DGFX_KEY_R 19 /* r */
+#define DGFX_KEY_T 20 /* t */
+#define DGFX_KEY_Y 21 /* y */
+#define DGFX_KEY_U 22 /* u */
+#define DGFX_KEY_I 23 /* i */
+#define DGFX_KEY_O 24 /* o */
+#define DGFX_KEY_P 25 /* p */
+#define DGFX_KEY_LBRACKET 26 /* [/{ */
+#define DGFX_KEY_RBRACKET 27 /* ]/} */
+#define DGFX_KEY_ENTER 28 /* enter */
+#define DGFX_KEY_CTRL 29 /* control */
+#define DGFX_KEY_A 30 /* a */
+#define DGFX_KEY_S 31 /* s */
+#define DGFX_KEY_D 32 /* d */
+#define DGFX_KEY_F 33 /* f */
+#define DGFX_KEY_G 34 /* g */
+#define DGFX_KEY_H 35 /* h */
+#define DGFX_KEY_J 36 /* j */
+#define DGFX_KEY_K 37 /* k */
+#define DGFX_KEY_L 38 /* l */
+#define DGFX_KEY_COLON 39 /* ;/: */
+#define DGFX_KEY_TILDE 41 /* tilde */
+#define DGFX_KEY_LSHIFT 42 /* left shift */
+#define DGFX_KEY_Z 44 /* z */
+#define DGFX_KEY_X 45 /* x */
+#define DGFX_KEY_C 46 /* c */
+#define DGFX_KEY_V 47 /* v */
+#define DGFX_KEY_B 48 /* b */
+#define DGFX_KEY_N 49 /* n */
+#define DGFX_KEY_M 50 /* m */
+#define DGFX_KEY_COMMA 51 /* ,/< */
+#define DGFX_KEY_DOT 52 /* ./> */
+#define DGFX_KEY_SLASH 53 /* / / ? */
+#define DGFX_KEY_RSHIFT 54 /* right shift */
+#define DGFX_KEY_ALT 56 /* alt key */
+#define DGFX_KEY_SPACE 57 /* space bar */
+#define DGFX_KEY_F1 59 /* f1 */
+#define DGFX_KEY_F2 60 /* f2 */
+#define DGFX_KEY_F3 61 /* f3 */
+#define DGFX_KEY_F4 62 /* f4 */
+#define DGFX_KEY_F5 63 /* f5 */
+#define DGFX_KEY_F6 64 /* f6 */
+#define DGFX_KEY_F7 65 /* f7 */
+#define DGFX_KEY_F8 66 /* f8 */
+#define DGFX_KEY_F9 67 /* f9 */
+#define DGFX_KEY_F10 68 /* f10 */
+
+#define DGFX_KEY_HOME 71 /* home */
+#define DGFX_KEY_PAGEUP 73 /* page up */
+#define DGFX_KEY_END 79 /* end */
+#define DGFX_KEY_PAGEDOWN 81 /* page down */
+#define DGFX_KEY_INSERT 82 /* insert */
+#define DGFX_KEY_DELETE 83 /* delete */
+
+#define DGFX_KEY_KPSUB 74 /* keypad - */
+#define DGFX_KEY_KPADD 78 /* keypad + */
+
+#define DGFX_KEY_F11 87 /* f11 */
+#define DGFX_KEY_F12 88 /* f12 (emergency exit) */
+
+#endif /* _SCI_DOS_H_ */
diff --git a/engines/sci/include/sci_memory.h b/engines/sci/include/sci_memory.h
new file mode 100644
index 0000000000..41e5aa35ac
--- /dev/null
+++ b/engines/sci/include/sci_memory.h
@@ -0,0 +1,381 @@
+/***************************************************************************
+ sci_memory.h Copyright (C) 2001 Alexander R Angas
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Alexander R Angas (Alex Angas) <wgd@internode.on.net>
+
+ History:
+
+ 20010815 - assembled from the various memory allocation functions lying
+ about, namely resource.h, tools.c (for repeated allocation
+ attempts), menubar.h (for malloc_cpy, malloc_ncpy).
+ -- Alex Angas
+
+***************************************************************************/
+
+
+/** This header file defines a portable library for allocating memory safely
+ ** throughout FreeSCI.
+ ** Implementations of basic functions found here are in this file and
+ ** $(SRCDIR)/src/scicore/sci_memory.c
+ *
+ * Usage notes:
+ **************
+ *
+ * Define MALLOC_DEBUG to output debug information whenever a memory
+ * allocation function is called.
+ *
+ * Make sure you #define it before any #includes.
+ *
+ * #define MALLOC_DEBUG
+ * #include <...>
+ *
+ **************
+ *
+ * Define WITH_DMALLOC to use the dmalloc debug library, available from
+ * http://dmalloc.com/
+ *
+ **************
+ *
+ * Sets behaviour if memory allocation call fails.
+ * UNCHECKED_MALLOCS: use C library routine without checks
+ * (nothing defined): check mallocs and exit immediately on fail (recommended)
+ *
+ ** -- Alex Angas
+ **
+ **/
+
+
+#ifndef _SCI_MEMORY_H
+#define _SCI_MEMORY_H
+
+#include <stdio.h>
+#include <assert.h>
+#include <resource.h>
+
+#ifdef _WIN32
+# undef scim_inline /* just to be sure it is not defined */
+# define scim_inline __inline
+#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199900L
+# define scim_inline
+#else
+# define scim_inline inline
+#endif
+
+/********** macros for error messages **********/
+
+/*
+ * Prints an error message.
+ */
+#define PANIC(prn)\
+ fprintf prn;
+
+/*
+ * Called if memory allocation fails.
+ */
+#ifdef WITH_DMALLOC
+# ifdef __unix__
+# define DISABLE_SCI_MEMORY /* Use malloc() and friends */
+# endif
+#define PANIC_MEMORY(size, filename, linenum, funcname, more_info)\
+ PANIC((stderr, "Memory allocation of %lu bytes failed\n"\
+ " [%s (%s) : %u]\n " #more_info "\n %s\n",\
+ (unsigned long)size, filename, funcname, linenum, dmalloc_strerror(dmalloc_errno)))
+#else
+#define PANIC_MEMORY(size, filename, linenum, funcname, more_info)\
+ PANIC((stderr, "Memory allocation of %lu bytes\n"\
+ " [%s (%s) : %u]\n " #more_info "\n %s\n",\
+ (unsigned long)size, filename, funcname, linenum, strerror(errno)))
+#endif
+
+
+/********** the memory allocation macros **********/
+
+#define INFO_MEMORY(alloc_statement, size, filename, linenum, funcname)\
+ fprintf(stderr, "ALLOC_MEM(%lu bytes) [%s (%s) : %u] "\
+ #alloc_statement "\n",\
+ (unsigned long)size, filename, funcname, linenum);
+
+
+#ifdef UNCHECKED_MALLOCS
+
+#define ALLOC_MEM(alloc_statement, size, filename, linenum, funcname)\
+do {\
+ alloc_statement;\
+} while (0);
+
+#else /* !UNCHECKED_MALLOCS */
+
+#define ALLOC_MEM(alloc_statement, size, filename, linenum, funcname)\
+do {\
+ if (size < 0)\
+ {\
+ PANIC_MEMORY(size, filename, linenum, funcname, "Cannot allocate negative bytes of memory!")\
+ BREAKPOINT()\
+ }\
+ else if (size == 0)\
+ {\
+ PANIC_MEMORY(size, filename, linenum, funcname, "WARNING: allocating zero bytes of memory.")\
+ }\
+\
+ alloc_statement; /* attempt to allocate the memory */\
+\
+ if (res == NULL)\
+ {\
+ /* exit immediately */\
+ PANIC_MEMORY(size, filename, linenum, funcname, "Failed! Exiting...")\
+ BREAKPOINT()\
+\
+ /* attempt to allocate memory indefinitely\
+ do\
+ {\
+ PANIC_MEMORY(size, filename, linenum, funcname, "Failed! Trying again...");\
+ sleep(1000);\
+ alloc_statement;\
+ } while (res == NULL);\
+ */\
+ }\
+} while (0);
+
+#endif /* !UNCHECKED_MALLOCS */
+
+
+/********** memory allocation routines **********/
+
+extern void *
+_SCI_MALLOC(size_t size, const char *file, int line, const char *funct);
+/* Allocates the specified amount of memory.
+** Parameters: (size_t) size: Number of bytes to allocate
+** (char *) file: Filename this routine is called from
+** (use __FILE__)
+** (int) line: Line number this routine is called from
+** (use __LINE__)
+** (char *) funct: Function this routine is called from
+** (use __PRETTY_FUNCTION__ if available)
+** Returns : (void *) A pointer to the allocated memory chunk
+** To free this string, use the sci_free() command.
+** If the call fails, behaviour is dependent on the definition of SCI_ALLOC.
+*/
+
+extern void *
+_SCI_CALLOC(size_t num, size_t size, const char *file, int line, const char *funct);
+/* Allocates num * size bytes of zeroed-out memory.
+** Parameters: (size_t) num: Number of elements to allocate
+** (size_t) size: Amount of memory per element to allocate
+** Please see _SCI_MALLOC() for details on other parameters.
+** Returns : (void *) A pointer to the allocated memory chunk
+** To free this string, use the sci_free() command.
+** See _SCI_MALLOC() for more information if call fails.
+*/
+
+extern void *
+_SCI_REALLOC(void *ptr, size_t size, const char *file, int line, const char *funct);
+/* Increases the size of an allocated memory chunk.
+** Parameters: (void *) ptr: The original pointer
+** (size_t) size: New size of the memory chunk
+** Please see _SCI_MALLOC() for details on other parameters.
+** Returns : (void *) A possibly new pointer, containing 'size'
+** bytes of memory and everything contained in the original 'ptr'
+** (possibly minus some trailing data if the new memory area is
+** smaller than the old one).
+** To free this string, use the sci_free() command.
+** See _SCI_MALLOC() for more information if call fails.
+*/
+
+extern void
+_SCI_FREE(void *ptr, const char *file, int line, const char *funct);
+/* Frees previously allocated memory chunks
+** Parameters: (void *) ptr: The pointer to free
+** Please see _SCI_MALLOC() for details on other parameters.
+** Returns : (void)
+*/
+
+extern void *
+_SCI_MEMDUP(const void *src, size_t size, const char *file, int line, const char *funct);
+/* Duplicates a chunk of memory
+** Parameters: (void *) src: Pointer to the data to duplicate
+** (size_t) size: Number of bytes to duplicate
+** Please see _SCI_MALLOC() for details on other parameters.
+** Returns : (void *) An appropriately allocated duplicate, or NULL on error
+** Please try to avoid data duplication unless absolutely neccessary!
+** To free this string, use the sci_free() command.
+** See _SCI_MALLOC() for more information if call fails.
+*/
+
+extern char *
+_SCI_STRDUP(const char *src, const char *file, int line, const char *funct);
+/* Duplicates a string.
+** Parameters: (const char *) src: The original pointer
+** Please see _SCI_MALLOC() for details on other parameters.
+** Returns : (char *) a pointer to the storage location for the copied
+** string.
+** To free this string, use the sci_free() command.
+** See _SCI_MALLOC() for more information if call fails.
+*/
+
+
+extern char *
+_SCI_STRNDUP(const char *src, size_t length, const char *file, int line, const char *funct);
+/* Copies a string into a newly allocated memory part, up to a certain length.
+** Parameters: (char *) src: The source string
+** (int) length: The maximum length of the string (not counting
+** a trailing \0).
+** Please see _SCI_MALLOC() for details on other parameters.
+** Returns : (char *) The resulting copy, allocated with sci_malloc().
+** To free this string, use the sci_free() command.
+** See _SCI_MALLOC() for more information if call fails.
+*/
+
+/****************************************/
+/* Refcounting garbage collected memory */
+/****************************************/
+
+/* Refcounting memory calls are a little slower than the others,
+** and using it improperly may cuase memory leaks. It conserves
+** memory, though. */
+
+#define SCI_REFCOUNT_TEST(f) sci_refcount_incref(f); sci_refcount_decref(f);
+
+extern void *
+sci_refcount_alloc(size_t length);
+/* Allocates "garbage" memory
+** Parameters: (size_t) length: Number of bytes to allocate
+** Returns : (void *) The allocated memory
+** Memory allocated in this fashion will be marked as holding one reference.
+** It cannot be freed with 'free()', only by using sci_refcount_decref().
+*/
+
+extern void *
+sci_refcount_incref(void *data);
+/* Adds another reference to refcounted memory
+** Parameters: (void *) data: The data to add a reference to
+** Returns : (void *) data
+*/
+
+extern void
+sci_refcount_decref(void *data);
+/* Decrements the reference count for refcounted memory
+** Parameters: (void *) data: The data to add a reference to
+** Returns : (void *) data
+** If the refcount reaches zero, the memory will be deallocated
+*/
+
+extern void *
+sci_refcount_memdup(void *data, size_t len);
+/* Duplicates non-refcounted memory into a refcounted block
+** Parameters: (void *) data: The memory to copy from
+** (size_t) len: The number of bytes to copy/allocate
+** Returns : (void *) Newly allocated refcounted memory
+** The number of references accounted for will be one.
+*/
+
+/********** macro definitions for routines **********/
+
+#ifdef DISABLE_SCI_MEMORY
+# define sci_malloc malloc
+# define sci_calloc calloc
+# define sci_realloc realloc
+# define sci_free free
+# define sci_strdup strdup
+# define sci_strndup strndup
+# define sci_memdup memdup
+#else
+
+# ifdef __GNUC__
+# define sci_malloc(size)\
+ _SCI_MALLOC(size, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+# else
+# define sci_malloc(size)\
+ _SCI_MALLOC(size, __FILE__, __LINE__, "")
+# endif
+
+# ifdef __GNUC__
+# define sci_calloc(num, count)\
+ _SCI_CALLOC(num, count, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+# else
+# define sci_calloc(num, count)\
+ _SCI_CALLOC(num, count, __FILE__, __LINE__, "")
+# endif
+
+
+# ifdef __GNUC__
+# define sci_realloc(ptr, size)\
+ _SCI_REALLOC(ptr, size, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+# else
+# define sci_realloc(ptr, size)\
+ _SCI_REALLOC(ptr, size, __FILE__, __LINE__, "")
+# endif
+
+
+# ifdef __GNUC__
+# define sci_free(ptr)\
+ _SCI_FREE(ptr, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+# else
+# define sci_free(ptr)\
+ _SCI_FREE(ptr, __FILE__, __LINE__, "")
+# endif
+
+
+# ifdef __GNUC__
+# define sci_memdup(src, size)\
+ _SCI_MEMDUP(src, size, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+# else
+# define sci_memdup(src, size)\
+ _SCI_MEMDUP(src, size, __FILE__, __LINE__, "")
+# endif
+
+
+# ifdef __GNUC__
+# define sci_strdup(src)\
+ _SCI_STRDUP(src, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+# else
+# define sci_strdup(src)\
+ _SCI_STRDUP(src, __FILE__, __LINE__, "")
+# endif
+
+
+# ifdef __GNUC__
+# define sci_strndup(src, length)\
+ _SCI_STRNDUP(src, length, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+# else
+# define sci_strndup(src, length)\
+ _SCI_STRNDUP(src, length, __FILE__, __LINE__, "")
+# endif
+#endif
+
+
+/********** other memory/debug related routines **********/
+
+#ifdef _WIN32
+extern void
+debug_win32_memory(int dbg_setting);
+/* Sets debugging for Win32 memory.
+** Parameters: (bool) dbg_setting:
+** 0: no debugging
+** 1: call _CrtCheckMemory at every memory request
+** 2: perform automatic leak checking at program exit
+** 3: enable debug heap allocations
+*/
+#endif
+
+
+#endif /* _SCI_MEMORY_H */
diff --git a/engines/sci/include/sci_midi.h b/engines/sci/include/sci_midi.h
new file mode 100644
index 0000000000..16003a3cbd
--- /dev/null
+++ b/engines/sci/include/sci_midi.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ sci_midi.h Copyright (C) 2003 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef _SCI_MIDI_H_
+#define _SCI_MIDI_H_
+
+#define MIDI_RHYTHM_CHANNEL 9
+
+/* Special SCI sound stuff */
+
+#define SCI_MIDI_TIME_EXPANSION_PREFIX 0xF8
+#define SCI_MIDI_TIME_EXPANSION_LENGTH 240
+
+#define SCI_MIDI_EOT 0xFC
+#define SCI_MIDI_SET_SIGNAL 0xCF
+#define SCI_MIDI_SET_POLYPHONY 0x4B
+#define SCI_MIDI_RESET_ON_SUSPEND 0x4C
+#define SCI_MIDI_CHANNEL_MUTE 0x4E
+#define SCI_MIDI_SET_REVERB 0x50
+#define SCI_MIDI_HOLD 0x52
+#define SCI_MIDI_CUMULATIVE_CUE 0x60
+#define SCI_MIDI_CHANNEL_NOTES_OFF 0x7B /* all-notes-off for Bn */
+
+#define SCI_MIDI_SET_SIGNAL_LOOP 0x7F
+/* If this is the parameter of 0xCF, the loop point is set here */
+
+#define SCI_MIDI_CONTROLLER(status) ((status & 0xF0) == 0xB0)
+
+#endif /* !defined(_SCI_MIDI_H_) */
diff --git a/engines/sci/include/sci_widgets.h b/engines/sci/include/sci_widgets.h
new file mode 100644
index 0000000000..f961021622
--- /dev/null
+++ b/engines/sci/include/sci_widgets.h
@@ -0,0 +1,211 @@
+/***************************************************************************
+ sci_widgets.h Copyright (C) 2000 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+/* SCI-specific widget handling */
+
+#ifndef _SCI_WIDGETS_H_
+#define _SCI_WIDGETS_H_
+
+#include <engine.h>
+
+/* The following flags are applicable to windows in SCI0: */
+#define WINDOW_FLAG_TRANSPARENT 0x01
+
+
+#define WINDOW_FLAG_NOFRAME 0x02
+/* No frame is drawn around the window onto wm_view */
+
+#define WINDOW_FLAG_TITLE 0x04
+/* Add titlebar to window (10 pixels high, framed, text is centered and written
+** in white on dark gray
+*/
+
+#define WINDOW_FLAG_DONTDRAW 0x80
+/* Don't draw anything */
+
+#define WINDOW_FLAG_NO_DROP_SHADOW 0x1000000
+
+
+/* Used in kgraphics to flag text surrounded by a dithered frame */
+#define CONTROL_STATE_DITHER_FRAMED 0x1000
+
+/* Used by the interpreter to flag buttons that are grayed out */
+#define CONTROL_STATE_GRAY 0x0004
+/* Used by the interpreter to flag some widgets to determine whether they should be surrounded by a frame */
+#define CONTROL_STATE_FRAMED 0x0008
+/* Used by the interpreter to flag buttons that are enabled */
+#define CONTROL_STATE_ENABLED 0x0001
+
+void
+sciw_set_status_bar(state_t *s, gfxw_port_t *status_bar, char *text, int fgcolor, int bgcolor);
+/* Sets the contents of a port used as status bar
+** Parmeters: (state_t *) s: The affected game state
+** (gfxw_port_t *) status_bar: The status bar port
+** (char *) text: The text to draw
+** Returns : (void)
+*/
+
+gfxw_port_t *
+sciw_new_window(state_t *s, rect_t area, int font, gfx_color_t color, gfx_color_t bgcolor,
+ int title_font, gfx_color_t title_color, gfx_color_t title_bg_color,
+ const char *title, int flags);
+/* Creates a new SCI style window
+** Parameters: (state_t *) s: The affected game state
+** (rect_t) area: The screen area to frame (not including a potential window title)
+** (int) font: Default font number to use
+** (gfx_color_t) color: The foreground color to use for drawing
+** (gfx_color_t) bgcolor: The background color to use
+** (int) title_font: The font to use for the title bar (if any)
+** (gfx_color_t) title_color: Color to use for the title bar text
+** (gfx_color_t) title_bg_color: Color to use for the title bar background
+** (const char *) title: The text to write into the title bar
+** (int) flags: Any ORred combination of window flags
+** Returns : (gfxw_port_t *) A newly allocated port with the requested characteristics
+*/
+
+/*---------------------*/
+/*** Control widgets ***/
+/*---------------------*/
+
+gfxw_list_t *
+sciw_new_button_control(gfxw_port_t *port, reg_t ID, rect_t zone, char *text, int font, char selected, char inverse, char gray);
+/* Creates a new button control list
+** Parameters: (gfxw_port_t *) port: The port containing the color values to use for the
+** button (the button is /not/ appended to the port there)
+** (reg_t) ID: Button's ID
+** (rect_t) zone: The area occupied by the button
+** (char *) text: The text to write into the button
+** (int) font: The font to use for the button
+** (char) selected: Whether the button should be marked as being selected by the keyboard focus
+** (char) inverse: Whether to inverse the color scheme
+** (char) gray: Whether the button should be grayed out
+** Returns : (gfxw_list_t *) The button
+*/
+
+gfxw_list_t *
+sciw_new_text_control(gfxw_port_t *port, reg_t ID, rect_t zone, char *text, int font,
+ gfx_alignment_t align, char frame, char inverse);
+/* Creates a new text control list
+** Parameters: (gfxw_port_t *) port: The port containing the color values to use
+** (reg_t) ID: Text widget ID
+** (rect_t) zone: Area occupied by the text
+** (char *) text: The text
+** (int) font: The font the text is to be drawn in
+** (gfx_alignment_t) align: Horizontal text alignment to use
+** (char) frame: Whether a dithered frame should surround the text
+** (char) inverse: Whether the text colors should be inversed
+** Returns : (gfxw_list_t *) The text control widget list
+*/
+
+gfxw_list_t *
+sciw_new_edit_control(gfxw_port_t *port, reg_t ID, rect_t zone, char *text, int font, unsigned int cursor,
+ char inverse);
+/* Creates a new edit control list
+** Parameters: (gfxw_port_t *) port: The port containing the color values to use
+** (reg_t) ID: Text widget ID
+** (rect_t) zone: Area occupied by the text
+** (char *) text: The text
+** (int) font: The font the text is to be drawn in
+** (int) cursor: Cursor position
+** (char) inverse: Whether the edit widget should be reversed
+** Returns : (gfxw_list_t *) An appropriate widget list
+*/
+
+gfxw_list_t *
+sciw_new_icon_control(gfxw_port_t *port, reg_t ID, rect_t zone, int view, int loop, int cel,
+ char frame, char inverse);
+/* Creates a new icon control list
+** Parameters: (gfxw_port_t *) port: The port containing the color values to use
+** (reg_t) ID: Text widget ID
+** (rect_t) zone: Area occupied by the text
+** (int x int x int) view, loop, cel: The cel to display
+** (char) frame: Whether the widget should be surrounded by a frame
+** (char) lina inverse: Whether colors should be inversed
+** Returns : (gfxw_list_t *) An appropriate widget list
+*/
+
+gfxw_list_t *
+sciw_new_list_control(gfxw_port_t *port, reg_t ID, rect_t zone, int font_nr, char **entries_list,
+ int entries_nr, int list_top, int selection, char inverse);
+/* Creates a new list control list
+** Parameters: (gfxw_port_t *) port: The port containing the color values to use
+** (int) ID: Text widget ID
+** (rect_t) zone: Area occupied by the text
+** (int) font_nr: number of the font to use
+** (char **) entries_list: List of strings to contain within the list
+** (int) entries_nr: Number of entries in entries_list
+** (int) list_top: First list item that is visible
+** (int) selection: The list item that is selected
+** (char) invserse: The usual meaning
+** Returns : (gfxw_list_t *) An appropriate widget list
+*/
+
+/*---------------------*/
+/*** Menubar widgets ***/
+/*---------------------*/
+
+void
+sciw_set_menubar(state_t *s, gfxw_port_t *status_bar, menubar_t *menubar, int selection);
+/* Draws the menu bar
+** Parameters: (state_t *) s: The state to operate on
+** (gfxw_port_t *) status_bar: The status bar port to modify
+** (menubar_t *) menubar: The menu bar to use
+** (int) selection: Number of the menu to hightlight, or -1 for 'none'
+** Returns : (void)
+*/
+
+gfxw_port_t *
+sciw_new_menu(state_t *s, gfxw_port_t *status_bar, menubar_t *menubar, int selection);
+/* Creates a menu port
+** Parameters: (state_t *) s: The state to operate on
+** (gfxw_port_t *) status_bar: The status bar
+** (menubar_t *) menubar: The menu bar to use
+** (int) selection: Number of the menu to interpret
+** Returns : (gfxw_port_t *) The result port
+*/
+
+gfxw_port_t *
+sciw_unselect_item(state_t *s, gfxw_port_t *menu_port, menu_t *menu, int selection);
+/* Unselects a previously selected item from a menu port
+** Parameters: (state_t *) s: The state to operate on
+** (gfxw_port_t *) menu_port: The port modify
+** (menu_t *) menu: The menu the menu port corresponds to
+** (int) selection: Number of the menu entry to unselect, or -1 to do a NOP
+** Returns : (gfxw_port_t *) The modified menu
+*/
+
+gfxw_port_t *
+sciw_select_item(state_t *s, gfxw_port_t *menu_port, menu_t *menu, int selection);
+/* Selects a menu item from a menu port
+** Parameters: (state_t *) s: The state to operate on
+** (gfxw_port_t *) menu_port: The port modify
+** (menu_t *) menu: The menu the menu port corresponds to
+** (int) selection: Number of the menu entry to select, or -1 to do a NOP
+** Returns : (gfxw_port_t *) The modified menu
+*/
+
+#endif /* _!SCI_WIDGETS_H_ */
+
diff --git a/engines/sci/include/sciresource.h b/engines/sci/include/sciresource.h
new file mode 100644
index 0000000000..e9ac7cf5d4
--- /dev/null
+++ b/engines/sci/include/sciresource.h
@@ -0,0 +1,538 @@
+/***************************************************************************
+ sciresource.h Copyright (C) 1999,2000,01 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) [creichen@rbg.informatik.tu-darmstadt.de]
+
+ History:
+
+ 990327 - created (CR)
+
+***************************************************************************/
+
+#ifndef _SCIRESOURCE_H_
+#define _SCIRESOURCE_H_
+
+/*#define _SCI_RESOURCE_DEBUG */
+/*#define _SCI_DECOMPRESS_DEBUG*/
+
+#include <resource.h>
+#include <versions.h>
+
+#define SCI_MAX_RESOURCE_SIZE 0x0400000
+/* The maximum allowed size for a compressed or decompressed resource */
+
+#ifdef _WIN32
+# define DIR_SEPARATOR_STR "\\"
+# define PATH_SEPARATOR_STR ";"
+#else
+# define DIR_SEPARATOR_STR "/"
+# define PATH_SEPARATOR_STR ":"
+#endif
+
+
+/*** RESOURCE STATUS TYPES ***/
+#define SCI_STATUS_NOMALLOC 0
+#define SCI_STATUS_ALLOCATED 1
+#define SCI_STATUS_ENQUEUED 2 /* In the LRU queue */
+#define SCI_STATUS_LOCKED 3 /* Allocated and in use */
+
+#define SCI_RES_FILE_NR_PATCH -1 /* Resource was read from a patch file rather than from a resource */
+
+
+/*** INITIALIZATION RESULT TYPES ***/
+#define SCI_ERROR_IO_ERROR 1
+#define SCI_ERROR_EMPTY_OBJECT 2
+#define SCI_ERROR_INVALID_RESMAP_ENTRY 3
+/* Invalid resource.map entry */
+#define SCI_ERROR_RESMAP_NOT_FOUND 4
+#define SCI_ERROR_NO_RESOURCE_FILES_FOUND 5
+/* No resource at all was found */
+#define SCI_ERROR_UNKNOWN_COMPRESSION 6
+#define SCI_ERROR_DECOMPRESSION_OVERFLOW 7
+/* decompression failed: Buffer overflow (wrong SCI version?) */
+#define SCI_ERROR_DECOMPRESSION_INSANE 8
+/* sanity checks failed during decompression */
+#define SCI_ERROR_RESOURCE_TOO_BIG 9
+/* Resource size exceeds SCI_MAX_RESOURCE_SIZE */
+#define SCI_ERROR_UNSUPPORTED_VERSION 10
+#define SCI_ERROR_INVALID_SCRIPT_VERSION 11
+
+#define SCI_ERROR_CRITICAL SCI_ERROR_NO_RESOURCE_FILES_FOUND
+/* the first critical error number */
+
+/*** SCI VERSION NUMBERS ***/
+#define SCI_VERSION_AUTODETECT 0
+#define SCI_VERSION_0 1
+#define SCI_VERSION_01 2
+#define SCI_VERSION_01_VGA 3
+#define SCI_VERSION_01_VGA_ODD 4
+#define SCI_VERSION_1_EARLY 5
+#define SCI_VERSION_1_LATE 6
+#define SCI_VERSION_1_1 7
+#define SCI_VERSION_32 8
+#define SCI_VERSION_LAST SCI_VERSION_1_LATE /* The last supported SCI version */
+
+#define SCI_VERSION_1 SCI_VERSION_1_EARLY
+
+#define RESSOURCE_TYPE_DIRECTORY 0
+#define RESSOURCE_TYPE_AUDIO_DIRECTORY 1
+#define RESSOURCE_TYPE_VOLUME 2
+#define RESSOURCE_TYPE_EXTERNAL_MAP 3
+#define RESSOURCE_TYPE_INTERNAL_MAP 4
+#define RESSOURCE_TYPE_MASK 127
+#define RESSOURCE_ADDRESSING_BASIC 0
+#define RESSOURCE_ADDRESSING_EXTENDED 128
+#define RESSOURCE_ADDRESSING_MASK 128
+
+extern DLLEXTERN const char* sci_error_types[];
+extern DLLEXTERN const char* sci_version_types[];
+extern DLLEXTERN const char* sci_resource_types[];
+extern DLLEXTERN const char* sci_resource_type_suffixes[]; /* Suffixes for SCI1 patch files */
+extern DLLEXTERN const int sci_max_resource_nr[]; /* Highest possible resource numbers */
+
+
+enum ResourceTypes {
+ sci_view=0, sci_pic, sci_script, sci_text,
+ sci_sound, sci_memory, sci_vocab, sci_font,
+ sci_cursor, sci_patch, sci_bitmap, sci_palette,
+ sci_cdaudio, sci_audio, sci_sync, sci_message,
+ sci_map, sci_heap, sci_invalid_resource
+};
+
+#define sci0_last_resource sci_patch
+#define sci1_last_resource sci_heap
+/* Used for autodetection */
+
+
+struct resource_index_struct {
+ unsigned short resource_id;
+ unsigned int resource_location;
+}; /* resource type as stored in the resource.map file */
+
+typedef struct resource_index_struct resource_index_t;
+
+typedef struct resource_source_struct {
+ int source_type;
+ int scanned;
+ union {
+ struct {
+ char *name;
+ int volume_number;
+ } file;
+ struct {
+ char *name;
+ } dir;
+ struct {
+ struct _resource_struct *resource;
+ } internal_map;
+ } location;
+ struct resource_source_struct *associated_map;
+ struct resource_source_struct *next;
+} resource_source_t;
+
+typedef struct _resource_altsource_struct {
+ resource_source_t *source;
+ unsigned int file_offset;
+ struct _resource_altsource_struct *next;
+} resource_altsource_t;
+
+
+typedef struct _resource_struct {
+ unsigned char *data;
+
+ unsigned short number;
+ unsigned short type;
+ guint16 id; /* contains number and type */
+
+ unsigned int size;
+
+ unsigned int file_offset; /* Offset in file */
+ resource_source_t *source;
+
+ unsigned char status;
+ unsigned short lockers; /* Number of places where this resource was locked */
+
+ struct _resource_struct *next; /* Position marker for the LRU queue */
+ struct _resource_struct *prev;
+
+ resource_altsource_t *alt_sources; /* SLL of alternative resource data sources */
+} resource_t; /* for storing resources in memory */
+
+
+typedef struct {
+ int max_memory; /* Config option: Maximum total byte number allocated */
+ int sci_version; /* SCI resource version to use */
+
+ int resources_nr;
+ resource_source_t *sources;
+ resource_t *resources;
+
+ int memory_locked; /* Amount of resource bytes in locked memory */
+ int memory_lru; /* Amount of resource bytes under LRU control */
+
+ char *resource_path; /* Path to the resource and patch files */
+
+ resource_t *lru_first, *lru_last; /* Pointers to the first and last LRU queue entries */
+ /* LRU queue: lru_first points to the most recent entry */
+
+ unsigned char allow_patches;
+} resource_mgr_t;
+
+/**** FUNCTION DECLARATIONS ****/
+
+/**--- New Resource manager ---**/
+
+resource_mgr_t *
+scir_new_resource_manager(char *dir, int version, char allow_patches, int max_memory);
+/* Creates a new FreeSCI resource manager
+** Parameters: (char *) dir: Path to the resource and patch files (not modified or freed
+** by the resource manager)
+** (int) version: The SCI version to look for; use SCI_VERSION_AUTODETECT
+** in the default case.
+** (char ) allow_patches: Set to 1 if external patches (those look like
+** "view.101" or "script.093") should be applied
+** (int) max_memory: Maximum number of bytes to allow allocated for resources
+** Returns : (resource_mgr_t *) A newly allocated resource manager
+** max_memory will not be interpreted as a hard limit, only as a restriction for resources
+** which are not explicitly locked. However, a warning will be issued whenever this limit
+** is exceeded.
+*/
+
+resource_source_t *
+scir_add_patch_dir(resource_mgr_t *mgr, int type, char *path);
+/* Add a path to the resource manager's list of sources.
+** Parameters: (resource_mgr_t *) mgr: The resource manager to look up in
+** (int) dirtype: The type of patch directory to add,
+** either RESSOURCE_TYPE_DIRECTORY or RESSOURCE_TYPE_AUDIO_DIRECTORY
+** (char *) path: The path to add
+** Returns: A pointer to the added source structure, or NULL if an error occurred.
+*/
+
+resource_source_t *
+scir_get_volume(resource_mgr_t *mgr, resource_source_t *map, int volume_nr);
+
+resource_source_t *
+scir_add_volume(resource_mgr_t *mgr, resource_source_t *map, char *filename,
+ int number, int extended_addressing);
+/* Add a volume to the resource manager's list of sources.
+** Parameters: (resource_mgr_t *) mgr: The resource manager to look up in
+** (resource_source_t *) map: The map associated with this volume
+** (char *) filename: The name of the volume to add
+** (int) extended_addressing: 1 if this volume uses extended addressing,
+** 0 otherwise.
+** Returns: A pointer to the added source structure, or NULL if an error occurred.
+*/
+
+resource_source_t *
+scir_add_external_map(resource_mgr_t *mgr, char *file_name);
+/* Add an external (i.e. separate file) map resource to the resource manager's list of sources.
+** Parameters: (resource_mgr_t *) mgr: The resource manager to look up in
+** (char *) file_name: The name of the volume to add
+** Returns: A pointer to the added source structure, or NULL if an error occurred.
+*/
+
+resource_source_t *
+scir_add_internal_map(resource_mgr_t *mgr, resource_t *map);
+/* Add an internal (i.e. a resource) map resource to the resource manager's list of sources.
+** Parameters: (resource_mgr_t *) mgr: The resource manager to look up in
+** (char *) file_name: The name of the volume to add
+** Returns: A pointer to the added source structure, or NULL if an error occurred.
+*/
+
+int
+scir_scan_new_sources(resource_mgr_t *mgr, int *detected_version);
+/* Scans newly registered resource sources for resources, earliest addition first.
+** Parameters: (resource_mgr_t *) mgr: The resource manager to look up in
+** (int *) detected_version: Pointer to the detected version number,
+** used during startup. May be NULL.
+** Returns: One of SCI_ERROR_*.
+*/
+
+resource_t *
+scir_find_resource(resource_mgr_t *mgr, int type, int number, int lock);
+/* Looks up a resource's data
+** Parameters: (resource_mgr_t *) mgr: The resource manager to look up in
+** (int) type: The resource type to look for
+** (int) number: The resource number to search
+** (int) lock: non-zero iff the resource should be locked
+** Returns : (resource_t *): The resource, or NULL if it doesn't exist
+** Locked resources are guaranteed not to have their contents freed until
+** they are unlocked explicitly (by scir_unlock_resource).
+*/
+
+void
+scir_unlock_resource(resource_mgr_t *mgr, resource_t *res, int restype, int resnum);
+/* Unlocks a previously locked resource
+** Parameters: (resource_mgr_t *) mgr: The manager the resource should be freed from
+** (resource_t *) res: The resource to free
+** (int) type: Type of the resource to check (for error checking)
+** (int) number: Number of the resource to check (ditto)
+** Returns : (void)
+*/
+
+resource_t *
+scir_test_resource(resource_mgr_t *mgr, int type, int number);
+/* Tests whether a resource exists
+** Parameters: (resource_mgr_t *) mgr: The resource manager to search in
+** (int) type: Type of the resource to check
+** (int) number: Number of the resource to check
+** Returns : (resource_t *) non-NULL if the resource exists, NULL otherwise
+** This function may often be much faster than finding the resource
+** and should be preferred for simple tests.
+** The resource object returned is, indeed, the resource in question, but
+** it should be used with care, as it may be unallocated.
+** Use scir_find_resource() if you want to use the data contained in the resource.
+*/
+
+void
+scir_free_resource_manager(resource_mgr_t *mgr);
+/* Frees a resource manager and all memory handled by it
+** Parameters: (resource_mgr_t *) mgr: The Manager to free
+** Returns : (void)
+*/
+
+/**--- Resource map decoding functions ---*/
+
+int
+sci0_read_resource_map(resource_mgr_t *mgr, resource_source_t *map, resource_t **resources, int *resource_nr_p, int *sci_version);
+/* Reads the SCI0 resource.map file from a local directory
+** Parameters: (char *) path: (unused)
+** (resource_t **) resources: Pointer to a pointer
+** that will be set to the
+** location of the resources
+** (in one large chunk)
+** (int *) resource_nr_p: Pointer to an int the number of resources
+** read is stored in
+** (int) sci_version: SCI resource version
+** Returns : (int) 0 on success, an SCI_ERROR_* code otherwise
+*/
+
+int
+sci1_read_resource_map(resource_mgr_t *mgr, resource_source_t *map, resource_source_t *vol,
+ resource_t **resource_p, int *resource_nr_p, int *sci_version);
+/* Reads the SCI1 resource.map file from a local directory
+** Parameters: (char *) path: (unused)
+** (resource_t **) resources: Pointer to a pointer
+** that will be set to the
+** location of the resources
+** (in one large chunk)
+** (int *) resource_nr_p: Pointer to an int the number of resources
+** read is stored in
+** (int) sci_version: SCI resource version
+** Returns : (int) 0 on success, an SCI_ERROR_* code otherwise
+*/
+
+/**--- Patch management functions ---*/
+
+void
+sci0_sprintf_patch_file_name(char *string, resource_t *res);
+/* Prints the name of a matching patch to a string buffer
+** Parameters: (char *) string: The buffer to print to
+** (resource_t *) res: Resource containing the number and type of the
+** resource whose name is to be print
+** Returns : (void)
+*/
+
+void
+sci1_sprintf_patch_file_name(char *string, resource_t *res);
+/* Prints the name of a matching patch to a string buffer
+** Parameters: (char *) string: The buffer to print to
+** (resource_t *) res: Resource containing the number and type of the
+** resource whose name is to be print
+** Returns : (void)
+*/
+
+int
+sci0_read_resource_patches(resource_source_t *source, resource_t **resources, int *resource_nr_p);
+/* Reads SCI0 patch files from a local directory
+** Parameters: (char *) path: (unused)
+** (resource_t **) resources: Pointer to a pointer
+** that will be set to the
+** location of the resources
+** (in one large chunk)
+** (int *) resource_nr_p: Pointer to an int the number of resources
+** read is stored in
+** Returns : (int) 0 on success, an SCI_ERROR_* code otherwise
+*/
+
+int
+sci1_read_resource_patches(resource_source_t *source, resource_t **resources, int *resource_nr_p);
+/* Reads SCI1 patch files from a local directory
+** Parameters: (char *) path: (unused)
+** (resource_t **) resources: Pointer to a pointer
+** that will be set to the
+** location of the resources
+** (in one large chunk)
+** (int *) resource_nr_p: Pointer to an int the number of resources
+** read is stored in
+** Returns : (int) 0 on success, an SCI_ERROR_* code otherwise
+*/
+
+
+/**--- Decompression functions ---**/
+
+
+int decompress0(resource_t *result, int resh, int sci_version);
+/* Decrypts resource data and stores the result for SCI0-style compression.
+** Parameters : result: The resource_t the decompressed data is stored in.
+** resh : File handle of the resource file
+** sci_version : Actual SCI resource version
+** Returns : (int) 0 on success, one of SCI_ERROR_* if a problem was
+** encountered.
+*/
+
+int decompress01(resource_t *result, int resh, int sci_version);
+/* Decrypts resource data and stores the result for SCI01-style compression.
+** Parameters : result: The resource_t the decompressed data is stored in.
+** resh : File handle of the resource file
+** sci_version : Actual SCI resource version
+** Returns : (int) 0 on success, one of SCI_ERROR_* if a problem was
+** encountered.
+*/
+
+int decompress1(resource_t *result, int resh, int sci_version);
+/* Decrypts resource data and stores the result for SCI1.1-style compression.
+** Parameters : result: The resource_t the decompressed data is stored in.
+** sci_version : Actual SCI resource version
+** resh : File handle of the resource file
+** Returns : (int) 0 on success, one of SCI_ERROR_* if a problem was
+** encountered.
+*/
+
+
+int decompress11(resource_t *result, int resh, int sci_version);
+/* Decrypts resource data and stores the result for SCI1.1-style compression.
+** Parameters : result: The resource_t the decompressed data is stored in.
+** sci_version : Actual SCI resource version
+** resh : File handle of the resource file
+** Returns : (int) 0 on success, one of SCI_ERROR_* if a problem was
+** encountered.
+*/
+
+
+int decrypt2(guint8* dest, guint8* src, int length, int complength);
+/* Huffman token decryptor - defined in decompress0.c and used in decompress01.c
+*/
+
+int decrypt4(guint8* dest, guint8* src, int length, int complength);
+/* DCL inflate- implemented in decompress1.c
+*/
+
+byte *view_reorder(byte *inbuffer, int dsize);
+/* SCI1 style view compression */
+
+byte *pic_reorder(byte *inbuffer, int dsize);
+/* SCI1 style pic compression */
+
+/*--- Internal helper functions ---*/
+
+void
+_scir_free_resources(resource_t *resources, int resources_nr);
+/* Frees a block of resources and associated data
+** Parameters: (resource_t *) resources: The resources to free
+** (int) resources_nr: Number of resources in the block
+** Returns : (void)
+*/
+
+resource_t *
+_scir_find_resource_unsorted(resource_t *res, int res_nr, int type, int number);
+/* Finds a resource matching type.number in an unsorted resource_t block
+** To be used during initial resource loading, when the resource list
+** may not have been sorted yet.
+** Parameters: (resource_t *) res: Pointer to the block to search in
+** (int) res_nr: Number of resource_t structs allocated and defined
+** in the block pointed to by res
+** (int) type: Type of the resource to look for
+** (int) number: Number of the resource to look for
+** Returns : (resource_t) The matching resource entry, or NULL if not found
+*/
+
+void
+_scir_add_altsource(resource_t *res, resource_source_t *source, unsigned int file_offset);
+/* Adds an alternative source to a resource
+** Parameters: (resource_t *) res: The resource to add to
+** (resource_source_t *) source: The source of the resource
+** (unsigned int) file_offset: Offset in the file the resource
+** is stored at
+** Retruns : (void)
+*/
+
+
+/**** Internal #defines ****/
+
+#define SCI_RESOURCE_FILE_PATCH -1 /* Identifies resources read from patches */
+
+/* Resource type encoding */
+#define SCI0_B1_RESTYPE_MASK 0xf8
+#define SCI0_B1_RESTYPE_SHIFT 3
+#define SCI0_B3_RESFILE_MASK 0xfc
+#define SCI0_B3_RESFILE_SHIFT 2
+#define SCI01V_B3_RESFILE_MASK 0xf0
+#define SCI01V_B3_RESFILE_SHIFT 4
+
+#define SCI0_RESID_GET_TYPE(bytes) \
+ (((bytes)[1] & SCI0_B1_RESTYPE_MASK) >> SCI0_B1_RESTYPE_SHIFT)
+#define SCI0_RESID_GET_NUMBER(bytes) \
+ ((((bytes)[1] & ~SCI0_B1_RESTYPE_MASK) << 8) | ((bytes)[0]))
+
+#define SCI0_RESFILE_GET_FILE(bytes) \
+ (((bytes)[3] & SCI0_B3_RESFILE_MASK) >> SCI0_B3_RESFILE_SHIFT)
+#define SCI0_RESFILE_GET_OFFSET(bytes) \
+ ((((bytes)[3] & ~SCI0_B3_RESFILE_MASK) << 24) \
+ | (((bytes)[2]) << 16) \
+ | (((bytes)[1]) << 8) \
+ | (((bytes)[0]) << 0))
+
+#define SCI01V_RESFILE_GET_FILE(bytes) \
+ (((bytes)[3] & SCI01V_B3_RESFILE_MASK) >> SCI01V_B3_RESFILE_SHIFT)
+#define SCI01V_RESFILE_GET_OFFSET(bytes) \
+ ((((bytes)[3] & ~SCI01V_B3_RESFILE_MASK) << 24) \
+ | (((bytes)[2]) << 16) \
+ | (((bytes)[1]) << 8) \
+ | (((bytes)[0]) << 0))
+
+#define SCI1_B5_RESFILE_MASK 0xf0
+#define SCI1_B5_RESFILE_SHIFT 4
+
+#define SCI1_RESFILE_GET_FILE(bytes) \
+ (((bytes)[5] & SCI1_B5_RESFILE_MASK) >> SCI1_B5_RESFILE_SHIFT)
+
+#define SCI1_RESFILE_GET_OFFSET(bytes) \
+ ((((bytes)[5] & ~SCI1_B5_RESFILE_MASK) << 24) \
+ | (((bytes)[4]) << 16) \
+ | (((bytes)[3]) << 8) \
+ | (((bytes)[2]) << 0))
+
+#define SCI1_RESFILE_GET_NUMBER(bytes) \
+ ((((bytes)[1]) << 8) \
+ | (((bytes)[0]) << 0))
+
+#define SCI11_RESFILE_GET_OFFSET(bytes) \
+ ((((bytes)[4]) << 17) \
+ | (((bytes)[3]) << 9) \
+ | (((bytes)[2]) << 1))
+
+#endif
+
+
+
diff --git a/engines/sci/include/scitypes.h b/engines/sci/include/scitypes.h
new file mode 100644
index 0000000000..b252d59565
--- /dev/null
+++ b/engines/sci/include/scitypes.h
@@ -0,0 +1,155 @@
+/***************************************************************************
+ scitypes.h Copyright (C) 2001 Christoph Reichenbach
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) [creichen@rbg.informatik.tu-darmstadt.de]
+
+***************************************************************************/
+
+#ifndef SCI_TYPES
+#define SCI_TYPES
+
+#ifdef SCUMMVM
+
+#include "common/scummsys.h"
+
+// TODO: rework sci_dir_t to use common/fs.h and remove these includes
+#include <sys/types.h>
+#include <dirent.h>
+
+typedef int8 gint8;
+typedef uint8 guint8;
+
+typedef int16 gint16;
+typedef uint16 guint16;
+
+typedef int32 gint32;
+typedef uint32 guint32;
+
+#undef byte
+
+#else // SCUMMVM
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_DIRENT_H
+# include <sys/types.h>
+# include <dirent.h>
+#endif
+#ifdef _WIN32
+# include <io.h>
+# include <sci_win32.h>
+#endif
+#ifdef _DREAMCAST
+# include <stdio.h>
+#endif
+
+#if defined(_WIN32) && defined(_MSC_VER)
+# define TYPE_16 short
+# define TYPE_32 int
+#endif
+
+#ifndef TYPE_8
+# define TYPE_8 char /* Guaranteed by ISO */
+#endif
+
+#ifndef TYPE_16
+# if (SIZEOF_SHORT == 2)
+# define TYPE_16 short
+# elif (SIZEOF_INT == 2)
+# define TYPE_16 int
+# else
+# error "Could not find a 16 bit data type!"
+# endif
+#endif /* !TYPE_16 */
+
+#ifndef TYPE_32
+# if (SIZEOF_INT == 4)
+# define TYPE_32 int
+# elif (SIZEOF_LONG == 4)
+# define TYPE_32 long
+# else
+# error "Could not find a 32 bit data type!"
+# endif
+#endif /* !TYPE_32 */
+
+typedef signed TYPE_8 gint8;
+typedef unsigned TYPE_8 guint8;
+
+typedef signed TYPE_16 gint16;
+typedef unsigned TYPE_16 guint16;
+
+typedef signed TYPE_32 gint32;
+typedef unsigned TYPE_32 guint32;
+
+#undef TYPE_8
+#undef TYPE_16
+#undef TYPE_32
+
+#endif // SCUMMVM
+
+typedef gint8 sbyte;
+typedef guint8 byte;
+typedef guint16 word;
+
+typedef struct {
+ long tv_sec;
+ long tv_usec;
+} GTimeVal;
+
+typedef struct {
+#ifdef _MSC_VER
+ long search;
+ struct _finddata_t fileinfo;
+#else
+ DIR *dir;
+ char *mask_copy;
+#endif
+} sci_dir_t; /* used by sci_find_first and friends */
+
+/*
+ * Fixed point type, borrowed from ScummVM.
+ * The precision of the fractional (fixed point) type we define below.
+ * Normally you should never have to modify this value.
+ */
+enum {
+ FRAC_BITS = 16,
+ FRAC_LO_MASK = ((1L << FRAC_BITS) - 1),
+ FRAC_HI_MASK = (((1L << (32 - FRAC_BITS)) - 1) << FRAC_BITS),
+
+ FRAC_ONE = (1L << FRAC_BITS), // 1.0
+ FRAC_HALF = (1L << (FRAC_BITS-1)) // 0.5
+};
+
+/*
+ * Fixed-point fractions, used by the sound rate converter and other code.
+ */
+typedef gint32 frac_t;
+
+static inline frac_t double_to_frac(double value) { return (frac_t)(value * FRAC_ONE); }
+static inline double frac_to_double(frac_t value) { return ((double)value) / FRAC_ONE; }
+
+static inline frac_t int_to_frac(gint32 value) { return value << FRAC_BITS; }
+static inline gint32 frac_to_int(frac_t value) { return value >> FRAC_BITS; }
+
+#endif /* !SCI_TYPES */
diff --git a/engines/sci/include/script.h b/engines/sci/include/script.h
new file mode 100644
index 0000000000..f979bd2a1e
--- /dev/null
+++ b/engines/sci/include/script.h
@@ -0,0 +1,214 @@
+/***************************************************************************
+ script.h Copyright (C) 2000,01 Magnus Reftel
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+***************************************************************************/
+
+#ifndef SCRIPT_H
+#define SCRIPT_H
+
+#include <sciresource.h>
+
+/*#define SCRIPT_DEBUG */
+
+#define SCI_SCRIPTS_NR 1000
+
+typedef struct script_opcode_
+{
+ unsigned opcode;
+ int arg1, arg2, arg3;
+ int pos, size;
+} script_opcode;
+
+
+typedef enum {
+ sci_obj_terminator,
+ sci_obj_object,
+ sci_obj_code,
+ sci_obj_synonyms,
+ sci_obj_said,
+ sci_obj_strings,
+ sci_obj_class,
+ sci_obj_exports,
+ sci_obj_pointers,
+ sci_obj_preload_text, /* This is really just a flag. */
+ sci_obj_localvars
+} script_object_types;
+
+void script_dissect(resource_mgr_t *resmgr, int res_no, char **snames, int snames_nr);
+
+/* Opcode formats as used by script.c */
+typedef enum {
+ Script_Invalid=-1,
+ Script_None=0,
+ Script_Byte,
+ Script_SByte,
+ Script_Word,
+ Script_SWord,
+ Script_Variable,
+ Script_SVariable,
+ Script_SRelative,
+ Script_Property,
+ Script_Global,
+ Script_Local,
+ Script_Temp,
+ Script_Param,
+ Script_Offset,
+ Script_End
+} opcode_format;
+
+typedef enum { /* FIXME */
+ op_bnot = 0,
+ op_add,
+ op_sub,
+ op_mul,
+ op_div,
+ op_mod,
+ op_shr,
+ op_shl,
+ op_xor,
+ op_and,
+ op_or,
+ op_neg,
+ op_not,
+ op_eq,
+ op_ne_,
+ op_gt_,
+ op_ge_,
+ op_lt_,
+ op_le_,
+ op_ugt_,
+ op_uge_,
+ op_ult_,
+ op_ule_,
+ op_bt,
+ op_bnt,
+ op_jmp,
+ op_ldi,
+ op_push,
+ op_pushi,
+ op_toss,
+ op_dup,
+ op_link,
+ op_call = 0x20,
+ op_callk,
+ op_callb,
+ op_calle,
+ op_ret,
+ op_send,
+ op_class = 0x28,
+ op_self = 0x2a,
+ op_super,
+ op_rest,
+ op_lea,
+ op_selfID,
+ op_pprev = 0x30,
+ op_pToa,
+ op_aTop,
+ op_pTos,
+ op_sTop,
+ op_ipToa,
+ op_dpToa,
+ op_ipTos,
+ op_dpTos,
+ op_lofsa,
+ op_lofss,
+ op_push0,
+ op_push1,
+ op_push2,
+ op_pushSelf,
+ op_lag = 0x40,
+ op_lal,
+ op_lat,
+ op_lap,
+ op_lagi,
+ op_lali,
+ op_lati,
+ op_lapi,
+ op_lsg,
+ op_lsl,
+ op_lst,
+ op_lsp,
+ op_lsgi,
+ op_lsli,
+ op_lsti,
+ op_lspi,
+ op_sag,
+ op_sal,
+ op_sat,
+ op_sap,
+ op_sagi,
+ op_sali,
+ op_sati,
+ op_sapi,
+ op_ssg,
+ op_ssl,
+ op_sst,
+ op_ssp,
+ op_ssgi,
+ op_ssli,
+ op_ssti,
+ op_sspi,
+ op_plusag,
+ op_plusal,
+ op_plusat,
+ op_plusap,
+ op_plusagi,
+ op_plusali,
+ op_plusati,
+ op_plusapi,
+ op_plussg,
+ op_plussl,
+ op_plusst,
+ op_plussp,
+ op_plussgi,
+ op_plussli,
+ op_plussti,
+ op_plusspi,
+ op_minusag,
+ op_minusal,
+ op_minusat,
+ op_minusap,
+ op_minusagi,
+ op_minusali,
+ op_minusati,
+ op_minusapi,
+ op_minussg,
+ op_minussl,
+ op_minusst,
+ op_minussp,
+ op_minussgi,
+ op_minussli,
+ op_minussti,
+ op_minusspi
+} sci_opcodes;
+
+extern DLLEXTERN opcode_format formats[128][4];
+
+void script_adjust_opcode_formats(int res_version);
+
+int
+script_find_selector(struct _state *s, const char *selector_name);
+/* Determines the selector ID of a selector by its name
+** Parameters: (state_t *) s: VM state
+** (char *) selector_name: Name of the selector to look up
+** Returns : (int) The appropriate selector ID, or -1 on error
+*/
+
+struct _state;
+void script_free_breakpoints(struct _state *s);
+
+#endif
diff --git a/engines/sci/include/seg_manager.h b/engines/sci/include/seg_manager.h
new file mode 100644
index 0000000000..600792568e
--- /dev/null
+++ b/engines/sci/include/seg_manager.h
@@ -0,0 +1,627 @@
+/***************************************************************************
+ seg_manager.h Copyright (C) 2002 Xiaojun Chen, Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+
+#ifndef _SCI_SEG_MANAGER_H
+#define _SCI_SEG_MANAGER_H
+
+#include <int_hashmap.h>
+#include <sys_strings.h>
+#include <vm.h>
+
+#define DEFAULT_SCRIPTS 32
+#define DEFAULT_OBJECTS 8 /* default # of objects per script */
+#define DEFAULT_OBJECTS_INCREMENT 4 /* Number of additional objects to
+ ** instantiate if we're running out of them */
+
+/* SCRIPT_ID must be 0 */
+typedef enum {
+ SCRIPT_ID,
+ SEG_ID
+} id_flag;
+
+//void dbg_print( const char* msg, void *i ); /* for debug only */
+
+/* verify the the given condition is true, output the message if condition is false, and exit
+** Parameters:
+** cond - condition to be verified
+** msg - the message to be printed if condition fails
+** return:
+** none, terminate the program if fails
+*/
+#define VERIFY( cond, msg ) if (! ( cond ) ) {\
+ sciprintf( "%s, line, %d, %s\n", __FILE__, __LINE__, msg ); \
+ BREAKPOINT(); \
+ }
+
+
+#define MEM_OBJ_INVALID 0
+#define MEM_OBJ_SCRIPT 1
+#define MEM_OBJ_CLONES 2
+#define MEM_OBJ_LOCALS 3
+#define MEM_OBJ_STACK 4
+#define MEM_OBJ_SYS_STRINGS 5
+#define MEM_OBJ_LISTS 6
+#define MEM_OBJ_NODES 7
+#define MEM_OBJ_HUNK 8
+#define MEM_OBJ_DYNMEM 9
+#define MEM_OBJ_RESERVED 10
+#define MEM_OBJ_MAX MEM_OBJ_RESERVED /* For sanity checking */
+typedef int mem_obj_enum;
+
+struct _mem_obj;
+
+#define GET_SEGMENT(mgr, index, rtype) ((index) > 0 && (mgr).heap_size > index)? \
+ (((mgr).heap[index] && (mgr).heap[index]->type == rtype)? (mgr).heap[index] \
+ : NULL) /* Type does not match */ \
+ : NULL /* Invalid index */
+
+#define GET_SEGMENT_ANY(mgr, index) ((index) > 0 && (mgr).heap_size > index)? \
+ (((mgr).heap[index])? (mgr).heap[index] \
+ : NULL) /* Type does not match */ \
+ : NULL /* Invalid index */
+
+#define GET_OBJECT_SEGMENT(mgr, index) ((index) > 0 && (mgr).heap_size > index)? \
+ (((mgr).heap[index] \
+ && ((mgr).heap[index]->type == MEM_OBJ_SCRIPT \
+ || (mgr).heap[index]->type == MEM_OBJ_CLONES))? (mgr).heap[index] \
+ : NULL) /* Type does not match */ \
+ : NULL /* Invalid index */
+
+
+typedef struct _seg_manager_t {
+ int_hash_map_t* id_seg_map; /* id - script id; seg - index of heap */
+ struct _mem_obj** heap;
+ int heap_size; /* size of the heap */
+ int reserved_id;
+ int exports_wide;
+ int sci1_1;
+
+ int gc_mark_bits; /* For standard Mark&Sweep:
+ ** 1 or 0, depending on what unreachable/freshly allocated
+ ** memory is tagged as */
+ size_t mem_allocated; /* Total amount of memory allocated */
+
+ seg_id_t clones_seg_id; /* ID of the (a) clones segment */
+ seg_id_t lists_seg_id; /* ID of the (a) list segment */
+ seg_id_t nodes_seg_id; /* ID of the (a) node segment */
+ seg_id_t hunks_seg_id; /* ID of the (a) hunk segment */
+} seg_manager_t;
+
+
+
+/*==============================================================*/
+/* Toplevel functionality */
+/*==============================================================*/
+void
+sm_init (seg_manager_t* self, int sci1_1);
+/* Initialize the segment manager
+*/
+
+void
+sm_destroy (seg_manager_t* self);
+/* Deallocate all memory associated with the segment manager
+*/
+
+void
+sm_gc(seg_manager_t *self, struct _state *s);
+/* Perform garbage collection
+** Parameters: (state_t *) s: The state to operate on
+** Effects : Unreachable objects in 's' are deallocated
+*/
+
+
+
+/*==============================================================*/
+/* 1. Scripts */
+/*==============================================================*/
+
+
+void
+sm_free_script ( mem_obj_t* mem );
+
+mem_obj_t*
+sm_allocate_script(struct _seg_manager_t* self, struct _state *s, int script_nr, int* seg_id);
+/* Allocate a script into the segment manager
+** Parameters: (int) script_nr: number of the script to load
+** (state_t *) s: The state containing resource manager handlers to load the
+** script data
+** Returns : (int) 0 on failure, 1 on success
+** (int) *seg_id: The segment ID of the newly allocated segment, on success
+
+** The script must then be initialised; see section (1b.), below.
+*/
+
+int
+sm_deallocate_script(struct _seg_manager_t* self, int script_nr);
+/* Forcefully deallocate a previously allocated script
+** Parameters: (int) script_nr: number of the script to deallocate
+** Returns : (int) 1 on success, 0 on failure
+*/
+
+int
+sm_script_is_loaded(struct _seg_manager_t* self, int id, id_flag flag);
+/* Determines whether a script has been loaded yet
+** Parameters: (int) id: number of the script or ID of the script segment to check for
+** (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
+** by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+** but less convenient.
+*/
+
+guint16
+sm_validate_export_func(struct _seg_manager_t* self, int pubfunct, int seg);
+/* Validate whether the specified public function is exported by the script in the specified segment
+** Parameters: (int) pubfunct: Index of the function to validate
+** (int) seg: Segment ID of the script the check is to be performed for
+** Returns : (guint16) 0 if the public function is invalid, its offset into the script's segment
+** otherwise
+**/
+
+int
+sm_seg_get (seg_manager_t* self, int script_nr);
+/* Get the segment ID associated with a script number
+** Parameters: (int) script_nr: Number of the script to look up
+** Returns : (int) The associated segment ID, or -1 if no matching segment exists
+** This function is "pure" (i.e, it doesn't modify anything).
+*/
+
+
+/**************************/
+/* script lock operations */
+/**************************/
+
+void
+sm_increment_lockers(struct _seg_manager_t* self, int id, id_flag flag);
+/* Increments the number of lockers of the script in question by one
+** Parameters: (int) id: ID of the script or script segment to modify
+** (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
+** by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+** but less convenient.
+*/
+
+void
+sm_decrement_lockers(struct _seg_manager_t* self, int id, id_flag flag);
+/* Decrements the number of lockers of the script in question by one
+** Parameters: (int) id: ID of the script or script segment to modify
+** (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
+** by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+** but less convenient.
+*/
+
+int
+sm_get_lockers(struct _seg_manager_t* self, int id, id_flag flag);
+/* Retrieves the number of locks held on this script
+** Parameters: (int) id: ID of the script or script segment to read from
+** (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
+** by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+** but less convenient.
+** Returns : (int) The number of locks held on the previously identified script
+*/
+
+void
+sm_set_lockers(struct _seg_manager_t* self, int lockers, int id, id_flag flag);
+/* Sets the number of locks held on the specified script
+** Parameters: (int) id: ID of the script or script segment to modify
+** (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
+** by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+** but less convenient.
+*/
+
+byte *
+sm_get_synonyms (struct _seg_manager_t* self, int id, id_flag flag);
+/* Retrieves a pointer to the synonyms associated with the specified script
+** Parameters: (int) id: ID of the script or script segment to read from
+** (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
+** by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+** but less convenient.
+** Returns : (byte *) Pointer to the synonyms, in non-parsed format.
+** A dynamic failure is issued if the specified ID does not reference a proper script.
+*/
+
+int
+sm_get_synonyms_nr (struct _seg_manager_t* self, int id, id_flag flag);
+/* Retrieves the number of synonyms associated with the specified script
+** Parameters: (int) id: ID of the script or script segment to read from
+** (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
+** by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+** but less convenient.
+** Returns : (int) The number of synonyms associated with the specified script
+** A dynamic failure is issued if the specified ID does not reference a proper script.
+*/
+
+
+/*==============================================================*/
+/* 1b. Script Initialisation */
+/*==============================================================*/
+
+/*******************************************/
+/* The set of functions below are intended */
+/* to be used during script instantiation, */
+/* i.e. loading and linking. */
+/*******************************************/
+
+void
+sm_script_initialise_locals_zero(struct _seg_manager_t *self, seg_id_t seg, int nr);
+/* Initializes a script's local variable block
+** Parameters: (seg_id_t) seg: Segment containing the script to initialize
+** (int) nr: Number of local variables to allocate
+** All variables are initialized to zero.
+*/
+
+void
+sm_script_initialise_locals(struct _seg_manager_t *self, reg_t location);
+/* Initializes a script's local variable block according to a prototype
+** Parameters: (reg_t) location: Location to initialize from
+*/
+
+object_t *
+sm_script_obj_init(seg_manager_t *self, struct _state *s, reg_t obj_pos);
+/* Initializes an object within the segment manager
+** Parameters: (reg_t) obj_pos: Location (segment, offset) of the object
+** Returns : (object_t *) A newly created object_t describing the object
+** obj_pos must point to the beginning of the script/class block (as opposed
+** to what the VM considers to be the object location)
+** The corresponding object_t is stored within the relevant script.
+*/
+
+void
+sm_script_add_code_block(struct _seg_manager_t* self, reg_t location);
+/* Informs the segment manager that a code block must be relocated
+** Parameters: (reg_t) location: Start of block to relocate
+*/
+
+void
+sm_set_export_width(struct _seg_manager_t* self, int flag);
+/* Tells the segment manager whether exports are wide (32-bit) or not.
+** Parameters: (int) flag: 1 if exports are wide, 0 otherwise */
+
+void
+sm_script_relocate(struct _seg_manager_t* self, reg_t block);
+/* Processes a relocation block witin a script
+** Parameters: (reg_t) obj_pos: Location (segment, offset) of the block
+** Returns : (object_t *) Location of the relocation block
+** This function is idempotent, but it must only be called after all
+** objects have been instantiated, or a run-time error will occur.
+*/
+
+void
+sm_script_free_unused_objects(struct _seg_manager_t *self, seg_id_t segid);
+/* Deallocates all unused but allocated entries for objects
+** Parameters: (seg_id_t) segid: segment of the script to prune in this way
+** These entries are created during script instantiation; deallocating them
+** frees up some additional memory.
+*/
+
+void
+sm_set_export_table_offset (struct _seg_manager_t* self, int offset, int id, id_flag flag);
+/* Sets the script-relative offset of the exports table
+** Parameters: (int) offset: The script-relative exports table offset
+** (int) id: ID of the script or script segment to write to
+** (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
+** by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+** but less convenient.
+** A dynamic failure is issued if the specified ID does not reference a proper script.
+*/
+
+void
+sm_set_synonyms_offset (struct _seg_manager_t* self, int offset, int id, id_flag flag);
+/* Sets the script-relative offset of the synonyms associated with the specified script
+** Parameters: (int) offset: The script-relative offset of the synonyms block
+** (int) id: ID of the script or script segment to write to
+** (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
+** by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+** but less convenient.
+** A dynamic failure is issued if the specified ID does not reference a proper script.
+*/
+
+void
+sm_set_synonyms_nr (struct _seg_manager_t* self, int nr, int id, id_flag flag);
+/* Sets the number of synonyms associated with the specified script
+** Parameters: (int) nr: The number of synonyms, as to be stored within the script
+** (int) id: ID of the script or script segment to write to
+** (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
+** by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+** but less convenient.
+** A dynamic failure is issued if the specified ID does not reference a proper script.
+*/
+
+void
+sm_mark_script_deleted(seg_manager_t* self, int script_nr);
+/* Marks the script identified by its script number as deleted
+** Parameters: (int) script_nr: Script number to mark as deleted
+** This will not actually delete the script. If references remain present on the
+** heap or the stack, the script will stay in memory in a quasi-deleted state until
+** either unreachable (resulting in its eventual deletion) or reloaded (resulting
+** in its data being updated).
+*/
+
+void
+sm_unmark_script_deleted(seg_manager_t* self, int script_nr);
+/* Marks the script identified by its script number as not deleted
+** Parameters: (int) script_nr: Script number to mark as not deleted
+*/
+
+int
+sm_script_is_marked_as_deleted(seg_manager_t* self, seg_id_t seg);
+/* Determines whether the script referenced by the indicated segment is marked as being deleted.
+** Parameters: (seg_id_t) Segment ID of the script to investigate
+** Returns : (int) 1 iff seg points to a script and the segment is deleted, 0 otherwise
+** Will return 0 when applied to an invalid or non-script seg.
+*/
+
+
+
+/*==============================================================*/
+/* 2. Clones */
+/*==============================================================*/
+
+clone_t*
+sm_alloc_clone(struct _seg_manager_t *self, reg_t *addr);
+/* Allocate a fresh clone
+** Returns : (clone_t*): Reference to the memory allocated for the clone
+** (reg_t) *addr: The offset of the freshly allocated clone
+*/
+
+void
+sm_free_clone(struct _seg_manager_t *self, reg_t addr);
+/* Deallocates a clone
+** Parameters: (reg_t) addr: Offset of the clone scheduled for termination
+*/
+
+
+
+/*==============================================================*/
+/* Objects (static, from Scripts, and dynmic, from Clones) */
+/*==============================================================*/
+
+/* Not all of these functions are fully operational for clones ATM */
+
+gint16
+sm_get_heap(struct _seg_manager_t* self, reg_t reg );
+/* Retrieves a 16 bit value from within a script's heap representation
+** Parameters: (reg_t) reg: The address to read from
+** Returns : (gint16) The value read from the specified location
+*/
+
+void
+sm_put_heap(struct _seg_manager_t* self, reg_t reg, gint16 value );
+/* Writes a 16 bit value into a script's heap representation
+** Parameters: (reg_t) reg: The address to write to
+** (gint16) value: The value to write
+*/
+
+void
+sm_mcpy_in_out (seg_manager_t* self, int dst, const void* src, size_t n, int id, int flag);
+/* Copies a byte string into a script's heap representation
+** Parameters: (int) dst: The script-relative offset of the destination area
+** (const void *) src: Pointer to the data source location
+** (size_t) n: Number of bytes to copy
+** (int) id: ID of the script or script segment to write to
+** (id_flag) flag: Whether to address the script by script number (SCRIPT_ID) or
+** by its segment (SEG_ID). SEG_ID is faster than SCRIPT_ID,
+** but less convenient.
+** A dynamic failure is issued if the specified ID does not reference a proper script.
+*/
+
+
+/*==============================================================*/
+/* 4. Stack */
+/*==============================================================*/
+
+dstack_t *
+sm_allocate_stack(struct _seg_manager_t *self, int size, seg_id_t *segid);
+/* Allocates a data stack
+** Parameters: (int) size: Number of stack entries to reserve
+** Returns : (dstack_t *): The physical stack
+** (seg_id_t) segid: Segment ID of the stack
+*/
+
+
+
+/*==============================================================*/
+/* 5. System Strings */
+/*==============================================================*/
+
+sys_strings_t *
+sm_allocate_sys_strings(struct _seg_manager_t *self, seg_id_t *segid);
+/* Allocates a system string table
+** Returns : (dstack_t *): The physical stack
+** (seg_id_t) segid: Segment ID of the stack
+** See also sys_string_acquire();
+*/
+
+
+
+/*==============================================================*/
+/* 6, 7. Lists and Nodes */
+/*==============================================================*/
+
+list_t*
+sm_alloc_list(struct _seg_manager_t *self, reg_t *addr);
+/* Allocate a fresh list
+** Returns : (listY_t*): Reference to the memory allocated for the list
+** (reg_t) *addr: The offset of the freshly allocated list
+*/
+
+void
+sm_free_list(struct _seg_manager_t *self, reg_t addr);
+/* Deallocates a list
+** Parameters: (reg_t) addr: Offset of the list scheduled for termination
+*/
+
+
+node_t*
+sm_alloc_node(struct _seg_manager_t *self, reg_t *addr);
+/* Allocate a fresh node
+** Returns : (node_t*): Reference to the memory allocated for the node
+** (reg_t) *addr: The offset of the freshly allocated node
+*/
+
+void
+sm_free_node(struct _seg_manager_t *self, reg_t addr);
+/* Deallocates a list node
+** Parameters: (reg_t) addr: Offset of the node scheduled for termination
+*/
+
+
+
+/*==============================================================*/
+/* 8. Hunk Memory */
+/*==============================================================*/
+
+hunk_t*
+sm_alloc_hunk_entry(struct _seg_manager_t *self, const char *hunk_type, int size, reg_t *addr);
+/* Allocate a fresh chunk of the hunk
+** Parameters: (int) size: Number of bytes to allocate for the hunk entry
+** (const char *) hunk_type: A descriptive string for the hunk entry,
+** for debugging purposes
+** Returns : (hunk_t*): Reference to the memory allocated for the hunk piece
+** (reg_t) *addr: The offset of the freshly allocated hunk entry
+*/
+
+void
+sm_free_hunk_entry(struct _seg_manager_t *self, reg_t addr);
+/* Deallocates a hunk eentry
+** Parameters: (reg_t) addr: Offset of the hunk entry to delete
+*/
+
+
+
+/*==============================================================*/
+/* 9. Dynamic Memory */
+/*==============================================================*/
+
+unsigned char *
+sm_alloc_dynmem(struct _seg_manager_t *self, int size, const char *description, reg_t *addr);
+/* Allocate some dynamic memory
+** Parameters: (int) size: Number of bytes to allocate
+** (const char_ *) description: A descriptive string,
+** for debugging purposes
+** Returns : (unsigned char*): Raw pointer into the allocated dynamic memory
+** (reg_t) *addr: The offset of the freshly allocated X
+*/
+
+int
+sm_free_dynmem(struct _seg_manager_t *self, reg_t addr);
+/* Deallocates a piece of dynamic memory
+** Parameters: (reg_t) addr: Offset of the dynmem chunk to free
+*/
+
+const char *
+sm_get_description(struct _seg_manager_t *self, reg_t addr);
+/* Gets the description of a dynmem segment
+** Parameters: (reg_t) addr: Segment to describe
+** Returns : (const char *): Pointer to the descriptive string set in
+** sm_alloc_dynmem
+*/
+
+/*==============================================================*/
+/* 10. Reserved segments */
+/*==============================================================*/
+
+seg_id_t
+sm_allocate_reserved_segment(struct _seg_manager_t *self, char *name);
+/* Reserves a special-purpose segment
+** Parameters: (char *) name: A string name identifying the segment (the string is cloned and retained)
+** Returns : A fresh segment ID for the segment in question
+** Reserved segments are never used by the segment manager. They can be used to tag special-purpose addresses.
+** Segment 0 is implicitly reserved for numbers.
+*/
+
+/*==============================================================*/
+/* Generic Operations on Segments and Addresses */
+/*==============================================================*/
+
+byte *
+sm_dereference(struct _seg_manager_t *self, reg_t reg, int *size);
+/* Dereferences a raw memory pointer
+** Parameters: (reg_t) reg: The reference to dereference
+** Returns : (byte *) The data block referenced
+** (int) size: (optionally) the theoretical maximum size of it
+*/
+
+
+/*==============================================================*/
+/* 11. Segment interface, primarily for GC */
+/*==============================================================*/
+
+typedef struct _seg_interface {
+ seg_manager_t *segmgr;
+ mem_obj_t *mobj;
+ seg_id_t seg_id;
+ mem_obj_enum type_id; /* Segment type */
+ const char *type; /* String description of the segment type */
+
+ reg_t
+ (*find_canonic_address)(struct _seg_interface *self, reg_t sub_addr);
+ /* Finds the canonic address associated with sub_reg
+ ** Parameters: (reg_t) sub_addr: The base address whose canonic address is to be found
+ ** For each valid address a, there exists a canonic address c(a) such that c(a) = c(c(a)).
+ ** This address "governs" a in the sense that deallocating c(a) will deallocate a.
+ */
+
+ void
+ (*free_at_address)(struct _seg_interface *self, reg_t sub_addr);
+ /* Deallocates all memory associated with the specified address
+ ** Parameters: (reg_t) sub_addr: The address (within the given segment) to deallocate
+ */
+
+ void
+ (*list_all_deallocatable)(struct _seg_interface *self, void *param, void (*note)(void *param, reg_t addr));
+ /* Iterates over and reports all addresses within the current segment
+ ** Parameters: note : (voidptr * addr) -> (): Invoked for each address on which free_at_address()
+ ** makes sense
+ ** (void *) param: Parameter passed to 'note'
+ */
+
+ void
+ (*list_all_outgoing_references)(struct _seg_interface *self, struct _state *s, reg_t object, void *param, void (*note)(void *param, reg_t addr));
+ /* Iterates over all references reachable from the specified object
+ ** Parameters: (reg_t) object: The object (within the current segment) to analyse
+ ** (void *) param: Parameter passed to 'note'
+ ** note : (voidptr * addr) -> (): Invoked for each outgoing reference within the object
+ ** Note: This function may also choose to report numbers (segment 0) as adresses
+ */
+
+ void
+ (*deallocate_self)(struct _seg_interface *self);
+ /* Deallocates the segment interface
+ */
+
+} seg_interface_t;
+
+seg_interface_t *
+get_seg_interface(seg_manager_t *self, seg_id_t segid);
+/* Retrieves the segment interface to the specified segment
+** Parameters: (seg_id_t) segid: ID of the segment to look up
+** Returns : (seg_interface_t *): An interface to the specified segment ID, or NULL on error
+** The returned interface 'si' must be freed after use by calling 'si->dealloc_self(si)';
+*/
+
+
+
+#endif
diff --git a/engines/sci/include/sfx_core.h b/engines/sci/include/sfx_core.h
new file mode 100644
index 0000000000..9a04e9f9e5
--- /dev/null
+++ b/engines/sci/include/sfx_core.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+ sfx_core.h Copyright (C) 2003,04 Christoph Reichenbach
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public Licence as
+ published by the Free Software Foundaton; either version 2 of the
+ Licence, or (at your option) any later version.
+
+ It is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ merchantibility or fitness for a particular purpose. See the
+ GNU General Public Licence for more details.
+
+ You should have received a copy of the GNU General Public Licence
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+
+ Please contact the maintainer for any program-related bug reports or
+ inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef _SFX_CORE_H_
+#define _SFX_CORE_H_
+
+#include <config.h>
+
+#define SFX_OK 0
+#define SFX_ERROR -1
+
+#define MIDI_CHANNELS 16
+
+#endif /* !defined(_SFX_CORE_H_) */
diff --git a/engines/sci/include/sfx_engine.h b/engines/sci/include/sfx_engine.h
new file mode 100644
index 0000000000..950f1e3dc8
--- /dev/null
+++ b/engines/sci/include/sfx_engine.h
@@ -0,0 +1,179 @@
+/***************************************************************************
+ sfx_engine.h Copyright (C) 2003,04 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+/* Sound engine */
+#ifndef _SFX_ENGINE_H_
+#define _SFX_ENGINE_H_
+
+#include <sfx_core.h>
+#include <sfx_songlib.h>
+#include <sfx_iterator.h>
+#include <sciresource.h>
+
+#define SOUND_TICK 1000000 / 60
+/* Approximately 16666 microseconds */
+
+
+#define SFX_STATE_FLAG_MULTIPLAY (1 << 0) /* More than one song playable
+ ** simultaneously ? */
+#define SFX_STATE_FLAG_NOSOUND (1 << 1) /* Completely disable sound playing */
+
+
+#define SFX_DEBUG_SONGS (1 << 0) /* Debug song changes */
+#define SFX_DEBUG_CUES (1 << 1) /* Debug cues, loops, and
+ ** song completions */
+
+typedef struct {
+ song_iterator_t *it; /* The song iterator at the heart of things */
+ unsigned int flags; /* SFX_STATE_FLAG_* */
+ songlib_t songlib; /* Song library */
+ song_t *song; /* Active song, or start of active song chain */
+ int suspended; /* Whether we are suspended */
+ unsigned int debug; /* Debug flags */
+
+} sfx_state_t;
+
+/***********/
+/* General */
+/***********/
+
+void
+sfx_init(sfx_state_t *self, resource_mgr_t *resmgr, int flags);
+/* Initializes the sound engine
+** Parameters: (resource_mgr_t *) resmgr: Resource manager for initialization
+** (int) flags: SFX_STATE_FLAG_*
+*/
+
+void
+sfx_exit(sfx_state_t *self);
+/* Deinitializes the sound subsystem
+*/
+
+void
+sfx_suspend(sfx_state_t *self, int suspend);
+/* Suspends/unsuspends the sound sybsystem
+** Parameters: (int) suspend: Whether to suspend (non-null) or to unsuspend
+*/
+
+int
+sfx_poll(sfx_state_t *self, song_handle_t *handle, int *cue);
+/* Polls the sound server for cues etc.
+** Returns : (int) 0 if the cue queue is empty, SI_LOOP, SI_CUE, or SI_FINISHED otherwise
+** (song_handle_t) *handle: The affected handle
+** (int) *cue: The sound cue number (if SI_CUE), or the loop number (if SI_LOOP)
+*/
+
+int
+sfx_poll_specific(sfx_state_t *self, song_handle_t handle, int *cue);
+/* Polls the sound server for cues etc.
+** Parameters: (song_handle_t) handle: The handle to poll
+** Returns : (int) 0 if the cue queue is empty, SI_LOOP, SI_CUE, or SI_FINISHED otherwise
+** (int) *cue: The sound cue number (if SI_CUE), or the loop number (if SI_LOOP)
+*/
+
+int
+sfx_get_volume(sfx_state_t *self);
+/* Determines the current global volume settings
+** Returns : (int) The global volume, between 0 (silent) and 127 (max. volume)
+*/
+
+void
+sfx_set_volume(sfx_state_t *self, int volume);
+/* Determines the current global volume settings
+** Parameters: (int) volume: The new global volume, between 0 and 127 (see above)
+*/
+
+void
+sfx_all_stop(sfx_state_t *self);
+/* Stops all songs currently playing, purges song library
+*/
+
+
+/*****************/
+/* Song basics */
+/*****************/
+
+int
+sfx_add_song(sfx_state_t *self, song_iterator_t *it, int priority, song_handle_t handle, int resnum);
+/* Adds a song to the internal sound library
+** Parameters: (song_iterator_t *) it: The iterator describing the song
+** (int) priority: Initial song priority (higher <-> more important)
+** (song_handle_t) handle: The handle to associate with the song
+** Returns : (int) 0 on success, nonzero on error
+*/
+
+
+void
+sfx_remove_song(sfx_state_t *self, song_handle_t handle);
+/* Deletes a song and its associated song iterator from the song queue
+** Parameters: (song_handle_t) handle: The song to remove
+*/
+
+
+/**********************/
+/* Song modifications */
+/**********************/
+
+
+void
+sfx_song_set_status(sfx_state_t *self, song_handle_t handle, int status);
+/* Sets the song status, i.e. whether it is playing, suspended, or stopped.
+** Parameters: (song_handle_t) handle: Handle of the song to modify
+** (int) status: The song status the song should assume
+** WAITING and PLAYING are set implicitly and essentially describe the same state
+** as far as this function is concerned.
+*/
+
+void
+sfx_song_renice(sfx_state_t *self, song_handle_t handle, int priority);
+/* Sets the new song priority
+** Parameters: (song_handle_t) handle: The handle to modify
+** (int) priority: The priority to set
+*/
+
+void
+sfx_song_set_loops(sfx_state_t *self, song_handle_t handle, int loops);
+/* Sets the number of loops for the specified song
+** Parameters: (song_handle_t) handle: The song handle to reference
+** (int) loops: Number of loops to set
+*/
+
+void
+sfx_song_set_hold(sfx_state_t *self, song_handle_t handle, int hold);
+/* Sets the number of loops for the specified song
+** Parameters: (song_handle_t) handle: The song handle to reference
+** (int) hold: Number of loops to setn
+*/
+
+void
+sfx_song_set_fade(sfx_state_t *self, song_handle_t handle, fade_params_t *fade_setup);
+/* Instructs a song to be faded out
+** Parameters: (song_handle_t) handle: The song handle to reference
+** (fade_params_t *) fade_setup: The precise fade-out configuration to use
+*/
+
+
+#endif /* !defined(_SFX_ENGINE_H_) */
diff --git a/engines/sci/include/sfx_iterator.h b/engines/sci/include/sfx_iterator.h
new file mode 100644
index 0000000000..de357b053d
--- /dev/null
+++ b/engines/sci/include/sfx_iterator.h
@@ -0,0 +1,353 @@
+/***************************************************************************
+ sfx_iterator.h (C) 2002..04 Christoph Reichenbach
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CJR) [reichenb@colorado.edu]
+
+***************************************************************************/
+/* Song iterator declarations */
+
+#ifndef _SCI_SFX_ITERATOR_H_
+#define _SCI_SFX_ITERATOR_H_
+
+#include <sfx_pcm.h>
+#include <listener.h>
+
+#define SI_FINISHED -1 /* Song finished playing */
+#define SI_LOOP -2 /* Song just looped */
+#define SI_ABSOLUTE_CUE -3 /* Found a song cue (absolute) */
+#define SI_RELATIVE_CUE -4 /* Found a song cue (relative) */
+#define SI_PCM -5 /* Found a PCM */
+#define SI_IGNORE -6 /* This event got edited out by the remapper */
+#define SI_MORPH -255 /* Song iterator requested self-morph. */
+
+#define FADE_ACTION_NONE 0
+#define FADE_ACTION_FADE_AND_STOP 1
+#define FADE_ACTION_FADE_AND_CONT 2
+
+typedef struct {
+ int ticks_per_step;
+ int final_volume;
+ int step_size;
+ int action;
+} fade_params_t;
+
+#define SONG_ITERATOR_MESSAGE_ARGUMENTS_NR 2
+
+/* Helper defs for messages */
+/* Base messages */
+#define _SIMSG_BASE 0 /* Any base decoder */
+#define _SIMSG_BASEMSG_SET_LOOPS 0 /* Set loops */
+#define _SIMSG_BASEMSG_CLONE 1 /* Clone object and data. Must provide the
+ ** (possibly negative) number of ticks that have
+ ** passed since the last delay time started being
+ ** used */
+#define _SIMSG_BASEMSG_SET_PLAYMASK 2 /* Set the current playmask for filtering */
+#define _SIMSG_BASEMSG_SET_RHYTHM 3 /* Activate/deactivate rhythm channel */
+#define _SIMSG_BASEMSG_ACK_MORPH 4 /* Acknowledge self-morph */
+#define _SIMSG_BASEMSG_STOP 5 /* Stop iterator */
+#define _SIMSG_BASEMSG_PRINT 6 /* Print self to stderr, after printing param1 tabs */
+#define _SIMSG_BASEMSG_SET_HOLD 7 /* Set value of hold parameter to expect */
+#define _SIMSG_BASEMSG_SET_FADE 8 /* Set fade parameters */
+
+/* "Plastic" (discardable) wrapper messages */
+#define _SIMSG_PLASTICWRAP 1 /* Any base decoder */
+#define _SIMSG_PLASTICWRAP_ACK_MORPH 4 /* Acknowledge self-morph */
+
+/* Messages */
+#define SIMSG_SET_LOOPS(x) _SIMSG_BASE,_SIMSG_BASEMSG_SET_LOOPS,(x),0
+#define SIMSG_SET_PLAYMASK(x) _SIMSG_BASE,_SIMSG_BASEMSG_SET_PLAYMASK,(x),0
+#define SIMSG_SET_RHYTHM(x) _SIMSG_BASE,_SIMSG_BASEMSG_SET_RHYTHM,(x),0
+#define SIMSG_CLONE(x) _SIMSG_BASE,_SIMSG_BASEMSG_CLONE,(x),0
+#define SIMSG_ACK_MORPH _SIMSG_PLASTICWRAP,_SIMSG_PLASTICWRAP_ACK_MORPH,0,0
+#define SIMSG_STOP _SIMSG_BASE,_SIMSG_BASEMSG_STOP,0,0
+#define SIMSG_PRINT(indentation) _SIMSG_BASE,_SIMSG_BASEMSG_PRINT,(indentation),0
+#define SIMSG_SET_HOLD(x) _SIMSG_BASE,_SIMSG_BASEMSG_SET_HOLD,(x),0
+/*#define SIMSG_SET_FADE(x) _SIMSG_BASE,_SIMSG_BASEMSG_SET_FADE,(x),0*/
+
+/* Message transmission macro: Takes song reference, message reference */
+#define SIMSG_SEND(o, m) songit_handle_message(&(o), songit_make_message((o)->ID, m))
+#define SIMSG_SEND_FADE(o, m) songit_handle_message(&(o), songit_make_ptr_message((o)->ID, _SIMSG_BASE, _SIMSG_BASEMSG_SET_FADE, m, 0))
+
+
+typedef unsigned long songit_id_t;
+
+typedef struct {
+ songit_id_t ID;
+ unsigned int recipient; /* Type of iterator supposed to receive this */
+ unsigned int type;
+ union {
+ unsigned int i;
+ void * p;
+ } args[SONG_ITERATOR_MESSAGE_ARGUMENTS_NR];
+} song_iterator_message_t;
+
+#define INHERITS_SONG_ITERATOR \
+ songit_id_t ID; \
+ guint16 channel_mask; \
+ fade_params_t fade; \
+ unsigned int flags; \
+ int priority; \
+ int (*next) (song_iterator_t *self, unsigned char *buf, int *buf_size); \
+ sfx_pcm_feed_t * (*get_pcm_feed) (song_iterator_t *s); \
+ song_iterator_t * (* handle_message)(song_iterator_t *self, song_iterator_message_t msg); \
+ void (*init) (struct _song_iterator *self); \
+ void (*cleanup) (struct _song_iterator *self); \
+ int (*get_timepos) (struct _song_iterator *self); \
+ listener_t death_listeners[SONGIT_MAX_LISTENERS]; \
+ int death_listeners_nr \
+
+#define SONGIT_MAX_LISTENERS 2
+
+typedef struct _song_iterator {
+
+ songit_id_t ID;
+ guint16 channel_mask; /* Bitmask of all channels this iterator will use */
+ fade_params_t fade;
+ unsigned int flags;
+ int priority;
+
+ int (*next) (struct _song_iterator *self,
+ unsigned char *buf, int *result);
+ /* Reads the next MIDI operation _or_ delta time
+ ** Parameters: (song_iterator_t *) self
+ ** (byte *) buf: The buffer to write to (needs to be able to
+ ** store at least 4 bytes)
+ ** Returns : (int) zero if a MIDI operation was written, SI_FINISHED
+ ** if the song has finished playing, SI_LOOP if looping
+ ** (after updating the loop variable), SI_CUE if we found
+ ** a cue, SI_PCM if a PCM was found, or the number of ticks
+ ** to wait before this function should be called next.
+ ** (int) *result: Number of bytes written to the buffer
+ ** (equals the number of bytes that need to be passed
+ ** to the lower layers) for 0, the cue value for SI_CUE,
+ ** or the number of loops remaining for SI_LOOP.
+ ** If SI_PCM is returned, get_pcm() may be used to retrieve the associated
+ ** PCM, but this must be done before any subsequent calls to next().
+ */
+
+ sfx_pcm_feed_t * (*get_pcm_feed) (struct _song_iterator *self);
+ /* Checks for the presence of a pcm sample
+ ** Parameters: (song_iterator_t *) self
+ ** Returns : (sfx_pcm_feed_t *) NULL if no PCM data was found, a
+ ** PCM feed otherwise
+ */
+
+
+ struct _song_iterator *
+ (* handle_message)(struct _song_iterator *self, song_iterator_message_t msg);
+ /* Handles a message to the song iterator
+ ** Parameters: (song_iterator_t *) self
+ ** (song_iterator_messag_t) msg: The message to handle
+ ** Returns : (song_iterator_t *) NULL if the message was not understood,
+ ** self if the message could be handled, or a new song iterator
+ ** if the current iterator had to be morphed (but the message could
+ ** still be handled)
+ ** This function is not supposed to be called directly; use
+ ** songit_handle_message() instead. It should not recurse, since songit_handle_message()
+ ** takes care of that and makes sure that its delegate received the message (and
+ ** was morphed) before self.
+ */
+
+
+ void (*init) (struct _song_iterator *self);
+ /* Resets/initializes the sound iterator
+ ** Parameters: (song_iterator_t *) self
+ ** Returns : (void)
+ */
+
+ void (*cleanup) (struct _song_iterator *self);
+ /* Frees any content of the iterator structure
+ ** Parameters: (song_iterator_t *) self
+ ** Does not physically free(self) yet. May be NULL if nothing needs to be done.
+ ** Must not recurse on its delegate.
+ */
+
+ int (*get_timepos) (struct _song_iterator *self);
+ /* Gets the song position to store in a savegame
+ ** Parameters: (song_iterator_t *) self
+ */
+
+ /* Death listeners */
+ /* These are not reset during initialisation */
+ listener_t death_listeners[SONGIT_MAX_LISTENERS];
+ int death_listeners_nr;
+
+ /* See songit_* for the constructor and non-virtual member functions */
+
+} song_iterator_t;
+
+
+/* Song iterator flags */
+#define SONGIT_FLAG_CLONE (1 << 0) /* This flag is set for clones, which are exclusively used in song players.
+ ** Thus, this flag distinguishes song iterators in the main thread from those
+ ** in the song-player thread. */
+
+void
+song_iterator_add_death_listener(song_iterator_t *it,
+ void *client,
+ void (*notify) (void *self, void *notifier));
+/* Adds a death listener to a song iterator
+** Parameters: (song_iterator_t *) it: The iterator to add to
+** (void *) client: The object wanting to be notified
+** (void* x void* -> void) notify: The notification function
+** to invoke
+** Effects: Fatally terminates the program if no listener slots are
+** available
+** Death listeners are NOT cloned.
+*/
+
+void
+song_iterator_remove_death_listener(song_iterator_t *it,
+ void *client);
+/* Removes a death listener from a song iterator
+** Parameters: (song_iterator_t *) it: The iterator to modify
+** (void *) client: The object no longer wanting to be notified
+** Effects: Fatally terminates the program if the listener was not
+** found
+** Death listeners are NOT cloned.
+*/
+
+/********************************/
+/*-- Song iterator operations --*/
+/********************************/
+
+#define SCI_SONG_ITERATOR_TYPE_SCI0 0
+#define SCI_SONG_ITERATOR_TYPE_SCI1 1
+
+#define IT_READER_MASK_MIDI (1 << 0)
+#define IT_READER_MASK_DELAY (1 << 1)
+#define IT_READER_MASK_LOOP (1 << 2)
+#define IT_READER_MASK_CUE (1 << 3)
+#define IT_READER_MASK_PCM (1 << 4)
+#define IT_READER_MAY_FREE (1 << 10) /* Free SI_FINISHED iterators */
+#define IT_READER_MAY_CLEAN (1 << 11)
+ /* MAY_CLEAN: May instantiate cleanup iterators
+ ** (use for players; this closes open channels at the end of a song) */
+
+#define IT_READER_MASK_ALL ( IT_READER_MASK_MIDI \
+ | IT_READER_MASK_DELAY \
+ | IT_READER_MASK_LOOP \
+ | IT_READER_MASK_CUE \
+ | IT_READER_MASK_PCM )
+
+int
+songit_next(song_iterator_t **it, unsigned char *buf, int *result, int mask);
+/* Convenience wrapper around it->next
+** Parameters: (song_iterator_t **it) Reference to the iterator to access
+** (byte *) buf: The buffer to write to (needs to be able to
+** store at least 4 bytes)
+** (int) mask: IT_READER_MASK options specifying the events to
+** listen for
+** Returns : (int) zero if a MIDI operation was written, SI_FINISHED
+** if the song has finished playing, SI_LOOP if looping
+** (after updating the loop variable), SI_CUE if we found
+** a cue, SI_PCM if a PCM was found, or the number of ticks
+** to wait before this function should be called next.
+** (int) *result: Number of bytes written to the buffer
+** (equals the number of bytes that need to be passed
+** to the lower layers) for 0, the cue value for SI_CUE,
+** or the number of loops remaining for SI_LOOP.
+*/
+
+song_iterator_t *
+songit_new(unsigned char *data, unsigned int size, int type, songit_id_t id);
+/* Constructs a new song iterator object
+** Parameters: (byte *) data: The song data to iterate over
+** (unsigned int) size: Number of bytes in the song
+** (int) type: One of the SCI_SONG_ITERATOR_TYPEs
+** (songit_id_t) id: An ID for addressing the song iterator
+** Returns : (song_iterator_t *) A newly allocated but uninitialized song
+** iterator, or NULL if 'type' was invalid or unsupported
+*/
+
+song_iterator_t *
+songit_new_tee(song_iterator_t *left, song_iterator_t *right, int may_destroy);
+/* Combines two iterators, returns the next event available from either
+** Parameters: (song_iterator_t *) left: One of the iterators
+** (song_iterator_t *) right: The other iterator
+** (int) may_destroy: Whether completed song iterators may be
+** destroyed
+** Returns : (song_iterator_t *) A combined iterator, as suggested above
+*/
+
+
+void
+songit_free(song_iterator_t *it);
+/* Frees a song iterator and the song it wraps
+** Parameters: (song_iterator_t *) it: The song iterator to free
+** Returns : (void)
+*/
+
+song_iterator_message_t
+songit_make_message(songit_id_t id,
+ int recipient_class, int type, int a1, int a2);
+/* Create a song iterator message
+** Parameters: (songit_id_t) id: song ID the message is targetted to
+** (int) recipient_class: Message recipient class
+** (int) type: Message type
+** (int x int) a1, a2: Arguments
+** You should only use this with the SIMSG_* macros
+*/
+
+song_iterator_message_t
+songit_make_ptr_message(songit_id_t id,
+ int recipient_class, int type, void * a1, int a2);
+/* Create a song iterator message, wherein the first parameter is a pointer
+** Parameters: (songit_id_t) id: song ID the message is targetted to
+** (int) recipient_class: Message recipient class
+** (int) type: Message type
+** (void* x int) a1, a2: Arguments
+** You should only use this with the SIMSG_* macros
+*/
+
+int
+songit_handle_message(song_iterator_t **it_reg, song_iterator_message_t msg);
+/* Handles a message to the song iterator
+** Parameters: (song_iterator_t **): A reference to the variable storing the song iterator
+** Returns : (int) Non-zero if the message was understood
+** The song iterator may polymorph as result of msg, so a writeable reference is required.
+*/
+
+
+song_iterator_t *
+songit_clone(song_iterator_t *it, int delta);
+/* Clones a song iterator
+** Parameters: (song_iterator_t *) it: The iterator to clone
+** (int) delta: Number of ticks that still need to elapse until
+** the next item should be read from the song iterator
+** Returns : (song_iterator_t *) A shallow clone of 'it'.
+** This performs a clone on the bottom-most part (containing the actual song data) _only_.
+** The justification for requiring 'delta' to be passed in here is that this
+** is typically maintained outside of the song iterator.
+*/
+
+
+int
+sfx_play_iterator_pcm(song_iterator_t *it, unsigned long handle);
+/* Plays a song iterator that found a PCM through a PCM device, if possible
+** Parameters: (song_iterator_t *) it: The iterator to play
+** (song_handle_t) handle: Debug handle
+** Returns : (int) 0 if the effect will not be played, nonzero if it will
+** This assumes that the last call to 'it->next()' returned SI_PCM.
+*/
+
+#endif
diff --git a/engines/sci/include/sfx_iterator_internal.h b/engines/sci/include/sfx_iterator_internal.h
new file mode 100644
index 0000000000..02b32502ac
--- /dev/null
+++ b/engines/sci/include/sfx_iterator_internal.h
@@ -0,0 +1,238 @@
+/***************************************************************************
+ sfx_iterator_internal.h Copyright (C) 2003 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef _SFX_ITERATOR_INTERNAL_
+#define _SFX_ITERATOR_INTERNAL_
+
+#include <sfx_iterator.h>
+#include <sci_midi.h>
+
+
+/* States */
+
+#define SI_STATE_UNINITIALISED -1
+#define SI_STATE_DELTA_TIME 0 /* Now at a delta time */
+#define SI_STATE_COMMAND 1 /* Now at a MIDI operation */
+#define SI_STATE_PENDING 2 /* Pending for loop */
+#define SI_STATE_FINISHED 3 /* End of song */
+#define SI_STATE_PCM 4 /* Should report a PCM next (-> DELTA_TIME) */
+#define SI_STATE_PCM_MAGIC_DELTA 5 /* Should report a ``magic'' one tick delta time next (goes on to FINISHED) */
+
+
+/* Iterator types */
+
+#define SCI_SONG_ITERATOR_TYPE_SCI0 0
+#define SCI_SONG_ITERATOR_TYPE_SCI1 1
+
+#define SIPFX __FILE__" : "
+
+
+typedef struct {
+ int state; /* SI_STATE_* */
+ int offset; /* Offset into the data chunk */
+ int end; /* Last allowed byte in track */
+ int id; /* Some channel ID */
+ int loop_offset;
+ int delay; /* Number of ticks before the
+ ** specified channel is next
+ ** used, or
+ ** CHANNEL_DELAY_MISSING to
+ ** indicate that the delay has
+ ** not yet been read */
+
+ /* Two additional offsets for recovering: */
+ int initial_offset;
+ int playmask; /* Active playmask (MIDI channels to play in here) */
+ int notes_played; /* #of notes played since the last loop start */
+ int loop_timepos; /* Total delay for this channel's loop marker */
+ int total_timepos; /* Number of ticks since the beginning, ignoring loops */
+ int timepos_increment; /* Number of ticks until the next command (to add) */
+
+ int saw_notes; /* Bitmask of channels we have currently played notes on */
+ byte last_cmd; /* Last operation executed, for running status */
+} song_iterator_channel_t;
+
+#define INHERITS_BASE_SONG_ITERATOR \
+ INHERITS_SONG_ITERATOR; /* aka "extends song iterator" */ \
+ \
+ int polyphony[MIDI_CHANNELS]; /* # of simultaneous notes on each */ \
+ int importance[MIDI_CHANNELS]; /* priority rating for each channel, 0 means unrated. */ \
+ \
+ \
+ int ccc; /* Cumulative cue counter, for those who need it */ \
+ unsigned char resetflag; /* for 0x4C -- on DoSound StopSound, do we return to start? */ \
+ int device_id; /* ID of the device we generating events for */ \
+ int active_channels; /* Number of active channels */ \
+ unsigned int size; /* Song size */ \
+ unsigned char *data; \
+ \
+ int loops; /* Number of loops remaining */ \
+ int recover_delay
+
+typedef struct _base_song_iterator {
+ INHERITS_BASE_SONG_ITERATOR;
+} base_song_iterator_t;
+
+/********************************/
+/*--------- SCI 0 --------------*/
+/********************************/
+
+typedef struct {
+ INHERITS_BASE_SONG_ITERATOR;
+ song_iterator_channel_t channel;
+ int delay_remaining; /* Number of ticks that haven't been polled yet */
+} sci0_song_iterator_t;
+
+
+/********************************/
+/*--------- SCI 1 --------------*/
+/********************************/
+
+
+typedef struct _sci1_sample {
+ int delta; /* Time left-- initially, this is 'Sample point 1'.
+ ** After initialisation, it is 'sample point 1 minus the sample point of the previous sample' */
+ int size;
+ int announced; /* Announced for download (SI_PCM) */
+ sfx_pcm_config_t format;
+ byte *data;
+ struct _sci1_sample *next;
+} sci1_sample_t;
+
+typedef struct {
+ INHERITS_BASE_SONG_ITERATOR;
+ song_iterator_channel_t channels[MIDI_CHANNELS];
+
+ /* Invariant: Whenever channels[i].delay == CHANNEL_DELAY_MISSING,
+ ** channel_offset[i] points to a delta time object. */
+
+ int initialised; /* Whether the MIDI channel setup has been initialised */
+ int channels_nr; /* Number of channels actually used */
+ sci1_sample_t *next_sample;
+ int channels_looped; /* Number of channels that are ready to loop */
+
+ int delay_remaining; /* Number of ticks that haven't been polled yet */
+ int hold; \
+} sci1_song_iterator_t;
+
+#define PLAYMASK_NONE 0x0
+
+/*********************************/
+/*---------- Cleanup ------------*/
+/*********************************/
+
+
+song_iterator_t *
+new_cleanup_iterator(unsigned int channels);
+/* Creates a new song iterator with the purpose of sending notes-off channel commands
+** Parameters: (unsigned int) channels: Channel mask to send these commands for
+** Returns : A song iterator with the aforementioned purpose
+*/
+
+int
+is_cleanup_iterator(song_iterator_t *it);
+/* Determines whether a given song iterator is a cleanup song iterator
+** Parameters: (song_iterator_t *) it: The iterator to check
+** Returns : (int) 1 iff 'it' is a cleanup song iterator
+** No deep recursion/delegation is considered.
+*/
+
+
+/**********************************/
+/*--------- Fast Forward ---------*/
+/**********************************/
+
+typedef struct {
+ INHERITS_SONG_ITERATOR;
+ song_iterator_t *delegate;
+ int delta; /* Remaining time */
+} fast_forward_song_iterator_t;
+
+
+song_iterator_t *
+new_fast_forward_iterator(song_iterator_t *it, int delta);
+/* Creates a new song iterator which fast-forwards
+** Parameters: (song_iterator_t *) it: The iterator to wrap
+** (int) delta: The number of ticks to skip
+** Returns : (song_iterator_t) A newly created song iterator
+** which skips all delta times
+** until 'delta' has been used up
+*/
+
+/**********************************/
+/*--------- Fast Forward ---------*/
+/**********************************/
+
+#define MAX_BUF_SIZE 4
+
+#define TEE_LEFT 0
+#define TEE_RIGHT 1
+#define TEE_LEFT_ACTIVE (1<<0)
+#define TEE_RIGHT_ACTIVE (1<<1)
+#define TEE_LEFT_READY (1<<2) /* left result is ready */
+#define TEE_RIGHT_READY (1<<3) /* right result is ready */
+#define TEE_LEFT_PCM (1<<4)
+#define TEE_RIGHT_PCM (1<<5)
+
+#define TEE_MORPH_NONE 0 /* Not waiting to self-morph */
+#define TEE_MORPH_READY 1 /* Ready to self-morph */
+
+typedef struct {
+ INHERITS_SONG_ITERATOR;
+
+ int status;
+
+ int may_destroy; /* May destroy song iterators */
+
+ int morph_deferred; /* One of TEE_MORPH_* above */
+
+ struct {
+ song_iterator_t *it;
+ byte buf[MAX_BUF_SIZE];
+ int result;
+ int retval;
+
+ byte channel_remap[MIDI_CHANNELS];
+ /* Remapping for channels */
+
+ } children[2];
+} tee_song_iterator_t;
+
+
+sfx_pcm_feed_t *
+sfx_iterator_make_feed(byte *base_data, int offset,
+ int size,
+ sfx_pcm_config_t conf);
+/* Generates a feed for a song iterator
+** Parameters: (byte *) base_data: A refcounted memory chunk containing
+** (among other things) PCM data
+** (int) offset; Offset into base_data
+** (int) size: Number of bytes to consider
+** (pcm_data_internal_t) conf: PCM encoding
+*/
+
+#endif /* !defined(_SFX_ITERATOR_INTERNAL_ */
diff --git a/engines/sci/include/sfx_pcm.h b/engines/sci/include/sfx_pcm.h
new file mode 100644
index 0000000000..b3a44868a9
--- /dev/null
+++ b/engines/sci/include/sfx_pcm.h
@@ -0,0 +1,235 @@
+/***************************************************************************
+ sfx_pcm.h Copyright (C) 2003,04 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef _SFX_PCM_H_
+#define _SFX_PCM_H_
+
+#include <sfx_core.h>
+#include <sfx_timer.h>
+#include <sfx_time.h>
+#include <scitypes.h>
+
+/* A number of standard options most devices will support */
+#define SFX_PCM_OPTION_RATE "rate" /* Sampling rate: Number of samples per second */
+#define SFX_PCM_OPTION_BITS "bits" /* Sample size in bits */
+#define SFX_PCM_OPTION_STEREO "stereo" /* Whether to support stereo output */
+#define SFX_PCM_OPTION_BUF_SIZE "buffer-size" /* Requested buffer size */
+/* Device implementors are advised to use these constants whenever possible. */
+
+#define SFX_PCM_MONO 0
+#define SFX_PCM_STEREO_LR 1 /* left sample, then right sample */
+#define SFX_PCM_STEREO_RL 2 /* right sample, then left sample */
+
+/* The following are used internally by the mixer */
+#define SFX_PCM_FORMAT_LMASK 0x7
+#define SFX_PCM_FORMAT_BE 0
+#define SFX_PCM_FORMAT_LE 1
+#define SFX_PCM_FORMAT_ENDIANNESS 1
+#define SFX_PCM_FORMAT_8 0
+#define SFX_PCM_FORMAT_16 2
+
+
+/* Pick one of these formats (including the _NATIVE) ones for your PCM feed */
+#define SFX_PCM_FORMAT_U8 (0x0080 | SFX_PCM_FORMAT_8) /* Unsigned (bias 128) 8 bit format */
+#define SFX_PCM_FORMAT_S8 (0x0000 | SFX_PCM_FORMAT_8) /* Signed 8 bit format */
+#define SFX_PCM_FORMAT_U16_LE (0x8000 | SFX_PCM_FORMAT_16 | SFX_PCM_FORMAT_LE) /* Unsigned (bias 32768) 16 bit LE format */
+#define SFX_PCM_FORMAT_S16_LE (0x0000 | SFX_PCM_FORMAT_16 | SFX_PCM_FORMAT_LE) /* Signed 16 bit format, little endian */
+#define SFX_PCM_FORMAT_U16_BE (0x8000 | SFX_PCM_FORMAT_16 | SFX_PCM_FORMAT_BE) /* Unsigned (bias 32768) 16 bit BE format */
+#define SFX_PCM_FORMAT_S16_BE (0x0000 | SFX_PCM_FORMAT_16 | SFX_PCM_FORMAT_BE) /* Signed 16 bit format, big endian */
+
+#ifdef WORDS_BIGENDIAN
+# define SFX_PCM_FORMAT_U16_NATIVE SFX_PCM_FORMAT_U16_BE
+# define SFX_PCM_FORMAT_S16_NATIVE SFX_PCM_FORMAT_S16_BE
+#else
+# define SFX_PCM_FORMAT_U16_NATIVE SFX_PCM_FORMAT_U16_LE
+# define SFX_PCM_FORMAT_S16_NATIVE SFX_PCM_FORMAT_S16_LE
+#endif
+
+#define SFX_PCM_FRAME_SIZE(conf) ((conf).stereo? 2 : 1) * (((conf).format & SFX_PCM_FORMAT_16)? 2 : 1)
+
+
+typedef struct {
+ int nom, den;
+ int val;
+
+ /* Total value: val + nom/den, where (nom < den) guaranteed. */
+} sfx_pcm_urat_t; /* Finitary unsigned rational numbers */
+
+typedef struct {
+ int rate; /* Sampling rate */
+ int stereo; /* The stereo mode used (SFX_PCM_MONO or SFX_PCM_STEREO_*) */
+ unsigned int format; /* Sample format (SFX_PCM_FORMAT_*) */
+} sfx_pcm_config_t;
+
+typedef struct _sfx_pcm_device {
+ /* SFX devices are PCM players, i.e. output drivers for digitalised audio (sequences of audio samples).
+ ** Implementors are (in general) allowed to export specifics of these devices and let the mixer handle
+ ** endianness/signedness/bit size/mono-vs-stereo conversions.
+ */
+
+ const char *name;
+ const char *version;
+
+ int (*init)(struct _sfx_pcm_device *self);
+ /* Initializes the device
+ ** Parameters: (sfx_pcm_device_t *) self: Self reference
+ ** Returns : (int) SFX_OK on success, SFX_ERROR if the device could not be
+ ** opened
+ ** This should attempt to open the highest quality output allowed by any options
+ ** specified beforehand.
+ */
+
+ void (*exit)(struct _sfx_pcm_device *self);
+ /* Uninitialises the device
+ ** Parameters: (sfx_pcm_device_t *) self: Self reference
+ */
+
+ int (*set_option)(struct _sfx_pcm_device *self, char *name, char *value);
+ /* Sets an option for the device
+ ** Parameters: (sfx_pcm_device_t *) self: Self reference
+ ** (char *) name: Name of the option to set
+ ** (char *) value: Value of the option to set
+ ** Returns : (int) SFX_OK on success, SFX_ERROR otherwise (unsupported option)
+ ** May be NULL
+ */
+
+ int (*output)(struct _sfx_pcm_device *self, byte *buf,
+ int count, sfx_timestamp_t *timestamp);
+ /* Writes output to the device
+ ** Parameters: (sfx_pcm_device_t *) self: Self reference
+ ** (byte *) buf: The buffer to write
+ ** (int) count: Number of /frames/ that should be written
+ ** (sfx_timestamp_t *) timestamp: Optional point in time
+ ** for which the PCM data is scheduled
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on error
+ ** The size of the buffer allocated as 'buf' equals buf_size.
+ ** 'buf' is guaranteed not to be modified in between calls to 'output()'.
+ ** 'timestamp' is guaranteed to be used only in sequential order, but not
+ ** guaranteed to be used in all cases. It is guaranteed to be compaible with
+ ** the sample rate used by the device itself (i.e., the sfx_time.h functionality
+ ** is applicable)
+ */
+
+ sfx_timestamp_t
+ (*get_output_timestamp)(struct _sfx_pcm_device *self);
+ /* Determines the timestamp for 'output'
+ ** Parameters: (sfx_pcm_device_t *) self: Self reference
+ ** Returns : (sfx_timestamp_t) A timestamp (with the device's conf.rate)
+ ** describing the point in time at which
+ ** the next frame passed to 'output'
+ ** will be played
+ ** This function is OPTIONAL and may be NULL, but it is recommended
+ ** that pcm device implementers attempt to really implement it.
+ */
+
+ /* The following must be set after initialisation */
+ sfx_pcm_config_t conf;
+ int buf_size; /* Output buffer size, i.e. the number of frames (!)
+ ** that can be queued by this driver before calling
+ ** output() will block or fail, drained according
+ ** to conf.rate */
+
+ /* The following are optional */
+ sfx_timer_t *timer;
+ /* Many PCM drivers use a callback mechanism, which can be
+ ** exploited as a timer. Such a timer may be exported here and
+ ** will be preferred over other timers. */
+ /* This is an _optional_ timer provided by the PCM
+ ** subsystem (may be NULL). It is checked for afer
+ ** initialisation, and used in preference to any
+ ** other timers available.
+ */
+ void *internal; /* The private bits */
+
+} sfx_pcm_device_t;
+
+
+#define PCM_FEED_TIMESTAMP 0 /* New timestamp available */
+#define PCM_FEED_IDLE 1 /* No sound ATM, but new timestamp may be available later */
+#define PCM_FEED_EMPTY 2 /* Feed is finished, can be destroyed */
+
+typedef struct _sfx_pcm_feed_t {
+ /* PCM feeds are sources of input for the PCM mixer. Their member functions
+ ** are invoked as callbacks on demand, to provide the mixer with input it
+ ** (in turn) passes on to PCM output devices.
+ ** PCM feeds must explicitly register themselves with the mixer in order
+ ** to be considered.
+ */
+
+ int (*poll)(struct _sfx_pcm_feed_t *self, byte *dest, int size);
+ /* Asks the PCM feed to write out the next stuff it would like to have written
+ ** Parameters: (sfx_pcm_feed_t *) self: Self reference
+ ** (byte *) dest: The destination buffer to write to
+ ** (int) size: The maximum number of _frames_ (not neccessarily bytes)
+ ** to write
+ ** Returns : (int) The number of frames written
+ ** If the number of frames written is smaller than 'size', the PCM feed will
+ ** be queried for a new timestamp afterwards, or destroyed if no new timestamp
+ ** is available.
+ */
+
+ void (*destroy)(struct _sfx_pcm_feed_t *self);
+ /* Asks the PCM feed to free all resources it occupies
+ ** Parameters: (sfx_pcm_feed_t *) self: Self reference
+ ** free(self) should be part of this function, if applicable.
+ */
+
+ int
+ (*get_timestamp)(struct _sfx_pcm_feed_t *self, sfx_timestamp_t *timestamp);
+ /* Determines the timestamp of the next frame-to-read
+ ** Returns : (sfx_timestamp_t) timestamp: The timestamp of the next frame
+ ** (int) PCM_FEED_*
+ ** This function is OPTIONAL and may be NULL
+ */
+
+ void *internal; /* The private bits of a PCM feed. */
+
+ sfx_pcm_config_t conf; /* The channel's setup */
+
+ const char *debug_name; /* The channel name, for debugging */
+ int debug_nr; /* A channel number relative to the channel name, for debugging
+ ** (print in hex) */
+ int frame_size; /* Frame size, computed by the mixer for the feed */
+
+} sfx_pcm_feed_t;
+
+int
+sfx_pcm_available(void);
+/* Determines whether a PCM device is available and has been initialised
+** Returns : (int) zero iff no PCM device is available
+*/
+
+sfx_pcm_device_t *
+sfx_pcm_find_device(char *name);
+/* Finds a PCM device by name
+** Parameters: (char *) name: Name of the PCM device to look for, or NULL to
+** use the system default
+** Returns : (sfx_pcm_device_t *) The requested device, or NULL if no matching
+** device could be found
+*/
+
+#endif /* !defined(_SFX_PCM_H_) */
diff --git a/engines/sci/include/sfx_player.h b/engines/sci/include/sfx_player.h
new file mode 100644
index 0000000000..3198ff7c49
--- /dev/null
+++ b/engines/sci/include/sfx_player.h
@@ -0,0 +1,166 @@
+/***************************************************************************
+ sfx_player.h Copyright (C) 2003,04 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+/* song player structure */
+
+#include <sfx_engine.h>
+#include <sfx_iterator.h>
+#include <sciresource.h>
+
+#ifndef _SFX_PLAYER_H
+#define _SFX_PLAYER_H
+
+typedef void tell_synth_func(int buf_nr, byte *buf);
+
+typedef struct {
+ const char *name;
+ const char *version;
+
+ int
+ (*set_option)(char *name, char *value);
+ /* Sets an option for player timing mechanism
+ ** Parameters: (char *) name: The name describing what to set
+ ** (char *) value: The value to set
+ ** Returns : (int) SFX_OK, or SFX_ERROR if the name wasn't understood
+ */
+
+ int
+ (*init)(resource_mgr_t *resmgr, int expected_latency);
+ /* Initializes the player
+ ** Parameters: (resource_mgr_t *) resmgr: A resource manager for driver initialization
+ ** (int) expected_latency: Expected delay in between calls to 'maintenance'
+ ** (in microseconds)
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ */
+
+ int
+ (*add_iterator)(song_iterator_t *it, GTimeVal start_time);
+ /* Adds an iterator to the song player
+ ** Parameters: (songx_iterator_t *) it: The iterator to play
+ ** (GTimeVal) start_time: The time to assume as the
+ ** time the first MIDI command executes at
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ ** The iterator should not be cloned (to avoid memory leaks) and
+ ** may be modified according to the needs of the player.
+ ** Implementors may use the 'sfx_iterator_combine()' function
+ ** to add iterators onto their already existing iterators
+ */
+
+ int
+ (*fade_out)(void);
+ /* Fades out the currently playing song (within two seconds
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ */
+
+ int
+ (*stop)(void);
+ /* Stops the currently playing song and deletes the associated iterator
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ */
+
+ int
+ (*iterator_message)(song_iterator_message_t msg);
+ /* Transmits a song iterator message to the active song
+ ** Parameters: (song_iterator_message_t) msg: The message to transmit
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ ** OPTIONAL -- may be NULL
+ ** If this method is not present, sending messages will stop
+ ** and re-start playing, so it is preferred that it is present
+ */
+
+ int
+ (*pause)(void); /* OPTIONAL -- may be NULL */
+ /* Pauses song playing
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ */
+
+ int
+ (*resume)(void); /* OPTIONAL -- may be NULL */
+ /* Resumes song playing after a pause
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ */
+
+ int
+ (*exit)(void);
+ /* Stops the player
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ */
+
+ void
+ (*maintenance)(void); /* OPTIONAL -- may be NULL */
+ /* Regularly called maintenance function
+ ** This function is called frequently and regularly (if present), it can be
+ ** used to emit sound.
+ */
+
+ tell_synth_func *tell_synth;
+ /* Pass a raw MIDI event to the synth
+ Parameters: (int) argc: Length of buffer holding the midi event
+ (byte *) argv: The buffer itself
+ */
+
+ int polyphony; /* Number of voices that can play simultaneously */
+
+} sfx_player_t;
+
+sfx_player_t *
+sfx_find_player(char *name);
+/* Looks up a player by name or finds the default player
+** Parameters: (char *) name: Name of the player to look up, or NULL for dedault
+** Returns : (sfx_player_t *) The player requested, or NULL if none was found
+*/
+
+tell_synth_func *
+sfx_get_player_tell_func(void);
+/* Gets the callback function of the player in use.
+** Returns: (tell_synth_func *) The callback function.
+*/
+
+int
+sfx_get_player_polyphony(void);
+/* Determines the polyphony of the player in use
+** Returns : (int) Number of voices the active player can emit
+*/
+
+void
+sfx_reset_player(void);
+/* Tells the player to stop its internal iterator
+** Parameters: None.
+** Returns: Nothing.
+ */
+
+song_iterator_t *
+sfx_iterator_combine(song_iterator_t *it1, song_iterator_t *it2);
+/* Combines two song iterators into one
+** Parameters: (sfx_iterator_t *) it1: One of the two iterators, or NULL
+** (sfx_iterator_t *) it2: The other iterator, or NULL
+** Returns : (sfx_iterator_t *) A combined iterator
+** If a combined iterator is returned, it will be flagged to be allowed to
+** dispose of 'it1' and 'it2', where applicable. This means that this
+** call should be used by song players, but not by the core sound system
+*/
+
+#endif /* !_SFX_PLAYER_H */
diff --git a/engines/sci/include/sfx_songlib.h b/engines/sci/include/sfx_songlib.h
new file mode 100644
index 0000000000..7aa6ea4fd5
--- /dev/null
+++ b/engines/sci/include/sfx_songlib.h
@@ -0,0 +1,200 @@
+/***************************************************************************
+ sfx_songlib.h (C) 2002..04 Christoph Reichenbach
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CJR) [reichenb@colorado.edu]
+
+***************************************************************************/
+/* Song library */
+
+#ifndef _SCI_SFX_SONGLIB_H_
+#define _SCI_SFX_SONGLIB_H_
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <scitypes.h>
+#include <sfx_iterator.h>
+
+#define SOUND_STATUS_STOPPED 0
+#define SOUND_STATUS_PLAYING 1
+#define SOUND_STATUS_SUSPENDED 2
+/* suspended: only if ordered from kernel space */
+#define SOUND_STATUS_WAITING 3
+/* "waiting" means "tagged for playing, but not active right now" */
+
+typedef unsigned long song_handle_t;
+
+typedef enum {
+ RESTORE_BEHAVIOR_CONTINUE, /* restart a song when restored from
+ a saved game */
+ RESTORE_BEHAVIOR_RESTART /* continue it from where it was */
+} RESTORE_BEHAVIOR;
+
+typedef struct _song {
+ song_handle_t handle;
+ int resource_num; /* Resource number */
+ int priority; /* Song priority (more important if priority is higher) */
+ int status; /* See above */
+
+ int restore_behavior;
+ int restore_time;
+
+/* Grabbed from the sound iterator, for save/restore purposes */
+ int loops;
+ int hold;
+
+ song_iterator_t *it;
+ long delay; /* Delay before accessing the iterator, in microseconds */
+
+ GTimeVal wakeup_time; /* Used by the sound core:
+ ** Playing -> time at which 'delay' has elapsed
+ ** Suspended/Waiting -> stopping time */
+
+ struct _song *next; /* Next song or NULL if this is the last one */
+ struct _song *next_playing; /* Next playing song; used by the
+ ** core song system */
+ struct _song *next_stopping; /* Next song pending stopping; used exclusively by
+ ** the core song system's _update_multi_song() */
+} song_t;
+
+
+typedef struct {
+ song_t **lib;
+ song_t *_s;
+} songlib_t;
+
+/**************************/
+/* Song library commands: */
+/**************************/
+
+song_t *
+song_new(song_handle_t handle, song_iterator_t *it, int priority);
+/* Initializes a new song
+** Parameters: (song_handle_t) handle: The sound handle
+** (song_iterator_t *) it: The song
+** (int) priority: The song's priority
+** Returns : (song_t *) A freshly allocated song
+** Other values are set to predefined defaults.
+*/
+
+
+void
+song_lib_init(songlib_t *songlib);
+/* Initializes a static song library
+** Parameters: (songlib_t *) songlib: Pointer to the library
+** to initialize
+** Returns : (void)
+*/
+
+void
+song_lib_free(songlib_t songlib);
+/* Frees a song library
+** Parameters: (songlib_t) songlib: The library to free
+** Returns : (void)
+*/
+
+void
+song_lib_add(songlib_t songlib, song_t *song);
+/* Adds a song to a song library.
+** Parameters: (songlib_t) songlib: An existing sound library, or NULL
+** (song_t *) song: The song to add
+** Returns : (void)
+*/
+
+song_t *
+song_lib_find(songlib_t songlib, song_handle_t handle);
+/* Looks up the song with the specified handle
+** Parameters: (songlib_t) songlib: An existing sound library, may point to NULL
+** (song_handle_t) handle: The sound handle to look for
+** Returns : (song_t *) The song or NULL if it wasn't found
+*/
+
+song_t *
+song_lib_find_active(songlib_t songlib);
+/* Finds the first song playing with the highest priority
+** Parameters: (songlib_t) songlib: An existing sound library
+** Returns : (song_t *) The song that should be played next, or NULL if there is none
+*/
+
+song_t *
+song_lib_find_next_active(songlib_t songlib, song_t *song);
+/* Finds the next song playing with the highest priority
+** Parameters: (songlib_t) songlib: The song library to operate on
+** (song_t *) song: A song previously returned from the song library
+** Returns : (song_t *) The next song to play relative to 'song', or
+** NULL if none are left
+** The functions 'song_lib_find_active' and 'song_lib_find_next_active
+** allow to iterate over all songs that satisfy the requirement of
+** being 'playable'.
+*/
+
+int
+song_lib_remove(songlib_t songlib, song_handle_t handle);
+/* Removes a song from the library
+** Parameters: (songlib_t) songlib: An existing sound library
+** (song_handle_t) handle: Handle of the song to remove
+** Returns : (int) The status of the song that was removed
+*/
+
+void
+song_lib_resort(songlib_t songlib, song_t *song);
+/* Removes a song from the library and sorts it in again; for use after renicing
+** Parameters: (songlib_t) songlib: An existing sound library
+** (song_t *) song: The song to work on
+** Returns : (void)
+*/
+
+int
+song_lib_count(songlib_t songlib);
+/* Counts the number of songs in a song library
+** Parameters: (songlib_t) songlib: The library to count
+** Returns : (int) The number of songs
+*/
+
+GTimeVal
+song_sleep_time(GTimeVal *lastslept, long ticks);
+/* Caluculates the amount of seconds and microseconds to sleep.
+** Parameters: (GTimeVal *) lastslept: The time to start counting on
+** (long) ticks: Number of ticks to sleep
+** Returns : (GTimeVal) The amount of time to sleep
+*/
+
+GTimeVal
+song_next_wakeup_time(GTimeVal *lastslept, long ticks);
+/* Calculates the time at which "ticks" have passed, counting from "lastslept".
+** Parameters: (GTimeVal *) lastslept: The base to start counting on
+** (long) ticks: Number of ticks to count
+** Returns : (GTimeVal) A structure describing the time at which the
+** specified number of ticks has passed
+*/
+
+void
+song_lib_set_restore_behavior(songlib_t songlib, song_handle_t handle,
+ RESTORE_BEHAVIOR action);
+/* Determines what should be done with the song "handle" when
+** restoring it from a saved game.
+** Parameters: (songlib_t) songlib: The library that contains the song
+** (song_handle_t) handle: Its handle
+** (RESTORE_BEHAVIOR) action: The desired action
+*/
+
+#endif /* !_SCI_SOUND_SERVER_H_ */
diff --git a/engines/sci/include/sfx_time.h b/engines/sci/include/sfx_time.h
new file mode 100644
index 0000000000..a7b65eae20
--- /dev/null
+++ b/engines/sci/include/sfx_time.h
@@ -0,0 +1,93 @@
+/***************************************************************************
+ sfx_time.h Copyright (C) 2003,04 Christoph Reichenbach
+
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public Licence as
+ published by the Free Software Foundaton; either version 2 of the
+ Licence, or (at your option) any later version.
+
+ It is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ merchantibility or fitness for a particular purpose. See the
+ GNU General Public Licence for more details.
+
+ You should have received a copy of the GNU General Public Licence
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+
+ Please contact the maintainer for any program-related bug reports or
+ inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef _SFX_TIME_H_
+#define _SFX_TIME_H_
+
+typedef struct {
+ long secs;
+ long usecs;
+ int frame_rate;
+ int frame_offset;
+ /* Total time: secs + usecs + frame_offset/frame_rate */
+} sfx_timestamp_t;
+
+
+sfx_timestamp_t
+sfx_new_timestamp(long secs, long usecs, int frame_rate);
+/* Creates a new mutable timestamp
+** Parameters: (long x long) (secs, usecs): Initial timestamp
+** (int) frame_rate: Frame rate, for increasing the time stamp
+*/
+
+sfx_timestamp_t
+sfx_timestamp_add(sfx_timestamp_t timestamp, int frames);
+/* Adds a number of frames to a timestamp
+** Parameters: (sfx_timestampt_t *) timestamp: The timestamp to update
+** (int) frames: Number of frames to add
+** Returns : (sfx_timestamp_t) The increased timestamp
+*/
+
+sfx_timestamp_t
+sfx_timestamp_renormalise(sfx_timestamp_t timestamp, int new_freq);
+/* Translates a timestamp to a new base frame frequency
+** Parameters: (sfx_timestamp_t *) timestamp: The timestamp to normalise
+** (int) new_freq: The new frequency to normalise to
+** Returns : (sfx_timestamp_t) The re-normalised timestamp
+** The translation looses accuracy in the order of magnitude of milliseconds
+** for "usual" sampling frequencies.
+*/
+
+int
+sfx_timestamp_frame_diff(sfx_timestamp_t a, sfx_timestamp_t b);
+/* Computes the difference (# of frames) between two timestamps
+** Parameters: (sfx_timestamp) a: See below
+** (sfx_timestamp) b: See below
+** Returns : (int) a-b
+*/
+
+long
+sfx_timestamp_usecs_diff(sfx_timestamp_t a, sfx_timestamp_t b);
+/* Computes the difference (# of microseconds) between two timestamps
+** Parameters: (sfx_timestamp) a: See below
+** (sfx_timestamp) b: See below
+** Returns : (long) a-b
+*/
+
+void
+sfx_timestamp_gettime(sfx_timestamp_t *timestamp, long *secs, long *usecs);
+/* Determines the time described by a given timestamp
+** Parameters: (sfx_timestamp_t *) timestamp: Timestamp to read from
+** Returns : (int * x int *) (secs, usecs): Seconds and microseconds since
+** the epoch described there
+*/
+
+
+
+#endif /* !defined(_SFX_TIME_H_) */
diff --git a/engines/sci/include/sfx_timer.h b/engines/sci/include/sfx_timer.h
new file mode 100644
index 0000000000..d747edc3ac
--- /dev/null
+++ b/engines/sci/include/sfx_timer.h
@@ -0,0 +1,96 @@
+/***************************************************************************
+ sfx_timer.h Copyright (C) 2002..04 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef _FREESCI_SFX_TIMER_H_
+#define _FREESCI_SFX_TIMER_H_
+
+#include <sfx_core.h>
+
+typedef struct {
+ const char *name;
+ const char *version;
+
+ int delay_ms; /* Approximate delay (in milliseconds) between calls */
+ int flags;
+
+ int
+ (*set_option)(char *name, char *value);
+ /* Sets an option for the timing mechanism
+ ** Parameters: (char *) name: The name describing what to set
+ ** (char *) value: The value to set
+ ** Returns : (int) SFX_OK, or SFX_ERROR if the name wasn't understood
+ ** May be NULL
+ */
+
+ int
+ (*init)(void (*callback)(void *data), void *data);
+ /* Initializes the timer
+ ** Parameters: (void* -> void) callback:
+ ** 'data' must contain the next argument:
+ ** (void *) data: Must always be passed to the callback
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ ** This does not start the timer yet, it just specifies and initializes it.
+ ** This function is called exactly once (provided that the timer is used at all).
+ */
+
+ int
+ (*exit)(void);
+ /* Stops the timer
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ ** All resources allocated with the timer should be freed as an effect
+ ** of this.
+ */
+
+ int
+ (*block)(void);
+ /* Blocks the timer
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ ** When this function returns it is guaranteed that no timer callback is
+ ** currently being executed and that no new timer callback will occur
+ ** until unblock() is called.
+ */
+
+ int
+ (*unblock)(void);
+ /* Unblocks the timer
+ ** Returns : (int) SFX_OK on success, SFX_ERROR on failure
+ ** Any callbacks that were blocked should be executed immediately when
+ ** possible.
+ */
+} sfx_timer_t;
+
+extern sfx_timer_t *
+sfx_find_timer(char *name);
+/* Finds a timer by name
+** Parameters: (char *) name: Name of the timer to look up, or NULL for default
+** Returns : (sfx_timer_t *) The timer of matching name, or NULL
+** if not found
+** This does not consider timers provided by PCM devices; there must be
+** retrieved externally.
+*/
+
+#endif /* !_FREESCI_SFX_TIMER_H_ */
diff --git a/engines/sci/include/sys_strings.h b/engines/sci/include/sys_strings.h
new file mode 100644
index 0000000000..7c47e6350b
--- /dev/null
+++ b/engines/sci/include/sys_strings.h
@@ -0,0 +1,80 @@
+/***************************************************************************
+ sys_strings.h Copyright (C) 2002 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef _FREESCI_SYSTEM_STRINGS_H_
+#define _FREESCI_SYSTEM_STRINGS_H_
+
+#define SYS_STRINGS_MAX 4
+
+#define SYS_STRING_SAVEDIR 0
+#define SYS_STRING_PARSER_BASE 1
+
+#define MAX_PARSER_BASE 64
+
+typedef struct {
+ char *name;
+ int max_size;
+ char *value;
+} sys_string_t;
+
+typedef struct {
+ sys_string_t strings[SYS_STRINGS_MAX];
+} sys_strings_t;
+
+void
+sys_string_acquire(sys_strings_t *strings, int index, const char *name, int max_len);
+/* Reserves a new system string
+** Parameters: (sys_strings_t *) strings: The string table to reserve in
+** (int) index: Index number to reserve
+** (const char *) name: Name the entry should be tagged with
+** (int) max_len: Maximum string length in bytes
+*/
+
+int
+sys_string_set(sys_strings_t *strings, int index, const char *value);
+/* Sets the value of a system string
+** Parameters: (sys_strings_t *) strings: The string table to use
+** (int) index: Index of the string to write to
+** (const char *) value: The value to copy
+** Returns : 0 on success, 1 on error
+** Length clipping is performed.
+*/
+
+void
+sys_strings_restore(sys_strings_t *new_strings, sys_strings_t *old_strings);
+/* Cleanup system strings after a gamestate restore
+** Parameters: (sys_strings_t *) The freshly loaded system strings to clean up
+** (sys_strings_t *) The old system strings to clean up
+*/
+
+void
+sys_string_free_all(sys_strings_t *strings);
+/* Deallocates all allocated system strings
+** Parameters: (sys_strings_t *) strings: The string table to deallocate
+*/
+
+#endif /* !_FREESCI_SYSTEM_STRINGS_H_ */
diff --git a/engines/sci/include/uinput.h b/engines/sci/include/uinput.h
new file mode 100644
index 0000000000..7e6ff4e749
--- /dev/null
+++ b/engines/sci/include/uinput.h
@@ -0,0 +1,130 @@
+/***************************************************************************
+ uinput.h (C) 1999,2000,01,03 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CJR) [creichen@rbg.informatik.tu-darmstadt.de]
+
+***************************************************************************/
+/* unified input header file */
+
+#ifndef _SCI_UINPUT_H
+#define _SCI_UINPUT_H
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+
+struct _state;
+
+#define SCI_INPUT_DEFAULT_CLOCKTIME 100000
+#define SCI_INPUT_DEFAULT_REDRAWTIME 30000
+
+
+typedef struct {
+ short type;
+ short data;
+ short buckybits;
+ short character; /* for keyboard events: 'data' after applying
+ ** the effects of 'buckybits', e.g. if
+ ** type == SCI_EVT_KEYBOARD
+ ** data == 'a'
+ ** buckybits == SCI_EVM_LSHIFT
+ ** then
+ ** character == 'A'
+ ** For 'Alt', characters are interpreted by their
+ ** PC keyboard scancodes.
+ */
+} sci_event_t;
+
+/*Values for type*/
+#define SCI_EVT_NONE 0
+#define SCI_EVT_MOUSE_PRESS (1<<0)
+#define SCI_EVT_MOUSE_RELEASE (1<<1)
+#define SCI_EVT_KEYBOARD (1<<2)
+#define SCI_EVT_JOYSTICK (1<<6)
+#define SCI_EVT_SAID (1<<7)
+/*Fake values for other events*/
+#define SCI_EVT_ERROR (1<<10)
+#define SCI_EVT_QUIT (1<<11)
+#define SCI_EVT_NONBLOCK (1<<15)
+/* The QUIT event may be used to signal an external 'quit' command being
+** issued to the gfx driver. */
+#define SCI_EVT_ANY 0x7fff
+
+
+
+/* Keycodes of special keys: */
+#define SCI_K_ESC 27
+#define SCI_K_BACKSPACE 8
+#define SCI_K_ENTER 13
+#define SCI_K_TAB '\t'
+#define SCI_K_SHIFT_TAB (0xf << 8)
+
+#define SCI_K_END (79 << 8)
+#define SCI_K_DOWN (80 << 8)
+#define SCI_K_PGDOWN (81 << 8)
+#define SCI_K_LEFT (75 << 8)
+#define SCI_K_CENTER (76 << 8)
+#define SCI_K_RIGHT (77 << 8)
+#define SCI_K_HOME (71 << 8)
+#define SCI_K_UP (72 << 8)
+#define SCI_K_PGUP (73 << 8)
+#define SCI_K_INSERT (82 << 8)
+#define SCI_K_DELETE (83 << 8)
+
+#define SCI_K_F1 (59<<8)
+#define SCI_K_F2 (60<<8)
+#define SCI_K_F3 (61<<8)
+#define SCI_K_F4 (62<<8)
+#define SCI_K_F5 (63<<8)
+#define SCI_K_F6 (64<<8)
+#define SCI_K_F7 (65<<8)
+#define SCI_K_F8 (66<<8)
+#define SCI_K_F9 (67<<8)
+#define SCI_K_F10 (68<<8)
+
+#define SCI_K_SHIFT_F1 (84<<8)
+#define SCI_K_SHIFT_F2 (85<<8)
+#define SCI_K_SHIFT_F3 (86<<8)
+#define SCI_K_SHIFT_F4 (87<<8)
+#define SCI_K_SHIFT_F5 (88<<8)
+#define SCI_K_SHIFT_F6 (89<<8)
+#define SCI_K_SHIFT_F7 (90<<8)
+#define SCI_K_SHIFT_F8 (91<<8)
+#define SCI_K_SHIFT_F9 (92<<8)
+#define SCI_K_SHIFT_F10 (93<<8)
+
+/*Values for buckybits */
+#define SCI_EVM_RSHIFT (1<<0)
+#define SCI_EVM_LSHIFT (1<<1)
+#define SCI_EVM_CTRL (1<<2)
+#define SCI_EVM_ALT (1<<3)
+#define SCI_EVM_SCRLOCK (1<<4)
+#define SCI_EVM_NUMLOCK (1<<5)
+#define SCI_EVM_CAPSLOCK (1<<6)
+#define SCI_EVM_INSERT (1<<7)
+
+#define SCI_EVM_NO_FOOLOCK (~(SCI_EVM_SCRLOCK | SCI_EVM_NUMLOCK | SCI_EVM_CAPSLOCK | SCI_EVM_INSERT))
+#define SCI_EVM_ALL 0xFF
+
+#endif /* _SCI_UINPUT_H */
diff --git a/engines/sci/include/util.h b/engines/sci/include/util.h
new file mode 100644
index 0000000000..75ec2e6706
--- /dev/null
+++ b/engines/sci/include/util.h
@@ -0,0 +1,108 @@
+/***************************************************************************
+ util.h Copyright (C) 1999,2000,01 Magnus Reftel
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+#ifndef UTIL_H
+#define UTIL_H
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/* An excercise in bloated macro writing ;-)*/
+
+/*Declare a flexarray type*/
+#define FLEXARRAY(type, extra) struct{\
+ type* data;\
+ int used, size, itemsize;\
+ extra\
+}
+
+/* [DJ] Declare a flexarray type without extra fields - Visual C++ complains
+** when the FLEXARRAY macro is used and extra parameter is not specified
+*/
+#define FLEXARRAY_NOEXTRA(type) struct{\
+ type* data;\
+ int used, size, itemsize;\
+}
+
+/*Initialize a flexarray*/
+#define FLEXARRAY_INIT(type, array) do {(array).itemsize=sizeof(type); (array).size=0; (array).used=0;} while(0)
+
+/*Prints an error message and returns (from the function using the macro)*/
+#define FLEXARRAY_PANIC(message, errorcode) do{\
+ fprintf message;\
+ errorcode;\
+} while(0)
+
+/*Use if the state of the array is incnsistent*/
+#define FLEXARRAY_PANIC_BADSTATE(array, errorcode) FLEXARRAY_PANIC((stderr, "PANIC: flexarray "#array" is in an inconsistent state (%d,%d).\n", (array).used, (array).size), errorcode)
+
+/*Use if memory allocation fails*/
+#define FLEXARRAY_PANIC_MEMORY(array, bytes, errorcode) FLEXARRAY_PANIC((stderr, "PANIC: Unable to allocate %d bytes for flexarray"#array"\n", bytes), errorcode)
+
+/*Allocates an initial array*/
+#define FLEXARRAY_ALLOCATE_INITIAL(type, array, errorcode) do{\
+ (array).data= (type*)sci_malloc(4*(array).itemsize);\
+ if((array).data==0) FLEXARRAY_PANIC_MEMORY(array, 4*(array).itemsize, errorcode);\
+ (array).size=4;\
+ (array).used=0;\
+} while(0)
+
+/*Doubles the size of the allocated area*/
+#define FLEXARRAY_RESIZE(type, array, errorcode) do{\
+ int size=(array).size*2*(array).itemsize;\
+ (array).data= (type*)sci_realloc((array).data, size);\
+ if((array).data==0) FLEXARRAY_PANIC_MEMORY(array, size, errorcode);\
+ (array).size*=2;\
+} while(0)
+
+/*Appends /value/ at the end of the array, resizing as necessary*/
+#define FLEXARRAY_APPEND(type, array, value, errorcode) do\
+{\
+ if((array).used>=(array).size)\
+ {\
+ if((array).size==0) FLEXARRAY_ALLOCATE_INITIAL(type, array, errorcode);\
+ else {\
+ if((array).used==(array).size) FLEXARRAY_RESIZE(type, array, errorcode);\
+ else FLEXARRAY_PANIC_BADSTATE(array, errorcode);\
+ }\
+ }\
+ (array).data[(array).used++]=(value);\
+}while(0)
+
+/*Adds space for a value at the end of the array, resizing as necessary, but
+ *does not initialize the value*/
+#define FLEXARRAY_ADD_SPACE(type, array, items, errorcode) do{\
+ if((array).used+items>(array).size)\
+ {\
+ if((array).size==0) FLEXARRAY_ALLOCATE_INITIAL(type, array, errorcode);\
+ else if((array).used==(array).size) FLEXARRAY_RESIZE(type, array, errorcode);\
+ else FLEXARRAY_PANIC_BADSTATE(array, errorcode);\
+ }\
+ (array).used++;\
+} while(0)
+
+#endif
diff --git a/engines/sci/include/versions.h b/engines/sci/include/versions.h
new file mode 100644
index 0000000000..ed184d29c0
--- /dev/null
+++ b/engines/sci/include/versions.h
@@ -0,0 +1,169 @@
+
+/***************************************************************************
+ versions.h Copyright (C) 1999,2000,01 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CJR) [jameson@linuxgames.com]
+
+
+***************************************************************************/
+/* Versions management */
+
+#ifndef _SCI_VERSIONS_H_
+#define _SCI_VERSIONS_H_
+
+#include <scitypes.h>
+
+struct _state;
+
+#define SCI_VERSION(_major_, _minor_, _patchlevel_) (((_major_)<<20) | ((_minor_)<<10) | _patchlevel_)
+/* This allows version numbers to be compared directly */
+
+#define SCI_VERSION_MAJOR(_version_) ((_version_) >> 20)
+#define SCI_VERSION_MINOR(_version_) (((_version_) >> 10) & 0x3ff)
+#define SCI_VERSION_PATCHLEVEL(_version_) ((_version_) & 0x3ff)
+#define SCI_VERSION_IGNORE_PATCHLEVEL(_version_) ((_version) & ~0x3ff)
+
+/* Version number guide:
+** - Always use the version number of the first known version to have a special feature.
+** - Don't assume that special feature changes are linked just because they appeared to change
+** simultaneously.
+** - Put all the magic version numbers here, into THIS file.
+** - "FTU" means "First To Use"
+*/
+
+#define SCI_VERSION_LAST_SCI0 SCI_VERSION(0,000,685)
+
+#define SCI_VERSION_DEFAULT_SCI0 SCI_VERSION_LAST_SCI0
+/* AFAIK this is the last published SCI0 version */
+#define SCI_VERSION_DEFAULT_SCI01 SCI_VERSION(1,000,72)
+/* The version used by my implementation of QfG2 */
+
+
+#define SCI_VERSION_FTU_CENTERED_TEXT_AS_DEFAULT SCI_VERSION(0,000,629)
+/* Last version known not to do this: 0.000.502 */
+
+#define SCI_VERSION_FTU_NEW_GETTIME SCI_VERSION(0,000,629)
+/* These versions of SCI has a different set of subfunctions in GetTime() */
+
+#define SCI_VERSION_FTU_NEWER_DRAWPIC_PARAMETERS SCI_VERSION(0,000,502)
+/* Last version known not to do this: 0.000.435
+** Old SCI versions used to interpret the third DrawPic() parameter inversely,
+** with the opposite default value (obviously)
+*/
+
+#define SCI_VERSION_FTU_PRIORITY_14_ZONES SCI_VERSION(0,000,502)
+/* Last version known to do this: 0.000.490
+ * Uses 14 zones from 42 to 190 instead of 15 zones from 42 to 200.
+*/
+
+
+#define SCI_VERSION_FTU_NEW_SCRIPT_HEADER SCI_VERSION(0,000,395)
+/* Last version known not to do this: 0.000.343
+** Old SCI versions used two word header for script blocks (first word equal
+** to 0x82, meaning of the second one unknown). New SCI versions used one
+** word header.
+*/
+
+#define SCI_VERSION_LTU_BASE_OB1 SCI_VERSION(0,000,256)
+/* First version version known not to have this bug: ?
+** When doing CanBeHere(), augment y offset by 1
+*/
+
+#define SCI_VERSION_FTU_2ND_ANGLES SCI_VERSION(0,000,395)
+/* Last version known not to use this: ?
+** Earlier versions assign 120 degrees to left & right , and 60 to up and down.
+** Later versions use an even 90 degree distribution.
+*/
+
+#define SCI_VERSION_RESUME_SUSPENDED_SONG SCI_VERSION(0,000,490)
+/* First version (PQ2-new) known to use the different song resumption
+ mechanism -- When a new song is initialized, we store its state and
+ resume it when the new one finishes. Older versions completely
+ clobbered the old songs.
+*/
+
+#define SCI_VERSION_FTU_INVERSE_CANBEHERE SCI_VERSION(1,000,510)
+/* FIXME: This shouldn't be a version number.
+ * But it'll do for now.
+ */
+
+#define SCI_VERSION_FTU_LOFS_ABSOLUTE SCI_VERSION(1,000,200)
+/* First version known to do this: ?
+ In later versions (SCI1 and beyond), the argument of lofs[as]
+ instructions is absolute rather than relative.
+*/
+
+#define SCI_VERSION_FTU_DISPLAY_COORDS_FUZZY SCI_VERSION(1,000,510)
+/* First version known to do this: ?
+ In later versions of SCI1 kDisplay(), if the text would not fit on
+ the screen, the text is moved to the left and upwards until it
+ fits.
+*/
+
+#define SCI_VERSION_FTU_DOSOUND_VARIANT_1 SCI_VERSION(1,000,000)
+#define SCI_VERSION_FTU_DOSOUND_VARIANT_2 SCI_VERSION(1,000,510)
+
+
+typedef int sci_version_t;
+
+struct _state;
+
+void
+version_require_earlier_than(struct _state *s, sci_version_t version);
+/* Function used in autodetection
+** Parameters: (state_t *) s: state_t containing the version
+** (sci_version_t) version: The version that we're earlier than
+*/
+
+void
+version_require_later_than(struct _state *s, sci_version_t version);
+/* Function used in autodetection (read this function "version_require_later_than_or_equal_to")
+** Parameters: (state_t *) s: state_t containing the version
+** (sci_version_t) version: The version that we're later than
+*/
+
+int
+version_parse(char *vn, sci_version_t *result);
+/* Parse a string containing an SCI version number
+** Parameters: (char *) vn: The string to parse
+** Returns : (int) 0 on success, 1 on failure
+** (sci_version_t) *result: The resulting version number on success
+*/
+
+int
+version_detect_from_executable(sci_version_t *result);
+/* Try to detect version from Sierra executable in cwd
+** Returns : (int) 0 on success, 1 on failure
+** (sci_version_t) *result: The version number detected on success
+*/
+
+const char *
+version_guess_from_hashcode(sci_version_t *result, int *res_version, guint32 *code);
+/* Try to detect version from Sierra resource file(s) in cwd
+** Returns : (const char *) NULL on failure, the name of the associated game otherwise
+** (sci_version_t) *result: The version number detected on success
+** (int) *res_version: The resource version number detected on success
+** (guint32) *code: The resource hash code
+*/
+
+#endif /* !_SCI_VERSIONS_H_ */
diff --git a/engines/sci/include/vm.h b/engines/sci/include/vm.h
new file mode 100644
index 0000000000..567df073f5
--- /dev/null
+++ b/engines/sci/include/vm.h
@@ -0,0 +1,843 @@
+/***************************************************************************
+ vm.h Copyright (C) 2000,2001 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+/* VM and kernel declarations */
+
+
+#include <script.h>
+#include <vocabulary.h>
+#include <versions.h>
+#include <seg_manager.h>
+#include <vm_types.h>
+#include <sys_strings.h>
+#include <heapmgr.h>
+
+#ifndef _SCI_VM_H
+#define _SCI_VM_H
+
+#ifdef __cplusplus
+# define new new_
+# define delete delete_
+# define class class_
+#endif /* __cplusplus */
+
+#define VM_STACK_SIZE 0x1000
+/* Number of bytes to be allocated for the stack */
+
+#define SCRIPT_MAX_EXEC_STACK 256
+/* Maximum number of calls residing on the stack */
+#define SCRIPT_MAX_CLASSTABLE_SIZE 256
+/* Maximum number of entries in the class table */
+#define SCRIPT_MAX_CLONES 256
+/* Maximum number of cloned objects on the heap */
+
+
+#define SCRIPT_SELECTOR_OFFSET 8 -8
+/* Object-relative offset of the selector area inside a script */
+
+#define SCRIPT_LOCALVARPTR_OFFSET 2 -8
+/* Object-relative offset of the pointer to the underlying script's local variables */
+
+#define SCRIPT_SELECTORCTR_OFFSET 6 -8
+/* Object-relative offset of the selector counter */
+
+#define SCRIPT_FUNCTAREAPTR_OFFSET 4 -8
+/* Object-relative offset of the offset of the function area */
+
+#define SCRIPT_FUNCTAREAPTR_MAGIC 8 -8
+/* Offset that has to be added to the function area pointer */
+
+#define SCRIPT_NAME_OFFSET (s->version < SCI_VERSION(1,001,000) ? 14 -8 : 16)
+/* Offset of the name pointer */
+#define SCRIPT_NAME_SELECTOR (s->version < SCI_VERSION(1,001,000) ? 3 : 8)
+
+#define SCRIPT_INFO_OFFSET (s->version < SCI_VERSION(1,001,000) ? 12 -8 : 14)
+/* Object-relative offset of the -info- selector */
+#define SCRIPT_INFO_SELECTOR (s->version < SCI_VERSION(1,001,000) ? 2 : 7)
+
+#define SCRIPT_INFO_CLONE 0x0001
+/* Flag fo the -info- selector */
+
+#define SCRIPT_INFO_CLASS 0x8000
+/* Flag for the -info- selector */
+
+
+#define SCRIPT_OBJECT_MAGIC_NUMBER 0x1234
+/* Magical object identifier */
+#define SCRIPT_OBJECT_MAGIC_OFFSET (s->version < SCI_VERSION(1,001,000) ? -8 : 0)
+/* Offset of this identifier */
+
+#define SCRIPT_SPECIES_OFFSET 8 -8
+/* Script-relative offset of the species ID */
+
+#define SCRIPT_SUPERCLASS_OFFSET (s->version < SCI_VERSION(1,001,000) ? 10 -8 : 12)
+
+/*---------------------------------*/
+/* Script selector index variables */
+/*---------------------------------*/
+#define SCRIPT_SPECIES_SELECTOR (s->version < SCI_VERSION(1,001,000) ? 0 : 5)
+#define SCRIPT_SUPERCLASS_SELECTOR (s->version < SCI_VERSION(1,001,000) ? 1 : 6)
+
+#define SCRIPT_LOFS_MAGIC 3
+/* Magic adjustment value for lofsa and lofss */
+
+
+#define CALL_SP_CARRY NULL /* Stack pointer value: Use predecessor's value */
+
+
+#define SELECTOR_NONE 0
+#define SELECTOR_VARIABLE 1
+#define SELECTOR_METHOD 2
+/* Types of selectors as returned by grep_selector() below */
+
+typedef struct {
+ int script; /* number of the script the class is in, -1 for non-existing */
+ reg_t reg; /* offset; script-relative offset, segment: 0 if not instantiated */
+} class_t;
+
+#define RAW_GET_CLASS_INDEX(scr, reg) (int_hash_map_check_value((scr)->obj_indices, reg.offset, 0, NULL))
+#define RAW_IS_OBJECT(datablock) (getUInt16(((byte *) datablock) + SCRIPT_OBJECT_MAGIC_OFFSET) == SCRIPT_OBJECT_MAGIC_NUMBER)
+
+#define IS_CLASS(obj) (obj->variables[SCRIPT_INFO_SELECTOR].offset & SCRIPT_INFO_CLASS)
+
+/* This struct is used to buffer the list of send calls in send_selector() */
+typedef struct {
+ union {
+ reg_t func;
+ reg_t *var;
+ } address;
+ stack_ptr_t argp;
+ int argc;
+ selector_t selector;
+ stack_ptr_t sp; /* Stack pointer */
+ int type; /* Same as exec_stack_t.type */
+} calls_struct_t;
+
+typedef struct {
+ int script_id; /* Script ID this local variable block belongs to */
+ reg_t *locals;
+ int nr;
+} local_variables_t;
+
+#define OBJECT_FLAG_FREED (0x1 << 0) /* Clone has been marked as 'freed' */
+
+typedef struct {
+ int flags;
+ reg_t pos; /* Object offset within its script; for clones, this is their base */
+ int variables_nr;
+ int variable_names_nr; /* Number of variable names, may be less than variables_nr */
+ int methods_nr;
+ byte *base; /* Points to a buffer all relative references (code, strings) point to */
+ byte *base_obj; /* base + object offset within base */
+ guint16 *base_method; /* Pointer to the method selector area for this object */
+ guint16 *base_vars; /* Pointer to the varselector area for this object */
+ reg_t *variables;
+} object_t;
+
+typedef struct {
+ reg_t pos;
+ int size;
+} code_block_t;
+
+#define VM_OBJECT_GET_VARSELECTOR(obj, i) \
+ (s->version < SCI_VERSION(1,001,000) ? \
+ getUInt16(obj->base_obj + obj->variables_nr * 2 + i*2) : \
+ *(obj->base_vars + i))
+#define VM_OBJECT_READ_PROPERTY(obj, i) (obj->variables[i])
+#define VM_OBJECT_GET_FUNCSELECTOR(obj, i) \
+ (s->version < SCI_VERSION(1,001,000) ? \
+ getUInt16((byte *) (obj->base_method + i)) : \
+ getUInt16((byte *) (obj->base_method + i*2 + 1)))
+#define VM_OBJECT_READ_FUNCTION(obj, i) \
+ (s->version < SCI_VERSION(1,001,000) ? \
+ make_reg(obj->pos.segment, \
+ getUInt16((byte *) (obj->base_method \
+ + obj->methods_nr + 1 \
+ + i))) : \
+ make_reg(obj->pos.segment, \
+ getUInt16((byte *) (obj->base_method \
+ + i * 2 + 2))))
+
+
+
+
+//#define VM_OBJECT_SET_INDEX(ptr, index) { ((byte *) (ptr))[0] = (index) & 0xff; ((byte *) (ptr))[1] = ((index) >> 8) & 0xff; }
+#define VM_OBJECT_GET_INDEX(scr, reg) (int_hash_map_check_value(scr->obj_indices, reg.offset, 0, NULL))
+
+typedef struct {
+ int nr; /* Script number */
+ byte* buf; /* Static data buffer, or NULL if not used */
+ size_t buf_size;
+ size_t script_size;
+ size_t heap_size;
+
+ byte *synonyms; /* Synonyms block or 0 if not present*/
+ byte *heap_start; /* Start of heap if SCI1.1, NULL otherwise */
+ guint16 *export_table; /* Abs. offset of the export table or 0 if not present */
+
+ int_hash_map_t *obj_indices;
+
+ int exports_nr; /* Number of entries in the exports table */
+ int synonyms_nr; /* Number of entries in the synonyms block */
+ int lockers; /* Number of classes and objects that require this script */
+
+ object_t *objects; /* Table for objects, contains property variables */
+ /* Indexed by the value stored at SCRIPT_LOCALVARPTR_OFFSET,
+ ** see VM_OBJECT_[GS]ET_INDEX() */
+ int objects_nr; /* Number of objects and classes */
+ int objects_allocated; /* Number of allocated objects */
+
+ int locals_offset;
+ int locals_segment; /* The local variable segment */
+ local_variables_t *locals_block;
+
+ code_block_t *code;
+ int code_blocks_nr;
+ int code_blocks_allocated;
+ int relocated;
+ int marked_as_deleted;
+} script_t;
+
+typedef struct {
+ int nr; /* Number of stack entries */
+ reg_t *entries;
+} dstack_t; /* Data stack */
+
+#define CLONE_USED -1
+#define CLONE_NONE -1
+
+typedef object_t clone_t;
+
+typedef struct _node_struct {
+ reg_t pred, succ; /* Predecessor, successor */
+ reg_t key;
+ reg_t value;
+} node_t; /* List nodes */
+
+typedef struct _list_struct {
+ reg_t first;
+ reg_t last;
+} list_t;
+
+typedef struct {
+ void *mem;
+ unsigned int size;
+ const char *type;
+} hunk_t;
+
+/* clone_table_t */
+DECLARE_HEAPENTRY(clone)
+/* node_table_t */
+DECLARE_HEAPENTRY(node)
+/* list_table_t */
+DECLARE_HEAPENTRY(list) /* list entries */
+/* hunk_table_t */
+DECLARE_HEAPENTRY(hunk)
+
+typedef struct {
+ int size;
+ const char *description;
+ byte *buf;
+} dynmem_t; /* Free-style memory */
+
+typedef struct _mem_obj {
+ int type;
+ int segmgr_id; /* Internal value used by the seg_manager's hash map */
+ union {
+ script_t script;
+ clone_table_t clones;
+ local_variables_t locals;
+ dstack_t stack;
+ sys_strings_t sys_strings;
+ list_table_t lists;
+ node_table_t nodes;
+ hunk_table_t hunks;
+ dynmem_t dynmem;
+ char *reserved;
+ } data;
+} mem_obj_t;
+
+
+
+typedef struct {
+ selector_t init; /* Init function */
+ selector_t play; /* Play function (first function to be called) */
+ selector_t replay; /* Replay function */
+ selector_t x, y, z; /* Coordinates */
+ selector_t priority;
+ selector_t view, loop, cel; /* Description of a specific image */
+ selector_t brLeft, brRight, brTop, brBottom; /* Bounding Rectangle */
+ selector_t xStep, yStep; /* BR adjustments */
+ selector_t nsLeft, nsRight, nsTop, nsBottom; /* View boundaries ('now seen') */
+ selector_t text, font; /* Used by controls */
+ selector_t type, state; /* Used by contols as well */
+ selector_t doit; /* Called (!) by the Animate() system call */
+ selector_t signal; /* Used by Animate() to control a view's behaviour */
+ selector_t underBits; /* Used by the graphics subroutines to store backupped BG pic data */
+
+ /* The following selectors are used by the Bresenham syscalls: */
+ selector_t canBeHere; /* Funcselector: Checks for movement validity */
+ selector_t client; /* The object that wants to be moved */
+ selector_t cycler; /* The cycler of the client */
+ selector_t dx, dy; /* Deltas */
+ selector_t edgeHit;
+ selector_t b_movCnt, b_i1, b_i2, b_di, b_xAxis, b_incr; /* Various Bresenham vars */
+ selector_t completed;
+
+ selector_t illegalBits; /* Used by CanBeHere */
+ selector_t dispose;
+
+ selector_t prevSignal; /* Used by DoSound */
+
+ selector_t message, modifiers; /* Used by GetEvent */
+
+ selector_t owner, handle;
+ selector_t cue;
+ selector_t number;
+
+ selector_t max, cursor; /* Used by EditControl */
+ selector_t mode; /* Used by text controls (-> DrawControl()) */
+
+ selector_t wordFail, syntaxFail, semanticFail; /* Used by Parse() */
+
+ selector_t claimed; /* Used generally by the event mechanism */
+
+ selector_t elements; /* Used by SetSynonyms() */
+
+ selector_t lsTop, lsBottom, lsRight, lsLeft; /* Used by Animate() subfunctions and scroll list controls */
+
+ selector_t baseSetter; /* Alternative baseSetter */
+
+ selector_t who, distance; /* Used for 'chasing' movers */
+
+ selector_t looper, mover, isBlocked, heading; /* Used in DoAvoider */
+
+ selector_t caller, moveDone, moveSpeed; /* Used for DoBresen */
+
+ selector_t delete; /* Called by Animate() to dispose a view object */
+
+ selector_t vol;
+ selector_t pri;
+
+ selector_t min; /* SMPTE time format */
+ selector_t sec;
+ selector_t frame;
+
+ selector_t dataInc;
+ selector_t size;
+ selector_t palette;
+ selector_t cantBeHere;
+ selector_t nodePtr;
+ selector_t flags;
+
+ selector_t points; /* Used by AvoidPath() */
+} selector_map_t; /* Contains selector IDs for a few selected selectors */
+
+typedef struct {
+ reg_t obj;
+ reg_t *signalp; /* Used only indirectly */
+ reg_t *underBitsp; /* The same goes for the handle storage */
+ int underBits; /* Copy of the underbits: Needed for cleanup */
+
+ int x, y;
+ int priority;
+ byte *view;
+ int view_nr, loop, cel; /* view_nr is ised for save/restore */
+ int nsTop, nsLeft, nsRight, nsBottom;
+ int real_y, z, index_nr; /* Used for sorting */
+} view_object_t;
+
+#define VAR_GLOBAL 0
+#define VAR_LOCAL 1
+#define VAR_TEMP 2
+#define VAR_PARAM 3
+
+#define EXEC_STACK_TYPE_CALL 0
+#define EXEC_STACK_TYPE_KERNEL 1
+#define EXEC_STACK_TYPE_VARSELECTOR 2
+
+typedef struct {
+ reg_t objp;
+ reg_t sendp; /* Pointer to the object containing the invoked method */
+ union {
+ reg_t *varp; /* Variable pointer for read/write access */
+ reg_t pc; /* Not accurate for the TOS element */
+ } addr;
+ stack_ptr_t fp; /* Frame pointer */
+ stack_ptr_t sp; /* Stack pointer */
+ int argc;
+
+ /* former variables[4]: [all other values are derived] */
+ stack_ptr_t variables_argp; /* Argument pointer */
+ seg_id_t local_segment; /* local variables etc. */
+
+ selector_t selector; /* The selector which was used to call or -1 if not applicable */
+ int origin; /* The stack frame position the call was made from, or -1 if it
+ ** was the initial call. */
+ byte type; /* EXEC_STACK_TYPE* */
+
+} exec_stack_t;
+
+typedef struct _breakpoint {
+ int type;
+ union {
+ guint32 address; /* Breakpoints on exports */
+ char *name; /* Breakpoints on selector names */
+ } data;
+ struct _breakpoint *next;
+} breakpoint_t;
+
+#define BREAK_SELECTOR 1
+/* Break when selector is executed. data contains (char *) selector name
+ (in the format Object::Method) */
+
+#define BREAK_EXPORT 2
+/* Break when an exported function is called. data contains script_no << 16 |
+ export_no. */
+
+extern DLLEXTERN int script_debug_flag;
+/* Set this to 1 to activate script debugging */
+
+extern int script_error_flag;
+/* Set to 1 to move pc back to last position, even though action is executed */
+
+extern int script_checkloads_flag;
+/* Displays the numbers of scripts when they are (un)loaded */
+
+#define SCRIPT_ABORT_WITH_REPLAY 1025
+extern DLLEXTERN int script_abort_flag;
+/* Set this to 1 to abort script execution immediately. Aborting will leave the
+** debug exec stack intact.
+** Set it to SCRIPT_ABORT_WITH_REPLAY to force a replay afterwards.
+*/
+
+#define GC_INTERVAL 32768 /* Number of kernel calls in between gcs; should be < 50000 */
+
+extern int script_gc_interval;
+/* Initially GC_DELAY, can be set at runtime */
+
+extern int script_step_counter;
+/* Number of steps executed */
+
+
+extern DLLEXTERN const char *(*_debug_get_input)(void);
+/* The function used to get input for debugging */
+
+extern DLLEXTERN int _debugstate_valid;
+extern DLLEXTERN int _debug_seeking;
+extern DLLEXTERN int _debug_step_running;
+
+
+typedef int kernel_function(struct _state* s);
+
+extern kernel_function* kfuncs[];
+extern int max_instance;
+
+/*inline*/ exec_stack_t *
+execute_method(struct _state *s, word script, word pubfunct, stack_ptr_t sp, reg_t calling_obj,
+ word argc, stack_ptr_t argp);
+/* Executes function pubfunct of the specified script.
+** Parameters: (state_t *) s: The state which is to be executed with
+** (word) script: The script which is called
+** (word) pubfunct: The exported script function which is to be called
+** (stack_ptr_t) sp: Stack pointer position
+** (reg_t) calling_obj: The heap address of the object which executed the call
+** (word) argc: Number of arguments supplied
+** (stack_ptr_t) argp: Pointer to the first supplied argument
+** Returns : (exec_stack_t *): A pointer to the new exec stack TOS entry
+*/
+
+
+exec_stack_t *
+send_selector(struct _state *s, reg_t send_obj, reg_t work_obj,
+ stack_ptr_t sp, int framesize, stack_ptr_t argp);
+/* Executes a "send" or related operation to a selector
+** Parameters: (state_t *) s: The state_t to operate on
+** (reg_t) send_obj: Heap address of the object to send to
+** (reg_t) work_obj: Heap address of the object initiating the send
+** (stack_ptr_t) sp: Stack pointer position
+** (int) framesize: Size of the send as determined by the "send" operation
+** (stack_ptr_t) argp: Pointer to the beginning of the heap block containing the
+** data to be send. This area is a succession of one or more
+** sequences of [selector_number][argument_counter] and then
+** "argument_counter" word entries with the parameter values.
+** Returns : (exec_stack_t *): A pointer to the new execution stack TOS entry
+*/
+
+
+#define SCI_XS_CALLEE_LOCALS -1
+
+exec_stack_t *
+add_exec_stack_entry(struct _state *s, reg_t pc, stack_ptr_t sp, reg_t objp, int argc,
+ stack_ptr_t argp, selector_t selector, reg_t sendp, int origin,
+ seg_id_t local_segment);
+/* Adds an entry to the top of the execution stack
+** Parameters: (state_t *) s: The state with which to execute
+** (reg_t) pc: The initial program counter
+** (stack_ptr_t) sp: The initial stack pointer
+** (reg_t) objp: Pointer to the beginning of the current object
+** (int) argc: Number of parameters to call with
+** (stack_ptr_t) argp: Heap pointer to the first parameter
+** (selector_t) selector: The selector by which it was called or
+** NULL_SELECTOR if n.a. For debugging.
+** (reg_t) sendp: Pointer to the object which the message was sent to.
+** Equal to objp for anything but super.
+** (int) origin: Number of the execution stack element this entry was created by
+** (usually the current TOS number, except for multiple sends).
+** (seg_id_t) local_segment: The segment to use for local variables,
+** or SCI_XS_CALLEE_LOCALS to use obj's segment.
+** Returns : (exec_stack_t *): A pointer to the new exec stack TOS entry
+*/
+
+
+exec_stack_t *
+add_exec_stack_varselector(struct _state *s, reg_t objp, int argc, stack_ptr_t argp,
+ selector_t selector, reg_t *address, int origin);
+/* Adds one varselector access to the execution stack
+** Parameters: (state_t *) s: The state_t to use
+** (reg_t) objp: Pointer to the object owning the selector
+** (int) argc: 1 for writing, 0 for reading
+** (stack_ptr_t) argp: Pointer to the address of the data to write -2
+** (int) selector: Selector name
+** (reg_t *) address: Heap address of the selector
+** (int) origin: Stack frame which the access originated from
+** Returns : (exec_stack_t *): Pointer to the new exec-TOS element
+** This function is called from send_selector only.
+*/
+
+
+void
+run_vm(struct _state *s, int restoring);
+/* Executes the code on s->heap[pc] until it hits a 'ret' operation while (stack_base == stack_pos)
+** Parameters: (state_t *) s: The state to use
+** (int) restoring: 1 if s has just been restored, 0 otherwise
+** Returns : (void)
+** This function will execute SCI bytecode. It requires s to be set up
+** correctly.
+*/
+
+void
+vm_handle_fatal_error(struct _state *s, int line, const char *file);
+/* Handles a fatal error condition
+** Parameters: (state_t *) s: The state to recover from
+** (int) line: Source code line number the error occured in
+** (const char *) file: File the error occured in
+*/
+
+
+void
+script_debug(struct _state *s, reg_t *pc, stack_ptr_t *sp, stack_ptr_t *pp, reg_t *objp,
+ int *restadjust,
+ seg_id_t *segids, reg_t **variables, reg_t **variables_base,
+ int *variables_nr,
+ int bp);
+/* Debugger functionality
+** Parameters: (state_t *) s: The state at which debugging should take place
+** (reg_t *) pc: Pointer to the program counter
+** (stack_ptr_t *) sp: Pointer to the stack pointer
+** (stack_ptr_t *) pp: Pointer to the frame pointer
+** (reg_t *) objp: Pointer to the object base pointer
+** (int *) restadjust: Pointer to the &rest adjustment value
+** (seg_id_t *) segids: four-element array containing segment IDs for locals etc.
+** (reg_t **) variables: four-element array referencing registers for globals etc.
+** (reg_t **) variables_base: four-element array referencing
+** register bases for temps etc.
+** (int *) variables_nr: four-element array giving sizes for params etc. (may be NULL)
+** (int) bp: Flag, set to 1 when a breakpoint is triggered
+** Returns : (void)
+*/
+
+int
+script_init_engine(struct _state *s, sci_version_t version);
+/* Initializes a state_t block
+** Parameters: (state_t *) s: The state to initialize
+** Returns : 0 on success, 1 if vocab.996 (the class table) is missing or corrupted
+*/
+
+void
+script_set_gamestate_save_dir(struct _state *s, const char *path);
+/* Sets the gamestate's save_dir to the parameter path
+** Parameters: (state_t *) s: The state to set
+** (const char *) path: Path where save_dir will point to
+** Returns : (void)
+*/
+
+void
+script_free_engine(struct _state *s);
+/* Frees all additional memory associated with a state_t block
+** Parameters: (state_t *) s: The state_t whose elements should be cleared
+** Returns : (void)
+*/
+
+void
+script_free_vm_memory(struct _state *s);
+/* Frees all script memory (heap, hunk, and class tables).
+** Parameters: (state_t *) s: The state_t to free
+** Returns : (void)
+** This operation is implicit in script_free_engine(), but is required for restoring
+** the game state.
+*/
+
+
+int
+lookup_selector(struct _state *s, reg_t obj, selector_t selectorid, reg_t **vptr, reg_t *fptr);
+/* Looks up a selector and returns its type and value
+** Parameters: (state_t *) s: The state_t to use
+** (reg_t) obj: Address of the object to look the selector up in
+** (selector_t) selectorid: The selector to look up
+** Returns : (int) SELECTOR_NONE if the selector was not found in the object or its superclasses.
+** SELECTOR_VARIABLE if the selector represents an object-relative variable
+** SELECTOR_METHOD if the selector represents a method
+** (reg_t *) *vptr: A pointer to the storage space associated with the selector, if
+** it is a variable
+** (reg_t) *fptr: A reference to the function described by that selector, if it is
+** a valid function selector.
+** *vptr is written to iff it is non-NULL and the selector indicates a property of the object.
+** *fptr is written to iff it is non-NULL and the selector indicates a member function of that object.
+*/
+
+
+#define SCRIPT_GET_DONT_LOAD 0 /* Fail if not loaded */
+#define SCRIPT_GET_LOAD 1 /* Load, if neccessary */
+#define SCRIPT_GET_LOCK 3 /* Load, if neccessary, and lock */
+
+seg_id_t
+script_get_segment(struct _state *s, int script_id, int load);
+/* Determines the segment occupied by a certain script
+** Parameters: (state_t *) s: The state to operate on
+** (int) script_id: The script in question
+** (int) load: One of SCRIPT_GET_*
+** Returns : The script's segment, or 0 on failure
+*/
+
+reg_t
+script_lookup_export(struct _state *s, int script_nr, int export_index);
+/* Looks up an entry of the exports table of a script
+** Parameters: (state_t *) s: The state to operate on
+** (int) script_nr: The script to look up in
+** Returns : (int) export_index: index of the export entry to look up
+*/
+
+int
+script_instantiate(struct _state *s, int script_nr);
+/* Makes sure that a script and its superclasses get loaded to the heap
+** Parameters: (state_t *) s: The state to operate on
+** (int) script_nr: The script number to load
+** Returns : (int) The script's segment ID or 0 if out of heap
+** If the script already has been loaded, only the number of lockers is increased.
+** All scripts containing superclasses of this script aret loaded recursively as well,
+** unless 'recursive' is set to zero.
+** The complementary function is "script_uninstantiate()" below.
+*/
+
+
+void
+script_uninstantiate(struct _state *s, int script_nr);
+/* Decreases the numer of lockers of a script and unloads it if that number reaches zero
+** Parameters: (state_t *) s: The state to operate on
+** (int) script_nr: The script number that is requestet to be unloaded
+** Returns : (void)
+** This function will recursively unload scripts containing its superclasses, if those
+** aren't locked by other scripts as well.
+*/
+
+
+int
+game_save_state(struct _state *s, char *name, int coredump);
+/* Saves the game state to the harddisk
+** Parameters: (state_t *) s: The game state to save
+** (char *) name: Name of the subdirectory (relative to s->save_dir)
+** (int) coredump: Set to non-zero in order to write additional debug information
+** Returns : (int) 0 on success, 1 otherwise
+*/
+
+
+struct _state *
+game_restore_state(char *name);
+/* Restores the game state from a file
+** Parameters: (char *) name: Name of the saved game state to restore
+** Returns : (state_t *): The restored game state, or NULL on failure
+*/
+
+
+int
+game_init(struct _state *s);
+/* Initializes an SCI game
+** Parameters: (state_t *) s: The state to operate on
+** Returns : (int): 0 on success, 1 if an error occured.
+** This function must be run before script_run() is executed.
+** Graphics data is initialized iff s->gfx_state != NULL.
+*/
+
+int
+game_init_graphics(struct _state *s);
+/* Initializes the graphics part of an SCI game
+** Parameters: (state_t *) s: The state to initialize the graphics in
+** Returns : (int) 0 on success, 1 if an error occured
+** This function may only be called if game_init() did not initialize
+** the graphics data.
+*/
+
+int
+game_init_sound(struct _state *s, int sound_flags);
+/* Initializes the sound part of an SCI game
+** Parameters: (state_t *) s: The state to initialize the sound in
+** (int) sound_flags: Flags to pass to the sound subsystem
+** Returns : (int) 0 on success, 1 if an error occured
+** This function may only be called if game_init() did not initialize
+** the graphics data.
+*/
+
+
+int
+game_run(struct _state **s);
+/* Runs an SCI game
+** Parameters: (state_t **) s: Pointer to the pointer of the state to operate on
+** Returns : (int): 0 on success, 1 if an error occured.
+** This is the main function for SCI games. It takes a valid state, loads script 0 to it,
+** finds the game object, allocates a stack, and runs the init method of the game object.
+** In layman's terms, this runs an SCI game.
+** By the way, *s may be changed during the game, e.g. if a game state is restored.
+*/
+
+int
+game_restore(struct _state **s, char *savegame_name);
+/* Restores an SCI game state and runs the game
+** Parameters: (state_t **) s: Pointer to the pointer of the state to operate on
+** (char *) savegame_name: Name of the savegame to restore
+** Returns : (int): 0 on success, 1 if an error occured.
+** This restores a savegame; otherwise, it behaves just like game_run().
+*/
+
+int
+game_exit(struct _state *s);
+/* Uninitializes an initialized SCI game
+** Parameters: (state_t *) s: The state to operate on
+** Returns : (int): 0 on success, 1 if an error occured.
+** This function should be run after each script_run() call.
+*/
+
+void
+quit_vm(void);
+/* Instructs the virtual machine to abort
+** Paramteres: (void)
+** Returns : (void)
+*/
+
+void
+script_map_selectors(struct _state *s, selector_map_t *map);
+/* Maps special selectors
+** Parameters: (state_t *) s: The state from which the selector information should be taken
+** (selector_map_t *) map: Pointer to the selector map to map
+** Returns : (void)
+** Called by script_run();
+*/
+
+int
+script_map_kernel(struct _state *s);
+/* Maps kernel functions
+** Parameters: (state_t *) s: The state which the kernel_names are retreived from
+** Returns : (void)
+** This function reads from and writes to s. It is called by script_run().
+*/
+
+
+void
+script_detect_versions(struct _state *s);
+/* Detects SCI versions by their different script header
+** Parameters: (state_t *) s: The state to operate on
+** Returns : (void)
+*/
+
+reg_t
+kalloc(struct _state *s, const char *type, int space);
+/* Allocates "kernel" memory and returns a handle suitable to be passed on to SCI scripts
+** Parameters: (state_t *) s: Pointer to the state_t to operate on
+** (const char *) type: A free-form type description string (static)
+** (int) space: The space to allocate
+** Returns : (reg_t) The handle
+*/
+
+int
+has_kernel_function(struct _state *s, const char *kname);
+/* Detects whether a particular kernel function is required in the game
+** Parameters: (state_t *) s: Pointer to the state_t to operate on
+** (const char *) kname: The name of the desired kernel function
+** Returns : (int) 1 if the kernel function is listed in the kernel table,
+** 0 otherwise
+*/
+
+byte *
+kmem(struct _state *s, reg_t handle);
+/* Returns a pointer to "kernel" memory based on the handle
+** Parameters: (state_t *) s: Pointer to the state_t to operate on
+** (reg_t) handle: The handle to use
+** Returns : (byte *) A pointer to the allocated memory
+*/
+
+
+int
+kfree(struct _state *s, reg_t handle);
+/* Frees all "kernel" memory associated with a handle
+** Parameters: (state_t *) s: Pointer to the state_t to operate on
+** (reg_t) handle: The handle to free
+** Returns : (int) 0 on success, 1 otherwise
+*/
+
+const char *
+obj_get_name(struct _state *s, reg_t pos);
+/* Determines the name of an object
+** Parameters: (state_t *) s: Pointer to the state_t to operate on
+** (reg_t) pos: Location of the object whose name we want to
+** inspect
+** Returns : (const char *) A name for that object, or a string describing
+** an error that occured while looking it up
+** The string is stored in a static buffer and need not be freed (neither
+** may it be modified).
+*/
+
+object_t *
+obj_get(struct _state *s, reg_t offset);
+/* Retreives an object from the specified location
+** Parameters: (state_t *) s: Pointer to the state_t to operate on
+** (reg_t) offset: The object's offset
+** Returns : (object_t *) The object in question, or NULL if there is none
+*/
+
+int
+test_savegame(struct _state *s, char *savegame_id, char *savegame_name, int savegame_name_length);
+/* Simple savegame validity check
+** Parameters: (state_t *) s: Pointer to the state_t to operate on
+** (char *) savegame_id: Name of the savegame to check
+** (char *) savegame_name: Pointer to a static buffer the savegame
+** name string should be stored in
+** (int) savegame_name_length: Max. number of bytes to write into the
+** static string
+** Returns : (int) 1 if it might be a savegame, 0 if not
+*/
+
+#endif /* !_SCI_VM_H */
diff --git a/engines/sci/include/vm_types.h b/engines/sci/include/vm_types.h
new file mode 100644
index 0000000000..66758425ae
--- /dev/null
+++ b/engines/sci/include/vm_types.h
@@ -0,0 +1,71 @@
+/***************************************************************************
+ vm_types.h Copyright (C) 2002 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CR) <jameson@linuxgames.com>
+
+***************************************************************************/
+
+
+#ifndef _SCI_VM_TYPES_H_
+#define _SCI_VM_TYPES_H_
+
+#include <scitypes.h>
+
+#define SCI_REG_SIZE 16;
+#define SCI_SEG_SIZE 16;
+
+typedef int seg_id_t; /* Segment ID type */
+
+struct _state; /* engine.h */
+
+typedef struct {
+ guint16 segment;
+ guint16 offset;
+} reg_t;
+
+#define PREG "%04x:%04x"
+#define PRINT_REG(r) (0xffff) & (unsigned) (r).segment, (unsigned) (r).offset
+
+typedef reg_t *stack_ptr_t; /* Stack pointer type */
+typedef int selector_t; /* Selector ID */
+#define NULL_SELECTOR -1
+
+#define PSTK "ST:%04x"
+#define PRINT_STK(v) (unsigned) (v - s->stack_base)
+
+static inline reg_t
+make_reg(int segment, int offset)
+{
+ reg_t r;
+ r.offset = offset;
+ r.segment = segment;
+ return r;
+}
+
+#define IS_NULL_REG(r) (!((r).offset || (r).segment))
+#define REG_EQ(a, b) (((a).offset == (b).offset) && ((a).segment == (b).segment))
+#define NULL_REG_INITIALIZER {0, 0}
+extern reg_t NULL_REG;
+
+
+#endif /* !_SCI_VM_TYPES_H_ */
diff --git a/engines/sci/include/vocabulary.h b/engines/sci/include/vocabulary.h
new file mode 100644
index 0000000000..fb58dd644b
--- /dev/null
+++ b/engines/sci/include/vocabulary.h
@@ -0,0 +1,424 @@
+/***************************************************************************
+ vocabulary.h Copyright (C) 1999,2000,01 Christoph Reichenbach
+
+
+ This program may be modified and copied freely according to the terms of
+ the GNU general public license (GPL), as long as the above copyright
+ notice and the licensing information contained herein are preserved.
+
+ Please refer to www.gnu.org for licensing details.
+
+ This work is provided AS IS, without warranty of any kind, expressed or
+ implied, including but not limited to the warranties of merchantibility,
+ noninfringement, and fitness for a specific purpose. The author will not
+ be held liable for any damage caused by this work or derivatives of it.
+
+ By using this source code, you agree to the licensing terms as stated
+ above.
+
+
+ Please contact the maintainer for bug reports or inquiries.
+
+ Current Maintainer:
+
+ Christoph Reichenbach (CJR) [jameson@linuxgames.com]
+
+***************************************************************************/
+
+#ifndef VOCABULARY_H
+#define VOCABULARY_H
+
+#include <versions.h>
+#include <sciresource.h>
+
+/*#define VOCABULARY_DEBUG */
+/*#define SCI_SIMPLE_SAID_CODE */ /* Whether the simplified Said() matching should be used */
+/*#define SCI_SIMPLE_SAID_DEBUG */ /* uncomment to enable simple said debugging */
+
+
+#define SCRIPT_UNKNOWN_FUNCTION_STRING "[Unknown]"
+/* The string used to identify the "unknown" SCI0 function for each game */
+
+#define PARSE_HEAP_SIZE 64
+/* Number of bytes allocated on the heap to store bad words if parsing fails */
+
+
+typedef struct opcode_
+{
+ int type;
+ int number;
+ char* name;
+} opcode;
+
+#define VOCAB_RESOURCE_OPCODES 998
+#define VOCAB_RESOURCE_KNAMES 999
+
+#define VOCAB_RESOURCE_SCI0_MAIN_VOCAB 0
+#define VOCAB_RESOURCE_SCI0_PARSE_TREE_BRANCHES 900
+#define VOCAB_RESOURCE_SCI0_SUFFIX_VOCAB 901
+
+#define VOCAB_RESOURCE_SCI1_MAIN_VOCAB 900
+#define VOCAB_RESOURCE_SCI1_PARSE_TREE_BRANCHES 901
+#define VOCAB_RESOURCE_SCI1_SUFFIX_VOCAB 902
+#define VOCAB_RESOURCE_SCI1_CHAR_TRANSFORMS 913
+
+#define VOCAB_CLASS_PREPOSITION 0x01
+#define VOCAB_CLASS_ARTICLE 0x02
+#define VOCAB_CLASS_ADJECTIVE 0x04
+#define VOCAB_CLASS_PRONOUN 0x08
+#define VOCAB_CLASS_NOUN 0x10
+#define VOCAB_CLASS_INDICATIVE_VERB 0x20
+#define VOCAB_CLASS_ADVERB 0x40
+#define VOCAB_CLASS_IMPERATIVE_VERB 0x80
+#define VOCAB_CLASS_NUMBER 0x001
+
+extern DLLEXTERN const char *class_names[]; /* Vocabulary class names */
+
+#define VOCAB_CLASS_ANYWORD 0xff
+/* Anywords are ignored by the parser */
+
+#define VOCAB_MAGIC_NUMBER_GROUP 0xffd /* 0xffe ? */
+/* This word class is used for numbers */
+
+#define VOCAB_TREE_NODES 500
+/* Number of nodes for each parse_tree_node structure */
+
+#define VOCAB_TREE_NODE_LAST_WORD_STORAGE 0x140
+#define VOCAB_TREE_NODE_COMPARE_TYPE 0x146
+#define VOCAB_TREE_NODE_COMPARE_GROUP 0x14d
+#define VOCAB_TREE_NODE_FORCE_STORAGE 0x154
+
+#define SAID_COMMA 0xf0
+#define SAID_AMP 0xf1
+#define SAID_SLASH 0xf2
+#define SAID_PARENO 0xf3
+#define SAID_PARENC 0xf4
+#define SAID_BRACKO 0xf5
+#define SAID_BRACKC 0xf6
+#define SAID_HASH 0xf7
+#define SAID_LT 0xf8
+#define SAID_GT 0xf9
+#define SAID_TERM 0xff
+
+#define SAID_FIRST SAID_COMMA
+
+/* There was no 'last matching word': */
+#define SAID_FULL_MATCH 0xffff
+#define SAID_NO_MATCH 0xfffe
+#define SAID_PARTIAL_MATCH 0xfffd
+
+#define SAID_LONG(x) ((x) << 8)
+
+typedef struct {
+
+ int w_class; /* Word class */
+ int group; /* Word group */
+ char word[1]; /* The actual word */
+
+} word_t;
+
+
+typedef struct {
+ int id; /* non-terminal ID */
+ int first_special; /* first terminal or non-terminal */
+ int specials_nr; /* number of terminals and non-terminals */
+ int length;
+ int data[1]; /* actual data (size 1 to avoid compiler warnings) */
+} parse_rule_t;
+
+
+typedef struct _parse_rule_list {
+ int terminal; /* Terminal character this rule matches against or 0 for a non-terminal rule */
+ parse_rule_t *rule;
+ struct _parse_rule_list *next;
+} parse_rule_list_t;
+
+
+typedef struct {
+
+ int class_mask; /* the word class this suffix applies to */
+ int result_class; /* the word class a word is morphed to if it doesn't fail this check */
+
+ int alt_suffix_length; /* String length of the suffix */
+ int word_suffix_length; /* String length of the other suffix */
+
+ char *alt_suffix; /* The alternative suffix */
+ char *word_suffix; /* The suffix as used in the word vocabulary */
+
+} suffix_t;
+
+
+typedef struct {
+
+ int w_class; /* Word class */
+ int group; /* Word group */
+
+} result_word_t;
+
+
+typedef struct
+{
+ int replaceant; /* The word group to replace */
+ int replacement; /* The replacement word group for this one */
+} synonym_t;
+
+
+typedef struct {
+
+ int id;
+
+ int data[10];
+
+} parse_tree_branch_t;
+
+#define PARSE_TREE_NODE_LEAF 0
+#define PARSE_TREE_NODE_BRANCH 1
+
+
+typedef struct {
+
+ short type; /* leaf or branch */
+
+ union {
+
+ int value; /* For leaves */
+ short branches[2]; /* For branches */
+
+ } content;
+
+} parse_tree_node_t;
+
+
+
+
+/*FIXME: These need freeing functions...*/
+
+int* vocabulary_get_classes(resource_mgr_t *resmgr, int *count);
+
+int vocabulary_get_class_count(resource_mgr_t *resmgr);
+
+/**
+ * Returns a null terminated array of selector names.
+ */
+char** vocabulary_get_snames(resource_mgr_t *resmgr, int *pcount, sci_version_t version);
+
+/**
+ * Frees the aforementioned array
+ */
+void vocabulary_free_snames(char **snames_list);
+
+/* Look up a selector name in an array, return the index */
+int vocabulary_lookup_sname(char **snames_list, char *sname);
+
+
+/**
+ * Returns a null terminated array of opcodes.
+ */
+opcode* vocabulary_get_opcodes(resource_mgr_t *resmgr);
+
+void
+vocabulary_free_opcodes(opcode *opcodes);
+/* Frees a previously allocated list of opcodes
+** Parameters: (opcode *) opcodes: Opcodes to free
+** Returns : (void)
+*/
+
+/**
+ * Returns a null terminated array of kernel function names.
+ *
+ * This function reads the kernel function name table from resource_map,
+ * and returns a null terminated array of deep copies of them.
+ * The returned array has the same format regardless of the format of the
+ * name table of the resource (the format changed between version 0 and 1).
+ */
+char** vocabulary_get_knames(resource_mgr_t *resmgr, int* count);
+void vocabulary_free_knames(char** names);
+
+
+
+word_t **
+vocab_get_words(resource_mgr_t *resmgr, int *word_counter);
+/* Gets all words from the main vocabulary
+** Parameters: (resource_mgr_t *) resmr: The resource manager to read from
+** (int *) word_counter: The int which the number of words is stored in
+** Returns : (word_t **): A list of all words, dynamically allocated
+*/
+
+
+void
+vocab_free_words(word_t **words, int words_nr);
+/* Frees memory allocated by vocab_get_words
+** Parameters: (word_t **) words: The words to free
+** (int) words_nr: Number of words in the structure
+** Returns : (void)
+*/
+
+
+suffix_t **
+vocab_get_suffices(resource_mgr_t *resmgr, int *suffices_nr);
+/* Gets all suffixes from the suffix vocabulary
+** Parameters: (resource_mgr_t*) resmgr: Resource manager the resources are
+** read from
+** (int *) suffices_nr: The variable to store the number of suffices in
+** Returns : (suffix_t **): A list of suffixes
+*/
+
+void
+vocab_free_suffices(resource_mgr_t *resmgr, suffix_t **suffices, int suffices_nr);
+/* Frees suffices_nr suffices
+** Parameters: (resource_mgr_t *) resmgr: The resource manager to free from
+** (suffix_t **) suffices: The suffixes to free
+** (int) suffices_nr: Number of entrie sin suffices
+** Returns : (void)
+*/
+
+parse_tree_branch_t *
+vocab_get_branches(resource_mgr_t *resmgr, int *branches_nr);
+/* Retrieves all grammar rules from the resource data
+** Parameters: (resource_mgr_t*) resmgr: Resource manager the rules are
+** read from
+** (int *) branches_nr: Pointer to the variable which the number of entries is to be
+** stored in
+** Returns : (parse_tree_branch_t *): The rules, or NULL on error
+*/
+
+void
+vocab_free_branches(parse_tree_branch_t *parser_branches);
+/* Frees all branches
+** Parameters: (parse_tree_branch_t *) parser_branches: The branches to free
+** Returns : (null)
+*/
+
+result_word_t *
+vocab_lookup_word(char *word, int word_len,
+ word_t **words, int words_nr,
+ suffix_t **suffices, int suffices_nr);
+/* Looks up a single word in the words and suffixes list
+** Parameters: (char *) word: Pointer to the word to look up
+** (int) word_len: Length of the word to look up
+** (word_t **) words: List of words
+** (int) words_nr: Number of elements in 'words'
+** (suffix_t **) suffices: List of suffices
+** (int) suffices_nr: Number of entries in 'suffices'
+** Returns : (result_word_t *) A malloc'd result_word_t, or NULL if the word
+** could not be found.
+*/
+
+
+result_word_t *
+vocab_tokenize_string(char *sentence, int *result_nr,
+ word_t **words, int words_nr,
+ suffix_t **suffices, int suffices_nr,
+ char **error);
+/* Tokenizes a string and compiles it into word_ts.
+** Parameters: (char *) sentence: The sentence to examine
+** (int *) result_nr: The variable to store the resulting number of words in
+** (word_t **) words: The words to scan for
+** (int) words_nr: Number of words to scan for
+** (suffix_t **) suffices: suffixes to scan for
+** (int) suffices_nr: Number of suffices to scan for
+** (char **) error: Points to a malloc'd copy of the offending text or to NULL on error
+** Returns : (word_t *): A list of word_ts containing the result, or NULL.
+** On error, NULL is returned. If *error is NULL, the sentence did not contain any useful words;
+** if not, *error points to a malloc'd copy of the offending word.
+** The returned list may contain anywords.
+*/
+
+
+parse_rule_list_t *
+vocab_build_gnf(parse_tree_branch_t *branches, int branches_nr);
+/* Constructs the Greibach Normal Form of the grammar supplied in 'branches'
+** Parameters: (parse_tree_branch_t *) branches: The parser's branches
+** (int) branches_nr: Number of parser branches
+** Returns : (parse_rule_list_t *): Pointer to a list of singly linked
+** GNF rules describing the same language
+** that was described by 'branches'
+** The original SCI rules are in almost-CNF (Chomsky Normal Form). Note that
+** branch[0] is used only for a few magical incantations, as it is treated
+** specially by the SCI parser.
+*/
+
+
+void
+vocab_free_rule_list(parse_rule_list_t *rule_list);
+/* Frees a parser rule list as returned by vocab_build_gnf()
+** Parameters: (parse_rule_list_t *) rule_list: The rule list to free
+** Returns : (void)
+*/
+
+
+int
+vocab_build_parse_tree(parse_tree_node_t *nodes, result_word_t *words, int words_nr,
+ parse_tree_branch_t *branch0, parse_rule_list_t *rules);
+/* Builds a parse tree from a list of words
+** Parameters: (parse_tree_node_t *) nodes: A node list to store the tree in (must have
+** at least VOCAB_TREE_NODES entries)
+** (result_word_t *) words: The words to build the tree from
+** (int) words_nr: The number of words
+** (parse_tree_branch_t *) branche0: The zeroeth original branch of the
+** original CNF parser grammar
+** (parse_rule_list *) rules: The GNF ruleset to parse with
+** Returns : 0 on success, 1 if the tree couldn't be built in VOCAB_TREE_NODES nodes
+** or if the sentence structure in 'words' is not part of the language
+** described by the grammar passed in 'rules'.
+*/
+
+void
+vocab_dump_parse_tree(const char *tree_name, parse_tree_node_t *nodes);
+/* Prints a parse tree
+** Parameters: (const char *) tree_name: Name of the tree to dump (free-form)
+** (parse_tree_node_t *) nodes: The nodes containing the parse tree
+** Returns : (void)
+*/
+
+
+
+
+struct _state;
+
+int
+said(struct _state *s, byte *spec, int verbose);
+/* Builds a parse tree from a spec and compares it to a parse tree
+** Parameters: (state_t *) s: The affected state
+** (byte *) spec: Pointer to the spec to build
+** (int) verbose: Whether to display the parse tree after building it
+** Returns : (int) 1 on a match, 0 otherwise
+*/
+
+const char *
+vocab_get_any_group_word(int group, word_t **words, int words_nr);
+/* Gets any word from the specified group.
+** Parameters: (int) group: Group number.
+** (word_t **) words: List of words
+** (int) words_nr: Count of words in the list.
+** For debugging only.
+*/
+
+
+void
+vocab_decypher_said_block(struct _state *s, byte *pos);
+/* Decyphers a said block and dumps its content via sciprintf.
+** Parameters: (state_t *) s: The state to use
+** (byte *) pos: Pointer to the data to dump
+** For debugging only.
+*/
+
+
+void
+vocab_synonymize_tokens(result_word_t *words, int words_nr, synonym_t *synonyms, int synonyms_nr);
+/* Synonymizes a token list
+** Parameters: (result_wort_t *) words: The word list to synonymize
+** (int) words_nr: Number of word_ts in the list
+** (synonym_t *) synonyms: Synonym list
+** (int) synonyms_nr: Number of synonyms in the list
+*/
+
+int
+vocab_gnf_parse(parse_tree_node_t *nodes, result_word_t *words, int words_nr,
+ parse_tree_branch_t *branch0, parse_rule_list_t *tlist, int verbose);
+
+void
+vocab_gnf_dump(parse_tree_branch_t *branches, int branches_nr);
+
+
+#endif
diff --git a/engines/sci/include/win32/Makefile.am b/engines/sci/include/win32/Makefile.am
new file mode 100644
index 0000000000..89551871e5
--- /dev/null
+++ b/engines/sci/include/win32/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST = getopt.h sci_win32.h usleep.h
diff --git a/engines/sci/include/win32/getopt.h b/engines/sci/include/win32/getopt.h
new file mode 100644
index 0000000000..0abce6e921
--- /dev/null
+++ b/engines/sci/include/win32/getopt.h
@@ -0,0 +1,127 @@
+/* Declarations for getopt.
+ Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns EOF, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+ for unrecognized options. */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized. */
+
+extern int optopt;
+
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+ of `struct option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `getopt'
+ returns the contents of the `val' field. */
+
+struct option
+{
+#if __STDC__
+ const char *name;
+#else
+ char *name;
+#endif
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+#if __STDC__ || defined(PROTO)
+#if defined(__GNU_LIBRARY__)
+/* Many other libraries have conflicting prototypes for getopt, with
+ differences in the consts, in stdlib.h. To avoid compilation
+ errors, only prototype getopt for the GNU C library. */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+#endif /* not __GNU_LIBRARY__ */
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+ const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+ const char *shortopts,
+ const struct option *longopts, int *longind);
+
+/* Internal only. Users should not call this directly. */
+extern int _getopt_internal (int argc, char *const *argv,
+ const char *shortopts,
+ const struct option *longopts, int *longind,
+ int long_only);
+#else /* not __STDC__ */
+extern int getopt ();
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* not __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
diff --git a/engines/sci/include/win32/sci_win32.h b/engines/sci/include/win32/sci_win32.h
new file mode 100644
index 0000000000..5174fd101c
--- /dev/null
+++ b/engines/sci/include/win32/sci_win32.h
@@ -0,0 +1,37 @@
+#ifdef _MSC_VER
+// inline keyword only supported in C++
+# undef inline /* just to be sure it is not defined */
+# define inline __inline
+# define strcasecmp _stricmp
+# define strncasecmp _strnicmp
+# define snprintf _snprintf
+
+# if _MSC_VER < 1500
+# define vsnprintf _vsnprintf
+# endif
+#endif
+
+#ifdef _WIN32
+
+# ifdef sleep
+# undef sleep
+# endif
+
+# define sleep(x) \
+ do { \
+ if (x == 0) { \
+ Sleep(0); \
+ } else { \
+ if (timeBeginPeriod(1) != TIMERR_NOERROR) \
+ fprintf(stderr, "timeBeginPeriod(1) failed\n"); \
+ Sleep(x); \
+ if (timeEndPeriod(1) != TIMERR_NOERROR) \
+ fprintf(stderr, "timeEndPeriod(1) failed\n"); \
+ } \
+ } while (0);
+
+# define RECT_T_TO_RECT(rect_t) \
+ { (rect_t).x, (rect_t).y, (rect_t).x + (rect_t).xl, (rect_t).y + (rect_t).yl }
+
+#endif
+
diff --git a/engines/sci/include/win32/usleep.h b/engines/sci/include/win32/usleep.h
new file mode 100644
index 0000000000..dd85d3cd87
--- /dev/null
+++ b/engines/sci/include/win32/usleep.h
@@ -0,0 +1,2 @@
+void
+usleep (long usec);