Skip to content

Commit

Permalink
FS: Lump check may contain an optional size condition
Browse files Browse the repository at this point in the history
For instance, "CHAIN>=1000" would match a lump called CHAIN
only if the size of the lump is greater or equal than 1000.

This is intended primarily as a tool for identifying IWADs.
  • Loading branch information
skyjake committed Apr 12, 2012
1 parent 02ba6a4 commit c1bdb1b
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 5 deletions.
114 changes: 111 additions & 3 deletions doomsday/engine/portable/src/fs_main.c
Expand Up @@ -615,37 +615,145 @@ boolean F_IsValidLumpNum(lumpnum_t absoluteLumpNum)
return LumpDirectory_IsValidIndex(ActiveWadLumpDirectory, lumpNum);
}

typedef enum lumpsizecondition_e {
LSCOND_NONE,
LSCOND_EQUAL,
LSCOND_GREATER_OR_EQUAL,
LSCOND_LESS_OR_EQUAL
} lumpsizecondition_t;

/**
* Modifies the name so that the size condition is removed.
*/
static void checkSizeConditionInName(ddstring_t* name, lumpsizecondition_t* pCond, size_t* pSize)
{
int i;
int len = Str_Length(name);
const char* txt = Str_Text(name);
int argPos = 0;

assert(pCond != 0);
assert(pSize != 0);

*pCond = LSCOND_NONE;
*pSize = 0;

for(i = 0; i < len - 2; ++i, ++txt)
{
if(!strncmp(txt, "==", 2))
{
*pCond = LSCOND_EQUAL;
argPos = i + 2;
break;
}
if(!strncmp(txt, ">=", 2))
{
*pCond = LSCOND_GREATER_OR_EQUAL;
argPos = i + 2;
break;
}
if(!strncmp(txt, "<=", 2))
{
*pCond = LSCOND_LESS_OR_EQUAL;
argPos = i + 2;
break;
}
}
if(!argPos) return;

// Get the argument.
*pSize = strtoul(txt + 2, NULL, 10);

// Remove it from the name.
Str_Truncate(name, i);
}

lumpnum_t F_CheckLumpNumForName2(const char* name, boolean silent)
{
lumpnum_t lumpNum = -1;
lumpsizecondition_t sizeCond;
size_t lumpSize = 0;
size_t refSize;

Con_Message("checking for \"%s\"\n", name);

errorIfNotInited("F_CheckLumpNumForName");

if(name && name[0])
{
ddstring_t searchPath;

Str_Init(&searchPath); Str_Set(&searchPath, name);

// The name may contain a size condition (==, >=, <=).
checkSizeConditionInName(&searchPath, &sizeCond, &refSize);

// Append a .lmp extension if none is specified.
if(!F_FindFileExtension(name))
{
Str_Append(&searchPath, ".lmp");
//F_PrependBasePath(&searchPath, &searchPath);
}

// We have to check both the primary and auxiliary caches because
// we've only got a name and don't know where it is located. Start with
// the auxiliary lumps because they take precedence.
if(useAuxiliaryWadLumpDirectory())
{
lumpNum = LumpDirectory_IndexForPath(ActiveWadLumpDirectory, Str_Text(&searchPath));

if(lumpNum >= 0 && sizeCond != LSCOND_NONE)
{
// Get the size as well for the condition check.
lumpSize = LumpDirectory_LumpInfo(ActiveWadLumpDirectory, lumpNum)->size;
}
}

// Found it yet?
if(lumpNum < 0)
{
usePrimaryWadLumpDirectory();
lumpNum = LumpDirectory_IndexForPath(ActiveWadLumpDirectory, Str_Text(&searchPath));

if(lumpNum >= 0 && sizeCond != LSCOND_NONE)
{
// Get the size as well for the condition check.
lumpSize = LumpDirectory_LumpInfo(ActiveWadLumpDirectory, lumpNum)->size;
}
}

if(!silent && lumpNum < 0)
Con_Message("Warning: F_CheckLumpNumForName: Lump \"%s\" not found.\n", name);
// Check the condition.
switch(sizeCond)
{
case LSCOND_EQUAL:
if(lumpSize != refSize) lumpNum = -1;
break;

case LSCOND_GREATER_OR_EQUAL:
if(lumpSize < refSize) lumpNum = -1;
break;

case LSCOND_LESS_OR_EQUAL:
if(lumpSize > refSize) lumpNum = -1;
break;

default:
break;
}

// If still not found, warn the user.
if(/*!silent &&*/ lumpNum < 0)
{
if(sizeCond == LSCOND_NONE)
{
Con_Message("Warning: F_CheckLumpNumForName: Lump \"%s\" not found.\n", name);
}
else
{
Con_Message("Warning: F_CheckLumpNumForName: Lump \"%s\" with size%s%i not found.\n",
name, sizeCond==LSCOND_EQUAL? "==" :
sizeCond==LSCOND_GREATER_OR_EQUAL? ">=" : "<=", (int)refSize);
}
}

Str_Free(&searchPath);
}
Expand Down
4 changes: 3 additions & 1 deletion doomsday/engine/portable/src/s_main.c
Expand Up @@ -230,7 +230,7 @@ sfxinfo_t* S_GetSoundInfo(int soundID, float* freq, float* volume)
sfxinfo_t* info;
int i;

if(soundID <= 0)
if(soundID <= 0 || soundID >= defs.count.sounds.num)
return NULL;

if(!freq)
Expand All @@ -250,6 +250,8 @@ sfxinfo_t* S_GetSoundInfo(int soundID, float* freq, float* volume)
(info->linkVolume != -1 ? info->linkVolume / 127.0f : 0), soundID =
info - sounds, i++);

assert(soundID < defs.count.sounds.num);

return info;
}

Expand Down
2 changes: 1 addition & 1 deletion doomsday/engine/portable/src/s_sfx.c
Expand Up @@ -669,7 +669,7 @@ int Sfx_StartSound(sfxsample_t* sample, float volume, float freq,
boolean play3D = sfx3D && (emitter || fixedPos);

if(!sfxAvail || sample->id < 1 || sample->id >= defs.count.sounds.num ||
volume <= 0)
volume <= 0 || !sample->size)
return false;

if(emitter && sfxOneSoundPerEmitter)
Expand Down

0 comments on commit c1bdb1b

Please sign in to comment.