Add MUSICDEF lump for defining custom songs & replacing existing songs

Very rudimentary at the moment, but it's workable
This commit is contained in:
TehRealSalt 2019-01-09 21:00:45 -05:00
parent 72bc1b48f6
commit de72403fb9
8 changed files with 233 additions and 158 deletions

View file

@ -1350,6 +1350,7 @@ void D_SRB2Main(void)
I_StartupSound();
I_InitMusic();
S_InitSfxChannels(cv_soundvolume.value);
S_InitMusicDefs();
CONS_Printf("ST_Init(): Init status bar.\n");
ST_Init();

View file

@ -2130,12 +2130,18 @@ static void HU_DrawDemoInfo(void)
//
static void HU_DrawSongCredits(void)
{
const char *str = va("\x1F"" %s", songCredits[cursongcredit.index].info);
INT32 len = V_ThinStringWidth(str, V_ALLOWLOWERCASE|V_6WIDTHSPACE);
INT32 destx = (len+7);
char *str;
INT32 len, destx;
INT32 y = (splitscreen ? (BASEVIDHEIGHT/2)-4 : 32);
INT32 bgt;
if (!cursongcredit.def) // No def
return;
str = va("\x1F"" %s", cursongcredit.def->source);
len = V_ThinStringWidth(str, V_ALLOWLOWERCASE|V_6WIDTHSPACE);
destx = (len+7);
if (cursongcredit.anim)
{
if (cursongcredit.trans > 0)

View file

@ -4446,7 +4446,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (P_IsLocalPlayer(player) && leveltime == (starttime + (TICRATE/2)))
{
S_ChangeMusicInternal(mapmusname, true);
S_InitMusicCredit();
S_ShowMusicCredit();
}
}

View file

@ -3439,6 +3439,11 @@ boolean P_AddWadFile(const char *wadfilename)
//
R_AddSkins(wadnum); // faB: wadfile index in wadfiles[]
//
// edit music defs
//
S_LoadMusicDefs(wadnum);
//
// search for maps
//

View file

@ -2450,7 +2450,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
mapmusflags |= MUSIC_RELOADRESET;
S_ChangeMusic(mapmusname, mapmusflags, !(line->flags & ML_EFFECT4));
S_InitMusicCredit();
S_ShowMusicCredit();
// Except, you can use the ML_BLOCKMONSTERS flag to change this behavior.
// if (mapmusflags & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn.

View file

@ -1541,131 +1541,209 @@ static void *music_data;
static UINT16 music_flags;
static boolean music_looping;
songcredits_t songCredits[] = {
// Race maps
{"kmap01","Toot Toot Sonic Warrior (Instrumental) - Sonic CD"},
{"kmap02","Chao Race (Extended Mix) - Sonic Adventure 2"},
{"kmap03","Touhou 10.5: Broken Moon (Jazz Arrangement) - Tokyo Active NEETs"},
{"kmap04","Mortvia Fountain - Castlevania: Curse of Darkness"},
{"kmap05","Let's Go Away - Daytona USA"},
{"kmap06","War Machine - Marvel vs. Capcom"},
{"kmap07","Sonic 3D Blast: Green Grove Zone, Act 1 (Remix) - Tee Lopes"},
{"kmap08","Sonic Drift 2: Hill Top (Remix) - SeventhSentinel"},
{"kmap09","Industrial District - Columns III"},
{"kmap10","Dream Uneven Bars - Mario & Sonic at the London 2012 Olympic Games"},
{"kmap11","Moon Palace 2 - Drift City"},
{"kmap12","Authentic Sky - Tekken 4"},
{"kmap13","Plant Man's Stage - Rockman 6 Complete Works"},
{"kmap14","Twinkle Cart - Sonic Adventure"},
{"kmap15","Pleasure Castle - Sonic Adventure"},
{"kmap16","Horizon Heights Zone, Act 2 - Sonic: After the Sequel"},
{"kmap17","Frost Man's Stage - Mega Man 8"},
{"kmap18","Foliage Furnace Zone, Act 1 - Sonic: After the Sequel"},
{"kmap19","Sand Ocean - F-Zero"},
{"kmap20","El Anoir Field South - LaTale"},
{"kmap21","Western GunRun - LaTale"},
{"kmap22","Jr. Street - Mario Hoops 3 on 3"},
{"kmap23","Fight or Flight (Air Armada) - Rivals of Aether"},
{"kmap24","White Land I - F-Zero"},
{"kmap25","Donkey Kong Country: Fear Factory (Remix) - Vincent Rubinetti"},
{"kmap26","Desert Palace - Sonic the Hedgehog 3"},
{"kmap27","Aurora Atoll Zone - SeventhSentinel"},
{"kmap28","Hol Horse - JoJo's Bizarre Adventure (Arcade)"},
{"kmap29","Red Barrage Area - Sonic Adventure"},
{"kmap30","Reach Out To The Truth - Persona 4 Arena"},
{"kmap31","Ave de Rapina - Beatmania IIDX 7th Style"},
{"kmap32","Atomic Waste Zone - Michael Staple"},
{"kmap33","Desert Area - LaTale"},
{"kmap34","DuckTales: The Moon (Remix) - Chris Holland, Luke Kwing"},
{"kmap35","Eggman Empire Zone - Michael Staple"},
{"kmap36","Shooting Star - Elwood"},
{"kmap37","Vigaku (Theme of Ein) - Dead or Alive 2"},
{"kmap38","Lovely Gate 3 - Sonic Adventure 2"},
{"kmap39","The Biggest Dreamer - Digimon Rumble Arena"},
{"kmap40","Soft Collision - Mighty Switch Force 2"},
{"kmap41","Ganbare Dochu - Konami Krazy Racers"},
{"kmap42","Theme of 'CHAO' - Sonic Adventure"},
{"kmap43","Join Us 4 Happy Time - Sonic Adventure"},
{"kmap44","Search ~ In the Midst - Ace Attorney: Justice for All"},
{"kmap45","Venezia, Italy - Tekken"},
{"kmap46","Balloon Panic - Sonic Drift 2"},
{"kmap47","Dimension Heist - Sonic Mania"},
{"kmap48","MKSC Sky Garden (Remix) - Mario Kart DS"},
{"kmap49","MKDS Peach Gardens (Remix) - Mario Kart Wii"},
{"kmap50","MKSC Rainbow Road (Remix) - Panman14"},
{"kmap51","Donut Plains - Super Mario Kart"},
{"kmap52","Mario Circuit - Super Mario Kart"},
{"kmap53","Ghost Valley - Super Mario Kart"},
{"kmap54","Bowser Castle - Super Mario Kart"},
{"kmap55","Vanilla Lake - Super Mario Kart"},
// Battle maps
{"kmapb0","Tropic Turf Zone, Act 1 - Karl Brueggemann"},
{"kmapb1","Seascape - Knuckles' Chaotix"},
{"kmapb2","Boss Challenge I - Diddy Kong Racing"},
{"kmapb3","Al's Toy Barn - Toy Story 2 (PS1)"},
{"kmapb4","SRB2: Techno Hill Zone, Act 1 (Remix) - SeventhSentinel"},
{"kmapb5","Sonic the Hedgehog: Marble Zone (Remix) - Tee Lopes"},
{"kmapb6","Phi Battle - Sonic Battle"},
{"kmapb7","Khan - JoJo's Bizarre Adventure (Arcade)"},
{"kmapb8","Underground - Wild Guns Reloaded"},
{"kmapb9","Disease Transport - DrTapeworm"},
{"kmapba","Shining Force II: Shrine (Remix) - gxf4c3"},
{"kmapbb","Bad Taste Aquarium - Sonic Adventure"},
{"kmapbc","Space Ship: Strut - Space Channel 5"},
{"kmapbd","Strollin' the City - Karl Brueggemann"},
{"kmapbe","Fakery Way - Sonic Adventure"},
{"kmapbf","Twinkle Circuit - Sonic Adventure"},
{"kmapbg","Never Let It Go - Sonic the Fighters"},
{"kmapbh","Power Plant - Sonic Heroes"},
{"kmapbi","Tails' Lab - Sonic Battle"},
{"kmapbj","Mega Man X: Armored Armadillo's Stage (Arranged) - Synthescissor"},
{"kmapbk","School Ordeal - Danganronpa V3: Killing Harmony"},
{"kmapbl","Mementos - Persona 5"},
{"kmapbm","Special Stage (US) - Sonic CD"},
{"kmapbn","Battle Mode - Super Mario Kart"},
{"kmapbp","Vanilla Lake (Beta) - Super Mario Kart"},
{"kmapbr","Choco Mountain - Mario Kart 64"},
// Hell maps
{"kmaph0","Neo City - Drift City"},
{"kmaph1","World Open Finals - Mario Power Tennis"},
{"kmaph2","Arid Sands: Day - Sonic Unleashed"},
{"kmaph3","Graveyard Gig - Sonic & All-Stars Racing Transformed"},
{"kmaph4","Dr. Robotnik's Mean Bean Machine: 2 Player (Remix) - Jonny Atma, The8BitDrummer"},
{"kmaph5","Living In One More City - Nib Roc"},
{"kmaph6","Ema Skye ~ Scientific Detective - Apollo Justice: Ace Attorney"},
{"kmaph7","4 Minutes Before Death - Ghost Trick: Phantom Detective"},
{"kmaph8","Napoleon Disappeared!? - Pop'n Music 10"},
{"kmaph9","Retro Maze - Pac-Man World Rally"},
{"kmapha","Midnight Freeze Zone - Arrow, SSNTails"},
{"kmaphb","Townsville Raceway - Cartoon Network Racing (DS)"},
{"kmaphc","F-Zero: Silence (Remix) - Tony Thai"},
{"kmaphd","Rainbow Road - Super Mario Kart"},
{"kmaphe","Meadow Match Zone - Arrow, SSNTails"},
{"kmaphf","merge-break - xaki"},
// Misc
{"titles","Fluvial Beat Deposits - Simon Stalenhag"}, // Stålenhag
{"vote", "Chaotic World - Knuckles' Chaotix"},
{"voteea","Decision - Knuckles' Chaotix"},
{"voteeb","Decision - Knuckles' Chaotix"},
{"kinvnc","Invincibility - Sonic the Hedgehog 3"},
{"kgrow", "Surging Power - Knuckles' Chaotix"},
{"kstart","Race Start - Diddy Kong Racing"},
{"estart","Phantom Ruby Ambience - Sonic Mania"},
{"krwin", "Practice - Sora"},
{"krok", "Practice - Sora"},
{"krlose","Hit 'Em Up (Instrumental) - 2Pac"},
{"krfail","Results - F-Zero"},
{"kbwin", "Wild Charabom Defeated! - Bomberman Tournament"},
{"kbok", "Deadly Bomber Base Cleared! - Bomberman Tournament"},
{"kblose","You Lose! - Bomberman Tournament"},
{"racent","Menu - Metropolis Street Racer"},
{"wait2j","Competition Results - Sonic the Hedgehog 3"},
{"chalng","Sonic the Hedgehog 3: Minor Boss (Dual PCM) - MarkeyJester"},
{"credit","Moot Booxle - Chomp"},
{NULL,NULL}
};
/// ------------------------
/// Music Definitions
/// ------------------------
struct cursongcredit cursongcredit;
musicdef_t *musicdefstart = NULL; // First music definition
struct cursongcredit cursongcredit; // Currently displayed song credit info
//
// search for music definition in wad
//
static UINT16 W_CheckForMusicDefInPwad(UINT16 wadid)
{
UINT16 i;
lumpinfo_t *lump_p;
lump_p = wadfiles[wadid]->lumpinfo;
for (i = 0; i < wadfiles[wadid]->numlumps; i++, lump_p++)
if (memcmp(lump_p->name, "MUSICDEF", 8) == 0)
return i;
return INT16_MAX; // not found
}
void S_LoadMusicDefs(UINT16 wadnum)
{
UINT16 lump;
char *buf;
char *buf2;
char *stoken;
char *value;
size_t size;
musicdef_t *def, *prev;
UINT16 line = 1; // for better error msgs
lump = W_CheckForMusicDefInPwad(wadnum);
if (lump == INT16_MAX)
return;
buf = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE);
size = W_LumpLengthPwad(wadnum, lump);
// for strtok
buf2 = malloc(size+1);
if (!buf2)
I_Error("S_LoadMusicDefs: No more free memory\n");
M_Memcpy(buf2,buf,size);
buf2[size] = '\0';
def = prev = NULL;
stoken = strtok (buf2, "\r\n ");
// Find music def
while (stoken)
{
/*if ((stoken[0] == '/' && stoken[1] == '/')
|| (stoken[0] == '#')) // skip comments
{
stoken = strtok(NULL, "\r\n"); // skip end of line
if (def)
stoken = strtok(NULL, "\r\n= ");
else
stoken = strtok(NULL, "\r\n ");
line++;
}
else*/ if (!stricmp(stoken, "lump"))
{
value = strtok(NULL, "\r\n ");
if (!value)
{
CONS_Alert(CONS_WARNING, "MUSICDEF: Lump '%s' is missing name. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
stoken = strtok(NULL, "\r\n"); // skip end of line
goto skip_lump;
}
// No existing musicdefs
if (!musicdefstart)
{
musicdefstart = Z_Calloc(sizeof (musicdef_t), PU_STATIC, NULL);
STRBUFCPY(musicdefstart->name, value);
strlwr(musicdefstart->name);
def = musicdefstart;
//CONS_Printf("S_LoadMusicDefs: Initialized musicdef w/ song '%s'\n", def->name);
}
else
{
def = musicdefstart;
// Search if this is a replacement
//CONS_Printf("S_LoadMusicDefs: Searching for song replacement...\n");
while (def)
{
if (!stricmp(def->name, value))
{
//CONS_Printf("S_LoadMusicDefs: Found song replacement '%s'\n", def->name);
break;
}
prev = def;
def = def->next;
}
// Nothing found, add to the end.
if (!def)
{
def = Z_Calloc(sizeof (musicdef_t), PU_STATIC, NULL);
STRBUFCPY(def->name, value);
strlwr(def->name);
if (prev != NULL)
prev->next = def;
//CONS_Printf("S_LoadMusicDefs: Added song '%s'\n", def->name);
}
}
skip_lump:
stoken = strtok(NULL, "\r\n ");
line++;
}
else
{
value = strtok(NULL, "\r\n= ");
if (!value)
{
CONS_Alert(CONS_WARNING, "MUSICDEF: Field '%s' is missing value. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
stoken = strtok(NULL, "\r\n"); // skip end of line
goto skip_field;
}
if (!def)
{
CONS_Alert(CONS_ERROR, "MUSICDEF: No music definition before field '%s'. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
free(buf2);
return;
}
if (!stricmp(stoken, "usage")) {
#if 0 // Ignore for now
STRBUFCPY(def->usage, value);
for (value = def->usage; *value; value++)
if (*value == '_') *value = ' '; // turn _ into spaces.
//CONS_Printf("S_LoadMusicDefs: Set usage to '%s'\n", def->usage);
#endif
} else if (!stricmp(stoken, "source")) {
STRBUFCPY(def->source, value);
for (value = def->source; *value; value++)
if (*value == '_') *value = ' '; // turn _ into spaces.
//CONS_Printf("S_LoadMusicDefs: Set source to '%s'\n", def->source);
} else {
CONS_Alert(CONS_WARNING, "MUSICDEF: Invalid field '%s'. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
}
skip_field:
stoken = strtok(NULL, "\r\n= ");
line++;
}
}
free(buf2);
return;
}
//
// S_InitMusicDefs
//
// Simply load music defs in all wads.
//
void S_InitMusicDefs(void)
{
UINT16 i;
for (i = 0; i < numwadfiles; i++)
S_LoadMusicDefs(i);
}
//
// S_ShowMusicCredit
//
// Display current song's credit on screen
//
void S_ShowMusicCredit(void)
{
musicdef_t *def = musicdefstart;
if (!cv_songcredits.value)
return;
if (!def) // No definitions
return;
while (def)
{
if (!stricmp(def->name, music_name))
{
cursongcredit.def = def;
cursongcredit.anim = 5*TICRATE;
cursongcredit.x = 0;
cursongcredit.trans = NUMTRANSMAPS;
return;
}
else
def = def->next;
}
}
/// ------------------------
/// Music Status
@ -1731,26 +1809,6 @@ boolean S_SpeedMusic(float speed)
return I_SetSongSpeed(speed);
}
void S_InitMusicCredit(void)
{
UINT16 i;
if (!cv_songcredits.value)
return;
for (i = 0; songCredits[i].lump; i++)
{
if (!stricmp(songCredits[i].lump, music_name))
{
cursongcredit.index = i;
cursongcredit.anim = 5*TICRATE;
cursongcredit.x = 0;
cursongcredit.trans = NUMTRANSMAPS;
return; // Don't return when there's SOC support, to see if there's any "replacement" credits?
}
}
}
/// ------------------------
/// Music Playback
/// ------------------------

View file

@ -129,23 +129,27 @@ boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi);
boolean S_SpeedMusic(float speed);
// Music credits
typedef struct musicdef_s
{
char name[7];
//char usage[256];
char source[256];
struct musicdef_s *next;
} musicdef_t;
extern struct cursongcredit
{
UINT16 index;
musicdef_t *def;
UINT16 anim;
INT32 x;
UINT8 trans;
} cursongcredit;
typedef struct
{
const char *lump;
const char *info;
} songcredits_t;
extern musicdef_t *musicdefstart;
extern songcredits_t songCredits[];
void S_InitMusicCredit(void);
void S_LoadMusicDefs(UINT16 wadnum);
void S_InitMusicDefs(void);
void S_ShowMusicCredit(void);
//
// Music Routines

View file

@ -1738,6 +1738,7 @@ int W_VerifyNMUSlumps(const char *filename)
{"MKFNT", 5}, // Kart font changes
{"K_", 2}, // Kart graphic changes
{"MUSICDEF", 8}, // Kart song definitions
{NULL, 0},
};