diff --git a/source/common/filesystem/filesystem.cpp b/source/common/filesystem/filesystem.cpp index 373edd0fd..5594966ed 100644 --- a/source/common/filesystem/filesystem.cpp +++ b/source/common/filesystem/filesystem.cpp @@ -338,6 +338,44 @@ int FileSystem::GetFile (const char *name, ELookupMode lookupmode, int filenum) return i; } +//========================================================================== +// +// FindFile +// +// Looks up a file by name, either eith or without path and extension +// +//========================================================================== + +int FileSystem::FindFileWithExtensions(const char* name, const FName *exts, int count) +{ + uint32_t i; + + if (name == NULL) + { + return -1; + } + if (*name == '/') name++; // maps get a '/' prepended to their name. No idea what's the point, but this must be removed here. + FName lname(name, true); + if (lname == NAME_None) return -1; + + const int lookupindex = FResourceLump::FullNameNoExtType; + uint32_t* fli = FirstFileIndex[lookupindex]; + uint32_t* nli = NextFileIndex[lookupindex]; + + for (i = fli[int(lname) % NumEntries]; i != NULL_INDEX; i = nli[i]) + { + auto lump = FileInfo[i].lump; + if (lump->LumpName[lookupindex] == lname) + { + for (int c = 0; c < count; c++) + { + if (lump->LumpName[FResourceLump::ExtensionType] == exts[c]) return i; + } + } + } + return -1; +} + //========================================================================== // // FindResource diff --git a/source/common/filesystem/filesystem.h b/source/common/filesystem/filesystem.h index 3c9a5eedd..c7cc0d7af 100644 --- a/source/common/filesystem/filesystem.h +++ b/source/common/filesystem/filesystem.h @@ -97,6 +97,7 @@ public: int GetEntryCount(int filenum) const noexcept; int FindFile (const char *name, ELookupMode lookupmode = ELookupMode::FullName, int filenum = -1) const noexcept; + int FindFileWithExtensions(const char* name, const FName* exts, int count); int GetFile (const char *name, ELookupMode lookupmode = ELookupMode::FullName, int filenum = -1) const; // Like FindFile, but throws an exception when it cannot find what it looks for. bool FileExists(const char* name) { diff --git a/source/common/keyboard.h b/source/common/keyboard.h deleted file mode 100644 index a78ee99c9..000000000 --- a/source/common/keyboard.h +++ /dev/null @@ -1,39 +0,0 @@ -//------------------------------------------------------------------------- -/* -Copyright (C) 1996, 2003 - 3D Realms Entertainment - -This file is part of Duke Nukem 3D version 1.5 - Atomic Edition - -Duke Nukem 3D is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -Original Source: 1996 - Todd Replogle -Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms -Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au) -*/ -//------------------------------------------------------------------------- - -#pragma once - -#ifndef keyboard_public_h_ -#define keyboard_public_h_ - -#include "baselayer.h" // for the keyboard stuff -#include "scancodes.h" -#include "inputstate.h" -#include "c_bind.h" - - -#endif diff --git a/source/common/music/music.cpp b/source/common/music/music.cpp index 94e6bf212..900ddef65 100644 --- a/source/common/music/music.cpp +++ b/source/common/music/music.cpp @@ -53,6 +53,7 @@ #include "savegamehelp.h" #include "sjson.h" #include "v_text.h" +#include "mapinfo.h" MusPlayingInfo mus_playing; MusicAliasMap MusicAliases; @@ -64,6 +65,72 @@ static bool mus_blocked; static FString lastStartedMusic; EXTERN_CVAR(Float, mus_volume) CVAR(Bool, printmusicinfo, false, 0) +CVAR(Bool, mus_extendedlookup, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) + +// Order is: streaming formats, module formats, emulated formats and MIDI formats - for external files the first one found wins so ambiguous names should be avoided +static FName knownMusicExts[] = { + NAME_OGG, + NAME_FLAC, + NAME_MP3, + NAME_MP2, + NAME_XA, + NAME_XM, + NAME_MOD, + NAME_IT, + NAME_S3M, + NAME_MTM, + NAME_STM, + NAME_669, + NAME_PTM, + NAME_AMF, + NAME_OKT, + NAME_DSM, + NAME_AMFF, + NAME_SPC, + NAME_VGM, + NAME_VGZ, + NAME_AY, + NAME_GBS, + NAME_GYM, + NAME_HES, + NAME_KSS, + NAME_NSF, + NAME_NSFE, + NAME_SAP, + NAME_MID, + NAME_HMP, + NAME_HMI, + NAME_XMI, + NAME_VOC, +}; + +FString G_SetupFilenameBasedMusic(const char* fileName, const char* defmusic) +{ + FString name = fileName; + char* p; + + int index = name.LastIndexOf("."); + if (index >= 0) name.Truncate(index); + + // Test if a real file with this name exists with all known extensions for music. + for (auto& ext : knownMusicExts) + { + FStringf test("%s.%s", name.GetChars(), ext.GetChars()); + if (FileExists(test)) return test; +#ifdef __unix__ + test.Format("%s.%s", name.GetChars(), FString(ext).MakeLower().GetChars()); + if (FileExists(test)) return test; +#endif + } + return defmusic; +} + +FString MusicFileExists(const char* fn) +{ + if (mus_extendedlookup) return G_SetupFilenameBasedMusic(fn, nullptr); + if (FileExists(fn)) return fn; + return FString(); +} //========================================================================== // @@ -309,10 +376,11 @@ bool S_ChangeMusic(const char* musicname, int order, bool looping, bool force) } FileReader reader; - if (FileExists(musicname)) + FString mus = MusicFileExists(musicname); + if (mus.IsNotEmpty()) { // Load an external file. - reader.OpenFile(musicname); + reader.OpenFile(mus); } if (!reader.isOpen()) { @@ -671,3 +739,5 @@ void Mus_ResumeSaved() { S_RestartMusic(); } + + diff --git a/source/common/music/z_music.h b/source/common/music/z_music.h index 735661f65..d848de0b8 100644 --- a/source/common/music/z_music.h +++ b/source/common/music/z_music.h @@ -1,5 +1,7 @@ #pragma once +#include "zstring.h" + // Totally minimalistic interface - should be all the game modules need. void Mus_Init(); @@ -9,3 +11,4 @@ bool Mus_IsPlaying(); void Mus_Fade(double seconds); void Mus_SetPaused(bool on); void Mus_ResumeSaved(); +FString G_SetupFilenameBasedMusic(const char* fileName, const char *defaultfn); diff --git a/source/common/utility/namedef.h b/source/common/utility/namedef.h index 535d6a20f..e6690280d 100644 --- a/source/common/utility/namedef.h +++ b/source/common/utility/namedef.h @@ -14,11 +14,43 @@ xx(SEQ) xx(SFX) xx(RAW) xx(MAP) +xx(RFS) xx(WAV) xx(OGG) xx(FLAC) xx(VOC) -xx(RFS) +xx(MP3) +xx(XM) +xx(MOD) +xx(IT) +xx(S3M) +xx(MTM) +xx(MID) +xx(HMP) +xx(HMI) +xx(XMI) +xx(SPC) +xx(VGM) +xx(VGZ) +xx(MP2) +xx(XA) +xx(STM) +xx(669) +xx(PTM) +xx(AMF) +xx(OKT) +xx(DSM) +xx(AMFF) +xx(AY) +xx(GBS) +xx(GYM) +xx(HES) +xx(KSS) +xx(NSF) +xx(NSFE) +xx(SAP) + + xx(Controlmessage) xx(MainMenu) diff --git a/source/duke3d/src/premap.cpp b/source/duke3d/src/premap.cpp index 211157ba0..ac833b89d 100644 --- a/source/duke3d/src/premap.cpp +++ b/source/duke3d/src/premap.cpp @@ -1673,67 +1673,6 @@ static void G_LoadMapHack(char *outbuf, const char *filename) } } -// levnamebuf should have at least size BMAX_PATH -void G_SetupFilenameBasedMusic(char *nameBuf, const char *fileName) -{ - char *p; - char const *exts[] = { - "flac", - "ogg", - "mp3", - "xm", - "mod", - "it", - "s3m", - "mtm", - "mid", - "hmp", - "hmi", - "xmi" - }; - - Bstrncpy(nameBuf, fileName, BMAX_PATH); - - Bcorrectfilename(nameBuf, 0); - - if (NULL == (p = Bstrrchr(nameBuf, '.'))) - { - p = nameBuf + Bstrlen(nameBuf); - p[0] = '.'; - } - - // Test if a real file with this name exists with all known extensions for music. - for (auto & ext : exts) - { - Bmemcpy(p+1, ext, Bstrlen(ext) + 1); - - if (FileExists(nameBuf)) - { - userMapRecord.music = nameBuf; - return; - } - } - - auto &usermapMusic = mapList[MUS_USERMAP].music; - if (usermapMusic.IsNotEmpty()) - { - userMapRecord.music = usermapMusic; - return; - } - -#ifndef EDUKE32_STANDALONE - if (!FURY) - { - auto &e1l8 = mapList[7].music; - if (e1l8.IsNotEmpty()) - { - userMapRecord.music = e1l8; - return; - } - } -#endif -} - static void G_CheckIfStateless() { for (bssize_t i = 0; i < (MAXVOLUMES * MAXLEVELS); i++) @@ -1842,7 +1781,8 @@ int G_EnterLevel(int gameMode) currentLevel = &userMapRecord; STAT_NewLevel(boardfilename); G_LoadMapHack(levelName, boardfilename); - G_SetupFilenameBasedMusic(levelName, boardfilename); + + userMapRecord.music = G_SetupFilenameBasedMusic(boardfilename, mapList[MUS_USERMAP].music.IsNotEmpty()? mapList[MUS_USERMAP].music.GetChars() :(!FURY? mapList[7].music.GetChars() : nullptr)); } else if (engineLoadBoard(mm.fileName, VOLUMEONE, &p0.pos, &playerAngle, &p0.cursectnum) < 0) { diff --git a/source/duke3d/src/premap.h b/source/duke3d/src/premap.h index 5c1292e45..b3a80597c 100644 --- a/source/duke3d/src/premap.h +++ b/source/duke3d/src/premap.h @@ -27,7 +27,6 @@ BEGIN_DUKE_NS extern int32_t g_levelTextTime; extern int32_t voting,vote_map,vote_episode; -void G_SetupFilenameBasedMusic(char *nameBuf, const char *fileName); int G_EnterLevel(int gameMode); int G_FindLevelByFile(const char *fileName); void G_CacheMapData(void); diff --git a/source/rr/src/premap.cpp b/source/rr/src/premap.cpp index f75f22909..3b1d996ab 100644 --- a/source/rr/src/premap.cpp +++ b/source/rr/src/premap.cpp @@ -2231,49 +2231,6 @@ static void G_LoadMapHack(char *outbuf, const char *filename) } } -// levnamebuf should have at least size BMAX_PATH -void G_SetupFilenameBasedMusic(char *nameBuf, const char *fileName) -{ - char *p; - char const *exts[] = { - "flac", - "ogg", - "mp3", - "xm", - "mod", - "it", - "s3m", - "mtm", - "mid", - "hmp", - "hmi", - "xmi" - }; - - Bstrncpy(nameBuf, fileName, BMAX_PATH); - - Bcorrectfilename(nameBuf, 0); - - if (NULL == (p = Bstrrchr(nameBuf, '.'))) - { - p = nameBuf + Bstrlen(nameBuf); - p[0] = '.'; - } - - for (auto & ext : exts) - { - Bmemcpy(p+1, ext, Bstrlen(ext) + 1); - - if (FileExists(nameBuf)) - { - userMapRecord.music = nameBuf; - return; - } - } - - if (!RR) userMapRecord.music = "dethtoll.mid"; -} - int G_EnterLevel(int gameMode) { int32_t i, mii; @@ -2359,7 +2316,7 @@ int G_EnterLevel(int gameMode) currentLevel = &userMapRecord; STAT_NewLevel(boardfilename); G_LoadMapHack(levelName, boardfilename); - G_SetupFilenameBasedMusic(levelName, boardfilename); + userMapRecord.music = G_SetupFilenameBasedMusic(boardfilename, !RR? "dethtoll.mid" : nullptr); } else if (engineLoadBoard(mi.fileName, VOLUMEONE, &pPlayer->pos, &lbang, &pPlayer->cursectnum) < 0) { diff --git a/source/rr/src/premap.h b/source/rr/src/premap.h index 53117c2d4..99a309ada 100644 --- a/source/rr/src/premap.h +++ b/source/rr/src/premap.h @@ -29,7 +29,6 @@ extern int16_t g_ambientLotag[64]; extern int16_t g_ambientHitag[64]; extern int32_t g_levelTextTime; extern int32_t voting,vote_map,vote_episode; -void G_SetupFilenameBasedMusic(char *nameBuf, const char *fileName, int levelNum); int G_EnterLevel(int gameMode); int G_FindLevelByFile(const char *fileName); void G_CacheMapData(void);