adding initial code for Another World engine

svn-id: r13783
This commit is contained in:
Paweł Kołodziejski 2004-05-05 07:25:32 +00:00
parent 0600200980
commit e29ec6e79c
30 changed files with 3863 additions and 10 deletions

View file

@ -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 \

130
awe/awe.cpp Normal file
View file

@ -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();
}
}

57
awe/awe.h Normal file
View file

@ -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

140
awe/bank.cpp Normal file
View file

@ -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;
}
}

56
awe/bank.h Normal file
View file

@ -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

145
awe/engine.cpp Normal file
View file

@ -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);
}
}
}
}

60
awe/engine.h Normal file
View file

@ -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

190
awe/file.cpp Normal file
View file

@ -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);
}
}

53
awe/file.h Normal file
View file

@ -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

67
awe/intern.h Normal file
View file

@ -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

512
awe/logic.cpp Normal file
View file

@ -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);
}
}

114
awe/logic.h Normal file
View file

@ -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

25
awe/module.mk Normal file
View file

@ -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

277
awe/resource.cpp Normal file
View file

@ -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;
}
}
}
}

92
awe/resource.h Normal file
View file

@ -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

324
awe/sdlstub.cpp Normal file
View file

@ -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;
}
}
}

127
awe/serializer.cpp Normal file
View file

@ -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;
}
}
}

88
awe/serializer.h Normal file
View file

@ -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

403
awe/staticres.cpp Normal file
View file

@ -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" },
};
}

68
awe/systemstub.h Normal file
View file

@ -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

58
awe/util.cpp Normal file
View file

@ -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';
}
}
}
}

47
awe/util.h Normal file
View file

@ -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

516
awe/video.cpp Normal file
View file

@ -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);
}
}
}

102
awe/video.h Normal file
View file

@ -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

View file

@ -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() {

View file

@ -173,6 +173,10 @@ DECLARE_PLUGIN(KYRA)
DECLARE_PLUGIN(SAGA)
#endif
#ifndef DISABLE_AWE
DECLARE_PLUGIN(AWE)
#endif
#endif
#endif

12
configure vendored
View file

@ -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... "

169
dists/msvc7/awe.vcproj Normal file
View file

@ -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>

View file

@ -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

View file

@ -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"