Clean up savegame's ReadGame() a bit

less duplicate code, more readable usage of strcmp()
This commit is contained in:
Daniel Gibson 2021-01-12 06:02:27 +01:00
parent ee7923a9dd
commit 9bc2fe29fe

View file

@ -851,113 +851,87 @@ ReadGame(const char *filename)
fread(str_os, sizeof(str_os), 1, f);
fread(str_arch, sizeof(str_arch), 1, f);
// for several released versions (up to incl. 7.45), the official Win32 binaries
// accidentally had the YQ2ARCH "AMD64" instead of "i386" set due to a bug in the Makefile
// so add this workaround for savegames before version 4 (the version was bumped for this fix)
qboolean amd64quirk = false;
#if defined(_WIN32) && (defined(__i386__) || defined(_M_IX86))
amd64quirk = (strcmp(str_arch, "AMD64") == 0);
#endif
static const struct {
const char* verstr;
int vernum;
} version_mappings[] = {
{"YQ2-1", 1},
{"YQ2-2", 2},
{"YQ2-3", 3},
{"YQ2-4", 4},
};
if (!strcmp(str_ver, SAVEGAMEVER))
for (i=0; i < sizeof(version_mappings)/sizeof(version_mappings[0]); ++i)
{
save_ver = 4;
if (strcmp(str_game, GAMEVERSION))
if (strcmp(version_mappings[i].verstr, str_ver) == 0)
{
fclose(f);
gi.error("Savegame from another game.so.\n");
}
else if (strcmp(str_os, YQ2OSTYPE))
{
fclose(f);
gi.error("Savegame from another os.\n");
}
else if (strcmp(str_arch, YQ2ARCH))
{
fclose(f);
gi.error("Savegame from another architecture.\n");
save_ver = version_mappings[i].vernum;
break;
}
}
else if (!strcmp(str_ver, "YQ2-3"))
{
save_ver = 3;
if (strcmp(str_game, GAMEVERSION))
{
fclose(f);
gi.error("Savegame from another game.so.\n");
}
else if (strcmp(str_os, YQ2OSTYPE))
{
fclose(f);
gi.error("Savegame from another os.\n");
}
else if (strcmp(str_arch, YQ2ARCH) && !amd64quirk)
{
fclose(f);
gi.error("Savegame from another architecture.\n");
}
}
else if (!strcmp(str_ver, "YQ2-2"))
{
save_ver = 2;
if (strcmp(str_game, GAMEVERSION))
{
fclose(f);
gi.error("Savegame from another game.so.\n");
}
else if (strcmp(str_os, YQ2OSTYPE))
{
fclose(f);
gi.error("Savegame from another os.\n");
}
else if (strcmp(str_arch, YQ2ARCH) && !amd64quirk)
{
fclose(f);
gi.error("Savegame from another architecture.\n");
}
}
else if (!strcmp(str_ver, "YQ2-1"))
{
save_ver = 1;
if (strcmp(str_game, GAMEVERSION))
{
fclose(f);
gi.error("Savegame from another game.so.\n");
}
else if (strcmp(str_os, OSTYPE_1))
{
fclose(f);
gi.error("Savegame from another os.\n");
}
if (!strcmp(str_os, "Windows"))
{
/* Windows was forced to i386 */
if (strcmp(str_arch, "i386"))
{
fclose(f);
gi.error("Savegame from another architecture.\n");
}
}
else
{
if (strcmp(str_arch, ARCH_1))
{
fclose(f);
gi.error("Savegame from another architecture.\n");
}
}
}
else
if (save_ver == 0) // not found in mappings table
{
fclose(f);
gi.error("Savegame from an incompatible version.\n");
}
if (save_ver == 1)
{
if (strcmp(str_game, GAMEVERSION) != 0)
{
fclose(f);
gi.error("Savegame from another game.so.\n");
}
else if (strcmp(str_os, OSTYPE_1) != 0)
{
fclose(f);
gi.error("Savegame from another os.\n");
}
#ifdef _WIN32
/* Windows was forced to i386 */
if (strcmp(str_arch, "i386") != 0)
{
fclose(f);
gi.error("Savegame from another architecture.\n");
}
#else
if (strcmp(str_arch, ARCH_1) != 0)
{
fclose(f);
gi.error("Savegame from another architecture.\n");
}
#endif
}
else // all newer savegame versions
{
if (strcmp(str_game, GAMEVERSION) != 0)
{
fclose(f);
gi.error("Savegame from another game.so.\n");
}
else if (strcmp(str_os, YQ2OSTYPE) != 0)
{
fclose(f);
gi.error("Savegame from another os.\n");
}
else if (strcmp(str_arch, YQ2ARCH) != 0)
{
#if defined(_WIN32) && (defined(__i386__) || defined(_M_IX86))
// before savegame version "YQ2-4" (and after version 1),
// the official Win32 binaries accidentally had the YQ2ARCH "AMD64"
// instead of "i386" set due to a bug in the Makefile.
// This quirk allows loading those savegames anyway
if (save_ver >= 4 || strcmp(str_arch, "AMD64") != 0)
#endif
{
fclose(f);
gi.error("Savegame from another architecture.\n");
}
}
}
g_edicts = gi.TagMalloc(game.maxentities * sizeof(g_edicts[0]), TAG_GAME);
globals.edicts = g_edicts;