Update to ZDoom r1514:

- Fixed: Altering a link type with Sector_SetLink did not work.
- Fixed: player.crouchsprite had no proper means of unsetting the crouch
  sprite which is needed by the ChexPlayer.
- Fixed: A_ChangeFlags must unlink the actor from the world before changing
  the NOBLOCKMAP and NOSECTOR flags.
- Fixed: Dehacked string replacement did not check the clusters' finaleflats.
- Changed the definition of several typedef'd structs so that they are
  properly named.
- Limited DEHSUPP lump lookup to search zdoom.pk3 only. It will no longer
  be possible to load DEHSUPP lumps from user WADs.
- Brought back the text-based DEHSUPP parser and changed it to be able to 
  reference states by label. Also changed label names of 
  DoomUnusedStates and added proper labels to all states that were
  previously forced to be the first state of an actor so that the old
  (limited) method could access them. This was done to address the following
  bug:
- Fixed: The player's death states calling A_PlayerSkinCheck should not be
  part of the state set that is accessible by Dehacked. These will produce
  error messages when mapped to non-players.
- Fixed: Reading the RNG states from a savegame calculated the amounts of
  RNGs in the savegame wrong.
- Changed random seed initialization so that it uses the system's
  cryptographically secure random number generator, if available, instead
  of the current time.
- Changed the random number generator from Lee Killough's algorithm to the
  SFMT607 variant of the Mersenne Twister.
  <http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html>
- Made fmodex.dll delay-loaded so the game should be runnable on Windows 95
  again, though without sound.
- Changed gameinfo_t and gameborder_t to be named structs instead of
  typedef'ed anonymous structs.
- Fixed: P_AutoUseHealth() used autousemodes 0 and 1 instead of 1 and 2.
- Fixed: SBARINFO did not recognize 5:4 aspect ratio.
- Fixed: screenshot_dir was ignored.
- Removed some obsolete code from G_InitLevelLocals that was causing problems
  with maps that have no name.
- Fixed: The inner loop in AWeaponSlot::PickWeapon could endlessly loop when
  the counter variable became negative.
- Fixed: Implicitly defined clusters were not initialized when being created.
- Fixed: Item tossing did not work anymore.
- Changed: Making the gameinfo customizable by MAPINFO requires different
  checks for map specific border flats.
- removed gamemission variable because it wasn't used anywhere.
- removed gamemode variable. All it was used for were some checks that
  really should depend on GI_MAPxx.
- Externalized all internal gameinfo definitions.
- added include to MAPINFO parser.
- split IWAD detection code off from d_main.cpp into its own file.
- disabled gamemission based switch filtering because it is not useful.
- added GAMEINFO submission by Blzut3 with significant modifications. There
  is no GAMEINFO lump. Instead all information is placed in MAPINFO, except
  the data that is needed to decide which WADs to autoload.


git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@318 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
Christoph Oelckers 2009-03-29 11:21:36 +00:00
parent f611ceadc6
commit df7261f8c5
89 changed files with 4910 additions and 2226 deletions

View file

@ -1,4 +1,104 @@
March 15, 2009 (Changes by Graf Zahl)
March 29, 2009 (Changes by Graf Zahl)
- Fixed: Altering a link type with Sector_SetLink did not work.
- Fixed: player.crouchsprite had no proper means of unsetting the crouch
sprite which is needed by the ChexPlayer.
- Fixed: A_ChangeFlags must unlink the actor from the world before changing
the NOBLOCKMAP and NOSECTOR flags.
March 28, 2009 (Changes by Graf Zahl)
- Fixed: Dehacked string replacement did not check the clusters' finaleflats.
- Changed the definition of several typedef'd structs so that they are
properly named.
- Limited DEHSUPP lump lookup to search zdoom.pk3 only. It will no longer
be possible to load DEHSUPP lumps from user WADs.
- Brought back the text-based DEHSUPP parser and changed it to be able to
reference states by label. Also changed label names of
DoomUnusedStates and added proper labels to all states that were
previously forced to be the first state of an actor so that the old
(limited) method could access them. This was done to address the following
bug:
- Fixed: The player's death states calling A_PlayerSkinCheck should not be
part of the state set that is accessible by Dehacked. These will produce
error messages when mapped to non-players.
March 27, 2009 (Changes by Graf Zahl)
- Fixed: Reading the RNG states from a savegame calculated the amounts of
RNGs in the savegame wrong.
March 26, 2009
- Changed random seed initialization so that it uses the system's
cryptographically secure random number generator, if available, instead
of the current time.
- Changed the random number generator from Lee Killough's algorithm to the
SFMT607 variant of the Mersenne Twister.
<http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html>
March 25, 2009
- Made fmodex.dll delay-loaded so the game should be runnable on Windows 95
again, though without sound.
- Changed gameinfo_t and gameborder_t to be named structs instead of
typedef'ed anonymous structs.
- Fixed: P_AutoUseHealth() used autousemodes 0 and 1 instead of 1 and 2.
- Fixed: SBARINFO did not recognize 5:4 aspect ratio.
- Fixed: screenshot_dir was ignored.
March 25, 2009 (Changes by Graf Zahl)
- Removed some obsolete code from G_InitLevelLocals that was causing problems
with maps that have no name.
- Fixed: The inner loop in AWeaponSlot::PickWeapon could endlessly loop when
the counter variable became negative.
- Fixed: Implicitly defined clusters were not initialized when being created.
March 24, 2009 (Changes by Graf Zahl)
- Fixed: Item tossing did not work anymore.
March 23, 2009 (Changes by Graf Zahl)
- Changed: Making the gameinfo customizable by MAPINFO requires different
checks for map specific border flats.
March 22, 2009 (Changes by Graf Zahl)
- removed gamemission variable because it wasn't used anywhere.
- removed gamemode variable. All it was used for were some checks that
really should depend on GI_MAPxx.
- Externalized all internal gameinfo definitions.
- added include to MAPINFO parser.
- split IWAD detection code off from d_main.cpp into its own file.
- disabled gamemission based switch filtering because it is not useful.
- added GAMEINFO submission by Blzut3 with significant modifications. There
is no GAMEINFO lump. Instead all information is placed in MAPINFO, except
the data that is needed to decide which WADs to autoload.
March 19, 2009
- Added the current value of the string buffer to the state saved when
making a function call in ACS. Now you can print inside functions and
also return values from them for the caller to plug directly into
another string without having to save it to a temporary variable.
- Added an OutputVolume() call after the MusicVolumeChanged() call in
MIDIStreamer::Play(). Since the state isn't playing yet when
MusicVolumeChanged() is called, it doesn't do this itself.
- Fixed: P_RailAttack() passed the wrong angle variable to P_TraceBleed().
March 18, 2009 (Changes by Graf Zahl)
- Fixed: S_StopSound may not assume that after stopping a sound channel
its link to the next item in the list is still valid.
- Fixed typo in src/CMakeLists.txt.
- Fixed: Armor only worked for players.
- Fixed: P_FindFloorCeiling may not call P_PointInSector if called from
P_SpawnMapThing. It must use the values the actor has been initialized to
by LinkToWorldForMapThing.
March 17, 2009
- Added the -norun parameter to quit the game just before video
initialization. To be used to check for errors in scripts without actually
running the game.
- Added the -stdout parameter to the Windows version to send all output to
a console, like the Linux version has done all along.
March 16, 2009
- Added support for loading ZGL2 nodes. (Only useful with UDMF and maps with
more than 65534 lines.)
March 15, 2009 (Changes by Graf Zahl)
- Fixed: AWeapon::PickupForAmmo accessed ammo type 1 when checking ammo type2.
March 14, 2009

View file

@ -6329,6 +6329,70 @@
</FileConfiguration>
</File>
</Filter>
<Filter
Name="SFMT"
>
<File
RelativePath=".\src\sfmt\SFMT-alti.h"
>
</File>
<File
RelativePath=".\src\sfmt\SFMT-params.h"
>
</File>
<File
RelativePath=".\src\sfmt\SFMT-params11213.h"
>
</File>
<File
RelativePath=".\src\sfmt\SFMT-params1279.h"
>
</File>
<File
RelativePath=".\src\sfmt\SFMT-params132049.h"
>
</File>
<File
RelativePath=".\src\sfmt\SFMT-params19937.h"
>
</File>
<File
RelativePath=".\src\sfmt\SFMT-params216091.h"
>
</File>
<File
RelativePath=".\src\sfmt\SFMT-params2281.h"
>
</File>
<File
RelativePath=".\src\sfmt\SFMT-params4253.h"
>
</File>
<File
RelativePath=".\src\sfmt\SFMT-params44497.h"
>
</File>
<File
RelativePath=".\src\sfmt\SFMT-params607.h"
>
</File>
<File
RelativePath=".\src\sfmt\SFMT-params86243.h"
>
</File>
<File
RelativePath=".\src\sfmt\SFMT-sse2.h"
>
</File>
<File
RelativePath=".\src\sfmt\SFMT.cpp"
>
</File>
<File
RelativePath=".\src\sfmt\SFMT.h"
>
</File>
</Filter>
<Filter
Name="FraggleScript"
>

View file

@ -695,6 +695,7 @@ add_executable( zdoom WIN32
oplsynth/music_opldumper_mididevice.cpp
oplsynth/music_opl_mididevice.cpp
oplsynth/opl_mus_player.cpp
sfmt/SFMT.cpp
sound/fmodsound.cpp
sound/i_music.cpp
sound/i_sound.cpp

View file

@ -200,25 +200,30 @@ CVAR (Color, am_ovthingcolor_item, 0xe88800, CVAR_ARCHIVE);
#define CXMTOF(x) (MTOF((x)-m_x)/* - f_x*/)
#define CYMTOF(y) (f_h - MTOF((y)-m_y)/* + f_y*/)
typedef struct {
struct fpoint_t
{
int x, y;
} fpoint_t;
};
typedef struct {
struct fline_t
{
fpoint_t a, b;
} fline_t;
};
typedef struct {
struct mpoint_t
{
fixed_t x,y;
} mpoint_t;
};
typedef struct {
struct mline_t
{
mpoint_t a, b;
} mline_t;
};
typedef struct {
struct islope_t
{
fixed_t slp, islp;
} islope_t;
};

File diff suppressed because it is too large Load diff

694
src/d_iwad.cpp Normal file
View file

@ -0,0 +1,694 @@
/*
** d_iwad.cpp
** IWAD detection code
**
**---------------------------------------------------------------------------
** Copyright 1998-2009 Randy Heit
** Copyright 2009 CHristoph Oelckers
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#include "d_main.h"
#include "gi.h"
#include "cmdlib.h"
#include "doomstat.h"
#include "i_system.h"
#include "w_wad.h"
#include "w_zip.h"
#include "v_palette.h"
#include "m_argv.h"
#include "m_misc.h"
#include "c_cvars.h"
#include "gameconfigfile.h"
EIWADType gameiwad;
CVAR (Bool, queryiwad, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
CVAR (String, defaultiwad, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
// If autoname is NULL, that's either because that game doesn't allow
// loading of external wads or because it's already caught by the
// general game-specific wads section.
const IWADInfo IWADInfos[NUM_IWAD_TYPES] =
{
// banner text, autoname, fg color, bg color
{ "Final Doom: TNT - Evilution", "TNT", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/tnt.txt", GI_MAPxx },
{ "Final Doom: Plutonia Experiment", "Plutonia", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/plutonia.txt", GI_MAPxx },
{ "Hexen: Beyond Heretic", NULL, MAKERGB(240,240,240), MAKERGB(107,44,24), GAME_Hexen, "mapinfo/hexen.txt", GI_MAPxx },
{ "Hexen: Deathkings of the Dark Citadel", "HexenDK", MAKERGB(240,240,240), MAKERGB(139,68,9), GAME_Hexen, "mapinfo/hexen.txt", GI_MAPxx },
{ "Hexen: Demo Version", "HexenDemo",MAKERGB(240,240,240), MAKERGB(107,44,24), GAME_Hexen, "mapinfo/hexen.txt", GI_MAPxx | GI_SHAREWARE },
{ "DOOM 2: Hell on Earth", "Doom2", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/doom2.txt", GI_MAPxx },
{ "Heretic Shareware", NULL, MAKERGB(252,252,0), MAKERGB(168,0,0), GAME_Heretic, "mapinfo/hereticsw.txt",GI_SHAREWARE },
{ "Heretic: Shadow of the Serpent Riders", NULL, MAKERGB(252,252,0), MAKERGB(168,0,0), GAME_Heretic, "mapinfo/heretic.txt", GI_MENUHACK_EXTENDED },
{ "Heretic", NULL, MAKERGB(252,252,0), MAKERGB(168,0,0), GAME_Heretic, "mapinfo/heretic.txt" },
{ "DOOM Shareware", NULL, MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/doom1.txt", GI_SHAREWARE },
{ "The Ultimate DOOM", "Doom1", MAKERGB(84,84,84), MAKERGB(168,168,168), GAME_Doom, "mapinfo/ultdoom.txt" },
{ "DOOM Registered", "Doom1", MAKERGB(84,84,84), MAKERGB(168,168,168), GAME_Doom, "mapinfo/doom1.txt" },
{ "Strife: Quest for the Sigil", NULL, MAKERGB(224,173,153), MAKERGB(0,107,101), GAME_Strife, "mapinfo/strife.txt", GI_MAPxx },
{ "Strife: Teaser (Old Version)", NULL, MAKERGB(224,173,153), MAKERGB(0,107,101), GAME_Strife, "mapinfo/strife.txt", GI_MAPxx | GI_SHAREWARE },
{ "Strife: Teaser (New Version)", NULL, MAKERGB(224,173,153), MAKERGB(0,107,101), GAME_Strife, "mapinfo/strife.txt", GI_MAPxx | GI_SHAREWARE | GI_TEASER2 },
{ "Freedoom", "Freedoom", MAKERGB(50,84,67), MAKERGB(198,220,209), GAME_Doom, "mapinfo/doom2.txt", GI_MAPxx },
{ "Freedoom \"Demo\"", "Freedoom1",MAKERGB(50,84,67), MAKERGB(198,220,209), GAME_Doom, "mapinfo/doom1.txt" },
{ "FreeDM", "FreeDM", MAKERGB(50,84,67), MAKERGB(198,220,209), GAME_Doom, "mapinfo/doom2.txt", GI_MAPxx },
{ "Chex(R) Quest", "Chex1", MAKERGB(255,255,0), MAKERGB(0,192,0), GAME_Chex, "mapinfo/chex.txt" },
{ "Chex(R) Quest 3", "Chex3", MAKERGB(255,255,0), MAKERGB(0,192,0), GAME_Chex, "mapinfo/chex3.txt" },
//{ "ZDoom Engine", NULL, MAKERGB(168,0,0), MAKERGB(168,168,168) },
};
static const char *IWADNames[] =
{
NULL,
"doom2f.wad",
"doom2.wad",
"plutonia.wad",
"tnt.wad",
"doomu.wad", // Hack from original Linux version. Not necessary, but I threw it in anyway.
"doom.wad",
"doom1.wad",
"heretic.wad",
"heretic1.wad",
"hexen.wad",
"hexdd.wad",
"hexendemo.wad",
"hexdemo.wad",
"strife1.wad",
"strife0.wad",
"freedoom.wad", // Freedoom.wad is distributed as Doom2.wad, but this allows to have both in the same directory.
"freedoom1.wad",
"freedm.wad",
"chex.wad",
"chex3.wad",
#ifdef unix
"DOOM2.WAD", // Also look for all-uppercase names
"PLUTONIA.WAD",
"TNT.WAD",
"DOOM.WAD",
"DOOM1.WAD",
"HERETIC.WAD",
"HERETIC1.WAD",
"HEXEN.WAD",
"HEXDD.WAD",
"HEXENDEMO.WAD",
"HEXDEMO.WAD",
"STRIFE1.WAD",
"STRIFE0.WAD",
"FREEDOOM.WAD",
"FREEDOOM1.WAD",
"FREEDM.WAD",
"CHEX.WAD",
"CHEX3.WAD",
#endif
NULL
};
//==========================================================================
//
// ScanIWAD
//
// Scan the contents of an IWAD to determine which one it is
//==========================================================================
static EIWADType ScanIWAD (const char *iwad)
{
static const char checklumps[][8] =
{
"E1M1",
"E4M2",
"MAP01",
"MAP40",
"MAP60",
"TITLE",
"REDTNT2",
"CAMO1",
{ 'E','X','T','E','N','D','E','D'},
"ENDSTRF",
"MAP33",
"INVCURS",
{ 'F','R','E','E','D','O','O','M' },
"W94_1",
{ 'P','O','S','S','H','0','M','0' },
"CYCLA1",
"FLMBA1",
"MAPINFO",
{ 'G','A','M','E','I','N','F','O' },
"E2M1","E2M2","E2M3","E2M4","E2M5","E2M6","E2M7","E2M8","E2M9",
"E3M1","E3M2","E3M3","E3M4","E3M5","E3M6","E3M7","E3M8","E3M9",
"DPHOOF","BFGGA0","HEADA1","CYBRA1",
{ 'S','P','I','D','A','1','D','1' },
};
#define NUM_CHECKLUMPS (sizeof(checklumps)/8)
enum
{
Check_e1m1,
Check_e4m1,
Check_map01,
Check_map40,
Check_map60,
Check_title,
Check_redtnt2,
Check_cam01,
Check_Extended,
Check_endstrf,
Check_map33,
Check_invcurs,
Check_FreeDoom,
Check_W94_1,
Check_POSSH0M0,
Check_Cycla1,
Check_Flmba1,
Check_Mapinfo,
Check_Gameinfo,
Check_e2m1
};
int lumpsfound[NUM_CHECKLUMPS];
size_t i;
wadinfo_t header;
FILE *f;
memset (lumpsfound, 0, sizeof(lumpsfound));
if ( (f = fopen (iwad, "rb")) )
{
fread (&header, sizeof(header), 1, f);
if (header.Magic == IWAD_ID || header.Magic == PWAD_ID)
{
header.NumLumps = LittleLong(header.NumLumps);
if (0 == fseek (f, LittleLong(header.InfoTableOfs), SEEK_SET))
{
for (i = 0; i < (size_t)header.NumLumps; i++)
{
wadlump_t lump;
size_t j;
if (0 == fread (&lump, sizeof(lump), 1, f))
break;
for (j = 0; j < NUM_CHECKLUMPS; j++)
if (strnicmp (lump.Name, checklumps[j], 8) == 0)
lumpsfound[j]++;
}
}
}
#if 0
else if (header.Magic == ZIP_ID)
{ // Using a zip as an IWAD replacement requires that the key lumps be in the global scope.
// This is because most of them will be "Custom IWADs" so all that we really should need
// to find is GAMEINFO, but why limit ourselves?
header.NumLumps = 0;
FileReader *reader = new FileReader(f);
DWORD centraldir = Zip_FindCentralDir(reader);
delete reader;
if (fseek(f, centraldir, SEEK_SET) == 0)
{
// First locate directory
FZipEndOfCentralDirectory directory;
if (0 != fread(&directory, sizeof(directory), 1, f) && LittleLong(directory.Magic) == 0x06054b50)
{
header.NumLumps += LittleLong(directory.NumEntries);
if (fseek(f, LittleLong(directory.DirectoryOffset), SEEK_SET) == 0)
{
// Scan directory for lumps in the global scope with key names.
do
{
FZipCentralDirectoryInfo entry;
if (0 == fread(&entry, sizeof(entry), 1, f))
break;
if (LittleLong(entry.Magic) == 0x02014b50)
{
// Now determine the lump's short name
char* fullname = new char[LittleLong(entry.NameLength)];
if (0 == fread(fullname, LittleLong(entry.NameLength), 1, f))
{
delete[] fullname;
break;
}
FString name = fullname;
delete[] fullname;
if(name.LastIndexOf('/') != -1)
continue;
name.Truncate(name.LastIndexOf('.'));
for (size_t j = 0; j < NUM_CHECKLUMPS; j++)
if (strnicmp (name, checklumps[j], 8) == 0)
lumpsfound[j]++;
}
else
break;
}
while(true);
}
}
}
}
#endif
fclose (f);
}
// Always check for custom iwads first.
#if 0
if (lumpsfound[Check_Gameinfo])
{
return IWAD_Custom;
}
#endif
if (lumpsfound[Check_title] && lumpsfound[Check_map60])
{
return IWAD_HexenDK;
}
else if (lumpsfound[Check_map33] && lumpsfound[Check_endstrf])
{
if (lumpsfound[Check_map01])
{
return IWAD_Strife;
}
else if (lumpsfound[Check_invcurs])
{
return IWAD_StrifeTeaser2;
}
else
{
return IWAD_StrifeTeaser;
}
}
else if (lumpsfound[Check_map01])
{
if (lumpsfound[Check_FreeDoom])
{
// Is there a 100% reliable way to tell FreeDoom and FreeDM
// apart based solely on the lump names?
if (strstr(iwad, "freedm.wad") || strstr(iwad, "FREEDM.WAD"))
{
return IWAD_FreeDM;
}
else
{
return IWAD_FreeDoom;
}
}
else if (lumpsfound[Check_redtnt2])
{
return IWAD_Doom2TNT;
}
else if (lumpsfound[Check_cam01])
{
return IWAD_Doom2Plutonia;
}
else
{
if (lumpsfound[Check_title])
{
if (lumpsfound[Check_map40])
{
return IWAD_Hexen;
}
else
{
return IWAD_HexenDemo;
}
}
else
{
return IWAD_Doom2;
}
}
}
else if (lumpsfound[Check_e1m1])
{
if (lumpsfound[Check_title])
{
if (!lumpsfound[Check_e2m1])
{
return IWAD_HereticShareware;
}
else
{
if (lumpsfound[Check_Extended])
{
return IWAD_HereticExtended;
}
else
{
return IWAD_Heretic;
}
}
}
else if (lumpsfound[Check_Cycla1] && lumpsfound[Check_Flmba1])
{
if (!lumpsfound[Check_Mapinfo])
{
// The original release won't work without its hacked custom EXE.
//I_FatalError("Found an incompatible version of Chex Quest 3");
return NUM_IWAD_TYPES; // Can't use it.
}
return IWAD_ChexQuest3;
}
else
{
if (lumpsfound[Check_FreeDoom])
{
return IWAD_FreeDoom1;
}
for (i = Check_e2m1; i < NUM_CHECKLUMPS; i++)
{
if (!lumpsfound[i])
{
return IWAD_DoomShareware;
}
}
if (i == NUM_CHECKLUMPS)
{
if (lumpsfound[Check_e4m1])
{
if (lumpsfound[Check_W94_1] && lumpsfound[Check_POSSH0M0])
{
return IWAD_ChexQuest;
}
else
{
return IWAD_UltimateDoom;
}
}
else
{
return IWAD_DoomRegistered;
}
}
}
}
return NUM_IWAD_TYPES; // Don't know
}
//==========================================================================
//
// CheckIWAD
//
// Tries to find an IWAD from a set of known IWAD names, and checks the
// contents of each one found to determine which game it belongs to.
// Returns the number of new wads found in this pass (does not count wads
// found from a previous call).
//
//==========================================================================
static int CheckIWAD (const char *doomwaddir, WadStuff *wads)
{
const char *slash;
int i;
int numfound;
numfound = 0;
slash = (doomwaddir[0] && doomwaddir[strlen (doomwaddir)-1] != '/') ? "/" : "";
// Search for a pre-defined IWAD
for (i = IWADNames[0] ? 0 : 1; IWADNames[i]; i++)
{
if (wads[i].Path.IsEmpty())
{
FString iwad;
iwad.Format ("%s%s%s", doomwaddir, slash, IWADNames[i]);
FixPathSeperator (iwad.LockBuffer());
iwad.UnlockBuffer();
if (FileExists (iwad))
{
wads[i].Type = ScanIWAD (iwad);
if (wads[i].Type != NUM_IWAD_TYPES)
{
wads[i].Path = iwad;
numfound++;
}
}
}
}
return numfound;
}
//==========================================================================
//
// CheckIWADinEnvDir
//
// Checks for an IWAD in a path that contains one or more environment
// variables.
//
//==========================================================================
static int CheckIWADinEnvDir (const char *str, WadStuff *wads)
{
FString expanded = ExpandEnvVars (str);
if (!expanded.IsEmpty())
{
char *dir = expanded.LockBuffer ();
FixPathSeperator (dir);
expanded.UnlockBuffer ();
if (expanded[expanded.Len() - 1] != '/')
{
expanded += '/';
}
return CheckIWAD (expanded, wads);
}
return false;
}
//==========================================================================
//
// IdentifyVersion
//
// Tries to find an IWAD in one of four directories under DOS or Win32:
// 1. Current directory
// 2. Executable directory
// 3. $DOOMWADDIR
// 4. $HOME
//
// Under UNIX OSes, the search path is:
// 1. Current directory
// 2. $DOOMWADDIR
// 3. $HOME/.zdoom
// 4. The share directory defined at compile time (/usr/local/share/zdoom)
//
// The search path can be altered by editing the IWADSearch.Directories
// section of the config file.
//
//==========================================================================
static EIWADType IdentifyVersion (const char *zdoom_wad)
{
WadStuff wads[countof(IWADNames)];
size_t foundwads[NUM_IWAD_TYPES] = { 0 };
const char *iwadparm = Args->CheckValue ("-iwad");
size_t numwads;
int pickwad;
size_t i;
bool iwadparmfound = false;
FString custwad;
if (iwadparm)
{
custwad = iwadparm;
FixPathSeperator (custwad.LockBuffer());
if (CheckIWAD (custwad, wads))
{ // -iwad parameter was a directory
iwadparm = NULL;
}
else
{
DefaultExtension (custwad, ".wad");
iwadparm = custwad;
IWADNames[0] = iwadparm;
CheckIWAD ("", wads);
}
}
if (iwadparm == NULL || wads[0].Path.IsEmpty())
{
if (GameConfig->SetSection ("IWADSearch.Directories"))
{
const char *key;
const char *value;
while (GameConfig->NextInSection (key, value))
{
if (stricmp (key, "Path") == 0)
{
if (strchr (value, '$') != NULL)
{
CheckIWADinEnvDir (value, wads);
}
#ifdef unix
else if (*value == '~' && (*(value + 1) == 0 || *(value + 1) == '/'))
{
FString homepath = GetUserFile (*(value + 1) ? value + 2 : value + 1, true);
CheckIWAD (homepath, wads);
}
#endif
else
{
CheckIWAD (value, wads);
}
}
}
}
#ifdef _WIN32
FString steam_path = I_GetSteamPath();
if (steam_path.IsNotEmpty())
{
static const char *const steam_dirs[] =
{
"doom 2/base",
"final doom/base",
"heretic shadow of the serpent riders/base",
"hexen/base",
"hexen deathkings of the dark citadel/base",
"ultimate doom/base"
};
steam_path += "/SteamApps/common/";
for (i = 0; i < countof(steam_dirs); ++i)
{
CheckIWAD (steam_path + steam_dirs[i], wads);
}
}
#endif
}
if (iwadparm != NULL && !wads[0].Path.IsEmpty())
{
iwadparmfound = true;
}
for (i = numwads = 0; i < countof(IWADNames); i++)
{
if (!wads[i].Path.IsEmpty())
{
if (i != numwads)
{
wads[numwads] = wads[i];
}
foundwads[wads[numwads].Type] = numwads + 1;
numwads++;
}
}
if (foundwads[IWAD_HexenDK] && !foundwads[IWAD_Hexen])
{ // Cannot play Hexen DK without Hexen
size_t kill = foundwads[IWAD_HexenDK];
for (i = kill; i < numwads; ++i)
{
wads[i - 1] = wads[i];
}
numwads--;
foundwads[IWAD_HexenDK] = 0;
for (i = 0; i < NUM_IWAD_TYPES; ++i)
{
if (foundwads[i] > kill)
{
foundwads[i]--;
}
}
}
if (numwads == 0)
{
I_FatalError ("Cannot find a game IWAD (doom.wad, doom2.wad, heretic.wad, etc.).\n"
"Did you install ZDoom properly? You can do either of the following:\n"
"\n"
"1. Place one or more of these wads in the same directory as ZDoom.\n"
"2. Edit your zdoom-username.ini and add the directories of your iwads\n"
"to the list beneath [IWADSearch.Directories]");
}
pickwad = 0;
if (!iwadparmfound && numwads > 1)
{
int defiwad = 0;
// Locate the user's prefered IWAD, if it was found.
if (defaultiwad[0] != '\0')
{
for (i = 0; i < numwads; ++i)
{
FString basename = ExtractFileBase (wads[i].Path);
if (stricmp (basename, defaultiwad) == 0)
{
defiwad = (int)i;
break;
}
}
}
pickwad = I_PickIWad (wads, (int)numwads, queryiwad, defiwad);
if (pickwad >= 0)
{
// The newly selected IWAD becomes the new default
FString basename = ExtractFileBase (wads[pickwad].Path);
defaultiwad = basename;
}
}
if (pickwad < 0)
exit (0);
// zdoom.pk3 must always be the first file loaded and the IWAD second.
D_AddFile (zdoom_wad);
if (wads[pickwad].Type == IWAD_HexenDK)
{ // load hexen.wad before loading hexdd.wad
D_AddFile (wads[foundwads[IWAD_Hexen]-1].Path);
}
D_AddFile (wads[pickwad].Path);
if (wads[pickwad].Type == IWAD_Strife)
{ // Try to load voices.wad along with strife1.wad
long lastslash = wads[pickwad].Path.LastIndexOf ('/');
FString path;
if (lastslash == -1)
{
path = "";// wads[pickwad].Path;
}
else
{
path = FString (wads[pickwad].Path.GetChars(), lastslash + 1);
}
path += "voices.wad";
D_AddFile (path);
}
return wads[pickwad].Type;
}
const IWADInfo *D_FindIWAD(const char *basewad)
{
gameiwad = IdentifyVersion(basewad);
const IWADInfo *iwad_info = &IWADInfos[gameiwad];
I_SetIWADInfo(iwad_info);
return iwad_info;
}

View file

@ -117,6 +117,7 @@ extern void R_ExecuteSetViewSize ();
extern void G_NewInit ();
extern void SetupPlayerClasses ();
extern bool CheckCheatmode ();
extern const IWADInfo *D_FindIWAD(const char *basewad);
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
@ -124,7 +125,6 @@ void D_CheckNetGame ();
void D_ProcessEvents ();
void G_BuildTiccmd (ticcmd_t* cmd);
void D_DoAdvanceDemo ();
void D_AddFile (const char *file);
void D_AddWildFile (const char *pattern);
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
@ -145,22 +145,6 @@ EXTERN_CVAR (Int, screenblocks)
EXTERN_CVAR (Bool, sv_cheats)
EXTERN_CVAR (Bool, sv_unlimited_pickup)
extern gameinfo_t SharewareGameInfo;
extern gameinfo_t RegisteredGameInfo;
extern gameinfo_t RetailGameInfo;
extern gameinfo_t CommercialGameInfo;
extern gameinfo_t HereticGameInfo;
extern gameinfo_t HereticSWGameInfo;
extern gameinfo_t HexenGameInfo;
extern gameinfo_t HexenDKGameInfo;
extern gameinfo_t StrifeGameInfo;
extern gameinfo_t StrifeTeaserGameInfo;
extern gameinfo_t StrifeTeaser2GameInfo;
extern gameinfo_t ChexGameInfo;
extern gameinfo_t Chex3GameInfo;
extern gameinfo_t PlutoniaGameInfo;
extern gameinfo_t TNTGameInfo;
extern int testingmode;
extern bool setmodeneeded;
extern bool netdemo;
@ -194,8 +178,6 @@ CUSTOM_CVAR (Int, fraglimit, 0, CVAR_SERVERINFO)
}
CVAR (Float, timelimit, 0.f, CVAR_SERVERINFO);
CVAR (Bool, queryiwad, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
CVAR (String, defaultiwad, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
CVAR (Int, wipetype, 1, CVAR_ARCHIVE);
CVAR (Int, snd_drawoutput, 0, 0);
@ -219,84 +201,12 @@ FTexture *Advisory;
cycle_t FrameCycles;
// If autoname is NULL, that's either because that game doesn't allow
// loading of external wads or because it's already caught by the
// general game-specific wads section.
const IWADInfo IWADInfos[NUM_IWAD_TYPES] =
{
// banner text, autoname, fg color, bg color
{ "Final Doom: TNT - Evilution", "TNT", MAKERGB(168,0,0), MAKERGB(168,168,168) },
{ "Final Doom: Plutonia Experiment", "Plutonia", MAKERGB(168,0,0), MAKERGB(168,168,168) },
{ "Hexen: Beyond Heretic", NULL, MAKERGB(240,240,240), MAKERGB(107,44,24) },
{ "Hexen: Deathkings of the Dark Citadel", "HexenDK", MAKERGB(240,240,240), MAKERGB(139,68,9) },
{ "Hexen: Demo Version", "HexenDemo",MAKERGB(240,240,240), MAKERGB(107,44,24) },
{ "DOOM 2: Hell on Earth", "Doom2", MAKERGB(168,0,0), MAKERGB(168,168,168) },
{ "Heretic Shareware", NULL, MAKERGB(252,252,0), MAKERGB(168,0,0) },
{ "Heretic: Shadow of the Serpent Riders", NULL, MAKERGB(252,252,0), MAKERGB(168,0,0) },
{ "Heretic", NULL, MAKERGB(252,252,0), MAKERGB(168,0,0) },
{ "DOOM Shareware", NULL, MAKERGB(168,0,0), MAKERGB(168,168,168) },
{ "The Ultimate DOOM", "Doom1", MAKERGB(84,84,84), MAKERGB(168,168,168) },
{ "DOOM Registered", "Doom1", MAKERGB(84,84,84), MAKERGB(168,168,168) },
{ "Strife: Quest for the Sigil", NULL, MAKERGB(224,173,153), MAKERGB(0,107,101) },
{ "Strife: Teaser (Old Version)", NULL, MAKERGB(224,173,153), MAKERGB(0,107,101) },
{ "Strife: Teaser (New Version)", NULL, MAKERGB(224,173,153), MAKERGB(0,107,101) },
{ "Freedoom", "Freedoom", MAKERGB(50,84,67), MAKERGB(198,220,209) },
{ "Freedoom \"Demo\"", "Freedoom1",MAKERGB(50,84,67), MAKERGB(198,220,209) },
{ "FreeDM", "FreeDM", MAKERGB(50,84,67), MAKERGB(198,220,209) },
{ "Chex(R) Quest", "Chex", MAKERGB(255,255,0), MAKERGB(0,192,0) },
{ "Chex(R) Quest 3", "Chex3", MAKERGB(255,255,0), MAKERGB(0,192,0) },
};
// PRIVATE DATA DEFINITIONS ------------------------------------------------
static wadlist_t **wadtail = &wadfiles;
static int demosequence;
static int pagetic;
static const char *IWADNames[] =
{
NULL,
"doom2f.wad",
"doom2.wad",
"plutonia.wad",
"tnt.wad",
"doomu.wad", // Hack from original Linux version. Not necessary, but I threw it in anyway.
"doom.wad",
"doom1.wad",
"heretic.wad",
"heretic1.wad",
"hexen.wad",
"hexdd.wad",
"hexendemo.wad",
"hexdemo.wad",
"strife1.wad",
"strife0.wad",
"freedoom.wad", // Freedoom.wad is distributed as Doom2.wad, but this allows to have both in the same directory.
"freedoom1.wad",
"freedm.wad",
"chex.wad",
"chex3.wad",
#ifdef unix
"DOOM2.WAD", // Also look for all-uppercase names
"PLUTONIA.WAD",
"TNT.WAD",
"DOOM.WAD",
"DOOM1.WAD",
"HERETIC.WAD",
"HERETIC1.WAD",
"HEXEN.WAD",
"HEXDD.WAD",
"HEXENDEMO.WAD",
"HEXDEMO.WAD",
"STRIFE1.WAD",
"STRIFE0.WAD",
"FREEDOOM.WAD",
"FREEDOOM1.WAD",
"FREEDM.WAD",
"CHEX.WAD",
"CHEX3.WAD",
#endif
NULL
};
// CODE --------------------------------------------------------------------
@ -1215,11 +1125,8 @@ void D_DoAdvanceDemo (void)
case 2:
pagetic = (int)(gameinfo.pageTime * TICRATE);
gamestate = GS_DEMOSCREEN;
if (pagecount == 0)
pagename = gameinfo.creditPage1;
else
pagename = gameinfo.creditPage2;
pagecount ^= 1;
pagename = gameinfo.creditPages[pagecount];
pagecount = (pagecount+1) % gameinfo.creditPages.Size();
demosequence = 1;
break;
}
@ -1429,555 +1336,6 @@ static void D_AddDirectory (const char *dir)
}
}
//==========================================================================
//
// SetIWAD
//
// Sets parameters for the game using the specified IWAD.
//==========================================================================
static void SetIWAD (const char *iwadpath, EIWADType type)
{
static const struct
{
GameMode_t Mode;
const gameinfo_t *Info;
GameMission_t Mission;
} Datas[NUM_IWAD_TYPES] = {
{ commercial, &TNTGameInfo, pack_tnt }, // Doom2TNT
{ commercial, &PlutoniaGameInfo, pack_plut }, // Doom2Plutonia
{ commercial, &HexenGameInfo, doom2 }, // Hexen
{ commercial, &HexenDKGameInfo, doom2 }, // HexenDK
{ commercial, &HexenGameInfo, doom2 }, // Hexen Demo
{ commercial, &CommercialGameInfo, doom2 }, // Doom2
{ shareware, &HereticSWGameInfo, doom }, // HereticShareware
{ retail, &HereticGameInfo, doom }, // HereticExtended
{ retail, &HereticGameInfo, doom }, // Heretic
{ shareware, &SharewareGameInfo, doom }, // DoomShareware
{ retail, &RetailGameInfo, doom }, // UltimateDoom
{ registered, &RegisteredGameInfo, doom }, // DoomRegistered
{ commercial, &StrifeGameInfo, doom2 }, // Strife
{ commercial, &StrifeTeaserGameInfo, doom2 }, // StrifeTeaser
{ commercial, &StrifeTeaser2GameInfo, doom2 }, // StrifeTeaser2
{ commercial, &CommercialGameInfo, doom2 }, // FreeDoom
{ shareware, &SharewareGameInfo, doom }, // FreeDoom1
{ commercial, &CommercialGameInfo, doom2 }, // FreeDM
{ registered, &ChexGameInfo, doom }, // Chex Quest
{ registered, &Chex3GameInfo, doom }, // Chex Quest 3
};
D_AddFile (iwadpath);
if ((unsigned)type < NUM_IWAD_TYPES)
{
gamemode = Datas[type].Mode;
gameinfo = *Datas[type].Info;
gamemission = Datas[type].Mission;
if (type == IWAD_HereticExtended)
{
gameinfo.flags |= GI_MENUHACK_EXTENDED;
}
}
else
{
gamemode = undetermined;
}
}
//==========================================================================
//
// ScanIWAD
//
// Scan the contents of an IWAD to determine which one it is
//==========================================================================
static EIWADType ScanIWAD (const char *iwad)
{
static const char checklumps[][8] =
{
"E1M1",
"E4M2",
"MAP01",
"MAP40",
"MAP60",
"TITLE",
"REDTNT2",
"CAMO1",
{ 'E','X','T','E','N','D','E','D'},
"ENDSTRF",
"MAP33",
"INVCURS",
{ 'F','R','E','E','D','O','O','M' },
"W94_1",
{ 'P','O','S','S','H','0','M','0' },
"CYCLA1",
"FLMBA1",
"MAPINFO",
"E2M1","E2M2","E2M3","E2M4","E2M5","E2M6","E2M7","E2M8","E2M9",
"E3M1","E3M2","E3M3","E3M4","E3M5","E3M6","E3M7","E3M8","E3M9",
"DPHOOF","BFGGA0","HEADA1","CYBRA1",
{ 'S','P','I','D','A','1','D','1' },
};
#define NUM_CHECKLUMPS (sizeof(checklumps)/8)
enum
{
Check_e1m1,
Check_e4m1,
Check_map01,
Check_map40,
Check_map60,
Check_title,
Check_redtnt2,
Check_cam01,
Check_Extended,
Check_endstrf,
Check_map33,
Check_invcurs,
Check_FreeDoom,
Check_W94_1,
Check_POSSH0M0,
Check_Cycla1,
Check_Flmba1,
Check_Mapinfo,
Check_e2m1
};
int lumpsfound[NUM_CHECKLUMPS];
size_t i;
wadinfo_t header;
FILE *f;
memset (lumpsfound, 0, sizeof(lumpsfound));
if ( (f = fopen (iwad, "rb")) )
{
fread (&header, sizeof(header), 1, f);
if (header.Magic == IWAD_ID || header.Magic == PWAD_ID)
{
header.NumLumps = LittleLong(header.NumLumps);
if (0 == fseek (f, LittleLong(header.InfoTableOfs), SEEK_SET))
{
for (i = 0; i < (size_t)header.NumLumps; i++)
{
wadlump_t lump;
size_t j;
if (0 == fread (&lump, sizeof(lump), 1, f))
break;
for (j = 0; j < NUM_CHECKLUMPS; j++)
if (strnicmp (lump.Name, checklumps[j], 8) == 0)
lumpsfound[j]++;
}
}
}
fclose (f);
}
if (lumpsfound[Check_title] && lumpsfound[Check_map60])
{
return IWAD_HexenDK;
}
else if (lumpsfound[Check_map33] && lumpsfound[Check_endstrf])
{
if (lumpsfound[Check_map01])
{
return IWAD_Strife;
}
else if (lumpsfound[Check_invcurs])
{
return IWAD_StrifeTeaser2;
}
else
{
return IWAD_StrifeTeaser;
}
}
else if (lumpsfound[Check_map01])
{
if (lumpsfound[Check_FreeDoom])
{
// Is there a 100% reliable way to tell FreeDoom and FreeDM
// apart based solely on the lump names?
if (strstr(iwad, "freedm.wad") || strstr(iwad, "FREEDM.WAD"))
{
return IWAD_FreeDM;
}
else
{
return IWAD_FreeDoom;
}
}
else if (lumpsfound[Check_redtnt2])
{
return IWAD_Doom2TNT;
}
else if (lumpsfound[Check_cam01])
{
return IWAD_Doom2Plutonia;
}
else
{
if (lumpsfound[Check_title])
{
if (lumpsfound[Check_map40])
{
return IWAD_Hexen;
}
else
{
return IWAD_HexenDemo;
}
}
else
{
return IWAD_Doom2;
}
}
}
else if (lumpsfound[Check_e1m1])
{
if (lumpsfound[Check_title])
{
if (!lumpsfound[Check_e2m1])
{
return IWAD_HereticShareware;
}
else
{
if (lumpsfound[Check_Extended])
{
return IWAD_HereticExtended;
}
else
{
return IWAD_Heretic;
}
}
}
else if (lumpsfound[Check_Cycla1] && lumpsfound[Check_Flmba1])
{
if (!lumpsfound[Check_Mapinfo])
{
// The original release won't work without its hacked custom EXE.
//I_FatalError("Found an incompatible version of Chex Quest 3");
return NUM_IWAD_TYPES; // Can't use it.
}
return IWAD_ChexQuest3;
}
else
{
if (lumpsfound[Check_FreeDoom])
{
return IWAD_FreeDoom1;
}
for (i = Check_e2m1; i < NUM_CHECKLUMPS; i++)
{
if (!lumpsfound[i])
{
return IWAD_DoomShareware;
}
}
if (i == NUM_CHECKLUMPS)
{
if (lumpsfound[Check_e4m1])
{
if (lumpsfound[Check_W94_1] && lumpsfound[Check_POSSH0M0])
{
return IWAD_ChexQuest;
}
else
{
return IWAD_UltimateDoom;
}
}
else
{
return IWAD_DoomRegistered;
}
}
}
}
return NUM_IWAD_TYPES; // Don't know
}
//==========================================================================
//
// CheckIWAD
//
// Tries to find an IWAD from a set of known IWAD names, and checks the
// contents of each one found to determine which game it belongs to.
// Returns the number of new wads found in this pass (does not count wads
// found from a previous call).
//
//==========================================================================
static int CheckIWAD (const char *doomwaddir, WadStuff *wads)
{
const char *slash;
int i;
int numfound;
numfound = 0;
slash = (doomwaddir[0] && doomwaddir[strlen (doomwaddir)-1] != '/') ? "/" : "";
// Search for a pre-defined IWAD
for (i = IWADNames[0] ? 0 : 1; IWADNames[i]; i++)
{
if (wads[i].Path.IsEmpty())
{
FString iwad;
iwad.Format ("%s%s%s", doomwaddir, slash, IWADNames[i]);
FixPathSeperator (iwad.LockBuffer());
iwad.UnlockBuffer();
if (FileExists (iwad))
{
wads[i].Type = ScanIWAD (iwad);
if (wads[i].Type != NUM_IWAD_TYPES)
{
wads[i].Path = iwad;
numfound++;
}
}
}
}
return numfound;
}
//==========================================================================
//
// CheckIWADinEnvDir
//
// Checks for an IWAD in a path that contains one or more environment
// variables.
//
//==========================================================================
static int CheckIWADinEnvDir (const char *str, WadStuff *wads)
{
FString expanded = ExpandEnvVars (str);
if (!expanded.IsEmpty())
{
char *dir = expanded.LockBuffer ();
FixPathSeperator (dir);
expanded.UnlockBuffer ();
if (expanded[expanded.Len() - 1] != '/')
{
expanded += '/';
}
return CheckIWAD (expanded, wads);
}
return false;
}
//==========================================================================
//
// IdentifyVersion
//
// Tries to find an IWAD in one of four directories under DOS or Win32:
// 1. Current directory
// 2. Executable directory
// 3. $DOOMWADDIR
// 4. $HOME
//
// Under UNIX OSes, the search path is:
// 1. Current directory
// 2. $DOOMWADDIR
// 3. $HOME/.zdoom
// 4. The share directory defined at compile time (/usr/local/share/zdoom)
//
// The search path can be altered by editing the IWADSearch.Directories
// section of the config file.
//
//==========================================================================
static EIWADType IdentifyVersion (const char *zdoom_wad)
{
WadStuff wads[countof(IWADNames)];
size_t foundwads[NUM_IWAD_TYPES] = { 0 };
const char *iwadparm = Args->CheckValue ("-iwad");
size_t numwads;
int pickwad;
size_t i;
bool iwadparmfound = false;
FString custwad;
if (iwadparm)
{
custwad = iwadparm;
FixPathSeperator (custwad.LockBuffer());
if (CheckIWAD (custwad, wads))
{ // -iwad parameter was a directory
iwadparm = NULL;
}
else
{
DefaultExtension (custwad, ".wad");
iwadparm = custwad;
IWADNames[0] = iwadparm;
CheckIWAD ("", wads);
}
}
if (iwadparm == NULL || wads[0].Path.IsEmpty())
{
if (GameConfig->SetSection ("IWADSearch.Directories"))
{
const char *key;
const char *value;
while (GameConfig->NextInSection (key, value))
{
if (stricmp (key, "Path") == 0)
{
if (strchr (value, '$') != NULL)
{
CheckIWADinEnvDir (value, wads);
}
#ifdef unix
else if (*value == '~' && (*(value + 1) == 0 || *(value + 1) == '/'))
{
FString homepath = GetUserFile (*(value + 1) ? value + 2 : value + 1, true);
CheckIWAD (homepath, wads);
}
#endif
else
{
CheckIWAD (value, wads);
}
}
}
}
#ifdef _WIN32
FString steam_path = I_GetSteamPath();
if (steam_path.IsNotEmpty())
{
static const char *const steam_dirs[] =
{
"doom 2/base",
"final doom/base",
"heretic shadow of the serpent riders/base",
"hexen/base",
"hexen deathkings of the dark citadel/base",
"ultimate doom/base"
};
steam_path += "/SteamApps/common/";
for (i = 0; i < countof(steam_dirs); ++i)
{
CheckIWAD (steam_path + steam_dirs[i], wads);
}
}
#endif
}
if (iwadparm != NULL && !wads[0].Path.IsEmpty())
{
iwadparmfound = true;
}
for (i = numwads = 0; i < countof(IWADNames); i++)
{
if (!wads[i].Path.IsEmpty())
{
if (i != numwads)
{
wads[numwads] = wads[i];
}
foundwads[wads[numwads].Type] = numwads + 1;
numwads++;
}
}
if (foundwads[IWAD_HexenDK] && !foundwads[IWAD_Hexen])
{ // Cannot play Hexen DK without Hexen
size_t kill = foundwads[IWAD_HexenDK];
for (i = kill; i < numwads; ++i)
{
wads[i - 1] = wads[i];
}
numwads--;
foundwads[IWAD_HexenDK] = 0;
for (i = 0; i < NUM_IWAD_TYPES; ++i)
{
if (foundwads[i] > kill)
{
foundwads[i]--;
}
}
}
if (numwads == 0)
{
I_FatalError ("Cannot find a game IWAD (doom.wad, doom2.wad, heretic.wad, etc.).\n"
"Did you install ZDoom properly? You can do either of the following:\n"
"\n"
"1. Place one or more of these wads in the same directory as ZDoom.\n"
"2. Edit your zdoom-username.ini and add the directories of your iwads\n"
"to the list beneath [IWADSearch.Directories]");
}
pickwad = 0;
if (!iwadparmfound && numwads > 1)
{
int defiwad = 0;
// Locate the user's prefered IWAD, if it was found.
if (defaultiwad[0] != '\0')
{
for (i = 0; i < numwads; ++i)
{
FString basename = ExtractFileBase (wads[i].Path);
if (stricmp (basename, defaultiwad) == 0)
{
defiwad = (int)i;
break;
}
}
}
pickwad = I_PickIWad (wads, (int)numwads, queryiwad, defiwad);
if (pickwad >= 0)
{
// The newly selected IWAD becomes the new default
FString basename = ExtractFileBase (wads[pickwad].Path);
defaultiwad = basename;
}
}
if (pickwad < 0)
exit (0);
// zdoom.pk3 must always be the first file loaded and the IWAD second.
D_AddFile (zdoom_wad);
if (wads[pickwad].Type == IWAD_HexenDK)
{ // load hexen.wad before loading hexdd.wad
D_AddFile (wads[foundwads[IWAD_Hexen]-1].Path);
}
SetIWAD (wads[pickwad].Path, wads[pickwad].Type);
if (wads[pickwad].Type == IWAD_Strife)
{ // Try to load voices.wad along with strife1.wad
long lastslash = wads[pickwad].Path.LastIndexOf ('/');
FString path;
if (lastslash == -1)
{
path = "";// wads[pickwad].Path;
}
else
{
path = FString (wads[pickwad].Path.GetChars(), lastslash + 1);
}
path += "voices.wad";
D_AddFile (path);
}
return wads[pickwad].Type;
}
//==========================================================================
//
@ -2195,7 +1553,6 @@ void D_DoomMain (void)
char *v;
const char *wad;
DArgs *execFiles;
const IWADInfo *iwad_info;
srand(I_MSTime());
@ -2223,7 +1580,7 @@ void D_DoomMain (void)
SetLanguageIDs ();
rngseed = (DWORD)time (NULL);
rngseed = I_MakeRNGSeed();
FRandom::StaticClearRandom ();
M_FindResponseFile ();
@ -2239,8 +1596,13 @@ void D_DoomMain (void)
I_FatalError ("Cannot find " BASEWAD);
}
iwad_info = &IWADInfos[IdentifyVersion(wad)];
I_SetIWADInfo(iwad_info);
// Load zdoom.pk3 alone so that we can get access to the internal gameinfos before
// the IWAD is known.
const IWADInfo *iwad_info = D_FindIWAD(wad);
gameinfo.gametype = iwad_info->gametype;
gameinfo.flags = iwad_info->flags;
GameConfig->DoGameSetup (GameNames[gameinfo.gametype]);
if (!(gameinfo.flags & GI_SHAREWARE))
@ -2508,7 +1870,7 @@ void D_DoomMain (void)
// [RH] Parse through all loaded mapinfo lumps
Printf ("G_ParseMapInfo: Load map definitions.\n");
G_ParseMapInfo ();
G_ParseMapInfo (iwad_info->MapInfo);
// [RH] Parse any SNDINFO lumps
Printf ("S_InitData: Load sound definitions.\n");

View file

@ -26,6 +26,7 @@
#define __D_MAIN__
#include "doomtype.h"
#include "gametype.h"
struct event_t;
@ -50,6 +51,7 @@ void D_PageTicker (void);
void D_PageDrawer (void);
void D_AdvanceDemo (void);
void D_StartTitle (void);
void D_AddFile (const char *file);
// [RH] Set this to something to draw an icon during the next screen refresh.
@ -78,6 +80,7 @@ enum EIWADType
IWAD_FreeDM,
IWAD_ChexQuest,
IWAD_ChexQuest3,
IWAD_Custom,
NUM_IWAD_TYPES
};
@ -96,8 +99,12 @@ struct IWADInfo
const char *Autoname; // Name of autoload ini section for this IWAD
DWORD FgColor; // Foreground color for title banner
DWORD BkColor; // Background color for title banner
EGameType gametype; // which game are we playing?
const char *MapInfo; // Base mapinfo to load
int flags;
};
extern const IWADInfo IWADInfos[NUM_IWAD_TYPES];
extern EIWADType gameiwad;
#endif

View file

@ -57,7 +57,7 @@
//
// Network packet data.
//
typedef struct
struct doomcom_t
{
DWORD id; // should be DOOMCOM_ID
SWORD intnum; // DOOM executes an int to execute commands
@ -86,7 +86,7 @@ typedef struct
// packet data to be sent
BYTE data[MAX_MSGLEN];
} doomcom_t;
};
class FDynamicBuffer

View file

@ -64,7 +64,7 @@ struct zdemoheader_s {
BYTE consoleplayer;
};
struct usercmd_s
struct usercmd_t
{
DWORD buttons;
short pitch; // up/down
@ -74,7 +74,6 @@ struct usercmd_s
short sidemove;
short upmove;
};
typedef struct usercmd_s usercmd_t;
class FArchive;

View file

@ -44,18 +44,6 @@ typedef enum
} GameMode_t;
// Mission packs - might be useful for TC stuff?
typedef enum
{
doom, // DOOM 1
doom2, // DOOM 2
pack_tnt, // TNT mission pack
pack_plut, // Plutonia pack
none
} GameMission_t;
// If rangecheck is undefined, most parameter validation debugging code
// will not be compiled
#ifndef NORANGECHECKING

View file

@ -38,10 +38,6 @@ FStringTable GStrings;
// Game speed
EGameSpeed GameSpeed = SPEED_Normal;
// Game Mode - identify IWAD as shareware, retail etc.
int gamemode = undetermined;
int gamemission = doom;
// Show developer messages if true.
CVAR (Bool, developer, false, 0)

View file

@ -51,9 +51,6 @@ extern bool devparm; // DEBUG: launched with -devparm
// -----------------------------------------------------
// Game Mode - identify IWAD as shareware, retail etc.
//
extern int gamemode;
extern int gamemission;
// -------------------------------------------
// Selected skill type, map etc.
//

View file

@ -89,7 +89,7 @@ void F_AdvanceSlideshow ();
void F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int cdid, const char *flat,
const char *text, INTBOOL textInLump, INTBOOL finalePic, INTBOOL lookupText, bool ending)
{
bool loopmusic = ending ? !(gameinfo.flags & GI_NOLOOPFINALEMUSIC) : true;
bool loopmusic = ending ? !gameinfo.noloopfinalemusic : true;
gameaction = ga_nothing;
gamestate = GS_FINALE;
viewactive = false;
@ -229,7 +229,7 @@ void F_Ticker ()
if (FinaleStage == 0)
{
if (interrupt ||
((gamemode != commercial || gameinfo.flags & GI_SHAREWARE)
((!(gameinfo.flags & GI_MAPxx) || gameinfo.flags & GI_SHAREWARE)
&& FinaleCount > FinaleTextLen*TEXTSPEED+TEXTWAIT))
{
if (FinaleCount < FinaleTextLen*TEXTSPEED+10)
@ -308,7 +308,7 @@ void F_Ticker ()
case 12: // Pic 2, Text 2
GetFinaleText ("win2msg");
FinaleEndCount = FinaleTextLen*TEXTSPEED+TEXTWAIT;
S_ChangeMusic ("orb", 0, !(gameinfo.flags & GI_NOLOOPFINALEMUSIC));
S_ChangeMusic ("orb", 0, !gameinfo.noloopfinalemusic);
break;
case 13: // Pic 2 -- Fade out
@ -319,7 +319,7 @@ void F_Ticker ()
case 14: // Pic 3 -- Fade in
FinaleEndCount = 71;
FadeDir = -1;
S_ChangeMusic ("chess", 0, !(gameinfo.flags & GI_NOLOOPFINALEMUSIC));
S_ChangeMusic ("chess", 0, !gameinfo.noloopfinalemusic);
break;
case 15: // Pic 3, Text 3
@ -460,13 +460,13 @@ void F_TextWrite (void)
// Casting by id Software.
// in order of appearance
//
typedef struct
struct castinfo_t
{
const char *name;
const char *type;
const AActor *info;
const PClass *Class;
} castinfo_t;
};
castinfo_t castorder[] =
{
@ -1247,19 +1247,19 @@ void F_Drawer (void)
{
default:
case END_Pic1:
picname = gameinfo.finalePage1;
picname = gameinfo.GetFinalePage(1);
screen->DrawTexture (TexMan[picname], 0, 0,
DTA_DestWidth, screen->GetWidth(),
DTA_DestHeight, screen->GetHeight(), TAG_DONE);
break;
case END_Pic2:
picname = gameinfo.finalePage2;
picname = gameinfo.GetFinalePage(2);
screen->DrawTexture (TexMan[picname], 0, 0,
DTA_DestWidth, screen->GetWidth(),
DTA_DestHeight, screen->GetHeight(), TAG_DONE);
break;
case END_Pic3:
picname = gameinfo.finalePage3;
picname = gameinfo.GetFinalePage(3);
screen->DrawTexture (TexMan[picname], 0, 0,
DTA_DestWidth, screen->GetWidth(),
DTA_DestHeight, screen->GetHeight(), TAG_DONE);

View file

@ -202,7 +202,7 @@ void G_SetForEndGame (char *nextmap)
{
SetEndSequence (nextmap, END_Chess);
}
else if (gamemode == commercial)
else if (gameinfo.gametype == GAME_Doom && (gameinfo.flags & GI_MAPxx))
{
SetEndSequence (nextmap, END_Cast);
}
@ -493,7 +493,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
{
if (!netgame)
{ // [RH] Change the random seed for each new single player game
rngseed = rngseed*3/2;
rngseed = rngseed + 1;
}
FRandom::StaticClearRandom ();
P_ClearACSVars(true);
@ -1283,45 +1283,28 @@ void G_InitLevelLocals ()
G_AirControlChanged ();
if (!info->LevelName.IsEmpty())
{
cluster_info_t *clus = FindClusterInfo (info->cluster);
cluster_info_t *clus = FindClusterInfo (info->cluster);
level.partime = info->partime;
level.sucktime = info->sucktime;
level.cluster = info->cluster;
level.clusterflags = clus ? clus->flags : 0;
level.flags |= info->flags;
level.flags2 |= info->flags2;
level.levelnum = info->levelnum;
level.Music = info->Music;
level.musicorder = info->musicorder;
level.partime = info->partime;
level.sucktime = info->sucktime;
level.cluster = info->cluster;
level.clusterflags = clus ? clus->flags : 0;
level.flags |= info->flags;
level.flags2 |= info->flags2;
level.levelnum = info->levelnum;
level.Music = info->Music;
level.musicorder = info->musicorder;
level.LevelName = level.info->LookupLevelName();
strncpy (level.nextmap, info->nextmap, 8);
level.nextmap[8] = 0;
strncpy (level.secretmap, info->secretmap, 8);
level.secretmap[8] = 0;
strncpy (level.skypic1, info->skypic1, 8);
level.skypic1[8] = 0;
if (!level.skypic2[0])
strncpy (level.skypic2, level.skypic1, 8);
level.skypic2[8] = 0;
}
else
{
level.partime = level.cluster = 0;
level.sucktime = 0;
level.LevelName = "Unnamed";
level.nextmap[0] =
level.secretmap[0] = 0;
level.Music = "";
strcpy (level.skypic1, "SKY1");
strcpy (level.skypic2, "SKY1");
level.flags = 0;
level.flags2 = 0;
level.levelnum = 1;
}
level.LevelName = level.info->LookupLevelName();
strncpy (level.nextmap, info->nextmap, 8);
level.nextmap[8] = 0;
strncpy (level.secretmap, info->secretmap, 8);
level.secretmap[8] = 0;
strncpy (level.skypic1, info->skypic1, 8);
level.skypic1[8] = 0;
if (!level.skypic2[0])
strncpy (level.skypic2, level.skypic1, 8);
level.skypic2[8] = 0;
compatflags.Callback();

View file

@ -82,9 +82,10 @@ struct FMapInfoParser
void ParseNextMap(char *mapname);
level_info_t *ParseMapHeader(level_info_t &defaultinfo);
void ParseMapDefinition(level_info_t &leveldef);
void ParseGameInfo();
void ParseEpisodeInfo ();
void ParseSkill ();
void ParseMapInfo (int lump, level_info_t &gamedefaults);
void ParseMapInfo (int lump, level_info_t &gamedefaults, level_info_t &defaultinfo);
void ParseOpenBrace();
bool ParseCloseBrace();
@ -500,7 +501,7 @@ level_info_t *CheckLevelRedirect (level_info_t *info);
FString CalcMapName (int episode, int level);
void G_ParseMapInfo (void);
void G_ParseMapInfo (const char *basemapinfo);
void G_ClearSnapshots (void);
void P_RemoveDefereds ();

View file

@ -259,7 +259,7 @@ void level_info_t::Reset()
intermusicorder = 0;
SoundInfo = "";
SndSeq = "";
strcpy (bordertexture, gameinfo.borderFlat);
bordertexture[0] = 0;
teamdamage = 0.f;
specialactions.Clear();
}
@ -948,6 +948,7 @@ DEFINE_MAP_OPTION(cluster, true)
{
unsigned int clusterindex = wadclusterinfos.Reserve(1);
cluster_info_t *clusterinfo = &wadclusterinfos[clusterindex];
clusterinfo->Reset();
clusterinfo->cluster = parse.sc.Number;
if (parse.HexenHack)
{
@ -1763,10 +1764,8 @@ static void SetLevelNum (level_info_t *info, int num)
//
//==========================================================================
void FMapInfoParser::ParseMapInfo (int lump, level_info_t &gamedefaults)
void FMapInfoParser::ParseMapInfo (int lump, level_info_t &gamedefaults, level_info_t &defaultinfo)
{
level_info_t defaultinfo;
sc.OpenLumpNum(lump);
defaultinfo = gamedefaults;
@ -1774,7 +1773,19 @@ void FMapInfoParser::ParseMapInfo (int lump, level_info_t &gamedefaults)
while (sc.GetString ())
{
if (sc.Compare("gamedefaults"))
if (sc.Compare("include"))
{
sc.MustGetString();
int inclump = Wads.CheckNumForFullName(sc.String, true);
if (inclump < 0)
{
sc.ScriptError("include file '%s' not found", sc.String);
}
FScanner saved_sc = sc;
ParseMapInfo(inclump, gamedefaults, defaultinfo);
sc = saved_sc;
}
else if (sc.Compare("gamedefaults"))
{
gamedefaults.Reset();
ParseMapDefinition(gamedefaults);
@ -1825,6 +1836,18 @@ void FMapInfoParser::ParseMapInfo (int lump, level_info_t &gamedefaults)
{
AllSkills.Clear();
}
else if (sc.Compare("gameinfo"))
{
if (format_type != FMT_Old)
{
format_type = FMT_New;
ParseGameInfo();
}
else
{
sc.ScriptError("gameinfo definitions not supported with old MAPINFO syntax");
}
}
else
{
sc.ScriptError("%s: Unknown top level keyword", sc.String);
@ -1841,7 +1864,7 @@ void FMapInfoParser::ParseMapInfo (int lump, level_info_t &gamedefaults)
//
//==========================================================================
void G_ParseMapInfo ()
void G_ParseMapInfo (const char *basemapinfo)
{
int lump, lastlump = 0;
level_info_t gamedefaults;
@ -1849,20 +1872,19 @@ void G_ParseMapInfo ()
atterm(ClearEpisodes);
// Parse the default MAPINFO for the current game.
for(int i=0; i<2; i++)
if (basemapinfo != NULL)
{
if (gameinfo.mapinfo[i] != NULL)
{
FMapInfoParser parse;
parse.ParseMapInfo(Wads.GetNumForFullName(gameinfo.mapinfo[i]), gamedefaults);
}
FMapInfoParser parse;
level_info_t defaultinfo;
parse.ParseMapInfo(Wads.GetNumForFullName(basemapinfo), gamedefaults, defaultinfo);
}
// Parse any extra MAPINFOs.
while ((lump = Wads.FindLump ("MAPINFO", &lastlump)) != -1)
{
FMapInfoParser parse;
parse.ParseMapInfo(lump, gamedefaults);
level_info_t defaultinfo;
parse.ParseMapInfo(lump, gamedefaults, defaultinfo);
}
EndSequences.ShrinkToFit ();

View file

@ -763,7 +763,7 @@ AWeapon *FWeaponSlot::PickWeapon(player_t *player)
{
for (j = (unsigned)(i - 1) % Weapons.Size();
j != i;
j = (unsigned)(j - 1) % Weapons.Size())
j = (unsigned)(j + Weapons.Size() - 1) % Weapons.Size()) // + Weapons.Size is to avoid underflows
{
AWeapon *weap = static_cast<AWeapon *> (player->mo->FindInventory(Weapons[j].Type));

View file

@ -275,7 +275,7 @@ enum //aspect ratios
ASPECTRATIO_4_3 = 0,
ASPECTRATIO_16_9 = 1,
ASPECTRATIO_16_10 = 2,
ASPECTRATIO_5_4 = 3,
ASPECTRATIO_5_4 = 4,
};
enum //Key words

18
src/gametype.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef EGAMETYPE
#define EGAMETYPE
enum EGameType
{
GAME_Any = 0,
GAME_Doom = 1,
GAME_Heretic = 2,
GAME_Hexen = 4,
GAME_Strife = 8,
GAME_Chex = 16, //Chex is basically Doom, but we need to have a different set of actors.
GAME_Raven = GAME_Heretic|GAME_Hexen,
GAME_DoomStrife = GAME_Doom|GAME_Strife,
GAME_DoomChex = GAME_Doom|GAME_Chex,
GAME_DoomStrifeChex = GAME_Doom|GAME_Strife|GAME_Chex
};
#endif

View file

@ -37,6 +37,11 @@
#include "gi.h"
#include "m_fixed.h"
#include "v_palette.h"
#include "sc_man.h"
#include "w_wad.h"
#include "i_system.h"
#include "v_video.h"
#include "g_level.h"
gameinfo_t gameinfo;
@ -70,512 +75,184 @@ static gameborder_t StrifeBorder =
"brdr_bl", "brdr_b", "brdr_br"
};
gameinfo_t HexenGameInfo =
// Custom GAMEINFO ------------------------------------------------------------
const char* GameInfoBoarders[] =
{
GI_PAGESARERAW | GI_MAPxx | GI_NOLOOPFINALEMUSIC | GI_INFOINDEXED | GI_ALWAYSFALLINGDAMAGE,
"TITLE",
"CREDIT",
"CREDIT",
"HEXEN",
280/35,
210/35,
200/35,
"Chat",
"hub",
"-NOFLAT",
"CREDIT",
"CREDIT",
"CREDIT",
{ { "TITLE", {4} } },
NULL,
33,
"F_022",
&HereticBorder,
32*FRACUNIT,
GAME_Hexen,
150,
"F_SKY",
24*FRACUNIT,
"xlat/heretic.txt", // not really correct but this was used before.
{ "mapinfo/hexen.txt", NULL },
MAKERGB(104,0,0),
MAKERGB(255,0,0),
"BagOfHolding", // Hexen doesn't have a backpack so use Heretic's.
NULL,
"DoomBorder",
"HereticBorder",
"StrifeBorder",
NULL
};
gameinfo_t HexenDKGameInfo =
{
GI_PAGESARERAW | GI_MAPxx | GI_NOLOOPFINALEMUSIC | GI_INFOINDEXED | GI_ALWAYSFALLINGDAMAGE,
"TITLE",
"CREDIT",
"CREDIT",
"HEXEN",
280/35,
210/35,
200/35,
"Chat",
"hub",
"-NOFLAT-",
"CREDIT",
"CREDIT",
"CREDIT",
{ { "TITLE", {4} } },
NULL,
33,
"F_022",
&HereticBorder,
32*FRACUNIT,
GAME_Hexen,
150,
"F_SKY",
24*FRACUNIT,
"xlat/heretic.txt", // not really correct but this was used before.
{ "mapinfo/hexen.txt", NULL },
MAKERGB(104,0,0),
MAKERGB(255,0,0),
"BagOfHolding",
NULL,
};
#define GAMEINFOKEY_CSTRING(key, variable, length) \
else if(nextKey.CompareNoCase(variable) == 0) \
{ \
sc.MustGetToken(TK_StringConst); \
if(strlen(sc.String) > length) \
{ \
sc.ScriptError("Value for '%s' can not be longer than %d characters.", #key, length); \
} \
strcpy(gameinfo.key, sc.String); \
}
gameinfo_t HereticGameInfo =
{
GI_PAGESARERAW | GI_INFOINDEXED,
"TITLE",
"CREDIT",
"CREDIT",
"MUS_TITL",
280/35,
210/35,
200/35,
"misc/chat",
"MUS_CPTD",
"FLOOR25",
"CREDIT",
"CREDIT",
"CREDIT",
{ { "TITLE", {4} } },
NULL,
17,
"FLAT513",
&HereticBorder,
32*FRACUNIT,
GAME_Heretic,
150,
"F_SKY1",
24*FRACUNIT,
"xlat/heretic.txt",
{ "mapinfo/heretic.txt", NULL },
MAKERGB(104,0,0),
MAKERGB(255,0,0),
"BagOfHolding",
NULL,
};
#define GAMEINFOKEY_STRINGARRAY(key, variable, length) \
else if(nextKey.CompareNoCase(variable) == 0) \
{ \
gameinfo.key.Clear(); \
do \
{ \
sc.MustGetToken(TK_StringConst); \
if(strlen(sc.String) > length) \
{ \
sc.ScriptError("Value for '%s' can not be longer than %d characters.", #key, length); \
} \
FName val = sc.String; \
gameinfo.key.Push(val); \
} \
while (sc.CheckToken(',')); \
}
gameinfo_t HereticSWGameInfo =
{
GI_PAGESARERAW | GI_SHAREWARE | GI_INFOINDEXED,
"TITLE",
"CREDIT",
"ORDER",
"MUS_TITL",
280/35,
210/35,
200/35,
"misc/chat",
"MUS_CPTD",
"FLOOR25",
"ORDER",
"CREDIT",
"CREDIT",
{ { "TITLE", {5} } },
NULL,
17,
"FLOOR04",
&HereticBorder,
32*FRACUNIT,
GAME_Heretic,
150,
"F_SKY1",
24*FRACUNIT,
"xlat/heretic.txt",
{ "mapinfo/heretic.txt", NULL },
MAKERGB(104,0,0),
MAKERGB(255,0,0),
"BagOfHolding",
NULL,
};
#define GAMEINFOKEY_STRING(key, variable) \
else if(nextKey.CompareNoCase(variable) == 0) \
{ \
sc.MustGetToken(TK_StringConst); \
gameinfo.key = sc.String; \
}
gameinfo_t SharewareGameInfo =
{
GI_SHAREWARE,
"TITLEPIC",
"CREDIT",
"HELP2",
"$MUSIC_INTRO",
5,
0,
200/35,
"misc/chat2",
"$MUSIC_VICTOR",
"FLOOR4_8",
"HELP2",
"VICTORY2",
"HELP2",
{ { "HELP1", "HELP2" } },
"menu/quit1",
1,
"FLOOR7_2",
&DoomBorder,
0,
GAME_Doom,
100,
"F_SKY1",
24*FRACUNIT,
"xlat/doom.txt",
{ "mapinfo/doomcommon.txt", "mapinfo/doom1.txt" },
MAKERGB(104,0,0),
MAKERGB(255,0,0),
"Backpack",
"sbarinfo/doom.txt",
};
#define GAMEINFOKEY_INT(key, variable) \
else if(nextKey.CompareNoCase(variable) == 0) \
{ \
sc.MustGetNumber(); \
gameinfo.key = sc.Number; \
}
gameinfo_t RegisteredGameInfo =
{
0,
"TITLEPIC",
"CREDIT",
"HELP2",
"$MUSIC_INTRO",
5,
0,
200/35,
"misc/chat2",
"$MUSIC_VICTOR",
"FLOOR4_8",
"HELP2",
"VICTORY2",
"ENDPIC",
{ { "HELP1", "HELP2" } },
"menu/quit1",
2,
"FLOOR7_2",
&DoomBorder,
0,
GAME_Doom,
100,
"F_SKY1",
24*FRACUNIT,
"xlat/doom.txt",
{ "mapinfo/doomcommon.txt", "mapinfo/doom1.txt" },
MAKERGB(104,0,0),
MAKERGB(255,0,0),
"Backpack",
"sbarinfo/doom.txt",
};
#define GAMEINFOKEY_FLOAT(key, variable) \
else if(nextKey.CompareNoCase(variable) == 0) \
{ \
sc.MustGetFloat(); \
gameinfo.key = static_cast<float> (sc.Float); \
}
gameinfo_t ChexGameInfo =
{
GI_CHEX_QUEST,
"TITLEPIC",
"CREDIT",
"HELP1",
"$MUSIC_INTRO",
5,
0,
200/35,
"misc/chat2",
"$MUSIC_VICTOR",
"FLOOR4_8",
"HELP2",
"VICTORY2",
"ENDPIC",
{ { "HELP1", "CREDIT" } },
"menu/quit1",
2,
"FLOOR7_2",
&DoomBorder,
0,
GAME_Chex,
100,
"F_SKY1",
24*FRACUNIT,
"xlat/doom.txt",
{ "mapinfo/chex.txt", NULL },
MAKERGB(63,125,57),
MAKERGB(95,175,87),
"ZorchPack",
"sbarinfo/doom.txt",
};
#define GAMEINFOKEY_FIXED(key, variable) \
else if(nextKey.CompareNoCase(variable) == 0) \
{ \
sc.MustGetFloat(); \
gameinfo.key = static_cast<int> (sc.Float*FRACUNIT); \
}
gameinfo_t Chex3GameInfo =
{
GI_CHEX_QUEST,
"TITLEPIC",
"ENDPIC",
"VICTORY2",
"$MUSIC_INTRO",
5,
0,
200/35,
"misc/chat2",
"$MUSIC_VICTOR",
"ENDPIC01",
"CREDIT",
"CREDIT",
"ENDPIC",
{ { "HELP1", "CREDIT" } },
"menu/quit1",
2,
"FLOOR7_2",
&DoomBorder,
0,
GAME_Chex,
100,
"F_SKY1",
24*FRACUNIT,
"xlat/doom.txt",
{ "mapinfo/chex.txt", NULL },
MAKERGB(63,125,57),
MAKERGB(95,175,87),
"ZorchPack",
"sbarinfo/doom.txt",
};
#define GAMEINFOKEY_COLOR(key, variable) \
else if(nextKey.CompareNoCase(variable) == 0) \
{ \
sc.MustGetToken(TK_StringConst); \
FString color = sc.String; \
FString colorName = V_GetColorStringByName(color); \
if(!colorName.IsEmpty()) \
color = colorName; \
gameinfo.key = V_GetColorFromString(NULL, color); \
}
gameinfo_t RetailGameInfo =
{
GI_MENUHACK_RETAIL,
"TITLEPIC",
"CREDIT",
"CREDIT",
"$MUSIC_INTRO",
5,
0,
200/35,
"misc/chat2",
"$MUSIC_VICTOR",
"FLOOR4_8",
"CREDIT",
"VICTORY2",
"ENDPIC",
{ { "HELP1", "CREDIT" } },
"menu/quit1",
2,
"FLOOR7_2",
&DoomBorder,
0,
GAME_Doom,
100,
"F_SKY1",
24*FRACUNIT,
"xlat/doom.txt",
{ "mapinfo/doomcommon.txt", "mapinfo/doom1.txt" },
MAKERGB(104,0,0),
MAKERGB(255,0,0),
"Backpack",
"sbarinfo/doom.txt",
};
#define GAMEINFOKEY_BOOL(key, variable) \
else if(nextKey.CompareNoCase(variable) == 0) \
{ \
if(sc.CheckToken(TK_False)) \
gameinfo.key = false; \
else \
{ \
sc.MustGetToken(TK_True); \
gameinfo.key = true; \
} \
}
gameinfo_t CommercialGameInfo =
void FMapInfoParser::ParseGameInfo()
{
GI_MAPxx | GI_MENUHACK_COMMERCIAL,
"TITLEPIC",
"CREDIT",
"CREDIT",
"$MUSIC_DM2TTL",
11,
0,
200/35,
"misc/chat",
"$MUSIC_READ_M",
"SLIME16",
"CREDIT",
"CREDIT",
"CREDIT",
{ { "HELP", "CREDIT" } },
"menu/quit2",
3,
"GRNROCK",
&DoomBorder,
0,
GAME_Doom,
100,
"F_SKY1",
24*FRACUNIT,
"xlat/doom.txt",
{ "mapinfo/doomcommon.txt", "mapinfo/doom2.txt" },
MAKERGB(104,0,0),
MAKERGB(255,0,0),
"Backpack",
"sbarinfo/doom.txt",
};
sc.MustGetToken('{');
while(sc.GetToken())
{
if (sc.TokenType == '}') return;
gameinfo_t PlutoniaGameInfo =
{
GI_MAPxx | GI_MENUHACK_COMMERCIAL,
"TITLEPIC",
"CREDIT",
"CREDIT",
"$MUSIC_DM2TTL",
11,
0,
200/35,
"misc/chat",
"$MUSIC_READ_M",
"SLIME16",
"CREDIT",
"CREDIT",
"CREDIT",
{ { "HELP", "CREDIT" } },
"menu/quit2",
3,
"GRNROCK",
&DoomBorder,
0,
GAME_Doom,
100,
"F_SKY1",
24*FRACUNIT,
"xlat/doom.txt",
{ "mapinfo/doomcommon.txt", "mapinfo/plutonia.txt" },
MAKERGB(104,0,0),
MAKERGB(255,0,0),
"Backpack",
"sbarinfo/doom.txt",
};
sc.TokenMustBe(TK_Identifier);
FString nextKey = sc.String;
sc.MustGetToken('=');
gameinfo_t TNTGameInfo =
{
GI_MAPxx | GI_MENUHACK_COMMERCIAL,
"TITLEPIC",
"CREDIT",
"CREDIT",
"$MUSIC_DM2TTL",
11,
0,
200/35,
"misc/chat",
"$MUSIC_READ_M",
"SLIME16",
"CREDIT",
"CREDIT",
"CREDIT",
{ { "HELP", "CREDIT" } },
"menu/quit2",
3,
"GRNROCK",
&DoomBorder,
0,
GAME_Doom,
100,
"F_SKY1",
24*FRACUNIT,
"xlat/doom.txt",
{ "mapinfo/doomcommon.txt", "mapinfo/tnt.txt" },
MAKERGB(104,0,0),
MAKERGB(255,0,0),
"Backpack",
"sbarinfo/doom.txt",
};
if(nextKey.CompareNoCase("border") == 0)
{
if(sc.CheckToken(TK_Identifier))
{
switch(sc.MustMatchString(GameInfoBoarders))
{
default:
gameinfo.border = &DoomBorder;
break;
case 1:
gameinfo.border = &HereticBorder;
break;
case 2:
gameinfo.border = &StrifeBorder;
break;
}
}
else
{
// border = {size, offset, tr, t, tl, r, l ,br, b, bl};
char *graphics[8] = {DoomBorder.tr, DoomBorder.t, DoomBorder.tl, DoomBorder.r, DoomBorder.l, DoomBorder.br, DoomBorder.b, DoomBorder.bl};
sc.MustGetToken('{');
sc.MustGetToken(TK_IntConst);
DoomBorder.offset = sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
DoomBorder.size = sc.Number;
for(int i = 0;i < 8;i++)
{
sc.MustGetToken(',');
sc.MustGetToken(TK_StringConst);
int len = int(strlen(sc.String));
if(len > 8)
sc.ScriptError("Border graphic can not be more than 8 characters long.\n");
memcpy(graphics[i], sc.String, len);
if(len < 8) // end with a null byte if the string is less than 8 chars.
graphics[i][len] = 0;
}
sc.MustGetToken('}');
}
}
// Insert valid keys here.
GAMEINFOKEY_CSTRING(titlePage, "titlePage", 8)
GAMEINFOKEY_STRINGARRAY(creditPages, "creditPage", 8)
GAMEINFOKEY_STRING(titleMusic, "titleMusic")
GAMEINFOKEY_FLOAT(titleTime, "titleTime")
GAMEINFOKEY_FLOAT(advisoryTime, "advisoryTime")
GAMEINFOKEY_FLOAT(pageTime, "pageTime")
GAMEINFOKEY_STRING(chatSound, "chatSound")
GAMEINFOKEY_STRING(finaleMusic, "finaleMusic")
GAMEINFOKEY_CSTRING(finaleFlat, "finaleFlat", 8)
GAMEINFOKEY_STRINGARRAY(finalePages, "finalePage", 8)
GAMEINFOKEY_STRINGARRAY(infoPages, "infoPage", 8)
GAMEINFOKEY_STRING(quitSound, "quitSound")
GAMEINFOKEY_CSTRING(borderFlat, "borderFlat", 8)
GAMEINFOKEY_FIXED(telefogheight, "telefogheight")
GAMEINFOKEY_INT(defKickback, "defKickback")
GAMEINFOKEY_CSTRING(SkyFlatName, "SkyFlatName", 8)
GAMEINFOKEY_STRING(translator, "translator")
GAMEINFOKEY_COLOR(defaultbloodcolor, "defaultbloodcolor")
GAMEINFOKEY_COLOR(defaultbloodparticlecolor, "defaultbloodparticlecolor")
GAMEINFOKEY_STRING(backpacktype, "backpacktype")
GAMEINFOKEY_STRING(statusbar, "statusbar")
GAMEINFOKEY_STRING(intermissionMusic, "intermissionMusic")
GAMEINFOKEY_BOOL(noloopfinalemusic, "noloopfinalemusic")
GAMEINFOKEY_BOOL(drawreadthis, "drawreadthis")
else
{
// ignore unkown keys.
sc.UnGet();
SkipToNext();
}
}
}
gameinfo_t StrifeGameInfo =
const char *gameinfo_t::GetFinalePage(unsigned int num) const
{
GI_MAPxx | GI_INFOINDEXED | GI_ALWAYSFALLINGDAMAGE,
"TITLEPIC",
"CREDIT",
"CREDIT",
"D_LOGO",
280/35,
0,
200/35,
"misc/chat",
"d_intro",
"-NOFLAT",
"CREDIT",
"CREDIT",
"CREDIT",
{ { "CREDIT", {4} } },
NULL,
49,
"F_PAVE01",
&StrifeBorder,
0,
GAME_Strife,
150,
"F_SKY001",
16*FRACUNIT,
"xlat/strife.txt",
{ "mapinfo/strife.txt", NULL },
MAKERGB(104,0,0),
MAKERGB(255,0,0),
"AmmoSatchel",
NULL,
};
gameinfo_t StrifeTeaserGameInfo =
{
GI_MAPxx | GI_INFOINDEXED | GI_ALWAYSFALLINGDAMAGE | GI_SHAREWARE,
"TITLEPIC",
"CREDIT",
"CREDIT",
"D_LOGO",
280/35,
0,
200/35,
"misc/chat",
"d_intro",
"-NOFLAT",
"CREDIT",
"CREDIT",
"CREDIT",
{ { "CREDIT", {4} } },
NULL,
49,
"F_PAVE01",
&StrifeBorder,
0,
GAME_Strife,
150,
"F_SKY001",
16*FRACUNIT,
"xlat/strife.txt",
{ "mapinfo/strife.txt", NULL },
MAKERGB(104,0,0),
MAKERGB(255,0,0),
"AmmoSatchel",
NULL,
};
gameinfo_t StrifeTeaser2GameInfo =
{
GI_MAPxx | GI_INFOINDEXED | GI_ALWAYSFALLINGDAMAGE | GI_SHAREWARE | GI_TEASER2,
"TITLEPIC",
"CREDIT",
"CREDIT",
"D_LOGO",
280/35,
0,
200/35,
"misc/chat",
"d_intro",
"-NOFLAT",
"CREDIT",
"CREDIT",
"CREDIT",
{ { "CREDIT", {4} } },
NULL,
49,
"F_PAVE01",
&StrifeBorder,
0,
GAME_Strife,
150,
"F_SKY001",
16*FRACUNIT,
"xlat/strife.txt",
{ "mapinfo/strife.txt", NULL },
MAKERGB(104,0,0),
MAKERGB(255,0,0),
"AmmoSatchel",
NULL,
};
if (finalePages.Size() == 0) return "-NOFLAT-";
else if (num < 1 || num > finalePages.Size()) return finalePages[0];
else return finalePages[num-1];
}

View file

@ -35,41 +35,19 @@
#define __GI_H__
#include "basictypes.h"
#include "zstring.h"
// Flags are not user configurable and only depend on the standard IWADs
#define GI_MAPxx 0x00000001
#define GI_PAGESARERAW 0x00000002
#define GI_SHAREWARE 0x00000004
#define GI_NOLOOPFINALEMUSIC 0x00000008
#define GI_INFOINDEXED 0x00000010
#define GI_MENUHACK 0x00000060
#define GI_MENUHACK_RETAIL 0x00000020
#define GI_MENUHACK_EXTENDED 0x00000040 // (Heretic)
#define GI_MENUHACK_COMMERCIAL 0x00000060
#define GI_ALWAYSFALLINGDAMAGE 0x00000080
#define GI_TEASER2 0x00000100 // Alternate version of the Strife Teaser
#define GI_CHEX_QUEST 0x00000200
#define GI_SHAREWARE 0x00000002
#define GI_MENUHACK_EXTENDED 0x00000004 // (Heretic)
#define GI_TEASER2 0x00000008 // Alternate version of the Strife Teaser
#ifndef EGAMETYPE
#define EGAMETYPE
enum EGameType
{
GAME_Any = 0,
GAME_Doom = 1,
GAME_Heretic = 2,
GAME_Hexen = 4,
GAME_Strife = 8,
GAME_Chex = 16, //Chex is basically Doom, but we need to have a different set of actors.
GAME_Raven = GAME_Heretic|GAME_Hexen,
GAME_DoomStrife = GAME_Doom|GAME_Strife,
GAME_DoomChex = GAME_Doom|GAME_Chex,
GAME_DoomStrifeChex = GAME_Doom|GAME_Strife|GAME_Chex
};
#endif
#include "gametype.h"
extern const char *GameNames[17];
typedef struct
struct gameborder_t
{
BYTE offset;
BYTE size;
@ -81,49 +59,43 @@ typedef struct
char bl[8];
char b[8];
char br[8];
} gameborder_t;
};
typedef struct
struct gameinfo_t
{
int flags;
EGameType gametype;
char titlePage[9];
char creditPage1[9];
char creditPage2[9];
char titleMusic[16];
bool drawreadthis;
bool noloopfinalemusic;
TArray<FName> creditPages;
TArray<FName> finalePages;
TArray<FName> infoPages;
FString titleMusic;
float titleTime;
float advisoryTime;
float pageTime;
char chatSound[16];
char finaleMusic[16];
FString chatSound;
FString finaleMusic;
char finaleFlat[9];
char finalePage1[9];
char finalePage2[9];
char finalePage3[9];
union
{
char infoPage[2][9];
struct
{
char basePage[9];
char numPages;
} indexed;
} info;
const char *quitSound;
int maxSwitch;
FString quitSound;
char borderFlat[9];
gameborder_t *border;
int telefogheight;
EGameType gametype;
int defKickback;
char SkyFlatName[9];
fixed_t StepHeight;
const char *translator;
const char *mapinfo[2];
FString translator;
DWORD defaultbloodcolor;
DWORD defaultbloodparticlecolor;
const char *backpacktype;
const char *statusbar;
} gameinfo_t;
FString backpacktype;
FString statusbar;
FString intermissionMusic;
const char *GetFinalePage(unsigned int num) const;
};
extern gameinfo_t gameinfo;

View file

@ -45,6 +45,7 @@
#include "cmdlib.h"
#include "sc_man.h"
#include "doomstat.h"
#include "d_main.h"
#include "gl/gl_struct.h"
#include "gl/gl_texture.h"
@ -78,6 +79,9 @@ int FGLTexture::CheckDDPK3()
static const char * strifetexpath[]= {
"data/jstrife/textures/%s.%s", NULL };
static const char * chextexpath[]= {
"data/jchex/textures/%s.%s", NULL };
static const char * doomflatpath[]= {
"data/jdoom/flats/%s.%s", NULL };
@ -90,6 +94,9 @@ int FGLTexture::CheckDDPK3()
static const char * strifeflatpath[]= {
"data/jstrife/flats/%s.%s", NULL };
static const char * chexflatpath[]= {
"data/jchex/flats/%s.%s", NULL };
FString checkName;
const char ** checklist;
@ -105,37 +112,52 @@ int FGLTexture::CheckDDPK3()
// for patches this doesn't work yet
if (ispatch) return -3;
switch (gameinfo.gametype)
switch (gameiwad)
{
case GAME_Doom:
switch (gamemission)
{
case doom:
checklist = useType==FTexture::TEX_Flat? doomflatpath : doom1texpath;
break;
case doom2:
checklist = useType==FTexture::TEX_Flat? doomflatpath : doom2texpath;
break;
case pack_tnt:
checklist = useType==FTexture::TEX_Flat? doomflatpath : tnttexpath;
break;
case pack_plut:
checklist = useType==FTexture::TEX_Flat? doomflatpath : pluttexpath;
break;
default:
return -3;
}
case IWAD_DoomShareware:
case IWAD_UltimateDoom:
case IWAD_DoomRegistered:
case IWAD_FreeDoom1:
checklist = useType==FTexture::TEX_Flat? doomflatpath : doom1texpath;
break;
case GAME_Heretic:
case IWAD_Doom2:
case IWAD_FreeDoom:
case IWAD_FreeDM:
checklist = useType==FTexture::TEX_Flat? doomflatpath : doom2texpath;
break;
case IWAD_Doom2TNT:
checklist = useType==FTexture::TEX_Flat? doomflatpath : tnttexpath;
break;
case IWAD_Doom2Plutonia:
checklist = useType==FTexture::TEX_Flat? doomflatpath : pluttexpath;
break;
case IWAD_HereticShareware:
case IWAD_HereticExtended:
case IWAD_Heretic:
checklist = useType==FTexture::TEX_Flat? hereticflatpath : heretictexpath;
break;
case GAME_Hexen:
case IWAD_Hexen:
case IWAD_HexenDK:
case IWAD_HexenDemo:
checklist = useType==FTexture::TEX_Flat? hexenflatpath : hexentexpath;
break;
case GAME_Strife:
case IWAD_Strife:
case IWAD_StrifeTeaser:
case IWAD_StrifeTeaser2:
checklist = useType==FTexture::TEX_Flat? strifeflatpath : strifetexpath;
break;
case IWAD_ChexQuest:
case IWAD_ChexQuest3: // check this!
checklist = useType==FTexture::TEX_Flat? chexflatpath : chextexpath;
break;
default:
return -3;
}
@ -197,6 +219,10 @@ int FGLTexture::CheckExternalFile(bool & hascolorkey)
"%stextures/strife/%s.%s", "%stextures/strife/%s-ck.%s", "%stextures/%s.%s", "%stextures/%s-ck.%s", NULL
};
static const char * chextexpath[]= {
"%stextures/chex/%s.%s", "%stextures/chex/%s-ck.%s", "%stextures/%s.%s", "%stextures/%s-ck.%s", NULL
};
static const char * doom1flatpath[]= {
"%sflats/doom/doom1/%s.%s", "%stextures/doom/doom1/flat-%s.%s",
"%sflats/doom/%s.%s", "%stextures/doom/flat-%s.%s", "%sflats/%s.%s", "%stextures/flat-%s.%s", NULL
@ -231,6 +257,10 @@ int FGLTexture::CheckExternalFile(bool & hascolorkey)
"%sflats/strife/%s.%s", "%stextures/strife/flat-%s.%s", "%sflats/%s.%s", "%stextures/flat-%s.%s", NULL
};
static const char * chexflatpath[]= {
"%sflats/chex/%s.%s", "%stextures/chex/flat-%s.%s", "%sflats/%s.%s", "%stextures/flat-%s.%s", NULL
};
static const char * doom1patchpath[]= {
"%spatches/doom/doom1/%s.%s", "%spatches/doom/%s.%s", "%spatches/%s.%s", NULL
};
@ -259,6 +289,10 @@ int FGLTexture::CheckExternalFile(bool & hascolorkey)
"%spatches/strife/%s.%s", "%spatches/%s.%s", NULL
};
static const char * chexpatchpath[]= {
"%spatches/chex/%s.%s", "%spatches/%s.%s", NULL
};
FString checkName;
const char ** checklist;
BYTE useType=tex->UseType;
@ -273,37 +307,52 @@ int FGLTexture::CheckExternalFile(bool & hascolorkey)
// for patches this doesn't work yet
if (ispatch) return -3;
switch (gameinfo.gametype)
switch (gameiwad)
{
case GAME_Doom:
switch (gamemission)
{
case doom:
checklist = ispatch ? doom1patchpath : useType==FTexture::TEX_Flat? doom1flatpath : doom1texpath;
break;
case doom2:
checklist = ispatch ? doom2patchpath : useType==FTexture::TEX_Flat? doom2flatpath : doom2texpath;
break;
case pack_tnt:
checklist = ispatch ? tntpatchpath : useType==FTexture::TEX_Flat? tntflatpath : tnttexpath;
break;
case pack_plut:
checklist = ispatch ? plutpatchpath : useType==FTexture::TEX_Flat? plutflatpath : pluttexpath;
break;
default:
return -3;
}
case IWAD_DoomShareware:
case IWAD_UltimateDoom:
case IWAD_DoomRegistered:
case IWAD_FreeDoom1:
checklist = ispatch ? doom1patchpath : useType==FTexture::TEX_Flat? doom1flatpath : doom1texpath;
break;
case GAME_Heretic:
case IWAD_Doom2:
case IWAD_FreeDoom:
case IWAD_FreeDM:
checklist = ispatch ? doom2patchpath : useType==FTexture::TEX_Flat? doom2flatpath : doom2texpath;
break;
case IWAD_Doom2TNT:
checklist = ispatch ? tntpatchpath : useType==FTexture::TEX_Flat? tntflatpath : tnttexpath;
break;
case IWAD_Doom2Plutonia:
checklist = ispatch ? plutpatchpath : useType==FTexture::TEX_Flat? plutflatpath : pluttexpath;
break;
case IWAD_HereticShareware:
case IWAD_HereticExtended:
case IWAD_Heretic:
checklist = ispatch ? hereticpatchpath : useType==FTexture::TEX_Flat? hereticflatpath : heretictexpath;
break;
case GAME_Hexen:
case IWAD_Hexen:
case IWAD_HexenDK:
case IWAD_HexenDemo:
checklist = ispatch ? hexenpatchpath : useType==FTexture::TEX_Flat? hexenflatpath : hexentexpath;
break;
case GAME_Strife:
case IWAD_Strife:
case IWAD_StrifeTeaser:
case IWAD_StrifeTeaser2:
checklist = ispatch ?strifepatchpath : useType==FTexture::TEX_Flat? strifeflatpath : strifetexpath;
break;
case IWAD_ChexQuest:
case IWAD_ChexQuest3: // check this!
checklist = ispatch ?chexpatchpath : useType==FTexture::TEX_Flat? chexflatpath : chextexpath;
break;
default:
return -3;
}

View file

@ -142,23 +142,7 @@ struct FStateLabels
FArchive &operator<< (FArchive &arc, FState *&state);
#ifndef EGAMETYPE
#define EGAMETYPE
enum EGameType
{
GAME_Any = 0,
GAME_Doom = 1,
GAME_Heretic = 2,
GAME_Hexen = 4,
GAME_Strife = 8,
GAME_Chex = 16,
GAME_Raven = GAME_Heretic|GAME_Hexen,
GAME_DoomStrife = GAME_Doom|GAME_Strife,
GAME_DoomChex = GAME_Doom|GAME_Chex,
GAME_DoomStrifeChex = GAME_Doom|GAME_Strife|GAME_Chex
};
#endif
#include "gametype.h"
typedef TMap<FName, fixed_t> DmgFactors;
typedef TMap<FName, BYTE> PainChanceList;

View file

@ -1460,36 +1460,23 @@ void M_DrawReadThis ()
FTexture *tex = NULL, *prevpic = NULL;
fixed_t alpha;
if (gameinfo.flags & GI_INFOINDEXED)
// Did the mapper choose a custom help page via MAPINFO?
if ((level.info != NULL) && level.info->f1[0] != 0)
{
char name[9];
name[8] = 0;
Wads.GetLumpName (name, Wads.GetNumForName (gameinfo.info.indexed.basePage, ns_graphics) + InfoType);
tex = TexMan[name];
if (InfoType > 1)
{
Wads.GetLumpName (name, Wads.GetNumForName (gameinfo.info.indexed.basePage, ns_graphics) + InfoType - 1);
prevpic = TexMan[name];
}
tex = TexMan.FindTexture(level.info->f1);
InfoType = 1;
}
else
if (tex == NULL)
{
// Did the mapper choose a custom help page via MAPINFO?
if ((level.info != NULL) && level.info->f1[0] != 0)
{
tex = TexMan.FindTexture(level.info->f1);
}
if (tex == NULL)
{
tex = TexMan[gameinfo.info.infoPage[InfoType-1]];
}
if (InfoType > 1)
{
prevpic = TexMan[gameinfo.info.infoPage[InfoType-2]];
}
tex = TexMan[gameinfo.infoPages[InfoType-1].GetChars()];
}
if (InfoType > 1)
{
prevpic = TexMan[gameinfo.infoPages[InfoType-2].GetChars()];
}
alpha = MIN<fixed_t> (Scale (gametic - InfoTic, OPAQUE, TICRATE/3), OPAQUE);
if (alpha < OPAQUE && prevpic != NULL)
{
@ -1975,14 +1962,7 @@ void M_ReadThisMore (int choice)
{
InfoType++;
InfoTic = gametic;
if (gameinfo.flags & GI_INFOINDEXED)
{
if (InfoType >= gameinfo.info.indexed.numPages)
{
M_FinishReadThis (0);
}
}
else if (InfoType > 2)
if ((level.info != NULL && level.info->f1[0] != 0) || InfoType > int(gameinfo.infoPages.Size()))
{
M_FinishReadThis (0);
}
@ -3504,19 +3484,15 @@ void M_Init (void)
LINEHEIGHT = 20;
}
switch (gameinfo.flags & GI_MENUHACK)
if (!gameinfo.drawreadthis)
{
case GI_MENUHACK_COMMERCIAL:
MainMenu[MainDef.numitems-2] = MainMenu[MainDef.numitems-1];
MainDef.numitems--;
MainDef.y += 8;
ReadDef.routine = M_DrawReadThis;
ReadDef.x = 330;
ReadDef.y = 165;
ReadMenu[0].routine = M_FinishReadThis;
break;
default:
break;
//ReadMenu[0].routine = M_FinishReadThis;
}
M_OptInit ();

View file

@ -116,7 +116,8 @@ typedef enum {
struct GUIDName;
typedef struct menuitem_s {
struct menuitem_t
{
itemtype type;
const char *label;
union {
@ -159,7 +160,7 @@ typedef struct menuitem_s {
int highlight;
int flagmask;
} e;
} menuitem_t;
};
struct menu_t {
const char *texttitle;
@ -190,7 +191,7 @@ struct valueenum_t {
const char *name; // Name on menu
};
typedef struct
struct oldmenuitem_t
{
// -1 = no cursor here, 1 = ok, 2 = arrows ok
SBYTE status;
@ -206,9 +207,9 @@ typedef struct
// choice=0:leftarrow,1:rightarrow
void (*routine)(int choice);
int textcolor;
} oldmenuitem_t;
};
typedef struct oldmenu_s
struct oldmenu_t
{
short numitems; // # of menu items
oldmenuitem_t *menuitems; // menu items
@ -216,9 +217,9 @@ typedef struct oldmenu_s
short x;
short y; // x,y of menu
short lastOn; // last item user was on in menu
} oldmenu_t;
};
typedef struct
struct menustack_t
{
union {
menu_t *newmenu;
@ -226,7 +227,7 @@ typedef struct
} menu;
bool isNewStyle;
bool drawSkull;
} menustack_t;
};
extern value_t YesNo[2];
extern value_t NoYes[2];

View file

@ -401,7 +401,7 @@ void M_LoadDefaults ()
//
typedef struct
struct pcx_t
{
char manufacturer;
char version;
@ -424,7 +424,7 @@ typedef struct
unsigned short palette_type;
char filler[58];
} pcx_t;
};
//
@ -648,7 +648,7 @@ void M_ScreenShot (const char *filename)
{
size_t dirlen;
autoname = Args->CheckValue("-shotdir");
if (autoname == NULL)
if (autoname.IsEmpty())
{
autoname = screenshot_dir;
}
@ -671,6 +671,7 @@ void M_ScreenShot (const char *filename)
}
}
autoname = NicePath(autoname);
CreatePath(autoname);
if (!FindFreeName (autoname, writepcx ? "pcx" : "png"))
{
Printf ("M_ScreenShot: Delete some screenshots\n");
@ -682,7 +683,6 @@ void M_ScreenShot (const char *filename)
autoname = filename;
DefaultExtension (autoname, writepcx ? ".pcx" : ".png");
}
CreatePath(screenshot_dir);
// save the screenshot
const BYTE *buffer;

View file

@ -1,33 +1,61 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// $Id: m_random.c,v 1.6 1998/05/03 23:13:18 killough Exp $
//
// Copyright (C) 1993-1996 by id Software, Inc.
//
// This source is available for distribution and/or modification
// only under the terms of the DOOM Source Code License as
// published by id Software. All rights reserved.
//
// The source is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
// for more details.
//
//
// DESCRIPTION:
// Random number LUT.
//
// 1/19/98 killough: Rewrote random number generator for better randomness,
// while at the same time maintaining demo sync and backward compatibility.
//
// 2/16/98 killough: Made each RNG local to each control-equivalent block,
// to reduce the chances of demo sync problems.
//
// [RH] Changed to use different class instances for different RNGs. Be
// sure to compile with _DEBUG if you want to catch bad RNG names.
//
//-----------------------------------------------------------------------------
/*
** m_random.cpp
** Random number generators
**
**---------------------------------------------------------------------------
** Copyright 2002-2009 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
** This file employs the techniques for improving demo sync and backward
** compatibility that Lee Killough introduced with BOOM. However, none of
** the actual code he wrote is left. In contrast to BOOM, each RNG source
** in ZDoom is implemented as a separate class instance that provides an
** interface to the high-quality Mersenne Twister. See
** <http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html>.
**
** As Killough's description from m_random.h is still mostly relevant,
** here it is:
** killough 2/16/98:
**
** Make every random number generator local to each control-equivalent block.
** Critical for demo sync. The random number generators are made local to
** reduce the chances of sync problems. In Doom, if a single random number
** generator call was off, it would mess up all random number generators.
** This reduces the chances of it happening by making each RNG local to a
** control flow block.
**
** Notes to developers: if you want to reduce your demo sync hassles, follow
** this rule: for each call to P_Random you add, add a new class to the enum
** type below for each block of code which calls P_Random. If two calls to
** P_Random are not in "control-equivalent blocks", i.e. there are any cases
** where one is executed, and the other is not, put them in separate classes.
*/
// HEADER FILES ------------------------------------------------------------
#include <assert.h>
@ -41,36 +69,73 @@
#include "c_dispatch.h"
#include "files.h"
// MACROS ------------------------------------------------------------------
#define RAND_ID MAKE_ID('r','a','N','d')
// TYPES -------------------------------------------------------------------
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
extern FRandom pr_spawnmobj;
extern FRandom pr_acs;
extern FRandom pr_chase;
extern FRandom pr_lost;
extern FRandom pr_slam;
extern FRandom pr_exrandom;
// PUBLIC DATA DEFINITIONS -------------------------------------------------
FRandom M_Random;
inline int UpdateSeed (DWORD &seed)
{
DWORD oldseed = seed;
seed = oldseed * 1664525ul + 221297ul;
return (int)oldseed;
}
// Global seed. This is modified predictably to initialize every RNG.
DWORD rngseed;
DWORD rngseed = 1993; // killough 3/26/98: The seed
// PRIVATE DATA DEFINITIONS ------------------------------------------------
FRandom *FRandom::RNGList;
static TDeletingArray<FRandom *> NewRNGs;
// CODE --------------------------------------------------------------------
//==========================================================================
//
// FRandom - Nameless constructor
//
// Constructing an RNG in this way means it won't be stored in savegames.
//
//==========================================================================
FRandom::FRandom ()
: Seed (0), Next (NULL), NameCRC (0)
: NameCRC (0)
{
#ifdef _DEBUG
#ifndef NDEBUG
Name = NULL;
initialized = false;
#endif
Next = RNGList;
RNGList = this;
}
//==========================================================================
//
// FRandom - Named constructor
//
// This is the standard way to construct RNGs.
//
//==========================================================================
FRandom::FRandom (const char *name)
: Seed (0)
{
NameCRC = CalcCRC32 ((const BYTE *)name, (unsigned int)strlen (name));
#ifdef _DEBUG
#ifndef NDEBUG
initialized = false;
Name = name;
// A CRC of 0 is reserved for nameless RNGs that don't get stored
// in savegames. The chance is very low that you would get a CRC of 0,
@ -87,7 +152,7 @@ FRandom::FRandom (const char *name)
probe = probe->Next;
}
#ifdef _DEBUG
#ifndef NDEBUG
if (probe != NULL)
{
// Because RNGs are identified by their CRCs in save games,
@ -101,6 +166,12 @@ FRandom::FRandom (const char *name)
*prev = this;
}
//==========================================================================
//
// FRandom - Destructor
//
//==========================================================================
FRandom::~FRandom ()
{
FRandom *rng, **prev;
@ -122,101 +193,100 @@ FRandom::~FRandom ()
}
}
int FRandom::operator() ()
{
return (UpdateSeed (Seed) >> 20) & 255;
}
int FRandom::operator() (int mod)
{
if (mod <= 256)
{ // The mod is small enough, so a byte is enough to get a good number.
return (*this)() % mod;
}
else
{ // For mods > 256, construct a 32-bit int and modulo that.
int num = (*this)();
num = (num << 8) | (*this)();
num = (num << 8) | (*this)();
num = (num << 8) | (*this)();
return (num&0x7fffffff) % mod;
}
}
int FRandom::Random2 ()
{
int t = (*this)();
int u = (*this)();
return t - u;
}
int FRandom::Random2 (int mask)
{
int t = (*this)() & mask;
int u = (*this)() & mask;
return t - u;
}
int FRandom::HitDice (int count)
{
return (1 + ((UpdateSeed (Seed) >> 20) & 7)) * count;
}
// Initialize all the seeds
//==========================================================================
//
// This initialization method is critical to maintaining demo sync.
// Each seed is initialized according to its class. killough
// FRandom :: StaticClearRandom
//
// Initialize every RNGs. RNGs are seeded based on the global seed and their
// name, so each different RNG can have a different starting value despite
// being derived from a common global seed.
//
//==========================================================================
void FRandom::StaticClearRandom ()
{
const DWORD seed = rngseed*2+1; // add 3/26/98: add rngseed
FRandom *rng = FRandom::RNGList;
// go through each RNG and set each starting seed differently
while (rng != NULL)
for (FRandom *rng = FRandom::RNGList; rng != NULL; rng = rng->Next)
{
// [RH] Use the RNG's name's CRC to modify the original seed.
// This way, new RNGs can be added later, and it doesn't matter
// which order they get initialized in.
rng->Seed = seed * rng->NameCRC;
rng = rng->Next;
rng->Init(rngseed);
}
}
//==========================================================================
//
// FRandom :: Init
//
// Initialize a single RNG with a given seed.
//
//==========================================================================
void FRandom::Init(DWORD seed)
{
// [RH] Use the RNG's name's CRC to modify the original seed.
// This way, new RNGs can be added later, and it doesn't matter
// which order they get initialized in.
DWORD seeds[2] = { NameCRC, seed };
InitByArray(seeds, 2);
}
//==========================================================================
//
// FRandom :: StaticSumSeeds
//
// This function produces a DWORD that can be used to check the consistancy
// of network games between different machines. Only a select few RNGs are
// used for the sum, because not all RNGs are important to network sync.
extern FRandom pr_spawnmobj;
extern FRandom pr_acs;
extern FRandom pr_chase;
extern FRandom pr_lost;
extern FRandom pr_slam;
//
//==========================================================================
DWORD FRandom::StaticSumSeeds ()
{
return pr_spawnmobj.Seed + pr_acs.Seed + pr_chase.Seed + pr_lost.Seed + pr_slam.Seed;
return
pr_spawnmobj.sfmt.u[0] + pr_spawnmobj.idx +
pr_acs.sfmt.u[0] + pr_acs.idx +
pr_chase.sfmt.u[0] + pr_chase.idx +
pr_lost.sfmt.u[0] + pr_lost.idx +
pr_slam.sfmt.u[0] + pr_slam.idx;
}
//==========================================================================
//
// FRandom :: StaticWriteRNGState
//
// Stores the state of every RNG into a savegame.
//
//==========================================================================
void FRandom::StaticWriteRNGState (FILE *file)
{
FRandom *rng;
const DWORD seed = rngseed*2+1;
FPNGChunkArchive arc (file, RAND_ID);
arc << rngseed;
// Only write those RNGs that have been used
for (rng = FRandom::RNGList; rng != NULL; rng = rng->Next)
{
if (rng->NameCRC != 0 && rng->Seed != seed + rng->NameCRC)
// Only write those RNGs that have names
if (rng->NameCRC != 0)
{
arc << rng->NameCRC << rng->Seed;
arc << rng->NameCRC << rng->idx;
for (int i = 0; i < SFMT::N32; ++i)
{
arc << rng->sfmt.u[i];
}
}
}
}
//==========================================================================
//
// FRandom :: StaticReadRNGState
//
// Restores the state of every RNG from a savegame. RNGs that were added
// since the savegame was created are cleared to their initial value.
//
//==========================================================================
void FRandom::StaticReadRNGState (PNGHandle *png)
{
FRandom *rng;
@ -225,7 +295,8 @@ void FRandom::StaticReadRNGState (PNGHandle *png)
if (len != 0)
{
const int rngcount = (int)((len-4) / 8);
const size_t sizeof_rng = sizeof(rng->NameCRC) + sizeof(rng->idx) + sizeof(rng->sfmt.u);
const int rngcount = (int)((len-4) / sizeof_rng);
int i;
DWORD crc;
@ -241,29 +312,46 @@ void FRandom::StaticReadRNGState (PNGHandle *png)
{
if (rng->NameCRC == crc)
{
arc << rng->Seed;
arc << rng->idx;
for (int i = 0; i < SFMT::N32; ++i)
{
arc << rng->sfmt.u[i];
}
break;
}
}
if (rng == NULL)
{ // The RNG was removed. Skip it.
int idx;
DWORD sfmt;
arc << idx;
for (int i = 0; i < SFMT::N32; ++i)
{
arc << sfmt;
}
}
}
png->File->ResetFilePtr();
}
}
//==========================================================================
//
// FRandom :: StaticFindRNG
//
// This function attempts to find an RNG with the given name.
// If it can't it will create a new one. Duplicate CRCs will
// be ignored and if it happens map to the same RNG.
// This is for use by DECORATE.
extern FRandom pr_exrandom;
static TDeletingArray<FRandom *> NewRNGs;
//
//==========================================================================
FRandom *FRandom::StaticFindRNG (const char *name)
{
DWORD NameCRC = CalcCRC32 ((const BYTE *)name, (unsigned int)strlen (name));
// Use the default RNG if this one happens to have a CRC of 0.
if (NameCRC==0) return &pr_exrandom;
if (NameCRC == 0) return &pr_exrandom;
// Find the RNG in the list, sorted by CRC
FRandom **prev = &RNGList, *probe = RNGList;
@ -285,14 +373,23 @@ FRandom *FRandom::StaticFindRNG (const char *name)
return probe;
}
#ifdef _DEBUG
//==========================================================================
//
// FRandom :: StaticPrintSeeds
//
// Prints a snapshot of the current RNG states. This is probably wrong.
//
//==========================================================================
#ifndef NDEBUG
void FRandom::StaticPrintSeeds ()
{
FRandom *rng = RNGList;
while (rng != NULL)
{
Printf ("%s: %08x\n", rng->Name, rng->Seed);
int idx = rng->idx < SFMT::N32 ? rng->idx : 0;
Printf ("%s: %08x .. %d\n", rng->Name, rng->sfmt.u[idx], idx);
rng = rng->Next;
}
}

View file

@ -1,57 +1,43 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// $Id: m_random.h,v 1.9 1998/05/01 14:20:31 killough Exp $
//
// Copyright (C) 1993-1996 by id Software, Inc.
//
// This source is available for distribution and/or modification
// only under the terms of the DOOM Source Code License as
// published by id Software. All rights reserved.
//
// The source is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
// for more details.
//
// DESCRIPTION:
//
// [RH] We now use BOOM's random number generator
//
//-----------------------------------------------------------------------------
/*
** m_random.h
** Random number generators
**
**---------------------------------------------------------------------------
** Copyright 2002-2009 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#ifndef __M_RANDOM__
#define __M_RANDOM__
#include <stdio.h>
#include "basictypes.h"
// killough 1/19/98: rewritten to use a better random number generator
// in the new engine, although the old one is available for compatibility.
// killough 2/16/98:
//
// Make every random number generator local to each control-equivalent block.
// Critical for demo sync. Changing the order of this list breaks all previous
// versions' demos. The random number generators are made local to reduce the
// chances of sync problems. In Doom, if a single random number generator call
// was off, it would mess up all random number generators. This reduces the
// chances of it happening by making each RNG local to a control flow block.
//
// Notes to developers: if you want to reduce your demo sync hassles, follow
// this rule: for each call to P_Random you add, add a new class to the enum
// type below for each block of code which calls P_Random. If two calls to
// P_Random are not in "control-equivalent blocks", i.e. there are any cases
// where one is executed, and the other is not, put them in separate classes.
//
// Keep all current entries in this list the same, and in the order
// indicated by the #'s, because they're critical for preserving demo
// sync. Do not remove entries simply because they become unused later.
//
// [RH] Changed to use different class instances for different generators.
// This makes adding new RNGs easier, because I don't need to recompile every
// file that uses random numbers.
#include "sfmt/SFMT.h"
struct PNGHandle;
@ -62,42 +48,169 @@ public:
FRandom (const char *name);
~FRandom ();
int operator() (); // Returns a random number in the range [0,255]
int operator() (int mod); // Returns a random number in the range [0,mod)
int Random2(); // Returns rand# - rand#
int Random2(int mask); // Returns (rand# & mask) - (rand# & mask)
int HitDice(int count); // HITDICE macro used in Heretic and Hexen
// Returns a random number in the range [0,255]
int operator()()
{
return GenRand32() & 255;
}
// Returns a random number in the range [0,mod)
int operator() (int mod)
{
return GenRand32() % mod;
}
// Returns rand# - rand#
int Random2()
{
return Random2(255);
}
// Returns (rand# & mask) - (rand# & mask)
int Random2(int mask)
{
int t = GenRand32() & mask;
return t - (GenRand32() & mask);
}
// HITDICE macro used in Heretic and Hexen
int HitDice(int count)
{
return (1 + (GenRand32() & 7)) * count;
}
int Random() // synonym for ()
{
return operator()();
}
DWORD GetSeed()
void Init(DWORD seed);
// SFMT interface
unsigned int GenRand32();
QWORD GenRand64();
void FillArray32(DWORD *array, int size);
void FillArray64(QWORD *array, int size);
void InitGenRand(DWORD seed);
void InitByArray(DWORD *init_key, int key_length);
int GetMinArraySize32();
int GetMinArraySize64();
/* These real versions are due to Isaku Wada */
/** generates a random number on [0,1]-real-interval */
static inline double ToReal1(DWORD v)
{
return Seed;
return v * (1.0/4294967295.0);
/* divided by 2^32-1 */
}
/** generates a random number on [0,1]-real-interval */
inline double GenRand_Real1()
{
return ToReal1(GenRand32());
}
/** generates a random number on [0,1)-real-interval */
static inline double ToReal2(DWORD v)
{
return v * (1.0/4294967296.0);
/* divided by 2^32 */
}
/** generates a random number on [0,1)-real-interval */
inline double GenRand_Real2()
{
return ToReal2(GenRand32());
}
/** generates a random number on (0,1)-real-interval */
static inline double ToReal3(DWORD v)
{
return (((double)v) + 0.5)*(1.0/4294967296.0);
/* divided by 2^32 */
}
/** generates a random number on (0,1)-real-interval */
inline double GenRand_Real3(void)
{
return ToReal3(GenRand32());
}
/** These real versions are due to Isaku Wada */
/** generates a random number on [0,1) with 53-bit resolution*/
static inline double ToRes53(QWORD v)
{
return v * (1.0/18446744073709551616.0L);
}
/** generates a random number on [0,1) with 53-bit resolution from two
* 32 bit integers */
static inline double ToRes53Mix(DWORD x, DWORD y)
{
return ToRes53(x | ((QWORD)y << 32));
}
/** generates a random number on [0,1) with 53-bit resolution
*/
inline double GenRand_Res53(void)
{
return ToRes53(GenRand64());
}
/** generates a random number on [0,1) with 53-bit resolution
using 32bit integer.
*/
inline double GenRand_Res53_Mix()
{
DWORD x, y;
x = GenRand32();
y = GenRand32();
return ToRes53Mix(x, y);
}
// Static interface
static void StaticClearRandom ();
static DWORD StaticSumSeeds ();
static void StaticReadRNGState (PNGHandle *png);
static void StaticWriteRNGState (FILE *file);
static FRandom *StaticFindRNG(const char *name);
#ifdef _DEBUG
#ifndef NDEBUG
static void StaticPrintSeeds ();
#endif
private:
DWORD Seed;
#ifndef NDEBUG
const char *Name;
#endif
FRandom *Next;
DWORD NameCRC;
#ifdef _DEBUG
const char *Name;
#endif
static FRandom *RNGList;
/*-------------------------------------------
SFMT internal state, index counter and flag
-------------------------------------------*/
void GenRandAll();
void GenRandArray(w128_t *array, int size);
void PeriodCertification();
/** the 128-bit internal state array */
union
{
w128_t w128[SFMT::N];
unsigned int u[SFMT::N32];
QWORD u64[SFMT::N64];
} sfmt;
/** index counter to the 32-bit internal state array */
int idx;
/** a flag: it is 0 if and only if the internal state is not yet
* initialized. */
#ifndef NDEBUG
bool initialized;
#endif
};
extern DWORD rngseed; // The starting seed (not part of state)

View file

@ -41,7 +41,7 @@
// bits 9-15: reserved
//40 bytes
typedef struct
struct sectortype
{
SWORD wallptr, wallnum;
SDWORD ceilingz, floorz;
@ -54,7 +54,7 @@ typedef struct
BYTE floorpal, floorxpanning, floorypanning;
BYTE visibility, filler;
SWORD lotag, hitag, extra;
} sectortype;
};
//cstat:
// bit 0: 1 = Blocking wall (use with clipmove, getzrange) "B"
@ -70,7 +70,7 @@ typedef struct
// bits 10-15: reserved
//32 bytes
typedef struct
struct walltype
{
SDWORD x, y;
SWORD point2, nextwall, nextsector, cstat;
@ -78,7 +78,7 @@ typedef struct
SBYTE shade;
BYTE pal, xrepeat, yrepeat, xpanning, ypanning;
SWORD lotag, hitag, extra;
} walltype;
};
//cstat:
// bit 0: 1 = Blocking sprite (use with clipmove, getzrange) "B"
@ -96,7 +96,7 @@ typedef struct
// bit 15: 1 = Invisible sprite, 0 = not invisible
//44 bytes
typedef struct
struct spritetype
{
SDWORD x, y, z;
SWORD cstat, picnum;
@ -107,7 +107,7 @@ typedef struct
SWORD sectnum, statnum;
SWORD ang, owner, xvel, yvel, zvel;
SWORD lotag, hitag, extra;
} spritetype;
};
struct SlopeWork
{

View file

@ -2507,23 +2507,26 @@ AInventory *P_DropItem (AActor *source, const PClass *type, int dropamount, int
}
}
mo = Spawn (type, source->x, source->y, spawnz, ALLOW_REPLACE);
mo->flags |= MF_DROPPED;
mo->flags &= ~MF_NOGRAVITY; // [RH] Make sure it is affected by gravity
if (mo->IsKindOf (RUNTIME_CLASS(AInventory)))
if (mo != NULL)
{
AInventory * inv = static_cast<AInventory *>(mo);
ModifyDropAmount(inv, dropamount);
if (inv->SpecialDropAction (source))
mo->flags |= MF_DROPPED;
mo->flags &= ~MF_NOGRAVITY; // [RH] Make sure it is affected by gravity
if (!(i_compatflags & COMPATF_NOTOSSDROPS))
{
return NULL;
P_TossItem (mo);
}
return inv;
if (mo->IsKindOf (RUNTIME_CLASS(AInventory)))
{
AInventory * inv = static_cast<AInventory *>(mo);
ModifyDropAmount(inv, dropamount);
if (inv->SpecialDropAction (source))
{
return NULL;
}
return inv;
}
// we can't really return an AInventory pointer to a non-inventory item here, can we?
}
if (!(i_compatflags & COMPATF_NOTOSSDROPS))
{
P_TossItem (mo);
}
// we can't really return an AInventory pointer to a non-inventory item here, can we?
}
return NULL;
}

View file

@ -779,8 +779,8 @@ void P_AutoUseHealth(player_t *player, int saveHealth)
{
int mode = static_cast<AHealthPickup*>(inv)->autousemode;
if (mode == 0) NormalHealthItems.Push(inv);
else if (mode == 1) LargeHealthItems.Push(inv);
if (mode == 1) NormalHealthItems.Push(inv);
else if (mode == 2) LargeHealthItems.Push(inv);
}
}

View file

@ -51,6 +51,9 @@ enum
LINK_CEILINGMIRROR=10,
LINK_BOTHMIRROR=15,
LINK_FLOORBITS=5,
LINK_CEILINGBITS=10,
LINK_FLAGMASK = 15
};
@ -236,26 +239,20 @@ void P_StartLinkedSectorInterpolations(TArray<DInterpolation *> &list, sector_t
static void AddSingleSector(extsector_t::linked::plane &scrollplane, sector_t *sector, int movetype)
{
// First we have to check the list if the sector is already in it
// If so the move type may have to be adjusted or the link to be removed
// If so the move type must be adjusted
for(unsigned i = 0; i < scrollplane.Sectors.Size(); i++)
{
if (scrollplane.Sectors[i].Sector == sector)
{
int oldtype = scrollplane.Sectors[i].Type;
if ((oldtype & (LINK_FLOOR|LINK_FLOORMIRROR)) &&
(movetype & (LINK_FLOORMIRROR|LINK_FLOOR)))
if (movetype & LINK_FLOORBITS)
{
// Invalid combination for floor.
movetype &= ~(LINK_FLOOR + LINK_FLOORMIRROR);
scrollplane.Sectors[i].Type &= ~LINK_FLOORBITS;
}
if ((oldtype & (LINK_CEILING|LINK_CEILINGMIRROR)) &&
(movetype == LINK_CEILINGMIRROR || movetype == LINK_CEILING))
if (movetype & LINK_CEILINGBITS)
{
// Invalid combination for CEILING.
movetype &= ~(LINK_CEILING + LINK_CEILINGMIRROR);
scrollplane.Sectors[i].Type &= ~LINK_CEILINGBITS;
}
scrollplane.Sectors[i].Type |= movetype;

View file

@ -150,16 +150,16 @@ void P_NoiseAlert (AActor* target, AActor* emmiter, bool splash);
//
// P_MAPUTL
//
typedef struct
struct divline_t
{
fixed_t x;
fixed_t y;
fixed_t dx;
fixed_t dy;
} divline_t;
};
typedef struct
struct intercept_t
{
fixed_t frac; // along trace line
bool isaline;
@ -168,7 +168,7 @@ typedef struct
AActor *thing;
line_t *line;
} d;
} intercept_t;
};
typedef bool (*traverser_t) (intercept_t *in);
@ -417,10 +417,9 @@ const secplane_t * P_CheckSlopeWalk (AActor *actor, fixed_t &xmove, fixed_t &ymo
// (For ZDoom itself this doesn't make any difference here but for GZDoom it does.)
//
//----------------------------------------------------------------------------------
subsector_t *P_PointInSubsector (fixed_t x, fixed_t y);
inline sector_t *P_PointInSector(fixed_t x, fixed_t y)
{
return P_PointInSubsector(x,y)->sector;
return R_PointInSubsector(x,y)->sector;
}
//
@ -471,14 +470,14 @@ bool EV_OpenPolyDoor (line_t *line, int polyNum, int speed, angle_t angle, int d
// [RH] Data structure for P_SpawnMapThing() to keep track
// of polyobject-related things.
typedef struct polyspawns_s
struct polyspawns_t
{
struct polyspawns_s *next;
polyspawns_t *next;
fixed_t x;
fixed_t y;
short angle;
short type;
} polyspawns_t;
};
enum
{

View file

@ -62,14 +62,14 @@ inline FArchive &operator<< (FArchive &arc, psprnum_t &i)
}
*/
typedef struct pspdef_s
struct pspdef_t
{
FState* state; // a NULL state means not active
int tics;
fixed_t sx;
fixed_t sy;
} pspdef_t;
};
class FArchive;

View file

@ -143,10 +143,9 @@ void P_InitSwitchList ()
Printf ("Switch %s in SWITCHES has the same 'on' state\n", list_p);
continue;
}
// [RH] Skip this switch if its texture can't be found.
if (((gameinfo.maxSwitch & 15) >= (list_p[18] & 15)) &&
((gameinfo.maxSwitch & ~15) == (list_p[18] & ~15)) &&
TexMan.CheckForTexture (list_p /* .name1 */, FTexture::TEX_Wall, texflags).Exists())
// [RH] Skip this switch if its textures can't be found.
if (TexMan.CheckForTexture (list_p /* .name1 */, FTexture::TEX_Wall, texflags).Exists() &&
TexMan.CheckForTexture (list_p + 9 /* .name2 */, FTexture::TEX_Wall, texflags).Exists())
{
def1 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef));
def2 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef));
@ -204,42 +203,40 @@ void P_ProcessSwitchDef (FScanner &sc)
FString picname;
FSwitchDef *def1, *def2;
FTextureID picnum;
BYTE max;
int gametype;
bool quest = false;
def1 = def2 = NULL;
sc.MustGetString ();
if (sc.Compare ("doom"))
{
max = 0;
gametype = GAME_DoomChex;
sc.CheckNumber(); // skip the gamemission filter
}
else if (sc.Compare ("heretic"))
{
max = 17;
gametype = GAME_Heretic;
}
else if (sc.Compare ("hexen"))
{
max = 33;
gametype = GAME_Hexen;
}
else if (sc.Compare ("strife"))
{
max = 49;
gametype = GAME_Strife;
}
else if (sc.Compare ("any"))
{
max = 240;
gametype = GAME_Any;
}
else
{
// There is no game specified; just treat as any
max = 240;
//max = 240;
gametype = GAME_Any;
sc.UnGet ();
}
if (max == 0)
{
sc.MustGetNumber ();
max |= sc.Number & 15;
}
sc.MustGetString ();
picnum = TexMan.CheckForTexture (sc.String, FTexture::TEX_Wall, texflags);
picname = sc.String;
@ -271,16 +268,9 @@ void P_ProcessSwitchDef (FScanner &sc)
break;
}
}
/*
if (def1 == NULL)
{
sc.ScriptError ("Switch must have an on state");
}
*/
if (def1 == NULL || !picnum.Exists() ||
((max & 240) != 240 &&
((gameinfo.maxSwitch & 240) != (max & 240) ||
(gameinfo.maxSwitch & 15) < (max & 15))))
(gametype != GAME_Any && !(gametype & gameinfo.gametype)))
{
if (def2 != NULL)
{

View file

@ -139,9 +139,10 @@ void R_ClearDrawSegs (void)
// should use it, since smaller arrays fit better in cache.
//
typedef struct {
struct cliprange_t
{
short first, last; // killough
} cliprange_t;
};
// newend is one past the last valid seg

View file

@ -1823,7 +1823,7 @@ void R_DrawBorder (int x1, int y1, int x2, int y2)
{
FTextureID picnum;
if (level.info != NULL)
if (level.info != NULL && level.info->bordertexture[0] != 0)
{
picnum = TexMan.CheckForTexture (level.info->bordertexture, FTexture::TEX_Flat);
}

View file

@ -89,10 +89,11 @@ typedef enum
SS_CMD_END
} sscmds_t;
typedef struct {
struct hexenseq_t
{
ENamedName Name;
BYTE Seqs[4];
} hexenseq_t;
};
class DSeqActorNode : public DSeqNode
{

View file

@ -31,6 +31,7 @@
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifndef NO_GTK
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
@ -619,3 +620,26 @@ FString I_GetFromClipboard (bool use_primary_selection)
#endif
return "";
}
// Return a random seed, preferably one with lots of entropy.
unsigned int I_MakeRNGSeed()
{
unsigned int seed;
int file;
// Try reading from /dev/urandom first, then /dev/random, then
// if all else fails, use a crappy seed from time().
seed = time(NULL);
file = open("/dev/urandom", O_RDONLY);
if (file < 0)
{
file = open("/dev/random", O_RDONLY);
}
if (file >= 0)
{
read(file, &seed, sizeof(seed));
close(file);
}
return seed;
}

View file

@ -64,6 +64,9 @@ extern void (*I_FreezeTime) (bool frozen);
fixed_t I_GetTimeFrac (uint32 *ms);
// Return a seed value for the RNG.
unsigned int I_MakeRNGSeed();
//
// Called by D_DoomLoop,
@ -127,12 +130,12 @@ unsigned int I_MSTime (void);
// Directory searching routines
typedef struct
struct findstate_t
{
int count;
struct dirent **namelist;
int current;
} findstate_t;
};
void *I_FindFirst (const char *filespec, findstate_t *fileinfo);
int I_FindNext (void *handle, findstate_t *fileinfo);

29
src/sfmt/LICENSE.txt Normal file
View file

@ -0,0 +1,29 @@
Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
University. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the Hiroshima University nor the names of
its contributors may be used to endorse or promote products
derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

156
src/sfmt/SFMT-alti.h Normal file
View file

@ -0,0 +1,156 @@
/**
* @file SFMT-alti.h
*
* @brief SIMD oriented Fast Mersenne Twister(SFMT)
* pseudorandom number generator
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (Hiroshima University)
*
* Copyright (C) 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University. All rights reserved.
*
* The new BSD License is applied to this software.
* see LICENSE.txt
*/
#ifndef SFMT_ALTI_H
#define SFMT_ALTI_H
inline static vector unsigned int vec_recursion(vector unsigned int a,
vector unsigned int b,
vector unsigned int c,
vector unsigned int d)
ALWAYSINLINE;
/**
* This function represents the recursion formula in AltiVec and BIG ENDIAN.
* @param a a 128-bit part of the interal state array
* @param b a 128-bit part of the interal state array
* @param c a 128-bit part of the interal state array
* @param d a 128-bit part of the interal state array
* @return output
*/
inline static vector unsigned int vec_recursion(vector unsigned int a,
vector unsigned int b,
vector unsigned int c,
vector unsigned int d) {
const vector unsigned int sl1 = ALTI_SL1;
const vector unsigned int sr1 = ALTI_SR1;
#ifdef ONLY64
const vector unsigned int mask = ALTI_MSK64;
const vector unsigned char perm_sl = ALTI_SL2_PERM64;
const vector unsigned char perm_sr = ALTI_SR2_PERM64;
#else
const vector unsigned int mask = ALTI_MSK;
const vector unsigned char perm_sl = ALTI_SL2_PERM;
const vector unsigned char perm_sr = ALTI_SR2_PERM;
#endif
vector unsigned int v, w, x, y, z;
x = vec_perm(a, (vector unsigned int)perm_sl, perm_sl);
v = a;
y = vec_sr(b, sr1);
z = vec_perm(c, (vector unsigned int)perm_sr, perm_sr);
w = vec_sl(d, sl1);
z = vec_xor(z, w);
y = vec_and(y, mask);
v = vec_xor(v, x);
z = vec_xor(z, y);
z = vec_xor(z, v);
return z;
}
/**
* This function fills the internal state array with pseudorandom
* integers.
*/
inline static void gen_rand_all(void) {
int i;
vector unsigned int r, r1, r2;
r1 = sfmt[N - 2].s;
r2 = sfmt[N - 1].s;
for (i = 0; i < N - POS1; i++) {
r = vec_recursion(sfmt[i].s, sfmt[i + POS1].s, r1, r2);
sfmt[i].s = r;
r1 = r2;
r2 = r;
}
for (; i < N; i++) {
r = vec_recursion(sfmt[i].s, sfmt[i + POS1 - N].s, r1, r2);
sfmt[i].s = r;
r1 = r2;
r2 = r;
}
}
/**
* This function fills the user-specified array with pseudorandom
* integers.
*
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pesudorandom numbers to be generated.
*/
inline static void gen_rand_array(w128_t *array, int size) {
int i, j;
vector unsigned int r, r1, r2;
r1 = sfmt[N - 2].s;
r2 = sfmt[N - 1].s;
for (i = 0; i < N - POS1; i++) {
r = vec_recursion(sfmt[i].s, sfmt[i + POS1].s, r1, r2);
array[i].s = r;
r1 = r2;
r2 = r;
}
for (; i < N; i++) {
r = vec_recursion(sfmt[i].s, array[i + POS1 - N].s, r1, r2);
array[i].s = r;
r1 = r2;
r2 = r;
}
/* main loop */
for (; i < size - N; i++) {
r = vec_recursion(array[i - N].s, array[i + POS1 - N].s, r1, r2);
array[i].s = r;
r1 = r2;
r2 = r;
}
for (j = 0; j < 2 * N - size; j++) {
sfmt[j].s = array[j + size - N].s;
}
for (; i < size; i++) {
r = vec_recursion(array[i - N].s, array[i + POS1 - N].s, r1, r2);
array[i].s = r;
sfmt[j++].s = r;
r1 = r2;
r2 = r;
}
}
#ifndef ONLY64
#if defined(__APPLE__)
#define ALTI_SWAP (vector unsigned char) \
(4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11)
#else
#define ALTI_SWAP {4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11}
#endif
/**
* This function swaps high and low 32-bit of 64-bit integers in user
* specified array.
*
* @param array an 128-bit array to be swaped.
* @param size size of 128-bit array.
*/
inline static void swap(w128_t *array, int size) {
int i;
const vector unsigned char perm = ALTI_SWAP;
for (i = 0; i < size; i++) {
array[i].s = vec_perm(array[i].s, (vector unsigned int)perm, perm);
}
}
#endif
#endif

70
src/sfmt/SFMT-params.h Normal file
View file

@ -0,0 +1,70 @@
#ifndef SFMT_PARAMS_H
#define SFMT_PARAMS_H
/*----------------------
the parameters of SFMT
following definitions are in paramsXXXX.h file.
----------------------*/
/** the pick up position of the array.
#define POS1 122
*/
/** the parameter of shift left as four 32-bit registers.
#define SL1 18
*/
/** the parameter of shift left as one 128-bit register.
* The 128-bit integer is shifted by (SL2 * 8) bits.
#define SL2 1
*/
/** the parameter of shift right as four 32-bit registers.
#define SR1 11
*/
/** the parameter of shift right as one 128-bit register.
* The 128-bit integer is shifted by (SL2 * 8) bits.
#define SR2 1
*/
/** A bitmask, used in the recursion. These parameters are introduced
* to break symmetry of SIMD.
#define MSK1 0xdfffffefU
#define MSK2 0xddfecb7fU
#define MSK3 0xbffaffffU
#define MSK4 0xbffffff6U
*/
/** These definitions are part of a 128-bit period certification vector.
#define PARITY1 0x00000001U
#define PARITY2 0x00000000U
#define PARITY3 0x00000000U
#define PARITY4 0xc98e126aU
*/
#if MEXP == 607
#include "SFMT-params607.h"
#elif MEXP == 1279
#include "SFMT-params1279.h"
#elif MEXP == 2281
#include "SFMT-params2281.h"
#elif MEXP == 4253
#include "SFMT-params4253.h"
#elif MEXP == 11213
#include "SFMT-params11213.h"
#elif MEXP == 19937
#include "SFMT-params19937.h"
#elif MEXP == 44497
#include "SFMT-params44497.h"
#elif MEXP == 86243
#include "SFMT-params86243.h"
#elif MEXP == 132049
#include "SFMT-params132049.h"
#elif MEXP == 216091
#include "SFMT-params216091.h"
#else
#error "MEXP is not valid."
#undef MEXP
#endif
#endif /* SFMT_PARAMS_H */

View file

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS11213_H
#define SFMT_PARAMS11213_H
#define POS1 68
#define SL1 14
#define SL2 3
#define SR1 7
#define SR2 3
#define MSK1 0xeffff7fbU
#define MSK2 0xffffffefU
#define MSK3 0xdfdfbfffU
#define MSK4 0x7fffdbfdU
#define PARITY1 0x00000001U
#define PARITY2 0x00000000U
#define PARITY3 0xe8148000U
#define PARITY4 0xd0c7afa3U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define ALTI_SR2_PERM \
(vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}
#define ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}
#endif /* For OSX */
#define IDSTR "SFMT-11213:68-14-3-7-3:effff7fb-ffffffef-dfdfbfff-7fffdbfd"
#endif /* SFMT_PARAMS11213_H */

View file

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS1279_H
#define SFMT_PARAMS1279_H
#define POS1 7
#define SL1 14
#define SL2 3
#define SR1 5
#define SR2 1
#define MSK1 0xf7fefffdU
#define MSK2 0x7fefcfffU
#define MSK3 0xaff3ef3fU
#define MSK4 0xb5ffff7fU
#define PARITY1 0x00000001U
#define PARITY2 0x00000000U
#define PARITY3 0x00000000U
#define PARITY4 0x20000000U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define IDSTR "SFMT-1279:7-14-3-5-1:f7fefffd-7fefcfff-aff3ef3f-b5ffff7f"
#endif /* SFMT_PARAMS1279_H */

View file

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS132049_H
#define SFMT_PARAMS132049_H
#define POS1 110
#define SL1 19
#define SL2 1
#define SR1 21
#define SR2 1
#define MSK1 0xffffbb5fU
#define MSK2 0xfb6ebf95U
#define MSK3 0xfffefffaU
#define MSK4 0xcff77fffU
#define PARITY1 0x00000001U
#define PARITY2 0x00000000U
#define PARITY3 0xcb520000U
#define PARITY4 0xc7e91c7dU
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
#define ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
#define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define IDSTR "SFMT-132049:110-19-1-21-1:ffffbb5f-fb6ebf95-fffefffa-cff77fff"
#endif /* SFMT_PARAMS132049_H */

View file

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS19937_H
#define SFMT_PARAMS19937_H
#define POS1 122
#define SL1 18
#define SL2 1
#define SR1 11
#define SR2 1
#define MSK1 0xdfffffefU
#define MSK2 0xddfecb7fU
#define MSK3 0xbffaffffU
#define MSK4 0xbffffff6U
#define PARITY1 0x00000001U
#define PARITY2 0x00000000U
#define PARITY3 0x00000000U
#define PARITY4 0x13c9e684U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
#define ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
#define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define IDSTR "SFMT-19937:122-18-1-11-1:dfffffef-ddfecb7f-bffaffff-bffffff6"
#endif /* SFMT_PARAMS19937_H */

View file

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS216091_H
#define SFMT_PARAMS216091_H
#define POS1 627
#define SL1 11
#define SL2 3
#define SR1 10
#define SR2 1
#define MSK1 0xbff7bff7U
#define MSK2 0xbfffffffU
#define MSK3 0xbffffa7fU
#define MSK4 0xffddfbfbU
#define PARITY1 0xf8000001U
#define PARITY2 0x89e80709U
#define PARITY3 0x3bd2b64bU
#define PARITY4 0x0c64b1e4U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define IDSTR "SFMT-216091:627-11-3-10-1:bff7bff7-bfffffff-bffffa7f-ffddfbfb"
#endif /* SFMT_PARAMS216091_H */

View file

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS2281_H
#define SFMT_PARAMS2281_H
#define POS1 12
#define SL1 19
#define SL2 1
#define SR1 5
#define SR2 1
#define MSK1 0xbff7ffbfU
#define MSK2 0xfdfffffeU
#define MSK3 0xf7ffef7fU
#define MSK4 0xf2f7cbbfU
#define PARITY1 0x00000001U
#define PARITY2 0x00000000U
#define PARITY3 0x00000000U
#define PARITY4 0x41dfa600U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
#define ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
#define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define IDSTR "SFMT-2281:12-19-1-5-1:bff7ffbf-fdfffffe-f7ffef7f-f2f7cbbf"
#endif /* SFMT_PARAMS2281_H */

View file

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS4253_H
#define SFMT_PARAMS4253_H
#define POS1 17
#define SL1 20
#define SL2 1
#define SR1 7
#define SR2 1
#define MSK1 0x9f7bffffU
#define MSK2 0x9fffff5fU
#define MSK3 0x3efffffbU
#define MSK4 0xfffff7bbU
#define PARITY1 0xa8000001U
#define PARITY2 0xaf5390a3U
#define PARITY3 0xb740b3f8U
#define PARITY4 0x6c11486dU
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
#define ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
#define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define IDSTR "SFMT-4253:17-20-1-7-1:9f7bffff-9fffff5f-3efffffb-fffff7bb"
#endif /* SFMT_PARAMS4253_H */

View file

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS44497_H
#define SFMT_PARAMS44497_H
#define POS1 330
#define SL1 5
#define SL2 3
#define SR1 9
#define SR2 3
#define MSK1 0xeffffffbU
#define MSK2 0xdfbebfffU
#define MSK3 0xbfbf7befU
#define MSK4 0x9ffd7bffU
#define PARITY1 0x00000001U
#define PARITY2 0x00000000U
#define PARITY3 0xa3ac4000U
#define PARITY4 0xecc1327aU
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define ALTI_SR2_PERM \
(vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}
#define ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}
#endif /* For OSX */
#define IDSTR "SFMT-44497:330-5-3-9-3:effffffb-dfbebfff-bfbf7bef-9ffd7bff"
#endif /* SFMT_PARAMS44497_H */

46
src/sfmt/SFMT-params607.h Normal file
View file

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS607_H
#define SFMT_PARAMS607_H
#define POS1 2
#define SL1 15
#define SL2 3
#define SR1 13
#define SR2 3
#define MSK1 0xfdff37ffU
#define MSK2 0xef7f3f7dU
#define MSK3 0xff777b7dU
#define MSK4 0x7ff7fb2fU
#define PARITY1 0x00000001U
#define PARITY2 0x00000000U
#define PARITY3 0x00000000U
#define PARITY4 0x5986f054U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define ALTI_SR2_PERM \
(vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}
#define ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}
#endif /* For OSX */
#define IDSTR "SFMT-607:2-15-3-13-3:fdff37ff-ef7f3f7d-ff777b7d-7ff7fb2f"
#endif /* SFMT_PARAMS607_H */

View file

@ -0,0 +1,46 @@
#ifndef SFMT_PARAMS86243_H
#define SFMT_PARAMS86243_H
#define POS1 366
#define SL1 6
#define SL2 7
#define SR1 19
#define SR2 1
#define MSK1 0xfdbffbffU
#define MSK2 0xbff7ff3fU
#define MSK3 0xfd77efffU
#define MSK4 0xbf9ff3ffU
#define PARITY1 0x00000001U
#define PARITY2 0x00000000U
#define PARITY3 0x00000000U
#define PARITY4 0xe9528d85U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1)
#define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1)
#define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4)
#define ALTI_MSK64 \
(vector unsigned int)(MSK2, MSK1, MSK4, MSK3)
#define ALTI_SL2_PERM \
(vector unsigned char)(25,25,25,25,3,25,25,25,7,0,1,2,11,4,5,6)
#define ALTI_SL2_PERM64 \
(vector unsigned char)(7,25,25,25,25,25,25,25,15,0,1,2,3,4,5,6)
#define ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define ALTI_SL1 {SL1, SL1, SL1, SL1}
#define ALTI_SR1 {SR1, SR1, SR1, SR1}
#define ALTI_MSK {MSK1, MSK2, MSK3, MSK4}
#define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3}
#define ALTI_SL2_PERM {25,25,25,25,3,25,25,25,7,0,1,2,11,4,5,6}
#define ALTI_SL2_PERM64 {7,25,25,25,25,25,25,25,15,0,1,2,3,4,5,6}
#define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define IDSTR "SFMT-86243:366-6-7-19-1:fdbffbff-bff7ff3f-fd77efff-bf9ff3ff"
#endif /* SFMT_PARAMS86243_H */

121
src/sfmt/SFMT-sse2.h Normal file
View file

@ -0,0 +1,121 @@
/**
* @file SFMT-sse2.h
* @brief SIMD oriented Fast Mersenne Twister(SFMT) for Intel SSE2
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (Hiroshima University)
*
* @note We assume LITTLE ENDIAN in this file
*
* Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University. All rights reserved.
*
* The new BSD License is applied to this software, see LICENSE.txt
*/
#ifndef SFMT_SSE2_H
#define SFMT_SSE2_H
PRE_ALWAYS static __m128i mm_recursion(__m128i *a, __m128i *b, __m128i c,
__m128i d, __m128i mask) ALWAYSINLINE;
/**
* This function represents the recursion formula.
* @param a a 128-bit part of the interal state array
* @param b a 128-bit part of the interal state array
* @param c a 128-bit part of the interal state array
* @param d a 128-bit part of the interal state array
* @param mask 128-bit mask
* @return output
*/
PRE_ALWAYS static __m128i mm_recursion(__m128i *a, __m128i *b,
__m128i c, __m128i d, __m128i mask) {
__m128i v, x, y, z;
x = _mm_load_si128(a);
y = _mm_srli_epi32(*b, SR1);
z = _mm_srli_si128(c, SR2);
v = _mm_slli_epi32(d, SL1);
z = _mm_xor_si128(z, x);
z = _mm_xor_si128(z, v);
x = _mm_slli_si128(x, SL2);
y = _mm_and_si128(y, mask);
z = _mm_xor_si128(z, x);
z = _mm_xor_si128(z, y);
return z;
}
/**
* This function fills the internal state array with pseudorandom
* integers.
*/
inline static void gen_rand_all(void) {
int i;
__m128i r, r1, r2, mask;
mask = _mm_set_epi32(MSK4, MSK3, MSK2, MSK1);
r1 = _mm_load_si128(&sfmt[N - 2].si);
r2 = _mm_load_si128(&sfmt[N - 1].si);
for (i = 0; i < N - POS1; i++) {
r = mm_recursion(&sfmt[i].si, &sfmt[i + POS1].si, r1, r2, mask);
_mm_store_si128(&sfmt[i].si, r);
r1 = r2;
r2 = r;
}
for (; i < N; i++) {
r = mm_recursion(&sfmt[i].si, &sfmt[i + POS1 - N].si, r1, r2, mask);
_mm_store_si128(&sfmt[i].si, r);
r1 = r2;
r2 = r;
}
}
/**
* This function fills the user-specified array with pseudorandom
* integers.
*
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pesudorandom numbers to be generated.
*/
inline static void gen_rand_array(w128_t *array, int size) {
int i, j;
__m128i r, r1, r2, mask;
mask = _mm_set_epi32(MSK4, MSK3, MSK2, MSK1);
r1 = _mm_load_si128(&sfmt[N - 2].si);
r2 = _mm_load_si128(&sfmt[N - 1].si);
for (i = 0; i < N - POS1; i++) {
r = mm_recursion(&sfmt[i].si, &sfmt[i + POS1].si, r1, r2, mask);
_mm_store_si128(&array[i].si, r);
r1 = r2;
r2 = r;
}
for (; i < N; i++) {
r = mm_recursion(&sfmt[i].si, &array[i + POS1 - N].si, r1, r2, mask);
_mm_store_si128(&array[i].si, r);
r1 = r2;
r2 = r;
}
/* main loop */
for (; i < size - N; i++) {
r = mm_recursion(&array[i - N].si, &array[i + POS1 - N].si, r1, r2,
mask);
_mm_store_si128(&array[i].si, r);
r1 = r2;
r2 = r;
}
for (j = 0; j < 2 * N - size; j++) {
r = _mm_load_si128(&array[j + size - N].si);
_mm_store_si128(&sfmt[j].si, r);
}
for (; i < size; i++) {
r = mm_recursion(&array[i - N].si, &array[i + POS1 - N].si, r1, r2,
mask);
_mm_store_si128(&array[i].si, r);
_mm_store_si128(&sfmt[j++].si, r);
r1 = r2;
r2 = r;
}
}
#endif

583
src/sfmt/SFMT.cpp Normal file
View file

@ -0,0 +1,583 @@
/**
* @file SFMT.c
* @brief SIMD oriented Fast Mersenne Twister(SFMT)
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (Hiroshima University)
*
* Copyright (C) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University. All rights reserved.
*
* The new BSD License is applied to this software, see LICENSE.txt
*/
#include <string.h>
#include <assert.h>
#include "m_random.h"
#include "SFMT-params.h"
#if defined(__BIG_ENDIAN__) && !defined(__amd64) && !defined(BIG_ENDIAN64)
#define BIG_ENDIAN64 1
#endif
#if defined(HAVE_ALTIVEC) && !defined(BIG_ENDIAN64)
#define BIG_ENDIAN64 1
#endif
#if defined(ONLY64) && !defined(BIG_ENDIAN64)
#if defined(__GNUC__)
#error "-DONLY64 must be specified with -DBIG_ENDIAN64"
#endif
#undef ONLY64
#endif
/** a parity check vector which certificate the period of 2^{MEXP} */
static const DWORD parity[4] = { PARITY1, PARITY2, PARITY3, PARITY4 };
/*----------------
STATIC FUNCTIONS
----------------*/
inline static int idxof(int i);
inline static void rshift128(w128_t *out, w128_t const *in, int shift);
inline static void lshift128(w128_t *out, w128_t const *in, int shift);
inline static DWORD func1(DWORD x);
inline static DWORD func2(DWORD x);
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
inline static void swap(w128_t *array, int size);
#endif
// These SIMD versions WILL NOT work as-is. I'm not even sure SSE2 is
// safe to provide as a runtime option without significant changes to
// how the state is stored, since the VC++ docs warn that:
// Using variables of type __m128i will cause the compiler to generate
// the SSE2 movdqa instruction. This instruction does not cause a fault
// on Pentium III processors but will result in silent failure, with
// possible side effects caused by whatever instructions movdqa
// translates into on Pentium III processors.
#if defined(HAVE_ALTIVEC)
#include "SFMT-alti.h"
#elif defined(HAVE_SSE2)
#include "SFMT-sse2.h"
#endif
/**
* This function simulate a 64-bit index of LITTLE ENDIAN
* in BIG ENDIAN machine.
*/
#ifdef ONLY64
inline static int idxof(int i) {
return i ^ 1;
}
#else
inline static int idxof(int i) {
return i;
}
#endif
/**
* This function simulates SIMD 128-bit right shift by the standard C.
* The 128-bit integer given in in is shifted by (shift * 8) bits.
* This function simulates the LITTLE ENDIAN SIMD.
* @param out the output of this function
* @param in the 128-bit data to be shifted
* @param shift the shift value
*/
#ifdef ONLY64
inline static void rshift128(w128_t *out, w128_t const *in, int shift) {
QWORD th, tl, oh, ol;
th = ((QWORD)in->u[2] << 32) | ((QWORD)in->u[3]);
tl = ((QWORD)in->u[0] << 32) | ((QWORD)in->u[1]);
oh = th >> (shift * 8);
ol = tl >> (shift * 8);
ol |= th << (64 - shift * 8);
out->u[0] = (DWORD)(ol >> 32);
out->u[1] = (DWORD)ol;
out->u[2] = (DWORD)(oh >> 32);
out->u[3] = (DWORD)oh;
}
#else
inline static void rshift128(w128_t *out, w128_t const *in, int shift) {
QWORD th, tl, oh, ol;
th = ((QWORD)in->u[3] << 32) | ((QWORD)in->u[2]);
tl = ((QWORD)in->u[1] << 32) | ((QWORD)in->u[0]);
oh = th >> (shift * 8);
ol = tl >> (shift * 8);
ol |= th << (64 - shift * 8);
out->u[1] = (DWORD)(ol >> 32);
out->u[0] = (DWORD)ol;
out->u[3] = (DWORD)(oh >> 32);
out->u[2] = (DWORD)oh;
}
#endif
/**
* This function simulates SIMD 128-bit left shift by the standard C.
* The 128-bit integer given in in is shifted by (shift * 8) bits.
* This function simulates the LITTLE ENDIAN SIMD.
* @param out the output of this function
* @param in the 128-bit data to be shifted
* @param shift the shift value
*/
#ifdef ONLY64
inline static void lshift128(w128_t *out, w128_t const *in, int shift) {
QWORD th, tl, oh, ol;
th = ((QWORD)in->u[2] << 32) | ((QWORD)in->u[3]);
tl = ((QWORD)in->u[0] << 32) | ((QWORD)in->u[1]);
oh = th << (shift * 8);
ol = tl << (shift * 8);
oh |= tl >> (64 - shift * 8);
out->u[0] = (DWORD)(ol >> 32);
out->u[1] = (DWORD)ol;
out->u[2] = (DWORD)(oh >> 32);
out->u[3] = (DWORD)oh;
}
#else
inline static void lshift128(w128_t *out, w128_t const *in, int shift) {
QWORD th, tl, oh, ol;
th = ((QWORD)in->u[3] << 32) | ((QWORD)in->u[2]);
tl = ((QWORD)in->u[1] << 32) | ((QWORD)in->u[0]);
oh = th << (shift * 8);
ol = tl << (shift * 8);
oh |= tl >> (64 - shift * 8);
out->u[1] = (DWORD)(ol >> 32);
out->u[0] = (DWORD)ol;
out->u[3] = (DWORD)(oh >> 32);
out->u[2] = (DWORD)oh;
}
#endif
/**
* This function represents the recursion formula.
* @param r output
* @param a a 128-bit part of the internal state array
* @param b a 128-bit part of the internal state array
* @param c a 128-bit part of the internal state array
* @param d a 128-bit part of the internal state array
*/
#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
#ifdef ONLY64
inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
w128_t *d) {
w128_t x;
w128_t y;
lshift128(&x, a, SL2);
rshift128(&y, c, SR2);
r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK2) ^ y.u[0]
^ (d->u[0] << SL1);
r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK1) ^ y.u[1]
^ (d->u[1] << SL1);
r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK4) ^ y.u[2]
^ (d->u[2] << SL1);
r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK3) ^ y.u[3]
^ (d->u[3] << SL1);
}
#else
inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
w128_t *d) {
w128_t x;
w128_t y;
lshift128(&x, a, SL2);
rshift128(&y, c, SR2);
r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK1) ^ y.u[0]
^ (d->u[0] << SL1);
r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK2) ^ y.u[1]
^ (d->u[1] << SL1);
r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK3) ^ y.u[2]
^ (d->u[2] << SL1);
r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK4) ^ y.u[3]
^ (d->u[3] << SL1);
}
#endif
#endif
#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
/**
* This function fills the internal state array with pseudorandom
* integers.
*/
void FRandom::GenRandAll()
{
int i;
w128_t *r1, *r2;
r1 = &sfmt.w128[SFMT::N - 2];
r2 = &sfmt.w128[SFMT::N - 1];
for (i = 0; i < SFMT::N - POS1; i++) {
do_recursion(&sfmt.w128[i], &sfmt.w128[i], &sfmt.w128[i + POS1], r1, r2);
r1 = r2;
r2 = &sfmt.w128[i];
}
for (; i < SFMT::N; i++) {
do_recursion(&sfmt.w128[i], &sfmt.w128[i], &sfmt.w128[i + POS1 - SFMT::N], r1, r2);
r1 = r2;
r2 = &sfmt.w128[i];
}
}
/**
* This function fills the user-specified array with pseudorandom
* integers.
*
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pseudorandom numbers to be generated.
*/
void FRandom::GenRandArray(w128_t *array, int size)
{
int i, j;
w128_t *r1, *r2;
r1 = &sfmt.w128[SFMT::N - 2];
r2 = &sfmt.w128[SFMT::N - 1];
for (i = 0; i < SFMT::N - POS1; i++) {
do_recursion(&array[i], &sfmt.w128[i], &sfmt.w128[i + POS1], r1, r2);
r1 = r2;
r2 = &array[i];
}
for (; i < SFMT::N; i++) {
do_recursion(&array[i], &sfmt.w128[i], &array[i + POS1 - SFMT::N], r1, r2);
r1 = r2;
r2 = &array[i];
}
for (; i < size - SFMT::N; i++) {
do_recursion(&array[i], &array[i - SFMT::N], &array[i + POS1 - SFMT::N], r1, r2);
r1 = r2;
r2 = &array[i];
}
for (j = 0; j < 2 * SFMT::N - size; j++) {
sfmt.w128[j] = array[j + size - SFMT::N];
}
for (; i < size; i++, j++) {
do_recursion(&array[i], &array[i - SFMT::N], &array[i + POS1 - SFMT::N], r1, r2);
r1 = r2;
r2 = &array[i];
sfmt.w128[j] = array[i];
}
}
#endif
#if defined(BIG_ENDIAN64) && !defined(ONLY64) && !defined(HAVE_ALTIVEC)
inline static void swap(w128_t *array, int size) {
int i;
DWORD x, y;
for (i = 0; i < size; i++) {
x = array[i].u[0];
y = array[i].u[2];
array[i].u[0] = array[i].u[1];
array[i].u[2] = array[i].u[3];
array[i].u[1] = x;
array[i].u[3] = y;
}
}
#endif
/**
* This function represents a function used in the initialization
* by init_by_array
* @param x 32-bit integer
* @return 32-bit integer
*/
static DWORD func1(DWORD x)
{
return (x ^ (x >> 27)) * (DWORD)1664525UL;
}
/**
* This function represents a function used in the initialization
* by init_by_array
* @param x 32-bit integer
* @return 32-bit integer
*/
static DWORD func2(DWORD x)
{
return (x ^ (x >> 27)) * (DWORD)1566083941UL;
}
/**
* This function certificate the period of 2^{MEXP}
*/
void FRandom::PeriodCertification()
{
int inner = 0;
int i, j;
DWORD work;
for (i = 0; i < 4; i++)
inner ^= sfmt.u[idxof(i)] & parity[i];
for (i = 16; i > 0; i >>= 1)
inner ^= inner >> i;
inner &= 1;
/* check OK */
if (inner == 1) {
return;
}
/* check NG, and modification */
for (i = 0; i < 4; i++) {
work = 1;
for (j = 0; j < 32; j++) {
if ((work & parity[i]) != 0) {
sfmt.u[idxof(i)] ^= work;
return;
}
work = work << 1;
}
}
}
/*----------------
PUBLIC FUNCTIONS
----------------*/
/**
* This function returns the minimum size of array used for \b
* fill_array32() function.
* @return minimum size of array used for FillArray32() function.
*/
int FRandom::GetMinArraySize32()
{
return SFMT::N32;
}
/**
* This function returns the minimum size of array used for \b
* fill_array64() function.
* @return minimum size of array used for FillArray64() function.
*/
int FRandom::GetMinArraySize64()
{
return SFMT::N64;
}
#ifndef ONLY64
/**
* This function generates and returns 32-bit pseudorandom number.
* init_gen_rand or init_by_array must be called before this function.
* @return 32-bit pseudorandom number
*/
unsigned int FRandom::GenRand32()
{
DWORD r;
assert(initialized);
if (idx >= SFMT::N32)
{
GenRandAll();
idx = 0;
}
r = sfmt.u[idx++];
return r;
}
#endif
/**
* This function generates and returns 64-bit pseudorandom number.
* init_gen_rand or init_by_array must be called before this function.
* The function gen_rand64 should not be called after gen_rand32,
* unless an initialization is again executed.
* @return 64-bit pseudorandom number
*/
QWORD FRandom::GenRand64()
{
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
DWORD r1, r2;
#else
QWORD r;
#endif
assert(initialized);
assert(idx % 2 == 0);
if (idx >= SFMT::N32)
{
GenRandAll();
idx = 0;
}
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
r1 = sfmt.u[idx];
r2 = sfmt.u[idx + 1];
idx += 2;
return ((QWORD)r2 << 32) | r1;
#else
r = sfmt.u64[idx / 2];
idx += 2;
return r;
#endif
}
#ifndef ONLY64
/**
* This function generates pseudorandom 32-bit integers in the
* specified array[] by one call. The number of pseudorandom integers
* is specified by the argument size, which must be at least 624 and a
* multiple of four. The generation by this function is much faster
* than the following gen_rand function.
*
* For initialization, init_gen_rand or init_by_array must be called
* before the first call of this function. This function can not be
* used after calling gen_rand function, without initialization.
*
* @param array an array where pseudorandom 32-bit integers are filled
* by this function. The pointer to the array must be \b "aligned"
* (namely, must be a multiple of 16) in the SIMD version, since it
* refers to the address of a 128-bit integer. In the standard C
* version, the pointer is arbitrary.
*
* @param size the number of 32-bit pseudorandom integers to be
* generated. size must be a multiple of 4, and greater than or equal
* to (MEXP / 128 + 1) * 4.
*
* @note \b memalign or \b posix_memalign is available to get aligned
* memory. Mac OSX doesn't have these functions, but \b malloc of OSX
* returns the pointer to the aligned memory block.
*/
void FRandom::FillArray32(DWORD *array, int size)
{
assert(initialized);
assert(idx == SFMT::N32);
assert(size % 4 == 0);
assert(size >= SFMT::N32);
GenRandArray((w128_t *)array, size / 4);
idx = SFMT::N32;
}
#endif
/**
* This function generates pseudorandom 64-bit integers in the
* specified array[] by one call. The number of pseudorandom integers
* is specified by the argument size, which must be at least 312 and a
* multiple of two. The generation by this function is much faster
* than the following gen_rand function.
*
* For initialization, init_gen_rand or init_by_array must be called
* before the first call of this function. This function can not be
* used after calling gen_rand function, without initialization.
*
* @param array an array where pseudorandom 64-bit integers are filled
* by this function. The pointer to the array must be "aligned"
* (namely, must be a multiple of 16) in the SIMD version, since it
* refers to the address of a 128-bit integer. In the standard C
* version, the pointer is arbitrary.
*
* @param size the number of 64-bit pseudorandom integers to be
* generated. size must be a multiple of 2, and greater than or equal
* to (MEXP / 128 + 1) * 2
*
* @note \b memalign or \b posix_memalign is available to get aligned
* memory. Mac OSX doesn't have these functions, but \b malloc of OSX
* returns the pointer to the aligned memory block.
*/
void FRandom::FillArray64(QWORD *array, int size)
{
assert(initialized);
assert(idx == SFMT::N32);
assert(size % 2 == 0);
assert(size >= SFMT::N64);
GenRandArray((w128_t *)array, size / 2);
idx = SFMT::N32;
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
swap((w128_t *)array, size / 2);
#endif
}
/**
* This function initializes the internal state array with a 32-bit
* integer seed.
*
* @param seed a 32-bit integer used as the seed.
*/
void FRandom::InitGenRand(DWORD seed)
{
int i;
sfmt.u[idxof(0)] = seed;
for (i = 1; i < SFMT::N32; i++)
{
sfmt.u[idxof(i)] = 1812433253UL * (sfmt.u[idxof(i - 1)]
^ (sfmt.u[idxof(i - 1)] >> 30))
+ i;
}
idx = SFMT::N32;
PeriodCertification();
#ifndef NDEBUG
initialized = 1;
#endif
}
/**
* This function initializes the internal state array,
* with an array of 32-bit integers used as the seeds
* @param init_key the array of 32-bit integers, used as a seed.
* @param key_length the length of init_key.
*/
void FRandom::InitByArray(DWORD *init_key, int key_length)
{
int i, j, count;
DWORD r;
int lag;
int mid;
int size = SFMT::N * 4;
if (size >= 623) {
lag = 11;
} else if (size >= 68) {
lag = 7;
} else if (size >= 39) {
lag = 5;
} else {
lag = 3;
}
mid = (size - lag) / 2;
memset(&sfmt, 0x8b, sizeof(sfmt));
if (key_length + 1 > SFMT::N32) {
count = key_length + 1;
} else {
count = SFMT::N32;
}
r = func1(sfmt.u[idxof(0)] ^ sfmt.u[idxof(mid)] ^ sfmt.u[idxof(SFMT::N32 - 1)]);
sfmt.u[idxof(mid)] += r;
r += key_length;
sfmt.u[idxof(mid + lag)] += r;
sfmt.u[idxof(0)] = r;
count--;
for (i = 1, j = 0; (j < count) && (j < key_length); j++)
{
r = func1(sfmt.u[idxof(i)] ^ sfmt.u[idxof((i + mid) % SFMT::N32)] ^ sfmt.u[idxof((i + SFMT::N32 - 1) % SFMT::N32)]);
sfmt.u[idxof((i + mid) % SFMT::N32)] += r;
r += init_key[j] + i;
sfmt.u[idxof((i + mid + lag) % SFMT::N32)] += r;
sfmt.u[idxof(i)] = r;
i = (i + 1) % SFMT::N32;
}
for (; j < count; j++)
{
r = func1(sfmt.u[idxof(i)] ^ sfmt.u[idxof((i + mid) % SFMT::N32)] ^ sfmt.u[idxof((i + SFMT::N32 - 1) % SFMT::N32)]);
sfmt.u[idxof((i + mid) % SFMT::N32)] += r;
r += i;
sfmt.u[idxof((i + mid + lag) % SFMT::N32)] += r;
sfmt.u[idxof(i)] = r;
i = (i + 1) % SFMT::N32;
}
for (j = 0; j < SFMT::N32; j++)
{
r = func2(sfmt.u[idxof(i)] + sfmt.u[idxof((i + mid) % SFMT::N32)] + sfmt.u[idxof((i + SFMT::N32 - 1) % SFMT::N32)]);
sfmt.u[idxof((i + mid) % SFMT::N32)] ^= r;
r -= i;
sfmt.u[idxof((i + mid + lag) % SFMT::N32)] ^= r;
sfmt.u[idxof(i)] = r;
i = (i + 1) % SFMT::N32;
}
idx = SFMT::N32;
PeriodCertification();
#ifndef NDEBUG
initialized = 1;
#endif
}

120
src/sfmt/SFMT.h Normal file
View file

@ -0,0 +1,120 @@
/**
* @file SFMT.h
*
* @brief SIMD oriented Fast Mersenne Twister(SFMT) pseudorandom
* number generator
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (Hiroshima University)
*
* Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University. All rights reserved.
*
* The new BSD License is applied to this software.
* see LICENSE.txt
*
* @note We assume that your system has inttypes.h. If your system
* doesn't have inttypes.h, you have to typedef uint32_t and uint64_t,
* and you have to define PRIu64 and PRIx64 in this file as follows:
* @verbatim
typedef unsigned int uint32_t
typedef unsigned long long uint64_t
#define PRIu64 "llu"
#define PRIx64 "llx"
@endverbatim
* uint32_t must be exactly 32-bit unsigned integer type (no more, no
* less), and uint64_t must be exactly 64-bit unsigned integer type.
* PRIu64 and PRIx64 are used for printf function to print 64-bit
* unsigned int and 64-bit unsigned int in hexadecimal format.
*/
#ifndef SFMT_H
#define SFMT_H
#ifndef PRIu64
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define PRIu64 "I64u"
#define PRIx64 "I64x"
#else
#define PRIu64 "llu"
#define PRIx64 "llx"
#endif
#endif
#if defined(__GNUC__)
#define ALWAYSINLINE __attribute__((always_inline))
#else
#define ALWAYSINLINE
#endif
#if defined(_MSC_VER)
#if _MSC_VER >= 1200
#define PRE_ALWAYS __forceinline
#else
#define PRE_ALWAYS inline
#endif
#else
#define PRE_ALWAYS inline
#endif
/*------------------------------------------------------
128-bit SIMD data type for Altivec, SSE2 or standard C
------------------------------------------------------*/
#if defined(HAVE_ALTIVEC)
#if !defined(__APPLE__)
#include <altivec.h>
#endif
/** 128-bit data structure */
union w128_t {
vector unsigned int s;
DWORD u[4];
QWORD u64[2];
};
#elif defined(HAVE_SSE2)
#include <emmintrin.h>
/** 128-bit data structure */
union w128_t {
__m128i si;
DWORD u[4];
QWORD u64[2];
};
#else
/** 128-bit data structure */
union w128_t {
DWORD u[4];
QWORD u64[2];
};
#endif
/*-----------------
BASIC DEFINITIONS
-----------------*/
/** Mersenne Exponent. The period of the sequence
* is a multiple of 2^MEXP-1. */
#if !defined(MEXP)
// [RH] The default MEXP for SFMT is 19937, but since that consumes
// quite a lot of space for state, and we're using lots of different
// RNGs, default to something smaller.
#define MEXP 607
#endif
namespace SFMT
{
/** SFMT generator has an internal state array of 128-bit integers,
* and N is its size. */
enum { N = MEXP / 128 + 1 };
/** N32 is the size of internal state array when regarded as an array
* of 32-bit integers.*/
enum { N32 = N * 4 };
/** N64 is the size of internal state array when regarded as an array
* of 64-bit integers.*/
enum { N64 = N * 2 };
};
#endif

View file

@ -1,9 +1,9 @@
/*
** i_sound.cpp
** fmodsound.cpp
** System interface for sound; uses FMOD Ex.
**
**---------------------------------------------------------------------------
** Copyright 1998-2008 Randy Heit
** Copyright 1998-2009 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
@ -582,6 +582,28 @@ bool FMODSoundRenderer::IsValid()
return InitSuccess;
}
#ifdef _MSC_VER
//==========================================================================
//
// CheckException
//
//==========================================================================
#define FACILITY_VISUALCPP ((LONG)0x6d)
#define VcppException(sev,err) ((sev) | (FACILITY_VISUALCPP<<16) | err)
static int CheckException(DWORD code)
{
if (code == VcppException(ERROR_SEVERITY_ERROR,ERROR_MOD_NOT_FOUND) ||
code == VcppException(ERROR_SEVERITY_ERROR,ERROR_PROC_NOT_FOUND))
{
return EXCEPTION_EXECUTE_HANDLER;
}
return EXCEPTION_CONTINUE_SEARCH;
}
#endif
//==========================================================================
//
// FMODSoundRenderer :: Init
@ -619,7 +641,23 @@ bool FMODSoundRenderer::Init()
Printf("I_InitSound: Initializing FMOD\n");
// Create a System object and initialize.
#ifdef _MSC_VER
__try {
#endif
result = FMOD::System_Create(&Sys);
#ifdef _MSC_VER
}
__except(CheckException(GetExceptionCode()))
{
Sys = NULL;
Printf(TEXTCOLOR_ORANGE"Failed to load fmodex"
#ifdef _WIN64
"64"
#endif
".dll\n");
return false;
}
#endif
if (result != FMOD_OK)
{
Sys = NULL;

View file

@ -130,8 +130,8 @@ inline volatile unsigned long long rdtsc()
if (CPU.bRDTSC)
#endif
{
register unsigned long long tsc asm("eax");
asm volatile ("\trdtsc\n" : : : "eax", "edx");
register unsigned long long tsc;
asm volatile ("\trdtsc\n" : "=A" (tsc));
return tsc;
}
return 0;

View file

@ -3,5 +3,5 @@
// This file was automatically generated by the
// updaterevision tool. Do not edit by hand.
#define ZD_SVN_REVISION_STRING "1493"
#define ZD_SVN_REVISION_NUMBER 1493
#define ZD_SVN_REVISION_STRING "1514"
#define ZD_SVN_REVISION_NUMBER 1514

View file

@ -2298,16 +2298,23 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeFlag)
if (fd != NULL)
{
bool kill_before, kill_after;
INTBOOL item_before, item_after;
kill_before = self->CountsAsKill();
item_before = self->flags & MF_COUNTITEM;
if (fd->structoffset == -1)
{
HandleDeprecatedFlags(self, cls->ActorInfo, expression, fd->flagbit);
}
else
{
int *flagp = (int*) (((char*)self) + fd->structoffset);
DWORD *flagp = (DWORD*) (((char*)self) + fd->structoffset);
// If these 2 flags get changed we need to update the blockmap and sector links.
bool linkchange = flagp == &self->flags && (fd->flagbit == MF_NOBLOCKMAP || fd->flagbit == MF_NOSECTOR);
if (linkchange) self->UnlinkFromWorld();
if (expression)
{
*flagp |= fd->flagbit;
@ -2316,8 +2323,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeFlag)
{
*flagp &= ~fd->flagbit;
}
if (linkchange) self->LinkToWorld();
}
kill_after = self->CountsAsKill();
item_after = self->flags & MF_COUNTITEM;
// Was this monster previously worth a kill but no longer is?
// Or vice versa?
if (kill_before != kill_after)
@ -2331,6 +2340,18 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeFlag)
level.total_monsters--;
}
}
// same for items
if (item_before != item_after)
{
if (item_after)
{ // It counts as an item now.
level.total_items++;
}
else
{ // It no longer counts as an item
level.total_items--;
}
}
}
else
{

View file

@ -1776,7 +1776,18 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, scoreicon, S, PlayerPawn)
DEFINE_CLASS_PROPERTY_PREFIX(player, crouchsprite, S, PlayerPawn)
{
PROP_STRING_PARM(z, 0);
defaults->crouchsprite = GetSpriteIndex (z);
if (strlen(z) == 4)
{
defaults->crouchsprite = GetSpriteIndex (z);
}
else if (*z == 0)
{
defaults->crouchsprite = 0;
}
else
{
I_Error("Sprite name must have exactly 4 characters");
}
}
//==========================================================================

View file

@ -56,7 +56,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 221
#define NETGAMEVERSION 222
// Version stored in the ini's [LastRun] section.
// Bump it if you made some configuration change that you want to
@ -77,7 +77,7 @@
// SAVESIG should match SAVEVER.
// MINSAVEVER is the minimum level snapshot version that can be loaded.
#define MINSAVEVER 1452
#define MINSAVEVER 1507
#if ZD_SVN_REVISION_NUMBER < MINSAVEVER
// Never write a savegame with a version lower than what we need

View file

@ -164,6 +164,11 @@ FWadCollection::FWadCollection ()
}
FWadCollection::~FWadCollection ()
{
DeleteAll();
}
void FWadCollection::DeleteAll ()
{
if (FirstLumpIndex != NULL)
{
@ -193,6 +198,7 @@ FWadCollection::~FWadCollection ()
}
}
LumpInfo.Clear();
NumLumps = 0;
for (DWORD i = 0; i < Wads.Size(); ++i)
{
@ -217,10 +223,8 @@ void FWadCollection::InitMultipleFiles (wadlist_t **filenames)
int numfiles;
// open all the files, load headers, and count lumps
DeleteAll();
numfiles = 0;
Wads.Clear();
LumpInfo.Clear();
NumLumps = 0;
while (*filenames)
{
@ -260,10 +264,10 @@ void FWadCollection::InitMultipleFiles (wadlist_t **filenames)
MergeLumps ("HI_START", "HI_END", ns_hires);
// [RH] Set up hash table
FirstLumpIndex = new WORD[NumLumps];
NextLumpIndex = new WORD[NumLumps];
FirstLumpIndex_FullName = new WORD[NumLumps];
NextLumpIndex_FullName = new WORD[NumLumps];
FirstLumpIndex = new DWORD[NumLumps];
NextLumpIndex = new DWORD[NumLumps];
FirstLumpIndex_FullName = new DWORD[NumLumps];
NextLumpIndex_FullName = new DWORD[NumLumps];
InitHashChains ();
}
@ -298,7 +302,7 @@ int FWadCollection::AddExternalFile(const char *filename)
//
//-----------------------------------------------------------------------
static DWORD Zip_FindCentralDir(FileReader * fin)
DWORD Zip_FindCentralDir(FileReader * fin)
{
unsigned char buf[BUFREADCOMMENT + 4];
DWORD FileSize;

View file

@ -103,6 +103,9 @@ void uppercopy (char *to, const char *from);
// Perform Blood encryption/decryption.
void BloodCrypt (void *data, int key, int len);
// Locate central directory in a zip file.
DWORD Zip_FindCentralDir(FileReader * fin);
// A very loose reference to a lump on disk. This is really just a wrapper
// around the main wad's FILE object with a different length recorded. Since
// two lumps from the same wad share the same FILE, you cannot read from
@ -224,11 +227,11 @@ protected:
class WadFileRecord;
struct LumpRecord;
WORD *FirstLumpIndex; // [RH] Hashing stuff moved out of lumpinfo structure
WORD *NextLumpIndex;
DWORD *FirstLumpIndex; // [RH] Hashing stuff moved out of lumpinfo structure
DWORD *NextLumpIndex;
WORD *FirstLumpIndex_FullName; // The same information for fully qualified paths from .zips
WORD *NextLumpIndex_FullName;
DWORD *FirstLumpIndex_FullName; // The same information for fully qualified paths from .zips
DWORD *NextLumpIndex_FullName;
TArray<LumpRecord> LumpInfo;
@ -249,6 +252,7 @@ private:
void ScanForFlatHack (int startlump);
void RenameSprites (int startlump);
void SetLumpAddress(LumpRecord *l);
void DeleteAll();
};
extern FWadCollection Wads;

View file

@ -123,10 +123,10 @@ typedef enum
} animenum_t;
typedef struct
struct yahpt_t
{
int x, y;
} yahpt_t;
};
struct lnode_t
{
@ -146,7 +146,7 @@ struct lnode_t
//
#define MAX_ANIMATION_FRAMES 20
typedef struct
struct in_anim_t
{
int type; // Made an int so I can use '|'
int period; // period in tics between animations
@ -162,7 +162,7 @@ typedef struct
char levelname[9];
char levelname2[9];
} in_anim_t;
};
static TArray<lnode_t> lnodes;
static TArray<in_anim_t> anims;
@ -312,7 +312,7 @@ void WI_LoadBackground(bool isenterpic)
{
case GAME_Chex:
case GAME_Doom:
if (gamemode != commercial)
if (!(gameinfo.flags & GI_MAPxx))
{
const char *level = isenterpic ? wbs->next : wbs->current;
if (IsExMy(level))
@ -332,7 +332,7 @@ void WI_LoadBackground(bool isenterpic)
if (level.info->ExitPic.IsNotEmpty()) return;
// E1-E3 need special treatment when playing Doom 1.
if (gamemode!=commercial)
if (!(gameinfo.flags & GI_MAPxx))
{
// not if the last level is not from the first 3 episodes
if (!IsExMy(wbs->current)) return;
@ -1881,16 +1881,8 @@ void WI_Ticker(void)
// intermission music - use the defaults if none specified
if (level.info->InterMusic.IsNotEmpty())
S_ChangeMusic(level.info->InterMusic, level.info->intermusicorder);
else if (gameinfo.gametype == GAME_Heretic)
S_ChangeMusic ("mus_intr");
else if (gameinfo.gametype == GAME_Hexen)
S_ChangeMusic ("hub");
else if (gameinfo.gametype == GAME_Strife) // Strife also needs a default
S_ChangeMusic ("d_slide");
else if (gamemode == commercial)
S_ChangeMusic ("$MUSIC_DM2INT");
else
S_ChangeMusic ("$MUSIC_INTER");
S_ChangeMusic (gameinfo.intermissionMusic.GetChars());
}

View file

@ -27,6 +27,7 @@
#include <direct.h>
#include <string.h>
#include <process.h>
#include <time.h>
#include <stdarg.h>
#include <sys/types.h>
@ -36,6 +37,7 @@
#include <windows.h>
#include <mmsystem.h>
#include <richedit.h>
#include <wincrypt.h>
#define USE_WINDOWS_DWORD
#include "hardware.h"
@ -564,7 +566,7 @@ void I_PrintStr (const char *cp)
int bpos = 0;
CHARRANGE selection;
CHARRANGE endselection;
LONG lines_before, lines_after;
LONG lines_before = 0, lines_after;
CHARFORMAT format;
if (edit != NULL)
@ -876,10 +878,39 @@ FString I_GetSteamPath()
return path;
}
long long QueryPerfCounter()
// Return a random seed, preferably one with lots of entropy.
unsigned int I_MakeRNGSeed()
{
LARGE_INTEGER counter;
unsigned int seed;
QueryPerformanceCounter(&counter);
return counter.QuadPart;
// If RtlGenRandom is available, use that to avoid increasing the
// working set by pulling in all of the crytographic API.
HMODULE advapi = GetModuleHandle("advapi32.dll");
if (advapi != NULL)
{
BOOLEAN (APIENTRY *RtlGenRandom)(void *, ULONG) =
(BOOLEAN (APIENTRY *)(void *, ULONG))GetProcAddress(advapi, "SystemFunction036");
if (RtlGenRandom != NULL)
{
if (RtlGenRandom(&seed, sizeof(seed)))
{
return seed;
}
}
}
// Use the full crytographic API to produce a seed. If that fails,
// time() is used as a fallback.
HCRYPTPROV prov;
if (!CryptAcquireContext(&prov, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
return (unsigned int)time(NULL);
}
if (!CryptGenRandom(prov, sizeof(seed), (BYTE *)&seed))
{
seed = (unsigned int)time(NULL);
}
CryptReleaseContext(prov, 0);
return seed;
}

View file

@ -68,6 +68,9 @@ extern void (*I_FreezeTime) (bool frozen);
fixed_t I_GetTimeFrac (uint32 *ms);
// Return a seed value for the RNG.
unsigned int I_MakeRNGSeed();
//
// Called by D_DoomLoop,

View file

@ -1,10 +1,5 @@
cmake_minimum_required( VERSION 2.4 )
# GZDoom doesn't build dehsupp
#add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated/dehsupp.lmp
# COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/generated
# COMMAND ${CMAKE_BINARY_DIR}/tools/dehsupp/dehsupp ${CMAKE_CURRENT_SOURCE_DIR}/sources/dehsupp.txt ${CMAKE_CURRENT_BINARY_DIR}/generated/dehsupp.lmp
# DEPENDS dehsupp ${CMAKE_CURRENT_SOURCE_DIR}/sources/dehsupp.txt )
add_custom_command( OUTPUT ${ZDOOM_OUTPUT_DIR}/gzdoom.pk3
COMMAND ${CMAKE_BINARY_DIR}/tools/zipdir/zipdir ${ZDOOM_OUTPUT_DIR}/gzdoom.pk3 ${CMAKE_CURRENT_SOURCE_DIR}/static ${CMAKE_CURRENT_BINARY_DIR}/generated

View file

@ -781,3 +781,20 @@ ACTOR BrainStem 81
}
}
// Grey stalagmite (unused Doom sprite, definition taken from Skulltag -----
ACTOR Stalagmite 5050
{
Game Doom
Radius 16
Height 48
+SOLID
States
{
Spawn:
SMT2 A -1
Stop
}
}

View file

@ -69,9 +69,10 @@ ACTOR DoomUnusedStates
{
States
{
Label1:
SMT2 A -1
stop
Death:
Label2:
PLAY N -1
stop
PLAY S -1

View file

@ -44,14 +44,18 @@ ACTOR DoomPlayer : PlayerPawn
PLAY G 4 A_Pain
Goto Spawn
Death:
PLAY H 10 A_PlayerSkinCheck("AltSkinDeath")
PLAY H 0 A_PlayerSkinCheck("AltSkinDeath")
Death1:
PLAY H 10
PLAY I 10 A_PlayerScream
PLAY J 10 A_NoBlocking
PLAY KLM 10
PLAY N -1
Stop
XDeath:
PLAY O 5 A_PlayerSkinCheck("AltSkinXDeath")
PLAY O 0 A_PlayerSkinCheck("AltSkinXDeath")
XDeath1:
PLAY O 5
PLAY P 5 A_XScream
PLAY Q 5 A_NoBlocking
PLAY RSTUV 5

View file

@ -27,6 +27,7 @@ ACTOR Sorcerer1 7
+NOTARGET
+NOICEDEATH
+FLOORCLIP
+DONTGIB
SeeSound "dsparilserpent/sight"
AttackSound "dsparilserpent/attack"
PainSound "dsparilserpent/pain"
@ -128,6 +129,7 @@ ACTOR Sorcerer2
+NOTARGET
+NOICEDEATH
+FLOORCLIP
+BOSSDEATH
SeeSound "dsparil/sight"
AttackSound "dsparil/attack"
PainSound "dsparil/pain"

View file

@ -57,7 +57,7 @@ ACTOR Acolyte : StrifeHumanoid
AGRD K 3 A_NoBlocking
AGRD L 3
AGRD M 3 A_AcolyteDie
AGRD N 1400
AGRD N -1
Stop
XDeath:
GIBS A 5 A_NoBlocking

View file

@ -22,7 +22,7 @@ ACTOR StrifeHumanoid
BURN N 5 Bright
BURN OPQPQ 5 Bright
BURN RSTU 7 Bright
BURN V 700
BURN V -1
Stop
Disintegrate:
DISR A 5 A_PlaySoundEx("misc/disruptordeath", "Voice")

Binary file not shown.

736
wadsrc/static/dehsupp.txt Normal file
View file

@ -0,0 +1,736 @@
OrgHeights
{
56, 56, 56, 56, 16, 56, 8, 16, 64, 8, 56, 56,
56, 56, 56, 64, 8, 64, 56, 100, 64, 110, 56, 56,
72, 16, 32, 32, 32, 16, 42, 8, 8, 8,
8, 8, 8, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 68, 84, 84,
68, 52, 84, 68, 52, 52, 68, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 88, 88, 64, 64, 64, 64,
16, 16, 16
};
// This is a list of all the action functions used by each of Doom's states.
ActionList
{
NULL, Light0, WeaponReady, Lower, Raise, NULL,
Punch, NULL, NULL, ReFire, WeaponReady, Lower,
Raise, NULL, FirePistol, NULL, ReFire, Light1,
WeaponReady, Lower, Raise, NULL, FireShotgun, NULL,
NULL, NULL, NULL, NULL, NULL, ReFire, Light1,
Light2, WeaponReady, Lower, Raise, NULL,
FireShotgun2, NULL, CheckReload, OpenShotgun2, NULL,
LoadShotgun2, NULL, CloseShotgun2, ReFire, NULL, NULL,
Light1, Light2, WeaponReady, Lower, Raise,
FireCGun, FireCGun, ReFire, Light1, Light2,
WeaponReady, Lower, Raise, GunFlash, FireMissile,
ReFire, Light1, NULL, Light2, Light2, WeaponReady,
WeaponReady, Lower, Raise, Saw, Saw, ReFire,
WeaponReady, Lower, Raise, FirePlasma, ReFire,
Light1, Light1, WeaponReady, Lower, Raise,
BFGsound, GunFlash, FireBFG, ReFire, Light1,
Light2, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, BFGSpray, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, Explode, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
Pain, NULL, PlayerScream, Fall, NULL, NULL, NULL,
NULL, NULL, XScream, Fall, NULL, NULL, NULL, NULL,
NULL, NULL, Look, Look, Chase, Chase, Chase,
Chase, Chase, Chase, Chase, Chase, FaceTarget,
PosAttack, NULL, NULL, Pain, NULL, Scream, Fall,
NULL, NULL, NULL, XScream, Fall, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, Look,
Look, Chase, Chase, Chase, Chase, Chase,
Chase, Chase, Chase, FaceTarget, SPosAttack, NULL,
NULL, Pain, NULL, Scream, Fall, NULL, NULL, NULL,
XScream, Fall, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, Look, Look,
VileChase, VileChase, VileChase, VileChase,
VileChase, VileChase, VileChase, VileChase,
VileChase, VileChase, VileChase, VileChase,
VileStart, FaceTarget, VileTarget, FaceTarget,
FaceTarget, FaceTarget, FaceTarget, FaceTarget,
FaceTarget, VileAttack, NULL, NULL, NULL, NULL, NULL,
Pain, NULL, Scream, Fall, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, StartFire, Fire, Fire, Fire,
FireCrackle, Fire, Fire, Fire, Fire, Fire,
Fire, Fire, Fire, Fire, Fire, Fire, Fire,
Fire, FireCrackle, Fire, Fire, Fire, Fire,
Fire, Fire, Fire, Fire, Fire, Fire, Fire,
NULL, NULL, NULL, NULL, NULL, Tracer, Tracer, NULL,
NULL, NULL, Look, Look, Chase, Chase, Chase,
Chase, Chase, Chase, Chase, Chase, Chase,
Chase, Chase, Chase, FaceTarget, SkelWhoosh,
FaceTarget, SkelFist, FaceTarget, FaceTarget,
SkelMissile, FaceTarget, NULL, Pain, NULL, NULL,
Scream, Fall, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, Look,
Look, Chase, Chase, Chase, Chase, Chase,
Chase, Chase, Chase, Chase, Chase, Chase,
Chase, FatRaise, FatAttack1, FaceTarget, FaceTarget,
FatAttack2, FaceTarget, FaceTarget, FatAttack3,
FaceTarget, FaceTarget, NULL, Pain, NULL, Scream,
Fall, NULL, NULL, NULL, NULL, NULL, NULL, BossDeath,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
Look, Look, Chase, Chase, Chase, Chase,
Chase, Chase, Chase, Chase, FaceTarget,
CPosAttack, CPosAttack, CPosRefire, NULL, Pain,
NULL, Scream, Fall, NULL, NULL, NULL, NULL, NULL,
XScream, Fall, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, Look, Look, Chase,
Chase, Chase, Chase, Chase, Chase, Chase,
Chase, FaceTarget, FaceTarget, TroopAttack, NULL,
Pain, NULL, Scream, NULL, Fall, NULL, NULL,
XScream, NULL, Fall, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, Look, Look, Chase,
Chase, Chase, Chase, Chase, Chase, Chase,
Chase, FaceTarget, FaceTarget, SargAttack, NULL,
Pain, NULL, Scream, NULL, Fall, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, Look, Chase,
FaceTarget, FaceTarget, HeadAttack, NULL, Pain,
NULL, NULL, Scream, NULL, NULL, Fall, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, Look, Look, Chase, Chase, Chase, Chase,
Chase, Chase, Chase, Chase, FaceTarget,
FaceTarget, BruisAttack, NULL, Pain, NULL, Scream,
NULL, Fall, NULL, NULL, BossDeath, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, Look, Look, Chase,
Chase, Chase, Chase, Chase, Chase, Chase,
Chase, FaceTarget, FaceTarget, BruisAttack, NULL,
Pain, NULL, Scream, NULL, Fall, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, Look,
Look, Chase, Chase, FaceTarget, SkullAttack, NULL,
NULL, NULL, Pain, NULL, Scream, NULL, Fall, NULL,
NULL, Look, Look, Metal, Chase, Chase, Chase,
Metal, Chase, Chase, Chase, Metal, Chase,
Chase, Chase, FaceTarget, SPosAttack, SPosAttack,
SpidRefire, NULL, Pain, Scream, Fall, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, BossDeath, Look,
Look, NULL, BabyMetal, Chase, Chase, Chase,
Chase, Chase, BabyMetal, Chase, Chase, Chase,
Chase, Chase, FaceTarget, BspiAttack, NULL,
SpidRefire, NULL, Pain, Scream, Fall, NULL, NULL,
NULL, NULL, BossDeath, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
Look, Look, Hoof, Chase, Chase, Chase,
Chase, Chase, Metal, Chase, FaceTarget,
CyberAttack, FaceTarget, CyberAttack, FaceTarget,
CyberAttack, Pain, NULL, Scream, NULL, NULL, NULL,
Fall, NULL, NULL, NULL, BossDeath, Look, Chase,
Chase, Chase, Chase, Chase, Chase, FaceTarget,
FaceTarget, FaceTarget, PainAttack, NULL, Pain,
NULL, Scream, NULL, NULL, PainDie, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, Look, Look, Chase,
Chase, Chase, Chase, Chase, Chase, Chase,
Chase, FaceTarget, FaceTarget, CPosAttack,
FaceTarget, CPosAttack, CPosRefire, NULL, Pain,
NULL, Scream, Fall, NULL, NULL, NULL, XScream,
Fall, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, Scream,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, KeenDie,
NULL, NULL, Pain, NULL, BrainPain, BrainScream,
NULL, NULL, BrainDie, Look, BrainAwake, BrainSpit,
SpawnSound, SpawnFly, SpawnFly, SpawnFly, Fire,
Fire, Fire, Fire, Fire, Fire, Fire, Fire,
NULL, NULL, BrainExplode, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, Scream, NULL, Explode
};
// DeHackEd made the erroneous assumption that if a state didn't appear in
// Doom with an action function, then it was incorrect to assign it one.
// This is a list of the states that had action functions, so we can figure
// out where in the original list of states a DeHackEd codepointer is.
// (DeHackEd might also have done this for compatibility between Doom
// versions, because states could move around, but actions would never
// disappear, but that doesn't explain why frame patches specify an exact
// state rather than a code pointer.)
CodePConv
{
1, 2, 3, 4, 6, 9, 10, 11, 12, 14,
16, 17, 18, 19, 20, 22, 29, 30, 31, 32,
33, 34, 36, 38, 39, 41, 43, 44, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
59, 60, 61, 62, 63, 65, 66, 67, 68, 69,
70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
119, 127, 157, 159, 160, 166, 167, 174, 175, 176,
177, 178, 179, 180, 181, 182, 183, 184, 185, 188,
190, 191, 195, 196, 207, 208, 209, 210, 211, 212,
213, 214, 215, 216, 217, 218, 221, 223, 224, 228,
229, 241, 242, 243, 244, 245, 246, 247, 248, 249,
250, 251, 252, 253, 254, 255, 256, 257, 258, 259,
260, 261, 262, 263, 264, 270, 272, 273, 281, 282,
283, 284, 285, 286, 287, 288, 289, 290, 291, 292,
293, 294, 295, 296, 297, 298, 299, 300, 301, 302,
303, 304, 305, 306, 307, 308, 309, 310, 316, 317,
321, 322, 323, 324, 325, 326, 327, 328, 329, 330,
331, 332, 333, 334, 335, 336, 337, 338, 339, 340,
341, 342, 344, 347, 348, 362, 363, 364, 365, 366,
367, 368, 369, 370, 371, 372, 373, 374, 375, 376,
377, 378, 379, 380, 381, 382, 383, 384, 385, 387,
389, 390, 397, 406, 407, 408, 409, 410, 411, 412,
413, 414, 415, 416, 417, 418, 419, 421, 423, 424,
430, 431, 442, 443, 444, 445, 446, 447, 448, 449,
450, 451, 452, 453, 454, 456, 458, 460, 463, 465,
475, 476, 477, 478, 479, 480, 481, 482, 483, 484,
485, 486, 487, 489, 491, 493, 502, 503, 504, 505,
506, 508, 511, 514, 527, 528, 529, 530, 531, 532,
533, 534, 535, 536, 537, 538, 539, 541, 543, 545,
548, 556, 557, 558, 559, 560, 561, 562, 563, 564,
565, 566, 567, 568, 570, 572, 574, 585, 586, 587,
588, 589, 590, 594, 596, 598, 601, 602, 603, 604,
605, 606, 607, 608, 609, 610, 611, 612, 613, 614,
615, 616, 617, 618, 620, 621, 622, 631, 632, 633,
635, 636, 637, 638, 639, 640, 641, 642, 643, 644,
645, 646, 647, 648, 650, 652, 653, 654, 659, 674,
675, 676, 677, 678, 679, 680, 681, 682, 683, 684,
685, 686, 687, 688, 689, 690, 692, 696, 700, 701,
702, 703, 704, 705, 706, 707, 708, 709, 710, 711,
713, 715, 718, 726, 727, 728, 729, 730, 731, 732,
733, 734, 735, 736, 737, 738, 739, 740, 741, 743,
745, 746, 750, 751, 766, 774, 777, 779, 780, 783,
784, 785, 786, 787, 788, 789, 790, 791, 792, 793,
794, 795, 796, 797, 798, 801, 809, 811
};
// Sprite names in the order Doom originally had them.
OrgSprNames
{
TROO,SHTG,PUNG,PISG,PISF,SHTF,SHT2,CHGG,CHGF,MISG,
MISF,SAWG,PLSG,PLSF,BFGG,BFGF,BLUD,PUFF,BAL1,BAL2,
PLSS,PLSE,MISL,BFS1,BFE1,BFE2,TFOG,IFOG,PLAY,POSS,
SPOS,VILE,FIRE,FATB,FBXP,SKEL,MANF,FATT,CPOS,SARG,
HEAD,BAL7,BOSS,BOS2,SKUL,SPID,BSPI,APLS,APBX,CYBR,
PAIN,SSWV,KEEN,BBRN,BOSF,ARM1,ARM2,BAR1,BEXP,FCAN,
BON1,BON2,BKEY,RKEY,YKEY,BSKU,RSKU,YSKU,STIM,MEDI,
SOUL,PINV,PSTR,PINS,MEGA,SUIT,PMAP,PVIS,CLIP,AMMO,
ROCK,BROK,CELL,CELP,SHEL,SBOX,BPAK,BFUG,MGUN,CSAW,
LAUN,PLAS,SHOT,SGN2,COLU,SMT2,GOR1,POL2,POL5,POL4,
POL3,POL1,POL6,GOR2,GOR3,GOR4,GOR5,SMIT,COL1,COL2,
COL3,COL4,CAND,CBRA,COL6,TRE1,TRE2,ELEC,CEYE,FSKU,
COL5,TBLU,TGRN,TRED,SMBT,SMGT,SMRT,HDB1,HDB2,HDB3,
HDB4,HDB5,HDB6,POB1,POB2,BRS1,TLMP,TLP2
};
StateMap
{
// S_NULL is implicit
Weapon, LightDone, 1, // S_LIGHTDONE
Fist, Ready, 8, // S_PUNCH - S_PUNCH5
Pistol, Ready, 8, // S_PISTOL - S_PISTOLFLASH
Shotgun, Ready, 14, // S_SGUN - S_SGUNFLASH2
SuperShotgun, Ready, 17, // S_DSGUN - S_DSGUNFLASH2
Chaingun, Ready, 8, // S_CHAIN - S_CHAINFLASH2
RocketLauncher, Ready, 10, // S_MISSILE - S_MISSILEFLASH4
Chainsaw, Ready, 7, // S_SAW - S_SAW3
PlasmaRifle, Ready, 7, // S_PLASMA - S_PLASMAFLASH2
BFG9000, Ready, 9, // S_BFG - S_BFGFLASH2
Blood, Spawn, 3, // S_BLOOD1 - S_BLOOD3
BulletPuff, Spawn, 4, // S_PUFF1 - S_PUFF4
DoomImpBall, Spawn, 5, // S_TBALL1 - S_TBALLX3
CacodemonBall, Spawn, 5, // S_RBALL1 - S_RBALLX3
PlasmaBall, Spawn, 7, // S_PLASBALL - S_PLASEXP5
Rocket, Spawn, 1, // S_ROCKET
BFGBall, Spawn, 8, // S_BFGSHOT - S_BFGLAND6
BFGExtra, Spawn, 4, // S_BFGEXP - S_BFGEXP4
Rocket, Death, 3, // S_EXPLODE1 - S_EXPLODE3
TeleportFog, Spawn, 12, // S_TFOG - S_TFOG10
ItemFog, Spawn, 7, // S_IFOG - S_IFOG5
DoomPlayer, Spawn, 9, // S_PLAY - S_PLAY_PAIN2
DoomPlayer, Death1, 7, // S_PLAY_DIE - S_PLAY_DIE7
DoomPlayer, XDeath1, 9, // S_PLAY_XDIE - S_PLAY_XDIE9
ZombieMan, Spawn, 33, // S_POSS_STND - S_POSS_RAISE4
ShotgunGuy, Spawn, 34, // S_SPOS_STND - S_SPOS_RAISE5
Archvile, Spawn, 40, // S_VILE_STND - S_VILE_DIE10
ArchvileFire, Spawn, 30, // S_FIRE1 - S_FIRE30
RevenantTracerSmoke, Spawn, 5, // S_SMOKE1 - S_SMOKE5
RevenantTracer, Spawn, 5, // S_TRACER - S_TRACEEXP3
Revenant, Spawn, 36, // S_SKEL_STND - S_SKEL_RAISE6
FatShot, Spawn, 5, // S_FATSHOT1 - S_FATSHOTX3
Fatso, Spawn, 44, // S_FATT_STND - S_FATT_RAISE8
ChaingunGuy, Spawn, 36, // S_CPOS_STND - S_CPOS_RAISE7
DoomImp, Spawn, 33, // S_TROO_STND - S_TROO_RAISE5
Demon, Spawn, 27, // S_SARG_STND - S_SARG_RAISE6
Cacodemon, Spawn, 20, // S_HEAD_STND - S_HEAD_RAISE6
BaronBall, Spawn, 5, // S_BRBALL1 - S_BRBALLX3
BaronOfHell, Spawn, 29, // S_BOSS_STND - S_BOSS_RAISE7
HellKnight, Spawn, 29, // S_BOS2_STND - S_BOS2_RAISE7
LostSoul, Spawn, 16, // S_SKULL_STND - S_SKULL_DIE6
SpiderMastermind, Spawn, 31, // S_SPID_STND - S_SPID_DIE11
Arachnotron, Spawn, 35, // S_BSPI_STND - S_BSPI_RAISE7
ArachnotronPlasma, Spawn, 7, // S_ARACH_PLAZ - S_ARACH_PLEX5
Cyberdemon, Spawn, 27, // S_CYBER_STND - S_CYBER_DIE10
PainElemental, Spawn, 25, // S_PAIN_STND - S_PAIN_RAISE6
WolfensteinSS, Spawn, 37, // S_SSWV_STND - S_SSWV_RAISE5
CommanderKeen, Spawn, 15, // S_KEENSTND - S_KEENPAIN2
BossBrain, Spawn, 6, // S_BRAIN - S_BRAIN_DIE4
BossEye, Spawn, 3, // S_BRAINEYE - S_BRAINEYE1
SpawnShot, Spawn, 4, // S_SPAWN1 - S_SPAWN4
SpawnFire, Spawn, 8, // S_SPAWNFIRE1 - S_SPAWNFIRE8
BossBrain, BrainExplode, 3, // S_BRAINEXPLODE1 - S_BRAINEXPLODE3
GreenArmor, Spawn, 2, // S_ARM1 - S_ARM1A
BlueArmor, Spawn, 2, // S_ARM2 - S_ARM2A
ExplosiveBarrel, Spawn, 7, // S_BAR1 - S_BEXP5
BurningBarrel, Spawn, 3, // S_BBAR1 - S_BBAR3
HealthBonus, Spawn, 6, // S_BON1 - S_BON1E
ArmorBonus, Spawn, 6, // S_BON2 - S_BON2E
BlueCard, Spawn, 2, // S_BKEY - S_BKEY2
RedCard, Spawn, 2, // S_RKEY - S_RKEY2
YellowCard, Spawn, 2, // S_YKEY - S_YKEY2
BlueSkull, Spawn, 2, // S_BSKULL - S_BSKULL2
RedSkull, Spawn, 2, // S_RSKULL - S_RSKULL2
YellowSkull, Spawn, 2, // S_YSKULL - S_YSKULL2
Stimpack, Spawn, 1, // S_STIM
Medikit, Spawn, 1, // S_MEDI
Soulsphere, Spawn, 6, // S_SOUL - S_SOUL6
InvulnerabilitySphere, Spawn, 4, // S_PINV - S_PINV4
Berserk, Spawn, 1, // S_PSTR
BlurSphere, Spawn, 4, // S_PINS - P_PINS4
Megasphere, Spawn, 4, // S_MEGA - S_MEGA4
RadSuit, Spawn, 1, // S_SUIT
Allmap, Spawn, 6, // S_PMAP - S_PMAP6
Infrared, Spawn, 2, // S_PVIS - S_PVIS2
Clip, Spawn, 1, // S_CLIP
ClipBox, Spawn, 1, // S_AMMO
RocketAmmo, Spawn, 1, // S_ROCK
RocketBox, Spawn, 1, // S_BROK
Cell, Spawn, 1, // S_CELL
CellPack, Spawn, 1, // S_CELP
Shell, Spawn, 1, // S_SHEL
ShellBox, Spawn, 1, // S_SBOX
Backpack, Spawn, 1, // S_BPAK
BFG9000, Spawn, 1, // S_BFUG
Chaingun, Spawn, 1, // S_MGUN
Chainsaw, Spawn, 1, // S_CSAW
RocketLauncher, Spawn, 1, // S_LAUN
PlasmaRifle, Spawn, 1, // S_PLAS
Shotgun, Spawn, 1, // S_SHOT
SuperShotgun, Spawn, 1, // S_SHOT2
Column, Spawn, 1, // S_COLU
DoomUnusedStates, Label1, 1, // S_STALAG
BloodyTwitch, Spawn, 4, // S_BLOODYTWITCH - S_BLOODYTWITCH4
DoomUnusedStates, Label2, 2, // S_DEADTORSO - S_DEADBOTTOM
HeadsOnAStick, Spawn, 1, // S_HEADSONSTICK
RealGibs, Spawn, 1, // S_GIBS
HeadOnAStick, Spawn, 1, // S_HEADONASTICK
HeadCandles, Spawn, 2, // S_HEADCANDLES - S_HEADCANDLES2
DeadStick, Spawn, 1, // S_DEADSTICK
LiveStick, Spawn, 2, // S_LIVESTICK
Meat2, Spawn, 1, // S_MEAT2
Meat3, Spawn, 1, // S_MEAT3
Meat4, Spawn, 1, // S_MEAT4
Meat5, Spawn, 1, // S_MEAT5
Stalagtite, Spawn, 1, // S_STALAGTITE
TallGreenColumn, Spawn, 1, // S_TALLGRNCOL
ShortGreenColumn, Spawn, 1, // S_SHRTGRNCOL
TallRedColumn, Spawn, 1, // S_TALLREDCOL
ShortRedColumn, Spawn, 1, // S_SHRTREDCOL
Candlestick, Spawn, 1, // S_CANDLESTIK
Candelabra, Spawn, 1, // S_CANDELABRA
SkullColumn, Spawn, 1, // S_SKULLCOL
TorchTree, Spawn, 1, // S_TORCHTREE
BigTree, Spawn, 1, // S_BIGTREE
TechPillar, Spawn, 1, // S_TECHPILLAR
EvilEye, Spawn, 4, // S_EVILEYE - S_EVILEYE4
FloatingSkull, Spawn, 3, // S_FLOATSKULL - S_FLOATSKULL3
HeartColumn, Spawn, 2, // S_HEARTCOL - S_HEARTCOL2
BlueTorch, Spawn, 4, // S_BLUETORCH - S_BLUETORCH4
GreenTorch, Spawn, 4, // S_GREENTORCH - S_GREENTORCH4
RedTorch, Spawn, 4, // S_REDTORCH - S_REDTORCH4
ShortBlueTorch, Spawn, 4, // S_BTORCHSHRT - S_BTORCHSHRT4
ShortGreenTorch, Spawn, 4, // S_GTORCHSHRT - S_GTORCHSHRT4
ShortRedTorch, Spawn, 4, // S_RTORCHSHRT - S_RTORCHSHRT4
HangNoGuts, Spawn, 1, // S_HANGNOGUTS
HangBNoBrain, Spawn, 1, // S_HANGBNOBRAIN
HangTLookingDown, Spawn, 1, // S_HANGTLOOKDN
HangTSkull, Spawn, 1, // S_HANGTSKULL
HangTLookingUp, Spawn, 1, // S_HANGTLOOKUP
HangTNoBrain, Spawn, 1, // S_HANGTNOBRAIN
ColonGibs, Spawn, 1, // S_COLONGIBS
SmallBloodPool, Spawn, 1, // S_SMALLPOOL
BrainStem, Spawn, 1, // S_BRAINSTEM
TechLamp, Spawn, 4, // S_TECHLAMP - S_TECHLAMP4
TechLamp2, Spawn, 4 // S_TECH2LAMP - S_TECH2LAMP4
};
// Sound equivalences. When a patch tries to change a sound, use these sound names.
SoundMap
{
"weapons/pistol",
"weapons/shotgf",
"weapons/shotgr",
"weapons/sshotf",
"weapons/sshoto",
"weapons/sshotc",
"weapons/sshotl",
"weapons/plasmaf",
"weapons/bfgf",
"weapons/sawup",
"weapons/sawidle",
"weapons/sawfull",
"weapons/sawhit",
"weapons/rocklf",
"weapons/bfgx",
"imp/attack",
"imp/shotx",
"plats/pt1_strt",
"plats/pt1_stop",
"doors/dr1_open",
"doors/dr1_clos",
"plats/pt1_mid",
"switches/normbutn",
"switches/exitbutn",
"*pain100",
"demon/pain",
"grunt/pain",
"vile/pain",
"fatso/pain",
"pain/pain",
"misc/gibbed",
"misc/i_pkup",
"misc/w_pkup",
"*land",
"misc/teleport",
"grunt/sight",
"grunt/sight",
"grunt/sight",
"imp/sight",
"imp/sight",
"demon/sight",
"caco/sight",
"baron/sight",
"cyber/sight",
"spider/sight",
"baby/sight",
"knight/sight",
"vile/sight",
"fatso/sight",
"pain/sight",
"skull/melee",
"demon/melee",
"skeleton/melee",
"vile/start",
"imp/melee",
"skeleton/swing",
"*death",
"*xdeath",
"grunt/death",
"grunt/death",
"grunt/death",
"imp/death",
"imp/death",
"demon/death",
"caco/death",
"misc/unused",
"baron/death",
"cyber/death",
"spider/death",
"baby/death",
"vile/death",
"knight/death",
"pain/death",
"skeleton/death",
"grunt/active",
"imp/active",
"demon/active",
"baby/active",
"baby/walk",
"vile/active",
"*grunt",
"world/barrelx",
"*fist",
"cyber/hoof",
"spider/walk",
"weapons/chngun",
"misc/chat2",
"doors/dr2_open",
"doors/dr2_clos",
"misc/spawn",
"vile/firecrkl",
"vile/firestrt",
"misc/p_pkup",
"brain/spit",
"brain/cube",
"brain/sight",
"brain/pain",
"brain/death",
"fatso/attack",
"fatso/death",
"wolfss/sight",
"wolfss/death",
"keen/pain",
"keen/death",
"skeleton/active",
"skeleton/sight",
"skeleton/attack",
"misc/chat"
};
// Names of different actor types, in original Doom 2 order
InfoNames
{
DoomPlayer,
ZombieMan,
ShotgunGuy,
Archvile,
ArchvileFire,
Revenant,
RevenantTracer,
RevenantTracerSmoke,
Fatso,
FatShot,
ChaingunGuy,
DoomImp,
Demon,
Spectre,
Cacodemon,
BaronOfHell,
BaronBall,
HellKnight,
LostSoul,
SpiderMastermind,
Arachnotron,
Cyberdemon,
PainElemental,
WolfensteinSS,
CommanderKeen,
BossBrain,
BossEye,
BossTarget,
SpawnShot,
SpawnFire,
ExplosiveBarrel,
DoomImpBall,
CacodemonBall,
Rocket,
PlasmaBall,
BFGBall,
ArachnotronPlasma,
BulletPuff,
Blood,
TeleportFog,
ItemFog,
TeleportDest,
BFGExtra,
GreenArmor,
BlueArmor,
HealthBonus,
ArmorBonus,
BlueCard,
RedCard,
YellowCard,
YellowSkull,
RedSkull,
BlueSkull,
Stimpack,
Medikit,
Soulsphere,
InvulnerabilitySphere,
Berserk,
BlurSphere,
RadSuit,
Allmap,
Infrared,
Megasphere,
Clip,
ClipBox,
RocketAmmo,
RocketBox,
Cell,
CellPack,
Shell,
ShellBox,
Backpack,
BFG9000,
Chaingun,
Chainsaw,
RocketLauncher,
PlasmaRifle,
Shotgun,
SuperShotgun,
TechLamp,
TechLamp2,
Column,
TallGreenColumn,
ShortGreenColumn,
TallRedColumn,
ShortRedColumn,
SkullColumn,
HeartColumn,
EvilEye,
FloatingSkull,
TorchTree,
BlueTorch,
GreenTorch,
RedTorch,
ShortBlueTorch,
ShortGreenTorch,
ShortRedTorch,
Stalagtite,
TechPillar,
Candlestick,
Candelabra,
BloodyTwitch,
Meat2,
Meat3,
Meat4,
Meat5,
NonsolidMeat2,
NonsolidMeat4,
NonsolidMeat3,
NonsolidMeat5,
NonsolidTwitch,
DeadCacodemon,
DeadMarine,
DeadZombieMan,
DeadDemon,
DeadLostSoul,
DeadDoomImp,
DeadShotgunGuy,
GibbedMarine,
GibbedMarineExtra,
HeadsOnAStick,
Gibs,
HeadOnAStick,
HeadCandles,
DeadStick,
LiveStick,
BigTree,
BurningBarrel,
HangNoGuts,
HangBNoBrain,
HangTLookingDown,
HangTSkull,
HangTLookingUp,
HangTNoBrain,
ColonGibs,
SmallBloodPool,
BrainStem
};
ThingBits
{
0, 0, SPECIAL,
1, 0, SOLID,
2, 0, SHOOTABLE,
3, 0, NOSECTOR,
4, 0, NOBLOCKMAP,
5, 0, AMBUSH,
6, 0, JUSTHIT,
7, 0, JUSTATTACKED,
8, 0, SPAWNCEILING,
9, 0, NOGRAVITY,
10, 0, DROPOFF,
11, 0, PICKUP,
12, 0, NOCLIP,
14, 0, FLOAT,
15, 0, TELEPORT,
16, 0, MISSILE,
17, 0, DROPPED,
18, 0, SHADOW,
19, 0, NOBLOOD,
20, 0, CORPSE,
21, 0, INFLOAT,
22, 0, COUNTKILL,
23, 0, COUNTITEM,
24, 0, SKULLFLY,
25, 0, NOTDMATCH,
26, 0, TRANSLATION1,
26, 0, TRANSLATION, // BOOM compatibility
27, 0, TRANSLATION2,
27, 0, UNUSED1, // BOOM compatibility
28, 0, UNUSED2, // BOOM compatibility
29, 0, UNUSED3, // BOOM compatibility
30, 0, UNUSED4, // BOOM compatibility
2, 2, TRANSLUCENT, // BOOM compatibility?
30, 0, STEALTH,
1, 2, TRANSLUC25,
2, 2, TRANSLUC50,
3, 2, TRANSLUC75,
// Names for flags2
0, 1, LOGRAV,
1, 1, WINDTHRUST,
2, 1, FLOORBOUNCE,
3, 1, BLASTED,
4, 1, FLY,
5, 1, FLOORCLIP,
6, 1, SPAWNFLOAT,
7, 1, NOTELEPORT,
8, 1, RIP,
9, 1, PUSHABLE,
10, 1, CANSLIDE, // Avoid conflict with SLIDE from BOOM
11, 1, ONMOBJ,
12, 1, PASSMOBJ,
13, 1, CANNOTPUSH,
14, 1, THRUGHOST,
15, 1, BOSS,
16, 1, FIREDAMAGE,
17, 1, NODMGTHRUST,
18, 1, TELESTOMP,
19, 1, FLOATBOB,
4, 2, DONTDRAW,
21, 1, IMPACT,
22, 1, PUSHWALL,
23, 1, MCROSS,
24, 1, PCROSS,
25, 1, CANTLEAVEFLOORPIC,
26, 1, NONSHOOTABLE,
27, 1, INVULNERABLE,
28, 1, DORMANT,
29, 1, ICEDAMAGE,
30, 1, SEEKERMISSILE,
31, 1, REFLECTIVE
};
// RenderStyles, should match those in actor.h
RenderStyles
{
0, STYLE_None,
1, STYLE_Normal,
2, STYLE_Fuzzy,
3, STYLE_SoulTrans,
4, STYLE_OptFuzzy,
8, STYLE_Shaded,
6, STYLE_Translucent,
7, STYLE_Add
};
AmmoNames
{
Clip,
Shell,
Cell,
RocketAmmo,
GoldWandAmmo,
NULL,
BlasterAmmo,
SkullRodAmmo,
PhoenixRodAmmo,
MaceAmmo,
Mana1,
Mana2
};
WeaponNames
{
Fist,
Pistol,
Shotgun,
Chaingun,
RocketLauncher,
PlasmaRifle,
BFG9000,
Chainsaw,
SuperShotgun
};

View file

@ -1,5 +1,32 @@
// MAPINFO for Chex Quest
gameinfo
{
titlepage = "TITLEPIC"
creditpage = "CREDIT", "HELP1"
titlemusic = "$MUSIC_INTRO"
titletime = 5
advisorytime = 0
pagetime = 5
chatsound = "misc/chat2"
finalemusic = "$MUSIC_VICTOR"
finaleflat = "FLOOR4_8"
finalepage = "HELP2", "VICTORY2", "ENDPIC"
infopage = "HELP1", "CREDIT"
quitsound = "menu/quit1"
borderflat = "FLOOR7_2"
border = DoomBorder
telefogheight = 0
defkickback = 100
skyflatname = "F_SKY1"
translator = "xlat/doom.txt"
defaultbloodcolor = "3f 7d 39"
defaultbloodparticlecolor = "5f af 57"
backpacktype = "ZorchPack"
statusbar = "sbarinfo/doom.txt"
intermissionmusic = "$MUSIC_INTER"
}
skill baby
{
AutoUseHealth

View file

@ -0,0 +1,10 @@
include "mapinfo/chex.txt"
// Chex Quest 3 gameinfo
gameinfo
{
creditpage = "ENDPIC", "VICTORY2"
finaleflat = "ENDPIC01"
finalepage = "CREDIT", "CREDIT", "ENDPIC"
}

View file

@ -1,4 +1,20 @@
// MAPINFO for Doom 1 (Shareware, Registered, and Retail)
include "mapinfo/doomcommon.txt"
gameinfo
{
creditpage = "CREDIT", "HELP2"
titlemusic = "$MUSIC_INTRO"
titletime = 5
finalemusic = "$MUSIC_VICTOR"
finaleflat = "FLOOR4_8"
finalepage = "HELP2", "VICTORY2", "ENDPIC"
infopage = "HELP1", "HELP2"
quitsound = "menu/quit1"
borderflat = "FLOOR7_2"
drawreadthis = true
intermissionmusic = "$MUSIC_INTER"
}
clearepisodes
episode e1m1

View file

@ -1,4 +1,5 @@
// MAPINFO for Doom 2
include "mapinfo/doomcommon.txt"
clearepisodes
episode map01

View file

@ -1,3 +1,32 @@
gameinfo
{
titlepage = "TITLEPIC"
creditpage = "CREDIT"
titlemusic = "$MUSIC_DM2TTL"
titletime = 11
advisorytime = 0
pagetime = 5
chatsound = "misc/chat"
finalemusic = "$MUSIC_READ_M"
finaleflat = "SLIME16"
finalepage = "CREDIT"
infopage = "HELP", "CREDIT"
quitsound = "menu/quit2"
borderflat = "GRNROCK"
border = DoomBorder
telefogheight = 0
defkickback = 100
skyflatname = "F_SKY1"
translator = "xlat/doom.txt"
mapinfo = "mapinfo/doom2.txt"
defaultbloodcolor = "68 00 00"
defaultbloodparticlecolor = "ff 00 00"
backpacktype = "Backpack"
statusbar = "sbarinfo/doom.txt"
intermissionmusic = "$MUSIC_DM2INT"
}
skill baby
{
AutoUseHealth

View file

@ -1,5 +1,32 @@
// MAPINFO for Heretic (Shareware and Retail)
gameinfo
{
titlepage = "TITLE"
creditpage = "CREDIT"
titlemusic = "MUS_TITL"
titletime = 8
advisorytime = 6
pagetime = 5
chatsound = "misc/chat"
finalemusic = "MUS_CPTD"
finaleflat = "FLOOR25"
finalepage = "CREDIT"
infopage = "HELP1", "HELP2", "CREDIT"
quitsound = ""
borderflat = "FLAT513"
border = HereticBorder
telefogheight = 32
defkickback = 150
skyflatname = "F_SKY1"
translator = "xlat/heretic.txt"
defaultbloodcolor = "68 00 00"
defaultbloodparticlecolor = "ff 00 00"
backpacktype = "BagOfHolding"
statusbar = ""
intermissionmusic = "mus_intr"
}
skill baby
{
AutoUseHealth

View file

@ -0,0 +1,8 @@
include "mapinfo/heretic.txt"
gameinfo
{
finalepage = "ORDER"
infopage = "ORDER", "HELP1", "HELP2", "CREDIT"
}

View file

@ -2,6 +2,34 @@
// Most of the MAPINFO is still in hexen.wad.
gameinfo
{
noloopfinalemusic = true
titlepage = "TITLE"
creditpage = "CREDIT"
titlemusic = "HEXEN"
titletime = 8
advisorytime = 6
pagetime = 5
chatsound = "Chat"
finalemusic = "hub"
finaleflat = "-NOFLAT-"
finalepage = "CREDIT"
infopage = "HELP1", "HELP2", "CREDIT"
quitsound = ""
borderflat = "F_022"
border = HereticBorder
telefogheight = 32
defkickback = 150
skyflatname = "F_SKY"
translator = "xlat/heretic.txt" // not really correct but this was used before.
defaultbloodcolor = "68 00 00"
defaultbloodparticlecolor = "ff 00 00"
backpacktype = "BagOfHolding" // Hexen doesn't have a backpack so use Heretic's.
statusbar = ""
intermissionmusic = "hub"
}
skill baby
{
AutoUseHealth

View file

@ -1,7 +1,8 @@
// MAPINFO for Plutonia. Exactly the same as Doom 2, except it
// has different map names and cluster messages.
include "mapinfo/doomcommon.txt"
clearepisodes
episode map01
{

View file

@ -1,5 +1,32 @@
// MAPINFO for Strife (full version and teaser)
gameinfo
{
titlepage = "TITLEPIC"
creditpage = "CREDIT"
titlemusic = "D_LOGO"
titletime = 8
advisorytime = 0
pagetime = 5
chatsound = "misc/chat"
finalemusic = "d_intro"
finaleflat = "-NOFLAT-"
finalepage = "CREDIT"
infopage = "HELP1", "HELP2", "HELP3"
quitsound = ""
borderflat = "F_PAVE01"
border = StrifeBorder
telefogheight = 0
defkickback = 150
skyflatname = "F_SKY001"
translator = "xlat/strife.txt"
defaultbloodcolor = "68 00 00"
defaultbloodparticlecolor = "ff 00 00"
backpacktype = "AmmoSatchel"
statusbar = ""
intermissionmusic = "d_slide"
}
skill baby
{
AutoUseHealth

View file

@ -1,7 +1,8 @@
// MAPINFO for TNT. Exactly the same as Doom 2, except it
// has different map names and cluster messages.
include "mapinfo/doomcommon.txt"
clearepisodes
episode map01
{

View file

@ -0,0 +1,10 @@
include "mapinfo/doom1.txt"
gameinfo
{
creditpage = "CREDIT"
chatsound = "misc/chat2"
finalepage = "CREDIT", "VICTORY2", "ENDPIC"
infopage = "HELP1", "CREDIT"
}