mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-11-15 01:01:43 +00:00
Add MUSICDEF lump for defining custom songs & replacing existing songs
Very rudimentary at the moment, but it's workable
This commit is contained in:
parent
72bc1b48f6
commit
de72403fb9
8 changed files with 233 additions and 158 deletions
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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.
|
||||
|
|
346
src/s_sound.c
346
src/s_sound.c
|
@ -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
|
||||
/// ------------------------
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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},
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue