ref: 5c644aea77f8e37f2f39928b2256c9a13cdebb99
parent: 4d9752561a4575f90a48c75e7d7bfa783c72deff
parent: 26524bf56324364ceb1f9fad6e1efec55315d73d
author: linguica <github@andrewstine.org>
date: Sun Sep 6 08:51:31 EDT 2015
Merge remote-tracking branch 'chocolate-doom/master'
--- a/configure.ac
+++ b/configure.ac
@@ -6,6 +6,7 @@
PACKAGE_LICENSE="GNU General Public License, version 2"
PACKAGE_MAINTAINER="Simon Howard"
PACKAGE_URL="http://www.chocolate-doom.org/"
+PACKAGE_ISSUES="https://github.com/chocolate-doom/chocolate-doom/issues"
AC_CONFIG_AUX_DIR(autotools)
@@ -102,7 +103,15 @@
AC_CHECK_LIB(amd64, amd64_iopl)
])
-AC_CHECK_TOOL(WINDRES, windres, )
+case $host in
+ *cygwin* | *mingw* )
+ AC_CHECK_TOOL(WINDRES, windres, )
+ ;;
+ *)
+ WINDRES=
+ ;;
+esac
+
AC_CHECK_TOOL(STRIP, strip, )
AM_CONDITIONAL(HAVE_WINDRES, test "$WINDRES" != "")
@@ -142,6 +151,7 @@
AC_SUBST(PACKAGE_LICENSE)
AC_SUBST(PACKAGE_MAINTAINER)
AC_SUBST(PACKAGE_URL)
+AC_SUBST(PACKAGE_ISSUES)
dnl Shut up the datarootdir warnings.
AC_DEFUN([AC_DATAROOTDIR_CHECKED])
@@ -159,11 +169,14 @@
rpm.spec
data/Makefile
src/Makefile
+src/doom.appdata.xml
src/doom.desktop
src/doom-screensaver.desktop
src/doom/Makefile
+src/heretic.appdata.xml
src/heretic.desktop
src/heretic/Makefile
+src/hexen.appdata.xml
src/hexen.desktop
src/hexen/Makefile
src/resource.rc
@@ -171,6 +184,7 @@
src/setup/Makefile
src/setup/setup.desktop
src/setup/setup-manifest.xml
+src/strife.appdata.xml
src/strife.desktop
src/strife/Makefile
textscreen/Makefile
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -1,4 +1,5 @@
MANPAGE_GEN_FILES = environ.man \
+ iwad_paths.man \
doom.template \
heretic.template \
hexen.template \
--- a/man/doom.template
+++ b/man/doom.template
@@ -10,6 +10,8 @@
to behave as similar to the original DOS version of Doom as is possible.
.br
@content
+.SH IWAD SEARCH PATHS
+@include iwad_paths.man
.SH ENVIRONMENT
This section describes environment variables that control Chocolate Doom's
behavior.
--- a/man/environ.man
+++ b/man/environ.man
@@ -1,9 +1,6 @@
.TP
\fBDOOMWADDIR\fR, \fBDOOMWADPATH\fR
-These environment variables provide paths to search for Doom .WAD files when
-looking for a game IWAD file or a PWAD file specified with the `\-file' option.
-\fBDOOMWADDIR\fR specifies a single path in which to look for WAD files,
-while \fBDOOMWWADPATH\fR specifies a colon-separated list of paths to search.
+See the section, \fBIWAD SEARCH PATHS\fR above.
.TP
\fBPCSOUND_DRIVER\fR
When running in PC speaker sound effect mode, this environment variable
--- a/man/heretic.template
+++ b/man/heretic.template
@@ -11,6 +11,8 @@
possible.
.br
@content
+.SH IWAD SEARCH PATHS
+@include iwad_paths.man
.SH ENVIRONMENT
This section describes environment variables that control Chocolate Heretic's
behavior.
--- a/man/hexen.template
+++ b/man/hexen.template
@@ -11,6 +11,8 @@
possible.
.br
@content
+.SH IWAD SEARCH PATHS
+@include iwad_paths.man
.SH ENVIRONMENT
This section describes environment variables that control Chocolate Hexen's
behavior.
--- /dev/null
+++ b/man/iwad_paths.man
@@ -1,0 +1,48 @@
+To play, an IWAD file is needed. This is a large file containing all of the
+levels, graphics, sound effects, music and other material that make up the
+game. IWAD files are named according to the game; the standard names are:
+.TP
+\fBdoom.wad, doom1.wad, doom2.wad, tnt.wad, plutonia.wad\fR
+Doom, Doom II, Final Doom
+.TP
+\fBheretic.wad, heretic1.wad, hexen.wad, strife1.wad\fR
+Heretic, Hexen and Strife (commercial Doom engine games).
+.TP
+\fBhacx.wad, chex.wad\fR
+Hacx and Chex Quest - more obscure games based on the Doom engine.
+.TP
+\fBfreedm.wad, freedoom1.wad, freedoom2.wad\fR
+The Freedoom open content IWAD files.
+.LP
+The following directory paths are searched in order to find an IWAD:
+.TP
+\fBCurrent working directory\fR
+Any IWAD files found in the current working directory will be used in
+preference to IWADs found in any other directories.
+.TP
+\fBDOOMWADDIR\fR
+This environment variable can be set to contain a path to a single directory
+in which to look for IWAD files. This environment variable is supported by
+most Doom source ports.
+.TP
+\fBDOOMWADPATH\fR
+This environment variable, if set, can contain a colon-separated list of
+directories in which to look for IWAD files, or alternatively full paths to
+specific IWAD files.
+.TP
+\fB$HOME/.local/share/games/doom\fR
+Writeable directory in the user's home directory. The path can be overridden
+using the \fBXDG_DATA_HOME\fR environment variable (see the XDG Base Directory
+Specification).
+.TP
+\fB/usr/local/share/games/doom, /usr/share/games/doom\fR
+System-wide locations that can be accessed by all users. The path
+\fB/usr/share/games/doom\fR is a standard path that is supported by most
+Doom source ports. These paths can be overridden using the \fBXDG_DATA_DIRS\fR
+environment variable (see the XDG Base Directory Specification).
+.LP
+The above can be overridden on a one-time basis by using the \fB\-iwad\fR
+command line parameter to provide the path to an IWAD file to use. This
+parameter can also be used to specify the name of a particular IWAD to use
+from one of the above paths. For example, '\fB-iwad doom.wad\fR' will search
+the above paths for the file \fBdoom.wad\fR to use.
--- a/man/strife.template
+++ b/man/strife.template
@@ -13,6 +13,8 @@
@content
+.SH IWAD SEARCH PATHS
+@include iwad_paths.man
.SH ENVIRONMENT
This section describes environment variables that control Chocolate Strife's
behavior.
--- a/msvc/heretic.vcproj
+++ b/msvc/heretic.vcproj
@@ -469,10 +469,6 @@
>
</File>
<File
- RelativePath="..\src\heretic\i_sound.c"
- >
- </File>
- <File
RelativePath="..\src\heretic\in_lude.c"
>
</File>
--- a/msvc/hexen.vcproj
+++ b/msvc/hexen.vcproj
@@ -426,19 +426,11 @@
>
</File>
<File
- RelativePath="..\src\hexen\i_sound.c"
- >
- </File>
- <File
RelativePath="..\src\hexen\in_lude.c"
>
</File>
<File
RelativePath="..\src\hexen\info.c"
- >
- </File>
- <File
- RelativePath="..\src\hexen\m_misc.c"
>
</File>
<File
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -14,5 +14,6 @@
chocolate-setup
*.exe
*.desktop
+*.appdata.xml
tags
TAGS
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -217,6 +217,25 @@
doom-screensaver.desktop.in \
manifest.xml
+appdatadir = $(prefix)/share/appdata
+appdata_DATA = \
+ @PROGRAM_PREFIX@doom.appdata.xml \
+ @PROGRAM_PREFIX@heretic.appdata.xml \
+ @PROGRAM_PREFIX@hexen.appdata.xml \
+ @PROGRAM_PREFIX@strife.appdata.xml
+
+@PROGRAM_PREFIX@doom.appdata.xml : doom.appdata.xml
+ cp doom.appdata.xml $@
+
+@PROGRAM_PREFIX@heretic.appdata.xml : heretic.appdata.xml
+ cp heretic.appdata.xml $@
+
+@PROGRAM_PREFIX@hexen.appdata.xml : hexen.appdata.xml
+ cp hexen.appdata.xml $@
+
+@PROGRAM_PREFIX@strife.appdata.xml : strife.appdata.xml
+ cp strife.appdata.xml $@
+
appdir = $(prefix)/share/applications
app_DATA = \
@PROGRAM_PREFIX@doom.desktop \
--- a/src/d_iwad.c
+++ b/src/d_iwad.c
@@ -142,22 +142,53 @@
},
};
-// Value installed by the Collector's Edition when it is installed
+// Values installed by the GOG.com and Collector's Edition versions
-static registry_value_t collectors_edition_value =
+static registry_value_t root_path_keys[] =
{
- HKEY_LOCAL_MACHINE,
- SOFTWARE_KEY "\\Activision\\DOOM Collector's Edition\\v1.0",
- "INSTALLPATH",
+ // Doom Collector's Edition
+
+ {
+ HKEY_LOCAL_MACHINE,
+ SOFTWARE_KEY "\\Activision\\DOOM Collector's Edition\\v1.0",
+ "INSTALLPATH",
+ },
+
+ // Ultimate Doom
+
+ {
+ HKEY_LOCAL_MACHINE,
+ SOFTWARE_KEY "\\GOG.com\\Games\\1435827232",
+ "PATH",
+ },
+
+ // Doom II
+
+ {
+ HKEY_LOCAL_MACHINE,
+ SOFTWARE_KEY "\\GOG.com\\Games\\1435848814",
+ "PATH",
+ },
+
+ // Final Doom
+
+ {
+ HKEY_LOCAL_MACHINE,
+ SOFTWARE_KEY "\\GOG.com\\Games\\1435848742",
+ "PATH",
+ },
};
// Subdirectories of the above install path, where IWADs are installed.
-static char *collectors_edition_subdirs[] =
+static char *root_path_subdirs[] =
{
+ ".",
"Doom2",
"Final Doom",
"Ultimate Doom",
+ "TNT",
+ "Plutonia",
};
// Location where Steam is installed
@@ -268,30 +299,34 @@
}
}
-// Check for Doom: Collector's Edition
+// Check for GOG.com and Doom: Collector's Edition
-static void CheckCollectorsEdition(void)
+static void CheckInstallRootPaths(void)
{
- char *install_path;
- char *subpath;
unsigned int i;
- install_path = GetRegistryString(&collectors_edition_value);
-
- if (install_path == NULL)
+ for (i=0; i<arrlen(root_path_keys); ++i)
{
- return;
- }
+ char *install_path;
+ char *subpath;
+ unsigned int j;
- for (i=0; i<arrlen(collectors_edition_subdirs); ++i)
- {
- subpath = M_StringJoin(install_path, DIR_SEPARATOR_S,
- collectors_edition_subdirs[i], NULL);
+ install_path = GetRegistryString(&root_path_keys[i]);
- AddIWADDir(subpath);
- }
+ if (install_path == NULL)
+ {
+ continue;
+ }
- free(install_path);
+ for (j=0; j<arrlen(root_path_subdirs); ++j)
+ {
+ subpath = M_StringJoin(install_path, DIR_SEPARATOR_S,
+ root_path_subdirs[j], NULL);
+ AddIWADDir(subpath);
+ }
+
+ free(install_path);
+ }
}
@@ -509,47 +544,29 @@
return mission;
}
-//
-// Add directories from the list in the DOOMWADPATH environment variable.
-//
-
-static void AddDoomWadPath(void)
+// Add IWAD directories parsed from splitting a path string containing
+// paths separated by PATH_SEPARATOR. 'suffix' is a string to concatenate
+// to the end of the paths before adding them.
+static void AddIWADPath(char *path, char *suffix)
{
- char *doomwadpath;
- char *p;
+ char *left, *p;
- // Check the DOOMWADPATH environment variable.
+ path = M_StringDuplicate(path);
- doomwadpath = getenv("DOOMWADPATH");
-
- if (doomwadpath == NULL)
- {
- return;
- }
-
- doomwadpath = M_StringDuplicate(doomwadpath);
-
- // Add the initial directory
-
- AddIWADDir(doomwadpath);
-
// Split into individual dirs within the list.
+ left = path;
- p = doomwadpath;
-
for (;;)
{
- p = strchr(p, PATH_SEPARATOR);
-
+ p = strchr(left, PATH_SEPARATOR);
if (p != NULL)
{
- // Break at the separator and store the right hand side
+ // Break at the separator and use the left hand side
// as another iwad dir
-
*p = '\0';
- p += 1;
- AddIWADDir(p);
+ AddIWADDir(M_StringJoin(left, suffix, NULL));
+ left = p + 1;
}
else
{
@@ -556,9 +573,68 @@
break;
}
}
+
+ AddIWADDir(M_StringJoin(left, suffix, NULL));
+
+ free(path);
}
+// Add standard directories where IWADs are located on Unix systems.
+// To respect the freedesktop.org specification we support overriding
+// using standard environment variables. See the XDG Base Directory
+// Specification:
+// <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>
+static void AddXdgDirs(void)
+{
+ char *env, *tmp_env;
+ // Quote:
+ // > $XDG_DATA_HOME defines the base directory relative to which
+ // > user specific data files should be stored. If $XDG_DATA_HOME
+ // > is either not set or empty, a default equal to
+ // > $HOME/.local/share should be used.
+ env = getenv("XDG_DATA_HOME");
+ tmp_env = NULL;
+
+ if (env == NULL)
+ {
+ char *homedir = getenv("HOME");
+ if (homedir == NULL)
+ {
+ homedir = "/";
+ }
+
+ tmp_env = M_StringJoin(homedir, "/.local/share", NULL);
+ env = tmp_env;
+ }
+
+ // We support $XDG_DATA_HOME/games/doom (which will usually be
+ // ~/.local/share/games/doom) as a user-writeable extension to
+ // the usual /usr/share/games/doom location.
+ AddIWADDir(M_StringJoin(env, "/games/doom", NULL));
+ free(tmp_env);
+
+ // Quote:
+ // > $XDG_DATA_DIRS defines the preference-ordered set of base
+ // > directories to search for data files in addition to the
+ // > $XDG_DATA_HOME base directory. The directories in $XDG_DATA_DIRS
+ // > should be seperated with a colon ':'.
+ // >
+ // > If $XDG_DATA_DIRS is either not set or empty, a value equal to
+ // > /usr/local/share/:/usr/share/ should be used.
+ env = getenv("XDG_DATA_DIRS");
+ if (env == NULL)
+ {
+ // (Trailing / omitted from paths, as it is added below)
+ env = "/usr/local/share:/usr/share";
+ }
+
+ // The "standard" location for IWADs on Unix that is supported by most
+ // source ports is /usr/share/games/doom - we support this through the
+ // XDG_DATA_DIRS mechanism, through which it can be overridden.
+ AddIWADPath(env, "/games/doom");
+}
+
//
// Build a list of IWAD files
//
@@ -565,7 +641,7 @@
static void BuildIWADDirList(void)
{
- char *doomwaddir;
+ char *env;
if (iwad_dirs_built)
{
@@ -573,28 +649,28 @@
}
// Look in the current directory. Doom always does this.
-
AddIWADDir(".");
// Add DOOMWADDIR if it is in the environment
+ env = getenv("DOOMWADDIR");
+ if (env != NULL)
+ {
+ AddIWADDir(env);
+ }
- doomwaddir = getenv("DOOMWADDIR");
-
- if (doomwaddir != NULL)
+ // Add dirs from DOOMWADPATH:
+ env = getenv("DOOMWADPATH");
+ if (env != NULL)
{
- AddIWADDir(doomwaddir);
- }
+ AddIWADPath(env, "");
+ }
- // Add dirs from DOOMWADPATH
-
- AddDoomWadPath();
-
#ifdef _WIN32
// Search the registry and find where IWADs have been installed.
CheckUninstallStrings();
- CheckCollectorsEdition();
+ CheckInstallRootPaths();
CheckSteamEdition();
CheckDOSDefaults();
@@ -603,12 +679,7 @@
CheckSteamGUSPatches();
#else
-
- // Standard places where IWAD files are installed under Unix.
-
- AddIWADDir("/usr/share/games/doom");
- AddIWADDir("/usr/local/share/games/doom");
-
+ AddXdgDirs();
#endif
// Don't run this function again.
--- a/src/deh_io.c
+++ b/src/deh_io.c
@@ -120,7 +120,7 @@
context->input_buffer_pos = 0;
context->filename = malloc(9);
- M_StringCopy(context->filename, lumpinfo[lumpnum].name, 9);
+ M_StringCopy(context->filename, lumpinfo[lumpnum]->name, 9);
return context;
}
--- /dev/null
+++ b/src/doom.appdata.xml.in
@@ -1,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<component type="desktop">
+ <id>@PROGRAM_PREFIX@doom.desktop</id>
+ <metadata_license>CC0-1.0</metadata_license>
+ <project_license>GPL-2.0+</project_license>
+ <developer_name>@PACKAGE_MAINTAINER@</developer_name>
+ <url type="homepage">@PACKAGE_URL@</url>
+ <url type="bugtracker">@PACKAGE_ISSUES@</url>
+ <description>
+ <p>
+ @PACKAGE_SHORTNAME@ Doom is a conservative,
+ historically-accurate Doom source port, which is compatible with
+ the thousands of mods and levels that were made before the Doom
+ source code was released. Unlike other source ports, the goal
+ is to preserve the original look, feel, limitations, and bugs of
+ the original DOS executable.
+ </p>
+ <p>
+ Full support for single- and multi-player games is provided, for
+ all of the original Doom games, Chex Quest, and Hacx. Unlike
+ the original executable, network play is implemented on the IP
+ network stack, allowing it to function on modern LANs and the
+ Internet.
+ </p>
+ </description>
+ <screenshots>
+ <screenshot type="default">
+ <image>http://www.chocolate-doom.org/wiki/images/9/97/GNOME_FreeDM_DEMO4.png</image>
+ <caption>FreeDM, DM05: Metal</caption>
+ </screenshot>
+ <screenshot>
+ <image>http://www.chocolate-doom.org/wiki/images/a/a6/GNOME_Doom_II_DEMO2.png</image>
+ <caption>Doom II, Level 5: The Waste Tunnels</caption>
+ </screenshot>
+ <screenshot>
+ <image>http://www.chocolate-doom.org/wiki/images/4/41/GNOME_Doomsday_of_UAC.png</image>
+ <caption>Doomsday of UAC (uac_dead.wad)</caption>
+ </screenshot>
+ <screenshot>
+ <image>http://www.chocolate-doom.org/wiki/images/2/2a/GNOME_Freedoom_DTWID_DEMO3.png</image>
+ <caption>Doom the Way id Did, on Freedoom. Level 3-2: City of Corpses</caption>
+ </screenshot>
+ </screenshots>
+</component>
--- a/src/doom/d_main.c
+++ b/src/doom/d_main.c
@@ -739,12 +739,12 @@
for (i=0; i<numlumps; ++i)
{
- if (!strncasecmp(lumpinfo[i].name, "MAP01", 8))
+ if (!strncasecmp(lumpinfo[i]->name, "MAP01", 8))
{
gamemission = doom2;
break;
}
- else if (!strncasecmp(lumpinfo[i].name, "E1M1", 8))
+ else if (!strncasecmp(lumpinfo[i]->name, "E1M1", 8))
{
gamemission = doom;
break;
@@ -954,7 +954,7 @@
static void InitGameVersion(void)
{
byte *demolump;
- byte demolumpname[6];
+ char demolumpname[6];
int demoversion;
int p;
int i;
@@ -1531,7 +1531,7 @@
if (D_AddFile(file))
{
- M_StringCopy(demolumpname, lumpinfo[numlumps - 1].name,
+ M_StringCopy(demolumpname, lumpinfo[numlumps - 1]->name,
sizeof(demolumpname));
}
else
@@ -1566,7 +1566,7 @@
for (i = numiwadlumps; i < numlumps; ++i)
{
- if (!strncmp(lumpinfo[i].name, "DEHACKED", 8))
+ if (!strncmp(lumpinfo[i]->name, "DEHACKED", 8))
{
DEH_LoadLump(i, false, false);
loaded++;
--- a/src/doom/g_game.c
+++ b/src/doom/g_game.c
@@ -614,7 +614,8 @@
// The "Sky never changes in Doom II" bug was fixed in
// the id Anthology version of doom2.exe for Final Doom.
- if ((gamemode == commercial) && (gameversion == exe_final2))
+ if ((gamemode == commercial)
+ && (gameversion == exe_final2 || gameversion == exe_chex))
{
char *skytexturename;
--- a/src/doom/hu_stuff.c
+++ b/src/doom/hu_stuff.c
@@ -48,7 +48,7 @@
#define HU_TITLE2 (mapnames_commercial[gamemap-1])
#define HU_TITLEP (mapnames_commercial[gamemap-1 + 32])
#define HU_TITLET (mapnames_commercial[gamemap-1 + 64])
-#define HU_TITLE_CHEX (mapnames[gamemap - 1])
+#define HU_TITLE_CHEX (mapnames_chex[(gameepisode-1)*9+gamemap-1])
#define HU_TITLEHEIGHT 1
#define HU_TITLEX 0
#define HU_TITLEY (167 - SHORT(hu_font[0]->height))
@@ -163,6 +163,60 @@
"NEWLEVEL"
};
+char* mapnames_chex[] = // Chex Quest names.
+{
+
+ HUSTR_E1M1,
+ HUSTR_E1M2,
+ HUSTR_E1M3,
+ HUSTR_E1M4,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+ HUSTR_E1M5,
+
+ "NEWLEVEL",
+ "NEWLEVEL",
+ "NEWLEVEL",
+ "NEWLEVEL",
+ "NEWLEVEL",
+ "NEWLEVEL",
+ "NEWLEVEL",
+ "NEWLEVEL",
+ "NEWLEVEL"
+};
+
// List of names for levels in commercial IWADs
// (doom2.wad, plutonia.wad, tnt.wad). These are stored in a
// single large array; WADs like pl2.wad have a MAP33, and rely on
@@ -351,10 +405,7 @@
break;
}
- // Chex.exe always uses the episode 1 level title
- // eg. E2M1 gives the title for E1M1
-
- if (gameversion == exe_chex)
+ if (logical_gamemission == doom && gameversion == exe_chex)
{
s = HU_TITLE_CHEX;
}
--- a/src/doom/r_data.c
+++ b/src/doom/r_data.c
@@ -832,7 +832,7 @@
if (flatpresent[i])
{
lump = firstflat + i;
- flatmemory += lumpinfo[lump].size;
+ flatmemory += lumpinfo[lump]->size;
W_CacheLumpNum(lump, PU_CACHE);
}
}
@@ -869,7 +869,7 @@
for (j=0 ; j<texture->patchcount ; j++)
{
lump = texture->patches[j].patch;
- texturememory += lumpinfo[lump].size;
+ texturememory += lumpinfo[lump]->size;
W_CacheLumpNum(lump , PU_CACHE);
}
}
@@ -898,7 +898,7 @@
for (k=0 ; k<8 ; k++)
{
lump = firstspritelump + sf->lump[k];
- spritememory += lumpinfo[lump].size;
+ spritememory += lumpinfo[lump]->size;
W_CacheLumpNum(lump , PU_CACHE);
}
}
--- a/src/doom/r_things.c
+++ b/src/doom/r_things.c
@@ -208,22 +208,22 @@
// filling in the frames for whatever is found
for (l=start+1 ; l<end ; l++)
{
- if (!strncasecmp(lumpinfo[l].name, spritename, 4))
+ if (!strncasecmp(lumpinfo[l]->name, spritename, 4))
{
- frame = lumpinfo[l].name[4] - 'A';
- rotation = lumpinfo[l].name[5] - '0';
+ frame = lumpinfo[l]->name[4] - 'A';
+ rotation = lumpinfo[l]->name[5] - '0';
if (modifiedgame)
- patched = W_GetNumForName (lumpinfo[l].name);
+ patched = W_GetNumForName (lumpinfo[l]->name);
else
patched = l;
R_InstallSpriteLump (patched, frame, rotation, false);
- if (lumpinfo[l].name[6])
+ if (lumpinfo[l]->name[6])
{
- frame = lumpinfo[l].name[6] - 'A';
- rotation = lumpinfo[l].name[7] - '0';
+ frame = lumpinfo[l]->name[6] - 'A';
+ rotation = lumpinfo[l]->name[7] - '0';
R_InstallSpriteLump (l, frame, rotation, true);
}
}
--- a/src/doom/st_stuff.c
+++ b/src/doom/st_stuff.c
@@ -618,13 +618,20 @@
{
epsd = buf[0] - '0';
map = buf[1] - '0';
- }
- // Chex.exe always warps to episode 1.
+ // Chex.exe always warps to episode 1.
- if (gameversion == exe_chex)
- {
- epsd = 1;
+ if (gameversion == exe_chex)
+ {
+ if (epsd > 1)
+ {
+ epsd = 1;
+ }
+ if (map > 5)
+ {
+ map = 5;
+ }
+ }
}
// Catch invalid maps.
--- a/src/doomtype.h
+++ b/src/doomtype.h
@@ -51,7 +51,13 @@
//
#ifdef __GNUC__
+
+#ifdef __clang__
#define PACKEDATTR __attribute__((packed))
+#else
+#define PACKEDATTR __attribute__((packed,gcc_struct))
+#endif
+
#else
#define PACKEDATTR
#endif
--- /dev/null
+++ b/src/heretic.appdata.xml.in
@@ -1,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<component type="desktop">
+ <id>@PROGRAM_PREFIX@heretic.desktop</id>
+ <metadata_license>CC0-1.0</metadata_license>
+ <project_license>GPL-2.0+</project_license>
+ <developer_name>@PACKAGE_MAINTAINER@</developer_name>
+ <url type="homepage">@PACKAGE_URL@</url>
+ <url type="bugtracker">@PACKAGE_ISSUES@</url>
+ <description>
+ <p>
+ @PACKAGE_SHORTNAME@ Heretic is a conservative,
+ historically-accurate Heretic source port, which is compatible
+ with mods and levels that were made before the Heretic source
+ code was released. Unlike other source ports, the goal is to
+ preserve the original look, feel, limitations, and bugs of the
+ original DOS executable.
+ </p>
+ <p>
+ Full support for single- and multi-player games is provided.
+ Unlike the original executable, network play is implemented on
+ the IP network stack, allowing it to function on modern LANs and
+ the Internet.
+ </p>
+ </description>
+ <screenshots>
+ <screenshot type="default">
+ <image>http://www.chocolate-doom.org/wiki/images/9/93/GNOME_Heretic_E5M4.png</image>
+ <caption>Level E5M4: Courtyard</caption>
+ </screenshot>
+ <screenshot>
+ <image>http://www.chocolate-doom.org/wiki/images/1/14/GNOME_Heretic_Shareware_DEMO3.png</image>
+ <caption>Shareware Level E1M9: The Graveyard</caption>
+ </screenshot>
+ <screenshot>
+ <image>http://www.chocolate-doom.org/wiki/images/3/34/GNOME_Heretic_E4M1.png</image>
+ <caption>Level E4M1: Catafalque</caption>
+ </screenshot>
+ <screenshot>
+ <image>http://www.chocolate-doom.org/wiki/images/4/42/GNOME_Heretic_Shareware_DEMO1.png</image>
+ <caption>Shareware Level E1M3: The Gatehouse</caption>
+ </screenshot>
+ </screenshots>
+</component>
--- a/src/heretic/d_main.c
+++ b/src/heretic/d_main.c
@@ -62,7 +62,6 @@
boolean debugmode; // checkparm of -debug
boolean ravpic; // checkparm of -ravpic
boolean cdrom; // true if cd-rom mode active
-boolean singletics; // debug flag to cancel adaptiveness
boolean noartiskip; // whether shift-enter skips an artifact
skill_t startskill;
@@ -1019,7 +1018,7 @@
if (D_AddFile(file))
{
- M_StringCopy(demolumpname, lumpinfo[numlumps - 1].name,
+ M_StringCopy(demolumpname, lumpinfo[numlumps - 1]->name,
sizeof(demolumpname));
}
else
--- a/src/heretic/g_game.c
+++ b/src/heretic/g_game.c
@@ -102,7 +102,6 @@
int consoleplayer; // player taking events and displaying
int displayplayer; // view being displayed
-int gametic;
int levelstarttic; // gametic at level start
int totalkills, totalitems, totalsecret; // for intermission
--- a/src/heretic/r_data.c
+++ b/src/heretic/r_data.c
@@ -671,7 +671,7 @@
if (flatpresent[i])
{
lump = firstflat + i;
- flatmemory += lumpinfo[lump].size;
+ flatmemory += lumpinfo[lump]->size;
W_CacheLumpNum(lump, PU_CACHE);
}
@@ -701,7 +701,7 @@
for (j = 0; j < texture->patchcount; j++)
{
lump = texture->patches[j].patch;
- texturememory += lumpinfo[lump].size;
+ texturememory += lumpinfo[lump]->size;
W_CacheLumpNum(lump, PU_CACHE);
}
}
@@ -731,7 +731,7 @@
for (k = 0; k < 8; k++)
{
lump = firstspritelump + sf->lump[k];
- spritememory += lumpinfo[lump].size;
+ spritememory += lumpinfo[lump]->size;
W_CacheLumpNum(lump, PU_CACHE);
}
}
--- a/src/heretic/r_things.c
+++ b/src/heretic/r_things.c
@@ -175,15 +175,15 @@
// scan the lumps, filling in the frames for whatever is found
//
for (l = start + 1; l < end; l++)
- if (!strncasecmp(lumpinfo[l].name, spritename, 4))
+ if (!strncasecmp(lumpinfo[l]->name, spritename, 4))
{
- frame = lumpinfo[l].name[4] - 'A';
- rotation = lumpinfo[l].name[5] - '0';
+ frame = lumpinfo[l]->name[4] - 'A';
+ rotation = lumpinfo[l]->name[5] - '0';
R_InstallSpriteLump(l, frame, rotation, false);
- if (lumpinfo[l].name[6])
+ if (lumpinfo[l]->name[6])
{
- frame = lumpinfo[l].name[6] - 'A';
- rotation = lumpinfo[l].name[7] - '0';
+ frame = lumpinfo[l]->name[6] - 'A';
+ rotation = lumpinfo[l]->name[7] - '0';
R_InstallSpriteLump(l, frame, rotation, true);
}
}
--- /dev/null
+++ b/src/hexen.appdata.xml.in
@@ -1,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<component type="desktop">
+ <id>@PROGRAM_PREFIX@hexen.desktop</id>
+ <metadata_license>CC0-1.0</metadata_license>
+ <project_license>GPL-2.0+</project_license>
+ <developer_name>@PACKAGE_MAINTAINER@</developer_name>
+ <url type="homepage">@PACKAGE_URL@</url>
+ <url type="bugtracker">@PACKAGE_ISSUES@</url>
+ <description>
+ <p>
+ @PACKAGE_SHORTNAME@ Hexen is a conservative,
+ historically-accurate Hexen source port, which is compatible
+ with mods and levels that were made before the Hexen source code
+ was released. Unlike other source ports, the goal is to
+ preserve the original look, feel, limitations, and bugs of the
+ original DOS executable.
+ </p>
+ <p>
+ Full support for single- and multi-player games is provided.
+ Unlike the original executable, network play is implemented on
+ the IP network stack, allowing it to function on modern LANs and
+ the Internet.
+ </p>
+ </description>
+ <screenshots>
+ <screenshot type="default">
+ <image>http://www.chocolate-doom.org/wiki/images/0/0f/GNOME_Hexen_Guardian_of_Fire.png</image>
+ <caption>Level "Guardian of Fire"</caption>
+ </screenshot>
+ <screenshot>
+ <image>http://www.chocolate-doom.org/wiki/images/5/5c/GNOME_Hexen_Effluvium.png</image>
+ <caption>Level "Effluvium"</caption>
+ </screenshot>
+ <screenshot>
+ <image>http://www.chocolate-doom.org/wiki/images/c/c1/GNOME_Hexen_Dragon_Chapel.png</image>
+ <caption>Level "Dragon Chapel"</caption>
+ </screenshot>
+ <screenshot>
+ <image>http://www.chocolate-doom.org/wiki/images/a/a7/GNOME_Hexen_Darkmere.png</image>
+ <caption>Level "Darkmere"</caption>
+ </screenshot>
+ </screenshots>
+</component>
--- a/src/hexen/g_game.c
+++ b/src/hexen/g_game.c
@@ -88,7 +88,6 @@
int consoleplayer; // player taking events and displaying
int displayplayer; // view being displayed
-int gametic;
int levelstarttic; // gametic at level start
char demoname[32];
--- a/src/hexen/h2_main.c
+++ b/src/hexen/h2_main.c
@@ -103,7 +103,6 @@
boolean ravpic; // checkparm of -ravpic
boolean cdrom = false; // true if cd-rom mode active
boolean cmdfrag; // true if a CMD_FRAG packet should be sent out
-boolean singletics; // debug flag to cancel adaptiveness
boolean artiskip; // whether shift-enter skips an artifact
int maxzone = 0x800000; // Maximum allocated for zone heap (8meg default)
skill_t startskill;
@@ -664,7 +663,7 @@
if (W_AddFile(file) != NULL)
{
- M_StringCopy(demolumpname, lumpinfo[numlumps - 1].name,
+ M_StringCopy(demolumpname, lumpinfo[numlumps - 1]->name,
sizeof(demolumpname));
}
else
--- a/src/hexen/r_data.c
+++ b/src/hexen/r_data.c
@@ -627,7 +627,7 @@
if (flatpresent[i])
{
lump = firstflat + i;
- flatmemory += lumpinfo[lump].size;
+ flatmemory += lumpinfo[lump]->size;
W_CacheLumpNum(lump, PU_CACHE);
}
@@ -658,7 +658,7 @@
for (j = 0; j < texture->patchcount; j++)
{
lump = texture->patches[j].patch;
- texturememory += lumpinfo[lump].size;
+ texturememory += lumpinfo[lump]->size;
W_CacheLumpNum(lump, PU_CACHE);
}
}
@@ -688,7 +688,7 @@
for (k = 0; k < 8; k++)
{
lump = firstspritelump + sf->lump[k];
- spritememory += lumpinfo[lump].size;
+ spritememory += lumpinfo[lump]->size;
W_CacheLumpNum(lump, PU_CACHE);
}
}
--- a/src/hexen/r_things.c
+++ b/src/hexen/r_things.c
@@ -178,15 +178,15 @@
// scan the lumps, filling in the frames for whatever is found
//
for (l = start + 1; l < end; l++)
- if (!strncmp(lumpinfo[l].name, namelist[i], 4))
+ if (!strncmp(lumpinfo[l]->name, namelist[i], 4))
{
- frame = lumpinfo[l].name[4] - 'A';
- rotation = lumpinfo[l].name[5] - '0';
+ frame = lumpinfo[l]->name[4] - 'A';
+ rotation = lumpinfo[l]->name[5] - '0';
R_InstallSpriteLump(l, frame, rotation, false);
- if (lumpinfo[l].name[6])
+ if (lumpinfo[l]->name[6])
{
- frame = lumpinfo[l].name[6] - 'A';
- rotation = lumpinfo[l].name[7] - '0';
+ frame = lumpinfo[l]->name[6] - 'A';
+ rotation = lumpinfo[l]->name[7] - '0';
R_InstallSpriteLump(l, frame, rotation, true);
}
}
--- a/src/i_oplmusic.c
+++ b/src/i_oplmusic.c
@@ -352,6 +352,12 @@
char *snd_dmxoption = "";
int opl_io_port = 0x388;
+// If true, OPL sound channels are reversed to their correct arrangement
+// (as intended by the MIDI standard) rather than the backwards one
+// used by DMX due to a bug.
+
+static boolean opl_stereo_correct = false;
+
// Load instrument table from GENMIDI lump:
static boolean LoadInstrumentTable(void)
@@ -1133,6 +1139,16 @@
unsigned int reg_pan;
unsigned int i;
+ // The DMX library has the stereo channels backwards, maybe because
+ // Paul Radek had a Soundblaster card with the channels reversed, or
+ // perhaps it was just a bug in the OPL3 support that was never
+ // finished. By default we preserve this bug, but we also provide a
+ // secret DMXOPTION to fix it.
+ if (opl_stereo_correct)
+ {
+ pan = 144 - pan;
+ }
+
if (opl_opl3mode)
{
if (pan >= 96)
@@ -1727,6 +1743,10 @@
opl_opl3mode = 0;
num_opl_voices = OPL_NUM_VOICES;
}
+
+ // Secret, undocumented DMXOPTION that reverses the stereo channels
+ // into their correct orientation.
+ opl_stereo_correct = strstr(dmxoption, "-reverse") != NULL;
// Initialize all registers.
--- a/src/i_sdlmusic.c
+++ b/src/i_sdlmusic.c
@@ -752,7 +752,7 @@
for (lumpnum = 0; lumpnum < numlumps; ++lumpnum)
{
- strncpy(name, lumpinfo[lumpnum].name, 8);
+ strncpy(name, lumpinfo[lumpnum]->name, 8);
name[8] = '\0';
if (!IsMusicLump(lumpnum))
--- a/src/setup/mainmenu.c
+++ b/src/setup/mainmenu.c
@@ -91,7 +91,7 @@
show_endoom = 0;
dclick_use = 0;
novert = 1;
- snd_dmxoption = "-opl3";
+ snd_dmxoption = "-opl3 -reverse";
png_screenshots = 1;
}
--- a/src/setup/setup-manifest.xml.in
+++ b/src/setup/setup-manifest.xml.in
@@ -32,6 +32,7 @@
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> <!-- Vista -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> <!-- 8 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> <!-- 8.1 -->
+ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> <!-- 10 -->
</application>
</compatibility>
--- /dev/null
+++ b/src/strife.appdata.xml.in
@@ -1,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<component type="desktop">
+ <id>@PROGRAM_PREFIX@strife.desktop</id>
+ <metadata_license>CC0-1.0</metadata_license>
+ <project_license>GPL-2.0+</project_license>
+ <developer_name>@PACKAGE_MAINTAINER@</developer_name>
+ <url type="homepage">@PACKAGE_URL@</url>
+ <url type="bugtracker">@PACKAGE_ISSUES@</url>
+ <description>
+ <p>
+ @PACKAGE_SHORTNAME@ Strife is a conservative,
+ historically-accurate recreation of the Strife engine. It is
+ completely compatible with the original game and mods created
+ with the original engine in mind. Made with a great reverse
+ engineering effort, it has the goal of preserving the original
+ look, feel, limitations, and bugs of the original DOS
+ executable.
+ </p>
+ <p>
+ Full support for single- and multi-player games is provided.
+ Unlike the original executable, network play is implemented on
+ the IP network stack, allowing it to function on modern LANs and
+ the Internet.
+ </p>
+ </description>
+ <screenshots>
+ <screenshot type="default">
+ <image>http://www.chocolate-doom.org/wiki/images/b/b2/GNOME_Strife_Rowan.png</image>
+ <caption>Talking to Rowan</caption>
+ </screenshot>
+ <screenshot>
+ <image>http://www.chocolate-doom.org/wiki/images/1/1f/GNOME_Strife_Town.png</image>
+ <caption>The Town</caption>
+ </screenshot>
+ <screenshot>
+ <image>http://www.chocolate-doom.org/wiki/images/8/8a/GNOME_Strife_Opening.png</image>
+ <caption>Opening Cinematic</caption>
+ </screenshot>
+ <screenshot>
+ <image>http://www.chocolate-doom.org/wiki/images/c/c4/GNOME_Strife_Sewage.png</image>
+ <caption>In the sewage</caption>
+ </screenshot>
+ </screenshots>
+</component>
--- a/src/strife/d_main.c
+++ b/src/strife/d_main.c
@@ -1629,7 +1629,7 @@
if (D_AddFile (file))
{
- M_StringCopy(demolumpname, lumpinfo[numlumps - 1].name,
+ M_StringCopy(demolumpname, lumpinfo[numlumps - 1]->name,
sizeof(demolumpname));
}
else
--- a/src/strife/g_game.c
+++ b/src/strife/g_game.c
@@ -124,7 +124,6 @@
int consoleplayer; // player taking events and displaying
int displayplayer; // view being displayed
-int gametic;
int levelstarttic; // gametic at level start
int totalkills, /*totalitems,*/ totalsecret; // for intermission
--- a/src/strife/r_data.c
+++ b/src/strife/r_data.c
@@ -938,7 +938,7 @@
if (flatpresent[i])
{
lump = firstflat + i;
- flatmemory += lumpinfo[lump].size;
+ flatmemory += lumpinfo[lump]->size;
W_CacheLumpNum(lump, PU_CACHE);
}
}
@@ -975,7 +975,7 @@
for (j=0 ; j<texture->patchcount ; j++)
{
lump = texture->patches[j].patch;
- texturememory += lumpinfo[lump].size;
+ texturememory += lumpinfo[lump]->size;
W_CacheLumpNum(lump , PU_CACHE);
}
}
@@ -1004,7 +1004,7 @@
for (k=0 ; k<8 ; k++)
{
lump = firstspritelump + sf->lump[k];
- spritememory += lumpinfo[lump].size;
+ spritememory += lumpinfo[lump]->size;
W_CacheLumpNum(lump , PU_CACHE);
}
}
--- a/src/strife/r_things.c
+++ b/src/strife/r_things.c
@@ -211,22 +211,22 @@
// filling in the frames for whatever is found
for (l=start+1 ; l<end ; l++)
{
- if (!strncasecmp(lumpinfo[l].name, spritename, 4))
+ if (!strncasecmp(lumpinfo[l]->name, spritename, 4))
{
- frame = lumpinfo[l].name[4] - 'A';
- rotation = lumpinfo[l].name[5] - '0';
+ frame = lumpinfo[l]->name[4] - 'A';
+ rotation = lumpinfo[l]->name[5] - '0';
if (modifiedgame)
- patched = W_GetNumForName (lumpinfo[l].name);
+ patched = W_GetNumForName (lumpinfo[l]->name);
else
patched = l;
R_InstallSpriteLump (patched, frame, rotation, false);
- if (lumpinfo[l].name[6])
+ if (lumpinfo[l]->name[6])
{
- frame = lumpinfo[l].name[6] - 'A';
- rotation = lumpinfo[l].name[7] - '0';
+ frame = lumpinfo[l]->name[6] - 'A';
+ rotation = lumpinfo[l]->name[7] - '0';
R_InstallSpriteLump (l, frame, rotation, true);
}
}
--- a/src/w_checksum.c
+++ b/src/w_checksum.c
@@ -33,7 +33,7 @@
int i;
int result;
- for (i=0; i<num_open_wadfiles; ++i)
+ for (i = 0; i < num_open_wadfiles; ++i)
{
if (open_wadfiles[i] == handle)
{
@@ -77,11 +77,11 @@
// Go through each entry in the WAD directory, adding information
// about each entry to the SHA1 hash.
- for (i=0; i<numlumps; ++i)
+ for (i = 0; i < numlumps; ++i)
{
- ChecksumAddLump(&sha1_context, &lumpinfo[i]);
+ ChecksumAddLump(&sha1_context, lumpinfo[i]);
}
-
+
SHA1_Final(digest, &sha1_context);
}
--- a/src/w_main.c
+++ b/src/w_main.c
@@ -16,8 +16,10 @@
// Common code to parse command line, identifying WAD files to load.
//
+#include "config.h"
#include "doomfeatures.h"
#include "d_iwad.h"
+#include "i_system.h"
#include "m_argv.h"
#include "w_main.h"
#include "w_merge.h"
@@ -26,7 +28,6 @@
// Parse the command line, merging WAD files that are sppecified.
// Returns true if at least one file was added.
-
boolean W_ParseCommandLine(void)
{
boolean modifiedgame = false;
@@ -194,5 +195,46 @@
// W_PrintDirectory();
return modifiedgame;
+}
+
+// Lump names that are unique to particular game types. This lets us check
+// the user is not trying to play with the wrong executable, eg.
+// chocolate-doom -iwad hexen.wad.
+static const struct
+{
+ GameMission_t mission;
+ char *lumpname;
+} unique_lumps[] = {
+ { doom, "POSSA1" },
+ { heretic, "IMPXA1" },
+ { hexen, "ETTNA1" },
+ { strife, "AGRDA1" },
+};
+
+void W_CheckCorrectIWAD(GameMission_t mission)
+{
+ int i;
+ lumpindex_t lumpnum;
+
+ for (i = 0; i < arrlen(unique_lumps); ++i)
+ {
+ if (mission != unique_lumps[i].mission)
+ {
+ lumpnum = W_CheckNumForName(unique_lumps[i].lumpname);
+
+ if (lumpnum >= 0)
+ {
+ I_Error("\nYou are trying to use a %s IWAD file with "
+ "the %s%s binary.\nThis isn't going to work.\n"
+ "You probably want to use the %s%s binary.",
+ D_SuggestGameName(unique_lumps[i].mission,
+ indetermined),
+ PROGRAM_PREFIX,
+ D_GameMissionString(mission),
+ PROGRAM_PREFIX,
+ D_GameMissionString(unique_lumps[i].mission));
+ }
+ }
+ }
}
--- a/src/w_main.h
+++ b/src/w_main.h
@@ -18,7 +18,10 @@
#ifndef W_MAIN_H
#define W_MAIN_H
+#include "d_mode.h"
+
boolean W_ParseCommandLine(void);
+void W_CheckCorrectIWAD(GameMission_t mission);
#endif /* #ifndef W_MAIN_H */
--- a/src/w_merge.c
+++ b/src/w_merge.c
@@ -39,7 +39,7 @@
typedef struct
{
- lumpinfo_t *lumps;
+ lumpinfo_t **lumps;
int numlumps;
} searchlist_t;
@@ -74,7 +74,7 @@
for (i=0; i<list->numlumps; ++i)
{
- if (!strncasecmp(list->lumps[i].name, name, 8))
+ if (!strncasecmp(list->lumps[i]->name, name, 8))
return i;
}
@@ -352,7 +352,7 @@
for (i=0; i<iwad_sprites.numlumps; ++i)
{
- AddSpriteLump(&iwad_sprites.lumps[i]);
+ AddSpriteLump(iwad_sprites.lumps[i]);
}
// Add all sprites from the PWAD
@@ -360,7 +360,7 @@
for (i=0; i<pwad_sprites.numlumps; ++i)
{
- AddSpriteLump(&pwad_sprites.lumps[i]);
+ AddSpriteLump(pwad_sprites.lumps[i]);
}
}
@@ -386,13 +386,13 @@
static void DoMerge(void)
{
section_t current_section;
- lumpinfo_t *newlumps;
+ lumpinfo_t **newlumps;
int num_newlumps;
int lumpindex;
int i, n;
-
+
// Can't ever have more lumps than we already have
- newlumps = malloc(sizeof(lumpinfo_t) * numlumps);
+ newlumps = calloc(numlumps, sizeof(lumpinfo_t *));
num_newlumps = 0;
// Add IWAD lumps
@@ -400,7 +400,7 @@
for (i=0; i<iwad.numlumps; ++i)
{
- lumpinfo_t *lump = &iwad.lumps[i];
+ lumpinfo_t *lump = iwad.lumps[i];
switch (current_section)
{
@@ -414,7 +414,7 @@
current_section = SECTION_SPRITES;
}
- newlumps[num_newlumps++] = *lump;
+ newlumps[num_newlumps++] = lump;
break;
@@ -432,7 +432,7 @@
newlumps[num_newlumps++] = pwad_flats.lumps[n];
}
- newlumps[num_newlumps++] = *lump;
+ newlumps[num_newlumps++] = lump;
// back to normal reading
current_section = SECTION_NORMAL;
@@ -448,7 +448,7 @@
if (lumpindex < 0)
{
- newlumps[num_newlumps++] = *lump;
+ newlumps[num_newlumps++] = lump;
}
}
@@ -460,11 +460,11 @@
if (!strncasecmp(lump->name, "S_END", 8))
{
- // add all the pwad sprites
+ // add all the PWAD sprites
for (n=0; n<pwad_sprites.numlumps; ++n)
{
- if (SpriteLumpNeeded(&pwad_sprites.lumps[n]))
+ if (SpriteLumpNeeded(pwad_sprites.lumps[n]))
{
newlumps[num_newlumps++] = pwad_sprites.lumps[n];
}
@@ -471,7 +471,7 @@
}
// copy the ending
- newlumps[num_newlumps++] = *lump;
+ newlumps[num_newlumps++] = lump;
// back to normal reading
current_section = SECTION_NORMAL;
@@ -483,7 +483,7 @@
if (SpriteLumpNeeded(lump))
{
- newlumps[num_newlumps++] = *lump;
+ newlumps[num_newlumps++] = lump;
}
}
@@ -496,7 +496,7 @@
for (i=0; i<pwad.numlumps; ++i)
{
- lumpinfo_t *lump = &pwad.lumps[i];
+ lumpinfo_t *lump = pwad.lumps[i];
switch (current_section)
{
@@ -515,7 +515,7 @@
{
// Don't include the headers of sections
- newlumps[num_newlumps++] = *lump;
+ newlumps[num_newlumps++] = lump;
}
break;
@@ -550,7 +550,6 @@
free(lumpinfo);
lumpinfo = newlumps;
numlumps = num_newlumps;
-
}
void W_PrintDirectory(void)
@@ -560,8 +559,8 @@
// debug
for (i=0; i<numlumps; ++i)
{
- for (n=0; n<8 && lumpinfo[i].name[n] != '\0'; ++n)
- putchar(lumpinfo[i].name[n]);
+ for (n=0; n<8 && lumpinfo[i]->name[n] != '\0'; ++n)
+ putchar(lumpinfo[i]->name[n]);
putchar('\n');
}
}
@@ -579,7 +578,7 @@
if (W_AddFile(filename) == NULL)
return;
- // iwad is at the start, pwad was appended to the end
+ // IWAD is at the start, PWAD was appended to the end
iwad.lumps = lumpinfo;
iwad.numlumps = old_numlumps;
@@ -606,25 +605,23 @@
{
int i;
- // Go through the IWAD list given, replacing lumps with lumps of
+ // Go through the IWAD list given, replacing lumps with lumps of
// the same name from the PWAD
-
for (i=0; i<list->numlumps; ++i)
{
int index;
- index = FindInList(&pwad, list->lumps[i].name);
+ index = FindInList(&pwad, list->lumps[i]->name);
if (index > 0)
{
- memcpy(&list->lumps[i], &pwad.lumps[index],
+ memcpy(list->lumps[i], pwad.lumps[index],
sizeof(lumpinfo_t));
}
}
-
}
-// Merge sprites and flats in the way NWT does with its -af and -as
+// Merge sprites and flats in the way NWT does with its -af and -as
// command-line options.
void W_NWTMergeFile(char *filename, int flags)
@@ -638,7 +635,7 @@
if (W_AddFile(filename) == NULL)
return;
- // iwad is at the start, pwad was appended to the end
+ // IWAD is at the start, PWAD was appended to the end
iwad.lumps = lumpinfo;
iwad.numlumps = old_numlumps;
@@ -645,13 +642,13 @@
pwad.lumps = lumpinfo + old_numlumps;
pwad.numlumps = numlumps - old_numlumps;
-
+
// Setup sprite/flat lists
SetupLists();
// Merge in flats?
-
+
if (flags & W_NWT_MERGE_FLATS)
{
W_NWTAddLumps(&iwad_flats);
@@ -690,7 +687,7 @@
return;
}
- // iwad is at the start, pwad was appended to the end
+ // IWAD is at the start, PWAD was appended to the end
iwad.lumps = lumpinfo;
iwad.numlumps = old_numlumps;
@@ -697,7 +694,7 @@
pwad.lumps = lumpinfo + old_numlumps;
pwad.numlumps = numlumps - old_numlumps;
-
+
// Setup sprite/flat lists
SetupLists();
@@ -706,12 +703,12 @@
for (i=0; i<iwad_sprites.numlumps; ++i)
{
- if (FindInList(&pwad, iwad_sprites.lumps[i].name) >= 0)
+ if (FindInList(&pwad, iwad_sprites.lumps[i]->name) >= 0)
{
// Replace this entry with an empty string. This is what
// nwt -merge does.
- M_StringCopy(iwad_sprites.lumps[i].name, "", 8);
+ M_StringCopy(iwad_sprites.lumps[i]->name, "", 8);
}
}
--- a/src/w_wad.c
+++ b/src/w_wad.c
@@ -26,8 +26,6 @@
#include "doomtype.h"
-#include "config.h"
-#include "d_iwad.h"
#include "i_swap.h"
#include "i_system.h"
#include "i_video.h"
@@ -57,16 +55,17 @@
//
// Location of each lump on disk.
-lumpinfo_t *lumpinfo;
+lumpinfo_t **lumpinfo;
unsigned int numlumps = 0;
// Hash table for fast lookups
-static lumpinfo_t **lumphash;
+static lumpindex_t *lumphash;
// Variables for the reload hack: filename of the PWAD to reload, and the
// lumps from WADs before the reload file, so we can resent numlumps and
// load the file again.
static wad_file_t *reloadhandle = NULL;
+static lumpinfo_t *reloadlumps = NULL;
static char *reloadname = NULL;
static int reloadlump = -1;
@@ -87,46 +86,6 @@
return result;
}
-// Increase the size of the lumpinfo[] array to the specified size.
-static void ExtendLumpInfo(int newnumlumps)
-{
- lumpinfo_t *newlumpinfo;
- unsigned int i;
-
- newlumpinfo = calloc(newnumlumps, sizeof(lumpinfo_t));
-
- if (newlumpinfo == NULL)
- {
- I_Error ("Couldn't realloc lumpinfo");
- }
-
- // Copy over lumpinfo_t structures from the old array. If any of
- // these lumps have been cached, we need to update the user
- // pointers to the new location.
- for (i = 0; i < numlumps && i < newnumlumps; ++i)
- {
- memcpy(&newlumpinfo[i], &lumpinfo[i], sizeof(lumpinfo_t));
-
- if (newlumpinfo[i].cache != NULL)
- {
- Z_ChangeUser(newlumpinfo[i].cache, &newlumpinfo[i].cache);
- }
-
- // We shouldn't be generating a hash table until after all WADs have
- // been loaded, but just in case...
- if (lumpinfo[i].next != NULL)
- {
- int nextlumpnum = lumpinfo[i].next - lumpinfo;
- newlumpinfo[i].next = &newlumpinfo[nextlumpnum];
- }
- }
-
- // All done.
- free(lumpinfo);
- lumpinfo = newlumpinfo;
- numlumps = newnumlumps;
-}
-
//
// LUMP BASED ROUTINES.
//
@@ -143,14 +102,14 @@
wad_file_t *W_AddFile (char *filename)
{
wadinfo_t header;
- lumpinfo_t *lump_p;
- unsigned int i;
+ lumpindex_t i;
wad_file_t *wad_file;
int length;
int startlump;
filelump_t *fileinfo;
filelump_t *filerover;
- int newnumlumps;
+ lumpinfo_t *filelumps;
+ int numfilelumps;
// If the filename begins with a ~, it indicates that we should use the
// reload hack.
@@ -180,15 +139,6 @@
return NULL;
}
- // If this is the reload file, we need to save the file handle so that we
- // can close it later on when we do a reload.
- if (reloadname)
- {
- reloadhandle = wad_file;
- }
-
- newnumlumps = numlumps;
-
if (strcasecmp(filename+strlen(filename)-3 , "wad" ) )
{
// single lump file
@@ -206,9 +156,9 @@
// extension).
M_ExtractFileBase (filename, fileinfo->name);
- newnumlumps++;
+ numfilelumps = 1;
}
- else
+ else
{
// WAD file
W_Read(wad_file, 0, &header, sizeof(header));
@@ -221,8 +171,8 @@
I_Error ("Wad file %s doesn't have IWAD "
"or PWAD id\n", filename);
}
-
- // ???modifiedgame = true;
+
+ // ???modifiedgame = true;
}
header.numlumps = LONG(header.numlumps);
@@ -231,26 +181,36 @@
fileinfo = Z_Malloc(length, PU_STATIC, 0);
W_Read(wad_file, header.infotableofs, fileinfo, length);
- newnumlumps += header.numlumps;
+ numfilelumps = header.numlumps;
}
// Increase size of numlumps array to accomodate the new file.
+ filelumps = calloc(numfilelumps, sizeof(lumpinfo_t));
+ if (filelumps == NULL)
+ {
+ I_Error("Failed to allocate array for lumps from new file.");
+ }
+
startlump = numlumps;
- ExtendLumpInfo(newnumlumps);
+ numlumps += numfilelumps;
+ lumpinfo = realloc(lumpinfo, numlumps * sizeof(lumpinfo_t *));
+ if (lumpinfo == NULL)
+ {
+ I_Error("Failed to increase lumpinfo[] array size.");
+ }
- lump_p = &lumpinfo[startlump];
-
filerover = fileinfo;
- for (i=startlump; i<numlumps; ++i)
+ for (i = startlump; i < numlumps; ++i)
{
- lump_p->wad_file = wad_file;
- lump_p->position = LONG(filerover->filepos);
- lump_p->size = LONG(filerover->size);
+ lumpinfo_t *lump_p = &filelumps[i - startlump];
+ lump_p->wad_file = wad_file;
+ lump_p->position = LONG(filerover->filepos);
+ lump_p->size = LONG(filerover->size);
lump_p->cache = NULL;
- strncpy(lump_p->name, filerover->name, 8);
+ strncpy(lump_p->name, filerover->name, 8);
+ lumpinfo[i] = lump_p;
- ++lump_p;
++filerover;
}
@@ -262,6 +222,14 @@
lumphash = NULL;
}
+ // If this is the reload file, we need to save some details about the
+ // file so that we can close it later on when we do a reload.
+ if (reloadname)
+ {
+ reloadhandle = wad_file;
+ reloadlumps = filelumps;
+ }
+
return wad_file;
}
@@ -282,10 +250,9 @@
// Returns -1 if name not found.
//
-int W_CheckNumForName (char* name)
+lumpindex_t W_CheckNumForName(char* name)
{
- lumpinfo_t *lump_p;
- int i;
+ lumpindex_t i;
// Do we have a hash table yet?
@@ -292,28 +259,28 @@
if (lumphash != NULL)
{
int hash;
-
+
// We do! Excellent.
hash = W_LumpNameHash(name) % numlumps;
-
- for (lump_p = lumphash[hash]; lump_p != NULL; lump_p = lump_p->next)
+
+ for (i = lumphash[hash]; i != -1; i = lumpinfo[i]->next)
{
- if (!strncasecmp(lump_p->name, name, 8))
+ if (!strncasecmp(lumpinfo[i]->name, name, 8))
{
- return lump_p - lumpinfo;
+ return i;
}
}
- }
+ }
else
{
// We don't have a hash table generate yet. Linear search :-(
- //
+ //
// scan backwards so patch lump files take precedence
- for (i=numlumps-1; i >= 0; --i)
+ for (i = numlumps - 1; i >= 0; --i)
{
- if (!strncasecmp(lumpinfo[i].name, name, 8))
+ if (!strncasecmp(lumpinfo[i]->name, name, 8))
{
return i;
}
@@ -332,12 +299,12 @@
// W_GetNumForName
// Calls W_CheckNumForName, but bombs out if not found.
//
-int W_GetNumForName (char* name)
+lumpindex_t W_GetNumForName(char* name)
{
- int i;
+ lumpindex_t i;
i = W_CheckNumForName (name);
-
+
if (i < 0)
{
I_Error ("W_GetNumForName: %s not found!", name);
@@ -351,7 +318,7 @@
// W_LumpLength
// Returns the buffer size needed to load the given lump.
//
-int W_LumpLength (unsigned int lump)
+int W_LumpLength(lumpindex_t lump)
{
if (lump >= numlumps)
{
@@ -358,7 +325,7 @@
I_Error ("W_LumpLength: %i >= numlumps", lump);
}
- return lumpinfo[lump].size;
+ return lumpinfo[lump]->size;
}
@@ -368,29 +335,29 @@
// Loads the lump into the given buffer,
// which must be >= W_LumpLength().
//
-void W_ReadLump(unsigned int lump, void *dest)
+void W_ReadLump(lumpindex_t lump, void *dest)
{
int c;
lumpinfo_t *l;
-
+
if (lump >= numlumps)
{
- I_Error ("W_ReadLump: %i >= numlumps", lump);
+ I_Error ("W_ReadLump: %i >= numlumps", lump);
}
- l = lumpinfo+lump;
-
- I_BeginRead ();
-
+ l = lumpinfo[lump];
+
+ I_BeginRead();
+
c = W_Read(l->wad_file, l->position, dest, l->size);
if (c < l->size)
{
- I_Error ("W_ReadLump: only read %i of %i on lump %i",
- c, l->size, lump);
+ I_Error("W_ReadLump: only read %i of %i on lump %i",
+ c, l->size, lump);
}
- I_EndRead ();
+ I_EndRead();
}
@@ -408,7 +375,7 @@
// when no longer needed (do not use Z_ChangeTag).
//
-void *W_CacheLumpNum(int lumpnum, int tag)
+void *W_CacheLumpNum(lumpindex_t lumpnum, int tag)
{
byte *result;
lumpinfo_t *lump;
@@ -418,7 +385,7 @@
I_Error ("W_CacheLumpNum: %i >= numlumps", lumpnum);
}
- lump = &lumpinfo[lumpnum];
+ lump = lumpinfo[lumpnum];
// Get the pointer to return. If the lump is in a memory-mapped
// file, we can just return a pointer to within the memory-mapped
@@ -470,7 +437,7 @@
// complicated ...
//
-void W_ReleaseLumpNum(int lumpnum)
+void W_ReleaseLumpNum(lumpindex_t lumpnum)
{
lumpinfo_t *lump;
@@ -479,7 +446,7 @@
I_Error ("W_ReleaseLumpNum: %i >= numlumps", lumpnum);
}
- lump = &lumpinfo[lumpnum];
+ lump = lumpinfo[lumpnum];
if (lump->wad_file->mapped != NULL)
{
@@ -566,7 +533,7 @@
void W_GenerateHashTable(void)
{
- unsigned int i;
+ lumpindex_t i;
// Free the old hash table, if there is one:
if (lumphash != NULL)
@@ -577,19 +544,23 @@
// Generate hash table
if (numlumps > 0)
{
- lumphash = Z_Malloc(sizeof(lumpinfo_t *) * numlumps, PU_STATIC, NULL);
- memset(lumphash, 0, sizeof(lumpinfo_t *) * numlumps);
+ lumphash = Z_Malloc(sizeof(lumpindex_t) * numlumps, PU_STATIC, NULL);
- for (i=0; i<numlumps; ++i)
+ for (i = 0; i < numlumps; ++i)
{
+ lumphash[i] = -1;
+ }
+
+ for (i = 0; i < numlumps; ++i)
+ {
unsigned int hash;
- hash = W_LumpNameHash(lumpinfo[i].name) % numlumps;
+ hash = W_LumpNameHash(lumpinfo[i]->name) % numlumps;
// Hook into the hash table
- lumpinfo[i].next = lumphash[hash];
- lumphash[hash] = &lumpinfo[i];
+ lumpinfo[i]->next = lumphash[hash];
+ lumphash[hash] = i;
}
}
@@ -605,7 +576,7 @@
void W_Reload(void)
{
char *filename;
- int i;
+ lumpindex_t i;
if (reloadname == NULL)
{
@@ -612,12 +583,12 @@
return;
}
- // We must release any lumps being held in the PWAD we're about to reload:
+ // We must free any lumps being cached from the PWAD we're about to reload:
for (i = reloadlump; i < numlumps; ++i)
{
- if (lumpinfo[i].cache != NULL)
+ if (lumpinfo[i]->cache != NULL)
{
- W_ReleaseLumpNum(i);
+ Z_Free(lumpinfo[i]->cache);
}
}
@@ -628,6 +599,8 @@
filename = reloadname;
W_CloseFile(reloadhandle);
+ free(reloadlumps);
+
reloadname = NULL;
reloadlump = -1;
reloadhandle = NULL;
@@ -637,46 +610,5 @@
// The WAD directory has changed, so we have to regenerate the
// fast lookup hashtable:
W_GenerateHashTable();
-}
-
-// Lump names that are unique to particular game types. This lets us check
-// the user is not trying to play with the wrong executable, eg.
-// chocolate-doom -iwad hexen.wad.
-static const struct
-{
- GameMission_t mission;
- char *lumpname;
-} unique_lumps[] = {
- { doom, "POSSA1" },
- { heretic, "IMPXA1" },
- { hexen, "ETTNA1" },
- { strife, "AGRDA1" },
-};
-
-void W_CheckCorrectIWAD(GameMission_t mission)
-{
- int i;
- int lumpnum;
-
- for (i = 0; i < arrlen(unique_lumps); ++i)
- {
- if (mission != unique_lumps[i].mission)
- {
- lumpnum = W_CheckNumForName(unique_lumps[i].lumpname);
-
- if (lumpnum >= 0)
- {
- I_Error("\nYou are trying to use a %s IWAD file with "
- "the %s%s binary.\nThis isn't going to work.\n"
- "You probably want to use the %s%s binary.",
- D_SuggestGameName(unique_lumps[i].mission,
- indetermined),
- PROGRAM_PREFIX,
- D_GameMissionString(mission),
- PROGRAM_PREFIX,
- D_GameMissionString(unique_lumps[i].mission));
- }
- }
- }
}
--- a/src/w_wad.h
+++ b/src/w_wad.h
@@ -23,8 +23,6 @@
#include <stdio.h>
#include "doomtype.h"
-#include "d_mode.h"
-
#include "w_file.h"
@@ -37,6 +35,7 @@
//
typedef struct lumpinfo_s lumpinfo_t;
+typedef int lumpindex_t;
struct lumpinfo_s
{
@@ -47,33 +46,30 @@
void *cache;
// Used for hash table lookups
-
- lumpinfo_t *next;
+ lumpindex_t next;
};
-extern lumpinfo_t *lumpinfo;
+extern lumpinfo_t **lumpinfo;
extern unsigned int numlumps;
-wad_file_t *W_AddFile (char *filename);
-void W_Reload (void);
+wad_file_t *W_AddFile(char *filename);
+void W_Reload(void);
-int W_CheckNumForName (char* name);
-int W_GetNumForName (char* name);
+lumpindex_t W_CheckNumForName(char *name);
+lumpindex_t W_GetNumForName(char *name);
-int W_LumpLength (unsigned int lump);
-void W_ReadLump (unsigned int lump, void *dest);
+int W_LumpLength(lumpindex_t lump);
+void W_ReadLump(lumpindex_t lump, void *dest);
-void* W_CacheLumpNum (int lump, int tag);
-void* W_CacheLumpName (char* name, int tag);
+void *W_CacheLumpNum(lumpindex_t lump, int tag);
+void *W_CacheLumpName(char *name, int tag);
-void W_GenerateHashTable(void);
+void W_GenerateHashTable(void);
extern unsigned int W_LumpNameHash(const char *s);
-void W_ReleaseLumpNum(int lump);
-void W_ReleaseLumpName(char *name);
-
-void W_CheckCorrectIWAD(GameMission_t mission);
+void W_ReleaseLumpNum(lumpindex_t lump);
+void W_ReleaseLumpName(char *name);
#endif