[Scummvm-git-logs] scummvm branch-2-9 -> 72091a10a6d5331886229b690a1d2b40421986cf

sluicebox noreply at scummvm.org
Tue Nov 26 08:14:39 UTC 2024


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

Summary:
4ad1ed32c9 AGI: PREAGI: Fix TROLL menu numbers
ecbd10ac4f AGI: PREAGI: Fix WINNIE keyboard modifier test
c49ecbb1a6 AGI: PREAGI: Fix menu selection keyboard handling
33ca7baf9b AGI: PREAGI: Fix WINNIE drop-object behavior
ddd160d457 AGI: PREAGI: Fix WINNIE save game message
4e6ea63f6e AGI: PREAGI: Play correct wind sound in WINNIE
8450191e05 AGI: Fix SoundGenPCJr not using sound flag on AGIv1
88f011dc62 AGI: Fix SoundGenPCJr incomplete re-initialization
443630853f AGI: Add thread safety to SoundGenPCJr and SoundGenSarien
998f81f646 AGI: PREAGI: Fix Eeyore not accepting his popped balloon
27df2d7396 AGI: PREAGI: Fix more WINNIE drop-object behavior
c7d528c2b3 AGI: PREAGI: Update WINNIE game loop for reloading room
41cf46ec92 AGI: PREAGI: Make WINNIE wind sounds platform dependent
21313909da AGI: PREAGI: Implement WINNIE Amiga help opcode
1b96e3cf46 AGI: PREAGI: Fix WINNIE Apple II tree house
899f8e6075 AGI: PREAGI: Fix WINNIE wind behavior
b748ca77e2 AGI: PREAGI: Implement WINNIE timer and events
f875af5396 AGI: PREAGI: Fix WINNIE RNG calls
72091a10a6 AGI: PREAGI: Fix WINNIE Amiga object parsing


Commit: 4ad1ed32c9750d3a76006e1e682497257333eeb9
    https://github.com/scummvm/scummvm/commit/4ad1ed32c9750d3a76006e1e682497257333eeb9
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:18-08:00

Commit Message:
AGI: PREAGI: Fix TROLL menu numbers

They are one-based

Changed paths:
    engines/agi/preagi/troll.cpp


diff --git a/engines/agi/preagi/troll.cpp b/engines/agi/preagi/troll.cpp
index d7f64b91557..4edb2e202c8 100644
--- a/engines/agi/preagi/troll.cpp
+++ b/engines/agi/preagi/troll.cpp
@@ -453,7 +453,7 @@ int TrollEngine::drawRoom(char *menu) {
 
 	for (int i = 0; i < 3; i++) {
 		if (_roomDescs[_roomPicture - 1].options[i]) {
-			strncat(menu, Common::String::format("\n  %d.", i).c_str(), 5);
+			strncat(menu, Common::String::format("\n  %d.", i + 1).c_str(), 5);
 
 			strncat(menu, (char *)_gameData + _options[_roomDescs[_roomPicture - 1].options[i] - 1], 35);
 


Commit: ecbd10ac4fceeb730278b5245c7a2fc825fb8c13
    https://github.com/scummvm/scummvm/commit/ecbd10ac4fceeb730278b5245c7a2fc825fb8c13
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:18-08:00

Commit Message:
AGI: PREAGI: Fix WINNIE keyboard modifier test

Fixes help text when number/caps/scroll lock is enabled

Changed paths:
    engines/agi/preagi/winnie.cpp


diff --git a/engines/agi/preagi/winnie.cpp b/engines/agi/preagi/winnie.cpp
index a212f9ab442..bed93ac9ae8 100644
--- a/engines/agi/preagi/winnie.cpp
+++ b/engines/agi/preagi/winnie.cpp
@@ -1018,7 +1018,8 @@ void WinnieEngine::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
 					}
 					break;
 				default:
-					if (!event.kbd.flags) { // if the control/alt/shift keys are not pressed
+					// show help if the control/alt/shift keys are not pressed
+					if (!(event.kbd.flags & Common::KBD_NON_STICKY)) {
 						keyHelp();
 						clrMenuSel(iSel, fCanSel);
 					}


Commit: c49ecbb1a628a362e9bbcf79aa10f1f2af32ace7
    https://github.com/scummvm/scummvm/commit/c49ecbb1a628a362e9bbcf79aa10f1f2af32ace7
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:18-08:00

Commit Message:
AGI: PREAGI: Fix menu selection keyboard handling

Fixes the default-key handler. It was ignoring all keys that are used
in a different selection mode. For example: 'Y', 'N', space, digits,
and others had no effect when prompted to press any key.

Fixes modifiers being treated as normal keys by the menu selection code.
This did not occur in the original, and it caused common ScummVM hotkeys
to affect in-game behavior.

Changed paths:
    engines/agi/preagi/preagi.cpp


diff --git a/engines/agi/preagi/preagi.cpp b/engines/agi/preagi/preagi.cpp
index 8f734eb5966..a6d24be6510 100644
--- a/engines/agi/preagi/preagi.cpp
+++ b/engines/agi/preagi/preagi.cpp
@@ -188,6 +188,9 @@ int PreAgiEngine::getSelection(SelectionTypes type) {
 					return 1;
 				break;
 			case Common::EVENT_KEYDOWN:
+				if (event.kbd.flags & Common::KBD_NON_STICKY) {
+					break;
+				}
 				switch (event.kbd.keycode) {
 				case Common::KEYCODE_y:
 					if (type == kSelYesNo)
@@ -222,15 +225,14 @@ int PreAgiEngine::getSelection(SelectionTypes type) {
 						return 0;
 					break;
 				default:
-					if (event.kbd.flags & Common::KBD_CTRL)
-						break;
-					if (type == kSelYesNo) {
-						return 2;
-					} else if (type == kSelNumber) {
-						return 10;
-					} else if (type == kSelAnyKey || type == kSelBackspace) {
-						return 1;
-					}
+					break;
+				}
+				if (type == kSelYesNo) {
+					return 2;
+				} else if (type == kSelNumber) {
+					return 10;
+				} else if (type == kSelAnyKey || type == kSelBackspace) {
+					return 1;
 				}
 				break;
 			default:


Commit: 33ca7baf9b8a1c887639b858e59859450c24323a
    https://github.com/scummvm/scummvm/commit/33ca7baf9b8a1c887639b858e59859450c24323a
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:19-08:00

Commit Message:
AGI: PREAGI: Fix WINNIE drop-object behavior

- Removes "Ok." message that the original did not display
- Removes wait-on-keypress that was not in the original

Changed paths:
    engines/agi/preagi/winnie.cpp


diff --git a/engines/agi/preagi/winnie.cpp b/engines/agi/preagi/winnie.cpp
index bed93ac9ae8..b7ea1318553 100644
--- a/engines/agi/preagi/winnie.cpp
+++ b/engines/agi/preagi/winnie.cpp
@@ -560,8 +560,6 @@ void WinnieEngine::dropObj(int iRoom) {
 
 		if (isRightObj(iRoom, _gameStateWinnie.iObjHave, &iCode)) {
 			// object has been dropped in the right place
-			printStr(IDS_WTP_OK);
-			getSelection(kSelAnyKey);
 			playSound(IDI_WTP_SND_DROP_OK);
 			printObjStr(_gameStateWinnie.iObjHave, IDI_WTP_OBJ_DROP);
 			getSelection(kSelAnyKey);
@@ -598,11 +596,12 @@ void WinnieEngine::dropObj(int iRoom) {
 
 			// object has been dropped in the wrong place
 			printStr(IDS_WTP_WRONG_PLACE);
-			getSelection(kSelAnyKey);
-
 			playSound(IDI_WTP_SND_DROP);
-			drawRoomPic();
 
+			// draw the object by redrawing the room and
+			// reprinting the message. the original just
+			// drew the object.
+			drawRoomPic();
 			printStr(IDS_WTP_WRONG_PLACE);
 			getSelection(kSelAnyKey);
 


Commit: ddd160d457e9c21c01bdbcc0f19b334972fb73e0
    https://github.com/scummvm/scummvm/commit/ddd160d457e9c21c01bdbcc0f19b334972fb73e0
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:19-08:00

Commit Message:
AGI: PREAGI: Fix WINNIE save game message

Changed paths:
    engines/agi/preagi/winnie.cpp


diff --git a/engines/agi/preagi/winnie.cpp b/engines/agi/preagi/winnie.cpp
index b7ea1318553..86b33600a3d 100644
--- a/engines/agi/preagi/winnie.cpp
+++ b/engines/agi/preagi/winnie.cpp
@@ -428,6 +428,7 @@ int WinnieEngine::parser(int pc, int index, uint8 *buffer) {
 				break;
 			case IDO_WTP_SAVE_GAME:
 				saveGame();
+				getSelection(kSelAnyKey);
 				_room = IDI_WTP_ROOM_HOME;
 				return IDI_WTP_PAR_GOTO;
 			case IDO_WTP_LOAD_GAME:


Commit: 4e6ea63f6e76fb3c58d9efa220c08814a30ffc83
    https://github.com/scummvm/scummvm/commit/4e6ea63f6e76fb3c58d9efa220c08814a30ffc83
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:19-08:00

Commit Message:
AGI: PREAGI: Play correct wind sound in WINNIE

Changed paths:
    engines/agi/preagi/winnie.cpp


diff --git a/engines/agi/preagi/winnie.cpp b/engines/agi/preagi/winnie.cpp
index 86b33600a3d..e77f578b045 100644
--- a/engines/agi/preagi/winnie.cpp
+++ b/engines/agi/preagi/winnie.cpp
@@ -648,11 +648,11 @@ void WinnieEngine::wind() {
 		return;
 
 	printStr(IDS_WTP_WIND_0);
-	playSound(IDI_WTP_SND_WIND_0);
+	playSound(IDI_WTP_SND_WIND_1); // not a bug, IDI_WTP_SND_WIND_0 isn't used here
 	getSelection(kSelAnyKey);
 
 	printStr(IDS_WTP_WIND_1);
-	playSound(IDI_WTP_SND_WIND_0);
+	playSound(IDI_WTP_SND_WIND_1);
 	getSelection(kSelAnyKey);
 
 	dropObjRnd();


Commit: 8450191e05e4476b4aea7a47a4e8890e87992279
    https://github.com/scummvm/scummvm/commit/8450191e05e4476b4aea7a47a4e8890e87992279
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:19-08:00

Commit Message:
AGI: Fix SoundGenPCJr not using sound flag on AGIv1

Fixes the in-game sound setting

Changed paths:
    engines/agi/sound_pcjr.cpp


diff --git a/engines/agi/sound_pcjr.cpp b/engines/agi/sound_pcjr.cpp
index efba2b4b788..75716348f2a 100644
--- a/engines/agi/sound_pcjr.cpp
+++ b/engines/agi/sound_pcjr.cpp
@@ -296,6 +296,9 @@ int SoundGenPCJr::getNextNote_v1(int ch) {
 	byte *data = _v1data;
 	uint32 len = _v1size;
 
+	if (!_vm->getFlag(VM_FLAG_SOUND_ON))
+		return -1;
+
 	if (len <= 0 || data == nullptr) {
 		_channel[ch].avail = 0;
 		_channel[ch].attenuation = 0x0F;


Commit: 88f011dc62cb49ab97c9fafaa54f29c11513f2d1
    https://github.com/scummvm/scummvm/commit/88f011dc62cb49ab97c9fafaa54f29c11513f2d1
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:19-08:00

Commit Message:
AGI: Fix SoundGenPCJr incomplete re-initialization

Fixes incomplete channel re-initialization when playing a sound.
This caused nearly every sound in Winnie the Pooh to randomly
play channels that were supposed to be silent, depending on the
state of the previous sound. The first sound would always play
correctly due to the constructor zeroing out all channel data.

Replaces static variables with class members so that they can be
consistently re-initialized when playing a sound.

Changed paths:
    engines/agi/sound_pcjr.cpp
    engines/agi/sound_pcjr.h


diff --git a/engines/agi/sound_pcjr.cpp b/engines/agi/sound_pcjr.cpp
index 75716348f2a..d3043282553 100644
--- a/engines/agi/sound_pcjr.cpp
+++ b/engines/agi/sound_pcjr.cpp
@@ -123,10 +123,13 @@ SoundGenPCJr::SoundGenPCJr(AgiBase *vm, Audio::Mixer *pMixer) : SoundGen(vm, pMi
 	memset(_channel, 0, sizeof(_channel));
 	memset(_tchannel, 0, sizeof(_tchannel));
 
-	_mixer->playStream(Audio::Mixer::kMusicSoundType, _soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
-
 	_v1data = nullptr;
 	_v1size = 0;
+	_v1duration = 0;
+
+	_reg = 0;
+
+	_mixer->playStream(Audio::Mixer::kMusicSoundType, _soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
 }
 
 SoundGenPCJr::~SoundGenPCJr() {
@@ -145,6 +148,8 @@ void SoundGenPCJr::play(int resnum) {
 		_channel[i].dissolveCount = 0xFFFF;
 		_channel[i].attenuation = 0;
 		_channel[i].attenuationCopy = 0;
+		_channel[i].genType = kGenSilence;
+		_channel[i].freqCount = 0;
 
 		_tchannel[i].avail = 1;
 		_tchannel[i].noteCount = 0;
@@ -153,10 +158,18 @@ void SoundGenPCJr::play(int resnum) {
 		_tchannel[i].atten = 0xF;   // silence
 		_tchannel[i].genType = kGenTone;
 		_tchannel[i].genTypePrev = -1;
+		_tchannel[i].count = 0;
+		_tchannel[i].scale = 0;
+		_tchannel[i].sign = 0;
+		_tchannel[i].noiseState = 0;
+		_tchannel[i].feedback = 0;
 	}
 
 	_v1data = pcjrSound->getData() + 1;
 	_v1size = pcjrSound->getLength() - 1;
+	_v1duration = 0;
+
+	_reg = 0;
 }
 
 void SoundGenPCJr::stop() {
@@ -291,8 +304,6 @@ int SoundGenPCJr::getNextNote_v2(int ch) {
 }
 
 int SoundGenPCJr::getNextNote_v1(int ch) {
-	static int duration = 0;
-
 	byte *data = _v1data;
 	uint32 len = _v1size;
 
@@ -307,11 +318,11 @@ int SoundGenPCJr::getNextNote_v1(int ch) {
 	}
 
 	// In the V1 player the default duration for a row is 3 ticks
-	if (duration > 0) {
-		duration--;
+	if (_v1duration > 0) {
+		_v1duration--;
 		return 0;
 	}
-	duration = 3 * CHAN_MAX;
+	_v1duration = 3 * CHAN_MAX;
 
 	// Otherwise fetch a row of data for all channels
 	while (*data) {
@@ -329,13 +340,11 @@ int SoundGenPCJr::getNextNote_v1(int ch) {
 }
 
 void SoundGenPCJr::writeData(uint8 val) {
-	static int reg = 0;
-
 	debugC(5, kDebugLevelSound, "writeData(%.2X)", val);
 
 	if ((val & 0x90) == 0x90) {
-		reg = (val >> 5) & 0x3;
-		_channel[reg].attenuation = val & 0xF;
+		_reg = (val >> 5) & 0x3;
+		_channel[_reg].attenuation = val & 0xF;
 	} else if ((val & 0xF0) == 0xE0) {
 		_channel[3].genType = (val & 0x4) ? kGenWhite : kGenPeriod;
 		int noiseFreq = val & 0x03;
@@ -356,11 +365,11 @@ void SoundGenPCJr::writeData(uint8 val) {
 			break;
 		}
 	} else if (val & 0x80) {
-		reg = (val >> 5) & 0x3;
-		_channel[reg].freqCount = val & 0xF;
-		_channel[reg].genType = kGenTone;
+		_reg = (val >> 5) & 0x3;
+		_channel[_reg].freqCount = val & 0xF;
+		_channel[_reg].genType = kGenTone;
 	} else {
-		_channel[reg].freqCount |= (val & 0x3F) << 4;
+		_channel[_reg].freqCount |= (val & 0x3F) << 4;
 	}
 }
 
diff --git a/engines/agi/sound_pcjr.h b/engines/agi/sound_pcjr.h
index b236c266ef9..4ffd1fb2b5c 100644
--- a/engines/agi/sound_pcjr.h
+++ b/engines/agi/sound_pcjr.h
@@ -117,6 +117,9 @@ private:
 
 	uint8 *_v1data;
 	uint32 _v1size;
+	int _v1duration;
+
+	int _reg;
 };
 
 } // End of namespace Agi


Commit: 443630853fbf0cb2628205e9b12dde7a2fbba4d8
    https://github.com/scummvm/scummvm/commit/443630853fbf0cb2628205e9b12dde7a2fbba4d8
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:20-08:00

Commit Message:
AGI: Add thread safety to SoundGenPCJr and SoundGenSarien

Fixes unsynchronized access to channel data

Changed paths:
    engines/agi/sound_pcjr.cpp
    engines/agi/sound_pcjr.h
    engines/agi/sound_sarien.cpp
    engines/agi/sound_sarien.h


diff --git a/engines/agi/sound_pcjr.cpp b/engines/agi/sound_pcjr.cpp
index d3043282553..10faa4416f7 100644
--- a/engines/agi/sound_pcjr.cpp
+++ b/engines/agi/sound_pcjr.cpp
@@ -139,6 +139,8 @@ SoundGenPCJr::~SoundGenPCJr() {
 }
 
 void SoundGenPCJr::play(int resnum) {
+	Common::StackLock lock(_mutex);
+
 	PCjrSound *pcjrSound = (PCjrSound *)_vm->_game.sounds[resnum];
 
 	for (int i = 0; i < CHAN_MAX; i++) {
@@ -173,9 +175,9 @@ void SoundGenPCJr::play(int resnum) {
 }
 
 void SoundGenPCJr::stop() {
-	int i;
+	Common::StackLock lock(_mutex);
 
-	for (i = 0; i < CHAN_MAX; i++) {
+	for (int i = 0; i < CHAN_MAX; i++) {
 		_channel[i].avail = 0;
 		_tchannel[i].avail = 0;
 	}
@@ -545,8 +547,7 @@ int SoundGenPCJr::fillNoise(ToneChan *t, int16 *buf, int len) {
 }
 
 int SoundGenPCJr::readBuffer(int16 *stream, const int len) {
-	int streamCount;
-	int16 *sPtr, *cPtr;
+	Common::StackLock lock(_mutex);
 
 	if (_chanAllocated < len) {
 		free(_chanData);
@@ -563,9 +564,9 @@ int SoundGenPCJr::readBuffer(int16 *stream, const int len) {
 		// get channel data(chan.userdata)
 		if (chanGen(i, _chanData, len) == 0) {
 			// divide by number of channels then add to stream
-			streamCount = len;
-			sPtr = stream;
-			cPtr = _chanData;
+			int streamCount = len;
+			int16 *sPtr = stream;
+			int16 *cPtr = _chanData;
 
 			while (streamCount--)
 				*(sPtr++) += *(cPtr++) / CHAN_MAX;
diff --git a/engines/agi/sound_pcjr.h b/engines/agi/sound_pcjr.h
index 4ffd1fb2b5c..b5bc203d4c5 100644
--- a/engines/agi/sound_pcjr.h
+++ b/engines/agi/sound_pcjr.h
@@ -108,6 +108,8 @@ private:
 	int fillSquare(ToneChan *t, int16 *buf, int len);
 
 private:
+	Common::Mutex _mutex;
+	
 	SndGenChan _channel[CHAN_MAX];
 	ToneChan _tchannel[CHAN_MAX];
 	int16 *_chanData;
diff --git a/engines/agi/sound_sarien.cpp b/engines/agi/sound_sarien.cpp
index 912718830b4..f7575d0c6bf 100644
--- a/engines/agi/sound_sarien.cpp
+++ b/engines/agi/sound_sarien.cpp
@@ -122,15 +122,17 @@ SoundGenSarien::~SoundGenSarien() {
 }
 
 int SoundGenSarien::readBuffer(int16 *buffer, const int numSamples) {
+	Common::StackLock lock(_mutex);
+
 	fillAudio(buffer, numSamples / 2);
 
 	return numSamples;
 }
 
 void SoundGenSarien::play(int resnum) {
-	AgiSoundEmuType type;
+	Common::StackLock lock(_mutex);
 
-	type = (AgiSoundEmuType)_vm->_game.sounds[resnum]->type();
+	AgiSoundEmuType type = (AgiSoundEmuType)_vm->_game.sounds[resnum]->type();
 
 	assert(type == AGI_SOUND_4CHN);
 
@@ -160,6 +162,8 @@ void SoundGenSarien::play(int resnum) {
 }
 
 void SoundGenSarien::stop() {
+	Common::StackLock lock(_mutex);
+
 	_playingSound = -1;
 
 	for (int i = 0; i < NUM_CHANNELS; i++)
diff --git a/engines/agi/sound_sarien.h b/engines/agi/sound_sarien.h
index e76071b63e0..1ebae491134 100644
--- a/engines/agi/sound_sarien.h
+++ b/engines/agi/sound_sarien.h
@@ -90,6 +90,8 @@ public:
 	}
 
 private:
+	Common::Mutex _mutex;
+
 	ChannelInfo _chn[NUM_CHANNELS];
 	uint8 _env;
 


Commit: 998f81f646aaa638f318b8b3ed06ebfb8d726c53
    https://github.com/scummvm/scummvm/commit/998f81f646aaa638f318b8b3ed06ebfb8d726c53
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:20-08:00

Commit Message:
AGI: PREAGI: Fix Eeyore not accepting his popped balloon

He loves it!

Changed paths:
    engines/agi/preagi/winnie.cpp


diff --git a/engines/agi/preagi/winnie.cpp b/engines/agi/preagi/winnie.cpp
index e77f578b045..c8b78937942 100644
--- a/engines/agi/preagi/winnie.cpp
+++ b/engines/agi/preagi/winnie.cpp
@@ -508,9 +508,23 @@ bool WinnieEngine::isRightObj(int iRoom, int iObj, int *iCode) {
 	free(roomdata);
 	free(objdata);
 
+	// must return the object id before the workarounds are applied below.
+	// dropping the board (objId 34) must set flag 34 to change the room
+	// above the bridge, but the pine cones and sticks (objId 11) must not.
 	*iCode = objhdr.objId;
 
-	if (objhdr.objId == 11) objhdr.objId = 34;
+	// The pine cones and sticks have an id that does not exist in any room.
+	// The game worked around this by using the correct id for the bridge.
+	if (objhdr.objId == 11) {
+		objhdr.objId = 34; // bridge
+	}
+
+	// Eeyore's popped balloon is assigned to Piglet in the data file.
+	// The game's executable must contain a hard-coded workaround,
+	// because the balloon is correctly assigned to Eeyore at runtime.
+	if (iObj == 25 && objhdr.objId == 8) { // popped balloon, Piglet
+		objhdr.objId = 7; // Eeyore
+	}
 
 	if (roomhdr.objId == objhdr.objId)
 		return true;
@@ -539,7 +553,7 @@ void WinnieEngine::takeObj(int iRoom) {
 		printObjStr(_gameStateWinnie.iObjHave, IDI_WTP_OBJ_TAKE);
 		getSelection(kSelAnyKey);
 
-		// HACK WARNING
+		// set the has-lantern flag when taking the lantern
 		if (iObj == 18) {
 			_gameStateWinnie.fGame[0x0d] = 1;
 		}
@@ -554,7 +568,7 @@ void WinnieEngine::dropObj(int iRoom) {
 		printStr(IDS_WTP_CANT_DROP);
 		getSelection(kSelAnyKey);
 	} else {
-		// HACK WARNING
+		// clear the has-lantern flag when dropping the lantern
 		if (_gameStateWinnie.iObjHave == 18) {
 			_gameStateWinnie.fGame[0x0d] = 0;
 		}


Commit: 27df2d73965558154612b64d307a844897aaf90e
    https://github.com/scummvm/scummvm/commit/27df2d73965558154612b64d307a844897aaf90e
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:20-08:00

Commit Message:
AGI: PREAGI: Fix more WINNIE drop-object behavior

Fixes menu options after giving Pooh or Kanga their first object.

Fixes climbing the tree after dropping the board in the bridge.

Changed paths:
    engines/agi/preagi/winnie.cpp
    engines/agi/preagi/winnie.h


diff --git a/engines/agi/preagi/winnie.cpp b/engines/agi/preagi/winnie.cpp
index c8b78937942..76b9b1abdb6 100644
--- a/engines/agi/preagi/winnie.cpp
+++ b/engines/agi/preagi/winnie.cpp
@@ -367,10 +367,15 @@ int WinnieEngine::parser(int pc, int index, uint8 *buffer) {
 				takeObj(_room);
 				setTakeDrop(fCanSel);
 				break;
-			case IDI_WTP_SEL_DROP:
-				dropObj(_room);
+			case IDI_WTP_SEL_DROP: {
+				bool droppedInRightRoom = dropObj(_room);
 				setTakeDrop(fCanSel);
+				if (droppedInRightRoom) {
+					// reload room so that the dropped object's flag takes effect
+					return IDI_WTP_PAR_OK;
+				}
 				break;
+			}
 			default:
 				break;
 			}
@@ -560,7 +565,8 @@ void WinnieEngine::takeObj(int iRoom) {
 	}
 }
 
-void WinnieEngine::dropObj(int iRoom) {
+// returns true if object was dropped in the right room
+bool WinnieEngine::dropObj(int iRoom) {
 	int iCode;
 
 	if (getObjInRoom(iRoom)) {
@@ -605,6 +611,7 @@ void WinnieEngine::dropObj(int iRoom) {
 				printStr(IDS_WTP_GAME_OVER_1);
 				getSelection(kSelAnyKey);
 			}
+			return true; // object dropped in right room
 		} else {
 			// drop object in the given room
 			_gameStateWinnie.iObjRoom[_gameStateWinnie.iObjHave] = iRoom;
@@ -627,6 +634,7 @@ void WinnieEngine::dropObj(int iRoom) {
 			_gameStateWinnie.iObjHave = 0;
 		}
 	}
+	return false; // object not dropped in right room
 }
 
 void WinnieEngine::dropObjRnd() {
diff --git a/engines/agi/preagi/winnie.h b/engines/agi/preagi/winnie.h
index 2ece0045ff5..81953655542 100644
--- a/engines/agi/preagi/winnie.h
+++ b/engines/agi/preagi/winnie.h
@@ -327,7 +327,7 @@ private:
 	void printObjStr(int, int);
 	uint32 readObj(int, uint8 *);
 	void takeObj(int);
-	void dropObj(int);
+	bool dropObj(int);
 	bool isRightObj(int, int, int *);
 	void drawObjPic(int, int, int);
 	void getMenuMouseSel(int *, int[], int, int);


Commit: c7d528c2b3a3cd3eed348ad48c840e91d203746d
    https://github.com/scummvm/scummvm/commit/c7d528c2b3a3cd3eed348ad48c840e91d203746d
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:20-08:00

Commit Message:
AGI: PREAGI: Update WINNIE game loop for reloading room

Follow-up to: 2258c07929b21d9e2a662e8f28c3c2f732ae084b

Changed paths:
    engines/agi/preagi/winnie.cpp
    engines/agi/preagi/winnie.h


diff --git a/engines/agi/preagi/winnie.cpp b/engines/agi/preagi/winnie.cpp
index 76b9b1abdb6..2a211e24766 100644
--- a/engines/agi/preagi/winnie.cpp
+++ b/engines/agi/preagi/winnie.cpp
@@ -372,7 +372,7 @@ int WinnieEngine::parser(int pc, int index, uint8 *buffer) {
 				setTakeDrop(fCanSel);
 				if (droppedInRightRoom) {
 					// reload room so that the dropped object's flag takes effect
-					return IDI_WTP_PAR_OK;
+					return IDI_WTP_PAR_RELOAD;
 				}
 				break;
 			}
@@ -1104,6 +1104,10 @@ void WinnieEngine::gameLoop() {
 					decodePhase = 2;
 					break;
 				}
+				if (result == IDI_WTP_PAR_RELOAD) {
+					// start over at block zero
+					break;
+				}
 			}
 		}
 	}
diff --git a/engines/agi/preagi/winnie.h b/engines/agi/preagi/winnie.h
index 81953655542..44e3b2e0c11 100644
--- a/engines/agi/preagi/winnie.h
+++ b/engines/agi/preagi/winnie.h
@@ -227,7 +227,8 @@ enum {
 enum {
 	IDI_WTP_PAR_OK = 0,
 	IDI_WTP_PAR_GOTO,
-	IDI_WTP_PAR_BACK
+	IDI_WTP_PAR_BACK,
+	IDI_WTP_PAR_RELOAD
 };
 
 // room file option block


Commit: 41cf46ec92da0eef9164ec4c380edb9d76905ead
    https://github.com/scummvm/scummvm/commit/41cf46ec92da0eef9164ec4c380edb9d76905ead
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:21-08:00

Commit Message:
AGI: PREAGI: Make WINNIE wind sounds platform dependent

Confirmed in disassembly

Changed paths:
    engines/agi/preagi/winnie.cpp


diff --git a/engines/agi/preagi/winnie.cpp b/engines/agi/preagi/winnie.cpp
index 2a211e24766..88c3b73c875 100644
--- a/engines/agi/preagi/winnie.cpp
+++ b/engines/agi/preagi/winnie.cpp
@@ -670,11 +670,11 @@ void WinnieEngine::wind() {
 		return;
 
 	printStr(IDS_WTP_WIND_0);
-	playSound(IDI_WTP_SND_WIND_1); // not a bug, IDI_WTP_SND_WIND_0 isn't used here
+	playSound(IDI_WTP_SND_WIND_0);
 	getSelection(kSelAnyKey);
 
 	printStr(IDS_WTP_WIND_1);
-	playSound(IDI_WTP_SND_WIND_1);
+	playSound(IDI_WTP_SND_WIND_0);
 	getSelection(kSelAnyKey);
 
 	dropObjRnd();
@@ -1190,6 +1190,12 @@ bool WinnieEngine::playSound(ENUM_WTP_SOUND iSound) {
 		return false;
 	}
 
+	// DOS version tests a platform global to choose the wind sound.
+	// Sound 10 is designed for PCJr, sound 11 for PC Speaker.
+	if (iSound == IDI_WTP_SND_WIND_0 && _soundemu == SOUND_EMU_PC) {
+		iSound = IDI_WTP_SND_WIND_1;
+	}
+
 	Common::Path fileName(Common::String::format(IDS_WTP_SND_DOS, iSound));
 
 	Common::File file;


Commit: 21313909dadc9e48e2468113f9bcd4b5cdbcfeeb
    https://github.com/scummvm/scummvm/commit/21313909dadc9e48e2468113f9bcd4b5cdbcfeeb
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:21-08:00

Commit Message:
AGI: PREAGI: Implement WINNIE Amiga help opcode

Fixes teleporting to a random room instead of displaying help messages

Changed paths:
    engines/agi/preagi/winnie.cpp
    engines/agi/preagi/winnie.h


diff --git a/engines/agi/preagi/winnie.cpp b/engines/agi/preagi/winnie.cpp
index 88c3b73c875..9db9f1f45f3 100644
--- a/engines/agi/preagi/winnie.cpp
+++ b/engines/agi/preagi/winnie.cpp
@@ -445,6 +445,12 @@ int WinnieEngine::parser(int pc, int index, uint8 *buffer) {
 				showOwlHelp();
 				break;
 			case IDO_WTP_GOTO_RND:
+				// Amiga changed opcode 1E to display its very long
+				// platform-specific help messages in the first room
+				if (getPlatform() == Common::kPlatformAmiga) {
+					showAmigaHelp();
+					break;
+				}
 				_room = rnd(IDI_WTP_MAX_ROOM_TELEPORT) + 1;
 				return IDI_WTP_PAR_GOTO;
 			default:
@@ -732,6 +738,13 @@ void WinnieEngine::showOwlHelp() {
 	}
 }
 
+void WinnieEngine::showAmigaHelp() {
+	// print edited versions of Amiga help text that fit in four lines
+	printStr(IDS_WTP_AMIGA_HELP_EDITED_0);
+	getSelection(kSelAnyKey);
+	printStr(IDS_WTP_AMIGA_HELP_EDITED_1);
+	getSelection(kSelAnyKey);
+}
 
 void WinnieEngine::drawMenu(char *szMenu, int iSel, int fCanSel[]) {
 	int iRow = 0, iCol = 0;
diff --git a/engines/agi/preagi/winnie.h b/engines/agi/preagi/winnie.h
index 44e3b2e0c11..fd45107a37f 100644
--- a/engines/agi/preagi/winnie.h
+++ b/engines/agi/preagi/winnie.h
@@ -89,6 +89,14 @@ namespace Agi {
 #define IDS_WTP_HELP_1_C64          "<F3> takes you back to the playroom (if you get lost, or want to save the game).<F5> turns the sound off and on.        <F7> shows what you're carrying."
 #define IDS_WTP_WRONG_PLACE_C64 "\nOk, but this is not the right place."
 
+// Amiga strings
+
+// original strings from the executable and edited versions for our four-line interface
+#define IDS_WTP_AMIGA_HELP_0          "Use the mouse to select your choice from\nthe bottom of the screen or the menu.\n\nTo use the keyboard instead of the\nmouse, press the NUMBER or first LETTER\nof what you want."
+#define IDS_WTP_AMIGA_HELP_1          "From the keyboard you can also press:\n  'l' to look at the scene you're in.\n  'o' to look at an object in the room.\n  'c' to see what you're carrying and\n        how you're doing.\n  CTRL-S to turn the sound on or off."
+#define IDS_WTP_AMIGA_HELP_EDITED_0   "Use the mouse to select your choice fromthe bottom of the screen or the menu.\nTo use the keyboard instead of the\nmouse, press the NUMBER or first LETTER."
+#define IDS_WTP_AMIGA_HELP_EDITED_1   "From the keyboard you can also press:\n  <C> to see what you're carrying and\n      how you're doing.\n  <CTRL-S> to turn the sound on or off."
+
 // maximum values
 
 #define IDI_WTP_MAX_OBJ_MISSING 10
@@ -346,6 +354,7 @@ private:
 	void tigger();
 
 	void showOwlHelp();
+	void showAmigaHelp();
 	bool playSound(ENUM_WTP_SOUND);
 
 	void printStrWinnie(char *szMsg);


Commit: 1b96e3cf465f69bc691bbf06dca8f571f415814d
    https://github.com/scummvm/scummvm/commit/1b96e3cf465f69bc691bbf06dca8f571f415814d
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:21-08:00

Commit Message:
AGI: PREAGI: Fix WINNIE Apple II tree house

Fixes messages and flags when exiting Christopher Robin's tree house

Changed paths:
    engines/agi/preagi/winnie.cpp


diff --git a/engines/agi/preagi/winnie.cpp b/engines/agi/preagi/winnie.cpp
index 9db9f1f45f3..edf761b9313 100644
--- a/engines/agi/preagi/winnie.cpp
+++ b/engines/agi/preagi/winnie.cpp
@@ -394,6 +394,16 @@ int WinnieEngine::parser(int pc, int index, uint8 *buffer) {
 			case IDO_WTP_GOTO_ROOM:
 				opcode = *(buffer + pc++);
 				iNewRoom = opcode;
+
+				// Apple II is missing a zero terminator in one script block of
+				// Christopher Robin's tree house. The room file was fixed in
+				// later versions, and the Apple II version behaves correctly,
+				// so the code must contain a workaround to prevent executing
+				// the next script block before exiting the room.
+				if (_room == 38 && getPlatform() == Common::kPlatformApple2) {
+					_room = iNewRoom; 
+					return IDI_WTP_PAR_GOTO; // change rooms immediately
+				}
 				break;
 			case IDO_WTP_PRINT_MSG:
 				opcode = *(buffer + pc++);


Commit: 899f8e6075c1bd5e9ec4d6e78e5633704690fd46
    https://github.com/scummvm/scummvm/commit/899f8e6075c1bd5e9ec4d6e78e5633704690fd46
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:21-08:00

Commit Message:
AGI: PREAGI: Fix WINNIE wind behavior

Wind is not supposed to drop the inventory object

Changed paths:
    engines/agi/preagi/winnie.cpp


diff --git a/engines/agi/preagi/winnie.cpp b/engines/agi/preagi/winnie.cpp
index edf761b9313..c517c1ec027 100644
--- a/engines/agi/preagi/winnie.cpp
+++ b/engines/agi/preagi/winnie.cpp
@@ -693,11 +693,13 @@ void WinnieEngine::wind() {
 	playSound(IDI_WTP_SND_WIND_0);
 	getSelection(kSelAnyKey);
 
-	dropObjRnd();
-
 	// randomize positions of objects at large
 	for (int i = 0; i < IDI_WTP_MAX_OBJ_MISSING; i++) {
 		if (!(_gameStateWinnie.iUsedObj[i] & IDI_XOR_KEY)) {
+			if (_gameStateWinnie.iUsedObj[i] == _gameStateWinnie.iObjHave) {
+				continue; // skip inventory object
+			}
+
 			done = false;
 			while (!done) {
 				iRoom = rnd(IDI_WTP_MAX_ROOM_NORMAL);


Commit: b748ca77e21a1561251193f49b519bc6e31aaa01
    https://github.com/scummvm/scummvm/commit/b748ca77e21a1561251193f49b519bc6e31aaa01
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:22-08:00

Commit Message:
AGI: PREAGI: Implement WINNIE timer and events

Tigger and mist now appear

Also fixes menu screens consuming 100% CPU

Changed paths:
    engines/agi/preagi/winnie.cpp
    engines/agi/preagi/winnie.h


diff --git a/engines/agi/preagi/winnie.cpp b/engines/agi/preagi/winnie.cpp
index c517c1ec027..ac68cc92f6c 100644
--- a/engines/agi/preagi/winnie.cpp
+++ b/engines/agi/preagi/winnie.cpp
@@ -314,21 +314,20 @@ int WinnieEngine::parser(int pc, int index, uint8 *buffer) {
 			// get menu selection
 			getMenuSel(szMenu, &iSel, fCanSel);
 
-			if (++_gameStateWinnie.nMoves == IDI_WTP_MAX_MOVES_UNTIL_WIND)
-				_doWind = true;
-
-			if (_winnieEvent && (_room <= IDI_WTP_MAX_ROOM_TELEPORT)) {
-				if (!_tiggerMist) {
-					_tiggerMist = 1;
+			if (iSel == IDI_WTP_SEL_TIMER_EVENT) {
+				stopTimer();
+				if (!_tiggerOrMist) {
 					tigger();
 				} else {
-					_tiggerMist = 0;
 					mist();
 				}
-				_winnieEvent = false;
+				_tiggerOrMist = !_tiggerOrMist;
 				return IDI_WTP_PAR_GOTO;
 			}
 
+			if (++_gameStateWinnie.nMoves == IDI_WTP_MAX_MOVES_UNTIL_WIND)
+				_doWind = true;
+
 			// process selection
 			switch (iSel) {
 			case IDI_WTP_SEL_HOME:
@@ -433,6 +432,7 @@ int WinnieEngine::parser(int pc, int index, uint8 *buffer) {
 			case IDO_WTP_WALK_MIST:
 				_mist--;
 				if (!_mist) {
+					startTimer();
 					_room = rnd(IDI_WTP_MAX_ROOM_TELEPORT) + 1;
 					return IDI_WTP_PAR_GOTO;
 				}
@@ -461,6 +461,7 @@ int WinnieEngine::parser(int pc, int index, uint8 *buffer) {
 					showAmigaHelp();
 					break;
 				}
+				startTimer();
 				_room = rnd(IDI_WTP_MAX_ROOM_TELEPORT) + 1;
 				return IDI_WTP_PAR_GOTO;
 			default:
@@ -474,6 +475,13 @@ int WinnieEngine::parser(int pc, int index, uint8 *buffer) {
 			return IDI_WTP_PAR_GOTO;
 		}
 
+		if (_room == IDI_WTP_ROOM_TIGGER && getPlatform() == Common::kPlatformAmiga) {
+			// Amiga removed Tigger's opcode that goes to a random room
+			startTimer();
+			_room = rnd(IDI_WTP_MAX_ROOM_TELEPORT) + 1;
+			return IDI_WTP_PAR_GOTO;
+		}
+
 		if (iBlock == 1)
 			return IDI_WTP_PAR_OK;
 		_system->updateScreen();
@@ -720,21 +728,32 @@ void WinnieEngine::mist() {
 	// mist length in turns is (2-5)
 	_mist = rnd(4) + 2;
 
+	printStr(IDS_WTP_MIST);
+	getSelection(kSelAnyKey);
+
 	_room = IDI_WTP_ROOM_MIST;
 	drawRoomPic();
-
-	printStr(IDS_WTP_MIST);
 }
 
 void WinnieEngine::tigger() {
-	_room = IDI_WTP_ROOM_TIGGER;
+	printStr(IDS_WTP_TIGGER);
+	getSelection(kSelAnyKey);
 
+	_room = IDI_WTP_ROOM_TIGGER;
 	drawRoomPic();
-	printStr(IDS_WTP_TIGGER);
 
 	dropObjRnd();
 }
 
+void WinnieEngine::startTimer() {
+	_timerEnabled = true;
+	_timerStart = _system->getMillis();
+}
+
+void WinnieEngine::stopTimer() {
+	_timerEnabled = false;
+}
+
 void WinnieEngine::showOwlHelp() {
 	if (_gameStateWinnie.iObjHave) {
 		printStr(IDS_WTP_OWL_0);
@@ -1079,6 +1098,15 @@ void WinnieEngine::getMenuSel(char *szMenu, int *iSel, int fCanSel[]) {
 
 			drawMenu(szMenu, *iSel, fCanSel);
 		}
+
+		_system->delayMillis(10);
+		
+		if (_timerEnabled &&
+			_system->getMillis() - _timerStart >= IDI_WTP_TIMER_INTERVAL &&
+			_room <= IDI_WTP_MAX_ROOM_TELEPORT) {
+			*iSel = IDI_WTP_SEL_TIMER_EVENT;
+			return;
+		}
 	}
 }
 
@@ -1088,10 +1116,14 @@ void WinnieEngine::gameLoop() {
 	int iBlock;
 	uint8 decodePhase = 0;
 
+	startTimer();
+
 	while (!shouldQuit()) {
 		if (decodePhase == 0) {
-			if (!_gameStateWinnie.nObjMiss && (_room == IDI_WTP_ROOM_PICNIC))
+			if (!_gameStateWinnie.nObjMiss && (_room == IDI_WTP_ROOM_PICNIC)) {
 				_room = IDI_WTP_ROOM_PARTY;
+				stopTimer();
+			}
 
 			readRoom(_room, roomdata, hdr);
 			drawRoomPic();
@@ -1448,7 +1480,8 @@ void WinnieEngine::init() {
 
 	_mist = -1;
 	_doWind = false;
-	_winnieEvent = false;
+	_tiggerOrMist = false; // tigger appears first
+	stopTimer(); // timer starts after intro
 
 	if (getPlatform() != Common::kPlatformAmiga) {
 		_isBigEndian = false;
diff --git a/engines/agi/preagi/winnie.h b/engines/agi/preagi/winnie.h
index fd45107a37f..41170ddd3c4 100644
--- a/engines/agi/preagi/winnie.h
+++ b/engines/agi/preagi/winnie.h
@@ -118,6 +118,8 @@ namespace Agi {
 #define IDI_WTP_MAX_DIR                 4
 #define IDI_WTP_MAX_MOVES_UNTIL_WIND    150
 
+#define IDI_WTP_TIMER_INTERVAL          (10 * 60 * 1000) // 10 minutes on DOS
+
 // positions
 
 #define IDI_WTP_ROW_MENU        21
@@ -166,7 +168,8 @@ enum {
 	IDI_WTP_SEL_DROP,
 	IDI_WTP_SEL_REAL_OPT_1,
 	IDI_WTP_SEL_REAL_OPT_2,
-	IDI_WTP_SEL_REAL_OPT_3
+	IDI_WTP_SEL_REAL_OPT_3,
+	IDI_WTP_SEL_TIMER_EVENT
 };
 
 #define IDI_WTP_SEL_LAST    IDI_WTP_SEL_REAL_OPT_3
@@ -304,8 +307,9 @@ private:
 	int _room;
 	int _mist;
 	bool _doWind;
-	bool _winnieEvent;
-	int _tiggerMist;
+	bool _tiggerOrMist;
+	bool _timerEnabled;
+	uint32 _timerStart;
 
 	int _roomOffset;
 	int _objOffset;
@@ -352,6 +356,8 @@ private:
 	void wind();
 	void mist();
 	void tigger();
+	void startTimer();
+	void stopTimer();
 
 	void showOwlHelp();
 	void showAmigaHelp();


Commit: f875af5396bf4c9ce481ac385da93bee86ccfef4
    https://github.com/scummvm/scummvm/commit/f875af5396bf4c9ce481ac385da93bee86ccfef4
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:22-08:00

Commit Message:
AGI: PREAGI: Fix WINNIE RNG calls

- Fixes Rabbit's turnip sign never appearing
- Fixes number of walks through mist
- Fixes teleporting up a tree after Tigger or mist

Changed paths:
    engines/agi/preagi/preagi.cpp
    engines/agi/preagi/preagi.h
    engines/agi/preagi/winnie.cpp


diff --git a/engines/agi/preagi/preagi.cpp b/engines/agi/preagi/preagi.cpp
index a6d24be6510..e2260fe86f1 100644
--- a/engines/agi/preagi/preagi.cpp
+++ b/engines/agi/preagi/preagi.cpp
@@ -83,8 +83,8 @@ PreAgiEngine::~PreAgiEngine() {
 	delete _font;
 }
 
-int PreAgiEngine::rnd(int hi) {
-	return (_rnd->getRandomNumber(hi - 1) + 1);
+int PreAgiEngine::rnd(int max) {
+	return (_rnd->getRandomNumber(max - 1) + 1);
 }
 
 // Screen functions
diff --git a/engines/agi/preagi/preagi.h b/engines/agi/preagi/preagi.h
index 2175e4b7af1..56f510e71f2 100644
--- a/engines/agi/preagi/preagi.h
+++ b/engines/agi/preagi/preagi.h
@@ -89,7 +89,8 @@ protected:
 	// Keyboard
 	int getSelection(SelectionTypes type);
 
-	int rnd(int hi);
+	// Random number between 1 and max. Example: rnd(2) returns 1 or 2.
+	int rnd(int max);
 
 	// Text
 	void drawStr(int row, int col, int attr, const char *buffer);
diff --git a/engines/agi/preagi/winnie.cpp b/engines/agi/preagi/winnie.cpp
index ac68cc92f6c..972d1fe1923 100644
--- a/engines/agi/preagi/winnie.cpp
+++ b/engines/agi/preagi/winnie.cpp
@@ -158,7 +158,7 @@ void WinnieEngine::randomize() {
 		done = false;
 
 		while (!done) {
-			iObj = rnd(IDI_WTP_MAX_OBJ - 1);
+			iObj = rnd(IDI_WTP_MAX_OBJ); // 1-40
 			done = true;
 
 			for (int j = 0; j < IDI_WTP_MAX_OBJ_MISSING; j++) {
@@ -173,7 +173,7 @@ void WinnieEngine::randomize() {
 
 		done = false;
 		while (!done) {
-			iRoom = rnd(IDI_WTP_MAX_ROOM_NORMAL);
+			iRoom = rnd(IDI_WTP_MAX_ROOM_NORMAL); // 1-57
 			done = true;
 
 			for (int j = 0; j < IDI_WTP_MAX_ROOM_OBJ; j++) {
@@ -433,7 +433,7 @@ int WinnieEngine::parser(int pc, int index, uint8 *buffer) {
 				_mist--;
 				if (!_mist) {
 					startTimer();
-					_room = rnd(IDI_WTP_MAX_ROOM_TELEPORT) + 1;
+					_room = rnd(IDI_WTP_MAX_ROOM_TELEPORT); // 1-30
 					return IDI_WTP_PAR_GOTO;
 				}
 				break;
@@ -462,7 +462,7 @@ int WinnieEngine::parser(int pc, int index, uint8 *buffer) {
 					break;
 				}
 				startTimer();
-				_room = rnd(IDI_WTP_MAX_ROOM_TELEPORT) + 1;
+				_room = rnd(IDI_WTP_MAX_ROOM_TELEPORT); // 1-30
 				return IDI_WTP_PAR_GOTO;
 			default:
 				opcode = 0;
@@ -478,7 +478,7 @@ int WinnieEngine::parser(int pc, int index, uint8 *buffer) {
 		if (_room == IDI_WTP_ROOM_TIGGER && getPlatform() == Common::kPlatformAmiga) {
 			// Amiga removed Tigger's opcode that goes to a random room
 			startTimer();
-			_room = rnd(IDI_WTP_MAX_ROOM_TELEPORT) + 1;
+			_room = rnd(IDI_WTP_MAX_ROOM_TELEPORT); // 1-30
 			return IDI_WTP_PAR_GOTO;
 		}
 
@@ -669,7 +669,7 @@ void WinnieEngine::dropObjRnd() {
 	bool done = false;
 
 	while (!done) {
-		iRoom = rnd(IDI_WTP_MAX_ROOM_NORMAL);
+		iRoom = rnd(IDI_WTP_MAX_ROOM_NORMAL); // 1-57
 		done = true;
 		if (iRoom == _room)
 			done = false;
@@ -710,7 +710,7 @@ void WinnieEngine::wind() {
 
 			done = false;
 			while (!done) {
-				iRoom = rnd(IDI_WTP_MAX_ROOM_NORMAL);
+				iRoom = rnd(IDI_WTP_MAX_ROOM_NORMAL); // 1-57
 				done = true;
 
 				for (int j = 0; j < IDI_WTP_MAX_ROOM_OBJ; j++) {
@@ -725,8 +725,7 @@ void WinnieEngine::wind() {
 }
 
 void WinnieEngine::mist() {
-	// mist length in turns is (2-5)
-	_mist = rnd(4) + 2;
+	_mist = 1 + rnd(4); // 2-5 walks through the mist
 
 	printStr(IDS_WTP_MIST);
 	getSelection(kSelAnyKey);


Commit: 72091a10a6d5331886229b690a1d2b40421986cf
    https://github.com/scummvm/scummvm/commit/72091a10a6d5331886229b690a1d2b40421986cf
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2024-11-26T00:13:22-08:00

Commit Message:
AGI: PREAGI: Fix WINNIE Amiga object parsing

Fixes objects never being accepted
Fixes talking to Owl

Changed paths:
    engines/agi/preagi/winnie.cpp


diff --git a/engines/agi/preagi/winnie.cpp b/engines/agi/preagi/winnie.cpp
index 972d1fe1923..1f42ddb7d4c 100644
--- a/engines/agi/preagi/winnie.cpp
+++ b/engines/agi/preagi/winnie.cpp
@@ -74,8 +74,9 @@ void WinnieEngine::parseObjHeader(WTP_OBJ_HDR *objHdr, byte *buffer, int len) {
 
 	Common::MemoryReadStreamEndian readS(buffer, len, _isBigEndian);
 
-	objHdr->fileLen = readS.readUint16();
-	objHdr->objId = readS.readUint16();
+	// these two values are always little endian, even on Amiga
+	objHdr->fileLen = readS.readUint16LE();
+	objHdr->objId = readS.readUint16LE();
 
 	for (i = 0; i < IDI_WTP_MAX_OBJ_STR_END; i++)
 		objHdr->ofsEndStr[i] = readS.readUint16();




More information about the Scummvm-git-logs mailing list