示例#1
0
static boolean LoadSoundLump(int sound, int *lumpnum, int *samplerate, uint32_t *length, byte **data_ref)
{
    int lumplen;
    byte *data;

    // Load the sound

    *lumpnum = S_sfx[sound].lumpnum;
    *data_ref = (byte *)W_CacheLumpNum(*lumpnum, PU_STATIC);
    lumplen = W_LumpLength(*lumpnum);
    data  = *data_ref;

    // Ensure this is a valid sound

    if (lumplen < 8 || data[0] != 0x03 || data[1] != 0x00)
    {
        // Invalid sound
        W_ReleaseLumpNum(*lumpnum);
        return false;
    }

    // 16 bit sample rate field, 32 bit length field

    *samplerate = (data[3] << 8) | data[2];
    *length = (data[7] << 24) | (data[6] << 16) | (data[5] << 8) | data[4];

    // If the header specifies that the length of the sound is
    // greater than the length of the lump itself, this is an invalid
    // sound lump.

    // We also discard sound lumps that are less than 49 samples long,
    // as this is how DMX behaves - although the actual cut-off length
    // seems to vary slightly depending on the sample rate.  This needs
    // further investigation to better understand the correct
    // behavior.

    if (*length > (unsigned)lumplen - 8 || *length <= 48)
    {
        W_ReleaseLumpNum(*lumpnum);
        return false;
    }

    // Prune header
    *data_ref += 8;

    // The DMX sound library seems to skip the first 16 and last 16
    // bytes of the lump - reason unknown.
    *data_ref += 16;
    *length -= 32;

    return true;
}
示例#2
0
void P_LoadSectors(int lump)
{
    byte *data;
    int i;
    mapsector_t *ms;
    sector_t *ss;

    numsectors = W_LumpLength(lump) / sizeof(mapsector_t);
    sectors = Z_Malloc(numsectors * sizeof(sector_t), PU_LEVEL, 0);
    memset(sectors, 0, numsectors * sizeof(sector_t));
    data = W_CacheLumpNum(lump, PU_STATIC);

    ms = (mapsector_t *) data;
    ss = sectors;

    for (i = 0; i < numsectors; i++, ss++, ms++)
    {
        ss->floorheight = SHORT(ms->floorheight) << FRACBITS;
        ss->ceilingheight = SHORT(ms->ceilingheight) << FRACBITS;
        ss->floorpic = R_FlatNumForName(ms->floorpic);
        ss->ceilingpic = R_FlatNumForName(ms->ceilingpic);
        ss->lightlevel = SHORT(ms->lightlevel);
        ss->special = SHORT(ms->special);
        ss->tag = SHORT(ms->tag);
        ss->thinglist = NULL;
        ss->seqType = SEQTYPE_STONE;    // default seqType
    }
    W_ReleaseLumpNum(lump);
}
示例#3
0
void P_LoadNodes(int lump)
{
    byte *data;
    int i, j, k;
    mapnode_t *mn;
    node_t *no;

    numnodes = W_LumpLength(lump) / sizeof(mapnode_t);
    nodes = Z_Malloc(numnodes * sizeof(node_t), PU_LEVEL, 0);
    data = W_CacheLumpNum(lump, PU_STATIC);

    mn = (mapnode_t *) data;
    no = nodes;
    for (i = 0; i < numnodes; i++, no++, mn++)
    {
        no->x = SHORT(mn->x) << FRACBITS;
        no->y = SHORT(mn->y) << FRACBITS;
        no->dx = SHORT(mn->dx) << FRACBITS;
        no->dy = SHORT(mn->dy) << FRACBITS;
        for (j = 0; j < 2; j++)
        {
            no->children[j] = SHORT(mn->children[j]);
            for (k = 0; k < 4; k++)
                no->bbox[j][k] = SHORT(mn->bbox[j][k]) << FRACBITS;
        }
    }
    W_ReleaseLumpNum(lump);
}
示例#4
0
static boolean CacheSFX_SDL(int sound)
{
    int lumpnum;
    int samplerate;
    uint32_t length;
    byte *data;

    if (!LoadSoundLump(sound, &lumpnum, &samplerate, &length, &data))
        return false;

    // Sample rate conversion
    // sound_chunks[sound].alen and abuf are determined by ExpandSoundData.

    sound_chunks[sound].allocated = 1;
    sound_chunks[sound].volume = MIX_MAX_VOLUME;

    ExpandSoundData_SDL(data,
                        samplerate,
                        length,
                        &sound_chunks[sound]);


    // don't need the original lump any more

    W_ReleaseLumpNum(lumpnum);

    return true;
}
示例#5
0
void P_LoadSideDefs(int lump)
{
    byte *data;
    int i;
    mapsidedef_t *msd;
    side_t *sd;

    numsides = W_LumpLength(lump) / sizeof(mapsidedef_t);
    sides = Z_Malloc(numsides * sizeof(side_t), PU_LEVEL, 0);
    memset(sides, 0, numsides * sizeof(side_t));
    data = W_CacheLumpNum(lump, PU_STATIC);

    msd = (mapsidedef_t *) data;
    sd = sides;

    for (i = 0; i < numsides; i++, msd++, sd++)
    {
        sd->textureoffset = SHORT(msd->textureoffset) << FRACBITS;
        sd->rowoffset = SHORT(msd->rowoffset) << FRACBITS;
        sd->toptexture = R_TextureNumForName(msd->toptexture);
        sd->bottomtexture = R_TextureNumForName(msd->bottomtexture);
        sd->midtexture = R_TextureNumForName(msd->midtexture);
        sd->sector = &sectors[SHORT(msd->sector)];
    }
    W_ReleaseLumpNum(lump);
}
示例#6
0
static void UnloadLumpCallback(const char *lumpname, int lumpnum, patch_t **ptr)
{
    if (lumpname != NULL)
    {
        W_ReleaseLumpName(lumpname);
    }
    else
    {
        W_ReleaseLumpNum(lumpnum);
    }
}
示例#7
0
void SC_Close(void)
{
    if (ScriptOpen)
    {
        if (ScriptLumpNum >= 0)
            W_ReleaseLumpNum(ScriptLumpNum);
        else
            Z_Free(ScriptBuffer);

        ScriptOpen = false;
    }
}
示例#8
0
void P_LoadThings(int lump)
{
    byte *data;
    int i;
    mapthing_t spawnthing;
    mapthing_t *mt;
    int numthings;
    int playerCount;
    int deathSpotsCount;

    data = W_CacheLumpNum(lump, PU_STATIC);
    numthings = W_LumpLength(lump) / sizeof(mapthing_t);

    mt = (mapthing_t *) data;
    for (i = 0; i < numthings; i++, mt++)
    {
        spawnthing.tid = SHORT(mt->tid);
        spawnthing.x = SHORT(mt->x);
        spawnthing.y = SHORT(mt->y);
        spawnthing.height = SHORT(mt->height);
        spawnthing.angle = SHORT(mt->angle);
        spawnthing.type = SHORT(mt->type);
        spawnthing.options = SHORT(mt->options);

        spawnthing.special = mt->special;
        spawnthing.arg1 = mt->arg1;
        spawnthing.arg2 = mt->arg2;
        spawnthing.arg3 = mt->arg3;
        spawnthing.arg4 = mt->arg4;
        spawnthing.arg5 = mt->arg5;

        P_SpawnMapThing(&spawnthing);
    }
    P_CreateTIDList();
    P_InitCreatureCorpseQueue(false);   // false = do NOT scan for corpses
    W_ReleaseLumpNum(lump);

    if (!deathmatch)
    {                           // Don't need to check deathmatch spots
        return;
    }
    playerCount = 0;
    for (i = 0; i < MAXPLAYERS; i++)
    {
        playerCount += playeringame[i];
    }
    deathSpotsCount = deathmatch_p - deathmatchstarts;
    if (deathSpotsCount < playerCount)
    {
        I_Error("P_LoadThings: Player count (%d) exceeds deathmatch "
                "spots (%d)", playerCount, deathSpotsCount);
    }
}
示例#9
0
void DEH_CloseFile(deh_context_t *context)
{
    if (context->type == DEH_INPUT_FILE)
    {
        fclose(context->stream);
    }
    else if (context->type == DEH_INPUT_LUMP)
    {
        W_ReleaseLumpNum(context->lumpnum);
    }

    Z_Free(context->readbuffer);
    Z_Free(context);
}
示例#10
0
// Load and convert a sound effect
// Returns true if successful
static dboolean CacheSFX(sfxinfo_t *sfxinfo)
{
    int                 lumpnum;
    unsigned int        lumplen;
    int                 samplerate;
    unsigned int        length;
    byte                *data;

    // need to load the sound
    lumpnum = sfxinfo->lumpnum;
    data = W_CacheLumpNum(lumpnum, PU_STATIC);
    lumplen = W_LumpLength(lumpnum);

    // Check the header, and ensure this is a valid sound
    if (lumplen < 8 || data[0] != 0x03 || data[1] != 0x00)
    {
        // Invalid sound
        return false;
    }

    // 16 bit sample rate field, 32 bit length field
    samplerate = ((data[3] << 8) | data[2]);
    length = ((data[7] << 24) | (data[6] << 16) | (data[5] << 8) | data[4]);

    // If the header specifies that the length of the sound is greater than
    // the length of the lump itself, this is an invalid sound lump

    // We also discard sound lumps that are less than 49 samples long,
    // as this is how DMX behaves - although the actual cut-off length
    // seems to vary slightly depending on the sample rate.  This needs
    // further investigation to better understand the correct
    // behavior.
    if (length > lumplen - 8 || length <= 48)
        return false;

    // The DMX sound library seems to skip the first 16 and last 16
    // bytes of the lump - reason unknown.
    data += 16;
    length -= 32;

    // Sample rate conversion
    if (!ExpandSoundData(sfxinfo, data + 8, samplerate, length))
        return false;

    // don't need the original lump any more
    W_ReleaseLumpNum(lumpnum);

    return true;
}
示例#11
0
//
// P_InitSwitchList()
//
// Only called at game initialization in order to list the set of switches
// and buttons known to the engine. This enables their texture to change
// when activated, and in the case of buttons, change back after a timeout.
//
// This routine modified to read its data from a predefined lump or
// PWAD lump called SWITCHES rather than a static table in this module to
// allow wad designers to insert or modify switches.
//
// Lump format is an array of byte packed switchlist_t structures, terminated
// by a structure with episode == -0. The lump can be generated from a
// text source file using SWANTBLS.EXE, distributed with the BOOM utils.
// The standard list of switches and animations is contained in the example
// source text file DEFSWANI.DAT also in the BOOM util distribution.
//
// Rewritten by Lee Killough to remove limit 2/8/98
//
void P_InitSwitchList(void)
{
    int                 i;
    int                 index = 0;
    int                 episode = (gamemode == registered || gamemode == retail ? 2 :
                            (gamemode == commercial ? 3 : 1));
    switchlist_t        *alphSwitchList;                // jff 3/23/98 pointer to switch table
    int                 lump = W_GetNumForName2("SWITCHES");    // cph - new wad lump handling

    // jff 3/23/98 read the switch table from a predefined lump
    alphSwitchList = (switchlist_t *)W_CacheLumpNum(lump, PU_STATIC);

    for (i = 0;; ++i)
    {
        if (index + 1 >= max_numswitches)
            switchlist = Z_Realloc(switchlist, sizeof(*switchlist)
                * (max_numswitches = max_numswitches ? max_numswitches * 2 : 8));
        if (SHORT(alphSwitchList[i].episode) <= episode)        // jff 5/11/98 endianess
        {
            int texture1;
            int texture2;

            if (!SHORT(alphSwitchList[i].episode))
                break;

            // Ignore switches referencing unknown texture names, instead of exiting.
            // Warn if either one is missing, but only add if both are valid.
            texture1 = R_CheckTextureNumForName(alphSwitchList[i].name1);
            if (texture1 == -1)
                C_Warning("Switch %i in SWITCHES lump has an unknown texture of %s.", i,
                    alphSwitchList[i].name1);
            texture2 = R_CheckTextureNumForName(alphSwitchList[i].name2);
            if (texture2 == -1)
                C_Warning("Switch %i in SWITCHES lump has an unknown texture of %s.", i,
                    alphSwitchList[i].name2);
            if (texture1 != -1 && texture2 != -1)
            {
                switchlist[index++] = texture1;
                switchlist[index++] = texture2;
            }
        }
    }

    numswitches = index / 2;
    switchlist[index] = -1;
    W_ReleaseLumpNum(lump);
}
示例#12
0
// Checks if the lump can be a Doom patch
static dboolean CheckIfPatch(int lump)
{
    int                 size;
    int                 width, height;
    const patch_t       *patch;
    dboolean            result;

    size = W_LumpLength(lump);

    // minimum length of a valid Doom patch
    if (size < 13)
        return false;

    patch = (const patch_t *)W_CacheLumpNum(lump, PU_STATIC);

    width = SHORT(patch->width);
    height = SHORT(patch->height);

    result = (height > 0 && height <= 16384 && width > 0 && width <= 16384 && width < size / 4);

    if (result)
    {
        // The dimensions seem like they might be valid for a patch, so
        // check the column directory for extra security. All columns 
        // must begin after the column directory, and none of them must
        // point past the end of the patch.
        int     x;

        for (x = 0; x < width; ++x)
        {
            unsigned int        ofs = LONG(patch->columnofs[x]);

            // Need one byte for an empty column (but there's patches that don't know that!)
            if (ofs < (unsigned int)width * 4 + 8 || ofs >= (unsigned int)size)
            {
                result = false;
                break;
            }
        }
    }

    W_ReleaseLumpNum(lump);
    return result;
}
示例#13
0
static void UnloadPics(void)
{
    int i;

    if (HubCount || gametype == DEATHMATCH)
    {
        W_ReleaseLumpName("INTERPIC");

        patchINTERPIC = W_CacheLumpName("INTERPIC", PU_STATIC);
        FontBLumpBase = W_GetNumForName("FONTB16");
        for (i = 0; i < 10; i++)
        {
            W_ReleaseLumpNum(FontBLumpBase + i);
        }
        W_ReleaseLumpName("FONTB13");
        W_ReleaseLumpName("FONTB15");
        W_ReleaseLumpName("FONTB05");
    }
}
示例#14
0
void P_LoadVertexes(int lump)
{
    byte *data;
    int i;
    mapvertex_t *ml;
    vertex_t *li;

    numvertexes = W_LumpLength(lump) / sizeof(mapvertex_t);
    vertexes = Z_Malloc(numvertexes * sizeof(vertex_t), PU_LEVEL, 0);
    data = W_CacheLumpNum(lump, PU_STATIC);

    ml = (mapvertex_t *) data;
    li = vertexes;
    for (i = 0; i < numvertexes; i++, li++, ml++)
    {
        li->x = SHORT(ml->x) << FRACBITS;
        li->y = SHORT(ml->y) << FRACBITS;
    }

    W_ReleaseLumpNum(lump);
}
示例#15
0
void P_LoadSubsectors(int lump)
{
    byte *data;
    int i;
    mapsubsector_t *ms;
    subsector_t *ss;

    numsubsectors = W_LumpLength(lump) / sizeof(mapsubsector_t);
    subsectors = Z_Malloc(numsubsectors * sizeof(subsector_t), PU_LEVEL, 0);
    data = W_CacheLumpNum(lump, PU_STATIC);

    ms = (mapsubsector_t *) data;
    memset(subsectors, 0, numsubsectors * sizeof(subsector_t));
    ss = subsectors;
    for (i = 0; i < numsubsectors; i++, ss++, ms++)
    {
        ss->numlines = SHORT(ms->numsegs);
        ss->firstline = SHORT(ms->firstseg);
    }

    W_ReleaseLumpNum(lump);
}
示例#16
0
void P_LoadSegs(int lump)
{
    byte *data;
    int i;
    mapseg_t *ml;
    seg_t *li;
    line_t *ldef;
    int linedef, side;

    numsegs = W_LumpLength(lump) / sizeof(mapseg_t);
    segs = Z_Malloc(numsegs * sizeof(seg_t), PU_LEVEL, 0);
    memset(segs, 0, numsegs * sizeof(seg_t));
    data = W_CacheLumpNum(lump, PU_STATIC);

    ml = (mapseg_t *) data;
    li = segs;
    for (i = 0; i < numsegs; i++, li++, ml++)
    {
        li->v1 = &vertexes[SHORT(ml->v1)];
        li->v2 = &vertexes[SHORT(ml->v2)];

        li->angle = (SHORT(ml->angle)) << 16;
        li->offset = (SHORT(ml->offset)) << 16;
        linedef = SHORT(ml->linedef);
        ldef = &lines[linedef];
        li->linedef = ldef;
        side = SHORT(ml->side);
        li->sidedef = &sides[ldef->sidenum[side]];
        li->frontsector = sides[ldef->sidenum[side]].sector;
        if (ldef->flags & ML_TWOSIDED)
            li->backsector = sides[ldef->sidenum[side ^ 1]].sector;
        else
            li->backsector = 0;
    }

    W_ReleaseLumpNum(lump);
}
示例#17
0
static void createPatch(int id)
{
    rpatch_t            *patch;
    const int           patchNum = id;
    const patch_t       *oldPatch;
    const column_t      *oldColumn;
    int                 x, y;
    int                 pixelDataSize;
    int                 columnsDataSize;
    int                 postsDataSize;
    int                 dataSize;
    int                 *numPostsInColumn;
    int                 numPostsTotal;
    const unsigned char *oldColumnPixelData;
    int                 numPostsUsedSoFar;

    if (!CheckIfPatch(patchNum))
        I_Error("createPatch: Unknown patch format %s.",
            (patchNum < numlumps ? lumpinfo[patchNum]->name : NULL));

    oldPatch = (const patch_t*)W_CacheLumpNum(patchNum, PU_STATIC);

    patch = &patches[id];
    patch->width = SHORT(oldPatch->width);
    patch->widthmask = 0;
    patch->height = SHORT(oldPatch->height);
    patch->leftoffset = SHORT(oldPatch->leftoffset);
    patch->topoffset = SHORT(oldPatch->topoffset);
    patch->flags = 0;
    if (getPatchIsNotTileable(oldPatch))
        patch->flags |= PATCH_ISNOTTILEABLE;

    // work out how much memory we need to allocate for this patch's data
    pixelDataSize = (patch->width * patch->height + 4) & ~3;
    columnsDataSize = sizeof(rcolumn_t) * patch->width;

    // count the number of posts in each column
    numPostsInColumn = malloc(sizeof(int) * patch->width);
    numPostsTotal = 0;

    for (x = 0; x < patch->width; ++x)
    {
        oldColumn = (const column_t *)((const byte *)oldPatch + LONG(oldPatch->columnofs[x]));
        numPostsInColumn[x] = 0;
        while (oldColumn->topdelta != 0xFF)
        {
            numPostsInColumn[x]++;
            numPostsTotal++;
            oldColumn = (const column_t *)((const byte *)oldColumn + oldColumn->length + 4);
        }
    }

    postsDataSize = numPostsTotal * sizeof(rpost_t);

    // allocate our data chunk
    dataSize = pixelDataSize + columnsDataSize + postsDataSize;
    patch->data = (unsigned char *)Z_Malloc(dataSize, PU_CACHE, (void **)&patch->data);
    memset(patch->data, 0, dataSize);

    // set out pixel, column, and post pointers into our data array
    patch->pixels = patch->data;
    patch->columns = (rcolumn_t *)((unsigned char *)patch->pixels + pixelDataSize);
    patch->posts = (rpost_t *)((unsigned char *)patch->columns + columnsDataSize);

    // sanity check that we've got all the memory allocated we need
    assert((((byte*)patch->posts + numPostsTotal * sizeof(rpost_t))
        - (byte *)patch->data) == dataSize);

    memset(patch->pixels, 0xFF, (patch->width*patch->height));

    // fill in the pixels, posts, and columns
    numPostsUsedSoFar = 0;
    for (x = 0; x < patch->width; ++x)
    {
        int     top = -1;

        oldColumn = (const column_t *)((const byte *)oldPatch + LONG(oldPatch->columnofs[x]));

        // setup the column's data
        patch->columns[x].pixels = patch->pixels + x * patch->height;
        patch->columns[x].numPosts = numPostsInColumn[x];
        patch->columns[x].posts = patch->posts + numPostsUsedSoFar;

        while (oldColumn->topdelta != 0xFF)
        {
            int len = oldColumn->length;

            //e6y: support for DeePsea's true tall patches
            if (oldColumn->topdelta <= top)
                top += oldColumn->topdelta;
            else
                top = oldColumn->topdelta;

            // Clip posts that extend past the bottom
            if (top + oldColumn->length > patch->height)
                len = patch->height - top;

            if (len > 0)
            {
                // set up the post's data
                patch->posts[numPostsUsedSoFar].topdelta = top;
                patch->posts[numPostsUsedSoFar].length = len;

                // fill in the post's pixels
                oldColumnPixelData = (const byte *)oldColumn + 3;
                for (y = 0; y < len; y++)
                    patch->pixels[x * patch->height + top + y] = oldColumnPixelData[y];
            }
            oldColumn = (const column_t *)((const byte *)oldColumn + oldColumn->length + 4);
            numPostsUsedSoFar++;
        }
    }

    {
        const rcolumn_t *column;
        const rcolumn_t *prevColumn;

        // copy the patch image down and to the right where there are
        // holes to eliminate the black halo from bilinear filtering
        for (x = 0; x < patch->width; ++x)
        {
            column = R_GetPatchColumnClamped(patch, x);
            prevColumn = R_GetPatchColumnClamped(patch, x - 1);

            if (column->pixels[0] == 0xFF)
            {
                // e6y: marking of all patches with holes
                patch->flags |= PATCH_HASHOLES;

                // force the first pixel (which is a hole), to use
                // the color from the next solid spot in the column
                for (y = 0; y < patch->height; y++)
                    if (column->pixels[y] != 0xFF)
                    {
                        column->pixels[0] = column->pixels[y];
                        break;
                    }
            }

            // copy from above or to the left
            for (y = 1; y < patch->height; ++y)
            {
                //if (getIsSolidAtSpot(oldColumn, y)) continue;
                if (column->pixels[y] != 0xFF) continue;

                // this pixel is a hole

                // e6y: marking of all patches with holes
                patch->flags |= PATCH_HASHOLES;

                if (x && prevColumn->pixels[y - 1] != 0xFF)
                    column->pixels[y] = prevColumn->pixels[y];  // copy the color from the left
                else
                    column->pixels[y] = column->pixels[y - 1];  // copy the color from above
            }
        }
    }

    W_ReleaseLumpNum(patchNum);
    free(numPostsInColumn);
}
示例#18
0
void P_LoadLineDefs(int lump)
{
    byte *data;
    int i;
    maplinedef_t *mld;
    line_t *ld;
    vertex_t *v1, *v2;

    numlines = W_LumpLength(lump) / sizeof(maplinedef_t);
    lines = Z_Malloc(numlines * sizeof(line_t), PU_LEVEL, 0);
    memset(lines, 0, numlines * sizeof(line_t));
    data = W_CacheLumpNum(lump, PU_STATIC);

    mld = (maplinedef_t *) data;
    ld = lines;
    for (i = 0; i < numlines; i++, mld++, ld++)
    {
        ld->flags = SHORT(mld->flags);

        // Old line special info ...
        //ld->special = SHORT(mld->special);
        //ld->tag = SHORT(mld->tag);

        // New line special info ...
        ld->special = mld->special;
        ld->arg1 = mld->arg1;
        ld->arg2 = mld->arg2;
        ld->arg3 = mld->arg3;
        ld->arg4 = mld->arg4;
        ld->arg5 = mld->arg5;

        v1 = ld->v1 = &vertexes[SHORT(mld->v1)];
        v2 = ld->v2 = &vertexes[SHORT(mld->v2)];
        ld->dx = v2->x - v1->x;
        ld->dy = v2->y - v1->y;
        if (!ld->dx)
            ld->slopetype = ST_VERTICAL;
        else if (!ld->dy)
            ld->slopetype = ST_HORIZONTAL;
        else
        {
            if (FixedDiv(ld->dy, ld->dx) > 0)
                ld->slopetype = ST_POSITIVE;
            else
                ld->slopetype = ST_NEGATIVE;
        }

        if (v1->x < v2->x)
        {
            ld->bbox[BOXLEFT] = v1->x;
            ld->bbox[BOXRIGHT] = v2->x;
        }
        else
        {
            ld->bbox[BOXLEFT] = v2->x;
            ld->bbox[BOXRIGHT] = v1->x;
        }
        if (v1->y < v2->y)
        {
            ld->bbox[BOXBOTTOM] = v1->y;
            ld->bbox[BOXTOP] = v2->y;
        }
        else
        {
            ld->bbox[BOXBOTTOM] = v2->y;
            ld->bbox[BOXTOP] = v1->y;
        }
        ld->sidenum[0] = SHORT(mld->sidenum[0]);
        ld->sidenum[1] = SHORT(mld->sidenum[1]);
        if (ld->sidenum[0] != -1)
            ld->frontsector = sides[ld->sidenum[0]].sector;
        else
            ld->frontsector = 0;
        if (ld->sidenum[1] != -1)
            ld->backsector = sides[ld->sidenum[1]].sector;
        else
            ld->backsector = 0;
    }

    W_ReleaseLumpNum(lump);
}
示例#19
0
文件: w_wad.c 项目: derek57/research
void W_ReleaseLumpName(char *name)
{
    W_ReleaseLumpNum(W_GetNumForName(name));
}
示例#20
0
文件: r_data.c 项目: mdgunn/doomretro
//
// R_InitTextures
// Initializes the texture list
//  with the textures from the world map.
//
void R_InitTextures(void)
{
    const maptexture_t  *mtexture;
    texture_t           *texture;
    int                 i, j;
    int                 maptex_lump[2] = { -1, -1 };
    const int           *maptex1;
    const int           *maptex2;
    char                name[9];
    int                 names_lump; // cph - new wad lump handling
    const char          *names; // cph -
    const char          *name_p;// const*'s
    int                 *patchlookup;
    int                 nummappatches;
    int                 maxoff, maxoff2;
    int                 numtextures1, numtextures2;
    const int           *directory;

    // Load the patch names from pnames.lmp.
    name[8] = '\0';
    names = W_CacheLumpNum(names_lump = W_GetNumForName("PNAMES"), PU_STATIC);
    nummappatches = LONG(*((const int *)names));
    name_p = names + 4;
    patchlookup = malloc(nummappatches * sizeof(*patchlookup));   // killough

    for (i = 0; i < nummappatches; i++)
    {
        strncpy(name, name_p + i * 8, 8);
        patchlookup[i] = W_CheckNumForName(name);
    }
    W_ReleaseLumpNum(names_lump);       // cph - release the lump

    // Load the map texture definitions from textures.lmp.
    // The data is contained in one or two lumps,
    //  TEXTURE1 for shareware, plus TEXTURE2 for commercial.
    maptex_lump[0] = W_GetNumForName("TEXTURE1");
    maptex1 = W_CacheLumpNum(maptex_lump[0], PU_STATIC);
    numtextures1 = LONG(*maptex1);
    maxoff = W_LumpLength(maptex_lump[0]);
    directory = maptex1 + 1;

    if (W_CheckNumForName("TEXTURE2") != -1)
    {
        maptex_lump[1] = W_GetNumForName("TEXTURE2");
        maptex2 = W_CacheLumpNum(maptex_lump[1], PU_STATIC);
        numtextures2 = LONG(*maptex2);
        maxoff2 = W_LumpLength(maptex_lump[1]);
    }
    else
    {
        maptex2 = NULL;
        numtextures2 = 0;
        maxoff2 = 0;
    }
    numtextures = numtextures1 + numtextures2;

    // killough 4/9/98: make column offsets 32-bit;
    // clean up malloc-ing to use sizeof
    textures = Z_Malloc(numtextures * sizeof(*textures), PU_STATIC, 0);
    textureheight = Z_Malloc(numtextures * sizeof(*textureheight), PU_STATIC, 0);

    for (i = 0; i < numtextures; ++i, ++directory)
    {
        const mappatch_t        *mpatch;
        texpatch_t              *patch;
        int                     offset;

        if (i == numtextures1)
        {
            // Start looking in second texture file.
            maptex1 = maptex2;
            maxoff = maxoff2;
            directory = maptex1 + 1;
        }

        offset = LONG(*directory);

        if (offset > maxoff)
            I_Error("R_InitTextures: Bad texture directory");

        mtexture = (const maptexture_t *)((const byte *)maptex1 + offset);

        texture = textures[i] = Z_Malloc(sizeof(texture_t) + sizeof(texpatch_t)
            * (SHORT(mtexture->patchcount) - 1), PU_STATIC, 0);

        texture->width = SHORT(mtexture->width);
        texture->height = SHORT(mtexture->height);
        texture->patchcount = SHORT(mtexture->patchcount);

        {
            size_t      j;

            for (j = 0; j < sizeof(texture->name); ++j)
                texture->name[j] = mtexture->name[j];
        }

        mpatch = mtexture->patches;
        patch = texture->patches;

        for (j = 0; j < texture->patchcount; ++j, ++mpatch, ++patch)
        {
            patch->originx = SHORT(mpatch->originx);
            patch->originy = SHORT(mpatch->originy);
            patch->patch = patchlookup[SHORT(mpatch->patch)];
            if (patch->patch == -1)
                C_Warning("Patch %d is missing in the %.8s texture.", SHORT(mpatch->patch),
                    texture->name);     // killough 4/17/98
        }

        for (j = 1; j * 2 <= texture->width; j <<= 1);
        texture->widthmask = j - 1;
        textureheight[i] = texture->height << FRACBITS;
    }

    free(patchlookup);          // killough

    for (i = 0; i < 2; ++i)     // cph - release the TEXTUREx lumps
        if (maptex_lump[i] != -1)
            W_ReleaseLumpNum(maptex_lump[i]);

    // Create translation table for global animation.
    // killough 4/9/98: make column offsets 32-bit;
    // clean up malloc-ing to use sizeof
    texturetranslation = Z_Malloc((numtextures + 1) * sizeof(*texturetranslation), PU_STATIC, 0);

    for (i = 0; i < numtextures; ++i)
        texturetranslation[i] = i;

    // killough 1/31/98: Initialize texture hash table
    for (i = 0; i < numtextures; ++i)
        textures[i]->index = -1;
    while (--i >= 0)
    {
        int     j = W_LumpNameHash(textures[i]->name) % (unsigned int)numtextures;

        textures[i]->next = textures[j]->index; // Prepend to chain
        textures[j]->index = i;
    }

    // [BH] Initialize partially fullbright textures.
    texturefullbright = Z_Malloc(numtextures * sizeof(*texturefullbright), PU_STATIC, 0);

    memset(texturefullbright, 0, numtextures * sizeof(*texturefullbright));
    if (r_brightmaps)
    {
        i = 0;
        while (fullbright[i].colormask)
        {
            if (fullbright[i].texture)
            {
                int num = R_CheckTextureNumForName(fullbright[i].texture);

                if (num != -1)
                    texturefullbright[num] = fullbright[i].colormask;
                i++;
            }
        }
    }
}
示例#21
0
文件: r_data.c 项目: jeffdoggett/Doom
static void R_ReadTextures (int names_lump, int maptex_lump_1, int maptex_lump_2)
{
    const maptexture_t	*mtexture;
    texture_t		*texture;
    int			i, j;
    const int		*maptex1;
    const int		*maptex2;
    const char		*names; // cph -
    const char		*name_p;// const*'s
    int			*patchlookup;
    int			texbase;
    int			numtex;
    int			nummappatches;
    int			maxoff, maxoff2;
    int			numtextures1, numtextures2;
    const int		*directory;
    char		name[9];

    // Load the patch names from pnames.lmp.
    name[8] = '\0';
    names = W_CacheLumpNum(names_lump, PU_STATIC);
    nummappatches = LONG(*((const int *)names));
    name_p = names + 4;
    patchlookup = malloc(nummappatches * sizeof(*patchlookup));   // killough

    for (i = 0; i < nummappatches; i++)
    {
	strncpy(name, name_p + i * 8, 8);
	patchlookup[i] = W_CheckNumForName(name);
    }
    W_ReleaseLumpNum(names_lump);       // cph - release the lump

    // Load the map texture definitions from textures.lmp.
    // The data is contained in one or two lumps,
    //  TEXTURE1 for shareware, plus TEXTURE2 for commercial.
    maptex1 = W_CacheLumpNum(maptex_lump_1, PU_STATIC);
    numtextures1 = LONG(*maptex1);
    maxoff = W_LumpLength(maptex_lump_1);
    directory = maptex1 + 1;

    if (maptex_lump_2 != -1)
    {
	maptex2 = W_CacheLumpNum(maptex_lump_2, PU_STATIC);
	numtextures2 = LONG(*maptex2);
	maxoff2 = W_LumpLength(maptex_lump_2);
    }
    else
    {
	maptex2 = NULL;
	numtextures2 = 0;
	maxoff2 = 0;
    }

    texbase = numtextures;
    numtex = numtextures1 + numtextures2;
    numtextures += numtex;

    // killough 4/9/98: make column offsets 32-bit;
    // clean up malloc-ing to use sizeof
    textures = Z_Realloc (textures, numtextures * sizeof(*textures), PU_STATIC, 0);
    textureheight = Z_Realloc (textureheight, numtextures * sizeof(*textureheight), PU_STATIC, 0);

    for (i = 0; i < numtex; ++directory)
    {
	const mappatch_t *mpatch;
	texpatch_t	*patch;
	int		offset;

	if (i == numtextures1)
	{
	    // Start looking in second texture file.
	    maptex1 = maptex2;
	    maxoff = maxoff2;
	    directory = maptex1 + 1;
	}

	if ((((byte *) directory) >= ((byte *)maptex1+maxoff))
	 || ((offset=LONG(*directory)) >= maxoff))
	{
	  printf ("R_InitTextures: bad texture directory %X/%X %d/%d\n",
		(uintptr_t)directory,((uintptr_t)maptex1+maxoff), offset, maxoff);
	  break;
	}

	mtexture = (const maptexture_t *)((const byte *)maptex1 + offset);

	if ((texbase)
	 && (R_DuplicateTexture (mtexture->name, texbase)))
	{
	  numtex--;
	  numtextures--;
	  numtextures1--;
	  continue;
	}

	texture = textures[texbase+i] = Z_Malloc(sizeof(texture_t) + sizeof(texpatch_t)
	    * (SHORT(mtexture->patchcount) - 1), PU_STATIC, 0);

	texture->width = SHORT(mtexture->width);
	texture->height = SHORT(mtexture->height);
	texture->patchcount = SHORT(mtexture->patchcount);
	// killough 1/31/98: Initialize texture hash table
	texture->index = -1;

	{
	    size_t      j;

	    for (j = 0; j < sizeof(texture->name); ++j)
		texture->name[j] = mtexture->name[j];
	}

#ifdef PADDED_STRUCTS
	mpatch = (mappatch_t *) ((char *) mtexture + 22);
#else
	mpatch = &mtexture->patches[0];
#endif
	patch = texture->patches;

	for (j = 0; j < texture->patchcount; ++j, ++patch)
	{
	    patch->originx = SHORT(mpatch->originx);
	    patch->originy = SHORT(mpatch->originy);
	    patch->patch = patchlookup[SHORT(mpatch->patch)];
	    if (patch->patch == -1)
		printf("Missing patch %d in texture %.8s.", SHORT(mpatch->patch),
		    texture->name);     // killough 4/17/98
#ifdef PADDED_STRUCTS
	    mpatch = (mappatch_t *)   ((unsigned char *) mpatch + 10);
#else
	    mpatch++;
#endif
	}

	for (j = 1; j * 2 <= texture->width; j <<= 1);
	texture->widthmask = j - 1;
	textureheight[texbase+i] = texture->height << FRACBITS;

	i++;	// Done here so that 'continue' misses it out...
    }

    free(patchlookup);	  // killough

    // cph - release the TEXTUREx lumps
    W_ReleaseLumpNum (maptex_lump_1);
    if (maptex_lump_2 != -1)
      W_ReleaseLumpNum (maptex_lump_2);
}
示例#22
0
static void createTextureCompositePatch(int id)
{
    rpatch_t            *composite_patch = &texture_composites[id];
    texture_t           *texture = textures[id];
    texpatch_t          *texpatch;
    int                 patchNum;
    const patch_t       *oldPatch;
    const column_t      *oldColumn;
    int                 i, x, y;
    int                 oy, count;
    int                 pixelDataSize;
    int                 columnsDataSize;
    int                 postsDataSize;
    int                 dataSize;
    int                 numPostsTotal;
    const unsigned char *oldColumnPixelData;
    int                 numPostsUsedSoFar;
    count_t             *countsInColumn;

    composite_patch->width = texture->width;
    composite_patch->height = texture->height;
    composite_patch->widthmask = texture->widthmask;
    composite_patch->leftoffset = 0;
    composite_patch->topoffset = 0;
    composite_patch->flags = 0;

    // work out how much memory we need to allocate for this patch's data
    pixelDataSize = (composite_patch->width * composite_patch->height + 4) & ~3;
    columnsDataSize = sizeof(rcolumn_t) * composite_patch->width;

    // count the number of posts in each column
    countsInColumn = (count_t *)calloc(sizeof(count_t), composite_patch->width);
    numPostsTotal = 0;

    for (i = 0; i < texture->patchcount; ++i)
    {
        texpatch = &texture->patches[i];
        patchNum = texpatch->patch;
        oldPatch = (const patch_t *)W_CacheLumpNum(patchNum, PU_STATIC);

        for (x = 0; x < SHORT(oldPatch->width); ++x)
        {
            int tx = texpatch->originx + x;

            if (tx < 0)
                continue;
            if (tx >= composite_patch->width)
                break;

            countsInColumn[tx].patches++;

            oldColumn = (const column_t *)((const byte *)oldPatch + LONG(oldPatch->columnofs[x]));
            while (oldColumn->topdelta != 0xFF)
            {
                countsInColumn[tx].posts++;
                numPostsTotal++;
                oldColumn = (const column_t *)((const byte *)oldColumn + oldColumn->length + 4);
            }
        }

        W_ReleaseLumpNum(patchNum);
    }

    postsDataSize = numPostsTotal * sizeof(rpost_t);

    // allocate our data chunk
    dataSize = pixelDataSize + columnsDataSize + postsDataSize;
    composite_patch->data = (unsigned char *)Z_Malloc(dataSize, PU_STATIC,
        (void **)&composite_patch->data);
    memset(composite_patch->data, 0, dataSize);

    // set out pixel, column, and post pointers into our data array
    composite_patch->pixels = composite_patch->data;
    composite_patch->columns = (rcolumn_t*)((unsigned char*)composite_patch->pixels
        + pixelDataSize);
    composite_patch->posts = (rpost_t*)((unsigned char*)composite_patch->columns
        + columnsDataSize);

    // sanity check that we've got all the memory allocated we need
    assert((((byte *)composite_patch->posts + numPostsTotal * sizeof(rpost_t))
        - (byte *)composite_patch->data) == dataSize);

    memset(composite_patch->pixels, 0xFF, (composite_patch->width * composite_patch->height));

    numPostsUsedSoFar = 0;

    for (x = 0; x < texture->width; ++x)
    {
        // setup the column's data
        composite_patch->columns[x].pixels = composite_patch->pixels
            + (x * composite_patch->height);
        composite_patch->columns[x].numPosts = countsInColumn[x].posts;
        composite_patch->columns[x].posts = composite_patch->posts + numPostsUsedSoFar;
        numPostsUsedSoFar += countsInColumn[x].posts;
    }

    // fill in the pixels, posts, and columns
    for (i = 0; i < texture->patchcount; ++i)
    {
        texpatch = &texture->patches[i];
        patchNum = texpatch->patch;
        oldPatch = (const patch_t *)W_CacheLumpNum(patchNum, PU_STATIC);

        for (x = 0; x < SHORT(oldPatch->width); ++x)
        {
            int top = -1;
            int tx = texpatch->originx + x;

            if (tx < 0)
                continue;
            if (tx >= composite_patch->width)
                break;

            oldColumn = (const column_t *)((const byte *)oldPatch + LONG(oldPatch->columnofs[x]));

            while (oldColumn->topdelta != 0xFF)
            {
                rpost_t *post = &composite_patch->columns[tx].posts[countsInColumn[tx].posts_used];

                // e6y: support for DeePsea's true tall patches
                if (oldColumn->topdelta <= top)
                    top += oldColumn->topdelta;
                else
                    top = oldColumn->topdelta;

                oldColumnPixelData = (const byte *)oldColumn + 3;
                oy = texpatch->originy;
                count = oldColumn->length;

                // the original renderer had several bugs which we reproduce here
                if (countsInColumn[tx].patches > 1)
                {
                    // when there are multiple patches, then we need to handle the
                    // column differently
                    if (!i)
                    {
                        // draw first patch at original position, it will be partly
                        // overdrawn below
                        for (y = 0; y < count; ++y)
                        {
                            int ty = oy + top + y;

                            if (ty < 0)
                                continue;
                            if (ty >= composite_patch->height)
                                break;
                            composite_patch->pixels[tx * composite_patch->height + ty]
                                = oldColumnPixelData[y];
                        }
                    }
                    // do the buggy clipping
                    if (oy + top < 0)
                    {
                        count += oy;
                        oy = 0;
                    }
                }
                else
                    oy = 0;     // with a single patch only negative y origins are wrong

                // set up the post's data
                post->topdelta = top + oy;
                post->length = count;
                if ((post->topdelta + post->length) > composite_patch->height)
                {
                    if (post->topdelta > composite_patch->height)
                        post->length = 0;
                    else
                        post->length = composite_patch->height - post->topdelta;
                }
                if (post->topdelta < 0)
                {
                    if ((post->topdelta + post->length) <= 0)
                        post->length = 0;
                    else
                        post->length -= post->topdelta;
                    post->topdelta = 0;
                }

                // fill in the post's pixels
                for (y = 0; y < count; ++y)
                {
                    int ty = oy + top + y;

                    if (ty < 0)
                        continue;
                    if (ty >= composite_patch->height)
                        break;
                    composite_patch->pixels[tx * composite_patch->height + ty]
                        = oldColumnPixelData[y];
                }

                oldColumn = (const column_t *)((const byte *)oldColumn + oldColumn->length + 4);
                countsInColumn[tx].posts_used++;
                assert(countsInColumn[tx].posts_used <= countsInColumn[tx].posts);
            }
        }

        W_ReleaseLumpNum(patchNum);
    }

    for (x = 0; x < texture->width; ++x)
    {
        rcolumn_t       *column;

        if (countsInColumn[x].patches <= 1)
            continue;

        // cleanup posts on multipatch columns
        column = &composite_patch->columns[x];

        i = 0;
        while (i < column->numPosts - 1)
        {
            rpost_t     *post1 = &column->posts[i];
            rpost_t     *post2 = &column->posts[i + 1];

            if (post2->topdelta - post1->topdelta < 0)
                switchPosts(post1, post2);

            if (post1->topdelta + post1->length >= post2->topdelta)
            {
                int     length = (post1->length + post2->length) - ((post1->topdelta
                    + post1->length) - post2->topdelta);

                if (post1->length < length)
                    post1->length = length;
                removePostFromColumn(column, i + 1);
                i = 0;
                continue;
            }
            i++;
        }
    }

    {
        const rcolumn_t *column;
        const rcolumn_t *prevColumn;

        // copy the patch image down and to the right where there are
        // holes to eliminate the black halo from bilinear filtering
        for (x = 0; x < composite_patch->width; ++x)
        {
            column = R_GetPatchColumnClamped(composite_patch, x);
            prevColumn = R_GetPatchColumnClamped(composite_patch, x - 1);

            if (column->pixels[0] == 0xFF)
            {
                // e6y: marking of all patches with holes
                composite_patch->flags |= PATCH_HASHOLES;

                // force the first pixel (which is a hole), to use
                // the color from the next solid spot in the column
                for (y = 0; y < composite_patch->height; ++y)
                {
                    if (column->pixels[y] != 0xFF)
                    {
                        column->pixels[0] = column->pixels[y];
                        break;
                    }
                }
            }

            // copy from above or to the left
            for (y = 1; y < composite_patch->height; ++y)
            {
                if (column->pixels[y] != 0xFF)
                    continue;

                // this pixel is a hole

                // e6y: marking of all patches with holes
                composite_patch->flags |= PATCH_HASHOLES;

                if (x && prevColumn->pixels[y - 1] != 0xFF)
                    column->pixels[y] = prevColumn->pixels[y];  // copy the color from the left
                else
                    column->pixels[y] = column->pixels[y - 1];  // copy the color from above
            }
        }
    }

    free(countsInColumn);
}
示例#23
0
static boolean CacheSFX(sfxinfo_t *sfxinfo)
{
    int lumpnum;
    unsigned int lumplen;
    int samplerate;
    unsigned int length;
    byte *data;

    // need to load the sound

    lumpnum = sfxinfo->lumpnum;
    data = W_CacheLumpNum(lumpnum, PU_STATIC);
    lumplen = W_LumpLength(lumpnum);

    // Check the header, and ensure this is a valid sound

    if (lumplen < 8
     || data[0] != 0x03 || data[1] != 0x00)
    {
        // Invalid sound

        return false;
    }

    // 16 bit sample rate field, 32 bit length field

    samplerate = (data[3] << 8) | data[2];
    length = (data[7] << 24) | (data[6] << 16) | (data[5] << 8) | data[4];

    // If the header specifies that the length of the sound is greater than
    // the length of the lump itself, this is an invalid sound lump

    // We also discard sound lumps that are less than 49 samples long,
    // as this is how DMX behaves - although the actual cut-off length
    // seems to vary slightly depending on the sample rate.  This needs
    // further investigation to better understand the correct
    // behavior.

    if (length > lumplen - 8 || length <= 48)
    {
        return false;
    }

    // The DMX sound library seems to skip the first 16 and last 16
    // bytes of the lump - reason unknown.

    data += 16;
    length -= 32;

    // Sample rate conversion

    if (!ExpandSoundData(sfxinfo, data + 8, samplerate, length))
    {
        return false;
    }

#ifdef DEBUG_DUMP_WAVS
    {
        char filename[16];
        allocated_sound_t * snd;

        M_snprintf(filename, sizeof(filename), "%s.wav",
                   DEH_String(sfxinfo->name));
        snd = GetAllocatedSoundBySfxInfoAndPitch(sfxinfo, NORM_PITCH);
        WriteWAV(filename, snd->chunk.abuf, snd->chunk.alen,mixer_freq);
    }
#endif

    // don't need the original lump any more
  
    W_ReleaseLumpNum(lumpnum);

    return true;
}