Merge branch 'musicdef-versioning' into 'next'

MUSICDEF cleanup, fixes, and VERSION directive to opt into new format

See merge request STJr/SRB2!708
This commit is contained in:
SteelT 2020-01-24 17:06:58 -05:00
commit c7b4054a7a
1 changed files with 210 additions and 159 deletions

View File

@ -1441,6 +1441,12 @@ static tic_t pause_starttic;
/// Music Definitions
/// ------------------------
enum
{
MUSICDEF_220,
MUSICDEF_221,
};
musicdef_t soundtestsfx = {
"_STSFX", // prevents exactly one valid track name from being used on the sound test
"Sound Effects",
@ -1472,188 +1478,164 @@ static UINT16 W_CheckForMusicDefInPwad(UINT16 wadid)
return INT16_MAX; // not found
}
void S_LoadMusicDefs(UINT16 wadnum)
static void
MusicDefStrcpy (char *p, const char *s, size_t n, int version)
{
UINT16 lumpnum;
char *lump, *buf;
char *musdeftext;
char *stoken;
strlcpy(p, s, n);
if (version == MUSICDEF_220)
{
while (( p = strchr(p, '_') ))
*p++ = ' '; // turn _ into spaces.
}
}
static boolean
ReadMusicDefFields (UINT16 wadnum, int line, boolean fields, char *stoken,
musicdef_t **defp, int *versionp)
{
musicdef_t *def;
int version;
char *value;
char *textline;
size_t size;
INT32 i;
musicdef_t *def = NULL;
UINT16 line = 1; // for better error msgs
int i;
lumpnum = W_CheckForMusicDefInPwad(wadnum);
if (lumpnum == INT16_MAX)
return;
lump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
size = W_LumpLengthPwad(wadnum, lumpnum);
// Null-terminated MUSICDEF lump.
musdeftext = malloc(size+1);
if (!musdeftext)
I_Error("S_LoadMusicDefs: No more free memory for the parser\n");
M_Memcpy(musdeftext, lump, size);
musdeftext[size] = '\0';
// for strtok
buf = malloc(size+1);
if (!buf)
I_Error("S_LoadMusicDefs: No more free memory for the parser\n");
M_Memcpy(buf, musdeftext, size+1);
stoken = strtok(buf, "\r\n ");
// Find music def
while (stoken)
if (!stricmp(stoken, "lump"))
{
/*if ((stoken[0] == '/' && stoken[1] == '/')
|| (stoken[0] == '#')) // skip comments
value = strtok(NULL, " ");
if (!value)
{
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*/
{
musicdef_t *prev = NULL;
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);
def->bpm = TICRATE<<(FRACBITS-1); // FixedDiv((60*TICRATE)<<FRACBITS, 120<<FRACBITS)
if (prev != NULL)
prev->next = def;
//CONS_Printf("S_LoadMusicDefs: Added song '%s'\n", def->name);
}
}
skip_lump:
stoken = strtok(NULL, "\r\n ");
line++;
CONS_Alert(CONS_WARNING,
"MUSICDEF: Field '%s' is missing name. (file %s, line %d)\n",
stoken, wadfiles[wadnum]->filename, line);
return false;
}
else
{
// If this is set true, the line was invalid.
boolean brokenline = false;
musicdef_t *prev = NULL;
def = musicdefstart;
// Delimit only by line break.
value = strtok(NULL, "\r\n");
// 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;
}
// Find the equals sign.
value = strchr(value, '=');
prev = def;
def = def->next;
}
// It's not there?!
// Nothing found, add to the end.
if (!def)
{
def = Z_Calloc(sizeof (musicdef_t), PU_STATIC, NULL);
STRBUFCPY(def->name, value);
strlwr(def->name);
def->bpm = TICRATE<<(FRACBITS-1); // FixedDiv((60*TICRATE)<<FRACBITS, 120<<FRACBITS)
if (prev != NULL)
prev->next = def;
//CONS_Printf("S_LoadMusicDefs: Added song '%s'\n", def->name);
}
(*defp) = def;
}
}
else if (!stricmp(stoken, "version"))
{
if (fields)/* is this not the first field? */
{
CONS_Alert(CONS_WARNING,
"MUSICDEF: Field '%s' must come first. (file %s, line %d)\n",
stoken, wadfiles[wadnum]->filename, line);
return false;
}
else
{
value = strtok(NULL, " ");
if (!value)
brokenline = true;
{
CONS_Alert(CONS_WARNING,
"MUSICDEF: Field '%s' is missing version. (file %s, line %d)\n",
stoken, wadfiles[wadnum]->filename, line);
return false;
}
else
{
if (strcasecmp(value, "2.2.0"))
(*versionp) = MUSICDEF_221;
}
}
}
else
{
version = (*versionp);
if (version == MUSICDEF_220)
value = strtok(NULL, " =");
else
{
value = strtok(NULL, "");
if (value)
{
// Find the equals sign.
value = strchr(value, '=');
}
}
if (!value)
{
CONS_Alert(CONS_WARNING,
"MUSICDEF: Field '%s' is missing value. (file %s, line %d)\n",
stoken, wadfiles[wadnum]->filename, line);
return false;
}
else
{
def = (*defp);
if (!def)
{
CONS_Alert(CONS_ERROR,
"MUSICDEF: No music definition before field '%s'. (file %s, line %d)\n",
stoken, wadfiles[wadnum]->filename, line);
return false;
}
if (version != MUSICDEF_220)
{
// Skip the equals sign.
value++;
// Now skip funny whitespace.
if (value[0] == '\0') // :NOTHING:
brokenline = true;
else
value += strspn(value, "\t ");
value += strspn(value, "\t ");
}
// If the line is valid, copy the text line from the lump data.
if (!brokenline)
{
// strtok returns memory that already belongs to the input string.
value = musdeftext + (value - buf);
// Find the length of the line.
size = strcspn(value, "\r\n");
// Copy the line.
textline = malloc(size+1);
if (!textline)
I_Error("S_LoadMusicDefs: No more free memory for text line\n");
M_Memcpy(textline, value, size);
textline[size] = '\0';
}
else
{
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(textline);
free(buf);
free(musdeftext);
return;
}
i = atoi(textline);
textline = value;
i = atoi(value);
/* based ignored lumps */
if (!stricmp(stoken, "usage")) {
#if 0 // Ignore for now
STRBUFCPY(def->usage, textline);
//CONS_Printf("S_LoadMusicDefs: Set usage to '%s'\n", def->usage);
#endif
} else if (!stricmp(stoken, "source")) {
#if 0 // Ignore for now
STRBUFCPY(def->source, textline);
//CONS_Printf("S_LoadMusicDefs: Set source to '%s'\n", def->usage);
#endif
} else if (!stricmp(stoken, "title")) {
STRBUFCPY(def->title, textline);
//CONS_Printf("S_LoadMusicDefs: Set title to '%s'\n", def->source);
MusicDefStrcpy(def->title, textline,
sizeof def->title, version);
} else if (!stricmp(stoken, "alttitle")) {
STRBUFCPY(def->alttitle, textline);
//CONS_Printf("S_LoadMusicDefs: Set alttitle to '%s'\n", def->source);
MusicDefStrcpy(def->alttitle, textline,
sizeof def->alttitle, version);
} else if (!stricmp(stoken, "authors")) {
STRBUFCPY(def->authors, textline);
//CONS_Printf("S_LoadMusicDefs: Set authors to '%s'\n", def->source);
MusicDefStrcpy(def->authors, textline,
sizeof def->authors, version);
} else if (!stricmp(stoken, "soundtestpage")) {
def->soundtestpage = (UINT8)i;
} else if (!stricmp(stoken, "soundtestcond")) {
@ -1670,21 +1652,90 @@ skip_lump:
if (bpmf > 0)
def->bpm = FixedDiv((60*TICRATE)<<FRACBITS, bpmf);
} else {
CONS_Alert(CONS_WARNING, "MUSICDEF: Invalid field '%s'. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
CONS_Alert(CONS_WARNING,
"MUSICDEF: Invalid field '%s'. (file %s, line %d)\n",
stoken, wadfiles[wadnum]->filename, line);
}
// Free the temporary text line from memory.
free(textline);
skip_field:
stoken = strtok(NULL, "\r\n= ");
line++;
}
}
free(buf);
return true;
}
void S_LoadMusicDefs(UINT16 wadnum)
{
UINT16 lumpnum;
char *lump;
char *musdeftext;
size_t size;
char *lf;
char *stoken;
size_t nlf;
size_t ncr;
musicdef_t *def = NULL;
int version = MUSICDEF_220;
int line = 1; // for better error msgs
boolean fields = false;
lumpnum = W_CheckForMusicDefInPwad(wadnum);
if (lumpnum == INT16_MAX)
return;
lump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
size = W_LumpLengthPwad(wadnum, lumpnum);
// Null-terminated MUSICDEF lump.
musdeftext = malloc(size+1);
if (!musdeftext)
I_Error("S_LoadMusicDefs: No more free memory for the parser\n");
M_Memcpy(musdeftext, lump, size);
musdeftext[size] = '\0';
// Find music def
stoken = musdeftext;
for (;;)
{
lf = strpbrk(stoken, "\r\n");
if (lf)
{
if (*lf == '\n')
nlf = 1;
else
nlf = 0;
*lf++ = '\0';/* now we can delimit to here */
}
stoken = strtok(stoken, " ");
if (stoken)
{
if (! ReadMusicDefFields(wadnum, line, fields, stoken,
&def, &version))
break;
fields = true;
}
if (lf)
{
do
{
line += nlf;
ncr = strspn(lf, "\r");/* skip CR */
lf += ncr;
nlf = strspn(lf, "\n");
lf += nlf;
}
while (nlf || ncr) ;
stoken = lf;/* now the next nonempty line */
}
else
break;/* EOF */
}
free(musdeftext);
return;
}
//