From 7c1fbe7ee573a709d3b47b2f4c7722283c817d10 Mon Sep 17 00:00:00 2001
From: Randy Heit <rheit@zdoom.fake>
Date: Thu, 19 Oct 2006 20:20:56 +0000
Subject: [PATCH] - Modified the way autosaves are done. Instead of setting
 gameaction to   ga_autosave, write DEM_CHECKAUTOSAVE to the net stream. When
 this is   processed, it will check if it's okay to do an autosave. If it is,
 it writes   DEM_DOAUTOSAVE to the net stream, which the sets gameaction to
 ga_autosave.   Essentially, about half of the functionality was moved out of
 G_DoAutoSave()   and into Net_DoCommand(). - Minor changes to OS detection:
 The os_WinNT enumeration has been renamed to   os_WinNT4, since every new OS
 coming out of Microsoft these days is   essentially NT. NT 5.2 and 6.0 are
 now properly identified as "Windows   Server 2003" and "Windows Vista"
 respectively, and any unknown NT versions   Microsoft introduces in the
 future will now be displayed as "Windows NT"   instead of "Windows 2000" if
 the minor version is 0 and "Windows XP" if the   minor version is non-0.
 Win32s detection has also been removed. Presumably   if somebody is foolish
 enough to try to run this on Windows 3.x with Win32s,   it won't even load
 due to missing DLLs. - Fixed: Demos with NETD chunks should not set netgame
 to true unless they   have more than one player. And since netdemo is ignored
 if netgame is   false, it doesn't need to set that either. - Fixed:
 FTexture::GetScaled* functions did not check for scale values of 0.

SVN r354 (trunk)
---
 docs/rh-log.txt          | 23 +++++++++++++++++++++++
 src/d_net.cpp            | 22 ++++++++++++++++++++++
 src/d_protocol.h         |  4 +++-
 src/g_game.cpp           | 25 ++++++++-----------------
 src/g_level.cpp          |  2 +-
 src/p_lnspec.cpp         |  2 +-
 src/r_defs.h             |  8 ++++----
 src/sound/fmodsound.cpp  |  4 ++--
 src/version.h            |  4 ++--
 src/win32/i_input.cpp    |  4 ++--
 src/win32/i_system.cpp   | 38 ++++++++++++++++++--------------------
 src/win32/i_system.h     |  5 ++---
 src/win32/win32video.cpp |  2 +-
 13 files changed, 89 insertions(+), 54 deletions(-)

diff --git a/docs/rh-log.txt b/docs/rh-log.txt
index fd80e0db3..2d3e29aa8 100644
--- a/docs/rh-log.txt
+++ b/docs/rh-log.txt
@@ -1,3 +1,20 @@
+October 19, 2006
+- Modified the way autosaves are done. Instead of setting gameaction to
+  ga_autosave, write DEM_CHECKAUTOSAVE to the net stream. When this is
+  processed, it will check if it's okay to do an autosave. If it is, it writes
+  DEM_DOAUTOSAVE to the net stream, which the sets gameaction to ga_autosave.
+  Essentially, about half of the functionality was moved out of G_DoAutoSave()
+  and into Net_DoCommand().
+- Minor changes to OS detection: The os_WinNT enumeration has been renamed to
+  os_WinNT4, since every new OS coming out of Microsoft these days is
+  essentially NT. NT 5.2 and 6.0 are now properly identified as "Windows
+  Server 2003" and "Windows Vista" respectively, and any unknown NT versions
+  Microsoft introduces in the future will now be displayed as "Windows NT"
+  instead of "Windows 2000" if the minor version is 0 and "Windows XP" if the
+  minor version is non-0. Win32s detection has also been removed. Presumably
+  if somebody is foolish enough to try to run this on Windows 3.x with Win32s,
+  it won't even load due to missing DLLs.
+
 October 15, 2006 (Changes by Graf Zahl)
 - Changed the rocket so that the FX_ROCKET flag is set in the actor
   definition and not in BeginPlay.
@@ -5,6 +22,12 @@ October 15, 2006 (Changes by Graf Zahl)
   (MF5_DEHEXPLOSION) so that its effects can be used on other actors
   as well without having to inherit from the rocket.
 
+October 9, 2006
+- Fixed: Demos with NETD chunks should not set netgame to true unless they
+  have more than one player. And since netdemo is ignored if netgame is
+  false, it doesn't need to set that either.
+- Fixed: FTexture::GetScaled* functions did not check for scale values of 0.
+
 October 7, 2006 (Changes by Graf Zahl)
 - Fixed: PrintAlias passed FString objects directly to Printf.
 - Added bitwise not (~) operator to ACS.
diff --git a/src/d_net.cpp b/src/d_net.cpp
index 779316062..96caa1941 100644
--- a/src/d_net.cpp
+++ b/src/d_net.cpp
@@ -55,6 +55,9 @@
 int P_StartScript (AActor *who, line_t *where, int script, char *map, bool backSide,
 					int arg0, int arg1, int arg2, int always, bool wantResultCode, bool net);
 
+EXTERN_CVAR (Int, disableautosave)
+EXTERN_CVAR (Int, autosavecount)
+
 //#define SIMULATEERRORS		(RAND_MAX/3)
 #define SIMULATEERRORS			0
 
@@ -2220,6 +2223,25 @@ void Net_DoCommand (int type, BYTE **stream, int player)
 		gameaction = ga_savegame;
 		break;
 
+	case DEM_CHECKAUTOSAVE:
+		// Do not autosave in multiplayer games or when dead.
+		// For demo playback, DEM_DOAUTOSAVE already exists in the demo if the
+		// autosave happened. And if it doesn't, we must not generate it.
+		if (multiplayer ||
+			demoplayback ||
+			players[consoleplayer].playerstate != PST_LIVE ||
+			disableautosave >= 2 ||
+			autosavecount == 0)
+		{
+			break;
+		}
+		Net_WriteByte (DEM_DOAUTOSAVE);
+		break;
+
+	case DEM_DOAUTOSAVE:
+		gameaction = ga_autosave;
+		break;
+
 	case DEM_FOV:
 		{
 			float newfov = (float)ReadByte (stream);
diff --git a/src/d_protocol.h b/src/d_protocol.h
index 448a2afa3..0443f7359 100644
--- a/src/d_protocol.h
+++ b/src/d_protocol.h
@@ -139,7 +139,9 @@ enum EDemoCommand
 	DEM_SUMMONFRIEND,	// 37 String: Thing to fabricate
 	DEM_SPRAY,			// 38 String: The decal to spray
 	DEM_CROUCH,			// 39
-	DEM_RUNSCRIPT2		// 40 Same as DEM_RUNSCRIPT, but always executes
+	DEM_RUNSCRIPT2,		// 40 Same as DEM_RUNSCRIPT, but always executes
+	DEM_CHECKAUTOSAVE,	// 41 Check if the user has autosaves enabled. Ignored for demoplayback.
+	DEM_DOAUTOSAVE,		// 42 An autosave should be made
 };
 
 // The following are implemented by cht_DoCheat in m_cheat.cpp
diff --git a/src/g_game.cpp b/src/g_game.cpp
index 54a85aeb5..cd14cc7db 100644
--- a/src/g_game.cpp
+++ b/src/g_game.cpp
@@ -97,7 +97,7 @@ void	G_DoCompleted (void);
 void	G_DoVictory (void);
 void	G_DoWorldDone (void);
 void	G_DoSaveGame (bool okForQuicksave);
-void	G_DoAutoSave (void);
+void	G_DoAutoSave ();
 
 FIntCVar gameskill ("skill", 2, CVAR_SERVERINFO|CVAR_LATCH);
 CVAR (Int, deathmatch, 0, CVAR_SERVERINFO|CVAR_LATCH);
@@ -1700,7 +1700,9 @@ void G_DoLoadGame ()
 
 	// load a base level
 	savegamerestore = true;		// Use the player actors in the savegame
+	bool demoplaybacksave = demoplayback;
 	G_InitNew (map, false);
+	demoplayback = demoplaybacksave;
 	delete[] map;
 	savegamerestore = false;
 
@@ -1802,22 +1804,12 @@ extern void P_CalcHeight (player_t *);
 
 void G_DoAutoSave ()
 {
-	// Do not autosave in multiplayer games or demos or when dead
-	if (multiplayer ||
-		demoplayback ||
-		players[consoleplayer].playerstate != PST_LIVE ||
-		disableautosave >= 2 ||
-		autosavecount == 0)
-	{
-		gameaction = ga_nothing;
-		return;
-	}
-
 	// Keep up to four autosaves at a time
 	UCVarValue num;
 	char *readableTime;
+	int count = autosavecount != 0 ? autosavecount : 1;
 	
-	num.Int = (autosavenum + 1) % autosavecount;
+	num.Int = (autosavenum + 1) % count;
 	autosavenum.ForceSet (num, CVAR_Int);
 
 	savegamefile = G_BuildSaveName ("auto", num.Int);
@@ -1967,11 +1959,10 @@ void G_DoSaveGame (bool okForQuicksave)
 {
 	if (demoplayback)
 	{
-		gameaction = ga_nothing;
-		return;
+		savegamefile = G_BuildSaveName ("demosave.zds", -1);
 	}
 
-	insave=true;
+	insave = true;
 	G_SnapshotLevel ();
 
 	FILE *stdfile = fopen (savegamefile.GetChars(), "wb");
@@ -2368,7 +2359,7 @@ bool G_ProcessIFFDemo (char *mapname)
 			break;
 
 		case NETD_ID:
-			multiplayer = netgame = netdemo = true;
+			multiplayer = true;
 			break;
 
 		case BODY_ID:
diff --git a/src/g_level.cpp b/src/g_level.cpp
index d1ea932f0..3a01ca4e3 100644
--- a/src/g_level.cpp
+++ b/src/g_level.cpp
@@ -1819,7 +1819,7 @@ IMPLEMENT_CLASS (DAutosaver)
 
 void DAutosaver::Tick ()
 {
-	gameaction = ga_autosave;
+	Net_WriteByte (DEM_CHECKAUTOSAVE);
 	Destroy ();
 }
 
diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp
index be6a53bac..49c3a0f23 100644
--- a/src/p_lnspec.cpp
+++ b/src/p_lnspec.cpp
@@ -2470,7 +2470,7 @@ FUNC(LS_Autosave)
 {
 	if (gameaction != ga_savegame)
 	{
-		gameaction = ga_autosave;
+		Net_WriteByte (DEM_CHECKAUTOSAVE);
 	}
 	return true;
 }
diff --git a/src/r_defs.h b/src/r_defs.h
index abc69f5f0..466794123 100644
--- a/src/r_defs.h
+++ b/src/r_defs.h
@@ -648,11 +648,11 @@ public:
 	int GetWidth () { return Width; }
 	int GetHeight () { return Height; }
 
-	int GetScaledWidth () { return DivScale3(Width, ScaleX); }
-	int GetScaledHeight () { return DivScale3(Height, ScaleY); }
+	int GetScaledWidth () { return ScaleX ? DivScale3(Width, ScaleX) : Width; }
+	int GetScaledHeight () { return ScaleY ? DivScale3(Height, ScaleY) : Height; }
 
-	int GetScaledLeftOffset () { return DivScale3(LeftOffset, ScaleX); }
-	int GetScaledTopOffset () { return DivScale3(TopOffset, ScaleY); }
+	int GetScaledLeftOffset () { return ScaleX ? DivScale3(LeftOffset, ScaleX) : Width; }
+	int GetScaledTopOffset () { return ScaleY ? DivScale3(TopOffset, ScaleY) : Height; }
 
 	virtual void SetFrontSkyLayer();
 
diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp
index dd5d4585e..dc71162f6 100644
--- a/src/sound/fmodsound.cpp
+++ b/src/sound/fmodsound.cpp
@@ -302,7 +302,7 @@ bool FMODSoundRenderer::Init ()
 	{
 		// If snd_3d is true, try for a3d output if snd_output was not recognized above.
 		// However, if running under NT 4.0, a3d will only be tried if specifically requested.
-		outindex = (OSPlatform == os_WinNT) ? 1 : 0;
+		outindex = (OSPlatform == os_WinNT4) ? 1 : 0;
 #if 0
 		// FMOD 3.6 no longer supports a3d. Keep this code here in case support comes back.
 		if (stricmp (snd_output, "a3d") == 0 || (outindex == 0 && snd_3d))
@@ -342,7 +342,7 @@ bool FMODSoundRenderer::Init ()
 	}
 
 #ifdef _WIN32
-	if (OSPlatform == os_WinNT)
+	if (OSPlatform == os_WinNT4)
 	{
 		// If running Windows NT 4, we need to initialize DirectSound before
 		// using WinMM. If we don't, then FSOUND_Close will corrupt a
diff --git a/src/version.h b/src/version.h
index a835a064d..bd5acd371 100644
--- a/src/version.h
+++ b/src/version.h
@@ -54,7 +54,7 @@
 // Version identifier for network games.
 // Bump it every time you do a release unless you're certain you
 // didn't change anything that will affect sync.
-#define NETGAMEVERSION 209
+#define NETGAMEVERSION 210
 
 // Version stored in the ini's [LastRun] section.
 // Bump it if you made some configuration change that you want to
@@ -64,7 +64,7 @@
 // Protocol version used in demos.
 // Bump it if you change existing DEM_ commands or add new ones.
 // Otherwise, it should be safe to leave it alone.
-#define DEMOGAMEVERSION 0x205
+#define DEMOGAMEVERSION 0x206
 
 // Minimum demo version we can play.
 // Bump it whenever you change or remove existing DEM_ commands.
diff --git a/src/win32/i_input.cpp b/src/win32/i_input.cpp
index 6072be736..d295c9470 100644
--- a/src/win32/i_input.cpp
+++ b/src/win32/i_input.cpp
@@ -339,7 +339,7 @@ CUSTOM_CVAR (Int, in_mouse, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
 	{
 		int new_mousemode;
 
-		if (self == 1 || (self == 0 && OSPlatform == os_WinNT))
+		if (self == 1 || (self == 0 && OSPlatform == os_WinNT4))
 			new_mousemode = win32;
 		else
 			new_mousemode = dinput;
@@ -1327,7 +1327,7 @@ static BOOL I_GetDIMouse ()
 	mousemode = win32;	// Assume failure
 	UngrabMouse_Win32 ();
 
-	if (in_mouse == 1 || (in_mouse == 0 && OSPlatform == os_WinNT))
+	if (in_mouse == 1 || (in_mouse == 0 && OSPlatform == os_WinNT4))
 		return FALSE;
 
 	// Obtain an interface to the system mouse device.
diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp
index 1900c968f..631af4a71 100644
--- a/src/win32/i_system.cpp
+++ b/src/win32/i_system.cpp
@@ -218,11 +218,6 @@ void I_DetectOS (void)
 
 	switch (info.dwPlatformId)
 	{
-	case VER_PLATFORM_WIN32s:
-		OSPlatform = os_Win32s;
-		osname = "3.x";
-		break;
-
 	case VER_PLATFORM_WIN32_WINDOWS:
 		OSPlatform = os_Win95;
 		if (info.dwMinorVersion < 10)
@@ -240,18 +235,26 @@ void I_DetectOS (void)
 		break;
 
 	case VER_PLATFORM_WIN32_NT:
-		OSPlatform = info.dwMajorVersion < 5 ? os_WinNT : os_Win2k;
-		if (OSPlatform == os_WinNT)
+		OSPlatform = info.dwMajorVersion < 5 ? os_WinNT4 : os_Win2k;
+		osname = "NT";
+		if (info.dwMajorVersion == 5)
 		{
-			osname = "NT";
+			if (info.dwMinorVersion == 0)
+			{
+				osname = "2000";
+			}
+			if (info.dwMinorVersion == 1)
+			{
+				osname = "XP";
+			}
+			else if (info.dwMinorVersion == 2)
+			{
+				osname = "Server 2003";
+			}
 		}
-		else if (info.dwMinorVersion == 0)
+		else if (info.dwMajorVersion == 6 && info.dwMinorVersion == 0)
 		{
-			osname = "2000";
-		}
-		else
-		{
-			osname = "XP";
+			osname = "Vista";
 		}
 		break;
 
@@ -270,12 +273,7 @@ void I_DetectOS (void)
 		Printf ("    %s\n", info.szCSDVersion);
 	}
 
-	if (OSPlatform == os_Win32s)
-	{
-		I_FatalError ("Sorry, Win32s is not supported.\n"
-					  "Upgrade to a newer version of Windows.");
-	}
-	else if (OSPlatform == os_unknown)
+	if (OSPlatform == os_unknown)
 	{
 		Printf ("(Assuming Windows 95)\n");
 		OSPlatform = os_Win95;
diff --git a/src/win32/i_system.h b/src/win32/i_system.h
index 219b3ecce..ceb853b81 100644
--- a/src/win32/i_system.h
+++ b/src/win32/i_system.h
@@ -44,9 +44,8 @@ void I_DetectOS (void);
 typedef enum {
 	os_unknown,
 	os_Win95,
-	os_WinNT,
-	os_Win2k,
-	os_Win32s
+	os_WinNT4,
+	os_Win2k
 } os_t;
 
 extern os_t OSPlatform;
diff --git a/src/win32/win32video.cpp b/src/win32/win32video.cpp
index 8820a05cf..26ffa54ba 100644
--- a/src/win32/win32video.cpp
+++ b/src/win32/win32video.cpp
@@ -625,7 +625,7 @@ bool DDrawFB::CreateResources ()
 		}
 		LOG3 ("Mode set to %d x %d x %d\n", Width, Height, bits);
 
-		if (vid_attachedsurfaces && OSPlatform == os_WinNT)
+		if (vid_attachedsurfaces && OSPlatform == os_WinNT4)
 		{
 			if (!CreateSurfacesAttached ())
 				return false;