[Scummvm-cvs-logs] SF.net SVN: scummvm:[53579] scummvm/trunk/engines
sev at users.sourceforge.net
sev at users.sourceforge.net
Mon Oct 18 21:17:39 CEST 2010
Revision: 53579
http://scummvm.svn.sourceforge.net/scummvm/?rev=53579&view=rev
Author: sev
Date: 2010-10-18 19:17:38 +0000 (Mon, 18 Oct 2010)
Log Message:
-----------
LASTEXPRESS: Merge in the engine.
Added Paths:
-----------
scummvm/trunk/engines/lastexpress/
scummvm/trunk/engines/lastexpress/data/
scummvm/trunk/engines/lastexpress/data/animation.cpp
scummvm/trunk/engines/lastexpress/data/animation.h
scummvm/trunk/engines/lastexpress/data/archive.cpp
scummvm/trunk/engines/lastexpress/data/archive.h
scummvm/trunk/engines/lastexpress/data/background.cpp
scummvm/trunk/engines/lastexpress/data/background.h
scummvm/trunk/engines/lastexpress/data/cursor.cpp
scummvm/trunk/engines/lastexpress/data/cursor.h
scummvm/trunk/engines/lastexpress/data/font.cpp
scummvm/trunk/engines/lastexpress/data/font.h
scummvm/trunk/engines/lastexpress/data/scene.cpp
scummvm/trunk/engines/lastexpress/data/scene.h
scummvm/trunk/engines/lastexpress/data/sequence.cpp
scummvm/trunk/engines/lastexpress/data/sequence.h
scummvm/trunk/engines/lastexpress/data/snd.cpp
scummvm/trunk/engines/lastexpress/data/snd.h
scummvm/trunk/engines/lastexpress/data/subtitle.cpp
scummvm/trunk/engines/lastexpress/data/subtitle.h
scummvm/trunk/engines/lastexpress/debug.cpp
scummvm/trunk/engines/lastexpress/debug.h
scummvm/trunk/engines/lastexpress/detection.cpp
scummvm/trunk/engines/lastexpress/drawable.h
scummvm/trunk/engines/lastexpress/entities/
scummvm/trunk/engines/lastexpress/entities/abbot.cpp
scummvm/trunk/engines/lastexpress/entities/abbot.h
scummvm/trunk/engines/lastexpress/entities/alexei.cpp
scummvm/trunk/engines/lastexpress/entities/alexei.h
scummvm/trunk/engines/lastexpress/entities/alouan.cpp
scummvm/trunk/engines/lastexpress/entities/alouan.h
scummvm/trunk/engines/lastexpress/entities/anna.cpp
scummvm/trunk/engines/lastexpress/entities/anna.h
scummvm/trunk/engines/lastexpress/entities/august.cpp
scummvm/trunk/engines/lastexpress/entities/august.h
scummvm/trunk/engines/lastexpress/entities/boutarel.cpp
scummvm/trunk/engines/lastexpress/entities/boutarel.h
scummvm/trunk/engines/lastexpress/entities/chapters.cpp
scummvm/trunk/engines/lastexpress/entities/chapters.h
scummvm/trunk/engines/lastexpress/entities/cooks.cpp
scummvm/trunk/engines/lastexpress/entities/cooks.h
scummvm/trunk/engines/lastexpress/entities/coudert.cpp
scummvm/trunk/engines/lastexpress/entities/coudert.h
scummvm/trunk/engines/lastexpress/entities/entity.cpp
scummvm/trunk/engines/lastexpress/entities/entity.h
scummvm/trunk/engines/lastexpress/entities/entity39.cpp
scummvm/trunk/engines/lastexpress/entities/entity39.h
scummvm/trunk/engines/lastexpress/entities/entity_intern.h
scummvm/trunk/engines/lastexpress/entities/francois.cpp
scummvm/trunk/engines/lastexpress/entities/francois.h
scummvm/trunk/engines/lastexpress/entities/gendarmes.cpp
scummvm/trunk/engines/lastexpress/entities/gendarmes.h
scummvm/trunk/engines/lastexpress/entities/hadija.cpp
scummvm/trunk/engines/lastexpress/entities/hadija.h
scummvm/trunk/engines/lastexpress/entities/ivo.cpp
scummvm/trunk/engines/lastexpress/entities/ivo.h
scummvm/trunk/engines/lastexpress/entities/kahina.cpp
scummvm/trunk/engines/lastexpress/entities/kahina.h
scummvm/trunk/engines/lastexpress/entities/kronos.cpp
scummvm/trunk/engines/lastexpress/entities/kronos.h
scummvm/trunk/engines/lastexpress/entities/mahmud.cpp
scummvm/trunk/engines/lastexpress/entities/mahmud.h
scummvm/trunk/engines/lastexpress/entities/max.cpp
scummvm/trunk/engines/lastexpress/entities/max.h
scummvm/trunk/engines/lastexpress/entities/mertens.cpp
scummvm/trunk/engines/lastexpress/entities/mertens.h
scummvm/trunk/engines/lastexpress/entities/milos.cpp
scummvm/trunk/engines/lastexpress/entities/milos.h
scummvm/trunk/engines/lastexpress/entities/mmeboutarel.cpp
scummvm/trunk/engines/lastexpress/entities/mmeboutarel.h
scummvm/trunk/engines/lastexpress/entities/pascale.cpp
scummvm/trunk/engines/lastexpress/entities/pascale.h
scummvm/trunk/engines/lastexpress/entities/rebecca.cpp
scummvm/trunk/engines/lastexpress/entities/rebecca.h
scummvm/trunk/engines/lastexpress/entities/salko.cpp
scummvm/trunk/engines/lastexpress/entities/salko.h
scummvm/trunk/engines/lastexpress/entities/servers0.cpp
scummvm/trunk/engines/lastexpress/entities/servers0.h
scummvm/trunk/engines/lastexpress/entities/servers1.cpp
scummvm/trunk/engines/lastexpress/entities/servers1.h
scummvm/trunk/engines/lastexpress/entities/sophie.cpp
scummvm/trunk/engines/lastexpress/entities/sophie.h
scummvm/trunk/engines/lastexpress/entities/tables.cpp
scummvm/trunk/engines/lastexpress/entities/tables.h
scummvm/trunk/engines/lastexpress/entities/tatiana.cpp
scummvm/trunk/engines/lastexpress/entities/tatiana.h
scummvm/trunk/engines/lastexpress/entities/train.cpp
scummvm/trunk/engines/lastexpress/entities/train.h
scummvm/trunk/engines/lastexpress/entities/vassili.cpp
scummvm/trunk/engines/lastexpress/entities/vassili.h
scummvm/trunk/engines/lastexpress/entities/verges.cpp
scummvm/trunk/engines/lastexpress/entities/verges.h
scummvm/trunk/engines/lastexpress/entities/vesna.cpp
scummvm/trunk/engines/lastexpress/entities/vesna.h
scummvm/trunk/engines/lastexpress/entities/yasmin.cpp
scummvm/trunk/engines/lastexpress/entities/yasmin.h
scummvm/trunk/engines/lastexpress/eventhandler.h
scummvm/trunk/engines/lastexpress/game/
scummvm/trunk/engines/lastexpress/game/action.cpp
scummvm/trunk/engines/lastexpress/game/action.h
scummvm/trunk/engines/lastexpress/game/beetle.cpp
scummvm/trunk/engines/lastexpress/game/beetle.h
scummvm/trunk/engines/lastexpress/game/entities.cpp
scummvm/trunk/engines/lastexpress/game/entities.h
scummvm/trunk/engines/lastexpress/game/fight.cpp
scummvm/trunk/engines/lastexpress/game/fight.h
scummvm/trunk/engines/lastexpress/game/inventory.cpp
scummvm/trunk/engines/lastexpress/game/inventory.h
scummvm/trunk/engines/lastexpress/game/logic.cpp
scummvm/trunk/engines/lastexpress/game/logic.h
scummvm/trunk/engines/lastexpress/game/menu.cpp
scummvm/trunk/engines/lastexpress/game/menu.h
scummvm/trunk/engines/lastexpress/game/object.cpp
scummvm/trunk/engines/lastexpress/game/object.h
scummvm/trunk/engines/lastexpress/game/savegame.cpp
scummvm/trunk/engines/lastexpress/game/savegame.h
scummvm/trunk/engines/lastexpress/game/savepoint.cpp
scummvm/trunk/engines/lastexpress/game/savepoint.h
scummvm/trunk/engines/lastexpress/game/scenes.cpp
scummvm/trunk/engines/lastexpress/game/scenes.h
scummvm/trunk/engines/lastexpress/game/sound.cpp
scummvm/trunk/engines/lastexpress/game/sound.h
scummvm/trunk/engines/lastexpress/game/state.cpp
scummvm/trunk/engines/lastexpress/game/state.h
scummvm/trunk/engines/lastexpress/graphics.cpp
scummvm/trunk/engines/lastexpress/graphics.h
scummvm/trunk/engines/lastexpress/helpers.h
scummvm/trunk/engines/lastexpress/lastexpress.cpp
scummvm/trunk/engines/lastexpress/lastexpress.h
scummvm/trunk/engines/lastexpress/module.mk
scummvm/trunk/engines/lastexpress/resource.cpp
scummvm/trunk/engines/lastexpress/resource.h
scummvm/trunk/engines/lastexpress/shared.h
Added: scummvm/trunk/engines/lastexpress/data/animation.cpp
===================================================================
--- scummvm/trunk/engines/lastexpress/data/animation.cpp (rev 0)
+++ scummvm/trunk/engines/lastexpress/data/animation.cpp 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,300 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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$
+ *
+ */
+
+// Based on Deniz Oezmen's code: http://oezmen.eu/
+
+#include "lastexpress/data/animation.h"
+
+#include "lastexpress/data/sequence.h"
+#include "lastexpress/data/snd.h"
+
+#include "lastexpress/debug.h"
+
+#include "common/events.h"
+#include "engines/engine.h"
+
+namespace LastExpress {
+
+Animation::Animation() : _stream(NULL), _currentChunk(NULL), _overlay(NULL), _background1(NULL), _background2(NULL), _backgroundCurrent(0), _audio(NULL), _startTime(0), _changed(false), _flag(0) {
+}
+
+Animation::~Animation() {
+ reset();
+}
+
+void Animation::reset() {
+ delete _overlay;
+ _overlay = NULL;
+ delete _background1;
+ _background1 = NULL;
+ delete _background2;
+ _background2 = NULL;
+ delete _audio;
+ _audio = NULL;
+
+ _backgroundCurrent = 0;
+ _chunks.clear();
+
+ _currentChunk = NULL;
+
+ delete _stream;
+}
+
+bool Animation::load(Common::SeekableReadStream *stream, int flag) {
+ if (!stream)
+ return false;
+
+ reset();
+
+ // Keep stream for later decoding of animation
+ _stream = stream;
+
+ // Read header to get the number of chunks
+ uint32 numChunks = _stream->readUint32LE();
+ debugC(3, kLastExpressDebugGraphics, "Number of chunks in NIS file: %d", numChunks);
+
+ // Check if there is enough data
+ if (_stream->size() - _stream->pos() < (signed)(numChunks * sizeof(Chunk))) {
+ debugC(2, kLastExpressDebugGraphics, "NIS file seems to be corrupted!");
+ return false;
+ }
+
+ // Read all the chunks
+ for (uint32 i = 0; i < numChunks; ++i) {
+ Chunk chunk;
+ chunk.type = (ChunkType)_stream->readUint16LE();
+ chunk.frame = _stream->readUint16LE();
+ chunk.size = _stream->readUint32LE();
+
+ _chunks.push_back(chunk);
+
+ debugC(9, kLastExpressDebugGraphics, "Chunk Entry: type 0x%.4x, frame=%d, size=%d", chunk.type, chunk.frame, chunk.size);
+ }
+ _currentChunk = _chunks.begin();
+ _changed = false;
+ _startTime = g_engine->_system->getMillis();
+
+ return true;
+}
+
+bool Animation::process() {
+ if (!_currentChunk)
+ error("Animation::process - internal error: the current chunk iterator is invalid!");
+
+ if (_stream == NULL || _chunks.size() == 0)
+ error("Trying to show an animation before loading data");
+
+ // TODO: substract the time paused by the GUI
+ uint32 currentFrame = (uint32)(((float)(g_engine->_system->getMillis() - _startTime)) / 33.33f);
+
+ // Process all chunks until the current frame
+ while (!_changed && currentFrame > _currentChunk->frame && !hasEnded()) {
+ switch(_currentChunk->type) {
+ //TODO: some info chunks are probably subtitle/sync related
+ case kChunkTypeUnknown1:
+ case kChunkTypeUnknown2:
+ case kChunkTypeUnknown5:
+ debugC(9, kLastExpressDebugGraphics | kLastExpressDebugUnknown, " info chunk: type 0x%.4x (size %d)", _currentChunk->type, _currentChunk->size);
+ assert (_currentChunk->frame == 0);
+ //TODO: _currentChunk->size?
+ break;
+
+ case kChunkTypeAudioInfo:
+ debugC(9, kLastExpressDebugGraphics, " audio info: %d blocks", _currentChunk->size);
+ assert (_currentChunk->frame == 0);
+ //TODO: save the size?
+ _audio = new AppendableSound();
+ break;
+
+ case kChunkTypeUnknown4:
+ debugC(9, kLastExpressDebugGraphics | kLastExpressDebugUnknown, " info block 4");
+ assert (_currentChunk->frame == 0 && _currentChunk->size == 0);
+ //TODO unknown type of chunk
+ break;
+
+ case kChunkTypeBackground1:
+ debugC(9, kLastExpressDebugGraphics, " background frame 1 (%d bytes, frame %d)", _currentChunk->size, _currentChunk->frame);
+ delete _background1;
+ _background1 = processChunkFrame(_stream, *_currentChunk);
+ break;
+
+ case kChunkTypeSelectBackground1:
+ debugC(9, kLastExpressDebugGraphics, " select background 1");
+ assert (_currentChunk->frame == 0 && _currentChunk->size == 0);
+ _backgroundCurrent = 1;
+ break;
+
+ case kChunkTypeBackground2:
+ debugC(9, kLastExpressDebugGraphics, " background frame 2 (%d bytes, frame %d)", _currentChunk->size, _currentChunk->frame);
+ delete _background2;
+ _background2 = processChunkFrame(_stream, *_currentChunk);
+ break;
+
+ case kChunkTypeSelectBackground2:
+ debugC(9, kLastExpressDebugGraphics, " select background 2");
+ assert (_currentChunk->frame == 0 && _currentChunk->size == 0);
+ _backgroundCurrent = 2;
+ break;
+
+ case kChunkTypeOverlay:
+ debugC(9, kLastExpressDebugGraphics, " overlay frame (%d bytes, frame %d)", _currentChunk->size, _currentChunk->frame);
+ delete _overlay;
+ _overlay = processChunkFrame(_stream, *_currentChunk);
+ break;
+
+ case kChunkTypeUpdate:
+ case kChunkTypeUpdateTransition:
+ debugC(9, kLastExpressDebugGraphics, " update%s: frame %d", _currentChunk->type == 15 ? "" : " with transition", _currentChunk->frame);
+ assert (_currentChunk->size == 0);
+ _changed = true;
+ break;
+
+ case kChunkTypeAudioData:
+ debugC(9, kLastExpressDebugGraphics, " audio (%d blocks, %d bytes, frame %d)", _currentChunk->size / _soundBlockSize, _currentChunk->size, _currentChunk->frame);
+ processChunkAudio(_stream, *_currentChunk);
+
+ // Synchronize the audio by resetting the start time
+ if (_currentChunk->frame == 0)
+ _startTime = g_engine->_system->getMillis();
+ break;
+
+ case kChunkTypeAudioEnd:
+ debugC(9, kLastExpressDebugGraphics, " audio end: %d blocks", _currentChunk->frame);
+ assert (_currentChunk->size == 0);
+ _audio->finish();
+ //TODO: we need to start the linked sound (.LNK) after the audio from the animation ends
+ break;
+
+ default:
+ error(" UNKNOWN chunk type=%x frame=%d size=%d", _currentChunk->type, _currentChunk->frame, _currentChunk->size);
+ break;
+ }
+ _currentChunk++;
+ }
+
+ return true;
+}
+
+bool Animation::hasEnded() {
+ return _currentChunk == _chunks.end();
+}
+
+Common::Rect Animation::draw(Graphics::Surface *surface) {
+ if (!_overlay)
+ error("Animation::draw - internal error: the current overlay animation frame is invalid!");
+
+ // Paint the background
+ if (_backgroundCurrent == 1 && _background1)
+ _background1->draw(surface);
+ else if (_backgroundCurrent == 2 && _background2)
+ _background2->draw(surface);
+
+ // Paint the overlay
+ _overlay->draw(surface);
+
+ //TODO
+ return Common::Rect();
+}
+
+AnimFrame *Animation::processChunkFrame(Common::SeekableReadStream *in, const Chunk &c) const {
+ assert (c.frame == 0);
+
+ // Create a temporary chunk buffer
+ Common::MemoryReadStream *str = in->readStream(c.size);
+
+ // Read the frame information
+ FrameInfo i;
+ i.read(str, false);
+
+ // Decode the frame
+ AnimFrame *f = new AnimFrame(str, i);
+
+ // Delete the temporary chunk buffer
+ delete str;
+
+ return f;
+}
+
+void Animation::processChunkAudio(Common::SeekableReadStream *in, const Chunk &c) {
+ if (!_audio)
+ error("Animation::processChunkAudio - internal error: the audio stream is invalid!");
+
+ // Skip the Snd header, to queue just the audio blocks
+ uint32 size = c.size;
+ if ((c.size % 739) != 0) {
+ // Read Snd header
+ uint32 header1 = in->readUint32LE();
+ uint16 header2 = in->readUint16LE();
+ warning("Start ADPCM: %d, %d", header1, header2);
+ size -= 6;
+ }
+
+ // Append the current chunk to the Snd
+ _audio->queueBuffer(in->readStream(size));
+}
+
+// TODO: this method will probably go away and be integrated in the main loop
+void Animation::play() {
+ while (!hasEnded() && !g_engine->getEventManager()->shouldQuit() && !g_engine->getEventManager()->shouldRTL()) {
+ process();
+
+ if (_changed) {
+ // Create a temporary surface to merge the overlay with the background
+ Graphics::Surface *s = new Graphics::Surface;
+ s->create(640, 480, 2);
+
+ draw(s);
+
+ // XXX: Update the screen
+ g_system->copyRectToScreen((byte *)s->pixels, s->pitch, 0, 0, s->w, s->h);
+
+ // Free the temporary surface
+ s->free();
+ delete s;
+
+ _changed = false;
+ }
+
+ g_system->updateScreen();
+
+ //FIXME: implement subtitles
+ g_engine->_system->delayMillis(20);
+
+ // Handle right-click to interrupt animations
+ Common::Event ev;
+ while (g_engine->getEventManager()->pollEvent(ev)) {
+ if (ev.type == Common::EVENT_RBUTTONUP) {
+ // Stop audio
+ if (_audio)
+ _audio->finish();
+
+ // TODO start LNK file sound?
+ return;
+ }
+ }
+ }
+}
+
+} // End of namespace LastExpress
Property changes on: scummvm/trunk/engines/lastexpress/data/animation.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/lastexpress/data/animation.h
===================================================================
--- scummvm/trunk/engines/lastexpress/data/animation.h (rev 0)
+++ scummvm/trunk/engines/lastexpress/data/animation.h 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,114 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 LASTEXPRESS_ANIMATION_H
+#define LASTEXPRESS_ANIMATION_H
+
+/*
+ Animation format (.NIS)
+
+ uint32 {4} - Number of chunks
+
+ // for each chunk
+ uint16 {2} - Type
+ uint16 {2} - Tag
+ uint32 {4} - Size of chunk
+ byte {x} - Data (for "data" chunks: backgrounds, overlay & audio data)
+*/
+
+#include "lastexpress/drawable.h"
+
+#include "common/array.h"
+#include "common/stream.h"
+
+namespace LastExpress {
+
+class AnimFrame;
+class AppendableSound;
+
+class Animation : public Drawable {
+public:
+ enum FlagType {
+ kFlagDefault = 16384,
+ kFlagProcess = 49152
+ };
+
+ Animation();
+ ~Animation();
+
+ bool load(Common::SeekableReadStream *stream, int flag = kFlagDefault);
+ bool process();
+ bool hasEnded();
+ Common::Rect draw(Graphics::Surface *surface);
+ void play();
+
+private:
+ static const uint32 _soundBlockSize = 739;
+
+ // despite their size field, info chunks don't have a payload
+ enum ChunkType {
+ kChunkTypeUnknown1 = 1,
+ kChunkTypeUnknown2 = 2,
+ kChunkTypeAudioInfo = 3,
+ kChunkTypeUnknown4 = 4,
+ kChunkTypeUnknown5 = 5,
+ kChunkTypeBackground1 = 10,
+ kChunkTypeSelectBackground1 = 11,
+ kChunkTypeBackground2 = 12,
+ kChunkTypeSelectBackground2 = 13,
+ kChunkTypeOverlay = 20,
+ kChunkTypeUpdate = 21,
+ kChunkTypeUpdateTransition = 22,
+ kChunkTypeSound1 = 30,
+ kChunkTypeSound2 = 31,
+ kChunkTypeAudioData = 32,
+ kChunkTypeAudioEnd = 99
+ };
+
+ struct Chunk {
+ ChunkType type;
+ uint16 frame;
+ uint32 size;
+ };
+
+ void reset();
+ AnimFrame *processChunkFrame(Common::SeekableReadStream *in, const Chunk &c) const;
+ void processChunkAudio(Common::SeekableReadStream *in, const Chunk &c);
+
+ Common::SeekableReadStream *_stream;
+ Common::Array<Chunk> _chunks;
+ Common::Array<Chunk>::iterator _currentChunk;
+ AnimFrame *_overlay, *_background1, *_background2;
+ byte _backgroundCurrent;
+ AppendableSound *_audio;
+
+ uint32 _startTime;
+ bool _changed;
+ int _flag;
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_ANIMATION_H
Property changes on: scummvm/trunk/engines/lastexpress/data/animation.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/lastexpress/data/archive.cpp
===================================================================
--- scummvm/trunk/engines/lastexpress/data/archive.cpp (rev 0)
+++ scummvm/trunk/engines/lastexpress/data/archive.cpp 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,115 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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$
+ *
+ */
+
+// Based on the Xentax Wiki documentation:
+// http://wiki.xentax.com/index.php/The_Last_Express_SND
+
+#include "lastexpress/data/archive.h"
+
+#include "lastexpress/debug.h"
+
+#include "common/debug.h"
+#include "common/file.h"
+
+namespace LastExpress {
+
+HPFArchive::HPFArchive(const Common::String &path) {
+ _filename = path;
+
+ // Open a stream to the archive
+ Common::SeekableReadStream *archive = SearchMan.createReadStreamForMember(_filename);
+ if (!archive) {
+ debugC(2, kLastExpressDebugResource, "Error opening file: %s", path.c_str());
+ return;
+ }
+
+ debugC(2, kLastExpressDebugResource, "Opened archive: %s", path.c_str());
+
+ // Read header to get the number of files
+ uint32 numFiles = archive->readUint32LE();
+ debugC(3, kLastExpressDebugResource, "Number of files in archive: %d", numFiles);
+
+ // Read the list of files
+ for (unsigned int i = 0; i < numFiles; ++i) {
+ char name[13];
+ HPFEntry entry;
+
+ archive->read(&name, sizeof(char) * _archiveNameSize);
+ entry.offset = archive->readUint32LE();
+ entry.size = archive->readUint32LE();
+ entry.isOnHD = archive->readUint16LE();
+
+ // Terminate string
+ name[12] = '\0';
+
+ Common::String filename(name);
+ filename.toLowercase();
+
+ _files[filename] = entry;
+
+ //debugC(9, kLastExpressDebugResource, "File entry: %s (offset:%d - Size: %d - HD: %u)", &name, entry.offset, entry.size, entry.isOnHD);
+ }
+
+ // Close stream
+ delete archive;
+}
+
+bool HPFArchive::hasFile(const Common::String &name) {
+ return (_files.find(name) != _files.end());
+}
+
+int HPFArchive::listMembers(Common::ArchiveMemberList &list) {
+ int numMembers = 0;
+
+ for (FileMap::const_iterator i = _files.begin(); i != _files.end(); ++i) {
+ list.push_back(Common::ArchiveMemberList::value_type(new Common::GenericArchiveMember(i->_key, this)));
+ numMembers++;
+ }
+
+ return numMembers;
+}
+
+Common::ArchiveMemberPtr HPFArchive::getMember(const Common::String &name) {
+ if (!hasFile(name))
+ return Common::ArchiveMemberPtr();
+
+ return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
+}
+
+Common::SeekableReadStream *HPFArchive::createReadStreamForMember(const Common::String &name) const {
+ FileMap::const_iterator fDesc = _files.find(name);
+ if (fDesc == _files.end())
+ return NULL;
+
+ Common::File *archive = new Common::File();
+ if (!archive->open(_filename)) {
+ delete archive;
+ return NULL;
+ }
+
+ return new Common::SeekableSubReadStream(archive, fDesc->_value.offset * _archiveSectorSize, fDesc->_value.offset * _archiveSectorSize + fDesc->_value.size * _archiveSectorSize, DisposeAfterUse::YES);
+}
+
+} // End of namespace LastExpress
Property changes on: scummvm/trunk/engines/lastexpress/data/archive.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/lastexpress/data/archive.h
===================================================================
--- scummvm/trunk/engines/lastexpress/data/archive.h (rev 0)
+++ scummvm/trunk/engines/lastexpress/data/archive.h 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,75 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 LASTEXPRESS_HPFARCHIVE_H
+#define LASTEXPRESS_HPFARCHIVE_H
+
+/*
+ Archive file format (.HPF)
+
+ uint32 {4} - number of files
+
+ // for each file
+ char {12} - name (zero-terminated)
+ uint32 {4} - offset (expressed in sectors of 2048 bytes)
+ uint32 {4} - size (expressed in sectors of 2048 bytes)
+ byte {2} - file status: 1 = on disk (ie. in HD.HPF), 0 = on CD
+*/
+
+#include "common/archive.h"
+
+namespace LastExpress {
+
+class HPFArchive : public Common::Archive {
+public:
+ HPFArchive(const Common::String &path);
+
+ bool hasFile(const Common::String &name);
+ int listMembers(Common::ArchiveMemberList &list);
+ Common::ArchiveMemberPtr getMember(const Common::String &name);
+ Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
+
+ int count() { return _files.size(); }
+
+private:
+ static const unsigned int _archiveNameSize = 12;
+ static const unsigned int _archiveSectorSize = 2048;
+
+ // File entry
+ struct HPFEntry {
+ uint32 offset; ///< Offset (in sectors of 2048 bytes)
+ uint32 size; ///< Size (in sectors of 2048 bytes)
+ uint16 isOnHD; ///< File location (1: on HD; 0: on CD)
+ };
+
+ typedef Common::HashMap<Common::String, HPFEntry, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> FileMap;
+
+ FileMap _files; ///< List of files
+ Common::String _filename; ///< Filename of the archive
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_HPFARCHIVE_H
Property changes on: scummvm/trunk/engines/lastexpress/data/archive.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/lastexpress/data/background.cpp
===================================================================
--- scummvm/trunk/engines/lastexpress/data/background.cpp (rev 0)
+++ scummvm/trunk/engines/lastexpress/data/background.cpp 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,141 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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$
+ *
+ */
+
+// Based on Deniz Oezmen's code and Xentax Wiki documentation
+// http://oezmen.eu/
+// http://wiki.xentax.com/index.php/The_Last_Express_BG
+
+#include "lastexpress/data/background.h"
+
+#include "lastexpress/debug.h"
+
+namespace LastExpress {
+
+Background::Background() : _data(NULL) {
+ memset(&_header, 0, sizeof(BackgroundHeader));
+}
+
+Background::~Background() {
+ delete[] _data;
+}
+
+bool Background::load(Common::SeekableReadStream *stream) {
+ if (!stream)
+ return false;
+
+ // Reset data
+ delete[] _data;
+
+ // Load Background header
+ _header.posX = stream->readUint32LE();
+ _header.posY = stream->readUint32LE();
+ _header.width = stream->readUint32LE();
+ _header.height = stream->readUint32LE();
+ _header.redSize = stream->readUint32LE();
+ _header.blueSize = stream->readUint32LE();
+ _header.greenSize = stream->readUint32LE();
+
+ debugC(3, kLastExpressDebugGraphics, "Background Info: (%d, %d) - (%d x %d) - (%d, %d, %d)",
+ _header.posX, _header.posY, _header.width, _header.height,
+ _header.redSize, _header.blueSize, _header.greenSize);
+
+ // Load and decompress Background channel data
+ uint32 numPix = _header.width * _header.height;
+ byte *dataR = decodeComponent(stream, _header.redSize, numPix);
+ byte *dataB = decodeComponent(stream, _header.blueSize, numPix);
+ byte *dataG = decodeComponent(stream, _header.greenSize, numPix);
+
+ // Save to pixel buffer
+ // FIXME handle big-endian case
+ _data = new uint16[_header.width * _header.height];
+ for (uint i = 0; i < _header.width * _header.height; i++)
+ _data[i] = (uint16)((dataR[i] << 10) + (dataG[i] << 5) + dataB[i]);
+
+ // Cleanup buffers
+ delete[] dataR;
+ delete[] dataG;
+ delete[] dataB;
+
+ delete stream;
+
+ return true;
+}
+
+Common::Rect Background::draw(Graphics::Surface *surface) {
+ if (!_data) {
+ debugC(2, kLastExpressDebugGraphics, "Trying to show a background before loading data!");
+ return Common::Rect();
+ }
+
+ int i = 0;
+ for (uint16 y = 0; y < _header.height; y++) {
+ for (uint16 x = 0; x < _header.width; x++) {
+ surface->fillRect(Common::Rect((int16)(_header.posX + x), (int16)(_header.posY + y), (int16)(_header.posX + x + 1), (int16)(_header.posY + y + 1)), _data[i]);
+ i ++;
+ }
+ }
+
+ return Common::Rect((int16)_header.posX, (int16)_header.posY, (int16)(_header.posX + _header.width), (int16)(_header.posY + _header.height));
+}
+
+byte *Background::decodeComponent(Common::SeekableReadStream *in, uint32 inSize, uint32 outSize) const {
+ // Create the destination array
+ byte *out = new byte[outSize];
+ if (!out)
+ return NULL;
+
+ // Initialize the decoding
+ uint32 inPos = 0;
+ uint32 outPos = 0;
+
+ // Decode
+ while (inPos < inSize) {
+ byte inByte = in->readByte();
+ inPos++;
+
+ if (inByte < 0x80) {
+ // Direct decompression (RLE)
+ byte len = (inByte >> 5) + 1;
+ byte data = inByte & 0x1f;
+ for (int i = 0; i < len && outPos < outSize; i++)
+ out[outPos++] = data;
+ } else {
+ // Buffer back reference, 4096 byte window
+ // Take inByte and the following value as a big endian
+ // OfsLen while zeroing the first bit
+ uint16 ofsLen = ((inByte & 0x7F) << 8) | in->readByte();
+ inPos++;
+
+ int32 len = (ofsLen >> 12) + 3;
+ int32 hisPos = (int32)(outPos + (ofsLen & 0x0FFF) - 4096);
+ for (int i = 0; i < len && outPos < outSize; i++)
+ out[outPos++] = out[hisPos++];
+ }
+ }
+
+ return out;
+}
+
+} // End of namespace LastExpress
Property changes on: scummvm/trunk/engines/lastexpress/data/background.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/lastexpress/data/background.h
===================================================================
--- scummvm/trunk/engines/lastexpress/data/background.h (rev 0)
+++ scummvm/trunk/engines/lastexpress/data/background.h 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,81 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 LASTEXPRESS_BACKGROUND_H
+#define LASTEXPRESS_BACKGROUND_H
+
+/*
+ Background file format (.BG)
+
+ header:
+ uint32 {4} - position X on screen
+ uint32 {4} - position Y on screen
+ uint32 {4} - image width
+ uint32 {4} - image height
+ uint32 {4} - red colour channel data size
+ uint32 {4} - blue colour channel data size
+ uint32 {4} - green colour channel data size
+
+ data:
+ byte {x} - red colour channel data
+ byte {x} - blue colour channel data
+ byte {x} - green colour channel data
+*/
+
+#include "lastexpress/drawable.h"
+
+#include "common/stream.h"
+
+namespace LastExpress {
+
+class Background : public Drawable {
+public:
+ Background();
+ ~Background();
+
+ bool load(Common::SeekableReadStream *stream);
+
+ Common::Rect draw(Graphics::Surface *surface);
+
+private:
+ struct BackgroundHeader {
+ uint32 posX; ///< position X on screen
+ uint32 posY; ///< position Y on screen
+ uint32 width; ///< image width
+ uint32 height; ///< image height
+ uint32 redSize; ///< red color channel data size
+ uint32 blueSize; ///< blue color channel data size
+ uint32 greenSize; ///< green color channel data size
+ };
+
+ BackgroundHeader _header;
+ uint16 *_data; ///< decoded background data
+
+ byte *decodeComponent(Common::SeekableReadStream *in, uint32 inSize, uint32 outSize) const;
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_BACKGROUND_H
Property changes on: scummvm/trunk/engines/lastexpress/data/background.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/lastexpress/data/cursor.cpp
===================================================================
--- scummvm/trunk/engines/lastexpress/data/cursor.cpp (rev 0)
+++ scummvm/trunk/engines/lastexpress/data/cursor.cpp 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,144 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 "lastexpress/data/cursor.h"
+
+#include "lastexpress/lastexpress.h"
+
+#include "common/system.h"
+#include "graphics/cursorman.h"
+
+namespace LastExpress {
+
+Cursor::Cursor() : _current(kCursorMAX) {
+ memset(&_cursors, 0, sizeof(_cursors));
+}
+
+bool Cursor::load(Common::SeekableReadStream *stream) {
+ if (!stream)
+ return false;
+
+ // Load the whole file to memory
+ Common::MemoryReadStream *data = stream->readStream((uint32) stream->size());
+ delete stream;
+ if (!data)
+ return false;
+
+ // Read the hotspot data
+ for (int i = 0; i < kCursorMAX; i++) {
+ _cursors[i].hotspotX = data->readUint16LE();
+ _cursors[i].hotspotY = data->readUint16LE();
+ debugC(15, kLastExpressDebugCursor | kLastExpressDebugAll,
+ "Cursor %d hotspot x: %d, hotspot y: %d",
+ i, _cursors[i].hotspotX, _cursors[i].hotspotY);
+ }
+
+ // Read the pixel data
+ for (int i = 0; i < kCursorMAX; i++)
+ for (int pix = 0; pix < 32 * 32; pix++)
+ _cursors[i].image[pix] = data->readUint16LE();
+
+ delete data;
+ return true;
+}
+
+void Cursor::show(bool visible) const {
+ CursorMan.showMouse(visible);
+}
+
+bool Cursor::checkStyle(CursorStyle style) const {
+ if (style >= kCursorMAX) {
+ debugC(2, kLastExpressDebugGraphics, "Trying to use an invalid cursor style: was %d, max %d", (int)style, kCursorMAX);
+ return false;
+ }
+
+ return true;
+}
+
+void Cursor::setStyle(CursorStyle style) {
+ if (!checkStyle(style))
+ return;
+
+ if (style == _current)
+ return;
+
+ debugC(10, kLastExpressDebugCursor | kLastExpressDebugAll, "Cursor: setting style: %d", style);
+
+ // Save the new cursor
+ _current = style;
+
+ // Reuse the screen pixel format
+ Graphics::PixelFormat pf = g_system->getScreenFormat();
+ CursorMan.replaceCursor((const byte *)getCursorImage(style),
+ 32, 32, _cursors[style].hotspotX, _cursors[style].hotspotY,
+ 0, 1, &pf);
+}
+
+const uint16 *Cursor::getCursorImage(CursorStyle style) const {
+ if (!checkStyle(style))
+ return NULL;
+
+ return _cursors[style].image;
+}
+
+
+Icon::Icon(CursorStyle style) : _style(style), _x(0), _y(0), _brightness(100) {}
+
+void Icon::setPosition(int16 x, int16 y) {
+ _x = x;
+ _y = y;
+}
+
+void Icon::setBrightness(uint brightness) {
+ assert(brightness <= 100);
+
+ _brightness = (uint8)brightness;
+}
+
+Common::Rect Icon::draw(Graphics::Surface *surface) {
+ const uint16 *image = ((LastExpressEngine *)g_engine)->getCursor()->getCursorImage((CursorStyle)_style);
+ if (!image)
+ return Common::Rect();
+
+ // TODO adjust brightness. The original game seems to be using a table for that (at least in the highlighting case)
+ for (int j = 0; j < 32; j++) {
+ uint16 *s = (uint16 *)surface->getBasePtr(_x, _y + j);
+ for (int i = 0; i < 32; i++) {
+ if (_brightness == 100)
+ *s = *image;
+ else
+ // HACK change color to show highlight
+ *s = (*image & 0x739C) >> 1;
+
+ // Update the image and surface pointers
+ image++;
+ s++;
+ }
+ }
+
+ return Common::Rect(_x, _y, _x + 32, _y + 32);
+}
+
+} // End of namespace LastExpress
Property changes on: scummvm/trunk/engines/lastexpress/data/cursor.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/lastexpress/data/cursor.h
===================================================================
--- scummvm/trunk/engines/lastexpress/data/cursor.h (rev 0)
+++ scummvm/trunk/engines/lastexpress/data/cursor.h 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,93 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 LASTEXPRESS_CURSOR_H
+#define LASTEXPRESS_CURSOR_H
+
+/*
+ Cursor format (CURSORS.TBM)
+
+ style table:
+ (for each cursor)
+ uint16 {2} - hotspot X
+ uint16 {2} - hotspot Y
+
+ data:
+ (for each cursor)
+ uint16 {32*32} - cursor data
+*/
+
+#include "lastexpress/drawable.h"
+
+#include "lastexpress/shared.h"
+
+#include "common/stream.h"
+
+namespace LastExpress {
+
+class Icon : public Drawable {
+public:
+ Icon(CursorStyle style);
+
+ void setPosition(int16 x, int16 y);
+ void setBrightness(uint brightness);
+ Common::Rect draw(Graphics::Surface *surface);
+
+private:
+ CursorStyle _style;
+ int16 _x, _y;
+ uint8 _brightness;
+};
+
+class Cursor {
+public:
+ Cursor();
+
+ bool load(Common::SeekableReadStream *stream);
+ void show(bool visible) const;
+
+ void setStyle(CursorStyle style);
+ CursorStyle getStyle() const { return _current; }
+
+private:
+ // Style
+ CursorStyle _current;
+
+ // Cursors data
+ struct {
+ uint16 image[32 * 32];
+ uint16 hotspotX, hotspotY;
+ } _cursors[kCursorMAX];
+
+ bool checkStyle(CursorStyle style) const;
+ const uint16 *getCursorImage(CursorStyle style) const;
+
+ // Only allow full access for drawing (needed for getCursorImage)
+ friend Common::Rect Icon::draw(Graphics::Surface *surface);
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_CURSOR_H
Property changes on: scummvm/trunk/engines/lastexpress/data/cursor.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/lastexpress/data/font.cpp
===================================================================
--- scummvm/trunk/engines/lastexpress/data/font.cpp (rev 0)
+++ scummvm/trunk/engines/lastexpress/data/font.cpp 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,205 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 "lastexpress/data/font.h"
+
+#include "common/system.h"
+
+namespace LastExpress {
+
+Font::Font() : _numGlyphs(0), _glyphs(NULL), _glyphWidths(0) {
+ memset(&_palette, 0, sizeof(_palette));
+ memset(&_charMap, 0, sizeof(_charMap));
+}
+
+Font::~Font() {
+ reset();
+}
+
+void Font::reset() {
+ delete[] _glyphs;
+ delete[] _glyphWidths;
+}
+
+bool Font::load(Common::SeekableReadStream *stream) {
+ if (!stream)
+ return false;
+
+ // Reset data
+ reset();
+
+ // Read the palette
+ for (uint i = 0; i < _paletteSize; i++) {
+ _palette[i] = stream->readUint16LE();
+ }
+
+ // Read the character map
+ stream->read(_charMap, _charMapSize);
+
+ // Read the glyphs
+ _numGlyphs = stream->readUint16LE();
+ _glyphs = new byte[_numGlyphs * 18 * 8];
+ stream->read(_glyphs, _numGlyphs * 18 * 8);
+
+ // TODO: Read something else?
+ //uint16 unknown = fontFile->readByte();
+ //warning("unknown = %d", unknown);
+ //warning("pos = %d", fontFile->pos());
+ //warning("left = %d", fontFile->size() - fontFile->pos());
+
+ //while (!fontFile->eos()) {
+ //unknown = fontFile->readByte();
+ //warning("val = %d", unknown);
+ //}
+
+ // Precalculate glyph widths
+ _glyphWidths = new byte[_numGlyphs];
+ for (uint16 i = 0; i < _numGlyphs; i++) {
+ _glyphWidths[i] = getGlyphWidth(i);
+ }
+
+ delete stream;
+
+ return true;
+}
+
+
+uint16 Font::getCharGlyph(uint16 c) const {
+ //warning("%c", c);
+ if (c >= 0x200)
+ error("Express::Font: Invalid character %d", c);
+
+ return _charMap[c];
+}
+
+byte *Font::getGlyphImg(uint16 g) {
+ if (!_glyphs)
+ error("Express::getGlyphImg: Invalid glyphs!");
+
+ if (g >= _numGlyphs)
+ error("Express::getGlyphImg: Invalid glyph %d (%d available)", g, _numGlyphs);
+
+ return _glyphs + g * 18 * 8;
+}
+
+uint8 Font::getGlyphWidth(uint16 g) {
+ byte *p = getGlyphImg(g);
+
+ uint8 maxLineWidth = 0;
+ for (int j = 0; j < 18; j++) {
+ uint8 currentLineWidth = 0;
+ for (uint8 i = 0; i < 16; i++) {
+ byte index;
+ if (i % 2)
+ index = *p & 0xf;
+ else
+ index = *p >> 4;
+ uint16 color = _palette[index];
+ if (color != 0x1f)
+ currentLineWidth = i;
+ if (i % 2)
+ p++;
+ }
+ if (currentLineWidth > maxLineWidth)
+ maxLineWidth = currentLineWidth;
+ }
+
+ return maxLineWidth;
+}
+
+byte *Font::getCharImg(uint16 c) {
+ return getGlyphImg(getCharGlyph(c));
+}
+
+uint8 Font::getCharWidth(uint16 c) const{
+ if (c == 0x20) {
+ // Space is a special case
+ // TODO: this is an arbitrary value
+ return 10;
+ } else {
+ if (!_glyphWidths)
+ error("Express::getCharWidth: Invalid glyphs widths!");
+
+ return _glyphWidths[getCharGlyph(c)];
+ }
+}
+
+uint16 Font::getStringWidth(Common::String str) const {
+ uint16 width = 0;
+ for (uint i = 0; i < str.size(); i++)
+ width += getCharWidth((unsigned) (int)str[i]);
+
+ return width;
+}
+
+uint16 Font::getStringWidth(const uint16 *str, uint16 length) const {
+ uint16 width = 0;
+ for (uint i = 0; i < length; i++)
+ width += getCharWidth(str[i]);
+
+ return width;
+}
+
+void Font::drawChar(Graphics::Surface *surface, int16 x, int16 y, uint16 c) {
+ byte *p = getCharImg(c);
+
+ for (int16 j = 0; j < 18; j++) {
+ for (int16 i = 0; i < 16; i++) {
+ byte index;
+ if (i % 2)
+ index = *p & 0xf;
+ else
+ index = *p >> 4;
+ uint16 color = _palette[index];
+ if (color != 0x1f) {
+ surface->fillRect(Common::Rect(x+i, y+j, x+i+1, y+j+1), color);
+ }
+ if (i % 2)
+ p++;
+ }
+ }
+}
+
+Common::Rect Font::drawString(Graphics::Surface *surface, int16 x, int16 y, Common::String str) {
+ int16 currentX = x;
+ for (uint i = 0; i < str.size(); i++) {
+ drawChar(surface, currentX, y, (unsigned) (int)str[i]);
+ currentX += getCharWidth((unsigned) (int)str[i]);
+ }
+
+ return Common::Rect(x, y, x + currentX, y + (int16)_charHeight);
+}
+
+Common::Rect Font::drawString(Graphics::Surface *surface, int16 x, int16 y, const uint16 *str, uint16 length) {
+ int16 currentX = x;
+ for (uint i = 0; i < length; i++) {
+ drawChar(surface, currentX, y, str[i]);
+ currentX += getCharWidth(str[i]);
+ }
+
+ return Common::Rect(x, y, x + currentX, y + (int16)_charHeight);
+}
+
+} // End of namespace LastExpress
Property changes on: scummvm/trunk/engines/lastexpress/data/font.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/lastexpress/data/font.h
===================================================================
--- scummvm/trunk/engines/lastexpress/data/font.h (rev 0)
+++ scummvm/trunk/engines/lastexpress/data/font.h 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,82 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 LASTEXPRESS_FONT_H
+#define LASTEXPRESS_FONT_H
+
+/*
+ Font format (FONT.DAT)
+
+ uint16 {40} - Palette data
+ byte {200} - Character map
+ uint16 {2} - Number of glyphs
+
+ // For each glyph
+ byte {18*8} - Glyph data
+
+ byte {x} - Unknown data (probably just garbage)
+*/
+
+#include "common/stream.h"
+#include "graphics/surface.h"
+
+namespace LastExpress {
+
+class Font {
+public:
+ Font();
+ ~Font();
+
+ bool load(Common::SeekableReadStream *stream);
+ Common::Rect drawString(Graphics::Surface *surface, int16 x, int16 y, Common::String str);
+ Common::Rect drawString(Graphics::Surface *surface, int16 x, int16 y, const uint16 *str, uint16 length);
+
+private:
+ static const uint32 _paletteSize = 0x10;
+ static const uint32 _charMapSize = 0x200;
+ static const uint32 _charHeight = 16;
+
+ void reset();
+
+ uint16 getCharGlyph(uint16 c) const;
+ byte *getGlyphImg(uint16 g);
+ uint8 getGlyphWidth(uint16 g);
+ byte *getCharImg(uint16 c);
+ uint8 getCharWidth(uint16 c) const;
+ uint16 getStringWidth(Common::String str) const;
+ uint16 getStringWidth(const uint16 *str, uint16 length) const;
+ void drawChar(Graphics::Surface *surface, int16 x, int16 y, uint16 c);
+
+ // Font data
+ uint16 _palette[_paletteSize];
+ uint8 _charMap[_charMapSize];
+ uint16 _numGlyphs;
+ byte *_glyphs;
+ uint8 *_glyphWidths;
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_FONT_H
Property changes on: scummvm/trunk/engines/lastexpress/data/font.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/lastexpress/data/scene.cpp
===================================================================
--- scummvm/trunk/engines/lastexpress/data/scene.cpp (rev 0)
+++ scummvm/trunk/engines/lastexpress/data/scene.cpp 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,292 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 "lastexpress/data/scene.h"
+
+#include "lastexpress/data/background.h"
+
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/resource.h"
+
+namespace LastExpress {
+
+SceneHotspot *SceneHotspot::load(Common::SeekableReadStream *stream) {
+ SceneHotspot *hs = new SceneHotspot();
+
+ // Rect
+ hs->rect.left = (int16)stream->readUint16LE();
+ hs->rect.right = (int16)stream->readUint16LE();
+ hs->rect.top = (int16)stream->readUint16LE();
+ hs->rect.bottom = (int16)stream->readUint16LE();
+
+ hs->coordsOffset = stream->readUint32LE();
+ hs->scene = (SceneIndex)stream->readUint16LE();
+ hs->location = stream->readByte();
+ hs->action = (Action)stream->readByte();
+ hs->param1 = stream->readByte();
+ hs->param2 = stream->readByte();
+ hs->param3 = stream->readByte();
+ hs->cursor = stream->readByte();
+ hs->next = stream->readUint32LE();
+
+ debugC(10, kLastExpressDebugScenes, "\thotspot: scene=%d location=%02d action=%d param1=%02d param2=%02d param3=%02d cursor=%02d rect=(%d, %d)x(%d,%d)",
+ hs->scene, hs->location, hs->action, hs->param1, hs->param2, hs->param3, hs->cursor, hs->rect.left, hs->rect.top, hs->rect.right, hs->rect.bottom);
+ debugC(10, kLastExpressDebugScenes, "\t coords=%d next=%d ", hs->coordsOffset, hs->next);
+
+ // Read all coords data
+ uint32 offset = hs->coordsOffset;
+ while (offset != 0) {
+
+ SceneCoord *sceneCoord = new SceneCoord;
+
+ stream->seek(offset, SEEK_SET);
+
+ sceneCoord->field_0 = stream->readSint32LE();
+ sceneCoord->field_4 = stream->readSint32LE();
+ sceneCoord->field_8 = stream->readByte();
+ sceneCoord->next = stream->readUint32LE();
+
+ hs->_coords.push_back(sceneCoord);
+
+ offset = sceneCoord->next;
+ }
+
+ return hs;
+}
+
+Common::String SceneHotspot::toString() const {
+ Common::String output = "";
+
+ output += Common::String::printf(" hotspot: scene=%d location=%02d action=%d param1=%02d param2=%02d param3=%02d cursor=%02d rect=(%d, %d)x(%d,%d)",
+ scene, location, action, param1, param2, param3, cursor, rect.left, rect.top, rect.right, rect.bottom);
+
+ return output;
+}
+
+bool SceneHotspot::isInside(const Common::Point &point) {
+
+ bool contains = rect.contains(point);
+
+ if (_coords.empty() || !contains)
+ return contains;
+
+ // Checks extended coordinates
+ for (uint i = 0; i < _coords.size(); i++) {
+
+ SceneCoord *sCoord = _coords[i];
+
+ bool cont;
+ if (sCoord->field_8)
+ cont = (sCoord->field_4 + point.x * sCoord->field_0 + 1000 * point.y) >= 0;
+ else
+ cont = (sCoord->field_4 + point.x * sCoord->field_0 + 1000 * point.y) <= 0;
+
+ if (!cont)
+ return false;
+ }
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Scene
+Scene::~Scene() {
+ // Free the hotspots
+ for (int i = 0; i < (int)_hotspots.size(); i++)
+ delete _hotspots[i];
+}
+
+Scene *Scene::load(Common::SeekableReadStream *stream) {
+ Scene *scene = new Scene();
+
+ stream->read(&scene->_name, sizeof(scene->_name));
+ scene->_sig = stream->readByte();
+ scene->entityPosition = (EntityPosition)stream->readUint16LE();;
+ scene->location = (Location)stream->readUint16LE();
+ scene->car = (CarIndex)stream->readUint16LE();
+ scene->position = stream->readByte();
+ scene->type = (Type)stream->readByte();
+ scene->param1 = stream->readByte();
+ scene->param2 = stream->readByte();
+ scene->param3 = stream->readByte();
+ scene->_hotspot = stream->readUint32LE();
+
+ return scene;
+}
+
+void Scene::loadHotspots(Common::SeekableReadStream *stream) {
+ if (!_hotspots.empty())
+ return;
+
+ debugC(10, kLastExpressDebugScenes, "Scene: name=%s, sig=%02d, entityPosition=%d, location=%d", _name, _sig, entityPosition, location);
+ debugC(10, kLastExpressDebugScenes, "\tcar=%02d, position=%02d, type=%02d, param1=%02d", car, position, type, param1);
+ debugC(10, kLastExpressDebugScenes, "\tparam2=%02d, param3=%02d, hotspot=%d\n", param2, param3, _hotspot);
+
+ // Read all hotspots
+ if (_hotspot != 0) {
+ stream->seek((int32)_hotspot, SEEK_SET);
+ SceneHotspot *hotspot = SceneHotspot::load(stream);
+ while (hotspot) {
+ _hotspots.push_back(hotspot);
+
+ if (hotspot->next == 0)
+ break;
+
+ stream->seek((int32)hotspot->next, SEEK_SET);
+ hotspot = SceneHotspot::load(stream);
+ }
+ }
+}
+
+bool Scene::checkHotSpot(const Common::Point &coord, SceneHotspot **hotspot) {
+ bool found = false;
+ int _location = 0;
+
+ for (int i = 0; i < (int)_hotspots.size(); i++) {
+ if (_hotspots[i]->isInside(coord)) {
+ if (_location <= _hotspots[i]->location) {
+ _location = _hotspots[i]->location;
+ *hotspot = _hotspots[i];
+ found = true;
+ }
+ }
+ }
+
+ return found;
+}
+
+SceneHotspot *Scene::getHotspot(uint index) {
+ if (_hotspots.empty())
+ error("Scene::getHotspot: scene does not have any hotspots!");
+
+ if (index >= _hotspots.size())
+ error("Scene::getHotspot: invalid index (was: %d, max: %d)", index, _hotspots.size() - 1);
+
+ return _hotspots[index];
+}
+
+Common::Rect Scene::draw(Graphics::Surface *surface) {
+ // Safety checks
+ Common::Rect rect;
+
+ Common::String sceneName(_name);
+ sceneName.trim();
+ if (sceneName.empty())
+ error("Scene::draw: This scene is not a valid drawing scene!");
+
+ // Load background
+ Background *background = ((LastExpressEngine *)g_engine)->getResourceManager()->loadBackground(sceneName);
+ if (background) {
+ rect = background->draw(surface);
+ delete background;
+ }
+
+ return rect;
+}
+
+Common::String Scene::toString() {
+ Common::String output = "";
+
+ output += Common::String::printf("Scene: name=%s, sig=%02d, entityPosition=%d, location=%d\n", _name, _sig, entityPosition, location);
+ output += Common::String::printf(" car=%02d, position=%02d, type=%02d, param1=%02d\n", car, position, type, param1);
+ output += Common::String::printf(" param2=%02d, param3=%02d, hotspot=%d\n", param2, param3, _hotspot);
+
+ // Hotspots
+ if (_hotspots.size() != 0) {
+ output += "\nHotspots:\n";
+ for (int i = 0; i < (int)_hotspots.size(); i++)
+ output += _hotspots[i]->toString() + "\n";
+ }
+
+ return output;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// SceneLoader
+SceneLoader::SceneLoader() : _stream(NULL) {}
+
+SceneLoader::~SceneLoader() {
+ clear();
+}
+
+void SceneLoader::clear() {
+ // Remove all scenes
+ for (int i = 0; i < (int)_scenes.size(); i++)
+ delete _scenes[i];
+
+ _scenes.clear();
+
+ delete _stream;
+}
+
+bool SceneLoader::load(Common::SeekableReadStream *stream) {
+ if (!stream)
+ return false;
+
+ clear();
+
+ _stream = stream;
+
+ // Read the default scene to get the total number of scenes
+ Scene *header = Scene::load(_stream);
+ if (!header)
+ error("SceneLoader::load: Invalid data file!");
+
+ debugC(2, kLastExpressDebugScenes, " found %d entries", header->entityPosition); /* Header entityPosition is the scene count */
+
+ if (header->entityPosition > 2500) {
+ delete header;
+
+ return false;
+ }
+
+ _scenes.push_back(header);
+
+ // Read all the chunks
+ for (uint i = 0; i < (uint)header->entityPosition; ++i) {
+ Scene *scene = Scene::load(_stream);
+ if (!scene)
+ break;
+
+ _scenes.push_back(scene);
+ }
+
+ return true;
+}
+
+Scene *SceneLoader::get(SceneIndex index) {
+ if (_scenes.empty())
+ return NULL;
+
+ if (index > _scenes.size())
+ return NULL;
+
+ // Load the hotspots if needed
+ _scenes[(int)index]->loadHotspots(_stream);
+
+ return _scenes[(int)index];
+}
+
+} // End of namespace LastExpress
Property changes on: scummvm/trunk/engines/lastexpress/data/scene.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/lastexpress/data/scene.h
===================================================================
--- scummvm/trunk/engines/lastexpress/data/scene.h (rev 0)
+++ scummvm/trunk/engines/lastexpress/data/scene.h 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,245 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 LASTEXPRESS_SCENE_H
+#define LASTEXPRESS_SCENE_H
+
+/*
+ Scene format (CDTRAIN.DAT)
+
+ (text:00484750)
+ header (24 bytes)
+ char {8} - entry name (null terminated)
+ byte {1} - 0xCD
+ uint16 {2} - number of scenes (for first entry - always 0 after?)
+ uint16 {2} - 11 ??
+ uint16 {2} - car
+ byte {1} - camera position (used to get the proper sequences to show)
+ byte {1} - type
+ byte {1} - param1
+ byte {1} - param2
+ byte {1} - param3
+ uint32 {4} - Offset to hotspot info struct
+
+ probably contains cursor type too / scene index : 0 - 2500 (max)
+
+ hotspot info (24 bytes)
+ uint16 {2} - left
+ uint16 {2} - right
+ uint16 {2} - top
+ uint16 {2} - bottom
+ uint32 {4} - scene coords data
+ uint16 {2} - scene
+ byte {1} - location;
+ byte {1} - action;
+ byte {1} - param1;
+ byte {1} - param2;
+ byte {1} - param3
+ byte {1} - cursor
+ uint32{4} - offset to next hotpost
+
+ coords data (9 bytes)
+ uint32 {4} - ??
+ uint32 {4} - ??
+ byte {1} - ??
+ uint32 {4} - offset to next coords data structure
+
+*/
+
+#include "lastexpress/drawable.h"
+#include "lastexpress/shared.h"
+
+#include "common/array.h"
+#include "common/stream.h"
+
+namespace LastExpress {
+
+class Scene;
+
+class SceneHotspot {
+public:
+ enum Action {
+ kActionInventory = 1,
+ kActionSavePoint = 2,
+ kActionPlaySound = 3,
+ kActionPlayMusic = 4,
+ kActionKnockOnDoor = 5,
+ kActionCompartment = 6,
+ kActionPlaySounds = 7,
+ kActionPlayAnimation = 8,
+ kActionOpenCloseObject = 9,
+ kActionObjectUpdateLocation2 = 10,
+ kActionSetItemLocation = 11,
+ kAction12 = 12,
+ kActionPickItem = 13,
+ kActionDropItem = 14,
+ kAction15 = 15,
+ kActionEnterCompartment = 16,
+ kActionGetOutsideTrain = 18,
+ kActionSlip = 19,
+ kActionGetInsideTrain = 20,
+ kActionClimbUpTrain = 21,
+ kActionClimbDownTrain = 22,
+ kActionJumpUpDownTrain = 23,
+ kActionUnbound = 24,
+ kAction25 = 25,
+ kAction26 = 26,
+ kAction27 = 27,
+ kActionConcertSitCough = 28,
+ kAction29 = 29,
+ kActionCatchBeetle = 30,
+ kActionExitCompartment = 31,
+ kAction32 = 32,
+ KActionUseWhistle = 33,
+ kActionOpenMatchBox = 34,
+ kActionOpenBed = 35,
+ kActionDialog = 37,
+ kActionEggBox = 38,
+ kAction39 = 39,
+ kActionBed = 40,
+ kAction41 = 41,
+ kAction42 = 42,
+ kActionSwitchChapter = 43,
+ kAction44 = 44
+ };
+
+ struct SceneCoord {
+ int32 field_0;
+ int32 field_4;
+ byte field_8;
+ uint32 next;
+
+ SceneCoord() {
+ field_0 = 0;
+ field_4 = 0;
+ field_8 = 0;
+ next = 0;
+ }
+ };
+
+ Common::Rect rect;
+ uint32 coordsOffset;
+ SceneIndex scene;
+ byte location;
+ Action action;
+ byte param1;
+ byte param2;
+ byte param3;
+ byte cursor;
+ uint32 next;
+
+ SceneHotspot() {}
+ static SceneHotspot *load(Common::SeekableReadStream *stream);
+
+ bool isInside(const Common::Point &point);
+
+ Common::String toString() const;
+
+private:
+ Common::Array<SceneCoord *> _coords;
+};
+
+class SceneLoader {
+public:
+ SceneLoader();
+ ~SceneLoader();
+
+ bool load(Common::SeekableReadStream *stream);
+ Scene *get(SceneIndex index);
+
+ uint32 count() const { return _scenes.size() - 1; };
+
+private:
+ Common::SeekableReadStream *_stream;
+ Common::Array<Scene *> _scenes;
+
+ void clear();
+};
+
+class Scene : public Drawable {
+public:
+ // Enumerations
+ enum Type {
+ // PreProcess
+ kTypeObject = 1,
+ kTypeItem = 2,
+ kTypeItem2 = 3,
+ kTypeObjectItem = 4,
+ kTypeItem3 = 5,
+ kTypeObjectLocation2 = 6,
+ kTypeCompartments = 7,
+ kTypeCompartmentsItem = 8,
+
+ // PostProcess
+ kTypeList = 128,
+ kTypeSavePointChapter = 129,
+ kTypeLoadBeetleSequences = 130,
+ kTypeGameOver = 131,
+ kTypeReadText = 132,
+ kType133 = 133
+ };
+
+ // Data
+ EntityPosition entityPosition;
+ Location location;
+ CarIndex car;
+ Position position;
+ Type type;
+ byte param1;
+ byte param2;
+ byte param3;
+
+ ~Scene();
+
+ Common::Rect draw(Graphics::Surface *surface);
+
+ // Hotspots
+ Common::Array<SceneHotspot *> *getHotspots() { return &_hotspots; }
+ bool checkHotSpot(const Common::Point &coord, SceneHotspot **hotspot);
+ SceneHotspot *getHotspot(uint index = 0);
+
+ Common::String toString();
+
+private:
+ char _name[8];
+ byte _sig;
+ uint32 _hotspot;
+
+ Scene() {}
+ Common::Array<SceneHotspot *> _hotspots;
+
+ static Scene *load(Common::SeekableReadStream *stream);
+ void loadHotspots(Common::SeekableReadStream *stream);
+
+ void clear();
+
+ // Only allow full access for loading the scene and the hotspots
+ friend bool SceneLoader::load(Common::SeekableReadStream *stream);
+ friend Scene *SceneLoader::get(SceneIndex index);
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_SCENE_H
Property changes on: scummvm/trunk/engines/lastexpress/data/scene.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/lastexpress/data/sequence.cpp
===================================================================
--- scummvm/trunk/engines/lastexpress/data/sequence.cpp (rev 0)
+++ scummvm/trunk/engines/lastexpress/data/sequence.cpp 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,475 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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$
+ *
+ */
+
+// Based on Deniz Oezmen's code: http://oezmen.eu/
+
+#include "lastexpress/data/sequence.h"
+
+#include "lastexpress/debug.h"
+
+namespace LastExpress {
+
+void FrameInfo::read(Common::SeekableReadStream *in, bool isSequence) {
+ // Save the current position
+ int32 basePos = in->pos();
+
+ dataOffset = in->readUint32LE();
+ unknown = in->readUint32LE();
+ paletteOffset = in->readUint32LE();
+ xPos1 = in->readUint32LE();
+ yPos1 = in->readUint32LE();
+ xPos2 = in->readUint32LE();
+ yPos2 = in->readUint32LE();
+ initialSkip = in->readUint32LE();
+ decompressedEndOffset = in->readUint32LE();
+
+ // Read the compression type for NIS files
+ if (!isSequence) {
+ in->seek(basePos + 0x124);
+ } else {
+ hotspot.left = (int16)in->readUint16LE();
+ hotspot.right = (int16)in->readUint16LE();
+ hotspot.top = (int16)in->readUint16LE();
+ hotspot.bottom = (int16)in->readUint16LE();
+ }
+
+ compressionType = in->readByte();
+ subType = (FrameSubType)in->readByte();
+
+ // Sequence information
+ field_2E = in->readByte();
+ keepPreviousFrame = in->readByte();
+ field_30 = in->readByte();
+ field_31 = in->readByte();
+ soundAction = in->readByte();
+ field_33 = in->readByte();
+ position = in->readByte();
+ field_35 = in->readByte();
+ field_36 = in->readUint16LE();
+ field_38 = in->readUint32LE();
+ entityPosition = (EntityPosition)in->readUint16LE();
+ location = in->readUint16LE();
+ next = in->readUint32LE();
+}
+
+
+// AnimFrame
+
+AnimFrame::AnimFrame(Common::SeekableReadStream *in, const FrameInfo &f) : _palette(NULL) {
+ _palSize = 1;
+ // TODO: use just the needed rectangle
+ _image.create(640, 480, 1);
+
+ //debugC(6, kLastExpressDebugGraphics, " Offsets: data=%d, unknown=%d, palette=%d", f.dataOffset, f.unknown, f.paletteOffset);
+ //debugC(6, kLastExpressDebugGraphics, " Position: (%d, %d) - (%d, %d)", f.xPos1, f.yPos1, f.xPos2, f.yPos2);
+ //debugC(6, kLastExpressDebugGraphics, " Initial Skip: %d", f.initialSkip);
+ //debugC(6, kLastExpressDebugGraphics, " Decompressed end offset: %d", f.decompressedEndOffset);
+ //debugC(6, kLastExpressDebugGraphics, " Hotspot: (%d, %d) x (%d, %d)\n", f.hotspot.left, f.hotspot.top, f.hotspot.right, f.hotspot.bottom);
+ //debugC(6, kLastExpressDebugGraphics, " Compression type: %u / %u", f.compressionType, f.subType);
+ //debugC(6, kLastExpressDebugGraphics, " Unknown: %u - %u - %u - %u - %u - %u - %u - %d", f.field_2E, f.field_2F, f.field_30, f.field_31, f.field_33, f.field_35, f.field_36, f.field_38);
+ //debugC(6, kLastExpressDebugGraphics, " Sound action: %u", f.soundAction);
+ //debugC(6, kLastExpressDebugGraphics, " Position: %d", f.position);
+ //debugC(6, kLastExpressDebugGraphics, " Entity Position: %d", f.entityPosition);
+ //debugC(6, kLastExpressDebugGraphics, " Location: %d", f.location);
+ //debugC(6, kLastExpressDebugGraphics, " next: %d", f.next);
+
+ switch (f.compressionType) {
+ case 0:
+ // Empty frame
+ break;
+ case 3:
+ decomp3(in, f);
+ break;
+ case 4:
+ decomp4(in, f);
+ break;
+ case 5:
+ decomp5(in, f);
+ break;
+ case 7:
+ decomp7(in, f);
+ break;
+ case 255:
+ decompFF(in, f);
+ break;
+ default:
+ error("Unknown frame compression: %d", f.compressionType);
+ }
+
+ readPalette(in, f);
+ _rect = Common::Rect((int16)f.xPos1, (int16)f.yPos1, (int16)f.xPos2, (int16)f.yPos2);
+ //_rect.debugPrint(0, "Frame rect:");
+}
+
+AnimFrame::~AnimFrame() {
+ _image.free();
+ delete[] _palette;
+}
+
+Common::Rect AnimFrame::draw(Graphics::Surface *s) {
+ byte *inp = (byte *)_image.pixels;
+ uint16 *outp = (uint16 *)s->pixels;
+ for (int i = 0; i < 640 * 480; i++, inp++, outp++) {
+ if (*inp)
+ *outp = _palette[*inp];
+ }
+ return _rect;
+}
+
+void AnimFrame::readPalette(Common::SeekableReadStream *in, const FrameInfo &f) {
+ // Read the palette
+ in->seek((int)f.paletteOffset);
+ _palette = new uint16[_palSize];
+ for (uint32 i = 0; i < _palSize; i++) {
+ _palette[i] = in->readUint16LE();
+ }
+}
+
+void AnimFrame::decomp3(Common::SeekableReadStream *in, const FrameInfo &f) {
+ decomp34(in, f, 0x7, 3);
+}
+
+void AnimFrame::decomp4(Common::SeekableReadStream *in, const FrameInfo &f) {
+ decomp34(in, f, 0xf, 4);
+}
+
+void AnimFrame::decomp34(Common::SeekableReadStream *in, const FrameInfo &f, byte mask, byte shift) {
+ byte *p = (byte *)_image.getBasePtr(0, 0);
+
+ uint32 skip = f.initialSkip / 2;
+ uint32 size = f.decompressedEndOffset / 2;
+ //warning("skip: %d, %d", skip % 640, skip / 640);
+ //warning("size: %d, %d", size % 640, size / 640);
+ //assert (f.yPos1 == skip / 640);
+ //assert (f.yPos2 == size / 640);
+
+ uint32 numBlanks = 640 - (f.xPos2 - f.xPos1);
+
+ in->seek((int)f.dataOffset);
+ for (uint32 out = skip; out < size; ) {
+ uint16 opcode = in->readByte();
+
+ if (opcode & 0x80) {
+ if (opcode & 0x40) {
+ opcode &= 0x3f;
+ out += numBlanks + opcode + 1;
+ } else {
+ opcode &= 0x3f;
+ if (opcode & 0x20) {
+ opcode = ((opcode & 0x1f) << 8) + in->readByte();
+ if (opcode & 0x1000) {
+ out += opcode & 0xfff;
+ continue;
+ }
+ }
+ out += opcode + 2;
+ }
+ } else {
+ byte value = opcode & mask;
+ opcode >>= shift;
+ if (_palSize <= value)
+ _palSize = value + 1;
+ if (!opcode)
+ opcode = in->readByte();
+ for (int i = 0; i < opcode; i++, out++) {
+ p[out] = value;
+ }
+ }
+ }
+}
+
+void AnimFrame::decomp5(Common::SeekableReadStream *in, const FrameInfo &f) {
+ byte *p = (byte *)_image.getBasePtr(0, 0);
+
+ uint32 skip = f.initialSkip / 2;
+ uint32 size = f.decompressedEndOffset / 2;
+ //warning("skip: %d, %d", skip % 640, skip / 640);
+ //warning("size: %d, %d", size % 640, size / 640);
+ //assert (f.yPos1 == skip / 640);
+ //assert (f.yPos2 == size / 640);
+
+ in->seek((int)f.dataOffset);
+ for (uint32 out = skip; out < size; ) {
+ uint16 opcode = in->readByte();
+ if (!(opcode & 0x1f)) {
+ opcode = (uint16)((opcode << 3) + in->readByte());
+ if (opcode & 0x400) {
+ // skip these 10 bits
+ out += (opcode & 0x3ff);
+ } else {
+ out += opcode + 2;
+ }
+ } else {
+ byte value = opcode & 0x1f;
+ opcode >>= 5;
+ if (_palSize <= value)
+ _palSize = value + 1;
+ if (!opcode)
+ opcode = in->readByte();
+ for (int i = 0; i < opcode; i++, out++) {
+ p[out] = value;
+ }
+ }
+ }
+}
+
+void AnimFrame::decomp7(Common::SeekableReadStream *in, const FrameInfo &f) {
+ byte *p = (byte *)_image.getBasePtr(0, 0);
+
+ uint32 skip = f.initialSkip / 2;
+ uint32 size = f.decompressedEndOffset / 2;
+ //warning("skip: %d, %d", skip % 640, skip / 640);
+ //warning("size: %d, %d", size % 640, size / 640);
+ //assert (f.yPos1 == skip / 640);
+ //assert (f.yPos2 == size / 640);
+
+ uint32 numBlanks = 640 - (f.xPos2 - f.xPos1);
+
+ in->seek((int)f.dataOffset);
+ for (uint32 out = skip; out < size; ) {
+ uint16 opcode = in->readByte();
+ if (opcode & 0x80) {
+ if (opcode & 0x40) {
+ if (opcode & 0x20) {
+ opcode &= 0x1f;
+ out += numBlanks + opcode + 1;
+ } else {
+ opcode &= 0x1f;
+ if (opcode & 0x10) {
+ opcode = ((opcode & 0xf) << 8) + in->readByte();
+ if (opcode & 0x800) {
+ // skip these 11 bits
+ out += (opcode & 0x7ff);
+ continue;
+ }
+ }
+
+ // skip these 4 bits
+ out += opcode + 2;
+ }
+ } else {
+ opcode &= 0x3f;
+ byte value = in->readByte();
+ if (_palSize <= value)
+ _palSize = value + 1;
+ for (int i = 0; i < opcode; i++, out++) {
+ p[out] = value;
+ }
+ }
+ } else {
+ if (_palSize <= opcode)
+ _palSize = opcode + 1;
+ // set the given value
+ p[out] = (byte)opcode;
+ out++;
+ }
+ }
+}
+
+void AnimFrame::decompFF(Common::SeekableReadStream *in, const FrameInfo &f) {
+ byte *p = (byte *)_image.getBasePtr(0, 0);
+
+ uint32 skip = f.initialSkip / 2;
+ uint32 size = f.decompressedEndOffset / 2;
+
+ in->seek((int)f.dataOffset);
+ for (uint32 out = skip; out < size; ) {
+ uint16 opcode = in->readByte();
+
+ if (opcode < 0x80) {
+ if (_palSize <= opcode)
+ _palSize = opcode + 1;
+ // set the given value
+ p[out] = (byte)opcode;
+ out++;
+ } else {
+ if (opcode < 0xf0) {
+ if (opcode < 0xe0) {
+ // copy old part
+ uint32 old = out + ((opcode & 0x7) << 8) + in->readByte() - 2048;
+ opcode = ((opcode >> 3) & 0xf) + 3;
+ for (int i = 0; i < opcode; i++, out++, old++) {
+ p[out] = p[old];
+ }
+ } else {
+ opcode = (opcode & 0xf) + 1;
+ byte value = in->readByte();
+ if (_palSize <= value)
+ _palSize = value + 1;
+ for (int i = 0; i < opcode; i++, out++) {
+ p[out] = value;
+ }
+ }
+ } else {
+ out += ((opcode & 0xf) << 8) + in->readByte();
+ }
+ }
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// SEQUENCE
+//////////////////////////////////////////////////////////////////////////
+
+Sequence::~Sequence() {
+ reset();
+}
+
+void Sequence::reset() {
+ _frames.clear();
+ delete _stream;
+ _stream = NULL;
+}
+
+Sequence *Sequence::load(Common::String name, Common::SeekableReadStream *stream, byte field30) {
+ Sequence *sequence = new Sequence(name);
+
+ if (!sequence->load(stream, field30)) {
+ delete sequence;
+ return NULL;
+ }
+
+ return sequence;
+}
+
+bool Sequence::load(Common::SeekableReadStream *stream, byte field30) {
+ if (!stream)
+ return false;
+
+ // Reset data
+ reset();
+
+ _field30 = field30;
+
+ // Keep stream for later decoding of sequence
+ _stream = stream;
+
+ // Read header to get the number of frames
+ _stream->seek(0);
+ uint32 numframes = _stream->readUint32LE();
+ uint32 unknown = _stream->readUint32LE();
+ debugC(3, kLastExpressDebugGraphics, "Number of frames in sequence: %d / unknown=0x%x", numframes, unknown);
+
+ // Store frames information
+ for (uint i = 0; i < numframes; i++) {
+
+ // Move stream to start of frame
+ _stream->seek((int32)(_sequenceHeaderSize + i * _sequenceFrameSize), SEEK_SET);
+ if (_stream->eos())
+ error("Couldn't seek to the current frame data");
+
+ // Check if there is enough data
+ if ((unsigned)(_stream->size() - _stream->pos()) < _sequenceFrameSize)
+ error("The sequence frame does not have a valid header");
+
+ FrameInfo info;
+ info.read(_stream, true);
+ _frames.push_back(info);
+ }
+
+ _isLoaded = true;
+
+ return true;
+}
+
+FrameInfo *Sequence::getFrameInfo(uint16 index) {
+ if (_frames.size() == 0)
+ error("Trying to decode a sequence before loading its data");
+
+ if (index > _frames.size() - 1)
+ error("Invalid sequence frame requested: %d, max %d", index, _frames.size() - 1);
+
+ return &_frames[index];
+}
+
+AnimFrame *Sequence::getFrame(uint16 index) {
+
+ FrameInfo *frame = getFrameInfo(index);
+
+ if (!frame)
+ return NULL;
+
+ // Skip "invalid" frames
+ if (frame->compressionType == 0)
+ return NULL;
+
+ debugC(9, kLastExpressDebugGraphics, "Decoding sequence %s: frame %d / %d", _name.c_str(), index, _frames.size() - 1);
+
+ return new AnimFrame(_stream, *frame);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// SequenceFrame
+SequenceFrame::~SequenceFrame() {
+ if (_dispose && _sequence) {
+ delete _sequence;
+ }
+
+ _sequence = NULL;
+}
+
+Common::Rect SequenceFrame::draw(Graphics::Surface *surface) {
+ if (!_sequence || _frame >= _sequence->count())
+ return Common::Rect();
+
+ AnimFrame *f = _sequence->getFrame(_frame);
+ if (!f)
+ return Common::Rect();
+
+ Common::Rect rect = f->draw(surface);
+
+ delete f;
+
+ return rect;
+}
+
+bool SequenceFrame::setFrame(uint16 frame) {
+ if (!_sequence)
+ return false;
+
+ if (frame < _sequence->count()) {
+ _frame = frame;
+ return true;
+ } else
+ return false;
+}
+
+bool SequenceFrame::nextFrame() {
+ return setFrame(_frame + 1);
+}
+
+FrameInfo *SequenceFrame::getInfo() {
+ if (!_sequence)
+ error("SequenceFrame::getFrameInfo: Invalid sequence!");
+
+ return _sequence->getFrameInfo(_frame);
+}
+
+bool SequenceFrame::equal(const SequenceFrame *other) const {
+ return _sequence->getName() == other->_sequence->getName() && _frame == other->_frame;
+}
+
+} // End of namespace LastExpress
Property changes on: scummvm/trunk/engines/lastexpress/data/sequence.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/lastexpress/data/sequence.h
===================================================================
--- scummvm/trunk/engines/lastexpress/data/sequence.h (rev 0)
+++ scummvm/trunk/engines/lastexpress/data/sequence.h 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,205 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 LASTEXPRESS_SEQUENCE_H
+#define LASTEXPRESS_SEQUENCE_H
+
+/*
+ Sequence format (.SEQ / .NIS (frame header & data only))
+
+ uint32 {4} - Number of frames in sequence
+ uint32 {4} - Unknown
+
+ frames headers (68 bytes):
+ // for each frame
+ uint32 {4} - Data offset (from beginning of file)
+ uint32 {4} - Unknown
+ uint32 {4} - Palette offset (from beginning of file)
+ uint32 {4} - Top-left X coordinate
+ uint32 {4} - Top-left Y coordinate
+ uint32 {4} - Bottom-right X coordinate
+ uint32 {4} - Bottom-right Y coordinate
+ uint32 {4} - Initial offset of decompressed data (doubled, since each pixel occupies one color word)
+ uint32 {4} - End of data after decompression
+
+ (for SEQ files only)
+ uint16 {2} - Hotspot left
+ uint16 {2} - Hotspot right
+ uint16 {2} - Hotspot top
+ uint16 {2} - Hotspot bottom
+ byte {1} - Compression type
+ byte {1} - Subtype (determines which set of decompression functions will be called) => 0, 1, 2, 3
+ byte {1} - Unknown
+ byte {1} - Unknown
+ uint16 {2} - Unknown
+ byte {1} - Sound action
+ byte {1} - Unknown
+ uint32 {4} - positionId
+ uint32 {4} - Unknown
+ uint16 {2} - Entity Position
+ uint16 {2} - Location (~z-order)
+ uint32 {4} - Next sequence in the linked list
+
+ (for NIS files: found at 0x124)
+ byte {1} - Compression type
+
+ palette data:
+ uint16 {x} - palette data (max size: 256)
+
+ data
+ byte {x} - compressed image data
+*/
+
+#include "lastexpress/drawable.h"
+
+#include "lastexpress/shared.h"
+
+#include "common/array.h"
+#include "common/stream.h"
+
+namespace LastExpress {
+
+enum FrameSubType {
+ kFrameTypeNone = 0,
+ kFrameType1 = 1,
+ kFrameType2 = 2,
+ kFrameType3 = 3
+};
+
+struct FrameInfo {
+ void read(Common::SeekableReadStream *in, bool isSequence);
+
+ uint32 dataOffset; ///< Data offset (from beginning of file)
+ uint32 unknown; ///< FIXME: unknown data
+ uint32 paletteOffset; ///< Palette offset (from beginning of file)
+ uint32 xPos1; ///< Top-left X coordinate
+ uint32 yPos1; ///< Top-left Y coordinate
+ uint32 xPos2; ///< Bottom-right X coordinate
+ uint32 yPos2; ///< Bottom-right Y coordinate
+ uint32 initialSkip; ///< Initial on-screen offset of decompressed data (doubled, since each pixel occupies one color word)
+ uint32 decompressedEndOffset; ///< End of data after decompression
+
+ // NIS frame headers end here. SEQ frame headers have additional 32 bytes of
+ // data, notably the compression type at the position outlined above in
+ // CompPos_SEQ
+
+ Common::Rect hotspot;
+
+ byte compressionType; ///< Type of frame compression (0x03, 0x04, 0x05, 0x07, 0xFF)
+ FrameSubType subType; ///< Subtype (byte)
+
+ byte field_2E;
+ byte keepPreviousFrame;
+ byte field_30;
+ byte field_31;
+ byte soundAction;
+ byte field_33;
+ Position position;
+ byte field_35;
+ int16 field_36;
+ uint32 field_38;
+ EntityPosition entityPosition;
+ uint16 location;
+ uint32 next;
+};
+
+class AnimFrame : public Drawable {
+public:
+ AnimFrame(Common::SeekableReadStream *in, const FrameInfo &f);
+ ~AnimFrame();
+ Common::Rect draw(Graphics::Surface *s);
+
+private:
+ void decomp3(Common::SeekableReadStream *in, const FrameInfo &f);
+ void decomp4(Common::SeekableReadStream *in, const FrameInfo &f);
+ void decomp34(Common::SeekableReadStream *in, const FrameInfo &f, byte mask, byte shift);
+ void decomp5(Common::SeekableReadStream *in, const FrameInfo &f);
+ void decomp7(Common::SeekableReadStream *in, const FrameInfo &f);
+ void decompFF(Common::SeekableReadStream *in, const FrameInfo &f);
+ void readPalette(Common::SeekableReadStream *in, const FrameInfo &f);
+
+ Graphics::Surface _image;
+ uint16 _palSize;
+ uint16 *_palette;
+ Common::Rect _rect;
+};
+
+class Sequence {
+public:
+ Sequence(Common::String name) : _stream(NULL), _isLoaded(false), _name(name), _field30(15) {}
+ ~Sequence();
+
+ static Sequence *load(Common::String name, Common::SeekableReadStream *stream = NULL, byte field30 = 15);
+
+ bool load(Common::SeekableReadStream *stream, byte field30 = 15);
+
+ uint16 count() const { return (uint16)_frames.size(); };
+ AnimFrame *getFrame(uint16 index = 0);
+ FrameInfo *getFrameInfo(uint16 index = 0);
+
+ Common::String getName() { return _name; }
+ byte getField30() { return _field30; }
+
+ bool isLoaded() { return _isLoaded; }
+
+private:
+ static const uint32 _sequenceHeaderSize = 8;
+ static const uint32 _sequenceFrameSize = 68;
+
+ void reset();
+
+ Common::Array<FrameInfo> _frames;
+ Common::SeekableReadStream *_stream;
+ bool _isLoaded;
+
+ Common::String _name;
+ byte _field30; // used when copying sequences
+};
+
+class SequenceFrame : public Drawable {
+public:
+ SequenceFrame(Sequence *sequence, uint16 frame = 0, bool dispose = false) : _sequence(sequence), _frame(frame), _dispose(dispose) {}
+ ~SequenceFrame();
+
+ Common::Rect draw(Graphics::Surface *surface);
+
+ bool setFrame(uint16 frame);
+ uint32 getFrame() { return _frame; }
+ bool nextFrame();
+
+ Common::String getName() { return _sequence->getName(); }
+ FrameInfo *getInfo();
+
+ bool equal(const SequenceFrame *other) const;
+
+private:
+ Sequence *_sequence;
+ uint16 _frame;
+ bool _dispose;
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_SEQUENCE_H
Property changes on: scummvm/trunk/engines/lastexpress/data/sequence.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/lastexpress/data/snd.cpp
===================================================================
--- scummvm/trunk/engines/lastexpress/data/snd.cpp (rev 0)
+++ scummvm/trunk/engines/lastexpress/data/snd.cpp 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,141 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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$
+ *
+ */
+
+// Based on the Xentax Wiki documentation:
+// http://wiki.xentax.com/index.php/The_Last_Express_SND
+
+#include "lastexpress/data/snd.h"
+
+#include "lastexpress/debug.h"
+
+#include "sound/decoders/adpcm.h"
+#include "sound/audiostream.h"
+
+namespace LastExpress {
+
+//////////////////////////////////////////////////////////////////////////
+// Sound
+//////////////////////////////////////////////////////////////////////////
+SimpleSound::SimpleSound() : _size(0), _blocks(0), _blockSize(0) {}
+
+SimpleSound::~SimpleSound() {
+ stop();
+}
+
+// Stop the sound
+void SimpleSound::stop() const {
+ g_system->getMixer()->stopHandle(_handle);
+}
+
+void SimpleSound::loadHeader(Common::SeekableReadStream *in) {
+ _size = in->readUint32LE();
+ _blocks = in->readUint16LE();
+ debugC(5, kLastExpressDebugSound, " sound header data: size=\"%d\", %d blocks", _size, _blocks);
+
+ assert (_size % _blocks == 0);
+ _blockSize = _size / _blocks;
+}
+
+Audio::AudioStream *SimpleSound::makeDecoder(Common::SeekableReadStream *in, uint32 size) const {
+ return Audio::makeADPCMStream(in, DisposeAfterUse::YES, size, Audio::kADPCMMSImaLastExpress, 44100, 1, _blockSize);
+}
+
+void SimpleSound::play(Audio::AudioStream *as) {
+ g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_handle, as);
+}
+
+//////////////////////////////////////////////////////////////////////////
+// StreamedSound
+//////////////////////////////////////////////////////////////////////////
+StreamedSound::StreamedSound() {}
+StreamedSound::~StreamedSound() {}
+
+bool StreamedSound::load(Common::SeekableReadStream *stream) {
+ if (!stream)
+ return false;
+
+ g_system->getMixer()->stopHandle(_handle);
+
+ loadHeader(stream);
+
+ // Start decoding the input stream
+ Audio::AudioStream *as = makeDecoder(stream, _size);
+
+ // Start playing the decoded audio stream
+ play(as);
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// StreamedSound
+//////////////////////////////////////////////////////////////////////////
+AppendableSound::AppendableSound() : SimpleSound() {
+ // Create an audio stream where the decoded chunks will be appended
+ _as = Audio::makeQueuingAudioStream(44100, false);
+ _finished = false;
+
+ // Start playing the decoded audio stream
+ play(_as);
+
+ // Initialize the block size
+ // TODO: get it as an argument?
+ _blockSize = 739;
+}
+
+AppendableSound::~AppendableSound() {
+ finish();
+
+ _as = NULL;
+}
+
+void AppendableSound::queueBuffer(const byte *data, uint32 size) {
+ Common::MemoryReadStream *buffer = new Common::MemoryReadStream(data, size);
+ queueBuffer(buffer);
+}
+
+void AppendableSound::queueBuffer(Common::SeekableReadStream *bufferIn) {
+ if (!_as)
+ error("AppendableSound::queueBuffer - internal error: the audio stream is invalid!");
+
+ // Setup the ADPCM decoder
+ uint32 sizeIn = (uint32)bufferIn->size();
+ Audio::AudioStream *adpcm = makeDecoder(bufferIn, sizeIn);
+
+ // Queue the stream
+ _as->queueAudioStream(adpcm);
+}
+
+void AppendableSound::finish() {
+ if (!_as)
+ error("AppendableSound::queueBuffer - internal error: the audio stream is invalid!");
+
+ if (!_finished)
+ _as->finish();
+
+ _finished = true;
+}
+
+} // End of namespace LastExpress
Property changes on: scummvm/trunk/engines/lastexpress/data/snd.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/lastexpress/data/snd.h
===================================================================
--- scummvm/trunk/engines/lastexpress/data/snd.h (rev 0)
+++ scummvm/trunk/engines/lastexpress/data/snd.h 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,97 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 LASTEXPRESS_SND_H
+#define LASTEXPRESS_SND_H
+
+/*
+ Sound format (.SND / .LNK)
+
+ uint32 {4} - data size
+ uint16 {2} - number of blocks
+
+ // for each block
+ int16 {2} - initial sample
+ byte {1} - initial index
+ byte {1} - unused (00)
+ byte {x} - IMA ADPCM sample codes
+*/
+
+#include "common/stream.h"
+#include "sound/mixer.h"
+
+namespace Audio {
+ class AudioStream;
+ class QueuingAudioStream;
+}
+
+namespace LastExpress {
+
+class SimpleSound {
+public:
+ SimpleSound();
+ virtual ~SimpleSound();
+
+ void stop() const;
+
+protected:
+ void loadHeader(Common::SeekableReadStream *in);
+ Audio::AudioStream *makeDecoder(Common::SeekableReadStream *in, uint32 size) const;
+ void play(Audio::AudioStream *as);
+
+ uint32 _size; ///< data size
+ ///< - NIS: size of all blocks, including those located in the matching LNK file
+ ///< - LNK: size of the LNK file itself, including the header
+ ///< - SND: size of all blocks
+ uint16 _blocks; ///< number of blocks
+ uint32 _blockSize;
+ Audio::SoundHandle _handle;
+};
+
+class StreamedSound : public SimpleSound {
+public:
+ StreamedSound();
+ ~StreamedSound();
+
+ bool load(Common::SeekableReadStream *stream);
+};
+
+class AppendableSound : public SimpleSound {
+public:
+ AppendableSound();
+ ~AppendableSound();
+
+ void queueBuffer(const byte *data, uint32 size);
+ void queueBuffer(Common::SeekableReadStream *bufferIn);
+ void finish();
+
+private:
+ Audio::QueuingAudioStream *_as;
+ bool _finished;
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_SND_H
Property changes on: scummvm/trunk/engines/lastexpress/data/snd.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/lastexpress/data/subtitle.cpp
===================================================================
--- scummvm/trunk/engines/lastexpress/data/subtitle.cpp (rev 0)
+++ scummvm/trunk/engines/lastexpress/data/subtitle.cpp 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,243 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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$
+ *
+ */
+
+// Based on the Xentax Wiki documentation:
+// http://wiki.xentax.com/index.php/The_Last_Express_SBE
+
+#include "lastexpress/data/subtitle.h"
+
+#include "lastexpress/data/font.h"
+
+#include "lastexpress/debug.h"
+
+#include "common/debug.h"
+
+namespace LastExpress {
+
+//////////////////////////////////////////////////////////////////////////
+// Subtitle
+//////////////////////////////////////////////////////////////////////////
+class Subtitle {
+public:
+ Subtitle() : _timeStart(0), _timeStop(0), _topLength(0), _topText(NULL),
+ _bottomLength(0), _bottomText(NULL) {}
+ ~Subtitle() { reset(); }
+
+ bool load(Common::SeekableReadStream *in);
+ Common::Rect draw(Graphics::Surface *surface, Font *font);
+
+ uint16 getTimeStart() const { return _timeStart; }
+ uint16 getTimeStop() const { return _timeStop; }
+
+private:
+ uint16 _timeStart; ///< display start time
+ uint16 _timeStop; ///< display stop time
+
+ uint16 _topLength; ///< top line length
+ uint16 *_topText; ///< bottom line length
+
+ uint16 _bottomLength; ///< top line (UTF-16 string)
+ uint16 *_bottomText; ///< bottom line (UTF-16 string)
+
+ void reset();
+};
+
+void Subtitle::reset() {
+ delete[] _topText;
+ delete[] _bottomText;
+ _topText = NULL;
+ _bottomText = NULL;
+}
+
+template<typename T>
+T *newArray(size_t n)
+{
+ if (n <= (size_t)-1 / sizeof(T))
+ return new T[n];
+
+ // n is too large
+ return NULL;
+}
+
+bool Subtitle::load(Common::SeekableReadStream *in) {
+ reset();
+
+ if (!in)
+ return false;
+
+ // Read the display times
+ _timeStart = in->readUint16LE();
+ _timeStop = in->readUint16LE();
+
+ // Read the text lengths
+ _topLength = in->readUint16LE();
+ _bottomLength = in->readUint16LE();
+
+ // Create the buffers
+ if (_topLength) {
+ _topText = newArray<uint16>(_topLength);
+ if (!_topText)
+ return false;
+ }
+ if (_bottomLength) {
+ _bottomText = newArray<uint16>(_bottomLength);
+ if (!_bottomText)
+ return false;
+ }
+
+ // Read the texts
+ for (int i = 0; i < _topLength; i++)
+ _topText[i] = in->readUint16LE();
+ for (int i = 0; i < _bottomLength; i++)
+ _bottomText[i] = in->readUint16LE();
+
+ debugC(9, kLastExpressDebugSubtitle, " %d -> %d:", _timeStart, _timeStop);
+ if (_topLength)
+ debugC(9, kLastExpressDebugSubtitle, "\t%ls", (wchar_t *)_topText);
+ if (_bottomLength)
+ debugC(9, kLastExpressDebugSubtitle, "\t%ls", (wchar_t *)_bottomText);
+
+ return true;
+}
+
+Common::Rect Subtitle::draw(Graphics::Surface *surface, Font *font) {
+ Common::Rect rectTop, rectBottom;
+
+ //FIXME find out proper subtitles coordinates (and hope it's hardcoded and not stored in the sequence or animation)
+ rectTop = font->drawString(surface, 100, 100, _topText, _topLength);
+ rectBottom = font->drawString(surface, 100, 300, _bottomText, _bottomLength);
+
+ rectTop.extend(rectBottom);
+
+ return rectTop;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+// SubtitleManager
+//////////////////////////////////////////////////////////////////////////
+SubtitleManager::SubtitleManager(Font *font) : _font(font), _maxTime(0), _currentIndex(-1), _lastIndex(-1) {}
+
+SubtitleManager::~SubtitleManager() {
+ reset();
+
+ _font = NULL;
+}
+
+void SubtitleManager::reset() {
+ for (int i = 0; i < (int)_subtitles.size(); i++)
+ delete _subtitles[i];
+
+ _subtitles.clear();
+ _currentIndex = -1;
+ _lastIndex = -1;
+
+ // Zero passed pointers
+ _font = NULL;
+}
+
+bool SubtitleManager::load(Common::SeekableReadStream *stream) {
+ if (!stream)
+ return false;
+
+ reset();
+
+ // Read header to get the number of subtitles
+ uint32 numSubtitles = stream->readUint16LE();
+ if (stream->eos())
+ error("Cannot read from subtitle file");
+
+ debugC(3, kLastExpressDebugSubtitle, "Number of subtitles in file: %d", numSubtitles);
+
+ // TODO: Check that stream contain enough data
+ //if (stream->size() < (signed)(numSubtitles * sizeof(SubtitleData))) {
+ //debugC(2, kLastExpressDebugSubtitle, "Subtitle file does not contain valid data!");
+ //return false;
+ //}
+
+ // Read the list of subtitles
+ _maxTime = 0;
+ for (uint i = 0; i < numSubtitles; i++) {
+ Subtitle *subtitle = new Subtitle();
+ if (!subtitle->load(stream)) {
+ // Failed to read this line
+ reset();
+
+ delete subtitle;
+
+ return false;
+ }
+
+ // Update the max time
+ if (subtitle->getTimeStop() > _maxTime)
+ _maxTime = subtitle->getTimeStop();
+
+ _subtitles.push_back(subtitle);
+ }
+
+ delete stream;
+
+ return true;
+}
+
+uint16 SubtitleManager::getMaxTime() const {
+ return _maxTime;
+}
+
+void SubtitleManager::setTime(uint16 time) {
+ _currentIndex = -1;
+
+ // Find the appropriate line to show
+ for (int16 i = 0; i < (int16)_subtitles.size(); i++) {
+ if ((time >= _subtitles[i]->getTimeStart()) && (time <= _subtitles[i]->getTimeStop())) {
+ // Keep the index of the line to show
+ _currentIndex = i;
+ return;
+ }
+ }
+}
+
+bool SubtitleManager::hasChanged() const {
+ // TODO: mark the old line rect as dirty
+ if (_currentIndex != _lastIndex)
+ return true;
+ else
+ return false;
+}
+
+Common::Rect SubtitleManager::draw(Graphics::Surface *surface) {
+ // Update the last drawn index
+ _lastIndex = _currentIndex;
+
+ // Return if we don't have to draw any line
+ if (_currentIndex == -1)
+ return Common::Rect();
+
+ // Draw the current line
+ assert(_currentIndex >= 0 && _currentIndex < (int16)_subtitles.size());
+ return _subtitles[_currentIndex]->draw(surface, _font);
+}
+
+} // End of namespace LastExpress
Property changes on: scummvm/trunk/engines/lastexpress/data/subtitle.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/lastexpress/data/subtitle.h
===================================================================
--- scummvm/trunk/engines/lastexpress/data/subtitle.h (rev 0)
+++ scummvm/trunk/engines/lastexpress/data/subtitle.h 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,79 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 LASTEXPRESS_SUBTITLE_H
+#define LASTEXPRESS_SUBTITLE_H
+
+/*
+ Subtitle format (.SBE)
+
+ uint16 {2} - number of subtitles
+
+ // for each subtitle
+ uint16 {2} - display start time
+ uint16 {2} - display stop time
+ uint16 {2} - top line length
+ uint16 {2} - bottom line length
+ byte {x} - top line (UTF-16 string)
+ byte {x} - bottom line (UTF-16 string)
+
+ Subtitles seem to be drawn on screen at (80, 420) x (560, 458)
+*/
+
+#include "lastexpress/drawable.h"
+
+#include "common/array.h"
+#include "common/stream.h"
+
+namespace LastExpress {
+
+class Font;
+class Subtitle;
+
+class SubtitleManager : public Drawable {
+public:
+ SubtitleManager(Font *font);
+ ~SubtitleManager();
+
+ bool load(Common::SeekableReadStream *stream);
+ uint16 getMaxTime() const;
+ void setTime(uint16 time);
+ bool hasChanged() const;
+ Common::Rect draw(Graphics::Surface *surface);
+
+private:
+ Common::Array<Subtitle *> _subtitles;
+ Font *_font;
+ uint16 _maxTime;
+
+ int16 _currentIndex;
+ int16 _lastIndex;
+
+ void reset();
+};
+
+} // End of namespace LastExpress
+
+#endif // LASTEXPRESS_SUBTITLE_H
Property changes on: scummvm/trunk/engines/lastexpress/data/subtitle.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/lastexpress/debug.cpp
===================================================================
--- scummvm/trunk/engines/lastexpress/debug.cpp (rev 0)
+++ scummvm/trunk/engines/lastexpress/debug.cpp 2010-10-18 19:17:38 UTC (rev 53579)
@@ -0,0 +1,1091 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * 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 "lastexpress/debug.h"
+
+// Data
+#include "lastexpress/data/animation.h"
+#include "lastexpress/data/background.h"
+#include "lastexpress/data/cursor.h"
+#include "lastexpress/data/scene.h"
+#include "lastexpress/data/sequence.h"
+#include "lastexpress/data/snd.h"
+#include "lastexpress/data/subtitle.h"
+
+#include "lastexpress/game/action.h"
+#include "lastexpress/game/beetle.h"
+#include "lastexpress/game/fight.h"
+#include "lastexpress/game/inventory.h"
+#include "lastexpress/game/logic.h"
+#include "lastexpress/game/object.h"
+#include "lastexpress/game/savegame.h"
+#include "lastexpress/game/savepoint.h"
+#include "lastexpress/game/scenes.h"
+#include "lastexpress/game/sound.h"
+#include "lastexpress/game/state.h"
+
+#include "lastexpress/graphics.h"
+#include "lastexpress/helpers.h"
+#include "lastexpress/lastexpress.h"
+#include "lastexpress/resource.h"
+
+#include "common/debug-channels.h"
+#include "common/events.h"
+
+namespace LastExpress {
+
+Debugger::Debugger(LastExpressEngine *engine) : _engine(engine), _command(NULL), _numParams(0), _commandParams(NULL) {
+
+ //////////////////////////////////////////////////////////////////////////
+ // Register the debugger commands
+
+ // General
+ DCmd_Register("help", WRAP_METHOD(Debugger, cmdHelp));
+
+ // Data
+ DCmd_Register("ls", WRAP_METHOD(Debugger, cmdListFiles));
+
+ DCmd_Register("showframe", WRAP_METHOD(Debugger, cmdShowFrame));
+ DCmd_Register("showbg", WRAP_METHOD(Debugger, cmdShowBg));
+ DCmd_Register("playseq", WRAP_METHOD(Debugger, cmdPlaySeq));
+ DCmd_Register("playsnd", WRAP_METHOD(Debugger, cmdPlaySnd));
+ DCmd_Register("playsbe", WRAP_METHOD(Debugger, cmdPlaySbe));
+ DCmd_Register("playnis", WRAP_METHOD(Debugger, cmdPlayNis));
+
+ // Scene & interaction
+ DCmd_Register("loadscene", WRAP_METHOD(Debugger, cmdLoadScene));
+ DCmd_Register("fight", WRAP_METHOD(Debugger, cmdFight));
+ DCmd_Register("beetle", WRAP_METHOD(Debugger, cmdBeetle));
+
+ // Game
+ DCmd_Register("delta", WRAP_METHOD(Debugger, cmdTimeDelta));
+ DCmd_Register("dump", WRAP_METHOD(Debugger, cmdDump));
+ DCmd_Register("entity", WRAP_METHOD(Debugger, cmdEntity));
+
+ // Misc
+ DCmd_Register("loadgame", WRAP_METHOD(Debugger, cmdLoadGame));
+ DCmd_Register("chapter", WRAP_METHOD(Debugger, cmdSwitchChapter));
+ DCmd_Register("clear", WRAP_METHOD(Debugger, cmdClear));
+
+ resetCommand();
+
+ _soundStream = new StreamedSound();
+}
+
+Debugger::~Debugger() {
+ DebugMan.clearAllDebugChannels();
+
+ delete _soundStream;
+
+ // Zero passed pointers
+ _engine = NULL;
+ _command = NULL;
+ _commandParams = NULL;
+}
+
@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list