[Scummvm-git-logs] scummvm master -> be1048d954684ec84fb0beee40f2dd7cd0f23199
a-yyg
76591232+a-yyg at users.noreply.github.com
Sat Jul 17 04:03:52 UTC 2021
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
be1048d954 SAGA2: Fix pointer arithmetic in actor/object constructors
Commit: be1048d954684ec84fb0beee40f2dd7cd0f23199
https://github.com/scummvm/scummvm/commit/be1048d954684ec84fb0beee40f2dd7cd0f23199
Author: a/ (yuri.kgpps at gmail.com)
Date: 2021-07-17T13:02:02+09:00
Commit Message:
SAGA2: Fix pointer arithmetic in actor/object constructors
Changed paths:
engines/saga2/actor.cpp
engines/saga2/enchant.cpp
engines/saga2/objects.cpp
engines/saga2/saga2.h
engines/saga2/sagafunc.cpp
diff --git a/engines/saga2/actor.cpp b/engines/saga2/actor.cpp
index 65fcc0e49e..94bce111a9 100644
--- a/engines/saga2/actor.cpp
+++ b/engines/saga2/actor.cpp
@@ -65,9 +65,6 @@ extern uint8 identityColors[256];
extern hResContext *listRes; // object list resource handle
-extern ProtoObj *objectProtos;
-extern ActorProto *actorProtos;
-
extern Actor *actorList;
extern int32 actorListSize;
@@ -972,7 +969,7 @@ void Actor::init(
debugC(1, kDebugActors, "Actor init flags: %d, permanent: %d", initFlags, initFlags & actorPermanent);
// Fixup the prototype pointer to point to an actor prototype
- prototype = (ProtoObj *)&actorProtos[protoIndex];
+ prototype = (ProtoObj *)g_vm->_actorProtos[protoIndex];
// Initialize object fields
// nameIndex = 0;
@@ -1121,7 +1118,7 @@ Actor::Actor(const ResourceActor &res) : GameObject(res) {
// Fixup the prototype pointer to point to an actor prototype
prototype = prototype != NULL
- ? (ProtoObj *)&actorProtos[prototype - objectProtos]
+ ? (ProtoObj *)g_vm->_actorProtos[getProtoNum()]
: NULL;
// Copy the resource fields
@@ -1192,7 +1189,7 @@ Actor::Actor(Common::InSaveFile *in) : GameObject(in) {
// Fixup the prototype pointer to point to an actor prototype
prototype = prototype != nullptr
- ? (ProtoObj *)&actorProtos[prototype - objectProtos]
+ ? (ProtoObj *)g_vm->_actorProtos[getProtoNum()]
: nullptr;
faction = in->readByte();
@@ -1335,11 +1332,10 @@ void Actor::write(Common::MemoryWriteStreamDynamic *out) {
debugC(3, kDebugSaveload, "Saving actor %d", thisID());
- warning("STUB: Actor::write: Pointer arithmetic");
// Modify the protoype temporarily so the GameObject::write()
// will store the index correctly
if (prototype != NULL)
- prototype = &objectProtos[(ActorProto *)prototype - actorProtos];
+ prototype = g_vm->_objectProtos[getProtoNum()];
GameObject::write(out, false);
@@ -1503,7 +1499,7 @@ Actor *Actor::newActor(
void Actor::deleteActor(void) {
if (flags & temporary) {
- uint16 protoNum = (ActorProto *)prototype - actorProtos;
+ uint16 protoNum = getProtoNum();
decTempActorCount(protoNum);
debugC(1, kDebugActors, "Actors: Deleting temp actor %d (%s) new count:%d", thisID() - 32768, objName(), getTempActorCount(protoNum));
diff --git a/engines/saga2/enchant.cpp b/engines/saga2/enchant.cpp
index e3d953353a..1bcf62539d 100644
--- a/engines/saga2/enchant.cpp
+++ b/engines/saga2/enchant.cpp
@@ -33,7 +33,6 @@
namespace Saga2 {
-extern ProtoObj *objectProtos; // object prototypes
extern int16 objectProtoCount; // object prototype count
int enchantmentProto = -1;
@@ -55,7 +54,7 @@ ObjectID EnchantObject(
assert(enchantmentProto >= 0);
assert(enchantmentProto < objectProtoCount);
- enchProto = &objectProtos[enchantmentProto];
+ enchProto = g_vm->_objectProtos[enchantmentProto];
ench = GameObject::newObject(); //Create Enchantment
if (ench == NULL) return Nothing;
diff --git a/engines/saga2/objects.cpp b/engines/saga2/objects.cpp
index 384f1d71bd..7e3764aab5 100644
--- a/engines/saga2/objects.cpp
+++ b/engines/saga2/objects.cpp
@@ -65,8 +65,6 @@ const uint32 nameListID = MKTAG('N', 'A', 'M', 'E'),
uint32 nameListCount;
-ProtoObj *objectProtos = nullptr; // object prototypes
-ActorProto *actorProtos = nullptr; // actor prototypes
uint16 *tempActorCount = nullptr; // array of temporary actor counts
int16 objectProtoCount, // object prototype count
@@ -209,7 +207,7 @@ GameObject::GameObject(void) {
// Constructor -- initial object construction
GameObject::GameObject(const ResourceGameObject &res) {
- prototype = &objectProtos[res.protoIndex];
+ prototype = g_vm->_objectProtos[res.protoIndex];
_data.projectDummy = 0;
_data.location = res.location;
_data.nameIndex = res.nameIndex;
@@ -243,7 +241,7 @@ void GameObject::read(Common::InSaveFile *in, bool expandProto) {
in->readSint16LE();
// Convert the protoype index into an object proto pointer
prototype = pInd != -1
- ? &objectProtos[pInd]
+ ? g_vm->_objectProtos[pInd]
: nullptr;
_data.projectDummy = 0;
@@ -292,8 +290,7 @@ int32 GameObject::archiveSize(void) {
void GameObject::write(Common::MemoryWriteStreamDynamic *out, bool expandProto) {
debugC(2, kDebugSaveload, "Saving object %d", thisID());
- warning("STUB: GameObject::write: Pointer arithmetic");
- int16 pInd = prototype != nullptr ? prototype - objectProtos : -1;
+ int16 pInd = prototype != nullptr ? getProtoNum() : -1;
out->writeSint16LE(pInd);
if (expandProto)
out->writeSint16LE(0);
@@ -2146,9 +2143,17 @@ bool GameObject::canSenseObjectProperty(
// Given an object, returns the prototype number
int32 GameObject::getProtoNum(void) {
- if (isActor(this))
- return (ActorProto *)prototype - actorProtos;
- else return prototype - objectProtos;
+ for (uint i = 0; i < g_vm->_actorProtos.size(); ++i) {
+ if (prototype == g_vm->_actorProtos[i])
+ return i;
+ }
+
+ for (uint i = 0; i < g_vm->_objectProtos.size(); ++i) {
+ if (prototype == g_vm->_objectProtos[i])
+ return i;
+ }
+
+ return -1;
}
//-------------------------------------------------------------------
@@ -2156,12 +2161,12 @@ int32 GameObject::getProtoNum(void) {
void GameObject::setProtoNum(int32 nProto) {
if (isActor(this))
- prototype = &actorProtos[nProto];
+ prototype = g_vm->_actorProtos[nProto];
else {
ObjectID oldParentID = _data.parentID;
bool wasStacked = unstack(); // Unstack if it was in a stack
- prototype = &objectProtos[nProto];
+ prototype = g_vm->_objectProtos[nProto];
if (wasStacked) {
ObjectID pos = possessor();
@@ -2466,8 +2471,6 @@ void initPrototypes(void) {
if (objectProtoCount < 1)
error("Unable to load Object Prototypes");
- objectProtos = (ProtoObj *)malloc(objectProtoCount * sizeof (ProtoObj));
-
if ((stream = loadResourceToStream(listRes, objProtoID, "object prototypes")) == nullptr)
error("Unable to load Object Prototypes");
@@ -2476,131 +2479,133 @@ void initPrototypes(void) {
for (int i = 0; i < objectProtoCount; i++) {
ResourceObjectPrototype ro;
- ProtoObj *pr = &objectProtos[i];
+ ProtoObj *pr;
ro.load(stream);
switch (ro.classType) {
case protoClassInventory:
- new (pr) InventoryProto(ro);
+ pr = new InventoryProto(ro);
break;
case protoClassPhysContainer:
- new (pr) PhysicalContainerProto(ro);
+ pr = new PhysicalContainerProto(ro);
break;
case protoClassKey:
- new (pr) KeyProto(ro);
+ pr = new KeyProto(ro);
break;
case protoClassBottle:
- new (pr) BottleProto(ro);
+ pr = new BottleProto(ro);
break;
case protoClassFood: // Food ProtoType
- new (pr) FoodProto(ro);
+ pr = new FoodProto(ro);
break;
case protoClassBludgeoningWeapon:
- new (pr) BludgeoningWeaponProto(ro);
+ pr = new BludgeoningWeaponProto(ro);
break;
case protoClassSlashingWeapon:
- new (pr) SlashingWeaponProto(ro);
+ pr = new SlashingWeaponProto(ro);
break;
case protoClassBow:
- new (pr) BowProto(ro);
+ pr = new BowProto(ro);
break;
case protoClassWeaponWand:
- new (pr) WeaponWandProto(ro);
+ pr = new WeaponWandProto(ro);
break;
case protoClassArrow:
- new (pr) ArrowProto(ro);
+ pr = new ArrowProto(ro);
break;
case protoClassShield:
- new (pr) ShieldProto(ro);
+ pr = new ShieldProto(ro);
break;
case protoClassArmor:
- new (pr) ArmorProto(ro);
+ pr = new ArmorProto(ro);
break;
case protoClassTool:
- new (pr) ToolProto(ro);
+ pr = new ToolProto(ro);
break;
case protoClassBookDoc:
- new (pr) BookProto(ro);
+ pr = new BookProto(ro);
break;
case protoClassScrollDoc:
- new (pr) ScrollProto(ro);
+ pr = new ScrollProto(ro);
break;
case protoClassMap:
- new (pr) AutoMapProto(ro);
+ pr = new AutoMapProto(ro);
break;
case protoClassIdea:
- new (pr) IdeaProto(ro);
+ pr = new IdeaProto(ro);
break;
case protoClassMemory:
- new (pr) MemoryProto(ro);
+ pr = new MemoryProto(ro);
break;
case protoClassPsych:
- new (pr) PsychProto(ro);
+ pr = new PsychProto(ro);
break;
case protoClassSkill:
- new (pr) SkillProto(ro);
+ pr = new SkillProto(ro);
initializeSkill((SkillProto *) pr, ((SkillProto *) pr)->getSpellID());
//initializeSkill(i,((SkillProto *) pr)->getSpellID());
break;
case protoClassIdeaContainer:
- new (pr) IdeaContainerProto(ro);
+ pr = new IdeaContainerProto(ro);
break;
case protoClassMemoryContainer:
- new (pr) MemoryContainerProto(ro);
+ pr = new MemoryContainerProto(ro);
break;
case protoClassPsychContainer:
- new (pr) PsychContainerProto(ro);
+ pr = new PsychContainerProto(ro);
break;
case protoClassSkillContainer:
- new (pr) SkillContainerProto(ro);
+ pr = new SkillContainerProto(ro);
break;
case protoClassEnchantment:
- new (pr) EnchantmentProto(ro);
+ pr = new EnchantmentProto(ro);
enchantmentProto = i;
break;
case protoClassMonsterGenerator:
- new (pr) MonsterGeneratorProto(ro);
+ pr = new MonsterGeneratorProto(ro);
break;
// REM: add this in when we change the database.
case protoClassEncounterGenerator:
- new (pr) EncounterGeneratorProto(ro);
+ pr = new EncounterGeneratorProto(ro);
break;
case protoClassMissionGenerator:
- new (pr) MissionGeneratorProto(ro);
+ pr = new MissionGeneratorProto(ro);
break;
default:
// Unrecognized prototypes now default to
// an inventory item.
- new (pr) InventoryProto(ro);
+ pr = new InventoryProto(ro);
break;
}
+
+ g_vm->_objectProtos.push_back(pr);
}
listRes->rest();
@@ -2614,18 +2619,15 @@ void initPrototypes(void) {
if (actorProtoCount < 1)
error("Unable to load Actor Prototypes");
- actorProtos = (ActorProto *)malloc(actorProtoCount * sizeof(ActorProto));
-
if ((stream = loadResourceToStream(listRes, actorProtoID, "actor prototypes")) == nullptr)
error("Unable to load Actor Prototypes");
for (int i = 0; i < actorProtoCount; i++) {
ResourceActorPrototype ra;
- ActorProto *pr = &actorProtos[i];
-
ra.load(stream);
- new (pr) ActorProto(ra);
+ ActorProto *pr = new ActorProto(ra);
+ g_vm->_actorProtos.push_back(pr);
}
listRes->rest();
@@ -2643,15 +2645,19 @@ void cleanupPrototypes(void) {
g_vm->_nameList.clear();
}
- if (actorProtos != nullptr) {
- free(actorProtos);
- actorProtos = nullptr;
+ for (uint i = 0; i < g_vm->_actorProtos.size(); ++i) {
+ if (g_vm->_actorProtos[i])
+ delete g_vm->_actorProtos[i];
}
- if (objectProtos != nullptr) {
- free(objectProtos);
- objectProtos = nullptr;
+ g_vm->_actorProtos.clear();
+
+ for (uint i = 0; i < g_vm->_objectProtos.size(); ++i) {
+ if (g_vm->_objectProtos[i])
+ delete g_vm->_objectProtos[i];
}
+
+ g_vm->_objectProtos.clear();
}
//-------------------------------------------------------------------
diff --git a/engines/saga2/saga2.h b/engines/saga2/saga2.h
index 4132f6b5d1..fe31a57c4d 100644
--- a/engines/saga2/saga2.h
+++ b/engines/saga2/saga2.h
@@ -66,6 +66,8 @@ class ActiveRegion;
class gToolBase;
class Properties;
class PlayerActor;
+class ProtoObj;
+class ActorProto;
enum {
kDebugResources = 1 << 0,
@@ -124,6 +126,8 @@ public:
weaponID _loadedWeapons;
Common::Array<char *> _nameList;
Common::Array<PlayerActor *> _playerList;
+ Common::Array<ProtoObj *> _objectProtos;
+ Common::Array<ActorProto *> _actorProtos;
Common::List<TimerList *> _timerLists;
Common::List<Timer *> _timers;
Common::List<ActorAppearance *> _appearanceLRU;
diff --git a/engines/saga2/sagafunc.cpp b/engines/saga2/sagafunc.cpp
index 6712b710f7..ba5e1d6778 100644
--- a/engines/saga2/sagafunc.cpp
+++ b/engines/saga2/sagafunc.cpp
@@ -2061,8 +2061,7 @@ int16 scriptActorDeductPayment(int16 *args) {
OBJLOG(DeductPayment);
Actor *a = (Actor *)thisThread->thisObject;
- extern ProtoObj *objectProtos;
- ProtoObj *currencyProto = &objectProtos[args[0]];
+ ProtoObj *currencyProto = g_vm->_objectProtos[args[0]];
int32 paymentAmount = args[1];
int32 paymentFound = 0;
GameObject *obj, *delObj = NULL;
@@ -2140,8 +2139,7 @@ int16 scriptActorCountPayment(int16 *args) {
OBJLOG(CountPayment);
Actor *a = (Actor *)thisThread->thisObject;
- extern ProtoObj *objectProtos;
- ProtoObj *currencyProto = &objectProtos[args[0]];
+ ProtoObj *currencyProto = g_vm->_objectProtos[args[0]];
int32 paymentFound = 0;
GameObject *obj;
ObjectID id;
@@ -3739,12 +3737,11 @@ int16 scriptNumTempActors(int16 *args) {
int16 scriptGetObjectBasePrice(int16 *args) {
MONOLOG(GetBaseObjectPrice);
- extern ProtoObj *objectProtos;
assert(args[0] >= 0);
assert(args[0] < objectProtoCount);
- return objectProtos[args[0]].price;
+ return g_vm->_objectProtos[args[0]]->price;
}
//-----------------------------------------------------------------------
More information about the Scummvm-git-logs
mailing list