Merge commit '2719ce86dc07c9f7b1ad6d61a9a49c974896abf2' into scripting

Conflicts:
	src/info.h
	src/thingdef/thingdef_codeptr.cpp

(until right before the main work for multiple tags.)
This commit is contained in:
Christoph Oelckers 2015-04-28 13:32:50 +02:00
commit 8447990889
93 changed files with 1873 additions and 1581 deletions

View file

@ -43,158 +43,11 @@
#include "configfile.h"
#include "i_system.h"
#include "d_event.h"
#include "w_wad.h"
#include <math.h>
#include <stdlib.h>
/* Default keybindings for Doom (and all other games)
*/
static const FBinding DefBindings[] =
{
{ "`", "toggleconsole" },
{ "1", "slot 1" },
{ "2", "slot 2" },
{ "3", "slot 3" },
{ "4", "slot 4" },
{ "5", "slot 5" },
{ "6", "slot 6" },
{ "7", "slot 7" },
{ "8", "slot 8" },
{ "9", "slot 9" },
{ "0", "slot 0" },
{ "[", "invprev" },
{ "]", "invnext" },
{ "mwheelleft", "invprev" },
{ "mwheelright", "invnext" },
{ "enter", "invuse" },
{ "-", "sizedown" },
{ "=", "sizeup" },
{ "ctrl", "+attack" },
{ "alt", "+strafe" },
{ "shift", "+speed" },
{ "space", "+use" },
{ "rightarrow", "+right" },
{ "leftarrow", "+left" },
{ "uparrow", "+forward" },
{ "downarrow", "+back" },
{ ",", "+moveleft" },
{ ".", "+moveright" },
{ "mouse1", "+attack" },
{ "mouse2", "+strafe" },
{ "mouse3", "+forward" },
{ "mouse4", "+speed" },
{ "capslock", "toggle cl_run" },
{ "f1", "menu_help" },
{ "f2", "menu_save" },
{ "f3", "menu_load" },
{ "f4", "menu_options" },
{ "f5", "menu_display" },
{ "f6", "quicksave" },
{ "f7", "menu_endgame" },
{ "f8", "togglemessages" },
{ "f9", "quickload" },
{ "f11", "bumpgamma" },
{ "f10", "menu_quit" },
{ "tab", "togglemap" },
{ "pause", "pause" },
{ "sysrq", "screenshot" },
{ "t", "messagemode" },
{ "\\", "+showscores" },
{ "f12", "spynext" },
{ "mwheeldown", "weapnext" },
{ "mwheelup", "weapprev" },
// Generic joystick buttons
{ "joy1", "+attack" },
{ "joy2", "+strafe" },
{ "joy3", "+speed" },
{ "joy4", "+use" },
// Xbox 360 / PS2 controllers
{ "pad_a", "+use" },
{ "pad_y", "+jump" },
{ "rtrigger", "+attack" },
{ "ltrigger", "+altattack" },
{ "lshoulder", "weapprev" },
{ "rshoulder", "weapnext" },
{ "dpadleft", "invprev" },
{ "dpadright", "invnext" },
{ "dpaddown", "invuse" },
{ "dpadup", "togglemap" },
{ "pad_start", "pause" },
{ "pad_back", "menu_main" },
{ "lthumb", "crouch" },
{ NULL, NULL }
};
static const FBinding DefRavenBindings[] =
{
{ "pgup", "+moveup" },
{ "ins", "+movedown" },
{ "home", "land" },
{ "pgdn", "+lookup" },
{ "del", "+lookdown" },
{ "end", "centerview" },
{ NULL, NULL }
};
static const FBinding DefHereticBindings[] =
{
{ "backspace", "use ArtiTomeOfPower" },
{ NULL, NULL }
};
static const FBinding DefHexenBindings[] =
{
{ "/", "+jump" },
{ "backspace", "invuseall" },
{ "\\", "use ArtiHealth" },
{ "0", "useflechette" },
{ "9", "use ArtiBlastRadius" },
{ "8", "use ArtiTeleport" },
{ "7", "use ArtiTeleportOther" },
{ "6", "use ArtiPork" },
{ "5", "use ArtiInvulnerability2" },
{ "scroll", "+showscores" },
{ NULL, NULL }
};
static const FBinding DefStrifeBindings[] =
{
{ "a", "+jump" },
{ "w", "showpop 1" },
{ "backspace", "invdrop" },
{ "z", "showpop 3" },
{ "k", "showpop 2" },
{ "q", "invquery" },
{ NULL, NULL }
// not done
// h - use health
};
static const FBinding DefAutomapBindings[] =
{
{ "f", "am_togglefollow" },
{ "g", "am_togglegrid" },
{ "p", "am_toggletexture" },
{ "m", "am_setmark" },
{ "c", "am_clearmarks" },
{ "0", "am_gobig" },
{ "rightarrow", "+am_panright" },
{ "leftarrow", "+am_panleft" },
{ "uparrow", "+am_panup" },
{ "downarrow", "+am_pandown" },
{ "-", "+am_zoomout" },
{ "=", "+am_zoomin" },
{ "kp-", "+am_zoomout" },
{ "kp+", "+am_zoomin" },
{ "mwheelup", "am_zoom 1.2" },
{ "mwheeldown", "am_zoom -1.2" },
{ NULL, NULL }
};
const char *KeyNames[NUM_KEYS] =
{
// This array is dependant on the particular keyboard input
@ -452,21 +305,6 @@ void FKeyBindings::DoBind (const char *key, const char *bind)
//
//=============================================================================
void FKeyBindings::SetBinds(const FBinding *binds)
{
while (binds->Key)
{
DoBind (binds->Key, binds->Bind);
binds++;
}
}
//=============================================================================
//
//
//
//=============================================================================
void FKeyBindings::UnbindAll ()
{
for (int i = 0; i < NUM_KEYS; ++i)
@ -785,29 +623,37 @@ CCMD (rebind)
void C_BindDefaults ()
{
Bindings.SetBinds (DefBindings);
int lump, lastlump = 0;
if (gameinfo.gametype & (GAME_Raven|GAME_Strife))
while ((lump = Wads.FindLump("DEFBINDS", &lastlump)) != -1)
{
Bindings.SetBinds (DefRavenBindings);
}
FScanner sc(lump);
if (gameinfo.gametype == GAME_Heretic)
{
Bindings.SetBinds (DefHereticBindings);
}
while (sc.GetString())
{
FKeyBindings *dest = &Bindings;
int key;
if (gameinfo.gametype == GAME_Hexen)
{
Bindings.SetBinds (DefHexenBindings);
// bind destination is optional and is the same as the console command
if (sc.Compare("bind"))
{
sc.MustGetString();
}
else if (sc.Compare("doublebind"))
{
dest = &DoubleBindings;
sc.MustGetString();
}
else if (sc.Compare("mapbind"))
{
dest = &AutomapBindings;
sc.MustGetString();
}
key = GetConfigKeyFromName(sc.String);
sc.MustGetString();
dest->SetBind(key, sc.String);
}
}
if (gameinfo.gametype == GAME_Strife)
{
Bindings.SetBinds (DefStrifeBindings);
}
AutomapBindings.SetBinds(DefAutomapBindings);
}
CCMD(binddefaults)

View file

@ -42,19 +42,12 @@ class FCommandLine;
void C_NameKeys (char *str, int first, int second);
struct FBinding
{
const char *Key;
const char *Bind;
};
class FKeyBindings
{
FString Binds[NUM_KEYS];
public:
void PerformBind(FCommandLine &argv, const char *msg);
void SetBinds(const FBinding *binds);
bool DoKey(event_t *ev);
void ArchiveBindings(FConfigFile *F, const char *matchcmd = NULL);
int GetKeysForCommand (const char *cmd, int *first, int *second);

View file

@ -448,11 +448,10 @@ CCMD (exec)
for (int i = 1; i < argv.argc(); ++i)
{
switch (C_ExecFile (argv[i], gamestate == GS_STARTUP))
if (!C_ExecFile(argv[i]))
{
case 1: Printf ("Could not open \"%s\"\n", argv[1]); break;
case 2: Printf ("Error parsing \"%s\"\n", argv[1]); break;
default: break;
Printf ("Could not exec \"%s\"\n", argv[i]);
break;
}
}
}

View file

@ -185,9 +185,6 @@ static const char *KeyConfCommands[] =
"clearplayerclasses"
};
static TArray<FString> StoredStartupSets;
static bool RunningStoredStartups;
// CODE --------------------------------------------------------------------
IMPLEMENT_CLASS (DWaitingCommand)
@ -540,18 +537,6 @@ void ResetButtonStates ()
}
}
void C_ExecStoredSets()
{
assert(!RunningStoredStartups);
RunningStoredStartups = true;
for (unsigned i = 0; i < StoredStartupSets.Size(); ++i)
{
C_DoCommand(StoredStartupSets[i]);
}
StoredStartupSets.Clear();
RunningStoredStartups = false;
}
void C_DoCommand (const char *cmd, int keynum)
{
FConsoleCommand *com;
@ -627,22 +612,7 @@ void C_DoCommand (const char *cmd, int keynum)
if ( (com = FindNameInHashTable (Commands, beg, len)) )
{
if (gamestate == GS_STARTUP && !RunningStoredStartups &&
len == 3 && strnicmp(beg, "set", 3) == 0)
{
// Save setting of unknown cvars for later, in case a loaded wad has a
// CVARINFO that defines it.
FCommandLine args(beg);
if (args.argc() > 1 && FindCVar(args[1], NULL) == NULL)
{
StoredStartupSets.Push(beg);
}
else
{
com->Run(args, players[consoleplayer].mo, keynum);
}
}
else if (gamestate != GS_STARTUP || ParsingKeyConf ||
if (gamestate != GS_STARTUP || ParsingKeyConf ||
(len == 3 && strnicmp (beg, "set", 3) == 0) ||
(len == 7 && strnicmp (beg, "logfile", 7) == 0) ||
(len == 9 && strnicmp (beg, "unbindall", 9) == 0) ||
@ -687,15 +657,7 @@ void C_DoCommand (const char *cmd, int keynum)
}
else
{ // We don't know how to handle this command
if (gamestate == GS_STARTUP && !RunningStoredStartups)
{
// Save it for later, in case a CVARINFO defines it.
StoredStartupSets.Push(beg);
}
else
{
Printf ("Unknown command \"%.*s\"\n", (int)len, beg);
}
Printf ("Unknown command \"%.*s\"\n", (int)len, beg);
}
}
}
@ -1368,7 +1330,7 @@ CCMD (key)
// Execute any console commands specified on the command line.
// These all begin with '+' as opposed to '-'.
void C_ExecCmdLineParams ()
FExecList *C_ParseCmdLineParams(FExecList *exec)
{
for (int currArg = 1; currArg < Args->NumArgs(); )
{
@ -1389,10 +1351,15 @@ void C_ExecCmdLineParams ()
cmdString = BuildString (cmdlen, Args->GetArgList (argstart));
if (!cmdString.IsEmpty())
{
C_DoCommand (&cmdString[1]);
if (exec == NULL)
{
exec = new FExecList;
}
exec->AddCommand(&cmdString[1]);
}
}
}
return exec;
}
bool FConsoleCommand::IsAlias ()
@ -1469,28 +1436,60 @@ void FConsoleAlias::SafeDelete ()
}
}
static BYTE PullinBad = 2;
static const char *PullinFile;
extern TArray<FString> allwads;
void FExecList::AddCommand(const char *cmd, const char *file)
{
// Pullins are special and need to be separated from general commands.
// They also turned out to be a really bad idea, since they make things
// more complicated. :(
if (file != NULL && strnicmp(cmd, "pullin", 6) == 0 && isspace(cmd[6]))
{
FCommandLine line(cmd);
C_SearchForPullins(this, file, line);
}
// Recursive exec: Parse this file now.
else if (strnicmp(cmd, "exec", 4) == 0 && isspace(cmd[4]))
{
FCommandLine argv(cmd);
for (int i = 1; i < argv.argc(); ++i)
{
C_ParseExecFile(argv[i], this);
}
}
else
{
Commands.Push(cmd);
}
}
int C_ExecFile (const char *file, bool usePullin)
void FExecList::ExecCommands() const
{
for (unsigned i = 0; i < Commands.Size(); ++i)
{
AddCommandString(Commands[i].LockBuffer());
Commands[i].UnlockBuffer();
}
}
void FExecList::AddPullins(TArray<FString> &wads) const
{
for (unsigned i = 0; i < Pullins.Size(); ++i)
{
D_AddFile(wads, Pullins[i]);
}
}
FExecList *C_ParseExecFile(const char *file, FExecList *exec)
{
FILE *f;
char cmd[4096];
int retval = 0;
BYTE pullinSaved = PullinBad;
const char *fileSaved = PullinFile;
if ( (f = fopen (file, "r")) )
{
PullinBad = 1-usePullin;
PullinFile = file;
while (fgets (cmd, 4095, f))
while (fgets(cmd, countof(cmd)-1, f))
{
// Comments begin with //
char *stop = cmd + strlen (cmd) - 1;
char *stop = cmd + strlen(cmd) - 1;
char *comment = cmd;
int inQuote = 0;
@ -1517,88 +1516,78 @@ int C_ExecFile (const char *file, bool usePullin)
{ // Comment in middle of line
*comment = 0;
}
AddCommandString (cmd);
if (exec == NULL)
{
exec = new FExecList;
}
exec->AddCommand(cmd, file);
}
if (!feof (f))
if (!feof(f))
{
retval = 2;
Printf("Error parsing \"%s\"\n", file);
}
fclose (f);
fclose(f);
}
else
{
retval = 1;
Printf ("Could not open \"%s\"\n", file);
}
return exec;
}
bool C_ExecFile (const char *file)
{
FExecList *exec = C_ParseExecFile(file, NULL);
if (exec != NULL)
{
exec->ExecCommands();
if (exec->Pullins.Size() > 0)
{
Printf(TEXTCOLOR_BOLD "Notice: Pullin files were ignored.\n");
}
delete exec;
}
return exec != NULL;
}
void C_SearchForPullins(FExecList *exec, const char *file, FCommandLine &argv)
{
const char *lastSlash;
assert(exec != NULL);
assert(file != NULL);
#ifdef __unix__
lastSlash = strrchr(file, '/');
#else
const char *lastSlash1, *lastSlash2;
lastSlash1 = strrchr(file, '/');
lastSlash2 = strrchr(file, '\\');
lastSlash = MAX(lastSlash1, lastSlash2);
#endif
for (int i = 1; i < argv.argc(); ++i)
{
// Try looking for the wad in the same directory as the .cfg
// before looking for it in the current directory.
if (lastSlash != NULL)
{
FString path(file, (lastSlash - file) + 1);
path += argv[i];
if (FileExists(path))
{
exec->Pullins.Push(path);
continue;
}
}
exec->Pullins.Push(argv[i]);
}
PullinBad = pullinSaved;
PullinFile = fileSaved;
return retval;
}
CCMD (pullin)
{
if (PullinBad == 2)
{
Printf ("This command is only valid from .cfg\n"
"files and only when used at startup.\n");
}
else if (argv.argc() > 1)
{
const char *lastSlash;
#ifdef __unix__
lastSlash = strrchr (PullinFile, '/');
#else
const char *lastSlash1, *lastSlash2;
lastSlash1 = strrchr (PullinFile, '/');
lastSlash2 = strrchr (PullinFile, '\\');
lastSlash = MAX (lastSlash1, lastSlash2);
#endif
if (PullinBad)
{
Printf ("Not loading:");
}
for (int i = 1; i < argv.argc(); ++i)
{
if (PullinBad)
{
Printf (" %s", argv[i]);
}
else
{
// Try looking for the wad in the same directory as the .cfg
// before looking for it in the current directory.
char *path = argv[i];
if (lastSlash != NULL)
{
size_t pathlen = lastSlash - PullinFile + strlen (argv[i]) + 2;
path = new char[pathlen];
strncpy (path, PullinFile, (lastSlash - PullinFile) + 1);
strcpy (path + (lastSlash - PullinFile) + 1, argv[i]);
if (!FileExists (path))
{
delete[] path;
path = argv[i];
}
else
{
FixPathSeperator (path);
}
}
D_AddFile (allwads, path);
if (path != argv[i])
{
delete[] path;
}
}
}
if (PullinBad)
{
Printf ("\n");
}
}
// Actual handling for pullin is now completely special-cased above
Printf (TEXTCOLOR_BOLD "Pullin" TEXTCOLOR_NORMAL " is only valid from .cfg\n"
"files and only when used at startup.\n");
}

View file

@ -39,31 +39,6 @@
class FConfigFile;
class APlayerPawn;
extern bool CheckCheatmode (bool printmsg = true);
void C_ExecCmdLineParams ();
void C_ExecStoredSets();
// Add commands to the console as if they were typed in. Can handle wait
// and semicolon-separated commands. This function may modify the source
// string, but the string will be restored to its original state before
// returning. Therefore, commands passed must not be in read-only memory.
void AddCommandString (char *text, int keynum=0);
// Process a single console command. Does not handle wait.
void C_DoCommand (const char *cmd, int keynum=0);
int C_ExecFile (const char *cmd, bool usePullin);
// Write out alias commands to a file for all current aliases.
void C_ArchiveAliases (FConfigFile *f);
void C_SetAlias (const char *name, const char *cmd);
void C_ClearAliases ();
// build a single string out of multiple strings
FString BuildString (int argc, FString *argv);
// Class that can parse command lines
class FCommandLine
{
@ -83,6 +58,44 @@ private:
bool noescapes;
};
// Contains the contents of an exec'ed file
struct FExecList
{
TArray<FString> Commands;
TArray<FString> Pullins;
void AddCommand(const char *cmd, const char *file = NULL);
void ExecCommands() const;
void AddPullins(TArray<FString> &wads) const;
};
extern bool CheckCheatmode (bool printmsg = true);
FExecList *C_ParseCmdLineParams(FExecList *exec);
// Add commands to the console as if they were typed in. Can handle wait
// and semicolon-separated commands. This function may modify the source
// string, but the string will be restored to its original state before
// returning. Therefore, commands passed must not be in read-only memory.
void AddCommandString (char *text, int keynum=0);
// Process a single console command. Does not handle wait.
void C_DoCommand (const char *cmd, int keynum=0);
FExecList *C_ParseExecFile(const char *file, FExecList *source);
void C_SearchForPullins(FExecList *exec, const char *file, class FCommandLine &args);
bool C_ExecFile(const char *file);
// Write out alias commands to a file for all current aliases.
void C_ArchiveAliases (FConfigFile *f);
void C_SetAlias (const char *name, const char *cmd);
void C_ClearAliases ();
// build a single string out of multiple strings
FString BuildString (int argc, FString *argv);
typedef void (*CCmdRun) (FCommandLine &argv, APlayerPawn *instigator, int key);
class FConsoleCommand

View file

@ -551,7 +551,8 @@ void SetCompatibilityParams()
{
if ((unsigned)CompatParams[i + 1] < (unsigned)numsectors)
{
sectors[CompatParams[i + 1]].tag = CompatParams[i + 2];
sectors[CompatParams[i + 1]].ClearTags();
sectors[CompatParams[i + 1]].SetMainTag(CompatParams[i + 2]);
}
i += 3;
break;

View file

@ -66,15 +66,13 @@ FConfigFile::FConfigFile ()
//
//====================================================================
FConfigFile::FConfigFile (const char *pathname,
void (*nosechandler)(const char *pathname, FConfigFile *config, void *userdata),
void *userdata)
FConfigFile::FConfigFile (const char *pathname)
{
Sections = CurrentSection = NULL;
LastSectionPtr = &Sections;
CurrentEntry = NULL;
ChangePathName (pathname);
LoadConfigFile (nosechandler, userdata);
LoadConfigFile ();
OkayToWrite = true;
FileExisted = true;
}
@ -118,8 +116,7 @@ FConfigFile::~FConfigFile ()
delete[] (char *)entry;
entry = nextentry;
}
section->~FConfigSection();
delete[] (char *)section;
delete section;
section = nextsection;
}
}
@ -140,7 +137,7 @@ FConfigFile &FConfigFile::operator = (const FConfigFile &other)
while (fromsection != NULL)
{
fromentry = fromsection->RootEntry;
tosection = NewConfigSection (fromsection->Name);
tosection = NewConfigSection (fromsection->SectionName);
while (fromentry != NULL)
{
NewConfigEntry (tosection, fromentry->Key, fromentry->Value);
@ -311,7 +308,7 @@ const char *FConfigFile::GetCurrentSection () const
{
if (CurrentSection != NULL)
{
return CurrentSection->Name;
return CurrentSection->SectionName.GetChars();
}
return NULL;
}
@ -508,13 +505,29 @@ FConfigFile::FConfigSection *FConfigFile::FindSection (const char *name) const
{
FConfigSection *section = Sections;
while (section != NULL && stricmp (section->Name, name) != 0)
while (section != NULL && section->SectionName.CompareNoCase(name) != 0)
{
section = section->Next;
}
return section;
}
//====================================================================
//
// FConfigFile :: RenameSection
//
//====================================================================
void FConfigFile::RenameSection (const char *oldname, const char *newname) const
{
FConfigSection *section = FindSection(oldname);
if (section != NULL)
{
section->SectionName = newname;
}
}
//====================================================================
//
// FConfigFile :: FindEntry
@ -542,19 +555,15 @@ FConfigFile::FConfigEntry *FConfigFile::FindEntry (
FConfigFile::FConfigSection *FConfigFile::NewConfigSection (const char *name)
{
FConfigSection *section;
char *memblock;
section = FindSection (name);
if (section == NULL)
{
size_t namelen = strlen (name);
memblock = new char[sizeof(*section)+namelen];
section = ::new(memblock) FConfigSection;
section = new FConfigSection;
section->RootEntry = NULL;
section->LastEntryPtr = &section->RootEntry;
section->Next = NULL;
memcpy (section->Name, name, namelen);
section->Name[namelen] = 0;
section->SectionName = name;
*LastSectionPtr = section;
LastSectionPtr = &section->Next;
}
@ -591,7 +600,7 @@ FConfigFile::FConfigEntry *FConfigFile::NewConfigEntry (
//
//====================================================================
void FConfigFile::LoadConfigFile (void (*nosechandler)(const char *pathname, FConfigFile *config, void *userdata), void *userdata)
void FConfigFile::LoadConfigFile ()
{
FILE *file = fopen (PathName, "r");
bool succ;
@ -605,14 +614,6 @@ void FConfigFile::LoadConfigFile (void (*nosechandler)(const char *pathname, FCo
succ = ReadConfig (file);
fclose (file);
FileExisted = succ;
if (!succ)
{ // First valid line did not define a section
if (nosechandler != NULL)
{
nosechandler (PathName, this, userdata);
}
}
}
//====================================================================
@ -787,7 +788,7 @@ bool FConfigFile::WriteConfigFile () const
{
fputs (section->Note.GetChars(), file);
}
fprintf (file, "[%s]\n", section->Name);
fprintf (file, "[%s]\n", section->SectionName.GetChars());
while (entry != NULL)
{
if (strpbrk(entry->Value, "\r\n") == NULL)

View file

@ -41,8 +41,7 @@ class FConfigFile
{
public:
FConfigFile ();
FConfigFile (const char *pathname,
void (*nosechandler)(const char *pathname, FConfigFile *config, void *userdata)=0, void *userdata=NULL);
FConfigFile (const char *pathname);
FConfigFile (const FConfigFile &other);
virtual ~FConfigFile ();
@ -70,7 +69,7 @@ public:
const char *GetPathName () const { return PathName.GetChars(); }
void ChangePathName (const char *path);
void LoadConfigFile (void (*nosechandler)(const char *pathname, FConfigFile *config, void *userdata), void *userdata);
void LoadConfigFile ();
bool WriteConfigFile () const;
protected:
@ -79,6 +78,7 @@ protected:
virtual char *ReadLine (char *string, int n, void *file) const;
bool ReadConfig (void *file);
static const char *GenerateEndTag(const char *value);
void RenameSection(const char *oldname, const char *newname) const;
bool OkayToWrite;
bool FileExisted;
@ -94,11 +94,12 @@ private:
};
struct FConfigSection
{
FString SectionName;
FConfigEntry *RootEntry;
FConfigEntry **LastEntryPtr;
FConfigSection *Next;
FString Note;
char Name[1]; // + length of name
//char Name[1]; // + length of name
};
FConfigSection *Sections;

View file

@ -138,12 +138,6 @@ void FIWadManager::ParseIWadInfo(const char *fn, const char *data, int datasize)
sc.MustGetString();
iwad->Autoname = sc.String;
}
else if (sc.Compare("Group"))
{
sc.MustGetStringName("=");
sc.MustGetString();
iwad->Group = sc.String;
}
else if (sc.Compare("Config"))
{
sc.MustGetStringName("=");
@ -225,6 +219,11 @@ void FIWadManager::ParseIWadInfo(const char *fn, const char *data, int datasize)
sc.ScriptError("Unknown keyword '%s'", sc.String);
}
}
if (iwad->MapInfo.IsEmpty())
{
// We must at least load the minimum defaults to allow the engine to run.
iwad->MapInfo = "mapinfo/mindefaults.txt";
}
}
else if (sc.Compare("NAMES"))
{
@ -393,7 +392,6 @@ int FIWadManager::IdentifyVersion (TArray<FString> &wadfiles, const char *iwad,
bool iwadparmfound = false;
FString custwad;
ParseIWadInfos(zdoom_wad);
wads.Resize(mIWadNames.Size());
foundwads.Resize(mIWads.Size());
memset(&foundwads[0], 0, foundwads.Size() * sizeof(foundwads[0]));

View file

@ -1657,7 +1657,7 @@ static const char *BaseFileSearch (const char *file, const char *ext, bool lookf
return wad;
}
if (GameConfig->SetSection ("FileSearch.Directories"))
if (GameConfig != NULL && GameConfig->SetSection ("FileSearch.Directories"))
{
const char *key;
const char *value;
@ -1723,12 +1723,13 @@ bool ConsiderPatches (const char *arg)
//
//==========================================================================
void D_MultiExec (DArgs *list, bool usePullin)
FExecList *D_MultiExec (DArgs *list, FExecList *exec)
{
for (int i = 0; i < list->NumArgs(); ++i)
{
C_ExecFile (list->GetArg (i), usePullin);
exec = C_ParseExecFile(list->GetArg(i), exec);
}
return exec;
}
static void GetCmdLineFiles(TArray<FString> &wadfiles)
@ -1998,10 +1999,6 @@ static void D_DoomInit()
}
FRandom::StaticClearRandom ();
Printf ("M_LoadDefaults: Load system defaults.\n");
M_LoadDefaults (); // load before initing other systems
}
//==========================================================================
@ -2010,10 +2007,9 @@ static void D_DoomInit()
//
//==========================================================================
static void AddAutoloadFiles(const char *group, const char *autoname)
static void AddAutoloadFiles(const char *autoname)
{
LumpFilterGroup = group;
LumpFilterIWAD = autoname;
LumpFilterIWAD.Format("%s.", autoname); // The '.' is appened to simplify parsing the string
if (!(gameinfo.flags & GI_SHAREWARE) && !Args->CheckParm("-noautoload"))
{
@ -2045,25 +2041,14 @@ static void AddAutoloadFiles(const char *group, const char *autoname)
// Add common (global) wads
D_AddConfigWads (allwads, "Global.Autoload");
// Add game-specific wads
file = gameinfo.ConfigName;
file += ".Autoload";
D_AddConfigWads (allwads, file);
long len;
int lastpos = -1;
// Add group-specific wads
if (group != NULL)
{
file = group;
file += ".Autoload";
D_AddConfigWads(allwads, file);
}
// Add IWAD-specific wads
if (autoname != NULL)
while ((len = LumpFilterIWAD.IndexOf('.', lastpos+1)) > 0)
{
file = autoname;
file += ".Autoload";
file = LumpFilterIWAD.Left(len) + ".Autoload";
D_AddConfigWads(allwads, file);
lastpos = len;
}
}
}
@ -2220,7 +2205,8 @@ void D_DoomMain (void)
DArgs *execFiles;
TArray<FString> pwads;
FString *args;
int argcount;
int argcount;
FIWadManager *iwad_man;
// +logfile gets checked too late to catch the full startup log in the logfile so do some extra check for it here.
FString logfile = Args->TakeValue("+logfile");
@ -2260,6 +2246,11 @@ void D_DoomMain (void)
}
FString basewad = wad;
iwad_man = new FIWadManager;
iwad_man->ParseIWadInfos(basewad);
Printf ("M_LoadDefaults: Load system defaults.\n");
M_LoadDefaults (iwad_man); // load before initing other systems
// reinit from here
@ -2281,7 +2272,11 @@ void D_DoomMain (void)
// restart is initiated without a defined IWAD assume for now that it's not going to change.
if (iwad.IsEmpty()) iwad = lastIWAD;
FIWadManager *iwad_man = new FIWadManager;
if (iwad_man == NULL)
{
iwad_man = new FIWadManager;
iwad_man->ParseIWadInfos(basewad);
}
const FIWADInfo *iwad_info = iwad_man->FindIWAD(allwads, iwad, basewad);
gameinfo.gametype = iwad_info->gametype;
gameinfo.flags = iwad_info->flags;
@ -2296,20 +2291,26 @@ void D_DoomMain (void)
FBaseCVar::DisableCallbacks();
GameConfig->DoGameSetup (gameinfo.ConfigName);
AddAutoloadFiles(iwad_info->Group, iwad_info->Autoname);
AddAutoloadFiles(iwad_info->Autoname);
// Run automatically executed files
// Process automatically executed files
FExecList *exec;
execFiles = new DArgs;
GameConfig->AddAutoexec (execFiles, gameinfo.ConfigName);
D_MultiExec (execFiles, true);
GameConfig->AddAutoexec(execFiles, gameinfo.ConfigName);
exec = D_MultiExec(execFiles, NULL);
// Run .cfg files at the start of the command line.
// Process .cfg files at the start of the command line.
execFiles = Args->GatherFiles ("-exec");
D_MultiExec (execFiles, true);
exec = D_MultiExec(execFiles, exec);
C_ExecCmdLineParams (); // [RH] do all +set commands on the command line
// [RH] process all + commands on the command line
exec = C_ParseCmdLineParams(exec);
CopyFiles(allwads, pwads);
if (exec != NULL)
{
exec->AddPullins(allwads);
}
// Since this function will never leave we must delete this array here manually.
pwads.Clear();
@ -2317,7 +2318,7 @@ void D_DoomMain (void)
if (hashfile)
{
Printf("Notice: File hashing is incredibly verbose. Expect loading files to take much longer then usual.\n");
Printf("Notice: File hashing is incredibly verbose. Expect loading files to take much longer than usual.\n");
}
Printf ("W_Init: Init WADfiles.\n");
@ -2326,11 +2327,18 @@ void D_DoomMain (void)
allwads.ShrinkToFit();
SetMapxxFlag();
GameConfig->DoKeySetup(gameinfo.ConfigName);
// Now that wads are loaded, define mod-specific cvars.
ParseCVarInfo();
// Try setting previously unknown cvars again, as a CVARINFO may have made them known.
C_ExecStoredSets();
// Actually exec command line commands and exec files.
if (exec != NULL)
{
exec->ExecCommands();
delete exec;
exec = NULL;
}
// [RH] Initialize localizable strings.
GStrings.LoadStrings (false);
@ -2496,6 +2504,7 @@ void D_DoomMain (void)
FBaseCVar::EnableNoSet ();
delete iwad_man; // now we won't need this anymore
iwad_man = NULL;
// [RH] Run any saved commands from the command line or autoexec.cfg now.
gamestate = GS_FULLCONSOLE;

View file

@ -75,7 +75,6 @@ struct FIWADInfo
{
FString Name; // Title banner text for this IWAD
FString Autoname; // Name of autoload ini section for this IWAD
FString Group; // Groupname for this IWAD
FString Configname; // Name of config section for this IWAD
FString Required; // Requires another IWAD
DWORD FgColor; // Foreground color for title banner
@ -116,15 +115,13 @@ extern FStartupInfo DoomStartupInfo;
//
//==========================================================================
struct FIWadManager
class FIWadManager
{
private:
TArray<FIWADInfo> mIWads;
TArray<FString> mIWadNames;
TArray<int> mLumpsFound;
void ParseIWadInfo(const char *fn, const char *data, int datasize);
void ParseIWadInfos(const char *fn);
void ClearChecks();
void CheckLumpName(const char *name);
int GetIWadInfo();
@ -132,7 +129,19 @@ private:
int CheckIWAD (const char *doomwaddir, WadStuff *wads);
int IdentifyVersion (TArray<FString> &wadfiles, const char *iwad, const char *zdoom_wad);
public:
void ParseIWadInfos(const char *fn);
const FIWADInfo *FindIWAD(TArray<FString> &wadfiles, const char *iwad, const char *basewad);
const FString *GetAutoname(unsigned int num) const
{
if (num < mIWads.Size()) return &mIWads[num].Autoname;
else return NULL;
}
int GetIWadFlags(unsigned int num) const
{
if (num < mIWads.Size()) return mIWads[num].flags;
else return false;
}
};

View file

@ -347,10 +347,10 @@ struct FMapThing
fixed_t y;
fixed_t z;
short angle;
FDoomEdEntry *info;
short EdNum;
WORD SkillFilter;
WORD ClassFilter;
short EdNum;
FDoomEdEntry *info;
DWORD flags;
int special;
int args[5];

View file

@ -69,4 +69,4 @@ int SinglePlayerClass[MAXPLAYERS];
bool ToggleFullscreen;
int BorderTopRefresh;
FString LumpFilterGroup, LumpFilterIWAD;
FString LumpFilterIWAD;

View file

@ -251,6 +251,6 @@ EXTERN_CVAR (Int, compatflags2);
extern int i_compatflags, i_compatflags2, ii_compatflags, ii_compatflags2, ib_compatflags;
// Filters from AddAutoloadFiles(). Used to filter files from archives.
extern FString LumpFilterGroup, LumpFilterIWAD;
extern FString LumpFilterIWAD;
#endif

View file

@ -67,6 +67,7 @@
#include "v_font.h"
#include "r_data/colormaps.h"
#include "farchive.h"
#include "p_setup.h"
static FRandom pr_script("FScript");
@ -312,18 +313,24 @@ static int T_GetPlayerNum(const svalue_t &arg)
// sectors directly by passing a negative value
//
//==========================================================================
int T_FindSectorFromTag(int tagnum,int startsector)
class FSSectorTagIterator : public FSectorTagIterator
{
if (tagnum<=0)
public:
FSSectorTagIterator(int tag)
: FSectorTagIterator(tag)
{
if (startsector<0)
if (tag < 0)
{
if (tagnum==-32768) return 0;
if (-tagnum<numsectors) return -tagnum;
searchtag = INT_MIN;
start = tag == -32768? 0 : -tag < numsectors? -tag : -1;
}
return -1;
}
return P_FindSectorFromTag(tagnum,startsector);
};
inline int T_FindFirstSectorFromTag(int tagnum)
{
FSSectorTagIterator it(tagnum);
return it.Next();
}
@ -1158,7 +1165,7 @@ void FParser::SF_ObjSector(void)
}
t_return.type = svt_int;
t_return.value.i = mo ? mo->Sector->tag : 0; // nullptr check
t_return.value.i = mo ? mo->Sector->GetMainTag() : 0; // nullptr check
}
//==========================================================================
@ -1536,7 +1543,8 @@ void FParser::SF_StartSectorSound(void)
tagnum = intvalue(t_argv[0]);
int i=-1;
while ((i = T_FindSectorFromTag(tagnum, i)) >= 0)
FSSectorTagIterator itr(tagnum);
while ((i = itr.Next()) >= 0)
{
sector = &sectors[i];
S_Sound(sector, CHAN_BODY, T_FindSound(stringvalue(t_argv[1])), 1.0f, ATTN_NORM);
@ -1595,7 +1603,8 @@ void FParser::SF_FloorHeight(void)
// set all sectors with tag
while ((i = T_FindSectorFromTag(tagnum, i)) >= 0)
FSSectorTagIterator itr(tagnum);
while ((i = itr.Next()) >= 0)
{
if (sectors[i].floordata) continue; // don't move floors that are active!
@ -1612,7 +1621,7 @@ void FParser::SF_FloorHeight(void)
}
else
{
secnum = T_FindSectorFromTag(tagnum, -1);
secnum = T_FindFirstSectorFromTag(tagnum);
if(secnum < 0)
{
script_error("sector not found with tagnum %i\n", tagnum);
@ -1671,7 +1680,8 @@ void FParser::SF_MoveFloor(void)
// move all sectors with tag
while ((secnum = T_FindSectorFromTag(tagnum, secnum)) >= 0)
FSSectorTagIterator itr(tagnum);
while ((secnum = itr.Next()) >= 0)
{
sec = &sectors[secnum];
// Don't start a second thinker on the same floor
@ -1733,7 +1743,8 @@ void FParser::SF_CeilingHeight(void)
dest = fixedvalue(t_argv[1]);
// set all sectors with tag
while ((i = T_FindSectorFromTag(tagnum, i)) >= 0)
FSSectorTagIterator itr(tagnum);
while ((i = itr.Next()) >= 0)
{
if (sectors[i].ceilingdata) continue; // don't move ceilings that are active!
@ -1750,7 +1761,7 @@ void FParser::SF_CeilingHeight(void)
}
else
{
secnum = T_FindSectorFromTag(tagnum, -1);
secnum = T_FindFirstSectorFromTag(tagnum);
if(secnum < 0)
{
script_error("sector not found with tagnum %i\n", tagnum);
@ -1823,7 +1834,8 @@ void FParser::SF_MoveCeiling(void)
silent=t_argc>4 ? intvalue(t_argv[4]):1;
// move all sectors with tag
while ((secnum = T_FindSectorFromTag(tagnum, secnum)) >= 0)
FSSectorTagIterator itr(tagnum);
while ((secnum = itr.Next()) >= 0)
{
sec = &sectors[secnum];
@ -1851,7 +1863,7 @@ void FParser::SF_LightLevel(void)
tagnum = intvalue(t_argv[0]);
// argv is sector tag
secnum = T_FindSectorFromTag(tagnum, -1);
secnum = T_FindFirstSectorFromTag(tagnum);
if(secnum < 0)
{
@ -1865,7 +1877,8 @@ void FParser::SF_LightLevel(void)
int i = -1;
// set all sectors with tag
while ((i = T_FindSectorFromTag(tagnum, i)) >= 0)
FSSectorTagIterator itr(tagnum);
while ((i = itr.Next()) >= 0)
{
sectors[i].SetLightLevel(intvalue(t_argv[1]));
}
@ -1984,7 +1997,8 @@ void FParser::SF_FadeLight(void)
destlevel = intvalue(t_argv[1]);
speed = t_argc>2 ? intvalue(t_argv[2]) : 1;
for (i = -1; (i = P_FindSectorFromTag(sectag,i)) >= 0;)
FSectorTagIterator it(sectag);
while ((i = it.Next()) >= 0)
{
if (!sectors[i].lightingdata) new DLightLevel(&sectors[i],destlevel,speed);
}
@ -2006,7 +2020,7 @@ void FParser::SF_FloorTexture(void)
tagnum = intvalue(t_argv[0]);
// argv is sector tag
secnum = T_FindSectorFromTag(tagnum, -1);
secnum = T_FindFirstSectorFromTag(tagnum);
if(secnum < 0)
{ script_error("sector not found with tagnum %i\n", tagnum); return;}
@ -2019,7 +2033,8 @@ void FParser::SF_FloorTexture(void)
FTextureID picnum = TexMan.GetTexture(t_argv[1].string, FTexture::TEX_Flat, FTextureManager::TEXMAN_Overridable);
// set all sectors with tag
while ((i = T_FindSectorFromTag(tagnum, i)) >= 0)
FSSectorTagIterator itr(tagnum);
while ((i = itr.Next()) >= 0)
{
sectors[i].SetTexture(sector_t::floor, picnum);
}
@ -2057,7 +2072,7 @@ void FParser::SF_SectorColormap(void)
tagnum = intvalue(t_argv[0]);
// argv is sector tag
secnum = T_FindSectorFromTag(tagnum, -1);
secnum = T_FindFirstSectorFromTag(tagnum);
if(secnum < 0)
{ script_error("sector not found with tagnum %i\n", tagnum); return;}
@ -2068,7 +2083,8 @@ void FParser::SF_SectorColormap(void)
{
DWORD cm = R_ColormapNumForName(t_argv[1].value.s);
while ((i = T_FindSectorFromTag(tagnum, i)) >= 0)
FSSectorTagIterator itr(tagnum);
while ((i = itr.Next()) >= 0)
{
sectors[i].midmap=cm;
sectors[i].heightsec=&sectors[i];
@ -2094,7 +2110,7 @@ void FParser::SF_CeilingTexture(void)
tagnum = intvalue(t_argv[0]);
// argv is sector tag
secnum = T_FindSectorFromTag(tagnum, -1);
secnum = T_FindFirstSectorFromTag(tagnum);
if(secnum < 0)
{ script_error("sector not found with tagnum %i\n", tagnum); return;}
@ -2107,7 +2123,8 @@ void FParser::SF_CeilingTexture(void)
FTextureID picnum = TexMan.GetTexture(t_argv[1].string, FTexture::TEX_Flat, FTextureManager::TEXMAN_Overridable);
// set all sectors with tag
while ((i = T_FindSectorFromTag(tagnum, i)) >= 0)
FSSectorTagIterator itr(tagnum);
while ((i = itr.Next()) >= 0)
{
sectors[i].SetTexture(sector_t::ceiling, picnum);
}
@ -2210,9 +2227,6 @@ void FParser::SF_RunCommand(void)
//
//==========================================================================
// any linedef type
extern void P_TranslateLineDef (line_t *ld, maplinedef_t *mld);
void FParser::SF_LineTrigger()
{
if (CheckArgs(1))
@ -2221,7 +2235,7 @@ void FParser::SF_LineTrigger()
maplinedef_t mld;
mld.special=intvalue(t_argv[0]);
mld.tag=t_argc > 1 ? intvalue(t_argv[1]) : 0;
P_TranslateLineDef(&line, &mld);
P_TranslateLineDef(&line, &mld, false);
P_ExecuteSpecial(line.special, NULL, Script->trigger, false,
line.args[0],line.args[1],line.args[2],line.args[3],line.args[4]);
}
@ -2281,9 +2295,11 @@ void FParser::SF_SetLineBlocking(void)
{
blocking=blocks[blocking];
int tag=intvalue(t_argv[0]);
for (int i = -1; (i = P_FindLineFromID(tag, i)) >= 0;)
FLineIdIterator itr(tag);
int i;
while ((i = itr.Next()) >= 0)
{
lines[i].flags = (lines[i].flags & ~(ML_BLOCKING|ML_BLOCKEVERYTHING)) | blocking;
lines[i].flags = (lines[i].flags & ~(ML_BLOCKING | ML_BLOCKEVERYTHING)) | blocking;
}
}
}
@ -2302,7 +2318,9 @@ void FParser::SF_SetLineMonsterBlocking(void)
int blocking = intvalue(t_argv[1]) ? ML_BLOCKMONSTERS : 0;
int tag=intvalue(t_argv[0]);
for (int i = -1; (i = P_FindLineFromID(tag, i)) >= 0;)
FLineIdIterator itr(tag);
int i;
while ((i = itr.Next()) >= 0)
{
lines[i].flags = (lines[i].flags & ~ML_BLOCKMONSTERS) | blocking;
}
@ -2357,12 +2375,13 @@ void FParser::SF_SetLineTexture(void)
texture = stringvalue(t_argv[3]);
texturenum = TexMan.GetTexture(texture, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable);
for (i = -1; (i = P_FindLineFromID(tag, i)) >= 0;)
FLineIdIterator itr(tag);
while ((i = itr.Next()) >= 0)
{
// bad sidedef, Hexen just SEGV'd here!
if(lines[i].sidedef[side] != NULL)
if (lines[i].sidedef[side] != NULL)
{
if (position >=0 && position <=2)
if (position >= 0 && position <= 2)
{
lines[i].sidedef[side]->SetTexture(position, texturenum);
}
@ -2376,7 +2395,8 @@ void FParser::SF_SetLineTexture(void)
int sections = intvalue(t_argv[3]);
// set all sectors with tag
for (i = -1; (i = P_FindLineFromID(tag, i)) >= 0;)
FLineIdIterator itr(tag);
while ((i = itr.Next()) >= 0)
{
side_t *sided = lines[i].sidedef[side];
if(sided != NULL)
@ -4201,7 +4221,7 @@ void FParser::SF_SetColor(void)
{
tagnum = intvalue(t_argv[0]);
secnum = T_FindSectorFromTag(tagnum, -1);
secnum = T_FindFirstSectorFromTag(tagnum);
if(secnum < 0)
{
@ -4222,7 +4242,8 @@ void FParser::SF_SetColor(void)
else return;
// set all sectors with tag
while ((i = T_FindSectorFromTag(tagnum, i)) >= 0)
FSSectorTagIterator itr(tagnum);
while ((i = itr.Next()) >= 0)
{
sectors[i].ColorMap = GetSpecialLights (color, sectors[i].ColorMap->Fade, 0);
}
@ -4291,7 +4312,7 @@ void FParser::SF_KillInSector()
while ((mo=it.Next()))
{
if (mo->flags3&MF3_ISMONSTER && mo->Sector->tag==tag) P_DamageMobj(mo, NULL, NULL, 1000000, NAME_Massacre);
if (mo->flags3&MF3_ISMONSTER && mo->Sector->HasTag(tag)) P_DamageMobj(mo, NULL, NULL, 1000000, NAME_Massacre);
}
}
}
@ -4314,7 +4335,7 @@ void FParser::SF_SectorType(void)
tagnum = intvalue(t_argv[0]);
// argv is sector tag
secnum = T_FindSectorFromTag(tagnum, -1);
secnum = T_FindFirstSectorFromTag(tagnum);
if(secnum < 0)
{ script_error("sector not found with tagnum %i\n", tagnum); return;}
@ -4327,7 +4348,8 @@ void FParser::SF_SectorType(void)
int spec = intvalue(t_argv[1]);
// set all sectors with tag
while ((i = T_FindSectorFromTag(tagnum, i)) >= 0)
FSSectorTagIterator itr(tagnum);
while ((i = itr.Next()) >= 0)
{
sectors[i].special = spec;
}
@ -4355,18 +4377,17 @@ void FParser::SF_SetLineTrigger()
id=intvalue(t_argv[0]);
spec=intvalue(t_argv[1]);
if (t_argc>2) tag=intvalue(t_argv[2]);
for (i = -1; (i = P_FindLineFromID (id, i)) >= 0; )
FLineIdIterator itr(id);
while ((i = itr.Next()) >= 0)
{
if (t_argc==2) tag=lines[i].id;
maplinedef_t mld;
mld.special=spec;
mld.tag=tag;
mld.flags=0;
mld.special = spec;
mld.tag = tag;
mld.flags = 0;
int f = lines[i].flags;
P_TranslateLineDef(&lines[i], &mld);
lines[i].id=tag;
lines[i].flags = (lines[i].flags & (ML_MONSTERSCANACTIVATE|ML_REPEAT_SPECIAL|ML_SPAC_MASK|ML_FIRSTSIDEONLY)) |
(f & ~(ML_MONSTERSCANACTIVATE|ML_REPEAT_SPECIAL|ML_SPAC_MASK|ML_FIRSTSIDEONLY));
P_TranslateLineDef(&lines[i], &mld, false);
lines[i].flags = (lines[i].flags & (ML_MONSTERSCANACTIVATE | ML_REPEAT_SPECIAL | ML_SPAC_MASK | ML_FIRSTSIDEONLY)) |
(f & ~(ML_MONSTERSCANACTIVATE | ML_REPEAT_SPECIAL | ML_SPAC_MASK | ML_FIRSTSIDEONLY));
}
}
@ -4375,33 +4396,13 @@ void FParser::SF_SetLineTrigger()
//==========================================================================
//
// new for GZDoom: Changes a sector's tag
// (I only need this because MAP02 in RTC-3057 has some issues with the GL
// renderer that I can't fix without the scripts. But loading a FS on top on
// ACS still works so I can hack around it with this.)
//
//
//==========================================================================
void FParser::SF_ChangeTag()
{
if (CheckArgs(2))
{
for (int secnum = -1; (secnum = P_FindSectorFromTag (t_argv[0].value.i, secnum)) >= 0; )
{
sectors[secnum].tag=t_argv[1].value.i;
}
// Recreate the hash tables
int i;
for (i=numsectors; --i>=0; ) sectors[i].firsttag = -1;
for (i=numsectors; --i>=0; )
{
int j = (unsigned) sectors[i].tag % (unsigned) numsectors;
sectors[i].nexttag = sectors[j].firsttag;
sectors[j].firsttag = i;
}
}
// Development garbage!
}

View file

@ -452,9 +452,9 @@ bool DFraggleThinker::wait_finished(DRunningScript *script)
case wt_tagwait:
{
int secnum = -1;
while ((secnum = P_FindSectorFromTag(script->wait_data, secnum)) >= 0)
int secnum;
FSectorTagIterator itr(script->wait_data);
while ((secnum = itr.Next()) >= 0)
{
sector_t *sec = &sectors[secnum];
if(sec->floordata || sec->ceilingdata || sec->lightingdata)

View file

@ -80,7 +80,8 @@ const char *SpecialMapthingNames[] = {
struct MapinfoEdMapItem
{
FName classname; // DECORATE is read after MAPINFO so we do not have the actual classes available here yet.
int special;
short special;
bool argsdefined;
int args[5];
// These are for error reporting. We must store the file information because it's no longer available when these items get resolved.
FString filename;
@ -180,14 +181,15 @@ void FMapInfoParser::ParseDoomEdNums()
editem.special = -1;
}
memset(editem.args, 0, sizeof(editem.args));
editem.argsdefined = false;
int minargs = 0;
int maxargs = 5;
FString specialname;
if (sc.CheckString(","))
{
// todo: parse a special or args
if (editem.special < 0) editem.special = 0; // mark args as used - if this is done we need to prevent assignment of map args in P_SpawnMapThing.
editem.argsdefined = true; // mark args as used - if this is done we need to prevent assignment of map args in P_SpawnMapThing.
if (editem.special < 0) editem.special = 0;
if (!sc.CheckNumber())
{
sc.MustGetString();
@ -264,6 +266,7 @@ void InitActorNumsFromMapinfo()
FDoomEdEntry ent;
ent.Type = cls;
ent.Special = pair->Value.special;
ent.ArgsDefined = pair->Value.argsdefined;
memcpy(ent.Args, pair->Value.args, sizeof(ent.Args));
DoomEdMap.Insert(pair->Key, ent);
}

View file

@ -2519,7 +2519,7 @@ bool G_ProcessIFFDemo (FString &mapname)
id = ReadLong (&demo_p);
if (id != ZDEM_ID)
{
Printf ("Not a ZDoom demo file!\n");
Printf ("Not a " GAMENAME " demo file!\n");
return true;
}
@ -2544,12 +2544,12 @@ bool G_ProcessIFFDemo (FString &mapname)
demover = ReadWord (&demo_p); // ZDoom version demo was created with
if (demover < MINDEMOVERSION)
{
Printf ("Demo requires an older version of ZDoom!\n");
Printf ("Demo requires an older version of " GAMENAME "!\n");
//return true;
}
if (ReadWord (&demo_p) > DEMOGAMEVERSION) // Minimum ZDoom version
{
Printf ("Demo requires a newer version of ZDoom!\n");
Printf ("Demo requires a newer version of " GAMENAME "!\n");
return true;
}
if (demover >= 0x21a)
@ -2676,7 +2676,7 @@ void G_DoPlayDemo (void)
if (ReadLong (&demo_p) != FORM_ID)
{
const char *eek = "Cannot play non-ZDoom demos.\n";
const char *eek = "Cannot play non-" GAMENAME " demos.\n";
C_ForgetCVars();
M_Free(demobuffer);

View file

@ -1757,6 +1757,7 @@ IMPLEMENT_CLASS(APowerRegeneration)
void APowerRegeneration::DoEffect()
{
Super::DoEffect();
if (Owner != NULL && Owner->health > 0 && (level.time & 31) == 0)
{
if (P_GiveBody(Owner, Strength/FRACUNIT))

View file

@ -119,7 +119,9 @@ void ASkyCamCompat::BeginPlay ()
// Finally, skyboxify all tagged sectors
// This involves changing their texture to the sky flat, because while
// EE works with any texture for its skybox portals, ZDoom doesn't.
for (int secnum =-1; (secnum = P_FindSectorFromTag (skybox_id, secnum)) != -1; )
FSectorTagIterator it(skybox_id);
int secnum;
while ((secnum = it.Next()) >= 0)
{
// plane: 0=floor, 1=ceiling, 2=both
if (refline->args[2] == 1 || refline->args[2] == 2)

View file

@ -1502,7 +1502,7 @@ void DBaseStatusBar::DrawTopStuff (EHudState state)
{
screen->DrawText (SmallFont, CR_TAN, 0, ST_Y - 40 * CleanYfac,
"Demo was recorded with a different version\n"
"of ZDoom. Expect it to go out of sync.",
"of " GAMENAME ". Expect it to go out of sync.",
DTA_CleanNoMove, true, TAG_DONE);
}

View file

@ -665,7 +665,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckTerrain)
}
else if ((sec->special & 0xFF) == Scroll_StrifeCurrent)
{
int anglespeed = sec->tag - 100;
int anglespeed = sec->GetMainTag() - 100;
fixed_t speed = (anglespeed % 10) << (FRACBITS - 4);
angle_t finean = (anglespeed / 10) << (32-3);
finean >>= ANGLETOFINESHIFT;

View file

@ -61,6 +61,7 @@ extern HWND Window;
#include "doomstat.h"
#include "i_system.h"
#include "gi.h"
#include "d_main.h"
EXTERN_CVAR (Bool, con_centernotify)
EXTERN_CVAR (Int, msg0color)
@ -75,7 +76,7 @@ EXTERN_CVAR (Color, am_cdwallcolor)
EXTERN_CVAR (Float, spc_amp)
EXTERN_CVAR (Bool, wi_percents)
FGameConfigFile::FGameConfigFile ()
FGameConfigFile::FGameConfigFile (FIWadManager *iwad_man)
{
#ifdef __APPLE__
FString user_docs, user_app_support, local_app_support;
@ -83,16 +84,10 @@ FGameConfigFile::FGameConfigFile ()
FString pathname;
OkayToWrite = false; // Do not allow saving of the config before DoGameSetup()
bMigrating = false;
bModSetup = false;
pathname = GetConfigPath (true);
ChangePathName (pathname);
LoadConfigFile (MigrateStub, NULL);
if (!HaveSections ())
{ // Config file not found; try the old one
MigrateOldConfig ();
}
LoadConfigFile ();
// If zdoom.ini was read from the program directory, switch
// to the user directory now. If it was read from the user
@ -169,28 +164,49 @@ FGameConfigFile::FGameConfigFile ()
// Create auto-load sections, so users know what's available.
// Note that this totem pole is the reverse of the order that
// they will appear in the file.
CreateSectionAtStart("Harmony.Autoload");
CreateSectionAtStart("UrbanBrawl.Autoload");
CreateSectionAtStart("Chex3.Autoload");
CreateSectionAtStart("Chex1.Autoload");
CreateSectionAtStart("Chex.Autoload");
CreateSectionAtStart("Strife.Autoload");
CreateSectionAtStart("HexenDK.Autoload");
CreateSectionAtStart("Hexen.Autoload");
CreateSectionAtStart("HereticSR.Autoload");
CreateSectionAtStart("Heretic.Autoload");
CreateSectionAtStart("FreeDM.Autoload");
CreateSectionAtStart("Freedoom2.Autoload");
CreateSectionAtStart("Freedoom1.Autoload");
CreateSectionAtStart("Freedoom.Autoload");
CreateSectionAtStart("Plutonia.Autoload");
CreateSectionAtStart("TNT.Autoload");
CreateSectionAtStart("Doom2BFG.Autoload");
CreateSectionAtStart("Doom2.Autoload");
CreateSectionAtStart("DoomBFG.Autoload");
CreateSectionAtStart("DoomU.Autoload");
CreateSectionAtStart("Doom1.Autoload");
CreateSectionAtStart("Doom.Autoload");
double last = 0;
if (SetSection ("LastRun"))
{
const char *lastver = GetValueForKey ("Version");
if (lastver != NULL) last = atof(lastver);
}
if (last < 211)
{
RenameSection("Chex3.Autoload", "chex.chex3.Autoload");
RenameSection("Chex1.Autoload", "chex.chex1.Autoload");
RenameSection("HexenDK.Autoload", "hexen.deathkings.Autoload");
RenameSection("HereticSR.Autoload", "heretic.shadow.Autoload");
RenameSection("FreeDM.Autoload", "doom.freedoom.freedm.Autoload");
RenameSection("Freedoom2.Autoload", "doom.freedoom.phase2.Autoload");
RenameSection("Freedoom1.Autoload", "doom.freedoom.phase1.Autoload");
RenameSection("Freedoom.Autoload", "doom.freedoom.Autoload");
RenameSection("DoomBFG.Autoload", "doom.doom1.bfg.Autoload");
RenameSection("DoomU.Autoload", "doom.doom1.ultimate.Autoload");
RenameSection("Doom1.Autoload", "doom.doom1.registered.Autoload");
RenameSection("TNT.Autoload", "doom.doom2.tnt.Autoload");
RenameSection("Plutonia.Autoload", "doom.doom2.plutonia.Autoload");
RenameSection("Doom2BFG.Autoload", "doom.doom2.bfg.Autoload");
RenameSection("Doom2.Autoload", "doom.doom2.commercial.Autoload");
}
const FString *pAuto;
for (int num = 0; (pAuto = iwad_man->GetAutoname(num)) != NULL; num++)
{
if (!(iwad_man->GetIWadFlags(num) & GI_SHAREWARE)) // we do not want autoload sections for shareware IWADs (which may have an autoname for resource filtering)
{
FString workname = *pAuto;
while (workname.IsNotEmpty())
{
FString section = workname + ".Autoload";
CreateSectionAtStart(section.GetChars());
long dotpos = workname.LastIndexOf('.');
if (dotpos < 0) break;
workname.Truncate(dotpos);
}
}
}
CreateSectionAtStart("Global.Autoload");
// The same goes for auto-exec files.
@ -223,9 +239,10 @@ FGameConfigFile::FGameConfigFile ()
"# Wad files to automatically load depending on the game and IWAD you are\n"
"# playing. You may have have files that are loaded for all similar IWADs\n"
"# (the game) and files that are only loaded for particular IWADs. For example,\n"
"# any files listed under Doom.Autoload will be loaded for any version of Doom,\n"
"# but files listed under Doom2.Autoload will only load when you are\n"
"# playing Doom 2.\n\n");
"# any files listed under 'doom.Autoload' will be loaded for any version of Doom,\n"
"# but files listed under 'doom.doom2.Autoload' will only load when you are\n"
"# playing a Doom 2 based game (doom2.wad, tnt.wad or plutonia.wad), and files listed under\n"
"# 'doom.doom2.commercial.Autoload' only when playing doom2.wad.\n\n");
}
FGameConfigFile::~FGameConfigFile ()
@ -237,18 +254,6 @@ void FGameConfigFile::WriteCommentHeader (FILE *file) const
fprintf (file, "# This file was generated by " GAMENAME " %s on %s\n", GetVersionString(), myasctime());
}
void FGameConfigFile::MigrateStub (const char *pathname, FConfigFile *config, void *userdata)
{
static_cast<FGameConfigFile *>(config)->bMigrating = true;
}
void FGameConfigFile::MigrateOldConfig ()
{
// Set default key bindings. These will be overridden
// by the bindings in the config file if it exists.
C_SetDefaultBindings ();
}
void FGameConfigFile::DoGlobalSetup ()
{
if (SetSection ("GlobalSettings.Unknown"))
@ -361,10 +366,6 @@ void FGameConfigFile::DoGameSetup (const char *gamename)
const char *key;
const char *value;
if (bMigrating)
{
MigrateOldConfig ();
}
sublen = countof(section) - 1 - mysnprintf (section, countof(section), "%s.", gamename);
subsection = section + countof(section) - sublen - 1;
section[countof(section) - 1] = '\0';
@ -400,41 +401,6 @@ void FGameConfigFile::DoGameSetup (const char *gamename)
ReadCVars (0);
}
if (!bMigrating)
{
C_SetDefaultBindings ();
}
strncpy (subsection, "Bindings", sublen);
if (SetSection (section))
{
Bindings.UnbindAll();
while (NextInSection (key, value))
{
Bindings.DoBind (key, value);
}
}
strncpy (subsection, "DoubleBindings", sublen);
if (SetSection (section))
{
DoubleBindings.UnbindAll();
while (NextInSection (key, value))
{
DoubleBindings.DoBind (key, value);
}
}
strncpy (subsection, "AutomapBindings", sublen);
if (SetSection (section))
{
AutomapBindings.UnbindAll();
while (NextInSection (key, value))
{
AutomapBindings.DoBind (key, value);
}
}
strncpy (subsection, "ConsoleAliases", sublen);
if (SetSection (section))
{
@ -455,6 +421,39 @@ void FGameConfigFile::DoGameSetup (const char *gamename)
OkayToWrite = true;
}
// Moved from DoGameSetup so that it can happen after wads are loaded
void FGameConfigFile::DoKeySetup(const char *gamename)
{
static const struct { const char *label; FKeyBindings *bindings; } binders[] =
{
{ "Bindings", &Bindings },
{ "DoubleBindings", &DoubleBindings },
{ "AutomapBindings", &AutomapBindings },
{ NULL, NULL }
};
const char *key, *value;
sublen = countof(section) - 1 - mysnprintf(section, countof(section), "%s.", gamename);
subsection = section + countof(section) - sublen - 1;
section[countof(section) - 1] = '\0';
C_SetDefaultBindings ();
for (int i = 0; binders[i].label != NULL; ++i)
{
strncpy(subsection, binders[i].label, sublen);
if (SetSection(section))
{
FKeyBindings *bindings = binders[i].bindings;
bindings->UnbindAll();
while (NextInSection(key, value))
{
bindings->DoBind(key, value);
}
}
}
}
// Like DoGameSetup(), but for mod-specific cvars.
// Called after CVARINFO has been parsed.
void FGameConfigFile::DoModSetup(const char *gamename)
@ -628,41 +627,20 @@ void FGameConfigFile::AddAutoexec (DArgs *list, const char *game)
mysnprintf (section, countof(section), "%s.AutoExec", game);
if (bMigrating)
// If <game>.AutoExec section does not exist, create it
// with a default autoexec.cfg file present.
CreateStandardAutoExec(section, false);
// Run any files listed in the <game>.AutoExec section
if (!SectionIsEmpty())
{
FBaseCVar *autoexec = FindCVar ("autoexec", NULL);
if (autoexec != NULL)
while (NextInSection (key, value))
{
UCVarValue val;
char *path;
val = autoexec->GetGenericRep (CVAR_String);
path = copystring (val.String);
delete autoexec;
SetSection (section, true);
SetValueForKey ("Path", path);
list->AppendArg (path);
delete[] path;
}
}
else
{
// If <game>.AutoExec section does not exist, create it
// with a default autoexec.cfg file present.
CreateStandardAutoExec(section, false);
// Run any files listed in the <game>.AutoExec section
if (!SectionIsEmpty())
{
while (NextInSection (key, value))
if (stricmp (key, "Path") == 0 && *value != '\0')
{
if (stricmp (key, "Path") == 0 && *value != '\0')
FString expanded_path = ExpandEnvVars(value);
if (FileExists(expanded_path))
{
FString expanded_path = ExpandEnvVars(value);
if (FileExists(expanded_path))
{
list->AppendArg (ExpandEnvVars(value));
}
list->AppendArg (ExpandEnvVars(value));
}
}
}
@ -673,13 +651,6 @@ void FGameConfigFile::SetRavenDefaults (bool isHexen)
{
UCVarValue val;
if (bMigrating)
{
con_centernotify.ResetToDefault ();
msg0color.ResetToDefault ();
color.ResetToDefault ();
}
val.Bool = false;
wi_percents.SetGenericRepDefault (val, CVAR_Bool);
val.Bool = true;

View file

@ -38,15 +38,17 @@
#include "configfile.h"
class DArgs;
class FIWadManager;
class FGameConfigFile : public FConfigFile
{
public:
FGameConfigFile ();
FGameConfigFile (FIWadManager *iwad_man);
~FGameConfigFile ();
void DoGlobalSetup ();
void DoGameSetup (const char *gamename);
void DoKeySetup (const char *gamename);
void DoModSetup (const char *gamename);
void ArchiveGlobalData ();
void ArchiveGameData (const char *gamename);
@ -59,13 +61,9 @@ protected:
void CreateStandardAutoExec (const char *section, bool start);
private:
static void MigrateStub (const char *pathname, FConfigFile *config, void *userdata);
void MigrateOldConfig ();
void SetRavenDefaults (bool isHexen);
void ReadCVars (DWORD flags);
bool bMigrating;
bool bModSetup;
char section[64];

View file

@ -279,7 +279,8 @@ inline PClassActor *PClass::FindActor(FName name)
struct FDoomEdEntry
{
PClassActor *Type;
int Special;
short Special;
bool ArgsDefined;
int Args[5];
};

View file

@ -410,9 +410,9 @@ CCMD (writeini)
// M_LoadDefaults
//
void M_LoadDefaults ()
void M_LoadDefaults (FIWadManager *iwad_man)
{
GameConfig = new FGameConfigFile;
GameConfig = new FGameConfigFile(iwad_man);
GameConfig->DoGlobalSetup ();
atterm (M_SaveDefaultsFinal);
}

View file

@ -28,6 +28,7 @@
class FConfigFile;
class FGameConfigFile;
class FIWadManager;
extern FGameConfigFile *GameConfig;
@ -40,7 +41,7 @@ void M_FindResponseFile (void);
// Pass a NULL to get the original behavior.
void M_ScreenShot (const char *filename);
void M_LoadDefaults ();
void M_LoadDefaults (FIWadManager *iwad_man);
bool M_SaveDefaults (const char *filename);
void M_SaveCustomKeys (FConfigFile *config, char *section, char *subsection, size_t sublen);

View file

@ -45,6 +45,35 @@
// TYPES -------------------------------------------------------------------
class OPLDump : public OPLEmul
{
public:
OPLDump(FILE *file) : File(file), TimePerTick(0), CurTime(0),
CurIntTime(0), TickMul(1), CurChip(0) {}
// If we're doing things right, these should never be reset.
virtual void Reset() { assert(0); }
// Update() is only used for getting waveform data, which dumps don't do.
virtual void Update(float *buffer, int length) { assert(0); }
// OPL dumps don't pan beyond what OPL3 is capable of (which is
// already written using registers from the original data).
virtual void SetPanning(int c, float left, float right) {}
// Only for the OPL dumpers, not the emulators
virtual void SetClockRate(double samples_per_tick) {}
virtual void WriteDelay(int ticks) = 0;
protected:
FILE *File;
double TimePerTick; // in milliseconds
double CurTime;
int CurIntTime;
int TickMul;
BYTE CurChip;
};
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
@ -59,6 +88,173 @@
// CODE --------------------------------------------------------------------
class OPL_RDOSdump : public OPLDump
{
public:
OPL_RDOSdump(FILE *file) : OPLDump(file)
{
assert(File != NULL);
fwrite("RAWADATA\0", 1, 10, File);
NeedClockRate = true;
}
virtual ~OPL_RDOSdump()
{
if (File != NULL)
{
WORD endmark = 0xFFFF;
fwrite(&endmark, 2, 1, File);
fclose(File);
}
}
virtual void WriteReg(int reg, int v)
{
assert(File != NULL);
BYTE chipnum = reg >> 8;
if (chipnum != CurChip)
{
BYTE switcher[2] = { chipnum + 1, 2 };
fwrite(switcher, 1, 2, File);
}
reg &= 255;
if (reg != 0 && reg != 2 && (reg != 255 || v != 255))
{
BYTE cmd[2] = { BYTE(v), BYTE(reg) };
fwrite(cmd, 1, 2, File);
}
}
virtual void SetClockRate(double samples_per_tick)
{
TimePerTick = samples_per_tick / OPL_SAMPLE_RATE * 1000.0;
double clock_rate;
int clock_mul;
WORD clock_word;
clock_rate = samples_per_tick * ADLIB_CLOCK_MUL;
clock_mul = 1;
// The RDos raw format's clock rate is stored in a word. Therefore,
// the longest tick that can be stored is only ~55 ms.
while (clock_rate / clock_mul + 0.5 > 65535.0)
{
clock_mul++;
}
clock_word = WORD(clock_rate / clock_mul + 0.5);
if (NeedClockRate)
{ // Set the initial clock rate.
clock_word = LittleShort(clock_word);
fseek(File, 8, SEEK_SET);
fwrite(&clock_word, 2, 1, File);
fseek(File, 0, SEEK_END);
NeedClockRate = false;
}
else
{ // Change the clock rate in the middle of the song.
BYTE clock_change[4] = { 0, 2, BYTE(clock_word & 255), BYTE(clock_word >> 8) };
fwrite(clock_change, 1, 4, File);
}
}
virtual void WriteDelay(int ticks)
{
if (ticks > 0)
{ // RDos raw has very precise delays but isn't very efficient at
// storing long delays.
BYTE delay[2];
ticks *= TickMul;
delay[1] = 0;
while (ticks > 255)
{
ticks -= 255;
delay[0] = 255;
fwrite(delay, 1, 2, File);
}
delay[0] = BYTE(ticks);
fwrite(delay, 1, 2, File);
}
}
protected:
bool NeedClockRate;
};
class OPL_DOSBOXdump : public OPLDump
{
public:
OPL_DOSBOXdump(FILE *file, bool dual) : OPLDump(file), Dual(dual)
{
assert(File != NULL);
fwrite("DBRAWOPL"
"\0\0" // Minor version number
"\1\0" // Major version number
"\0\0\0\0" // Total milliseconds
"\0\0\0", // Total data
1, 20, File);
char type[4] = { Dual * 2, 0, 0, 0 }; // Single or dual OPL-2
fwrite(type, 1, 4, File);
}
virtual ~OPL_DOSBOXdump()
{
if (File != NULL)
{
long where_am_i = ftell(File);
DWORD len[2];
fseek(File, 12, SEEK_SET);
len[0] = LittleLong(CurIntTime);
len[1] = LittleLong(DWORD(where_am_i - 24));
fwrite(len, 4, 2, File);
fclose(File);
}
}
virtual void WriteReg(int reg, int v)
{
assert(File != NULL);
BYTE chipnum = reg >> 8;
if (chipnum != CurChip)
{
CurChip = chipnum;
fputc(chipnum + 2, File);
}
reg &= 255;
BYTE cmd[3] = { 4, BYTE(reg), BYTE(v) };
fwrite (cmd + (reg > 4), 1, 3 - (reg > 4), File);
}
virtual void WriteDelay(int ticks)
{
if (ticks > 0)
{ // DosBox only has millisecond-precise delays.
int delay;
CurTime += TimePerTick * ticks;
delay = int(CurTime + 0.5) - CurIntTime;
CurIntTime += delay;
while (delay > 65536)
{
BYTE cmd[3] = { 1, 255, 255 };
fwrite(cmd, 1, 2, File);
delay -= 65536;
}
delay--;
if (delay <= 255)
{
BYTE cmd[2] = { 0, BYTE(delay) };
fwrite(cmd, 1, 2, File);
}
else
{
assert(delay <= 65535);
BYTE cmd[3] = { 1, BYTE(delay & 255), BYTE(delay >> 8) };
fwrite(cmd, 1, 3, File);
}
}
}
protected:
bool Dual;
};
//==========================================================================
//
// OPLDumperMIDIDevice Constructor
@ -139,139 +335,34 @@ DiskWriterIO::~DiskWriterIO()
//
//==========================================================================
int DiskWriterIO::OPLinit(uint numchips, bool, bool)
int DiskWriterIO::OPLinit(uint numchips, bool, bool initopl3)
{
// If the file extension is unknown or not present, the default format
// is RAW. Otherwise, you can use DRO.
if (Filename.Len() < 5 || stricmp(&Filename[Filename.Len() - 4], ".dro") != 0)
{
Format = FMT_RDOS;
}
else
{
Format = FMT_DOSBOX;
}
File = fopen(Filename, "wb");
if (File == NULL)
FILE *file = fopen(Filename, "wb");
if (file == NULL)
{
Printf("Could not open %s for writing.\n", Filename.GetChars());
return 0;
}
if (Format == FMT_RDOS)
numchips = clamp(numchips, 1u, 2u);
memset(chips, 0, sizeof(chips));
// If the file extension is unknown or not present, the default format
// is RAW. Otherwise, you can use DRO.
if (Filename.Len() < 5 || stricmp(&Filename[Filename.Len() - 4], ".dro") != 0)
{
fwrite("RAWADATA\0", 1, 10, File);
NeedClockRate = true;
chips[0] = new OPL_RDOSdump(file);
}
else
{
fwrite("DBRAWOPL"
"\0\0" // Minor version number
"\1\0" // Major version number
"\0\0\0\0" // Total milliseconds
"\0\0\0", // Total data
1, 20, File);
if (numchips == 1)
{
fwrite("\0\0\0", 1, 4, File); // Single OPL-2
}
else
{
fwrite("\2\0\0", 1, 4, File); // Dual OPL-2
}
NeedClockRate = false;
chips[0] = new OPL_DOSBOXdump(file, numchips > 1);
}
TimePerTick = 0;
TickMul = 1;
CurTime = 0;
CurIntTime = 0;
CurChip = 0;
OPLchannels = OPL2CHANNELS * numchips;
OPLwriteInitState(false);
NumChips = numchips;
IsOPL3 = numchips > 1;
OPLwriteInitState(initopl3);
return numchips;
}
//==========================================================================
//
// DiskWriterIO :: OPLdeinit
//
//==========================================================================
void DiskWriterIO::OPLdeinit()
{
if (File != NULL)
{
if (Format == FMT_RDOS)
{
WORD endmark = 65535;
fwrite(&endmark, 2, 1, File);
}
else
{
long where_am_i = ftell(File);
DWORD len[2];
fseek(File, 12, SEEK_SET);
len[0] = LittleLong(CurIntTime);
len[1] = LittleLong(DWORD(where_am_i - 24));
fwrite(len, 4, 2, File);
}
fclose(File);
File = NULL;
}
}
//==========================================================================
//
// DiskWriterIO :: OPLwriteReg
//
//==========================================================================
void DiskWriterIO::OPLwriteReg(int which, uint reg, uchar data)
{
SetChip(which);
if (Format == FMT_RDOS)
{
if (reg != 0 && reg != 2 && (reg != 255 || data != 255))
{
BYTE cmd[2] = { data, BYTE(reg) };
fwrite(cmd, 1, 2, File);
}
}
else
{
BYTE cmd[3] = { 4, BYTE(reg), data };
fwrite (cmd + (reg > 4), 1, 3 - (reg > 4), File);
}
}
//==========================================================================
//
// DiskWriterIO :: SetChip
//
//==========================================================================
void DiskWriterIO :: SetChip(int chipnum)
{
assert(chipnum == 0 || chipnum == 1);
if (chipnum != CurChip)
{
CurChip = chipnum;
if (Format == FMT_RDOS)
{
BYTE switcher[2] = { BYTE(chipnum + 1), 2 };
fwrite(switcher, 1, 2, File);
}
else
{
BYTE switcher = chipnum + 2;
fwrite(&switcher, 1, 1, File);
}
}
}
//==========================================================================
//
// DiskWriterIO :: SetClockRate
@ -280,39 +371,7 @@ void DiskWriterIO :: SetChip(int chipnum)
void DiskWriterIO::SetClockRate(double samples_per_tick)
{
TimePerTick = samples_per_tick / OPL_SAMPLE_RATE * 1000.0;
if (Format == FMT_RDOS)
{
double clock_rate;
int clock_mul;
WORD clock_word;
clock_rate = samples_per_tick * ADLIB_CLOCK_MUL;
clock_mul = 1;
// The RDos raw format's clock rate is stored in a word. Therefore,
// the longest tick that can be stored is only ~55 ms.
while (clock_rate / clock_mul + 0.5 > 65535.0)
{
clock_mul++;
}
clock_word = WORD(clock_rate / clock_mul + 0.5);
if (NeedClockRate)
{ // Set the initial clock rate.
clock_word = LittleShort(clock_word);
fseek(File, 8, SEEK_SET);
fwrite(&clock_word, 2, 1, File);
fseek(File, 0, SEEK_END);
NeedClockRate = false;
}
else
{ // Change the clock rate in the middle of the song.
BYTE clock_change[4] = { 0, 2, BYTE(clock_word & 255), BYTE(clock_word >> 8) };
fwrite(clock_change, 1, 4, File);
}
}
static_cast<OPLDump *>(chips[0])->SetClockRate(samples_per_tick);
}
//==========================================================================
@ -323,50 +382,5 @@ void DiskWriterIO::SetClockRate(double samples_per_tick)
void DiskWriterIO :: WriteDelay(int ticks)
{
if (ticks <= 0)
{
return;
}
if (Format == FMT_RDOS)
{ // RDos raw has very precise delays but isn't very efficient at
// storing long delays.
BYTE delay[2];
ticks *= TickMul;
delay[1] = 0;
while (ticks > 255)
{
ticks -= 255;
delay[0] = 255;
fwrite(delay, 1, 2, File);
}
delay[0] = BYTE(ticks);
fwrite(delay, 1, 2, File);
}
else
{ // DosBox only has millisecond-precise delays.
int delay;
CurTime += TimePerTick * ticks;
delay = int(CurTime + 0.5) - CurIntTime;
CurIntTime += delay;
while (delay > 65536)
{
BYTE cmd[3] = { 1, 255, 255 };
fwrite(cmd, 1, 2, File);
delay -= 65536;
}
delay--;
if (delay <= 255)
{
BYTE cmd[2] = { 0, BYTE(delay) };
fwrite(cmd, 1, 2, File);
}
else
{
assert(delay <= 65535);
BYTE cmd[3] = { 1, BYTE(delay & 255), BYTE(delay >> 8) };
fwrite(cmd, 1, 3, File);
}
}
static_cast<OPLDump *>(chips[0])->WriteDelay(ticks);
}

View file

@ -195,25 +195,11 @@ struct DiskWriterIO : public OPLio
DiskWriterIO(const char *filename);
~DiskWriterIO();
int OPLinit(uint numchips, bool notused=false, bool notused2=false);
void OPLdeinit();
void OPLwriteReg(int which, uint reg, uchar data);
int OPLinit(uint numchips, bool notused, bool initopl3);
void SetClockRate(double samples_per_tick);
void WriteDelay(int ticks);
void SetChip(int chipnum);
FILE *File;
FString Filename;
int Format;
bool NeedClockRate;
double TimePerTick; // In milliseconds
double CurTime;
int CurIntTime;
int TickMul;
int CurChip;
enum { FMT_RDOS, FMT_DOSBOX };
};
struct musicBlock {

View file

@ -220,7 +220,8 @@ static int P_Set3DFloor(line_t * line, int param, int param2, int alpha)
int tag=line->args[0];
sector_t * sec = line->frontsector, * ss;
for (s=-1; (s = P_FindSectorFromTag(tag,s)) >= 0;)
FSectorTagIterator it(tag);
while ((s = it.Next()) >= 0)
{
ss=&sectors[s];
@ -488,7 +489,7 @@ void P_Recalculate3DFloors(sector_t * sector)
// by the clipping code below.
ffloors.Push(pick);
}
else if ((pick->flags&(FF_SWIMMABLE|FF_TRANSLUCENT) || (!(pick->flags&(FF_ALLSIDES|FF_BOTHPLANES)))) && pick->flags&FF_EXISTS)
else if ((pick->flags&(FF_SWIMMABLE|FF_TRANSLUCENT) || (!(pick->flags&FF_RENDERALL))) && pick->flags&FF_EXISTS)
{
// We must check if this nonsolid segment gets clipped from the top by another 3D floor
if (solid != NULL && solid_bottom < height)
@ -843,7 +844,7 @@ void P_Spawn3DFloors (void)
{
if (line->args[1]&8)
{
line->id = line->args[4];
line->SetMainId(line->args[4]);
}
else
{

View file

@ -143,7 +143,9 @@ void P_Attach3dMidtexLinesToSector(sector_t *sector, int lineid, int tag, bool c
if (tag == 0)
{
for(int line = -1; (line = P_FindLineFromID(lineid,line)) >= 0; )
FLineIdIterator itr(lineid);
int line;
while ((line = itr.Next()) >= 0)
{
line_t *ln = &lines[line];
@ -157,13 +159,15 @@ void P_Attach3dMidtexLinesToSector(sector_t *sector, int lineid, int tag, bool c
}
else
{
for(int sec = -1; (sec = P_FindSectorFromTag(tag, sec)) >= 0; )
FSectorTagIterator it(tag);
int sec;
while ((sec = it.Next()) >= 0)
{
for (int line = 0; line < sectors[sec].linecount; line ++)
{
line_t *ln = sectors[sec].lines[line];
if (lineid != 0 && ln->id != lineid) continue;
if (lineid != 0 && !ln->HasId(lineid)) continue;
if (ln->frontsector == NULL || ln->backsector == NULL || !(ln->flags & ML_3DMIDTEX))
{

View file

@ -1341,7 +1341,7 @@ DPlaneWatcher::DPlaneWatcher (AActor *it, line_t *line, int lineSide, bool ceili
{
int secnum;
secnum = P_FindSectorFromTag (tag, -1);
secnum = P_FindFirstSectorFromTag (tag);
if (secnum >= 0)
{
secplane_t plane;
@ -1409,12 +1409,6 @@ void DPlaneWatcher::Tick ()
// own behavior is loaded (if it has one).
void FBehavior::StaticLoadDefaultModules ()
{
// When playing Strife, STRFHELP is always loaded.
if (gameinfo.gametype == GAME_Strife)
{
StaticLoadModule (Wads.CheckNumForName ("STRFHELP", ns_acslibrary));
}
// Scan each LOADACS lump and load the specified modules in order
int lump, lastlump = 0;
@ -3216,7 +3210,7 @@ do_count:
if (actor->health > 0 &&
(kind == NULL || actor->IsA (kind)))
{
if (actor->Sector->tag == tag || tag == -1)
if (actor->Sector->HasTag(tag) || tag == -1)
{
// Don't count items in somebody's inventory
if (!actor->IsKindOf (RUNTIME_CLASS(AInventory)) ||
@ -3236,7 +3230,7 @@ do_count:
if (actor->health > 0 &&
(kind == NULL || actor->IsA (kind)))
{
if (actor->Sector->tag == tag || tag == -1)
if (actor->Sector->HasTag(tag) || tag == -1)
{
// Don't count items in somebody's inventory
if (!actor->IsKindOf (RUNTIME_CLASS(AInventory)) ||
@ -3273,7 +3267,8 @@ void DLevelScript::ChangeFlat (int tag, int name, bool floorOrCeiling)
flat = TexMan.GetTexture (flatname, FTexture::TEX_Flat, FTextureManager::TEXMAN_Overridable);
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
FSectorTagIterator it(tag);
while ((secnum = it.Next()) >= 0)
{
int pos = floorOrCeiling? sector_t::ceiling : sector_t::floor;
sectors[secnum].SetTexture(pos, flat);
@ -3304,7 +3299,8 @@ void DLevelScript::SetLineTexture (int lineid, int side, int position, int name)
texture = TexMan.GetTexture (texname, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable);
while ((linenum = P_FindLineFromID (lineid, linenum)) >= 0)
FLineIdIterator itr(lineid);
while ((linenum = itr.Next()) >= 0)
{
side_t *sidedef;
@ -4462,7 +4458,7 @@ int DLevelScript::SideFromID(int id, int side)
}
else
{
int line = P_FindLineFromID(id, -1);
int line = P_FindFirstLineFromID(id);
if (line == -1) return -1;
if (lines[line].sidedef[side] == NULL) return -1;
return lines[line].sidedef[side]->Index;
@ -4478,7 +4474,7 @@ int DLevelScript::LineFromID(int id)
}
else
{
return P_FindLineFromID(id, -1);
return P_FindFirstLineFromID(id);
}
}
@ -4837,10 +4833,10 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const
return 0; // Not implemented yet
case ACSF_GetSectorUDMFInt:
return GetUDMFInt(UDMF_Sector, P_FindSectorFromTag(args[0], -1), FBehavior::StaticLookupString(args[1]));
return GetUDMFInt(UDMF_Sector, P_FindFirstSectorFromTag(args[0]), FBehavior::StaticLookupString(args[1]));
case ACSF_GetSectorUDMFFixed:
return GetUDMFFixed(UDMF_Sector, P_FindSectorFromTag(args[0], -1), FBehavior::StaticLookupString(args[1]));
return GetUDMFFixed(UDMF_Sector, P_FindFirstSectorFromTag(args[0]), FBehavior::StaticLookupString(args[1]));
case ACSF_GetSideUDMFInt:
return GetUDMFInt(UDMF_Side, SideFromID(args[0], args[1]), FBehavior::StaticLookupString(args[2]));
@ -5167,11 +5163,11 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const
int space = args[2] < CHAN_FLOOR || args[2] > CHAN_INTERIOR ? CHAN_FULLHEIGHT : args[2];
if (seqname != NULL)
{
int secnum = -1;
while ((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0)
FSectorTagIterator it(args[0]);
int s;
while ((s = it.Next()) >= 0)
{
SN_StartSequence(&sectors[secnum], args[2], seqname, 0);
SN_StartSequence(&sectors[s], args[2], seqname, 0);
}
}
}
@ -5690,9 +5686,9 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
case ACSF_SetLineActivation:
if (argCount >= 2)
{
int line = -1;
while ((line = P_FindLineFromID(args[0], line)) >= 0)
int line;
FLineIdIterator itr(args[0]);
while ((line = itr.Next()) >= 0)
{
lines[line].activation = args[1];
}
@ -5702,7 +5698,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
case ACSF_GetLineActivation:
if (argCount > 0)
{
int line = P_FindLineFromID(args[0], -1);
int line = P_FindFirstLineFromID(args[0]);
return line >= 0 ? lines[line].activation : 0;
}
break;
@ -5950,11 +5946,13 @@ int DLevelScript::RunScript ()
// Wait for tagged sector(s) to go inactive, then enter
// state running
{
int secnum = -1;
while ((secnum = P_FindSectorFromTag (statedata, secnum)) >= 0)
int secnum;
FSectorTagIterator it(statedata);
while ((secnum = it.Next()) >= 0)
{
if (sectors[secnum].floordata || sectors[secnum].ceilingdata)
return resultValue;
}
// If we got here, none of the tagged sectors were busy
state = SCRIPT_Running;
@ -7994,9 +7992,10 @@ scriptwait:
case PCD_SETLINEBLOCKING:
{
int line = -1;
int line;
while ((line = P_FindLineFromID (STACK(2), line)) >= 0)
FLineIdIterator itr(STACK(2));
while ((line = itr.Next()) >= 0)
{
switch (STACK(1))
{
@ -8029,9 +8028,10 @@ scriptwait:
case PCD_SETLINEMONSTERBLOCKING:
{
int line = -1;
int line;
while ((line = P_FindLineFromID (STACK(2), line)) >= 0)
FLineIdIterator itr(STACK(2));
while ((line = itr.Next()) >= 0)
{
if (STACK(1))
lines[line].flags |= ML_BLOCKMONSTERS;
@ -8056,7 +8056,8 @@ scriptwait:
arg0 = -FName(FBehavior::StaticLookupString(arg0));
}
while ((linenum = P_FindLineFromID (STACK(7), linenum)) >= 0)
FLineIdIterator itr(STACK(7));
while ((linenum = itr.Next()) >= 0)
{
line_t *line = &lines[linenum];
line->special = specnum;
@ -8516,7 +8517,7 @@ scriptwait:
fixed_t z = 0;
if (tag != 0)
secnum = P_FindSectorFromTag (tag, -1);
secnum = P_FindFirstSectorFromTag (tag);
else
secnum = int(P_PointInSector (x, y) - sectors);
@ -8538,7 +8539,7 @@ scriptwait:
case PCD_GETSECTORLIGHTLEVEL:
{
int secnum = P_FindSectorFromTag (STACK(1), -1);
int secnum = P_FindFirstSectorFromTag (STACK(1));
int z = -1;
if (secnum >= 0)

View file

@ -781,14 +781,14 @@ vertex_t *FindVertex (fixed_t x, fixed_t y)
static void CreateStartSpot (fixed_t *pos, FMapThing *start)
{
short angle = LittleShort(*(WORD *)(&pos[3]));
FMapThing mt =
{
0, (LittleLong(pos[0])<<12), ((-LittleLong(pos[1]))<<12), 0,// tid, x, y, z
short(Scale ((2048-angle)&2047, 360, 2048)), DoomEdMap.CheckKey(1), 1, // angle, type
0, 0, // Skillfilter, Classfilter
7|MTF_SINGLE|224, // flags
0, {0}, 0 // special is 0, args and Conversation are 0
};
FMapThing mt = { 0, };
mt.x = LittleLong(pos[0])<<12;
mt.y = (-LittleLong(pos[1]))<<12;
mt.angle = short(Scale((2048-angle)&2047, 360, 2048));
mt.info = DoomEdMap.CheckKey(1);
mt.EdNum = 1;
mt.flags = 7|MTF_SINGLE|224;
*start = mt;
}

View file

@ -510,9 +510,9 @@ bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line,
P_ActivateInStasisCeiling (tag);
}
secnum = -1;
// affects all sectors with the same tag as the linedef
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
FSectorTagIterator it(tag);
while ((secnum = it.Next()) >= 0)
{
rtn |= !!DCeiling::Create(&sectors[secnum], type, line, tag, speed, speed2, height, crush, silent, change, hexencrush);
}

View file

@ -484,8 +484,8 @@ bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing,
else
{ // [RH] Remote door
secnum = -1;
while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0)
FSectorTagIterator it(tag);
while ((secnum = it.Next()) >= 0)
{
sec = &sectors[secnum];
// if the ceiling is already moving, don't start the door action
@ -812,7 +812,8 @@ bool EV_SlidingDoor (line_t *line, AActor *actor, int tag, int speed, int delay)
return false;
}
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
FSectorTagIterator it(tag);
while ((secnum = it.Next()) >= 0)
{
sec = &sectors[secnum];
if (sec->ceilingdata != NULL)

View file

@ -290,28 +290,13 @@ bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag,
rtn = false;
// check if a manual trigger; if so do just the sector on the backside
if (tag == 0)
{
if (!line || !(sec = line->backsector))
return rtn;
secnum = (int)(sec-sectors);
goto manual_floor;
}
secnum = -1;
while (tag && (secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
FSectorTagIterator it(tag, line);
while ((secnum = it.Next()) >= 0)
{
sec = &sectors[secnum];
manual_floor:
// ALREADY MOVING? IF SO, KEEP GOING...
if (sec->PlaneMoving(sector_t::floor))
{
// There was a test for 0/non-0 here, supposed to prevent 0-tags from executing "continue" and searching for unrelated sectors
// Unfortunately, the condition had been reversed, so that searches for tag-0 would continue,
// while numbered tags would abort (return false, even if some floors have been successfully triggered)
// All occurences of the condition (faulty or not) have been replaced by a looping condition: Looping only occurs if we're looking for a non-0 tag.
continue;
}
@ -545,9 +530,9 @@ manual_floor:
bool EV_FloorCrushStop (int tag)
{
int secnum = -1;
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
int secnum;
FSectorTagIterator it(tag);
while ((secnum = it.Next()) >= 0)
{
sector_t *sec = sectors + secnum;
@ -562,21 +547,6 @@ bool EV_FloorCrushStop (int tag)
return true;
}
//==========================================================================
//
// Linear tag search to emulate stair building from Doom.exe
//
//==========================================================================
static int P_FindSectorFromTagLinear (int tag, int start)
{
for (int i=start+1;i<numsectors;i++)
{
if (sectors[i].tag == tag) return i;
}
return -1;
}
//==========================================================================
//
// BUILD A STAIRCASE!
@ -591,7 +561,7 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line,
fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt,
int usespecials)
{
int secnum;
int secnum = -1;
int osecnum; //jff 3/4/98 save old loop index
int height;
fixed_t stairstep;
@ -607,44 +577,27 @@ bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line,
sector_t* prev = NULL;
DFloor* floor;
bool manual = false;
if (speed == 0)
return false;
persteptime = FixedDiv (stairsize, speed) >> FRACBITS;
int (* FindSector) (int tag, int start) =
(i_compatflags & COMPATF_STAIRINDEX)? P_FindSectorFromTagLinear : P_FindSectorFromTag;
// check if a manual trigger, if so do just the sector on the backside
if (tag == 0)
{
if (!line || !(sec = line->backsector))
return rtn;
secnum = (int)(sec-sectors);
manual = true;
goto manual_stair;
}
FSectorTagIterator itr(tag, line);
// The compatibility mode doesn't work with a hashing algorithm.
// It needs the original linear search method. This was broken in Boom.
secnum = -1;
while ((secnum = FindSector (tag, secnum)) >= 0)
bool compatible = tag != 0 && (i_compatflags & COMPATF_STAIRINDEX);
while ((secnum = itr.NextCompat(compatible, secnum)) >= 0)
{
sec = &sectors[secnum];
manual_stair:
// ALREADY MOVING? IF SO, KEEP GOING...
//jff 2/26/98 add special lockout condition to wait for entire
//staircase to build before retriggering
if (sec->PlaneMoving(sector_t::floor) || sec->stairlock)
{
if (!manual)
continue;
else
return rtn;
continue;
}
// new floor thinker
@ -781,14 +734,6 @@ manual_stair:
// [RH] make sure the first sector doesn't point to a previous one, otherwise
// it can infinite loop when the first sector stops moving.
sectors[osecnum].prevsec = -1;
if (manual)
{
return rtn;
}
if (!(i_compatflags & COMPATF_STAIRINDEX))
{
secnum = osecnum; //jff 3/4/98 restore loop index
}
}
return rtn;
}
@ -811,21 +756,13 @@ bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed)
vertex_t* spot;
fixed_t height;
secnum = -1;
rtn = false;
if (tag == 0)
{
if (!line || !(s1 = line->backsector))
return rtn;
goto manual_donut;
}
while (tag && (secnum = P_FindSectorFromTag(tag,secnum)) >= 0)
FSectorTagIterator itr(tag, line);
while ((secnum = itr.Next()) >= 0)
{
s1 = &sectors[secnum]; // s1 is pillar's sector
manual_donut:
// ALREADY MOVING? IF SO, KEEP GOING...
if (s1->PlaneMoving(sector_t::floor))
continue; // safe now, because we check that tag is non-0 in the looping condition [fdari]
@ -1042,19 +979,12 @@ bool EV_DoElevator (line_t *line, DElevator::EElevator elevtype,
secnum = -1;
rtn = false;
if (tag == 0)
{
if (!line || !(sec = line->backsector))
return rtn;
goto manual_elevator;
}
FSectorTagIterator itr(tag, line);
// act on all sectors with the same tag as the triggering linedef
while (tag && (secnum = P_FindSectorFromTag (tag, secnum)) >= 0) // never loop for a non-0 tag (condition moved to beginning of loop) [FDARI]
while ((secnum = itr.Next()) >= 0)
{
sec = &sectors[secnum];
manual_elevator:
// If either floor or ceiling is already activated, skip it
if (sec->PlaneMoving(sector_t::floor) || sec->ceilingdata) //jff 2/22/98
continue; // the loop used to break at the end if tag were 0, but would miss that step if "continue" occured [FDARI]
@ -1142,10 +1072,10 @@ bool EV_DoChange (line_t *line, EChange changetype, int tag)
sector_t *sec;
sector_t *secm;
secnum = -1;
rtn = false;
// change all sectors with the same tag as the linedef
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
FSectorTagIterator it(tag);
while ((secnum = it.Next()) >= 0)
{
sec = &sectors[secnum];
@ -1374,20 +1304,12 @@ bool EV_StartWaggle (int tag, line_t *line, int height, int speed, int offset,
bool retCode;
retCode = false;
sectorIndex = -1;
if (tag == 0)
{
if (!line || !(sector = line->backsector))
return retCode;
goto manual_waggle;
}
FSectorTagIterator itr(tag, line);
while (tag && (sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0)
while ((sectorIndex = itr.Next()) >= 0)
{
sector = &sectors[sectorIndex];
manual_waggle:
if ((!ceiling && sector->PlaneMoving(sector_t::floor)) ||
(ceiling && sector->PlaneMoving(sector_t::ceiling)))
{ // Already busy with another thinker

View file

@ -338,7 +338,14 @@ static bool LoadGLSegs(FileReader * lump)
ml->side=LittleShort(ml->side);
segs[i].sidedef = ldef->sidedef[ml->side];
segs[i].frontsector = ldef->sidedef[ml->side]->sector;
if (ldef->sidedef[ml->side] != NULL)
{
segs[i].frontsector = ldef->sidedef[ml->side]->sector;
}
else
{
segs[i].frontsector = NULL;
}
if (ldef->flags & ML_TWOSIDED && ldef->sidedef[ml->side^1] != NULL)
{
segs[i].backsector = ldef->sidedef[ml->side^1]->sector;
@ -346,7 +353,7 @@ static bool LoadGLSegs(FileReader * lump)
else
{
ldef->flags &= ~ML_TWOSIDED;
segs[i].backsector = 0;
segs[i].backsector = NULL;
}
}
@ -385,7 +392,14 @@ static bool LoadGLSegs(FileReader * lump)
ml->side=LittleShort(ml->side);
segs[i].sidedef = ldef->sidedef[ml->side];
segs[i].frontsector = ldef->sidedef[ml->side]->sector;
if (ldef->sidedef[ml->side] != NULL)
{
segs[i].frontsector = ldef->sidedef[ml->side]->sector;
}
else
{
segs[i].frontsector = NULL;
}
if (ldef->flags & ML_TWOSIDED && ldef->sidedef[ml->side^1] != NULL)
{
segs[i].backsector = ldef->sidedef[ml->side^1]->sector;
@ -393,7 +407,7 @@ static bool LoadGLSegs(FileReader * lump)
else
{
ldef->flags &= ~ML_TWOSIDED;
segs[i].backsector = 0;
segs[i].backsector = NULL;
}
}

View file

@ -189,9 +189,8 @@ DFlicker::DFlicker (sector_t *sector, int upper, int lower)
void EV_StartLightFlickering (int tag, int upper, int lower)
{
int secnum;
secnum = -1;
while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0)
FSectorTagIterator it(tag);
while ((secnum = it.Next()) >= 0)
{
new DFlicker (&sectors[secnum], upper, lower);
}
@ -359,9 +358,8 @@ DStrobe::DStrobe (sector_t *sector, int utics, int ltics, bool inSync)
void EV_StartLightStrobing (int tag, int upper, int lower, int utics, int ltics)
{
int secnum;
secnum = -1;
while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0)
FSectorTagIterator it(tag);
while ((secnum = it.Next()) >= 0)
{
sector_t *sec = &sectors[secnum];
if (sec->lightingdata)
@ -374,9 +372,8 @@ void EV_StartLightStrobing (int tag, int upper, int lower, int utics, int ltics)
void EV_StartLightStrobing (int tag, int utics, int ltics)
{
int secnum;
secnum = -1;
while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0)
FSectorTagIterator it(tag);
while ((secnum = it.Next()) >= 0)
{
sector_t *sec = &sectors[secnum];
if (sec->lightingdata)
@ -396,16 +393,14 @@ void EV_StartLightStrobing (int tag, int utics, int ltics)
void EV_TurnTagLightsOff (int tag)
{
int i;
int secnum;
// [RH] Don't do a linear search
for (secnum = -1; (secnum = P_FindSectorFromTag (tag, secnum)) >= 0; )
FSectorTagIterator it(tag);
while ((secnum = it.Next()) >= 0)
{
sector_t *sector = sectors + secnum;
int min = sector->lightlevel;
for (i = 0; i < sector->linecount; i++)
for (int i = 0; i < sector->linecount; i++)
{
sector_t *tsec = getNextSector (sector->lines[i],sector);
if (!tsec)
@ -427,10 +422,9 @@ void EV_TurnTagLightsOff (int tag)
void EV_LightTurnOn (int tag, int bright)
{
int secnum = -1;
// [RH] Don't do a linear search
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
int secnum;
FSectorTagIterator it(tag);
while ((secnum = it.Next()) >= 0)
{
sector_t *sector = sectors + secnum;
int tbright = bright; //jff 5/17/98 search for maximum PER sector
@ -480,15 +474,14 @@ void EV_LightTurnOn (int tag, int bright)
void EV_LightTurnOnPartway (int tag, fixed_t frac)
{
int i;
frac = clamp<fixed_t> (frac, 0, FRACUNIT);
// Search all sectors for ones with same tag as activating line
i = -1;
while ((i = P_FindSectorFromTag (tag, i)) >= 0)
int secnum;
FSectorTagIterator it(tag);
while ((secnum = it.Next()) >= 0)
{
sector_t *temp, *sector = sectors + i;
sector_t *temp, *sector = &sectors[secnum];
int j, bright = 0, min = sector->lightlevel;
for (j = 0; j < sector->linecount; ++j)
@ -520,9 +513,9 @@ void EV_LightTurnOnPartway (int tag, fixed_t frac)
void EV_LightChange (int tag, int value)
{
int secnum = -1;
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
int secnum;
FSectorTagIterator it(tag);
while ((secnum = it.Next()) >= 0)
{
sectors[secnum].SetLightLevel(sectors[secnum].lightlevel + value);
}
@ -681,8 +674,8 @@ void EV_StartLightGlowing (int tag, int upper, int lower, int tics)
lower = temp;
}
secnum = -1;
while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0)
FSectorTagIterator it(tag);
while ((secnum = it.Next()) >= 0)
{
sector_t *sec = &sectors[secnum];
if (sec->lightingdata)
@ -701,9 +694,8 @@ void EV_StartLightGlowing (int tag, int upper, int lower, int tics)
void EV_StartLightFading (int tag, int value, int tics)
{
int secnum;
secnum = -1;
while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0)
FSectorTagIterator it(tag);
while ((secnum = it.Next()) >= 0)
{
sector_t *sec = &sectors[secnum];
if (sec->lightingdata)
@ -846,7 +838,7 @@ void EV_StopLightEffect (int tag)
while ((effect = iterator.Next()) != NULL)
{
if (effect->GetSector()->tag == tag)
if (effect->GetSector()->HasTag(tag))
{
effect->Destroy();
}

View file

@ -278,7 +278,7 @@ static void RemoveTaggedSectors(extsector_t::linked::plane &scrollplane, int tag
{
for(int i = scrollplane.Sectors.Size()-1; i>=0; i--)
{
if (scrollplane.Sectors[i].Sector->tag == tag)
if (scrollplane.Sectors[i].Sector->HasTag(tag))
{
scrollplane.Sectors.Delete(i);
}
@ -316,7 +316,9 @@ bool P_AddSectorLinks(sector_t *control, int tag, INTBOOL ceiling, int movetype)
if (movetype > 0)
{
for(int sec = -1; (sec = P_FindSectorFromTag(tag, sec)) >= 0; )
int sec;
FSectorTagIterator itr(tag);
while ((sec = itr.Next()) >= 0)
{
// Don't attach to self!
if (control != &sectors[sec])
@ -346,7 +348,9 @@ void P_AddSectorLinksByID(sector_t *control, int id, INTBOOL ceiling)
{
extsector_t::linked::plane &scrollplane = ceiling? control->e->Linked.Ceiling : control->e->Linked.Floor;
for(int line = -1; (line = P_FindLineFromID(id, line)) >= 0; )
FLineIdIterator itr(id);
int line;
while ((line = itr.Next()) >= 0)
{
line_t *ld = &lines[line];

View file

@ -1266,7 +1266,7 @@ FUNC(LS_Thing_Destroy)
while (actor)
{
AActor *temp = iterator.Next ();
if (actor->flags & MF_SHOOTABLE && actor->Sector->tag == arg2)
if (actor->flags & MF_SHOOTABLE && actor->Sector->HasTag(arg2))
P_DamageMobj (actor, NULL, it, arg1 ? TELEFRAG_DAMAGE : actor->health, NAME_None);
actor = temp;
}
@ -1279,7 +1279,7 @@ FUNC(LS_Thing_Destroy)
while (actor)
{
AActor *temp = iterator.Next ();
if (actor->flags & MF_SHOOTABLE && (arg2 == 0 || actor->Sector->tag == arg2))
if (actor->flags & MF_SHOOTABLE && (arg2 == 0 || actor->Sector->HasTag(arg2)))
P_DamageMobj (actor, NULL, it, arg1 ? TELEFRAG_DAMAGE : actor->health, NAME_None);
actor = temp;
}
@ -1914,9 +1914,9 @@ FUNC(LS_Sector_ChangeSound)
if (!arg0)
return false;
secNum = -1;
rtn = false;
while ((secNum = P_FindSectorFromTag (arg0, secNum)) >= 0)
FSectorTagIterator itr(arg0);
while ((secNum = itr.Next()) >= 0)
{
sectors[secNum].seqType = arg1;
rtn = true;
@ -1933,9 +1933,9 @@ FUNC(LS_Sector_ChangeFlags)
if (!arg0)
return false;
secNum = -1;
rtn = false;
while ((secNum = P_FindSectorFromTag (arg0, secNum)) >= 0)
FSectorTagIterator itr(arg0);
while ((secNum = itr.Next()) >= 0)
{
sectors[secNum].Flags = (sectors[secNum].Flags | arg1) & ~arg2;
rtn = true;
@ -1969,10 +1969,11 @@ void AdjustPusher (int tag, int magnitude, int angle, DPusher::EPusher type)
}
size_t numcollected = Collection.Size ();
int secnum = -1;
int secnum;
// Now create pushers for any sectors that don't already have them.
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
FSectorTagIterator itr(tag);
while ((secnum = itr.Next()) >= 0)
{
unsigned int i;
for (i = 0; i < numcollected; i++)
@ -2020,9 +2021,9 @@ FUNC(LS_Sector_SetTranslucent)
{
if (arg0 != 0)
{
int secnum = -1;
while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0)
int secnum;
FSectorTagIterator itr(arg0);
while ((secnum = itr.Next()) >= 0)
{
sectors[secnum].SetAlpha(arg1, Scale(arg2, OPAQUE, 255));
sectors[secnum].ChangeFlags(arg1, ~PLANEF_ADDITIVE, arg3? PLANEF_ADDITIVE:0);
@ -2037,7 +2038,7 @@ FUNC(LS_Sector_SetLink)
{
if (arg0 != 0) // control tag == 0 is for static initialization and must not be handled here
{
int control = P_FindSectorFromTag(arg0, -1);
int control = P_FindFirstSectorFromTag(arg0);
if (control >= 0)
{
return P_AddSectorLinks(&sectors[control], arg1, arg2, arg3);
@ -2062,7 +2063,7 @@ static void SetWallScroller (int id, int sidechoice, fixed_t dx, fixed_t dy, int
{
int wallnum = scroller->GetWallNum ();
if (wallnum >= 0 && sides[wallnum].linedef->id == id &&
if (wallnum >= 0 && sides[wallnum].linedef->HasId(id) &&
int(sides[wallnum].linedef->sidedef[sidechoice] - sides) == wallnum &&
Where == scroller->GetScrollParts())
{
@ -2081,7 +2082,7 @@ static void SetWallScroller (int id, int sidechoice, fixed_t dx, fixed_t dy, int
while ( (collect.Obj = iterator.Next ()) )
{
if ((collect.RefNum = ((DScroller *)collect.Obj)->GetWallNum ()) != -1 &&
sides[collect.RefNum].linedef->id == id &&
sides[collect.RefNum].linedef->HasId(id) &&
int(sides[collect.RefNum].linedef->sidedef[sidechoice] - sides) == collect.RefNum &&
Where == ((DScroller *)collect.Obj)->GetScrollParts())
{
@ -2092,10 +2093,11 @@ static void SetWallScroller (int id, int sidechoice, fixed_t dx, fixed_t dy, int
}
size_t numcollected = Collection.Size ();
int linenum = -1;
int linenum;
// Now create scrollers for any walls that don't already have them.
while ((linenum = P_FindLineFromID (id, linenum)) >= 0)
FLineIdIterator itr(id);
while ((linenum = itr.Next()) >= 0)
{
if (lines[linenum].sidedef[sidechoice] != NULL)
{
@ -2167,7 +2169,7 @@ static void SetScroller (int tag, DScroller::EScrollType type, fixed_t dx, fixed
{
if (scroller->IsType (type))
{
if (sectors[scroller->GetAffectee ()].tag == tag)
if (sectors[scroller->GetAffectee ()].HasTag(tag))
{
i++;
scroller->SetRate (dx, dy);
@ -2181,7 +2183,8 @@ static void SetScroller (int tag, DScroller::EScrollType type, fixed_t dx, fixed
}
// Need to create scrollers for the sector(s)
for (i = -1; (i = P_FindSectorFromTag (tag, i)) >= 0; )
FSectorTagIterator itr(tag);
while ((i = itr.Next()) >= 0)
{
new DScroller (type, dx, dy, -1, i, 0);
}
@ -2240,8 +2243,10 @@ FUNC(LS_Sector_SetDamage)
// problems by adding an unwanted constructor.
// Since it doesn't really matter whether the type is translated
// here or in P_PlayerInSpecialSector I think it's the best solution.
int secnum = -1;
while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0) {
FSectorTagIterator itr(arg0);
int secnum;
while ((secnum = itr.Next()) >= 0)
{
sectors[secnum].damage = arg1;
sectors[secnum].mod = arg2;
}
@ -2251,14 +2256,15 @@ FUNC(LS_Sector_SetDamage)
FUNC(LS_Sector_SetGravity)
// Sector_SetGravity (tag, intpart, fracpart)
{
int secnum = -1;
float gravity;
if (arg2 > 99)
arg2 = 99;
gravity = (float)arg1 + (float)arg2 * 0.01f;
while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0)
FSectorTagIterator itr(arg0);
int secnum;
while ((secnum = itr.Next()) >= 0)
sectors[secnum].gravity = gravity;
return true;
@ -2267,9 +2273,9 @@ FUNC(LS_Sector_SetGravity)
FUNC(LS_Sector_SetColor)
// Sector_SetColor (tag, r, g, b, desaturate)
{
int secnum = -1;
while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0)
FSectorTagIterator itr(arg0);
int secnum;
while ((secnum = itr.Next()) >= 0)
{
sectors[secnum].SetColor(arg1, arg2, arg3, arg4);
}
@ -2280,9 +2286,9 @@ FUNC(LS_Sector_SetColor)
FUNC(LS_Sector_SetFade)
// Sector_SetFade (tag, r, g, b)
{
int secnum = -1;
while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0)
FSectorTagIterator itr(arg0);
int secnum;
while ((secnum = itr.Next()) >= 0)
{
sectors[secnum].SetFade(arg1, arg2, arg3);
}
@ -2292,11 +2298,12 @@ FUNC(LS_Sector_SetFade)
FUNC(LS_Sector_SetCeilingPanning)
// Sector_SetCeilingPanning (tag, x-int, x-frac, y-int, y-frac)
{
int secnum = -1;
fixed_t xofs = arg1 * FRACUNIT + arg2 * (FRACUNIT/100);
fixed_t yofs = arg3 * FRACUNIT + arg4 * (FRACUNIT/100);
while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0)
FSectorTagIterator itr(arg0);
int secnum;
while ((secnum = itr.Next()) >= 0)
{
sectors[secnum].SetXOffset(sector_t::ceiling, xofs);
sectors[secnum].SetYOffset(sector_t::ceiling, yofs);
@ -2307,11 +2314,12 @@ FUNC(LS_Sector_SetCeilingPanning)
FUNC(LS_Sector_SetFloorPanning)
// Sector_SetFloorPanning (tag, x-int, x-frac, y-int, y-frac)
{
int secnum = -1;
fixed_t xofs = arg1 * FRACUNIT + arg2 * (FRACUNIT/100);
fixed_t yofs = arg3 * FRACUNIT + arg4 * (FRACUNIT/100);
while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0)
FSectorTagIterator itr(arg0);
int secnum;
while ((secnum = itr.Next()) >= 0)
{
sectors[secnum].SetXOffset(sector_t::floor, xofs);
sectors[secnum].SetYOffset(sector_t::floor, yofs);
@ -2322,7 +2330,6 @@ FUNC(LS_Sector_SetFloorPanning)
FUNC(LS_Sector_SetFloorScale)
// Sector_SetFloorScale (tag, x-int, x-frac, y-int, y-frac)
{
int secnum = -1;
fixed_t xscale = arg1 * FRACUNIT + arg2 * (FRACUNIT/100);
fixed_t yscale = arg3 * FRACUNIT + arg4 * (FRACUNIT/100);
@ -2331,7 +2338,9 @@ FUNC(LS_Sector_SetFloorScale)
if (yscale)
yscale = FixedDiv (FRACUNIT, yscale);
while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0)
FSectorTagIterator itr(arg0);
int secnum;
while ((secnum = itr.Next()) >= 0)
{
if (xscale)
sectors[secnum].SetXScale(sector_t::floor, xscale);
@ -2344,7 +2353,6 @@ FUNC(LS_Sector_SetFloorScale)
FUNC(LS_Sector_SetCeilingScale)
// Sector_SetCeilingScale (tag, x-int, x-frac, y-int, y-frac)
{
int secnum = -1;
fixed_t xscale = arg1 * FRACUNIT + arg2 * (FRACUNIT/100);
fixed_t yscale = arg3 * FRACUNIT + arg4 * (FRACUNIT/100);
@ -2353,7 +2361,9 @@ FUNC(LS_Sector_SetCeilingScale)
if (yscale)
yscale = FixedDiv (FRACUNIT, yscale);
while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0)
FSectorTagIterator itr(arg0);
int secnum;
while ((secnum = itr.Next()) >= 0)
{
if (xscale)
sectors[secnum].SetXScale(sector_t::ceiling, xscale);
@ -2366,14 +2376,14 @@ FUNC(LS_Sector_SetCeilingScale)
FUNC(LS_Sector_SetFloorScale2)
// Sector_SetFloorScale2 (tag, x-factor, y-factor)
{
int secnum = -1;
if (arg1)
arg1 = FixedDiv (FRACUNIT, arg1);
if (arg2)
arg2 = FixedDiv (FRACUNIT, arg2);
while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0)
FSectorTagIterator itr(arg0);
int secnum;
while ((secnum = itr.Next()) >= 0)
{
if (arg1)
sectors[secnum].SetXScale(sector_t::floor, arg1);
@ -2386,14 +2396,14 @@ FUNC(LS_Sector_SetFloorScale2)
FUNC(LS_Sector_SetCeilingScale2)
// Sector_SetFloorScale2 (tag, x-factor, y-factor)
{
int secnum = -1;
if (arg1)
arg1 = FixedDiv (FRACUNIT, arg1);
if (arg2)
arg2 = FixedDiv (FRACUNIT, arg2);
while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0)
FSectorTagIterator itr(arg0);
int secnum;
while ((secnum = itr.Next()) >= 0)
{
if (arg1)
sectors[secnum].SetXScale(sector_t::ceiling, arg1);
@ -2406,11 +2416,12 @@ FUNC(LS_Sector_SetCeilingScale2)
FUNC(LS_Sector_SetRotation)
// Sector_SetRotation (tag, floor-angle, ceiling-angle)
{
int secnum = -1;
angle_t ceiling = arg2 * ANGLE_1;
angle_t floor = arg1 * ANGLE_1;
while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0)
FSectorTagIterator itr(arg0);
int secnum;
while ((secnum = itr.Next()) >= 0)
{
sectors[secnum].SetAngle(sector_t::floor, floor);
sectors[secnum].SetAngle(sector_t::ceiling, ceiling);
@ -2421,30 +2432,28 @@ FUNC(LS_Sector_SetRotation)
FUNC(LS_Line_AlignCeiling)
// Line_AlignCeiling (lineid, side)
{
int line = P_FindLineFromID (arg0, -1);
bool ret = 0;
if (line < 0)
I_Error ("Sector_AlignCeiling: Lineid %d is undefined", arg0);
do
FLineIdIterator itr(arg0);
int line;
while ((line = itr.Next()) >= 0)
{
ret |= P_AlignFlat (line, !!arg1, 1);
} while ( (line = P_FindLineFromID (arg0, line)) >= 0);
}
return ret;
}
FUNC(LS_Line_AlignFloor)
// Line_AlignFloor (lineid, side)
{
int line = P_FindLineFromID (arg0, -1);
bool ret = 0;
if (line < 0)
I_Error ("Sector_AlignFloor: Lineid %d is undefined", arg0);
do
FLineIdIterator itr(arg0);
int line;
while ((line = itr.Next()) >= 0)
{
ret |= P_AlignFlat (line, !!arg1, 0);
} while ( (line = P_FindLineFromID (arg0, line)) >= 0);
}
return ret;
}
@ -2456,7 +2465,9 @@ FUNC(LS_Line_SetTextureOffset)
if (arg0 == 0 || arg3 < 0 || arg3 > 1)
return false;
for(int line = -1; (line = P_FindLineFromID (arg0, line)) >= 0; )
FLineIdIterator itr(arg0);
int line;
while ((line = itr.Next()) >= 0)
{
side_t *side = lines[line].sidedef[arg3];
if (side != NULL)
@ -2507,7 +2518,9 @@ FUNC(LS_Line_SetTextureScale)
if (arg0 == 0 || arg3 < 0 || arg3 > 1)
return false;
for(int line = -1; (line = P_FindLineFromID (arg0, line)) >= 0; )
FLineIdIterator itr(arg0);
int line;
while ((line = itr.Next()) >= 0)
{
side_t *side = lines[line].sidedef[arg3];
if (side != NULL)
@ -2578,7 +2591,9 @@ FUNC(LS_Line_SetBlocking)
if (arg2 & 1) clearflags |= flagtrans[i];
}
for(int line = -1; (line = P_FindLineFromID (arg0, line)) >= 0; )
FLineIdIterator itr(arg0);
int line;
while ((line = itr.Next()) >= 0)
{
lines[line].flags = (lines[line].flags & ~clearflags) | setflags;
}
@ -2871,8 +2886,9 @@ FUNC(LS_SetPlayerProperty)
FUNC(LS_TranslucentLine)
// TranslucentLine (id, amount, type)
{
int linenum = -1;
while ((linenum = P_FindLineFromID (arg0, linenum)) >= 0)
FLineIdIterator itr(arg0);
int linenum;
while ((linenum = itr.Next()) >= 0)
{
lines[linenum].Alpha = Scale(clamp(arg1, 0, 255), FRACUNIT, 255);
if (arg2 == 0)
@ -2997,10 +3013,11 @@ FUNC(LS_ForceField)
FUNC(LS_ClearForceField)
// ClearForceField (tag)
{
int secnum = -1;
bool rtn = false;
while ((secnum = P_FindSectorFromTag (arg0, secnum)) >= 0)
FSectorTagIterator itr(arg0);
int secnum;
while ((secnum = itr.Next()) >= 0)
{
sector_t *sec = &sectors[secnum];
rtn = true;

View file

@ -3545,7 +3545,7 @@ void AActor::Tick ()
}
else if (scrolltype == Scroll_StrifeCurrent)
{ // Strife scroll special
int anglespeed = sec->tag - 100;
int anglespeed = sec->GetMainTag() - 100;
fixed_t carryspeed = DivScale32 (anglespeed % 10, 16*CARRYFACTOR);
angle_t fineangle = (anglespeed / 10) << (32-3);
fineangle >>= ANGLETOFINESHIFT;
@ -4725,9 +4725,9 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
}
// copy args to mapthing so that we have them in one place for the rest of this function
if (mentry->Special >= 0)
if (mentry->ArgsDefined)
{
mthing->special = mentry->Special;
if (mentry->Type!= NULL) mthing->special = mentry->Special;
memcpy(mthing->args, mentry->Args, sizeof(mthing->args));
}

View file

@ -220,20 +220,11 @@ bool EV_DoPillar (DPillar::EPillar type, line_t *line, int tag,
bool rtn = false;
// check if a manual trigger; if so do just the sector on the backside
if (tag == 0)
{
if (!line || !(sec = line->backsector))
return rtn;
secnum = (int)(sec-sectors);
goto manual_pillar;
}
secnum = -1;
while (tag && (secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
FSectorTagIterator itr(tag, line);
while ((secnum = itr.Next()) >= 0)
{
sec = &sectors[secnum];
manual_pillar:
if (sec->PlaneMoving(sector_t::floor) || sec->PlaneMoving(sector_t::ceiling))
continue;

View file

@ -233,42 +233,33 @@ bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type, int height,
fixed_t newheight = 0;
vertex_t *spot;
if (tag != 0)
{
// Activate all <type> plats that are in_stasis
switch (type)
{
case DPlat::platToggle:
rtn = true;
case DPlat::platPerpetualRaise:
P_ActivateInStasis (tag);
break;
default:
break;
}
}
// [RH] If tag is zero, use the sector on the back side
// of the activating line (if any).
if (!tag)
{
if (!line || !(sec = line->backsector))
return false;
secnum = (int)(sec - sectors);
manual = true;
goto manual_plat;
}
// Activate all <type> plats that are in_stasis
switch (type)
{
case DPlat::platToggle:
rtn = true;
case DPlat::platPerpetualRaise:
P_ActivateInStasis (tag);
break;
default:
break;
}
secnum = -1;
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
FSectorTagIterator itr(tag, line);
while ((secnum = itr.Next()) >= 0)
{
sec = &sectors[secnum];
manual_plat:
if (sec->PlaneMoving(sector_t::floor))
{
if (!manual)
continue;
else
return false;
continue;
}
// Find lowest & highest floors around sector
@ -406,8 +397,6 @@ manual_plat:
default:
break;
}
if (manual)
return rtn;
}
return rtn;
}

View file

@ -825,6 +825,77 @@ sector_t *sector_t::GetHeightSec() const
}
bool sector_t::HasTag(int checktag) const
{
return tag == checktag;
}
bool sector_t::HasTags() const
{
return tag != 0;
}
void sector_t::SetMainTag(int tagnum)
{
tag = tagnum;
}
int sector_t::GetMainTag() const
{
return tag;
}
void sector_t::ClearTags()
{
tag = 0;
}
void sector_t::HashTags()
{
int i;
for (i=numsectors; --i>=0; ) // Initially make all slots empty.
sectors[i].firsttag = -1;
for (i=numsectors; --i>=0; ) // Proceed from last to first sector
{ // so that lower sectors appear first
int j = (unsigned) sectors[i].tag % (unsigned) numsectors; // Hash func
sectors[i].nexttag = sectors[j].firsttag; // Prepend sector to chain
sectors[j].firsttag = i;
}
}
void line_t::SetMainId(int newid)
{
id = newid;
}
void line_t::ClearIds()
{
id = -1;
}
bool line_t::HasId(int checkid) const
{
return id == checkid;
}
void line_t::HashIds()
{
// killough 4/17/98: same thing, only for linedefs
int i;
for (i=numlines; --i>=0; ) // Initially make all slots empty.
lines[i].firstid = -1;
for (i=numlines; --i>=0; ) // Proceed from last to first linedef
{ // so that lower linedefs appear first
int j = (unsigned) lines[i].id % (unsigned) numlines; // Hash func
lines[i].nextid = lines[j].firstid; // Prepend linedef to chain
lines[j].firstid = i;
}
}
bool secplane_t::CopyPlaneIfValid (secplane_t *dest, const secplane_t *opp) const
{
bool copy = false;

View file

@ -96,7 +96,6 @@ CVAR (Bool, gennodes, false, CVAR_SERVERINFO|CVAR_GLOBALCONFIG);
CVAR (Bool, genglnodes, false, CVAR_SERVERINFO);
CVAR (Bool, showloadtimes, false, 0);
static void P_InitTagLists ();
static void P_Shutdown ();
bool P_IsBuildMap(MapData *map);
@ -1514,7 +1513,7 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex)
else // [RH] Translate to new sector special
ss->special = P_TranslateSectorSpecial (LittleShort(ms->special));
ss->secretsector = !!(ss->special&SECRET_MASK);
ss->tag = LittleShort(ms->tag);
ss->SetMainTag(LittleShort(ms->tag));
ss->thinglist = NULL;
ss->touching_thinglist = NULL; // phares 3/14/98
ss->seqType = defSeqType;
@ -1917,40 +1916,40 @@ void P_SetLineID (line_t *ld)
case Line_SetIdentification:
if (!(level.flags2 & LEVEL2_HEXENHACK))
{
ld->id = ld->args[0] + 256 * ld->args[4];
ld->SetMainId(ld->args[0] + 256 * ld->args[4]);
ld->flags |= ld->args[1]<<16;
}
else
{
ld->id = ld->args[0];
ld->SetMainId(ld->args[0]);
}
ld->special = 0;
break;
case TranslucentLine:
ld->id = ld->args[0];
ld->SetMainId(ld->args[0]);
ld->flags |= ld->args[3]<<16;
break;
case Teleport_Line:
case Scroll_Texture_Model:
ld->id = ld->args[0];
ld->SetMainId(ld->args[0]);
break;
case Polyobj_StartLine:
ld->id = ld->args[3];
ld->SetMainId(ld->args[3]);
break;
case Polyobj_ExplicitLine:
ld->id = ld->args[4];
ld->SetMainId(ld->args[4]);
break;
case Plane_Align:
ld->id = ld->args[2];
ld->SetMainId(ld->args[2]);
break;
case Static_Init:
if (ld->args[1] == Init_SectorLink) ld->id = ld->args[0];
if (ld->args[1] == Init_SectorLink) ld->SetMainId(ld->args[0]);
break;
}
}
@ -2035,7 +2034,7 @@ void P_FinishLoadingLineDef(line_t *ld, int alpha)
{
for (j = 0; j < numlines; j++)
{
if (lines[j].id == ld->args[0])
if (lines[j].HasId(ld->args[0]))
{
lines[j].Alpha = alpha;
if (additive)
@ -2143,11 +2142,10 @@ void P_LoadLineDefs (MapData * map)
// [RH] Translate old linedef special and flags to be
// compatible with the new format.
P_TranslateLineDef (ld, mld);
P_TranslateLineDef (ld, mld, true);
ld->v1 = &vertexes[LittleShort(mld->v1)];
ld->v2 = &vertexes[LittleShort(mld->v2)];
//ld->id = -1; ID has been assigned in P_TranslateLineDef
P_SetSideNum (&ld->sidedef[0], LittleShort(mld->sidenum[0]));
P_SetSideNum (&ld->sidedef[1], LittleShort(mld->sidenum[1]));
@ -2230,7 +2228,7 @@ void P_LoadLineDefs2 (MapData * map)
ld->v1 = &vertexes[LittleShort(mld->v1)];
ld->v2 = &vertexes[LittleShort(mld->v2)];
ld->Alpha = FRACUNIT; // [RH] Opaque by default
ld->id = -1;
ld->ClearIds();
P_SetSideNum (&ld->sidedef[0], LittleShort(mld->sidenum[0]));
P_SetSideNum (&ld->sidedef[1], LittleShort(mld->sidenum[1]));
@ -2492,7 +2490,7 @@ void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, intmaps
for (s = 0; s < numsectors; s++)
{
if (sectors[s].tag == tag)
if (sectors[s].HasTag(tag))
{
if (!colorgood) color = sectors[s].ColorMap->Color;
if (!foggood) fog = sectors[s].ColorMap->Fade;
@ -3128,9 +3126,9 @@ static void P_GroupLines (bool buildmap)
{
if (sector->linecount == 0)
{
Printf ("Sector %i (tag %i) has no lines\n", i, sector->tag);
Printf ("Sector %i (tag %i) has no lines\n", i, sector->GetMainTag());
// 0 the sector's tag so that no specials can use it
sector->tag = 0;
sector->ClearTags();
}
else
{
@ -3206,7 +3204,9 @@ static void P_GroupLines (bool buildmap)
// [RH] Moved this here
times[4].Clock();
P_InitTagLists(); // killough 1/30/98: Create xref tables for tags
// killough 1/30/98: Create xref tables for tags
sector_t::HashTags();
line_t::HashIds();
times[4].Unclock();
times[5].Clock();
@ -3303,32 +3303,6 @@ void P_LoadBehavior (MapData * map)
}
}
// Hash the sector tags across the sectors and linedefs.
static void P_InitTagLists ()
{
int i;
for (i=numsectors; --i>=0; ) // Initially make all slots empty.
sectors[i].firsttag = -1;
for (i=numsectors; --i>=0; ) // Proceed from last to first sector
{ // so that lower sectors appear first
int j = (unsigned) sectors[i].tag % (unsigned) numsectors; // Hash func
sectors[i].nexttag = sectors[j].firsttag; // Prepend sector to chain
sectors[j].firsttag = i;
}
// killough 4/17/98: same thing, only for linedefs
for (i=numlines; --i>=0; ) // Initially make all slots empty.
lines[i].firstid = -1;
for (i=numlines; --i>=0; ) // Proceed from last to first linedef
{ // so that lower linedefs appear first
int j = (unsigned) lines[i].id % (unsigned) numlines; // Hash func
lines[i].nextid = lines[j].firstid; // Prepend linedef to chain
lines[j].firstid = i;
}
}
void P_GetPolySpots (MapData * map, TArray<FNodeBuilder::FPolyStart> &spots, TArray<FNodeBuilder::FPolyStart> &anchors)
{
if (map->HasBehavior)

View file

@ -115,7 +115,7 @@ struct line_t;
struct maplinedef_t;
void P_LoadTranslator(const char *lumpname);
void P_TranslateLineDef (line_t *ld, maplinedef_t *mld);
void P_TranslateLineDef (line_t *ld, maplinedef_t *mld, bool setlineid);
int P_TranslateSectorSpecial (int);
int GetUDMFInt(int type, int index, const char *key);

View file

@ -45,9 +45,10 @@
static void P_SlopeLineToPoint (int lineid, fixed_t x, fixed_t y, fixed_t z, bool slopeCeil)
{
int linenum = -1;
int linenum;
while ((linenum = P_FindLineFromID (lineid, linenum)) != -1)
FLineIdIterator itr(lineid);
while ((linenum = itr.Next()) >= 0)
{
const line_t *line = &lines[linenum];
sector_t *sec;
@ -123,7 +124,7 @@ static void P_CopyPlane (int tag, sector_t *dest, bool copyCeil)
int secnum;
size_t planeofs;
secnum = P_FindSectorFromTag (tag, -1);
secnum = P_FindFirstSectorFromTag (tag);
if (secnum == -1)
{
return;

View file

@ -195,29 +195,48 @@ bool CheckIfExitIsGood (AActor *self, level_info_t *info)
// Find the next sector with a specified tag.
// Rewritten by Lee Killough to use chained hashing to improve speed
int P_FindSectorFromTag (int tag, int start)
int FSectorTagIterator::Next()
{
start = start >= 0 ? sectors[start].nexttag :
sectors[(unsigned) tag % (unsigned) numsectors].firsttag;
while (start >= 0 && sectors[start].tag != tag)
int ret;
if (searchtag == INT_MIN)
{
ret = start;
start = -1;
}
else
{
while (start != -1 && sectors[start].tag != searchtag) start = sectors[start].nexttag;
if (start == -1) return -1;
ret = start;
start = sectors[start].nexttag;
return start;
}
return ret;
}
int FSectorTagIterator::NextCompat(bool compat, int start)
{
if (!compat) return Next();
for (int i = start + 1; i < numsectors; i++)
{
if (sectors[i].HasTag(searchtag)) return i;
}
return -1;
}
// killough 4/16/98: Same thing, only for linedefs
int P_FindLineFromID (int id, int start)
int FLineIdIterator::Next()
{
start = start >= 0 ? lines[start].nextid :
lines[(unsigned) id % (unsigned) numlines].firstid;
while (start >= 0 && lines[start].id != id)
start = lines[start].nextid;
return start;
while (start != -1 && lines[start].id != searchtag) start = lines[start].nextid;
if (start == -1) return -1;
int ret = start;
start = lines[start].nextid;
return ret;
}
//============================================================================
//
// P_ActivateLine
@ -260,13 +279,13 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType)
}
// some old WADs use this method to create walls that change the texture when shot.
else if (activationType == SPAC_Impact && // only for shootable triggers
(level.flags2 & LEVEL2_DUMMYSWITCHES) && // this is only a compatibility setting for an old hack!
(level.flags2 & LEVEL2_DUMMYSWITCHES) && // this is only a compatibility setting for an old hack!
!repeat && // only non-repeatable triggers
(special<Generic_Floor || special>Generic_Crusher) && // not for Boom's generalized linedefs
special && // not for lines without a special
line->args[0] == line->id && // Safety check: exclude edited UDMF linedefs or ones that don't map the tag to args[0]
line->HasId(line->args[0]) && // Safety check: exclude edited UDMF linedefs or ones that don't map the tag to args[0]
line->args[0] && // only if there's a tag (which is stored in the first arg)
P_FindSectorFromTag (line->args[0], -1) == -1) // only if no sector is tagged to this linedef
P_FindFirstSectorFromTag (line->args[0]) == -1) // only if no sector is tagged to this linedef
{
P_ChangeSwitchTexture (line->sidedef[0], repeat, special);
line->special = 0;
@ -657,9 +676,9 @@ static void DoSectorDamage(AActor *actor, sector_t *sec, int amount, FName type,
void P_SectorDamage(int tag, int amount, FName type, PClassActor *protectClass, int flags)
{
int secnum = -1;
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
FSectorTagIterator itr(tag);
int secnum;
while ((secnum = itr.Next()) >= 0)
{
AActor *actor, *next;
sector_t *sec = &sectors[secnum];
@ -884,12 +903,14 @@ DLightTransfer::DLightTransfer (sector_t *srcSec, int target, bool copyFloor)
if (copyFloor)
{
for (secnum = -1; (secnum = P_FindSectorFromTag (target, secnum)) >= 0; )
FSectorTagIterator itr(target);
while ((secnum = itr.Next()) >= 0)
sectors[secnum].ChangeFlags(sector_t::floor, 0, PLANEF_ABSLIGHTING);
}
else
{
for (secnum = -1; (secnum = P_FindSectorFromTag (target, secnum)) >= 0; )
FSectorTagIterator itr(target);
while ((secnum = itr.Next()) >= 0)
sectors[secnum].ChangeFlags(sector_t::ceiling, 0, PLANEF_ABSLIGHTING);
}
ChangeStatNum (STAT_LIGHTTRANSFER);
@ -912,12 +933,14 @@ void DLightTransfer::DoTransfer (int level, int target, bool floor)
if (floor)
{
for (secnum = -1; (secnum = P_FindSectorFromTag (target, secnum)) >= 0; )
FSectorTagIterator itr(target);
while ((secnum = itr.Next()) >= 0)
sectors[secnum].SetPlaneLight(sector_t::floor, level);
}
else
{
for (secnum = -1; (secnum = P_FindSectorFromTag (target, secnum)) >= 0; )
FSectorTagIterator itr(target);
while ((secnum = itr.Next()) >= 0)
sectors[secnum].SetPlaneLight(sector_t::ceiling, level);
}
}
@ -985,7 +1008,8 @@ DWallLightTransfer::DWallLightTransfer (sector_t *srcSec, int target, BYTE flags
wallflags = WALLF_ABSLIGHTING | WALLF_NOFAKECONTRAST;
}
for (linenum = -1; (linenum = P_FindLineFromID (target, linenum)) >= 0; )
FLineIdIterator itr(target);
while ((linenum = itr.Next()) >= 0)
{
if (flags & WLF_SIDE1 && lines[linenum].sidedef[0] != NULL)
{
@ -1015,7 +1039,8 @@ void DWallLightTransfer::DoTransfer (short lightlevel, int target, BYTE flags)
{
int linenum;
for (linenum = -1; (linenum = P_FindLineFromID (target, linenum)) >= 0; )
FLineIdIterator itr(target);
while ((linenum = itr.Next()) >= 0)
{
line_t *line = &lines[linenum];
@ -1173,7 +1198,9 @@ void P_SpawnPortal(line_t *line, int sectortag, int plane, int alpha)
reference->flags |= MF_JUSTATTACKED;
anchor->flags |= MF_JUSTATTACKED;
for (int s=-1; (s = P_FindSectorFromTag(sectortag,s)) >= 0;)
int s;
FSectorTagIterator itr(sectortag);
while ((s = itr.Next()) >= 0)
{
SetPortal(&sectors[s], plane, reference, alpha);
}
@ -1193,7 +1220,8 @@ void P_SpawnPortal(line_t *line, int sectortag, int plane, int alpha)
}
else
{
for (int s=-1; (s = P_FindSectorFromTag(lines[j].args[0],s)) >= 0;)
FSectorTagIterator itr(lines[j].args[0]);
while ((s = itr.Next()) >= 0)
{
SetPortal(&sectors[s], plane, reference, alpha);
}
@ -1374,38 +1402,41 @@ void P_SpawnSpecials (void)
// killough 3/7/98:
// support for drawn heights coming from different sector
case Transfer_Heights:
sec = lines[i].frontsector;
if (lines[i].args[1] & 2)
{
sec->MoreFlags |= SECF_FAKEFLOORONLY;
sec = lines[i].frontsector;
if (lines[i].args[1] & 2)
{
sec->MoreFlags |= SECF_FAKEFLOORONLY;
}
if (lines[i].args[1] & 4)
{
sec->MoreFlags |= SECF_CLIPFAKEPLANES;
}
if (lines[i].args[1] & 8)
{
sec->MoreFlags |= SECF_UNDERWATER;
}
else if (forcewater)
{
sec->MoreFlags |= SECF_FORCEDUNDERWATER;
}
if (lines[i].args[1] & 16)
{
sec->MoreFlags |= SECF_IGNOREHEIGHTSEC;
}
if (lines[i].args[1] & 32)
{
sec->MoreFlags |= SECF_NOFAKELIGHT;
}
FSectorTagIterator itr(lines[i].args[0]);
while ((s = itr.Next()) >= 0)
{
sectors[s].heightsec = sec;
sec->e->FakeFloor.Sectors.Push(&sectors[s]);
sectors[s].AdjustFloorClip();
}
break;
}
if (lines[i].args[1] & 4)
{
sec->MoreFlags |= SECF_CLIPFAKEPLANES;
}
if (lines[i].args[1] & 8)
{
sec->MoreFlags |= SECF_UNDERWATER;
}
else if (forcewater)
{
sec->MoreFlags |= SECF_FORCEDUNDERWATER;
}
if (lines[i].args[1] & 16)
{
sec->MoreFlags |= SECF_IGNOREHEIGHTSEC;
}
if (lines[i].args[1] & 32)
{
sec->MoreFlags |= SECF_NOFAKELIGHT;
}
for (s = -1; (s = P_FindSectorFromTag(lines[i].args[0],s)) >= 0;)
{
sectors[s].heightsec = sec;
sec->e->FakeFloor.Sectors.Push(&sectors[s]);
sectors[s].AdjustFloorClip();
}
break;
// killough 3/16/98: Add support for setting
// floor lighting independently (e.g. lava)
@ -1458,9 +1489,10 @@ void P_SpawnSpecials (void)
{
case Init_Gravity:
{
float grav = ((float)P_AproxDistance (lines[i].dx, lines[i].dy)) / (FRACUNIT * 100.0f);
for (s = -1; (s = P_FindSectorFromTag(lines[i].args[0],s)) >= 0;)
sectors[s].gravity = grav;
float grav = ((float)P_AproxDistance (lines[i].dx, lines[i].dy)) / (FRACUNIT * 100.0f);
FSectorTagIterator itr(lines[i].args[0]);
while ((s = itr.Next()) >= 0)
sectors[s].gravity = grav;
}
break;
@ -1470,7 +1502,8 @@ void P_SpawnSpecials (void)
case Init_Damage:
{
int damage = P_AproxDistance (lines[i].dx, lines[i].dy) >> FRACBITS;
for (s = -1; (s = P_FindSectorFromTag(lines[i].args[0],s)) >= 0;)
FSectorTagIterator itr(lines[i].args[0]);
while ((s = itr.Next()) >= 0)
{
sectors[s].damage = damage;
sectors[s].mod = 0;//MOD_UNKNOWN;
@ -1493,9 +1526,12 @@ void P_SpawnSpecials (void)
// or ceiling texture, to distinguish floor and ceiling sky.
case Init_TransferSky:
for (s = -1; (s = P_FindSectorFromTag(lines[i].args[0],s)) >= 0;)
sectors[s].sky = (i+1) | PL_SKYFLAT;
break;
{
FSectorTagIterator itr(lines[i].args[0]);
while ((s = itr.Next()) >= 0)
sectors[s].sky = (i + 1) | PL_SKYFLAT;
break;
}
}
break;
}
@ -1756,7 +1792,7 @@ static void P_SpawnScrollers(void)
if (lines[i].special == Sector_CopyScroller)
{
// don't allow copying the scroller if the sector has the same tag as it would just duplicate it.
if (lines[i].args[0] != lines[i].frontsector->tag)
if (lines[i].frontsector->HasTag(lines[i].args[0]))
{
copyscrollers.Push(i);
}
@ -1832,25 +1868,29 @@ static void P_SpawnScrollers(void)
register int s;
case Scroll_Ceiling:
for (s=-1; (s = P_FindSectorFromTag (l->args[0],s)) >= 0;)
{
FSectorTagIterator itr(l->args[0]);
while ((s = itr.Next()) >= 0)
{
new DScroller (DScroller::sc_ceiling, -dx, dy, control, s, accel);
new DScroller(DScroller::sc_ceiling, -dx, dy, control, s, accel);
}
for(unsigned j = 0;j < copyscrollers.Size(); j++)
for (unsigned j = 0; j < copyscrollers.Size(); j++)
{
line_t *line = &lines[copyscrollers[j]];
if (line->args[0] == l->args[0] && (line->args[1] & 1))
{
new DScroller (DScroller::sc_ceiling, -dx, dy, control, int(line->frontsector-sectors), accel);
new DScroller(DScroller::sc_ceiling, -dx, dy, control, int(line->frontsector - sectors), accel);
}
}
break;
}
case Scroll_Floor:
if (l->args[2] != 1)
{ // scroll the floor texture
for (s=-1; (s = P_FindSectorFromTag (l->args[0],s)) >= 0;)
FSectorTagIterator itr(l->args[0]);
while ((s = itr.Next()) >= 0)
{
new DScroller (DScroller::sc_floor, -dx, dy, control, s, accel);
}
@ -1867,7 +1907,8 @@ static void P_SpawnScrollers(void)
if (l->args[2] > 0)
{ // carry objects on the floor
for (s=-1; (s = P_FindSectorFromTag (l->args[0],s)) >= 0;)
FSectorTagIterator itr(l->args[0]);
while ((s = itr.Next()) >= 0)
{
new DScroller (DScroller::sc_carry, dx, dy, control, s, accel);
}
@ -1886,10 +1927,15 @@ static void P_SpawnScrollers(void)
// killough 3/1/98: scroll wall according to linedef
// (same direction and speed as scrolling floors)
case Scroll_Texture_Model:
for (s=-1; (s = P_FindLineFromID (l->args[0],s)) >= 0;)
{
FLineIdIterator itr(l->args[0]);
while ((s = itr.Next()) >= 0)
{
if (s != i)
new DScroller (dx, dy, lines+s, control, accel);
new DScroller(dx, dy, lines + s, control, accel);
}
break;
}
case Scroll_Texture_Offsets:
// killough 3/2/98: scroll according to sidedef offsets
@ -2041,7 +2087,8 @@ void P_SetSectorFriction (int tag, int amount, bool alterFlag)
// higher friction value actually means 'less friction'.
movefactor = FrictionToMoveFactor(friction);
for (s = -1; (s = P_FindSectorFromTag (tag,s)) >= 0; )
FSectorTagIterator itr(tag);
while ((s = itr.Next()) >= 0)
{
// killough 8/28/98:
//
@ -2153,7 +2200,7 @@ DPusher::DPusher (DPusher::EPusher type, line_t *l, int magnitude, int angle,
int DPusher::CheckForSectorMatch (EPusher type, int tag)
{
if (m_Type == type && sectors[m_Affectee].tag == tag)
if (m_Type == type && sectors[m_Affectee].HasTag(tag))
return m_Affectee;
else
return -1;
@ -2356,20 +2403,27 @@ static void P_SpawnPushers ()
switch (l->special)
{
case Sector_SetWind: // wind
for (s = -1; (s = P_FindSectorFromTag (l->args[0],s)) >= 0 ; )
new DPusher (DPusher::p_wind, l->args[3] ? l : NULL, l->args[1], l->args[2], NULL, s);
{
FSectorTagIterator itr(l->args[0]);
while ((s = itr.Next()) >= 0)
new DPusher(DPusher::p_wind, l->args[3] ? l : NULL, l->args[1], l->args[2], NULL, s);
l->special = 0;
break;
}
case Sector_SetCurrent: // current
for (s = -1; (s = P_FindSectorFromTag (l->args[0],s)) >= 0 ; )
new DPusher (DPusher::p_current, l->args[3] ? l : NULL, l->args[1], l->args[2], NULL, s);
{
FSectorTagIterator itr(l->args[0]);
while ((s = itr.Next()) >= 0)
new DPusher(DPusher::p_current, l->args[3] ? l : NULL, l->args[1], l->args[2], NULL, s);
l->special = 0;
break;
}
case PointPush_SetForce: // push/pull
if (l->args[0]) { // [RH] Find thing by sector
for (s = -1; (s = P_FindSectorFromTag (l->args[0], s)) >= 0 ; )
FSectorTagIterator itr(l->args[0]);
while ((s = itr.Next()) >= 0)
{
AActor *thing = P_GetPushThing (s);
if (thing) { // No MT_P* means no effect

View file

@ -242,10 +242,66 @@ inline sector_t *getNextSector (line_t *line, const sector_t *sec)
line->frontsector;
}
class FSectorTagIterator
{
protected:
int searchtag;
int start;
int P_FindSectorFromTag (int tag, int start);
int P_FindLineFromID (int id, int start);
public:
FSectorTagIterator(int tag)
{
searchtag = tag;
start = sectors[(unsigned)tag % (unsigned)numsectors].firsttag;
}
// Special constructor for actions that treat tag 0 as 'back of activation line'
FSectorTagIterator(int tag, line_t *line)
{
if (tag == 0)
{
searchtag = INT_MIN;
start = (line == NULL || line->backsector == NULL)? -1 : (int)(line->backsector - sectors);
}
else
{
searchtag = tag;
start = sectors[(unsigned)tag % (unsigned)numsectors].firsttag;
}
}
int Next();
int NextCompat(bool compat, int secnum);
};
class FLineIdIterator
{
protected:
int searchtag;
int start;
public:
FLineIdIterator(int id)
{
searchtag = id;
start = lines[(unsigned) id % (unsigned) numlines].firstid;
}
int Next();
};
inline int P_FindFirstSectorFromTag(int tag)
{
FSectorTagIterator it(tag);
return it.Next();
}
inline int P_FindFirstLineFromID(int tag)
{
FLineIdIterator it(tag);
return it.Next();
}
//
// P_LIGHTS

View file

@ -249,7 +249,7 @@ static AActor *SelectTeleDest (int tid, int tag, bool norandom)
int count = 0;
while ( (searcher = iterator.Next ()) )
{
if (tag == 0 || searcher->Sector->tag == tag)
if (tag == 0 || searcher->Sector->HasTag(tag))
{
count++;
}
@ -288,7 +288,7 @@ static AActor *SelectTeleDest (int tid, int tag, bool norandom)
while (count > 0)
{
searcher = iterator.Next ();
if (tag == 0 || searcher->Sector->tag == tag)
if (tag == 0 || searcher->Sector->HasTag(tag))
{
count--;
}
@ -299,9 +299,10 @@ static AActor *SelectTeleDest (int tid, int tag, bool norandom)
if (tag != 0)
{
int secnum = -1;
int secnum;
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
FSectorTagIterator itr(tag);
while ((secnum = itr.Next()) >= 0)
{
// Scanning the snext links of things in the sector will not work, because
// TeleportDests have MF_NOSECTOR set. So you have to search *everything*.
@ -422,7 +423,8 @@ bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBO
if (side || thing->flags2 & MF2_NOTELEPORT || !line || line->sidedef[1] == NULL)
return false;
for (i = -1; (i = P_FindLineFromID (id, i)) >= 0; )
FLineIdIterator itr(id);
while ((i = itr.Next()) >= 0)
{
if (line-lines == i)
continue;
@ -725,7 +727,8 @@ bool EV_TeleportSector (int tag, int source_tid, int dest_tid, bool fog, int gro
int secnum;
secnum = -1;
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
FSectorTagIterator itr(tag);
while ((secnum = itr.Next()) >= 0)
{
msecnode_t *node;
const sector_t * const sec = &sectors[secnum];

View file

@ -69,6 +69,12 @@ public:
}
void Set(int index, int value)
{
if ((unsigned)index >= Types.Size())
{
int oldsize = Types.Size();
Resize(index + 1);
memset(&Types[oldsize], 0xff, (index + 1 - oldsize)*sizeof(WORD));
}
Types[index] = value;
}
};

View file

@ -722,6 +722,7 @@ public:
break;
default:
CHECK_N(Zd | Zdt)
if (0 == strnicmp("user_", key.GetChars(), 5))
{ // Custom user key - Sets an actor's user variable directly
FMapThingUserData ud;
@ -753,7 +754,7 @@ public:
mld.flags = 0;
mld.special = th->special;
mld.tag = th->args[0];
P_TranslateLineDef(&ld, &mld);
P_TranslateLineDef(&ld, &mld, true);
th->special = ld.special;
memcpy(th->args, ld.args, sizeof (ld.args));
}
@ -777,10 +778,11 @@ public:
bool strifetrans = false;
bool strifetrans2 = false;
FString arg0str, arg1str;
int lineid; // forZDoomTranslated namespace
memset(ld, 0, sizeof(*ld));
ld->Alpha = FRACUNIT;
ld->id = -1;
ld->ClearIds();
ld->sidedef[0] = ld->sidedef[1] = NULL;
if (level.flags2 & LEVEL2_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX;
if (level.flags2 & LEVEL2_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX;
@ -813,7 +815,8 @@ public:
continue;
case NAME_Id:
ld->id = CheckInt(key);
lineid = CheckInt(key);
ld->SetMainId(lineid);
continue;
case NAME_Sidefront:
@ -1040,7 +1043,20 @@ public:
break;
}
if (!strnicmp("user_", key.GetChars(), 5))
#if 0 // for later
if (namespace_bits & (Zd)) && !strnicmp(key.GetChars(), "Id", 2))
{
char *endp;
int num = strtol(key.GetChars(), &endp, 10);
if (num > 0 && *endp == NULL)
{
// only allow ID## with ## as a proper number
ld->SetId((short)CheckInt(key), false);
}
}
#endif
if ((namespace_bits & (Zd | Zdt)) && !strnicmp("user_", key.GetChars(), 5))
{
AddUserKey(key, UDMF_Line, index);
}
@ -1053,8 +1069,8 @@ public:
maplinedef_t mld;
memset(&mld, 0, sizeof(mld));
mld.special = ld->special;
mld.tag = ld->id;
P_TranslateLineDef(ld, &mld);
mld.tag = lineid;
P_TranslateLineDef(ld, &mld, false);
ld->flags = saved | (ld->flags&(ML_MONSTERSCANACTIVATE|ML_REPEAT_SPECIAL|ML_FIRSTSIDEONLY));
}
if (passuse && (ld->activation & SPAC_Use))
@ -1226,7 +1242,7 @@ public:
break;
}
if (!strnicmp("user_", key.GetChars(), 5))
if ((namespace_bits & (Zd | Zdt)) && !strnicmp("user_", key.GetChars(), 5))
{
AddUserKey(key, UDMF_Side, index);
}
@ -1316,7 +1332,7 @@ public:
continue;
case NAME_Id:
sec->tag = (short)CheckInt(key);
sec->SetMainTag((short)CheckInt(key));
continue;
default:
@ -1497,8 +1513,20 @@ public:
default:
break;
}
#if 0 // for later
if (namespace_bits & (Zd)) && !strnicmp(key.GetChars(), "Id", 2))
{
char *endp;
int num = strtol(key.GetChars(), &endp, 10);
if (num > 0 && *endp == NULL)
{
// only allow ID## with ## as a proper number
sec->SetTag((short)CheckInt(key), false);
}
}
#endif
if (!strnicmp("user_", key.GetChars(), 5))
if ((namespace_bits & (Zd | Zdt)) && !strnicmp("user_", key.GetChars(), 5))
{
AddUserKey(key, UDMF_Sector, index);
}

View file

@ -294,23 +294,23 @@ player_t::player_t()
respawn_time(0),
camera(0),
air_finished(0),
MUSINFOactor(0),
MUSINFOtics(-1),
crouching(0),
crouchdir(0),
Bot(0),
BlendR(0),
BlendG(0),
BlendB(0),
BlendA(0),
LogText(),
crouching(0),
crouchdir(0),
crouchfactor(0),
crouchoffset(0),
crouchviewdelta(0),
ConversationNPC(0),
ConversationPC(0),
ConversationNPCAngle(0),
ConversationFaceTalker(0),
MUSINFOactor(0),
MUSINFOtics(-1)
ConversationFaceTalker(0)
{
memset (&cmd, 0, sizeof(cmd));
memset (frags, 0, sizeof(frags));

View file

@ -262,7 +262,7 @@ static int WriteSECTORS (FILE *file)
uppercopy (ms.ceilingpic, GetTextureName (sectors[i].GetTexture(sector_t::ceiling)));
ms.lightlevel = LittleShort((short)sectors[i].lightlevel);
ms.special = LittleShort(sectors[i].special);
ms.tag = LittleShort(sectors[i].tag);
ms.tag = LittleShort(sectors[i].GetMainTag());
fwrite (&ms, sizeof(ms), 1, file);
}
return numsectors * sizeof(ms);

View file

@ -60,7 +60,7 @@ typedef enum
PushMany,
} triggertype_e;
void P_TranslateLineDef (line_t *ld, maplinedef_t *mld)
void P_TranslateLineDef (line_t *ld, maplinedef_t *mld, bool setid)
{
unsigned short special = (unsigned short) LittleShort(mld->special);
short tag = LittleShort(mld->tag);
@ -100,11 +100,14 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld)
}
flags = newflags;
// For purposes of maintaining BOOM compatibility, each
// line also needs to have its ID set to the same as its tag.
// An external conversion program would need to do this more
// intelligently.
ld->id = tag;
if (setid)
{
// For purposes of maintaining BOOM compatibility, each
// line also needs to have its ID set to the same as its tag.
// An external conversion program would need to do this more
// intelligently.
ld->SetMainId(tag);
}
// 0 specials are never translated.
if (special == 0)
@ -304,7 +307,7 @@ void P_TranslateTeleportThings ()
while ( (dest = iterator.Next()) )
{
if (dest->Sector->tag == 0)
if (!dest->Sector->HasTags())
{
dest->tid = 1;
dest->AddToHash ();

View file

@ -128,6 +128,8 @@ enum
kVK_UpArrow = 0x7E
};
static const NSOpenGLPixelFormatAttribute NSOpenGLPFAAllowOfflineRenderers = NSOpenGLPixelFormatAttribute(96);
#endif // prior to 10.5

View file

@ -72,6 +72,11 @@ CUSTOM_CVAR(Bool, fullscreen, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
setmodeneeded = true;
}
CUSTOM_CVAR(Bool, vid_autoswitch, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
{
Printf("You must restart " GAMENAME " to apply graphics switching mode\n");
}
RenderBufferOptions rbOpts;
@ -399,6 +404,11 @@ CocoaVideo::CocoaVideo(const int multisample)
attributes[i++] = NSOpenGLPFAStencilSize;
attributes[i++] = NSOpenGLPixelFormatAttribute(8);
if (!vid_autoswitch)
{
attributes[i++] = NSOpenGLPFAAllowOfflineRenderers;
}
if (multisample)
{
attributes[i++] = NSOpenGLPFAMultisample;

View file

@ -331,7 +331,7 @@ int I_PickIWad_Gtk (WadStuff *wads, int numwads, bool showwin, int defaultiwad)
gtk_container_add (GTK_CONTAINER(window), vbox);
// Create the top label.
widget = gtk_label_new ("ZDoom found more than one IWAD\nSelect from the list below to determine which one to use:");
widget = gtk_label_new (GAMENAME " found more than one IWAD\nSelect from the list below to determine which one to use:");
gtk_box_pack_start (GTK_BOX(vbox), widget, false, false, 0);
gtk_misc_set_alignment (GTK_MISC(widget), 0, 0);
@ -450,7 +450,7 @@ int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad)
{
FString cmd("kdialog --title \"" GAMESIG " ");
cmd << GetVersionString() << ": Select an IWAD to use\""
" --menu \"ZDoom found more than one IWAD\n"
" --menu \"" GAMENAME " found more than one IWAD\n"
"Select from the list below to determine which one to use:\"";
for(i = 0; i < numwads; ++i)
@ -603,6 +603,15 @@ int I_FindAttr (findstate_t *fileinfo)
#ifdef __APPLE__
static PasteboardRef s_clipboard;
static CFDataRef GetPasteboardData(const PasteboardItemID itemID, const CFStringRef flavorType)
{
CFDataRef data = NULL;
const OSStatus result = PasteboardCopyItemFlavorData(s_clipboard, itemID, flavorType, &data);
return noErr == result ? data : NULL;
}
#endif // __APPLE__
// Clipboard support requires GTK+
@ -688,35 +697,41 @@ FString I_GetFromClipboard (bool use_primary_selection)
return FString();
}
CFArrayRef flavorTypeArray;
if (0 != PasteboardCopyItemFlavors(s_clipboard, itemID, &flavorTypeArray))
if (CFDataRef data = GetPasteboardData(itemID, kUTTypeUTF8PlainText))
{
return FString();
const CFIndex bufferLength = CFDataGetLength(data);
char* const buffer = result.LockNewBuffer(bufferLength);
memcpy(buffer, CFDataGetBytePtr(data), bufferLength);
result.UnlockBuffer();
}
const CFIndex flavorCount = CFArrayGetCount(flavorTypeArray);
for (CFIndex flavorIndex = 0; flavorIndex < flavorCount; ++flavorIndex)
else if (CFDataRef data = GetPasteboardData(itemID, kUTTypeUTF16PlainText))
{
const CFStringRef flavorType = static_cast<const CFStringRef>(
CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex));
#ifdef __LITTLE_ENDIAN__
static const CFStringEncoding ENCODING = kCFStringEncodingUTF16LE;
#else // __BIG_ENDIAN__
static const CFStringEncoding ENCODING = kCFStringEncodingUTF16BE;
#endif // __LITTLE_ENDIAN__
if (UTTypeConformsTo(flavorType, CFSTR("public.utf8-plain-text")))
if (const CFStringRef utf16 = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, data, ENCODING))
{
CFDataRef flavorData;
const CFRange range = { 0, CFStringGetLength(utf16) };
CFIndex bufferLength = 0;
if (0 == PasteboardCopyItemFlavorData(s_clipboard, itemID, flavorType, &flavorData))
if (CFStringGetBytes(utf16, range, kCFStringEncodingUTF8, '?', false, NULL, 0, &bufferLength) > 0)
{
result += reinterpret_cast<const char*>(CFDataGetBytePtr(flavorData));
UInt8* const buffer = reinterpret_cast<UInt8*>(result.LockNewBuffer(bufferLength));
CFStringGetBytes(utf16, range, kCFStringEncodingUTF8, '?', false, buffer, bufferLength, NULL);
result.UnlockBuffer();
}
CFRelease(flavorData);
CFRelease(utf16);
}
}
CFRelease(flavorTypeArray);
return result;
#endif
return "";

View file

@ -43,5 +43,7 @@
</array>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<string>YES</string>
</dict>
</plist>

View file

@ -18,8 +18,6 @@
#include "templates.h"
#include "s_sound.h"
void ScaleWithAspect (int &w, int &h, int Width, int Height);
static void I_CheckGUICapture ();
static void I_CheckNativeMouse ();
@ -320,35 +318,11 @@ void MessagePump (const SDL_Event &sev)
int x, y;
SDL_GetMouseState (&x, &y);
// Detect if we're doing scaling in the Window and adjust the mouse
// coordinates accordingly. This could be more efficent, but I
// don't think performance is an issue in the menus.
SDL_Window *focus;
if (screen->IsFullscreen() && (focus = SDL_GetMouseFocus ()))
{
int w, h;
SDL_GetWindowSize (focus, &w, &h);
int realw = w, realh = h;
ScaleWithAspect (realw, realh, SCREENWIDTH, SCREENHEIGHT);
if (realw != SCREENWIDTH || realh != SCREENHEIGHT)
{
double xratio = (double)SCREENWIDTH/realw;
double yratio = (double)SCREENHEIGHT/realh;
if (realw < w)
{
x = (x - (w - realw)/2)*xratio;
y *= yratio;
}
else
{
y = (y - (h - realh)/2)*yratio;
x *= xratio;
}
}
}
event.data1 = x;
event.data2 = y;
screen->ScaleCoordsFromWindow(event.data1, event.data2);
event.type = EV_GUI_Event;
if(sev.type == SDL_MOUSEMOTION)
event.subtype = EV_GUI_MouseMove;

View file

@ -50,6 +50,7 @@ public:
friend class SDLVideo;
virtual void SetVSync (bool vsync);
virtual void ScaleCoordsFromWindow(SWORD &x, SWORD &y);
private:
PalEntry SourcePalette[256];
@ -723,6 +724,35 @@ void SDLFB::SetVSync (bool vsync)
#endif // __APPLE__
}
void SDLFB::ScaleCoordsFromWindow(SWORD &x, SWORD &y)
{
// Detect if we're doing scaling in the Window and adjust the mouse
// coordinates accordingly. This could be more efficent, but I
// don't think performance is an issue in the menus.
if(IsFullscreen())
{
int w, h;
SDL_GetWindowSize (Screen, &w, &h);
int realw = w, realh = h;
ScaleWithAspect (realw, realh, SCREENWIDTH, SCREENHEIGHT);
if (realw != SCREENWIDTH || realh != SCREENHEIGHT)
{
double xratio = (double)SCREENWIDTH/realw;
double yratio = (double)SCREENHEIGHT/realh;
if (realw < w)
{
x = (x - (w - realw)/2)*xratio;
y *= yratio;
}
else
{
y = (y - (h - realh)/2)*yratio;
x *= xratio;
}
}
}
}
ADD_STAT (blit)
{
FString out;

View file

@ -633,6 +633,13 @@ struct sector_t
return pos == floor? floorplane:ceilingplane;
}
bool HasTag(int checktag) const;
bool HasTags() const;
void SetMainTag(int tagnum);
int GetMainTag() const;
void ClearTags();
static void HashTags();
bool PlaneMoving(int pos);
@ -899,6 +906,12 @@ struct line_t
sector_t *frontsector, *backsector;
int validcount; // if == validcount, already checked
int locknumber; // [Dusk] lock number for special
void SetMainId(int newid);
void ClearIds();
bool HasId(int id) const;
static void HashIds();
};
// phares 3/14/98

View file

@ -72,7 +72,7 @@ struct FDirectoryLump : public FResourceLump
virtual FileReader *NewReader();
virtual int FillCache();
private:
FString mFullPath;
};
@ -300,6 +300,8 @@ void FDirectory::AddEntry(const char *fullpath, int size)
{
FDirectoryLump *lump_p = &Lumps[Lumps.Reserve(1)];
// Store the full path here so that we can access the file later, even if it is from a filter directory.
lump_p->mFullPath = fullpath;
// The lump's name is only the part relative to the main directory
lump_p->LumpNameSetup(fullpath + strlen(Filename));
lump_p->LumpSize = size;
@ -319,9 +321,7 @@ FileReader *FDirectoryLump::NewReader()
{
try
{
FString fullpath = Owner->Filename;
fullpath += FullName;
return new FileReader(fullpath);
return new FileReader(mFullPath);
}
catch (CRecoverableError &)
{
@ -339,6 +339,11 @@ int FDirectoryLump::FillCache()
{
Cache = new char[LumpSize];
FileReader *reader = NewReader();
if (reader == NULL)
{
memset(Cache, 0, LumpSize);
return 0;
}
reader->Read(Cache, LumpSize);
delete reader;
RefCount = 1;

View file

@ -168,7 +168,7 @@ bool FZipFile::Open(bool quiet)
if (centraldir == 0)
{
if (!quiet) Printf("\n%s: ZIP file corrupt!\n", Filename);
if (!quiet) Printf(TEXTCOLOR_RED "\n%s: ZIP file corrupt!\n", Filename);
return false;
}
@ -180,7 +180,7 @@ bool FZipFile::Open(bool quiet)
if (info.NumEntries != info.NumEntriesOnAllDisks ||
info.FirstDisk != 0 || info.DiskNumber != 0)
{
if (!quiet) Printf("\n%s: Multipart Zip files are not supported.\n", Filename);
if (!quiet) Printf(TEXTCOLOR_RED "\n%s: Multipart Zip files are not supported.\n", Filename);
return false;
}
@ -188,9 +188,10 @@ bool FZipFile::Open(bool quiet)
Lumps = new FZipLump[NumLumps];
// Load the entire central directory. Too bad that this contains variable length entries...
void *directory = malloc(LittleLong(info.DirectorySize));
int dirsize = LittleLong(info.DirectorySize);
void *directory = malloc(dirsize);
Reader->Seek(LittleLong(info.DirectoryOffset), SEEK_SET);
Reader->Read(directory, LittleLong(info.DirectorySize));
Reader->Read(directory, dirsize);
char *dirptr = (char*)directory;
FZipLump *lump_p = Lumps;
@ -204,6 +205,13 @@ bool FZipFile::Open(bool quiet)
LittleShort(zip_fh->NameLength) +
LittleShort(zip_fh->ExtraLength) +
LittleShort(zip_fh->CommentLength);
if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file.
{
free(directory);
if (!quiet) Printf(TEXTCOLOR_RED "\n%s: Central directory corrupted.", Filename);
return false;
}
// skip Directories
if (name[len - 1] == '/' && LittleLong(zip_fh->UncompressedSize) == 0)
@ -221,7 +229,7 @@ bool FZipFile::Open(bool quiet)
zip_fh->Method != METHOD_IMPLODE &&
zip_fh->Method != METHOD_SHRINK)
{
if (!quiet) Printf("\n%s: '%s' uses an unsupported compression algorithm (#%d).\n", Filename, name.GetChars(), zip_fh->Method);
if (!quiet) Printf(TEXTCOLOR_YELLOW "\n%s: '%s' uses an unsupported compression algorithm (#%d).\n", Filename, name.GetChars(), zip_fh->Method);
skipped++;
continue;
}
@ -229,7 +237,7 @@ bool FZipFile::Open(bool quiet)
zip_fh->Flags = LittleShort(zip_fh->Flags);
if (zip_fh->Flags & ZF_ENCRYPTED)
{
if (!quiet) Printf("\n%s: '%s' is encrypted. Encryption is not supported.\n", Filename, name.GetChars());
if (!quiet) Printf(TEXTCOLOR_YELLOW "\n%s: '%s' is encrypted. Encryption is not supported.\n", Filename, name.GetChars());
skipped++;
continue;
}
@ -260,7 +268,7 @@ bool FZipFile::Open(bool quiet)
NumLumps -= skipped;
free(directory);
if (!quiet) Printf(", %d lumps\n", NumLumps);
if (!quiet) Printf(TEXTCOLOR_NORMAL ", %d lumps\n", NumLumps);
PostProcessArchive(&Lumps[0], sizeof(FZipLump));
return true;

View file

@ -90,16 +90,14 @@ FResourceLump::~FResourceLump()
//
//==========================================================================
void FResourceLump::LumpNameSetup(const char *iname)
void FResourceLump::LumpNameSetup(FString iname)
{
const char *lname = strrchr(iname,'/');
lname = (lname == NULL) ? iname : lname + 1;
FString base = lname;
base = base.Left(base.LastIndexOf('.'));
long slash = iname.LastIndexOf('/');
FString base = (slash >= 0) ? iname.Mid(slash + 1) : iname;
base.Truncate(base.LastIndexOf('.'));
uppercopy(Name, base);
Name[8] = 0;
FString temp = iname; // Note: iname can point to inside FullName's string buffer so we cannot do the assignment directly.
FullName = temp;
FullName = iname;
// Map some directories to WAD namespaces.
// Note that some of these namespaces don't exist in WADS.
@ -117,12 +115,12 @@ void FResourceLump::LumpNameSetup(const char *iname)
!strncmp(iname, "sounds/", 7) ? ns_sounds :
!strncmp(iname, "music/", 6) ? ns_music :
!strchr(iname, '/') ? ns_global :
-1;
ns_hidden;
// Anything that is not in one of these subdirectories or the main directory
// should not be accessible through the standard WAD functions but only through
// the ones which look for the full name.
if (Namespace == -1)
if (Namespace == ns_hidden)
{
memset(Name, 0, 8);
}
@ -346,9 +344,17 @@ void FResourceFile::PostProcessArchive(void *lumps, size_t lumpsize)
// in the ini file use. We reduce the maximum lump concidered after
// each one so that we don't risk refiltering already filtered lumps.
DWORD max = NumLumps;
max -= FilterLumps(gameinfo.ConfigName, lumps, lumpsize, max);
max -= FilterLumps(LumpFilterGroup, lumps, lumpsize, max);
max -= FilterLumps(LumpFilterIWAD, lumps, lumpsize, max);
max -= FilterLumpsByGameType(gameinfo.gametype, lumps, lumpsize, max);
long len;
int lastpos = -1;
FString file;
while ((len = LumpFilterIWAD.IndexOf('.', lastpos+1)) > 0)
{
max -= FilterLumps(LumpFilterIWAD.Left(len), lumps, lumpsize, max);
lastpos = len;
}
JunkLeftoverFilters(lumps, lumpsize, max);
}
@ -382,7 +388,7 @@ int FResourceFile::FilterLumps(FString filtername, void *lumps, size_t lumpsize,
{
FResourceLump *lump = (FResourceLump *)lump_p;
assert(lump->FullName.CompareNoCase(filter, (int)filter.Len()) == 0);
lump->LumpNameSetup(&lump->FullName[filter.Len()]);
lump->LumpNameSetup(lump->FullName.Mid(filter.Len()));
}
// Move filtered lumps to the end of the lump list.
@ -408,6 +414,41 @@ int FResourceFile::FilterLumps(FString filtername, void *lumps, size_t lumpsize,
return end - start;
}
//==========================================================================
//
// FResourceFile :: FilterLumpsByGameType
//
// Matches any lumps that match "filter/game-<gametype>/*". Includes
// inclusive gametypes like Raven.
//
//==========================================================================
int FResourceFile::FilterLumpsByGameType(int type, void *lumps, size_t lumpsize, DWORD max)
{
static const struct { int match; const char *name; } blanket[] =
{
{ GAME_Raven, "game-Raven" },
{ GAME_DoomStrifeChex, "game-DoomStrifeChex" },
{ GAME_DoomChex, "game-DoomChex" },
{ GAME_Any, NULL }
};
if (type == 0)
{
return 0;
}
int count = 0;
for (int i = 0; blanket[i].name != NULL; ++i)
{
if (type & blanket[i].match)
{
count += FilterLumps(blanket[i].name, lumps, lumpsize, max);
}
}
FString filter = "game-";
filter += GameNames[type];
return count + FilterLumps(filter, lumps, lumpsize, max);
}
//==========================================================================
//
// FResourceFile :: JunkLeftoverFilters
@ -430,7 +471,7 @@ void FResourceFile::JunkLeftoverFilters(void *lumps, size_t lumpsize, DWORD max)
FResourceLump *lump = (FResourceLump *)p;
lump->FullName = 0;
lump->Name[0] = '\0';
lump->Namespace = ns_invalid;
lump->Namespace = ns_hidden;
}
}
}

View file

@ -44,7 +44,7 @@ struct FResourceLump
virtual FileReader *NewReader();
virtual int GetFileOffset() { return -1; }
virtual int GetIndexNum() const { return 0; }
void LumpNameSetup(const char *iname);
void LumpNameSetup(FString iname);
void CheckEmbedded();
void *CacheLump();
@ -72,6 +72,7 @@ private:
DWORD FirstLump;
int FilterLumps(FString filtername, void *lumps, size_t lumpsize, DWORD max);
int FilterLumpsByGameType(int gametype, void *lumps, size_t lumpsize, DWORD max);
bool FindPrefixRange(FString filter, void *lumps, size_t lumpsize, DWORD max, DWORD &start, DWORD &end);
void JunkLeftoverFilters(void *lumps, size_t lumpsize, DWORD max);

View file

@ -2,6 +2,7 @@
#include "c_cvars.h"
#include "cmdlib.h"
#include "templates.h"
#include "version.h"
#ifndef _WIN32
#include <unistd.h>
@ -20,9 +21,11 @@ void ChildSigHandler (int signum)
#endif
#ifdef _WIN32
BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode);
static char TimidityTitle[] = "TiMidity (ZDoom Launched)";
static char TimidityTitle[] = "TiMidity (" GAMENAME " Launched)";
const char TimidityPPMIDIDevice::EventName[] = "TiMidity Killer";
CVAR (String, timidity_exe, "timidity.exe", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
@ -347,7 +350,7 @@ bool TimidityPPMIDIDevice::ValidateTimidity()
}
if (!good)
{
Printf(PRINT_BOLD, "ZDoom requires a special version of TiMidity++\n");
Printf(PRINT_BOLD, GAMENAME " requires a special version of TiMidity++\n");
}
UnmapViewOfFile((LPVOID)exeBase);

View file

@ -177,8 +177,8 @@ void FTextureManager::InitAnimated (void)
{
FMemLump animatedlump = Wads.ReadLump (lumpnum);
int animatedlen = Wads.LumpLength(lumpnum);
const char *animdefs = (const char *)animatedlump.GetMem();
const char *anim_p;
const BYTE *animdefs = (const BYTE *)animatedlump.GetMem();
const BYTE *anim_p;
FTextureID pic1, pic2;
int animtype;
DWORD animspeed;
@ -186,7 +186,7 @@ void FTextureManager::InitAnimated (void)
// Init animation
animtype = FAnimDef::ANIM_Forward;
for (anim_p = animdefs; *anim_p != -1; anim_p += 23)
for (anim_p = animdefs; *anim_p != 0xFF; anim_p += 23)
{
// make sure the current chunk of data is inside the lump boundaries.
if (anim_p + 22 >= animdefs + animatedlen)
@ -196,8 +196,8 @@ void FTextureManager::InitAnimated (void)
if (*anim_p /* .istexture */ & 1)
{
// different episode ?
if (!(pic1 = CheckForTexture (anim_p + 10 /* .startname */, FTexture::TEX_Wall, texflags)).Exists() ||
!(pic2 = CheckForTexture (anim_p + 1 /* .endname */, FTexture::TEX_Wall, texflags)).Exists())
if (!(pic1 = CheckForTexture ((const char*)(anim_p + 10) /* .startname */, FTexture::TEX_Wall, texflags)).Exists() ||
!(pic2 = CheckForTexture ((const char*)(anim_p + 1) /* .endname */, FTexture::TEX_Wall, texflags)).Exists())
continue;
// [RH] Bit 1 set means allow decals on walls with this texture
@ -205,16 +205,16 @@ void FTextureManager::InitAnimated (void)
}
else
{
if (!(pic1 = CheckForTexture (anim_p + 10 /* .startname */, FTexture::TEX_Flat, texflags)).Exists() ||
!(pic2 = CheckForTexture (anim_p + 1 /* .startname */, FTexture::TEX_Flat, texflags)).Exists())
if (!(pic1 = CheckForTexture ((const char*)(anim_p + 10) /* .startname */, FTexture::TEX_Flat, texflags)).Exists() ||
!(pic2 = CheckForTexture ((const char*)(anim_p + 1) /* .startname */, FTexture::TEX_Flat, texflags)).Exists())
continue;
}
FTexture *tex1 = Texture(pic1);
FTexture *tex2 = Texture(pic2);
animspeed = (BYTE(anim_p[19]) << 0) | (BYTE(anim_p[20]) << 8) |
(BYTE(anim_p[21]) << 16) | (BYTE(anim_p[22]) << 24);
animspeed = (anim_p[19] << 0) | (anim_p[20] << 8) |
(anim_p[21] << 16) | (anim_p[22] << 24);
// SMMU-style swirly hack? Don't apply on already-warping texture
if (animspeed > 65535 && tex1 != NULL && !tex1->bWarped)
@ -242,7 +242,7 @@ void FTextureManager::InitAnimated (void)
if (pic1 == pic2)
{
// This animation only has one frame. Skip it. (Doom aborted instead.)
Printf ("Animation %s in ANIMATED has only one frame\n", anim_p + 10);
Printf ("Animation %s in ANIMATED has only one frame\n", (const char*)(anim_p + 10));
continue;
}
// [RH] Allow for backward animations as well as forward.

View file

@ -70,6 +70,7 @@
#include "m_bbox.h"
#include "r_data/r_translate.h"
#include "p_trace.h"
#include "p_setup.h"
#include "gstrings.h"
@ -4856,7 +4857,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Weave)
//
//===========================================================================
void P_TranslateLineDef (line_t *ld, maplinedef_t *mld);
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LineEffect)
{
PARAM_ACTION_PROLOGUE;
@ -4871,7 +4871,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LineEffect)
if ((oldjunk.special = special)) // Linedef type
{
oldjunk.tag = tag; // Sector tag for linedef
P_TranslateLineDef(&junk, &oldjunk); // Turn into native type
P_TranslateLineDef(&junk, &oldjunk, false); // Turn into native type
res = !!P_ExecuteSpecial(junk.special, NULL, self, false, junk.args[0],
junk.args[1], junk.args[2], junk.args[3], junk.args[4]);
if (res && !(junk.flags & ML_REPEAT_SPECIAL)) // If only once,

View file

@ -398,8 +398,8 @@ public:
virtual void WipeEndScreen();
virtual bool WipeDo(int ticks);
virtual void WipeCleanup();
virtual int GetPixelDoubling() const { return 0; }
virtual int GetTrueHeight() { return GetHeight(); }
virtual void ScaleCoordsFromWindow(SWORD &x, SWORD &y) {}
uint32 GetLastFPS() const { return LastCount; }

View file

@ -56,7 +56,7 @@ const char *GetVersionString();
// Version stored in the ini's [LastRun] section.
// Bump it if you made some configuration change that you want to
// be able to migrate in FGameConfigFile::DoGlobalSetup().
#define LASTRUNVERSION "210"
#define LASTRUNVERSION "211"
// Protocol version used in demos.
// Bump it if you change existing DEM_ commands or add new ones.

View file

@ -317,7 +317,7 @@ void FWadCollection::AddFile (const char *filename, FileReader *wadinfo)
sprintf(cksumout + (j * 2), "%02X", cksum[j]);
}
fprintf(hashfile, "file: %s, hash: %s, size: %d\n", filename, cksumout, reader->GetLength());
fprintf(hashfile, "file: %s, hash: %s, size: %ld\n", filename, cksumout, reader->GetLength());
}
else

View file

@ -52,7 +52,7 @@ struct wadlump_t
// [RH] Namespaces from BOOM.
typedef enum {
ns_invalid = -1,
ns_hidden = -1,
ns_global = 0,
ns_sprites,

View file

@ -45,6 +45,7 @@
#include "c_dispatch.h"
#include "m_argv.h"
#include "i_system.h"
#include "version.h"
#include "i_cd.h"
#include "helperthread.h"
@ -175,7 +176,7 @@ bool FCDThread::Init ()
CD_WindowClass.style = CS_NOCLOSE;
CD_WindowClass.lpfnWndProc = CD_WndProc;
CD_WindowClass.hInstance = g_hInst;
CD_WindowClass.lpszClassName = "ZDoom CD Player";
CD_WindowClass.lpszClassName = GAMENAME " CD Player";
CD_WindowAtom = RegisterClass (&CD_WindowClass);
if (CD_WindowAtom == 0)
@ -183,7 +184,7 @@ bool FCDThread::Init ()
CD_Window = CreateWindow (
(LPCTSTR)(INT_PTR)(int)CD_WindowAtom,
"ZDoom CD Player",
GAMENAME " CD Player",
0,
0, 0, 10, 10,
NULL,

View file

@ -125,10 +125,7 @@ RtlVirtualUnwind (
#define UPLOAD_BOUNDARY "Von-DnrNbJl0 P9d_BD;cEEsQVWpYMq0pbZ6NUmYHus;yIbFbkgB?.N=YC5O=BGZm+Rab5"
#define DBGHELP_URI "/msredist/dbghelp.dl_"
// If you are working on your own modified version of ZDoom, change
// the last part of the UPLOAD_AGENT (between parentheses) to your
// own program's name. e.g. (Skulltag) or (ZDaemon) or (ZDoomFu)
#define UPLOAD_AGENT "ZDoom/" VERSIONSTR " (" GAMESIG ")"
#define UPLOAD_AGENT GAMENAME "/" VERSIONSTR " (" GAMESIG ")"
// Time, in milliseconds, to wait for a send() or recv() to complete.
#define TIMEOUT 60000

View file

@ -323,11 +323,11 @@ bool GUIWndProcHook(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESU
if (BlockMouseMove > 0) return true;
}
ev.data1 = LOWORD(lParam);
ev.data2 = HIWORD(lParam);
if (screen != NULL)
{
int shift = screen? screen->GetPixelDoubling() : 0;
ev.data1 = LOWORD(lParam) >> shift;
ev.data2 = HIWORD(lParam) >> shift;
if (screen) ev.data2 -= (screen->GetTrueHeight() - screen->GetHeight())/2;
screen->ScaleCoordsFromWindow(ev.data1, ev.data2);
}
if (wParam & MK_SHIFT) ev.data3 |= GKM_SHIFT;

View file

@ -143,7 +143,7 @@ LONG ErrorIconChar;
// PRIVATE DATA DEFINITIONS ------------------------------------------------
static const char WinClassName[] = "ZDoomMainWindow";
static const char WinClassName[] = GAMENAME "MainWindow";
static HMODULE hwtsapi32; // handle to wtsapi32.dll
static void (*TermFuncs[MAX_TERMS])(void);
static int NumTerms;
@ -1224,7 +1224,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n
// This should only happen on basic Windows 95 installations, but since we
// don't support Windows 95, we have no obligation to provide assistance in
// getting it installed.
MessageBoxA(NULL, "Could not load riched20.dll", "ZDoom Error", MB_OK | MB_ICONSTOP);
MessageBoxA(NULL, "Could not load riched20.dll", GAMENAME " Error", MB_OK | MB_ICONSTOP);
exit(0);
}

View file

@ -127,10 +127,12 @@ public:
virtual void Blank () = 0;
virtual bool PaintToWindow () = 0;
virtual HRESULT GetHR () = 0;
virtual void ScaleCoordsFromWindow(SWORD &x, SWORD &y);
protected:
virtual bool CreateResources () = 0;
virtual void ReleaseResources () = 0;
virtual int GetTrueHeight() { return GetHeight(); }
bool Windowed;
@ -164,8 +166,8 @@ public:
void SetVSync (bool vsync);
void NewRefreshRate();
HRESULT GetHR ();
virtual int GetTrueHeight() { return TrueHeight; }
bool Is8BitMode();
virtual int GetTrueHeight() { return TrueHeight; }
void Blank ();
bool PaintToWindow ();
@ -269,8 +271,8 @@ public:
bool WipeDo(int ticks);
void WipeCleanup();
HRESULT GetHR ();
virtual int GetTrueHeight() { return TrueHeight; }
bool Is8BitMode() { return false; }
virtual int GetTrueHeight() { return TrueHeight; }
private:
friend class D3DTex;
@ -380,7 +382,6 @@ private:
void EndLineBatch();
void EndBatch();
void CopyNextFrontBuffer();
int GetPixelDoubling() const { return PixelDoubling; }
D3DCAPS9 DeviceCaps;

View file

@ -70,6 +70,7 @@
#include "r_defs.h"
#include "v_text.h"
#include "r_swrenderer.h"
#include "version.h"
#include "win32iface.h"
@ -301,7 +302,7 @@ void Win32Video::InitDDraw ()
DDraw->Release ();
DDraw = NULL;
I_FatalError ("DirectDraw returned no display modes.\n\n"
"If you started ZDoom from a fullscreen DOS box, run it from "
"If you started " GAMENAME " from a fullscreen DOS box, run it from "
"a DOS window instead. If that does not work, you may need to reboot.");
}
if (Args->CheckParm ("-2"))
@ -735,6 +736,29 @@ void Win32Video::SetWindowedScale (float scale)
// FIXME
}
//==========================================================================
//
// BaseWinFB :: ScaleCoordsFromWindow
//
// Given coordinates in window space, return coordinates in what the game
// thinks screen space is.
//
//==========================================================================
void BaseWinFB::ScaleCoordsFromWindow(SWORD &x, SWORD &y)
{
RECT rect;
int TrueHeight = GetTrueHeight();
if (GetClientRect(Window, &rect))
{
x = SWORD(x * Width / (rect.right - rect.left));
y = SWORD(y * TrueHeight / (rect.bottom - rect.top));
}
// Subtract letterboxing borders
y -= (TrueHeight - Height) / 2;
}
//==========================================================================
//
// SetFPSLimit

View file

@ -1096,7 +1096,7 @@ void FString::ReallocBuffer (size_t newlen)
{ // If more than one reference, we must use a new copy
FStringData *old = Data();
AllocBuffer (newlen);
StrCopy (Chars, old->Chars(), old->Len);
StrCopy (Chars, old->Chars(), newlen < old->Len ? newlen : old->Len);
old->Release();
}
else

103
wadsrc/static/defbinds.txt Normal file
View file

@ -0,0 +1,103 @@
/* Default keybindings for all games */
` toggleconsole
1 "slot 1"
2 "slot 2"
3 "slot 3"
4 "slot 4"
5 "slot 5"
6 "slot 6"
7 "slot 7"
8 "slot 8"
9 "slot 9"
0 "slot 0"
[ invprev
] invnext
mwheelleft invprev
mwheelright invnext
enter invuse
- sizedown
= sizeup
ctrl +attack
alt +strafe
shift +speed
space +use
rightarrow +right
leftarrow +left
uparrow +forward
downarrow +back
, +moveleft
. +moveright
mouse1 +attack
mouse2 +strafe
mouse3 +forward
mouse4 +speed
capslock "toggle cl_run"
f1 menu_help
f2 menu_save
f3 menu_load
f4 menu_options
f5 menu_display
f6 quicksave
f7 menu_endgame
f8 togglemessages
f9 quickload
f11 bumpgamma
f10 menu_quit
tab togglemap
pause pause
sysrq screenshot
t messagemode
\ +showscores
f12 spynext
mwheeldown weapnext
mwheelup weapprev
// Originally just for Heretic, Hexen, and Strife.
// I can't see why they shouldn't be for Doom or Chex either.
pgup +moveup
ins +movedown
home land
pgdn +lookup
del +lookdown
end centerview
// Generic joystick buttons
joy1 +attack
joy2 +strafe
joy3 +speed
joy4 +use
// Xbox 360 / PS2 controllers
pad_a +use
pad_y +jump
rtrigger +attack
ltrigger +altattack
lshoulder weapprev
rshoulder weapnext
dpadleft invprev
dpadright invnext
dpaddown invuse
dpadup togglemap
pad_start pause
pad_back menu_main
lthumb crouch
/* Default automap bindings */
mapbind f am_togglefollow
mapbind g am_togglegrid
mapbind p am_toggletexture
mapbind m am_setmark
mapbind c am_clearmarks
mapbind 0 am_gobig
mapbind rightarrow +am_panright
mapbind leftarrow +am_panleft
mapbind uparrow +am_panup
mapbind downarrow +am_pandown
mapbind - +am_zoomout
mapbind = +am_zoomin
mapbind kp- +am_zoomout
mapbind kp+ +am_zoomin
mapbind mwheelup "am_zoom 1.2"
mapbind mwheeldown "am_zoom -1.2"

View file

@ -1,3 +1,4 @@
/****************************************************************************/
/* */
/* DOOM SOUNDS */

View file

@ -0,0 +1,3 @@
/* Default keybindings for Heretic */
backspace "use ArtiTomeOfPower"

View file

@ -1,3 +1,4 @@
/****************************************************************************/
/* */
/* HERETIC SOUNDS */

View file

@ -0,0 +1,12 @@
/* Default keybindings for Hexen */
/ +jump
backspace invuseall
\ "use ArtiHealth"
0 useflechette
9 "use ArtiBlastRadius"
8 "use ArtiTeleport"
7 "use ArtiTeleportOther"
6 "use ArtiPork"
5 "use ArtiInvulnerability2"
scroll +showscores

View file

@ -1,3 +1,4 @@
/****************************************************************************/
/* */
/* HEXEN SOUNDS */

View file

@ -0,0 +1,11 @@
/* Default keybindings for Strife */
a +jump
w "showpop 1"
backspace invdrop
z "showpop 3"
k "showpop 2"
q invquery
; not done
; h - use health

View file

@ -0,0 +1 @@
strfhelp

View file

@ -1,3 +1,4 @@
/****************************************************************************/
/* */
/* STRIFE SOUNDS */

View file

@ -1,144 +1,144 @@
conversationids
{
2 WeaponSmith
3 BarKeep
4 Armorer
5 Medic
6 Peasant1
7 Peasant2
8 Peasant3
9 Peasant4
10 Peasant5
11 Peasant6
12 Peasant7
13 Peasant8
14 Peasant9
15 Peasant10
16 Peasant11
17 Peasant12
18 Peasant13
19 Peasant14
20 Peasant15
21 Peasant16
22 Peasant17
23 Peasant18
24 Peasant19
25 Peasant20
26 Peasant21
27 Peasant22
37 Beggar1
38 Beggar2
39 Beggar3
40 Beggar4
41 Beggar5
42 Rebel1
43 Rebel2
44 Rebel3
45 Rebel4
46 Rebel5
47 Rebel6
48 Macil1
49 Macil2
52 AcolyteTan
53 AcolyteRed
54 AcolyteRust
55 AcolyteGray
56 AcolyteDGreen
57 AcolyteGold
58 AcolyteShadow
61 Templar
62 Oracle
63 Loremaster
70 AlienSpectre2
94 InquisitorArm
121 MedPatch
122 MedicalKit
123 SurgeryKit
124 DegninOre
125 MetalArmor
126 LeatherArmor
129 BaseKey
130 GovsKey
131 Passcard
132 IDBadge
133 PrisonKey
134 SeveredHand
135 Power1Key
136 Power2Key
137 Power3Key
138 GoldKey
139 IDCard
140 SilverKey
141 OracleKey
142 MilitaryID
143 OrderKey
144 WarehouseKey
145 BrassKey
146 RedCrystalKey
147 BlueCrystalKey
148 ChapelKey
149 CatacombKey
150 SecurityKey
151 CoreKey
152 MaulerKey
153 FactoryKey
154 MineKey
155 NewKey5
156 ShadowArmor
157 EnvironmentalSuit
158 GuardUniform
159 OfficersUniform
160 StrifeMap
161 Coin
162 Gold10
163 Gold25
164 Gold50
165 BeldinsRing
166 OfferingChalice
167 Ear
168 Communicator
169 Targeter
170 HEGrenadeRounds
171 PhosphorusGrenadeRounds
173 ClipOfBullets
174 BoxOfBullets
175 MiniMissiles
176 CrateOfMissiles
177 EnergyPod
178 EnergyPack
179 PoisonBolts
180 ElectricBolts
181 AmmoSatchel
182 AssaultGun
183 AssaultGunStanding
184 FlameThrower
185 FlameThrowerParts
186 MiniMissileLauncher
187 Mauler
188 StrifeCrossbow
189 StrifeGrenadeLauncher
190 Sigil1
191 Sigil2
192 Sigil3
193 Sigil4
194 Sigil5
196 RatBuddy
230 DeadCrusader
280 AmmoFillup
281 HealthFillup
282 info
283 RaiseAlarm
284 OpenDoor222
285 CloseDoor222
286 PrisonPass
287 UpgradeStamina
288 UpgradeAccuracy
289 InterrogatorReport
292 OraclePass
293 QuestItem1
294 QuestItem2
295 QuestItem3
296 QuestItem4
297 QuestItem5
298 QuestItem6
2 = WeaponSmith
3 = BarKeep
4 = Armorer
5 = Medic
6 = Peasant1
7 = Peasant2
8 = Peasant3
9 = Peasant4
10 = Peasant5
11 = Peasant6
12 = Peasant7
13 = Peasant8
14 = Peasant9
15 = Peasant10
16 = Peasant11
17 = Peasant12
18 = Peasant13
19 = Peasant14
20 = Peasant15
21 = Peasant16
22 = Peasant17
23 = Peasant18
24 = Peasant19
25 = Peasant20
26 = Peasant21
27 = Peasant22
37 = Beggar1
38 = Beggar2
39 = Beggar3
40 = Beggar4
41 = Beggar5
42 = Rebel1
43 = Rebel2
44 = Rebel3
45 = Rebel4
46 = Rebel5
47 = Rebel6
48 = Macil1
49 = Macil2
52 = AcolyteTan
53 = AcolyteRed
54 = AcolyteRust
55 = AcolyteGray
56 = AcolyteDGreen
57 = AcolyteGold
58 = AcolyteShadow
61 = Templar
62 = Oracle
63 = Loremaster
70 = AlienSpectre2
94 = InquisitorArm
121 = MedPatch
122 = MedicalKit
123 = SurgeryKit
124 = DegninOre
125 = MetalArmor
126 = LeatherArmor
129 = BaseKey
130 = GovsKey
131 = Passcard
132 = IDBadge
133 = PrisonKey
134 = SeveredHand
135 = Power1Key
136 = Power2Key
137 = Power3Key
138 = GoldKey
139 = IDCard
140 = SilverKey
141 = OracleKey
142 = MilitaryID
143 = OrderKey
144 = WarehouseKey
145 = BrassKey
146 = RedCrystalKey
147 = BlueCrystalKey
148 = ChapelKey
149 = CatacombKey
150 = SecurityKey
151 = CoreKey
152 = MaulerKey
153 = FactoryKey
154 = MineKey
155 = NewKey5
156 = ShadowArmor
157 = EnvironmentalSuit
158 = GuardUniform
159 = OfficersUniform
160 = StrifeMap
161 = Coin
162 = Gold10
163 = Gold25
164 = Gold50
165 = BeldinsRing
166 = OfferingChalice
167 = Ear
168 = Communicator
169 = Targeter
170 = HEGrenadeRounds
171 = PhosphorusGrenadeRounds
173 = ClipOfBullets
174 = BoxOfBullets
175 = MiniMissiles
176 = CrateOfMissiles
177 = EnergyPod
178 = EnergyPack
179 = PoisonBolts
180 = ElectricBolts
181 = AmmoSatchel
182 = AssaultGun
183 = AssaultGunStanding
184 = FlameThrower
185 = FlameThrowerParts
186 = MiniMissileLauncher
187 = Mauler
188 = StrifeCrossbow
189 = StrifeGrenadeLauncher
190 = Sigil1
191 = Sigil2
192 = Sigil3
193 = Sigil4
194 = Sigil5
196 = RatBuddy
230 = DeadCrusader
280 = AmmoFillup
281 = HealthFillup
282 = info
283 = RaiseAlarm
284 = OpenDoor222
285 = CloseDoor222
286 = PrisonPass
287 = UpgradeStamina
288 = UpgradeAccuracy
289 = InterrogatorReport
292 = OraclePass
293 = QuestItem1
294 = QuestItem2
295 = QuestItem3
296 = QuestItem4
297 = QuestItem5
298 = QuestItem6
}

View file

@ -3,8 +3,10 @@
IWad
{
Name = "The Adventures of Square"
Autoname = "square.square"
Game = "Doom"
Config = "Square"
Mapinfo = "mapinfo/mindefaults.txt"
MustContain = "SQU-IWAD", "E1A1"
BannerColors = "ff ff ff", "80 00 80"
}
@ -12,8 +14,10 @@ IWad
IWad
{
Name = "The Adventures of Square (Square-ware)"
Autoname = "square.squareware"
Game = "Doom"
Config = "Square"
Mapinfo = "mapinfo/mindefaults.txt"
MustContain = "SQU-SWE1", "E1A1"
BannerColors = "ff ff ff", "80 00 80"
}
@ -21,6 +25,7 @@ IWad
IWad
{
Name = "Harmony"
Autoname = "harmony"
Game = "Doom"
Config = "Harmony"
Mapinfo = "mapinfo/hacxharm.txt"
@ -33,7 +38,7 @@ IWad
Name = "Hacx 2.0"
Game = "Doom"
Config = "Hacx"
Autoname = "Hacx2"
Autoname = "hacx.hacx2"
Mapinfo = "mapinfo/hacxharm.txt"
MustContain = "MAP01", "HACX-E"
BannerColors = "ff ff ff", "00 88 22"
@ -44,7 +49,7 @@ IWad
Name = "Hacx: Twitch'n Kill"
Game = "Doom"
Config = "Hacx"
Autoname = "Hacx12"
Autoname = "hacx.hacx1"
Mapinfo = "mapinfo/hacxharm.txt"
MustContain = "MAP01", "HACX-R"
BannerColors = "00 00 a8", "a8 a8 a8"
@ -53,6 +58,7 @@ IWad
IWad
{
Name = "Action Doom 2: Urban Brawl"
Autoname = "urbanbrawl"
Game = "Doom"
Config = "UrbanBrawl"
Mapinfo = "mapinfo/urbanbrawl.txt"
@ -63,7 +69,7 @@ IWad
IWad
{
Name = "Chex(R) Quest 3"
Autoname = "Chex3"
Autoname = "chex.chex3"
Game = "Chex"
Config = "Chex"
Mapinfo = "mapinfo/chex.txt"
@ -75,7 +81,7 @@ IWad
IWad
{
Name = "Chex(R) Quest"
Autoname = "Chex1"
Autoname = "chex.chex1"
Game = "Chex"
Config = "Chex"
Mapinfo = "mapinfo/chex.txt"
@ -86,6 +92,7 @@ IWad
IWad
{
Name = "Strife: Quest for the Sigil"
Autoname = "strife"
Game = "Strife"
Config = "Strife"
Mapinfo = "mapinfo/strife.txt"
@ -99,7 +106,7 @@ IWad
Name = "Strife: Teaser (New Version)"
Game = "Strife"
Config = "Strife"
Autoname = "Strifeteaser2"
Autoname = "strifeteaser2"
Mapinfo = "mapinfo/strife.txt"
Compatibility = "Shareware", "Teaser2"
MustContain = "MAP33", "ENDSTRF", "INVCURS"
@ -111,7 +118,7 @@ IWad
Name = "Strife: Teaser (Old Version)"
Game = "Strife"
Config = "Strife"
Autoname = "Strifeteaser1"
Autoname = "strifeteaser1"
Mapinfo = "mapinfo/strife.txt"
Compatibility = "Shareware"
MustContain = "MAP33", "ENDSTRF"
@ -123,7 +130,7 @@ IWad
Name = "Hexen: Beyond Heretic"
Game = "Hexen"
Config = "Hexen"
Autoname = "Hexen1"
Autoname = "hexen.hexen"
Mapinfo = "mapinfo/hexen.txt"
Compatibility = "Poly1"
MustContain = "TITLE", "MAP01", "MAP40", "WINNOWR"
@ -133,7 +140,7 @@ IWad
IWad
{
Name = "Hexen: Deathkings of the Dark Citadel"
Autoname = "HexenDK"
Autoname = "hexen.deathkings"
Game = "Hexen"
Config = "Hexen"
Mapinfo = "mapinfo/hexen.txt"
@ -157,7 +164,7 @@ IWad
IWad
{
Name = "Blasphemer"
Autoname = "Blasphemer"
Autoname = "blasphemer"
Game = "Heretic"
Config = "Heretic"
Mapinfo = "mapinfo/heretic.txt"
@ -168,7 +175,7 @@ IWad
IWad
{
Name = "Heretic: Shadow of the Serpent Riders"
Autoname = "HereticSR"
Autoname = "heretic.shadow"
Game = "Heretic"
Config = "Heretic"
Mapinfo = "mapinfo/heretic.txt"
@ -182,7 +189,7 @@ IWad
Name = "Heretic"
Game = "Heretic"
Config = "Heretic"
Autoname = "Heretic1"
Autoname = "heretic.heretic"
Mapinfo = "mapinfo/heretic.txt"
MustContain = "E1M1", "E2M1", "TITLE", "MUS_E1M1"
BannerColors = "fc fc 00", "a8 00 00"
@ -202,8 +209,7 @@ IWad
IWad
{
Name = "FreeDM"
Autoname = "FreeDM"
Group = "Freedoom"
Autoname = "doom.freedoom.freedm"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/doom2.txt"
@ -214,8 +220,7 @@ IWad
IWad
{
Name = "Freedoom: Phase 2"
Autoname = "Freedoom2"
Group = "Freedoom"
Autoname = "doom.freedoom.phase2"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/doom2.txt"
@ -226,8 +231,7 @@ IWad
IWad
{
Name = "Freedoom: Phase 1"
Autoname = "Freedoom1"
Group = "Freedoom"
Autoname = "doom.freedoom.phase1"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/doom1.txt"
@ -238,8 +242,7 @@ IWad
IWad
{
Name = "Freedoom: Demo Version"
Autoname = "Freedoom1"
Group = "Freedoom"
Autoname = "doom.freedoom.demo"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/doom1.txt"
@ -250,7 +253,7 @@ IWad
IWad
{
Name = "DOOM: BFG Edition"
Autoname = "DoomBFG"
Autoname = "doom.doom1.bfg"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/ultdoom.txt"
@ -265,7 +268,7 @@ IWad
IWad
{
Name = "The Ultimate DOOM"
Autoname = "DoomU"
Autoname = "doom.doom1.ultimate"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/ultdoom.txt"
@ -279,7 +282,7 @@ IWad
IWad
{
Name = "DOOM Registered"
Autoname = "Doom1"
Autoname = "doom.doom1.registered"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/doom1.txt"
@ -304,7 +307,7 @@ IWad
IWad
{
Name = "Final Doom: TNT - Evilution"
Autoname = "TNT"
Autoname = "doom.doom2.tnt"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/tnt.txt"
@ -316,7 +319,7 @@ IWad
IWad
{
Name = "Final Doom: Plutonia Experiment"
Autoname = "Plutonia"
Autoname = "doom.doom2.plutonia"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/plutonia.txt"
@ -328,7 +331,7 @@ IWad
IWad
{
Name = "DOOM 2: BFG Edition"
Autoname = "Doom2BFG"
Autoname = "doom.doom2.bfg"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/doom2bfg.txt"
@ -342,7 +345,7 @@ IWad
IWad
{
Name = "DOOM 2: Hell on Earth"
Autoname = "Doom2"
Autoname = "doom.doom2.commercial"
Game = "Doom"
Config = "Doom"
Mapinfo = "mapinfo/doom2.txt"

View file

@ -0,0 +1,59 @@
// defines the minimum needed entries to let an unknown IWAD run
gameinfo
{
titlepage = "-NOFLAT-"
titletime = 999
infopage = "-NOFLAT-"
titlemusic = ""
advisorytime = 0
chatsound = ""
finalemusic = ""
finaleflat = "-NOFLAT-"
finalepage = "-NOFLAT-"
quitsound = ""
borderflat = "-NOFLAT-"
border = DoomBorder
telefogheight = 0
defkickback = 100
skyflatname = "F_SKY1"
translator = "xlat/doom.txt"
defaultbloodcolor = "68 00 00"
defaultbloodparticlecolor = "ff 00 00"
backpacktype = "Backpack"
armoricons = "AICNA0", 0.75, "AICNC0"
statusbar = "sbarinfo/doom.txt"
intermissionmusic = ""
intermissioncounter = true
dimcolor = "6f 00 6b"
dimamount = 0.8
definventorymaxamount = 25
defaultrespawntime = 12
defaultdropstyle = 1
endoom = "ENDOOM"
player5start = 4001
pickupcolor = "c0 c0 c0"
quitmessages = "Do you want to quit?"
menufontcolor_title = "purple"
menufontcolor_label = "default"
menufontcolor_value = "gray"
menufontcolor_action = "gray"
menufontcolor_header = "blue"
menufontcolor_highlight = "lightblue"
menufontcolor_selection = "purple"
menubackbutton = "M_BACK_D"
playerclasses = "DoomPlayer"
pausesign = "-NOFLAT-"
gibfactor = 1
cursorpic = "doomcurs"
textscreenx = 10
textscreeny = 10
defaultendsequence = "Inter_Cast"
maparrow = "maparrows/arrow.txt", "maparrows/ddtarrow.txt"
statscreen_mapnamefont = "BigFont"
statscreen_finishedpatch = "WIF"
statscreen_enteringpatch = "WIENTER"
}
include "mapinfo/common.txt"