aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/engine/seg_manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/engine/seg_manager.cpp')
-rw-r--r--engines/sci/engine/seg_manager.cpp135
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 &lt = *(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) {