diff options
Diffstat (limited to 'engines/sci/include')
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); |