[Scummvm-cvs-logs] SF.net SVN: scummvm: [20536] scummvm/trunk

kirben at users.sourceforge.net kirben at users.sourceforge.net
Sat Feb 11 04:58:00 CET 2006


Revision: 20536
Author:   kirben
Date:     2006-02-11 04:54:56 -0800 (Sat, 11 Feb 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm?rev=20536&view=rev

Log Message:
-----------
Add patch #1374870 - New Lure of the Temptress module

Modified Paths:
--------------
    scummvm/trunk/Makefile.common
    scummvm/trunk/base/plugins.cpp
    scummvm/trunk/configure

Added Paths:
-----------
    scummvm/trunk/lure/
    scummvm/trunk/lure/animseq.cpp
    scummvm/trunk/lure/animseq.h
    scummvm/trunk/lure/debug-input.cpp
    scummvm/trunk/lure/debug-input.h
    scummvm/trunk/lure/debug-methods.cpp
    scummvm/trunk/lure/debug-methods.h
    scummvm/trunk/lure/decode.cpp
    scummvm/trunk/lure/decode.h
    scummvm/trunk/lure/disk.cpp
    scummvm/trunk/lure/disk.h
    scummvm/trunk/lure/events.cpp
    scummvm/trunk/lure/events.h
    scummvm/trunk/lure/game.cpp
    scummvm/trunk/lure/game.h
    scummvm/trunk/lure/hotspots.cpp
    scummvm/trunk/lure/hotspots.h
    scummvm/trunk/lure/intro.cpp
    scummvm/trunk/lure/intro.h
    scummvm/trunk/lure/lure.cpp
    scummvm/trunk/lure/lure.h
    scummvm/trunk/lure/luredefs.h
    scummvm/trunk/lure/memory.cpp
    scummvm/trunk/lure/memory.h
    scummvm/trunk/lure/menu.cpp
    scummvm/trunk/lure/menu.h
    scummvm/trunk/lure/module.mk
    scummvm/trunk/lure/palette.cpp
    scummvm/trunk/lure/palette.h
    scummvm/trunk/lure/res.cpp
    scummvm/trunk/lure/res.h
    scummvm/trunk/lure/res_struct.cpp
    scummvm/trunk/lure/res_struct.h
    scummvm/trunk/lure/room.cpp
    scummvm/trunk/lure/room.h
    scummvm/trunk/lure/screen.cpp
    scummvm/trunk/lure/screen.h
    scummvm/trunk/lure/scripts.cpp
    scummvm/trunk/lure/scripts.h
    scummvm/trunk/lure/strings.cpp
    scummvm/trunk/lure/strings.h
    scummvm/trunk/lure/surface.cpp
    scummvm/trunk/lure/surface.h
    scummvm/trunk/lure/system.cpp
    scummvm/trunk/lure/system.h
Modified: scummvm/trunk/Makefile.common
===================================================================
--- scummvm/trunk/Makefile.common	2006-02-11 12:47:47 UTC (rev 20535)
+++ scummvm/trunk/Makefile.common	2006-02-11 12:54:56 UTC (rev 20536)
@@ -96,6 +96,12 @@
 MODULES += gob
 endif
 
+ifdef DISABLE_LURE
+DEFINES += -DDISABLE_LURE
+else
+MODULES += lure
+endif
+
 # After the game specific modules follow the shared modules
 MODULES += \
 	gui \

Modified: scummvm/trunk/base/plugins.cpp
===================================================================
--- scummvm/trunk/base/plugins.cpp	2006-02-11 12:47:47 UTC (rev 20535)
+++ scummvm/trunk/base/plugins.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -329,6 +329,9 @@
 	#ifndef DISABLE_GOB
 	LINK_PLUGIN(GOB)
 	#endif
+	#ifndef DISABLE_LURE
+	LINK_PLUGIN(LURE)
+	#endif
 
 #endif
 }

Modified: scummvm/trunk/configure
===================================================================
--- scummvm/trunk/configure	2006-02-11 12:47:47 UTC (rev 20535)
+++ scummvm/trunk/configure	2006-02-11 12:54:56 UTC (rev 20536)
@@ -56,6 +56,7 @@
 _build_saga=yes
 _build_gob=yes
 _build_kyra=yes
+_build_lure=yes
 _need_memalign=no
 _build_plugins=no
 _nasm=auto
@@ -301,6 +302,7 @@
   --disable-saga           don't build the SAGA engine
   --disable-gob            don't build the Gobli*ns engine
   --disable-kyra           don't build the Legend of Kyrandia engine
+  --disable-lure           don't build the Lure of the Temptress engine
   --enable-plugins         build engines as loadable modules instead of
                            static linking them
   --disable-mt32emu        don't enable the integrated MT-32 emulator
@@ -366,6 +368,7 @@
       --disable-saga)           _build_saga=no ;;
       --disable-gob)            _build_gob=no ;;
       --disable-kyra)           _build_kyra=no ;;
+      --disable-lure)           _build_lure=no ;;
       --disable-hq-scalers)     _build_hq_scalers=no ;;
       --disable-scalers)        _build_scalers=no ;;
       --enable-alsa)            _alsa=yes       ;;
@@ -677,6 +680,12 @@
 	_mak_gob='# DISABLE_GOB = 1'
 fi
 
+if test "$_build_lure" = no ; then
+	_mak_lure='DISABLE_LURE = 1'
+else
+	_mak_lure='# DISABLE_LURE = 1'
+fi
+
 if test "$_build_hq_scalers" = no ; then
 	_mak_hq_scalers='DISABLE_HQ_SCALERS = 1'
 else
@@ -1242,6 +1251,9 @@
 if test "$_build_gob" = yes ; then
 	echo "    Gobli*ns"
 fi
+if test "$_build_lure" = yes ; then
+	echo "    Lure of the Temptress"
+fi
 
 echo
 
@@ -1379,6 +1391,7 @@
 $_mak_kyra
 $_mak_saga
 $_mak_gob
+$_mak_lure
 $_mak_mt32emu
 
 $_mak_hq_scalers

Added: scummvm/trunk/lure/animseq.cpp
===================================================================
--- scummvm/trunk/lure/animseq.cpp	                        (rev 0)
+++ scummvm/trunk/lure/animseq.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,148 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/animseq.h"
+#include "lure/palette.h"
+#include "lure/decode.h"
+#include "lure/events.h"
+
+namespace Lure {
+
+// delay
+// Delays for a given number of milliseconds. If it returns true, it indicates that
+// Escape has been pressed, and the introduction should be aborted.
+
+AnimAbortType AnimationSequence::delay(uint32 milliseconds) {
+	uint32 delayCtr = _system.getMillis() + milliseconds;
+	Events &events = Events::getReference();
+
+	while (_system.getMillis() < delayCtr) {
+		while (events.pollEvent()) {
+			if (events.type() == OSystem::EVENT_KEYDOWN) {
+				if (events.event().kbd.keycode == 27) return ABORT_END_INTRO;
+				else return ABORT_NEXT_SCENE;
+			} else if (events.type() == OSystem::EVENT_LBUTTONDOWN)
+				return ABORT_NEXT_SCENE;
+			else if (events.type() == OSystem::EVENT_QUIT) 
+				return ABORT_END_INTRO;
+		}
+
+		uint32 delayAmount = delayCtr - _system.getMillis();
+		if (delayAmount > 10) delayAmount = 10;
+		_system.delayMillis(delayAmount);
+	}
+	return ABORT_NONE;
+}
+
+// decodeFrame
+// Decodes a single frame of the animation sequence
+
+void AnimationSequence::decodeFrame(byte *&pPixels, byte *&pLines) {
+	byte *screen = _screen.screen_raw();   
+	uint16 screenPos = 0;
+	uint16 len;
+
+	while (screenPos < SCREEN_SIZE) {
+		// Get line length
+		len = (uint16) *pLines++;
+		if (len == 0) {
+			len = *((uint16 *) pLines);
+			pLines += 2;
+		}
+	
+		// Move the splice over
+		memcpy(screen, pPixels, len);
+		screen += len;
+		screenPos += len;
+		pPixels += len;
+
+		// Get the offset inc amount
+		len = (uint16) *pLines++;
+		if (len == 0) {
+			len = *((uint16 *) pLines);
+			pLines += 2;
+		}
+
+		screen += len;
+		screenPos += len;
+	}
+
+	// Make the decoded frame visible
+	_screen.update();
+}
+
+AnimationSequence::AnimationSequence(Screen &screen, OSystem &system, uint16 screenId, Palette &palette, 
+					 bool fadeIn): _screen(screen), _system(system), _screenId(screenId), _palette(palette) {
+	PictureDecoder decoder;
+	Disk &d = Disk::getReference();
+	MemoryBlock *data = d.getEntry(_screenId);
+	_decodedData = decoder.decode(data, MAX_ANIM_DECODER_BUFFER_SIZE);
+	delete data;
+
+	_lineRefs = d.getEntry(_screenId + 1);
+
+	// Show the screen that preceeds the start of the animation data
+	_screen.setPaletteEmpty();
+	_screen.screen().data().copyFrom(_decodedData, 0, 0, FULL_SCREEN_HEIGHT * FULL_SCREEN_WIDTH);
+	_screen.update();
+
+	// Set the palette
+	if (fadeIn)	_screen.paletteFadeIn(&_palette);
+	else _screen.setPalette(&_palette);
+
+	// Set up frame poitners
+	_pPixels = _decodedData->data() + SCREEN_SIZE;
+	_pLines = _lineRefs->data();
+	_pPixelsEnd = _decodedData->data() + _decodedData->size() - 1;
+	_pLinesEnd = _lineRefs->data() + _lineRefs->size() - 1;
+}
+
+AnimationSequence::~AnimationSequence() {
+	delete _lineRefs;
+	delete _decodedData;
+}
+
+// show
+// Main method for displaying the animation
+
+AnimAbortType AnimationSequence::show() {
+	AnimAbortType result;
+
+	// Loop through displaying the animations
+	while ((_pPixels < _pPixelsEnd) && (_pLines < _pLinesEnd)) {
+		decodeFrame(_pPixels, _pLines);
+
+		result = delay(130);
+		if (result != ABORT_NONE) return result;
+	}
+
+	return ABORT_NONE;
+}
+
+bool AnimationSequence::step() {
+	if ((_pPixels >= _pPixelsEnd) || (_pLines >= _pLinesEnd)) return false;
+	decodeFrame(_pPixels, _pLines);
+	_screen.setPalette(&_palette);
+	return true;
+}
+
+} // end of namespace Lure


Property changes on: scummvm/trunk/lure/animseq.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/animseq.h
===================================================================
--- scummvm/trunk/lure/animseq.h	                        (rev 0)
+++ scummvm/trunk/lure/animseq.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,56 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __lure_animseq_h__
+#define __lure_animseq_h__
+
+#include "lure/screen.h"
+
+namespace Lure {
+
+enum AnimAbortType {ABORT_NONE, ABORT_END_INTRO, ABORT_NEXT_SCENE};
+
+class AnimationSequence {
+private:
+	Screen &_screen;
+	OSystem &_system;
+	uint16 _screenId;
+	Palette &_palette;
+	MemoryBlock *_decodedData;
+	MemoryBlock *_lineRefs;
+	byte *_pPixels, *_pLines;
+	byte *_pPixelsEnd, *_pLinesEnd;
+
+	AnimAbortType delay(uint32 milliseconds);
+	void decodeFrame(byte *&pPixels, byte *&pLines);
+public:
+	AnimationSequence(Screen &screen, OSystem &system, uint16 screenId, Palette &palette, 
+		bool fadeIn);
+	~AnimationSequence();
+
+	AnimAbortType show();
+	bool step();
+};
+
+} // End of namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/animseq.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/debug-input.cpp
===================================================================
--- scummvm/trunk/lure/debug-input.cpp	                        (rev 0)
+++ scummvm/trunk/lure/debug-input.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,133 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/debug-input.h"
+#include "lure/luredefs.h"
+#include "lure/events.h"
+#include "lure/surface.h"
+#include "lure/screen.h"
+
+#ifdef LURE_DEBUG
+
+namespace Lure {
+
+bool get_string(char *buffer, uint32 maxSize, bool isNumeric, uint16 x, uint16 y) {
+	Events &e = Events::getReference();
+	buffer[0] = '\0';
+
+	// Create surface for holding entered text
+	Surface *s = new Surface((maxSize + 1) * FONT_WIDTH, FONT_HEIGHT);
+
+	bool abortFlag = false;
+	bool refreshFlag = true;
+
+	while (!e.quitFlag && !abortFlag) {
+		// Check for refreshing display of text
+		if (refreshFlag) {
+			uint16 strWidth = Surface::textWidth(buffer);
+			s->empty();
+			s->writeString(0, 0, buffer, false, DIALOG_TEXT_COLOUR);
+			s->writeChar(strWidth, 0, '_', false, DIALOG_TEXT_COLOUR);
+			s->copyToScreen(x, y);
+
+			refreshFlag = false;
+		}
+
+		if (e.pollEvent()) {
+			if (e.type() == OSystem::EVENT_KEYDOWN) {
+				char ch = e.event().kbd.ascii;
+				uint16 keycode = e.event().kbd.keycode;
+
+				if ((ch == 13) || (keycode == 0x10f))
+					break;
+				else if (ch == 27) 
+					abortFlag = true;
+				else if (ch == 8) {
+					if (*buffer != '\0') {
+						*((char *) buffer + strlen(buffer) - 1) = '\0';
+						refreshFlag = true;
+					}
+				} else if ((ch >= ' ') && (strlen(buffer) < maxSize)) {
+					if (((ch >= '0') && (ch <= '9')) || !isNumeric) {
+						char *p = buffer + strlen(buffer);
+						*p++ = ch;
+						*p++ = '\0';
+						refreshFlag = true;
+					}
+				}
+			}
+		}
+	}
+
+	delete s;
+	if (e.quitFlag) abortFlag = true;
+	return !abortFlag;
+}
+
+bool input_integer(Common::String desc, uint32 &value)
+{
+	const int MAX_SIZE = 5;
+	char buffer[MAX_SIZE + 1];
+
+	uint16 width = DIALOG_EDGE_SIZE + Surface::textWidth(desc.c_str()) + FONT_WIDTH;
+	uint16 totalWidth = width + FONT_WIDTH * (MAX_SIZE + 1) + DIALOG_EDGE_SIZE;
+	uint16 totalHeight = FONT_HEIGHT + DIALOG_EDGE_SIZE * 2;
+
+	Surface *s = new Surface(totalWidth, totalHeight);
+	s->createDialog(true);
+	s->writeString(DIALOG_EDGE_SIZE + 3, DIALOG_EDGE_SIZE, desc, false);
+
+	uint16 xs = (FULL_SCREEN_WIDTH-totalWidth) / 2;
+	uint16 ys = (FULL_SCREEN_HEIGHT-totalHeight) / 2;
+	s->copyToScreen(xs, ys);
+
+	bool result = get_string(&buffer[0], MAX_SIZE, true, xs+width, ys+DIALOG_EDGE_SIZE);
+	Screen::getReference().update();
+	if (!result || (buffer[0] == '\0')) 
+		return false;
+
+	value = atoi(buffer);
+	return true;
+}
+
+bool input_string(Common::String desc, char *buffer, uint32 maxSize)
+{
+	uint16 width = Surface::textWidth(desc.c_str());
+	if (width < FONT_WIDTH * maxSize) width = FONT_WIDTH * maxSize;
+
+	Surface *s = new Surface(width + 2 * DIALOG_EDGE_SIZE, 2 * FONT_HEIGHT + 2 * DIALOG_EDGE_SIZE);
+	s->createDialog();
+	s->writeString(DIALOG_EDGE_SIZE, DIALOG_EDGE_SIZE, desc, false, DIALOG_TEXT_COLOUR);
+
+	uint16 xs = (FULL_SCREEN_WIDTH-s->width()) / 2;
+	uint16 ys = (FULL_SCREEN_HEIGHT-s->height()) / 2;
+
+	s->copyToScreen(xs, ys);
+	bool result = get_string(buffer, maxSize, true, xs + width, ys + DIALOG_EDGE_SIZE);
+
+	Screen::getReference().update();
+	return result;
+}
+
+} // end of namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/debug-input.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/debug-input.h
===================================================================
--- scummvm/trunk/lure/debug-input.h	                        (rev 0)
+++ scummvm/trunk/lure/debug-input.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,42 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifdef LURE_DEBUG
+#ifndef __lure_input_h__
+#define __lure_input_h__
+
+#include "common/stdafx.h"
+#include "common/str.h"
+#include "lure/surface.h"
+
+namespace Lure {
+
+bool get_string(char *buffer, uint32 maxSize, bool isNumeric, uint16 x, uint16 y);
+
+bool input_integer(Common::String desc, uint32 &value);
+
+bool input_string(Common::String desc, char *buffer, uint32 maxSize);
+
+} // End of namespace Lure
+
+#endif
+#endif


Property changes on: scummvm/trunk/lure/debug-input.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/debug-methods.cpp
===================================================================
--- scummvm/trunk/lure/debug-methods.cpp	                        (rev 0)
+++ scummvm/trunk/lure/debug-methods.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,132 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/debug-methods.h"
+#include "lure/luredefs.h"
+
+#include "lure/events.h"
+#include "lure/surface.h"
+#include "lure/screen.h"
+#include "lure/res.h"
+#include "lure/strings.h"
+#include "lure/room.h"
+
+#ifdef LURE_DEBUG
+
+namespace Lure {
+
+void showActiveHotspots() {
+	char buffer[16384];
+	char *lines[100];
+	char *s = buffer;
+	int numLines = 0;
+	lines[0] = s;
+	*s = '\0';
+
+	Resources &resources = Resources::getReference();
+	Mouse &mouse = Mouse::getReference();
+	Events &events = Events::getReference();
+	Screen &screen = Screen::getReference();
+
+	HotspotList::iterator i = resources.activeHotspots().begin();
+	for (; i != resources.activeHotspots().end(); ++i) {
+		Hotspot &h = *i.operator*();
+		lines[numLines++] = s;
+
+		if (numLines == 16) {
+			strcpy(s, "..more..");
+			break;
+		}
+
+		sprintf(s, "%x", h.hotspotId());
+		s += strlen(s);
+
+		sprintf(s, "h pos=(%d,%d,%d) size=(%d,%d) - ",
+			h.resource().roomNumber, h.x(), h.y(), h.width(), h.height());
+		s += strlen(s);
+
+		uint16 nameId = h.resource().nameId;
+		if (nameId != 0) {
+			StringData::getReference().getString(nameId, s, NULL, NULL);
+			s += strlen(s);
+		}
+		++s;
+	}
+
+	Surface *surface = Surface::newDialog(300, numLines, lines);
+	mouse.cursorOff();
+	surface->copyToScreen(10, 40);
+	events.waitForPress();
+	screen.update();
+	mouse.cursorOn();
+	delete surface;
+}
+
+void showRoomHotspots() {
+	char buffer[16384];
+	char *lines[100];
+	char *s = buffer;
+	int numLines = 0;
+	lines[0] = s;
+	*s = '\0';
+
+	Resources &resources = Resources::getReference();
+	Mouse &mouse = Mouse::getReference();
+	Events &events = Events::getReference();
+	Screen &screen = Screen::getReference();
+	uint16 roomNumber = Room::getReference().roomNumber();
+
+	HotspotDataList::iterator i = resources.hotspotData().begin();
+	for (; i != resources.hotspotData().end(); ++i) {
+		HotspotData &h = *i.operator*();
+		if (h.roomNumber == roomNumber) {
+			lines[numLines++] = s;
+
+			sprintf(s, "%x", h.hotspotId);
+			s += strlen(s);
+
+			sprintf(s, "h pos=(%d,%d) size=(%d,%d) - ",
+				h.startX, h.startY, h.width, h.height);
+			s += strlen(s);
+
+			uint16 nameId = h.nameId;
+			if (nameId != 0) {
+				StringData::getReference().getString(nameId, s, NULL, NULL);
+				s += strlen(s);
+			}
+			++s;
+		}
+	}
+
+	Surface *surface = Surface::newDialog(300, numLines, lines);
+	mouse.cursorOff();
+	surface->copyToScreen(10, 40);
+	events.waitForPress();
+	screen.update();
+	mouse.cursorOn();
+	delete surface;
+}
+
+
+} // end of namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/debug-methods.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/debug-methods.h
===================================================================
--- scummvm/trunk/lure/debug-methods.h	                        (rev 0)
+++ scummvm/trunk/lure/debug-methods.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,39 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifdef LURE_DEBUG
+#ifndef __lure_debugprocs_h__
+#define __lure_debugprocs_h__
+
+#include "common/stdafx.h"
+#include "lure/surface.h"
+
+namespace Lure {
+
+void showActiveHotspots();
+
+void showRoomHotspots();
+
+} // End of namespace Lure
+
+#endif
+#endif


Property changes on: scummvm/trunk/lure/debug-methods.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/decode.cpp
===================================================================
--- scummvm/trunk/lure/decode.cpp	                        (rev 0)
+++ scummvm/trunk/lure/decode.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,360 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/decode.h"
+#include "lure/memory.h"
+#include "lure/luredefs.h"
+
+namespace Lure {
+
+/*--------------------------------------------------------------------------*/
+/* PictureDecoder class                                                     */
+/*                                                                          */
+/* Provides the functionality for decoding screens                          */
+/*--------------------------------------------------------------------------*/
+
+void PictureDecoder::writeByte(MemoryBlock *dest, byte v) {
+	if (outputOffset == dest->size()) 
+		error("Decoded data exceeded allocated output buffer size");
+	dest->data()[outputOffset++] = v;
+}
+
+void PictureDecoder::writeBytes(MemoryBlock *dest, byte v, uint16 numBytes) {
+	if (outputOffset + numBytes > dest->size()) 
+		error("Decoded data exceeded allocated output buffer size");
+	dest->memset(v, outputOffset, numBytes);
+	outputOffset += numBytes;
+}
+
+byte PictureDecoder::DSSI(bool incr) {
+	byte result = dataIn[dataPos];
+	if (incr) ++dataPos;
+	return result;
+}
+
+byte PictureDecoder::ESBX(bool incr) {
+	byte result = dataIn[dataPos2];
+	if (incr) ++dataPos2;
+	return result;
+}
+
+void PictureDecoder::decrCtr() {
+	--CL;
+	if (CL == 0) {
+		CH = ESBX();
+		CL = 8;
+	}
+}
+
+bool PictureDecoder::shlCarry() {
+	bool result = (CH & 0x80) != 0;
+	CH <<= 1;
+	return result;
+}
+
+void PictureDecoder::swap(uint16 &v1, uint16 &v2) {
+	uint16 vTemp;
+	vTemp = v1; 
+	v1 = v2;
+	v2 = vTemp;
+}
+
+// decode_data
+// Takes care of decoding compressed Lure of the Temptress data
+
+MemoryBlock *PictureDecoder::decode(MemoryBlock *src, uint32 maxOutputSize) {
+	MemoryBlock *dest = Memory::allocate(maxOutputSize);
+
+	// Set up initial states
+	dataIn = src->data();
+	outputOffset = 0;
+	dataPos = READ_LE_UINT32(dataIn + 0x400);
+	dataPos2 = 0x404;
+
+	CH = ESBX();
+	CL = 9;
+
+Loc754:
+	AL = DSSI();
+	writeByte(dest, AL);
+	BP = ((uint16) AL) << 2;
+
+Loc755:
+	decrCtr();
+	if (shlCarry()) goto Loc761;
+	decrCtr();
+	if (shlCarry()) goto Loc759;
+	AL = dataIn[BP];
+
+Loc758:
+	writeByte(dest, AL);
+	BP = ((uint16) AL) << 2;
+	goto Loc755;
+
+Loc759:
+	AL = (byte) (BP >> 2);
+	AH = DSSI();
+	if (AH == 0) goto Loc768;
+
+	writeBytes(dest, AL, AH);
+	goto Loc755;
+
+Loc761:
+	decrCtr();
+	if (shlCarry()) goto Loc765;
+	decrCtr();
+
+	if (shlCarry()) goto Loc764;
+	AL = dataIn[BP+1];
+	goto Loc758;
+
+Loc764:
+	AL = dataIn[BP+2];
+	goto Loc758;
+
+Loc765:
+	decrCtr();
+	if (shlCarry()) goto Loc767;
+	AL = dataIn[BP+3];
+	goto Loc758;
+
+Loc767:
+	goto Loc754;
+
+Loc768:
+	AL = DSSI();
+	if (AL != 0) goto Loc755;
+
+	// Resize the output to be the number of outputed bytes and return it
+	if (outputOffset < dest->size()) dest->reallocate(outputOffset);
+	return dest;
+}
+
+/*--------------------------------------------------------------------------*/
+/* AnimationDecoder class                                                   */
+/*                                                                          */
+/* Provides the functionality for decoding animations                       */
+/*--------------------------------------------------------------------------*/
+
+// The code below is responsible for decompressing the pixel data
+// for an animation. I'm not currently sure of the of the exact details
+// of the compression format - for now I've simply copied the code
+// from the executable
+
+void AnimationDecoder::rcl(uint16 &value, bool &carry) {
+	bool result = (value & 0x8000) != 0;
+	value = (value << 1) + (carry ? 1 : 0);
+	carry = result;
+}
+
+#define GET_BYTE currData = (currData & 0xff00) | *pSrc++
+#define BX_VAL(x) *((byte *) (dest->data() + tableOffset + x))
+#define SET_HI_BYTE(x,v) x = (x & 0xff) | ((v) << 8);
+#define SET_LO_BYTE(x,v) x = (x & 0xff00) | (v);
+
+void AnimationDecoder::decode_data_2(byte *&pSrc, uint16 &currData, uint16 &bitCtr, 
+									 uint16 &dx, bool &carry) {
+	SET_HI_BYTE(dx, currData >> 8);
+	
+	for (int v = 0; v < 8; ++v) {
+		rcl(currData, carry);
+		if (--bitCtr == 0) {
+			GET_BYTE;
+			bitCtr = 8;
+		}
+	}
+}
+
+uint32 AnimationDecoder::decode_data(MemoryBlock *src, MemoryBlock *dest, uint32 srcPos) {
+	byte *pSrc = src->data() + srcPos;
+	byte *pDest = dest->data();
+	byte v;
+	bool carry = false;
+	uint16 currData, bitCtr, dx;
+	byte tableOffset;
+	uint16 tempReg1, tempReg2;
+
+	// Handle splitting up 16 bytes into individual nibbles
+	for (int numBytes = 0; numBytes < 16; ++numBytes, ++pDest) {
+		// Split up next byte to pDest and pDest+0x10
+		currData = *pSrc++;
+		*(pDest + 0x10) = currData & 0xf;
+		*pDest = (currData >> 4) & 0xf;
+
+		// Split up next byte to pDest+0x20 and pDest+0x30
+		currData = *pSrc++;
+		*(pDest + 0x30) = currData & 0xf;
+		*(pDest + 0x20) = (currData >> 4) & 0xf;
+	}	
+
+	pDest = (byte *) (dest->data() + 0x40);
+	currData = READ_BE_UINT16(pSrc);
+	pSrc += sizeof(uint16);
+
+	bitCtr = 4;
+	*pDest = (currData >> 8) & 0xf0;
+	tableOffset = currData >> 12;
+	currData <<= 4;
+	dx = 1;
+
+	for (;;) {
+		carry = false;
+		rcl(currData, carry);
+		if (--bitCtr == 0) {
+			GET_BYTE;
+			bitCtr = 8;
+		}
+		if (carry) goto loc_1441;
+		tableOffset = BX_VAL(0);
+
+loc_1439:
+		dx ^= 1;
+		if ((dx & 1) != 0) {
+			SET_HI_BYTE(dx, tableOffset << 4);
+			*pDest = dx >> 8;
+		} else {
+			*pDest++ |= tableOffset;
+		}
+		continue;
+
+loc_1441:
+		rcl(currData, carry);
+		if (--bitCtr == 0) {
+			GET_BYTE;
+			bitCtr = 8;
+		}
+		if (!carry) {
+			rcl(currData, carry);
+			if (--bitCtr == 0) {
+				GET_BYTE;
+				bitCtr = 8;
+			}
+
+			if (!carry) {
+				tableOffset = BX_VAL(0x10);
+			} else {
+				tableOffset = BX_VAL(0x20);
+			}
+			goto loc_1439;
+		}
+
+		rcl(currData, carry);
+		if (--bitCtr == 0) {
+			GET_BYTE;
+			bitCtr = 8;
+		}
+		if (!carry) {
+			tableOffset = BX_VAL(0x30);
+			goto loc_1439;
+		}
+
+		SET_HI_BYTE(dx, currData >> 12);
+		carry = false;
+		for (int ctr = 0; ctr < 4; ++ctr) {
+			rcl(currData, carry);
+			if (--bitCtr == 0) {
+				GET_BYTE;
+				bitCtr = 8;
+			}
+		}
+
+		byte dxHigh = dx >> 8;
+		if (dxHigh == BX_VAL(0)) {
+			tempReg1 = bitCtr;
+			tempReg2 = dx;
+			decode_data_2(pSrc, currData, bitCtr, dx, carry);
+		
+			SET_LO_BYTE(dx, dx >> 8);
+			decode_data_2(pSrc, currData, bitCtr, dx, carry);
+			SET_HI_BYTE(bitCtr, dx & 0xff);
+			SET_LO_BYTE(bitCtr, dx >> 8);
+			dx = tempReg2;
+
+			if (bitCtr == 0) 
+				// Exit out of infinite loop
+				break;
+
+		} else if (dxHigh == BX_VAL(0x10)) {
+			tempReg1 = bitCtr;
+			decode_data_2(pSrc, currData, bitCtr, dx, carry);
+			bitCtr = dx >> 8;
+
+		} else if (dxHigh == BX_VAL(0x20)) {
+			SET_HI_BYTE(dx, currData >> 10);
+
+			for (v = 0; v < 6; ++v) {
+				rcl(currData, carry);
+				if (--bitCtr == 0) {
+					GET_BYTE;
+					bitCtr = 8;
+				}
+			}
+
+			tempReg1 = bitCtr;
+			bitCtr = dx >> 8;
+		
+		} else if (dxHigh == BX_VAL(0x30)) {
+			SET_HI_BYTE(dx, currData >> 11);
+
+			for (v = 0; v < 5; ++v) {
+				rcl(currData, carry);
+				if (--bitCtr == 0) {
+					GET_BYTE;
+					bitCtr = 8;
+				}
+			}
+
+			tempReg1 = bitCtr;
+			bitCtr = dx >> 8;
+
+		} else {
+			tableOffset = dx >> 8;
+			goto loc_1439;
+		}
+
+		if ((dx & 1) == 1) {
+			*pDest++ |= tableOffset;
+			--bitCtr;
+			dx &= 0xfffe;
+		}
+
+		SET_HI_BYTE(dx, tableOffset << 4);
+		tableOffset |= dx >> 8;
+
+		v = bitCtr >> 1;
+		while (v-- > 0) *pDest++ = tableOffset;
+
+		bitCtr &= 1;
+		if (bitCtr != 0) {
+			*pDest = tableOffset & 0xf0;
+			dx |= 1; //dx.l
+		}
+
+		bitCtr = tempReg1;
+		tableOffset &= 0x0f;
+	}
+
+	// Return number of bytes written
+	return pDest - dest->data();
+}
+
+} // end of namespace Lure


Property changes on: scummvm/trunk/lure/decode.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/decode.h
===================================================================
--- scummvm/trunk/lure/decode.h	                        (rev 0)
+++ scummvm/trunk/lure/decode.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,62 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __lure_decode_h__
+#define __lure_decode_h__
+
+#include "common/stdafx.h"
+#include "lure/luredefs.h"
+#include "lure/memory.h"
+
+namespace Lure {
+
+class PictureDecoder {
+private:
+	byte *dataIn;
+	uint32 BP;
+	uint32 dataPos, dataPos2;
+	uint32 outputOffset;
+	byte AL, AH;
+	byte CH, CL;
+
+	void writeByte(MemoryBlock *dest, byte v);
+	void writeBytes(MemoryBlock *dest, byte v, uint16 numBytes);
+	byte DSSI(bool incr = true);
+	byte ESBX(bool incr = true);
+	void decrCtr();
+	bool shlCarry();
+	void swap(uint16 &v1, uint16 &v2);
+public:
+	MemoryBlock *decode(MemoryBlock *src, uint32 maxOutputSize = SCREEN_SIZE);
+};
+
+class AnimationDecoder {
+public:
+	static void rcl(uint16 &value, bool &carry);
+	static uint32 decode_data(MemoryBlock *src, MemoryBlock *dest, uint32 srcPos);
+	static void decode_data_2(byte *&pSrc, uint16 &currData, uint16 &bitCtr, 
+					   uint16 &dx, bool &carry);
+};
+
+} // End of namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/decode.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/disk.cpp
===================================================================
--- scummvm/trunk/lure/disk.cpp	                        (rev 0)
+++ scummvm/trunk/lure/disk.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,174 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+#include "common/file.h"
+#include "common/util.h"
+#include "common/scummsys.h"
+
+#include "lure/disk.h"
+#include "lure/luredefs.h"
+
+namespace Lure {
+
+static Disk *int_disk = NULL;
+
+Disk &Disk::getReference() {
+	return *int_disk;
+}
+
+Disk::Disk(const Common::String &gameDataPath) {
+	_gameDataPath = gameDataPath;
+	_fileNum = 0xff;
+	_fileHandle = NULL;
+	int_disk = this;
+}
+
+Disk::~Disk() {
+	if (_fileHandle) delete _fileHandle;
+	int_disk = NULL;
+}
+
+uint8 Disk::indexOf(uint16 id, bool suppressError) {
+	// Make sure the correct file is open - the upper two bits of the Id give the file number. Note
+	// that an extra check is done for the upper byte of the Id being 0x3f, which is the Id range
+	// I use for lure.dat resources, which are resources extracted from the lure.exe executable
+	uint8 entryFileNum = ((id>>8) == 0x3f) ? 0 : ((id >> 14) & 3) + 1;
+	openFile(entryFileNum);
+
+	// Find the correct entry in the list based on the Id
+	for (int entryIndex=0; entryIndex<NUM_ENTRIES_IN_HEADER; ++entryIndex) {
+		if (_entries[entryIndex].id == HEADER_ENTRY_UNUSED_ID) break;
+		else if (_entries[entryIndex].id == id) return entryIndex;
+	}
+	
+	if (suppressError) return 0xff;
+	error("Could not find entry Id #%d in file %sdisk%d.vga", id, _gameDataPath.c_str(), _fileNum);
+}
+
+void Disk::openFile(uint8 fileNum) {
+	// Validate that the file number is correct
+	if (fileNum > 4)
+		error("Invalid file number specified - %d", fileNum);
+
+	// Only load up the new file if the current file number has changed
+	if (fileNum == _fileNum) return;
+	
+	// Delete any existing open file handle
+	if (_fileNum != 0xff) delete _fileHandle;		
+	_fileNum = fileNum;
+	
+	// Open up the the new file
+	_fileHandle = new Common::File();
+
+	char sFilename[10];
+	if (_fileNum == 0) 
+		strcpy(sFilename, SUPPORT_FILENAME);
+	else
+		sprintf(sFilename, "disk%d.vga", _fileNum);
+
+	_fileHandle->open(sFilename);
+	if (!_fileHandle->isOpen())
+		error("Could not open %s%s", _gameDataPath.c_str(), sFilename);
+
+	// Validate the header
+	char buffer[7];
+	uint32 bytesRead;
+
+	bytesRead = _fileHandle->read(buffer, 6);
+	buffer[6] = '\0';
+	if (strcmp(buffer, HEADER_IDENT_STRING) != 0)
+		error("The file %s%s was not a valid VGA file", _gameDataPath.c_str(), sFilename);
+
+	uint16 fileFileNum = _fileHandle->readUint16BE();
+	if (fileFileNum != _fileNum)
+		error("The file %s%s was not the correct file number", _gameDataPath.c_str(), sFilename);
+
+	// Read in the header entries
+	uint32 headerSize = sizeof(FileEntry) * NUM_ENTRIES_IN_HEADER;
+	if (_fileHandle->read(_entries, headerSize) != headerSize)
+		error("The file %s%s had a corrupted header", _gameDataPath.c_str(), sFilename);
+
+#ifdef SCUMM_BIG_ENDIAN
+	// Process the read in header list to convert to big endian
+	for (int i = 0; i < NUM_ENTRIES_IN_HEADER; ++i) {
+		_entries[i].id = FROM_LE_16(_entries[i].id);
+		_entries[i].size = FROM_LE_16(_entries[i].size);
+		_entries[i].offset = FROM_LE_16(_entries[i].offset);
+	}
+#endif
+}
+
+uint32 Disk::getEntrySize(uint16 id) {
+	// Get the index of the resource, if necessary opening the correct file
+	uint8 index = indexOf(id);
+
+	// Calculate the offset and size of the entry
+	uint32 size = (uint32) _entries[index].size;
+	if (_entries[index].sizeExtension) size += 0x10000;
+
+	return size;
+}
+
+MemoryBlock *Disk::getEntry(uint16 id)
+{
+	// Get the index of the resource, if necessary opening the correct file
+	uint8 index = indexOf(id);
+		
+	// Calculate the offset and size of the entry
+	uint32 size = (uint32) _entries[index].size;
+	if (_entries[index].sizeExtension) size += 0x10000;
+	uint32 offset = (uint32) _entries[index].offset * 0x20;
+
+	MemoryBlock *result = Memory::allocate(size);
+	_fileHandle->seek(offset, SEEK_SET);
+	_fileHandle->read(result->data(), size);
+	return result;
+}
+
+bool Disk::exists(uint16 id) {
+	// Get the index of the resource, if necessary opening the correct file
+	uint8 index = indexOf(id, true);
+	return (index != 0xff);
+}
+
+uint8 Disk::numEntries() {
+	if (_fileNum == 0)
+		error("No file is currently open");
+
+	// Figure out how many entries there are by count until an unused entry is found
+	for (byte entryIndex = 0; entryIndex < NUM_ENTRIES_IN_HEADER; ++entryIndex)
+		if (_entries[entryIndex].id == HEADER_ENTRY_UNUSED_ID) return entryIndex;
+	
+	return NUM_ENTRIES_IN_HEADER;
+}
+
+FileEntry *Disk::getIndex(uint8 entryIndex) {
+	if (_fileNum == 0)
+		error("No file is currently open");
+	if ((entryIndex >= NUM_ENTRIES_IN_HEADER) || (_entries[entryIndex].id == HEADER_ENTRY_UNUSED_ID))
+		error("There is no entry at the specified index");
+
+	return &_entries[entryIndex];
+}
+
+} // end of namespace Lure


Property changes on: scummvm/trunk/lure/disk.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/disk.h
===================================================================
--- scummvm/trunk/lure/disk.h	                        (rev 0)
+++ scummvm/trunk/lure/disk.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,66 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __lure_disk_h__
+#define __lure_disk_h__
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/str.h"
+#include "lure/memory.h"
+#include "lure/res_struct.h"
+
+namespace Common {
+	class File;
+}
+
+namespace Lure {
+
+#define NUM_ENTRIES_IN_HEADER 0xBF
+#define HEADER_IDENT_STRING "heywow"
+#define HEADER_ENTRY_UNUSED_ID 0xffff
+
+class Disk {
+private:
+	Common::String _gameDataPath;
+	uint8 _fileNum;
+	Common::File *_fileHandle;
+	FileEntry _entries[NUM_ENTRIES_IN_HEADER];
+
+	uint8 indexOf(uint16 id, bool suppressError = false);
+public:
+	Disk(const Common::String &gameDataPath);
+	~Disk();
+	static Disk &getReference();
+
+	void openFile(uint8 fileNum);
+	uint32 getEntrySize(uint16 id);
+	MemoryBlock *getEntry(uint16 id);
+	bool exists(uint16 id);
+
+	uint8 numEntries();
+	FileEntry *getIndex(uint8 entryIndex);
+};
+
+} // end of namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/disk.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/events.cpp
===================================================================
--- scummvm/trunk/lure/events.cpp	                        (rev 0)
+++ scummvm/trunk/lure/events.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,159 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/events.h"
+
+namespace Lure {
+
+static Mouse *int_mouse = NULL;
+
+Mouse &Mouse::getReference() { 
+	return *int_mouse; 
+}
+
+Mouse::Mouse(OSystem &system): _system(system), _cursors(Disk::getReference().getEntry(CURSOR_RESOURCE_ID)) {
+	int_mouse = this;
+
+	_lButton = false; 
+	_rButton = false;
+	_cursorNum = 0;
+	setCursorNum(0);
+}
+
+Mouse::~Mouse() {
+	delete _cursors;
+}
+
+void Mouse::handleEvent(OSystem::Event event) {
+	_x = (int16) event.mouse.x;
+	_y = (int16) event.mouse.y;
+
+	switch (event.type) {
+	case OSystem::EVENT_LBUTTONDOWN:
+		_lButton = true;
+		break;
+	case OSystem::EVENT_LBUTTONUP:
+		_lButton = false;
+		break;
+	case OSystem::EVENT_RBUTTONDOWN:
+		_rButton = true;
+		break;
+	case OSystem::EVENT_RBUTTONUP:
+		_rButton = false;
+		break;
+	default:
+		break;
+	}
+}
+
+
+void Mouse::cursorOn() {
+	_system.showMouse(true);
+}
+
+void Mouse::cursorOff() {
+	_system.showMouse(false);
+}
+
+void Mouse::setCursorNum(uint8 cursorNum) {
+	int hotspotX = 7, hotspotY = 7;
+	if ((cursorNum == CURSOR_ARROW) || (cursorNum == CURSOR_MENUBAR)) {
+		hotspotX = 0; 
+		hotspotY = 0;
+	}
+
+	setCursorNum(cursorNum, hotspotX, hotspotY);
+}
+
+void Mouse::setCursorNum(uint8 cursorNum, int hotspotX, int hotspotY) {
+	_cursorNum = cursorNum;
+	byte *cursorAddr = _cursors->data() + (cursorNum * CURSOR_SIZE);
+	_system.setMouseCursor(cursorAddr, CURSOR_WIDTH, CURSOR_HEIGHT, hotspotX, hotspotY, 0);
+}
+
+void Mouse::setPosition(int newX, int newY) {
+	_system.warpMouse(newX, newY);
+}
+
+void Mouse::waitForRelease() {
+	Events &e = Events::getReference();
+
+	do {
+		e.pollEvent();
+	} while (!e.quitFlag && (lButton() || rButton()));
+}
+
+/*--------------------------------------------------------------------------*/
+
+static Events *int_events = NULL;
+
+Events::Events(OSystem &system, Mouse &mouse): _system(system), _mouse(mouse), quitFlag(false) {
+	int_events = this;
+}
+
+Events &Events::getReference() {
+	return *int_events;
+}
+
+
+bool Events::pollEvent() {
+	if (!_system.pollEvent(_event)) return false;
+
+	// Handle keypress
+	switch (_event.type) {
+	case OSystem::EVENT_QUIT:
+		quitFlag = true;
+		break;
+
+	case OSystem::EVENT_LBUTTONDOWN:
+	case OSystem::EVENT_LBUTTONUP:
+	case OSystem::EVENT_RBUTTONDOWN:
+	case OSystem::EVENT_RBUTTONUP:
+	case OSystem::EVENT_MOUSEMOVE:
+	case OSystem::EVENT_WHEELUP:
+	case OSystem::EVENT_WHEELDOWN:
+		_mouse.handleEvent(_event);
+		break;
+
+	default:
+ 		break;
+	}
+
+	return true;
+}
+
+void Events::waitForPress() {
+	bool keyButton = false;
+	while (!keyButton) {
+		if (pollEvent()) {
+			if (_event.type == OSystem::EVENT_QUIT) return;
+			else if (_event.type == OSystem::EVENT_KEYDOWN) keyButton = true;
+			else if ((_event.type == OSystem::EVENT_LBUTTONDOWN) ||
+				(_event.type == OSystem::EVENT_RBUTTONDOWN)) {
+				keyButton = true;
+				_mouse.waitForRelease();				
+			}
+		}
+	}
+}
+
+} // end of namespace Lure


Property changes on: scummvm/trunk/lure/events.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/events.h
===================================================================
--- scummvm/trunk/lure/events.h	                        (rev 0)
+++ scummvm/trunk/lure/events.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,78 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __lure_events_h__
+#define __lure_events_h__
+
+#include "common/stdafx.h"
+#include "common/str.h"
+#include "lure/luredefs.h"
+#include "lure/disk.h"
+
+namespace Lure {
+
+class Mouse {
+private:
+	OSystem &_system;
+	MemoryBlock *_cursors;
+	uint8 _cursorNum;
+	int16 _x, _y;
+	bool _lButton, _rButton;
+public:
+	Mouse(OSystem &system);
+	~Mouse();
+	static Mouse &getReference(); 
+	void handleEvent(OSystem::Event event);
+
+	void cursorOn();
+	void cursorOff();
+	void setCursorNum(uint8 cursorNum);
+	void setCursorNum(uint8 cursorNum, int hotspotX, int hotspotY);
+	uint8 getCursorNum() { return _cursorNum; }
+	void setPosition(int x, int y);
+	int16 x() { return _x; }
+	int16 y() { return _y; }
+	bool lButton() { return _lButton; }
+	bool rButton() { return _rButton; }
+	void waitForRelease();
+};
+
+class Events {
+private:
+	OSystem &_system;
+	Mouse &_mouse;
+	OSystem::Event _event;
+public:
+	bool quitFlag;
+
+	Events(OSystem &system, Mouse &mouse);
+	static Events &getReference();
+
+	bool pollEvent();
+	void waitForPress();
+	OSystem::Event event() { return _event; }
+	OSystem::EventType type() { return _event.type; }
+};
+
+} // End of namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/events.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/game.cpp
===================================================================
--- scummvm/trunk/lure/game.cpp	                        (rev 0)
+++ scummvm/trunk/lure/game.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,420 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/game.h"
+#include "lure/strings.h"
+#include "lure/room.h"
+#include "lure/system.h"
+#include "lure/debug-input.h"
+#include "lure/debug-methods.h"
+#include "lure/scripts.h"
+#include "lure/res_struct.h"
+
+namespace Lure {
+
+static Game *int_game = NULL;
+
+Game &Game::getReference() {
+	return *int_game;
+}
+
+Game::Game() {
+	int_game = this;
+	_slowSpeedFlag = true;
+	_soundFlag = true;
+	_remoteView = false;
+}
+
+void Game::nextFrame() {
+	Resources &r = Resources::getReference();
+	HotspotList::iterator i = r.activeHotspots().begin();
+	HotspotList::iterator iTemp;
+
+	// Note the somewhat more complicated loop style as a hotspot tick handler may
+	// unload the hotspot and accompanying record
+	for (; i != r.activeHotspots().end(); i = iTemp) {
+		iTemp = i;
+		++iTemp;
+		Hotspot &h = *i.operator*();
+		h.tick();
+	}
+}
+
+void Game::execute() {
+	OSystem &system = System::getReference();
+	Room &r = Room::getReference();
+	Resources &res = Resources::getReference();
+	Events &events = Events::getReference();
+	Mouse &mouse = Mouse::getReference();
+	Screen &screen = Screen::getReference();
+	Menu &menu = Menu::getReference();
+	ValueTableData &fields = res.fieldList();
+
+	uint32 timerVal = system.getMillis();
+
+	screen.empty();
+	//_screen.resetPalette();
+	screen.setPaletteEmpty();
+
+	Script::execute(STARTUP_SCRIPT);
+
+	// Load the first room
+	r.setRoomNumber(1);
+
+	// Set the player direction
+	res.getActiveHotspot(PLAYER_ID)->setDirection(UP);
+
+	r.update();
+	mouse.setCursorNum(CURSOR_ARROW);
+	mouse.cursorOn();
+	
+	while (!events.quitFlag) {
+		// If time for next frame, allow everything to update
+		if (system.getMillis() > timerVal + GAME_FRAME_DELAY) {
+			timerVal = system.getMillis();
+			nextFrame();			
+		}
+		res.delayList().tick();
+		r.update();
+
+		if (events.pollEvent()) {
+			if (events.type() == OSystem::EVENT_KEYDOWN) {
+				uint16 roomNum = r.roomNumber();
+
+#ifdef LURE_DEBUG
+				if (events.event().kbd.keycode == 282) {
+					doDebugMenu();
+					continue;
+				}
+#endif
+
+				switch (events.event().kbd.ascii) {
+				case 27:
+					events.quitFlag = true;
+					break;
+
+#ifdef LURE_DEBUG
+				case '+':
+					while (++roomNum <= 51) 
+						if (res.getRoom(roomNum) != NULL) break; 
+					if (roomNum == 52) roomNum = 1;
+
+					r.leaveRoom();
+					r.setRoomNumber(roomNum);
+					break;
+
+				case '-':
+					if (roomNum == 1) roomNum = 55;
+					while (res.getRoom(--roomNum) == NULL) ;
+
+					r.leaveRoom();
+					r.setRoomNumber(roomNum);
+					break;
+
+				case '*':
+					res.getActiveHotspot(PLAYER_ID)->setRoomNumber(
+						r.roomNumber());
+					break;
+#endif
+				default:
+					break;
+				}
+			}
+
+			if (mouse.y() < MENUBAR_Y_SIZE) 
+			{
+				if (mouse.getCursorNum() != CURSOR_MENUBAR) mouse.setCursorNum(CURSOR_MENUBAR);
+				if ((mouse.getCursorNum() == CURSOR_MENUBAR) && mouse.lButton())
+				{
+					uint8 responseId = menu.execute();
+					mouse.setCursorNum((mouse.y() < MENUBAR_Y_SIZE) ? CURSOR_MENUBAR : CURSOR_ARROW);
+					if (responseId != MENUITEM_NONE)
+						handleMenuResponse(responseId);
+				}
+			} else {
+				if (mouse.getCursorNum() == CURSOR_MENUBAR) mouse.setCursorNum(CURSOR_ARROW);
+				
+				if (events.type() == OSystem::EVENT_MOUSEMOVE)
+					r.cursorMoved();
+
+				if (mouse.rButton()) handleRightClickMenu();
+				else if (mouse.lButton()) handleLeftClick();
+			}
+		}
+
+		uint16 destRoom = fields.getField(NEW_ROOM_NUMBER);
+		if (_remoteView && (destRoom != 0)) {
+			// Show a remote view of the specified room
+			uint16 currentRoom = r.roomNumber();
+			r.setRoomNumber(destRoom, true);
+
+			// This code eventually needs to be moved into the main loop so that,
+			// amongst other things, the tick handlers controlling animation can work
+			while (!events.quitFlag && !mouse.lButton() && !mouse.rButton()) {
+				if (events.pollEvent()) {
+					if ((events.type() == OSystem::EVENT_KEYDOWN) && 
+						(events.event().kbd.ascii == 27))
+						events.quitFlag = true;
+					if (events.type() == OSystem::EVENT_MOUSEMOVE)
+						r.cursorMoved();
+				}
+
+				if (system.getMillis() > timerVal + GAME_FRAME_DELAY) {
+					timerVal = system.getMillis();
+					nextFrame();			
+				}
+				res.delayList().tick();
+				r.update();
+			}
+
+			fields.setField(NEW_ROOM_NUMBER, 0);
+			Hotspot *player = res.getActiveHotspot(PLAYER_ID);
+			player->setTickProc(0x5e44); // reattach player handler
+			_remoteView = false;
+			r.setRoomNumber(currentRoom);
+		}
+	}
+
+	r.leaveRoom();
+}
+
+#ifdef LURE_DEBUG
+
+#define NUM_DEBUG_ITEMS 4
+const char *debugItems[NUM_DEBUG_ITEMS] = 
+		{"Toggle Info", "Set Room", "Show Active HS", "Show Room HS"};
+
+void Game::doDebugMenu() {
+	uint16 index = PopupMenu::Show(NUM_DEBUG_ITEMS, debugItems);
+	Room &r = Room::getReference();
+	Resources &res = Resources::getReference();
+	
+	switch (index) {
+	case 0:
+		// Toggle co-ordinates
+		r.setShowInfo(!r.showInfo());
+		break;
+
+	case 1:
+		// Set room number:
+		uint32 roomNumber;
+		if (!input_integer("Enter room number:", roomNumber)) return;
+		if (res.getRoom(roomNumber))
+			r.setRoomNumber(roomNumber);
+		else
+			Dialog::show("The room does not exist");
+		break;
+
+	case 2:
+		// Show active hotspots
+        showActiveHotspots();
+		break;
+
+	case 3:
+		// Show hotspots in room
+		showRoomHotspots();
+		break;
+
+	default:
+		break;
+	}
+}
+
+#endif
+
+void Game::handleMenuResponse(uint8 selection) {
+	switch (selection) {
+	case MENUITEM_CREDITS:
+		doShowCredits();
+		break;
+
+	case MENUITEM_RESTART_GAME: 
+	case MENUITEM_SAVE_GAME:
+	case MENUITEM_RESTORE_GAME: 
+		break;
+
+	case MENUITEM_QUIT:
+		doQuit();
+		break;
+
+	case MENUITEM_TEXT_SPEED:
+		doTextSpeed();
+		break;
+
+	case MENUITEM_SOUND:
+		doSound();
+	}
+}
+
+void Game::handleRightClickMenu() {
+	Room &r = Room::getReference();
+	Resources &res = Resources::getReference();
+	ValueTableData &fields = Resources::getReference().fieldList();
+	Hotspot *player = res.getActiveHotspot(PLAYER_ID);
+	HotspotData *hotspot;
+	Action action;
+	uint32 actions;
+	uint16 itemId;
+
+	if (r.hotspotId() != 0) {
+		// Get hotspot actions
+		actions = r.hotspotActions();
+	} else {
+		// Standard actions - drink, examine, look, status
+		actions = 0x1184000;
+	}
+
+	// If no inventory items remove entries that require them
+	if (res.numInventoryItems() == 0) 
+		actions &= 0xFEF3F9FD;
+
+	action = NONE;
+	hotspot = NULL;
+
+	bool breakFlag = false;
+	while (!breakFlag) {
+		action = PopupMenu::Show(actions);
+
+		switch (action) {
+		case LOOK:
+		case STATUS:
+			breakFlag = true;
+			break;
+
+		case GIVE:
+		case USE:
+		case EXAMINE:
+		case DRINK:
+			if (action != DRINK)
+				hotspot = res.getHotspot(r.hotspotId());
+			itemId = PopupMenu::ShowInventory();
+			breakFlag = (itemId != 0xffff);
+			if (breakFlag) 
+				fields.setField(USE_HOTSPOT_ID, itemId);
+			break;
+
+		default:
+			hotspot = res.getHotspot(r.hotspotId());
+			breakFlag = true;
+			break;
+		}
+	}
+
+	// Set fields used by the script interpreter
+	fields.setField(CHARACTER_HOTSPOT_ID, PLAYER_ID);
+	if (hotspot) {
+		fields.setField(ACTIVE_HOTSPOT_ID, hotspot->hotspotId);
+		if ((action != USE) && (action != GIVE)) {
+			fields.setField(USE_HOTSPOT_ID, hotspot->hotspotId);
+		}
+	}
+
+	if (action != NONE)
+		player->doAction(action, hotspot);
+}
+
+void Game::handleLeftClick() {
+	Room &room = Room::getReference();
+	Mouse &mouse = Mouse::getReference();
+	Resources &resources = Resources::getReference();
+
+	if (room.hotspotId()) {
+		// Handle look at hotspot
+		HotspotData *hs = resources.getHotspot(room.hotspotId());
+		Hotspot *player = resources.getActiveHotspot(PLAYER_ID);
+		room.setAction(LOOK_AT);
+		room.update();
+		player->doAction(LOOK_AT, hs);
+		room.setAction(NONE);
+	} else {
+		// Walk to mouse click. TODO: still need to recognise other actions,
+		// such as to room exits or closing an on-screen floating dialog
+		Hotspot *hs =  resources.getActiveHotspot(PLAYER_ID);
+		hs->walkTo(mouse.x(), mouse.y(), 0);
+	}
+}
+
+void Game::doShowCredits() {
+	Events &events = Events::getReference();
+	Mouse &mouse = Mouse::getReference();
+	Screen &screen = Screen::getReference();
+
+	mouse.cursorOff();
+	Palette p(CREDITS_RESOURCE_ID - 1);
+	Surface *s = Surface::getScreen(CREDITS_RESOURCE_ID);
+	screen.setPalette(&p);	
+	s->copyToScreen(0, 0);
+	delete s;
+
+	events.waitForPress();
+
+	screen.resetPalette();
+	screen.update();
+	mouse.cursorOn();
+}
+
+void Game::doQuit() {
+	Mouse &mouse = Mouse::getReference();
+	Events &events = Events::getReference();
+	Screen &screen = Screen::getReference();
+
+	mouse.cursorOff();
+	Surface *s = Surface::newDialog(190, "Are you sure (y/n)?");
+	s->centerOnScreen();
+	delete s;
+
+	char key = '\0';
+	do {
+		if (events.pollEvent()) {
+			if (events.event().type == OSystem::EVENT_KEYDOWN) {
+				key = events.event().kbd.ascii;
+				if ((key >= 'A') && (key <= 'Z')) key += 'a' - 'A';
+			}
+		}
+	} while (((uint8) key != 27) && (key != 'y') && (key != 'n'));
+
+	events.quitFlag = key == 'y';
+	if (!events.quitFlag) {
+		screen.update();
+		mouse.cursorOn();
+	}
+}
+
+void Game::doTextSpeed() {
+	Menu &menu = Menu::getReference();
+
+	_slowSpeedFlag = !_slowSpeedFlag;
+	const char *pSrc = _slowSpeedFlag ? "Slow" : "Fast";
+	char *pDest = menu.getMenu(2).getEntry(1);
+	memcpy(pDest, pSrc, 4);
+}
+
+void Game::doSound() {
+	Menu &menu = Menu::getReference();
+
+	_soundFlag = !_soundFlag;
+	const char *pSrc = _soundFlag ? "on " : "off";
+	char *pDest = menu.getMenu(2).getEntry(2) + 6;
+	memcpy(pDest, pSrc, 3);
+}
+
+} // end of namespace Lure


Property changes on: scummvm/trunk/lure/game.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/game.h
===================================================================
--- scummvm/trunk/lure/game.h	                        (rev 0)
+++ scummvm/trunk/lure/game.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,64 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __lure_game_h__
+#define __lure_game_h__
+
+#include "common/stdafx.h"
+#include "base/engine.h"
+#include "lure/luredefs.h"
+#include "lure/menu.h"
+#include "lure/palette.h"
+#include "lure/disk.h"
+#include "lure/memory.h"
+#include "lure/screen.h"
+#include "lure/events.h"
+
+namespace Lure {
+
+class Game {
+private:
+	bool _slowSpeedFlag, _soundFlag;
+	bool _remoteView;
+
+	void handleMenuResponse(uint8 selection);
+	void handleRightClickMenu();
+	void handleLeftClick();
+public:
+	Game();
+	static Game &getReference();
+
+	void nextFrame();
+	void execute();
+	void setRemoteView() { _remoteView = true; }
+
+	// Menu item support methods
+	void doDebugMenu();
+	void doShowCredits();
+	void doQuit();
+	void doTextSpeed();
+	void doSound();
+};
+
+} // End of namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/game.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/hotspots.cpp
===================================================================
--- scummvm/trunk/lure/hotspots.cpp	                        (rev 0)
+++ scummvm/trunk/lure/hotspots.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,806 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/hotspots.h"
+#include "lure/decode.h"
+#include "lure/palette.h"
+#include "lure/disk.h"
+#include "lure/res.h"
+#include "lure/scripts.h"
+#include "lure/room.h"
+#include "lure/strings.h"
+#include "lure/res_struct.h"
+#include "lure/events.h"
+
+namespace Lure {
+
+Hotspot::Hotspot(HotspotData *res) {
+	_data = res;
+	_anim = NULL;
+	_frames = NULL;
+	_numFrames = 0;
+	_persistant = false;
+
+	_startX = res->startX;
+	_startY = res->startY;
+	_destX = res->startX;
+	_destY = res->startY;
+	_destHotspotId = 0;
+	_width = res->width;
+	_height = res->height;
+	_tickCtr = res->tickTimeout;
+
+	// Check for a hotspot override
+	HotspotOverrideData *hor = Resources::getReference().getHotspotOverride(res->hotspotId);
+		
+	if (hor) {
+		_startX = hor->xs;
+		_startY = hor->ys;
+		if (hor->xe < hor->xs) _width = 0; 
+		else _width = hor->xe - hor->xs + 1;
+		if (hor->ye < hor->ys) _height = 0;
+		else _height = hor->ye - hor->ys + 1;
+	}
+	
+	if (_data->animRecordId != 0)
+		setAnimation(_data->animRecordId);
+
+	_tickHandler = HotspotTickHandlers::getHandler(_data->tickProcOffset);
+}
+
+Hotspot::~Hotspot() {
+	if (_frames) delete _frames;
+}
+
+void Hotspot::setAnimation(uint16 newAnimId) {
+	Resources &r = Resources::getReference();
+	HotspotAnimData *tempAnim;
+	if (newAnimId == 0) tempAnim = NULL;
+	else tempAnim = r.getAnimation(newAnimId); 
+	
+	setAnimation(tempAnim);
+}
+
+void Hotspot::setAnimation(HotspotAnimData *newRecord) {
+	Disk &r = Disk::getReference();
+	if (_frames) {
+		delete _frames;
+		_frames = NULL;
+	}
+	_anim = NULL;
+	_numFrames = 0;
+	_frameNumber = 0;
+	if (!newRecord) return;
+	if (!r.exists(newRecord->animId)) return;
+
+	_anim = newRecord;
+	MemoryBlock *src = Disk::getReference().getEntry(_anim->animId);
+	
+	uint16 *numEntries = (uint16 *) src->data();
+	uint16 *headerEntry = (uint16 *) (src->data() + 2);
+
+	if ((*numEntries > 99) || (*numEntries == 0)) {
+		// Wobbly, likely something wrong with the resoure
+		_width = 1;
+		_numFrames = 1;
+		_frameNumber = 0;
+		_frames = new Surface(1, 1);
+		_frames->data().memset(_data->colourOffset, 0, 1);
+		return;
+	}
+
+	// Calculate total needed size for output and create memory block to hold it
+	uint32 totalSize = 0;
+	for (uint16 ctr = 0; ctr < *numEntries; ++ctr, ++headerEntry) {
+		totalSize += (*headerEntry + 31) / 32;
+	}
+	totalSize = (totalSize + 0x81) << 4;
+	MemoryBlock *dest = Memory::allocate(totalSize);
+
+	uint32 srcStart = (*numEntries + 1) * sizeof(uint16) + 6;
+	AnimationDecoder::decode_data(src, dest, srcStart);
+
+	_numFrames = *numEntries;
+	_frameNumber = 0;
+	
+	_frames = new Surface(_data->width * _numFrames, _data->height);
+
+	_frames->data().memset(_data->colourOffset, 0, _frames->data().size());
+
+	byte *pSrc = dest->data() + 0x40;
+	byte *pDest;
+	headerEntry = (uint16 *) (src->data() + 2);
+	MemoryBlock &mDest = _frames->data();
+
+	for (uint16 frameCtr = 0; frameCtr < _numFrames; ++frameCtr, ++headerEntry) {
+		
+		// Copy over the frame, applying the colour offset to each nibble
+		for (uint16 yPos = 0; yPos < _data->height; ++yPos) {
+			pDest = mDest.data() + (yPos * _numFrames + frameCtr) * _data->width;
+
+			for (uint16 ctr = 0; ctr < _data->width / 2; ++ctr) {
+				*pDest++ = _data->colourOffset + (*pSrc >> 4);
+				*pDest++ = _data->colourOffset + (*pSrc & 0xf);
+				++pSrc;
+			}
+		}
+	}
+
+	delete src;
+	delete dest;
+}
+
+void Hotspot::copyTo(Surface *dest) {
+/*
+	int16 xPos = x();
+	int16 yPos = y();
+	uint16 hWidth = width();
+	uint16 hHeight = height();
+*/
+	int16 xPos = _data->startX;
+	int16 yPos = _data->startY;
+	uint16 hWidth = _data->width;
+	uint16 hHeight = _data->height;
+
+	Rect r(_frameNumber * hWidth, 0, (_frameNumber + 1) * hWidth - 1, 
+		hHeight - 1);
+
+	if (yPos < 0) {
+		if (yPos + hHeight <= 0) 
+			// Completely off screen, so don't display
+			return;
+
+		// Reduce the source rectangle to only the on-screen portion
+		r.top = -yPos;
+		yPos = 0;
+	}
+
+	if (xPos < 0) {
+		if (xPos + hWidth <= 0)
+			// Completely off screen, so don't display
+			return;
+
+		// Reduce the source rectangle to only the on-screen portion
+		r.left = -xPos;
+		xPos = 0;
+	}
+
+	if (xPos >= FULL_SCREEN_WIDTH) 
+		return;
+	else if (xPos + hWidth > FULL_SCREEN_WIDTH)
+		r.right = (_frameNumber * hWidth) + (FULL_SCREEN_WIDTH - xPos) - 1;
+	if (yPos >= FULL_SCREEN_HEIGHT)
+		return;
+	else if (yPos + hHeight > FULL_SCREEN_HEIGHT)
+		r.bottom = FULL_SCREEN_HEIGHT - yPos - 1;
+
+	_frames->copyTo(dest, r, (uint16) xPos, (uint16) yPos, _data->colourOffset);
+}
+
+void Hotspot::incFrameNumber() {
+	++_frameNumber;
+	if (_frameNumber >= _numFrames) 
+		_frameNumber = 0;
+}
+
+bool Hotspot::isActiveAnimation() {
+	return ((_numFrames != 0) && (_data->layer != 0));
+}
+
+void Hotspot::setPosition(int16 newX, int16 newY) {
+	_startX = newX;
+	_startY = newY;
+	_data->startX = newX;
+	_data->startY = newY;
+}
+
+void Hotspot::setSize(uint16 newWidth, uint16 newHeight) {
+	_width = newWidth;
+	_height = newHeight;
+}
+
+bool Hotspot::executeScript() {
+	if (_data->sequenceOffset == 0)
+		return false;
+	else
+		return HotspotScript::execute(this);
+}
+
+void Hotspot::tick() {
+	_tickHandler(*this);
+}
+
+void Hotspot::setTickProc(uint16 newVal) {
+	_data->tickProcOffset = newVal;
+	_tickHandler = HotspotTickHandlers::getHandler(newVal);	
+}
+
+
+void Hotspot::walkTo(int16 endPosX, int16 endPosY, uint16 destHotspot, bool immediate) {
+	_destX = endPosX;
+	_destY = endPosY - _data->height;
+
+	_destHotspotId = destHotspot;
+	if (immediate) 
+		setPosition(_destX, _destY);
+}
+
+void Hotspot::setDirection(Direction dir) {
+	switch (dir) {
+	case UP:
+		setFrameNumber(_anim->upFrame);
+		break;
+	case DOWN:
+		setFrameNumber(_anim->downFrame);
+		break;
+	case LEFT:
+		setFrameNumber(_anim->leftFrame);
+		break;
+	case RIGHT:
+		setFrameNumber(_anim->rightFrame);
+		break;
+	default:
+		break;
+	}
+}
+
+/*-------------------------------------------------------------------------*/
+/* Hotspot action handling                                                 */
+/*                                                                         */
+/*-------------------------------------------------------------------------*/
+
+uint16 validRoomExitHotspots[] = {0x2711, 0x2712, 0x2714, 0x2715, 0x2716, 0x2717,
+	0x2718, 0x2719, 0x271A, 0x271E, 0x271F, 0x2720, 0x2721, 0x2722, 0x2725, 0x2726,
+	0x2729, 0x272A, 0x272B, 0x272C, 0x272D, 0x272E, 0x272F, 0};
+
+bool Hotspot::isRoomExit(uint16 id) {
+	for (uint16 *p = &validRoomExitHotspots[0]; *p != 0; ++p) 
+		if (*p == id) return true;
+	return false;
+}
+
+void Hotspot::doAction(Action action, HotspotData *hotspot) {
+	switch (action) {
+	case GET:
+		doGet(hotspot);
+		break;
+	case PUSH:
+	case PULL:
+	case OPERATE:
+		doOperate(hotspot, action);
+		break;
+	case OPEN:
+		doOpen(hotspot);
+		break;
+	case CLOSE:
+		doClose(hotspot);
+		break;
+	case LOCK:
+		doSimple(hotspot, LOCK);
+		break;
+	case UNLOCK:
+		doSimple(hotspot, UNLOCK);
+		break;
+	case USE:
+		doUse(hotspot);
+		break;
+	case GIVE:
+		doGive(hotspot);
+		break;
+	case TALK_TO:
+		doTalkTo(hotspot);
+		break;
+	case TELL:
+		doTell(hotspot);
+		break;
+	case LOOK:
+		doLook();
+		break;
+	case LOOK_AT:
+		doLookAt(hotspot);
+		break;
+	case LOOK_THROUGH:
+		doSimple(hotspot, LOOK_THROUGH);
+		break;
+	case ASK:
+		doAsk(hotspot);
+		break;
+	case DRINK:
+		doDrink();
+		break;
+	case STATUS:
+		doStatus();
+		break;
+	case BRIBE:
+		doBribe(hotspot);
+		break;
+	case EXAMINE:
+		doExamine();
+		break;
+	default:
+		doSimple(hotspot, action);
+		break;
+	}	
+}
+
+void Hotspot::doGet(HotspotData *hotspot) {
+	Resources &res = Resources::getReference();
+	uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, GET);
+
+	if (sequenceOffset >= 0x8000) {
+		Dialog::showMessage(sequenceOffset, hotspotId());
+		return;
+	} 
+	
+	if (sequenceOffset != 0) {
+		uint16 result = Script::execute(sequenceOffset);
+
+		if (result == 1) return;
+		else if (result != 0) {
+			Dialog::showMessage(result, hotspotId());
+			return;
+		}
+	}
+
+	// Move hotspot into characters's inventory
+	hotspot->roomNumber = hotspotId();  
+
+	if (hotspot->hotspotId < START_NONVISUAL_HOTSPOT_ID) {
+		// Deactive hotspot animation
+		Resources::getReference().deactivateHotspot(hotspot->hotspotId);
+		// Remove any 'on the ground' description for the hotspot
+		hotspot->descId2 = 0;
+	}
+}
+
+void Hotspot::doOperate(HotspotData *hotspot, Action action) {
+	Resources &res = Resources::getReference();
+	uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, action);
+
+	if (sequenceOffset >= 0x8000) {
+		Dialog::showMessage(sequenceOffset, hotspotId());
+	} else if (sequenceOffset != 0) {
+		uint16 result = Script::execute(sequenceOffset);
+		if (result > 1)
+			Dialog::showMessage(result, hotspotId());
+	}
+}
+
+void Hotspot::doOpen(HotspotData *hotspot) {
+	Resources &res = Resources::getReference();
+	RoomExitJoinData *joinRec;
+
+	if (isRoomExit(hotspot->hotspotId)) {
+		joinRec = res.getExitJoin(hotspot->hotspotId);
+		if (!joinRec->blocked) {
+			// Room exit is already open
+			Dialog::showMessage(4, hotspotId());
+			// TODO: jmp loc_1102
+			return;
+		}
+	}
+
+	// TODO: Call to sub_107 and checking the results, then sub_110
+
+	uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, OPEN);
+	if (sequenceOffset >= 0x8000) {
+		// Message to display
+		Dialog::showMessage(sequenceOffset, hotspotId());
+	} else if (sequenceOffset != 0) {
+		// Otherwise handle script
+		uint16 result = Script::execute(sequenceOffset);
+
+		if (result == 0) {
+			joinRec = res.getExitJoin(hotspot->hotspotId);
+			if (joinRec->blocked) {
+				joinRec->blocked = 0;
+
+				if (hotspotId() != PLAYER_ID) {
+					// TODO: HS[44h]=3, HS[42h]W = 4
+				}
+			}
+		} else if (result != 1) {
+			// TODO: Figure out: if Hotspot-rec[60h] != 0, then set = 4
+			Dialog::showMessage(result, hotspotId());
+		}
+	}
+}
+
+void Hotspot::doClose(HotspotData *hotspot) {
+	Resources &res = Resources::getReference();
+	RoomExitJoinData *joinRec;
+
+	if (isRoomExit(hotspot->hotspotId)) {
+		joinRec = res.getExitJoin(hotspot->hotspotId);
+		if (joinRec->blocked) {
+			// Room exit is already closed/blocked
+			Dialog::showMessage(3, hotspotId());
+			// TODO: jmp sub_129
+			return;
+		}
+	}
+
+	// TODO: Call to sub_107 and checking the results, then sub_110
+
+	uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, CLOSE);
+
+	if (sequenceOffset >= 0x8000) {
+		// Message to display
+		Dialog::showMessage(sequenceOffset, hotspotId());
+	} else if (sequenceOffset != 0) {
+		// Otherwise handle script
+		uint16 result = Script::execute(sequenceOffset);
+
+		if (result != 0) {
+			Dialog::showMessage(result, hotspotId());
+		} else {
+			joinRec = res.getExitJoin(hotspot->hotspotId);
+			if (!joinRec->blocked) {
+				// Close the door
+				// TODO: Decode sub_183 - does check to see if door is 'jammed', but
+				// a cursory inspection seems to indicate that the routine is more
+				// concerned with checking if any character is blocking the door
+//				if (!sub183(joinRec->0Dh) || !sub183(joinRec->0Fh)) {
+//					Dialog::showMessage(2, hotspotId());
+//				} else {
+					joinRec->blocked = 1;
+//				}
+			}
+		}
+	}
+}
+
+void Hotspot::doUse(HotspotData *hotspot) {
+	Resources &res = Resources::getReference();
+//	uint16 usedId = res.fieldList().getField(USE_HOTSPOT_ID);
+	uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, USE);
+
+	if (sequenceOffset >= 0x8000) {
+		Dialog::showMessage(sequenceOffset, hotspotId());
+	} else if (sequenceOffset == 0) {
+		Dialog::showMessage(17, hotspotId());
+	} else {
+		uint16 result = Script::execute(sequenceOffset);
+		if (result != 0) 
+			Dialog::showMessage(result, hotspotId());
+	}
+}
+
+void Hotspot::doGive(HotspotData *hotspot) {
+	Resources &res = Resources::getReference();
+	uint16 usedId = res.fieldList().getField(USE_HOTSPOT_ID);
+	uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, GIVE);
+
+	if (sequenceOffset >= 0x8000) {
+		Dialog::showMessage(sequenceOffset, hotspotId());
+	} else {
+		uint16 result = Script::execute(sequenceOffset);
+		if (result == 0x3E7) {
+			// TODO
+		} else if (result == 0) {
+			// Move item into character's inventory
+			HotspotData *usedItem = res.getHotspot(usedId);
+			usedItem->roomNumber = hotspotId();
+		} else if (result > 1) {
+			// TODO
+		}
+	}
+}
+
+void Hotspot::doTalkTo(HotspotData *hotspot) {
+	// TODO: extra checking at start
+	Resources &res = Resources::getReference();
+	uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, TALK_TO);
+
+	if (sequenceOffset >= 0x8000) {
+		Dialog::showMessage(sequenceOffset, hotspotId());
+	} else if (sequenceOffset != 0) {
+		uint16 result = Script::execute(sequenceOffset);
+
+		if (result == 0) {
+			// Do talking with character
+			// TODO
+			Dialog::show("Still need to figure out talking");
+		}
+	}
+}
+
+void Hotspot::doTell(HotspotData *hotspot) {
+	// TODO
+}
+
+void Hotspot::doLook() {
+	Dialog::show(Room::getReference().descId());
+}
+
+void Hotspot::doLookAt(HotspotData *hotspot) {
+	Resources &res = Resources::getReference();
+	uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, LOOK_AT);
+	
+	if (sequenceOffset >= 0x8000) {
+		Dialog::showMessage(sequenceOffset, hotspotId());
+	} else {
+		if (sequenceOffset != 0) 
+			sequenceOffset = Script::execute(sequenceOffset);
+
+		if (sequenceOffset == 0) {
+			uint16 descId = (hotspot->descId2 != 0) ? hotspot->descId2 : hotspot->descId;
+			Dialog::show(descId);
+		}
+	}
+}
+
+void Hotspot::doAsk(HotspotData *hotspot) {
+	// TODO
+}
+
+void Hotspot::doDrink() {
+	Resources &res = Resources::getReference();
+	uint16 usedId = res.fieldList().getField(USE_HOTSPOT_ID);
+	HotspotData *hotspot = res.getHotspot(usedId);
+	uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, DRINK);
+
+	if (sequenceOffset >= 0x8000) {
+		Dialog::showMessage(sequenceOffset, hotspotId());
+	} else if (sequenceOffset == 0) {
+		Dialog::showMessage(22, hotspotId());
+	} else {
+		uint16 result = Script::execute(sequenceOffset);
+		if (result == 0) {
+			// Item has been drunk, so remove item from game
+			hotspot->roomNumber = 0;
+		} else if (result != 1) {
+			Dialog::showMessage(result, hotspotId());
+		}
+	}
+}
+
+// doStatus
+// Handle the status window
+
+void Hotspot::doStatus() {
+	char buffer[MAX_DESC_SIZE];
+	uint16 numItems = 0;
+	StringData &strings = StringData::getReference();
+	Resources &resources = Resources::getReference();
+	Room &room = Room::getReference();
+
+	strings.getString(room.roomNumber(), buffer, NULL, NULL);
+	strcat(buffer, "\n\nYou are carrying ");
+
+	// Scan through the list and add in any items assigned to the player
+	HotspotDataList &list = resources.hotspotData();
+	HotspotDataList::iterator i;
+	for (i = list.begin(); i != list.end(); ++i) {
+		HotspotData *rec = *i;
+
+		if (rec->roomNumber == PLAYER_ID) {
+			if (numItems++ == 0) strcat(buffer, ": ");
+			else strcat(buffer, ", ");
+			strings.getString(rec->nameId, buffer + strlen(buffer), NULL, NULL);
+		}
+	}
+
+	// If there were no items, add in the word 'nothing'
+	if (numItems == 0) strcat(buffer, "nothing.");
+
+	// If the player has money, add it in
+	// TODO
+
+	// Display the dialog
+	Screen &screen = Screen::getReference();
+	Mouse &mouse = Mouse::getReference();
+	mouse.cursorOff();
+
+	Surface *s = Surface::newDialog(INFO_DIALOG_WIDTH, buffer);
+	s->copyToScreen(INFO_DIALOG_X, (FULL_SCREEN_HEIGHT-s->height())/2);
+
+	Events::getReference().waitForPress();
+	screen.update();
+	mouse.cursorOn();
+}
+
+void Hotspot::doBribe(HotspotData *hotspot) {
+	// TODO
+}
+
+void Hotspot::doExamine() {
+	Resources &res = Resources::getReference();
+	uint16 usedId = res.fieldList().getField(USE_HOTSPOT_ID);
+	HotspotData *hotspot = res.getHotspot(usedId);
+	uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, EXAMINE);
+	
+	if (sequenceOffset >= 0x8000) {
+		Dialog::showMessage(sequenceOffset, hotspotId());
+	} else {
+		if (sequenceOffset != 0) 
+			sequenceOffset = Script::execute(sequenceOffset);
+
+		if (sequenceOffset == 0) {
+			Dialog::show(hotspot->descId);
+		}
+	}
+}
+
+void Hotspot::doSimple(HotspotData *hotspot, Action action) {
+	Resources &res = Resources::getReference();
+	uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, action);
+
+	if (sequenceOffset >= 0x8000) {
+		Dialog::showMessage(sequenceOffset, hotspotId());
+	} else if (sequenceOffset != 0) {
+		Script::execute(sequenceOffset);
+	}
+}
+
+/*------------------------------------------------------------------------*/
+
+HandlerMethodPtr HotspotTickHandlers::getHandler(uint16 procOffset) {
+	switch (procOffset) {
+	case 0x7F3A:
+		return standardAnimHandler;
+	case 0x7207:
+		return roomExitAnimHandler;
+	case 0x5e44:
+		return playerAnimHandler;
+	case 0x7F69:
+		return droppingTorchAnimHandler;
+	case 0x8009:
+		return fireAnimHandler;
+	case 0x8241:
+		return headAnimationHandler;
+	default:
+		return defaultHandler;
+	}
+}
+
+void HotspotTickHandlers::defaultHandler(Hotspot &h) {
+	// No handling done
+}
+
+void HotspotTickHandlers::standardAnimHandler(Hotspot &h) {
+	if (h.tickCtr() > 0) 
+		h.setTickCtr(h.tickCtr() - 1);
+	else 
+		h.executeScript();
+}
+
+void HotspotTickHandlers::roomExitAnimHandler(Hotspot &h) {
+	RoomExitJoinData *rec = Resources::getReference().getExitJoin(h.hotspotId());
+	if (!rec) return;
+	byte *currentFrame, *destFrame;
+
+	if (rec->hotspot1Id == h.hotspotId()) {
+		currentFrame = &rec->h1CurrentFrame; 
+		destFrame = &rec->h1DestFrame;
+	} else {
+		currentFrame = &rec->h2CurrentFrame;
+		destFrame = &rec->h2DestFrame;
+	}
+	
+	if ((rec->blocked != 0) && (*currentFrame != *destFrame)) {
+		// sub_178
+
+		++*currentFrame;
+		if (*currentFrame != *destFrame) {
+			// cx=1 => sub_184 
+		}
+	} else if ((rec->blocked == 0) && (*currentFrame != 0)) {
+		// sub_179
+		if (*currentFrame == *destFrame) {
+			// sub_184 and other stuff TODO
+		}
+		--*currentFrame;
+	}
+
+	h.setFrameNumber(*currentFrame);
+}
+
+void HotspotTickHandlers::playerAnimHandler(Hotspot &h) {
+	int16 xPos = h.x();
+	int16 yPos = h.y();
+	if ((xPos == h.destX()) && (yPos == h.destY())) return;
+	HotspotAnimData &anim = h.anim();
+	int16 xDiff = h.destX() - h.x();
+	int16 yDiff = h.destY() - h.y();
+
+	int16 xChange, yChange;
+	uint16 nextFrame;
+	MovementDataList *moves;
+
+	if ((yDiff < 0) && (xDiff <= 0)) moves = &anim.upFrames;
+	else if (xDiff < 0) moves = &anim.leftFrames;
+	else if (yDiff > 0) moves = &anim.downFrames;
+	else moves = &anim.rightFrames;
+
+	// Get movement amount and next frame number
+	moves->getFrame(h.frameNumber(), xChange, yChange, nextFrame);
+	xPos += xChange; yPos += yChange;
+
+	// Make sure that the move amount doesn't overstep the destination X/Y
+	if ((yDiff < 0) && (yPos < h.destY())) yPos = h.destY();
+	else if ((xDiff < 0) && (xPos < h.destX())) xPos = h.destX();
+	else if ((yDiff > 0) && (yPos > h.destY())) yPos = h.destY();
+	else if ((xDiff > 0) && (xPos > h.destX())) xPos = h.destX();
+
+	// Check to see if player has entered an exit area
+	RoomData *roomData = Resources::getReference().getRoom(h.roomNumber());
+	Room &room = Room::getReference();
+	bool charInRoom = room.roomNumber() == h.roomNumber();
+	RoomExitData *exitRec = roomData->exits.checkExits(xPos, yPos + h.height());
+
+	if (!exitRec) {
+		h.setPosition(xPos, yPos);
+		h.setFrameNumber(nextFrame);
+	} else {
+		h.setRoomNumber(exitRec->roomNumber);
+		h.walkTo(exitRec->x, exitRec->y, 0, true);
+		if (exitRec->direction != NO_DIRECTION)
+			h.setDirection(exitRec->direction);
+		if (charInRoom)
+			room.setRoomNumber(exitRec->roomNumber, false);
+	}
+}
+
+void HotspotTickHandlers::droppingTorchAnimHandler(Hotspot &h) {
+	if (h.tickCtr() > 0) 
+		h.setTickCtr(h.tickCtr() - 1);
+	else {
+		bool result = h.executeScript();
+		if (result) {
+			// Changeover to the fire on the straw
+			Resources &res = Resources::getReference();
+			res.deactivateHotspot(h.hotspotId());
+			res.activateHotspot(0x41C);
+
+			// Enable the fire and activate it's animation
+			HotspotData *fire = res.getHotspot(0x418);
+			fire->flags |= 0x80;
+			fire->loadOffset = 0x7172; 
+			res.activateHotspot(0x418);
+		}
+ 	}
+}
+
+void HotspotTickHandlers::fireAnimHandler(Hotspot &h) {
+	standardAnimHandler(h);
+	// TODO: figure out remainder of method
+}
+
+void HotspotTickHandlers::headAnimationHandler(Hotspot &h) {
+	Resources &res = Resources::getReference();
+	Hotspot *character = res.getActiveHotspot(PLAYER_ID);
+	uint16 frameNumber = 0;
+
+	if (character->y() < 79) {
+		//character = res.getActiveHotspot(RATPOUCH_ID);
+		frameNumber = 1;
+	} else {
+		if (character->x() < 72) frameNumber = 0;
+		else if (character->x() < 172) frameNumber = 1;
+		else frameNumber = 2;
+	}
+
+	h.setFrameNumber(frameNumber);
+}
+
+} // end of namespace Lure


Property changes on: scummvm/trunk/lure/hotspots.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/hotspots.h
===================================================================
--- scummvm/trunk/lure/hotspots.h	                        (rev 0)
+++ scummvm/trunk/lure/hotspots.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,137 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __lure_hotspots_h__
+#define __lure_hotspots_h__
+
+#include "lure/luredefs.h"
+#include "lure/screen.h"
+#include "lure/disk.h"
+#include "lure/res_struct.h"
+
+namespace Lure {
+
+class Hotspot;
+
+typedef void(*HandlerMethodPtr)(Hotspot &h);
+
+class HotspotTickHandlers {
+private:
+	static void defaultHandler(Hotspot &h);
+	static void standardAnimHandler(Hotspot &h);
+	static void roomExitAnimHandler(Hotspot &h);
+	static void playerAnimHandler(Hotspot &h);
+	static void droppingTorchAnimHandler(Hotspot &h);
+	static void fireAnimHandler(Hotspot &h);
+	static void headAnimationHandler(Hotspot &h);
+
+public:
+	static HandlerMethodPtr getHandler(uint16 procOffset);
+};
+
+
+class Hotspot {
+private:
+	HotspotData *_data;
+	HotspotAnimData *_anim;
+	HandlerMethodPtr _tickHandler;
+	Surface *_frames;
+	int16 _startX, _startY;
+	uint16 _height, _width;
+	uint16 _numFrames;
+	uint16 _frameNumber;
+	uint16 _tickCtr;
+	bool _persistant;
+
+	int16 _destX, _destY;
+	uint16 _destHotspotId;
+public:
+	Hotspot(HotspotData *res);
+	~Hotspot();
+
+	void setAnimation(uint16 newAnimId);
+	void setAnimation(HotspotAnimData *newRecord);
+	uint16 hotspotId() { return _data->hotspotId; }
+	Surface &frames() { return *_frames; }
+	HotspotAnimData &anim() { return *_anim; }
+	HotspotData &resource() { return *_data; }
+	uint16 numFrames() { return _numFrames; }
+	uint16 frameNumber() { return _frameNumber; }
+	void setFrameNumber(uint16 v) { _frameNumber = v; }
+	void incFrameNumber();
+	uint16 frameWidth() { return _width; }
+	int16 x() { return _startX; }
+	int16 y() { return _startY; }
+	int16 destX() { return _destX; }
+	int16 destY() { return _destY; }
+	uint16 destHotspotId() { return _destHotspotId; }
+	uint16 width() { return _width; }
+	uint16 height() { return _height; }
+	uint16 roomNumber() { return _data->roomNumber; }
+	uint16 script() { return _data->sequenceOffset; }
+	uint8 layer() { return _data->layer; }
+	uint16 tickCtr() { return _tickCtr; }
+	void setTickCtr(uint16 newVal) { _tickCtr = newVal; }
+	void setTickProc(uint16 newVal);
+	bool persistant() { return _persistant; }
+	void setPersistant(bool value) { _persistant = value; }
+	void setRoomNumber(uint16 roomNum) { _data->roomNumber = roomNum; }
+	bool isActiveAnimation();
+	void setPosition(int16 newX, int16 newY);
+	void setDestPosition(int16 newX, int16 newY) { _destX = newX; _destY = newY; }
+	void setSize(uint16 newWidth, uint16 newHeight);
+	void setScript(uint16 offset) { _data->sequenceOffset = offset; }
+	void setActions(uint32 newActions) { _data->actions = newActions; }
+
+	void copyTo(Surface *dest);
+	bool executeScript();
+	void tick();
+	void walkTo(int16 endPosX, int16 endPosY, uint16 destHotspot = 0, bool immediate = false);
+	void setDirection(Direction dir);
+
+	// Action set
+	void doAction(Action action, HotspotData *hotspot);
+	bool isRoomExit(uint16 id);
+	void doGet(HotspotData *hotspot);
+	void doOperate(HotspotData *hotspot, Action action);
+	void doOpen(HotspotData *hotspot);
+	void doClose(HotspotData *hotspot);
+	void doLockUnlock(HotspotData *hotspot);
+	void doUse(HotspotData *hotspot);
+	void doGive(HotspotData *hotspot);
+	void doTalkTo(HotspotData *hotspot);
+	void doTell(HotspotData *hotspot);
+	void doLook();
+	void doLookAt(HotspotData *hotspot);
+	void doAsk(HotspotData *hotspot);
+	void doDrink();
+	void doStatus();
+	void doBribe(HotspotData *hotspot);
+	void doExamine();
+	void doSimple(HotspotData *hotspot, Action action);
+};
+
+typedef ManagedList<Hotspot *> HotspotList;
+
+} // End of namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/hotspots.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/intro.cpp
===================================================================
--- scummvm/trunk/lure/intro.cpp	                        (rev 0)
+++ scummvm/trunk/lure/intro.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,151 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/intro.h"
+#include "lure/animseq.h"
+#include "lure/events.h"
+
+namespace Lure {
+
+struct AnimRecord {
+	uint16 resourceId;
+	uint8 paletteIndex;
+	bool initialPause;
+	bool endingPause;
+};
+
+static const uint16 start_screens[] = {0x18, 0x1A, 0x1E, 0x1C, 0};
+static const AnimRecord anim_screens[] = {{0x40, 0, true, true}, {0x42, 1, false, true}, 
+	{0x44, 2, false, false}, {0x24, 3, false, true}, {0x46, 3, false, false}, 
+	{0, 0, false, false}};
+
+// showScreen
+// Shows a screen by loading it from the given resource, and then fading it in
+// with a palette in the following resource. Returns true if the introduction
+// should be aborted
+
+bool Introduction::showScreen(uint16 screenId, uint16 paletteId, uint16 delaySize) {
+	_screen.screen().loadScreen(screenId);
+	_screen.update();
+	Palette p(paletteId);
+	_screen.paletteFadeIn(&p);
+	
+	bool result = delay(delaySize);
+	if (Events::getReference().quitFlag) return true;
+
+	_screen.paletteFadeOut();
+	return result;
+}
+
+// delay
+// Delays for a given number of milliseconds. If it returns true, it indicates that
+// Escape has been pressed, and the introduction should be aborted.
+
+bool Introduction::delay(uint32 milliseconds) {
+	Events &events = Events::getReference();
+	uint32 delayCtr = _system.getMillis() + milliseconds;
+
+	while (_system.getMillis() < delayCtr) {
+		if (events.quitFlag) return true;
+
+		if (events.pollEvent()) {
+			if (events.type() == OSystem::EVENT_KEYDOWN) 
+				return events.event().kbd.keycode == 27;
+			else if (events.type() == OSystem::EVENT_LBUTTONDOWN)
+				return false;
+		}
+
+		uint32 delayAmount = delayCtr - _system.getMillis();
+		if (delayAmount > 10) delayAmount = 10;
+		_system.delayMillis(delayAmount);
+	}
+	return false;
+}
+
+// show
+// Main method for the introduction sequence
+
+bool Introduction::show() {
+	_screen.setPaletteEmpty();
+
+	// Initial game company and then game screen
+
+	for (int ctr = 0; start_screens[ctr]; ++ctr)
+		if (showScreen(start_screens[ctr], start_screens[ctr] + 1, 5000)) 
+			return true;	
+
+	AnimationSequence *anim;
+	bool result;
+
+	// Animated screens
+
+	PaletteCollection coll(0x32);
+	const AnimRecord *curr_anim = anim_screens;
+	for (; curr_anim->resourceId; ++curr_anim)
+	{
+		bool fadeIn = curr_anim == anim_screens;
+		anim = new AnimationSequence(_screen, _system, curr_anim->resourceId, 
+			coll.getPalette(curr_anim->paletteIndex), fadeIn);
+		if (curr_anim->initialPause) 
+			if (delay(12000)) return true;
+
+		result = false;
+		switch (anim->show()) {
+			case ABORT_NONE:
+				if (curr_anim->endingPause) {
+					result = delay(12000);
+				}
+				break;
+
+			case ABORT_END_INTRO:
+				result = true;
+				break;
+
+			case ABORT_NEXT_SCENE:
+				break;
+		}
+		delete anim;
+
+		if (result) return true;
+	}
+
+	// Show battle pictures one frame at a time
+
+	result = false;
+	anim = new AnimationSequence(_screen, _system, 0x48, coll.getPalette(4), false);
+	do {
+		result = delay(2000);
+		_screen.paletteFadeOut();
+		if (!result) result = delay(500);
+		if (result) break;
+	} while (anim->step());
+	delete anim;
+	if (result) return true;
+
+	// Show final introduction screen
+
+	showScreen(0x22, 0x21, 10000);
+
+	return false;
+}
+
+} // end of namespace Lure


Property changes on: scummvm/trunk/lure/intro.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/intro.h
===================================================================
--- scummvm/trunk/lure/intro.h	                        (rev 0)
+++ scummvm/trunk/lure/intro.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,45 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __lure_intro_h__
+#define __lure_intro_h__
+
+#include "lure/screen.h"
+
+namespace Lure {
+
+class Introduction {
+private:
+	Screen &_screen;
+	OSystem &_system;
+
+	bool showScreen(uint16 screenId, uint16 paletteId, uint16 delaySize);
+	bool delay(uint32 milliseconds);
+public:
+	Introduction(Screen &screen, OSystem &system): _screen(screen), _system(system) {};
+
+	bool show();
+};
+
+} // End of namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/intro.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/lure.cpp
===================================================================
--- scummvm/trunk/lure/lure.cpp	                        (rev 0)
+++ scummvm/trunk/lure/lure.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,306 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/stdafx.h"
+
+#include "backends/fs/fs.h"
+
+#include "base/gameDetector.h"
+#include "base/plugins.h"
+
+#include "common/config-manager.h"
+#include "common/file.h"
+#include "common/system.h"
+#include "common/md5.h"
+
+#include "sound/mixer.h"
+#include "sound/mididrv.h"
+#include "sound/audiostream.h"
+
+#include "lure/luredefs.h"
+#include "lure/surface.h"
+#include "lure/lure.h"
+#include "lure/intro.h"
+#include "lure/game.h"
+#include "lure/system.h"
+
+using namespace Lure;
+
+enum {
+	// We only compute MD5 of the first megabyte of our data files.
+	kMD5FileSizeLimit = 1024 * 1024
+};
+
+struct LureGameSettings {
+	const char *name;
+	const char *description;
+	byte id;
+	uint32 features;
+	const char *md5sum;
+	const char *checkFile;
+	GameSettings toGameSettings() const {
+		GameSettings dummy = { name, description, features };
+		return dummy;
+	}
+};
+
+//
+static const LureGameSettings lure_games[] = {
+	{ "lure", "Lure of the Temptress (Floppy, English)", GI_LURE, GF_ENGLISH | GF_FLOPPY, 
+										"e45ea5d279a268c7d3c6524c2f63a2d2", "disk1.vga" },
+	{ 0, 0, 0, 0, 0, 0 }
+};
+
+// Keep list of different supported games
+
+struct LureGameList {
+	const char *name;
+	const char *description;
+	uint32 features;
+	GameSettings toGameSettings() const {
+		GameSettings dummy = { name, description, features };
+		return dummy;
+	}
+};
+
+static const LureGameList lure_list[] = {
+	{ "lure", "Lure of the Temptress", 0 },
+	{ 0, 0, 0 }
+};
+
+GameList Engine_LURE_gameList() {
+	GameList games;
+	const LureGameList *g = lure_list;
+
+	while (g->name) {
+		games.push_back(g->toGameSettings());
+		g++;
+	}
+	return games;
+}
+
+DetectedGameList Engine_LURE_detectGames(const FSList &fslist) {
+	DetectedGameList detectedGames;
+	const LureGameSettings *g;
+	FSList::const_iterator file;
+
+	// Iterate over all files in the given directory
+	bool isFound = false;
+	for (file = fslist.begin(); file != fslist.end(); file++) {
+		if (file->isDirectory())
+			continue;
+
+		for (g = lure_games; g->name; g++) {
+			if (scumm_stricmp(file->displayName().c_str(), g->checkFile) == 0)
+				isFound = true;
+		}
+		if (isFound)
+			break;
+	}
+
+	if (file == fslist.end())
+		return detectedGames;
+
+	uint8 md5sum[16];
+	char md5str[32 + 1];
+
+	if (Common::md5_file(file->path().c_str(), md5sum, NULL, kMD5FileSizeLimit)) {
+		for (int i = 0; i < 16; i++) {
+			sprintf(md5str + i * 2, "%02x", (int)md5sum[i]);
+		}
+		for (g = lure_games; g->name; g++) {
+			if (strcmp(g->md5sum, (char *)md5str) == 0) {
+				detectedGames.push_back(g->toGameSettings());
+			}
+		}
+		if (detectedGames.isEmpty()) {
+			debug("Unknown MD5 (%s)! Please report the details (language, platform, etc.) of this game to the ScummVM team\n", md5str);
+
+			const LureGameList *g1 = lure_list;
+			while (g1->name) {
+				detectedGames.push_back(g1->toGameSettings());
+				g1++;
+			}
+		}
+	}
+	return detectedGames;
+}
+
+Engine *Engine_LURE_create(GameDetector *detector, OSystem *system) {
+	return new LureEngine(detector, system);
+}
+
+REGISTER_PLUGIN(LURE, "Lure of the Temptress Engine")
+
+namespace Lure {
+
+LureEngine::LureEngine(GameDetector *detector, OSystem *system): Engine(system) {
+	// Setup mixer
+/*
+	if (!_mixer->isReady()) {
+		warning("Sound initialization failed.");
+	}
+
+	_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
+	_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
+	_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
+*/
+	_features = 0;
+	_game = 0;
+}
+
+void LureEngine::detectGame() {
+	// Make sure all the needed files are present
+	
+	if (!Common::File::exists(SUPPORT_FILENAME))
+		error("Missing %s - this is a custom file containing resources from the\n"
+			"Lure of the Temptress executable. See the documentation for creating it.",
+			SUPPORT_FILENAME);
+
+	for (uint8 fileNum = 1; fileNum <= 4; ++fileNum)
+	{
+		char sFilename[10];
+		sprintf(sFilename, "disk%d.vga", fileNum);
+
+		if (!Common::File::exists(sFilename))
+			error("Missing disk%d.vga", fileNum);
+	}
+
+	// Check the version of the lure.dat file
+	Common::File f;
+	if (!f.open(SUPPORT_FILENAME)) {
+		error("Error opening %s for validation", SUPPORT_FILENAME);
+	} else {
+		f.seek(0xbf * 8);
+		VersionStructure version;
+		f.read(&version, sizeof(VersionStructure));
+		f.close();
+
+		if (READ_LE_UINT16(&version.id) != 0xffff)
+			error("Error validating %s - file is invalid or out of date", SUPPORT_FILENAME);
+		else if ((version.vMajor != LURE_DAT_MAJOR) || (version.vMinor != LURE_DAT_MINOR))
+			error("Incorrect version of %s file - expected %d.%d but got %d.%d",
+				SUPPORT_FILENAME, LURE_DAT_MAJOR, LURE_DAT_MINOR, 
+				version.vMajor, version.vMinor);
+	}
+
+	// Do an md5 check 
+	
+	uint8 md5sum[16];
+	char md5str[32 + 1];
+	const LureGameSettings *g;
+	bool found = false;
+
+	*md5str = 0;
+
+	for (g = lure_games; g->name; g++) {
+		if (!Common::File::exists(g->checkFile))
+			continue;
+
+		if (Common::md5_file(g->checkFile, md5sum, ConfMan.get("path").c_str(), kMD5FileSizeLimit)) {
+			for (int j = 0; j < 16; j++) {
+				sprintf(md5str + j * 2, "%02x", (int)md5sum[j]);
+			}
+		} else
+			continue;
+
+		if (strcmp(g->md5sum, (char *)md5str) == 0) {
+			_features = g->features;
+			_game = g->id;
+
+			if (g->description)
+				g_system->setWindowCaption(g->description);
+
+			found = true;
+			break;
+		}
+	}
+
+	if (!found) {
+		debug("Unknown MD5 (%s)! Please report the details (language, platform, etc.) of this game to the ScummVM team", md5str);
+		_features = GF_LNGUNK || GF_FLOPPY;
+		_game = GI_LURE;
+	}
+}
+
+int LureEngine::init(GameDetector &detector) {
+	_system->beginGFXTransaction();
+		initCommonGFX(detector);
+		_system->initSize(FULL_SCREEN_WIDTH, FULL_SCREEN_HEIGHT);
+	_system->endGFXTransaction();
+
+	detectGame();
+
+	_sys = new System(_system);
+	_disk = new Disk(_gameDataPath);
+	_resources = new Resources();
+	_strings = new StringData();
+	_screen = new Screen(*_system);
+	_mouse = new Mouse(*_system);
+	_events = new Events(*_system, *_mouse);
+	_menu = new Menu(*_system);
+	Surface::initialise();
+	_room = new Room();
+
+	return 0;
+}
+
+LureEngine::~LureEngine() {
+	Surface::deinitialise();
+	delete _room;
+	delete _menu;
+	delete _events;
+	delete _mouse;
+	delete _screen;
+	delete _strings;
+	delete _resources;
+	delete _disk;
+	delete _sys;
+}
+
+int LureEngine::go() {
+	// Show the introduction
+	Introduction *intro = new Introduction(*_screen, *_system);
+	intro->show();
+	delete intro;
+
+	// Play the game
+	if (!_events->quitFlag) {
+		// Play the game
+		Game *gameInstance = new Game();
+		gameInstance->execute();
+		delete gameInstance;
+	}
+
+	//quitGame();
+	return 0;
+}
+
+void LureEngine::errorString(const char *buf1, char *buf2) {
+	strcpy(buf2, buf1);
+}
+
+void LureEngine::quitGame() {
+	_system->quit();
+}
+
+} // End of namespace Lure


Property changes on: scummvm/trunk/lure/lure.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/lure.h
===================================================================
--- scummvm/trunk/lure/lure.h	                        (rev 0)
+++ scummvm/trunk/lure/lure.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,73 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __LURE_H__
+#define __LURE_H__
+
+#include "base/engine.h"
+#include "common/rect.h"
+#include "sound/mixer.h"
+#include "common/file.h"
+
+#include "lure/disk.h"
+#include "lure/res.h"
+#include "lure/screen.h"
+#include "lure/events.h"
+#include "lure/menu.h"
+#include "lure/system.h"
+#include "lure/strings.h"
+#include "lure/room.h"
+
+namespace Lure {
+
+class LureEngine : public Engine {
+private:
+	uint32 _features;
+	uint8 _game;
+	Disk *_disk;
+	Resources *_resources;
+	Screen *_screen;
+	Mouse *_mouse;
+	Events *_events;
+	Menu *_menu;
+	System *_sys;
+	StringData *_strings;
+	Room *_room;
+
+	void detectGame();
+public:
+	LureEngine(GameDetector *detector, OSystem *system);
+	~LureEngine();
+	
+	virtual int init(GameDetector &detector);
+	virtual int go();
+	virtual void errorString(const char *buf_input, char *buf_output);
+	void quitGame();
+
+	uint32 features() { return _features; }
+	uint8 game() { return _game; }
+	Disk &disk() { return *_disk; }
+};
+
+} // End of namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/lure.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/luredefs.h
===================================================================
--- scummvm/trunk/lure/luredefs.h	                        (rev 0)
+++ scummvm/trunk/lure/luredefs.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,183 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __luredefs_h__
+#define __luredefs_h__
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "common/list.h"
+
+namespace Lure {
+
+#define LURE_DEBUG 1
+
+#define READ_LE_INT16(x) (int16) READ_LE_UINT16(x)
+#define READ_LE_INT32(x) (int32) READ_LE_UINT32(x)
+
+enum {
+	GF_FLOPPY	= 1 <<  0,
+	GF_ENGLISH	= 1 <<  1,
+	GF_LNGUNK	= 1 << 15
+};
+
+enum {
+	GI_LURE = 0
+};
+
+enum Action {
+	GET = 1,
+	DROP = 0,
+	PUSH = 3,
+	PULL = 4,
+	OPERATE = 5,
+	OPEN = 6,
+	CLOSE = 7,
+	LOCK = 8,
+	UNLOCK = 9,
+	USE = 10,
+	GIVE = 11,
+	TALK_TO = 12,
+	TELL = 13,
+	BUY = 14,
+	LOOK = 15,
+	LOOK_AT = 16,
+	LOOK_THROUGH = 17,
+	ASK = 18,
+	EAT = 0,
+	DRINK = 20,
+	STATUS = 21,
+	GO_TO = 22,
+	RETURN = 23,
+	BRIBE = 24,
+	EXAMINE = 25,
+	NONE = 0xffff
+};
+
+// Basic game dimensions
+#define FULL_SCREEN_WIDTH 320
+#define FULL_SCREEN_HEIGHT 200
+#define GAME_COLOURS 256
+#define SCREEN_SIZE (FULL_SCREEN_HEIGHT * FULL_SCREEN_WIDTH)
+
+#define SUPPORT_FILENAME "lure.dat"
+#define LURE_DAT_MAJOR 1
+#define LURE_DAT_MINOR 1
+
+// Some resources include multiple packed palettes of 64 entries each
+#define SUB_PALETTE_SIZE 64
+// Palette resources have 220 palette entries
+#define RES_PALETTE_ENTRIES 220
+// Palette colour increment amouns for palette fade in/outs
+#define PALETTE_FADE_INC_SIZE 4
+
+// Specifies the maximum buffer sized allocated for decoding animation data
+#define MAX_ANIM_DECODER_BUFFER_SIZE 200000
+
+#define MAX_DESC_SIZE 1024
+#define MAX_HOTSPOT_NAME_SIZE 80
+#define MAX_ACTION_NAME_SIZE 15
+
+// Menubar constants
+#define MENUBAR_Y_SIZE 8
+
+// Cursor definitions
+#define CURSOR_WIDTH 16
+#define CURSOR_HEIGHT 16
+#define CURSOR_SIZE 256
+#define  CURSOR_RESOURCE_ID 1
+#define CURSOR_ARROW 0
+#define CURSOR_DISK 1
+#define CURSOR_TIME_START 2
+#define CURSOR_TIME_END 9
+#define CURSOR_CROSS 10
+#define CURSOR_MENUBAR 17
+
+// Font details
+#define FONT_RESOURCE_ID 4
+#define NUM_CHARS_IN_FONT 122
+#define FONT_WIDTH 8
+#define FONT_HEIGHT 8
+
+// Menu constants
+#define MENUBAR_SELECTED_COLOUR 0xf7
+#define MENU_UNSELECTED_COLOUR 0xe2
+#define MENU_SELECTED_COLOUR 0xe3
+#define MENUITEM_NONE 0
+#define MENUITEM_CREDITS 1 
+#define MENUITEM_RESTART_GAME 2 
+#define MENUITEM_SAVE_GAME 3 
+#define MENUITEM_RESTORE_GAME 4 
+#define MENUITEM_QUIT 5 
+#define MENUITEM_TEXT_SPEED 6 
+#define MENUITEM_SOUND 7
+
+// Mouse change needed to change an item in a popup menu
+#define POPMENU_CHANGE_SENSITIVITY 5
+
+// Dialog related defines
+#define DIALOG_EDGE_SIZE 9
+#define	DIALOG_TEXT_COLOUR 0xe2
+#define DIALOG_WHITE_COLOUR 0xe3
+#define INFO_DIALOG_X 69
+#define INFO_DIALOG_Y 61
+#define INFO_DIALOG_WIDTH 191
+
+// Strings defines
+#define STRINGS_RESOURCE_ID 0x10
+#define STRINGS_2_RESOURCE_ID 0x11
+#define STRINGS_3_RESOURCE_ID 0x12
+#define STRING_ID_RANGE 0x7d0
+#define STRING_ID_UPPER 0xfa0
+
+// Custom resources stored in lure.dat
+#define GAME_PALETTE_RESOURCE_ID 0x3f01
+#define ALT_PALETTE_RESOURCE_ID 0x3f02
+#define DIALOG_RESOURCE_ID 0x3f03
+#define ROOM_DATA_RESOURCE_ID 0x3f04
+#define HOTSPOT_DATA_RESOURCE_ID 0x3f05
+#define HOTSPOT_OVERRIDE_DATA_RESOURCE_ID 0x3f06
+#define ROOM_EXITS_RESOURCE_ID 0x3f07
+#define ROOM_EXIT_JOINS_RESOURCE_ID 0x3f08
+#define ANIM_DATA_RESOURCE_ID 0x3f09
+#define SCRIPT_DATA_RESOURCE_ID 0x3f0a
+#define SCRIPT2_DATA_RESOURCE_ID 0x3f0b
+#define HOTSPOT_SCRIPT_LIST_RESOURCE_ID 0x3f0c
+#define	MESSAGES_LIST_RESOURCE_ID 0x3f0d
+#define ACTION_LIST_RESOURCE_ID 0x3f0e
+
+// Script constants
+#define STARTUP_SCRIPT 0x23FC
+
+// Miscellaneous resources
+#define CREDITS_RESOURCE_ID 0x7800
+#define NAMES_RESOURCE_ID 9
+#define PLAYER_ID 0x3E8
+#define RATPOUCH_ID 0x3E9
+#define START_NONVISUAL_HOTSPOT_ID 0x7530
+
+// Milliseconds delay between game frames
+#define GAME_FRAME_DELAY 100
+
+} // End of namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/luredefs.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/memory.cpp
===================================================================
--- scummvm/trunk/lure/memory.cpp	                        (rev 0)
+++ scummvm/trunk/lure/memory.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,107 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/memory.h"
+#include "common/file.h"
+
+namespace Lure {
+
+MemoryBlock *Memory::allocate(uint32 size) {
+	MemoryBlock *block = new MemoryBlock(size);
+	return block;
+}
+
+MemoryBlock *Memory::duplicate(MemoryBlock *src) {
+	MemoryBlock *block = new MemoryBlock(src);
+	return block;
+}
+
+uint8 *Memory::alloc(uint32 size) {
+	return (uint8 *) malloc(size);
+}
+
+void Memory::dealloc(uint8 *block) {
+	free(block);
+}
+
+/*--------------------------------------------------------------------------*/
+
+MemoryBlock::MemoryBlock(uint32 size1) {
+	_data = (uint8 *) malloc(size1);
+	if (!_data) error ("Failed allocating memory block");
+	_size = size1;
+}
+
+MemoryBlock::MemoryBlock(MemoryBlock *src) {
+	_size = src->size();
+	_data = (uint8 *) malloc(_size);
+	if (!_data) error ("Failed allocating memory block");
+	memcpy(_data, src->data(), _size);
+}
+
+MemoryBlock::~MemoryBlock() {
+	free(_data);
+}
+
+void MemoryBlock::empty() {
+	::memset(_data, 0, _size);
+}
+
+void MemoryBlock::memset(int c, size_t startIndex, size_t num) {
+	byte *p = _data + startIndex;
+	::memset(p, c, num);
+}
+
+void MemoryBlock::copyFrom(MemoryBlock *src) {
+	copyFrom(src, 0, 0, src->size());
+}
+
+void MemoryBlock::copyFrom(MemoryBlock *src, uint32 srcPos, uint32 destPos, uint32 srcLen) {
+	if ((srcPos + srcLen > src->size()) || (destPos + srcLen > size()))
+		error("Memory block overrun in block copy");
+
+	uint8 *pDest = _data + destPos;
+	uint8 *pSrc = src->data() + srcPos;
+	memcpy(pDest, pSrc, srcLen);
+}
+
+void MemoryBlock::copyFrom(const byte *src, uint32 srcPos, uint32 destPos, uint32 srcLen) {
+	byte *pDest = _data + destPos;
+	const byte *pSrc = src + srcPos;
+	memcpy(pDest, pSrc, srcLen);
+}
+
+void MemoryBlock::reallocate(uint32 size1) {
+	_size = size1;
+	_data = (byte *) realloc(_data, size1);
+	if (!_data) error ("Failed reallocating memory block");
+}
+
+void MemoryBlock::saveToFile(const Common::String &filename) {
+	Common::File *f = new Common::File();
+	f->open(filename.c_str(), Common::File::kFileWriteMode);
+	f->write(_data, _size);
+	f->close();
+	delete f;
+}
+
+} // end of namespace Lure


Property changes on: scummvm/trunk/lure/memory.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/memory.h
===================================================================
--- scummvm/trunk/lure/memory.h	                        (rev 0)
+++ scummvm/trunk/lure/memory.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,63 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __lure_memory_h__
+#define __lure_memory_h__
+
+#include "common/stdafx.h"
+#include "common/system.h"
+#include "common/str.h"
+
+namespace Lure {
+
+class MemoryBlock {
+private:
+	byte *_data;
+	uint32 _size;
+public:
+	MemoryBlock(uint32 size);
+	MemoryBlock(MemoryBlock *src);
+	~MemoryBlock();
+
+	byte *data() { return _data; }
+	uint32 size() { return _size; }
+
+	void empty();
+	void memset(int c, size_t startIndex, size_t num);
+	void copyFrom(MemoryBlock *src);
+	void copyFrom(MemoryBlock *src, uint32 srcPos, uint32 destPos, uint32 srcLen);
+	void copyFrom(const byte *src, uint32 srcPos, uint32 destPos, uint32 srcLen);
+	void reallocate(uint32 size);
+	void saveToFile(const Common::String &filename);
+};
+
+class Memory {
+public:
+	static MemoryBlock *allocate(uint32 size);
+	static MemoryBlock *duplicate(MemoryBlock *src);
+	static uint8 *alloc(uint32 size);
+	static void dealloc(uint8 *block);
+};
+
+} // end of namspace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/memory.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/menu.cpp
===================================================================
--- scummvm/trunk/lure/menu.cpp	                        (rev 0)
+++ scummvm/trunk/lure/menu.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,415 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/menu.h"
+#include "lure/luredefs.h"
+#include "lure/decode.h"
+#include "lure/surface.h"
+#include "lure/system.h"
+#include "lure/res_struct.h"
+#include "lure/res.h"
+#include "lure/strings.h"
+
+namespace Lure {
+
+MenuRecord::MenuRecord(uint16 hsxstartVal, uint16 hsxendVal, uint16 xstartVal, 
+					   uint16 widthVal, const char *strings) {
+	_xstart = xstartVal; _width = widthVal;
+	_hsxstart = hsxstartVal; _hsxend = hsxendVal;
+
+	// Figure out the number of entries
+	const char *sPtr = strings;
+	_numEntries = 1;
+	while ((sPtr = strchr(sPtr, ',')) != NULL) {
+		++_numEntries;
+		++sPtr;
+	}
+
+	// Set up the list of entries
+	char *sCopy = strdup(strings);
+	char *s;
+	_entries = (char **) malloc(sizeof(char *) * _numEntries);
+	uint8 index = 0;
+	s = sCopy;
+	while (s != NULL) {
+		_entries[index++] = s;
+		s = strchr(s, ',');
+		if (s != NULL) *s++ = '\0'; // replace comma with NULL
+	}
+}
+
+MenuRecord::~MenuRecord() {
+	delete _entries[0];	// Delete string data for all the menu items
+	free(_entries);		// Free the list
+}
+
+char *MenuRecord::getEntry(uint8 index) {
+	if (index >= _numEntries) error("Invalid menuitem index specified: %d", index);
+	return _entries[index];
+}
+
+/*--------------------------------------------------------------------------*/
+
+static Menu *int_menu = NULL;
+
+Menu::Menu(OSystem &system): _system(system), _screen(Screen::getReference()),
+	_events(Events::getReference()), _mouse(Mouse::getReference()) {
+	int_menu = this;
+
+	MemoryBlock *res = Disk::getReference().getEntry(5);
+	PictureDecoder decoder;
+	_menu = decoder.decode(res, SCREEN_SIZE);
+	delete res;
+
+	_menus[0] = new MenuRecord(40, 87, 20, 80, "Credits");
+	_menus[1] = new MenuRecord(127, 179, 100, 120, "Restart game,Save game,Restore game");
+	_menus[2] = new MenuRecord(224, 281, 210, 105, "Quit,Slow Text\x8b,Sound on ");
+	_selectedMenu = NULL;
+}
+
+Menu::~Menu() {
+	for (int ctr=0; ctr<NUM_MENUS; ++ctr) delete _menus[ctr];
+	delete _menu;
+}
+
+Menu &Menu::getReference() {
+	return *int_menu;
+}
+
+uint8 Menu::execute() {
+	_mouse.setCursorNum(CURSOR_ARROW);
+	_system.copyRectToScreen(_menu->data(), FULL_SCREEN_WIDTH, 0, 0, FULL_SCREEN_WIDTH, MENUBAR_Y_SIZE);
+	_system.updateScreen();
+
+	_selectedMenu = NULL;
+	_surfaceMenu = NULL;
+	_selectedIndex = 0;
+
+	while (_mouse.lButton()) {
+		if (_events.pollEvent()) {
+			// handle events
+		}
+
+		if (_mouse.y() < MENUBAR_Y_SIZE)
+		{
+			MenuRecord *p = getMenuAt(_mouse.x());
+
+			if (_selectedMenu != p) {
+				// If necessary, remove prior menu
+				if (_selectedMenu) {
+					toggleHighlight(_selectedMenu);
+					_screen.updateArea(_selectedMenu->xstart(), MENUBAR_Y_SIZE,
+						_surfaceMenu->width(), _surfaceMenu->height());
+					delete _surfaceMenu;
+					_surfaceMenu = NULL;
+					_selectedIndex = 0;
+				}						
+
+				_selectedMenu = p;
+
+				// If a new menu is selected, show it
+				if (_selectedMenu) {
+					toggleHighlight(_selectedMenu);
+					_surfaceMenu = Surface::newDialog(
+						_selectedMenu->width(), _selectedMenu->numEntries(), 
+						_selectedMenu->entries(), false, MENU_UNSELECTED_COLOUR);
+					_surfaceMenu->copyToScreen(_selectedMenu->xstart(), MENUBAR_Y_SIZE);
+				}
+
+				_system.copyRectToScreen(_menu->data(), FULL_SCREEN_WIDTH, 0, 0, FULL_SCREEN_WIDTH, MENUBAR_Y_SIZE);
+				_system.updateScreen();
+			}
+		}
+
+		// Check for changing selected index
+		uint8 index = getIndexAt(_mouse.x(), _mouse.y());
+		if (index != _selectedIndex) {
+			if (_selectedIndex != 0) toggleHighlightItem(_selectedIndex);
+			_selectedIndex = index;
+			if (_selectedIndex != 0) toggleHighlightItem(_selectedIndex);
+		}
+	}
+
+	if (_surfaceMenu) delete _surfaceMenu;
+
+	// Deselect the currently selected menu header
+	if (_selectedMenu) 
+		toggleHighlight(_selectedMenu);
+
+	// Restore the previous screen
+	_screen.update();
+	
+	if (_selectedMenu == NULL) return MENUITEM_NONE;
+	else if (_selectedMenu == _menus[0]) return MENUITEM_CREDITS;
+	else if (_selectedMenu == _menus[1]) {
+		switch (_selectedIndex) {
+			case 1: return MENUITEM_RESTART_GAME;
+			case 2: return MENUITEM_SAVE_GAME;
+			case 3: return MENUITEM_RESTORE_GAME;
+		}
+	} else {
+		switch (_selectedIndex) {
+			case 1: return MENUITEM_QUIT;
+			case 2: return MENUITEM_TEXT_SPEED;
+			case 3: return MENUITEM_SOUND;
+		}
+	}
+	return MENUITEM_NONE;
+}	
+
+MenuRecord *Menu::getMenuAt(int x) {
+	for (int ctr = 0; ctr < NUM_MENUS; ++ctr)
+		if ((x >= _menus[ctr]->hsxstart()) && (x <= _menus[ctr]->hsxend())) 
+			return _menus[ctr];
+
+	return NULL;
+}
+
+uint8 Menu::getIndexAt(uint16 x, uint16 y) {
+	if (!_selectedMenu) return 0;
+
+	int ys = MENUBAR_Y_SIZE + DIALOG_EDGE_SIZE + 3;
+	int ye = MENUBAR_Y_SIZE + _surfaceMenu->height() - DIALOG_EDGE_SIZE - 3;
+	if ((y < ys) || (y > ye)) return 0;
+
+	uint16 yRelative = y - ys;
+	uint8 index = (uint8) (yRelative / 8) + 1;
+	if (index > _selectedMenu->numEntries()) index = _selectedMenu->numEntries();
+	return index;
+}
+
+void Menu::toggleHighlight(MenuRecord *menuRec) {
+	byte *addr = _menu->data();
+
+	for (uint16 y=0; y<MENUBAR_Y_SIZE; ++y) {
+		for (uint16 x=menuRec->hsxstart(); x<=menuRec->hsxend(); ++x) {
+			if (addr[x] == MENUBAR_SELECTED_COLOUR) addr[x] = 0;
+			else if (addr[x] == 0) addr[x] = MENUBAR_SELECTED_COLOUR;
+		}
+		addr += FULL_SCREEN_WIDTH;
+	}
+}
+
+void Menu::toggleHighlightItem(uint8 index) {
+	byte *p = _surfaceMenu->data().data() + (DIALOG_EDGE_SIZE + 3 + 
+		((index - 1) * 8)) * _surfaceMenu->width();
+	uint32 numBytes = 8 * _surfaceMenu->width();
+
+	while (numBytes-- > 0) {
+		if (*p == MENU_UNSELECTED_COLOUR) *p = MENU_SELECTED_COLOUR;
+		else if (*p == MENU_SELECTED_COLOUR) *p = MENU_UNSELECTED_COLOUR;
+		++p;
+	}
+
+	_surfaceMenu->copyToScreen(_selectedMenu->xstart(), MENUBAR_Y_SIZE);
+}
+
+/*--------------------------------------------------------------------------*/
+
+uint16 PopupMenu::ShowInventory() {
+	Resources &rsc = Resources::getReference();
+	StringData &strings = StringData::getReference();
+
+	uint16 numItems = rsc.numInventoryItems();
+	uint16 itemCtr = 0;
+	char **itemNames = (char **) Memory::alloc(sizeof(char *) * numItems);
+	uint16 *idList = (uint16 *) Memory::alloc(sizeof(uint16) * numItems);
+
+	HotspotDataList::iterator i;
+	for (i = rsc.hotspotData().begin(); i != rsc.hotspotData().end(); ++i) {
+		HotspotData *hotspot = *i;
+		if (hotspot->roomNumber == PLAYER_ID) {
+			idList[itemCtr] = hotspot->hotspotId;
+			char *hotspotName = itemNames[itemCtr++] = (char *) malloc(MAX_HOTSPOT_NAME_SIZE);
+			strings.getString(hotspot->nameId, hotspotName, NULL, NULL);
+		}
+	}
+	
+	uint16 result = Show(numItems, (const char **) itemNames);
+	if (result != 0xffff) result = idList[result];
+
+	for (itemCtr = 0; itemCtr < numItems; ++itemCtr)
+		free(itemNames[itemCtr]);
+
+	delete itemNames;
+	delete idList;
+	return result;
+}
+
+Action PopupMenu::Show(uint32 actionMask) {
+	int numEntries = 0;
+	uint32 v = actionMask;
+	int index;
+
+	for (index = 1; index <= EXAMINE; ++index, v >>= 1) {
+		if (v & 1) ++numEntries;
+	}
+
+	const char **strList = (const char **) Memory::alloc(sizeof(char *) * numEntries);
+
+	v = actionMask;
+	int strIndex = 0;
+	for (index=1; index<=EXAMINE; ++index, v >>= 1) {
+		if (v & 1) 
+			strList[strIndex++] = actionList[index];
+	}
+
+	uint16 result = Show(numEntries, strList);
+	
+	if (result == 0xffff) return NONE;
+
+	v = actionMask;
+	for (index = 1; index <= EXAMINE; ++index, v >>= 1) {
+		if (v & 1) 
+			if (result-- == 0) return (Action) index;
+	}
+
+	delete strList;
+	return NONE;
+}
+
+Action PopupMenu::Show(int numEntries, Action *actions) {
+	const char **strList = (const char **) Memory::alloc(sizeof(char *) * numEntries);
+	Action *actionPtr = actions;
+	for (int index = 0; index < numEntries; ++index)
+		strList[index] = actionList[*actionPtr++];
+	uint16 result = Show(numEntries, strList);
+	
+	delete strList;
+	if (result == 0xffff) return NONE;
+	else return actions[result];
+}
+
+uint16 PopupMenu::Show(int numEntries, const char *actions[]) {
+	if (numEntries == 0) return 0xffff;
+	Events &e = Events::getReference();
+	Mouse &mouse = Mouse::getReference();
+	OSystem &system = System::getReference();
+	Screen &screen = Screen::getReference();
+	Rect r;
+
+	mouse.cursorOff();
+	uint16 oldX = mouse.x();
+	uint16 oldY = mouse.y();
+	const uint16 yMiddle = FULL_SCREEN_HEIGHT / 2;
+	mouse.setPosition(FULL_SCREEN_WIDTH / 2, yMiddle);
+
+	// Round up number of lines in dialog to next odd number
+	uint16 numLines = (numEntries / 2) * 2 + 1;
+	if (numLines > 5) numLines = 5;
+
+	// Figure out the character width
+	uint16 numCols = 0;
+	for (int ctr = 0; ctr < numEntries; ++ctr) {
+		int len = strlen(actions[ctr]);
+		if (len > numCols)
+			numCols = len;
+	}
+
+	// Create the dialog surface
+	Surface *s = new Surface(DIALOG_EDGE_SIZE * 2 + numCols * FONT_WIDTH, 
+		DIALOG_EDGE_SIZE * 2 + numLines * FONT_HEIGHT);
+	s->createDialog();
+
+	int selectedIndex = 0;
+	bool refreshFlag = true;
+	r.left = DIALOG_EDGE_SIZE;
+	r.right = s->width() - DIALOG_EDGE_SIZE - 1;
+	r.top = DIALOG_EDGE_SIZE;
+	r.bottom = s->height() - DIALOG_EDGE_SIZE - 1;
+
+	for (;;) {
+		if (refreshFlag) {
+			// Set up the contents of the menu
+			s->fillRect(r, 0);
+
+			for (int index = 0; index < numLines; ++index) {
+				int actionIndex = selectedIndex - (numEntries / 2) + index;
+				if ((actionIndex >= 0) && (actionIndex < numEntries)) {
+					s->writeString(DIALOG_EDGE_SIZE, DIALOG_EDGE_SIZE + index * FONT_HEIGHT,
+						actions[actionIndex], true, 
+						(index == (numLines / 2)) ? MENU_SELECTED_COLOUR : MENU_UNSELECTED_COLOUR,
+						false);
+				}
+			}
+
+			s->copyToScreen(0, yMiddle-(s->height() / 2));
+			system.updateScreen();
+			refreshFlag = false;
+		}
+
+		if (e.pollEvent()) {
+			if (e.quitFlag) {
+				selectedIndex = 0xffff;
+				break;
+			}
+
+			if (e.type() == OSystem::EVENT_KEYDOWN) {
+				byte ch = e.event().kbd.ascii;
+				uint16 keycode = e.event().kbd.keycode;
+
+				if (((keycode == 0x108) || (keycode == 0x111)) && (selectedIndex > 0)) {
+					--selectedIndex;
+					refreshFlag = true;
+				} else if (((keycode == 0x102) || (keycode == 0x112)) && 
+						(selectedIndex < numEntries-1)) {
+					++selectedIndex;
+					refreshFlag = true;
+				} else if ((ch == '\xd') || (keycode == 0x10f)) {
+					break;
+				} else if (ch == '\x1b') {
+					selectedIndex = 0xffff;
+					break;
+				}
+
+			} else if (e.type() == OSystem::EVENT_MOUSEMOVE) {
+				if ((mouse.y() < yMiddle) && (selectedIndex > 0) && 
+					(yMiddle-mouse.y() >= POPMENU_CHANGE_SENSITIVITY)) {
+					--selectedIndex;
+					mouse.setPosition(FULL_SCREEN_WIDTH / 2, yMiddle);
+					refreshFlag = true;
+				} else if ((mouse.y() > yMiddle) && (selectedIndex < numEntries - 1) &&
+					(mouse.y()-yMiddle >= POPMENU_CHANGE_SENSITIVITY)) {
+					++selectedIndex;
+					mouse.setPosition(FULL_SCREEN_WIDTH/2, yMiddle);
+					refreshFlag = true;
+				}
+
+			} else if (e.type() == OSystem::EVENT_LBUTTONDOWN) {
+				mouse.waitForRelease();
+				break;
+
+			} else if (e.type() == OSystem::EVENT_RBUTTONDOWN) {
+				mouse.waitForRelease();
+				selectedIndex = 0xffff;
+				break;
+			}
+		}
+	}
+
+	mouse.setPosition(oldX, oldY);
+	mouse.cursorOn();
+	screen.update();
+	return selectedIndex;
+}
+
+} // end of namespace Lure


Property changes on: scummvm/trunk/lure/menu.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/menu.h
===================================================================
--- scummvm/trunk/lure/menu.h	                        (rev 0)
+++ scummvm/trunk/lure/menu.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,92 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __lure_menu_h__
+#define __lure_menu_h__
+
+#include "common/stdafx.h"
+#include "common/str.h"
+#include "lure/luredefs.h"
+#include "lure/disk.h"
+#include "lure/screen.h"
+#include "lure/surface.h"
+#include "lure/events.h"
+
+#define NUM_MENUS 3
+
+namespace Lure {
+
+class MenuRecord {
+private:
+	uint16 _xstart, _width;
+	uint16 _hsxstart, _hsxend;
+	char **_entries;
+	uint8 _numEntries;
+public:
+	MenuRecord(uint16 hsxstartVal, uint16 hsxendVal, uint16 xstartVal, 
+		uint16 widthVal, const char *strings); 
+	~MenuRecord();
+
+	uint16 xstart() { return _xstart; }
+	uint16 width() { return _width; }
+	uint16 hsxstart() { return _hsxstart; }
+	uint16 hsxend() { return _hsxend; }
+	uint8 numEntries() { return _numEntries; }
+	char **entries() { return _entries; }
+	char *getEntry(uint8 index);
+};
+
+class Menu {
+private:
+	OSystem &_system;
+	Screen &_screen;
+	Events &_events;
+	Mouse &_mouse;
+	MemoryBlock *_menu;
+	MenuRecord *_menus[NUM_MENUS];
+	MenuRecord *_selectedMenu;
+	Surface *_surfaceMenu;
+	uint8 _selectedIndex;
+
+	MenuRecord *getMenuAt(int x);
+	uint8 getIndexAt(uint16 x, uint16 y);	
+	void toggleHighlight(MenuRecord *menuRec);
+	void toggleHighlightItem(uint8 index);
+public:
+	Menu(OSystem &system);
+	~Menu();
+	static Menu &getReference();
+	uint8 execute();
+	MenuRecord &getMenu(uint8 index) { return *_menus[index]; }
+};
+
+class PopupMenu {
+public:
+	static Action Show(uint32 actionMask);
+	static Action Show(int numEntries, Action *actions);
+	static uint16 Show(int numEntries, const char *actions[]);
+	static uint16 ShowInventory();
+};
+
+} // End of namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/menu.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/module.mk
===================================================================
--- scummvm/trunk/lure/module.mk	                        (rev 0)
+++ scummvm/trunk/lure/module.mk	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,36 @@
+MODULE := lure
+
+MODULE_OBJS := \
+	lure/animseq.o \
+	lure/debug-input.o \
+	lure/debug-methods.o \
+	lure/decode.o \
+	lure/disk.o \
+	lure/events.o \
+	lure/game.o \
+	lure/hotspots.o \
+	lure/intro.o \
+	lure/lure.o \
+	lure/memory.o \
+	lure/menu.o \
+	lure/palette.o \
+	lure/res.o \
+	lure/res_struct.o \
+	lure/room.o \
+	lure/screen.o \
+	lure/scripts.o \
+	lure/strings.o \
+	lure/surface.o \
+	lure/system.o
+
+MODULE_DIRS += \
+	lure
+
+# This module can be built as a plugin
+ifdef BUILD_PLUGINS
+PLUGIN := 1
+endif
+
+# Include common rules 
+include $(srcdir)/common.rules
+

Added: scummvm/trunk/lure/palette.cpp
===================================================================
--- scummvm/trunk/lure/palette.cpp	                        (rev 0)
+++ scummvm/trunk/lure/palette.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,142 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/palette.h"
+#include "common/util.h"
+
+namespace Lure {
+
+// Constructor
+// Defaults the palette to a full 256 entry palette
+
+Palette::Palette() {
+	_numEntries = GAME_COLOURS;
+	_palette = Memory::allocate(_numEntries * 4);
+	_palette->empty();
+}
+
+// Consructor
+// Sets up a palette with the given number of entries and a copy of the passed data
+
+Palette::Palette(uint8 numEntries1, const byte *data1, PaletteSource paletteSource) {
+	_numEntries = numEntries1;
+	_palette = Memory::allocate(_numEntries * 4);
+
+	if (data1) {
+		if (paletteSource == RGB64) 
+			convertPalette(data1, _numEntries);
+		else
+			_palette->copyFrom(data1, 0, 0, _numEntries * 4);
+	} else {
+		// No data provided, set a null palette
+		_palette->empty();
+	}
+}
+
+// Constructor
+// Makes a copy of a passed palette object
+
+Palette::Palette(Palette &src) {
+	_numEntries = src.numEntries();
+	_palette = Memory::duplicate(src._palette);
+}
+
+// Constructor
+// Loads a palette from a resource
+
+Palette::Palette(uint16 resourceId) {
+	Disk &d = Disk::getReference();
+
+	MemoryBlock *srcData = d.getEntry(resourceId); 
+	if (((srcData->size() % 3) != 0) || ((srcData->size() / 3) > GAME_COLOURS))
+		error("Specified resource %d is not a palette", resourceId);
+
+	_numEntries = srcData->size() / 3;
+	_palette = Memory::allocate(_numEntries * 4);
+	convertPalette(srcData->data(), _numEntries);
+	delete srcData;
+}
+
+void Palette::convertPalette(const byte *palette1, uint16 numEntries1) {
+	byte *pDest = _palette->data();
+	const byte *pSrc = palette1;
+
+	while (numEntries1-- > 0) {
+		*pDest++ = (pSrc[0] << 2) + (pSrc[0] >> 4);
+		*pDest++ = (pSrc[1] << 2) + (pSrc[1] >> 4);
+		*pDest++ = (pSrc[2] << 2) + (pSrc[2] >> 4);
+		*pDest++ = 0;
+		pSrc += 3;
+	}
+}
+
+void Palette::setEntry(uint8 index, uint32 value) {
+	if (index >= numEntries()) error("Invalid palette index: %d", index);
+	uint32 *entry = (uint32 *) (data() + index * 4);
+	*entry = value;
+}
+
+uint32 Palette::getEntry(uint8 index) {
+	if (index >= numEntries()) error("Invalid palette index: %d", index);
+	uint32 *entry = (uint32 *) (data() + index * 4);
+	return *entry;
+}
+
+void Palette::copyFrom(Palette *src) { 
+	_palette->copyFrom(src->palette());
+}
+
+/*--------------------------------------------------------------------------*/
+
+PaletteCollection::PaletteCollection(uint16 resourceId) {
+	Disk &d = Disk::getReference();
+	MemoryBlock *resource = d.getEntry(resourceId);
+	uint32 palSize;
+	uint8 *data = resource->data();
+
+	if (resource->size() % (SUB_PALETTE_SIZE * 3) != 0)
+		error("Resource #%d is not a valid palette set", resourceId);
+
+	palSize = SUB_PALETTE_SIZE * 3;
+	_numPalettes = resource->size() / palSize;
+
+	_palettes = (Palette **) Memory::alloc(_numPalettes * sizeof(Palette *));
+	for (uint8 paletteCtr = 0; paletteCtr < _numPalettes; ++paletteCtr, data += palSize)
+		_palettes[paletteCtr] = new Palette(SUB_PALETTE_SIZE, data, RGB64);
+
+	delete resource;
+}
+
+PaletteCollection::~PaletteCollection() {
+	for (int paletteCtr = 0; paletteCtr < _numPalettes; ++paletteCtr)
+		delete _palettes[paletteCtr];
+	free(_palettes);
+}
+
+
+Palette &PaletteCollection::getPalette(uint8 paletteNum) {
+	if (paletteNum >= _numPalettes)
+		error("Invalid palette index specified");
+	return *_palettes[paletteNum];
+}
+
+} // end of namespace Lure


Property changes on: scummvm/trunk/lure/palette.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/palette.h
===================================================================
--- scummvm/trunk/lure/palette.h	                        (rev 0)
+++ scummvm/trunk/lure/palette.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,68 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __lure_palette_h__
+#define __lure_palette_h__
+
+#include "lure/luredefs.h"
+#include "lure/disk.h"
+#include "lure/memory.h"
+
+namespace Lure {
+
+enum PaletteSource {RGB, RGB64};
+
+class Palette {
+private:
+	MemoryBlock *_palette;
+	uint16 _numEntries;
+
+	void convertPalette(const byte *palette, uint16 numEntries);
+public:
+	Palette();
+	Palette(uint8 numEntries, const byte *data, PaletteSource paletteSource);
+	Palette(Palette &src);
+	Palette(uint16 resourceId);
+
+	uint8 *data() { return _palette->data(); }
+	MemoryBlock *palette() { return _palette; }
+	uint16 numEntries() { return _palette->size() / 4; }
+	void setEntry(uint8 index, uint32 value);
+	uint32 getEntry(uint8 index);
+	void copyFrom(Palette *src); 
+};
+
+class PaletteCollection {
+private:
+	Palette **_palettes;
+	uint8 _numPalettes;
+public:
+	PaletteCollection(uint16 resourceId);
+	~PaletteCollection();
+
+	uint8 numPalettes() { return _numPalettes; }
+	Palette &getPalette(uint8 paletteNum);
+};
+
+} // end of namspace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/palette.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/res.cpp
===================================================================
--- scummvm/trunk/lure/res.cpp	                        (rev 0)
+++ scummvm/trunk/lure/res.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,399 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/res.h"
+#include "lure/disk.h"
+#include "lure/scripts.h"
+#include "lure/screen.h"
+
+namespace Lure {
+
+static Resources *int_resources = NULL;
+
+Resources &Resources::getReference() {
+	return *int_resources;
+}
+
+Resources::Resources() {
+	int_resources = this;
+	reloadData();
+}
+
+Resources::~Resources() {
+	// Delete any unremoved active hotspots
+	freeData();
+}
+
+void Resources::freeData() {
+	_activeHotspots.clear();
+	_roomData.clear();
+	_hotspotData.clear();
+	_hotspotOverrides.clear();
+	_animData.clear();
+	_exitJoins.clear();
+	_delayList.clear();
+
+	delete _paletteSubset;
+	delete _scriptData;
+	delete _script2Data;
+	delete _hotspotScriptData;
+	delete _messagesData;
+}
+
+struct AnimRecordTemp {
+	uint16 *offset;
+	MovementDataList *list;
+};
+
+void Resources::reloadData() {
+	Disk &d = Disk::getReference();
+	MemoryBlock *mb;
+	uint16 *offset, offsetVal;
+	int ctr;
+
+	// Get the palette subset data
+	_paletteSubset = new Palette(ALT_PALETTE_RESOURCE_ID);
+
+	// Load room data 
+	mb = d.getEntry(ROOM_DATA_RESOURCE_ID);
+	offset = (uint16 *) mb->data();
+	for (ctr = 0; READ_LE_UINT16(offset) != 0xffff; ++ctr, ++offset) {
+		offsetVal = READ_LE_UINT16(offset);
+		if (offsetVal != 0) {
+			// Get room resource
+			RoomResource *rec = (RoomResource *) (mb->data() + offsetVal);
+			RoomData *newEntry = new RoomData(rec);
+			_roomData.push_back(newEntry);
+
+			if (rec->numExits > 0) {
+				RoomExitResource *exitRes = (RoomExitResource *)
+					(mb->data() + offsetVal + sizeof(RoomResource));
+
+				for (uint16 exitCtr = 0; exitCtr < rec->numExits; ++exitCtr, ++exitRes) {
+					RoomExitData *exit = new RoomExitData(exitRes);
+					newEntry->exits.push_back(exit);
+				}
+			}
+		}
+	}
+	delete mb;
+
+	// Load room exits
+	mb = d.getEntry(ROOM_EXITS_RESOURCE_ID);
+	ctr = 0;
+	for (;;) {
+		offsetVal = READ_LE_UINT16(mb->data() + (ctr * 2));
+		if (offsetVal == 0xffff) break;
+		
+		if (offsetVal != 0) {
+			RoomData *room = getRoom(ctr);
+			if (room) {
+				RoomExitHotspotRecord *re = (RoomExitHotspotRecord *) 
+					(mb->data() + offsetVal);
+				while (READ_LE_UINT16(&re->hotspotId) != 0xffff) {
+					RoomExitHotspotData *newEntry = new RoomExitHotspotData(re);
+					room->exitHotspots.push_back(newEntry);
+					++re;
+				}
+			}
+		}
+		++ctr;
+	}
+	delete mb;
+
+	// Load room joins
+	mb = d.getEntry(ROOM_EXIT_JOINS_RESOURCE_ID);
+	RoomExitJoinRecord *joinRec = (RoomExitJoinRecord *) mb->data();
+	while (READ_LE_UINT16(&joinRec->hotspot1Id) != 0xffff) {
+		RoomExitJoinData *newEntry = new RoomExitJoinData(joinRec);
+		_exitJoins.push_back(newEntry);
+		++joinRec;
+	}
+	delete mb;
+
+	// Load the hotspot list
+	mb = d.getEntry(HOTSPOT_DATA_RESOURCE_ID);
+	HotspotResource *hsRec = (HotspotResource *) mb->data();
+	while (READ_LE_UINT16(&hsRec->hotspotId) != 0xffff) {
+		HotspotData *newEntry = new HotspotData(hsRec);
+		_hotspotData.push_back(newEntry);
+		++hsRec;
+	}
+	delete mb;
+
+	// Load the hotspot overrides
+	mb = d.getEntry(HOTSPOT_OVERRIDE_DATA_RESOURCE_ID);
+	HotspotOverrideResource *hsoRec = (HotspotOverrideResource *) mb->data();
+	while (READ_LE_UINT16(&hsoRec->hotspotId) != 0xffff) {
+		HotspotOverrideData *newEntry = new HotspotOverrideData(hsoRec);
+		_hotspotOverrides.push_back(newEntry);
+		++hsoRec;
+	}
+	delete mb;
+
+	// Load the animation list
+	mb = d.getEntry(ANIM_DATA_RESOURCE_ID);
+	HotspotAnimResource *animRec = (HotspotAnimResource *) mb->data();
+	while (READ_LE_UINT16(&animRec->animRecordId) != 0xffff) {
+		HotspotAnimData *newEntry = new HotspotAnimData(animRec);
+		_animData.push_back(newEntry);
+
+		// Handle any direction frames
+		AnimRecordTemp dirEntries[4] = {
+			{&animRec->leftOffset, &newEntry->leftFrames},
+			{&animRec->rightOffset, &newEntry->rightFrames},
+			{&animRec->upOffset, &newEntry->upFrames},
+			{&animRec->downOffset, &newEntry->downFrames}};
+		for (int dirCtr = 0; dirCtr < 4; ++dirCtr) {
+			offsetVal = READ_LE_UINT16(dirEntries[dirCtr].offset);
+			if (offsetVal != 0) {
+				MovementResource *moveRec = (MovementResource *)
+					(mb->data() + offsetVal);
+				while (READ_LE_UINT16(&moveRec->frameNumber) != 0xffff) {
+					MovementData *newMove = new MovementData(moveRec);
+					dirEntries[dirCtr].list->push_back(newMove);
+					++moveRec;
+				}
+			}
+		}
+
+		++animRec;
+	}
+	delete mb;
+
+	// Hotspot scripts
+	mb = d.getEntry(HOTSPOT_SCRIPT_LIST_RESOURCE_ID);
+	uint16 numEntries = mb->size() / 2;
+	uint16 *srcVal = (uint16 *) mb->data();
+	uint16 *destVal = _hotspotScriptData = (uint16 *) 
+		Memory::alloc(numEntries * sizeof(uint16));
+	for (ctr = 0; ctr < numEntries; ++ctr, ++srcVal, ++destVal) {
+		*destVal = READ_LE_UINT16(srcVal);
+	}
+	delete mb;
+
+	// Handle the hotspot action lists
+	mb = d.getEntry(ACTION_LIST_RESOURCE_ID);
+	uint16 *v = (uint16 *) mb->data();
+	uint16 recordId;
+	while ((recordId = READ_LE_UINT16(v)) != 0xffff) {
+		++v;
+		offsetVal = READ_LE_UINT16(v);
+		++v;
+
+		HotspotActionList *list = new HotspotActionList(
+			recordId, mb->data() + offsetVal);
+		_actionsList.push_back(list);
+	}
+	delete mb;
+
+	_delayList.clear();
+
+	// Load miscellaneous data
+	_scriptData = d.getEntry(SCRIPT_DATA_RESOURCE_ID);
+	_script2Data = d.getEntry(SCRIPT2_DATA_RESOURCE_ID);
+	_messagesData = d.getEntry(MESSAGES_LIST_RESOURCE_ID);
+}
+
+RoomExitJoinData *Resources::getExitJoin(uint16 hotspotId) {
+	RoomExitJoinList::iterator i;
+	
+	for (i = _exitJoins.begin(); i != _exitJoins.end(); ++i) {
+		RoomExitJoinData *rec = *i;
+		if ((rec->hotspot1Id == hotspotId) || (rec->hotspot2Id == hotspotId))
+			return rec;
+	}
+
+	return NULL;
+}
+
+uint16 Resources::getHotspotScript(uint16 index) {
+	return _hotspotScriptData[index];
+}
+
+RoomData *Resources::getRoom(uint16 roomNumber) {
+	RoomDataList::iterator i;
+
+	for (i = _roomData.begin(); i != _roomData.end(); ++i) {
+		RoomData *rec = *i;
+		if (rec->roomNumber == roomNumber) return rec;
+		++rec;
+	}
+
+	return NULL;
+}
+
+void Resources::insertPaletteSubset(Palette &p) {
+	p.palette()->copyFrom(_paletteSubset->palette(), 0, 129*4, 60*4);
+	p.palette()->copyFrom(_paletteSubset->palette(), 60*4, 220*4, 8*4);
+}
+
+HotspotData *Resources::getHotspot(uint16 hotspotId) {
+	HotspotDataList::iterator i;
+
+	for (i = _hotspotData.begin(); i != _hotspotData.end(); ++i) {
+		HotspotData *rec = *i;
+		if (rec->hotspotId == hotspotId) return rec;
+	}
+
+	return NULL;
+}
+
+Hotspot *Resources::getActiveHotspot(uint16 hotspotId) {
+	HotspotList::iterator i;
+
+	for (i = _activeHotspots.begin(); i != _activeHotspots.end(); ++i) {
+		Hotspot *rec = *i;
+		if (rec->hotspotId() == hotspotId) return rec;
+	}
+
+	return NULL;
+}
+
+
+HotspotOverrideData *Resources::getHotspotOverride(uint16 hotspotId) {
+	HotspotOverrideList::iterator i;
+
+	for (i = _hotspotOverrides.begin(); i != _hotspotOverrides.end(); ++i) {
+		HotspotOverrideData *rec = *i;
+		if (rec->hotspotId == hotspotId) return rec;
+	}
+
+	return NULL;
+}
+
+HotspotAnimData *Resources::getAnimation(uint16 animRecordId) {
+	HotspotAnimList::iterator i;
+
+	for (i = _animData.begin(); i != _animData.end(); ++i) {
+		HotspotAnimData *rec = *i;
+		if (rec->animRecordId == animRecordId) return rec;
+	}
+
+	return NULL;
+}
+
+uint16 Resources::getHotspotAction(uint16 actionsOffset, Action action) {
+	HotspotActionList *list = _actionsList.getActions(actionsOffset);
+	if (!list) return 0;
+	return list->getActionOffset(action);
+}
+
+HotspotActionList *Resources::getHotspotActions(uint16 actionsOffset) {
+	return _actionsList.getActions(actionsOffset);
+}
+
+void Resources::activateHotspot(uint16 hotspotId) {
+	HotspotData *res = getHotspot(hotspotId);
+	if (!res) return;
+	res->roomNumber &= 0x7fff; // clear any suppression bit in room #
+
+	// Make sure that the hotspot isn't already active
+	HotspotList::iterator i = _activeHotspots.begin();
+	bool found = false;
+
+	for (; i != _activeHotspots.end(); ++i) {
+		Hotspot &h = *i.operator*();
+		if (h.hotspotId() == res->hotspotId) {
+			found = true;
+			break;
+		}
+	}
+	if (found) return;
+
+	// Check the script load flag
+	if (res->scriptLoadFlag) {
+		// Execute a script rather than doing a standard load
+		Script::execute(res->loadOffset);
+	} else {
+		// Standard load
+		bool loadFlag = true;
+
+		switch (res->loadOffset) {
+		case 0x3afe:
+			// Copy protection check - since the game is freeware now,
+			// don't bother with it
+			loadFlag = false;
+			break;
+
+		case 0x41BD:
+			// Empty handler used to prevent loading hotspots that
+			// are yet to be active (such as the straw fire)
+			loadFlag = false;
+			break;
+
+		case 0x7172:
+		case 0x7167:
+			// Standard animation load
+			break;
+
+		case 0x88ac:
+			// Torch in room #1
+			loadFlag = _fieldList.getField(TORCH_HIDE) == 0;
+			break;
+
+		default:
+			// All others simply activate the hotspot
+			warning("Hotspot %d uses unknown load offset proc %d",
+				res->hotspotId, res->loadOffset);
+		}
+
+		if (loadFlag) {
+			Hotspot *hotspot = addHotspot(hotspotId);
+//			if (res->loadOffset == 0x7167) hotspot->setPersistant(true);
+			// DEBUG - for now only keep certain hotspots active
+			hotspot->setPersistant((res->hotspotId >= 0x3e8) && (res->hotspotId <= 0x3ea));
+		}
+	}
+}
+
+Hotspot *Resources::addHotspot(uint16 hotspotId) {
+	Hotspot *hotspot = new Hotspot(getHotspot(hotspotId));
+	_activeHotspots.push_back(hotspot);
+	return hotspot;
+}
+
+void Resources::deactivateHotspot(uint16 hotspotId) {
+	HotspotList::iterator i = _activeHotspots.begin();
+
+	while (i != _activeHotspots.end()) {
+		Hotspot *h = *i;
+		if (h->hotspotId() == hotspotId) 
+			i = _activeHotspots.erase(i);
+		else 
+			i++;
+	}
+}
+
+uint16 Resources::numInventoryItems() {
+	uint16 numItems = 0;
+	HotspotDataList &list = _hotspotData;
+	HotspotDataList::iterator i;
+	for (i = list.begin(); i != list.end(); ++i) {
+		HotspotData *rec = *i;
+		if (rec->roomNumber == PLAYER_ID) ++numItems;
+	}
+
+	return numItems;
+}
+
+} // end of namespace Lure


Property changes on: scummvm/trunk/lure/res.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/res.h
===================================================================
--- scummvm/trunk/lure/res.h	                        (rev 0)
+++ scummvm/trunk/lure/res.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,94 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __lure_res_h__
+#define __lure_res_h__
+
+#include "lure/luredefs.h"
+#include "lure/memory.h"
+#include "common/list.h"
+#include "lure/res_struct.h"
+#include "lure/hotspots.h"
+#include "lure/palette.h"
+
+namespace Lure {
+
+class Resources {
+private:
+	Common::RandomSource _rnd;
+	Palette *_paletteSubset;
+	RoomDataList _roomData;
+	HotspotDataList _hotspotData;
+	HotspotOverrideList _hotspotOverrides;
+	HotspotAnimList _animData;
+	MemoryBlock *_scriptData;
+	MemoryBlock *_script2Data;
+	MemoryBlock *_messagesData;
+	uint16 *_hotspotScriptData;
+	RoomExitJoinList _exitJoins;
+	HotspotList _activeHotspots;
+	ValueTableData _fieldList;
+	HotspotActionSet _actionsList;
+	SequenceDelayList _delayList;
+
+	void freeData();
+public:
+	Resources();
+	~Resources();
+	static Resources &getReference();
+	void reloadData();
+
+	byte *getResource(uint16 resId);
+	RoomDataList &roomData() { return _roomData; }
+	RoomData *getRoom(uint16 roomNumber);
+	void insertPaletteSubset(Palette &p);
+
+	HotspotDataList &hotspotData() { return _hotspotData; }
+	HotspotOverrideList &hotspotOverrides() { return _hotspotOverrides; }
+	HotspotAnimList &animRecords() { return _animData; }
+	MemoryBlock *scriptData() { return _scriptData; }
+	MemoryBlock *hotspotScriptData() { return _script2Data; }
+	MemoryBlock *messagesData() { return _messagesData; }
+	uint16 getHotspotScript(uint16 index);
+	HotspotList &activeHotspots() { return _activeHotspots; }
+	uint16 random() { return _rnd.getRandomNumber(65536) & 0xffff; }
+	HotspotData *getHotspot(uint16 hotspotId);
+	Hotspot *getActiveHotspot(uint16 hotspotId);
+	HotspotOverrideData *getHotspotOverride(uint16 hotspotId);
+	HotspotAnimData *getAnimation(uint16 animRecordId);
+	RoomExitJoinList &exitJoins() { return _exitJoins; }
+	RoomExitJoinData *getExitJoin(uint16 hotspotId);
+	uint16 getHotspotAction(uint16 actionsOffset, Action action);
+	HotspotActionList *getHotspotActions(uint16 actionsOffset);
+	ValueTableData &fieldList() { return _fieldList; }
+	SequenceDelayList &delayList() { return _delayList; }
+	uint16 numInventoryItems();
+	
+	void activateHotspot(uint16 hotspotId);
+	Hotspot *addHotspot(uint16 hotspotId);
+	void deactivateHotspot(uint16 hotspotId);
+
+};
+
+} // End of namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/res.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/res_struct.cpp
===================================================================
--- scummvm/trunk/lure/res_struct.cpp	                        (rev 0)
+++ scummvm/trunk/lure/res_struct.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,309 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/res.h"
+#include "lure/disk.h"
+#include "lure/scripts.h"
+#include "lure/system.h"
+
+namespace Lure {
+
+const char *actionList[] = {NULL, "Get", NULL, "Push", "Pull", "Operate", "Open",
+	"Close", "Lock", "Unlock", "Use", "Give", "Talk to", "Tell", "Buy",
+	"Look", "Look at", "Look through", "Ask", NULL, "Drink", "Status",
+	"Go to", "Return", "Bribe", "Examine"};
+
+// Room data holding class
+
+RoomData::RoomData(RoomResource *rec) {
+	roomNumber = READ_LE_UINT16(&rec->roomNumber);
+	descId = READ_LE_UINT16(&rec->descId);
+	sequenceOffset = READ_LE_UINT16(&rec->sequenceOffset);
+	numLayers = READ_LE_UINT16(&rec->numLayers);
+
+	for (int ctr = 0; ctr < 4; ++ctr)
+		layers[ctr] = READ_LE_UINT16(&rec->layers[ctr]);
+}
+
+// Room exit hotspot area holding class
+
+RoomExitHotspotData::RoomExitHotspotData(RoomExitHotspotRecord *rec) {
+	hotspotId = READ_LE_UINT16(&rec->hotspotId);
+	xs = READ_LE_INT16(&rec->xs);
+	ys = READ_LE_INT16(&rec->ys);
+	xe = READ_LE_INT16(&rec->xe);
+	ye = READ_LE_INT16(&rec->ye);
+	cursorNum = rec->cursorNum;
+	destRoomNumber = READ_LE_UINT16(&rec->destRoomNumber);
+}
+
+//  Room exit class
+
+RoomExitData::RoomExitData(RoomExitResource *rec) {
+	xs = rec->xs; 
+	ys = rec->ys;
+	xe = rec->xe;
+	ye = rec->ye;
+	sequenceOffset = rec->sequenceOffset;
+	roomNumber = rec->newRoom;
+	x = rec->newRoomX;
+	y = rec->newRoomY;
+
+	switch (rec->direction) {
+	case 0x80: 
+		direction = UP;
+		break;
+	case 0x40: 
+		direction = DOWN;
+		break;
+	case 0x20: 
+		direction = LEFT;
+		break;
+	case 0x10: 
+		direction = RIGHT;
+		break;
+	default:
+		direction = NO_DIRECTION;
+		break;
+	}
+}
+
+bool RoomExitData::insideRect(int16 xp, int16 yp) {
+	return ((xp >= xs) && (xp <= xe) && (yp >= ys) && (yp <= ye));
+}
+
+RoomExitData *RoomExitList::checkExits(int16 xp, int16 yp) {
+	iterator i;
+	for (i = begin(); i != end(); i++) {
+		RoomExitData *rec = *i;
+		if (rec->insideRect(xp, yp)) return rec;
+	}
+	return NULL;
+}
+
+// Room exit joins class
+
+RoomExitJoinData::RoomExitJoinData(RoomExitJoinRecord *rec) {
+	hotspot1Id = READ_LE_UINT16(&rec->hotspot1Id);
+	h1CurrentFrame = rec->h1CurrentFrame;
+	h1DestFrame = rec->h1DestFrame;
+	h1Unknown = READ_LE_UINT16(&rec->h1Unknown);
+	hotspot2Id = READ_LE_UINT16(&rec->hotspot2Id);
+	h2CurrentFrame = rec->h2CurrentFrame;
+	h2DestFrame = rec->h2DestFrame;
+	h2Unknown = READ_LE_UINT16(&rec->h2Unknown);
+	blocked = rec->blocked;
+	unknown = rec->unknown;
+}
+
+// Hotspot action record
+
+HotspotActionData::HotspotActionData(HotspotActionRecord *rec) {
+	action = (Action) rec->action;
+	sequenceOffset = READ_LE_UINT16(&rec->sequenceOffset);
+}
+
+uint16 HotspotActionList::getActionOffset(Action action) {
+	iterator i;
+	for (i = begin(); i != end(); ++i) {
+		HotspotActionData *rec = *i;
+		if (rec->action == action) return rec->sequenceOffset;
+	}
+
+	return 0;
+}
+
+
+// Hotspot data
+
+HotspotData::HotspotData(HotspotResource *rec) {
+	hotspotId = READ_LE_UINT16(&rec->hotspotId);
+	nameId = READ_LE_UINT16(&rec->nameId);
+	descId = READ_LE_UINT16(&rec->descId);
+	descId2 = READ_LE_UINT16(&rec->descId2);
+	actions = READ_LE_UINT32(&rec->actions);
+	actionsOffset = READ_LE_UINT16(&rec->actionsOffset);
+	flags = (byte) (actions >> 24) & 0xf0;
+	actions &= 0xfffffff;
+
+	roomNumber = READ_LE_UINT16(&rec->roomNumber);
+	layer = rec->layer;
+	scriptLoadFlag = rec->scriptLoadFlag;
+	loadOffset = READ_LE_UINT16(&rec->loadOffset);
+	startX = READ_LE_INT16(&rec->startX);
+	startY = READ_LE_INT16(&rec->startY);
+	width = READ_LE_UINT16(&rec->width);
+	height = READ_LE_UINT16(&rec->height);
+	colourOffset = READ_LE_UINT16(&rec->colourOffset);
+	animRecordId = READ_LE_UINT16(&rec->animRecordId);
+	sequenceOffset = READ_LE_UINT16(&rec->sequenceOffset);
+	tickProcOffset = READ_LE_UINT16(&rec->tickProcOffset);
+	tickTimeout = READ_LE_UINT16(&rec->tickTimeout);
+}
+
+// Hotspot override data
+
+HotspotOverrideData::HotspotOverrideData(HotspotOverrideResource *rec) {
+	hotspotId = READ_LE_UINT16(&rec->hotspotId);
+	xs = READ_LE_INT16(&rec->xs);
+	ys = READ_LE_INT16(&rec->ys);
+	xe = READ_LE_INT16(&rec->xe);
+	ye = READ_LE_INT16(&rec->ye);
+}
+
+// Hotspot animation movement frame
+
+MovementData::MovementData(MovementResource *rec) {
+	frameNumber = READ_LE_UINT16(&rec->frameNumber);
+	xChange = READ_LE_INT16(&rec->xChange);
+	yChange = READ_LE_INT16(&rec->yChange);
+}
+
+// List of movement frames
+
+bool MovementDataList::getFrame(uint16 currentFrame, int16 &xChange, 
+							   int16 &yChange, uint16 &nextFrame) {
+	if (isEmpty()) return false;
+	bool foundFlag = false;
+	iterator i;
+
+	for (i = begin(); i != end(); ++i) {
+		MovementData *rec = *i;
+		if (foundFlag || (i == begin())) {
+			xChange = rec->xChange;
+			yChange = rec->yChange;
+			nextFrame = rec->frameNumber;
+			if (foundFlag) return true;
+		}
+		if (rec->frameNumber == currentFrame) foundFlag = true;
+	}
+
+	return true;
+}
+
+
+// Hotspot animation data
+
+HotspotAnimData::HotspotAnimData(HotspotAnimResource *rec) {
+	animRecordId = READ_LE_UINT16(&rec->animRecordId);
+	animId = READ_LE_UINT16(&rec->animId);
+	flags = READ_LE_UINT16(&rec->flags);
+
+	upFrame = rec->upFrame;
+	downFrame = rec->downFrame;
+	leftFrame = rec->leftFrame;
+	rightFrame = rec->rightFrame;
+}
+
+// Hotspot action lists
+
+HotspotActionList::HotspotActionList(uint16 id, byte *data) {
+	recordId = id;
+	uint16  numItems = READ_LE_UINT16(data);
+	data += 2;
+
+	HotspotActionRecord *actionRec = (HotspotActionRecord *) data;
+	
+	for (int actionCtr = 0; actionCtr < numItems; ++actionCtr, ++actionRec) {
+		HotspotActionData *actionEntry = new HotspotActionData(actionRec);
+		push_back(actionEntry);
+	}
+}
+
+HotspotActionList *HotspotActionSet::getActions(uint16 recordId) {
+	HotspotActionSet::iterator i;
+	for (i = begin(); i != end(); ++i) {
+		HotspotActionList *list = *i;
+		if (list->recordId == recordId) return list;
+	}
+
+	return NULL;
+}
+
+// The following classes hold any sequence offsets that are being delayed
+
+SequenceDelayData::SequenceDelayData(uint16 delay, uint16 seqOffset) {
+	OSystem &system = System::getReference();
+
+	_timeoutCtr = system.getMillis() + delay;
+	_sequenceOffset = seqOffset;
+}
+
+void SequenceDelayList::addSequence(uint16 delay, uint16 seqOffset) {
+	SequenceDelayData *entry = new SequenceDelayData(delay, seqOffset);
+	push_back(entry);
+}
+
+void SequenceDelayList::tick() {
+	uint32 currTime = System::getReference().getMillis();
+	SequenceDelayList::iterator i;
+
+	for (i = begin(); i != end(); i++) {
+		SequenceDelayData *entry = *i;
+		if (entry->_timeoutCtr >= currTime) {
+			uint16 seqOffset = entry->_sequenceOffset;
+			erase(i);
+			Script::execute(seqOffset);
+			return;
+		}
+	}
+}
+
+// Field list and miscellaneous variables
+
+ValueTableData::ValueTableData() {
+	_numGroats = 0;
+
+	for (uint16 index = 0; index < NUM_VALUE_FIELDS; ++index)
+		_fieldList[index] = 0;
+}
+
+bool ValueTableData::isKnownField(uint16 fieldIndex) {
+	return (fieldIndex <= 8) || (fieldIndex == 10) || (fieldIndex == 15) || 
+		(fieldIndex == 18) || (fieldIndex == 20);
+}
+
+uint16 ValueTableData::getField(uint16 fieldIndex) {
+	if (fieldIndex > NUM_VALUE_FIELDS)
+		error("Invalid field index specified %d", fieldIndex);
+	if (!isKnownField(fieldIndex))
+		warning("Unknown field index %d in GET_FIELD opcode", fieldIndex);
+	return _fieldList[fieldIndex];
+}
+
+uint16 ValueTableData::getField(FieldName fieldName) {
+	return getField((uint16) fieldName);
+}
+
+void ValueTableData::setField(uint16 fieldIndex, uint16 value) {
+	if (fieldIndex > NUM_VALUE_FIELDS)
+		error("Invalid field index specified %d", fieldIndex);
+	_fieldList[fieldIndex] = value;
+	if (!isKnownField(fieldIndex))
+		warning("Unknown field index %d in SET_FIELD opcode", fieldIndex);
+}
+
+void ValueTableData::setField(FieldName fieldName, uint16 value) {
+	setField((uint16) fieldName, value);
+}
+
+} // end of namespace Lure


Property changes on: scummvm/trunk/lure/res_struct.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/res_struct.h
===================================================================
--- scummvm/trunk/lure/res_struct.h	                        (rev 0)
+++ scummvm/trunk/lure/res_struct.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,401 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __lure_resstruct_h__
+#define __lure_resstruct_h__
+
+#include "lure/luredefs.h"
+#include "common/list.h"
+
+namespace Lure {
+
+extern const char *actionList[];
+
+/*-------------------------------------------------------------------------*/
+/* Structure definitions                                                   */
+/*                                                                         */
+/*-------------------------------------------------------------------------*/
+
+#if !defined(__GNUC__)
+#pragma START_PACK_STRUCTS
+#endif
+
+struct HotspotResource {
+	uint16 hotspotId;
+	uint16 nameId;
+	uint16 descId;
+	uint16 descId2;
+	uint32 actions;
+	uint16 actionsOffset;
+	uint16 roomNumber;
+	byte layer;
+	byte scriptLoadFlag;
+	uint16 loadOffset;
+	int16 startX;
+	int16 startY;
+	uint16 width;
+	uint16 height;
+	uint16 colourOffset;
+	uint16 animRecordId;
+	uint16 sequenceOffset;
+	uint16 tickProcOffset;
+	uint16 tickTimeout;
+} GCC_PACK;
+
+struct HotspotAnimResource {
+	uint16 animRecordId;
+	uint16 animId;
+	uint16 flags;
+	uint16 upOffset;
+	uint16 downOffset;
+	uint16 leftOffset;
+	uint16 rightOffset;
+	uint8 upFrame;
+	uint8 downFrame;
+	uint8 leftFrame;
+	uint8 rightFrame;
+} GCC_PACK;
+
+struct MovementResource {
+	uint16 frameNumber;
+	int16 xChange;
+	int16 yChange;
+} GCC_PACK;
+
+
+struct RoomResource {
+	uint16 roomNumber;
+	uint16 descId;
+	uint16 numLayers;
+	uint16 layers[4];
+	uint16 sequenceOffset;
+	uint16 numExits;
+} GCC_PACK;
+
+struct RoomExitResource {
+	int16 xs, xe, ys, ye;
+	uint16 sequenceOffset;
+	uint8 newRoom;
+	uint8 direction;
+	int16 newRoomX, newRoomY;
+} GCC_PACK;
+
+struct HotspotOverrideResource {
+	uint16 hotspotId;
+	int16 xs, xe, ys, ye;
+} GCC_PACK;
+
+struct RoomExitHotspotRecord {
+	uint16 hotspotId;
+	int16 xs, xe;
+	int16 ys, ye;
+	uint16 cursorNum;
+	uint16 destRoomNumber;
+} GCC_PACK;
+
+struct RoomExitJoinRecord {
+	uint16 hotspot1Id;
+	byte h1CurrentFrame;
+	byte h1DestFrame;
+	uint16 h1Unknown;
+	uint16 hotspot2Id;
+	byte h2CurrentFrame;
+	byte h2DestFrame;
+	uint16 h2Unknown;
+	byte blocked;
+	uint32 unknown;
+} GCC_PACK;
+
+struct HotspotActionRecord {
+	byte action;
+	uint16 sequenceOffset;
+} GCC_PACK;
+
+struct FileEntry {
+	uint16 id;
+	byte unused;
+	byte sizeExtension;
+	uint16 size;
+	uint16 offset;
+} GCC_PACK;
+
+struct VersionStructure {
+	uint16 id;
+	byte vMajor;
+	byte vMinor;
+} GCC_PACK;
+
+#if !defined(__GNUC__)
+#pragma END_PACK_STRUCTS
+#endif
+
+// Class template for a derived list that destroys the contained
+// object when the record containing it is destroyed. It's not
+// perfect, since the underlying list doesn't have virtual
+// methods, but it's sufficient for my usage
+
+template <class T>
+class ManagedList: public Common::List<T> {
+public:
+	~ManagedList() {
+		clear();
+	}
+
+	void clear() {
+		typename Common::List<T>::iterator i;
+		for (i = Common::List<T>::begin(); i != Common::List<T>::end(); ++i)
+			delete *i;
+		Common::List<T>::clear();		
+	}
+
+	typename Common::List<T>::iterator erase(typename Common::List<T>::iterator pos) {
+		delete *pos;
+		return Common::List<T>::erase(pos);
+	}
+
+	typename Common::List<T>::iterator erase(typename Common::List<T>::iterator first, 
+			typename Common::List<T>::iterator last) {
+		typename Common::List<T>::iterator i;
+		for (i = first; i != last; ++i)
+			delete *i;
+		return Common::List<T>::erase(first, last);
+	}
+};
+
+// Enumeration used for direction facings
+
+enum Direction {UP, DOWN, LEFT, RIGHT, NO_DIRECTION};
+
+// Support classes to hold loaded resources
+
+class RoomExitHotspotData {
+public:
+	RoomExitHotspotData(RoomExitHotspotRecord *rec);
+
+	uint16 hotspotId;
+	int16 xs, xe;
+	int16 ys, ye;
+	uint16 cursorNum;
+	uint16 destRoomNumber;
+};
+
+typedef ManagedList<RoomExitHotspotData *> RoomExitHotspotList;
+
+class RoomExitData {
+public:
+	RoomExitData(RoomExitResource *rec);
+	bool insideRect(int16 xp, int16 yp);
+
+	int16 xs, xe, ys, ye;
+	uint16 sequenceOffset;
+	Direction direction;
+	uint8 roomNumber;
+	uint16 x, y;
+};
+
+class RoomExitList: public ManagedList<RoomExitData *> {
+public:
+	RoomExitData *checkExits(int16 xp, int16 yp);
+};
+
+#define MAX_NUM_LAYERS 4
+
+class RoomData {
+public:
+	RoomData(RoomResource *rec);
+
+	uint16 roomNumber;
+	uint16 descId;
+	uint16 numLayers;
+	uint16 layers[MAX_NUM_LAYERS];
+	uint16 sequenceOffset;
+	RoomExitHotspotList exitHotspots;
+	RoomExitList exits;
+};
+
+typedef ManagedList<RoomData *> RoomDataList;
+
+class RoomExitJoinData {
+public:
+	RoomExitJoinData(RoomExitJoinRecord *rec);
+
+	uint16 hotspot1Id;
+	byte h1CurrentFrame;
+	byte h1DestFrame;
+	uint16 h1Unknown;
+	uint16 hotspot2Id;
+	byte h2CurrentFrame;
+	byte h2DestFrame;
+	uint16 h2Unknown;
+	byte blocked;
+	uint32 unknown;
+};
+
+typedef ManagedList<RoomExitJoinData *> RoomExitJoinList;
+
+class HotspotActionData {
+public:
+	HotspotActionData(HotspotActionRecord *rec);
+
+	Action action;
+	uint16 sequenceOffset;
+};
+
+class HotspotActionList: public ManagedList<HotspotActionData *> {
+public:
+	uint16 recordId;
+
+	HotspotActionList(uint16 id, byte *data);
+	uint16 getActionOffset(Action action);
+};
+
+class HotspotActionSet: public ManagedList<HotspotActionList *> {
+public:
+	HotspotActionList *getActions(uint16 recordId);
+};
+
+class HotspotData {
+public:
+	HotspotData(HotspotResource *rec);
+	
+	uint16 hotspotId;
+	uint16 nameId;
+	uint16 descId;
+	uint16 descId2;
+	uint32 actions;
+	uint16 actionsOffset;
+	byte flags;
+	uint16 roomNumber;
+	byte layer;
+	byte scriptLoadFlag;
+	uint16 loadOffset;
+	int16 startX;
+	int16 startY;
+	uint16 width;
+	uint16 height;
+	uint16 colourOffset;
+	uint16 animRecordId;
+	uint16 sequenceOffset;
+	uint16 tickProcOffset;
+	uint16 tickTimeout;
+};
+
+typedef ManagedList<HotspotData *> HotspotDataList;
+
+class HotspotOverrideData {
+public:
+	HotspotOverrideData(HotspotOverrideResource *rec);
+
+	uint16 hotspotId;
+	int16 xs, xe, ys, ye;
+};
+
+typedef ManagedList<HotspotOverrideData *> HotspotOverrideList;
+
+class MovementData {
+public:
+	MovementData(MovementResource *);
+
+	uint16 frameNumber;
+	int16 xChange;
+	int16 yChange;
+};
+
+class MovementDataList: public ManagedList<MovementData *> {
+public:
+	bool getFrame(uint16 currentFrame, int16 &xChange, int16 &yChange, 
+		uint16 &nextFrame);
+};
+
+class HotspotAnimData {
+public:
+	HotspotAnimData(HotspotAnimResource *rec);
+
+	uint16 animRecordId;
+	uint16 animId;
+	uint16 flags;
+	uint8 upFrame;
+	uint8 downFrame;
+	uint8 leftFrame;
+	uint8 rightFrame;
+
+	MovementDataList leftFrames, rightFrames;
+	MovementDataList upFrames, downFrames;
+};
+
+typedef ManagedList<HotspotAnimData *> HotspotAnimList;
+
+// The following classes hold any sequence offsets that are being delayed
+
+class SequenceDelayData {
+	friend class SequenceDelayList;
+private:
+	uint32 _timeoutCtr;
+	uint16 _sequenceOffset;
+public:
+	SequenceDelayData(uint16 delay, uint16 seqOffset);
+};
+
+class SequenceDelayList: public ManagedList<SequenceDelayData *> {
+public:
+	void addSequence(uint16 delay, uint16 seqOffset);
+	void tick();
+};
+
+// The following class holds the field list used by the script engine as 
+// well as miscellaneous fields used by the game.                          
+
+#define NUM_VALUE_FIELDS 85
+
+enum FieldName {
+	ROOM_NUMBER = 0, 
+	CHARACTER_HOTSPOT_ID = 1, 
+	USE_HOTSPOT_ID = 2,
+	ACTIVE_HOTSPOT_ID = 3,
+	SEQUENCE_RESULT = 4,
+	GENERAL = 5,
+	NEW_ROOM_NUMBER = 7,
+	GENERAL_STATUS = 8,
+	TORCH_HIDE = 10,
+	PRISONER_DEAD = 15,
+	BOTTLE_FILLED = 18,
+	SACK_CUT = 20
+};
+
+class ValueTableData {
+private:
+	uint16 _numGroats;
+	uint16 _fieldList[NUM_VALUE_FIELDS];
+	bool isKnownField(uint16 fieldIndex);
+public:
+	ValueTableData();
+	uint16 getField(uint16 fieldIndex);
+	uint16 getField(FieldName fieldName);
+
+	void setField(uint16 fieldIndex, uint16 value);
+	void setField(FieldName fieldName, uint16 value);
+	uint16 &numGroats() { return _numGroats; }
+};
+
+} // End of namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/res_struct.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/room.cpp
===================================================================
--- scummvm/trunk/lure/room.cpp	                        (rev 0)
+++ scummvm/trunk/lure/room.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,485 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/room.h"
+#include "lure/luredefs.h"
+#include "lure/res.h"
+#include "lure/screen.h"
+#include "lure/events.h"
+#include "lure/strings.h"
+#include "lure/scripts.h"
+
+namespace Lure {
+
+static Room *int_room;
+
+RoomLayer::RoomLayer(uint16 screenId, bool backgroundLayer): 
+		Surface(FULL_SCREEN_WIDTH, FULL_SCREEN_HEIGHT) {
+	loadScreen(screenId);	
+	byte cellIndex = 0;
+	byte *screenData = data().data();
+
+	memset(_cells, 0xff, FULL_HORIZ_RECTS*FULL_VERT_RECTS);
+
+	// Loop through each cell of the screen
+	for (int cellY = 0; cellY < NUM_VERT_RECTS; ++cellY) {
+		for (int cellX = 0; cellX < NUM_HORIZ_RECTS; ++cellX) {
+			bool hasPixels = false;
+
+			if (backgroundLayer) {
+				hasPixels = true;
+			} else {
+				// Check the cell
+				for (int yP = 0; yP < RECT_SIZE; ++yP) {
+					if (hasPixels) break;
+					byte *linePos = screenData + (cellY * RECT_SIZE + yP + 8) 
+						* FULL_SCREEN_WIDTH + (cellX * RECT_SIZE);
+
+					for (int xP = 0; xP < RECT_SIZE; ++xP) {
+						hasPixels = *linePos++ != 0;
+						if (hasPixels) break;
+					}
+				}
+			}
+
+			_cells[(cellY + NUM_EDGE_RECTS) * FULL_HORIZ_RECTS + NUM_EDGE_RECTS +
+				cellX] = !hasPixels ? 0xff : cellIndex++;
+		}
+	}
+}
+
+Room::Room(): _screen(Screen::getReference()) {
+	int_room = this;
+
+	_roomData = NULL;
+	_hotspotName[0] = '\0';
+	for (int ctr = 0; ctr < MAX_NUM_LAYERS; ++ctr) _layers[ctr] = NULL;
+	_numLayers = 0;
+	_showInfo = false;
+	_currentAction = NONE;
+}
+
+Room::~Room() {
+	for (int layerNum = 0; layerNum < _numLayers; ++layerNum)
+		if (_layers[layerNum])
+			delete _layers[layerNum];
+
+	int_room = NULL;
+}
+
+Room &Room::getReference() {
+	return *int_room;
+}
+
+// leaveRoom
+// Handles leaving the current room
+
+void Room::leaveRoom() {
+	Resources &r = Resources::getReference();
+
+	// Deallocate graphical layers from the room
+	for (int layerNum = 0; layerNum < _numLayers; ++layerNum)
+		if (_layers[layerNum]) {
+			delete _layers[layerNum];
+			_layers[layerNum] = NULL;
+		}
+
+	// Scan through the hotspot list and remove any uneeded entries 
+//r.activeHotspots().clear();
+	HotspotList &list = r.activeHotspots();
+	HotspotList::iterator i = list.begin();
+	while (i != list.end()) {
+		Hotspot *h = i.operator*();
+		if (!h->persistant()) {
+			i = list.erase(i);
+		} else {
+			++i;
+		}
+	}
+}
+
+void Room::loadRoomHotspots() {
+	Resources &r = Resources::getReference();
+	HotspotDataList &list = r.hotspotData();
+
+	HotspotDataList::iterator i;
+	for (i = list.begin(); i != list.end(); ++i) {
+		HotspotData *rec = *i;
+
+		if ((rec->hotspotId < 0x7530) && (rec->roomNumber == _roomNumber) && 
+			(rec->layer != 0))
+			r.activateHotspot(rec->hotspotId);
+	}
+}
+
+void Room::checkRoomHotspots() {
+	Mouse &m = Mouse::getReference();
+	Resources &r = Resources::getReference();
+	HotspotDataList &list = r.hotspotData();
+	HotspotData *entry = NULL;
+	int16 currentX = m.x();
+	int16 currentY = m.y();
+
+	HotspotDataList::iterator i;
+	for (i = list.begin(); i != list.end(); ++i) {
+		entry = *i;
+
+		bool skipFlag = (entry->roomNumber != _roomNumber);
+		if (!skipFlag) {
+			skipFlag = (((entry->flags & 0x80) == 0) && 
+				        ((entry->flags & 0x40) != 0)) ||
+				       ((entry->flags & 0x20) != 0);
+		}
+
+		if ((!skipFlag) && (entry->hotspotId < 0x409))
+			skipFlag = sub_112();
+		
+		if (!skipFlag && (entry->hotspotId >= 0x2710) && (entry->hotspotId <= 0x27ff)) {
+			RoomExitJoinData *rec = r.getExitJoin(entry->hotspotId);
+			if ((rec) && (!rec->blocked))
+				// Hotspot is over a room exit, and it's not blocked, so don't 
+				// register it as an active hotspot
+				skipFlag = true;
+		}
+
+		if (!skipFlag) {
+			// Check for a hotspot override
+			HotspotOverrideData *hsEntry = r.getHotspotOverride(entry->hotspotId);
+
+			if (hsEntry) {
+				// Check whether cursor is in override hotspot area
+				if ((currentX >= hsEntry->xs) && (currentX <= hsEntry->xe) &&
+					(currentY >= hsEntry->ys) && (currentY <= hsEntry->ye))
+					// Found to be in hotspot entry
+					break;
+			} else {
+				// Check whether cursor is in default hospot area
+				if ((currentX >= entry->startX) && (currentX < entry->startX + entry->width) && 
+					(currentY >= entry->startY) && (currentY < entry->startY + entry->height)) 
+					// Found hotspot entry
+					break;
+			}
+		}
+	}
+
+	if (i == list.end()) {
+		_hotspotId = 0;
+		_hotspotNameId = 0;
+		_hotspot = NULL;
+	} else {
+		_hotspotNameId = entry->nameId;
+		_hotspot = entry;
+		_hotspotId = entry->hotspotId;
+	}
+}
+
+uint8 Room::checkRoomExits() {
+	Mouse &m = Mouse::getReference();
+	Resources &r = Resources::getReference();
+
+	RoomExitHotspotList &exits = _roomData->exitHotspots;
+	if (exits.isEmpty()) return CURSOR_ARROW;
+	RoomExitJoinData *join;
+	bool skipFlag;
+
+	RoomExitHotspotList::iterator i;
+	for (i = exits.begin(); i != exits.end(); ++i) {
+		RoomExitHotspotData *rec = *i;
+		skipFlag = false;
+
+		if (rec->hotspotId != 0) {
+			join = r.getExitJoin(rec->hotspotId);
+			if ((join) && (join->blocked != 0))
+				skipFlag = true;
+		}
+
+		if (!skipFlag && (m.x() >= rec->xs) && (m.x() <= rec->xe) &&
+			(m.y() >= rec->ys) && (m.y() <= rec->ye)) {
+			// Cursor is within exit area
+			uint8 cursorNum = rec->cursorNum;
+
+			// If it's a hotspotted exit, change arrow to the + arrow
+			if (rec->hotspotId != 0) cursorNum += 7;
+
+			return cursorNum;
+		}
+	}
+
+	// No room exits found
+	return CURSOR_ARROW;
+}
+
+void Room::flagCoveredCells(Hotspot &h) {
+	int16 yStart = (h.y() - MENUBAR_Y_SIZE) / RECT_SIZE;
+	int16 yEnd = (h.y() + h.height() - 1 - MENUBAR_Y_SIZE) / RECT_SIZE;
+	int16 numY = yEnd - yStart + 1;
+	int16 xStart = h.x() / RECT_SIZE;
+	int16 xEnd = (h.x() + h.width() - 1) / RECT_SIZE;
+	int16 numX = xEnd - xStart + 1;
+
+	int index = yStart * NUM_HORIZ_RECTS + xStart;
+
+	for (int16 yP = 0; yP < numY; ++yP) {
+		for (int16 xP = 0; xP < numX; ++xP) {
+			int indexPos = index + xP;
+			if ((indexPos < 0) || (indexPos >= NUM_HORIZ_RECTS*NUM_VERT_RECTS)) 
+				continue;
+			_cells[index+xP] |= 0x81;
+			_cells2[index+xP] |= 1;
+		}
+		index += NUM_HORIZ_RECTS;
+	}
+}
+
+void Room::addAnimation(Hotspot &h) {
+	Surface &s = _screen.screen();
+	char buffer[10];
+	h.copyTo(&s);
+
+	if (_showInfo) {
+		int16 x = h.x();
+		int16 y = h.y();
+		if ((x >= 0) && (x <= 319) && (y >= 0) && (y <= 200)) {
+			sprintf(buffer, "%x", h.resource().hotspotId);
+			strcat(buffer, "h");
+			s.writeString(h.x(), h.y(), buffer, false);
+		}
+	}
+}
+
+void Room::addLayers(Hotspot &h) {
+	int16 hsX = h.x() + (4 * RECT_SIZE);
+	int16 hsY = h.y() + (4 * RECT_SIZE) - MENUBAR_Y_SIZE;
+
+	int16 xStart = hsX / RECT_SIZE;
+	int16 xEnd = (hsX + h.width()) / RECT_SIZE;
+	int16 numX = xEnd - xStart + 1;
+	int16 yStart = hsY / RECT_SIZE;
+	int16 yEnd = (hsY + h.height() - 1) / RECT_SIZE;
+	int16 numY = yEnd - yStart + 1;
+
+	for (int16 xCtr = 0; xCtr < numX; ++xCtr, ++xStart) {
+		int16 xs = xStart - 4;
+		if (xs < 0) continue;
+
+		// Check foreground layers for an occupied one
+/* DEBUG
+		int layerNum = 1;
+		while ((layerNum < _numLayers) &&
+					!_layers[layerNum]->isOccupied(xStart, yEnd)) 
+			++layerNum;
+		if (layerNum == _numLayers) continue;
+*/
+		int layerNum = _numLayers - 1;
+		while ((layerNum > 0) &&
+					!_layers[layerNum]->isOccupied(xStart, yEnd)) 
+			--layerNum;
+		if (layerNum == 0) continue;
+
+		int16 ye = yEnd - 4;
+		for (int16 yCtr = 0; yCtr < numY; ++yCtr, --ye) {
+			if (ye < 0) break;
+			addCell(xs, ye, layerNum);
+		}
+	}
+}
+
+void Room::addCell(int16 xp, int16 yp, int layerNum) {
+	Surface &s = _screen.screen();
+
+	while ((layerNum > 0) && !_layers[layerNum]->isOccupied(xp+4, yp+4))
+		--layerNum;
+	if (layerNum == 0) return;
+/* DEBUG
+	while ((layerNum < _numLayers) && !_layers[layerNum]->isOccupied(xp+4, yp+4))
+		++layerNum;
+	if (layerNum == _numLayers) return;
+*/
+	RoomLayer *layer = _layers[layerNum];
+
+	int index = ((yp * RECT_SIZE + 8) * FULL_SCREEN_WIDTH) + (xp * RECT_SIZE);
+	byte *srcPos = layer->data().data() + index;
+	byte *destPos = s.data().data() + index;
+
+	for (int yCtr = 0; yCtr < RECT_SIZE; ++yCtr) {
+		for (int xCtr = 0; xCtr < RECT_SIZE; ++xCtr, ++destPos) {
+			byte pixel = *srcPos++;
+			if (pixel) *destPos = pixel;
+		}
+
+		// Move to start of next cell line
+		srcPos += FULL_SCREEN_WIDTH - RECT_SIZE;
+		destPos += FULL_SCREEN_WIDTH - RECT_SIZE;
+	}
+
+	// Note: old version of screen layers load compresses loaded layers down to
+	// only a set of the non-empty rects. Since modern memory allows me to load
+	// all the layers completely, I'm bypassing the need to use cell index values
+}
+
+void Room::update() {
+	Surface &s = _screen.screen();
+	Resources &r = Resources::getReference();
+	HotspotList &hotspots = r.activeHotspots();
+	HotspotList::iterator i;
+
+	memset(_cells, 0x81, NUM_HORIZ_RECTS*NUM_VERT_RECTS);
+	memset(_cells2, 0x81, NUM_HORIZ_RECTS*NUM_VERT_RECTS);
+
+	_layers[0]->copyTo(&s);
+	for (int ctr = 1; ctr < _numLayers; ++ctr)
+		_layers[ctr]->transparentCopyTo(&s);
+
+	// Handle first layer (layer 3)
+	for (i = hotspots.begin(); i != hotspots.end(); ++i) {
+		Hotspot &h = *i.operator*();
+		if ((h.roomNumber() == _roomNumber) && h.isActiveAnimation() && (h.layer() == 3)) {
+			flagCoveredCells(h);
+			addAnimation(h);
+			addLayers(h);
+		}
+	}
+
+	// Handle second layer (layer 1) - do in order of Y axis
+	List<Hotspot *> tempList;
+	List<Hotspot *>::iterator iTemp;
+	for (i = hotspots.begin(); i != hotspots.end(); ++i) {
+		Hotspot *h = i.operator*();
+		if ((h->roomNumber() != _roomNumber) || !h->isActiveAnimation() 
+				|| (h->layer() != 1)) 
+			continue;
+		int16 endY = h->y() + h->height();
+
+		for (iTemp = tempList.begin(); iTemp != tempList.end(); ++iTemp) {
+			Hotspot *hTemp = iTemp.operator*();
+			int16 tempY = hTemp->y() + hTemp->height();
+			if (endY < tempY) {
+				if (iTemp != tempList.begin()) --iTemp;
+				break;
+			}
+		}
+		tempList.insert(iTemp, h);
+	}
+	for (iTemp = tempList.begin(); iTemp != tempList.end(); ++iTemp) {
+		Hotspot &h = *iTemp.operator*();
+		flagCoveredCells(h);
+		addAnimation(h);
+		addLayers(h);
+	}
+
+	// Handle third layer (layer 2)
+	for (i = hotspots.begin(); i != hotspots.end(); ++i) {
+		Hotspot &h = *i.operator*();
+		if ((h.roomNumber() == _roomNumber) && h.isActiveAnimation() && (h.layer() == 2)) {
+			flagCoveredCells(h);
+			addAnimation(h);
+		}
+	}
+
+	// Handle showing name of highlighted hotspot
+	if (_hotspotName[0] != '\0') {
+		if (_currentAction == NONE) {
+			s.writeString(0, 0, _hotspotName, false, DIALOG_TEXT_COLOUR);
+		} else {
+			char buffer[MAX_ACTION_NAME_SIZE + MAX_HOTSPOT_NAME_SIZE];
+			strcpy(buffer, actionList[_currentAction]);
+			strcat(buffer, " ");
+			strcat(buffer, _hotspotName);
+			s.writeString(0, 0, buffer, false, DIALOG_WHITE_COLOUR);
+		}
+	}
+
+	// If show information is turned on, show room and position
+	if (_showInfo) {
+		char buffer[64];
+		Mouse &m = Mouse::getReference();
+		sprintf(buffer, "Room %d Pos (%d,%d)", _roomNumber, m.x(), m.y());
+		s.writeString(FULL_SCREEN_WIDTH / 2, 0, buffer, false, DIALOG_TEXT_COLOUR);
+	}
+
+	_screen.update();
+}
+
+void Room::setRoomNumber(uint16 newRoomNumber, bool showOverlay) {
+	Resources &r = Resources::getReference();
+	_roomData = r.getRoom(newRoomNumber);
+	if (!_roomData)
+		error("Tried to change to non-existant room: %d", newRoomNumber);
+
+	_roomNumber = _roomData->roomNumber;
+	_descId = _roomData->descId;
+	
+	_screen.empty();
+	_screen.resetPalette();
+
+	if (_layers[0]) leaveRoom();
+
+	_numLayers = _roomData->numLayers;
+	if (showOverlay) ++_numLayers;
+
+	uint16 paletteId = (_roomData->layers[0] & 0xffe0) - 1;
+
+	for (uint8 layerNum = 0; layerNum < _numLayers; ++layerNum) 
+		_layers[layerNum] = new RoomLayer(_roomData->layers[layerNum],
+			layerNum == 0);
+
+	// Load in the palette, add in the two replacements segments, and then
+	// set to the system palette
+	Palette p(228, NULL, RGB64);
+	Palette tempPalette(paletteId);
+	p.copyFrom(&tempPalette);
+	r.insertPaletteSubset(p);
+	_screen.setPalette(&p);
+
+	if (_roomData->sequenceOffset != 0xffff)
+		Script::execute(_roomData->sequenceOffset);
+	loadRoomHotspots();
+	cursorMoved();
+
+	update();
+}
+
+// cursorMoved
+// Called as the cursor moves to handle any changes that must occur
+
+void Room::cursorMoved() {
+	uint16 cursorNew = CURSOR_ARROW;
+	uint16 oldHotspotId = _hotspotId;
+
+	Mouse &m = Mouse::getReference();
+	checkRoomHotspots();
+
+	if (_hotspotId != 0) {
+		cursorNew = CURSOR_CROSS;
+
+		if (oldHotspotId != _hotspotId) 
+			StringData::getReference().getString(_hotspotNameId, _hotspotName, NULL, NULL);
+	} else {
+		_hotspotName[0] = '\0';
+		cursorNew = checkRoomExits();
+	}
+
+	if (m.getCursorNum() != cursorNew) 
+		m.setCursorNum(cursorNew);
+}
+
+} // end of namespace Lure


Property changes on: scummvm/trunk/lure/room.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/room.h
===================================================================
--- scummvm/trunk/lure/room.h	                        (rev 0)
+++ scummvm/trunk/lure/room.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,107 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __lure_room_h__
+#define __lure_room_h__
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "lure/disk.h"
+#include "lure/res.h"
+#include "lure/memory.h"
+#include "lure/surface.h"
+#include "lure/screen.h"
+#include "lure/hotspots.h"
+
+namespace Lure {
+
+#define RECT_SIZE 32
+#define NUM_HORIZ_RECTS 10
+#define NUM_VERT_RECTS 6
+#define FULL_HORIZ_RECTS 18
+#define FULL_VERT_RECTS 14
+#define NUM_EDGE_RECTS 4
+
+class RoomLayer: public Surface {
+private:
+	byte _cells[FULL_HORIZ_RECTS*FULL_VERT_RECTS];
+public:
+	RoomLayer(uint16 screenId, bool backgroundLayer);
+	byte cellVal(byte cellX, byte cellY) { 
+		return _cells[FULL_HORIZ_RECTS*cellY + cellX]; 
+	}
+	bool isOccupied(byte cellX, byte cellY) { 
+		return cellVal(cellX, cellY) != 0xff; 
+	}
+};
+
+class Room {
+private:
+	RoomData *_roomData;
+	Screen &_screen;
+	uint16 _roomNumber;
+	uint16 _descId;
+	uint16 _hotspotId;
+	uint16 _hotspotNameId;
+	Action _currentAction;
+	char _hotspotName[MAX_HOTSPOT_NAME_SIZE + MAX_ACTION_NAME_SIZE];
+	HotspotData *_hotspot;
+	bool _showInfo;
+	uint8 _numLayers;
+	RoomLayer *_layers[MAX_NUM_LAYERS];
+	byte _cells[NUM_HORIZ_RECTS*NUM_VERT_RECTS];
+	byte _cells2[NUM_HORIZ_RECTS*NUM_VERT_RECTS];
+
+	void checkRoomHotspots();
+	uint8 checkRoomExits();
+	void loadRoomHotspots();
+	bool sub_112() { return false; } // not yet implemented
+	void flagCoveredCells(Hotspot &h);
+	void addAnimation(Hotspot &h);
+	void addLayers(Hotspot &h);
+	void addCell(int16 xp, int16 yp, int layerNum);
+public:
+	Room();
+	~Room();
+	static Room &getReference();
+	
+	void update();
+	void nextFrame();
+	void cursorMoved();
+	uint16 roomNumber() { return _roomNumber; }
+	void setRoomNumber(uint16 newRoomNumber, bool showOverlay = false);
+	void leaveRoom();
+	void setAction(Action action) {	_currentAction = action; }
+	Action getCurrentAction() { return _currentAction; }
+	uint16 hotspotId() { return _hotspotId; }
+	uint32 hotspotActions() { return _hotspot->actions & 0x10ffffff; }
+	uint8 hotspotFlags() { return (_hotspot->actions >> 24) & 0xfe; }
+	HotspotData &hotspot() { return *_hotspot; }
+	uint16 descId() { return _descId; }
+	bool showInfo() { return _showInfo; }
+	void setShowInfo(bool value) { _showInfo = value; }
+	uint32 xyzzy() { return (uint32) _layers[3]; }
+};
+
+} // end of namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/room.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/screen.cpp
===================================================================
--- scummvm/trunk/lure/screen.cpp	                        (rev 0)
+++ scummvm/trunk/lure/screen.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,152 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/screen.h"
+#include "lure/luredefs.h"
+#include "lure/memory.h"
+#include "lure/disk.h"
+#include "lure/decode.h"
+
+namespace Lure {
+
+static Screen *int_disk = NULL;
+
+Screen &Screen::getReference() {
+	return *int_disk;
+}
+
+Screen::Screen(OSystem &system): _system(system), 
+		_screen(new Surface(FULL_SCREEN_WIDTH, FULL_SCREEN_HEIGHT)), 
+		_disk(Disk::getReference()),
+		_palette(new Palette(GAME_PALETTE_RESOURCE_ID)) {
+	int_disk = this;
+	_screen->empty();
+	_system.setPalette(_palette->data(), 0, GAME_COLOURS);
+}
+
+Screen::~Screen() {
+	delete _screen;
+	delete _palette;
+}
+
+// setPaletteEmpty
+// Defaults the palette to an empty set
+
+void Screen::setPaletteEmpty() {
+	delete _palette;
+	_palette = new Palette();
+
+	_system.setPalette(_palette->data(), 0, GAME_COLOURS);
+	_system.updateScreen();
+}
+
+// setPalette
+// Sets the current palette to the passed palette
+
+void Screen::setPalette(Palette *p) {
+	_palette->copyFrom(p);
+	_system.setPalette(_palette->data(), 0, GAME_COLOURS);
+	_system.updateScreen();
+}
+
+// paletteFadeIn
+// Fades in the palette. For proper operation, the palette should have been
+// previously set to empty
+
+void Screen::paletteFadeIn(Palette *p) {
+	bool changed;
+	byte *const pDest = p->data();
+	byte *const pTemp = _palette->data();
+
+	do {
+		changed = false;
+
+		for (int palCtr = 0; palCtr < p->numEntries() * 4; ++palCtr)
+		{
+			if (palCtr % PALETTE_FADE_INC_SIZE == (PALETTE_FADE_INC_SIZE - 1)) continue;
+			bool isDifferent = pTemp[palCtr] < pDest[palCtr];
+			if (isDifferent) {
+				if (pDest[palCtr] - pTemp[palCtr] < PALETTE_FADE_INC_SIZE) 
+					pTemp[palCtr] = pDest[palCtr];
+				else pTemp[palCtr] += PALETTE_FADE_INC_SIZE;
+				changed = true;
+			}
+		}
+
+		if (changed) {
+			_system.setPalette(_palette->data(), 0, GAME_COLOURS);
+			_system.updateScreen();
+			_system.delayMillis(20);
+		}
+	} while (changed);
+}
+
+// paletteFadeOut
+// Fades the screen to black by gradually decreasing the palette colours
+
+void Screen::paletteFadeOut() {
+	bool changed;
+
+	do {
+		byte *pTemp = _palette->data();
+		changed = false;
+
+		for (uint32 palCtr = 0; palCtr < _palette->palette()->size(); ++palCtr, ++pTemp) {
+			if (palCtr % PALETTE_FADE_INC_SIZE == (PALETTE_FADE_INC_SIZE - 1)) 
+				continue;
+			bool isDifferent = *pTemp > 0;
+			if (isDifferent) {
+				if (*pTemp < PALETTE_FADE_INC_SIZE) *pTemp = 0;
+				else *pTemp -= PALETTE_FADE_INC_SIZE;
+				changed = true;
+			}
+		}
+
+		if (changed) {
+			_system.setPalette(_palette->data(), 0, GAME_COLOURS);
+			_system.updateScreen();
+			_system.delayMillis(20);
+		}
+	} while (changed);
+}
+
+void Screen::resetPalette() {
+	Palette p(GAME_PALETTE_RESOURCE_ID);
+	setPalette(&p);
+}
+
+void Screen::empty() {
+	_screen->empty();
+	update();
+}
+
+void Screen::update() {
+	_system.copyRectToScreen(screen_raw(), FULL_SCREEN_WIDTH, 0, 0, FULL_SCREEN_WIDTH, FULL_SCREEN_HEIGHT);
+	_system.updateScreen();
+}
+
+void Screen::updateArea(uint16 x, uint16 y, uint16 w, uint16 h) {
+	_system.copyRectToScreen(screen_raw(), FULL_SCREEN_WIDTH, x, y, w, h);
+	_system.updateScreen();
+}
+
+} // end of namespace Lure


Property changes on: scummvm/trunk/lure/screen.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/screen.h
===================================================================
--- scummvm/trunk/lure/screen.h	                        (rev 0)
+++ scummvm/trunk/lure/screen.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,64 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __lure_screen_h__
+#define __lure_screen_h__
+
+#include "common/stdafx.h"
+#include "base/engine.h"
+#include "lure/luredefs.h"
+#include "lure/palette.h"
+#include "lure/disk.h"
+#include "lure/memory.h"
+#include "lure/surface.h"
+
+namespace Lure {
+
+class Screen {
+private:
+	OSystem &_system;
+	Disk &_disk;
+	Surface *_screen;
+	Palette *_palette;
+public:
+	Screen(OSystem &system);
+	~Screen();
+	static Screen &getReference();
+
+	void setPaletteEmpty();
+	void setPalette(Palette *p);
+	Palette &getPalette() { return *_palette; }
+	void paletteFadeIn(Palette *p);
+	void paletteFadeOut();
+	void resetPalette();
+	void empty();
+	void update();
+	void updateArea(uint16 x, uint16 y, uint16 w, uint16 h);
+
+	Surface &screen() { return *_screen; }
+	uint8 *screen_raw() { return _screen->data().data(); }
+	uint8 *pixel_raw(uint16 x, uint16 y) { return screen_raw() + (y * FULL_SCREEN_WIDTH) + x; }
+};
+
+} // End of namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/screen.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/scripts.cpp
===================================================================
--- scummvm/trunk/lure/scripts.cpp	                        (rev 0)
+++ scummvm/trunk/lure/scripts.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,576 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/scripts.h"
+#include "lure/res.h"
+#include "lure/game.h"
+#include "common/stack.h"
+
+namespace Lure {
+
+/*------------------------------------------------------------------------*/
+/*-  Script Method List                                                  -*/
+/*-                                                                      -*/
+/*------------------------------------------------------------------------*/
+
+// activateHotspot
+// Activates a hotspot entry for active use
+
+void Script::activateHotspot(uint16 hotspotId, uint16 v2, uint16 v3) {
+	Resources::getReference().activateHotspot(hotspotId);
+}
+
+// setHotspotScript
+// Sets a hotspot's animation script offset from a master table of offsets
+
+void Script::setHotspotScript(uint16 hotspotId, uint16 scriptIndex, uint16 v3) {
+	Resources &r = Resources::getReference();
+	uint16 offset = r.getHotspotScript(scriptIndex);
+	HotspotData *rsc = r.getHotspot(hotspotId);
+	rsc->sequenceOffset = offset;
+}
+
+// Clears the sequence delay list
+
+void Script::clearSequenceDelayList(uint16 v1, uint16 scriptIndex, uint16 v3) {
+	Resources::getReference().delayList().clear();
+}
+
+// deactivates the specified hotspot from active animation
+
+void Script::deactivateHotspot(uint16 hotspotId, uint16 v2, uint16 v3) {
+	Resources &rsc = Resources::getReference();
+	if (hotspotId < START_NONVISUAL_HOTSPOT_ID) 
+		rsc.deactivateHotspot(hotspotId);
+	HotspotData *hs = rsc.getHotspot(hotspotId);
+	hs->flags |= 0x20;
+	if (hotspotId < START_NONVISUAL_HOTSPOT_ID) 
+		hs->layer = 0xff;
+}
+
+// Sets the offset for the table of action sequence offsets for the given
+// hotspot
+
+void Script::setActionsOffset(uint16 hotspotId, uint16 offset, uint16 v3) {
+	Resources &res = Resources::getReference();
+	HotspotData *hotspot = res.getHotspot(hotspotId);
+	
+	if (!res.getHotspotActions(offset))
+		warning("Hotspot %d set to invalid actions offset %d",
+			hotspotId, offset);
+	
+	hotspot->actionsOffset = offset;
+}
+
+// Add a sequence to be executed after a specified delay
+
+void Script::addDelayedSequence(uint16 seqOffset, uint16 delay, uint16 v3) {
+	SequenceDelayList &list = Resources::getReference().delayList();
+	list.addSequence(delay, seqOffset);
+}
+
+// Checks whether the given character is in the specified room, and stores
+// the result in the general value field
+
+void Script::characterInRoom(uint16 characterId, uint16 roomNumber, uint16 v3) {
+	Resources &res = Resources::getReference();
+	uint16 result = 0;
+	if (characterId >= PLAYER_ID) {
+		HotspotData *hotspot = res.getHotspot(characterId);
+		if (hotspot->roomNumber == roomNumber)
+			result = 1;
+	}
+
+	res.fieldList().setField(GENERAL, result);
+}
+
+// Changes the given hotspot's name to a new name
+
+void Script::setHotspotName(uint16 hotspotId, uint16 nameId, uint16 v3) {
+	HotspotData *hotspot = Resources::getReference().getHotspot(hotspotId);
+	hotspot->nameId = nameId;
+}
+
+// Displays the given string resource Id in a dialog
+
+void Script::displayDialog(uint16 stringId, uint16 v2, uint16 v3) {
+	Dialog::show(stringId);
+}
+
+// Flags for remotely viewing a room
+
+void Script::remoteRoomViewSetup(uint16 v1, uint16 v2, uint16 v3) {
+	Hotspot *player = Resources::getReference().getActiveHotspot(PLAYER_ID);
+	player->setTickProc(0); // disable player actions
+	Game::getReference().setRemoteView();
+}
+
+// Gets the current blocked state for the given door and stores it in the
+// general value field
+
+void Script::getDoorBlocked(uint16 hotspotId, uint16 v2, uint16 v3) {
+	Resources &res = Resources::getReference();
+	RoomExitJoinData *joinRec = res.getExitJoin(hotspotId);
+	res.fieldList().setField(GENERAL, joinRec->blocked);
+}
+
+// Decrements the number of inventory itemst he player has
+
+void Script::decrInventoryItems(uint16 v1, uint16 v2, uint16 v3) {
+	// module currently doesn't use a static counter for the number of
+	// inventory items, so don't do anything
+}
+
+// Sets the current frame number for the given hotspot
+
+void Script::setFrameNumber(uint16 hotspotId, uint16 frameNumber, uint16 v3) {
+	Hotspot *hotspot = Resources::getReference().getActiveHotspot(hotspotId);
+	hotspot->setFrameNumber(frameNumber);
+}
+
+// Disables the given hotspot from being highlighted by the cursor
+
+void Script::disableHotspot(uint16 hotspotId, uint16 v2, uint16 v3) {
+	HotspotData *hotspot = Resources::getReference().getHotspot(hotspotId);
+	hotspot->flags |= 0x20;	
+}
+
+// Increase the player's number by the specified amount
+
+void Script::increaseNumGroats(uint16 v1, uint16 numGroats, uint16 v3) {
+	ValueTableData &fields = Resources::getReference().fieldList();
+	fields.numGroats() += numGroats;
+}
+
+// Enables the flags for the given hotspot for it to be actively highlighted
+
+void Script::enableHotspot(uint16 hotspotId, uint16 v2, uint16 v3) {
+	HotspotData *hotspot = Resources::getReference().getHotspot(hotspotId);
+	// Clear flag 0x20 and add flag 0x80
+	hotspot->flags = (hotspot->flags & 0xdf) | 0x80;
+}
+
+// Marks the door in room 14 for closing
+
+void Script::room14DoorClose(uint16 v1, uint16 v2, uint16 v3) {
+	RoomExitJoinData *joinRec = Resources::getReference().getExitJoin(0x2719);
+	joinRec->blocked = 1;
+}
+
+// Sets the sequence result to 1 if the given secondary description for a 
+// hotspot is empty (for inventory items, this gives the description before
+// the item is initially picked up)
+
+void Script::checkDroppedDesc(uint16 hotspotId, uint16 v2, uint16 v3) {
+	Resources &res = Resources::getReference();
+	HotspotData *hotspot = res.getHotspot(hotspotId);
+	uint16 seqResult = (hotspot->descId2 == 0) ? 1 : 0;
+	res.fieldList().setField(SEQUENCE_RESULT, seqResult);
+}
+
+// Marks the given door hotspot for closing
+
+void Script::doorClose(uint16 hotspotId, uint16 v2, uint16 v3) {
+	RoomExitJoinData *joinRec = Resources::getReference().getExitJoin(hotspotId);
+	if (!joinRec) error("Tried to close a non-door");
+	joinRec->blocked = 1;
+}
+
+// Marks the given door hotspot for opening
+
+void Script::doorOpen(uint16 hotspotId, uint16 v2, uint16 v3) {
+	RoomExitJoinData *joinRec = Resources::getReference().getExitJoin(hotspotId);
+	if (!joinRec) error("Tried to close a non-door");
+	joinRec->blocked = 0;
+}
+
+// Lookup the given message Id for the specified character and display in a dialog
+
+void Script::displayMessage(uint16 messageId, uint16 characterId, uint16 unknownVal) {
+	Dialog::showMessage(messageId, characterId);
+}
+
+// Assign the given hotspot item to the player's inventory
+
+void Script::givePlayerItem(uint16 hotspotId, uint16 v2, uint16 v3) {
+	HotspotData *hotspot = Resources::getReference().getHotspot(hotspotId);
+	hotspot->roomNumber = PLAYER_ID;
+	hotspot->flags |= 0x80;
+}
+
+// Decrease the number of graots the player has
+
+void Script::decreaseNumGroats(uint16 characterId, uint16 numGroats, uint16 v3) {
+	ValueTableData &fields = Resources::getReference().fieldList();
+	fields.numGroats() -= numGroats;
+}
+
+// Sets the tick handler for the village Skorl to an alternate handler
+
+void Script::setVillageSkorlTickProc(uint16 v1, uint16 v2, uint16 v3) {
+	HotspotData *hotspot = Resources::getReference().getHotspot(0x3F1);
+	hotspot->tickProcOffset = 0x7efa;
+}
+
+// Stores the current number of groats in the general field
+
+void Script::getNumGroats(uint16 v1, uint16 v2, uint16 v3) {
+	ValueTableData fields = Resources::getReference().fieldList();
+	fields.setField(GENERAL, fields.numGroats());
+}
+
+// Loads the specified animation, completely bypassing the standard process
+// of checking for a load proc/sequence
+
+void Script::animationLoad(uint16 hotspotId, uint16 v2, uint16 v3) {
+	Resources::getReference().addHotspot(hotspotId);
+}
+
+// Adds the passed actions to the available actions for the given hotspot
+
+void Script::addActions(uint16 hotspotId, uint16 actions, uint16 v3) {
+	HotspotData *hotspot = Resources::getReference().getHotspot(hotspotId);
+	hotspot->actions |= actions;
+}
+
+// Checks the status of the cell door, and starts music depending on it's state
+
+void Script::checkCellDoor(uint16 v1, uint16 v2, uint16 v3) {
+	// In the original game, this method checks to see if the cell door
+	// is currently open, if it is, starts a music sequence. I'll 
+	// implement this method properly when I get around to implementing
+	// the in-game music
+}
+
+typedef void(*SequenceMethodPtr)(uint16, uint16, uint16);
+
+struct SequenceMethodRecord {
+	uint8 methodIndex;
+	SequenceMethodPtr proc;
+};
+
+SequenceMethodRecord scriptMethods[] = {
+	{0, Script::activateHotspot}, 
+	{1, Script::setHotspotScript},
+	{4, Script::clearSequenceDelayList},
+	{6, Script::deactivateHotspot},
+	{8, Script::addDelayedSequence},
+	{10, Script::characterInRoom},
+	{11, Script::setActionsOffset},
+	{12, Script::setHotspotName},
+	{16, Script::displayDialog},
+	{18, Script::remoteRoomViewSetup},
+	{20, Script::checkCellDoor},
+	{22, Script::getDoorBlocked},
+	{28, Script::decrInventoryItems},
+	{30, Script::setFrameNumber},
+	{32, Script::disableHotspot},
+	{34, Script::increaseNumGroats},
+	{35, Script::enableHotspot},
+	{39, Script::room14DoorClose},
+	{40, Script::checkDroppedDesc},
+	{42, Script::doorClose},
+	{44, Script::doorOpen},
+	{47, Script::displayMessage},
+	{50, Script::givePlayerItem},
+	{51, Script::decreaseNumGroats},
+	{54, Script::setVillageSkorlTickProc},
+	{57, Script::getNumGroats},
+	{62, Script::animationLoad},
+	{63, Script::addActions},
+	{65, Script::checkCellDoor},
+	{0xff, NULL}};
+	
+/*------------------------------------------------------------------------*/
+/*-  Script Execution                                                    -*/
+/*-                                                                      -*/
+/*------------------------------------------------------------------------*/
+
+uint16 Script::execute(uint16 startOffset) {
+	Resources &r = Resources::getReference();
+	ValueTableData &fields = r.fieldList();
+	MemoryBlock *scriptData = r.scriptData();
+	byte *scripts = scriptData->data();
+	Common::Stack<uint16> stack;
+	Common::Stack<uint16> methodStack;
+	byte opcode;
+	uint16 param, v1, v2;
+	uint16 param1, param2, param3;
+	uint16 fieldNum;
+	uint32 tempVal;
+	SequenceMethodPtr ptr;
+	SequenceMethodRecord *rec;
+
+	uint16 offset = startOffset;
+	bool breakFlag = false;
+	param = 0;
+	fields.setField(SEQUENCE_RESULT, 0);
+
+	while (!breakFlag) {
+		if (offset >= scriptData->size()) 
+			error("Script failure in script %d - invalid offset %d", startOffset, offset);
+
+		opcode = scripts[offset++];
+		if ((opcode & 1) != 0) {
+			// Flag to read next two bytes as active parameter
+			if (offset >= scriptData->size()-2) 
+				error("Script failure in script %d - invalid offset %d", startOffset, offset);
+
+			param = READ_LE_UINT16(scripts + offset);
+			offset += 2;
+		}
+		opcode >>= 1;	// Discard param bit from opcode byte
+
+		switch (opcode) {
+		case S_OPCODE_ABORT:
+		case S_OPCODE_ABORT2:
+		case S_OPCODE_ABORT3:
+			methodStack.clear();
+			break;
+
+		case S_OPCODE_ADD:
+			stack.push(stack.pop() + stack.pop());
+			break;
+
+		case S_OPCODE_SUBTRACT:
+			v1 = stack.pop();
+			v2 = stack.pop();
+			stack.push(v2 - v1);
+			break;
+
+		case S_OPCODE_MULTIPLY:
+			tempVal = stack.pop() * stack.pop();
+			stack.push(tempVal & 0xffff);
+			param = (uint16) (tempVal >> 16);
+			break;
+
+		case S_OPCODE_DIVIDE:
+			v1 = stack.pop();
+			v2 = stack.pop();
+			stack.push(v2 / v1);
+			param = v2 % v1;      // remainder
+			break;
+
+		case S_OPCODE_NOT_EQUALS:
+			stack.push((stack.pop() != stack.pop()) ? 0 : 1);
+			break;
+
+		case S_OPCODE_EQUALS:
+			stack.push((stack.pop() == stack.pop()) ? 0 : 1);
+			break;
+
+		case S_OPCODE_GT:
+			stack.push((stack.pop() > stack.pop()) ? 1 : 0);
+			break;
+
+		case S_OPCODE_LT:
+			stack.push((stack.pop() < stack.pop()) ? 1 : 0);
+			break;
+
+		case S_OPCODE_LT2:
+			stack.push((stack.pop() < stack.pop()) ? 1 : 0);
+			break;
+
+		case S_OPCODE_GT2:
+			stack.push((stack.pop() > stack.pop()) ? 1 : 0);
+			break;
+
+		case S_OPCODE_AND:
+			stack.push(stack.pop() & stack.pop());
+			break;
+
+		case S_OPCODE_OR:
+			stack.push(stack.pop() | stack.pop());
+			break;
+
+		case S_OPCODE_LOGICAL_AND:
+			stack.push(((stack.pop() != 0) && (stack.pop() != 0)) ? 1 : 0);
+			break;
+
+		case S_OPCODE_LOGICAL_OR:
+			stack.push(((stack.pop() != 0) || (stack.pop() != 0)) ? 1 : 0);
+			break;
+
+		case S_OPCODE_GET_FIELD:
+			// Opcode not yet fully implemented
+			fieldNum = param >> 1;
+			v1 = fields.getField(fieldNum);
+			stack.push(v1);
+			break;
+
+		case S_OPCODE_SET_FIELD:
+			// Opcode not yet fully implemented
+			fieldNum = param >> 1;
+			v1 = stack.pop();
+			fields.setField(fieldNum, v1);
+			break;
+
+		case S_OPCODE_PUSH:
+			stack.push(param);
+			break;
+
+		case S_OPCODE_SUBROUTINE:
+			methodStack.push(offset);
+			offset = param;
+			break;
+
+		case S_OPCODE_EXEC:
+			param1 = 0; param2 = 0; param3 = 0;
+			if (!stack.empty()) param1 = stack.pop();
+			if (!stack.empty()) param2 = stack.pop();
+			if (!stack.empty()) param3 = stack.pop();
+
+			rec = &scriptMethods[0];
+			while ((rec->methodIndex != 0xff) && (rec->methodIndex != param))
+				++rec;
+
+			if (rec->methodIndex == 0xff) 
+				warning("Undefined script method %d", param);
+			else {
+				ptr = rec->proc;
+				ptr(param1, param2, param3);
+			}
+			break;
+
+		case S_OPCODE_COND_JUMP:
+			v1 = stack.pop();
+			if (v1 == 0) offset += (int16) param;
+			break;
+
+		case S_OPCODE_JUMP:
+			offset += (int16) param;
+			break;
+
+		case S_OPCODE_RANDOM:
+			param = r.random() >> 8; // make number between 0 to 255
+			break;
+
+		case S_OPCODE_END:
+			// Signal to end the execution
+			if (!methodStack.empty()) 
+				offset = methodStack.pop();
+			else
+				breakFlag = true;
+			break;
+
+		default:
+			error("Unknown script opcode %d", opcode);
+			break;
+		}
+	}
+
+	return fields.getField(SEQUENCE_RESULT);
+}
+
+/*------------------------------------------------------------------------*/
+/*-  Hotspot Script Handler                                              -*/
+/*-                                                                      -*/
+/*------------------------------------------------------------------------*/
+
+int16 HotspotScript::nextVal(MemoryBlock *data, uint16 &offset) {
+	if (offset >= data->size() - 1) 
+		error("Script failure - invalid offset");
+	int16 value = READ_LE_UINT16(data->data() + offset);
+	offset += 2;
+	return value;
+}
+
+bool HotspotScript::execute(Hotspot *h)
+{
+	Resources &r = Resources::getReference();
+	MemoryBlock *scriptData = r.hotspotScriptData();
+	uint16 offset = h->script();
+	int16 opcode = 0;
+	int16 param1, param2;
+	bool breakFlag = false;
+
+	while (!breakFlag) {
+		opcode = nextVal(scriptData, offset);
+		switch (opcode) {
+		case S2_OPCODE_TIMEOUT:
+			param1 = nextVal(scriptData, offset);
+			h->setTickCtr(param1);
+			h->setScript(offset);
+			breakFlag = true;
+			break;
+
+		case S2_OPCODE_POSITION:
+			param1 = nextVal(scriptData, offset);
+			param2 = nextVal(scriptData, offset);
+			h->setPosition(param1 - 0x80, param2 - 0x80);
+			break;
+			
+		case S2_OPCODE_CHANGE_POS:
+			param1 = nextVal(scriptData, offset);
+			param2 = nextVal(scriptData, offset);
+			h->setPosition(h->x() + param1, h->y() + param2);
+			break;
+
+		case S2_OPCODE_UNLOAD:
+			breakFlag = true;
+			break;
+
+		case S2_OPCODE_DIMENSIONS:
+			param1 = nextVal(scriptData, offset) << 4;
+			param2 = nextVal(scriptData, offset);
+			h->setSize((uint16) param1, (uint16) param2);
+			break;
+
+		case S2_OPCODE_JUMP:
+			offset = (uint16) nextVal(scriptData, offset);
+			break;
+
+		case S2_OPCODE_ANIMATION:
+			param1 = nextVal(scriptData, offset);
+			h->setAnimation(param1);
+			break;
+
+		case S2_OPCODE_UNKNOWN_247:
+			param1 = nextVal(scriptData, offset);
+			param2 = nextVal(scriptData, offset);
+//			warning("UNKNOWN_247 stub called");
+			break;
+
+		case S2_OPCODE_UNKNOWN_258:
+			param1 = nextVal(scriptData, offset);
+//			warning("UNKNOWN_258 stub called");
+			break;
+
+		case S2_OPCODE_ACTIONS:
+			param1 = nextVal(scriptData, offset) << 4;
+			param2 = nextVal(scriptData, offset);
+			h->setActions((uint32) param1 | ((uint32) param2 << 16));
+			break;
+
+		default:
+			// Set the animation frame number
+			h->setFrameNumber(opcode);
+			h->setScript(offset);
+			breakFlag = true;
+			break;
+		}
+	}
+
+	return (opcode == S2_OPCODE_UNLOAD);
+}
+
+} // end of namespace Lure


Property changes on: scummvm/trunk/lure/scripts.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/scripts.h
===================================================================
--- scummvm/trunk/lure/scripts.h	                        (rev 0)
+++ scummvm/trunk/lure/scripts.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,117 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __lure_scripts_h__
+#define __lure_scripts_h__
+
+#include "lure/luredefs.h"
+#include "lure/memory.h"
+#include "lure/hotspots.h"
+
+namespace Lure {
+
+// Opcode list
+#define S_OPCODE_ABORT 0
+#define S_OPCODE_ADD 1
+#define S_OPCODE_SUBTRACT 2
+#define S_OPCODE_MULTIPLY 3
+#define S_OPCODE_DIVIDE 4
+#define S_OPCODE_NOT_EQUALS 5
+#define S_OPCODE_EQUALS 6
+#define S_OPCODE_GT 7
+#define S_OPCODE_LT 8
+#define S_OPCODE_LT2 9
+#define S_OPCODE_GT2 10
+#define S_OPCODE_AND 11
+#define S_OPCODE_OR 12
+#define S_OPCODE_LOGICAL_AND 13
+#define S_OPCODE_LOGICAL_OR 14
+#define S_OPCODE_GET_FIELD 15
+#define S_OPCODE_SET_FIELD 16
+#define S_OPCODE_PUSH 17
+#define S_OPCODE_SUBROUTINE 18
+#define S_OPCODE_EXEC 19
+#define S_OPCODE_END 20
+#define S_OPCODE_COND_JUMP 21
+#define S_OPCODE_JUMP 22
+#define S_OPCODE_ABORT2 23
+#define S_OPCODE_ABORT3 24
+#define S_OPCODE_RANDOM 25
+
+#define S2_OPCODE_TIMEOUT -1
+#define S2_OPCODE_POSITION -2
+#define S2_OPCODE_CHANGE_POS -3
+#define S2_OPCODE_UNLOAD -4
+#define S2_OPCODE_DIMENSIONS -5
+#define S2_OPCODE_JUMP -6
+#define S2_OPCODE_ANIMATION -7
+#define S2_OPCODE_UNKNOWN_247 -8
+#define S2_OPCODE_UNKNOWN_258 -9
+#define S2_OPCODE_ACTIONS -10
+
+
+
+class Script {
+public:
+	static uint16 execute(uint16 startOffset);
+
+	static void activateHotspot(uint16 hotspotId, uint16 v2, uint16 v3);
+	static void setHotspotScript(uint16 hotspotId, uint16 scriptIndex, uint16 v3);
+	static void clearSequenceDelayList(uint16 v1, uint16 scriptIndex, uint16 v3);
+	static void method2(uint16 v1, uint16 v2, uint16 v3);
+	static void deactivateHotspot(uint16 hotspotId, uint16 v2, uint16 v3);
+	static void setActionsOffset(uint16 hotspotId, uint16 offset, uint16 v3);
+	static void addDelayedSequence(uint16 seqOffset, uint16 delay, uint16 v3);
+	static void characterInRoom(uint16 characterId, uint16 roomNumber, uint16 v3);
+	static void setHotspotName(uint16 hotspotId, uint16 nameId, uint16 v3);
+	static void displayDialog(uint16 stringId, uint16 v2, uint16 v3);
+	static void remoteRoomViewSetup(uint16 v1, uint16 v2, uint16 v3);
+	static void getDoorBlocked(uint16 hotspotId, uint16 v2, uint16 v3);
+	static void decrInventoryItems(uint16 v1, uint16 v2, uint16 v3);
+	static void setFrameNumber(uint16 hotspotId, uint16 offset, uint16 v3);
+	static void disableHotspot(uint16 hotspotId, uint16 v2, uint16 v3);
+	static void increaseNumGroats(uint16 characterId, uint16 numGroats, uint16 v3);
+	static void enableHotspot(uint16 hotspotId, uint16 v2, uint16 v3);
+	static void room14DoorClose(uint16 v1, uint16 v2, uint16 v3);
+	static void checkDroppedDesc(uint16 hotspotId, uint16 v2, uint16 v3);
+	static void doorClose(uint16 hotspotId, uint16 v2, uint16 v3);
+	static void displayMessage(uint16 messageId, uint16 characterId, uint16 unknownVal);
+	static void doorOpen(uint16 hotspotId, uint16 v2, uint16 v3);
+	static void givePlayerItem(uint16 hotspotId, uint16 v2, uint16 v3);
+	static void decreaseNumGroats(uint16 characterId, uint16 numGroats, uint16 v3);
+	static void setVillageSkorlTickProc(uint16 v1, uint16 v2, uint16 v3);
+	static void getNumGroats(uint16 v1, uint16 v2, uint16 v3);
+	static void animationLoad(uint16 hotspotId, uint16 v2, uint16 v3);
+	static void addActions(uint16 hotspotId, uint16 actions, uint16 v3);
+	static void checkCellDoor(uint16 v1, uint16 v2, uint16 v3);
+};
+
+class HotspotScript {
+private:
+	static int16 nextVal(MemoryBlock *data, uint16 &offset);
+public:
+	static bool execute(Hotspot *h);
+};
+
+} // End of namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/scripts.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/strings.cpp
===================================================================
--- scummvm/trunk/lure/strings.cpp	                        (rev 0)
+++ scummvm/trunk/lure/strings.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,300 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/strings.h"
+#include "lure/disk.h"
+#include "lure/room.h"
+
+namespace Lure {
+
+StringData *int_strings = NULL;
+
+StringData::StringData() {
+    int_strings = this;
+
+	for (uint8 ctr = 0; ctr < MAX_NUM_CHARS; ++ctr) _chars[ctr] = NULL;
+	_numChars = 0;
+	_names = Disk::getReference().getEntry(NAMES_RESOURCE_ID);
+	_strings[0] = Disk::getReference().getEntry(STRINGS_RESOURCE_ID);
+	_strings[1] = Disk::getReference().getEntry(STRINGS_2_RESOURCE_ID);
+	_strings[2] = Disk::getReference().getEntry(STRINGS_3_RESOURCE_ID);
+
+	// Add in the list of bit sequences, and what characters they represent
+	add("00", ' ');
+	add("0100", 'e');
+	add("0101", 'o');
+	add("0110", 't');
+	add("01110", 'a');
+	add("01111", 'n');
+	add("1000", 's');
+	add("1001", 'i');
+	add("1010", 'r');
+	add("10110", 'h');
+	add("101110", 'u');
+	add("1011110", 'l');
+	add("1011111", 'd');
+	add("11000", 'y');
+	add("110010", 'g');
+	add("110011", '\0');
+	add("110100", 'w');
+	add("110101", 'c');
+	add("110110", 'f');
+	add("1101110", '.');
+	add("1101111", 'm');
+	add("111000", 'p');
+	add("111001", 'b');
+	add("1110100", ',');
+	add("1110101", 'k');
+	add("1110110", '\'');
+	add("11101110", 'I');
+	add("11101111", 'v');
+	add("1111000", '!');
+	add("1111001", '\xb4');
+	add("11110100", 'T');
+	add("11110101", '\xb5');
+	add("11110110", '?');
+	add("111101110", '\xb2');
+	add("111101111", '\xb3');
+	add("11111000", 'W');
+	add("111110010", 'H');
+	add("111110011", 'A');
+	add("111110100", '\xb1');
+	add("111110101", 'S');
+	add("111110110", 'Y');
+	add("1111101110", 'G');
+	add("11111011110", 'M');
+	add("11111011111", 'N');
+	add("111111000", 'O');
+	add("1111110010", 'E');
+	add("1111110011", 'L');
+	add("1111110100", '-');
+	add("1111110101", 'R');
+	add("1111110110", 'B');
+	add("11111101110", 'D');
+	add("11111101111", '\xa6');
+	add("1111111000", 'C');
+	add("11111110010", 'x');
+	add("11111110011", 'j');
+	add("1111111010", '\xac');
+	add("11111110110", '\xa3');
+	add("111111101110", 'P');
+	add("111111101111", 'U');
+	add("11111111000", 'q');
+	add("11111111001", '\xad');
+	add("111111110100", 'F');
+	add("111111110101", '1');
+	add("111111110110", '\xaf');
+	add("1111111101110", ';');
+	add("1111111101111", 'z');
+	add("111111111000", '\xa5');
+	add("1111111110010", '2');
+	add("1111111110011", '\xb0');
+	add("111111111010", 'K');
+	add("1111111110110", '%');
+	add("11111111101110", '\xa2');
+	add("11111111101111", '5');
+	add("1111111111000", ':');
+	add("1111111111001", 'J');
+	add("1111111111010", 'V');
+	add("11111111110110", '6');
+	add("11111111110111", '3');
+	add("1111111111100", '\xab');
+	add("11111111111010", '\xae');
+	add("111111111110110", '0');
+	add("111111111110111", '4');
+	add("11111111111100", '7');
+	add("111111111111010", '9');
+	add("111111111111011", '"');
+	add("111111111111100", '8');
+	add("111111111111101", '\xa7');
+	add("1111111111111100", '/');
+	add("1111111111111101", 'Q');
+	add("11111111111111100", '\xa8');
+	add("11111111111111101", '(');
+	add("111111111111111100", ')');
+	add("111111111111111101", '\x99');
+	add("11111111111111111", '\xa9');
+}
+
+StringData::~StringData() {
+	int_strings = NULL;
+
+	for (uint8 ctr = 0; ctr < MAX_NUM_CHARS; ++ctr)
+		if (_chars[ctr]) delete _chars[ctr];
+		else break;
+
+	delete _names;
+	delete _strings[0];
+	delete _strings[1];
+	delete _strings[2];
+}
+
+StringData &StringData::getReference() {
+	return *int_strings;
+}
+
+void StringData::add(const char *sequence, char ascii) {
+	uint32 value = 0;
+
+	for (uint8 index = 0; index < strlen(sequence); ++index) {
+		if (sequence[index] == '1') 
+			value |= (1 << index);
+		else if (sequence[index] != '0') 
+			error("Invalid character in string bit-stream sequence");
+	}
+
+	if (_numChars == MAX_NUM_CHARS) 
+		error("Max characters too lower in string decoder");
+	_chars[_numChars++] = new CharacterEntry(strlen(sequence), value, ascii);
+}
+
+byte StringData::readBit() {
+	byte result = ((*_srcPos & _bitMask) != 0) ? 1 : 0;
+	_bitMask >>= 1;
+	if (_bitMask == 0) {
+		_bitMask = 0x80;
+		++_srcPos;
+	}
+
+	return result;
+}
+
+void StringData::initPosition(uint16 stringId) {
+	uint16 roomNumber = Room::getReference().roomNumber();
+	byte *stringTable;
+	
+	if ((roomNumber >= 0x2A) && (stringId >= STRING_ID_RANGE) && (stringId < STRING_ID_UPPER)) 
+		stringId = 0x76;
+	if ((roomNumber < 0x2A) && (stringId >= STRING_ID_UPPER)) 
+		stringId = 0x76;
+
+	if (stringId < STRING_ID_RANGE)
+		stringTable = _strings[0]->data();
+	else if (stringId < STRING_ID_RANGE*2) {
+		stringId -= STRING_ID_RANGE;
+		stringTable = _strings[1]->data();
+	} else {
+		stringId -= STRING_ID_RANGE * 2;
+		stringTable = _strings[2]->data();
+	}
+
+	_srcPos = stringTable + 4;
+	
+	uint32 total = 0;
+	int numLoops = stringId >> 5;
+	for (int ctr = 0; ctr < numLoops; ++ctr) {
+		total += READ_LE_UINT16(_srcPos);
+		_srcPos += sizeof(uint16);
+	}
+
+	numLoops = stringId & 0x1f;
+	if (numLoops!= 0) {
+		byte *tempPtr = stringTable + (stringId & 0xffe0) + READ_LE_UINT16(stringTable);
+		
+		for (int ctr = 0; ctr < numLoops; ++ctr) {
+			byte v = *tempPtr++;
+			if ((v & 0x80) == 0) {
+				total += v;
+			} else {
+				total += (v & 0x7f) << 3;
+			}
+		}
+	}
+
+	_bitMask = 0x80;
+
+	if ((total & 3) != 0)
+		_bitMask >>= (total & 3) * 2;
+
+	_srcPos = stringTable + (total >> 2) + READ_LE_UINT16(stringTable + 2);
+
+	// Final positioning to start of string
+	for (;;) {
+		if (readBit() == 0) break;
+		_srcPos += 2;
+	}
+	readBit();
+}
+
+// readCharatcer
+// Reads the next character from the input bit stream
+
+char StringData::readCharacter() {
+	uint32 searchValue = 0;
+
+	// Loop through an increasing number of bits
+
+	for (uint8 numBits = 1; numBits <= 18; ++numBits) {
+		searchValue |= readBit() << (numBits - 1);
+
+		// Scan through list for a match
+		for (int index = 0; _chars[index] != NULL; ++index) {
+			if ((_chars[index]->_numBits == numBits) && 
+				(_chars[index]->_sequence == searchValue))
+				return _chars[index]->_ascii;
+		}
+	}
+
+	error("Unknown bit sequence encountered when decoding string");
+}
+
+void StringData::getString(uint16 stringId, char *dest, const char *hotspotName, 
+							  const char *actionName) {
+	char ch;
+	char *destPos = dest;
+	initPosition(stringId);
+
+	ch = readCharacter();
+	while (ch != '\0') {
+		if (ch == '%') {
+			// Copy over hotspot or action 
+			ch = readCharacter();
+			const char *p = (ch == '1') ? hotspotName : actionName;
+			strcpy(destPos, p);
+			destPos += strlen(p);
+		} else if ((uint8) ch >= 0xa0) {
+			const char *p = getName((uint8) ch - 0xa0);
+			strcpy(destPos, p);
+			destPos += strlen(p);
+		} else {
+			*destPos++ = ch;
+		}
+
+		ch = readCharacter();
+	}
+
+	*destPos = '\0';
+}
+
+// getName
+// Returns the name or fragment of word at the specified index in the names resource
+
+char *StringData::getName(uint8 nameIndex) {
+	uint16 numNames = *((uint16 *) _names->data()) / 2;
+	if (nameIndex >= numNames) 
+		error("Invalid name index was passed to getCharacterName");
+
+	uint16 nameStart = *((uint16 *) (_names->data() + (nameIndex * 2)));
+	return (char *) (_names->data() + nameStart);
+}
+
+} // namespace Lure


Property changes on: scummvm/trunk/lure/strings.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/strings.h
===================================================================
--- scummvm/trunk/lure/strings.h	                        (rev 0)
+++ scummvm/trunk/lure/strings.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,67 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __lure_strings_h__
+#define __lure_strings_h__
+
+#include "lure/luredefs.h"
+#include "lure/memory.h"
+
+namespace Lure {
+
+class CharacterEntry {
+public:
+	uint8 _numBits;
+	uint32 _sequence;
+	char _ascii;
+
+	CharacterEntry(uint8 numBits, uint32 sequence, char ascii): _numBits(numBits),
+		_sequence(sequence), _ascii(ascii) {};
+};
+
+#define MAX_NUM_CHARS 218
+
+class StringData {
+private:
+	MemoryBlock *_strings[3];
+	MemoryBlock *_names;
+	CharacterEntry *_chars[MAX_NUM_CHARS];
+	uint8 _numChars;
+	byte *_srcPos;
+	byte _bitMask;
+
+	void add(const char *sequence, char ascii);
+	void initPosition(uint16 stringId);
+	char readCharacter();
+	byte readBit();
+public:
+	StringData();
+	~StringData();
+	static StringData &getReference();
+
+	void getString(uint16 stringId, char *dest, const char *hotspotName, const char *actionName);
+	char *getName(uint8 nameIndex);
+};
+
+} // namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/strings.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/surface.cpp
===================================================================
--- scummvm/trunk/lure/surface.cpp	                        (rev 0)
+++ scummvm/trunk/lure/surface.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,456 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/surface.h"
+#include "lure/decode.h"
+#include "lure/system.h"
+#include "lure/events.h"
+#include "lure/screen.h"
+#include "lure/room.h"
+#include "lure/strings.h"
+
+namespace Lure {
+
+// These variables hold resources commonly used by the Surfaces, and must be initialised and freed
+// by the static Surface methods initialise and deinitailse
+
+static MemoryBlock *int_font = NULL;
+static MemoryBlock *int_dialog_frame = NULL;
+static uint8 fontSize[NUM_CHARS_IN_FONT];
+
+void Surface::initialise() {
+	int_font = Disk::getReference().getEntry(FONT_RESOURCE_ID);
+	int_dialog_frame = Disk::getReference().getEntry(DIALOG_RESOURCE_ID);
+
+	// Calculate the size of each font character
+	for (int ctr = 0; ctr < NUM_CHARS_IN_FONT; ++ctr) {
+		byte *pChar = int_font->data() + (ctr * 8);
+		fontSize[ctr] = 0;
+
+		for (int yp = 0; yp < FONT_HEIGHT; ++yp) 
+		{
+			byte v = *pChar++;
+
+			for (int xp = 0; xp < FONT_WIDTH; ++xp) {
+				if ((v & 0x80) && (xp > fontSize[ctr])) 
+					fontSize[ctr] = xp;
+				v = (v << 1) & 0xff;
+			}
+		}
+
+		// If character is empty, like for a space, give a default size
+		if (fontSize[ctr] == 0) fontSize[ctr] = 2;
+	}
+}
+
+void Surface::deinitialise() {
+	delete int_font;
+	delete int_dialog_frame;
+}
+
+/*--------------------------------------------------------------------------*/
+
+Surface::Surface(MemoryBlock *src, uint16 wdth, uint16 hght): _data(src), 
+		_width(wdth), _height(hght) {
+	if ((uint32) (wdth * hght) != src->size())
+		error("Surface dimensions do not match size of passed data");
+}
+
+Surface::Surface(uint16 wdth, uint16 hght): _data(Memory::allocate(wdth*hght)),
+	_width(wdth), _height(hght) {
+}
+
+Surface::~Surface() {
+	delete _data;
+}
+
+void Surface::loadScreen(uint16 resourceId) {
+	MemoryBlock *rawData = Disk::getReference().getEntry(resourceId);
+	PictureDecoder decoder;
+	MemoryBlock *tmpScreen = decoder.decode(rawData, FULL_SCREEN_HEIGHT * FULL_SCREEN_WIDTH);
+	delete rawData;
+	empty();
+	copyFrom(tmpScreen, MENUBAR_Y_SIZE * FULL_SCREEN_WIDTH);
+	
+	delete tmpScreen;
+}
+
+void Surface::writeChar(uint16 x, uint16 y, uint8 ascii, bool transparent, uint8 colour) {
+	byte *const addr = _data->data() + (y * _width) + x;
+
+	if ((ascii < 32) || (ascii >= 32 + NUM_CHARS_IN_FONT))
+		error("Invalid ascii character passed for display '%d'", ascii);
+	
+	uint8 v;
+	byte *pFont = int_font->data() + ((ascii - 32) * 8);
+	byte *pDest;
+	uint8 charWidth = 0;
+
+	for (int y1 = 0; y1 < 8; ++y1) {
+		v = *pFont++;
+		pDest = addr + (y1 * _width);
+
+		for (int x1 = 0; x1 < 8; ++x1, ++pDest) {
+			if (v & 0x80) {
+				*pDest = colour;
+				if (x1+1 > charWidth) charWidth = x1 + 1;
+			}
+			else if (!transparent) *pDest = 0;
+			v = (v << 1) & 0xff;
+		}
+	}
+}
+
+void Surface::writeString(uint16 x, uint16 y, Common::String line, bool transparent, 
+						  uint8 colour, bool varLength) {
+	const char *sPtr = line.c_str();
+
+	while (*sPtr) {
+		writeChar(x, y, (uint8) *sPtr, transparent, colour);
+
+		// Move to after the character in preparation for the next character
+		if (!varLength) x += FONT_WIDTH;
+		else x += fontSize[*sPtr - ' '] + 2;
+
+		++sPtr;		// Move to next character
+	}
+}
+
+void Surface::transparentCopyTo(Surface *dest) {
+	if (dest->width() != _width) 
+		error("Incompatible surface sizes for transparent copy");
+
+	byte *pSrc = _data->data();
+	byte *pDest = dest->data().data();
+	uint16 numBytes = MIN(_height,dest->height()) * FULL_SCREEN_WIDTH;
+
+	while (numBytes-- > 0) {
+		if (*pSrc) *pDest = *pSrc;
+		
+		++pSrc;
+		++pDest;
+	}
+}
+
+void Surface::copyTo(Surface *dest)
+{
+	copyTo(dest, 0, 0);
+}
+
+void Surface::copyTo(Surface *dest, uint16 x, uint16 y)
+{
+	if ((x == 0) && (dest->width() == _width)) {
+		// Use fast data transfer
+		uint32 dataSize = dest->data().size() - (y * _width);
+		if (dataSize > _data->size()) dataSize = _data->size();
+		dest->data().copyFrom(_data, 0, y * _width, dataSize);
+	} else {
+		// Use slower transfer
+		Rect rect;
+		rect.left = 0; rect.top = 0;
+		rect.right = _width-1; rect.bottom = _height-1;
+		copyTo(dest, rect, x, y);
+	}
+}
+
+void Surface::copyTo(Surface *dest, const Rect &srcBounds, 
+					 uint16 destX, uint16 destY, int transparentColour) {
+	for (uint16 y=0; y<=(srcBounds.bottom-srcBounds.top); ++y) {
+		const uint32 srcPos = (srcBounds.top + y) * _width + srcBounds.left;
+		const uint32 destPos = (destY+y) * dest->width() + destX;
+		
+		uint16 numBytes = srcBounds.right-srcBounds.left+1;
+		if (transparentColour == -1) {
+			// No trnnsparent colour, so copy all the bytes of the line
+			dest->data().copyFrom(_data, srcPos, destPos, numBytes);
+		} else {
+			byte *pSrc = _data->data() + srcPos;
+			byte *pDest = dest->data().data() + destPos;
+
+			while (numBytes-- > 0) {
+				if (*pSrc != (uint8) transparentColour)
+					*pDest = *pSrc;
+				++pSrc;
+				++pDest;
+			}
+		}
+	}
+}
+
+void Surface::copyFrom(MemoryBlock *src, uint32 destOffset) {
+	uint32 size = _data->size() - destOffset;
+	if (src->size() > size) size = src->size();
+	_data->copyFrom(src, 0, destOffset, size);
+}
+
+// fillRect
+// Fills a rectangular area with a colour
+
+void Surface::fillRect(const Rect &r, uint8 colour) {
+	for (int yp = r.top; yp <= r.bottom; ++yp) {
+		byte *const addr = _data->data() + (yp * _width) + r.left;
+		memset(addr, colour, r.width());
+	}
+}
+
+// createDialog
+// Forms a dialog encompassing the entire surface
+
+void copyLine(byte *pSrc, byte *pDest, uint16 leftSide, uint16 center, uint16 rightSide) {
+	// Left area
+	memcpy(pDest, pSrc, leftSide); 
+	pSrc += leftSide; pDest += leftSide; 
+	// Center area
+	memset(pDest, *pSrc, center);
+	++pSrc; pDest += center; 
+	// Right side
+	memcpy(pDest, pSrc, rightSide); 
+	pSrc += rightSide; pDest += rightSide; 
+}
+
+void Surface::createDialog(bool blackFlag) {
+	if ((_width < 20) || (_height < 20)) return;
+
+	byte *pSrc = int_dialog_frame->data();
+	byte *pDest = _data->data();
+	uint16 xCenter = _width - DIALOG_EDGE_SIZE * 2;
+	uint16 yCenter = _height - DIALOG_EDGE_SIZE * 2;
+
+	// Dialog top
+	for (int y = 0; y < 9; ++y) {
+		copyLine(pSrc, pDest, DIALOG_EDGE_SIZE - 2, xCenter + 2, DIALOG_EDGE_SIZE);
+		pSrc += (DIALOG_EDGE_SIZE - 2) + 1 + DIALOG_EDGE_SIZE;
+		pDest += _width;
+	}
+
+	// Dialog sides - note that the same source data gets used for all side lines
+	for (int y = 0; y < yCenter; ++y) {
+		copyLine(pSrc, pDest, DIALOG_EDGE_SIZE, xCenter, DIALOG_EDGE_SIZE);
+		pDest += _width;
+	}
+	pSrc += DIALOG_EDGE_SIZE * 2 + 1;
+
+	// Dialog bottom
+	for (int y = 0; y < 9; ++y) {
+		copyLine(pSrc, pDest, DIALOG_EDGE_SIZE, xCenter + 1, DIALOG_EDGE_SIZE - 1);
+		pSrc += DIALOG_EDGE_SIZE + 1 + (DIALOG_EDGE_SIZE - 1);
+		pDest += _width;
+	}
+
+	// Final processing - if black flag set, clear dialog inside area
+	if (blackFlag) {
+		Rect r = Rect(DIALOG_EDGE_SIZE, DIALOG_EDGE_SIZE, 
+			_width - DIALOG_EDGE_SIZE, _height-DIALOG_EDGE_SIZE);
+		fillRect(r, 0);
+	}
+}
+
+void Surface::copyToScreen(uint16 x, uint16 y) {
+	OSystem &system = System::getReference();
+	system.copyRectToScreen(_data->data(), _width, x, y, _width, _height);
+	system.updateScreen();
+}
+
+void Surface::centerOnScreen() {
+	OSystem &system = System::getReference();
+
+	system.copyRectToScreen(_data->data(), _width, 
+		(FULL_SCREEN_WIDTH - _width) / 2, (FULL_SCREEN_HEIGHT - _height) / 2,
+		_width, _height);
+	system.updateScreen();
+}
+
+uint16 Surface::textWidth(const char *s, int numChars) {
+	uint16 result = 0;
+	if (numChars == 0) numChars = strlen(s);
+
+	while (numChars-- > 0) result += fontSize[*s++ - ' '] + 2;
+	return result;
+}
+
+Surface *Surface::newDialog(uint16 width, uint8 numLines, char **lines, bool varLength, uint8 colour) {
+	Surface *s = new Surface(width, (DIALOG_EDGE_SIZE + 3) * 2 + 
+		numLines * (FONT_HEIGHT - 1));
+	s->createDialog();
+
+	for (uint8 ctr = 0; ctr < numLines; ++ctr)
+		s->writeString(DIALOG_EDGE_SIZE + 3, DIALOG_EDGE_SIZE + 3 + 
+			(ctr * (FONT_HEIGHT - 1)), lines[ctr], true, colour, varLength);
+	return s;
+}
+
+Surface *Surface::newDialog(uint16 width, const char *line, uint8 colour) {
+	uint8 numLines = 1;
+	uint16 lineWidth = 0;
+	char *s, *lineCopy;
+	bool newLine;
+
+	s = lineCopy = strdup(line);
+
+	// Scan through the text and insert NULLs to break the line into allowable widths
+
+	while (*s != '\0') {
+		char *wordStart = s;
+		while (*wordStart == ' ') ++wordStart;
+		char *wordEnd = strchr(wordStart, ' ');
+		char *wordEnd2 = strchr(wordStart, '\n');
+		if ((!wordEnd) || ((wordEnd2) && (wordEnd2 < wordEnd))) {
+			wordEnd = wordEnd2;
+			newLine = (wordEnd2 != NULL);
+		} else {
+			newLine = false;
+		}
+
+		if (wordEnd) --wordEnd; // move back one to end of word
+		else wordEnd = strchr(s, '\0') - 1;
+
+		uint16 wordSize = textWidth(s, (int) (wordEnd - s + 1));
+
+		if (lineWidth + wordSize > width - (DIALOG_EDGE_SIZE + 3) * 2) {
+			// Break word onto next line
+			*(wordStart - 1) = '\0';
+			++numLines;
+			lineWidth = textWidth(wordStart, (int) (wordEnd - wordStart + 1));
+		} else if (newLine) {
+			// Break on newline
+			++numLines;
+			++wordEnd;
+			*wordEnd = '\0';
+			lineWidth = 0;
+		} else {
+			// Add word's length to total for line
+			lineWidth += wordSize;
+		}
+
+		s = wordEnd+1;
+	}
+
+	// Set up a list for the start of each line 
+	char **lines = (char **) Memory::alloc(sizeof(char *) * numLines);
+	lines[0] = lineCopy;
+	for (int ctr = 1; ctr < numLines; ++ctr) 
+		lines[ctr] = strchr(lines[ctr-1], 0) + 1;
+
+	// Create the dialog 
+	Surface *result = newDialog(width, numLines, lines, true, colour);
+
+	// Deallocate used resources
+	free(lines);
+	free(lineCopy);
+
+	return result;
+}
+
+Surface *Surface::getScreen(uint16 resourceId) {
+	MemoryBlock *block = Disk::getReference().getEntry(resourceId);
+	PictureDecoder d;
+	MemoryBlock *decodedData = d.decode(block);
+	delete block;
+	return new Surface(decodedData, FULL_SCREEN_WIDTH, decodedData->size() / FULL_SCREEN_WIDTH);
+}
+
+/*--------------------------------------------------------------------------*/
+
+void Dialog::show(const char *text) {
+	Screen &screen = Screen::getReference();
+	Mouse &mouse = Mouse::getReference();
+	mouse.cursorOff();
+
+	Surface *s = Surface::newDialog(INFO_DIALOG_WIDTH, text);
+	s->copyToScreen(INFO_DIALOG_X, INFO_DIALOG_Y);
+
+	// Wait for a keypress or mouse button
+	Events::getReference().waitForPress();
+
+	screen.update();
+	mouse.cursorOn();
+}
+
+void Dialog::show(uint16 stringId) {
+	char buffer[MAX_DESC_SIZE];
+	Room &r = Room::getReference();
+	StringData &sl = StringData::getReference();
+
+	Action action = r.getCurrentAction();
+
+	const char *actionName = (action == NONE) ? NULL : actionList[action];
+	char hotspotName[MAX_HOTSPOT_NAME_SIZE];
+	if (r.hotspotId() == 0) 
+		strcpy(hotspotName, "");
+	else
+		sl.getString(r.hotspot().nameId, hotspotName, NULL, NULL);
+
+	sl.getString(stringId, buffer, hotspotName, actionName);
+	show(buffer);
+}
+
+void Dialog::showMessage(uint16 messageId, uint16 characterId) {
+	MemoryBlock *data = Resources::getReference().messagesData();
+    uint16 *v = (uint16 *) data->data();
+	uint16 v2, idVal;
+	messageId &= 0x7fff;
+
+	// Skip through header to find table for given character
+	while (READ_LE_UINT16(v) != characterId) v += 2;
+
+	// Scan through secondary list
+	++v;
+	v = (uint16 *) (data->data() + READ_LE_UINT16(v));
+	v2 = 0;
+	while ((idVal = READ_LE_UINT16(v)) != 0xffff) {
+		++v;
+		if (READ_LE_UINT16(v) == messageId) break;
+		++v;
+	}
+	// default response if a specific response not found
+	if (idVal == 0xffff) idVal = 0x8c4; 
+	
+	if (idVal == 0x76) {
+		/* 
+		call    sub_154                 ; (64E7)
+		mov     ax,word ptr ds:[5813h]  ; (273F:5813=1BA3h)
+		mov     [bx+ANIM_SEGMENT],ax
+		mov     ax,word ptr ds:[5817h]  ; (273F:5817=0ED8Eh)
+		mov     [bx+ANIM_FRAME],ax
+		retn
+*/
+	} else if (idVal == 0x120) {
+		/* 
+		call    sub_154                 ; (64E7)
+		mov     ax,word ptr ds:[5813h]  ; (273F:5813=1BA3h)
+		mov     [bx+ANIM_SEGMENT],ax
+		mov     ax,word ptr ds:[5817h]  ; (273F:5817=0ED8Eh)
+		shl     ax,1
+		mov     [bx+ANIM_FRAME],ax
+*/
+	} else if (idVal >= 0x8000) {
+		// Handle string display
+		idVal &= 0x7fff;
+		Dialog::show(idVal);
+		
+	} else if (idVal != 0) {
+		/* still to be decoded */
+
+	}
+}
+
+} // end of namespace Lure


Property changes on: scummvm/trunk/lure/surface.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/surface.h
===================================================================
--- scummvm/trunk/lure/surface.h	                        (rev 0)
+++ scummvm/trunk/lure/surface.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,83 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __lure_surface_h__
+#define __lure_surface_h__
+
+#include "common/stdafx.h"
+#include "common/str.h"
+#include "lure/disk.h"
+#include "lure/luredefs.h"
+
+using namespace Common;
+
+namespace Lure {
+
+class Surface {
+private:
+	MemoryBlock *_data;	
+	uint16 _width, _height;
+public:
+	Surface(MemoryBlock *src, uint16 width, uint16 height);
+	Surface(uint16 width, uint16 height);		
+	~Surface();
+	
+	static void initialise();
+	static void deinitialise();
+
+	uint16 width() { return _width; }
+	uint16 height() { return _height; }
+	MemoryBlock &data() { return *_data; }
+
+	void loadScreen(uint16 resourceId);
+	void writeChar(uint16 x, uint16 y, uint8 ascii, bool transparent, uint8 colour);
+	void writeString(uint16 x, uint16 y, Common::String line, bool transparent, 
+		uint8 colour = DIALOG_TEXT_COLOUR, bool varLength = true);
+	void transparentCopyTo(Surface *dest);
+	void copyTo(Surface *dest);
+	void copyTo(Surface *dest, uint16 x, uint16 y);
+	void copyTo(Surface *dest, const Rect &srcBounds, uint16 destX, uint16 destY,
+		int transparentColour = -1);
+	void copyFrom(MemoryBlock *src) { _data->copyFrom(src); }
+	void copyFrom(MemoryBlock *src, uint32 destOffset);
+	void empty() { _data->empty(); }
+	void fillRect(const Rect &r, uint8 colour);
+	void createDialog(bool blackFlag = false);
+	void copyToScreen(uint16 x, uint16 y);
+	void centerOnScreen();
+
+	static uint16 textWidth(const char *s, int numChars = 0);
+	static Surface *newDialog(uint16 width, uint8 numLines, char **lines, bool varLength = true, uint8 colour = DIALOG_TEXT_COLOUR);
+	static Surface *newDialog(uint16 width, const char *lines, uint8 colour = DIALOG_TEXT_COLOUR);
+	static Surface *getScreen(uint16 resourceId);
+};
+
+class Dialog {
+public:
+	static void show(const char *text);
+	static void show(uint16 stringId);
+	static void showMessage(uint16 messageId, uint16 characterId);
+};
+
+} // End of namespace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/surface.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/system.cpp
===================================================================
--- scummvm/trunk/lure/system.cpp	                        (rev 0)
+++ scummvm/trunk/lure/system.cpp	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,41 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "lure/system.h"
+
+namespace Lure {
+
+OSystem *int_system = NULL;
+
+System::System(OSystem *sys) {
+	int_system = sys;
+}
+
+System::~System() {
+	int_system = NULL;
+}
+
+OSystem &System::getReference() {
+    return *int_system;
+}
+
+} // end of namespace Lure


Property changes on: scummvm/trunk/lure/system.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Added: scummvm/trunk/lure/system.h
===================================================================
--- scummvm/trunk/lure/system.h	                        (rev 0)
+++ scummvm/trunk/lure/system.h	2006-02-11 12:54:56 UTC (rev 20536)
@@ -0,0 +1,40 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2005-2006 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef __lure_system_h__
+#define __lure_system_h__
+
+#include "common/stdafx.h"
+#include "common/system.h"
+
+namespace Lure {
+
+class System {
+public:
+	System(OSystem *sys);
+	~System();
+	static OSystem &getReference();
+};
+
+} // end of namspace Lure
+
+#endif


Property changes on: scummvm/trunk/lure/system.h
___________________________________________________________________
Name: svn:mime-type
   + text/plain







More information about the Scummvm-git-logs mailing list