예제 #1
0
	void ProcessLineDefs()
	{
		int sidecount = 0;
		for(unsigned i = 0, skipped = 0; i < ParsedLines.Size();)
		{
			// Relocate the vertices
			intptr_t v1i = intptr_t(ParsedLines[i].v1);
			intptr_t v2i = intptr_t(ParsedLines[i].v2);

			if (v1i >= numvertexes || v2i >= numvertexes || v1i < 0 || v2i < 0)
			{
				I_Error ("Line %d has invalid vertices: %zd and/or %zd.\nThe map only contains %d vertices.", i+skipped, v1i, v2i, numvertexes);
			}
			else if (v1i == v2i ||
				(vertexes[v1i].x == vertexes[v2i].x && vertexes[v1i].y == vertexes[v2i].y))
			{
				Printf ("Removing 0-length line %d\n", i+skipped);
				ParsedLines.Delete(i);
				ForceNodeBuild = true;
				skipped++;
			}
			else
			{
				ParsedLines[i].v1 = &vertexes[v1i];
				ParsedLines[i].v2 = &vertexes[v2i];

				if (ParsedLines[i].sidedef[0] != NULL)
					sidecount++;
				if (ParsedLines[i].sidedef[1] != NULL)
					sidecount++;
				linemap.Push(i+skipped);
				i++;
			}
		}
		numlines = ParsedLines.Size();
		numsides = sidecount;
		lines = new line_t[numlines];
		sides = new side_t[numsides];
		int line, side;

		for(line = 0, side = 0; line < numlines; line++)
		{
			short tempalpha[2] = { SHRT_MIN, SHRT_MIN };

			lines[line] = ParsedLines[line];

			for(int sd = 0; sd < 2; sd++)
			{
				if (lines[line].sidedef[sd] != NULL)
				{
					int mapside = int(intptr_t(lines[line].sidedef[sd]))-1;
					if (mapside < sidecount)
					{
						sides[side] = ParsedSides[mapside];
						sides[side].linedef = &lines[line];
						sides[side].sector = &sectors[intptr_t(sides[side].sector)];
						lines[line].sidedef[sd] = &sides[side];

						P_ProcessSideTextures(!isExtended, &sides[side], sides[side].sector, &ParsedSideTextures[mapside],
							lines[line].special, lines[line].args[0], &tempalpha[sd], missingTex);

						side++;
					}
					else
					{
						lines[line].sidedef[sd] = NULL;
					}
				}
			}

			P_AdjustLine(&lines[line]);
			P_FinishLoadingLineDef(&lines[line], tempalpha[0]);
		}
		assert(side <= numsides);
		if (side < numsides)
		{
			Printf("Map had %d invalid side references\n", numsides - side);
			numsides = side;
		}
	}
예제 #2
0
static void LoadWalls (walltype *walls, int numwalls, sectortype *bsec)
{
    int i, j;

    // Setting numvertexes to the same as numwalls is overly conservative,
    // but the extra vertices will be removed during the BSP building pass.
    numsides = numvertexes = numwalls;
    numlines = 0;

    sides = new side_t[numsides];
    memset (sides, 0, numsides*sizeof(side_t));

    vertexes = new vertex_t[numvertexes];
    numvertexes = 0;

    // First mark each sidedef with the sector it belongs to
    for (i = 0; i < numsectors; ++i)
    {
        if (bsec[i].wallptr >= 0)
        {
            for (j = 0; j < bsec[i].wallnum; ++j)
            {
                sides[j + bsec[i].wallptr].sector = sectors + i;
            }
        }
    }

    // Now copy wall properties to their matching sidedefs
    for (i = 0; i < numwalls; ++i)
    {
        char tnam[9];
        FTextureID overpic, pic;

        mysnprintf (tnam, countof(tnam), "BTIL%04d", LittleShort(walls[i].picnum));
        pic = TexMan.GetTexture (tnam, FTexture::TEX_Build);
        mysnprintf (tnam, countof(tnam), "BTIL%04d", LittleShort(walls[i].overpicnum));
        overpic = TexMan.GetTexture (tnam, FTexture::TEX_Build);

        walls[i].x = LittleLong(walls[i].x);
        walls[i].y = LittleLong(walls[i].y);
        walls[i].point2 = LittleShort(walls[i].point2);
        walls[i].cstat = LittleShort(walls[i].cstat);
        walls[i].nextwall = LittleShort(walls[i].nextwall);
        walls[i].nextsector = LittleShort(walls[i].nextsector);

        sides[i].SetTextureXOffset(walls[i].xpanning << FRACBITS);
        sides[i].SetTextureYOffset(walls[i].ypanning << FRACBITS);

        sides[i].SetTexture(side_t::top, pic);
        sides[i].SetTexture(side_t::bottom, pic);
        if (walls[i].nextsector < 0 || (walls[i].cstat & 32))
        {
            sides[i].SetTexture(side_t::mid, pic);
        }
        else if (walls[i].cstat & 16)
        {
            sides[i].SetTexture(side_t::mid, overpic);
        }
        else
        {
            sides[i].SetTexture(side_t::mid, FNullTextureID());
        }

        sides[i].TexelLength = walls[i].xrepeat * 8;
        sides[i].SetTextureYScale(walls[i].yrepeat << (FRACBITS - 3));
        sides[i].SetTextureXScale(FRACUNIT);
        sides[i].SetLight(SHADE2LIGHT(walls[i].shade));
        sides[i].Flags = WALLF_ABSLIGHTING;
        sides[i].RightSide = walls[i].point2;
        sides[walls[i].point2].LeftSide = i;

        if (walls[i].nextwall >= 0 && walls[i].nextwall <= i)
        {
            sides[i].linedef = sides[walls[i].nextwall].linedef;
        }
        else
        {
            sides[i].linedef = (line_t*)(intptr_t)(numlines++);
        }
    }

    // Set line properties that Doom doesn't store per-sidedef
    lines = new line_t[numlines];
    memset (lines, 0, numlines*sizeof(line_t));

    for (i = 0, j = -1; i < numwalls; ++i)
    {
        if (walls[i].nextwall >= 0 && walls[i].nextwall <= i)
        {
            continue;
        }

        j = int(intptr_t(sides[i].linedef));
        lines[j].sidedef[0] = (side_t*)(intptr_t)i;
        lines[j].sidedef[1] = (side_t*)(intptr_t)walls[i].nextwall;
        lines[j].v1 = FindVertex (walls[i].x, walls[i].y);
        lines[j].v2 = FindVertex (walls[walls[i].point2].x, walls[walls[i].point2].y);
        lines[j].frontsector = sides[i].sector;
        lines[j].flags |= ML_WRAP_MIDTEX;
        if (walls[i].nextsector >= 0)
        {
            lines[j].backsector = sectors + walls[i].nextsector;
            lines[j].flags |= ML_TWOSIDED;
        }
        else
        {
            lines[j].backsector = NULL;
        }
        P_AdjustLine (&lines[j]);
        if (walls[i].cstat & 128)
        {
            if (walls[i].cstat & 512)
            {
                lines[j].Alpha = FRACUNIT/3;
            }
            else
            {
                lines[j].Alpha = FRACUNIT*2/3;
            }
        }
        if (walls[i].cstat & 1)
        {
            lines[j].flags |= ML_BLOCKING;
        }
        if (walls[i].nextwall < 0)
        {
            if (walls[i].cstat & 4)
            {
                lines[j].flags |= ML_DONTPEGBOTTOM;
            }
        }
        else
        {
            if (walls[i].cstat & 4)
            {
                lines[j].flags |= ML_DONTPEGTOP;
            }
            else
            {
                lines[j].flags |= ML_DONTPEGBOTTOM;
            }
        }
        if (walls[i].cstat & 64)
        {
            lines[j].flags |= ML_BLOCKEVERYTHING;
        }
    }

    // Finish setting sector properties that depend on walls
    for (i = 0; i < numsectors; ++i, ++bsec)
    {
        SlopeWork slope;

        slope.wal = &walls[bsec->wallptr];
        slope.wal2 = &walls[slope.wal->point2];
        slope.dx = slope.wal2->x - slope.wal->x;
        slope.dy = slope.wal2->y - slope.wal->y;
        slope.i = long (sqrt ((double)(slope.dx*slope.dx+slope.dy*slope.dy))) << 5;
        if (slope.i == 0)
        {
            continue;
        }
        if ((bsec->floorstat & 2) && (bsec->floorheinum != 0))
        {   // floor is sloped
            slope.heinum = -LittleShort(bsec->floorheinum);
            slope.z[0] = slope.z[1] = slope.z[2] = -bsec->floorz;
            CalcPlane (slope, sectors[i].floorplane);
        }
        if ((bsec->ceilingstat & 2) && (bsec->ceilingheinum != 0))
        {   // ceiling is sloped
            slope.heinum = -LittleShort(bsec->ceilingheinum);
            slope.z[0] = slope.z[1] = slope.z[2] = -bsec->ceilingz;
            CalcPlane (slope, sectors[i].ceilingplane);
        }
        int linenum = int(intptr_t(sides[bsec->wallptr].linedef));
        int sidenum = int(intptr_t(lines[linenum].sidedef[1]));
        if (bsec->floorstat & 64)
        {   // floor is aligned to first wall
            P_AlignFlat (linenum, sidenum == bsec->wallptr, 0);
        }
        if (bsec->ceilingstat & 64)
        {   // ceiling is aligned to first wall
            P_AlignFlat (linenum, sidenum == bsec->wallptr, 0);
        }
    }
    for (i = 0; i < numlines; i++)
    {
        intptr_t front = intptr_t(lines[i].sidedef[0]);
        intptr_t back = intptr_t(lines[i].sidedef[1]);
        lines[i].sidedef[0] = front >= 0 ? &sides[front] : NULL;
        lines[i].sidedef[1] = back >= 0 ? &sides[back] : NULL;
    }
    for (i = 0; i < numsides; i++)
    {
        assert(sides[i].sector != NULL);
        sides[i].linedef = &lines[intptr_t(sides[i].linedef)];
    }
}