[Scummvm-git-logs] scummvm master -> ad37508aa71c4f0a078c0cc6527a9441b94abc74

sev- noreply at scummvm.org
Tue Jun 30 19:24:11 UTC 2026


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

Summary:
13883f26ca SKY: Add ibass to the detection logic
cc5f494998 SKY: Populate the entry table after veryfying the bass.dat file and initialize graphics
b97b4dc390 SKY: Load animations, overlay icons and port mouse input logic for ibass
20c9c684fb SKY: Implement inventory logic in ibass
4ad2771b90 SKY: Implement inventory closing logic
a27d38d52a SKY: Make clearAllInvIcons to actually clear the inventory icons
7f28801edf SKY: Fix formatting and change names
3e8ecfcf6e SKY: Some more cleanup, refactoring and naming changes
76f09bad0d SKY: Move some variables to class, fix formatting and adress PR reviews
63c8945283 SKY: Create lookup table for giveYCood and fix a syntax error in mouse.h
d2523dae96 SKY: Fix formatting
a22163d14e SKY: Implement clicking for inventory icon
923dbca07d SKY: Convert control panel to 32 bit before outputting
bb5125236b SKY: Implement inventory item's examining in ibass
53b3d8b64d SKY: Port invMouse hover logic
7547e56db8 SKY: Make og BASS run in 8bpp mode, some fixes in control panel and a lot of refactoring overall
62ca0c692a SKY: Implement inventory item's dragging in IBASS
e0d7b342a9 SKY: Add debug level and remove a newline character
9aafca550f SKY: Remove separate cursor path for ibass
01608c6080 SKY: Fix crash due to writing outside the boundary of _screen32
d2bd6badb5 SKY: Close LINC inventory if clicked outside the inventory in IBASS
ad37508aa7 SKY: Use active mouse state instead of _mouseB, fix a logical error and some cleanup in LINC inventory for IBASS


Commit: 13883f26ca45f05f5caf478d5938b51c5914967d
    https://github.com/scummvm/scummvm/commit/13883f26ca45f05f5caf478d5938b51c5914967d
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Add ibass to the detection logic

Changed paths:
    engines/sky/detection.cpp


diff --git a/engines/sky/detection.cpp b/engines/sky/detection.cpp
index a23f057a74c..5be37983f61 100644
--- a/engines/sky/detection.cpp
+++ b/engines/sky/detection.cpp
@@ -32,6 +32,9 @@
 static const PlainGameDescriptor skySetting =
 	{"sky", "Beneath a Steel Sky" };
 
+static const PlainGameDescriptor ibassSetting =
+	{ "ibass", "Beneath a Steel Sky iOS remastered" };
+
 struct SkyVersion {
 	int dinnerTableEntries;
 	int dataDiskSize;
@@ -95,12 +98,15 @@ const char *SkyMetaEngineDetection::getOriginalCopyright() const {
 PlainGameList SkyMetaEngineDetection::getSupportedGames() const {
 	PlainGameList games;
 	games.push_back(skySetting);
+	games.push_back(ibassSetting);
 	return games;
 }
 
 PlainGameDescriptor SkyMetaEngineDetection::findGame(const char *gameid) const {
 	if (0 == scumm_stricmp(gameid, skySetting.gameId))
 		return skySetting;
+	else if (0 == scumm_stricmp(gameid, ibassSetting.gameId))
+		return ibassSetting;
 	return PlainGameDescriptor::empty();
 }
 
@@ -116,6 +122,8 @@ DetectedGames SkyMetaEngineDetection::detectGames(const Common::FSList &fslist,
 	bool hasSkyDnr = false;
 	int dinnerTableEntries = -1;
 	int dataDiskSize = -1;
+	bool hasibassDat = false;
+	int ibassDiskSize = -1;
 	Common::String dataDiskHeadMD5 = "";
 	int exeSize = -1; 
 	const Common::Language langs[] = {
@@ -145,6 +153,16 @@ DetectedGames SkyMetaEngineDetection::detectGames(const Common::FSList &fslist,
 				}
 			}
 
+			if (0 == scumm_stricmp("bass.dat", file->getName().c_str())) {
+				Common::File ibassDisk;
+				if (ibassDisk.open(*file)) {
+					hasibassDat = true;
+					ibassDiskSize = ibassDisk.size();
+					if (ibassDiskSize == 9737168 )
+						dataDiskHeadMD5 = Common::computeStreamMD5AsString(ibassDisk, 5000);
+				}
+			}
+
 			if (0 == scumm_stricmp("sky.dnr", file->getName().c_str())) {
 				Common::File dinner;
 				if (dinner.open(*file)) {
@@ -211,6 +229,13 @@ DetectedGames SkyMetaEngineDetection::detectGames(const Common::FSList &fslist,
 		detectedGames.push_back(game);
 	}
 
+	if (hasibassDat) {
+		DetectedGame game;
+		Common::Language lang = Common::Language::UNK_LANG;
+		game = DetectedGame(getName(), ibassSetting.gameId, ibassSetting.description, lang);
+		detectedGames.push_back(game);
+	}
+
 	return detectedGames;
 }
 


Commit: cc5f4949984edb9a09fae09010c9fbdb85cb10d4
    https://github.com/scummvm/scummvm/commit/cc5f4949984edb9a09fae09010c9fbdb85cb10d4
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Populate the entry table after veryfying the bass.dat file and initialize graphics

Changed paths:
    engines/sky/disk.cpp
    engines/sky/disk.h
    engines/sky/screen.cpp
    engines/sky/sky.cpp
    engines/sky/sound.cpp
    engines/sky/text.cpp


diff --git a/engines/sky/disk.cpp b/engines/sky/disk.cpp
index 6b56735fa5b..8c24b33fb57 100644
--- a/engines/sky/disk.cpp
+++ b/engines/sky/disk.cpp
@@ -24,6 +24,8 @@
 #include "common/textconsole.h"
 #include "common/endian.h"
 #include "common/file.h"
+#include "common/config-manager.h"
+#include "common/compression/deflate.h"
 
 #include "sky/disk.h"
 #include "sky/sky.h"
@@ -34,34 +36,68 @@ namespace Sky {
 static const char *const dataFilename = "sky.dsk";
 static const char *const dinnerFilename = "sky.dnr";
 
+static int hashCompFunc(const void *m1, const void *m2) {
+	fileEntry *e1 = (fileEntry *)m1;
+	fileEntry *e2 = (fileEntry *)m2;
+	if (e1->filenum == e2->filenum)
+		return 0;
+	return (e1->filenum < e2->filenum ? -1 : 1);
+}
+
 Disk::Disk() {
 	_dataDiskHandle = new Common::File();
-	Common::File *dnrHandle = new Common::File();
 
-	dnrHandle->open(dinnerFilename);
-	if (!dnrHandle->isOpen())
-		error("Could not open %s", dinnerFilename);
+	if (ConfMan.get("gameid") == "ibass") {
+		if (!_dataDiskHandle->open("bass.dat"))
+			error("Error opening bass.dat");
+
+		char magic[4];
+		_dataDiskHandle->read(magic, 4);
+		if (0 != strncmp("HSFS", magic, 4))
+			error("Invalid bass.dat file");
+
+		_numFiles = _dataDiskHandle->readUint32LE();
+		_entry = new fileEntry[_numFiles];
+
+		//now populate the entry table
+		for (uint32 i = 0; i < _numFiles; i++) {
+			_entry[i].filenum = _dataDiskHandle->readUint32LE();
+			_entry[i].offset = _dataDiskHandle->readUint32LE();
+			_entry[i].size = _dataDiskHandle->readUint32LE();
+			_entry[i].compressed_size = _dataDiskHandle->readUint32LE();
+		}
+
+ 		memset(_buildList, 0, 60 * 2);
+ 		memset(_loadedFilesList, 0, 60 * 4);
+
+	} else {
+		Common::File *dnrHandle = new Common::File();
+
+		dnrHandle->open(dinnerFilename);
+		if (!dnrHandle->isOpen())
+			error("Could not open %s", dinnerFilename);
 
-	if (!(_dinnerTableEntries = dnrHandle->readUint32LE()))
-		error("Error reading from sky.dnr"); //even though it was opened correctly?!
+		if (!(_dinnerTableEntries = dnrHandle->readUint32LE()))
+			error("Error reading from sky.dnr"); //even though it was opened correctly?!
 
-	_dinnerTableArea = (uint8 *)malloc(_dinnerTableEntries * 8);
-	uint32 entriesRead = dnrHandle->read(_dinnerTableArea, 8 * _dinnerTableEntries) / 8;
+		_dinnerTableArea = (uint8 *)malloc(_dinnerTableEntries * 8);
+		uint32 entriesRead = dnrHandle->read(_dinnerTableArea, 8 * _dinnerTableEntries) / 8;
 
-	if (entriesRead != _dinnerTableEntries)
-		error("entriesRead != dinnerTableEntries. [%d/%d]", entriesRead, _dinnerTableEntries);
+		if (entriesRead != _dinnerTableEntries)
+			error("entriesRead != dinnerTableEntries. [%d/%d]", entriesRead, _dinnerTableEntries);
 
-	_dataDiskHandle->open(dataFilename);
-	if (!_dataDiskHandle->isOpen())
-		error("Error opening %s", dataFilename);
+		_dataDiskHandle->open(dataFilename);
+		if (!_dataDiskHandle->isOpen())
+			error("Error opening %s", dataFilename);
 
-	debug("Found BASS version v0.0%d (%d dnr entries)", determineGameVersion(), _dinnerTableEntries);
+		debug("Found BASS version v0.0%d (%d dnr entries)", determineGameVersion(), _dinnerTableEntries);
 
-	memset(_buildList, 0, 60 * 2);
-	memset(_loadedFilesList, 0, 60 * 4);
+		memset(_buildList, 0, 60 * 2);
+		memset(_loadedFilesList, 0, 60 * 4);
 
-	dnrHandle->close();
-	delete dnrHandle;
+		dnrHandle->close();
+		delete dnrHandle;
+	}
 }
 
 Disk::~Disk() {
@@ -70,106 +106,136 @@ Disk::~Disk() {
 	fnFlushBuffers();
 	free(_dinnerTableArea);
 	delete _dataDiskHandle;
+	delete[] _entry;
+	_entry = 0;
 }
 
 bool Disk::fileExists(uint16 fileNr) {
 	return (getFileInfo(fileNr) != NULL);
 }
 
+fileEntry *Disk::getEntry(uint32 filenum) {
+	fileEntry searchEntry;
+	searchEntry.filenum = filenum;
+	return (fileEntry *)bsearch(&searchEntry, _entry, _numFiles, sizeof(fileEntry), hashCompFunc);
+}
+
 // allocate memory, load the file and return a pointer
 uint8 *Disk::loadFile(uint16 fileNr) {
-	uint8 cflag;
 
-	debug(3, "load file %d,%d (%d)", (fileNr >> 11), (fileNr & 2047), fileNr);
+	if (ConfMan.get("gameid") == "ibass") {
+		fileEntry *entry = getEntry(fileNr);
+		if (!entry) {
+			debug(1, "iBass: File %d not found!", fileNr);
+			return NULL;
+		}
+		uint8 *compressedData = (uint8 *)malloc(entry->compressed_size);
+		uint8 *uncompressedData = (uint8 *)malloc(entry->size);
+		_dataDiskHandle->seek(entry->offset, SEEK_SET);
+		uint32 bytesRead = _dataDiskHandle->read(compressedData, entry->compressed_size);
+		assert(entry->compressed_size == bytesRead);
+
+		unsigned long destLen = entry->size;
+		bool result = Common::inflateZlib(uncompressedData, &destLen, compressedData, entry->compressed_size);
+		assert(result == true);
+
+		free(compressedData);
+		_lastLoadedFileSize = entry->size;
+		return uncompressedData;
+	} else {
+		uint8 cflag;
 
-	uint8 *fileInfoPtr = getFileInfo(fileNr);
-	if (fileInfoPtr == NULL) {
-		debug(1, "File %d not found", fileNr);
-		return NULL;
-	}
+		debug(3, "load file %d,%d (%d)", (fileNr >> 11), (fileNr & 2047), fileNr);
 
-	uint32 fileFlags = READ_LE_UINT24(fileInfoPtr + 5);
-	uint32 fileSize = fileFlags & 0x03fffff;
-	uint32 fileOffset = READ_LE_UINT32(fileInfoPtr + 2) & 0x0ffffff;
+		uint8 *fileInfoPtr = getFileInfo(fileNr);
+		if (fileInfoPtr == NULL) {
+			debug(1, "File %d not found", fileNr);
+			return NULL;
+		}
 
-	_lastLoadedFileSize = fileSize;
-	cflag = (uint8)((fileOffset >> 23) & 0x1);
-	fileOffset &= 0x7FFFFF;
+		uint32 fileFlags = READ_LE_UINT24(fileInfoPtr + 5);
+		uint32 fileSize = fileFlags & 0x03fffff;
+		uint32 fileOffset = READ_LE_UINT32(fileInfoPtr + 2) & 0x0ffffff;
 
-	if (cflag) {
-		if (SkyEngine::_systemVars->gameVersion == 331)
-			fileOffset <<= 3;
-		else
-			fileOffset <<= 4;
-	}
+		_lastLoadedFileSize = fileSize;
+		cflag = (uint8)((fileOffset >> 23) & 0x1);
+		fileOffset &= 0x7FFFFF;
 
-	uint8 *fileDest = (uint8 *)malloc(fileSize + 4); // allocate memory for file
+		if (cflag) {
+			if (SkyEngine::_systemVars->gameVersion == 331)
+				fileOffset <<= 3;
+			else
+				fileOffset <<= 4;
+		}
 
-	_dataDiskHandle->seek(fileOffset, SEEK_SET);
+		uint8 *fileDest = (uint8 *)malloc(fileSize + 4); // allocate memory for file
 
-	//now read in the data
-	int32 bytesRead = _dataDiskHandle->read(fileDest, fileSize);
+		_dataDiskHandle->seek(fileOffset, SEEK_SET);
 
-	if (bytesRead != (int32)fileSize)
-		warning("Unable to read %d bytes from datadisk (%d bytes read)", fileSize, bytesRead);
+		//now read in the data
+		int32 bytesRead = _dataDiskHandle->read(fileDest, fileSize);
 
-	cflag = (uint8)((fileFlags >> 23) & 0x1);
-	//if cflag == 0 then file is compressed, 1 == uncompressed
+		if (bytesRead != (int32)fileSize)
+			warning("Unable to read %d bytes from datadisk (%d bytes read)", fileSize, bytesRead);
 
-	DataFileHeader *fileHeader = (DataFileHeader *)fileDest;
+		cflag = (uint8)((fileFlags >> 23) & 0x1);
+		//if cflag == 0 then file is compressed, 1 == uncompressed
 
-	if ((!cflag) && ((FROM_LE_16(fileHeader->flag) >> 7) & 1)) {
-		debug(4, "File is RNC compressed.");
+		DataFileHeader *fileHeader = (DataFileHeader *)fileDest;
 
-		uint32 decompSize = (FROM_LE_16(fileHeader->flag) & ~0xFF) << 8;
-		decompSize |= FROM_LE_16(fileHeader->s_tot_size);
+		if ((!cflag) && ((FROM_LE_16(fileHeader->flag) >> 7) & 1)) {
+			debug(4, "File is RNC compressed.");
 
-		uint8 *uncompDest = (uint8 *)malloc(decompSize);
+			uint32 decompSize = (FROM_LE_16(fileHeader->flag) & ~0xFF) << 8;
+			decompSize |= FROM_LE_16(fileHeader->s_tot_size);
 
-		int32 unpackLen;
-		void *output, *input = fileDest + sizeof(DataFileHeader);
+			uint8 *uncompDest = (uint8 *)malloc(decompSize);
 
-		if ((fileFlags >> 22) & 0x1) { //do we include the header?
-			// don't return the file's header
-			output = uncompDest;
-			unpackLen = _rncDecoder.unpackM1(input, fileSize - sizeof(DataFileHeader), output);
-		} else {
-#ifdef SCUMM_BIG_ENDIAN
-			// Convert DataFileHeader to BE (it only consists of 16 bit words)
-			uint16 *headPtr = (uint16 *)fileDest;
-			for (uint i = 0; i < sizeof(DataFileHeader) / 2; i++)
-				*(headPtr + i) = READ_LE_UINT16(headPtr + i);
-#endif
+			int32 unpackLen;
+			void *output, *input = fileDest + sizeof(DataFileHeader);
 
-			memcpy(uncompDest, fileDest, sizeof(DataFileHeader));
-			output = uncompDest + sizeof(DataFileHeader);
-			unpackLen = _rncDecoder.unpackM1(input, fileSize - sizeof(DataFileHeader), output);
-			if (unpackLen)
-				unpackLen += sizeof(DataFileHeader);
-		}
+			if ((fileFlags >> 22) & 0x1) { //do we include the header?
+				// don't return the file's header
+				output = uncompDest;
+				unpackLen = _rncDecoder.unpackM1(input, fileSize - sizeof(DataFileHeader), output);
+			} else {
+	#ifdef SCUMM_BIG_ENDIAN
+				// Convert DataFileHeader to BE (it only consists of 16 bit words)
+				uint16 *headPtr = (uint16 *)fileDest;
+				for (uint i = 0; i < sizeof(DataFileHeader) / 2; i++)
+					*(headPtr + i) = READ_LE_UINT16(headPtr + i);
+	#endif
 
-		debug(5, "UnpackM1 returned: %d", unpackLen);
+				memcpy(uncompDest, fileDest, sizeof(DataFileHeader));
+				output = uncompDest + sizeof(DataFileHeader);
+				unpackLen = _rncDecoder.unpackM1(input, fileSize - sizeof(DataFileHeader), output);
+				if (unpackLen)
+					unpackLen += sizeof(DataFileHeader);
+			}
 
-		if (unpackLen == 0) { //Unpack returned 0: file was probably not packed.
-			free(uncompDest);
-			return fileDest;
-		} else {
-			if (unpackLen != (int32)decompSize)
-				debug(1, "ERROR: File %d: invalid decomp size! (was: %d, should be: %d)", fileNr, unpackLen, decompSize);
-			_lastLoadedFileSize = decompSize;
+			debug(5, "UnpackM1 returned: %d", unpackLen);
 
-			free(fileDest);
-			return uncompDest;
-		}
-	} else {
-#ifdef SCUMM_BIG_ENDIAN
-		if (!cflag) {
-			uint16 *headPtr = (uint16 *)fileDest;
-			for (uint i = 0; i < sizeof(DataFileHeader) / 2; i++)
-				*(headPtr + i) = READ_LE_UINT16(headPtr + i);
+			if (unpackLen == 0) { //Unpack returned 0: file was probably not packed.
+				free(uncompDest);
+				return fileDest;
+			} else {
+				if (unpackLen != (int32)decompSize)
+					debug(1, "ERROR: File %d: invalid decomp size! (was: %d, should be: %d)", fileNr, unpackLen, decompSize);
+				_lastLoadedFileSize = decompSize;
+
+				free(fileDest);
+				return uncompDest;
+			}
+		} else {
+	#ifdef SCUMM_BIG_ENDIAN
+			if (!cflag) {
+				uint16 *headPtr = (uint16 *)fileDest;
+				for (uint i = 0; i < sizeof(DataFileHeader) / 2; i++)
+					*(headPtr + i) = READ_LE_UINT16(headPtr + i);
+			}
+	#endif
+			return fileDest;
 		}
-#endif
-		return fileDest;
 	}
 }
 
@@ -329,6 +395,9 @@ void Disk::dumpFile(uint16 fileNr) {
 }
 
 uint32 Disk::determineGameVersion() {
+	if (ConfMan.get("gameid") == "ibass")
+		return 400; // force the ibass version and immediately exit the function
+
 	//determine game version based on number of entries in dinner table
 	switch (_dinnerTableEntries) {
 	case 232:
diff --git a/engines/sky/disk.h b/engines/sky/disk.h
index af721d875e4..96ea61d3d31 100644
--- a/engines/sky/disk.h
+++ b/engines/sky/disk.h
@@ -32,6 +32,14 @@ namespace Common {
 class File;
 }
 
+struct fileEntry {
+	uint32 filenum;
+	uint32 offset;
+	uint32 size;
+	uint32 compressed_size;
+	fileEntry() : filenum(0), offset(0), size(0), compressed_size(0) {}
+};
+
 namespace Sky {
 
 class Disk {
@@ -59,11 +67,17 @@ protected:
 	uint8 *getFileInfo(uint16 fileNr);
 	void dumpFile(uint16 fileNr);
 
+	uint32 _numFiles;
+	fileEntry *_entry;
+
 	uint32 _dinnerTableEntries;
 	uint8 *_dinnerTableArea;
 	Common::File *_dataDiskHandle;
 	Common::RncDecoder _rncDecoder;
 
+	uint32 getFileSize(uint32 filenum);
+	fileEntry *getEntry(uint32 filenum);
+
 	uint16 _buildList[MAX_FILES_IN_LIST];
 	uint32 _loadedFilesList[MAX_FILES_IN_LIST];
 };
diff --git a/engines/sky/screen.cpp b/engines/sky/screen.cpp
index 11f5f3002fd..924b7f39f6c 100644
--- a/engines/sky/screen.cpp
+++ b/engines/sky/screen.cpp
@@ -24,9 +24,13 @@
 #include "common/events.h"
 #include "common/system.h"
 #include "common/textconsole.h"
+#include "common/config-manager.h"
+#include "common/memstream.h"
 
 #include "graphics/paletteman.h"
 
+#include "image/png.h"
+
 #include "sky/disk.h"
 #include "sky/logic.h"
 #include "sky/screen.h"
@@ -81,7 +85,8 @@ Screen::Screen(OSystem *pSystem, Disk *pDisk, SkyCompact *skyCompact) {
 	}
 
 	//set the palette
-	_system->getPaletteManager()->setPalette(tmpPal, 0, VGA_COLORS);
+	if (ConfMan.get("gameid") != "ibass")
+		_system->getPaletteManager()->setPalette(tmpPal, 0, VGA_COLORS);
 	_currentPalette = 0;
 
 	_seqInfo.nextFrame = _seqInfo.framesLeft = 0;
@@ -108,7 +113,8 @@ void Screen::setFocusRectangle(const Common::Rect& rect) {
 //set a new palette, pal is a pointer to dos vga rgb components 0..63
 void Screen::setPalette(uint8 *pal) {
 	convertPalette(pal, _palette);
-	_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
+	if (ConfMan.get("gameid") != "ibass")
+		_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
 	_system->updateScreen();
 }
 
@@ -121,7 +127,8 @@ void Screen::setPaletteEndian(uint8 *pal) {
 #else
 	convertPalette(pal, _palette);
 #endif
-	_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
+	if (ConfMan.get("gameid") != "ibass")
+		_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
 	_system->updateScreen();
 }
 
@@ -133,7 +140,8 @@ void Screen::halvePalette() {
 		halfPalette[cnt * 3 + 1] = _palette[cnt * 3 + 1] >> 1;
 		halfPalette[cnt * 3 + 2] = _palette[cnt * 3 + 2] >> 1;
 	}
-	_system->getPaletteManager()->setPalette(halfPalette, 0, GAME_COLORS);
+	if (ConfMan.get("gameid") != "ibass")
+		_system->getPaletteManager()->setPalette(halfPalette, 0, GAME_COLORS);
 }
 
 void Screen::setPalette(uint16 fileNum) {
@@ -146,18 +154,40 @@ void Screen::setPalette(uint16 fileNum) {
 }
 
   void Screen::showScreen(uint16 fileNum, bool fullscreen) {
-	// This is only used for static images in the floppy and cd intro
-	free(_currentScreen);
-	_currentScreen = _skyDisk->loadFile(fileNum);
-	if (!fullscreen) {
-		// make sure the last 8 lines are forced to black.
-		memset(_currentScreen + GAME_SCREEN_HEIGHT * GAME_SCREEN_WIDTH, 0, (FULL_SCREEN_HEIGHT - GAME_SCREEN_HEIGHT) * GAME_SCREEN_WIDTH);
-	}
 
-	if (_currentScreen)
-		showScreen(_currentScreen, fullscreen);
-	else
-		warning("Screen::showScreen: can't load file nr. %d",fileNum);
+	if (ConfMan.get("gameid") != "ibass") {
+		uint8 *imgData = _skyDisk->loadFile(fileNum);
+
+		if (imgData) {
+			Common::MemoryReadStream stream(imgData, _skyDisk->_lastLoadedFileSize);
+
+			Image::PNGDecoder decoder;
+			free(_currentScreen);
+			if (decoder.loadStream(stream)) {
+				const Graphics::Surface *surface = decoder.getSurface();
+				_currentScreen = (uint8 *)malloc(surface->pitch * surface->h);
+				memcpy(_currentScreen, surface->getPixels(), surface->w * surface->h);
+
+				_system->copyRectToScreen(_currentScreen, surface->pitch, 0, 0, surface->pitch, surface->h);
+				_system->updateScreen();
+				free(imgData);
+				return;
+			}
+		}
+	} else {
+		// This is only used for static images in the floppy and cd intro
+		free(_currentScreen);
+		_currentScreen = _skyDisk->loadFile(fileNum);
+		if (!fullscreen) {
+			// make sure the last 8 lines are forced to black.
+			memset(_currentScreen + GAME_SCREEN_HEIGHT * GAME_SCREEN_WIDTH, 0, (FULL_SCREEN_HEIGHT - GAME_SCREEN_HEIGHT) * GAME_SCREEN_WIDTH);
+		}
+
+		if (_currentScreen)
+			showScreen(_currentScreen, fullscreen);
+		else
+			warning("Screen::showScreen: can't load file nr. %d",fileNum);
+	}
 }
 
 void Screen::showScreen(uint8 *pScreen, bool fullscreen) {
@@ -249,7 +279,8 @@ void Screen::fnFadeDown(uint32 scroll) {
 		for (uint8 cnt = 0; cnt < 32; cnt++) {
 			delayTime += 20;
 			palette_fadedown_helper(_palette, GAME_COLORS);
-			_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
+			if (ConfMan.get("gameid") != "ibass")
+				_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
 			_system->updateScreen();
 			int32 waitTime = (int32)delayTime - _system->getMillis();
 			if (waitTime < 0)
@@ -310,8 +341,8 @@ void Screen::paletteFadeUp(uint8 *pal) {
 			_palette[colCnt * 3 + 1] = (tmpPal[colCnt * 3 + 1] * cnt) >> 5;
 			_palette[colCnt * 3 + 2] = (tmpPal[colCnt * 3 + 2] * cnt) >> 5;
 		}
-
-		_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
+		if (ConfMan.get("gameid") != "ibass")
+			_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
 		_system->updateScreen();
 
 		int32 waitTime = (int32)delayTime - _system->getMillis();
diff --git a/engines/sky/sky.cpp b/engines/sky/sky.cpp
index 58d1b093e53..f26ce1e935c 100644
--- a/engines/sky/sky.cpp
+++ b/engines/sky/sky.cpp
@@ -345,7 +345,11 @@ bool SkyEngine::loadChineseTraditional() {
 }
 
 Common::Error SkyEngine::init() {
-	initGraphics(320, 200);
+	if (ConfMan.get("gameid") == "ibass") {
+		Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0);
+		initGraphics(640, 480, &format);
+	} else
+		initGraphics(320, 200);
 
 	_skyDisk = new Disk();
 	_skySound = new Sound(_mixer, _skyDisk, Audio::Mixer::kMaxChannelVolume);
@@ -559,6 +563,7 @@ bool SkyEngine::isDemo() {
 	case 348:
 	case 368:
 	case 372:
+	case 400:
 		return false;
 	default:
 		error("Unknown game version %d", _systemVars->gameVersion);
@@ -578,6 +583,7 @@ bool SkyEngine::isCDVersion() {
 	case 365:
 	case 368:
 	case 372:
+	case 400:
 		return true;
 	default:
 		error("Unknown game version %d", _systemVars->gameVersion);
diff --git a/engines/sky/sound.cpp b/engines/sky/sound.cpp
index f532141332a..16d34c9bd86 100644
--- a/engines/sky/sound.cpp
+++ b/engines/sky/sound.cpp
@@ -23,6 +23,7 @@
 #include "common/debug.h"
 #include "common/endian.h"
 #include "common/textconsole.h"
+#include "common/config-manager.h"
 
 #include "sky/disk.h"
 #include "sky/logic.h"
@@ -1062,10 +1063,12 @@ void Sound::loadSection(uint8 pSection) {
 	} else
 		asmOfs = 0x7E;
 
-	if ((_soundData[asmOfs] != 0x3C) || (_soundData[asmOfs + 0x27] != 0x8D) ||
-		(_soundData[asmOfs + 0x28] != 0x1E) || (_soundData[asmOfs + 0x2F] != 0x8D) ||
-		(_soundData[asmOfs + 0x30] != 0x36))
-			error("Unknown sounddriver version");
+	if (ConfMan.get("gameid") != "ibass") {
+		if ((_soundData[asmOfs] != 0x3C) || (_soundData[asmOfs + 0x27] != 0x8D) ||
+			(_soundData[asmOfs + 0x28] != 0x1E) || (_soundData[asmOfs + 0x2F] != 0x8D) ||
+			(_soundData[asmOfs + 0x30] != 0x36))
+				error("Unknown sounddriver version");
+	}
 
 	_soundsTotal = _soundData[asmOfs + 1];
 	uint16 sRateTabOfs = READ_LE_UINT16(_soundData + asmOfs + 0x29);
diff --git a/engines/sky/text.cpp b/engines/sky/text.cpp
index 048d5edfac5..f225289137b 100644
--- a/engines/sky/text.cpp
+++ b/engines/sky/text.cpp
@@ -516,6 +516,8 @@ void Text::initHuffTree() {
 	case 372:
 		_huffTree = _huffTree_00372;
 		break;
+	case 400:
+		break;
 	default:
 		error("Unknown game version %d", SkyEngine::_systemVars->gameVersion);
 	}


Commit: b97b4dc390dd83fb3af3d66fe0bec554484a7c9a
    https://github.com/scummvm/scummvm/commit/b97b4dc390dd83fb3af3d66fe0bec554484a7c9a
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Load animations, overlay icons and port mouse input logic for ibass

Changed paths:
    engines/sky/compact.cpp
    engines/sky/disk.cpp
    engines/sky/disk.h
    engines/sky/logic.h
    engines/sky/mouse.cpp
    engines/sky/mouse.h
    engines/sky/screen.cpp
    engines/sky/screen.h
    engines/sky/sky.cpp
    engines/sky/sky.h
    engines/sky/sound.cpp
    engines/sky/struc.h
    engines/sky/text.cpp


diff --git a/engines/sky/compact.cpp b/engines/sky/compact.cpp
index 7e35015a214..432ee0712c7 100644
--- a/engines/sky/compact.cpp
+++ b/engines/sky/compact.cpp
@@ -463,6 +463,10 @@ void *SkyCompact::getCompactElem(Compact *cpt, uint16 off) {
 }
 
 uint8 *SkyCompact::createResetData(uint16 gameVersion) {
+	// fall back to actual cd version for ibass
+	if (gameVersion == 400)
+		gameVersion = 372;
+
 	_cptFile->seek(_resetDataPos);
 	uint32 dataSize = _cptFile->readUint16LE() * sizeof(uint16);
 	uint16 *resetBuf = (uint16 *)malloc(dataSize);
diff --git a/engines/sky/disk.cpp b/engines/sky/disk.cpp
index 8c24b33fb57..9dce4485357 100644
--- a/engines/sky/disk.cpp
+++ b/engines/sky/disk.cpp
@@ -47,7 +47,7 @@ static int hashCompFunc(const void *m1, const void *m2) {
 Disk::Disk() {
 	_dataDiskHandle = new Common::File();
 
-	if (ConfMan.get("gameid") == "ibass") {
+	if (SkyEngine::_isIbass()) {
 		if (!_dataDiskHandle->open("bass.dat"))
 			error("Error opening bass.dat");
 
@@ -104,12 +104,66 @@ Disk::~Disk() {
 	if (_dataDiskHandle->isOpen())
 		_dataDiskHandle->close();
 	fnFlushBuffers();
-	free(_dinnerTableArea);
+	if (!SkyEngine::_isIbass())
+		free(_dinnerTableArea);
 	delete _dataDiskHandle;
-	delete[] _entry;
+	if (SkyEngine::_isIbass())
+		delete[] _entry;
 	_entry = 0;
 }
 
+animation *Disk::loadAnim(const char *filename, const Graphics::PixelFormat &targetFormat) {
+	Common::File fp;
+
+	if (!fp.open(filename))
+		return 0;
+
+	animation *anim = new animation;
+
+	int num_frames;
+	int width;
+	int height;
+	char magic[4];
+
+	fp.read(magic, 4);
+	num_frames = fp.readUint32LE();
+	width = fp.readUint32LE();
+	height = fp.readUint32LE();
+
+	if (0 != strncmp(magic, "JPTX", 4) || width > 64 || height > 64)
+		error("Too large or invalid texture!\n");
+
+	if (num_frames >= MAX_FRAMES)
+		error("Too many frames (%d)\n", num_frames);
+
+	int scaledWidth = width  * 2 / 3;
+	int scaledHeight = height * 2 / 3;
+
+	anim->num_frames = num_frames;
+	anim->width = scaledWidth;
+	anim->height = scaledHeight;
+	anim->frames = new Graphics::Surface*[MAX_FRAMES];
+
+	for (int frame = 0; frame < num_frames; frame++) {
+		Graphics::Surface tempCanvas;
+		tempCanvas.create(width, height, Graphics::PixelFormat::createFormatRGBA32());
+		uint32 *tempPixels = (uint32 *)tempCanvas.getPixels();
+
+		int totalPixels = width * height;
+
+		for (int i = 0; i < totalPixels; i++)
+			tempPixels[i] = fp.readUint32LE();
+
+		Graphics::Surface *scaledCanvas = tempCanvas.scale(scaledWidth, scaledHeight);
+
+		anim->frames[frame] = scaledCanvas->convertTo(targetFormat);
+		scaledCanvas->free();
+		delete scaledCanvas;
+	}
+	fp.close();
+	return anim;
+}
+
 bool Disk::fileExists(uint16 fileNr) {
 	return (getFileInfo(fileNr) != NULL);
 }
@@ -123,7 +177,7 @@ fileEntry *Disk::getEntry(uint32 filenum) {
 // allocate memory, load the file and return a pointer
 uint8 *Disk::loadFile(uint16 fileNr) {
 
-	if (ConfMan.get("gameid") == "ibass") {
+	if (SkyEngine::_isIbass()) {
 		fileEntry *entry = getEntry(fileNr);
 		if (!entry) {
 			debug(1, "iBass: File %d not found!", fileNr);
@@ -395,7 +449,7 @@ void Disk::dumpFile(uint16 fileNr) {
 }
 
 uint32 Disk::determineGameVersion() {
-	if (ConfMan.get("gameid") == "ibass")
+	if (SkyEngine::_isIbass())
 		return 400; // force the ibass version and immediately exit the function
 
 	//determine game version based on number of entries in dinner table
diff --git a/engines/sky/disk.h b/engines/sky/disk.h
index 96ea61d3d31..579f5f3328f 100644
--- a/engines/sky/disk.h
+++ b/engines/sky/disk.h
@@ -26,8 +26,12 @@
 #include "common/scummsys.h"
 #include "common/compression/rnc_deco.h"
 
+#include "graphics/surface.h"
+
 #define MAX_FILES_IN_LIST 60
 
+#define MAX_FRAMES	16	//maximum number of frames per animation in ibass
+
 namespace Common {
 class File;
 }
@@ -42,6 +46,13 @@ struct fileEntry {
 
 namespace Sky {
 
+struct animation {
+	Graphics::Surface **frames;
+	int num_frames;
+	int width;
+	int height;
+};
+
 class Disk {
 public:
 	Disk();
@@ -62,6 +73,7 @@ public:
 	void fnFlushBuffers();
 	uint32 *giveLoadedFilesList() { return _loadedFilesList; }
 	void refreshFilesList(uint32 *list);
+	animation *loadAnim(const char *filename, const Graphics::PixelFormat &targetFormat);
 
 protected:
 	uint8 *getFileInfo(uint16 fileNr);
diff --git a/engines/sky/logic.h b/engines/sky/logic.h
index 43cacad9dd0..efe56d48c16 100644
--- a/engines/sky/logic.h
+++ b/engines/sky/logic.h
@@ -33,6 +33,7 @@ enum scriptVariableOffsets {
 	RESULT = 0,
 	SCREEN = 1,
 	LOGIC_LIST_NO = 2,
+	SAFE_LOGIC_LIST = 3,
 	MOUSE_LIST_NO = 6,
 	DRAW_LIST_NO = 8,
 	CUR_ID = 12,
@@ -58,10 +59,12 @@ enum scriptVariableOffsets {
 	GRID_3_ID = 47,
 	THE_CHOSEN_ONE = 51,
 	TEXT1 = 53,
+	FIRST_ICON = 99,
 	MENU_LENGTH = 100,
 	SCROLL_OFFSET = 101,
 	MENU = 102,
 	OBJECT_HELD = 103,
+	ICON_LIT = 104,
 	LAMB_GREET = 109,
 	RND = 115,
 	CUR_SECTION = 143,
@@ -153,6 +156,21 @@ public:
 	void initScreen0();
 	void parseSaveData(uint32 *data);
 
+	void Start_inventory(uint32	highlightedId = 0) {
+		//normal gameplay inv
+		fnStartMenu(_scriptVariables[FIRST_ICON],highlightedId,0);
+	}
+
+	uint32 *Give_inv_list() {
+		return &_objectList[0];
+	}
+
+	void KillInventory();
+
+	void BlankMouse() {
+		fnBlankMouse(0, 0, 0);
+	}
+
 private:
 	void setupLogicTable();
 	void setupMcodeTable();
diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index 50085a21e04..292f44a4479 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -20,13 +20,16 @@
  */
 
 
+#include "common/config-manager.h"
 #include "common/events.h"
 #include "common/system.h"
 #include "common/textconsole.h"
 #include "graphics/cursorman.h"
+#include "sky/control.h"
 #include "sky/disk.h"
 #include "sky/logic.h"
 #include "sky/mouse.h"
+#include "sky/screen.h"
 #include "sky/sky.h"
 #include "sky/skydefs.h"
 #include "sky/struc.h"
@@ -37,7 +40,6 @@ namespace Sky {
 #define MICE_FILE	60300
 #define NO_MAIN_OBJECTS	24
 #define NO_LINC_OBJECTS	21
-
 uint32 Mouse::_mouseMainObjects[24] = {
 	65,
 	9,
@@ -95,6 +97,7 @@ Mouse::Mouse(OSystem *system, Disk *skyDisk, SkyCompact *skyCompact) {
 	_system = system;
 	_mouseB = 0;
 	_currentCursor = 6;
+	_touchId = 0;
 	_mouseX = GAME_SCREEN_WIDTH / 2;
 	_mouseY = GAME_SCREEN_HEIGHT / 2;
 
@@ -102,9 +105,32 @@ Mouse::Mouse(OSystem *system, Disk *skyDisk, SkyCompact *skyCompact) {
 
 	//load in the object mouse file
 	_objectMouseData = _skyDisk->loadFile(MICE_FILE + 1);
+
+	resetUI();
+}
+
+void Mouse::resetUI() {
+	//popup
+	_clickedNum = 0;
+	_prevMouseOn = false;
+	_touchId = 0;
+	_holding = false;
+	_timeOn = 0;
+	_fadeOut = 0;
+	m_mode = Gameplay;//master ui mode
+	_isFloor = false;
+	_isExit = false;
+	_actionFlash = false;
+	_floorLock = false;
+
+	if (((SkyEngine *)g_engine)->getScreen()) {
+		((SkyEngine *)g_engine)->getScreen()->clearAllProximityIcons(false);
+		((SkyEngine *)g_engine)->getScreen()->clearAllIbassIcons(false);
+	}
+
 }
 
-Mouse::~Mouse( ){
+Mouse::~Mouse() {
 	free (_miceData);
 	free (_objectMouseData);
 }
@@ -118,6 +144,9 @@ bool Mouse::fnAddHuman() {
 	//reintroduce the mouse so that the human can control the player
 	//could still be switched out at high-level
 
+	if (m_mode == Gameplay)
+		m_mode = MustRelease;
+
 	if (!Logic::_scriptVariables[MOUSE_STOP]) {
 		Logic::_scriptVariables[MOUSE_STATUS] |= 6;	//cursor & mouse
 
@@ -202,6 +231,13 @@ void Mouse::waitMouseNotPressed(int minDelay) {
 void Mouse::spriteMouse(uint16 frameNum, uint8 mouseX, uint8 mouseY) {
 	_currentCursor = frameNum;
 
+	if (SkyEngine::_isIbass()) {
+		debug("ibass cursor path executed\n");
+		CursorMan.setDefaultArrowCursor();
+		CursorMan.showMouse(true);
+		return;
+	}
+
 	byte *newCursor = _miceData;
 	newCursor += ((DataFileHeader *)_miceData)->s_sp_size * frameNum;
 	newCursor += sizeof(DataFileHeader);
@@ -216,9 +252,72 @@ void Mouse::spriteMouse(uint16 frameNum, uint8 mouseX, uint8 mouseY) {
 		CursorMan.showMouse(true);
 }
 
+bool Mouse::IsUILive() {
+	if (!Logic::_scriptVariables[MOUSE_STOP] && (Logic::_scriptVariables[MOUSE_STATUS] & (1 << 1)) && (Logic::_scriptVariables[MOUSE_STATUS] & (1 << 2)) )
+		return	true;
+
+	return false;
+}
+
 void Mouse::mouseEngine() {
 	_logicClick = (_mouseB > 0); // click signal is available for Logic for one gamecycle
 
+	if (SkyEngine::_isIbass()) {
+		m_mode = Gameplay; // TODO: REMOVE THIS AFTER INTRO IS IMPLEMENTED
+		if (_actionFlash) {
+			_actionFlashTime--;
+			if (!_actionFlashTime)
+				_actionFlash = false;
+
+			if (!(_actionFlashTime & 1))
+				((SkyEngine *)g_engine)->getScreen()->clearIbassIcon(_actionFlashIcon, false);
+			else
+				((SkyEngine *)g_engine)->getScreen()->setIcon(_actionFlashIcon, _actionFlashX, _actionFlashY);
+		}
+
+		// if (!IsUILive())
+		// 	return;
+
+		switch (m_mode) {
+			case Alert_to_game:
+				if (!_mouseB)
+					return;
+
+				((SkyEngine *)g_engine)->getScreen()->hideInventory();
+				m_mode=MustRelease;
+				break;
+
+			case MustRelease:
+				if (_mouseB)
+					return;
+
+				resetUI();
+				m_mode=Gameplay;
+				break;
+
+			case Gameplay:
+				pointerEngine(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
+				if (Logic::_scriptVariables[MOUSE_STATUS] & (1 << 2))
+					buttonEngine1();
+				break;
+
+			case PreInventory:
+				if (_mouseB)
+					return;
+
+				m_mode=Inventory;
+				break;
+
+			case Inventory:
+			case InventoryUseOn:
+			case Text_chooser:
+				break;
+		}
+
+		_mouseB = 0;
+		return;
+	}
+
 	if (!Logic::_scriptVariables[MOUSE_STOP]) {
 		if (Logic::_scriptVariables[MOUSE_STATUS] & (1 << 1)) {
 			pointerEngine(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
@@ -229,7 +328,1022 @@ void Mouse::mouseEngine() {
 	_mouseB = 0;	//don't save up buttons
 }
 
+int Mouse::doProximityHighlights(uint16 xPos, uint16 yPos) {
+	uint32 currentListNum = Logic::_scriptVariables[MOUSE_LIST_NO];
+	uint16 *currentList;
+	int	midx,midy;
+	Compact *itemData;
+	uint16 itemNum;
+	int	found=0;
+	int	nearestDist=99999;
+	int	nearestId=0;
+	_nearestProximityIconId=0;
+
+	static int	proxFrame=0;
+	static int	proxFrameSpeed=0;
+
+	proxFrameSpeed++;
+	if	(proxFrameSpeed&1)
+		proxFrame++;
+	if	(proxFrame==3)
+		proxFrame=0;
+
+	//near inv button?
+	if (yPos>HOTSPOT_invy && xPos<HOTSPOT_invx)
+		return	0;
+
+	//not on same as last time, or was not on anything previously, so re-scan all objects
+	do {
+		currentList = (uint16 *)_skyCompact->fetchCpt(currentListNum);
+		while ((*currentList != 0) && (*currentList != 0xFFFF)) {
+			itemNum = *currentList;
+			itemData = _skyCompact->fetchCpt(itemNum);
+			currentList++;
+
+			if ((itemData->screen == Logic::_scriptVariables[SCREEN]) && (itemData->status & 16)) {
+				//hotspot, if a non-floor object
+				if (itemData->mouseOn && yPos > (20+TOP_LEFT_Y)) {
+					midx = giveXcood(itemData, itemNum);
+					midy = giveYcood(itemData, itemNum);
+
+					//skip very high hotspots - eg the old inventory catch object
+					if (midy < (TOP_LEFT_Y + 5))
+						continue;
+
+					//how far from finger?
+					int	d = abs(xPos - midx) + abs(yPos - midy);
+					if (d < GLOW_DIST) {
+						float opacity = 1.0 - ((d * 1.0) / GLOW_DIST);
+						((SkyEngine *)g_engine)->getScreen()->setProximityIcon(found++, midx - TOP_LEFT_X - 4, ((midy - TOP_LEFT_Y) - 4), opacity, proxFrame);
+					}
+
+					if (d < nearestDist) {
+						nearestDist = d;
+						nearestId = itemNum;
+						_nearestProximityIconId = (found - 1);
+					}
+				}
+			}
+		}
+		if (*currentList == 0xFFFF)
+			currentListNum = currentList[1];
+	}
+	while (*currentList != 0);
+
+	return	nearestId;
+}
+
+UIIcon Mouse::getInteractIcon(uint32 id) {
+
+	switch(id) {
+		case	70://screen 1 stairs
+		case	4119://elevator hole
+		case	8210://outside stairs to furnace
+			return	UI_ICON_DOWN;//
+
+		case	69://screen 1 stairs
+			return	UI_ICON_UP;//
+
+		case	1://joey
+		case	4122://hobbins
+		case	16://lamb
+		case	8324://guard
+		case	8211://sam
+		case	8301://norville
+		case	8544://clipboard man
+		case	136://power room man
+		case	12546://galagher
+		case	12442://insurance man
+		case	12430://anchor man
+		case	12407://dr burke
+		case	16516://henri
+		case	16601://guard
+		case	16441://piermont
+		case	16599://gameboy
+		case	16600://gardener
+		case	16701://barman
+		case	16772://babs
+		case	16737://man1
+		case	16731://man2
+//		case	20511://medi joey
+		case	20911://ken
+		case	137://anita
+	//	case	12407://patient
+		case	12289://mr cool
+		case	8205://rad suit man
+		case	8309://guard walkway
+		case	21014://father @ end
+			return	UI_ICON_MOUTH;//talk
+
+		case	4151://notice
+		case	4152://ledge-side notice
+		case	12383://sculpture
+		case	12388://mural
+		case	12386://poster
+		case	12387://ins poster
+		case	12378://surgery poster
+		case	12375://surgery poster
+		case	12376://surgery poster
+		case	12377://surgery poster
+		case	12401://dr poster
+		case	12402://dr poster
+		case	12545://ins poster
+		case	20678://crowbar on floor
+		case	12508://reich poster
+		case	12507://reich cert
+		case	12495://reich poster
+		case	8500://sensors
+		case	20576://medical computer monitor
+		case	20578://medical computer
+		case	8543://securty hq linc terminal
+			return	UI_ICON_LOOK;//look at
+
+		case	4113://sandwhich
+		case	4114://sandwhich
+		case	8://reich card
+		case	9://sunglasses
+		case	8442://key
+		case	8443://wd40
+		case	8446://putty
+		case	24642://linc item
+		case	24602://linc item
+		case	16501://secateurs
+		case	16747://glass
+		case	20527://brick
+		case	20660://tongs
+		case	71://anita card
+		case	49://dog biscuits
+		case	24638://linc
+		case	24639://linc
+		case	24604://linc
+		case	12588://light bulb
+		case	12501://magazine
+		case	12565://tour ticket
+		case	8517://reactor anita card??!
+		case	20526://plaster
+		case	24641://linc world tuning fork
+		case	24787://virus
+		case	12517://video
+		case	12434://anchor
+		case	12435://anchor
+			return	UI_ICON_HAND;
+	}
+
+	return	UI_ICON_USE;
+}
+
+bool Mouse::hasSingleInteractIcon(uint32 id) {
+	switch(id) {
+		case	1://joey
+		case	4122://hobbins
+		case	4151://notice
+		case	4152://ledge-side notice
+		case	16://lamb
+		case	8500://sensors
+		case	8324://guard
+		case	8211://sam
+		case	8301://norville
+		case	8544://clipboard man
+		case	136://power room man
+		case	12546://galagher
+		case	12383://sculpture
+		case	12442://insurance man
+		case	12388://mural
+		case	12386://ins poster
+		case	12387://ins poster
+		case	12430://anchor man
+		case	12378://surgery poster
+		case	12375://surgery poster
+		case	12376://surgery poster
+		case	12377://surgery poster
+		case	12407://dr burke
+		case	12401://dr poster
+		case	12402://dr poster
+		case	12545://ins poster
+		case	24810://linc window button
+		case	16516://henri
+		case	16601://guard
+		case	16441://piermont
+		case	16599://gameboy
+		case	16600://gardener
+		case	16701://barman
+		case	16772://babs
+		case	16737://man1
+		case	16731://man2
+//		case	20511://medi joey
+		case	20911://ken
+		case	137://anita
+		case	12508://reich poster
+		case	12507://reich cert
+		case	12495://reich poster
+//		case	12407://patient
+		case	12289://mr cool
+		case	8205://rad suit man
+		case	8309://guard walkway
+
+		case	20576://medical computer monitor
+		case	20578://medical computer
+
+		case	24586://linc maze
+		case	24592://linc maze
+		case	24633://linc maze
+		case	24634://linc maze
+		case	24593://linc maze
+		case	24594://linc maze
+		case	24595://linc maze
+		case	24598://linc maze
+		case	8543://securty hq linc terminal
+
+		case	69://screen 1 stairs
+		case	70://screen 1 stairs
+		case	4119://elevator hole
+		case	8210://outside stairs to furnace
+
+		case	21014://father @ end
+				return	true;
+	}
+
+	return	false;
+}
+
+uint16 Mouse::giveXcood(Compact *itemData, uint32 id) {
+	uint16 mid, midy;
+
+	mid = itemData->xcood + ((int16)itemData->mouseRelX) + (itemData->mouseSizeX >> 1);
+	midy = itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY >> 1);
+
+	if (mid < HOTSPOT_invx && midy > HOTSPOT_invy)
+		return	HOTSPOT_invx + 16;
+
+
+	//not lamb
+	if (id != 16) {
+		if	(mid > 428)
+			return	428;
+		if	(mid < 142)
+			return	142;
+	}
+
+	switch(id) {
+		case	4112:{mid=258;break;}//cupboard door
+		case	4113:{mid=254;break;}//sandwich
+		case	4114:{mid=254;break;}//spanner
+
+		case	12358:	{mid=428;break;}//bellevue - missing exit
+		case	12681:	{mid=428;break;}//bellevue
+		case	12349:	{mid=142;break;}//bellevue
+		case	12347:	{mid=428;break;}//bellevue
+		case	90:{mid=404;break;}//first room, door
+		case	97:{mid=190;break;}//ledge room, door
+		case	4116:{mid=269;break;}//elevator
+		case	4119:{mid=269;break;}//hole
+		case	4110:{mid=356;break;}//lathe
+		case	8248:{mid=357;break;}//walkway to security lobby
+		case	8238:{mid=181;break;}//walkway to power
+		case	8317:{mid=426;break;}//walkway to crash
+		case	8341:{mid=173;break;}//factory to walkway
+		case	8344:{mid=433;break;}//factory to factory 2
+		case	8500:{mid=224;break;}//sensors
+		case	8355:{mid=428;break;}//factory 2 to factory 3
+		case	8446:{mid=226;break;}//putty
+		case	8438:{mid=226;break;}//gangway
+		case	12680:{mid=201;break;}//exit
+		case	12679:{mid=307;break;}//exit
+		case	12678:{mid=179;break;}//exit
+		case	12677:{mid=319;break;}//exit
+		case	12324:{mid=191;break;}//exit
+		case	12336:{mid=182;break;}//exit
+		case	12442:{mid=376;break;}//exit
+		case	8483:{mid=225;break;}//console
+		case	12641:{mid=158;break;}//exit
+
+		//linc
+		case	12633:{mid=190;break;}//maze
+		case	24586:{mid=210;break;}//maze
+		case	24592:{mid=288;break;}//maze mid-bot
+		case	24593:{mid=400;break;}//maze mid-bot
+		case	24594:{mid=203;break;}//maze left-mid
+		case	24595:{mid=299;break;}//maze left-mid
+
+
+		//hyde
+		case	16496:{mid=263;break;}//plant
+		//cathedral
+		case	16462:{mid=168;break;}//exit
+
+		//lockers
+		case	16576:{mid=246;break;}//body == 16569
+		case	16577:{mid=271;break;}//body == 16570
+		case	16578:{mid=296;break;}//body == 16571
+		case	16579:{mid=321;break;}//body == 16572
+		case	16580:{mid=346;break;}//body == 16573
+
+		//underworld
+		case	20506:{mid=389;break;}//metal door
+		//pit room
+		case	20600:{mid=283;break;}//cover
+		case	20648:{mid=283;break;}//pit
+		case	20570:{mid=247;break;}//exit to medical droid room
+
+		case	20575:{mid=277;break;}//slot
+		case	20577:{mid=297;break;}//recharge unit
+
+		case	24786:{mid=288;break;}//linc crystal
+		case	24787:{mid=288;break;}//virus
+
+		case	20712:{mid=305;break;}//console
+		case	20713:{mid=356;break;}//console
+
+		case	20728:{mid=388;break;}//exit from door room
+
+		case	8272:{mid=278;break;}//power room chair
+
+		case	12390:{mid=187;break;}//burke door
+		case	12541:{mid=187;break;}//burke exit
+
+	}
+
+	return	mid;
+}
+
+uint16 Mouse::giveYcood(Compact *itemData, uint32 id) {
+	//push objects that are too far to left, or to the right, back onto the screen
+	uint16 mid;
+
+	mid=itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY>>1);
+
+	switch(id) {
+		case	4112: {//cupboard door - not if open
+			if	(Logic::_scriptVariables[112])//cupb_flag
+				return	0;
+			mid=221;
+			break;
+		}
+		case	4113:{mid=218;break;}//sandwich
+		case	4114:{mid=226;break;}//spanner
+
+		case	4108:{mid=0;break;}//remove monitor screen
+		case	4111:{mid=0;break;}//remove lazer
+		case	4115:{mid=0;break;}//remove monitor screen
+		case	4117:{mid=0;break;}//remove monitor screen
+		case	4154:{mid=0;break;}//remove right sign
+
+
+		case	12349:	{mid=TWEEKY_EXIT_ADJUST;break;}//bellevue
+		case	12347:	{mid=TWEEKY_EXIT_ADJUST;break;}//bellevue
+		case	12358:	{mid=TWEEKY_EXIT_ADJUST;break;}//bellevue
+		case	90:{mid=208;break;}//first room, door
+		case	97:{mid=216;break;}//ledge room, door
+		case	4116:{mid=259;break;}//elevator
+		case	4119:{mid=259;break;}//hole
+		case	4315:{mid=261;break;}//exit left from junk room
+		case	4103:{mid=242;break;}//exit right from junk room
+		case	4105:{mid=241;break;}//exit left from hobbins room
+		case	4110:{mid=230;break;}//lathe
+		case	8248:{mid=222;break;}//walkway to security lobby
+		case	8238:{mid=222;break;}//walkway to power
+		case	8310:{mid=222;break;}//walkway to first room
+		case	8246:{mid=273;break;}//power exit
+		case	8317:{mid=273;break;}//walkway to crash
+		case	8331:{mid=230;break;}//walkway to factory
+		case	8341:{mid=239;break;}//factory to walkway
+		case	8344:{mid=282;break;}//factory to factory 2
+		case	8500:{mid=197;break;}//sensors
+		case	8355:{mid=255;break;}//factory 2 to factory 3
+		case	8366:{mid=227;break;}//factory 2 to storeroom
+		case	8375:{mid=238;break;}//storeroom to factory 2
+		case	8446:{mid=247;break;}//putty
+		case	8438:{mid=247;break;}//gangway
+		case	8364:{mid=252;break;}//exit
+		case	8459:{mid=252;break;}//exit
+		case	8256:{mid=297;break;}//exit
+
+		//bellevue
+		case	12304:{mid=252;break;}//exit
+		case	12338:{mid=286;break;}//exit
+		case	12681:{mid=250;break;}//exit
+		case	12370:{mid=289;break;}//exit
+		case	12361:{mid=267;break;}//exit
+		case	12679:{mid=179;break;}//exit
+		case	12678:{mid=179;break;}//exit
+		case	12677:{mid=179;break;}//exit
+		case	12313:{mid=284;break;}//exit
+		case	12676:{mid=241;break;}//exit
+		case	12327:{mid=244;break;}//exit
+		case	12315:{mid=286;break;}//exit
+		case	12324:{mid=308;break;}//exit
+		case	12336:{mid=306;break;}//exit
+		case	12442:{mid=246;break;}//exit
+		case	12447:{mid=242;break;}//exit
+		case	12680:{mid=179;break;}//exit
+		case	12459:{mid=281;break;}//exit
+		case	12471:{mid=302;break;}//exit
+		case	12399:{mid=257;break;}//exit
+		case	12390:{mid=264;break;}//burke door
+		case	12541:{mid=264;break;}//burke exit
+
+		case	12630:{mid+=4;break;}//slot
+		case	12616:{mid+=4;break;}//slot
+		case	12629:{mid+=4;break;}//slot
+		case	12628:{mid+=4;break;}//slot
+		case	12627:{mid+=4;break;}//slot
+		case	12626:{mid+=4;break;}//slot
+
+		case	12620:{mid=220;break;}//locker
+		case	12621:{mid=220;break;}//locker
+		case	12622:{mid=220;break;}//locker
+		case	12623:{mid=220;break;}//locker
+		case	12613:{mid=220;break;}//locker
+		case	12624:{mid=220;break;}//locker
+
+		case	12631:{mid=273;break;}//exit
+		case	12641:{mid=290;break;}//exit
+		case	12642:{mid=273;break;}//exit
+
+		case	12474:{mid=282;break;}//lamb door
+		case	12486:{mid=298;break;}//lamb door
+
+		//security room
+		case	8295:{mid=299;break;}//exit
+
+		//hyde
+		case	16415:{mid=261;break;}//exit
+		case	16403:{mid=261;break;}//exit
+		case	16393:{mid=246;break;}//exit
+		case	16487:{mid=256;break;}//exit
+		case	16492:{mid=287;break;}//exit
+		case	16394:{mid=313;break;}//exit
+		case	16412:{mid=276;break;}//exit
+		case	16428:{mid=233;break;}//exit
+		case	16424:{mid=236;break;}//exit
+
+
+		//cathedral
+		case	16462:{mid=296;break;}//exit
+		case	16464:{mid=250;break;}//exit
+		case	16465:{mid=226;break;}//exit
+		case	16474:{mid=263;break;}//exit
+
+		case	16576:{mid=229;break;}//body == 16569
+		case	16577:{mid=229;break;}//body == 16570
+		case	16578:{mid=229;break;}//body == 16571
+		case	16579:{mid=229;break;}//body == 16572
+		case	16580:{mid=229;break;}//body == 16573
+
+		//reactor
+		case	8478:{mid=291;break;}//exit
+		case	8481:{mid=253;break;}//exit
+		case	8511:{mid=271;break;}//exit
+
+		//club
+		case	16538:{mid=279;break;}//exit
+
+		//abandoned subway
+		case	16439:{mid=267;break;}//exit
+
+		//entrance to underworld
+		case	16592:{mid=267;break;}//exit
+
+		//underworld
+		case	16649:{mid=291;break;}//exit
+		case	16660:{mid=285;break;}//exit
+		case	16662:{mid=254;break;}//exit
+		case	16661:{mid=291;break;}//exit
+		case	16671:{mid=291;break;}//exit
+		case	16681:{mid=282;break;}//exit
+		case	16682:{mid=282;break;}//exit
+		case	16719:{mid=287;break;}//exit
+		case	16720:{mid=287;break;}//exit
+		case	16729:{mid=291;break;}//exit
+		case	16730:{mid=301;break;}//exit
+		case	20506:{mid=276;break;}//metal door
+		//underworld main
+		case	20518:{mid=276;break;}//metal door
+		case	20532:{mid=264;break;}//exit
+		case	20558:{mid=296;break;}//exit
+		case	20598:{mid=237;break;}//exit
+		case	20601:{mid=183;break;}//metal bar
+		case	20600:{mid=237;break;}//cover
+		case	20648:{mid=237;break;}//pit
+		case	20570:{mid=268;break;}//exit to medical droid room
+
+		case	20573:{mid=290;break;}//droid room exit
+		case	20579:{mid=272;break;}//droid room exit
+		case	20572:{mid=277;break;}//droid room exit
+		case	20578:{mid=286;break;}//console
+		case	20674:{mid=279;break;}//droid room exit
+
+		case	20675:{mid=238;break;}//robot
+		case	20511:{mid=259;break;}//slot
+
+		case	20583:{mid=291;break;}//tank room exit
+		case	20604:{mid=264;break;}//tank room exit
+		case	20676:{mid=294;break;}//exit
+		case	20619:{mid=269;break;}//exit
+		case	20628:{mid=284;break;}//exit
+		case	20617:{mid=295;break;}//exit
+
+		case	24786:{mid=256;break;}//linc crystal
+		case	24787:{mid=256;break;}//linc crystal
+
+		case	20672:{mid=265;break;}//android room exit
+		case	20696:{mid=265;break;}//android room exit
+		case	20697:{mid=265;break;}//android room exit
+		case	20715:{mid=265;break;}//android room exit
+
+		case	20711:{mid=219;break;}//console
+		case	20712:{mid=219;break;}//console
+		case	20713:{mid=219;break;}//console
+
+		case	20725:{mid=268;break;}//exit
+
+		case	20726:{mid=270;break;}//exit from door room
+		case	20728:{mid=219;break;}//exit from door room
+
+		case	20741:{mid=254;break;}//exit from first vein room
+		case	20743:{mid=279;break;}//exit from first vein room
+		case	20752:{mid=279;break;}//exit near end
+		case	20886:{mid=243;break;}//exit orifice to linc
+
+		case	20874:{mid=0;break;}//pipe support - removed as appears to have no interaction
+
+		//linc
+		case	24592:{mid=306;break;}//maze mid-bot
+		case	24634:{mid=306;break;}//maze mid-bot
+//		case	24633:{mid=308;break;}//maze left-mid
+		case	24594:{mid=278;break;}//maze left-mid
+
+		case	8272:{mid=0;break;}//REMOVE power room chair
+
+		case	8290:
+		case	8291://power room switches
+		{
+			if	(!Logic::_scriptVariables[429])
+				return	0;
+		}
+	}
+
+
+	return	mid;
+}
+
+int Mouse::touchingFloor(uint16 xPos, uint16 yPos) {
+	uint32 currentListNum = Logic::_scriptVariables[MOUSE_LIST_NO];
+	uint16 *currentList;
+	Compact *itemData;
+	uint16 itemNum;
+
+	//do not detect floors beyond a certain depth
+	if	(yPos > (HOTSPOT_invy+8)) return 0;
+	if	(yPos<(20+TOP_LEFT_Y))	return 0;
+
+	do {
+		currentList = (uint16 *)_skyCompact->fetchCpt(currentListNum);
+		while ((*currentList != 0) && (*currentList != 0xFFFF)) {
+			itemNum = *currentList;
+			itemData = _skyCompact->fetchCpt(itemNum);
+			currentList++;
+
+			//on this screen, active, and a floor
+			if ((itemData->screen == Logic::_scriptVariables[SCREEN]) && (!itemData->mouseOn) && (itemData->status & 16)) {
+				if (itemData->xcood + ((int16)itemData->mouseRelX) > xPos) continue;
+				if (itemData->xcood + ((int16)itemData->mouseRelX) + itemData->mouseSizeX < xPos) continue;
+				if (itemData->ycood + ((int16)itemData->mouseRelY) > yPos) continue;
+				if (itemData->ycood + ((int16)itemData->mouseRelY) + itemData->mouseSizeY < yPos) continue;
+
+				//hit this floor - we're done here
+				return	itemNum;
+			}
+		}
+		if (*currentList == 0xFFFF)
+			currentListNum = currentList[1];
+	} while (*currentList != 0);
+
+	//found nowt
+	return	0;
+}
+
 void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
+
+	if (SkyEngine::_isIbass()) {
+		int midx, midy; //open hotspot dimensions
+		Compact *itemData;
+		int itemProx;
+		int d = 0;
+
+		debug("TOP: _mouseB = %d, _fadeout = %d", _mouseB, _fadeOut);
+
+		if (yPos < (TOP_LEFT_Y + 5))
+			return;
+
+		//mouse must be down to search for stuff
+		if (_mouseB) {
+			//debug("Clicked");
+			//what are we near?
+			itemProx = doProximityHighlights(xPos,yPos);
+
+			//seems we need to clear this, but only safe to do so when a new click occurs as player is still live when walking to interact after a use-on interaction
+			//but not in linc terminal
+			if	(101 != Logic::_scriptVariables[SCREEN])
+				Logic::_scriptVariables[OBJECT_HELD] = 0;
+
+			//need to check if still touching any currently popped up hotspot
+			if (_touchId && _touchId != 32767 && _timeOn < CLICK_THRESHOLD) {
+				if (_prevMouseOn == false)
+					_timeOn = 1;
+
+				//fetch the compact
+				itemData = _skyCompact->fetchCpt(_touchId);
+
+				//if not a floor
+				if (itemData->mouseOn) {
+					((SkyEngine *)g_engine)->getScreen()->setProximityNotAnimate(_nearestProximityIconId);//we want this one remaining one to not animate
+
+					midx = giveXcood(itemData, _touchId);
+					midy = giveYcood(itemData, _touchId);
+					//calc dist
+					d = abs(xPos - midx) + abs(yPos - midy);
+
+					//some left hand edge adjust for twin-hotspot non-exits
+					if (!hasSingleInteractIcon(_touchId) && !_isExit)
+						if ((midx - HOTSPOT_dim) < TOP_LEFT_X)
+							midx = TOP_LEFT_X + HOTSPOT_dim;
+
+					//still touching a normal hotspot?
+					if (!_isExit && midx - HOTSPOT_dim < xPos && midx + HOTSPOT_dim > xPos && midy - HOTSPOT_yoff < yPos && midy/*+HOTSPOT_yoff*/ > yPos) {
+						//if newly touching, and same item as last time, then inc the click count
+						if	(_prevMouseOn == false) {
+
+							_clickedNum++;	//one more click
+							//reset fade out timer to max
+							_fadeOut = HOTSPOT_FADEOUT;
+							//reset hover time
+							_timeOn = 1;
+						}
+						else
+							_timeOn++;
+
+						int	icony = midy - HOTSPOT_yoff;
+						icony -= TOP_LEFT_Y;//normalise for renderer
+						if (icony < 0)
+							icony = 0;
+
+						if (hasSingleInteractIcon(_touchId)) {
+							//update the coordinate of the hotspot
+							midx -= TOP_LEFT_X;
+							midx -= HOTSPOT_ExitDim;
+
+							//draw the icons
+							((SkyEngine *)g_engine)->getScreen()->setIcon( getInteractIcon(_touchId), midx+4, icony);
+							_actionFlashX = midx + 4;
+							_actionFlashIcon = getInteractIcon(_touchId);
+							_actionFlashY = icony;
+
+						} else { // 2 icons
+							midx -= TOP_LEFT_X;
+							midx -= HOTSPOT_dim;
+
+							_actionFlashY = icony;
+
+							if (xPos <= (midx + HOTSPOT_dim + TOP_LEFT_X)) {
+								Logic::_scriptVariables[BUTTON] = 2;
+								_actionFlashX = midx;
+								_actionFlashIcon = UI_ICON_LOOK;
+							} else {
+								Logic::_scriptVariables[BUTTON] = 1;
+								_actionFlashX = midx + HOTSPOT_dim + 4;
+								_actionFlashIcon = getInteractIcon(_touchId);
+							}
+						}
+
+						// mouse on
+						_prevMouseOn = true;
+
+						//end here, when button held on something
+						return;
+					} else if (_isExit && midx - HOTSPOT_dim < xPos && midx + HOTSPOT_dim > xPos && midy - HOTSPOT_yoff < yPos && midy/*+HOTSPOT_yoff*/ > yPos) {
+						//still touching the poped up exit
+						//which action
+						Logic::_scriptVariables[BUTTON] = 1;
+
+						//if newly touching, and same item as last time, then inc the click count
+						if (_prevMouseOn == false) {
+							_clickedNum++;	//one more click
+							//reset fade out timer to max
+							_fadeOut = HOTSPOT_FADEOUT;
+							//reset hover time
+							_timeOn = 0;
+						} else {
+							_timeOn++; // one more cycle
+							//update the coordinate of the hotspot
+							int	iconx = midx - HOTSPOT_ExitDim;
+							iconx -= TOP_LEFT_X;//normalise for renderer
+							if	(iconx < 0)
+								iconx = 0;
+
+							int	icony = midy - HOTSPOT_exit_yoff;
+							icony -= TOP_LEFT_Y;//normalise for renderer
+							if	(icony < 0)
+								icony = 0;
+
+							//draw the icon
+							initExitIcon(_exitType, iconx, icony);
+
+							_actionFlashY = icony;
+						}
+
+						//mouse on
+						_prevMouseOn=true;
+
+						//end here, when button held on something
+						return;
+					} else {
+						_touchId = 0;
+						_clickedNum = 0;
+					}
+				} else {// else if floor
+					//floors just count time - we only want clicks(jabs)
+					//still touching it?
+					if ((itemData->xcood + ((int16)itemData->mouseRelX) < xPos) && (itemData->xcood + ((int16)itemData->mouseRelX) + itemData->mouseSizeX > xPos) && (itemData->ycood + ((int16)itemData->mouseRelY) < yPos) && (itemData->ycood + ((int16)itemData->mouseRelY) + itemData->mouseSizeY > yPos))
+						_timeOn++;//one more cycle
+					else {
+						_touchId=0;
+						_clickedNum=0;
+					}
+				}
+			}
+			//find if we're touching a floor
+			int	floor = touchingFloor(xPos, yPos);
+
+			if (itemProx) {
+				itemData = _skyCompact->fetchCpt(itemProx);
+				midx=giveXcood(itemData, itemProx);	//->xcood + ((int16)itemData->mouseRelX) + (itemData->mouseSizeX>>1);
+				midy=giveYcood(itemData, itemProx);//itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY>>1);
+				//calc dist
+				d= abs(xPos-midx)+abs(yPos-midy);
+			}
+
+			//not close enough to real hotspot, and still touching previous floor
+			if (floor && (d >= USE_ON_DIST) && floor == _touchId)
+				//if we skip floor, and dont hit another hotspot, then we quit after this search, because there is no fadeOut on floors, so the system resets the couter
+				//floorSkip=true;
+				//continue;
+				return;
+
+			if ((itemProx && d < USE_ON_DIST) || floor) {
+				// we've hit a new object
+
+				//floor or object?
+				if (itemProx && d < USE_ON_DIST) {
+					//record what we're touching
+					Logic::_scriptVariables[SPECIAL_ITEM] = itemProx;//put in here now, for mouseOn script
+					_touchId = itemProx;
+					_touchIdLegacy = itemProx;	//remembered when mouse off
+				}
+				else {
+					//record what we're touching
+					Logic::_scriptVariables[SPECIAL_ITEM] = floor;//put in here now, for mouseOn script
+					_touchId = floor;
+					_touchIdLegacy = floor;	//remembered when mouse off
+				}
+
+				itemData = _skyCompact->fetchCpt(_touchId);
+
+				//jumping straight from one object to another?
+				if (Logic::_scriptVariables[SPECIAL_ITEM]) {
+					//remove hotspot icons
+					((SkyEngine *)g_engine)->getScreen()->clearAllIbassIcons(false);
+				}
+
+				//reset hover time to max
+				_timeOn = 1;
+				_clickedNum = 0;
+
+				//run previous items get-off, if there was one (gone straight from one object onto another!)
+				if (Logic::_scriptVariables[GET_OFF])
+					_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], itemData);
+
+				//write mouse off script number
+				Logic::_scriptVariables[GET_OFF] = itemData->mouseOff;
+
+				//run the mouse on script
+				if (itemData->mouseOn) {
+					//disallow sliding back onto floors
+					_floorLock = true;
+
+					//reset fade out timer
+					_fadeOut = HOTSPOT_FADEOUT;
+					debug("Fadeout det to 36, mouseOn = %d, dist = %d", itemData->mouseOn, d);
+
+					((SkyEngine *)g_engine)->getScreen()->setProximityNotAnimate(_nearestProximityIconId);//we want this one remaining one to not animate
+
+					//assume not
+					_isExit = false;
+					_isFloor = false;
+
+					_skyLogic->mouseScript(itemData->mouseOn, itemData);
+
+					//exit, or hotspot?
+					if (_isExit) {
+
+						int	iconx = midx - HOTSPOT_ExitDim;
+						iconx -= TOP_LEFT_X;//normalise for renderer
+						if (iconx < 0)
+							iconx = 0;
+
+						int	icony = midy - HOTSPOT_exit_yoff;
+						icony -= TOP_LEFT_Y;//normalise for renderer
+						if (icony < 0)
+							icony = 0;
+
+						//draw the icon
+						initExitIcon(_exitType, iconx, icony);
+					} else {
+						int	icony = midy - HOTSPOT_yoff;
+						icony -= TOP_LEFT_Y;//normalise for renderer
+						if (icony < 0)
+							icony = 0;
+
+						if (hasSingleInteractIcon(_touchId)) {
+							//update the coordinate of the hotspot
+							int	iconx = midx - HOTSPOT_ExitDim;
+							iconx -= TOP_LEFT_X;//normalise for renderer
+							if (iconx < 0)
+								iconx = 0;
+
+							//draw the icons
+
+							((SkyEngine *)g_engine)->getScreen()->setIcon( getInteractIcon(_touchId), iconx+4, icony);
+
+							if (_touchId == 70 || _touchId == 69 || _touchId == 24633 || _touchId == 24634 || _touchId == 4119 || _touchId == 8210)//stairs on screen 1 - normal object turned into exit - need to hack the button - the rest are either talk-to, which doesnt seem to matter, or look-at, like posters on walls
+								Logic::_scriptVariables[BUTTON] = 1;
+							else
+								Logic::_scriptVariables[BUTTON] = 2;
+
+						} else {	//2 icons
+							//update the coordinate of the hotspot
+							int	iconx = midx - HOTSPOT_dim;
+							iconx -= TOP_LEFT_X;//normalise for renderer
+							if (iconx < 0)
+								iconx = 0;
+
+							//draw the icons
+							((SkyEngine *)g_engine)->getScreen()->setIcon(UI_ICON_LOOK, iconx, icony);
+							((SkyEngine *)g_engine)->getScreen()->setIcon(getInteractIcon(_touchId), iconx+HOTSPOT_dim+4, icony);
+						}
+					}
+				} else if (!_floorLock) {//no mouseOn script, which probably always means this is a floor?
+					//set action
+					Logic::_scriptVariables[BUTTON] = 1;
+					//non graphical hotspots - floors - can interact first click
+					_clickedNum = 1;
+					//reset hover time to max
+					_timeOn = 1;
+					_isFloor = true;
+				} else
+					_touchId = 0; //locked floor
+
+				//mouse on
+				_prevMouseOn = true;
+				//we're done
+				return;
+			} else {
+				debug("nothing");
+				//not touching anything, force open hotspot to close
+				if (_fadeOut)
+					_fadeOut=0;
+			}
+			//not touching a game object - but what about HU buttons, such as Inv?
+			if (!_prevMouseOn && 101!=Logic::_scriptVariables[SCREEN] && Logic::_scriptVariables[LOGIC_LIST_NO]!=24765) {
+				if (xPos < HOTSPOT_invx && yPos > HOTSPOT_invy) {
+					// _system->playUISFX(UI_SOUND_MENU_INTO);
+					_skyLogic->Start_inventory();
+					_touchId = 0;
+					_holding = false;
+					m_mode = PreInventory;
+					((SkyEngine *)g_engine)->getScreen()->clearAllProximityIcons(false);
+					((SkyEngine *)g_engine)->getScreen()->clearAllIbassIcons(false);
+					return;
+				}
+				//control panel
+				if (xPos < HOTSPOT_optionsx && yPos < HOTSPOT_optionsy) {
+					//_system->playUISFX(UI_SOUND_MENU_INTO);
+					((SkyEngine *)g_engine)->getControl()->doControlPanel();
+					((SkyEngine *)g_engine)->getScreen()->clearAllProximityIcons(false);
+					((SkyEngine *)g_engine)->getScreen()->clearAllIbassIcons(false);
+					_mouseB = 0;
+				}
+				//help screen
+				if (xPos>HOTSPOT_helpx && yPos<HOTSPOT_helpy) {
+					//_system->playUISFX(UI_SOUND_MENU_INTO);
+					((SkyEngine *)g_engine)->getScreen()->clearAllProximityIcons(false);
+					((SkyEngine *)g_engine)->getScreen()->clearAllIbassIcons(false);
+					_mouseB = 0;
+				}
+			}
+
+			//mouse on
+			_prevMouseOn = true;
+
+
+			debug("floor returned = %d", floor);
+		} else { // not touching screen
+			if (_prevMouseOn) {
+
+				if (!_touchId || _isFloor)
+					((SkyEngine *)g_engine)->getScreen()->clearAllProximityIcons();
+
+				else if (_touchId) {
+					((SkyEngine *)g_engine)->getScreen()->clearAllProximityIcons();
+					//clear all but the one relating to the highlighted hotspot - hmmm
+					itemData = _skyCompact->fetchCpt(_touchId);
+					midx = giveXcood(itemData,_touchId);
+					midy = giveYcood(itemData,_touchId);//itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY>>1);
+					((SkyEngine *)g_engine)->getScreen()->setProximityIcon(0, midx-TOP_LEFT_X-4, ((midy-TOP_LEFT_Y)-4), 1.0, 0);
+					((SkyEngine *)g_engine)->getScreen()->setProximityNotAnimate(0);//we want this one remaining one to not animate
+				}
+			}
+
+			//let go
+			_prevMouseOn = false;
+			_floorLock = false;
+
+			//if 2nd or more click on this item
+			if (_timeOn && _clickedNum) {
+
+
+				//faking the click so that the engine scripts execute correctly
+				_logicClick = true;
+				if (Logic::_scriptVariables[BUTTON] == 0)
+					Logic::_scriptVariables[BUTTON] = 1;
+
+				//first, some autosaving incase this is a fatal, yes FATAL, interaction
+				if (g_engine->canSaveGameStateCurrently())
+					g_engine->saveGameState(0, "Autosave", true);
+
+				//an sfx
+				//Sky::g_engine->giveSystem()->playUISFX(UI_SOUND_MENU_ACK);
+				debug("WIPED");
+
+				_fadeOut = 0;	//force getOff script to run also
+
+				//setup action flash
+				if (!_isFloor) {
+					_actionFlash = true;
+					_actionFlashTime = ACTION_FLASH_TIME;
+				}
+				//set this again, as there's a chance some other random script may have cleared it since we first touched this hotspot
+				Logic::_scriptVariables[SPECIAL_ITEM] = _touchId;
+
+
+				//over anything?
+				Compact *item = _skyCompact->fetchCpt(Logic::_scriptVariables[SPECIAL_ITEM]);
+				if (item->mouseClick/* && item->cursorText*/)//not floors
+					_skyLogic->mouseScript(item->mouseClick, item);
+			}
+
+			//reset ready for next stab
+			_timeOn = 0;
+			//debug("Else block executed");
+		}
+
+		//mouse is not pressed, or not touching anything
+
+		//count down to fade out and run get-off
+		if (_fadeOut) {
+			_fadeOut--;
+			warning("_fadeout = %d, _touchIdLegacy: %d", _fadeOut, _touchIdLegacy);
+			//update coordinate, so hotspot follows walking megas
+			updateHotspotCoordinate(xPos);
+		}
+
+		if (!_fadeOut) {
+			((SkyEngine *)g_engine)->getScreen()->clearAllProximityIcons();
+
+			//reset number of times we clicked on this
+			_clickedNum=0;
+			_touchId=0;
+
+			//process get-off script, if we were touching, and there is one
+			if (Logic::_scriptVariables[SPECIAL_ITEM] != 0) {
+				//close the hotspot popup
+
+				//remove hotspot icons
+				((SkyEngine *)g_engine)->getScreen()->clearAllIbassIcons(true);
+
+				Logic::_scriptVariables[SPECIAL_ITEM] = 0;
+
+				//get off
+				if (Logic::_scriptVariables[GET_OFF])
+					_skyLogic->script((uint16)Logic::_scriptVariables[GET_OFF],(uint16)(Logic::_scriptVariables[GET_OFF] >> 16));
+
+				Logic::_scriptVariables[GET_OFF] = 0;
+			}
+		}
+		_mouseB = 0;
+		return;
+	}
+
 	uint32 currentListNum = Logic::_scriptVariables[MOUSE_LIST_NO];
 	uint16 *currentList;
 	do {
@@ -267,6 +1381,86 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 	}
 }
 
+void Mouse::initExitIcon(uint32 type, int iconx, int icony) {
+	switch(type) {
+		case MOUSE_LEFT: {
+			_actionFlashIcon = UI_ICON_LEFT;
+			_actionFlashX = iconx + 8;
+			((SkyEngine *)g_engine)->getScreen()->setIcon(UI_ICON_LEFT, iconx + 8, icony);
+			break;
+		}
+		case MOUSE_RIGHT: {
+			_actionFlashIcon = UI_ICON_RIGHT;
+			_actionFlashX = iconx + 4;
+			((SkyEngine *)g_engine)->getScreen()->setIcon(UI_ICON_RIGHT, iconx + 4, icony);
+			break;
+		}
+		case MOUSE_UP: {
+			_actionFlashIcon = UI_ICON_UP;
+			_actionFlashX = iconx + 5;
+			((SkyEngine *)g_engine)->getScreen()->setIcon(UI_ICON_UP, iconx + 5, icony);
+			break;
+		}
+		case MOUSE_DOWN: {
+			_actionFlashIcon = UI_ICON_DOWN;
+			_actionFlashX = iconx + 5;
+			((SkyEngine *)g_engine)->getScreen()->setIcon(UI_ICON_DOWN, iconx + 5, icony);
+			break;
+		}
+	}
+}
+
+void Mouse::updateHotspotCoordinate(uint16 xPos) {
+	Compact *itemData;
+	int	midx,  midy;
+
+	//fetch the compact
+	itemData = _skyCompact->fetchCpt(_touchIdLegacy);
+
+	if (!itemData)
+		return;
+
+	//if not a floor
+	if (itemData->mouseOn && !_isExit) {
+
+		midx = giveXcood(itemData,_touchIdLegacy);//itemData->xcood + ((int16)itemData->mouseRelX) + (itemData->mouseSizeX>>1);
+		midy = giveYcood(itemData,_touchIdLegacy);//itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY>>1);
+
+		int	icony = midy - HOTSPOT_yoff;
+		icony -= TOP_LEFT_Y;//normalise for renderer
+		if	(icony < 0)
+			icony = 0;
+
+		if	(hasSingleInteractIcon(_touchIdLegacy)) {
+			//update the coordinate of the hotspot
+			int	iconx = midx - HOTSPOT_ExitDim;
+			iconx -= TOP_LEFT_X;//normalise for renderer
+			if	(iconx < 0)
+				iconx = 0;
+
+			//draw the icons
+			((SkyEngine *)g_engine)->getScreen()->setIcon(getInteractIcon(_touchIdLegacy), iconx + 4, icony);
+		} else {
+			//update the coordinate of the hotspot
+			int	iconx = midx - HOTSPOT_dim;
+			iconx -= TOP_LEFT_X;//normalise for renderer
+			if	(iconx < 0)
+				iconx = 0;
+
+			//draw the icons
+			((SkyEngine *)g_engine)->getScreen()->setIcon(UI_ICON_LOOK, iconx, icony);
+			((SkyEngine *)g_engine)->getScreen()->setIcon(getInteractIcon(_touchIdLegacy), iconx + HOTSPOT_dim + 4, icony);
+
+			//still touching the poped up area
+			//which action
+			if (xPos <= midx)
+				Logic::_scriptVariables[BUTTON] = 2;
+			else
+				Logic::_scriptVariables[BUTTON] = 1;
+		}
+	}
+}
+
 void Mouse::buttonPressed(uint8 button) {
 	_mouseB = button;
 }
@@ -282,7 +1476,7 @@ void Mouse::buttonEngine1() {
 
 	if (_mouseB) {	//anything pressed?
 		Logic::_scriptVariables[BUTTON] = _mouseB;
-		if (Logic::_scriptVariables[SPECIAL_ITEM]) { //over anything?
+		if (Logic::_scriptVariables[SPECIAL_ITEM] && Logic::_scriptVariables[SPECIAL_ITEM] != 0xFFFFFFFF) { //over anything?
 			Compact *item = _skyCompact->fetchCpt(Logic::_scriptVariables[SPECIAL_ITEM]);
 			if (item->mouseClick)
 				_skyLogic->mouseScript(item->mouseClick, item);
diff --git a/engines/sky/mouse.h b/engines/sky/mouse.h
index 857830baa07..c4fa4738190 100644
--- a/engines/sky/mouse.h
+++ b/engines/sky/mouse.h
@@ -29,9 +29,62 @@ class OSystem;
 
 namespace Sky {
 
+//max click cycles before interact is not valid upon release
+#define	CLICK_THRESHOLD	10
+//cycles before inv use-on trigger
+#define USEON_THRESHOLD 5
+//time till hotspot fades out after stopped touching
+#define	HOTSPOT_FADEOUT	36
+//hotspot icon size
+#define HOTSPOT_dim	36
+//exit is just one icon, so half width as straddles centre point
+#define HOTSPOT_ExitDim (HOTSPOT_dim >> 1)
+//closed hotspot radius
+#define	HOTSPOT_RADx 8
+#define	HOTSPOT_RAD 16
+
+//how far the popup icons sit above the midy
+#define	HOTSPOT_yoff 48
+//differentiate exits, just incase
+#define HOTSPOT_exit_yoff 48
+
+//use on cursor offset
+#define HOTSPOT_useon_yoff (-55)
+
+//inv button (bottom left)
+#define HOTSPOT_invx (TOP_LEFT_X + 40)
+#define HOTSPOT_invy (TOP_LEFT_Y + FULL_SCREEN_HEIGHT-35)
+
+//control panel button (top left)
+#define HOTSPOT_optionsx (TOP_LEFT_X + 30)
+#define HOTSPOT_optionsy (TOP_LEFT_Y + 30)
+
+//help button (top right)
+#define HOTSPOT_helpx (TOP_LEFT_X + FULL_SCREEN_WIDTH-30)
+#define HOTSPOT_helpy (TOP_LEFT_Y + 30)
+
+//glow proximity
+#define GLOW_DIST 150
+//drag to use on distance
+#define	USE_ON_DIST	40
+
+//fix super deep exits
+#define	TWEEKY_EXIT_ADJUST (FULL_SCREEN_HEIGHT + TOP_LEFT_Y - 40);
+
+
+//inv item sizes
+#define	XWIDTH 32
+#define YDEPTH 32
+
+//action flash
+#define	ACTION_FLASH_TIME 7
+
 class Disk;
 class Logic;
 class SkyCompact;
+class Text;
+struct Compact;
+enum UIIcon : uint8;
 
 class Mouse {
 
@@ -61,6 +114,15 @@ public:
 	bool wasClicked();
 	void logicClick() { _logicClick = true; }
 	void resetCursor();
+	bool IsUILive();
+	void resetUI();
+	int	doProximityHighlights(uint16 xPos, uint16 yPos);
+	uint16 giveXcood(Compact *itemData, uint32 id);
+	uint16 giveYcood(Compact *itemData, uint32 id);
+	UIIcon getInteractIcon(uint32 id);
+	bool hasSingleInteractIcon(uint32 id);
+	void updateHotspotCoordinate(uint16 xPos);
+	int	touchingFloor(uint16 xPos, uint16 yPos);
 
 protected:
 
@@ -73,6 +135,38 @@ protected:
 	uint16 _mouseX;	//actual mouse coordinates
 	uint16 _mouseY;
 
+	int16	_mouseXOff;
+	int16	_mouseYOff;
+	uint16	_timeOn;//how long have we held on this item
+	uint16	_clickedNum;//remmebers what we clicked last
+	uint16	_fadeOut;//how long before current hotspot fades out when let go
+	bool	_prevMouseOn;//touching yes/no last cycle
+	uint16	_touchId;
+	uint16	_touchIdLegacy;
+	uint16	_hoverId;	//inv drag over inv
+	bool	_holding;
+	bool	_isExit;	//cur hotspot an exit?
+	uint32	_exitType;	//what type of exit
+	bool	_isFloor;
+	bool	_isLincInv;	//current inventory is in LINC which works weirdly differently
+	uint32	_lincMenuRef;	//used to check if a linc inv menu restarted the inv
+	uint16	_invYCoord;	//store inv item y coords ready for patching back in
+	int		_nearestProximityIconId;
+	bool	_floorLock;//stop moving off hotpots onto floors then releasing to get an interaction
+
+	uint16	_invX;//inventory bounds x
+	uint16	_invY;//inventory bounds y
+	uint16	_invW;//inventory bounds w
+	uint16	_invH;//inventory bounds h
+
+	bool	_actionFlash = false;	//clicked on action icon flasher
+	int		_actionFlashTime = 0;//counts down
+	int		_actionFlashIcon = 0;
+	int		_actionFlashX = 0;
+	int		_actionFlashY = 0;
+	void initExitIcon(uint32 type, int iconx, int icony);
+
+
 	uint16 _currentCursor;
 
 	byte *_miceData;	//address of mouse sprites
@@ -85,6 +179,17 @@ protected:
 	Disk *_skyDisk;
 	Logic *_skyLogic;
 	SkyCompact *_skyCompact;
+
+	enum : uint8 {
+		Gameplay,
+		PreInventory,
+		Inventory,
+		INV_temp_examine,
+		InventoryUseOn,
+		Text_chooser,
+		MustRelease,
+		Alert_to_game,//new game alert box
+	} m_mode;
 };
 
 } // End of namespace Sky
diff --git a/engines/sky/screen.cpp b/engines/sky/screen.cpp
index 924b7f39f6c..776ff630e38 100644
--- a/engines/sky/screen.cpp
+++ b/engines/sky/screen.cpp
@@ -60,6 +60,107 @@ uint8 Screen::_top16Colors[16*3] = {
 	63, 63, 63
 };
 
+void Screen::setIcon(int idx, int x, int y) {
+	if (idx < 0 || idx >= NUM_UI_ICONS)
+		return;
+
+	_uiIcon[idx].set(x, y);
+}
+
+void Screen::drawIbassIcon() {
+	for (int i = 0; i < NUM_UI_ICONS; i++) {
+		if (_uiIcon[i].visible) {
+
+			// if (_uiIcon[i].anim == nullptr)
+			// 	continue;
+
+			// get the current animation frame
+			Graphics::Surface *currentFrame = _uiIcon[i].anim->frames[_uiIcon[i].cur_frame];
+
+			_screen32.copyRectToSurfaceWithKey(*currentFrame, _uiIcon[i].x, _uiIcon[i].y, Common::Rect(currentFrame->w, currentFrame->h), _screen32.format.ARGBToColor(0x00, 0xFF, 0xFF, 0xFF));
+		}
+
+	}
+}
+
+void Screen::initIbassIcon(int idx, const char *filename) {
+	_uiIcon[idx].anim = _skyDisk->loadAnim(filename, _screen32.format);
+}
+
+void Screen::clearIbassIcon(int idx, bool fade = true) {
+	_uiIcon[idx].visible = false;
+	//_uiIcon[idx].x = _uiIcon[idx].y = 0;
+
+	if (!fade) {
+		_uiIcon[idx].alpha = 0.0f;
+	}
+}
+
+void Screen::setProximityIcon(int idx, int x, int y, float alpha, int frame) {
+	if (idx < 0 || idx >= NUM_PROXIMITY_ICONS)
+		return;
+
+	_proximityIcon[idx].set(x, y, alpha);
+	_proximityIcon[idx].animating = true;
+	_proximityIcon[idx].cur_frame = frame;
+}
+
+void Screen::setProximityNotAnimate(int idx) {
+	if (idx < 0 || idx >= NUM_PROXIMITY_ICONS)
+		return;
+
+	_proximityIcon[idx].animating = false;
+	_proximityIcon[idx].cur_frame = 2;
+}
+
+void Screen::clearAllIbassIcons(bool fade = true) {
+	for (int i = 0; i < NUM_UI_ICONS; i++)
+		clearIbassIcon(i, fade);
+
+}
+
+void Screen::clearProximityIcon(int idx, bool fade) {
+	if (idx < 0 || idx >= NUM_PROXIMITY_ICONS)
+		return;
+
+	_proximityIcon[idx].visible = false;
+
+	if (!fade)
+		_proximityIcon[idx].alpha = 0.0f;
+}
+
+void Screen::clearAllProximityIcons(bool fade) {
+	for (int i = 0; i < NUM_PROXIMITY_ICONS; i++) {
+		clearProximityIcon(i, fade);
+	}
+}
+
+bool Screen::isUIOpen() {
+	for (int i = 0; i < NUM_UI_ICONS; i++) {
+		if (_uiIcon[i].visible)
+			return true;
+	}
+	return false;
+}
+
+bool _invVisible;
+int _invX1;
+int _invY1;
+int _invX2;
+int _invY2;
+
+void Screen::showInventory(int x1, int y1, int x2, int y2) {
+	_invX1 = x1;
+	_invY1 = y1;
+	_invX2 = x2;
+	_invY2 = y2;
+	_invVisible = true;
+}
+
+void Screen::hideInventory(void) {
+	_invVisible = false;
+}
+
 Screen::Screen(OSystem *pSystem, Disk *pDisk, SkyCompact *skyCompact) {
 	_system = pSystem;
 	_skyDisk = pDisk;
@@ -74,6 +175,8 @@ Screen::Screen(OSystem *pSystem, Disk *pDisk, SkyCompact *skyCompact) {
 	_currentScreen = NULL;
 	_scrollScreen = NULL;
 
+	_screen32.create(GAME_SCREEN_WIDTH, FULL_SCREEN_HEIGHT, _system->getScreenFormat());
+
 	//blank the first 240 colors of the palette
 	memset(tmpPal, 0, GAME_COLORS * 3);
 
@@ -85,25 +188,95 @@ Screen::Screen(OSystem *pSystem, Disk *pDisk, SkyCompact *skyCompact) {
 	}
 
 	//set the palette
-	if (ConfMan.get("gameid") != "ibass")
+	if ((ConfMan.get("gameid") != "ibass") && _system->getScreenFormat().bytesPerPixel == 1)
 		_system->getPaletteManager()->setPalette(tmpPal, 0, VGA_COLORS);
 	_currentPalette = 0;
 
 	_seqInfo.nextFrame = _seqInfo.framesLeft = 0;
 	_seqInfo.seqData = _seqInfo.seqDataPos = NULL;
 	_seqInfo.running = false;
+
+	for (int i = 0; i < NUM_UI_ICONS; i++) {
+		_uiIcon[i].visible = false;
+		_uiIcon[i].anim = nullptr;
+		_uiIcon[i].x = 0;
+		_uiIcon[i].y = 0;
+		_uiIcon[i].alpha = 0.0f;
+	}
+
+	for (int i = 0; i < NUM_PROXIMITY_ICONS; i++) {
+		_proximityIcon[i].visible = false;
+		_proximityIcon[i].anim = nullptr;
+		_proximityIcon[i].x = 0;
+		_proximityIcon[i].y = 0;
+		_proximityIcon[i].alpha = 0.0f;
+	}
+
+	if (SkyEngine::_isIbass()) {
+		initIbassIcon(UI_ICON_LOOK, "eye.tex");
+		initIbassIcon(UI_ICON_USE, "cogs.tex");
+		initIbassIcon(UI_ICON_HAND, "hand.tex");
+		initIbassIcon(UI_ICON_MOUTH, "mouth.tex");
+		initIbassIcon(UI_ICON_HELP, "hints.tex");
+		initIbassIcon(UI_ICON_INV, "inventory.tex");
+		initIbassIcon(UI_ICON_OPTIONS, "options.tex");
+		initIbassIcon(UI_ICON_UP, "exit_up.tex");
+		initIbassIcon(UI_ICON_DOWN, "exit_down.tex");
+		initIbassIcon(UI_ICON_LEFT, "exit_left.tex");
+		initIbassIcon(UI_ICON_RIGHT, "exit_right.tex");
+	}
 }
 
 Screen::~Screen() {
 	free(_gameGrid);
 	free(_currentScreen);
 	free(_scrollScreen);
+	_screen32.free();
+	_iconSurface.free();
+}
+
+void Screen::update32BitScreen() {
+	if (!_currentScreen)
+		return;
+
+	uint32 *dstPixels = (uint32 *)_screen32.getPixels();
+	uint32 dstPitch = _screen32.pitch / 4;
+
+	for (int y = 0; y < GAME_SCREEN_HEIGHT; y++) {
+		uint8 *srcRow = _currentScreen + (y * GAME_SCREEN_WIDTH);
+		uint32 *dstRow = dstPixels + (y * dstPitch);
+
+		for (int x = 0; x < GAME_SCREEN_WIDTH; x++) {
+			uint8 colorIdx = srcRow[x];
+
+			uint8 r = _palette[colorIdx * 3 + 0];
+			uint8 g = _palette[colorIdx * 3 + 1];
+			uint8 b = _palette[colorIdx * 3 + 2];
+
+			dstRow[x] = _screen32.format.RGBToColor(r, g, b);
+		}
+	}
+}
+
+void Screen::renderFinalFrame() {
+	update32BitScreen();
+
+	drawIbassIcon();
+
+	if (_screen32.getPixels()) {
+		_system->copyRectToScreen(_screen32.getPixels(), _screen32.pitch, 0, 0, _screen32.w, _screen32.h);
+		_system->updateScreen();
+	}
 }
 
 void Screen::clearScreen(bool fullscreen) {
-	memset(_currentScreen, 0, FULL_SCREEN_WIDTH * FULL_SCREEN_HEIGHT);
-	_system->copyRectToScreen(_currentScreen, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, fullscreen ? FULL_SCREEN_HEIGHT : GAME_SCREEN_HEIGHT);
-	_system->updateScreen();
+	if (!_currentScreen)
+		_currentScreen = (uint8 *)malloc(FULL_SCREEN_WIDTH * FULL_SCREEN_HEIGHT);
+
+	if (_currentScreen)
+		memset(_currentScreen, 0, FULL_SCREEN_WIDTH * FULL_SCREEN_HEIGHT);
+
+	renderFinalFrame();
 }
 
 void Screen::setFocusRectangle(const Common::Rect& rect) {
@@ -113,7 +286,7 @@ void Screen::setFocusRectangle(const Common::Rect& rect) {
 //set a new palette, pal is a pointer to dos vga rgb components 0..63
 void Screen::setPalette(uint8 *pal) {
 	convertPalette(pal, _palette);
-	if (ConfMan.get("gameid") != "ibass")
+	if ((ConfMan.get("gameid") != "ibass") && _system->getScreenFormat().bytesPerPixel == 1)
 		_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
 	_system->updateScreen();
 }
@@ -127,7 +300,7 @@ void Screen::setPaletteEndian(uint8 *pal) {
 #else
 	convertPalette(pal, _palette);
 #endif
-	if (ConfMan.get("gameid") != "ibass")
+	if ((ConfMan.get("gameid") != "ibass") && _system->getScreenFormat().bytesPerPixel == 1)
 		_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
 	_system->updateScreen();
 }
@@ -140,7 +313,7 @@ void Screen::halvePalette() {
 		halfPalette[cnt * 3 + 1] = _palette[cnt * 3 + 1] >> 1;
 		halfPalette[cnt * 3 + 2] = _palette[cnt * 3 + 2] >> 1;
 	}
-	if (ConfMan.get("gameid") != "ibass")
+	if ((ConfMan.get("gameid") != "ibass") && _system->getScreenFormat().bytesPerPixel == 1)
 		_system->getPaletteManager()->setPalette(halfPalette, 0, GAME_COLORS);
 }
 
@@ -155,7 +328,7 @@ void Screen::setPalette(uint16 fileNum) {
 
   void Screen::showScreen(uint16 fileNum, bool fullscreen) {
 
-	if (ConfMan.get("gameid") != "ibass") {
+	if (SkyEngine::_isIbass()) {
 		uint8 *imgData = _skyDisk->loadFile(fileNum);
 
 		if (imgData) {
@@ -168,8 +341,7 @@ void Screen::setPalette(uint16 fileNum) {
 				_currentScreen = (uint8 *)malloc(surface->pitch * surface->h);
 				memcpy(_currentScreen, surface->getPixels(), surface->w * surface->h);
 
-				_system->copyRectToScreen(_currentScreen, surface->pitch, 0, 0, surface->pitch, surface->h);
-				_system->updateScreen();
+				renderFinalFrame();
 				free(imgData);
 				return;
 			}
@@ -178,7 +350,7 @@ void Screen::setPalette(uint16 fileNum) {
 		// This is only used for static images in the floppy and cd intro
 		free(_currentScreen);
 		_currentScreen = _skyDisk->loadFile(fileNum);
-		if (!fullscreen) {
+		if (!fullscreen && _currentScreen) {
 			// make sure the last 8 lines are forced to black.
 			memset(_currentScreen + GAME_SCREEN_HEIGHT * GAME_SCREEN_WIDTH, 0, (FULL_SCREEN_HEIGHT - GAME_SCREEN_HEIGHT) * GAME_SCREEN_WIDTH);
 		}
@@ -191,8 +363,7 @@ void Screen::setPalette(uint16 fileNum) {
 }
 
 void Screen::showScreen(uint8 *pScreen, bool fullscreen) {
-	_system->copyRectToScreen(pScreen, 320, 0, 0, GAME_SCREEN_WIDTH, fullscreen ? FULL_SCREEN_HEIGHT : GAME_SCREEN_HEIGHT);
-	_system->updateScreen();
+	renderFinalFrame();
 }
 
 //convert 3 byte 0..63 rgb to 3 byte 0..255 rgb
@@ -240,27 +411,24 @@ void Screen::recreate() {
 }
 
 void Screen::flip(bool doUpdate) {
-	uint32 copyX, copyWidth;
-	copyX = copyWidth = 0;
+	bool isDirty = false;
+
+	// just clear the dirty grid flags and detect if anything changed
 	for (uint8 cnty = 0; cnty < GRID_Y; cnty++) {
 		for (uint8 cntx = 0; cntx < GRID_X; cntx++) {
 			if (_gameGrid[cnty * GRID_X + cntx] & 1) {
 				_gameGrid[cnty * GRID_X + cntx] &= ~1;
-				if (!copyWidth)
-					copyX = cntx * GRID_W;
-				copyWidth += GRID_W;
-			} else if (copyWidth) {
-				_system->copyRectToScreen(_currentScreen + cnty * GRID_H * GAME_SCREEN_WIDTH + copyX, GAME_SCREEN_WIDTH, copyX, cnty * GRID_H, copyWidth, GRID_H);
-				copyWidth = 0;
+				isDirty = true;
 			}
 		}
-		if (copyWidth) {
-			_system->copyRectToScreen(_currentScreen + cnty * GRID_H * GAME_SCREEN_WIDTH + copyX, GAME_SCREEN_WIDTH, copyX, cnty * GRID_H, copyWidth, GRID_H);
-			copyWidth = 0;
-		}
 	}
-	if (doUpdate)
+
+	// only perform the 32-bit conversion ONCE per frame
+	if (isDirty || isUIOpen()) {
+		renderFinalFrame();
+	} else if (doUpdate) {
 		_system->updateScreen();
+	}
 }
 
 void Screen::fnDrawScreen(uint32 palette, uint32 scroll) {
@@ -279,7 +447,7 @@ void Screen::fnFadeDown(uint32 scroll) {
 		for (uint8 cnt = 0; cnt < 32; cnt++) {
 			delayTime += 20;
 			palette_fadedown_helper(_palette, GAME_COLORS);
-			if (ConfMan.get("gameid") != "ibass")
+			if ((ConfMan.get("gameid") != "ibass") && _system->getScreenFormat().bytesPerPixel == 1)
 				_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
 			_system->updateScreen();
 			int32 waitTime = (int32)delayTime - _system->getMillis();
@@ -319,12 +487,14 @@ void Screen::palette_fadedown_helper(uint8 *pal, uint num) {
 }
 
 void Screen::paletteFadeUp(uint16 fileNr) {
-	uint8 *pal = _skyDisk->loadFile(fileNr);
-	if (pal) {
-		paletteFadeUp(pal);
-		free(pal);
-	} else
-		warning("Screen::paletteFadeUp: Can't load palette #%d",fileNr);
+	if (!SkyEngine::_isIbass()) {
+		uint8 *pal = _skyDisk->loadFile(fileNr);
+		if (pal) {
+			paletteFadeUp(pal);
+			free(pal);
+		} else
+			warning("Screen::paletteFadeUp: Can't load palette #%d",fileNr);
+	}
 }
 
 void Screen::paletteFadeUp(uint8 *pal) {
@@ -341,7 +511,7 @@ void Screen::paletteFadeUp(uint8 *pal) {
 			_palette[colCnt * 3 + 1] = (tmpPal[colCnt * 3 + 1] * cnt) >> 5;
 			_palette[colCnt * 3 + 2] = (tmpPal[colCnt * 3 + 2] * cnt) >> 5;
 		}
-		if (ConfMan.get("gameid") != "ibass")
+		if ((ConfMan.get("gameid") != "ibass") && _system->getScreenFormat().bytesPerPixel == 1)
 			_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
 		_system->updateScreen();
 
@@ -534,14 +704,14 @@ void Screen::processSequence() {
 				}
 				rectWid++;
 			} else if (rectWid) {
-				_system->copyRectToScreen(rectPtr, GAME_SCREEN_WIDTH, rectX << 4, rectY << 4, rectWid << 4, 16);
+				renderFinalFrame();
 				rectWid = 0;
 			}
 			scrPtr += 16;
 			gridPtr++;
 		}
 		if (rectWid) {
-			_system->copyRectToScreen(rectPtr, GAME_SCREEN_WIDTH, rectX << 4, rectY << 4, rectWid << 4, 16);
+			renderFinalFrame();
 			rectWid = 0;
 		}
 		scrPtr += 15 * GAME_SCREEN_WIDTH;
@@ -848,7 +1018,7 @@ void Screen::showGrid(uint8 *gridBuf) {
 			gridData <<= 1;
 		}
 	}
-	_system->copyRectToScreen(_currentScreen, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, GAME_SCREEN_HEIGHT);
+	renderFinalFrame();
 
 }
 
diff --git a/engines/sky/screen.h b/engines/sky/screen.h
index 055e988c235..11dbd48f1d3 100644
--- a/engines/sky/screen.h
+++ b/engines/sky/screen.h
@@ -25,6 +25,9 @@
 
 #include "common/scummsys.h"
 #include "sky/skydefs.h"
+#include "sky/struc.h"
+
+#include "graphics/surface.h"
 
 class OSystem;
 
@@ -39,6 +42,7 @@ class SkyEngine;
 class SkyCompact;
 struct Compact;
 struct DataFileHeader;
+struct Icon;
 
 #define SCROLL_JUMP		16
 #define VGA_COLORS		256
@@ -46,6 +50,9 @@ struct DataFileHeader;
 
 #define FORE 1
 #define BACK 0
+#define NUM_INV_ANIMS	44	//unique textures
+#define NUM_INV_ICONS	20	//(max) number of on-screen items
+#define NUM_PROXIMITY_ICONS 16	//(max) number of proximity icons
 
 typedef struct {
 	uint16 yCood;
@@ -53,6 +60,21 @@ typedef struct {
 	DataFileHeader *sprite;
 } StSortList;
 
+enum UIIcon : uint8{
+	UI_ICON_INV = 0,
+	UI_ICON_LOOK,
+	UI_ICON_USE,
+	UI_ICON_HAND,
+	UI_ICON_MOUTH,
+	UI_ICON_HELP,
+	UI_ICON_OPTIONS,
+	UI_ICON_UP,
+	UI_ICON_DOWN,
+	UI_ICON_LEFT,
+	UI_ICON_RIGHT,
+	NUM_UI_ICONS
+};
+
 class Screen {
 public:
 	Screen(OSystem *pSystem, Disk *pDisk, SkyCompact *skyCompact);
@@ -92,6 +114,28 @@ public:
 
 	void paintBox(uint16 x, uint16 y);
 	void showGrid(uint8 *gridBuf);
+	Graphics::Surface _screen32;
+	Graphics::Surface _iconSurface;
+	void renderFinalFrame();
+	void update32BitScreen();
+	Icon _uiIcon[NUM_UI_ICONS];
+	Icon _proximityIcon[NUM_PROXIMITY_ICONS];
+	Icon _invIcon[NUM_INV_ICONS];
+
+	void setIcon(int idx, int x, int y);
+	void drawIbassIcon();
+	void initIbassIcon(int idx, const char *filename);
+	void clearIbassIcon(int idx, bool fade);
+	void clearAllIbassIcons(bool fade);
+
+	bool isUIOpen();
+	void showInventory(int x1, int y1, int x2, int y2);
+	void hideInventory(void);
+
+	void setProximityIcon(int idx, int x, int y, float alpha, int frame);
+	void clearAllProximityIcons(bool fade = true);
+	void clearProximityIcon(int idx, bool fade = true);
+	void setProximityNotAnimate(int idx);
 
 private:
 	OSystem *_system;
diff --git a/engines/sky/sky.cpp b/engines/sky/sky.cpp
index f26ce1e935c..53420dbe874 100644
--- a/engines/sky/sky.cpp
+++ b/engines/sky/sky.cpp
@@ -170,6 +170,10 @@ void SkyEngine::handleKey() {
 			break;
 
 		case kSkyActionOpenControlPanel:
+			if (SkyEngine::_isIbass()) {
+				openMainMenuDialog();
+				break;
+			}
 			_skyControl->doControlPanel();
 			break;
 
@@ -212,12 +216,13 @@ Common::Error SkyEngine::go() {
 		// Clear pastIntro here (set to false) explicilty
 		// It should be false already, but better to ensure it
 		_systemVars->pastIntro = false;
-		if (_systemVars->gameVersion > 272) { // don't do intro for floppydemos
+		if (_systemVars->gameVersion > 272 && ConfMan.get("gameid") != "ibass") { // don't do intro for floppydemos
 			Intro *skyIntro = new Intro(_skyDisk, _skyScreen, _skyMusic, _skySound, _skyText, _mixer, _system);
 			bool floppyIntro = ConfMan.getBool("alt_intro");
 			introSkipped = !skyIntro->doIntro(floppyIntro);
 			delete skyIntro;
-		}
+		} else if (SkyEngine::_isIbass())
+			introSkipped = true;
 
 		if (!shouldQuit()) {
 			_skyScreen->clearScreen(true);
@@ -345,11 +350,8 @@ bool SkyEngine::loadChineseTraditional() {
 }
 
 Common::Error SkyEngine::init() {
-	if (ConfMan.get("gameid") == "ibass") {
-		Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0);
-		initGraphics(640, 480, &format);
-	} else
-		initGraphics(320, 200);
+	Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0);
+	initGraphics(320, 200, &format);
 
 	_skyDisk = new Disk();
 	_skySound = new Sound(_mixer, _skyDisk, Audio::Mixer::kMaxChannelVolume);
@@ -590,4 +592,10 @@ bool SkyEngine::isCDVersion() {
 	}
 }
 
+bool SkyEngine::_isIbass() {
+	if (ConfMan.get("gameid") == "ibass")
+		return true;
+	return false;
+}
+
 } // End of namespace Sky
diff --git a/engines/sky/sky.h b/engines/sky/sky.h
index 51fcc649d0d..8f6fcfe7047 100644
--- a/engines/sky/sky.h
+++ b/engines/sky/sky.h
@@ -99,6 +99,7 @@ public:
 
 	static bool isDemo();
 	static bool isCDVersion();
+	static bool _isIbass();
 
 	Common::Error loadGameState(int slot) override;
 	Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
@@ -108,6 +109,14 @@ public:
 		return Common::String::format("SKY-VM.%03d", slot);
 	}
 
+	Screen *getScreen() {
+		return _skyScreen;
+	}
+
+	Control *getControl() {
+		return _skyControl;
+	}
+
 	static void *fetchItem(uint32 num);
 	static void *_itemList[300];
 	static SystemVars *_systemVars;
@@ -116,6 +125,9 @@ public:
 	char *_chineseTraditionalBlock;
 	Graphics::Big5Font *_big5Font;
 
+	bool canSaveGameStateCurrently();
+	int	giveCurrentScreen();
+
 protected:
 	// Engine APIs
 	Common::Error init();
diff --git a/engines/sky/sound.cpp b/engines/sky/sound.cpp
index 16d34c9bd86..b799f520ce4 100644
--- a/engines/sky/sound.cpp
+++ b/engines/sky/sound.cpp
@@ -1063,7 +1063,7 @@ void Sound::loadSection(uint8 pSection) {
 	} else
 		asmOfs = 0x7E;
 
-	if (ConfMan.get("gameid") != "ibass") {
+	if (!SkyEngine::_isIbass()) {
 		if ((_soundData[asmOfs] != 0x3C) || (_soundData[asmOfs + 0x27] != 0x8D) ||
 			(_soundData[asmOfs + 0x28] != 0x1E) || (_soundData[asmOfs + 0x2F] != 0x8D) ||
 			(_soundData[asmOfs + 0x30] != 0x36))
diff --git a/engines/sky/struc.h b/engines/sky/struc.h
index 602599aba99..8367f51a018 100644
--- a/engines/sky/struc.h
+++ b/engines/sky/struc.h
@@ -48,6 +48,40 @@ struct DataFileHeader {
 	uint16 s_compressed_size;
 } PACKED_STRUCT;
 
+struct animation;
+
+struct Icon {
+	int x;
+	int y;
+	bool visible;
+	bool animating;
+	animation *anim;
+	int cur_frame;
+	int tick;
+	float alpha;
+
+	Icon() {
+		reset();
+	}
+
+	void reset(void) {
+		visible = false;
+		animating = true;
+		anim = 0;
+		cur_frame = 0;
+		tick = 0;
+		x = y = 0;
+		alpha = 0.0f;
+	}
+
+	void set(int xPos, int yPos, float alphaVal = 1.0f) {
+		x = xPos;
+		y = yPos;
+		visible = true;
+		alpha = alphaVal;
+	}
+};
+
 struct TurnTable {
 	uint16 turnTableUp[5];
 	uint16 turnTableDown[5];
diff --git a/engines/sky/text.cpp b/engines/sky/text.cpp
index f225289137b..d013ebf466b 100644
--- a/engines/sky/text.cpp
+++ b/engines/sky/text.cpp
@@ -23,6 +23,7 @@
 #include "common/debug.h"
 #include "common/endian.h"
 #include "common/textconsole.h"
+#include "common/config-manager.h"
 
 #include "sky/disk.h"
 #include "sky/logic.h"
@@ -514,9 +515,8 @@ void Text::initHuffTree() {
 		_huffTree = _huffTree_00368;
 		break;
 	case 372:
-		_huffTree = _huffTree_00372;
-		break;
 	case 400:
+		_huffTree = _huffTree_00372;
 		break;
 	default:
 		error("Unknown game version %d", SkyEngine::_systemVars->gameVersion);


Commit: 20c9c684fbdb27cc6f24ff730fe2ed373e3f56fa
    https://github.com/scummvm/scummvm/commit/20c9c684fbdb27cc6f24ff730fe2ed373e3f56fa
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Implement inventory logic in ibass

Changed paths:
  A engines/sky/inventory.cpp
    engines/sky/compact.cpp
    engines/sky/detection.cpp
    engines/sky/disk.cpp
    engines/sky/disk.h
    engines/sky/logic.cpp
    engines/sky/logic.h
    engines/sky/module.mk
    engines/sky/mouse.cpp
    engines/sky/mouse.h
    engines/sky/screen.cpp
    engines/sky/screen.h
    engines/sky/sky.cpp
    engines/sky/sky.h
    engines/sky/sound.cpp
    engines/sky/struc.h
    engines/sky/text.cpp


diff --git a/engines/sky/compact.cpp b/engines/sky/compact.cpp
index 432ee0712c7..7e35015a214 100644
--- a/engines/sky/compact.cpp
+++ b/engines/sky/compact.cpp
@@ -463,10 +463,6 @@ void *SkyCompact::getCompactElem(Compact *cpt, uint16 off) {
 }
 
 uint8 *SkyCompact::createResetData(uint16 gameVersion) {
-	// fall back to actual cd version for ibass
-	if (gameVersion == 400)
-		gameVersion = 372;
-
 	_cptFile->seek(_resetDataPos);
 	uint32 dataSize = _cptFile->readUint16LE() * sizeof(uint16);
 	uint16 *resetBuf = (uint16 *)malloc(dataSize);
diff --git a/engines/sky/detection.cpp b/engines/sky/detection.cpp
index 5be37983f61..b518bd654c3 100644
--- a/engines/sky/detection.cpp
+++ b/engines/sky/detection.cpp
@@ -122,7 +122,7 @@ DetectedGames SkyMetaEngineDetection::detectGames(const Common::FSList &fslist,
 	bool hasSkyDnr = false;
 	int dinnerTableEntries = -1;
 	int dataDiskSize = -1;
-	bool hasibassDat = false;
+	bool hasIbassDat = false;
 	int ibassDiskSize = -1;
 	Common::String dataDiskHeadMD5 = "";
 	int exeSize = -1; 
@@ -156,9 +156,9 @@ DetectedGames SkyMetaEngineDetection::detectGames(const Common::FSList &fslist,
 			if (0 == scumm_stricmp("bass.dat", file->getName().c_str())) {
 				Common::File ibassDisk;
 				if (ibassDisk.open(*file)) {
-					hasibassDat = true;
+					hasIbassDat = true;
 					ibassDiskSize = ibassDisk.size();
-					if (ibassDiskSize == 9737168 )
+					if (ibassDiskSize == 9737168)
 						dataDiskHeadMD5 = Common::computeStreamMD5AsString(ibassDisk, 5000);
 				}
 			}
@@ -229,7 +229,7 @@ DetectedGames SkyMetaEngineDetection::detectGames(const Common::FSList &fslist,
 		detectedGames.push_back(game);
 	}
 
-	if (hasibassDat) {
+	if (hasIbassDat) {
 		DetectedGame game;
 		Common::Language lang = Common::Language::UNK_LANG;
 		game = DetectedGame(getName(), ibassSetting.gameId, ibassSetting.description, lang);
diff --git a/engines/sky/disk.cpp b/engines/sky/disk.cpp
index 9dce4485357..117333ddbd8 100644
--- a/engines/sky/disk.cpp
+++ b/engines/sky/disk.cpp
@@ -37,100 +37,99 @@ static const char *const dataFilename = "sky.dsk";
 static const char *const dinnerFilename = "sky.dnr";
 
 static int hashCompFunc(const void *m1, const void *m2) {
-	fileEntry *e1 = (fileEntry *)m1;
-	fileEntry *e2 = (fileEntry *)m2;
-	if (e1->filenum == e2->filenum)
+	FileEntry *e1 = (FileEntry *)m1;
+	FileEntry *e2 = (FileEntry *)m2;
+	if (e1->_fileNum == e2->_fileNum)
 		return 0;
-	return (e1->filenum < e2->filenum ? -1 : 1);
+	return (e1->_fileNum < e2->_fileNum ? -1 : 1);
 }
 
 Disk::Disk() {
 	_dataDiskHandle = new Common::File();
+	Common::File *dnrHandle = new Common::File();
 
-	if (SkyEngine::_isIbass()) {
+	if (SkyEngine::isIbass()) {
 		if (!_dataDiskHandle->open("bass.dat"))
 			error("Error opening bass.dat");
 
-		char magic[4];
+		byte magic[4];
 		_dataDiskHandle->read(magic, 4);
-		if (0 != strncmp("HSFS", magic, 4))
+		if (0 != memcmp(magic, "HSFS", 4))
 			error("Invalid bass.dat file");
 
 		_numFiles = _dataDiskHandle->readUint32LE();
-		_entry = new fileEntry[_numFiles];
+		_entry = new FileEntry[_numFiles];
 
-		//now populate the entry table
+		// now populate the entry table
 		for (uint32 i = 0; i < _numFiles; i++) {
-			_entry[i].filenum = _dataDiskHandle->readUint32LE();
-			_entry[i].offset = _dataDiskHandle->readUint32LE();
-			_entry[i].size = _dataDiskHandle->readUint32LE();
-			_entry[i].compressed_size = _dataDiskHandle->readUint32LE();
+			_entry[i]._fileNum = _dataDiskHandle->readUint32LE();
+			_entry[i]._offset = _dataDiskHandle->readUint32LE();
+			_entry[i]._size = _dataDiskHandle->readUint32LE();
+			_entry[i]._compressedSize = _dataDiskHandle->readUint32LE();
 		}
 
  		memset(_buildList, 0, 60 * 2);
  		memset(_loadedFilesList, 0, 60 * 4);
+		return;
+	}
 
-	} else {
-		Common::File *dnrHandle = new Common::File();
-
-		dnrHandle->open(dinnerFilename);
-		if (!dnrHandle->isOpen())
-			error("Could not open %s", dinnerFilename);
+	dnrHandle->open(dinnerFilename);
+	if (!dnrHandle->isOpen())
+		error("Could not open %s", dinnerFilename);
 
-		if (!(_dinnerTableEntries = dnrHandle->readUint32LE()))
-			error("Error reading from sky.dnr"); //even though it was opened correctly?!
+	if (!(_dinnerTableEntries = dnrHandle->readUint32LE()))
+		error("Error reading from sky.dnr"); //even though it was opened correctly?!
 
-		_dinnerTableArea = (uint8 *)malloc(_dinnerTableEntries * 8);
-		uint32 entriesRead = dnrHandle->read(_dinnerTableArea, 8 * _dinnerTableEntries) / 8;
+	_dinnerTableArea = (uint8 *)malloc(_dinnerTableEntries * 8);
+	uint32 entriesRead = dnrHandle->read(_dinnerTableArea, 8 * _dinnerTableEntries) / 8;
 
-		if (entriesRead != _dinnerTableEntries)
-			error("entriesRead != dinnerTableEntries. [%d/%d]", entriesRead, _dinnerTableEntries);
+	if (entriesRead != _dinnerTableEntries)
+		error("entriesRead != dinnerTableEntries. [%d/%d]", entriesRead, _dinnerTableEntries);
 
-		_dataDiskHandle->open(dataFilename);
-		if (!_dataDiskHandle->isOpen())
-			error("Error opening %s", dataFilename);
+	_dataDiskHandle->open(dataFilename);
+	if (!_dataDiskHandle->isOpen())
+		error("Error opening %s", dataFilename);
 
-		debug("Found BASS version v0.0%d (%d dnr entries)", determineGameVersion(), _dinnerTableEntries);
+	debug("Found BASS version v0.0%d (%d dnr entries)", determineGameVersion(), _dinnerTableEntries);
 
-		memset(_buildList, 0, 60 * 2);
-		memset(_loadedFilesList, 0, 60 * 4);
+	memset(_buildList, 0, 60 * 2);
+	memset(_loadedFilesList, 0, 60 * 4);
 
-		dnrHandle->close();
-		delete dnrHandle;
-	}
+	dnrHandle->close();
+	delete dnrHandle;
 }
 
 Disk::~Disk() {
 	if (_dataDiskHandle->isOpen())
 		_dataDiskHandle->close();
 	fnFlushBuffers();
-	if (!SkyEngine::_isIbass())
+	if (!SkyEngine::isIbass())
 		free(_dinnerTableArea);
 	delete _dataDiskHandle;
-	if (SkyEngine::_isIbass())
+	if (SkyEngine::isIbass())
 		delete[] _entry;
 	_entry = 0;
 }
 
-animation *Disk::loadAnim(const char *filename, const Graphics::PixelFormat &targetFormat) {
+Animation *Disk::loadAnim(const char *filename, const Graphics::PixelFormat &targetFormat) {
 	Common::File fp;
 
 	if (!fp.open(filename))
 		return 0;
 
-	animation *anim = new animation;
+	Animation *anim = new Animation;
 
 	int num_frames;
 	int width;
 	int height;
-	char magic[4];
+	byte magic[4];
 
 	fp.read(magic, 4);
 	num_frames = fp.readUint32LE();
 	width = fp.readUint32LE();
 	height = fp.readUint32LE();
 
-	if (0 != strncmp(magic, "JPTX", 4) || width > 64 || height > 64)
+	if (0 != memcmp(magic, "JPTX", 4) || width > 64 || height > 64)
 		error("Too large or invalid texture!\n");
 
 	if (num_frames >= MAX_FRAMES)
@@ -139,10 +138,10 @@ animation *Disk::loadAnim(const char *filename, const Graphics::PixelFormat &tar
 	int scaledWidth = width  * 2 / 3;
 	int scaledHeight = height * 2 / 3;
 
-	anim->num_frames = num_frames;
-	anim->width = scaledWidth;
-	anim->height = scaledHeight;
-	anim->frames = new Graphics::Surface*[MAX_FRAMES];
+	anim->_numFrames = num_frames;
+	anim->_width = scaledWidth;
+	anim->_height = scaledHeight;
+	anim->_frames = new Graphics::Surface*[MAX_FRAMES];
 
 	for (int frame = 0; frame < num_frames; frame++) {
 		Graphics::Surface tempCanvas;
@@ -154,9 +153,11 @@ animation *Disk::loadAnim(const char *filename, const Graphics::PixelFormat &tar
 		for (int i = 0; i < totalPixels; i++)
 			tempPixels[i] = fp.readUint32LE();
 
+		tempCanvas.flipVertical(Common::Rect(width, height));
+
 		Graphics::Surface *scaledCanvas = tempCanvas.scale(scaledWidth, scaledHeight);
 
-		anim->frames[frame] = scaledCanvas->convertTo(targetFormat);
+		anim->_frames[frame] = scaledCanvas->convertTo(targetFormat);
 		scaledCanvas->free();
 		delete scaledCanvas;
 	}
@@ -168,128 +169,127 @@ bool Disk::fileExists(uint16 fileNr) {
 	return (getFileInfo(fileNr) != NULL);
 }
 
-fileEntry *Disk::getEntry(uint32 filenum) {
-	fileEntry searchEntry;
-	searchEntry.filenum = filenum;
-	return (fileEntry *)bsearch(&searchEntry, _entry, _numFiles, sizeof(fileEntry), hashCompFunc);
+FileEntry *Disk::getEntry(uint32 filenum) {
+	FileEntry searchEntry;
+	searchEntry._fileNum = filenum;
+	return (FileEntry *)bsearch(&searchEntry, _entry, _numFiles, sizeof(FileEntry), hashCompFunc);
 }
 
 // allocate memory, load the file and return a pointer
 uint8 *Disk::loadFile(uint16 fileNr) {
 
-	if (SkyEngine::_isIbass()) {
-		fileEntry *entry = getEntry(fileNr);
+	if (SkyEngine::isIbass()) {
+		FileEntry *entry = getEntry(fileNr);
 		if (!entry) {
 			debug(1, "iBass: File %d not found!", fileNr);
 			return NULL;
 		}
-		uint8 *compressedData = (uint8 *)malloc(entry->compressed_size);
-		uint8 *uncompressedData = (uint8 *)malloc(entry->size);
-		_dataDiskHandle->seek(entry->offset, SEEK_SET);
-		uint32 bytesRead = _dataDiskHandle->read(compressedData, entry->compressed_size);
-		assert(entry->compressed_size == bytesRead);
-
-		unsigned long destLen = entry->size;
-		bool result = Common::inflateZlib(uncompressedData, &destLen, compressedData, entry->compressed_size);
+		uint8 *compressedData = (uint8 *)malloc(entry->_compressedSize);
+		uint8 *uncompressedData = (uint8 *)malloc(entry->_size);
+		_dataDiskHandle->seek(entry->_offset, SEEK_SET);
+		uint32 bytesRead = _dataDiskHandle->read(compressedData, entry->_compressedSize);
+		assert(entry->_compressedSize == bytesRead);
+
+		unsigned long destLen = entry->_size;
+		bool result = Common::inflateZlib(uncompressedData, &destLen, compressedData, entry->_compressedSize);
 		assert(result == true);
 
 		free(compressedData);
-		_lastLoadedFileSize = entry->size;
+		_lastLoadedFileSize = entry->_size;
 		return uncompressedData;
-	} else {
-		uint8 cflag;
-
-		debug(3, "load file %d,%d (%d)", (fileNr >> 11), (fileNr & 2047), fileNr);
+	}
+	uint8 cflag;
 
-		uint8 *fileInfoPtr = getFileInfo(fileNr);
-		if (fileInfoPtr == NULL) {
-			debug(1, "File %d not found", fileNr);
-			return NULL;
-		}
+	debug(3, "load file %d,%d (%d)", (fileNr >> 11), (fileNr & 2047), fileNr);
 
-		uint32 fileFlags = READ_LE_UINT24(fileInfoPtr + 5);
-		uint32 fileSize = fileFlags & 0x03fffff;
-		uint32 fileOffset = READ_LE_UINT32(fileInfoPtr + 2) & 0x0ffffff;
+	uint8 *fileInfoPtr = getFileInfo(fileNr);
+	if (fileInfoPtr == NULL) {
+		debug(1, "File %d not found", fileNr);
+		return NULL;
+	}
 
-		_lastLoadedFileSize = fileSize;
-		cflag = (uint8)((fileOffset >> 23) & 0x1);
-		fileOffset &= 0x7FFFFF;
+	uint32 fileFlags = READ_LE_UINT24(fileInfoPtr + 5);
+	uint32 fileSize = fileFlags & 0x03fffff;
+	uint32 fileOffset = READ_LE_UINT32(fileInfoPtr + 2) & 0x0ffffff;
 
-		if (cflag) {
-			if (SkyEngine::_systemVars->gameVersion == 331)
-				fileOffset <<= 3;
-			else
-				fileOffset <<= 4;
-		}
+	_lastLoadedFileSize = fileSize;
+	cflag = (uint8)((fileOffset >> 23) & 0x1);
+	fileOffset &= 0x7FFFFF;
 
-		uint8 *fileDest = (uint8 *)malloc(fileSize + 4); // allocate memory for file
+	if (cflag) {
+		if (SkyEngine::_systemVars->gameVersion == 331)
+			fileOffset <<= 3;
+		else
+			fileOffset <<= 4;
+	}
 
-		_dataDiskHandle->seek(fileOffset, SEEK_SET);
+	uint8 *fileDest = (uint8 *)malloc(fileSize + 4); // allocate memory for file
 
-		//now read in the data
-		int32 bytesRead = _dataDiskHandle->read(fileDest, fileSize);
+	_dataDiskHandle->seek(fileOffset, SEEK_SET);
 
-		if (bytesRead != (int32)fileSize)
-			warning("Unable to read %d bytes from datadisk (%d bytes read)", fileSize, bytesRead);
+	//now read in the data
+	int32 bytesRead = _dataDiskHandle->read(fileDest, fileSize);
 
-		cflag = (uint8)((fileFlags >> 23) & 0x1);
-		//if cflag == 0 then file is compressed, 1 == uncompressed
+	if (bytesRead != (int32)fileSize)
+		warning("Unable to read %d bytes from datadisk (%d bytes read)", fileSize, bytesRead);
 
-		DataFileHeader *fileHeader = (DataFileHeader *)fileDest;
+	cflag = (uint8)((fileFlags >> 23) & 0x1);
+	//if cflag == 0 then file is compressed, 1 == uncompressed
 
-		if ((!cflag) && ((FROM_LE_16(fileHeader->flag) >> 7) & 1)) {
-			debug(4, "File is RNC compressed.");
+	DataFileHeader *fileHeader = (DataFileHeader *)fileDest;
 
-			uint32 decompSize = (FROM_LE_16(fileHeader->flag) & ~0xFF) << 8;
-			decompSize |= FROM_LE_16(fileHeader->s_tot_size);
+	if ((!cflag) && ((FROM_LE_16(fileHeader->flag) >> 7) & 1)) {
+		debug(4, "File is RNC compressed.");
 
-			uint8 *uncompDest = (uint8 *)malloc(decompSize);
+		uint32 decompSize = (FROM_LE_16(fileHeader->flag) & ~0xFF) << 8;
+		decompSize |= FROM_LE_16(fileHeader->s_tot_size);
 
-			int32 unpackLen;
-			void *output, *input = fileDest + sizeof(DataFileHeader);
+		uint8 *uncompDest = (uint8 *)malloc(decompSize);
 
-			if ((fileFlags >> 22) & 0x1) { //do we include the header?
-				// don't return the file's header
-				output = uncompDest;
-				unpackLen = _rncDecoder.unpackM1(input, fileSize - sizeof(DataFileHeader), output);
-			} else {
-	#ifdef SCUMM_BIG_ENDIAN
-				// Convert DataFileHeader to BE (it only consists of 16 bit words)
-				uint16 *headPtr = (uint16 *)fileDest;
-				for (uint i = 0; i < sizeof(DataFileHeader) / 2; i++)
-					*(headPtr + i) = READ_LE_UINT16(headPtr + i);
-	#endif
+		int32 unpackLen;
+		void *output, *input = fileDest + sizeof(DataFileHeader);
 
-				memcpy(uncompDest, fileDest, sizeof(DataFileHeader));
-				output = uncompDest + sizeof(DataFileHeader);
-				unpackLen = _rncDecoder.unpackM1(input, fileSize - sizeof(DataFileHeader), output);
-				if (unpackLen)
-					unpackLen += sizeof(DataFileHeader);
-			}
+		if ((fileFlags >> 22) & 0x1) { //do we include the header?
+			// don't return the file's header
+			output = uncompDest;
+			unpackLen = _rncDecoder.unpackM1(input, fileSize - sizeof(DataFileHeader), output);
+		} else {
+#ifdef SCUMM_BIG_ENDIAN
+			// Convert DataFileHeader to BE (it only consists of 16 bit words)
+			uint16 *headPtr = (uint16 *)fileDest;
+			for (uint i = 0; i < sizeof(DataFileHeader) / 2; i++)
+				*(headPtr + i) = READ_LE_UINT16(headPtr + i);
+#endif
 
-			debug(5, "UnpackM1 returned: %d", unpackLen);
+			memcpy(uncompDest, fileDest, sizeof(DataFileHeader));
+			output = uncompDest + sizeof(DataFileHeader);
+			unpackLen = _rncDecoder.unpackM1(input, fileSize - sizeof(DataFileHeader), output);
+			if (unpackLen)
+				unpackLen += sizeof(DataFileHeader);
+		}
 
-			if (unpackLen == 0) { //Unpack returned 0: file was probably not packed.
-				free(uncompDest);
-				return fileDest;
-			} else {
-				if (unpackLen != (int32)decompSize)
-					debug(1, "ERROR: File %d: invalid decomp size! (was: %d, should be: %d)", fileNr, unpackLen, decompSize);
-				_lastLoadedFileSize = decompSize;
+		debug(5, "UnpackM1 returned: %d", unpackLen);
 
-				free(fileDest);
-				return uncompDest;
-			}
-		} else {
-	#ifdef SCUMM_BIG_ENDIAN
-			if (!cflag) {
-				uint16 *headPtr = (uint16 *)fileDest;
-				for (uint i = 0; i < sizeof(DataFileHeader) / 2; i++)
-					*(headPtr + i) = READ_LE_UINT16(headPtr + i);
-			}
-	#endif
+		if (unpackLen == 0) { //Unpack returned 0: file was probably not packed.
+			free(uncompDest);
 			return fileDest;
+		} else {
+			if (unpackLen != (int32)decompSize)
+				debug(1, "ERROR: File %d: invalid decomp size! (was: %d, should be: %d)", fileNr, unpackLen, decompSize);
+			_lastLoadedFileSize = decompSize;
+
+			free(fileDest);
+			return uncompDest;
+		}
+	} else {
+#ifdef SCUMM_BIG_ENDIAN
+		if (!cflag) {
+			uint16 *headPtr = (uint16 *)fileDest;
+			for (uint i = 0; i < sizeof(DataFileHeader) / 2; i++)
+				*(headPtr + i) = READ_LE_UINT16(headPtr + i);
 		}
+#endif
+		return fileDest;
 	}
 }
 
@@ -449,8 +449,8 @@ void Disk::dumpFile(uint16 fileNr) {
 }
 
 uint32 Disk::determineGameVersion() {
-	if (SkyEngine::_isIbass())
-		return 400; // force the ibass version and immediately exit the function
+	if (SkyEngine::isIbass())
+		return 372; // fall back to actual cd version for ibass
 
 	//determine game version based on number of entries in dinner table
 	switch (_dinnerTableEntries) {
diff --git a/engines/sky/disk.h b/engines/sky/disk.h
index 579f5f3328f..fdf927ee14c 100644
--- a/engines/sky/disk.h
+++ b/engines/sky/disk.h
@@ -26,31 +26,34 @@
 #include "common/scummsys.h"
 #include "common/compression/rnc_deco.h"
 
-#include "graphics/surface.h"
-
 #define MAX_FILES_IN_LIST 60
 
-#define MAX_FRAMES	16	//maximum number of frames per animation in ibass
+#define MAX_FRAMES 16 // Maximum number of frames per animation in ibass
 
 namespace Common {
 class File;
 }
 
-struct fileEntry {
-	uint32 filenum;
-	uint32 offset;
-	uint32 size;
-	uint32 compressed_size;
-	fileEntry() : filenum(0), offset(0), size(0), compressed_size(0) {}
+namespace Graphics {
+class Surface;
+class PixelFormat;
+}
+
+struct FileEntry {
+	uint32 _fileNum;
+	uint32 _offset;
+	uint32 _size;
+	uint32 _compressedSize;
+	FileEntry() : _fileNum(0), _offset(0), _size(0), _compressedSize(0) {}
 };
 
 namespace Sky {
 
-struct animation {
-	Graphics::Surface **frames;
-	int num_frames;
-	int width;
-	int height;
+struct Animation {
+	Graphics::Surface **_frames;
+	int _numFrames;
+	int _width;
+	int _height;
 };
 
 class Disk {
@@ -73,14 +76,14 @@ public:
 	void fnFlushBuffers();
 	uint32 *giveLoadedFilesList() { return _loadedFilesList; }
 	void refreshFilesList(uint32 *list);
-	animation *loadAnim(const char *filename, const Graphics::PixelFormat &targetFormat);
+	Animation *loadAnim(const char *filename, const Graphics::PixelFormat &targetFormat);
 
 protected:
 	uint8 *getFileInfo(uint16 fileNr);
 	void dumpFile(uint16 fileNr);
 
 	uint32 _numFiles;
-	fileEntry *_entry;
+	FileEntry *_entry;
 
 	uint32 _dinnerTableEntries;
 	uint8 *_dinnerTableArea;
@@ -88,7 +91,7 @@ protected:
 	Common::RncDecoder _rncDecoder;
 
 	uint32 getFileSize(uint32 filenum);
-	fileEntry *getEntry(uint32 filenum);
+	FileEntry *getEntry(uint32 filenum);
 
 	uint16 _buildList[MAX_FILES_IN_LIST];
 	uint32 _loadedFilesList[MAX_FILES_IN_LIST];
diff --git a/engines/sky/inventory.cpp b/engines/sky/inventory.cpp
new file mode 100644
index 00000000000..7e57ded7a02
--- /dev/null
+++ b/engines/sky/inventory.cpp
@@ -0,0 +1,149 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "sky/logic.h"
+#include "sky/compact.h"
+#include "sky/text.h"
+#include "sky/screen.h"
+#include "sky/mouse.h"
+#include "sky/sky.h"
+
+
+namespace Sky {
+
+const int invIconId[NUM_INV_ANIMS + 1] = {
+	2304,
+	3201,
+	3203,
+	3205,
+	3207,
+	3209,
+	3211,
+	4672,
+	4674,
+	5568,
+	5570,
+	12225,
+	12227,
+	12229,
+	12231,
+	12233,
+	12235,
+	12237,
+	12239,
+	12241,
+	12243,
+	12245,
+	12247,
+	12249,
+	12251,
+	12253,
+	12255,
+	12257,
+	16768,
+	16832,
+	16896,
+	16960,
+	17024,
+	17088,
+	17152,
+	17154,
+	17156,
+	17158,
+	17160,
+	17162,
+	17164,
+	17216,
+	17344,
+	17408,
+	-1,
+};
+
+void Screen::addInvIcon(int frame, int x, int y, bool highlighted) {
+	if (_invIconsInUse >= NUM_INV_ICONS)
+		return;
+
+	_invIcon[_invIconsInUse]._anim = _invAnim[getInventoryAnimIdx(frame)];
+	_invIcon[_invIconsInUse].set(x, y);
+	_invIcon[_invIconsInUse]._curFrame = highlighted ? 1 : 0;
+
+	_invIconsInUse++;
+}
+
+void Screen::showInventory(int x1, int y1, int x2, int y2) {
+	_invX1 = x1;
+	_invY1 = y1;
+	_invX2 = x2;
+	_invY2 = y2;
+	_invVisible = true;
+}
+
+void Screen::hideInventory() {
+	_invVisible = false;
+}
+
+void Screen::clearAllInvIcons() {
+	_invIconsInUse = 0;
+}
+
+int Screen::getInventoryAnimIdx(int frame) {
+	for (int i = 0; i < NUM_INV_ANIMS; i++) {
+		if (frame == invIconId[i])
+			return i;
+	}
+
+	debug("Couldn't find inventory item%d\n", frame);
+	return 0; // fallback
+}
+
+void Logic::startInventory(uint32	highlightedId) {
+	// normal gameplay inv
+	fnStartMenu(Logic::_scriptVariables[FIRST_ICON], highlightedId, 0);
+}
+
+void Logic::killInventory() {
+
+	// shut down displayed inv objects
+
+	int j;
+	Compact *itemData;
+
+
+	if (_liveInv) {
+
+		for (j = 0; j < _scriptVariables[MENU_LENGTH]; j++) {
+			// fetch the compact
+			itemData = _skyCompact->fetchCpt(_objectList[j]);
+
+			itemData->status = 0;
+		}
+	}
+
+
+	_liveInv = false;
+
+	// kill inv bg
+	_skyScreen->hideInventory();
+	_skyScreen->clearAllInvIcons();
+
+}
+
+}
diff --git a/engines/sky/logic.cpp b/engines/sky/logic.cpp
index c9e0b1c6764..8097e88cb8f 100644
--- a/engines/sky/logic.cpp
+++ b/engines/sky/logic.cpp
@@ -1874,6 +1874,84 @@ bool Logic::fnStartMenu(uint32 firstObject, uint32 b, uint32 c) {
 	/// initialize the top menu bar
 	// firstObject is o0 for game menu, k0 for linc
 
+	if (SkyEngine::isIbass()) {
+		Compact *cpt;
+
+		debug("init inv menu %d", firstObject);
+
+		// safety flag
+		_liveInv = true;
+
+		if (firstObject == 2048 || firstObject == 2168 || firstObject == 2288)
+			_skyMouse->setLincInv(true);
+		else
+			_skyMouse->setLincInv(false);
+
+		_skyMouse->incLincMenuRef();
+		_skyScreen->hideInventory();
+		_skyScreen->clearAllInvIcons();
+
+		uint i;
+		firstObject /= 4;
+
+		uint32 menuLength = 0;
+		for (i = firstObject; i < firstObject + ARRAYSIZE(_objectList); i++) {
+			// skip unused linc items
+			if (_scriptVariables[i] == 24581 || _scriptVariables[i] == 24628)
+				continue;
+
+			if (_scriptVariables[i])
+				_objectList[menuLength++] = _scriptVariables[i];
+		}
+		_scriptVariables[MENU_LENGTH] = menuLength;
+
+		debug("Menu length = %d", menuLength);
+
+		uint16 rollingX = TOP_LEFT_X + XWIDTH;
+		int xx = 0;
+		uint16 rollingY = 236;
+
+		int didX = 0, didY = 1;
+
+		for (i = 0; i < menuLength; i++) {
+			if (xx == 8) {
+				rollingX = TOP_LEFT_X + XWIDTH;
+				xx = 0;
+				rollingY += YDEPTH;
+
+				didY++;
+			}
+
+			cpt = _skyCompact->fetchCpt(_objectList[i]);
+			debug("Init i = %d ob = %d fr = %d\n", i, _objectList[i], cpt->frame);
+
+			cpt->status = ST_MOUSE + ST_FOREGROUND + /*ST_LOGIC +*/ ST_RECREATE;
+			cpt->screen = 999;
+
+			cpt->xcood = rollingX;
+			cpt->ycood = rollingY; // 112;
+
+			int frame = cpt->frame;
+
+			// if LINC then check for off frames and mask off :O :O
+			if (_objectList[i] > 20000)
+				if (!(frame & 1))
+					frame--;
+
+			_skyScreen->addInvIcon(frame, rollingX - TOP_LEFT_X, rollingY - TOP_LEFT_Y, (b == _objectList[i]));
+
+			rollingX += XWIDTH;
+
+			xx++;
+
+			if (didY == 1)
+				didX++;
+		}
+
+		return true;
+
+	}
+
 	uint i;
 	firstObject /= 4;
 
diff --git a/engines/sky/logic.h b/engines/sky/logic.h
index efe56d48c16..74df32375fc 100644
--- a/engines/sky/logic.h
+++ b/engines/sky/logic.h
@@ -156,26 +156,20 @@ public:
 	void initScreen0();
 	void parseSaveData(uint32 *data);
 
-	void Start_inventory(uint32	highlightedId = 0) {
-		//normal gameplay inv
-		fnStartMenu(_scriptVariables[FIRST_ICON],highlightedId,0);
-	}
+	void startInventory(uint32 highlightedId = 0);
 
-	uint32 *Give_inv_list() {
+	uint32 *giveInvList() {
 		return &_objectList[0];
 	}
 
-	void KillInventory();
-
-	void BlankMouse() {
-		fnBlankMouse(0, 0, 0);
-	}
+	void killInventory();
 
 private:
 	void setupLogicTable();
 	void setupMcodeTable();
 	const LogicTable *_logicTable;
 	const McodeTable *_mcodeTable;
+	bool _liveInv;
 
 protected:
 	void push(uint32);
diff --git a/engines/sky/module.mk b/engines/sky/module.mk
index 21517d8edfc..efb19e77cf9 100644
--- a/engines/sky/module.mk
+++ b/engines/sky/module.mk
@@ -9,6 +9,7 @@ MODULE_OBJS := \
 	grid.o \
 	hufftext.o \
 	intro.o \
+	inventory.o \
 	logic.o \
 	metaengine.o \
 	mouse.o \
diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index 292f44a4479..911795655a2 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -20,7 +20,6 @@
  */
 
 
-#include "common/config-manager.h"
 #include "common/events.h"
 #include "common/system.h"
 #include "common/textconsole.h"
@@ -40,6 +39,7 @@ namespace Sky {
 #define MICE_FILE	60300
 #define NO_MAIN_OBJECTS	24
 #define NO_LINC_OBJECTS	21
+
 uint32 Mouse::_mouseMainObjects[24] = {
 	65,
 	9,
@@ -91,10 +91,11 @@ uint32 Mouse::_mouseLincObjects[21] = {
 	24829
 };
 
-Mouse::Mouse(OSystem *system, Disk *skyDisk, SkyCompact *skyCompact) {
+Mouse::Mouse(OSystem *system, Disk *skyDisk, SkyCompact *skyCompact, Screen *skyScreen) {
 	_skyDisk = skyDisk;
 	_skyCompact = skyCompact;
 	_system = system;
+	_skyScreen = skyScreen;
 	_mouseB = 0;
 	_currentCursor = 6;
 	_touchId = 0;
@@ -110,27 +111,27 @@ Mouse::Mouse(OSystem *system, Disk *skyDisk, SkyCompact *skyCompact) {
 }
 
 void Mouse::resetUI() {
-	//popup
+	// popup
 	_clickedNum = 0;
 	_prevMouseOn = false;
 	_touchId = 0;
 	_holding = false;
 	_timeOn = 0;
 	_fadeOut = 0;
-	m_mode = Gameplay;//master ui mode
+	M_MODE = GAMEPLAY; // master ui mode
 	_isFloor = false;
 	_isExit = false;
 	_actionFlash = false;
 	_floorLock = false;
 
-	if (((SkyEngine *)g_engine)->getScreen()) {
-		((SkyEngine *)g_engine)->getScreen()->clearAllProximityIcons(false);
-		((SkyEngine *)g_engine)->getScreen()->clearAllIbassIcons(false);
+	if (_skyScreen) {
+		_skyScreen->clearAllProximityIcons(false);
+		_skyScreen->clearAllIbassIcons(false);
 	}
 
 }
 
-Mouse::~Mouse() {
+Mouse::~Mouse( ){
 	free (_miceData);
 	free (_objectMouseData);
 }
@@ -144,8 +145,8 @@ bool Mouse::fnAddHuman() {
 	//reintroduce the mouse so that the human can control the player
 	//could still be switched out at high-level
 
-	if (m_mode == Gameplay)
-		m_mode = MustRelease;
+	if (M_MODE == GAMEPLAY)
+		M_MODE = MUST_RELEASE;
 
 	if (!Logic::_scriptVariables[MOUSE_STOP]) {
 		Logic::_scriptVariables[MOUSE_STATUS] |= 6;	//cursor & mouse
@@ -231,7 +232,7 @@ void Mouse::waitMouseNotPressed(int minDelay) {
 void Mouse::spriteMouse(uint16 frameNum, uint8 mouseX, uint8 mouseY) {
 	_currentCursor = frameNum;
 
-	if (SkyEngine::_isIbass()) {
+	if (SkyEngine::isIbass()) {
 		debug("ibass cursor path executed\n");
 		CursorMan.setDefaultArrowCursor();
 		CursorMan.showMouse(true);
@@ -252,7 +253,7 @@ void Mouse::spriteMouse(uint16 frameNum, uint8 mouseX, uint8 mouseY) {
 		CursorMan.showMouse(true);
 }
 
-bool Mouse::IsUILive() {
+bool Mouse::isUILive() {
 	if (!Logic::_scriptVariables[MOUSE_STOP] && (Logic::_scriptVariables[MOUSE_STATUS] & (1 << 1)) && (Logic::_scriptVariables[MOUSE_STATUS] & (1 << 2)) )
 		return	true;
 
@@ -262,55 +263,52 @@ bool Mouse::IsUILive() {
 void Mouse::mouseEngine() {
 	_logicClick = (_mouseB > 0); // click signal is available for Logic for one gamecycle
 
-	if (SkyEngine::_isIbass()) {
-		m_mode = Gameplay; // TODO: REMOVE THIS AFTER INTRO IS IMPLEMENTED
+	if (SkyEngine::isIbass()) {
 		if (_actionFlash) {
 			_actionFlashTime--;
 			if (!_actionFlashTime)
 				_actionFlash = false;
 
 			if (!(_actionFlashTime & 1))
-				((SkyEngine *)g_engine)->getScreen()->clearIbassIcon(_actionFlashIcon, false);
+				_skyScreen->clearIbassIcon(_actionFlashIcon, false);
 			else
-				((SkyEngine *)g_engine)->getScreen()->setIcon(_actionFlashIcon, _actionFlashX, _actionFlashY);
+				_skyScreen->setIcon(_actionFlashIcon, _actionFlashX, _actionFlashY);
 		}
 
-		// if (!IsUILive())
-		// 	return;
-
-		switch (m_mode) {
-			case Alert_to_game:
+		switch (M_MODE) {
+			case ALERT_TO_GAME:
 				if (!_mouseB)
 					return;
 
-				((SkyEngine *)g_engine)->getScreen()->hideInventory();
-				m_mode=MustRelease;
+				_skyScreen->hideInventory();
+				M_MODE = MUST_RELEASE;
 				break;
 
-			case MustRelease:
+			case MUST_RELEASE:
 				if (_mouseB)
 					return;
 
 				resetUI();
-				m_mode=Gameplay;
+				M_MODE = GAMEPLAY;
 				break;
 
-			case Gameplay:
+			case GAMEPLAY:
 				pointerEngine(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
-				if (Logic::_scriptVariables[MOUSE_STATUS] & (1 << 2))
-					buttonEngine1();
 				break;
 
-			case PreInventory:
+			case PRE_INVENTORY:
 				if (_mouseB)
 					return;
 
-				m_mode=Inventory;
+				M_MODE = INVENTORY;
 				break;
 
-			case Inventory:
-			case InventoryUseOn:
-			case Text_chooser:
+			case INVENTORY:
+				if (isLincInv())
+					lincInvMouse(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
+
+			case INVENTORY_USE_ON:
+			case TEXT_CHOOSER:
 				break;
 		}
 
@@ -331,50 +329,48 @@ void Mouse::mouseEngine() {
 int Mouse::doProximityHighlights(uint16 xPos, uint16 yPos) {
 	uint32 currentListNum = Logic::_scriptVariables[MOUSE_LIST_NO];
 	uint16 *currentList;
-	int	midx,midy;
+	int midx, midy;
 	Compact *itemData;
 	uint16 itemNum;
-	int	found=0;
-	int	nearestDist=99999;
-	int	nearestId=0;
-	_nearestProximityIconId=0;
+	int found = 0;
+	int nearestDist = 99999;
+	int nearestId = 0;
+	_nearestProximityIconId = 0;
 
-	static int	proxFrame=0;
-	static int	proxFrameSpeed=0;
+	static int  proxFrame = 0;
+	static int  proxFrameSpeed = 0;
 
 	proxFrameSpeed++;
-	if	(proxFrameSpeed&1)
+	if (proxFrameSpeed & 1)
 		proxFrame++;
-	if	(proxFrame==3)
-		proxFrame=0;
+	if (proxFrame == 3)
+		proxFrame = 0;
 
-	//near inv button?
-	if (yPos>HOTSPOT_invy && xPos<HOTSPOT_invx)
-		return	0;
+	// near inv button?
+	if (yPos > HOTSPOT_invy && xPos < HOTSPOT_invx)
+		return  0;
 
-	//not on same as last time, or was not on anything previously, so re-scan all objects
+	// not on same as last time, or was not on anything previously, so re-scan all objects
 	do {
 		currentList = (uint16 *)_skyCompact->fetchCpt(currentListNum);
 		while ((*currentList != 0) && (*currentList != 0xFFFF)) {
 			itemNum = *currentList;
 			itemData = _skyCompact->fetchCpt(itemNum);
 			currentList++;
-
 			if ((itemData->screen == Logic::_scriptVariables[SCREEN]) && (itemData->status & 16)) {
-				//hotspot, if a non-floor object
-				if (itemData->mouseOn && yPos > (20+TOP_LEFT_Y)) {
+				// hotspot, if a non-floor object
+				if (itemData->mouseOn && yPos > (20 + TOP_LEFT_Y)) {
 					midx = giveXcood(itemData, itemNum);
 					midy = giveYcood(itemData, itemNum);
 
-					//skip very high hotspots - eg the old inventory catch object
+					// skip very high hotspots - eg the old inventory catch object
 					if (midy < (TOP_LEFT_Y + 5))
 						continue;
 
-					//how far from finger?
-					int	d = abs(xPos - midx) + abs(yPos - midy);
+					int d = abs(xPos - midx) + abs(yPos - midy);
 					if (d < GLOW_DIST) {
 						float opacity = 1.0 - ((d * 1.0) / GLOW_DIST);
-						((SkyEngine *)g_engine)->getScreen()->setProximityIcon(found++, midx - TOP_LEFT_X - 4, ((midy - TOP_LEFT_Y) - 4), opacity, proxFrame);
+						_skyScreen->setProximityIcon(found++, midx - TOP_LEFT_X - 4, ((midy - TOP_LEFT_Y) - 4), opacity, proxFrame);
 					}
 
 					if (d < nearestDist) {
@@ -395,175 +391,171 @@ int Mouse::doProximityHighlights(uint16 xPos, uint16 yPos) {
 
 UIIcon Mouse::getInteractIcon(uint32 id) {
 
-	switch(id) {
-		case	70://screen 1 stairs
-		case	4119://elevator hole
-		case	8210://outside stairs to furnace
-			return	UI_ICON_DOWN;//
-
-		case	69://screen 1 stairs
-			return	UI_ICON_UP;//
-
-		case	1://joey
-		case	4122://hobbins
-		case	16://lamb
-		case	8324://guard
-		case	8211://sam
-		case	8301://norville
-		case	8544://clipboard man
-		case	136://power room man
-		case	12546://galagher
-		case	12442://insurance man
-		case	12430://anchor man
-		case	12407://dr burke
-		case	16516://henri
-		case	16601://guard
-		case	16441://piermont
-		case	16599://gameboy
-		case	16600://gardener
-		case	16701://barman
-		case	16772://babs
-		case	16737://man1
-		case	16731://man2
-//		case	20511://medi joey
-		case	20911://ken
-		case	137://anita
-	//	case	12407://patient
-		case	12289://mr cool
-		case	8205://rad suit man
-		case	8309://guard walkway
-		case	21014://father @ end
-			return	UI_ICON_MOUTH;//talk
-
-		case	4151://notice
-		case	4152://ledge-side notice
-		case	12383://sculpture
-		case	12388://mural
-		case	12386://poster
-		case	12387://ins poster
-		case	12378://surgery poster
-		case	12375://surgery poster
-		case	12376://surgery poster
-		case	12377://surgery poster
-		case	12401://dr poster
-		case	12402://dr poster
-		case	12545://ins poster
-		case	20678://crowbar on floor
-		case	12508://reich poster
-		case	12507://reich cert
-		case	12495://reich poster
-		case	8500://sensors
-		case	20576://medical computer monitor
-		case	20578://medical computer
-		case	8543://securty hq linc terminal
-			return	UI_ICON_LOOK;//look at
-
-		case	4113://sandwhich
-		case	4114://sandwhich
-		case	8://reich card
-		case	9://sunglasses
-		case	8442://key
-		case	8443://wd40
-		case	8446://putty
-		case	24642://linc item
-		case	24602://linc item
-		case	16501://secateurs
-		case	16747://glass
-		case	20527://brick
-		case	20660://tongs
-		case	71://anita card
-		case	49://dog biscuits
-		case	24638://linc
-		case	24639://linc
-		case	24604://linc
-		case	12588://light bulb
-		case	12501://magazine
-		case	12565://tour ticket
-		case	8517://reactor anita card??!
-		case	20526://plaster
-		case	24641://linc world tuning fork
-		case	24787://virus
-		case	12517://video
-		case	12434://anchor
-		case	12435://anchor
-			return	UI_ICON_HAND;
-	}
-
-	return	UI_ICON_USE;
+	switch (id) {
+	case 70: // screen 1 stairs
+	case 4119: // elevator hole
+	case 8210: // outside stairs to furnace
+		return UI_ICON_DOWN;
+
+	case 69: // screen 1 stairs
+		return UI_ICON_UP;//
+
+	case 1: // joey
+	case 4122: // hobbins
+	case 16: // lamb
+	case 8324: // guard
+	case 8211: // sam
+	case 8301: // norville
+	case 8544: // clipboard man
+	case 136: // power room man
+	case 12546: // galagher
+	case 12442: // insurance man
+	case 12430: // anchor man
+	case 12407: // dr burke
+	case 16516: // henri
+	case 16601: // guard
+	case 16441: // piermont
+	case 16599: // gameboy
+	case 16600: // gardener
+	case 16701: // barman
+	case 16772: // babs
+	case 16737: // man1
+	case 16731: // man2
+	case 20911: // ken
+	case 137: // anita
+	case 12289: // mr cool
+	case 8205: // rad suit man
+	case 8309: // guard walkway
+	case 21014: // father @ end
+		return UI_ICON_MOUTH; // talk
+
+	case 4151: // notice
+	case 4152: // ledge-side notice
+	case 12383: // sculpture
+	case 2388: // mural
+	case 12386: // poster
+	case 12387: // ins poster
+	case 12378: // surgery poster
+	case 12375: // surgery poster
+	case 12376: // surgery poster
+	case 12377: // surgery poster
+	case 12401: // dr poster
+	case 12402: // dr poster
+	case 12545: // ins poster
+	case 20678: // crowbar on floor
+	case 12508: // reich poster
+	case 12507: // reich cert
+	case 12495: // reich poster
+	case 8500: // sensors
+	case 20576: // medical computer monitor
+	case 20578: // medical computer
+	case 8543: // securty hq linc terminal
+		return UI_ICON_LOOK;//look at
+
+	case 4113: // sandwhich
+	case 4114: // sandwhich
+	case 8: // reich card
+	case 9: // sunglasses
+	case 8442: // key
+	case 8443: // wd40
+	case 8446: // putty
+	case 24642: // linc item
+	case 24602: // linc item
+	case 16501: // secateurs
+	case 16747: // glass
+	case 20527: // brick
+	case 20660: // tongs
+	case 71: // anita card
+	case 49: // dog biscuits
+	case 24638: // linc
+	case 24639: // linc
+	case 24604: // linc
+	case 12588: // light bulb
+	case 12501: // magazine
+	case 12565: // tour ticket
+	case 8517: // reactor anita card??!
+	case 20526: // plaster
+	case 24641: // linc world tuning fork
+	case 24787: // virus
+	case 12517: // video
+	case 12434: // anchor
+	case 12435: // anchor
+		return  UI_ICON_HAND;
+	}
+
+	return UI_ICON_USE;
 }
 
 bool Mouse::hasSingleInteractIcon(uint32 id) {
-	switch(id) {
-		case	1://joey
-		case	4122://hobbins
-		case	4151://notice
-		case	4152://ledge-side notice
-		case	16://lamb
-		case	8500://sensors
-		case	8324://guard
-		case	8211://sam
-		case	8301://norville
-		case	8544://clipboard man
-		case	136://power room man
-		case	12546://galagher
-		case	12383://sculpture
-		case	12442://insurance man
-		case	12388://mural
-		case	12386://ins poster
-		case	12387://ins poster
-		case	12430://anchor man
-		case	12378://surgery poster
-		case	12375://surgery poster
-		case	12376://surgery poster
-		case	12377://surgery poster
-		case	12407://dr burke
-		case	12401://dr poster
-		case	12402://dr poster
-		case	12545://ins poster
-		case	24810://linc window button
-		case	16516://henri
-		case	16601://guard
-		case	16441://piermont
-		case	16599://gameboy
-		case	16600://gardener
-		case	16701://barman
-		case	16772://babs
-		case	16737://man1
-		case	16731://man2
-//		case	20511://medi joey
-		case	20911://ken
-		case	137://anita
-		case	12508://reich poster
-		case	12507://reich cert
-		case	12495://reich poster
-//		case	12407://patient
-		case	12289://mr cool
-		case	8205://rad suit man
-		case	8309://guard walkway
-
-		case	20576://medical computer monitor
-		case	20578://medical computer
-
-		case	24586://linc maze
-		case	24592://linc maze
-		case	24633://linc maze
-		case	24634://linc maze
-		case	24593://linc maze
-		case	24594://linc maze
-		case	24595://linc maze
-		case	24598://linc maze
-		case	8543://securty hq linc terminal
-
-		case	69://screen 1 stairs
-		case	70://screen 1 stairs
-		case	4119://elevator hole
-		case	8210://outside stairs to furnace
-
-		case	21014://father @ end
-				return	true;
-	}
-
-	return	false;
+	switch (id) {
+	case    1: // joey
+	case    4122: // hobbins
+	case    4151: // notice
+	case    4152: // ledge-side notice
+	case    16: // lamb
+	case    8500: // sensors
+	case    8324: // guard
+	case    8211: // sam
+	case    8301: // norville
+	case    8544: // clipboard man
+	case    136: // power room man
+	case    12546: // galagher
+	case    12383: // sculpture
+	case    12442: // insurance man
+	case    12388: // mural
+	case    12386: // ins poster
+	case    12387: // ins poster
+	case    12430: // anchor man
+	case    12378: // surgery poster
+	case    12375: // surgery poster
+	case    12376: // surgery poster
+	case    12377: // surgery poster
+	case    12407: // dr burke
+	case    12401: // dr poster
+	case    12402: // dr poster
+	case    12545: // ins poster
+	case    24810: // linc window button
+	case    16516: // henri
+	case    16601: // guard
+	case    16441: // piermont
+	case    16599: // gameboy
+	case    16600: // gardener
+	case    16701: // barman
+	case    16772: // babs
+	case    16737: // man1
+	case    16731: // man2
+	case    20911: // ken
+	case    137: // anita
+	case    12508: // reich poster
+	case    12507: // reich cert
+	case    12495: // reich poster
+	case    12289: // mr cool
+	case    8205: // rad suit man
+	case    8309: // guard walkway
+
+	case    20576: // medical computer monitor
+	case    20578: // medical computer
+
+	case    24586: // linc maze
+	case    24592: // linc maze
+	case    24633: // linc maze
+	case    24634: // linc maze
+	case    24593: // linc maze
+	case    24594: // linc maze
+	case    24595: // linc maze
+	case    24598: // linc maze
+	case    8543: // securty hq linc terminal
+
+	case    69: // screen 1 stairs
+	case    70: // screen 1 stairs
+	case    4119: // elevator hole
+	case    8210: // outside stairs to furnace
+
+	case    21014: // father @ end
+		return  true;
+	}
+
+	return  false;
 }
 
 uint16 Mouse::giveXcood(Compact *itemData, uint32 id) {
@@ -573,318 +565,938 @@ uint16 Mouse::giveXcood(Compact *itemData, uint32 id) {
 	midy = itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY >> 1);
 
 	if (mid < HOTSPOT_invx && midy > HOTSPOT_invy)
-		return	HOTSPOT_invx + 16;
+		return  HOTSPOT_invx + 16;
 
 
-	//not lamb
+	// not lamb
 	if (id != 16) {
-		if	(mid > 428)
-			return	428;
-		if	(mid < 142)
-			return	142;
-	}
-
-	switch(id) {
-		case	4112:{mid=258;break;}//cupboard door
-		case	4113:{mid=254;break;}//sandwich
-		case	4114:{mid=254;break;}//spanner
-
-		case	12358:	{mid=428;break;}//bellevue - missing exit
-		case	12681:	{mid=428;break;}//bellevue
-		case	12349:	{mid=142;break;}//bellevue
-		case	12347:	{mid=428;break;}//bellevue
-		case	90:{mid=404;break;}//first room, door
-		case	97:{mid=190;break;}//ledge room, door
-		case	4116:{mid=269;break;}//elevator
-		case	4119:{mid=269;break;}//hole
-		case	4110:{mid=356;break;}//lathe
-		case	8248:{mid=357;break;}//walkway to security lobby
-		case	8238:{mid=181;break;}//walkway to power
-		case	8317:{mid=426;break;}//walkway to crash
-		case	8341:{mid=173;break;}//factory to walkway
-		case	8344:{mid=433;break;}//factory to factory 2
-		case	8500:{mid=224;break;}//sensors
-		case	8355:{mid=428;break;}//factory 2 to factory 3
-		case	8446:{mid=226;break;}//putty
-		case	8438:{mid=226;break;}//gangway
-		case	12680:{mid=201;break;}//exit
-		case	12679:{mid=307;break;}//exit
-		case	12678:{mid=179;break;}//exit
-		case	12677:{mid=319;break;}//exit
-		case	12324:{mid=191;break;}//exit
-		case	12336:{mid=182;break;}//exit
-		case	12442:{mid=376;break;}//exit
-		case	8483:{mid=225;break;}//console
-		case	12641:{mid=158;break;}//exit
-
-		//linc
-		case	12633:{mid=190;break;}//maze
-		case	24586:{mid=210;break;}//maze
-		case	24592:{mid=288;break;}//maze mid-bot
-		case	24593:{mid=400;break;}//maze mid-bot
-		case	24594:{mid=203;break;}//maze left-mid
-		case	24595:{mid=299;break;}//maze left-mid
-
-
-		//hyde
-		case	16496:{mid=263;break;}//plant
-		//cathedral
-		case	16462:{mid=168;break;}//exit
-
-		//lockers
-		case	16576:{mid=246;break;}//body == 16569
-		case	16577:{mid=271;break;}//body == 16570
-		case	16578:{mid=296;break;}//body == 16571
-		case	16579:{mid=321;break;}//body == 16572
-		case	16580:{mid=346;break;}//body == 16573
-
-		//underworld
-		case	20506:{mid=389;break;}//metal door
-		//pit room
-		case	20600:{mid=283;break;}//cover
-		case	20648:{mid=283;break;}//pit
-		case	20570:{mid=247;break;}//exit to medical droid room
-
-		case	20575:{mid=277;break;}//slot
-		case	20577:{mid=297;break;}//recharge unit
-
-		case	24786:{mid=288;break;}//linc crystal
-		case	24787:{mid=288;break;}//virus
-
-		case	20712:{mid=305;break;}//console
-		case	20713:{mid=356;break;}//console
-
-		case	20728:{mid=388;break;}//exit from door room
-
-		case	8272:{mid=278;break;}//power room chair
-
-		case	12390:{mid=187;break;}//burke door
-		case	12541:{mid=187;break;}//burke exit
-
-	}
-
-	return	mid;
+		if (mid > 428)
+			return  428;
+		if (mid < 142)
+			return  142;
+	}
+
+	switch (id) {
+	case 4112: {
+		mid = 258; // cupboard door
+		break;
+	}
+	case 4113: {
+		mid = 254; // sandwich
+		break;
+	}
+	case 4114: {
+		mid = 254; // spanner
+		break;
+	}
+
+	case 12358:  {
+		mid = 428; // bellevue - missing exit
+		break;
+	}
+	case 12681:  {
+		mid = 428; // bellevue
+		break;
+	}
+	case 12349:  {
+		mid = 142; // bellevue
+		break;
+	}
+	case 12347:  {
+		mid = 428; // bellevue
+		break;
+	}
+	case 90: {
+		mid = 404; // first room, door
+		break;
+	}
+	case 97: {
+		mid = 190; // ledge room, door
+		break;
+	}
+	case 4116: {
+		mid = 269; // elevator
+		break;
+	}
+	case 4119: {
+		mid = 269; // hole
+		break;
+	}
+	case 4110: {
+		mid = 356; // lathe
+		break;
+	}
+	case 8248: {
+		mid = 357; // walkway to security lobby
+		break;
+	}
+	case 8238: {
+		mid = 181; // walkway to power
+		break;
+	}
+	case 8317: {
+		mid = 426; // walkway to crash
+		break;
+	}
+	case 8341: {
+		mid = 173; // factory to walkway
+		break;
+	}
+	case 8344: {
+		mid = 433; // factory to factory 2
+		break;
+	}
+	case 8500: {
+		mid = 224; // sensors
+		break;
+	}
+	case 8355: {
+		mid = 428; // factory 2 to factory 3
+		break;
+	}
+	case 8446: {
+		mid = 226; // putty
+		break;
+	}
+	case 8438: {
+		mid = 226; // gangway
+		break;
+	}
+	case 12680: {
+		mid = 201; // exit
+		break;
+	}
+	case 12679: {
+		mid = 307; // exit
+		break;
+	}
+	case 12678: {
+		mid = 179; // exit
+		break;
+	}
+	case 12677: {
+		mid = 319; // exit
+		break;
+	}
+	case 12324: {
+		mid = 191; // exit
+		break;
+	}
+	case 12336: {
+		mid = 182; // exit
+		break;
+	}
+	case 12442: {
+		mid = 376; // exit
+		break;
+	}
+	case 8483: {
+		mid = 225; // console
+		break;
+	}
+	case 12641: {
+		mid = 158; // exit
+		break;
+	}
+
+	// linc
+	case 12633: {
+		mid = 190; // maze
+		break;
+	}
+	case 24586: {
+		mid = 210; // maze
+		break;
+	}
+	case 24592: {
+		mid = 288; // maze mid-bot
+		break;
+	}
+	case 24593: {
+		mid = 400; // maze mid-bot
+		break;
+	}
+	case 24594: {
+		mid = 203; // maze left-mid
+		break;
+	}
+	case 24595: {
+		mid = 299; // maze left-mid
+		break;
+	}
+
+
+	// hyde
+	case 16496: {
+		mid = 263; // plant
+		break;
+	}
+	// cathedral
+	case 16462: {
+		mid = 168; // exit
+		break;
+	}
+
+	// lockers
+	case 16576: {
+		mid = 246; // body == 16569
+		break;
+	}
+	case 16577: {
+		mid = 271; // body == 16570
+		break;
+	}
+	case 16578: {
+		mid = 296; // body == 16571
+		break;
+	}
+	case 16579: {
+		mid = 321; // body == 16572
+		break;
+	}
+	case 16580: {
+		mid = 346; // body == 16573
+		break;
+	}
+
+	// underworld
+	case 20506: {
+		mid = 389; // metal door
+		break;
+	}
+	// pit room
+	case 20600: {
+		mid = 283; // cover
+		break;
+	}
+	case 20648: {
+		mid = 283; // pit
+		break;
+	}
+	case 20570: {
+		mid = 247; // exit to medical droid room
+		break;
+	}
+
+	case 20575: {
+		mid = 277; // slot
+		break;
+	}
+	case 20577: {
+		mid = 297; // recharge unit
+		break;
+	}
+
+	case 24786: {
+		mid = 288; // linc crystal
+		break;
+	}
+	case 24787: {
+		mid = 288; // virus
+		break;
+	}
+
+	case 20712: {
+		mid = 305; // console
+		break;
+	}
+	case 20713: {
+		mid = 356; // console
+		break;
+	}
+
+	case 20728: {
+		mid = 388; // exit from door room
+		break;
+	}
+
+	case 8272: {
+		mid = 278; // power room chair
+		break;
+	}
+
+	case 12390: {
+		mid = 187; // burke door
+		break;
+	}
+	case 12541: {
+		mid = 187; // burke exit
+		break;
+	}
+
+	}
+
+	return  mid;
 }
 
 uint16 Mouse::giveYcood(Compact *itemData, uint32 id) {
-	//push objects that are too far to left, or to the right, back onto the screen
+	// push objects that are too far to left, or to the right, back onto the screen
 	uint16 mid;
 
-	mid=itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY>>1);
+	mid = itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY >> 1);
 
-	switch(id) {
-		case	4112: {//cupboard door - not if open
-			if	(Logic::_scriptVariables[112])//cupb_flag
-				return	0;
-			mid=221;
-			break;
-		}
-		case	4113:{mid=218;break;}//sandwich
-		case	4114:{mid=226;break;}//spanner
-
-		case	4108:{mid=0;break;}//remove monitor screen
-		case	4111:{mid=0;break;}//remove lazer
-		case	4115:{mid=0;break;}//remove monitor screen
-		case	4117:{mid=0;break;}//remove monitor screen
-		case	4154:{mid=0;break;}//remove right sign
-
-
-		case	12349:	{mid=TWEEKY_EXIT_ADJUST;break;}//bellevue
-		case	12347:	{mid=TWEEKY_EXIT_ADJUST;break;}//bellevue
-		case	12358:	{mid=TWEEKY_EXIT_ADJUST;break;}//bellevue
-		case	90:{mid=208;break;}//first room, door
-		case	97:{mid=216;break;}//ledge room, door
-		case	4116:{mid=259;break;}//elevator
-		case	4119:{mid=259;break;}//hole
-		case	4315:{mid=261;break;}//exit left from junk room
-		case	4103:{mid=242;break;}//exit right from junk room
-		case	4105:{mid=241;break;}//exit left from hobbins room
-		case	4110:{mid=230;break;}//lathe
-		case	8248:{mid=222;break;}//walkway to security lobby
-		case	8238:{mid=222;break;}//walkway to power
-		case	8310:{mid=222;break;}//walkway to first room
-		case	8246:{mid=273;break;}//power exit
-		case	8317:{mid=273;break;}//walkway to crash
-		case	8331:{mid=230;break;}//walkway to factory
-		case	8341:{mid=239;break;}//factory to walkway
-		case	8344:{mid=282;break;}//factory to factory 2
-		case	8500:{mid=197;break;}//sensors
-		case	8355:{mid=255;break;}//factory 2 to factory 3
-		case	8366:{mid=227;break;}//factory 2 to storeroom
-		case	8375:{mid=238;break;}//storeroom to factory 2
-		case	8446:{mid=247;break;}//putty
-		case	8438:{mid=247;break;}//gangway
-		case	8364:{mid=252;break;}//exit
-		case	8459:{mid=252;break;}//exit
-		case	8256:{mid=297;break;}//exit
-
-		//bellevue
-		case	12304:{mid=252;break;}//exit
-		case	12338:{mid=286;break;}//exit
-		case	12681:{mid=250;break;}//exit
-		case	12370:{mid=289;break;}//exit
-		case	12361:{mid=267;break;}//exit
-		case	12679:{mid=179;break;}//exit
-		case	12678:{mid=179;break;}//exit
-		case	12677:{mid=179;break;}//exit
-		case	12313:{mid=284;break;}//exit
-		case	12676:{mid=241;break;}//exit
-		case	12327:{mid=244;break;}//exit
-		case	12315:{mid=286;break;}//exit
-		case	12324:{mid=308;break;}//exit
-		case	12336:{mid=306;break;}//exit
-		case	12442:{mid=246;break;}//exit
-		case	12447:{mid=242;break;}//exit
-		case	12680:{mid=179;break;}//exit
-		case	12459:{mid=281;break;}//exit
-		case	12471:{mid=302;break;}//exit
-		case	12399:{mid=257;break;}//exit
-		case	12390:{mid=264;break;}//burke door
-		case	12541:{mid=264;break;}//burke exit
-
-		case	12630:{mid+=4;break;}//slot
-		case	12616:{mid+=4;break;}//slot
-		case	12629:{mid+=4;break;}//slot
-		case	12628:{mid+=4;break;}//slot
-		case	12627:{mid+=4;break;}//slot
-		case	12626:{mid+=4;break;}//slot
-
-		case	12620:{mid=220;break;}//locker
-		case	12621:{mid=220;break;}//locker
-		case	12622:{mid=220;break;}//locker
-		case	12623:{mid=220;break;}//locker
-		case	12613:{mid=220;break;}//locker
-		case	12624:{mid=220;break;}//locker
-
-		case	12631:{mid=273;break;}//exit
-		case	12641:{mid=290;break;}//exit
-		case	12642:{mid=273;break;}//exit
-
-		case	12474:{mid=282;break;}//lamb door
-		case	12486:{mid=298;break;}//lamb door
-
-		//security room
-		case	8295:{mid=299;break;}//exit
-
-		//hyde
-		case	16415:{mid=261;break;}//exit
-		case	16403:{mid=261;break;}//exit
-		case	16393:{mid=246;break;}//exit
-		case	16487:{mid=256;break;}//exit
-		case	16492:{mid=287;break;}//exit
-		case	16394:{mid=313;break;}//exit
-		case	16412:{mid=276;break;}//exit
-		case	16428:{mid=233;break;}//exit
-		case	16424:{mid=236;break;}//exit
-
-
-		//cathedral
-		case	16462:{mid=296;break;}//exit
-		case	16464:{mid=250;break;}//exit
-		case	16465:{mid=226;break;}//exit
-		case	16474:{mid=263;break;}//exit
-
-		case	16576:{mid=229;break;}//body == 16569
-		case	16577:{mid=229;break;}//body == 16570
-		case	16578:{mid=229;break;}//body == 16571
-		case	16579:{mid=229;break;}//body == 16572
-		case	16580:{mid=229;break;}//body == 16573
-
-		//reactor
-		case	8478:{mid=291;break;}//exit
-		case	8481:{mid=253;break;}//exit
-		case	8511:{mid=271;break;}//exit
-
-		//club
-		case	16538:{mid=279;break;}//exit
-
-		//abandoned subway
-		case	16439:{mid=267;break;}//exit
-
-		//entrance to underworld
-		case	16592:{mid=267;break;}//exit
-
-		//underworld
-		case	16649:{mid=291;break;}//exit
-		case	16660:{mid=285;break;}//exit
-		case	16662:{mid=254;break;}//exit
-		case	16661:{mid=291;break;}//exit
-		case	16671:{mid=291;break;}//exit
-		case	16681:{mid=282;break;}//exit
-		case	16682:{mid=282;break;}//exit
-		case	16719:{mid=287;break;}//exit
-		case	16720:{mid=287;break;}//exit
-		case	16729:{mid=291;break;}//exit
-		case	16730:{mid=301;break;}//exit
-		case	20506:{mid=276;break;}//metal door
-		//underworld main
-		case	20518:{mid=276;break;}//metal door
-		case	20532:{mid=264;break;}//exit
-		case	20558:{mid=296;break;}//exit
-		case	20598:{mid=237;break;}//exit
-		case	20601:{mid=183;break;}//metal bar
-		case	20600:{mid=237;break;}//cover
-		case	20648:{mid=237;break;}//pit
-		case	20570:{mid=268;break;}//exit to medical droid room
-
-		case	20573:{mid=290;break;}//droid room exit
-		case	20579:{mid=272;break;}//droid room exit
-		case	20572:{mid=277;break;}//droid room exit
-		case	20578:{mid=286;break;}//console
-		case	20674:{mid=279;break;}//droid room exit
-
-		case	20675:{mid=238;break;}//robot
-		case	20511:{mid=259;break;}//slot
-
-		case	20583:{mid=291;break;}//tank room exit
-		case	20604:{mid=264;break;}//tank room exit
-		case	20676:{mid=294;break;}//exit
-		case	20619:{mid=269;break;}//exit
-		case	20628:{mid=284;break;}//exit
-		case	20617:{mid=295;break;}//exit
-
-		case	24786:{mid=256;break;}//linc crystal
-		case	24787:{mid=256;break;}//linc crystal
-
-		case	20672:{mid=265;break;}//android room exit
-		case	20696:{mid=265;break;}//android room exit
-		case	20697:{mid=265;break;}//android room exit
-		case	20715:{mid=265;break;}//android room exit
-
-		case	20711:{mid=219;break;}//console
-		case	20712:{mid=219;break;}//console
-		case	20713:{mid=219;break;}//console
-
-		case	20725:{mid=268;break;}//exit
-
-		case	20726:{mid=270;break;}//exit from door room
-		case	20728:{mid=219;break;}//exit from door room
-
-		case	20741:{mid=254;break;}//exit from first vein room
-		case	20743:{mid=279;break;}//exit from first vein room
-		case	20752:{mid=279;break;}//exit near end
-		case	20886:{mid=243;break;}//exit orifice to linc
-
-		case	20874:{mid=0;break;}//pipe support - removed as appears to have no interaction
-
-		//linc
-		case	24592:{mid=306;break;}//maze mid-bot
-		case	24634:{mid=306;break;}//maze mid-bot
-//		case	24633:{mid=308;break;}//maze left-mid
-		case	24594:{mid=278;break;}//maze left-mid
-
-		case	8272:{mid=0;break;}//REMOVE power room chair
-
-		case	8290:
-		case	8291://power room switches
-		{
-			if	(!Logic::_scriptVariables[429])
-				return	0;
-		}
+	switch (id) {
+	case 4112: { // cupboard door - not if open
+		if (Logic::_scriptVariables[112]) // cupb_flag
+			return  0;
+		mid = 221;
+		break;
+	}
+	case 4113: {
+		mid = 218; // sandwich
+		break;
+	}
+	case 4114: {
+		mid = 226; // spanner
+		break;
 	}
 
+	case 4108: {
+		mid = 0; // remove monitor screen
+		break;
+	}
+	case 4111: {
+		mid = 0; // remove lazer
+		break;
+	}
+	case 4115: {
+		mid = 0; // remove monitor screen
+		break;
+	}
+	case 4117: {
+		mid = 0; // remove monitor screen
+		break;
+	}
+	case 4154: {
+		mid = 0; // remove right sign
+		break;
+	}
+	case 12349:
+	// fall through
+	case 12347:
+	case 12358:  {
+		mid = TWEEKY_EXIT_ADJUST; // bellevue
+		break;
+	}
+	case 90: {
+		mid = 208; // first room, door
+		break;
+	}
+	case 97: {
+		mid = 216; // ledge room, door
+		break;
+	}
+	case 4116: {
+		mid = 259; // elevator
+		break;
+	}
+	case 4119: {
+		mid = 259; // hole
+		break;
+	}
+	case 4315: {
+		mid = 261; // exit left from junk room
+		break;
+	}
+	case 4103: {
+		mid = 242; // exit right from junk room
+		break;
+	}
+	case 4105: {
+		mid = 241; // exit left from hobbins room
+		break;
+	}
+	case 4110: {
+		mid = 230; // lathe
+		break;
+	}
+	case 8248: {
+		mid = 222;  // walkway to security lobby
+		break;
+	}
+	case 8238: {
+		mid = 222; // walkway to power
+		break;
+	}
+	case 8310: {
+		mid = 222; // walkway to first room
+		break;
+	}
+	case 8246: {
+		mid = 273; // power exit
+		break;
+	}
+	case 8317: {
+		mid = 273; // walkway to crash
+		break;
+	}
+	case 8331: {
+		mid = 230; // walkway to factory
+		break;
+	}
+	case 8341: {
+		mid = 239; // factory to walkway
+		break;
+	}
+	case 8344: {
+		mid = 282; // factory to factory 2
+		break;
+	}
+	case 8500: {
+		mid = 197; // sensors
+		break;
+	}
+	case 8355: {
+		mid = 255; // factory 2 to factory 3
+		break;
+	}
+	case 8366: {
+		mid = 227; // factory 2 to storeroom
+		break;
+	}
+	case 8375: {
+		mid = 238; // storeroom to factory 2
+		break;
+	}
+	case 8446: {
+		mid = 247; // putty
+		break;
+	}
+	case 8438: {
+		mid = 247; // gangway
+		break;
+	}
+	case 8364: {
+		mid = 252; // exit
+		break;
+	}
+	case 8459: {
+		mid = 252; // exit
+		break;
+	}
+	case 8256: {
+		mid = 297; // exit
+		break;
+	}
+
+	// bellevue
+	case 12304: {
+		mid = 252; // exit
+		break;
+	}
+	case 12338: {
+		mid = 286; // exit
+		break;
+	}
+	case 12681: {
+		mid = 250; // exit
+		break;
+	}
+	case 12370: {
+		mid = 289; // exit
+		break;
+	}
+	case 12361: {
+		mid = 267; // exit
+		break;
+	}
+	case 12679: {
+		mid = 179; // exit
+		break;
+	}
+	case 12678: {
+		mid = 179; // exit
+		break;
+	}
+	case 12677: {
+		mid = 179; // exit
+		break;
+	}
+	case 12313: {
+		mid = 284; // exit
+		break;
+	}
+	case 12676: {
+		mid = 241; // exit
+		break;
+	}
+	case 12327: {
+		mid = 244; // exit
+		break;
+	}
+	case 12315: {
+		mid = 286; // exit
+		break;
+	}
+	case 12324: {
+		mid = 308; // exit
+		break;
+	}
+	case 12336: {
+		mid = 306; // exit
+		break;
+	}
+	case 12442: {
+		mid = 246; // exit
+		break;
+	}
+	case 12447: {
+		mid = 242; // exit
+		break;
+	}
+	case 12680: {
+		mid = 179; // exit
+		break;
+	}
+	case 12459: {
+		mid = 281; // exit
+		break;
+	}
+	case 12471: {
+		mid = 302; // exit
+		break;
+	}
+	case 12399: {
+		mid = 257; // exit
+		break;
+	}
+	case 12390: {
+		mid = 264; // burke door
+		break;
+	}
+	case 12541: {
+		mid = 264; // burke exit
+		break;
+	}
+
+	case 12630: {
+		mid += 4; // slot
+		break;
+	}
+	case 12616: {
+		mid += 4; // slot
+		break;
+	}
+	case 12629: {
+		mid += 4; // slot
+		break;
+	}
+	case 12628: {
+		mid += 4; // slot
+		break;
+	}
+	case 12627: {
+		mid += 4; // slot
+		break;
+	}
+	case 12626: {
+		mid += 4; // slot
+		break;
+	}
+
+	case 12620: {
+		mid = 220; // locker
+		break;
+	}
+	case 12621: {
+		mid = 220; // locker
+		break;
+	}
+	case 12622: {
+		mid = 220; // locker
+		break;
+	}
+	case 12623: {
+		mid = 220; // locker
+		break;
+	}
+	case 12613: {
+		mid = 220; // locker
+		break;
+	}
+	case 12624: {
+		mid = 220; // locker
+		break;
+	}
+
+	case 12631: {
+		mid = 273; // exit
+		break;
+	}
+	case 12641: {
+		mid = 290; // exit
+		break;
+	}
+	case 12642: {
+		mid = 273; // exit
+		break;
+	}
+
+	case 12474: {
+		mid = 282; // lamb door
+		break;
+	}
+	case 12486: {
+		mid = 298; // lamb door
+		break;
+	}
+
+	// security room
+	case 8295: {
+		mid = 299; // exit
+		break;
+	}
+
+	// hyde
+	case 16415: {
+		mid = 261; // exit
+		break;
+	}
+	case 16403: {
+		mid = 261; // exit
+		break;
+	}
+	case 16393: {
+		mid = 246; // exit
+		break;
+	}
+	case 16487: {
+		mid = 256; // exit
+		break;
+	}
+	case 16492: {
+		mid = 287; // exit
+		break;
+	}
+	case 16394: {
+		mid = 313; // exit
+		break;
+	}
+	case 16412: {
+		mid = 276; // exit
+		break;
+	}
+	case 16428: {
+		mid = 233; // exit
+		break;
+	}
+	case 16424: {
+		mid = 236; // exit
+		break;
+	}
+
+
+	// cathedral
+	case 16462: {
+		mid = 296; // exit
+		break;
+	}
+	case 16464: {
+		mid = 250; // exit
+		break;
+	}
+	case 16465: {
+		mid = 226; // exit
+		break;
+	}
+	case 16474: {
+		mid = 263; // exit
+		break;
+	}
+
+	case 16576: {
+		mid = 229; // body == 16569
+		break;
+	}
+	case 16577: {
+		mid = 229; // body == 16570
+		break;
+	}
+	case 16578: {
+		mid = 229; // body == 16571
+		break;
+	}
+	case 16579: {
+		mid = 229; // body == 16572
+		break;
+	}
+	case 16580: {
+		mid = 229; // body == 16573
+		break;
+	}
+
+	// reactor
+	case 8478: {
+		mid = 291; // exit
+		break;
+	}
+	case 8481: {
+		mid = 253; // exit
+		break;
+	}
+	case 8511: {
+		mid = 271; // exit
+		break;
+	}
 
-	return	mid;
+	// club
+	case 16538: {
+		mid = 279; // exit
+		break;
+	}
+
+	// abandoned subway
+	case 16439: {
+		mid = 267; // exit
+		break;
+	}
+
+	// entrance to underworld
+	case 16592: {
+		mid = 267; // exit
+		break;
+	}
+
+	// underworld
+	case 16649: {
+		mid = 291; // exit
+		break;
+	}
+	case 16660: {
+		mid = 285; // exit
+		break;
+	}
+	case 16662: {
+		mid = 254; // exit
+		break;
+	}
+	case 16661: {
+		mid = 291; // exit
+		break;
+	}
+	case 16671: {
+		mid = 291; // exit
+		break;
+	}
+	case 16681: {
+		mid = 282; // exit
+		break;
+	}
+	case 16682: {
+		mid = 282; // exit
+		break;
+	}
+	case 16719: {
+		mid = 287; // exit
+		break;
+	}
+	case 16720: {
+		mid = 287; // exit
+		break;
+	}
+	case 16729: {
+		mid = 291; // exit
+		break;
+	}
+	case 16730: {
+		mid = 301; // exit
+		break;
+	}
+	case 20506: {
+		mid = 276; // metal door
+		break;
+	}
+	// underworld main
+	case 20518: {
+		mid = 276; // metal door
+		break;
+	}
+	case 20532: {
+		mid = 264; // exit
+		break;
+	}
+	case 20558: {
+		mid = 296; // exit
+		break;
+	}
+	case 20598: {
+		mid = 237; // exit
+		break;
+	}
+	case 20601: {
+		mid = 183; // metal bar
+		break;
+	}
+	case 20600: {
+		mid = 237; // cover
+		break;
+	}
+	case 20648: {
+		mid = 237; // pit
+		break;
+	}
+	case 20570: {
+		mid = 268; // exit to medical droid room
+		break;
+	}
+
+	case 20573: {
+		mid = 290; // droid room exit
+		break;
+	}
+	case 20579: {
+		mid = 272; // droid room exit
+		break;
+	}
+	case 20572: {
+		mid = 277; // droid room exit
+		break;
+	}
+	case 20578: {
+		mid = 286; // console
+		break;
+	}
+	case 20674: {
+		mid = 279; // droid room exit
+		break;
+	}
+
+	case 20675: {
+		mid = 238; // robot
+		break;
+	}
+	case 20511: {
+		mid = 259; // slot
+		break;
+	}
+
+	case 20583: {
+		mid = 291; // tank room exit
+		break;
+	}
+	case 20604: {
+		mid = 264; // tank room exit
+		break;
+	}
+	case 20676: {
+		mid = 294; // exit
+		break;
+	}
+	case 20619: {
+		mid = 269; // exit
+		break;
+	}
+	case 20628: {
+		mid = 284; // exit
+		break;
+	}
+	case 20617: {
+		mid = 295; // exit
+		break;
+	}
+
+	case 24786: {
+		mid = 256; // linc crystal
+		break;
+	}
+	case 24787: {
+		mid = 256; // linc crystal
+		break;
+	}
+
+	case 20672: {
+		mid = 265; // android room exit
+		break;
+	}
+	case 20696: {
+		mid = 265; // android room exit
+		break;
+	}
+	case 20697: {
+		mid = 265; // android room exit
+		break;
+	}
+	case 20715: {
+		mid = 265; // android room exit
+		break;
+	}
+
+	case 20711: {
+		mid = 219; // console
+		break;
+	}
+	case 20712: {
+		mid = 219; // console
+		break;
+	}
+	case 20713: {
+		mid = 219; // console
+		break;
+	}
+
+	case 20725: {
+		mid = 268; // exit
+		break;
+	}
+
+	case 20726: {
+		mid = 270; // exit from door room
+		break;
+	}
+	case 20728: {
+		mid = 219; // exit from door room
+		break;
+	}
+
+	case 20741: {
+		mid = 254; // exit from first vein room
+		break;
+	}
+	case 20743: {
+		mid = 279; // exit from first vein room
+		break;
+	}
+	case 20752: {
+		mid = 279; // exit near end
+		break;
+	}
+	case 20886: {
+		mid = 243; // exit orifice to linc
+		break;
+	}
+
+	case 20874: {
+		mid = 0; // pipe support - removed as appears to have no interaction
+		break;
+	}
+
+	// linc
+	case 24592: {
+		mid = 306; // maze mid-bot
+		break;
+	}
+	case 24634: {
+		mid = 306; // maze mid-bot
+		break;
+	}
+	case 24594: {
+		mid = 278; // maze left-mid
+		break;
+	}
+
+	case 8272: {
+		mid = 0; // REMOVE power room chair
+		break;
+	}
+
+	case 8290:
+	case 8291: { // power room switches
+		if (!Logic::_scriptVariables[429])
+			return  0;
+	}
+	}
+
+	return mid;
 }
 
 int Mouse::touchingFloor(uint16 xPos, uint16 yPos) {
@@ -893,9 +1505,9 @@ int Mouse::touchingFloor(uint16 xPos, uint16 yPos) {
 	Compact *itemData;
 	uint16 itemNum;
 
-	//do not detect floors beyond a certain depth
-	if	(yPos > (HOTSPOT_invy+8)) return 0;
-	if	(yPos<(20+TOP_LEFT_Y))	return 0;
+	// do not detect floors beyond a certain depth
+	if (yPos > (HOTSPOT_invy + 8)) return 0;
+	if (yPos < (20 + TOP_LEFT_Y)) return 0;
 
 	do {
 		currentList = (uint16 *)_skyCompact->fetchCpt(currentListNum);
@@ -904,97 +1516,94 @@ int Mouse::touchingFloor(uint16 xPos, uint16 yPos) {
 			itemData = _skyCompact->fetchCpt(itemNum);
 			currentList++;
 
-			//on this screen, active, and a floor
+			// on this screen, active, and a floor
 			if ((itemData->screen == Logic::_scriptVariables[SCREEN]) && (!itemData->mouseOn) && (itemData->status & 16)) {
 				if (itemData->xcood + ((int16)itemData->mouseRelX) > xPos) continue;
 				if (itemData->xcood + ((int16)itemData->mouseRelX) + itemData->mouseSizeX < xPos) continue;
 				if (itemData->ycood + ((int16)itemData->mouseRelY) > yPos) continue;
 				if (itemData->ycood + ((int16)itemData->mouseRelY) + itemData->mouseSizeY < yPos) continue;
 
-				//hit this floor - we're done here
-				return	itemNum;
+				// hit this floor - we're done here
+				return  itemNum;
 			}
 		}
 		if (*currentList == 0xFFFF)
 			currentListNum = currentList[1];
 	} while (*currentList != 0);
 
-	//found nowt
-	return	0;
+	// found nowt
+	return 0;
 }
 
 void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 
-	if (SkyEngine::_isIbass()) {
-		int midx, midy; //open hotspot dimensions
+	if (SkyEngine::isIbass()) {
+		int midx, midy; // open hotspot dimensions
 		Compact *itemData;
 		int itemProx;
 		int d = 0;
 
-		debug("TOP: _mouseB = %d, _fadeout = %d", _mouseB, _fadeOut);
-
 		if (yPos < (TOP_LEFT_Y + 5))
 			return;
 
-		//mouse must be down to search for stuff
+		// mouse must be down to search for stuff
 		if (_mouseB) {
-			//debug("Clicked");
-			//what are we near?
-			itemProx = doProximityHighlights(xPos,yPos);
+			// debug("Clicked");
+			// what are we near?
+			itemProx = doProximityHighlights(xPos, yPos);
 
-			//seems we need to clear this, but only safe to do so when a new click occurs as player is still live when walking to interact after a use-on interaction
-			//but not in linc terminal
-			if	(101 != Logic::_scriptVariables[SCREEN])
+			// seems we need to clear this, but only safe to do so when a new click occurs as player is still live when walking to interact after a use-on interaction
+			// but not in linc terminal
+			if (101 != Logic::_scriptVariables[SCREEN])
 				Logic::_scriptVariables[OBJECT_HELD] = 0;
 
-			//need to check if still touching any currently popped up hotspot
+			// need to check if still touching any currently popped up hotspot
 			if (_touchId && _touchId != 32767 && _timeOn < CLICK_THRESHOLD) {
 				if (_prevMouseOn == false)
 					_timeOn = 1;
 
-				//fetch the compact
+				// fetch the compact
 				itemData = _skyCompact->fetchCpt(_touchId);
 
-				//if not a floor
+				// if not a floor
 				if (itemData->mouseOn) {
-					((SkyEngine *)g_engine)->getScreen()->setProximityNotAnimate(_nearestProximityIconId);//we want this one remaining one to not animate
+					_skyScreen->setProximityNotAnimate(_nearestProximityIconId);//we want this one remaining one to not animate
 
 					midx = giveXcood(itemData, _touchId);
 					midy = giveYcood(itemData, _touchId);
-					//calc dist
+					// calc dist
 					d = abs(xPos - midx) + abs(yPos - midy);
 
-					//some left hand edge adjust for twin-hotspot non-exits
+					// some left hand edge adjust for twin-hotspot non-exits
 					if (!hasSingleInteractIcon(_touchId) && !_isExit)
 						if ((midx - HOTSPOT_dim) < TOP_LEFT_X)
 							midx = TOP_LEFT_X + HOTSPOT_dim;
 
-					//still touching a normal hotspot?
+					// still touching a normal hotspot?
 					if (!_isExit && midx - HOTSPOT_dim < xPos && midx + HOTSPOT_dim > xPos && midy - HOTSPOT_yoff < yPos && midy/*+HOTSPOT_yoff*/ > yPos) {
-						//if newly touching, and same item as last time, then inc the click count
-						if	(_prevMouseOn == false) {
+						// if newly touching, and same item as last time, then inc the click count
+						if (_prevMouseOn == false) {
 
-							_clickedNum++;	//one more click
-							//reset fade out timer to max
+							_clickedNum++;  // one more click
+							// reset fade out timer to max
 							_fadeOut = HOTSPOT_FADEOUT;
-							//reset hover time
+							// reset hover time
 							_timeOn = 1;
-						}
-						else
+						} else
 							_timeOn++;
 
-						int	icony = midy - HOTSPOT_yoff;
-						icony -= TOP_LEFT_Y;//normalise for renderer
+						int icony = midy - HOTSPOT_yoff;
+						icony -= TOP_LEFT_Y; // normalise for renderer
 						if (icony < 0)
 							icony = 0;
 
 						if (hasSingleInteractIcon(_touchId)) {
-							//update the coordinate of the hotspot
+							// update the coordinate of the hotspot
 							midx -= TOP_LEFT_X;
 							midx -= HOTSPOT_ExitDim;
 
-							//draw the icons
-							((SkyEngine *)g_engine)->getScreen()->setIcon( getInteractIcon(_touchId), midx+4, icony);
+							// draw the icons
+							_skyScreen->setIcon(getInteractIcon(_touchId), midx + 4, icony);
 							_actionFlashX = midx + 4;
 							_actionFlashIcon = getInteractIcon(_touchId);
 							_actionFlashY = icony;
@@ -1019,230 +1628,226 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 						// mouse on
 						_prevMouseOn = true;
 
-						//end here, when button held on something
+						// end here, when button held on something
 						return;
 					} else if (_isExit && midx - HOTSPOT_dim < xPos && midx + HOTSPOT_dim > xPos && midy - HOTSPOT_yoff < yPos && midy/*+HOTSPOT_yoff*/ > yPos) {
-						//still touching the poped up exit
-						//which action
+						// still touching the poped up exit
+						// which action
 						Logic::_scriptVariables[BUTTON] = 1;
 
-						//if newly touching, and same item as last time, then inc the click count
+						// if newly touching, and same item as last time, then inc the click count
 						if (_prevMouseOn == false) {
-							_clickedNum++;	//one more click
-							//reset fade out timer to max
+							_clickedNum++;  // one more click
+							// reset fade out timer to max
 							_fadeOut = HOTSPOT_FADEOUT;
-							//reset hover time
+							// reset hover time
 							_timeOn = 0;
 						} else {
 							_timeOn++; // one more cycle
-							//update the coordinate of the hotspot
-							int	iconx = midx - HOTSPOT_ExitDim;
-							iconx -= TOP_LEFT_X;//normalise for renderer
-							if	(iconx < 0)
+							// update the coordinate of the hotspot
+							int iconx = midx - HOTSPOT_ExitDim;
+							iconx -= TOP_LEFT_X; // normalise for renderer
+							if (iconx < 0)
 								iconx = 0;
 
-							int	icony = midy - HOTSPOT_exit_yoff;
-							icony -= TOP_LEFT_Y;//normalise for renderer
-							if	(icony < 0)
+							int icony = midy - HOTSPOT_exit_yoff;
+							icony -= TOP_LEFT_Y; // normalise for renderer
+							if (icony < 0)
 								icony = 0;
 
-							//draw the icon
+							// draw the icon
 							initExitIcon(_exitType, iconx, icony);
 
 							_actionFlashY = icony;
 						}
 
-						//mouse on
-						_prevMouseOn=true;
+						// mouse on
+						_prevMouseOn = true;
 
-						//end here, when button held on something
+						// end here, when button held on something
 						return;
 					} else {
 						_touchId = 0;
 						_clickedNum = 0;
 					}
-				} else {// else if floor
-					//floors just count time - we only want clicks(jabs)
-					//still touching it?
+				} else { // else if floor
+					// floors just count time - we only want clicks(jabs)
+					// still touching it?
 					if ((itemData->xcood + ((int16)itemData->mouseRelX) < xPos) && (itemData->xcood + ((int16)itemData->mouseRelX) + itemData->mouseSizeX > xPos) && (itemData->ycood + ((int16)itemData->mouseRelY) < yPos) && (itemData->ycood + ((int16)itemData->mouseRelY) + itemData->mouseSizeY > yPos))
-						_timeOn++;//one more cycle
+						_timeOn++; // one more cycle
 					else {
-						_touchId=0;
-						_clickedNum=0;
+						_touchId = 0;
+						_clickedNum = 0;
 					}
 				}
 			}
-			//find if we're touching a floor
-			int	floor = touchingFloor(xPos, yPos);
+			// find if we're touching a floor
+			int floor = touchingFloor(xPos, yPos);
 
 			if (itemProx) {
 				itemData = _skyCompact->fetchCpt(itemProx);
-				midx=giveXcood(itemData, itemProx);	//->xcood + ((int16)itemData->mouseRelX) + (itemData->mouseSizeX>>1);
-				midy=giveYcood(itemData, itemProx);//itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY>>1);
-				//calc dist
-				d= abs(xPos-midx)+abs(yPos-midy);
+				midx = giveXcood(itemData, itemProx);
+				midy = giveYcood(itemData, itemProx);
+				// calc dist
+				d = abs(xPos - midx) + abs(yPos - midy);
 			}
 
-			//not close enough to real hotspot, and still touching previous floor
+			// not close enough to real hotspot, and still touching previous floor
 			if (floor && (d >= USE_ON_DIST) && floor == _touchId)
-				//if we skip floor, and dont hit another hotspot, then we quit after this search, because there is no fadeOut on floors, so the system resets the couter
-				//floorSkip=true;
-				//continue;
+				// if we skip floor, and dont hit another hotspot, then we quit after this search, because there is no fadeOut on floors, so the system resets the couter
+				// floorSkip=true;
+				// continue;
 				return;
 
 			if ((itemProx && d < USE_ON_DIST) || floor) {
 				// we've hit a new object
 
-				//floor or object?
+				// floor or object?
 				if (itemProx && d < USE_ON_DIST) {
-					//record what we're touching
-					Logic::_scriptVariables[SPECIAL_ITEM] = itemProx;//put in here now, for mouseOn script
+					// record what we're touching
+					Logic::_scriptVariables[SPECIAL_ITEM] = itemProx; // put in here now, for mouseOn script
 					_touchId = itemProx;
-					_touchIdLegacy = itemProx;	//remembered when mouse off
-				}
-				else {
-					//record what we're touching
-					Logic::_scriptVariables[SPECIAL_ITEM] = floor;//put in here now, for mouseOn script
+					_touchIdLegacy = itemProx; // remembered when mouse off
+				} else {
+					// record what we're touching
+					Logic::_scriptVariables[SPECIAL_ITEM] = floor; // put in here now, for mouseOn script
 					_touchId = floor;
-					_touchIdLegacy = floor;	//remembered when mouse off
+					_touchIdLegacy = floor; // remembered when mouse off
 				}
 
 				itemData = _skyCompact->fetchCpt(_touchId);
 
-				//jumping straight from one object to another?
+				// jumping straight from one object to another?
 				if (Logic::_scriptVariables[SPECIAL_ITEM]) {
-					//remove hotspot icons
-					((SkyEngine *)g_engine)->getScreen()->clearAllIbassIcons(false);
+					// remove hotspot icons
+					_skyScreen->clearAllIbassIcons(false);
 				}
 
-				//reset hover time to max
+				// reset hover time to max
 				_timeOn = 1;
 				_clickedNum = 0;
 
-				//run previous items get-off, if there was one (gone straight from one object onto another!)
+				// run previous items get-off, if there was one (gone straight from one object onto another!)
 				if (Logic::_scriptVariables[GET_OFF])
 					_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], itemData);
 
-				//write mouse off script number
+				// write mouse off script number
 				Logic::_scriptVariables[GET_OFF] = itemData->mouseOff;
 
-				//run the mouse on script
+				// run the mouse on script
 				if (itemData->mouseOn) {
-					//disallow sliding back onto floors
+					// disallow sliding back onto floors
 					_floorLock = true;
 
-					//reset fade out timer
+					// reset fade out timer
 					_fadeOut = HOTSPOT_FADEOUT;
 					debug("Fadeout det to 36, mouseOn = %d, dist = %d", itemData->mouseOn, d);
 
-					((SkyEngine *)g_engine)->getScreen()->setProximityNotAnimate(_nearestProximityIconId);//we want this one remaining one to not animate
+					_skyScreen->setProximityNotAnimate(_nearestProximityIconId); // we want this one remaining one to not animate
 
-					//assume not
+					// assume not
 					_isExit = false;
 					_isFloor = false;
 
 					_skyLogic->mouseScript(itemData->mouseOn, itemData);
 
-					//exit, or hotspot?
+					// exit, or hotspot?
 					if (_isExit) {
 
-						int	iconx = midx - HOTSPOT_ExitDim;
-						iconx -= TOP_LEFT_X;//normalise for renderer
+						int iconx = midx - HOTSPOT_ExitDim;
+						iconx -= TOP_LEFT_X; // normalise for renderer
 						if (iconx < 0)
 							iconx = 0;
 
-						int	icony = midy - HOTSPOT_exit_yoff;
-						icony -= TOP_LEFT_Y;//normalise for renderer
+						int icony = midy - HOTSPOT_exit_yoff;
+						icony -= TOP_LEFT_Y; // normalise for renderer
 						if (icony < 0)
 							icony = 0;
 
-						//draw the icon
+						// draw the icon
 						initExitIcon(_exitType, iconx, icony);
 					} else {
-						int	icony = midy - HOTSPOT_yoff;
-						icony -= TOP_LEFT_Y;//normalise for renderer
+						int icony = midy - HOTSPOT_yoff;
+						icony -= TOP_LEFT_Y;// normalise for renderer
 						if (icony < 0)
 							icony = 0;
 
 						if (hasSingleInteractIcon(_touchId)) {
-							//update the coordinate of the hotspot
-							int	iconx = midx - HOTSPOT_ExitDim;
-							iconx -= TOP_LEFT_X;//normalise for renderer
+							// update the coordinate of the hotspot
+							int iconx = midx - HOTSPOT_ExitDim;
+							iconx -= TOP_LEFT_X;// normalise for renderer
 							if (iconx < 0)
 								iconx = 0;
 
-							//draw the icons
+							// draw the icons
 
-							((SkyEngine *)g_engine)->getScreen()->setIcon( getInteractIcon(_touchId), iconx+4, icony);
+							_skyScreen->setIcon(getInteractIcon(_touchId), iconx + 4, icony);
 
-							if (_touchId == 70 || _touchId == 69 || _touchId == 24633 || _touchId == 24634 || _touchId == 4119 || _touchId == 8210)//stairs on screen 1 - normal object turned into exit - need to hack the button - the rest are either talk-to, which doesnt seem to matter, or look-at, like posters on walls
+							if (_touchId == 70 || _touchId == 69 || _touchId == 24633 || _touchId == 24634 || _touchId == 4119 || _touchId == 8210) // stairs on screen 1 - normal object turned into exit - need to hack the button - the rest are either talk-to, which doesnt seem to matter, or look-at, like posters on walls
 								Logic::_scriptVariables[BUTTON] = 1;
 							else
 								Logic::_scriptVariables[BUTTON] = 2;
 
-						} else {	//2 icons
-							//update the coordinate of the hotspot
-							int	iconx = midx - HOTSPOT_dim;
-							iconx -= TOP_LEFT_X;//normalise for renderer
+						} else { // 2 icons
+							// update the coordinate of the hotspot
+							int iconx = midx - HOTSPOT_dim;
+							iconx -= TOP_LEFT_X;// normalise for renderer
 							if (iconx < 0)
 								iconx = 0;
 
-							//draw the icons
-							((SkyEngine *)g_engine)->getScreen()->setIcon(UI_ICON_LOOK, iconx, icony);
-							((SkyEngine *)g_engine)->getScreen()->setIcon(getInteractIcon(_touchId), iconx+HOTSPOT_dim+4, icony);
+							// draw the icons
+							_skyScreen->setIcon(UI_ICON_LOOK, iconx, icony);
+							_skyScreen->setIcon(getInteractIcon(_touchId), iconx + HOTSPOT_dim + 4, icony);
 						}
 					}
-				} else if (!_floorLock) {//no mouseOn script, which probably always means this is a floor?
-					//set action
+				} else if (!_floorLock) { // no mouseOn script, which probably always means this is a floor?
+					// set action
 					Logic::_scriptVariables[BUTTON] = 1;
-					//non graphical hotspots - floors - can interact first click
+					// non graphical hotspots - floors - can interact first click
 					_clickedNum = 1;
-					//reset hover time to max
+					// reset hover time to max
 					_timeOn = 1;
 					_isFloor = true;
 				} else
-					_touchId = 0; //locked floor
+					_touchId = 0; // locked floor
 
-				//mouse on
+				// mouse on
 				_prevMouseOn = true;
-				//we're done
+				// we're done
 				return;
 			} else {
 				debug("nothing");
-				//not touching anything, force open hotspot to close
+				// not touching anything, force open hotspot to close
 				if (_fadeOut)
-					_fadeOut=0;
+					_fadeOut = 0;
 			}
-			//not touching a game object - but what about HU buttons, such as Inv?
-			if (!_prevMouseOn && 101!=Logic::_scriptVariables[SCREEN] && Logic::_scriptVariables[LOGIC_LIST_NO]!=24765) {
+			// not touching a game object - but what about HU buttons, such as Inv?
+			if (!_prevMouseOn && 101 != Logic::_scriptVariables[SCREEN] && Logic::_scriptVariables[LOGIC_LIST_NO] != 24765) {
 				if (xPos < HOTSPOT_invx && yPos > HOTSPOT_invy) {
-					// _system->playUISFX(UI_SOUND_MENU_INTO);
-					_skyLogic->Start_inventory();
+					_skyLogic->startInventory();
 					_touchId = 0;
 					_holding = false;
-					m_mode = PreInventory;
-					((SkyEngine *)g_engine)->getScreen()->clearAllProximityIcons(false);
-					((SkyEngine *)g_engine)->getScreen()->clearAllIbassIcons(false);
+					M_MODE = PRE_INVENTORY;
+					_skyScreen->clearAllProximityIcons(false);
+					_skyScreen->clearAllIbassIcons(false);
 					return;
 				}
-				//control panel
+				// control panel
 				if (xPos < HOTSPOT_optionsx && yPos < HOTSPOT_optionsy) {
-					//_system->playUISFX(UI_SOUND_MENU_INTO);
-					((SkyEngine *)g_engine)->getControl()->doControlPanel();
-					((SkyEngine *)g_engine)->getScreen()->clearAllProximityIcons(false);
-					((SkyEngine *)g_engine)->getScreen()->clearAllIbassIcons(false);
+					_skyControl->doControlPanel();
+					_skyScreen->clearAllProximityIcons(false);
+					_skyScreen->clearAllIbassIcons(false);
 					_mouseB = 0;
 				}
-				//help screen
-				if (xPos>HOTSPOT_helpx && yPos<HOTSPOT_helpy) {
-					//_system->playUISFX(UI_SOUND_MENU_INTO);
-					((SkyEngine *)g_engine)->getScreen()->clearAllProximityIcons(false);
-					((SkyEngine *)g_engine)->getScreen()->clearAllIbassIcons(false);
+				// help screen
+				if (xPos > HOTSPOT_helpx && yPos < HOTSPOT_helpy) {
+					_skyScreen->clearAllProximityIcons(false);
+					_skyScreen->clearAllIbassIcons(false);
 					_mouseB = 0;
 				}
 			}
 
-			//mouse on
+			// mouse on
 			_prevMouseOn = true;
 
 
@@ -1251,96 +1856,91 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 			if (_prevMouseOn) {
 
 				if (!_touchId || _isFloor)
-					((SkyEngine *)g_engine)->getScreen()->clearAllProximityIcons();
+					_skyScreen->clearAllProximityIcons();
 
 				else if (_touchId) {
-					((SkyEngine *)g_engine)->getScreen()->clearAllProximityIcons();
-					//clear all but the one relating to the highlighted hotspot - hmmm
+					_skyScreen->clearAllProximityIcons();
+					// clear all but the one relating to the highlighted hotspot - hmmm
 					itemData = _skyCompact->fetchCpt(_touchId);
-					midx = giveXcood(itemData,_touchId);
-					midy = giveYcood(itemData,_touchId);//itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY>>1);
-					((SkyEngine *)g_engine)->getScreen()->setProximityIcon(0, midx-TOP_LEFT_X-4, ((midy-TOP_LEFT_Y)-4), 1.0, 0);
-					((SkyEngine *)g_engine)->getScreen()->setProximityNotAnimate(0);//we want this one remaining one to not animate
+					midx = giveXcood(itemData, _touchId);
+					midy = giveYcood(itemData, _touchId); //itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY>>1);
+					_skyScreen->setProximityIcon(0, midx - TOP_LEFT_X - 4, ((midy - TOP_LEFT_Y) - 4), 1.0, 0);
+					_skyScreen->setProximityNotAnimate(0);//we want this one remaining one to not animate
 				}
 			}
 
-			//let go
+			// let go
 			_prevMouseOn = false;
 			_floorLock = false;
 
-			//if 2nd or more click on this item
+			// if 2nd or more click on this item
 			if (_timeOn && _clickedNum) {
 
 
-				//faking the click so that the engine scripts execute correctly
+				// faking the click so that the engine scripts execute correctly
 				_logicClick = true;
 				if (Logic::_scriptVariables[BUTTON] == 0)
 					Logic::_scriptVariables[BUTTON] = 1;
 
-				//first, some autosaving incase this is a fatal, yes FATAL, interaction
+				// first, some autosaving incase this is a fatal, yes FATAL, interaction
 				if (g_engine->canSaveGameStateCurrently())
 					g_engine->saveGameState(0, "Autosave", true);
 
-				//an sfx
-				//Sky::g_engine->giveSystem()->playUISFX(UI_SOUND_MENU_ACK);
-				debug("WIPED");
+				// an sfx
 
-				_fadeOut = 0;	//force getOff script to run also
+				_fadeOut = 0;   // force getOff script to run also
 
-				//setup action flash
+				// setup action flash
 				if (!_isFloor) {
 					_actionFlash = true;
 					_actionFlashTime = ACTION_FLASH_TIME;
 				}
-				//set this again, as there's a chance some other random script may have cleared it since we first touched this hotspot
+				// set this again, as there's a chance some other random script may have cleared it since we first touched this hotspot
 				Logic::_scriptVariables[SPECIAL_ITEM] = _touchId;
 
 
-				//over anything?
+				// over anything?
 				Compact *item = _skyCompact->fetchCpt(Logic::_scriptVariables[SPECIAL_ITEM]);
-				if (item->mouseClick/* && item->cursorText*/)//not floors
+				if (item->mouseClick/* && item->cursorText*/)// not floors
 					_skyLogic->mouseScript(item->mouseClick, item);
 			}
 
-			//reset ready for next stab
+			// reset ready for next stab
 			_timeOn = 0;
-			//debug("Else block executed");
 		}
 
-		//mouse is not pressed, or not touching anything
+		// mouse is not pressed, or not touching anything
 
-		//count down to fade out and run get-off
+		// count down to fade out and run get-off
 		if (_fadeOut) {
 			_fadeOut--;
-			warning("_fadeout = %d, _touchIdLegacy: %d", _fadeOut, _touchIdLegacy);
-			//update coordinate, so hotspot follows walking megas
+			// update coordinate, so hotspot follows walking megas
 			updateHotspotCoordinate(xPos);
 		}
 
 		if (!_fadeOut) {
-			((SkyEngine *)g_engine)->getScreen()->clearAllProximityIcons();
+			_skyScreen->clearAllProximityIcons();
 
-			//reset number of times we clicked on this
-			_clickedNum=0;
-			_touchId=0;
+			// reset number of times we clicked on this
+			_clickedNum = 0;
+			_touchId = 0;
 
-			//process get-off script, if we were touching, and there is one
+			// process get-off script, if we were touching, and there is one
 			if (Logic::_scriptVariables[SPECIAL_ITEM] != 0) {
-				//close the hotspot popup
+				// close the hotspot popup
 
-				//remove hotspot icons
-				((SkyEngine *)g_engine)->getScreen()->clearAllIbassIcons(true);
+				// remove hotspot icons
+				_skyScreen->clearAllIbassIcons(true);
 
 				Logic::_scriptVariables[SPECIAL_ITEM] = 0;
 
-				//get off
+				// get off
 				if (Logic::_scriptVariables[GET_OFF])
-					_skyLogic->script((uint16)Logic::_scriptVariables[GET_OFF],(uint16)(Logic::_scriptVariables[GET_OFF] >> 16));
+					_skyLogic->script((uint16)Logic::_scriptVariables[GET_OFF], (uint16)(Logic::_scriptVariables[GET_OFF] >> 16));
 
 				Logic::_scriptVariables[GET_OFF] = 0;
 			}
 		}
-		_mouseB = 0;
 		return;
 	}
 
@@ -1353,10 +1953,14 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 			Compact *itemData = _skyCompact->fetchCpt(itemNum);
 			currentList++;
 			if ((itemData->screen == Logic::_scriptVariables[SCREEN]) && (itemData->status & 16)) {
-				if (itemData->xcood + ((int16)itemData->mouseRelX) > xPos) continue;
-				if (itemData->xcood + ((int16)itemData->mouseRelX) + itemData->mouseSizeX < xPos) continue;
-				if (itemData->ycood + ((int16)itemData->mouseRelY) > yPos) continue;
-				if (itemData->ycood + ((int16)itemData->mouseRelY) + itemData->mouseSizeY < yPos) continue;
+				if (itemData->xcood + ((int16)itemData->mouseRelX) > xPos)
+					continue;
+				if (itemData->xcood + ((int16)itemData->mouseRelX) + itemData->mouseSizeX < xPos)
+					continue;
+				if (itemData->ycood + ((int16)itemData->mouseRelY) > yPos)
+					continue;
+				if (itemData->ycood + ((int16)itemData->mouseRelY) + itemData->mouseSizeY < yPos)
+					continue;
 				// we've hit the item
 				if (Logic::_scriptVariables[SPECIAL_ITEM] == itemNum)
 					return;
@@ -1382,77 +1986,77 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 }
 
 void Mouse::initExitIcon(uint32 type, int iconx, int icony) {
-	switch(type) {
-		case MOUSE_LEFT: {
-			_actionFlashIcon = UI_ICON_LEFT;
-			_actionFlashX = iconx + 8;
-			((SkyEngine *)g_engine)->getScreen()->setIcon(UI_ICON_LEFT, iconx + 8, icony);
-			break;
-		}
-		case MOUSE_RIGHT: {
-			_actionFlashIcon = UI_ICON_RIGHT;
-			_actionFlashX = iconx + 4;
-			((SkyEngine *)g_engine)->getScreen()->setIcon(UI_ICON_RIGHT, iconx + 4, icony);
-			break;
-		}
-		case MOUSE_UP: {
-			_actionFlashIcon = UI_ICON_UP;
-			_actionFlashX = iconx + 5;
-			((SkyEngine *)g_engine)->getScreen()->setIcon(UI_ICON_UP, iconx + 5, icony);
-			break;
-		}
-		case MOUSE_DOWN: {
-			_actionFlashIcon = UI_ICON_DOWN;
-			_actionFlashX = iconx + 5;
-			((SkyEngine *)g_engine)->getScreen()->setIcon(UI_ICON_DOWN, iconx + 5, icony);
-			break;
-		}
+	switch (type) {
+	case MOUSE_LEFT: {
+		_actionFlashIcon = UI_ICON_LEFT;
+		_actionFlashX = iconx + 8;
+		_skyScreen->setIcon(UI_ICON_LEFT, iconx + 8, icony);
+		break;
+	}
+	case MOUSE_RIGHT: {
+		_actionFlashIcon = UI_ICON_RIGHT;
+		_actionFlashX = iconx + 4;
+		_skyScreen->setIcon(UI_ICON_RIGHT, iconx + 4, icony);
+		break;
+	}
+	case MOUSE_UP: {
+		_actionFlashIcon = UI_ICON_UP;
+		_actionFlashX = iconx + 5;
+		_skyScreen->setIcon(UI_ICON_UP, iconx + 5, icony);
+		break;
+	}
+	case MOUSE_DOWN: {
+		_actionFlashIcon = UI_ICON_DOWN;
+		_actionFlashX = iconx + 5;
+		_skyScreen->setIcon(UI_ICON_DOWN, iconx + 5, icony);
+		break;
+	}
 	}
 }
 
 void Mouse::updateHotspotCoordinate(uint16 xPos) {
 	Compact *itemData;
-	int	midx,  midy;
+	int midx,  midy;
 
-	//fetch the compact
+	// fetch the compact
 	itemData = _skyCompact->fetchCpt(_touchIdLegacy);
 
 	if (!itemData)
 		return;
 
-	//if not a floor
+	// if not a floor
 	if (itemData->mouseOn && !_isExit) {
 
-		midx = giveXcood(itemData,_touchIdLegacy);//itemData->xcood + ((int16)itemData->mouseRelX) + (itemData->mouseSizeX>>1);
-		midy = giveYcood(itemData,_touchIdLegacy);//itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY>>1);
+		midx = giveXcood(itemData, _touchIdLegacy);
+		midy = giveYcood(itemData, _touchIdLegacy);
 
-		int	icony = midy - HOTSPOT_yoff;
-		icony -= TOP_LEFT_Y;//normalise for renderer
-		if	(icony < 0)
+		int icony = midy - HOTSPOT_yoff;
+		icony -= TOP_LEFT_Y; // normalise for renderer
+		if (icony < 0)
 			icony = 0;
 
-		if	(hasSingleInteractIcon(_touchIdLegacy)) {
-			//update the coordinate of the hotspot
-			int	iconx = midx - HOTSPOT_ExitDim;
+		if (hasSingleInteractIcon(_touchIdLegacy)) {
+			// update the coordinate of the hotspot
+			int iconx = midx - HOTSPOT_ExitDim;
 			iconx -= TOP_LEFT_X;//normalise for renderer
-			if	(iconx < 0)
+			if (iconx < 0)
 				iconx = 0;
 
-			//draw the icons
-			((SkyEngine *)g_engine)->getScreen()->setIcon(getInteractIcon(_touchIdLegacy), iconx + 4, icony);
+			// draw the icons
+			_skyScreen->setIcon(getInteractIcon(_touchIdLegacy), iconx + 4, icony);
 		} else {
-			//update the coordinate of the hotspot
-			int	iconx = midx - HOTSPOT_dim;
+			// update the coordinate of the hotspot
+			int iconx = midx - HOTSPOT_dim;
 			iconx -= TOP_LEFT_X;//normalise for renderer
-			if	(iconx < 0)
+			if (iconx < 0)
 				iconx = 0;
 
-			//draw the icons
-			((SkyEngine *)g_engine)->getScreen()->setIcon(UI_ICON_LOOK, iconx, icony);
-			((SkyEngine *)g_engine)->getScreen()->setIcon(getInteractIcon(_touchIdLegacy), iconx + HOTSPOT_dim + 4, icony);
+			// draw the icons
+			_skyScreen->setIcon(UI_ICON_LOOK, iconx, icony);
+			_skyScreen->setIcon(getInteractIcon(_touchIdLegacy), iconx + HOTSPOT_dim + 4, icony);
 
-			//still touching the poped up area
-			//which action
+			// still touching the poped up area
+			// which action
 			if (xPos <= midx)
 				Logic::_scriptVariables[BUTTON] = 2;
 			else
@@ -1530,4 +2134,233 @@ bool Mouse::wasClicked() {
 		return false;
 }
 
+void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
+	uint32 *objList;
+	int j, num;
+	Compact *itemData;
+	bool touched = false;
+
+	if (_mouseB)
+		_logicClick++;
+	else
+		_logicClick = 0;
+
+	// get list of compacts in inventory
+	objList = _skyLogic->giveInvList();
+
+	// how many
+	num = (int)Logic::_scriptVariables[MENU_LENGTH];
+
+	if (_holding) {
+
+		// dragged off of inv? Quit inv mode
+		if (xPos < _invX || xPos > _invX + _invW || yPos < _invY || yPos > _invY + _invH) {
+
+			// dragged off of the inv
+			M_MODE = INVENTORY_USE_ON;
+			// remove inv items from screen/logic processing
+			_skyLogic->killInventory();
+			// got to tidy the inv item
+			itemData = _skyCompact->fetchCpt(_touchId);
+			itemData->frame--;
+			itemData->getToFlag = 0;
+
+			// start fresh
+			_touchId = 0;
+
+			// highlight off
+			_skyScreen->setDragIconHighlight(false);
+			return;
+		}
+		// else, wait for release, and see if release on another item
+		if (_mouseB) {
+			// keep scanning objects to run geton/off
+			for (j = 0; j < num; j++) {
+
+
+				// fetch the compact
+				itemData = _skyCompact->fetchCpt(objList[j]);
+
+				if (itemData->xcood + ((int16)itemData->mouseRelX) > xPos)
+					continue;
+				if (itemData->xcood + ((int16)itemData->mouseRelX) + XWIDTH < xPos)
+					continue;
+				if (itemData->ycood + ((int16)itemData->mouseRelY) > yPos)
+					continue;
+				if (itemData->ycood + ((int16)itemData->mouseRelY) + YDEPTH < yPos)
+					continue;
+
+				touched = true;
+
+				// on previous?
+				if (_hoverId == objList[j])
+					continue; // still on previous, so skip
+
+
+				// run previous items get-off, if there was one (gone straight from one object onto another!)
+				if (Logic::_scriptVariables[GET_OFF])
+					_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], _skyCompact->fetchCpt(_hoverId));
+
+
+				// write new mouse off script number
+				Logic::_scriptVariables[GET_OFF] = itemData->mouseOff;
+
+				_hoverId = objList[j];
+
+				// new item
+				_skyLogic->startInventory(_hoverId); // highlight touched item
+
+				// run the mouse on script
+				if (itemData->mouseOn) {
+					uint16 tempY = itemData->ycood;
+					pushInvY(tempY);
+					itemData->ycood = 136;
+					Logic::_scriptVariables[BUTTON] = 3;
+					Logic::_scriptVariables[ICON_LIT] = _hoverId;
+					Logic::_scriptVariables[SPECIAL_ITEM] = _hoverId;
+					_skyLogic->mouseScript(itemData->mouseOn, itemData);
+					// and bring back render position
+					itemData->ycood = tempY;
+				}
+
+			}
+
+			// if we didn't register any hit then run the get off - we're sitting on blank inventory space
+			if (!touched) {
+				// touching nothing
+				_hoverId = 0;
+				if (Logic::_scriptVariables[GET_OFF]) {
+					_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], _skyCompact->fetchCpt(_hoverId));
+					Logic::_scriptVariables[GET_OFF] = 0;
+				}
+
+			}
+
+			// we're done
+			return;
+		}
+
+		if (_hoverId == 24584 || _hoverId == 24630 || _hoverId == 24732 || _hoverId == 24643) {
+			// fetch the compact
+			itemData = _skyCompact->fetchCpt(_touchId);
+
+			// set button
+			Logic::_scriptVariables[BUTTON] = 3;
+			// record what we're touching
+			Logic::_scriptVariables[SPECIAL_ITEM] = _hoverId;
+
+			// fight internal logic's impulse to slide back up
+			uint16 tempY = itemData->ycood;
+			itemData->ycood = 136;
+			uint32 menuRef = _lincMenuRef;
+			_skyLogic->mouseScript(itemData->mouseClick, itemData);
+			// and bring back render position
+			itemData->ycood = tempY; // itemData->invY;
+
+
+			if (menuRef != _lincMenuRef) {
+				itemData = _skyCompact->fetchCpt(_touchId);
+				itemData->frame--;
+				itemData->getToFlag = 0;
+			} else {
+			}
+		} else {
+			// wont combine
+			itemData = _skyCompact->fetchCpt(_touchId);
+			itemData->frame--;
+			itemData->getToFlag = 0;
+
+		}
+		// bring back new inv - have to call again to kick in this frame fix
+		_skyLogic->startInventory();
+		_holding = false;
+		_skyScreen->clearDragIcon(); // clear the dragging icon
+
+		// cancel cursor
+		Logic::_scriptVariables[OBJECT_HELD] = 0;
+
+		return;
+	}
+
+	//---------------------------------------------------------------------------------------------------------------------------------------------
+
+	// touching screen, but not an object yet
+	if (_mouseB) {
+		for (j = 0; j < num; j++) {
+			// fetch the compact
+			itemData = _skyCompact->fetchCpt(objList[j]);
+
+			if (itemData->xcood + ((int16)itemData->mouseRelX) > xPos) continue;
+			if (itemData->xcood + ((uint16)itemData->mouseRelX) + XWIDTH < xPos) continue;
+			if (itemData->ycood + ((uint16)itemData->mouseRelX) > yPos) continue;
+			if (itemData->ycood + ((uint16)itemData->mouseRelX) + YDEPTH < yPos) continue;
+
+			// record what we're touching
+			Logic::_scriptVariables[SPECIAL_ITEM] = objList[j];
+
+			if (_touchId != objList[j] && !_holding) {
+				debug("New touch\n");
+				// run previous items get-off, if there was one (gone straight from one object onto another)
+				if (Logic::_scriptVariables[GET_OFF])
+					_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], itemData);
+
+				// write mouse off script number
+				Logic::_scriptVariables[GET_OFF] = itemData->mouseOff;
+
+				_touchId = objList[j];
+				_hoverId = objList[j];
+
+				Logic::_scriptVariables[ICON_LIT] = objList[j];
+
+				_skyLogic->mouseScript(itemData->mouseOn, itemData);
+				// reset hold counter
+
+				// init drag
+				_skyScreen->setDragIcon(itemData->frame, true);
+
+				// set button
+				Logic::_scriptVariables[BUTTON] = 2;
+				// record what we're touching
+				Logic::_scriptVariables[SPECIAL_ITEM] = _touchId;
+				Logic::_scriptVariables[ICON_LIT] = 0;
+				Logic::_scriptVariables[OBJECT_HELD] = 0;
+
+				// fetch the compact
+				itemData = _skyCompact->fetchCpt(_touchId);
+
+				// fight internal logic's impulse to slide back up
+
+				uint16 tempY = itemData->ycood;
+				itemData->ycood = 136;
+
+				// special stuff for quit-linc
+				if (_touchId == 24582) {
+					debug("QUIT LINC\n");
+					itemData->frame--;
+
+					// remove inventory items from screen/logic processing
+					_skyLogic->killInventory();
+					_skyScreen->clearDragIcon();
+					_skyLogic->mouseScript(itemData->mouseClick, itemData);
+					return;
+				}
+				_skyLogic->mouseScript(itemData->mouseClick, itemData);
+				// and bring back render position
+				itemData->ycood = tempY;
+
+				if (Logic::_scriptVariables[OBJECT_HELD]) {
+					// just render offset - cursor is still beneath the finger
+					_mouseYOff = HOTSPOT_useon_yoff;
+					_holding = true;
+					_touchIdLegacy = _touchId;
+					_skyLogic->startInventory(_touchId); // highlight touched item
+				}
+			}
+			// touching something - we're done
+			return;
+		}
+	}
+
+}
+
 } // End of namespace Sky
diff --git a/engines/sky/mouse.h b/engines/sky/mouse.h
index c4fa4738190..c79722e6b12 100644
--- a/engines/sky/mouse.h
+++ b/engines/sky/mouse.h
@@ -29,60 +29,62 @@ class OSystem;
 
 namespace Sky {
 
-//max click cycles before interact is not valid upon release
-#define	CLICK_THRESHOLD	10
-//cycles before inv use-on trigger
+// max click cycles before interact is not valid upon release
+#define CLICK_THRESHOLD 10
+// cycles before inv use-on trigger
 #define USEON_THRESHOLD 5
-//time till hotspot fades out after stopped touching
-#define	HOTSPOT_FADEOUT	36
-//hotspot icon size
-#define HOTSPOT_dim	36
-//exit is just one icon, so half width as straddles centre point
+// time till hotspot fades out after stopped touching
+#define HOTSPOT_FADEOUT 36
+// hotspot icon size
+#define HOTSPOT_dim 36
+// exit is just one icon, so half width as straddles centre point
 #define HOTSPOT_ExitDim (HOTSPOT_dim >> 1)
-//closed hotspot radius
-#define	HOTSPOT_RADx 8
-#define	HOTSPOT_RAD 16
+// closed hotspot radius
+#define HOTSPOT_RADx 8
+#define HOTSPOT_RAD 16
 
-//how far the popup icons sit above the midy
-#define	HOTSPOT_yoff 48
-//differentiate exits, just incase
+// how far the popup icons sit above the midy
+#define HOTSPOT_yoff 48
+// differentiate exits, just incase
 #define HOTSPOT_exit_yoff 48
 
-//use on cursor offset
+// use on cursor offset
 #define HOTSPOT_useon_yoff (-55)
 
-//inv button (bottom left)
+// inv button (bottom left)
 #define HOTSPOT_invx (TOP_LEFT_X + 40)
 #define HOTSPOT_invy (TOP_LEFT_Y + FULL_SCREEN_HEIGHT-35)
 
-//control panel button (top left)
+// control panel button (top left)
 #define HOTSPOT_optionsx (TOP_LEFT_X + 30)
 #define HOTSPOT_optionsy (TOP_LEFT_Y + 30)
 
-//help button (top right)
+// help button (top right)
 #define HOTSPOT_helpx (TOP_LEFT_X + FULL_SCREEN_WIDTH-30)
 #define HOTSPOT_helpy (TOP_LEFT_Y + 30)
 
-//glow proximity
+// glow proximity
 #define GLOW_DIST 150
-//drag to use on distance
-#define	USE_ON_DIST	40
+// drag to use on distance
+#define USE_ON_DIST 40
 
-//fix super deep exits
-#define	TWEEKY_EXIT_ADJUST (FULL_SCREEN_HEIGHT + TOP_LEFT_Y - 40);
+// fix super deep exits
+#define TWEEKY_EXIT_ADJUST (FULL_SCREEN_HEIGHT + TOP_LEFT_Y - 40);
 
 
-//inv item sizes
-#define	XWIDTH 32
+// inv item sizes
+#define XWIDTH 32
 #define YDEPTH 32
 
-//action flash
-#define	ACTION_FLASH_TIME 7
+// action flash
+#define ACTION_FLASH_TIME 7
 
 class Disk;
 class Logic;
 class SkyCompact;
 class Text;
+class Screen;
+class Control;
 struct Compact;
 enum UIIcon : uint8;
 
@@ -90,7 +92,7 @@ class Mouse {
 
 public:
 
-	Mouse(OSystem *system, Disk *skyDisk, SkyCompact *skyCompact);
+	Mouse(OSystem *system, Disk *skyDisk, SkyCompact *skyCompact, Screen *skyScreen);
 	~Mouse();
 
 	void mouseEngine();
@@ -105,6 +107,7 @@ public:
 	void drawNewMouse();
 	void spriteMouse(uint16 frameNum, uint8 mouseX, uint8 mouseY);
 	void useLogicInstance(Logic *skyLogic) { _skyLogic = skyLogic; }
+	void useControlInstance(Control *control) { _skyControl = control; }
 	void buttonPressed(uint8 button);
 	void mouseMoved(uint16 mouseX, uint16 mouseY);
 	void waitMouseNotPressed(int minDelay = 0);
@@ -114,11 +117,29 @@ public:
 	bool wasClicked();
 	void logicClick() { _logicClick = true; }
 	void resetCursor();
-	bool IsUILive();
+	bool isUILive();
 	void resetUI();
+	OSystem *giveSystem(){
+		return	_system;
+	}
 	int	doProximityHighlights(uint16 xPos, uint16 yPos);
 	uint16 giveXcood(Compact *itemData, uint32 id);
 	uint16 giveYcood(Compact *itemData, uint32 id);
+	void setLincInv(bool inv) {
+		_isLincInv = inv;
+	}
+	bool isLincInv() {
+		return _isLincInv;
+	}
+	void incLincMenuRef() {
+		_lincMenuRef++	;
+	}
+	void pushInvY(uint16 y) {
+		_invYCoord = y;
+	}
+	uint16 popInvY() {
+		return _invYCoord;
+	}
 	UIIcon getInteractIcon(uint32 id);
 	bool hasSingleInteractIcon(uint32 id);
 	void updateHotspotCoordinate(uint16 xPos);
@@ -128,6 +149,8 @@ protected:
 
 	void pointerEngine(uint16 xPos, uint16 yPos);
 	void buttonEngine1();
+	void invMouse(uint16 xPos, uint16 yPos);
+	void lincInvMouse(uint16 xPos, uint16 yPos);
 
 	bool _logicClick;
 
@@ -137,30 +160,30 @@ protected:
 
 	int16	_mouseXOff;
 	int16	_mouseYOff;
-	uint16	_timeOn;//how long have we held on this item
-	uint16	_clickedNum;//remmebers what we clicked last
-	uint16	_fadeOut;//how long before current hotspot fades out when let go
-	bool	_prevMouseOn;//touching yes/no last cycle
+	uint16	_timeOn; // how long have we held on this item
+	uint16	_clickedNum; // remmebers what we clicked last
+	uint16	_fadeOut; // how long before current hotspot fades out when let go
+	bool	_prevMouseOn; // touching yes/no last cycle
 	uint16	_touchId;
 	uint16	_touchIdLegacy;
-	uint16	_hoverId;	//inv drag over inv
+	uint16	_hoverId; // inv drag over inv
 	bool	_holding;
-	bool	_isExit;	//cur hotspot an exit?
-	uint32	_exitType;	//what type of exit
+	bool	_isExit; // cur hotspot an exit?
+	uint32	_exitType; // what type of exit
 	bool	_isFloor;
-	bool	_isLincInv;	//current inventory is in LINC which works weirdly differently
-	uint32	_lincMenuRef;	//used to check if a linc inv menu restarted the inv
-	uint16	_invYCoord;	//store inv item y coords ready for patching back in
+	bool	_isLincInv;	// current inventory is in LINC which works weirdly differently
+	uint32	_lincMenuRef; // used to check if a linc inv menu restarted the inv
+	uint16	_invYCoord;	// store inv item y coords ready for patching back in
 	int		_nearestProximityIconId;
-	bool	_floorLock;//stop moving off hotpots onto floors then releasing to get an interaction
+	bool	_floorLock; // stop moving off hotpots onto floors then releasing to get an interaction
 
-	uint16	_invX;//inventory bounds x
-	uint16	_invY;//inventory bounds y
-	uint16	_invW;//inventory bounds w
-	uint16	_invH;//inventory bounds h
+	uint16	_invX; // inventory bounds x
+	uint16	_invY; // inventory bounds y
+	uint16	_invW; // inventory bounds w
+	uint16	_invH; // inventory bounds h
 
-	bool	_actionFlash = false;	//clicked on action icon flasher
-	int		_actionFlashTime = 0;//counts down
+	bool	_actionFlash = false; // clicked on action icon flasher
+	int		_actionFlashTime = 0; // counts down
 	int		_actionFlashIcon = 0;
 	int		_actionFlashX = 0;
 	int		_actionFlashY = 0;
@@ -179,17 +202,19 @@ protected:
 	Disk *_skyDisk;
 	Logic *_skyLogic;
 	SkyCompact *_skyCompact;
+	Screen *_skyScreen;
+	Control *_skyControl;
 
 	enum : uint8 {
-		Gameplay,
-		PreInventory,
-		Inventory,
-		INV_temp_examine,
-		InventoryUseOn,
-		Text_chooser,
-		MustRelease,
-		Alert_to_game,//new game alert box
-	} m_mode;
+		GAMEPLAY,
+		PRE_INVENTORY,
+		INVENTORY,
+		INV_TEMP_EXAMINE,
+		INVENTORY_USE_ON,
+		TEXT_CHOOSER,
+		MUST_RELEASE,
+		ALERT_TO_GAME, // new game alert box
+	} M_MODE;
 };
 
 } // End of namespace Sky
diff --git a/engines/sky/screen.cpp b/engines/sky/screen.cpp
index 776ff630e38..a5e54b22df6 100644
--- a/engines/sky/screen.cpp
+++ b/engines/sky/screen.cpp
@@ -24,7 +24,6 @@
 #include "common/events.h"
 #include "common/system.h"
 #include "common/textconsole.h"
-#include "common/config-manager.h"
 #include "common/memstream.h"
 
 #include "graphics/paletteman.h"
@@ -69,31 +68,38 @@ void Screen::setIcon(int idx, int x, int y) {
 
 void Screen::drawIbassIcon() {
 	for (int i = 0; i < NUM_UI_ICONS; i++) {
-		if (_uiIcon[i].visible) {
-
-			// if (_uiIcon[i].anim == nullptr)
-			// 	continue;
+		if (_uiIcon[i]._visible) {
 
 			// get the current animation frame
-			Graphics::Surface *currentFrame = _uiIcon[i].anim->frames[_uiIcon[i].cur_frame];
+			Graphics::Surface *currentFrame = _uiIcon[i]._anim->_frames[_uiIcon[i]._curFrame];
 
-			_screen32.copyRectToSurfaceWithKey(*currentFrame, _uiIcon[i].x, _uiIcon[i].y, Common::Rect(currentFrame->w, currentFrame->h), _screen32.format.ARGBToColor(0x00, 0xFF, 0xFF, 0xFF));
+			_screen32.copyRectToSurfaceWithKey(*currentFrame, _uiIcon[i]._x, _uiIcon[i]._y, Common::Rect(currentFrame->w, currentFrame->h), _screen32.format.ARGBToColor(0x00, 0xFF, 0xFF, 0xFF));
 		}
 
 	}
 }
 
+void Screen::drawIbassInventory() {
+	for (int i = 0; i < NUM_INV_ICONS; i++) {
+		if (_invIcon[i]._visible) {
+
+			// get the current animation frame
+			Graphics::Surface *currentFrame = _invIcon[i]._anim->_frames[_invIcon[i]._curFrame];
+
+			_screen32.copyRectToSurfaceWithKey(*currentFrame, _invIcon[i]._x, _invIcon[i]._y, Common::Rect(currentFrame->w, currentFrame->h), _screen32.format.ARGBToColor(0x00, 0xFF, 0xFF, 0xFF));
+		}
+	}
+}
+
 void Screen::initIbassIcon(int idx, const char *filename) {
-	_uiIcon[idx].anim = _skyDisk->loadAnim(filename, _screen32.format);
+	_uiIcon[idx]._anim = _skyDisk->loadAnim(filename, _screen32.format);
 }
 
 void Screen::clearIbassIcon(int idx, bool fade = true) {
-	_uiIcon[idx].visible = false;
-	//_uiIcon[idx].x = _uiIcon[idx].y = 0;
+	_uiIcon[idx]._visible = false;
 
-	if (!fade) {
-		_uiIcon[idx].alpha = 0.0f;
-	}
+	if (!fade)
+		_uiIcon[idx]._alpha = 0.0f;
 }
 
 void Screen::setProximityIcon(int idx, int x, int y, float alpha, int frame) {
@@ -101,32 +107,31 @@ void Screen::setProximityIcon(int idx, int x, int y, float alpha, int frame) {
 		return;
 
 	_proximityIcon[idx].set(x, y, alpha);
-	_proximityIcon[idx].animating = true;
-	_proximityIcon[idx].cur_frame = frame;
+	_proximityIcon[idx]._animating = true;
+	_proximityIcon[idx]._curFrame = frame;
 }
 
 void Screen::setProximityNotAnimate(int idx) {
 	if (idx < 0 || idx >= NUM_PROXIMITY_ICONS)
 		return;
 
-	_proximityIcon[idx].animating = false;
-	_proximityIcon[idx].cur_frame = 2;
+	_proximityIcon[idx]._animating = false;
+	_proximityIcon[idx]._curFrame = 2;
 }
 
 void Screen::clearAllIbassIcons(bool fade = true) {
 	for (int i = 0; i < NUM_UI_ICONS; i++)
 		clearIbassIcon(i, fade);
-
 }
 
 void Screen::clearProximityIcon(int idx, bool fade) {
 	if (idx < 0 || idx >= NUM_PROXIMITY_ICONS)
 		return;
 
-	_proximityIcon[idx].visible = false;
+	_proximityIcon[idx]._visible = false;
 
 	if (!fade)
-		_proximityIcon[idx].alpha = 0.0f;
+		_proximityIcon[idx]._alpha = 0.0f;
 }
 
 void Screen::clearAllProximityIcons(bool fade) {
@@ -135,32 +140,28 @@ void Screen::clearAllProximityIcons(bool fade) {
 	}
 }
 
+void Screen::setDragIcon(int frame, bool highlighted) {
+	_dragIcon._anim = _invAnim[getInventoryAnimIdx(frame)];
+	_dragIcon.set(0, 0);
+	_dragIcon._curFrame = highlighted ? 1 : 0;
+}
+
+void Screen::clearDragIcon() {
+	_dragIcon._visible = false;
+}
+
+void Screen::setDragIconHighlight(bool highlighted) {
+	_dragIcon._curFrame = highlighted ? 1 : 0;
+}
+
 bool Screen::isUIOpen() {
 	for (int i = 0; i < NUM_UI_ICONS; i++) {
-		if (_uiIcon[i].visible)
+		if (_uiIcon[i]._visible)
 			return true;
 	}
 	return false;
 }
 
-bool _invVisible;
-int _invX1;
-int _invY1;
-int _invX2;
-int _invY2;
-
-void Screen::showInventory(int x1, int y1, int x2, int y2) {
-	_invX1 = x1;
-	_invY1 = y1;
-	_invX2 = x2;
-	_invY2 = y2;
-	_invVisible = true;
-}
-
-void Screen::hideInventory(void) {
-	_invVisible = false;
-}
-
 Screen::Screen(OSystem *pSystem, Disk *pDisk, SkyCompact *skyCompact) {
 	_system = pSystem;
 	_skyDisk = pDisk;
@@ -188,7 +189,7 @@ Screen::Screen(OSystem *pSystem, Disk *pDisk, SkyCompact *skyCompact) {
 	}
 
 	//set the palette
-	if ((ConfMan.get("gameid") != "ibass") && _system->getScreenFormat().bytesPerPixel == 1)
+	if (!SkyEngine::isIbass() && _system->getScreenFormat().bytesPerPixel == 1)
 		_system->getPaletteManager()->setPalette(tmpPal, 0, VGA_COLORS);
 	_currentPalette = 0;
 
@@ -197,22 +198,37 @@ Screen::Screen(OSystem *pSystem, Disk *pDisk, SkyCompact *skyCompact) {
 	_seqInfo.running = false;
 
 	for (int i = 0; i < NUM_UI_ICONS; i++) {
-		_uiIcon[i].visible = false;
-		_uiIcon[i].anim = nullptr;
-		_uiIcon[i].x = 0;
-		_uiIcon[i].y = 0;
-		_uiIcon[i].alpha = 0.0f;
+		_uiIcon[i]._visible = false;
+		_uiIcon[i]._anim = nullptr;
+		_uiIcon[i]._x = 0;
+		_uiIcon[i]._y = 0;
+		_uiIcon[i]._alpha = 0.0f;
 	}
 
 	for (int i = 0; i < NUM_PROXIMITY_ICONS; i++) {
-		_proximityIcon[i].visible = false;
-		_proximityIcon[i].anim = nullptr;
-		_proximityIcon[i].x = 0;
-		_proximityIcon[i].y = 0;
-		_proximityIcon[i].alpha = 0.0f;
+		_proximityIcon[i]._visible = false;
+		_proximityIcon[i]._anim = nullptr;
+		_proximityIcon[i]._x = 0;
+		_proximityIcon[i]._y = 0;
+		_proximityIcon[i]._alpha = 0.0f;
+	}
+
+	for (int i = 0; i < NUM_INV_ICONS; i++) {
+		_invIcon[i]._visible = false;
+		_invIcon[i]._anim = nullptr;
+		_invIcon[i]._x = 0;
+		_invIcon[i]._y = 0;
+		_invIcon[i]._alpha = 0.0f;
+	}
+
+	for (int i = 0; i < NUM_INV_ANIMS; i++) {
+		char invTexFile[64];
+		Common::sprintf_s(invTexFile, "%d.tex", invIconId[i]);
+
+		_invAnim[i] = _skyDisk->loadAnim(invTexFile, _screen32.format);
 	}
 
-	if (SkyEngine::_isIbass()) {
+	if (SkyEngine::isIbass()) {
 		initIbassIcon(UI_ICON_LOOK, "eye.tex");
 		initIbassIcon(UI_ICON_USE, "cogs.tex");
 		initIbassIcon(UI_ICON_HAND, "hand.tex");
@@ -261,7 +277,13 @@ void Screen::update32BitScreen() {
 void Screen::renderFinalFrame() {
 	update32BitScreen();
 
+	if (SkyEngine::isIbass()) {
+
+		setIcon(UI_ICON_INV, 0, GAME_SCREEN_HEIGHT - 35);
+	}
+
 	drawIbassIcon();
+	drawIbassInventory();
 
 	if (_screen32.getPixels()) {
 		_system->copyRectToScreen(_screen32.getPixels(), _screen32.pitch, 0, 0, _screen32.w, _screen32.h);
@@ -286,7 +308,7 @@ void Screen::setFocusRectangle(const Common::Rect& rect) {
 //set a new palette, pal is a pointer to dos vga rgb components 0..63
 void Screen::setPalette(uint8 *pal) {
 	convertPalette(pal, _palette);
-	if ((ConfMan.get("gameid") != "ibass") && _system->getScreenFormat().bytesPerPixel == 1)
+	if (SkyEngine::isIbass() && _system->getScreenFormat().bytesPerPixel == 1)
 		_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
 	_system->updateScreen();
 }
@@ -300,7 +322,7 @@ void Screen::setPaletteEndian(uint8 *pal) {
 #else
 	convertPalette(pal, _palette);
 #endif
-	if ((ConfMan.get("gameid") != "ibass") && _system->getScreenFormat().bytesPerPixel == 1)
+	if (SkyEngine::isIbass() && _system->getScreenFormat().bytesPerPixel == 1)
 		_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
 	_system->updateScreen();
 }
@@ -313,7 +335,7 @@ void Screen::halvePalette() {
 		halfPalette[cnt * 3 + 1] = _palette[cnt * 3 + 1] >> 1;
 		halfPalette[cnt * 3 + 2] = _palette[cnt * 3 + 2] >> 1;
 	}
-	if ((ConfMan.get("gameid") != "ibass") && _system->getScreenFormat().bytesPerPixel == 1)
+	if (SkyEngine::isIbass() && _system->getScreenFormat().bytesPerPixel == 1)
 		_system->getPaletteManager()->setPalette(halfPalette, 0, GAME_COLORS);
 }
 
@@ -328,7 +350,7 @@ void Screen::setPalette(uint16 fileNum) {
 
   void Screen::showScreen(uint16 fileNum, bool fullscreen) {
 
-	if (SkyEngine::_isIbass()) {
+	if (SkyEngine::isIbass()) {
 		uint8 *imgData = _skyDisk->loadFile(fileNum);
 
 		if (imgData) {
@@ -346,20 +368,21 @@ void Screen::setPalette(uint16 fileNum) {
 				return;
 			}
 		}
-	} else {
-		// This is only used for static images in the floppy and cd intro
-		free(_currentScreen);
-		_currentScreen = _skyDisk->loadFile(fileNum);
-		if (!fullscreen && _currentScreen) {
-			// make sure the last 8 lines are forced to black.
-			memset(_currentScreen + GAME_SCREEN_HEIGHT * GAME_SCREEN_WIDTH, 0, (FULL_SCREEN_HEIGHT - GAME_SCREEN_HEIGHT) * GAME_SCREEN_WIDTH);
-		}
+		return;
+	}
 
-		if (_currentScreen)
-			showScreen(_currentScreen, fullscreen);
-		else
-			warning("Screen::showScreen: can't load file nr. %d",fileNum);
+	// This is only used for static images in the floppy and cd intro
+	free(_currentScreen);
+	_currentScreen = _skyDisk->loadFile(fileNum);
+	if (!fullscreen && _currentScreen) {
+		// make sure the last 8 lines are forced to black.
+		memset(_currentScreen + GAME_SCREEN_HEIGHT * GAME_SCREEN_WIDTH, 0, (FULL_SCREEN_HEIGHT - GAME_SCREEN_HEIGHT) * GAME_SCREEN_WIDTH);
 	}
+
+	if (_currentScreen)
+		showScreen(_currentScreen, fullscreen);
+	else
+		warning("Screen::showScreen: can't load file nr. %d",fileNum);
 }
 
 void Screen::showScreen(uint8 *pScreen, bool fullscreen) {
@@ -424,11 +447,10 @@ void Screen::flip(bool doUpdate) {
 	}
 
 	// only perform the 32-bit conversion ONCE per frame
-	if (isDirty || isUIOpen()) {
+	if (isDirty || isUIOpen())
 		renderFinalFrame();
-	} else if (doUpdate) {
+	 else if (doUpdate)
 		_system->updateScreen();
-	}
 }
 
 void Screen::fnDrawScreen(uint32 palette, uint32 scroll) {
@@ -447,7 +469,7 @@ void Screen::fnFadeDown(uint32 scroll) {
 		for (uint8 cnt = 0; cnt < 32; cnt++) {
 			delayTime += 20;
 			palette_fadedown_helper(_palette, GAME_COLORS);
-			if ((ConfMan.get("gameid") != "ibass") && _system->getScreenFormat().bytesPerPixel == 1)
+			if (!SkyEngine::isIbass() && _system->getScreenFormat().bytesPerPixel == 1)
 				_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
 			_system->updateScreen();
 			int32 waitTime = (int32)delayTime - _system->getMillis();
@@ -487,7 +509,7 @@ void Screen::palette_fadedown_helper(uint8 *pal, uint num) {
 }
 
 void Screen::paletteFadeUp(uint16 fileNr) {
-	if (!SkyEngine::_isIbass()) {
+	if (!SkyEngine::isIbass()) {
 		uint8 *pal = _skyDisk->loadFile(fileNr);
 		if (pal) {
 			paletteFadeUp(pal);
@@ -511,7 +533,7 @@ void Screen::paletteFadeUp(uint8 *pal) {
 			_palette[colCnt * 3 + 1] = (tmpPal[colCnt * 3 + 1] * cnt) >> 5;
 			_palette[colCnt * 3 + 2] = (tmpPal[colCnt * 3 + 2] * cnt) >> 5;
 		}
-		if ((ConfMan.get("gameid") != "ibass") && _system->getScreenFormat().bytesPerPixel == 1)
+		if (!SkyEngine::isIbass() && _system->getScreenFormat().bytesPerPixel == 1)
 			_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
 		_system->updateScreen();
 
diff --git a/engines/sky/screen.h b/engines/sky/screen.h
index 11dbd48f1d3..cada7044b37 100644
--- a/engines/sky/screen.h
+++ b/engines/sky/screen.h
@@ -50,9 +50,9 @@ struct Icon;
 
 #define FORE 1
 #define BACK 0
-#define NUM_INV_ANIMS	44	//unique textures
-#define NUM_INV_ICONS	20	//(max) number of on-screen items
-#define NUM_PROXIMITY_ICONS 16	//(max) number of proximity icons
+#define NUM_INV_ANIMS	44	// unique textures
+#define NUM_INV_ICONS	20	// (max) number of on-screen items
+#define NUM_PROXIMITY_ICONS 16	// (max) number of proximity icons
 
 typedef struct {
 	uint16 yCood;
@@ -75,6 +75,8 @@ enum UIIcon : uint8{
 	NUM_UI_ICONS
 };
 
+extern const int invIconId[];
+
 class Screen {
 public:
 	Screen(OSystem *pSystem, Disk *pDisk, SkyCompact *skyCompact);
@@ -121,22 +123,44 @@ public:
 	Icon _uiIcon[NUM_UI_ICONS];
 	Icon _proximityIcon[NUM_PROXIMITY_ICONS];
 	Icon _invIcon[NUM_INV_ICONS];
+	Icon _dragIcon;
 
 	void setIcon(int idx, int x, int y);
 	void drawIbassIcon();
+	void drawIbassInventory();
 	void initIbassIcon(int idx, const char *filename);
 	void clearIbassIcon(int idx, bool fade);
 	void clearAllIbassIcons(bool fade);
 
 	bool isUIOpen();
+
+	void addInvIcon(int frame, int x, int y, bool highlighted = false);
 	void showInventory(int x1, int y1, int x2, int y2);
 	void hideInventory(void);
+	void clearAllInvIcons();
+	int getInventoryAnimIdx(int frame);
 
 	void setProximityIcon(int idx, int x, int y, float alpha, int frame);
 	void clearAllProximityIcons(bool fade = true);
 	void clearProximityIcon(int idx, bool fade = true);
 	void setProximityNotAnimate(int idx);
 
+	void setDragIcon(int frame, bool highlighted = false);
+	void clearDragIcon();
+	void setDragIconHighlight(bool highlighted);
+
+protected:
+
+	int _invX1;
+	int _invY1;
+	int _invX2;
+	int _invY2;
+	bool _invVisible;
+	int _invIconsInUse;
+
+	Animation *_invAnim[NUM_INV_ANIMS];
+
+
 private:
 	OSystem *_system;
 	Disk *_skyDisk;
diff --git a/engines/sky/sky.cpp b/engines/sky/sky.cpp
index 53420dbe874..80a14bbadcd 100644
--- a/engines/sky/sky.cpp
+++ b/engines/sky/sky.cpp
@@ -170,8 +170,8 @@ void SkyEngine::handleKey() {
 			break;
 
 		case kSkyActionOpenControlPanel:
-			if (SkyEngine::_isIbass()) {
-				openMainMenuDialog();
+			if (SkyEngine::isIbass()) {
+				_skyControl->doControlPanel();
 				break;
 			}
 			_skyControl->doControlPanel();
@@ -216,12 +216,12 @@ Common::Error SkyEngine::go() {
 		// Clear pastIntro here (set to false) explicilty
 		// It should be false already, but better to ensure it
 		_systemVars->pastIntro = false;
-		if (_systemVars->gameVersion > 272 && ConfMan.get("gameid") != "ibass") { // don't do intro for floppydemos
+		if (_systemVars->gameVersion > 272 && !SkyEngine::isIbass()) { // don't do intro for floppydemos
 			Intro *skyIntro = new Intro(_skyDisk, _skyScreen, _skyMusic, _skySound, _skyText, _mixer, _system);
 			bool floppyIntro = ConfMan.getBool("alt_intro");
 			introSkipped = !skyIntro->doIntro(floppyIntro);
 			delete skyIntro;
-		} else if (SkyEngine::_isIbass())
+		} else if (SkyEngine::isIbass())
 			introSkipped = true;
 
 		if (!shouldQuit()) {
@@ -391,8 +391,8 @@ Common::Error SkyEngine::init() {
 
 	_skyCompact = new SkyCompact();
 	_skyText = new Text(this, _skyDisk, _skyCompact);
-	_skyMouse = new Mouse(_system, _skyDisk, _skyCompact);
 	_skyScreen = new Screen(_system, _skyDisk, _skyCompact);
+	_skyMouse = new Mouse(_system, _skyDisk, _skyCompact, _skyScreen);
 
 	initVirgin();
 	initItemList();
@@ -405,6 +405,7 @@ Common::Error SkyEngine::init() {
 	assert(shortcutsKeymap);
 
 	_skyControl = new Control(this, _saveFileMan, _skyScreen, _skyDisk, _skyMouse, _skyText, _skyMusic, _skyLogic, _skySound, _skyCompact, _system, shortcutsKeymap);
+	_skyMouse->useControlInstance(_skyControl);
 	_skyLogic->useControlInstance(_skyControl);
 
 	switch (Common::parseLanguage(ConfMan.get("language"))) {
@@ -565,7 +566,6 @@ bool SkyEngine::isDemo() {
 	case 348:
 	case 368:
 	case 372:
-	case 400:
 		return false;
 	default:
 		error("Unknown game version %d", _systemVars->gameVersion);
@@ -585,14 +585,13 @@ bool SkyEngine::isCDVersion() {
 	case 365:
 	case 368:
 	case 372:
-	case 400:
 		return true;
 	default:
 		error("Unknown game version %d", _systemVars->gameVersion);
 	}
 }
 
-bool SkyEngine::_isIbass() {
+bool SkyEngine::isIbass() {
 	if (ConfMan.get("gameid") == "ibass")
 		return true;
 	return false;
diff --git a/engines/sky/sky.h b/engines/sky/sky.h
index 8f6fcfe7047..bb878abffd8 100644
--- a/engines/sky/sky.h
+++ b/engines/sky/sky.h
@@ -99,7 +99,7 @@ public:
 
 	static bool isDemo();
 	static bool isCDVersion();
-	static bool _isIbass();
+	static bool isIbass();
 
 	Common::Error loadGameState(int slot) override;
 	Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
@@ -109,14 +109,6 @@ public:
 		return Common::String::format("SKY-VM.%03d", slot);
 	}
 
-	Screen *getScreen() {
-		return _skyScreen;
-	}
-
-	Control *getControl() {
-		return _skyControl;
-	}
-
 	static void *fetchItem(uint32 num);
 	static void *_itemList[300];
 	static SystemVars *_systemVars;
diff --git a/engines/sky/sound.cpp b/engines/sky/sound.cpp
index b799f520ce4..4edec22f12a 100644
--- a/engines/sky/sound.cpp
+++ b/engines/sky/sound.cpp
@@ -23,7 +23,6 @@
 #include "common/debug.h"
 #include "common/endian.h"
 #include "common/textconsole.h"
-#include "common/config-manager.h"
 
 #include "sky/disk.h"
 #include "sky/logic.h"
@@ -1063,7 +1062,7 @@ void Sound::loadSection(uint8 pSection) {
 	} else
 		asmOfs = 0x7E;
 
-	if (!SkyEngine::_isIbass()) {
+	if (!SkyEngine::isIbass()) {
 		if ((_soundData[asmOfs] != 0x3C) || (_soundData[asmOfs + 0x27] != 0x8D) ||
 			(_soundData[asmOfs + 0x28] != 0x1E) || (_soundData[asmOfs + 0x2F] != 0x8D) ||
 			(_soundData[asmOfs + 0x30] != 0x36))
diff --git a/engines/sky/struc.h b/engines/sky/struc.h
index 8367f51a018..c3c40f1ce4d 100644
--- a/engines/sky/struc.h
+++ b/engines/sky/struc.h
@@ -48,37 +48,37 @@ struct DataFileHeader {
 	uint16 s_compressed_size;
 } PACKED_STRUCT;
 
-struct animation;
+struct Animation;
 
 struct Icon {
-	int x;
-	int y;
-	bool visible;
-	bool animating;
-	animation *anim;
-	int cur_frame;
-	int tick;
-	float alpha;
+	int _x;
+	int _y;
+	bool _visible;
+	bool _animating;
+	Animation *_anim;
+	int _curFrame;
+	int _tick;
+	float _alpha;
 
 	Icon() {
 		reset();
 	}
 
 	void reset(void) {
-		visible = false;
-		animating = true;
-		anim = 0;
-		cur_frame = 0;
-		tick = 0;
-		x = y = 0;
-		alpha = 0.0f;
+		_visible = false;
+		_animating = true;
+		_anim = 0;
+		_curFrame = 0;
+		_tick = 0;
+		_x = _y = 0;
+		_alpha = 0.0f;
 	}
 
 	void set(int xPos, int yPos, float alphaVal = 1.0f) {
-		x = xPos;
-		y = yPos;
-		visible = true;
-		alpha = alphaVal;
+		_x = xPos;
+		_y = yPos;
+		_visible = true;
+		_alpha = alphaVal;
 	}
 };
 
diff --git a/engines/sky/text.cpp b/engines/sky/text.cpp
index d013ebf466b..048d5edfac5 100644
--- a/engines/sky/text.cpp
+++ b/engines/sky/text.cpp
@@ -23,7 +23,6 @@
 #include "common/debug.h"
 #include "common/endian.h"
 #include "common/textconsole.h"
-#include "common/config-manager.h"
 
 #include "sky/disk.h"
 #include "sky/logic.h"
@@ -515,7 +514,6 @@ void Text::initHuffTree() {
 		_huffTree = _huffTree_00368;
 		break;
 	case 372:
-	case 400:
 		_huffTree = _huffTree_00372;
 		break;
 	default:


Commit: 4ad2771b90641a2265e7f98a163e78e063cc340f
    https://github.com/scummvm/scummvm/commit/4ad2771b90641a2265e7f98a163e78e063cc340f
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Implement inventory closing logic

Changed paths:
    engines/sky/mouse.cpp


diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index 911795655a2..40ea3dd450f 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -306,6 +306,8 @@ void Mouse::mouseEngine() {
 			case INVENTORY:
 				if (isLincInv())
 					lincInvMouse(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
+				else
+					invMouse(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
 
 			case INVENTORY_USE_ON:
 			case TEXT_CHOOSER:
@@ -2363,4 +2365,25 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 
 }
 
+void Mouse::invMouse(uint16 xPos, uint16 yPos) {
+
+	Compact *itemData;
+
+	// if clicked somewhere outside the inventory, close the inventory
+	if (!_touchId && _mouseB) {
+		if (xPos < _invX || xPos > _invX + _invW || yPos < _invY || yPos > _invY + _invH) {
+
+			M_MODE = MUST_RELEASE; // MUST_RELEASE because if we go straight to GAMEPLAY, robert will move to the place of clicking
+			_skyLogic->killInventory(); // stop rendering the inventory items
+			return;
+		}
+	}
+
+	// reset
+	if (Logic::_scriptVariables[GET_OFF]) {
+		_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], itemData);
+		Logic::_scriptVariables[GET_OFF] = 0;
+	}
+}
+
 } // End of namespace Sky


Commit: a27d38d52ad9f11fbb4b95c59b9c7ed3c45018bc
    https://github.com/scummvm/scummvm/commit/a27d38d52ad9f11fbb4b95c59b9c7ed3c45018bc
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Make clearAllInvIcons to actually clear the inventory icons

Changed paths:
    engines/sky/inventory.cpp


diff --git a/engines/sky/inventory.cpp b/engines/sky/inventory.cpp
index 7e57ded7a02..688d5508e62 100644
--- a/engines/sky/inventory.cpp
+++ b/engines/sky/inventory.cpp
@@ -101,6 +101,10 @@ void Screen::hideInventory() {
 }
 
 void Screen::clearAllInvIcons() {
+
+	for (int i = 0; i < NUM_INV_ICONS; i++)
+		_invIcon[i]._visible = false;
+
 	_invIconsInUse = 0;
 }
 


Commit: 7f28801edf13ecc99d91f4aea76f141b0acefbd3
    https://github.com/scummvm/scummvm/commit/7f28801edf13ecc99d91f4aea76f141b0acefbd3
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Fix formatting and change names

Changed paths:
    engines/sky/inventory.cpp
    engines/sky/mouse.cpp
    engines/sky/mouse.h


diff --git a/engines/sky/inventory.cpp b/engines/sky/inventory.cpp
index 688d5508e62..40db2616775 100644
--- a/engines/sky/inventory.cpp
+++ b/engines/sky/inventory.cpp
@@ -124,15 +124,11 @@ void Logic::startInventory(uint32	highlightedId) {
 }
 
 void Logic::killInventory() {
-
 	// shut down displayed inv objects
-
 	int j;
 	Compact *itemData;
 
-
 	if (_liveInv) {
-
 		for (j = 0; j < _scriptVariables[MENU_LENGTH]; j++) {
 			// fetch the compact
 			itemData = _skyCompact->fetchCpt(_objectList[j]);
@@ -140,14 +136,11 @@ void Logic::killInventory() {
 			itemData->status = 0;
 		}
 	}
-
-
 	_liveInv = false;
 
 	// kill inv bg
 	_skyScreen->hideInventory();
 	_skyScreen->clearAllInvIcons();
-
 }
 
 }
diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index 40ea3dd450f..e5cd4f665eb 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -118,7 +118,7 @@ void Mouse::resetUI() {
 	_holding = false;
 	_timeOn = 0;
 	_fadeOut = 0;
-	M_MODE = GAMEPLAY; // master ui mode
+	_mMode = GAMEPLAY; // master ui mode
 	_isFloor = false;
 	_isExit = false;
 	_actionFlash = false;
@@ -145,8 +145,8 @@ bool Mouse::fnAddHuman() {
 	//reintroduce the mouse so that the human can control the player
 	//could still be switched out at high-level
 
-	if (M_MODE == GAMEPLAY)
-		M_MODE = MUST_RELEASE;
+	if (_mMode == GAMEPLAY)
+		_mMode = MUST_RELEASE;
 
 	if (!Logic::_scriptVariables[MOUSE_STOP]) {
 		Logic::_scriptVariables[MOUSE_STATUS] |= 6;	//cursor & mouse
@@ -275,13 +275,13 @@ void Mouse::mouseEngine() {
 				_skyScreen->setIcon(_actionFlashIcon, _actionFlashX, _actionFlashY);
 		}
 
-		switch (M_MODE) {
+		switch (_mMode) {
 			case ALERT_TO_GAME:
 				if (!_mouseB)
 					return;
 
 				_skyScreen->hideInventory();
-				M_MODE = MUST_RELEASE;
+				_mMode = MUST_RELEASE;
 				break;
 
 			case MUST_RELEASE:
@@ -289,7 +289,7 @@ void Mouse::mouseEngine() {
 					return;
 
 				resetUI();
-				M_MODE = GAMEPLAY;
+				_mMode = GAMEPLAY;
 				break;
 
 			case GAMEPLAY:
@@ -300,7 +300,7 @@ void Mouse::mouseEngine() {
 				if (_mouseB)
 					return;
 
-				M_MODE = INVENTORY;
+				_mMode = INVENTORY;
 				break;
 
 			case INVENTORY:
@@ -339,8 +339,8 @@ int Mouse::doProximityHighlights(uint16 xPos, uint16 yPos) {
 	int nearestId = 0;
 	_nearestProximityIconId = 0;
 
-	static int  proxFrame = 0;
-	static int  proxFrameSpeed = 0;
+	int proxFrame = 0;
+	int proxFrameSpeed = 0;
 
 	proxFrameSpeed++;
 	if (proxFrameSpeed & 1)
@@ -362,8 +362,8 @@ int Mouse::doProximityHighlights(uint16 xPos, uint16 yPos) {
 			if ((itemData->screen == Logic::_scriptVariables[SCREEN]) && (itemData->status & 16)) {
 				// hotspot, if a non-floor object
 				if (itemData->mouseOn && yPos > (20 + TOP_LEFT_Y)) {
-					midx = giveXcood(itemData, itemNum);
-					midy = giveYcood(itemData, itemNum);
+					midx = giveXCood(itemData, itemNum);
+					midy = giveYCood(itemData, itemNum);
 
 					// skip very high hotspots - eg the old inventory catch object
 					if (midy < (TOP_LEFT_Y + 5))
@@ -560,7 +560,7 @@ bool Mouse::hasSingleInteractIcon(uint32 id) {
 	return  false;
 }
 
-uint16 Mouse::giveXcood(Compact *itemData, uint32 id) {
+uint16 Mouse::giveXCood(Compact *itemData, uint32 id) {
 	uint16 mid, midy;
 
 	mid = itemData->xcood + ((int16)itemData->mouseRelX) + (itemData->mouseSizeX >> 1);
@@ -579,924 +579,881 @@ uint16 Mouse::giveXcood(Compact *itemData, uint32 id) {
 	}
 
 	switch (id) {
-	case 4112: {
+	case 4112:
 		mid = 258; // cupboard door
 		break;
-	}
-	case 4113: {
+
+	case 4113:
 		mid = 254; // sandwich
 		break;
-	}
-	case 4114: {
+
+	case 4114:
 		mid = 254; // spanner
 		break;
-	}
 
-	case 12358:  {
+
+	case 12358:
 		mid = 428; // bellevue - missing exit
 		break;
-	}
-	case 12681:  {
+
+	case 12681:
 		mid = 428; // bellevue
 		break;
-	}
-	case 12349:  {
+
+	case 12349:
 		mid = 142; // bellevue
 		break;
-	}
-	case 12347:  {
+
+	case 12347:
 		mid = 428; // bellevue
 		break;
-	}
-	case 90: {
+
+	case 90:
 		mid = 404; // first room, door
 		break;
-	}
-	case 97: {
+
+	case 97:
 		mid = 190; // ledge room, door
 		break;
-	}
-	case 4116: {
+
+	case 4116:
 		mid = 269; // elevator
 		break;
-	}
-	case 4119: {
+
+	case 4119:
 		mid = 269; // hole
 		break;
-	}
-	case 4110: {
+
+	case 4110:
 		mid = 356; // lathe
 		break;
-	}
-	case 8248: {
+
+	case 8248:
 		mid = 357; // walkway to security lobby
 		break;
-	}
-	case 8238: {
+
+	case 8238:
 		mid = 181; // walkway to power
 		break;
-	}
-	case 8317: {
+
+	case 8317:
 		mid = 426; // walkway to crash
 		break;
-	}
-	case 8341: {
+
+	case 8341:
 		mid = 173; // factory to walkway
 		break;
-	}
-	case 8344: {
+
+	case 8344:
 		mid = 433; // factory to factory 2
 		break;
-	}
-	case 8500: {
+
+	case 8500:
 		mid = 224; // sensors
 		break;
-	}
-	case 8355: {
+
+	case 8355:
 		mid = 428; // factory 2 to factory 3
 		break;
-	}
-	case 8446: {
+
+	case 8446:
 		mid = 226; // putty
 		break;
-	}
-	case 8438: {
+
+	case 8438:
 		mid = 226; // gangway
 		break;
-	}
-	case 12680: {
+
+	case 12680:
 		mid = 201; // exit
 		break;
-	}
-	case 12679: {
+
+	case 12679:
 		mid = 307; // exit
 		break;
-	}
-	case 12678: {
+
+	case 12678:
 		mid = 179; // exit
 		break;
-	}
-	case 12677: {
+
+	case 12677:
 		mid = 319; // exit
 		break;
-	}
-	case 12324: {
+
+	case 12324:
 		mid = 191; // exit
 		break;
-	}
-	case 12336: {
+
+	case 12336:
 		mid = 182; // exit
 		break;
-	}
-	case 12442: {
+
+	case 12442:
 		mid = 376; // exit
 		break;
-	}
-	case 8483: {
+
+	case 8483:
 		mid = 225; // console
 		break;
-	}
-	case 12641: {
+
+	case 12641:
 		mid = 158; // exit
 		break;
-	}
 
 	// linc
-	case 12633: {
+	case 12633:
 		mid = 190; // maze
 		break;
-	}
-	case 24586: {
+
+	case 24586:
 		mid = 210; // maze
 		break;
-	}
-	case 24592: {
+
+	case 24592:
 		mid = 288; // maze mid-bot
 		break;
-	}
-	case 24593: {
+
+	case 24593:
 		mid = 400; // maze mid-bot
 		break;
-	}
-	case 24594: {
+
+	case 24594:
 		mid = 203; // maze left-mid
 		break;
-	}
-	case 24595: {
+
+	case 24595:
 		mid = 299; // maze left-mid
 		break;
-	}
-
 
 	// hyde
-	case 16496: {
+	case 16496:
 		mid = 263; // plant
 		break;
-	}
+
 	// cathedral
-	case 16462: {
+	case 16462:
 		mid = 168; // exit
 		break;
-	}
 
 	// lockers
-	case 16576: {
+	case 16576:
 		mid = 246; // body == 16569
 		break;
-	}
-	case 16577: {
+
+	case 16577:
 		mid = 271; // body == 16570
 		break;
-	}
-	case 16578: {
+
+	case 16578:
 		mid = 296; // body == 16571
 		break;
-	}
-	case 16579: {
+
+	case 16579:
 		mid = 321; // body == 16572
 		break;
-	}
-	case 16580: {
+
+	case 16580:
 		mid = 346; // body == 16573
 		break;
-	}
 
 	// underworld
-	case 20506: {
+	case 20506:
 		mid = 389; // metal door
 		break;
-	}
+
 	// pit room
-	case 20600: {
+	case 20600:
 		mid = 283; // cover
 		break;
-	}
-	case 20648: {
+
+	case 20648:
 		mid = 283; // pit
 		break;
-	}
-	case 20570: {
+
+	case 20570:
 		mid = 247; // exit to medical droid room
 		break;
-	}
 
-	case 20575: {
+	case 20575:
 		mid = 277; // slot
 		break;
-	}
-	case 20577: {
+
+	case 20577:
 		mid = 297; // recharge unit
 		break;
-	}
 
-	case 24786: {
+	case 24786:
 		mid = 288; // linc crystal
 		break;
-	}
-	case 24787: {
+
+	case 24787:
 		mid = 288; // virus
 		break;
-	}
 
-	case 20712: {
+	case 20712:
 		mid = 305; // console
 		break;
-	}
-	case 20713: {
+
+	case 20713:
 		mid = 356; // console
 		break;
-	}
 
-	case 20728: {
+	case 20728:
 		mid = 388; // exit from door room
 		break;
-	}
 
-	case 8272: {
+	case 8272:
 		mid = 278; // power room chair
 		break;
-	}
 
-	case 12390: {
+	case 12390:
 		mid = 187; // burke door
 		break;
-	}
-	case 12541: {
+
+	case 12541:
 		mid = 187; // burke exit
 		break;
 	}
 
-	}
-
 	return  mid;
 }
 
-uint16 Mouse::giveYcood(Compact *itemData, uint32 id) {
+uint16 Mouse::giveYCood(Compact *itemData, uint32 id) {
 	// push objects that are too far to left, or to the right, back onto the screen
 	uint16 mid;
 
 	mid = itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY >> 1);
 
 	switch (id) {
-	case 4112: { // cupboard door - not if open
+	case 4112: // cupboard door - not if open
 		if (Logic::_scriptVariables[112]) // cupb_flag
 			return  0;
 		mid = 221;
 		break;
-	}
-	case 4113: {
+
+	case 4113:
 		mid = 218; // sandwich
 		break;
-	}
-	case 4114: {
+
+	case 4114:
 		mid = 226; // spanner
 		break;
-	}
 
-	case 4108: {
+	case 4108:
 		mid = 0; // remove monitor screen
 		break;
-	}
-	case 4111: {
+
+	case 4111:
 		mid = 0; // remove lazer
 		break;
-	}
-	case 4115: {
+
+	case 4115:
 		mid = 0; // remove monitor screen
 		break;
-	}
-	case 4117: {
+
+	case 4117:
 		mid = 0; // remove monitor screen
 		break;
-	}
-	case 4154: {
+
+	case 4154:
 		mid = 0; // remove right sign
 		break;
-	}
+
 	case 12349:
 	// fall through
 	case 12347:
-	case 12358:  {
+	case 12358:
 		mid = TWEEKY_EXIT_ADJUST; // bellevue
 		break;
-	}
-	case 90: {
+
+	case 90:
 		mid = 208; // first room, door
 		break;
-	}
-	case 97: {
+
+	case 97:
 		mid = 216; // ledge room, door
 		break;
-	}
-	case 4116: {
+
+	case 4116:
 		mid = 259; // elevator
 		break;
-	}
-	case 4119: {
+
+	case 4119:
 		mid = 259; // hole
 		break;
-	}
-	case 4315: {
+
+	case 4315:
 		mid = 261; // exit left from junk room
 		break;
-	}
-	case 4103: {
+
+	case 4103:
 		mid = 242; // exit right from junk room
 		break;
-	}
-	case 4105: {
+
+	case 4105:
 		mid = 241; // exit left from hobbins room
 		break;
-	}
-	case 4110: {
+
+	case 4110:
 		mid = 230; // lathe
 		break;
-	}
-	case 8248: {
+
+	case 8248:
 		mid = 222;  // walkway to security lobby
 		break;
-	}
-	case 8238: {
+
+	case 8238:
 		mid = 222; // walkway to power
 		break;
-	}
-	case 8310: {
+
+	case 8310:
 		mid = 222; // walkway to first room
 		break;
-	}
-	case 8246: {
+
+	case 8246:
 		mid = 273; // power exit
 		break;
-	}
-	case 8317: {
+
+	case 8317:
 		mid = 273; // walkway to crash
 		break;
-	}
-	case 8331: {
+
+	case 8331:
 		mid = 230; // walkway to factory
 		break;
-	}
-	case 8341: {
+
+	case 8341:
 		mid = 239; // factory to walkway
 		break;
-	}
-	case 8344: {
+
+	case 8344:
 		mid = 282; // factory to factory 2
 		break;
-	}
-	case 8500: {
+
+	case 8500:
 		mid = 197; // sensors
 		break;
-	}
-	case 8355: {
+
+	case 8355:
 		mid = 255; // factory 2 to factory 3
 		break;
-	}
-	case 8366: {
+
+	case 8366:
 		mid = 227; // factory 2 to storeroom
 		break;
-	}
-	case 8375: {
+
+	case 8375:
 		mid = 238; // storeroom to factory 2
 		break;
-	}
-	case 8446: {
+
+	case 8446:
 		mid = 247; // putty
 		break;
-	}
-	case 8438: {
+
+	case 8438:
 		mid = 247; // gangway
 		break;
-	}
-	case 8364: {
+
+	case 8364:
 		mid = 252; // exit
 		break;
-	}
-	case 8459: {
+
+	case 8459:
 		mid = 252; // exit
 		break;
-	}
-	case 8256: {
+
+	case 8256:
 		mid = 297; // exit
 		break;
-	}
 
 	// bellevue
-	case 12304: {
+	case 12304:
 		mid = 252; // exit
 		break;
-	}
-	case 12338: {
+
+	case 12338:
 		mid = 286; // exit
 		break;
-	}
-	case 12681: {
+
+	case 12681:
 		mid = 250; // exit
 		break;
-	}
-	case 12370: {
+
+	case 12370:
 		mid = 289; // exit
 		break;
-	}
-	case 12361: {
+
+	case 12361:
 		mid = 267; // exit
 		break;
-	}
-	case 12679: {
+
+	case 12679:
 		mid = 179; // exit
 		break;
-	}
-	case 12678: {
+
+	case 12678:
 		mid = 179; // exit
 		break;
-	}
-	case 12677: {
+
+	case 12677:
 		mid = 179; // exit
 		break;
-	}
-	case 12313: {
+
+	case 12313:
 		mid = 284; // exit
 		break;
-	}
-	case 12676: {
+
+	case 12676:
 		mid = 241; // exit
 		break;
-	}
-	case 12327: {
+
+	case 12327:
 		mid = 244; // exit
 		break;
-	}
-	case 12315: {
+
+	case 12315:
 		mid = 286; // exit
 		break;
-	}
-	case 12324: {
+
+	case 12324:
 		mid = 308; // exit
 		break;
-	}
-	case 12336: {
+
+	case 12336:
 		mid = 306; // exit
 		break;
-	}
-	case 12442: {
+
+	case 12442:
 		mid = 246; // exit
 		break;
-	}
-	case 12447: {
+
+	case 12447:
 		mid = 242; // exit
 		break;
-	}
-	case 12680: {
+
+	case 12680:
 		mid = 179; // exit
 		break;
-	}
-	case 12459: {
+
+	case 12459:
 		mid = 281; // exit
 		break;
-	}
-	case 12471: {
+
+	case 12471:
 		mid = 302; // exit
 		break;
-	}
-	case 12399: {
+
+	case 12399:
 		mid = 257; // exit
 		break;
-	}
-	case 12390: {
+
+	case 12390:
 		mid = 264; // burke door
 		break;
-	}
-	case 12541: {
+
+	case 12541:
 		mid = 264; // burke exit
 		break;
-	}
 
-	case 12630: {
+	case 12630:
 		mid += 4; // slot
 		break;
-	}
-	case 12616: {
+
+	case 12616:
 		mid += 4; // slot
 		break;
-	}
-	case 12629: {
+
+	case 12629:
 		mid += 4; // slot
 		break;
-	}
-	case 12628: {
+
+	case 12628:
 		mid += 4; // slot
 		break;
-	}
-	case 12627: {
+
+	case 12627:
 		mid += 4; // slot
 		break;
-	}
-	case 12626: {
+
+	case 12626:
 		mid += 4; // slot
 		break;
-	}
 
-	case 12620: {
+	case 12620:
 		mid = 220; // locker
 		break;
-	}
-	case 12621: {
+
+	case 12621:
 		mid = 220; // locker
 		break;
-	}
-	case 12622: {
+
+	case 12622:
 		mid = 220; // locker
 		break;
-	}
-	case 12623: {
+
+	case 12623:
 		mid = 220; // locker
 		break;
-	}
-	case 12613: {
+
+	case 12613:
 		mid = 220; // locker
 		break;
-	}
-	case 12624: {
+
+	case 12624:
 		mid = 220; // locker
 		break;
-	}
 
-	case 12631: {
+	case 12631:
 		mid = 273; // exit
 		break;
-	}
-	case 12641: {
+
+	case 12641:
 		mid = 290; // exit
 		break;
-	}
-	case 12642: {
+
+	case 12642:
 		mid = 273; // exit
 		break;
-	}
 
-	case 12474: {
+	case 12474:
 		mid = 282; // lamb door
 		break;
-	}
-	case 12486: {
+
+	case 12486:
 		mid = 298; // lamb door
 		break;
-	}
 
 	// security room
-	case 8295: {
+	case 8295:
 		mid = 299; // exit
 		break;
-	}
 
 	// hyde
-	case 16415: {
+	case 16415:
 		mid = 261; // exit
 		break;
-	}
-	case 16403: {
+
+	case 16403:
 		mid = 261; // exit
 		break;
-	}
-	case 16393: {
+
+	case 16393:
 		mid = 246; // exit
 		break;
-	}
-	case 16487: {
+
+	case 16487:
 		mid = 256; // exit
 		break;
-	}
-	case 16492: {
+
+	case 16492:
 		mid = 287; // exit
 		break;
-	}
-	case 16394: {
+
+	case 16394:
 		mid = 313; // exit
 		break;
-	}
-	case 16412: {
+
+	case 16412:
 		mid = 276; // exit
 		break;
-	}
-	case 16428: {
+
+	case 16428:
 		mid = 233; // exit
 		break;
-	}
-	case 16424: {
+
+	case 16424:
 		mid = 236; // exit
 		break;
-	}
-
 
 	// cathedral
-	case 16462: {
+	case 16462:
 		mid = 296; // exit
 		break;
-	}
-	case 16464: {
+
+	case 16464:
 		mid = 250; // exit
 		break;
-	}
-	case 16465: {
+
+	case 16465:
 		mid = 226; // exit
 		break;
-	}
-	case 16474: {
+
+	case 16474:
 		mid = 263; // exit
 		break;
-	}
 
-	case 16576: {
+	case 16576:
 		mid = 229; // body == 16569
 		break;
-	}
-	case 16577: {
+
+	case 16577:
 		mid = 229; // body == 16570
 		break;
-	}
-	case 16578: {
+
+	case 16578:
 		mid = 229; // body == 16571
 		break;
-	}
-	case 16579: {
+
+	case 16579:
 		mid = 229; // body == 16572
 		break;
-	}
-	case 16580: {
+
+	case 16580:
 		mid = 229; // body == 16573
 		break;
-	}
 
 	// reactor
-	case 8478: {
+	case 8478:
 		mid = 291; // exit
 		break;
-	}
-	case 8481: {
+
+	case 8481:
 		mid = 253; // exit
 		break;
-	}
-	case 8511: {
+
+	case 8511:
 		mid = 271; // exit
 		break;
-	}
 
 	// club
-	case 16538: {
+	case 16538:
 		mid = 279; // exit
 		break;
-	}
 
 	// abandoned subway
-	case 16439: {
+	case 16439:
 		mid = 267; // exit
 		break;
-	}
 
 	// entrance to underworld
-	case 16592: {
+	case 16592:
 		mid = 267; // exit
 		break;
-	}
 
 	// underworld
-	case 16649: {
+	case 16649:
 		mid = 291; // exit
 		break;
-	}
-	case 16660: {
+
+	case 16660:
 		mid = 285; // exit
 		break;
-	}
-	case 16662: {
+
+	case 16662:
 		mid = 254; // exit
 		break;
-	}
-	case 16661: {
+
+	case 16661:
 		mid = 291; // exit
 		break;
-	}
-	case 16671: {
+
+	case 16671:
 		mid = 291; // exit
 		break;
-	}
-	case 16681: {
+
+	case 16681:
 		mid = 282; // exit
 		break;
-	}
-	case 16682: {
+
+	case 16682:
 		mid = 282; // exit
 		break;
-	}
-	case 16719: {
+
+	case 16719:
 		mid = 287; // exit
 		break;
-	}
-	case 16720: {
+
+	case 16720:
 		mid = 287; // exit
 		break;
-	}
-	case 16729: {
+
+	case 16729:
 		mid = 291; // exit
 		break;
-	}
-	case 16730: {
+
+	case 16730:
 		mid = 301; // exit
 		break;
-	}
-	case 20506: {
+
+	case 20506:
 		mid = 276; // metal door
 		break;
-	}
+
 	// underworld main
-	case 20518: {
+	case 20518:
 		mid = 276; // metal door
 		break;
-	}
-	case 20532: {
+
+	case 20532:
 		mid = 264; // exit
 		break;
-	}
-	case 20558: {
+
+	case 20558:
 		mid = 296; // exit
 		break;
-	}
-	case 20598: {
+
+	case 20598:
 		mid = 237; // exit
 		break;
-	}
-	case 20601: {
+
+	case 20601:
 		mid = 183; // metal bar
 		break;
-	}
-	case 20600: {
+
+	case 20600:
 		mid = 237; // cover
 		break;
-	}
-	case 20648: {
+
+	case 20648:
 		mid = 237; // pit
 		break;
-	}
-	case 20570: {
+
+	case 20570:
 		mid = 268; // exit to medical droid room
 		break;
-	}
 
-	case 20573: {
+	case 20573:
 		mid = 290; // droid room exit
 		break;
-	}
-	case 20579: {
+
+	case 20579:
 		mid = 272; // droid room exit
 		break;
-	}
-	case 20572: {
+
+	case 20572:
 		mid = 277; // droid room exit
 		break;
-	}
-	case 20578: {
+
+	case 20578:
 		mid = 286; // console
 		break;
-	}
-	case 20674: {
+
+	case 20674:
 		mid = 279; // droid room exit
 		break;
-	}
 
-	case 20675: {
+	case 20675:
 		mid = 238; // robot
 		break;
-	}
-	case 20511: {
+
+	case 20511:
 		mid = 259; // slot
 		break;
-	}
 
-	case 20583: {
+	case 20583:
 		mid = 291; // tank room exit
 		break;
-	}
-	case 20604: {
+
+	case 20604:
 		mid = 264; // tank room exit
 		break;
-	}
-	case 20676: {
+
+	case 20676:
 		mid = 294; // exit
 		break;
-	}
-	case 20619: {
+
+	case 20619:
 		mid = 269; // exit
 		break;
-	}
-	case 20628: {
+
+	case 20628:
 		mid = 284; // exit
 		break;
-	}
-	case 20617: {
+
+	case 20617:
 		mid = 295; // exit
 		break;
-	}
 
-	case 24786: {
+	case 24786:
 		mid = 256; // linc crystal
 		break;
-	}
-	case 24787: {
+
+	case 24787:
 		mid = 256; // linc crystal
 		break;
-	}
 
-	case 20672: {
+	case 20672:
 		mid = 265; // android room exit
 		break;
-	}
-	case 20696: {
+
+	case 20696:
 		mid = 265; // android room exit
 		break;
-	}
-	case 20697: {
+
+	case 20697:
 		mid = 265; // android room exit
 		break;
-	}
-	case 20715: {
+
+	case 20715:
 		mid = 265; // android room exit
 		break;
-	}
 
-	case 20711: {
+	case 20711:
 		mid = 219; // console
 		break;
-	}
-	case 20712: {
+
+	case 20712:
 		mid = 219; // console
 		break;
-	}
-	case 20713: {
+
+	case 20713:
 		mid = 219; // console
 		break;
-	}
 
-	case 20725: {
+	case 20725:
 		mid = 268; // exit
 		break;
-	}
 
-	case 20726: {
+	case 20726:
 		mid = 270; // exit from door room
 		break;
-	}
-	case 20728: {
+
+	case 20728:
 		mid = 219; // exit from door room
 		break;
-	}
 
-	case 20741: {
+	case 20741:
 		mid = 254; // exit from first vein room
 		break;
-	}
-	case 20743: {
+
+	case 20743:
 		mid = 279; // exit from first vein room
 		break;
-	}
-	case 20752: {
+
+	case 20752:
 		mid = 279; // exit near end
 		break;
-	}
-	case 20886: {
+
+	case 20886:
 		mid = 243; // exit orifice to linc
 		break;
-	}
 
-	case 20874: {
+	case 20874:
 		mid = 0; // pipe support - removed as appears to have no interaction
 		break;
-	}
 
 	// linc
-	case 24592: {
+	case 24592:
 		mid = 306; // maze mid-bot
 		break;
-	}
-	case 24634: {
+
+	case 24634:
 		mid = 306; // maze mid-bot
 		break;
-	}
-	case 24594: {
+
+	case 24594:
 		mid = 278; // maze left-mid
 		break;
-	}
 
-	case 8272: {
+	case 8272:
 		mid = 0; // REMOVE power room chair
 		break;
-	}
 
 	case 8290:
-	case 8291: { // power room switches
+	case 8291: // power room switches
 		if (!Logic::_scriptVariables[429])
 			return  0;
 	}
-	}
 
 	return mid;
 }
@@ -1538,7 +1495,6 @@ int Mouse::touchingFloor(uint16 xPos, uint16 yPos) {
 }
 
 void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
-
 	if (SkyEngine::isIbass()) {
 		int midx, midy; // open hotspot dimensions
 		Compact *itemData;
@@ -1571,8 +1527,8 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 				if (itemData->mouseOn) {
 					_skyScreen->setProximityNotAnimate(_nearestProximityIconId);//we want this one remaining one to not animate
 
-					midx = giveXcood(itemData, _touchId);
-					midy = giveYcood(itemData, _touchId);
+					midx = giveXCood(itemData, _touchId);
+					midy = giveYCood(itemData, _touchId);
 					// calc dist
 					d = abs(xPos - midx) + abs(yPos - midy);
 
@@ -1688,8 +1644,8 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 
 			if (itemProx) {
 				itemData = _skyCompact->fetchCpt(itemProx);
-				midx = giveXcood(itemData, itemProx);
-				midy = giveYcood(itemData, itemProx);
+				midx = giveXCood(itemData, itemProx);
+				midy = giveYCood(itemData, itemProx);
 				// calc dist
 				d = abs(xPos - midx) + abs(yPos - midy);
 			}
@@ -1785,7 +1741,10 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 
 							_skyScreen->setIcon(getInteractIcon(_touchId), iconx + 4, icony);
 
-							if (_touchId == 70 || _touchId == 69 || _touchId == 24633 || _touchId == 24634 || _touchId == 4119 || _touchId == 8210) // stairs on screen 1 - normal object turned into exit - need to hack the button - the rest are either talk-to, which doesnt seem to matter, or look-at, like posters on walls
+							// stairs on screen 1 - normal object turned into exit - need to hack the button -
+							// the rest are either talk-to, which doesnt seem to matter, or look-at, like posters on walls
+							if (_touchId == 70 || _touchId == 69 || _touchId == 24633
+								|| _touchId == 24634 || _touchId == 4119 || _touchId == 8210)
 								Logic::_scriptVariables[BUTTON] = 1;
 							else
 								Logic::_scriptVariables[BUTTON] = 2;
@@ -1829,7 +1788,7 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 					_skyLogic->startInventory();
 					_touchId = 0;
 					_holding = false;
-					M_MODE = PRE_INVENTORY;
+					_mMode = PRE_INVENTORY;
 					_skyScreen->clearAllProximityIcons(false);
 					_skyScreen->clearAllIbassIcons(false);
 					return;
@@ -1864,8 +1823,8 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 					_skyScreen->clearAllProximityIcons();
 					// clear all but the one relating to the highlighted hotspot - hmmm
 					itemData = _skyCompact->fetchCpt(_touchId);
-					midx = giveXcood(itemData, _touchId);
-					midy = giveYcood(itemData, _touchId); //itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY>>1);
+					midx = giveXCood(itemData, _touchId);
+					midy = giveYCood(itemData, _touchId); //itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY>>1);
 					_skyScreen->setProximityIcon(0, midx - TOP_LEFT_X - 4, ((midy - TOP_LEFT_Y) - 4), 1.0, 0);
 					_skyScreen->setProximityNotAnimate(0);//we want this one remaining one to not animate
 				}
@@ -1989,30 +1948,30 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 
 void Mouse::initExitIcon(uint32 type, int iconx, int icony) {
 	switch (type) {
-	case MOUSE_LEFT: {
+	case MOUSE_LEFT:
 		_actionFlashIcon = UI_ICON_LEFT;
 		_actionFlashX = iconx + 8;
 		_skyScreen->setIcon(UI_ICON_LEFT, iconx + 8, icony);
 		break;
-	}
-	case MOUSE_RIGHT: {
+
+	case MOUSE_RIGHT:
 		_actionFlashIcon = UI_ICON_RIGHT;
 		_actionFlashX = iconx + 4;
 		_skyScreen->setIcon(UI_ICON_RIGHT, iconx + 4, icony);
 		break;
-	}
-	case MOUSE_UP: {
+
+	case MOUSE_UP:
 		_actionFlashIcon = UI_ICON_UP;
 		_actionFlashX = iconx + 5;
 		_skyScreen->setIcon(UI_ICON_UP, iconx + 5, icony);
 		break;
-	}
-	case MOUSE_DOWN: {
+
+	case MOUSE_DOWN:
 		_actionFlashIcon = UI_ICON_DOWN;
 		_actionFlashX = iconx + 5;
 		_skyScreen->setIcon(UI_ICON_DOWN, iconx + 5, icony);
 		break;
-	}
+
 	}
 }
 
@@ -2029,8 +1988,8 @@ void Mouse::updateHotspotCoordinate(uint16 xPos) {
 	// if not a floor
 	if (itemData->mouseOn && !_isExit) {
 
-		midx = giveXcood(itemData, _touchIdLegacy);
-		midy = giveYcood(itemData, _touchIdLegacy);
+		midx = giveXCood(itemData, _touchIdLegacy);
+		midy = giveYCood(itemData, _touchIdLegacy);
 
 		int icony = midy - HOTSPOT_yoff;
 		icony -= TOP_LEFT_Y; // normalise for renderer
@@ -2159,7 +2118,7 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 		if (xPos < _invX || xPos > _invX + _invW || yPos < _invY || yPos > _invY + _invH) {
 
 			// dragged off of the inv
-			M_MODE = INVENTORY_USE_ON;
+			_mMode = INVENTORY_USE_ON;
 			// remove inv items from screen/logic processing
 			_skyLogic->killInventory();
 			// got to tidy the inv item
@@ -2373,7 +2332,7 @@ void Mouse::invMouse(uint16 xPos, uint16 yPos) {
 	if (!_touchId && _mouseB) {
 		if (xPos < _invX || xPos > _invX + _invW || yPos < _invY || yPos > _invY + _invH) {
 
-			M_MODE = MUST_RELEASE; // MUST_RELEASE because if we go straight to GAMEPLAY, robert will move to the place of clicking
+			_mMode = MUST_RELEASE; // MUST_RELEASE because if we go straight to GAMEPLAY, robert will move to the place of clicking
 			_skyLogic->killInventory(); // stop rendering the inventory items
 			return;
 		}
diff --git a/engines/sky/mouse.h b/engines/sky/mouse.h
index c79722e6b12..93cf8398923 100644
--- a/engines/sky/mouse.h
+++ b/engines/sky/mouse.h
@@ -123,8 +123,8 @@ public:
 		return	_system;
 	}
 	int	doProximityHighlights(uint16 xPos, uint16 yPos);
-	uint16 giveXcood(Compact *itemData, uint32 id);
-	uint16 giveYcood(Compact *itemData, uint32 id);
+	uint16 giveXCood(Compact *itemData, uint32 id);
+	uint16 giveYCood(Compact *itemData, uint32 id);
 	void setLincInv(bool inv) {
 		_isLincInv = inv;
 	}
@@ -214,7 +214,7 @@ protected:
 		TEXT_CHOOSER,
 		MUST_RELEASE,
 		ALERT_TO_GAME, // new game alert box
-	} M_MODE;
+	} _mMode;
 };
 
 } // End of namespace Sky


Commit: 3e8ecfcf6e61999443158b2e46f05164bc611dec
    https://github.com/scummvm/scummvm/commit/3e8ecfcf6e61999443158b2e46f05164bc611dec
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Some more cleanup, refactoring and naming changes

Changed paths:
    engines/sky/mouse.cpp
    engines/sky/mouse.h


diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index e5cd4f665eb..a7cef2b17c5 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -349,7 +349,7 @@ int Mouse::doProximityHighlights(uint16 xPos, uint16 yPos) {
 		proxFrame = 0;
 
 	// near inv button?
-	if (yPos > HOTSPOT_invy && xPos < HOTSPOT_invx)
+	if (yPos > HOTSPOT_INVY && xPos < HOTSPOT_INVX)
 		return  0;
 
 	// not on same as last time, or was not on anything previously, so re-scan all objects
@@ -561,14 +561,84 @@ bool Mouse::hasSingleInteractIcon(uint32 id) {
 }
 
 uint16 Mouse::giveXCood(Compact *itemData, uint32 id) {
+
+	struct MouseXMap {
+		int id;
+		int mid;
+	} mouseXMap[] = {
+		{ 4112, 258 }, // cupboard door
+		{ 4113, 254 }, // sandwich
+		{ 4114, 254 }, // spanner
+		{ 12358, 428 }, // bellevue - missing exit
+		{ 12681, 428 }, // bellevue
+		{ 12349, 142 }, // bellevue
+		{ 12347, 428 }, // bellevue
+		{ 90, 404 }, // first room, door
+		{ 97, 190 }, // ledge room, door
+		{ 4116, 269 }, // elevator
+		{ 4119, 269 }, // hole
+		{ 4110, 356 }, // lathe
+		{ 8248, 357 }, // walkway to security lobby
+		{ 8238, 181 }, // walkway to power
+		{ 8317, 426 }, // walkway to crash
+		{ 8341, 173 }, // factory to walkway
+		{ 8344, 433 }, // factory to factory 2
+		{ 8500, 224 }, // sensors
+		{ 8355, 428 }, // factory 2 to factory 3
+		{ 8446, 226 }, // putty
+		{ 8438, 226 }, // gangway
+		{ 12680, 201 }, // exit
+		{ 12679, 307 }, // exit
+		{ 12678, 179 }, // exit
+		{ 12677, 319 }, // exit
+		{ 12324, 191 }, // exit
+		{ 12336, 182 }, // exit
+		{ 12442, 376 }, // exit
+		{ 8483, 225 }, // console
+		{ 12641, 158 }, // exit
+		// linc
+		{ 12633, 190 }, // maze
+		{ 24586, 210 }, // maze
+		{ 24592, 288 }, // maze
+		{ 24593, 400 }, // maze
+		{ 24594, 203 }, // maze
+		{ 24595, 299 }, // maze
+		// hyde
+		{ 16496, 263 }, // plant
+		// cathedral
+		{ 16462, 168 }, // exit
+		// lockers
+		{ 16576, 246 }, // body == 16569
+		{ 16577, 271 }, // body == 16570
+		{ 16578, 296 }, // body == 16571
+		{ 16579, 321 }, // body == 16572
+		{ 16580, 346 }, // body == 16573
+		// underworld
+		{ 20506, 389 }, // metal door
+		// pit world
+		{ 20600, 283 }, // cover
+		{ 20648, 283 }, // pit
+		{ 20570, 247 }, // exit to medical droid room
+		{ 20575, 277 }, // slot
+		{ 20577, 297 }, // recharge unit
+		{ 24786, 288 }, // linc crystal
+		{ 24787, 288 }, // virus
+		{ 20712, 305 }, // console
+		{ 20713, 356 }, // console
+		{ 20728, 388 }, // exit from door room
+		{ 8272, 278 }, // power room chair
+		{ 12390, 187 }, // burke door
+		{ 12541, 187 }, // burke exit
+		{ 0, 0 }
+	};
+
 	uint16 mid, midy;
 
 	mid = itemData->xcood + ((int16)itemData->mouseRelX) + (itemData->mouseSizeX >> 1);
 	midy = itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY >> 1);
 
-	if (mid < HOTSPOT_invx && midy > HOTSPOT_invy)
-		return  HOTSPOT_invx + 16;
-
+	if (mid < HOTSPOT_INVX && midy > HOTSPOT_INVY)
+		return  HOTSPOT_INVX + 16;
 
 	// not lamb
 	if (id != 16) {
@@ -578,243 +648,18 @@ uint16 Mouse::giveXCood(Compact *itemData, uint32 id) {
 			return  142;
 	}
 
-	switch (id) {
-	case 4112:
-		mid = 258; // cupboard door
-		break;
-
-	case 4113:
-		mid = 254; // sandwich
-		break;
-
-	case 4114:
-		mid = 254; // spanner
-		break;
-
-
-	case 12358:
-		mid = 428; // bellevue - missing exit
-		break;
-
-	case 12681:
-		mid = 428; // bellevue
-		break;
-
-	case 12349:
-		mid = 142; // bellevue
-		break;
-
-	case 12347:
-		mid = 428; // bellevue
-		break;
-
-	case 90:
-		mid = 404; // first room, door
-		break;
-
-	case 97:
-		mid = 190; // ledge room, door
-		break;
-
-	case 4116:
-		mid = 269; // elevator
-		break;
-
-	case 4119:
-		mid = 269; // hole
-		break;
-
-	case 4110:
-		mid = 356; // lathe
-		break;
-
-	case 8248:
-		mid = 357; // walkway to security lobby
-		break;
-
-	case 8238:
-		mid = 181; // walkway to power
-		break;
-
-	case 8317:
-		mid = 426; // walkway to crash
-		break;
-
-	case 8341:
-		mid = 173; // factory to walkway
-		break;
-
-	case 8344:
-		mid = 433; // factory to factory 2
-		break;
+	Common::HashMap<int, int> hotspotMap;
+	bool mapInitialized = false;
 
-	case 8500:
-		mid = 224; // sensors
-		break;
-
-	case 8355:
-		mid = 428; // factory 2 to factory 3
-		break;
-
-	case 8446:
-		mid = 226; // putty
-		break;
-
-	case 8438:
-		mid = 226; // gangway
-		break;
-
-	case 12680:
-		mid = 201; // exit
-		break;
-
-	case 12679:
-		mid = 307; // exit
-		break;
-
-	case 12678:
-		mid = 179; // exit
-		break;
-
-	case 12677:
-		mid = 319; // exit
-		break;
-
-	case 12324:
-		mid = 191; // exit
-		break;
-
-	case 12336:
-		mid = 182; // exit
-		break;
-
-	case 12442:
-		mid = 376; // exit
-		break;
-
-	case 8483:
-		mid = 225; // console
-		break;
-
-	case 12641:
-		mid = 158; // exit
-		break;
-
-	// linc
-	case 12633:
-		mid = 190; // maze
-		break;
-
-	case 24586:
-		mid = 210; // maze
-		break;
-
-	case 24592:
-		mid = 288; // maze mid-bot
-		break;
-
-	case 24593:
-		mid = 400; // maze mid-bot
-		break;
-
-	case 24594:
-		mid = 203; // maze left-mid
-		break;
-
-	case 24595:
-		mid = 299; // maze left-mid
-		break;
-
-	// hyde
-	case 16496:
-		mid = 263; // plant
-		break;
-
-	// cathedral
-	case 16462:
-		mid = 168; // exit
-		break;
-
-	// lockers
-	case 16576:
-		mid = 246; // body == 16569
-		break;
-
-	case 16577:
-		mid = 271; // body == 16570
-		break;
-
-	case 16578:
-		mid = 296; // body == 16571
-		break;
-
-	case 16579:
-		mid = 321; // body == 16572
-		break;
-
-	case 16580:
-		mid = 346; // body == 16573
-		break;
-
-	// underworld
-	case 20506:
-		mid = 389; // metal door
-		break;
-
-	// pit room
-	case 20600:
-		mid = 283; // cover
-		break;
-
-	case 20648:
-		mid = 283; // pit
-		break;
-
-	case 20570:
-		mid = 247; // exit to medical droid room
-		break;
-
-	case 20575:
-		mid = 277; // slot
-		break;
-
-	case 20577:
-		mid = 297; // recharge unit
-		break;
-
-	case 24786:
-		mid = 288; // linc crystal
-		break;
-
-	case 24787:
-		mid = 288; // virus
-		break;
-
-	case 20712:
-		mid = 305; // console
-		break;
-
-	case 20713:
-		mid = 356; // console
-		break;
-
-	case 20728:
-		mid = 388; // exit from door room
-		break;
-
-	case 8272:
-		mid = 278; // power room chair
-		break;
-
-	case 12390:
-		mid = 187; // burke door
-		break;
-
-	case 12541:
-		mid = 187; // burke exit
-		break;
+	if (!mapInitialized) {
+		for (MouseXMap *m = mouseXMap; m->id != 0; m++)
+			hotspotMap[m->id] = m->mid;
+		mapInitialized = true;
 	}
 
+	if (hotspotMap.contains(id))
+		return hotspotMap[id];
+
 	return  mid;
 }
 
@@ -1465,7 +1310,7 @@ int Mouse::touchingFloor(uint16 xPos, uint16 yPos) {
 	uint16 itemNum;
 
 	// do not detect floors beyond a certain depth
-	if (yPos > (HOTSPOT_invy + 8)) return 0;
+	if (yPos > (HOTSPOT_INVY + 8)) return 0;
 	if (yPos < (20 + TOP_LEFT_Y)) return 0;
 
 	do {
@@ -1534,11 +1379,11 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 
 					// some left hand edge adjust for twin-hotspot non-exits
 					if (!hasSingleInteractIcon(_touchId) && !_isExit)
-						if ((midx - HOTSPOT_dim) < TOP_LEFT_X)
-							midx = TOP_LEFT_X + HOTSPOT_dim;
+						if ((midx - HOTSPOT_DIM) < TOP_LEFT_X)
+							midx = TOP_LEFT_X + HOTSPOT_DIM;
 
 					// still touching a normal hotspot?
-					if (!_isExit && midx - HOTSPOT_dim < xPos && midx + HOTSPOT_dim > xPos && midy - HOTSPOT_yoff < yPos && midy/*+HOTSPOT_yoff*/ > yPos) {
+					if (!_isExit && midx - HOTSPOT_DIM < xPos && midx + HOTSPOT_DIM > xPos && midy - HOTSPOT_YOFF < yPos && midy/*+HOTSPOT_YOFF*/ > yPos) {
 						// if newly touching, and same item as last time, then inc the click count
 						if (_prevMouseOn == false) {
 
@@ -1550,7 +1395,7 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 						} else
 							_timeOn++;
 
-						int icony = midy - HOTSPOT_yoff;
+						int icony = midy - HOTSPOT_YOFF;
 						icony -= TOP_LEFT_Y; // normalise for renderer
 						if (icony < 0)
 							icony = 0;
@@ -1558,7 +1403,7 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 						if (hasSingleInteractIcon(_touchId)) {
 							// update the coordinate of the hotspot
 							midx -= TOP_LEFT_X;
-							midx -= HOTSPOT_ExitDim;
+							midx -= HOTSPOT_EXIT_DIM;
 
 							// draw the icons
 							_skyScreen->setIcon(getInteractIcon(_touchId), midx + 4, icony);
@@ -1568,17 +1413,17 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 
 						} else { // 2 icons
 							midx -= TOP_LEFT_X;
-							midx -= HOTSPOT_dim;
+							midx -= HOTSPOT_DIM;
 
 							_actionFlashY = icony;
 
-							if (xPos <= (midx + HOTSPOT_dim + TOP_LEFT_X)) {
+							if (xPos <= (midx + HOTSPOT_DIM + TOP_LEFT_X)) {
 								Logic::_scriptVariables[BUTTON] = 2;
 								_actionFlashX = midx;
 								_actionFlashIcon = UI_ICON_LOOK;
 							} else {
 								Logic::_scriptVariables[BUTTON] = 1;
-								_actionFlashX = midx + HOTSPOT_dim + 4;
+								_actionFlashX = midx + HOTSPOT_DIM + 4;
 								_actionFlashIcon = getInteractIcon(_touchId);
 							}
 						}
@@ -1588,7 +1433,7 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 
 						// end here, when button held on something
 						return;
-					} else if (_isExit && midx - HOTSPOT_dim < xPos && midx + HOTSPOT_dim > xPos && midy - HOTSPOT_yoff < yPos && midy/*+HOTSPOT_yoff*/ > yPos) {
+					} else if (_isExit && midx - HOTSPOT_DIM < xPos && midx + HOTSPOT_DIM > xPos && midy - HOTSPOT_YOFF < yPos && midy/*+HOTSPOT_YOFF*/ > yPos) {
 						// still touching the poped up exit
 						// which action
 						Logic::_scriptVariables[BUTTON] = 1;
@@ -1603,12 +1448,12 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 						} else {
 							_timeOn++; // one more cycle
 							// update the coordinate of the hotspot
-							int iconx = midx - HOTSPOT_ExitDim;
+							int iconx = midx - HOTSPOT_EXIT_DIM;
 							iconx -= TOP_LEFT_X; // normalise for renderer
 							if (iconx < 0)
 								iconx = 0;
 
-							int icony = midy - HOTSPOT_exit_yoff;
+							int icony = midy - HOTSPOT_EXIT_YOFF;
 							icony -= TOP_LEFT_Y; // normalise for renderer
 							if (icony < 0)
 								icony = 0;
@@ -1712,12 +1557,12 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 					// exit, or hotspot?
 					if (_isExit) {
 
-						int iconx = midx - HOTSPOT_ExitDim;
+						int iconx = midx - HOTSPOT_EXIT_DIM;
 						iconx -= TOP_LEFT_X; // normalise for renderer
 						if (iconx < 0)
 							iconx = 0;
 
-						int icony = midy - HOTSPOT_exit_yoff;
+						int icony = midy - HOTSPOT_EXIT_YOFF;
 						icony -= TOP_LEFT_Y; // normalise for renderer
 						if (icony < 0)
 							icony = 0;
@@ -1725,14 +1570,14 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 						// draw the icon
 						initExitIcon(_exitType, iconx, icony);
 					} else {
-						int icony = midy - HOTSPOT_yoff;
+						int icony = midy - HOTSPOT_YOFF;
 						icony -= TOP_LEFT_Y;// normalise for renderer
 						if (icony < 0)
 							icony = 0;
 
 						if (hasSingleInteractIcon(_touchId)) {
 							// update the coordinate of the hotspot
-							int iconx = midx - HOTSPOT_ExitDim;
+							int iconx = midx - HOTSPOT_EXIT_DIM;
 							iconx -= TOP_LEFT_X;// normalise for renderer
 							if (iconx < 0)
 								iconx = 0;
@@ -1751,14 +1596,14 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 
 						} else { // 2 icons
 							// update the coordinate of the hotspot
-							int iconx = midx - HOTSPOT_dim;
+							int iconx = midx - HOTSPOT_DIM;
 							iconx -= TOP_LEFT_X;// normalise for renderer
 							if (iconx < 0)
 								iconx = 0;
 
 							// draw the icons
 							_skyScreen->setIcon(UI_ICON_LOOK, iconx, icony);
-							_skyScreen->setIcon(getInteractIcon(_touchId), iconx + HOTSPOT_dim + 4, icony);
+							_skyScreen->setIcon(getInteractIcon(_touchId), iconx + HOTSPOT_DIM + 4, icony);
 						}
 					}
 				} else if (!_floorLock) { // no mouseOn script, which probably always means this is a floor?
@@ -1784,7 +1629,7 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 			}
 			// not touching a game object - but what about HU buttons, such as Inv?
 			if (!_prevMouseOn && 101 != Logic::_scriptVariables[SCREEN] && Logic::_scriptVariables[LOGIC_LIST_NO] != 24765) {
-				if (xPos < HOTSPOT_invx && yPos > HOTSPOT_invy) {
+				if (xPos < HOTSPOT_INVX && yPos > HOTSPOT_INVY) {
 					_skyLogic->startInventory();
 					_touchId = 0;
 					_holding = false;
@@ -1794,7 +1639,7 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 					return;
 				}
 				// control panel
-				if (xPos < HOTSPOT_optionsx && yPos < HOTSPOT_optionsy) {
+				if (xPos < HOTSPOT_OPTIONSX && yPos < HOTSPOT_OPTIONSY) {
 					_skyControl->doControlPanel();
 					_skyScreen->clearAllProximityIcons(false);
 					_skyScreen->clearAllIbassIcons(false);
@@ -1991,14 +1836,14 @@ void Mouse::updateHotspotCoordinate(uint16 xPos) {
 		midx = giveXCood(itemData, _touchIdLegacy);
 		midy = giveYCood(itemData, _touchIdLegacy);
 
-		int icony = midy - HOTSPOT_yoff;
+		int icony = midy - HOTSPOT_YOFF;
 		icony -= TOP_LEFT_Y; // normalise for renderer
 		if (icony < 0)
 			icony = 0;
 
 		if (hasSingleInteractIcon(_touchIdLegacy)) {
 			// update the coordinate of the hotspot
-			int iconx = midx - HOTSPOT_ExitDim;
+			int iconx = midx - HOTSPOT_EXIT_DIM;
 			iconx -= TOP_LEFT_X;//normalise for renderer
 			if (iconx < 0)
 				iconx = 0;
@@ -2007,14 +1852,14 @@ void Mouse::updateHotspotCoordinate(uint16 xPos) {
 			_skyScreen->setIcon(getInteractIcon(_touchIdLegacy), iconx + 4, icony);
 		} else {
 			// update the coordinate of the hotspot
-			int iconx = midx - HOTSPOT_dim;
+			int iconx = midx - HOTSPOT_DIM;
 			iconx -= TOP_LEFT_X;//normalise for renderer
 			if (iconx < 0)
 				iconx = 0;
 
 			// draw the icons
 			_skyScreen->setIcon(UI_ICON_LOOK, iconx, icony);
-			_skyScreen->setIcon(getInteractIcon(_touchIdLegacy), iconx + HOTSPOT_dim + 4, icony);
+			_skyScreen->setIcon(getInteractIcon(_touchIdLegacy), iconx + HOTSPOT_DIM + 4, icony);
 
 			// still touching the poped up area
 			// which action
@@ -2311,7 +2156,7 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 
 				if (Logic::_scriptVariables[OBJECT_HELD]) {
 					// just render offset - cursor is still beneath the finger
-					_mouseYOff = HOTSPOT_useon_yoff;
+					_mouseYOff = HOTSPOT_USE_ON_YOFF;
 					_holding = true;
 					_touchIdLegacy = _touchId;
 					_skyLogic->startInventory(_touchId); // highlight touched item
diff --git a/engines/sky/mouse.h b/engines/sky/mouse.h
index 93cf8398923..d7e0982b33b 100644
--- a/engines/sky/mouse.h
+++ b/engines/sky/mouse.h
@@ -36,28 +36,24 @@ namespace Sky {
 // time till hotspot fades out after stopped touching
 #define HOTSPOT_FADEOUT 36
 // hotspot icon size
-#define HOTSPOT_dim 36
+#define HOTSPOT_DIM 36
 // exit is just one icon, so half width as straddles centre point
-#define HOTSPOT_ExitDim (HOTSPOT_dim >> 1)
-// closed hotspot radius
-#define HOTSPOT_RADx 8
-#define HOTSPOT_RAD 16
-
+#define HOTSPOT_EXIT_DIM (HOTSPOT_DIM >> 1)
 // how far the popup icons sit above the midy
-#define HOTSPOT_yoff 48
+#define HOTSPOT_YOFF 48
 // differentiate exits, just incase
-#define HOTSPOT_exit_yoff 48
+#define HOTSPOT_EXIT_YOFF 48
 
 // use on cursor offset
-#define HOTSPOT_useon_yoff (-55)
+#define HOTSPOT_USE_ON_YOFF (-55)
 
 // inv button (bottom left)
-#define HOTSPOT_invx (TOP_LEFT_X + 40)
-#define HOTSPOT_invy (TOP_LEFT_Y + FULL_SCREEN_HEIGHT-35)
+#define HOTSPOT_INVX (TOP_LEFT_X + 40)
+#define HOTSPOT_INVY (TOP_LEFT_Y + FULL_SCREEN_HEIGHT-35)
 
 // control panel button (top left)
-#define HOTSPOT_optionsx (TOP_LEFT_X + 30)
-#define HOTSPOT_optionsy (TOP_LEFT_Y + 30)
+#define HOTSPOT_OPTIONSX (TOP_LEFT_X + 30)
+#define HOTSPOT_OPTIONSY (TOP_LEFT_Y + 30)
 
 // help button (top right)
 #define HOTSPOT_helpx (TOP_LEFT_X + FULL_SCREEN_WIDTH-30)


Commit: 76f09bad0db3e95085577e1da0e5d608805d11ec
    https://github.com/scummvm/scummvm/commit/76f09bad0db3e95085577e1da0e5d608805d11ec
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Move some variables to class, fix formatting and adress PR reviews

Changed paths:
    engines/sky/inventory.cpp
    engines/sky/logic.cpp
    engines/sky/mouse.cpp
    engines/sky/mouse.h


diff --git a/engines/sky/inventory.cpp b/engines/sky/inventory.cpp
index 40db2616775..b8087185a76 100644
--- a/engines/sky/inventory.cpp
+++ b/engines/sky/inventory.cpp
@@ -114,7 +114,7 @@ int Screen::getInventoryAnimIdx(int frame) {
 			return i;
 	}
 
-	debug("Couldn't find inventory item%d\n", frame);
+	debug(1, "Couldn't find inventory item%d", frame);
 	return 0; // fallback
 }
 
@@ -143,4 +143,4 @@ void Logic::killInventory() {
 	_skyScreen->clearAllInvIcons();
 }
 
-}
+} // End of namespace Sky
diff --git a/engines/sky/logic.cpp b/engines/sky/logic.cpp
index 8097e88cb8f..673279b977c 100644
--- a/engines/sky/logic.cpp
+++ b/engines/sky/logic.cpp
@@ -1877,7 +1877,7 @@ bool Logic::fnStartMenu(uint32 firstObject, uint32 b, uint32 c) {
 	if (SkyEngine::isIbass()) {
 		Compact *cpt;
 
-		debug("init inv menu %d", firstObject);
+		debug(1, "init inv menu %d", firstObject);
 
 		// safety flag
 		_liveInv = true;
@@ -1905,7 +1905,7 @@ bool Logic::fnStartMenu(uint32 firstObject, uint32 b, uint32 c) {
 		}
 		_scriptVariables[MENU_LENGTH] = menuLength;
 
-		debug("Menu length = %d", menuLength);
+		debug(1, "Menu length = %d", menuLength);
 
 		uint16 rollingX = TOP_LEFT_X + XWIDTH;
 		int xx = 0;
@@ -1923,7 +1923,7 @@ bool Logic::fnStartMenu(uint32 firstObject, uint32 b, uint32 c) {
 			}
 
 			cpt = _skyCompact->fetchCpt(_objectList[i]);
-			debug("Init i = %d ob = %d fr = %d\n", i, _objectList[i], cpt->frame);
+			debug(1, "Init i = %d ob = %d fr = %d\n", i, _objectList[i], cpt->frame);
 
 			cpt->status = ST_MOUSE + ST_FOREGROUND + /*ST_LOGIC +*/ ST_RECREATE;
 			cpt->screen = 999;
diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index a7cef2b17c5..ec11e96329c 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -107,6 +107,11 @@ Mouse::Mouse(OSystem *system, Disk *skyDisk, SkyCompact *skyCompact, Screen *sky
 	//load in the object mouse file
 	_objectMouseData = _skyDisk->loadFile(MICE_FILE + 1);
 
+	_proxFrame = 0;
+	_proxFrameSpeed = 0;
+
+	_mapInitialized = false;
+
 	resetUI();
 }
 
@@ -233,7 +238,7 @@ void Mouse::spriteMouse(uint16 frameNum, uint8 mouseX, uint8 mouseY) {
 	_currentCursor = frameNum;
 
 	if (SkyEngine::isIbass()) {
-		debug("ibass cursor path executed\n");
+		debug(1, "ibass cursor path executed\n");
 		CursorMan.setDefaultArrowCursor();
 		CursorMan.showMouse(true);
 		return;
@@ -276,42 +281,42 @@ void Mouse::mouseEngine() {
 		}
 
 		switch (_mMode) {
-			case ALERT_TO_GAME:
-				if (!_mouseB)
-					return;
+		case ALERT_TO_GAME:
+			if (!_mouseB)
+				return;
 
-				_skyScreen->hideInventory();
-				_mMode = MUST_RELEASE;
-				break;
+			_skyScreen->hideInventory();
+			_mMode = MUST_RELEASE;
+			break;
 
-			case MUST_RELEASE:
-				if (_mouseB)
-					return;
+		case MUST_RELEASE:
+			if (_mouseB)
+				return;
 
-				resetUI();
-				_mMode = GAMEPLAY;
-				break;
+			resetUI();
+			_mMode = GAMEPLAY;
+			break;
 
-			case GAMEPLAY:
-				pointerEngine(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
-				break;
+		case GAMEPLAY:
+			pointerEngine(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
+			break;
 
-			case PRE_INVENTORY:
-				if (_mouseB)
-					return;
+		case PRE_INVENTORY:
+			if (_mouseB)
+				return;
 
-				_mMode = INVENTORY;
-				break;
+			_mMode = INVENTORY;
+			break;
 
-			case INVENTORY:
-				if (isLincInv())
-					lincInvMouse(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
-				else
-					invMouse(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
+		case INVENTORY:
+			if (isLincInv())
+				lincInvMouse(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
+			else
+				invMouse(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
 
-			case INVENTORY_USE_ON:
-			case TEXT_CHOOSER:
-				break;
+		case INVENTORY_USE_ON:
+		case TEXT_CHOOSER:
+			break;
 		}
 
 		_mouseB = 0;
@@ -339,14 +344,11 @@ int Mouse::doProximityHighlights(uint16 xPos, uint16 yPos) {
 	int nearestId = 0;
 	_nearestProximityIconId = 0;
 
-	int proxFrame = 0;
-	int proxFrameSpeed = 0;
-
-	proxFrameSpeed++;
-	if (proxFrameSpeed & 1)
-		proxFrame++;
-	if (proxFrame == 3)
-		proxFrame = 0;
+	_proxFrameSpeed++;
+	if (_proxFrameSpeed & 1)
+		_proxFrame++;
+	if (_proxFrame == 3)
+		_proxFrame = 0;
 
 	// near inv button?
 	if (yPos > HOTSPOT_INVY && xPos < HOTSPOT_INVX)
@@ -372,7 +374,7 @@ int Mouse::doProximityHighlights(uint16 xPos, uint16 yPos) {
 					int d = abs(xPos - midx) + abs(yPos - midy);
 					if (d < GLOW_DIST) {
 						float opacity = 1.0 - ((d * 1.0) / GLOW_DIST);
-						_skyScreen->setProximityIcon(found++, midx - TOP_LEFT_X - 4, ((midy - TOP_LEFT_Y) - 4), opacity, proxFrame);
+						_skyScreen->setProximityIcon(found++, midx - TOP_LEFT_X - 4, ((midy - TOP_LEFT_Y) - 4), opacity, _proxFrame);
 					}
 
 					if (d < nearestDist) {
@@ -385,10 +387,9 @@ int Mouse::doProximityHighlights(uint16 xPos, uint16 yPos) {
 		}
 		if (*currentList == 0xFFFF)
 			currentListNum = currentList[1];
-	}
-	while (*currentList != 0);
+	} while (*currentList != 0);
 
-	return	nearestId;
+	return  nearestId;
 }
 
 UIIcon Mouse::getInteractIcon(uint32 id) {
@@ -560,78 +561,77 @@ bool Mouse::hasSingleInteractIcon(uint32 id) {
 	return  false;
 }
 
-uint16 Mouse::giveXCood(Compact *itemData, uint32 id) {
-
-	struct MouseXMap {
-		int id;
-		int mid;
-	} mouseXMap[] = {
-		{ 4112, 258 }, // cupboard door
-		{ 4113, 254 }, // sandwich
-		{ 4114, 254 }, // spanner
-		{ 12358, 428 }, // bellevue - missing exit
-		{ 12681, 428 }, // bellevue
-		{ 12349, 142 }, // bellevue
-		{ 12347, 428 }, // bellevue
-		{ 90, 404 }, // first room, door
-		{ 97, 190 }, // ledge room, door
-		{ 4116, 269 }, // elevator
-		{ 4119, 269 }, // hole
-		{ 4110, 356 }, // lathe
-		{ 8248, 357 }, // walkway to security lobby
-		{ 8238, 181 }, // walkway to power
-		{ 8317, 426 }, // walkway to crash
-		{ 8341, 173 }, // factory to walkway
-		{ 8344, 433 }, // factory to factory 2
-		{ 8500, 224 }, // sensors
-		{ 8355, 428 }, // factory 2 to factory 3
-		{ 8446, 226 }, // putty
-		{ 8438, 226 }, // gangway
-		{ 12680, 201 }, // exit
-		{ 12679, 307 }, // exit
-		{ 12678, 179 }, // exit
-		{ 12677, 319 }, // exit
-		{ 12324, 191 }, // exit
-		{ 12336, 182 }, // exit
-		{ 12442, 376 }, // exit
-		{ 8483, 225 }, // console
-		{ 12641, 158 }, // exit
-		// linc
-		{ 12633, 190 }, // maze
-		{ 24586, 210 }, // maze
-		{ 24592, 288 }, // maze
-		{ 24593, 400 }, // maze
-		{ 24594, 203 }, // maze
-		{ 24595, 299 }, // maze
-		// hyde
-		{ 16496, 263 }, // plant
-		// cathedral
-		{ 16462, 168 }, // exit
-		// lockers
-		{ 16576, 246 }, // body == 16569
-		{ 16577, 271 }, // body == 16570
-		{ 16578, 296 }, // body == 16571
-		{ 16579, 321 }, // body == 16572
-		{ 16580, 346 }, // body == 16573
-		// underworld
-		{ 20506, 389 }, // metal door
-		// pit world
-		{ 20600, 283 }, // cover
-		{ 20648, 283 }, // pit
-		{ 20570, 247 }, // exit to medical droid room
-		{ 20575, 277 }, // slot
-		{ 20577, 297 }, // recharge unit
-		{ 24786, 288 }, // linc crystal
-		{ 24787, 288 }, // virus
-		{ 20712, 305 }, // console
-		{ 20713, 356 }, // console
-		{ 20728, 388 }, // exit from door room
-		{ 8272, 278 }, // power room chair
-		{ 12390, 187 }, // burke door
-		{ 12541, 187 }, // burke exit
-		{ 0, 0 }
-	};
+struct MouseXMap {
+	int id;
+	int mid;
+} mouseXMap[] = {
+	{ 4112, 258 }, // cupboard door
+	{ 4113, 254 }, // sandwich
+	{ 4114, 254 }, // spanner
+	{ 12358, 428 }, // bellevue - missing exit
+	{ 12681, 428 }, // bellevue
+	{ 12349, 142 }, // bellevue
+	{ 12347, 428 }, // bellevue
+	{ 90, 404 }, // first room, door
+	{ 97, 190 }, // ledge room, door
+	{ 4116, 269 }, // elevator
+	{ 4119, 269 }, // hole
+	{ 4110, 356 }, // lathe
+	{ 8248, 357 }, // walkway to security lobby
+	{ 8238, 181 }, // walkway to power
+	{ 8317, 426 }, // walkway to crash
+	{ 8341, 173 }, // factory to walkway
+	{ 8344, 433 }, // factory to factory 2
+	{ 8500, 224 }, // sensors
+	{ 8355, 428 }, // factory 2 to factory 3
+	{ 8446, 226 }, // putty
+	{ 8438, 226 }, // gangway
+	{ 12680, 201 }, // exit
+	{ 12679, 307 }, // exit
+	{ 12678, 179 }, // exit
+	{ 12677, 319 }, // exit
+	{ 12324, 191 }, // exit
+	{ 12336, 182 }, // exit
+	{ 12442, 376 }, // exit
+	{ 8483, 225 }, // console
+	{ 12641, 158 }, // exit
+	// linc
+	{ 12633, 190 }, // maze
+	{ 24586, 210 }, // maze
+	{ 24592, 288 }, // maze
+	{ 24593, 400 }, // maze
+	{ 24594, 203 }, // maze
+	{ 24595, 299 }, // maze
+	// hyde
+	{ 16496, 263 }, // plant
+	// cathedral
+	{ 16462, 168 }, // exit
+	// lockers
+	{ 16576, 246 }, // body == 16569
+	{ 16577, 271 }, // body == 16570
+	{ 16578, 296 }, // body == 16571
+	{ 16579, 321 }, // body == 16572
+	{ 16580, 346 }, // body == 16573
+	// underworld
+	{ 20506, 389 }, // metal door
+	// pit world
+	{ 20600, 283 }, // cover
+	{ 20648, 283 }, // pit
+	{ 20570, 247 }, // exit to medical droid room
+	{ 20575, 277 }, // slot
+	{ 20577, 297 }, // recharge unit
+	{ 24786, 288 }, // linc crystal
+	{ 24787, 288 }, // virus
+	{ 20712, 305 }, // console
+	{ 20713, 356 }, // console
+	{ 20728, 388 }, // exit from door room
+	{ 8272, 278 }, // power room chair
+	{ 12390, 187 }, // burke door
+	{ 12541, 187 }, // burke exit
+	{ 0, 0 }
+};
 
+uint16 Mouse::giveXCood(Compact *itemData, uint32 id) {
 	uint16 mid, midy;
 
 	mid = itemData->xcood + ((int16)itemData->mouseRelX) + (itemData->mouseSizeX >> 1);
@@ -648,17 +648,14 @@ uint16 Mouse::giveXCood(Compact *itemData, uint32 id) {
 			return  142;
 	}
 
-	Common::HashMap<int, int> hotspotMap;
-	bool mapInitialized = false;
-
-	if (!mapInitialized) {
+	if (!_mapInitialized) {
 		for (MouseXMap *m = mouseXMap; m->id != 0; m++)
-			hotspotMap[m->id] = m->mid;
-		mapInitialized = true;
+			_hotspotXMap[m->id] = m->mid;
+		_mapInitialized = true;
 	}
 
-	if (hotspotMap.contains(id))
-		return hotspotMap[id];
+	if (_hotspotXMap.contains(id))
+		return _hotspotXMap[id];
 
 	return  mid;
 }
@@ -1351,7 +1348,7 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 
 		// mouse must be down to search for stuff
 		if (_mouseB) {
-			// debug("Clicked");
+			debug(1, "Clicked");
 			// what are we near?
 			itemProx = doProximityHighlights(xPos, yPos);
 
@@ -1544,7 +1541,7 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 
 					// reset fade out timer
 					_fadeOut = HOTSPOT_FADEOUT;
-					debug("Fadeout det to 36, mouseOn = %d, dist = %d", itemData->mouseOn, d);
+					debug(1, "Fadeout det to 36, mouseOn = %d, dist = %d", itemData->mouseOn, d);
 
 					_skyScreen->setProximityNotAnimate(_nearestProximityIconId); // we want this one remaining one to not animate
 
@@ -1622,7 +1619,7 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 				// we're done
 				return;
 			} else {
-				debug("nothing");
+				debug(1, "nothing");
 				// not touching anything, force open hotspot to close
 				if (_fadeOut)
 					_fadeOut = 0;
@@ -1657,7 +1654,7 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 			_prevMouseOn = true;
 
 
-			debug("floor returned = %d", floor);
+			debug(1, "floor returned = %d", floor);
 		} else { // not touching screen
 			if (_prevMouseOn) {
 
@@ -2105,7 +2102,7 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 			Logic::_scriptVariables[SPECIAL_ITEM] = objList[j];
 
 			if (_touchId != objList[j] && !_holding) {
-				debug("New touch\n");
+				debug(1, "New touch\n");
 				// run previous items get-off, if there was one (gone straight from one object onto another)
 				if (Logic::_scriptVariables[GET_OFF])
 					_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], itemData);
@@ -2141,7 +2138,7 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 
 				// special stuff for quit-linc
 				if (_touchId == 24582) {
-					debug("QUIT LINC\n");
+					debug(1, "QUIT LINC\n");
 					itemData->frame--;
 
 					// remove inventory items from screen/logic processing
diff --git a/engines/sky/mouse.h b/engines/sky/mouse.h
index d7e0982b33b..3a56c721e4e 100644
--- a/engines/sky/mouse.h
+++ b/engines/sky/mouse.h
@@ -24,6 +24,7 @@
 
 
 #include "common/scummsys.h"
+#include "common/hashmap.h"
 
 class OSystem;
 
@@ -190,6 +191,12 @@ protected:
 
 	byte *_miceData;	//address of mouse sprites
 	byte *_objectMouseData;	//address of object mouse sprites
+	
+	int _proxFrame;
+	int _proxFrameSpeed;
+
+	Common::HashMap<int, int> _hotspotXMap;
+	bool _mapInitialized = false;
 
 	static uint32 _mouseMainObjects[24];
 	static uint32 _mouseLincObjects[21];


Commit: 63c89452831bbda966e696abba3ec85a70fef300
    https://github.com/scummvm/scummvm/commit/63c89452831bbda966e696abba3ec85a70fef300
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Create lookup table for giveYCood and fix a syntax error in mouse.h

Changed paths:
    engines/sky/mouse.cpp
    engines/sky/mouse.h


diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index ec11e96329c..7b7cf3d1246 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -110,7 +110,7 @@ Mouse::Mouse(OSystem *system, Disk *skyDisk, SkyCompact *skyCompact, Screen *sky
 	_proxFrame = 0;
 	_proxFrameSpeed = 0;
 
-	_mapInitialized = false;
+	_xMapInitialized = false;
 
 	resetUI();
 }
@@ -648,10 +648,10 @@ uint16 Mouse::giveXCood(Compact *itemData, uint32 id) {
 			return  142;
 	}
 
-	if (!_mapInitialized) {
+	if (!_xMapInitialized) {
 		for (MouseXMap *m = mouseXMap; m->id != 0; m++)
 			_hotspotXMap[m->id] = m->mid;
-		_mapInitialized = true;
+		_xMapInitialized = true;
 	}
 
 	if (_hotspotXMap.contains(id))
@@ -660,643 +660,189 @@ uint16 Mouse::giveXCood(Compact *itemData, uint32 id) {
 	return  mid;
 }
 
+struct MouseYMap {
+	uint32 id;
+	uint16 mid;
+} mouseYMap[] = {
+	{ 4113, 218 },
+	{ 4114, 226 },
+	{ 4108, 0 },
+	{ 4111, 0 },
+	{ 4115, 0 },
+	{ 4117, 0 },
+	{ 4154, 0 },
+	{ 12349, TWEEKY_EXIT_ADJUST },
+	{ 12347, TWEEKY_EXIT_ADJUST },
+	{ 12358, TWEEKY_EXIT_ADJUST },
+	{ 90, 208 },
+	{ 97, 216 },
+	{ 4116, 259 },
+	{ 4119, 259 },
+	{ 4315, 261 },
+	{ 4103, 242 },
+	{ 4105, 241 },
+	{ 4110, 230 },
+	{ 8248, 222 },
+	{ 8238, 222 },
+	{ 8310, 222 },
+	{ 8246, 273 },
+	{ 8317, 273 },
+	{ 8331, 230 },
+	{ 8341, 239 },
+	{ 8344, 282 },
+	{ 8500, 197 },
+	{ 8355, 255 },
+	{ 8366, 227 },
+	{ 8375, 238 },
+	{ 8446, 247 },
+	{ 8438, 247 },
+	{ 8364, 252 },
+	{ 8459, 252 },
+	{ 8256, 297 },
+	{ 12304, 252 },
+	{ 12338, 286 },
+	{ 12681, 250 },
+	{ 12370, 289 },
+	{ 12361, 267 },
+	{ 12679, 179 },
+	{ 12678, 179 },
+	{ 12677, 179 },
+	{ 12313, 284 },
+	{ 12676, 241 },
+	{ 12327, 244 },
+	{ 12315, 286 },
+	{ 12324, 308 },
+	{ 12336, 306 },
+	{ 12442, 246 },
+	{ 12447, 242 },
+	{ 12680, 179 },
+	{ 12459, 281 },
+	{ 12471, 302 },
+	{ 12399, 257 },
+	{ 12390, 264 },
+	{ 12541, 264 },
+	{ 12620, 220 },
+	{ 12621, 220 },
+	{ 12622, 220 },
+	{ 12623, 220 },
+	{ 12613, 220 },
+	{ 12624, 220 },
+	{ 12631, 273 },
+	{ 12641, 290 },
+	{ 12642, 273 },
+	{ 12474, 282 },
+	{ 12486, 298 },
+	{ 8295, 299 },
+	{ 16415, 261 },
+	{ 16403, 261 },
+	{ 16393, 246 },
+	{ 16487, 256 },
+	{ 16492, 287 },
+	{ 16394, 313 },
+	{ 16412, 276 },
+	{ 16428, 233 },
+	{ 16424, 236 },
+	{ 16462, 296 },
+	{ 16464, 250 },
+	{ 16465, 226 },
+	{ 16474, 263 },
+	{ 16576, 229 },
+	{ 16577, 229 },
+	{ 16578, 229 },
+	{ 16579, 229 },
+	{16580, 229 },
+	{ 8478, 291 },
+	{ 8481, 253 },
+	{ 8511, 271 },
+	{ 16538, 279 },
+	{ 16439, 267 },
+	{ 16592, 267 },
+	{ 16649, 291 },
+	{ 16660, 285 },
+	{ 16662, 254 },
+	{ 16661, 291 },
+	{ 16671, 291 },
+	{ 16681, 282 },
+	{ 16682, 282 },
+	{ 16719, 287 },
+	{ 16720, 287 },
+	{ 16729, 291 },
+	{ 16730, 301 },
+	{ 20506, 276 },
+	{ 20518, 276 },
+	{ 20532, 264 },
+	{ 20558, 296 },
+	{ 20598, 237 },
+	{ 20601, 183 },
+	{ 20600, 237 },
+	{ 20648, 237 },
+	{ 20570, 268 },
+	{ 20573, 290 },
+	{ 20579, 272 },
+	{ 20572, 277 },
+	{ 20578, 286 },
+	{ 20674, 279 },
+	{ 20675, 238 },
+	{ 20511, 259 },
+	{ 20583, 291 },
+	{ 20604, 264 },
+	{ 20676, 294 },
+	{ 20619, 269 },
+	{ 20628, 284 },
+	{ 20617, 295 },
+	{ 24786, 256 },
+	{ 24787, 256 },
+	{ 20672, 265 },
+	{ 20696, 265 },
+	{ 20697, 265 },
+	{ 20715, 265 },
+	{ 20711, 219 },
+	{ 20712, 219 },
+	{ 20713, 219 },
+	{ 20725, 268 },
+	{ 20726, 270 },
+	{ 20728, 219 },
+	{ 20741, 254 },
+	{ 20743, 279 },
+	{ 20752, 279 },
+	{ 20886, 243 },
+	{ 20874, 0 },
+	{ 24592, 306 },
+	{ 24634, 306 },
+	{ 24594, 278 },
+	{ 8272, 0 },
+	{ 0, 0 }
+};
+
 uint16 Mouse::giveYCood(Compact *itemData, uint32 id) {
 	// push objects that are too far to left, or to the right, back onto the screen
 	uint16 mid;
 
 	mid = itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY >> 1);
 
-	switch (id) {
-	case 4112: // cupboard door - not if open
+	if (id == 4112) {
 		if (Logic::_scriptVariables[112]) // cupb_flag
-			return  0;
+			return 0;
 		mid = 221;
-		break;
-
-	case 4113:
-		mid = 218; // sandwich
-		break;
-
-	case 4114:
-		mid = 226; // spanner
-		break;
-
-	case 4108:
-		mid = 0; // remove monitor screen
-		break;
-
-	case 4111:
-		mid = 0; // remove lazer
-		break;
-
-	case 4115:
-		mid = 0; // remove monitor screen
-		break;
-
-	case 4117:
-		mid = 0; // remove monitor screen
-		break;
-
-	case 4154:
-		mid = 0; // remove right sign
-		break;
-
-	case 12349:
-	// fall through
-	case 12347:
-	case 12358:
-		mid = TWEEKY_EXIT_ADJUST; // bellevue
-		break;
-
-	case 90:
-		mid = 208; // first room, door
-		break;
-
-	case 97:
-		mid = 216; // ledge room, door
-		break;
-
-	case 4116:
-		mid = 259; // elevator
-		break;
-
-	case 4119:
-		mid = 259; // hole
-		break;
-
-	case 4315:
-		mid = 261; // exit left from junk room
-		break;
-
-	case 4103:
-		mid = 242; // exit right from junk room
-		break;
-
-	case 4105:
-		mid = 241; // exit left from hobbins room
-		break;
-
-	case 4110:
-		mid = 230; // lathe
-		break;
-
-	case 8248:
-		mid = 222;  // walkway to security lobby
-		break;
-
-	case 8238:
-		mid = 222; // walkway to power
-		break;
-
-	case 8310:
-		mid = 222; // walkway to first room
-		break;
-
-	case 8246:
-		mid = 273; // power exit
-		break;
-
-	case 8317:
-		mid = 273; // walkway to crash
-		break;
-
-	case 8331:
-		mid = 230; // walkway to factory
-		break;
-
-	case 8341:
-		mid = 239; // factory to walkway
-		break;
-
-	case 8344:
-		mid = 282; // factory to factory 2
-		break;
-
-	case 8500:
-		mid = 197; // sensors
-		break;
-
-	case 8355:
-		mid = 255; // factory 2 to factory 3
-		break;
-
-	case 8366:
-		mid = 227; // factory 2 to storeroom
-		break;
-
-	case 8375:
-		mid = 238; // storeroom to factory 2
-		break;
-
-	case 8446:
-		mid = 247; // putty
-		break;
-
-	case 8438:
-		mid = 247; // gangway
-		break;
-
-	case 8364:
-		mid = 252; // exit
-		break;
-
-	case 8459:
-		mid = 252; // exit
-		break;
-
-	case 8256:
-		mid = 297; // exit
-		break;
-
-	// bellevue
-	case 12304:
-		mid = 252; // exit
-		break;
-
-	case 12338:
-		mid = 286; // exit
-		break;
-
-	case 12681:
-		mid = 250; // exit
-		break;
-
-	case 12370:
-		mid = 289; // exit
-		break;
-
-	case 12361:
-		mid = 267; // exit
-		break;
-
-	case 12679:
-		mid = 179; // exit
-		break;
-
-	case 12678:
-		mid = 179; // exit
-		break;
-
-	case 12677:
-		mid = 179; // exit
-		break;
-
-	case 12313:
-		mid = 284; // exit
-		break;
-
-	case 12676:
-		mid = 241; // exit
-		break;
-
-	case 12327:
-		mid = 244; // exit
-		break;
-
-	case 12315:
-		mid = 286; // exit
-		break;
-
-	case 12324:
-		mid = 308; // exit
-		break;
-
-	case 12336:
-		mid = 306; // exit
-		break;
-
-	case 12442:
-		mid = 246; // exit
-		break;
-
-	case 12447:
-		mid = 242; // exit
-		break;
-
-	case 12680:
-		mid = 179; // exit
-		break;
-
-	case 12459:
-		mid = 281; // exit
-		break;
-
-	case 12471:
-		mid = 302; // exit
-		break;
-
-	case 12399:
-		mid = 257; // exit
-		break;
-
-	case 12390:
-		mid = 264; // burke door
-		break;
-
-	case 12541:
-		mid = 264; // burke exit
-		break;
-
-	case 12630:
-		mid += 4; // slot
-		break;
-
-	case 12616:
-		mid += 4; // slot
-		break;
-
-	case 12629:
-		mid += 4; // slot
-		break;
-
-	case 12628:
-		mid += 4; // slot
-		break;
-
-	case 12627:
-		mid += 4; // slot
-		break;
-
-	case 12626:
-		mid += 4; // slot
-		break;
-
-	case 12620:
-		mid = 220; // locker
-		break;
-
-	case 12621:
-		mid = 220; // locker
-		break;
-
-	case 12622:
-		mid = 220; // locker
-		break;
-
-	case 12623:
-		mid = 220; // locker
-		break;
-
-	case 12613:
-		mid = 220; // locker
-		break;
-
-	case 12624:
-		mid = 220; // locker
-		break;
-
-	case 12631:
-		mid = 273; // exit
-		break;
-
-	case 12641:
-		mid = 290; // exit
-		break;
-
-	case 12642:
-		mid = 273; // exit
-		break;
-
-	case 12474:
-		mid = 282; // lamb door
-		break;
-
-	case 12486:
-		mid = 298; // lamb door
-		break;
-
-	// security room
-	case 8295:
-		mid = 299; // exit
-		break;
-
-	// hyde
-	case 16415:
-		mid = 261; // exit
-		break;
-
-	case 16403:
-		mid = 261; // exit
-		break;
-
-	case 16393:
-		mid = 246; // exit
-		break;
-
-	case 16487:
-		mid = 256; // exit
-		break;
-
-	case 16492:
-		mid = 287; // exit
-		break;
-
-	case 16394:
-		mid = 313; // exit
-		break;
-
-	case 16412:
-		mid = 276; // exit
-		break;
-
-	case 16428:
-		mid = 233; // exit
-		break;
-
-	case 16424:
-		mid = 236; // exit
-		break;
-
-	// cathedral
-	case 16462:
-		mid = 296; // exit
-		break;
-
-	case 16464:
-		mid = 250; // exit
-		break;
-
-	case 16465:
-		mid = 226; // exit
-		break;
-
-	case 16474:
-		mid = 263; // exit
-		break;
-
-	case 16576:
-		mid = 229; // body == 16569
-		break;
-
-	case 16577:
-		mid = 229; // body == 16570
-		break;
-
-	case 16578:
-		mid = 229; // body == 16571
-		break;
-
-	case 16579:
-		mid = 229; // body == 16572
-		break;
-
-	case 16580:
-		mid = 229; // body == 16573
-		break;
-
-	// reactor
-	case 8478:
-		mid = 291; // exit
-		break;
-
-	case 8481:
-		mid = 253; // exit
-		break;
-
-	case 8511:
-		mid = 271; // exit
-		break;
-
-	// club
-	case 16538:
-		mid = 279; // exit
-		break;
-
-	// abandoned subway
-	case 16439:
-		mid = 267; // exit
-		break;
-
-	// entrance to underworld
-	case 16592:
-		mid = 267; // exit
-		break;
-
-	// underworld
-	case 16649:
-		mid = 291; // exit
-		break;
-
-	case 16660:
-		mid = 285; // exit
-		break;
-
-	case 16662:
-		mid = 254; // exit
-		break;
-
-	case 16661:
-		mid = 291; // exit
-		break;
-
-	case 16671:
-		mid = 291; // exit
-		break;
-
-	case 16681:
-		mid = 282; // exit
-		break;
-
-	case 16682:
-		mid = 282; // exit
-		break;
-
-	case 16719:
-		mid = 287; // exit
-		break;
-
-	case 16720:
-		mid = 287; // exit
-		break;
-
-	case 16729:
-		mid = 291; // exit
-		break;
-
-	case 16730:
-		mid = 301; // exit
-		break;
-
-	case 20506:
-		mid = 276; // metal door
-		break;
-
-	// underworld main
-	case 20518:
-		mid = 276; // metal door
-		break;
-
-	case 20532:
-		mid = 264; // exit
-		break;
-
-	case 20558:
-		mid = 296; // exit
-		break;
-
-	case 20598:
-		mid = 237; // exit
-		break;
-
-	case 20601:
-		mid = 183; // metal bar
-		break;
-
-	case 20600:
-		mid = 237; // cover
-		break;
-
-	case 20648:
-		mid = 237; // pit
-		break;
-
-	case 20570:
-		mid = 268; // exit to medical droid room
-		break;
-
-	case 20573:
-		mid = 290; // droid room exit
-		break;
-
-	case 20579:
-		mid = 272; // droid room exit
-		break;
-
-	case 20572:
-		mid = 277; // droid room exit
-		break;
-
-	case 20578:
-		mid = 286; // console
-		break;
-
-	case 20674:
-		mid = 279; // droid room exit
-		break;
-
-	case 20675:
-		mid = 238; // robot
-		break;
-
-	case 20511:
-		mid = 259; // slot
-		break;
-
-	case 20583:
-		mid = 291; // tank room exit
-		break;
-
-	case 20604:
-		mid = 264; // tank room exit
-		break;
-
-	case 20676:
-		mid = 294; // exit
-		break;
-
-	case 20619:
-		mid = 269; // exit
-		break;
-
-	case 20628:
-		mid = 284; // exit
-		break;
-
-	case 20617:
-		mid = 295; // exit
-		break;
-
-	case 24786:
-		mid = 256; // linc crystal
-		break;
-
-	case 24787:
-		mid = 256; // linc crystal
-		break;
-
-	case 20672:
-		mid = 265; // android room exit
-		break;
-
-	case 20696:
-		mid = 265; // android room exit
-		break;
-
-	case 20697:
-		mid = 265; // android room exit
-		break;
-
-	case 20715:
-		mid = 265; // android room exit
-		break;
-
-	case 20711:
-		mid = 219; // console
-		break;
-
-	case 20712:
-		mid = 219; // console
-		break;
-
-	case 20713:
-		mid = 219; // console
-		break;
-
-	case 20725:
-		mid = 268; // exit
-		break;
-
-	case 20726:
-		mid = 270; // exit from door room
-		break;
-
-	case 20728:
-		mid = 219; // exit from door room
-		break;
-
-	case 20741:
-		mid = 254; // exit from first vein room
-		break;
-
-	case 20743:
-		mid = 279; // exit from first vein room
-		break;
-
-	case 20752:
-		mid = 279; // exit near end
-		break;
-
-	case 20886:
-		mid = 243; // exit orifice to linc
-		break;
-
-	case 20874:
-		mid = 0; // pipe support - removed as appears to have no interaction
-		break;
-
-	// linc
-	case 24592:
-		mid = 306; // maze mid-bot
-		break;
+	}
 
-	case 24634:
-		mid = 306; // maze mid-bot
-		break;
+	if (id == 12630 || id == 12616 || id == 12629 || id == 12628 || id == 12627 || id == 12626) // slot
+		mid += 4;
 
-	case 24594:
-		mid = 278; // maze left-mid
-		break;
-
-	case 8272:
-		mid = 0; // REMOVE power room chair
-		break;
-
-	case 8290:
-	case 8291: // power room switches
+	if (id == 8291 || id == 8290) { // power room switched
 		if (!Logic::_scriptVariables[429])
-			return  0;
+			return 0;
+	}
+
+	if (!_yMapInitialized) {
+		for (MouseYMap *m = mouseYMap; m->id != 0; m++)
+			_hotspotYMap[m->id] = m->mid;
+		_yMapInitialized = true;
 	}
 
+	if (_hotspotYMap.contains(id))
+		return _hotspotYMap[id];
+
 	return mid;
 }
 
diff --git a/engines/sky/mouse.h b/engines/sky/mouse.h
index 3a56c721e4e..8dd4e46a404 100644
--- a/engines/sky/mouse.h
+++ b/engines/sky/mouse.h
@@ -66,7 +66,7 @@ namespace Sky {
 #define USE_ON_DIST 40
 
 // fix super deep exits
-#define TWEEKY_EXIT_ADJUST (FULL_SCREEN_HEIGHT + TOP_LEFT_Y - 40);
+#define TWEEKY_EXIT_ADJUST (FULL_SCREEN_HEIGHT + TOP_LEFT_Y - 40)
 
 
 // inv item sizes
@@ -196,7 +196,9 @@ protected:
 	int _proxFrameSpeed;
 
 	Common::HashMap<int, int> _hotspotXMap;
-	bool _mapInitialized = false;
+	Common::HashMap<int, int> _hotspotYMap;
+	bool _xMapInitialized = false;
+	bool _yMapInitialized = false;
 
 	static uint32 _mouseMainObjects[24];
 	static uint32 _mouseLincObjects[21];


Commit: d2523dae9669781edc00755c69e93b7b801c8ab1
    https://github.com/scummvm/scummvm/commit/d2523dae9669781edc00755c69e93b7b801c8ab1
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Fix formatting

Changed paths:
    engines/sky/inventory.cpp


diff --git a/engines/sky/inventory.cpp b/engines/sky/inventory.cpp
index b8087185a76..ab8321994f5 100644
--- a/engines/sky/inventory.cpp
+++ b/engines/sky/inventory.cpp
@@ -30,51 +30,15 @@
 namespace Sky {
 
 const int invIconId[NUM_INV_ANIMS + 1] = {
-	2304,
-	3201,
-	3203,
-	3205,
-	3207,
-	3209,
-	3211,
-	4672,
-	4674,
-	5568,
-	5570,
-	12225,
-	12227,
-	12229,
-	12231,
-	12233,
-	12235,
-	12237,
-	12239,
-	12241,
-	12243,
-	12245,
-	12247,
-	12249,
-	12251,
-	12253,
-	12255,
-	12257,
-	16768,
-	16832,
-	16896,
-	16960,
-	17024,
-	17088,
-	17152,
-	17154,
-	17156,
-	17158,
-	17160,
-	17162,
-	17164,
-	17216,
-	17344,
-	17408,
-	-1,
+	2304,  3201,  3203,  3205,  3207,
+	3209,  3211,  4672,  4674,  5568,
+	5570, 12225, 12227, 12229, 12231,
+	12233, 12235, 12237, 12239, 12241,
+	12243, 12245, 12247, 12249, 12251,
+	12253, 12255, 12257, 16768, 16832,
+	16896, 16960, 17024, 17088, 17152,
+	17154, 17156, 17158, 17160, 17162,
+	17164, 17216, 17344, 17408,  -1,
 };
 
 void Screen::addInvIcon(int frame, int x, int y, bool highlighted) {


Commit: a22163d14e5f9b6401773149bbeec0bdd8655906
    https://github.com/scummvm/scummvm/commit/a22163d14e5f9b6401773149bbeec0bdd8655906
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Implement clicking for inventory icon

Changed paths:
    engines/sky/logic.cpp
    engines/sky/mouse.cpp
    engines/sky/mouse.h


diff --git a/engines/sky/logic.cpp b/engines/sky/logic.cpp
index 673279b977c..b9187defbe8 100644
--- a/engines/sky/logic.cpp
+++ b/engines/sky/logic.cpp
@@ -1948,6 +1948,9 @@ bool Logic::fnStartMenu(uint32 firstObject, uint32 b, uint32 c) {
 				didX++;
 		}
 
+		_skyMouse->setInvDims(TOP_LEFT_X + XWIDTH, 236, didX * XWIDTH, didY * YDEPTH);
+		_skyScreen->showInventory(XWIDTH, 236 - TOP_LEFT_Y, XWIDTH + 8 * XWIDTH, (236 - TOP_LEFT_Y) + (didY * YDEPTH));
+
 		return true;
 
 	}
diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index 7b7cf3d1246..dd64e6e1ee5 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -1714,10 +1714,20 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 
 void Mouse::invMouse(uint16 xPos, uint16 yPos) {
 
+	uint32 *objList;
 	Compact *itemData;
+	int j, num;
+
+	debug(1, "xPos = %d, yPos = %d, _invX = %d, _invY = %d, _invW = %d, _invH = %d", xPos, yPos, _invX, _invY, _invW, _invH);
+
+	bool buttonHeld = (_system->getEventManager()->getButtonState() != 0); // mouseEngine() consumes the click at the end so using _mouseB would increment the timer at each click not on hold
+
+	objList = _skyLogic->giveInvList();
+
+	num = (int)Logic::_scriptVariables[MENU_LENGTH];
 
 	// if clicked somewhere outside the inventory, close the inventory
-	if (!_touchId && _mouseB) {
+	if (!_touchId && buttonHeld) {
 		if (xPos < _invX || xPos > _invX + _invW || yPos < _invY || yPos > _invY + _invH) {
 
 			_mMode = MUST_RELEASE; // MUST_RELEASE because if we go straight to GAMEPLAY, robert will move to the place of clicking
@@ -1726,6 +1736,60 @@ void Mouse::invMouse(uint16 xPos, uint16 yPos) {
 		}
 	}
 
+	if (buttonHeld) {
+		for (j = 0; j < num; j++) {
+			itemData = _skyCompact->fetchCpt(objList[j]);
+
+			if (itemData->xcood + (int16)itemData->mouseRelX > xPos)
+				continue;
+			if (itemData->xcood + (int16)itemData->mouseRelX + XWIDTH < xPos)
+				continue;
+			if (itemData->ycood + (int16)itemData->mouseRelY > yPos)
+				continue;
+			if (itemData->ycood + (int16)itemData->mouseRelY + YDEPTH < yPos)
+				continue;
+
+			// record what we are touching
+			Logic::_scriptVariables[SPECIAL_ITEM] = objList[j];
+
+			// if we are on an object that is different from the object we were over just a moment ago
+			if (_touchId != objList[j] && !_holding) {
+				debug(1, "Entered the if block");
+				if (Logic::_scriptVariables[GET_OFF])
+					_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], itemData);
+
+				// update GET_OFF
+				Logic::_scriptVariables[GET_OFF] = itemData->mouseOff;
+
+				_touchId = objList[j];
+				_hoverId = objList[j];
+				// run the mouseOn script
+				_skyLogic->mouseScript(itemData->mouseOn, itemData);
+				// reset hold counter
+				_timeOn = 0;
+				_skyLogic->startInventory(_touchId);
+			} else {
+				// holding
+				_timeOn++;
+				debug(1, "Holding item - %d, timer - %d", _touchId, _timeOn);
+
+				// if held long enough
+				if (_timeOn == USEON_THRESHOLD) {
+					debug(1, "Threshold crossed");
+					_skyScreen->setDragIcon(itemData->frame, true);
+
+					// hold the item
+					Logic::_scriptVariables[OBJECT_HELD] = _touchId;
+
+					_mouseYOff = HOTSPOT_USE_ON_YOFF;
+
+					_holding = true;
+				}
+			}
+			return;
+		}
+	}
+
 	// reset
 	if (Logic::_scriptVariables[GET_OFF]) {
 		_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], itemData);
diff --git a/engines/sky/mouse.h b/engines/sky/mouse.h
index 8dd4e46a404..37e04eeada8 100644
--- a/engines/sky/mouse.h
+++ b/engines/sky/mouse.h
@@ -114,6 +114,12 @@ public:
 	bool wasClicked();
 	void logicClick() { _logicClick = true; }
 	void resetCursor();
+	void setInvDims(uint16 x, uint16 y, uint16 w, uint16 h) {
+		_invX = x;
+		_invY = y;
+		_invW = w;
+		_invH = h;
+	}
 	bool isUILive();
 	void resetUI();
 	OSystem *giveSystem(){


Commit: 923dbca07dab7dc27bfbff1e697aa92585ae3a8a
    https://github.com/scummvm/scummvm/commit/923dbca07dab7dc27bfbff1e697aa92585ae3a8a
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Convert control panel to 32 bit before outputting

Changed paths:
    engines/sky/control.cpp
    engines/sky/screen.cpp
    engines/sky/screen.h


diff --git a/engines/sky/control.cpp b/engines/sky/control.cpp
index f854b9f42d4..f5d0a7377a8 100644
--- a/engines/sky/control.cpp
+++ b/engines/sky/control.cpp
@@ -91,7 +91,6 @@ void ConResource::drawToScreen(bool doMask) {
 			spriteData += _spriteData->s_width;
 		}
 	}
-	_system->copyRectToScreen(updatePos, GAME_SCREEN_WIDTH, _x, _y, _spriteData->s_width, _spriteData->s_height);
 }
 
 TextResource::TextResource(void *pSpData, uint32 pNSprites, uint32 pCurSprite, uint16 pX, uint16 pY, uint32 pText, uint8 pOnClick, OSystem *system, uint8 *screen) :
@@ -129,7 +128,6 @@ void TextResource::drawToScreen(bool doMask) {
 			cpHeight = PAN_CHAR_HEIGHT;
 		for (cnty = 0; cnty < cpHeight; cnty++)
 			memcpy(_screen + (cnty + _oldY) * GAME_SCREEN_WIDTH + _oldX, _oldScreen + cnty * PAN_LINE_WIDTH, cpWidth);
-		_system->copyRectToScreen(_screen + _oldY * GAME_SCREEN_WIDTH + _oldX, GAME_SCREEN_WIDTH, _oldX, _oldY, cpWidth, PAN_CHAR_HEIGHT);
 	}
 	if (!_spriteData) {
 		_oldX = GAME_SCREEN_WIDTH;
@@ -153,7 +151,6 @@ void TextResource::drawToScreen(bool doMask) {
 		copyDest += PAN_LINE_WIDTH;
 		screenPos += GAME_SCREEN_WIDTH;
 	}
-	_system->copyRectToScreen(_screen + _y * GAME_SCREEN_WIDTH + _x, GAME_SCREEN_WIDTH, _x, _y, cpWidth, cpHeight);
 }
 
 ControlStatus::ControlStatus(Text *skyText, OSystem *system, uint8 *scrBuf) {
@@ -519,6 +516,7 @@ void Control::doControlPanel() {
 
 	while (!quitPanel && !Engine::shouldQuit()) {
 		_text->drawToScreen(WITH_MASK);
+		_skyScreen->renderControlPanel(_screenBuf);
 		_system->updateScreen();
 		_mouseClicked = false;
 		delay(ANIM_DELAY);
@@ -934,6 +932,7 @@ uint16 Control::saveRestorePanel(bool allowSave) {
 		}
 
 		_text->drawToScreen(WITH_MASK);
+		_skyScreen->renderControlPanel(_screenBuf);
 		_system->updateScreen();
 		_mouseClicked = false;
 		delay(ANIM_DELAY);
diff --git a/engines/sky/screen.cpp b/engines/sky/screen.cpp
index a5e54b22df6..26e273ef2ec 100644
--- a/engines/sky/screen.cpp
+++ b/engines/sky/screen.cpp
@@ -251,15 +251,15 @@ Screen::~Screen() {
 	_iconSurface.free();
 }
 
-void Screen::update32BitScreen() {
-	if (!_currentScreen)
+void Screen::update32BitScreen(uint8 *overrideBuffer) {
+	if (!overrideBuffer)
 		return;
 
 	uint32 *dstPixels = (uint32 *)_screen32.getPixels();
 	uint32 dstPitch = _screen32.pitch / 4;
 
 	for (int y = 0; y < GAME_SCREEN_HEIGHT; y++) {
-		uint8 *srcRow = _currentScreen + (y * GAME_SCREEN_WIDTH);
+		uint8 *srcRow = overrideBuffer + (y * GAME_SCREEN_WIDTH);
 		uint32 *dstRow = dstPixels + (y * dstPitch);
 
 		for (int x = 0; x < GAME_SCREEN_WIDTH; x++) {
@@ -275,7 +275,7 @@ void Screen::update32BitScreen() {
 }
 
 void Screen::renderFinalFrame() {
-	update32BitScreen();
+	update32BitScreen(_currentScreen);
 
 	if (SkyEngine::isIbass()) {
 
@@ -291,6 +291,13 @@ void Screen::renderFinalFrame() {
 	}
 }
 
+void Screen::renderControlPanel(uint8 *buffer) {
+	update32BitScreen(buffer);
+
+	if (_screen32.getPixels())
+		_system->copyRectToScreen(_screen32.getPixels(), _screen32.pitch, 0, 0, _screen32.w, _screen32.h);
+}
+
 void Screen::clearScreen(bool fullscreen) {
 	if (!_currentScreen)
 		_currentScreen = (uint8 *)malloc(FULL_SCREEN_WIDTH * FULL_SCREEN_HEIGHT);
diff --git a/engines/sky/screen.h b/engines/sky/screen.h
index cada7044b37..6c740cb07d2 100644
--- a/engines/sky/screen.h
+++ b/engines/sky/screen.h
@@ -119,7 +119,8 @@ public:
 	Graphics::Surface _screen32;
 	Graphics::Surface _iconSurface;
 	void renderFinalFrame();
-	void update32BitScreen();
+	void renderControlPanel(uint8 *buffer);
+	void update32BitScreen(uint8 *overrideBuffer);
 	Icon _uiIcon[NUM_UI_ICONS];
 	Icon _proximityIcon[NUM_PROXIMITY_ICONS];
 	Icon _invIcon[NUM_INV_ICONS];


Commit: bb5125236b5400f370e65243480e2800a8c7c2db
    https://github.com/scummvm/scummvm/commit/bb5125236b5400f370e65243480e2800a8c7c2db
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Implement inventory item's examining in ibass

Changed paths:
    engines/sky/mouse.cpp


diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index dd64e6e1ee5..8221aa41df1 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -1790,6 +1790,27 @@ void Mouse::invMouse(uint16 xPos, uint16 yPos) {
 		}
 	}
 
+	// made a quick click and release
+	if (!buttonHeld && _touchId && _timeOn < CLICK_THRESHOLD) {
+		Logic::_scriptVariables[BUTTON] = 2;
+		Logic::_scriptVariables[SPECIAL_ITEM] = _touchId;
+
+		itemData = _skyCompact->fetchCpt(_touchId);
+
+		uint16 tempY = itemData->ycood;
+		pushInvY(tempY);
+		itemData->ycood = 136;
+
+		_mMode = INV_TEMP_EXAMINE;
+
+		_skyLogic->mouseScript(itemData->mouseClick, itemData);
+
+		_mMode = INVENTORY;
+
+		_skyScreen->clearDragIcon();
+		_skyLogic->startInventory();
+	}
+
 	// reset
 	if (Logic::_scriptVariables[GET_OFF]) {
 		_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], itemData);


Commit: 53b3d8b64d64f0dcc91e7984d9110bafb7b7df09
    https://github.com/scummvm/scummvm/commit/53b3d8b64d64f0dcc91e7984d9110bafb7b7df09
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Port invMouse hover logic

Changed paths:
    engines/sky/mouse.cpp


diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index 8221aa41df1..a3119e698a9 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -1717,6 +1717,7 @@ void Mouse::invMouse(uint16 xPos, uint16 yPos) {
 	uint32 *objList;
 	Compact *itemData;
 	int j, num;
+	bool touched = false;
 
 	debug(1, "xPos = %d, yPos = %d, _invX = %d, _invY = %d, _invW = %d, _invH = %d", xPos, yPos, _invX, _invY, _invW, _invH);
 
@@ -1726,14 +1727,104 @@ void Mouse::invMouse(uint16 xPos, uint16 yPos) {
 
 	num = (int)Logic::_scriptVariables[MENU_LENGTH];
 
-	// if clicked somewhere outside the inventory, close the inventory
-	if (!_touchId && buttonHeld) {
-		if (xPos < _invX || xPos > _invX + _invW || yPos < _invY || yPos > _invY + _invH) {
+	// held for more than the threshold time
+	if (_holding) {
+		debug(1, "Holding an object");
 
-			_mMode = MUST_RELEASE; // MUST_RELEASE because if we go straight to GAMEPLAY, robert will move to the place of clicking
-			_skyLogic->killInventory(); // stop rendering the inventory items
+		// if moved(i.e., taken out of the item's original dimension)
+		if (xPos < _invX || yPos < _invY || xPos > _invX + _invW || yPos > _invY + _invH) {
+
+			// for invUseOn() to drag object around the screen
+			_mMode = INVENTORY_USE_ON;
+
+			// remove all the inv items from the screen when one is being dragged
+			_skyLogic->killInventory();
+
+			_touchId = 0;
+			_skyScreen->setDragIconHighlight(false);
+
+			return;
+		}
+
+		// still holding the button, just update the hover text for the item it is dragging over and stop
+		if (buttonHeld) {
+			for (j = 0; j < num; j++) {
+				itemData = _skyCompact->fetchCpt(objList[j]);
+				debug("itemData->xcood = %d, itemData->mouseRelX = %d, itemData->ycood = %d, itemData->mouseRelY = %d", itemData->xcood, itemData->mouseRelX, itemData->ycood, itemData->mouseRelY);
+
+				if (itemData->xcood + (uint16)itemData->mouseRelX > xPos)
+					continue;
+				if (itemData->xcood + (uint16)itemData->mouseRelX + XWIDTH < xPos)
+					continue;
+				if (itemData->ycood + (uint16)itemData->mouseRelY > yPos)
+					continue;
+				if (itemData->ycood + (uint16)itemData->mouseRelY + YDEPTH < yPos)
+					continue;
+
+				touched = true;
+
+				if (_hoverId == objList[j]) // still on previous
+					continue;
+
+				// run previous item's GET_OFF, if there was one
+				if (Logic::_scriptVariables[GET_OFF])
+					_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], _skyCompact->fetchCpt(_hoverId));
+
+				Logic::_scriptVariables[GET_OFF] = itemData->mouseOff;
+				_hoverId = objList[j];
+
+				// run the mouseOn script
+				if (itemData->mouseOn) {
+					uint16 tempY = itemData->ycood;
+					itemData->ycood = 136;
+					Logic::_scriptVariables[BUTTON] = 2;
+
+					// record what we are touching
+					Logic::_scriptVariables[SPECIAL_ITEM] = _hoverId;
+					_skyLogic->mouseScript(itemData->mouseOn, itemData);
+
+					// reset the render position to original
+					itemData->ycood = tempY;
+				}
+
+				_skyLogic->startInventory(_hoverId);
+			}
+			if (!touched) {
+				// touching nothin
+				_hoverId = 0;
+				if (Logic::_scriptVariables[GET_OFF]) {
+					_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], _skyCompact->fetchCpt(_hoverId));
+					Logic::_scriptVariables[GET_OFF] = 0;
+				}
+			}
 			return;
 		}
+
+		// dropped on another item
+		// fetch the compact
+		itemData = _skyCompact->fetchCpt(_touchId);
+		// cancel cursor
+		Logic::_scriptVariables[OBJECT_HELD] = 0;
+
+		// check for the actual two objects that can combine like touhchId == 37 and hoverId == 74 etc.
+		if ((_touchId == 74 && _hoverId == 37) || (_touchId == 37 && _hoverId == 74)) {
+			Logic::_scriptVariables[83] = 0;
+			Logic::_scriptVariables[89] = 0;
+			Logic::_scriptVariables[90] = 39;
+			debug(1, "Combined");
+
+			_skyLogic->killInventory();
+			_skyLogic->startInventory();
+
+			_touchId = 0;
+		} else {
+			// dropping on an item that can't combine
+			_touchId = 0;
+			debug(1, "Using on invalid item");
+		}
+
+		_skyScreen->clearDragIcon();
+		_skyLogic->startInventory();
 	}
 
 	if (buttonHeld) {
@@ -1811,6 +1902,19 @@ void Mouse::invMouse(uint16 xPos, uint16 yPos) {
 		_skyLogic->startInventory();
 	}
 
+	// if clicked somewhere outside the inventory, close the inventory
+	if (!_touchId && buttonHeld) {
+		if (xPos < _invX || xPos > _invX + _invW || yPos < _invY || yPos > _invY + _invH) {
+
+			_mMode = MUST_RELEASE; // MUST_RELEASE because if we go straight to GAMEPLAY, robert will move to the place of clicking
+			_skyLogic->killInventory(); // stop rendering the inventory items
+			return;
+		}
+	}
+
+	_holding = false;
+	_touchId = false;
+
 	// reset
 	if (Logic::_scriptVariables[GET_OFF]) {
 		_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], itemData);


Commit: 7547e56db8151e154917120fcc682df87df2b292
    https://github.com/scummvm/scummvm/commit/7547e56db8151e154917120fcc682df87df2b292
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Make og BASS run in 8bpp mode, some fixes in control panel and a lot of refactoring overall

Changed paths:
    engines/sky/control.cpp
    engines/sky/inventory.cpp
    engines/sky/logic.cpp
    engines/sky/mouse.cpp
    engines/sky/mouse.h
    engines/sky/screen.cpp
    engines/sky/sky.cpp


diff --git a/engines/sky/control.cpp b/engines/sky/control.cpp
index f5d0a7377a8..bcb3d68a7eb 100644
--- a/engines/sky/control.cpp
+++ b/engines/sky/control.cpp
@@ -407,7 +407,6 @@ void Control::drawCross(uint16 x, uint16 y) {
 		crossPos += CROSS_SZ_X;
 	}
 	bufPos = _screenBuf + y * GAME_SCREEN_WIDTH + x;
-	_system->copyRectToScreen(bufPos, GAME_SCREEN_WIDTH, x, y, CROSS_SZ_X, CROSS_SZ_Y);
 	_text->drawToScreen(WITH_MASK);
 }
 
@@ -417,6 +416,7 @@ void Control::animClick(ConResource *pButton) {
 		_text->flushForRedraw();
 		pButton->drawToScreen(NO_MASK);
 		_text->drawToScreen(WITH_MASK);
+		_skyScreen->renderControlPanel(_screenBuf);
 		_system->updateScreen();
 		delay(CLICK_DELAY);
 		if (!_controlPanel)
@@ -425,13 +425,13 @@ void Control::animClick(ConResource *pButton) {
 		_text->flushForRedraw();
 		pButton->drawToScreen(NO_MASK);
 		_text->drawToScreen(WITH_MASK);
+		_skyScreen->renderControlPanel(_screenBuf);
 		_system->updateScreen();
 	}
 }
 
 void Control::drawMainPanel() {
 	memset(_screenBuf, 0, GAME_SCREEN_WIDTH * FULL_SCREEN_HEIGHT);
-	_system->copyRectToScreen(_screenBuf, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, FULL_SCREEN_HEIGHT);
 	if (_controlPanel)
 		_controlPanel->drawToScreen(NO_MASK);
 	_exitButton->drawToScreen(NO_MASK);
@@ -470,7 +470,7 @@ void Control::doLoadSavePanel() {
 	saveRestorePanel(false);
 
 	memset(_screenBuf, 0, GAME_SCREEN_WIDTH * FULL_SCREEN_HEIGHT);
-	_system->copyRectToScreen(_screenBuf, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, FULL_SCREEN_HEIGHT);
+	_skyScreen->renderControlPanel(_screenBuf);
 	_system->updateScreen();
 	_skyScreen->forceRefresh();
 	_skyScreen->setPaletteEndian((uint8 *)_skyCompact->fetchCpt(SkyEngine::_systemVars->currentPalette));
@@ -550,7 +550,7 @@ void Control::doControlPanel() {
 			buttonControl(NULL);
 	}
 	memset(_screenBuf, 0, GAME_SCREEN_WIDTH * FULL_SCREEN_HEIGHT);
-	_system->copyRectToScreen(_screenBuf, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, FULL_SCREEN_HEIGHT);
+	_skyScreen->renderControlPanel(_screenBuf);
 	if (!Engine::shouldQuit())
 		_system->updateScreen();
 	_skyScreen->forceRefresh();
@@ -670,6 +670,7 @@ bool Control::getYesNo(char *text, uint bufSize) {
 			mouseType = wantMouse;
 			_skyMouse->spriteMouse(mouseType, 0, 0);
 		}
+		_skyScreen->renderControlPanel(_screenBuf);
 		_system->updateScreen();
 		delay(ANIM_DELAY);
 		if (!_controlPanel) {
@@ -729,6 +730,7 @@ uint16 Control::doMusicSlide() {
 		}
 		buttonControl(_slide2);
 		_text->drawToScreen(WITH_MASK);
+		_skyScreen->renderControlPanel(_screenBuf);
 		_system->updateScreen();
 	}
 	return 0;
@@ -760,6 +762,7 @@ uint16 Control::doSpeedSlide() {
 		}
 		buttonControl(_slide);
 		_text->drawToScreen(WITH_MASK);
+		_skyScreen->renderControlPanel(_screenBuf);
 		_system->updateScreen();
 	}
 	SkyEngine::_systemVars->gameSpeed = speedDelay;
@@ -779,6 +782,7 @@ void Control::toggleFx(ConResource *pButton) {
 	ConfMan.setBool("sfx_mute", (SkyEngine::_systemVars->systemFlags & SF_FX_OFF) != 0);
 
 	pButton->drawToScreen(WITH_MASK);
+	_skyScreen->renderControlPanel(_screenBuf);
 	_system->updateScreen();
 }
 
@@ -804,6 +808,7 @@ uint16 Control::toggleText() {
 
 	drawTextCross(flags);
 
+	_skyScreen->renderControlPanel(_screenBuf);
 	_system->updateScreen();
 	return TOGGLED;
 }
@@ -823,6 +828,7 @@ void Control::toggleMusic(ConResource *pButton) {
 	ConfMan.setBool("music_mute", (SkyEngine::_systemVars->systemFlags & SF_MUS_OFF) != 0);
 
 	pButton->drawToScreen(WITH_MASK);
+	_skyScreen->renderControlPanel(_screenBuf);
 	_system->updateScreen();
 }
 
@@ -1110,7 +1116,6 @@ void Control::showSprites(DataFileHeader **nameSprites, bool allowSave) {
 				drawResource->setXY(GAME_NAME_X + _enteredTextWidth + 1, GAME_NAME_Y + cnt * PAN_CHAR_HEIGHT + 4);
 				drawResource->drawToScreen(WITH_MASK);
 			}
-			_system->copyRectToScreen(_screenBuf + (GAME_NAME_Y + cnt * PAN_CHAR_HEIGHT) * GAME_SCREEN_WIDTH + GAME_NAME_X, GAME_SCREEN_WIDTH, GAME_NAME_X, GAME_NAME_Y + cnt * PAN_CHAR_HEIGHT, PAN_LINE_WIDTH, PAN_CHAR_HEIGHT);
 		} else
 			drawResource->drawToScreen(NO_MASK);
 	}
@@ -1507,7 +1512,7 @@ uint16 Control::quickXRestore(uint16 slot) {
 	_savedCharSet = _skyText->giveCurrentCharSet();
 	_skyText->fnSetFont(2);
 
-	_system->copyRectToScreen(_screenBuf, GAME_SCREEN_WIDTH, 0, 0, FULL_SCREEN_WIDTH, FULL_SCREEN_HEIGHT);
+	_skyScreen->renderControlPanel(_screenBuf);
 	_system->updateScreen();
 
 	if (SkyEngine::_systemVars->gameVersion < 331)
@@ -1531,7 +1536,7 @@ uint16 Control::quickXRestore(uint16 slot) {
 		_skyScreen->setPaletteEndian((uint8 *)_skyCompact->fetchCpt(SkyEngine::_systemVars->currentPalette));
 	} else {
 		memset(_screenBuf, 0, FULL_SCREEN_WIDTH * FULL_SCREEN_HEIGHT);
-		_system->copyRectToScreen(_screenBuf, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, FULL_SCREEN_HEIGHT);
+		_skyScreen->renderControlPanel(_screenBuf);
 		_system->updateScreen();
 		_skyScreen->showScreen(_skyScreen->giveCurrent());
 		_skyScreen->setPalette(60111);
diff --git a/engines/sky/inventory.cpp b/engines/sky/inventory.cpp
index ab8321994f5..689a67d328c 100644
--- a/engines/sky/inventory.cpp
+++ b/engines/sky/inventory.cpp
@@ -65,7 +65,6 @@ void Screen::hideInventory() {
 }
 
 void Screen::clearAllInvIcons() {
-
 	for (int i = 0; i < NUM_INV_ICONS; i++)
 		_invIcon[i]._visible = false;
 
@@ -82,7 +81,7 @@ int Screen::getInventoryAnimIdx(int frame) {
 	return 0; // fallback
 }
 
-void Logic::startInventory(uint32	highlightedId) {
+void Logic::startInventory(uint32 highlightedId) {
 	// normal gameplay inv
 	fnStartMenu(Logic::_scriptVariables[FIRST_ICON], highlightedId, 0);
 }
diff --git a/engines/sky/logic.cpp b/engines/sky/logic.cpp
index b9187defbe8..0936b2f613e 100644
--- a/engines/sky/logic.cpp
+++ b/engines/sky/logic.cpp
@@ -1952,7 +1952,6 @@ bool Logic::fnStartMenu(uint32 firstObject, uint32 b, uint32 c) {
 		_skyScreen->showInventory(XWIDTH, 236 - TOP_LEFT_Y, XWIDTH + 8 * XWIDTH, (236 - TOP_LEFT_Y) + (didY * YDEPTH));
 
 		return true;
-
 	}
 
 	uint i;
diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index a3119e698a9..6574bd5d418 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -109,9 +109,6 @@ Mouse::Mouse(OSystem *system, Disk *skyDisk, SkyCompact *skyCompact, Screen *sky
 
 	_proxFrame = 0;
 	_proxFrameSpeed = 0;
-
-	_xMapInitialized = false;
-
 	resetUI();
 }
 
@@ -268,61 +265,6 @@ bool Mouse::isUILive() {
 void Mouse::mouseEngine() {
 	_logicClick = (_mouseB > 0); // click signal is available for Logic for one gamecycle
 
-	if (SkyEngine::isIbass()) {
-		if (_actionFlash) {
-			_actionFlashTime--;
-			if (!_actionFlashTime)
-				_actionFlash = false;
-
-			if (!(_actionFlashTime & 1))
-				_skyScreen->clearIbassIcon(_actionFlashIcon, false);
-			else
-				_skyScreen->setIcon(_actionFlashIcon, _actionFlashX, _actionFlashY);
-		}
-
-		switch (_mMode) {
-		case ALERT_TO_GAME:
-			if (!_mouseB)
-				return;
-
-			_skyScreen->hideInventory();
-			_mMode = MUST_RELEASE;
-			break;
-
-		case MUST_RELEASE:
-			if (_mouseB)
-				return;
-
-			resetUI();
-			_mMode = GAMEPLAY;
-			break;
-
-		case GAMEPLAY:
-			pointerEngine(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
-			break;
-
-		case PRE_INVENTORY:
-			if (_mouseB)
-				return;
-
-			_mMode = INVENTORY;
-			break;
-
-		case INVENTORY:
-			if (isLincInv())
-				lincInvMouse(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
-			else
-				invMouse(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
-
-		case INVENTORY_USE_ON:
-		case TEXT_CHOOSER:
-			break;
-		}
-
-		_mouseB = 0;
-		return;
-	}
-
 	if (!Logic::_scriptVariables[MOUSE_STOP]) {
 		if (Logic::_scriptVariables[MOUSE_STATUS] & (1 << 1)) {
 			pointerEngine(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
@@ -333,6 +275,57 @@ void Mouse::mouseEngine() {
 	_mouseB = 0;	//don't save up buttons
 }
 
+void Mouse::mouseEngineIBASS() {
+	_logicClick = (_mouseB > 0);
+
+	if (_actionFlash) {
+		_actionFlashTime--;
+		if (!_actionFlashTime)
+			_actionFlash = false;
+
+		if (!(_actionFlashTime & 1))
+			_skyScreen->clearIbassIcon(_actionFlashIcon, false);
+		else
+			_skyScreen->setIcon(_actionFlashIcon, _actionFlashX, _actionFlashY);
+	}
+
+	switch (_mMode) {
+	case ALERT_TO_GAME:
+		if (!_mouseB)
+			return;
+
+		_skyScreen->hideInventory();
+		_mMode = MUST_RELEASE;
+		break;
+	case MUST_RELEASE:
+		if (_mouseB)
+			return;
+		resetUI();
+		_mMode = GAMEPLAY;
+		break;
+	case GAMEPLAY:
+		pointerEngineIBASS(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
+		break;
+	case PRE_INVENTORY:
+		if (_mouseB)
+			return;
+
+		_mMode = INVENTORY;
+		break;
+	case INVENTORY:
+		if (isLincInv())
+			lincInvMouse(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
+		else
+			invMouse(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
+		break;
+	case INVENTORY_USE_ON:
+	case TEXT_CHOOSER:
+		break;
+	}
+	_mouseB = 0;
+	return;
+}
+
 int Mouse::doProximityHighlights(uint16 xPos, uint16 yPos) {
 	uint32 currentListNum = Logic::_scriptVariables[MOUSE_LIST_NO];
 	uint16 *currentList;
@@ -352,7 +345,7 @@ int Mouse::doProximityHighlights(uint16 xPos, uint16 yPos) {
 
 	// near inv button?
 	if (yPos > HOTSPOT_INVY && xPos < HOTSPOT_INVX)
-		return  0;
+		return 0;
 
 	// not on same as last time, or was not on anything previously, so re-scan all objects
 	do {
@@ -393,7 +386,6 @@ int Mouse::doProximityHighlights(uint16 xPos, uint16 yPos) {
 }
 
 UIIcon Mouse::getInteractIcon(uint32 id) {
-
 	switch (id) {
 	case 70: // screen 1 stairs
 	case 4119: // elevator hole
@@ -648,16 +640,15 @@ uint16 Mouse::giveXCood(Compact *itemData, uint32 id) {
 			return  142;
 	}
 
-	if (!_xMapInitialized) {
+	if (_hotspotXMap.size() == 0) {
 		for (MouseXMap *m = mouseXMap; m->id != 0; m++)
 			_hotspotXMap[m->id] = m->mid;
-		_xMapInitialized = true;
 	}
 
 	if (_hotspotXMap.contains(id))
 		return _hotspotXMap[id];
 
-	return  mid;
+	return mid;
 }
 
 struct MouseYMap {
@@ -834,10 +825,9 @@ uint16 Mouse::giveYCood(Compact *itemData, uint32 id) {
 			return 0;
 	}
 
-	if (!_yMapInitialized) {
+	if (_hotspotYMap.size() == 0) {
 		for (MouseYMap *m = mouseYMap; m->id != 0; m++)
 			_hotspotYMap[m->id] = m->mid;
-		_yMapInitialized = true;
 	}
 
 	if (_hotspotYMap.contains(id))
@@ -883,223 +873,144 @@ int Mouse::touchingFloor(uint16 xPos, uint16 yPos) {
 }
 
 void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
-	if (SkyEngine::isIbass()) {
-		int midx, midy; // open hotspot dimensions
-		Compact *itemData;
-		int itemProx;
-		int d = 0;
-
-		if (yPos < (TOP_LEFT_Y + 5))
-			return;
-
-		// mouse must be down to search for stuff
-		if (_mouseB) {
-			debug(1, "Clicked");
-			// what are we near?
-			itemProx = doProximityHighlights(xPos, yPos);
-
-			// seems we need to clear this, but only safe to do so when a new click occurs as player is still live when walking to interact after a use-on interaction
-			// but not in linc terminal
-			if (101 != Logic::_scriptVariables[SCREEN])
-				Logic::_scriptVariables[OBJECT_HELD] = 0;
-
-			// need to check if still touching any currently popped up hotspot
-			if (_touchId && _touchId != 32767 && _timeOn < CLICK_THRESHOLD) {
-				if (_prevMouseOn == false)
-					_timeOn = 1;
-
-				// fetch the compact
-				itemData = _skyCompact->fetchCpt(_touchId);
-
-				// if not a floor
-				if (itemData->mouseOn) {
-					_skyScreen->setProximityNotAnimate(_nearestProximityIconId);//we want this one remaining one to not animate
-
-					midx = giveXCood(itemData, _touchId);
-					midy = giveYCood(itemData, _touchId);
-					// calc dist
-					d = abs(xPos - midx) + abs(yPos - midy);
-
-					// some left hand edge adjust for twin-hotspot non-exits
-					if (!hasSingleInteractIcon(_touchId) && !_isExit)
-						if ((midx - HOTSPOT_DIM) < TOP_LEFT_X)
-							midx = TOP_LEFT_X + HOTSPOT_DIM;
-
-					// still touching a normal hotspot?
-					if (!_isExit && midx - HOTSPOT_DIM < xPos && midx + HOTSPOT_DIM > xPos && midy - HOTSPOT_YOFF < yPos && midy/*+HOTSPOT_YOFF*/ > yPos) {
-						// if newly touching, and same item as last time, then inc the click count
-						if (_prevMouseOn == false) {
-
-							_clickedNum++;  // one more click
-							// reset fade out timer to max
-							_fadeOut = HOTSPOT_FADEOUT;
-							// reset hover time
-							_timeOn = 1;
-						} else
-							_timeOn++;
-
-						int icony = midy - HOTSPOT_YOFF;
-						icony -= TOP_LEFT_Y; // normalise for renderer
-						if (icony < 0)
-							icony = 0;
+	uint32 currentListNum = Logic::_scriptVariables[MOUSE_LIST_NO];
+	uint16 *currentList;
+	do {
+		currentList = (uint16 *)_skyCompact->fetchCpt(currentListNum);
+		while ((*currentList != 0) && (*currentList != 0xFFFF)) {
+			uint16 itemNum = *currentList;
+			Compact *itemData = _skyCompact->fetchCpt(itemNum);
+			currentList++;
+			if ((itemData->screen == Logic::_scriptVariables[SCREEN]) && (itemData->status & 16)) {
+				if (itemData->xcood + ((int16)itemData->mouseRelX) > xPos)
+					continue;
+				if (itemData->xcood + ((int16)itemData->mouseRelX) + itemData->mouseSizeX < xPos)
+					continue;
+				if (itemData->ycood + ((int16)itemData->mouseRelY) > yPos)
+					continue;
+				if (itemData->ycood + ((int16)itemData->mouseRelY) + itemData->mouseSizeY < yPos)
+					continue;
+				// we've hit the item
+				if (Logic::_scriptVariables[SPECIAL_ITEM] == itemNum)
+					return;
+				Logic::_scriptVariables[SPECIAL_ITEM] = itemNum;
+				if (Logic::_scriptVariables[GET_OFF])
+					_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], itemData);
+				Logic::_scriptVariables[GET_OFF] = itemData->mouseOff;
+				if (itemData->mouseOn)
+					_skyLogic->mouseScript(itemData->mouseOn, itemData);
+				return;
+			}
+		}
+		if (*currentList == 0xFFFF)
+			currentListNum = currentList[1];
+	} while (*currentList != 0);
+	if (Logic::_scriptVariables[SPECIAL_ITEM] != 0) {
+		Logic::_scriptVariables[SPECIAL_ITEM] = 0;
 
-						if (hasSingleInteractIcon(_touchId)) {
-							// update the coordinate of the hotspot
-							midx -= TOP_LEFT_X;
-							midx -= HOTSPOT_EXIT_DIM;
+		if (Logic::_scriptVariables[GET_OFF])
+			_skyLogic->script((uint16)Logic::_scriptVariables[GET_OFF],(uint16)(Logic::_scriptVariables[GET_OFF] >> 16));
+		Logic::_scriptVariables[GET_OFF] = 0;
+	}
+}
 
-							// draw the icons
-							_skyScreen->setIcon(getInteractIcon(_touchId), midx + 4, icony);
-							_actionFlashX = midx + 4;
-							_actionFlashIcon = getInteractIcon(_touchId);
-							_actionFlashY = icony;
-
-						} else { // 2 icons
-							midx -= TOP_LEFT_X;
-							midx -= HOTSPOT_DIM;
-
-							_actionFlashY = icony;
-
-							if (xPos <= (midx + HOTSPOT_DIM + TOP_LEFT_X)) {
-								Logic::_scriptVariables[BUTTON] = 2;
-								_actionFlashX = midx;
-								_actionFlashIcon = UI_ICON_LOOK;
-							} else {
-								Logic::_scriptVariables[BUTTON] = 1;
-								_actionFlashX = midx + HOTSPOT_DIM + 4;
-								_actionFlashIcon = getInteractIcon(_touchId);
-							}
-						}
+void Mouse::pointerEngineIBASS(uint16 xPos, uint16 yPos) {
+	int midx, midy; // open hotspot dimensions
+	Compact *itemData;
+	int itemProx;
+	int d = 0;
+	if (yPos < (TOP_LEFT_Y + 5))
+		return;
+	// mouse must be down to search for stuff
+	if (_mouseB) {
+		debug(1, "Clicked");
+		// what are we near?
+		itemProx = doProximityHighlights(xPos, yPos);
+
+		// seems we need to clear this, but only safe to do so when a new click occurs as player is still live when walking to interact after a use-on interaction
+		// but not in linc terminal
+		if (101 != Logic::_scriptVariables[SCREEN])
+			Logic::_scriptVariables[OBJECT_HELD] = 0;
+		// need to check if still touching any currently popped up hotspot
+		if (_touchId && _touchId != 32767 && _timeOn < CLICK_THRESHOLD) {
+			if (_prevMouseOn == false)
+				_timeOn = 1;
+			// fetch the compact
+			itemData = _skyCompact->fetchCpt(_touchId);
+			// if not a floor
+			if (itemData->mouseOn) {
+				_skyScreen->setProximityNotAnimate(_nearestProximityIconId);//we want this one remaining one to not animate
 
-						// mouse on
-						_prevMouseOn = true;
-
-						// end here, when button held on something
-						return;
-					} else if (_isExit && midx - HOTSPOT_DIM < xPos && midx + HOTSPOT_DIM > xPos && midy - HOTSPOT_YOFF < yPos && midy/*+HOTSPOT_YOFF*/ > yPos) {
-						// still touching the poped up exit
-						// which action
-						Logic::_scriptVariables[BUTTON] = 1;
-
-						// if newly touching, and same item as last time, then inc the click count
-						if (_prevMouseOn == false) {
-							_clickedNum++;  // one more click
-							// reset fade out timer to max
-							_fadeOut = HOTSPOT_FADEOUT;
-							// reset hover time
-							_timeOn = 0;
+				midx = giveXCood(itemData, _touchId);
+				midy = giveYCood(itemData, _touchId);
+				// calc dist
+				d = abs(xPos - midx) + abs(yPos - midy);
+				// some left hand edge adjust for twin-hotspot non-exits
+				if (!hasSingleInteractIcon(_touchId) && !_isExit)
+					if ((midx - HOTSPOT_DIM) < TOP_LEFT_X)
+						midx = TOP_LEFT_X + HOTSPOT_DIM;
+				// still touching a normal hotspot?
+				if (!_isExit && midx - HOTSPOT_DIM < xPos && midx + HOTSPOT_DIM > xPos && midy - HOTSPOT_YOFF < yPos && midy/*+HOTSPOT_YOFF*/ > yPos) {
+					// if newly touching, and same item as last time, then inc the click count
+					if (_prevMouseOn == false) {
+						_clickedNum++;  // one more click
+						// reset fade out timer to max
+						_fadeOut = HOTSPOT_FADEOUT;
+						// reset hover time
+						_timeOn = 1;
+					} else
+						_timeOn++;
+
+					int icony = midy - HOTSPOT_YOFF;
+					icony -= TOP_LEFT_Y; // normalise for renderer
+					if (icony < 0)
+						icony = 0;
+
+					if (hasSingleInteractIcon(_touchId)) {
+						// update the coordinate of the hotspot
+						midx -= TOP_LEFT_X;
+						midx -= HOTSPOT_EXIT_DIM;
+
+						// draw the icons
+						_skyScreen->setIcon(getInteractIcon(_touchId), midx + 4, icony);
+						_actionFlashX = midx + 4;
+						_actionFlashIcon = getInteractIcon(_touchId);
+						_actionFlashY = icony;
+					} else { // 2 icons
+						midx -= TOP_LEFT_X;
+						midx -= HOTSPOT_DIM;
+
+						_actionFlashY = icony;
+
+						if (xPos <= (midx + HOTSPOT_DIM + TOP_LEFT_X)) {
+							Logic::_scriptVariables[BUTTON] = 2;
+							_actionFlashX = midx;
+							_actionFlashIcon = UI_ICON_LOOK;
 						} else {
-							_timeOn++; // one more cycle
-							// update the coordinate of the hotspot
-							int iconx = midx - HOTSPOT_EXIT_DIM;
-							iconx -= TOP_LEFT_X; // normalise for renderer
-							if (iconx < 0)
-								iconx = 0;
-
-							int icony = midy - HOTSPOT_EXIT_YOFF;
-							icony -= TOP_LEFT_Y; // normalise for renderer
-							if (icony < 0)
-								icony = 0;
-
-							// draw the icon
-							initExitIcon(_exitType, iconx, icony);
-
-							_actionFlashY = icony;
+							Logic::_scriptVariables[BUTTON] = 1;
+							_actionFlashX = midx + HOTSPOT_DIM + 4;
+							_actionFlashIcon = getInteractIcon(_touchId);
 						}
+					}
+					// mouse on
+					_prevMouseOn = true;
+					// end here, when button held on something
+					return;
+				} else if (_isExit && midx - HOTSPOT_DIM < xPos && midx + HOTSPOT_DIM > xPos && midy - HOTSPOT_YOFF < yPos && midy/*+HOTSPOT_YOFF*/ > yPos) {
+					// still touching the poped up exit
+					// which action
+					Logic::_scriptVariables[BUTTON] = 1;
 
-						// mouse on
-						_prevMouseOn = true;
-
-						// end here, when button held on something
-						return;
+					// if newly touching, and same item as last time, then inc the click count
+					if (_prevMouseOn == false) {
+						_clickedNum++;  // one more click
+						// reset fade out timer to max
+						_fadeOut = HOTSPOT_FADEOUT;
+						// reset hover time
+						_timeOn = 0;
 					} else {
-						_touchId = 0;
-						_clickedNum = 0;
-					}
-				} else { // else if floor
-					// floors just count time - we only want clicks(jabs)
-					// still touching it?
-					if ((itemData->xcood + ((int16)itemData->mouseRelX) < xPos) && (itemData->xcood + ((int16)itemData->mouseRelX) + itemData->mouseSizeX > xPos) && (itemData->ycood + ((int16)itemData->mouseRelY) < yPos) && (itemData->ycood + ((int16)itemData->mouseRelY) + itemData->mouseSizeY > yPos))
 						_timeOn++; // one more cycle
-					else {
-						_touchId = 0;
-						_clickedNum = 0;
-					}
-				}
-			}
-			// find if we're touching a floor
-			int floor = touchingFloor(xPos, yPos);
-
-			if (itemProx) {
-				itemData = _skyCompact->fetchCpt(itemProx);
-				midx = giveXCood(itemData, itemProx);
-				midy = giveYCood(itemData, itemProx);
-				// calc dist
-				d = abs(xPos - midx) + abs(yPos - midy);
-			}
-
-			// not close enough to real hotspot, and still touching previous floor
-			if (floor && (d >= USE_ON_DIST) && floor == _touchId)
-				// if we skip floor, and dont hit another hotspot, then we quit after this search, because there is no fadeOut on floors, so the system resets the couter
-				// floorSkip=true;
-				// continue;
-				return;
-
-			if ((itemProx && d < USE_ON_DIST) || floor) {
-				// we've hit a new object
-
-				// floor or object?
-				if (itemProx && d < USE_ON_DIST) {
-					// record what we're touching
-					Logic::_scriptVariables[SPECIAL_ITEM] = itemProx; // put in here now, for mouseOn script
-					_touchId = itemProx;
-					_touchIdLegacy = itemProx; // remembered when mouse off
-				} else {
-					// record what we're touching
-					Logic::_scriptVariables[SPECIAL_ITEM] = floor; // put in here now, for mouseOn script
-					_touchId = floor;
-					_touchIdLegacy = floor; // remembered when mouse off
-				}
-
-				itemData = _skyCompact->fetchCpt(_touchId);
-
-				// jumping straight from one object to another?
-				if (Logic::_scriptVariables[SPECIAL_ITEM]) {
-					// remove hotspot icons
-					_skyScreen->clearAllIbassIcons(false);
-				}
-
-				// reset hover time to max
-				_timeOn = 1;
-				_clickedNum = 0;
-
-				// run previous items get-off, if there was one (gone straight from one object onto another!)
-				if (Logic::_scriptVariables[GET_OFF])
-					_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], itemData);
-
-				// write mouse off script number
-				Logic::_scriptVariables[GET_OFF] = itemData->mouseOff;
-
-				// run the mouse on script
-				if (itemData->mouseOn) {
-					// disallow sliding back onto floors
-					_floorLock = true;
-
-					// reset fade out timer
-					_fadeOut = HOTSPOT_FADEOUT;
-					debug(1, "Fadeout det to 36, mouseOn = %d, dist = %d", itemData->mouseOn, d);
-
-					_skyScreen->setProximityNotAnimate(_nearestProximityIconId); // we want this one remaining one to not animate
-
-					// assume not
-					_isExit = false;
-					_isFloor = false;
-
-					_skyLogic->mouseScript(itemData->mouseOn, itemData);
-
-					// exit, or hotspot?
-					if (_isExit) {
-
+						// update the coordinate of the hotspot
 						int iconx = midx - HOTSPOT_EXIT_DIM;
 						iconx -= TOP_LEFT_X; // normalise for renderer
 						if (iconx < 0)
@@ -1112,226 +1023,260 @@ void Mouse::pointerEngine(uint16 xPos, uint16 yPos) {
 
 						// draw the icon
 						initExitIcon(_exitType, iconx, icony);
-					} else {
-						int icony = midy - HOTSPOT_YOFF;
-						icony -= TOP_LEFT_Y;// normalise for renderer
-						if (icony < 0)
-							icony = 0;
 
-						if (hasSingleInteractIcon(_touchId)) {
-							// update the coordinate of the hotspot
-							int iconx = midx - HOTSPOT_EXIT_DIM;
-							iconx -= TOP_LEFT_X;// normalise for renderer
-							if (iconx < 0)
-								iconx = 0;
-
-							// draw the icons
-
-							_skyScreen->setIcon(getInteractIcon(_touchId), iconx + 4, icony);
-
-							// stairs on screen 1 - normal object turned into exit - need to hack the button -
-							// the rest are either talk-to, which doesnt seem to matter, or look-at, like posters on walls
-							if (_touchId == 70 || _touchId == 69 || _touchId == 24633
-								|| _touchId == 24634 || _touchId == 4119 || _touchId == 8210)
-								Logic::_scriptVariables[BUTTON] = 1;
-							else
-								Logic::_scriptVariables[BUTTON] = 2;
-
-						} else { // 2 icons
-							// update the coordinate of the hotspot
-							int iconx = midx - HOTSPOT_DIM;
-							iconx -= TOP_LEFT_X;// normalise for renderer
-							if (iconx < 0)
-								iconx = 0;
-
-							// draw the icons
-							_skyScreen->setIcon(UI_ICON_LOOK, iconx, icony);
-							_skyScreen->setIcon(getInteractIcon(_touchId), iconx + HOTSPOT_DIM + 4, icony);
-						}
+						_actionFlashY = icony;
 					}
-				} else if (!_floorLock) { // no mouseOn script, which probably always means this is a floor?
-					// set action
-					Logic::_scriptVariables[BUTTON] = 1;
-					// non graphical hotspots - floors - can interact first click
-					_clickedNum = 1;
-					// reset hover time to max
-					_timeOn = 1;
-					_isFloor = true;
-				} else
-					_touchId = 0; // locked floor
-
-				// mouse on
-				_prevMouseOn = true;
-				// we're done
-				return;
-			} else {
-				debug(1, "nothing");
-				// not touching anything, force open hotspot to close
-				if (_fadeOut)
-					_fadeOut = 0;
-			}
-			// not touching a game object - but what about HU buttons, such as Inv?
-			if (!_prevMouseOn && 101 != Logic::_scriptVariables[SCREEN] && Logic::_scriptVariables[LOGIC_LIST_NO] != 24765) {
-				if (xPos < HOTSPOT_INVX && yPos > HOTSPOT_INVY) {
-					_skyLogic->startInventory();
-					_touchId = 0;
-					_holding = false;
-					_mMode = PRE_INVENTORY;
-					_skyScreen->clearAllProximityIcons(false);
-					_skyScreen->clearAllIbassIcons(false);
+					// mouse on
+					_prevMouseOn = true;
+					// end here, when button held on something
 					return;
+				} else {
+					_touchId = 0;
+					_clickedNum = 0;
 				}
-				// control panel
-				if (xPos < HOTSPOT_OPTIONSX && yPos < HOTSPOT_OPTIONSY) {
-					_skyControl->doControlPanel();
-					_skyScreen->clearAllProximityIcons(false);
-					_skyScreen->clearAllIbassIcons(false);
-					_mouseB = 0;
-				}
-				// help screen
-				if (xPos > HOTSPOT_helpx && yPos < HOTSPOT_helpy) {
-					_skyScreen->clearAllProximityIcons(false);
-					_skyScreen->clearAllIbassIcons(false);
-					_mouseB = 0;
+			} else { // else if floor
+				// floors just count time - we only want clicks(jabs)
+				// still touching it?
+				if ((itemData->xcood + ((int16)itemData->mouseRelX) < xPos) && (itemData->xcood + ((int16)itemData->mouseRelX) + itemData->mouseSizeX > xPos) && (itemData->ycood + ((int16)itemData->mouseRelY) < yPos) && (itemData->ycood + ((int16)itemData->mouseRelY) + itemData->mouseSizeY > yPos))
+					_timeOn++; // one more cycle
+				else {
+					_touchId = 0;
+					_clickedNum = 0;
 				}
 			}
+		}
+		// find if we're touching a floor
+		int floor = touchingFloor(xPos, yPos);
+
+		if (itemProx) {
+			itemData = _skyCompact->fetchCpt(itemProx);
+			midx = giveXCood(itemData, itemProx);
+			midy = giveYCood(itemData, itemProx);
+			// calc dist
+			d = abs(xPos - midx) + abs(yPos - midy);
+		}
+		// not close enough to real hotspot, and still touching previous floor
+		if (floor && (d >= USE_ON_DIST) && floor == _touchId)
+			// if we skip floor, and dont hit another hotspot, then we quit after this search, because there is no fadeOut on floors, so the system resets the couter
+			return;
 
-			// mouse on
-			_prevMouseOn = true;
-
-
-			debug(1, "floor returned = %d", floor);
-		} else { // not touching screen
-			if (_prevMouseOn) {
-
-				if (!_touchId || _isFloor)
-					_skyScreen->clearAllProximityIcons();
-
-				else if (_touchId) {
-					_skyScreen->clearAllProximityIcons();
-					// clear all but the one relating to the highlighted hotspot - hmmm
-					itemData = _skyCompact->fetchCpt(_touchId);
-					midx = giveXCood(itemData, _touchId);
-					midy = giveYCood(itemData, _touchId); //itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY>>1);
-					_skyScreen->setProximityIcon(0, midx - TOP_LEFT_X - 4, ((midy - TOP_LEFT_Y) - 4), 1.0, 0);
-					_skyScreen->setProximityNotAnimate(0);//we want this one remaining one to not animate
-				}
+		if ((itemProx && d < USE_ON_DIST) || floor) {
+			// we've hit a new object
+			// floor or object?
+			if (itemProx && d < USE_ON_DIST) {
+				// record what we're touching
+				Logic::_scriptVariables[SPECIAL_ITEM] = itemProx; // put in here now, for mouseOn script
+				_touchId = itemProx;
+				_touchIdLegacy = itemProx; // remembered when mouse off
+			} else {
+				// record what we're touching
+				Logic::_scriptVariables[SPECIAL_ITEM] = floor; // put in here now, for mouseOn script
+				_touchId = floor;
+				_touchIdLegacy = floor; // remembered when mouse off
 			}
+			itemData = _skyCompact->fetchCpt(_touchId);
 
-			// let go
-			_prevMouseOn = false;
-			_floorLock = false;
+			// jumping straight from one object to another?
+			if (Logic::_scriptVariables[SPECIAL_ITEM]) {
+				// remove hotspot icons
+				_skyScreen->clearAllIbassIcons(false);
+			}
+			// reset hover time to max
+			_timeOn = 1;
+			_clickedNum = 0;
 
-			// if 2nd or more click on this item
-			if (_timeOn && _clickedNum) {
+			// run previous items get-off, if there was one (gone straight from one object onto another!)
+			if (Logic::_scriptVariables[GET_OFF])
+				_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], itemData);
+
+			// write mouse off script number
+			Logic::_scriptVariables[GET_OFF] = itemData->mouseOff;
+			// run the mouse on script
+			if (itemData->mouseOn) {
+				// disallow sliding back onto floors
+				_floorLock = true;
+				// reset fade out timer
+				_fadeOut = HOTSPOT_FADEOUT;
+				debug(1, "Fadeout det to 36, mouseOn = %d, dist = %d", itemData->mouseOn, d);
+				_skyScreen->setProximityNotAnimate(_nearestProximityIconId); // we want this one remaining one to not animate
+
+				// assume not
+				_isExit = false;
+				_isFloor = false;
 
+				_skyLogic->mouseScript(itemData->mouseOn, itemData);
 
-				// faking the click so that the engine scripts execute correctly
-				_logicClick = true;
-				if (Logic::_scriptVariables[BUTTON] == 0)
-					Logic::_scriptVariables[BUTTON] = 1;
+				// exit, or hotspot?
+				if (_isExit) {
+					int iconx = midx - HOTSPOT_EXIT_DIM;
+					iconx -= TOP_LEFT_X; // normalise for renderer
+					if (iconx < 0)
+						iconx = 0;
 
-				// first, some autosaving incase this is a fatal, yes FATAL, interaction
-				if (g_engine->canSaveGameStateCurrently())
-					g_engine->saveGameState(0, "Autosave", true);
+					int icony = midy - HOTSPOT_EXIT_YOFF;
+					icony -= TOP_LEFT_Y; // normalise for renderer
+					if (icony < 0)
+						icony = 0;
 
-				// an sfx
+					// draw the icon
+					initExitIcon(_exitType, iconx, icony);
+				} else {
+					int icony = midy - HOTSPOT_YOFF;
+					icony -= TOP_LEFT_Y;// normalise for renderer
+					if (icony < 0)
+						icony = 0;
+					if (hasSingleInteractIcon(_touchId)) {
+						// update the coordinate of the hotspot
+						int iconx = midx - HOTSPOT_EXIT_DIM;
+						iconx -= TOP_LEFT_X;// normalise for renderer
+						if (iconx < 0)
+							iconx = 0;
 
-				_fadeOut = 0;   // force getOff script to run also
+						// draw the icons
+						_skyScreen->setIcon(getInteractIcon(_touchId), iconx + 4, icony);
+						// stairs on screen 1 - normal object turned into exit - need to hack the button -
+						// the rest are either talk-to, which doesnt seem to matter, or look-at, like posters on walls
+						if (_touchId == 70 || _touchId == 69 || _touchId == 24633
+						        || _touchId == 24634 || _touchId == 4119 || _touchId == 8210)
+							Logic::_scriptVariables[BUTTON] = 1;
+						else
+							Logic::_scriptVariables[BUTTON] = 2;
+
+					} else { // 2 icons
+						// update the coordinate of the hotspot
+						int iconx = midx - HOTSPOT_DIM;
+						iconx -= TOP_LEFT_X;// normalise for renderer
+						if (iconx < 0)
+							iconx = 0;
 
-				// setup action flash
-				if (!_isFloor) {
-					_actionFlash = true;
-					_actionFlashTime = ACTION_FLASH_TIME;
+						// draw the icons
+						_skyScreen->setIcon(UI_ICON_LOOK, iconx, icony);
+						_skyScreen->setIcon(getInteractIcon(_touchId), iconx + HOTSPOT_DIM + 4, icony);
+					}
 				}
-				// set this again, as there's a chance some other random script may have cleared it since we first touched this hotspot
-				Logic::_scriptVariables[SPECIAL_ITEM] = _touchId;
-
+			} else if (!_floorLock) { // no mouseOn script, which probably always means this is a floor?
+				// set action
+				Logic::_scriptVariables[BUTTON] = 1;
+				// non graphical hotspots - floors - can interact first click
+				_clickedNum = 1;
+				// reset hover time to max
+				_timeOn = 1;
+				_isFloor = true;
+			} else
+				_touchId = 0; // locked floor
 
-				// over anything?
-				Compact *item = _skyCompact->fetchCpt(Logic::_scriptVariables[SPECIAL_ITEM]);
-				if (item->mouseClick/* && item->cursorText*/)// not floors
-					_skyLogic->mouseScript(item->mouseClick, item);
+			// mouse on
+			_prevMouseOn = true;
+			// we're done
+			return;
+		} else {
+			debug(1, "nothing");
+			// not touching anything, force open hotspot to close
+			if (_fadeOut)
+				_fadeOut = 0;
+		}
+		// not touching a game object - but what about HU buttons, such as Inv?
+		if (!_prevMouseOn && 101 != Logic::_scriptVariables[SCREEN] && Logic::_scriptVariables[LOGIC_LIST_NO] != 24765) {
+			if (xPos < HOTSPOT_INVX && yPos > HOTSPOT_INVY) {
+				_skyLogic->startInventory();
+				_touchId = 0;
+				_holding = false;
+				_mMode = PRE_INVENTORY;
+				_skyScreen->clearAllProximityIcons(false);
+				_skyScreen->clearAllIbassIcons(false);
+				return;
+			}
+			// control panel
+			if (xPos < HOTSPOT_OPTIONSX && yPos < HOTSPOT_OPTIONSY) {
+				_skyControl->doControlPanel();
+				_skyScreen->clearAllProximityIcons(false);
+				_skyScreen->clearAllIbassIcons(false);
+				_mouseB = 0;
+			}
+			// help screen
+			if (xPos > HOTSPOT_helpx && yPos < HOTSPOT_helpy) {
+				_skyScreen->clearAllProximityIcons(false);
+				_skyScreen->clearAllIbassIcons(false);
+				_mouseB = 0;
 			}
-
-			// reset ready for next stab
-			_timeOn = 0;
 		}
-
-		// mouse is not pressed, or not touching anything
-
-		// count down to fade out and run get-off
-		if (_fadeOut) {
-			_fadeOut--;
-			// update coordinate, so hotspot follows walking megas
-			updateHotspotCoordinate(xPos);
+		// mouse on
+		_prevMouseOn = true;
+		debug(1, "floor returned = %d", floor);
+	} else { // not touching screen
+		if (_prevMouseOn) {
+			if (!_touchId || _isFloor)
+				_skyScreen->clearAllProximityIcons();
+			else if (_touchId) {
+				_skyScreen->clearAllProximityIcons();
+				// clear all but the one relating to the highlighted hotspot - hmmm
+				itemData = _skyCompact->fetchCpt(_touchId);
+				midx = giveXCood(itemData, _touchId);
+				midy = giveYCood(itemData, _touchId); //itemData->ycood + ((int16)itemData->mouseRelY) + (itemData->mouseSizeY>>1);
+				_skyScreen->setProximityIcon(0, midx - TOP_LEFT_X - 4, ((midy - TOP_LEFT_Y) - 4), 1.0, 0);
+				_skyScreen->setProximityNotAnimate(0);//we want this one remaining one to not animate
+			}
 		}
+		// let go
+		_prevMouseOn = false;
+		_floorLock = false;
+
+		// if 2nd or more click on this item
+		if (_timeOn && _clickedNum) {
+			// faking the click so that the engine scripts execute correctly
+			_logicClick = true;
+			if (Logic::_scriptVariables[BUTTON] == 0)
+				Logic::_scriptVariables[BUTTON] = 1;
 
-		if (!_fadeOut) {
-			_skyScreen->clearAllProximityIcons();
-
-			// reset number of times we clicked on this
-			_clickedNum = 0;
-			_touchId = 0;
-
-			// process get-off script, if we were touching, and there is one
-			if (Logic::_scriptVariables[SPECIAL_ITEM] != 0) {
-				// close the hotspot popup
-
-				// remove hotspot icons
-				_skyScreen->clearAllIbassIcons(true);
-
-				Logic::_scriptVariables[SPECIAL_ITEM] = 0;
-
-				// get off
-				if (Logic::_scriptVariables[GET_OFF])
-					_skyLogic->script((uint16)Logic::_scriptVariables[GET_OFF], (uint16)(Logic::_scriptVariables[GET_OFF] >> 16));
+			// first, some autosaving incase this is a fatal, yes FATAL, interaction
+			if (g_engine->canSaveGameStateCurrently())
+				g_engine->saveGameState(0, "Autosave", true);
+			_fadeOut = 0;   // force getOff script to run also
 
-				Logic::_scriptVariables[GET_OFF] = 0;
+			// setup action flash
+			if (!_isFloor) {
+				_actionFlash = true;
+				_actionFlashTime = ACTION_FLASH_TIME;
 			}
+			// set this again, as there's a chance some other random script may have cleared it since we first touched this hotspot
+			Logic::_scriptVariables[SPECIAL_ITEM] = _touchId;
+			// over anything?
+			Compact *item = _skyCompact->fetchCpt(Logic::_scriptVariables[SPECIAL_ITEM]);
+			if (item->mouseClick/* && item->cursorText*/)// not floors
+				_skyLogic->mouseScript(item->mouseClick, item);
 		}
-		return;
+		// reset ready for next stab
+		_timeOn = 0;
+	}
+	// mouse is not pressed, or not touching anything
+	// count down to fade out and run get-off
+	if (_fadeOut) {
+		_fadeOut--;
+		// update coordinate, so hotspot follows walking megas
+		updateHotspotCoordinate(xPos);
 	}
 
-	uint32 currentListNum = Logic::_scriptVariables[MOUSE_LIST_NO];
-	uint16 *currentList;
-	do {
-		currentList = (uint16 *)_skyCompact->fetchCpt(currentListNum);
-		while ((*currentList != 0) && (*currentList != 0xFFFF)) {
-			uint16 itemNum = *currentList;
-			Compact *itemData = _skyCompact->fetchCpt(itemNum);
-			currentList++;
-			if ((itemData->screen == Logic::_scriptVariables[SCREEN]) && (itemData->status & 16)) {
-				if (itemData->xcood + ((int16)itemData->mouseRelX) > xPos)
-					continue;
-				if (itemData->xcood + ((int16)itemData->mouseRelX) + itemData->mouseSizeX < xPos)
-					continue;
-				if (itemData->ycood + ((int16)itemData->mouseRelY) > yPos)
-					continue;
-				if (itemData->ycood + ((int16)itemData->mouseRelY) + itemData->mouseSizeY < yPos)
-					continue;
-				// we've hit the item
-				if (Logic::_scriptVariables[SPECIAL_ITEM] == itemNum)
-					return;
-				Logic::_scriptVariables[SPECIAL_ITEM] = itemNum;
-				if (Logic::_scriptVariables[GET_OFF])
-					_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], itemData);
-				Logic::_scriptVariables[GET_OFF] = itemData->mouseOff;
-				if (itemData->mouseOn)
-					_skyLogic->mouseScript(itemData->mouseOn, itemData);
-				return;
-			}
-		}
-		if (*currentList == 0xFFFF)
-			currentListNum = currentList[1];
-	} while (*currentList != 0);
-	if (Logic::_scriptVariables[SPECIAL_ITEM] != 0) {
-		Logic::_scriptVariables[SPECIAL_ITEM] = 0;
+	if (!_fadeOut) {
+		_skyScreen->clearAllProximityIcons();
 
-		if (Logic::_scriptVariables[GET_OFF])
-			_skyLogic->script((uint16)Logic::_scriptVariables[GET_OFF],(uint16)(Logic::_scriptVariables[GET_OFF] >> 16));
-		Logic::_scriptVariables[GET_OFF] = 0;
+		// reset number of times we clicked on this
+		_clickedNum = 0;
+		_touchId = 0;
+
+		// process get-off script, if we were touching, and there is one
+		if (Logic::_scriptVariables[SPECIAL_ITEM] != 0) {
+			// close the hotspot popup
+			// remove hotspot icons
+			_skyScreen->clearAllIbassIcons(true);
+			Logic::_scriptVariables[SPECIAL_ITEM] = 0;
+			// get off
+			if (Logic::_scriptVariables[GET_OFF])
+				_skyLogic->script((uint16)Logic::_scriptVariables[GET_OFF], (uint16)(Logic::_scriptVariables[GET_OFF] >> 16));
+
+			Logic::_scriptVariables[GET_OFF] = 0;
+		}
 	}
+	return;
 }
 
 void Mouse::initExitIcon(uint32 type, int iconx, int icony) {
@@ -1364,18 +1309,16 @@ void Mouse::initExitIcon(uint32 type, int iconx, int icony) {
 }
 
 void Mouse::updateHotspotCoordinate(uint16 xPos) {
-	Compact *itemData;
 	int midx,  midy;
 
 	// fetch the compact
-	itemData = _skyCompact->fetchCpt(_touchIdLegacy);
+	Compact *itemData = _skyCompact->fetchCpt(_touchIdLegacy);
 
 	if (!itemData)
 		return;
 
 	// if not a floor
 	if (itemData->mouseOn && !_isExit) {
-
 		midx = giveXCood(itemData, _touchIdLegacy);
 		midy = giveYCood(itemData, _touchIdLegacy);
 
@@ -1429,7 +1372,7 @@ void Mouse::buttonEngine1() {
 
 	if (_mouseB) {	//anything pressed?
 		Logic::_scriptVariables[BUTTON] = _mouseB;
-		if (Logic::_scriptVariables[SPECIAL_ITEM] && Logic::_scriptVariables[SPECIAL_ITEM] != 0xFFFFFFFF) { //over anything?
+		if (Logic::_scriptVariables[SPECIAL_ITEM] && Logic::_scriptVariables[SPECIAL_ITEM] != 0xFFFFFFFF) { // over anything?
 			Compact *item = _skyCompact->fetchCpt(Logic::_scriptVariables[SPECIAL_ITEM]);
 			if (item->mouseClick)
 				_skyLogic->mouseScript(item->mouseClick, item);
@@ -1501,10 +1444,8 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 	num = (int)Logic::_scriptVariables[MENU_LENGTH];
 
 	if (_holding) {
-
 		// dragged off of inv? Quit inv mode
 		if (xPos < _invX || xPos > _invX + _invW || yPos < _invY || yPos > _invY + _invH) {
-
 			// dragged off of the inv
 			_mMode = INVENTORY_USE_ON;
 			// remove inv items from screen/logic processing
@@ -1525,8 +1466,6 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 		if (_mouseB) {
 			// keep scanning objects to run geton/off
 			for (j = 0; j < num; j++) {
-
-
 				// fetch the compact
 				itemData = _skyCompact->fetchCpt(objList[j]);
 
@@ -1544,16 +1483,11 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 				// on previous?
 				if (_hoverId == objList[j])
 					continue; // still on previous, so skip
-
-
 				// run previous items get-off, if there was one (gone straight from one object onto another!)
 				if (Logic::_scriptVariables[GET_OFF])
 					_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], _skyCompact->fetchCpt(_hoverId));
-
-
 				// write new mouse off script number
 				Logic::_scriptVariables[GET_OFF] = itemData->mouseOff;
-
 				_hoverId = objList[j];
 
 				// new item
@@ -1571,9 +1505,7 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 					// and bring back render position
 					itemData->ycood = tempY;
 				}
-
 			}
-
 			// if we didn't register any hit then run the get off - we're sitting on blank inventory space
 			if (!touched) {
 				// touching nothing
@@ -1582,9 +1514,7 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 					_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], _skyCompact->fetchCpt(_hoverId));
 					Logic::_scriptVariables[GET_OFF] = 0;
 				}
-
 			}
-
 			// we're done
 			return;
 		}
@@ -1592,12 +1522,10 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 		if (_hoverId == 24584 || _hoverId == 24630 || _hoverId == 24732 || _hoverId == 24643) {
 			// fetch the compact
 			itemData = _skyCompact->fetchCpt(_touchId);
-
 			// set button
 			Logic::_scriptVariables[BUTTON] = 3;
 			// record what we're touching
 			Logic::_scriptVariables[SPECIAL_ITEM] = _hoverId;
-
 			// fight internal logic's impulse to slide back up
 			uint16 tempY = itemData->ycood;
 			itemData->ycood = 136;
@@ -1606,12 +1534,10 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 			// and bring back render position
 			itemData->ycood = tempY; // itemData->invY;
 
-
 			if (menuRef != _lincMenuRef) {
 				itemData = _skyCompact->fetchCpt(_touchId);
 				itemData->frame--;
 				itemData->getToFlag = 0;
-			} else {
 			}
 		} else {
 			// wont combine
@@ -1709,11 +1635,9 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 			return;
 		}
 	}
-
 }
 
 void Mouse::invMouse(uint16 xPos, uint16 yPos) {
-
 	uint32 *objList;
 	Compact *itemData;
 	int j, num;
diff --git a/engines/sky/mouse.h b/engines/sky/mouse.h
index 37e04eeada8..1559e7c7f8c 100644
--- a/engines/sky/mouse.h
+++ b/engines/sky/mouse.h
@@ -93,6 +93,7 @@ public:
 	~Mouse();
 
 	void mouseEngine();
+	void mouseEngineIBASS();
 	void replaceMouseCursors(uint16 fileNo);
 	bool fnAddHuman();
 	void fnSaveCoods();
@@ -151,6 +152,7 @@ public:
 protected:
 
 	void pointerEngine(uint16 xPos, uint16 yPos);
+	void pointerEngineIBASS(uint16 xPos, uint16 yPos);
 	void buttonEngine1();
 	void invMouse(uint16 xPos, uint16 yPos);
 	void lincInvMouse(uint16 xPos, uint16 yPos);
@@ -203,8 +205,6 @@ protected:
 
 	Common::HashMap<int, int> _hotspotXMap;
 	Common::HashMap<int, int> _hotspotYMap;
-	bool _xMapInitialized = false;
-	bool _yMapInitialized = false;
 
 	static uint32 _mouseMainObjects[24];
 	static uint32 _mouseLincObjects[21];
diff --git a/engines/sky/screen.cpp b/engines/sky/screen.cpp
index 26e273ef2ec..2558d00c3ec 100644
--- a/engines/sky/screen.cpp
+++ b/engines/sky/screen.cpp
@@ -275,27 +275,29 @@ void Screen::update32BitScreen(uint8 *overrideBuffer) {
 }
 
 void Screen::renderFinalFrame() {
-	update32BitScreen(_currentScreen);
-
 	if (SkyEngine::isIbass()) {
-
+		update32BitScreen(_currentScreen);
 		setIcon(UI_ICON_INV, 0, GAME_SCREEN_HEIGHT - 35);
-	}
-
-	drawIbassIcon();
-	drawIbassInventory();
-
-	if (_screen32.getPixels()) {
-		_system->copyRectToScreen(_screen32.getPixels(), _screen32.pitch, 0, 0, _screen32.w, _screen32.h);
+		drawIbassIcon();
+		drawIbassInventory();
+		if (_screen32.getPixels()) {
+			_system->copyRectToScreen(_screen32.getPixels(), _screen32.pitch, 0, 0, _screen32.w, _screen32.h);
+			_system->updateScreen();
+		}
+	} else {
+		_system->copyRectToScreen(_currentScreen, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, GAME_SCREEN_HEIGHT);
 		_system->updateScreen();
 	}
 }
 
 void Screen::renderControlPanel(uint8 *buffer) {
-	update32BitScreen(buffer);
-
-	if (_screen32.getPixels())
-		_system->copyRectToScreen(_screen32.getPixels(), _screen32.pitch, 0, 0, _screen32.w, _screen32.h);
+	if (SkyEngine::isIbass()) {
+		update32BitScreen(buffer);
+		if (_screen32.getPixels())
+			_system->copyRectToScreen(_screen32.getPixels(), _screen32.pitch, 0, 0, _screen32.w, _screen32.h);
+	} else {
+		_system->copyRectToScreen(buffer, GAME_SCREEN_WIDTH, 0, 0, GAME_SCREEN_WIDTH, GAME_SCREEN_HEIGHT);
+	}
 }
 
 void Screen::clearScreen(bool fullscreen) {
@@ -315,8 +317,8 @@ void Screen::setFocusRectangle(const Common::Rect& rect) {
 //set a new palette, pal is a pointer to dos vga rgb components 0..63
 void Screen::setPalette(uint8 *pal) {
 	convertPalette(pal, _palette);
-	if (SkyEngine::isIbass() && _system->getScreenFormat().bytesPerPixel == 1)
-		_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
+	if (_system->getScreenFormat().bytesPerPixel == 1)
+	_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
 	_system->updateScreen();
 }
 
@@ -329,8 +331,8 @@ void Screen::setPaletteEndian(uint8 *pal) {
 #else
 	convertPalette(pal, _palette);
 #endif
-	if (SkyEngine::isIbass() && _system->getScreenFormat().bytesPerPixel == 1)
-		_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
+	if (_system->getScreenFormat().bytesPerPixel == 1)
+	_system->getPaletteManager()->setPalette(_palette, 0, GAME_COLORS);
 	_system->updateScreen();
 }
 
@@ -342,7 +344,7 @@ void Screen::halvePalette() {
 		halfPalette[cnt * 3 + 1] = _palette[cnt * 3 + 1] >> 1;
 		halfPalette[cnt * 3 + 2] = _palette[cnt * 3 + 2] >> 1;
 	}
-	if (SkyEngine::isIbass() && _system->getScreenFormat().bytesPerPixel == 1)
+	if (_system->getScreenFormat().bytesPerPixel == 1)
 		_system->getPaletteManager()->setPalette(halfPalette, 0, GAME_COLORS);
 }
 
diff --git a/engines/sky/sky.cpp b/engines/sky/sky.cpp
index 80a14bbadcd..be9355bb613 100644
--- a/engines/sky/sky.cpp
+++ b/engines/sky/sky.cpp
@@ -243,7 +243,10 @@ Common::Error SkyEngine::go() {
 	uint32 delayCount = _system->getMillis();
 	while (!shouldQuit()) {
 		_skySound->checkFxQueue();
-		_skyMouse->mouseEngine();
+		if (SkyEngine::isIbass())
+			_skyMouse->mouseEngineIBASS();
+		else
+			_skyMouse->mouseEngine();
 		handleKey();
 		if (_systemVars->paused) {
 			do {
@@ -350,8 +353,14 @@ bool SkyEngine::loadChineseTraditional() {
 }
 
 Common::Error SkyEngine::init() {
-	Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0);
-	initGraphics(320, 200, &format);
+	if (SkyEngine::isIbass()) {
+		Graphics::PixelFormat format(4, 8, 8, 8, 8, 24, 16, 8, 0);
+		initGraphics(320, 200, &format);
+	} else {
+		initGraphics(320, 200);
+	}
+
+	debug(1, "%d bytes per pixel", _system->getScreenFormat().bytesPerPixel);
 
 	_skyDisk = new Disk();
 	_skySound = new Sound(_mixer, _skyDisk, Audio::Mixer::kMaxChannelVolume);


Commit: 62ca0c692aaadd1cfcc6a4ec834f97addb3ecadc
    https://github.com/scummvm/scummvm/commit/62ca0c692aaadd1cfcc6a4ec834f97addb3ecadc
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Implement inventory item's dragging in IBASS

Changed paths:
    engines/sky/mouse.cpp
    engines/sky/mouse.h


diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index 6574bd5d418..410f7809dac 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -319,6 +319,9 @@ void Mouse::mouseEngineIBASS() {
 			invMouse(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
 		break;
 	case INVENTORY_USE_ON:
+		invUseOn(_mouseX + TOP_LEFT_X, _mouseY + TOP_LEFT_Y);
+		break;
+
 	case TEXT_CHOOSER:
 		break;
 	}
@@ -1846,4 +1849,83 @@ void Mouse::invMouse(uint16 xPos, uint16 yPos) {
 	}
 }
 
+// dragging the inventory items around the screen and releasing to use
+void Mouse::invUseOn(uint16 xPos, uint16 yPos) {
+	Compact *itemData;
+	uint32 itemNum;
+	uint16 midX, midY;
+	bool buttonHeld = (_system->getEventManager()->getButtonState() != 0);
+
+	if (buttonHeld)
+		_logicClick++;
+	else
+		_logicClick = 0;
+
+	if (buttonHeld) {
+		itemNum = doProximityHighlights(xPos, yPos);
+		// without this, it would calculate Compact 0 if hovering over a non interactive item
+		if (!itemNum)
+			return;
+		debug("Item %d is being dragged", _touchId);
+		// what are we near
+		itemNum = doProximityHighlights(xPos, yPos);
+		itemData = _skyCompact->fetchCpt(itemNum);
+		midX = giveXCood(itemData, itemNum);
+		midY = giveYCood(itemData, itemNum);
+		int d = abs(xPos - midX) + abs(yPos - midY);
+		if (d < USE_ON_DIST) {
+			if (_touchId != itemNum) {
+				// run previous item's GET_OFF
+				if (Logic::_scriptVariables[GET_OFF])
+					_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], itemData);
+
+				Logic::_scriptVariables[GET_OFF] = itemData->mouseOff;
+				// record what we're touching
+				Logic::_scriptVariables[SPECIAL_ITEM] = itemNum;
+				_touchId = itemNum;
+				if (itemData->mouseOn) {
+					_skyLogic->mouseScript(itemData->mouseOn, itemData);
+					_skyScreen->setDragIconHighlight(true);
+				} else {
+					_skyScreen->setDragIconHighlight(false);
+				}
+			}
+			// touching something
+			_skyScreen->setProximityNotAnimate(_nearestProximityIconId);
+			return;
+		}
+		// touching nothing
+		// run previous item's GET_OFF if there was one
+		if (Logic::_scriptVariables[GET_OFF]) {
+			_skyScreen->setDragIconHighlight(false); // highlight off
+			itemData = _skyCompact->fetchCpt(_touchId);
+			_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], itemData);
+			Logic::_scriptVariables[GET_OFF] = 0;
+		}
+		_touchId = 0; // clear
+	} else { // release on another object
+		_skyScreen->clearAllProximityIcons();
+		// run previous item's GET_OFF if there was one
+		if (Logic::_scriptVariables[GET_OFF]) {
+			itemData = _skyCompact->fetchCpt(_touchId);
+			_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], itemData);
+			Logic::_scriptVariables[GET_OFF] = 0;
+		}
+		if (_touchId) {
+			if (g_engine->canSaveGameStateCurrently())
+				g_engine->saveGameState(0, "Autosave", true);
+			Logic::_scriptVariables[BUTTON] = 3;
+			itemData = _skyCompact->fetchCpt(_touchId);
+			if (itemData->mouseClick && itemData->mouseOn) {
+				Logic::_scriptVariables[SAFE_LOGIC_LIST] = Logic::_scriptVariables[LOGIC_LIST_NO];
+				_skyLogic->mouseScript(itemData->mouseClick, itemData);
+			}
+		}
+		resetUI();
+		_touchId = 0;
+		_mMode = GAMEPLAY;
+		_skyScreen->clearDragIcon();
+	}
+}
+
 } // End of namespace Sky
diff --git a/engines/sky/mouse.h b/engines/sky/mouse.h
index 1559e7c7f8c..cf8e4476f6f 100644
--- a/engines/sky/mouse.h
+++ b/engines/sky/mouse.h
@@ -156,6 +156,7 @@ protected:
 	void buttonEngine1();
 	void invMouse(uint16 xPos, uint16 yPos);
 	void lincInvMouse(uint16 xPos, uint16 yPos);
+	void invUseOn(uint16 xPos, uint16 yPos);
 
 	bool _logicClick;
 


Commit: e0d7b342a997a84890a4d48b9f40e4af3f454690
    https://github.com/scummvm/scummvm/commit/e0d7b342a997a84890a4d48b9f40e4af3f454690
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Add debug level and remove a newline character

Changed paths:
    engines/sky/mouse.cpp


diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index 410f7809dac..980474e1695 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -1613,7 +1613,7 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 
 				// special stuff for quit-linc
 				if (_touchId == 24582) {
-					debug(1, "QUIT LINC\n");
+					debug(1, "QUIT LINC");
 					itemData->frame--;
 
 					// remove inventory items from screen/logic processing
@@ -1677,7 +1677,7 @@ void Mouse::invMouse(uint16 xPos, uint16 yPos) {
 		if (buttonHeld) {
 			for (j = 0; j < num; j++) {
 				itemData = _skyCompact->fetchCpt(objList[j]);
-				debug("itemData->xcood = %d, itemData->mouseRelX = %d, itemData->ycood = %d, itemData->mouseRelY = %d", itemData->xcood, itemData->mouseRelX, itemData->ycood, itemData->mouseRelY);
+				debug(1, "itemData->xcood = %d, itemData->mouseRelX = %d, itemData->ycood = %d, itemData->mouseRelY = %d", itemData->xcood, itemData->mouseRelX, itemData->ycood, itemData->mouseRelY);
 
 				if (itemData->xcood + (uint16)itemData->mouseRelX > xPos)
 					continue;
@@ -1866,7 +1866,7 @@ void Mouse::invUseOn(uint16 xPos, uint16 yPos) {
 		// without this, it would calculate Compact 0 if hovering over a non interactive item
 		if (!itemNum)
 			return;
-		debug("Item %d is being dragged", _touchId);
+		debug(1, "Item %d is being dragged", _touchId);
 		// what are we near
 		itemNum = doProximityHighlights(xPos, yPos);
 		itemData = _skyCompact->fetchCpt(itemNum);


Commit: 9aafca550ffee882b6a216aa71fe04aece4b76ba
    https://github.com/scummvm/scummvm/commit/9aafca550ffee882b6a216aa71fe04aece4b76ba
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Remove separate cursor path for ibass

Changed paths:
    engines/sky/mouse.cpp


diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index 980474e1695..8924848a63a 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -234,13 +234,6 @@ void Mouse::waitMouseNotPressed(int minDelay) {
 void Mouse::spriteMouse(uint16 frameNum, uint8 mouseX, uint8 mouseY) {
 	_currentCursor = frameNum;
 
-	if (SkyEngine::isIbass()) {
-		debug(1, "ibass cursor path executed\n");
-		CursorMan.setDefaultArrowCursor();
-		CursorMan.showMouse(true);
-		return;
-	}
-
 	byte *newCursor = _miceData;
 	newCursor += ((DataFileHeader *)_miceData)->s_sp_size * frameNum;
 	newCursor += sizeof(DataFileHeader);


Commit: 01608c608032a9e3e01afdc1eded6b2a504fb60e
    https://github.com/scummvm/scummvm/commit/01608c608032a9e3e01afdc1eded6b2a504fb60e
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Fix crash due to writing outside the boundary of _screen32

Changed paths:
    engines/sky/screen.cpp


diff --git a/engines/sky/screen.cpp b/engines/sky/screen.cpp
index 2558d00c3ec..a34f62227f1 100644
--- a/engines/sky/screen.cpp
+++ b/engines/sky/screen.cpp
@@ -72,8 +72,8 @@ void Screen::drawIbassIcon() {
 
 			// get the current animation frame
 			Graphics::Surface *currentFrame = _uiIcon[i]._anim->_frames[_uiIcon[i]._curFrame];
-
-			_screen32.copyRectToSurfaceWithKey(*currentFrame, _uiIcon[i]._x, _uiIcon[i]._y, Common::Rect(currentFrame->w, currentFrame->h), _screen32.format.ARGBToColor(0x00, 0xFF, 0xFF, 0xFF));
+			if ((_uiIcon[i]._x + currentFrame->w) <= _screen32.w)
+				_screen32.copyRectToSurfaceWithKey(*currentFrame, _uiIcon[i]._x, _uiIcon[i]._y, Common::Rect(currentFrame->w, currentFrame->h), _screen32.format.ARGBToColor(0x00, 0xFF, 0xFF, 0xFF));
 		}
 
 	}


Commit: d2bd6badb5e0662c994866fd9634462adf6071cd
    https://github.com/scummvm/scummvm/commit/d2bd6badb5e0662c994866fd9634462adf6071cd
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Close LINC inventory if clicked outside the inventory in IBASS

Changed paths:
    engines/sky/mouse.cpp


diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index 8924848a63a..a552b0b1a8c 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -1631,6 +1631,22 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 			return;
 		}
 	}
+	// clicked outside the inventory, close it
+	if (!_touchId && _mouseB) {
+		if (xPos < _invX || xPos > _invX + _invW || yPos < _invY || yPos > _invY + _invH) {
+			_mMode = MUST_RELEASE;
+			_skyLogic->killInventory();
+			return;
+		}
+	}
+	_holding = false;
+	_touchId = 0;
+	_timeOn = 0;
+
+	if (Logic::_scriptVariables[GET_OFF]) {
+		_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], itemData);
+		Logic::_scriptVariables[GET_OFF] = 0;
+	}
 }
 
 void Mouse::invMouse(uint16 xPos, uint16 yPos) {


Commit: ad37508aa71c4f0a078c0cc6527a9441b94abc74
    https://github.com/scummvm/scummvm/commit/ad37508aa71c4f0a078c0cc6527a9441b94abc74
Author: Priyanshu (10b.priyanshu at gmail.com)
Date: 2026-06-30T21:23:57+02:00

Commit Message:
SKY: Use active mouse state instead of _mouseB, fix a logical error and some cleanup in LINC inventory for IBASS

Changed paths:
    engines/sky/mouse.cpp


diff --git a/engines/sky/mouse.cpp b/engines/sky/mouse.cpp
index a552b0b1a8c..5403964afb7 100644
--- a/engines/sky/mouse.cpp
+++ b/engines/sky/mouse.cpp
@@ -1427,8 +1427,9 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 	int j, num;
 	Compact *itemData;
 	bool touched = false;
+	bool buttonHeld = (_system->getEventManager()->getButtonState() != 0); // mouseEngine() consumes the click at the end so using _mouseB would increment the timer at each click not on hold
 
-	if (_mouseB)
+	if (buttonHeld)
 		_logicClick++;
 	else
 		_logicClick = 0;
@@ -1440,6 +1441,7 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 	num = (int)Logic::_scriptVariables[MENU_LENGTH];
 
 	if (_holding) {
+		debug(1, "Object held = %d", _touchId);
 		// dragged off of inv? Quit inv mode
 		if (xPos < _invX || xPos > _invX + _invW || yPos < _invY || yPos > _invY + _invH) {
 			// dragged off of the inv
@@ -1450,7 +1452,6 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 			itemData = _skyCompact->fetchCpt(_touchId);
 			itemData->frame--;
 			itemData->getToFlag = 0;
-
 			// start fresh
 			_touchId = 0;
 
@@ -1459,7 +1460,7 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 			return;
 		}
 		// else, wait for release, and see if release on another item
-		if (_mouseB) {
+		if (buttonHeld) {
 			// keep scanning objects to run geton/off
 			for (j = 0; j < num; j++) {
 				// fetch the compact
@@ -1556,21 +1557,21 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 	//---------------------------------------------------------------------------------------------------------------------------------------------
 
 	// touching screen, but not an object yet
-	if (_mouseB) {
+	if (buttonHeld) {
 		for (j = 0; j < num; j++) {
 			// fetch the compact
 			itemData = _skyCompact->fetchCpt(objList[j]);
 
 			if (itemData->xcood + ((int16)itemData->mouseRelX) > xPos) continue;
 			if (itemData->xcood + ((uint16)itemData->mouseRelX) + XWIDTH < xPos) continue;
-			if (itemData->ycood + ((uint16)itemData->mouseRelX) > yPos) continue;
-			if (itemData->ycood + ((uint16)itemData->mouseRelX) + YDEPTH < yPos) continue;
+			if (itemData->ycood + ((uint16)itemData->mouseRelY) > yPos) continue;
+			if (itemData->ycood + ((uint16)itemData->mouseRelY) + YDEPTH < yPos) continue;
 
 			// record what we're touching
 			Logic::_scriptVariables[SPECIAL_ITEM] = objList[j];
 
 			if (_touchId != objList[j] && !_holding) {
-				debug(1, "New touch\n");
+				debug(1, "New touch");
 				// run previous items get-off, if there was one (gone straight from one object onto another)
 				if (Logic::_scriptVariables[GET_OFF])
 					_skyLogic->mouseScript(Logic::_scriptVariables[GET_OFF], itemData);
@@ -1632,7 +1633,7 @@ void Mouse::lincInvMouse(uint16 xPos, uint16 yPos) {
 		}
 	}
 	// clicked outside the inventory, close it
-	if (!_touchId && _mouseB) {
+	if (!_touchId && buttonHeld) {
 		if (xPos < _invX || xPos > _invX + _invW || yPos < _invY || yPos > _invY + _invH) {
 			_mMode = MUST_RELEASE;
 			_skyLogic->killInventory();




More information about the Scummvm-git-logs mailing list