[Scummvm-git-logs] scummvm master -> 0ef2ac659b71efc36e8ab55ee675cd40ad687d5f

dreammaster dreammaster at scummvm.org
Sun Feb 28 21:28:07 UTC 2021


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

Summary:
80bfa0510d AGS: Move troom to Globals
ef245e2104 AGS: Move thisroom to Globals
887472c8c1 AGS: Moved a lot of game.cpp globals to Globals
0ef2ac659b AGS: Move DbgMgr to Globals


Commit: 80bfa0510d7559b66cb112a1cfe7243f493ada11
    https://github.com/scummvm/scummvm/commit/80bfa0510d7559b66cb112a1cfe7243f493ada11
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-02-28T13:27:21-08:00

Commit Message:
AGS: Move troom to Globals

Changed paths:
    engines/ags/engine/ac/game.cpp
    engines/ags/engine/ac/room.cpp
    engines/ags/engine/ac/roomstatus.cpp
    engines/ags/engine/ac/roomstatus.h
    engines/ags/engine/game/savegame.cpp
    engines/ags/engine/game/savegame_components.cpp
    engines/ags/engine/main/quit.cpp
    engines/ags/globals.cpp
    engines/ags/globals.h


diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index 8cada9fb09..d472526c93 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -151,7 +151,6 @@ extern IGraphicsDriver *gfxDriver;
 //=============================================================================
 
 GameSetup usetup;
-RoomStatus troom;    // used for non-saveable rooms, eg. intro
 RoomObject *objs;
 RoomStatus *croom = nullptr;
 RoomStruct thisroom;
@@ -1338,13 +1337,13 @@ void restore_game_displayed_room_status(Stream *in, RestoredData &r_data) {
 			raw_saved_screen = read_serialized_bitmap(in);
 
 		// get the current troom, in case they save in room 600 or whatever
-		ReadRoomStatus_Aligned(&troom, in);
+		ReadRoomStatus_Aligned(&_GP(troom), in);
 
-		if (troom.tsdatasize > 0) {
-			troom.tsdata = (char *)malloc(troom.tsdatasize + 5);
-			in->Read(&troom.tsdata[0], troom.tsdatasize);
+		if (_GP(troom).tsdatasize > 0) {
+			_GP(troom).tsdata = (char *)malloc(_GP(troom).tsdatasize + 5);
+			in->Read(&_GP(troom).tsdata[0], _GP(troom).tsdatasize);
 		} else
-			troom.tsdata = nullptr;
+			_GP(troom).tsdata = nullptr;
 	}
 }
 
diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp
index 09f24de99b..12248ba400 100644
--- a/engines/ags/engine/ac/room.cpp
+++ b/engines/ags/engine/ac/room.cpp
@@ -90,7 +90,6 @@ extern GameSetup usetup;
 
 
 extern RoomStatus *croom;
-extern RoomStatus troom;    // used for non-saveable rooms, eg. intro
 extern int displayed_room;
 extern RoomObject *objs;
 extern ccInstance *roominst;
@@ -551,15 +550,15 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
 	// setup objects
 	if (forchar != nullptr) {
 		// if not restoring a game, always reset this room
-		troom.beenhere = 0;
-		troom.FreeScriptData();
-		troom.FreeProperties();
-		memset(&troom.hotspot_enabled[0], 1, MAX_ROOM_HOTSPOTS);
-		memset(&troom.region_enabled[0], 1, MAX_ROOM_REGIONS);
+		_GP(troom).beenhere = 0;
+		_GP(troom).FreeScriptData();
+		_GP(troom).FreeProperties();
+		memset(&_GP(troom).hotspot_enabled[0], 1, MAX_ROOM_HOTSPOTS);
+		memset(&_GP(troom).region_enabled[0], 1, MAX_ROOM_REGIONS);
 	}
 	if ((newnum >= 0) & (newnum < MAX_ROOMS))
 		croom = getRoomStatus(newnum);
-	else croom = &troom;
+	else croom = &_GP(troom);
 
 	if (croom->beenhere > 0) {
 		// if we've been here before, save the Times Run information
diff --git a/engines/ags/engine/ac/roomstatus.cpp b/engines/ags/engine/ac/roomstatus.cpp
index d24aff1fa8..3fde08a7e8 100644
--- a/engines/ags/engine/ac/roomstatus.cpp
+++ b/engines/ags/engine/ac/roomstatus.cpp
@@ -35,12 +35,7 @@ using namespace AGS::Shared;
 using namespace AGS::Engine;
 
 RoomStatus::RoomStatus() {
-	beenhere = 0;
-	numobj = 0;
 	memset(&flagstates, 0, sizeof(flagstates));
-	tsdatasize = 0;
-	tsdata = nullptr;
-
 	memset(&hotspot_enabled, 0, sizeof(hotspot_enabled));
 	memset(&region_enabled, 0, sizeof(region_enabled));
 	memset(&walkbehind_base, 0, sizeof(walkbehind_base));
diff --git a/engines/ags/engine/ac/roomstatus.h b/engines/ags/engine/ac/roomstatus.h
index 3be1e11ee0..e1783c26e3 100644
--- a/engines/ags/engine/ac/roomstatus.h
+++ b/engines/ags/engine/ac/roomstatus.h
@@ -43,12 +43,12 @@ using AGS::Shared::Interaction;
 // This struct is saved in the save games - it contains everything about
 // a room that could change
 struct RoomStatus {
-	int   beenhere;
-	int   numobj;
+	int   beenhere = 0;
+	int   numobj = 0;
 	RoomObject obj[MAX_ROOM_OBJECTS];
 	short flagstates[MAX_FLAGS];
-	int   tsdatasize;
-	char *tsdata;
+	int   tsdatasize = 0;
+	char *tsdata = nullptr;
 	Interaction intrHotspot[MAX_ROOM_HOTSPOTS];
 	Interaction intrObject[MAX_ROOM_OBJECTS];
 	Interaction intrRegion[MAX_ROOM_REGIONS];
@@ -61,7 +61,7 @@ struct RoomStatus {
 #ifdef UNUSED_CODE
 	EventBlock hscond[MAX_ROOM_HOTSPOTS];
 	EventBlock objcond[MAX_ROOM_OBJECTS];
-	EventBlock misccond;
+	EventBlock misccond = 0;
 #endif
 	char  hotspot_enabled[MAX_ROOM_HOTSPOTS];
 	char  region_enabled[MAX_ROOM_REGIONS];
diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp
index 7cb4963fb0..bfe9b3ee07 100644
--- a/engines/ags/engine/game/savegame.cpp
+++ b/engines/ags/engine/game/savegame.cpp
@@ -78,7 +78,7 @@ extern AGS::Engine::IDriverDependantBitmap **guibgbmp;
 extern AGS::Engine::IGraphicsDriver *gfxDriver;
 extern Bitmap *dynamicallyCreatedSurfaces[MAX_DYNAMIC_SURFACES];
 extern Bitmap *raw_saved_screen;
-extern RoomStatus troom;
+
 extern RoomStatus *croom;
 
 
@@ -381,8 +381,8 @@ void DoBeforeRestore(PreservedParams &pp) {
 	dialogScriptsInst = nullptr;
 
 	resetRoomStatuses();
-	troom.FreeScriptData();
-	troom.FreeProperties();
+	_GP(troom).FreeScriptData();
+	_GP(troom).FreeProperties();
 	free_do_once_tokens();
 
 	// unregister gui controls from API exports
diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp
index 321357d739..973292cbfc 100644
--- a/engines/ags/engine/game/savegame_components.cpp
+++ b/engines/ags/engine/game/savegame_components.cpp
@@ -71,7 +71,7 @@ extern int numAnimButs;
 extern ViewStruct *views;
 extern Bitmap *dynamicallyCreatedSurfaces[MAX_DYNAMIC_SURFACES];
 extern RoomStruct thisroom;
-extern RoomStatus troom;
+
 extern Bitmap *raw_saved_screen;
 extern MoveList *mls;
 
@@ -930,7 +930,7 @@ HSaveError WriteThisRoom(PStream out) {
 	out->WriteBool(persist);
 	// write the current troom state, in case they save in temporary room
 	if (!persist)
-		troom.WriteToSavegame(out.get());
+		_GP(troom).WriteToSavegame(out.get());
 	return HSaveError::None();
 }
 
@@ -976,7 +976,7 @@ HSaveError ReadThisRoom(PStream in, int32_t cmp_ver, const PreservedParams &pp,
 
 	// read the current troom state, in case they saved in temporary room
 	if (!in->ReadBool())
-		troom.ReadFromSavegame(in.get());
+		_GP(troom).ReadFromSavegame(in.get());
 
 	return HSaveError::None();
 }
diff --git a/engines/ags/engine/main/quit.cpp b/engines/ags/engine/main/quit.cpp
index bc538f1bb2..f3ff6848ea 100644
--- a/engines/ags/engine/main/quit.cpp
+++ b/engines/ags/engine/main/quit.cpp
@@ -57,7 +57,7 @@ using namespace AGS::Engine;
 
 
 extern RoomStruct thisroom;
-extern RoomStatus troom;    // used for non-saveable rooms, eg. intro
+    // used for non-saveable rooms, eg. intro
 extern int our_eip;
 extern GameSetup usetup;
 extern char pexbuf[STD_BUFFER_SIZE];
diff --git a/engines/ags/globals.cpp b/engines/ags/globals.cpp
index 8e159ca605..31d4143c7e 100644
--- a/engines/ags/globals.cpp
+++ b/engines/ags/globals.cpp
@@ -24,6 +24,7 @@
 #include "ags/shared/ac/gamesetupstruct.h"
 #include "ags/shared/ac/spritecache.h"
 #include "ags/engine/ac/gamestate.h"
+#include "ags/engine/ac/roomstatus.h"
 
 namespace AGS3 {
 
@@ -37,6 +38,7 @@ Globals::Globals() {
 	_play = new GameState();
 	_game = new GameSetupStruct();
 	_spriteset = new SpriteCache(_game->SpriteInfos);
+	_troom = new RoomStatus();
 }
 
 Globals::~Globals() {
@@ -44,6 +46,7 @@ Globals::~Globals() {
 	delete _game;
 	delete _play;
 	delete _spriteset;
+	delete _troom;
 }
 
 } // namespace AGS3
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index f85d226b0d..238ff5822a 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -43,6 +43,7 @@ class Bitmap;
 struct IAGSEditorDebugger;
 struct GameSetupStruct;
 struct GameState;
+struct RoomStatus;
 class SpriteCache;
 
 class Globals {
@@ -80,6 +81,7 @@ public:
 	GameSetupStruct *_game = nullptr;
 	GameState *_play = nullptr;
 	SpriteCache *_spriteset = nullptr;
+	RoomStatus *_troom = nullptr; // used for non-saveable rooms, eg. intro
 
 	 /**@}*/
 


Commit: ef245e2104509860a058ab981b606d4c67b0716f
    https://github.com/scummvm/scummvm/commit/ef245e2104509860a058ab981b606d4c67b0716f
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-02-28T13:27:21-08:00

Commit Message:
AGS: Move thisroom to Globals

Changed paths:
    engines/ags/ags.cpp
    engines/ags/engine/ac/audiochannel.cpp
    engines/ags/engine/ac/character.cpp
    engines/ags/engine/ac/characterinfo_engine.cpp
    engines/ags/engine/ac/draw.cpp
    engines/ags/engine/ac/dynamicsprite.cpp
    engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp
    engines/ags/engine/ac/event.cpp
    engines/ags/engine/ac/game.cpp
    engines/ags/engine/ac/gamestate.cpp
    engines/ags/engine/ac/global_audio.cpp
    engines/ags/engine/ac/global_character.cpp
    engines/ags/engine/ac/global_debug.cpp
    engines/ags/engine/ac/global_display.cpp
    engines/ags/engine/ac/global_drawingsurface.cpp
    engines/ags/engine/ac/global_game.cpp
    engines/ags/engine/ac/global_hotspot.cpp
    engines/ags/engine/ac/global_object.cpp
    engines/ags/engine/ac/global_region.cpp
    engines/ags/engine/ac/global_room.cpp
    engines/ags/engine/ac/global_screen.cpp
    engines/ags/engine/ac/global_walkablearea.cpp
    engines/ags/engine/ac/gui.cpp
    engines/ags/engine/ac/hotspot.cpp
    engines/ags/engine/ac/object.cpp
    engines/ags/engine/ac/region.cpp
    engines/ags/engine/ac/room.cpp
    engines/ags/engine/ac/room.h
    engines/ags/engine/ac/walkablearea.cpp
    engines/ags/engine/ac/walkbehind.cpp
    engines/ags/engine/debugging/debug.cpp
    engines/ags/engine/game/savegame.cpp
    engines/ags/engine/game/savegame_components.cpp
    engines/ags/engine/game/viewport.cpp
    engines/ags/engine/main/game_run.cpp
    engines/ags/engine/main/quit.cpp
    engines/ags/engine/main/update.cpp
    engines/ags/engine/media/audio/audio.cpp
    engines/ags/engine/script/script.cpp
    engines/ags/globals.cpp
    engines/ags/globals.h
    engines/ags/plugins/agsplugin.cpp


diff --git a/engines/ags/ags.cpp b/engines/ags/ags.cpp
index ea5dd58196..ffe3e8fbf5 100644
--- a/engines/ags/ags.cpp
+++ b/engines/ags/ags.cpp
@@ -394,12 +394,12 @@ void AGSEngine::setGraphicsMode(size_t w, size_t h) {
 }
 
 bool AGSEngine::canLoadGameStateCurrently() {
-	return !::AGS3::thisroom.Options.SaveLoadDisabled &&
+	return !_GP(thisroom).Options.SaveLoadDisabled &&
 		!::AGS3::inside_script && !_GP(play).fast_forward;
 }
 
 bool AGSEngine::canSaveGameStateCurrently() {
-	return !::AGS3::thisroom.Options.SaveLoadDisabled &&
+	return !_GP(thisroom).Options.SaveLoadDisabled &&
 		!::AGS3::inside_script && !_GP(play).fast_forward;
 }
 
diff --git a/engines/ags/engine/ac/audiochannel.cpp b/engines/ags/engine/ac/audiochannel.cpp
index 8e6e06c941..105d5cb050 100644
--- a/engines/ags/engine/ac/audiochannel.cpp
+++ b/engines/ags/engine/ac/audiochannel.cpp
@@ -29,6 +29,7 @@
 #include "ags/engine/script/runtimescriptvalue.h"
 #include "ags/engine/media/audio/audio_system.h"
 #include "ags/shared/debugging/out.h"
+#include "ags/shared/game/roomstruct.h"
 #include "ags/engine/script/script_api.h"
 #include "ags/engine/script/script_runtime.h"
 #include "ags/globals.h"
@@ -38,7 +39,7 @@ namespace AGS3 {
 using namespace AGS::Shared;
 
 
-extern RoomStruct thisroom;
+
 extern CCAudioClip ccDynamicAudioClip;
 
 int AudioChannel_GetID(ScriptAudioChannel *channel) {
@@ -188,7 +189,7 @@ void AudioChannel_SetRoomLocation(ScriptAudioChannel *channel, int xPos, int yPo
 	auto *ch = lock.GetChannelIfPlaying(channel->id);
 
 	if (ch) {
-		int maxDist = ((xPos > thisroom.Width / 2) ? xPos : (thisroom.Width - xPos)) - AMBIENCE_FULL_DIST;
+		int maxDist = ((xPos > _GP(thisroom).Width / 2) ? xPos : (_GP(thisroom).Width - xPos)) - AMBIENCE_FULL_DIST;
 		ch->_xSource = (xPos > 0) ? xPos : -1;
 		ch->_ySource = yPos;
 		ch->_maximumPossibleDistanceAway = maxDist;
diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp
index 2643fbefc5..f0f717214e 100644
--- a/engines/ags/engine/ac/character.cpp
+++ b/engines/ags/engine/ac/character.cpp
@@ -80,7 +80,7 @@ namespace AGS3 {
 using namespace AGS::Shared;
 
 extern int displayed_room, starting_room;
-extern RoomStruct thisroom;
+
 extern MoveList *mls;
 extern ViewStruct *views;
 extern RoomObject *objs;
@@ -226,13 +226,13 @@ void Character_ChangeRoomAutoPosition(CharacterInfo *chaa, int room, int newPos)
 
 	if (new_room_pos == 0) {
 		// auto place on other side of screen
-		if (chaa->x <= thisroom.Edges.Left + 10)
+		if (chaa->x <= _GP(thisroom).Edges.Left + 10)
 			new_room_pos = 2000;
-		else if (chaa->x >= thisroom.Edges.Right - 10)
+		else if (chaa->x >= _GP(thisroom).Edges.Right - 10)
 			new_room_pos = 1000;
-		else if (chaa->y <= thisroom.Edges.Top + 10)
+		else if (chaa->y <= _GP(thisroom).Edges.Top + 10)
 			new_room_pos = 3000;
-		else if (chaa->y >= thisroom.Edges.Bottom - 10)
+		else if (chaa->y >= _GP(thisroom).Edges.Bottom - 10)
 			new_room_pos = 4000;
 
 		if (new_room_pos < 3000)
@@ -1856,16 +1856,16 @@ int doNextCharMoveStep(CharacterInfo *chi, int &char_index, CharacterExtras *che
 int find_nearest_walkable_area_within(int32_t *xx, int32_t *yy, int range, int step) {
 	int ex, ey, nearest = 99999, thisis, nearx = 0, neary = 0;
 	int startx = 0, starty = 14;
-	int roomWidthLowRes = room_to_mask_coord(thisroom.Width);
-	int roomHeightLowRes = room_to_mask_coord(thisroom.Height);
+	int roomWidthLowRes = room_to_mask_coord(_GP(thisroom).Width);
+	int roomHeightLowRes = room_to_mask_coord(_GP(thisroom).Height);
 	int xwidth = roomWidthLowRes, yheight = roomHeightLowRes;
 
 	int xLowRes = room_to_mask_coord(xx[0]);
 	int yLowRes = room_to_mask_coord(yy[0]);
-	int rightEdge = room_to_mask_coord(thisroom.Edges.Right);
-	int leftEdge = room_to_mask_coord(thisroom.Edges.Left);
-	int topEdge = room_to_mask_coord(thisroom.Edges.Top);
-	int bottomEdge = room_to_mask_coord(thisroom.Edges.Bottom);
+	int rightEdge = room_to_mask_coord(_GP(thisroom).Edges.Right);
+	int leftEdge = room_to_mask_coord(_GP(thisroom).Edges.Left);
+	int topEdge = room_to_mask_coord(_GP(thisroom).Edges.Top);
+	int bottomEdge = room_to_mask_coord(_GP(thisroom).Edges.Bottom);
 
 	// tweak because people forget to move the edges sometimes
 	// if the player is already over the edge, ignore it
@@ -1888,7 +1888,7 @@ int find_nearest_walkable_area_within(int32_t *xx, int32_t *yy, int range, int s
 	for (ex = startx; ex < xwidth; ex += step) {
 		for (ey = starty; ey < yheight; ey += step) {
 			// non-walkalbe, so don't go here
-			if (thisroom.WalkAreaMask->GetPixel(ex, ey) == 0) continue;
+			if (_GP(thisroom).WalkAreaMask->GetPixel(ex, ey) == 0) continue;
 			// off a screen edge, don't move them there
 			if ((ex <= leftEdge) || (ex >= rightEdge) ||
 			        (ey <= topEdge) || (ey >= bottomEdge))
@@ -1913,7 +1913,7 @@ int find_nearest_walkable_area_within(int32_t *xx, int32_t *yy, int range, int s
 
 void find_nearest_walkable_area(int32_t *xx, int32_t *yy) {
 
-	int pixValue = thisroom.WalkAreaMask->GetPixel(room_to_mask_coord(xx[0]), room_to_mask_coord(yy[0]));
+	int pixValue = _GP(thisroom).WalkAreaMask->GetPixel(room_to_mask_coord(xx[0]), room_to_mask_coord(yy[0]));
 	// only fix this code if the game was built with 2.61 or above
 	if (pixValue == 0 || (loaded_game_file_version >= kGameVersion_261 && pixValue < 1)) {
 		// First, check every 2 pixels within immediate area
diff --git a/engines/ags/engine/ac/characterinfo_engine.cpp b/engines/ags/engine/ac/characterinfo_engine.cpp
index a00321c88e..6d79208a07 100644
--- a/engines/ags/engine/ac/characterinfo_engine.cpp
+++ b/engines/ags/engine/ac/characterinfo_engine.cpp
@@ -46,7 +46,7 @@ extern ViewStruct *views;
 extern int displayed_room;
 
 extern int char_speaking;
-extern RoomStruct thisroom;
+
 extern unsigned int loopcounter;
 
 #define Random __Rand
@@ -403,17 +403,17 @@ void CharacterInfo::update_character_follower(int &aa, int &numSheep, int *follo
 			if (room == displayed_room) {
 				// only move to the room-entered position if coming into
 				// the current room
-				if (_GP(play).entered_at_x > (thisroom.Width - 8)) {
-					x = thisroom.Width + 8;
+				if (_GP(play).entered_at_x > (_GP(thisroom).Width - 8)) {
+					x = _GP(thisroom).Width + 8;
 					y = _GP(play).entered_at_y;
 				} else if (_GP(play).entered_at_x < 8) {
 					x = -8;
 					y = _GP(play).entered_at_y;
-				} else if (_GP(play).entered_at_y > (thisroom.Height - 8)) {
-					y = thisroom.Height + 8;
+				} else if (_GP(play).entered_at_y > (_GP(thisroom).Height - 8)) {
+					y = _GP(thisroom).Height + 8;
 					x = _GP(play).entered_at_x;
-				} else if (_GP(play).entered_at_y < thisroom.Edges.Top + 8) {
-					y = thisroom.Edges.Top + 1;
+				} else if (_GP(play).entered_at_y < _GP(thisroom).Edges.Top + 8) {
+					y = _GP(thisroom).Edges.Top + 1;
 					x = _GP(play).entered_at_x;
 				} else {
 					// not at one of the edges
diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index 40efba0b77..f0e9d2bf77 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -94,7 +94,7 @@ extern GameSetup usetup;
 extern int convert_16bit_bgr;
 extern ScriptSystem scsystem;
 extern AGSPlatformDriver *platform;
-extern RoomStruct thisroom;
+
 extern char noWalkBehindsAtAll;
 extern unsigned int loopcounter;
 extern char *walkBehindExists;  // whether a WB area is in this column
@@ -527,8 +527,8 @@ void prepare_roomview_frame(Viewport *view) {
 		PBitmap &camera_buffer = draw_dat.Buffer;
 		if (!camera_buffer || camera_buffer->GetWidth() < cam_sz.Width || camera_buffer->GetHeight() < cam_sz.Height) {
 			// Allocate new buffer bitmap with an extra size in case they will want to zoom out
-			int room_width = data_to_game_coord(thisroom.Width);
-			int room_height = data_to_game_coord(thisroom.Height);
+			int room_width = data_to_game_coord(_GP(thisroom).Width);
+			int room_height = data_to_game_coord(_GP(thisroom).Height);
 			Size alloc_sz = Size::Clamp(cam_sz * 2, Size(1, 1), Size(room_width, room_height));
 			camera_buffer.reset(new Bitmap(alloc_sz.Width, alloc_sz.Height, gfxDriver->GetMemoryBackBuffer()->GetColorDepth()));
 		}
@@ -801,7 +801,7 @@ int sort_out_walk_behinds(Bitmap *sprit, int xx, int yy, int basel, Bitmap *copy
 	if (noWalkBehindsAtAll)
 		return 0;
 
-	if ((!thisroom.WalkBehindMask->IsMemoryBitmap()) ||
+	if ((!_GP(thisroom).WalkBehindMask->IsMemoryBitmap()) ||
 	        (!sprit->IsMemoryBitmap()))
 		quit("!sort_out_walk_behinds: wb bitmap not linear");
 
@@ -809,7 +809,7 @@ int sort_out_walk_behinds(Bitmap *sprit, int xx, int yy, int basel, Bitmap *copy
 	// precalculate this to try and shave some time off
 	int maskcol = sprit->GetMaskColor();
 	int spcoldep = sprit->GetColorDepth();
-	int screenhit = thisroom.WalkBehindMask->GetHeight();
+	int screenhit = _GP(thisroom).WalkBehindMask->GetHeight();
 	short *shptr, *shptr2;
 	int *loptr, *loptr2;
 	int pixelsChanged = 0;
@@ -821,7 +821,7 @@ int sort_out_walk_behinds(Bitmap *sprit, int xx, int yy, int basel, Bitmap *copy
 		quit("sprite colour depth does not match background colour depth");
 
 	for (; ee < sprit->GetWidth(); ee++) {
-		if (ee + xx >= thisroom.WalkBehindMask->GetWidth())
+		if (ee + xx >= _GP(thisroom).WalkBehindMask->GetWidth())
 			break;
 
 		if ((!walkBehindExists[ee + xx]) ||
@@ -849,10 +849,10 @@ int sort_out_walk_behinds(Bitmap *sprit, int xx, int yy, int basel, Bitmap *copy
 		for (; rr < toheight; rr++) {
 
 			// we're ok with _getpixel because we've checked the screen edges
-			//tmm = _getpixel(thisroom.WalkBehindMask,ee+xx,rr+yy);
+			//tmm = _getpixel(_GP(thisroom).WalkBehindMask,ee+xx,rr+yy);
 			// actually, _getpixel is well inefficient, do it ourselves
 			// since we know it's 8-bit bitmap
-			tmm = thisroom.WalkBehindMask->GetScanLine(rr + yy)[ee + xx];
+			tmm = _GP(thisroom).WalkBehindMask->GetScanLine(rr + yy)[ee + xx];
 			if (tmm < 1) continue;
 			if (croom->walkbehind_base[tmm] <= basel) continue;
 
@@ -913,10 +913,10 @@ void sort_out_char_sprite_walk_behind(int actspsIndex, int xx, int yy, int basel
 	        (actspswbcache[actspsIndex].xWas != xx) ||
 	        (actspswbcache[actspsIndex].yWas != yy) ||
 	        (actspswbcache[actspsIndex].baselineWas != basel)) {
-		actspswb[actspsIndex] = recycle_bitmap(actspswb[actspsIndex], thisroom.BgFrames[_GP(play).bg_frame].Graphic->GetColorDepth(), width, height, true);
+		actspswb[actspsIndex] = recycle_bitmap(actspswb[actspsIndex], _GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic->GetColorDepth(), width, height, true);
 		Bitmap *wbSprite = actspswb[actspsIndex];
 
-		actspswbcache[actspsIndex].isWalkBehindHere = sort_out_walk_behinds(wbSprite, xx, yy, basel, thisroom.BgFrames[_GP(play).bg_frame].Graphic.get(), actsps[actspsIndex], zoom);
+		actspswbcache[actspsIndex].isWalkBehindHere = sort_out_walk_behinds(wbSprite, xx, yy, basel, _GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic.get(), actsps[actspsIndex], zoom);
 		actspswbcache[actspsIndex].xWas = xx;
 		actspswbcache[actspsIndex].yWas = yy;
 		actspswbcache[actspsIndex].baselineWas = basel;
@@ -1111,11 +1111,11 @@ void get_local_tint(int xpp, int ypp, int nolight,
 		}
 
 		if ((onRegion > 0) && (onRegion < MAX_ROOM_REGIONS)) {
-			light_level = thisroom.Regions[onRegion].Light;
-			tint_level = thisroom.Regions[onRegion].Tint;
+			light_level = _GP(thisroom).Regions[onRegion].Light;
+			tint_level = _GP(thisroom).Regions[onRegion].Tint;
 		} else if (onRegion <= 0) {
-			light_level = thisroom.Regions[0].Light;
-			tint_level = thisroom.Regions[0].Tint;
+			light_level = _GP(thisroom).Regions[0].Light;
+			tint_level = _GP(thisroom).Regions[0].Tint;
 		}
 
 		int tint_sat = (tint_level >> 24) & 0xFF;
@@ -1329,7 +1329,7 @@ int construct_object_gfx(int aa, int *drawnWidth, int *drawnHeight, bool alwaysU
 		zoom_level = objs[aa].zoom;
 	} else {
 		int onarea = get_walkable_area_at_location(objs[aa].x, objs[aa].y);
-		if ((onarea <= 0) && (thisroom.WalkAreas[0].ScalingFar == 0)) {
+		if ((onarea <= 0) && (_GP(thisroom).WalkAreas[0].ScalingFar == 0)) {
 			// just off the edge of an area -- use the scaling we had
 			// while on the area
 			zoom_level = objs[aa].zoom;
@@ -1485,7 +1485,7 @@ void prepare_objects_for_drawing() {
 	for (int aa = 0; aa < croom->numobj; aa++) {
 		if (objs[aa].on != 1) continue;
 		// offscreen, don't draw
-		if ((objs[aa].x >= thisroom.Width) || (objs[aa].y < 1))
+		if ((objs[aa].x >= _GP(thisroom).Width) || (objs[aa].y < 1))
 			continue;
 
 		const int useindx = aa;
@@ -1503,7 +1503,7 @@ void prepare_objects_for_drawing() {
 		if (objs[aa].flags & OBJF_NOWALKBEHINDS) {
 			// ignore walk-behinds, do nothing
 			if (walkBehindMethod == DrawAsSeparateSprite) {
-				usebasel += thisroom.Height;
+				usebasel += _GP(thisroom).Height;
 			}
 		} else if (walkBehindMethod == DrawAsSeparateCharSprite) {
 			sort_out_char_sprite_walk_behind(useindx, atxp, atyp, usebasel, objs[aa].zoom, objs[aa].last_width, objs[aa].last_height);
@@ -1631,7 +1631,7 @@ void prepare_characters_for_drawing() {
 		// calculate the zoom level
 		if (chin->flags & CHF_MANUALSCALING)  // character ignores scaling
 			zoom_level = charextra[aa].zoom;
-		else if ((onarea <= 0) && (thisroom.WalkAreas[0].ScalingFar == 0)) {
+		else if ((onarea <= 0) && (_GP(thisroom).WalkAreas[0].ScalingFar == 0)) {
 			zoom_level = charextra[aa].zoom;
 			// NOTE: room objects don't have this fix
 			if (zoom_level == 0)
@@ -1785,7 +1785,7 @@ void prepare_characters_for_drawing() {
 		if (chin->flags & CHF_NOWALKBEHINDS) {
 			// ignore walk-behinds, do nothing
 			if (walkBehindMethod == DrawAsSeparateSprite) {
-				usebasel += thisroom.Height;
+				usebasel += _GP(thisroom).Height;
 			}
 		} else if (walkBehindMethod == DrawAsSeparateCharSprite) {
 			sort_out_char_sprite_walk_behind(useindx, bgX, bgY, usebasel, charextra[aa].zoom, newwidth, newheight);
@@ -1835,10 +1835,10 @@ void prepare_room_sprites() {
 	// Note that software DDB is just a tiny wrapper around bitmap, so overhead is negligible.
 	if (roomBackgroundBmp == nullptr) {
 		update_polled_stuff_if_runtime();
-		roomBackgroundBmp = gfxDriver->CreateDDBFromBitmap(thisroom.BgFrames[_GP(play).bg_frame].Graphic.get(), false, true);
+		roomBackgroundBmp = gfxDriver->CreateDDBFromBitmap(_GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic.get(), false, true);
 	} else if (current_background_is_dirty) {
 		update_polled_stuff_if_runtime();
-		gfxDriver->UpdateDDBFromBitmap(roomBackgroundBmp, thisroom.BgFrames[_GP(play).bg_frame].Graphic.get(), false);
+		gfxDriver->UpdateDDBFromBitmap(roomBackgroundBmp, _GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic.get(), false);
 	}
 	if (gfxDriver->RequiresFullRedrawEachFrame()) {
 		if (current_background_is_dirty || walkBehindsCachedForBgNum != _GP(play).bg_frame) {
@@ -1905,7 +1905,7 @@ PBitmap draw_room_background(Viewport *view, const SpriteTransform &room_trans)
 		// the following line takes up to 50% of the game CPU time at
 		// high resolutions and colour depths - if we can optimise it
 		// somehow, significant performance gains to be had
-		update_room_invreg_and_reset(view_index, roomcam_surface, thisroom.BgFrames[_GP(play).bg_frame].Graphic.get(), draw_to_camsurf);
+		update_room_invreg_and_reset(view_index, roomcam_surface, _GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic.get(), draw_to_camsurf);
 	}
 
 	return CameraDrawData[view_index].Frame;
diff --git a/engines/ags/engine/ac/dynamicsprite.cpp b/engines/ags/engine/ac/dynamicsprite.cpp
index dc53b51714..71d2f4d3a3 100644
--- a/engines/ags/engine/ac/dynamicsprite.cpp
+++ b/engines/ags/engine/ac/dynamicsprite.cpp
@@ -51,7 +51,7 @@ using namespace Engine;
 
 
 
-extern RoomStruct thisroom;
+
 extern RoomObject *objs;
 extern RoomStatus *croom;
 extern CharacterCache *charcache;
@@ -409,7 +409,7 @@ ScriptDynamicSprite *DynamicSprite_CreateFromBackground(int frame, int x1, int y
 
 	if (frame == SCR_NO_VALUE) {
 		frame = _GP(play).bg_frame;
-	} else if ((frame < 0) || ((size_t)frame >= thisroom.BgFrameCount))
+	} else if ((frame < 0) || ((size_t)frame >= _GP(thisroom).BgFrameCount))
 		quit("!DynamicSprite.CreateFromBackground: invalid frame specified");
 
 	if (x1 == SCR_NO_VALUE) {
@@ -429,11 +429,11 @@ ScriptDynamicSprite *DynamicSprite_CreateFromBackground(int frame, int x1, int y
 		return nullptr;
 
 	// create a new sprite as a copy of the existing one
-	Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, thisroom.BgFrames[frame].Graphic->GetColorDepth());
+	Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, _GP(thisroom).BgFrames[frame].Graphic->GetColorDepth());
 	if (newPic == nullptr)
 		return nullptr;
 
-	newPic->Blit(thisroom.BgFrames[frame].Graphic.get(), x1, y1, 0, 0, width, height);
+	newPic->Blit(_GP(thisroom).BgFrames[frame].Graphic.get(), x1, y1, 0, 0, width, height);
 
 	// replace the bitmap in the sprite set
 	add_dynamic_sprite(gotSlot, newPic);
diff --git a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp
index 6c52347753..79e443c06b 100644
--- a/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp
+++ b/engines/ags/engine/ac/dynobj/scriptdrawingsurface.cpp
@@ -35,7 +35,7 @@ namespace AGS3 {
 
 using namespace AGS::Shared;
 
-extern RoomStruct thisroom;
+
 
 extern Bitmap *dynamicallyCreatedSurfaces[MAX_DYNAMIC_SURFACES];
 
@@ -43,7 +43,7 @@ extern Bitmap *dynamicallyCreatedSurfaces[MAX_DYNAMIC_SURFACES];
 Bitmap *ScriptDrawingSurface::GetBitmapSurface() {
 	// TODO: consider creating weak_ptr here, and store one in the DrawingSurface!
 	if (roomBackgroundNumber >= 0)
-		return thisroom.BgFrames[roomBackgroundNumber].Graphic.get();
+		return _GP(thisroom).BgFrames[roomBackgroundNumber].Graphic.get();
 	else if (dynamicSpriteNumber >= 0)
 		return _GP(spriteset)[dynamicSpriteNumber];
 	else if (dynamicSurfaceNumber >= 0)
@@ -51,7 +51,7 @@ Bitmap *ScriptDrawingSurface::GetBitmapSurface() {
 	else if (linkedBitmapOnly != nullptr)
 		return linkedBitmapOnly;
 	else if (roomMaskType > kRoomAreaNone)
-		return thisroom.GetMask(roomMaskType);
+		return _GP(thisroom).GetMask(roomMaskType);
 	quit("!DrawingSurface: attempted to use surface after Release was called");
 	return nullptr;
 }
diff --git a/engines/ags/engine/ac/event.cpp b/engines/ags/engine/ac/event.cpp
index b6f43b71a7..08a3c15afe 100644
--- a/engines/ags/engine/ac/event.cpp
+++ b/engines/ags/engine/ac/event.cpp
@@ -49,7 +49,7 @@ using namespace AGS::Shared;
 using namespace AGS::Engine;
 
 
-extern RoomStruct thisroom;
+
 extern RoomStatus *croom;
 extern int displayed_room;
 
@@ -115,8 +115,8 @@ void run_on_event(int evtype, RuntimeScriptValue &wparam) {
 void run_room_event(int id) {
 	evblockbasename = "room";
 
-	if (thisroom.EventHandlers != nullptr) {
-		run_interaction_script(thisroom.EventHandlers.get(), id);
+	if (_GP(thisroom).EventHandlers != nullptr) {
+		run_interaction_script(_GP(thisroom).EventHandlers.get(), id);
 	} else {
 		run_interaction_event(&croom->intrRoom, id);
 	}
@@ -172,8 +172,8 @@ void process_event(EventHappened *evp) {
 
 		if (evp->data1 == EVB_HOTSPOT) {
 
-			if (thisroom.Hotspots[evp->data2].EventHandlers != nullptr)
-				scriptPtr = thisroom.Hotspots[evp->data2].EventHandlers;
+			if (_GP(thisroom).Hotspots[evp->data2].EventHandlers != nullptr)
+				scriptPtr = _GP(thisroom).Hotspots[evp->data2].EventHandlers;
 			else
 				evpt = &croom->intrHotspot[evp->data2];
 
@@ -182,8 +182,8 @@ void process_event(EventHappened *evp) {
 			//Debug::Printf("Running hotspot interaction for hotspot %d, event %d", evp->data2, evp->data3);
 		} else if (evp->data1 == EVB_ROOM) {
 
-			if (thisroom.EventHandlers != nullptr)
-				scriptPtr = thisroom.EventHandlers;
+			if (_GP(thisroom).EventHandlers != nullptr)
+				scriptPtr = _GP(thisroom).EventHandlers;
 			else
 				evpt = &croom->intrRoom;
 
diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index d472526c93..e82cf8b649 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -153,7 +153,6 @@ extern IGraphicsDriver *gfxDriver;
 GameSetup usetup;
 RoomObject *objs;
 RoomStatus *croom = nullptr;
-RoomStruct thisroom;
 
 volatile int switching_away_from_game = 0;
 volatile bool switched_away = false;
@@ -484,7 +483,7 @@ const char *Game_GetSaveSlotDescription(int slnum) {
 
 void restore_game_dialog() {
 	can_run_delayed_command();
-	if (thisroom.Options.SaveLoadDisabled) {
+	if (_GP(thisroom).Options.SaveLoadDisabled) {
 		DisplayMessage(983);
 		return;
 	}
@@ -501,7 +500,7 @@ void restore_game_dialog() {
 }
 
 void save_game_dialog() {
-	if (thisroom.Options.SaveLoadDisabled == 1) {
+	if (_GP(thisroom).Options.SaveLoadDisabled == 1) {
 		DisplayMessage(983);
 		return;
 	}
@@ -1707,7 +1706,7 @@ int __GetLocationType(int xxx, int yyy, int allowHotspot0) {
 		return 0;
 	xxx = vpt.first.X;
 	yyy = vpt.first.Y;
-	if ((xxx >= thisroom.Width) | (xxx < 0) | (yyy < 0) | (yyy >= thisroom.Height))
+	if ((xxx >= _GP(thisroom).Width) | (xxx < 0) | (yyy < 0) | (yyy >= _GP(thisroom).Height))
 		return 0;
 
 	// check characters, objects and walkbehinds, work out which is
@@ -1718,7 +1717,7 @@ int __GetLocationType(int xxx, int yyy, int allowHotspot0) {
 
 	data_to_game_coords(&xxx, &yyy);
 
-	int wbat = thisroom.WalkBehindMask->GetPixel(xxx, yyy);
+	int wbat = _GP(thisroom).WalkBehindMask->GetPixel(xxx, yyy);
 
 	if (wbat <= 0) wbat = 0;
 	else wbat = croom->walkbehind_base[wbat];
@@ -1908,7 +1907,7 @@ void get_message_text(int msnum, char *buffer, char giveErr) {
 		buffer[0] = 0;
 		replace_tokens(get_translation(_GP(game).messages[msnum - 500]), buffer, maxlen);
 		return;
-	} else if (msnum < 0 || (size_t)msnum >= thisroom.MessageCount) {
+	} else if (msnum < 0 || (size_t)msnum >= _GP(thisroom).MessageCount) {
 		if (giveErr)
 			quit("!DisplayMessage: Invalid message number to display");
 		buffer[0] = 0;
@@ -1916,7 +1915,7 @@ void get_message_text(int msnum, char *buffer, char giveErr) {
 	}
 
 	buffer[0] = 0;
-	replace_tokens(get_translation(thisroom.Messages[msnum]), buffer, maxlen);
+	replace_tokens(get_translation(_GP(thisroom).Messages[msnum]), buffer, maxlen);
 }
 
 bool unserialize_audio_script_object(int index, const char *objectType, const char *serializedData, int dataSize) {
diff --git a/engines/ags/engine/ac/gamestate.cpp b/engines/ags/engine/ac/gamestate.cpp
index 4483c8447c..2b79f885cb 100644
--- a/engines/ags/engine/ac/gamestate.cpp
+++ b/engines/ags/engine/ac/gamestate.cpp
@@ -45,7 +45,7 @@ namespace AGS3 {
 using namespace AGS::Shared;
 using namespace AGS::Engine;
 
-extern RoomStruct thisroom;
+
 extern CharacterInfo *playerchar;
 extern ScriptSystem scsystem;
 
@@ -179,7 +179,7 @@ void GameState::UpdateRoomCameras() {
 void GameState::UpdateRoomCamera(int index) {
 	auto cam = _roomCameras[index];
 	const Rect &rc = cam->GetRect();
-	const Size real_room_sz = Size(data_to_game_coord(thisroom.Width), data_to_game_coord(thisroom.Height));
+	const Size real_room_sz = Size(data_to_game_coord(_GP(thisroom).Width), data_to_game_coord(_GP(thisroom).Height));
 	if ((real_room_sz.Width > rc.GetWidth()) || (real_room_sz.Height > rc.GetHeight())) {
 		// TODO: split out into Camera Behavior
 		if (!cam->IsLocked()) {
diff --git a/engines/ags/engine/ac/global_audio.cpp b/engines/ags/engine/ac/global_audio.cpp
index d359ca43a5..48fd8dd9df 100644
--- a/engines/ags/engine/ac/global_audio.cpp
+++ b/engines/ags/engine/ac/global_audio.cpp
@@ -44,7 +44,7 @@ using namespace AGS::Shared;
 extern GameSetup usetup;
 
 
-extern RoomStruct thisroom;
+
 extern SpeechLipSyncLine *splipsync;
 extern int numLipLines, curLipLine, curLipLinePhoneme;
 
@@ -92,7 +92,7 @@ void PlayAmbientSound(int channel, int sndnum, int vol, int x, int y) {
 	}
 	// calculate the maximum distance away the player can be, using X
 	// only (since X centred is still more-or-less total Y)
-	ambient[channel].maxdist = ((x > thisroom.Width / 2) ? x : (thisroom.Width - x)) - AMBIENCE_FULL_DIST;
+	ambient[channel].maxdist = ((x > _GP(thisroom).Width / 2) ? x : (_GP(thisroom).Width - x)) - AMBIENCE_FULL_DIST;
 	ambient[channel].num = sndnum;
 	ambient[channel].x = x;
 	ambient[channel].y = y;
@@ -322,7 +322,7 @@ int GetMP3PosMillis() {
 void SetMusicVolume(int newvol) {
 	if ((newvol < kRoomVolumeMin) || (newvol > kRoomVolumeMax))
 		quitprintf("!SetMusicVolume: invalid volume number. Must be from %d to %d.", kRoomVolumeMin, kRoomVolumeMax);
-	thisroom.Options.MusicVolume = (RoomVolumeMod)newvol;
+	_GP(thisroom).Options.MusicVolume = (RoomVolumeMod)newvol;
 	update_music_volume();
 }
 
diff --git a/engines/ags/engine/ac/global_character.cpp b/engines/ags/engine/ac/global_character.cpp
index cd35a484de..4cad7011e4 100644
--- a/engines/ags/engine/ac/global_character.cpp
+++ b/engines/ags/engine/ac/global_character.cpp
@@ -56,7 +56,7 @@ using namespace AGS::Shared;
 
 extern ViewStruct *views;
 extern RoomObject *objs;
-extern RoomStruct thisroom;
+
 
 extern ScriptObject scrObj[MAX_ROOM_OBJECTS];
 extern ScriptInvItem scrInv[MAX_INV];
@@ -346,8 +346,8 @@ void MoveCharacterToObject(int chaa, int obbj) {
 void MoveCharacterToHotspot(int chaa, int hotsp) {
 	if ((hotsp < 0) || (hotsp >= MAX_ROOM_HOTSPOTS))
 		quit("!MovecharacterToHotspot: invalid hotspot");
-	if (thisroom.Hotspots[hotsp].WalkTo.X < 1) return;
-	walk_character(chaa, thisroom.Hotspots[hotsp].WalkTo.X, thisroom.Hotspots[hotsp].WalkTo.Y, 0, true);
+	if (_GP(thisroom).Hotspots[hotsp].WalkTo.X < 1) return;
+	walk_character(chaa, _GP(thisroom).Hotspots[hotsp].WalkTo.X, _GP(thisroom).Hotspots[hotsp].WalkTo.Y, 0, true);
 
 	GameLoopUntilNotMoving(&_GP(game).chars[chaa].walking);
 }
diff --git a/engines/ags/engine/ac/global_debug.cpp b/engines/ags/engine/ac/global_debug.cpp
index 05db804e52..658fa0a0f1 100644
--- a/engines/ags/engine/ac/global_debug.cpp
+++ b/engines/ags/engine/ac/global_debug.cpp
@@ -56,7 +56,7 @@ using namespace AGS::Engine;
 
 extern GameSetup usetup;
 
-extern RoomStruct thisroom;
+
 extern CharacterInfo *playerchar;
 
 extern int convert_16bit_bgr;
@@ -113,12 +113,12 @@ void script_debug(int cmdd, int dataa) {
 		// TODO: support multiple viewports?!
 		const int viewport_index = 0;
 		const int camera_index = 0;
-		Bitmap *tempw = BitmapHelper::CreateBitmap(thisroom.WalkAreaMask->GetWidth(), thisroom.WalkAreaMask->GetHeight());
+		Bitmap *tempw = BitmapHelper::CreateBitmap(_GP(thisroom).WalkAreaMask->GetWidth(), _GP(thisroom).WalkAreaMask->GetHeight());
 		tempw->Blit(prepare_walkable_areas(-1), 0, 0, 0, 0, tempw->GetWidth(), tempw->GetHeight());
 		const Rect &viewport = _GP(play).GetRoomViewport(viewport_index)->GetRect();
 		const Rect &camera = _GP(play).GetRoomCamera(camera_index)->GetRect();
 		Bitmap *view_bmp = BitmapHelper::CreateBitmap(viewport.GetWidth(), viewport.GetHeight());
-		Rect mask_src = Rect(camera.Left / thisroom.MaskResolution, camera.Top / thisroom.MaskResolution, camera.Right / thisroom.MaskResolution, camera.Bottom / thisroom.MaskResolution);
+		Rect mask_src = Rect(camera.Left / _GP(thisroom).MaskResolution, camera.Top / _GP(thisroom).MaskResolution, camera.Right / _GP(thisroom).MaskResolution, camera.Bottom / _GP(thisroom).MaskResolution);
 		view_bmp->StretchBlt(tempw, mask_src, RectWH(0, 0, viewport.GetWidth(), viewport.GetHeight()), Shared::kBitmap_Transparency);
 
 		IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(view_bmp, false, true);
@@ -153,7 +153,7 @@ void script_debug(int cmdd, int dataa) {
 			Display("Not currently moving.");
 			return;
 		}
-		Bitmap *tempw = BitmapHelper::CreateTransparentBitmap(thisroom.WalkAreaMask->GetWidth(), thisroom.WalkAreaMask->GetHeight());
+		Bitmap *tempw = BitmapHelper::CreateTransparentBitmap(_GP(thisroom).WalkAreaMask->GetWidth(), _GP(thisroom).WalkAreaMask->GetHeight());
 		int mlsnum = _GP(game).chars[dataa].walking;
 		if (_GP(game).chars[dataa].walking >= TURNING_AROUND)
 			mlsnum %= TURNING_AROUND;
@@ -172,7 +172,7 @@ void script_debug(int cmdd, int dataa) {
 		const Rect &viewport = _GP(play).GetRoomViewport(viewport_index)->GetRect();
 		const Rect &camera = _GP(play).GetRoomCamera(camera_index)->GetRect();
 		Bitmap *view_bmp = BitmapHelper::CreateBitmap(viewport.GetWidth(), viewport.GetHeight());
-		Rect mask_src = Rect(camera.Left / thisroom.MaskResolution, camera.Top / thisroom.MaskResolution, camera.Right / thisroom.MaskResolution, camera.Bottom / thisroom.MaskResolution);
+		Rect mask_src = Rect(camera.Left / _GP(thisroom).MaskResolution, camera.Top / _GP(thisroom).MaskResolution, camera.Right / _GP(thisroom).MaskResolution, camera.Bottom / _GP(thisroom).MaskResolution);
 		view_bmp->StretchBlt(tempw, mask_src, RectWH(0, 0, viewport.GetWidth(), viewport.GetHeight()), Shared::kBitmap_Transparency);
 
 		IDriverDependantBitmap *ddb = gfxDriver->CreateDDBFromBitmap(view_bmp, false, true);
diff --git a/engines/ags/engine/ac/global_display.cpp b/engines/ags/engine/ac/global_display.cpp
index c639304db4..500e482c99 100644
--- a/engines/ags/engine/ac/global_display.cpp
+++ b/engines/ags/engine/ac/global_display.cpp
@@ -46,7 +46,7 @@ using namespace AGS::Shared;
 
 extern TopBarSettings topBar;
 
-extern RoomStruct thisroom;
+
 extern int display_message_aschar;
 
 
@@ -122,19 +122,19 @@ void DisplayMessageAtY(int msnum, int ypos) {
 	while (repeatloop) {
 		get_message_text(msnum, msgbufr);
 
-		if (thisroom.MessageInfos[msnum].DisplayAs > 0) {
-			DisplaySpeech(msgbufr, thisroom.MessageInfos[msnum].DisplayAs - 1);
+		if (_GP(thisroom).MessageInfos[msnum].DisplayAs > 0) {
+			DisplaySpeech(msgbufr, _GP(thisroom).MessageInfos[msnum].DisplayAs - 1);
 		} else {
 			// time out automatically if they have set that
 			int oldGameSkipDisp = _GP(play).skip_display;
-			if (thisroom.MessageInfos[msnum].Flags & MSG_TIMELIMIT)
+			if (_GP(thisroom).MessageInfos[msnum].Flags & MSG_TIMELIMIT)
 				_GP(play).skip_display = 0;
 
 			DisplayAtY(ypos, msgbufr);
 
 			_GP(play).skip_display = oldGameSkipDisp;
 		}
-		if (thisroom.MessageInfos[msnum].Flags & MSG_DISPLAYNEXT) {
+		if (_GP(thisroom).MessageInfos[msnum].Flags & MSG_DISPLAYNEXT) {
 			msnum++;
 			repeatloop = 1;
 		} else
diff --git a/engines/ags/engine/ac/global_drawingsurface.cpp b/engines/ags/engine/ac/global_drawingsurface.cpp
index 3e6e6ee9a1..87374d0cbc 100644
--- a/engines/ags/engine/ac/global_drawingsurface.cpp
+++ b/engines/ags/engine/ac/global_drawingsurface.cpp
@@ -44,13 +44,13 @@ using namespace AGS::Shared;
 using namespace AGS::Engine;
 
 extern Bitmap *raw_saved_screen;
-extern RoomStruct thisroom;
+
 
 
 
 
 // Raw screen writing routines - similar to old CapturedStuff
-#define RAW_START() _GP(play).raw_drawing_surface = thisroom.BgFrames[_GP(play).bg_frame].Graphic; _GP(play).raw_modified[_GP(play).bg_frame] = 1
+#define RAW_START() _GP(play).raw_drawing_surface = _GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic; _GP(play).raw_modified[_GP(play).bg_frame] = 1
 #define RAW_END()
 #define RAW_SURFACE() (_GP(play).raw_drawing_surface.get())
 
@@ -58,7 +58,7 @@ extern RoomStruct thisroom;
 void RawSaveScreen() {
 	if (raw_saved_screen != nullptr)
 		delete raw_saved_screen;
-	PBitmap source = thisroom.BgFrames[_GP(play).bg_frame].Graphic;
+	PBitmap source = _GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic;
 	raw_saved_screen = BitmapHelper::CreateBitmapCopy(source.get());
 }
 // RawRestoreScreen: copy backup bitmap back to screen; we
@@ -69,7 +69,7 @@ void RawRestoreScreen() {
 		debug_script_warn("RawRestoreScreen: unable to restore, since the screen hasn't been saved previously.");
 		return;
 	}
-	PBitmap deston = thisroom.BgFrames[_GP(play).bg_frame].Graphic;
+	PBitmap deston = _GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic;
 	deston->Blit(raw_saved_screen, 0, 0, 0, 0, deston->GetWidth(), deston->GetHeight());
 	invalidate_screen();
 	mark_current_background_dirty();
@@ -87,18 +87,18 @@ void RawRestoreScreenTinted(int red, int green, int blue, int opacity) {
 
 	debug_script_log("RawRestoreTinted RGB(%d,%d,%d) %d%%", red, green, blue, opacity);
 
-	PBitmap deston = thisroom.BgFrames[_GP(play).bg_frame].Graphic;
+	PBitmap deston = _GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic;
 	tint_image(deston.get(), raw_saved_screen, red, green, blue, opacity);
 	invalidate_screen();
 	mark_current_background_dirty();
 }
 
 void RawDrawFrameTransparent(int frame, int translev) {
-	if ((frame < 0) || ((size_t)frame >= thisroom.BgFrameCount) ||
+	if ((frame < 0) || ((size_t)frame >= _GP(thisroom).BgFrameCount) ||
 		(translev < 0) || (translev > 99))
 		quit("!RawDrawFrameTransparent: invalid parameter (transparency must be 0-99, frame a valid BG frame)");
 
-	PBitmap bg = thisroom.BgFrames[frame].Graphic;
+	PBitmap bg = _GP(thisroom).BgFrames[frame].Graphic;
 	if (bg->GetColorDepth() <= 8)
 		quit("!RawDrawFrameTransparent: 256-colour backgrounds not supported");
 
@@ -135,7 +135,7 @@ void RawSetColorRGB(int red, int grn, int blu) {
 		(blu < 0) || (blu > 255))
 		quit("!RawSetColorRGB: colour values must be 0-255");
 
-	_GP(play).raw_color = makecol_depth(thisroom.BgFrames[_GP(play).bg_frame].Graphic->GetColorDepth(), red, grn, blu);
+	_GP(play).raw_color = makecol_depth(_GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic->GetColorDepth(), red, grn, blu);
 }
 void RawPrint(int xx, int yy, const char *text) {
 	RAW_START();
@@ -267,7 +267,7 @@ void RawDrawLine(int fromx, int fromy, int tox, int toy) {
 	_GP(play).raw_modified[_GP(play).bg_frame] = 1;
 	int ii, jj;
 	// draw a line thick enough to look the same at all resolutions
-	PBitmap bg = thisroom.BgFrames[_GP(play).bg_frame].Graphic;
+	PBitmap bg = _GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic;
 	color_t draw_color = _GP(play).raw_color;
 	for (ii = 0; ii < get_fixed_pixel_size(1); ii++) {
 		for (jj = 0; jj < get_fixed_pixel_size(1); jj++)
@@ -281,7 +281,7 @@ void RawDrawCircle(int xx, int yy, int rad) {
 	rad = data_to_game_coord(rad);
 
 	_GP(play).raw_modified[_GP(play).bg_frame] = 1;
-	PBitmap bg = thisroom.BgFrames[_GP(play).bg_frame].Graphic;
+	PBitmap bg = _GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic;
 	bg->FillCircle(Circle(xx, yy, rad), _GP(play).raw_color);
 	invalidate_screen();
 	mark_current_background_dirty();
@@ -291,7 +291,7 @@ void RawDrawRectangle(int x1, int y1, int x2, int y2) {
 	data_to_game_coords(&x1, &y1);
 	data_to_game_round_up(&x2, &y2);
 
-	PBitmap bg = thisroom.BgFrames[_GP(play).bg_frame].Graphic;
+	PBitmap bg = _GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic;
 	bg->FillRect(Rect(x1, y1, x2, y2), _GP(play).raw_color);
 	invalidate_screen();
 	mark_current_background_dirty();
@@ -302,7 +302,7 @@ void RawDrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3) {
 	data_to_game_coords(&x2, &y2);
 	data_to_game_coords(&x3, &y3);
 
-	PBitmap bg = thisroom.BgFrames[_GP(play).bg_frame].Graphic;
+	PBitmap bg = _GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic;
 	bg->DrawTriangle(Triangle(x1, y1, x2, y2, x3, y3), _GP(play).raw_color);
 	invalidate_screen();
 	mark_current_background_dirty();
diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp
index 26a0520278..c22c9156b0 100644
--- a/engines/ags/engine/ac/global_game.cpp
+++ b/engines/ags/engine/ac/global_game.cpp
@@ -90,7 +90,7 @@ extern int load_new_game_restore;
 extern ViewStruct *views;
 extern RoomStatus *croom;
 extern int gui_disabled_style;
-extern RoomStruct thisroom;
+
 extern int getloctype_index;
 extern IGraphicsDriver *gfxDriver;
 extern color palette[256];
@@ -561,7 +561,7 @@ void GetLocationName(int xxx, int yyy, char *tempo) {
 		return;
 	xxx = vpt.first.X;
 	yyy = vpt.first.Y;
-	if ((xxx >= thisroom.Width) | (xxx < 0) | (yyy < 0) | (yyy >= thisroom.Height))
+	if ((xxx >= _GP(thisroom).Width) | (xxx < 0) | (yyy < 0) | (yyy >= _GP(thisroom).Height))
 		return;
 
 	int onhs, aa;
@@ -585,7 +585,7 @@ void GetLocationName(int xxx, int yyy, char *tempo) {
 	// on object
 	if (loctype == LOCTYPE_OBJ) {
 		aa = getloctype_index;
-		strcpy(tempo, get_translation(thisroom.Objects[aa].Name));
+		strcpy(tempo, get_translation(_GP(thisroom).Objects[aa].Name));
 		// Compatibility: < 3.1.1 games returned space for nameless object
 		// (presumably was a bug, but fixing it affected certain games behavior)
 		if (loaded_game_file_version < kGameVersion_311 && tempo[0] == 0) {
@@ -599,7 +599,7 @@ void GetLocationName(int xxx, int yyy, char *tempo) {
 	}
 	onhs = getloctype_index;
 	if (onhs > 0)
-		strcpy(tempo, get_translation(thisroom.Hotspots[onhs].Name));
+		strcpy(tempo, get_translation(_GP(thisroom).Hotspots[onhs].Name));
 	if (_GP(play).get_loc_name_last_time != onhs)
 		guis_need_update = 1;
 	_GP(play).get_loc_name_last_time = onhs;
@@ -900,11 +900,11 @@ void RoomProcessClick(int xx, int yy, int mood) {
 	if ((mood == MODE_WALK) && (_GP(game).options[OPT_NOWALKMODE] == 0)) {
 		int hsnum = get_hotspot_at(xx, yy);
 		if (hsnum < 1);
-		else if (thisroom.Hotspots[hsnum].WalkTo.X < 1);
+		else if (_GP(thisroom).Hotspots[hsnum].WalkTo.X < 1);
 		else if (_GP(play).auto_use_walkto_points == 0);
 		else {
-			xx = thisroom.Hotspots[hsnum].WalkTo.X;
-			yy = thisroom.Hotspots[hsnum].WalkTo.Y;
+			xx = _GP(thisroom).Hotspots[hsnum].WalkTo.X;
+			yy = _GP(thisroom).Hotspots[hsnum].WalkTo.Y;
 			debug_script_log("Move to walk-to point hotspot %d", hsnum);
 		}
 		walk_character(_GP(game).playercharacter, xx, yy, 0, true);
diff --git a/engines/ags/engine/ac/global_hotspot.cpp b/engines/ags/engine/ac/global_hotspot.cpp
index 891ecea208..69d96445bf 100644
--- a/engines/ags/engine/ac/global_hotspot.cpp
+++ b/engines/ags/engine/ac/global_hotspot.cpp
@@ -42,7 +42,7 @@ namespace AGS3 {
 
 using namespace AGS::Shared;
 
-extern RoomStruct thisroom;
+
 extern RoomStatus *croom;
 extern CharacterInfo *playerchar;
 
@@ -66,20 +66,20 @@ int GetHotspotPointX(int hotspot) {
 	if ((hotspot < 0) || (hotspot >= MAX_ROOM_HOTSPOTS))
 		quit("!GetHotspotPointX: invalid hotspot");
 
-	if (thisroom.Hotspots[hotspot].WalkTo.X < 1)
+	if (_GP(thisroom).Hotspots[hotspot].WalkTo.X < 1)
 		return -1;
 
-	return thisroom.Hotspots[hotspot].WalkTo.X;
+	return _GP(thisroom).Hotspots[hotspot].WalkTo.X;
 }
 
 int GetHotspotPointY(int hotspot) {
 	if ((hotspot < 0) || (hotspot >= MAX_ROOM_HOTSPOTS))
 		quit("!GetHotspotPointY: invalid hotspot");
 
-	if (thisroom.Hotspots[hotspot].WalkTo.X < 1) // TODO: there was "x" here, why?
+	if (_GP(thisroom).Hotspots[hotspot].WalkTo.X < 1) // TODO: there was "x" here, why?
 		return -1;
 
-	return thisroom.Hotspots[hotspot].WalkTo.Y;
+	return _GP(thisroom).Hotspots[hotspot].WalkTo.Y;
 }
 
 int GetHotspotIDAtScreen(int scrx, int scry) {
@@ -93,7 +93,7 @@ void GetHotspotName(int hotspot, char *buffer) {
 	if ((hotspot < 0) || (hotspot >= MAX_ROOM_HOTSPOTS))
 		quit("!GetHotspotName: invalid hotspot number");
 
-	strcpy(buffer, get_translation(thisroom.Hotspots[hotspot].Name));
+	strcpy(buffer, get_translation(_GP(thisroom).Hotspots[hotspot].Name));
 }
 
 void RunHotspotInteraction(int hotspothere, int mood) {
@@ -125,10 +125,10 @@ void RunHotspotInteraction(int hotspothere, int mood) {
 	evblockbasename = "hotspot%d";
 	evblocknum = hotspothere;
 
-	if (thisroom.Hotspots[hotspothere].EventHandlers != nullptr) {
+	if (_GP(thisroom).Hotspots[hotspothere].EventHandlers != nullptr) {
 		if (passon >= 0)
-			run_interaction_script(thisroom.Hotspots[hotspothere].EventHandlers.get(), passon, 5, (passon == 3));
-		run_interaction_script(thisroom.Hotspots[hotspothere].EventHandlers.get(), 5);  // any click on hotspot
+			run_interaction_script(_GP(thisroom).Hotspots[hotspothere].EventHandlers.get(), passon, 5, (passon == 3));
+		run_interaction_script(_GP(thisroom).Hotspots[hotspothere].EventHandlers.get(), 5);  // any click on hotspot
 	} else {
 		if (passon >= 0) {
 			if (run_interaction_event(&croom->intrHotspot[hotspothere], passon, 5, (passon == 3))) {
@@ -146,11 +146,11 @@ void RunHotspotInteraction(int hotspothere, int mood) {
 }
 
 int GetHotspotProperty(int hss, const char *property) {
-	return get_int_property(thisroom.Hotspots[hss].Properties, croom->hsProps[hss], property);
+	return get_int_property(_GP(thisroom).Hotspots[hss].Properties, croom->hsProps[hss], property);
 }
 
 void GetHotspotPropertyText(int item, const char *property, char *bufer) {
-	get_text_property(thisroom.Hotspots[item].Properties, croom->hsProps[item], property, bufer);
+	get_text_property(_GP(thisroom).Hotspots[item].Properties, croom->hsProps[item], property, bufer);
 }
 
 } // namespace AGS3
diff --git a/engines/ags/engine/ac/global_object.cpp b/engines/ags/engine/ac/global_object.cpp
index cbd3ec7736..c455b0562e 100644
--- a/engines/ags/engine/ac/global_object.cpp
+++ b/engines/ags/engine/ac/global_object.cpp
@@ -57,7 +57,7 @@ extern RoomObject *objs;
 extern ViewStruct *views;
 
 extern ObjectCache objcache[MAX_ROOM_OBJECTS];
-extern RoomStruct thisroom;
+
 extern CharacterInfo *playerchar;
 extern int displayed_room;
 
@@ -267,8 +267,8 @@ void MergeObject(int obn) {
 	construct_object_gfx(obn, nullptr, &theHeight, true);
 
 	//Bitmap *oldabuf = graphics->bmp;
-	//abuf = thisroom.BgFrames.Graphic[_GP(play).bg_frame];
-	PBitmap bg_frame = thisroom.BgFrames[_GP(play).bg_frame].Graphic;
+	//abuf = _GP(thisroom).BgFrames.Graphic[_GP(play).bg_frame];
+	PBitmap bg_frame = _GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic;
 	if (bg_frame->GetColorDepth() != actsps[obn]->GetColorDepth())
 		quit("!MergeObject: unable to merge object due to color depth differences");
 
@@ -372,7 +372,7 @@ void GetObjectName(int obj, char *buffer) {
 	if (!is_valid_object(obj))
 		quit("!GetObjectName: invalid object number");
 
-	strcpy(buffer, get_translation(thisroom.Objects[obj].Name));
+	strcpy(buffer, get_translation(_GP(thisroom).Objects[obj].Name));
 }
 
 void MoveObject(int objj, int xx, int yy, int spp) {
@@ -420,12 +420,12 @@ void RunObjectInteraction(int aa, int mood) {
 	evblockbasename = "object%d";
 	evblocknum = aa;
 
-	if (thisroom.Objects[aa].EventHandlers != nullptr) {
+	if (_GP(thisroom).Objects[aa].EventHandlers != nullptr) {
 		if (passon >= 0) {
-			if (run_interaction_script(thisroom.Objects[aa].EventHandlers.get(), passon, 4, (passon == 3)))
+			if (run_interaction_script(_GP(thisroom).Objects[aa].EventHandlers.get(), passon, 4, (passon == 3)))
 				return;
 		}
-		run_interaction_script(thisroom.Objects[aa].EventHandlers.get(), 4);  // any click on obj
+		run_interaction_script(_GP(thisroom).Objects[aa].EventHandlers.get(), 4);  // any click on obj
 	} else {
 		if (passon >= 0) {
 			if (run_interaction_event(&croom->intrObject[aa], passon, 4, (passon == 3)))
@@ -499,11 +499,11 @@ int AreThingsOverlapping(int thing1, int thing2) {
 int GetObjectProperty(int hss, const char *property) {
 	if (!is_valid_object(hss))
 		quit("!GetObjectProperty: invalid object");
-	return get_int_property(thisroom.Objects[hss].Properties, croom->objProps[hss], property);
+	return get_int_property(_GP(thisroom).Objects[hss].Properties, croom->objProps[hss], property);
 }
 
 void GetObjectPropertyText(int item, const char *property, char *bufer) {
-	get_text_property(thisroom.Objects[item].Properties, croom->objProps[item], property, bufer);
+	get_text_property(_GP(thisroom).Objects[item].Properties, croom->objProps[item], property, bufer);
 }
 
 Bitmap *GetObjectImage(int obj, int *isFlipped) {
diff --git a/engines/ags/engine/ac/global_region.cpp b/engines/ags/engine/ac/global_region.cpp
index 4a33d1664b..a8d69526fc 100644
--- a/engines/ags/engine/ac/global_region.cpp
+++ b/engines/ags/engine/ac/global_region.cpp
@@ -36,7 +36,7 @@ namespace AGS3 {
 
 using namespace AGS::Shared;
 
-extern RoomStruct thisroom;
+
 extern RoomStatus *croom;
 extern const char *evblockbasename;
 extern int evblocknum;
@@ -49,17 +49,17 @@ int GetRegionIDAtRoom(int xxx, int yyy) {
 	yyy = room_to_mask_coord(yyy);
 
 	if (loaded_game_file_version >= kGameVersion_262) { // Version 2.6.2+
-		if (xxx >= thisroom.RegionMask->GetWidth())
-			xxx = thisroom.RegionMask->GetWidth() - 1;
-		if (yyy >= thisroom.RegionMask->GetHeight())
-			yyy = thisroom.RegionMask->GetHeight() - 1;
+		if (xxx >= _GP(thisroom).RegionMask->GetWidth())
+			xxx = _GP(thisroom).RegionMask->GetWidth() - 1;
+		if (yyy >= _GP(thisroom).RegionMask->GetHeight())
+			yyy = _GP(thisroom).RegionMask->GetHeight() - 1;
 		if (xxx < 0)
 			xxx = 0;
 		if (yyy < 0)
 			yyy = 0;
 	}
 
-	int hsthere = thisroom.RegionMask->GetPixel(xxx, yyy);
+	int hsthere = _GP(thisroom).RegionMask->GetPixel(xxx, yyy);
 	if (hsthere <= 0 || hsthere >= MAX_ROOM_REGIONS) return 0;
 	if (croom->region_enabled[hsthere] == 0) return 0;
 	return hsthere;
@@ -70,9 +70,9 @@ void SetAreaLightLevel(int area, int brightness) {
 		quit("!SetAreaLightLevel: invalid region");
 	if (brightness < -100) brightness = -100;
 	if (brightness > 100) brightness = 100;
-	thisroom.Regions[area].Light = brightness;
+	_GP(thisroom).Regions[area].Light = brightness;
 	// disable RGB tint for this area
-	thisroom.Regions[area].Tint = 0;
+	_GP(thisroom).Regions[area].Tint = 0;
 	debug_script_log("Region %d light level set to %d", area, brightness);
 }
 
@@ -101,11 +101,11 @@ void SetRegionTint(int area, int red, int green, int blue, int amount, int lumin
 	green -= 100;
 	blue -= 100;*/
 
-	thisroom.Regions[area].Tint = (red & 0xFF) |
+	_GP(thisroom).Regions[area].Tint = (red & 0xFF) |
 		((green & 0xFF) << 8) |
 		((blue & 0XFF) << 16) |
 		((amount & 0xFF) << 24);
-	thisroom.Regions[area].Light = (luminance * 25) / 10;
+	_GP(thisroom).Regions[area].Light = (luminance * 25) / 10;
 }
 
 void DisableRegion(int hsnum) {
@@ -158,8 +158,8 @@ void RunRegionInteraction(int regnum, int mood) {
 	evblockbasename = "region%d";
 	evblocknum = regnum;
 
-	if (thisroom.Regions[regnum].EventHandlers != nullptr) {
-		run_interaction_script(thisroom.Regions[regnum].EventHandlers.get(), mood);
+	if (_GP(thisroom).Regions[regnum].EventHandlers != nullptr) {
+		run_interaction_script(_GP(thisroom).Regions[regnum].EventHandlers.get(), mood);
 	} else {
 		run_interaction_event(&croom->intrRegion[regnum], mood);
 	}
diff --git a/engines/ags/engine/ac/global_room.cpp b/engines/ags/engine/ac/global_room.cpp
index 7e489114f6..c25c0fd821 100644
--- a/engines/ags/engine/ac/global_room.cpp
+++ b/engines/ags/engine/ac/global_room.cpp
@@ -54,7 +54,7 @@ extern int in_leaves_screen;
 extern int in_inv_screen, inv_screen_newroom;
 extern MoveList *mls;
 extern int gs_to_newroom;
-extern RoomStruct thisroom;
+
 
 void SetAmbientTint(int red, int green, int blue, int opacity, int luminance) {
 	if ((red < 0) || (green < 0) || (blue < 0) ||
@@ -198,11 +198,11 @@ int HasBeenToRoom(int roomnum) {
 }
 
 void GetRoomPropertyText(const char *property, char *bufer) {
-	get_text_property(thisroom.Properties, croom->roomProps, property, bufer);
+	get_text_property(_GP(thisroom).Properties, croom->roomProps, property, bufer);
 }
 
 void SetBackgroundFrame(int frnum) {
-	if ((frnum < -1) || (frnum != -1 && (size_t)frnum >= thisroom.BgFrameCount))
+	if ((frnum < -1) || (frnum != -1 && (size_t)frnum >= _GP(thisroom).BgFrameCount))
 		quit("!SetBackgrondFrame: invalid frame number specified");
 	if (frnum < 0) {
 		_GP(play).bg_frame_locked = 0;
diff --git a/engines/ags/engine/ac/global_screen.cpp b/engines/ags/engine/ac/global_screen.cpp
index 20383bf4ae..cc4f177401 100644
--- a/engines/ags/engine/ac/global_screen.cpp
+++ b/engines/ags/engine/ac/global_screen.cpp
@@ -44,7 +44,7 @@ using namespace AGS::Engine;
 extern GameSetup usetup;
 
 
-extern RoomStruct thisroom;
+
 extern IGraphicsDriver *gfxDriver;
 extern AGSPlatformDriver *platform;
 extern color palette[256];
diff --git a/engines/ags/engine/ac/global_walkablearea.cpp b/engines/ags/engine/ac/global_walkablearea.cpp
index 0a5f2239ea..db16635ee6 100644
--- a/engines/ags/engine/ac/global_walkablearea.cpp
+++ b/engines/ags/engine/ac/global_walkablearea.cpp
@@ -33,7 +33,7 @@ namespace AGS3 {
 
 using namespace AGS::Shared;
 
-extern RoomStruct thisroom;
+
 
 
 int GetScalingAt(int x, int y) {
@@ -59,11 +59,11 @@ void SetAreaScaling(int area, int min, int max) {
 	max -= 100;
 
 	if (min == max) {
-		thisroom.WalkAreas[area].ScalingFar = min;
-		thisroom.WalkAreas[area].ScalingNear = NOT_VECTOR_SCALED;
+		_GP(thisroom).WalkAreas[area].ScalingFar = min;
+		_GP(thisroom).WalkAreas[area].ScalingNear = NOT_VECTOR_SCALED;
 	} else {
-		thisroom.WalkAreas[area].ScalingFar = min;
-		thisroom.WalkAreas[area].ScalingNear = max;
+		_GP(thisroom).WalkAreas[area].ScalingFar = min;
+		_GP(thisroom).WalkAreas[area].ScalingNear = max;
 	}
 }
 
diff --git a/engines/ags/engine/ac/gui.cpp b/engines/ags/engine/ac/gui.cpp
index d59fafada6..931e10a027 100644
--- a/engines/ags/engine/ac/gui.cpp
+++ b/engines/ags/engine/ac/gui.cpp
@@ -66,7 +66,7 @@ using namespace AGS::Engine;
 
 
 extern GameSetup usetup;
-extern RoomStruct thisroom;
+
 extern int cur_mode, cur_cursor;
 extern ccInstance *gameinst;
 extern ScriptGUI *scrGui;
diff --git a/engines/ags/engine/ac/hotspot.cpp b/engines/ags/engine/ac/hotspot.cpp
index 92f1168d01..8d855ac1a5 100644
--- a/engines/ags/engine/ac/hotspot.cpp
+++ b/engines/ags/engine/ac/hotspot.cpp
@@ -42,7 +42,7 @@ namespace AGS3 {
 
 using namespace AGS::Shared;
 
-extern RoomStruct thisroom;
+
 extern RoomStatus *croom;
 extern ScriptHotspot scrHotspot[MAX_ROOM_HOTSPOTS];
 extern CCHotspot ccDynamicHotspot;
@@ -83,7 +83,7 @@ void Hotspot_GetName(ScriptHotspot *hss, char *buffer) {
 }
 
 const char *Hotspot_GetName_New(ScriptHotspot *hss) {
-	return CreateNewScriptString(get_translation(thisroom.Hotspots[hss->id].Name));
+	return CreateNewScriptString(get_translation(_GP(thisroom).Hotspots[hss->id].Name));
 }
 
 bool Hotspot_IsInteractionAvailable(ScriptHotspot *hhot, int mood) {
@@ -100,16 +100,16 @@ void Hotspot_RunInteraction(ScriptHotspot *hss, int mood) {
 }
 
 int Hotspot_GetProperty(ScriptHotspot *hss, const char *property) {
-	return get_int_property(thisroom.Hotspots[hss->id].Properties, croom->hsProps[hss->id], property);
+	return get_int_property(_GP(thisroom).Hotspots[hss->id].Properties, croom->hsProps[hss->id], property);
 }
 
 void Hotspot_GetPropertyText(ScriptHotspot *hss, const char *property, char *bufer) {
-	get_text_property(thisroom.Hotspots[hss->id].Properties, croom->hsProps[hss->id], property, bufer);
+	get_text_property(_GP(thisroom).Hotspots[hss->id].Properties, croom->hsProps[hss->id], property, bufer);
 
 }
 
 const char *Hotspot_GetTextProperty(ScriptHotspot *hss, const char *property) {
-	return get_text_property_dynamic_string(thisroom.Hotspots[hss->id].Properties, croom->hsProps[hss->id], property);
+	return get_text_property_dynamic_string(_GP(thisroom).Hotspots[hss->id].Properties, croom->hsProps[hss->id], property);
 }
 
 bool Hotspot_SetProperty(ScriptHotspot *hss, const char *property, int value) {
@@ -121,7 +121,7 @@ bool Hotspot_SetTextProperty(ScriptHotspot *hss, const char *property, const cha
 }
 
 int get_hotspot_at(int xpp, int ypp) {
-	int onhs = thisroom.HotspotMask->GetPixel(room_to_mask_coord(xpp), room_to_mask_coord(ypp));
+	int onhs = _GP(thisroom).HotspotMask->GetPixel(room_to_mask_coord(xpp), room_to_mask_coord(ypp));
 	if (onhs <= 0 || onhs >= MAX_ROOM_HOTSPOTS) return 0;
 	if (croom->hotspot_enabled[onhs] == 0) return 0;
 	return onhs;
diff --git a/engines/ags/engine/ac/object.cpp b/engines/ags/engine/ac/object.cpp
index 82c11e417e..16964bffd6 100644
--- a/engines/ags/engine/ac/object.cpp
+++ b/engines/ags/engine/ac/object.cpp
@@ -59,7 +59,7 @@ extern ScriptObject scrObj[MAX_ROOM_OBJECTS];
 extern RoomStatus *croom;
 extern RoomObject *objs;
 extern ViewStruct *views;
-extern RoomStruct thisroom;
+
 extern ObjectCache objcache[MAX_ROOM_OBJECTS];
 extern MoveList *mls;
 
@@ -292,7 +292,7 @@ const char *Object_GetName_New(ScriptObject *objj) {
 	if (!is_valid_object(objj->id))
 		quit("!Object.Name: invalid object number");
 
-	return CreateNewScriptString(get_translation(thisroom.Objects[objj->id].Name));
+	return CreateNewScriptString(get_translation(_GP(thisroom).Objects[objj->id].Name));
 }
 
 bool Object_IsInteractionAvailable(ScriptObject *oobj, int mood) {
@@ -460,7 +460,7 @@ void Object_GetPropertyText(ScriptObject *objj, const char *property, char *bufe
 }
 
 const char *Object_GetTextProperty(ScriptObject *objj, const char *property) {
-	return get_text_property_dynamic_string(thisroom.Objects[objj->id].Properties, croom->objProps[objj->id], property);
+	return get_text_property_dynamic_string(_GP(thisroom).Objects[objj->id].Properties, croom->objProps[objj->id], property);
 }
 
 bool Object_SetProperty(ScriptObject *objj, const char *property, int value) {
diff --git a/engines/ags/engine/ac/region.cpp b/engines/ags/engine/ac/region.cpp
index a094e3267f..d7616d0504 100644
--- a/engines/ags/engine/ac/region.cpp
+++ b/engines/ags/engine/ac/region.cpp
@@ -41,7 +41,7 @@ namespace AGS3 {
 using namespace AGS::Shared;
 
 extern ScriptRegion scrRegion[MAX_ROOM_REGIONS];
-extern RoomStruct thisroom;
+
 extern RoomStatus *croom;
 
 extern COLOR_MAP maincoltable;
@@ -65,37 +65,37 @@ void Region_SetLightLevel(ScriptRegion *ssr, int brightness) {
 }
 
 int Region_GetLightLevel(ScriptRegion *ssr) {
-	return thisroom.GetRegionLightLevel(ssr->id);
+	return _GP(thisroom).GetRegionLightLevel(ssr->id);
 }
 
 int Region_GetTintEnabled(ScriptRegion *srr) {
-	if (thisroom.Regions[srr->id].Tint & 0xFF000000)
+	if (_GP(thisroom).Regions[srr->id].Tint & 0xFF000000)
 		return 1;
 	return 0;
 }
 
 int Region_GetTintRed(ScriptRegion *srr) {
 
-	return thisroom.Regions[srr->id].Tint & 0x000000ff;
+	return _GP(thisroom).Regions[srr->id].Tint & 0x000000ff;
 }
 
 int Region_GetTintGreen(ScriptRegion *srr) {
 
-	return (thisroom.Regions[srr->id].Tint >> 8) & 0x000000ff;
+	return (_GP(thisroom).Regions[srr->id].Tint >> 8) & 0x000000ff;
 }
 
 int Region_GetTintBlue(ScriptRegion *srr) {
 
-	return (thisroom.Regions[srr->id].Tint >> 16) & 0x000000ff;
+	return (_GP(thisroom).Regions[srr->id].Tint >> 16) & 0x000000ff;
 }
 
 int Region_GetTintSaturation(ScriptRegion *srr) {
 
-	return (thisroom.Regions[srr->id].Tint >> 24) & 0xFF;
+	return (_GP(thisroom).Regions[srr->id].Tint >> 24) & 0xFF;
 }
 
 int Region_GetTintLuminance(ScriptRegion *srr) {
-	return thisroom.GetRegionTintLuminance(srr->id);
+	return _GP(thisroom).GetRegionTintLuminance(srr->id);
 }
 
 void Region_Tint(ScriptRegion *srr, int red, int green, int blue, int amount, int luminance) {
diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp
index 12248ba400..b980f15fb5 100644
--- a/engines/ags/engine/ac/room.cpp
+++ b/engines/ags/engine/ac/room.cpp
@@ -139,7 +139,7 @@ ScriptDrawingSurface *Room_GetDrawingSurfaceForBackground(int backgroundNumber)
 		backgroundNumber = _GP(play).bg_frame;
 	}
 
-	if ((backgroundNumber < 0) || ((size_t)backgroundNumber >= thisroom.BgFrameCount))
+	if ((backgroundNumber < 0) || ((size_t)backgroundNumber >= _GP(thisroom).BgFrameCount))
 		quit("!Room.GetDrawingSurfaceForBackground: invalid background number specified");
 
 
@@ -163,43 +163,43 @@ int Room_GetObjectCount() {
 }
 
 int Room_GetWidth() {
-	return thisroom.Width;
+	return _GP(thisroom).Width;
 }
 
 int Room_GetHeight() {
-	return thisroom.Height;
+	return _GP(thisroom).Height;
 }
 
 int Room_GetColorDepth() {
-	return thisroom.BgFrames[0].Graphic->GetColorDepth();
+	return _GP(thisroom).BgFrames[0].Graphic->GetColorDepth();
 }
 
 int Room_GetLeftEdge() {
-	return thisroom.Edges.Left;
+	return _GP(thisroom).Edges.Left;
 }
 
 int Room_GetRightEdge() {
-	return thisroom.Edges.Right;
+	return _GP(thisroom).Edges.Right;
 }
 
 int Room_GetTopEdge() {
-	return thisroom.Edges.Top;
+	return _GP(thisroom).Edges.Top;
 }
 
 int Room_GetBottomEdge() {
-	return thisroom.Edges.Bottom;
+	return _GP(thisroom).Edges.Bottom;
 }
 
 int Room_GetMusicOnLoad() {
-	return thisroom.Options.StartupMusic;
+	return _GP(thisroom).Options.StartupMusic;
 }
 
 int Room_GetProperty(const char *property) {
-	return get_int_property(thisroom.Properties, croom->roomProps, property);
+	return get_int_property(_GP(thisroom).Properties, croom->roomProps, property);
 }
 
 const char *Room_GetTextProperty(const char *property) {
-	return get_text_property_dynamic_string(thisroom.Properties, croom->roomProps, property);
+	return get_text_property_dynamic_string(_GP(thisroom).Properties, croom->roomProps, property);
 }
 
 bool Room_SetProperty(const char *property, int value) {
@@ -211,12 +211,12 @@ bool Room_SetTextProperty(const char *property, const char *value) {
 }
 
 const char *Room_GetMessages(int index) {
-	if ((index < 0) || ((size_t)index >= thisroom.MessageCount)) {
+	if ((index < 0) || ((size_t)index >= _GP(thisroom).MessageCount)) {
 		return nullptr;
 	}
 	char buffer[STD_BUFFER_SIZE];
 	buffer[0] = 0;
-	replace_tokens(get_translation(thisroom.Messages[index]), buffer, STD_BUFFER_SIZE);
+	replace_tokens(get_translation(_GP(thisroom).Messages[index]), buffer, STD_BUFFER_SIZE);
 	return CreateNewScriptString(buffer);
 }
 
@@ -227,19 +227,19 @@ const char *Room_GetMessages(int index) {
 // in game resolution coordinates; in other words makes graphics appropriate
 // for display in the game.
 void convert_room_background_to_game_res() {
-	if (!_GP(game).AllowRelativeRes() || !thisroom.IsRelativeRes())
+	if (!_GP(game).AllowRelativeRes() || !_GP(thisroom).IsRelativeRes())
 		return;
 
-	int bkg_width = thisroom.Width;
-	int bkg_height = thisroom.Height;
+	int bkg_width = _GP(thisroom).Width;
+	int bkg_height = _GP(thisroom).Height;
 	data_to_game_coords(&bkg_width, &bkg_height);
 
-	for (size_t i = 0; i < thisroom.BgFrameCount; ++i)
-		thisroom.BgFrames[i].Graphic = FixBitmap(thisroom.BgFrames[i].Graphic, bkg_width, bkg_height);
+	for (size_t i = 0; i < _GP(thisroom).BgFrameCount; ++i)
+		_GP(thisroom).BgFrames[i].Graphic = FixBitmap(_GP(thisroom).BgFrames[i].Graphic, bkg_width, bkg_height);
 
 	// Fix walk-behinds to match room background
 	// TODO: would not we need to do similar to each mask if they were 1:1 in hires room?
-	thisroom.WalkBehindMask = FixBitmap(thisroom.WalkBehindMask, bkg_width, bkg_height);
+	_GP(thisroom).WalkBehindMask = FixBitmap(_GP(thisroom).WalkBehindMask, bkg_width, bkg_height);
 }
 
 
@@ -299,8 +299,8 @@ void unload_old_room() {
 	raw_saved_screen = nullptr;
 	for (ff = 0; ff < MAX_ROOM_BGFRAMES; ff++)
 		_GP(play).raw_modified[ff] = 0;
-	for (size_t i = 0; i < thisroom.LocalVariables.size() && i < MAX_GLOBAL_VARIABLES; ++i)
-		croom->interactionVariableValues[i] = thisroom.LocalVariables[i].Value;
+	for (size_t i = 0; i < _GP(thisroom).LocalVariables.size() && i < MAX_GLOBAL_VARIABLES; ++i)
+		croom->interactionVariableValues[i] = _GP(thisroom).LocalVariables[i].Value;
 
 	// wipe the character cache when we change rooms
 	for (ff = 0; ff < _GP(game).numcharacters; ff++) {
@@ -325,10 +325,10 @@ void unload_old_room() {
 	}
 
 	for (ff = 0; ff < MAX_ROOM_HOTSPOTS; ff++) {
-		if (thisroom.Hotspots[ff].ScriptName.IsEmpty())
+		if (_GP(thisroom).Hotspots[ff].ScriptName.IsEmpty())
 			continue;
 
-		ccRemoveExternalSymbol(thisroom.Hotspots[ff].ScriptName);
+		ccRemoveExternalSymbol(_GP(thisroom).Hotspots[ff].ScriptName);
 	}
 
 	croom_ptr_clear();
@@ -402,7 +402,7 @@ void convert_room_coordinates_to_data_res(RoomStruct *rstruc) {
 extern int convert_16bit_bgr;
 
 void update_letterbox_mode() {
-	const Size real_room_sz = Size(data_to_game_coord(thisroom.Width), data_to_game_coord(thisroom.Height));
+	const Size real_room_sz = Size(data_to_game_coord(_GP(thisroom).Width), data_to_game_coord(_GP(thisroom).Height));
 	const Rect game_frame = RectWH(_GP(game).GetGameRes());
 	Rect new_main_view = game_frame;
 	// In the original engine the letterbox feature only allowed viewports of
@@ -421,7 +421,7 @@ void update_letterbox_mode() {
 
 // Automatically reset primary room viewport and camera to match the new room size
 static void adjust_viewport_to_room() {
-	const Size real_room_sz = Size(data_to_game_coord(thisroom.Width), data_to_game_coord(thisroom.Height));
+	const Size real_room_sz = Size(data_to_game_coord(_GP(thisroom).Width), data_to_game_coord(_GP(thisroom).Height));
 	const Rect main_view = _GP(play).GetMainViewport();
 	Rect new_room_view = RectWH(Size::Clamp(real_room_sz, Size(1, 1), main_view.GetSize()));
 
@@ -475,43 +475,43 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
 
 	// load the room from disk
 	our_eip = 200;
-	thisroom.GameID = NO_GAME_ID_IN_ROOM_FILE;
-	load_room(room_filename, &thisroom, _GP(game).IsLegacyHiRes(), _GP(game).SpriteInfos);
+	_GP(thisroom).GameID = NO_GAME_ID_IN_ROOM_FILE;
+	load_room(room_filename, &_GP(thisroom), _GP(game).IsLegacyHiRes(), _GP(game).SpriteInfos);
 
-	if ((thisroom.GameID != NO_GAME_ID_IN_ROOM_FILE) &&
-	        (thisroom.GameID != _GP(game).uniqueid)) {
+	if ((_GP(thisroom).GameID != NO_GAME_ID_IN_ROOM_FILE) &&
+	        (_GP(thisroom).GameID != _GP(game).uniqueid)) {
 		quitprintf("!Unable to load '%s'. This room file is assigned to a different game.", room_filename.GetCStr());
 	}
 
-	convert_room_coordinates_to_data_res(&thisroom);
+	convert_room_coordinates_to_data_res(&_GP(thisroom));
 
 	update_polled_stuff_if_runtime();
 	our_eip = 201;
 	/*  // apparently, doing this stops volume spiking between tracks
-	if (thisroom.Options.StartupMusic>0) {
+	if (_GP(thisroom).Options.StartupMusic>0) {
 	stopmusic();
 	delay(100);
 	}*/
 
-	_GP(play).room_width = thisroom.Width;
-	_GP(play).room_height = thisroom.Height;
-	_GP(play).anim_background_speed = thisroom.BgAnimSpeed;
+	_GP(play).room_width = _GP(thisroom).Width;
+	_GP(play).room_height = _GP(thisroom).Height;
+	_GP(play).anim_background_speed = _GP(thisroom).BgAnimSpeed;
 	_GP(play).bg_anim_delay = _GP(play).anim_background_speed;
 
 	// do the palette
 	for (cc = 0; cc < 256; cc++) {
 		if (_GP(game).paluses[cc] == PAL_BACKGROUND)
-			palette[cc] = thisroom.Palette[cc];
+			palette[cc] = _GP(thisroom).Palette[cc];
 		else {
 			// copy the gamewide colours into the room palette
-			for (size_t i = 0; i < thisroom.BgFrameCount; ++i)
-				thisroom.BgFrames[i].Palette[cc] = palette[cc];
+			for (size_t i = 0; i < _GP(thisroom).BgFrameCount; ++i)
+				_GP(thisroom).BgFrames[i].Palette[cc] = palette[cc];
 		}
 	}
 
-	for (size_t i = 0; i < thisroom.BgFrameCount; ++i) {
+	for (size_t i = 0; i < _GP(thisroom).BgFrameCount; ++i) {
 		update_polled_stuff_if_runtime();
-		thisroom.BgFrames[i].Graphic = PrepareSpriteForUse(thisroom.BgFrames[i].Graphic, false);
+		_GP(thisroom).BgFrames[i].Graphic = PrepareSpriteForUse(_GP(thisroom).BgFrames[i].Graphic, false);
 	}
 
 	update_polled_stuff_if_runtime();
@@ -528,13 +528,13 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
 	// walkable_areas_temp is used by the pathfinder to generate a
 	// copy of the walkable areas - allocate it here to save time later
 	delete walkable_areas_temp;
-	walkable_areas_temp = BitmapHelper::CreateBitmap(thisroom.WalkAreaMask->GetWidth(), thisroom.WalkAreaMask->GetHeight(), 8);
+	walkable_areas_temp = BitmapHelper::CreateBitmap(_GP(thisroom).WalkAreaMask->GetWidth(), _GP(thisroom).WalkAreaMask->GetHeight(), 8);
 
 	// Make a backup copy of the walkable areas prior to
 	// any RemoveWalkableArea commands
 	delete walkareabackup;
 	// copy the walls screen
-	walkareabackup = BitmapHelper::CreateBitmapCopy(thisroom.WalkAreaMask.get());
+	walkareabackup = BitmapHelper::CreateBitmapCopy(_GP(thisroom).WalkAreaMask.get());
 
 	our_eip = 204;
 	update_polled_stuff_if_runtime();
@@ -565,52 +565,52 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
 		// since we will overwrite the actual NewInteraction structs
 		// (cos they have pointers and this might have been loaded from
 		// a save game)
-		if (thisroom.EventHandlers == nullptr) {
+		if (_GP(thisroom).EventHandlers == nullptr) {
 			// legacy interactions
-			thisroom.Interaction->CopyTimesRun(croom->intrRoom);
+			_GP(thisroom).Interaction->CopyTimesRun(croom->intrRoom);
 			for (cc = 0; cc < MAX_ROOM_HOTSPOTS; cc++)
-				thisroom.Hotspots[cc].Interaction->CopyTimesRun(croom->intrHotspot[cc]);
+				_GP(thisroom).Hotspots[cc].Interaction->CopyTimesRun(croom->intrHotspot[cc]);
 			for (cc = 0; cc < MAX_ROOM_OBJECTS; cc++)
-				thisroom.Objects[cc].Interaction->CopyTimesRun(croom->intrObject[cc]);
+				_GP(thisroom).Objects[cc].Interaction->CopyTimesRun(croom->intrObject[cc]);
 			for (cc = 0; cc < MAX_ROOM_REGIONS; cc++)
-				thisroom.Regions[cc].Interaction->CopyTimesRun(croom->intrRegion[cc]);
+				_GP(thisroom).Regions[cc].Interaction->CopyTimesRun(croom->intrRegion[cc]);
 		}
 	}
 	if (croom->beenhere == 0) {
-		croom->numobj = thisroom.ObjectCount;
+		croom->numobj = _GP(thisroom).ObjectCount;
 		croom->tsdatasize = 0;
 		for (cc = 0; cc < croom->numobj; cc++) {
-			croom->obj[cc].x = thisroom.Objects[cc].X;
-			croom->obj[cc].y = thisroom.Objects[cc].Y;
-			croom->obj[cc].num = thisroom.Objects[cc].Sprite;
-			croom->obj[cc].on = thisroom.Objects[cc].IsOn;
+			croom->obj[cc].x = _GP(thisroom).Objects[cc].X;
+			croom->obj[cc].y = _GP(thisroom).Objects[cc].Y;
+			croom->obj[cc].num = _GP(thisroom).Objects[cc].Sprite;
+			croom->obj[cc].on = _GP(thisroom).Objects[cc].IsOn;
 			croom->obj[cc].view = -1;
 			croom->obj[cc].loop = 0;
 			croom->obj[cc].frame = 0;
 			croom->obj[cc].wait = 0;
 			croom->obj[cc].transparent = 0;
 			croom->obj[cc].moving = -1;
-			croom->obj[cc].flags = thisroom.Objects[cc].Flags;
+			croom->obj[cc].flags = _GP(thisroom).Objects[cc].Flags;
 			croom->obj[cc].baseline = -1;
 			croom->obj[cc].zoom = 100;
 			croom->obj[cc].last_width = 0;
 			croom->obj[cc].last_height = 0;
 			croom->obj[cc].blocking_width = 0;
 			croom->obj[cc].blocking_height = 0;
-			if (thisroom.Objects[cc].Baseline >= 0)
-				//        croom->obj[cc].baseoffs=thisroom.Objects.Baseline[cc]-thisroom.Objects[cc].y;
-				croom->obj[cc].baseline = thisroom.Objects[cc].Baseline;
+			if (_GP(thisroom).Objects[cc].Baseline >= 0)
+				//        croom->obj[cc].baseoffs=_GP(thisroom).Objects.Baseline[cc]-_GP(thisroom).Objects[cc].y;
+				croom->obj[cc].baseline = _GP(thisroom).Objects[cc].Baseline;
 		}
 		for (size_t i = 0; i < (size_t)MAX_WALK_BEHINDS; ++i)
-			croom->walkbehind_base[i] = thisroom.WalkBehinds[i].Baseline;
+			croom->walkbehind_base[i] = _GP(thisroom).WalkBehinds[i].Baseline;
 		for (cc = 0; cc < MAX_FLAGS; cc++) croom->flagstates[cc] = 0;
 
 		/*    // we copy these structs for the Score column to work
-		croom->misccond=thisroom.misccond;
+		croom->misccond=_GP(thisroom).misccond;
 		for (cc=0;cc<MAX_ROOM_HOTSPOTS;cc++)
-		croom->hscond[cc]=thisroom.hscond[cc];
+		croom->hscond[cc]=_GP(thisroom).hscond[cc];
 		for (cc=0;cc<MAX_ROOM_OBJECTS;cc++)
-		croom->objcond[cc]=thisroom.objcond[cc];*/
+		croom->objcond[cc]=_GP(thisroom).objcond[cc];*/
 
 		for (cc = 0; cc < MAX_ROOM_HOTSPOTS; cc++) {
 			croom->hotspot_enabled[cc] = 1;
@@ -623,22 +623,22 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
 		in_new_room = 2;
 	} else {
 		// We have been here before
-		for (size_t i = 0; i < thisroom.LocalVariables.size() && i < (size_t)MAX_GLOBAL_VARIABLES; ++i)
-			thisroom.LocalVariables[i].Value = croom->interactionVariableValues[i];
+		for (size_t i = 0; i < _GP(thisroom).LocalVariables.size() && i < (size_t)MAX_GLOBAL_VARIABLES; ++i)
+			_GP(thisroom).LocalVariables[i].Value = croom->interactionVariableValues[i];
 	}
 
 	update_polled_stuff_if_runtime();
 
-	if (thisroom.EventHandlers == nullptr) {
+	if (_GP(thisroom).EventHandlers == nullptr) {
 		// legacy interactions
 		// copy interactions from room file into our temporary struct
-		croom->intrRoom = *thisroom.Interaction;
+		croom->intrRoom = *_GP(thisroom).Interaction;
 		for (cc = 0; cc < MAX_ROOM_HOTSPOTS; cc++)
-			croom->intrHotspot[cc] = *thisroom.Hotspots[cc].Interaction;
+			croom->intrHotspot[cc] = *_GP(thisroom).Hotspots[cc].Interaction;
 		for (cc = 0; cc < MAX_ROOM_OBJECTS; cc++)
-			croom->intrObject[cc] = *thisroom.Objects[cc].Interaction;
+			croom->intrObject[cc] = *_GP(thisroom).Objects[cc].Interaction;
 		for (cc = 0; cc < MAX_ROOM_REGIONS; cc++)
-			croom->intrRegion[cc] = *thisroom.Regions[cc].Interaction;
+			croom->intrRegion[cc] = *_GP(thisroom).Regions[cc].Interaction;
 	}
 
 	objs = &croom->obj[0];
@@ -651,31 +651,31 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
 
 	for (cc = 0; cc < croom->numobj; cc++) {
 		// export the object's script object
-		if (thisroom.Objects[cc].ScriptName.IsEmpty())
+		if (_GP(thisroom).Objects[cc].ScriptName.IsEmpty())
 			continue;
-		objectScriptObjNames[cc] = thisroom.Objects[cc].ScriptName;
+		objectScriptObjNames[cc] = _GP(thisroom).Objects[cc].ScriptName;
 		ccAddExternalDynamicObject(objectScriptObjNames[cc], &scrObj[cc], &ccDynamicObject);
 	}
 
 	for (cc = 0; cc < MAX_ROOM_HOTSPOTS; cc++) {
-		if (thisroom.Hotspots[cc].ScriptName.IsEmpty())
+		if (_GP(thisroom).Hotspots[cc].ScriptName.IsEmpty())
 			continue;
 
-		ccAddExternalDynamicObject(thisroom.Hotspots[cc].ScriptName, &scrHotspot[cc], &ccDynamicHotspot);
+		ccAddExternalDynamicObject(_GP(thisroom).Hotspots[cc].ScriptName, &scrHotspot[cc], &ccDynamicHotspot);
 	}
 
 	our_eip = 206;
 	/*  THIS IS DONE IN THE EDITOR NOW
-	thisroom.BgFrames.IsPaletteShared[0] = 1;
-	for (dd = 1; dd < thisroom.BgFrameCount; dd++) {
-	if (memcmp (&thisroom.BgFrames.Palette[dd][0], &palette[0], sizeof(color) * 256) == 0)
-	thisroom.BgFrames.IsPaletteShared[dd] = 1;
+	_GP(thisroom).BgFrames.IsPaletteShared[0] = 1;
+	for (dd = 1; dd < _GP(thisroom).BgFrameCount; dd++) {
+	if (memcmp (&_GP(thisroom).BgFrames.Palette[dd][0], &palette[0], sizeof(color) * 256) == 0)
+	_GP(thisroom).BgFrames.IsPaletteShared[dd] = 1;
 	else
-	thisroom.BgFrames.IsPaletteShared[dd] = 0;
+	_GP(thisroom).BgFrames.IsPaletteShared[dd] = 0;
 	}
 	// only make the first frame shared if the last is
-	if (thisroom.BgFrames.IsPaletteShared[thisroom.BgFrameCount - 1] == 0)
-	thisroom.BgFrames.IsPaletteShared[0] = 0;*/
+	if (_GP(thisroom).BgFrames.IsPaletteShared[_GP(thisroom).BgFrameCount - 1] == 0)
+	_GP(thisroom).BgFrames.IsPaletteShared[0] = 0;*/
 
 	update_polled_stuff_if_runtime();
 
@@ -725,7 +725,7 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
 
 	roominst = nullptr;
 	if (debug_flags & DBG_NOSCRIPT) ;
-	else if (thisroom.CompiledScript != nullptr) {
+	else if (_GP(thisroom).CompiledScript != nullptr) {
 		compile_room_script();
 		if (croom->tsdatasize > 0) {
 			if (croom->tsdatasize != roominst->globaldatasize)
@@ -749,43 +749,43 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
 	if ((new_room_pos > 0) & (forchar != nullptr)) {
 		if (new_room_pos >= 4000) {
 			_GP(play).entered_edge = 3;
-			forchar->y = thisroom.Edges.Top + get_fixed_pixel_size(1);
+			forchar->y = _GP(thisroom).Edges.Top + get_fixed_pixel_size(1);
 			forchar->x = new_room_pos % 1000;
-			if (forchar->x == 0) forchar->x = thisroom.Width / 2;
-			if (forchar->x <= thisroom.Edges.Left)
-				forchar->x = thisroom.Edges.Left + 3;
-			if (forchar->x >= thisroom.Edges.Right)
-				forchar->x = thisroom.Edges.Right - 3;
+			if (forchar->x == 0) forchar->x = _GP(thisroom).Width / 2;
+			if (forchar->x <= _GP(thisroom).Edges.Left)
+				forchar->x = _GP(thisroom).Edges.Left + 3;
+			if (forchar->x >= _GP(thisroom).Edges.Right)
+				forchar->x = _GP(thisroom).Edges.Right - 3;
 			forchar->loop = 0;
 		} else if (new_room_pos >= 3000) {
 			_GP(play).entered_edge = 2;
-			forchar->y = thisroom.Edges.Bottom - get_fixed_pixel_size(1);
+			forchar->y = _GP(thisroom).Edges.Bottom - get_fixed_pixel_size(1);
 			forchar->x = new_room_pos % 1000;
-			if (forchar->x == 0) forchar->x = thisroom.Width / 2;
-			if (forchar->x <= thisroom.Edges.Left)
-				forchar->x = thisroom.Edges.Left + 3;
-			if (forchar->x >= thisroom.Edges.Right)
-				forchar->x = thisroom.Edges.Right - 3;
+			if (forchar->x == 0) forchar->x = _GP(thisroom).Width / 2;
+			if (forchar->x <= _GP(thisroom).Edges.Left)
+				forchar->x = _GP(thisroom).Edges.Left + 3;
+			if (forchar->x >= _GP(thisroom).Edges.Right)
+				forchar->x = _GP(thisroom).Edges.Right - 3;
 			forchar->loop = 3;
 		} else if (new_room_pos >= 2000) {
 			_GP(play).entered_edge = 1;
-			forchar->x = thisroom.Edges.Right - get_fixed_pixel_size(1);
+			forchar->x = _GP(thisroom).Edges.Right - get_fixed_pixel_size(1);
 			forchar->y = new_room_pos % 1000;
-			if (forchar->y == 0) forchar->y = thisroom.Height / 2;
-			if (forchar->y <= thisroom.Edges.Top)
-				forchar->y = thisroom.Edges.Top + 3;
-			if (forchar->y >= thisroom.Edges.Bottom)
-				forchar->y = thisroom.Edges.Bottom - 3;
+			if (forchar->y == 0) forchar->y = _GP(thisroom).Height / 2;
+			if (forchar->y <= _GP(thisroom).Edges.Top)
+				forchar->y = _GP(thisroom).Edges.Top + 3;
+			if (forchar->y >= _GP(thisroom).Edges.Bottom)
+				forchar->y = _GP(thisroom).Edges.Bottom - 3;
 			forchar->loop = 1;
 		} else if (new_room_pos >= 1000) {
 			_GP(play).entered_edge = 0;
-			forchar->x = thisroom.Edges.Left + get_fixed_pixel_size(1);
+			forchar->x = _GP(thisroom).Edges.Left + get_fixed_pixel_size(1);
 			forchar->y = new_room_pos % 1000;
-			if (forchar->y == 0) forchar->y = thisroom.Height / 2;
-			if (forchar->y <= thisroom.Edges.Top)
-				forchar->y = thisroom.Edges.Top + 3;
-			if (forchar->y >= thisroom.Edges.Bottom)
-				forchar->y = thisroom.Edges.Bottom - 3;
+			if (forchar->y == 0) forchar->y = _GP(thisroom).Height / 2;
+			if (forchar->y <= _GP(thisroom).Edges.Top)
+				forchar->y = _GP(thisroom).Edges.Top + 3;
+			if (forchar->y >= _GP(thisroom).Edges.Bottom)
+				forchar->y = _GP(thisroom).Edges.Bottom - 3;
 			forchar->loop = 2;
 		}
 		// if starts on un-walkable area
@@ -802,11 +802,11 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
 						break;
 					}
 					int nowhere = 0;
-					if (tryleft > thisroom.Edges.Left) {
+					if (tryleft > _GP(thisroom).Edges.Left) {
 						tryleft--;
 						nowhere++;
 					}
-					if (tryright < thisroom.Edges.Right) {
+					if (tryright < _GP(thisroom).Edges.Right) {
 						tryright++;
 						nowhere++;
 					}
@@ -824,11 +824,11 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
 						break;
 					}
 					int nowhere = 0;
-					if (tryleft > thisroom.Edges.Top) {
+					if (tryleft > _GP(thisroom).Edges.Top) {
 						tryleft--;
 						nowhere++;
 					}
-					if (tryright < thisroom.Edges.Bottom) {
+					if (tryright < _GP(thisroom).Edges.Bottom) {
 						tryright++;
 						nowhere++;
 					}
@@ -841,21 +841,21 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
 	if (forchar != nullptr) {
 		_GP(play).entered_at_x = forchar->x;
 		_GP(play).entered_at_y = forchar->y;
-		if (forchar->x >= thisroom.Edges.Right)
+		if (forchar->x >= _GP(thisroom).Edges.Right)
 			_GP(play).entered_edge = 1;
-		else if (forchar->x <= thisroom.Edges.Left)
+		else if (forchar->x <= _GP(thisroom).Edges.Left)
 			_GP(play).entered_edge = 0;
-		else if (forchar->y >= thisroom.Edges.Bottom)
+		else if (forchar->y >= _GP(thisroom).Edges.Bottom)
 			_GP(play).entered_edge = 2;
-		else if (forchar->y <= thisroom.Edges.Top)
+		else if (forchar->y <= _GP(thisroom).Edges.Top)
 			_GP(play).entered_edge = 3;
 	}
-	if (thisroom.Options.StartupMusic > 0)
-		PlayMusicResetQueue(thisroom.Options.StartupMusic);
+	if (_GP(thisroom).Options.StartupMusic > 0)
+		PlayMusicResetQueue(_GP(thisroom).Options.StartupMusic);
 
 	our_eip = 208;
 	if (forchar != nullptr) {
-		if (thisroom.Options.PlayerCharOff == 0) {
+		if (_GP(thisroom).Options.PlayerCharOff == 0) {
 			forchar->on = 1;
 			enable_cursor_mode(0);
 		} else {
@@ -867,8 +867,8 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
 			_GP(play).temporarily_turned_off_character = _GP(game).playercharacter;
 		}
 		if (forchar->flags & CHF_FIXVIEW) ;
-		else if (thisroom.Options.PlayerView == 0) forchar->view = forchar->defview;
-		else forchar->view = thisroom.Options.PlayerView - 1;
+		else if (_GP(thisroom).Options.PlayerView == 0) forchar->view = forchar->defview;
+		else forchar->view = _GP(thisroom).Options.PlayerView - 1;
 		forchar->frame = 0; // make him standing
 	}
 	color_map = nullptr;
@@ -1006,7 +1006,7 @@ void check_new_room() {
 void compile_room_script() {
 	ccError = 0;
 
-	roominst = ccInstance::CreateFromScript(thisroom.CompiledScript);
+	roominst = ccInstance::CreateFromScript(_GP(thisroom).CompiledScript);
 
 	if ((ccError != 0) || (roominst == nullptr)) {
 		quitprintf("Unable to create local script: %s", ccErrorString.GetCStr());
@@ -1030,7 +1030,7 @@ void on_background_frame_change() {
 	invalidate_cached_walkbehinds();
 
 	// get the new frame's palette
-	memcpy(palette, thisroom.BgFrames[_GP(play).bg_frame].Palette, sizeof(color) * 256);
+	memcpy(palette, _GP(thisroom).BgFrames[_GP(play).bg_frame].Palette, sizeof(color) * 256);
 
 	// hi-colour, update the palette. It won't have an immediate effect
 	// but will be drawn properly when the screen fades in
@@ -1041,7 +1041,7 @@ void on_background_frame_change() {
 		return;
 
 	// Don't update the palette if it hasn't changed
-	if (thisroom.BgFrames[_GP(play).bg_frame].IsPaletteShared)
+	if (_GP(thisroom).BgFrames[_GP(play).bg_frame].IsPaletteShared)
 		return;
 
 	// 256-colours, tell it to update the palette (will actually be done as
@@ -1057,11 +1057,11 @@ void croom_ptr_clear() {
 
 
 AGS_INLINE int room_to_mask_coord(int coord) {
-	return coord * _GP(game).GetDataUpscaleMult() / thisroom.MaskResolution;
+	return coord * _GP(game).GetDataUpscaleMult() / _GP(thisroom).MaskResolution;
 }
 
 AGS_INLINE int mask_to_room_coord(int coord) {
-	return coord * thisroom.MaskResolution / _GP(game).GetDataUpscaleMult();
+	return coord * _GP(thisroom).MaskResolution / _GP(game).GetDataUpscaleMult();
 }
 
 void convert_move_path_to_room_resolution(MoveList *ml) {
@@ -1074,7 +1074,7 @@ void convert_move_path_to_room_resolution(MoveList *ml) {
 		}
 	}
 
-	if (thisroom.MaskResolution == _GP(game).GetDataUpscaleMult())
+	if (_GP(thisroom).MaskResolution == _GP(game).GetDataUpscaleMult())
 		return;
 
 	ml->fromx = mask_to_room_coord(ml->fromx);
diff --git a/engines/ags/engine/ac/room.h b/engines/ags/engine/ac/room.h
index e90fda831c..b663bca60d 100644
--- a/engines/ags/engine/ac/room.h
+++ b/engines/ags/engine/ac/room.h
@@ -76,8 +76,6 @@ struct MoveList;
 // Convert move path from room's mask resolution to room resolution
 void convert_move_path_to_room_resolution(MoveList *ml);
 
-extern AGS::Shared::RoomStruct thisroom;
-
 } // namespace AGS3
 
 #endif
diff --git a/engines/ags/engine/ac/walkablearea.cpp b/engines/ags/engine/ac/walkablearea.cpp
index 8ee8979250..817c1d2058 100644
--- a/engines/ags/engine/ac/walkablearea.cpp
+++ b/engines/ags/engine/ac/walkablearea.cpp
@@ -38,7 +38,7 @@ namespace AGS3 {
 
 using namespace AGS::Shared;
 
-extern RoomStruct thisroom;
+
 
 extern int displayed_room;
 extern RoomStatus *croom;
@@ -50,16 +50,16 @@ void redo_walkable_areas() {
 
 	// since this is an 8-bit memory bitmap, we can just use direct
 	// memory access
-	if ((!thisroom.WalkAreaMask->IsLinearBitmap()) || (thisroom.WalkAreaMask->GetColorDepth() != 8))
+	if ((!_GP(thisroom).WalkAreaMask->IsLinearBitmap()) || (_GP(thisroom).WalkAreaMask->GetColorDepth() != 8))
 		quit("Walkable areas bitmap not linear");
 
-	thisroom.WalkAreaMask->Blit(walkareabackup, 0, 0, 0, 0, thisroom.WalkAreaMask->GetWidth(), thisroom.WalkAreaMask->GetHeight());
+	_GP(thisroom).WalkAreaMask->Blit(walkareabackup, 0, 0, 0, 0, _GP(thisroom).WalkAreaMask->GetWidth(), _GP(thisroom).WalkAreaMask->GetHeight());
 
 	int hh, ww;
 	for (hh = 0; hh < walkareabackup->GetHeight(); hh++) {
-		uint8_t *walls_scanline = thisroom.WalkAreaMask->GetScanLineForWriting(hh);
+		uint8_t *walls_scanline = _GP(thisroom).WalkAreaMask->GetScanLineForWriting(hh);
 		for (ww = 0; ww < walkareabackup->GetWidth(); ww++) {
-			//      if (_GP(play).walkable_areas_on[_getpixel(thisroom.WalkAreaMask,ww,hh)]==0)
+			//      if (_GP(play).walkable_areas_on[_getpixel(_GP(thisroom).WalkAreaMask,ww,hh)]==0)
 			if (_GP(play).walkable_areas_on[walls_scanline[ww]] == 0)
 				walls_scanline[ww] = 0;
 		}
@@ -68,7 +68,7 @@ void redo_walkable_areas() {
 }
 
 int get_walkable_area_pixel(int x, int y) {
-	return thisroom.WalkAreaMask->GetPixel(room_to_mask_coord(x), room_to_mask_coord(y));
+	return _GP(thisroom).WalkAreaMask->GetPixel(room_to_mask_coord(x), room_to_mask_coord(y));
 }
 
 int get_area_scaling(int onarea, int xx, int yy) {
@@ -78,29 +78,29 @@ int get_area_scaling(int onarea, int xx, int yy) {
 	yy = room_to_mask_coord(yy);
 
 	if ((onarea >= 0) && (onarea <= MAX_WALK_AREAS) &&
-		(thisroom.WalkAreas[onarea].ScalingNear != NOT_VECTOR_SCALED)) {
+		(_GP(thisroom).WalkAreas[onarea].ScalingNear != NOT_VECTOR_SCALED)) {
 		// We have vector scaling!
 		// In case the character is off the screen, limit the Y co-ordinate
 		// to within the area range (otherwise we get silly zoom levels
 		// that cause Out Of Memory crashes)
-		if (yy > thisroom.WalkAreas[onarea].Bottom)
-			yy = thisroom.WalkAreas[onarea].Bottom;
-		if (yy < thisroom.WalkAreas[onarea].Top)
-			yy = thisroom.WalkAreas[onarea].Top;
+		if (yy > _GP(thisroom).WalkAreas[onarea].Bottom)
+			yy = _GP(thisroom).WalkAreas[onarea].Bottom;
+		if (yy < _GP(thisroom).WalkAreas[onarea].Top)
+			yy = _GP(thisroom).WalkAreas[onarea].Top;
 		// Work it all out without having to use floats
 		// Percent = ((y - top) * 100) / (areabottom - areatop)
 		// Zoom level = ((max - min) * Percent) / 100
-		if (thisroom.WalkAreas[onarea].Bottom != thisroom.WalkAreas[onarea].Top) {
-			int percent = ((yy - thisroom.WalkAreas[onarea].Top) * 100)
-				/ (thisroom.WalkAreas[onarea].Bottom - thisroom.WalkAreas[onarea].Top);
-			zoom_level = ((thisroom.WalkAreas[onarea].ScalingNear - thisroom.WalkAreas[onarea].ScalingFar) * (percent)) / 100 + thisroom.WalkAreas[onarea].ScalingFar;
+		if (_GP(thisroom).WalkAreas[onarea].Bottom != _GP(thisroom).WalkAreas[onarea].Top) {
+			int percent = ((yy - _GP(thisroom).WalkAreas[onarea].Top) * 100)
+				/ (_GP(thisroom).WalkAreas[onarea].Bottom - _GP(thisroom).WalkAreas[onarea].Top);
+			zoom_level = ((_GP(thisroom).WalkAreas[onarea].ScalingNear - _GP(thisroom).WalkAreas[onarea].ScalingFar) * (percent)) / 100 + _GP(thisroom).WalkAreas[onarea].ScalingFar;
 		} else {
 			// Special case for 1px tall walkable area: take bottom line scaling
-			zoom_level = thisroom.WalkAreas[onarea].ScalingNear;
+			zoom_level = _GP(thisroom).WalkAreas[onarea].ScalingNear;
 		}
 		zoom_level += 100;
 	} else if ((onarea >= 0) & (onarea <= MAX_WALK_AREAS))
-		zoom_level = thisroom.WalkAreas[onarea].ScalingFar + 100;
+		zoom_level = _GP(thisroom).WalkAreas[onarea].ScalingFar + 100;
 
 	if (zoom_level == 0)
 		zoom_level = 100;
@@ -146,7 +146,7 @@ int is_point_in_rect(int x, int y, int left, int top, int right, int bottom) {
 
 Bitmap *prepare_walkable_areas(int sourceChar) {
 	// copy the walkable areas to the temp bitmap
-	walkable_areas_temp->Blit(thisroom.WalkAreaMask.get(), 0, 0, 0, 0, thisroom.WalkAreaMask->GetWidth(), thisroom.WalkAreaMask->GetHeight());
+	walkable_areas_temp->Blit(_GP(thisroom).WalkAreaMask.get(), 0, 0, 0, 0, _GP(thisroom).WalkAreaMask->GetWidth(), _GP(thisroom).WalkAreaMask->GetHeight());
 	// if the character who's moving doesn't Bitmap *, don't bother checking
 	if (sourceChar < 0);
 	else if (_GP(game).chars[sourceChar].flags & CHF_NOBLOCKING)
@@ -210,12 +210,12 @@ int get_walkable_area_at_location(int xx, int yy) {
 	if (onarea < 0) {
 		// the character has walked off the edge of the screen, so stop them
 		// jumping up to full size when leaving
-		if (xx >= thisroom.Width)
-			onarea = get_walkable_area_pixel(thisroom.Width - 1, yy);
+		if (xx >= _GP(thisroom).Width)
+			onarea = get_walkable_area_pixel(_GP(thisroom).Width - 1, yy);
 		else if (xx < 0)
 			onarea = get_walkable_area_pixel(0, yy);
-		else if (yy >= thisroom.Height)
-			onarea = get_walkable_area_pixel(xx, thisroom.Height - 1);
+		else if (yy >= _GP(thisroom).Height)
+			onarea = get_walkable_area_pixel(xx, _GP(thisroom).Height - 1);
 		else if (yy < 0)
 			onarea = get_walkable_area_pixel(xx, 1);
 	}
diff --git a/engines/ags/engine/ac/walkbehind.cpp b/engines/ags/engine/ac/walkbehind.cpp
index b1f4cb484a..eeb6d33025 100644
--- a/engines/ags/engine/ac/walkbehind.cpp
+++ b/engines/ags/engine/ac/walkbehind.cpp
@@ -33,7 +33,7 @@ namespace AGS3 {
 using namespace AGS::Shared;
 using namespace AGS::Engine;
 
-extern RoomStruct thisroom;
+
 extern IGraphicsDriver *gfxDriver;
 
 
@@ -49,7 +49,7 @@ int walk_behind_baselines_changed = 0;
 
 void update_walk_behind_images() {
 	int ee, rr;
-	int bpp = (thisroom.BgFrames[_GP(play).bg_frame].Graphic->GetColorDepth() + 7) / 8;
+	int bpp = (_GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic->GetColorDepth() + 7) / 8;
 	Bitmap *wbbmp;
 	for (ee = 1; ee < MAX_WALK_BEHINDS; ee++) {
 		update_polled_stuff_if_runtime();
@@ -58,13 +58,13 @@ void update_walk_behind_images() {
 			wbbmp = BitmapHelper::CreateTransparentBitmap(
 				(walkBehindRight[ee] - walkBehindLeft[ee]) + 1,
 				(walkBehindBottom[ee] - walkBehindTop[ee]) + 1,
-				thisroom.BgFrames[_GP(play).bg_frame].Graphic->GetColorDepth());
+				_GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic->GetColorDepth());
 			int yy, startX = walkBehindLeft[ee], startY = walkBehindTop[ee];
 			for (rr = startX; rr <= walkBehindRight[ee]; rr++) {
 				for (yy = startY; yy <= walkBehindBottom[ee]; yy++) {
-					if (thisroom.WalkBehindMask->GetScanLine(yy)[rr] == ee) {
+					if (_GP(thisroom).WalkBehindMask->GetScanLine(yy)[rr] == ee) {
 						for (int ii = 0; ii < bpp; ii++)
-							wbbmp->GetScanLineForWriting(yy - startY)[(rr - startX) * bpp + ii] = thisroom.BgFrames[_GP(play).bg_frame].Graphic->GetScanLine(yy)[rr * bpp + ii];
+							wbbmp->GetScanLineForWriting(yy - startY)[(rr - startX) * bpp + ii] = _GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic->GetScanLine(yy)[rr * bpp + ii];
 					}
 				}
 			}
@@ -90,9 +90,9 @@ void recache_walk_behinds() {
 		free(walkBehindEndY);
 	}
 
-	walkBehindExists = (char *)malloc(thisroom.WalkBehindMask->GetWidth());
-	walkBehindStartY = (int *)malloc(thisroom.WalkBehindMask->GetWidth() * sizeof(int));
-	walkBehindEndY = (int *)malloc(thisroom.WalkBehindMask->GetWidth() * sizeof(int));
+	walkBehindExists = (char *)malloc(_GP(thisroom).WalkBehindMask->GetWidth());
+	walkBehindStartY = (int *)malloc(_GP(thisroom).WalkBehindMask->GetWidth() * sizeof(int));
+	walkBehindEndY = (int *)malloc(_GP(thisroom).WalkBehindMask->GetWidth() * sizeof(int));
 	noWalkBehindsAtAll = 1;
 
 	int ee, rr, tmm;
@@ -113,14 +113,14 @@ void recache_walk_behinds() {
 
 	// since this is an 8-bit memory bitmap, we can just use direct
 	// memory access
-	if ((!thisroom.WalkBehindMask->IsLinearBitmap()) || (thisroom.WalkBehindMask->GetColorDepth() != 8))
+	if ((!_GP(thisroom).WalkBehindMask->IsLinearBitmap()) || (_GP(thisroom).WalkBehindMask->GetColorDepth() != 8))
 		quit("Walk behinds bitmap not linear");
 
-	for (ee = 0; ee < thisroom.WalkBehindMask->GetWidth(); ee++) {
+	for (ee = 0; ee < _GP(thisroom).WalkBehindMask->GetWidth(); ee++) {
 		walkBehindExists[ee] = 0;
-		for (rr = 0; rr < thisroom.WalkBehindMask->GetHeight(); rr++) {
-			tmm = thisroom.WalkBehindMask->GetScanLine(rr)[ee];
-			//tmm = _getpixel(thisroom.WalkBehindMask,ee,rr);
+		for (rr = 0; rr < _GP(thisroom).WalkBehindMask->GetHeight(); rr++) {
+			tmm = _GP(thisroom).WalkBehindMask->GetScanLine(rr)[ee];
+			//tmm = _getpixel(_GP(thisroom).WalkBehindMask,ee,rr);
 			if ((tmm >= 1) && (tmm < MAX_WALK_BEHINDS)) {
 				if (!walkBehindExists[ee]) {
 					walkBehindStartY[ee] = rr;
diff --git a/engines/ags/engine/debugging/debug.cpp b/engines/ags/engine/debugging/debug.cpp
index 907fa54a18..aaf85ed7b2 100644
--- a/engines/ags/engine/debugging/debug.cpp
+++ b/engines/ags/engine/debugging/debug.cpp
@@ -58,7 +58,7 @@ using namespace AGS::Engine;
 
 extern char check_dynamic_sprites_at_exit;
 extern int displayed_room;
-extern RoomStruct thisroom;
+
 extern char pexbuf[STD_BUFFER_SIZE];
 
 
@@ -293,7 +293,7 @@ void debug_script_print(const String &msg, MessageType mt) {
 		String scriptname;
 		if (curinst->instanceof == gamescript)
 			scriptname = "G ";
-		else if (curinst->instanceof == thisroom.CompiledScript)
+		else if (curinst->instanceof == _GP(thisroom).CompiledScript)
 			scriptname = "R ";
 		else if (curinst->instanceof == dialogScriptsScript)
 			scriptname = "D ";
diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp
index bfe9b3ee07..a292e75aad 100644
--- a/engines/ags/engine/game/savegame.cpp
+++ b/engines/ags/engine/game/savegame.cpp
@@ -500,7 +500,7 @@ HSaveError DoAfterRestore(const PreservedParams &pp, const RestoredData &r_data)
 	_GP(play).gscript_timer = gstimer;
 	// restore the correct room volume (they might have modified
 	// it with SetMusicVolume)
-	thisroom.Options.MusicVolume = r_data.RoomVolume;
+	_GP(thisroom).Options.MusicVolume = r_data.RoomVolume;
 
 	Mouse::SetMoveLimit(Rect(oldx1, oldy1, oldx2, oldy2));
 
@@ -518,21 +518,21 @@ HSaveError DoAfterRestore(const PreservedParams &pp, const RestoredData &r_data)
 	if (displayed_room >= 0) {
 		for (int i = 0; i < MAX_ROOM_BGFRAMES; ++i) {
 			if (r_data.RoomBkgScene[i]) {
-				thisroom.BgFrames[i].Graphic = r_data.RoomBkgScene[i];
+				_GP(thisroom).BgFrames[i].Graphic = r_data.RoomBkgScene[i];
 			}
 		}
 
 		in_new_room = 3; // don't run "enters screen" events
 		// now that room has loaded, copy saved light levels in
 		for (size_t i = 0; i < MAX_ROOM_REGIONS; ++i) {
-			thisroom.Regions[i].Light = r_data.RoomLightLevels[i];
-			thisroom.Regions[i].Tint = r_data.RoomTintLevels[i];
+			_GP(thisroom).Regions[i].Light = r_data.RoomLightLevels[i];
+			_GP(thisroom).Regions[i].Tint = r_data.RoomTintLevels[i];
 		}
 		generate_light_table();
 
 		for (size_t i = 0; i < MAX_WALK_AREAS + 1; ++i) {
-			thisroom.WalkAreas[i].ScalingFar = r_data.RoomZoomLevels1[i];
-			thisroom.WalkAreas[i].ScalingNear = r_data.RoomZoomLevels2[i];
+			_GP(thisroom).WalkAreas[i].ScalingFar = r_data.RoomZoomLevels1[i];
+			_GP(thisroom).WalkAreas[i].ScalingNear = r_data.RoomZoomLevels2[i];
 		}
 
 		on_background_frame_change();
@@ -735,8 +735,8 @@ void DoBeforeSave() {
 			save_room_data_segment();
 
 		// Update the saved interaction variable values
-		for (size_t i = 0; i < thisroom.LocalVariables.size() && i < (size_t)MAX_GLOBAL_VARIABLES; ++i)
-			croom->interactionVariableValues[i] = thisroom.LocalVariables[i].Value;
+		for (size_t i = 0; i < _GP(thisroom).LocalVariables.size() && i < (size_t)MAX_GLOBAL_VARIABLES; ++i)
+			croom->interactionVariableValues[i] = _GP(thisroom).LocalVariables[i].Value;
 	}
 }
 
diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp
index 973292cbfc..6764897ed2 100644
--- a/engines/ags/engine/game/savegame_components.cpp
+++ b/engines/ags/engine/game/savegame_components.cpp
@@ -70,7 +70,7 @@ extern AnimatingGUIButton animbuts[MAX_ANIMATING_BUTTONS];
 extern int numAnimButs;
 extern ViewStruct *views;
 extern Bitmap *dynamicallyCreatedSurfaces[MAX_DYNAMIC_SURFACES];
-extern RoomStruct thisroom;
+
 
 extern Bitmap *raw_saved_screen;
 extern MoveList *mls;
@@ -900,7 +900,7 @@ HSaveError WriteThisRoom(PStream out) {
 	for (int i = 0; i < MAX_ROOM_BGFRAMES; ++i) {
 		out->WriteBool(_GP(play).raw_modified[i] != 0);
 		if (_GP(play).raw_modified[i])
-			serialize_bitmap(thisroom.BgFrames[i].Graphic.get(), out.get());
+			serialize_bitmap(_GP(thisroom).BgFrames[i].Graphic.get(), out.get());
 	}
 	out->WriteBool(raw_saved_screen != nullptr);
 	if (raw_saved_screen)
@@ -908,22 +908,22 @@ HSaveError WriteThisRoom(PStream out) {
 
 	// room region state
 	for (int i = 0; i < MAX_ROOM_REGIONS; ++i) {
-		out->WriteInt32(thisroom.Regions[i].Light);
-		out->WriteInt32(thisroom.Regions[i].Tint);
+		out->WriteInt32(_GP(thisroom).Regions[i].Light);
+		out->WriteInt32(_GP(thisroom).Regions[i].Tint);
 	}
 	for (int i = 0; i < MAX_WALK_AREAS + 1; ++i) {
-		out->WriteInt32(thisroom.WalkAreas[i].ScalingFar);
-		out->WriteInt32(thisroom.WalkAreas[i].ScalingNear);
+		out->WriteInt32(_GP(thisroom).WalkAreas[i].ScalingFar);
+		out->WriteInt32(_GP(thisroom).WalkAreas[i].ScalingNear);
 	}
 
 	// room object movement paths cache
-	out->WriteInt32(thisroom.ObjectCount + 1);
-	for (size_t i = 0; i < thisroom.ObjectCount + 1; ++i) {
+	out->WriteInt32(_GP(thisroom).ObjectCount + 1);
+	for (size_t i = 0; i < _GP(thisroom).ObjectCount + 1; ++i) {
 		mls[i].WriteToFile(out.get());
 	}
 
 	// room music volume
-	out->WriteInt32(thisroom.Options.MusicVolume);
+	out->WriteInt32(_GP(thisroom).Options.MusicVolume);
 
 	// persistent room's indicator
 	const bool persist = displayed_room < MAX_ROOMS;
diff --git a/engines/ags/engine/game/viewport.cpp b/engines/ags/engine/game/viewport.cpp
index c4484dd765..afd6574350 100644
--- a/engines/ags/engine/game/viewport.cpp
+++ b/engines/ags/engine/game/viewport.cpp
@@ -25,13 +25,12 @@
 #include "ags/engine/debugging/debug_log.h"
 #include "ags/shared/game/roomstruct.h"
 #include "ags/engine/game/viewport.h"
+#include "ags/globals.h"
 
 namespace AGS3 {
 
 using namespace AGS::Shared;
 
-extern RoomStruct thisroom;
-
 void Camera::SetID(int id) {
 	_id = id;
 }
@@ -45,7 +44,7 @@ const Rect &Camera::GetRect() const {
 void Camera::SetSize(const Size cam_size) {
 	// TODO: currently we don't support having camera larger than room background
 	// (or rather - looking outside of the room background); look into this later
-	const Size real_room_sz = Size(data_to_game_coord(thisroom.Width), data_to_game_coord(thisroom.Height));
+	const Size real_room_sz = Size(data_to_game_coord(_GP(thisroom).Width), data_to_game_coord(_GP(thisroom).Height));
 	Size real_size = Size::Clamp(cam_size, Size(1, 1), real_room_sz);
 
 	_position.SetWidth(real_size.Width);
@@ -62,8 +61,8 @@ void Camera::SetSize(const Size cam_size) {
 void Camera::SetAt(int x, int y) {
 	int cw = _position.GetWidth();
 	int ch = _position.GetHeight();
-	int room_width = data_to_game_coord(thisroom.Width);
-	int room_height = data_to_game_coord(thisroom.Height);
+	int room_width = data_to_game_coord(_GP(thisroom).Width);
+	int room_height = data_to_game_coord(_GP(thisroom).Height);
 	x = Math::Clamp(x, 0, room_width - cw);
 	y = Math::Clamp(y, 0, room_height - ch);
 	_position.MoveTo(Point(x, y));
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index ffdbbfbe76..f31d3badcb 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -81,7 +81,7 @@ extern int is_text_overlay;
 extern int proper_exit, our_eip;
 extern int displayed_room, starting_room, in_new_room, new_room_was;
 
-extern RoomStruct thisroom;
+
 extern int game_paused;
 extern int getloctype_index;
 extern int in_enters_screen, done_es_error;
@@ -560,13 +560,13 @@ static void check_room_edges(int numevents_was) {
 		if ((numevents == numevents_was) &&
 			((_GP(play).ground_level_areas_disabled & GLED_INTERACTION) == 0)) {
 
-			if (playerchar->x <= thisroom.Edges.Left)
+			if (playerchar->x <= _GP(thisroom).Edges.Left)
 				edgesActivated[0] = 1;
-			else if (playerchar->x >= thisroom.Edges.Right)
+			else if (playerchar->x >= _GP(thisroom).Edges.Right)
 				edgesActivated[1] = 1;
-			if (playerchar->y >= thisroom.Edges.Bottom)
+			if (playerchar->y >= _GP(thisroom).Edges.Bottom)
 				edgesActivated[2] = 1;
-			else if (playerchar->y <= thisroom.Edges.Top)
+			else if (playerchar->y <= _GP(thisroom).Edges.Top)
 				edgesActivated[3] = 1;
 
 			if ((_GP(play).entered_edge >= 0) && (_GP(play).entered_edge <= 3)) {
@@ -679,9 +679,9 @@ static void game_loop_update_background_animation() {
 	else {
 		_GP(play).bg_anim_delay = _GP(play).anim_background_speed;
 		_GP(play).bg_frame++;
-		if ((size_t)_GP(play).bg_frame >= thisroom.BgFrameCount)
+		if ((size_t)_GP(play).bg_frame >= _GP(thisroom).BgFrameCount)
 			_GP(play).bg_frame = 0;
-		if (thisroom.BgFrameCount >= 2) {
+		if (_GP(thisroom).BgFrameCount >= 2) {
 			// get the new frame's palette
 			on_background_frame_change();
 		}
diff --git a/engines/ags/engine/main/quit.cpp b/engines/ags/engine/main/quit.cpp
index f3ff6848ea..f7972a68e6 100644
--- a/engines/ags/engine/main/quit.cpp
+++ b/engines/ags/engine/main/quit.cpp
@@ -56,7 +56,7 @@ using namespace AGS::Engine;
 
 
 
-extern RoomStruct thisroom;
+
     // used for non-saveable rooms, eg. intro
 extern int our_eip;
 extern GameSetup usetup;
@@ -179,7 +179,7 @@ void quit_message_on_exit(const char *qmsg, String &alertis, QuitReason qreason)
 
 void quit_release_data() {
 	resetRoomStatuses();
-	thisroom.Free();
+	_GP(thisroom).Free();
 	_GP(play).Free();
 
 	/*  _CrtMemState memstart;
diff --git a/engines/ags/engine/main/update.cpp b/engines/ags/engine/main/update.cpp
index b1b913af9e..739a690470 100644
--- a/engines/ags/engine/main/update.cpp
+++ b/engines/ags/engine/main/update.cpp
@@ -57,7 +57,7 @@ using namespace AGS::Engine;
 extern MoveList *mls;
 extern RoomStatus *croom;
 
-extern RoomStruct thisroom;
+
 extern RoomObject *objs;
 extern ViewStruct *views;
 extern int our_eip;
@@ -213,10 +213,10 @@ void update_shadow_areas() {
 	if (onwalkarea < 0);
 	else if (playerchar->flags & CHF_FIXVIEW);
 	else {
-		onwalkarea = thisroom.WalkAreas[onwalkarea].Light;
+		onwalkarea = _GP(thisroom).WalkAreas[onwalkarea].Light;
 		if (onwalkarea > 0) playerchar->view = onwalkarea - 1;
-		else if (thisroom.Options.PlayerView == 0) playerchar->view = playerchar->defview;
-		else playerchar->view = thisroom.Options.PlayerView - 1;
+		else if (_GP(thisroom).Options.PlayerView == 0) playerchar->view = playerchar->defview;
+		else playerchar->view = _GP(thisroom).Options.PlayerView - 1;
 	}
 }
 
diff --git a/engines/ags/engine/media/audio/audio.cpp b/engines/ags/engine/media/audio/audio.cpp
index fdaaa9f6da..5f1523c6e9 100644
--- a/engines/ags/engine/media/audio/audio.cpp
+++ b/engines/ags/engine/media/audio/audio.cpp
@@ -105,7 +105,7 @@ void set_clip_to_channel(int chanid, SOUNDCLIP *clip) {
 volatile bool _audio_doing_crossfade;
 
 extern GameSetup usetup;
-extern RoomStruct thisroom;
+
 extern CharacterInfo *playerchar;
 
 extern volatile int switching_away_from_game;
@@ -788,7 +788,7 @@ void play_next_queued() {
 
 int calculate_max_volume() {
 	// quieter so that sounds can be heard better
-	int newvol = _GP(play).music_master_volume + ((int)thisroom.Options.MusicVolume) * LegacyRoomVolumeFactor;
+	int newvol = _GP(play).music_master_volume + ((int)_GP(thisroom).Options.MusicVolume) * LegacyRoomVolumeFactor;
 	if (newvol > 255) newvol = 255;
 	if (newvol < 0) newvol = 0;
 
diff --git a/engines/ags/engine/script/script.cpp b/engines/ags/engine/script/script.cpp
index a47f45888a..defd59ba55 100644
--- a/engines/ags/engine/script/script.cpp
+++ b/engines/ags/engine/script/script.cpp
@@ -488,7 +488,7 @@ String GetScriptName(ccInstance *sci) {
 		return "Not in a script";
 	else if (sci->instanceof == gamescript)
 		return "Global script";
-	else if (sci->instanceof == thisroom.CompiledScript)
+	else if (sci->instanceof == _GP(thisroom).CompiledScript)
 		return String::FromFormat("Room %d script", displayed_room);
 	return "Unknown script";
 }
@@ -615,8 +615,8 @@ int get_nivalue(InteractionCommandList *nic, int idx, int parm) {
 
 InteractionVariable *get_interaction_variable(int varindx) {
 
-	if ((varindx >= LOCAL_VARIABLE_OFFSET) && ((size_t)varindx < LOCAL_VARIABLE_OFFSET + thisroom.LocalVariables.size()))
-		return &thisroom.LocalVariables[varindx - LOCAL_VARIABLE_OFFSET];
+	if ((varindx >= LOCAL_VARIABLE_OFFSET) && ((size_t)varindx < LOCAL_VARIABLE_OFFSET + _GP(thisroom).LocalVariables.size()))
+		return &_GP(thisroom).LocalVariables[varindx - LOCAL_VARIABLE_OFFSET];
 
 	if ((varindx < 0) || (varindx >= numGlobalVars))
 		quit("!invalid interaction variable specified");
@@ -630,9 +630,9 @@ InteractionVariable *FindGraphicalVariable(const char *varName) {
 		if (ags_stricmp(globalvars[ii].Name, varName) == 0)
 			return &globalvars[ii];
 	}
-	for (size_t i = 0; i < thisroom.LocalVariables.size(); ++i) {
-		if (ags_stricmp(thisroom.LocalVariables[i].Name, varName) == 0)
-			return &thisroom.LocalVariables[i];
+	for (size_t i = 0; i < _GP(thisroom).LocalVariables.size(); ++i) {
+		if (ags_stricmp(_GP(thisroom).LocalVariables[i].Name, varName) == 0)
+			return &_GP(thisroom).LocalVariables[i];
 	}
 	return nullptr;
 }
diff --git a/engines/ags/globals.cpp b/engines/ags/globals.cpp
index 31d4143c7e..0c6890bded 100644
--- a/engines/ags/globals.cpp
+++ b/engines/ags/globals.cpp
@@ -23,6 +23,7 @@
 #include "ags/globals.h"
 #include "ags/shared/ac/gamesetupstruct.h"
 #include "ags/shared/ac/spritecache.h"
+#include "ags/shared/game/roomstruct.h"
 #include "ags/engine/ac/gamestate.h"
 #include "ags/engine/ac/roomstatus.h"
 
@@ -38,6 +39,7 @@ Globals::Globals() {
 	_play = new GameState();
 	_game = new GameSetupStruct();
 	_spriteset = new SpriteCache(_game->SpriteInfos);
+	_thisroom = new AGS::Shared::RoomStruct();
 	_troom = new RoomStatus();
 }
 
@@ -46,6 +48,7 @@ Globals::~Globals() {
 	delete _game;
 	delete _play;
 	delete _spriteset;
+	delete _thisroom;
 	delete _troom;
 }
 
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index 238ff5822a..3bd6cb75df 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -37,6 +37,7 @@ using Version = AGS::Shared::Version;
 namespace AGS {
 namespace Shared {
 class Bitmap;
+class RoomStruct;
 } // namespace Shared
 } // namespace AGS
 
@@ -78,10 +79,11 @@ public:
 	 * @{
 	 */
 
-	GameSetupStruct *_game = nullptr;
-	GameState *_play = nullptr;
-	SpriteCache *_spriteset = nullptr;
-	RoomStatus *_troom = nullptr; // used for non-saveable rooms, eg. intro
+	GameSetupStruct *_game;
+	GameState *_play;
+	SpriteCache *_spriteset;
+	AGS::Shared::RoomStruct *_thisroom;
+	RoomStatus *_troom; // used for non-saveable rooms, eg. intro
 
 	 /**@}*/
 
diff --git a/engines/ags/plugins/agsplugin.cpp b/engines/ags/plugins/agsplugin.cpp
index b3d31aaca2..1da80d0632 100644
--- a/engines/ags/plugins/agsplugin.cpp
+++ b/engines/ags/plugins/agsplugin.cpp
@@ -88,7 +88,7 @@ using namespace AGS::Engine;
 
 extern IGraphicsDriver *gfxDriver;
 extern int displayed_room;
-extern RoomStruct thisroom;
+
 
 extern RoomStatus *croom;
 
@@ -290,13 +290,13 @@ int IAGSEngine::GetCurrentRoom() {
 	return displayed_room;
 }
 int IAGSEngine::GetNumBackgrounds() {
-	return thisroom.BgFrameCount;
+	return _GP(thisroom).BgFrameCount;
 }
 int IAGSEngine::GetCurrentBackground() {
 	return _GP(play).bg_frame;
 }
 BITMAP *IAGSEngine::GetBackgroundScene(int32 index) {
-	return (BITMAP *)thisroom.BgFrames[index].Graphic->GetAllegroBitmap();
+	return (BITMAP *)_GP(thisroom).BgFrames[index].Graphic->GetAllegroBitmap();
 }
 void IAGSEngine::GetBitmapDimensions(BITMAP *bmp, int32 *width, int32 *height, int32 *coldepth) {
 	if (bmp == nullptr)
@@ -488,13 +488,13 @@ BITMAP *IAGSEngine::GetSpriteGraphic(int32 num) {
 }
 BITMAP *IAGSEngine::GetRoomMask(int32 index) {
 	if (index == MASK_WALKABLE)
-		return (BITMAP *)thisroom.WalkAreaMask->GetAllegroBitmap();
+		return (BITMAP *)_GP(thisroom).WalkAreaMask->GetAllegroBitmap();
 	else if (index == MASK_WALKBEHIND)
-		return (BITMAP *)thisroom.WalkBehindMask->GetAllegroBitmap();
+		return (BITMAP *)_GP(thisroom).WalkBehindMask->GetAllegroBitmap();
 	else if (index == MASK_HOTSPOT)
-		return (BITMAP *)thisroom.HotspotMask->GetAllegroBitmap();
+		return (BITMAP *)_GP(thisroom).HotspotMask->GetAllegroBitmap();
 	else if (index == MASK_REGIONS)
-		return (BITMAP *)thisroom.RegionMask->GetAllegroBitmap();
+		return (BITMAP *)_GP(thisroom).RegionMask->GetAllegroBitmap();
 	else
 		quit("!IAGSEngine::GetRoomMask: invalid mask requested");
 	return nullptr;


Commit: 887472c8c1a93b8512bfdb5f173bac35c348c79e
    https://github.com/scummvm/scummvm/commit/887472c8c1a93b8512bfdb5f173bac35c348c79e
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-02-28T13:27:21-08:00

Commit Message:
AGS: Moved a lot of game.cpp globals to Globals

Changed paths:
    engines/ags/engine/ac/audiochannel.cpp
    engines/ags/engine/ac/audioclip.cpp
    engines/ags/engine/ac/button.cpp
    engines/ags/engine/ac/character.cpp
    engines/ags/engine/ac/character.h
    engines/ags/engine/ac/characterinfo_engine.cpp
    engines/ags/engine/ac/dialog.cpp
    engines/ags/engine/ac/dialog.h
    engines/ags/engine/ac/dialogoptionsrendering.cpp
    engines/ags/engine/ac/display.cpp
    engines/ags/engine/ac/draw.cpp
    engines/ags/engine/ac/drawingsurface.cpp
    engines/ags/engine/ac/dynamicsprite.cpp
    engines/ags/engine/ac/dynobj/cc_dialog.cpp
    engines/ags/engine/ac/dynobj/cc_gui.cpp
    engines/ags/engine/ac/dynobj/cc_guiobject.cpp
    engines/ags/engine/ac/dynobj/cc_hotspot.cpp
    engines/ags/engine/ac/dynobj/cc_inventory.cpp
    engines/ags/engine/ac/dynobj/cc_object.cpp
    engines/ags/engine/ac/dynobj/cc_region.cpp
    engines/ags/engine/ac/dynobj/cc_serializer.cpp
    engines/ags/engine/ac/dynobj/scripthotspot.h
    engines/ags/engine/ac/dynobj/scriptinvitem.h
    engines/ags/engine/ac/dynobj/scriptobject.h
    engines/ags/engine/ac/dynobj/scriptregion.h
    engines/ags/engine/ac/file.cpp
    engines/ags/engine/ac/game.cpp
    engines/ags/engine/ac/global_api.cpp
    engines/ags/engine/ac/global_button.cpp
    engines/ags/engine/ac/global_character.cpp
    engines/ags/engine/ac/global_debug.cpp
    engines/ags/engine/ac/global_game.cpp
    engines/ags/engine/ac/global_gui.cpp
    engines/ags/engine/ac/global_inventoryitem.cpp
    engines/ags/engine/ac/global_label.cpp
    engines/ags/engine/ac/global_object.cpp
    engines/ags/engine/ac/global_room.cpp
    engines/ags/engine/ac/global_slider.cpp
    engines/ags/engine/ac/global_textbox.cpp
    engines/ags/engine/ac/global_viewframe.cpp
    engines/ags/engine/ac/gui.cpp
    engines/ags/engine/ac/guicontrol.cpp
    engines/ags/engine/ac/hotspot.cpp
    engines/ags/engine/ac/inventoryitem.cpp
    engines/ags/engine/ac/invwindow.cpp
    engines/ags/engine/ac/label.cpp
    engines/ags/engine/ac/listbox.cpp
    engines/ags/engine/ac/mouse.cpp
    engines/ags/engine/ac/object.cpp
    engines/ags/engine/ac/objectcache.h
    engines/ags/engine/ac/overlay.cpp
    engines/ags/engine/ac/parser.cpp
    engines/ags/engine/ac/properties.cpp
    engines/ags/engine/ac/region.cpp
    engines/ags/engine/ac/room.cpp
    engines/ags/engine/ac/roomobject.cpp
    engines/ags/engine/ac/route_finder_impl.cpp
    engines/ags/engine/ac/route_finder_impl_legacy.cpp
    engines/ags/engine/ac/scriptcontainers.cpp
    engines/ags/engine/ac/string.cpp
    engines/ags/engine/ac/system.cpp
    engines/ags/engine/ac/textbox.cpp
    engines/ags/engine/ac/viewframe.cpp
    engines/ags/engine/game/game_init.cpp
    engines/ags/engine/game/savegame.cpp
    engines/ags/engine/game/savegame_components.cpp
    engines/ags/engine/main/engine.cpp
    engines/ags/engine/main/engine_setup.cpp
    engines/ags/engine/main/game_file.cpp
    engines/ags/engine/main/game_run.cpp
    engines/ags/engine/main/update.cpp
    engines/ags/engine/script/cc_instance.cpp
    engines/ags/globals.cpp
    engines/ags/globals.h
    engines/ags/plugins/agsplugin.cpp
    engines/ags/shared/game/main_game_file.cpp
    engines/ags/shared/gui/guimain.h


diff --git a/engines/ags/engine/ac/audiochannel.cpp b/engines/ags/engine/ac/audiochannel.cpp
index 105d5cb050..33ba0c2257 100644
--- a/engines/ags/engine/ac/audiochannel.cpp
+++ b/engines/ags/engine/ac/audiochannel.cpp
@@ -40,7 +40,7 @@ using namespace AGS::Shared;
 
 
 
-extern CCAudioClip ccDynamicAudioClip;
+
 
 int AudioChannel_GetID(ScriptAudioChannel *channel) {
 	return channel->id;
@@ -229,7 +229,7 @@ RuntimeScriptValue Sc_AudioChannel_SetPanning(void *self, const RuntimeScriptVal
 
 // ScriptAudioClip* | ScriptAudioChannel *channel
 RuntimeScriptValue Sc_AudioChannel_GetPlayingClip(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ(ScriptAudioChannel, ScriptAudioClip, ccDynamicAudioClip, AudioChannel_GetPlayingClip);
+	API_OBJCALL_OBJ(ScriptAudioChannel, ScriptAudioClip, _GP(ccDynamicAudioClip), AudioChannel_GetPlayingClip);
 }
 
 // int | ScriptAudioChannel *channel
diff --git a/engines/ags/engine/ac/audioclip.cpp b/engines/ags/engine/ac/audioclip.cpp
index 545a45f85d..85ecff1395 100644
--- a/engines/ags/engine/ac/audioclip.cpp
+++ b/engines/ags/engine/ac/audioclip.cpp
@@ -28,12 +28,11 @@
 #include "ags/engine/script/script_runtime.h"
 #include "ags/engine/ac/dynobj/cc_audiochannel.h"
 #include "ags/engine/media/audio/audio_system.h"
+#include "ags/globals.h"
 
 namespace AGS3 {
 
-
 extern ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1];
-extern CCAudioChannel ccDynamicAudio;
 
 int AudioClip_GetID(ScriptAudioClip *clip) {
 	return clip->id;
@@ -111,17 +110,17 @@ RuntimeScriptValue Sc_AudioClip_Stop(void *self, const RuntimeScriptValue *param
 
 // ScriptAudioChannel* | ScriptAudioClip *clip, int priority, int repeat
 RuntimeScriptValue Sc_AudioClip_Play(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ_PINT2(ScriptAudioClip, ScriptAudioChannel, ccDynamicAudio, AudioClip_Play);
+	API_OBJCALL_OBJ_PINT2(ScriptAudioClip, ScriptAudioChannel, _GP(ccDynamicAudio), AudioClip_Play);
 }
 
 // ScriptAudioChannel* | ScriptAudioClip *clip, int position, int priority, int repeat
 RuntimeScriptValue Sc_AudioClip_PlayFrom(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ_PINT3(ScriptAudioClip, ScriptAudioChannel, ccDynamicAudio, AudioClip_PlayFrom);
+	API_OBJCALL_OBJ_PINT3(ScriptAudioClip, ScriptAudioChannel, _GP(ccDynamicAudio), AudioClip_PlayFrom);
 }
 
 // ScriptAudioChannel* | ScriptAudioClip *clip, int priority, int repeat
 RuntimeScriptValue Sc_AudioClip_PlayQueued(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ_PINT2(ScriptAudioClip, ScriptAudioChannel, ccDynamicAudio, AudioClip_PlayQueued);
+	API_OBJCALL_OBJ_PINT2(ScriptAudioClip, ScriptAudioChannel, _GP(ccDynamicAudio), AudioClip_PlayQueued);
 }
 
 void RegisterAudioClipAPI() {
diff --git a/engines/ags/engine/ac/button.cpp b/engines/ags/engine/ac/button.cpp
index 06a7d39a5b..59b358c101 100644
--- a/engines/ags/engine/ac/button.cpp
+++ b/engines/ags/engine/ac/button.cpp
@@ -41,8 +41,6 @@ namespace AGS3 {
 
 using namespace AGS::Shared;
 
-extern ViewStruct *views;
-
 // *** BUTTON FUNCTIONS
 
 AnimatingGUIButton animbuts[MAX_ANIMATING_BUTTONS];
@@ -56,7 +54,7 @@ void Button_Animate(GUIButton *butt, int view, int loop, int speed, int repeat)
 		quit("!AnimateButton: invalid view specified");
 	view--;
 
-	if ((loop < 0) || (loop >= views[view].numLoops))
+	if ((loop < 0) || (loop >= _G(views)[view].numLoops))
 		quit("!AnimateButton: invalid loop specified for view");
 
 	// if it's already animating, stop it
@@ -65,7 +63,7 @@ void Button_Animate(GUIButton *butt, int view, int loop, int speed, int repeat)
 	if (numAnimButs >= MAX_ANIMATING_BUTTONS)
 		quit("!AnimateButton: too many animating GUI buttons at once");
 
-	int buttonId = guis[guin].GetControlID(objn);
+	int buttonId = _GP(guis)[guin].GetControlID(objn);
 
 	guibuts[buttonId].PushedImage = 0;
 	guibuts[buttonId].MouseOverImage = 0;
@@ -206,7 +204,7 @@ int UpdateAnimatingButton(int bu) {
 		animbuts[bu].wait--;
 		return 0;
 	}
-	ViewStruct *tview = &views[animbuts[bu].view];
+	ViewStruct *tview = &_G(views)[animbuts[bu].view];
 
 	animbuts[bu].frame++;
 
@@ -305,7 +303,7 @@ void Button_SetTextAlignment(GUIButton *butt, int align) {
 //
 //=============================================================================
 
-extern ScriptString myScriptStringImpl;
+
 
 // void | GUIButton *butt, int view, int loop, int speed, int repeat
 RuntimeScriptValue Sc_Button_Animate(void *self, const RuntimeScriptValue *params, int32_t param_count) {
@@ -314,7 +312,7 @@ RuntimeScriptValue Sc_Button_Animate(void *self, const RuntimeScriptValue *param
 
 // const char* | GUIButton *butt
 RuntimeScriptValue Sc_Button_GetText_New(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ(GUIButton, const char, myScriptStringImpl, Button_GetText_New);
+	API_CONST_OBJCALL_OBJ(GUIButton, const char, _GP(myScriptStringImpl), Button_GetText_New);
 }
 
 // void | GUIButton *butt, char *buffer
diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp
index f0f717214e..52f411b6e5 100644
--- a/engines/ags/engine/ac/character.cpp
+++ b/engines/ags/engine/ac/character.cpp
@@ -81,10 +81,10 @@ using namespace AGS::Shared;
 
 extern int displayed_room, starting_room;
 
-extern MoveList *mls;
-extern ViewStruct *views;
+
+
 extern RoomObject *objs;
-extern ScriptInvItem scrInv[MAX_INV];
+
 extern Bitmap *walkable_areas_temp;
 extern IGraphicsDriver *gfxDriver;
 extern Bitmap **actsps;
@@ -92,8 +92,8 @@ extern int is_text_overlay;
 extern int said_speech_line;
 extern int said_text;
 extern int our_eip;
-extern CCCharacter ccDynamicCharacter;
-extern CCInventory ccDynamicInv;
+
+
 
 //--------------------------------
 
@@ -180,7 +180,7 @@ void Character_AddWaypoint(CharacterInfo *chaa, int x, int y) {
 		return;
 	}
 
-	MoveList *cmls = &mls[chaa->walking % TURNING_AROUND];
+	MoveList *cmls = &_G(mls)[chaa->walking % TURNING_AROUND];
 	if (cmls->numstage >= MAXNEEDSTAGES) {
 		debug_script_warn("Character_AddWaypoint: move is too complex, cannot add any further paths");
 		return;
@@ -332,7 +332,7 @@ enum DirectionalLoop {
 DirectionalLoop GetDirectionalLoop(CharacterInfo *chinfo, int x_diff, int y_diff) {
 	DirectionalLoop next_loop = kDirLoop_Left; // NOTE: default loop was Left for some reason
 
-	const ViewStruct &chview  = views[chinfo->view];
+	const ViewStruct &chview  = _G(views)[chinfo->view];
 	const bool new_version    = loaded_game_file_version > kGameVersion_272;
 	const bool has_down_loop  = ((chview.numLoops > kDirLoop_Down)  && (chview.loops[kDirLoop_Down].numFrames > 0));
 	const bool has_up_loop    = ((chview.numLoops > kDirLoop_Up)    && (chview.loops[kDirLoop_Up].numFrames > 0));
@@ -618,17 +618,17 @@ void Character_LockViewAlignedEx(CharacterInfo *chap, int vii, int loop, int ali
 	if (chap->view < 0)
 		quit("!SetCharacterLoop: character has invalid old view number");
 
-	int sppic = views[chap->view].loops[chap->loop].frames[chap->frame].pic;
+	int sppic = _G(views)[chap->view].loops[chap->loop].frames[chap->frame].pic;
 	int leftSide = data_to_game_coord(chap->x) - _GP(game).SpriteInfos[sppic].Width / 2;
 
 	Character_LockViewEx(chap, vii, stopMoving);
 
-	if ((loop < 0) || (loop >= views[chap->view].numLoops))
+	if ((loop < 0) || (loop >= _G(views)[chap->view].numLoops))
 		quit("!SetCharacterViewEx: invalid loop specified");
 
 	chap->loop = loop;
 	chap->frame = 0;
-	int newpic = views[chap->view].loops[chap->loop].frames[chap->frame].pic;
+	int newpic = _G(views)[chap->view].loops[chap->loop].frames[chap->frame].pic;
 	int newLeft = data_to_game_coord(chap->x) - _GP(game).SpriteInfos[newpic].Width / 2;
 	int xdiff = 0;
 
@@ -654,9 +654,9 @@ void Character_LockViewFrameEx(CharacterInfo *chaa, int view, int loop, int fram
 	Character_LockViewEx(chaa, view, stopMoving);
 
 	view--;
-	if ((loop < 0) || (loop >= views[view].numLoops))
+	if ((loop < 0) || (loop >= _G(views)[view].numLoops))
 		quit("!SetCharacterFrame: invalid loop specified");
-	if ((frame < 0) || (frame >= views[view].loops[loop].numFrames))
+	if ((frame < 0) || (frame >= _G(views)[view].loops[loop].numFrames))
 		quit("!SetCharacterFrame: invalid frame specified");
 
 	chaa->loop = loop;
@@ -926,7 +926,7 @@ void Character_StopMoving(CharacterInfo *charp) {
 	}
 	if ((charp->walking > 0) && (charp->walking < TURNING_AROUND)) {
 		// if it's not a MoveCharDirect, make sure they end up on a walkable area
-		if ((mls[charp->walking].direct == 0) && (charp->room == displayed_room))
+		if ((_G(mls)[charp->walking].direct == 0) && (charp->room == displayed_room))
 			Character_PlaceOnWalkableArea(charp);
 
 		debug_script_log("%s: stop moving", charp->scrname);
@@ -980,7 +980,7 @@ void Character_UnlockViewEx(CharacterInfo *chaa, int stopMoving) {
 		Character_StopMoving(chaa);
 	}
 	if (chaa->view >= 0) {
-		int maxloop = views[chaa->view].numLoops;
+		int maxloop = _G(views)[chaa->view].numLoops;
 		if (((chaa->flags & CHF_NODIAGONAL) != 0) && (maxloop > 4))
 			maxloop = 4;
 		FindReasonableLoopForCharacter(chaa);
@@ -1068,7 +1068,7 @@ ScriptInvItem *Character_GetActiveInventory(CharacterInfo *chaa) {
 	if (chaa->activeinv <= 0)
 		return nullptr;
 
-	return &scrInv[chaa->activeinv];
+	return &_G(scrInv)[chaa->activeinv];
 }
 
 void Character_SetActiveInventory(CharacterInfo *chaa, ScriptInvItem *iit) {
@@ -1335,12 +1335,12 @@ int Character_GetLoop(CharacterInfo *chaa) {
 }
 
 void Character_SetLoop(CharacterInfo *chaa, int newval) {
-	if ((newval < 0) || (newval >= views[chaa->view].numLoops))
+	if ((newval < 0) || (newval >= _G(views)[chaa->view].numLoops))
 		quit("!Character.Loop: invalid loop number for this view");
 
 	chaa->loop = newval;
 
-	if (chaa->frame >= views[chaa->view].loops[chaa->loop].numFrames)
+	if (chaa->frame >= _G(views)[chaa->view].loops[chaa->loop].numFrames)
 		chaa->frame = 0;
 }
 
@@ -1352,7 +1352,7 @@ int Character_GetMoving(CharacterInfo *chaa) {
 
 int Character_GetDestinationX(CharacterInfo *chaa) {
 	if (chaa->walking) {
-		MoveList *cmls = &mls[chaa->walking % TURNING_AROUND];
+		MoveList *cmls = &_G(mls)[chaa->walking % TURNING_AROUND];
 		return cmls->pos[cmls->numstage - 1] >> 16;
 	} else
 		return chaa->x;
@@ -1360,7 +1360,7 @@ int Character_GetDestinationX(CharacterInfo *chaa) {
 
 int Character_GetDestinationY(CharacterInfo *chaa) {
 	if (chaa->walking) {
-		MoveList *cmls = &mls[chaa->walking % TURNING_AROUND];
+		MoveList *cmls = &_G(mls)[chaa->walking % TURNING_AROUND];
 		return cmls->pos[cmls->numstage - 1] & 0xFFFF;
 	} else
 		return chaa->y;
@@ -1667,8 +1667,8 @@ void walk_character(int chac, int tox, int toy, int ignwal, bool autoWalkAnims)
 	set_color_depth(_GP(game).GetColorDepth());
 	if (mslot > 0) {
 		chin->walking = mslot;
-		mls[mslot].direct = ignwal;
-		convert_move_path_to_room_resolution(&mls[mslot]);
+		_G(mls)[mslot].direct = ignwal;
+		convert_move_path_to_room_resolution(&_G(mls)[mslot]);
 
 		// cancel any pending waits on current animations
 		// or if they were already moving, keep the current wait -
@@ -1678,8 +1678,8 @@ void walk_character(int chac, int tox, int toy, int ignwal, bool autoWalkAnims)
 			chin->walkwait = waitWas;
 			charextra[chac].animwait = animWaitWas;
 
-			if (mls[mslot].pos[0] != mls[mslot].pos[1]) {
-				fix_player_sprite(&mls[mslot], chin);
+			if (_G(mls)[mslot].pos[0] != _G(mls)[mslot].pos[1]) {
+				fix_player_sprite(&_G(mls)[mslot], chin);
 			}
 		} else
 			chin->flags |= CHF_MOVENOTWALK;
@@ -1698,11 +1698,11 @@ int find_looporder_index(int curloop) {
 
 // returns 0 to use diagonal, 1 to not
 int useDiagonal(CharacterInfo *char1) {
-	if ((views[char1->view].numLoops < 8) || ((char1->flags & CHF_NODIAGONAL) != 0))
+	if ((_G(views)[char1->view].numLoops < 8) || ((char1->flags & CHF_NODIAGONAL) != 0))
 		return 1;
 	// If they have just provided standing frames for loops 4-7, to
 	// provide smoother turning
-	if (views[char1->view].loops[4].numFrames < 2)
+	if (_G(views)[char1->view].loops[4].numFrames < 2)
 		return 2;
 	return 0;
 }
@@ -1711,9 +1711,9 @@ int useDiagonal(CharacterInfo *char1) {
 int hasUpDownLoops(CharacterInfo *char1) {
 	// if no loops in the Down animation
 	// or no loops in the Up animation
-	if ((views[char1->view].loops[0].numFrames < 1) ||
-	        (views[char1->view].numLoops < 4) ||
-	        (views[char1->view].loops[3].numFrames < 1)) {
+	if ((_G(views)[char1->view].loops[0].numFrames < 1) ||
+	        (_G(views)[char1->view].numLoops < 4) ||
+	        (_G(views)[char1->view].loops[3].numFrames < 1)) {
 		return 0;
 	}
 
@@ -1751,9 +1751,9 @@ void start_character_turning(CharacterInfo *chinf, int useloop, int no_diagonal)
 			break;
 		if ((turnlooporder[ii] >= 4) && (no_diagonal > 0))
 			continue;
-		if (views[chinf->view].loops[turnlooporder[ii]].numFrames < 1)
+		if (_G(views)[chinf->view].loops[turnlooporder[ii]].numFrames < 1)
 			continue;
-		if (turnlooporder[ii] < views[chinf->view].numLoops)
+		if (turnlooporder[ii] < _G(views)[chinf->view].numLoops)
 			chinf->walking += TURNING_AROUND;
 	}
 
@@ -1779,8 +1779,8 @@ void fix_player_sprite(MoveList *cmls, CharacterInfo *chinf) {
 		chinf->loop = useloop;
 		return;
 	}
-	if ((chinf->loop >= views[chinf->view].numLoops) ||
-	        (views[chinf->view].loops[chinf->loop].numFrames < 1) ||
+	if ((chinf->loop >= _G(views)[chinf->view].numLoops) ||
+	        (_G(views)[chinf->view].loops[chinf->loop].numFrames < 1) ||
 	        (hasUpDownLoops(chinf) == 0)) {
 		// Character is not currently on a valid loop, so don't try to rotate
 		// eg. left/right only view, but current loop 0
@@ -1823,7 +1823,7 @@ int doNextCharMoveStep(CharacterInfo *chi, int &char_index, CharacterExtras *che
 
 	if (do_movelist_move(&chi->walking, &chi->x, &chi->y) == 2) {
 		if ((chi->flags & CHF_MOVENOTWALK) == 0)
-			fix_player_sprite(&mls[chi->walking], chi);
+			fix_player_sprite(&_G(mls)[chi->walking], chi);
 	}
 
 	ntf = has_hit_another_character(char_index);
@@ -1842,8 +1842,8 @@ int doNextCharMoveStep(CharacterInfo *chi, int &char_index, CharacterExtras *che
 		}
 
 		if ((chi->walking < 1) || (chi->walking >= TURNING_AROUND)) ;
-		else if (mls[chi->walking].onpart > 0) {
-			mls[chi->walking].onpart --;
+		else if (_G(mls)[chi->walking].onpart > 0) {
+			_G(mls)[chi->walking].onpart --;
 			chi->x = xwas;
 			chi->y = ywas;
 		}
@@ -1927,15 +1927,15 @@ void find_nearest_walkable_area(int32_t *xx, int32_t *yy) {
 
 void FindReasonableLoopForCharacter(CharacterInfo *chap) {
 
-	if (chap->loop >= views[chap->view].numLoops)
+	if (chap->loop >= _G(views)[chap->view].numLoops)
 		chap->loop = kDirLoop_Default;
-	if (views[chap->view].numLoops < 1)
+	if (_G(views)[chap->view].numLoops < 1)
 		quitprintf("!View %d does not have any loops", chap->view + 1);
 
 	// if the current loop has no frames, find one that does
-	if (views[chap->view].loops[chap->loop].numFrames < 1) {
-		for (int i = 0; i < views[chap->view].numLoops; i++) {
-			if (views[chap->view].loops[i].numFrames > 0) {
+	if (_G(views)[chap->view].loops[chap->loop].numFrames < 1) {
+		for (int i = 0; i < _G(views)[chap->view].numLoops; i++) {
+			if (_G(views)[chap->view].loops[i].numFrames > 0) {
 				chap->loop = i;
 				break;
 			}
@@ -2047,7 +2047,7 @@ void setup_player_character(int charid) {
 	playerchar = &_GP(game).chars[charid];
 	_sc_PlayerCharPtr = ccGetObjectHandleFromAddress((char *)playerchar);
 	if (loaded_game_file_version < kGameVersion_270) {
-		ccAddExternalDynamicObject("player", playerchar, &ccDynamicCharacter);
+		ccAddExternalDynamicObject("player", playerchar, &_GP(ccDynamicCharacter));
 	}
 }
 
@@ -2064,9 +2064,9 @@ void animate_character(CharacterInfo *chap, int loopn, int sppd, int rept, int n
 		Character_UnlockView(chap);
 		chap->idleleft = chap->idletime;
 	}
-	if ((loopn < 0) || (loopn >= views[chap->view].numLoops))
+	if ((loopn < 0) || (loopn >= _G(views)[chap->view].numLoops))
 		quit("!AnimateCharacter: invalid loop number specified");
-	if ((sframe < 0) || (sframe >= views[chap->view].loops[loopn].numFrames))
+	if ((sframe < 0) || (sframe >= _G(views)[chap->view].loops[loopn].numFrames))
 		quit("!AnimateCharacter: invalid starting frame number specified");
 	Character_StopMoving(chap);
 	chap->animating = 1;
@@ -2079,11 +2079,11 @@ void animate_character(CharacterInfo *chap, int loopn, int sppd, int rept, int n
 	if (direction) {
 		sframe--;
 		if (sframe < 0)
-			sframe = views[chap->view].loops[loopn].numFrames - (-sframe);
+			sframe = _G(views)[chap->view].loops[loopn].numFrames - (-sframe);
 	}
 	chap->frame = sframe;
 
-	chap->wait = sppd + views[chap->view].loops[loopn].frames[chap->frame].speed;
+	chap->wait = sppd + _G(views)[chap->view].loops[loopn].frames[chap->frame].speed;
 	CheckViewFrameForCharacter(chap);
 }
 
@@ -2118,7 +2118,7 @@ Bitmap *GetCharacterImage(int charid, int *isFlipped) {
 		}
 	}
 	CharacterInfo *chin = &_GP(game).chars[charid];
-	int sppic = views[chin->view].loops[chin->loop].frames[chin->frame].pic;
+	int sppic = _G(views)[chin->view].loops[chin->loop].frames[chin->frame].pic;
 	return _GP(spriteset)[sppic];
 }
 
@@ -2148,12 +2148,12 @@ int is_pos_on_character(int xx, int yy) {
 		CharacterInfo *chin = &_GP(game).chars[cc];
 
 		if ((chin->view < 0) ||
-		        (chin->loop >= views[chin->view].numLoops) ||
-		        (chin->frame >= views[chin->view].loops[chin->loop].numFrames)) {
+		        (chin->loop >= _G(views)[chin->view].numLoops) ||
+		        (chin->frame >= _G(views)[chin->view].loops[chin->loop].numFrames)) {
 			continue;
 		}
 
-		sppic = views[chin->view].loops[chin->loop].frames[chin->frame].pic;
+		sppic = _G(views)[chin->view].loops[chin->loop].frames[chin->frame].pic;
 		int usewid = charextra[cc].width;
 		int usehit = charextra[cc].height;
 		if (usewid == 0) usewid = _GP(game).SpriteInfos[sppic].Width;
@@ -2161,7 +2161,7 @@ int is_pos_on_character(int xx, int yy) {
 		int xxx = chin->x - game_to_data_coord(usewid) / 2;
 		int yyy = chin->get_effective_y() - game_to_data_coord(usehit);
 
-		int mirrored = views[chin->view].loops[chin->loop].frames[chin->frame].flags & VFLG_FLIPSPRITE;
+		int mirrored = _G(views)[chin->view].loops[chin->loop].frames[chin->frame].flags & VFLG_FLIPSPRITE;
 		Bitmap *theImage = GetCharacterImage(cc, &mirrored);
 
 		if (is_pos_in_sprite(xx, yy, xxx, yyy, theImage,
@@ -2424,12 +2424,12 @@ void _displayspeech(const char *texx, int aschar, int xx, int yy, int widd, int
 			charFrameWas = speakingChar->frame;
 
 		// if the current loop doesn't exist in talking view, use loop 0
-		if (speakingChar->loop >= views[speakingChar->view].numLoops)
+		if (speakingChar->loop >= _G(views)[speakingChar->view].numLoops)
 			speakingChar->loop = 0;
 
 		if ((speakingChar->view < 0) ||
-		        (speakingChar->loop >= views[speakingChar->view].numLoops) ||
-		        (views[speakingChar->view].loops[speakingChar->loop].numFrames < 1)) {
+		        (speakingChar->loop >= _G(views)[speakingChar->view].numLoops) ||
+		        (_G(views)[speakingChar->view].loops[speakingChar->loop].numFrames < 1)) {
 			quitprintf("Unable to display speech because the character %s has an invalid view frame (View %d, loop %d, frame %d)", speakingChar->scrname, speakingChar->view + 1, speakingChar->loop, speakingChar->frame);
 		}
 
@@ -2444,7 +2444,7 @@ void _displayspeech(const char *texx, int aschar, int xx, int yy, int widd, int
 		tdxp = -tdxp;  // tell it to centre it ([ikm] not sure what's going on here... wrong comment?)
 
 		if (tdyp < 0) {
-			int sppic = views[speakingChar->view].loops[speakingChar->loop].frames[0].pic;
+			int sppic = _G(views)[speakingChar->view].loops[speakingChar->loop].frames[0].pic;
 			int height = (charextra[aschar].height < 1) ? _GP(game).SpriteInfos[sppic].Height : charextra[aschar].height;
 			tdyp = view->RoomToScreen(0, data_to_game_coord(_GP(game).chars[aschar].get_effective_y()) - height).first.Y
 			       - get_fixed_pixel_size(5);
@@ -2526,7 +2526,7 @@ void _displayspeech(const char *texx, int aschar, int xx, int yy, int widd, int
 
 
 			int bigx = 0, bigy = 0, kk;
-			ViewStruct *viptr = &views[useview];
+			ViewStruct *viptr = &_G(views)[useview];
 			for (kk = 0; kk < viptr->loops[0].numFrames; kk++) {
 				int tw = _GP(game).SpriteInfos[viptr->loops[0].frames[kk].pic].Width;
 				if (tw > bigx) bigx = tw;
@@ -2661,7 +2661,7 @@ void _displayspeech(const char *texx, int aschar, int xx, int yy, int widd, int
 			speakingChar->frame = 0;
 			speakingChar->flags |= CHF_FIXVIEW;
 
-			if (speakingChar->loop >= views[speakingChar->view].numLoops) {
+			if (speakingChar->loop >= _G(views)[speakingChar->view].numLoops) {
 				// current character loop is outside the normal talking directions
 				speakingChar->loop = 0;
 			}
@@ -2669,14 +2669,14 @@ void _displayspeech(const char *texx, int aschar, int xx, int yy, int widd, int
 			facetalkBlinkLoop = speakingChar->loop;
 
 			if (speakingChar->on && // don't bother checking if character is not visible (also fixes 'Trilby's Notes' legacy game)
-			        ((speakingChar->loop >= views[speakingChar->view].numLoops) ||
-			         (views[speakingChar->view].loops[speakingChar->loop].numFrames < 1))) {
+			        ((speakingChar->loop >= _G(views)[speakingChar->view].numLoops) ||
+			         (_G(views)[speakingChar->view].loops[speakingChar->loop].numFrames < 1))) {
 				quitprintf("!Unable to display speech because the character %s has an invalid speech view (View %d, loop %d, frame %d)", speakingChar->scrname, speakingChar->view + 1, speakingChar->loop, speakingChar->frame);
 			}
 
 			// set up the speed of the first frame
 			speakingChar->wait = GetCharacterSpeechAnimationDelay(speakingChar) +
-			                     views[speakingChar->view].loops[speakingChar->loop].frames[0].speed;
+			                     _G(views)[speakingChar->view].loops[speakingChar->loop].frames[0].speed;
 
 			if (widd < 0) {
 				bwidth = ui_view.GetWidth() / 2 + ui_view.GetWidth() / 6;
@@ -2801,11 +2801,11 @@ int update_lip_sync(int talkview, int talkloop, int *talkframeptr) {
 		talkframe = 0;
 	else {
 		talkframe = GetLipSyncFrame(nowsaying, &text_lips_offset);
-		if (talkframe >= views[talkview].loops[talkloop].numFrames)
+		if (talkframe >= _G(views)[talkview].loops[talkloop].numFrames)
 			talkframe = 0;
 	}
 
-	talkwait = loops_per_character + views[talkview].loops[talkloop].frames[talkframe].speed;
+	talkwait = loops_per_character + _G(views)[talkview].loops[talkloop].frames[talkframe].speed;
 
 	talkframeptr[0] = talkframe;
 	return talkwait;
@@ -2816,7 +2816,7 @@ Rect GetCharacterRoomBBox(int charid, bool use_frame_0) {
 	const CharacterExtras &chex = charextra[charid];
 	const CharacterInfo &chin = _GP(game).chars[charid];
 	int frame = use_frame_0 ? 0 : chin.frame;
-	int pic = views[chin.view].loops[chin.loop].frames[frame].pic;
+	int pic = _G(views)[chin.view].loops[chin.loop].frames[frame].pic;
 	scale_sprite_size(pic, chex.zoom, &width, &height);
 	return RectWH(chin.x - width / 2, chin.y - height, width, height);
 }
@@ -2850,7 +2850,7 @@ PViewport FindNearestViewport(int charid) {
 //
 //=============================================================================
 
-extern ScriptString myScriptStringImpl;
+
 
 // void | CharacterInfo *chaa, ScriptInvItem *invi, int addIndex
 RuntimeScriptValue Sc_Character_AddInventory(void *self, const RuntimeScriptValue *params, int32_t param_count) {
@@ -2927,7 +2927,7 @@ RuntimeScriptValue Sc_Character_GetPropertyText(void *self, const RuntimeScriptV
 
 // const char* (CharacterInfo *chaa, const char *property)
 RuntimeScriptValue Sc_Character_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ_POBJ(CharacterInfo, const char, myScriptStringImpl, Character_GetTextProperty, const char);
+	API_CONST_OBJCALL_OBJ_POBJ(CharacterInfo, const char, _GP(myScriptStringImpl), Character_GetTextProperty, const char);
 }
 
 RuntimeScriptValue Sc_Character_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) {
@@ -3138,17 +3138,17 @@ RuntimeScriptValue Sc_Character_WalkStraight(void *self, const RuntimeScriptValu
 }
 
 RuntimeScriptValue Sc_GetCharacterAtRoom(const RuntimeScriptValue *params, int32_t param_count) {
-	API_SCALL_OBJ_PINT2(CharacterInfo, ccDynamicCharacter, GetCharacterAtRoom);
+	API_SCALL_OBJ_PINT2(CharacterInfo, _GP(ccDynamicCharacter), GetCharacterAtRoom);
 }
 
 // CharacterInfo *(int xx, int yy)
 RuntimeScriptValue Sc_GetCharacterAtScreen(const RuntimeScriptValue *params, int32_t param_count) {
-	API_SCALL_OBJ_PINT2(CharacterInfo, ccDynamicCharacter, GetCharacterAtScreen);
+	API_SCALL_OBJ_PINT2(CharacterInfo, _GP(ccDynamicCharacter), GetCharacterAtScreen);
 }
 
 // ScriptInvItem* (CharacterInfo *chaa)
 RuntimeScriptValue Sc_Character_GetActiveInventory(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ(CharacterInfo, ScriptInvItem, ccDynamicInv, Character_GetActiveInventory);
+	API_OBJCALL_OBJ(CharacterInfo, ScriptInvItem, _GP(ccDynamicInv), Character_GetActiveInventory);
 }
 
 // void (CharacterInfo *chaa, ScriptInvItem* iit)
@@ -3361,7 +3361,7 @@ RuntimeScriptValue Sc_Character_GetDestinationY(void *self, const RuntimeScriptV
 
 // const char* (CharacterInfo *chaa)
 RuntimeScriptValue Sc_Character_GetName(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ(CharacterInfo, const char, myScriptStringImpl, Character_GetName);
+	API_CONST_OBJCALL_OBJ(CharacterInfo, const char, _GP(myScriptStringImpl), Character_GetName);
 }
 
 // void (CharacterInfo *chaa, const char *newName)
diff --git a/engines/ags/engine/ac/character.h b/engines/ags/engine/ac/character.h
index 41aba50dc2..b21ff4206a 100644
--- a/engines/ags/engine/ac/character.h
+++ b/engines/ags/engine/ac/character.h
@@ -221,7 +221,7 @@ PViewport FindNearestViewport(int charid);
 
 extern CharacterInfo *playerchar;
 extern CharacterExtras *charextra;
-extern MoveList *mls;
+
 extern int32_t _sc_PlayerCharPtr;
 
 // order of loops to turn character in circle from down to down
diff --git a/engines/ags/engine/ac/characterinfo_engine.cpp b/engines/ags/engine/ac/characterinfo_engine.cpp
index 6d79208a07..f0b546bd90 100644
--- a/engines/ags/engine/ac/characterinfo_engine.cpp
+++ b/engines/ags/engine/ac/characterinfo_engine.cpp
@@ -41,7 +41,7 @@ namespace AGS3 {
 
 using namespace AGS::Shared;
 
-extern ViewStruct *views;
+
 
 extern int displayed_room;
 
@@ -86,7 +86,7 @@ void CharacterInfo::UpdateMoveAndAnim(int &char_index, CharacterExtras *chex, in
 
 	// Make sure it doesn't flash up a blue cup
 	if (view < 0);
-	else if (loop >= views[view].numLoops)
+	else if (loop >= _G(views)[view].numLoops)
 		loop = 0;
 
 	int doing_nothing = 1;
@@ -138,8 +138,8 @@ int CharacterInfo::update_character_walking(CharacterExtras *chex) {
 					wantloop = 0;
 				if (wantloop < 0)
 					wantloop = 7;
-				if ((turnlooporder[wantloop] >= views[view].numLoops) ||
-					(views[view].loops[turnlooporder[wantloop]].numFrames < 1) ||
+				if ((turnlooporder[wantloop] >= _G(views)[view].numLoops) ||
+					(_G(views)[view].loops[turnlooporder[wantloop]].numFrames < 1) ||
 					((turnlooporder[wantloop] >= 4) && ((flags & CHF_NODIAGONAL) != 0))) {
 					if (walking >= TURNING_BACKWARDS)
 						wantloop--;
@@ -203,11 +203,11 @@ void CharacterInfo::update_character_moving(int &char_index, CharacterExtras *ch
 				walkwaitcounter++;
 		}
 
-		if (loop >= views[view].numLoops)
+		if (loop >= _G(views)[view].numLoops)
 			quitprintf("Unable to render character %d (%s) because loop %d does not exist in view %d", index_id, name, loop, view + 1);
 
 		// check don't overflow loop
-		int framesInLoop = views[view].loops[loop].numFrames;
+		int framesInLoop = _G(views)[view].loops[loop].numFrames;
 		if (frame > framesInLoop) {
 			frame = 1;
 
@@ -234,15 +234,15 @@ void CharacterInfo::update_character_moving(int &char_index, CharacterExtras *ch
 
 			if ((flags & CHF_MOVENOTWALK) == 0) {
 				frame++;
-				if (frame >= views[view].loops[loop].numFrames) {
+				if (frame >= _G(views)[view].loops[loop].numFrames) {
 					// end of loop, so loop back round skipping the standing frame
 					frame = 1;
 
-					if (views[view].loops[loop].numFrames < 2)
+					if (_G(views)[view].loops[loop].numFrames < 2)
 						frame = 0;
 				}
 
-				chex->animwait = views[view].loops[loop].frames[frame].speed + animspeed;
+				chex->animwait = _G(views)[view].loops[loop].frames[frame].speed + animspeed;
 
 				if (flags & CHF_ANTIGLIDE)
 					walkwait = chex->animwait;
@@ -292,17 +292,17 @@ int CharacterInfo::update_character_animating(int &aa, int &doing_nothing) {
 				if (frame < 0) {
 					// if the previous loop is a Run Next Loop one, go back to it
 					if ((loop > 0) &&
-						(views[view].loops[loop - 1].RunNextLoop())) {
+						(_G(views)[view].loops[loop - 1].RunNextLoop())) {
 
 						loop--;
-						frame = views[view].loops[loop].numFrames - 1;
+						frame = _G(views)[view].loops[loop].numFrames - 1;
 					} else if (animating & CHANIM_REPEAT) {
 
-						frame = views[view].loops[loop].numFrames - 1;
+						frame = _G(views)[view].loops[loop].numFrames - 1;
 
-						while (views[view].loops[loop].RunNextLoop()) {
+						while (_G(views)[view].loops[loop].RunNextLoop()) {
 							loop++;
-							frame = views[view].loops[loop].numFrames - 1;
+							frame = _G(views)[view].loops[loop].numFrames - 1;
 						}
 					} else {
 						frame++;
@@ -322,10 +322,10 @@ int CharacterInfo::update_character_animating(int &aa, int &doing_nothing) {
 				frame = 0;
 			}
 
-			if (frame >= views[view].loops[loop].numFrames) {
+			if (frame >= _G(views)[view].loops[loop].numFrames) {
 
-				if (views[view].loops[loop].RunNextLoop()) {
-					if (loop + 1 >= views[view].numLoops)
+				if (_G(views)[view].loops[loop].RunNextLoop()) {
+					if (loop + 1 >= _G(views)[view].numLoops)
 						quit("!Animating character tried to overrun last loop in view");
 					loop++;
 					frame = 0;
@@ -348,12 +348,12 @@ int CharacterInfo::update_character_animating(int &aa, int &doing_nothing) {
 					// if it's a multi-loop animation, go back to start
 					if (_GP(play).no_multiloop_repeat == 0) {
 						while ((loop > 0) &&
-							(views[view].loops[loop - 1].RunNextLoop()))
+							(_G(views)[view].loops[loop - 1].RunNextLoop()))
 							loop--;
 					}
 				}
 			}
-			wait = views[view].loops[loop].frames[frame].speed;
+			wait = _G(views)[view].loops[loop].frames[frame].speed;
 			// idle anim doesn't have speed stored cos animating==0
 			if (idleleft < 0)
 				wait += animspeed + 5;
@@ -463,7 +463,7 @@ void CharacterInfo::update_character_idle(CharacterExtras *chex, int &doing_noth
 			Character_LockView(this, idleview + 1);
 			// SetCharView resets it to 0
 			idleleft = -2;
-			int maxLoops = views[idleview].numLoops;
+			int maxLoops = _G(views)[idleview].numLoops;
 			// if the char is set to "no diagonal loops", don't try
 			// to use diagonal idle loops either
 			if ((maxLoops > 4) && (useDiagonal(this)))
@@ -474,7 +474,7 @@ void CharacterInfo::update_character_idle(CharacterExtras *chex, int &doing_noth
 				do {
 					useloop = ::AGS::g_vm->getRandomNumber(maxLoops - 1);
 					// don't select a loop which is a continuation of a previous one
-				} while ((useloop > 0) && (views[idleview].loops[useloop - 1].RunNextLoop()));
+				} while ((useloop > 0) && (_G(views)[idleview].loops[useloop - 1].RunNextLoop()));
 			}
 			// Normal idle anim - just reset to loop 0 if not enough to
 			// use the current one
diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp
index 224199470b..53c9fe9164 100644
--- a/engines/ags/engine/ac/dialog.cpp
+++ b/engines/ags/engine/ac/dialog.cpp
@@ -560,7 +560,7 @@ void DialogOptions::Show() {
 		dirtyheight = data_to_game_coord(ccDialogOptionsRendering.height);
 		dialog_abs_x = dirtyx;
 	} else if (_GP(game).options[OPT_DIALOGIFACE] > 0) {
-		GUIMain *guib = &guis[_GP(game).options[OPT_DIALOGIFACE]];
+		GUIMain *guib = &_GP(guis)[_GP(game).options[OPT_DIALOGIFACE]];
 		if (guib->IsTextWindow()) {
 			// text-window, so do the QFG4-style speech options
 			is_textwindow = 1;
@@ -664,7 +664,7 @@ void DialogOptions::Redraw() {
 		// text window behind the options
 		areawid = data_to_game_coord(_GP(play).max_dialogoption_width);
 		int biggest = 0;
-		padding = guis[_GP(game).options[OPT_DIALOGIFACE]].Padding;
+		padding = _GP(guis)[_GP(game).options[OPT_DIALOGIFACE]].Padding;
 		for (int i = 0; i < numdisp; ++i) {
 			break_up_text_into_lines(get_translation(dtop->optionnames[(int)disporder[i]]), Lines, areawid - ((2 * padding + 2) + bullet_wid), usingfont);
 			if (longestline > biggest)
@@ -691,7 +691,7 @@ void DialogOptions::Redraw() {
 		// needs to draw the right text window, not the default
 		Bitmap *text_window_ds = nullptr;
 		draw_text_window(&text_window_ds, false, &txoffs, &tyoffs, &xspos, &yspos, &areawid, nullptr, needheight, _GP(game).options[OPT_DIALOGIFACE]);
-		options_surface_has_alpha = guis[_GP(game).options[OPT_DIALOGIFACE]].HasAlphaChannel();
+		options_surface_has_alpha = _GP(guis)[_GP(game).options[OPT_DIALOGIFACE]].HasAlphaChannel();
 		// since draw_text_window incrases the width, restore it
 		areawid = savedwid;
 
@@ -722,7 +722,7 @@ void DialogOptions::Redraw() {
 				color_t draw_color = ds->GetCompatibleColor(16);
 				ds->FillRect(Rect(0, dlgyp - 1, ui_view.GetWidth() - 1, ui_view.GetHeight() - 1), draw_color);
 			} else {
-				GUIMain *guib = &guis[_GP(game).options[OPT_DIALOGIFACE]];
+				GUIMain *guib = &_GP(guis)[_GP(game).options[OPT_DIALOGIFACE]];
 				if (!guib->IsTextWindow())
 					draw_gui_for_dialog_options(ds, guib, dlgxp, dlgyp);
 			}
@@ -734,7 +734,7 @@ void DialogOptions::Redraw() {
 		if (_GP(game).options[OPT_DIALOGIFACE] > 0) {
 			// the whole GUI area should be marked dirty in order
 			// to ensure it gets drawn
-			GUIMain *guib = &guis[_GP(game).options[OPT_DIALOGIFACE]];
+			GUIMain *guib = &_GP(guis)[_GP(game).options[OPT_DIALOGIFACE]];
 			dirtyheight = guib->Height;
 			dirtyy = dlgyp;
 			options_surface_has_alpha = guib->HasAlphaChannel();
@@ -1157,7 +1157,7 @@ void do_conversation(int dlgnum) {
 //
 //=============================================================================
 
-extern ScriptString myScriptStringImpl;
+
 
 // int (ScriptDialog *sd)
 RuntimeScriptValue Sc_Dialog_GetID(void *self, const RuntimeScriptValue *params, int32_t param_count) {
@@ -1186,7 +1186,7 @@ RuntimeScriptValue Sc_Dialog_GetOptionState(void *self, const RuntimeScriptValue
 
 // const char* (ScriptDialog *sd, int option)
 RuntimeScriptValue Sc_Dialog_GetOptionText(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ_PINT(ScriptDialog, const char, myScriptStringImpl, Dialog_GetOptionText);
+	API_CONST_OBJCALL_OBJ_PINT(ScriptDialog, const char, _GP(myScriptStringImpl), Dialog_GetOptionText);
 }
 
 // int (ScriptDialog *sd, int option)
diff --git a/engines/ags/engine/ac/dialog.h b/engines/ags/engine/ac/dialog.h
index 6621259050..025abe9c2a 100644
--- a/engines/ags/engine/ac/dialog.h
+++ b/engines/ags/engine/ac/dialog.h
@@ -41,8 +41,6 @@ void Dialog_Start(ScriptDialog *sd);
 void do_conversation(int dlgnum);
 int  show_dialog_options(int dlgnum, int sayChosenOption, bool runGameLoopsInBackground);
 
-extern ScriptDialog *scrDialog;
-
 } // namespace AGS3
 
 #endif
diff --git a/engines/ags/engine/ac/dialogoptionsrendering.cpp b/engines/ags/engine/ac/dialogoptionsrendering.cpp
index 059d6aa07e..2f368c6ea7 100644
--- a/engines/ags/engine/ac/dialogoptionsrendering.cpp
+++ b/engines/ags/engine/ac/dialogoptionsrendering.cpp
@@ -28,11 +28,11 @@
 #include "ags/engine/script/runtimescriptvalue.h"
 #include "ags/engine/script/script_runtime.h"
 #include "ags/engine/ac/dynobj/cc_dialog.h"
+#include "ags/globals.h"
 
 namespace AGS3 {
 
 extern DialogTopic *dialog;
-extern CCDialog ccDynamicDialog;
 
 // ** SCRIPT DIALOGOPTIONSRENDERING OBJECT
 
@@ -110,7 +110,7 @@ void DialogOptionsRendering_SetParserTextboxWidth(ScriptDialogOptionsRendering *
 }
 
 ScriptDialog *DialogOptionsRendering_GetDialogToRender(ScriptDialogOptionsRendering *dlgOptRender) {
-	return &scrDialog[dlgOptRender->dialogID];
+	return &_G(scrDialog)[dlgOptRender->dialogID];
 }
 
 ScriptDrawingSurface *DialogOptionsRendering_GetSurface(ScriptDialogOptionsRendering *dlgOptRender) {
@@ -123,7 +123,7 @@ int DialogOptionsRendering_GetActiveOptionID(ScriptDialogOptionsRendering *dlgOp
 }
 
 void DialogOptionsRendering_SetActiveOptionID(ScriptDialogOptionsRendering *dlgOptRender, int activeOptionID) {
-	int optionCount = dialog[scrDialog[dlgOptRender->dialogID].id].numoptions;
+	int optionCount = dialog[_G(scrDialog)[dlgOptRender->dialogID].id].numoptions;
 	if ((activeOptionID < 0) || (activeOptionID > optionCount))
 		quitprintf("DialogOptionsRenderingInfo.ActiveOptionID: invalid ID specified for this dialog (specified %d, valid range: 1..%d)", activeOptionID, optionCount);
 
@@ -163,7 +163,7 @@ RuntimeScriptValue Sc_DialogOptionsRendering_SetActiveOptionID(void *self, const
 
 // ScriptDialog* (ScriptDialogOptionsRendering *dlgOptRender)
 RuntimeScriptValue Sc_DialogOptionsRendering_GetDialogToRender(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ(ScriptDialogOptionsRendering, ScriptDialog, ccDynamicDialog, DialogOptionsRendering_GetDialogToRender);
+	API_OBJCALL_OBJ(ScriptDialogOptionsRendering, ScriptDialog, _GP(ccDynamicDialog), DialogOptionsRendering_GetDialogToRender);
 }
 
 // int (ScriptDialogOptionsRendering *dlgOptRender)
diff --git a/engines/ags/engine/ac/display.cpp b/engines/ags/engine/ac/display.cpp
index 4f2f8b0037..473c93e55e 100644
--- a/engines/ags/engine/ac/display.cpp
+++ b/engines/ags/engine/ac/display.cpp
@@ -205,7 +205,7 @@ int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int
 		if (drawBackground) {
 			draw_text_window_and_bar(&text_window_ds, wantFreeScreenop, &ttxleft, &ttxtop, &adjustedXX, &adjustedYY, &wii, &text_color, 0, usingGui);
 			if (usingGui > 0) {
-				alphaChannel = guis[usingGui].HasAlphaChannel();
+				alphaChannel = _GP(guis)[usingGui].HasAlphaChannel();
 			}
 		} else if ((ShouldAntiAliasText()) && (_GP(game).GetColorDepth() >= 24))
 			alphaChannel = true;
@@ -218,7 +218,7 @@ int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int
 			if (asspch < 0) {
 				if ((usingGui >= 0) &&
 					((_GP(game).options[OPT_SPEECHTYPE] >= 2) || (isThought)))
-					text_color = text_window_ds->GetCompatibleColor(guis[usingGui].FgColor);
+					text_color = text_window_ds->GetCompatibleColor(_GP(guis)[usingGui].FgColor);
 				else
 					text_color = text_window_ds->GetCompatibleColor(-asspch);
 
@@ -233,7 +233,7 @@ int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int
 		draw_text_window_and_bar(&text_window_ds, wantFreeScreenop, &xoffs, &yoffs, &xx, &yy, &wii, &text_color);
 
 		if (_GP(game).options[OPT_TWCUSTOM] > 0) {
-			alphaChannel = guis[_GP(game).options[OPT_TWCUSTOM]].HasAlphaChannel();
+			alphaChannel = _GP(guis)[_GP(game).options[OPT_TWCUSTOM]].HasAlphaChannel();
 		}
 
 		adjust_y_coordinate_for_text(&yoffs, usingfont);
@@ -682,11 +682,11 @@ int get_textwindow_border_width(int twgui) {
 	if (twgui < 0)
 		return 0;
 
-	if (!guis[twgui].IsTextWindow())
+	if (!_GP(guis)[twgui].IsTextWindow())
 		quit("!GUI set as text window but is not actually a text window GUI");
 
-	int borwid = _GP(game).SpriteInfos[get_but_pic(&guis[twgui], 4)].Width +
-		_GP(game).SpriteInfos[get_but_pic(&guis[twgui], 5)].Width;
+	int borwid = _GP(game).SpriteInfos[get_but_pic(&_GP(guis)[twgui], 4)].Width +
+		_GP(game).SpriteInfos[get_but_pic(&_GP(guis)[twgui], 5)].Width;
 
 	return borwid;
 }
@@ -696,10 +696,10 @@ int get_textwindow_top_border_height(int twgui) {
 	if (twgui < 0)
 		return 0;
 
-	if (!guis[twgui].IsTextWindow())
+	if (!_GP(guis)[twgui].IsTextWindow())
 		quit("!GUI set as text window but is not actually a text window GUI");
 
-	return _GP(game).SpriteInfos[get_but_pic(&guis[twgui], 6)].Height;
+	return _GP(game).SpriteInfos[get_but_pic(&_GP(guis)[twgui], 6)].Height;
 }
 
 // Get the padding for a text window
@@ -710,7 +710,7 @@ int get_textwindow_padding(int ifnum) {
 	if (ifnum < 0)
 		ifnum = _GP(game).options[OPT_TWCUSTOM];
 	if (ifnum > 0 && ifnum < _GP(game).numgui)
-		result = guis[ifnum].Padding;
+		result = _GP(guis)[ifnum].Padding;
 	else
 		result = TEXTWINDOW_PADDING_DEFAULT;
 
@@ -735,10 +735,10 @@ void draw_text_window(Bitmap **text_window_ds, bool should_free_ds,
 	} else {
 		if (ifnum >= _GP(game).numgui)
 			quitprintf("!Invalid GUI %d specified as text window (total GUIs: %d)", ifnum, _GP(game).numgui);
-		if (!guis[ifnum].IsTextWindow())
+		if (!_GP(guis)[ifnum].IsTextWindow())
 			quit("!GUI set as text window but is not actually a text window GUI");
 
-		int tbnum = get_but_pic(&guis[ifnum], 0);
+		int tbnum = get_but_pic(&_GP(guis)[ifnum], 0);
 
 		wii[0] += get_textwindow_border_width(ifnum);
 		xx[0] -= _GP(game).SpriteInfos[tbnum].Width;
@@ -752,9 +752,9 @@ void draw_text_window(Bitmap **text_window_ds, bool should_free_ds,
 		*text_window_ds = BitmapHelper::CreateTransparentBitmap(wii[0], ovrheight + (padding * 2) + _GP(game).SpriteInfos[tbnum].Height * 2, _GP(game).GetColorDepth());
 		ds = *text_window_ds;
 		int xoffs = _GP(game).SpriteInfos[tbnum].Width, yoffs = _GP(game).SpriteInfos[tbnum].Height;
-		draw_button_background(ds, xoffs, yoffs, (ds->GetWidth() - xoffs) - 1, (ds->GetHeight() - yoffs) - 1, &guis[ifnum]);
+		draw_button_background(ds, xoffs, yoffs, (ds->GetWidth() - xoffs) - 1, (ds->GetHeight() - yoffs) - 1, &_GP(guis)[ifnum]);
 		if (set_text_color)
-			*set_text_color = ds->GetCompatibleColor(guis[ifnum].FgColor);
+			*set_text_color = ds->GetCompatibleColor(_GP(guis)[ifnum].FgColor);
 		xins[0] = xoffs + padding;
 		yins[0] = yoffs + padding;
 	}
diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index f0e9d2bf77..fdd0cf955e 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -110,9 +110,7 @@ extern RoomStatus *croom;
 extern int our_eip;
 extern int in_new_room;
 extern RoomObject *objs;
-extern ViewStruct *views;
-extern CharacterCache *charcache;
-extern ObjectCache objcache[MAX_ROOM_OBJECTS];
+
 extern int displayed_room;
 extern CharacterExtras *charextra;
 extern CharacterInfo *playerchar;
@@ -1375,25 +1373,25 @@ int construct_object_gfx(int aa, int *drawnWidth, int *drawnHeight, bool alwaysU
 	// check whether the image should be flipped
 	int isMirrored = 0;
 	if ((objs[aa].view >= 0) &&
-	        (views[objs[aa].view].loops[objs[aa].loop].frames[objs[aa].frame].pic == objs[aa].num) &&
-	        ((views[objs[aa].view].loops[objs[aa].loop].frames[objs[aa].frame].flags & VFLG_FLIPSPRITE) != 0)) {
+	        (_G(views)[objs[aa].view].loops[objs[aa].loop].frames[objs[aa].frame].pic == objs[aa].num) &&
+	        ((_G(views)[objs[aa].view].loops[objs[aa].loop].frames[objs[aa].frame].flags & VFLG_FLIPSPRITE) != 0)) {
 		isMirrored = 1;
 	}
 
 	if ((hardwareAccelerated) &&
 	        (walkBehindMethod != DrawOverCharSprite) &&
-	        (objcache[aa].image != nullptr) &&
-	        (objcache[aa].sppic == objs[aa].num) &&
+	        (_G(objcache)[aa].image != nullptr) &&
+	        (_G(objcache)[aa].sppic == objs[aa].num) &&
 	        (actsps[useindx] != nullptr)) {
 		// HW acceleration
-		objcache[aa].tintamntwas = tint_level;
-		objcache[aa].tintredwas = tint_red;
-		objcache[aa].tintgrnwas = tint_green;
-		objcache[aa].tintbluwas = tint_blue;
-		objcache[aa].tintlightwas = tint_light;
-		objcache[aa].lightlevwas = light_level;
-		objcache[aa].zoomWas = zoom_level;
-		objcache[aa].mirroredWas = isMirrored;
+		_G(objcache)[aa].tintamntwas = tint_level;
+		_G(objcache)[aa].tintredwas = tint_red;
+		_G(objcache)[aa].tintgrnwas = tint_green;
+		_G(objcache)[aa].tintbluwas = tint_blue;
+		_G(objcache)[aa].tintlightwas = tint_light;
+		_G(objcache)[aa].lightlevwas = light_level;
+		_G(objcache)[aa].zoomWas = zoom_level;
+		_G(objcache)[aa].mirroredWas = isMirrored;
 
 		return 1;
 	}
@@ -1401,33 +1399,33 @@ int construct_object_gfx(int aa, int *drawnWidth, int *drawnHeight, bool alwaysU
 	if ((!hardwareAccelerated) && (gfxDriver->HasAcceleratedTransform())) {
 		// They want to draw it in software mode with the D3D driver,
 		// so force a redraw
-		objcache[aa].sppic = -389538;
+		_G(objcache)[aa].sppic = -389538;
 	}
 
 	// If we have the image cached, use it
-	if ((objcache[aa].image != nullptr) &&
-	        (objcache[aa].sppic == objs[aa].num) &&
-	        (objcache[aa].tintamntwas == tint_level) &&
-	        (objcache[aa].tintlightwas == tint_light) &&
-	        (objcache[aa].tintredwas == tint_red) &&
-	        (objcache[aa].tintgrnwas == tint_green) &&
-	        (objcache[aa].tintbluwas == tint_blue) &&
-	        (objcache[aa].lightlevwas == light_level) &&
-	        (objcache[aa].zoomWas == zoom_level) &&
-	        (objcache[aa].mirroredWas == isMirrored)) {
+	if ((_G(objcache)[aa].image != nullptr) &&
+	        (_G(objcache)[aa].sppic == objs[aa].num) &&
+	        (_G(objcache)[aa].tintamntwas == tint_level) &&
+	        (_G(objcache)[aa].tintlightwas == tint_light) &&
+	        (_G(objcache)[aa].tintredwas == tint_red) &&
+	        (_G(objcache)[aa].tintgrnwas == tint_green) &&
+	        (_G(objcache)[aa].tintbluwas == tint_blue) &&
+	        (_G(objcache)[aa].lightlevwas == light_level) &&
+	        (_G(objcache)[aa].zoomWas == zoom_level) &&
+	        (_G(objcache)[aa].mirroredWas == isMirrored)) {
 		// the image is the same, we can use it cached!
 		if ((walkBehindMethod != DrawOverCharSprite) &&
 		        (actsps[useindx] != nullptr))
 			return 1;
 		// Check if the X & Y co-ords are the same, too -- if so, there
 		// is scope for further optimisations
-		if ((objcache[aa].xwas == objs[aa].x) &&
-		        (objcache[aa].ywas == objs[aa].y) &&
+		if ((_G(objcache)[aa].xwas == objs[aa].x) &&
+		        (_G(objcache)[aa].ywas == objs[aa].y) &&
 		        (actsps[useindx] != nullptr) &&
 		        (walk_behind_baselines_changed == 0))
 			return 1;
 		actsps[useindx] = recycle_bitmap(actsps[useindx], coldept, sprwidth, sprheight);
-		actsps[useindx]->Blit(objcache[aa].image, 0, 0, 0, 0, objcache[aa].image->GetWidth(), objcache[aa].image->GetHeight());
+		actsps[useindx]->Blit(_G(objcache)[aa].image, 0, 0, 0, 0, _G(objcache)[aa].image->GetWidth(), _G(objcache)[aa].image->GetHeight());
 		return 0;
 	}
 
@@ -1459,18 +1457,18 @@ int construct_object_gfx(int aa, int *drawnWidth, int *drawnHeight, bool alwaysU
 	}
 
 	// Re-use the bitmap if it's the same size
-	objcache[aa].image = recycle_bitmap(objcache[aa].image, coldept, sprwidth, sprheight);
+	_G(objcache)[aa].image = recycle_bitmap(_G(objcache)[aa].image, coldept, sprwidth, sprheight);
 	// Create the cached image and store it
-	objcache[aa].image->Blit(actsps[useindx], 0, 0, 0, 0, sprwidth, sprheight);
-	objcache[aa].sppic = objs[aa].num;
-	objcache[aa].tintamntwas = tint_level;
-	objcache[aa].tintredwas = tint_red;
-	objcache[aa].tintgrnwas = tint_green;
-	objcache[aa].tintbluwas = tint_blue;
-	objcache[aa].tintlightwas = tint_light;
-	objcache[aa].lightlevwas = light_level;
-	objcache[aa].zoomWas = zoom_level;
-	objcache[aa].mirroredWas = isMirrored;
+	_G(objcache)[aa].image->Blit(actsps[useindx], 0, 0, 0, 0, sprwidth, sprheight);
+	_G(objcache)[aa].sppic = objs[aa].num;
+	_G(objcache)[aa].tintamntwas = tint_level;
+	_G(objcache)[aa].tintredwas = tint_red;
+	_G(objcache)[aa].tintgrnwas = tint_green;
+	_G(objcache)[aa].tintbluwas = tint_blue;
+	_G(objcache)[aa].tintlightwas = tint_light;
+	_G(objcache)[aa].lightlevwas = light_level;
+	_G(objcache)[aa].zoomWas = zoom_level;
+	_G(objcache)[aa].mirroredWas = isMirrored;
 	return 0;
 }
 
@@ -1493,8 +1491,8 @@ void prepare_objects_for_drawing() {
 		int actspsIntact = construct_object_gfx(aa, nullptr, &tehHeight, false);
 
 		// update the cache for next time
-		objcache[aa].xwas = objs[aa].x;
-		objcache[aa].ywas = objs[aa].y;
+		_G(objcache)[aa].xwas = objs[aa].x;
+		_G(objcache)[aa].ywas = objs[aa].y;
 		int atxp = data_to_game_coord(objs[aa].x);
 		int atyp = data_to_game_coord(objs[aa].y) - tehHeight;
 
@@ -1520,19 +1518,19 @@ void prepare_objects_for_drawing() {
 		}
 
 		if (gfxDriver->HasAcceleratedTransform()) {
-			actspsbmp[useindx]->SetFlippedLeftRight(objcache[aa].mirroredWas != 0);
+			actspsbmp[useindx]->SetFlippedLeftRight(_G(objcache)[aa].mirroredWas != 0);
 			actspsbmp[useindx]->SetStretch(objs[aa].last_width, objs[aa].last_height);
-			actspsbmp[useindx]->SetTint(objcache[aa].tintredwas, objcache[aa].tintgrnwas, objcache[aa].tintbluwas, (objcache[aa].tintamntwas * 256) / 100);
+			actspsbmp[useindx]->SetTint(_G(objcache)[aa].tintredwas, _G(objcache)[aa].tintgrnwas, _G(objcache)[aa].tintbluwas, (_G(objcache)[aa].tintamntwas * 256) / 100);
 
-			if (objcache[aa].tintamntwas > 0) {
-				if (objcache[aa].tintlightwas == 0)  // luminance of 0 -- pass 1 to enable
+			if (_G(objcache)[aa].tintamntwas > 0) {
+				if (_G(objcache)[aa].tintlightwas == 0)  // luminance of 0 -- pass 1 to enable
 					actspsbmp[useindx]->SetLightLevel(1);
-				else if (objcache[aa].tintlightwas < 250)
-					actspsbmp[useindx]->SetLightLevel(objcache[aa].tintlightwas);
+				else if (_G(objcache)[aa].tintlightwas < 250)
+					actspsbmp[useindx]->SetLightLevel(_G(objcache)[aa].tintlightwas);
 				else
 					actspsbmp[useindx]->SetLightLevel(0);
-			} else if (objcache[aa].lightlevwas != 0)
-				actspsbmp[useindx]->SetLightLevel((objcache[aa].lightlevwas * 25) / 10 + 256);
+			} else if (_G(objcache)[aa].lightlevwas != 0)
+				actspsbmp[useindx]->SetLightLevel((_G(objcache)[aa].lightlevwas * 25) / 10 + 256);
 			else
 				actspsbmp[useindx]->SetLightLevel(0);
 		}
@@ -1611,16 +1609,16 @@ void prepare_characters_for_drawing() {
 			           chin->name, displayed_room);
 		}
 
-		if (chin->frame >= views[chin->view].loops[chin->loop].numFrames)
+		if (chin->frame >= _G(views)[chin->view].loops[chin->loop].numFrames)
 			chin->frame = 0;
 
-		if ((chin->loop >= views[chin->view].numLoops) ||
-		        (views[chin->view].loops[chin->loop].numFrames < 1)) {
+		if ((chin->loop >= _G(views)[chin->view].numLoops) ||
+		        (_G(views)[chin->view].loops[chin->loop].numFrames < 1)) {
 			quitprintf("!The character '%s' could not be displayed because there were no frames in loop %d of view %d.",
 			           chin->name, chin->loop, chin->view + 1);
 		}
 
-		sppic = views[chin->view].loops[chin->loop].frames[chin->frame].pic;
+		sppic = _G(views)[chin->view].loops[chin->loop].frames[chin->frame].pic;
 		if (sppic < 0)
 			sppic = 0;  // in case it's screwed up somehow
 		our_eip = 331;
@@ -1667,7 +1665,7 @@ void prepare_characters_for_drawing() {
 
 		// adjust the sppic if mirrored, so it doesn't accidentally
 		// cache the mirrored frame as the real one
-		if (views[chin->view].loops[chin->loop].frames[chin->frame].flags & VFLG_FLIPSPRITE) {
+		if (_G(views)[chin->view].loops[chin->loop].frames[chin->frame].flags & VFLG_FLIPSPRITE) {
 			isMirrored = 1;
 			specialpic = -sppic;
 		}
@@ -1676,28 +1674,28 @@ void prepare_characters_for_drawing() {
 
 		// if the character was the same sprite and scaling last time,
 		// just use the cached image
-		if ((charcache[aa].inUse) &&
-		        (charcache[aa].sppic == specialpic) &&
-		        (charcache[aa].scaling == zoom_level) &&
-		        (charcache[aa].tintredwas == tint_red) &&
-		        (charcache[aa].tintgrnwas == tint_green) &&
-		        (charcache[aa].tintbluwas == tint_blue) &&
-		        (charcache[aa].tintamntwas == tint_amount) &&
-		        (charcache[aa].tintlightwas == tint_light) &&
-		        (charcache[aa].lightlevwas == light_level)) {
+		if ((_G(charcache)[aa].inUse) &&
+		        (_G(charcache)[aa].sppic == specialpic) &&
+		        (_G(charcache)[aa].scaling == zoom_level) &&
+		        (_G(charcache)[aa].tintredwas == tint_red) &&
+		        (_G(charcache)[aa].tintgrnwas == tint_green) &&
+		        (_G(charcache)[aa].tintbluwas == tint_blue) &&
+		        (_G(charcache)[aa].tintamntwas == tint_amount) &&
+		        (_G(charcache)[aa].tintlightwas == tint_light) &&
+		        (_G(charcache)[aa].lightlevwas == light_level)) {
 			if (walkBehindMethod == DrawOverCharSprite) {
-				actsps[useindx] = recycle_bitmap(actsps[useindx], charcache[aa].image->GetColorDepth(), charcache[aa].image->GetWidth(), charcache[aa].image->GetHeight());
-				actsps[useindx]->Blit(charcache[aa].image, 0, 0, 0, 0, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight());
+				actsps[useindx] = recycle_bitmap(actsps[useindx], _G(charcache)[aa].image->GetColorDepth(), _G(charcache)[aa].image->GetWidth(), _G(charcache)[aa].image->GetHeight());
+				actsps[useindx]->Blit(_G(charcache)[aa].image, 0, 0, 0, 0, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight());
 			} else {
 				usingCachedImage = true;
 			}
-		} else if ((charcache[aa].inUse) &&
-		           (charcache[aa].sppic == specialpic) &&
+		} else if ((_G(charcache)[aa].inUse) &&
+		           (_G(charcache)[aa].sppic == specialpic) &&
 		           (gfxDriver->HasAcceleratedTransform())) {
 			usingCachedImage = true;
-		} else if (charcache[aa].inUse) {
-			//destroy_bitmap (charcache[aa].image);
-			charcache[aa].inUse = 0;
+		} else if (_G(charcache)[aa].inUse) {
+			//destroy_bitmap (_G(charcache)[aa].image);
+			_G(charcache)[aa].inUse = 0;
 		}
 
 		our_eip = 3332;
@@ -1725,17 +1723,17 @@ void prepare_characters_for_drawing() {
 		                 // adjust the Y positioning for the character's Z co-ord
 		                 - data_to_game_coord(chin->z);
 
-		charcache[aa].scaling = zoom_level;
-		charcache[aa].sppic = specialpic;
-		charcache[aa].tintredwas = tint_red;
-		charcache[aa].tintgrnwas = tint_green;
-		charcache[aa].tintbluwas = tint_blue;
-		charcache[aa].tintamntwas = tint_amount;
-		charcache[aa].tintlightwas = tint_light;
-		charcache[aa].lightlevwas = light_level;
+		_G(charcache)[aa].scaling = zoom_level;
+		_G(charcache)[aa].sppic = specialpic;
+		_G(charcache)[aa].tintredwas = tint_red;
+		_G(charcache)[aa].tintgrnwas = tint_green;
+		_G(charcache)[aa].tintbluwas = tint_blue;
+		_G(charcache)[aa].tintamntwas = tint_amount;
+		_G(charcache)[aa].tintlightwas = tint_light;
+		_G(charcache)[aa].lightlevwas = light_level;
 
 		// If cache needs to be re-drawn
-		if (!charcache[aa].inUse) {
+		if (!_G(charcache)[aa].inUse) {
 
 			// create the base sprite in actsps[useindx], which will
 			// be scaled and/or flipped, as appropriate
@@ -1768,10 +1766,10 @@ void prepare_characters_for_drawing() {
 			}
 
 			// update the character cache with the new image
-			charcache[aa].inUse = 1;
-			//charcache[aa].image = BitmapHelper::CreateBitmap_ (coldept, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight());
-			charcache[aa].image = recycle_bitmap(charcache[aa].image, coldept, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight());
-			charcache[aa].image->Blit(actsps[useindx], 0, 0, 0, 0, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight());
+			_G(charcache)[aa].inUse = 1;
+			//_G(charcache)[aa].image = BitmapHelper::CreateBitmap_ (coldept, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight());
+			_G(charcache)[aa].image = recycle_bitmap(_G(charcache)[aa].image, coldept, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight());
+			_G(charcache)[aa].image->Blit(actsps[useindx], 0, 0, 0, 0, actsps[useindx]->GetWidth(), actsps[useindx]->GetHeight());
 
 		} // end if !cache.inUse
 
@@ -1987,25 +1985,25 @@ void draw_gui_and_overlays() {
 		if (guis_need_update) {
 			guis_need_update = 0;
 			for (aa = 0; aa < _GP(game).numgui; aa++) {
-				if (!guis[aa].IsDisplayed()) continue;
+				if (!_GP(guis)[aa].IsDisplayed()) continue;
 
 				if (guibg[aa] == nullptr)
-					recreate_guibg_image(&guis[aa]);
+					recreate_guibg_image(&_GP(guis)[aa]);
 
 				eip_guinum = aa;
 				our_eip = 370;
 				guibg[aa]->ClearTransparent();
 				our_eip = 372;
-				guis[aa].DrawAt(guibg[aa], 0, 0);
+				_GP(guis)[aa].DrawAt(guibg[aa], 0, 0);
 				our_eip = 373;
 
 				bool isAlpha = false;
-				if (guis[aa].HasAlphaChannel()) {
+				if (_GP(guis)[aa].HasAlphaChannel()) {
 					isAlpha = true;
 
-					if ((_GP(game).options[OPT_NEWGUIALPHA] == kGuiAlphaRender_Legacy) && (guis[aa].BgImage > 0)) {
+					if ((_GP(game).options[OPT_NEWGUIALPHA] == kGuiAlphaRender_Legacy) && (_GP(guis)[aa].BgImage > 0)) {
 						// old-style (pre-3.0.2) GUI alpha rendering
-						repair_alpha_channel(guibg[aa], _GP(spriteset)[guis[aa].BgImage]);
+						repair_alpha_channel(guibg[aa], _GP(spriteset)[_GP(guis)[aa].BgImage]);
 					}
 				}
 
@@ -2021,20 +2019,20 @@ void draw_gui_and_overlays() {
 		// Draw the GUIs
 		for (int gg = 0; gg < _GP(game).numgui; gg++) {
 			aa = _GP(play).gui_draw_order[gg];
-			if (!guis[aa].IsDisplayed()) continue;
+			if (!_GP(guis)[aa].IsDisplayed()) continue;
 
 			// Don't draw GUI if "GUIs Turn Off When Disabled"
 			if ((_GP(game).options[OPT_DISABLEOFF] == 3) &&
 			        (all_buttons_disabled > 0) &&
-			        (guis[aa].PopupStyle != kGUIPopupNoAutoRemove))
+			        (_GP(guis)[aa].PopupStyle != kGUIPopupNoAutoRemove))
 				continue;
 
-			add_thing_to_draw(guibgbmp[aa], guis[aa].X, guis[aa].Y, guis[aa].Transparency, guis[aa].HasAlphaChannel());
+			add_thing_to_draw(guibgbmp[aa], _GP(guis)[aa].X, _GP(guis)[aa].Y, _GP(guis)[aa].Transparency, _GP(guis)[aa].HasAlphaChannel());
 
 			// only poll if the interface is enabled (mouseovers should not
 			// work while in Wait state)
 			if (IsInterfaceEnabled())
-				guis[aa].Poll();
+				_GP(guis)[aa].Poll();
 		}
 	}
 
@@ -2215,16 +2213,16 @@ void construct_game_screen_overlay(bool draw_mouse) {
 		else {
 			int viewnum = _GP(game).mcurs[cur_cursor].view;
 			int loopnum = 0;
-			if (loopnum >= views[viewnum].numLoops)
+			if (loopnum >= _G(views)[viewnum].numLoops)
 				quitprintf("An animating mouse cursor is using view %d which has no loops", viewnum + 1);
-			if (views[viewnum].loops[loopnum].numFrames < 1)
+			if (_G(views)[viewnum].loops[loopnum].numFrames < 1)
 				quitprintf("An animating mouse cursor is using view %d which has no frames in loop %d", viewnum + 1, loopnum);
 
 			mouse_frame++;
-			if (mouse_frame >= views[viewnum].loops[loopnum].numFrames)
+			if (mouse_frame >= _G(views)[viewnum].loops[loopnum].numFrames)
 				mouse_frame = 0;
-			set_new_cursor_graphic(views[viewnum].loops[loopnum].frames[mouse_frame].pic);
-			mouse_delay = views[viewnum].loops[loopnum].frames[mouse_frame].speed + 5;
+			set_new_cursor_graphic(_G(views)[viewnum].loops[loopnum].frames[mouse_frame].pic);
+			mouse_delay = _G(views)[viewnum].loops[loopnum].frames[mouse_frame].speed + 5;
 			CheckViewFrame(viewnum, loopnum, mouse_frame);
 		}
 		lastmx = _G(mousex);
diff --git a/engines/ags/engine/ac/drawingsurface.cpp b/engines/ags/engine/ac/drawingsurface.cpp
index 7357583743..92bed17d70 100644
--- a/engines/ags/engine/ac/drawingsurface.cpp
+++ b/engines/ags/engine/ac/drawingsurface.cpp
@@ -56,8 +56,8 @@ using namespace AGS::Engine;
 
 extern RoomStatus *croom;
 extern RoomObject *objs;
-extern CharacterCache *charcache;
-extern ObjectCache objcache[MAX_ROOM_OBJECTS];
+
+
 
 extern Bitmap *dynamicallyCreatedSurfaces[MAX_DYNAMIC_SURFACES];
 
@@ -88,16 +88,16 @@ void DrawingSurface_Release(ScriptDrawingSurface *sds) {
 			if (croom != nullptr) {
 				for (tt = 0; tt < croom->numobj; tt++) {
 					if (objs[tt].num == sds->dynamicSpriteNumber)
-						objcache[tt].sppic = -31999;
+						_G(objcache)[tt].sppic = -31999;
 				}
 			}
 			for (tt = 0; tt < _GP(game).numcharacters; tt++) {
-				if (charcache[tt].sppic == sds->dynamicSpriteNumber)
-					charcache[tt].sppic = -31999;
+				if (_G(charcache)[tt].sppic == sds->dynamicSpriteNumber)
+					_G(charcache)[tt].sppic = -31999;
 			}
 			for (tt = 0; tt < _GP(game).numgui; tt++) {
-				if ((guis[tt].BgImage == sds->dynamicSpriteNumber) &&
-					(guis[tt].IsDisplayed())) {
+				if ((_GP(guis)[tt].BgImage == sds->dynamicSpriteNumber) &&
+					(_GP(guis)[tt].IsDisplayed())) {
 					guis_need_update = 1;
 					break;
 				}
diff --git a/engines/ags/engine/ac/dynamicsprite.cpp b/engines/ags/engine/ac/dynamicsprite.cpp
index 71d2f4d3a3..319682475a 100644
--- a/engines/ags/engine/ac/dynamicsprite.cpp
+++ b/engines/ags/engine/ac/dynamicsprite.cpp
@@ -54,8 +54,8 @@ using namespace Engine;
 
 extern RoomObject *objs;
 extern RoomStatus *croom;
-extern CharacterCache *charcache;
-extern ObjectCache objcache[MAX_ROOM_OBJECTS];
+
+
 
 extern color palette[256];
 extern AGS::Engine::IGraphicsDriver *gfxDriver;
@@ -494,9 +494,9 @@ void free_dynamic_sprite(int gotSlot) {
 		for (tt = 0; tt < croom->numobj; tt++) {
 			if (objs[tt].num == gotSlot) {
 				objs[tt].num = 0;
-				objcache[tt].sppic = -1;
-			} else if (objcache[tt].sppic == gotSlot)
-				objcache[tt].sppic = -1;
+				_G(objcache)[tt].sppic = -1;
+			} else if (_G(objcache)[tt].sppic == gotSlot)
+				_G(objcache)[tt].sppic = -1;
 		}
 	}
 }
diff --git a/engines/ags/engine/ac/dynobj/cc_dialog.cpp b/engines/ags/engine/ac/dynobj/cc_dialog.cpp
index e6283dec2a..db7cb37724 100644
--- a/engines/ags/engine/ac/dynobj/cc_dialog.cpp
+++ b/engines/ags/engine/ac/dynobj/cc_dialog.cpp
@@ -24,6 +24,7 @@
 #include "ags/engine/ac/dialog.h"
 #include "ags/shared/ac/dialogtopic.h"
 #include "ags/shared/ac/gamestructdefines.h"
+#include "ags/globals.h"
 
 namespace AGS3 {
 
@@ -44,7 +45,7 @@ int CCDialog::Serialize(const char *address, char *buffer, int bufsize) {
 void CCDialog::Unserialize(int index, const char *serializedData, int dataSize) {
 	StartUnserialize(serializedData, dataSize);
 	int num = UnserializeInt();
-	ccRegisterUnserializedObject(index, &scrDialog[num], this);
+	ccRegisterUnserializedObject(index, &_G(scrDialog)[num], this);
 }
 
 } // namespace AGS3
diff --git a/engines/ags/engine/ac/dynobj/cc_gui.cpp b/engines/ags/engine/ac/dynobj/cc_gui.cpp
index cdc7c871b6..6e3826937b 100644
--- a/engines/ags/engine/ac/dynobj/cc_gui.cpp
+++ b/engines/ags/engine/ac/dynobj/cc_gui.cpp
@@ -22,11 +22,10 @@
 
 #include "ags/engine/ac/dynobj/cc_gui.h"
 #include "ags/engine/ac/dynobj/scriptgui.h"
+#include "ags/globals.h"
 
 namespace AGS3 {
 
-extern ScriptGUI *scrGui;
-
 // return the type name of the object
 const char *CCGUI::GetType() {
 	return "GUI";
@@ -44,7 +43,7 @@ int CCGUI::Serialize(const char *address, char *buffer, int bufsize) {
 void CCGUI::Unserialize(int index, const char *serializedData, int dataSize) {
 	StartUnserialize(serializedData, dataSize);
 	int num = UnserializeInt();
-	ccRegisterUnserializedObject(index, &scrGui[num], this);
+	ccRegisterUnserializedObject(index, &_G(scrGui)[num], this);
 }
 
 } // namespace AGS3
diff --git a/engines/ags/engine/ac/dynobj/cc_guiobject.cpp b/engines/ags/engine/ac/dynobj/cc_guiobject.cpp
index 0f0a9a5abc..b8fe19bac6 100644
--- a/engines/ags/engine/ac/dynobj/cc_guiobject.cpp
+++ b/engines/ags/engine/ac/dynobj/cc_guiobject.cpp
@@ -24,6 +24,7 @@
 #include "ags/engine/ac/dynobj/scriptgui.h"
 #include "ags/shared/gui/guimain.h"
 #include "ags/shared/gui/guiobject.h"
+#include "ags/globals.h"
 
 namespace AGS3 {
 
@@ -48,7 +49,7 @@ void CCGUIObject::Unserialize(int index, const char *serializedData, int dataSiz
 	StartUnserialize(serializedData, dataSize);
 	int guinum = UnserializeInt();
 	int objnum = UnserializeInt();
-	ccRegisterUnserializedObject(index, guis[guinum].GetControl(objnum), this);
+	ccRegisterUnserializedObject(index, _GP(guis)[guinum].GetControl(objnum), this);
 }
 
 } // namespace AGS3
diff --git a/engines/ags/engine/ac/dynobj/cc_hotspot.cpp b/engines/ags/engine/ac/dynobj/cc_hotspot.cpp
index 33fe02d823..3b6730e173 100644
--- a/engines/ags/engine/ac/dynobj/cc_hotspot.cpp
+++ b/engines/ags/engine/ac/dynobj/cc_hotspot.cpp
@@ -24,10 +24,11 @@
 #include "ags/engine/ac/dynobj/scripthotspot.h"
 #include "ags/shared/ac/common_defines.h"
 #include "ags/shared/game/roomstruct.h"
+#include "ags/globals.h"
 
 namespace AGS3 {
 
-extern ScriptHotspot scrHotspot[MAX_ROOM_HOTSPOTS];
+
 
 // return the type name of the object
 const char *CCHotspot::GetType() {
@@ -46,7 +47,7 @@ int CCHotspot::Serialize(const char *address, char *buffer, int bufsize) {
 void CCHotspot::Unserialize(int index, const char *serializedData, int dataSize) {
 	StartUnserialize(serializedData, dataSize);
 	int num = UnserializeInt();
-	ccRegisterUnserializedObject(index, &scrHotspot[num], this);
+	ccRegisterUnserializedObject(index, &_G(scrHotspot)[num], this);
 }
 
 } // namespace AGS3
diff --git a/engines/ags/engine/ac/dynobj/cc_inventory.cpp b/engines/ags/engine/ac/dynobj/cc_inventory.cpp
index f453395f7a..b95627943a 100644
--- a/engines/ags/engine/ac/dynobj/cc_inventory.cpp
+++ b/engines/ags/engine/ac/dynobj/cc_inventory.cpp
@@ -23,11 +23,10 @@
 #include "ags/engine/ac/dynobj/cc_inventory.h"
 #include "ags/engine/ac/dynobj/scriptinvitem.h"
 #include "ags/shared/ac/characterinfo.h"
+#include "ags/globals.h"
 
 namespace AGS3 {
 
-extern ScriptInvItem scrInv[MAX_INV];
-
 // return the type name of the object
 const char *CCInventory::GetType() {
 	return "Inventory";
@@ -45,7 +44,7 @@ int CCInventory::Serialize(const char *address, char *buffer, int bufsize) {
 void CCInventory::Unserialize(int index, const char *serializedData, int dataSize) {
 	StartUnserialize(serializedData, dataSize);
 	int num = UnserializeInt();
-	ccRegisterUnserializedObject(index, &scrInv[num], this);
+	ccRegisterUnserializedObject(index, &_G(scrInv)[num], this);
 }
 
 } // namespace AGS3
diff --git a/engines/ags/engine/ac/dynobj/cc_object.cpp b/engines/ags/engine/ac/dynobj/cc_object.cpp
index 35b61676e7..d67bf9e6d7 100644
--- a/engines/ags/engine/ac/dynobj/cc_object.cpp
+++ b/engines/ags/engine/ac/dynobj/cc_object.cpp
@@ -24,11 +24,10 @@
 #include "ags/engine/ac/dynobj/scriptobject.h"
 #include "ags/shared/ac/common_defines.h"
 #include "ags/shared/game/roomstruct.h"
+#include "ags/globals.h"
 
 namespace AGS3 {
 
-extern ScriptObject scrObj[MAX_ROOM_OBJECTS];
-
 // return the type name of the object
 const char *CCObject::GetType() {
 	return "Object";
@@ -46,7 +45,7 @@ int CCObject::Serialize(const char *address, char *buffer, int bufsize) {
 void CCObject::Unserialize(int index, const char *serializedData, int dataSize) {
 	StartUnserialize(serializedData, dataSize);
 	int num = UnserializeInt();
-	ccRegisterUnserializedObject(index, &scrObj[num], this);
+	ccRegisterUnserializedObject(index, &_G(scrObj)[num], this);
 }
 
 } // namespace AGS3
diff --git a/engines/ags/engine/ac/dynobj/cc_region.cpp b/engines/ags/engine/ac/dynobj/cc_region.cpp
index 56d099b1c4..eae1c5d718 100644
--- a/engines/ags/engine/ac/dynobj/cc_region.cpp
+++ b/engines/ags/engine/ac/dynobj/cc_region.cpp
@@ -24,11 +24,10 @@
 #include "ags/engine/ac/dynobj/scriptregion.h"
 #include "ags/shared/ac/common_defines.h"
 #include "ags/shared/game/roomstruct.h"
+#include "ags/globals.h"
 
 namespace AGS3 {
 
-extern ScriptRegion scrRegion[MAX_ROOM_REGIONS];
-
 // return the type name of the object
 const char *CCRegion::GetType() {
 	return "Region";
@@ -46,7 +45,7 @@ int CCRegion::Serialize(const char *address, char *buffer, int bufsize) {
 void CCRegion::Unserialize(int index, const char *serializedData, int dataSize) {
 	StartUnserialize(serializedData, dataSize);
 	int num = UnserializeInt();
-	ccRegisterUnserializedObject(index, &scrRegion[num], this);
+	ccRegisterUnserializedObject(index, &_G(scrRegion)[num], this);
 }
 
 } // namespace AGS3
diff --git a/engines/ags/engine/ac/dynobj/cc_serializer.cpp b/engines/ags/engine/ac/dynobj/cc_serializer.cpp
index 7390b4629c..7140e1919c 100644
--- a/engines/ags/engine/ac/dynobj/cc_serializer.cpp
+++ b/engines/ags/engine/ac/dynobj/cc_serializer.cpp
@@ -33,17 +33,10 @@
 #include "ags/engine/debugging/debug_log.h"
 #include "ags/plugins/agsplugin.h"
 #include "ags/plugins/pluginobjectreader.h"
+#include "ags/globals.h"
 
 namespace AGS3 {
 
-extern CCGUIObject ccDynamicGUIObject;
-extern CCCharacter ccDynamicCharacter;
-extern CCHotspot   ccDynamicHotspot;
-extern CCRegion    ccDynamicRegion;
-extern CCInventory ccDynamicInv;
-extern CCGUI       ccDynamicGUI;
-extern CCObject    ccDynamicObject;
-extern CCDialog    ccDynamicDialog;
 extern ScriptDrawingSurface *dialogOptionsRenderingSurface;
 extern ScriptDialogOptionsRendering ccDialogOptionsRendering;
 extern PluginObjectReader pluginReaders[MAX_PLUGIN_OBJECT_READERS];
@@ -51,25 +44,23 @@ extern int numPluginReaders;
 
 // *** De-serialization of script objects
 
-
-
 void AGSDeSerializer::Unserialize(int index, const char *objectType, const char *serializedData, int dataSize) {
 	if (strcmp(objectType, "GUIObject") == 0) {
-		ccDynamicGUIObject.Unserialize(index, serializedData, dataSize);
+		_GP(ccDynamicGUIObject).Unserialize(index, serializedData, dataSize);
 	} else if (strcmp(objectType, "Character") == 0) {
-		ccDynamicCharacter.Unserialize(index, serializedData, dataSize);
+		_GP(ccDynamicCharacter).Unserialize(index, serializedData, dataSize);
 	} else if (strcmp(objectType, "Hotspot") == 0) {
-		ccDynamicHotspot.Unserialize(index, serializedData, dataSize);
+		_GP(ccDynamicHotspot).Unserialize(index, serializedData, dataSize);
 	} else if (strcmp(objectType, "Region") == 0) {
-		ccDynamicRegion.Unserialize(index, serializedData, dataSize);
+		_GP(ccDynamicRegion).Unserialize(index, serializedData, dataSize);
 	} else if (strcmp(objectType, "Inventory") == 0) {
-		ccDynamicInv.Unserialize(index, serializedData, dataSize);
+		_GP(ccDynamicInv).Unserialize(index, serializedData, dataSize);
 	} else if (strcmp(objectType, "Dialog") == 0) {
-		ccDynamicDialog.Unserialize(index, serializedData, dataSize);
+		_GP(ccDynamicDialog).Unserialize(index, serializedData, dataSize);
 	} else if (strcmp(objectType, "GUI") == 0) {
-		ccDynamicGUI.Unserialize(index, serializedData, dataSize);
+		_GP(ccDynamicGUI).Unserialize(index, serializedData, dataSize);
 	} else if (strcmp(objectType, "Object") == 0) {
-		ccDynamicObject.Unserialize(index, serializedData, dataSize);
+		_GP(ccDynamicObject).Unserialize(index, serializedData, dataSize);
 	} else if (strcmp(objectType, "String") == 0) {
 		ScriptString *scf = new ScriptString();
 		scf->Unserialize(index, serializedData, dataSize);
diff --git a/engines/ags/engine/ac/dynobj/scripthotspot.h b/engines/ags/engine/ac/dynobj/scripthotspot.h
index c11d3828d6..43dfe5a465 100644
--- a/engines/ags/engine/ac/dynobj/scripthotspot.h
+++ b/engines/ags/engine/ac/dynobj/scripthotspot.h
@@ -26,8 +26,8 @@
 namespace AGS3 {
 
 struct ScriptHotspot {
-	int id;
-	int reserved;
+	int id = 0;
+	int reserved = 0;
 };
 
 } // namespace AGS3
diff --git a/engines/ags/engine/ac/dynobj/scriptinvitem.h b/engines/ags/engine/ac/dynobj/scriptinvitem.h
index 962bf59410..5b2175f992 100644
--- a/engines/ags/engine/ac/dynobj/scriptinvitem.h
+++ b/engines/ags/engine/ac/dynobj/scriptinvitem.h
@@ -26,8 +26,8 @@
 namespace AGS3 {
 
 struct ScriptInvItem {
-	int id;
-	int reserved;
+	int id = 0;
+	int reserved = 0;
 };
 
 } // namespace AGS3
diff --git a/engines/ags/engine/ac/dynobj/scriptobject.h b/engines/ags/engine/ac/dynobj/scriptobject.h
index 6292bbddb4..0cb519a6e8 100644
--- a/engines/ags/engine/ac/dynobj/scriptobject.h
+++ b/engines/ags/engine/ac/dynobj/scriptobject.h
@@ -27,11 +27,12 @@
 
 namespace AGS3 {
 
+// TODO: Check whether these should be made int32
 // 64 bit: Struct size must be 8 byte for scripts to work
 struct ScriptObject {
-	int id;
+	int id = 0;
 	//RoomObject *obj;
-	int __padding;
+	int __padding = 0;
 };
 
 } // namespace AGS3
diff --git a/engines/ags/engine/ac/dynobj/scriptregion.h b/engines/ags/engine/ac/dynobj/scriptregion.h
index 743477d65f..dc25f96be5 100644
--- a/engines/ags/engine/ac/dynobj/scriptregion.h
+++ b/engines/ags/engine/ac/dynobj/scriptregion.h
@@ -26,8 +26,8 @@
 namespace AGS3 {
 
 struct ScriptRegion {
-	int id;
-	int reserved;
+	int id = 0;
+	int reserved = 0;
 };
 
 } // namespace AGS3
diff --git a/engines/ags/engine/ac/file.cpp b/engines/ags/engine/ac/file.cpp
index f8a52411a0..f2532ba5a1 100644
--- a/engines/ags/engine/ac/file.cpp
+++ b/engines/ags/engine/ac/file.cpp
@@ -612,7 +612,7 @@ Stream *get_valid_file_stream_from_handle(int32_t handle, const char *operation_
 //
 //=============================================================================
 
-extern ScriptString myScriptStringImpl;
+
 
 // int (const char *fnmm)
 RuntimeScriptValue Sc_File_Delete(const RuntimeScriptValue *params, int32_t param_count) {
@@ -656,7 +656,7 @@ RuntimeScriptValue Sc_File_ReadRawLine(void *self, const RuntimeScriptValue *par
 
 // const char* (sc_File *fil)
 RuntimeScriptValue Sc_File_ReadRawLineBack(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ(sc_File, const char, myScriptStringImpl, File_ReadRawLineBack);
+	API_CONST_OBJCALL_OBJ(sc_File, const char, _GP(myScriptStringImpl), File_ReadRawLineBack);
 }
 
 // void (sc_File *fil, char *toread)
@@ -666,7 +666,7 @@ RuntimeScriptValue Sc_File_ReadString(void *self, const RuntimeScriptValue *para
 
 // const char* (sc_File *fil)
 RuntimeScriptValue Sc_File_ReadStringBack(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ(sc_File, const char, myScriptStringImpl, File_ReadStringBack);
+	API_CONST_OBJCALL_OBJ(sc_File, const char, _GP(myScriptStringImpl), File_ReadStringBack);
 }
 
 // void (sc_File *fil, int towrite)
diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index e82cf8b649..9527e8d6f7 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -167,38 +167,6 @@ int new_room_loop = SCR_NO_VALUE;
 // initially size 1, this will be increased by the initFile function
 int proper_exit = 0, our_eip = 0;
 
-std::vector<GUIMain> guis;
-
-CCGUIObject ccDynamicGUIObject;
-CCCharacter ccDynamicCharacter;
-CCHotspot   ccDynamicHotspot;
-CCRegion    ccDynamicRegion;
-CCInventory ccDynamicInv;
-CCGUI       ccDynamicGUI;
-CCObject    ccDynamicObject;
-CCDialog    ccDynamicDialog;
-CCAudioClip ccDynamicAudioClip;
-CCAudioChannel ccDynamicAudio;
-ScriptString myScriptStringImpl;
-// TODO: IMPORTANT!!
-// we cannot simply replace these arrays with vectors, or other C++ containers,
-// until we implement safe management of such containers in script exports
-// system. Noteably we would need an alternate to StaticArray class to track
-// access to their elements.
-ScriptObject scrObj[MAX_ROOM_OBJECTS];
-ScriptGUI    *scrGui = nullptr;
-ScriptHotspot scrHotspot[MAX_ROOM_HOTSPOTS];
-ScriptRegion scrRegion[MAX_ROOM_REGIONS];
-ScriptInvItem scrInv[MAX_INV];
-ScriptDialog *scrDialog;
-
-ViewStruct *views = nullptr;
-
-CharacterCache *charcache = nullptr;
-ObjectCache objcache[MAX_ROOM_OBJECTS];
-
-MoveList *mls = nullptr;
-
 //=============================================================================
 
 String saveGameDirectory = SAVE_FOLDER_PREFIX;
@@ -529,7 +497,7 @@ void unload_game_file() {
 
 	characterScriptObjNames.clear();
 	free(charextra);
-	free(mls);
+	free(_G(mls));
 	free(actsps);
 	free(actspsbmp);
 	free(actspswb);
@@ -574,11 +542,11 @@ void unload_game_file() {
 	runDialogOptionRepExecFunc.moduleHasFunction.resize(0);
 	numScriptModules = 0;
 
-	free(views);
-	views = nullptr;
+	free(_G(views));
+	_G(views) = nullptr;
 
-	free(charcache);
-	charcache = nullptr;
+	free(_G(charcache));
+	_G(charcache) = nullptr;
 
 	if (splipsync != nullptr) {
 		for (int i = 0; i < numLipLines; ++i) {
@@ -598,8 +566,8 @@ void unload_game_file() {
 	}
 	free(dialog);
 	dialog = nullptr;
-	delete[] scrDialog;
-	scrDialog = nullptr;
+	delete[] _G(scrDialog);
+	_G(scrDialog) = nullptr;
 
 	for (int i = 0; i < _GP(game).numgui; ++i) {
 		free(guibg[i]);
@@ -608,8 +576,8 @@ void unload_game_file() {
 
 	guiScriptObjNames.clear();
 	free(guibg);
-	guis.clear();
-	free(scrGui);
+	_GP(guis).clear();
+	free(_G(scrGui));
 
 	pl_stop_plugins();
 	ccRemoveAllSymbols();
@@ -691,33 +659,33 @@ int Game_GetLoopCountForView(int viewNumber) {
 	if ((viewNumber < 1) || (viewNumber > _GP(game).numviews))
 		quit("!GetGameParameter: invalid view specified");
 
-	return views[viewNumber - 1].numLoops;
+	return _G(views)[viewNumber - 1].numLoops;
 }
 
 int Game_GetRunNextSettingForLoop(int viewNumber, int loopNumber) {
 	if ((viewNumber < 1) || (viewNumber > _GP(game).numviews))
 		quit("!GetGameParameter: invalid view specified");
-	if ((loopNumber < 0) || (loopNumber >= views[viewNumber - 1].numLoops))
+	if ((loopNumber < 0) || (loopNumber >= _G(views)[viewNumber - 1].numLoops))
 		quit("!GetGameParameter: invalid loop specified");
 
-	return (views[viewNumber - 1].loops[loopNumber].RunNextLoop()) ? 1 : 0;
+	return (_G(views)[viewNumber - 1].loops[loopNumber].RunNextLoop()) ? 1 : 0;
 }
 
 int Game_GetFrameCountForLoop(int viewNumber, int loopNumber) {
 	if ((viewNumber < 1) || (viewNumber > _GP(game).numviews))
 		quit("!GetGameParameter: invalid view specified");
-	if ((loopNumber < 0) || (loopNumber >= views[viewNumber - 1].numLoops))
+	if ((loopNumber < 0) || (loopNumber >= _G(views)[viewNumber - 1].numLoops))
 		quit("!GetGameParameter: invalid loop specified");
 
-	return views[viewNumber - 1].loops[loopNumber].numFrames;
+	return _G(views)[viewNumber - 1].loops[loopNumber].numFrames;
 }
 
 ScriptViewFrame *Game_GetViewFrame(int viewNumber, int loopNumber, int frame) {
 	if ((viewNumber < 1) || (viewNumber > _GP(game).numviews))
 		quit("!GetGameParameter: invalid view specified");
-	if ((loopNumber < 0) || (loopNumber >= views[viewNumber - 1].numLoops))
+	if ((loopNumber < 0) || (loopNumber >= _G(views)[viewNumber - 1].numLoops))
 		quit("!GetGameParameter: invalid loop specified");
-	if ((frame < 0) || (frame >= views[viewNumber - 1].loops[loopNumber].numFrames))
+	if ((frame < 0) || (frame >= _G(views)[viewNumber - 1].loops[loopNumber].numFrames))
 		quit("!GetGameParameter: invalid frame specified");
 
 	ScriptViewFrame *sdt = new ScriptViewFrame(viewNumber - 1, loopNumber, frame);
@@ -1195,7 +1163,7 @@ void restore_game_play(Stream *in, RestoredData &r_data) {
 void ReadMoveList_Aligned(Stream *in) {
 	AlignedStream align_s(in, Shared::kAligned_Read);
 	for (int i = 0; i < _GP(game).numcharacters + MAX_ROOM_OBJECTS + 1; ++i) {
-		mls[i].ReadFromFile_Legacy(&align_s);
+		_G(mls)[i].ReadFromFile_Legacy(&align_s);
 
 		align_s.Reset();
 	}
@@ -1240,10 +1208,10 @@ void ReadAnimatedButtons_Aligned(Stream *in) {
 }
 
 HSaveError restore_game_gui(Stream *in, int numGuisWas) {
-	HError err = GUI::ReadGUI(guis, in, true);
+	HError err = GUI::ReadGUI(_GP(guis), in, true);
 	if (!err)
 		return new SavegameError(kSvgErr_GameObjectInitFailed, err);
-	_GP(game).numgui = guis.size();
+	_GP(game).numgui = _GP(guis).size();
 
 	if (numGuisWas != _GP(game).numgui) {
 		return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of GUI.");
@@ -1363,10 +1331,10 @@ HSaveError restore_game_views(Stream *in) {
 	}
 
 	for (int bb = 0; bb < _GP(game).numviews; bb++) {
-		for (int cc = 0; cc < views[bb].numLoops; cc++) {
-			for (int dd = 0; dd < views[bb].loops[cc].numFrames; dd++) {
-				views[bb].loops[cc].frames[dd].sound = in->ReadInt32();
-				views[bb].loops[cc].frames[dd].pic = in->ReadInt32();
+		for (int cc = 0; cc < _G(views)[bb].numLoops; cc++) {
+			for (int dd = 0; dd < _G(views)[bb].loops[cc].numFrames; dd++) {
+				_G(views)[bb].loops[cc].frames[dd].sound = in->ReadInt32();
+				_G(views)[bb].loops[cc].frames[dd].pic = in->ReadInt32();
 			}
 		}
 	}
@@ -1920,9 +1888,9 @@ void get_message_text(int msnum, char *buffer, char giveErr) {
 
 bool unserialize_audio_script_object(int index, const char *objectType, const char *serializedData, int dataSize) {
 	if (strcmp(objectType, "AudioChannel") == 0) {
-		ccDynamicAudio.Unserialize(index, serializedData, dataSize);
+		_GP(ccDynamicAudio).Unserialize(index, serializedData, dataSize);
 	} else if (strcmp(objectType, "AudioClip") == 0) {
-		ccDynamicAudioClip.Unserialize(index, serializedData, dataSize);
+		_GP(ccDynamicAudioClip).Unserialize(index, serializedData, dataSize);
 	} else {
 		return false;
 	}
@@ -1977,7 +1945,7 @@ RuntimeScriptValue Sc_Game_GetFrameCountForLoop(const RuntimeScriptValue *params
 
 // const char* (int x, int y)
 RuntimeScriptValue Sc_Game_GetLocationName(const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_SCALL_OBJ_PINT2(const char, myScriptStringImpl, Game_GetLocationName);
+	API_CONST_SCALL_OBJ_PINT2(const char, _GP(myScriptStringImpl), Game_GetLocationName);
 }
 
 // int (int viewNumber)
@@ -1997,7 +1965,7 @@ RuntimeScriptValue Sc_Game_GetRunNextSettingForLoop(const RuntimeScriptValue *pa
 
 // const char* (int slnum)
 RuntimeScriptValue Sc_Game_GetSaveSlotDescription(const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_SCALL_OBJ_PINT(const char, myScriptStringImpl, Game_GetSaveSlotDescription);
+	API_CONST_SCALL_OBJ_PINT(const char, _GP(myScriptStringImpl), Game_GetSaveSlotDescription);
 }
 
 // ScriptViewFrame* (int viewNumber, int loopNumber, int frame)
@@ -2007,7 +1975,7 @@ RuntimeScriptValue Sc_Game_GetViewFrame(const RuntimeScriptValue *params, int32_
 
 // const char* (const char *msg)
 RuntimeScriptValue Sc_Game_InputBox(const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_SCALL_OBJ_POBJ(const char, myScriptStringImpl, Game_InputBox, const char);
+	API_CONST_SCALL_OBJ_POBJ(const char, _GP(myScriptStringImpl), Game_InputBox, const char);
 }
 
 // int (const char *newFolder)
@@ -2032,7 +2000,7 @@ RuntimeScriptValue Sc_Game_GetDialogCount(const RuntimeScriptValue *params, int3
 
 // const char *()
 RuntimeScriptValue Sc_Game_GetFileName(const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_SCALL_OBJ(const char, myScriptStringImpl, Game_GetFileName);
+	API_CONST_SCALL_OBJ(const char, _GP(myScriptStringImpl), Game_GetFileName);
 }
 
 // int ()
@@ -2042,12 +2010,12 @@ RuntimeScriptValue Sc_Game_GetFontCount(const RuntimeScriptValue *params, int32_
 
 // const char* (int index)
 RuntimeScriptValue Sc_Game_GetGlobalMessages(const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_SCALL_OBJ_PINT(const char, myScriptStringImpl, Game_GetGlobalMessages);
+	API_CONST_SCALL_OBJ_PINT(const char, _GP(myScriptStringImpl), Game_GetGlobalMessages);
 }
 
 // const char* (int index)
 RuntimeScriptValue Sc_Game_GetGlobalStrings(const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_SCALL_OBJ_PINT(const char, myScriptStringImpl, Game_GetGlobalStrings);
+	API_CONST_SCALL_OBJ_PINT(const char, _GP(myScriptStringImpl), Game_GetGlobalStrings);
 }
 
 // void  (int index, char *newval);
@@ -2097,7 +2065,7 @@ RuntimeScriptValue Sc_Game_GetMouseCursorCount(const RuntimeScriptValue *params,
 
 // const char *()
 RuntimeScriptValue Sc_Game_GetName(const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_SCALL_OBJ(const char, myScriptStringImpl, Game_GetName);
+	API_CONST_SCALL_OBJ(const char, _GP(myScriptStringImpl), Game_GetName);
 }
 
 // void (const char *newName)
@@ -2152,7 +2120,7 @@ RuntimeScriptValue Sc_Game_SetTextReadingSpeed(const RuntimeScriptValue *params,
 
 // const char* ()
 RuntimeScriptValue Sc_Game_GetTranslationFilename(const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_SCALL_OBJ(const char, myScriptStringImpl, Game_GetTranslationFilename);
+	API_CONST_SCALL_OBJ(const char, _GP(myScriptStringImpl), Game_GetTranslationFilename);
 }
 
 // int ()
@@ -2170,7 +2138,7 @@ RuntimeScriptValue Sc_Game_GetAudioClipCount(const RuntimeScriptValue *params, i
 }
 
 RuntimeScriptValue Sc_Game_GetAudioClip(const RuntimeScriptValue *params, int32_t param_count) {
-	API_SCALL_OBJ_PINT(ScriptAudioClip, ccDynamicAudioClip, Game_GetAudioClip);
+	API_SCALL_OBJ_PINT(ScriptAudioClip, _GP(ccDynamicAudioClip), Game_GetAudioClip);
 }
 
 RuntimeScriptValue Sc_Game_IsPluginLoaded(const RuntimeScriptValue *params, int32_t param_count) {
@@ -2178,7 +2146,7 @@ RuntimeScriptValue Sc_Game_IsPluginLoaded(const RuntimeScriptValue *params, int3
 }
 
 RuntimeScriptValue Sc_Game_PlayVoiceClip(const RuntimeScriptValue *params, int32_t param_count) {
-	API_SCALL_OBJ_POBJ_PINT_PBOOL(ScriptAudioChannel, ccDynamicAudio, PlayVoiceClip, CharacterInfo);
+	API_SCALL_OBJ_POBJ_PINT_PBOOL(ScriptAudioChannel, _GP(ccDynamicAudio), PlayVoiceClip, CharacterInfo);
 }
 
 RuntimeScriptValue Sc_Game_GetCamera(const RuntimeScriptValue *params, int32_t param_count) {
diff --git a/engines/ags/engine/ac/global_api.cpp b/engines/ags/engine/ac/global_api.cpp
index 20fd5507a4..817bdfcfc2 100644
--- a/engines/ags/engine/ac/global_api.cpp
+++ b/engines/ags/engine/ac/global_api.cpp
@@ -29,7 +29,6 @@
 #include "ags/shared/debugging/out.h"
 #include "ags/engine/script/script_api.h"
 #include "ags/engine/script/script_runtime.h"
-
 #include "ags/engine/ac/cdaudio.h"
 #include "ags/engine/ac/display.h"
 #include "ags/engine/ac/dynamicsprite.h"
@@ -79,13 +78,11 @@
 #include "ags/engine/media/video/video.h"
 #include "ags/shared/util/string_compat.h"
 #include "ags/engine/media/audio/audio_system.h"
-
 #include "ags/engine/ac/dynobj/scriptstring.h"
+#include "ags/globals.h"
 
 namespace AGS3 {
 
-extern ScriptString myScriptStringImpl;
-
 // void (char*texx, ...)
 RuntimeScriptValue Sc_sc_AbortGame(const RuntimeScriptValue *params, int32_t param_count) {
 	API_SCALL_SCRIPT_SPRINTF(_sc_AbortGame, 1);
@@ -691,7 +688,7 @@ RuntimeScriptValue Sc_sc_GetTime(const RuntimeScriptValue *params, int32_t param
 
 // char * (const char *text)
 RuntimeScriptValue Sc_get_translation(const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_SCALL_OBJ_POBJ(const char, myScriptStringImpl, get_translation, const char);
+	API_CONST_SCALL_OBJ_POBJ(const char, _GP(myScriptStringImpl), get_translation, const char);
 }
 
 // int  (char* buffer)
@@ -872,7 +869,7 @@ RuntimeScriptValue Sc_ListBoxDirList(const RuntimeScriptValue *params, int32_t p
 
 // char* (int guin, int objn, int item, char*buffer)
 RuntimeScriptValue Sc_ListBoxGetItemText(const RuntimeScriptValue *params, int32_t param_count) {
-	API_SCALL_OBJ_PINT3_POBJ(char, myScriptStringImpl, ListBoxGetItemText, char);
+	API_SCALL_OBJ_PINT3_POBJ(char, _GP(myScriptStringImpl), ListBoxGetItemText, char);
 }
 
 // int (int guin, int objn)
diff --git a/engines/ags/engine/ac/global_button.cpp b/engines/ags/engine/ac/global_button.cpp
index f5e25f65c1..f44f9a2093 100644
--- a/engines/ags/engine/ac/global_button.cpp
+++ b/engines/ags/engine/ac/global_button.cpp
@@ -37,34 +37,34 @@ void SetButtonText(int guin, int objn, const char *newtx) {
 	VALIDATE_STRING(newtx);
 	if ((guin < 0) | (guin >= _GP(game).numgui))
 		quit("!SetButtonText: invalid GUI number");
-	if ((objn < 0) | (objn >= guis[guin].GetControlCount()))
+	if ((objn < 0) | (objn >= _GP(guis)[guin].GetControlCount()))
 		quit("!SetButtonText: invalid object number");
-	if (guis[guin].GetControlType(objn) != kGUIButton)
+	if (_GP(guis)[guin].GetControlType(objn) != kGUIButton)
 		quit("!SetButtonText: specified control is not a button");
 
-	GUIButton *guil = (GUIButton *)guis[guin].GetControl(objn);
+	GUIButton *guil = (GUIButton *)_GP(guis)[guin].GetControl(objn);
 	Button_SetText(guil, newtx);
 }
 
 
 void AnimateButton(int guin, int objn, int view, int loop, int speed, int repeat) {
 	if ((guin < 0) | (guin >= _GP(game).numgui)) quit("!AnimateButton: invalid GUI number");
-	if ((objn < 0) | (objn >= guis[guin].GetControlCount())) quit("!AnimateButton: invalid object number");
-	if (guis[guin].GetControlType(objn) != kGUIButton)
+	if ((objn < 0) | (objn >= _GP(guis)[guin].GetControlCount())) quit("!AnimateButton: invalid object number");
+	if (_GP(guis)[guin].GetControlType(objn) != kGUIButton)
 		quit("!AnimateButton: specified control is not a button");
 
-	Button_Animate((GUIButton *)guis[guin].GetControl(objn), view, loop, speed, repeat);
+	Button_Animate((GUIButton *)_GP(guis)[guin].GetControl(objn), view, loop, speed, repeat);
 }
 
 
 int GetButtonPic(int guin, int objn, int ptype) {
 	if ((guin < 0) | (guin >= _GP(game).numgui)) quit("!GetButtonPic: invalid GUI number");
-	if ((objn < 0) | (objn >= guis[guin].GetControlCount())) quit("!GetButtonPic: invalid object number");
-	if (guis[guin].GetControlType(objn) != kGUIButton)
+	if ((objn < 0) | (objn >= _GP(guis)[guin].GetControlCount())) quit("!GetButtonPic: invalid object number");
+	if (_GP(guis)[guin].GetControlType(objn) != kGUIButton)
 		quit("!GetButtonPic: specified control is not a button");
 	if ((ptype < 0) | (ptype > 3)) quit("!GetButtonPic: invalid pic type");
 
-	GUIButton *guil = (GUIButton *)guis[guin].GetControl(objn);
+	GUIButton *guil = (GUIButton *)_GP(guis)[guin].GetControl(objn);
 
 	if (ptype == 0) {
 		// currently displayed pic
@@ -84,12 +84,12 @@ int GetButtonPic(int guin, int objn, int ptype) {
 
 void SetButtonPic(int guin, int objn, int ptype, int slotn) {
 	if ((guin < 0) | (guin >= _GP(game).numgui)) quit("!SetButtonPic: invalid GUI number");
-	if ((objn < 0) | (objn >= guis[guin].GetControlCount())) quit("!SetButtonPic: invalid object number");
-	if (guis[guin].GetControlType(objn) != kGUIButton)
+	if ((objn < 0) | (objn >= _GP(guis)[guin].GetControlCount())) quit("!SetButtonPic: invalid object number");
+	if (_GP(guis)[guin].GetControlType(objn) != kGUIButton)
 		quit("!SetButtonPic: specified control is not a button");
 	if ((ptype < 1) | (ptype > 3)) quit("!SetButtonPic: invalid pic type");
 
-	GUIButton *guil = (GUIButton *)guis[guin].GetControl(objn);
+	GUIButton *guil = (GUIButton *)_GP(guis)[guin].GetControl(objn);
 	if (ptype == 1) {
 		Button_SetNormalGraphic(guil, slotn);
 	} else if (ptype == 2) {
diff --git a/engines/ags/engine/ac/global_character.cpp b/engines/ags/engine/ac/global_character.cpp
index 4cad7011e4..1be04f2ff7 100644
--- a/engines/ags/engine/ac/global_character.cpp
+++ b/engines/ags/engine/ac/global_character.cpp
@@ -53,14 +53,8 @@ namespace AGS3 {
 using namespace AGS::Shared;
 
 
-
-extern ViewStruct *views;
 extern RoomObject *objs;
 
-
-extern ScriptObject scrObj[MAX_ROOM_OBJECTS];
-extern ScriptInvItem scrInv[MAX_INV];
-
 // defined in character unit
 extern CharacterExtras *charextra;
 extern CharacterInfo *playerchar;
@@ -118,13 +112,13 @@ int GetCharacterWidth(int ww) {
 
 	if (charextra[ww].width < 1) {
 		if ((char1->view < 0) ||
-			(char1->loop >= views[char1->view].numLoops) ||
-			(char1->frame >= views[char1->view].loops[char1->loop].numFrames)) {
+			(char1->loop >= _G(views)[char1->view].numLoops) ||
+			(char1->frame >= _G(views)[char1->view].loops[char1->loop].numFrames)) {
 			debug_script_warn("GetCharacterWidth: Character %s has invalid frame: view %d, loop %d, frame %d", char1->scrname, char1->view + 1, char1->loop, char1->frame);
 			return data_to_game_coord(4);
 		}
 
-		return _GP(game).SpriteInfos[views[char1->view].loops[char1->loop].frames[char1->frame].pic].Width;
+		return _GP(game).SpriteInfos[_G(views)[char1->view].loops[char1->loop].frames[char1->frame].pic].Width;
 	} else
 		return charextra[ww].width;
 }
@@ -134,13 +128,13 @@ int GetCharacterHeight(int charid) {
 
 	if (charextra[charid].height < 1) {
 		if ((char1->view < 0) ||
-			(char1->loop >= views[char1->view].numLoops) ||
-			(char1->frame >= views[char1->view].loops[char1->loop].numFrames)) {
+			(char1->loop >= _G(views)[char1->view].numLoops) ||
+			(char1->frame >= _G(views)[char1->view].loops[char1->loop].numFrames)) {
 			debug_script_warn("GetCharacterHeight: Character %s has invalid frame: view %d, loop %d, frame %d", char1->scrname, char1->view + 1, char1->loop, char1->frame);
 			return data_to_game_coord(2);
 		}
 
-		return _GP(game).SpriteInfos[views[char1->view].loops[char1->loop].frames[char1->frame].pic].Height;
+		return _GP(game).SpriteInfos[_G(views)[char1->view].loops[char1->loop].frames[char1->frame].pic].Height;
 	} else
 		return charextra[charid].height;
 }
@@ -417,7 +411,7 @@ int AreCharObjColliding(int charid, int objid) {
 	if (!is_valid_object(objid))
 		quit("!AreCharObjColliding: invalid object number");
 
-	return Character_IsCollidingWithObject(&_GP(game).chars[charid], &scrObj[objid]);
+	return Character_IsCollidingWithObject(&_GP(game).chars[charid], &_G(scrObj)[objid]);
 }
 
 int AreCharactersColliding(int cchar1, int cchar2) {
@@ -457,7 +451,7 @@ void SetActiveInventory(int iit) {
 
 	ScriptInvItem *tosend = nullptr;
 	if ((iit > 0) && (iit < _GP(game).numinvitems))
-		tosend = &scrInv[iit];
+		tosend = &_G(scrInv)[iit];
 	else if (iit != -1)
 		quitprintf("!SetActiveInventory: invalid inventory number %d", iit);
 
@@ -494,7 +488,7 @@ void add_inventory(int inum) {
 	if ((inum < 0) || (inum >= MAX_INV))
 		quit("!AddInventory: invalid inventory number");
 
-	Character_AddInventory(playerchar, &scrInv[inum], SCR_NO_VALUE);
+	Character_AddInventory(playerchar, &_G(scrInv)[inum], SCR_NO_VALUE);
 
 	_GP(play).obsolete_inv_numorder = charextra[_GP(game).playercharacter].invorder_count;
 }
@@ -503,7 +497,7 @@ void lose_inventory(int inum) {
 	if ((inum < 0) || (inum >= MAX_INV))
 		quit("!LoseInventory: invalid inventory number");
 
-	Character_LoseInventory(playerchar, &scrInv[inum]);
+	Character_LoseInventory(playerchar, &_G(scrInv)[inum]);
 
 	_GP(play).obsolete_inv_numorder = charextra[_GP(game).playercharacter].invorder_count;
 }
@@ -514,7 +508,7 @@ void AddInventoryToCharacter(int charid, int inum) {
 	if ((inum < 1) || (inum >= _GP(game).numinvitems))
 		quit("!AddInventory: invalid inv item specified");
 
-	Character_AddInventory(&_GP(game).chars[charid], &scrInv[inum], SCR_NO_VALUE);
+	Character_AddInventory(&_GP(game).chars[charid], &_G(scrInv)[inum], SCR_NO_VALUE);
 }
 
 void LoseInventoryFromCharacter(int charid, int inum) {
@@ -523,7 +517,7 @@ void LoseInventoryFromCharacter(int charid, int inum) {
 	if ((inum < 1) || (inum >= _GP(game).numinvitems))
 		quit("!AddInventory: invalid inv item specified");
 
-	Character_LoseInventory(&_GP(game).chars[charid], &scrInv[inum]);
+	Character_LoseInventory(&_GP(game).chars[charid], &_G(scrInv)[inum]);
 }
 
 void DisplayThought(int chid, const char *text) {
diff --git a/engines/ags/engine/ac/global_debug.cpp b/engines/ags/engine/ac/global_debug.cpp
index 658fa0a0f1..fbca3d3136 100644
--- a/engines/ags/engine/ac/global_debug.cpp
+++ b/engines/ags/engine/ac/global_debug.cpp
@@ -64,7 +64,7 @@ extern IGraphicsDriver *gfxDriver;
 
 extern TreeMap *transtree;
 extern int displayed_room, starting_room;
-extern MoveList *mls;
+
 extern char transFileName[MAX_PATH];
 
 String GetRuntimeInfo() {
@@ -107,7 +107,7 @@ void script_debug(int cmdd, int dataa) {
 		Display(toDisplay.GetCStr());
 		//    Display("shftR: %d  shftG: %d  shftB: %d", _rgb_r_shift_16, _rgb_g_shift_16, _rgb_b_shift_16);
 		//    Display("Remaining memory: %d kb",_go32_dpmi_remaining_virtual_memory()/1024);
-		//Display("Play char bcd: %d",->GetColorDepth(_GP(spriteset)[views[playerchar->view].frames[playerchar->loop][playerchar->frame].pic]));
+		//Display("Play char bcd: %d",->GetColorDepth(_GP(spriteset)[_G(views)[playerchar->view].frames[playerchar->loop][playerchar->frame].pic]));
 	} else if (cmdd == 2) {
 		// show walkable areas from here
 		// TODO: support multiple viewports?!
@@ -157,7 +157,7 @@ void script_debug(int cmdd, int dataa) {
 		int mlsnum = _GP(game).chars[dataa].walking;
 		if (_GP(game).chars[dataa].walking >= TURNING_AROUND)
 			mlsnum %= TURNING_AROUND;
-		MoveList *cmls = &mls[mlsnum];
+		MoveList *cmls = &_G(mls)[mlsnum];
 		for (int i = 0; i < cmls->numstage - 1; i++) {
 			short srcx = short((cmls->pos[i] >> 16) & 0x00ffff);
 			short srcy = short(cmls->pos[i] & 0x00ffff);
diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp
index c22c9156b0..c64542222d 100644
--- a/engines/ags/engine/ac/global_game.cpp
+++ b/engines/ags/engine/ac/global_game.cpp
@@ -87,7 +87,7 @@ extern GameSetup usetup;
 extern unsigned int load_new_game;
 extern int load_new_game_restore;
 
-extern ViewStruct *views;
+
 extern RoomStatus *croom;
 extern int gui_disabled_style;
 
@@ -328,14 +328,14 @@ int GetGameParameter(int parm, int data1, int data2, int data3) {
 		if ((data1 < 1) || (data1 > _GP(game).numviews)) {
 			quitprintf("!GetGameParameter: invalid view specified (v: %d, l: %d, f: %d)", data1, data2, data3);
 		}
-		if ((data2 < 0) || (data2 >= views[data1 - 1].numLoops)) {
+		if ((data2 < 0) || (data2 >= _G(views)[data1 - 1].numLoops)) {
 			quitprintf("!GetGameParameter: invalid loop specified (v: %d, l: %d, f: %d)", data1, data2, data3);
 		}
-		if ((data3 < 0) || (data3 >= views[data1 - 1].loops[data2].numFrames)) {
+		if ((data3 < 0) || (data3 >= _G(views)[data1 - 1].loops[data2].numFrames)) {
 			quitprintf("!GetGameParameter: invalid frame specified (v: %d, l: %d, f: %d)", data1, data2, data3);
 		}
 
-		ViewFrame *pvf = &views[data1 - 1].loops[data2].frames[data3];
+		ViewFrame *pvf = &_G(views)[data1 - 1].loops[data2].frames[data3];
 
 		if (parm == GP_FRAMESPEED)
 			return pvf->speed;
diff --git a/engines/ags/engine/ac/global_gui.cpp b/engines/ags/engine/ac/global_gui.cpp
index 76db50f33e..d20b7ea4e5 100644
--- a/engines/ags/engine/ac/global_gui.cpp
+++ b/engines/ags/engine/ac/global_gui.cpp
@@ -42,23 +42,23 @@ namespace AGS3 {
 using namespace AGS::Shared;
 
 
-extern ScriptGUI *scrGui;
+
 
 int IsGUIOn(int guinum) {
 	if ((guinum < 0) || (guinum >= _GP(game).numgui))
 		quit("!IsGUIOn: invalid GUI number specified");
-	return (guis[guinum].IsDisplayed()) ? 1 : 0;
+	return (_GP(guis)[guinum].IsDisplayed()) ? 1 : 0;
 }
 
 // This is an internal script function, and is undocumented.
 // It is used by the editor's automatic macro generation.
 int FindGUIID(const char *GUIName) {
 	for (int ii = 0; ii < _GP(game).numgui; ii++) {
-		if (guis[ii].Name.IsEmpty())
+		if (_GP(guis)[ii].Name.IsEmpty())
 			continue;
-		if (strcmp(guis[ii].Name, GUIName) == 0)
+		if (strcmp(_GP(guis)[ii].Name, GUIName) == 0)
 			return ii;
-		if ((guis[ii].Name[0u] == 'g') && (ags_stricmp(guis[ii].Name.GetCStr() + 1, GUIName) == 0))
+		if ((_GP(guis)[ii].Name[0u] == 'g') && (ags_stricmp(_GP(guis)[ii].Name.GetCStr() + 1, GUIName) == 0))
 			return ii;
 	}
 	quit("FindGUIID: No matching GUI found: GUI may have been deleted");
@@ -71,93 +71,93 @@ void InterfaceOn(int ifn) {
 
 	EndSkippingUntilCharStops();
 
-	if (guis[ifn].IsVisible()) {
+	if (_GP(guis)[ifn].IsVisible()) {
 		debug_script_log("GUIOn(%d) ignored (already on)", ifn);
 		return;
 	}
 	guis_need_update = 1;
-	guis[ifn].SetVisible(true);
+	_GP(guis)[ifn].SetVisible(true);
 	debug_script_log("GUI %d turned on", ifn);
 	// modal interface
-	if (guis[ifn].PopupStyle == kGUIPopupModal) PauseGame();
+	if (_GP(guis)[ifn].PopupStyle == kGUIPopupModal) PauseGame();
 	// clear the cached mouse position
-	guis[ifn].OnControlPositionChanged();
-	guis[ifn].Poll();
+	_GP(guis)[ifn].OnControlPositionChanged();
+	_GP(guis)[ifn].Poll();
 }
 
 void InterfaceOff(int ifn) {
 	if ((ifn < 0) | (ifn >= _GP(game).numgui)) quit("!GUIOff: invalid GUI specified");
-	if (!guis[ifn].IsVisible()) {
+	if (!_GP(guis)[ifn].IsVisible()) {
 		debug_script_log("GUIOff(%d) ignored (already off)", ifn);
 		return;
 	}
 	debug_script_log("GUI %d turned off", ifn);
-	guis[ifn].SetVisible(false);
-	if (guis[ifn].MouseOverCtrl >= 0) {
+	_GP(guis)[ifn].SetVisible(false);
+	if (_GP(guis)[ifn].MouseOverCtrl >= 0) {
 		// Make sure that the overpic is turned off when the GUI goes off
-		guis[ifn].GetControl(guis[ifn].MouseOverCtrl)->OnMouseLeave();
-		guis[ifn].MouseOverCtrl = -1;
+		_GP(guis)[ifn].GetControl(_GP(guis)[ifn].MouseOverCtrl)->OnMouseLeave();
+		_GP(guis)[ifn].MouseOverCtrl = -1;
 	}
-	guis[ifn].OnControlPositionChanged();
+	_GP(guis)[ifn].OnControlPositionChanged();
 	guis_need_update = 1;
 	// modal interface
-	if (guis[ifn].PopupStyle == kGUIPopupModal) UnPauseGame();
+	if (_GP(guis)[ifn].PopupStyle == kGUIPopupModal) UnPauseGame();
 }
 
 void SetGUIObjectEnabled(int guin, int objn, int enabled) {
 	if ((guin < 0) || (guin >= _GP(game).numgui))
 		quit("!SetGUIObjectEnabled: invalid GUI number");
-	if ((objn < 0) || (objn >= guis[guin].GetControlCount()))
+	if ((objn < 0) || (objn >= _GP(guis)[guin].GetControlCount()))
 		quit("!SetGUIObjectEnabled: invalid object number");
 
-	GUIControl_SetEnabled(guis[guin].GetControl(objn), enabled);
+	GUIControl_SetEnabled(_GP(guis)[guin].GetControl(objn), enabled);
 }
 
 void SetGUIObjectPosition(int guin, int objn, int xx, int yy) {
 	if ((guin < 0) || (guin >= _GP(game).numgui))
 		quit("!SetGUIObjectPosition: invalid GUI number");
-	if ((objn < 0) || (objn >= guis[guin].GetControlCount()))
+	if ((objn < 0) || (objn >= _GP(guis)[guin].GetControlCount()))
 		quit("!SetGUIObjectPosition: invalid object number");
 
-	GUIControl_SetPosition(guis[guin].GetControl(objn), xx, yy);
+	GUIControl_SetPosition(_GP(guis)[guin].GetControl(objn), xx, yy);
 }
 
 void SetGUIPosition(int ifn, int xx, int yy) {
 	if ((ifn < 0) || (ifn >= _GP(game).numgui))
 		quit("!SetGUIPosition: invalid GUI number");
 
-	GUI_SetPosition(&scrGui[ifn], xx, yy);
+	GUI_SetPosition(&_G(scrGui)[ifn], xx, yy);
 }
 
 void SetGUIObjectSize(int ifn, int objn, int newwid, int newhit) {
 	if ((ifn < 0) || (ifn >= _GP(game).numgui))
 		quit("!SetGUIObjectSize: invalid GUI number");
 
-	if ((objn < 0) || (objn >= guis[ifn].GetControlCount()))
+	if ((objn < 0) || (objn >= _GP(guis)[ifn].GetControlCount()))
 		quit("!SetGUIObjectSize: invalid object number");
 
-	GUIControl_SetSize(guis[ifn].GetControl(objn), newwid, newhit);
+	GUIControl_SetSize(_GP(guis)[ifn].GetControl(objn), newwid, newhit);
 }
 
 void SetGUISize(int ifn, int widd, int hitt) {
 	if ((ifn < 0) || (ifn >= _GP(game).numgui))
 		quit("!SetGUISize: invalid GUI number");
 
-	GUI_SetSize(&scrGui[ifn], widd, hitt);
+	GUI_SetSize(&_G(scrGui)[ifn], widd, hitt);
 }
 
 void SetGUIZOrder(int guin, int z) {
 	if ((guin < 0) || (guin >= _GP(game).numgui))
 		quit("!SetGUIZOrder: invalid GUI number");
 
-	GUI_SetZOrder(&scrGui[guin], z);
+	GUI_SetZOrder(&_G(scrGui)[guin], z);
 }
 
 void SetGUIClickable(int guin, int clickable) {
 	if ((guin < 0) || (guin >= _GP(game).numgui))
 		quit("!SetGUIClickable: invalid GUI number");
 
-	GUI_SetClickable(&scrGui[guin], clickable);
+	GUI_SetClickable(&_G(scrGui)[guin], clickable);
 }
 
 // pass trans=0 for fully solid, trans=100 for fully transparent
@@ -165,14 +165,14 @@ void SetGUITransparency(int ifn, int trans) {
 	if ((ifn < 0) | (ifn >= _GP(game).numgui))
 		quit("!SetGUITransparency: invalid GUI number");
 
-	GUI_SetTransparency(&scrGui[ifn], trans);
+	GUI_SetTransparency(&_G(scrGui)[ifn], trans);
 }
 
 void CentreGUI(int ifn) {
 	if ((ifn < 0) | (ifn >= _GP(game).numgui))
 		quit("!CentreGUI: invalid GUI number");
 
-	GUI_Centre(&scrGui[ifn]);
+	GUI_Centre(&_G(scrGui)[ifn]);
 }
 
 int GetTextWidth(const char *text, int fontnum) {
@@ -209,7 +209,7 @@ void SetGUIBackgroundPic(int guin, int slotn) {
 	if ((guin < 0) | (guin >= _GP(game).numgui))
 		quit("!SetGUIBackgroundPic: invalid GUI number");
 
-	GUI_SetBackgroundGraphic(&scrGui[guin], slotn);
+	GUI_SetBackgroundGraphic(&_G(scrGui)[guin], slotn);
 }
 
 void DisableInterface() {
@@ -245,7 +245,7 @@ int GetGUIAt(int xx, int yy) {
 	int aa, ll;
 	for (ll = _GP(game).numgui - 1; ll >= 0; ll--) {
 		aa = _GP(play).gui_draw_order[ll];
-		if (guis[aa].IsInteractableAt(xx, yy))
+		if (_GP(guis)[aa].IsInteractableAt(xx, yy))
 			return aa;
 	}
 	return -1;
@@ -256,7 +256,7 @@ void SetTextWindowGUI(int guinum) {
 		quit("!SetTextWindowGUI: invalid GUI number");
 
 	if (guinum < 0);  // disable it
-	else if (!guis[guinum].IsTextWindow())
+	else if (!_GP(guis)[guinum].IsTextWindow())
 		quit("!SetTextWindowGUI: specified GUI is not a text window");
 
 	if (_GP(play).speech_textwindow_gui == _GP(game).options[OPT_TWCUSTOM])
diff --git a/engines/ags/engine/ac/global_inventoryitem.cpp b/engines/ags/engine/ac/global_inventoryitem.cpp
index 342e0673b9..da80d98935 100644
--- a/engines/ags/engine/ac/global_inventoryitem.cpp
+++ b/engines/ags/engine/ac/global_inventoryitem.cpp
@@ -80,17 +80,17 @@ int GetInvAt(int xxx, int yyy) {
 	int ongui = GetGUIAt(xxx, yyy);
 	if (ongui >= 0) {
 		int mxwas = _G(mousex), mywas = _G(mousey);
-		_G(mousex) = data_to_game_coord(xxx) - guis[ongui].X;
-		_G(mousey) = data_to_game_coord(yyy) - guis[ongui].Y;
-		int onobj = guis[ongui].FindControlUnderMouse();
-		GUIObject *guio = guis[ongui].GetControl(onobj);
+		_G(mousex) = data_to_game_coord(xxx) - _GP(guis)[ongui].X;
+		_G(mousey) = data_to_game_coord(yyy) - _GP(guis)[ongui].Y;
+		int onobj = _GP(guis)[ongui].FindControlUnderMouse();
+		GUIObject *guio = _GP(guis)[ongui].GetControl(onobj);
 		if (guio) {
 			mouse_ifacebut_xoffs = _G(mousex) - (guio->X);
 			mouse_ifacebut_yoffs = _G(mousey) - (guio->Y);
 		}
 		_G(mousex) = mxwas;
 		_G(mousey) = mywas;
-		if (guio && (guis[ongui].GetControlType(onobj) == kGUIInvWindow))
+		if (guio && (_GP(guis)[ongui].GetControlType(onobj) == kGUIInvWindow))
 			return offset_over_inv((GUIInvWindow *)guio);
 	}
 	return -1;
diff --git a/engines/ags/engine/ac/global_label.cpp b/engines/ags/engine/ac/global_label.cpp
index 03b6c089b1..562d6fd54e 100644
--- a/engines/ags/engine/ac/global_label.cpp
+++ b/engines/ags/engine/ac/global_label.cpp
@@ -35,34 +35,34 @@ using namespace AGS::Shared;
 void SetLabelColor(int guin, int objn, int colr) {
 	if ((guin < 0) | (guin >= _GP(game).numgui))
 		quit("!SetLabelColor: invalid GUI number");
-	if ((objn < 0) | (objn >= guis[guin].GetControlCount()))
+	if ((objn < 0) | (objn >= _GP(guis)[guin].GetControlCount()))
 		quit("!SetLabelColor: invalid object number");
-	if (guis[guin].GetControlType(objn) != kGUILabel)
+	if (_GP(guis)[guin].GetControlType(objn) != kGUILabel)
 		quit("!SetLabelColor: specified control is not a label");
 
-	GUILabel *guil = (GUILabel *)guis[guin].GetControl(objn);
+	GUILabel *guil = (GUILabel *)_GP(guis)[guin].GetControl(objn);
 	Label_SetColor(guil, colr);
 }
 
 void SetLabelText(int guin, int objn, const char *newtx) {
 	VALIDATE_STRING(newtx);
 	if ((guin < 0) | (guin >= _GP(game).numgui)) quit("!SetLabelText: invalid GUI number");
-	if ((objn < 0) | (objn >= guis[guin].GetControlCount())) quit("!SetLabelTexT: invalid object number");
-	if (guis[guin].GetControlType(objn) != kGUILabel)
+	if ((objn < 0) | (objn >= _GP(guis)[guin].GetControlCount())) quit("!SetLabelTexT: invalid object number");
+	if (_GP(guis)[guin].GetControlType(objn) != kGUILabel)
 		quit("!SetLabelText: specified control is not a label");
 
-	GUILabel *guil = (GUILabel *)guis[guin].GetControl(objn);
+	GUILabel *guil = (GUILabel *)_GP(guis)[guin].GetControl(objn);
 	Label_SetText(guil, newtx);
 }
 
 void SetLabelFont(int guin, int objn, int fontnum) {
 
 	if ((guin < 0) | (guin >= _GP(game).numgui)) quit("!SetLabelFont: invalid GUI number");
-	if ((objn < 0) | (objn >= guis[guin].GetControlCount())) quit("!SetLabelFont: invalid object number");
-	if (guis[guin].GetControlType(objn) != kGUILabel)
+	if ((objn < 0) | (objn >= _GP(guis)[guin].GetControlCount())) quit("!SetLabelFont: invalid object number");
+	if (_GP(guis)[guin].GetControlType(objn) != kGUILabel)
 		quit("!SetLabelFont: specified control is not a label");
 
-	GUILabel *guil = (GUILabel *)guis[guin].GetControl(objn);
+	GUILabel *guil = (GUILabel *)_GP(guis)[guin].GetControl(objn);
 	Label_SetFont(guil, fontnum);
 }
 
diff --git a/engines/ags/engine/ac/global_object.cpp b/engines/ags/engine/ac/global_object.cpp
index c455b0562e..4d68ab6d7e 100644
--- a/engines/ags/engine/ac/global_object.cpp
+++ b/engines/ags/engine/ac/global_object.cpp
@@ -54,9 +54,9 @@ using namespace AGS::Shared;
 
 extern RoomStatus *croom;
 extern RoomObject *objs;
-extern ViewStruct *views;
 
-extern ObjectCache objcache[MAX_ROOM_OBJECTS];
+
+
 
 extern CharacterInfo *playerchar;
 extern int displayed_room;
@@ -89,7 +89,7 @@ int GetObjectIDAtRoom(int roomx, int roomy) {
 		int spWidth = game_to_data_coord(objs[aa].get_width());
 		int spHeight = game_to_data_coord(objs[aa].get_height());
 		if (objs[aa].view >= 0)
-			isflipped = views[objs[aa].view].loops[objs[aa].loop].frames[objs[aa].frame].flags & VFLG_FLIPSPRITE;
+			isflipped = _G(views)[objs[aa].view].loops[objs[aa].loop].frames[objs[aa].frame].flags & VFLG_FLIPSPRITE;
 
 		Bitmap *theImage = GetObjectImage(aa, &isflipped);
 
@@ -150,36 +150,36 @@ void SetObjectView(int obn, int vii) {
 
 	objs[obn].view = vii;
 	objs[obn].frame = 0;
-	if (objs[obn].loop >= views[vii].numLoops)
+	if (objs[obn].loop >= _G(views)[vii].numLoops)
 		objs[obn].loop = 0;
 	objs[obn].cycling = 0;
-	objs[obn].num = views[vii].loops[0].frames[0].pic;
+	objs[obn].num = _G(views)[vii].loops[0].frames[0].pic;
 }
 
 void SetObjectFrame(int obn, int viw, int lop, int fra) {
 	if (!is_valid_object(obn)) quit("!SetObjectFrame: invalid object number specified");
 	viw--;
 	if (viw < 0 || viw >= _GP(game).numviews) quitprintf("!SetObjectFrame: invalid view number used (%d, range is 0 - %d)", viw, _GP(game).numviews - 1);
-	if (lop < 0 || lop >= views[viw].numLoops) quitprintf("!SetObjectFrame: invalid loop number used (%d, range is 0 - %d)", lop, views[viw].numLoops - 1);
+	if (lop < 0 || lop >= _G(views)[viw].numLoops) quitprintf("!SetObjectFrame: invalid loop number used (%d, range is 0 - %d)", lop, _G(views)[viw].numLoops - 1);
 	// AGS < 3.5.1 let user to pass literally any positive invalid frame value by silently reassigning it to zero...
 	if (loaded_game_file_version < kGameVersion_351) {
-		if (fra >= views[viw].loops[lop].numFrames) {
-			debug_script_warn("SetObjectFrame: frame index out of range (%d, must be 0 - %d), set to 0", fra, views[viw].loops[lop].numFrames - 1);
+		if (fra >= _G(views)[viw].loops[lop].numFrames) {
+			debug_script_warn("SetObjectFrame: frame index out of range (%d, must be 0 - %d), set to 0", fra, _G(views)[viw].loops[lop].numFrames - 1);
 			fra = 0;
 		}
 	}
-	if (fra < 0 || fra >= views[viw].loops[lop].numFrames) quitprintf("!SetObjectFrame: invalid frame number used (%d, range is 0 - %d)", fra, views[viw].loops[lop].numFrames - 1);
+	if (fra < 0 || fra >= _G(views)[viw].loops[lop].numFrames) quitprintf("!SetObjectFrame: invalid frame number used (%d, range is 0 - %d)", fra, _G(views)[viw].loops[lop].numFrames - 1);
 	// AGS >= 3.2.0 do not let assign an empty loop
 	// NOTE: pre-3.2.0 games are converting views from ViewStruct272 struct, always has at least 1 frame
 	if (loaded_game_file_version >= kGameVersion_320) {
-		if (views[viw].loops[lop].numFrames == 0)
+		if (_G(views)[viw].loops[lop].numFrames == 0)
 			quit("!SetObjectFrame: specified loop has no frames");
 	}
 	objs[obn].view = viw;
 	objs[obn].loop = lop;
 	objs[obn].frame = fra;
 	objs[obn].cycling = 0;
-	objs[obn].num = views[viw].loops[lop].frames[fra].pic;
+	objs[obn].num = _G(views)[viw].loops[lop].frames[fra].pic;
 	CheckViewFrame(viw, objs[obn].loop, objs[obn].frame);
 }
 
@@ -197,7 +197,7 @@ void SetObjectBaseline(int obn, int basel) {
 	if (!is_valid_object(obn)) quit("!SetObjectBaseline: invalid object number specified");
 	// baseline has changed, invalidate the cache
 	if (objs[obn].baseline != basel) {
-		objcache[obn].ywas = -9999;
+		_G(objcache)[obn].ywas = -9999;
 		objs[obn].baseline = basel;
 	}
 }
@@ -220,15 +220,15 @@ void AnimateObjectImpl(int obn, int loopn, int spdd, int rept, int direction, in
 		quit("!AnimateObject: invalid object number specified");
 	if (objs[obn].view < 0)
 		quit("!AnimateObject: object has not been assigned a view");
-	if (loopn < 0 || loopn >= views[objs[obn].view].numLoops)
+	if (loopn < 0 || loopn >= _G(views)[objs[obn].view].numLoops)
 		quit("!AnimateObject: invalid loop number specified");
-	if (sframe < 0 || sframe >= views[objs[obn].view].loops[loopn].numFrames)
+	if (sframe < 0 || sframe >= _G(views)[objs[obn].view].loops[loopn].numFrames)
 		quit("!AnimateObject: invalid starting frame number specified");
 	if ((direction < 0) || (direction > 1))
 		quit("!AnimateObjectEx: invalid direction");
 	if ((rept < 0) || (rept > 2))
 		quit("!AnimateObjectEx: invalid repeat value");
-	if (views[objs[obn].view].loops[loopn].numFrames < 1)
+	if (_G(views)[objs[obn].view].loops[loopn].numFrames < 1)
 		quit("!AnimateObject: no frames in the specified view loop");
 
 	debug_script_log("Obj %d start anim view %d loop %d, speed %d, repeat %d, frame %d", obn, objs[obn].view + 1, loopn, spdd, rept, sframe);
@@ -239,13 +239,13 @@ void AnimateObjectImpl(int obn, int loopn, int spdd, int rept, int direction, in
 	if (direction) {
 		sframe--;
 		if (sframe < 0)
-			sframe = views[objs[obn].view].loops[loopn].numFrames - (-sframe);
+			sframe = _G(views)[objs[obn].view].loops[loopn].numFrames - (-sframe);
 	}
 	objs[obn].frame = sframe;
 
 	objs[obn].overall_speed = spdd;
-	objs[obn].wait = spdd + views[objs[obn].view].loops[loopn].frames[objs[obn].frame].speed;
-	objs[obn].num = views[objs[obn].view].loops[loopn].frames[objs[obn].frame].pic;
+	objs[obn].wait = spdd + _G(views)[objs[obn].view].loops[loopn].frames[objs[obn].frame].speed;
+	objs[obn].num = _G(views)[objs[obn].view].loops[loopn].frames[objs[obn].frame].pic;
 	CheckViewFrame(objs[obn].view, loopn, objs[obn].frame);
 
 	if (blocking)
@@ -399,7 +399,7 @@ void SetObjectIgnoreWalkbehinds(int cha, int clik) {
 	if (clik)
 		objs[cha].flags |= OBJF_NOWALKBEHINDS;
 	// clear the cache
-	objcache[cha].ywas = -9999;
+	_G(objcache)[cha].ywas = -9999;
 }
 
 void RunObjectInteraction(int aa, int mood) {
diff --git a/engines/ags/engine/ac/global_room.cpp b/engines/ags/engine/ac/global_room.cpp
index c25c0fd821..00e43cf0c0 100644
--- a/engines/ags/engine/ac/global_room.cpp
+++ b/engines/ags/engine/ac/global_room.cpp
@@ -52,7 +52,7 @@ extern int displayed_room;
 extern int in_enters_screen;
 extern int in_leaves_screen;
 extern int in_inv_screen, inv_screen_newroom;
-extern MoveList *mls;
+
 extern int gs_to_newroom;
 
 
@@ -130,7 +130,7 @@ void NewRoom(int nrnum) {
 		if ((playerchar->walking > 0) && (playerchar->walking < TURNING_AROUND)) {
 			// nasty hack - make sure it doesn't move the character
 			// to a walkable area
-			mls[playerchar->walking].direct = 1;
+			_G(mls)[playerchar->walking].direct = 1;
 			StopMoving(_GP(game).playercharacter);
 		}
 	} else if (in_graph_script)
diff --git a/engines/ags/engine/ac/global_slider.cpp b/engines/ags/engine/ac/global_slider.cpp
index 98324a51bf..4d6a73df84 100644
--- a/engines/ags/engine/ac/global_slider.cpp
+++ b/engines/ags/engine/ac/global_slider.cpp
@@ -34,19 +34,19 @@ using namespace AGS::Shared;
 
 void SetSliderValue(int guin, int objn, int valn) {
 	if ((guin < 0) | (guin >= _GP(game).numgui)) quit("!SetSliderValue: invalid GUI number");
-	if (guis[guin].GetControlType(objn) != kGUISlider)
+	if (_GP(guis)[guin].GetControlType(objn) != kGUISlider)
 		quit("!SetSliderValue: specified control is not a slider");
 
-	GUISlider *guisl = (GUISlider *)guis[guin].GetControl(objn);
+	GUISlider *guisl = (GUISlider *)_GP(guis)[guin].GetControl(objn);
 	Slider_SetValue(guisl, valn);
 }
 
 int GetSliderValue(int guin, int objn) {
 	if ((guin < 0) | (guin >= _GP(game).numgui)) quit("!GetSliderValue: invalid GUI number");
-	if (guis[guin].GetControlType(objn) != kGUISlider)
+	if (_GP(guis)[guin].GetControlType(objn) != kGUISlider)
 		quit("!GetSliderValue: specified control is not a slider");
 
-	GUISlider *guisl = (GUISlider *)guis[guin].GetControl(objn);
+	GUISlider *guisl = (GUISlider *)_GP(guis)[guin].GetControl(objn);
 	return Slider_GetValue(guisl);
 }
 
diff --git a/engines/ags/engine/ac/global_textbox.cpp b/engines/ags/engine/ac/global_textbox.cpp
index da9e124d36..adbd211b9d 100644
--- a/engines/ags/engine/ac/global_textbox.cpp
+++ b/engines/ags/engine/ac/global_textbox.cpp
@@ -38,32 +38,32 @@ using namespace AGS::Shared;
 void SetTextBoxFont(int guin, int objn, int fontnum) {
 
 	if ((guin < 0) | (guin >= _GP(game).numgui)) quit("!SetTextBoxFont: invalid GUI number");
-	if ((objn < 0) | (objn >= guis[guin].GetControlCount())) quit("!SetTextBoxFont: invalid object number");
-	if (guis[guin].GetControlType(objn) != kGUITextBox)
+	if ((objn < 0) | (objn >= _GP(guis)[guin].GetControlCount())) quit("!SetTextBoxFont: invalid object number");
+	if (_GP(guis)[guin].GetControlType(objn) != kGUITextBox)
 		quit("!SetTextBoxFont: specified control is not a text box");
 
-	GUITextBox *guit = (GUITextBox *)guis[guin].GetControl(objn);
+	GUITextBox *guit = (GUITextBox *)_GP(guis)[guin].GetControl(objn);
 	TextBox_SetFont(guit, fontnum);
 }
 
 void GetTextBoxText(int guin, int objn, char *txbuf) {
 	VALIDATE_STRING(txbuf);
 	if ((guin < 0) | (guin >= _GP(game).numgui)) quit("!GetTextBoxText: invalid GUI number");
-	if ((objn < 0) | (objn >= guis[guin].GetControlCount())) quit("!GetTextBoxText: invalid object number");
-	if (guis[guin].GetControlType(objn) != kGUITextBox)
+	if ((objn < 0) | (objn >= _GP(guis)[guin].GetControlCount())) quit("!GetTextBoxText: invalid object number");
+	if (_GP(guis)[guin].GetControlType(objn) != kGUITextBox)
 		quit("!GetTextBoxText: specified control is not a text box");
 
-	GUITextBox *guisl = (GUITextBox *)guis[guin].GetControl(objn);
+	GUITextBox *guisl = (GUITextBox *)_GP(guis)[guin].GetControl(objn);
 	TextBox_GetText(guisl, txbuf);
 }
 
 void SetTextBoxText(int guin, int objn, const char *txbuf) {
 	if ((guin < 0) | (guin >= _GP(game).numgui)) quit("!SetTextBoxText: invalid GUI number");
-	if ((objn < 0) | (objn >= guis[guin].GetControlCount())) quit("!SetTextBoxText: invalid object number");
-	if (guis[guin].GetControlType(objn) != kGUITextBox)
+	if ((objn < 0) | (objn >= _GP(guis)[guin].GetControlCount())) quit("!SetTextBoxText: invalid object number");
+	if (_GP(guis)[guin].GetControlType(objn) != kGUITextBox)
 		quit("!SetTextBoxText: specified control is not a text box");
 
-	GUITextBox *guisl = (GUITextBox *)guis[guin].GetControl(objn);
+	GUITextBox *guisl = (GUITextBox *)_GP(guis)[guin].GetControl(objn);
 	TextBox_SetText(guisl, txbuf);
 }
 
diff --git a/engines/ags/engine/ac/global_viewframe.cpp b/engines/ags/engine/ac/global_viewframe.cpp
index f4a823af07..0d2ab4160a 100644
--- a/engines/ags/engine/ac/global_viewframe.cpp
+++ b/engines/ags/engine/ac/global_viewframe.cpp
@@ -30,27 +30,27 @@
 
 namespace AGS3 {
 
-extern ViewStruct *views;
+
 
 void SetFrameSound(int vii, int loop, int frame, int sound) {
 	if ((vii < 1) || (vii > _GP(game).numviews))
 		quit("!SetFrameSound: invalid view number");
 	vii--;
 
-	if (loop >= views[vii].numLoops)
+	if (loop >= _G(views)[vii].numLoops)
 		quit("!SetFrameSound: invalid loop number");
 
-	if (frame >= views[vii].loops[loop].numFrames)
+	if (frame >= _G(views)[vii].loops[loop].numFrames)
 		quit("!SetFrameSound: invalid frame number");
 
 	if (sound < 1) {
-		views[vii].loops[loop].frames[frame].sound = -1;
+		_G(views)[vii].loops[loop].frames[frame].sound = -1;
 	} else {
 		ScriptAudioClip *clip = GetAudioClipForOldStyleNumber(_GP(game), false, sound);
 		if (clip == nullptr)
 			quitprintf("!SetFrameSound: audio clip aSound%d not found", sound);
 
-		views[vii].loops[loop].frames[frame].sound = clip->id + (_GP(game).IsLegacyAudioSystem() ? 0x10000000 : 0);
+		_G(views)[vii].loops[loop].frames[frame].sound = clip->id + (_GP(game).IsLegacyAudioSystem() ? 0x10000000 : 0);
 	}
 }
 
diff --git a/engines/ags/engine/ac/gui.cpp b/engines/ags/engine/ac/gui.cpp
index 931e10a027..93c3e3928b 100644
--- a/engines/ags/engine/ac/gui.cpp
+++ b/engines/ags/engine/ac/gui.cpp
@@ -69,15 +69,15 @@ extern GameSetup usetup;
 
 extern int cur_mode, cur_cursor;
 extern ccInstance *gameinst;
-extern ScriptGUI *scrGui;
 
-extern CCGUIObject ccDynamicGUIObject;
+
+
 extern Bitmap **guibg;
 extern IDriverDependantBitmap **guibgbmp;
 extern IGraphicsDriver *gfxDriver;
 
-extern CCGUI ccDynamicGUI;
-extern CCGUIObject ccDynamicGUIObject;
+
+
 
 
 int ifacepopped = -1; // currently displayed pop-up GUI (-1 if none)
@@ -89,11 +89,11 @@ int eip_guinum, eip_guiobj;
 
 ScriptGUI *GUI_AsTextWindow(ScriptGUI *tehgui) {
 	// Internally both GUI and TextWindow are implemented by same class
-	return guis[tehgui->id].IsTextWindow() ? &scrGui[tehgui->id] : nullptr;
+	return _GP(guis)[tehgui->id].IsTextWindow() ? &_G(scrGui)[tehgui->id] : nullptr;
 }
 
 int GUI_GetPopupStyle(ScriptGUI *tehgui) {
-	return guis[tehgui->id].PopupStyle;
+	return _GP(guis)[tehgui->id].PopupStyle;
 }
 
 void GUI_SetVisible(ScriptGUI *tehgui, int isvisible) {
@@ -107,23 +107,23 @@ int GUI_GetVisible(ScriptGUI *tehgui) {
 	// GUI_GetVisible is slightly different from IsGUIOn, because
 	// with a mouse ypos gui it returns 1 if the GUI is enabled,
 	// whereas IsGUIOn actually checks if it is displayed
-	return guis[tehgui->id].IsVisible() ? 1 : 0;
+	return _GP(guis)[tehgui->id].IsVisible() ? 1 : 0;
 }
 
 int GUI_GetX(ScriptGUI *tehgui) {
-	return game_to_data_coord(guis[tehgui->id].X);
+	return game_to_data_coord(_GP(guis)[tehgui->id].X);
 }
 
 void GUI_SetX(ScriptGUI *tehgui, int xx) {
-	guis[tehgui->id].X = data_to_game_coord(xx);
+	_GP(guis)[tehgui->id].X = data_to_game_coord(xx);
 }
 
 int GUI_GetY(ScriptGUI *tehgui) {
-	return game_to_data_coord(guis[tehgui->id].Y);
+	return game_to_data_coord(_GP(guis)[tehgui->id].Y);
 }
 
 void GUI_SetY(ScriptGUI *tehgui, int yy) {
-	guis[tehgui->id].Y = data_to_game_coord(yy);
+	_GP(guis)[tehgui->id].Y = data_to_game_coord(yy);
 }
 
 void GUI_SetPosition(ScriptGUI *tehgui, int xx, int yy) {
@@ -135,7 +135,7 @@ void GUI_SetSize(ScriptGUI *sgui, int widd, int hitt) {
 	if ((widd < 1) || (hitt < 1))
 		quitprintf("!SetGUISize: invalid dimensions (tried to set to %d x %d)", widd, hitt);
 
-	GUIMain *tehgui = &guis[sgui->id];
+	GUIMain *tehgui = &_GP(guis)[sgui->id];
 	data_to_game_coords(&widd, &hitt);
 
 	if ((tehgui->Width == widd) && (tehgui->Height == hitt))
@@ -150,11 +150,11 @@ void GUI_SetSize(ScriptGUI *sgui, int widd, int hitt) {
 }
 
 int GUI_GetWidth(ScriptGUI *sgui) {
-	return game_to_data_coord(guis[sgui->id].Width);
+	return game_to_data_coord(_GP(guis)[sgui->id].Width);
 }
 
 int GUI_GetHeight(ScriptGUI *sgui) {
-	return game_to_data_coord(guis[sgui->id].Height);
+	return game_to_data_coord(_GP(guis)[sgui->id].Height);
 }
 
 void GUI_SetWidth(ScriptGUI *sgui, int newwid) {
@@ -166,20 +166,20 @@ void GUI_SetHeight(ScriptGUI *sgui, int newhit) {
 }
 
 void GUI_SetZOrder(ScriptGUI *tehgui, int z) {
-	guis[tehgui->id].ZOrder = z;
+	_GP(guis)[tehgui->id].ZOrder = z;
 	update_gui_zorder();
 }
 
 int GUI_GetZOrder(ScriptGUI *tehgui) {
-	return guis[tehgui->id].ZOrder;
+	return _GP(guis)[tehgui->id].ZOrder;
 }
 
 void GUI_SetClickable(ScriptGUI *tehgui, int clickable) {
-	guis[tehgui->id].SetClickable(clickable != 0);
+	_GP(guis)[tehgui->id].SetClickable(clickable != 0);
 }
 
 int GUI_GetClickable(ScriptGUI *tehgui) {
-	return guis[tehgui->id].IsClickable() ? 1 : 0;
+	return _GP(guis)[tehgui->id].IsClickable() ? 1 : 0;
 }
 
 int GUI_GetID(ScriptGUI *tehgui) {
@@ -187,114 +187,114 @@ int GUI_GetID(ScriptGUI *tehgui) {
 }
 
 GUIObject *GUI_GetiControls(ScriptGUI *tehgui, int idx) {
-	if ((idx < 0) || (idx >= guis[tehgui->id].GetControlCount()))
+	if ((idx < 0) || (idx >= _GP(guis)[tehgui->id].GetControlCount()))
 		return nullptr;
-	return guis[tehgui->id].GetControl(idx);
+	return _GP(guis)[tehgui->id].GetControl(idx);
 }
 
 int GUI_GetControlCount(ScriptGUI *tehgui) {
-	return guis[tehgui->id].GetControlCount();
+	return _GP(guis)[tehgui->id].GetControlCount();
 }
 
 int GUI_GetPopupYPos(ScriptGUI *tehgui) {
-	return guis[tehgui->id].PopupAtMouseY;
+	return _GP(guis)[tehgui->id].PopupAtMouseY;
 }
 
 void GUI_SetPopupYPos(ScriptGUI *tehgui, int newpos) {
-	if (!guis[tehgui->id].IsTextWindow())
-		guis[tehgui->id].PopupAtMouseY = newpos;
+	if (!_GP(guis)[tehgui->id].IsTextWindow())
+		_GP(guis)[tehgui->id].PopupAtMouseY = newpos;
 }
 
 void GUI_SetTransparency(ScriptGUI *tehgui, int trans) {
 	if ((trans < 0) | (trans > 100))
 		quit("!SetGUITransparency: transparency value must be between 0 and 100");
 
-	guis[tehgui->id].SetTransparencyAsPercentage(trans);
+	_GP(guis)[tehgui->id].SetTransparencyAsPercentage(trans);
 }
 
 int GUI_GetTransparency(ScriptGUI *tehgui) {
-	if (guis[tehgui->id].Transparency == 0)
+	if (_GP(guis)[tehgui->id].Transparency == 0)
 		return 0;
-	if (guis[tehgui->id].Transparency == 255)
+	if (_GP(guis)[tehgui->id].Transparency == 255)
 		return 100;
 
-	return 100 - ((guis[tehgui->id].Transparency * 10) / 25);
+	return 100 - ((_GP(guis)[tehgui->id].Transparency * 10) / 25);
 }
 
 void GUI_Centre(ScriptGUI *sgui) {
-	GUIMain *tehgui = &guis[sgui->id];
+	GUIMain *tehgui = &_GP(guis)[sgui->id];
 	tehgui->X = _GP(play).GetUIViewport().GetWidth() / 2 - tehgui->Width / 2;
 	tehgui->Y = _GP(play).GetUIViewport().GetHeight() / 2 - tehgui->Height / 2;
 }
 
 void GUI_SetBackgroundGraphic(ScriptGUI *tehgui, int slotn) {
-	if (guis[tehgui->id].BgImage != slotn) {
-		guis[tehgui->id].BgImage = slotn;
+	if (_GP(guis)[tehgui->id].BgImage != slotn) {
+		_GP(guis)[tehgui->id].BgImage = slotn;
 		guis_need_update = 1;
 	}
 }
 
 int GUI_GetBackgroundGraphic(ScriptGUI *tehgui) {
-	if (guis[tehgui->id].BgImage < 1)
+	if (_GP(guis)[tehgui->id].BgImage < 1)
 		return 0;
-	return guis[tehgui->id].BgImage;
+	return _GP(guis)[tehgui->id].BgImage;
 }
 
 void GUI_SetBackgroundColor(ScriptGUI *tehgui, int newcol) {
-	if (guis[tehgui->id].BgColor != newcol) {
-		guis[tehgui->id].BgColor = newcol;
+	if (_GP(guis)[tehgui->id].BgColor != newcol) {
+		_GP(guis)[tehgui->id].BgColor = newcol;
 		guis_need_update = 1;
 	}
 }
 
 int GUI_GetBackgroundColor(ScriptGUI *tehgui) {
-	return guis[tehgui->id].BgColor;
+	return _GP(guis)[tehgui->id].BgColor;
 }
 
 void GUI_SetBorderColor(ScriptGUI *tehgui, int newcol) {
-	if (guis[tehgui->id].IsTextWindow())
+	if (_GP(guis)[tehgui->id].IsTextWindow())
 		return;
-	if (guis[tehgui->id].FgColor != newcol) {
-		guis[tehgui->id].FgColor = newcol;
+	if (_GP(guis)[tehgui->id].FgColor != newcol) {
+		_GP(guis)[tehgui->id].FgColor = newcol;
 		guis_need_update = 1;
 	}
 }
 
 int GUI_GetBorderColor(ScriptGUI *tehgui) {
-	if (guis[tehgui->id].IsTextWindow())
+	if (_GP(guis)[tehgui->id].IsTextWindow())
 		return 0;
-	return guis[tehgui->id].FgColor;
+	return _GP(guis)[tehgui->id].FgColor;
 }
 
 void GUI_SetTextColor(ScriptGUI *tehgui, int newcol) {
-	if (!guis[tehgui->id].IsTextWindow())
+	if (!_GP(guis)[tehgui->id].IsTextWindow())
 		return;
-	if (guis[tehgui->id].FgColor != newcol) {
-		guis[tehgui->id].FgColor = newcol;
+	if (_GP(guis)[tehgui->id].FgColor != newcol) {
+		_GP(guis)[tehgui->id].FgColor = newcol;
 		guis_need_update = 1;
 	}
 }
 
 int GUI_GetTextColor(ScriptGUI *tehgui) {
-	if (!guis[tehgui->id].IsTextWindow())
+	if (!_GP(guis)[tehgui->id].IsTextWindow())
 		return 0;
-	return guis[tehgui->id].FgColor;
+	return _GP(guis)[tehgui->id].FgColor;
 }
 
 int GUI_GetTextPadding(ScriptGUI *tehgui) {
-	return guis[tehgui->id].Padding;
+	return _GP(guis)[tehgui->id].Padding;
 }
 
 void GUI_SetTextPadding(ScriptGUI *tehgui, int newpos) {
-	if (guis[tehgui->id].IsTextWindow())
-		guis[tehgui->id].Padding = newpos;
+	if (_GP(guis)[tehgui->id].IsTextWindow())
+		_GP(guis)[tehgui->id].Padding = newpos;
 }
 
 ScriptGUI *GetGUIAtLocation(int xx, int yy) {
 	int guiid = GetGUIAt(xx, yy);
 	if (guiid < 0)
 		return nullptr;
-	return &scrGui[guiid];
+	return &_G(scrGui)[guiid];
 }
 
 void GUI_Click(ScriptGUI *scgui, int mbut) {
@@ -308,7 +308,7 @@ void GUI_ProcessClick(int x, int y, int mbut) {
 		const int real_mousey = _G(mousey);
 		_G(mousex) = x;
 		_G(mousey) = y;
-		guis[guiid].Poll();
+		_GP(guis)[guiid].Poll();
 		gui_on_mouse_down(guiid, mbut);
 		gui_on_mouse_up(guiid, mbut);
 		_G(mousex) = real_mousex;
@@ -322,9 +322,9 @@ void remove_popup_interface(int ifacenum) {
 	if (ifacepopped != ifacenum) return;
 	ifacepopped = -1;
 	UnPauseGame();
-	guis[ifacenum].SetConceal(true);
-	if (_G(mousey) <= guis[ifacenum].PopupAtMouseY)
-		Mouse::SetPosition(Point(_G(mousex), guis[ifacenum].PopupAtMouseY + 2));
+	_GP(guis)[ifacenum].SetConceal(true);
+	if (_G(mousey) <= _GP(guis)[ifacenum].PopupAtMouseY)
+		Mouse::SetPosition(Point(_G(mousex), _GP(guis)[ifacenum].PopupAtMouseY + 2));
 	if ((!IsInterfaceEnabled()) && (cur_cursor == cur_mode))
 		// Only change the mouse cursor if it hasn't been specifically changed first
 		set_mouse_cursor(CURS_WAIT);
@@ -338,16 +338,16 @@ void remove_popup_interface(int ifacenum) {
 void process_interface_click(int ifce, int btn, int mbut) {
 	if (btn < 0) {
 		// click on GUI background
-		QueueScriptFunction(kScInstGame, guis[ifce].OnClickHandler, 2,
-			RuntimeScriptValue().SetDynamicObject(&scrGui[ifce], &ccDynamicGUI),
+		QueueScriptFunction(kScInstGame, _GP(guis)[ifce].OnClickHandler, 2,
+			RuntimeScriptValue().SetDynamicObject(&_G(scrGui)[ifce], &_GP(ccDynamicGUI)),
 			RuntimeScriptValue().SetInt32(mbut));
 		return;
 	}
 
-	int btype = guis[ifce].GetControlType(btn);
+	int btype = _GP(guis)[ifce].GetControlType(btn);
 	int rtype = kGUIAction_None, rdata = 0;
 	if (btype == kGUIButton) {
-		GUIButton *gbuto = (GUIButton *)guis[ifce].GetControl(btn);
+		GUIButton *gbuto = (GUIButton *)_GP(guis)[ifce].GetControl(btn);
 		rtype = gbuto->ClickAction[kMouseLeft];
 		rdata = gbuto->ClickData[kMouseLeft];
 	} else if ((btype == kGUISlider) || (btype == kGUITextBox) || (btype == kGUIListBox))
@@ -358,7 +358,7 @@ void process_interface_click(int ifce, int btn, int mbut) {
 	else if (rtype == kGUIAction_SetMode)
 		set_cursor_mode(rdata);
 	else if (rtype == kGUIAction_RunScript) {
-		GUIObject *theObj = guis[ifce].GetControl(btn);
+		GUIObject *theObj = _GP(guis)[ifce].GetControl(btn);
 		// if the object has a special handler script then run it;
 		// otherwise, run interface_click
 		if ((theObj->GetEventCount() > 0) &&
@@ -367,11 +367,11 @@ void process_interface_click(int ifce, int btn, int mbut) {
 			// control-specific event handler
 			if (strchr(theObj->GetEventArgs(0), ',') != nullptr)
 				QueueScriptFunction(kScInstGame, theObj->EventHandlers[0], 2,
-					RuntimeScriptValue().SetDynamicObject(theObj, &ccDynamicGUIObject),
+					RuntimeScriptValue().SetDynamicObject(theObj, &_GP(ccDynamicGUIObject)),
 					RuntimeScriptValue().SetInt32(mbut));
 			else
 				QueueScriptFunction(kScInstGame, theObj->EventHandlers[0], 1,
-					RuntimeScriptValue().SetDynamicObject(theObj, &ccDynamicGUIObject));
+					RuntimeScriptValue().SetDynamicObject(theObj, &_GP(ccDynamicGUIObject)));
 		} else
 			QueueScriptFunction(kScInstGame, "interface_click", 2,
 				RuntimeScriptValue().SetInt32(ifce),
@@ -447,7 +447,7 @@ void update_gui_zorder() {
 		// find the right place in the draw order array
 		int insertAt = numdone;
 		for (b = 0; b < numdone; b++) {
-			if (guis[a].ZOrder < guis[_GP(play).gui_draw_order[b]].ZOrder) {
+			if (_GP(guis)[a].ZOrder < _GP(guis)[_GP(play).gui_draw_order[b]].ZOrder) {
 				insertAt = b;
 				break;
 			}
@@ -463,17 +463,17 @@ void update_gui_zorder() {
 
 
 void export_gui_controls(int ee) {
-	for (int ff = 0; ff < guis[ee].GetControlCount(); ff++) {
-		GUIObject *guio = guis[ee].GetControl(ff);
+	for (int ff = 0; ff < _GP(guis)[ee].GetControlCount(); ff++) {
+		GUIObject *guio = _GP(guis)[ee].GetControl(ff);
 		if (!guio->Name.IsEmpty())
-			ccAddExternalDynamicObject(guio->Name, guio, &ccDynamicGUIObject);
-		ccRegisterManagedObject(guio, &ccDynamicGUIObject);
+			ccAddExternalDynamicObject(guio->Name, guio, &_GP(ccDynamicGUIObject));
+		ccRegisterManagedObject(guio, &_GP(ccDynamicGUIObject));
 	}
 }
 
 void unexport_gui_controls(int ee) {
-	for (int ff = 0; ff < guis[ee].GetControlCount(); ff++) {
-		GUIObject *guio = guis[ee].GetControl(ff);
+	for (int ff = 0; ff < _GP(guis)[ee].GetControlCount(); ff++) {
+		GUIObject *guio = _GP(guis)[ee].GetControl(ff);
 		if (!guio->Name.IsEmpty())
 			ccRemoveExternalSymbol(guio->Name);
 		if (!ccUnRegisterManagedObject(guio))
@@ -512,7 +512,7 @@ void update_gui_disabled_status() {
 	if (all_buttons_was != all_buttons_disabled) {
 		// GUIs might have been removed/added
 		for (int aa = 0; aa < _GP(game).numgui; aa++) {
-			guis[aa].OnControlPositionChanged();
+			_GP(guis)[aa].OnControlPositionChanged();
 		}
 		guis_need_update = 1;
 		invalidate_screen();
@@ -525,20 +525,20 @@ int adjust_x_for_guis(int xx, int yy) {
 		return xx;
 	// If it's covered by a GUI, move it right a bit
 	for (int aa = 0; aa < _GP(game).numgui; aa++) {
-		if (!guis[aa].IsDisplayed())
+		if (!_GP(guis)[aa].IsDisplayed())
 			continue;
-		if ((guis[aa].X > xx) || (guis[aa].Y > yy) || (guis[aa].Y + guis[aa].Height < yy))
+		if ((_GP(guis)[aa].X > xx) || (_GP(guis)[aa].Y > yy) || (_GP(guis)[aa].Y + _GP(guis)[aa].Height < yy))
 			continue;
 		// totally transparent GUI, ignore
-		if ((guis[aa].BgColor == 0) && (guis[aa].BgImage < 1))
+		if ((_GP(guis)[aa].BgColor == 0) && (_GP(guis)[aa].BgImage < 1))
 			continue;
 
 		// try to deal with full-width GUIs across the top
-		if (guis[aa].X + guis[aa].Width >= get_fixed_pixel_size(280))
+		if (_GP(guis)[aa].X + _GP(guis)[aa].Width >= get_fixed_pixel_size(280))
 			continue;
 
-		if (xx < guis[aa].X + guis[aa].Width)
-			xx = guis[aa].X + guis[aa].Width + 2;
+		if (xx < _GP(guis)[aa].X + _GP(guis)[aa].Width)
+			xx = _GP(guis)[aa].X + _GP(guis)[aa].Width + 2;
 	}
 	return xx;
 }
@@ -548,20 +548,20 @@ int adjust_y_for_guis(int yy) {
 		return yy;
 	// If it's covered by a GUI, move it down a bit
 	for (int aa = 0; aa < _GP(game).numgui; aa++) {
-		if (!guis[aa].IsDisplayed())
+		if (!_GP(guis)[aa].IsDisplayed())
 			continue;
-		if (guis[aa].Y > yy)
+		if (_GP(guis)[aa].Y > yy)
 			continue;
 		// totally transparent GUI, ignore
-		if ((guis[aa].BgColor == 0) && (guis[aa].BgImage < 1))
+		if ((_GP(guis)[aa].BgColor == 0) && (_GP(guis)[aa].BgImage < 1))
 			continue;
 
 		// try to deal with full-height GUIs down the left or right
-		if (guis[aa].Height > get_fixed_pixel_size(50))
+		if (_GP(guis)[aa].Height > get_fixed_pixel_size(50))
 			continue;
 
-		if (yy < guis[aa].Y + guis[aa].Height)
-			yy = guis[aa].Y + guis[aa].Height + 2;
+		if (yy < _GP(guis)[aa].Y + _GP(guis)[aa].Height)
+			yy = _GP(guis)[aa].Y + _GP(guis)[aa].Height + 2;
 	}
 	return yy;
 }
@@ -598,19 +598,19 @@ int gui_on_mouse_move() {
 		int ll;
 		for (ll = 0; ll < _GP(game).numgui; ll++) {
 			const int guin = _GP(play).gui_draw_order[ll];
-			if (guis[guin].IsInteractableAt(_G(mousex), _G(mousey))) mouse_over_gui = guin;
+			if (_GP(guis)[guin].IsInteractableAt(_G(mousex), _G(mousey))) mouse_over_gui = guin;
 
-			if (guis[guin].PopupStyle != kGUIPopupMouseY) continue;
+			if (_GP(guis)[guin].PopupStyle != kGUIPopupMouseY) continue;
 			if (is_complete_overlay > 0) break; // interfaces disabled
 			//    if (_GP(play).disabled_user_interface>0) break;
 			if (ifacepopped == guin) continue;
-			if (!guis[guin].IsVisible()) continue;
+			if (!_GP(guis)[guin].IsVisible()) continue;
 			// Don't allow it to be popped up while skipping cutscene
 			if (_GP(play).fast_forward) continue;
 
-			if (_G(mousey) < guis[guin].PopupAtMouseY) {
+			if (_G(mousey) < _GP(guis)[guin].PopupAtMouseY) {
 				set_mouse_cursor(CURS_ARROW);
-				guis[guin].SetConceal(false);
+				_GP(guis)[guin].SetConceal(false);
 				guis_need_update = 1;
 				ifacepopped = guin;
 				PauseGame();
@@ -622,10 +622,10 @@ int gui_on_mouse_move() {
 }
 
 void gui_on_mouse_hold(const int wasongui, const int wasbutdown) {
-	for (int i = 0; i < guis[wasongui].GetControlCount(); i++) {
-		GUIObject *guio = guis[wasongui].GetControl(i);
+	for (int i = 0; i < _GP(guis)[wasongui].GetControlCount(); i++) {
+		GUIObject *guio = _GP(guis)[wasongui].GetControl(i);
 		if (!guio->IsActivated) continue;
-		if (guis[wasongui].GetControlType(i) != kGUISlider) continue;
+		if (_GP(guis)[wasongui].GetControlType(i) != kGUISlider) continue;
 		// GUI Slider repeatedly activates while being dragged
 		guio->IsActivated = false;
 		force_event(EV_IFACECLICK, wasongui, i, wasbutdown);
@@ -634,20 +634,20 @@ void gui_on_mouse_hold(const int wasongui, const int wasbutdown) {
 }
 
 void gui_on_mouse_up(const int wasongui, const int wasbutdown) {
-	guis[wasongui].OnMouseButtonUp();
+	_GP(guis)[wasongui].OnMouseButtonUp();
 
-	for (int i = 0; i < guis[wasongui].GetControlCount(); i++) {
-		GUIObject *guio = guis[wasongui].GetControl(i);
+	for (int i = 0; i < _GP(guis)[wasongui].GetControlCount(); i++) {
+		GUIObject *guio = _GP(guis)[wasongui].GetControl(i);
 		if (!guio->IsActivated) continue;
 		guio->IsActivated = false;
 		if (!IsInterfaceEnabled()) break;
 
-		int cttype = guis[wasongui].GetControlType(i);
+		int cttype = _GP(guis)[wasongui].GetControlType(i);
 		if ((cttype == kGUIButton) || (cttype == kGUISlider) || (cttype == kGUIListBox)) {
 			force_event(EV_IFACECLICK, wasongui, i, wasbutdown);
 		} else if (cttype == kGUIInvWindow) {
-			mouse_ifacebut_xoffs = _G(mousex) - (guio->X) - guis[wasongui].X;
-			mouse_ifacebut_yoffs = _G(mousey) - (guio->Y) - guis[wasongui].Y;
+			mouse_ifacebut_xoffs = _G(mousex) - (guio->X) - _GP(guis)[wasongui].X;
+			mouse_ifacebut_yoffs = _G(mousey) - (guio->Y) - _GP(guis)[wasongui].Y;
 			int iit = offset_over_inv((GUIInvWindow *)guio);
 			if (iit >= 0) {
 				evblocknum = iit;
@@ -665,7 +665,7 @@ void gui_on_mouse_up(const int wasongui, const int wasbutdown) {
 				evblocknum = -1;
 			}
 		} else quit("clicked on unknown control type");
-		if (guis[wasongui].PopupStyle == kGUIPopupMouseY)
+		if (_GP(guis)[wasongui].PopupStyle == kGUIPopupMouseY)
 			remove_popup_interface(wasongui);
 		break;
 	}
@@ -675,9 +675,9 @@ void gui_on_mouse_up(const int wasongui, const int wasbutdown) {
 
 void gui_on_mouse_down(const int guin, const int mbut) {
 	debug_script_log("Mouse click over GUI %d", guin);
-	guis[guin].OnMouseButtonDown();
+	_GP(guis)[guin].OnMouseButtonDown();
 	// run GUI click handler if not on any control
-	if ((guis[guin].MouseDownCtrl < 0) && (!guis[guin].OnClickHandler.IsEmpty()))
+	if ((_GP(guis)[guin].MouseDownCtrl < 0) && (!_GP(guis)[guin].OnClickHandler.IsEmpty()))
 		force_event(EV_IFACECLICK, guin, -1, mbut);
 
 	run_on_event(GE_GUI_MOUSEDOWN, RuntimeScriptValue().SetInt32(guin));
@@ -696,7 +696,7 @@ RuntimeScriptValue Sc_GUI_Centre(void *self, const RuntimeScriptValue *params, i
 
 // ScriptGUI *(int xx, int yy)
 RuntimeScriptValue Sc_GetGUIAtLocation(const RuntimeScriptValue *params, int32_t param_count) {
-	API_SCALL_OBJ_PINT2(ScriptGUI, ccDynamicGUI, GetGUIAtLocation);
+	API_SCALL_OBJ_PINT2(ScriptGUI, _GP(ccDynamicGUI), GetGUIAtLocation);
 }
 
 // void (ScriptGUI *tehgui, int xx, int yy)
@@ -760,7 +760,7 @@ RuntimeScriptValue Sc_GUI_GetControlCount(void *self, const RuntimeScriptValue *
 
 // GUIObject* (ScriptGUI *tehgui, int idx)
 RuntimeScriptValue Sc_GUI_GetiControls(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ_PINT(ScriptGUI, GUIObject, ccDynamicGUIObject, GUI_GetiControls);
+	API_OBJCALL_OBJ_PINT(ScriptGUI, GUIObject, _GP(ccDynamicGUIObject), GUI_GetiControls);
 }
 
 // int (ScriptGUI *sgui)
@@ -855,7 +855,7 @@ RuntimeScriptValue Sc_GUI_SetZOrder(void *self, const RuntimeScriptValue *params
 }
 
 RuntimeScriptValue Sc_GUI_AsTextWindow(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ(ScriptGUI, ScriptGUI, ccDynamicGUI, GUI_AsTextWindow);
+	API_OBJCALL_OBJ(ScriptGUI, ScriptGUI, _GP(ccDynamicGUI), GUI_AsTextWindow);
 }
 
 RuntimeScriptValue Sc_GUI_GetPopupStyle(void *self, const RuntimeScriptValue *params, int32_t param_count) {
diff --git a/engines/ags/engine/ac/guicontrol.cpp b/engines/ags/engine/ac/guicontrol.cpp
index b061db762d..4356443484 100644
--- a/engines/ags/engine/ac/guicontrol.cpp
+++ b/engines/ags/engine/ac/guicontrol.cpp
@@ -43,9 +43,7 @@ namespace AGS3 {
 
 using namespace AGS::Shared;
 
-extern ScriptGUI *scrGui;
-extern CCGUI ccDynamicGUI;
-extern CCGUIObject ccDynamicGUIObject;
+
 
 GUIObject *GetGUIControlAtLocation(int xx, int yy) {
 	int guinum = GetGUIAt(xx, yy);
@@ -55,15 +53,15 @@ GUIObject *GetGUIControlAtLocation(int xx, int yy) {
 	data_to_game_coords(&xx, &yy);
 
 	int oldmousex = _G(mousex), oldmousey = _G(mousey);
-	_G(mousex) = xx - guis[guinum].X;
-	_G(mousey) = yy - guis[guinum].Y;
-	int toret = guis[guinum].FindControlUnderMouse(0, false);
+	_G(mousex) = xx - _GP(guis)[guinum].X;
+	_G(mousey) = yy - _GP(guis)[guinum].Y;
+	int toret = _GP(guis)[guinum].FindControlUnderMouse(0, false);
 	_G(mousex) = oldmousex;
 	_G(mousey) = oldmousey;
 	if (toret < 0)
 		return nullptr;
 
-	return guis[guinum].GetControl(toret);
+	return _GP(guis)[guinum].GetControl(toret);
 }
 
 int GUIControl_GetVisible(GUIObject *guio) {
@@ -74,7 +72,7 @@ void GUIControl_SetVisible(GUIObject *guio, int visible) {
 	const bool on = visible != 0;
 	if (on != guio->IsVisible()) {
 		guio->SetVisible(on);
-		guis[guio->ParentId].OnControlPositionChanged();
+		_GP(guis)[guio->ParentId].OnControlPositionChanged();
 		guis_need_update = 1;
 	}
 }
@@ -91,7 +89,7 @@ void GUIControl_SetClickable(GUIObject *guio, int enabled) {
 	else
 		guio->SetClickable(false);
 
-	guis[guio->ParentId].OnControlPositionChanged();
+	_GP(guis)[guio->ParentId].OnControlPositionChanged();
 	guis_need_update = 1;
 }
 
@@ -103,7 +101,7 @@ void GUIControl_SetEnabled(GUIObject *guio, int enabled) {
 	const bool on = enabled != 0;
 	if (on != guio->IsEnabled()) {
 		guio->SetEnabled(on);
-		guis[guio->ParentId].OnControlPositionChanged();
+		_GP(guis)[guio->ParentId].OnControlPositionChanged();
 		guis_need_update = 1;
 	}
 }
@@ -114,46 +112,46 @@ int GUIControl_GetID(GUIObject *guio) {
 }
 
 ScriptGUI *GUIControl_GetOwningGUI(GUIObject *guio) {
-	return &scrGui[guio->ParentId];
+	return &_G(scrGui)[guio->ParentId];
 }
 
 GUIButton *GUIControl_GetAsButton(GUIObject *guio) {
-	if (guis[guio->ParentId].GetControlType(guio->Id) != kGUIButton)
+	if (_GP(guis)[guio->ParentId].GetControlType(guio->Id) != kGUIButton)
 		return nullptr;
 
 	return (GUIButton *)guio;
 }
 
 GUIInvWindow *GUIControl_GetAsInvWindow(GUIObject *guio) {
-	if (guis[guio->ParentId].GetControlType(guio->Id) != kGUIInvWindow)
+	if (_GP(guis)[guio->ParentId].GetControlType(guio->Id) != kGUIInvWindow)
 		return nullptr;
 
 	return (GUIInvWindow *)guio;
 }
 
 GUILabel *GUIControl_GetAsLabel(GUIObject *guio) {
-	if (guis[guio->ParentId].GetControlType(guio->Id) != kGUILabel)
+	if (_GP(guis)[guio->ParentId].GetControlType(guio->Id) != kGUILabel)
 		return nullptr;
 
 	return (GUILabel *)guio;
 }
 
 GUIListBox *GUIControl_GetAsListBox(GUIObject *guio) {
-	if (guis[guio->ParentId].GetControlType(guio->Id) != kGUIListBox)
+	if (_GP(guis)[guio->ParentId].GetControlType(guio->Id) != kGUIListBox)
 		return nullptr;
 
 	return (GUIListBox *)guio;
 }
 
 GUISlider *GUIControl_GetAsSlider(GUIObject *guio) {
-	if (guis[guio->ParentId].GetControlType(guio->Id) != kGUISlider)
+	if (_GP(guis)[guio->ParentId].GetControlType(guio->Id) != kGUISlider)
 		return nullptr;
 
 	return (GUISlider *)guio;
 }
 
 GUITextBox *GUIControl_GetAsTextBox(GUIObject *guio) {
-	if (guis[guio->ParentId].GetControlType(guio->Id) != kGUITextBox)
+	if (_GP(guis)[guio->ParentId].GetControlType(guio->Id) != kGUITextBox)
 		return nullptr;
 
 	return (GUITextBox *)guio;
@@ -165,7 +163,7 @@ int GUIControl_GetX(GUIObject *guio) {
 
 void GUIControl_SetX(GUIObject *guio, int xx) {
 	guio->X = data_to_game_coord(xx);
-	guis[guio->ParentId].OnControlPositionChanged();
+	_GP(guis)[guio->ParentId].OnControlPositionChanged();
 	guis_need_update = 1;
 }
 
@@ -175,7 +173,7 @@ int GUIControl_GetY(GUIObject *guio) {
 
 void GUIControl_SetY(GUIObject *guio, int yy) {
 	guio->Y = data_to_game_coord(yy);
-	guis[guio->ParentId].OnControlPositionChanged();
+	_GP(guis)[guio->ParentId].OnControlPositionChanged();
 	guis_need_update = 1;
 }
 
@@ -184,7 +182,7 @@ int GUIControl_GetZOrder(GUIObject *guio) {
 }
 
 void GUIControl_SetZOrder(GUIObject *guio, int zorder) {
-	if (guis[guio->ParentId].SetControlZOrder(guio->Id, zorder))
+	if (_GP(guis)[guio->ParentId].SetControlZOrder(guio->Id, zorder))
 		guis_need_update = 1;
 }
 
@@ -201,7 +199,7 @@ int GUIControl_GetWidth(GUIObject *guio) {
 void GUIControl_SetWidth(GUIObject *guio, int newwid) {
 	guio->Width = data_to_game_coord(newwid);
 	guio->OnResized();
-	guis[guio->ParentId].OnControlPositionChanged();
+	_GP(guis)[guio->ParentId].OnControlPositionChanged();
 	guis_need_update = 1;
 }
 
@@ -212,7 +210,7 @@ int GUIControl_GetHeight(GUIObject *guio) {
 void GUIControl_SetHeight(GUIObject *guio, int newhit) {
 	guio->Height = data_to_game_coord(newhit);
 	guio->OnResized();
-	guis[guio->ParentId].OnControlPositionChanged();
+	_GP(guis)[guio->ParentId].OnControlPositionChanged();
 	guis_need_update = 1;
 }
 
@@ -226,12 +224,12 @@ void GUIControl_SetSize(GUIObject *guio, int newwid, int newhit) {
 }
 
 void GUIControl_SendToBack(GUIObject *guio) {
-	if (guis[guio->ParentId].SendControlToBack(guio->Id))
+	if (_GP(guis)[guio->ParentId].SendControlToBack(guio->Id))
 		guis_need_update = 1;
 }
 
 void GUIControl_BringToFront(GUIObject *guio) {
-	if (guis[guio->ParentId].BringControlToFront(guio->Id))
+	if (_GP(guis)[guio->ParentId].BringControlToFront(guio->Id))
 		guis_need_update = 1;
 }
 
@@ -248,7 +246,7 @@ RuntimeScriptValue Sc_GUIControl_BringToFront(void *self, const RuntimeScriptVal
 
 // GUIObject *(int xx, int yy)
 RuntimeScriptValue Sc_GetGUIControlAtLocation(const RuntimeScriptValue *params, int32_t param_count) {
-	API_SCALL_OBJ_PINT2(GUIObject, ccDynamicGUIObject, GetGUIControlAtLocation);
+	API_SCALL_OBJ_PINT2(GUIObject, _GP(ccDynamicGUIObject), GetGUIControlAtLocation);
 }
 
 // void (GUIObject *guio)
@@ -268,32 +266,32 @@ RuntimeScriptValue Sc_GUIControl_SetSize(void *self, const RuntimeScriptValue *p
 
 // GUIButton* (GUIObject *guio)
 RuntimeScriptValue Sc_GUIControl_GetAsButton(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ(GUIObject, GUIButton, ccDynamicGUI, GUIControl_GetAsButton);
+	API_OBJCALL_OBJ(GUIObject, GUIButton, _GP(ccDynamicGUI), GUIControl_GetAsButton);
 }
 
 // GUIInvWindow* (GUIObject *guio)
 RuntimeScriptValue Sc_GUIControl_GetAsInvWindow(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ(GUIObject, GUIInvWindow, ccDynamicGUI, GUIControl_GetAsInvWindow);
+	API_OBJCALL_OBJ(GUIObject, GUIInvWindow, _GP(ccDynamicGUI), GUIControl_GetAsInvWindow);
 }
 
 // GUILabel* (GUIObject *guio)
 RuntimeScriptValue Sc_GUIControl_GetAsLabel(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ(GUIObject, GUILabel, ccDynamicGUI, GUIControl_GetAsLabel);
+	API_OBJCALL_OBJ(GUIObject, GUILabel, _GP(ccDynamicGUI), GUIControl_GetAsLabel);
 }
 
 // GUIListBox* (GUIObject *guio)
 RuntimeScriptValue Sc_GUIControl_GetAsListBox(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ(GUIObject, GUIListBox, ccDynamicGUI, GUIControl_GetAsListBox);
+	API_OBJCALL_OBJ(GUIObject, GUIListBox, _GP(ccDynamicGUI), GUIControl_GetAsListBox);
 }
 
 // GUISlider* (GUIObject *guio)
 RuntimeScriptValue Sc_GUIControl_GetAsSlider(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ(GUIObject, GUISlider, ccDynamicGUI, GUIControl_GetAsSlider);
+	API_OBJCALL_OBJ(GUIObject, GUISlider, _GP(ccDynamicGUI), GUIControl_GetAsSlider);
 }
 
 // GUITextBox* (GUIObject *guio)
 RuntimeScriptValue Sc_GUIControl_GetAsTextBox(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ(GUIObject, GUITextBox, ccDynamicGUI, GUIControl_GetAsTextBox);
+	API_OBJCALL_OBJ(GUIObject, GUITextBox, _GP(ccDynamicGUI), GUIControl_GetAsTextBox);
 }
 
 // int (GUIObject *guio)
@@ -333,7 +331,7 @@ RuntimeScriptValue Sc_GUIControl_GetID(void *self, const RuntimeScriptValue *par
 
 // ScriptGUI* (GUIObject *guio)
 RuntimeScriptValue Sc_GUIControl_GetOwningGUI(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ(GUIObject, ScriptGUI, ccDynamicGUI, GUIControl_GetOwningGUI);
+	API_OBJCALL_OBJ(GUIObject, ScriptGUI, _GP(ccDynamicGUI), GUIControl_GetOwningGUI);
 }
 
 // int (GUIObject *guio)
diff --git a/engines/ags/engine/ac/hotspot.cpp b/engines/ags/engine/ac/hotspot.cpp
index 8d855ac1a5..56794f24fc 100644
--- a/engines/ags/engine/ac/hotspot.cpp
+++ b/engines/ags/engine/ac/hotspot.cpp
@@ -42,10 +42,7 @@ namespace AGS3 {
 
 using namespace AGS::Shared;
 
-
 extern RoomStatus *croom;
-extern ScriptHotspot scrHotspot[MAX_ROOM_HOTSPOTS];
-extern CCHotspot ccDynamicHotspot;
 
 void Hotspot_SetEnabled(ScriptHotspot *hss, int newval) {
 	if (newval)
@@ -71,11 +68,11 @@ int Hotspot_GetWalkToY(ScriptHotspot *hss) {
 }
 
 ScriptHotspot *GetHotspotAtScreen(int xx, int yy) {
-	return &scrHotspot[GetHotspotIDAtScreen(xx, yy)];
+	return &_G(scrHotspot)[GetHotspotIDAtScreen(xx, yy)];
 }
 
 ScriptHotspot *GetHotspotAtRoom(int x, int y) {
-	return &scrHotspot[get_hotspot_at(x, y)];
+	return &_G(scrHotspot)[get_hotspot_at(x, y)];
 }
 
 void Hotspot_GetName(ScriptHotspot *hss, char *buffer) {
@@ -133,15 +130,15 @@ int get_hotspot_at(int xpp, int ypp) {
 //
 //=============================================================================
 
-extern ScriptString myScriptStringImpl;
+
 
 RuntimeScriptValue Sc_GetHotspotAtRoom(const RuntimeScriptValue *params, int32_t param_count) {
-	API_SCALL_OBJ_PINT2(ScriptHotspot, ccDynamicHotspot, GetHotspotAtRoom);
+	API_SCALL_OBJ_PINT2(ScriptHotspot, _GP(ccDynamicHotspot), GetHotspotAtRoom);
 }
 
 // ScriptHotspot *(int xx, int yy)
 RuntimeScriptValue Sc_GetHotspotAtScreen(const RuntimeScriptValue *params, int32_t param_count) {
-	API_SCALL_OBJ_PINT2(ScriptHotspot, ccDynamicHotspot, GetHotspotAtScreen);
+	API_SCALL_OBJ_PINT2(ScriptHotspot, _GP(ccDynamicHotspot), GetHotspotAtScreen);
 }
 
 RuntimeScriptValue Sc_Hotspot_GetDrawingSurface(const RuntimeScriptValue *params, int32_t param_count) {
@@ -166,7 +163,7 @@ RuntimeScriptValue Sc_Hotspot_GetPropertyText(void *self, const RuntimeScriptVal
 
 // const char* (ScriptHotspot *hss, const char *property)
 RuntimeScriptValue Sc_Hotspot_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ_POBJ(ScriptHotspot, const char, myScriptStringImpl, Hotspot_GetTextProperty, const char);
+	API_CONST_OBJCALL_OBJ_POBJ(ScriptHotspot, const char, _GP(myScriptStringImpl), Hotspot_GetTextProperty, const char);
 }
 
 RuntimeScriptValue Sc_Hotspot_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) {
@@ -203,7 +200,7 @@ RuntimeScriptValue Sc_Hotspot_GetID(void *self, const RuntimeScriptValue *params
 
 // const char* (ScriptHotspot *hss)
 RuntimeScriptValue Sc_Hotspot_GetName_New(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ(ScriptHotspot, const char, myScriptStringImpl, Hotspot_GetName_New);
+	API_CONST_OBJCALL_OBJ(ScriptHotspot, const char, _GP(myScriptStringImpl), Hotspot_GetName_New);
 }
 
 // int (ScriptHotspot *hss)
diff --git a/engines/ags/engine/ac/inventoryitem.cpp b/engines/ags/engine/ac/inventoryitem.cpp
index 78a3317a14..547a411f63 100644
--- a/engines/ags/engine/ac/inventoryitem.cpp
+++ b/engines/ags/engine/ac/inventoryitem.cpp
@@ -41,10 +41,10 @@
 
 namespace AGS3 {
 
-extern ScriptInvItem scrInv[MAX_INV];
+
 extern int cur_cursor;
 extern CharacterInfo *playerchar;
-extern CCInventory ccDynamicInv;
+
 
 void InventoryItem_SetCursorGraphic(ScriptInvItem *iitem, int newSprite) {
 	set_inv_item_cursorpic(iitem->id, newSprite);
@@ -70,7 +70,7 @@ ScriptInvItem *GetInvAtLocation(int xx, int yy) {
 	int hsnum = GetInvAt(xx, yy);
 	if (hsnum <= 0)
 		return nullptr;
-	return &scrInv[hsnum];
+	return &_G(scrInv)[hsnum];
 }
 
 void InventoryItem_GetName(ScriptInvItem *iitem, char *buff) {
@@ -130,11 +130,11 @@ void set_inv_item_cursorpic(int invItemId, int piccy) {
 //
 //=============================================================================
 
-extern ScriptString myScriptStringImpl;
+
 
 // ScriptInvItem *(int xx, int yy)
 RuntimeScriptValue Sc_GetInvAtLocation(const RuntimeScriptValue *params, int32_t param_count) {
-	API_SCALL_OBJ_PINT2(ScriptInvItem, ccDynamicInv, GetInvAtLocation);
+	API_SCALL_OBJ_PINT2(ScriptInvItem, _GP(ccDynamicInv), GetInvAtLocation);
 }
 
 // int (ScriptInvItem *iitem, int mood)
@@ -159,7 +159,7 @@ RuntimeScriptValue Sc_InventoryItem_GetPropertyText(void *self, const RuntimeScr
 
 // const char* (ScriptInvItem *scii, const char *property)
 RuntimeScriptValue Sc_InventoryItem_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ_POBJ(ScriptInvItem, const char, myScriptStringImpl, InventoryItem_GetTextProperty, const char);
+	API_CONST_OBJCALL_OBJ_POBJ(ScriptInvItem, const char, _GP(myScriptStringImpl), InventoryItem_GetTextProperty, const char);
 }
 
 RuntimeScriptValue Sc_InventoryItem_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) {
@@ -207,7 +207,7 @@ RuntimeScriptValue Sc_InventoryItem_GetID(void *self, const RuntimeScriptValue *
 
 // const char* (ScriptInvItem *invitem)
 RuntimeScriptValue Sc_InventoryItem_GetName_New(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ(ScriptInvItem, const char, myScriptStringImpl, InventoryItem_GetName_New);
+	API_CONST_OBJCALL_OBJ(ScriptInvItem, const char, _GP(myScriptStringImpl), InventoryItem_GetName_New);
 }
 
 
diff --git a/engines/ags/engine/ac/invwindow.cpp b/engines/ags/engine/ac/invwindow.cpp
index 0b67bbc520..75b3ca189e 100644
--- a/engines/ags/engine/ac/invwindow.cpp
+++ b/engines/ags/engine/ac/invwindow.cpp
@@ -56,14 +56,14 @@ using namespace AGS::Shared;
 
 
 extern CharacterExtras *charextra;
-extern ScriptInvItem scrInv[MAX_INV];
+
 extern int mouse_ifacebut_xoffs, mouse_ifacebut_yoffs;
 
 extern int evblocknum;
 extern CharacterInfo *playerchar;
 extern AGSPlatformDriver *platform;
-extern CCCharacter ccDynamicCharacter;
-extern CCInventory ccDynamicInv;
+
+
 
 int in_inv_screen = 0, inv_screen_newroom = -1;
 
@@ -149,7 +149,7 @@ void InvWindow_ScrollUp(GUIInvWindow *guii) {
 ScriptInvItem *InvWindow_GetItemAtIndex(GUIInvWindow *guii, int index) {
 	if ((index < 0) || (index >= charextra[guii->GetCharacterId()].invorder_count))
 		return nullptr;
-	return &scrInv[charextra[guii->GetCharacterId()].invorder[index]];
+	return &_G(scrInv)[charextra[guii->GetCharacterId()].invorder[index]];
 }
 
 //=============================================================================
@@ -541,7 +541,7 @@ RuntimeScriptValue Sc_InvWindow_ScrollUp(void *self, const RuntimeScriptValue *p
 
 // CharacterInfo* (GUIInvWindow *guii)
 RuntimeScriptValue Sc_InvWindow_GetCharacterToUse(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ(GUIInvWindow, CharacterInfo, ccDynamicCharacter, InvWindow_GetCharacterToUse);
+	API_OBJCALL_OBJ(GUIInvWindow, CharacterInfo, _GP(ccDynamicCharacter), InvWindow_GetCharacterToUse);
 }
 
 // void (GUIInvWindow *guii, CharacterInfo *chaa)
@@ -551,7 +551,7 @@ RuntimeScriptValue Sc_InvWindow_SetCharacterToUse(void *self, const RuntimeScrip
 
 // ScriptInvItem* (GUIInvWindow *guii, int index)
 RuntimeScriptValue Sc_InvWindow_GetItemAtIndex(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ_PINT(GUIInvWindow, ScriptInvItem, ccDynamicInv, InvWindow_GetItemAtIndex);
+	API_OBJCALL_OBJ_PINT(GUIInvWindow, ScriptInvItem, _GP(ccDynamicInv), InvWindow_GetItemAtIndex);
 }
 
 // int (GUIInvWindow *guii)
diff --git a/engines/ags/engine/ac/label.cpp b/engines/ags/engine/ac/label.cpp
index 45455d0761..2fb12950cd 100644
--- a/engines/ags/engine/ac/label.cpp
+++ b/engines/ags/engine/ac/label.cpp
@@ -96,7 +96,7 @@ void Label_SetFont(GUILabel *guil, int fontnum) {
 //
 //=============================================================================
 
-extern ScriptString myScriptStringImpl;
+
 
 // void (GUILabel *labl, char *buffer)
 RuntimeScriptValue Sc_Label_GetText(void *self, const RuntimeScriptValue *params, int32_t param_count) {
@@ -129,7 +129,7 @@ RuntimeScriptValue Sc_Label_SetFont(void *self, const RuntimeScriptValue *params
 
 // const char* (GUILabel *labl)
 RuntimeScriptValue Sc_Label_GetText_New(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ(GUILabel, const char, myScriptStringImpl, Label_GetText_New);
+	API_CONST_OBJCALL_OBJ(GUILabel, const char, _GP(myScriptStringImpl), Label_GetText_New);
 }
 
 // int (GUILabel *labl)
diff --git a/engines/ags/engine/ac/listbox.cpp b/engines/ags/engine/ac/listbox.cpp
index b81f656ad3..3ccee016e3 100644
--- a/engines/ags/engine/ac/listbox.cpp
+++ b/engines/ags/engine/ac/listbox.cpp
@@ -159,12 +159,12 @@ int ListBox_FillSaveGameList(GUIListBox *listbox) {
 
 int ListBox_GetItemAtLocation(GUIListBox *listbox, int x, int y) {
 
-	if (!guis[listbox->ParentId].IsDisplayed())
+	if (!_GP(guis)[listbox->ParentId].IsDisplayed())
 		return -1;
 
 	data_to_game_coords(&x, &y);
-	x = (x - listbox->X) - guis[listbox->ParentId].X;
-	y = (y - listbox->Y) - guis[listbox->ParentId].Y;
+	x = (x - listbox->X) - _GP(guis)[listbox->ParentId].X;
+	y = (y - listbox->Y) - _GP(guis)[listbox->ParentId].Y;
 
 	if ((x < 0) || (y < 0) || (x >= listbox->Width) || (y >= listbox->Height))
 		return -1;
@@ -367,11 +367,11 @@ void ListBox_ScrollUp(GUIListBox *listbox) {
 
 GUIListBox *is_valid_listbox(int guin, int objn) {
 	if ((guin < 0) | (guin >= _GP(game).numgui)) quit("!ListBox: invalid GUI number");
-	if ((objn < 0) | (objn >= guis[guin].GetControlCount())) quit("!ListBox: invalid object number");
-	if (guis[guin].GetControlType(objn) != kGUIListBox)
+	if ((objn < 0) | (objn >= _GP(guis)[guin].GetControlCount())) quit("!ListBox: invalid object number");
+	if (_GP(guis)[guin].GetControlType(objn) != kGUIListBox)
 		quit("!ListBox: specified control is not a list box");
 	guis_need_update = 1;
-	return (GUIListBox *)guis[guin].GetControl(objn);
+	return (GUIListBox *)_GP(guis)[guin].GetControl(objn);
 }
 
 //=============================================================================
@@ -380,7 +380,7 @@ GUIListBox *is_valid_listbox(int guin, int objn) {
 //
 //=============================================================================
 
-extern ScriptString myScriptStringImpl;
+
 
 // int (GUIListBox *lbb, const char *text)
 RuntimeScriptValue Sc_ListBox_AddItem(void *self, const RuntimeScriptValue *params, int32_t param_count) {
@@ -409,7 +409,7 @@ RuntimeScriptValue Sc_ListBox_GetItemAtLocation(void *self, const RuntimeScriptV
 
 // char *(GUIListBox *listbox, int index, char *buffer)
 RuntimeScriptValue Sc_ListBox_GetItemText(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ_PINT_POBJ(GUIListBox, char, myScriptStringImpl, ListBox_GetItemText, char);
+	API_OBJCALL_OBJ_PINT_POBJ(GUIListBox, char, _GP(myScriptStringImpl), ListBox_GetItemText, char);
 }
 
 // int (GUIListBox *lbb, int index, const char *text)
@@ -490,7 +490,7 @@ RuntimeScriptValue Sc_ListBox_GetItemCount(void *self, const RuntimeScriptValue
 
 // const char* (GUIListBox *listbox, int index)
 RuntimeScriptValue Sc_ListBox_GetItems(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ_PINT(GUIListBox, const char, myScriptStringImpl, ListBox_GetItems);
+	API_CONST_OBJCALL_OBJ_PINT(GUIListBox, const char, _GP(myScriptStringImpl), ListBox_GetItems);
 }
 
 // int (GUIListBox *listbox)
diff --git a/engines/ags/engine/ac/mouse.cpp b/engines/ags/engine/ac/mouse.cpp
index f90b30a5ef..ed9bd52025 100644
--- a/engines/ags/engine/ac/mouse.cpp
+++ b/engines/ags/engine/ac/mouse.cpp
@@ -255,9 +255,9 @@ void enable_cursor_mode(int modd) {
 	int uu, ww;
 
 	for (uu = 0; uu < _GP(game).numgui; uu++) {
-		for (ww = 0; ww < guis[uu].GetControlCount(); ww++) {
-			if (guis[uu].GetControlType(ww) != kGUIButton) continue;
-			GUIButton *gbpt = (GUIButton *)guis[uu].GetControl(ww);
+		for (ww = 0; ww < _GP(guis)[uu].GetControlCount(); ww++) {
+			if (_GP(guis)[uu].GetControlType(ww) != kGUIButton) continue;
+			GUIButton *gbpt = (GUIButton *)_GP(guis)[uu].GetControl(ww);
 			if (gbpt->ClickAction[kMouseLeft] != kGUIAction_SetMode) continue;
 			if (gbpt->ClickData[kMouseLeft] != modd) continue;
 			gbpt->SetEnabled(true);
@@ -272,9 +272,9 @@ void disable_cursor_mode(int modd) {
 	int uu, ww;
 
 	for (uu = 0; uu < _GP(game).numgui; uu++) {
-		for (ww = 0; ww < guis[uu].GetControlCount(); ww++) {
-			if (guis[uu].GetControlType(ww) != kGUIButton) continue;
-			GUIButton *gbpt = (GUIButton *)guis[uu].GetControl(ww);
+		for (ww = 0; ww < _GP(guis)[uu].GetControlCount(); ww++) {
+			if (_GP(guis)[uu].GetControlType(ww) != kGUIButton) continue;
+			GUIButton *gbpt = (GUIButton *)_GP(guis)[uu].GetControl(ww);
 			if (gbpt->ClickAction[kMouseLeft] != kGUIAction_SetMode) continue;
 			if (gbpt->ClickData[kMouseLeft] != modd) continue;
 			gbpt->SetEnabled(false);
diff --git a/engines/ags/engine/ac/object.cpp b/engines/ags/engine/ac/object.cpp
index 16964bffd6..624c835f14 100644
--- a/engines/ags/engine/ac/object.cpp
+++ b/engines/ags/engine/ac/object.cpp
@@ -55,17 +55,11 @@ namespace AGS3 {
 
 using namespace AGS::Shared;
 
-extern ScriptObject scrObj[MAX_ROOM_OBJECTS];
 extern RoomStatus *croom;
 extern RoomObject *objs;
-extern ViewStruct *views;
-
-extern ObjectCache objcache[MAX_ROOM_OBJECTS];
-extern MoveList *mls;
 
 extern Bitmap *walkable_areas_temp;
 extern IGraphicsDriver *gfxDriver;
-extern CCObject ccDynamicObject;
 
 
 int Object_IsCollidingWithObject(ScriptObject *objj, ScriptObject *obj2) {
@@ -76,14 +70,14 @@ ScriptObject *GetObjectAtScreen(int xx, int yy) {
 	int hsnum = GetObjectIDAtScreen(xx, yy);
 	if (hsnum < 0)
 		return nullptr;
-	return &scrObj[hsnum];
+	return &_G(scrObj)[hsnum];
 }
 
 ScriptObject *GetObjectAtRoom(int x, int y) {
 	int hsnum = GetObjectIDAtRoom(x, y);
 	if (hsnum < 0)
 		return nullptr;
-	return &scrObj[hsnum];
+	return &_G(scrObj)[hsnum];
 }
 
 AGS_INLINE int is_valid_object(int obtest) {
@@ -107,8 +101,8 @@ void Object_SetView(ScriptObject *objj, int view, int loop, int frame) {
 		if (frame < 0) frame = obj.frame;
 		const int vidx = view - 1;
 		if (vidx < 0 || vidx >= _GP(game).numviews) quit("!Object_SetView: invalid view number used");
-		loop = Math::Clamp(loop, 0, (int)views[vidx].numLoops - 1);
-		frame = Math::Clamp(frame, 0, (int)views[vidx].loops[loop].numFrames - 1);
+		loop = Math::Clamp(loop, 0, (int)_G(views)[vidx].numLoops - 1);
+		frame = Math::Clamp(frame, 0, (int)_G(views)[vidx].loops[loop].numFrames - 1);
 	}
 	SetObjectFrame(objj->id, view, loop, frame);
 }
@@ -337,7 +331,7 @@ void Object_SetManualScaling(ScriptObject *objj, bool on) {
 	if (on) objs[objj->id].flags &= ~OBJF_USEROOMSCALING;
 	else objs[objj->id].flags |= OBJF_USEROOMSCALING;
 	// clear the cache
-	objcache[objj->id].ywas = -9999;
+	_G(objcache)[objj->id].ywas = -9999;
 }
 
 void Object_SetIgnoreScaling(ScriptObject *objj, int newval) {
@@ -442,8 +436,8 @@ void move_object(int objj, int tox, int toy, int spee, int ignwal) {
 	set_color_depth(_GP(game).GetColorDepth());
 	if (mslot > 0) {
 		objs[objj].moving = mslot;
-		mls[mslot].direct = ignwal;
-		convert_move_path_to_room_resolution(&mls[mslot]);
+		_G(mls)[mslot].direct = ignwal;
+		convert_move_path_to_room_resolution(&_G(mls)[mslot]);
 	}
 }
 
@@ -562,7 +556,7 @@ int check_click_on_object(int roomx, int roomy, int mood) {
 //
 //=============================================================================
 
-extern ScriptString myScriptStringImpl;
+
 
 // void (ScriptObject *objj, int loop, int delay, int repeat, int blocking, int direction)
 RuntimeScriptValue Sc_Object_Animate(void *self, const RuntimeScriptValue *params, int32_t param_count) {
@@ -595,7 +589,7 @@ RuntimeScriptValue Sc_Object_GetPropertyText(void *self, const RuntimeScriptValu
 
 //const char* (ScriptObject *objj, const char *property)
 RuntimeScriptValue Sc_Object_GetTextProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ_POBJ(ScriptObject, const char, myScriptStringImpl, Object_GetTextProperty, const char);
+	API_CONST_OBJCALL_OBJ_POBJ(ScriptObject, const char, _GP(myScriptStringImpl), Object_GetTextProperty, const char);
 }
 
 RuntimeScriptValue Sc_Object_SetProperty(void *self, const RuntimeScriptValue *params, int32_t param_count) {
@@ -692,12 +686,12 @@ RuntimeScriptValue Sc_Object_Tint(void *self, const RuntimeScriptValue *params,
 }
 
 RuntimeScriptValue Sc_GetObjectAtRoom(const RuntimeScriptValue *params, int32_t param_count) {
-	API_SCALL_OBJ_PINT2(ScriptObject, ccDynamicObject, GetObjectAtRoom);
+	API_SCALL_OBJ_PINT2(ScriptObject, _GP(ccDynamicObject), GetObjectAtRoom);
 }
 
 // ScriptObject *(int xx, int yy)
 RuntimeScriptValue Sc_GetObjectAtScreen(const RuntimeScriptValue *params, int32_t param_count) {
-	API_SCALL_OBJ_PINT2(ScriptObject, ccDynamicObject, GetObjectAtScreen);
+	API_SCALL_OBJ_PINT2(ScriptObject, _GP(ccDynamicObject), GetObjectAtScreen);
 }
 
 // int (ScriptObject *objj)
@@ -801,7 +795,7 @@ RuntimeScriptValue Sc_Object_GetMoving(void *self, const RuntimeScriptValue *par
 
 // const char* (ScriptObject *objj)
 RuntimeScriptValue Sc_Object_GetName_New(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ(ScriptObject, const char, myScriptStringImpl, Object_GetName_New);
+	API_CONST_OBJCALL_OBJ(ScriptObject, const char, _GP(myScriptStringImpl), Object_GetName_New);
 }
 
 RuntimeScriptValue Sc_Object_GetScaling(void *self, const RuntimeScriptValue *params, int32_t param_count) {
diff --git a/engines/ags/engine/ac/objectcache.h b/engines/ags/engine/ac/objectcache.h
index 7f2d994e15..438dfa2e9e 100644
--- a/engines/ags/engine/ac/objectcache.h
+++ b/engines/ags/engine/ac/objectcache.h
@@ -27,12 +27,13 @@ namespace AGS3 {
 
 // stores cached object info
 struct ObjectCache {
-	Shared::Bitmap *image;
-	int   sppic;
-	short tintredwas, tintgrnwas, tintbluwas, tintamntwas, tintlightwas;
-	short lightlevwas, mirroredWas, zoomWas;
+	Shared::Bitmap *image = nullptr;
+	int   sppic = 0;
+	short tintredwas = 0, tintgrnwas = 0, tintbluwas = 0;
+	short tintamntwas = 0, tintlightwas = 0;
+	short lightlevwas = 0, mirroredWas = 0, zoomWas = 0;
 	// The following are used to determine if the character has moved
-	int   xwas, ywas;
+	int   xwas = 0, ywas = 0;
 };
 
 } // namespace AGS3
diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp
index d85b4c42db..a2810573cf 100644
--- a/engines/ags/engine/ac/overlay.cpp
+++ b/engines/ags/engine/ac/overlay.cpp
@@ -49,7 +49,7 @@ using namespace AGS::Engine;
 
 extern int displayed_room;
 extern int face_talking;
-extern ViewStruct *views;
+
 extern CharacterExtras *charextra;
 extern IGraphicsDriver *gfxDriver;
 
@@ -238,7 +238,7 @@ void get_overlay_position(const ScreenOverlay &over, int *x, int *y) {
 		int charid = over.y;
 
 		auto view = FindNearestViewport(charid);
-		const int charpic = views[_GP(game).chars[charid].view].loops[_GP(game).chars[charid].loop].frames[0].pic;
+		const int charpic = _G(views)[_GP(game).chars[charid].view].loops[_GP(game).chars[charid].loop].frames[0].pic;
 		const int height = (charextra[charid].height < 1) ? _GP(game).SpriteInfos[charpic].Height : charextra[charid].height;
 		Point screenpt = view->RoomToScreen(
 			data_to_game_coord(_GP(game).chars[charid].x),
diff --git a/engines/ags/engine/ac/parser.cpp b/engines/ags/engine/ac/parser.cpp
index 1c61119f8d..b1aadd7d39 100644
--- a/engines/ags/engine/ac/parser.cpp
+++ b/engines/ags/engine/ac/parser.cpp
@@ -304,7 +304,7 @@ int parse_sentence(const char *src_text, int *numwords, short *wordarray, short
 //
 //=============================================================================
 
-extern ScriptString myScriptStringImpl;
+
 
 // int (const char *wordToFind)
 RuntimeScriptValue Sc_Parser_FindWordID(const RuntimeScriptValue *params, int32_t param_count) {
@@ -318,7 +318,7 @@ RuntimeScriptValue Sc_ParseText(const RuntimeScriptValue *params, int32_t param_
 
 // const char* ()
 RuntimeScriptValue Sc_Parser_SaidUnknownWord(const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_SCALL_OBJ(const char, myScriptStringImpl, Parser_SaidUnknownWord);
+	API_CONST_SCALL_OBJ(const char, _GP(myScriptStringImpl), Parser_SaidUnknownWord);
 }
 
 // int  (char*checkwords)
diff --git a/engines/ags/engine/ac/properties.cpp b/engines/ags/engine/ac/properties.cpp
index 1aa5b17e0c..68aa7be8f2 100644
--- a/engines/ags/engine/ac/properties.cpp
+++ b/engines/ags/engine/ac/properties.cpp
@@ -33,7 +33,7 @@ namespace AGS3 {
 
 using namespace AGS::Shared;
 
-extern ScriptString myScriptStringImpl;
+
 
 // begin custom property functions
 
diff --git a/engines/ags/engine/ac/region.cpp b/engines/ags/engine/ac/region.cpp
index d7616d0504..dd89680e11 100644
--- a/engines/ags/engine/ac/region.cpp
+++ b/engines/ags/engine/ac/region.cpp
@@ -40,17 +40,12 @@ namespace AGS3 {
 
 using namespace AGS::Shared;
 
-extern ScriptRegion scrRegion[MAX_ROOM_REGIONS];
-
 extern RoomStatus *croom;
-
 extern COLOR_MAP maincoltable;
 extern color palette[256];
-extern CCRegion ccDynamicRegion;
-
 
 ScriptRegion *GetRegionAtRoom(int xx, int yy) {
-	return &scrRegion[GetRegionIDAtRoom(xx, yy)];
+	return &_G(scrRegion)[GetRegionIDAtRoom(xx, yy)];
 }
 
 ScriptRegion *GetRegionAtScreen(int x, int y) {
@@ -142,11 +137,11 @@ void generate_light_table() {
 
 // ScriptRegion *(int xx, int yy)
 RuntimeScriptValue Sc_GetRegionAtRoom(const RuntimeScriptValue *params, int32_t param_count) {
-	API_SCALL_OBJ_PINT2(ScriptRegion, ccDynamicRegion, GetRegionAtRoom);
+	API_SCALL_OBJ_PINT2(ScriptRegion, _GP(ccDynamicRegion), GetRegionAtRoom);
 }
 
 RuntimeScriptValue Sc_GetRegionAtScreen(const RuntimeScriptValue *params, int32_t param_count) {
-	API_SCALL_OBJ_PINT2(ScriptRegion, ccDynamicRegion, GetRegionAtScreen);
+	API_SCALL_OBJ_PINT2(ScriptRegion, _GP(ccDynamicRegion), GetRegionAtScreen);
 }
 
 RuntimeScriptValue Sc_Region_GetDrawingSurface(const RuntimeScriptValue *params, int32_t param_count) {
diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp
index b980f15fb5..bd5f48898e 100644
--- a/engines/ags/engine/ac/room.cpp
+++ b/engines/ags/engine/ac/room.cpp
@@ -95,16 +95,16 @@ extern RoomObject *objs;
 extern ccInstance *roominst;
 extern AGSPlatformDriver *platform;
 extern int numevents;
-extern CharacterCache *charcache;
-extern ObjectCache objcache[MAX_ROOM_OBJECTS];
+
+
 extern CharacterExtras *charextra;
 extern int done_es_error;
 extern int our_eip;
 extern Bitmap *walkareabackup, *walkable_areas_temp;
-extern ScriptObject scrObj[MAX_ROOM_OBJECTS];
+
 
 extern int in_new_room, new_room_was;  // 1 in new room, 2 first time in new room, 3 loading saved game
-extern ScriptHotspot scrHotspot[MAX_ROOM_HOTSPOTS];
+
 extern int in_leaves_screen;
 extern CharacterInfo *playerchar;
 extern int starting_room;
@@ -124,9 +124,6 @@ extern int mouse_z_was;
 extern Bitmap **guibg;
 extern IDriverDependantBitmap **guibgbmp;
 
-extern CCHotspot ccDynamicHotspot;
-extern CCObject ccDynamicObject;
-
 RGB_MAP rgb_table;  // for 256-col antialiasing
 int new_room_flags = 0;
 int gs_to_newroom = -1;
@@ -304,10 +301,10 @@ void unload_old_room() {
 
 	// wipe the character cache when we change rooms
 	for (ff = 0; ff < _GP(game).numcharacters; ff++) {
-		if (charcache[ff].inUse) {
-			delete charcache[ff].image;
-			charcache[ff].image = nullptr;
-			charcache[ff].inUse = 0;
+		if (_G(charcache)[ff].inUse) {
+			delete _G(charcache)[ff].image;
+			_G(charcache)[ff].image = nullptr;
+			_G(charcache)[ff].inUse = 0;
 		}
 		// ensure that any half-moves (eg. with scaled movement) are stopped
 		charextra[ff].xwas = INVALID_X;
@@ -335,8 +332,8 @@ void unload_old_room() {
 
 	// clear the object cache
 	for (ff = 0; ff < MAX_ROOM_OBJECTS; ff++) {
-		delete objcache[ff].image;
-		objcache[ff].image = nullptr;
+		delete _G(objcache)[ff].image;
+		_G(objcache)[ff].image = nullptr;
 	}
 	// clear the actsps buffers to save memory, since the
 	// objects/characters involved probably aren't on the
@@ -645,7 +642,7 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
 
 	for (cc = 0; cc < MAX_ROOM_OBJECTS; cc++) {
 		// 64 bit: Using the id instead
-		// scrObj[cc].obj = &croom->obj[cc];
+		// _G(scrObj)[cc].obj = &croom->obj[cc];
 		objectScriptObjNames[cc].Free();
 	}
 
@@ -654,14 +651,14 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
 		if (_GP(thisroom).Objects[cc].ScriptName.IsEmpty())
 			continue;
 		objectScriptObjNames[cc] = _GP(thisroom).Objects[cc].ScriptName;
-		ccAddExternalDynamicObject(objectScriptObjNames[cc], &scrObj[cc], &ccDynamicObject);
+		ccAddExternalDynamicObject(objectScriptObjNames[cc], &_G(scrObj)[cc], &_GP(ccDynamicObject));
 	}
 
 	for (cc = 0; cc < MAX_ROOM_HOTSPOTS; cc++) {
 		if (_GP(thisroom).Hotspots[cc].ScriptName.IsEmpty())
 			continue;
 
-		ccAddExternalDynamicObject(_GP(thisroom).Hotspots[cc].ScriptName, &scrHotspot[cc], &ccDynamicHotspot);
+		ccAddExternalDynamicObject(_GP(thisroom).Hotspots[cc].ScriptName, &_G(scrHotspot)[cc], &_GP(ccDynamicHotspot));
 	}
 
 	our_eip = 206;
@@ -1103,7 +1100,7 @@ void convert_move_path_to_room_resolution(MoveList *ml) {
 //
 //=============================================================================
 
-extern ScriptString myScriptStringImpl;
+
 
 // ScriptDrawingSurface* (int backgroundNumber)
 RuntimeScriptValue Sc_Room_GetDrawingSurfaceForBackground(const RuntimeScriptValue *params, int32_t param_count) {
@@ -1117,7 +1114,7 @@ RuntimeScriptValue Sc_Room_GetProperty(const RuntimeScriptValue *params, int32_t
 
 // const char* (const char *property)
 RuntimeScriptValue Sc_Room_GetTextProperty(const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_SCALL_OBJ_POBJ(const char, myScriptStringImpl, Room_GetTextProperty, const char);
+	API_CONST_SCALL_OBJ_POBJ(const char, _GP(myScriptStringImpl), Room_GetTextProperty, const char);
 }
 
 RuntimeScriptValue Sc_Room_SetProperty(const RuntimeScriptValue *params, int32_t param_count) {
@@ -1151,7 +1148,7 @@ RuntimeScriptValue Sc_Room_GetLeftEdge(const RuntimeScriptValue *params, int32_t
 
 // const char* (int index)
 RuntimeScriptValue Sc_Room_GetMessages(const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_SCALL_OBJ_PINT(const char, myScriptStringImpl, Room_GetMessages);
+	API_CONST_SCALL_OBJ_PINT(const char, _GP(myScriptStringImpl), Room_GetMessages);
 }
 
 // int ()
diff --git a/engines/ags/engine/ac/roomobject.cpp b/engines/ags/engine/ac/roomobject.cpp
index f66e31dc7b..aff837ec85 100644
--- a/engines/ags/engine/ac/roomobject.cpp
+++ b/engines/ags/engine/ac/roomobject.cpp
@@ -35,7 +35,7 @@ namespace AGS3 {
 
 using AGS::Shared::Stream;
 
-extern ViewStruct *views;
+
 
 
 
@@ -96,7 +96,7 @@ void RoomObject::UpdateCyclingView() {
 
 	}  // end if forwards
 
-	ViewFrame *vfptr = &views[view].loops[loop].frames[frame];
+	ViewFrame *vfptr = &_G(views)[view].loops[loop].frames[frame];
 	num = vfptr->pic;
 
 	if (cycling == 0)
@@ -109,10 +109,10 @@ void RoomObject::UpdateCyclingView() {
 
 void RoomObject::update_cycle_view_forwards() {
 	frame++;
-	if (frame >= views[view].loops[loop].numFrames) {
+	if (frame >= _G(views)[view].loops[loop].numFrames) {
 		// go to next loop thing
-		if (views[view].loops[loop].RunNextLoop()) {
-			if (loop + 1 >= views[view].numLoops)
+		if (_G(views)[view].loops[loop].RunNextLoop()) {
+			if (loop + 1 >= _G(views)[view].numLoops)
 				quit("!Last loop in a view requested to move to next loop");
 			loop++;
 			frame = 0;
@@ -124,7 +124,7 @@ void RoomObject::update_cycle_view_forwards() {
 			if (_GP(play).no_multiloop_repeat == 0) {
 				// multi-loop anims, go back to start of it
 				while ((loop > 0) &&
-					(views[view].loops[loop - 1].RunNextLoop()))
+					(_G(views)[view].loops[loop - 1].RunNextLoop()))
 					loop--;
 			}
 			if (cycling % ANIM_BACKWARDS == ANIM_ONCERESET)
@@ -139,16 +139,16 @@ void RoomObject::update_cycle_view_backwards() {
 	frame--;
 	if (frame < 0) {
 		if ((loop > 0) &&
-			(views[view].loops[loop - 1].RunNextLoop())) {
+			(_G(views)[view].loops[loop - 1].RunNextLoop())) {
 			// If it's a Go-to-next-loop on the previous one, then go back
 			loop--;
-			frame = views[view].loops[loop].numFrames - 1;
+			frame = _G(views)[view].loops[loop].numFrames - 1;
 		} else if (cycling % ANIM_BACKWARDS == ANIM_ONCE) {
 			// leave it on the first frame
 			cycling = 0;
 			frame = 0;
 		} else { // repeating animation
-			frame = views[view].loops[loop].numFrames - 1;
+			frame = _G(views)[view].loops[loop].numFrames - 1;
 		}
 	}
 }
diff --git a/engines/ags/engine/ac/route_finder_impl.cpp b/engines/ags/engine/ac/route_finder_impl.cpp
index 49bfdee00a..275012e4e2 100644
--- a/engines/ags/engine/ac/route_finder_impl.cpp
+++ b/engines/ags/engine/ac/route_finder_impl.cpp
@@ -33,11 +33,10 @@
 #include "ags/shared/ac/common_defines.h"
 #include "ags/shared/gfx/bitmap.h"
 #include "ags/shared/debugging/out.h"
+#include "ags/globals.h"
 
 namespace AGS3 {
 
-extern MoveList *mls;
-
 using AGS::Shared::Bitmap;
 
 // #define DEBUG_PATHFINDER
@@ -239,22 +238,22 @@ int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int
 #endif
 
 	int mlist = movlst;
-	mls[mlist].numstage = num_navpoints;
-	memcpy(&mls[mlist].pos[0], &navpoints[0], sizeof(int32_t) * num_navpoints);
+	_G(mls)[mlist].numstage = num_navpoints;
+	memcpy(&_G(mls)[mlist].pos[0], &navpoints[0], sizeof(int32_t) * num_navpoints);
 #ifdef DEBUG_PATHFINDER
 	AGS::Shared::Debug::Printf("stages: %d\n", num_navpoints);
 #endif
 
 	for (i = 0; i < num_navpoints - 1; i++)
-		calculate_move_stage(&mls[mlist], i);
-
-	mls[mlist].fromx = srcx;
-	mls[mlist].fromy = srcy;
-	mls[mlist].onstage = 0;
-	mls[mlist].onpart = 0;
-	mls[mlist].doneflag = 0;
-	mls[mlist].lastx = -1;
-	mls[mlist].lasty = -1;
+		calculate_move_stage(&_G(mls)[mlist], i);
+
+	_G(mls)[mlist].fromx = srcx;
+	_G(mls)[mlist].fromy = srcy;
+	_G(mls)[mlist].onstage = 0;
+	_G(mls)[mlist].onpart = 0;
+	_G(mls)[mlist].doneflag = 0;
+	_G(mls)[mlist].lastx = -1;
+	_G(mls)[mlist].lasty = -1;
 	return mlist;
 }
 
diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.cpp b/engines/ags/engine/ac/route_finder_impl_legacy.cpp
index c047ab1ee1..57e42bcc76 100644
--- a/engines/ags/engine/ac/route_finder_impl_legacy.cpp
+++ b/engines/ags/engine/ac/route_finder_impl_legacy.cpp
@@ -28,22 +28,19 @@
 //=============================================================================
 
 #include "ags/engine/ac/route_finder_impl_legacy.h"
-
-//include <string.h>
-//include <math.h>
-
 #include "ags/shared/ac/common.h"   // quit()
 #include "ags/shared/ac/common_defines.h"
 #include "ags/shared/game/roomstruct.h"
 #include "ags/engine/ac/movelist.h"     // MoveList
 #include "ags/shared/gfx/bitmap.h"
 #include "ags/shared/debugging/out.h"
+#include "ags/globals.h"
 
 namespace AGS3 {
 
 extern void update_polled_stuff_if_runtime();
 
-extern MoveList *mls;
+
 
 using AGS::Shared::Bitmap;
 namespace BitmapHelper = AGS::Shared::BitmapHelper;
@@ -746,7 +743,7 @@ void calculate_move_stage(MoveList *mlsp, int aaa) {
 
 int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross, int ignore_walls) {
 	assert(onscreen != nullptr);
-	assert(mls != nullptr);
+	assert(_G(mls) != nullptr);
 	assert(pathbackx != nullptr);
 	assert(pathbacky != nullptr);
 
@@ -858,23 +855,23 @@ stage_again:
 		AGS::Shared::Debug::Printf("Route from %d,%d to %d,%d - %d stage, %d stages", orisrcx, orisrcy, xx, yy, pathbackstage, numstages);
 #endif
 		int mlist = movlst;
-		mls[mlist].numstage = numstages;
-		memcpy(&mls[mlist].pos[0], &reallyneed[0], sizeof(int32_t) * numstages);
+		_G(mls)[mlist].numstage = numstages;
+		memcpy(&_G(mls)[mlist].pos[0], &reallyneed[0], sizeof(int32_t) * numstages);
 #ifdef DEBUG_PATHFINDER
 		AGS::Shared::Debug::Printf("stages: %d\n", numstages);
 #endif
 
 		for (aaa = 0; aaa < numstages - 1; aaa++) {
-			calculate_move_stage(&mls[mlist], aaa);
+			calculate_move_stage(&_G(mls)[mlist], aaa);
 		}
 
-		mls[mlist].fromx = orisrcx;
-		mls[mlist].fromy = orisrcy;
-		mls[mlist].onstage = 0;
-		mls[mlist].onpart = 0;
-		mls[mlist].doneflag = 0;
-		mls[mlist].lastx = -1;
-		mls[mlist].lasty = -1;
+		_G(mls)[mlist].fromx = orisrcx;
+		_G(mls)[mlist].fromy = orisrcy;
+		_G(mls)[mlist].onstage = 0;
+		_G(mls)[mlist].onpart = 0;
+		_G(mls)[mlist].doneflag = 0;
+		_G(mls)[mlist].lastx = -1;
+		_G(mls)[mlist].lasty = -1;
 #ifdef DEBUG_PATHFINDER
 		// getch();
 #endif
diff --git a/engines/ags/engine/ac/scriptcontainers.cpp b/engines/ags/engine/ac/scriptcontainers.cpp
index 0baa5ea971..267bdcabbd 100644
--- a/engines/ags/engine/ac/scriptcontainers.cpp
+++ b/engines/ags/engine/ac/scriptcontainers.cpp
@@ -36,11 +36,10 @@
 #include "ags/engine/script/script_api.h"
 #include "ags/engine/script/script_runtime.h"
 #include "ags/shared/util/bbop.h"
+#include "ags/globals.h"
 
 namespace AGS3 {
 
-extern ScriptString myScriptStringImpl;
-
 //=============================================================================
 //
 // Dictionary of strings script API.
@@ -147,7 +146,7 @@ RuntimeScriptValue Sc_Dict_Contains(void *self, const RuntimeScriptValue *params
 }
 
 RuntimeScriptValue Sc_Dict_Get(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ_POBJ(ScriptDictBase, const char, myScriptStringImpl, Dict_Get, const char);
+	API_CONST_OBJCALL_OBJ_POBJ(ScriptDictBase, const char, _GP(myScriptStringImpl), Dict_Get, const char);
 }
 
 RuntimeScriptValue Sc_Dict_Remove(void *self, const RuntimeScriptValue *params, int32_t param_count) {
diff --git a/engines/ags/engine/ac/string.cpp b/engines/ags/engine/ac/string.cpp
index 4612ec2198..9ddc04f6ba 100644
--- a/engines/ags/engine/ac/string.cpp
+++ b/engines/ags/engine/ac/string.cpp
@@ -43,7 +43,7 @@ namespace AGS3 {
 
 
 extern int longestline;
-extern ScriptString myScriptStringImpl;
+
 
 int String_IsNullOrEmpty(const char *thisString) {
 	if ((thisString == nullptr) || (thisString[0] == 0))
@@ -309,12 +309,12 @@ RuntimeScriptValue Sc_String_IsNullOrEmpty(const RuntimeScriptValue *params, int
 
 // const char* (const char *thisString, const char *extrabit)
 RuntimeScriptValue Sc_String_Append(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ_POBJ(const char, const char, myScriptStringImpl, String_Append, const char);
+	API_CONST_OBJCALL_OBJ_POBJ(const char, const char, _GP(myScriptStringImpl), String_Append, const char);
 }
 
 // const char* (const char *thisString, char extraOne)
 RuntimeScriptValue Sc_String_AppendChar(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ_PINT(const char, const char, myScriptStringImpl, String_AppendChar);
+	API_CONST_OBJCALL_OBJ_PINT(const char, const char, _GP(myScriptStringImpl), String_AppendChar);
 }
 
 // int (const char *thisString, const char *otherString, bool caseSensitive)
@@ -329,7 +329,7 @@ RuntimeScriptValue Sc_StrContains(void *self, const RuntimeScriptValue *params,
 
 // const char* (const char *srcString)
 RuntimeScriptValue Sc_String_Copy(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ(const char, const char, myScriptStringImpl, String_Copy);
+	API_CONST_OBJCALL_OBJ(const char, const char, _GP(myScriptStringImpl), String_Copy);
 }
 
 // int (const char *thisString, const char *checkForString, bool caseSensitive)
@@ -340,22 +340,22 @@ RuntimeScriptValue Sc_String_EndsWith(void *self, const RuntimeScriptValue *para
 // const char* (const char *texx, ...)
 RuntimeScriptValue Sc_String_Format(const RuntimeScriptValue *params, int32_t param_count) {
 	API_SCALL_SCRIPT_SPRINTF(String_Format, 1);
-	return RuntimeScriptValue().SetDynamicObject(const_cast<char *>(CreateNewScriptString(scsf_buffer)), &myScriptStringImpl);
+	return RuntimeScriptValue().SetDynamicObject(const_cast<char *>(CreateNewScriptString(scsf_buffer)), &_GP(myScriptStringImpl));
 }
 
 // const char* (const char *thisString)
 RuntimeScriptValue Sc_String_LowerCase(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ(const char, const char, myScriptStringImpl, String_LowerCase);
+	API_CONST_OBJCALL_OBJ(const char, const char, _GP(myScriptStringImpl), String_LowerCase);
 }
 
 // const char* (const char *thisString, const char *lookForText, const char *replaceWithText, bool caseSensitive)
 RuntimeScriptValue Sc_String_Replace(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ_POBJ2_PBOOL(const char, const char, myScriptStringImpl, String_Replace, const char, const char);
+	API_CONST_OBJCALL_OBJ_POBJ2_PBOOL(const char, const char, _GP(myScriptStringImpl), String_Replace, const char, const char);
 }
 
 // const char* (const char *thisString, int index, char newChar)
 RuntimeScriptValue Sc_String_ReplaceCharAt(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ_PINT2(const char, const char, myScriptStringImpl, String_ReplaceCharAt);
+	API_CONST_OBJCALL_OBJ_PINT2(const char, const char, _GP(myScriptStringImpl), String_ReplaceCharAt);
 }
 
 // int (const char *thisString, const char *checkForString, bool caseSensitive)
@@ -365,17 +365,17 @@ RuntimeScriptValue Sc_String_StartsWith(void *self, const RuntimeScriptValue *pa
 
 // const char* (const char *thisString, int index, int length)
 RuntimeScriptValue Sc_String_Substring(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ_PINT2(const char, const char, myScriptStringImpl, String_Substring);
+	API_CONST_OBJCALL_OBJ_PINT2(const char, const char, _GP(myScriptStringImpl), String_Substring);
 }
 
 // const char* (const char *thisString, int length)
 RuntimeScriptValue Sc_String_Truncate(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ_PINT(const char, const char, myScriptStringImpl, String_Truncate);
+	API_CONST_OBJCALL_OBJ_PINT(const char, const char, _GP(myScriptStringImpl), String_Truncate);
 }
 
 // const char* (const char *thisString)
 RuntimeScriptValue Sc_String_UpperCase(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ(const char, const char, myScriptStringImpl, String_UpperCase);
+	API_CONST_OBJCALL_OBJ(const char, const char, _GP(myScriptStringImpl), String_UpperCase);
 }
 
 // FLOAT_RETURN_TYPE (const char *theString);
diff --git a/engines/ags/engine/ac/system.cpp b/engines/ags/engine/ac/system.cpp
index 85bf016897..8cb7e203c5 100644
--- a/engines/ags/engine/ac/system.cpp
+++ b/engines/ags/engine/ac/system.cpp
@@ -56,7 +56,7 @@ extern GameSetup usetup;
 extern ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1];
 extern ScriptSystem scsystem;
 extern IGraphicsDriver *gfxDriver;
-extern CCAudioChannel ccDynamicAudio;
+
 extern volatile bool switched_away;
 
 bool System_HasInputFocus() {
@@ -217,7 +217,7 @@ void System_SetRenderAtScreenResolution(int enable) {
 //
 //=============================================================================
 
-extern ScriptString myScriptStringImpl;
+
 
 // int ()
 RuntimeScriptValue Sc_System_GetAudioChannelCount(const RuntimeScriptValue *params, int32_t param_count) {
@@ -226,7 +226,7 @@ RuntimeScriptValue Sc_System_GetAudioChannelCount(const RuntimeScriptValue *para
 
 // ScriptAudioChannel* (int index)
 RuntimeScriptValue Sc_System_GetAudioChannels(const RuntimeScriptValue *params, int32_t param_count) {
-	API_SCALL_OBJ_PINT(ScriptAudioChannel, ccDynamicAudio, System_GetAudioChannels);
+	API_SCALL_OBJ_PINT(ScriptAudioChannel, _GP(ccDynamicAudio), System_GetAudioChannels);
 }
 
 // int ()
@@ -295,7 +295,7 @@ RuntimeScriptValue Sc_System_GetSupportsGammaControl(const RuntimeScriptValue *p
 
 // const char *()
 RuntimeScriptValue Sc_System_GetVersion(const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_SCALL_OBJ(const char, myScriptStringImpl, System_GetVersion);
+	API_CONST_SCALL_OBJ(const char, _GP(myScriptStringImpl), System_GetVersion);
 }
 
 // int ()
@@ -338,7 +338,7 @@ RuntimeScriptValue Sc_System_SetWindowed(const RuntimeScriptValue *params, int32
 
 // const char *()
 RuntimeScriptValue Sc_System_GetRuntimeInfo(const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_SCALL_OBJ(const char, myScriptStringImpl, System_GetRuntimeInfo);
+	API_CONST_SCALL_OBJ(const char, _GP(myScriptStringImpl), System_GetRuntimeInfo);
 }
 
 RuntimeScriptValue Sc_System_GetRenderAtScreenResolution(const RuntimeScriptValue *params, int32_t param_count) {
diff --git a/engines/ags/engine/ac/textbox.cpp b/engines/ags/engine/ac/textbox.cpp
index 674d7adbb6..b5b696c0a8 100644
--- a/engines/ags/engine/ac/textbox.cpp
+++ b/engines/ags/engine/ac/textbox.cpp
@@ -91,7 +91,7 @@ void TextBox_SetShowBorder(GUITextBox *guit, bool on) {
 //
 //=============================================================================
 
-extern ScriptString myScriptStringImpl;
+
 
 // void (GUITextBox *texbox, char *buffer)
 RuntimeScriptValue Sc_TextBox_GetText(void *self, const RuntimeScriptValue *params, int32_t param_count) {
@@ -124,7 +124,7 @@ RuntimeScriptValue Sc_TextBox_SetShowBorder(void *self, const RuntimeScriptValue
 
 // const char* (GUITextBox *texbox)
 RuntimeScriptValue Sc_TextBox_GetText_New(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_CONST_OBJCALL_OBJ(GUITextBox, const char, myScriptStringImpl, TextBox_GetText_New);
+	API_CONST_OBJCALL_OBJ(GUITextBox, const char, _GP(myScriptStringImpl), TextBox_GetText_New);
 }
 
 // int (GUITextBox *guit)
diff --git a/engines/ags/engine/ac/viewframe.cpp b/engines/ags/engine/ac/viewframe.cpp
index 144d395a56..b8ab24f882 100644
--- a/engines/ags/engine/ac/viewframe.cpp
+++ b/engines/ags/engine/ac/viewframe.cpp
@@ -42,27 +42,27 @@ using AGS::Shared::Bitmap;
 using AGS::Shared::Graphics;
 
 
-extern ViewStruct *views;
 
-extern CCAudioClip ccDynamicAudioClip;
+
+
 
 
 int ViewFrame_GetFlipped(ScriptViewFrame *svf) {
-	if (views[svf->view].loops[svf->loop].frames[svf->frame].flags & VFLG_FLIPSPRITE)
+	if (_G(views)[svf->view].loops[svf->loop].frames[svf->frame].flags & VFLG_FLIPSPRITE)
 		return 1;
 	return 0;
 }
 
 int ViewFrame_GetGraphic(ScriptViewFrame *svf) {
-	return views[svf->view].loops[svf->loop].frames[svf->frame].pic;
+	return _G(views)[svf->view].loops[svf->loop].frames[svf->frame].pic;
 }
 
 void ViewFrame_SetGraphic(ScriptViewFrame *svf, int newPic) {
-	views[svf->view].loops[svf->loop].frames[svf->frame].pic = newPic;
+	_G(views)[svf->view].loops[svf->loop].frames[svf->frame].pic = newPic;
 }
 
 ScriptAudioClip *ViewFrame_GetLinkedAudio(ScriptViewFrame *svf) {
-	int soundIndex = views[svf->view].loops[svf->loop].frames[svf->frame].sound;
+	int soundIndex = _G(views)[svf->view].loops[svf->loop].frames[svf->frame].sound;
 	if (soundIndex < 0)
 		return nullptr;
 
@@ -74,29 +74,29 @@ void ViewFrame_SetLinkedAudio(ScriptViewFrame *svf, ScriptAudioClip *clip) {
 	if (clip != nullptr)
 		newSoundIndex = clip->id;
 
-	views[svf->view].loops[svf->loop].frames[svf->frame].sound = newSoundIndex;
+	_G(views)[svf->view].loops[svf->loop].frames[svf->frame].sound = newSoundIndex;
 }
 
 int ViewFrame_GetSound(ScriptViewFrame *svf) {
 	// convert audio clip to old-style sound number
-	return get_old_style_number_for_sound(views[svf->view].loops[svf->loop].frames[svf->frame].sound);
+	return get_old_style_number_for_sound(_G(views)[svf->view].loops[svf->loop].frames[svf->frame].sound);
 }
 
 void ViewFrame_SetSound(ScriptViewFrame *svf, int newSound) {
 	if (newSound < 1) {
-		views[svf->view].loops[svf->loop].frames[svf->frame].sound = -1;
+		_G(views)[svf->view].loops[svf->loop].frames[svf->frame].sound = -1;
 	} else {
 		// convert sound number to audio clip
 		ScriptAudioClip *clip = GetAudioClipForOldStyleNumber(_GP(game), false, newSound);
 		if (clip == nullptr)
 			quitprintf("!SetFrameSound: audio clip aSound%d not found", newSound);
 
-		views[svf->view].loops[svf->loop].frames[svf->frame].sound = clip->id + (_GP(game).IsLegacyAudioSystem() ? 0x10000000 : 0);
+		_G(views)[svf->view].loops[svf->loop].frames[svf->frame].sound = clip->id + (_GP(game).IsLegacyAudioSystem() ? 0x10000000 : 0);
 	}
 }
 
 int ViewFrame_GetSpeed(ScriptViewFrame *svf) {
-	return views[svf->view].loops[svf->loop].frames[svf->frame].speed;
+	return _G(views)[svf->view].loops[svf->loop].frames[svf->frame].speed;
 }
 
 int ViewFrame_GetView(ScriptViewFrame *svf) {
@@ -117,9 +117,9 @@ void precache_view(int view) {
 	if (view < 0)
 		return;
 
-	for (int i = 0; i < views[view].numLoops; i++) {
-		for (int j = 0; j < views[view].loops[i].numFrames; j++)
-			_GP(spriteset).Precache(views[view].loops[i].frames[j].pic);
+	for (int i = 0; i < _G(views)[view].numLoops; i++) {
+		for (int j = 0; j < _G(views)[view].loops[i].numFrames; j++)
+			_GP(spriteset).Precache(_G(views)[view].loops[i].frames[j].pic);
 	}
 }
 
@@ -128,22 +128,22 @@ void precache_view(int view) {
 void CheckViewFrame(int view, int loop, int frame, int sound_volume) {
 	ScriptAudioChannel *channel = nullptr;
 	if (_GP(game).IsLegacyAudioSystem()) {
-		if (views[view].loops[loop].frames[frame].sound > 0) {
-			if (views[view].loops[loop].frames[frame].sound < 0x10000000) {
-				ScriptAudioClip *clip = GetAudioClipForOldStyleNumber(_GP(game), false, views[view].loops[loop].frames[frame].sound);
+		if (_G(views)[view].loops[loop].frames[frame].sound > 0) {
+			if (_G(views)[view].loops[loop].frames[frame].sound < 0x10000000) {
+				ScriptAudioClip *clip = GetAudioClipForOldStyleNumber(_GP(game), false, _G(views)[view].loops[loop].frames[frame].sound);
 				if (clip)
-					views[view].loops[loop].frames[frame].sound = clip->id + 0x10000000;
+					_G(views)[view].loops[loop].frames[frame].sound = clip->id + 0x10000000;
 				else {
-					views[view].loops[loop].frames[frame].sound = 0;
+					_G(views)[view].loops[loop].frames[frame].sound = 0;
 					return;
 				}
 			}
-			channel = play_audio_clip_by_index(views[view].loops[loop].frames[frame].sound - 0x10000000);
+			channel = play_audio_clip_by_index(_G(views)[view].loops[loop].frames[frame].sound - 0x10000000);
 		}
 	} else {
-		if (views[view].loops[loop].frames[frame].sound >= 0) {
+		if (_G(views)[view].loops[loop].frames[frame].sound >= 0) {
 			// play this sound (eg. footstep)
-			channel = play_audio_clip_by_index(views[view].loops[loop].frames[frame].sound);
+			channel = play_audio_clip_by_index(_G(views)[view].loops[loop].frames[frame].sound);
 		}
 	}
 	if (sound_volume != SCR_NO_VALUE && channel != nullptr) {
@@ -204,7 +204,7 @@ RuntimeScriptValue Sc_ViewFrame_SetGraphic(void *self, const RuntimeScriptValue
 
 // ScriptAudioClip* (ScriptViewFrame *svf)
 RuntimeScriptValue Sc_ViewFrame_GetLinkedAudio(void *self, const RuntimeScriptValue *params, int32_t param_count) {
-	API_OBJCALL_OBJ(ScriptViewFrame, ScriptAudioClip, ccDynamicAudioClip, ViewFrame_GetLinkedAudio);
+	API_OBJCALL_OBJ(ScriptViewFrame, ScriptAudioClip, _GP(ccDynamicAudioClip), ViewFrame_GetLinkedAudio);
 }
 
 // void (ScriptViewFrame *svf, ScriptAudioClip* clip)
diff --git a/engines/ags/engine/game/game_init.cpp b/engines/ags/engine/game/game_init.cpp
index be4d4dacc0..63206a0ada 100644
--- a/engines/ags/engine/game/game_init.cpp
+++ b/engines/ags/engine/game/game_init.cpp
@@ -57,33 +57,15 @@ namespace AGS3 {
 using namespace Shared;
 using namespace Engine;
 
-
 extern int actSpsCount;
 extern Bitmap **actsps;
 extern IDriverDependantBitmap **actspsbmp;
 extern Bitmap **actspswb;
 extern IDriverDependantBitmap **actspswbbmp;
 extern CachedActSpsData *actspswbcache;
-extern CharacterCache *charcache;
-
-extern CCGUIObject ccDynamicGUIObject;
-extern CCCharacter ccDynamicCharacter;
-extern CCHotspot   ccDynamicHotspot;
-extern CCRegion    ccDynamicRegion;
-extern CCInventory ccDynamicInv;
-extern CCGUI       ccDynamicGUI;
-extern CCObject    ccDynamicObject;
-extern CCDialog    ccDynamicDialog;
-extern CCAudioChannel ccDynamicAudio;
-extern CCAudioClip ccDynamicAudioClip;
-extern ScriptString myScriptStringImpl;
-extern ScriptObject scrObj[MAX_ROOM_OBJECTS];
-extern ScriptGUI *scrGui;
-extern ScriptHotspot scrHotspot[MAX_ROOM_HOTSPOTS];
-extern ScriptRegion scrRegion[MAX_ROOM_REGIONS];
-extern ScriptInvItem scrInv[MAX_INV];
-extern ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1];
 
+
+extern ScriptAudioChannel scrAudioChannel[MAX_SOUND_CHANNELS + 1];
 extern ScriptDialogOptionsRendering ccDialogOptionsRendering;
 extern ScriptDrawingSurface *dialogOptionsRenderingSurface;
 
@@ -141,7 +123,7 @@ String GetGameInitErrorText(GameInitErrorType err) {
 void InitAndRegisterAudioObjects() {
 	for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) {
 		scrAudioChannel[i].id = i;
-		ccRegisterManagedObject(&scrAudioChannel[i], &ccDynamicAudio);
+		ccRegisterManagedObject(&scrAudioChannel[i], &_GP(ccDynamicAudio));
 	}
 
 	for (size_t i = 0; i < _GP(game).audioClips.size(); ++i) {
@@ -149,8 +131,8 @@ void InitAndRegisterAudioObjects() {
 		// to actual item index in array, so we don't make any difference
 		// between game versions, for now.
 		_GP(game).audioClips[i].id = i;
-		ccRegisterManagedObject(&_GP(game).audioClips[i], &ccDynamicAudioClip);
-		ccAddExternalDynamicObject(_GP(game).audioClips[i].scriptName, &_GP(game).audioClips[i], &ccDynamicAudioClip);
+		ccRegisterManagedObject(&_GP(game).audioClips[i], &_GP(ccDynamicAudioClip));
+		ccAddExternalDynamicObject(_GP(game).audioClips[i].scriptName, &_GP(game).audioClips[i], &_GP(ccDynamicAudioClip));
 	}
 }
 
@@ -171,24 +153,24 @@ void InitAndRegisterCharacters() {
 		_GP(game).chars[i].loop = 0;
 		_GP(game).chars[i].frame = 0;
 		_GP(game).chars[i].walkwait = -1;
-		ccRegisterManagedObject(&_GP(game).chars[i], &ccDynamicCharacter);
+		ccRegisterManagedObject(&_GP(game).chars[i], &_GP(ccDynamicCharacter));
 
 		// export the character's script object
 		characterScriptObjNames[i] = _GP(game).chars[i].scrname;
-		ccAddExternalDynamicObject(characterScriptObjNames[i], &_GP(game).chars[i], &ccDynamicCharacter);
+		ccAddExternalDynamicObject(characterScriptObjNames[i], &_GP(game).chars[i], &_GP(ccDynamicCharacter));
 	}
 }
 
 // Initializes dialog and registers them in the script system
 void InitAndRegisterDialogs() {
-	scrDialog = new ScriptDialog[_GP(game).numdialog];
+	_G(scrDialog) = new ScriptDialog[_GP(game).numdialog];
 	for (int i = 0; i < _GP(game).numdialog; ++i) {
-		scrDialog[i].id = i;
-		scrDialog[i].reserved = 0;
-		ccRegisterManagedObject(&scrDialog[i], &ccDynamicDialog);
+		_G(scrDialog)[i].id = i;
+		_G(scrDialog)[i].reserved = 0;
+		ccRegisterManagedObject(&_G(scrDialog)[i], &_GP(ccDynamicDialog));
 
 		if (!_GP(game).dialogScriptNames[i].IsEmpty())
-			ccAddExternalDynamicObject(_GP(game).dialogScriptNames[i], &scrDialog[i], &ccDynamicDialog);
+			ccAddExternalDynamicObject(_GP(game).dialogScriptNames[i], &_G(scrDialog)[i], &_GP(ccDynamicDialog));
 	}
 }
 
@@ -204,25 +186,25 @@ void InitAndRegisterDialogOptions() {
 
 // Initializes gui and registers them in the script system
 HError InitAndRegisterGUI() {
-	scrGui = (ScriptGUI *)malloc(sizeof(ScriptGUI) * _GP(game).numgui);
+	_G(scrGui) = (ScriptGUI *)malloc(sizeof(ScriptGUI) * _GP(game).numgui);
 	for (int i = 0; i < _GP(game).numgui; ++i) {
-		scrGui[i].id = -1;
+		_G(scrGui)[i].id = -1;
 	}
 
 	guiScriptObjNames.resize(_GP(game).numgui);
 	for (int i = 0; i < _GP(game).numgui; ++i) {
 		// link controls to their parent guis
-		HError err = guis[i].RebuildArray();
+		HError err = _GP(guis)[i].RebuildArray();
 		if (!err)
 			return err;
 		// export all the GUI's controls
 		export_gui_controls(i);
 		// copy the script name to its own memory location
 		// because ccAddExtSymbol only keeps a reference
-		guiScriptObjNames[i] = guis[i].Name;
-		scrGui[i].id = i;
-		ccAddExternalDynamicObject(guiScriptObjNames[i], &scrGui[i], &ccDynamicGUI);
-		ccRegisterManagedObject(&scrGui[i], &ccDynamicGUI);
+		guiScriptObjNames[i] = _GP(guis)[i].Name;
+		_G(scrGui)[i].id = i;
+		ccAddExternalDynamicObject(guiScriptObjNames[i], &_G(scrGui)[i], &_GP(ccDynamicGUI));
+		ccRegisterManagedObject(&_G(scrGui)[i], &_GP(ccDynamicGUI));
 	}
 	return HError::None();
 }
@@ -230,57 +212,57 @@ HError InitAndRegisterGUI() {
 // Initializes inventory items and registers them in the script system
 void InitAndRegisterInvItems() {
 	for (int i = 0; i < MAX_INV; ++i) {
-		scrInv[i].id = i;
-		scrInv[i].reserved = 0;
-		ccRegisterManagedObject(&scrInv[i], &ccDynamicInv);
+		_G(scrInv)[i].id = i;
+		_G(scrInv)[i].reserved = 0;
+		ccRegisterManagedObject(&_G(scrInv)[i], &_GP(ccDynamicInv));
 
 		if (!_GP(game).invScriptNames[i].IsEmpty())
-			ccAddExternalDynamicObject(_GP(game).invScriptNames[i], &scrInv[i], &ccDynamicInv);
+			ccAddExternalDynamicObject(_GP(game).invScriptNames[i], &_G(scrInv)[i], &_GP(ccDynamicInv));
 	}
 }
 
 // Initializes room hotspots and registers them in the script system
 void InitAndRegisterHotspots() {
 	for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) {
-		scrHotspot[i].id = i;
-		scrHotspot[i].reserved = 0;
-		ccRegisterManagedObject(&scrHotspot[i], &ccDynamicHotspot);
+		_G(scrHotspot)[i].id = i;
+		_G(scrHotspot)[i].reserved = 0;
+		ccRegisterManagedObject(&_G(scrHotspot)[i], &_GP(ccDynamicHotspot));
 	}
 }
 
 // Initializes room objects and registers them in the script system
 void InitAndRegisterRoomObjects() {
 	for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) {
-		ccRegisterManagedObject(&scrObj[i], &ccDynamicObject);
+		ccRegisterManagedObject(&_G(scrObj)[i], &_GP(ccDynamicObject));
 	}
 }
 
 // Initializes room regions and registers them in the script system
 void InitAndRegisterRegions() {
 	for (int i = 0; i < MAX_ROOM_REGIONS; ++i) {
-		scrRegion[i].id = i;
-		scrRegion[i].reserved = 0;
-		ccRegisterManagedObject(&scrRegion[i], &ccDynamicRegion);
+		_G(scrRegion)[i].id = i;
+		_G(scrRegion)[i].reserved = 0;
+		ccRegisterManagedObject(&_G(scrRegion)[i], &_GP(ccDynamicRegion));
 	}
 }
 
 // Registers static entity arrays in the script system
 void RegisterStaticArrays() {
-	StaticCharacterArray.Create(&ccDynamicCharacter, sizeof(CharacterInfo), sizeof(CharacterInfo));
-	StaticObjectArray.Create(&ccDynamicObject, sizeof(ScriptObject), sizeof(ScriptObject));
-	StaticGUIArray.Create(&ccDynamicGUI, sizeof(ScriptGUI), sizeof(ScriptGUI));
-	StaticHotspotArray.Create(&ccDynamicHotspot, sizeof(ScriptHotspot), sizeof(ScriptHotspot));
-	StaticRegionArray.Create(&ccDynamicRegion, sizeof(ScriptRegion), sizeof(ScriptRegion));
-	StaticInventoryArray.Create(&ccDynamicInv, sizeof(ScriptInvItem), sizeof(ScriptInvItem));
-	StaticDialogArray.Create(&ccDynamicDialog, sizeof(ScriptDialog), sizeof(ScriptDialog));
+	StaticCharacterArray.Create(&_GP(ccDynamicCharacter), sizeof(CharacterInfo), sizeof(CharacterInfo));
+	StaticObjectArray.Create(&_GP(ccDynamicObject), sizeof(ScriptObject), sizeof(ScriptObject));
+	StaticGUIArray.Create(&_GP(ccDynamicGUI), sizeof(ScriptGUI), sizeof(ScriptGUI));
+	StaticHotspotArray.Create(&_GP(ccDynamicHotspot), sizeof(ScriptHotspot), sizeof(ScriptHotspot));
+	StaticRegionArray.Create(&_GP(ccDynamicRegion), sizeof(ScriptRegion), sizeof(ScriptRegion));
+	StaticInventoryArray.Create(&_GP(ccDynamicInv), sizeof(ScriptInvItem), sizeof(ScriptInvItem));
+	StaticDialogArray.Create(&_GP(ccDynamicDialog), sizeof(ScriptDialog), sizeof(ScriptDialog));
 
 	ccAddExternalStaticArray("character", &_GP(game).chars[0], &StaticCharacterArray);
-	ccAddExternalStaticArray("object", &scrObj[0], &StaticObjectArray);
-	ccAddExternalStaticArray("gui", &scrGui[0], &StaticGUIArray);
-	ccAddExternalStaticArray("hotspot", &scrHotspot[0], &StaticHotspotArray);
-	ccAddExternalStaticArray("region", &scrRegion[0], &StaticRegionArray);
-	ccAddExternalStaticArray("inventory", &scrInv[0], &StaticInventoryArray);
-	ccAddExternalStaticArray("dialog", &scrDialog[0], &StaticDialogArray);
+	ccAddExternalStaticArray("object", &_G(scrObj)[0], &StaticObjectArray);
+	ccAddExternalStaticArray("gui", &_G(scrGui)[0], &StaticGUIArray);
+	ccAddExternalStaticArray("hotspot", &_G(scrHotspot)[0], &StaticHotspotArray);
+	ccAddExternalStaticArray("region", &_G(scrRegion)[0], &StaticRegionArray);
+	ccAddExternalStaticArray("inventory", &_G(scrInv)[0], &StaticInventoryArray);
+	ccAddExternalStaticArray("dialog", &_G(scrDialog)[0], &StaticDialogArray);
 }
 
 // Initializes various game entities and registers them in the script system
@@ -379,8 +361,8 @@ HGameInitError InitGameState(const LoadedGameEntities &ents, GameDataVersion dat
 	// 3. Allocate and init game objects
 	//
 	charextra = (CharacterExtras *)calloc(_GP(game).numcharacters, sizeof(CharacterExtras));
-	charcache = (CharacterCache *)calloc(1, sizeof(CharacterCache) * _GP(game).numcharacters + 5);
-	mls = (MoveList *)calloc(_GP(game).numcharacters + MAX_ROOM_OBJECTS + 1, sizeof(MoveList));
+	_G(charcache) = (CharacterCache *)calloc(1, sizeof(CharacterCache) * _GP(game).numcharacters + 5);
+	_G(mls) = (MoveList *)calloc(_GP(game).numcharacters + MAX_ROOM_OBJECTS + 1, sizeof(MoveList));
 	actSpsCount = _GP(game).numcharacters + MAX_ROOM_OBJECTS + 2;
 	actsps = (Bitmap **)calloc(actSpsCount, sizeof(Bitmap *));
 	actspsbmp = (IDriverDependantBitmap **)calloc(actSpsCount, sizeof(IDriverDependantBitmap *));
@@ -426,7 +408,7 @@ HGameInitError InitGameState(const LoadedGameEntities &ents, GameDataVersion dat
 	// require access to script API at initialization time.
 	//
 	ccSetScriptAliveTimer(150000);
-	ccSetStringClassImpl(&myScriptStringImpl);
+	ccSetStringClassImpl(&_GP(myScriptStringImpl));
 	setup_script_exports(base_api, compat_api);
 
 	//
diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp
index a292e75aad..b55f5fc50f 100644
--- a/engines/ags/engine/game/savegame.cpp
+++ b/engines/ags/engine/game/savegame.cpp
@@ -603,7 +603,7 @@ HSaveError DoAfterRestore(const PreservedParams &pp, const RestoredData &r_data)
 	update_directional_sound_vol();
 
 	for (int i = 0; i < _GP(game).numgui; ++i) {
-		guibg[i] = BitmapHelper::CreateBitmap(guis[i].Width, guis[i].Height, _GP(game).GetColorDepth());
+		guibg[i] = BitmapHelper::CreateBitmap(_GP(guis)[i].Width, _GP(guis)[i].Height, _GP(game).GetColorDepth());
 		guibg[i] = ReplaceBitmapWithSupportedFormat(guibg[i]);
 	}
 
diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp
index 6764897ed2..b3da41f7c0 100644
--- a/engines/ags/engine/game/savegame_components.cpp
+++ b/engines/ags/engine/game/savegame_components.cpp
@@ -63,18 +63,13 @@ namespace AGS3 {
 
 using namespace Shared;
 
-
 extern color palette[256];
 extern DialogTopic *dialog;
 extern AnimatingGUIButton animbuts[MAX_ANIMATING_BUTTONS];
 extern int numAnimButs;
-extern ViewStruct *views;
-extern Bitmap *dynamicallyCreatedSurfaces[MAX_DYNAMIC_SURFACES];
-
 
+extern Bitmap *dynamicallyCreatedSurfaces[MAX_DYNAMIC_SURFACES];
 extern Bitmap *raw_saved_screen;
-extern MoveList *mls;
-
 
 namespace AGS {
 namespace Engine {
@@ -493,7 +488,7 @@ HSaveError WriteCharacters(PStream out) {
 		if (loaded_game_file_version <= kGameVersion_272)
 			WriteTimesRun272(*_GP(game).intrChar[i], out.get());
 		// character movement path cache
-		mls[CHMLSOFFS + i].WriteToFile(out.get());
+		_G(mls)[CHMLSOFFS + i].WriteToFile(out.get());
 	}
 	return HSaveError::None();
 }
@@ -509,7 +504,7 @@ HSaveError ReadCharacters(PStream in, int32_t cmp_ver, const PreservedParams &pp
 		if (loaded_game_file_version <= kGameVersion_272)
 			ReadTimesRun272(*_GP(game).intrChar[i], in.get());
 		// character movement path cache
-		err = mls[CHMLSOFFS + i].ReadFromFile(in.get(), cmp_ver > 0 ? 1 : 0);
+		err = _G(mls)[CHMLSOFFS + i].ReadFromFile(in.get(), cmp_ver > 0 ? 1 : 0);
 		if (!err)
 			return err;
 	}
@@ -539,7 +534,7 @@ HSaveError WriteGUI(PStream out) {
 	WriteFormatTag(out, "GUIs");
 	out->WriteInt32(_GP(game).numgui);
 	for (int i = 0; i < _GP(game).numgui; ++i)
-		guis[i].WriteToSavegame(out.get());
+		_GP(guis)[i].WriteToSavegame(out.get());
 
 	WriteFormatTag(out, "GUIButtons");
 	out->WriteInt32(numguibuts);
@@ -588,7 +583,7 @@ HSaveError ReadGUI(PStream in, int32_t cmp_ver, const PreservedParams &pp, Resto
 	if (!AssertGameContent(err, in->ReadInt32(), _GP(game).numgui, "GUIs"))
 		return err;
 	for (int i = 0; i < _GP(game).numgui; ++i)
-		guis[i].ReadFromSavegame(in.get(), svg_ver);
+		_GP(guis)[i].ReadFromSavegame(in.get(), svg_ver);
 
 	if (!AssertFormatTagStrict(err, in, "GUIButtons"))
 		return err;
@@ -689,12 +684,12 @@ HSaveError ReadMouseCursors(PStream in, int32_t cmp_ver, const PreservedParams &
 HSaveError WriteViews(PStream out) {
 	out->WriteInt32(_GP(game).numviews);
 	for (int view = 0; view < _GP(game).numviews; ++view) {
-		out->WriteInt32(views[view].numLoops);
-		for (int loop = 0; loop < views[view].numLoops; ++loop) {
-			out->WriteInt32(views[view].loops[loop].numFrames);
-			for (int frame = 0; frame < views[view].loops[loop].numFrames; ++frame) {
-				out->WriteInt32(views[view].loops[loop].frames[frame].sound);
-				out->WriteInt32(views[view].loops[loop].frames[frame].pic);
+		out->WriteInt32(_G(views)[view].numLoops);
+		for (int loop = 0; loop < _G(views)[view].numLoops; ++loop) {
+			out->WriteInt32(_G(views)[view].loops[loop].numFrames);
+			for (int frame = 0; frame < _G(views)[view].loops[loop].numFrames; ++frame) {
+				out->WriteInt32(_G(views)[view].loops[loop].frames[frame].sound);
+				out->WriteInt32(_G(views)[view].loops[loop].frames[frame].pic);
 			}
 		}
 	}
@@ -706,16 +701,16 @@ HSaveError ReadViews(PStream in, int32_t cmp_ver, const PreservedParams &pp, Res
 	if (!AssertGameContent(err, in->ReadInt32(), _GP(game).numviews, "Views"))
 		return err;
 	for (int view = 0; view < _GP(game).numviews; ++view) {
-		if (!AssertGameObjectContent(err, in->ReadInt32(), views[view].numLoops,
+		if (!AssertGameObjectContent(err, in->ReadInt32(), _G(views)[view].numLoops,
 		                             "Loops", "View", view))
 			return err;
-		for (int loop = 0; loop < views[view].numLoops; ++loop) {
-			if (!AssertGameObjectContent2(err, in->ReadInt32(), views[view].loops[loop].numFrames,
+		for (int loop = 0; loop < _G(views)[view].numLoops; ++loop) {
+			if (!AssertGameObjectContent2(err, in->ReadInt32(), _G(views)[view].loops[loop].numFrames,
 			                              "Frame", "View", view, "Loop", loop))
 				return err;
-			for (int frame = 0; frame < views[view].loops[loop].numFrames; ++frame) {
-				views[view].loops[loop].frames[frame].sound = in->ReadInt32();
-				views[view].loops[loop].frames[frame].pic = in->ReadInt32();
+			for (int frame = 0; frame < _G(views)[view].loops[loop].numFrames; ++frame) {
+				_G(views)[view].loops[loop].frames[frame].sound = in->ReadInt32();
+				_G(views)[view].loops[loop].frames[frame].pic = in->ReadInt32();
 			}
 		}
 	}
@@ -919,7 +914,7 @@ HSaveError WriteThisRoom(PStream out) {
 	// room object movement paths cache
 	out->WriteInt32(_GP(thisroom).ObjectCount + 1);
 	for (size_t i = 0; i < _GP(thisroom).ObjectCount + 1; ++i) {
-		mls[i].WriteToFile(out.get());
+		_G(mls)[i].WriteToFile(out.get());
 	}
 
 	// room music volume
@@ -966,7 +961,7 @@ HSaveError ReadThisRoom(PStream in, int32_t cmp_ver, const PreservedParams &pp,
 	if (!AssertCompatLimit(err, objmls_count, CHMLSOFFS, "room object move lists"))
 		return err;
 	for (int i = 0; i < objmls_count; ++i) {
-		err = mls[i].ReadFromFile(in.get(), cmp_ver > 0 ? 1 : 0);
+		err = _G(mls)[i].ReadFromFile(in.get(), cmp_ver > 0 ? 1 : 0);
 		if (!err)
 			return err;
 	}
diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp
index a0d19b27cf..b7f39d8adb 100644
--- a/engines/ags/engine/main/engine.cpp
+++ b/engines/ags/engine/main/engine.cpp
@@ -89,8 +89,8 @@ extern GameSetup usetup;
 extern int proper_exit;
 extern char pexbuf[STD_BUFFER_SIZE];
 
-extern ObjectCache objcache[MAX_ROOM_OBJECTS];
-extern ScriptObject scrObj[MAX_ROOM_OBJECTS];
+
+
 extern int displayed_room;
 extern int eip_guinum;
 extern int eip_guiobj;
@@ -104,7 +104,7 @@ extern CharacterExtras *charextra;
 extern CharacterInfo *playerchar;
 extern Bitmap **guibg;
 extern IDriverDependantBitmap **guibgbmp;
-extern ViewStruct *views;
+
 ResourcePaths ResPaths;
 
 t_engine_pre_init_callback engine_pre_init_callback = nullptr;
@@ -676,7 +676,7 @@ void engine_init_game_settings() {
 		precache_view(playerchar->view);
 
 	for (ee = 0; ee < MAX_ROOM_OBJECTS; ee++)
-		objcache[ee].image = nullptr;
+		_G(objcache)[ee].image = nullptr;
 
 	/*  dummygui.guiId = -1;
 	dummyguicontrol.guin = -1;
@@ -687,9 +687,9 @@ void engine_init_game_settings() {
 	//init_language_text(_GP(game).langcodes[0]);
 
 	for (ee = 0; ee < MAX_ROOM_OBJECTS; ee++) {
-		scrObj[ee].id = ee;
+		_G(scrObj)[ee].id = ee;
 		// 64 bit: Using the id instead
-		// scrObj[ee].obj = NULL;
+		// _G(scrObj)[ee].obj = NULL;
 	}
 
 	for (ee = 0; ee < _GP(game).numcharacters; ee++) {
@@ -709,7 +709,7 @@ void engine_init_game_settings() {
 			// set initial loop to 0
 			_GP(game).chars[ee].loop = 0;
 			// or to 1 if they don't have up/down frames
-			if (views[_GP(game).chars[ee].view].loops[0].numFrames < 1)
+			if (_G(views)[_GP(game).chars[ee].view].loops[0].numFrames < 1)
 				_GP(game).chars[ee].loop = 1;
 		}
 		charextra[ee].process_idle_this_time = 0;
diff --git a/engines/ags/engine/main/engine_setup.cpp b/engines/ags/engine/main/engine_setup.cpp
index f375549365..55c221a50a 100644
--- a/engines/ags/engine/main/engine_setup.cpp
+++ b/engines/ags/engine/main/engine_setup.cpp
@@ -75,7 +75,7 @@ void convert_gui_to_game_resolution(GameDataVersion filever) {
 	}
 
 	for (int i = 0; i < _GP(game).numgui; ++i) {
-		GUIMain *cgp = &guis[i];
+		GUIMain *cgp = &_GP(guis)[i];
 		cgp->X *= mul;
 		cgp->Y *= mul;
 		if (cgp->Width < 1)
diff --git a/engines/ags/engine/main/game_file.cpp b/engines/ags/engine/main/game_file.cpp
index e6ae7bcf56..c17a88e3af 100644
--- a/engines/ags/engine/main/game_file.cpp
+++ b/engines/ags/engine/main/game_file.cpp
@@ -62,7 +62,7 @@ using namespace AGS::Engine;
 extern int ifacepopped;
 
 
-extern ViewStruct *views;
+
 extern DialogTopic *dialog;
 
 extern AGSPlatformDriver *platform;
@@ -139,7 +139,7 @@ HError preload_game_data() {
 
 HError load_game_file() {
 	MainGameSource src;
-	LoadedGameEntities ents(_GP(game), dialog, views);
+	LoadedGameEntities ents(_GP(game), dialog, _G(views));
 	HGameFileError load_err = OpenMainGameFileFromDefaultAsset(src);
 	if (load_err) {
 		load_err = ReadGameData(ents, src.InputStream.get(), src.DataVersion);
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index f31d3badcb..956ca7a40a 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -226,7 +226,7 @@ static void check_mouse_controls() {
 	mongu = gui_on_mouse_move();
 
 	mouse_on_iface = mongu;
-	if ((ifacepopped >= 0) && (_G(mousey) >= guis[ifacepopped].Y + guis[ifacepopped].Height))
+	if ((ifacepopped >= 0) && (_G(mousey) >= _GP(guis)[ifacepopped].Y + _GP(guis)[ifacepopped].Height))
 		remove_popup_interface(ifacepopped);
 
 	// check mouse clicks on GUIs
@@ -498,7 +498,7 @@ static void check_keyboard_controls() {
 	if ((((kgn >= 32) && (kgn <= 255) && (kgn != '[')) || (kgn == eAGSKeyCodeReturn) || (kgn == eAGSKeyCodeBackspace))
 		&& !all_buttons_disabled) {
 		for (int guiIndex = 0; guiIndex < _GP(game).numgui; guiIndex++) {
-			auto &gui = guis[guiIndex];
+			auto &gui = _GP(guis)[guiIndex];
 
 			if (!gui.IsDisplayed()) continue;
 
diff --git a/engines/ags/engine/main/update.cpp b/engines/ags/engine/main/update.cpp
index 739a690470..dba14f843c 100644
--- a/engines/ags/engine/main/update.cpp
+++ b/engines/ags/engine/main/update.cpp
@@ -54,12 +54,12 @@ namespace AGS3 {
 using namespace AGS::Shared;
 using namespace AGS::Engine;
 
-extern MoveList *mls;
+
 extern RoomStatus *croom;
 
 
 extern RoomObject *objs;
-extern ViewStruct *views;
+
 extern int our_eip;
 extern CharacterInfo *playerchar;
 extern CharacterExtras *charextra;
@@ -77,7 +77,7 @@ int do_movelist_move(int16_t *mlnum, int32_t *xx, int32_t *yy) {
 	int need_to_fix_sprite = 0;
 	if (mlnum[0] < 1) quit("movelist_move: attempted to move on a non-exist movelist");
 	MoveList *cmls;
-	cmls = &mls[mlnum[0]];
+	cmls = &_G(mls)[mlnum[0]];
 	fixed xpermove = cmls->xpermove[cmls->onstage], ypermove = cmls->ypermove[cmls->onstage];
 
 	short targetx = short((cmls->pos[cmls->onstage + 1] >> 16) & 0x00ffff);
@@ -315,12 +315,12 @@ void update_sierra_speech() {
 				}
 			} else if (facetalkchar->blinktimer < 0) {
 				// currently playing blink anim
-				if (facetalkchar->blinktimer < ((0 - 6) - views[facetalkchar->blinkview].loops[facetalkBlinkLoop].frames[facetalkchar->blinkframe].speed)) {
+				if (facetalkchar->blinktimer < ((0 - 6) - _G(views)[facetalkchar->blinkview].loops[facetalkBlinkLoop].frames[facetalkchar->blinkframe].speed)) {
 					// time to advance to next frame
 					facetalkchar->blinktimer = -1;
 					facetalkchar->blinkframe++;
 					updatedFrame = 2;
-					if (facetalkchar->blinkframe >= views[facetalkchar->blinkview].loops[facetalkBlinkLoop].numFrames) {
+					if (facetalkchar->blinkframe >= _G(views)[facetalkchar->blinkview].loops[facetalkBlinkLoop].numFrames) {
 						facetalkchar->blinkframe = 0;
 						facetalkchar->blinktimer = facetalkchar->blinkinterval;
 					}
@@ -343,7 +343,7 @@ void update_sierra_speech() {
 					else
 						facetalkframe = splipsync[curLipLine].frame[curLipLinePhoneme];
 
-					if (facetalkframe >= views[facetalkview].loops[facetalkloop].numFrames)
+					if (facetalkframe >= _G(views)[facetalkview].loops[facetalkloop].numFrames)
 						facetalkframe = 0;
 
 					updatedFrame |= 1;
@@ -375,11 +375,11 @@ void update_sierra_speech() {
 			} else {
 				// normal non-lip-sync
 				facetalkframe++;
-				if ((facetalkframe >= views[facetalkview].loops[facetalkloop].numFrames) ||
+				if ((facetalkframe >= _G(views)[facetalkview].loops[facetalkloop].numFrames) ||
 					(!_GP(play).speech_has_voice && (_GP(play).messagetime < 1) && (_GP(play).close_mouth_speech_time > 0))) {
 
-					if ((facetalkframe >= views[facetalkview].loops[facetalkloop].numFrames) &&
-						(views[facetalkview].loops[facetalkloop].RunNextLoop())) {
+					if ((facetalkframe >= _G(views)[facetalkview].loops[facetalkloop].numFrames) &&
+						(_G(views)[facetalkview].loops[facetalkloop].RunNextLoop())) {
 						facetalkloop++;
 					} else {
 						facetalkloop = 0;
@@ -389,7 +389,7 @@ void update_sierra_speech() {
 						facetalkwait = 999999;
 				}
 				if ((facetalkframe != 0) || (facetalkrepeat == 1))
-					facetalkwait = views[facetalkview].loops[facetalkloop].frames[facetalkframe].speed + GetCharacterSpeechAnimationDelay(facetalkchar);
+					facetalkwait = _G(views)[facetalkview].loops[facetalkloop].frames[facetalkframe].speed + GetCharacterSpeechAnimationDelay(facetalkchar);
 			}
 			updatedFrame |= 1;
 		}
@@ -402,7 +402,7 @@ void update_sierra_speech() {
 			if (updatedFrame & 2)
 				CheckViewFrame(facetalkchar->blinkview, facetalkBlinkLoop, facetalkchar->blinkframe);
 
-			int thisPic = views[facetalkview].loops[facetalkloop].frames[facetalkframe].pic;
+			int thisPic = _G(views)[facetalkview].loops[facetalkloop].frames[facetalkframe].pic;
 			int view_frame_x = 0;
 			int view_frame_y = 0;
 
@@ -422,12 +422,12 @@ void update_sierra_speech() {
 			}
 
 			Bitmap *frame_pic = screenover[face_talking].pic;
-			const ViewFrame *face_vf = &views[facetalkview].loops[facetalkloop].frames[facetalkframe];
+			const ViewFrame *face_vf = &_G(views)[facetalkview].loops[facetalkloop].frames[facetalkframe];
 			bool face_has_alpha = (_GP(game).SpriteInfos[face_vf->pic].Flags & SPF_ALPHACHANNEL) != 0;
 			DrawViewFrame(frame_pic, face_vf, view_frame_x, view_frame_y);
 
 			if ((facetalkchar->blinkview > 0) && (facetalkchar->blinktimer < 0)) {
-				ViewFrame *blink_vf = &views[facetalkchar->blinkview].loops[facetalkBlinkLoop].frames[facetalkchar->blinkframe];
+				ViewFrame *blink_vf = &_G(views)[facetalkchar->blinkview].loops[facetalkBlinkLoop].frames[facetalkchar->blinkframe];
 				face_has_alpha |= (_GP(game).SpriteInfos[blink_vf->pic].Flags & SPF_ALPHACHANNEL) != 0;
 				// draw the blinking sprite on top
 				DrawViewFrame(frame_pic, blink_vf, view_frame_x, view_frame_y, face_has_alpha);
diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp
index 0d894775b1..3d8fb64f43 100644
--- a/engines/ags/engine/script/cc_instance.cpp
+++ b/engines/ags/engine/script/cc_instance.cpp
@@ -56,7 +56,7 @@ extern ExecutingScript *curscript; // in script/script
 extern int maxWhileLoops;
 extern new_line_hook_type new_line_hook;
 
-extern ScriptString myScriptStringImpl;
+
 
 enum ScriptOpArgIsReg {
 	kScOpNoArgIsReg     = 0,
@@ -1177,7 +1177,7 @@ int ccInstance::Run(int32_t curpc) {
 			direct_ptr1 = (const char *)reg1.GetDirectPtr();
 			reg1.SetDynamicObject(
 			    stringClassImpl->CreateString(direct_ptr1).second,
-			    &myScriptStringImpl);
+			    &_GP(myScriptStringImpl));
 			break;
 		case SCMD_STRINGSEQUAL:
 			if ((reg1.IsNull()) || (reg2.IsNull())) {
diff --git a/engines/ags/globals.cpp b/engines/ags/globals.cpp
index 0c6890bded..9124a98b74 100644
--- a/engines/ags/globals.cpp
+++ b/engines/ags/globals.cpp
@@ -26,6 +26,22 @@
 #include "ags/shared/game/roomstruct.h"
 #include "ags/engine/ac/gamestate.h"
 #include "ags/engine/ac/roomstatus.h"
+#include "ags/engine/ac/dynobj/cc_dialog.h"
+#include "ags/engine/ac/dynobj/cc_guiobject.h"
+#include "ags/engine/ac/dynobj/cc_character.h"
+#include "ags/engine/ac/dynobj/cc_hotspot.h"
+#include "ags/engine/ac/dynobj/cc_region.h"
+#include "ags/engine/ac/dynobj/cc_inventory.h"
+#include "ags/engine/ac/dynobj/cc_gui.h"
+#include "ags/engine/ac/dynobj/cc_object.h"
+#include "ags/engine/ac/dynobj/cc_audiochannel.h"
+#include "ags/engine/ac/dynobj/cc_audioclip.h"
+#include "ags/engine/ac/objectcache.h"
+#include "ags/engine/ac/dynobj/scripthotspot.h"
+#include "ags/engine/ac/dynobj/scriptinvitem.h"
+#include "ags/engine/ac/dynobj/scriptobject.h"
+#include "ags/engine/ac/dynobj/scriptregion.h"
+#include "ags/engine/ac/dynobj/scriptstring.h"
 
 namespace AGS3 {
 
@@ -36,15 +52,46 @@ Globals::Globals() {
 
 	Common::fill(&_mousecurs[0], &_mousecurs[MAXCURSORS], nullptr);
 
+	// game.cpp globals
+	_ccDynamicGUIObject = new CCGUIObject();
+	_ccDynamicCharacter = new CCCharacter();
+	_ccDynamicHotspot = new CCHotspot();
+	_ccDynamicRegion = new CCRegion();
+	_ccDynamicInv = new CCInventory();
+	_ccDynamicGUI = new CCGUI();
+	_ccDynamicObject = new CCObject();
+	_ccDynamicDialog = new CCDialog();
+	_ccDynamicAudioClip = new CCAudioClip();
+	_ccDynamicAudio = new CCAudioChannel();
+	_myScriptStringImpl = new ScriptString();
+	_guis = new std::vector<AGS::Shared::GUIMain>();
 	_play = new GameState();
 	_game = new GameSetupStruct();
 	_spriteset = new SpriteCache(_game->SpriteInfos);
 	_thisroom = new AGS::Shared::RoomStruct();
 	_troom = new RoomStatus();
+	_scrObj = new ScriptObject[MAX_ROOM_OBJECTS];
+	_scrHotspot = new ScriptHotspot[MAX_ROOM_HOTSPOTS];
+	_scrRegion = new ScriptRegion[MAX_ROOM_REGIONS];
+	_scrInv = new ScriptInvItem[MAX_INV];
+	_objcache = new ObjectCache[MAX_ROOM_OBJECTS];
 }
 
 Globals::~Globals() {
 	g_globals = nullptr;
+
+	delete _ccDynamicGUIObject;
+	delete _ccDynamicCharacter;
+	delete _ccDynamicHotspot;
+	delete _ccDynamicRegion;
+	delete _ccDynamicInv;
+	delete _ccDynamicGUI;
+	delete _ccDynamicObject;
+	delete _ccDynamicDialog;
+	delete _ccDynamicAudioClip;
+	delete _ccDynamicAudio;
+	delete _myScriptStringImpl;
+	delete _guis;
 	delete _game;
 	delete _play;
 	delete _spriteset;
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index 3bd6cb75df..476ab13f61 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -25,6 +25,7 @@
 
 #include "ags/shared/util/string.h"
 #include "ags/shared/util/version.h"
+#include "ags/shared/gui/guimain.h"
 #include "ags/lib/std/set.h"
 
 namespace AGS3 {
@@ -41,10 +42,32 @@ class RoomStruct;
 } // namespace Shared
 } // namespace AGS
 
+struct CCAudioChannel;
+struct CCAudioClip;
+struct CCCharacter;
+struct CCDialog;
+struct CCGUI;
+struct CCGUIObject;
+struct CCHotspot;
+struct CCInventory;
+struct CCObject;
+struct CCRegion;
 struct IAGSEditorDebugger;
 struct GameSetupStruct;
 struct GameState;
 struct RoomStatus;
+struct ScriptString;
+struct ScriptObject;
+struct ScriptGUI;
+struct ScriptHotspot;
+struct ScriptRegion;
+struct ScriptInvItem;
+struct ScriptDialog;
+struct ViewStruct;
+struct CharacterCache;
+struct ObjectCache;
+struct MoveList;
+
 class SpriteCache;
 
 class Globals {
@@ -85,6 +108,35 @@ public:
 	AGS::Shared::RoomStruct *_thisroom;
 	RoomStatus *_troom; // used for non-saveable rooms, eg. intro
 
+	std::vector<AGS::Shared::GUIMain> *_guis;
+	CCGUIObject *_ccDynamicGUIObject;
+	CCCharacter *_ccDynamicCharacter;
+	CCHotspot *_ccDynamicHotspot;
+	CCRegion *_ccDynamicRegion;
+	CCInventory *_ccDynamicInv;
+	CCGUI *_ccDynamicGUI;
+	CCObject *_ccDynamicObject;
+	CCDialog *_ccDynamicDialog;
+	CCAudioClip *_ccDynamicAudioClip;
+	CCAudioChannel *_ccDynamicAudio;
+	ScriptString *_myScriptStringImpl;
+
+	// TODO: IMPORTANT!!
+	// we cannot simply replace these arrays with vectors, or other C++ containers,
+	// until we implement safe management of such containers in script exports
+	// system. Noteably we would need an alternate to StaticArray class to track
+	// access to their elements.
+	ScriptObject *_scrObj;
+	ScriptGUI *_scrGui = nullptr;
+	ScriptHotspot *_scrHotspot;
+	ScriptRegion *_scrRegion;
+	ScriptInvItem *_scrInv;
+	ScriptDialog *_scrDialog = nullptr;
+	ViewStruct *_views = nullptr;
+	CharacterCache *_charcache = nullptr;
+	ObjectCache *_objcache;
+	MoveList *_mls = nullptr;
+
 	 /**@}*/
 
 	/**
diff --git a/engines/ags/plugins/agsplugin.cpp b/engines/ags/plugins/agsplugin.cpp
index 1da80d0632..9dba73ecb4 100644
--- a/engines/ags/plugins/agsplugin.cpp
+++ b/engines/ags/plugins/agsplugin.cpp
@@ -92,19 +92,19 @@ extern int displayed_room;
 
 extern RoomStatus *croom;
 
-extern ViewStruct *views;
+
 extern int game_paused;
 extern GameSetup usetup;
 extern int inside_script;
 extern ccInstance *gameinst, *roominst;
-extern CharacterCache *charcache;
-extern ObjectCache objcache[MAX_ROOM_OBJECTS];
-extern MoveList *mls;
+
+
+
 extern color palette[256];
 extern PluginObjectReader pluginReaders[MAX_PLUGIN_OBJECT_READERS];
 extern int numPluginReaders;
 extern RuntimeScriptValue GlobalReturnValue;
-extern ScriptString myScriptStringImpl;
+
 
 // **************** PLUGIN IMPLEMENTATION ****************
 
@@ -503,12 +503,12 @@ AGSViewFrame *IAGSEngine::GetViewFrame(int32 view, int32 loop, int32 frame) {
 	view--;
 	if ((view < 0) || (view >= _GP(game).numviews))
 		quit("!IAGSEngine::GetViewFrame: invalid view");
-	if ((loop < 0) || (loop >= views[view].numLoops))
+	if ((loop < 0) || (loop >= _G(views)[view].numLoops))
 		quit("!IAGSEngine::GetViewFrame: invalid loop");
-	if ((frame < 0) || (frame >= views[view].loops[loop].numFrames))
+	if ((frame < 0) || (frame >= _G(views)[view].loops[loop].numFrames))
 		return nullptr;
 
-	return (AGSViewFrame *)&views[view].loops[loop].frames[frame];
+	return (AGSViewFrame *)&_G(views)[view].loops[loop].frames[frame];
 }
 
 int IAGSEngine::GetRawPixelColor(int32 color) {
@@ -693,18 +693,18 @@ void IAGSEngine::NotifySpriteUpdated(int32 slot) {
 	int ff;
 	// wipe the character cache when we change rooms
 	for (ff = 0; ff < _GP(game).numcharacters; ff++) {
-		if ((charcache[ff].inUse) && (charcache[ff].sppic == slot)) {
-			delete charcache[ff].image;
-			charcache[ff].image = nullptr;
-			charcache[ff].inUse = 0;
+		if ((_G(charcache)[ff].inUse) && (_G(charcache)[ff].sppic == slot)) {
+			delete _G(charcache)[ff].image;
+			_G(charcache)[ff].image = nullptr;
+			_G(charcache)[ff].inUse = 0;
 		}
 	}
 
 	// clear the object cache
 	for (ff = 0; ff < MAX_ROOM_OBJECTS; ff++) {
-		if ((objcache[ff].image != nullptr) && (objcache[ff].sppic == slot)) {
-			delete objcache[ff].image;
-			objcache[ff].image = nullptr;
+		if ((_G(objcache)[ff].image != nullptr) && (_G(objcache)[ff].sppic == slot)) {
+			delete _G(objcache)[ff].image;
+			_G(objcache)[ff].image = nullptr;
 		}
 	}
 }
@@ -779,7 +779,7 @@ const char *IAGSEngine::CreateScriptString(const char *fromText) {
 	const char *string = CreateNewScriptString(fromText);
 	// Should be still standard dynamic object, because not managed by plugin
 	// TODO: handle loss of const better
-	GlobalReturnValue.SetDynamicObject(const_cast<char *>(string), &myScriptStringImpl);
+	GlobalReturnValue.SetDynamicObject(const_cast<char *>(string), &_GP(myScriptStringImpl));
 	return string;
 }
 
@@ -801,21 +801,21 @@ void IAGSEngine::SimulateMouseClick(int32 button) {
 }
 
 int IAGSEngine::GetMovementPathWaypointCount(int32 pathId) {
-	return mls[pathId % TURNING_AROUND].numstage;
+	return _G(mls)[pathId % TURNING_AROUND].numstage;
 }
 
 int IAGSEngine::GetMovementPathLastWaypoint(int32 pathId) {
-	return mls[pathId % TURNING_AROUND].onstage;
+	return _G(mls)[pathId % TURNING_AROUND].onstage;
 }
 
 void IAGSEngine::GetMovementPathWaypointLocation(int32 pathId, int32 waypoint, int32 *x, int32 *y) {
-	*x = (mls[pathId % TURNING_AROUND].pos[waypoint] >> 16) & 0x0000ffff;
-	*y = (mls[pathId % TURNING_AROUND].pos[waypoint] & 0x0000ffff);
+	*x = (_G(mls)[pathId % TURNING_AROUND].pos[waypoint] >> 16) & 0x0000ffff;
+	*y = (_G(mls)[pathId % TURNING_AROUND].pos[waypoint] & 0x0000ffff);
 }
 
 void IAGSEngine::GetMovementPathWaypointSpeed(int32 pathId, int32 waypoint, int32 *xSpeed, int32 *ySpeed) {
-	*xSpeed = mls[pathId % TURNING_AROUND].xpermove[waypoint];
-	*ySpeed = mls[pathId % TURNING_AROUND].ypermove[waypoint];
+	*xSpeed = _G(mls)[pathId % TURNING_AROUND].xpermove[waypoint];
+	*ySpeed = _G(mls)[pathId % TURNING_AROUND].ypermove[waypoint];
 }
 
 int IAGSEngine::IsRunningUnderDebugger() {
diff --git a/engines/ags/shared/game/main_game_file.cpp b/engines/ags/shared/game/main_game_file.cpp
index 8fe501c4ed..08b901038b 100644
--- a/engines/ags/shared/game/main_game_file.cpp
+++ b/engines/ags/shared/game/main_game_file.cpp
@@ -219,7 +219,7 @@ void ReadViews(GameSetupStruct &game, ViewStruct *&views, Stream *in, GameDataVe
 	views = (ViewStruct *)calloc(sizeof(ViewStruct) * count, 1);
 	if (data_ver > kGameVersion_272) { // 3.x views
 		for (int i = 0; i < _GP(game).numviews; ++i) {
-			views[i].ReadFromFile(in);
+			_G(views)[i].ReadFromFile(in);
 		}
 	} else { // 2.x views
 		std::vector<ViewStruct272> oldv;
@@ -694,10 +694,10 @@ HGameFileError ReadGameData(LoadedGameEntities &ents, Stream *in, GameDataVersio
 
 	ReadDialogs(ents.Dialogs, ents.OldDialogScripts, ents.OldDialogSources, ents.OldSpeechLines,
 		in, data_ver, _GP(game).numdialog);
-	HError err2 = GUI::ReadGUI(guis, in);
+	HError err2 = GUI::ReadGUI(_GP(guis), in);
 	if (!err2)
 		return new MainGameFileError(kMGFErr_GameEntityFailed, err2);
-	_GP(game).numgui = guis.size();
+	_GP(game).numgui = _GP(guis).size();
 
 	if (data_ver >= kGameVersion_260) {
 		err = ReadPlugins(ents.PluginInfos, in);
diff --git a/engines/ags/shared/gui/guimain.h b/engines/ags/shared/gui/guimain.h
index 2e56d313ce..301f1aa092 100644
--- a/engines/ags/shared/gui/guimain.h
+++ b/engines/ags/shared/gui/guimain.h
@@ -218,7 +218,7 @@ void ApplyLegacyVisibility(GUIMain &gui, LegacyGUIVisState vis);
 } // namespace Shared
 } // namespace AGS
 
-extern std::vector<Shared::GUIMain> guis;
+
 extern int all_buttons_disabled, gui_inv_pic;
 extern int gui_disabled_style;
 


Commit: 0ef2ac659b71efc36e8ab55ee675cd40ad687d5f
    https://github.com/scummvm/scummvm/commit/0ef2ac659b71efc36e8ab55ee675cd40ad687d5f
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2021-02-28T13:27:21-08:00

Commit Message:
AGS: Move DbgMgr to Globals

Changed paths:
    engines/ags/engine/debugging/debug.cpp
    engines/ags/engine/debugging/messagebuffer.cpp
    engines/ags/globals.cpp
    engines/ags/globals.h
    engines/ags/shared/debugging/debugmanager.cpp
    engines/ags/shared/debugging/debugmanager.h


diff --git a/engines/ags/engine/debugging/debug.cpp b/engines/ags/engine/debugging/debug.cpp
index aaf85ed7b2..b83e60503e 100644
--- a/engines/ags/engine/debugging/debug.cpp
+++ b/engines/ags/engine/debugging/debug.cpp
@@ -102,18 +102,18 @@ const String OutputGameConsoleID = "console";
 PDebugOutput create_log_output(const String &name, const String &path = "", LogFile::OpenMode open_mode = LogFile::kLogFile_Overwrite) {
 	// Else create new one, if we know this ID
 	if (name.CompareNoCase(OutputSystemID) == 0) {
-		return DbgMgr.RegisterOutput(OutputSystemID, AGSPlatformDriver::GetDriver(), kDbgMsg_None);
+		return _GP(DbgMgr).RegisterOutput(OutputSystemID, AGSPlatformDriver::GetDriver(), kDbgMsg_None);
 	} else if (name.CompareNoCase(OutputFileID) == 0) {
 		DebugLogFile.reset(new LogFile());
 		String logfile_path = !path.IsEmpty() ? path : String::FromFormat("%s/ags.log", platform->GetAppOutputDirectory());
 		if (!DebugLogFile->OpenFile(logfile_path, open_mode))
 			return nullptr;
 		platform->WriteStdOut("Logging to %s", logfile_path.GetCStr());
-		auto dbgout = DbgMgr.RegisterOutput(OutputFileID, DebugLogFile.get(), kDbgMsg_None);
+		auto dbgout = _GP(DbgMgr).RegisterOutput(OutputFileID, DebugLogFile.get(), kDbgMsg_None);
 		return dbgout;
 	} else if (name.CompareNoCase(OutputGameConsoleID) == 0) {
 		DebugConsole.reset(new ConsoleOutputTarget());
-		return DbgMgr.RegisterOutput(OutputGameConsoleID, DebugConsole.get(), kDbgMsg_None);
+		return _GP(DbgMgr).RegisterOutput(OutputGameConsoleID, DebugConsole.get(), kDbgMsg_None);
 	}
 	return nullptr;
 }
@@ -168,7 +168,7 @@ void apply_log_config(const ConfigTree &cfg, const String &log_id,
 		return;
 
 	// First test if already registered, if not then try create it
-	auto dbgout = DbgMgr.GetOutput(log_id);
+	auto dbgout = _GP(DbgMgr).GetOutput(log_id);
 	const bool was_created_earlier = dbgout != nullptr;
 	if (!dbgout) {
 		String path = INIreadstring(cfg, "log", String::FromFormat("%s-path", log_id.GetCStr()));
@@ -220,7 +220,7 @@ void init_debug(const ConfigTree &cfg, bool stderr_only) {
 
 	// Message buffer to save all messages in case we read different log settings from config file
 	DebugMsgBuff.reset(new MessageBuffer());
-	DbgMgr.RegisterOutput(OutputMsgBufID, DebugMsgBuff.get(), kDbgMsg_All);
+	_GP(DbgMgr).RegisterOutput(OutputMsgBufID, DebugMsgBuff.get(), kDbgMsg_All);
 }
 
 void apply_debug_config(const ConfigTree &cfg) {
@@ -267,13 +267,13 @@ void apply_debug_config(const ConfigTree &cfg) {
 	}
 
 	// We don't need message buffer beyond this point
-	DbgMgr.UnregisterOutput(OutputMsgBufID);
+	_GP(DbgMgr).UnregisterOutput(OutputMsgBufID);
 	DebugMsgBuff.reset();
 }
 
 void shutdown_debug() {
 	// Shutdown output subsystem
-	DbgMgr.UnregisterAll();
+	_GP(DbgMgr).UnregisterAll();
 
 	DebugMsgBuff.reset();
 	DebugLogFile.reset();
@@ -282,7 +282,7 @@ void shutdown_debug() {
 
 void debug_set_console(bool enable) {
 	if (DebugConsole)
-		DbgMgr.GetOutput(OutputGameConsoleID)->SetEnabled(enable);
+		_GP(DbgMgr).GetOutput(OutputGameConsoleID)->SetEnabled(enable);
 }
 
 // Prepends message text with current room number and running script info, then logs result
diff --git a/engines/ags/engine/debugging/messagebuffer.cpp b/engines/ags/engine/debugging/messagebuffer.cpp
index d946c2a2af..344ba37d14 100644
--- a/engines/ags/engine/debugging/messagebuffer.cpp
+++ b/engines/ags/engine/debugging/messagebuffer.cpp
@@ -22,6 +22,7 @@
 
 #include "ags/shared/debugging/debugmanager.h"
 #include "ags/engine/debugging/messagebuffer.h"
+#include "ags/globals.h"
 
 namespace AGS3 {
 namespace AGS {
@@ -50,12 +51,12 @@ void MessageBuffer::Send(const String &out_id) {
 	if (_buffer.empty())
 		return;
 	if (_msgLost > 0) {
-		DebugGroup gr = DbgMgr.GetGroup(kDbgGroup_Main);
-		DbgMgr.SendMessage(out_id, DebugMessage(String::FromFormat("WARNING: output %s lost exceeding buffer: %u debug messages\n", out_id.GetCStr(), (unsigned)_msgLost),
+		DebugGroup gr = _GP(DbgMgr).GetGroup(kDbgGroup_Main);
+		_GP(DbgMgr).SendMessage(out_id, DebugMessage(String::FromFormat("WARNING: output %s lost exceeding buffer: %u debug messages\n", out_id.GetCStr(), (unsigned)_msgLost),
 			gr.UID.ID, gr.OutputName, kDbgMsg_All));
 	}
 	for (std::vector<DebugMessage>::const_iterator it = _buffer.begin(); it != _buffer.end(); ++it) {
-		DbgMgr.SendMessage(out_id, *it);
+		_GP(DbgMgr).SendMessage(out_id, *it);
 	}
 }
 
diff --git a/engines/ags/globals.cpp b/engines/ags/globals.cpp
index 9124a98b74..d5ea40a1c9 100644
--- a/engines/ags/globals.cpp
+++ b/engines/ags/globals.cpp
@@ -23,6 +23,7 @@
 #include "ags/globals.h"
 #include "ags/shared/ac/gamesetupstruct.h"
 #include "ags/shared/ac/spritecache.h"
+#include "ags/shared/debugging/debugmanager.h"
 #include "ags/shared/game/roomstruct.h"
 #include "ags/engine/ac/gamestate.h"
 #include "ags/engine/ac/roomstatus.h"
@@ -52,6 +53,9 @@ Globals::Globals() {
 
 	Common::fill(&_mousecurs[0], &_mousecurs[MAXCURSORS], nullptr);
 
+	// debugmanager.cpp globals
+	_DbgMgr = new AGS::Shared::DebugManager();
+
 	// game.cpp globals
 	_ccDynamicGUIObject = new CCGUIObject();
 	_ccDynamicCharacter = new CCCharacter();
@@ -80,6 +84,8 @@ Globals::Globals() {
 Globals::~Globals() {
 	g_globals = nullptr;
 
+	delete _DbgMgr;
+
 	delete _ccDynamicGUIObject;
 	delete _ccDynamicCharacter;
 	delete _ccDynamicHotspot;
@@ -97,6 +103,11 @@ Globals::~Globals() {
 	delete _spriteset;
 	delete _thisroom;
 	delete _troom;
+	delete[] _scrObj;
+	delete[] _scrHotspot;
+	delete[] _scrRegion;
+	delete[] _scrInv;
+	delete[] _objcache;
 }
 
 } // namespace AGS3
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index 476ab13f61..6716594d9a 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -38,6 +38,7 @@ using Version = AGS::Shared::Version;
 namespace AGS {
 namespace Shared {
 class Bitmap;
+class DebugManager;
 class RoomStruct;
 } // namespace Shared
 } // namespace AGS
@@ -97,6 +98,15 @@ public:
 
 	/**@}*/
 
+
+	/**
+	 * \defgroup debug globals
+	 * @{
+	 */
+
+	AGS::Shared::DebugManager *_DbgMgr;
+	/**@}*/
+
 	/**
 	 * \defgroup game globals
 	 * @{
diff --git a/engines/ags/shared/debugging/debugmanager.cpp b/engines/ags/shared/debugging/debugmanager.cpp
index f54484a66d..ad804dfef2 100644
--- a/engines/ags/shared/debugging/debugmanager.cpp
+++ b/engines/ags/shared/debugging/debugmanager.cpp
@@ -23,6 +23,7 @@
 //include <stdarg.h>
 #include "ags/shared/debugging/debugmanager.h"
 #include "ags/shared/util/string_types.h"
+#include "ags/globals.h"
 
 namespace AGS3 {
 namespace AGS {
@@ -33,7 +34,7 @@ DebugOutput::DebugOutput(const String &id, IOutputHandler *handler, MessageType
 	, _handler(handler)
 	, _enabled(enabled)
 	, _defaultVerbosity(def_verbosity) {
-	_groupFilter.resize(DbgMgr._lastGroupID + 1, _defaultVerbosity);
+	_groupFilter.resize(_GP(DbgMgr)._lastGroupID + 1, _defaultVerbosity);
 }
 
 String DebugOutput::GetID() const {
@@ -53,7 +54,7 @@ void DebugOutput::SetEnabled(bool enable) {
 }
 
 void DebugOutput::SetGroupFilter(DebugGroupID id, MessageType verbosity) {
-	uint32_t key = DbgMgr.GetGroup(id).UID.ID;
+	uint32_t key = _GP(DbgMgr).GetGroup(id).UID.ID;
 	if (key != (uint32_t)kDbgGroup_None)
 		_groupFilter[key] = verbosity;
 	else
@@ -77,7 +78,7 @@ void DebugOutput::ResolveGroupID(DebugGroupID id) {
 	if (!id.IsValid())
 		return;
 
-	DebugGroupID real_id = DbgMgr.GetGroup(id).UID;
+	DebugGroupID real_id = _GP(DbgMgr).GetGroup(id).UID;
 	if (real_id.IsValid()) {
 		if (_groupFilter.size() <= id.ID)
 			_groupFilter.resize(id.ID + 1, _defaultVerbosity);
@@ -90,7 +91,7 @@ void DebugOutput::ResolveGroupID(DebugGroupID id) {
 }
 
 bool DebugOutput::TestGroup(DebugGroupID id, MessageType mt) const {
-	DebugGroupID real_id = DbgMgr.GetGroup(id).UID;
+	DebugGroupID real_id = _GP(DbgMgr).GetGroup(id).UID;
 	if (real_id.ID == (uint32_t)kDbgGroup_None || real_id.ID >= _groupFilter.size())
 		return false;
 	return (_groupFilter[real_id.ID] >= mt) != 0;
@@ -126,7 +127,7 @@ DebugGroup DebugManager::RegisterGroup(const String &id, const String &out_name)
 	DebugGroup group = GetGroup(id);
 	if (group.UID.IsValid())
 		return group;
-	group = DebugGroup(DebugGroupID(++DbgMgr._lastGroupID, id), out_name);
+	group = DebugGroup(DebugGroupID(++_GP(DbgMgr)._lastGroupID, id), out_name);
 	_groups.push_back(group);
 	_groupByStrLookup[group.UID.SID] = group.UID;
 
@@ -196,30 +197,26 @@ void DebugManager::SendMessage(OutputSlot &out, const DebugMessage &msg) {
 	out.Suppressed = false;
 }
 
-// TODO: move this to the dynamically allocated engine object whenever it is implemented
-DebugManager DbgMgr;
-
-
 namespace Debug {
 
 void Printf(const char *fmt, ...) {
 	va_list argptr;
 	va_start(argptr, fmt);
-	DbgMgr.Print(kDbgGroup_Main, kDbgMsg_Default, String::FromFormatV(fmt, argptr));
+	_GP(DbgMgr).Print(kDbgGroup_Main, kDbgMsg_Default, String::FromFormatV(fmt, argptr));
 	va_end(argptr);
 }
 
 void Printf(MessageType mt, const char *fmt, ...) {
 	va_list argptr;
 	va_start(argptr, fmt);
-	DbgMgr.Print(kDbgGroup_Main, mt, String::FromFormatV(fmt, argptr));
+	_GP(DbgMgr).Print(kDbgGroup_Main, mt, String::FromFormatV(fmt, argptr));
 	va_end(argptr);
 }
 
 void Printf(DebugGroupID group, MessageType mt, const char *fmt, ...) {
 	va_list argptr;
 	va_start(argptr, fmt);
-	DbgMgr.Print(group, mt, String::FromFormatV(fmt, argptr));
+	_GP(DbgMgr).Print(group, mt, String::FromFormatV(fmt, argptr));
 	va_end(argptr);
 }
 
diff --git a/engines/ags/shared/debugging/debugmanager.h b/engines/ags/shared/debugging/debugmanager.h
index a8b92fc527..a6a30d2447 100644
--- a/engines/ags/shared/debugging/debugmanager.h
+++ b/engines/ags/shared/debugging/debugmanager.h
@@ -162,9 +162,6 @@ private:
 	OutMap              _outputs;
 };
 
-// TODO: move this to the dynamically allocated engine object whenever it is implemented
-extern DebugManager DbgMgr;
-
 } // namespace Shared
 } // namespace AGS
 } // namespace AGS3




More information about the Scummvm-git-logs mailing list