Commit 4017418b authored by Jonathan Dowland's avatar Jonathan Dowland

New upstream version 5.2

parent 516b4bde
......@@ -19,7 +19,7 @@ mw.user.tokens.set({"editToken":"57b0d0a42998edb616af4511ffad9a235b2a6707+\\","p
<link rel="shortcut icon" href="/favicon.png"/>
<link rel="search" type="application/opensearchdescription+xml" href="/wiki/opensearch_desc.php" title="Chocolate Doom (en)"/>
<link rel="EditURI" type="application/rsd+xml" href="//www.chocolate-doom.org/wiki/api.php?action=rsd"/>
<link rel="copyright" href="https://creativecommons.org/licenses/by-sa/4.0/"/>
<link rel="copyright" href="https://creativecommons.org/licenses/by-nc-sa/4.0/"/>
<link rel="alternate" type="application/atom+xml" title="Chocolate Doom Atom feed" href="/wiki/index.php?title=Special:RecentChanges&amp;feed=atom"/>
</head>
<body class="mediawiki ltr sitedir-ltr ns-0 ns-subject page-Crispy_Doom rootpage-Crispy_Doom skin-vector action-view">
......
......@@ -41,6 +41,7 @@ m_background.h \
m_crispy.c m_crispy.h \
m_random.c m_random.h \
p_bexptr.c \
p_blockmap.c \
p_ceilng.c \
p_doors.c \
p_enemy.c \
......
//
// Copyright(C) 1993-1996 Id Software, Inc.
// Copyright(C) 1999 id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
// Copyright(C) 2005-2014 Simon Howard
// Copyright(C) 2017 Fabian Greffrath
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// DESCRIPTION:
// [crispy] Create Blockmap
//
#include <stdlib.h>
#include "i_system.h"
#include "p_local.h"
#include "z_zone.h"
// [crispy] taken from mbfsrc/P_SETUP.C:547-707, slightly adapted
void P_CreateBlockMap(void)
{
register int i;
fixed_t minx = INT_MAX, miny = INT_MAX, maxx = INT_MIN, maxy = INT_MIN;
// First find limits of map
for (i=0; i<numvertexes; i++)
{
if (vertexes[i].x >> FRACBITS < minx)
minx = vertexes[i].x >> FRACBITS;
else
if (vertexes[i].x >> FRACBITS > maxx)
maxx = vertexes[i].x >> FRACBITS;
if (vertexes[i].y >> FRACBITS < miny)
miny = vertexes[i].y >> FRACBITS;
else
if (vertexes[i].y >> FRACBITS > maxy)
maxy = vertexes[i].y >> FRACBITS;
}
// [crispy] doombsp/DRAWING.M:175-178
minx -= 8; miny -= 8;
maxx += 8; maxy += 8;
// Save blockmap parameters
bmaporgx = minx << FRACBITS;
bmaporgy = miny << FRACBITS;
bmapwidth = ((maxx-minx) >> MAPBTOFRAC) + 1;
bmapheight = ((maxy-miny) >> MAPBTOFRAC) + 1;
// Compute blockmap, which is stored as a 2d array of variable-sized lists.
//
// Pseudocode:
//
// For each linedef:
//
// Map the starting and ending vertices to blocks.
//
// Starting in the starting vertex's block, do:
//
// Add linedef to current block's list, dynamically resizing it.
//
// If current block is the same as the ending vertex's block, exit loop.
//
// Move to an adjacent block by moving towards the ending block in
// either the x or y direction, to the block which contains the linedef.
{
typedef struct { int n, nalloc, *list; } bmap_t; // blocklist structure
unsigned tot = bmapwidth * bmapheight; // size of blockmap
bmap_t *bmap = calloc(sizeof *bmap, tot); // array of blocklists
int x, y, adx, ady, bend;
for (i=0; i < numlines; i++)
{
int dx, dy, diff, b;
// starting coordinates
if (crispy->fliplevels)
{
x = (lines[i].v2->x >> FRACBITS) - minx;
y = (lines[i].v2->y >> FRACBITS) - miny;
}
else
{
x = (lines[i].v1->x >> FRACBITS) - minx;
y = (lines[i].v1->y >> FRACBITS) - miny;
}
// x-y deltas
adx = lines[i].dx >> FRACBITS, dx = adx < 0 ? -1 : 1;
ady = lines[i].dy >> FRACBITS, dy = ady < 0 ? -1 : 1;
// difference in preferring to move across y (>0) instead of x (<0)
diff = !adx ? 1 : !ady ? -1 :
(((x >> MAPBTOFRAC) << MAPBTOFRAC) +
(dx > 0 ? MAPBLOCKUNITS-1 : 0) - x) * (ady = abs(ady)) * dx -
(((y >> MAPBTOFRAC) << MAPBTOFRAC) +
(dy > 0 ? MAPBLOCKUNITS-1 : 0) - y) * (adx = abs(adx)) * dy;
// starting block, and pointer to its blocklist structure
b = (y >> MAPBTOFRAC)*bmapwidth + (x >> MAPBTOFRAC);
// ending block
if (crispy->fliplevels)
{
bend = (((lines[i].v1->y >> FRACBITS) - miny) >> MAPBTOFRAC) *
bmapwidth + (((lines[i].v1->x >> FRACBITS) - minx) >> MAPBTOFRAC);
}
else
{
bend = (((lines[i].v2->y >> FRACBITS) - miny) >> MAPBTOFRAC) *
bmapwidth + (((lines[i].v2->x >> FRACBITS) - minx) >> MAPBTOFRAC);
}
// delta for pointer when moving across y
dy *= bmapwidth;
// deltas for diff inside the loop
adx <<= MAPBTOFRAC;
ady <<= MAPBTOFRAC;
// Now we simply iterate block-by-block until we reach the end block.
while ((unsigned) b < tot) // failsafe -- should ALWAYS be true
{
// Increase size of allocated list if necessary
if (bmap[b].n >= bmap[b].nalloc)
bmap[b].list = I_Realloc(bmap[b].list,
(bmap[b].nalloc = bmap[b].nalloc ?
bmap[b].nalloc*2 : 8)*sizeof*bmap->list);
// Add linedef to end of list
bmap[b].list[bmap[b].n++] = i;
// If we have reached the last block, exit
if (b == bend)
break;
// Move in either the x or y direction to the next block
if (diff < 0)
diff += ady, b += dx;
else
diff -= adx, b += dy;
}
}
// Compute the total size of the blockmap.
//
// Compression of empty blocks is performed by reserving two offset words
// at tot and tot+1.
//
// 4 words, unused if this routine is called, are reserved at the start.
{
int count = tot+6; // we need at least 1 word per block, plus reserved's
for (i = 0; i < tot; i++)
if (bmap[i].n)
count += bmap[i].n + 2; // 1 header word + 1 trailer word + blocklist
// Allocate blockmap lump with computed count
blockmaplump = Z_Malloc(sizeof(*blockmaplump) * count, PU_LEVEL, 0);
}
// Now compress the blockmap.
{
int ndx = tot += 4; // Advance index to start of linedef lists
bmap_t *bp = bmap; // Start of uncompressed blockmap
blockmaplump[ndx++] = 0; // Store an empty blockmap list at start
blockmaplump[ndx++] = -1; // (Used for compression)
for (i = 4; i < tot; i++, bp++)
if (bp->n) // Non-empty blocklist
{
blockmaplump[blockmaplump[i] = ndx++] = 0; // Store index & header
do
blockmaplump[ndx++] = bp->list[--bp->n]; // Copy linedef list
while (bp->n);
blockmaplump[ndx++] = -1; // Store trailer
free(bp->list); // Free linedef list
}
else // Empty blocklist: point to reserved empty blocklist
blockmaplump[i] = tot;
free(bmap); // Free uncompressed blockmap
}
}
// [crispy] copied over from P_LoadBlockMap()
{
int count = sizeof(*blocklinks) * bmapwidth * bmapheight;
blocklinks = Z_Malloc(count, PU_LEVEL, 0);
memset(blocklinks, 0, count);
blockmap = blockmaplump+4;
}
}
......@@ -740,182 +740,6 @@ void P_LoadSideDefs (int lump)
W_ReleaseLumpNum(lump);
}
// [crispy] taken from mbfsrc/P_SETUP.C:547-707, slightly adapted
static void P_CreateBlockMap(void)
{
register int i;
fixed_t minx = INT_MAX, miny = INT_MAX, maxx = INT_MIN, maxy = INT_MIN;
// First find limits of map
for (i=0; i<numvertexes; i++)
{
if (vertexes[i].x >> FRACBITS < minx)
minx = vertexes[i].x >> FRACBITS;
else
if (vertexes[i].x >> FRACBITS > maxx)
maxx = vertexes[i].x >> FRACBITS;
if (vertexes[i].y >> FRACBITS < miny)
miny = vertexes[i].y >> FRACBITS;
else
if (vertexes[i].y >> FRACBITS > maxy)
maxy = vertexes[i].y >> FRACBITS;
}
// Save blockmap parameters
bmaporgx = minx << FRACBITS;
bmaporgy = miny << FRACBITS;
bmapwidth = ((maxx-minx) >> MAPBTOFRAC) + 1;
bmapheight = ((maxy-miny) >> MAPBTOFRAC) + 1;
// Compute blockmap, which is stored as a 2d array of variable-sized lists.
//
// Pseudocode:
//
// For each linedef:
//
// Map the starting and ending vertices to blocks.
//
// Starting in the starting vertex's block, do:
//
// Add linedef to current block's list, dynamically resizing it.
//
// If current block is the same as the ending vertex's block, exit loop.
//
// Move to an adjacent block by moving towards the ending block in
// either the x or y direction, to the block which contains the linedef.
{
typedef struct { int n, nalloc, *list; } bmap_t; // blocklist structure
unsigned tot = bmapwidth * bmapheight; // size of blockmap
bmap_t *bmap = calloc(sizeof *bmap, tot); // array of blocklists
int x, y, adx, ady, bend;
for (i=0; i < numlines; i++)
{
int dx, dy, diff, b;
// starting coordinates
if (crispy->fliplevels)
{
x = (lines[i].v2->x >> FRACBITS) - minx;
y = (lines[i].v2->y >> FRACBITS) - miny;
}
else
{
x = (lines[i].v1->x >> FRACBITS) - minx;
y = (lines[i].v1->y >> FRACBITS) - miny;
}
// x-y deltas
adx = lines[i].dx >> FRACBITS, dx = adx < 0 ? -1 : 1;
ady = lines[i].dy >> FRACBITS, dy = ady < 0 ? -1 : 1;
// difference in preferring to move across y (>0) instead of x (<0)
diff = !adx ? 1 : !ady ? -1 :
(((x >> MAPBTOFRAC) << MAPBTOFRAC) +
(dx > 0 ? MAPBLOCKUNITS-1 : 0) - x) * (ady = abs(ady)) * dx -
(((y >> MAPBTOFRAC) << MAPBTOFRAC) +
(dy > 0 ? MAPBLOCKUNITS-1 : 0) - y) * (adx = abs(adx)) * dy;
// starting block, and pointer to its blocklist structure
b = (y >> MAPBTOFRAC)*bmapwidth + (x >> MAPBTOFRAC);
// ending block
if (crispy->fliplevels)
{
bend = (((lines[i].v1->y >> FRACBITS) - miny) >> MAPBTOFRAC) *
bmapwidth + (((lines[i].v1->x >> FRACBITS) - minx) >> MAPBTOFRAC);
}
else
{
bend = (((lines[i].v2->y >> FRACBITS) - miny) >> MAPBTOFRAC) *
bmapwidth + (((lines[i].v2->x >> FRACBITS) - minx) >> MAPBTOFRAC);
}
// delta for pointer when moving across y
dy *= bmapwidth;
// deltas for diff inside the loop
adx <<= MAPBTOFRAC;
ady <<= MAPBTOFRAC;
// Now we simply iterate block-by-block until we reach the end block.
while ((unsigned) b < tot) // failsafe -- should ALWAYS be true
{
// Increase size of allocated list if necessary
if (bmap[b].n >= bmap[b].nalloc)
bmap[b].list = realloc(bmap[b].list,
(bmap[b].nalloc = bmap[b].nalloc ?
bmap[b].nalloc*2 : 8)*sizeof*bmap->list);
// Add linedef to end of list
bmap[b].list[bmap[b].n++] = i;
// If we have reached the last block, exit
if (b == bend)
break;
// Move in either the x or y direction to the next block
if (diff < 0)
diff += ady, b += dx;
else
diff -= adx, b += dy;
}
}
// Compute the total size of the blockmap.
//
// Compression of empty blocks is performed by reserving two offset words
// at tot and tot+1.
//
// 4 words, unused if this routine is called, are reserved at the start.
{
int count = tot+6; // we need at least 1 word per block, plus reserved's
for (i = 0; i < tot; i++)
if (bmap[i].n)
count += bmap[i].n + 2; // 1 header word + 1 trailer word + blocklist
// Allocate blockmap lump with computed count
blockmaplump = Z_Malloc(sizeof(*blockmaplump) * count, PU_LEVEL, 0);
}
// Now compress the blockmap.
{
int ndx = tot += 4; // Advance index to start of linedef lists
bmap_t *bp = bmap; // Start of uncompressed blockmap
blockmaplump[ndx++] = 0; // Store an empty blockmap list at start
blockmaplump[ndx++] = -1; // (Used for compression)
for (i = 4; i < tot; i++, bp++)
if (bp->n) // Non-empty blocklist
{
blockmaplump[blockmaplump[i] = ndx++] = 0; // Store index & header
do
blockmaplump[ndx++] = bp->list[--bp->n]; // Copy linedef list
while (bp->n);
blockmaplump[ndx++] = -1; // Store trailer
free(bp->list); // Free linedef list
}
else // Empty blocklist: point to reserved empty blocklist
blockmaplump[i] = tot;
free(bmap); // Free uncompressed blockmap
}
}
// [crispy] copied over from P_LoadBlockMap()
{
int count = sizeof(*blocklinks) * bmapwidth * bmapheight;
blocklinks = Z_Malloc(count, PU_LEVEL, 0);
memset(blocklinks, 0, count);
blockmap = blockmaplump+4;
}
}
//
// P_LoadBlockMap
......@@ -933,7 +757,6 @@ boolean P_LoadBlockMap (int lump)
(lumplen = W_LumpLength(lump)) < 8 ||
(count = lumplen / 2) >= 0x10000)
{
fprintf(stderr, "P_LoadBlockMap: (Re-)creating BLOCKMAP.\n");
return false;
}
......@@ -1400,7 +1223,10 @@ P_SetupLevel
P_LoadLineDefs (lumpnum+ML_LINEDEFS);
// [crispy] (re-)create BLOCKMAP if necessary
if (!crispy_validblockmap)
{
extern void P_CreateBlockMap (void);
P_CreateBlockMap();
}
if (crispy_mapformat & (MFMT_ZDBSPX | MFMT_ZDBSPZ))
P_LoadNodes_ZDBSP (lumpnum+ML_NODES, crispy_mapformat & MFMT_ZDBSPZ);
else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment