aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.common6
-rw-r--r--awe/awe.cpp130
-rw-r--r--awe/awe.h57
-rw-r--r--awe/bank.cpp140
-rw-r--r--awe/bank.h56
-rw-r--r--awe/engine.cpp145
-rw-r--r--awe/engine.h60
-rw-r--r--awe/file.cpp190
-rw-r--r--awe/file.h53
-rw-r--r--awe/intern.h67
-rw-r--r--awe/logic.cpp512
-rw-r--r--awe/logic.h114
-rw-r--r--awe/module.mk25
-rw-r--r--awe/resource.cpp277
-rw-r--r--awe/resource.h92
-rw-r--r--awe/sdlstub.cpp324
-rw-r--r--awe/serializer.cpp127
-rw-r--r--awe/serializer.h88
-rw-r--r--awe/staticres.cpp403
-rw-r--r--awe/systemstub.h68
-rw-r--r--awe/util.cpp58
-rw-r--r--awe/util.h47
-rw-r--r--awe/video.cpp516
-rw-r--r--awe/video.h102
-rw-r--r--base/plugins.cpp4
-rw-r--r--base/plugins.h4
-rwxr-xr-xconfigure12
-rw-r--r--dists/msvc7/awe.vcproj169
-rw-r--r--dists/msvc7/scummvm.sln23
-rw-r--r--dists/msvc7/scummvm.vcproj4
30 files changed, 3863 insertions, 10 deletions
diff --git a/Makefile.common b/Makefile.common
index 78968451bb..09a7bc73ee 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -91,6 +91,12 @@ else
MODULES += kyra
endif
+ifdef DISABLE_AWE
+DEFINES += -DDISABLE_AWE
+else
+MODULES += awe
+endif
+
# After the game specific modules follow the shared modules
MODULES += \
gui \
diff --git a/awe/awe.cpp b/awe/awe.cpp
new file mode 100644
index 0000000000..df1f7c59d4
--- /dev/null
+++ b/awe/awe.cpp
@@ -0,0 +1,130 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "common/stdafx.h"
+
+#include "base/gameDetector.h"
+#include "base/plugins.h"
+#include "backends/fs/fs.h"
+
+#include "sound/mixer.h"
+#include "common/file.h"
+#include "common/config-manager.h"
+
+#include "awe/awe.h"
+#include "awe/engine.h"
+#include "awe/systemstub.h"
+#include "awe/util.h"
+
+
+struct AWEGameSettings {
+ const char *name;
+ const char *description;
+ byte id;
+ uint32 features;
+ const char *detectname;
+ GameSettings toGameSettings() const {
+ GameSettings dummy = { name, description, features };
+ return dummy;
+ }
+};
+
+static const AWEGameSettings awe_settings[] = {
+ /* Another World - Out of this World - Europe DOS version */
+ { "worlde", "Another World - Out of this World - (Europe, DOS)", Awe::GID_WORLDE, MDT_ADLIB, "bank01" },
+ { NULL, NULL, 0, 0, NULL }
+};
+
+GameList Engine_AWE_gameList() {
+ const AWEGameSettings *g = awe_settings;
+ GameList games;
+ while (g->name) {
+ games.push_back(g->toGameSettings());
+ g++;
+ }
+ return games;
+}
+
+DetectedGameList Engine_AWE_detectGames(const FSList &fslist) {
+ DetectedGameList detectedGames;
+ const AWEGameSettings *g;
+
+ for (g = awe_settings; g->name; ++g) {
+ // Iterate over all files in the given directory
+ for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
+ const char *gameName = file->displayName().c_str();
+
+ if (0 == scumm_stricmp(g->detectname, gameName)) {
+ // Match found, add to list of candidates, then abort inner loop.
+ detectedGames.push_back(g->toGameSettings());
+ break;
+ }
+ }
+ }
+ return detectedGames;
+}
+
+Engine *Engine_AWE_create(GameDetector *detector, OSystem *syst) {
+ return new Awe::AweEngine(detector, syst);
+}
+
+REGISTER_PLUGIN("AWE Engine", Engine_AWE_gameList, Engine_AWE_create, Engine_AWE_detectGames)
+
+namespace Awe {
+
+AweEngine::AweEngine(GameDetector *detector, OSystem *syst)
+ : Engine(syst) {
+
+ // Setup mixer
+ if (!_mixer->isReady()) {
+ ::warning("Sound initialization failed.");
+ }
+
+ _mixer->setVolume(ConfMan.getInt("sfx_volume") * ConfMan.getInt("master_volume") / 255);
+
+ _dataPath = getGameDataPath();
+ _savePath = getSavePath();
+
+ // Initialize backend
+ syst->initSize(320, 200);
+}
+
+AweEngine::~AweEngine() {
+
+}
+
+void AweEngine::errorString(const char *buf1, char *buf2) {
+ strcpy(buf2, buf1);
+}
+
+void AweEngine::go() {
+ g_debugMask = DBG_INFO;
+ SystemStub *stub = SystemStub_SDL_create();
+ debug(0, "%s %s", _dataPath, _savePath);
+ Awe::Engine *e = new Awe::Engine(stub, _dataPath, _savePath);
+ e->run();
+ delete e;
+ delete stub;
+}
+
+void AweEngine::shutdown() {
+ _system->quit();
+}
+
+}
diff --git a/awe/awe.h b/awe/awe.h
new file mode 100644
index 0000000000..4091874137
--- /dev/null
+++ b/awe/awe.h
@@ -0,0 +1,57 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef AWE_H
+#define AWE_H
+
+#include "common/stdafx.h"
+#include "common/scummsys.h"
+#include "base/engine.h"
+#include "base/gameDetector.h"
+#include "common/util.h"
+
+namespace Awe {
+
+#define BYPASS_PROTECTION
+
+enum AWEGameId {
+ GID_WORLDE
+};
+
+class AweEngine : public ::Engine {
+
+ void errorString( const char *buf_input, char *buf_output);
+
+protected:
+ void go();
+ void shutdown();
+
+ const char *_dataPath;
+ const char *_savePath;
+
+public:
+
+ AweEngine(GameDetector *detector, OSystem *syst);
+ virtual ~AweEngine();
+
+};
+
+}
+
+#endif
diff --git a/awe/bank.cpp b/awe/bank.cpp
new file mode 100644
index 0000000000..65934dd339
--- /dev/null
+++ b/awe/bank.cpp
@@ -0,0 +1,140 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "common/stdafx.h"
+
+#include "awe/awe.h"
+#include "awe/bank.h"
+#include "awe/file.h"
+#include "awe/resource.h"
+
+namespace Awe {
+
+Bank::Bank(const char *dataDir)
+ : _dataDir(dataDir) {
+}
+
+bool Bank::read(const MemEntry *me, uint8 *buf) {
+ bool ret = false;
+ char bankName[10];
+ sprintf(bankName, "bank%02x", me->bankNum);
+ File f;
+ if (f.open(bankName, _dataDir)) {
+ f.seek(me->bankPos);
+ if (me->packedSize == me->unpackedSize) {
+ f.read(buf, me->packedSize);
+ ret = true;
+ } else {
+ f.read(buf, me->packedSize);
+ _startBuf = buf;
+ _iBuf = buf + me->packedSize - 4;
+ ret = unpack();
+ }
+ } else {
+ ::error("Bank::read() unable to open '%s'", bankName);
+ }
+ return ret;
+}
+
+void Bank::decUnk1(uint8 numChunks, uint8 addCount) {
+ uint16 count = getCode(numChunks) + addCount + 1;
+ debug(DBG_BANK, "Bank::decUnk1(%d, %d) count=%d", numChunks, addCount, count);
+ _unpCtx.datasize -= count;
+ while (count--) {
+ assert(_oBuf >= _iBuf && _oBuf >= _startBuf);
+ *_oBuf = (uint8)getCode(8);
+ --_oBuf;
+ }
+}
+
+void Bank::decUnk2(uint8 numChunks) {
+ uint16 i = getCode(numChunks);
+ uint16 count = _unpCtx.size + 1;
+ debug(DBG_BANK, "Bank::decUnk2(%d) i=%d count=%d", numChunks, i, count);
+ _unpCtx.datasize -= count;
+ while (count--) {
+ assert(_oBuf >= _iBuf && _oBuf >= _startBuf);
+ *_oBuf = *(_oBuf + i);
+ --_oBuf;
+ }
+}
+
+bool Bank::unpack() {
+ _unpCtx.size = 0;
+ _unpCtx.datasize = READ_BE_UINT32(_iBuf); _iBuf -= 4;
+ _oBuf = _startBuf + _unpCtx.datasize - 1;
+ _unpCtx.crc = READ_BE_UINT32(_iBuf); _iBuf -= 4;
+ _unpCtx.chk = READ_BE_UINT32(_iBuf); _iBuf -= 4;
+ _unpCtx.crc ^= _unpCtx.chk;
+ do {
+ if (!nextChunk()) {
+ _unpCtx.size = 1;
+ if (!nextChunk()) {
+ decUnk1(3, 0);
+ } else {
+ decUnk2(8);
+ }
+ } else {
+ uint16 c = getCode(2);
+ if (c == 3) {
+ decUnk1(8, 8);
+ } else {
+ if (c < 2) {
+ _unpCtx.size = c + 2;
+ decUnk2(c + 9);
+ } else {
+ _unpCtx.size = getCode(8);
+ decUnk2(12);
+ }
+ }
+ }
+ } while (_unpCtx.datasize > 0);
+ return (_unpCtx.crc == 0);
+}
+
+uint16 Bank::getCode(uint8 numChunks) {
+ uint16 c = 0;
+ while (numChunks--) {
+ c <<= 1;
+ if (nextChunk()) {
+ c |= 1;
+ }
+ }
+ return c;
+}
+
+bool Bank::nextChunk() {
+ bool CF = rcr(false);
+ if (_unpCtx.chk == 0) {
+ assert(_iBuf >= _startBuf);
+ _unpCtx.chk = READ_BE_UINT32(_iBuf); _iBuf -= 4;
+ _unpCtx.crc ^= _unpCtx.chk;
+ CF = rcr(true);
+ }
+ return CF;
+}
+
+bool Bank::rcr(bool CF) {
+ bool rCF = (_unpCtx.chk & 1);
+ _unpCtx.chk >>= 1;
+ if (CF) _unpCtx.chk |= 0x80000000;
+ return rCF;
+}
+
+}
diff --git a/awe/bank.h b/awe/bank.h
new file mode 100644
index 0000000000..a5c14b13f9
--- /dev/null
+++ b/awe/bank.h
@@ -0,0 +1,56 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __BANK_H__
+#define __BANK_H__
+
+#include "stdafx.h"
+
+#include "intern.h"
+
+namespace Awe {
+
+struct MemEntry;
+
+struct UnpackContext {
+ uint16 size;
+ uint32 crc;
+ uint32 chk;
+ int32 datasize;
+};
+
+struct Bank {
+ UnpackContext _unpCtx;
+ const char *_dataDir;
+ uint8 *_iBuf, *_oBuf, *_startBuf;
+
+ Bank(const char *dataDir);
+
+ bool read(const MemEntry *me, uint8 *buf);
+ void decUnk1(uint8 numChunks, uint8 addCount);
+ void decUnk2(uint8 numChunks);
+ bool unpack();
+ uint16 getCode(uint8 numChunks);
+ bool nextChunk();
+ bool rcr(bool CF);
+};
+
+}
+
+#endif
diff --git a/awe/engine.cpp b/awe/engine.cpp
new file mode 100644
index 0000000000..ab8b60dea4
--- /dev/null
+++ b/awe/engine.cpp
@@ -0,0 +1,145 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "stdafx.h"
+
+#include "awe.h"
+#include "engine.h"
+#include "file.h"
+#include "serializer.h"
+#include "systemstub.h"
+
+namespace Awe {
+
+Engine::Engine(SystemStub *stub, const char *dataDir, const char *saveDir)
+ : _stub(stub), _log(&_res, &_vid, stub), _res(&_vid, dataDir), _vid(&_res, stub),
+ _dataDir(dataDir), _saveDir(saveDir), _stateSlot(0) {
+}
+
+void Engine::run() {
+ _stub->init("Out Of This World");
+ setup();
+ // XXX
+ _log.restartAt(0x3E80); // demo starts at 0x3E81
+ while (!_stub->_pi.quit) {
+ _log.setupScripts();
+ _log.inp_updatePlayer();
+ processInput();
+ _log.runScripts();
+ }
+ finish();
+ _stub->destroy();
+}
+
+void Engine::setup() {
+ _vid.init();
+ _res.allocMemBlock();
+ _res.readEntries();
+ _log.init();
+}
+
+void Engine::finish() {
+ // XXX
+ _res.freeMemBlock();
+}
+
+void Engine::processInput() {
+ if (_stub->_pi.load) {
+ loadGameState(_stateSlot);
+ _stub->_pi.load = false;
+ }
+ if (_stub->_pi.save) {
+ saveGameState(_stateSlot, "quicksave");
+ _stub->_pi.save = false;
+ }
+ if (_stub->_pi.fastMode) {
+ _log._fastMode = !_log._fastMode;
+ _stub->_pi.fastMode = false;
+ }
+ if (_stub->_pi.stateSlot != 0) {
+ int8 slot = _stateSlot + _stub->_pi.stateSlot;
+ if (slot >= 0 && slot < MAX_SAVE_SLOTS) {
+ _stateSlot = slot;
+ debug(DBG_INFO, "Current game state slot is %d", _stateSlot);
+ }
+ _stub->_pi.stateSlot = 0;
+ }
+}
+
+void Engine::makeGameStateName(uint8 slot, char *buf) {
+ sprintf(buf, "raw.s%02d", slot);
+}
+
+void Engine::saveGameState(uint8 slot, const char *desc) {
+ char stateFile[20];
+ makeGameStateName(slot, stateFile);
+ File f(true);
+ if (!f.open(stateFile, _saveDir, "wb")) {
+ ::warning("Unable to save state file '%s'", stateFile);
+ } else {
+ // header
+ f.writeUint32BE('AWSV');
+ f.writeUint16BE(Serializer::CUR_VER);
+ f.writeUint16BE(0);
+ char hdrdesc[32];
+ strncpy(hdrdesc, desc, sizeof(hdrdesc) - 1);
+ f.write(hdrdesc, sizeof(hdrdesc));
+ // contents
+ Serializer s(&f, Serializer::SM_SAVE, _res._memPtrStart);
+ _log.saveOrLoad(s);
+ _res.saveOrLoad(s);
+ _vid.saveOrLoad(s);
+ if (f.ioErr()) {
+ ::warning("I/O error when saving game state");
+ } else {
+ debug(DBG_INFO, "Saved state to slot %d", _stateSlot);
+ }
+ }
+}
+
+void Engine::loadGameState(uint8 slot) {
+ char stateFile[20];
+ makeGameStateName(slot, stateFile);
+ File f(true);
+ if (!f.open(stateFile, _saveDir, "rb")) {
+ ::warning("Unable to open state file '%s'", stateFile);
+ } else {
+ uint32 id = f.readUint32BE();
+ if (id != 'AWSV') {
+ ::warning("Bad savegame format");
+ } else {
+ uint16 ver = f.readUint16BE();
+ f.readUint16BE();
+ char hdrdesc[32];
+ f.read(hdrdesc, sizeof(hdrdesc));
+ // contents
+ Serializer s(&f, Serializer::SM_LOAD, _res._memPtrStart, ver);
+ _log.saveOrLoad(s);
+ _res.saveOrLoad(s);
+ _vid.saveOrLoad(s);
+ }
+ if (f.ioErr()) {
+ ::warning("I/O error when loading game state");
+ } else {
+ debug(DBG_INFO, "Loaded state from slot %d", _stateSlot);
+ }
+ }
+}
+
+}
diff --git a/awe/engine.h b/awe/engine.h
new file mode 100644
index 0000000000..4a8a7ca19b
--- /dev/null
+++ b/awe/engine.h
@@ -0,0 +1,60 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ENGINE_H__
+#define __ENGINE_H__
+
+#include "stdafx.h"
+
+#include "intern.h"
+#include "logic.h"
+#include "resource.h"
+#include "video.h"
+
+namespace Awe {
+
+struct SystemStub;
+
+struct Engine {
+ enum {
+ MAX_SAVE_SLOTS = 100
+ };
+
+ SystemStub *_stub;
+ Logic _log;
+ Resource _res;
+ Video _vid;
+ const char *_dataDir, *_saveDir;
+ uint8 _stateSlot;
+
+ Engine(SystemStub *stub, const char *dataDir, const char *saveDir);
+
+ void run();
+ void setup();
+ void finish();
+ void processInput();
+
+ void makeGameStateName(uint8 slot, char *buf);
+ void saveGameState(uint8 slot, const char *desc);
+ void loadGameState(uint8 slot);
+};
+
+}
+
+#endif
diff --git a/awe/file.cpp b/awe/file.cpp
new file mode 100644
index 0000000000..15dead158e
--- /dev/null
+++ b/awe/file.cpp
@@ -0,0 +1,190 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "stdafx.h"
+
+#include "zlib.h"
+#include "file.h"
+
+namespace Awe {
+
+struct File_impl {
+ bool _ioErr;
+ File_impl() : _ioErr(false) {}
+ virtual bool open(const char *path, const char *mode) = 0;
+ virtual void close() = 0;
+ virtual void seek(int32 off) = 0;
+ virtual void read(void *ptr, uint32 size) = 0;
+ virtual void write(void *ptr, uint32 size) = 0;
+};
+
+struct stdFile : File_impl {
+ FILE *_fp;
+ stdFile() : _fp(0) {}
+ bool open(const char *path, const char *mode) {
+ _ioErr = false;
+ _fp = fopen(path, mode);
+ return (_fp != NULL);
+ }
+ void close() {
+ if (_fp) {
+ fclose(_fp);
+ _fp = 0;
+ }
+ }
+ void seek(int32 off) {
+ if (_fp) {
+ fseek(_fp, off, SEEK_SET);
+ }
+ }
+ void read(void *ptr, uint32 size) {
+ if (_fp) {
+ uint32 r = fread(ptr, 1, size, _fp);
+ if (r != size) {
+ _ioErr = true;
+ }
+ }
+ }
+ void write(void *ptr, uint32 size) {
+ if (_fp) {
+ uint32 r = fwrite(ptr, 1, size, _fp);
+ if (r != size) {
+ _ioErr = true;
+ }
+ }
+ }
+};
+
+struct zlibFile : File_impl {
+ gzFile _fp;
+ zlibFile() : _fp(0) {}
+ bool open(const char *path, const char *mode) {
+ _ioErr = false;
+ _fp = gzopen(path, mode);
+ return (_fp != NULL);
+ }
+ void close() {
+ if (_fp) {
+ gzclose(_fp);
+ _fp = 0;
+ }
+ }
+ void seek(int32 off) {
+ if (_fp) {
+ gzseek(_fp, off, SEEK_SET);
+ }
+ }
+ void read(void *ptr, uint32 size) {
+ if (_fp) {
+ uint32 r = gzread(_fp, ptr, size);
+ if (r != size) {
+ _ioErr = true;
+ }
+ }
+ }
+ void write(void *ptr, uint32 size) {
+ if (_fp) {
+ uint32 r = gzwrite(_fp, ptr, size);
+ if (r != size) {
+ _ioErr = true;
+ }
+ }
+ }
+};
+
+File::File(bool gzipped) {
+ if (gzipped) {
+ _impl = new zlibFile;
+ } else {
+ _impl = new stdFile;
+ }
+}
+
+File::~File() {
+ _impl->close();
+ delete _impl;
+}
+
+bool File::open(const char *filename, const char *directory, const char *mode) {
+ _impl->close();
+ char buf[512];
+ sprintf(buf, "%s/%s", directory, filename);
+ char *p = buf + strlen(directory) + 1;
+ string_lower(p);
+ bool opened = _impl->open(buf, mode);
+ if (!opened) { // let's try uppercase
+ string_upper(p);
+ opened = _impl->open(buf, mode);
+ }
+ return opened;
+}
+
+void File::close() {
+ _impl->close();
+}
+
+bool File::ioErr() const {
+ return _impl->_ioErr;
+}
+
+void File::seek(int32 off) {
+ _impl->seek(off);
+}
+
+void File::read(void *ptr, uint32 size) {
+ _impl->read(ptr, size);
+}
+
+uint8 File::readByte() {
+ uint8 b;
+ read(&b, 1);
+ return b;
+}
+
+uint16 File::readUint16BE() {
+ uint8 hi = readByte();
+ uint8 lo = readByte();
+ return (hi << 8) | lo;
+}
+
+uint32 File::readUint32BE() {
+ uint16 hi = readUint16BE();
+ uint16 lo = readUint16BE();
+ return (hi << 16) | lo;
+}
+
+void File::write(void *ptr, uint32 size) {
+ _impl->write(ptr, size);
+}
+
+void File::writeByte(uint8 b) {
+ write(&b, 1);
+}
+
+void File::writeUint16BE(uint16 n) {
+ writeByte(n >> 8);
+ writeByte(n & 0xFF);
+}
+
+void File::writeUint32BE(uint32 n) {
+ writeUint16BE(n >> 16);
+ writeUint16BE(n & 0xFFFF);
+}
+
+}
diff --git a/awe/file.h b/awe/file.h
new file mode 100644
index 0000000000..c1efc33ec1
--- /dev/null
+++ b/awe/file.h
@@ -0,0 +1,53 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __FILE_H__
+#define __FILE_H__
+
+#include "stdafx.h"
+
+#include "intern.h"
+
+namespace Awe {
+
+struct File_impl;
+
+struct File {
+ File_impl *_impl;
+
+ File(bool gzipped = false);
+ ~File();
+
+ bool open(const char *filename, const char *directory, const char *mode="rb");
+ void close();
+ bool ioErr() const;
+ void seek(int32 off);
+ void read(void *ptr, uint32 size);
+ uint8 readByte();
+ uint16 readUint16BE();
+ uint32 readUint32BE();
+ void write(void *ptr, uint32 size);
+ void writeByte(uint8 b);
+ void writeUint16BE(uint16 n);
+ void writeUint32BE(uint32 n);
+};
+
+}
+
+#endif
diff --git a/awe/intern.h b/awe/intern.h
new file mode 100644
index 0000000000..81b632de87
--- /dev/null
+++ b/awe/intern.h
@@ -0,0 +1,67 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __INTERN_H__
+#define __INTERN_H__
+
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+#include <cassert>
+
+#include "stdafx.h"
+
+#include "common/scummsys.h"
+
+#include "util.h"
+
+namespace Awe {
+
+template<typename T>
+inline void SWAP(T &a, T &b) {
+ T tmp = a;
+ a = b;
+ b = tmp;
+}
+
+struct Ptr {
+ uint8 *pc;
+
+ uint8 fetchByte() {
+ return *pc++;
+ }
+
+ uint16 fetchWord() {
+ uint16 i = READ_BE_UINT16(pc);
+ pc += 2;
+ return i;
+ }
+};
+
+struct Point {
+ int16 x, y;
+
+ Point() : x(0), y(0) {}
+ Point(int16 xx, int16 yy) : x(xx), y(yy) {}
+ Point(const Point &p) : x(p.x), y(p.y) {}
+};
+
+}
+
+#endif
diff --git a/awe/logic.cpp b/awe/logic.cpp
new file mode 100644
index 0000000000..64733e67f3
--- /dev/null
+++ b/awe/logic.cpp
@@ -0,0 +1,512 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <ctime>
+
+#include "stdafx.h"
+
+#include "awe.h"
+#include "logic.h"
+#include "resource.h"
+#include "video.h"
+#include "serializer.h"
+#include "systemstub.h"
+
+namespace Awe {
+
+Logic::Logic(Resource *res, Video *vid, SystemStub *stub)
+ : _res(res), _vid(vid), _stub(stub) {
+}
+
+void Logic::init() {
+ memset(_scriptVars, 0, sizeof(_scriptVars));
+ _scriptVars[0x54] = 0x81;
+ _scriptVars[VAR_RANDOM_SEED] = time(0);
+ _fastMode = false;
+}
+
+void Logic::op_movConst() {
+ uint8 i = _scriptPtr.fetchByte();
+ int16 n = _scriptPtr.fetchWord();
+ debug(DBG_LOGIC, "Logic::op_movConst(0x%02X, %d)", i, n);
+ _scriptVars[i] = n;
+}
+
+void Logic::op_mov() {
+ uint8 i = _scriptPtr.fetchByte();
+ uint8 j = _scriptPtr.fetchByte();
+ debug(DBG_LOGIC, "Logic::op_mov(0x%02X, 0x%02X)", i, j);
+ _scriptVars[i] = _scriptVars[j];
+}
+
+void Logic::op_add() {
+ uint8 i = _scriptPtr.fetchByte();
+ uint8 j = _scriptPtr.fetchByte();
+ debug(DBG_LOGIC, "Logic::op_add(0x%02X, 0x%02X)", i, j);
+ _scriptVars[i] += _scriptVars[j];
+}
+
+void Logic::op_addConst() {
+ uint8 i = _scriptPtr.fetchByte();
+ int16 n = _scriptPtr.fetchWord();
+ debug(DBG_LOGIC, "Logic::op_addConst(0x%02X, %d)", i, n);
+ _scriptVars[i] += n;
+}
+
+void Logic::op_call() {
+ uint16 off = _scriptPtr.fetchWord();
+ uint8 sp = _stackPtr;
+ debug(DBG_LOGIC, "Logic::op_call(0x%X)", off);
+ _scriptStackCalls[sp] = _scriptPtr.pc - _res->_segCode;
+ ++_stackPtr;
+ _scriptPtr.pc = _res->_segCode + off;
+}
+
+void Logic::op_ret() {
+ debug(DBG_LOGIC, "Logic::op_ret()");
+ --_stackPtr;
+ uint8 sp = _stackPtr;
+ _scriptPtr.pc = _res->_segCode + _scriptStackCalls[sp];
+}
+
+void Logic::op_break() {
+ debug(DBG_LOGIC, "Logic::op_break()");
+ _scriptHalted = true;
+}
+
+void Logic::op_jmp() {
+ uint16 off = _scriptPtr.fetchWord();
+ debug(DBG_LOGIC, "Logic::op_jmp(0x%02X)", off);
+ _scriptPtr.pc = _res->_segCode + off;
+}
+
+void Logic::op_setScriptPos() {
+ uint8 i = _scriptPtr.fetchByte();
+ uint16 n = _scriptPtr.fetchWord();
+ debug(DBG_LOGIC, "Logic::op_setScriptPos(0x%X, 0x%X)", i, n);
+ _scriptPos[1][i] = n;
+}
+
+void Logic::op_jnz() {
+ uint8 i = _scriptPtr.fetchByte();
+ debug(DBG_LOGIC, "Logic::op_jnz(0x%02X)", i);
+ --_scriptVars[i];
+ if (_scriptVars[i] != 0) {
+ op_jmp();
+ } else {
+ _scriptPtr.fetchWord();
+ }
+}
+
+void Logic::op_condJmp() {
+#ifdef BYPASS_PROTECTION
+ if (_res->_curPtrsId == 0x3E80 && _scriptPtr.pc == _res->_segCode + 0xCB9) {
+ // (0x0CB8) condJmp(0x80, VAR(41), VAR(30), 0xCD3)
+ *(_scriptPtr.pc + 0x00) = 0x81;
+ *(_scriptPtr.pc + 0x03) = 0x0D;
+ *(_scriptPtr.pc + 0x04) = 0x24;
+ // (0x0D4E) condJmp(0x4, VAR(50), 6, 0xDBC)
+ *(_scriptPtr.pc + 0x99) = 0x0D;
+ *(_scriptPtr.pc + 0x9A) = 0x5A;
+ ::warning("Logic::op_condJmp() bypassing protection");
+ }
+#endif
+ uint8 op = _scriptPtr.fetchByte();
+ int16 b = _scriptVars[_scriptPtr.fetchByte()];
+ int16 a = _scriptPtr.fetchByte();
+ if (op & 0x80) {
+ a = _scriptVars[a];
+ } else {
+ if (op & 0x40) {
+ a = (a << 8) | _scriptPtr.fetchByte();
+ }
+ }
+ debug(DBG_LOGIC, "Logic::op_condJmp(%d, 0x%02X, 0x%02X)", op, b, a);
+ bool expr = false;
+ switch (op & 7) {
+ case 0: // jz
+ expr = (b == a);
+ break;
+ case 1: // jnz
+ expr = (b != a);
+ break;
+ case 2: // jg
+ expr = (b > a);
+ break;
+ case 3: // jge
+ expr = (b >= a);
+ break;
+ case 4: // jl
+ expr = (b < a);
+ break;
+ case 5: // jle
+ expr = (b <= a);
+ break;
+ default:
+ ::warning("Logic::op_condJmp() invalid condition %d", (op & 7));
+ break;
+ }
+ if (expr) {
+ op_jmp();
+ } else {
+ _scriptPtr.fetchWord();
+ }
+}
+
+void Logic::op_setPalette() {
+ uint16 i = _scriptPtr.fetchWord();
+ debug(DBG_LOGIC, "Logic::op_changePalette(%d)", i);
+ _vid->_newPal = i >> 8;
+}
+
+void Logic::op_resetScript() {
+ uint8 j = _scriptPtr.fetchByte();
+ uint8 i = _scriptPtr.fetchByte();
+ int8 n = (i & 0x3F) - j;
+ if (n < 0) {
+ ::warning("Logic::op_resetScript() ec=0x%X (n < 0)", 0x880);
+ return;
+ }
+ ++n;
+ uint8 _al = _scriptPtr.fetchByte();
+
+ debug(DBG_LOGIC, "Logic::op_resetScript(%d, %d, %d)", j, i, _al);
+
+ if (_al == 2) {
+ uint16 *_si = &_scriptPos[1][j];
+ while (n--) {
+ *_si = 0xFFFE;
+ ++_si;
+ }
+ } else if (_al < 2) {
+ uint8 *_si = &_scriptPaused[1][j];
+ while (n--) {
+ *_si = _al;
+ ++_si;
+ }
+ }
+}
+
+void Logic::op_selectPage() {
+ uint8 i = _scriptPtr.fetchByte();
+ debug(DBG_LOGIC, "Logic::op_selectPage(%d)", i);
+ _vid->changePagePtr1(i);
+}
+
+void Logic::op_fillPage() {
+ uint8 screen = _scriptPtr.fetchByte();
+ uint8 color = _scriptPtr.fetchByte();
+ debug(DBG_LOGIC, "Logic::op_fillPage(%d, %d)", screen, color);
+ _vid->fillPage(screen, color);
+}
+
+void Logic::op_copyPage() {
+ uint8 i = _scriptPtr.fetchByte();
+ uint8 j = _scriptPtr.fetchByte();
+ debug(DBG_LOGIC, "Logic::op_copyPage(%d, %d)", i, j);
+ _vid->copyPage(i, j, _scriptVars[VAR_SCROLL_Y]);
+}
+
+void Logic::op_updateDisplay() {
+ uint8 page = _scriptPtr.fetchByte();
+ debug(DBG_LOGIC, "Logic::op_updateDisplay(%d)", page);
+ inp_handleSpecialKeys();
+ if (_res->_curPtrsId == 0x3E80 && _scriptVars[0x67] == 1) {
+ _scriptVar_0xBF = _scriptVars[0xBF];
+ _scriptVars[0xDC] = 0x21;
+ }
+
+ static uint32 tstamp = 0;
+ if (!_fastMode) {
+ // XXX experimental
+ int32 delay = _stub->getTimeStamp() - tstamp;
+ int32 pause = _scriptVars[VAR_PAUSE_SLICES] * 20 - delay;
+ if (pause > 0) {
+ _stub->sleep(pause);
+ }
+ }
+ _scriptVars[0xF7] = 0;
+
+ _vid->updateDisplay(page);
+ tstamp = _stub->getTimeStamp();
+}
+
+void Logic::op_halt() {
+ debug(DBG_LOGIC, "Logic::op_halt()");
+ _scriptPtr.pc = _res->_segCode + 0xFFFF;
+ _scriptHalted = true;
+}
+
+void Logic::op_drawString() {
+ uint16 strId = _scriptPtr.fetchWord();
+ uint16 x = _scriptPtr.fetchByte();
+ uint16 y = _scriptPtr.fetchByte();
+ uint16 col = _scriptPtr.fetchByte();
+ debug(DBG_LOGIC, "Logic::op_drawString(0x%03X, %d, %d, %d)", strId, x, y, col);
+ _vid->drawString(col, x, y, strId);
+}
+
+void Logic::op_sub() {
+ uint8 i = _scriptPtr.fetchByte();
+ uint8 j = _scriptPtr.fetchByte();
+ debug(DBG_LOGIC, "Logic::op_sub(0x%02X, 0x%02X)", i, j);
+ _scriptVars[i] -= _scriptVars[j];
+}
+
+void Logic::op_and() {
+ uint8 i = _scriptPtr.fetchByte();
+ uint16 n = _scriptPtr.fetchWord();
+ debug(DBG_LOGIC, "Logic::op_and(0x%02X, %d)", i, n);
+ _scriptVars[i] = (uint16)_scriptVars[i] & n;
+}
+
+void Logic::op_or() {
+ uint8 i = _scriptPtr.fetchByte();
+ uint16 n = _scriptPtr.fetchWord();
+ debug(DBG_LOGIC, "Logic::op_or(0x%02X, %d)", i, n);
+ _scriptVars[i] = (uint16)_scriptVars[i] | n;
+}
+
+void Logic::op_shl() {
+ uint8 i = _scriptPtr.fetchByte();
+ uint16 n = _scriptPtr.fetchWord();
+ debug(DBG_LOGIC, "Logic::op_shl(0x%02X, %d)", i, n);
+ _scriptVars[i] = (uint16)_scriptVars[i] << n;
+}
+
+void Logic::op_shr() {
+ uint8 i = _scriptPtr.fetchByte();
+ uint16 n = _scriptPtr.fetchWord();
+ debug(DBG_LOGIC, "Logic::op_shr(0x%02X, %d)", i, n);
+ _scriptVars[i] = (uint16)_scriptVars[i] >> n;
+}
+
+void Logic::op_soundUnk1() {
+ uint16 b = _scriptPtr.fetchWord();
+ uint16 c = _scriptPtr.fetchWord();
+ uint8 a = _scriptPtr.fetchByte();
+ debug(DBG_LOGIC, "Logic::op_soundUnk1(0x%X, 0x%X, %d)", b, c, a);
+ // XXX
+}
+
+void Logic::op_updateMemList() {
+ uint16 num = _scriptPtr.fetchWord();
+ debug(DBG_LOGIC, "Logic::op_updateMemList(%d)", num);
+ _res->update(num);
+}
+
+void Logic::op_soundUnk2() {
+ uint16 b = _scriptPtr.fetchWord();
+ uint16 c = _scriptPtr.fetchWord();
+ uint8 a = _scriptPtr.fetchByte();
+ debug(DBG_LOGIC, "Logic::op_soundUnk2(0x%X, 0x%X, %d)", b, c, a);
+ // XXX
+}
+
+void Logic::restartAt(uint16 ptrId) {
+ // XXX
+ _scriptVars[0xE4] = 0x14;
+ _res->setupPtrs(ptrId);
+ memset((uint8 *)_scriptPos, 0xFF, sizeof(_scriptPos));
+ memset((uint8 *)_scriptPaused, 0, sizeof(_scriptPaused));
+ _scriptPos[0][0] = 0;
+}
+
+void Logic::setupScripts() {
+ if (_res->_newPtrsId != 0) {
+ restartAt(_res->_newPtrsId);
+ _res->_newPtrsId = 0;
+ }
+ for (int i = 0; i < 0x40; ++i) {
+ _scriptPaused[0][i] = _scriptPaused[1][i];
+ uint16 n = _scriptPos[1][i];
+ if (n != 0xFFFF) {
+ _scriptPos[0][i] = (n == 0xFFFE) ? 0xFFFF : n;
+ _scriptPos[1][i] = 0xFFFF;
+ }
+ }
+}
+
+void Logic::runScripts() {
+ for (int i = 0; i < 0x40; ++i) {
+ if (_scriptPaused[0][i] == 0) {
+ uint16 n = _scriptPos[0][i];
+ if (n != 0xFFFF) {
+ _scriptPtr.pc = _res->_segCode + n;
+ _stackPtr = 0;
+ _scriptHalted = false;
+ debug(DBG_LOGIC, "Logic::runScripts() i=0x%02X n=0x%02X *p=0x%02X", i, n, *_scriptPtr.pc);
+ executeScript();
+ _scriptPos[0][i] = _scriptPtr.pc - _res->_segCode;
+ debug(DBG_LOGIC, "Logic::runScripts() i=0x%02X pos=0x%X", i, _scriptPos[0][i]);
+ if (_stub->_pi.quit) {
+ break;
+ }
+ }
+ }
+ }
+}
+
+void Logic::executeScript() {
+ while (!_scriptHalted) {
+ uint8 opcode = _scriptPtr.fetchByte();
+ if (opcode & 0x80) {
+ uint16 off = ((opcode << 8) | _scriptPtr.fetchByte()) * 2;
+ _res->_useSegVideo2 = false;
+ int16 x = _scriptPtr.fetchByte();
+ int16 y = _scriptPtr.fetchByte();
+ int16 h = y - 199;
+ if (h > 0) {
+ y = 199;
+ x += h;
+ }
+ debug(DBG_VIDEO, "vid_opcd_0x80 : opcode=0x%X off=0x%X x=%d y=%d", opcode, off, x, y);
+ _vid->setDataBuffer(_res->_segVideo1, off);
+ _vid->drawShape(0xFF, 0x40, Point(x,y));
+ } else if (opcode & 0x40) {
+ int16 x, y;
+ uint16 off = _scriptPtr.fetchWord() * 2;
+ x = _scriptPtr.fetchByte();
+ _res->_useSegVideo2 = false;
+ if (!(opcode & 0x20)) {
+ if (!(opcode & 0x10)) {
+ x = (x << 8) | _scriptPtr.fetchByte();
+ } else {
+ x = _scriptVars[x];
+ }
+ } else {
+ if (opcode & 0x10) {
+ x += 0x100;
+ }
+ }
+ y = _scriptPtr.fetchByte();
+ if (!(opcode & 8)) {
+ if (!(opcode & 4)) {
+ y = (y << 8) | _scriptPtr.fetchByte();
+ } else {
+ y = _scriptVars[y];
+ }
+ }
+ uint16 zoom = _scriptPtr.fetchByte();
+ if (!(opcode & 2)) {
+ if (!(opcode & 1)) {
+ --_scriptPtr.pc;
+ zoom = 0x40;
+ } else {
+ zoom = _scriptVars[zoom];
+ }
+ } else {
+ if (opcode & 1) {
+ _res->_useSegVideo2 = true;
+ --_scriptPtr.pc;
+ zoom = 0x40;
+ }
+ }
+ debug(DBG_VIDEO, "vid_opcd_0x40 : off=0x%X x=%d y=%d", off, x, y);
+ _vid->setDataBuffer(_res->_useSegVideo2 ? _res->_segVideo2 : _res->_segVideo1, off);
+ _vid->drawShape(0xFF, zoom, Point(x, y));
+ } else {
+ if (opcode > 0x1A) {
+ ::error("Logic::executeScript() ec=0x%X invalid opcode=0x%X", 0xFFF, opcode);
+ } else {
+ (this->*_opTable[opcode])();
+ }
+ }
+ }
+}
+
+void Logic::inp_updatePlayer() {
+ _stub->processEvents();
+ if (_res->_curPtrsId == 0x3E89) {
+ char c = _stub->_pi.lastChar;
+ if (c == 8 || /*c == 0xD ||*/ c == 0 || (c >= 'a' && c <= 'z')) {
+ _scriptVars[VAR_LAST_KEYCHAR] = c & ~0x20;
+ _stub->_pi.lastChar = 0;
+ }
+ }
+ int16 lr = 0;
+ int16 m = 0;
+ int16 ud = 0;
+ if (_stub->_pi.dirMask & PlayerInput::DIR_RIGHT) {
+ lr = 1;
+ m |= 1;
+ }
+ if (_stub->_pi.dirMask & PlayerInput::DIR_LEFT) {
+ lr = -1;
+ m |= 2;
+ }
+ if (_stub->_pi.dirMask & PlayerInput::DIR_DOWN) {
+ ud = 1;
+ m |= 4;
+ }
+ _scriptVars[VAR_HERO_POS_UP_DOWN] = ud;
+ if (_stub->_pi.dirMask & PlayerInput::DIR_UP) {
+ _scriptVars[VAR_HERO_POS_UP_DOWN] = -1;
+ }
+ if (_stub->_pi.dirMask & PlayerInput::DIR_UP) { // inpJump
+ ud = -1;
+ m |= 8;
+ }
+ _scriptVars[VAR_HERO_POS_JUMP_DOWN] = ud;
+ _scriptVars[VAR_HERO_POS_LEFT_RIGHT] = lr;
+ _scriptVars[VAR_HERO_POS_MASK] = m;
+ int16 button = 0;
+ if (_stub->_pi.button) { // inpButton
+ button = 1;
+ m |= 0x80;
+ }
+ _scriptVars[VAR_HERO_ACTION] = button;
+ _scriptVars[VAR_HERO_ACTION_POS_MASK] = m;
+}
+
+void Logic::inp_handleSpecialKeys() {
+ if (_stub->_pi.pause) {
+ if (_res->_curPtrsId != 0x3E80 && _res->_curPtrsId != 0x3E81) {
+ _stub->_pi.pause = false;
+ while (!_stub->_pi.pause) {
+ _stub->processEvents();
+ _stub->sleep(200);
+ }
+ }
+ _stub->_pi.pause = false;
+ }
+ if (_stub->_pi.code) {
+ _stub->_pi.code = false;
+ if (_res->_curPtrsId != 0x3E89 && _res->_curPtrsId != 0x3E80) {
+ _res->_newPtrsId = 0x3E89;
+ }
+ }
+ // XXX
+ if (_scriptVars[0xC9] == 1) {
+ ::warning("Logic::inp_handleSpecialKeys() unhandled case (_scriptVars[0xC9] == 1)");
+ }
+}
+
+void Logic::saveOrLoad(Serializer &ser) {
+ Serializer::Entry entries[] = {
+ SE_ARRAY(_scriptVars, 0x100, Serializer::SES_INT16, VER(1)),
+ SE_ARRAY(_scriptStackCalls, 0x100, Serializer::SES_INT16, VER(1)),
+ SE_ARRAY(_scriptPos, 0x40 * 2, Serializer::SES_INT16, VER(1)),
+ SE_ARRAY(_scriptPaused, 0x40 * 2, Serializer::SES_INT8, VER(1)),
+ SE_END()
+ };
+ ser.saveOrLoadEntries(entries);
+}
+
+}
diff --git a/awe/logic.h b/awe/logic.h
new file mode 100644
index 0000000000..7763c5204d
--- /dev/null
+++ b/awe/logic.h
@@ -0,0 +1,114 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __LOGIC_H__
+#define __LOGIC_H__
+
+#include "stdafx.h"
+
+#include "intern.h"
+
+namespace Awe {
+
+struct Resource;
+struct Serializer;
+struct SystemStub;
+struct Video;
+
+struct Logic {
+ typedef void (Logic::*OpcodeStub)();
+
+ enum ScriptVars {
+ VAR_RANDOM_SEED = 0x3C,
+
+ VAR_LAST_KEYCHAR = 0xDA,
+
+ VAR_HERO_POS_UP_DOWN = 0xE5,
+
+ VAR_SCROLL_Y = 0xF9,
+ VAR_HERO_ACTION = 0xFA,
+ VAR_HERO_POS_JUMP_DOWN = 0xFB,
+ VAR_HERO_POS_LEFT_RIGHT = 0xFC,
+ VAR_HERO_POS_MASK = 0xFD,
+ VAR_HERO_ACTION_POS_MASK = 0xFE,
+ VAR_PAUSE_SLICES = 0xFF
+ };
+
+ static const OpcodeStub _opTable[];
+
+ Resource *_res;
+ Video *_vid;
+ SystemStub *_stub;
+
+ int16 _scriptVar_0xBF;
+ int16 _scriptVars[0x100];
+ uint16 _scriptStackCalls[0x40];
+ uint16 _scriptPos[2][0x40];
+ uint8 _scriptPaused[2][0x40];
+ Ptr _scriptPtr;
+ uint8 _stackPtr;
+ bool _scriptHalted;
+ bool _fastMode;
+
+ Logic(Resource *res, Video *vid, SystemStub *stub);
+ void init();
+
+ void op_movConst();
+ void op_mov();
+ void op_add();
+ void op_addConst();
+ void op_call();
+ void op_ret();
+ void op_break();
+ void op_jmp();
+ void op_setScriptPos();
+ void op_jnz();
+ void op_condJmp();
+ void op_setPalette();
+ void op_resetScript();
+ void op_selectPage();
+ void op_fillPage();
+ void op_copyPage();
+ void op_updateDisplay();
+ void op_halt();
+ void op_drawString();
+ void op_sub();
+ void op_and();
+ void op_or();
+ void op_shl();
+ void op_shr();
+ void op_soundUnk1();
+ void op_updateMemList();
+ void op_soundUnk2();
+
+ void restartAt(uint16 ptrId);
+ void setupPtrs(uint16 ptrId);
+ void setupScripts();
+ void runScripts();
+ void executeScript();
+
+ void inp_updatePlayer();
+ void inp_handleSpecialKeys();
+
+ void saveOrLoad(Serializer &ser);
+};
+
+}
+
+#endif
diff --git a/awe/module.mk b/awe/module.mk
new file mode 100644
index 0000000000..c1ef6bdb4e
--- /dev/null
+++ b/awe/module.mk
@@ -0,0 +1,25 @@
+MODULE := awe
+
+MODULE_OBJS = \
+ awe/awe.o \
+ awe/bank.o \
+ awe/engine.o \
+ awe/file.o \
+ awe/logic.o \
+ awe/resource.o \
+ awe/sdlstub.o \
+ awe/serializer.o \
+ awe/staticres.o \
+ awe/util.o \
+ awe/video.o
+
+MODULE_DIRS += \
+ awe
+
+# This module can be built as a plugin
+ifdef BUILD_PLUGINS
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/common.rules
diff --git a/awe/resource.cpp b/awe/resource.cpp
new file mode 100644
index 0000000000..b5c621fcc6
--- /dev/null
+++ b/awe/resource.cpp
@@ -0,0 +1,277 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "stdafx.h"
+
+#include "awe.h"
+#include "resource.h"
+#include "bank.h"
+#include "file.h"
+#include "serializer.h"
+#include "video.h"
+
+namespace Awe {
+
+Resource::Resource(Video *vid, const char *dataDir)
+ : _vid(vid), _dataDir(dataDir) {
+}
+
+void Resource::readBank(const MemEntry *me, uint8 *dstBuf) {
+ uint16 n = me - _memList;
+ debug(DBG_BANK, "Resource::readBank(%d)", n);
+#ifdef USE_UNPACKED
+ char bankEntryName[64];
+ sprintf(bankEntryName, "ootw-%02X-%d.dump", n, me->type);
+ File f;
+ if (!f.open(bankEntryName, _dataDir)) {
+ ::error("Resource::readBank() unable to open '%s' file\n", bankEntryName);
+ }
+ f.read(dstBuf, me->unpackedSize);
+#else
+ Bank bk(_dataDir);
+ if (!bk.read(me, dstBuf)) {
+ ::error("Resource::readBank() unable to unpack entry %d\n", n);
+ }
+#endif
+}
+
+void Resource::readEntries() {
+ File f;
+ if (!f.open("memlist.bin", _dataDir)) {
+ ::error("Resource::readEntries() unable to open 'memlist.bin' file\n");
+ }
+ _numMemList = 0;
+ MemEntry *me = _memList;
+ while (1) {
+ assert(_numMemList < ARRAYSIZE(_memList));
+ me->valid = f.readByte();
+ me->type = f.readByte();
+ me->bufPtr = 0; f.readUint16BE();
+ me->unk4 = f.readUint16BE();
+ me->rankNum = f.readByte();
+ me->bankNum = f.readByte();
+ me->bankPos = f.readUint32BE();
+ me->unkC = f.readUint16BE();
+ me->packedSize = f.readUint16BE();
+ me->unk10 = f.readUint16BE();
+ me->unpackedSize = f.readUint16BE();
+ if (me->valid == 0xFF) {
+ break;
+ }
+ ++_numMemList;
+ ++me;
+ }
+}
+
+void Resource::load() {
+ while (1) {
+ MemEntry *it = _memList;
+ MemEntry *me = 0;
+
+ // get resource with max rankNum
+ uint8 maxNum = 0;
+ uint16 i = _numMemList;
+ while (i--) {
+ if (it->valid == 2 && maxNum <= it->rankNum) {
+ maxNum = it->rankNum;
+ me = it;
+ }
+ ++it;
+ }
+ if (me == 0) {
+ break; // no entry found
+ }
+
+ uint8 *memPtr = 0;
+ // XXX if (_audio_no_sound != 0 && _audio_use_roland != 0 && me->type < 2) {
+ // XXX me->valid = 0;
+ // XXX continue;
+ // XXX }
+ if (me->type == 2) {
+ memPtr = _vidCurPtr;
+ } else {
+ memPtr = _scriptCurPtr;
+ if (me->unpackedSize > _vidBakPtr - _scriptCurPtr) {
+ ::warning("Resource::load() not enough memory");
+ me->valid = 0;
+ continue;
+ }
+ }
+ if (me->bankNum == 0) {
+ ::warning("Resource::load() ec=0x%X (me->bankNum == 0)", 0xF00);
+ me->valid = 0;
+ } else {
+ debug(DBG_BANK, "Resource::load() bufPos=%X size=%X type=%X pos=%X bankNum=%X", memPtr - _memPtrStart, me->packedSize, me->type, me->bankPos, me->bankNum);
+ readBank(me, memPtr);
+ if(me->type == 2) {
+ _vid->copyPagePtr(_vidCurPtr);
+ me->valid = 0;
+ } else {
+ me->bufPtr = memPtr;
+ me->valid = 1;
+ _scriptCurPtr += me->unpackedSize;
+ }
+ }
+ }
+}
+
+void Resource::invalidateRes() {
+ // XXX call ds:sound_stub_1_ptr
+ MemEntry *me = _memList;
+ uint16 i = _numMemList;
+ while (i--) {
+ if (me->type <= 2 || me->type > 6) {
+ me->valid = 0;
+ }
+ ++me;
+ }
+ _scriptCurPtr = _scriptBakPtr;
+}
+
+void Resource::invalidateAll() {
+ MemEntry *me = _memList;
+ uint16 i = _numMemList;
+ while (i--) {
+ me->valid = 0;
+ ++me;
+ }
+ _scriptCurPtr = _memPtrStart;
+}
+
+void Resource::update(uint16 num) {
+ if (num == 0) {
+ invalidateRes();
+ } else {
+ if (num > _numMemList) {
+ _newPtrsId = num;
+ } else {
+ if (false) { // XXX (_audio_use_pro_or_adlib == 1 || _audio_use_spk == 1) {
+ for (const uint16 *ml = _memListAudio; *ml != 0xFFFF; ++ml) {
+ if (*ml == num)
+ return;
+ }
+ }
+ MemEntry *me = &_memList[num];
+ if (me->valid == 0) {
+ me->valid = 2;
+ load();
+ }
+ }
+ }
+}
+
+void Resource::setupPtrs(uint16 ptrId) {
+ if (ptrId != _curPtrsId) {
+ uint8 ipal = 0;
+ uint8 icod = 0;
+ uint8 ivd1 = 0;
+ uint8 ivd2 = 0;
+ if (ptrId >= 0x3E80 && ptrId <= 0x3E89) {
+ uint16 part = ptrId - 0x3E80;
+ ipal = _memListParts[part][0];
+ icod = _memListParts[part][1];
+ ivd1 = _memListParts[part][2];
+ ivd2 = _memListParts[part][3];
+ } else {
+ ::error("Resource::setupPtrs() ec=0x%X invalid ptrId", 0xF07);
+ }
+ invalidateAll();
+ _memList[ipal].valid = 2;
+ _memList[icod].valid = 2;
+ _memList[ivd1].valid = 2;
+ if (ivd2 != 0) {
+ _memList[ivd2].valid = 2;
+ }
+ load();
+ _segVideoPal = _memList[ipal].bufPtr;
+ _segCode = _memList[icod].bufPtr;
+ _segVideo1 = _memList[ivd1].bufPtr;
+ if (ivd2 != 0) {
+ _segVideo2 = _memList[ivd2].bufPtr;
+ }
+ _curPtrsId = ptrId;
+ }
+ _scriptBakPtr = _scriptCurPtr;
+}
+
+void Resource::allocMemBlock() {
+ _memPtrStart = (uint8 *)malloc(MEM_BLOCK_SIZE);
+ _scriptBakPtr = _scriptCurPtr = _memPtrStart;
+ _vidBakPtr = _vidCurPtr = _memPtrStart + MEM_BLOCK_SIZE - 0x800 * 16;
+ _useSegVideo2 = false;
+}
+
+void Resource::freeMemBlock() {
+ free(_memPtrStart);
+}
+
+void Resource::saveOrLoad(Serializer &ser) {
+ uint8 loadedList[64];
+ if (ser._mode == Serializer::SM_SAVE) {
+ memset(loadedList, 0, sizeof(loadedList));
+ uint8 *p = loadedList;
+ uint8 *q = _memPtrStart;
+ while (1) {
+ MemEntry *it = _memList;
+ MemEntry *me = 0;
+ uint16 num = _numMemList;
+ while (num--) {
+ if (it->valid == 1 && it->bufPtr == q) {
+ me = it;
+ }
+ ++it;
+ }
+ if (me == 0) {
+ break;
+ } else {
+ assert(p < loadedList + 64);
+ *p++ = me - _memList;
+ q += me->unpackedSize;
+ }
+ }
+ }
+ Serializer::Entry entries[] = {
+ SE_ARRAY(loadedList, 64, Serializer::SES_INT8, VER(1)),
+ SE_INT(&_curPtrsId, Serializer::SES_INT16, VER(1)),
+ SE_PTR(&_scriptBakPtr, VER(1)),
+ SE_PTR(&_scriptCurPtr, VER(1)),
+ SE_PTR(&_vidBakPtr, VER(1)),
+ SE_PTR(&_vidCurPtr, VER(1)),
+ SE_INT(&_useSegVideo2, Serializer::SES_INT8, VER(1)),
+ SE_PTR(&_segVideoPal, VER(1)),
+ SE_PTR(&_segCode, VER(1)),
+ SE_PTR(&_segVideo1, VER(1)),
+ SE_PTR(&_segVideo2, VER(1)),
+ SE_END()
+ };
+ ser.saveOrLoadEntries(entries);
+ if (ser._mode == Serializer::SM_LOAD) {
+ uint8 *p = loadedList;
+ uint8 *q = _memPtrStart;
+ while (*p) {
+ MemEntry *me = &_memList[*p++];
+ readBank(me, q);
+ me->bufPtr = q;
+ me->valid = 1;
+ q += me->unpackedSize;
+ }
+ }
+}
+
+}
diff --git a/awe/resource.h b/awe/resource.h
new file mode 100644
index 0000000000..3b6f60a2d6
--- /dev/null
+++ b/awe/resource.h
@@ -0,0 +1,92 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __RESOURCE_H__
+#define __RESOURCE_H__
+
+#include "stdafx.h"
+
+#include "intern.h"
+
+namespace Awe {
+
+struct MemEntry {
+ uint8 valid; // 0x0
+ uint8 type; // 0x1, Resource::ResType
+ uint8 *bufPtr; // 0x2
+ uint16 unk4; // 0x4, unused ?
+ uint8 rankNum; // 0x6
+ uint8 bankNum; // 0x7
+ uint32 bankPos; // 0x8 0xA
+ uint16 unkC; // 0xC, unused ?
+ uint16 packedSize; // 0xE
+ uint16 unk10; // 0x10, unused ?
+ uint16 unpackedSize; // 0x12
+};
+
+struct Serializer;
+struct Video;
+
+struct Resource {
+ enum ResType {
+ RT_SOUND = 0,
+ RT_MUSIC = 1,
+ RT_VIDBUF = 2, // full screen video buffer, size=0x7D00
+ RT_PAL = 3, // palette (1024=vga + 1024=ega), size=2048
+ RT_SCRIPT = 4,
+ RT_VBMP = 5
+ };
+
+ enum {
+ MEM_BLOCK_SIZE = 600 * 1024
+ };
+
+ static const uint16 _memListAudio[];
+ static const uint16 _memListParts[][4];
+
+ Video *_vid;
+ const char *_dataDir;
+ MemEntry _memList[150];
+ uint16 _numMemList;
+ uint16 _curPtrsId, _newPtrsId;
+ uint8 *_memPtrStart, *_scriptBakPtr, *_scriptCurPtr, *_vidBakPtr, *_vidCurPtr;
+ bool _useSegVideo2;
+ uint8 *_segVideoPal;
+ uint8 *_segCode;
+ uint8 *_segVideo1;
+ uint8 *_segVideo2;
+
+ Resource(Video *vid, const char *dataDir);
+
+ void readBank(const MemEntry *me, uint8 *dstBuf);
+ void readEntries();
+ void load();
+ void invalidateAll();
+ void invalidateRes();
+ void update(uint16 num);
+ void setupPtrs(uint16 ptrId);
+ void allocMemBlock();
+ void freeMemBlock();
+
+ void saveOrLoad(Serializer &ser);
+};
+
+}
+
+#endif
diff --git a/awe/sdlstub.cpp b/awe/sdlstub.cpp
new file mode 100644
index 0000000000..79e468b1a9
--- /dev/null
+++ b/awe/sdlstub.cpp
@@ -0,0 +1,324 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "stdafx.h"
+#include "common/util.h"
+
+#include <SDL.h>
+
+#include "awe.h"
+#include "systemstub.h"
+#include "util.h"
+
+namespace Awe {
+
+struct SDLStub : SystemStub {
+ typedef void (SDLStub::*ScaleProc)(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
+
+ enum {
+ SCREEN_W = 320,
+ SCREEN_H = 200
+ };
+
+ struct Scaler {
+ const char *name;
+ ScaleProc proc;
+ uint8 factor;
+ };
+
+ static const Scaler _scalers[];
+
+ uint8 *_offscreen;
+ SDL_Surface *_screen;
+ SDL_Surface *_sclscreen;
+ bool _fullscreen;
+ uint8 _scaler;
+ uint16 _pal[16];
+
+ virtual ~SDLStub() {}
+ virtual void init(const char *title);
+ virtual void destroy();
+ virtual void setPalette(uint8 s, uint8 n, const uint8 *buf);
+ virtual void copyRect(uint16 x, uint16 y, uint16 w, uint16 h, const uint8 *buf, uint32 pitch);
+ virtual void processEvents();
+ virtual void sleep(uint32 duration);
+ virtual uint32 getTimeStamp();
+
+ void prepareGfxMode();
+ void cleanupGfxMode();
+ void switchGfxMode(bool fullscreen, uint8 scaler);
+
+ void point1x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
+ void point2x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
+ void point3x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h);
+};
+
+const SDLStub::Scaler SDLStub::_scalers[] = {
+ { "Point1x", &SDLStub::point1x, 1 },
+ { "Point2x", &SDLStub::point2x, 2 },
+ { "Point3x", &SDLStub::point3x, 3 }
+};
+
+SystemStub *SystemStub_SDL_create() {
+ return new SDLStub();
+}
+
+void SDLStub::init(const char *title) {
+ SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
+ SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+ SDL_ShowCursor(SDL_DISABLE);
+ SDL_WM_SetCaption(title, NULL);
+ memset(&_pi, 0, sizeof(_pi));
+ _offscreen = (uint8 *)malloc(SCREEN_W * SCREEN_H * 2);
+ if (!_offscreen) {
+ ::error("Unable to allocate offscreen buffer");
+ }
+ _fullscreen = false;
+ _scaler = 1;
+ prepareGfxMode();
+}
+
+void SDLStub::destroy() {
+ cleanupGfxMode();
+}
+
+void SDLStub::setPalette(uint8 s, uint8 n, const uint8 *buf) {
+ assert(s + n <= 16);
+ for (int i = s; i < s + n; ++i) {
+ uint8 c[3];
+ for (int j = 0; j < 3; ++j) {
+ uint8 col = buf[i * 3 + j];
+ c[j] = (col << 2) | (col & 3);
+ }
+ _pal[i] = SDL_MapRGB(_screen->format, c[0], c[1], c[2]);
+ }
+}
+
+void SDLStub::copyRect(uint16 x, uint16 y, uint16 w, uint16 h, const uint8 *buf, uint32 pitch) {
+ buf += y * pitch + x;
+ uint16 *p = (uint16 *)_offscreen;
+ while (h--) {
+ for (int i = 0; i < w / 2; ++i) {
+ uint8 p1 = *(buf + i) >> 4;
+ uint8 p2 = *(buf + i) & 0xF;
+ *(p + i * 2 + 0) = _pal[p1];
+ *(p + i * 2 + 1) = _pal[p2];
+ }
+ p += SCREEN_W;
+ buf += pitch;
+ }
+ SDL_LockSurface(_sclscreen);
+ (this->*_scalers[_scaler].proc)((uint16 *)_sclscreen->pixels, _sclscreen->pitch, (uint16 *)_offscreen, SCREEN_W, SCREEN_W, SCREEN_H);
+ SDL_UnlockSurface(_sclscreen);
+ SDL_BlitSurface(_sclscreen, NULL, _screen, NULL);
+ SDL_UpdateRect(_screen, 0, 0, 0, 0);
+}
+
+void SDLStub::processEvents() {
+ SDL_Event ev;
+ while(SDL_PollEvent(&ev)) {
+ switch (ev.type) {
+ case SDL_QUIT:
+ exit(0);
+ break;
+ case SDL_KEYUP:
+ switch(ev.key.keysym.sym) {
+ case SDLK_LEFT:
+ _pi.dirMask &= ~PlayerInput::DIR_LEFT;
+ break;
+ case SDLK_RIGHT:
+ _pi.dirMask &= ~PlayerInput::DIR_RIGHT;
+ break;
+ case SDLK_UP:
+ _pi.dirMask &= ~PlayerInput::DIR_UP;
+ break;
+ case SDLK_DOWN:
+ _pi.dirMask &= ~PlayerInput::DIR_DOWN;
+ break;
+ case SDLK_SPACE:
+ case SDLK_RETURN:
+ _pi.button = false;
+ break;
+ default:
+ break;
+ }
+ break;
+ case SDL_KEYDOWN:
+ if (ev.key.keysym.mod & KMOD_ALT) {
+ if (ev.key.keysym.sym == SDLK_RETURN) {
+ switchGfxMode(!_fullscreen, _scaler);
+ } else if (ev.key.keysym.sym == SDLK_KP_PLUS) {
+ uint8 s = _scaler + 1;
+ if (s < ARRAYSIZE(_scalers)) {
+ switchGfxMode(_fullscreen, s);
+ }
+ } else if (ev.key.keysym.sym == SDLK_KP_MINUS) {
+ int8 s = _scaler - 1;
+ if (_scaler > 0) {
+ switchGfxMode(_fullscreen, s);
+ }
+ } else if (ev.key.keysym.sym == SDLK_x) {
+ _pi.quit = true;
+ }
+ break;
+ } else if (ev.key.keysym.mod & KMOD_CTRL) {
+ if (ev.key.keysym.sym == SDLK_s) {
+ _pi.save = true;
+ } else if (ev.key.keysym.sym == SDLK_l) {
+ _pi.load = true;
+ } else if (ev.key.keysym.sym == SDLK_f) {
+ _pi.fastMode = true;
+ } else if (ev.key.keysym.sym == SDLK_KP_PLUS) {
+ _pi.stateSlot = 1;
+ } else if (ev.key.keysym.sym == SDLK_KP_MINUS) {
+ _pi.stateSlot = -1;
+ }
+ break;
+ }
+ _pi.lastChar = ev.key.keysym.sym;
+ switch(ev.key.keysym.sym) {
+ case SDLK_LEFT:
+ _pi.dirMask |= PlayerInput::DIR_LEFT;
+ break;
+ case SDLK_RIGHT:
+ _pi.dirMask |= PlayerInput::DIR_RIGHT;
+ break;
+ case SDLK_UP:
+ _pi.dirMask |= PlayerInput::DIR_UP;
+ break;
+ case SDLK_DOWN:
+ _pi.dirMask |= PlayerInput::DIR_DOWN;
+ break;
+ case SDLK_SPACE:
+ case SDLK_RETURN:
+ _pi.button = true;
+ break;
+ case SDLK_c:
+ _pi.code = true;
+ break;
+ case SDLK_p:
+ _pi.pause = true;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void SDLStub::sleep(uint32 duration) {
+ SDL_Delay(duration);
+}
+
+uint32 SDLStub::getTimeStamp() {
+ return SDL_GetTicks();
+}
+
+void SDLStub::prepareGfxMode() {
+ int w = SCREEN_W * _scalers[_scaler].factor;
+ int h = SCREEN_H * _scalers[_scaler].factor;
+ _screen = SDL_SetVideoMode(w, h, 16, _fullscreen ? (SDL_FULLSCREEN | SDL_HWSURFACE) : SDL_HWSURFACE);
+ if (!_screen) {
+ ::error("SDLStub::prepareGfxMode() unable to allocate _screen buffer");
+ }
+ _sclscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 16,
+ _screen->format->Rmask,
+ _screen->format->Gmask,
+ _screen->format->Bmask,
+ _screen->format->Amask);
+ if (!_sclscreen) {
+ ::error("SDLStub::prepareGfxMode() unable to allocate _sclscreen buffer");
+ }
+}
+
+void SDLStub::cleanupGfxMode() {
+ if (_offscreen) {
+ free(_offscreen);
+ _offscreen = 0;
+ }
+ if (_sclscreen) {
+ SDL_FreeSurface(_sclscreen);
+ _sclscreen = 0;
+ }
+ if (_screen) {
+ SDL_FreeSurface(_screen);
+ _screen = 0;
+ }
+}
+
+void SDLStub::switchGfxMode(bool fullscreen, uint8 scaler) {
+ SDL_Surface *prev_sclscreen = _sclscreen;
+ SDL_FreeSurface(_screen);
+ _fullscreen = fullscreen;
+ _scaler = scaler;
+ prepareGfxMode();
+ SDL_BlitSurface(prev_sclscreen, NULL, _sclscreen, NULL);
+ SDL_FreeSurface(prev_sclscreen);
+}
+
+void SDLStub::point1x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h) {
+ dstPitch >>= 1;
+ while (h--) {
+ memcpy(dst, src, w * 2);
+ dst += dstPitch;
+ src += dstPitch;
+ }
+}
+
+void SDLStub::point2x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h) {
+ dstPitch >>= 1;
+ while (h--) {
+ uint16 *p = dst;
+ for (int i = 0; i < w; ++i, p += 2) {
+ uint16 c = *(src + i);
+ *(p + 0) = c;
+ *(p + 1) = c;
+ *(p + 0 + dstPitch) = c;
+ *(p + 1 + dstPitch) = c;
+ }
+ dst += dstPitch * 2;
+ src += srcPitch;
+ }
+}
+
+void SDLStub::point3x(uint16 *dst, uint16 dstPitch, const uint16 *src, uint16 srcPitch, uint16 w, uint16 h) {
+ dstPitch >>= 1;
+ while (h--) {
+ uint16 *p = dst;
+ for (int i = 0; i < w; ++i, p += 3) {
+ uint16 c = *(src + i);
+ *(p + 0) = c;
+ *(p + 1) = c;
+ *(p + 2) = c;
+ *(p + 0 + dstPitch) = c;
+ *(p + 1 + dstPitch) = c;
+ *(p + 2 + dstPitch) = c;
+ *(p + 0 + dstPitch * 2) = c;
+ *(p + 1 + dstPitch * 2) = c;
+ *(p + 2 + dstPitch * 2) = c;
+ }
+ dst += dstPitch * 3;
+ src += srcPitch;
+ }
+}
+
+}
diff --git a/awe/serializer.cpp b/awe/serializer.cpp
new file mode 100644
index 0000000000..aec79d6995
--- /dev/null
+++ b/awe/serializer.cpp
@@ -0,0 +1,127 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "stdafx.h"
+
+#include "serializer.h"
+#include "file.h"
+#include "util.h"
+
+namespace Awe {
+
+Serializer::Serializer(File *stream, Mode mode, uint8 *ptrBlock, uint16 saveVer)
+ : _stream(stream), _mode(mode), _ptrBlock(ptrBlock), _saveVer(saveVer) {
+}
+
+void Serializer::saveOrLoadEntries(Entry *entry) {
+ switch (_mode) {
+ case SM_SAVE:
+ saveEntries(entry);
+ break;
+ case SM_LOAD:
+ loadEntries(entry);
+ break;
+ }
+}
+
+void Serializer::saveEntries(Entry *entry) {
+ for (; entry->type != SET_END; ++entry) {
+ if (entry->maxVer == CUR_VER) {
+ switch (entry->type) {
+ case SET_INT:
+ saveInt(entry->size, entry->data);
+ break;
+ case SET_ARRAY:
+ if (entry->size == Serializer::SES_INT8) {
+ _stream->write(entry->data, entry->n);
+ } else {
+ uint8 *p = (uint8 *)entry->data;
+ for (int i = 0; i < entry->n; ++i) {
+ saveInt(entry->size, p);
+ p += entry->size;
+ }
+ }
+ break;
+ case SET_PTR:
+ _stream->writeUint32BE(*(uint8 **)(entry->data) - _ptrBlock);
+ break;
+ case SET_END:
+ break;
+ }
+ }
+ }
+}
+
+void Serializer::loadEntries(Entry *entry) {
+ for (; entry->type != SET_END; ++entry) {
+ if (_saveVer >= entry->minVer && _saveVer <= entry->maxVer) {
+ switch (entry->type) {
+ case SET_INT:
+ loadInt(entry->size, entry->data);
+ break;
+ case SET_ARRAY:
+ if (entry->size == Serializer::SES_INT8) {
+ _stream->read(entry->data, entry->n);
+ } else {
+ uint8 *p = (uint8 *)entry->data;
+ for (int i = 0; i < entry->n; ++i) {
+ loadInt(entry->size, p);
+ p += entry->size;
+ }
+ }
+ break;
+ case SET_PTR:
+ *(uint8 **)(entry->data) = _ptrBlock + _stream->readUint32BE();
+ break;
+ case SET_END:
+ break;
+ }
+ }
+ }
+}
+
+void Serializer::saveInt(uint8 es, void *p) {
+ switch (es) {
+ case SES_INT8:
+ _stream->writeByte(*(uint8 *)p);
+ break;
+ case SES_INT16:
+ _stream->writeUint16BE(*(uint16 *)p);
+ break;
+ case SES_INT32:
+ _stream->writeUint32BE(*(uint32 *)p);
+ break;
+ }
+}
+
+void Serializer::loadInt(uint8 es, void *p) {
+ switch (es) {
+ case SES_INT8:
+ *(uint8 *)p = _stream->readByte();
+ break;
+ case SES_INT16:
+ *(uint16 *)p = _stream->readUint16BE();
+ break;
+ case SES_INT32:
+ *(uint32 *)p = _stream->readUint32BE();
+ break;
+ }
+}
+
+}
diff --git a/awe/serializer.h b/awe/serializer.h
new file mode 100644
index 0000000000..9547c3b099
--- /dev/null
+++ b/awe/serializer.h
@@ -0,0 +1,88 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __SERIALIZER_H__
+#define __SERIALIZER_H__
+
+#include "stdafx.h"
+
+#include "intern.h"
+
+namespace Awe {
+
+#define VER(x) x
+
+#define SE_INT(i,sz,ver) { Serializer::SET_INT, sz, 1, i, ver, Serializer::CUR_VER }
+#define SE_ARRAY(a,n,sz,ver) { Serializer::SET_ARRAY, sz, n, a, ver, Serializer::CUR_VER }
+#define SE_PTR(p,ver) { Serializer::SET_PTR, 0, 0, p, ver, Serializer::CUR_VER }
+#define SE_END() { Serializer::SET_END, 0, 0, 0, 0, 0 }
+
+struct File;
+
+struct Serializer {
+ enum {
+ CUR_VER = 1
+ };
+
+ enum EntryType {
+ SET_INT,
+ SET_ARRAY,
+ SET_PTR,
+ SET_END
+ };
+
+ enum {
+ SES_INT8 = 1,
+ SES_INT16 = 2,
+ SES_INT32 = 4
+ };
+
+ enum Mode {
+ SM_SAVE,
+ SM_LOAD
+ };
+
+ struct Entry {
+ EntryType type;
+ uint8 size;
+ uint16 n;
+ void *data;
+ uint16 minVer;
+ uint16 maxVer;
+ };
+
+ File *_stream;
+ Mode _mode;
+ uint8 *_ptrBlock;
+ uint16 _saveVer;
+
+ Serializer(File *stream, Mode mode, uint8 *ptrBlock, uint16 saveVer = CUR_VER);
+
+ void saveOrLoadEntries(Entry *entry);
+
+ void saveEntries(Entry *entry);
+ void loadEntries(Entry *entry);
+
+ void saveInt(uint8 es, void *p);
+ void loadInt(uint8 es, void *p);
+};
+
+}
+
+#endif
diff --git a/awe/staticres.cpp b/awe/staticres.cpp
new file mode 100644
index 0000000000..686da2ebd6
--- /dev/null
+++ b/awe/staticres.cpp
@@ -0,0 +1,403 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "stdafx.h"
+
+#include "logic.h"
+#include "resource.h"
+#include "video.h"
+
+namespace Awe {
+
+const Logic::OpcodeStub Logic::_opTable[] = {
+ /* 0x00 */
+ &Logic::op_movConst,
+ &Logic::op_mov,
+ &Logic::op_add,
+ &Logic::op_addConst,
+ /* 0x04 */
+ &Logic::op_call,
+ &Logic::op_ret,
+ &Logic::op_break,
+ &Logic::op_jmp,
+ /* 0x08 */
+ &Logic::op_setScriptPos,
+ &Logic::op_jnz,
+ &Logic::op_condJmp,
+ &Logic::op_setPalette,
+ /* 0x0C */
+ &Logic::op_resetScript,
+ &Logic::op_selectPage,
+ &Logic::op_fillPage,
+ &Logic::op_copyPage,
+ /* 0x10 */
+ &Logic::op_updateDisplay,
+ &Logic::op_halt,
+ &Logic::op_drawString,
+ &Logic::op_sub,
+ /* 0x14 */
+ &Logic::op_and,
+ &Logic::op_or,
+ &Logic::op_shl,
+ &Logic::op_shr,
+ /* 0x18 */
+ &Logic::op_soundUnk1,
+ &Logic::op_updateMemList,
+ &Logic::op_soundUnk2
+};
+
+const uint16 Resource::_memListAudio[] = {
+ 8, 0x10, 0x61, 0x66, 0xFFFF
+};
+
+const uint16 Resource::_memListParts[][4] = {
+ { 0x14, 0x15, 0x16, 0x00 }, // protection screens
+ { 0x17, 0x18, 0x19, 0x00 }, // introduction
+ { 0x1A, 0x1B, 0x1C, 0x11 },
+ { 0x1D, 0x1E, 0x1F, 0x11 },
+ { 0x20, 0x21, 0x22, 0x11 },
+ { 0x23, 0x24, 0x25, 0x00 },
+ { 0x26, 0x27, 0x28, 0x11 },
+ { 0x29, 0x2A, 0x2B, 0x11 },
+ { 0x7D, 0x7E, 0x7F, 0x00 },
+ { 0x7D, 0x7E, 0x7F, 0x00 } // password screen
+};
+
+const uint8 Video::_font[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00,
+ 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x7E, 0x24, 0x24, 0x7E, 0x24, 0x00,
+ 0x08, 0x3E, 0x48, 0x3C, 0x12, 0x7C, 0x10, 0x00, 0x42, 0xA4, 0x48, 0x10, 0x24, 0x4A, 0x84, 0x00,
+ 0x60, 0x90, 0x90, 0x70, 0x8A, 0x84, 0x7A, 0x00, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x06, 0x08, 0x10, 0x10, 0x10, 0x08, 0x06, 0x00, 0xC0, 0x20, 0x10, 0x10, 0x10, 0x20, 0xC0, 0x00,
+ 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x20, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x10, 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
+ 0x78, 0x84, 0x8C, 0x94, 0xA4, 0xC4, 0x78, 0x00, 0x10, 0x30, 0x50, 0x10, 0x10, 0x10, 0x7C, 0x00,
+ 0x78, 0x84, 0x04, 0x08, 0x30, 0x40, 0xFC, 0x00, 0x78, 0x84, 0x04, 0x38, 0x04, 0x84, 0x78, 0x00,
+ 0x08, 0x18, 0x28, 0x48, 0xFC, 0x08, 0x08, 0x00, 0xFC, 0x80, 0xF8, 0x04, 0x04, 0x84, 0x78, 0x00,
+ 0x38, 0x40, 0x80, 0xF8, 0x84, 0x84, 0x78, 0x00, 0xFC, 0x04, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00,
+ 0x78, 0x84, 0x84, 0x78, 0x84, 0x84, 0x78, 0x00, 0x78, 0x84, 0x84, 0x7C, 0x04, 0x08, 0x70, 0x00,
+ 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x10, 0x10, 0x60,
+ 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00,
+ 0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x00, 0x7C, 0x82, 0x02, 0x0C, 0x10, 0x00, 0x10, 0x00,
+ 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x78, 0x84, 0x84, 0xFC, 0x84, 0x84, 0x84, 0x00,
+ 0xF8, 0x84, 0x84, 0xF8, 0x84, 0x84, 0xF8, 0x00, 0x78, 0x84, 0x80, 0x80, 0x80, 0x84, 0x78, 0x00,
+ 0xF8, 0x84, 0x84, 0x84, 0x84, 0x84, 0xF8, 0x00, 0x7C, 0x40, 0x40, 0x78, 0x40, 0x40, 0x7C, 0x00,
+ 0xFC, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80, 0x00, 0x7C, 0x80, 0x80, 0x8C, 0x84, 0x84, 0x7C, 0x00,
+ 0x84, 0x84, 0x84, 0xFC, 0x84, 0x84, 0x84, 0x00, 0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x00,
+ 0x04, 0x04, 0x04, 0x04, 0x84, 0x84, 0x78, 0x00, 0x8C, 0x90, 0xA0, 0xE0, 0x90, 0x88, 0x84, 0x00,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xFC, 0x00, 0x82, 0xC6, 0xAA, 0x92, 0x82, 0x82, 0x82, 0x00,
+ 0x84, 0xC4, 0xA4, 0x94, 0x8C, 0x84, 0x84, 0x00, 0x78, 0x84, 0x84, 0x84, 0x84, 0x84, 0x78, 0x00,
+ 0xF8, 0x84, 0x84, 0xF8, 0x80, 0x80, 0x80, 0x00, 0x78, 0x84, 0x84, 0x84, 0x84, 0x8C, 0x7C, 0x03,
+ 0xF8, 0x84, 0x84, 0xF8, 0x90, 0x88, 0x84, 0x00, 0x78, 0x84, 0x80, 0x78, 0x04, 0x84, 0x78, 0x00,
+ 0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x78, 0x00,
+ 0x84, 0x84, 0x84, 0x84, 0x84, 0x48, 0x30, 0x00, 0x82, 0x82, 0x82, 0x82, 0x92, 0xAA, 0xC6, 0x00,
+ 0x82, 0x44, 0x28, 0x10, 0x28, 0x44, 0x82, 0x00, 0x82, 0x44, 0x28, 0x10, 0x10, 0x10, 0x10, 0x00,
+ 0xFC, 0x04, 0x08, 0x10, 0x20, 0x40, 0xFC, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00,
+ 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00,
+ 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
+ 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00, 0x00, 0x00, 0x38, 0x04, 0x3C, 0x44, 0x3C, 0x00,
+ 0x40, 0x40, 0x78, 0x44, 0x44, 0x44, 0x78, 0x00, 0x00, 0x00, 0x3C, 0x40, 0x40, 0x40, 0x3C, 0x00,
+ 0x04, 0x04, 0x3C, 0x44, 0x44, 0x44, 0x3C, 0x00, 0x00, 0x00, 0x38, 0x44, 0x7C, 0x40, 0x3C, 0x00,
+ 0x38, 0x44, 0x40, 0x60, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3C, 0x44, 0x44, 0x3C, 0x04, 0x78,
+ 0x40, 0x40, 0x58, 0x64, 0x44, 0x44, 0x44, 0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00,
+ 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x42, 0x3C, 0x40, 0x40, 0x46, 0x48, 0x70, 0x48, 0x46, 0x00,
+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0xEC, 0x92, 0x92, 0x92, 0x92, 0x00,
+ 0x00, 0x00, 0x78, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
+ 0x00, 0x00, 0x78, 0x44, 0x44, 0x78, 0x40, 0x40, 0x00, 0x00, 0x3C, 0x44, 0x44, 0x3C, 0x04, 0x04,
+ 0x00, 0x00, 0x4C, 0x70, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x3C, 0x40, 0x38, 0x04, 0x78, 0x00,
+ 0x10, 0x10, 0x3C, 0x10, 0x10, 0x10, 0x0C, 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x78, 0x00,
+ 0x00, 0x00, 0x44, 0x44, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x82, 0x82, 0x92, 0xAA, 0xC6, 0x00,
+ 0x00, 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x42, 0x22, 0x24, 0x18, 0x08, 0x30,
+ 0x00, 0x00, 0x7C, 0x08, 0x10, 0x20, 0x7C, 0x00, 0x60, 0x90, 0x20, 0x40, 0xF0, 0x00, 0x00, 0x00,
+ 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0x00, 0x38, 0x44, 0xBA, 0xA2, 0xBA, 0x44, 0x38, 0x00,
+ 0x38, 0x44, 0x82, 0x82, 0x44, 0x28, 0xEE, 0x00, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA
+};
+
+const StrEntry Video::_stringsTableEng[] = {
+ { 0x001, "P E A N U T 3000" },
+ { 0x002, "Copyright } 1990 Peanut Computer, Inc.\nAll rights reserved.\n\nCDOS Version 5.01" },
+ { 0x003, "2" },
+ { 0x004, "3" },
+ { 0x005, "." },
+ { 0x006, "A" },
+ { 0x007, "@" },
+ { 0x008, "PEANUT 3000" },
+ { 0x00A, "R" },
+ { 0x00B, "U" },
+ { 0x00C, "N" },
+ { 0x00D, "P" },
+ { 0x00E, "R" },
+ { 0x00F, "O" },
+ { 0x010, "J" },
+ { 0x011, "E" },
+ { 0x012, "C" },
+ { 0x013, "T" },
+ { 0x014, "Shield 9A.5f Ok" },
+ { 0x015, "Flux % 5.0177 Ok" },
+ { 0x016, "CDI Vector ok" },
+ { 0x017, " %%%ddd ok" },
+ { 0x018, "Race-Track ok" },
+ { 0x019, "SYNCHROTRON" },
+ { 0x01A, "E: 23%\ng: .005\n\nRK: 77.2L\n\nopt: g+\n\n Shield:\n1: OFF\n2: ON\n3: ON\n\nP~: 1\n" },
+ { 0x01B, "ON" },
+ { 0x01C, "-" },
+ { 0x021, "|" },
+ { 0x022, "--- Theoretical study ---" },
+ { 0x023, " THE EXPERIMENT WILL BEGIN IN SECONDS" },
+ { 0x024, " 20" },
+ { 0x025, " 19" },
+ { 0x026, " 18" },
+ { 0x027, " 4" },
+ { 0x028, " 3" },
+ { 0x029, " 2" },
+ { 0x02A, " 1" },
+ { 0x02B, " 0" },
+ { 0x02C, "L E T ' S G O" },
+ { 0x031, "- Phase 0:\nINJECTION of particles\ninto synchrotron" },
+ { 0x032, "- Phase 1:\nParticle ACCELERATION." },
+ { 0x033, "- Phase 2:\nEJECTION of particles\non the shield." },
+ { 0x034, "A N A L Y S I S" },
+ { 0x035, "- RESULT:\nProbability of creating:\n ANTIMATTER: 91.V %\n NEUTRINO 27: 0.04 %\n NEUTRINO 424: 18 %\n" },
+ { 0x036, " Practical verification Y/N ?" },
+ { 0x037, "SURE ?" },
+ { 0x038, "MODIFICATION OF PARAMETERS\nRELATING TO PARTICLE\nACCELERATOR (SYNCHROTRON)." },
+ { 0x039, " RUN EXPERIMENT ?" },
+ { 0x03C, "t---t" },
+ { 0x03D, "000 ~" },
+ { 0x03E, ".20x14dd" },
+ { 0x03F, "gj5r5r" },
+ { 0x040, "tilgor 25%" },
+ { 0x041, "12% 33% checked" },
+ { 0x042, "D=4.2158005584" },
+ { 0x043, "d=10.00001" },
+ { 0x044, "+" },
+ { 0x045, "*" },
+ { 0x046, "% 304" },
+ { 0x047, "gurgle 21" },
+ { 0x048, "{{{{" },
+ { 0x049, "Delphine Software" },
+ { 0x04A, "By Eric Chahi" },
+ { 0x04B, " 5" },
+ { 0x04C, " 17" },
+ { 0x12C, "0" },
+ { 0x12D, "1" },
+ { 0x12E, "2" },
+ { 0x12F, "3" },
+ { 0x130, "4" },
+ { 0x131, "5" },
+ { 0x132, "6" },
+ { 0x133, "7" },
+ { 0x134, "8" },
+ { 0x135, "9" },
+ { 0x136, "A" },
+ { 0x137, "B" },
+ { 0x138, "C" },
+ { 0x139, "D" },
+ { 0x13A, "E" },
+ { 0x13B, "F" },
+ { 0x13C, " ACCESS CODE:" },
+ { 0x13D, "PRESS BUTTON OR RETURN TO CONTINUE" },
+ { 0x13E, " ENTER ACCESS CODE" },
+ { 0x13F, " INVALID PASSWORD !" },
+ { 0x140, "ANNULER" },
+ { 0x141, " INSERT DISK ?\n\n\n\n\n\n\n\n\nPRESS ANY KEY TO CONTINUE" },
+ { 0x142, " SELECT SYMBOLS CORRESPONDING TO\n THE POSITION\n ON THE CODE WHEEL" },
+ { 0x143, " LOADING..." },
+ { 0x144, " ERROR" },
+ { 0x15E, "LDKD" },
+ { 0x15F, "HTDC" },
+ { 0x160, "CLLD" },
+ { 0x161, "FXLC" },
+ { 0x162, "KRFK" },
+ { 0x163, "XDDJ" },
+ { 0x164, "LBKG" },
+ { 0x165, "KLFB" },
+ { 0x166, "TTCT" },
+ { 0x167, "DDRX" },
+ { 0x168, "TBHK" },
+ { 0x169, "BRTD" },
+ { 0x16A, "CKJL" },
+ { 0x16B, "LFCK" },
+ { 0x16C, "BFLX" },
+ { 0x16D, "XJRT" },
+ { 0x16E, "HRTB" },
+ { 0x16F, "HBHK" },
+ { 0x170, "JCGB" },
+ { 0x171, "HHFL" },
+ { 0x172, "TFBB" },
+ { 0x173, "TXHF" },
+ { 0x174, "JHJL" },
+ { 0x181, " BY" },
+ { 0x182, "ERIC CHAHI" },
+ { 0x183, " MUSIC AND SOUND EFFECTS" },
+ { 0x184, " " },
+ { 0x185, "JEAN-FRANCOIS FREITAS" },
+ { 0x186, "IBM PC VERSION" },
+ { 0x187, " BY" },
+ { 0x188, " DANIEL MORAIS" },
+ { 0x18B, " THEN PRESS FIRE" },
+ { 0x18C, " PUT THE PADDLE ON THE UPPER LEFT CORNER" },
+ { 0x18D, "PUT THE PADDLE IN CENTRAL POSITION" },
+ { 0x18E, "PUT THE PADDLE ON THE LOWER RIGHT CORNER" },
+ { 0x258, " Designed by ..... Eric Chahi" },
+ { 0x259, " Programmed by...... Eric Chahi" },
+ { 0x25A, " Artwork ......... Eric Chahi" },
+ { 0x25B, "Music by ........ Jean-francois Freitas" },
+ { 0x25C, " Sound effects" },
+ { 0x25D, " Jean-Francois Freitas\n Eric Chahi" },
+ { 0x263, " Thanks To" },
+ { 0x264, " Jesus Martinez\n\n Daniel Morais\n\n Frederic Savoir\n\n Cecile Chahi\n\n Philippe Delamarre\n\n Philippe Ulrich\n\nSebastien Berthet\n\nPierre Gousseau" },
+ { 0x265, "Now Go Out Of This World" },
+ { 0x190, "Good evening professor." },
+ { 0x191, "I see you have driven here in your\nFerrari." },
+ { 0x192, "IDENTIFICATION" },
+ { 0x193, "Monsieur est en parfaite sante." },
+ { 0x194, "Y\n" },
+ { 0x193, "AU BOULOT !!!\n" },
+ { 0xFFFF, "" }
+};
+
+const StrEntry Video::_stringsTableDemo[] = {
+ { 0x001, "P E A N U T 3000" },
+ { 0x002, "Copyright } 1990 Peanut Computer, Inc.\nAll rights reserved.\n\nCDOS Version 5.01" },
+ { 0x003, "2" },
+ { 0x004, "3" },
+ { 0x005, "." },
+ { 0x006, "A" },
+ { 0x007, "@" },
+ { 0x008, "PEANUT 3000" },
+ { 0x00A, "R" },
+ { 0x00B, "U" },
+ { 0x00C, "N" },
+ { 0x00D, "P" },
+ { 0x00E, "R" },
+ { 0x00F, "O" },
+ { 0x010, "J" },
+ { 0x011, "E" },
+ { 0x012, "C" },
+ { 0x013, "T" },
+ { 0x014, "Shield 9A.5f Ok" },
+ { 0x015, "Flux % 5.0177 Ok" },
+ { 0x016, "CDI Vector ok" },
+ { 0x017, " %%%ddd ok" },
+ { 0x018, "Race-Track ok" },
+ { 0x019, "SYNCHROTRON" },
+ { 0x01A, "E: 23%\ng: .005\n\nRK: 77.2L\n\nopt: g+\n\n Shield:\n1: OFF\n2: ON\n3: ON\n\nP~: 1\n" },
+ { 0x01B, "ON" },
+ { 0x01C, "-" },
+ { 0x021, "|" },
+ { 0x022, "--- Theoretical study ---" },
+ { 0x023, " THE EXPERIMENT WILL BEGIN IN SECONDS" },
+ { 0x024, " 20" },
+ { 0x025, " 19" },
+ { 0x026, " 18" },
+ { 0x027, " 4" },
+ { 0x028, " 3" },
+ { 0x029, " 2" },
+ { 0x02A, " 1" },
+ { 0x02B, " 0" },
+ { 0x02C, "L E T ' S G O" },
+ { 0x031, "- Phase 0:\nINJECTION of particles\ninto synchrotron" },
+ { 0x032, "- Phase 1:\nParticle ACCELERATION." },
+ { 0x033, "- Phase 2:\nEJECTION of particles\non the shield." },
+ { 0x034, "A N A L Y S I S" },
+ { 0x035, "- RESULT:\nProbability of creating:\n ANTIMATTER: 91.V %\n NEUTRINO 27: 0.04 %\n NEUTRINO 424: 18 %\n" },
+ { 0x036, " Practical verification Y/N ?" },
+ { 0x037, "SURE ?" },
+ { 0x038, "MODIFICATION OF PARAMETERS\nRELATING TO PARTICLE\nACCELERATOR (SYNCHROTRON)." },
+ { 0x039, " RUN EXPERIMENT ?" },
+ { 0x03C, "t---t" },
+ { 0x03D, "000 ~" },
+ { 0x03E, ".20x14dd" },
+ { 0x03F, "gj5r5r" },
+ { 0x040, "tilgor 25%" },
+ { 0x041, "12% 33% checked" },
+ { 0x042, "D=4.2158005584" },
+ { 0x043, "d=10.00001" },
+ { 0x044, "+" },
+ { 0x045, "*" },
+ { 0x046, "% 304" },
+ { 0x047, "gurgle 21" },
+ { 0x048, "{{{{" },
+ { 0x049, "Delphine Software" },
+ { 0x04A, "By Eric Chahi" },
+ { 0x04B, " 5" },
+ { 0x04C, " 17" },
+ { 0x12C, "0" },
+ { 0x12D, "1" },
+ { 0x12E, "2" },
+ { 0x12F, "3" },
+ { 0x130, "4" },
+ { 0x131, "5" },
+ { 0x132, "6" },
+ { 0x133, "7" },
+ { 0x134, "8" },
+ { 0x135, "9" },
+ { 0x136, "A" },
+ { 0x137, "B" },
+ { 0x138, "C" },
+ { 0x139, "D" },
+ { 0x13A, "E" },
+ { 0x13B, "F" },
+ { 0x13D, "PRESS BUTTON OR RETURN TO CONTINUE" },
+ { 0x13E, " ENTER ACCESS CODE" },
+ { 0x13F, " INVALID PASSWORD !" },
+ { 0x140, "ANNULER" },
+ { 0x141, " INSERT DISK ?" },
+ { 0x142, " SELECT SYMBOLS CORRESPONDING TO\n THE POSITION\n ON THE CODE WHEEL" },
+ { 0x143, " LOADING..." },
+ { 0x144, " ERROR" },
+ { 0x181, " BY" },
+ { 0x182, "ERIC CHAHI" },
+ { 0x183, " MUSIC AND SOUND EFFECTS" },
+ { 0x184, " " },
+ { 0x185, "JEAN-FRANCOIS FREITAS" },
+ { 0x186, "IBM PC VERSION" },
+ { 0x187, " BY" },
+ { 0x188, " DANIEL MORAIS" },
+ { 0x18B, " THEN PRESS FIRE" },
+ { 0x18C, " PUT THE PADDLE ON THE UPPER LEFT CORNER" },
+ { 0x18D, "PUT THE PADDLE IN CENTRAL POSITION" },
+ { 0x18E, "PUT THE PADDLE ON THE LOWER RIGHT CORNER" },
+ { 0x1F4, "Over Two Years in the Making" },
+ { 0x1F5, " A New, State\nof the Art, Polygon\n Graphics System" },
+ { 0x1F6, " Comes to the\nComputer With Full\n Screen Graphics" },
+ { 0x1F7, "While conducting a nuclear fission\nexperiment at your local\nparticle accelerator ..." },
+ { 0x1F8, "Nature decides to put a little\n extra spin on the ball" },
+ { 0x1F9, "And sends you ..." },
+ { 0x1FA, " Out of this World\nA Cinematic Action Adventure\n Coming soon to a computer\n screen near you\n from Interplay Productions\n coming soon to the IBM" },
+ { 0x258, " Designed by ..... Eric Chahi" },
+ { 0x259, " Programmed by...... Eric Chahi" },
+ { 0x25A, " Artwork ......... Eric Chahi" },
+ { 0x25B, "Music by ........ Jean-francois Freitas" },
+ { 0x25C, " Sound effects" },
+ { 0x25D, " Jean-Francois Freitas\n Eric Chahi" },
+ { 0x263, " Thanks To" },
+ { 0x264, " Jesus Martinez\n\n Daniel Morais\n\n Frederic Savoir\n\n Cecile Chahi\n\n Philippe Delamarre\n\n Philippe Ulrich\n\nSebastien Berthet\n\nPierre Gousseau" },
+ { 0x265, "Now Go Out Of This World" },
+ { 0x190, "Good evening professor." },
+ { 0x191, "I see you have driven here in your\nFerrari." },
+ { 0x192, "IDENTIFICATION" },
+ { 0x193, "Monsieur est en parfaite sante." },
+ { 0x194, "Y\n" },
+ { 0x193, "AU BOULOT !!!\n" },
+};
+
+}
diff --git a/awe/systemstub.h b/awe/systemstub.h
new file mode 100644
index 0000000000..f86c7aaa68
--- /dev/null
+++ b/awe/systemstub.h
@@ -0,0 +1,68 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __SYSTEMSTUB_H__
+#define __SYSTEMSTUB_H__
+
+#include "stdafx.h"
+
+#include "intern.h"
+
+namespace Awe {
+
+struct PlayerInput {
+ enum {
+ DIR_LEFT = 1 << 0,
+ DIR_RIGHT = 1 << 1,
+ DIR_UP = 1 << 2,
+ DIR_DOWN = 1 << 3
+ };
+
+ uint8 dirMask;
+ bool button;
+ bool code;
+ bool pause;
+ bool quit;
+ char lastChar;
+ bool save, load;
+ bool fastMode;
+ int8 stateSlot;
+};
+
+struct SystemStub {
+ PlayerInput _pi;
+
+ virtual ~SystemStub() {}
+
+ virtual void init(const char *title) = 0;
+ virtual void destroy() = 0;
+
+ virtual void setPalette(uint8 s, uint8 n, const uint8 *buf) = 0;
+ virtual void copyRect(uint16 x, uint16 y, uint16 w, uint16 h, const uint8 *buf, uint32 pitch) = 0;
+
+ virtual void processEvents() = 0;
+ virtual void sleep(uint32 duration) = 0;
+ virtual uint32 getTimeStamp() = 0;
+};
+
+extern SystemStub *SystemStub_SDL_create();
+
+}
+
+#endif
diff --git a/awe/util.cpp b/awe/util.cpp
new file mode 100644
index 0000000000..5de89f6eb2
--- /dev/null
+++ b/awe/util.cpp
@@ -0,0 +1,58 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <cstdarg>
+
+#include "stdafx.h"
+
+#include "util.h"
+
+namespace Awe {
+
+uint16 g_debugMask;
+
+void debug(uint16 cm, const char *msg, ...) {
+ char buf[1024];
+ if (cm & g_debugMask) {
+ va_list va;
+ va_start(va, msg);
+ vsprintf(buf, msg, va);
+ va_end(va);
+ printf("%s\n", buf);
+ fflush(stdout);
+ }
+}
+
+void string_lower(char *p) {
+ for (; *p; ++p) {
+ if (*p >= 'A' && *p <= 'Z') {
+ *p += 'a' - 'A';
+ }
+ }
+}
+
+void string_upper(char *p) {
+ for (; *p; ++p) {
+ if (*p >= 'a' && *p <= 'z') {
+ *p += 'A' - 'a';
+ }
+ }
+}
+
+}
diff --git a/awe/util.h b/awe/util.h
new file mode 100644
index 0000000000..64cf47603a
--- /dev/null
+++ b/awe/util.h
@@ -0,0 +1,47 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __UTIL_H__
+#define __UTIL_H__
+
+#include "stdafx.h"
+
+#include "intern.h"
+
+namespace Awe {
+
+enum {
+ DBG_LOGIC = 1 << 0,
+ DBG_BANK = 1 << 1,
+ DBG_VIDEO = 1 << 2,
+ DBG_INFO = 1 << 3
+};
+
+extern uint16 g_debugMask;
+
+extern void debug(uint16 cm, const char *msg, ...);
+extern void error(const char *msg, ...);
+extern void warning(const char *msg, ...);
+
+extern void string_lower(char *p);
+extern void string_upper(char *p);
+
+}
+
+#endif
diff --git a/awe/video.cpp b/awe/video.cpp
new file mode 100644
index 0000000000..52df154d05
--- /dev/null
+++ b/awe/video.cpp
@@ -0,0 +1,516 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "stdafx.h"
+
+#include "awe.h"
+#include "video.h"
+#include "resource.h"
+#include "serializer.h"
+#include "systemstub.h"
+
+namespace Awe {
+
+void Polygon::init(const uint8 *p, uint16 zoom) {
+ bbw = (*p++) * zoom / 64;
+ bbh = (*p++) * zoom / 64;
+ numPoints = *p++;
+ assert((numPoints & 1) == 0 && numPoints < MAX_POINTS);
+ for (int i = 0; i < numPoints; ++i) {
+ Point *pt = &points[i];
+ pt->x = (*p++) * zoom / 64;
+ pt->y = (*p++) * zoom / 64;
+ }
+}
+
+Video::Video(Resource *res, SystemStub *stub)
+ : _res(res), _stub(stub) {
+}
+
+void Video::init() {
+ _newPal = 0xFF;
+ for (int i = 0; i < 4; ++i) {
+ _pagePtrs[i] = allocPage();
+ }
+ _curPagePtr3 = getPagePtr(1);
+ _curPagePtr2 = getPagePtr(2);
+ changePagePtr1(0xFE);
+ _interpTable[0] = 0x4000;
+ for (int i = 1; i < 0x400; ++i) {
+ _interpTable[i] = 0x4000 / i;
+ }
+}
+
+void Video::setDataBuffer(uint8 *dataBuf, uint16 offset) {
+ _dataBuf = dataBuf;
+ _pData.pc = dataBuf + offset;
+}
+
+void Video::drawShape(uint8 color, uint16 zoom, const Point &pt) {
+ uint8 i = _pData.fetchByte();
+ if (i >= 0xC0) {
+ if (color & 0x80) {
+ color = i & 0x3F;
+ }
+ _pg.init(_pData.pc, zoom);
+ fillPolygon(color, zoom, pt);
+ } else {
+ i &= 0x3F;
+ if (i == 1) {
+ ::warning("Video::drawShape() ec=0x%X (i != 2)", 0xF80);
+ } else if (i == 2) {
+ drawShapeParts(zoom, pt);
+ } else {
+ ::warning("Video::drawShape() ec=0x%X (i != 2)", 0xFBB);
+ }
+ }
+}
+
+void Video::fillPolygon(uint16 color, uint16 zoom, const Point &pt) {
+ if (_pg.bbw == 0 && _pg.bbh == 1 && _pg.numPoints == 4) {
+ drawPoint(color, pt.x, pt.y);
+ return;
+ }
+
+ int16 x1 = pt.x - _pg.bbw / 2;
+ int16 x2 = pt.x + _pg.bbw / 2;
+ int16 y1 = pt.y - _pg.bbh / 2;
+ int16 y2 = pt.y + _pg.bbh / 2;
+
+ if (x1 > 319 || x2 < 0 || y1 > 199 || y2 < 0)
+ return;
+
+ _hliney = y1;
+
+ uint16 i, j;
+ i = 0;
+ j = _pg.numPoints - 1;
+
+ x2 = _pg.points[i].x + x1;
+ x1 = _pg.points[j].x + x1;
+
+ ++i;
+ --j;
+
+ drawLine pdl;
+ if (color < 0x10) {
+ pdl = &Video::drawLineN;
+ } else if (color > 0x10) {
+ pdl = &Video::drawLineP;
+ } else {
+ pdl = &Video::drawLineT;
+ }
+
+ uint32 cpt1 = x1 << 16;
+ uint32 cpt2 = x2 << 16;
+
+ while (1) {
+ _pg.numPoints -= 2;
+ if (_pg.numPoints == 0) {
+ return;
+ }
+ uint16 h;
+ int32 step1 = calcStep(_pg.points[j + 1], _pg.points[j], h);
+ int32 step2 = calcStep(_pg.points[i - 1], _pg.points[i], h);
+
+ ++i;
+ --j;
+
+ cpt1 = (cpt1 & 0xFFFF0000) | 0x7FFF;
+ cpt2 = (cpt2 & 0xFFFF0000) | 0x8000;
+
+ if (h == 0) {
+ cpt1 += step1;
+ cpt2 += step2;
+ } else {
+ for (; h != 0; --h) {
+ if (_hliney >= 0) {
+ x1 = cpt1 >> 16;
+ x2 = cpt2 >> 16;
+ if (x1 <= 319 && x2 >= 0) {
+ if (x1 < 0) x1 = 0;
+ if (x2 > 319) x2 = 319;
+ (this->*pdl)(x1, x2, color);
+ }
+ }
+ cpt1 += step1;
+ cpt2 += step2;
+ ++_hliney;
+ if (_hliney > 199) return;
+ }
+ }
+ }
+}
+
+void Video::drawShapeParts(uint16 zoom, const Point &pgc) {
+ Point pt(pgc);
+ pt.x -= _pData.fetchByte() * zoom / 64;
+ pt.y -= _pData.fetchByte() * zoom / 64;
+ int16 n = _pData.fetchByte();
+ debug(DBG_VIDEO, "Video::drawShapeParts n=%d", n);
+ for ( ; n >= 0; --n) {
+ uint16 off = _pData.fetchWord();
+ Point po(pt);
+ po.x += _pData.fetchByte() * zoom / 64;
+ po.y += _pData.fetchByte() * zoom / 64;
+ uint16 color = 0xFF;
+ uint16 _bp = off;
+ off &= 0x7FFF;
+ if (_bp & 0x8000) {
+ color = *_pData.pc & 0x7F;
+ _pData.pc += 2;
+ }
+ uint8 *bak = _pData.pc;
+ _pData.pc = _dataBuf + off * 2;
+ drawShape(color, zoom, po);
+ _pData.pc = bak;
+ }
+}
+
+int32 Video::calcStep(const Point &p1, const Point &p2, uint16 &dy) {
+ dy = p2.y - p1.y;
+ return (p2.x - p1.x) * _interpTable[dy] * 4;
+}
+
+void Video::drawString(uint8 color, uint16 x, uint16 y, uint16 strId) {
+ const StrEntry *se = _stringsTableEng;
+ while (se->id != 0xFFFF && se->id != strId) ++se;
+ debug(DBG_VIDEO, "drawString(%d, %d, %d, '%s')", color, x, y, se->str);
+ uint16 xx = x;
+ int len = strlen(se->str);
+ for (int i = 0; i < len; ++i) {
+ if (se->str[i] == '\n') {
+ y += 8;
+ x = xx;
+ } else {
+ drawChar(se->str[i], x, y, color, _curPagePtr1);
+ ++x;
+ }
+ }
+}
+
+void Video::drawChar(uint8 c, uint16 x, uint16 y, uint8 color, uint8 *buf) {
+ if (x <= 39 && y <= 192) {
+ const uint8 *ft = _font + (c - 0x20) * 8;
+ uint8 *p = buf + x * 4 + y * 160;
+ for (int j = 0; j < 8; ++j) {
+ uint8 ch = *(ft + j);
+ for (int i = 0; i < 4; ++i) {
+ uint8 b = *(p + i);
+ uint8 cmask = 0xFF;
+ uint8 colb = 0;
+ if (ch & 0x80) {
+ colb |= color << 4;
+ cmask &= 0x0F;
+ }
+ ch <<= 1;
+ if (ch & 0x80) {
+ colb |= color;
+ cmask &= 0xF0;
+ }
+ ch <<= 1;
+ *(p + i) = (b & cmask) | colb;
+ }
+ p += 160;
+ }
+ }
+}
+
+void Video::drawPoint(uint8 color, int16 x, int16 y) {
+ debug(DBG_VIDEO, "drawPoint(%d, %d, %d)", color, x, y);
+ if (x >= 0 && x <= 319 && y >= 0 && y <= 199) {
+ uint16 off = y * 160 + x / 2;
+
+ uint8 cmasko, cmaskn;
+ if (x & 1) {
+ cmaskn = 0x0F;
+ cmasko = 0xF0;
+ } else {
+ cmaskn = 0xF0;
+ cmasko = 0x0F;
+ }
+
+ uint8 colb = (color << 4) | color;
+ if (color == 0x10) {
+ cmaskn &= 0x88;
+ cmasko = ~cmaskn;
+ colb = 0x88;
+ } else if (color == 0x11) {
+ colb = *(_pagePtrs[0] + off);
+ }
+ uint8 b = *(_curPagePtr1 + off);
+ *(_curPagePtr1 + off) = (b & cmasko) | (colb & cmaskn);
+ }
+}
+
+void Video::drawLineT(int16 x1, int16 x2, uint8 color) {
+ debug(DBG_VIDEO, "drawLineT(%d, %d, %d)", x1, x2, color);
+ int16 xmax = MAX(x1, x2);
+ int16 xmin = MIN(x1, x2);
+ uint8 *p = _curPagePtr1 + _hliney * 160 + xmin / 2;
+
+ uint16 w = xmax / 2 - xmin / 2 + 1;
+ uint8 cmaske = 0;
+ uint8 cmasks = 0;
+ if (xmin & 1) {
+ --w;
+ cmasks = 0xF7;
+ }
+ if (!(xmax & 1)) {
+ --w;
+ cmaske = 0x7F;
+ }
+
+ if (cmasks != 0) {
+ *p = (*p & cmasks) | 0x08;
+ ++p;
+ }
+ while (w--) {
+ *p = (*p & 0x77) | 0x88;
+ ++p;
+ }
+ if (cmaske != 0) {
+ *p = (*p & cmaske) | 0x80;
+ ++p;
+ }
+}
+
+void Video::drawLineN(int16 x1, int16 x2, uint8 color) {
+ debug(DBG_VIDEO, "drawLineN(%d, %d, %d)", x1, x2, color);
+ int16 xmax = MAX(x1, x2);
+ int16 xmin = MIN(x1, x2);
+ uint8 *p = _curPagePtr1 + _hliney * 160 + xmin / 2;
+
+ uint16 w = xmax / 2 - xmin / 2 + 1;
+ uint8 cmaske = 0;
+ uint8 cmasks = 0;
+ if (xmin & 1) {
+ --w;
+ cmasks = 0xF0;
+ }
+ if (!(xmax & 1)) {
+ --w;
+ cmaske = 0x0F;
+ }
+
+ uint8 colb = ((color & 0xF) << 4) | (color & 0xF);
+ if (cmasks != 0) {
+ *p = (*p & cmasks) | (colb & 0x0F);
+ ++p;
+ }
+ while (w--) {
+ *p++ = colb;
+ }
+ if (cmaske != 0) {
+ *p = (*p & cmaske) | (colb & 0xF0);
+ ++p;
+ }
+}
+
+void Video::drawLineP(int16 x1, int16 x2, uint8 color) {
+ debug(DBG_VIDEO, "drawLineP(%d, %d, %d)", x1, x2, color);
+ int16 xmax = MAX(x1, x2);
+ int16 xmin = MIN(x1, x2);
+ uint16 off = _hliney * 160 + xmin / 2;
+ uint8 *p = _curPagePtr1 + off;
+ uint8 *q = _pagePtrs[0] + off;
+
+ uint8 w = xmax / 2 - xmin / 2 + 1;
+ uint8 cmaske = 0;
+ uint8 cmasks = 0;
+ if (xmin & 1) {
+ --w;
+ cmasks = 0xF0;
+ }
+ if (!(xmax & 1)) {
+ --w;
+ cmaske = 0x0F;
+ }
+
+ if (cmasks != 0) {
+ *p = (*p & cmasks) | (*q & 0x0F);
+ ++p;
+ ++q;
+ }
+ while (w--) {
+ *p++ = *q++;
+ }
+ if (cmaske != 0) {
+ *p = (*p & cmaske) | (*q & 0xF0);
+ ++p;
+ ++q;
+ }
+}
+
+uint8 *Video::getPagePtr(uint8 page) {
+ uint8 *p;
+ if (page <= 3) {
+ p = _pagePtrs[page];
+ } else {
+ switch (page) {
+ case 0xFF:
+ p = _curPagePtr3;
+ break;
+ case 0xFE:
+ p = _curPagePtr2;
+ break;
+ default:
+ p = _pagePtrs[0]; // XXX check
+ ::warning("Video::getPagePtr() p != [0,1,2,3,0xFF,0xFE] == 0x%X", page);
+ break;
+ }
+ }
+ return p;
+}
+
+void Video::changePagePtr1(uint8 page) {
+ debug(DBG_VIDEO, "Video::changePagePtr1(%d)", page);
+ _curPagePtr1 = getPagePtr(page);
+}
+
+void Video::fillPage(uint8 page, uint8 color) {
+ debug(DBG_VIDEO, "Video::fillPage(%d, %d)", page, color);
+ uint8 *p = getPagePtr(page);
+ uint8 c = (color << 4) | color;
+ memset(p, c, VID_PAGE_SIZE);
+}
+
+void Video::copyPage(uint8 src, uint8 dst, int16 vscroll) {
+ debug(DBG_VIDEO, "Video::copyPage(%d, %d)", src, dst);
+ if (src >= 0xFE || !((src &= 0xBF) & 0x80)) {
+ uint8 *p = getPagePtr(src);
+ uint8 *q = getPagePtr(dst);
+ if (p != q) {
+ memcpy(q, p, VID_PAGE_SIZE);
+ }
+ } else {
+ uint8 *p = getPagePtr(src & 3);
+ uint8 *q = getPagePtr(dst);
+ if (p != q && vscroll >= -199 && vscroll <= 199) {
+ uint16 h = 200;
+ if (vscroll < 0) {
+ h += vscroll;
+ p += -vscroll * 160;
+ } else {
+ h -= vscroll;
+ q += vscroll * 160;
+ }
+ memcpy(q, p, h * 160);
+ }
+ }
+}
+
+void Video::copyPagePtr(const uint8 *src) {
+ debug(DBG_VIDEO, "Video::copyPagePtr()");
+ uint8 *dst = _pagePtrs[0];
+ int h = 200;
+ while (h--) {
+ int w = 40;
+ while (w--) {
+ uint8 p[] = {
+ *(src + 8000 * 3),
+ *(src + 8000 * 2),
+ *(src + 8000 * 1),
+ *(src + 8000 * 0)
+ };
+ for(int j = 0; j < 4; ++j) {
+ uint8 acc = 0;
+ for (int i = 0; i < 8; ++i) {
+ acc <<= 1;
+ acc |= (p[i & 3] & 0x80) ? 1 : 0;
+ p[i & 3] <<= 1;
+ }
+ *dst++ = acc;
+ }
+ ++src;
+ }
+ }
+}
+
+uint8 *Video::allocPage() {
+ uint8 *buf = (uint8 *)malloc(VID_PAGE_SIZE);
+ memset(buf, 0, VID_PAGE_SIZE);
+ return buf;
+}
+
+void Video::changePal(uint8 palNum) {
+ if (palNum < 32) {
+ uint8 *p = _res->_segVideoPal + palNum * 32;
+ uint8 pal[16 * 3];
+ for (int i = 0; i < 16; ++i) {
+ uint8 c1 = *(p + 0);
+ uint8 c2 = *(p + 1);
+ p += 2;
+ pal[i * 3 + 0] = ((c1 & 0x0F) << 2) | ((c1 & 0x0F) >> 2); // r
+ pal[i * 3 + 1] = ((c2 & 0xF0) >> 2) | ((c2 & 0xF0) >> 6); // g
+ pal[i * 3 + 2] = ((c2 & 0x0F) >> 2) | ((c2 & 0x0F) << 2); // b
+ }
+ _stub->setPalette(0, 16, pal);
+ _curPal = palNum;
+ }
+}
+
+void Video::updateDisplay(uint8 page) {
+ debug(DBG_VIDEO, "Video::updateDisplay(%d)", page);
+ if (page != 0xFE) {
+ if (page == 0xFF) {
+ SWAP(_curPagePtr2, _curPagePtr3);
+ } else {
+ _curPagePtr2 = getPagePtr(page);
+ }
+ }
+ if (_newPal != 0xFF) {
+ changePal(_newPal);
+ _newPal = 0xFF;
+ }
+ _stub->copyRect(0, 0, 320, 200, _curPagePtr2, 160);
+}
+
+void Video::saveOrLoad(Serializer &ser) {
+ uint8 mask = 0;
+ if (ser._mode == Serializer::SM_SAVE) {
+ for (int i = 0; i < 4; ++i) {
+ if (_pagePtrs[i] == _curPagePtr1)
+ mask |= i << 4;
+ if (_pagePtrs[i] == _curPagePtr2)
+ mask |= i << 2;
+ if (_pagePtrs[i] == _curPagePtr3)
+ mask |= i << 0;
+ }
+ }
+ Serializer::Entry entries[] = {
+ SE_INT(&_curPal, Serializer::SES_INT8, VER(1)),
+ SE_INT(&_newPal, Serializer::SES_INT8, VER(1)),
+ SE_INT(&mask, Serializer::SES_INT8, VER(1)),
+ SE_ARRAY(_pagePtrs[0], Video::VID_PAGE_SIZE, Serializer::SES_INT8, VER(1)),
+ SE_ARRAY(_pagePtrs[1], Video::VID_PAGE_SIZE, Serializer::SES_INT8, VER(1)),
+ SE_ARRAY(_pagePtrs[2], Video::VID_PAGE_SIZE, Serializer::SES_INT8, VER(1)),
+ SE_ARRAY(_pagePtrs[3], Video::VID_PAGE_SIZE, Serializer::SES_INT8, VER(1)),
+ SE_END()
+ };
+ ser.saveOrLoadEntries(entries);
+ if (ser._mode == Serializer::SM_LOAD) {
+ _curPagePtr1 = _pagePtrs[(mask >> 4) & 0x3];
+ _curPagePtr2 = _pagePtrs[(mask >> 2) & 0x3];
+ _curPagePtr3 = _pagePtrs[(mask >> 0) & 0x3];
+ changePal(_curPal);
+ }
+}
+
+}
diff --git a/awe/video.h b/awe/video.h
new file mode 100644
index 0000000000..e6a5d5ea9f
--- /dev/null
+++ b/awe/video.h
@@ -0,0 +1,102 @@
+/* AWE - Another World Engine
+ * Copyright (C) 2004 Gregory Montoir
+ * Copyright (C) 2004 The ScummVM project
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __VIDEO_H__
+#define __VIDEO_H__
+
+#include "stdafx.h"
+
+#include "intern.h"
+
+namespace Awe {
+
+struct StrEntry {
+ uint16 id;
+ const char *str;
+};
+
+struct Polygon {
+ enum {
+ MAX_POINTS = 50
+ };
+
+ uint16 bbw, bbh;
+ uint8 numPoints;
+ Point points[MAX_POINTS];
+
+ void init(const uint8 *p, uint16 zoom);
+};
+
+struct Resource;
+struct Serializer;
+struct SystemStub;
+
+struct Video {
+ typedef void (Video::*drawLine)(int16 x1, int16 x2, uint8 col);
+
+ enum {
+ VID_PAGE_SIZE = 320 * 200 / 2
+ };
+
+ static const uint8 _font[];
+ static const StrEntry _stringsTableEng[];
+ static const StrEntry _stringsTableDemo[];
+
+ Resource *_res;
+ SystemStub *_stub;
+
+ uint8 _newPal, _curPal;
+ uint8 *_pagePtrs[4];
+ uint8 *_curPagePtr1, *_curPagePtr2, *_curPagePtr3;
+ Polygon _pg;
+ int16 _hliney;
+ uint16 _interpTable[0x400];
+ Ptr _pData;
+ uint8 *_dataBuf;
+
+ Video(Resource *res, SystemStub *stub);
+ void init();
+
+ void setDataBuffer(uint8 *dataBuf, uint16 offset);
+ void drawShape(uint8 color, uint16 zoom, const Point &pt);
+ void fillPolygon(uint16 color, uint16 zoom, const Point &pt);
+ void drawShapeParts(uint16 zoom, const Point &pt);
+ int32 calcStep(const Point &p1, const Point &p2, uint16 &dy);
+
+ void drawString(uint8 color, uint16 x, uint16 y, uint16 strId);
+ void drawChar(uint8 c, uint16 x, uint16 y, uint8 color, uint8 *buf);
+ void drawPoint(uint8 color, int16 x, int16 y);
+ void drawLineT(int16 x1, int16 x2, uint8 color);
+ void drawLineN(int16 x1, int16 x2, uint8 color);
+ void drawLineP(int16 x1, int16 x2, uint8 color);
+ uint8 *getPagePtr(uint8 page);
+ void changePagePtr1(uint8 page);
+ void fillPage(uint8 page, uint8 color);
+ void copyPage(uint8 src, uint8 dst, int16 vscroll);
+ void copyPagePtr(const uint8 *src);
+ uint8 *allocPage();
+ void changePal(uint8 pal);
+ void updateDisplay(uint8 page);
+
+ void saveOrLoad(Serializer &ser);
+};
+
+}
+
+#endif
diff --git a/base/plugins.cpp b/base/plugins.cpp
index c096d1813a..97c1187761 100644
--- a/base/plugins.cpp
+++ b/base/plugins.cpp
@@ -252,6 +252,10 @@ void PluginManager::loadPlugins() {
#ifndef DISABLE_SAGA
LOAD_MODULE("saga", SAGA);
#endif
+
+#ifndef DISABLE_AWE
+ LOAD_MODULE("awe", AWE);
+#endif
}
void PluginManager::unloadPlugins() {
diff --git a/base/plugins.h b/base/plugins.h
index 5c5e94559f..600a8aaa03 100644
--- a/base/plugins.h
+++ b/base/plugins.h
@@ -173,6 +173,10 @@ DECLARE_PLUGIN(KYRA)
DECLARE_PLUGIN(SAGA)
#endif
+#ifndef DISABLE_AWE
+DECLARE_PLUGIN(AWE)
+#endif
+
#endif
#endif
diff --git a/configure b/configure
index 925f983b91..13aeba48c9 100755
--- a/configure
+++ b/configure
@@ -40,6 +40,7 @@ _build_sword2=yes
_build_queen=yes
_build_kyra=no
_build_saga=no
+_build_awe=no
_need_memalign=no
_build_plugins=no
# more defaults
@@ -222,6 +223,7 @@ Optional Features:
--disable-queen don't build the Flight of the Amazon Queen engine
--enable-kyra build the Legend of Kyrandia engine
--enable-saga build the SAGA engine
+ --enable-awe build the Another World engine
--enable-plugins build engines as loadable modules instead of
static linking them
@@ -272,6 +274,7 @@ for ac_option in $@; do
--disable-queen) _build_queen=no ;;
--enable-kyra) _build_kyra=yes ;;
--enable-saga) _build_saga=yes ;;
+ --enable-awe) _build_awe=yes ;;
--enable-alsa) _alsa=yes ;;
--disable-alsa) _alsa=no ;;
--enable-vorbis) _vorbis=yes ;;
@@ -509,6 +512,11 @@ else
_mak_saga='# DISABLE_SAGA = 1'
fi
+if test "$_build_awe" = no ; then
+ _mak_awe='DISABLE_AWE = 1'
+else
+ _mak_awe='# DISABLE_AWE = 1'
+fi
if test -n "$_host"; then
# Cross-compiling mode - add your target here if needed
@@ -892,6 +900,10 @@ fi
if test "$_build_kyra" = yes ; then
echo " Legend of Kyrandia"
fi
+if test "$_build_awe" = yes ; then
+ echo " Another World"
+fi
+
echo
echo_n "Backend... "
diff --git a/dists/msvc7/awe.vcproj b/dists/msvc7/awe.vcproj
new file mode 100644
index 0000000000..cbe5df0ec2
--- /dev/null
+++ b/dists/msvc7/awe.vcproj
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding = "windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="7.00"
+ Name="awe"
+ ProjectGUID="{9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}"
+ Keyword="Win32Proj">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="awe_Debug"
+ IntermediateDirectory="awe_Debug"
+ ConfigurationType="4"
+ CharacterSet="2">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/wd4201 /wd4512 /wd4511 /wd4100 /wd4121 /wd4310 /wd4706 /wd4127 /wd4189 /wd4702"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../;../../common"
+ PreprocessorDefinitions="WIN32;_DEBUG;USE_ZLIB;USE_MAD;USE_VORBIS"
+ MinimalRebuild="TRUE"
+ ExceptionHandling="TRUE"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="TRUE"
+ EnableFunctionLevelLinking="TRUE"
+ ForceConformanceInForLoopScope="TRUE"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ WarnAsError="TRUE"
+ SuppressStartupBanner="FALSE"
+ DebugInformationFormat="4"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/awe.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="awe_Release"
+ IntermediateDirectory="awe_Release"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="FALSE">
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="/wd4201 /wd4512 /wd4511 /wd4100 /wd4121 /wd4310 /wd4706 /wd4127 /wd4189 /wd4702"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ OmitFramePointers="TRUE"
+ AdditionalIncludeDirectories="../../;../../common"
+ PreprocessorDefinitions="WIN32;NDEBUG;USE_ZLIB;USE_MAD;USE_VORBIS"
+ StringPooling="TRUE"
+ ExceptionHandling="TRUE"
+ RuntimeLibrary="0"
+ BufferSecurityCheck="FALSE"
+ EnableFunctionLevelLinking="FALSE"
+ ForceConformanceInForLoopScope="TRUE"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ WarnAsError="TRUE"
+ DebugInformationFormat="0"/>
+ <Tool
+ Name="VCCustomBuildTool"/>
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="$(OutDir)/awe.lib"/>
+ <Tool
+ Name="VCMIDLTool"/>
+ <Tool
+ Name="VCPostBuildEventTool"/>
+ <Tool
+ Name="VCPreBuildEventTool"/>
+ <Tool
+ Name="VCPreLinkEventTool"/>
+ <Tool
+ Name="VCResourceCompilerTool"/>
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"/>
+ </Configuration>
+ </Configurations>
+ <Files>
+ <File
+ RelativePath="..\..\awe\awe.cpp">
+ </File>
+ <File
+ RelativePath="..\..\awe\awe.h">
+ </File>
+ <File
+ RelativePath="..\..\awe\bank.cpp">
+ </File>
+ <File
+ RelativePath="..\..\awe\bank.h">
+ </File>
+ <File
+ RelativePath="..\..\awe\engine.cpp">
+ </File>
+ <File
+ RelativePath="..\..\awe\engine.h">
+ </File>
+ <File
+ RelativePath="..\..\awe\file.cpp">
+ </File>
+ <File
+ RelativePath="..\..\awe\file.h">
+ </File>
+ <File
+ RelativePath="..\..\awe\intern.h">
+ </File>
+ <File
+ RelativePath="..\..\awe\logic.cpp">
+ </File>
+ <File
+ RelativePath="..\..\awe\logic.h">
+ </File>
+ <File
+ RelativePath="..\..\awe\resource.cpp">
+ </File>
+ <File
+ RelativePath="..\..\awe\resource.h">
+ </File>
+ <File
+ RelativePath="..\..\awe\sdlstub.cpp">
+ </File>
+ <File
+ RelativePath="..\..\awe\serializer.cpp">
+ </File>
+ <File
+ RelativePath="..\..\awe\serializer.h">
+ </File>
+ <File
+ RelativePath="..\..\awe\staticres.cpp">
+ </File>
+ <File
+ RelativePath="..\..\awe\systemstub.h">
+ </File>
+ <File
+ RelativePath="..\..\awe\util.cpp">
+ </File>
+ <File
+ RelativePath="..\..\awe\util.h">
+ </File>
+ <File
+ RelativePath="..\..\awe\video.cpp">
+ </File>
+ <File
+ RelativePath="..\..\awe\video.h">
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/dists/msvc7/scummvm.sln b/dists/msvc7/scummvm.sln
index 1d1b89e0c6..ad0b50023e 100644
--- a/dists/msvc7/scummvm.sln
+++ b/dists/msvc7/scummvm.sln
@@ -17,20 +17,23 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kyra", "kyra.vcproj", "{9D9
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "saga", "saga.vcproj", "{676DB4C5-9A3E-4EE1-8483-EBB79DC0700E}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "awe", "awe.vcproj", "{9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}"
+EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
ConfigName.0 = Debug
ConfigName.1 = Release
EndGlobalSection
GlobalSection(ProjectDependencies) = postSolution
- {8434CB15-D08F-427D-9E6D-581AE5B28440}.0 = {C8AAE83E-198B-4ECA-A877-166827953979}
- {8434CB15-D08F-427D-9E6D-581AE5B28440}.1 = {676DB4C5-9A3E-4EE1-8483-EBB79DC0700E}
- {8434CB15-D08F-427D-9E6D-581AE5B28440}.2 = {B5527758-2F51-4CCD-AAE1-B0E28654BD6A}
- {8434CB15-D08F-427D-9E6D-581AE5B28440}.3 = {E0EC9C72-A33E-49DA-B1DC-BB44B9799BFA}
- {8434CB15-D08F-427D-9E6D-581AE5B28440}.4 = {B6AFD548-63D2-40CD-A652-E87095AFCBAF}
- {8434CB15-D08F-427D-9E6D-581AE5B28440}.5 = {6A55AF61-7CA1-49E0-9385-59C1FE9D4DB7}
- {8434CB15-D08F-427D-9E6D-581AE5B28440}.6 = {6CC3E421-779D-4E80-8100-520886A0F9FF}
- {8434CB15-D08F-427D-9E6D-581AE5B28440}.7 = {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}
+ {8434CB15-D08F-427D-9E6D-581AE5B28440}.0 = {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}
+ {8434CB15-D08F-427D-9E6D-581AE5B28440}.1 = {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}
+ {8434CB15-D08F-427D-9E6D-581AE5B28440}.2 = {C8AAE83E-198B-4ECA-A877-166827953979}
+ {8434CB15-D08F-427D-9E6D-581AE5B28440}.3 = {676DB4C5-9A3E-4EE1-8483-EBB79DC0700E}
+ {8434CB15-D08F-427D-9E6D-581AE5B28440}.4 = {B5527758-2F51-4CCD-AAE1-B0E28654BD6A}
+ {8434CB15-D08F-427D-9E6D-581AE5B28440}.5 = {E0EC9C72-A33E-49DA-B1DC-BB44B9799BFA}
+ {8434CB15-D08F-427D-9E6D-581AE5B28440}.6 = {B6AFD548-63D2-40CD-A652-E87095AFCBAF}
+ {8434CB15-D08F-427D-9E6D-581AE5B28440}.7 = {6A55AF61-7CA1-49E0-9385-59C1FE9D4DB7}
+ {8434CB15-D08F-427D-9E6D-581AE5B28440}.8 = {6CC3E421-779D-4E80-8100-520886A0F9FF}
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{8434CB15-D08F-427D-9E6D-581AE5B28440}.Debug.ActiveCfg = Debug|Win32
@@ -69,6 +72,10 @@ Global
{676DB4C5-9A3E-4EE1-8483-EBB79DC0700E}.Debug.Build.0 = Debug|Win32
{676DB4C5-9A3E-4EE1-8483-EBB79DC0700E}.Release.ActiveCfg = Release|Win32
{676DB4C5-9A3E-4EE1-8483-EBB79DC0700E}.Release.Build.0 = Release|Win32
+ {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}.Debug.ActiveCfg = Debug|Win32
+ {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}.Debug.Build.0 = Debug|Win32
+ {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}.Release.ActiveCfg = Release|Win32
+ {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
diff --git a/dists/msvc7/scummvm.vcproj b/dists/msvc7/scummvm.vcproj
index bd2964b43b..7425466ca9 100644
--- a/dists/msvc7/scummvm.vcproj
+++ b/dists/msvc7/scummvm.vcproj
@@ -39,7 +39,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib sdl.lib libz.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib sword1_debug/sword1.lib sword2_debug/sword2.lib kyra_debug/kyra.lib queen_debug/queen.lib scumm_debug/scumm.lib simon_debug/simon.lib sky_debug/sky.lib"
+ AdditionalDependencies="winmm.lib sdl.lib libz.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib awe_debug/awe.lib sword1_debug/sword1.lib sword2_debug/sword2.lib kyra_debug/kyra.lib queen_debug/queen.lib saga_debug/saga.lib scumm_debug/scumm.lib simon_debug/simon.lib sky_debug/sky.lib"
OutputFile="$(OutDir)/scummvm.exe"
LinkIncremental="2"
IgnoreDefaultLibraryNames="libcmtd.lib"
@@ -93,7 +93,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="winmm.lib sdl.lib libz.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib sword1_release/sword1.lib sword2_release/sword2.lib kyra_release/kyra.lib queen_release/queen.lib scumm_release/scumm.lib simon_release/simon.lib sky_release/sky.lib"
+ AdditionalDependencies="winmm.lib sdl.lib libz.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib awe_release/awe.lib saga_release/saga.lib sword1_release/sword1.lib sword2_release/sword2.lib kyra_release/kyra.lib queen_release/queen.lib scumm_release/scumm.lib simon_release/simon.lib sky_release/sky.lib"
OutputFile="$(OutDir)/scummvm.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"