diff --git a/src/s_sound.c b/src/s_sound.c index 0235d8376..83000d321 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1466,31 +1466,38 @@ static UINT16 W_CheckForMusicDefInPwad(UINT16 wadid) void S_LoadMusicDefs(UINT16 wadnum) { - UINT16 lump; - char *buf; - char *buf2; + UINT16 lumpnum; + char *lump, *buf; + char *musdeftext; char *stoken; char *value; + char *textline; size_t size; INT32 i; musicdef_t *def = NULL; UINT16 line = 1; // for better error msgs - lump = W_CheckForMusicDefInPwad(wadnum); - if (lump == INT16_MAX) + lumpnum = W_CheckForMusicDefInPwad(wadnum); + if (lumpnum == INT16_MAX) return; - buf = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE); - size = W_LumpLengthPwad(wadnum, lump); + 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 - buf2 = malloc(size+1); - if (!buf2) - I_Error("S_LoadMusicDefs: No more free memory\n"); - M_Memcpy(buf2,buf,size); - buf2[size] = '\0'; + 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 (buf2, "\r\n "); + stoken = strtok(buf, "\r\n "); // Find music def while (stoken) { @@ -1562,9 +1569,47 @@ skip_lump: } else { - value = strtok(NULL, "\r\n= "); + // If this is set true, the line was invalid. + boolean brokenline = false; + // Delimit only by line break. + value = strtok(NULL, "\r\n"); + + // Find the equals sign. + value = strchr(value, '='); + + // It's not there?! if (!value) + brokenline = true; + else + { + // Skip the equals sign. + value++; + + // Now skip funny whitespace. + if (value[0] == '\0') // :NOTHING: + brokenline = true; + else + 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 @@ -1574,53 +1619,45 @@ skip_lump: 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); + free(textline); + free(buf); + free(musdeftext); return; } - i = atoi(value); + i = atoi(textline); 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. + 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, value); - for (value = def->source; *value; value++) - if (*value == '_') *value = ' '; // turn _ into spaces. + STRBUFCPY(def->source, textline); //CONS_Printf("S_LoadMusicDefs: Set source to '%s'\n", def->usage); #endif } else if (!stricmp(stoken, "title")) { - STRBUFCPY(def->title, value); - for (value = def->title; *value; value++) - if (*value == '_') *value = ' '; // turn _ into spaces. + STRBUFCPY(def->title, textline); //CONS_Printf("S_LoadMusicDefs: Set title to '%s'\n", def->source); } else if (!stricmp(stoken, "alttitle")) { - STRBUFCPY(def->alttitle, value); - for (value = def->alttitle; *value; value++) - if (*value == '_') *value = ' '; // turn _ into spaces. + STRBUFCPY(def->alttitle, textline); //CONS_Printf("S_LoadMusicDefs: Set alttitle to '%s'\n", def->source); } else if (!stricmp(stoken, "authors")) { - STRBUFCPY(def->authors, value); - for (value = def->authors; *value; value++) - if (*value == '_') *value = ' '; // turn _ into spaces. + STRBUFCPY(def->authors, textline); //CONS_Printf("S_LoadMusicDefs: Set authors to '%s'\n", def->source); } else if (!stricmp(stoken, "soundtestpage")) { def->soundtestpage = (UINT8)i; } else if (!stricmp(stoken, "soundtestcond")) { // Convert to map number - if (value[0] >= 'A' && value[0] <= 'Z' && value[2] == '\0') - i = M_MapNumber(value[0], value[1]); + if (textline[0] >= 'A' && textline[0] <= 'Z' && textline[2] == '\0') + i = M_MapNumber(textline[0], textline[1]); def->soundtestcond = (INT16)i; } else if (!stricmp(stoken, "stoppingtime")) { - double stoppingtime = atof(value)*TICRATE; + double stoppingtime = atof(textline)*TICRATE; def->stoppingtics = (tic_t)stoppingtime; } else if (!stricmp(stoken, "bpm")) { - double bpm = atof(value); + double bpm = atof(textline); fixed_t bpmf = FLOAT_TO_FIXED(bpm); if (bpmf > 0) def->bpm = FixedDiv((60*TICRATE)<filename, line); } + // Free the temporary text line from memory. + free(textline); + skip_field: stoken = strtok(NULL, "\r\n= "); line++; } } - free(buf2); + free(buf); + free(musdeftext); return; } diff --git a/tools/musicdef-2.2.1/Makefile b/tools/musicdef-2.2.1/Makefile new file mode 100644 index 000000000..403d27b04 --- /dev/null +++ b/tools/musicdef-2.2.1/Makefile @@ -0,0 +1 @@ +musicdef-2.2.1: diff --git a/tools/musicdef-2.2.1/musicdef-2.2.1.c b/tools/musicdef-2.2.1/musicdef-2.2.1.c new file mode 100644 index 000000000..d73f16efc --- /dev/null +++ b/tools/musicdef-2.2.1/musicdef-2.2.1.c @@ -0,0 +1,76 @@ +/* +Copyright 2019 James R. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include + +#ifdef _WIN32 +#define strcasecmp _stricmp +#else +#include +#endif + +int +main (int ac, char **av) +{ + char line[256]; + char buf[256]; + char *var; + char *val; + char *p; + int n; + (void)ac; + (void)av; + fputs( + "Copyright 2019 James R.\n" + "All rights reserved.\n" + "\n" + "Usage: musicdef-2.2.1 < old-MUSICDEF > new-MUSICDEF\n" + "\n" + ,stderr); + while (fgets(line, sizeof line, stdin)) + { + memcpy(buf, line, sizeof buf); + if (( var = strtok(buf, " =") )) + { + if (!( + strcasecmp(var, "TITLE") && + strcasecmp(var, "AUTHORS") + )){ + if (( val = strtok(0, "") )) + { + for (p = val; ( p = strchr(p, '_') ); ) + { + n = strspn(p, "_"); + memset(p, ' ', n); + p += n; + } + printf("%s %s", var, val); + continue; + } + } + } + fputs(line, stdout); + } + return 0; +}