diff --git a/source/core/gamestruct.h b/source/core/gamestruct.h
index d2594bae8..cf63cef3f 100644
--- a/source/core/gamestruct.h
+++ b/source/core/gamestruct.h
@@ -4,6 +4,7 @@ bool System_WantGuiCapture();	// During playing this tells us whether the game m
 
 #include <stdint.h>
 #include "vectors.h"
+#include "engineerrors.h"
 
 struct GameStats
 {
@@ -84,6 +85,7 @@ struct GameInterface
 	virtual void SetAmbience(bool on) {}
 	virtual FString GetCoordString() { return "'stat coord' not implemented"; }
 	virtual bool CheatAllowed(bool printmsg) { return true; }
+	virtual void ExitFromMenu() { throw CExitEvent(0); }
 
 };
 
diff --git a/source/core/menu/messagebox.cpp b/source/core/menu/messagebox.cpp
index 44d7f3d1e..02090ec02 100644
--- a/source/core/menu/messagebox.cpp
+++ b/source/core/menu/messagebox.cpp
@@ -454,7 +454,7 @@ CCMD (menu_quit)
 
 	DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, EndString, 0, 500, false, NAME_None, [](bool res)
 	{
-		if (res) throw CExitEvent(0);
+			if (res) gi->ExitFromMenu();
 	});
 
 	M_ActivateMenu(newmenu);
diff --git a/source/games/duke/src/2d_r.cpp b/source/games/duke/src/2d_r.cpp
index e72f9608e..98641bb00 100644
--- a/source/games/duke/src/2d_r.cpp
+++ b/source/games/duke/src/2d_r.cpp
@@ -578,7 +578,7 @@ void dobonus_r(bool bonusonly, CompletionFunc completion)
 			int levnum = clamp((currentLevel->levelNumber / 100) * 7 + (currentLevel->levelNumber % 100), 0, 13);
 			char fn[20];
 			mysnprintf(fn, 20, "lvl%d.anm", levnum + 1);
-			static const int framespeed[] = { 20, 20, 7200 };   // wait for one minute on the final frame so that the video doesn't appear before the user notices.
+			static const int framespeed[] = { 20, 20, 7200 };   // wait for one minute on the final frame so that the video doesn't stop  before the user notices.
 			jobs[job++] = { PlayVideo(fn, nullptr, framespeed) };
 			if (ud.eog && currentLevel->levelNumber > 100)
 			{
diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h
index 8c198fcb6..20ac92728 100644
--- a/source/games/duke/src/duke3d.h
+++ b/source/games/duke/src/duke3d.h
@@ -63,6 +63,7 @@ struct GameInterface : ::GameInterface
 	void QuitToTitle() override;
 	FString GetCoordString() override;
 	bool CheatAllowed(bool printmsg) override;
+	void ExitFromMenu() override;
 };
 
 struct Dispatcher
diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h
index 5802b1979..92bb46e52 100644
--- a/source/games/duke/src/funct.h
+++ b/source/games/duke/src/funct.h
@@ -208,7 +208,7 @@ void drawstatusbar_d(int snum);
 void drawstatusbar_r(int snum);
 void drawoverheadmap(int cposx, int cposy, int czoom, int cang);
 void cameratext(int i);
-void dobonus(int bonusonly);
+void dobonus(int bonusonly, CompletionFunc completion);
 void dobonus_d(bool bonusonly, CompletionFunc completion);
 void dobonus_r(bool bonusonly, CompletionFunc completion);
 
diff --git a/source/games/duke/src/game_misc.cpp b/source/games/duke/src/game_misc.cpp
index a78e3a942..6ecec0474 100644
--- a/source/games/duke/src/game_misc.cpp
+++ b/source/games/duke/src/game_misc.cpp
@@ -109,22 +109,41 @@ void setmapfog(int fogtype)
 //
 //---------------------------------------------------------------------------
 
-void gameexitfrommenu()
+static void runbonus(CompletionFunc completion)
 {
 	// MP scoreboard
 	if (playerswhenstarted > 1 && ps[myconnectindex].gm & MODE_GAME && !ud.coop)
 	{
-		dobonus(1);
+		dobonus(1, completion);
 	}
+	else if (completion) completion(false);
 
+}
+static void runtwoscreens(CompletionFunc completion)
+{
 	// shareware and TEN screens
 	if (!VOLUMEALL && !isRR())
-		showtwoscreens([](bool) {});
+		showtwoscreens(completion);
+	else if (completion) completion(false);
+}
 
+static void endthegame(bool)
+{
 	endoomName = isRR() ? "redneck.bin" : VOLUMEALL ? "duke3d.bin" : "dukesw.bin";
 	ST_Endoom();
 }
 
+
+void gameexitfrommenu()
+{
+	runbonus([](bool aborted) { runtwoscreens(endthegame); });
+}
+
+void GameInterface::ExitFromMenu() 
+{ 
+	gameexitfrommenu();
+}
+
 //---------------------------------------------------------------------------
 //
 // This now redirects the messagew to the console's notification display
@@ -704,11 +723,11 @@ void cameratext(int i)
 //
 //---------------------------------------------------------------------------
 
-void dobonus(int bonusonly)
+void dobonus(int bonusonly, CompletionFunc completion)
 {
-    if (isRRRA());
-    else if (isRR()) dobonus_r(bonusonly, nullptr);
-    else dobonus_d(bonusonly, nullptr);
+	if (isRRRA()) { if (completion) completion(false); }
+    else if (isRR()) dobonus_r(bonusonly, completion);
+    else dobonus_d(bonusonly, completion);
 }
 
 //---------------------------------------------------------------------------
diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp
index 30e4f9a38..8b04d6f4e 100644
--- a/source/games/duke/src/input.cpp
+++ b/source/games/duke/src/input.cpp
@@ -893,12 +893,12 @@ static void processMovement(player_struct *p, input_t &input, ControlInfo &info,
 		if (buttonMap.ButtonDown(gamefunc_Turn_Left))
 		{
 			turnheldtime += tics;
-			input.q16avel -= fix16_from_dbl(2 * scaleFactor * (turnheldtime >= TURBOTURNTIME) ? turnamount : PREAMBLETURN);
+			input.q16avel -= fix16_from_dbl(2 * scaleFactor * (turnheldtime >= TURBOTURNTIME ? turnamount : PREAMBLETURN));
 		}
 		else if (buttonMap.ButtonDown(gamefunc_Turn_Right))
 		{
 			turnheldtime += tics;
-			input.q16avel += fix16_from_dbl(2 * scaleFactor * (turnheldtime >= TURBOTURNTIME) ? turnamount : PREAMBLETURN);
+			input.q16avel += fix16_from_dbl(2 * scaleFactor * (turnheldtime >= TURBOTURNTIME ? turnamount : PREAMBLETURN));
 		}
 		else
 		{
@@ -1202,7 +1202,7 @@ static void FinalizeInput(int playerNum, input_t& input, bool vehicle)
 			loc.q16avel += input.q16avel;
 			if (!synchronized_input)
 			{
-				p->q16ang = (p->q16ang + input.q16avel) & 0x7FFFFFF;
+				p->q16ang = (p->q16ang + input.q16avel * 2) & 0x7FFFFFF;	// Why * 2 now?
 
 				if (input.q16avel)
 					p->one_eighty_count = 0;
diff --git a/source/games/duke/src/premap.cpp b/source/games/duke/src/premap.cpp
index a8cfdb79a..a96a4d277 100644
--- a/source/games/duke/src/premap.cpp
+++ b/source/games/duke/src/premap.cpp
@@ -1093,7 +1093,7 @@ int exitlevel(void)
     if (ps[myconnectindex].gm & MODE_EOL)
     {
         ready2send = 0;
-        dobonus(0);
+        dobonus(0, nullptr);
 
         // Clear potentially loaded per-map ART only after the bonus screens.
         artClearMapArt();