- Fixed: Parsing sector special bit masks must be done backwards so that later

definitions take precedence.
- Added base translation tables for UDMF compatibility maps which only should
  handle the native line and sector types of each game.
- Turned the inactive SILENT_INSTANT_FLOORS define into a compatibility option
  so that it can be (un)set in a map definition and the menu. 

SVN r966 (trunk)
This commit is contained in:
Christoph Oelckers 2008-05-12 17:14:38 +00:00
parent b2176a4a33
commit 0869b51928
17 changed files with 196 additions and 103 deletions

View file

@ -1,4 +1,10 @@
May 12, 2008 (Changes by Graf Zahl) May 12, 2008 (Changes by Graf Zahl)
- Fixed: Parsing sector special bit masks must be done backwards so that later
definitions take precedence.
- Added base translation tables for UDMF compatibility maps which only should
handle the native line and sector types of each game.
- Turned the inactive SILENT_INSTANT_FLOORS define into a compatibility option
so that it can be (un)set in a map definition and the menu.
- Fixed: SPAC_AnyCross didn't work. - Fixed: SPAC_AnyCross didn't work.
- Fixed: Pushable doors must also check for SPAC_MPush. - Fixed: Pushable doors must also check for SPAC_MPush.
- Fixed: P_LoadThings2 did not adjust the byte order for the thingid field. - Fixed: P_LoadThings2 did not adjust the byte order for the thingid field.

View file

@ -452,6 +452,7 @@ CVAR (Flag, compat_trace, compatflags, COMPATF_TRACE);
CVAR (Flag, compat_dropoff, compatflags, COMPATF_DROPOFF); CVAR (Flag, compat_dropoff, compatflags, COMPATF_DROPOFF);
CVAR (Flag, compat_boomscroll, compatflags, COMPATF_BOOMSCROLL); CVAR (Flag, compat_boomscroll, compatflags, COMPATF_BOOMSCROLL);
CVAR (Flag, compat_invisibility,compatflags, COMPATF_INVISIBILITY); CVAR (Flag, compat_invisibility,compatflags, COMPATF_INVISIBILITY);
CVAR (Flag, compat_silentinstantfloors,compatflags, COMPATF_SILENT_INSTANT_FLOORS);
//========================================================================== //==========================================================================
// //

View file

@ -88,7 +88,7 @@ typedef struct
} mapsidedef_t; } mapsidedef_t;
// A LineDef, as used for editing, and as input to the BSP builder. // A LineDef, as used for editing, and as input to the BSP builder.
typedef struct struct maplinedef_t
{ {
WORD v1; WORD v1;
WORD v2; WORD v2;
@ -97,10 +97,10 @@ typedef struct
short tag; short tag;
WORD sidenum[2]; // sidenum[1] will be -1 if one sided WORD sidenum[2]; // sidenum[1] will be -1 if one sided
} maplinedef_t; } ;
// [RH] Hexen-compatible LineDef. // [RH] Hexen-compatible LineDef.
typedef struct struct maplinedef2_t
{ {
WORD v1; WORD v1;
WORD v2; WORD v2;
@ -108,7 +108,7 @@ typedef struct
BYTE special; BYTE special;
BYTE args[5]; BYTE args[5];
WORD sidenum[2]; WORD sidenum[2];
} maplinedef2_t; } ;
// //

View file

@ -282,6 +282,7 @@ enum
COMPATF_DROPOFF = 1 << 14, // Monsters cannot move when hanging over a dropoff COMPATF_DROPOFF = 1 << 14, // Monsters cannot move when hanging over a dropoff
COMPATF_BOOMSCROLL = 1 << 15, // Scrolling sectors are additive like in Boom COMPATF_BOOMSCROLL = 1 << 15, // Scrolling sectors are additive like in Boom
COMPATF_INVISIBILITY = 1 << 16, // Monsters can see semi-invisible players COMPATF_INVISIBILITY = 1 << 16, // Monsters can see semi-invisible players
COMPATF_SILENT_INSTANT_FLOORS = 1<<17, // Instantly moving floors are not silent
}; };
// phares 3/20/98: // phares 3/20/98:

View file

@ -295,6 +295,7 @@ static const char *MapInfoMapLevel[] =
"compat_dropoff", "compat_dropoff",
"compat_boomscroll", "compat_boomscroll",
"compat_invisibility", "compat_invisibility",
"compat_silent_instant_floors",
"bordertexture", "bordertexture",
"f1", // [RC] F1 help "f1", // [RC] F1 help
"noinfighting", "noinfighting",
@ -445,6 +446,7 @@ MapHandlers[] =
{ MITYPE_COMPATFLAG, COMPATF_DROPOFF}, { MITYPE_COMPATFLAG, COMPATF_DROPOFF},
{ MITYPE_COMPATFLAG, COMPATF_BOOMSCROLL}, { MITYPE_COMPATFLAG, COMPATF_BOOMSCROLL},
{ MITYPE_COMPATFLAG, COMPATF_INVISIBILITY}, { MITYPE_COMPATFLAG, COMPATF_INVISIBILITY},
{ MITYPE_COMPATFLAG, COMPATF_SILENT_INSTANT_FLOORS},
{ MITYPE_LUMPNAME, lioffset(bordertexture), 0 }, { MITYPE_LUMPNAME, lioffset(bordertexture), 0 },
{ MITYPE_LUMPNAME, lioffset(f1), 0, }, { MITYPE_LUMPNAME, lioffset(f1), 0, },
{ MITYPE_SCFLAGS, LEVEL_NOINFIGHTING, ~LEVEL_TOTALINFIGHTING }, { MITYPE_SCFLAGS, LEVEL_NOINFIGHTING, ~LEVEL_TOTALINFIGHTING },

View file

@ -1108,6 +1108,7 @@ static menuitem_t CompatibilityItems[] = {
{ bitflag, "Monsters get stuck over dropoffs", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_DROPOFF} }, { bitflag, "Monsters get stuck over dropoffs", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_DROPOFF} },
{ bitflag, "Monsters see invisible players", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_INVISIBILITY} }, { bitflag, "Monsters see invisible players", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_INVISIBILITY} },
{ bitflag, "Boom scrollers are additive", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_BOOMSCROLL} }, { bitflag, "Boom scrollers are additive", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_BOOMSCROLL} },
{ bitflag, "Inst. moving floors are not silent", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_SILENT_INSTANT_FLOORS} },
{ discrete, "Interpolate monster movement", {&nomonsterinterpolation}, {2.0}, {0.0}, {0.0}, {NoYes} }, { discrete, "Interpolate monster movement", {&nomonsterinterpolation}, {2.0}, {0.0}, {0.0}, {NoYes} },
}; };

View file

@ -533,8 +533,6 @@ manual_floor:
} }
// Do not interpolate instant movement floors. // Do not interpolate instant movement floors.
// Note for ZDoomGL: Check to make sure that you update the sector
// after the floor moves, because it hasn't actually moved yet.
bool silent = false; bool silent = false;
if ((floor->m_Direction>0 && floor->m_FloorDestDist>sec->floorplane.d) || // moving up but going down if ((floor->m_Direction>0 && floor->m_FloorDestDist>sec->floorplane.d) || // moving up but going down
@ -542,18 +540,15 @@ manual_floor:
(floor->m_Speed >= abs(sec->floorplane.d - floor->m_FloorDestDist))) // moving in one step (floor->m_Speed >= abs(sec->floorplane.d - floor->m_FloorDestDist))) // moving in one step
{ {
stopinterpolation (INTERP_SectorFloor, sec); stopinterpolation (INTERP_SectorFloor, sec);
// [Graf Zahl] // [Graf Zahl]
// Don't make sounds for instant movement hacks but make an exception for // Don't make sounds for instant movement hacks but make an exception for
// switches that activate their own back side. // switches that activate their own back side.
// I'll leave the decision about this to somebody else. In many maps if (!(i_compatflags & COMPATF_SILENT_INSTANT_FLOORS))
// it helps but there are some where this omits sounds that should be there.
#ifdef SILENT_INSTANT_FLOORS
if (floortype != DFloor::floorRaiseInstant && floortype != DFloor::floorLowerInstant)
{ {
if (!line || GET_SPAC(line->flags) != SPAC_USE || line->backsector!=sec) if (!line || !(line->activation & (SPAC_Use|SPAC_Push)) || line->backsector!=sec)
silent = true; silent = true;
} }
#endif
} }
if (!silent) floor->StartFloorSound (); if (!silent) floor->StartFloorSound ();

View file

@ -67,10 +67,7 @@ void P_SetSlopes ();
extern AActor *P_SpawnMapThing (FMapThing *mthing, int position); extern AActor *P_SpawnMapThing (FMapThing *mthing, int position);
extern bool P_LoadBuildMap (BYTE *mapdata, size_t len, FMapThing **things, int *numthings); extern bool P_LoadBuildMap (BYTE *mapdata, size_t len, FMapThing **things, int *numthings);
extern void P_LoadTranslator(const char *lump);
extern void P_TranslateLineDef (line_t *ld, maplinedef_t *mld);
extern void P_TranslateTeleportThings (void); extern void P_TranslateTeleportThings (void);
extern int P_TranslateSectorSpecial (int);
void P_ParseTextMap(MapData *map); void P_ParseTextMap(MapData *map);
void P_SpawnTextThings(int position); void P_SpawnTextThings(int position);

View file

@ -99,4 +99,11 @@ void P_FreeExtraLevelData();
// Called by startup code. // Called by startup code.
void P_Init (void); void P_Init (void);
struct line_t;
struct maplinedef_t;
void P_LoadTranslator(const char *lumpname);
void P_TranslateLineDef (line_t *ld, maplinedef_t *mld);
int P_TranslateSectorSpecial (int);
#endif #endif

View file

@ -41,8 +41,6 @@
#include "templates.h" #include "templates.h"
#include "i_system.h" #include "i_system.h"
extern void P_TranslateLineDef (line_t *ld, maplinedef_t *mld);
extern int P_TranslateSectorSpecial (int);
void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, mapsidedef_t *msd, int special, int tag, short *alpha); void P_ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec, mapsidedef_t *msd, int special, int tag, short *alpha);
void P_AdjustLine (line_t *ld); void P_AdjustLine (line_t *ld);
void P_FinishLoadingLineDef(line_t *ld, int alpha); void P_FinishLoadingLineDef(line_t *ld, int alpha);
@ -193,16 +191,25 @@ struct UDMFParser
} }
if (isTranslated) if (isTranslated)
{ {
// NOTE: Handling of this is undefined in the UDMF spec yet! if (isExtended)
maplinedef_t mld; {
line_t ld; // NOTE: Handling of this is undefined in the UDMF spec
// so it is only done for namespace ZDoomTranslated
maplinedef_t mld;
line_t ld;
mld.flags = 0; mld.flags = 0;
mld.special = th->special; mld.special = th->special;
mld.tag = th->args[0]; mld.tag = th->args[0];
P_TranslateLineDef(&ld, &mld); P_TranslateLineDef(&ld, &mld);
th->special = ld.special; th->special = ld.special;
memcpy(th->args, ld.args, sizeof (ld.args)); memcpy(th->args, ld.args, sizeof (ld.args));
}
else // NULL the special
{
th->special = 0;
memset(th->args, 0, sizeof (th->args));
}
} }
} }
@ -226,6 +233,8 @@ struct UDMFParser
sc.MustGetString(); sc.MustGetString();
FString value = sc.String; FString value = sc.String;
sc.MustGetStringName(";"); sc.MustGetStringName(";");
// This switch contains all keys of the UDMF base spec
switch(key) switch(key)
{ {
case NAME_V1: case NAME_V1:
@ -273,55 +282,65 @@ struct UDMFParser
Flag(ld->flags, ML_MAPPED, value); break; Flag(ld->flags, ML_MAPPED, value); break;
case NAME_Monsteractivate: case NAME_Monsteractivate:
Flag(ld->flags, ML_MONSTERSCANACTIVATE, value); break; Flag(ld->flags, ML_MONSTERSCANACTIVATE, value); break;
case NAME_Blockplayers:
if (isExtended) Flag(ld->flags, ML_BLOCK_PLAYERS, value); break;
case NAME_Blockeverything:
if (isExtended) Flag(ld->flags, ML_BLOCKEVERYTHING, value); break;
case NAME_Zoneboundary:
if (isExtended) Flag(ld->flags, ML_ZONEBOUNDARY, value); break;
case NAME_Jumpover: case NAME_Jumpover:
if (isExtended || namespc == NAME_Strife) Flag(ld->flags, ML_RAILING, value); break; Flag(ld->flags, ML_RAILING, value); break;
case NAME_Blockfloating: case NAME_Blockfloating:
if (isExtended || namespc == NAME_Strife) Flag(ld->flags, ML_BLOCK_FLOATERS, value); break; Flag(ld->flags, ML_BLOCK_FLOATERS, value); break;
case NAME_Clipmidtex:
if (isExtended) Flag(ld->flags, ML_CLIP_MIDTEX, value); break;
case NAME_Wrapmidtex:
if (isExtended) Flag(ld->flags, ML_WRAP_MIDTEX, value); break;
case NAME_Midtex3d:
if (isExtended) Flag(ld->flags, ML_3DMIDTEX, value); break;
case NAME_Checkswitchrange:
if (isExtended) Flag(ld->flags, ML_CHECKSWITCHRANGE, value); break;
case NAME_Firstsideonly:
if (isExtended) Flag(ld->flags, ML_FIRSTSIDEONLY, value); break;
case NAME_Transparent: case NAME_Transparent:
ld->Alpha = !value.CompareNoCase("true")? FRACUNIT*3/4 : FRACUNIT; break; ld->Alpha = !value.CompareNoCase("true")? FRACUNIT*3/4 : FRACUNIT; break;
case NAME_Passuse: case NAME_Passuse:
passuse = !value.CompareNoCase("true"); passuse = !value.CompareNoCase("true"); break;
case NAME_Playercross: default:
if (isExtended) Flag(ld->activation, SPAC_Cross, value); break; break;
case NAME_Playeruse: }
if (isExtended) Flag(ld->activation, SPAC_Use, value); break;
case NAME_Monstercross:
if (isExtended) Flag(ld->activation, SPAC_MCross, value); break;
case NAME_Impact:
if (isExtended) Flag(ld->activation, SPAC_Impact, value); break;
case NAME_Playerpush:
if (isExtended) Flag(ld->activation, SPAC_Push, value); break;
case NAME_Missilecross:
if (isExtended) Flag(ld->activation, SPAC_PCross, value); break;
case NAME_Monsteruse:
if (isExtended) Flag(ld->activation, SPAC_MUse, value); break;
case NAME_Monsterpush:
if (isExtended) Flag(ld->activation, SPAC_MPush, value); break;
// This switch contains all keys of the UDMF base spec which only apply to Hexen format specials
if (!isTranslated) switch (key)
{
case NAME_Playercross:
Flag(ld->activation, SPAC_Cross, value); break;
case NAME_Playeruse:
Flag(ld->activation, SPAC_Use, value); break;
case NAME_Monstercross:
Flag(ld->activation, SPAC_MCross, value); break;
case NAME_Impact:
Flag(ld->activation, SPAC_Impact, value); break;
case NAME_Playerpush:
Flag(ld->activation, SPAC_Push, value); break;
case NAME_Missilecross:
Flag(ld->activation, SPAC_PCross, value); break;
case NAME_Monsteruse:
Flag(ld->activation, SPAC_MUse, value); break;
case NAME_Monsterpush:
Flag(ld->activation, SPAC_MPush, value); break;
default:
break;
}
// This switch contains all keys which are ZDoom specific
if (isExtended) switch(key)
{
case NAME_Blockplayers:
Flag(ld->flags, ML_BLOCK_PLAYERS, value); break;
case NAME_Blockeverything:
Flag(ld->flags, ML_BLOCKEVERYTHING, value); break;
case NAME_Zoneboundary:
Flag(ld->flags, ML_ZONEBOUNDARY, value); break;
case NAME_Clipmidtex:
Flag(ld->flags, ML_CLIP_MIDTEX, value); break;
case NAME_Wrapmidtex:
Flag(ld->flags, ML_WRAP_MIDTEX, value); break;
case NAME_Midtex3d:
Flag(ld->flags, ML_3DMIDTEX, value); break;
case NAME_Checkswitchrange:
Flag(ld->flags, ML_CHECKSWITCHRANGE, value); break;
case NAME_Firstsideonly:
Flag(ld->flags, ML_FIRSTSIDEONLY, value); break;
default: default:
break; break;
} }
} }
if (isTranslated) if (isTranslated)
{
}
else
{ {
int saved = ld->flags; int saved = ld->flags;
@ -589,42 +608,50 @@ struct UDMFParser
map->Read(ML_TEXTMAP, buffer); map->Read(ML_TEXTMAP, buffer);
sc.OpenMem(Wads.GetLumpFullName(map->lumpnum), buffer, map->Size(ML_TEXTMAP)); sc.OpenMem(Wads.GetLumpFullName(map->lumpnum), buffer, map->Size(ML_TEXTMAP));
sc.SetCMode(true); sc.SetCMode(true);
if (sc.CheckString("namespace"))
{
sc.MustGetStringName("=");
sc.MustGetString();
namespc = sc.String;
if (namespc == NAME_ZDoom)
{
isTranslated = false;
isExtended = true;
}
else if (namespc == NAME_Hexen)
{
isTranslated = false;
}
else if (namespc == NAME_ZDoomTranslated)
{
isExtended = true;
}
else if (namespc == NAME_Doom)
{
P_LoadTranslator("xlat/doom_base.txt");
}
else if (namespc == NAME_Heretic)
{
P_LoadTranslator("xlat/heretic_base.txt");
}
else if (namespc == NAME_Strife)
{
P_LoadTranslator("xlat/strife_base.txt");
}
else
{
Printf("Unknown namespace %s\n", sc.String);
}
sc.MustGetStringName(";");
}
else
{
Printf("Map does not define a namespace.\n");
}
while (sc.GetString()) while (sc.GetString())
{ {
if (sc.Compare("namespace")) if (sc.Compare("thing"))
{
sc.MustGetStringName("=");
sc.MustGetString();
namespc = sc.String;
if (namespc == NAME_ZDoom)
{
isTranslated = false;
isExtended = true;
}
else if (namespc == NAME_Hexen)
{
isTranslated = false;
}
else if (namespc == NAME_ZDoomTranslated)
{
isExtended = true;
}
else if (namespc == NAME_Doom)
{
}
else if (namespc == NAME_Heretic)
{
}
else if (namespc == NAME_Strife)
{
}
else
{
sc.ScriptError("Unknown namespace %s", sc.String);
}
sc.MustGetStringName(";");
}
else if (sc.Compare("thing"))
{ {
FMapThing th; FMapThing th;
ParseThing(&th); ParseThing(&th);

View file

@ -337,7 +337,7 @@ int P_TranslateSectorSpecial (int special)
{ {
int mask = 0; int mask = 0;
for(unsigned i = 0; i < SectorMasks.Size(); i++) for(int i = SectorMasks.Size()-1; i>=0; i--)
{ {
int newmask = special & SectorMasks[i].mask; int newmask = special & SectorMasks[i].mask;
if (newmask) if (newmask)

View file

@ -111,20 +111,20 @@ struct XlatParseContext : public FParseContext
//========================================================================== //==========================================================================
bool FindToken (char *tok, int *type) bool FindToken (char *tok, int *type)
{ {
static const char tokens[][10] = static const char *tokens[] =
{ {
"arg2", "arg3", "arg4", "arg5", "bitmask", "clear", "arg2", "arg3", "arg4", "arg5", "bitmask", "clear",
"define", "enum", "flags", "include", "lineid", "define", "enum", "flags", "include", "lineid",
"nobitmask", "sector", "tag" "nobitmask", "sector", "tag", "maxlinespecial"
}; };
static const short types[] = static const short types[] =
{ {
XLAT_ARG2, XLAT_ARG3, XLAT_ARG4, XLAT_ARG5, XLAT_BITMASK, XLAT_CLEAR, XLAT_ARG2, XLAT_ARG3, XLAT_ARG4, XLAT_ARG5, XLAT_BITMASK, XLAT_CLEAR,
XLAT_DEFINE, XLAT_ENUM, XLAT_FLAGS, XLAT_INCLUDE, XLAT_TAG, XLAT_DEFINE, XLAT_ENUM, XLAT_FLAGS, XLAT_INCLUDE, XLAT_TAG,
XLAT_NOBITMASK, XLAT_SECTOR, XLAT_TAG, XLAT_NOBITMASK, XLAT_SECTOR, XLAT_TAG, XLAT_MAXLINESPECIAL
}; };
int min = 0, max = sizeof(tokens)/sizeof(tokens[0]) - 1; int min = 0, max = countof(tokens) - 1;
while (min <= max) while (min <= max)
{ {

View file

@ -18,6 +18,7 @@ external_declaration ::= linetype_declaration.
external_declaration ::= boom_declaration. external_declaration ::= boom_declaration.
external_declaration ::= sector_declaration. external_declaration ::= sector_declaration.
external_declaration ::= sector_bitmask. external_declaration ::= sector_bitmask.
external_declaration ::= maxlinespecial_def.
external_declaration ::= NOP. external_declaration ::= NOP.
@ -452,6 +453,19 @@ list_val(A) ::= exp(B) COLON exp(C).
A.value = C; A.value = C;
} }
//==========================================================================
//
// max line special
//
//==========================================================================
maxlinespecial_def ::= MAXLINESPECIAL EQUALS exp(mx) SEMICOLON.
{
// Just kill all specials higher than the max.
// If the translator wants to redefine some later, just let it.s
SimpleLineTranslations.Resize(mx+1);
}
//========================================================================== //==========================================================================
// //
// sector types // sector types

17
wadsrc/xlat/doom_base.txt Normal file
View file

@ -0,0 +1,17 @@
include "xlat/doom.txt"
maxlinespecial = 272;
sector bitmask 0xffe0 clear;
sector 15 = 0;
sector 17 = 0;
sector 18 = 0;
sector 19 = 0;
sector 20 = 0;
sector 21 = 0;
sector 22 = 0;
sector 23 = 0;
sector 24 = 0;

View file

@ -0,0 +1,8 @@
include "xlat/heretic.txt"
maxlinespecial = 107;
sector bitmask 0xffc0 clear;
sector 17 = 0;

View file

@ -0,0 +1,14 @@
include "xlat/strife.txt"
maxlinespecial = 234;
sector bitmask 0xffe0 clear;
sector 19 = 0;
sector 20 = 0;
sector 21 = 0;
sector 22 = 0;
sector 23 = 0;
sector 24 = 0;

View file

@ -71,6 +71,9 @@ xlat/heretic.txt xlat/heretic.txt
xlat/strife.txt xlat/strife.txt xlat/strife.txt xlat/strife.txt
xlat/base.txt xlat/base.txt xlat/base.txt xlat/base.txt
xlat/defines.i xlat/defines.i xlat/defines.i xlat/defines.i
xlat/doom_base.txt xlat/doom_base.txt
xlat/heretic_base.txt xlat/heretic_base.txt
xlat/strife_base.txt xlat/strife_base.txt
======== ========