[Scummvm-cvs-logs] SF.net SVN: scummvm:[38227] scummvm/trunk/engines/sci
sev at users.sourceforge.net
sev at users.sourceforge.net
Sun Feb 15 12:39:08 CET 2009
Revision: 38227
http://scummvm.svn.sourceforge.net/scummvm/?rev=38227&view=rev
Author: sev
Date: 2009-02-15 11:39:07 +0000 (Sun, 15 Feb 2009)
Log Message:
-----------
- Remove some unneeded files
- Mass rename .c to .cpp
Modified Paths:
--------------
scummvm/trunk/engines/sci/module.mk
Added Paths:
-----------
scummvm/trunk/engines/sci/engine/game.cpp
scummvm/trunk/engines/sci/engine/gc.cpp
scummvm/trunk/engines/sci/engine/grammar.cpp
scummvm/trunk/engines/sci/engine/heap.cpp
scummvm/trunk/engines/sci/engine/kernel.cpp
scummvm/trunk/engines/sci/engine/kevent.cpp
scummvm/trunk/engines/sci/engine/kfile.cpp
scummvm/trunk/engines/sci/engine/kgraphics.cpp
scummvm/trunk/engines/sci/engine/klists.cpp
scummvm/trunk/engines/sci/engine/kmath.cpp
scummvm/trunk/engines/sci/engine/kmenu.cpp
scummvm/trunk/engines/sci/engine/kmovement.cpp
scummvm/trunk/engines/sci/engine/kpathing.cpp
scummvm/trunk/engines/sci/engine/kscripts.cpp
scummvm/trunk/engines/sci/engine/ksound.cpp
scummvm/trunk/engines/sci/engine/kstring.cpp
scummvm/trunk/engines/sci/engine/message.cpp
scummvm/trunk/engines/sci/engine/said.cpp
scummvm/trunk/engines/sci/engine/savegame.cpp
scummvm/trunk/engines/sci/engine/scriptconsole.cpp
scummvm/trunk/engines/sci/engine/scriptdebug.cpp
scummvm/trunk/engines/sci/engine/seg_manager.cpp
scummvm/trunk/engines/sci/engine/sys_strings.cpp
scummvm/trunk/engines/sci/engine/vm.cpp
scummvm/trunk/engines/sci/gfx/alpha_mvi_crossblit.cpp
scummvm/trunk/engines/sci/gfx/antialias.cpp
scummvm/trunk/engines/sci/gfx/font-5x8.cpp
scummvm/trunk/engines/sci/gfx/font-6x10.cpp
scummvm/trunk/engines/sci/gfx/font.cpp
scummvm/trunk/engines/sci/gfx/gfx_crossblit.cpp
scummvm/trunk/engines/sci/gfx/gfx_line.cpp
scummvm/trunk/engines/sci/gfx/gfx_pixmap_scale.cpp
scummvm/trunk/engines/sci/gfx/gfx_res_options.cpp
scummvm/trunk/engines/sci/gfx/gfx_resource.cpp
scummvm/trunk/engines/sci/gfx/gfx_support.cpp
scummvm/trunk/engines/sci/gfx/gfx_test.cpp
scummvm/trunk/engines/sci/gfx/gfx_tools.cpp
scummvm/trunk/engines/sci/gfx/menubar.cpp
scummvm/trunk/engines/sci/gfx/operations.cpp
scummvm/trunk/engines/sci/gfx/resmgr.cpp
scummvm/trunk/engines/sci/gfx/resource/sci_cursor_0.cpp
scummvm/trunk/engines/sci/gfx/resource/sci_font.cpp
scummvm/trunk/engines/sci/gfx/resource/sci_pal_1.cpp
scummvm/trunk/engines/sci/gfx/resource/sci_pic_0.cpp
scummvm/trunk/engines/sci/gfx/resource/sci_picfill.cpp
scummvm/trunk/engines/sci/gfx/resource/sci_picfill_aux.cpp
scummvm/trunk/engines/sci/gfx/resource/sci_resmgr.cpp
scummvm/trunk/engines/sci/gfx/resource/sci_view_0.cpp
scummvm/trunk/engines/sci/gfx/resource/sci_view_1.cpp
scummvm/trunk/engines/sci/gfx/sbtree.cpp
scummvm/trunk/engines/sci/gfx/sci_widgets.cpp
scummvm/trunk/engines/sci/gfx/widgets.cpp
scummvm/trunk/engines/sci/scicore/aatree.cpp
scummvm/trunk/engines/sci/scicore/console.cpp
scummvm/trunk/engines/sci/scicore/decompress0.cpp
scummvm/trunk/engines/sci/scicore/decompress01.cpp
scummvm/trunk/engines/sci/scicore/decompress1.cpp
scummvm/trunk/engines/sci/scicore/decompress11.cpp
scummvm/trunk/engines/sci/scicore/exe.cpp
scummvm/trunk/engines/sci/scicore/exe_lzexe.cpp
scummvm/trunk/engines/sci/scicore/exe_raw.cpp
scummvm/trunk/engines/sci/scicore/fnmatch.cpp
scummvm/trunk/engines/sci/scicore/hashmap.cpp
scummvm/trunk/engines/sci/scicore/int_hashmap.cpp
scummvm/trunk/engines/sci/scicore/modules.cpp
scummvm/trunk/engines/sci/scicore/old_objects.cpp
scummvm/trunk/engines/sci/scicore/reg_t_hashmap.cpp
scummvm/trunk/engines/sci/scicore/resource.cpp
scummvm/trunk/engines/sci/scicore/resource_map.cpp
scummvm/trunk/engines/sci/scicore/resource_patch.cpp
scummvm/trunk/engines/sci/scicore/resourcecheck.cpp
scummvm/trunk/engines/sci/scicore/sci_memory.cpp
scummvm/trunk/engines/sci/scicore/script.cpp
scummvm/trunk/engines/sci/scicore/tools.cpp
scummvm/trunk/engines/sci/scicore/versions.cpp
scummvm/trunk/engines/sci/scicore/vocab.cpp
scummvm/trunk/engines/sci/scicore/vocab_debug.cpp
scummvm/trunk/engines/sci/sfx/adlib.cpp
scummvm/trunk/engines/sci/sfx/core.cpp
scummvm/trunk/engines/sci/sfx/device/alsa-midi.cpp
scummvm/trunk/engines/sci/sfx/device/camd-midi.cpp
scummvm/trunk/engines/sci/sfx/device/devices.cpp
scummvm/trunk/engines/sci/sfx/device/unixraw-midi.cpp
scummvm/trunk/engines/sci/sfx/iterator.cpp
scummvm/trunk/engines/sci/sfx/lists/gm_patches.cpp
scummvm/trunk/engines/sci/sfx/lists/mt32_timbres.cpp
scummvm/trunk/engines/sci/sfx/mixer/dc.cpp
scummvm/trunk/engines/sci/sfx/mixer/mixers.cpp
scummvm/trunk/engines/sci/sfx/mixer/soft.cpp
scummvm/trunk/engines/sci/sfx/mixer/test.cpp
scummvm/trunk/engines/sci/sfx/pcm-iterator.cpp
scummvm/trunk/engines/sci/sfx/pcm_device/alsa.cpp
scummvm/trunk/engines/sci/sfx/pcm_device/audbuf_test.cpp
scummvm/trunk/engines/sci/sfx/pcm_device/audiobuf.cpp
scummvm/trunk/engines/sci/sfx/pcm_device/pcm_devices.cpp
scummvm/trunk/engines/sci/sfx/pcm_device/sdl.cpp
scummvm/trunk/engines/sci/sfx/player/players.cpp
scummvm/trunk/engines/sci/sfx/player/polled.cpp
scummvm/trunk/engines/sci/sfx/player/realtime.cpp
scummvm/trunk/engines/sci/sfx/seq/gm.cpp
scummvm/trunk/engines/sci/sfx/seq/instrument-map.cpp
scummvm/trunk/engines/sci/sfx/seq/map-mt32-to-gm.cpp
scummvm/trunk/engines/sci/sfx/seq/mt32.cpp
scummvm/trunk/engines/sci/sfx/seq/oss-adlib.cpp
scummvm/trunk/engines/sci/sfx/seq/sequencers.cpp
scummvm/trunk/engines/sci/sfx/softseq/SN76496.cpp
scummvm/trunk/engines/sci/sfx/softseq/amiga.cpp
scummvm/trunk/engines/sci/sfx/softseq/fluidsynth.cpp
scummvm/trunk/engines/sci/sfx/softseq/opl2.cpp
scummvm/trunk/engines/sci/sfx/softseq/pcspeaker.cpp
scummvm/trunk/engines/sci/sfx/softseq/softsequencers.cpp
scummvm/trunk/engines/sci/sfx/songlib.cpp
scummvm/trunk/engines/sci/sfx/test-iterator.cpp
scummvm/trunk/engines/sci/sfx/time.cpp
scummvm/trunk/engines/sci/sfx/timer/pthread.cpp
scummvm/trunk/engines/sci/sfx/timer/sigalrm.cpp
scummvm/trunk/engines/sci/sfx/timer/timers.cpp
scummvm/trunk/engines/sci/sfx/timetest.cpp
scummvm/trunk/engines/sci/tools/bdf.cpp
scummvm/trunk/engines/sci/tools/bdfgname.cpp
scummvm/trunk/engines/sci/tools/bdfgrid.cpp
scummvm/trunk/engines/sci/tools/bdftofont.cpp
scummvm/trunk/engines/sci/tools/classes.cpp
scummvm/trunk/engines/sci/tools/fonttoc.cpp
scummvm/trunk/engines/sci/tools/listwords.cpp
scummvm/trunk/engines/sci/tools/musicplayer.cpp
scummvm/trunk/engines/sci/tools/scidisasm.cpp
scummvm/trunk/engines/sci/tools/scipack.cpp
scummvm/trunk/engines/sci/tools/sciunpack.cpp
scummvm/trunk/engines/sci/tools/scriptdump.cpp
scummvm/trunk/engines/sci/tools/vocabdump.cpp
Removed Paths:
-------------
scummvm/trunk/engines/sci/engine/game.c
scummvm/trunk/engines/sci/engine/gc.c
scummvm/trunk/engines/sci/engine/grammar.c
scummvm/trunk/engines/sci/engine/heap.c
scummvm/trunk/engines/sci/engine/kernel.c
scummvm/trunk/engines/sci/engine/kevent.c
scummvm/trunk/engines/sci/engine/kfile.c
scummvm/trunk/engines/sci/engine/kgraphics.c
scummvm/trunk/engines/sci/engine/klists.c
scummvm/trunk/engines/sci/engine/kmath.c
scummvm/trunk/engines/sci/engine/kmenu.c
scummvm/trunk/engines/sci/engine/kmovement.c
scummvm/trunk/engines/sci/engine/kpathing.c
scummvm/trunk/engines/sci/engine/kscripts.c
scummvm/trunk/engines/sci/engine/ksound.c
scummvm/trunk/engines/sci/engine/kstring.c
scummvm/trunk/engines/sci/engine/makefile.dos
scummvm/trunk/engines/sci/engine/message.c
scummvm/trunk/engines/sci/engine/said.c
scummvm/trunk/engines/sci/engine/savegame.c
scummvm/trunk/engines/sci/engine/scriptconsole.c
scummvm/trunk/engines/sci/engine/scriptdebug.c
scummvm/trunk/engines/sci/engine/seg_manager.c
scummvm/trunk/engines/sci/engine/sys_strings.c
scummvm/trunk/engines/sci/engine/vm.c
scummvm/trunk/engines/sci/gfx/alpha_mvi_crossblit.c
scummvm/trunk/engines/sci/gfx/antialias.c
scummvm/trunk/engines/sci/gfx/font-5x8.c
scummvm/trunk/engines/sci/gfx/font-6x10.c
scummvm/trunk/engines/sci/gfx/font.c
scummvm/trunk/engines/sci/gfx/gfx_crossblit.c
scummvm/trunk/engines/sci/gfx/gfx_line.c
scummvm/trunk/engines/sci/gfx/gfx_pixmap_scale.c
scummvm/trunk/engines/sci/gfx/gfx_res_options.c
scummvm/trunk/engines/sci/gfx/gfx_resource.c
scummvm/trunk/engines/sci/gfx/gfx_support.c
scummvm/trunk/engines/sci/gfx/gfx_test.c
scummvm/trunk/engines/sci/gfx/gfx_tools.c
scummvm/trunk/engines/sci/gfx/menubar.c
scummvm/trunk/engines/sci/gfx/operations.c
scummvm/trunk/engines/sci/gfx/resmgr.c
scummvm/trunk/engines/sci/gfx/resource/sci_cursor_0.c
scummvm/trunk/engines/sci/gfx/resource/sci_font.c
scummvm/trunk/engines/sci/gfx/resource/sci_pal_1.c
scummvm/trunk/engines/sci/gfx/resource/sci_pic_0.c
scummvm/trunk/engines/sci/gfx/resource/sci_picfill.c
scummvm/trunk/engines/sci/gfx/resource/sci_picfill_aux.c
scummvm/trunk/engines/sci/gfx/resource/sci_resmgr.c
scummvm/trunk/engines/sci/gfx/resource/sci_view_0.c
scummvm/trunk/engines/sci/gfx/resource/sci_view_1.c
scummvm/trunk/engines/sci/gfx/sbtree.c
scummvm/trunk/engines/sci/gfx/sci_widgets.c
scummvm/trunk/engines/sci/gfx/widgets.c
scummvm/trunk/engines/sci/gfx/wrapper.c
scummvm/trunk/engines/sci/menu/
scummvm/trunk/engines/sci/scicore/aatree.c
scummvm/trunk/engines/sci/scicore/console.c
scummvm/trunk/engines/sci/scicore/decompress0.c
scummvm/trunk/engines/sci/scicore/decompress01.c
scummvm/trunk/engines/sci/scicore/decompress1.c
scummvm/trunk/engines/sci/scicore/decompress11.c
scummvm/trunk/engines/sci/scicore/exe.c
scummvm/trunk/engines/sci/scicore/exe_lzexe.c
scummvm/trunk/engines/sci/scicore/exe_raw.c
scummvm/trunk/engines/sci/scicore/fnmatch.c
scummvm/trunk/engines/sci/scicore/hashmap.c
scummvm/trunk/engines/sci/scicore/int_hashmap.c
scummvm/trunk/engines/sci/scicore/modules.c
scummvm/trunk/engines/sci/scicore/old_objects.c
scummvm/trunk/engines/sci/scicore/reg_t_hashmap.c
scummvm/trunk/engines/sci/scicore/resource.c
scummvm/trunk/engines/sci/scicore/resource_map.c
scummvm/trunk/engines/sci/scicore/resource_patch.c
scummvm/trunk/engines/sci/scicore/resourcecheck.c
scummvm/trunk/engines/sci/scicore/sci_memory.c
scummvm/trunk/engines/sci/scicore/script.c
scummvm/trunk/engines/sci/scicore/tools.c
scummvm/trunk/engines/sci/scicore/versions.c
scummvm/trunk/engines/sci/scicore/vocab.c
scummvm/trunk/engines/sci/scicore/vocab_debug.c
scummvm/trunk/engines/sci/sfx/adlib.c
scummvm/trunk/engines/sci/sfx/core.c
scummvm/trunk/engines/sci/sfx/device/alsa-midi.c
scummvm/trunk/engines/sci/sfx/device/camd-midi.c
scummvm/trunk/engines/sci/sfx/device/devices.c
scummvm/trunk/engines/sci/sfx/device/unixraw-midi.c
scummvm/trunk/engines/sci/sfx/iterator.c
scummvm/trunk/engines/sci/sfx/lists/gm_patches.c
scummvm/trunk/engines/sci/sfx/lists/mt32_timbres.c
scummvm/trunk/engines/sci/sfx/mixer/dc.c
scummvm/trunk/engines/sci/sfx/mixer/mixers.c
scummvm/trunk/engines/sci/sfx/mixer/soft.c
scummvm/trunk/engines/sci/sfx/mixer/test.c
scummvm/trunk/engines/sci/sfx/pcm-iterator.c
scummvm/trunk/engines/sci/sfx/pcm_device/alsa.c
scummvm/trunk/engines/sci/sfx/pcm_device/audbuf_test.c
scummvm/trunk/engines/sci/sfx/pcm_device/audiobuf.c
scummvm/trunk/engines/sci/sfx/pcm_device/pcm_devices.c
scummvm/trunk/engines/sci/sfx/pcm_device/sdl.c
scummvm/trunk/engines/sci/sfx/player/players.c
scummvm/trunk/engines/sci/sfx/player/polled.c
scummvm/trunk/engines/sci/sfx/player/realtime.c
scummvm/trunk/engines/sci/sfx/seq/gm.c
scummvm/trunk/engines/sci/sfx/seq/instrument-map.c
scummvm/trunk/engines/sci/sfx/seq/map-mt32-to-gm.c
scummvm/trunk/engines/sci/sfx/seq/mt32.c
scummvm/trunk/engines/sci/sfx/seq/oss-adlib.c
scummvm/trunk/engines/sci/sfx/seq/sequencers.c
scummvm/trunk/engines/sci/sfx/softseq/SN76496.c
scummvm/trunk/engines/sci/sfx/softseq/amiga.c
scummvm/trunk/engines/sci/sfx/softseq/fluidsynth.c
scummvm/trunk/engines/sci/sfx/softseq/opl2.c
scummvm/trunk/engines/sci/sfx/softseq/pcspeaker.c
scummvm/trunk/engines/sci/sfx/softseq/softsequencers.c
scummvm/trunk/engines/sci/sfx/songlib.c
scummvm/trunk/engines/sci/sfx/test-iterator.c
scummvm/trunk/engines/sci/sfx/time.c
scummvm/trunk/engines/sci/sfx/timer/pthread.c
scummvm/trunk/engines/sci/sfx/timer/sigalrm.c
scummvm/trunk/engines/sci/sfx/timer/timers.c
scummvm/trunk/engines/sci/sfx/timetest.c
scummvm/trunk/engines/sci/tools/bdf.c
scummvm/trunk/engines/sci/tools/bdfgname.c
scummvm/trunk/engines/sci/tools/bdfgrid.c
scummvm/trunk/engines/sci/tools/bdftofont.c
scummvm/trunk/engines/sci/tools/classes.c
scummvm/trunk/engines/sci/tools/fonttoc.c
scummvm/trunk/engines/sci/tools/listwords.c
scummvm/trunk/engines/sci/tools/musicplayer.c
scummvm/trunk/engines/sci/tools/scidisasm.c
scummvm/trunk/engines/sci/tools/scipack.c
scummvm/trunk/engines/sci/tools/sciunpack.c
scummvm/trunk/engines/sci/tools/scriptdump.c
scummvm/trunk/engines/sci/tools/vocabdump.c
Deleted: scummvm/trunk/engines/sci/engine/game.c
===================================================================
--- scummvm/trunk/engines/sci/engine/game.c 2009-02-15 11:21:31 UTC (rev 38226)
+++ scummvm/trunk/engines/sci/engine/game.c 2009-02-15 11:39:07 UTC (rev 38227)
@@ -1,773 +0,0 @@
-/***************************************************************************
- game.c Copyright (C) 1999 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 at linuxgames.com]
-
-***************************************************************************/
-
-#include "sci/include/sciresource.h"
-#include "sci/include/engine.h"
-#include "sci/include/versions.h"
-#include "sci/include/kernel.h"
-#include "sci/engine/kernel_types.h"
-
-/* Structures and data from vm.c: */
-extern calls_struct_t *send_calls;
-extern int send_calls_allocated;
-extern int bp_flag;
-
-
-
-static int
-_init_vocabulary(state_t *s) /* initialize vocabulary and related resources */
-{
- s->parser_lastmatch_word = SAID_NO_MATCH;
- s->parser_rules = NULL;
-
- sciprintf("Initializing vocabulary\n");
-
- if ((s->resmgr->sci_version < SCI_VERSION_01_VGA)&&(s->parser_words = vocab_get_words(s->resmgr, &(s->parser_words_nr)))) {
- s->parser_suffices = vocab_get_suffices(s->resmgr, &(s->parser_suffices_nr));
- if ((s->parser_branches = vocab_get_branches(s->resmgr, &(s->parser_branches_nr))))
- /* Now build a GNF grammar out of this */
- s->parser_rules = vocab_build_gnf(s->parser_branches, s->parser_branches_nr);
-
- } else {
- sciprintf("Assuming that this game does not use a parser.\n");
- s->parser_rules = NULL;
- }
-
-
- s->opcodes = vocabulary_get_opcodes(s->resmgr);
-
- if (!(s->selector_names = vocabulary_get_snames(s->resmgr, NULL, s->version))) {
- sciprintf("_init_vocabulary(): Could not retreive selector names (vocab.997)!\n");
- return 1;
- }
-
- for (s->selector_names_nr = 0; s->selector_names[s->selector_names_nr]; s->selector_names_nr++);
- /* Counts the number of selector names */
-
- script_map_selectors(s, &(s->selector_map));
- /* Maps a few special selectors for later use */
-
- return 0;
-}
-
-extern int _allocd_rules;
-static void
-_free_vocabulary(state_t *s)
-{
- sciprintf("Freeing vocabulary\n");
-
- if (s->parser_words) {
- vocab_free_words(s->parser_words, s->parser_words_nr);
- vocab_free_suffices(s->resmgr, s->parser_suffices, s->parser_suffices_nr);
- vocab_free_branches(s->parser_branches);
- vocab_free_rule_list(s->parser_rules);
- }
-
- vocabulary_free_snames(s->selector_names);
- vocabulary_free_knames(s->kernel_names);
- vocabulary_free_opcodes(s->opcodes);
- s->opcodes = NULL;
-
- s->selector_names = NULL;
- s->kernel_names = NULL;
- s->opcodes = NULL;
-}
-
-
-static int
-_init_graphics_input(state_t *s)
-{
- s->pic_priority_table = NULL;
- s->pics = NULL;
- s->pics_nr = 0;
- return 0;
-}
-
-static void
-_sci1_alloc_system_colors(state_t *s)
-{
- gfx_color_t white;
- gfx_color_t black;
-
- white.visual.global_index = 255;
- white.visual.r = white.visual.g = white.visual.b = 255;
- white.alpha = 0;
- white.priority = white.control = 0;
- white.mask = GFX_MASK_VISUAL;
- gfxop_set_system_color(s->gfx_state, &white);
-
- black.visual.global_index = 0;
- black.visual.r = black.visual.g = black.visual.b = 0;
- black.alpha = 0;
- black.priority = black.control = 0;
- black.mask = GFX_MASK_VISUAL;
- gfxop_set_system_color(s->gfx_state, &black);
-}
-
-int
-_reset_graphics_input(state_t *s)
-{
- resource_t *resource;
- int font_nr;
- gfx_color_t transparent;
- sciprintf("Initializing graphics\n");
-
- if (s->resmgr->sci_version <= SCI_VERSION_01) {
- int i;
-
- for (i = 0; i < 16; i++) {
- if (gfxop_set_color(s->gfx_state, &(s->ega_colors[i]),
- gfx_sci0_image_colors[sci0_palette][i].r,
- gfx_sci0_image_colors[sci0_palette][i].g,
- gfx_sci0_image_colors[sci0_palette][i].b,
- 0, -1, -1))
- return 1;
- gfxop_set_system_color(s->gfx_state, &(s->ega_colors[i]));
- }
- } else
- {
- /* Check for Amiga palette file. */
- FILE *f = sci_fopen("spal", "rb");
- if (f) {
- s->gfx_state->resstate->static_palette =
- gfxr_read_pal1_amiga(&s->gfx_state->resstate->static_palette_entries, f);
- fclose(f);
- _sci1_alloc_system_colors(s);
- } else {
- resource = scir_find_resource(s->resmgr, sci_palette, 999, 1);
- if (resource) {
- if (s->version < SCI_VERSION(1,001,000))
- s->gfx_state->resstate->static_palette =
- gfxr_read_pal1(999, &s->gfx_state->resstate->static_palette_entries,
- resource->data, resource->size);
- else
- s->gfx_state->resstate->static_palette =
- gfxr_read_pal11(999, &s->gfx_state->resstate->static_palette_entries,
- resource->data, resource->size);
- _sci1_alloc_system_colors(s);
- scir_unlock_resource(s->resmgr, resource, sci_palette, 999);
- } else
- sciprintf("Couldn't find the default palette!\n");
- }
- }
- transparent.mask = 0;
-
- gfxop_fill_box(s->gfx_state, gfx_rect(0, 0, 320, 200), s->ega_colors[0]); /* Fill screen black */
- gfxop_update(s->gfx_state);
-
- s->mouse_pointer_view = s->mouse_pointer_loop = s->mouse_pointer_cel = -1; /* No mouse pointer resource */
- s->save_mouse_pointer_view = s->save_mouse_pointer_loop = s->save_mouse_pointer_cel = -1; /* No mouse pointer resource */
- gfxop_set_pointer_position(s->gfx_state, gfx_point(160, 150));
-
- s->mouse_pointer_view = s->mouse_pointer_loop = s->mouse_pointer_cel = -1; /* No mouse pointer resource */
- s->save_mouse_pointer_view = s->save_mouse_pointer_loop = s->save_mouse_pointer_cel = -1; /* No mouse pointer resource */
-
-
- s->pic_is_new = 0;
- s->pic_visible_map = GFX_MASK_NONE; /* Other values only make sense for debugging */
- s->dyn_views = NULL; /* no DynViews */
- s->drop_views = NULL; /* And, consequently, no list for dropped views */
-
- s->priority_first = 42; /* Priority zone 0 ends here */
-
- if (s->version < SCI_VERSION_FTU_PRIORITY_14_ZONES)
- s->priority_last = 200; else
- s->priority_last = 190;
-
- font_nr = -1;
- do {
- resource = scir_test_resource(s->resmgr, sci_font, ++font_nr);
- } while ((!resource) && (font_nr < sci_max_resource_nr[s->resmgr->sci_version]));
-
- if (!resource) {
- sciprintf("No text font was found.\n");
- return 1;
- }
-
- s->visual = gfxw_new_visual(s->gfx_state, font_nr);
-
- s->wm_port = gfxw_new_port(s->visual, NULL, s->gfx_state->options->pic_port_bounds, s->ega_colors[0], transparent);
- s->iconbar_port = gfxw_new_port(s->visual, NULL, gfx_rect(0, 0, 320, 200), s->ega_colors[0], transparent);
- s->iconbar_port->flags |= GFXW_FLAG_NO_IMPLICIT_SWITCH;
-
- if (s->resmgr->sci_version >= SCI_VERSION_01_VGA)
- {
- gfx_color_t fgcolor;
- gfx_color_t bgcolor;
-
-#if 0
- fgcolor.visual = s->gfx_state->resstate->static_palette[0];
- fgcolor.mask = GFX_MASK_VISUAL;
- bgcolor.visual = s->gfx_state->resstate->static_palette[255];
- bgcolor.mask = GFX_MASK_VISUAL;
-#endif
- s->titlebar_port = gfxw_new_port(s->visual, NULL, gfx_rect(0, 0, 320, 10),
- fgcolor, bgcolor);
- } else
- s->titlebar_port = gfxw_new_port(s->visual, NULL, gfx_rect(0, 0, 320, 10),
- s->ega_colors[0], s->ega_colors[15]);
- s->titlebar_port->color.mask |= GFX_MASK_PRIORITY;
- s->titlebar_port->color.priority = 11;
- s->titlebar_port->bgcolor.mask |= GFX_MASK_PRIORITY;
- s->titlebar_port->bgcolor.priority = 11;
- s->titlebar_port->flags |= GFXW_FLAG_NO_IMPLICIT_SWITCH;
-
- /* but this is correct */
- s->picture_port = gfxw_new_port(s->visual, NULL, s->gfx_state->options->pic_port_bounds, s->ega_colors[0], transparent);
-
- s->pics_drawn_nr = 0;
-
- s->visual->add(GFXWC(s->visual), GFXW(s->wm_port));
- s->visual->add(GFXWC(s->visual), GFXW(s->titlebar_port));
- s->visual->add(GFXWC(s->visual), GFXW(s->picture_port));
- s->visual->add(GFXWC(s->visual), GFXW(s->iconbar_port));
- /* Add ports to visual */
-
- s->port = s->picture_port; /* Currently using the picture port */
-
-#if 0
- s->titlebar_port->bgcolor.mask |= GFX_MASK_PRIORITY;
- s->titlebar_port->bgcolor.priority = 11; /* Standard priority for the titlebar port */
-#endif
-
- return 0;
-}
-
-int
-game_init_graphics(state_t *s)
-{
-#ifndef WITH_PIC_SCALING
- if (s->gfx_state->options->pic0_unscaled == 0)
- sciprintf("WARNING: Pic scaling was disabled; your version of FreeSCI has no support for scaled pic drawing built in.\n");
-
- s->gfx_state->options->pic0_unscaled = 1;
-#endif
- return _reset_graphics_input(s);
-}
-
-
-static void
-_free_graphics_input(state_t *s)
-{
- sciprintf("Freeing graphics\n");
-
- s->visual->widfree(GFXW(s->visual));
-
- s->wm_port = s->titlebar_port = s->picture_port = NULL;
- s->visual = NULL;
- s->dyn_views = NULL;
- s->port = NULL;
-
- if (s->pics)
- sci_free(s->pics);
- s->pics = NULL;
-}
-
-/*------------------------------------------------------------*/
-
-int
-game_init_sound(state_t *s, int sound_flags)
-{
- if (s->resmgr->sci_version >= SCI_VERSION_01)
- sound_flags |= SFX_STATE_FLAG_MULTIPLAY;
-
- s->sfx_init_flags = sound_flags;
- sfx_init(&s->sound, s->resmgr, sound_flags);
- return 0;
-}
-
-
-/* Maps a class ID to the script the corresponding class is contained in */
-/* Returns the script number suggested by vocab.996, or -1 if there's none */
-static int
-suggested_script(resource_t *res, unsigned int class)
-{
- int offset;
- if (!res || class >= res->size >> 2)
- return -1;
-
- offset = 2 + (class << 2);
-
- return getInt16(res->data + offset);
-}
-
-
-int
-test_cursor_style(state_t *s)
-{
- int resource_nr = 0;
- int ok = 0;
-
- do {
- ok |= scir_test_resource(s->resmgr, sci_cursor, resource_nr++) != NULL;
- } while (resource_nr < 1000 && !ok);
-
- return ok;
-}
-
-int
-create_class_table_sci11(state_t *s)
-{
- int scriptnr;
- unsigned int seeker_offset;
- char *seeker_ptr;
- int classnr;
-
- resource_t *vocab996 = scir_find_resource(s->resmgr, sci_vocab, 996, 1);
-
- if (!vocab996)
- s->classtable_size = 20;
- else
- s->classtable_size = vocab996->size >> 2;
-
- s->classtable = (class_t*)sci_calloc(sizeof(class_t), s->classtable_size);
-
- for (scriptnr = 0; scriptnr < 1000; scriptnr++) {
- resource_t *heap = scir_find_resource(s->resmgr, sci_heap,
- scriptnr, 0);
-
- if (heap) {
- int global_vars = getUInt16(heap->data + 2);
-
- seeker_ptr = (char*)heap->data + 4 + global_vars*2;
- seeker_offset = 4 + global_vars*2;
-
- while (getUInt16((byte*)seeker_ptr) == SCRIPT_OBJECT_MAGIC_NUMBER)
- {
- if (getUInt16((byte*)seeker_ptr + 14) & SCRIPT_INFO_CLASS)
- {
- classnr = getUInt16((byte*)seeker_ptr + 10);
- if (classnr >= s->classtable_size) {
-
- if (classnr >= SCRIPT_MAX_CLASSTABLE_SIZE) {
- fprintf(stderr,"Invalid class number 0x%x in script.%d(0x%x), offset %04x\n",
- classnr, scriptnr, scriptnr, seeker_offset);
- return 1;
- }
-
- s->classtable = (class_t*)sci_realloc(s->classtable, sizeof(class_t) * (classnr + 1));
- memset(&(s->classtable[s->classtable_size]), 0,
- sizeof(class_t) * (1 + classnr - s->classtable_size)); /* Clear after resize */
-
- s->classtable_size = classnr + 1; /* Adjust maximum number of entries */
- }
-
- s->classtable[classnr].reg.offset = seeker_offset;
- s->classtable[classnr].reg.segment = 0;
- s->classtable[classnr].script = scriptnr;
- }
-
- seeker_ptr += getUInt16((byte*)seeker_ptr + 2) * 2;
- seeker_offset += getUInt16((byte*)seeker_ptr + 2) * 2;
- }
- }
- }
-
- return 0;
-}
-static int
-create_class_table_sci0(state_t *s)
-{
- int scriptnr;
- unsigned int seeker;
- int classnr;
- int magic_offset; /* For strange scripts in older SCI versions */
-
- resource_t *vocab996 = scir_find_resource(s->resmgr, sci_vocab, 996, 1);
-
- if (!vocab996)
- s->classtable_size = 20;
- else
- s->classtable_size = vocab996->size >> 2;
-
- s->classtable = (class_t*)sci_calloc(sizeof(class_t), s->classtable_size);
-
- for (scriptnr = 0; scriptnr < 1000; scriptnr++) {
- int objtype = 0;
- resource_t *script = scir_find_resource(s->resmgr, sci_script,
- scriptnr, 0);
-
- if (script) {
- if (s->version < SCI_VERSION_FTU_NEW_SCRIPT_HEADER)
- magic_offset = seeker = 2;
- else
- magic_offset = seeker = 0;
-
- do {
-
- while (seeker < script->size) {
- unsigned int lastseeker = seeker;
- objtype = getInt16(script->data + seeker);
- if (objtype == sci_obj_class || objtype == sci_obj_terminator)
- break;
- seeker += getInt16(script->data + seeker + 2);
- if (seeker <= lastseeker) {
- sciprintf("Warning: Script version is invalid.\n");
- sci_free(s->classtable);
- return SCI_ERROR_INVALID_SCRIPT_VERSION;
- }
- }
-
- if (objtype == sci_obj_class) {
- int sugg_script;
-
- seeker -= SCRIPT_OBJECT_MAGIC_OFFSET; /* Adjust position; script home is base +8 bytes */
-
- classnr = getInt16(script->data + seeker + 4 + SCRIPT_SPECIES_OFFSET);
- if (classnr >= s->classtable_size) {
-
- if (classnr >= SCRIPT_MAX_CLASSTABLE_SIZE) {
- fprintf(stderr,"Invalid class number 0x%x in script.%d(0x%x), offset %04x\n",
- classnr, scriptnr, scriptnr, seeker);
- return 1;
- }
-
- s->classtable = (class_t*)sci_realloc(s->classtable, sizeof(class_t) * (classnr + 1));
- memset(&(s->classtable[s->classtable_size]), 0,
- sizeof(class_t) * (1 + classnr - s->classtable_size)); /* Clear after resize */
-
- s->classtable_size = classnr + 1; /* Adjust maximum number of entries */
- }
-
- sugg_script = suggested_script(vocab996, classnr);
-
- /* First, test whether the script hasn't been claimed, or if it's been claimed by the wrong script */
-
- if (sugg_script == -1 || scriptnr == sugg_script /*|| !s->classtable[classnr].reg.segment*/) {
- /* Now set the home script of the class */
- s->classtable[classnr].reg.offset = seeker + 4 - magic_offset;
- s->classtable[classnr].reg.segment = 0;
- s->classtable[classnr].script = scriptnr;
- }
-
- seeker += SCRIPT_OBJECT_MAGIC_OFFSET; /* Re-adjust position */
-
- seeker += getInt16(script->data + seeker + 2); /* Move to next */
- }
-
- } while (objtype != sci_obj_terminator && seeker <= script->size);
-
- }
- }
- scir_unlock_resource(s->resmgr, vocab996, sci_vocab, 996);
- vocab996 = NULL;
- return 0;
-}
-
-/* Architectural stuff: Init/Unintialize engine */
-int
-script_init_engine(state_t *s, sci_version_t version)
-{
- int result;
-
- s->max_version = SCI_VERSION(9,999,999); /* :-) */
- s->min_version = 0; /* Set no real limits */
- s->version = SCI_VERSION_DEFAULT_SCI0;
- s->kernel_opt_flags = 0;
-
- if (!version) {
- s->version_lock_flag = 0;
- } else {
- s->version = version;
- s->version_lock_flag = 1; /* Lock version */
- }
-
- script_detect_versions(s);
-
- if (s->version >= SCI_VERSION(1,001,000))
- result = create_class_table_sci11(s);
- else
- result = create_class_table_sci0(s);
-
- sm_init(&s->seg_manager, s->version >= SCI_VERSION(1,001,000));
- s->gc_countdown = GC_INTERVAL - 1;
-
- if (result)
- {
- sciprintf("Failed to initialize class table\n");
- return 1;
- }
-
- s->script_000_segment = script_get_segment(s, 0, SCRIPT_GET_LOCK);
-
- if (s->script_000_segment <= 0) {
- sciprintf("Failed to instantiate script.000\n");
- return 1;
- }
-
- s->script_000 = &(s->seg_manager.heap[s->script_000_segment]->data.script);
-
-
- s->sys_strings = sm_allocate_sys_strings(&s->seg_manager,
- &s->sys_strings_segment);
- /* Allocate static buffer for savegame and CWD directories */
- sys_string_acquire(s->sys_strings, SYS_STRING_SAVEDIR, "savedir", MAX_SAVE_DIR_SIZE);
-
- s->save_dir_copy = make_reg(s->sys_strings_segment, SYS_STRING_SAVEDIR);
- s->save_dir_edit_offset = 0;
-
- s->r_acc = s->r_prev = NULL_REG;
- s->r_amp_rest = 0;
-
- s->execution_stack = NULL; /* Start without any execution stack */
- s->execution_stack_base = -1; /* No vm is running yet */
- s->execution_stack_pos = -1; /* Start at execution stack position 0 */
-
-
- s->kernel_names = vocabulary_get_knames(s->resmgr, &s->kernel_names_nr);
- script_map_kernel(s);
- /* Maps the kernel functions */
-
- if (_init_vocabulary(s)) return 1;
- if (s->selector_map.cantBeHere != -1)
- version_require_later_than(s, SCI_VERSION_FTU_INVERSE_CANBEHERE);
-
- s->restarting_flags = SCI_GAME_IS_NOT_RESTARTING;
-
- s->bp_list = NULL; /* No breakpoints defined */
- s->have_bp = 0;
-
- s->file_handles_nr = 5;
- s->file_handles = (FILE**)sci_calloc(sizeof(FILE *), s->file_handles_nr);
- /* Allocate memory for file handles */
-
- sci_init_dir(&(s->dirseeker));
- s->dirseeker_outbuffer = NULL_REG;
- /* Those two are used by FileIO for FIND_FIRST, FIND_NEXT */
-
- if (s->version >= SCI_VERSION_FTU_LOFS_ABSOLUTE &&
- s->version < SCI_VERSION(1,001,000))
- sm_set_export_width(&s->seg_manager, 1);
- else
- sm_set_export_width(&s->seg_manager, 0);
-
- sciprintf("Engine initialized\n");
-
- if (_init_graphics_input(s))
- return 1;
-
- return 0;
-}
-
-
-void
-script_set_gamestate_save_dir(state_t *s, const char* path)
-{
- sys_string_set(s->sys_strings, SYS_STRING_SAVEDIR, path);
-}
-
-void
-script_free_vm_memory(state_t *s)
-{
- int i;
-
- sciprintf("Freeing VM memory\n");
- s->save_dir_copy_buf = NULL;
-
- sci_free(s->classtable);
- s->classtable = NULL;
-
- /* Close all opened file handles */
-#ifndef _DOS
- for (i = 1; i < s->file_handles_nr; i++)
- if (s->file_handles[i])
- fclose(s->file_handles[i]);
-#endif
-
- sci_free(s->file_handles);
- s->file_handles = NULL;
-
- /* FIXME: file handles will NOT be closed under DOS. DJGPP generates an
- exception fault whenever you try to close a never-opened file */
-}
-
-extern void
-free_kfunct_tables(state_t *s);
-/* From kernel.c */
-
-void
-script_free_engine(state_t *s)
-{
- script_free_vm_memory(s);
-
- sciprintf("Freeing state-dependant data\n");
-
- free_kfunct_tables(s);
-
- _free_vocabulary(s);
-
-}
-
-void
-script_free_breakpoints(state_t *s)
-{
- breakpoint_t *bp, *bp_next;
-
- /* Free breakpoint list */
- bp = s->bp_list;
- while (bp) {
- bp_next = bp->next;
- if (bp->type == BREAK_SELECTOR) sci_free (bp->data.name);
- free (bp);
- bp = bp_next;
- }
-
- s->bp_list = NULL;
-}
-
-/*************************************************************/
-/* Game instance stuff: Init/Unitialize state-dependant data */
-/*************************************************************/
-
-
-int
-game_init(state_t *s)
-{
-#ifdef __GNUC__
-# warning "Fixme: Use new VM instantiation code all over the place"
-#endif
- reg_t game_obj; /* Address of the game object */
- dstack_t *stack;
-
- stack = sm_allocate_stack(&s->seg_manager, VM_STACK_SIZE,
- &s->stack_segment);
- s->stack_base = stack->entries;
- s->stack_top = s->stack_base + VM_STACK_SIZE;
-
- if (!script_instantiate(s, 0)) {
- sciprintf("game_init(): Could not instantiate script 0\n");
- return 1;
- }
-
- s->parser_valid = 0; /* Invalidate parser */
- s->parser_event = NULL_REG; /* Invalidate parser event */
-
- s->synonyms = NULL;
- s->synonyms_nr = 0; /* No synonyms */
-
- /* Initialize send_calls buffer */
-
- if (!send_calls_allocated)
- send_calls = (calls_struct_t*)sci_calloc(sizeof(calls_struct_t), send_calls_allocated = 16);
-
- if (s->gfx_state && _reset_graphics_input(s))
- return 1;
-
- s->successor = NULL; /* No successor */
- s->status_bar_text = NULL; /* Status bar is blank */
- s->status_bar_foreground = 0;
- s->status_bar_background = s->resmgr->sci_version >= SCI_VERSION_01_VGA ? 255 : 15;
-
- sys_string_acquire(s->sys_strings, SYS_STRING_PARSER_BASE, "parser-base", MAX_PARSER_BASE);
- s->parser_base = make_reg(s->sys_strings_segment, SYS_STRING_PARSER_BASE);
-
- sci_get_current_time(&(s->game_start_time)); /* Get start time */
- memcpy(&(s->last_wait_time), &(s->game_start_time), sizeof(GTimeVal));
- /* Use start time as last_wait_time */
-
- s->debug_mode = 0x0; /* Disable all debugging */
- s->onscreen_console = 0; /* No onscreen console unless explicitly requested */
-
- srand(time(NULL)); /* Initialize random number generator */
-
- /* script_dissect(0, s->selector_names, s->selector_names_nr); */
- game_obj = script_lookup_export(s, 0, 0);
- /* The first entry in the export table of script 0 points to the game object */
-
- s->game_name = sci_strdup(obj_get_name(s, game_obj));
-
- if (!s->game_name) {
- sciprintf("Error: script.000, export 0 ("PREG") does not\n"
- " yield an object with a name -> sanity check failed\n",
- PRINT_REG(game_obj));
- return 1;
- }
-
- sciprintf(" \"%s\" at "PREG"\n", s->game_name, PRINT_REG(game_obj));
-
- if (strlen((char *) s->game_name) >= MAX_GAMEDIR_SIZE) {
-
- s->game_name[MAX_GAMEDIR_SIZE - 1] = 0; /* Fix length with brute force */
- sciprintf(" Designation too long; was truncated to \"%s\"\n", s->game_name);
- }
-
- s->game_obj = game_obj;
-
- /* Mark parse tree as unused */
- s->parser_nodes[0].type = PARSE_TREE_NODE_LEAF;
- s->parser_nodes[0].content.value = 0;
-
- s->menubar = menubar_new(); /* Create menu bar */
-
- return 0;
-}
-
-int
-game_exit(state_t *s)
-{
- if (s->execution_stack) {
- sci_free(s->execution_stack);
- }
-
-#if 0
- sfx_exit(&s->sound);
-/* Reinit because some other code depends on having a valid state */
- game_init_sound(s, SFX_STATE_FLAG_NOSOUND);
-#else
-#endif
-
- sm_destroy(&s->seg_manager);
-
- if (s->synonyms_nr) {
- sci_free(s->synonyms);
- s->synonyms = NULL;
- s->synonyms_nr = 0;
- }
-
- sciprintf("Freeing miscellaneous data...\n");
-
-#ifdef __GNUC__
-#warning "Free parser segment here"
-#endif
- if (send_calls_allocated) {
- sci_free(send_calls);
- send_calls_allocated = 0;
- }
-
-#ifdef __GNUC__
-#warning "Free scripts here"
-#endif
-
- menubar_free(s->menubar);
-
- _free_graphics_input(s);
-
- sci_free(s->game_name);
-
- return 0;
-}
-
Copied: scummvm/trunk/engines/sci/engine/game.cpp (from rev 38224, scummvm/trunk/engines/sci/engine/game.c)
===================================================================
--- scummvm/trunk/engines/sci/engine/game.cpp (rev 0)
+++ scummvm/trunk/engines/sci/engine/game.cpp 2009-02-15 11:39:07 UTC (rev 38227)
@@ -0,0 +1,773 @@
+/***************************************************************************
+ game.c Copyright (C) 1999 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 at linuxgames.com]
+
+***************************************************************************/
+
+#include "sci/include/sciresource.h"
+#include "sci/include/engine.h"
+#include "sci/include/versions.h"
+#include "sci/include/kernel.h"
+#include "sci/engine/kernel_types.h"
+
+/* Structures and data from vm.c: */
+extern calls_struct_t *send_calls;
+extern int send_calls_allocated;
+extern int bp_flag;
+
+
+
+static int
+_init_vocabulary(state_t *s) /* initialize vocabulary and related resources */
+{
+ s->parser_lastmatch_word = SAID_NO_MATCH;
+ s->parser_rules = NULL;
+
+ sciprintf("Initializing vocabulary\n");
+
+ if ((s->resmgr->sci_version < SCI_VERSION_01_VGA)&&(s->parser_words = vocab_get_words(s->resmgr, &(s->parser_words_nr)))) {
+ s->parser_suffices = vocab_get_suffices(s->resmgr, &(s->parser_suffices_nr));
+ if ((s->parser_branches = vocab_get_branches(s->resmgr, &(s->parser_branches_nr))))
+ /* Now build a GNF grammar out of this */
+ s->parser_rules = vocab_build_gnf(s->parser_branches, s->parser_branches_nr);
+
+ } else {
+ sciprintf("Assuming that this game does not use a parser.\n");
+ s->parser_rules = NULL;
+ }
+
+
+ s->opcodes = vocabulary_get_opcodes(s->resmgr);
+
+ if (!(s->selector_names = vocabulary_get_snames(s->resmgr, NULL, s->version))) {
+ sciprintf("_init_vocabulary(): Could not retreive selector names (vocab.997)!\n");
+ return 1;
+ }
+
+ for (s->selector_names_nr = 0; s->selector_names[s->selector_names_nr]; s->selector_names_nr++);
+ /* Counts the number of selector names */
+
+ script_map_selectors(s, &(s->selector_map));
+ /* Maps a few special selectors for later use */
+
+ return 0;
+}
+
+extern int _allocd_rules;
+static void
+_free_vocabulary(state_t *s)
+{
+ sciprintf("Freeing vocabulary\n");
+
+ if (s->parser_words) {
+ vocab_free_words(s->parser_words, s->parser_words_nr);
+ vocab_free_suffices(s->resmgr, s->parser_suffices, s->parser_suffices_nr);
+ vocab_free_branches(s->parser_branches);
+ vocab_free_rule_list(s->parser_rules);
+ }
+
+ vocabulary_free_snames(s->selector_names);
+ vocabulary_free_knames(s->kernel_names);
+ vocabulary_free_opcodes(s->opcodes);
+ s->opcodes = NULL;
+
+ s->selector_names = NULL;
+ s->kernel_names = NULL;
+ s->opcodes = NULL;
+}
+
+
+static int
+_init_graphics_input(state_t *s)
+{
+ s->pic_priority_table = NULL;
+ s->pics = NULL;
+ s->pics_nr = 0;
+ return 0;
+}
+
+static void
+_sci1_alloc_system_colors(state_t *s)
+{
+ gfx_color_t white;
+ gfx_color_t black;
+
+ white.visual.global_index = 255;
+ white.visual.r = white.visual.g = white.visual.b = 255;
+ white.alpha = 0;
+ white.priority = white.control = 0;
+ white.mask = GFX_MASK_VISUAL;
+ gfxop_set_system_color(s->gfx_state, &white);
+
+ black.visual.global_index = 0;
+ black.visual.r = black.visual.g = black.visual.b = 0;
+ black.alpha = 0;
+ black.priority = black.control = 0;
+ black.mask = GFX_MASK_VISUAL;
+ gfxop_set_system_color(s->gfx_state, &black);
+}
+
+int
+_reset_graphics_input(state_t *s)
+{
+ resource_t *resource;
+ int font_nr;
+ gfx_color_t transparent;
+ sciprintf("Initializing graphics\n");
+
+ if (s->resmgr->sci_version <= SCI_VERSION_01) {
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ if (gfxop_set_color(s->gfx_state, &(s->ega_colors[i]),
+ gfx_sci0_image_colors[sci0_palette][i].r,
+ gfx_sci0_image_colors[sci0_palette][i].g,
+ gfx_sci0_image_colors[sci0_palette][i].b,
+ 0, -1, -1))
+ return 1;
+ gfxop_set_system_color(s->gfx_state, &(s->ega_colors[i]));
+ }
+ } else
+ {
+ /* Check for Amiga palette file. */
+ FILE *f = sci_fopen("spal", "rb");
+ if (f) {
+ s->gfx_state->resstate->static_palette =
+ gfxr_read_pal1_amiga(&s->gfx_state->resstate->static_palette_entries, f);
+ fclose(f);
+ _sci1_alloc_system_colors(s);
+ } else {
+ resource = scir_find_resource(s->resmgr, sci_palette, 999, 1);
+ if (resource) {
+ if (s->version < SCI_VERSION(1,001,000))
+ s->gfx_state->resstate->static_palette =
+ gfxr_read_pal1(999, &s->gfx_state->resstate->static_palette_entries,
+ resource->data, resource->size);
+ else
+ s->gfx_state->resstate->static_palette =
+ gfxr_read_pal11(999, &s->gfx_state->resstate->static_palette_entries,
+ resource->data, resource->size);
+ _sci1_alloc_system_colors(s);
+ scir_unlock_resource(s->resmgr, resource, sci_palette, 999);
+ } else
+ sciprintf("Couldn't find the default palette!\n");
+ }
+ }
+ transparent.mask = 0;
+
+ gfxop_fill_box(s->gfx_state, gfx_rect(0, 0, 320, 200), s->ega_colors[0]); /* Fill screen black */
+ gfxop_update(s->gfx_state);
+
+ s->mouse_pointer_view = s->mouse_pointer_loop = s->mouse_pointer_cel = -1; /* No mouse pointer resource */
+ s->save_mouse_pointer_view = s->save_mouse_pointer_loop = s->save_mouse_pointer_cel = -1; /* No mouse pointer resource */
+ gfxop_set_pointer_position(s->gfx_state, gfx_point(160, 150));
+
+ s->mouse_pointer_view = s->mouse_pointer_loop = s->mouse_pointer_cel = -1; /* No mouse pointer resource */
+ s->save_mouse_pointer_view = s->save_mouse_pointer_loop = s->save_mouse_pointer_cel = -1; /* No mouse pointer resource */
+
+
+ s->pic_is_new = 0;
+ s->pic_visible_map = GFX_MASK_NONE; /* Other values only make sense for debugging */
+ s->dyn_views = NULL; /* no DynViews */
+ s->drop_views = NULL; /* And, consequently, no list for dropped views */
+
+ s->priority_first = 42; /* Priority zone 0 ends here */
+
+ if (s->version < SCI_VERSION_FTU_PRIORITY_14_ZONES)
+ s->priority_last = 200; else
+ s->priority_last = 190;
+
+ font_nr = -1;
+ do {
+ resource = scir_test_resource(s->resmgr, sci_font, ++font_nr);
+ } while ((!resource) && (font_nr < sci_max_resource_nr[s->resmgr->sci_version]));
+
+ if (!resource) {
+ sciprintf("No text font was found.\n");
+ return 1;
+ }
+
+ s->visual = gfxw_new_visual(s->gfx_state, font_nr);
+
+ s->wm_port = gfxw_new_port(s->visual, NULL, s->gfx_state->options->pic_port_bounds, s->ega_colors[0], transparent);
+ s->iconbar_port = gfxw_new_port(s->visual, NULL, gfx_rect(0, 0, 320, 200), s->ega_colors[0], transparent);
+ s->iconbar_port->flags |= GFXW_FLAG_NO_IMPLICIT_SWITCH;
+
+ if (s->resmgr->sci_version >= SCI_VERSION_01_VGA)
+ {
+ gfx_color_t fgcolor;
+ gfx_color_t bgcolor;
+
+#if 0
+ fgcolor.visual = s->gfx_state->resstate->static_palette[0];
+ fgcolor.mask = GFX_MASK_VISUAL;
+ bgcolor.visual = s->gfx_state->resstate->static_palette[255];
+ bgcolor.mask = GFX_MASK_VISUAL;
+#endif
+ s->titlebar_port = gfxw_new_port(s->visual, NULL, gfx_rect(0, 0, 320, 10),
+ fgcolor, bgcolor);
+ } else
+ s->titlebar_port = gfxw_new_port(s->visual, NULL, gfx_rect(0, 0, 320, 10),
+ s->ega_colors[0], s->ega_colors[15]);
+ s->titlebar_port->color.mask |= GFX_MASK_PRIORITY;
+ s->titlebar_port->color.priority = 11;
+ s->titlebar_port->bgcolor.mask |= GFX_MASK_PRIORITY;
+ s->titlebar_port->bgcolor.priority = 11;
+ s->titlebar_port->flags |= GFXW_FLAG_NO_IMPLICIT_SWITCH;
+
+ /* but this is correct */
+ s->picture_port = gfxw_new_port(s->visual, NULL, s->gfx_state->options->pic_port_bounds, s->ega_colors[0], transparent);
+
+ s->pics_drawn_nr = 0;
+
+ s->visual->add(GFXWC(s->visual), GFXW(s->wm_port));
+ s->visual->add(GFXWC(s->visual), GFXW(s->titlebar_port));
+ s->visual->add(GFXWC(s->visual), GFXW(s->picture_port));
+ s->visual->add(GFXWC(s->visual), GFXW(s->iconbar_port));
+ /* Add ports to visual */
+
+ s->port = s->picture_port; /* Currently using the picture port */
+
+#if 0
+ s->titlebar_port->bgcolor.mask |= GFX_MASK_PRIORITY;
+ s->titlebar_port->bgcolor.priority = 11; /* Standard priority for the titlebar port */
+#endif
+
+ return 0;
+}
+
+int
+game_init_graphics(state_t *s)
+{
+#ifndef WITH_PIC_SCALING
+ if (s->gfx_state->options->pic0_unscaled == 0)
+ sciprintf("WARNING: Pic scaling was disabled; your version of FreeSCI has no support for scaled pic drawing built in.\n");
+
+ s->gfx_state->options->pic0_unscaled = 1;
+#endif
+ return _reset_graphics_input(s);
+}
+
+
+static void
+_free_graphics_input(state_t *s)
+{
+ sciprintf("Freeing graphics\n");
+
+ s->visual->widfree(GFXW(s->visual));
+
+ s->wm_port = s->titlebar_port = s->picture_port = NULL;
+ s->visual = NULL;
+ s->dyn_views = NULL;
+ s->port = NULL;
+
+ if (s->pics)
+ sci_free(s->pics);
+ s->pics = NULL;
+}
+
+/*------------------------------------------------------------*/
+
+int
+game_init_sound(state_t *s, int sound_flags)
+{
+ if (s->resmgr->sci_version >= SCI_VERSION_01)
+ sound_flags |= SFX_STATE_FLAG_MULTIPLAY;
+
+ s->sfx_init_flags = sound_flags;
+ sfx_init(&s->sound, s->resmgr, sound_flags);
+ return 0;
+}
+
+
+/* Maps a class ID to the script the corresponding class is contained in */
+/* Returns the script number suggested by vocab.996, or -1 if there's none */
+static int
+suggested_script(resource_t *res, unsigned int class)
+{
+ int offset;
+ if (!res || class >= res->size >> 2)
+ return -1;
+
+ offset = 2 + (class << 2);
+
+ return getInt16(res->data + offset);
+}
+
+
+int
+test_cursor_style(state_t *s)
+{
+ int resource_nr = 0;
+ int ok = 0;
+
+ do {
+ ok |= scir_test_resource(s->resmgr, sci_cursor, resource_nr++) != NULL;
+ } while (resource_nr < 1000 && !ok);
+
+ return ok;
+}
+
+int
+create_class_table_sci11(state_t *s)
+{
+ int scriptnr;
+ unsigned int seeker_offset;
+ char *seeker_ptr;
+ int classnr;
+
+ resource_t *vocab996 = scir_find_resource(s->resmgr, sci_vocab, 996, 1);
+
+ if (!vocab996)
+ s->classtable_size = 20;
+ else
+ s->classtable_size = vocab996->size >> 2;
+
+ s->classtable = (class_t*)sci_calloc(sizeof(class_t), s->classtable_size);
+
+ for (scriptnr = 0; scriptnr < 1000; scriptnr++) {
+ resource_t *heap = scir_find_resource(s->resmgr, sci_heap,
+ scriptnr, 0);
+
+ if (heap) {
+ int global_vars = getUInt16(heap->data + 2);
+
+ seeker_ptr = (char*)heap->data + 4 + global_vars*2;
+ seeker_offset = 4 + global_vars*2;
+
+ while (getUInt16((byte*)seeker_ptr) == SCRIPT_OBJECT_MAGIC_NUMBER)
+ {
+ if (getUInt16((byte*)seeker_ptr + 14) & SCRIPT_INFO_CLASS)
+ {
+ classnr = getUInt16((byte*)seeker_ptr + 10);
+ if (classnr >= s->classtable_size) {
+
+ if (classnr >= SCRIPT_MAX_CLASSTABLE_SIZE) {
+ fprintf(stderr,"Invalid class number 0x%x in script.%d(0x%x), offset %04x\n",
+ classnr, scriptnr, scriptnr, seeker_offset);
+ return 1;
+ }
+
+ s->classtable = (class_t*)sci_realloc(s->classtable, sizeof(class_t) * (classnr + 1));
+ memset(&(s->classtable[s->classtable_size]), 0,
+ sizeof(class_t) * (1 + classnr - s->classtable_size)); /* Clear after resize */
+
+ s->classtable_size = classnr + 1; /* Adjust maximum number of entries */
+ }
+
+ s->classtable[classnr].reg.offset = seeker_offset;
+ s->classtable[classnr].reg.segment = 0;
+ s->classtable[classnr].script = scriptnr;
+ }
+
+ seeker_ptr += getUInt16((byte*)seeker_ptr + 2) * 2;
+ seeker_offset += getUInt16((byte*)seeker_ptr + 2) * 2;
+ }
+ }
+ }
+
+ return 0;
+}
+static int
+create_class_table_sci0(state_t *s)
+{
+ int scriptnr;
+ unsigned int seeker;
+ int classnr;
+ int magic_offset; /* For strange scripts in older SCI versions */
+
+ resource_t *vocab996 = scir_find_resource(s->resmgr, sci_vocab, 996, 1);
+
+ if (!vocab996)
+ s->classtable_size = 20;
+ else
+ s->classtable_size = vocab996->size >> 2;
+
+ s->classtable = (class_t*)sci_calloc(sizeof(class_t), s->classtable_size);
+
+ for (scriptnr = 0; scriptnr < 1000; scriptnr++) {
+ int objtype = 0;
+ resource_t *script = scir_find_resource(s->resmgr, sci_script,
+ scriptnr, 0);
+
+ if (script) {
+ if (s->version < SCI_VERSION_FTU_NEW_SCRIPT_HEADER)
+ magic_offset = seeker = 2;
+ else
+ magic_offset = seeker = 0;
+
+ do {
+
+ while (seeker < script->size) {
+ unsigned int lastseeker = seeker;
+ objtype = getInt16(script->data + seeker);
+ if (objtype == sci_obj_class || objtype == sci_obj_terminator)
+ break;
+ seeker += getInt16(script->data + seeker + 2);
+ if (seeker <= lastseeker) {
+ sciprintf("Warning: Script version is invalid.\n");
+ sci_free(s->classtable);
+ return SCI_ERROR_INVALID_SCRIPT_VERSION;
+ }
+ }
+
+ if (objtype == sci_obj_class) {
+ int sugg_script;
+
+ seeker -= SCRIPT_OBJECT_MAGIC_OFFSET; /* Adjust position; script home is base +8 bytes */
+
+ classnr = getInt16(script->data + seeker + 4 + SCRIPT_SPECIES_OFFSET);
+ if (classnr >= s->classtable_size) {
+
+ if (classnr >= SCRIPT_MAX_CLASSTABLE_SIZE) {
+ fprintf(stderr,"Invalid class number 0x%x in script.%d(0x%x), offset %04x\n",
+ classnr, scriptnr, scriptnr, seeker);
+ return 1;
+ }
+
+ s->classtable = (class_t*)sci_realloc(s->classtable, sizeof(class_t) * (classnr + 1));
+ memset(&(s->classtable[s->classtable_size]), 0,
+ sizeof(class_t) * (1 + classnr - s->classtable_size)); /* Clear after resize */
+
+ s->classtable_size = classnr + 1; /* Adjust maximum number of entries */
+ }
+
+ sugg_script = suggested_script(vocab996, classnr);
+
+ /* First, test whether the script hasn't been claimed, or if it's been claimed by the wrong script */
+
+ if (sugg_script == -1 || scriptnr == sugg_script /*|| !s->classtable[classnr].reg.segment*/) {
+ /* Now set the home script of the class */
+ s->classtable[classnr].reg.offset = seeker + 4 - magic_offset;
+ s->classtable[classnr].reg.segment = 0;
+ s->classtable[classnr].script = scriptnr;
+ }
+
+ seeker += SCRIPT_OBJECT_MAGIC_OFFSET; /* Re-adjust position */
+
+ seeker += getInt16(script->data + seeker + 2); /* Move to next */
+ }
+
+ } while (objtype != sci_obj_terminator && seeker <= script->size);
+
+ }
+ }
+ scir_unlock_resource(s->resmgr, vocab996, sci_vocab, 996);
+ vocab996 = NULL;
+ return 0;
+}
+
+/* Architectural stuff: Init/Unintialize engine */
+int
+script_init_engine(state_t *s, sci_version_t version)
+{
+ int result;
+
+ s->max_version = SCI_VERSION(9,999,999); /* :-) */
+ s->min_version = 0; /* Set no real limits */
+ s->version = SCI_VERSION_DEFAULT_SCI0;
+ s->kernel_opt_flags = 0;
+
+ if (!version) {
+ s->version_lock_flag = 0;
+ } else {
+ s->version = version;
+ s->version_lock_flag = 1; /* Lock version */
+ }
+
+ script_detect_versions(s);
+
+ if (s->version >= SCI_VERSION(1,001,000))
+ result = create_class_table_sci11(s);
+ else
+ result = create_class_table_sci0(s);
+
+ sm_init(&s->seg_manager, s->version >= SCI_VERSION(1,001,000));
+ s->gc_countdown = GC_INTERVAL - 1;
+
+ if (result)
+ {
+ sciprintf("Failed to initialize class table\n");
+ return 1;
+ }
+
+ s->script_000_segment = script_get_segment(s, 0, SCRIPT_GET_LOCK);
+
+ if (s->script_000_segment <= 0) {
+ sciprintf("Failed to instantiate script.000\n");
+ return 1;
+ }
+
+ s->script_000 = &(s->seg_manager.heap[s->script_000_segment]->data.script);
+
+
+ s->sys_strings = sm_allocate_sys_strings(&s->seg_manager,
+ &s->sys_strings_segment);
+ /* Allocate static buffer for savegame and CWD directories */
+ sys_string_acquire(s->sys_strings, SYS_STRING_SAVEDIR, "savedir", MAX_SAVE_DIR_SIZE);
+
+ s->save_dir_copy = make_reg(s->sys_strings_segment, SYS_STRING_SAVEDIR);
+ s->save_dir_edit_offset = 0;
+
+ s->r_acc = s->r_prev = NULL_REG;
+ s->r_amp_rest = 0;
+
+ s->execution_stack = NULL; /* Start without any execution stack */
+ s->execution_stack_base = -1; /* No vm is running yet */
+ s->execution_stack_pos = -1; /* Start at execution stack position 0 */
+
+
+ s->kernel_names = vocabulary_get_knames(s->resmgr, &s->kernel_names_nr);
+ script_map_kernel(s);
+ /* Maps the kernel functions */
+
+ if (_init_vocabulary(s)) return 1;
+ if (s->selector_map.cantBeHere != -1)
+ version_require_later_than(s, SCI_VERSION_FTU_INVERSE_CANBEHERE);
+
+ s->restarting_flags = SCI_GAME_IS_NOT_RESTARTING;
+
+ s->bp_list = NULL; /* No breakpoints defined */
+ s->have_bp = 0;
+
+ s->file_handles_nr = 5;
+ s->file_handles = (FILE**)sci_calloc(sizeof(FILE *), s->file_handles_nr);
+ /* Allocate memory for file handles */
+
+ sci_init_dir(&(s->dirseeker));
+ s->dirseeker_outbuffer = NULL_REG;
+ /* Those two are used by FileIO for FIND_FIRST, FIND_NEXT */
+
+ if (s->version >= SCI_VERSION_FTU_LOFS_ABSOLUTE &&
+ s->version < SCI_VERSION(1,001,000))
+ sm_set_export_width(&s->seg_manager, 1);
+ else
+ sm_set_export_width(&s->seg_manager, 0);
+
+ sciprintf("Engine initialized\n");
+
+ if (_init_graphics_input(s))
+ return 1;
+
+ return 0;
+}
+
+
+void
+script_set_gamestate_save_dir(state_t *s, const char* path)
+{
+ sys_string_set(s->sys_strings, SYS_STRING_SAVEDIR, path);
+}
+
+void
+script_free_vm_memory(state_t *s)
+{
+ int i;
+
+ sciprintf("Freeing VM memory\n");
+ s->save_dir_copy_buf = NULL;
+
+ sci_free(s->classtable);
+ s->classtable = NULL;
+
+ /* Close all opened file handles */
+#ifndef _DOS
+ for (i = 1; i < s->file_handles_nr; i++)
+ if (s->file_handles[i])
+ fclose(s->file_handles[i]);
+#endif
+
+ sci_free(s->file_handles);
+ s->file_handles = NULL;
+
+ /* FIXME: file handles will NOT be closed under DOS. DJGPP generates an
+ exception fault whenever you try to close a never-opened file */
+}
+
+extern void
+free_kfunct_tables(state_t *s);
+/* From kernel.c */
+
+void
+script_free_engine(state_t *s)
+{
+ script_free_vm_memory(s);
+
+ sciprintf("Freeing state-dependant data\n");
+
+ free_kfunct_tables(s);
+
+ _free_vocabulary(s);
+
+}
+
+void
+script_free_breakpoints(state_t *s)
+{
+ breakpoint_t *bp, *bp_next;
+
+ /* Free breakpoint list */
+ bp = s->bp_list;
+ while (bp) {
+ bp_next = bp->next;
+ if (bp->type == BREAK_SELECTOR) sci_free (bp->data.name);
+ free (bp);
+ bp = bp_next;
+ }
+
+ s->bp_list = NULL;
+}
+
+/*************************************************************/
+/* Game instance stuff: Init/Unitialize state-dependant data */
+/*************************************************************/
+
+
+int
+game_init(state_t *s)
+{
+#ifdef __GNUC__
+# warning "Fixme: Use new VM instantiation code all over the place"
+#endif
+ reg_t game_obj; /* Address of the game object */
+ dstack_t *stack;
+
+ stack = sm_allocate_stack(&s->seg_manager, VM_STACK_SIZE,
+ &s->stack_segment);
+ s->stack_base = stack->entries;
+ s->stack_top = s->stack_base + VM_STACK_SIZE;
+
+ if (!script_instantiate(s, 0)) {
+ sciprintf("game_init(): Could not instantiate script 0\n");
+ return 1;
+ }
+
+ s->parser_valid = 0; /* Invalidate parser */
+ s->parser_event = NULL_REG; /* Invalidate parser event */
+
+ s->synonyms = NULL;
+ s->synonyms_nr = 0; /* No synonyms */
+
+ /* Initialize send_calls buffer */
+
+ if (!send_calls_allocated)
+ send_calls = (calls_struct_t*)sci_calloc(sizeof(calls_struct_t), send_calls_allocated = 16);
+
+ if (s->gfx_state && _reset_graphics_input(s))
+ return 1;
+
+ s->successor = NULL; /* No successor */
+ s->status_bar_text = NULL; /* Status bar is blank */
+ s->status_bar_foreground = 0;
+ s->status_bar_background = s->resmgr->sci_version >= SCI_VERSION_01_VGA ? 255 : 15;
+
+ sys_string_acquire(s->sys_strings, SYS_STRING_PARSER_BASE, "parser-base", MAX_PARSER_BASE);
+ s->parser_base = make_reg(s->sys_strings_segment, SYS_STRING_PARSER_BASE);
+
+ sci_get_current_time(&(s->game_start_time)); /* Get start time */
+ memcpy(&(s->last_wait_time), &(s->game_start_time), sizeof(GTimeVal));
+ /* Use start time as last_wait_time */
+
+ s->debug_mode = 0x0; /* Disable all debugging */
+ s->onscreen_console = 0; /* No onscreen console unless explicitly requested */
+
+ srand(time(NULL)); /* Initialize random number generator */
+
+ /* script_dissect(0, s->selector_names, s->selector_names_nr); */
+ game_obj = script_lookup_export(s, 0, 0);
+ /* The first entry in the export table of script 0 points to the game object */
+
+ s->game_name = sci_strdup(obj_get_name(s, game_obj));
+
+ if (!s->game_name) {
+ sciprintf("Error: script.000, export 0 ("PREG") does not\n"
+ " yield an object with a name -> sanity check failed\n",
+ PRINT_REG(game_obj));
+ return 1;
+ }
+
+ sciprintf(" \"%s\" at "PREG"\n", s->game_name, PRINT_REG(game_obj));
+
+ if (strlen((char *) s->game_name) >= MAX_GAMEDIR_SIZE) {
+
+ s->game_name[MAX_GAMEDIR_SIZE - 1] = 0; /* Fix length with brute force */
+ sciprintf(" Designation too long; was truncated to \"%s\"\n", s->game_name);
+ }
+
+ s->game_obj = game_obj;
+
+ /* Mark parse tree as unused */
+ s->parser_nodes[0].type = PARSE_TREE_NODE_LEAF;
+ s->parser_nodes[0].content.value = 0;
+
+ s->menubar = menubar_new(); /* Create menu bar */
+
+ return 0;
+}
+
+int
+game_exit(state_t *s)
+{
+ if (s->execution_stack) {
+ sci_free(s->execution_stack);
+ }
+
+#if 0
+ sfx_exit(&s->sound);
+/* Reinit because some other code depends on having a valid state */
+ game_init_sound(s, SFX_STATE_FLAG_NOSOUND);
+#else
+#endif
+
+ sm_destroy(&s->seg_manager);
+
+ if (s->synonyms_nr) {
+ sci_free(s->synonyms);
+ s->synonyms = NULL;
+ s->synonyms_nr = 0;
+ }
+
+ sciprintf("Freeing miscellaneous data...\n");
+
+#ifdef __GNUC__
+#warning "Free parser segment here"
+#endif
+ if (send_calls_allocated) {
+ sci_free(send_calls);
+ send_calls_allocated = 0;
+ }
+
+#ifdef __GNUC__
+#warning "Free scripts here"
+#endif
+
+ menubar_free(s->menubar);
+
+ _free_graphics_input(s);
+
+ sci_free(s->game_name);
+
+ return 0;
+}
+
Deleted: scummvm/trunk/engines/sci/engine/gc.c
===================================================================
--- scummvm/trunk/engines/sci/engine/gc.c 2009-02-15 11:21:31 UTC (rev 38226)
+++ scummvm/trunk/engines/sci/engine/gc.c 2009-02-15 11:39:07 UTC (rev 38227)
@@ -1,334 +0,0 @@
-/***************************************************************************
- Copyright (C) 2005 Christoph Reichenbach <reichenb at colorado.edu>
-
- 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.
-
-***************************************************************************/
-
-#include "sci/engine/gc.h"
-
-#define WORKLIST_CHUNK_SIZE 32
-
-/*#define DEBUG_GC*/
-/*#define DEBUG_GC_VERBOSE*/
-
-typedef struct _worklist {
- int used;
- reg_t entries[WORKLIST_CHUNK_SIZE];
- struct _worklist *next;
-} worklist_t;
-
-static worklist_t *
-fresh_worklist(worklist_t *old)
-{
- worklist_t *retval = (worklist_t*)sci_malloc(sizeof(worklist_t));
- retval->used = 0;
- retval->next = old;
- return retval;
-}
-
-static worklist_t *
-new_worklist()
-{
- return fresh_worklist(NULL);
-}
-
-static void
-worklist_push(worklist_t **wlp, reg_t_hash_map_ptr hashmap, reg_t reg)
-{
- worklist_t *wl = *wlp;
- char added;
-
- if (!reg.segment) /* No numbers */
- return;
-
-#ifdef DEBUG_GC_VERBOSE
- sciprintf("[GC] Adding "PREG"\n", PRINT_REG(reg));
-#endif
-
- reg_t_hash_map_check_value(hashmap, reg, 1, &added);
-
- if (!added)
- return; /* already dealt with it */
-
- if (!wl || wl->used == WORKLIST_CHUNK_SIZE)
- *wlp = wl = fresh_worklist(wl);
-
- wl->entries[wl->used++] = reg;
-}
-
-static int
-worklist_has_next(worklist_t *wl)
-{
- return (wl && wl->used);
-}
-
-static reg_t
-worklist_pop(worklist_t **wlp)
-{
- worklist_t *wl = *wlp;
- reg_t retval;
-
- if (!wl || !wl->used) {
- fprintf(stderr, "Attempt to pop from empty worklist");
- exit(1);
- }
-
- retval = wl->entries[--wl->used];
-
- if (!wl->used) {
- *wlp = wl->next;
- sci_free(wl);
- }
-
- return retval;
-}
-
-static void
-free_worklist(worklist_t *wl)
-{
- if (wl) {
- if (wl->next)
- free_worklist(wl->next);
- sci_free(wl);
- }
-}
-
-typedef struct {
- seg_interface_t **interfaces;
- int interfaces_nr;
- reg_t_hash_map_ptr normal_map;
-} normaliser_t;
-
-void
-store_normalised(void *pre_normaliser, reg_t reg, int _)
-{
- seg_interface_t *interfce;
- normaliser_t *normaliser = (normaliser_t *) pre_normaliser;
- interfce = (reg.segment < normaliser->interfaces_nr)
- ? normaliser->interfaces[reg.segment]
- : NULL;
-
- if (interfce) {
- reg = interfce->find_canonic_address(interfce, reg);
- reg_t_hash_map_check_value(normaliser->normal_map, reg, 1, NULL);
- }
-}
-
-static reg_t_hash_map_ptr
-normalise_hashmap_ptrs(reg_t_hash_map_ptr nonnormal_map, seg_interface_t **interfaces, int interfaces_nr)
-{
- normaliser_t normaliser;
-
- normaliser.normal_map = new_reg_t_hash_map();
- normaliser.interfaces_nr = interfaces_nr;
- normaliser.interfaces = interfaces;
- apply_to_reg_t_hash_map(nonnormal_map, &normaliser, &store_normalised);
-
- return normaliser.normal_map;
-}
-
-
-typedef struct {
- reg_t_hash_map_ptr nonnormal_map;
- worklist_t **worklist_ref;
-} worklist_manager_t;
-
-void
-add_outgoing_refs(void *pre_wm, reg_t addr)
-{
- worklist_manager_t *wm = (worklist_manager_t *) pre_wm;
- worklist_push(wm->worklist_ref, wm->nonnormal_map, addr);
-}
-
-reg_t_hash_map_ptr
-find_all_used_references(state_t *s)
-{
- seg_manager_t *sm = &(s->seg_manager);
- seg_interface_t **interfaces = (seg_interface_t**)sci_calloc(sizeof(seg_interface_t *), sm->heap_size);
- reg_t_hash_map_ptr nonnormal_map = new_reg_t_hash_map();
- reg_t_hash_map_ptr normal_map = NULL;
- worklist_t *worklist = new_worklist();
- worklist_manager_t worklist_manager;
- int i;
-
- worklist_manager.worklist_ref = &worklist;
- worklist_manager.nonnormal_map = nonnormal_map;
-
- for (i = 1; i < sm->heap_size; i++)
- if (sm->heap[i] == NULL)
- interfaces[i] = NULL;
- else
- interfaces[i] = get_seg_interface(sm, i);
-
- /* Initialise */
- /* Init: Registers */
- worklist_push(&worklist, nonnormal_map, s->r_acc);
- worklist_push(&worklist, nonnormal_map, s->r_prev);
- /* Init: Value Stack */
- /* We do this one by hand since the stack doesn't know the current execution stack */
- {
- exec_stack_t *xs = s->execution_stack + s->execution_stack_pos;
- reg_t *pos;
-
- for (pos = s->stack_base; pos < xs->sp; pos++)
- worklist_push(&worklist, nonnormal_map, *pos);
- }
-#ifdef DEBUG_GC_VERBOSE
- sciprintf("[GC] -- Finished adding value stack");
-#endif
-
-
- /* Init: Execution Stack */
- for (i = 0; i <= s->execution_stack_pos; i++) {
- exec_stack_t *es = s->execution_stack + i;
-
- if (es->type != EXEC_STACK_TYPE_KERNEL) {
- worklist_push(&worklist, nonnormal_map, es->objp);
- worklist_push(&worklist, nonnormal_map, es->sendp);
- if (es->type == EXEC_STACK_TYPE_VARSELECTOR)
- worklist_push(&worklist, nonnormal_map, *(es->addr.varp));
- }
- }
-#ifdef DEBUG_GC_VERBOSE
- sciprintf("[GC] -- Finished adding execution stack");
-#endif
-
- /* Init: Explicitly loaded scripts */
- for (i = 1; i < sm->heap_size; i++)
- if (interfaces[i]
- && interfaces[i]->type_id == MEM_OBJ_SCRIPT) {
- script_t *script = &(interfaces[i]->mobj->data.script);
-
- if (script->lockers) { /* Explicitly loaded? */
- int obj_nr;
-
- /* Locals, if present */
- worklist_push(&worklist, nonnormal_map, make_reg(script->locals_segment, 0));
-
- /* All objects (may be classes, may be indirectly reachable) */
- for (obj_nr = 0; obj_nr < script->objects_nr; obj_nr++) {
- object_t *obj = script->objects + obj_nr;
- worklist_push(&worklist,
- nonnormal_map,
- obj->pos);
- }
- }
- }
-#ifdef DEBUG_GC_VERBOSE
- sciprintf("[GC] -- Finished explicitly loaded scripts, done with root set");
-#endif
-
-
- /* Run Worklist Algorithm */
- while (worklist_has_next(worklist)) {
- reg_t reg = worklist_pop(&worklist);
- if (reg.segment != s->stack_segment) { /* No need to repeat this one */
-#ifdef DEBUG_GC_VERBOSE
- sciprintf("[GC] Checking "PREG"\n", PRINT_REG(reg));
-#endif
- if (reg.segment < sm->heap_size
- && interfaces[reg.segment])
- interfaces[reg.segment]->list_all_outgoing_references(interfaces[reg.segment],
- s,
- reg,
- &worklist_manager,
- add_outgoing_refs);
- }
- }
-
- /* Normalise */
- normal_map = normalise_hashmap_ptrs(nonnormal_map, interfaces, sm->heap_size);
-
- /* Cleanup */
- for (i = 1; i < sm->heap_size; i++)
- if (interfaces[i])
- interfaces[i]->deallocate_self(interfaces[i]);
- sci_free(interfaces);
- free_reg_t_hash_map(nonnormal_map);
- return normal_map;
-}
-
-
-typedef struct {
- seg_interface_t *interfce;
-#ifdef DEBUG_GC
- char *segnames[MEM_OBJ_MAX + 1];
- int segcount[MEM_OBJ_MAX + 1];
-#endif
- reg_t_hash_map_ptr use_map;
-} deallocator_t;
-
-void
-free_unless_used (void *pre_use_map, reg_t addr)
-{
- deallocator_t *deallocator = (deallocator_t *) pre_use_map;
- reg_t_hash_map_ptr use_map = deallocator->use_map;
-
- if (0 > reg_t_hash_map_check_value(use_map, addr, 0, NULL)) {
- /* Not found -> we can free it */
- deallocator->interfce->free_at_address(deallocator->interfce, addr);
-#ifdef DEBUG_GC
- sciprintf("[GC] Deallocating "PREG"\n", PRINT_REG(addr));
- deallocator->segcount[deallocator->interfce->type_id]++;
-#endif
- }
-
-}
-
-void
-run_gc(state_t *s)
-{
- int seg_nr;
- deallocator_t deallocator;
- seg_manager_t *sm = &(s->seg_manager);
-
-#ifdef DEBUG_GC
- c_segtable(s);
- sciprintf("[GC] Running...\n");
- memset(&(deallocator.segcount), 0, sizeof(int) * (MEM_OBJ_MAX + 1));
-#endif
-
- deallocator.use_map = find_all_used_references(s);
-
- for (seg_nr = 1; seg_nr < sm->heap_size; seg_nr++)
- if (sm->heap[seg_nr] != NULL) {
- deallocator.interfce = get_seg_interface(sm, seg_nr);
-#ifdef DEBUG_GC
- deallocator.segnames[deallocator.interfce->type_id] = deallocator.interfce->type;
-#endif
-
- deallocator.interfce->list_all_deallocatable(deallocator.interfce,
- &deallocator,
- free_unless_used);
-
- deallocator.interfce->deallocate_self(deallocator.interfce);
- }
-
- free_reg_t_hash_map(deallocator.use_map);
-
-#ifdef DEBUG_GC
- {
- int i;
- sciprintf("[GC] Summary:\n");
- for (i = 0; i <= MEM_OBJ_MAX; i++)
- if (deallocator.segcount[i])
- sciprintf("\t%d\t* %s\n",
- deallocator.segcount[i],
- deallocator.segnames[i]);
- }
-#endif
-}
Copied: scummvm/trunk/engines/sci/engine/gc.cpp (from rev 38224, scummvm/trunk/engines/sci/engine/gc.c)
===================================================================
--- scummvm/trunk/engines/sci/engine/gc.cpp (rev 0)
+++ scummvm/trunk/engines/sci/engine/gc.cpp 2009-02-15 11:39:07 UTC (rev 38227)
@@ -0,0 +1,334 @@
+/***************************************************************************
+ Copyright (C) 2005 Christoph Reichenbach <reichenb at colorado.edu>
+
+ 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.
+
+***************************************************************************/
+
+#include "sci/engine/gc.h"
+
+#define WORKLIST_CHUNK_SIZE 32
+
+/*#define DEBUG_GC*/
+/*#define DEBUG_GC_VERBOSE*/
+
+typedef struct _worklist {
+ int used;
+ reg_t entries[WORKLIST_CHUNK_SIZE];
+ struct _worklist *next;
+} worklist_t;
+
+static worklist_t *
+fresh_worklist(worklist_t *old)
+{
+ worklist_t *retval = (worklist_t*)sci_malloc(sizeof(worklist_t));
+ retval->used = 0;
+ retval->next = old;
+ return retval;
+}
+
+static worklist_t *
+new_worklist()
+{
+ return fresh_worklist(NULL);
+}
+
+static void
+worklist_push(worklist_t **wlp, reg_t_hash_map_ptr hashmap, reg_t reg)
+{
+ worklist_t *wl = *wlp;
+ char added;
+
+ if (!reg.segment) /* No numbers */
+ return;
+
+#ifdef DEBUG_GC_VERBOSE
+ sciprintf("[GC] Adding "PREG"\n", PRINT_REG(reg));
+#endif
+
+ reg_t_hash_map_check_value(hashmap, reg, 1, &added);
+
+ if (!added)
+ return; /* already dealt with it */
+
+ if (!wl || wl->used == WORKLIST_CHUNK_SIZE)
+ *wlp = wl = fresh_worklist(wl);
+
+ wl->entries[wl->used++] = reg;
+}
+
+static int
+worklist_has_next(worklist_t *wl)
+{
+ return (wl && wl->used);
+}
+
+static reg_t
+worklist_pop(worklist_t **wlp)
+{
+ worklist_t *wl = *wlp;
+ reg_t retval;
+
+ if (!wl || !wl->used) {
+ fprintf(stderr, "Attempt to pop from empty worklist");
+ exit(1);
+ }
+
+ retval = wl->entries[--wl->used];
+
+ if (!wl->used) {
+ *wlp = wl->next;
+ sci_free(wl);
+ }
+
+ return retval;
+}
+
+static void
+free_worklist(worklist_t *wl)
+{
+ if (wl) {
+ if (wl->next)
+ free_worklist(wl->next);
+ sci_free(wl);
+ }
+}
+
+typedef struct {
+ seg_interface_t **interfaces;
+ int interfaces_nr;
+ reg_t_hash_map_ptr normal_map;
+} normaliser_t;
+
+void
+store_normalised(void *pre_normaliser, reg_t reg, int _)
+{
+ seg_interface_t *interfce;
+ normaliser_t *normaliser = (normaliser_t *) pre_normaliser;
+ interfce = (reg.segment < normaliser->interfaces_nr)
+ ? normaliser->interfaces[reg.segment]
+ : NULL;
+
+ if (interfce) {
+ reg = interfce->find_canonic_address(interfce, reg);
+ reg_t_hash_map_check_value(normaliser->normal_map, reg, 1, NULL);
+ }
+}
+
+static reg_t_hash_map_ptr
+normalise_hashmap_ptrs(reg_t_hash_map_ptr nonnormal_map, seg_interface_t **interfaces, int interfaces_nr)
+{
+ normaliser_t normaliser;
+
+ normaliser.normal_map = new_reg_t_hash_map();
+ normaliser.interfaces_nr = interfaces_nr;
+ normaliser.interfaces = interfaces;
+ apply_to_reg_t_hash_map(nonnormal_map, &normaliser, &store_normalised);
+
+ return normaliser.normal_map;
+}
+
+
+typedef struct {
+ reg_t_hash_map_ptr nonnormal_map;
+ worklist_t **worklist_ref;
+} worklist_manager_t;
+
+void
+add_outgoing_refs(void *pre_wm, reg_t addr)
+{
+ worklist_manager_t *wm = (worklist_manager_t *) pre_wm;
+ worklist_push(wm->worklist_ref, wm->nonnormal_map, addr);
+}
+
+reg_t_hash_map_ptr
+find_all_used_references(state_t *s)
+{
+ seg_manager_t *sm = &(s->seg_manager);
+ seg_interface_t **interfaces = (seg_interface_t**)sci_calloc(sizeof(seg_interface_t *), sm->heap_size);
+ reg_t_hash_map_ptr nonnormal_map = new_reg_t_hash_map();
+ reg_t_hash_map_ptr normal_map = NULL;
+ worklist_t *worklist = new_worklist();
+ worklist_manager_t worklist_manager;
+ int i;
+
+ worklist_manager.worklist_ref = &worklist;
+ worklist_manager.nonnormal_map = nonnormal_map;
+
+ for (i = 1; i < sm->heap_size; i++)
+ if (sm->heap[i] == NULL)
+ interfaces[i] = NULL;
+ else
+ interfaces[i] = get_seg_interface(sm, i);
+
+ /* Initialise */
+ /* Init: Registers */
+ worklist_push(&worklist, nonnormal_map, s->r_acc);
+ worklist_push(&worklist, nonnormal_map, s->r_prev);
+ /* Init: Value Stack */
+ /* We do this one by hand since the stack doesn't know the current execution stack */
+ {
+ exec_stack_t *xs = s->execution_stack + s->execution_stack_pos;
+ reg_t *pos;
+
+ for (pos = s->stack_base; pos < xs->sp; pos++)
+ worklist_push(&worklist, nonnormal_map, *pos);
+ }
+#ifdef DEBUG_GC_VERBOSE
+ sciprintf("[GC] -- Finished adding value stack");
+#endif
+
+
+ /* Init: Execution Stack */
+ for (i = 0; i <= s->execution_stack_pos; i++) {
+ exec_stack_t *es = s->execution_stack + i;
+
+ if (es->type != EXEC_STACK_TYPE_KERNEL) {
+ worklist_push(&worklist, nonnormal_map, es->objp);
+ worklist_push(&worklist, nonnormal_map, es->sendp);
+ if (es->type == EXEC_STACK_TYPE_VARSELECTOR)
+ worklist_push(&worklist, nonnormal_map, *(es->addr.varp));
+ }
+ }
+#ifdef DEBUG_GC_VERBOSE
+ sciprintf("[GC] -- Finished adding execution stack");
+#endif
+
+ /* Init: Explicitly loaded scripts */
+ for (i = 1; i < sm->heap_size; i++)
+ if (interfaces[i]
+ && interfaces[i]->type_id == MEM_OBJ_SCRIPT) {
+ script_t *script = &(interfaces[i]->mobj->data.script);
+
+ if (script->lockers) { /* Explicitly loaded? */
+ int obj_nr;
+
+ /* Locals, if present */
+ worklist_push(&worklist, nonnormal_map, make_reg(script->locals_segment, 0));
+
+ /* All objects (may be classes, may be indirectly reachable) */
+ for (obj_nr = 0; obj_nr < script->objects_nr; obj_nr++) {
+ object_t *obj = script->objects + obj_nr;
+ worklist_push(&worklist,
+ nonnormal_map,
+ obj->pos);
+ }
+ }
+ }
+#ifdef DEBUG_GC_VERBOSE
+ sciprintf("[GC] -- Finished explicitly loaded scripts, done with root set");
+#endif
+
+
+ /* Run Worklist Algorithm */
+ while (worklist_has_next(worklist)) {
+ reg_t reg = worklist_pop(&worklist);
+ if (reg.segment != s->stack_segment) { /* No need to repeat this one */
+#ifdef DEBUG_GC_VERBOSE
+ sciprintf("[GC] Checking "PREG"\n", PRINT_REG(reg));
+#endif
+ if (reg.segment < sm->heap_size
+ && interfaces[reg.segment])
+ interfaces[reg.segment]->list_all_outgoing_references(interfaces[reg.segment],
+ s,
+ reg,
+ &worklist_manager,
+ add_outgoing_refs);
+ }
+ }
+
+ /* Normalise */
+ normal_map = normalise_hashmap_ptrs(nonnormal_map, interfaces, sm->heap_size);
+
+ /* Cleanup */
+ for (i = 1; i < sm->heap_size; i++)
+ if (interfaces[i])
+ interfaces[i]->deallocate_self(interfaces[i]);
+ sci_free(interfaces);
+ free_reg_t_hash_map(nonnormal_map);
+ return normal_map;
+}
+
+
+typedef struct {
+ seg_interface_t *interfce;
+#ifdef DEBUG_GC
+ char *segnames[MEM_OBJ_MAX + 1];
+ int segcount[MEM_OBJ_MAX + 1];
+#endif
+ reg_t_hash_map_ptr use_map;
+} deallocator_t;
+
+void
+free_unless_used (void *pre_use_map, reg_t addr)
+{
+ deallocator_t *deallocator = (deallocator_t *) pre_use_map;
+ reg_t_hash_map_ptr use_map = deallocator->use_map;
+
+ if (0 > reg_t_hash_map_check_value(use_map, addr, 0, NULL)) {
+ /* Not found -> we can free it */
+ deallocator->interfce->free_at_address(deallocator->interfce, addr);
+#ifdef DEBUG_GC
+ sciprintf("[GC] Deallocating "PREG"\n", PRINT_REG(addr));
+ deallocator->segcount[deallocator->interfce->type_id]++;
+#endif
+ }
+
+}
+
+void
+run_gc(state_t *s)
+{
+ int seg_nr;
+ deallocator_t deallocator;
+ seg_manager_t *sm = &(s->seg_manager);
+
+#ifdef DEBUG_GC
+ c_segtable(s);
+ sciprintf("[GC] Running...\n");
+ memset(&(deallocator.segcount), 0, sizeof(int) * (MEM_OBJ_MAX + 1));
+#endif
+
+ deallocator.use_map = find_all_used_references(s);
+
+ for (seg_nr = 1; seg_nr < sm->heap_size; seg_nr++)
+ if (sm->heap[seg_nr] != NULL) {
+ deallocator.interfce = get_seg_interface(sm, seg_nr);
+#ifdef DEBUG_GC
+ deallocator.segnames[deallocator.interfce->type_id] = deallocator.interfce->type;
+#endif
+
+ deallocator.interfce->list_all_deallocatable(deallocator.interfce,
+ &deallocator,
+ free_unless_used);
+
+ deallocator.interfce->deallocate_self(deallocator.interfce);
+ }
+
+ free_reg_t_hash_map(deallocator.use_map);
+
+#ifdef DEBUG_GC
+ {
+ int i;
+ sciprintf("[GC] Summary:\n");
+ for (i = 0; i <= MEM_OBJ_MAX; i++)
+ if (deallocator.segcount[i])
+ sciprintf("\t%d\t* %s\n",
+ deallocator.segcount[i],
+ deallocator.segnames[i]);
+ }
+#endif
+}
Deleted: scummvm/trunk/engines/sci/engine/grammar.c
===================================================================
--- scummvm/trunk/engines/sci/engine/grammar.c 2009-02-15 11:21:31 UTC (rev 38226)
+++ scummvm/trunk/engines/sci/engine/grammar.c 2009-02-15 11:39:07 UTC (rev 38227)
@@ -1,720 +0,0 @@
-/**************************************************************************
- grammar.c 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.
-
-***************************************************************************/
-
-/* Functionality to transform the context-free SCI grammar rules into
-** strict Greibach normal form (strict GNF), and to test SCI input against
-** that grammar, writing an appropriate node tree if successful.
-*/
-
-#include "sci/include/resource.h"
-#include "sci/include/vocabulary.h"
-#include "sci/include/console.h"
-#include <stdarg.h>
-#include <string.h>
-
-#define TOKEN_OPAREN 0xff000000
-#define TOKEN_CPAREN 0xfe000000
-#define TOKEN_TERMINAL_CLASS 0x10000
-#define TOKEN_TERMINAL_GROUP 0x20000
-#define TOKEN_STUFFING_WORD 0x40000
-#define TOKEN_NON_NT (TOKEN_OPAREN | TOKEN_TERMINAL_CLASS | TOKEN_TERMINAL_GROUP | TOKEN_STUFFING_WORD)
-#define TOKEN_TERMINAL (TOKEN_TERMINAL_CLASS | TOKEN_TERMINAL_GROUP)
-
- int _allocd_rules = 0;
-
-static void
-vocab_print_rule(parse_rule_t *rule)
-{
- int i;
- int wspace = 0;
-
- if (!rule) {
- sciprintf("NULL rule");
- return;
- }
-
- sciprintf("[%03x] -> ", rule->id);
-
- if (!rule->length)
- sciprintf("e");
-
- for(i = 0; i < rule->length; i++) {
- int token = rule->data[i];
-
- if (token == TOKEN_OPAREN) {
-
- if (i == rule->first_special)
- sciprintf("_");
-
- sciprintf("(");
- wspace = 0;
- } else if (token == TOKEN_CPAREN) {
-
- if (i == rule->first_special)
- sciprintf("_");
-
- sciprintf(")");
- wspace = 0;
- } else {
- if (wspace)
- sciprintf(" ");
-
- if (i == rule->first_special)
- sciprintf("_");
- if (token & TOKEN_TERMINAL_CLASS)
- sciprintf("C(%04x)", token & 0xffff);
- else if (token & TOKEN_TERMINAL_GROUP)
- sciprintf("G(%04x)", token & 0xffff);
- else if (token & TOKEN_STUFFING_WORD)
- sciprintf("%03x", token & 0xffff);
- else
- sciprintf("[%03x]", token); /* non-terminal */
- wspace = 1;
- }
-
- if (i == rule->first_special)
- sciprintf("_");
- }
- sciprintf(" [%d specials]", rule->specials_nr);
-}
-
-
-static void
-_vfree(parse_rule_t *rule)
-{
- free(rule);
- --_allocd_rules;
- rule = NULL;
-}
-
-static parse_rule_t *
-_vbuild(int id, int argc, ...)
-{
- va_list args;
- int i;
- parse_rule_t *rule = (parse_rule_t*)sci_malloc(sizeof(int) * (argc + 4));
-
- ++_allocd_rules;
- rule->id = id;
- rule->first_special = 0;
- rule->specials_nr = 0;
- rule->length = argc;
- va_start(args, argc);
- for (i = 0; i < argc; i++) {
- int v;
- rule->data[i] = v = va_arg(args, int);
- if ((v & TOKEN_TERMINAL)
- || !(v & TOKEN_NON_NT)) {
-
- ++rule->specials_nr;
-
- if (!rule->first_special)
- rule->first_special = i;
- }
- }
- va_end(args);
- return rule;
-}
-
-static parse_rule_t *
-_vcat(int id, parse_rule_t *a, parse_rule_t *b)
-{
- parse_rule_t *rule = (parse_rule_t*)sci_malloc(sizeof(int) * (a->length + b->length + 4));
-
- rule->id = id;
- rule->length = a->length + b->length;
- rule->specials_nr = a->specials_nr + b->specials_nr;
- rule->first_special = a->first_special;
- ++_allocd_rules;
-
- memcpy(rule->data, a->data, sizeof(int) * a->length);
- memcpy(&(rule->data[a->length]), b->data, sizeof(int) * b->length);
-
- return rule;
-}
-
-static parse_rule_t *
-_vdup(parse_rule_t *a)
-{
- parse_rule_t *rule = (parse_rule_t*)sci_malloc(sizeof(int) * (a->length + 4));
-
- rule->id = a->id;
- rule->length = a->length;
- rule->specials_nr = a->specials_nr;
- rule->first_special = a->first_special;
- ++_allocd_rules;
-
- memcpy(rule->data, a->data, sizeof(int) * a->length);
-
- return rule;
-}
-
-static parse_rule_t *
-_vinsert(parse_rule_t *turkey, parse_rule_t *stuffing)
-{
- int firstnt = turkey->first_special;
- parse_rule_t *rule;
-
- while ((firstnt < turkey->length)
- && (turkey->data[firstnt] & TOKEN_NON_NT))
- firstnt++;
-
- if ((firstnt == turkey->length)
- || (turkey->data[firstnt] != stuffing->id))
- return NULL;
-
- rule = (parse_rule_t*)sci_malloc(sizeof(int) * (turkey->length - 1 + stuffing->length + 4));
- rule->id = turkey->id;
- rule->specials_nr = turkey->specials_nr + stuffing->specials_nr - 1;
- rule->first_special = firstnt + stuffing->first_special;
- rule->length = turkey->length - 1 + stuffing->length;
- ++_allocd_rules;
-
- if (firstnt > 0)
- memcpy(rule->data, turkey->data, sizeof(int) * firstnt);
- memcpy(&(rule->data[firstnt]), stuffing->data, sizeof(int) * stuffing->length);
- if (firstnt < turkey->length - 1)
- memcpy(&(rule->data[firstnt + stuffing->length]), &(turkey->data[firstnt + 1]),
- sizeof(int) * (turkey->length - firstnt - 1));
-
- return rule;
-}
-
-
-static int
-_greibach_rule_p(parse_rule_t *rule)
-{
- int pos = rule->first_special;
- while (pos < rule->length
- && (rule->data[pos] & TOKEN_NON_NT)
- && !(rule->data[pos] & TOKEN_TERMINAL))
- ++pos;
-
- if (pos == rule->length)
- return 0;
-
- return (rule->data[pos] & TOKEN_TERMINAL);
-}
-
-static parse_rule_t *
-_vbuild_rule(parse_tree_branch_t *branch)
-{
- parse_rule_t *rule;
- int tokens = 0, tokenpos = 0, i;
-
- while (tokenpos < 10 && branch->data[tokenpos]) {
- int type = branch->data[tokenpos];
- tokenpos += 2;
-
- if ((type == VOCAB_TREE_NODE_COMPARE_TYPE)
- || (type == VOCAB_TREE_NODE_COMPARE_GROUP)
- || (type == VOCAB_TREE_NODE_FORCE_STORAGE))
- ++tokens;
- else if (type > VOCAB_TREE_NODE_LAST_WORD_STORAGE)
- tokens += 5;
- else return NULL; /* invalid */
- }
-
- rule = (parse_rule_t*)sci_malloc(sizeof(int) * (4 + tokens));
-
- ++_allocd_rules;
- rule->id = branch->id;
- rule->specials_nr = tokenpos >> 1;
- rule->length = tokens;
- rule->first_special = 0;
-
- tokens = 0;
- for (i = 0; i < tokenpos; i += 2) {
- int type = branch->data[i];
- int value = branch->data[i + 1];
-
- if (type == VOCAB_TREE_NODE_COMPARE_TYPE)
- rule->data[tokens++] = value | TOKEN_TERMINAL_CLASS;
- else if (type == VOCAB_TREE_NODE_COMPARE_GROUP)
- rule->data[tokens++] = value | TOKEN_TERMINAL_GROUP;
- else if (type == VOCAB_TREE_NODE_FORCE_STORAGE)
- rule->data[tokens++] = value | TOKEN_STUFFING_WORD;
- else { /* normal inductive rule */
- rule->data[tokens++] = TOKEN_OPAREN;
- rule->data[tokens++] = type | TOKEN_STUFFING_WORD;
- rule->data[tokens++] = value | TOKEN_STUFFING_WORD;
-
- if (i == 0)
- rule->first_special = tokens;
-
- rule->data[tokens++] = value; /* The non-terminal */
- rule->data[tokens++] = TOKEN_CPAREN;
- }
- }
-
- return rule;
-}
-
-
-static parse_rule_t *
-_vsatisfy_rule(parse_rule_t *rule, result_word_t *input)
-{
- int dep;
-
- if (!rule->specials_nr)
- return NULL;
-
- dep = rule->data[rule->first_special];
-
- if (((dep & TOKEN_TERMINAL_CLASS)
- && ((dep & 0xffff) & input->w_class))
- ||
- ((dep & TOKEN_TERMINAL_GROUP)
- && ((dep & 0xffff) & input->group))) {
- parse_rule_t *retval = (parse_rule_t*)sci_malloc(sizeof(int) * (4 + rule->length));
- ++_allocd_rules;
- retval->id = rule->id;
- retval->specials_nr = rule->specials_nr - 1;
- retval->length = rule->length;
- memcpy(retval->data, rule->data, sizeof(int) * retval->length);
- retval->data[rule->first_special] = TOKEN_STUFFING_WORD | input->group;
- retval->first_special = 0;
-
- if (retval->specials_nr) { /* find first special, if it exists */
- int tmp, i = rule->first_special;
-
- while ((i < rule->length)
- && ((tmp = retval->data[i]) & TOKEN_NON_NT)
- && !(tmp & TOKEN_TERMINAL))
- ++i;
-
- if (i < rule->length)
- retval->first_special = i;
- }
-
- return retval;
- }
- else return NULL;
-}
-
-/************** Rule lists **************/
-
-void
-vocab_free_rule_list(parse_rule_list_t *list)
-{
- if (list) {
- _vfree(list->rule);
- vocab_free_rule_list(list->next); /* Yep, this is slow and memory-intensive. */
- free(list);
- }
-}
-
-static inline int
-_rules_equal_p(parse_rule_t *r1, parse_rule_t *r2)
-{
- if ((r1->id != r2->id)
- || (r1->length != r2->length)
- || (r1->first_special != r2->first_special))
- return 0;
-
- return !(memcmp(r1->data, r2->data, sizeof(int) * r1->length));
-}
-
-static parse_rule_list_t *
-_vocab_add_rule(parse_rule_list_t *list, parse_rule_t *rule)
-{
- parse_rule_list_t *new_elem;
- int term;
-
- if (!rule)
- return list;
-
- new_elem = (parse_rule_list_t*)sci_malloc(sizeof(parse_rule_list_t));
- term = rule->data[rule->first_special];
-
- new_elem->rule = rule;
- new_elem->next = NULL;
- new_elem->terminal = term = ((term & TOKEN_TERMINAL)? term : 0);
-
- if (!list)
- return new_elem;
- else/* if (term < list->terminal) {
- new_elem->next = list;
- return new_elem;
- } else*/ {
- parse_rule_list_t *seeker = list;
-
- while (seeker->next/* && seeker->next->terminal <= term*/) {
- if (seeker->next->terminal == term)
- if (_rules_equal_p(seeker->next->rule, rule)) {
- _vfree(rule);
- free(new_elem);
- return list; /* No duplicate rules */
- }
- seeker = seeker->next;
- }
-
- new_elem->next = seeker->next;
- seeker->next = new_elem;
- return list;
- }
-}
-
-static void
-_vprl(parse_rule_list_t *list, int pos)
-{
- if (list) {
- sciprintf("R%03d: ", pos);
- vocab_print_rule(list->rule);
- sciprintf("\n");
- _vprl(list->next, pos+1);
- } else {
- sciprintf("%d rules total.\n", pos);
- }
-}
-
-void
-vocab_print_rule_list(parse_rule_list_t *list)
-{
- _vprl(list, 0);
-}
-
-static parse_rule_list_t *
-_vocab_split_rule_list(parse_rule_list_t *list)
-{
- if (!list->next
- || (list->next->terminal)) {
- parse_rule_list_t *tmp = list->next;
- list->next = NULL;
- return tmp;
- }
- else return _vocab_split_rule_list(list->next);
-}
-
-static void
-_vocab_free_empty_rule_list(parse_rule_list_t *list)
-{
- if (list->next)
- _vocab_free_empty_rule_list(list->next);
-
- free(list);
-}
-
-static parse_rule_list_t *
-_vocab_merge_rule_lists(parse_rule_list_t *l1, parse_rule_list_t *l2)
-{
- parse_rule_list_t *retval = l1, *seeker = l2;
- while (seeker) {
- retval = _vocab_add_rule(retval, seeker->rule);
- seeker = seeker->next;
- }
- _vocab_free_empty_rule_list(l2);
-
- return retval;
-}
-
-static int
-_vocab_rule_list_length(parse_rule_list_t *list)
-{
- return ((list)? _vocab_rule_list_length(list->next) + 1 : 0);
-}
-
-
-static parse_rule_list_t *
-_vocab_clone_rule_list_by_id(parse_rule_list_t *list, int id)
-{
- parse_rule_list_t *result = NULL;
- parse_rule_list_t *seeker = list;
-
- while (seeker) {
- if (seeker->rule->id == id) {
- result = _vocab_add_rule(result, _vdup(seeker->rule));
- }
- seeker = seeker->next;
- }
-
- return result;
-}
-
-
-parse_rule_list_t *
-_vocab_build_gnf(parse_tree_branch_t *branches, int branches_nr, int verbose)
-{
- int i;
- int iterations = 0;
- int last_termrules, termrules = 0;
- int ntrules_nr;
- parse_rule_list_t *ntlist = NULL;
- parse_rule_list_t *tlist, *new_tlist;
-
- for (i = 1; i < branches_nr; i++) { /* branch rule 0 is treated specially */
- parse_rule_t *rule = _vbuild_rule(branches + i);
-
- if (!rule) return NULL;
- ntlist = _vocab_add_rule(ntlist, rule);
- }
-
- tlist = _vocab_split_rule_list(ntlist);
- ntrules_nr = _vocab_rule_list_length(ntlist);
-
- if (verbose)
- sciprintf("Starting with %d rules\n", ntrules_nr);
-
- new_tlist = tlist;
- tlist = NULL;
-
- do {
- parse_rule_list_t *new_new_tlist = NULL;
- parse_rule_list_t *ntseeker, *tseeker;
- last_termrules = termrules;
-
- ntseeker = ntlist;
- while (ntseeker) {
- tseeker = new_tlist;
-
- while (tseeker) {
- parse_rule_t *newrule = _vinsert(ntseeker->rule, tseeker->rule);
- if (newrule)
- new_new_tlist = _vocab_add_rule(new_new_tlist, newrule);
- tseeker = tseeker->next;
- }
-
- ntseeker = ntseeker->next;
- }
-
- tlist = _vocab_merge_rule_lists(tlist, new_tlist);
-
- new_tlist = new_new_tlist;
-
- termrules = _vocab_rule_list_length(new_new_tlist);
-
- if (verbose)
- sciprintf("After iteration #%d: %d new term rules\n", ++iterations, termrules);
- } while (termrules && (iterations < 30));
-
- vocab_free_rule_list(ntlist);
-
- if (verbose) {
- sciprintf("\nGNF rules:\n");
- vocab_print_rule_list(tlist);
- }
-
- return tlist;
-}
-
-parse_rule_list_t *
-vocab_build_gnf(parse_tree_branch_t *branches, int branches_nr)
-{
- return _vocab_build_gnf(branches, branches_nr, 0);
-}
-
-
-void
-vocab_gnf_dump(parse_tree_branch_t *branches, int branches_nr)
-{
- parse_rule_list_t *tlist = _vocab_build_gnf(branches, branches_nr, 1);
-
- sciprintf("%d allocd rules\n", _allocd_rules);
- vocab_free_rule_list(tlist);
-}
-
-
-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)
-{
- return vocab_gnf_parse(nodes, words, words_nr, branch0, rules, 0);
-}
-
-
-static int
-_vbpt_pareno(parse_tree_node_t *nodes, int *pos, int base)
-/* Opens parentheses */
-{
- nodes[base].content.branches[0] = (*pos)+1;
- nodes[++(*pos)].type = PARSE_TREE_NODE_BRANCH;
- nodes[*pos].content.branches[0] = 0;
- nodes[*pos].content.branches[1] = 0;
- return *pos;
-}
-
-
-static int
-_vbpt_parenc(parse_tree_node_t *nodes, int *pos, int paren)
-/* Closes parentheses for appending */
-{
- nodes[paren].content.branches[1] = ++(*pos);
- nodes[*pos].type = PARSE_TREE_NODE_BRANCH;
- nodes[*pos].content.branches[0] = 0;
- nodes[*pos].content.branches[1] = 0;
- return *pos;
-}
-
-
-static int
-_vbpt_append(parse_tree_node_t *nodes, int *pos, int base, int value)
-/* writes one value to an existing base node and creates a successor node for writing */
-{
- nodes[base].content.branches[0] = ++(*pos);
- nodes[*pos].type = PARSE_TREE_NODE_LEAF;
- nodes[*pos].content.value = value;
- nodes[base].content.branches[1] = ++(*pos);
- nodes[*pos].type = PARSE_TREE_NODE_BRANCH;
- nodes[*pos].content.branches[0] = 0;
- nodes[*pos].content.branches[1] = 0;
- return *pos;
-}
-
-
-static int
-_vbpt_terminate(parse_tree_node_t *nodes, int *pos, int base, int value)
- /* Terminates, overwriting a nextwrite forknode */
-{
- nodes[base].type = PARSE_TREE_NODE_LEAF;
- nodes[base].content.value = value;
- return *pos;
-}
-
-static int
-_vbpt_write_subexpression(parse_tree_node_t *nodes, int *pos,
- parse_rule_t *rule, int rulepos, int writepos)
-{
- int token;
- while ((token = ((rulepos < rule->length)? rule->data[rulepos++] : TOKEN_CPAREN)) != TOKEN_CPAREN) {
- int nexttoken = (rulepos < rule->length)? rule->data[rulepos] : TOKEN_CPAREN;
- if (token == TOKEN_OPAREN) {
- int wpold;
- int writepos2 = _vbpt_pareno(nodes, pos, wpold = writepos);
- rulepos = _vbpt_write_subexpression(nodes, pos, rule, rulepos, writepos2);
- nexttoken = (rulepos < rule->length)? rule->data[rulepos] : TOKEN_CPAREN;
- if (nexttoken != TOKEN_CPAREN)
- writepos = _vbpt_parenc(nodes, pos, wpold);
- } else if (token & TOKEN_STUFFING_WORD) {
- if (nexttoken == TOKEN_CPAREN)
- writepos = _vbpt_terminate(nodes, pos, writepos, token & 0xffff);
- else
- writepos = _vbpt_append(nodes, pos, writepos, token & 0xffff);
- } else {
- sciprintf("\nError in parser (grammar.c, _vbpt_write_subexpression()): Rule data broken in rule ");
- vocab_print_rule(rule);
- sciprintf(", at token position %d\n", *pos);
- return rulepos;
- }
- }
-
- return rulepos;
-}
-
-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)
-{
- /* Get the start rules: */
- parse_rule_list_t *work = _vocab_clone_rule_list_by_id(tlist, branch0->data[1]);
- parse_rule_list_t *results = NULL;
- int word;
-
- for (word = 0; word < words_nr; word++) {
- parse_rule_list_t *new_work = NULL;
- parse_rule_list_t *reduced_rules = NULL;
- parse_rule_list_t *seeker, *subseeker;
-
- if (verbose)
- sciprintf("Adding word %d...\n", word);
-
- seeker = work;
- while (seeker) {
-
- if (seeker->rule->specials_nr <= (words_nr - word))
- reduced_rules = _vocab_add_rule(reduced_rules, _vsatisfy_rule(seeker->rule, words + word));
-
- seeker = seeker->next;
- }
-
- if (reduced_rules == NULL) {
- vocab_free_rule_list(work);
- if (verbose)
- sciprintf("No results.\n");
- return 1;
- }
-
- vocab_free_rule_list(work);
-
- if (word +1 < words_nr) {
- seeker = reduced_rules;
-
- while (seeker) {
- if (seeker->rule->specials_nr) {
- int my_id = seeker->rule->data[seeker->rule->first_special];
-
- subseeker = tlist;
- while (subseeker) {
- if (subseeker->rule->id == my_id)
- new_work = _vocab_add_rule(new_work, _vinsert(seeker->rule, subseeker->rule));
-
- subseeker = subseeker->next;
- }
- }
-
- seeker = seeker->next;
- }
- vocab_free_rule_list(reduced_rules);
- } else /* last word */
- new_work = reduced_rules;
-
- work = new_work;
- if (verbose)
- sciprintf("Now at %d candidates\n", _vocab_rule_list_length(work));
- if (work == NULL) {
- if (verbose)
- sciprintf("No results.\n");
- return 1;
- }
- }
-
- results = work;
-
- if (verbose) {
- sciprintf("All results (excluding the surrounding '(141 %03x' and ')'):\n",
- branch0->id);
- vocab_print_rule_list(results);
- sciprintf("\n");
- }
-
- /* now use the first result */
- {
- int temp, pos;
-
- nodes[0].type = PARSE_TREE_NODE_BRANCH;
- nodes[0].content.branches[0] = 1;
- nodes[0].content.branches[1] = 2;
-
- nodes[1].type = PARSE_TREE_NODE_LEAF;
- nodes[1].content.value = 0x141;
-
- nodes[2].type = PARSE_TREE_NODE_BRANCH;
- nodes[2].content.branches[0] = 0;
- nodes[2].content.branches[1] = 0;
-
- pos = 2;
-
- temp = _vbpt_append(nodes, &pos, 2, branch0->id);
- /* _vbpt_write_subexpression(nodes, &pos, results[_vocab_rule_list_length(results)].rule, 0, temp); */
- _vbpt_write_subexpression(nodes, &pos, results->rule, 0, temp);
- }
-
- vocab_free_rule_list(results);
- return 0;
-}
Copied: scummvm/trunk/engines/sci/engine/grammar.cpp (from rev 38224, scummvm/trunk/engines/sci/engine/grammar.c)
===================================================================
--- scummvm/trunk/engines/sci/engine/grammar.cpp (rev 0)
+++ scummvm/trunk/engines/sci/engine/grammar.cpp 2009-02-15 11:39:07 UTC (rev 38227)
@@ -0,0 +1,720 @@
+/**************************************************************************
+ grammar.c 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.
+
+***************************************************************************/
+
+/* Functionality to transform the context-free SCI grammar rules into
+** strict Greibach normal form (strict GNF), and to test SCI input against
+** that grammar, writing an appropriate node tree if successful.
+*/
+
+#include "sci/include/resource.h"
+#include "sci/include/vocabulary.h"
+#include "sci/include/console.h"
+#include <stdarg.h>
+#include <string.h>
+
+#define TOKEN_OPAREN 0xff000000
+#define TOKEN_CPAREN 0xfe000000
+#define TOKEN_TERMINAL_CLASS 0x10000
+#define TOKEN_TERMINAL_GROUP 0x20000
+#define TOKEN_STUFFING_WORD 0x40000
+#define TOKEN_NON_NT (TOKEN_OPAREN | TOKEN_TERMINAL_CLASS | TOKEN_TERMINAL_GROUP | TOKEN_STUFFING_WORD)
+#define TOKEN_TERMINAL (TOKEN_TERMINAL_CLASS | TOKEN_TERMINAL_GROUP)
+
+ int _allocd_rules = 0;
+
+static void
+vocab_print_rule(parse_rule_t *rule)
+{
+ int i;
+ int wspace = 0;
+
+ if (!rule) {
+ sciprintf("NULL rule");
+ return;
+ }
+
+ sciprintf("[%03x] -> ", rule->id);
+
+ if (!rule->length)
+ sciprintf("e");
+
+ for(i = 0; i < rule->length; i++) {
+ int token = rule->data[i];
+
+ if (token == TOKEN_OPAREN) {
+
+ if (i == rule->first_special)
+ sciprintf("_");
+
+ sciprintf("(");
+ wspace = 0;
+ } else if (token == TOKEN_CPAREN) {
+
+ if (i == rule->first_special)
+ sciprintf("_");
+
+ sciprintf(")");
+ wspace = 0;
+ } else {
+ if (wspace)
+ sciprintf(" ");
+
+ if (i == rule->first_special)
+ sciprintf("_");
+ if (token & TOKEN_TERMINAL_CLASS)
+ sciprintf("C(%04x)", token & 0xffff);
+ else if (token & TOKEN_TERMINAL_GROUP)
+ sciprintf("G(%04x)", token & 0xffff);
+ else if (token & TOKEN_STUFFING_WORD)
+ sciprintf("%03x", token & 0xffff);
+ else
+ sciprintf("[%03x]", token); /* non-terminal */
+ wspace = 1;
+ }
+
+ if (i == rule->first_special)
+ sciprintf("_");
+ }
+ sciprintf(" [%d specials]", rule->specials_nr);
+}
+
+
+static void
+_vfree(parse_rule_t *rule)
+{
+ free(rule);
+ --_allocd_rules;
+ rule = NULL;
+}
+
+static parse_rule_t *
+_vbuild(int id, int argc, ...)
+{
+ va_list args;
+ int i;
+ parse_rule_t *rule = (parse_rule_t*)sci_malloc(sizeof(int) * (argc + 4));
+
+ ++_allocd_rules;
+ rule->id = id;
+ rule->first_special = 0;
+ rule->specials_nr = 0;
+ rule->length = argc;
+ va_start(args, argc);
+ for (i = 0; i < argc; i++) {
+ int v;
+ rule->data[i] = v = va_arg(args, int);
+ if ((v & TOKEN_TERMINAL)
+ || !(v & TOKEN_NON_NT)) {
+
+ ++rule->specials_nr;
+
+ if (!rule->first_special)
+ rule->first_special = i;
+ }
+ }
+ va_end(args);
+ return rule;
+}
+
+static parse_rule_t *
+_vcat(int id, parse_rule_t *a, parse_rule_t *b)
+{
+ parse_rule_t *rule = (parse_rule_t*)sci_malloc(sizeof(int) * (a->length + b->length + 4));
+
+ rule->id = id;
+ rule->length = a->length + b->length;
+ rule->specials_nr = a->specials_nr + b->specials_nr;
+ rule->first_special = a->first_special;
+ ++_allocd_rules;
+
+ memcpy(rule->data, a->data, sizeof(int) * a->length);
+ memcpy(&(rule->data[a->length]), b->data, sizeof(int) * b->length);
+
+ return rule;
+}
+
+static parse_rule_t *
+_vdup(parse_rule_t *a)
+{
+ parse_rule_t *rule = (parse_rule_t*)sci_malloc(sizeof(int) * (a->length + 4));
+
+ rule->id = a->id;
+ rule->length = a->length;
+ rule->specials_nr = a->specials_nr;
+ rule->first_special = a->first_special;
+ ++_allocd_rules;
+
+ memcpy(rule->data, a->data, sizeof(int) * a->length);
+
+ return rule;
+}
+
+static parse_rule_t *
+_vinsert(parse_rule_t *turkey, parse_rule_t *stuffing)
+{
+ int firstnt = turkey->first_special;
+ parse_rule_t *rule;
+
+ while ((firstnt < turkey->length)
+ && (turkey->data[firstnt] & TOKEN_NON_NT))
+ firstnt++;
+
+ if ((firstnt == turkey->length)
+ || (turkey->data[firstnt] != stuffing->id))
+ return NULL;
+
+ rule = (parse_rule_t*)sci_malloc(sizeof(int) * (turkey->length - 1 + stuffing->length + 4));
+ rule->id = turkey->id;
+ rule->specials_nr = turkey->specials_nr + stuffing->specials_nr - 1;
+ rule->first_special = firstnt + stuffing->first_special;
+ rule->length = turkey->length - 1 + stuffing->length;
+ ++_allocd_rules;
+
+ if (firstnt > 0)
+ memcpy(rule->data, turkey->data, sizeof(int) * firstnt);
+ memcpy(&(rule->data[firstnt]), stuffing->data, sizeof(int) * stuffing->length);
+ if (firstnt < turkey->length - 1)
+ memcpy(&(rule->data[firstnt + stuffing->length]), &(turkey->data[firstnt + 1]),
+ sizeof(int) * (turkey->length - firstnt - 1));
+
+ return rule;
+}
+
+
+static int
+_greibach_rule_p(parse_rule_t *rule)
+{
+ int pos = rule->first_special;
+ while (pos < rule->length
+ && (rule->data[pos] & TOKEN_NON_NT)
+ && !(rule->data[pos] & TOKEN_TERMINAL))
+ ++pos;
+
+ if (pos == rule->length)
+ return 0;
+
+ return (rule->data[pos] & TOKEN_TERMINAL);
+}
+
+static parse_rule_t *
+_vbuild_rule(parse_tree_branch_t *branch)
+{
+ parse_rule_t *rule;
+ int tokens = 0, tokenpos = 0, i;
+
+ while (tokenpos < 10 && branch->data[tokenpos]) {
+ int type = branch->data[tokenpos];
+ tokenpos += 2;
+
+ if ((type == VOCAB_TREE_NODE_COMPARE_TYPE)
+ || (type == VOCAB_TREE_NODE_COMPARE_GROUP)
+ || (type == VOCAB_TREE_NODE_FORCE_STORAGE))
+ ++tokens;
+ else if (type > VOCAB_TREE_NODE_LAST_WORD_STORAGE)
+ tokens += 5;
+ else return NULL; /* invalid */
+ }
+
+ rule = (parse_rule_t*)sci_malloc(sizeof(int) * (4 + tokens));
+
+ ++_allocd_rules;
+ rule->id = branch->id;
+ rule->specials_nr = tokenpos >> 1;
+ rule->length = tokens;
+ rule->first_special = 0;
+
+ tokens = 0;
+ for (i = 0; i < tokenpos; i += 2) {
+ int type = branch->data[i];
+ int value = branch->data[i + 1];
+
+ if (type == VOCAB_TREE_NODE_COMPARE_TYPE)
+ rule->data[tokens++] = value | TOKEN_TERMINAL_CLASS;
+ else if (type == VOCAB_TREE_NODE_COMPARE_GROUP)
+ rule->data[tokens++] = value | TOKEN_TERMINAL_GROUP;
+ else if (type == VOCAB_TREE_NODE_FORCE_STORAGE)
+ rule->data[tokens++] = value | TOKEN_STUFFING_WORD;
+ else { /* normal inductive rule */
+ rule->data[tokens++] = TOKEN_OPAREN;
+ rule->data[tokens++] = type | TOKEN_STUFFING_WORD;
+ rule->data[tokens++] = value | TOKEN_STUFFING_WORD;
+
+ if (i == 0)
+ rule->first_special = tokens;
+
+ rule->data[tokens++] = value; /* The non-terminal */
+ rule->data[tokens++] = TOKEN_CPAREN;
+ }
+ }
+
+ return rule;
+}
+
+
+static parse_rule_t *
+_vsatisfy_rule(parse_rule_t *rule, result_word_t *input)
+{
+ int dep;
+
+ if (!rule->specials_nr)
+ return NULL;
+
+ dep = rule->data[rule->first_special];
+
+ if (((dep & TOKEN_TERMINAL_CLASS)
+ && ((dep & 0xffff) & input->w_class))
+ ||
+ ((dep & TOKEN_TERMINAL_GROUP)
+ && ((dep & 0xffff) & input->group))) {
+ parse_rule_t *retval = (parse_rule_t*)sci_malloc(sizeof(int) * (4 + rule->length));
+ ++_allocd_rules;
+ retval->id = rule->id;
+ retval->specials_nr = rule->specials_nr - 1;
+ retval->length = rule->length;
+ memcpy(retval->data, rule->data, sizeof(int) * retval->length);
+ retval->data[rule->first_special] = TOKEN_STUFFING_WORD | input->group;
+ retval->first_special = 0;
+
+ if (retval->specials_nr) { /* find first special, if it exists */
+ int tmp, i = rule->first_special;
+
+ while ((i < rule->length)
+ && ((tmp = retval->data[i]) & TOKEN_NON_NT)
+ && !(tmp & TOKEN_TERMINAL))
+ ++i;
+
+ if (i < rule->length)
+ retval->first_special = i;
+ }
+
+ return retval;
+ }
+ else return NULL;
+}
+
+/************** Rule lists **************/
+
+void
+vocab_free_rule_list(parse_rule_list_t *list)
+{
+ if (list) {
+ _vfree(list->rule);
+ vocab_free_rule_list(list->next); /* Yep, this is slow and memory-intensive. */
+ free(list);
+ }
+}
+
+static inline int
+_rules_equal_p(parse_rule_t *r1, parse_rule_t *r2)
+{
+ if ((r1->id != r2->id)
+ || (r1->length != r2->length)
+ || (r1->first_special != r2->first_special))
+ return 0;
+
+ return !(memcmp(r1->data, r2->data, sizeof(int) * r1->length));
+}
+
+static parse_rule_list_t *
+_vocab_add_rule(parse_rule_list_t *list, parse_rule_t *rule)
+{
+ parse_rule_list_t *new_elem;
+ int term;
+
+ if (!rule)
+ return list;
+
+ new_elem = (parse_rule_list_t*)sci_malloc(sizeof(parse_rule_list_t));
+ term = rule->data[rule->first_special];
+
+ new_elem->rule = rule;
+ new_elem->next = NULL;
+ new_elem->terminal = term = ((term & TOKEN_TERMINAL)? term : 0);
+
+ if (!list)
+ return new_elem;
+ else/* if (term < list->terminal) {
+ new_elem->next = list;
+ return new_elem;
+ } else*/ {
+ parse_rule_list_t *seeker = list;
+
+ while (seeker->next/* && seeker->next->terminal <= term*/) {
+ if (seeker->next->terminal == term)
+ if (_rules_equal_p(seeker->next->rule, rule)) {
+ _vfree(rule);
+ free(new_elem);
+ return list; /* No duplicate rules */
+ }
+ seeker = seeker->next;
+ }
+
+ new_elem->next = seeker->next;
+ seeker->next = new_elem;
+ return list;
+ }
+}
+
+static void
+_vprl(parse_rule_list_t *list, int pos)
+{
+ if (list) {
+ sciprintf("R%03d: ", pos);
+ vocab_print_rule(list->rule);
+ sciprintf("\n");
+ _vprl(list->next, pos+1);
+ } else {
+ sciprintf("%d rules total.\n", pos);
+ }
+}
+
+void
+vocab_print_rule_list(parse_rule_list_t *list)
+{
+ _vprl(list, 0);
+}
+
+static parse_rule_list_t *
+_vocab_split_rule_list(parse_rule_list_t *list)
+{
+ if (!list->next
+ || (list->next->terminal)) {
+ parse_rule_list_t *tmp = list->next;
+ list->next = NULL;
+ return tmp;
+ }
+ else return _vocab_split_rule_list(list->next);
+}
+
+static void
+_vocab_free_empty_rule_list(parse_rule_list_t *list)
+{
+ if (list->next)
+ _vocab_free_empty_rule_list(list->next);
+
+ free(list);
+}
+
+static parse_rule_list_t *
+_vocab_merge_rule_lists(parse_rule_list_t *l1, parse_rule_list_t *l2)
+{
+ parse_rule_list_t *retval = l1, *seeker = l2;
+ while (seeker) {
+ retval = _vocab_add_rule(retval, seeker->rule);
+ seeker = seeker->next;
+ }
+ _vocab_free_empty_rule_list(l2);
+
+ return retval;
+}
+
+static int
+_vocab_rule_list_length(parse_rule_list_t *list)
+{
+ return ((list)? _vocab_rule_list_length(list->next) + 1 : 0);
+}
+
+
+static parse_rule_list_t *
+_vocab_clone_rule_list_by_id(parse_rule_list_t *list, int id)
+{
+ parse_rule_list_t *result = NULL;
+ parse_rule_list_t *seeker = list;
+
+ while (seeker) {
+ if (seeker->rule->id == id) {
+ result = _vocab_add_rule(result, _vdup(seeker->rule));
+ }
+ seeker = seeker->next;
+ }
+
+ return result;
+}
+
+
+parse_rule_list_t *
+_vocab_build_gnf(parse_tree_branch_t *branches, int branches_nr, int verbose)
+{
+ int i;
+ int iterations = 0;
+ int last_termrules, termrules = 0;
+ int ntrules_nr;
+ parse_rule_list_t *ntlist = NULL;
+ parse_rule_list_t *tlist, *new_tlist;
+
+ for (i = 1; i < branches_nr; i++) { /* branch rule 0 is treated specially */
+ parse_rule_t *rule = _vbuild_rule(branches + i);
+
+ if (!rule) return NULL;
+ ntlist = _vocab_add_rule(ntlist, rule);
+ }
+
+ tlist = _vocab_split_rule_list(ntlist);
+ ntrules_nr = _vocab_rule_list_length(ntlist);
+
+ if (verbose)
+ sciprintf("Starting with %d rules\n", ntrules_nr);
+
+ new_tlist = tlist;
+ tlist = NULL;
+
+ do {
+ parse_rule_list_t *new_new_tlist = NULL;
+ parse_rule_list_t *ntseeker, *tseeker;
+ last_termrules = termrules;
+
+ ntseeker = ntlist;
+ while (ntseeker) {
+ tseeker = new_tlist;
+
+ while (tseeker) {
+ parse_rule_t *newrule = _vinsert(ntseeker->rule, tseeker->rule);
+ if (newrule)
+ new_new_tlist = _vocab_add_rule(new_new_tlist, newrule);
+ tseeker = tseeker->next;
+ }
+
+ ntseeker = ntseeker->next;
+ }
+
+ tlist = _vocab_merge_rule_lists(tlist, new_tlist);
+
+ new_tlist = new_new_tlist;
+
+ termrules = _vocab_rule_list_length(new_new_tlist);
+
+ if (verbose)
+ sciprintf("After iteration #%d: %d new term rules\n", ++iterations, termrules);
+ } while (termrules && (iterations < 30));
+
+ vocab_free_rule_list(ntlist);
+
+ if (verbose) {
+ sciprintf("\nGNF rules:\n");
+ vocab_print_rule_list(tlist);
+ }
+
+ return tlist;
+}
+
+parse_rule_list_t *
+vocab_build_gnf(parse_tree_branch_t *branches, int branches_nr)
+{
+ return _vocab_build_gnf(branches, branches_nr, 0);
+}
+
+
+void
+vocab_gnf_dump(parse_tree_branch_t *branches, int branches_nr)
+{
+ parse_rule_list_t *tlist = _vocab_build_gnf(branches, branches_nr, 1);
+
+ sciprintf("%d allocd rules\n", _allocd_rules);
+ vocab_free_rule_list(tlist);
+}
+
+
+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)
+{
+ return vocab_gnf_parse(nodes, words, words_nr, branch0, rules, 0);
+}
+
+
+static int
+_vbpt_pareno(parse_tree_node_t *nodes, int *pos, int base)
+/* Opens parentheses */
+{
+ nodes[base].content.branches[0] = (*pos)+1;
+ nodes[++(*pos)].type = PARSE_TREE_NODE_BRANCH;
+ nodes[*pos].content.branches[0] = 0;
+ nodes[*pos].content.branches[1] = 0;
+ return *pos;
+}
+
+
+static int
+_vbpt_parenc(parse_tree_node_t *nodes, int *pos, int paren)
+/* Closes parentheses for appending */
+{
+ nodes[paren].content.branches[1] = ++(*pos);
+ nodes[*pos].type = PARSE_TREE_NODE_BRANCH;
+ nodes[*pos].content.branches[0] = 0;
+ nodes[*pos].content.branches[1] = 0;
+ return *pos;
+}
+
+
+static int
+_vbpt_append(parse_tree_node_t *nodes, int *pos, int base, int value)
+/* writes one value to an existing base node and creates a successor node for writing */
+{
+ nodes[base].content.branches[0] = ++(*pos);
+ nodes[*pos].type = PARSE_TREE_NODE_LEAF;
+ nodes[*pos].content.value = value;
+ nodes[base].content.branches[1] = ++(*pos);
+ nodes[*pos].type = PARSE_TREE_NODE_BRANCH;
+ nodes[*pos].content.branches[0] = 0;
+ nodes[*pos].content.branches[1] = 0;
+ return *pos;
+}
+
+
+static int
+_vbpt_terminate(parse_tree_node_t *nodes, int *pos, int base, int value)
+ /* Terminates, overwriting a nextwrite forknode */
+{
+ nodes[base].type = PARSE_TREE_NODE_LEAF;
+ nodes[base].content.value = value;
+ return *pos;
+}
+
+static int
+_vbpt_write_subexpression(parse_tree_node_t *nodes, int *pos,
+ parse_rule_t *rule, int rulepos, int writepos)
+{
+ int token;
+ while ((token = ((rulepos < rule->length)? rule->data[rulepos++] : TOKEN_CPAREN)) != TOKEN_CPAREN) {
+ int nexttoken = (rulepos < rule->length)? rule->data[rulepos] : TOKEN_CPAREN;
+ if (token == TOKEN_OPAREN) {
+ int wpold;
+ int writepos2 = _vbpt_pareno(nodes, pos, wpold = writepos);
+ rulepos = _vbpt_write_subexpression(nodes, pos, rule, rulepos, writepos2);
+ nexttoken = (rulepos < rule->length)? rule->data[rulepos] : TOKEN_CPAREN;
+ if (nexttoken != TOKEN_CPAREN)
+ writepos = _vbpt_parenc(nodes, pos, wpold);
+ } else if (token & TOKEN_STUFFING_WORD) {
+ if (nexttoken == TOKEN_CPAREN)
+ writepos = _vbpt_terminate(nodes, pos, writepos, token & 0xffff);
+ else
+ writepos = _vbpt_append(nodes, pos, writepos, token & 0xffff);
+ } else {
+ sciprintf("\nError in parser (grammar.c, _vbpt_write_subexpression()): Rule data broken in rule ");
+ vocab_print_rule(rule);
+ sciprintf(", at token position %d\n", *pos);
+ return rulepos;
+ }
+ }
+
+ return rulepos;
+}
+
+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)
+{
+ /* Get the start rules: */
+ parse_rule_list_t *work = _vocab_clone_rule_list_by_id(tlist, branch0->data[1]);
+ parse_rule_list_t *results = NULL;
+ int word;
+
+ for (word = 0; word < words_nr; word++) {
+ parse_rule_list_t *new_work = NULL;
+ parse_rule_list_t *reduced_rules = NULL;
+ parse_rule_list_t *seeker, *subseeker;
+
+ if (verbose)
+ sciprintf("Adding word %d...\n", word);
+
+ seeker = work;
+ while (seeker) {
+
+ if (seeker->rule->specials_nr <= (words_nr - word))
+ reduced_rules = _vocab_add_rule(reduced_rules, _vsatisfy_rule(seeker->rule, words + word));
+
+ seeker = seeker->next;
+ }
+
+ if (reduced_rules == NULL) {
+ vocab_free_rule_list(work);
+ if (verbose)
+ sciprintf("No results.\n");
+ return 1;
+ }
+
+ vocab_free_rule_list(work);
+
+ if (word +1 < words_nr) {
+ seeker = reduced_rules;
+
+ while (seeker) {
+ if (seeker->rule->specials_nr) {
+ int my_id = seeker->rule->data[seeker->rule->first_special];
+
+ subseeker = tlist;
+ while (subseeker) {
+ if (subseeker->rule->id == my_id)
+ new_work = _vocab_add_rule(new_work, _vinsert(seeker->rule, subseeker->rule));
+
+ subseeker = subseeker->next;
+ }
+ }
+
+ seeker = seeker->next;
+ }
+ vocab_free_rule_list(reduced_rules);
+ } else /* last word */
+ new_work = reduced_rules;
+
+ work = new_work;
+ if (verbose)
+ sciprintf("Now at %d candidates\n", _vocab_rule_list_length(work));
+ if (work == NULL) {
+ if (verbose)
+ sciprintf("No results.\n");
+ return 1;
+ }
+ }
+
+ results = work;
+
+ if (verbose) {
+ sciprintf("All results (excluding the surrounding '(141 %03x' and ')'):\n",
+ branch0->id);
+ vocab_print_rule_list(results);
+ sciprintf("\n");
+ }
+
+ /* now use the first result */
+ {
+ int temp, pos;
+
+ nodes[0].type = PARSE_TREE_NODE_BRANCH;
+ nodes[0].content.branches[0] = 1;
+ nodes[0].content.branches[1] = 2;
+
+ nodes[1].type = PARSE_TREE_NODE_LEAF;
+ nodes[1].content.value = 0x141;
+
+ nodes[2].type = PARSE_TREE_NODE_BRANCH;
+ nodes[2].content.branches[0] = 0;
+ nodes[2].content.branches[1] = 0;
+
+ pos = 2;
+
+ temp = _vbpt_append(nodes, &pos, 2, branch0->id);
+ /* _vbpt_write_subexpression(nodes, &pos, results[_vocab_rule_list_length(results)].rule, 0, temp); */
+ _vbpt_write_subexpression(nodes, &pos, results->rule, 0, temp);
+ }
+
+ vocab_free_rule_list(results);
+ return 0;
+}
Deleted: scummvm/trunk/engines/sci/engine/heap.c
===================================================================
--- scummvm/trunk/engines/sci/engine/heap.c 2009-02-15 11:21:31 UTC (rev 38226)
+++ scummvm/trunk/engines/sci/engine/heap.c 2009-02-15 11:39:07 UTC (rev 38227)
@@ -1,298 +0,0 @@
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "sci/include/engine.h"
-#include "sci/include/console.h"
-#include "sci/engine/heap.h"
-
-#define assert_in_range(pos) assert(pos>=1000 && pos<=0xffff)
-
-static void set_size(heap_t *h, int block_pos, int size)
-{
- assert_in_range(block_pos);
- assert(size<=0xffff-1000);
- putInt16(h->start+block_pos, size);
-}
-
-static void set_next(heap_t* h, int block_pos, int next)
-{
- assert_in_range(block_pos);
- assert_in_range(next);
- putInt16(h->start+block_pos+2, next);
-}
-
-
-static unsigned int get_size(heap_t* h, int block_pos)
-{
- assert_in_range(block_pos);
- return (guint16)getInt16(h->start+block_pos);
-}
-
-static unsigned int get_next(heap_t* h, int block_pos)
-{
- assert_in_range(block_pos);
- return (guint16)getInt16(h->start+block_pos+2);
-}
-
-/*Allocates a new heap*/
-heap_t* heap_new()
-{
- heap_t* h;
- if((h= (heap_t*)sci_malloc(sizeof(heap_t)))==0) return 0;
-
- if((h->start= sci_calloc(SCI_HEAP_SIZE, 1))==0)
- {
- free(h);
- return 0;
- }
-
- h->base=h->start+1000;
- h->first_free=1000;
- h->old_ff=-1;
- set_size(h, 1000, 0xffff-1000);
- set_next(h, 1000, 0xffff);
-
- return h;
-}
-
-/*Deletes a heap*/
-void heap_del(heap_t* h)
-{
- free(h->start);
- free(h);
-}
-
-
-int heap_meminfo(heap_t* h)
-{
- heap_ptr current = h->first_free;
- int total = 0;
-
- while (current != 0xffff) {
- total += get_size(h, current);
- current = get_next(h, current);
- }
-
- return total;
-}
-
-
-int heap_largest(heap_t* h)
-{
@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list