Skip to content

Commit

Permalink
AGS: Store room objects in std::vector
Browse files Browse the repository at this point in the history
From upstream 5f3b8eb509c9535c75b401f9b7257f7c7acd0e6d
  • Loading branch information
criezy committed Jun 15, 2022
1 parent 74416f5 commit 5d9ae41
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 123 deletions.
5 changes: 2 additions & 3 deletions engines/ags/engine/ac/dynobj/script_object.h
Expand Up @@ -26,10 +26,9 @@

namespace AGS3 {

// 64 bit: Struct size must be 8 byte for scripts to work
// WARNING: struct size must be 8 byte for old scripts to work
struct ScriptObject {
int id = 0;
//RoomObject *obj;
int id = -1;
int __padding = 0;
};

Expand Down
71 changes: 37 additions & 34 deletions engines/ags/engine/ac/room.cpp
Expand Up @@ -314,11 +314,11 @@ void convert_room_coordinates_to_data_res(RoomStruct *rstruc) {
return;

const int mul = _GP(game).GetDataUpscaleMult();
for (size_t i = 0; i < rstruc->ObjectCount; ++i) {
rstruc->Objects[i].X /= mul;
rstruc->Objects[i].Y /= mul;
if (rstruc->Objects[i].Baseline > 0) {
rstruc->Objects[i].Baseline /= mul;
for (auto &obj : rstruc->Objects) {
obj.X /= mul;
obj.Y /= mul;
if (obj.Baseline > 0) {
obj.Baseline /= mul;
}
}

Expand Down Expand Up @@ -405,8 +405,6 @@ HError LoadRoomScript(RoomStruct *room, int newnum) {
}

static void reset_temp_room() {
_GP(troom).FreeScriptData();
_GP(troom).FreeProperties();
_GP(troom) = RoomStatus();
}

Expand Down Expand Up @@ -537,7 +535,7 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
_GP(thisroom).Interaction->CopyTimesRun(_G(croom)->intrRoom);
for (cc = 0; cc < MAX_ROOM_HOTSPOTS; cc++)
_GP(thisroom).Hotspots[cc].Interaction->CopyTimesRun(_G(croom)->intrHotspot[cc]);
for (cc = 0; cc < MAX_ROOM_OBJECTS; cc++)
for (cc = 0; cc < _GP(thisroom).Objects.size(); cc++)
_GP(thisroom).Objects[cc].Interaction->CopyTimesRun(_G(croom)->intrObject[cc]);
for (cc = 0; cc < MAX_ROOM_REGIONS; cc++)
_GP(thisroom).Regions[cc].Interaction->CopyTimesRun(_G(croom)->intrRegion[cc]);
Expand All @@ -547,39 +545,44 @@ void load_new_room(int newnum, CharacterInfo *forchar) {

// Always copy object and hotspot names for < 3.6.0 games, because they were not settable
if (_G(loaded_game_file_version) < kGameVersion_360_16) {
for (cc = 0; cc < _G(croom)->numobj; ++cc)
for (cc = 0; cc < _GP(thisroom).Objects.size(); ++cc)
_G(croom)->obj[cc].name = _GP(thisroom).Objects[cc].Name;
for (cc = 0; cc < MAX_ROOM_HOTSPOTS; cc++)
_G(croom)->hotspot[cc].Name = _GP(thisroom).Hotspots[cc].Name;
}
} else {
// If we have not been in this room before, then copy necessary fields from _GP(thisroom)
_G(croom)->numobj = _GP(thisroom).ObjectCount;
_G(croom)->numobj = _GP(thisroom).Objects.size();
_G(croom)->tsdatasize = 0;
_G(croom)->obj.resize(_G(croom)->numobj);
_G(croom)->objProps.resize(_G(croom)->numobj);
_G(croom)->intrObject.resize(_G(croom)->numobj);
for (cc = 0; cc < _G(croom)->numobj; cc++) {
_G(croom)->obj[cc].x = _GP(thisroom).Objects[cc].X;
_G(croom)->obj[cc].y = _GP(thisroom).Objects[cc].Y;
_G(croom)->obj[cc].num = Math::InRangeOrDef<uint16_t>(_GP(thisroom).Objects[cc].Sprite, 0);
_G(croom)->obj[cc].on = _GP(thisroom).Objects[cc].IsOn;
_G(croom)->obj[cc].view = RoomObject::NoView;
_G(croom)->obj[cc].loop = 0;
_G(croom)->obj[cc].frame = 0;
_G(croom)->obj[cc].wait = 0;
_G(croom)->obj[cc].transparent = 0;
_G(croom)->obj[cc].moving = -1;
_G(croom)->obj[cc].flags = _GP(thisroom).Objects[cc].Flags;
_G(croom)->obj[cc].baseline = -1;
_G(croom)->obj[cc].zoom = 100;
_G(croom)->obj[cc].last_width = 0;
_G(croom)->obj[cc].last_height = 0;
_G(croom)->obj[cc].blocking_width = 0;
_G(croom)->obj[cc].blocking_height = 0;
_G(croom)->obj[cc].name = _GP(thisroom).Objects[cc].Name;
if (_GP(thisroom).Objects[cc].Baseline >= 0)
_G(croom)->obj[cc].baseline = _GP(thisroom).Objects[cc].Baseline;
if (_GP(thisroom).Objects[cc].Sprite > UINT16_MAX)
const auto &trobj = _GP(thisroom).Objects[cc];
auto &crobj = _G(croom)->obj[cc];
crobj.x = trobj.X;
crobj.y = trobj.Y;
crobj.num = Math::InRangeOrDef<uint16_t>(trobj.Sprite, 0);
crobj.on = trobj.IsOn;
crobj.view = RoomObject::NoView;
crobj.loop = 0;
crobj.frame = 0;
crobj.wait = 0;
crobj.transparent = 0;
crobj.moving = -1;
crobj.flags = trobj.Flags;
crobj.baseline = -1;
crobj.zoom = 100;
crobj.last_width = 0;
crobj.last_height = 0;
crobj.blocking_width = 0;
crobj.blocking_height = 0;
crobj.name = trobj.Name;
if (trobj.Baseline >= 0)
crobj.baseline = trobj.Baseline;
if (trobj.Sprite > UINT16_MAX)
debug_script_warn("Warning: object's (id %d) sprite %d outside of internal range (%d), reset to 0",
cc, _GP(thisroom).Objects[cc].Sprite, UINT16_MAX);
cc, trobj.Sprite, UINT16_MAX);
}
for (size_t i = 0; i < (size_t)MAX_WALK_BEHINDS; ++i)
_G(croom)->walkbehind_base[i] = _GP(thisroom).WalkBehinds[i].Baseline;
Expand Down Expand Up @@ -614,13 +617,13 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
_G(croom)->intrRoom = *_GP(thisroom).Interaction;
for (cc = 0; cc < MAX_ROOM_HOTSPOTS; cc++)
_G(croom)->intrHotspot[cc] = *_GP(thisroom).Hotspots[cc].Interaction;
for (cc = 0; cc < MAX_ROOM_OBJECTS; cc++)
for (cc = 0; cc < _GP(thisroom).Objects.size(); cc++)
_G(croom)->intrObject[cc] = *_GP(thisroom).Objects[cc].Interaction;
for (cc = 0; cc < MAX_ROOM_REGIONS; cc++)
_G(croom)->intrRegion[cc] = *_GP(thisroom).Regions[cc].Interaction;
}

_G(objs) = &_G(croom)->obj[0];
_G(objs) = _G(croom)->obj.size() > 0 ? &_G(croom)->obj[0] : nullptr;

for (cc = 0; cc < _G(croom)->numobj; cc++) {
// export the object's script object
Expand Down
30 changes: 19 additions & 11 deletions engines/ags/engine/ac/room_status.cpp
Expand Up @@ -73,23 +73,28 @@ void RoomStatus::FreeProperties() {
for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) {
hsProps[i].clear();
}
for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) {
objProps[i].clear();
}
objProps.clear();
}

void RoomStatus::ReadFromFile_v321(Stream *in) {
FreeScriptData();
FreeProperties();

beenhere = in->ReadInt32();
numobj = in->ReadInt32();
obj.resize(numobj);
objProps.resize(numobj);
intrObject.resize(numobj);
ReadRoomObjects_Aligned(in);

in->Seek(MAX_LEGACY_ROOM_FLAGS * sizeof(int16_t)); // flagstates (OBSOLETE)
tsdatasize = in->ReadInt32();
in->ReadInt32(); // tsdata
for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) {
intrHotspot[i].ReadFromSavedgame_v321(in);
}
for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) {
intrObject[i].ReadFromSavedgame_v321(in);
for (auto &intr : intrObject) {
intr.ReadFromSavedgame_v321(in);
}
for (int i = 0; i < MAX_ROOM_REGIONS; ++i) {
intrRegion[i].ReadFromSavedgame_v321(in);
Expand All @@ -106,16 +111,16 @@ void RoomStatus::ReadFromFile_v321(Stream *in) {
for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) {
Properties::ReadValues(hsProps[i], in);
}
for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) {
Properties::ReadValues(objProps[i], in);
for (auto &props : objProps) {
Properties::ReadValues(props, in);
}
}
}

void RoomStatus::ReadRoomObjects_Aligned(Shared::Stream *in) {
AlignedStream align_s(in, Shared::kAligned_Read);
for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) {
obj[i].ReadFromSavegame(&align_s, 0);
for (auto &o : obj) {
o.ReadFromSavegame(&align_s, 0);
align_s.Reset();
}
}
Expand All @@ -126,7 +131,10 @@ void RoomStatus::ReadFromSavegame(Stream *in, int save_ver) {

beenhere = in->ReadInt8();
numobj = in->ReadInt32();
for (int i = 0; i < numobj; ++i) {
obj.resize(numobj);
objProps.resize(numobj);
intrObject.resize(numobj);
for (size_t i = 0; i < numobj; ++i) {
obj[i].ReadFromSavegame(in, save_ver);
Properties::ReadValues(objProps[i], in);
if (_G(loaded_game_file_version) <= kGameVersion_272)
Expand Down Expand Up @@ -163,7 +171,7 @@ void RoomStatus::ReadFromSavegame(Stream *in, int save_ver) {
void RoomStatus::WriteToSavegame(Stream *out) const {
out->WriteInt8(beenhere);
out->WriteInt32(numobj);
for (int i = 0; i < numobj; ++i) {
for (size_t i = 0; i < numobj; ++i) {
obj[i].WriteToSavegame(out);
Properties::WriteValues(objProps[i], out);
if (_G(loaded_game_file_version) <= kGameVersion_272)
Expand Down
6 changes: 3 additions & 3 deletions engines/ags/engine/ac/room_status.h
Expand Up @@ -52,17 +52,17 @@ struct HotspotState {
struct RoomStatus {
int beenhere = 0;
int numobj = 0;
RoomObject obj[MAX_ROOM_OBJECTS];
std::vector<RoomObject> obj;
int tsdatasize = 0;
char *tsdata = nullptr;
Interaction intrHotspot[MAX_ROOM_HOTSPOTS];
Interaction intrObject[MAX_ROOM_OBJECTS];
std::vector<Interaction> intrObject;
Interaction intrRegion[MAX_ROOM_REGIONS];
Interaction intrRoom;

Shared::StringIMap roomProps;
Shared::StringIMap hsProps[MAX_ROOM_HOTSPOTS];
Shared::StringIMap objProps[MAX_ROOM_OBJECTS];
std::vector<Shared::StringIMap> objProps;
HotspotState hotspot[MAX_ROOM_HOTSPOTS];
int8 region_enabled[MAX_ROOM_REGIONS];
short walkbehind_base[MAX_WALK_BEHINDS];
Expand Down
3 changes: 1 addition & 2 deletions engines/ags/engine/game/savegame.cpp
Expand Up @@ -374,8 +374,7 @@ void DoBeforeRestore(PreservedParams &pp) {
_G(dialogScriptsInst) = nullptr;

resetRoomStatuses();
_GP(troom).FreeScriptData();
_GP(troom).FreeProperties();
_GP(troom) = RoomStatus(); // reset temp room state
free_do_once_tokens();

// unregister gui controls from API exports
Expand Down
5 changes: 3 additions & 2 deletions engines/ags/engine/game/savegame_components.cpp
Expand Up @@ -917,8 +917,9 @@ HSaveError WriteThisRoom(Stream *out) {
}

// room object movement paths cache
out->WriteInt32(_GP(thisroom).ObjectCount + 1);
for (size_t i = 0; i < _GP(thisroom).ObjectCount + 1; ++i) {
// CHECKME: not sure why it saves (object count + 1) move lists
out->WriteInt32(_GP(thisroom).Objects.size() + 1);
for (size_t i = 0; i < _GP(thisroom).Objects.size() + 1; ++i) {
_GP(mls)[i].WriteToFile(out);
}

Expand Down

0 comments on commit 5d9ae41

Please sign in to comment.