diff --git a/src/c_bind.cpp b/src/c_bind.cpp index 1a62469bc..0231820dc 100644 --- a/src/c_bind.cpp +++ b/src/c_bind.cpp @@ -43,158 +43,11 @@ #include "configfile.h" #include "i_system.h" #include "d_event.h" +#include "w_wad.h" #include #include -/* 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) diff --git a/src/c_bind.h b/src/c_bind.h index 4c9edb2bb..394d313c9 100644 --- a/src/c_bind.h +++ b/src/c_bind.h @@ -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); diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index aa6af4b43..8a9b5311b 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -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; } } } diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index 6a526a661..d72993cb7 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -185,9 +185,6 @@ static const char *KeyConfCommands[] = "clearplayerclasses" }; -static TArray 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 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 &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"); } diff --git a/src/c_dispatch.h b/src/c_dispatch.h index b494005c7..f9aeb0dc3 100644 --- a/src/c_dispatch.h +++ b/src/c_dispatch.h @@ -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 Commands; + TArray Pullins; + + void AddCommand(const char *cmd, const char *file = NULL); + void ExecCommands() const; + void AddPullins(TArray &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 diff --git a/src/compatibility.cpp b/src/compatibility.cpp index fd309ec8b..096811def 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -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; diff --git a/src/configfile.cpp b/src/configfile.cpp index 177c019fb..b8db74eb3 100644 --- a/src/configfile.cpp +++ b/src/configfile.cpp @@ -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 = §ion->RootEntry; section->Next = NULL; - memcpy (section->Name, name, namelen); - section->Name[namelen] = 0; + section->SectionName = name; *LastSectionPtr = section; LastSectionPtr = §ion->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) diff --git a/src/configfile.h b/src/configfile.h index 25c366f01..e125351dc 100644 --- a/src/configfile.h +++ b/src/configfile.h @@ -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; diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index 4a46a93cd..3fc365e8c 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -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 &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])); diff --git a/src/d_main.cpp b/src/d_main.cpp index aa247f95d..de5a7234a 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -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 &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 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; diff --git a/src/d_main.h b/src/d_main.h index dd2ffc409..afca8bc3b 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -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 mIWads; TArray mIWadNames; TArray 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 &wadfiles, const char *iwad, const char *zdoom_wad); public: + void ParseIWadInfos(const char *fn); const FIWADInfo *FindIWAD(TArray &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; + } + }; diff --git a/src/doomdata.h b/src/doomdata.h index b51dd5d20..71e581e26 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -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]; diff --git a/src/doomstat.cpp b/src/doomstat.cpp index 697ef3afe..2ec72db9d 100644 --- a/src/doomstat.cpp +++ b/src/doomstat.cpp @@ -69,4 +69,4 @@ int SinglePlayerClass[MAXPLAYERS]; bool ToggleFullscreen; int BorderTopRefresh; -FString LumpFilterGroup, LumpFilterIWAD; +FString LumpFilterIWAD; diff --git a/src/doomstat.h b/src/doomstat.h index d7f3796ac..835ef73fb 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -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 diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 57e436137..eb93cdbd6 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -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 (-tagnumSector->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 = §ors[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 = §ors[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 = §ors[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(§ors[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=§ors[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! } diff --git a/src/fragglescript/t_script.cpp b/src/fragglescript/t_script.cpp index 09c65d073..98911a418 100644 --- a/src/fragglescript/t_script.cpp +++ b/src/fragglescript/t_script.cpp @@ -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 = §ors[secnum]; if(sec->floordata || sec->ceilingdata || sec->lightingdata) diff --git a/src/g_doomedmap.cpp b/src/g_doomedmap.cpp index 9122232d5..bb2f18dc0 100644 --- a/src/g_doomedmap.cpp +++ b/src/g_doomedmap.cpp @@ -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); } diff --git a/src/g_game.cpp b/src/g_game.cpp index b1275239a..3012d04ff 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -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); diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 2a398e750..e0bddc9aa 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -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)) diff --git a/src/g_shared/a_skies.cpp b/src/g_shared/a_skies.cpp index 616b87c9e..d62a2a07b 100644 --- a/src/g_shared/a_skies.cpp +++ b/src/g_shared/a_skies.cpp @@ -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) diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index df1bf6daf..333dc1d26 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -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); } diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index 82f4b55d7..466832c48 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -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; diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index deb870774..30dc2276d 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -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(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 .AutoExec section does not exist, create it + // with a default autoexec.cfg file present. + CreateStandardAutoExec(section, false); + // Run any files listed in the .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 .AutoExec section does not exist, create it - // with a default autoexec.cfg file present. - CreateStandardAutoExec(section, false); - // Run any files listed in the .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; diff --git a/src/gameconfigfile.h b/src/gameconfigfile.h index 74376b583..5862bb79e 100644 --- a/src/gameconfigfile.h +++ b/src/gameconfigfile.h @@ -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]; diff --git a/src/info.h b/src/info.h index acd43f34d..2af62c824 100644 --- a/src/info.h +++ b/src/info.h @@ -279,7 +279,8 @@ inline PClassActor *PClass::FindActor(FName name) struct FDoomEdEntry { PClassActor *Type; - int Special; + short Special; + bool ArgsDefined; int Args[5]; }; diff --git a/src/m_misc.cpp b/src/m_misc.cpp index 7f4fa482d..1369bdb52 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -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); } diff --git a/src/m_misc.h b/src/m_misc.h index 9599306de..ea146c690 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -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); diff --git a/src/oplsynth/music_opldumper_mididevice.cpp b/src/oplsynth/music_opldumper_mididevice.cpp index 74bef0677..33e026c07 100644 --- a/src/oplsynth/music_opldumper_mididevice.cpp +++ b/src/oplsynth/music_opldumper_mididevice.cpp @@ -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(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(chips[0])->WriteDelay(ticks); } diff --git a/src/oplsynth/muslib.h b/src/oplsynth/muslib.h index 6cfb5bd55..8499a6bed 100644 --- a/src/oplsynth/muslib.h +++ b/src/oplsynth/muslib.h @@ -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 { diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index 58c2dbde7..42d79dcc0 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -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=§ors[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 { diff --git a/src/p_3dmidtex.cpp b/src/p_3dmidtex.cpp index 7f934e2f5..ff0d3a181 100644 --- a/src/p_3dmidtex.cpp +++ b/src/p_3dmidtex.cpp @@ -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)) { diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 819de6732..eafbd172e 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -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(§ors[secnum], args[2], seqname, 0); + SN_StartSequence(§ors[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) diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 4e7a8e45a..73cd11f23 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -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; } diff --git a/src/p_ceiling.cpp b/src/p_ceiling.cpp index d0c54761a..7efef80a5 100644 --- a/src/p_ceiling.cpp +++ b/src/p_ceiling.cpp @@ -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(§ors[secnum], type, line, tag, speed, speed2, height, crush, silent, change, hexencrush); } diff --git a/src/p_doors.cpp b/src/p_doors.cpp index 844f23af9..49ed20f46 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -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 = §ors[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 = §ors[secnum]; if (sec->ceilingdata != NULL) diff --git a/src/p_floor.cpp b/src/p_floor.cpp index 9a5a6eaf8..97e23571b 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -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 = §ors[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> 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 = §ors[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 = §ors[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 = §ors[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 = §ors[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 = §ors[sectorIndex]; -manual_waggle: if ((!ceiling && sector->PlaneMoving(sector_t::floor)) || (ceiling && sector->PlaneMoving(sector_t::ceiling))) { // Already busy with another thinker diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index 1b34e8bbc..547cecace 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -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; } } diff --git a/src/p_lights.cpp b/src/p_lights.cpp index 878b1f5c3..b4bfa1669 100644 --- a/src/p_lights.cpp +++ b/src/p_lights.cpp @@ -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 (§ors[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 = §ors[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 = §ors[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 (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 = §ors[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 = §ors[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 = §ors[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(); } diff --git a/src/p_linkedsectors.cpp b/src/p_linkedsectors.cpp index 2d06bc043..8f78aadda 100644 --- a/src/p_linkedsectors.cpp +++ b/src/p_linkedsectors.cpp @@ -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 != §ors[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]; diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 54ab60337..ec968d020 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -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(§ors[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 = §ors[secnum]; rtn = true; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 7f99cb81f..d9b904e69 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -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)); } diff --git a/src/p_pillar.cpp b/src/p_pillar.cpp index 809542949..884218bee 100644 --- a/src/p_pillar.cpp +++ b/src/p_pillar.cpp @@ -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 = §ors[secnum]; -manual_pillar: if (sec->PlaneMoving(sector_t::floor) || sec->PlaneMoving(sector_t::ceiling)) continue; diff --git a/src/p_plats.cpp b/src/p_plats.cpp index d87c30991..7600637b2 100644 --- a/src/p_plats.cpp +++ b/src/p_plats.cpp @@ -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 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 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 = §ors[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; } diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 904c76c1b..49d8db9f1 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -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; diff --git a/src/p_setup.cpp b/src/p_setup.cpp index ea4f5378b..3433c243b 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -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 &spots, TArray &anchors) { if (map->HasBehavior) diff --git a/src/p_setup.h b/src/p_setup.h index ee26f4c57..20caa5d76 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -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); diff --git a/src/p_slopes.cpp b/src/p_slopes.cpp index 41f7a1837..c0b9b5ef0 100644 --- a/src/p_slopes.cpp +++ b/src/p_slopes.cpp @@ -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; diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 7ca756b2b..74d4b6f17 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -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 (specialGeneric_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 = §ors[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(§ors[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(§ors[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(§ors[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(§ors[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 diff --git a/src/p_spec.h b/src/p_spec.h index 02b590ed9..64d73e8c4 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -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 diff --git a/src/p_teleport.cpp b/src/p_teleport.cpp index 59265b198..8ca54d0e4 100644 --- a/src/p_teleport.cpp +++ b/src/p_teleport.cpp @@ -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 = §ors[secnum]; diff --git a/src/p_terrain.h b/src/p_terrain.h index 7cf9ac387..6bebe20ce 100644 --- a/src/p_terrain.h +++ b/src/p_terrain.h @@ -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; } }; diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 31634ee81..657281a11 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -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); } diff --git a/src/p_user.cpp b/src/p_user.cpp index 3dc46524d..feef742af 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -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)); diff --git a/src/p_writemap.cpp b/src/p_writemap.cpp index 83ed40b5b..2f11ee5c1 100644 --- a/src/p_writemap.cpp +++ b/src/p_writemap.cpp @@ -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); diff --git a/src/p_xlat.cpp b/src/p_xlat.cpp index be2d154c3..76d0cb811 100644 --- a/src/p_xlat.cpp +++ b/src/p_xlat.cpp @@ -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 (); diff --git a/src/posix/cocoa/i_common.h b/src/posix/cocoa/i_common.h index 081466e87..545540b2f 100644 --- a/src/posix/cocoa/i_common.h +++ b/src/posix/cocoa/i_common.h @@ -128,6 +128,8 @@ enum kVK_UpArrow = 0x7E }; +static const NSOpenGLPixelFormatAttribute NSOpenGLPFAAllowOfflineRenderers = NSOpenGLPixelFormatAttribute(96); + #endif // prior to 10.5 diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index 350202a13..29e6bf4d4 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -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; diff --git a/src/posix/i_system.cpp b/src/posix/i_system.cpp index b3de61419..fd6bb4c0c 100644 --- a/src/posix/i_system.cpp +++ b/src/posix/i_system.cpp @@ -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( - 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(CFDataGetBytePtr(flavorData)); + UInt8* const buffer = reinterpret_cast(result.LockNewBuffer(bufferLength)); + + CFStringGetBytes(utf16, range, kCFStringEncodingUTF8, '?', false, buffer, bufferLength, NULL); + + result.UnlockBuffer(); } - CFRelease(flavorData); + CFRelease(utf16); } } - CFRelease(flavorTypeArray); - return result; #endif return ""; diff --git a/src/posix/osx/zdoom-info.plist b/src/posix/osx/zdoom-info.plist index 2a1911cdf..73be09aa8 100644 --- a/src/posix/osx/zdoom-info.plist +++ b/src/posix/osx/zdoom-info.plist @@ -43,5 +43,7 @@ NSPrincipalClass NSApplication + NSSupportsAutomaticGraphicsSwitching + YES diff --git a/src/posix/sdl/i_input.cpp b/src/posix/sdl/i_input.cpp index 6fff2d2a9..372b23446 100644 --- a/src/posix/sdl/i_input.cpp +++ b/src/posix/sdl/i_input.cpp @@ -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; diff --git a/src/posix/sdl/sdlvideo.cpp b/src/posix/sdl/sdlvideo.cpp index 309002456..c24fd797a 100644 --- a/src/posix/sdl/sdlvideo.cpp +++ b/src/posix/sdl/sdlvideo.cpp @@ -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; diff --git a/src/r_defs.h b/src/r_defs.h index dd2136508..3cf25573c 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -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 diff --git a/src/resourcefiles/file_directory.cpp b/src/resourcefiles/file_directory.cpp index f6adf0723..8b85425f1 100644 --- a/src/resourcefiles/file_directory.cpp +++ b/src/resourcefiles/file_directory.cpp @@ -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; diff --git a/src/resourcefiles/file_zip.cpp b/src/resourcefiles/file_zip.cpp index 5d6ff6c9e..c7e787c70 100644 --- a/src/resourcefiles/file_zip.cpp +++ b/src/resourcefiles/file_zip.cpp @@ -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; diff --git a/src/resourcefiles/resourcefile.cpp b/src/resourcefiles/resourcefile.cpp index ebeb40d96..11d60795e 100644 --- a/src/resourcefiles/resourcefile.cpp +++ b/src/resourcefiles/resourcefile.cpp @@ -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-/*". 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; } } } diff --git a/src/resourcefiles/resourcefile.h b/src/resourcefiles/resourcefile.h index 9927b1eae..e84967a24 100644 --- a/src/resourcefiles/resourcefile.h +++ b/src/resourcefiles/resourcefile.h @@ -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); diff --git a/src/sound/music_midi_timidity.cpp b/src/sound/music_midi_timidity.cpp index 38ba8557e..a8c099d52 100644 --- a/src/sound/music_midi_timidity.cpp +++ b/src/sound/music_midi_timidity.cpp @@ -2,6 +2,7 @@ #include "c_cvars.h" #include "cmdlib.h" #include "templates.h" +#include "version.h" #ifndef _WIN32 #include @@ -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); diff --git a/src/textures/animations.cpp b/src/textures/animations.cpp index ffff062c6..0290a293f 100644 --- a/src/textures/animations.cpp +++ b/src/textures/animations.cpp @@ -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. diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 478700103..a46766472 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -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, diff --git a/src/v_video.h b/src/v_video.h index 69741c7f8..5250cdaa9 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -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; } diff --git a/src/version.h b/src/version.h index cbbb8bd21..f45f58b2f 100644 --- a/src/version.h +++ b/src/version.h @@ -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. diff --git a/src/w_wad.cpp b/src/w_wad.cpp index 4d0b51623..2b3413460 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -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 diff --git a/src/w_wad.h b/src/w_wad.h index 262a332c6..63912373e 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -52,7 +52,7 @@ struct wadlump_t // [RH] Namespaces from BOOM. typedef enum { - ns_invalid = -1, + ns_hidden = -1, ns_global = 0, ns_sprites, diff --git a/src/win32/i_cd.cpp b/src/win32/i_cd.cpp index b4982b865..29167f276 100644 --- a/src/win32/i_cd.cpp +++ b/src/win32/i_cd.cpp @@ -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, diff --git a/src/win32/i_crash.cpp b/src/win32/i_crash.cpp index 453549ab7..0735e3553 100644 --- a/src/win32/i_crash.cpp +++ b/src/win32/i_crash.cpp @@ -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 diff --git a/src/win32/i_input.cpp b/src/win32/i_input.cpp index ed7c81cf1..a26ff320e 100644 --- a/src/win32/i_input.cpp +++ b/src/win32/i_input.cpp @@ -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; diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index 7647fea95..668c74f95 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -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); } diff --git a/src/win32/win32iface.h b/src/win32/win32iface.h index 2704de0fa..934931ea0 100644 --- a/src/win32/win32iface.h +++ b/src/win32/win32iface.h @@ -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; diff --git a/src/win32/win32video.cpp b/src/win32/win32video.cpp index b6d6d670e..8aa74bfb5 100644 --- a/src/win32/win32video.cpp +++ b/src/win32/win32video.cpp @@ -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 diff --git a/src/zstring.cpp b/src/zstring.cpp index 14d19f46f..510ff19d7 100644 --- a/src/zstring.cpp +++ b/src/zstring.cpp @@ -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 diff --git a/wadsrc/static/defbinds.txt b/wadsrc/static/defbinds.txt new file mode 100644 index 000000000..420d22432 --- /dev/null +++ b/wadsrc/static/defbinds.txt @@ -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" diff --git a/wadsrc/static/filter/doom/sndinfo.txt b/wadsrc/static/filter/game-doomchex/sndinfo.txt similarity index 99% rename from wadsrc/static/filter/doom/sndinfo.txt rename to wadsrc/static/filter/game-doomchex/sndinfo.txt index 6028b11f0..c103f493c 100644 --- a/wadsrc/static/filter/doom/sndinfo.txt +++ b/wadsrc/static/filter/game-doomchex/sndinfo.txt @@ -1,3 +1,4 @@ + /****************************************************************************/ /* */ /* DOOM SOUNDS */ diff --git a/wadsrc/static/filter/game-heretic/defbinds.txt b/wadsrc/static/filter/game-heretic/defbinds.txt new file mode 100644 index 000000000..ed820a378 --- /dev/null +++ b/wadsrc/static/filter/game-heretic/defbinds.txt @@ -0,0 +1,3 @@ +/* Default keybindings for Heretic */ + +backspace "use ArtiTomeOfPower" \ No newline at end of file diff --git a/wadsrc/static/filter/heretic/sndinfo.txt b/wadsrc/static/filter/game-heretic/sndinfo.txt similarity index 99% rename from wadsrc/static/filter/heretic/sndinfo.txt rename to wadsrc/static/filter/game-heretic/sndinfo.txt index cb3fe1e73..b9f1fd7c3 100644 --- a/wadsrc/static/filter/heretic/sndinfo.txt +++ b/wadsrc/static/filter/game-heretic/sndinfo.txt @@ -1,3 +1,4 @@ + /****************************************************************************/ /* */ /* HERETIC SOUNDS */ diff --git a/wadsrc/static/filter/game-hexen/defbinds.txt b/wadsrc/static/filter/game-hexen/defbinds.txt new file mode 100644 index 000000000..58167f57e --- /dev/null +++ b/wadsrc/static/filter/game-hexen/defbinds.txt @@ -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 \ No newline at end of file diff --git a/wadsrc/static/filter/hexen/sndinfo.txt b/wadsrc/static/filter/game-hexen/sndinfo.txt similarity index 99% rename from wadsrc/static/filter/hexen/sndinfo.txt rename to wadsrc/static/filter/game-hexen/sndinfo.txt index 85d7a75dd..a1169dcb9 100644 --- a/wadsrc/static/filter/hexen/sndinfo.txt +++ b/wadsrc/static/filter/game-hexen/sndinfo.txt @@ -1,3 +1,4 @@ + /****************************************************************************/ /* */ /* HEXEN SOUNDS */ diff --git a/wadsrc/static/acs/strfhelp.o b/wadsrc/static/filter/game-strife/acs/strfhelp.o similarity index 100% rename from wadsrc/static/acs/strfhelp.o rename to wadsrc/static/filter/game-strife/acs/strfhelp.o diff --git a/wadsrc/static/filter/game-strife/defbinds.txt b/wadsrc/static/filter/game-strife/defbinds.txt new file mode 100644 index 000000000..9370896a0 --- /dev/null +++ b/wadsrc/static/filter/game-strife/defbinds.txt @@ -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 diff --git a/wadsrc/static/filter/game-strife/loadacs.txt b/wadsrc/static/filter/game-strife/loadacs.txt new file mode 100644 index 000000000..eb41c01ae --- /dev/null +++ b/wadsrc/static/filter/game-strife/loadacs.txt @@ -0,0 +1 @@ +strfhelp diff --git a/wadsrc/static/filter/strife/sndinfo.txt b/wadsrc/static/filter/game-strife/sndinfo.txt similarity index 99% rename from wadsrc/static/filter/strife/sndinfo.txt rename to wadsrc/static/filter/game-strife/sndinfo.txt index 877bba50a..22f9b8356 100644 --- a/wadsrc/static/filter/strife/sndinfo.txt +++ b/wadsrc/static/filter/game-strife/sndinfo.txt @@ -1,3 +1,4 @@ + /****************************************************************************/ /* */ /* STRIFE SOUNDS */ diff --git a/wadsrc/static/filter/strifeteaser1/mapinfo/conversationids.txt b/wadsrc/static/filter/strifeteaser1/mapinfo/conversationids.txt index 268702d52..b1b6ae380 100644 --- a/wadsrc/static/filter/strifeteaser1/mapinfo/conversationids.txt +++ b/wadsrc/static/filter/strifeteaser1/mapinfo/conversationids.txt @@ -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 } diff --git a/wadsrc/static/iwadinfo.txt b/wadsrc/static/iwadinfo.txt index 0fcdd9b87..6c958ddfa 100644 --- a/wadsrc/static/iwadinfo.txt +++ b/wadsrc/static/iwadinfo.txt @@ -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" diff --git a/wadsrc/static/mapinfo/mindefaults.txt b/wadsrc/static/mapinfo/mindefaults.txt new file mode 100644 index 000000000..cbb3fa06b --- /dev/null +++ b/wadsrc/static/mapinfo/mindefaults.txt @@ -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"