[Scummvm-git-logs] scummvm master -> 7bfbc85cb5a3f86fd0268eeacda17016132c4a93

athrxx noreply at scummvm.org
Thu Nov 28 00:51:42 UTC 2024


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
d69a62e4e5 KYRA: (EOB) - make item table size dynamic
7bfbc85cb5 KYRA: (EOB) - prevent invalid graphics mode settings


Commit: d69a62e4e5ecd6aef18b475f75b96ce744ddd1fc
    https://github.com/scummvm/scummvm/commit/d69a62e4e5ecd6aef18b475f75b96ce744ddd1fc
Author: athrxx (athrxx at scummvm.org)
Date: 2024-11-28T01:50:42+01:00

Commit Message:
KYRA: (EOB) - make item table size dynamic

The original item table can overflow when playing long
enough. This code change prevents that....

Changed paths:
    engines/kyra/engine/chargen.cpp
    engines/kyra/engine/eobcommon.cpp
    engines/kyra/engine/eobcommon.h
    engines/kyra/engine/items_eob.cpp
    engines/kyra/engine/scene_eob.cpp
    engines/kyra/engine/sprites_eob.cpp
    engines/kyra/gui/debugger.cpp
    engines/kyra/gui/saveload.cpp
    engines/kyra/gui/saveload_eob.cpp
    engines/kyra/script/script_eob.cpp


diff --git a/engines/kyra/engine/chargen.cpp b/engines/kyra/engine/chargen.cpp
index 5adf310ddda..9d5aa8ee908 100644
--- a/engines/kyra/engine/chargen.cpp
+++ b/engines/kyra/engine/chargen.cpp
@@ -2037,7 +2037,7 @@ private:
 	Screen_EoB *_screen;
 
 	int _highlight;
-	EoBItem *_oldItems;
+	Common::Array<EoBItem> _oldItems;
 
 	const uint16 *_portraitFrames;
 	const uint8 *_convertTable;
@@ -2072,12 +2072,10 @@ TransferPartyWiz::TransferPartyWiz(EoBCoreEngine *vm, Screen_EoB *screen) : _vm(
 	_strings2 = _vm->staticres()->loadStrings(kEoB2TransferStrings2, temp);
 	_labels = _vm->staticres()->loadStrings(kEoB2TransferLabels, temp);
 	_highlight = -1;
-	_oldItems = 0;
 }
 
 TransferPartyWiz::~TransferPartyWiz() {
 	_vm->gui()->notifyUpdateSaveSlotsList();
-	delete[] _oldItems;
 }
 
 bool TransferPartyWiz::start() {
@@ -2091,8 +2089,9 @@ bool TransferPartyWiz::start() {
 
 	convertStats();
 
-	_oldItems = new EoBItem[600];
-	memcpy(_oldItems, _vm->_items, sizeof(EoBItem) * 600);
+	_oldItems.clear();
+	for (Common::Array<EoBItem>::const_iterator it = _vm->_items.begin(); it != _vm->_items.end(); ++it)
+		_oldItems.push_back(*it);
 	_vm->loadItemDefs();
 
 	int selection = selectCharactersMenu();
@@ -2485,8 +2484,7 @@ Item TransferPartyWiz::convertItem(Item eob1Item) {
 		break;
 	case 48:
 		if (itm1->value == 5) {
-			memset(itm2, 0, sizeof(EoBItem));
-			itm2->block = -1;
+			*itm2 = EoBItem();
 			return 0;
 		}
 		itm2->value = itm1->value;
@@ -2520,7 +2518,7 @@ Item TransferPartyWiz::convertItem(Item eob1Item) {
 		break;
 	}
 
-	for (int i = 1; i < 600; i++) {
+	for (uint i = 1; i < _vm->_items.size(); i++) {
 		if (i == 60 || i == 62 || i == 63 || i == 83)
 			continue;
 		EoBItem *tmp = &_vm->_items[i];
@@ -2533,7 +2531,7 @@ Item TransferPartyWiz::convertItem(Item eob1Item) {
 	}
 
 	if (!match) {
-		for (int i = 1; i < 600; i++) {
+		for (uint i = 1; i < _vm->_items.size(); i++) {
 			if (i == 60 || i == 62 || i == 63 || i == 83)
 				continue;
 			EoBItem *tmp = &_vm->_items[i];
@@ -2547,8 +2545,7 @@ Item TransferPartyWiz::convertItem(Item eob1Item) {
 	}
 
 	if (!match) {
-		memset(itm2, 0, sizeof(EoBItem));
-		itm2->block = -1;
+		*itm2 = EoBItem();
 		return 0;
 	}
 
diff --git a/engines/kyra/engine/eobcommon.cpp b/engines/kyra/engine/eobcommon.cpp
index 741563676e9..7ad6736d67e 100644
--- a/engines/kyra/engine/eobcommon.cpp
+++ b/engines/kyra/engine/eobcommon.cpp
@@ -89,7 +89,6 @@ EoBCoreEngine::EoBCoreEngine(OSystem *system, const GameFlags &flags) : KyraRpgE
 
 	_faceShapes = 0;
 	_characters = 0;
-	_items = 0;
 	_itemTypes = 0;
 	_itemNames = 0;
 	_itemNamesStatic = 0;
@@ -299,7 +298,6 @@ EoBCoreEngine::~EoBCoreEngine() {
 	}
 
 	delete[] _characters;
-	delete[] _items;
 	delete[] _itemTypes;
 
 	releaseShpArr(_itemNames, 130);
@@ -528,8 +526,6 @@ Common::Error EoBCoreEngine::init() {
 
 	_characters = new EoBCharacter[6]();
 
-	_items = new EoBItem[600]();
-
 	_itemNames = new char*[130];
 	for (int i = 0; i < 130; i++) {
 		_itemNames[i] = new char[35]();
diff --git a/engines/kyra/engine/eobcommon.h b/engines/kyra/engine/eobcommon.h
index 4a640ad0a06..1bade515075 100644
--- a/engines/kyra/engine/eobcommon.h
+++ b/engines/kyra/engine/eobcommon.h
@@ -136,6 +136,7 @@ struct EoBCharacter {
 };
 
 struct EoBItem {
+	EoBItem() : nameUnid(0), nameId(0), flags(0), icon(0), type(0), pos(0), block(-1), next(0), prev(0), level(0), value(0) {}
 	uint8 nameUnid;
 	uint8 nameId;
 	uint8 flags;
@@ -491,7 +492,7 @@ protected:
 
 	void reloadWeaponSlot(int charIndex, int slotIndex, int itemType, int arrowOrDagger);
 
-	EoBItem *_items;
+	Common::Array<EoBItem> _items;
 	uint16 _numItems;
 	EoBItemType *_itemTypes;
 	char **_itemNames;
diff --git a/engines/kyra/engine/items_eob.cpp b/engines/kyra/engine/items_eob.cpp
index 315ca857a20..7c726e2255b 100644
--- a/engines/kyra/engine/items_eob.cpp
+++ b/engines/kyra/engine/items_eob.cpp
@@ -34,50 +34,54 @@ Common::SeekableReadStreamEndian *EoBCoreEngine::getItemDefinitionFile(int index
 
 void EoBCoreEngine::loadItemDefs() {
 	Common::SeekableReadStreamEndian *s = getItemDefinitionFile(0);
-	memset(_items, 0, sizeof(EoBItem) * 600);
+	_items.clear();
 	_numItems = s->readUint16();
 
-	for (int i = 0; i < 600; i++)
-		_items[i].block = -1;
-
 	for (int i = 0; i < _numItems; i++) {
-		_items[i].nameUnid = s->readByte();
-		_items[i].nameId = s->readByte();
-		_items[i].flags = s->readByte();
-		_items[i].icon = s->readSByte();
-		_items[i].type = s->readSByte();
-		_items[i].pos = s->readSByte();
-		_items[i].block = s->readSint16();
-		_items[i].next = s->readSint16();
-		_items[i].prev = s->readSint16();
-		_items[i].level = s->readByte();
-		_items[i].value = s->readSByte();
+		EoBItem it;
+		it.nameUnid = s->readByte();
+		it.nameId = s->readByte();
+		it.flags = s->readByte();
+		it.icon = s->readSByte();
+		it.type = s->readSByte();
+		it.pos = s->readSByte();
+		it.block = s->readSint16();
+		it.next = s->readSint16();
+		it.prev = s->readSint16();
+		it.level = s->readByte();
+		it.value = s->readSByte();
+		_items.push_back(it);
 	}
 
 	if (_flags.platform == Common::kPlatformSegaCD) {
-		_items[498].block = _items[499].block = -2;
-
 		int temp = 0;
 		const uint8 *pos = _staticres->loadRawData(kEoB1MapLevelData, temp);
 
 		for (int i = _numItems; i < _numItems + temp / 14; i++) {
-			_items[i].nameUnid = *pos++;
-			_items[i].nameId = *pos++;
-			_items[i].flags = *pos++;
-			_items[i].icon = (int8)*pos++;
-			_items[i].type = (int8)*pos++;
-			_items[i].pos = (int8)*pos++;
-			_items[i].block = (int16)READ_BE_UINT16(pos);
+			EoBItem it;
+			it.nameUnid = *pos++;
+			it.nameId = *pos++;
+			it.flags = *pos++;
+			it.icon = (int8)*pos++;
+			it.type = (int8)*pos++;
+			it.pos = (int8)*pos++;
+			it.block = (int16)READ_BE_UINT16(pos);
 			pos += 2;
-			_items[i].next = (int16)READ_BE_UINT16(pos);
+			it.next = (int16)READ_BE_UINT16(pos);
 			pos += 2;
-			_items[i].prev = (int16)READ_BE_UINT16(pos);
+			it.prev = (int16)READ_BE_UINT16(pos);
 			pos += 2;
-			_items[i].level = *pos++;
-			_items[i].value = (int8)*pos++;
+			it.level = *pos++;
+			it.value = (int8)*pos++;
+			_items.push_back(it);
 		}
 		_numItems += (temp / 14);
 		_items[22].nameUnid = _items[27].nameUnid = _items[28].nameUnid = _items[29].nameUnid = _items[59].nameUnid = 96;
+
+		for (int i = _numItems; i < 500; i++)
+			_items.emplace_back(EoBItem());
+
+		_items[498].block = _items[499].block = -2;
 	}
 
 	if (_itemNamesStatic) {
@@ -139,6 +143,7 @@ void EoBCoreEngine::loadItemDefs() {
 }
 
 Kyra::Item EoBCoreEngine::duplicateItem(Item itemIndex) {
+	assert(itemIndex < (Item)_items.size());
 	EoBItem *itm = &_items[itemIndex];
 
 	if (itm->block == -1)
@@ -147,7 +152,7 @@ Kyra::Item EoBCoreEngine::duplicateItem(Item itemIndex) {
 	Item i = 1;
 	bool foundSlot = false;
 
-	for (; i < 600; i++) {
+	for (; i < (Item)_items.size(); i++) {
 		if (_items[i].block == -1) {
 			foundSlot = true;
 			break;
@@ -155,9 +160,10 @@ Kyra::Item EoBCoreEngine::duplicateItem(Item itemIndex) {
 	}
 
 	if (!foundSlot)
-		return 0;
+		_items.push_back(*itm);
+	else
+		_items[i] = *itm;
 
-	memcpy(&_items[i], itm, sizeof(EoBItem));
 	return i;
 }
 
@@ -373,7 +379,7 @@ int EoBCoreEngine::countQueuedItems(Item itemQueue, int16 id, int16 type, int co
 	int res = 0;
 
 	for (bool forceLoop = true; o1 != o2 || forceLoop; o1 = _items[o1].prev) {
-		EoBItem *itm = &_items[o1];
+		const EoBItem *itm = &_items[o1];
 		forceLoop = false;
 		if (id != -1 || type != -1) {
 			if (((id != -1) || (id == -1 && type != itm->type)) && ((type != -1) || (type == -1 && id != o1)))
diff --git a/engines/kyra/engine/scene_eob.cpp b/engines/kyra/engine/scene_eob.cpp
index ed067b5a663..be1fcc80744 100644
--- a/engines/kyra/engine/scene_eob.cpp
+++ b/engines/kyra/engine/scene_eob.cpp
@@ -314,7 +314,7 @@ void EoBCoreEngine::addLevelItems() {
 	for (int i = 0; i < 1024; i++)
 		_levelBlockProperties[i].drawObjects = 0;
 
-	for (int i = 0; i < 600; i++) {
+	for (uint i = 0; i < _items.size(); i++) {
 		if (_items[i].level != _currentLevel || _items[i].block <= 0)
 			continue;
 		setItemPosition((Item *)&_levelBlockProperties[_items[i].block & 0x3FF].drawObjects, _items[i].block, i, _items[i].pos);
diff --git a/engines/kyra/engine/sprites_eob.cpp b/engines/kyra/engine/sprites_eob.cpp
index 50538927b2a..2f8845802b6 100644
--- a/engines/kyra/engine/sprites_eob.cpp
+++ b/engines/kyra/engine/sprites_eob.cpp
@@ -350,7 +350,7 @@ void EoBCoreEngine::drawBlockItems(int index) {
 	int tile2 = 0;
 
 	for (bool loop = true; o != o2 || loop; ) {
-		EoBItem *itm = &_items[o];
+		const EoBItem *itm = &_items[o];
 		if (itm->pos == 8 || itm->pos < 4) {
 			tile2 = -1;
 
diff --git a/engines/kyra/gui/debugger.cpp b/engines/kyra/gui/debugger.cpp
index d65a6e74aee..0623da7b0ca 100644
--- a/engines/kyra/gui/debugger.cpp
+++ b/engines/kyra/gui/debugger.cpp
@@ -652,7 +652,7 @@ bool Debugger_EoB::cmdPrintMap(int, const char **) {
 
 		bool key = false;
 		for (int t = bl->drawObjects; t; ) {
-			EoBItem *itm = &_vm->_items[t];
+			const EoBItem *itm = &_vm->_items[t];
 			if (itm->type == 38)
 				key = true;
 			t = (itm->next != bl->drawObjects) ? itm->next : 0;
diff --git a/engines/kyra/gui/saveload.cpp b/engines/kyra/gui/saveload.cpp
index 06fd48cb89c..cdcdca5b32b 100644
--- a/engines/kyra/gui/saveload.cpp
+++ b/engines/kyra/gui/saveload.cpp
@@ -28,7 +28,7 @@
 #include "graphics/thumbnail.h"
 #include "graphics/surface.h"
 
-#define CURRENT_SAVE_VERSION 23
+#define CURRENT_SAVE_VERSION 24
 
 #define GF_FLOPPY  (1 <<  0)
 #define GF_TALKIE  (1 <<  1)
diff --git a/engines/kyra/gui/saveload_eob.cpp b/engines/kyra/gui/saveload_eob.cpp
index 935fd15afa3..da0020fb798 100644
--- a/engines/kyra/gui/saveload_eob.cpp
+++ b/engines/kyra/gui/saveload_eob.cpp
@@ -152,19 +152,23 @@ Common::Error EoBCoreEngine::loadGameState(int slot) {
 		_inf->loadState(in);
 	}
 
-	for (int i = 0; i < 600; i++) {
-		EoBItem *t = &_items[i];
-		t->nameUnid = in.readByte();
-		t->nameId = in.readByte();
-		t->flags = in.readByte();
-		t->icon = in.readSByte();
-		t->type = in.readSByte();
-		t->pos = in.readSByte();
-		t->block = in.readSint16BE();
-		t->next = in.readSint16BE();
-		t->prev = in.readSint16BE();
-		t->level = in.readByte();
-		t->value = in.readSByte();
+	uint32 numItems = (header.version < 24) ? 600 : in.readUint32BE();
+	_items.clear();
+
+	for (uint i = 0; i < numItems; i++) {
+		EoBItem t;
+		t.nameUnid = in.readByte();
+		t.nameId = in.readByte();
+		t.flags = in.readByte();
+		t.icon = in.readSByte();
+		t.type = in.readSByte();
+		t.pos = in.readSByte();
+		t.block = in.readSint16BE();
+		t.next = in.readSint16BE();
+		t.prev = in.readSint16BE();
+		t.level = in.readByte();
+		t.value = in.readSByte();
+		_items.push_back(t);
 	}
 
 	// No more data needed for party transfer
@@ -436,7 +440,8 @@ Common::Error EoBCoreEngine::saveGameStateIntern(int slot, const char *saveName,
 
 	_inf->saveState(out);
 
-	for (int i = 0; i < 600; i++) {
+	out->writeUint32BE(_items.size());
+	for (uint i = 0; i < _items.size(); i++) {
 		EoBItem *t = &_items[i];
 		out->writeByte(t->nameUnid);
 		out->writeByte(t->nameId);
@@ -827,20 +832,22 @@ Common::String EoBCoreEngine::readOriginalSaveFile(const Common::Path &file) {
 
 	loadItemDefs();
 
+	_items.clear();
 	int numItems = (_flags.gameID == GI_EOB1) ? 500 : 600;
 	for (int i = 0; i < numItems; i++) {
-		EoBItem *t = &_items[i];
-		t->nameUnid = in.readByte();
-		t->nameId = in.readByte();
-		t->flags = in.readByte();
-		t->icon = in.readSByte();
-		t->type = in.readSByte();
-		t->pos = in.readSByte();
-		t->block = in.readSint16();
-		t->next = in.readSint16();
-		t->prev = in.readSint16();
-		t->level = in.readByte();
-		t->value = in.readSByte();
+		EoBItem t;
+		t.nameUnid = in.readByte();
+		t.nameId = in.readByte();
+		t.flags = in.readByte();
+		t.icon = in.readSByte();
+		t.type = in.readSByte();
+		t.pos = in.readSByte();
+		t.block = in.readSint16();
+		t.next = in.readSint16();
+		t.prev = in.readSint16();
+		t.level = in.readByte();
+		t.value = in.readSByte();
+		_items.push_back(t);
 	}
 
 	int numParts = (_flags.gameID == GI_EOB1) ? 12 : 17;
@@ -1254,9 +1261,15 @@ bool EoBCoreEngine::saveAsOriginalSaveFile(int slot) {
 
 	_inf->saveState(out, true);
 
-	int numItems = (_flags.gameID == GI_EOB1) ? 500 : 600;
-	for (int i = 0; i < numItems; i++) {
-		EoBItem *t = &_items[i];
+	uint numItems = (_flags.gameID == GI_EOB1) ? 500 : 600;
+
+	if (numItems < _items.size())
+		warning("%s(): Number of items in play exceed the limit of the original game. Items will be missing in the generated save file which might break the game.", __FUNCTION__);
+
+	EoBItem dummyItem;
+
+	for (uint i = 0; i < numItems; i++) {
+		EoBItem *t = (i < _items.size()) ? &_items[i] : &dummyItem;
 		out->writeByte(t->nameUnid);
 		out->writeByte(t->nameId);
 		out->writeByte(t->flags);
diff --git a/engines/kyra/script/script_eob.cpp b/engines/kyra/script/script_eob.cpp
index 6acf1868979..df8a641cd04 100644
--- a/engines/kyra/script/script_eob.cpp
+++ b/engines/kyra/script/script_eob.cpp
@@ -455,7 +455,7 @@ int EoBInfProcessor::oeob_movePartyOrObject(int8 *data) {
 			}
 
 		} else {
-			for (int i = 0; i < 600; i++) {
+			for (uint i = 0; i < _vm->_items.size(); i++) {
 				if (_vm->_items[i].level != e || _vm->_items[i].block != c)
 					continue;
 				_vm->_items[i].level = f;
@@ -755,7 +755,7 @@ int EoBInfProcessor::oeob_eval_v1(int8 *data) {
 	int a = 0;
 	int b = 0;
 	int i = 0;
-	EoBItem *itm = &_vm->_items[_vm->_itemInHand];
+	const EoBItem *itm = &_vm->_items[_vm->_itemInHand];
 	Common::String tempString1;
 	Common::String tempString2;
 
@@ -975,7 +975,7 @@ int EoBInfProcessor::oeob_eval_v2(int8 *data) {
 	int a = 0;
 	int b = 0;
 	int i = 0;
-	EoBItem *itm = (_vm->_itemInHand != -1) ? &_vm->_items[_vm->_itemInHand] : 0;
+	const EoBItem *itm = (_vm->_itemInHand != -1) ? &_vm->_items[_vm->_itemInHand] : 0;
 	Common::String tempString1;
 	Common::String tempString2;
 


Commit: 7bfbc85cb5a3f86fd0268eeacda17016132c4a93
    https://github.com/scummvm/scummvm/commit/7bfbc85cb5a3f86fd0268eeacda17016132c4a93
Author: athrxx (athrxx at scummvm.org)
Date: 2024-11-28T01:50:50+01:00

Commit Message:
KYRA: (EOB) - prevent invalid graphics mode settings

(This could happen e. g. when selecting Amiga rendering
from the global menu)

Changed paths:
    engines/kyra/engine/eobcommon.cpp
    engines/kyra/graphics/screen.cpp


diff --git a/engines/kyra/engine/eobcommon.cpp b/engines/kyra/engine/eobcommon.cpp
index 7ad6736d67e..b2181f2db5a 100644
--- a/engines/kyra/engine/eobcommon.cpp
+++ b/engines/kyra/engine/eobcommon.cpp
@@ -393,6 +393,10 @@ Common::Error EoBCoreEngine::init() {
 	if (ConfMan.hasKey("render_mode"))
 		_configRenderMode = Common::parseRenderMode(ConfMan.get("render_mode"));
 
+	if (_flags.platform == Common::kPlatformDOS && ((_flags.gameID == GI_EOB1 && _configRenderMode != Common::kRenderVGA && _configRenderMode != Common::kRenderCGA && _configRenderMode != Common::kRenderEGA) ||
+		(_flags.gameID == GI_EOB2 && _configRenderMode != Common::kRenderVGA && _configRenderMode != Common::kRenderEGA)))
+			_configRenderMode = Common::kRenderDefault;
+
 	_enableHiResDithering = (_configRenderMode == Common::kRenderEGA && _flags.useHiRes);
 
 	_screen = new Screen_EoB(this, _system);
diff --git a/engines/kyra/graphics/screen.cpp b/engines/kyra/graphics/screen.cpp
index 0cab7c62bd2..ce69e40b88d 100644
--- a/engines/kyra/graphics/screen.cpp
+++ b/engines/kyra/graphics/screen.cpp
@@ -151,10 +151,13 @@ bool Screen::init() {
 	// to the engines. We already limit the selection via our GUIO flags in
 	// the game specific settings, but this is not enough due to global
 	// settings allowing everything.
-	if (_vm->game() == GI_EOB1 || _vm->game() == GI_EOB2) {
+	if (_vm->gameFlags().platform == Common::kPlatformDOS && (_vm->game() == GI_EOB1 || _vm->game() == GI_EOB2)) {
 		if (ConfMan.hasKey("render_mode"))
 			_renderMode = Common::parseRenderMode(ConfMan.get("render_mode"));
-	}
+		if ((_vm->game() == GI_EOB1 && _renderMode != Common::kRenderVGA && _renderMode != Common::kRenderCGA && _renderMode != Common::kRenderEGA) ||
+			(_vm->game() == GI_EOB2 && _renderMode != Common::kRenderVGA && _renderMode != Common::kRenderEGA))
+				_renderMode = Common::kRenderDefault;
+	} 
 
 	// In VGA mode the odd and even page pointers point to the same buffers.
 	for (int i = 0; i < SCREEN_PAGE_NUM; i++)




More information about the Scummvm-git-logs mailing list