Merge branch 'music-credits' into 'next'

In-game music credits

See merge request KartKrew/Kart-Public!23
This commit is contained in:
Sal 2019-01-10 18:42:44 -05:00
commit d726185f8e
14 changed files with 344 additions and 14 deletions

0
debian-template/rules Executable file → Normal file
View file

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

@ -791,6 +791,7 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_consolechat);
CV_RegisterVar(&cv_chatnotifications);
CV_RegisterVar(&cv_chatbacktint);
CV_RegisterVar(&cv_songcredits);
//CV_RegisterVar(&cv_crosshair);
//CV_RegisterVar(&cv_crosshair2);
//CV_RegisterVar(&cv_crosshair3);

View file

@ -435,6 +435,9 @@ consvar_t cv_chatbacktint = {"chatbacktint", "On", CV_SAVE, CV_OnOff, NULL, 0, N
static CV_PossibleValue_t consolechat_cons_t[] = {{0, "Window"}, {1, "Console"}, {2, "Window (Hidden)"}, {0, NULL}};
consvar_t cv_consolechat = {"chatmode", "Window", CV_SAVE, consolechat_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// Display song credits
consvar_t cv_songcredits = {"songcredits", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
/*consvar_t cv_crosshair = {"crosshair", "Off", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_crosshair2 = {"crosshair2", "Off", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_crosshair3 = {"crosshair3", "Off", CV_SAVE, crosshair_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -2359,6 +2362,7 @@ void G_PlayerReborn(INT32 player)
INT32 bumper;
INT32 comebackpoints;
INT32 wanted;
boolean songcredit = false;
score = players[player].score;
marescore = players[player].marescore;
@ -2537,10 +2541,13 @@ void G_PlayerReborn(INT32 player)
strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
mapmusname[6] = 0;
mapmusflags = mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK;
songcredit = true;
}
}
P_RestoreMusic(p);
if (songcredit)
S_ShowMusicCredit();
if (leveltime > (starttime + (TICRATE/2)) && !p->spectator)
p->kartstuff[k_respawn] = 48; // Respawn effect

View file

@ -55,6 +55,7 @@ extern INT16 rw_maximums[NUM_WEAPONS];
// used in game menu
extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, cv_consolechat, cv_chatbacktint, cv_chatspamprotection/*, cv_compactscoreboard*/;
extern consvar_t cv_songcredits;
//extern consvar_t cv_crosshair, cv_crosshair2, cv_crosshair3, cv_crosshair4;
extern consvar_t cv_invertmouse/*, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove*/;
extern consvar_t cv_invertmouse2/*, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2*/;

View file

@ -51,6 +51,7 @@
#include "lua_hook.h"
#endif
#include "s_sound.h" // song credits
#include "k_kart.h"
// coords are scaled
@ -103,6 +104,8 @@ static patch_t *tokenicon;
// crosshair 0 = off, 1 = cross, 2 = angle, 3 = point, see m_menu.c
static patch_t *crosshair[HU_CROSSHAIRS]; // 3 precached crosshair graphics
// song credits
static patch_t *songcreditbg;
// -------
// protos.
@ -290,6 +293,8 @@ void HU_LoadGraphics(void)
tinyemeraldpics[4] = W_CachePatchName("TEMER5", PU_HUDGFX);
tinyemeraldpics[5] = W_CachePatchName("TEMER6", PU_HUDGFX);
tinyemeraldpics[6] = W_CachePatchName("TEMER7", PU_HUDGFX);
songcreditbg = W_CachePatchName("K_SONGCR", PU_HUDGFX);
}
// Initialise Heads up
@ -2119,6 +2124,51 @@ static void HU_DrawDemoInfo(void)
}
}
//
// Song credits
//
static void HU_DrawSongCredits(void)
{
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)
cursongcredit.trans--;
if (cursongcredit.x < destx)
cursongcredit.x += (destx - cursongcredit.x) / 2;
if (cursongcredit.x > destx)
cursongcredit.x = destx;
cursongcredit.anim--;
}
else
{
if (cursongcredit.trans < NUMTRANSMAPS)
cursongcredit.trans++;
if (cursongcredit.x > 0)
cursongcredit.x /= 2;
if (cursongcredit.x < 0)
cursongcredit.x = 0;
}
bgt = (NUMTRANSMAPS/2)+(cursongcredit.trans/2);
if (bgt < NUMTRANSMAPS)
V_DrawScaledPatch(cursongcredit.x, y-2, V_SNAPTOLEFT|(bgt<<V_ALPHASHIFT), songcreditbg);
if (cursongcredit.trans < NUMTRANSMAPS)
V_DrawRightAlignedThinString(cursongcredit.x, y, V_ALLOWLOWERCASE|V_6WIDTHSPACE|V_SNAPTOLEFT|(cursongcredit.trans<<V_ALPHASHIFT), str);
}
// Heads up displays drawer, call each frame
//
void HU_Drawer(void)
@ -2212,6 +2262,10 @@ void HU_Drawer(void)
HU_DrawCrosshair4();
}*/
// draw song credits
if (cv_songcredits.value)
HU_DrawSongCredits();
// draw desynch text
if (hu_resynching)
{

View file

@ -4444,7 +4444,10 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
// Plays the music after the starting countdown.
if (P_IsLocalPlayer(player) && leveltime == (starttime + (TICRATE/2)))
S_ChangeMusicInternal(mapmusname, true);
{
S_ChangeMusic(mapmusname, mapmusflags, true);
S_ShowMusicCredit();
}
}
void K_KartPlayerAfterThink(player_t *player)

View file

@ -1839,6 +1839,21 @@ static int lib_sStopSoundByID(lua_State *L)
return 0;
}
static int lib_sShowMusicCredit(lua_State *L)
{
player_t *player = NULL;
//HUDSAFE
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
S_ShowMusicCredit();
return 0;
}
static int lib_sChangeMusic(lua_State *L)
{
#ifdef MUSICSLOT_COMPATIBILITY
@ -2666,6 +2681,7 @@ static luaL_Reg lib[] = {
{"S_StartSoundAtVolume",lib_sStartSoundAtVolume},
{"S_StopSound",lib_sStopSound},
{"S_StopSoundByID",lib_sStopSoundByID},
{"S_ShowMusicCredit",lib_sShowMusicCredit},
{"S_ChangeMusic",lib_sChangeMusic},
{"S_SpeedMusic",lib_sSpeedMusic},
{"S_StopMusic",lib_sStopMusic},

View file

@ -2304,6 +2304,10 @@ static void P_LevelInitStuff(void)
// earthquake camera
memset(&quake,0,sizeof(struct quake));
// song credit init
memset(&cursongcredit,0,sizeof(struct cursongcredit));
cursongcredit.trans = NUMTRANSMAPS;
for (i = 0; i < MAXPLAYERS; i++)
{
#if 0
@ -2865,10 +2869,6 @@ boolean P_SetupLevel(boolean skipprecip)
// As oddly named as this is, this handles music only.
// We should be fine starting it here.
S_Start();
// SRB2 Kart - Yes this is weird, but we don't want the music to start until after the countdown is finished
// but we do still need the mapmusname to be changed
if (leveltime < (starttime + (TICRATE/2)))
S_ChangeMusicInternal((encoremode ? "estart" : "kstart"), false); //S_StopMusic();
levelfadecol = (encoremode && !ranspecialwipe ? 122 : 120);
@ -3435,6 +3435,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,6 +2450,8 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
mapmusflags |= MUSIC_RELOADRESET;
S_ChangeMusic(mapmusname, mapmusflags, !(line->flags & ML_EFFECT4));
if (!(line->flags & ML_EFFECT3))
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

@ -101,7 +101,7 @@ consvar_t cv_numChannels = {"snd_channels", "64", CV_SAVE|CV_CALL, CV_Unsigned,
#endif
consvar_t surround = {"surround", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_resetmusic = {"resetmusic", "No", CV_SAVE|CV_NOSHOWHELP, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
//consvar_t cv_resetmusic = {"resetmusic", "No", CV_SAVE|CV_NOSHOWHELP, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
// Sound system toggles, saved into the config
consvar_t cv_gamedigimusic = {"digimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameDigiMusic_OnChange, 0, NULL, NULL, 0, 0, NULL};
@ -263,7 +263,7 @@ void S_RegisterSoundStuff(void)
#endif
CV_RegisterVar(&surround);
CV_RegisterVar(&cv_samplerate);
CV_RegisterVar(&cv_resetmusic);
//CV_RegisterVar(&cv_resetmusic);
CV_RegisterVar(&cv_gamesounds);
CV_RegisterVar(&cv_gamedigimusic);
#ifndef NO_MIDI
@ -1541,6 +1541,210 @@ static void *music_data;
static UINT16 music_flags;
static boolean music_looping;
/// ------------------------
/// Music Definitions
/// ------------------------
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
/// ------------------------
@ -1839,9 +2043,13 @@ void S_Start(void)
mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
}
if (cv_resetmusic.value)
//if (cv_resetmusic.value) // Starting ambience should always be restarted
S_StopMusic();
S_ChangeMusic(mapmusname, mapmusflags, true);
if (leveltime < (starttime + (TICRATE/2))) // SRB2Kart
S_ChangeMusic((encoremode ? "estart" : "kstart"), 0, false);
else
S_ChangeMusic(mapmusname, mapmusflags, true);
}
static void Command_Tunes_f(void)
@ -1974,7 +2182,7 @@ void GameDigiMusic_OnChange(void)
if (Playing())
P_RestoreMusic(&players[consoleplayer]);
else
S_ChangeMusicInternal("lclear", false);
S_ChangeMusicInternal("titles", looptitle);
}
else
{
@ -2016,7 +2224,7 @@ void GameMIDIMusic_OnChange(void)
if (Playing())
P_RestoreMusic(&players[consoleplayer]);
else
S_ChangeMusicInternal("lclear", false);
S_ChangeMusicInternal("titles", looptitle);
}
else
{

View file

@ -27,7 +27,7 @@ extern consvar_t stereoreverse;
extern consvar_t cv_soundvolume, cv_digmusicvolume;//, cv_midimusicvolume;
extern consvar_t cv_numChannels;
extern consvar_t surround;
extern consvar_t cv_resetmusic;
//extern consvar_t cv_resetmusic;
extern consvar_t cv_gamedigimusic;
#ifndef NO_MIDI
extern consvar_t cv_gamemidimusic;
@ -128,6 +128,29 @@ boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi);
// Set Speed of Music
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
{
musicdef_t *def;
UINT16 anim;
INT32 x;
UINT8 trans;
} cursongcredit;
extern musicdef_t *musicdefstart;
void S_LoadMusicDefs(UINT16 wadnum);
void S_InitMusicDefs(void);
void S_ShowMusicCredit(void);
//
// Music Routines
//

View file

@ -2267,6 +2267,7 @@ INT32 V_ThinStringWidth(const char *string, INT32 option)
{
INT32 c, w = 0;
INT32 spacewidth = 2, charwidth = 0;
boolean lowercase = (option & V_ALLOWLOWERCASE);
size_t i;
switch (option & V_SPACINGMASK)
@ -2290,14 +2291,21 @@ INT32 V_ThinStringWidth(const char *string, INT32 option)
if ((UINT8)c >= 0x80 && (UINT8)c <= 0x8F) //color parsing! -Inuyasha 2.16.09
continue;
c = toupper(c) - HU_FONTSTART;
if (!lowercase || !tny_font[c-HU_FONTSTART])
c = toupper(c);
c -= HU_FONTSTART;
if (c < 0 || c >= HU_FONTSIZE || !tny_font[c])
w += spacewidth;
else
{
w += (charwidth ? charwidth
: (option & V_6WIDTHSPACE ? max(1, SHORT(tny_font[c]->width)-1) : SHORT(tny_font[c]->width))); // Reuse this flag for the alternate bunched-up spacing
: ((option & V_6WIDTHSPACE && i < strlen(string)-1) ? max(1, SHORT(tny_font[c]->width)-1) // Reuse this flag for the alternate bunched-up spacing
: SHORT(tny_font[c]->width)));
}
}
return w;
}

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},
};