diff options
author | Paweł Kołodziejski | 2004-05-05 07:25:32 +0000 |
---|---|---|
committer | Paweł Kołodziejski | 2004-05-05 07:25:32 +0000 |
commit | e29ec6e79c325bcea2c95ecbfeb3a64c80a30630 (patch) | |
tree | cc532d796c8800d693105ce7c1f9c799111f37fe /awe/resource.cpp | |
parent | 06002009806a770198c7e228f8b3e0203439b17d (diff) | |
download | scummvm-rg350-e29ec6e79c325bcea2c95ecbfeb3a64c80a30630.tar.gz scummvm-rg350-e29ec6e79c325bcea2c95ecbfeb3a64c80a30630.tar.bz2 scummvm-rg350-e29ec6e79c325bcea2c95ecbfeb3a64c80a30630.zip |
adding initial code for Another World engine
svn-id: r13783
Diffstat (limited to 'awe/resource.cpp')
-rw-r--r-- | awe/resource.cpp | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/awe/resource.cpp b/awe/resource.cpp new file mode 100644 index 0000000000..b5c621fcc6 --- /dev/null +++ b/awe/resource.cpp @@ -0,0 +1,277 @@ +/* AWE - Another World Engine + * Copyright (C) 2004 Gregory Montoir + * Copyright (C) 2004 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "stdafx.h" + +#include "awe.h" +#include "resource.h" +#include "bank.h" +#include "file.h" +#include "serializer.h" +#include "video.h" + +namespace Awe { + +Resource::Resource(Video *vid, const char *dataDir) + : _vid(vid), _dataDir(dataDir) { +} + +void Resource::readBank(const MemEntry *me, uint8 *dstBuf) { + uint16 n = me - _memList; + debug(DBG_BANK, "Resource::readBank(%d)", n); +#ifdef USE_UNPACKED + char bankEntryName[64]; + sprintf(bankEntryName, "ootw-%02X-%d.dump", n, me->type); + File f; + if (!f.open(bankEntryName, _dataDir)) { + ::error("Resource::readBank() unable to open '%s' file\n", bankEntryName); + } + f.read(dstBuf, me->unpackedSize); +#else + Bank bk(_dataDir); + if (!bk.read(me, dstBuf)) { + ::error("Resource::readBank() unable to unpack entry %d\n", n); + } +#endif +} + +void Resource::readEntries() { + File f; + if (!f.open("memlist.bin", _dataDir)) { + ::error("Resource::readEntries() unable to open 'memlist.bin' file\n"); + } + _numMemList = 0; + MemEntry *me = _memList; + while (1) { + assert(_numMemList < ARRAYSIZE(_memList)); + me->valid = f.readByte(); + me->type = f.readByte(); + me->bufPtr = 0; f.readUint16BE(); + me->unk4 = f.readUint16BE(); + me->rankNum = f.readByte(); + me->bankNum = f.readByte(); + me->bankPos = f.readUint32BE(); + me->unkC = f.readUint16BE(); + me->packedSize = f.readUint16BE(); + me->unk10 = f.readUint16BE(); + me->unpackedSize = f.readUint16BE(); + if (me->valid == 0xFF) { + break; + } + ++_numMemList; + ++me; + } +} + +void Resource::load() { + while (1) { + MemEntry *it = _memList; + MemEntry *me = 0; + + // get resource with max rankNum + uint8 maxNum = 0; + uint16 i = _numMemList; + while (i--) { + if (it->valid == 2 && maxNum <= it->rankNum) { + maxNum = it->rankNum; + me = it; + } + ++it; + } + if (me == 0) { + break; // no entry found + } + + uint8 *memPtr = 0; + // XXX if (_audio_no_sound != 0 && _audio_use_roland != 0 && me->type < 2) { + // XXX me->valid = 0; + // XXX continue; + // XXX } + if (me->type == 2) { + memPtr = _vidCurPtr; + } else { + memPtr = _scriptCurPtr; + if (me->unpackedSize > _vidBakPtr - _scriptCurPtr) { + ::warning("Resource::load() not enough memory"); + me->valid = 0; + continue; + } + } + if (me->bankNum == 0) { + ::warning("Resource::load() ec=0x%X (me->bankNum == 0)", 0xF00); + me->valid = 0; + } else { + debug(DBG_BANK, "Resource::load() bufPos=%X size=%X type=%X pos=%X bankNum=%X", memPtr - _memPtrStart, me->packedSize, me->type, me->bankPos, me->bankNum); + readBank(me, memPtr); + if(me->type == 2) { + _vid->copyPagePtr(_vidCurPtr); + me->valid = 0; + } else { + me->bufPtr = memPtr; + me->valid = 1; + _scriptCurPtr += me->unpackedSize; + } + } + } +} + +void Resource::invalidateRes() { + // XXX call ds:sound_stub_1_ptr + MemEntry *me = _memList; + uint16 i = _numMemList; + while (i--) { + if (me->type <= 2 || me->type > 6) { + me->valid = 0; + } + ++me; + } + _scriptCurPtr = _scriptBakPtr; +} + +void Resource::invalidateAll() { + MemEntry *me = _memList; + uint16 i = _numMemList; + while (i--) { + me->valid = 0; + ++me; + } + _scriptCurPtr = _memPtrStart; +} + +void Resource::update(uint16 num) { + if (num == 0) { + invalidateRes(); + } else { + if (num > _numMemList) { + _newPtrsId = num; + } else { + if (false) { // XXX (_audio_use_pro_or_adlib == 1 || _audio_use_spk == 1) { + for (const uint16 *ml = _memListAudio; *ml != 0xFFFF; ++ml) { + if (*ml == num) + return; + } + } + MemEntry *me = &_memList[num]; + if (me->valid == 0) { + me->valid = 2; + load(); + } + } + } +} + +void Resource::setupPtrs(uint16 ptrId) { + if (ptrId != _curPtrsId) { + uint8 ipal = 0; + uint8 icod = 0; + uint8 ivd1 = 0; + uint8 ivd2 = 0; + if (ptrId >= 0x3E80 && ptrId <= 0x3E89) { + uint16 part = ptrId - 0x3E80; + ipal = _memListParts[part][0]; + icod = _memListParts[part][1]; + ivd1 = _memListParts[part][2]; + ivd2 = _memListParts[part][3]; + } else { + ::error("Resource::setupPtrs() ec=0x%X invalid ptrId", 0xF07); + } + invalidateAll(); + _memList[ipal].valid = 2; + _memList[icod].valid = 2; + _memList[ivd1].valid = 2; + if (ivd2 != 0) { + _memList[ivd2].valid = 2; + } + load(); + _segVideoPal = _memList[ipal].bufPtr; + _segCode = _memList[icod].bufPtr; + _segVideo1 = _memList[ivd1].bufPtr; + if (ivd2 != 0) { + _segVideo2 = _memList[ivd2].bufPtr; + } + _curPtrsId = ptrId; + } + _scriptBakPtr = _scriptCurPtr; +} + +void Resource::allocMemBlock() { + _memPtrStart = (uint8 *)malloc(MEM_BLOCK_SIZE); + _scriptBakPtr = _scriptCurPtr = _memPtrStart; + _vidBakPtr = _vidCurPtr = _memPtrStart + MEM_BLOCK_SIZE - 0x800 * 16; + _useSegVideo2 = false; +} + +void Resource::freeMemBlock() { + free(_memPtrStart); +} + +void Resource::saveOrLoad(Serializer &ser) { + uint8 loadedList[64]; + if (ser._mode == Serializer::SM_SAVE) { + memset(loadedList, 0, sizeof(loadedList)); + uint8 *p = loadedList; + uint8 *q = _memPtrStart; + while (1) { + MemEntry *it = _memList; + MemEntry *me = 0; + uint16 num = _numMemList; + while (num--) { + if (it->valid == 1 && it->bufPtr == q) { + me = it; + } + ++it; + } + if (me == 0) { + break; + } else { + assert(p < loadedList + 64); + *p++ = me - _memList; + q += me->unpackedSize; + } + } + } + Serializer::Entry entries[] = { + SE_ARRAY(loadedList, 64, Serializer::SES_INT8, VER(1)), + SE_INT(&_curPtrsId, Serializer::SES_INT16, VER(1)), + SE_PTR(&_scriptBakPtr, VER(1)), + SE_PTR(&_scriptCurPtr, VER(1)), + SE_PTR(&_vidBakPtr, VER(1)), + SE_PTR(&_vidCurPtr, VER(1)), + SE_INT(&_useSegVideo2, Serializer::SES_INT8, VER(1)), + SE_PTR(&_segVideoPal, VER(1)), + SE_PTR(&_segCode, VER(1)), + SE_PTR(&_segVideo1, VER(1)), + SE_PTR(&_segVideo2, VER(1)), + SE_END() + }; + ser.saveOrLoadEntries(entries); + if (ser._mode == Serializer::SM_LOAD) { + uint8 *p = loadedList; + uint8 *q = _memPtrStart; + while (*p) { + MemEntry *me = &_memList[*p++]; + readBank(me, q); + me->bufPtr = q; + me->valid = 1; + q += me->unpackedSize; + } + } +} + +} |