[Scummvm-git-logs] scummvm master -> 39ad93d738e46a3af8f7bd3c75bbb0ac6e058b11

sev- sev at scummvm.org
Sun Aug 26 12:09:47 CEST 2018


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

Summary:
f771fa40ad LASTEXPRESS: multiple fixes in NPC logic
39ad93d738 LASTEXPRESS: fix gcc build


Commit: f771fa40ad474d78d32ce5bff67afc937547e5de
    https://github.com/scummvm/scummvm/commit/f771fa40ad474d78d32ce5bff67afc937547e5de
Author: Evgeny Grechnikov (diamondaz at yandex.ru)
Date: 2018-08-26T12:09:43+02:00

Commit Message:
LASTEXPRESS: multiple fixes in NPC logic

Checked the logic against the original game
(to be precise, DOS English version from GOG, although I think
AI logic has no significant differences with other versions).
Fixed a *lot* of errors with varying visibility for the user.

Also, save+exit+load sometimes resulted in memory corruption like
((EntityParametersSSII*)(new EntityParametersIIII))->param8 = 0;
load operation did not restore the correct type of NPC logic context,
the default one was used (which also has the smallest sizeof).
Should be fixed now. Save+load is still unusable because it locks
everybody waiting for kActionEndSound (the sound state is not restored),
but, at least, it should not corrupt the memory. Hopefully.

Changed paths:
    engines/lastexpress/debug.cpp
    engines/lastexpress/entities/abbot.cpp
    engines/lastexpress/entities/alexei.cpp
    engines/lastexpress/entities/alexei.h
    engines/lastexpress/entities/alouan.cpp
    engines/lastexpress/entities/anna.cpp
    engines/lastexpress/entities/august.cpp
    engines/lastexpress/entities/boutarel.cpp
    engines/lastexpress/entities/chapters.cpp
    engines/lastexpress/entities/cooks.cpp
    engines/lastexpress/entities/coudert.cpp
    engines/lastexpress/entities/entity.cpp
    engines/lastexpress/entities/entity.h
    engines/lastexpress/entities/francois.cpp
    engines/lastexpress/entities/gendarmes.cpp
    engines/lastexpress/entities/hadija.cpp
    engines/lastexpress/entities/ivo.cpp
    engines/lastexpress/entities/kahina.cpp
    engines/lastexpress/entities/kronos.cpp
    engines/lastexpress/entities/mahmud.cpp
    engines/lastexpress/entities/max.cpp
    engines/lastexpress/entities/mertens.cpp
    engines/lastexpress/entities/mertens.h
    engines/lastexpress/entities/milos.cpp
    engines/lastexpress/entities/mmeboutarel.cpp
    engines/lastexpress/entities/pascale.cpp
    engines/lastexpress/entities/rebecca.cpp
    engines/lastexpress/entities/salko.cpp
    engines/lastexpress/entities/sophie.cpp
    engines/lastexpress/entities/tatiana.cpp
    engines/lastexpress/entities/train.cpp
    engines/lastexpress/entities/vassili.cpp
    engines/lastexpress/entities/verges.cpp
    engines/lastexpress/entities/vesna.cpp
    engines/lastexpress/entities/waiter1.cpp
    engines/lastexpress/entities/waiter2.cpp
    engines/lastexpress/entities/yasmin.cpp
    engines/lastexpress/game/entities.cpp
    engines/lastexpress/game/savegame.cpp
    engines/lastexpress/game/savepoint.cpp
    engines/lastexpress/game/savepoint.h
    engines/lastexpress/game/state.h
    engines/lastexpress/shared.h
    engines/lastexpress/sound/entry.cpp
    engines/lastexpress/sound/entry.h
    engines/lastexpress/sound/queue.cpp
    engines/lastexpress/sound/sound.cpp


diff --git a/engines/lastexpress/debug.cpp b/engines/lastexpress/debug.cpp
index a6cecc7..dec57a4 100644
--- a/engines/lastexpress/debug.cpp
+++ b/engines/lastexpress/debug.cpp
@@ -487,10 +487,7 @@ bool Debugger::cmdPlaySeq(int argc, const char **argv) {
 
 					// Handle right-click to interrupt sequence
 					Common::Event ev;
-					if (!_engine->getEventManager()->pollEvent(ev))
-						break;
-
-					if (ev.type == Common::EVENT_RBUTTONUP)
+					if (_engine->getEventManager()->pollEvent(ev) && ev.type == Common::EVENT_RBUTTONUP)
 						break;
 
 					_engine->_system->delayMillis(175);
diff --git a/engines/lastexpress/entities/abbot.cpp b/engines/lastexpress/entities/abbot.cpp
index 1581916..99b9ee3 100644
--- a/engines/lastexpress/entities/abbot.cpp
+++ b/engines/lastexpress/entities/abbot.cpp
@@ -41,18 +41,18 @@ namespace LastExpress {
 
 Abbot::Abbot(LastExpressEngine *engine) : Entity(engine, kEntityAbbot) {
 	ADD_CALLBACK_FUNCTION(Abbot, reset);
-	ADD_CALLBACK_FUNCTION(Abbot, draw);
-	ADD_CALLBACK_FUNCTION(Abbot, enterExitCompartment);
-	ADD_CALLBACK_FUNCTION(Abbot, enterExitCompartment2);
+	ADD_CALLBACK_FUNCTION_S(Abbot, draw);
+	ADD_CALLBACK_FUNCTION_SI(Abbot, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_SI(Abbot, enterExitCompartment2);
 	ADD_CALLBACK_FUNCTION(Abbot, callbackActionOnDirection);
-	ADD_CALLBACK_FUNCTION(Abbot, draw2);
-	ADD_CALLBACK_FUNCTION(Abbot, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Abbot, updateFromTicks);
-	ADD_CALLBACK_FUNCTION(Abbot, playSound);
-	ADD_CALLBACK_FUNCTION(Abbot, savegame);
-	ADD_CALLBACK_FUNCTION(Abbot, updateEntity);
-	ADD_CALLBACK_FUNCTION(Abbot, callSavepoint);
-	ADD_CALLBACK_FUNCTION(Abbot, updatePosition);
+	ADD_CALLBACK_FUNCTION_SSI(Abbot, draw2);
+	ADD_CALLBACK_FUNCTION_I(Abbot, updateFromTime);
+	ADD_CALLBACK_FUNCTION_I(Abbot, updateFromTicks);
+	ADD_CALLBACK_FUNCTION_S(Abbot, playSound);
+	ADD_CALLBACK_FUNCTION_II(Abbot, savegame);
+	ADD_CALLBACK_FUNCTION_II(Abbot, updateEntity);
+	ADD_CALLBACK_FUNCTION_SIIS(Abbot, callSavepoint);
+	ADD_CALLBACK_FUNCTION_SII(Abbot, updatePosition);
 	ADD_CALLBACK_FUNCTION(Abbot, callbackActionRestaurantOrSalon);
 	ADD_CALLBACK_FUNCTION(Abbot, chapter1);
 	ADD_CALLBACK_FUNCTION(Abbot, chapter2);
@@ -79,7 +79,7 @@ Abbot::Abbot(LastExpressEngine *engine) : Entity(engine, kEntityAbbot) {
 	ADD_CALLBACK_FUNCTION(Abbot, goCompartment4);
 	ADD_CALLBACK_FUNCTION(Abbot, inCompartment4);
 	ADD_CALLBACK_FUNCTION(Abbot, chapter4);
-	ADD_CALLBACK_FUNCTION(Abbot, doWalkSearchingForCath);
+	ADD_CALLBACK_FUNCTION_II(Abbot, doWalkSearchingForCath);
 	ADD_CALLBACK_FUNCTION(Abbot, chapter4Handler);
 	ADD_CALLBACK_FUNCTION(Abbot, leaveDinner);
 	ADD_CALLBACK_FUNCTION(Abbot, inCompartment);
@@ -616,7 +616,7 @@ IMPLEMENT_FUNCTION(26, Abbot, inSalon1)
 		break;
 
 	case kActionNone:
-		if (!Entity::updateParameter(params->param2, getState()->time, 4500))
+		if (!params->param1 || !Entity::updateParameterCheck(params->param2, getState()->time, 4500))
 			break;
 
 		if (getEntities()->isSomebodyInsideRestaurantOrSalon())
@@ -691,7 +691,7 @@ IMPLEMENT_FUNCTION(28, Abbot, openCompartment2)
 		break;
 
 	case kActionNone:
-		Entity::timeCheckCallback(kTime2052000, params->param1, 1, WRAP_SETUP_FUNCTION(Abbot, setup_goWander));
+		Entity::timeCheckCallback(kTime2052000, params->param1, 2, WRAP_SETUP_FUNCTION(Abbot, setup_goWander));
 		break;
 
 	case kActionDefault:
@@ -699,7 +699,7 @@ IMPLEMENT_FUNCTION(28, Abbot, openCompartment2)
 		getEntities()->drawSequenceLeft(kEntityAbbot, "508A");
 
 		setCallback(1);
-		setup_playSound("abb3013");
+		setup_playSound("Abb3013");
 		break;
 
 	case kActionCallback:
@@ -749,6 +749,9 @@ IMPLEMENT_FUNCTION(29, Abbot, goWander)
 			break;
 
 		case 4:
+			// compare with callback 2.
+			// This is taken from the original game as is,
+			// but do we really want real-time 30s in case 2 but simulated-time 15s (aka real-time 5s) here?
 			setCallback(5);
 			setup_updateFromTime(225);
 			break;
@@ -962,7 +965,7 @@ IMPLEMENT_FUNCTION(32, Abbot, goCompartment3)
 		case 1:
 			getObjects()->update(kObjectCompartmentC, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
 
-			setCallback(1);
+			setCallback(2);
 			setup_enterExitCompartment("617Ac", kObjectCompartmentC);
 			break;
 
@@ -1355,7 +1358,7 @@ IMPLEMENT_FUNCTION(42, Abbot, leaveDinner)
 
 	case kActionDefault:
 		getData()->location = kLocationOutsideCompartment;
-		getEntities()->updatePositionExit(kEntityAbbot, kCarRestaurant, 67);
+		getEntities()->updatePositionEnter(kEntityAbbot, kCarRestaurant, 67);
 
 		setCallback(1);
 		setup_callSavepoint("029F", kEntityTables4, kActionDrawTablesWithChairs, "029G");
@@ -1406,8 +1409,8 @@ IMPLEMENT_FUNCTION(43, Abbot, inCompartment)
 		break;
 
 	case kActionNone:
-		if (params->param1 && params->param4 != kTimeInvalid && params->param2 < getState()->time) {
-			if (getState()->time < kTime2452500) {
+		if (params->param1 && params->param4 != kTimeInvalid) {
+			if (getState()->time > kTime2452500) {
 				params->param4 = kTimeInvalid;
 
 				setCallback(1);
@@ -1415,7 +1418,7 @@ IMPLEMENT_FUNCTION(43, Abbot, inCompartment)
 				break;
 			} else {
 				if (!getEntities()->isDistanceBetweenEntities(kEntityAbbot, kEntityPlayer, 1000) || getSoundQueue()->isBuffered(kEntityBoutarel) || !params->param4)
-					params->param4 = (uint)getState()->time + 450;
+					params->param4 = (uint)getState()->time;
 
 				if (params->param4 < getState()->time) {
 					params->param4 = kTimeInvalid;
@@ -1655,7 +1658,8 @@ IMPLEMENT_FUNCTION(48, Abbot, afterBomb)
 			getData()->inventoryItem = kItemNone;
 
 			setCallback(4);
-			setup_updatePosition("126C", kCarRedSleeping, 52);
+			setup_updatePosition("126C", kCarRestaurant, 52);
+			break;
 		}
 
 		Entity::timeCheckCallbackInventory(kTime2533500, params->param2, 5, WRAP_SETUP_FUNCTION(Abbot, setup_callbackActionRestaurantOrSalon));
@@ -1771,6 +1775,9 @@ IMPLEMENT_FUNCTION(49, Abbot, catchCath)
 		getSavePoints()->push(kEntityAbbot, kEntityTatiana, kAction238790488);
 		getObjects()->update(kObjectCompartment2, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
 		getObjects()->update(kObjectHandleInsideBathroom, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+
+		setCallback(1);
+		setup_savegame(kSavegameTypeEvent, kEventAbbotWrongCompartment);
 		break;
 
 	case kActionDefault:
@@ -1791,7 +1798,7 @@ IMPLEMENT_FUNCTION(49, Abbot, catchCath)
 			break;
 
 		case 1:
-			getAction()->playAnimation(getObjects()->get(kObjectCompartment2).model < kObjectModel2 ? kEventAbbotWrongCompartmentBed : kEventAbbotWrongCompartment);
+			getAction()->playAnimation(getObjects()->get(kObjectCompartment2).model == kObjectModel1 ? kEventAbbotWrongCompartmentBed : kEventAbbotWrongCompartment);
 			getEntities()->updateEntity(kEntityAbbot, kCarRedSleeping, kPosition_6470);
 			getSound()->playSound(kEntityPlayer, "LIB015");
 			getScenes()->loadSceneFromObject(kObjectCompartment2, true);
diff --git a/engines/lastexpress/entities/alexei.cpp b/engines/lastexpress/entities/alexei.cpp
index 5ea3ff4..89027c2 100644
--- a/engines/lastexpress/entities/alexei.cpp
+++ b/engines/lastexpress/entities/alexei.cpp
@@ -37,21 +37,21 @@ namespace LastExpress {
 
 Alexei::Alexei(LastExpressEngine *engine) : Entity(engine, kEntityAlexei) {
 	ADD_CALLBACK_FUNCTION(Alexei, reset);
-	ADD_CALLBACK_FUNCTION(Alexei, playSound);
-	ADD_CALLBACK_FUNCTION(Alexei, updateFromTicks);
-	ADD_CALLBACK_FUNCTION(Alexei, draw);
-	ADD_CALLBACK_FUNCTION(Alexei, updatePosition);
-	ADD_CALLBACK_FUNCTION(Alexei, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_S(Alexei, playSound);
+	ADD_CALLBACK_FUNCTION_I(Alexei, updateFromTime);
+	ADD_CALLBACK_FUNCTION_S(Alexei, draw);
+	ADD_CALLBACK_FUNCTION_SII(Alexei, updatePosition);
+	ADD_CALLBACK_FUNCTION_SI(Alexei, enterExitCompartment);
 	ADD_CALLBACK_FUNCTION(Alexei, callbackActionOnDirection);
-	ADD_CALLBACK_FUNCTION(Alexei, callSavepoint);
-	ADD_CALLBACK_FUNCTION(Alexei, savegame);
-	ADD_CALLBACK_FUNCTION(Alexei, updateEntity);
-	ADD_CALLBACK_FUNCTION(Alexei, draw2);
+	ADD_CALLBACK_FUNCTION_SIIS(Alexei, callSavepoint);
+	ADD_CALLBACK_FUNCTION_II(Alexei, savegame);
+	ADD_CALLBACK_FUNCTION_II(Alexei, updateEntity);
+	ADD_CALLBACK_FUNCTION_SSI(Alexei, draw2);
 	ADD_CALLBACK_FUNCTION(Alexei, callbackActionRestaurantOrSalon);
 	ADD_CALLBACK_FUNCTION(Alexei, enterComparment);
 	ADD_CALLBACK_FUNCTION(Alexei, exitCompartment);
 	ADD_CALLBACK_FUNCTION(Alexei, pacingAtWindow);
-	ADD_CALLBACK_FUNCTION(Alexei, compartmentLogic);
+	ADD_CALLBACK_FUNCTION_IS(Alexei, compartmentLogic);
 	ADD_CALLBACK_FUNCTION(Alexei, chapter1);
 	ADD_CALLBACK_FUNCTION(Alexei, atDinner);
 	ADD_CALLBACK_FUNCTION(Alexei, returnCompartment);
@@ -97,8 +97,8 @@ IMPLEMENT_FUNCTION_S(2, Alexei, playSound)
 IMPLEMENT_FUNCTION_END
 
 //////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION_I(3, Alexei, updateFromTicks, uint32)
-	Entity::updateFromTicks(savepoint);
+IMPLEMENT_FUNCTION_I(3, Alexei, updateFromTime, uint32)
+	Entity::updateFromTime(savepoint);
 IMPLEMENT_FUNCTION_END
 
 //////////////////////////////////////////////////////////////////////////
@@ -394,7 +394,7 @@ IMPLEMENT_FUNCTION_IS(16, Alexei, compartmentLogic, TimeValue)
 
 		case 7:
 			setCallback(8);
-			setup_updateFromTicks(300);
+			setup_updateFromTime(300);
 			break;
 
 		case 8:
@@ -675,7 +675,7 @@ IMPLEMENT_FUNCTION(20, Alexei, goSalon)
 
 		case 4:
 			getData()->location = kLocationInsideCompartment;
-			setup_function26();
+			setup_sitting();
 			break;
 		}
 		break;
@@ -689,7 +689,7 @@ IMPLEMENT_FUNCTION(21, Alexei, sitting)
 		break;
 
 	case kActionNone:
-		if (Entity::updateParameterCheck(params->param2, getState()->time, params->param1)) {
+		if (Entity::updateParameterCheck(params->param2, getState()->time, params->param1) && getEntities()->isSomebodyInsideRestaurantOrSalon()) {
 			getData()->location = kLocationOutsideCompartment;
 			getData()->inventoryItem = kItemNone;
 
@@ -738,6 +738,7 @@ IMPLEMENT_FUNCTION(21, Alexei, sitting)
 		case 3:
 			getEntities()->drawSequenceLeft(kEntityAlexei, "103B");
 			getEntities()->updatePositionExit(kEntityAlexei, kCarRestaurant, 52);
+			getData()->location = kLocationInsideCompartment;
 			break;
 		}
 		break;
@@ -751,7 +752,7 @@ IMPLEMENT_FUNCTION(22, Alexei, standingAtWindow)
 		break;
 
 	case kActionNone:
-		if (Entity::updateParameter(params->param2, getState()->time, params->param2)) {
+		if (Entity::updateParameterCheck(params->param2, getState()->time, params->param1)) {
 			if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
 				getData()->location = kLocationOutsideCompartment;
 				getData()->inventoryItem = kItemNone;
@@ -768,7 +769,7 @@ IMPLEMENT_FUNCTION(22, Alexei, standingAtWindow)
 		if (getState()->time > kTime1138500) {
 			params->param3 = kTimeInvalid;
 		} else {
-			if (!getEntities()->isInSalon(kEntityPlayer) || getEntities()->isInSalon(kEntityPlayer) || !params->param3)
+			if (!getEntities()->isInSalon(kEntityPlayer) && !getEntities()->isInRestaurant(kEntityPlayer) || !params->param3)
 				params->param3 = (uint)getState()->time;
 
 			if (params->param3 >= getState()->time)
@@ -788,7 +789,7 @@ IMPLEMENT_FUNCTION(22, Alexei, standingAtWindow)
 		break;
 
 	case kActionDefault:
-		params->param1 = 255 * (4 * rnd(4) + 8);
+		params->param1 = 225 * (4 * rnd(4) + 8);
 		getEntities()->drawSequenceLeft(kEntityAlexei, "103E");
 		if (!getEvent(kEventAlexeiSalonPoem))
 			getData()->inventoryItem = kItemParchemin;
@@ -821,7 +822,7 @@ IMPLEMENT_FUNCTION(22, Alexei, standingAtWindow)
 			getEntities()->updatePositionExit(kEntityAlexei, kCarRestaurant, 52);
 			getData()->location = kLocationInsideCompartment;
 
-			setup_standingAtWindow();
+			setup_sitting();
 			break;
 		}
 		break;
@@ -835,7 +836,7 @@ IMPLEMENT_FUNCTION(23, Alexei, waitingForTatiana)
 		break;
 
 	case kActionNone:
-		getData()->inventoryItem = (!getEntities()->isInRestaurant(kEntityAlexei) || getEvent(kEventAlexeiSalonPoem)) ? kItemNone : kItemParchemin;
+		getData()->inventoryItem = (!getEntities()->isInRestaurant(kEntityTatiana) || getEvent(kEventAlexeiSalonPoem)) ? kItemNone : kItemParchemin;
 		break;
 
 	case kAction1:
@@ -913,7 +914,7 @@ IMPLEMENT_FUNCTION(24, Alexei, upset)
 
 		case 1:
 			getAction()->playAnimation(kEventAlexeiSalonCath);
-			getData()->car = kCarRestaurant;
+			getData()->car = kCarRedSleeping;
 			getData()->entityPosition = kPosition_9460;
 			getEntities()->clearSequences(kEntityAlexei);
 			getScenes()->loadSceneFromPosition(kCarRestaurant, 55);
@@ -1125,7 +1126,7 @@ IMPLEMENT_FUNCTION(30, Alexei, atBreakfast)
 			break;
 
 		case 2:
-			getSound()->playSound(kEntityAlexei, "TAt2116A");
+			getSound()->playSound(kEntityAlexei, "TAT2116A");
 			getEntities()->updatePositionEnter(kEntityAlexei, kCarRestaurant, 63);
 
 			setCallback(3);
@@ -1333,7 +1334,7 @@ IMPLEMENT_FUNCTION(35, Alexei, pacing3)
 
 	case kActionNone:
 		if (getEntities()->isInSalon(kEntityPlayer)) {
-			if (Entity::updateParameter(params->param2, getState()->time, 2700)) {
+			if (Entity::updateParameterCheck(params->param2, getState()->time, 2700)) {
 				setCallback(1);
 				setup_callbackActionRestaurantOrSalon();
 				break;
@@ -1342,7 +1343,7 @@ IMPLEMENT_FUNCTION(35, Alexei, pacing3)
 			params->param2 = 0;
 		}
 
-		if (Entity::updateParameter(params->param3, getState()->time, params->param1)) {
+		if (Entity::updateParameterCheck(params->param3, getState()->time, params->param1)) {
 			if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
 				setCallback(3);
 				setup_pacingAtWindow();
@@ -1535,10 +1536,10 @@ IMPLEMENT_FUNCTION(39, Alexei, meetTatiana)
 					break;
 			}
 
-			params->param4 = kTimeInvalid;
+			params->param5 = kTimeInvalid;
 
-			getEntities()->updatePositionEnter(kEntityAlexei, kCarGreenSleeping, 70);
-			getEntities()->updatePositionEnter(kEntityAlexei, kCarGreenSleeping, 71);
+			getEntities()->updatePositionExit(kEntityAlexei, kCarGreenSleeping, 70);
+			getEntities()->updatePositionExit(kEntityAlexei, kCarGreenSleeping, 71);
 
 			if (getEntities()->isInGreenCarEntrance(kEntityPlayer)) {
 				getSound()->excuseMe(kEntityAlexei);
@@ -1725,10 +1726,7 @@ IMPLEMENT_FUNCTION(43, Alexei, pacing)
 		break;
 
 	case kActionNone:
-		if (getState()->time < kTime1806300 && params->param2 < getState()->time) {
-			if (!params->param2)
-				params->param2 = (uint)getState()->time + params->param1;
-
+		if (getState()->time < kTime1806300 && Entity::updateParameterCheck(params->param2, getState()->time, params->param1)) {
 			if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
 				setCallback(1);
 				setup_pacingAtWindow();
@@ -1782,7 +1780,7 @@ IMPLEMENT_FUNCTION(44, Alexei, goToPlatform)
 		break;
 
 	case kActionNone:
-		if (getState()->time > kTime2457000 && !params->param1) {
+		if (getState()->time > kTime2475000 && !params->param1) {
 			params->param1 = 1;
 
 			getEntities()->updatePositionExit(kEntityAlexei, kCarGreenSleeping, 70);
@@ -1986,7 +1984,7 @@ IMPLEMENT_FUNCTION(47, Alexei, function47)
 
 		getData()->entityPosition = kPositionNone;
 		getData()->location = kLocationOutsideCompartment;
-		getData()->car = kCarNone;
+		getData()->car = kCarLocomotive;
 
 		getObjects()->update(kObjectCompartment2, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
 		getObjects()->update(kObjectHandleInsideBathroom, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
diff --git a/engines/lastexpress/entities/alexei.h b/engines/lastexpress/entities/alexei.h
index 5e14039..713a8c7 100644
--- a/engines/lastexpress/entities/alexei.h
+++ b/engines/lastexpress/entities/alexei.h
@@ -47,11 +47,11 @@ public:
 	DECLARE_FUNCTION_1(playSound, const char *filename)
 
 	/**
-	 * Updates parameter 2 using ticks value
+	 * Updates parameter 2 using time value
 	 *
-	 * @param ticks The number of ticks to add
+	 * @param time The time to add
 	 */
-	DECLARE_FUNCTION_1(updateFromTicks, uint32 ticks)
+	DECLARE_FUNCTION_1(updateFromTime, uint32 time)
 
 	/**
 	 * Draws the entity
diff --git a/engines/lastexpress/entities/alouan.cpp b/engines/lastexpress/entities/alouan.cpp
index 0667d11..a4bb105 100644
--- a/engines/lastexpress/entities/alouan.cpp
+++ b/engines/lastexpress/entities/alouan.cpp
@@ -34,10 +34,10 @@ namespace LastExpress {
 
 Alouan::Alouan(LastExpressEngine *engine) : Entity(engine, kEntityAlouan) {
 	ADD_CALLBACK_FUNCTION(Alouan, reset);
-	ADD_CALLBACK_FUNCTION(Alouan, enterExitCompartment);
-	ADD_CALLBACK_FUNCTION(Alouan, playSound);
-	ADD_CALLBACK_FUNCTION(Alouan, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Alouan, updateEntity);
+	ADD_CALLBACK_FUNCTION_SI(Alouan, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_S(Alouan, playSound);
+	ADD_CALLBACK_FUNCTION_I(Alouan, updateFromTime);
+	ADD_CALLBACK_FUNCTION_II(Alouan, updateEntity);
 	ADD_CALLBACK_FUNCTION(Alouan, peekF);
 	ADD_CALLBACK_FUNCTION(Alouan, peekH);
 	ADD_CALLBACK_FUNCTION(Alouan, goFtoH);
@@ -287,7 +287,7 @@ IMPLEMENT_FUNCTION(16, Alouan, chapter3Handler)
 
 label_callback1:
 		if (params->param2 != kTimeInvalid && getState()->time > kTime1989000) {
-			if (Entity::timeCheckCar(kTime2119500, params->param5, 5, WRAP_SETUP_FUNCTION(Alouan, setup_peekH)))
+			if (Entity::timeCheckCar(kTime2119500, params->param2, 2, WRAP_SETUP_FUNCTION(Alouan, setup_peekF)))
 				break;
 		}
 
@@ -486,7 +486,7 @@ IMPLEMENT_FUNCTION(23, Alouan, hiding)
 
 		case 1:
 			setCallback(2);
-			setup_enterExitCompartment("619AF", kObjectCompartment5);
+			setup_enterExitCompartment("619AF", kObjectCompartment6);
 			break;
 
 		case 2:
diff --git a/engines/lastexpress/entities/anna.cpp b/engines/lastexpress/entities/anna.cpp
index 52e9750..2b31c7b 100644
--- a/engines/lastexpress/entities/anna.cpp
+++ b/engines/lastexpress/entities/anna.cpp
@@ -22,6 +22,8 @@
 
 #include "lastexpress/entities/anna.h"
 
+#include "lastexpress/entities/vesna.h"
+
 #include "lastexpress/fight/fight.h"
 
 #include "lastexpress/game/action.h"
@@ -41,23 +43,23 @@ namespace LastExpress {
 
 Anna::Anna(LastExpressEngine *engine) : Entity(engine, kEntityAnna) {
 	ADD_CALLBACK_FUNCTION(Anna, reset);
-	ADD_CALLBACK_FUNCTION(Anna, draw);
-	ADD_CALLBACK_FUNCTION(Anna, updatePosition);
-	ADD_CALLBACK_FUNCTION(Anna, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_S(Anna, draw);
+	ADD_CALLBACK_FUNCTION_SII(Anna, updatePosition);
+	ADD_CALLBACK_FUNCTION_SI(Anna, enterExitCompartment);
 	ADD_CALLBACK_FUNCTION(Anna, callbackActionOnDirection);
-	ADD_CALLBACK_FUNCTION(Anna, callSavepoint);
-	ADD_CALLBACK_FUNCTION(Anna, playSound);
+	ADD_CALLBACK_FUNCTION_SIIS(Anna, callSavepoint);
+	ADD_CALLBACK_FUNCTION_S(Anna, playSound);
 	ADD_CALLBACK_FUNCTION(Anna, callbackActionRestaurantOrSalon);
-	ADD_CALLBACK_FUNCTION(Anna, savegame);
-	ADD_CALLBACK_FUNCTION(Anna, updateEntity);
-	ADD_CALLBACK_FUNCTION(Anna, updateFromTime);
+	ADD_CALLBACK_FUNCTION_II(Anna, savegame);
+	ADD_CALLBACK_FUNCTION_II(Anna, updateEntity);
+	ADD_CALLBACK_FUNCTION_I(Anna, updateFromTime);
 	ADD_CALLBACK_FUNCTION(Anna, practiceMusic);
-	ADD_CALLBACK_FUNCTION(Anna, draw2);
-	ADD_CALLBACK_FUNCTION(Anna, updateFromTicks);
-	ADD_CALLBACK_FUNCTION(Anna, compartmentLogic);
+	ADD_CALLBACK_FUNCTION_SSI(Anna, draw2);
+	ADD_CALLBACK_FUNCTION_I(Anna, updateFromTicks);
+	ADD_CALLBACK_FUNCTION_IS(Anna, compartmentLogic);
 	ADD_CALLBACK_FUNCTION(Anna, chapter1);
-	ADD_CALLBACK_FUNCTION(Anna, doWalkP1);
-	ADD_CALLBACK_FUNCTION(Anna, diningLogic);
+	ADD_CALLBACK_FUNCTION_II(Anna, doWalkP1);
+	ADD_CALLBACK_FUNCTION_I(Anna, diningLogic);
 	ADD_CALLBACK_FUNCTION(Anna, fleeTyler);
 	ADD_CALLBACK_FUNCTION(Anna, waitDinner);
 	ADD_CALLBACK_FUNCTION(Anna, goDinner);
@@ -78,13 +80,13 @@ Anna::Anna(LastExpressEngine *engine) : Entity(engine, kEntityAnna) {
 	ADD_CALLBACK_FUNCTION(Anna, goVassili);
 	ADD_CALLBACK_FUNCTION(Anna, function37);
 	ADD_CALLBACK_FUNCTION(Anna, speakTatiana);
-	ADD_CALLBACK_FUNCTION(Anna, doWalk1019);
+	ADD_CALLBACK_FUNCTION_II(Anna, doWalk1019);
 	ADD_CALLBACK_FUNCTION(Anna, leaveTatiana);
 	ADD_CALLBACK_FUNCTION(Anna, goBackToSleep);
 	ADD_CALLBACK_FUNCTION(Anna, chapter2);
 	ADD_CALLBACK_FUNCTION(Anna, inPart2);
 	ADD_CALLBACK_FUNCTION(Anna, chapter3);
-	ADD_CALLBACK_FUNCTION(Anna, exitCompartment);
+	ADD_CALLBACK_FUNCTION_I(Anna, exitCompartment);
 	ADD_CALLBACK_FUNCTION(Anna, practicing);
 	ADD_CALLBACK_FUNCTION(Anna, goLunch);
 	ADD_CALLBACK_FUNCTION(Anna, lunch);
@@ -111,7 +113,7 @@ Anna::Anna(LastExpressEngine *engine) : Entity(engine, kEntityAnna) {
 	ADD_CALLBACK_FUNCTION(Anna, goSalon4);
 	ADD_CALLBACK_FUNCTION(Anna, returnCompartment4);
 	ADD_CALLBACK_FUNCTION(Anna, enterCompartmentCathFollowsAnna);
-	ADD_CALLBACK_FUNCTION(Anna, doWalkCathFollowsAnna);
+	ADD_CALLBACK_FUNCTION_II(Anna, doWalkCathFollowsAnna);
 	ADD_CALLBACK_FUNCTION(Anna, letDownHair);
 	ADD_CALLBACK_FUNCTION(Anna, chapter5);
 	ADD_CALLBACK_FUNCTION(Anna, tiedUp);
@@ -125,7 +127,7 @@ Anna::Anna(LastExpressEngine *engine) : Entity(engine, kEntityAnna) {
 
 //////////////////////////////////////////////////////////////////////////
 IMPLEMENT_FUNCTION(1, Anna, reset)
-	Entity::reset(savepoint, true, true);
+	Entity::reset(savepoint, kClothes3, true);
 IMPLEMENT_FUNCTION_END
 
 //////////////////////////////////////////////////////////////////////////
@@ -311,7 +313,7 @@ IMPLEMENT_FUNCTION(12, Anna, practiceMusic)
 			}
 
 			params->param4 = 0;
-			params->param5 = 0;
+			params->param5 = 1;
 		} else {
 			getSoundQueue()->removeFromQueue(kEntityAnna);
 
@@ -335,7 +337,7 @@ IMPLEMENT_FUNCTION(12, Anna, practiceMusic)
 		getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
 		getObjects()->update(kObjectOutsideAnnaCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
 
-		if (getEntities()->isPlayerPosition(kCarRedSleeping, 49))
+		if (getEntities()->isPlayerPosition(kCarRedSleeping, 78))
 			getScenes()->loadSceneFromPosition(kCarRedSleeping, 49);
 
 		getEntities()->drawSequenceLeft(kEntityAnna, "418C");
@@ -357,7 +359,7 @@ IMPLEMENT_FUNCTION(12, Anna, practiceMusic)
 		if (getEntities()->isPlayerPosition(kCarRedSleeping, 60)) {
 			++params->param3;
 			if (params->param3 == 2) {
-				setCallback(2);
+				setCallback(5);
 				setup_draw("418B");
 			}
 		}
@@ -606,6 +608,7 @@ IMPLEMENT_FUNCTION_II(17, Anna, doWalkP1, uint32, uint32)
 		break;
 
 	case kActionDefault:
+		getData()->inventoryItem = kItemNone;
 		if (getProgress().jacket == kJacketGreen) {
 			if (!getEvent(kEventGotALight) && !getEvent(kEventGotALightD) && !getEvent(kEventAugustPresentAnna) && !getEvent(kEventAugustPresentAnnaFirstIntroduction))
 				params->param3 = kItemInvalid;
@@ -729,7 +732,7 @@ IMPLEMENT_FUNCTION_I(18, Anna, diningLogic, TimeValue)
 		case 2:
 			getAction()->playAnimation(kEventDinerMindJoin);
 
-			params->param2 &= 0xFFFFFFF7;
+			params->param2 &= 0xFFFFFF7F;
 
 			if (getProgress().jacket == kJacketGreen
 			 && !getEvent(kEventAnnaGiveScarfAsk)
@@ -992,6 +995,7 @@ IMPLEMENT_FUNCTION(25, Anna, eatingDinner)
 			break;
 
 		case 2:
+			setCallback(3);
 			setup_callbackActionRestaurantOrSalon();
 			break;
 
@@ -1021,10 +1025,10 @@ IMPLEMENT_FUNCTION(26, Anna, leaveDinner)
 
 	case kActionDefault:
 		getData()->location = kLocationOutsideCompartment;
-		getEntities()->updatePositionExit(kEntityAnna, kCarRestaurant, 62);
+		getEntities()->updatePositionEnter(kEntityAnna, kCarRestaurant, 62);
 
 		setCallback(1);
-		setup_callSavepoint("001L", kEntityTables0, kActionDrawTablesWithChairs, "001H");
+		setup_callSavepoint("001L", kEntityTables0, kActionDrawTablesWithChairs, "001M");
 		break;
 
 	case kActionCallback:
@@ -1222,7 +1226,7 @@ IMPLEMENT_FUNCTION(29, Anna, waitAugust)
 		case 2:
 			getAction()->playAnimation((getEvent(kEventAugustPresentAnna) || getEvent(kEventAugustPresentAnnaFirstIntroduction)) ? kEventAnnaConversationGoodNight : kEventAnnaIntroductionRejected);
 
-			getData()->inventoryItem = (InventoryItem)(getData()->inventoryItem & kItemToggleLow);
+			getData()->inventoryItem = (InventoryItem)(getData()->inventoryItem & kItemToggleHigh);
 
 			if (getProgress().jacket == kJacketGreen
 			 && !getEvent(kEventAnnaGiveScarfAsk)
@@ -1698,7 +1702,7 @@ IMPLEMENT_FUNCTION_II(39, Anna, doWalk1019, CarIndex, EntityPosition)
 
 	case kActionCallback:
 		if (getCallback() == 1) {
-			getAction()->playAnimation(getData()->direction == kDirectionNone ? kEventAnnaGoodNight : kEventAnnaGoodNightInverse);
+			getAction()->playAnimation(getData()->direction == kDirectionUp ? kEventAnnaGoodNight : kEventAnnaGoodNightInverse);
 			getData()->inventoryItem = kItemNone;
 
 			getEntities()->loadSceneFromEntityPosition(getData()->car, (EntityPosition)(getData()->entityPosition + (750 * (getData()->direction == kDirectionUp ? -1 : 1))), getData()->direction == kDirectionUp);
@@ -1807,8 +1811,8 @@ IMPLEMENT_FUNCTION(41, Anna, goBackToSleep)
 		if (!Entity::updateParameter(params->param2, getState()->time, 2700))
 			break;
 
-		params->param5++;
-		switch (params->param5) {
+		params->param1++;
+		switch (params->param1) {
 		default:
 			break;
 
@@ -2127,7 +2131,7 @@ label_callback_4:
 		break;
 
 	case kActionDefault:
-		getEntities()->drawSequenceLeft(kEntityAnna, "026C");
+		getEntities()->drawSequenceLeft(kEntityAnna, "026c");
 		getData()->location = kLocationInsideCompartment;
 
 		setCallback(1);
@@ -2220,7 +2224,7 @@ IMPLEMENT_FUNCTION(50, Anna, leaveLunch)
 
 	case kActionDefault:
 		setCallback(1);
-		setup_playSound("ann3141");
+		setup_playSound("Ann3141");
 		break;
 
 	case kActionCallback:
@@ -2266,7 +2270,7 @@ IMPLEMENT_FUNCTION(51, Anna, afterLunch)
 		break;
 
 	case kActionDefault:
-		getSound()->playSound(kEntityAnna, "Aug3142", kFlagInvalid, 30);
+		getSound()->playSound(kEntityAnna, "Ann3142", kFlagInvalid, 30);
 		getEntities()->updatePositionEnter(kEntityAnna, kCarRestaurant, 57);
 		getEntities()->drawSequenceRight(kEntityAnna, "112A");
 		if (getEntities()->isInRestaurant(kEntityPlayer))
@@ -2401,7 +2405,7 @@ IMPLEMENT_FUNCTION(53, Anna, dressing)
 		if (params->param3) {
 			if (Entity::updateParameter(params->param6, getState()->time, 9000)) {
 				params->param4 = !params->param4;
-				getEntities()->drawSequenceLeft(kEntityAnna, params->param4 ? "417B" : "417A");
+				getEntities()->drawSequenceLeft(kEntityAnna, params->param4 ? "417A" : "417B");
 				params->param6 = 0;
 			}
 		}
@@ -2549,7 +2553,7 @@ IMPLEMENT_FUNCTION(54, Anna, giveMaxToConductor2)
 
 			if (Entity::updateParameter(params->param6, getState()->time, 9000)) {
 				params->param4 = !params->param4;
-				getEntities()->drawSequenceLeft(kEntityAnna, params->param4 ? "417B" : "417A");
+				getEntities()->drawSequenceLeft(kEntityAnna, params->param4 ? "417A" : "417B");
 				params->param6 = 0;
 			}
 		}
@@ -2729,7 +2733,7 @@ IMPLEMENT_FUNCTION(55, Anna, goConcert)
 		case 1:
 			getObjects()->update(kObjectCompartmentF, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
 			setCallback(2);
-			setup_updateEntity(kCarRedSleeping, kPosition_9270);
+			setup_updateEntity(kCarKronos, kPosition_9270);
 			break;
 
 		case 2:
@@ -3072,7 +3076,7 @@ IMPLEMENT_FUNCTION(61, Anna, goBaggageCompartment)
 		getState()->timeDelta = 3;
 
 		setCallback(1);
-		setup_savegame(kSavegameTypeIndex, 0);
+		setup_savegame(kSavegameTypeTime, 0);
 		break;
 
 	case kActionCallback:
@@ -3132,7 +3136,7 @@ IMPLEMENT_FUNCTION(62, Anna, function62)
 		break;
 
 	case kActionNone:
-		if (getState()->time > kTime2259000 && !params->param2) {
+		if (params->param1 && getState()->time > kTime2259000 && !params->param2) {
 			params->param2 = 1;
 			getSavePoints()->push(kEntityAnna, kEntityVesna, kAction189299008);
 			setup_deadBaggageCompartment();
@@ -3222,6 +3226,7 @@ IMPLEMENT_FUNCTION(64, Anna, baggageFight)
 			getScenes()->loadSceneFromPosition(kCarBaggage, 96);
 
 			getProgress().field_54 = 0;
+			RESET_ENTITY_STATE(kEntityVesna, Vesna, setup_inCompartment);
 			getState()->time = kTime2266200;
 
 			setup_prepareVienna();
@@ -3302,7 +3307,7 @@ label_next:
 
 	case kAction1:
 		getData()->inventoryItem = kItemNone;
-		getData()->location = kLocationInsideCompartment;
+		getEntityData(kEntityPlayer)->location = kLocationInsideCompartment;
 
 		setCallback(1);
 		setup_savegame(kSavegameTypeEvent, kEventAnnaConversation_34);
@@ -3329,9 +3334,11 @@ label_next:
 		break;
 
 	case kActionDrawScene:
-		getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
-		params->param1 = 0;
-		params->param2 = 0;
+		if (params->param1 || params->param2) {
+			getObjects()->update(kObject53, kEntityAnna, kObjectLocation1, kCursorHandKnock, kCursorHand);
+			params->param1 = 0;
+			params->param2 = 0;
+		}
 		break;
 
 	case kActionCallback:
@@ -3743,7 +3750,7 @@ IMPLEMENT_FUNCTION(75, Anna, tiedUp)
 			else
 				getAction()->playAnimation(getEvent(kEventAnnaKissTrainHijacked) ? kEventAnnaBaggageTies3 : kEventAnnaBaggageTies4);
 
-			getScenes()->loadSceneFromPosition(kCarBaggage, 8);
+			getScenes()->loadSceneFromPosition(kCarBaggageRear, 88);
 			setup_function76();
 		}
 		break;
@@ -3806,7 +3813,7 @@ IMPLEMENT_FUNCTION(77, Anna, readyToScore)
 			getObjects()->update(kObject106, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
 			getAction()->playAnimation(kEventAnnaDialogGoToJerusalem);
 
-			getState()->time = kTimeCityConstantinople;
+			getState()->time = kTime4914000;
 			getState()->timeDelta = 0;
 
 			getSavePoints()->push(kEntityAnna, kEntityTatiana, kAction236060709);
@@ -3837,10 +3844,12 @@ IMPLEMENT_FUNCTION(78, Anna, kidnapped)
 			break;
 		}
 
-		getState()->time = kTimeInvalid2;
+		if (getEntities()->isInSalon(kEntityPlayer)) {
+			getState()->time = kTime4920300;
 
-		setCallback(getInventory()->get(kItemFirebird)->location == kObjectLocation4 ? 2 : 1);
-		setup_savegame(kSavegameTypeEvent, getInventory()->get(kItemFirebird)->location == kObjectLocation4 ? kEventKronosHostageAnna : kEventKronosHostageAnnaNoFirebird);
+			setCallback(getInventory()->get(kItemFirebird)->location == kObjectLocation4 ? 2 : 1);
+			setup_savegame(kSavegameTypeEvent, getInventory()->get(kItemFirebird)->location == kObjectLocation4 ? kEventKronosHostageAnna : kEventKronosHostageAnnaNoFirebird);
+		}
 		break;
 
 	case kActionCallback:
@@ -3871,9 +3880,9 @@ IMPLEMENT_FUNCTION(79, Anna, waiting)
 		break;
 
 	case kActionEndSound:
-		getState()->time = kTime5933;
+		getState()->time = kTime4923000;
 		setCallback(1);
-		setup_savegame(kSavegameTypeEvent, kEventKahinaPunch);
+		setup_savegame(kSavegameTypeEvent, kEventKahinaPunchBaggageCarEntrance);
 		break;
 
 	case kActionDrawScene:
@@ -3883,7 +3892,7 @@ IMPLEMENT_FUNCTION(79, Anna, waiting)
 		}
 
 		if (getEntities()->isInSalon(kEntityPlayer) && !getEvent(kEventKahinaPunch)) {
-			getState()->time = kTime5933;
+			getState()->time = kTime4923000;
 			setCallback(2);
 			setup_savegame(kSavegameTypeEvent, kEventKahinaPunch);
 		}
@@ -3908,7 +3917,7 @@ IMPLEMENT_FUNCTION(79, Anna, waiting)
 			break;
 
 		case 2:
-			getAction()->playAnimation(kEventKahinaPunchSalon);
+			getAction()->playAnimation(kEventKahinaPunch);
 			break;
 		}
 
@@ -3932,17 +3941,17 @@ IMPLEMENT_FUNCTION(80, Anna, finalSequence)
 
 	case kActionEndSound:
 		getSound()->playSound(kEntityPlayer, "Kro5002", kFlagDefault);
-		getState()->time = kTime4923000;
+		getState()->time = kTime4929300;
 
-		setCallback(1);
-		setup_savegame(kSavegameTypeEvent, kEventKronosBringFirebird);
+		setCallback(2);
+		setup_savegame(kSavegameTypeEvent, kEventKahinaPunch);
 		break;
 
 	case kActionDefault:
-		getState()->time = kTime4929300;
+		getState()->time = kTime4923000;
 
-		setCallback(2);
-		setup_savegame(kSavegameTypeEvent, kEventKahinaPunch);
+		setCallback(1);
+		setup_savegame(kSavegameTypeEvent, kEventKronosBringFirebird);
 		break;
 
 	case kActionCallback:
@@ -3997,8 +4006,8 @@ IMPLEMENT_FUNCTION(81, Anna, openFirebird)
 		if (!Entity::updateParameter(params->param1, getState()->timeTicks, 180))
 			break;
 
-		getSound()->playSound(kEntityTrain, "LIB069");
-		getLogic()->gameOver(kSavegameTypeIndex, 2, kSceneNone, true);
+		getSound()->playSound(kEntityTrain, "LIB069", kFlagDefault);
+		getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, true);
 		break;
 
 	case kActionCallback:
diff --git a/engines/lastexpress/entities/august.cpp b/engines/lastexpress/entities/august.cpp
index 1176d9d..01dc0b7 100644
--- a/engines/lastexpress/entities/august.cpp
+++ b/engines/lastexpress/entities/august.cpp
@@ -43,28 +43,28 @@ namespace LastExpress {
 
 August::August(LastExpressEngine *engine) : Entity(engine, kEntityAugust) {
 	ADD_CALLBACK_FUNCTION(August, reset);
-	ADD_CALLBACK_FUNCTION(August, updateFromTime);
-	ADD_CALLBACK_FUNCTION(August, draw);
-	ADD_CALLBACK_FUNCTION(August, updatePosition);
-	ADD_CALLBACK_FUNCTION(August, enterExitCompartment);
-	ADD_CALLBACK_FUNCTION(August, enterExitCompartment2);
-	ADD_CALLBACK_FUNCTION(August, enterExitCompartment3);
+	ADD_CALLBACK_FUNCTION_I(August, updateFromTime);
+	ADD_CALLBACK_FUNCTION_S(August, draw);
+	ADD_CALLBACK_FUNCTION_SII(August, updatePosition);
+	ADD_CALLBACK_FUNCTION_SI(August, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_SI(August, enterExitCompartment2);
+	ADD_CALLBACK_FUNCTION_SI(August, enterExitCompartment3);
 	ADD_CALLBACK_FUNCTION(August, callbackActionOnDirection);
-	ADD_CALLBACK_FUNCTION(August, callSavepoint);
-	ADD_CALLBACK_FUNCTION(August, callSavepointNoDrawing);
-	ADD_CALLBACK_FUNCTION(August, draw2);
-	ADD_CALLBACK_FUNCTION(August, playSound);
-	ADD_CALLBACK_FUNCTION(August, playSound16);
+	ADD_CALLBACK_FUNCTION_SIIS(August, callSavepoint);
+	ADD_CALLBACK_FUNCTION_IIS(August, callSavepointNoDrawing);
+	ADD_CALLBACK_FUNCTION_SSI(August, draw2);
+	ADD_CALLBACK_FUNCTION_S(August, playSound);
+	ADD_CALLBACK_FUNCTION_S(August, playSound16);
 	ADD_CALLBACK_FUNCTION(August, callbackActionRestaurantOrSalon);
-	ADD_CALLBACK_FUNCTION(August, savegame);
-	ADD_CALLBACK_FUNCTION(August, updateEntity);
-	ADD_CALLBACK_FUNCTION(August, function17);
-	ADD_CALLBACK_FUNCTION(August, updateEntity2);
-	ADD_CALLBACK_FUNCTION(August, function19);
-	ADD_CALLBACK_FUNCTION(August, function20);
-	ADD_CALLBACK_FUNCTION(August, function21);
+	ADD_CALLBACK_FUNCTION_II(August, savegame);
+	ADD_CALLBACK_FUNCTION_II(August, updateEntity);
+	ADD_CALLBACK_FUNCTION_I(August, function17);
+	ADD_CALLBACK_FUNCTION_II(August, updateEntity2);
+	ADD_CALLBACK_FUNCTION_TYPE(August, function19, EntityParametersIISS);
+	ADD_CALLBACK_FUNCTION_TYPE(August, function20, EntityParametersISSI);
+	ADD_CALLBACK_FUNCTION_I(August, function21);
 	ADD_CALLBACK_FUNCTION(August, chapter1);
-	ADD_CALLBACK_FUNCTION(August, function23);
+	ADD_CALLBACK_FUNCTION_I(August, function23);
 	ADD_CALLBACK_FUNCTION(August, dinner);
 	ADD_CALLBACK_FUNCTION(August, chapter1Handler);
 	ADD_CALLBACK_FUNCTION(August, function26);
@@ -82,8 +82,8 @@ August::August(LastExpressEngine *engine) : Entity(engine, kEntityAugust) {
 	ADD_CALLBACK_FUNCTION(August, function38);
 	ADD_CALLBACK_FUNCTION(August, function39);
 	ADD_CALLBACK_FUNCTION(August, chapter3);
-	ADD_CALLBACK_FUNCTION(August, function41);
-	ADD_CALLBACK_FUNCTION(August, function42);
+	ADD_CALLBACK_FUNCTION_II(August, function41);
+	ADD_CALLBACK_FUNCTION_III(August, function42);
 	ADD_CALLBACK_FUNCTION(August, chapter3Handler);
 	ADD_CALLBACK_FUNCTION(August, function44);
 	ADD_CALLBACK_FUNCTION(August, function45);
@@ -116,7 +116,7 @@ August::August(LastExpressEngine *engine) : Entity(engine, kEntityAugust) {
 
 //////////////////////////////////////////////////////////////////////////
 IMPLEMENT_FUNCTION(1, August, reset)
-	Entity::reset(savepoint, true);
+	Entity::reset(savepoint, kClothes2, true);
 IMPLEMENT_FUNCTION_END
 
 //////////////////////////////////////////////////////////////////////////
@@ -141,7 +141,7 @@ IMPLEMENT_FUNCTION_END
 
 //////////////////////////////////////////////////////////////////////////
 IMPLEMENT_FUNCTION_SI(6, August, enterExitCompartment2, ObjectIndex)
-	Entity::enterExitCompartment(savepoint, kPosition_6470, kPosition_6130, kCarGreenSleeping, kObjectCompartment3, true);
+	Entity::enterExitCompartment(savepoint, kPosition_6470, kPosition_6130, kCarGreenSleeping, kObjectCompartment3, true, true);
 IMPLEMENT_FUNCTION_END
 
 //////////////////////////////////////////////////////////////////////////
@@ -250,7 +250,7 @@ IMPLEMENT_FUNCTION_I(17, August, function17, TimeValue)
 		ENTITY_PARAM(0, 1) = 0;
 
 		setCallback(1);
-		setup_updateEntity(kCarRedSleeping, kPosition_540);
+		setup_updateEntity2(kCarRedSleeping, kPosition_540);
 		break;
 
 	case kActionCallback:
@@ -397,7 +397,7 @@ IMPLEMENT_FUNCTION_II(19, August, function19, bool, bool)
 			strcat((char *)&parameters->seq2, parameters->param1 ? "Fc" : "Dc");
 
 			setCallback(3);
-			setup_enterExitCompartment((char *)&parameters->seq2, kObjectCompartment3);
+			setup_enterExitCompartment2((char *)&parameters->seq2, kObjectCompartment3);
 			break;
 
 		case 3:
@@ -451,7 +451,7 @@ IMPLEMENT_FUNCTION_I(20, August, function20, bool)
 			break;
 		}
 
-		if (params->param1) {
+		if (parameters->param1) {
 			Common::String sequence = Common::String::format("%s%s", (char *)&parameters->seq1, "Gc");
 			assert(sequence.size() <= 13);
 
@@ -575,7 +575,7 @@ label_continue:
 	case kActionOpenDoor:
 		if (getProgress().chapter == kChapter1 && !getProgress().eventMetAugust && getProgress().jacket == kJacketGreen) {
 			getObjects()->update(kObjectOutsideTylerCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
-			getData()->location = kLocationInsideCompartment;
+			getEntityData(kEntityPlayer)->location = kLocationInsideCompartment;
 
 			setCallback(6);
 			setup_savegame(kSavegameTypeEvent, kEventMeetAugustHisCompartment);
@@ -648,7 +648,7 @@ label_continue:
 			params->param2 = 0;
 			params->param3 = 0;
 			params->param5 = 0;
-			params->param6 = 0;
+			params->param6 = 1;
 			CURRENT_PARAM(1, 1) = 0;
 			break;
 
@@ -694,7 +694,11 @@ label_continue:
 		case 11:
 		case 12:
 		case 13:
-			getObjects()->update(kObjectCompartment3, kEntityAugust, kObjectLocation1, kCursorTalk, (getProgress().eventMetAugust || getProgress().jacket != kJacketGreen) ? kCursorNormal : kCursorHand);
+			{
+				CursorStyle cursor1 = (getCallback() == 12 || getCallback() == 13) ? kCursorNormal : kCursorTalk;
+				CursorStyle cursor2 = (getProgress().eventMetAugust || getProgress().jacket != kJacketGreen) ? kCursorNormal : kCursorHand;
+				getObjects()->update(kObjectCompartment3, kEntityAugust, kObjectLocation1, cursor1, cursor2);
+			}
 
 			if (getCallback() == 12 || getCallback() == 13) {
 				params->param2 = 0;
@@ -806,10 +810,10 @@ IMPLEMENT_FUNCTION_I(23, August, function23, TimeValue)
 		if (!params->param2) {
 
 			if (!CURRENT_PARAM(1, 3))
-				CURRENT_PARAM(1, 3) = getState()->timeTicks + 45;
+				CURRENT_PARAM(1, 3) = getState()->timeTicks + 75;
 
 			if (CURRENT_PARAM(1, 3) >= getState()->timeTicks)
-				break;
+				goto label_callback_9;
 
 			if (!params->param5) {
 				setCallback(8);
@@ -892,7 +896,7 @@ label_callback_9:
 		} else {
 
 			if (getProgress().eventCorpseMovedFromFloor && getProgress().jacket != kJacketBlood) {
-				params->param7 = (getObjects()->get(kObjectCompartment1).model == kObjectModel1) ? 8 : 7;
+				params->param7 = (getObjects()->get(kObjectCompartment1).model == kObjectModel1) ? kEventMeetAugustTylerCompartmentBed : kEventMeetAugustTylerCompartment;
 				getObjects()->update(kObjectOutsideTylerCompartment, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
 
 				setCallback(4);
@@ -916,14 +920,14 @@ label_callback_9:
 			getObjects()->update(kObjectCompartment1, kEntityAugust, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorNormal);
 
 			setCallback(17);
-			setup_playSound("AUG1002A");
+			setup_playSound16("AUG1002A");
 		}
 		break;
 
 	case kActionOpenDoor:
 		if (getProgress().eventCorpseMovedFromFloor && getProgress().jacket != kJacketBlood) {
 			if (params->param3) {
-				getData()->location = kLocationInsideCompartment;
+				getEntityData(kEntityPlayer)->location = kLocationInsideCompartment;
 
 				params->param7 = (getObjects()->get(kObjectCompartment1).model == kObjectModel1) ? kEventMeetAugustHisCompartmentBed : kEventMeetAugustHisCompartment;
 			} else {
@@ -1057,7 +1061,7 @@ label_callback_9:
 			break;
 
 		case 14:
-			if (!params->param2)
+			if (!params->param3)
 				getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).status == kObjectLocation1 ? "LIB032" : "LIB014");
 
 			getObjects()->update(kObjectCompartment1, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
@@ -1436,16 +1440,16 @@ IMPLEMENT_FUNCTION(29, August, function29)
 		break;
 
 	case kActionNone:
-		if (!getProgress().field_28 || (params->param2 && params->param3 == kTimeInvalid))
+		if (!getProgress().field_28 || params->param2 || params->param3 == kTimeInvalid)
 			break;
 
-		if (getState()->time < kTime1134000) {
+		if (getState()->time <= kTime1134000) {
 
 			if (!getEntities()->isInRestaurant(kEntityPlayer)
-			 || getSoundQueue()->isBuffered("MRB1076") || getSoundQueue()->isBuffered("MRB1078") || getSoundQueue()->isBuffered("MRB1078A"))
+			 || getSoundQueue()->isBuffered("MRB1076") || getSoundQueue()->isBuffered("MRB1078") || getSoundQueue()->isBuffered("MRB1078A") || !params->param3)
 				params->param3 = (uint)getState()->time + 225;
 
-			if (params->param3 > getState()->time)
+			if (params->param3 >= getState()->time)
 				break;
 		}
 
@@ -1528,7 +1532,7 @@ IMPLEMENT_FUNCTION(30, August, restaurant)
 			if (getProgress().eventMetAugust)
 				getData()->inventoryItem = kItemNone;
 
-			getSound()->playSound(kEntityAugust, "Aug1003A");
+			getSound()->playSound(kEntityAugust, "AUG1003A");
 		} else {
 			getData()->inventoryItem = kItemNone;
 			getSavePoints()->push(kEntityAugust, kEntityAnna, kAction201437056);
@@ -1576,7 +1580,12 @@ IMPLEMENT_FUNCTION(30, August, restaurant)
 			break;
 
 		case 4:
-
+			getAction()->playAnimation(getProgress().eventMetAugust ? kEventAugustPresentAnna : kEventAugustPresentAnnaFirstIntroduction);
+			getSavePoints()->push(kEntityAugust, kEntityAnna, kAction201437056);
+			getEntities()->drawSequenceRight(kEntityAugust, getProgress().eventMetAugust ? "803GS" : "010P");
+			getScenes()->loadSceneFromPosition(kCarRestaurant, getProgress().eventMetAugust ? 55 : 65);
+			setCallback(getProgress().eventMetAugust ? 5 : 6);
+			setup_callbackActionOnDirection();
 			break;
 
 		case 5:
@@ -1623,7 +1632,7 @@ IMPLEMENT_FUNCTION(31, August, function31)
 			break;
 
 		case 2:
-			setCallback(2);
+			setCallback(3);
 			setup_function21(kTime1161000);
 			break;
 
@@ -1648,7 +1657,7 @@ IMPLEMENT_FUNCTION(32, August, function32)
 		break;
 
 	case kActionNone:
-		if (Entity::updateParameterTime(kTime1179000, (!getEntities()->isInSalon(kEntityAnna) || getEntities()->isInSalon(kEntityPlayer)), params->param6, 0)) {
+		if (params->param6 != kTimeInvalid && Entity::updateParameterTime(kTime1179000, (!getEntities()->isInSalon(kEntityAnna) || getEntities()->isInSalon(kEntityPlayer)), params->param6, 0)) {
 			getSavePoints()->push(kEntityAugust, kEntityAnna, kAction123712592);
 		}
 
@@ -2003,6 +2012,7 @@ IMPLEMENT_FUNCTION(38, August, function38)
 		case 2:
 			getScenes()->loadSceneFromItemPosition(kItem3);
 			getData()->location = kLocationInsideCompartment;
+			getEntities()->drawSequenceLeft(kEntityAugust, "109B");
 			break;
 
 		case 3:
@@ -2125,6 +2135,7 @@ IMPLEMENT_FUNCTION_II(41, August, function41, CarIndex, EntityPosition)
 			getData()->inventoryItem = kItemNone;
 
 		if (getEntities()->updateEntity(kEntityAugust, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+			getData()->inventoryItem = kItemNone;
 			callbackAction();
 			break;
 		}
@@ -2232,6 +2243,7 @@ IMPLEMENT_FUNCTION(43, August, chapter3Handler)
 		// Set as same position as Anna
 		if (params->param1) {
 			getData()->entityPosition = getEntityData(kEntityAnna)->entityPosition;
+			getData()->location = getEntityData(kEntityAnna)->location;
 			getData()->car = getEntityData(kEntityAnna)->car;
 		}
 
@@ -2328,7 +2340,7 @@ IMPLEMENT_FUNCTION(44, August, function44)
 		getData()->location = kLocationOutsideCompartment;
 
 		setCallback(1);
-		setup_updatePosition("122H", kCarRestaurant, 57);
+		setup_updatePosition("112H", kCarRestaurant, 57);
 		break;
 
 	case kActionCallback:
@@ -2417,10 +2429,10 @@ IMPLEMENT_FUNCTION_END
 IMPLEMENT_FUNCTION(46, August, function46)
 	switch (savepoint.action) {
 	default:
-		Entity::timeCheckCallback(kTime2088000, params->param1, 1, WRAP_SETUP_FUNCTION(August, setup_function47));
 		break;
 
 	case kActionNone:
+		Entity::timeCheckCallback(kTime2088000, params->param1, 1, WRAP_SETUP_FUNCTION(August, setup_function47));
 		break;
 
 	case kActionDrawScene:
@@ -2655,7 +2667,7 @@ IMPLEMENT_FUNCTION(52, August, function52)
 	case kActionKnock:
 	case kActionOpenDoor:
 		if (getInventory()->hasItem(kItemBriefcase)) {
-			getData()->location = kLocationInsideCompartment;
+			getEntityData(kEntityPlayer)->location = kLocationInsideCompartment;
 			if (savepoint.action == kActionKnock)
 				getSound()->playSound(kEntityPlayer, "LIB012");
 
@@ -2779,13 +2791,13 @@ IMPLEMENT_FUNCTION(54, August, function54)
 		break;
 
 	case kActionNone:
-		if (!params->param4 || params->param2 || getProgress().field_44)
+		if (!params->param3 || params->param1 || getProgress().field_44)
 			getData()->inventoryItem = kItemNone;
 		else
 			getData()->inventoryItem = kItemInvalid;
 
-		if (!params->param2 && params->param1) {
-			if (!Entity::updateParameter(params->param5, getState()->time, params->param1))
+		if (getEvent(kEventAugustTalkCigar) && params->param2 && !params->param1) {
+			if (!Entity::updateParameter(params->param4, getState()->time, 9000))
 				break;
 
 			getData()->inventoryItem = kItemNone;
@@ -2811,10 +2823,10 @@ IMPLEMENT_FUNCTION(54, August, function54)
 		break;
 
 	case kActionDrawScene:
-		if (!getEntities()->isPlayerPosition(kCarRestaurant, 60) || params->param3) {
-			if (!params->param2 && getEntities()->isPlayerPosition(kCarRestaurant, 57))
+		if (!getEntities()->isPlayerPosition(kCarRestaurant, 60) || params->param2 || params->param1) {
+			if (!params->param1 && getEntities()->isPlayerPosition(kCarRestaurant, 57))
 				getScenes()->loadSceneFromPosition(kCarRestaurant, 50);
-		} else if (!params->param2) {
+		} else {
 			getEntities()->updatePositionEnter(kEntityAugust, kCarRestaurant, 57);
 			getEntities()->drawSequenceRight(kEntityAugust, "105C3");
 		}
@@ -2837,36 +2849,32 @@ IMPLEMENT_FUNCTION(54, August, function54)
 			getData()->location = kLocationInsideCompartment;
 			getSavePoints()->push(kEntityAugust, kEntityAbbot, kAction123712592);
 			getEntities()->drawSequenceLeft(kEntityAugust, "105B3");
-			params->param4 = 1;
+			params->param3 = 1;
 			break;
 
 		case 3:
 			getAction()->playAnimation(kEventAugustTalkCigar);
-			getEntities()->drawSequenceLeft(kEntityAugust, params->param3 ? "122B" : "105B3");
+			getEntities()->drawSequenceLeft(kEntityAugust, params->param2 ? "122B" : "105B3");
 			getScenes()->processScene();
 
-			params->param1 = 9000;
-			params->param4 = 0;
+			params->param3 = 0;
 			break;
 		}
 		break;
 
 	case kAction122288808:
 		getEntities()->drawSequenceLeft(kEntityAugust, "122B");
-		params->param2 = 0;
-
-		if (getEvent(kEventAugustTalkCigar))
-			params->param1 = 9000;
+		params->param1 = 0;
 		break;
 
 	case kAction122358304:
 		getEntities()->drawSequenceLeft(kEntityAugust, "BLANK");
+		params->param1 = 1;
 		params->param2 = 1;
-		params->param3 = 1;
 		break;
 
 	case kAction136196244:
-		params->param2 = 1;
+		params->param1 = 1;
 		getData()->inventoryItem = kItemNone;
 		break;
 	}
@@ -2973,7 +2981,7 @@ IMPLEMENT_FUNCTION(58, August, chapter4Handler)
 
 	case kActionDefault:
 		setCallback(1);
-		setup_function20(false);
+		setup_function20(true);
 		break;
 
 	case kActionCallback:
@@ -3047,7 +3055,6 @@ IMPLEMENT_FUNCTION(60, August, function60)
 	case kActionNone: {
 		bool pushSavepoint = false;
 		if (!params->param2) {
-			pushSavepoint = true;
 			params->param2 = (uint)getState()->time + 450;
 		}
 
@@ -3252,7 +3259,7 @@ IMPLEMENT_FUNCTION(63, August, function63)
 		if (!Entity::updateParameter(params->param5, getState()->timeTicks, params->param1))
 			break;
 
-		params->param2 = (params->param6 < 1 ? 1 : 0);
+		params->param2 = (params->param2 == 0 ? 1 : 0);
 
 		getEntities()->drawSequenceLeft(kEntityAugust, params->param2 ? "122H" : "122F");
 
diff --git a/engines/lastexpress/entities/boutarel.cpp b/engines/lastexpress/entities/boutarel.cpp
index 0385eb0..2ee7136 100644
--- a/engines/lastexpress/entities/boutarel.cpp
+++ b/engines/lastexpress/entities/boutarel.cpp
@@ -39,23 +39,23 @@ namespace LastExpress {
 
 Boutarel::Boutarel(LastExpressEngine *engine) : Entity(engine, kEntityBoutarel) {
 	ADD_CALLBACK_FUNCTION(Boutarel, reset);
-	ADD_CALLBACK_FUNCTION(Boutarel, playSound);
-	ADD_CALLBACK_FUNCTION(Boutarel, draw);
-	ADD_CALLBACK_FUNCTION(Boutarel, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Boutarel, updatePosition);
-	ADD_CALLBACK_FUNCTION(Boutarel, enterExitCompartment);
-	ADD_CALLBACK_FUNCTION(Boutarel, enterExitCompartment2);
+	ADD_CALLBACK_FUNCTION_S(Boutarel, playSound);
+	ADD_CALLBACK_FUNCTION_S(Boutarel, draw);
+	ADD_CALLBACK_FUNCTION_I(Boutarel, updateFromTime);
+	ADD_CALLBACK_FUNCTION_SII(Boutarel, updatePosition);
+	ADD_CALLBACK_FUNCTION_SI(Boutarel, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_SI(Boutarel, enterExitCompartment2);
 	ADD_CALLBACK_FUNCTION(Boutarel, callbackActionOnDirection);
 	ADD_CALLBACK_FUNCTION(Boutarel, callbackActionRestaurantOrSalon);
-	ADD_CALLBACK_FUNCTION(Boutarel, updateEntity);
-	ADD_CALLBACK_FUNCTION(Boutarel, function11);
+	ADD_CALLBACK_FUNCTION_II(Boutarel, updateEntity);
+	ADD_CALLBACK_FUNCTION_I(Boutarel, function11);
 	ADD_CALLBACK_FUNCTION(Boutarel, enterTableWithMmeBoutarel);
 	ADD_CALLBACK_FUNCTION(Boutarel, leaveTableWithMmeBoutarel);
-	ADD_CALLBACK_FUNCTION(Boutarel, function14);
-	ADD_CALLBACK_FUNCTION(Boutarel, function15);
-	ADD_CALLBACK_FUNCTION(Boutarel, function16);
-	ADD_CALLBACK_FUNCTION(Boutarel, function17);
-	ADD_CALLBACK_FUNCTION(Boutarel, function18);
+	ADD_CALLBACK_FUNCTION_I(Boutarel, function14);
+	ADD_CALLBACK_FUNCTION_IS(Boutarel, function15);
+	ADD_CALLBACK_FUNCTION_IS(Boutarel, function16);
+	ADD_CALLBACK_FUNCTION_IS(Boutarel, function17);
+	ADD_CALLBACK_FUNCTION_I(Boutarel, function18);
 	ADD_CALLBACK_FUNCTION(Boutarel, chapter1);
 	ADD_CALLBACK_FUNCTION(Boutarel, function20);
 	ADD_CALLBACK_FUNCTION(Boutarel, chapter1Handler);
@@ -257,8 +257,8 @@ IMPLEMENT_FUNCTION(12, Boutarel, enterTableWithMmeBoutarel)
 
 		if (getEntities()->isInSalon(kEntityPlayer)) {
 			getEntities()->updateFrame(kEntityBoutarel);
-			getEntityData(kEntityMmeBoutarel)->location = getData()->location;
-			getEntityData(kEntityTables2)->location = getData()->location;
+			getEntityData(kEntityMmeBoutarel)->field_4A1 = getData()->field_4A1;
+			getEntityData(kEntityTables2)->field_4A1 = getData()->field_4A1;
 		}
 		break;
 	}
@@ -836,7 +836,7 @@ IMPLEMENT_FUNCTION(24, Boutarel, chapter2Handler)
 		break;
 
 	case kActionNone:
-		Entity::timeCheckCallback(kTime1759500, params->param2, 1, false, WRAP_SETUP_FUNCTION_B(Boutarel, setup_function14));
+		Entity::timeCheckCallback(kTime1759500, params->param2, 1, true, WRAP_SETUP_FUNCTION_B(Boutarel, setup_function14));
 		break;
 
 	case kActionDefault:
@@ -961,7 +961,7 @@ IMPLEMENT_FUNCTION(29, Boutarel, function29)
 			}
 		}
 
-		Entity::timeCheckCallback(kTime2002500, params->param4, 1, true, WRAP_SETUP_FUNCTION_B(Boutarel, setup_function14));
+		Entity::timeCheckCallback(kTime2002500, params->param4, 2, true, WRAP_SETUP_FUNCTION_B(Boutarel, setup_function14));
 		break;
 
 	case kActionDefault:
@@ -974,7 +974,7 @@ IMPLEMENT_FUNCTION(29, Boutarel, function29)
 			break;
 
 		case 1:
-			Entity::timeCheckCallback(kTime2002500, params->param4, 1, true, WRAP_SETUP_FUNCTION_B(Boutarel, setup_function14));
+			Entity::timeCheckCallback(kTime2002500, params->param4, 2, true, WRAP_SETUP_FUNCTION_B(Boutarel, setup_function14));
 			break;
 
 		case 2:
diff --git a/engines/lastexpress/entities/chapters.cpp b/engines/lastexpress/entities/chapters.cpp
index f1a7d02..8ed458c 100644
--- a/engines/lastexpress/entities/chapters.cpp
+++ b/engines/lastexpress/entities/chapters.cpp
@@ -72,9 +72,9 @@
 namespace LastExpress {
 
 Chapters::Chapters(LastExpressEngine *engine) : Entity(engine, kEntityChapters) {
-	ADD_CALLBACK_FUNCTION(Chapters, savegame);
-	ADD_CALLBACK_FUNCTION(Chapters, enterStation);
-	ADD_CALLBACK_FUNCTION(Chapters, exitStation);
+	ADD_CALLBACK_FUNCTION_II(Chapters, savegame);
+	ADD_CALLBACK_FUNCTION_SI(Chapters, enterStation);
+	ADD_CALLBACK_FUNCTION_S(Chapters, exitStation);
 	ADD_CALLBACK_FUNCTION(Chapters, chapter1);
 	ADD_CALLBACK_FUNCTION(Chapters, resetMainEntities);
 	ADD_CALLBACK_FUNCTION(Chapters, firstDream);
@@ -92,8 +92,8 @@ Chapters::Chapters(LastExpressEngine *engine) : Entity(engine, kEntityChapters)
 	ADD_CALLBACK_FUNCTION(Chapters, chapter4Init);
 	ADD_CALLBACK_FUNCTION(Chapters, chapter4Handler);
 	ADD_CALLBACK_FUNCTION(Chapters, chapter5);
-	ADD_CALLBACK_FUNCTION(Chapters, chapter4Init);
-	ADD_CALLBACK_FUNCTION(Chapters, chapter4Handler);
+	ADD_CALLBACK_FUNCTION(Chapters, chapter5Init);
+	ADD_CALLBACK_FUNCTION(Chapters, chapter5Handler);
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -135,6 +135,7 @@ IMPLEMENT_FUNCTION(5, Chapters, resetMainEntities)
 	RESET_ENTITY_STATE(kEntityHadija, Hadija, setup_reset);
 	RESET_ENTITY_STATE(kEntityIvo, Ivo, setup_reset);
 	RESET_ENTITY_STATE(kEntityKahina, Kahina, setup_reset);
+	RESET_ENTITY_STATE(kEntityKronos, Kronos, setup_reset);
 	RESET_ENTITY_STATE(kEntityMmeBoutarel, MmeBoutarel, setup_reset);
 	RESET_ENTITY_STATE(kEntityMahmud, Mahmud, setup_reset);
 	RESET_ENTITY_STATE(kEntityMax, Max, setup_reset);
@@ -258,17 +259,13 @@ IMPLEMENT_FUNCTION(6, Chapters, firstDream)
 
 		if (getSoundQueue()->isBuffered("ZFX1005"))
 			getSoundQueue()->processEntry("ZFX1005");
-
-		if (getSoundQueue()->isBuffered("ZFX1006"))
+		else if (getSoundQueue()->isBuffered("ZFX1006"))
 			getSoundQueue()->processEntry("ZFX1006");
-
-		if (getSoundQueue()->isBuffered("ZFX1007"))
+		else if (getSoundQueue()->isBuffered("ZFX1007"))
 			getSoundQueue()->processEntry("ZFX1007");
-
-		if (getSoundQueue()->isBuffered("ZFX1007A"))
+		else if (getSoundQueue()->isBuffered("ZFX1007A"))
 			getSoundQueue()->processEntry("ZFX1007A");
-
-		if (getSoundQueue()->isBuffered("ZFX1007B"))
+		else if (getSoundQueue()->isBuffered("ZFX1007B"))
 			getSoundQueue()->processEntry("ZFX1007B");
 
 		getSound()->playSound(kEntityPlayer, "MUS008", kFlagDefault);
@@ -321,7 +318,7 @@ IMPLEMENT_FUNCTION(7, Chapters, chapter1Init)
 	getProgress().chapter = kChapter1;
 	getSoundQueue()->resetState();
 
-	getState()->time = kTimeChapter1;
+	getState()->time = kTimeStartGame;
 	getState()->timeDelta = 0;
 	getProgress().isTrainRunning = true;
 	getProgress().portrait = kPortraitOriginal;
@@ -376,8 +373,8 @@ IMPLEMENT_FUNCTION(7, Chapters, chapter1Init)
 	getObjects()->update(kObject65, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
 	getObjects()->update(kObject69, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
 	getObjects()->update(kObject98, kEntityPlayer, kObjectLocationNone, kCursorNormal, kCursorForward);
-	getObjects()->update(kObjectHandleOutsideLeft, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHandKnock);
-	getObjects()->update(kObjectHandleOutsideRight, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHandKnock);
+	getObjects()->update(kObjectHandleOutsideLeft, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHand);
+	getObjects()->update(kObjectHandleOutsideRight, kEntityPlayer, kObjectLocation1, kCursorNormal, kCursorHand);
 	getObjects()->update(kObject101, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
 
 	setup_chapter1Handler();
@@ -972,7 +969,7 @@ label_callback_4:
 			break;
 
 label_callback_5:
-		if (timeCheckExitStation(kTimeEnterWels, CURRENT_PARAM(1, 3), 6, "Wels"))
+		if (timeCheckExitStation(kTimeExitWels, CURRENT_PARAM(1, 3), 6, "Wels"))
 			break;
 
 label_callback_6:
@@ -980,7 +977,7 @@ label_callback_6:
 			break;
 
 label_callback_7:
-		if (timeCheckExitStation(kTimeCityLinz, CURRENT_PARAM(1, 5), 8, "Linz"))
+		if (timeCheckExitStation(kTimeExitLinz, CURRENT_PARAM(1, 5), 8, "Linz"))
 			break;
 
 label_callback_8:
@@ -1024,7 +1021,7 @@ label_callback_8:
 			getSound()->playSteam((CityIndex)ENTITY_PARAM(0, 4));
 
 			ENTITY_PARAM(0, 2) = 0;
-			if (params->param1)
+			if (params->param3)
 				setup_viennaEvents();
 
 			break;
@@ -1086,6 +1083,30 @@ IMPLEMENT_FUNCTION(16, Chapters, viennaEvents)
 		break;
 
 	case kActionDefault:
+		getEntityData(kEntityPlayer)->car = kCarLocomotive;
+		if (getSoundQueue()->isBuffered(kEntityAbbot))
+			getSoundQueue()->processEntry(kEntityAbbot);
+
+		if (!getEvent(kEventAugustBringBriefcase)) {
+			setCallback(1);
+			setup_savegame(kSavegameTypeEvent, kEventViennaAugustUnloadGuns);
+			break;
+		}
+
+		if (getInventory()->get(kItemFirebird)->location == kObjectLocation5) {
+			setCallback(2);
+			setup_savegame(kSavegameTypeEvent, kEventViennaKronosFirebird);
+			break;
+		}
+
+		if (ENTITY_PARAM(0, 1)) {
+			setCallback(3);
+			setup_savegame(kSavegameTypeEvent, kEventVergesAnnaDead);
+			break;
+		}
+
+		setCallback(4);
+		setup_savegame(kSavegameTypeEvent, kEventViennaContinueGame);
 		break;
 
 	case kActionCallback:
@@ -1108,10 +1129,7 @@ IMPLEMENT_FUNCTION(16, Chapters, viennaEvents)
 			if (getEvent(kEventKronosBringEggCeiling))
 				getLogic()->gameOver(kSavegameTypeEvent2, kEventKronosBringEggCeiling, kSceneGameOverVienna1, true);
 			else if (getEvent(kEventKronosBringEgg)) {
-				if (getEvent(kEventKronosBringEggCeiling))
-					getLogic()->gameOver(kSavegameTypeEvent2, kEventKronosBringEggCeiling, kSceneGameOverVienna1, true);
-				else
-					getLogic()->gameOver(kSavegameTypeTime, kTime2155500, kSceneGameOverVienna1, true);
+				getLogic()->gameOver(kSavegameTypeTime, kTime2155500, kSceneGameOverVienna1, true);
 			} else {
 				if (getProgress().field_C0) {
 					if (getEvent(kEventKronosReturnBriefcase))
@@ -1733,7 +1751,7 @@ IMPLEMENT_FUNCTION(22, Chapters, chapter5Handler)
 			setCallback(1);
 			setup_savegame(kSavegameTypeEvent, kEventTrainStopped);
 		} else {
-			getLogic()->gameOver(kSavegameTypeTime, kTimeTrainStopped2, kSceneGameOverTrainStopped, true);
+			getLogic()->gameOver(kSavegameTypeTime, kTime2934000, kSceneGameOverTrainStopped, true);
 		}
 		break;
 
diff --git a/engines/lastexpress/entities/cooks.cpp b/engines/lastexpress/entities/cooks.cpp
index 749e939..34cd4a7 100644
--- a/engines/lastexpress/entities/cooks.cpp
+++ b/engines/lastexpress/entities/cooks.cpp
@@ -35,8 +35,8 @@
 namespace LastExpress {
 
 Cooks::Cooks(LastExpressEngine *engine) : Entity(engine, kEntityCooks) {
-	ADD_CALLBACK_FUNCTION(Cooks, draw);
-	ADD_CALLBACK_FUNCTION(Cooks, playSound);
+	ADD_CALLBACK_FUNCTION_S(Cooks, draw);
+	ADD_CALLBACK_FUNCTION_S(Cooks, playSound);
 	ADD_CALLBACK_FUNCTION(Cooks, uptrainVersion);
 	ADD_CALLBACK_FUNCTION(Cooks, downtrainVersion);
 	ADD_CALLBACK_FUNCTION(Cooks, chapter1);
@@ -98,26 +98,17 @@ IMPLEMENT_FUNCTION(3, Cooks, uptrainVersion)
 			break;
 		}
 
-		if (getEntities()->isPlayerPosition(kCarRestaurant, 46)) {
+		if (getEntities()->isPlayerPosition(kCarRestaurant, 76)) {
 			getEntities()->drawSequenceLeft(kEntityCooks, "308D");
 
-			if (!getSoundQueue()->isBuffered(kEntityCooks)) {
-				if (params->param1) {
-					if (!getEntities()->hasValidFrame(kEntityCooks)) {
-						getSound()->playSound(kEntityCooks, "LIB015");
-						getEntities()->clearSequences(kEntityCooks);
-						callbackAction();
-					}
-					break;
-				}
-
+			if (!getSoundQueue()->isBuffered(kEntityCooks) && !params->param1) {
 				// Kitchen apprentice getting a lesson :D
 				getSound()->playSound(kEntityCooks, "KIT1011A");
 				params->param1 = 1;
 			}
 		}
 
-		if (params->param1 && !getEntities()->hasValidFrame(kEntityCooks)) {
+		if (params->param1 && !getEntities()->hasValidFrame(kEntityCooks) && !getSoundQueue()->isBuffered(kEntityCooks)) {
 			getSound()->playSound(kEntityCooks, "LIB015");
 			getEntities()->clearSequences(kEntityCooks);
 			callbackAction();
@@ -159,22 +150,21 @@ IMPLEMENT_FUNCTION(4, Cooks, downtrainVersion)
 
 		switch (getProgress().chapter) {
 		default:
+			getSound()->playSound(kEntityCooks, "KIT1011");
+			setCallback(3);
+			setup_draw("308B");
 			break;
 
 		case kChapter1:
-			setCallback(2);
-			setup_playSound("ZFX1011");
+			setCallback(1);
+			setup_playSound("KIT1010");
 			break;
 
 		case kChapter3:
 			setCallback(2);
-			setup_playSound("ZFX1011");
+			setup_playSound("KIT1012");
 			break;
 		}
-
-		getSound()->playSound(kEntityCooks, "KIT1011");
-		setCallback(3);
-		setup_draw("308B");
 		break;
 
 	case kActionDrawScene:
@@ -187,23 +177,14 @@ IMPLEMENT_FUNCTION(4, Cooks, downtrainVersion)
 		if (getEntities()->isPlayerPosition(kCarRestaurant, 80)) {
 			getEntities()->drawSequenceLeft(kEntityCooks, "308D");
 
-			if (!getSoundQueue()->isBuffered(kEntityCooks)) {
-				if (params->param1) {
-					if (!getEntities()->hasValidFrame(kEntityCooks)) {
-						getSound()->playSound(kEntityCooks, "LIB015");
-						getEntities()->clearSequences(kEntityCooks);
-						callbackAction();
-					}
-					break;
-				}
-
+			if (!getSoundQueue()->isBuffered(kEntityCooks) && !params->param1) {
 				// Kitchen apprentice getting a lesson :D
 				getSound()->playSound(kEntityCooks, "KIT1011A");
 				params->param1 = 1;
 			}
 		}
 
-		if (params->param1 && !getEntities()->hasValidFrame(kEntityCooks)) {
+		if (params->param1 && !getEntities()->hasValidFrame(kEntityCooks) && !getSoundQueue()->isBuffered(kEntityCooks)) {
 			getSound()->playSound(kEntityCooks, "LIB015");
 			getEntities()->clearSequences(kEntityCooks);
 			callbackAction();
@@ -225,7 +206,7 @@ IMPLEMENT_FUNCTION(4, Cooks, downtrainVersion)
 		case 3:
 			getEntities()->drawSequenceLeft(kEntityCooks, "308C");
 			getEntities()->updatePositionExit(kEntityCooks, kCarRestaurant, 75);
-			getEntities()->updatePositionEnter(kEntityCooks, kCarRestaurant, 78);
+			getEntities()->updatePositionExit(kEntityCooks, kCarRestaurant, 78);
 			break;
 		}
 		break;
@@ -388,6 +369,9 @@ IMPLEMENT_FUNCTION(9, Cooks, inKitchenBreakfast)
 		break;
 
 	case kActionDrawScene:
+		if (!getEntities()->isInKitchen(kEntityPlayer))
+			break;
+
 		if (params->param2) {
 			setCallback(1);
 			setup_playSound("ZFX1011");
diff --git a/engines/lastexpress/entities/coudert.cpp b/engines/lastexpress/entities/coudert.cpp
index 66e6b83..dd1377d 100644
--- a/engines/lastexpress/entities/coudert.cpp
+++ b/engines/lastexpress/entities/coudert.cpp
@@ -39,25 +39,25 @@ namespace LastExpress {
 
 Coudert::Coudert(LastExpressEngine *engine) : Entity(engine, kEntityCoudert) {
 	ADD_CALLBACK_FUNCTION(Coudert, reset);
-	ADD_CALLBACK_FUNCTION(Coudert, bloodJacket);
-	ADD_CALLBACK_FUNCTION(Coudert, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_S(Coudert, bloodJacket);
+	ADD_CALLBACK_FUNCTION_SI(Coudert, enterExitCompartment);
 	ADD_CALLBACK_FUNCTION(Coudert, callbackActionOnDirection);
-	ADD_CALLBACK_FUNCTION(Coudert, enterExitCompartment2);
-	ADD_CALLBACK_FUNCTION(Coudert, playSound);
-	ADD_CALLBACK_FUNCTION(Coudert, playSound16);
-	ADD_CALLBACK_FUNCTION(Coudert, savegame);
-	ADD_CALLBACK_FUNCTION(Coudert, updateEntity);
-	ADD_CALLBACK_FUNCTION(Coudert, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Coudert, updateFromTicks);
-	ADD_CALLBACK_FUNCTION(Coudert, excuseMe);
-	ADD_CALLBACK_FUNCTION(Coudert, function13);
-	ADD_CALLBACK_FUNCTION(Coudert, function14);
-	ADD_CALLBACK_FUNCTION(Coudert, function15);
+	ADD_CALLBACK_FUNCTION_SIII(Coudert, enterExitCompartment2);
+	ADD_CALLBACK_FUNCTION_S(Coudert, playSound);
+	ADD_CALLBACK_FUNCTION_S(Coudert, playSound16);
+	ADD_CALLBACK_FUNCTION_II(Coudert, savegame);
+	ADD_CALLBACK_FUNCTION_II(Coudert, updateEntity);
+	ADD_CALLBACK_FUNCTION_I(Coudert, updateFromTime);
+	ADD_CALLBACK_FUNCTION_I(Coudert, updateFromTicks);
+	ADD_CALLBACK_FUNCTION_I(Coudert, excuseMe);
+	ADD_CALLBACK_FUNCTION_II(Coudert, function13);
+	ADD_CALLBACK_FUNCTION_I(Coudert, function14);
+	ADD_CALLBACK_FUNCTION_I(Coudert, function15);
 	ADD_CALLBACK_FUNCTION(Coudert, function16);
-	ADD_CALLBACK_FUNCTION(Coudert, function17);
+	ADD_CALLBACK_FUNCTION_I(Coudert, function17);
 	ADD_CALLBACK_FUNCTION(Coudert, function18);
-	ADD_CALLBACK_FUNCTION(Coudert, function19);
-	ADD_CALLBACK_FUNCTION(Coudert, function20);
+	ADD_CALLBACK_FUNCTION_I(Coudert, function19);
+	ADD_CALLBACK_FUNCTION_II(Coudert, function20);
 	ADD_CALLBACK_FUNCTION(Coudert, function21);
 	ADD_CALLBACK_FUNCTION(Coudert, function22);
 	ADD_CALLBACK_FUNCTION(Coudert, function23);
@@ -67,12 +67,12 @@ Coudert::Coudert(LastExpressEngine *engine) : Entity(engine, kEntityCoudert) {
 	ADD_CALLBACK_FUNCTION(Coudert, function27);
 	ADD_CALLBACK_FUNCTION(Coudert, visitCompartmentB);
 	ADD_CALLBACK_FUNCTION(Coudert, visitCompartmentA);
-	ADD_CALLBACK_FUNCTION(Coudert, function30);
-	ADD_CALLBACK_FUNCTION(Coudert, function31);
+	ADD_CALLBACK_FUNCTION_TYPE2(Coudert, function30, EntityParametersI5S, EntityParametersSIIS);
+	ADD_CALLBACK_FUNCTION_I(Coudert, function31);
 	ADD_CALLBACK_FUNCTION(Coudert, function32);
 	ADD_CALLBACK_FUNCTION(Coudert, function33);
-	ADD_CALLBACK_FUNCTION(Coudert, function34);
-	ADD_CALLBACK_FUNCTION(Coudert, function35);
+	ADD_CALLBACK_FUNCTION_I(Coudert, function34);
+	ADD_CALLBACK_FUNCTION_I(Coudert, function35);
 	ADD_CALLBACK_FUNCTION(Coudert, chapter1);
 	ADD_CALLBACK_FUNCTION(Coudert, function37);
 	ADD_CALLBACK_FUNCTION(Coudert, function38);
@@ -84,7 +84,7 @@ Coudert::Coudert(LastExpressEngine *engine) : Entity(engine, kEntityCoudert) {
 	ADD_CALLBACK_FUNCTION(Coudert, chapter3);
 	ADD_CALLBACK_FUNCTION(Coudert, function45);
 	ADD_CALLBACK_FUNCTION(Coudert, function46);
-	ADD_CALLBACK_FUNCTION(Coudert, function47);
+	ADD_CALLBACK_FUNCTION_I(Coudert, function47);
 	ADD_CALLBACK_FUNCTION(Coudert, function48);
 	ADD_CALLBACK_FUNCTION(Coudert, function49);
 	ADD_CALLBACK_FUNCTION(Coudert, function50);
@@ -105,7 +105,7 @@ Coudert::Coudert(LastExpressEngine *engine) : Entity(engine, kEntityCoudert) {
 
 //////////////////////////////////////////////////////////////////////////
 IMPLEMENT_FUNCTION(1, Coudert, reset)
-	Entity::reset(savepoint, true);
+	Entity::reset(savepoint, kClothes1, true);
 IMPLEMENT_FUNCTION_END
 
 //////////////////////////////////////////////////////////////////////////
@@ -115,7 +115,7 @@ IMPLEMENT_FUNCTION_S(2, Coudert, bloodJacket)
 		break;
 
 	case kActionNone:
-		Entity::savegameBloodJacket();
+		Entity::savegameBloodJacket(1);
 		break;
 
 	case kActionExitCompartment:
@@ -142,7 +142,7 @@ IMPLEMENT_FUNCTION_SI(3, Coudert, enterExitCompartment, ObjectIndex)
 		break;
 
 	case kActionNone:
-		Entity::savegameBloodJacket();
+		Entity::savegameBloodJacket(1);
 		return;
 
 	case kActionCallback:
@@ -168,7 +168,7 @@ IMPLEMENT_FUNCTION(4, Coudert, callbackActionOnDirection)
 			break;
 		}
 
-		Entity::savegameBloodJacket();
+		Entity::savegameBloodJacket(1);
 		break;
 
 	case kActionExitCompartment:
@@ -191,7 +191,7 @@ IMPLEMENT_FUNCTION_SIII(5, Coudert, enterExitCompartment2, ObjectIndex, EntityPo
 		break;
 
 	case kActionNone:
-		Entity::savegameBloodJacket();
+		Entity::savegameBloodJacket(1);
 		return;
 
 	case kActionCallback:
@@ -212,7 +212,7 @@ IMPLEMENT_FUNCTION_S(6, Coudert, playSound)
 		break;
 
 	case kActionNone:
-		Entity::savegameBloodJacket();
+		Entity::savegameBloodJacket(1);
 		break;
 
 	case kActionEndSound:
@@ -241,7 +241,7 @@ IMPLEMENT_FUNCTION_NOSETUP(7, Coudert, playSound16)
 		break;
 
 	case kActionNone:
-		Entity::savegameBloodJacket();
+		Entity::savegameBloodJacket(1);
 		break;
 
 	case kActionEndSound:
@@ -354,7 +354,7 @@ IMPLEMENT_FUNCTION_I(10, Coudert, updateFromTime, uint32)
 		break;
 
 	case kActionNone:
-		Entity::savegameBloodJacket();
+		Entity::savegameBloodJacket(1);
 
 		if (!Entity::updateParameter(params->param2, getState()->time, params->param1))
 			break;
@@ -378,7 +378,7 @@ IMPLEMENT_FUNCTION_I(11, Coudert, updateFromTicks, uint32)
 		break;
 
 	case kActionNone:
-		Entity::savegameBloodJacket();
+		Entity::savegameBloodJacket(1);
 
 		if (!Entity::updateParameter(params->param2, getState()->timeTicks, params->param1))
 			break;
@@ -453,7 +453,8 @@ IMPLEMENT_FUNCTION_II(13, Coudert, function13, bool, EntityIndex)
 		break;
 
 	case kActionNone:
-		Entity::savegameBloodJacket();
+		if (Entity::savegameBloodJacket(1))
+			break;
 
 		if (!params->param2 && !params->param3) {
 
@@ -576,7 +577,7 @@ IMPLEMENT_FUNCTION_I(14, Coudert, function14, EntityIndex)
 		break;
 
 	case kActionNone:
-		Entity::savegameBloodJacket();
+		Entity::savegameBloodJacket(4);
 		break;
 
 	case kActionDefault:
@@ -678,7 +679,7 @@ IMPLEMENT_FUNCTION_I(15, Coudert, function15, bool)
 			if (params->param1)
 				getSound()->playSound(kEntityCoudert, "Tat3163");
 			else
-				getSound()->playSound(kEntityCoudert, (getProgress().chapter != kChapter3 || getState()->time > kTime1449000) ? "Tat3162A" : "Tat3161A");
+				getSound()->playSound(kEntityCoudert, (getProgress().chapter != kChapter3 || getState()->time >= kTime1449000) ? "Tat3162A" : "Tat3161A");
 
 			setCallback(3);
 			setup_enterExitCompartment("627Xb", kObjectCompartmentB);
@@ -808,6 +809,7 @@ IMPLEMENT_FUNCTION(18, Coudert, function18)
 		if (ENTITY_PARAM(0, 3) || ENTITY_PARAM(0, 5) || ENTITY_PARAM(0, 4)) {
 			getEntities()->drawSequenceLeft(kEntityCoudert, "627K");
 			getScenes()->loadSceneFromItemPosition(kItem5);
+			ENTITY_PARAM(2, 1) = 1;
 
 			callbackAction();
 			break;
@@ -1305,7 +1307,7 @@ IMPLEMENT_FUNCTION(26, Coudert, function26)
 		break;
 
 	case kActionNone:
-		if (params->param1) {
+		if (!params->param1) {
 			if (!Entity::updateParameter(params->param2, getState()->timeTicks, 75))
 				break;
 
@@ -1963,7 +1965,7 @@ IMPLEMENT_FUNCTION(36, Coudert, chapter1)
 		break;
 
 	case kActionNone:
-		Entity::timeCheckCallback(kTimeChapter1, params->param1, 1, WRAP_SETUP_FUNCTION(Coudert, setup_chapter1Handler));
+		Entity::timeCheckCallback(kTimeChapter1, params->param1, 1, WRAP_SETUP_FUNCTION(Coudert, setup_function18));
 		break;
 
 	case kActionDefault:
@@ -2088,7 +2090,7 @@ switch (savepoint.action) {
 	case kAction191477936:
 		getData()->entityPosition = kPosition_4070;
 		getData()->location = kLocationOutsideCompartment;
-		getObjects()->update(kObjectCompartment4, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+		getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
 
 		setCallback(1);
 		setup_updateEntity(kCarRedSleeping, kPosition_2000);
@@ -2152,7 +2154,7 @@ IMPLEMENT_FUNCTION(39, Coudert, function39)
 
 		case 7:
 			setCallback(8);
-			setup_enterExitCompartment("MME1151", kObjectCompartmentD);
+			setup_enterExitCompartment("697Ad", kObjectCompartmentD);
 			break;
 
 		case 8:
@@ -2271,7 +2273,7 @@ label_callback_9:
 		if (ENTITY_PARAM(0, 1) && !getSoundQueue()->isBuffered(kEntityCoudert))
 			getSound()->playSound(kEntityCoudert, rnd(2) ? "JAC1065" : "JAC1065A");
 
-		if (getState()->time > kTime1107000 && !ENTITY_PARAM(0, 1) && !getEvent(kEventVassiliSeizure)) {
+		if (getState()->time > kTime1107000 && !params->param1 && !getEvent(kEventVassiliSeizure)) {
 			getData()->inventoryItem = kItemNone;
 
 			setCallback(10);
@@ -2601,7 +2603,7 @@ IMPLEMENT_FUNCTION(43, Coudert, function43)
 		}
 
 label_callback1:
-		if (!ENTITY_PARAM(1, 1)) {
+		if (ENTITY_PARAM(1, 1)) {
 			setCallback(2);
 			setup_function15(false);
 			break;
@@ -3366,7 +3368,7 @@ IMPLEMENT_FUNCTION(51, Coudert, function51)
 
 	case kActionNone:
 		if (getState()->time > kTime2133000 && !getProgress().field_40) {
-			getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentB);
+			getEntities()->exitCompartment(kEntityCoudert, kObjectCompartmentB, true);
 			getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
 			getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
 
@@ -3439,7 +3441,7 @@ IMPLEMENT_FUNCTION(51, Coudert, function51)
 			break;
 
 		case 5:
-			setCallback(5);
+			setCallback(6);
 			setup_function18();
 			break;
 		}
@@ -4095,7 +4097,7 @@ IMPLEMENT_FUNCTION(62, Coudert, function62)
 		case 3:
 			++params->param3;
 
-			if (params->param3 == 1 || params->param2) {
+			if (params->param3 == 1 || params->param3 == 2) {
 				getObjects()->update(kObjectCompartmentH, kEntityCoudert, kObjectLocation1, kCursorNormal, kCursorNormal);
 				setCallback(params->param3 == 1 ? 4 : 5);
 				setup_playSound(params->param3 == 1 ? "Jac5002" : "Jac5002A");
diff --git a/engines/lastexpress/entities/entity.cpp b/engines/lastexpress/entities/entity.cpp
index 170248d..faf937c 100644
--- a/engines/lastexpress/entities/entity.cpp
+++ b/engines/lastexpress/entities/entity.cpp
@@ -147,11 +147,35 @@ void EntityData::updateParameters(uint32 index) const {
 		error("[EntityData::updateParameters] Invalid param index to update (was:%d, max:32)", index);
 }
 
-void EntityData::saveLoadWithSerializer(Common::Serializer &s) {
-	for (uint i = 0; i < ARRAYSIZE(_parameters); i++)
-		_parameters[i].saveLoadWithSerializer(s);
+void EntityData::saveLoadWithSerializer(Common::Serializer &s, const Common::Array<TypeSetter>* paramsTypeSetters) {
+	if (s.isSaving()) {
+		for (uint i = 0; i < ARRAYSIZE(_parameters); i++)
+			_parameters[i].saveLoadWithSerializer(s);
 
-	_data.saveLoadWithSerializer(s);
+		_data.saveLoadWithSerializer(s);
+	} else {
+		// to correctly deserialize parameters, we need to know their runtime type
+		// but we don't know it until callbacks[] array will be deserialized
+		// all types of parameters are serialized to 32*4 bytes
+		// (the original game has same-size-PODs and just memcpy-s them.
+		// *sigh* Why does this implementation even need the extra byte in strings?
+		// Well, big-endian vs little-endian is also a thing...)
+		byte buf[ARRAYSIZE(_parameters) * 32 * 4];
+		s.syncBytes(buf, sizeof(buf));
+
+		_data.saveLoadWithSerializer(s);
+
+		for (uint i = 0; i < 8; i++) {
+			if (!paramsTypeSetters || _data.callbacks[i] >= paramsTypeSetters->size())
+				resetParametersType<EntityParametersIIII>(&_parameters[i]);
+			else
+				(*paramsTypeSetters)[_data.callbacks[i]](&_parameters[i]);
+		}
+		Common::MemoryReadStream paramsStream(buf, sizeof(buf));
+		Common::Serializer paramsSerializer(&paramsStream, NULL);
+		for (uint i = 0; i < ARRAYSIZE(_parameters); i++)
+			_parameters[i].saveLoadWithSerializer(paramsSerializer);
+	}
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -162,6 +186,7 @@ Entity::Entity(LastExpressEngine *engine, EntityIndex index) : _engine(engine),
 
 	// Add first empty entry to callbacks array
 	_callbacks.push_back(NULL);
+	_paramsTypeSetters.push_back(&EntityData::resetParametersType<EntityData::EntityParametersIIII>);
 }
 
 Entity::~Entity() {
@@ -211,7 +236,7 @@ void Entity::setup(ChapterIndex index) {
 // Shared functions
 //////////////////////////////////////////////////////////////////////////
 
-void Entity::reset(const SavePoint &savepoint, bool resetClothes, bool resetItem) {
+void Entity::reset(const SavePoint &savepoint, ClothesIndex maxClothes, bool resetItem) {
 	EXPOSE_PARAMS(EntityData::EntityParametersIIII)
 
 	switch (savepoint.action) {
@@ -219,10 +244,10 @@ void Entity::reset(const SavePoint &savepoint, bool resetClothes, bool resetItem
 		break;
 
 	case kAction1:
-		if (resetClothes) {
+		if (maxClothes != kClothesDefault) {
 			// Select next available clothes
 			getData()->clothes = (ClothesIndex)(getData()->clothes + 1);
-			if (getData()->clothes > kClothes3)
+			if (getData()->clothes > maxClothes)
 				getData()->clothes = kClothesDefault;
 		}
 		break;
@@ -263,26 +288,16 @@ void Entity::savegame(const SavePoint &savepoint) {
 	}
 }
 
-void Entity::savegameBloodJacket() {
+bool Entity::savegameBloodJacket(byte callback) {
 	if (getProgress().jacket == kJacketBlood
 	 && getEntities()->isDistanceBetweenEntities(_entityIndex, kEntityPlayer, 1000)
 	 && !getEntities()->isInsideCompartments(kEntityPlayer)
 	 && !getEntities()->checkFields10(kEntityPlayer)) {
-		setCallback(1);
-
-		switch (_entityIndex) {
-		default:
-			break;
-
-		case kEntityCoudert:
-			setup_savegame(kSavegameTypeEvent, kEventCoudertBloodJacket);
-			break;
-
-		case kEntityMertens:
-			setup_savegame(kSavegameTypeEvent, kEventCoudertBloodJacket);
-			break;
-		}
+		setCallback(callback);
+		setup_savegame(kSavegameTypeEvent, kEventMertensBloodJacket);
+		return true;
 	}
+	return false;
 }
 
 void Entity::playSound(const SavePoint &savepoint, bool resetItem, SoundFlag flag) {
@@ -355,7 +370,7 @@ void Entity::updateFromTicks(const SavePoint &savepoint) {
 		break;
 
 	case kActionNone:
-		if (Entity::updateParameter(params->param2, getState()->timeTicks, params->param1))
+		if (!Entity::updateParameter(params->param2, getState()->timeTicks, params->param1))
 			break;
 
 		callbackAction();
@@ -371,7 +386,7 @@ void Entity::updateFromTime(const SavePoint &savepoint) {
 		break;
 
 	case kActionNone:
-		if (Entity::updateParameter(params->param2, getState()->time, params->param1))
+		if (!Entity::updateParameter(params->param2, getState()->time, params->param1))
 			break;
 
 		callbackAction();
@@ -388,7 +403,7 @@ void Entity::callbackActionOnDirection(const SavePoint &savepoint) {
 		callbackAction();
 		break;
 
-	case kActionDefault:
+	case kActionNone:
 		if (getData()->direction != kDirectionRight)
 			callbackAction();
 		break;
@@ -609,22 +624,22 @@ void Entity::callbackAction() {
 //////////////////////////////////////////////////////////////////////////
 // Setup functions
 //////////////////////////////////////////////////////////////////////////
-void Entity::setup(const char *name, uint index) {
+void Entity::setup(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter) {
 	debugC(6, kLastExpressDebugLogic, "Entity: %s()", name);
 
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
 	_data->setCurrentCallback(index);
-	_data->resetCurrentParameters<EntityData::EntityParametersIIII>();
+	paramsTypeSetter(_data->getCurrentCallParameters());
 
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
 }
 
-void Entity::setupI(const char *name, uint index, uint param1) {
+void Entity::setupI(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1) {
 	debugC(6, kLastExpressDebugLogic, "Entity: %s(%u)", name, param1);
 
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
 	_data->setCurrentCallback(index);
-	_data->resetCurrentParameters<EntityData::EntityParametersIIII>();
+	paramsTypeSetter(_data->getCurrentCallParameters());
 
 	EntityData::EntityParametersIIII *params = (EntityData::EntityParametersIIII *)_data->getCurrentParameters();
 	params->param1 = (unsigned int)param1;
@@ -632,12 +647,12 @@ void Entity::setupI(const char *name, uint index, uint param1) {
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
 }
 
-void Entity::setupII(const char *name, uint index, uint param1, uint param2) {
+void Entity::setupII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2) {
 	debugC(6, kLastExpressDebugLogic, "Entity: %s(%u, %u)", name, param1, param2);
 
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
 	_data->setCurrentCallback(index);
-	_data->resetCurrentParameters<EntityData::EntityParametersIIII>();
+	paramsTypeSetter(_data->getCurrentCallParameters());
 
 	EntityData::EntityParametersIIII *params = (EntityData::EntityParametersIIII *)_data->getCurrentParameters();
 	params->param1 = param1;
@@ -646,12 +661,12 @@ void Entity::setupII(const char *name, uint index, uint param1, uint param2) {
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
 }
 
-void Entity::setupIII(const char *name, uint index, uint param1, uint param2, uint param3) {
+void Entity::setupIII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2, uint param3) {
 	debugC(6, kLastExpressDebugLogic, "Entity: %s(%u, %u, %u)", name, param1, param2, param3);
 
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
 	_data->setCurrentCallback(index);
-	_data->resetCurrentParameters<EntityData::EntityParametersIIII>();
+	paramsTypeSetter(_data->getCurrentCallParameters());
 
 	EntityData::EntityParametersIIII *params = (EntityData::EntityParametersIIII *)_data->getCurrentParameters();
 	params->param1 = param1;
@@ -661,12 +676,12 @@ void Entity::setupIII(const char *name, uint index, uint param1, uint param2, ui
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
 }
 
-void Entity::setupS(const char *name, uint index, const char *seq1) {
+void Entity::setupS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1) {
 	debugC(6, kLastExpressDebugLogic, "Entity: %s(%s)", name, seq1);
 
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
 	_data->setCurrentCallback(index);
-	_data->resetCurrentParameters<EntityData::EntityParametersSIIS>();
+	paramsTypeSetter(_data->getCurrentCallParameters());
 
 	EntityData::EntityParametersSIIS *params = (EntityData::EntityParametersSIIS*)_data->getCurrentParameters();
 	strncpy(params->seq1, seq1, 12);
@@ -674,12 +689,12 @@ void Entity::setupS(const char *name, uint index, const char *seq1) {
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
 }
 
-void Entity::setupSS(const char *name, uint index, const char *seq1, const char *seq2) {
+void Entity::setupSS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, const char *seq2) {
 	debugC(6, kLastExpressDebugLogic, "Entity: %s(%s, %s)", name, seq1, seq2);
 
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
 	_data->setCurrentCallback(index);
-	_data->resetCurrentParameters<EntityData::EntityParametersSSII>();
+	paramsTypeSetter(_data->getCurrentCallParameters());
 
 	EntityData::EntityParametersSSII *params = (EntityData::EntityParametersSSII*)_data->getCurrentParameters();
 	strncpy(params->seq1, seq1, 12);
@@ -688,12 +703,12 @@ void Entity::setupSS(const char *name, uint index, const char *seq1, const char
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
 }
 
-void Entity::setupSI(const char *name, uint index, const char *seq1, uint param4) {
+void Entity::setupSI(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, uint param4) {
 	debugC(6, kLastExpressDebugLogic, "Entity: %s(%s, %u)", name, seq1, param4);
 
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
 	_data->setCurrentCallback(index);
-	_data->resetCurrentParameters<EntityData::EntityParametersSIIS>();
+	paramsTypeSetter(_data->getCurrentCallParameters());
 
 	EntityData::EntityParametersSIIS *params = (EntityData::EntityParametersSIIS *)_data->getCurrentParameters();
 	strncpy(params->seq1, seq1, 12);
@@ -702,27 +717,27 @@ void Entity::setupSI(const char *name, uint index, const char *seq1, uint param4
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
 }
 
-void Entity::setupSII(const char *name, uint index, const char *seq1, uint param4, uint param5) {
+void Entity::setupSII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, uint param4, uint param5) {
 	debugC(6, kLastExpressDebugLogic, "Entity: %s(%s, %u, %u)", name, seq1, param4, param5);
 
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
 	_data->setCurrentCallback(index);
-	_data->resetCurrentParameters<EntityData::EntityParametersSIIS>();
+	paramsTypeSetter(_data->getCurrentCallParameters());
 
-	EntityData::EntityParametersSIIS *params = (EntityData::EntityParametersSIIS *)_data->getCurrentParameters();
-	strncpy(params->seq1, seq1, 12);
+	EntityData::EntityParametersSIII *params = (EntityData::EntityParametersSIII *)_data->getCurrentParameters();
+	strncpy(params->seq, seq1, 12);
 	params->param4 = param4;
 	params->param5 = param5;
 
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
 }
 
-void Entity::setupSIII(const char *name, uint index, const char *seq, uint param4, uint param5, uint param6) {
+void Entity::setupSIII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq, uint param4, uint param5, uint param6) {
 	debugC(6, kLastExpressDebugLogic, "Entity: %s(%s, %u, %u, %u)", name, seq, param4, param5, param6);
 
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
 	_data->setCurrentCallback(index);
-	_data->resetCurrentParameters<EntityData::EntityParametersSIII>();
+	paramsTypeSetter(_data->getCurrentCallParameters());
 
 	EntityData::EntityParametersSIII *params = (EntityData::EntityParametersSIII *)_data->getCurrentParameters();
 	strncpy(params->seq, seq, 12);
@@ -733,12 +748,12 @@ void Entity::setupSIII(const char *name, uint index, const char *seq, uint param
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
 }
 
-void Entity::setupSIIS(const char *name, uint index, const char *seq1, uint param4, uint param5, const char *seq2) {
+void Entity::setupSIIS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, uint param4, uint param5, const char *seq2) {
 	debugC(6, kLastExpressDebugLogic, "Entity: %s(%s, %u, %u, %s)", name, seq1, param4, param5, seq2);
 
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
 	_data->setCurrentCallback(index);
-	_data->resetCurrentParameters<EntityData::EntityParametersSIIS>();
+	paramsTypeSetter(_data->getCurrentCallParameters());
 
 	EntityData::EntityParametersSIIS *params = (EntityData::EntityParametersSIIS *)_data->getCurrentParameters();
 	strncpy(params->seq1, seq1, 12);
@@ -749,12 +764,12 @@ void Entity::setupSIIS(const char *name, uint index, const char *seq1, uint para
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
 }
 
-void Entity::setupSSI(const char *name, uint index, const char *seq1, const char *seq2, uint param7) {
+void Entity::setupSSI(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, const char *seq2, uint param7) {
 	debugC(6, kLastExpressDebugLogic, "Entity: %s(%s, %s, %u)", name, seq1, seq2, param7);
 
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
 	_data->setCurrentCallback(index);
-	_data->resetCurrentParameters<EntityData::EntityParametersSSII>();
+	paramsTypeSetter(_data->getCurrentCallParameters());
 
 	EntityData::EntityParametersSSII *params = (EntityData::EntityParametersSSII *)_data->getCurrentParameters();
 	strncpy(params->seq1, seq1, 12);
@@ -764,12 +779,12 @@ void Entity::setupSSI(const char *name, uint index, const char *seq1, const char
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
 }
 
-void Entity::setupIS(const char *name, uint index, uint param1, const char *seq) {
+void Entity::setupIS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, const char *seq) {
 	debugC(6, kLastExpressDebugLogic, "Entity: %s(%u, %s)", name, param1, seq);
 
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
 	_data->setCurrentCallback(index);
-	_data->resetCurrentParameters<EntityData::EntityParametersISII>();
+	paramsTypeSetter(_data->getCurrentCallParameters());
 
 	EntityData::EntityParametersISII *params = (EntityData::EntityParametersISII *)_data->getCurrentParameters();
 	params->param1 = (unsigned int)param1;
@@ -778,12 +793,12 @@ void Entity::setupIS(const char *name, uint index, uint param1, const char *seq)
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
 }
 
-void Entity::setupISS(const char *name, uint index, uint param1, const char *seq1, const char *seq2) {
+void Entity::setupISS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, const char *seq1, const char *seq2) {
 	debugC(6, kLastExpressDebugLogic, "Entity: %s(%u, %s, %s)", name, param1, seq1, seq2);
 
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
 	_data->setCurrentCallback(index);
-	_data->resetCurrentParameters<EntityData::EntityParametersISSI>();
+	paramsTypeSetter(_data->getCurrentCallParameters());
 
 	EntityData::EntityParametersISSI *params = (EntityData::EntityParametersISSI *)_data->getCurrentParameters();
 	params->param1 = param1;
@@ -793,12 +808,12 @@ void Entity::setupISS(const char *name, uint index, uint param1, const char *seq
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
 }
 
-void Entity::setupIIS(const char *name, uint index, uint param1, uint param2, const char *seq) {
+void Entity::setupIIS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2, const char *seq) {
 	debugC(6, kLastExpressDebugLogic, "Entity: %s(%u, %u, %s)", name, param1, param2, seq);
 
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
 	_data->setCurrentCallback(index);
-	_data->resetCurrentParameters<EntityData::EntityParametersIISI>();
+	paramsTypeSetter(_data->getCurrentCallParameters());
 
 	EntityData::EntityParametersIISI *params = (EntityData::EntityParametersIISI *)_data->getCurrentParameters();
 	params->param1 = param1;
@@ -808,12 +823,12 @@ void Entity::setupIIS(const char *name, uint index, uint param1, uint param2, co
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->call(_entityIndex, _entityIndex, kActionDefault);
 }
 
-void Entity::setupIISS(const char *name, uint index, uint param1, uint param2, const char *seq1, const char *seq2) {
+void Entity::setupIISS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2, const char *seq1, const char *seq2) {
 	debugC(6, kLastExpressDebugLogic, "Entity: %s(%u, %u, %s, %s)", name, param1, param2, seq1, seq2);
 
 	_engine->getGameLogic()->getGameState()->getGameSavePoints()->setCallback(_entityIndex, _callbacks[index]);
 	_data->setCurrentCallback(index);
-	_data->resetCurrentParameters<EntityData::EntityParametersIISS>();
+	paramsTypeSetter(_data->getCurrentCallParameters());
 
 	EntityData::EntityParametersIISS *params = (EntityData::EntityParametersIISS *)_data->getCurrentParameters();
 	params->param1 = param1;
@@ -855,12 +870,12 @@ bool Entity::updateParameterTime(TimeValue timeValue, bool check, uint &paramete
 }
 
 bool Entity::updateParameterCheck(uint &parameter, uint timeType, uint delta) const {
-	if (parameter && parameter >= timeType)
-		return false;
-
 	if (!parameter)
 		parameter = (uint)(timeType + delta);
 
+	if (parameter && parameter >= timeType)
+		return false;
+
 	return true;
 }
 
diff --git a/engines/lastexpress/entities/entity.h b/engines/lastexpress/entities/entity.h
index 25c481c..0e01b08 100644
--- a/engines/lastexpress/entities/entity.h
+++ b/engines/lastexpress/entities/entity.h
@@ -76,11 +76,37 @@ struct SavePoint;
 #define ENTITY_CALLBACK(class, name, pointer) \
 	Common::Functor1Mem<const SavePoint&, void, class>(pointer, &class::name)
 
-#define ADD_CALLBACK_FUNCTION(class, name) \
-	_callbacks.push_back(new ENTITY_CALLBACK(class, name, this));
+#define ADD_CALLBACK_FUNCTION_TYPE(class, name, type) \
+	_callbacks.push_back(new ENTITY_CALLBACK(class, name, this)); \
+	_paramsTypeSetters.push_back(&EntityData::resetParametersType<EntityData::type>);
+
+#define ADD_CALLBACK_FUNCTION_TYPE2(class, name, type1, type2) \
+	_callbacks.push_back(new ENTITY_CALLBACK(class, name, this)); \
+	_paramsTypeSetters.push_back(&EntityData::resetParametersType<EntityData::type1, EntityData::type2>);
+
+#define ADD_CALLBACK_FUNCTION_TYPE3(class, name, type1, type2, type3) \
+	_callbacks.push_back(new ENTITY_CALLBACK(class, name, this)); \
+	_paramsTypeSetters.push_back(&EntityData::resetParametersType<EntityData::type1, EntityData::type2, EntityData::type3>);
+
+#define ADD_CALLBACK_FUNCTION(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersIIII)
+#define ADD_CALLBACK_FUNCTION_I(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersIIII)
+#define ADD_CALLBACK_FUNCTION_II(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersIIII)
+#define ADD_CALLBACK_FUNCTION_III(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersIIII)
+#define ADD_CALLBACK_FUNCTION_S(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSIIS)
+#define ADD_CALLBACK_FUNCTION_SI(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSIIS)
+#define ADD_CALLBACK_FUNCTION_SII(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSIII)
+#define ADD_CALLBACK_FUNCTION_SIII(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSIII)
+#define ADD_CALLBACK_FUNCTION_SIIS(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSIIS)
+#define ADD_CALLBACK_FUNCTION_SS(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSSII)
+#define ADD_CALLBACK_FUNCTION_SSI(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersSSII)
+#define ADD_CALLBACK_FUNCTION_IS(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersISII)
+#define ADD_CALLBACK_FUNCTION_ISS(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersISSI)
+#define ADD_CALLBACK_FUNCTION_IIS(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersIISI)
+#define ADD_CALLBACK_FUNCTION_IISS(class, name) ADD_CALLBACK_FUNCTION_TYPE(class, name, EntityParametersIISS)
 
 #define ADD_NULL_FUNCTION() \
-	_callbacks.push_back(new ENTITY_CALLBACK(Entity, nullfunction, this));
+	_callbacks.push_back(new ENTITY_CALLBACK(Entity, nullfunction, this)); \
+	_paramsTypeSetters.push_back(&(EntityData::resetParametersType<EntityData::EntityParametersIIII>));
 
 #define WRAP_SETUP_FUNCTION(className, method) \
 	new Common::Functor0Mem<void, className>(this, &className::method)
@@ -125,7 +151,7 @@ struct SavePoint;
 // simple setup with no parameters
 #define IMPLEMENT_FUNCTION(index, class, name) \
 	void class::setup_##name() { \
-		Entity::setup(#class "::setup_" #name, index); \
+		Entity::setup(#class "::setup_" #name, index, _paramsTypeSetters[index]); \
 	} \
 	void class::name(const SavePoint &savepoint) { \
 		EXPOSE_PARAMS(EntityData::EntityParametersIIII) \
@@ -136,13 +162,13 @@ struct SavePoint;
 // nullfunction call
 #define IMPLEMENT_NULL_FUNCTION(index, class) \
 	void class::setup_nullfunction() { \
-		Entity::setup(#class "::setup_nullfunction", index); \
+		Entity::setup(#class "::setup_nullfunction", index, _paramsTypeSetters[index]); \
 	}
 
 // setup with one uint parameter
 #define IMPLEMENT_FUNCTION_I(index, class, name, paramType) \
 	void class::setup_##name(paramType param1) { \
-		Entity::setupI(#class "::setup_" #name, index, param1); \
+		Entity::setupI(#class "::setup_" #name, index, _paramsTypeSetters[index], param1); \
 	} \
 	void class::name(const SavePoint &savepoint) { \
 		EXPOSE_PARAMS(EntityData::EntityParametersIIII) \
@@ -151,7 +177,7 @@ struct SavePoint;
 // setup with two uint parameters
 #define IMPLEMENT_FUNCTION_II(index, class, name, paramType1, paramType2) \
 	void class::setup_##name(paramType1 param1, paramType2 param2) { \
-		Entity::setupII(#class "::setup_" #name, index, param1, param2); \
+		Entity::setupII(#class "::setup_" #name, index, _paramsTypeSetters[index], param1, param2); \
 	} \
 	void class::name(const SavePoint &savepoint) { \
 		EXPOSE_PARAMS(EntityData::EntityParametersIIII) \
@@ -160,7 +186,7 @@ struct SavePoint;
 // setup with three uint parameters
 #define IMPLEMENT_FUNCTION_III(index, class, name, paramType1, paramType2, paramType3) \
 	void class::setup_##name(paramType1 param1, paramType2 param2, paramType3 param3) { \
-		Entity::setupIII(#class "::setup_" #name, index, param1, param2, param3); \
+		Entity::setupIII(#class "::setup_" #name, index, _paramsTypeSetters[index], param1, param2, param3); \
 	} \
 	void class::name(const SavePoint &savepoint) { \
 		EXPOSE_PARAMS(EntityData::EntityParametersIIII) \
@@ -169,7 +195,7 @@ struct SavePoint;
 // setup with one char *parameter
 #define IMPLEMENT_FUNCTION_S(index, class, name) \
 	void class::setup_##name(const char *seq1) { \
-		Entity::setupS(#class "::setup_" #name, index, seq1); \
+		Entity::setupS(#class "::setup_" #name, index, _paramsTypeSetters[index], seq1); \
 	} \
 	void class::name(const SavePoint &savepoint) { \
 		EXPOSE_PARAMS(EntityData::EntityParametersSIIS) \
@@ -178,7 +204,7 @@ struct SavePoint;
 // setup with one char *parameter and one uint
 #define IMPLEMENT_FUNCTION_SI(index, class, name, paramType2) \
 	void class::setup_##name(const char *seq1, paramType2 param4) { \
-		Entity::setupSI(#class "::setup_" #name, index, seq1, param4); \
+		Entity::setupSI(#class "::setup_" #name, index, _paramsTypeSetters[index], seq1, param4); \
 	} \
 	void class::name(const SavePoint &savepoint) { \
 		EXPOSE_PARAMS(EntityData::EntityParametersSIIS) \
@@ -187,16 +213,16 @@ struct SavePoint;
 // setup with one char *parameter and two uints
 #define IMPLEMENT_FUNCTION_SII(index, class, name, paramType2, paramType3) \
 	void class::setup_##name(const char *seq1, paramType2 param4, paramType3 param5) { \
-		Entity::setupSII(#class "::setup_" #name, index, seq1, param4, param5); \
+		Entity::setupSII(#class "::setup_" #name, index, _paramsTypeSetters[index], seq1, param4, param5); \
 	} \
 	void class::name(const SavePoint &savepoint) { \
-		EXPOSE_PARAMS(EntityData::EntityParametersSIIS) \
-		debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%s, %d, %d) - action: %s", (char *)&params->seq1, params->param4, params->param5, ACTION_NAME(savepoint.action));
+		EXPOSE_PARAMS(EntityData::EntityParametersSIII) \
+		debugC(6, kLastExpressDebugLogic, "Entity: " #class "::" #name "(%s, %d, %d) - action: %s", (char *)&params->seq, params->param4, params->param5, ACTION_NAME(savepoint.action));
 
 // setup with one char *parameter and three uints
 #define IMPLEMENT_FUNCTION_SIII(index, class, name, paramType2, paramType3, paramType4) \
 	void class::setup_##name(const char *seq, paramType2 param4, paramType3 param5, paramType4 param6) { \
-		Entity::setupSIII(#class "::setup_" #name, index, seq, param4, param5, param6); \
+		Entity::setupSIII(#class "::setup_" #name, index, _paramsTypeSetters[index], seq, param4, param5, param6); \
 	} \
 	void class::name(const SavePoint &savepoint) { \
 		EXPOSE_PARAMS(EntityData::EntityParametersSIII) \
@@ -204,7 +230,7 @@ struct SavePoint;
 
 #define IMPLEMENT_FUNCTION_SIIS(index, class, name, paramType2, paramType3) \
 	void class::setup_##name(const char *seq1, paramType2 param4, paramType3 param5, const char *seq2) { \
-		Entity::setupSIIS(#class "::setup_" #name, index, seq1, param4, param5, seq2); \
+		Entity::setupSIIS(#class "::setup_" #name, index, _paramsTypeSetters[index], seq1, param4, param5, seq2); \
 	} \
 	void class::name(const SavePoint &savepoint) { \
 		EXPOSE_PARAMS(EntityData::EntityParametersSIIS) \
@@ -212,7 +238,7 @@ struct SavePoint;
 
 #define IMPLEMENT_FUNCTION_SS(index, class, name) \
 	void class::setup_##name(const char *seq1, const char *seq2) { \
-		Entity::setupSS(#class "::setup_" #name, index, seq1, seq2); \
+		Entity::setupSS(#class "::setup_" #name, index, _paramsTypeSetters[index], seq1, seq2); \
 	} \
 	void class::name(const SavePoint &savepoint) { \
 		EXPOSE_PARAMS(EntityData::EntityParametersSSII) \
@@ -220,7 +246,7 @@ struct SavePoint;
 
 #define IMPLEMENT_FUNCTION_SSI(index, class, name, paramType3) \
 	void class::setup_##name(const char *seq1, const char *seq2, paramType3 param7) { \
-		Entity::setupSSI(#class "::setup_" #name, index, seq1, seq2, param7); \
+		Entity::setupSSI(#class "::setup_" #name, index, _paramsTypeSetters[index], seq1, seq2, param7); \
 	} \
 	void class::name(const SavePoint &savepoint) { \
 		EXPOSE_PARAMS(EntityData::EntityParametersSSII) \
@@ -228,7 +254,7 @@ struct SavePoint;
 
 #define IMPLEMENT_FUNCTION_IS(index, class, name, paramType) \
 	void class::setup_##name(paramType param1, const char *seq) { \
-		Entity::setupIS(#class "::setup_" #name, index, param1, seq); \
+		Entity::setupIS(#class "::setup_" #name, index, _paramsTypeSetters[index], param1, seq); \
 	} \
 	void class::name(const SavePoint &savepoint) { \
 		EXPOSE_PARAMS(EntityData::EntityParametersISII) \
@@ -236,7 +262,7 @@ struct SavePoint;
 
 #define IMPLEMENT_FUNCTION_ISS(index, class, name, paramType) \
 	void class::setup_##name(paramType param1, const char *seq1, const char *seq2) { \
-		Entity::setupISS(#class "::setup_" #name, index, param1, seq1, seq2); \
+		Entity::setupISS(#class "::setup_" #name, index, _paramsTypeSetters[index], param1, seq1, seq2); \
 	} \
 	void class::name(const SavePoint &savepoint) { \
 		EXPOSE_PARAMS(EntityData::EntityParametersISSI) \
@@ -244,7 +270,7 @@ struct SavePoint;
 
 #define IMPLEMENT_FUNCTION_IIS(index, class, name, paramType1, paramType2) \
 	void class::setup_##name(paramType1 param1, paramType2 param2, const char *seq) { \
-		Entity::setupIIS(#class "::setup_" #name, index, param1, param2, seq); \
+		Entity::setupIIS(#class "::setup_" #name, index, _paramsTypeSetters[index], param1, param2, seq); \
 	} \
 	void class::name(const SavePoint &savepoint) { \
 		EXPOSE_PARAMS(EntityData::EntityParametersIISI) \
@@ -252,7 +278,7 @@ struct SavePoint;
 
 #define IMPLEMENT_FUNCTION_IISS(index, class, name, paramType1, paramType2) \
 	void class::setup_##name(paramType1 param1, paramType2 param2, const char *seq1, const char *seq2) { \
-		Entity::setupIISS(#class "::setup_" #name, index, param1, param2, seq1, seq2); \
+		Entity::setupIISS(#class "::setup_" #name, index, _paramsTypeSetters[index], param1, param2, seq1, seq2); \
 	} \
 	void class::name(const SavePoint &savepoint) { \
 		EXPOSE_PARAMS(EntityData::EntityParametersIISS) \
@@ -260,7 +286,7 @@ struct SavePoint;
 
 
 //////////////////////////////////////////////////////////////////////////
-class EntityData : Common::Serializable {
+class EntityData {
 public:
 
 	struct EntityParameters : Common::Serializable {
@@ -688,6 +714,23 @@ public:
 			memset(&seq, 0, 13);
 		}
 
+		Common::String toString() {
+			return Common::String::format("I5S: %d %d %d %d %d %s\n", param1, param2, param3, param4, param5, seq);
+		}
+
+		void update(uint32 index) {
+			switch (index) {
+			default:
+				error("[EntityParametersI5S::update] Invalid index (was: %d)", index);
+
+			case 0: param1 = 1; break;
+			case 1: param2 = 1; break;
+			case 2: param3 = 1; break;
+			case 3: param4 = 1; break;
+			case 4: param5 = 1; break;
+			}
+		}
+
 		void saveLoadWithSerializer(Common::Serializer &s) {
 			s.syncAsUint32LE(param1);
 			s.syncAsUint32LE(param2);
@@ -830,13 +873,13 @@ public:
 
 	EntityData() {}
 
-	template<class T>
-	void resetCurrentParameters() {
-		EntityCallParameters *params = &_parameters[_data.currentCall];
+	template<class T1, class T2 = EntityParametersIIII, class T3 = EntityParametersIIII>
+	static void resetParametersType(EntityCallParameters* params) {
 		params->clear();
-
-		for (int i = 0; i < 4; i++)
-			params->parameters[i] = new T();
+		params->parameters[0] = new T1();
+		params->parameters[1] = new T2();
+		params->parameters[2] = new T3();
+		params->parameters[3] = new EntityParametersIIII();
 	}
 
 	EntityCallData       *getCallData() { return &_data; }
@@ -853,7 +896,8 @@ public:
 	void                  updateParameters(uint32 index) const;
 
 	// Serializable
-	void                  saveLoadWithSerializer(Common::Serializer &ser);
+	typedef void(*TypeSetter)(EntityCallParameters*);
+	void saveLoadWithSerializer(Common::Serializer &ser, const Common::Array<TypeSetter>* paramsTypeSetters);
 
 private:
 
@@ -890,7 +934,7 @@ public:
 	virtual void setup_playSound(const char*) { error("[Entity::setup_playSound] Trying to call the parent setup function. Use the specific entity function directly"); }
 
 	// Serializable
-	void saveLoadWithSerializer(Common::Serializer &ser) { _data->saveLoadWithSerializer(ser); }
+	void saveLoadWithSerializer(Common::Serializer &ser) { _data->saveLoadWithSerializer(ser, &_paramsTypeSetters); }
 
 	void nullfunction(const SavePoint &savepoint) {}
 
@@ -901,6 +945,7 @@ protected:
 	EntityIndex                _entityIndex;
 	EntityData                *_data;
 	Common::Array<Callback *>  _callbacks;
+	Common::Array<EntityData::TypeSetter> _paramsTypeSetters;
 
 	/**
 	 * Saves the game
@@ -914,9 +959,10 @@ protected:
 	/**
 	 * Saves the game before being found out with a blood covered jacket.
 	 *
-	 * @param	saveFunction	The setup function to call to save the game
+	 * @param callback argument for setCallback()
+	 * @return         true if the event has been processed, false if nothing happened
 	 */
-	void savegameBloodJacket();
+	bool savegameBloodJacket(byte callback);
 
 	/**
 	 * Play sound
@@ -968,10 +1014,10 @@ protected:
 	 * Resets an entity
 	 *
 	 * @param savepoint    The savepoint.
-	 * @param resetClothes true to reset clothes.
+	 * @param maxClothes   cycles clothes from kClothesDefault to maxClothes inclusively
 	 * @param resetItem    true to reset inventoryItem to kItemInvalid
 	 */
-	void reset(const SavePoint &savepoint, bool resetClothes = false, bool resetItem = false);
+	void reset(const SavePoint &savepoint, ClothesIndex maxClothes = kClothesDefault, bool resetItem = false);
 
 	/**
 	 * Process callback action when the entity direction is not kDirectionRight
@@ -1064,21 +1110,21 @@ protected:
 	//////////////////////////////////////////////////////////////////////////
 	// Setup functions
 	//////////////////////////////////////////////////////////////////////////
-	void setup(const char *name, uint index);
-	void setupI(const char *name, uint index, uint param1);
-	void setupII(const char *name, uint index, uint param1, uint param2);
-	void setupIII(const char *name, uint index, uint param1, uint param2, uint param3);
-	void setupS(const char *name, uint index, const char *seq1);
-	void setupSS(const char *name, uint index, const char *seq1, const char *seq2);
-	void setupSI(const char *name, uint index, const char *seq1, uint param4);
-	void setupSII(const char *name, uint index, const char *seq1, uint param4, uint param5);
-	void setupSIII(const char *name, uint index, const char *seq, uint param4, uint param5, uint param6);
-	void setupSIIS(const char *name, uint index, const char *seq1, uint param4, uint param5, const char *seq2);
-	void setupSSI(const char *name, uint index, const char *seq1, const char *seq2, uint param7);
-	void setupIS(const char *name, uint index, uint param1, const char *seq);
-	void setupISS(const char *name, uint index, uint param1, const char *seq1, const char *seq2);
-	void setupIIS(const char *name, uint index, uint param1, uint param2, const char *seq);
-	void setupIISS(const char *name, uint index, uint param1, uint param2, const char *seq1, const char *seq2);
+	void setup(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter);
+	void setupI(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1);
+	void setupII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2);
+	void setupIII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2, uint param3);
+	void setupS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1);
+	void setupSS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, const char *seq2);
+	void setupSI(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, uint param4);
+	void setupSII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, uint param4, uint param5);
+	void setupSIII(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq, uint param4, uint param5, uint param6);
+	void setupSIIS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, uint param4, uint param5, const char *seq2);
+	void setupSSI(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, const char *seq1, const char *seq2, uint param7);
+	void setupIS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, const char *seq);
+	void setupISS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, const char *seq1, const char *seq2);
+	void setupIIS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2, const char *seq);
+	void setupIISS(const char *name, uint index, EntityData::TypeSetter paramsTypeSetter, uint param1, uint param2, const char *seq1, const char *seq2);
 
 	//////////////////////////////////////////////////////////////////////////
 	// Helper functions
diff --git a/engines/lastexpress/entities/francois.cpp b/engines/lastexpress/entities/francois.cpp
index d2fb66c..9eb12fb 100644
--- a/engines/lastexpress/entities/francois.cpp
+++ b/engines/lastexpress/entities/francois.cpp
@@ -38,19 +38,19 @@ namespace LastExpress {
 
 Francois::Francois(LastExpressEngine *engine) : Entity(engine, kEntityFrancois) {
 	ADD_CALLBACK_FUNCTION(Francois, reset);
-	ADD_CALLBACK_FUNCTION(Francois, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Francois, draw);
-	ADD_CALLBACK_FUNCTION(Francois, enterExitCompartment);
-	ADD_CALLBACK_FUNCTION(Francois, enterExitCompartment2);
-	ADD_CALLBACK_FUNCTION(Francois, playSound);
-	ADD_CALLBACK_FUNCTION(Francois, savegame);
-	ADD_CALLBACK_FUNCTION(Francois, doWalk);
+	ADD_CALLBACK_FUNCTION_I(Francois, updateFromTime);
+	ADD_CALLBACK_FUNCTION_S(Francois, draw);
+	ADD_CALLBACK_FUNCTION_SI(Francois, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_SI(Francois, enterExitCompartment2);
+	ADD_CALLBACK_FUNCTION_S(Francois, playSound);
+	ADD_CALLBACK_FUNCTION_II(Francois, savegame);
+	ADD_CALLBACK_FUNCTION_II(Francois, doWalk);
 	ADD_CALLBACK_FUNCTION(Francois, exitCompartment);
 	ADD_CALLBACK_FUNCTION(Francois, enterCompartment);
-	ADD_CALLBACK_FUNCTION(Francois, rampage);
+	ADD_CALLBACK_FUNCTION_I(Francois, rampage);
 	ADD_CALLBACK_FUNCTION(Francois, takeWalk);
 	ADD_CALLBACK_FUNCTION(Francois, haremVisit);
-	ADD_CALLBACK_FUNCTION(Francois, chaseBeetle);
+	ADD_CALLBACK_FUNCTION_TYPE(Francois, chaseBeetle, EntityParametersIISS);
 	ADD_CALLBACK_FUNCTION(Francois, findCath);
 	ADD_CALLBACK_FUNCTION(Francois, letsGo);
 	ADD_CALLBACK_FUNCTION(Francois, chapter1);
@@ -72,7 +72,7 @@ Francois::Francois(LastExpressEngine *engine) : Entity(engine, kEntityFrancois)
 
 //////////////////////////////////////////////////////////////////////////
 IMPLEMENT_FUNCTION(1, Francois, reset)
-	Entity::reset(savepoint, true);
+	Entity::reset(savepoint, kClothes1, true);
 IMPLEMENT_FUNCTION_END
 
 //////////////////////////////////////////////////////////////////////////
@@ -113,6 +113,7 @@ IMPLEMENT_FUNCTION_II(8, Francois, doWalk, CarIndex, EntityPosition)
 
 	case kActionNone:
 		if (getEntities()->updateEntity(_entityIndex, (CarIndex)params->param1, (EntityPosition)params->param2)) {
+			getData()->inventoryItem = kItemNone;
 			callbackAction();
 		} else {
 			if (!getEntities()->isDistanceBetweenEntities(kEntityFrancois, kEntityPlayer, 2000)
@@ -126,6 +127,8 @@ IMPLEMENT_FUNCTION_II(8, Francois, doWalk, CarIndex, EntityPosition)
 				 && !getEvent(kEventFrancoisShowBeetle)
 				 && !getEvent(kEventFrancoisShowBeetleD))
 					getData()->inventoryItem = kItemMatchBox;
+				else
+					getData()->inventoryItem = kItemNone;
 			} else {
 				getData()->inventoryItem = kItemFirebird;
 			}
@@ -145,12 +148,12 @@ IMPLEMENT_FUNCTION_II(8, Francois, doWalk, CarIndex, EntityPosition)
 		default:
 			break;
 
-		case 1:
+		case kItemMatchBox:
 			setCallback(2);
 			setup_savegame(kSavegameTypeEvent, kEventFrancoisShowBeetle);
 			break;
 
-		case 18:
+		case kItemFirebird:
 			if (isNight())
 				getAction()->playAnimation(getData()->entityPosition < getEntityData(kEntityPlayer)->entityPosition ? kEventFrancoisShowEggNightD : kEventFrancoisShowEggNight);
 			else
@@ -588,6 +591,9 @@ IMPLEMENT_FUNCTION(13, Francois, haremVisit)
 			}
 
 			getEntities()->drawSequenceLeft(kEntityFrancois, "605He");
+			getEntities()->enterCompartment(kEntityFrancois, kObjectCompartmentE, true);
+			setCallback(8);
+			setup_playSound(rnd(2) ? "Fra2005B" : "Fra2005C");
 			break;
 
 		case 8:
@@ -683,7 +689,7 @@ IMPLEMENT_FUNCTION_IIS(14, Francois, chaseBeetle, ObjectIndex, EntityPosition)
 			break;
 
 		case 8:
-			getEntities()->exitCompartment(kEntityFrancois, (ObjectIndex)parameters->param1);
+			getEntities()->exitCompartment(kEntityFrancois, (ObjectIndex)parameters->param1, true);
 			// fall through
 
 		case 9:
@@ -788,6 +794,7 @@ IMPLEMENT_FUNCTION(16, Francois, letsGo)
 	case kActionNone:
 		getData()->entityPosition = getEntityData(kEntityBoutarel)->entityPosition;
 		getData()->location = getEntityData(kEntityBoutarel)->location;
+		getData()->car = getEntityData(kEntityBoutarel)->car;
 		break;
 
 	case kActionDefault:
@@ -828,6 +835,7 @@ IMPLEMENT_FUNCTION(16, Francois, letsGo)
 
 			getData()->entityPosition = kPosition_5790;
 			getData()->location = kLocationInsideCompartment;
+			getEntities()->clearSequences(kEntityFrancois);
 
 			callbackAction();
 			break;
@@ -996,8 +1004,22 @@ label_callback_4:
 		}
 
 label_callback_5:
-		if (getInventory()->get(kItemWhistle)->location != kObjectLocation3) {
-			// TODO: do we also need to check if the whistle is in the inventory?
+		if (getInventory()->get(kItemBeetle)->location != kObjectLocation3) {
+			if (!getInventory()->hasItem(kItemWhistle) && getInventory()->get(kItemWhistle)->location != kObjectLocation3) {
+				// BUG in the original game: condition is always false
+				if (getState()->time < kTime1782000 && getState()->time > kTime1782000 && !params->param8) {
+					params->param8 = 1;
+					setCallback(9);
+					setup_takeWalk();
+					break;
+				}
+				if (getState()->time < kTime1813500 && getState()->time > kTime1813500 && !CURRENT_PARAM(1, 1)) {
+					CURRENT_PARAM(1, 1) = 1;
+					setCallback(10);
+					setup_takeWalk();
+					break;
+				}
+			}
 			break;
 		}
 
@@ -1010,11 +1032,11 @@ label_callback_5:
 		}
 
 label_callback_6:
-		if (timeCheckCallbackCompartment(kTime1782000, params->param6, 7, kObjectCompartmentC, kPosition_6470, "c"))
+		if (timeCheckCallbackCompartment(kTime1782000, params->param6, 7, kObjectCompartmentF, kPosition_4070, "f"))
 			break;
 
 label_callback_7:
-		timeCheckCallbackCompartment(kTime1813500, params->param7, 8, kObjectCompartmentF, kPosition_4070, "f");
+		timeCheckCallbackCompartment(kTime1813500, params->param7, 8, kObjectCompartmentC, kPosition_6470, "c");
 		break;
 
 	case kActionCallback:
@@ -1128,13 +1150,13 @@ label_callback_10:
 			}
 
 label_callback_11:
-			if (getInventory()->get(kItemWhistle)->location == kObjectLocation3) {
+			if (getInventory()->get(kItemBeetle)->location == kObjectLocation3) {
 				if (getState()->time <= kTimeEnd)
-					if (!getEntities()->isDistanceBetweenEntities(kEntityFrancois, kEntityPlayer, 2000) || !params->param4)
-						params->param4 = (uint)(getState()->time + 75);
+					if (!getEntities()->isDistanceBetweenEntities(kEntityFrancois, kEntityPlayer, 2000) || !CURRENT_PARAM(1, 4))
+						CURRENT_PARAM(1, 4) = (uint)(getState()->time + 75);
 
-				if (params->param4 < getState()->time || getState()->time > kTimeEnd) {
-					params->param4 = kTimeInvalid;
+				if (CURRENT_PARAM(1, 4) < getState()->time || getState()->time > kTimeEnd) {
+					CURRENT_PARAM(1, 4) = kTimeInvalid;
 
 					setCallback(12);
 					setup_playSound("Fra2010");
@@ -1146,11 +1168,11 @@ label_callback_12:
 					break;
 
 label_callback_13:
-				if (timeCheckCallbackCompartment(kTime2040300, CURRENT_PARAM(1, 6), 14, kObjectCompartmentF, kPosition_4070, "f"))
+				if (timeCheckCallbackCompartment(kTime2146500, CURRENT_PARAM(1, 6), 14, kObjectCompartmentF, kPosition_4070, "f"))
 					break;
 
 label_callback_14:
-				timeCheckCallbackCompartment(kTime2040300, CURRENT_PARAM(1, 7), 15, kObjectCompartmentB, kPosition_7500, "b");
+				timeCheckCallbackCompartment(kTime2218500, CURRENT_PARAM(1, 7), 15, kObjectCompartmentB, kPosition_7500, "b");
 			}
 		}
 		break;
diff --git a/engines/lastexpress/entities/gendarmes.cpp b/engines/lastexpress/entities/gendarmes.cpp
index 572f47c..981ad46 100644
--- a/engines/lastexpress/entities/gendarmes.cpp
+++ b/engines/lastexpress/entities/gendarmes.cpp
@@ -37,14 +37,14 @@ namespace LastExpress {
 Gendarmes::Gendarmes(LastExpressEngine *engine) : Entity(engine, kEntityGendarmes) {
 	ADD_CALLBACK_FUNCTION(Gendarmes, reset);
 	ADD_CALLBACK_FUNCTION(Gendarmes, chapter1);
-	ADD_CALLBACK_FUNCTION(Gendarmes, doDraw);
-	ADD_CALLBACK_FUNCTION(Gendarmes, doDialog);
-	ADD_CALLBACK_FUNCTION(Gendarmes, doDialogFullVolume);
-	ADD_CALLBACK_FUNCTION(Gendarmes, doWait);
-	ADD_CALLBACK_FUNCTION(Gendarmes, savegame);
-	ADD_CALLBACK_FUNCTION(Gendarmes, doWalk);
-	ADD_CALLBACK_FUNCTION(Gendarmes, doCompartment);
-	ADD_CALLBACK_FUNCTION(Gendarmes, trappedCath);
+	ADD_CALLBACK_FUNCTION_S(Gendarmes, doDraw);
+	ADD_CALLBACK_FUNCTION_S(Gendarmes, doDialog);
+	ADD_CALLBACK_FUNCTION_S(Gendarmes, doDialogFullVolume);
+	ADD_CALLBACK_FUNCTION_I(Gendarmes, doWait);
+	ADD_CALLBACK_FUNCTION_II(Gendarmes, savegame);
+	ADD_CALLBACK_FUNCTION_II(Gendarmes, doWalk);
+	ADD_CALLBACK_FUNCTION_TYPE3(Gendarmes, doCompartment, EntityParametersIISS, EntityParametersSSS, EntityParametersISII);
+	ADD_CALLBACK_FUNCTION_III(Gendarmes, trappedCath);
 	ADD_CALLBACK_FUNCTION(Gendarmes, chapter1Handler);
 	ADD_CALLBACK_FUNCTION(Gendarmes, searchTrain);
 	ADD_CALLBACK_FUNCTION(Gendarmes, function13);
@@ -156,7 +156,7 @@ IMPLEMENT_FUNCTION_IISS(9, Gendarmes, doCompartment, CarIndex, EntityPosition)
 			parameters2->param7 = kPosition_7850;
 		}
 
-		if (params->param1 == kCarBaggageRear)
+		if (params->param1 == kCarRedSleeping)
 			parameters2->param5 += 31; // Switch to next compartment car
 
 		if (parameters2->param6) {
@@ -184,7 +184,7 @@ IMPLEMENT_FUNCTION_IISS(9, Gendarmes, doCompartment, CarIndex, EntityPosition)
 			setup_trappedCath((CarIndex)params->param1, (EntityPosition)params->param2, (ObjectIndex)parameters2->param5);
 		} else {
 			getEntities()->drawSequenceLeft(kEntityGendarmes, (char *)&parameters1->seq1);
-			getEntities()->enterCompartment(kEntityGendarmes, (ObjectIndex)CURRENT_PARAM(2, 5));
+			getEntities()->enterCompartment(kEntityGendarmes, (ObjectIndex)CURRENT_PARAM(2, 5), true);
 
 			setCallback(parameters2->param6 ? 2 : 3);
 			setup_doDialog(parameters2->param6 ? "POL1044A" : "POL1044B");
@@ -234,7 +234,7 @@ IMPLEMENT_FUNCTION_IISS(9, Gendarmes, doCompartment, CarIndex, EntityPosition)
 
 		case 6:
 			getData()->location = kLocationOutsideCompartment;
-			getEntities()->exitCompartment(kEntityGendarmes, (ObjectIndex)parameters2->param5);
+			getEntities()->exitCompartment(kEntityGendarmes, (ObjectIndex)parameters2->param5, true);
 			callbackAction();
 			break;
 		}
@@ -249,10 +249,10 @@ IMPLEMENT_FUNCTION_III(10, Gendarmes, trappedCath, CarIndex, EntityPosition, Obj
 		break;
 
 	case kActionNone:
-		if (!params->param5 || getState()->timeTicks > (uint32)params->param5) {
-			if (!params->param5)
-				params->param5 = getState()->timeTicks + 75;
+		if (!params->param5)
+			params->param5 = getState()->timeTicks + 75;
 
+		if (getState()->timeTicks > (uint32)params->param5) {
 			if (!getEntities()->isOutsideAlexeiWindow() && getObjects()->get((ObjectIndex)params->param3).status != kObjectLocation1) {
 				setCallback(2);
 				setup_savegame(kSavegameTypeEvent, kEventGendarmesArrestation);
@@ -321,7 +321,7 @@ IMPLEMENT_FUNCTION_III(10, Gendarmes, trappedCath, CarIndex, EntityPosition, Obj
 			break;
 
 		case 3:
-			getAction()->playAnimation((params->param1 < kCarRedSleeping) ? kEventMertensBloodJacket : kEventCoudertBloodJacket);
+			getAction()->playAnimation((params->param1 == kCarGreenSleeping) ? kEventMertensBloodJacket : kEventCoudertBloodJacket);
 			getLogic()->gameOver(kSavegameTypeIndex, 1, kSceneGameOverBloodJacket, true);
 
 			getObjects()->update((ObjectIndex)params->param3, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
@@ -338,6 +338,7 @@ IMPLEMENT_FUNCTION_III(10, Gendarmes, trappedCath, CarIndex, EntityPosition, Obj
 
 		case 5:
 			getObjects()->update((ObjectIndex)params->param3, kEntityGendarmes, getObjects()->get((ObjectIndex)params->param3).status, kCursorNormal, kCursorHand);
+			params->param4 = 1;
 			break;
 
 		case 6:
@@ -574,7 +575,7 @@ void Gendarmes::handleAction(const SavePoint &savepoint, bool shouldPlaySound, S
 			ENTITY_PARAM(0, 1) = 1;
 		}
 
-		if (getEntities()->isDistanceBetweenEntities(kEntityGendarmes, kEntityPlayer, 1000) && !getEntityData(kEntityPlayer)->location) {
+		if (getEntities()->isDistanceBetweenEntities(kEntityGendarmes, kEntityPlayer, shouldUpdateEntity ? 1750 : 1000) && !getEntityData(kEntityPlayer)->location) {
 
 			if (shouldUpdateEntity)
 				if (getEntities()->isPlayerPosition(kCarRedSleeping, 22) && !getEntities()->isDistanceBetweenEntities(kEntityGendarmes, kEntityPlayer, 250))
@@ -585,13 +586,21 @@ void Gendarmes::handleAction(const SavePoint &savepoint, bool shouldPlaySound, S
 		}
 		break;
 
+	case kActionEndSound:
+		if (shouldPlaySound && !checkCallback && !shouldUpdateEntity) {
+			callbackAction();
+		}
+		break;
+
 	case kActionExitCompartment:
-		callbackAction();
+		if (!shouldPlaySound && !checkCallback && !shouldUpdateEntity) {
+			callbackAction();
+		}
 		break;
 
 	case kActionDefault:
 		// Only handle when passing SIIS params
-		if (!checkCallback) {
+		if (!checkCallback && !shouldUpdateEntity) {
 			EXPOSE_PARAMS(EntityData::EntityParametersSIIS);
 
 			if (!shouldPlaySound)
diff --git a/engines/lastexpress/entities/hadija.cpp b/engines/lastexpress/entities/hadija.cpp
index eb255d7..d925dd1 100644
--- a/engines/lastexpress/entities/hadija.cpp
+++ b/engines/lastexpress/entities/hadija.cpp
@@ -34,10 +34,10 @@ namespace LastExpress {
 
 Hadija::Hadija(LastExpressEngine *engine) : Entity(engine, kEntityHadija) {
 	ADD_CALLBACK_FUNCTION(Hadija, reset);
-	ADD_CALLBACK_FUNCTION(Hadija, enterExitCompartment);
-	ADD_CALLBACK_FUNCTION(Hadija, playSound);
-	ADD_CALLBACK_FUNCTION(Hadija, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Hadija, updateEntity);
+	ADD_CALLBACK_FUNCTION_SI(Hadija, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_S(Hadija, playSound);
+	ADD_CALLBACK_FUNCTION_I(Hadija, updateFromTime);
+	ADD_CALLBACK_FUNCTION_II(Hadija, updateEntity);
 	ADD_CALLBACK_FUNCTION(Hadija, peekF);
 	ADD_CALLBACK_FUNCTION(Hadija, peekH);
 	ADD_CALLBACK_FUNCTION(Hadija, goFtoH);
@@ -151,15 +151,15 @@ label_callback2:
 						return;
 					}
 				}
-
-				if (params->param3 >= getState()->time)
-					return;
 			}
+			if (getState()->time > kTime1134000 || getState()->time > params->param3) {
 
-			params->param3 = kTimeInvalid;
+				params->param3 = kTimeInvalid;
 
-			setCallback(3);
-			setup_peekH();
+				setCallback(3);
+				setup_peekH();
+				break;
+			}
 		}
 
 label_callback3:
@@ -343,10 +343,6 @@ label_callback4:
 		}
 		break;
 
-	case kActionDefault:
-		getSavePoints()->push(kEntityAlouan, kEntityTrain, kAction191070912, kPosition_4840);
-		break;
-
 	case kActionCallback:
 		switch (getCallback()) {
 		default:
diff --git a/engines/lastexpress/entities/ivo.cpp b/engines/lastexpress/entities/ivo.cpp
index 12a23e7d..bd38d69 100644
--- a/engines/lastexpress/entities/ivo.cpp
+++ b/engines/lastexpress/entities/ivo.cpp
@@ -38,15 +38,15 @@ namespace LastExpress {
 
 Ivo::Ivo(LastExpressEngine *engine) : Entity(engine, kEntityIvo) {
 	ADD_CALLBACK_FUNCTION(Ivo, reset);
-	ADD_CALLBACK_FUNCTION(Ivo, draw);
-	ADD_CALLBACK_FUNCTION(Ivo, enterExitCompartment);
-	ADD_CALLBACK_FUNCTION(Ivo, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Ivo, updateFromTicks);
-	ADD_CALLBACK_FUNCTION(Ivo, updateEntity);
+	ADD_CALLBACK_FUNCTION_S(Ivo, draw);
+	ADD_CALLBACK_FUNCTION_SI(Ivo, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_I(Ivo, updateFromTime);
+	ADD_CALLBACK_FUNCTION_I(Ivo, updateFromTicks);
+	ADD_CALLBACK_FUNCTION_II(Ivo, updateEntity);
 	ADD_CALLBACK_FUNCTION(Ivo, callbackActionOnDirection);
-	ADD_CALLBACK_FUNCTION(Ivo, playSound);
+	ADD_CALLBACK_FUNCTION_S(Ivo, playSound);
 	ADD_CALLBACK_FUNCTION(Ivo, callbackActionRestaurantOrSalon);
-	ADD_CALLBACK_FUNCTION(Ivo, savegame);
+	ADD_CALLBACK_FUNCTION_II(Ivo, savegame);
 	ADD_CALLBACK_FUNCTION(Ivo, goCompartment);
 	ADD_CALLBACK_FUNCTION(Ivo, sitAtTableWithSalko);
 	ADD_CALLBACK_FUNCTION(Ivo, leaveTableWithSalko);
@@ -270,6 +270,7 @@ IMPLEMENT_FUNCTION(15, Ivo, chapter1Handler)
 	case kActionNone:
 		getData()->entityPosition = getEntityData(kEntityMilos)->entityPosition;
 		getData()->location = getEntityData(kEntityMilos)->location;
+		getData()->car = getEntityData(kEntityMilos)->car;
 		break;
 
 	case kActionCallback:
@@ -318,7 +319,7 @@ IMPLEMENT_FUNCTION(16, Ivo, inCompartment)
 
 		case 1:
 			getEntities()->drawSequenceLeft(kEntityIvo, "613Ch");
-			getEntities()->enterCompartment(kEntityIvo, kObjectCompartmentH);
+			getEntities()->enterCompartment(kEntityIvo, kObjectCompartmentH, true);
 			getSavePoints()->push(kEntityIvo, kEntityCoudert, kAction88652208);
 			break;
 
@@ -384,7 +385,7 @@ IMPLEMENT_FUNCTION(18, Ivo, chapter2)
 		getData()->inventoryItem = kItemNone;
 
 		getObjects()->update(kObjectCompartmentH, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
-		getObjects()->update(kObject47, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
+		getObjects()->update(kObject47, kEntityPlayer, kObjectLocation1, kCursorKeepValue, kCursorKeepValue);
 
 		break;
 	}
@@ -744,7 +745,7 @@ IMPLEMENT_FUNCTION_END
 
 //////////////////////////////////////////////////////////////////////////
 IMPLEMENT_FUNCTION(31, Ivo, chapter5Handler)
-	if (savepoint.action == kActionProceedChapter5)
+	if (savepoint.action == kAction192637492)
 		setup_fightCath();
 IMPLEMENT_FUNCTION_END
 
@@ -780,7 +781,7 @@ IMPLEMENT_FUNCTION(32, Ivo, fightCath)
 		case 2:
 			params->param1 = getFight()->setup(kFightIvo);
 			if (params->param1) {
-				getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, true);
+				getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, params->param1 == Fight::kFightEndLost);
 			} else {
 				getScenes()->loadSceneFromPosition(kCarBaggageRear, 96);
 				setup_knockedOut();
diff --git a/engines/lastexpress/entities/kahina.cpp b/engines/lastexpress/entities/kahina.cpp
index 047e3f0..3b15053 100644
--- a/engines/lastexpress/entities/kahina.cpp
+++ b/engines/lastexpress/entities/kahina.cpp
@@ -39,14 +39,14 @@ namespace LastExpress {
 
 Kahina::Kahina(LastExpressEngine *engine) : Entity(engine, kEntityKahina) {
 	ADD_CALLBACK_FUNCTION(Kahina, reset);
-	ADD_CALLBACK_FUNCTION(Kahina, playSound);
-	ADD_CALLBACK_FUNCTION(Kahina, savegame);
-	ADD_CALLBACK_FUNCTION(Kahina, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Kahina, updateFromTicks);
-	ADD_CALLBACK_FUNCTION(Kahina, lookingForCath);
-	ADD_CALLBACK_FUNCTION(Kahina, updateEntity2);
-	ADD_CALLBACK_FUNCTION(Kahina, updateEntity);
-	ADD_CALLBACK_FUNCTION(Kahina, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_S(Kahina, playSound);
+	ADD_CALLBACK_FUNCTION_II(Kahina, savegame);
+	ADD_CALLBACK_FUNCTION_I(Kahina, updateFromTime);
+	ADD_CALLBACK_FUNCTION_I(Kahina, updateFromTicks);
+	ADD_CALLBACK_FUNCTION_I(Kahina, lookingForCath);
+	ADD_CALLBACK_FUNCTION_II(Kahina, updateEntity2);
+	ADD_CALLBACK_FUNCTION_II(Kahina, updateEntity);
+	ADD_CALLBACK_FUNCTION_SI(Kahina, enterExitCompartment);
 	ADD_CALLBACK_FUNCTION(Kahina, chapter1);
 	ADD_CALLBACK_FUNCTION(Kahina, chapter1Handler);
 	ADD_CALLBACK_FUNCTION(Kahina, awaitingCath);
@@ -56,7 +56,7 @@ Kahina::Kahina(LastExpressEngine *engine) : Entity(engine, kEntityKahina) {
 	ADD_CALLBACK_FUNCTION(Kahina, chapter2);
 	ADD_CALLBACK_FUNCTION(Kahina, inSeclusionPart2);
 	ADD_CALLBACK_FUNCTION(Kahina, chapter3);
-	ADD_CALLBACK_FUNCTION(Kahina, function19);
+	ADD_CALLBACK_FUNCTION_II(Kahina, function19);
 	ADD_CALLBACK_FUNCTION(Kahina, beforeConcert);
 	ADD_CALLBACK_FUNCTION(Kahina, concert);
 	ADD_CALLBACK_FUNCTION(Kahina, finished);
@@ -194,12 +194,12 @@ IMPLEMENT_FUNCTION_II(7, Kahina, updateEntity2, CarIndex, EntityPosition)
 	default:
 		break;
 
-	case kActionNone:
+	case kActionDefault:
 		if (getEntities()->updateEntity(_entityIndex, (CarIndex)params->param1, (EntityPosition)params->param2))
 			callbackAction();
 		break;
 
-	case kActionDefault:
+	case kActionNone:
 		if (getEntities()->updateEntity(_entityIndex, (CarIndex)params->param1, (EntityPosition)params->param2)) {
 			callbackAction();
 		} else if (getEntities()->isDistanceBetweenEntities(kEntityKahina, kEntityPlayer, 1000)
@@ -579,14 +579,14 @@ IMPLEMENT_FUNCTION(17, Kahina, inSeclusionPart2)
 		break;
 
 	case kActionNone:
-		if (params->param1) {
+		if (!params->param1) {
 			if (Entity::updateParameter(params->param2, getState()->time, 9000)) {
 				params->param1 = 1;
 				params->param2 = 0;
 			}
 		}
 
-		if (getEvent(kEventKahinaAskSpeakFirebird) && getEvent(kEventKronosConversationFirebird) && getEntities()->isInsideTrainCar(kEntityPlayer, kCarKronos)) {
+		if (getEvent(kEventKahinaAskSpeakFirebird) && !getEvent(kEventKronosConversationFirebird) && getEntities()->isInsideTrainCar(kEntityPlayer, kCarKronos)) {
 			if (Entity::updateParameter(params->param3, getState()->time, 900)) {
 				setCallback(1);
 				setup_savegame(kSavegameTypeEvent, kEventKronosConversationFirebird);
@@ -927,7 +927,7 @@ IMPLEMENT_FUNCTION(21, Kahina, concert)
 			if (!params->param3)
 				params->param3 = (uint)getState()->time + 4500;
 
-			if (params->param6 != kTimeInvalid) {
+			if (params->param5 != kTimeInvalid) {
 				if (Entity::updateParameterTime((TimeValue)params->param3, (getEntities()->isPlayerPosition(kCarKronos, 80) || getEntities()->isPlayerPosition(kCarKronos, 88)), params->param5, 0)) {
 					setCallback(2);
 					setup_findFirebird();
@@ -1043,7 +1043,7 @@ IMPLEMENT_FUNCTION(22, Kahina, finished)
 		break;
 
 	case kActionDrawScene:
-		if (getData()->car > kCarGreenSleeping || (getData()->car == kCarGreenSleeping && getData()->entityPosition > kPosition_2740))
+		if (getEntityData(kEntityPlayer)->car > kCarGreenSleeping || (getEntityData(kEntityPlayer)->car == kCarGreenSleeping && getEntityData(kEntityPlayer)->entityPosition > kPosition_2740))
 			params->param1 = 1;
 		break;
 	}
@@ -1181,7 +1181,7 @@ IMPLEMENT_FUNCTION(24, Kahina, seekCath)
 
 		case 2:
 			if (getEntityData(kEntityPlayer)->entityPosition >= getData()->entityPosition)
-				getAction()->playAnimation(getData()->car < kCarRedSleeping ? kEventKahinaGunYellow : kEventKahinaGunBlue);
+				getAction()->playAnimation(getData()->car == kCarRedSleeping ? kEventKahinaGunYellow : kEventKahinaGunBlue);
 			else
 				getAction()->playAnimation(kEventKahinaGun);
 
@@ -1396,7 +1396,7 @@ IMPLEMENT_FUNCTION(26, Kahina, searchTatiana)
 			break;
 
 		case 1:
-			if (getEntities()->checkFields19(kEntityPlayer, kCarGreenSleeping, kPosition_7850)) {
+			if (getEntities()->checkFields19(kEntityPlayer, kCarRedSleeping, kPosition_7850)) {
 				setCallback(2);
 				setup_function19(kCarRedSleeping, kPosition_9460);
 			} else {
diff --git a/engines/lastexpress/entities/kronos.cpp b/engines/lastexpress/entities/kronos.cpp
index 61c1641..60be35e 100644
--- a/engines/lastexpress/entities/kronos.cpp
+++ b/engines/lastexpress/entities/kronos.cpp
@@ -63,11 +63,11 @@ static const struct {
 
 Kronos::Kronos(LastExpressEngine *engine) : Entity(engine, kEntityKronos) {
 	ADD_CALLBACK_FUNCTION(Kronos, reset);
-	ADD_CALLBACK_FUNCTION(Kronos, savegame);
-	ADD_CALLBACK_FUNCTION(Kronos, updateEntity);
-	ADD_CALLBACK_FUNCTION(Kronos, playSound);
-	ADD_CALLBACK_FUNCTION(Kronos, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Kronos, updateFromTicks);
+	ADD_CALLBACK_FUNCTION_II(Kronos, savegame);
+	ADD_CALLBACK_FUNCTION_II(Kronos, updateEntity);
+	ADD_CALLBACK_FUNCTION_S(Kronos, playSound);
+	ADD_CALLBACK_FUNCTION_I(Kronos, updateFromTime);
+	ADD_CALLBACK_FUNCTION_I(Kronos, updateFromTicks);
 	ADD_CALLBACK_FUNCTION(Kronos, chapter1);
 	ADD_CALLBACK_FUNCTION(Kronos, chapter1Handler);
 	ADD_CALLBACK_FUNCTION(Kronos, greetCath);
@@ -147,7 +147,16 @@ IMPLEMENT_FUNCTION(8, Kronos, chapter1Handler)
 		break;
 
 	case kActionNone:
-		Entity::timeCheck(kTime1489500, params->param2, WRAP_SETUP_FUNCTION(Kronos, setup_function11));
+		if (Entity::timeCheck(kTime1489500, params->param2, WRAP_SETUP_FUNCTION(Kronos, setup_function11)))
+			break;
+
+		if (params->param1 && getEntities()->isInsideTrainCar(kEntityPlayer, kCarKronos)) {
+			if (Entity::updateParameter(params->param3, getState()->timeTicks, 150)) {
+				setup_greetCath();
+				break;
+			}
+		}
+
 		break;
 
 	case kAction171849314:
@@ -260,7 +269,7 @@ IMPLEMENT_FUNCTION(14, Kronos, chapter3Handler)
 		break;
 
 	case kActionNone:
-		if (getState()->time > kTime1993500 && !params->param1 && !params->param2 && !params->param3)
+		if (getState()->time > kTime1993500 && params->param1 && params->param2 && params->param3)
 			setup_function15();
 		break;
 
@@ -301,7 +310,7 @@ IMPLEMENT_FUNCTION(15, Kronos, function15)
 
 		if (params->param3 != kTimeInvalid && getState()->time > kTime2002500) {
 			if (getState()->time <= kTime2052000) {
-				if (!getEntities()->isInSalon(kEntityPlayer) || getEntities()->isInSalon(kEntityPlayer) || !params->param3)
+				if (!getEntities()->isInSalon(kEntityPlayer) || getEntities()->isInSalon(kEntityBoutarel) || !params->param3)
 					params->param3 = (uint)getState()->time + 900;
 
 				if (params->param3 >= getState()->time)
@@ -381,7 +390,7 @@ IMPLEMENT_FUNCTION(17, Kronos, returnCompartment)
 		getData()->car = kCarRedSleeping;
 
 		setCallback(1);
-		setup_updateEntity(kCarGreenSleeping, kPosition_9270);
+		setup_updateEntity(kCarKronos, kPosition_9270);
 		break;
 
 	case kActionCallback:
@@ -435,6 +444,19 @@ IMPLEMENT_FUNCTION(19, Kronos, startConcert)
 		break;
 
 	case kActionNone:
+		if (getState()->time > kTime2115000 && !params->param1) {
+			params->param1 = 1;
+			getSound()->playSound(kEntityKronos, "1917.lnk");
+			setup_duringConcert();
+			break;
+		}
+
+		if (getEntities()->isInKronosSanctum(kEntityPlayer)) {
+			setCallback(1);
+			setup_savegame(kSavegameTypeEvent, kEventKahinaPunchSuite4);
+			break;
+		}
+
 		break;
 
 	case kActionDefault:
@@ -442,6 +464,14 @@ IMPLEMENT_FUNCTION(19, Kronos, startConcert)
 		break;
 
 	case kActionDrawScene:
+		if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarKronos)
+		 && !getEntities()->isInKronosSanctum(kEntityPlayer)
+		 && !getInventory()->hasItem(kItemFirebird)
+		 && !getEvent(kEventConcertStart)) {
+			getEntities()->drawSequenceLeft(kEntityKronos, "201a");
+			setCallback(2);
+			setup_savegame(kSavegameTypeEvent, kEventConcertStart);
+		}
 		break;
 
 	case kActionCallback:
@@ -479,6 +509,7 @@ IMPLEMENT_FUNCTION(20, Kronos, duringConcert)
 		break;
 
 	case kActionNone:
+		// TODO: should *2 really be there? should it be /2?
 		params->param5 = getSoundQueue()->getEntryTime(kEntityKronos)* 2;
 
 		if (params->param6 < ARRAYSIZE(concertData) && params->param5 > concertData[params->param6].time) {
@@ -734,12 +765,14 @@ IMPLEMENT_FUNCTION(22, Kronos, awaitingCath)
 		break;
 
 	case kActionNone:
-		if (getProgress().field_44) {
-			setCallback(5);
-			setup_savegame(kSavegameTypeEvent, kEventKahinaPunchBaggageCarEntrance);
-		} else {
-			setCallback(6);
-			setup_savegame(kSavegameTypeEvent, kEventKahinaWrongDoor);
+		if (getEntities()->isInKronosSanctum(kEntityPlayer)) {
+			if (getProgress().field_44) {
+				setCallback(5);
+				setup_savegame(kSavegameTypeEvent, kEventKahinaPunchBaggageCarEntrance);
+			} else {
+				setCallback(6);
+				setup_savegame(kSavegameTypeEvent, kEventKahinaWrongDoor);
+			}
 		}
 		break;
 
diff --git a/engines/lastexpress/entities/mahmud.cpp b/engines/lastexpress/entities/mahmud.cpp
index 08edda5..9f43c69 100644
--- a/engines/lastexpress/entities/mahmud.cpp
+++ b/engines/lastexpress/entities/mahmud.cpp
@@ -41,15 +41,15 @@ namespace LastExpress {
 
 Mahmud::Mahmud(LastExpressEngine *engine) : Entity(engine, kEntityMahmud) {
 	ADD_CALLBACK_FUNCTION(Mahmud, reset);
-	ADD_CALLBACK_FUNCTION(Mahmud, draw);
-	ADD_CALLBACK_FUNCTION(Mahmud, enterExitCompartment);
-	ADD_CALLBACK_FUNCTION(Mahmud, enterExitCompartment2);
-	ADD_CALLBACK_FUNCTION(Mahmud, playSound);
-	ADD_CALLBACK_FUNCTION(Mahmud, playSoundMertens);
-	ADD_CALLBACK_FUNCTION(Mahmud, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Mahmud, savegame);
-	ADD_CALLBACK_FUNCTION(Mahmud, updateEntity);
-	ADD_CALLBACK_FUNCTION(Mahmud, function10);
+	ADD_CALLBACK_FUNCTION_S(Mahmud, draw);
+	ADD_CALLBACK_FUNCTION_SI(Mahmud, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_SIII(Mahmud, enterExitCompartment2);
+	ADD_CALLBACK_FUNCTION_S(Mahmud, playSound);
+	ADD_CALLBACK_FUNCTION_S(Mahmud, playSoundMertens);
+	ADD_CALLBACK_FUNCTION_I(Mahmud, updateFromTime);
+	ADD_CALLBACK_FUNCTION_II(Mahmud, savegame);
+	ADD_CALLBACK_FUNCTION_II(Mahmud, updateEntity);
+	ADD_CALLBACK_FUNCTION_II(Mahmud, function10);
 	ADD_CALLBACK_FUNCTION(Mahmud, function11);
 	ADD_CALLBACK_FUNCTION(Mahmud, function12);
 	ADD_CALLBACK_FUNCTION(Mahmud, function13);
@@ -128,7 +128,7 @@ IMPLEMENT_FUNCTION_END
 IMPLEMENT_FUNCTION_II(9, Mahmud, updateEntity, CarIndex, EntityPosition)
 	if (savepoint.action == kActionExcuseMeCath) {
 		if (getInventory()->hasItem(kItemPassengerList))
-			getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1025" : "CAT1025Q");
+			getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1025" : "CAT1025A");
 		else
 			getSound()->excuseMeCath();
 
@@ -189,7 +189,7 @@ IMPLEMENT_FUNCTION_II(10, Mahmud, function10, ObjectIndex, bool)
 				break;
 
 			case 1:
-				getSound()->playSound(kEntityMahmud, "MAH1174");
+				getSound()->playSound(kEntityMahmud, params->param2 ? "MAH1170E" : "MAH1173A");
 				break;
 
 			case 2:
@@ -197,7 +197,7 @@ IMPLEMENT_FUNCTION_II(10, Mahmud, function10, ObjectIndex, bool)
 				break;
 
 			case 3:
-				getSound()->playSound(kEntityMahmud, params->param2 ? "MAH1170E" : "MAH1173A");
+				getSound()->playSound(kEntityMahmud, "MAH1174");
 				break;
 			}
 		}
@@ -720,7 +720,7 @@ IMPLEMENT_FUNCTION(14, Mahmud, chaptersHandler)
 		break;
 
 	case kAction290410610:
-		params->param3 = (params->param3 < 1) ? 1 : 0;
+		params->param3 = (params->param3 == 0) ? 1 : 0;
 		setCallback(11);
 		setup_function10((ObjectIndex)savepoint.param.intValue, (bool)params->param3);
 		break;
diff --git a/engines/lastexpress/entities/max.cpp b/engines/lastexpress/entities/max.cpp
index d75b6af..180bc1d 100644
--- a/engines/lastexpress/entities/max.cpp
+++ b/engines/lastexpress/entities/max.cpp
@@ -38,10 +38,10 @@ namespace LastExpress {
 
 Max::Max(LastExpressEngine *engine) : Entity(engine, kEntityMax) {
 	ADD_CALLBACK_FUNCTION(Max, reset);
-	ADD_CALLBACK_FUNCTION(Max, playSound);
-	ADD_CALLBACK_FUNCTION(Max, draw);
-	ADD_CALLBACK_FUNCTION(Max, enterExitCompartment);
-	ADD_CALLBACK_FUNCTION(Max, savegame);
+	ADD_CALLBACK_FUNCTION_S(Max, playSound);
+	ADD_CALLBACK_FUNCTION_S(Max, draw);
+	ADD_CALLBACK_FUNCTION_SI(Max, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_II(Max, savegame);
 	ADD_CALLBACK_FUNCTION(Max, withAnna);
 	ADD_CALLBACK_FUNCTION(Max, guardingCompartment);
 	ADD_CALLBACK_FUNCTION(Max, inCageFriendly);
@@ -95,12 +95,12 @@ IMPLEMENT_FUNCTION(6, Max, withAnna)
 		if (!getSoundQueue()->isBuffered(kEntityMax))
 			getSound()->playSound(kEntityMax, "Max1122");
 
-		params->param1 = 255 * (4 * rnd(20) + 40);
+		params->param1 = 225 * (4 * rnd(20) + 40);
 		params->param2 = 0;
 		break;
 
 	case kActionDefault:
-		params->param1 = 255 * (4 * rnd(20) + 40);
+		params->param1 = 225 * (4 * rnd(20) + 40);
 		break;
 
 	case kAction71277948:
@@ -111,7 +111,7 @@ IMPLEMENT_FUNCTION(6, Max, withAnna)
 	case kAction158007856:
 		if (!getSoundQueue()->isBuffered(kEntityMax)) {
 			getSound()->playSound(kEntityMax, "Max1122");
-			params->param1 = 255 * (4 * rnd(20) + 40);
+			params->param1 = 225 * (4 * rnd(20) + 40);
 		}
 		break;
 	}
@@ -130,7 +130,7 @@ IMPLEMENT_FUNCTION(7, Max, guardingCompartment)
 		if (!getSoundQueue()->isBuffered(kEntityMax))
 			getSound()->playSound(kEntityMax, "Max1122");
 
-		params->param1 = 255 * (4 * rnd(20) + 40);
+		params->param1 = 225 * (4 * rnd(20) + 40);
 		params->param2 = 0;
 		break;
 
@@ -147,7 +147,7 @@ IMPLEMENT_FUNCTION(7, Max, guardingCompartment)
 		break;
 
 	case kActionDefault:
-		params->param1 = 255 * (4 * rnd(20) + 40);
+		params->param1 = 225 * (4 * rnd(20) + 40);
 
 		getData()->entityPosition = kPosition_4070;
 		getData()->location = kLocationInsideCompartment;
@@ -160,7 +160,7 @@ IMPLEMENT_FUNCTION(7, Max, guardingCompartment)
 	case kActionDrawScene:
 		if (!getSoundQueue()->isBuffered(kEntityMax)) {
 			if (getEntities()->isPlayerPosition(kCarRedSleeping, 56) || getEntities()->isPlayerPosition(kCarRedSleeping, 78))
-				getSound()->playSound(kEntityMax, "Max1120");
+				getSound()->playSound(kEntityMax, "MAX1120");
 		}
 		break;
 
@@ -173,7 +173,7 @@ IMPLEMENT_FUNCTION(7, Max, guardingCompartment)
 		case 1:
 		case 2:
 			setCallback(3);
-			setup_playSound("Max1122");
+			setup_playSound("MAX1122");
 			break;
 
 		case 3:
@@ -201,7 +201,7 @@ IMPLEMENT_FUNCTION(7, Max, guardingCompartment)
 	case kAction158007856:
 		if (!getSoundQueue()->isBuffered(kEntityMax)) {
 			getSound()->playSound(kEntityMax, "Max1122");
-			params->param1 = 255 * (4 * rnd(20) + 40);
+			params->param1 = 225 * (4 * rnd(20) + 40);
 		}
 		break;
 	}
@@ -220,7 +220,7 @@ IMPLEMENT_FUNCTION(8, Max, inCageFriendly)
 		if (!getSoundQueue()->isBuffered(kEntityMax))
 			getSound()->playSound(kEntityMax, "Max3101");
 
-		params->param2 = 255 * (4 * rnd(20) + 40);
+		params->param2 = 225 * (4 * rnd(4) + 8);
 		params->param3 = 0;
 		break;
 
@@ -241,7 +241,7 @@ IMPLEMENT_FUNCTION(8, Max, inCageFriendly)
 		break;
 
 	case kActionDefault:
-		params->param2 = 255 * (4 * rnd(20) + 40);
+		params->param2 = 225 * (4 * rnd(4) + 8);
 
 		getObjects()->update(kObjectCageMax, kEntityMax, kObjectLocationNone, kCursorNormal, kCursorHand);
 		getEntities()->clearSequences(kEntityMax);
@@ -360,7 +360,7 @@ IMPLEMENT_FUNCTION(11, Max, chapter2)
 IMPLEMENT_FUNCTION_END
 
 //////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION(13, Max, chapter3)
+IMPLEMENT_FUNCTION(12, Max, chapter3)
 	switch (savepoint.action) {
 	default:
 		break;
@@ -390,6 +390,8 @@ IMPLEMENT_FUNCTION(13, Max, chapter3Handler)
 	case kActionNone:
 		if (params->param2) {
 			getData()->entityPosition = getEntityData(kEntityCoudert)->entityPosition;
+			getData()->location = getEntityData(kEntityCoudert)->location;
+			getData()->car = getEntityData(kEntityCoudert)->car;
 			break;
 		}
 
@@ -399,12 +401,12 @@ IMPLEMENT_FUNCTION(13, Max, chapter3Handler)
 		if (!getSoundQueue()->isBuffered(kEntityMax))
 			getSound()->playSound(kEntityMax, "Max1122");
 
-		params->param1 = 255 * (4 * rnd(20) + 40);
+		params->param1 = 225 * (4 * rnd(20) + 40);
 		params->param3 = 0;
 		break;
 
 	case kActionDefault:
-		params->param1 = 255 * (4 * rnd(20) + 40);
+		params->param1 = 225 * (4 * rnd(20) + 40);
 
 		getData()->entityPosition = kPosition_4070;
 		getData()->location = kLocationInsideCompartment;
@@ -430,7 +432,7 @@ IMPLEMENT_FUNCTION(13, Max, chapter3Handler)
 
 		if (!getSoundQueue()->isBuffered(kEntityMax)) {
 			getSound()->playSound(kEntityMax, "Max1122");
-			params->param1 = 255 * (4 * rnd(20) + 40);
+			params->param1 = 225 * (4 * rnd(20) + 40);
 		}
 		break;
 	}
@@ -450,7 +452,7 @@ IMPLEMENT_FUNCTION(14, Max, inCageMad)
 	// Save game after freeing Max from his cage
 	case kActionOpenDoor:
 		if (getEvent(kEventCathMaxCage)) {
-			if (getEvent(kEventCathMaxFree)) {
+			if (!getEvent(kEventCathMaxFree)) {
 				setCallback(2);
 				setup_savegame(kSavegameTypeEvent, kEventCathMaxFree);
 			}
@@ -512,6 +514,7 @@ IMPLEMENT_FUNCTION(15, Max, letMeIn)
 	case kActionNone:
 		if (params->param2) {
 			getData()->entityPosition = getEntityData(kEntityCoudert)->entityPosition;
+			getData()->location = getEntityData(kEntityCoudert)->location;
 			getData()->car = getEntityData(kEntityCoudert)->car;
 		}
 
@@ -532,7 +535,7 @@ IMPLEMENT_FUNCTION(15, Max, letMeIn)
 			getSound()->playSound(kEntityMax, "Max3010");
 
 		setCallback(1);
-		setup_enterExitCompartment("630Bf", kObjectCompartment4);
+		setup_enterExitCompartment("630Bf", kObjectCompartmentF);
 		break;
 
 	case kActionCallback:
@@ -585,6 +588,7 @@ IMPLEMENT_FUNCTION(17, Max, function17)
 	case kActionNone:
 		if (params->param1) {
 			getData()->entityPosition = getEntityData(kEntityCoudert)->entityPosition;
+			getData()->location = getEntityData(kEntityCoudert)->location;
 			getData()->car = getEntityData(kEntityCoudert)->car;
 		}
 		break;
diff --git a/engines/lastexpress/entities/mertens.cpp b/engines/lastexpress/entities/mertens.cpp
index 7126adb..573a350 100644
--- a/engines/lastexpress/entities/mertens.cpp
+++ b/engines/lastexpress/entities/mertens.cpp
@@ -40,36 +40,36 @@ namespace LastExpress {
 
 Mertens::Mertens(LastExpressEngine *engine) : Entity(engine, kEntityMertens) {
 	ADD_CALLBACK_FUNCTION(Mertens, reset);
-	ADD_CALLBACK_FUNCTION(Mertens, bloodJacket);
-	ADD_CALLBACK_FUNCTION(Mertens, enterExitCompartment);
-	ADD_CALLBACK_FUNCTION(Mertens, enterExitCompartment2);
-	ADD_CALLBACK_FUNCTION(Mertens, enterExitCompartment3);
+	ADD_CALLBACK_FUNCTION_S(Mertens, bloodJacket);
+	ADD_CALLBACK_FUNCTION_SI(Mertens, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_SI(Mertens, enterExitCompartment2);
+	ADD_CALLBACK_FUNCTION_SIII(Mertens, enterExitCompartment3);
 	ADD_CALLBACK_FUNCTION(Mertens, callbackActionOnDirection);
-	ADD_CALLBACK_FUNCTION(Mertens, playSound);
-	ADD_CALLBACK_FUNCTION(Mertens, playSound16);
-	ADD_CALLBACK_FUNCTION(Mertens, savegame);
-	ADD_CALLBACK_FUNCTION(Mertens, updateEntity);
-	ADD_CALLBACK_FUNCTION(Mertens, function11);
-	ADD_CALLBACK_FUNCTION(Mertens, bonsoir);
-	ADD_CALLBACK_FUNCTION(Mertens, function13);
-	ADD_CALLBACK_FUNCTION(Mertens, function14);
-	ADD_CALLBACK_FUNCTION(Mertens, function15);
-	ADD_CALLBACK_FUNCTION(Mertens, function16);
+	ADD_CALLBACK_FUNCTION_S(Mertens, playSound);
+	ADD_CALLBACK_FUNCTION_S(Mertens, playSound16);
+	ADD_CALLBACK_FUNCTION_II(Mertens, savegame);
+	ADD_CALLBACK_FUNCTION_II(Mertens, updateEntity);
+	ADD_CALLBACK_FUNCTION_I(Mertens, function11);
+	ADD_CALLBACK_FUNCTION_I(Mertens, bonsoir);
+	ADD_CALLBACK_FUNCTION_II(Mertens, function13);
+	ADD_CALLBACK_FUNCTION_I(Mertens, function14);
+	ADD_CALLBACK_FUNCTION_I(Mertens, function15);
+	ADD_CALLBACK_FUNCTION_I(Mertens, function16);
 	ADD_CALLBACK_FUNCTION(Mertens, function17);
 	ADD_CALLBACK_FUNCTION(Mertens, function18);
 	ADD_CALLBACK_FUNCTION(Mertens, function19);
 	ADD_CALLBACK_FUNCTION(Mertens, function20);
-	ADD_CALLBACK_FUNCTION(Mertens, function21);
+	ADD_CALLBACK_FUNCTION_II(Mertens, function21);
 	ADD_CALLBACK_FUNCTION(Mertens, function22);
 	ADD_CALLBACK_FUNCTION(Mertens, function23);
 	ADD_CALLBACK_FUNCTION(Mertens, function24);
 	ADD_CALLBACK_FUNCTION(Mertens, function25);
-	ADD_CALLBACK_FUNCTION(Mertens, function26);
-	ADD_CALLBACK_FUNCTION(Mertens, tylerCompartment);
-	ADD_CALLBACK_FUNCTION(Mertens, function28);
-	ADD_CALLBACK_FUNCTION(Mertens, function29);
-	ADD_CALLBACK_FUNCTION(Mertens, function30);
-	ADD_CALLBACK_FUNCTION(Mertens, function31);
+	ADD_CALLBACK_FUNCTION_I(Mertens, function26);
+	ADD_CALLBACK_FUNCTION_I(Mertens, tylerCompartment);
+	ADD_CALLBACK_FUNCTION_S(Mertens, function28);
+	ADD_CALLBACK_FUNCTION_SS(Mertens, function29);
+	ADD_CALLBACK_FUNCTION_I(Mertens, function30);
+	ADD_CALLBACK_FUNCTION_I(Mertens, function31);
 	ADD_CALLBACK_FUNCTION(Mertens, function32);
 	ADD_CALLBACK_FUNCTION(Mertens, function33);
 	ADD_CALLBACK_FUNCTION(Mertens, chapter1);
@@ -107,7 +107,7 @@ IMPLEMENT_FUNCTION_S(2, Mertens, bloodJacket)
 		break;
 
 	case kActionNone:
-		Entity::savegameBloodJacket();
+		Entity::savegameBloodJacket(1);
 		break;
 
 	case kActionExitCompartment:
@@ -134,7 +134,7 @@ IMPLEMENT_FUNCTION_SI(3, Mertens, enterExitCompartment, ObjectIndex)
 		break;
 
 	case kActionNone:
-		Entity::savegameBloodJacket();
+		Entity::savegameBloodJacket(1);
 		return;
 
 	case kActionCallback:
@@ -155,7 +155,7 @@ IMPLEMENT_FUNCTION_SI(4, Mertens, enterExitCompartment2, ObjectIndex)
 		break;
 
 	case kActionNone:
-		Entity::savegameBloodJacket();
+		Entity::savegameBloodJacket(1);
 		return;
 
 	case kAction4:
@@ -181,7 +181,7 @@ IMPLEMENT_FUNCTION_SIII(5, Mertens, enterExitCompartment3, ObjectIndex, EntityPo
 		break;
 
 	case kActionNone:
-		Entity::savegameBloodJacket();
+		Entity::savegameBloodJacket(1);
 		break;
 
 	case kActionExitCompartment:
@@ -223,7 +223,7 @@ IMPLEMENT_FUNCTION(6, Mertens, callbackActionOnDirection)
 			break;
 		}
 
-		Entity::savegameBloodJacket();
+		Entity::savegameBloodJacket(1);
 		break;
 
 	case kActionExitCompartment:
@@ -246,7 +246,7 @@ IMPLEMENT_FUNCTION_S(7, Mertens, playSound)
 		break;
 
 	case kActionNone:
-		Entity::savegameBloodJacket();
+		Entity::savegameBloodJacket(1);
 		break;
 
 	case kActionEndSound:
@@ -273,7 +273,7 @@ IMPLEMENT_FUNCTION_S(8, Mertens, playSound16)
 		break;
 
 	case kActionNone:
-		Entity::savegameBloodJacket();
+		Entity::savegameBloodJacket(1);
 		break;
 
 	case kActionEndSound:
@@ -352,6 +352,7 @@ IMPLEMENT_FUNCTION_II(10, Mertens, updateEntity, CarIndex, EntityPosition)
 
 	case kAction1:
 		params->param3 = 0;
+		getData()->inventoryItem = kItemNone;
 		if (getProgress().eventCorpseFound || getEvent(kEventMertensAskTylerCompartment) || getEvent(kEventMertensAskTylerCompartmentD)) {
 			if (ENTITY_PARAM(0, 4) && getProgress().jacket == kJacketGreen && !getEvent(kEventMertensDontMakeBed) && !getProgress().eventCorpseThrown) {
 				setCallback(6);
@@ -462,7 +463,8 @@ IMPLEMENT_FUNCTION_I(11, Mertens, function11, uint32)
 		break;
 
 	case kActionNone:
-		Entity::savegameBloodJacket();
+		if (Entity::savegameBloodJacket(1))
+			break;
 
 		if (!Entity::updateParameter(params->param2, getState()->time, params->param1))
 			break;
@@ -483,7 +485,7 @@ IMPLEMENT_FUNCTION_END
 IMPLEMENT_FUNCTION_I(12, Mertens, bonsoir, EntityIndex)
 	EntityIndex entity = (EntityIndex)params->param1;
 
-	if (savepoint.action == kActionDefault)
+	if (savepoint.action != kActionDefault)
 		return;
 
 	if (getSoundQueue()->isBuffered(kEntityMertens)) {
@@ -495,7 +497,7 @@ IMPLEMENT_FUNCTION_I(12, Mertens, bonsoir, EntityIndex)
 		if (Entities::isFemale(entity)) {
 			getSound()->playSound(kEntityMertens, rnd(2) ? "CON1112" : "CON1112A");
 		} else {
-			if (entity || getProgress().field_18 != 2) {
+			if (entity != kEntityPlayer || getProgress().field_18 != 2) {
 				getSound()->playSound(kEntityMertens, "CON1112F");
 			} else {
 				switch (rnd(3)) {
@@ -525,15 +527,16 @@ IMPLEMENT_FUNCTION_I(12, Mertens, bonsoir, EntityIndex)
 IMPLEMENT_FUNCTION_END
 
 //////////////////////////////////////////////////////////////////////////
-IMPLEMENT_FUNCTION_II(13, Mertens, function13, bool, bool)
+IMPLEMENT_FUNCTION_II(13, Mertens, function13, bool, EntityIndex)
 	switch (savepoint.action) {
 	default:
 		break;
 
 	case kActionNone:
-		Entity::savegameBloodJacket();
+		if (Entity::savegameBloodJacket(4))
+			break;
 
-		if (!params->param2 && !params->param3) {
+		if (params->param2 == kEntityPlayer && !params->param3) {
 			if (Entity::updateParameter(params->param4, getState()->timeTicks, 75)) {
 				getData()->inventoryItem = kItemNone;
 				setCallback(5);
@@ -569,11 +572,29 @@ IMPLEMENT_FUNCTION_II(13, Mertens, function13, bool, bool)
 		break;
 
 	case kActionDefault:
-		if (params->param2)
+		if (params->param2 != kEntityPlayer)
 			params->param3 = 1;
 
 		if (!getSoundQueue()->isBuffered(kEntityMertens)) {
-
+			if (getProgress().chapter == kChapter3 && !params->param1 && getState()->time < kTime2173500 &&
+			 (getState()->time > kTime2106000 || params->param2 != kEntityPlayer && getState()->time > kTime2079000)) {
+				// guide guests to the concert
+				if (params->param2 == kEntityAugust)
+					getSound()->playSound(kEntityMertens, "CON3052");
+				else if (Entities::isFemale((EntityIndex)params->param2))
+					getSound()->playSound(kEntityMertens, "CON3051");
+				else if (params->param2 == kEntityPlayer)
+					getSound()->playSound(kEntityMertens, getProgress().field_40 ? "CON3054" : "CON3053");
+				else {
+					setCallback(1);
+					setup_bonsoir((EntityIndex)params->param2);
+					break;
+				}
+			} else {
+				setCallback(2);
+				setup_bonsoir((EntityIndex)params->param2);
+				break;
+			}
 		}
 
 		setCallback(3);
@@ -583,7 +604,7 @@ IMPLEMENT_FUNCTION_II(13, Mertens, function13, bool, bool)
 	case kAction16:
 		params->param3--;
 
-		if (params->param2 && !params->param3) {
+		if (params->param2 != kEntityPlayer && !params->param3) {
 			getData()->inventoryItem = kItemNone;
 			setCallback(10);
 			setup_function18();
@@ -594,6 +615,12 @@ IMPLEMENT_FUNCTION_II(13, Mertens, function13, bool, bool)
 		if (getEntities()->isPlayerPosition(kCarGreenSleeping, 23) && ENTITY_PARAM(0, 7) && !getEvent(kEventKronosConversation)) {
 			setCallback(8);
 			setup_savegame(kSavegameTypeEvent, kEventMertensKronosInvitation);
+			break;
+		}
+		if (!params->param3) {
+			getData()->inventoryItem = kItemNone;
+			setCallback(9);
+			setup_function18();
 		}
 		break;
 
@@ -631,13 +658,14 @@ IMPLEMENT_FUNCTION_II(13, Mertens, function13, bool, bool)
 
 		case 8:
 			getAction()->playAnimation(kEventMertensKronosInvitation);
+			getProgress().eventMertensKronosInvitation = true;
 			ENTITY_PARAM(0, 6) = 0;
 			ENTITY_PARAM(0, 7) = 0;
 			getScenes()->processScene();
 
 			if (!params->param3) {
 				getData()->inventoryItem = kItemNone;
-				setCallback(10);
+				setCallback(9);
 				setup_function18();
 			}
 			break;
@@ -653,7 +681,7 @@ IMPLEMENT_FUNCTION_I(14, Mertens, function14, EntityIndex)
 		break;
 
 	case kActionNone:
-		Entity::savegameBloodJacket();
+		Entity::savegameBloodJacket(4);
 		break;
 
 	case kActionDefault:
@@ -1167,7 +1195,7 @@ IMPLEMENT_FUNCTION(22, Mertens, function22)
 
 		case 4:
 			getEntities()->drawSequenceLeft(kEntityMertens, "601Nh");
-			getEntities()->enterCompartment(kEntityMertens, kObjectCompartment8);
+			getEntities()->enterCompartment(kEntityMertens, kObjectCompartment8, true);
 			getSavePoints()->push(kEntityMertens, kEntityMahmud, kAction225563840);
 			break;
 
@@ -1257,7 +1285,7 @@ IMPLEMENT_FUNCTION(23, Mertens, function23)
 			break;
 
 		case 4:
-			getEntities()->exitCompartment(kEntityMertens, kObjectCompartment4);
+			getEntities()->exitCompartment(kEntityMertens, kObjectCompartment4, true);
 			getData()->location = kLocationInsideCompartment;
 			getEntities()->clearSequences(kEntityMertens);
 
@@ -1669,7 +1697,7 @@ label_callback11:
 						break;
 					}
 				} else {
-					setCallback(26);
+					setCallback(19);
 					setup_function26(false);
 				}
 
@@ -1742,7 +1770,7 @@ label_callback11:
 
 	case kActionKnock:
 		if (params->param1) {
-			getObjects()->update(kObjectCompartment1, kEntityMertens, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorNormal);
+			getObjects()->update(kObjectCompartment1, kEntityPlayer, getObjects()->get(kObjectCompartment1).status, kCursorNormal, kCursorNormal);
 
 			switch (params->param1) {
 			default:
@@ -1774,7 +1802,7 @@ label_callback11:
 		break;
 
 	case kActionOpenDoor:
-		getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).status == kObjectLocation1 ? "LIB012" : "LIB014");
+		getSound()->playSound(kEntityPlayer, getObjects()->get(kObjectCompartment1).status == kObjectLocation1 ? "LIB032" : "LIB014");
 
 		if (getProgress().eventCorpseMovedFromFloor) {
 
@@ -1855,7 +1883,7 @@ label_callback11:
 			} else {
 				if (getEntities()->isInsideTrainCar(kEntityPlayer, kCarGreenSleeping)) {
 					setCallback(2);
-					setup_enterExitCompartment("601Ra", kObjectCompartment1);
+					setup_enterExitCompartment2("601Ra", kObjectCompartment1);
 				} else {
 					getScenes()->loadSceneFromPosition(kCarNone, 1);
 
@@ -2222,7 +2250,7 @@ IMPLEMENT_FUNCTION_I(30, Mertens, function30, MertensActionType)
 			if (params->param3)
 				getObjects()->update(kObjectCompartment2, kEntityPlayer, getObjects()->get(kObjectCompartment2).status, kCursorHandKnock, kCursorHand);
 
-			getEntities()->exitCompartment(kEntityMertens, kObjectCompartment2);
+			getEntities()->exitCompartment(kEntityMertens, kObjectCompartment2, true);
 
 			if (getProgress().field_14 == 3)
 					getProgress().field_14 = 0;
@@ -2243,7 +2271,7 @@ IMPLEMENT_FUNCTION_I(30, Mertens, function30, MertensActionType)
 			if (params->param3)
 				getObjects()->update(kObjectCompartment3, kEntityPlayer, getObjects()->get(kObjectCompartment3).status, kCursorHandKnock, kCursorHand);
 
-			getEntities()->exitCompartment(kEntityMertens, kObjectCompartment3);
+			getEntities()->exitCompartment(kEntityMertens, kObjectCompartment3, true);
 
 			if (getProgress().field_14 == 3)
 					getProgress().field_14 = 0;
@@ -2465,6 +2493,7 @@ IMPLEMENT_FUNCTION(33, Mertens, function33)
 				break;
 			}
 
+			ENTITY_PARAM(1, 8) = 0;
 			callbackAction();
 			break;
 
@@ -2478,12 +2507,14 @@ IMPLEMENT_FUNCTION(33, Mertens, function33)
 				break;
 			}
 
+			ENTITY_PARAM(1, 8) = 0;
 			callbackAction();
 			break;
 
 		case 13:
 			ENTITY_PARAM(2, 2) = 0;
 
+			ENTITY_PARAM(1, 8) = 0;
 			callbackAction();
 			break;
 		}
@@ -2631,14 +2662,12 @@ IMPLEMENT_FUNCTION(36, Mertens, function36)
 			break;
 
 		case 2:
-			if (ENTITY_PARAM(0, 6)) {
-				if (getEntities()->isPlayerInCar(kCarGreenSleeping) && getData()->entityPosition < getEntityData(kEntityPlayer)->entityPosition) {
-					setCallback(3);
-					setup_updateEntity(kCarGreenSleeping, kPosition_9460);
-				} else {
-					setCallback(7);
-					setup_tylerCompartment(kMertensAction2);
-				}
+			if (ENTITY_PARAM(0, 6) && getEntities()->isPlayerInCar(kCarGreenSleeping) && getData()->entityPosition < getEntityData(kEntityPlayer)->entityPosition) {
+				setCallback(3);
+				setup_updateEntity(kCarGreenSleeping, kPosition_9460);
+			} else if (!getProgress().eventMertensKronosInvitation) {
+				setCallback(7);
+				setup_tylerCompartment(kMertensAction2);
 			} else {
 				ENTITY_PARAM(0, 6) = 0;
 				ENTITY_PARAM(0, 7) = 0;
@@ -2657,7 +2686,7 @@ IMPLEMENT_FUNCTION(36, Mertens, function36)
 			break;
 
 		case 4:
-			if (ENTITY_PARAM(0, 6)) {
+			if (!getProgress().eventMertensKronosInvitation) {
 				setCallback(7);
 				setup_tylerCompartment(kMertensAction2);
 			} else {
@@ -2720,9 +2749,9 @@ IMPLEMENT_FUNCTION(37, Mertens, function37)
 		break;
 
 	case kActionEndSound:
-		++params->param6;
+		++params->param1;
 
-		if (params->param6 == 1)
+		if (params->param1 == 1)
 			getSound()->playSound(kEntityMertens, getEntities()->isDistanceBetweenEntities(kEntityMertens, kEntityPlayer, 2000) ? "CON1152" : "CON1151");
 		break;
 
@@ -2737,7 +2766,7 @@ IMPLEMENT_FUNCTION(37, Mertens, function37)
 			break;
 
 		case 1:
-			setCallback(1);
+			setCallback(2);
 			setup_updateEntity(kCarRedSleeping, kPosition_1500);
 			break;
 
@@ -3039,10 +3068,10 @@ label_callback_8:
 			break;
 		}
 
+label_callback_9:
 		if (getProgress().field_14 == 29)
 			goto label_callback_13;
 
-label_callback_9:
 		if (ENTITY_PARAM(1, 6)) {
 			getData()->inventoryItem = kItemNone;
 			setCallback(10);
@@ -3141,7 +3170,7 @@ label_callback_19:
 		if (!ENTITY_PARAM(0, 1) && !ENTITY_PARAM(2, 1)) {
 			getData()->inventoryItem = kItemNone;
 			setCallback(20);
-			setup_function13((bool)savepoint.param.intValue, (bool)savepoint.entity2);
+			setup_function13((bool)savepoint.param.intValue, savepoint.entity2);
 		}
 		break;
 
@@ -3172,13 +3201,13 @@ label_callback_2_4:
 		if ((getEntities()->isPlayerPosition(kCarGreenSleeping, 1) || getEntities()->isPlayerPosition(kCarGreenSleeping, 23)) && !ENTITY_PARAM(0, 1) && !ENTITY_PARAM(2, 1)) {
 			getData()->inventoryItem = kItemNone;
 			setCallback(getEntities()->isPlayerPosition(kCarGreenSleeping, 1) ? 5 : 6);
-			setup_function13(getEntities()->isPlayerPosition(kCarGreenSleeping, 1), false);
+			setup_function13(getEntities()->isPlayerPosition(kCarGreenSleeping, 1), kEntityPlayer);
 			break;
 		}
 
 label_callback_5_6:
 		if (getEntities()->isPlayerInCar(kCarGreenSleeping) && getData()->entityPosition < getEntityData(kEntityPlayer)->entityPosition) {
-			if (getProgress().jacket == kJacketOriginal || ENTITY_PARAM(0, 7)) {
+			if (getProgress().jacket == kJacketBlood || ENTITY_PARAM(0, 7)) {
 				getData()->inventoryItem = kItemNone;
 				setCallback(7);
 				setup_function32();
@@ -3325,13 +3354,13 @@ IMPLEMENT_FUNCTION(43, Mertens, chapter2)
 		ENTITY_PARAM(0, 6) = 0;
 		ENTITY_PARAM(0, 8) = 0;
 
-		ENTITY_PARAM(0, 1) = 0;
-		ENTITY_PARAM(0, 2) = 0;
-		ENTITY_PARAM(0, 3) = 0;
-		ENTITY_PARAM(0, 4) = 0;
-		ENTITY_PARAM(0, 5) = 0;
-		ENTITY_PARAM(0, 6) = 0;
-		ENTITY_PARAM(0, 7) = 0;
+		ENTITY_PARAM(1, 1) = 0;
+		ENTITY_PARAM(1, 2) = 0;
+		ENTITY_PARAM(1, 3) = 0;
+		ENTITY_PARAM(1, 4) = 0;
+		ENTITY_PARAM(1, 5) = 0;
+		ENTITY_PARAM(1, 6) = 0;
+		ENTITY_PARAM(1, 7) = 0;
 		break;
 
 	case kActionCallback:
@@ -3380,7 +3409,7 @@ label_callback3:
 	case kAction11:
 		if (!ENTITY_PARAM(2, 1)) {
 			setCallback(5);
-			setup_function13((bool)savepoint.param.intValue, (bool)savepoint.entity2);
+			setup_function13((bool)savepoint.param.intValue, savepoint.entity2);
 		}
 		break;
 
@@ -3390,11 +3419,11 @@ label_callback3:
 
 		if (getEntities()->isPlayerPosition(kCarGreenSleeping, 1)) {
 			setCallback(6);
-			setup_function13(true, false);
+			setup_function13(true, kEntityPlayer);
 
 		} else if (getEntities()->isPlayerPosition(kCarGreenSleeping, 23)) {
 			setCallback(7);
-			setup_function13(false, false);
+			setup_function13(false, kEntityPlayer);
 		}
 		break;
 
@@ -3470,7 +3499,7 @@ IMPLEMENT_FUNCTION(45, Mertens, chapter3)
 		ENTITY_PARAM(1, 6) = 0;
 		ENTITY_PARAM(1, 7) = 0;
 
-		ENTITY_PARAM(2, 3) = 0;
+		ENTITY_PARAM(2, 4) = 0;
 		break;
 
 	case kActionCallback:
@@ -3554,7 +3583,7 @@ label_callback_10:
 	case kAction11:
 		if (!ENTITY_PARAM(2, 1)) {
 			setCallback(12);
-			setup_function13((bool)savepoint.param.intValue, savepoint.entity2 != kEntityPlayer);
+			setup_function13((bool)savepoint.param.intValue, savepoint.entity2);
 		}
 		break;
 
@@ -3565,10 +3594,10 @@ label_callback_10:
 		if (!ENTITY_PARAM(2, 1)) {
 			if (getEntities()->isPlayerPosition(kCarGreenSleeping, 1)) {
 				setCallback(13);
-				setup_function13(true, false);
+				setup_function13(true, kEntityPlayer);
 			} else if (getEntities()->isPlayerPosition(kCarGreenSleeping, 23)) {
 				setCallback(14);
-				setup_function13(false, false);
+				setup_function13(false, kEntityPlayer);
 			}
 		}
 		break;
@@ -3668,7 +3697,7 @@ IMPLEMENT_FUNCTION(47, Mertens, chapter4)
 		ENTITY_PARAM(1, 6) = 0;
 		ENTITY_PARAM(1, 7) = 0;
 
-		ENTITY_PARAM(2, 4) = 0;
+		ENTITY_PARAM(2, 3) = 0;
 		break;
 
 	case kActionCallback:
@@ -3762,7 +3791,7 @@ label_callback_8:
 	case kAction11:
 		if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1)) {
 			setCallback(9);
-			setup_function13((bool)savepoint.param.intValue, savepoint.entity2 != kEntityPlayer);
+			setup_function13((bool)savepoint.param.intValue, savepoint.entity2);
 		}
 		break;
 
@@ -3778,10 +3807,10 @@ label_callback_8:
 		if (!ENTITY_PARAM(2, 1) && !ENTITY_PARAM(0, 1)) {
 			if (getEntities()->isPlayerPosition(kCarGreenSleeping, 1)) {
 				setCallback(10);
-				setup_function13(true, false);
+				setup_function13(true, kEntityPlayer);
 			} else if (getEntities()->isPlayerPosition(kCarGreenSleeping, 23)) {
 				setCallback(11);
-				setup_function13(false, false);
+				setup_function13(false, kEntityPlayer);
 			}
 		}
 		break;
@@ -4008,7 +4037,7 @@ IMPLEMENT_FUNCTION(53, Mertens, function53)
 				break;
 
 			params->param1 = 0;
-			params->param2 = 0;
+			params->param2 = 1;
 
 			getObjects()->update(kObjectCompartment4, kEntityMertens, kObjectLocation1, kCursorNormal, kCursorNormal);
 		}
diff --git a/engines/lastexpress/entities/mertens.h b/engines/lastexpress/entities/mertens.h
index 1b6d1d2..55c2ddd 100644
--- a/engines/lastexpress/entities/mertens.h
+++ b/engines/lastexpress/entities/mertens.h
@@ -126,7 +126,7 @@ public:
 	* @param entity The entity
 	*/
 	DECLARE_FUNCTION_1(bonsoir, EntityIndex entity)
-	DECLARE_FUNCTION_2(function13, bool, bool)
+	DECLARE_FUNCTION_2(function13, bool, EntityIndex entity)
 	DECLARE_FUNCTION_1(function14, EntityIndex entity)
 	DECLARE_FUNCTION_1(function15, bool)
 	DECLARE_FUNCTION_1(function16, bool)
diff --git a/engines/lastexpress/entities/milos.cpp b/engines/lastexpress/entities/milos.cpp
index 65cad07..8177f99 100644
--- a/engines/lastexpress/entities/milos.cpp
+++ b/engines/lastexpress/entities/milos.cpp
@@ -43,16 +43,16 @@ namespace LastExpress {
 
 Milos::Milos(LastExpressEngine *engine) : Entity(engine, kEntityMilos) {
 	ADD_CALLBACK_FUNCTION(Milos, reset);
-	ADD_CALLBACK_FUNCTION(Milos, draw);
-	ADD_CALLBACK_FUNCTION(Milos, enterExitCompartment);
-	ADD_CALLBACK_FUNCTION(Milos, enterExitCompartment2);
+	ADD_CALLBACK_FUNCTION_S(Milos, draw);
+	ADD_CALLBACK_FUNCTION_SI(Milos, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_SI(Milos, enterExitCompartment2);
 	ADD_CALLBACK_FUNCTION(Milos, callbackActionOnDirection);
-	ADD_CALLBACK_FUNCTION(Milos, playSound);
-	ADD_CALLBACK_FUNCTION(Milos, playSound16);
-	ADD_CALLBACK_FUNCTION(Milos, savegame);
-	ADD_CALLBACK_FUNCTION(Milos, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Milos, enterCompartmentDialog);
-	ADD_CALLBACK_FUNCTION(Milos, function11);
+	ADD_CALLBACK_FUNCTION_S(Milos, playSound);
+	ADD_CALLBACK_FUNCTION_S(Milos, playSound16);
+	ADD_CALLBACK_FUNCTION_II(Milos, savegame);
+	ADD_CALLBACK_FUNCTION_I(Milos, updateFromTime);
+	ADD_CALLBACK_FUNCTION_II(Milos, enterCompartmentDialog);
+	ADD_CALLBACK_FUNCTION_I(Milos, function11);
 	ADD_CALLBACK_FUNCTION(Milos, chapter1);
 	ADD_CALLBACK_FUNCTION(Milos, function13);
 	ADD_CALLBACK_FUNCTION(Milos, function14);
@@ -67,8 +67,8 @@ Milos::Milos(LastExpressEngine *engine) : Entity(engine, kEntityMilos) {
 	ADD_CALLBACK_FUNCTION(Milos, function23);
 	ADD_CALLBACK_FUNCTION(Milos, function24);
 	ADD_CALLBACK_FUNCTION(Milos, function25);
-	ADD_CALLBACK_FUNCTION(Milos, function26);
-	ADD_CALLBACK_FUNCTION(Milos, function27);
+	ADD_CALLBACK_FUNCTION_I(Milos, function26);
+	ADD_CALLBACK_FUNCTION_II(Milos, function27);
 	ADD_CALLBACK_FUNCTION(Milos, chapter4);
 	ADD_CALLBACK_FUNCTION(Milos, chapter4Handler);
 	ADD_CALLBACK_FUNCTION(Milos, function30);
@@ -180,11 +180,12 @@ IMPLEMENT_FUNCTION_I(11, Milos, function11, TimeValue)
 				params->param2 = 0;
 				params->param3 = 1;
 				getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation1, kCursorNormal, kCursorNormal);
+				params->param8 = 0;
 			}
+		} else {
+			params->param8 = 0;
 		}
 
-		params->param8 = 0;
-
 		if (getProgress().chapter != kChapter1 || params->param5)
 			break;
 
@@ -344,7 +345,7 @@ IMPLEMENT_FUNCTION_I(11, Milos, function11, TimeValue)
 		break;
 
 	case kAction123852928:
-		params->param1 = 13;
+		setCallback(13);
 		setup_enterExitCompartment("611Dg", kObjectCompartmentG);
 		break;
 
@@ -737,6 +738,7 @@ IMPLEMENT_FUNCTION(15, Milos, chapter1Handler)
 			}
 		}
 
+label_callback_1:
 		if (getEntities()->isPlayerPosition(kCarRestaurant, 70) && !params->param2) {
 			if (!Entity::updateParameter(params->param5, getState()->timeTicks, 45))
 				break;
@@ -759,7 +761,7 @@ IMPLEMENT_FUNCTION(15, Milos, chapter1Handler)
 		case 1:
 			getEntities()->drawSequenceLeft(kEntityMilos, "009A");
 			params->param1 = 1;
-			break;
+			goto label_callback_1;
 
 		case 2:
 			getEntities()->drawSequenceLeft(kEntityMilos, "009A");
@@ -891,9 +893,11 @@ IMPLEMENT_FUNCTION(19, Milos, chapter2)
 	case kActionDefault:
 		getEntities()->clearSequences(kEntityMilos);
 
-		getData()->entityPosition = kPosition_4689;
-		getData()->location = kLocationInsideCompartment;
-		getData()->car = kCarRestaurant;
+		getData()->entityPosition = kPosition_540;
+		getData()->location = kLocationOutsideCompartment;
+		getData()->car = kCarRedSleeping;
+		getData()->inventoryItem = kItemNone;
+		getData()->clothes = kClothesDefault;
 
 		getObjects()->update(kObjectCompartmentG, kEntityPlayer, kObjectLocation3, kCursorHandKnock, kCursorHand);
 		getObjects()->update(kObject46, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
@@ -969,6 +973,7 @@ IMPLEMENT_FUNCTION(21, Milos, function21)
 
 	case kActionOpenDoor:
 		getObjects()->update(kObjectCompartmentG, kEntityMilos, kObjectLocation3, kCursorNormal, kCursorNormal);
+		getEntityData(kEntityPlayer)->location = kLocationInsideCompartment;
 
 		setCallback(3);
 		setup_savegame(kSavegameTypeEvent, kEventMilosCompartmentVisitAugust);
@@ -1156,7 +1161,7 @@ IMPLEMENT_FUNCTION(24, Milos, function24)
 			setCallback(12);
 			setup_playSound("LIB013");
 		} else {
-			getData()->location = kLocationInsideCompartment;
+			getEntityData(kEntityPlayer)->location = kLocationInsideCompartment;
 
 			setCallback(11);
 			setup_savegame(kSavegameTypeEvent, kEventMilosCompartmentVisitAugust);
@@ -1354,7 +1359,7 @@ IMPLEMENT_FUNCTION(25, Milos, function25)
 
 			RESET_ENTITY_STATE(kEntityVesna, Vesna, setup_inCompartment);
 
-			getData()->location = kLocationInsideCompartment;
+			getEntityData(kEntityPlayer)->location = kLocationInsideCompartment;
 
 			setCallback(4);
 			setup_savegame(kSavegameTypeEvent, kEventMilosCompartmentVisitTyler);
@@ -1390,6 +1395,7 @@ IMPLEMENT_FUNCTION_I(26, Milos, function26, TimeValue)
 
 	case kActionNone:
 		if (params->param1 < getState()->time && !params->param2) {
+			params->param2 = 1;
 			callbackAction();
 			break;
 		}
@@ -1556,7 +1562,7 @@ IMPLEMENT_FUNCTION(29, Milos, chapter4Handler)
 			break;
 
 		case 2:
-			getEntities()->exitCompartment(kEntityMilos, kObjectCompartmentG);
+			getEntities()->exitCompartment(kEntityMilos, kObjectCompartmentG, true);
 
 			getData()->location = kLocationInsideCompartment;
 			getData()->entityPosition = kPosition_3050;
@@ -1600,7 +1606,7 @@ IMPLEMENT_FUNCTION(30, Milos, function30)
 	default:
 		break;
 
-	case kActionNone:
+	case kActionDefault:
 		setCallback(1);
 		setup_function11(kTime2410200);
 		break;
@@ -1638,7 +1644,7 @@ IMPLEMENT_FUNCTION(31, Milos, function31)
 	default:
 		break;
 
-	case kActionNone:
+	case kActionDefault:
 		setCallback(1);
 		setup_enterExitCompartment("609CG", kObjectCompartmentG);
 		break;
@@ -1721,7 +1727,7 @@ IMPLEMENT_FUNCTION(34, Milos, chapter5Handler)
 			break;
 
 		case 1:
-			getAction()->playAnimation(isNight() ? kEventLocomotiveMilosShovelingNight : kEventLocomotiveMilosShovelingDay);
+			getAction()->playAnimation(getProgress().isNightTime ? kEventLocomotiveMilosShovelingDay : kEventLocomotiveMilosShovelingNight);
 			getScenes()->processScene();
 			break;
 
@@ -1733,7 +1739,7 @@ IMPLEMENT_FUNCTION(34, Milos, chapter5Handler)
 				getSoundQueue()->removeFromQueue("ARRIVE");
 
 			getSoundQueue()->processEntries();
-			getAction()->playAnimation(isNight() ? kEventLocomotiveMilosNight : kEventLocomotiveMilosDay);
+			getAction()->playAnimation(getProgress().isNightTime ? kEventLocomotiveMilosDay : kEventLocomotiveMilosNight);
 			getSoundQueue()->setupEntry(kSoundType7, kEntityMilos);
 			getScenes()->loadSceneFromPosition(kCarCoalTender, 1);
 			break;
@@ -1787,11 +1793,12 @@ IMPLEMENT_FUNCTION(34, Milos, chapter5Handler)
 		if (!getProgress().isNightTime) {
 			setCallback(3);
 			setup_savegame(kSavegameTypeEvent, kEventLocomotiveAnnaStopsTrain);
+			break;
 		}
 
 		getSoundQueue()->processEntry(kEntityMilos);
-		if (getState()->time < kTimeTrainStopped2)
-			getState()->time = kTimeTrainStopped2;
+		if (getState()->time < kTime2949300)
+			getState()->time = kTime2949300;
 
 		setCallback(4);
 		setup_savegame(kSavegameTypeEvent, kEventLocomotiveRestartTrain);
diff --git a/engines/lastexpress/entities/mmeboutarel.cpp b/engines/lastexpress/entities/mmeboutarel.cpp
index f00fb7a..994a0ce 100644
--- a/engines/lastexpress/entities/mmeboutarel.cpp
+++ b/engines/lastexpress/entities/mmeboutarel.cpp
@@ -38,13 +38,13 @@ namespace LastExpress {
 
 MmeBoutarel::MmeBoutarel(LastExpressEngine *engine) : Entity(engine, kEntityMmeBoutarel) {
 	ADD_CALLBACK_FUNCTION(MmeBoutarel, reset);
-	ADD_CALLBACK_FUNCTION(MmeBoutarel, playSound);
-	ADD_CALLBACK_FUNCTION(MmeBoutarel, draw);
-	ADD_CALLBACK_FUNCTION(MmeBoutarel, updateFromTime);
-	ADD_CALLBACK_FUNCTION(MmeBoutarel, enterExitCompartment);
-	ADD_CALLBACK_FUNCTION(MmeBoutarel, enterExitCompartment2);
-	ADD_CALLBACK_FUNCTION(MmeBoutarel, updateEntity);
-	ADD_CALLBACK_FUNCTION(MmeBoutarel, function8);
+	ADD_CALLBACK_FUNCTION_S(MmeBoutarel, playSound);
+	ADD_CALLBACK_FUNCTION_S(MmeBoutarel, draw);
+	ADD_CALLBACK_FUNCTION_I(MmeBoutarel, updateFromTime);
+	ADD_CALLBACK_FUNCTION_SI(MmeBoutarel, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_SI(MmeBoutarel, enterExitCompartment2);
+	ADD_CALLBACK_FUNCTION_II(MmeBoutarel, updateEntity);
+	ADD_CALLBACK_FUNCTION_S(MmeBoutarel, function8);
 	ADD_CALLBACK_FUNCTION(MmeBoutarel, function9);
 	ADD_CALLBACK_FUNCTION(MmeBoutarel, chapter1);
 	ADD_CALLBACK_FUNCTION(MmeBoutarel, function11);
@@ -163,6 +163,7 @@ IMPLEMENT_FUNCTION(9, MmeBoutarel, function9)
 		if (!params->param1) {
 			getData()->entityPosition = getEntityData(kEntityBoutarel)->entityPosition;
 			getData()->location = getEntityData(kEntityBoutarel)->location;
+			getData()->car = getEntityData(kEntityBoutarel)->car;
 		}
 		break;
 
@@ -912,6 +913,7 @@ IMPLEMENT_FUNCTION(21, MmeBoutarel, chapter3Handler)
 		getObjects()->update(kObject51, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
 		getObjects()->update(kObject43, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
 		getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "501");
+		getSavePoints()->push(kEntityMmeBoutarel, kEntityFrancois, kAction189872836);
 		break;
 
 	case kActionCallback:
@@ -968,6 +970,7 @@ IMPLEMENT_FUNCTION(21, MmeBoutarel, chapter3Handler)
 		case 9:
 			getEntities()->drawSequenceLeft(kEntityMmeBoutarel, "501");
 			params->param1 = 1;
+			getSavePoints()->push(kEntityMmeBoutarel, kEntityFrancois, kAction190390860);
 			break;
 		}
 		break;
diff --git a/engines/lastexpress/entities/pascale.cpp b/engines/lastexpress/entities/pascale.cpp
index 24b7f04..f5fa1aa 100644
--- a/engines/lastexpress/entities/pascale.cpp
+++ b/engines/lastexpress/entities/pascale.cpp
@@ -36,13 +36,13 @@
 namespace LastExpress {
 
 Pascale::Pascale(LastExpressEngine *engine) : Entity(engine, kEntityPascale) {
-	ADD_CALLBACK_FUNCTION(Pascale, draw);
+	ADD_CALLBACK_FUNCTION_S(Pascale, draw);
 	ADD_CALLBACK_FUNCTION(Pascale, callbackActionRestaurantOrSalon);
 	ADD_CALLBACK_FUNCTION(Pascale, callbackActionOnDirection);
-	ADD_CALLBACK_FUNCTION(Pascale, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Pascale, updatePosition);
-	ADD_CALLBACK_FUNCTION(Pascale, playSound);
-	ADD_CALLBACK_FUNCTION(Pascale, draw2);
+	ADD_CALLBACK_FUNCTION_I(Pascale, updateFromTime);
+	ADD_CALLBACK_FUNCTION_SII(Pascale, updatePosition);
+	ADD_CALLBACK_FUNCTION_S(Pascale, playSound);
+	ADD_CALLBACK_FUNCTION_SSI(Pascale, draw2);
 	ADD_CALLBACK_FUNCTION(Pascale, welcomeSophieAndRebecca);
 	ADD_CALLBACK_FUNCTION(Pascale, sitSophieAndRebecca);
 	ADD_CALLBACK_FUNCTION(Pascale, welcomeCath);
@@ -188,9 +188,9 @@ IMPLEMENT_FUNCTION(9, Pascale, sitSophieAndRebecca)
 		break;
 
 	case kActionDefault:
-		getEntities()->drawSequenceLeft(kEntityPascale, "012C1");
-		getEntities()->drawSequenceLeft(kEntityRebecca, "012C2");
-		getEntities()->drawSequenceLeft(kEntityTables3, "012C3");
+		getEntities()->drawSequenceRight(kEntityPascale, "012C1");
+		getEntities()->drawSequenceRight(kEntityRebecca, "012C2");
+		getEntities()->drawSequenceRight(kEntityTables3, "012C3");
 		break;
 	}
 IMPLEMENT_FUNCTION_END
@@ -353,7 +353,7 @@ IMPLEMENT_FUNCTION(13, Pascale, greetAugust)
 			break;
 
 		case 2:
-			getEntities()->drawSequenceLeft(kEntityPascale, "010B");
+			getEntities()->drawSequenceLeft(kEntityAugust, "010B");
 
 			setCallback(3);
 			setup_draw("905");
@@ -739,7 +739,7 @@ IMPLEMENT_FUNCTION(24, Pascale, welcomeAbbot)
 	default:
 		break;
 
-	case kActionNone:
+	case kActionEndSound:
 		if (!params->param1) {
 			getSound()->playSound(kEntityPascale, "ABB3015A");
 			params->param1 = 1;
@@ -1132,7 +1132,7 @@ label_callback1:
 				break;
 
 			params->param1 = 0;
-			params->param2 = 2;
+			params->param2 = 1;
 
 			getObjects()->update(kObjectCompartmentG, kEntityPascale, kObjectLocation1, kCursorNormal, kCursorNormal);
 		}
@@ -1192,7 +1192,7 @@ label_callback1:
 			if (params->param3 == 1 || params->param3 == 2) {
 				getObjects()->update(kObjectCompartmentG, kEntityPascale, kObjectLocation1, kCursorNormal, kCursorNormal);
 				setCallback(params->param3 == 1 ? 5 : 6);
-				setup_playSound(params->param3 == 1 ? "Wat5001" : "Wat5002");
+				setup_playSound(params->param3 == 1 ? "Wat5001" : "Wat5001A");
 			}
 			break;
 
diff --git a/engines/lastexpress/entities/rebecca.cpp b/engines/lastexpress/entities/rebecca.cpp
index b8b4aa1..acb58f7 100644
--- a/engines/lastexpress/entities/rebecca.cpp
+++ b/engines/lastexpress/entities/rebecca.cpp
@@ -23,6 +23,7 @@
 #include "lastexpress/entities/rebecca.h"
 
 #include "lastexpress/game/entities.h"
+#include "lastexpress/game/inventory.h"
 #include "lastexpress/game/logic.h"
 #include "lastexpress/game/object.h"
 #include "lastexpress/game/savepoint.h"
@@ -37,25 +38,25 @@ namespace LastExpress {
 
 Rebecca::Rebecca(LastExpressEngine *engine) : Entity(engine, kEntityRebecca) {
 	ADD_CALLBACK_FUNCTION(Rebecca, reset);
-	ADD_CALLBACK_FUNCTION(Rebecca, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Rebecca, playSound);
-	ADD_CALLBACK_FUNCTION(Rebecca, playSound16);
-	ADD_CALLBACK_FUNCTION(Rebecca, callSavepoint);
-	ADD_CALLBACK_FUNCTION(Rebecca, draw);
-	ADD_CALLBACK_FUNCTION(Rebecca, enterExitCompartment);
-	ADD_CALLBACK_FUNCTION(Rebecca, enterExitCompartment2);
-	ADD_CALLBACK_FUNCTION(Rebecca, enterExitCompartment3);
+	ADD_CALLBACK_FUNCTION_I(Rebecca, updateFromTime);
+	ADD_CALLBACK_FUNCTION_S(Rebecca, playSound);
+	ADD_CALLBACK_FUNCTION_S(Rebecca, playSound16);
+	ADD_CALLBACK_FUNCTION_SIIS(Rebecca, callSavepoint);
+	ADD_CALLBACK_FUNCTION_S(Rebecca, draw);
+	ADD_CALLBACK_FUNCTION_SI(Rebecca, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_SI(Rebecca, enterExitCompartment2);
+	ADD_CALLBACK_FUNCTION_SI(Rebecca, enterExitCompartment3);
 	ADD_CALLBACK_FUNCTION(Rebecca, callbackActionOnDirection);
 	ADD_CALLBACK_FUNCTION(Rebecca, callbackActionRestaurantOrSalon);
-	ADD_CALLBACK_FUNCTION(Rebecca, updateEntity);
-	ADD_CALLBACK_FUNCTION(Rebecca, updatePosition);
-	ADD_CALLBACK_FUNCTION(Rebecca, draw2);
+	ADD_CALLBACK_FUNCTION_II(Rebecca, updateEntity);
+	ADD_CALLBACK_FUNCTION_SII(Rebecca, updatePosition);
+	ADD_CALLBACK_FUNCTION_SSI(Rebecca, draw2);
 	ADD_CALLBACK_FUNCTION(Rebecca, function15);
-	ADD_CALLBACK_FUNCTION(Rebecca, function16);
-	ADD_CALLBACK_FUNCTION(Rebecca, function17);
+	ADD_CALLBACK_FUNCTION_I(Rebecca, function16);
+	ADD_CALLBACK_FUNCTION_I(Rebecca, function17);
 	ADD_CALLBACK_FUNCTION(Rebecca, function18);
 	ADD_CALLBACK_FUNCTION(Rebecca, function19);
-	ADD_CALLBACK_FUNCTION(Rebecca, function20);
+	ADD_CALLBACK_FUNCTION_I(Rebecca, function20);
 	ADD_CALLBACK_FUNCTION(Rebecca, chapter1);
 	ADD_CALLBACK_FUNCTION(Rebecca, chapter1Handler);
 	ADD_CALLBACK_FUNCTION(Rebecca, function23);
@@ -129,6 +130,11 @@ IMPLEMENT_FUNCTION_END
 
 //////////////////////////////////////////////////////////////////////////
 IMPLEMENT_FUNCTION_SI(9, Rebecca, enterExitCompartment3, ObjectIndex)
+	if (savepoint.action == kAction4) {
+		getEntities()->exitCompartment(_entityIndex, (ObjectIndex)params->param4);
+		callbackAction();
+		return;
+	}
 	Entity::enterExitCompartment(savepoint);
 IMPLEMENT_FUNCTION_END
 
@@ -239,7 +245,7 @@ IMPLEMENT_FUNCTION_I(16, Rebecca, function16, bool)
 			if (getEntities()->isInSalon(kEntityPlayer))
 				getEntities()->updateFrame(kEntityRebecca);
 
-			setCallback(4);
+			setCallback(5);
 			setup_callbackActionOnDirection();
 			break;
 
@@ -442,7 +448,7 @@ IMPLEMENT_FUNCTION(19, Rebecca, function19)
 			if (getEntities()->isInRestaurant(kEntityPlayer))
 				getEntities()->updateFrame(kEntityRebecca);
 
-			setCallback(4);
+			setCallback(3);
 			setup_callbackActionOnDirection();
 			break;
 
@@ -563,6 +569,30 @@ label_callback:
 
 	case kActionKnock:
 	case kActionOpenDoor:
+		if (params->param2) {
+			getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+			getObjects()->update(kObject52, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+			if (savepoint.param.intValue == kObject52) {
+				setCallback(8);
+				setup_playSound(getSound()->justAMinuteCath());
+			} else if (getInventory()->hasItem(kItemPassengerList)) {
+				if (rnd(2)) {
+					setCallback(9);
+					setup_playSound(getSound()->wrongDoorCath());
+				} else {
+					setCallback(10);
+					setup_playSound(params->param4 ? "CAT1509" : (rnd(2) ? "CAT1508" : "CAT1508A"));
+				}
+			} else {
+				setCallback(11);
+				setup_playSound(getSound()->wrongDoorCath());
+			}
+		} else {
+			getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+			getObjects()->update(kObject52, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
+			setCallback(savepoint.action == kActionKnock ? 4 : 5);
+			setup_playSound(savepoint.action == kActionKnock ? "LIB012" : "LIB013");
+		}
 		break;
 
 	case kActionDefault:
@@ -955,7 +985,7 @@ IMPLEMENT_FUNCTION(25, Rebecca, function25)
 
 		case 1:
 			setCallback(2);
-			setup_function17(false);
+			setup_function17(true);
 			break;
 
 		case 2:
@@ -1109,7 +1139,7 @@ IMPLEMENT_FUNCTION(30, Rebecca, function30)
 			}
 		}
 
-		if (!params->param3 && !params->param2 && params->param5 != kTimeInvalid) {
+		if (params->param3 && !params->param2 && params->param5 != kTimeInvalid) {
 
 			if (getState()->time <= kTime10881000) {
 				if (!getEntities()->isInSalon(kEntityPlayer) || !params->param5)
@@ -1231,13 +1261,15 @@ IMPLEMENT_FUNCTION(34, Rebecca, function34)
 		break;
 
 	case kActionNone:
-		if (params->param2 == kTimeInvalid) {
+		if (params->param2 != kTimeInvalid) {
 			if (getState()->time <= kTime1386000) {
 				if (!getEntities()->isInRestaurant(kEntityPlayer) || !params->param2)
 					params->param2 = (uint)getState()->time;
 
 				if (params->param2 >= getState()->time) {
-					Entity::timeCheckCallback(kTime2052000, params->param3, 1, WRAP_SETUP_FUNCTION(Rebecca, setup_function19));
+					if (params->param1) {
+						Entity::timeCheckCallback(kTime2052000, params->param3, 3, WRAP_SETUP_FUNCTION(Rebecca, setup_function19));
+					}
 					break;
 				}
 			}
@@ -1247,7 +1279,9 @@ IMPLEMENT_FUNCTION(34, Rebecca, function34)
 			getSavePoints()->push(kEntityRebecca, kEntityWaiter1, kAction223712416);
 		}
 
-		Entity::timeCheckCallback(kTime2052000, params->param3, 1, WRAP_SETUP_FUNCTION(Rebecca, setup_function19));
+		if (params->param1) {
+			Entity::timeCheckCallback(kTime2052000, params->param3, 3, WRAP_SETUP_FUNCTION(Rebecca, setup_function19));
+		}
 		break;
 
 	case kActionEndSound:
@@ -1785,7 +1819,7 @@ IMPLEMENT_FUNCTION(48, Rebecca, function48)
 		getObjects()->update(kObjectCompartmentE, kEntityRebecca, kObjectLocation1, kCursorNormal, kCursorNormal);
 
 		if (params->param1) {
-			params->param1 = 0;
+			params->param2 = 1;
 
 			setCallback(2);
 			setup_playSound(getSound()->justCheckingCath());
diff --git a/engines/lastexpress/entities/salko.cpp b/engines/lastexpress/entities/salko.cpp
index 26f512b..f93d13c 100644
--- a/engines/lastexpress/entities/salko.cpp
+++ b/engines/lastexpress/entities/salko.cpp
@@ -40,12 +40,12 @@ namespace LastExpress {
 
 Salko::Salko(LastExpressEngine *engine) : Entity(engine, kEntitySalko) {
 	ADD_CALLBACK_FUNCTION(Salko, reset);
-	ADD_CALLBACK_FUNCTION(Salko, enterExitCompartment);
-	ADD_CALLBACK_FUNCTION(Salko, draw);
-	ADD_CALLBACK_FUNCTION(Salko, updateEntity);
-	ADD_CALLBACK_FUNCTION(Salko, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Salko, savegame);
-	ADD_CALLBACK_FUNCTION(Salko, function7);
+	ADD_CALLBACK_FUNCTION_SI(Salko, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_S(Salko, draw);
+	ADD_CALLBACK_FUNCTION_II(Salko, updateEntity);
+	ADD_CALLBACK_FUNCTION_I(Salko, updateFromTime);
+	ADD_CALLBACK_FUNCTION_II(Salko, savegame);
+	ADD_CALLBACK_FUNCTION_II(Salko, function7);
 	ADD_CALLBACK_FUNCTION(Salko, function8);
 	ADD_CALLBACK_FUNCTION(Salko, chapter1);
 	ADD_CALLBACK_FUNCTION(Salko, chapter1Handler);
@@ -176,6 +176,7 @@ IMPLEMENT_FUNCTION(10, Salko, chapter1Handler)
 	case kActionNone:
 		getData()->entityPosition = getEntityData(kEntityIvo)->entityPosition;
 		getData()->location = getEntityData(kEntityIvo)->location;
+		getData()->car = getEntityData(kEntityIvo)->car;
 		break;
 
 	case kActionCallback:
@@ -357,6 +358,8 @@ label_callback3:
 			break;
 
 		case 2:
+			getEntities()->drawSequenceLeft(kEntitySalko, "612AF");
+			getEntities()->enterCompartment(kEntitySalko, kObjectCompartmentF, true);
 			break;
 
 		case 3:
@@ -416,7 +419,7 @@ IMPLEMENT_FUNCTION(17, Salko, function17)
 		getData()->inventoryItem = kItemNone;
 
 		setCallback(1);
-		setup_updateEntity(kCarGreenSleeping, kPosition_2740);
+		setup_updateEntity(kCarRedSleeping, kPosition_2740);
 		break;
 
 	case kActionCallback:
diff --git a/engines/lastexpress/entities/sophie.cpp b/engines/lastexpress/entities/sophie.cpp
index ac47325..cda72bd 100644
--- a/engines/lastexpress/entities/sophie.cpp
+++ b/engines/lastexpress/entities/sophie.cpp
@@ -33,7 +33,7 @@ namespace LastExpress {
 
 Sophie::Sophie(LastExpressEngine *engine) : Entity(engine, kEntitySophie) {
 	ADD_CALLBACK_FUNCTION(Sophie, reset);
-	ADD_CALLBACK_FUNCTION(Sophie, updateEntity);
+	ADD_CALLBACK_FUNCTION_II(Sophie, updateEntity);
 	ADD_CALLBACK_FUNCTION(Sophie, chaptersHandler);
 	ADD_CALLBACK_FUNCTION(Sophie, chapter1);
 	ADD_CALLBACK_FUNCTION(Sophie, function5);
@@ -70,8 +70,8 @@ IMPLEMENT_FUNCTION_II(2, Sophie, updateEntity, CarIndex, EntityPosition)
 		CarIndex rebeccaCar = getEntityData(kEntityRebecca)->car;
 
 		if (getEntities()->isDistanceBetweenEntities(kEntitySophie, kEntityRebecca, 500)
-		|| (direction == kDirectionUp && car >= rebeccaCar && position > rebecca_position)
-		|| (direction == kDirectionDown && car <= rebeccaCar && position < rebecca_position)) {
+		|| (direction == kDirectionUp && (car > rebeccaCar || car == rebeccaCar && position > rebecca_position))
+		|| (direction == kDirectionDown && (car < rebeccaCar || car == rebeccaCar && position < rebecca_position))) {
 			 getData()->field_49B = 0;
 			 params->param3 = 1;
 		}
@@ -108,6 +108,7 @@ IMPLEMENT_FUNCTION(3, Sophie, chaptersHandler)
 
 	case kActionNone:
 		getData()->entityPosition = getEntityData(kEntityRebecca)->entityPosition;
+		getData()->location = getEntityData(kEntityRebecca)->location;
 		getData()->car = getEntityData(kEntityRebecca)->car;
 		break;
 
diff --git a/engines/lastexpress/entities/tatiana.cpp b/engines/lastexpress/entities/tatiana.cpp
index 807a844..5dd61e3 100644
--- a/engines/lastexpress/entities/tatiana.cpp
+++ b/engines/lastexpress/entities/tatiana.cpp
@@ -42,21 +42,21 @@ namespace LastExpress {
 
 Tatiana::Tatiana(LastExpressEngine *engine) : Entity(engine, kEntityTatiana) {
 	ADD_CALLBACK_FUNCTION(Tatiana, reset);
-	ADD_CALLBACK_FUNCTION(Tatiana, playSound);
-	ADD_CALLBACK_FUNCTION(Tatiana, draw);
-	ADD_CALLBACK_FUNCTION(Tatiana, updatePosition);
-	ADD_CALLBACK_FUNCTION(Tatiana, enterExitCompartment);
-	ADD_CALLBACK_FUNCTION(Tatiana, enterExitCompartment2);
-	ADD_CALLBACK_FUNCTION(Tatiana, callSavepoint);
+	ADD_CALLBACK_FUNCTION_S(Tatiana, playSound);
+	ADD_CALLBACK_FUNCTION_S(Tatiana, draw);
+	ADD_CALLBACK_FUNCTION_SII(Tatiana, updatePosition);
+	ADD_CALLBACK_FUNCTION_SI(Tatiana, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_SI(Tatiana, enterExitCompartment2);
+	ADD_CALLBACK_FUNCTION_SIIS(Tatiana, callSavepoint);
 	ADD_CALLBACK_FUNCTION(Tatiana, callbackActionOnDirection);
-	ADD_CALLBACK_FUNCTION(Tatiana, updateFromTicks);
-	ADD_CALLBACK_FUNCTION(Tatiana, updateFromTime);
+	ADD_CALLBACK_FUNCTION_I(Tatiana, updateFromTicks);
+	ADD_CALLBACK_FUNCTION_I(Tatiana, updateFromTime);
 	ADD_CALLBACK_FUNCTION(Tatiana, callbackActionRestaurantOrSalon);
-	ADD_CALLBACK_FUNCTION(Tatiana, savegame);
-	ADD_CALLBACK_FUNCTION(Tatiana, updateEntity);
+	ADD_CALLBACK_FUNCTION_II(Tatiana, savegame);
+	ADD_CALLBACK_FUNCTION_II(Tatiana, updateEntity);
 	ADD_CALLBACK_FUNCTION(Tatiana, enterCompartment);
 	ADD_CALLBACK_FUNCTION(Tatiana, exitCompartment);
-	ADD_CALLBACK_FUNCTION(Tatiana, handleCompartment);
+	ADD_CALLBACK_FUNCTION_I(Tatiana, handleCompartment);
 	ADD_CALLBACK_FUNCTION(Tatiana, chapter1);
 	ADD_CALLBACK_FUNCTION(Tatiana, function18);
 	ADD_CALLBACK_FUNCTION(Tatiana, chapter1Handler);
@@ -72,7 +72,7 @@ Tatiana::Tatiana(LastExpressEngine *engine) : Entity(engine, kEntityTatiana) {
 	ADD_CALLBACK_FUNCTION(Tatiana, leaveBreakfast);
 	ADD_CALLBACK_FUNCTION(Tatiana, returnToCompartment2);
 	ADD_CALLBACK_FUNCTION(Tatiana, chapter3);
-	ADD_CALLBACK_FUNCTION(Tatiana, playChess);
+	ADD_CALLBACK_FUNCTION_TYPE2(Tatiana, playChess, EntityParametersI5S, EntityParametersSIII);
 	ADD_CALLBACK_FUNCTION(Tatiana, returnToCompartment3);
 	ADD_CALLBACK_FUNCTION(Tatiana, beforeConcert);
 	ADD_CALLBACK_FUNCTION(Tatiana, concert);
@@ -82,11 +82,11 @@ Tatiana::Tatiana(LastExpressEngine *engine) : Entity(engine, kEntityTatiana) {
 	ADD_CALLBACK_FUNCTION(Tatiana, function39);
 	ADD_CALLBACK_FUNCTION(Tatiana, function40);
 	ADD_CALLBACK_FUNCTION(Tatiana, trapCath);
-	ADD_CALLBACK_FUNCTION(Tatiana, function42);
+	ADD_CALLBACK_FUNCTION_II(Tatiana, function42);
 	ADD_CALLBACK_FUNCTION(Tatiana, chapter4);
 	ADD_CALLBACK_FUNCTION(Tatiana, inCompartment4);
 	ADD_CALLBACK_FUNCTION(Tatiana, meetAlexei);
-	ADD_CALLBACK_FUNCTION(Tatiana, withAlexei);
+	ADD_CALLBACK_FUNCTION_TYPE(Tatiana, withAlexei, EntityParametersI5S);
 	ADD_CALLBACK_FUNCTION(Tatiana, thinking);
 	ADD_CALLBACK_FUNCTION(Tatiana, seekCath);
 	ADD_CALLBACK_FUNCTION(Tatiana, function49);
@@ -100,7 +100,7 @@ Tatiana::Tatiana(LastExpressEngine *engine) : Entity(engine, kEntityTatiana) {
 
 //////////////////////////////////////////////////////////////////////////
 IMPLEMENT_FUNCTION(1, Tatiana, reset)
-	Entity::reset(savepoint, true);
+	Entity::reset(savepoint, kClothes3, true);
 IMPLEMENT_FUNCTION_END
 
 //////////////////////////////////////////////////////////////////////////
@@ -421,7 +421,7 @@ IMPLEMENT_FUNCTION(19, Tatiana, chapter1Handler)
 		break;
 
 	case kActionNone:
-		if (getSoundQueue()->isBuffered(kEntityTatiana) || !params->param4 || params->param3 == 2 || getSoundQueue()->isBuffered("TAT1066"))
+		if (getSoundQueue()->isBuffered(kEntityTatiana) || !params->param4 || params->param3 >= 2 || getSoundQueue()->isBuffered("TAT1066"))
 			goto label_tatiana_chapter1_2;
 
 		if (Entity::updateParameter(params->param5, getState()->timeTicks, 450)) {
@@ -616,6 +616,8 @@ IMPLEMENT_FUNCTION(22, Tatiana, getSomeAir)
 			goto label_update;
 
 		if (Entity::updateParameterTime(kTime1233000, ((!getEvent(kEventTatianaAskMatchSpeakRussian) && !getEvent(kEventTatianaAskMatch)) || getEntities()->isInGreenCarEntrance(kEntityPlayer)), params->param1, 0)) {
+			params->param1 = kTimeInvalid;
+
 label_update:
 			if (!getEvent(kEventTatianaAskMatchSpeakRussian)
 			 && !getEvent(kEventTatianaAskMatch)
@@ -624,10 +626,9 @@ label_update:
 				getObjects()->update(kObject25, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorForward);
 				getObjects()->update(kObjectTrainTimeTable, kEntityTatiana, kObjectLocation1, kCursorNormal, kCursorForward);
 			}
+			break;
 		}
 
-		params->param1 = kTimeInvalid;
-
 		getObjects()->update(kObject25, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
 		getObjects()->update(kObjectTrainTimeTable, kEntityPlayer, kObjectLocationNone, kCursorKeepValue, kCursorKeepValue);
 		getEntities()->updatePositionExit(kEntityTatiana, kCarGreenSleeping, 70);
@@ -796,7 +797,7 @@ IMPLEMENT_FUNCTION(26, Tatiana, chapter2Handler)
 
 	case kAction1:
 		getData()->inventoryItem = kItemNone;
-		setup_joinAlexei();
+		setup_breakfastClick();
 		break;
 
 	case kActionDefault:
@@ -1023,7 +1024,7 @@ IMPLEMENT_FUNCTION(32, Tatiana, playChess)
 		}
 
 		if (parameters->param4 && parameters->param5) {
-			if (Entity::updateParameterCheck(parameters->param4, getState()->time, 6300)) {
+			if (Entity::updateParameterCheck(parameters1->param4, getState()->time, 6300)) {
 				if (getEntities()->isSomebodyInsideRestaurantOrSalon()) {
 					getData()->location = kLocationOutsideCompartment;
 
@@ -1035,7 +1036,6 @@ IMPLEMENT_FUNCTION(32, Tatiana, playChess)
 		break;
 
 	case  kActionEndSound:
-		parameters->param2 = 0;
 		++parameters->param3;
 
 		switch (parameters->param3) {
@@ -1080,7 +1080,7 @@ IMPLEMENT_FUNCTION(32, Tatiana, playChess)
 		case 6:
 			parameters->param1 = 4500;
 			getEntities()->drawSequenceLeft(kEntityTatiana, "110B");
-			strcpy((char *)&parameters->seq, "Tat3160B");
+			strcpy((char *)&parameters->seq, "Tat3160F");
 			break;
 		}
 		break;
@@ -1165,6 +1165,7 @@ IMPLEMENT_FUNCTION(34, Tatiana, beforeConcert)
 
 			getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
 			getObjects()->update(kObject49, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
+			setCallback(2);
 			setup_exitCompartment();
 			break;
 
@@ -1238,7 +1239,7 @@ IMPLEMENT_FUNCTION(36, Tatiana, leaveConcert)
 		getData()->location = kLocationOutsideCompartment;
 
 		setCallback(1);
-		setup_updateEntity(kCarGreenSleeping, kPosition_7500);
+		setup_updateEntity(kCarRedSleeping, kPosition_7500);
 		break;
 
 	case kActionCallback:
@@ -1247,7 +1248,7 @@ IMPLEMENT_FUNCTION(36, Tatiana, leaveConcert)
 			break;
 
 		case 1:
-			if (!getEntities()->checkFields19(kEntityPlayer, kCarGreenSleeping, kPosition_7850) || getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_8200)) {
+			if (!getEntities()->checkFields19(kEntityPlayer, kCarRedSleeping, kPosition_7850) || getEntities()->isInsideCompartment(kEntityPlayer, kCarRedSleeping, kPosition_8200)) {
 				setCallback(2);
 				setup_enterCompartment();
 				break;
@@ -1262,6 +1263,7 @@ IMPLEMENT_FUNCTION(36, Tatiana, leaveConcert)
 			}
 
 			getScenes()->loadSceneFromObject(kObjectCompartmentB);
+			setup_afterConcert();
 			break;
 
 		case 2:
@@ -1543,7 +1545,7 @@ IMPLEMENT_FUNCTION(40, Tatiana, function40)
 
 	case kActionExcuseMe:
 		if (getEvent(kEventTatianaAskMatchSpeakRussian) || getEvent(kEventTatianaAskMatch) || getEvent(kEventVassiliSeizure))
-			getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1001A" : "CAT1010");
+			getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1010A" : "CAT1010");
 		else
 			getSound()->excuseMeCath();
 		break;
@@ -1732,7 +1734,7 @@ IMPLEMENT_FUNCTION(45, Tatiana, meetAlexei)
 			getObjects()->update(kObjectCompartmentB, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
 			getData()->location = kLocationOutsideCompartment;
 
-			setCallback(1);
+			setCallback(2);
 			setup_updateEntity(kCarGreenSleeping, kPosition_540);
 			break;
 
@@ -1782,7 +1784,7 @@ IMPLEMENT_FUNCTION(46, Tatiana, withAlexei)
 		if (CURRENT_PARAM(1, 1) == kTimeInvalid || getState()->time <= kTime2394000)
 			break;
 
-		if (getState()->time >= kTime2398500) {
+		if (getState()->time > kTime2398500) {
 			CURRENT_PARAM(1, 1) = kTimeInvalid;
 		} else {
 			if (getEntities()->isInGreenCarEntrance(kEntityPlayer) || !CURRENT_PARAM(1, 1))
diff --git a/engines/lastexpress/entities/train.cpp b/engines/lastexpress/entities/train.cpp
index f707b02..c8cfe8c 100644
--- a/engines/lastexpress/entities/train.cpp
+++ b/engines/lastexpress/entities/train.cpp
@@ -38,14 +38,14 @@
 namespace LastExpress {
 
 Train::Train(LastExpressEngine *engine) : Entity(engine, kEntityTrain) {
-	ADD_CALLBACK_FUNCTION(Train, savegame);
+	ADD_CALLBACK_FUNCTION_II(Train, savegame);
 	ADD_CALLBACK_FUNCTION(Train, chapter1);
 	ADD_CALLBACK_FUNCTION(Train, chapter2);
 	ADD_CALLBACK_FUNCTION(Train, chapter3);
 	ADD_CALLBACK_FUNCTION(Train, chapter4);
 	ADD_CALLBACK_FUNCTION(Train, chapter5);
-	ADD_CALLBACK_FUNCTION(Train, harem);
-	ADD_CALLBACK_FUNCTION(Train, process);
+	ADD_CALLBACK_FUNCTION_II(Train, harem);
+	ADD_CALLBACK_FUNCTION_TYPE2(Train, process, EntityParametersIIII, EntityParametersIIIS);
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -111,7 +111,7 @@ IMPLEMENT_FUNCTION_II(7, Train, harem, ObjectIndex, uint32)
 	}
 
 	params->param4 = getEntities()->isInsideCompartment(kEntityAlouan, kCarGreenSleeping, (EntityPosition)params->param3);
-	params->param5 = (ENTITY_PARAM(0, 7) - params->param3) < 1 ? true : false;
+	params->param5 = (ENTITY_PARAM(0, 7) == params->param3) ? true : false;
 	params->param6 = getEntities()->isInsideCompartment(kEntityYasmin, kCarGreenSleeping, (EntityPosition)params->param3);
 	params->param7 = getEntities()->isInsideCompartment(kEntityHadija, kCarGreenSleeping, (EntityPosition)params->param3);
 
@@ -374,7 +374,10 @@ label_process:
 					break;
 
 				case kCarRestaurant:
-					getEntities()->drawSequenceLeft(kEntityTrain, isNight() ? "RCWNN" : "RCWND");
+					if (getProgress().isNightTime)
+						getEntities()->drawSequenceLeft(kEntityTrain, "RCWNM");
+					else
+						getEntities()->drawSequenceLeft(kEntityTrain, isNight() ? "RCWNN" : "RCWND");
 					break;
 				}
 
@@ -478,7 +481,7 @@ label_process:
 		break;
 
 	case kAction203863200:
-		if (!strcmp(savepoint.param.charValue, "")) {
+		if (strcmp(savepoint.param.charValue, "")) {
 			params->param8 = 1;
 			strcpy((char *)&params1->seq, savepoint.param.charValue);	// this is the sound file name
 		}
@@ -502,7 +505,7 @@ label_process:
 		case kObjectCompartment4:
 		case kObjectCompartmentC:
 		case kObjectCompartmentD:
-			params1->param1 = (savepoint.param.intValue == kObjectCompartment1 || savepoint.param.intValue == kObjectCompartment2) ? kCarGreenSleeping : kCarRedSleeping;
+			params1->param1 = (savepoint.param.intValue == kObjectCompartment3 || savepoint.param.intValue == kObjectCompartment4) ? kCarGreenSleeping : kCarRedSleeping;
 			params1->param2 = (savepoint.param.intValue == kObjectCompartment3 || savepoint.param.intValue == kObjectCompartmentC) ? kPosition_6470 : kPosition_5790;
 			params1->param3 = kPosition_6130;
 			break;
@@ -511,7 +514,7 @@ label_process:
 		case kObjectCompartment6:
 		case kObjectCompartmentE:
 		case kObjectCompartmentF:
-			params1->param1 = (savepoint.param.intValue == kObjectCompartment1 || savepoint.param.intValue == kObjectCompartment2) ? kCarGreenSleeping : kCarRedSleeping;
+			params1->param1 = (savepoint.param.intValue == kObjectCompartment5 || savepoint.param.intValue == kObjectCompartment6) ? kCarGreenSleeping : kCarRedSleeping;
 			params1->param2 = (savepoint.param.intValue == kObjectCompartment5 || savepoint.param.intValue == kObjectCompartmentE) ? kPosition_4840 : kPosition_4070;
 			params1->param3 = kPosition_4455;
 			break;
@@ -520,7 +523,7 @@ label_process:
 		case kObjectCompartment8:
 		case kObjectCompartmentG:
 		case kObjectCompartmentH:
-			params1->param1 = (savepoint.param.intValue == kObjectCompartment1 || savepoint.param.intValue == kObjectCompartment2) ? kCarGreenSleeping : kCarRedSleeping;
+			params1->param1 = (savepoint.param.intValue == kObjectCompartment7 || savepoint.param.intValue == kObjectCompartment8) ? kCarGreenSleeping : kCarRedSleeping;
 			params1->param2 = (savepoint.param.intValue == kObjectCompartment7 || savepoint.param.intValue == kObjectCompartmentG) ? kPosition_3050 : kPosition_2740;
 			params1->param3 = kPositionNone;
 			break;
diff --git a/engines/lastexpress/entities/vassili.cpp b/engines/lastexpress/entities/vassili.cpp
index e28ace9..1c25ce2 100644
--- a/engines/lastexpress/entities/vassili.cpp
+++ b/engines/lastexpress/entities/vassili.cpp
@@ -42,8 +42,8 @@ namespace LastExpress {
 
 Vassili::Vassili(LastExpressEngine *engine) : Entity(engine, kEntityVassili) {
 	ADD_CALLBACK_FUNCTION(Vassili, reset);
-	ADD_CALLBACK_FUNCTION(Vassili, draw);
-	ADD_CALLBACK_FUNCTION(Vassili, savegame);
+	ADD_CALLBACK_FUNCTION_S(Vassili, draw);
+	ADD_CALLBACK_FUNCTION_II(Vassili, savegame);
 	ADD_CALLBACK_FUNCTION(Vassili, chapter1);
 	ADD_CALLBACK_FUNCTION(Vassili, chapter1Handler);
 	ADD_CALLBACK_FUNCTION(Vassili, inBed);
@@ -103,14 +103,10 @@ IMPLEMENT_FUNCTION(5, Vassili, chapter1Handler)
 		if (params->param1) {
 			getData()->entityPosition = getEntityData(kEntityTatiana)->entityPosition;
 			getData()->location = getEntityData(kEntityTatiana)->location;
+			getData()->car = getEntityData(kEntityTatiana)->car;
 		} else {
-			if (params->param3 && params->param3 >= getState()->time) {
+			if (!Entity::updateParameterCheck(params->param3, getState()->time, 450))
 				break;
-			}else {
-				params->param3 = (uint)getState()->time + 450;
-				if (params->param3 == 0)
-					break;
-			}
 
 			if (!params->param2 && getObjects()->get(kObjectCompartmentA).status == kObjectLocation1) {
 				params->param2 = 1;
@@ -215,9 +211,9 @@ IMPLEMENT_FUNCTION(7, Vassili, function7)
 		if (params->param1 != kTimeInvalid && getState()->time > kTime1503000) {
 
 			 if (getState()->time <= kTime1512000) {
-				 if (getEntities()->isPlayerInCar(kCarRedSleeping) || !params->param1) {
+				 if (!getEntities()->isPlayerInCar(kCarRedSleeping) || !params->param1) {
 					 params->param1 = (uint)getState()->time + 150;
-					 if (params->param1) {
+					 if (!params->param1) {
 						 setup_function8();
 						 break;
 					 }
@@ -345,7 +341,7 @@ IMPLEMENT_FUNCTION(10, Vassili, seizure)
 		if (getCallback() != 1)
 			break;
 
-		getData()->location = kLocationInsideCompartment;
+		getEntityData(kEntityPlayer)->location = kLocationInsideCompartment;
 		getAction()->playAnimation(kEventVassiliSeizure);
 
 		getObjects()->update(kObjectCompartmentA, kEntityPlayer, kObjectLocationNone, kCursorHandKnock, kCursorHand);
diff --git a/engines/lastexpress/entities/verges.cpp b/engines/lastexpress/entities/verges.cpp
index b16217b..c3e56d9 100644
--- a/engines/lastexpress/entities/verges.cpp
+++ b/engines/lastexpress/entities/verges.cpp
@@ -39,21 +39,21 @@ namespace LastExpress {
 
 Verges::Verges(LastExpressEngine *engine) : Entity(engine, kEntityVerges) {
 	ADD_CALLBACK_FUNCTION(Verges, reset);
-	ADD_CALLBACK_FUNCTION(Verges, draw);
+	ADD_CALLBACK_FUNCTION_S(Verges, draw);
 	ADD_CALLBACK_FUNCTION(Verges, callbackActionOnDirection);
-	ADD_CALLBACK_FUNCTION(Verges, playSound);
-	ADD_CALLBACK_FUNCTION(Verges, playSound16);
+	ADD_CALLBACK_FUNCTION_S(Verges, playSound);
+	ADD_CALLBACK_FUNCTION_S(Verges, playSound16);
 	ADD_CALLBACK_FUNCTION(Verges, callbackActionRestaurantOrSalon);
-	ADD_CALLBACK_FUNCTION(Verges, savegame);
-	ADD_CALLBACK_FUNCTION(Verges, updateEntity);
-	ADD_CALLBACK_FUNCTION(Verges, walkBetweenCars);
-	ADD_CALLBACK_FUNCTION(Verges, makeAnnouncement);
+	ADD_CALLBACK_FUNCTION_II(Verges, savegame);
+	ADD_CALLBACK_FUNCTION_II(Verges, updateEntity);
+	ADD_CALLBACK_FUNCTION_S(Verges, walkBetweenCars);
+	ADD_CALLBACK_FUNCTION_IIS(Verges, makeAnnouncement);
 	ADD_CALLBACK_FUNCTION(Verges, function11);
 	ADD_CALLBACK_FUNCTION(Verges, function12);
-	ADD_CALLBACK_FUNCTION(Verges, baggageCar);
-	ADD_CALLBACK_FUNCTION(Verges, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Verges, dialog);
-	ADD_CALLBACK_FUNCTION(Verges, dialog2);
+	ADD_CALLBACK_FUNCTION_I(Verges, baggageCar);
+	ADD_CALLBACK_FUNCTION_I(Verges, updateFromTime);
+	ADD_CALLBACK_FUNCTION_IS(Verges, dialog);
+	ADD_CALLBACK_FUNCTION_ISS(Verges, dialog2);
 	ADD_CALLBACK_FUNCTION(Verges, talkAboutPassengerList);
 	ADD_CALLBACK_FUNCTION(Verges, chapter1);
 	ADD_CALLBACK_FUNCTION(Verges, talkHarem);
@@ -67,7 +67,7 @@ Verges::Verges(LastExpressEngine *engine) : Entity(engine, kEntityVerges) {
 	ADD_CALLBACK_FUNCTION(Verges, chapter2);
 	ADD_CALLBACK_FUNCTION(Verges, chapter2Handler);
 	ADD_CALLBACK_FUNCTION(Verges, chapter3);
-	ADD_CALLBACK_FUNCTION(Verges, function30);
+	ADD_CALLBACK_FUNCTION_S(Verges, function30);
 	ADD_CALLBACK_FUNCTION(Verges, talkAboutMax);
 	ADD_CALLBACK_FUNCTION(Verges, function32);
 	ADD_CALLBACK_FUNCTION(Verges, function33);
@@ -492,7 +492,7 @@ IMPLEMENT_FUNCTION_ISS(16, Verges, dialog2, EntityIndex)
 		break;
 
 	case kActionNone:
-		if (CURRENT_PARAM(1, 1) && params->param8) {
+		if (CURRENT_PARAM(1, 1) >= 2 && params->param8) {
 			getSavePoints()->push(kEntityVerges, (EntityIndex)params->param1, kAction125499160);
 
 			if (!getEntities()->isPlayerPosition(kCarGreenSleeping, 2) && !getEntities()->isPlayerPosition(kCarRedSleeping, 2))
@@ -742,7 +742,7 @@ IMPLEMENT_FUNCTION(25, Verges, policeSearch)
 					getData()->car = kCarRedSleeping;
 					getData()->entityPosition = kPosition_9270;
 				} else {
-					if (getEntityData(kEntityPlayer)->car > kCarGreenSleeping
+					if (getEntityData(kEntityPlayer)->car < kCarGreenSleeping
 					 || (getEntityData(kEntityPlayer)->car == kCarGreenSleeping && getEntityData(kEntityPlayer)->entityPosition < kPosition_4840)) {
 						getSound()->playSound(kEntityPlayer, "BUMP");
 						getScenes()->loadSceneFromObject(kObjectCompartment5, true);
@@ -777,7 +777,7 @@ IMPLEMENT_FUNCTION(25, Verges, policeSearch)
 					setup_makeAnnouncement(kCarGreenSleeping, kPosition_540, "TRA1005");
 				} else {
 					setCallback(7);
-					setup_makeAnnouncement(kCarRedSleeping, kPosition_9460, "TRA1006");
+					setup_makeAnnouncement(kCarRedSleeping, kPosition_9460, "TRA1005");
 				}
 				break;
 			}
@@ -911,15 +911,13 @@ label_callback3:
 			break;
 
 label_callback4:
-		if (Entity::timeCheckCallback(kTime1089000, params->param8, 5, WRAP_SETUP_FUNCTION(Verges, setup_function12)))
-			break;
-
-		params->param8 = 1;
-
-		if (!params->param5) {
-			setCallback(5);
-			setup_function12();
-			break;
+		if (getState()->time > kTime1089000 && !params->param8) {
+			params->param8 = 1;
+			if (!params->param5) {
+				setCallback(5);
+				setup_function12();
+				break;
+			}
 		}
 
 label_callback8:
@@ -970,7 +968,7 @@ label_callback15:
 
 	case kActionOpenDoor:
 		setCallback(17);
-		setup_baggageCar(savepoint.param.intValue < 106 ? true : false);
+		setup_baggageCar(savepoint.param.intValue == kObject105 ? true : false);
 		break;
 
 	case kActionDefault:
@@ -1130,7 +1128,7 @@ label_callback_6:
 
 	case kActionOpenDoor:
 		setCallback(8);
-		setup_baggageCar(savepoint.param.intValue < 106);
+		setup_baggageCar(savepoint.param.intValue == kObject105);
 		break;
 
 	case kActionDefault:
@@ -1318,7 +1316,7 @@ IMPLEMENT_FUNCTION(32, Verges, function32)
 			break;
 
 		case 1:
-			getData()->entityPosition = kPosition_8500;
+			getData()->entityPosition = kPosition_5800;
 			getData()->location = kLocationOutsideCompartment;
 			getSound()->playSound(kEntityVerges, "TRA3004");
 
@@ -1400,12 +1398,12 @@ IMPLEMENT_FUNCTION(33, Verges, function33)
 			getData()->entityPosition = kPosition_5799;
 
 			setCallback(getProgress().field_3C ? 4 : 5);
-			setup_playSound(getProgress().field_3C ? "ABB3035A" : "ABB3035");
+			setup_playSound(getProgress().field_3C ? "ABB3035A" : "Abb3035");
 			break;
 
 		case 4:
 			setCallback(5);
-			setup_playSound("ABB3035");
+			setup_playSound("Abb3035");
 			break;
 
 		case 5:
@@ -1480,7 +1478,7 @@ label_callback_9:
 
 	case kActionOpenDoor:
 		setCallback(11);
-		setup_baggageCar(savepoint.param.intValue < 106);
+		setup_baggageCar(savepoint.param.intValue == kObject105);
 		break;
 
 	case kActionCallback:
@@ -1542,7 +1540,7 @@ IMPLEMENT_FUNCTION(35, Verges, organizeConcertInvitations)
 
 		case 2:
 			setCallback(3);
-			setup_dialog(kEntityMertens, "Tra3011A");
+			setup_dialog(kEntityCoudert, "Tra3011A");
 			break;
 
 		case 3:
@@ -1614,7 +1612,7 @@ IMPLEMENT_FUNCTION(37, Verges, chapter4Handler)
 		}
 
 label_callback_1:
-		if (ENTITY_PARAM(0, 6)) {
+		if (!ENTITY_PARAM(0, 6)) {
 			if (ENTITY_PARAM(0, 3)) {
 				setCallback(2);
 				setup_talkAboutPassengerList();
@@ -1652,7 +1650,7 @@ label_callback_8:
 
 	case kActionOpenDoor:
 		setCallback(10);
-		setup_baggageCar(savepoint.param.intValue < 106);
+		setup_baggageCar(savepoint.param.intValue == kObject105);
 		break;
 
 	case kActionDefault:
@@ -1739,7 +1737,7 @@ IMPLEMENT_FUNCTION(38, Verges, resetState)
 		getData()->entityPosition = kPosition_5790;
 
 		setCallback(1);
-		setup_updateEntity(kCarGreenSleeping, kPosition_540);
+		setup_updateEntity(kCarRedSleeping, kPosition_540);
 		break;
 	}
 IMPLEMENT_FUNCTION_END
@@ -1905,6 +1903,7 @@ void Verges::talk(const SavePoint &savepoint, const char *sound1, const char *so
 			break;
 
 		case 5:
+			setCallback(6);
 			setup_function11();
 			break;
 
diff --git a/engines/lastexpress/entities/vesna.cpp b/engines/lastexpress/entities/vesna.cpp
index 8ab3902..7ac53ce 100644
--- a/engines/lastexpress/entities/vesna.cpp
+++ b/engines/lastexpress/entities/vesna.cpp
@@ -38,16 +38,16 @@ namespace LastExpress {
 
 Vesna::Vesna(LastExpressEngine *engine) : Entity(engine, kEntityVesna) {
 	ADD_CALLBACK_FUNCTION(Vesna, reset);
-	ADD_CALLBACK_FUNCTION(Vesna, playSound);
-	ADD_CALLBACK_FUNCTION(Vesna, enterExitCompartment);
-	ADD_CALLBACK_FUNCTION(Vesna, draw);
-	ADD_CALLBACK_FUNCTION(Vesna, updateEntity);
-	ADD_CALLBACK_FUNCTION(Vesna, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Vesna, updateEntity2);
+	ADD_CALLBACK_FUNCTION_S(Vesna, playSound);
+	ADD_CALLBACK_FUNCTION_SI(Vesna, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_S(Vesna, draw);
+	ADD_CALLBACK_FUNCTION_II(Vesna, updateEntity);
+	ADD_CALLBACK_FUNCTION_I(Vesna, updateFromTime);
+	ADD_CALLBACK_FUNCTION_II(Vesna, updateEntity2);
 	ADD_CALLBACK_FUNCTION(Vesna, callbackActionRestaurantOrSalon);
 	ADD_CALLBACK_FUNCTION(Vesna, callbackActionOnDirection);
-	ADD_CALLBACK_FUNCTION(Vesna, savegame);
-	ADD_CALLBACK_FUNCTION(Vesna, homeAlone);
+	ADD_CALLBACK_FUNCTION_II(Vesna, savegame);
+	ADD_CALLBACK_FUNCTION_TYPE(Vesna, homeAlone, EntityParametersIIIS);
 	ADD_CALLBACK_FUNCTION(Vesna, chapter1);
 	ADD_CALLBACK_FUNCTION(Vesna, withMilos);
 	ADD_CALLBACK_FUNCTION(Vesna, homeTogether);
@@ -56,7 +56,7 @@ Vesna::Vesna(LastExpressEngine *engine) : Entity(engine, kEntityVesna) {
 	ADD_CALLBACK_FUNCTION(Vesna, chapter2Handler);
 	ADD_CALLBACK_FUNCTION(Vesna, checkTrain);
 	ADD_CALLBACK_FUNCTION(Vesna, chapter3);
-	ADD_CALLBACK_FUNCTION(Vesna, inCompartment);
+	ADD_CALLBACK_FUNCTION_TYPE(Vesna, inCompartment, EntityParametersIIIS);
 	ADD_CALLBACK_FUNCTION(Vesna, takeAWalk);
 	ADD_CALLBACK_FUNCTION(Vesna, killAnna);
 	ADD_CALLBACK_FUNCTION(Vesna, killedAnna);
@@ -93,7 +93,7 @@ IMPLEMENT_FUNCTION_END
 //////////////////////////////////////////////////////////////////////////
 IMPLEMENT_FUNCTION_II(5, Vesna, updateEntity, CarIndex, EntityPosition)
 	if (savepoint.action == kActionExcuseMeCath) {
-		getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT10150" : "CAT1015A");
+		getSound()->playSound(kEntityPlayer, rnd(2) ? "CAT1015" : "CAT1015A");
 
 		return;
 	}
@@ -116,8 +116,8 @@ IMPLEMENT_FUNCTION_II(7, Vesna, updateEntity2, CarIndex, EntityPosition)
 		params->param3 = 0;
 
 		if (getEntities()->isDistanceBetweenEntities(kEntityVesna, kEntityMilos, 500)
-		 || (((getData()->direction == kDirectionUp && (getData()->car > getEntityData(kEntityMilos)->car)) || (getData()->car == getEntityData(kEntityMilos)->car && getData()->entityPosition > getEntityData(kEntityMilos)->entityPosition)))
-		 || (((getData()->direction == kDirectionDown && (getData()->car < getEntityData(kEntityMilos)->car)) || (getData()->car == getEntityData(kEntityMilos)->car && getData()->entityPosition < getEntityData(kEntityMilos)->entityPosition)))) {
+		 || (getData()->direction == kDirectionUp && (getData()->car > getEntityData(kEntityMilos)->car || (getData()->car == getEntityData(kEntityMilos)->car && getData()->entityPosition > getEntityData(kEntityMilos)->entityPosition)))
+		 || (getData()->direction == kDirectionDown && (getData()->car < getEntityData(kEntityMilos)->car || (getData()->car == getEntityData(kEntityMilos)->car && getData()->entityPosition < getEntityData(kEntityMilos)->entityPosition)))) {
 			getData()->field_49B = 0;
 			params->param3 = 1;
 		}
@@ -277,6 +277,7 @@ IMPLEMENT_FUNCTION(13, Vesna, withMilos)
 	case kActionNone:
 		getData()->entityPosition = getEntityData(kEntityMilos)->entityPosition;
 		getData()->location = getEntityData(kEntityMilos)->location;
+		getData()->car = getEntityData(kEntityMilos)->car;
 		break;
 
 	case kActionCallback:
@@ -373,7 +374,7 @@ IMPLEMENT_FUNCTION(18, Vesna, checkTrain)
 
 	case kActionDefault:
 		setCallback(1);
-		setup_enterExitCompartment("610Bg", kObjectCompartmentG);
+		setup_enterExitCompartment("610BG", kObjectCompartmentG);
 		break;
 
 	case kActionCallback:
@@ -449,7 +450,7 @@ IMPLEMENT_FUNCTION(18, Vesna, checkTrain)
 
 		case 10:
 			setCallback(11);
-			setup_enterExitCompartment("610Ag", kObjectCompartmentG);
+			setup_enterExitCompartment("610AG", kObjectCompartmentG);
 			break;
 
 		case 11:
@@ -538,6 +539,8 @@ IMPLEMENT_FUNCTION(20, Vesna, inCompartment)
 
 		switch (parameters->param3) {
 		default:
+			strcpy((char *)&parameters->seq, "VES1015C");
+			parameters->param3 = 0;
 			break;
 
 		case 1:
@@ -547,11 +550,6 @@ IMPLEMENT_FUNCTION(20, Vesna, inCompartment)
 		case 2:
 			strcpy((char *)&parameters->seq, "VES1015B");
 			break;
-
-		case 3:
-			strcpy((char *)&parameters->seq, "VES1015C");
-			parameters->param3 = 0;
-			break;
 		}
 
 		getObjects()->update(kObjectCompartmentG, kEntityVesna, kObjectLocation3, kCursorNormal, kCursorNormal);
@@ -1083,7 +1081,7 @@ IMPLEMENT_FUNCTION(30, Vesna, climbing)
 	case kActionNone:
 		if (!params->param1) {
 			if (Entity::updateParameter(params->param3, getState()->timeTicks, 120)) {
-				getSound()->playSound(kEntityVesna, "Ves50001", kFlagDefault);
+				getSound()->playSound(kEntityVesna, "Ves5001", kFlagDefault);
 				params->param1 = 1;
 			}
 		}
@@ -1117,7 +1115,7 @@ IMPLEMENT_FUNCTION(30, Vesna, climbing)
 			params->param2 = getFight()->setup(kFightVesna);
 
 			if (params->param2) {
-				getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, params->param2 != Fight::kFightEndExit);
+				getLogic()->gameOver(kSavegameTypeIndex, 0, kSceneNone, params->param2 == Fight::kFightEndLost);
 			} else {
 				getSound()->playSound(kEntityPlayer, "TUNNEL");
 
diff --git a/engines/lastexpress/entities/waiter1.cpp b/engines/lastexpress/entities/waiter1.cpp
index 80ec471..0743d77 100644
--- a/engines/lastexpress/entities/waiter1.cpp
+++ b/engines/lastexpress/entities/waiter1.cpp
@@ -40,12 +40,12 @@ namespace LastExpress {
 	}
 
 Waiter1::Waiter1(LastExpressEngine *engine) : Entity(engine, kEntityWaiter1) {
-	ADD_CALLBACK_FUNCTION(Waiter1, callSavepoint);
-	ADD_CALLBACK_FUNCTION(Waiter1, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Waiter1, draw);
-	ADD_CALLBACK_FUNCTION(Waiter1, updatePosition);
+	ADD_CALLBACK_FUNCTION_SIIS(Waiter1, callSavepoint);
+	ADD_CALLBACK_FUNCTION_I(Waiter1, updateFromTime);
+	ADD_CALLBACK_FUNCTION_S(Waiter1, draw);
+	ADD_CALLBACK_FUNCTION_SII(Waiter1, updatePosition);
 	ADD_CALLBACK_FUNCTION(Waiter1, callbackActionOnDirection);
-	ADD_CALLBACK_FUNCTION(Waiter1, playSound);
+	ADD_CALLBACK_FUNCTION_S(Waiter1, playSound);
 	ADD_CALLBACK_FUNCTION(Waiter1, rebeccaFeedUs);
 	ADD_CALLBACK_FUNCTION(Waiter1, rebeccaClearOurTable);
 	ADD_CALLBACK_FUNCTION(Waiter1, abbotCheckMe);
@@ -296,7 +296,7 @@ IMPLEMENT_FUNCTION_END
 
 //////////////////////////////////////////////////////////////////////////
 IMPLEMENT_FUNCTION(18, Waiter1, clearAugust1)
-	serveTable(savepoint, "911", kEntityTables3, "010L", "010H", "913", &ENTITY_PARAM(0, 7));
+	serveTable(savepoint, "911", kEntityTables3, "010L", "010M", "913", &ENTITY_PARAM(0, 7));
 IMPLEMENT_FUNCTION_END
 
 //////////////////////////////////////////////////////////////////////////
@@ -325,7 +325,7 @@ IMPLEMENT_FUNCTION(20, Waiter1, servingDinner)
 			}
 		}
 
-		if (!getEntities()->isInKitchen(kEntityWaiter1) && !getEntities()->isSomebodyInsideRestaurantOrSalon())
+		if (!getEntities()->isInKitchen(kEntityWaiter1) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
 			break;
 
 		HANDLE_TABLE(0, 1, 1, setup_annaOrder);
@@ -536,7 +536,7 @@ IMPLEMENT_FUNCTION(28, Waiter1, serving3)
 		break;
 
 	case kActionNone:
-		if (!getEntities()->isInKitchen(kEntityWaiter2) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
+		if (!getEntities()->isInKitchen(kEntityWaiter1) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
 			break;
 
 		if (ENTITY_PARAM(1, 5)) {
@@ -734,12 +734,14 @@ IMPLEMENT_FUNCTION(32, Waiter1, serving4)
 		break;
 
 	case kActionNone:
-		if (Entity::updateParameter(params->param2, getState()->time, 3600)) {
-			ENTITY_PARAM(1, 8) = 1;
-			params->param1 = 0;
+		if (params->param1) {
+			if (Entity::updateParameter(params->param2, getState()->time, 3600)) {
+				ENTITY_PARAM(1, 8) = 1;
+				params->param1 = 0;
+			}
 		}
 
-		if (!getEntities()->isInKitchen(kEntityWaiter2) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
+		if (!getEntities()->isInKitchen(kEntityWaiter1) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
 			break;
 
 		if (ENTITY_PARAM(1, 7)) {
@@ -964,7 +966,7 @@ void Waiter1::handleServer(const SavePoint &savepoint, const char *name, EntityI
 	case kActionCallback:
 		if (getCallback() == 1) {
 			// Prepare or draw sequences depending of value of string
-			if (strcmp(name2, ""))
+			if (!strcmp(name2, ""))
 				getEntities()->clearSequences(kEntityWaiter1);
 			else
 				getEntities()->drawSequenceLeft(kEntityWaiter1, name2);
diff --git a/engines/lastexpress/entities/waiter2.cpp b/engines/lastexpress/entities/waiter2.cpp
index 52a48a7..2be7b4e 100644
--- a/engines/lastexpress/entities/waiter2.cpp
+++ b/engines/lastexpress/entities/waiter2.cpp
@@ -33,12 +33,12 @@
 namespace LastExpress {
 
 Waiter2::Waiter2(LastExpressEngine *engine) : Entity(engine, kEntityWaiter2) {
-	ADD_CALLBACK_FUNCTION(Waiter2, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Waiter2, draw);
-	ADD_CALLBACK_FUNCTION(Waiter2, updatePosition);
+	ADD_CALLBACK_FUNCTION_I(Waiter2, updateFromTime);
+	ADD_CALLBACK_FUNCTION_S(Waiter2, draw);
+	ADD_CALLBACK_FUNCTION_SII(Waiter2, updatePosition);
 	ADD_CALLBACK_FUNCTION(Waiter2, callbackActionOnDirection);
-	ADD_CALLBACK_FUNCTION(Waiter2, callSavepoint);
-	ADD_CALLBACK_FUNCTION(Waiter2, playSound);
+	ADD_CALLBACK_FUNCTION_SIIS(Waiter2, callSavepoint);
+	ADD_CALLBACK_FUNCTION_S(Waiter2, playSound);
 	ADD_CALLBACK_FUNCTION(Waiter2, monsieurServeUs);
 	ADD_CALLBACK_FUNCTION(Waiter2, chapter1);
 	ADD_CALLBACK_FUNCTION(Waiter2, milosOrder);
@@ -260,7 +260,7 @@ IMPLEMENT_FUNCTION(10, Waiter2, monsieurOrder)
 		case 3:
 			getEntities()->clearSequences(kEntityWaiter2);
 			getData()->entityPosition = kPosition_5900;
-			ENTITY_PARAM(0, 2) = 0;
+			ENTITY_PARAM(1, 2) = 0;
 
 			callbackAction();
 			break;
@@ -290,7 +290,7 @@ switch (savepoint.action) {
 	default:
 		break;
 
-	case kActionDefault:
+	case kActionNone:
 		if (!getEntities()->isInKitchen(kEntityWaiter2) || !getEntities()->isSomebodyInsideRestaurantOrSalon())
 			break;
 
@@ -524,7 +524,7 @@ IMPLEMENT_FUNCTION_END
 
 //////////////////////////////////////////////////////////////////////////
 IMPLEMENT_FUNCTION(24, Waiter2, annaBringTea3)
-	serveSalon(savepoint, "927", "Ann3143A", kEntityAnna, "Ann31444", "112C", kAction122288808, "928", &ENTITY_PARAM(1, 1));
+	serveSalon(savepoint, "927", "Ann3143A", kEntityAnna, "Ann3144", "112C", kAction122288808, "928", &ENTITY_PARAM(1, 1));
 IMPLEMENT_FUNCTION_END
 
 //////////////////////////////////////////////////////////////////////////
@@ -562,7 +562,7 @@ IMPLEMENT_FUNCTION(26, Waiter2, serving4)
 		break;
 
 	case kActionNone:
-		if (params->param2) {
+		if (params->param1) {
 			if (Entity::updateParameter(params->param2, getState()->time, 900)) {
 				ENTITY_PARAM(1, 5) = 1;
 				params->param1 = 0;
@@ -740,7 +740,7 @@ void Waiter2::serveSalon(const SavePoint &savepoint, const char *seq1, const cha
 			if (getEntities()->isInRestaurant(kEntityPlayer))
 				getEntities()->updateFrame(kEntityWaiter2);
 
-			if (!strcmp(snd1, ""))
+			if (strcmp(snd1, ""))
 				getSound()->playSound(kEntityWaiter2, snd1);
 
 			setCallback(2);
@@ -753,7 +753,9 @@ void Waiter2::serveSalon(const SavePoint &savepoint, const char *seq1, const cha
 			getSound()->playSound(kEntityWaiter2, snd2);
 
 			setCallback(3);
-			setup_updatePosition(seq2, kCarRestaurant, 57);
+			// the last arg is actually a constant varying between calls,
+			// but this function already has too many args to add yet another one
+			setup_updatePosition(seq2, kCarRestaurant, strcmp(seq2, "127D") ? 57 : 56);
 			break;
 
 		case 3:
diff --git a/engines/lastexpress/entities/yasmin.cpp b/engines/lastexpress/entities/yasmin.cpp
index 971799f..45837e7 100644
--- a/engines/lastexpress/entities/yasmin.cpp
+++ b/engines/lastexpress/entities/yasmin.cpp
@@ -28,6 +28,7 @@
 #include "lastexpress/game/savepoint.h"
 #include "lastexpress/game/state.h"
 
+#include "lastexpress/sound/queue.h"
 
 #include "lastexpress/lastexpress.h"
 
@@ -35,10 +36,10 @@ namespace LastExpress {
 
 Yasmin::Yasmin(LastExpressEngine *engine) : Entity(engine, kEntityYasmin) {
 	ADD_CALLBACK_FUNCTION(Yasmin, reset);
-	ADD_CALLBACK_FUNCTION(Yasmin, enterExitCompartment);
-	ADD_CALLBACK_FUNCTION(Yasmin, playSound);
-	ADD_CALLBACK_FUNCTION(Yasmin, updateFromTime);
-	ADD_CALLBACK_FUNCTION(Yasmin, updateEntity);
+	ADD_CALLBACK_FUNCTION_SI(Yasmin, enterExitCompartment);
+	ADD_CALLBACK_FUNCTION_S(Yasmin, playSound);
+	ADD_CALLBACK_FUNCTION_I(Yasmin, updateFromTime);
+	ADD_CALLBACK_FUNCTION_II(Yasmin, updateEntity);
 	ADD_CALLBACK_FUNCTION(Yasmin, goEtoG);
 	ADD_CALLBACK_FUNCTION(Yasmin, goGtoE);
 	ADD_CALLBACK_FUNCTION(Yasmin, chapter1);
@@ -492,19 +493,46 @@ IMPLEMENT_FUNCTION(21, Yasmin, hiding)
 		break;
 
 	case kActionNone:
+		if (!getSoundQueue()->isBuffered(kEntityYasmin)) {
+			if (Entity::updateParameter(params->param1, getState()->timeTicks, 450)) {
+				getSound()->playSound(kEntityYasmin, "Har5001");
+				params->param1 = 0;
+			}
+		}
+		break;
+
 	case kActionDefault:
-		if (getEntities()->updateEntity(kEntityYasmin, (CarIndex)params->param1, (EntityPosition)params->param2))
-			callbackAction();
+		setCallback(1);
+		setup_updateEntity(kCarGreenSleeping, kPosition_4840);
 		break;
 
-	case kActionExcuseMeCath:
-		getSound()->excuseMeCath();
+	case kActionCallback:
+		switch (getCallback()) {
+		default:
+			break;
+
+		case 1:
+			setCallback(2);
+			setup_enterExitCompartment("615BE", kObjectCompartment5);
+			break;
+
+		case 2:
+			getEntities()->clearSequences(kEntityYasmin);
+			getData()->location = kLocationInsideCompartment;
+			getData()->entityPosition = kPosition_3050;
+			getObjects()->update(kObjectCompartment7, kEntityPlayer, kObjectLocation1, kCursorHandKnock, kCursorHand);
+			getSound()->playSound(kEntityYasmin, "Har5001");
+			break;
+		}
 		break;
 
-	case kActionExcuseMe:
-		getSound()->excuseMe(kEntityYasmin);
+	case kAction135800432:
+		setup_nullfunction();
 		break;
 	}
 IMPLEMENT_FUNCTION_END
 
+//////////////////////////////////////////////////////////////////////////
+IMPLEMENT_NULL_FUNCTION(22, Yasmin)
+
 } // End of namespace LastExpress
diff --git a/engines/lastexpress/game/entities.cpp b/engines/lastexpress/game/entities.cpp
index b881d34..1afebbb 100644
--- a/engines/lastexpress/game/entities.cpp
+++ b/engines/lastexpress/game/entities.cpp
@@ -241,7 +241,7 @@ int Entities::getCompartments1(int index) const {
 // Savegame
 //////////////////////////////////////////////////////////////////////////
 void Entities::saveLoadWithSerializer(Common::Serializer &s) {
-	_header->saveLoadWithSerializer(s);
+	_header->saveLoadWithSerializer(s, NULL);
 	for (uint i = 1; i < _entities.size(); i++)
 		_entities[i]->saveLoadWithSerializer(s);
 }
@@ -1931,7 +1931,7 @@ void Entities::loadSceneFromEntityPosition(CarIndex car, EntityPosition entityPo
 	// Determine position
 	Position position = (alternate ? 1 : 40);
 	do {
-		if (entityPosition > entityPositions[position]) {
+		if (alternate ? entityPosition < entityPositions[position] : entityPosition > entityPositions[position]) {
 			if (alternate)
 				break;
 
@@ -1945,7 +1945,7 @@ void Entities::loadSceneFromEntityPosition(CarIndex car, EntityPosition entityPo
 	} while (alternate ? position <= 18 : position >= 22);
 
 	// For position outside bounds, use minimal value
-	if ((alternate && position > 18) || (alternate && position < 22)) {
+	if ((alternate && position > 18) || (!alternate && position < 22)) {
 		getScenes()->loadSceneFromPosition(car, alternate ? 18 : 22);
 		return;
 	}
@@ -2117,7 +2117,7 @@ label_process_entity:
 
 				if (checkDistanceFromPosition(entity, kPosition_1500, 750) && entity != kEntityFrancois) {
 
-					if (data->entity != kEntityPlayer) {
+					if (data->entity == kEntityPlayer) {
 						if (data->direction != kDirectionUp || (position <= kPosition_2000 && data->car == car)) {
 							if (data->direction == kDirectionDown && (position < kPosition_1500 || data->car != car)) {
 								if (data->entityPosition > kPosition_1500 && (data->car == kCarGreenSleeping || data->car == kCarRedSleeping)) {
@@ -2282,8 +2282,8 @@ label_process_entity:
 							}
 						}
 					}
-					return false;
 				}
+				return false;
 			}
 		} else if (!flag1) {
 			drawSequences(entity, direction, true);
diff --git a/engines/lastexpress/game/savegame.cpp b/engines/lastexpress/game/savegame.cpp
index e2682ba..ce53e6e 100644
--- a/engines/lastexpress/game/savegame.cpp
+++ b/engines/lastexpress/game/savegame.cpp
@@ -802,7 +802,7 @@ void SaveLoad::readEntry(SavegameType *type, EntityIndex *entity, uint32 *val, b
 	// Skip padding
 	uint32 offset = (uint32)_savegame->pos() - originalPosition;
 	if (offset & 0xF) {
-		_savegame->seek((~offset & 0xF) + 1, SEEK_SET);
+		_savegame->seek((~offset & 0xF) + 1, SEEK_CUR);
 	}
 }
 
diff --git a/engines/lastexpress/game/savepoint.cpp b/engines/lastexpress/game/savepoint.cpp
index a8483e6..bd134c6 100644
--- a/engines/lastexpress/game/savepoint.cpp
+++ b/engines/lastexpress/game/savepoint.cpp
@@ -162,8 +162,8 @@ void SavePoints::call(EntityIndex entity2, EntityIndex entity1, ActionIndex acti
 	point.action = action;
 	point.entity2 = entity2;
 
-	assert(param.size() <= 5);
-	strncpy((char *)&point.param.charValue, param.c_str(), 5);
+	assert(param.size() <= 6); // "MUS%03d"
+	strncpy((char *)&point.param.charValue, param.c_str(), 6);
 
 	Callback *callback = getCallback(entity1);
 	if (callback != NULL && callback->isValid()) {
@@ -230,6 +230,8 @@ bool SavePoints::updateEntityFromData(const SavePoint &savepoint) {
 void SavePoints::saveLoadWithSerializer(Common::Serializer &s) {
 
 	// Serialize savepoint data
+	if (s.isLoading())
+		_data.clear();
 	uint32 dataSize = (s.isLoading() ? _savePointsMaxSize : _data.size());
 	for (uint i = 0; i < dataSize; i++) {
 		if (s.isLoading()) {
diff --git a/engines/lastexpress/game/savepoint.h b/engines/lastexpress/game/savepoint.h
index ab64907..ea73e7c 100644
--- a/engines/lastexpress/game/savepoint.h
+++ b/engines/lastexpress/game/savepoint.h
@@ -58,7 +58,7 @@ struct SavePoint {
 	EntityIndex entity2;
 	union {
 		uint32 intValue;
-		char charValue[5];
+		char charValue[7]; // "MUS%03d" with terminating zero
 	} param;
 
 	SavePoint() {
@@ -66,6 +66,7 @@ struct SavePoint {
 		action = kActionNone;
 		entity2 = kEntityPlayer;
 		param.intValue = 0;
+		param.charValue[6] = 0;
 	}
 
 	Common::String toString() {
diff --git a/engines/lastexpress/game/state.h b/engines/lastexpress/game/state.h
index 38cd851..b46807b 100644
--- a/engines/lastexpress/game/state.h
+++ b/engines/lastexpress/game/state.h
@@ -313,13 +313,14 @@ public:
 		 * @return true if equal, false if not.
 		 */
 		bool isEqual(uint index, uint val) {
-			return getValueName(index) == val;
+			return getOrSetValueName(index) == val;
 		}
 
-		uint32 getValueName(uint index, Common::String *name = NULL) {
-			#define EXPOSE_VALUE(idx, entryName) \
+		uint32 getOrSetValueName(uint index, Common::String *name = NULL, const uint32* newValue = NULL) {
+			#define EXPOSE_VALUE(idx, entryName, fieldType) \
 				case idx: { \
 					if (name) (*name) = "" #entryName; \
+					if (newValue) {entryName = (fieldType)*newValue;} \
 					return (uint32)entryName; \
 				}
 
@@ -328,134 +329,134 @@ public:
 				error("[GameProgress::getValueName] Invalid index value (was: %d, max:127)", index);
 				break;
 
-			EXPOSE_VALUE(0, field_0);
-			EXPOSE_VALUE(1, jacket);
-			EXPOSE_VALUE(2, eventCorpseMovedFromFloor);
-			EXPOSE_VALUE(3, field_C);
-			EXPOSE_VALUE(4, eventCorpseFound);
-			EXPOSE_VALUE(5, field_14);
-			EXPOSE_VALUE(6, field_18);
-			EXPOSE_VALUE(7, portrait);
-			EXPOSE_VALUE(8, eventCorpseThrown);
-			EXPOSE_VALUE(9, field_24);
-			EXPOSE_VALUE(10, field_28);
-			EXPOSE_VALUE(11, chapter);
-			EXPOSE_VALUE(12, field_30);
-			EXPOSE_VALUE(13, eventMetAugust);
-			EXPOSE_VALUE(14, isNightTime);
-			EXPOSE_VALUE(15, field_3C);
-			EXPOSE_VALUE(16, field_40);
-			EXPOSE_VALUE(17, field_44);
-			EXPOSE_VALUE(18, field_48);
-			EXPOSE_VALUE(19, field_4C);
-			EXPOSE_VALUE(20, isTrainRunning);
-			EXPOSE_VALUE(21, field_54);
-			EXPOSE_VALUE(22, field_58);
-			EXPOSE_VALUE(23, field_5C);
-			EXPOSE_VALUE(24, field_60);
-			EXPOSE_VALUE(25, field_64);
-			EXPOSE_VALUE(26, field_68);
-			EXPOSE_VALUE(27, eventMertensAugustWaiting);
-			EXPOSE_VALUE(28, eventMertensKronosInvitation);
-			EXPOSE_VALUE(29, isEggOpen);
-			EXPOSE_VALUE(30, field_78);
-			EXPOSE_VALUE(31, field_7C);
-			EXPOSE_VALUE(32, field_80);
-			EXPOSE_VALUE(33, field_84);
-			EXPOSE_VALUE(34, field_88);
-			EXPOSE_VALUE(35, field_8C);
-			EXPOSE_VALUE(36, field_90);
-			EXPOSE_VALUE(37, field_94);
-			EXPOSE_VALUE(38, field_98);
-			EXPOSE_VALUE(39, field_9C);
-			EXPOSE_VALUE(40, field_A0);
-			EXPOSE_VALUE(41, field_A4);
-			EXPOSE_VALUE(42, field_A8);
-			EXPOSE_VALUE(43, field_AC);
-			EXPOSE_VALUE(44, field_B0);
-			EXPOSE_VALUE(45, field_B4);
-			EXPOSE_VALUE(46, field_B8);
-			EXPOSE_VALUE(47, field_BC);
-			EXPOSE_VALUE(48, field_C0);
-			EXPOSE_VALUE(49, field_C4);
-			EXPOSE_VALUE(50, field_C8);
-			EXPOSE_VALUE(51, field_CC);
-			EXPOSE_VALUE(52, eventMetBoutarel);
-			EXPOSE_VALUE(53, eventMetHadija);
-			EXPOSE_VALUE(54, eventMetYasmin);
-			EXPOSE_VALUE(55, field_DC);
-			EXPOSE_VALUE(56, field_E0);
-			EXPOSE_VALUE(57, field_E4);
-			EXPOSE_VALUE(58, field_E8);
-			EXPOSE_VALUE(59, field_EC);
-			EXPOSE_VALUE(60, field_F0);
-			EXPOSE_VALUE(61, field_F4);
-			EXPOSE_VALUE(62, field_F8);
-			EXPOSE_VALUE(63, field_FC);
-			EXPOSE_VALUE(64, field_100);
-			EXPOSE_VALUE(65, field_104);
-			EXPOSE_VALUE(66, field_108);
-			EXPOSE_VALUE(67, field_10C);
-			EXPOSE_VALUE(68, field_110);
-			EXPOSE_VALUE(69, field_114);
-			EXPOSE_VALUE(70, field_118);
-			EXPOSE_VALUE(71, field_11C);
-			EXPOSE_VALUE(72, field_120);
-			EXPOSE_VALUE(73, field_124);
-			EXPOSE_VALUE(74, field_128);
-			EXPOSE_VALUE(75, field_12C);
-			EXPOSE_VALUE(76, field_130);
-			EXPOSE_VALUE(77, field_134);
-			EXPOSE_VALUE(78, field_138);
-			EXPOSE_VALUE(79, field_13C);
-			EXPOSE_VALUE(80, field_140);
-			EXPOSE_VALUE(81, field_144);
-			EXPOSE_VALUE(82, field_148);
-			EXPOSE_VALUE(83, field_14C);
-			EXPOSE_VALUE(84, field_150);
-			EXPOSE_VALUE(85, field_154);
-			EXPOSE_VALUE(86, field_158);
-			EXPOSE_VALUE(87, field_15C);
-			EXPOSE_VALUE(88, field_160);
-			EXPOSE_VALUE(89, field_164);
-			EXPOSE_VALUE(90, field_168);
-			EXPOSE_VALUE(91, field_16C);
-			EXPOSE_VALUE(92, field_170);
-			EXPOSE_VALUE(93, field_174);
-			EXPOSE_VALUE(94, field_178);
-			EXPOSE_VALUE(95, field_17C);
-			EXPOSE_VALUE(96, field_180);
-			EXPOSE_VALUE(97, field_184);
-			EXPOSE_VALUE(98, field_188);
-			EXPOSE_VALUE(99, field_18C);
-			EXPOSE_VALUE(100, field_190);
-			EXPOSE_VALUE(101, field_194);
-			EXPOSE_VALUE(102, field_198);
-			EXPOSE_VALUE(103, field_19C);
-			EXPOSE_VALUE(104, field_1A0);
-			EXPOSE_VALUE(105, field_1A4);
-			EXPOSE_VALUE(106, field_1A8);
-			EXPOSE_VALUE(107, field_1AC);
-			EXPOSE_VALUE(108, field_1B0);
-			EXPOSE_VALUE(109, field_1B4);
-			EXPOSE_VALUE(110, field_1B8);
-			EXPOSE_VALUE(111, field_1BC);
-			EXPOSE_VALUE(112, field_1C0);
-			EXPOSE_VALUE(113, field_1C4);
-			EXPOSE_VALUE(114, field_1C8);
-			EXPOSE_VALUE(115, field_1CC);
-			EXPOSE_VALUE(116, field_1D0);
-			EXPOSE_VALUE(117, field_1D4);
-			EXPOSE_VALUE(118, field_1D8);
-			EXPOSE_VALUE(119, field_1DC);
-			EXPOSE_VALUE(120, field_1E0);
-			EXPOSE_VALUE(121, field_1E4);
-			EXPOSE_VALUE(122, field_1E8);
-			EXPOSE_VALUE(123, field_1EC);
-			EXPOSE_VALUE(124, field_1F0);
-			EXPOSE_VALUE(125, field_1F4);
-			EXPOSE_VALUE(126, field_1F8);
-			EXPOSE_VALUE(127, field_1FC);
+			EXPOSE_VALUE(0, field_0, uint32);
+			EXPOSE_VALUE(1, jacket, JacketType);
+			EXPOSE_VALUE(2, eventCorpseMovedFromFloor, bool);
+			EXPOSE_VALUE(3, field_C, uint32);
+			EXPOSE_VALUE(4, eventCorpseFound, bool);
+			EXPOSE_VALUE(5, field_14, uint32);
+			EXPOSE_VALUE(6, field_18, uint32);
+			EXPOSE_VALUE(7, portrait, uint32);
+			EXPOSE_VALUE(8, eventCorpseThrown, bool);
+			EXPOSE_VALUE(9, field_24, uint32);
+			EXPOSE_VALUE(10, field_28, uint32);
+			EXPOSE_VALUE(11, chapter, ChapterIndex);
+			EXPOSE_VALUE(12, field_30, uint32);
+			EXPOSE_VALUE(13, eventMetAugust, bool);
+			EXPOSE_VALUE(14, isNightTime, bool);
+			EXPOSE_VALUE(15, field_3C, uint32);
+			EXPOSE_VALUE(16, field_40, uint32);
+			EXPOSE_VALUE(17, field_44, uint32);
+			EXPOSE_VALUE(18, field_48, uint32);
+			EXPOSE_VALUE(19, field_4C, uint32);
+			EXPOSE_VALUE(20, isTrainRunning, bool);
+			EXPOSE_VALUE(21, field_54, uint32);
+			EXPOSE_VALUE(22, field_58, uint32);
+			EXPOSE_VALUE(23, field_5C, uint32);
+			EXPOSE_VALUE(24, field_60, uint32);
+			EXPOSE_VALUE(25, field_64, uint32);
+			EXPOSE_VALUE(26, field_68, uint32);
+			EXPOSE_VALUE(27, eventMertensAugustWaiting, bool);
+			EXPOSE_VALUE(28, eventMertensKronosInvitation, bool);
+			EXPOSE_VALUE(29, isEggOpen, bool);
+			EXPOSE_VALUE(30, field_78, uint32);
+			EXPOSE_VALUE(31, field_7C, uint32);
+			EXPOSE_VALUE(32, field_80, uint32);
+			EXPOSE_VALUE(33, field_84, uint32);
+			EXPOSE_VALUE(34, field_88, uint32);
+			EXPOSE_VALUE(35, field_8C, uint32);
+			EXPOSE_VALUE(36, field_90, uint32);
+			EXPOSE_VALUE(37, field_94, uint32);
+			EXPOSE_VALUE(38, field_98, uint32);
+			EXPOSE_VALUE(39, field_9C, uint32);
+			EXPOSE_VALUE(40, field_A0, uint32);
+			EXPOSE_VALUE(41, field_A4, uint32);
+			EXPOSE_VALUE(42, field_A8, uint32);
+			EXPOSE_VALUE(43, field_AC, uint32);
+			EXPOSE_VALUE(44, field_B0, uint32);
+			EXPOSE_VALUE(45, field_B4, uint32);
+			EXPOSE_VALUE(46, field_B8, uint32);
+			EXPOSE_VALUE(47, field_BC, uint32);
+			EXPOSE_VALUE(48, field_C0, uint32);
+			EXPOSE_VALUE(49, field_C4, uint32);
+			EXPOSE_VALUE(50, field_C8, uint32);
+			EXPOSE_VALUE(51, field_CC, uint32);
+			EXPOSE_VALUE(52, eventMetBoutarel, bool);
+			EXPOSE_VALUE(53, eventMetHadija, bool);
+			EXPOSE_VALUE(54, eventMetYasmin, bool);
+			EXPOSE_VALUE(55, field_DC, uint32);
+			EXPOSE_VALUE(56, field_E0, uint32);
+			EXPOSE_VALUE(57, field_E4, uint32);
+			EXPOSE_VALUE(58, field_E8, uint32);
+			EXPOSE_VALUE(59, field_EC, uint32);
+			EXPOSE_VALUE(60, field_F0, uint32);
+			EXPOSE_VALUE(61, field_F4, uint32);
+			EXPOSE_VALUE(62, field_F8, uint32);
+			EXPOSE_VALUE(63, field_FC, uint32);
+			EXPOSE_VALUE(64, field_100, uint32);
+			EXPOSE_VALUE(65, field_104, uint32);
+			EXPOSE_VALUE(66, field_108, uint32);
+			EXPOSE_VALUE(67, field_10C, uint32);
+			EXPOSE_VALUE(68, field_110, uint32);
+			EXPOSE_VALUE(69, field_114, uint32);
+			EXPOSE_VALUE(70, field_118, uint32);
+			EXPOSE_VALUE(71, field_11C, uint32);
+			EXPOSE_VALUE(72, field_120, uint32);
+			EXPOSE_VALUE(73, field_124, uint32);
+			EXPOSE_VALUE(74, field_128, uint32);
+			EXPOSE_VALUE(75, field_12C, uint32);
+			EXPOSE_VALUE(76, field_130, uint32);
+			EXPOSE_VALUE(77, field_134, uint32);
+			EXPOSE_VALUE(78, field_138, uint32);
+			EXPOSE_VALUE(79, field_13C, uint32);
+			EXPOSE_VALUE(80, field_140, uint32);
+			EXPOSE_VALUE(81, field_144, uint32);
+			EXPOSE_VALUE(82, field_148, uint32);
+			EXPOSE_VALUE(83, field_14C, uint32);
+			EXPOSE_VALUE(84, field_150, uint32);
+			EXPOSE_VALUE(85, field_154, uint32);
+			EXPOSE_VALUE(86, field_158, uint32);
+			EXPOSE_VALUE(87, field_15C, uint32);
+			EXPOSE_VALUE(88, field_160, uint32);
+			EXPOSE_VALUE(89, field_164, uint32);
+			EXPOSE_VALUE(90, field_168, uint32);
+			EXPOSE_VALUE(91, field_16C, uint32);
+			EXPOSE_VALUE(92, field_170, uint32);
+			EXPOSE_VALUE(93, field_174, uint32);
+			EXPOSE_VALUE(94, field_178, uint32);
+			EXPOSE_VALUE(95, field_17C, uint32);
+			EXPOSE_VALUE(96, field_180, uint32);
+			EXPOSE_VALUE(97, field_184, uint32);
+			EXPOSE_VALUE(98, field_188, uint32);
+			EXPOSE_VALUE(99, field_18C, uint32);
+			EXPOSE_VALUE(100, field_190, uint32);
+			EXPOSE_VALUE(101, field_194, uint32);
+			EXPOSE_VALUE(102, field_198, uint32);
+			EXPOSE_VALUE(103, field_19C, uint32);
+			EXPOSE_VALUE(104, field_1A0, uint32);
+			EXPOSE_VALUE(105, field_1A4, uint32);
+			EXPOSE_VALUE(106, field_1A8, uint32);
+			EXPOSE_VALUE(107, field_1AC, uint32);
+			EXPOSE_VALUE(108, field_1B0, uint32);
+			EXPOSE_VALUE(109, field_1B4, uint32);
+			EXPOSE_VALUE(110, field_1B8, uint32);
+			EXPOSE_VALUE(111, field_1BC, uint32);
+			EXPOSE_VALUE(112, field_1C0, uint32);
+			EXPOSE_VALUE(113, field_1C4, uint32);
+			EXPOSE_VALUE(114, field_1C8, uint32);
+			EXPOSE_VALUE(115, field_1CC, uint32);
+			EXPOSE_VALUE(116, field_1D0, uint32);
+			EXPOSE_VALUE(117, field_1D4, uint32);
+			EXPOSE_VALUE(118, field_1D8, uint32);
+			EXPOSE_VALUE(119, field_1DC, uint32);
+			EXPOSE_VALUE(120, field_1E0, uint32);
+			EXPOSE_VALUE(121, field_1E4, uint32);
+			EXPOSE_VALUE(122, field_1E8, uint32);
+			EXPOSE_VALUE(123, field_1EC, uint32);
+			EXPOSE_VALUE(124, field_1F0, uint32);
+			EXPOSE_VALUE(125, field_1F4, uint32);
+			EXPOSE_VALUE(126, field_1F8, uint32);
+			EXPOSE_VALUE(127, field_1FC, uint32);
 			}
 		}
 
@@ -464,7 +465,7 @@ public:
 
 			for (uint i = 0; i < 128; i++) {
 				Common::String name = "";
-				uint val = getValueName(i, &name);
+				uint val = getOrSetValueName(i, &name, NULL);
 				ret += Common::String::format("(%03d) %s = %d\n", i, name.c_str(), val);
 			}
 
@@ -472,9 +473,17 @@ public:
 		}
 
 		void saveLoadWithSerializer(Common::Serializer &s) {
-			for (uint i = 0; i < 128; i++) {
-				uint32 val = getValueName(i);
-				s.syncAsUint32LE(val);
+			if (s.isLoading()) {
+				for (uint i = 0; i < 128; i++) {
+					uint32 val;
+					s.syncAsUint32LE(val);
+					getOrSetValueName(i, NULL, &val);
+				}
+			} else {
+				for (uint i = 0; i < 128; i++) {
+					uint32 val = getOrSetValueName(i);
+					s.syncAsUint32LE(val);
+				}
 			}
 		}
 	};
diff --git a/engines/lastexpress/shared.h b/engines/lastexpress/shared.h
index 724c4b3..1b703ac 100644
--- a/engines/lastexpress/shared.h
+++ b/engines/lastexpress/shared.h
@@ -274,6 +274,7 @@ enum TimeValue {
 	kTime2097000              = 2097000,	// Day 2, 14:50
 	kTimeEnterLinz            = 2099700,	// Day 2, 14:53
 	kTimeCityLinz             = 2101500,	// Day 2, 14:55
+	kTimeExitLinz             = 2105100,    // Day 2, 14:59
 	kTime2106000              = 2106000,	// Day 2, 15:00
 	kTime2110500              = 2110500,	// Day 2, 15:05
 	kTime2115000              = 2115000,	// Day 2, 15:10
@@ -373,14 +374,18 @@ enum TimeValue {
 	kTimeTrainStopped         = 2898000,	// Day 3, 05:40
 	kTime2907000              = 2907000,	// Day 3, 05:50
 	kTime2916000              = 2916000,	// Day 3, 06:00
-	kTimeCityBelgrade         = 2952000,	// Day 3, 06:40
+	kTime2934000              = 2934000,    // Day 3, 06:20
 	kTimeTrainStopped2        = 2943000,	// Day 3, 06:30
+	kTime2949300              = 2949300,    // Day 3, 06:37
+	kTimeCityBelgrade         = 2952000,	// Day 3, 06:40
 	kTime2983500              = 2983500,	// Day 3, 07:15
 	kTimeCityNish             = 3205800,	// Day 3, 11:22
 	kTimeCityTzaribrod        = 3492000,	// Day 3, 16:40
 	kTime3645000              = 3645000,	// Day 3, 19:30
 	kTimeCitySofia            = 3690000,	// Day 3, 20:20
 	kTimeCityAdrianople       = 4320900,	// Day 4, 08:01
+	kTime4914000              = 4914000,    // Day 4, 19:00
+	kTime4920300              = 4920300,    // Day 4, 19:07
 	kTime4923000              = 4923000,	// Day 4, 19:10
 	kTime4929300              = 4929300,	// Day 4, 19:17
 	kTimeCityConstantinople   = 4941000,	// Day 4, 19:30
@@ -1193,8 +1198,8 @@ enum EventIndex {
 	kEventVergesSuitcaseNightOtherEntryStart = 137,
 	kEventMertensAskTylerCompartment = 138,
 	kEventMertensAskTylerCompartmentD = 139,
-	kEventMertensPushCall = 140,
-	kEventMertensPushCallNight = 141,
+	kEventMertensPushCallNight = 140,
+	kEventMertensPushCall = 141,
 	kEventMertensAugustWaiting = 142,
 	kEventMertensAugustWaitingCompartment = 143,
 	kEventIntroBroderbrund = 144,
@@ -1232,8 +1237,8 @@ enum EventIndex {
 	kEventCathSalkoTrainTopWin = 176,
 	kEventFrancoisWhistle = 177,
 	kEventFrancoisWhistleD = 178,
-	kEventFrancoisWhistleNight = 179,
-	kEventFrancoisWhistleNightD = 180,
+	kEventFrancoisWhistleNightD = 179,
+	kEventFrancoisWhistleNight = 180,
 	kEventFrancoisShowBeetle = 181,
 	kEventFrancoisShowBeetleD = 182,
 	kEventFrancoisTradeWhistle = 183,
diff --git a/engines/lastexpress/sound/entry.cpp b/engines/lastexpress/sound/entry.cpp
index 7308214..87ecd26 100644
--- a/engines/lastexpress/sound/entry.cpp
+++ b/engines/lastexpress/sound/entry.cpp
@@ -93,7 +93,7 @@ void SoundEntry::close() {
 	_status.status |= kSoundStatusClosed;
 
 	// Loop until ready
-	//while (!(_status.status1 & 4) && !(getSoundQueue()->getFlag() & 8) && (getSoundQueue()->getFlag() & 1))
+	//while (!(_status.b.status1 & 4) && !(getSoundQueue()->getFlag() & 8) && (getSoundQueue()->getFlag() & 1))
 	//	;	// empty loop body
 
 	// The original game remove the entry from the cache here,
@@ -246,7 +246,7 @@ void SoundEntry::loadStream(Common::String name) {
 }
 
 void SoundEntry::update(uint val) {
-	if (!(_status.status3 & 64)) {
+	if (!(_status.b.status3 & 64)) {
 		int value2 = val;
 
 		_status.status |= kSoundStatus_100000;
@@ -271,10 +271,10 @@ bool SoundEntry::updateSound() {
 	bool result;
 	char sub[16];
 
-	if (_status.status2 & 4) {
+	if (_status.b.status2 & 4) {
 		result = false;
 	} else {
-		if (_status.status2 & 0x80) {
+		if (_status.b.status2 & 0x80) {
 			if (_field_48 <= getSound()->getData2()) {
 				_status.status |= 0x20;
 				_status.status &= ~0x8000;
@@ -288,7 +288,7 @@ bool SoundEntry::updateSound() {
 			}
 		} else {
 			if (!(getSoundQueue()->getFlag() & 0x20)) {
-				if (!(_status.status3 & 8)) {
+				if (!(_status.b.status3 & 8)) {
 					if (_entity) {
 						if (_entity < 0x80) {
 							updateEntryFlag(getSound()->getSoundFlag(_entity));
@@ -296,7 +296,7 @@ bool SoundEntry::updateSound() {
 					}
 				}
 			}
-			//if (status.status2 & 0x40 && !((uint32)_status.status & 0x180) && v1->soundBuffer)
+			//if (status.b.status2 & 0x40 && !((uint32)_status.status & 0x180) && v1->soundBuffer)
 			//	Sound_FillSoundBuffer(v1);
 		}
 		result = true;
@@ -354,7 +354,7 @@ void SoundEntry::showSubtitle(Common::String filename) {
 	_subtitle = new SubtitleEntry(_engine);
 	_subtitle->load(filename, this);
 
-	if (_subtitle->getStatus().status2 & 4) {
+	if (_subtitle->getStatus().b.status2 & 4) {
 		_subtitle->draw();
 		SAFE_DELETE(_subtitle);
 	} else {
diff --git a/engines/lastexpress/sound/entry.h b/engines/lastexpress/sound/entry.h
index d92b16a..0ebe550 100644
--- a/engines/lastexpress/sound/entry.h
+++ b/engines/lastexpress/sound/entry.h
@@ -76,12 +76,15 @@ namespace LastExpress {
 class LastExpressEngine;
 class SubtitleEntry;
 
+// TODO: this union assumes little-endian machine
 union SoundStatusUnion {
 	uint32 status;
-	byte status1;
-	byte status2;
-	byte status3;
-	byte status4;
+	struct {
+		byte status1;
+		byte status2;
+		byte status3;
+		byte status4;
+	} b;
 
 	SoundStatusUnion() {
 		status = 0;
diff --git a/engines/lastexpress/sound/queue.cpp b/engines/lastexpress/sound/queue.cpp
index fe6d6f2..a088da3 100644
--- a/engines/lastexpress/sound/queue.cpp
+++ b/engines/lastexpress/sound/queue.cpp
@@ -132,7 +132,7 @@ void SoundQueue::updateQueue() {
 		// and if the sound data buffer is not full, loads a new entry to be played based on
 		// its priority and filter id
 
-		if (!entry->updateSound() && !(entry->getStatus().status3 & 0x8)) {
+		if (!entry->updateSound() && !(entry->getStatus().b.status3 & 0x8)) {
 			entry->close();
 			SAFE_DELETE(entry);
 			it = _soundList.reverse_erase(it);
diff --git a/engines/lastexpress/sound/sound.cpp b/engines/lastexpress/sound/sound.cpp
index 3a2d0c0..ca79915 100644
--- a/engines/lastexpress/sound/sound.cpp
+++ b/engines/lastexpress/sound/sound.cpp
@@ -136,7 +136,7 @@ SoundManager::~SoundManager() {
 // Sound-related functions
 //////////////////////////////////////////////////////////////////////////
 void SoundManager::playSound(EntityIndex entity, Common::String filename, SoundFlag flag, byte a4) {
-	if (_queue->isBuffered(entity) && entity)
+	if (_queue->isBuffered(entity) && entity && entity < kEntityTrain)
 		_queue->removeFromQueue(entity);
 
 	SoundFlag currentFlag = (flag == -1) ? getSoundFlag(entity) : (SoundFlag)(flag | 0x80000);
@@ -372,6 +372,8 @@ void SoundManager::playLocomotiveSound() {
 }
 
 const char *SoundManager::getDialogName(EntityIndex entity) const {
+	if (_queue->isBuffered(kEntityTables4))
+		return NULL;
 	switch (entity) {
 	case kEntityAnna:
 		if (getEvent(kEventAnnaDialogGoToJerusalem))
@@ -558,7 +560,7 @@ const char *SoundManager::getDialogName(EntityIndex entity) const {
 			return "XKRO4";
 
 		if (getEvent(kEventKronosConversation)) {
-			if (!getEvent(kEventMilosCompartmentVisitAugust))
+			if (getEvent(kEventMilosCompartmentVisitAugust))
 				return "XKRO3";
 			else
 				return "XKRO2";
@@ -675,7 +677,7 @@ const char *SoundManager::getDialogName(EntityIndex entity) const {
 // Letters & Messages
 //////////////////////////////////////////////////////////////////////////
 void SoundManager::readText(int id) {
-	if (!_queue->isBuffered(kEntityTables4))
+	if (_queue->isBuffered(kEntityTables4))
 		return;
 
 	if (id < 0 || (id > 8 && id < 50) || id > 64)
@@ -840,9 +842,9 @@ void SoundManager::playWarningCompartment(EntityIndex entity, ObjectIndex compar
 			}
 
 			if (rnd(2) || getEntities()->isInsideCompartment(kEntityAnna, kCarRedSleeping, kPosition_4070))
-				getSound()->playSound(kEntityCoudert, "Jac1503", kFlagDefault);
-			else
 				getSound()->playSound(kEntityCoudert, "Jac1503A", kFlagDefault);
+			else
+				getSound()->playSound(kEntityCoudert, "Jac1503", kFlagDefault);
 			break;
 
 		case kObjectCompartmentG:
@@ -851,6 +853,10 @@ void SoundManager::playWarningCompartment(EntityIndex entity, ObjectIndex compar
 				break;
 			}
 
+			// BUG: the original game got isInsideCompartment() inverted
+			// Jac1502A is "the serbian gentleman is not in, monsier",
+			// Jac1502 is a generic response,
+			// so Coudert only says "Milos is not in" when Milos is actually in.
 			if (rnd(2) || getEntities()->isInsideCompartment(kEntityMilos, kCarRedSleeping, kPosition_3050))
 				getSound()->playSound(kEntityCoudert, "Jac1502", kFlagDefault);
 			else
@@ -922,7 +928,7 @@ void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, SoundFlag f
 		if (Entities::isFemale(entity2)) {
 			playSound(kEntityPlayer, (rnd(2) ? "CON1111" : "CON1111A"), flag);
 		} else {
-			if (entity2 || getProgress().jacket != kJacketGreen || !rnd(2)) {
+			if (entity2 != kEntityPlayer || getProgress().jacket != kJacketGreen || !rnd(2)) {
 				switch(rnd(3)) {
 				default:
 					break;
@@ -941,9 +947,9 @@ void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, SoundFlag f
 				}
 			} else {
 				if (isNight()) {
-					playSound(kEntityPlayer, (getProgress().field_18 == 2 ? "CON1110F" : "CON1110E"));
+					playSound(kEntityPlayer, (getProgress().field_18 == 2 ? "CON1110F" : "CON1110E"), flag);
 				} else {
-					playSound(kEntityPlayer, "CON1110D");
+					playSound(kEntityPlayer, "CON1110D", flag);
 				}
 			}
 		}
@@ -953,7 +959,7 @@ void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, SoundFlag f
 		if (Entities::isFemale(entity2)) {
 			playSound(kEntityPlayer, "JAC1111D", flag);
 		} else {
-			if (entity2 || getProgress().jacket != kJacketGreen || !rnd(2)) {
+			if (entity2 != kEntityPlayer || getProgress().jacket != kJacketGreen || !rnd(2)) {
 				switch(rnd(4)) {
 				default:
 					break;
@@ -981,7 +987,7 @@ void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, SoundFlag f
 		break;
 
 	case kEntityPascale:
-		playSound(kEntityPlayer, (rnd(2) ? "HDE1002" : "HED1002A"), flag);
+		playSound(kEntityPlayer, (rnd(2) ? "HED1002" : "HED1002A"), flag);
 		break;
 
 	case kEntityWaiter1:
@@ -1006,7 +1012,7 @@ void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, SoundFlag f
 
 	case kEntityVerges:
 		if (Entities::isFemale(entity2)) {
-			playSound(kEntityPlayer, (rnd(2) ? "TRA1113A" : "TRA1113B"));
+			playSound(kEntityPlayer, (rnd(2) ? "TRA1113A" : "TRA1113B"), flag);
 		} else {
 			playSound(kEntityPlayer, "TRA1112", flag);
 		}
@@ -1097,7 +1103,7 @@ void SoundManager::excuseMe(EntityIndex entity, EntityIndex entity2, SoundFlag f
 		break;
 
 	case kEntityRebecca:
-		playSound(kEntityPlayer, (rnd(2) ? "REB1106" : "REB110A"), flag);
+		playSound(kEntityPlayer, (rnd(2) ? "REB1106" : "Reb1106A"), flag);
 		break;
 
 	case kEntitySophie: {
@@ -1239,8 +1245,8 @@ SoundFlag SoundManager::getSoundFlag(EntityIndex entity) const {
 	if (index < 32)
 		ret = soundFlags[index];
 
-	if (getEntityData(entity)->location == kLocationOutsideTrain) {
-		if (getEntityData(entity)->car != kCarKronos
+	if (getEntityData(kEntityPlayer)->location == kLocationOutsideTrain) {
+		if (getEntityData(kEntityPlayer)->car != kCarKronos
 		&& !getEntities()->isOutsideAlexeiWindow()
 		&& !getEntities()->isOutsideAnnaWindow())
 			return kFlagNone;
@@ -1254,25 +1260,24 @@ SoundFlag SoundManager::getSoundFlag(EntityIndex entity) const {
 
 	case kCarKronos:
 		if (getEntities()->isInKronosSalon(entity) != getEntities()->isInKronosSalon(kEntityPlayer))
-			ret = (SoundFlag)(ret * 2);
+			ret = (SoundFlag)(ret / 2);
 		break;
 
 	case kCarGreenSleeping:
 	case kCarRedSleeping:
-		if (getEntities()->isInGreenCarEntrance(kEntityPlayer) && !getEntities()->isInKronosSalon(entity))
-			ret = (SoundFlag)(ret * 2);
+		if (getEntities()->isInGreenCarEntrance(kEntityPlayer) && !getEntities()->isInGreenCarEntrance(entity))
+			ret = (SoundFlag)(ret / 2);
 
-		if (getEntityData(kEntityPlayer)->location
-		&& (getEntityData(entity)->entityPosition != kPosition_1 || !getEntities()->isDistanceBetweenEntities(kEntityPlayer, entity, 400)))
-			ret = (SoundFlag)(ret * 2);
+		if (getEntityData(kEntityPlayer)->location == kLocationInsideCompartment
+		&& (getEntityData(entity)->location != kLocationInsideCompartment || !getEntities()->isDistanceBetweenEntities(kEntityPlayer, entity, 400)))
+			ret = (SoundFlag)(ret / 2);
 		break;
 
 	case kCarRestaurant:
-		if (getEntities()->isInSalon(entity) == getEntities()->isInSalon(kEntityPlayer)
-		&& (getEntities()->isInRestaurant(entity) != getEntities()->isInRestaurant(kEntityPlayer)))
-			ret = (SoundFlag)(ret * 2);
-		else
-			ret = (SoundFlag)(ret * 4);
+		if (getEntities()->isInSalon(entity) != getEntities()->isInSalon(kEntityPlayer))
+			ret = (SoundFlag)(ret / 4);
+		else if (getEntities()->isInRestaurant(entity) != getEntities()->isInRestaurant(kEntityPlayer))
+			ret = (SoundFlag)(ret / 2);
 		break;
 	}
 
@@ -1314,7 +1319,7 @@ void SoundManager::playLoopingSound(int param) {
 				partNumber = 6;
 			} else {
 				if (getEntities()->isInsideCompartments(kEntityPlayer)) {
-					int objNum = (getEntityData(kEntityPlayer)->car - 3) < 1 ? 9 : 40; // Weird numbers
+					int objNum = (getEntityData(kEntityPlayer)->car == kCarGreenSleeping) ? 9 : 40; // Weird numbers
 
 					numLoops[0] = 0;
 
@@ -1323,7 +1328,7 @@ void SoundManager::playLoopingSound(int param) {
 							break;
 						if (getEntities()->isInsideCompartment(kEntityPlayer, getEntityData(kEntityPlayer)->car, positions[pos])) {
 							numLoops[0] = 1;
-							partNumber = (getObjects()->get((ObjectIndex)objNum).status - 2) < 1 ? 6 : 1;
+							partNumber = (getObjects()->get((ObjectIndex)objNum).status == kObjectLocation2) ? 6 : 1;
 						}
 						objNum++;
 					}


Commit: 39ad93d738e46a3af8f7bd3c75bbb0ac6e058b11
    https://github.com/scummvm/scummvm/commit/39ad93d738e46a3af8f7bd3c75bbb0ac6e058b11
Author: Evgeny Grechnikov (diamondaz at yandex.ru)
Date: 2018-08-26T12:09:43+02:00

Commit Message:
LASTEXPRESS: fix gcc build

Changed paths:
    engines/lastexpress/entities/entity.cpp
    engines/lastexpress/entities/entity.h


diff --git a/engines/lastexpress/entities/entity.cpp b/engines/lastexpress/entities/entity.cpp
index faf937c..447b556 100644
--- a/engines/lastexpress/entities/entity.cpp
+++ b/engines/lastexpress/entities/entity.cpp
@@ -167,7 +167,7 @@ void EntityData::saveLoadWithSerializer(Common::Serializer &s, const Common::Arr
 
 		for (uint i = 0; i < 8; i++) {
 			if (!paramsTypeSetters || _data.callbacks[i] >= paramsTypeSetters->size())
-				resetParametersType<EntityParametersIIII>(&_parameters[i]);
+				resetParametersType<EntityParametersIIII, EntityParametersIIII, EntityParametersIIII>(&_parameters[i]);
 			else
 				(*paramsTypeSetters)[_data.callbacks[i]](&_parameters[i]);
 		}
@@ -186,7 +186,7 @@ Entity::Entity(LastExpressEngine *engine, EntityIndex index) : _engine(engine),
 
 	// Add first empty entry to callbacks array
 	_callbacks.push_back(NULL);
-	_paramsTypeSetters.push_back(&EntityData::resetParametersType<EntityData::EntityParametersIIII>);
+	_paramsTypeSetters.push_back(&EntityData::resetParametersType<EntityData::EntityParametersIIII, EntityData::EntityParametersIIII, EntityData::EntityParametersIIII>);
 }
 
 Entity::~Entity() {
diff --git a/engines/lastexpress/entities/entity.h b/engines/lastexpress/entities/entity.h
index 0e01b08..22bfe67 100644
--- a/engines/lastexpress/entities/entity.h
+++ b/engines/lastexpress/entities/entity.h
@@ -78,11 +78,11 @@ struct SavePoint;
 
 #define ADD_CALLBACK_FUNCTION_TYPE(class, name, type) \
 	_callbacks.push_back(new ENTITY_CALLBACK(class, name, this)); \
-	_paramsTypeSetters.push_back(&EntityData::resetParametersType<EntityData::type>);
+	_paramsTypeSetters.push_back(&EntityData::resetParametersType<EntityData::type, EntityData::EntityParametersIIII, EntityData::EntityParametersIIII>);
 
 #define ADD_CALLBACK_FUNCTION_TYPE2(class, name, type1, type2) \
 	_callbacks.push_back(new ENTITY_CALLBACK(class, name, this)); \
-	_paramsTypeSetters.push_back(&EntityData::resetParametersType<EntityData::type1, EntityData::type2>);
+	_paramsTypeSetters.push_back(&EntityData::resetParametersType<EntityData::type1, EntityData::type2, EntityData::EntityParametersIIII>);
 
 #define ADD_CALLBACK_FUNCTION_TYPE3(class, name, type1, type2, type3) \
 	_callbacks.push_back(new ENTITY_CALLBACK(class, name, this)); \
@@ -106,7 +106,7 @@ struct SavePoint;
 
 #define ADD_NULL_FUNCTION() \
 	_callbacks.push_back(new ENTITY_CALLBACK(Entity, nullfunction, this)); \
-	_paramsTypeSetters.push_back(&(EntityData::resetParametersType<EntityData::EntityParametersIIII>));
+	_paramsTypeSetters.push_back(&(EntityData::resetParametersType<EntityData::EntityParametersIIII, EntityData::EntityParametersIIII, EntityData::EntityParametersIIII>));
 
 #define WRAP_SETUP_FUNCTION(className, method) \
 	new Common::Functor0Mem<void, className>(this, &className::method)
@@ -873,7 +873,7 @@ public:
 
 	EntityData() {}
 
-	template<class T1, class T2 = EntityParametersIIII, class T3 = EntityParametersIIII>
+	template<class T1, class T2, class T3>
 	static void resetParametersType(EntityCallParameters* params) {
 		params->clear();
 		params->parameters[0] = new T1();





More information about the Scummvm-git-logs mailing list