static VStr FindMainWad(VStr MainWad) { // First check in IWAD directories. for (int i = 0; i < IWadDirs.Num(); i++) { if (Sys_FileExists(IWadDirs[i] + "/" + MainWad)) { return IWadDirs[i] + "/" + MainWad; } } // Then look in the save directory. if (fl_savedir.IsNotEmpty() && Sys_FileExists(fl_savedir + "/" + MainWad)) { return fl_savedir + "/" + MainWad; } // Finally in base directory. if (Sys_FileExists(fl_basedir + "/" + MainWad)) { return fl_basedir + "/" + MainWad; } return VStr(); }
static void AddGameDir(const VStr& dir) { guard(AddGameDir); AddGameDir(fl_basedir, dir); if (fl_savedir.IsNotEmpty()) { AddGameDir(fl_savedir, dir); } fl_gamedir = dir; unguard; }
static void AddGameDir(const VStr& basedir, const VStr& dir) { guard(AddGameDir); // First add all .pk3 files in that directory. if (Sys_OpenDir(basedir + "/" + dir)) { TArray<VStr> ZipFiles; for (VStr test = Sys_ReadDir(); test.IsNotEmpty(); test = Sys_ReadDir()) { VStr ext = test.ExtractFileExtension().ToLower(); if (ext == "pk3") ZipFiles.Append(test); } Sys_CloseDir(); qsort(ZipFiles.Ptr(), ZipFiles.Num(), sizeof(VStr), cmpfunc); for (int i = 0; i < ZipFiles.Num(); i++) { AddZipFile(basedir + "/" + dir + "/" + ZipFiles[i]); } } // Then add wad##.wad files. VStr gwadir; if (fl_savedir.IsNotEmpty() && basedir != fl_savedir) { gwadir = fl_savedir + "/" + dir; } for (int i = 0; i < 1024; i++) { VStr buf = basedir + "/" + dir + "/wad" + i + ".wad"; if (!Sys_FileExists(buf)) break; W_AddFile(buf, gwadir, false); } // Finally add directory itself. VFilesDir* info = new VFilesDir(basedir + "/" + dir); SearchPaths.Append(info); unguard; }
void Info_SetValueForKey(VStr& s, const VStr& key, const VStr& value) { guard(Info_SetValueForKey); if (s.Length() >= MAX_INFO_STRING) { Host_Error("Info_SetValueForKey: oversize infostring"); } if (strchr(*key, '\\') || strchr(*value, '\\')) { GCon->Log("Can't use keys or values with a \\"); return; } if (strchr(*key, '\"') || strchr(*value, '\"')) { GCon->Log("Can't use keys or values with a \""); return; } // this next line is kinda trippy VStr v = Info_ValueForKey(s, key); if (v.IsNotEmpty()) { // Key exists, make sure we have enough room for new value, if we // don't, don't change it! if (value.Length() - v.Length() + s.Length() > MAX_INFO_STRING) { GCon->Log("Info string length exceeded"); return; } } Info_RemoveKey(s, key); if (value.IsEmpty()) return; VStr newi = VStr("\\") + key + "\\" + value; if (newi.Length() + s.Length() > MAX_INFO_STRING) { GCon->Log("Info string length exceeded"); return; } s = s + newi; unguard; }
VStream* FL_OpenFileWrite(const VStr& Name) { guard(FL_OpenFileWrite); VStr TmpName; if (fl_savedir.IsNotEmpty()) TmpName = fl_savedir + "/" + fl_gamedir + "/" + Name; else TmpName = fl_basedir + "/" + fl_gamedir + "/" + Name; FL_CreatePath(TmpName.ExtractFilePath()); FILE *File = fopen(*TmpName, "wb"); if (!File) { return NULL; } return new VStreamFileWriter(File, GCon); unguard; }
static void ParseBase(const VStr& name) { guard(ParseBase); TArray<version_t> games; bool select_game; VStr UseName; if (fl_savedir.IsNotEmpty() && Sys_FileExists(fl_savedir + "/" + name)) { UseName = fl_savedir + "/" + name; } else if (Sys_FileExists(fl_basedir + "/" + name)) { UseName = fl_basedir + "/" + name; } else { return; } select_game = false; VScriptParser* sc = new VScriptParser(UseName, FL_OpenSysFileRead(UseName)); while (!sc->AtEnd()) { version_t &dst = games.Alloc(); dst.ParmFound = 0; dst.FixVoices = false; sc->Expect("game"); sc->ExpectString(); dst.GameDir = sc->String; if (sc->Check("iwad")) { sc->ExpectString(); dst.MainWad = sc->String; } while (sc->Check("addfile")) { sc->ExpectString(); dst.AddFiles.Append(sc->String); } if (sc->Check("param")) { sc->ExpectString(); dst.ParmFound = GArgs.CheckParm(*sc->String); if (dst.ParmFound) { select_game = true; } } if (sc->Check("fixvoices")) { dst.FixVoices = true; } sc->Expect("end"); } delete sc; sc = NULL; for (int gi = games.Num() - 1; gi >= 0; gi--) { version_t& G = games[gi]; if (select_game && !G.ParmFound) { continue; } if (fl_mainwad.IsNotEmpty()) { if (G.MainWad.IsEmpty() || G.MainWad == fl_mainwad || select_game) { if (!bIwadAdded) { IWadIndex = SearchPaths.Num(); VStr MainWadPath = FindMainWad(fl_mainwad); W_AddFile(MainWadPath, fl_savedir, G.FixVoices); bIwadAdded = true; } for (int j = 0; j < G.AddFiles.Num(); j++) { W_AddFile(fl_basedir + "/" + G.AddFiles[j], fl_savedir, false); } SetupGameDir(G.GameDir); return; } continue; } if (G.MainWad.IsEmpty()) { continue; } // Look for the main wad file. VStr MainWadPath = FindMainWad(G.MainWad); if (MainWadPath.IsNotEmpty()) { fl_mainwad = G.MainWad; if (!bIwadAdded) { IWadIndex = SearchPaths.Num(); W_AddFile(MainWadPath, fl_savedir, G.FixVoices); bIwadAdded = true; } for (int j = 0; j < G.AddFiles.Num(); j++) { VStr FName = FindMainWad(G.AddFiles[j]); if (FName.IsEmpty()) { Sys_Error("Required file %s not found", *G.AddFiles[j]); } W_AddFile(FName, fl_savedir, false); } SetupGameDir(G.GameDir); return; } } if (select_game) Sys_Error("Main wad file not found."); else Sys_Error("Game mode indeterminate."); unguard; }
bool C_Responder(event_t* ev) { const char* cp; VStr str; int i; bool eat; // Respond to events only when console is active if (!C_Active()) return false; // We are iterested only in key down events if (ev->type != ev_keydown) return false; switch (ev->data1) { // Close console case K_ESCAPE: if (consolestate != cons_open) return false; case '`': if (consolestate == cons_closing) C_Start(); else C_Stop(); return true; // Execute entered command case K_ENTER: case K_PADENTER: // Print it GCon->Logf(">%s", c_iline.Data); // Add to history c_history_last = (MAXHISTORY + c_history_last - 1) % MAXHISTORY; if (c_history_size < MAXHISTORY) c_history_size++; VStr::Cpy(c_history[c_history_last], c_iline.Data); c_history_current = -1; // Add to command buffer GCmdBuf << c_iline.Data << "\n"; // Clear line c_iline.Init(); c_autocompleteIndex = -1; return true; // Scroll lines up case K_PAGEUP: for (i = 0; i < (GInput->ShiftDown ? 1 : 5); i++) { if (last_line > 1) { last_line--; } } return true; // Scroll lines down case K_PAGEDOWN: for (i = 0; i < (GInput->ShiftDown ? 1 : 5); i++) { if (last_line < num_lines) { last_line++; } } return true; // Go to first line case K_HOME: last_line = 1; return true; // Go to last line case K_END: last_line = num_lines; return true; // Command history up case K_UPARROW: c_history_current++; c_iline.Init(); if (c_history_current >= c_history_size) { c_history_current = c_history_size; } else { cp = c_history[(c_history_last + c_history_current) % MAXHISTORY]; while (*cp) c_iline.AddChar(*cp++); } c_autocompleteIndex = -1; return true; // Command history down case K_DOWNARROW: c_history_current--; c_iline.Init(); if (c_history_current < 0) { c_history_current = -1; } else { cp = c_history[(c_history_last + c_history_current) % MAXHISTORY]; while (*cp) c_iline.AddChar(*cp++); } c_autocompleteIndex = -1; return true; // Auto complete case K_TAB: if (!c_iline.Data[0]) return true; if (c_autocompleteIndex == -1) { c_autocompleteString = c_iline.Data; } str = VCommand::GetAutoComplete(c_autocompleteString, c_autocompleteIndex, GInput->ShiftDown ? true : false); if (str.IsNotEmpty()) { c_iline.Init(); for (i = 0; i < (int)str.Length(); i++) c_iline.AddChar(str[i]); c_iline.AddChar(' '); } return true; // Add character to input line default: eat = c_iline.Key((byte)ev->data1); if (eat) c_autocompleteIndex = -1; return eat; } }