mirror of
https://github.com/ZDoom/gzdoom-last-svn.git
synced 2025-06-02 02:01:19 +00:00
- Added patch for Linux fixes.
- Added new ZDoom specific UDMF sector properties to map parser. - Added class definitions for new interpolators that are better equipped to interact with the interpolated objects. - Separated interpolation code into its own file r_interpolate.cpp. - Added some simple customization options to the end game screens. - Fixed: Polyobject detection in the internal node builder did not work anymore due to some code rearrangement for UDMF map loading. To keep it compatible between all map formats the THINGS lump of binary format maps must be loaded before building the nodes. This also means that the spawning itself can be done in the same function for all map types (except Build) now. - Changed 'Smooth mouse movement' menu option from m_filter to smooth_mouse which is more what would be expected from this option. - Fixed: Weapons and ammo items that were modified by Dehacked gave full ammo when being dropped by monsters. To properly handle this the handling of spawning Dehacked modified pickups was changed to use the DECORATE replacement feature instead of hacking the spawn state of the original item and calling a spawn function from there. - Fixed: The compatibility searches for teleport destinations did not work properly when the teleporter had both a tid and a tag. Now, if a teleporter has a tag these are skipped because they are only present for Hexen compatibility. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@111 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
parent
0afaae1d50
commit
c74026c71b
50 changed files with 1262 additions and 719 deletions
411
src/r_main.cpp
411
src/r_main.cpp
|
@ -1835,414 +1835,3 @@ void R_MultiresInit ()
|
|||
R_OldBlend = ~0;
|
||||
}
|
||||
|
||||
// Stuff from BUILD to interpolate floors and ceilings
|
||||
//
|
||||
// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
|
||||
// Ken Silverman's official web site: "http://www.advsys.net/ken"
|
||||
// See the included license file "BUILDLIC.TXT" for license info.
|
||||
// This code has been modified from its original form.
|
||||
|
||||
static bool didInterp;
|
||||
|
||||
FActiveInterpolation *FActiveInterpolation::curiposhash[INTERPOLATION_BUCKETS];
|
||||
|
||||
void FActiveInterpolation::CopyInterpToOld ()
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case INTERP_SectorFloor:
|
||||
oldipos[0] = ((sector_t*)Address)->floorplane.d;
|
||||
oldipos[1] = ((sector_t*)Address)->floortexz;
|
||||
break;
|
||||
case INTERP_SectorCeiling:
|
||||
oldipos[0] = ((sector_t*)Address)->ceilingplane.d;
|
||||
oldipos[1] = ((sector_t*)Address)->ceilingtexz;
|
||||
break;
|
||||
case INTERP_Vertex:
|
||||
oldipos[0] = ((vertex_t*)Address)->x;
|
||||
oldipos[1] = ((vertex_t*)Address)->y;
|
||||
break;
|
||||
case INTERP_FloorPanning:
|
||||
oldipos[0] = ((sector_t*)Address)->floor_xoffs;
|
||||
oldipos[1] = ((sector_t*)Address)->floor_yoffs;
|
||||
break;
|
||||
case INTERP_CeilingPanning:
|
||||
oldipos[0] = ((sector_t*)Address)->ceiling_xoffs;
|
||||
oldipos[1] = ((sector_t*)Address)->ceiling_yoffs;
|
||||
break;
|
||||
case INTERP_WallPanning_Top:
|
||||
case INTERP_WallPanning_Mid:
|
||||
case INTERP_WallPanning_Bottom:
|
||||
oldipos[0] = ((side_t*)Address)->GetTextureYOffset(Type - INTERP_WallPanning_Top);
|
||||
oldipos[1] = ((side_t*)Address)->GetTextureXOffset(Type - INTERP_WallPanning_Top);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FActiveInterpolation::CopyBakToInterp ()
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case INTERP_SectorFloor:
|
||||
((sector_t*)Address)->floorplane.d = bakipos[0];
|
||||
((sector_t*)Address)->floortexz = bakipos[1];
|
||||
break;
|
||||
case INTERP_SectorCeiling:
|
||||
((sector_t*)Address)->ceilingplane.d = bakipos[0];
|
||||
((sector_t*)Address)->ceilingtexz = bakipos[1];
|
||||
break;
|
||||
case INTERP_Vertex:
|
||||
((vertex_t*)Address)->x = bakipos[0];
|
||||
((vertex_t*)Address)->y = bakipos[1];
|
||||
break;
|
||||
case INTERP_FloorPanning:
|
||||
((sector_t*)Address)->floor_xoffs = bakipos[0];
|
||||
((sector_t*)Address)->floor_yoffs = bakipos[1];
|
||||
break;
|
||||
case INTERP_CeilingPanning:
|
||||
((sector_t*)Address)->ceiling_xoffs = bakipos[0];
|
||||
((sector_t*)Address)->ceiling_yoffs = bakipos[1];
|
||||
break;
|
||||
case INTERP_WallPanning_Top:
|
||||
case INTERP_WallPanning_Mid:
|
||||
case INTERP_WallPanning_Bottom:
|
||||
((side_t*)Address)->SetTextureYOffset(Type - INTERP_WallPanning_Top, bakipos[0]);
|
||||
((side_t*)Address)->SetTextureXOffset(Type - INTERP_WallPanning_Top, bakipos[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FActiveInterpolation::DoAnInterpolation (fixed_t smoothratio)
|
||||
{
|
||||
fixed_t *adr1, *adr2, pos;
|
||||
int v1, v2;
|
||||
|
||||
switch (Type)
|
||||
{
|
||||
case INTERP_SectorFloor:
|
||||
adr1 = &((sector_t*)Address)->floorplane.d;
|
||||
adr2 = &((sector_t*)Address)->floortexz;
|
||||
break;
|
||||
case INTERP_SectorCeiling:
|
||||
adr1 = &((sector_t*)Address)->ceilingplane.d;
|
||||
adr2 = &((sector_t*)Address)->ceilingtexz;
|
||||
break;
|
||||
case INTERP_Vertex:
|
||||
adr1 = &((vertex_t*)Address)->x;
|
||||
adr2 = &((vertex_t*)Address)->y;
|
||||
break;
|
||||
case INTERP_FloorPanning:
|
||||
adr1 = &((sector_t*)Address)->floor_xoffs;
|
||||
adr2 = &((sector_t*)Address)->floor_yoffs;
|
||||
break;
|
||||
case INTERP_CeilingPanning:
|
||||
adr1 = &((sector_t*)Address)->ceiling_xoffs;
|
||||
adr2 = &((sector_t*)Address)->ceiling_yoffs;
|
||||
break;
|
||||
case INTERP_WallPanning_Top:
|
||||
case INTERP_WallPanning_Mid:
|
||||
case INTERP_WallPanning_Bottom:
|
||||
v1 = ((side_t*)Address)->GetTextureYOffset(Type - INTERP_WallPanning_Top);
|
||||
v2 = ((side_t*)Address)->GetTextureXOffset(Type - INTERP_WallPanning_Top);
|
||||
adr1 = &v1;
|
||||
adr2 = &v2;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
pos = bakipos[0] = *adr1;
|
||||
*adr1 = oldipos[0] + FixedMul (pos - oldipos[0], smoothratio);
|
||||
|
||||
pos = bakipos[1] = *adr2;
|
||||
*adr2 = oldipos[1] + FixedMul (pos - oldipos[1], smoothratio);
|
||||
|
||||
switch (Type)
|
||||
{
|
||||
case INTERP_WallPanning_Top:
|
||||
case INTERP_WallPanning_Mid:
|
||||
case INTERP_WallPanning_Bottom:
|
||||
((side_t*)Address)->SetTextureYOffset(Type - INTERP_WallPanning_Top, v1);
|
||||
((side_t*)Address)->SetTextureXOffset(Type - INTERP_WallPanning_Top, v2);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
size_t FActiveInterpolation::HashKey (EInterpType type, void *interptr)
|
||||
{
|
||||
return (size_t)type * ((size_t)interptr>>5);
|
||||
}
|
||||
|
||||
int FActiveInterpolation::CountInterpolations ()
|
||||
{
|
||||
int d1, d2, d3;
|
||||
return CountInterpolations (&d1, &d2, &d3);
|
||||
}
|
||||
|
||||
int FActiveInterpolation::CountInterpolations (int *usedbuckets, int *minbucketfill, int *maxbucketfill)
|
||||
{
|
||||
int count = 0;
|
||||
int inuse = 0;
|
||||
int minuse = INT_MAX;
|
||||
int maxuse = INT_MIN;
|
||||
|
||||
for (int i = INTERPOLATION_BUCKETS-1; i >= 0; --i)
|
||||
{
|
||||
int use = 0;
|
||||
FActiveInterpolation *probe = FActiveInterpolation::curiposhash[i];
|
||||
if (probe != NULL)
|
||||
{
|
||||
inuse++;
|
||||
}
|
||||
while (probe != NULL)
|
||||
{
|
||||
count++;
|
||||
use++;
|
||||
probe = probe->Next;
|
||||
}
|
||||
if (use > 0 && use < minuse)
|
||||
{
|
||||
minuse = use;
|
||||
}
|
||||
if (use > maxuse)
|
||||
{
|
||||
maxuse = use;
|
||||
}
|
||||
}
|
||||
*usedbuckets = inuse;
|
||||
*minbucketfill = minuse == INT_MAX ? 0 : minuse;
|
||||
*maxbucketfill = maxuse;
|
||||
return count;
|
||||
}
|
||||
|
||||
FActiveInterpolation *FActiveInterpolation::FindInterpolation (EInterpType type, void *interptr, FActiveInterpolation **&interp_p)
|
||||
{
|
||||
size_t hash = HashKey (type, interptr) % INTERPOLATION_BUCKETS;
|
||||
FActiveInterpolation *probe, **probe_p;
|
||||
|
||||
for (probe_p = &curiposhash[hash], probe = *probe_p;
|
||||
probe != NULL;
|
||||
probe_p = &probe->Next, probe = *probe_p)
|
||||
{
|
||||
if (probe->Address > interptr)
|
||||
{ // We passed the place it would have been, so it must not be here.
|
||||
probe = NULL;
|
||||
break;
|
||||
}
|
||||
if (probe->Address == interptr && probe->Type == type)
|
||||
{ // Found it.
|
||||
break;
|
||||
}
|
||||
}
|
||||
interp_p = probe_p;
|
||||
return probe;
|
||||
}
|
||||
|
||||
void clearinterpolations()
|
||||
{
|
||||
for (int i = INTERPOLATION_BUCKETS-1; i >= 0; --i)
|
||||
{
|
||||
for (FActiveInterpolation *probe = FActiveInterpolation::curiposhash[i];
|
||||
probe != NULL; )
|
||||
{
|
||||
FActiveInterpolation *next = probe->Next;
|
||||
delete probe;
|
||||
probe = next;
|
||||
}
|
||||
FActiveInterpolation::curiposhash[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void updateinterpolations() //Stick at beginning of domovethings
|
||||
{
|
||||
for (int i = INTERPOLATION_BUCKETS-1; i >= 0; --i)
|
||||
{
|
||||
for (FActiveInterpolation *probe = FActiveInterpolation::curiposhash[i];
|
||||
probe != NULL; probe = probe->Next)
|
||||
{
|
||||
probe->CopyInterpToOld ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setinterpolation(EInterpType type, void *posptr, bool dolinks)
|
||||
{
|
||||
FActiveInterpolation **interp_p;
|
||||
FActiveInterpolation *interp = FActiveInterpolation::FindInterpolation (type, posptr, interp_p);
|
||||
if (interp != NULL) return; // It's already active
|
||||
interp = new FActiveInterpolation;
|
||||
interp->Type = type;
|
||||
interp->Address = posptr;
|
||||
interp->Next = *interp_p;
|
||||
*interp_p = interp;
|
||||
interp->CopyInterpToOld ();
|
||||
|
||||
if (dolinks)
|
||||
{
|
||||
if (type == INTERP_SectorFloor)
|
||||
{
|
||||
P_Start3dMidtexInterpolations((sector_t*)posptr, false);
|
||||
P_StartLinkedSectorInterpolations((sector_t*)posptr, false);
|
||||
}
|
||||
else if (type == INTERP_SectorCeiling)
|
||||
{
|
||||
P_Start3dMidtexInterpolations((sector_t*)posptr, true);
|
||||
P_StartLinkedSectorInterpolations((sector_t*)posptr, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stopinterpolation(EInterpType type, void *posptr, bool dolinks)
|
||||
{
|
||||
FActiveInterpolation **interp_p;
|
||||
FActiveInterpolation *interp = FActiveInterpolation::FindInterpolation (type, posptr, interp_p);
|
||||
if (interp != NULL)
|
||||
{
|
||||
*interp_p = interp->Next;
|
||||
delete interp;
|
||||
|
||||
if (dolinks)
|
||||
{
|
||||
if (type == INTERP_SectorFloor)
|
||||
{
|
||||
P_Stop3dMidtexInterpolations((sector_t*)posptr, false);
|
||||
P_StopLinkedSectorInterpolations((sector_t*)posptr, false);
|
||||
}
|
||||
else if (type == INTERP_SectorCeiling)
|
||||
{
|
||||
P_Stop3dMidtexInterpolations((sector_t*)posptr, true);
|
||||
P_StopLinkedSectorInterpolations((sector_t*)posptr, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dointerpolations(fixed_t smoothratio) //Stick at beginning of drawscreen
|
||||
{
|
||||
if (smoothratio == FRACUNIT)
|
||||
{
|
||||
didInterp = false;
|
||||
return;
|
||||
}
|
||||
|
||||
didInterp = true;
|
||||
|
||||
for (int i = INTERPOLATION_BUCKETS-1; i >= 0; --i)
|
||||
{
|
||||
for (FActiveInterpolation *probe = FActiveInterpolation::curiposhash[i];
|
||||
probe != NULL; probe = probe->Next)
|
||||
{
|
||||
probe->DoAnInterpolation (smoothratio);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void restoreinterpolations() //Stick at end of drawscreen
|
||||
{
|
||||
if (didInterp)
|
||||
{
|
||||
didInterp = false;
|
||||
for (int i = INTERPOLATION_BUCKETS-1; i >= 0; --i)
|
||||
{
|
||||
for (FActiveInterpolation *probe = FActiveInterpolation::curiposhash[i];
|
||||
probe != NULL; probe = probe->Next)
|
||||
{
|
||||
probe->CopyBakToInterp ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SerializeInterpolations (FArchive &arc)
|
||||
{
|
||||
FActiveInterpolation *interp;
|
||||
int numinterpolations;
|
||||
int i;
|
||||
|
||||
if (arc.IsStoring ())
|
||||
{
|
||||
numinterpolations = FActiveInterpolation::CountInterpolations();
|
||||
arc.WriteCount (numinterpolations);
|
||||
for (i = INTERPOLATION_BUCKETS-1; i >= 0; --i)
|
||||
{
|
||||
for (interp = FActiveInterpolation::curiposhash[i];
|
||||
interp != NULL; interp = interp->Next)
|
||||
{
|
||||
arc << interp;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
clearinterpolations ();
|
||||
numinterpolations = arc.ReadCount ();
|
||||
for (i = numinterpolations; i > 0; --i)
|
||||
{
|
||||
FActiveInterpolation **interp_p;
|
||||
arc << interp;
|
||||
if (FActiveInterpolation::FindInterpolation (interp->Type, interp->Address, interp_p) == NULL)
|
||||
{ // Should always return NULL, because there should never be any duplicates stored.
|
||||
interp->Next = *interp_p;
|
||||
*interp_p = interp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FArchive &operator << (FArchive &arc, FActiveInterpolation *&interp)
|
||||
{
|
||||
BYTE type;
|
||||
union
|
||||
{
|
||||
vertex_t *vert;
|
||||
sector_t *sect;
|
||||
side_t *side;
|
||||
void *ptr;
|
||||
} ptr;
|
||||
|
||||
if (arc.IsStoring ())
|
||||
{
|
||||
type = interp->Type;
|
||||
ptr.ptr = interp->Address;
|
||||
arc << type;
|
||||
switch (type)
|
||||
{
|
||||
case INTERP_Vertex: arc << ptr.vert; break;
|
||||
case INTERP_WallPanning_Top:
|
||||
case INTERP_WallPanning_Mid:
|
||||
case INTERP_WallPanning_Bottom:
|
||||
arc << ptr.side; break;
|
||||
default: arc << ptr.sect; break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
interp = new FActiveInterpolation;
|
||||
arc << type;
|
||||
interp->Type = (EInterpType)type;
|
||||
switch (type)
|
||||
{
|
||||
case INTERP_Vertex: arc << ptr.vert; break;
|
||||
case INTERP_WallPanning_Top:
|
||||
case INTERP_WallPanning_Mid:
|
||||
case INTERP_WallPanning_Bottom:
|
||||
arc << ptr.side; break;
|
||||
default: arc << ptr.sect; break;
|
||||
}
|
||||
interp->Address = ptr.ptr;
|
||||
}
|
||||
return arc;
|
||||
}
|
||||
|
||||
ADD_STAT (interpolations)
|
||||
{
|
||||
int inuse, minuse, maxuse, total;
|
||||
FString out;
|
||||
total = FActiveInterpolation::CountInterpolations (&inuse, &minuse, &maxuse);
|
||||
out.Format ("%d interpolations buckets:%3d min:%3d max:%3d avg:%3d %d%% full %d%% buckfull",
|
||||
total, inuse, minuse, maxuse, inuse?total/inuse:0, total*100/INTERPOLATION_BUCKETS, inuse*100/INTERPOLATION_BUCKETS);
|
||||
return out;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue