diff options
Diffstat (limited to 'engines/sci/engine/seg_manager.cpp')
-rw-r--r-- | engines/sci/engine/seg_manager.cpp | 135 |
1 files changed, 74 insertions, 61 deletions
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 8090b1861d..159d3170f8 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -42,7 +42,7 @@ SegManager::SegManager(ResourceManager *resMan, ScriptPatcher *scriptPatcher) #ifdef ENABLE_SCI32 _arraysSegId = 0; - _stringSegId = 0; + _bitmapSegId = 0; #endif createClassTable(); @@ -71,7 +71,7 @@ void SegManager::resetSegMan() { #ifdef ENABLE_SCI32 _arraysSegId = 0; - _stringSegId = 0; + _bitmapSegId = 0; #endif // Reinitialize class table @@ -86,9 +86,8 @@ void SegManager::initSysStrings() { _parserPtr = make_reg(_saveDirPtr.getSegment(), _saveDirPtr.getOffset() + 256); #ifdef ENABLE_SCI32 } else { - SciString *saveDirString = allocateString(&_saveDirPtr); - saveDirString->setSize(256); - saveDirString->setValue(0, 0); + SciArray *saveDirString = allocateArray(kArrayTypeString, 256, &_saveDirPtr); + saveDirString->byteAt(0) = '\0'; _parserPtr = NULL_REG; // no SCI2 game had a parser #endif @@ -247,9 +246,9 @@ Object *SegManager::getObject(reg_t pos) const { if (mobj != NULL) { if (mobj->getType() == SEG_TYPE_CLONES) { - CloneTable *ct = (CloneTable *)mobj; - if (ct->isValidEntry(pos.getOffset())) - obj = &(ct->_table[pos.getOffset()]); + CloneTable &ct = *(CloneTable *)mobj; + if (ct.isValidEntry(pos.getOffset())) + obj = &(ct[pos.getOffset()]); else warning("getObject(): Trying to get an invalid object"); } else if (mobj->getType() == SEG_TYPE_SCRIPT) { @@ -313,7 +312,7 @@ reg_t SegManager::findObjectByName(const Common::String &name, int index) { } else if (mobj->getType() == SEG_TYPE_CLONES) { // It's clone table, scan all objects in it const CloneTable *ct = (const CloneTable *)mobj; - for (uint idx = 0; idx < ct->_table.size(); ++idx) { + for (uint idx = 0; idx < ct->size(); ++idx) { if (!ct->isValidEntry(idx)) continue; @@ -404,7 +403,7 @@ reg_t SegManager::allocateHunkEntry(const char *hunk_type, int size) { offset = table->allocEntry(); reg_t addr = make_reg(_hunksSegId, offset); - Hunk *h = &(table->_table[offset]); + Hunk *h = &table->at(offset); if (!h) return NULL_REG; @@ -424,7 +423,7 @@ byte *SegManager::getHunkPointer(reg_t addr) { return NULL; } - return (byte *)ht->_table[addr.getOffset()].mem; + return (byte *)ht->at(addr.getOffset()).mem; } Clone *SegManager::allocateClone(reg_t *addr) { @@ -439,7 +438,7 @@ Clone *SegManager::allocateClone(reg_t *addr) { offset = table->allocEntry(); *addr = make_reg(_clonesSegId, offset); - return &(table->_table[offset]); + return &table->at(offset); } List *SegManager::allocateList(reg_t *addr) { @@ -453,7 +452,7 @@ List *SegManager::allocateList(reg_t *addr) { offset = table->allocEntry(); *addr = make_reg(_listsSegId, offset); - return &(table->_table[offset]); + return &table->at(offset); } Node *SegManager::allocateNode(reg_t *addr) { @@ -467,7 +466,7 @@ Node *SegManager::allocateNode(reg_t *addr) { offset = table->allocEntry(); *addr = make_reg(_nodesSegId, offset); - return &(table->_table[offset]); + return &table->at(offset); } reg_t SegManager::newNode(reg_t value, reg_t key) { @@ -486,14 +485,14 @@ List *SegManager::lookupList(reg_t addr) { return NULL; } - ListTable *lt = (ListTable *)_heap[addr.getSegment()]; + ListTable < = *(ListTable *)_heap[addr.getSegment()]; - if (!lt->isValidEntry(addr.getOffset())) { + if (!lt.isValidEntry(addr.getOffset())) { error("Attempt to use non-list %04x:%04x as list", PRINT_REG(addr)); return NULL; } - return &(lt->_table[addr.getOffset()]); + return &(lt[addr.getOffset()]); } Node *SegManager::lookupNode(reg_t addr, bool stopOnDiscarded) { @@ -507,9 +506,9 @@ Node *SegManager::lookupNode(reg_t addr, bool stopOnDiscarded) { return NULL; } - NodeTable *nt = (NodeTable *)_heap[addr.getSegment()]; + NodeTable &nt = *(NodeTable *)_heap[addr.getSegment()]; - if (!nt->isValidEntry(addr.getOffset())) { + if (!nt.isValidEntry(addr.getOffset())) { if (!stopOnDiscarded) return NULL; @@ -517,7 +516,7 @@ Node *SegManager::lookupNode(reg_t addr, bool stopOnDiscarded) { return NULL; } - return &(nt->_table[addr.getOffset()]); + return &(nt[addr.getOffset()]); } SegmentRef SegManager::dereference(reg_t pointer) { @@ -797,7 +796,7 @@ size_t SegManager::strlen(reg_t str) { } -Common::String SegManager::getString(reg_t pointer, int entries) { +Common::String SegManager::getString(reg_t pointer) { Common::String ret; if (pointer.isNull()) return ret; // empty text @@ -807,10 +806,7 @@ Common::String SegManager::getString(reg_t pointer, int entries) { warning("SegManager::getString(): Attempt to dereference invalid pointer %04x:%04x", PRINT_REG(pointer)); return ret; } - if (entries > src_r.maxSize) { - warning("Trying to dereference pointer %04x:%04x beyond end of segment", PRINT_REG(pointer)); - return ret; - } + if (src_r.isRaw) ret = (char *)src_r.raw; else { @@ -861,7 +857,10 @@ bool SegManager::freeDynmem(reg_t addr) { } #ifdef ENABLE_SCI32 -SciArray<reg_t> *SegManager::allocateArray(reg_t *addr) { +#pragma mark - +#pragma mark Arrays + +SciArray *SegManager::allocateArray(SciArrayType type, uint16 size, reg_t *addr) { ArrayTable *table; int offset; @@ -873,78 +872,94 @@ SciArray<reg_t> *SegManager::allocateArray(reg_t *addr) { offset = table->allocEntry(); *addr = make_reg(_arraysSegId, offset); - return &(table->_table[offset]); + + SciArray *array = &table->at(offset); + array->setType(type); + array->resize(size); + return array; } -SciArray<reg_t> *SegManager::lookupArray(reg_t addr) { +SciArray *SegManager::lookupArray(reg_t addr) { if (_heap[addr.getSegment()]->getType() != SEG_TYPE_ARRAY) error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr)); - ArrayTable *arrayTable = (ArrayTable *)_heap[addr.getSegment()]; + ArrayTable &arrayTable = *(ArrayTable *)_heap[addr.getSegment()]; - if (!arrayTable->isValidEntry(addr.getOffset())) + if (!arrayTable.isValidEntry(addr.getOffset())) error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr)); - return &(arrayTable->_table[addr.getOffset()]); + return &(arrayTable[addr.getOffset()]); } void SegManager::freeArray(reg_t addr) { if (_heap[addr.getSegment()]->getType() != SEG_TYPE_ARRAY) error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr)); - ArrayTable *arrayTable = (ArrayTable *)_heap[addr.getSegment()]; + ArrayTable &arrayTable = *(ArrayTable *)_heap[addr.getSegment()]; - if (!arrayTable->isValidEntry(addr.getOffset())) + if (!arrayTable.isValidEntry(addr.getOffset())) error("Attempt to use non-array %04x:%04x as array", PRINT_REG(addr)); - arrayTable->_table[addr.getOffset()].destroy(); - arrayTable->freeEntry(addr.getOffset()); + arrayTable.freeEntry(addr.getOffset()); +} + +bool SegManager::isArray(reg_t addr) const { + return addr.getSegment() == _arraysSegId; } -SciString *SegManager::allocateString(reg_t *addr) { - StringTable *table; +#pragma mark - +#pragma mark Bitmaps + +SciBitmap *SegManager::allocateBitmap(reg_t *addr, const int16 width, const int16 height, const uint8 skipColor, const int16 originX, const int16 originY, const int16 xResolution, const int16 yResolution, const uint32 paletteSize, const bool remap, const bool gc) { + BitmapTable *table; int offset; - if (!_stringSegId) { - table = (StringTable *)allocSegment(new StringTable(), &(_stringSegId)); - } else - table = (StringTable *)_heap[_stringSegId]; + if (!_bitmapSegId) { + table = (BitmapTable *)allocSegment(new BitmapTable(), &(_bitmapSegId)); + } else { + table = (BitmapTable *)_heap[_bitmapSegId]; + } offset = table->allocEntry(); - *addr = make_reg(_stringSegId, offset); - return &(table->_table[offset]); + *addr = make_reg(_bitmapSegId, offset); + SciBitmap &bitmap = table->at(offset); + + bitmap.create(width, height, skipColor, originX, originY, xResolution, yResolution, paletteSize, remap, gc); + + return &bitmap; } -SciString *SegManager::lookupString(reg_t addr) { - if (_heap[addr.getSegment()]->getType() != SEG_TYPE_STRING) - error("lookupString: Attempt to use non-string %04x:%04x as string", PRINT_REG(addr)); +SciBitmap *SegManager::lookupBitmap(const reg_t addr) { + if (_heap[addr.getSegment()]->getType() != SEG_TYPE_BITMAP) + error("Attempt to use non-bitmap %04x:%04x as bitmap", PRINT_REG(addr)); - StringTable *stringTable = (StringTable *)_heap[addr.getSegment()]; + BitmapTable &bitmapTable = *(BitmapTable *)_heap[addr.getSegment()]; - if (!stringTable->isValidEntry(addr.getOffset())) - error("lookupString: Attempt to use non-string %04x:%04x as string", PRINT_REG(addr)); + if (!bitmapTable.isValidEntry(addr.getOffset())) + error("Attempt to use invalid entry %04x:%04x as bitmap", PRINT_REG(addr)); - return &(stringTable->_table[addr.getOffset()]); + return &(bitmapTable.at(addr.getOffset())); } -void SegManager::freeString(reg_t addr) { - if (_heap[addr.getSegment()]->getType() != SEG_TYPE_STRING) - error("freeString: Attempt to use non-string %04x:%04x as string", PRINT_REG(addr)); +void SegManager::freeBitmap(const reg_t addr) { + if (_heap[addr.getSegment()]->getType() != SEG_TYPE_BITMAP) + error("Attempt to free non-bitmap %04x:%04x as bitmap", PRINT_REG(addr)); - StringTable *stringTable = (StringTable *)_heap[addr.getSegment()]; + BitmapTable &bitmapTable = *(BitmapTable *)_heap[addr.getSegment()]; - if (!stringTable->isValidEntry(addr.getOffset())) - error("freeString: Attempt to use non-string %04x:%04x as string", PRINT_REG(addr)); + if (!bitmapTable.isValidEntry(addr.getOffset())) + error("Attempt to free invalid entry %04x:%04x as bitmap", PRINT_REG(addr)); - stringTable->_table[addr.getOffset()].destroy(); - stringTable->freeEntry(addr.getOffset()); + bitmapTable.freeEntry(addr.getOffset()); } +#pragma mark - + #endif void SegManager::createClassTable() { - Resource *vocab996 = _resMan->findResource(ResourceId(kResourceTypeVocab, 996), 1); + Resource *vocab996 = _resMan->findResource(ResourceId(kResourceTypeVocab, 996), false); if (!vocab996) error("SegManager: failed to open vocab 996"); @@ -958,8 +973,6 @@ void SegManager::createClassTable() { _classTable[classNr].reg = NULL_REG; _classTable[classNr].script = scriptNr; } - - _resMan->unlockResource(vocab996); } reg_t SegManager::getClassAddress(int classnr, ScriptLoadType lock, uint16 callerSegment) { |