From 8d83f03138a0ed48ad05a0b5872bc41b73e6928f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 2 Feb 2019 01:14:51 +0100 Subject: [PATCH] - changed the linedef translator into a struct and reorganized its storage to allow having different ones at the same time. This was the last piece of data that couldn't be distinct for more than one level. --- src/CMakeLists.txt | 14 +-- src/fragglescript/t_load.cpp | 4 +- src/g_levellocals.h | 3 + src/{ => gamedata}/p_xlat.cpp | 44 ++++----- src/gamedata/umapinfo.cpp | 2 - src/{ => gamedata}/xlat/parse_xlat.cpp | 40 +++------ src/{ => gamedata/xlat}/parsecontext.cpp | 0 src/{ => gamedata/xlat}/parsecontext.h | 0 src/{ => gamedata}/xlat/xlat.h | 31 ++++--- src/{ => gamedata}/xlat/xlat_parser.y | 66 +++++++------- src/maploader/maploader.cpp | 5 +- src/maploader/udmf.cpp | 15 ++-- src/p_setup.h | 3 - src/utility/tflags.h | 109 +++++++++++++++++++++++ 14 files changed, 220 insertions(+), 116 deletions(-) rename src/{ => gamedata}/p_xlat.cpp (88%) rename src/{ => gamedata}/xlat/parse_xlat.cpp (81%) rename src/{ => gamedata/xlat}/parsecontext.cpp (100%) rename src/{ => gamedata/xlat}/parsecontext.h (100%) rename src/{ => gamedata}/xlat/xlat.h (76%) rename src/{ => gamedata}/xlat/xlat_parser.y (72%) create mode 100644 src/utility/tflags.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 602166fe5..b18165a50 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -597,8 +597,8 @@ else() endif() add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.h - COMMAND lemon -C${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/xlat/xlat_parser.y - DEPENDS lemon ${CMAKE_CURRENT_SOURCE_DIR}/xlat/xlat_parser.y ) + COMMAND lemon -C${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/gamedata/xlat/xlat_parser.y + DEPENDS lemon ${CMAKE_CURRENT_SOURCE_DIR}/gamedata/xlat/xlat_parser.y ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.c ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.h COMMAND lemon -C${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/scripting/zscript/zcc-parse.lemon @@ -653,6 +653,7 @@ file( GLOB HEADER_FILES gamedata/textures/hires/hqnx/*.h gamedata/textures/hires/hqnx_asm/*.h gamedata/textures/hires/xbr/*.h + gamedata/xlat/*.h intermission/*.h maploader/*.h menu/*.h @@ -683,7 +684,6 @@ file( GLOB HEADER_FILES sound/timidity/*.h sound/timiditypp/*.h sound/wildmidi/*.h - xlat/*.h rendering/swrenderer/*.h rendering/swrenderer/textures/*.h rendering/swrenderer/drawers/*.h @@ -794,7 +794,7 @@ set( NOT_COMPILED_SOURCE_FILES sc_man_scanner.h utility/sc_man_scanner.re g_statusbar/sbarinfo_commands.cpp - xlat/xlat_parser.y + gamedata/xlat/xlat_parser.y xlat_parser.c xlat_parser.h scripting/zscript/zcc-parse.lemon @@ -936,8 +936,6 @@ set (PCH_SOURCES p_tick.cpp p_usdf.cpp p_user.cpp - p_xlat.cpp - parsecontext.cpp r_utility.cpp r_sky.cpp r_videoscale.cpp @@ -1110,7 +1108,9 @@ set (PCH_SOURCES gamedata/textures/formats/tgatexture.cpp gamedata/textures/hires/hqresize.cpp gamedata/textures/hires/hirestex.cpp - xlat/parse_xlat.cpp + gamedata/p_xlat.cpp + gamedata/xlat/parse_xlat.cpp + gamedata/xlat/parsecontext.cpp fragglescript/t_func.cpp fragglescript/t_load.cpp fragglescript/t_oper.cpp diff --git a/src/fragglescript/t_load.cpp b/src/fragglescript/t_load.cpp index bcb4dadcf..7f5d8024f 100644 --- a/src/fragglescript/t_load.cpp +++ b/src/fragglescript/t_load.cpp @@ -294,9 +294,9 @@ void T_LoadScripts(FLevelLocals *Level, MapData *map) // the default translator is being used. // Custom translators will not be patched. if ((gameinfo.gametype == GAME_Doom || gameinfo.gametype == GAME_Heretic) && Level->info->Translator.IsEmpty() && - Level->maptype == MAPTYPE_DOOM && SimpleLineTranslations.Size() > 272 && SimpleLineTranslations[272 - 2*HasScripts].special == FS_Execute) + Level->maptype == MAPTYPE_DOOM && Level->Translator->SimpleLineTranslations.Size() > 272 && Level->Translator->SimpleLineTranslations[272 - 2*HasScripts].special == FS_Execute) { - std::swap(SimpleLineTranslations[270], SimpleLineTranslations[272]); + std::swap(Level->Translator->SimpleLineTranslations[270], Level->Translator->SimpleLineTranslations[272]); } } diff --git a/src/g_levellocals.h b/src/g_levellocals.h index e43b27445..0b854a797 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -95,6 +95,7 @@ struct FStrifeDialogueNode; class DAutomapBase; struct wbstartstruct_t; class DSectorMarker; +struct FTranslator; typedef TMap FDialogueIDMap; // maps dialogue IDs to dialogue array index (for ACS) typedef TMap FDialogueMap; // maps actor class names to dialogue array index @@ -127,6 +128,7 @@ struct FLevelLocals void FormatMapName(FString &mapname, const char *mapnamecolor); void ClearAllSubsectorLinks(); void TranslateLineDef (line_t *ld, maplinedef_t *mld, int lineindexforid = -1); + int TranslateSectorSpecial(int special); bool IsTIDUsed(int tid); int FindUniqueTID(int start_tid, int limit); int GetConversation(int conv_id); @@ -494,6 +496,7 @@ public: FString NextMap; // go here when using the regular exit FString NextSecretMap; // map to go to when used secret exit FString F1Pic; + FTranslator *Translator; EMapType maptype; FTagManager tagManager; FInterpolator interpolator; diff --git a/src/p_xlat.cpp b/src/gamedata/p_xlat.cpp similarity index 88% rename from src/p_xlat.cpp rename to src/gamedata/p_xlat.cpp index 963cff272..2ab3ebf12 100644 --- a/src/p_xlat.cpp +++ b/src/gamedata/p_xlat.cpp @@ -56,8 +56,11 @@ typedef enum PushMany, } triggertype_e; + void FLevelLocals::TranslateLineDef (line_t *ld, maplinedef_t *mld, int lineindexforid) { + auto translator = Translator; + uint32_t special = mld->special; short tag = mld->tag; uint32_t flags =mld->flags; @@ -68,16 +71,16 @@ void FLevelLocals::TranslateLineDef (line_t *ld, maplinedef_t *mld, int lineinde for(int i=0;i<16;i++) { - if ((flags & (1<LineFlagTranslations[i].ismask) { - flags1 &= LineFlagTranslations[i].newvalue; + flags1 &= translator->LineFlagTranslations[i].newvalue; } } for(int i=0;i<16;i++) { - if ((flags1 & (1<LineFlagTranslations[i].ismask) { - switch (LineFlagTranslations[i].newvalue) + switch (translator->LineFlagTranslations[i].newvalue) { case -1: passthrough = true; @@ -89,7 +92,7 @@ void FLevelLocals::TranslateLineDef (line_t *ld, maplinedef_t *mld, int lineinde ld->alpha = 0.25; break; default: - newflags |= LineFlagTranslations[i].newvalue; + newflags |= translator->LineFlagTranslations[i].newvalue; break; } } @@ -116,7 +119,7 @@ void FLevelLocals::TranslateLineDef (line_t *ld, maplinedef_t *mld, int lineinde } FLineTrans *linetrans = NULL; - if (special < SimpleLineTranslations.Size()) linetrans = &SimpleLineTranslations[special]; + if (special < translator->SimpleLineTranslations.Size()) linetrans = &translator->SimpleLineTranslations[special]; if (linetrans != NULL && linetrans->special != 0) { ld->special = linetrans->special; @@ -157,7 +160,7 @@ void FLevelLocals::TranslateLineDef (line_t *ld, maplinedef_t *mld, int lineinde break; case ARGOP_Expr: { - int *xnode = &XlatExpressions[arg]; + int *xnode = &translator->XlatExpressions[arg]; state.bIsConstant = true; XlatExprEval[*xnode](&ld->args[t], xnode, &state); } @@ -176,9 +179,9 @@ void FLevelLocals::TranslateLineDef (line_t *ld, maplinedef_t *mld, int lineinde return; } - for(int i=0;iNumBoomish;i++) { - FBoomTranslator *b = &Boomish[i]; + FBoomTranslator *b = &translator->Boomish[i]; if (special >= b->FirstLinetype && special <= b->LastLinetype) { @@ -290,32 +293,33 @@ void FLevelLocals::TranslateLineDef (line_t *ld, maplinedef_t *mld, int lineinde memset (ld->args, 0, sizeof(ld->args)); } -int P_TranslateSectorSpecial (int special) +int FLevelLocals::TranslateSectorSpecial (int special) { int mask = 0; + auto translator = Translator; - for(int i = SectorMasks.Size()-1; i>=0; i--) + for(int i = translator->SectorMasks.Size()-1; i>=0; i--) { - int newmask = special & SectorMasks[i].mask; + int newmask = special & translator->SectorMasks[i].mask; if (newmask) { special &= ~newmask; - if (SectorMasks[i].op == 1) - newmask <<= SectorMasks[i].shift; - else if (SectorMasks[i].op == -1) - newmask >>= SectorMasks[i].shift; - else if (SectorMasks[i].op == 0 && SectorMasks[i].shift == 1) + if (translator->SectorMasks[i].op == 1) + newmask <<= translator->SectorMasks[i].shift; + else if (translator->SectorMasks[i].op == -1) + newmask >>= translator->SectorMasks[i].shift; + else if (translator->SectorMasks[i].op == 0 && translator->SectorMasks[i].shift == 1) newmask = 0; mask |= newmask; } } - if ((unsigned)special < SectorTranslations.Size()) + if ((unsigned)special < translator->SectorTranslations.Size()) { - if (!SectorTranslations[special].bitmask_allowed && mask) + if (!translator->SectorTranslations[special].bitmask_allowed && mask) special = 0; else - special = SectorTranslations[special].newtype; + special = translator->SectorTranslations[special].newtype; } return special | mask; } diff --git a/src/gamedata/umapinfo.cpp b/src/gamedata/umapinfo.cpp index 6da8f3316..ac82ff8e2 100644 --- a/src/gamedata/umapinfo.cpp +++ b/src/gamedata/umapinfo.cpp @@ -325,8 +325,6 @@ static int ParseMapEntry(FScanner &scanner, UMapEntry *val) int ParseUMapInfo(int lumpnum) { - P_LoadTranslator(gameinfo.translator); - FScanner scanner(lumpnum); unsigned int i; diff --git a/src/xlat/parse_xlat.cpp b/src/gamedata/xlat/parse_xlat.cpp similarity index 81% rename from src/xlat/parse_xlat.cpp rename to src/gamedata/xlat/parse_xlat.cpp index 3e7f02d01..44771b00a 100644 --- a/src/xlat/parse_xlat.cpp +++ b/src/gamedata/xlat/parse_xlat.cpp @@ -51,14 +51,7 @@ enum DEFINE_TOKEN_TRANS(XLAT_) -static FString LastTranslator; -TAutoGrowArray SimpleLineTranslations; -TArray XlatExpressions; -FBoomTranslator Boomish[MAX_BOOMISH]; -int NumBoomish; -TAutoGrowArray SectorTranslations; -TArray SectorMasks; -FLineFlagTrans LineFlagTranslations[16]; +TMap translators; struct SpecialArgs @@ -102,9 +95,10 @@ struct ParseBoomArg struct XlatParseContext : public FParseContext { - XlatParseContext(void *parser, ParseFunc parse, int *tt) + XlatParseContext(void *parser, ParseFunc parse, int *tt, FTranslator *trans) : FParseContext(parser, parse, tt) { + Translator = trans; DefiningLineType = -1; } @@ -152,6 +146,7 @@ struct XlatParseContext : public FParseContext } int DefiningLineType; + FTranslator *Translator; }; #include "xlat_parser.c" @@ -163,36 +158,23 @@ struct XlatParseContext : public FParseContext // //========================================================================== -void P_ClearTranslator() +FTranslator *P_LoadTranslator(const char *lumpname) { - SimpleLineTranslations.Clear(); - XlatExpressions.Clear(); - NumBoomish = 0; - SectorTranslations.Clear(); - SectorMasks.Clear(); - memset(LineFlagTranslations, 0, sizeof(LineFlagTranslations)); - LastTranslator = ""; -} - -void P_LoadTranslator(const char *lumpname) -{ - // Only read the lump if it differs from the previous one. - if (LastTranslator.CompareNoCase(lumpname)) + FName fname = lumpname; + auto translator = &translators[fname]; + if (!translator->loaded) { - // Clear the old data before parsing the lump. - P_ClearTranslator(); - void *pParser = XlatParseAlloc(malloc); - XlatParseContext context(pParser, XlatParse, TokenTrans); - + XlatParseContext context(pParser, XlatParse, TokenTrans, translator); context.ParseLump(lumpname); FParseToken tok; tok.val=0; XlatParse(pParser, 0, tok, &context); XlatParseFree(pParser, free); - LastTranslator = lumpname; + translator->loaded = true; } + return translator; } diff --git a/src/parsecontext.cpp b/src/gamedata/xlat/parsecontext.cpp similarity index 100% rename from src/parsecontext.cpp rename to src/gamedata/xlat/parsecontext.cpp diff --git a/src/parsecontext.h b/src/gamedata/xlat/parsecontext.h similarity index 100% rename from src/parsecontext.h rename to src/gamedata/xlat/parsecontext.h diff --git a/src/xlat/xlat.h b/src/gamedata/xlat/xlat.h similarity index 76% rename from src/xlat/xlat.h rename to src/gamedata/xlat/xlat.h index cf5fc7089..f488704ff 100644 --- a/src/xlat/xlat.h +++ b/src/gamedata/xlat/xlat.h @@ -37,6 +37,10 @@ enum XEXP_COUNT }; +struct FXlatExprState; + +extern const int* (*XlatExprEval[XEXP_COUNT])(int *dest, const int *xnode, FXlatExprState *state); + struct FLineTrans { int special; @@ -76,9 +80,9 @@ struct FBoomArg struct FBoomTranslator { - uint16_t FirstLinetype; - uint16_t LastLinetype; - uint8_t NewSpecial; + uint16_t FirstLinetype = 0; + uint16_t LastLinetype = 0; + uint8_t NewSpecial = 0; TArray Args; } ; @@ -115,13 +119,18 @@ struct FXlatExprState }; -extern TAutoGrowArray SimpleLineTranslations; -extern TArray XlatExpressions; -extern FBoomTranslator Boomish[MAX_BOOMISH]; -extern int NumBoomish; -extern TAutoGrowArray SectorTranslations; -extern TArray SectorMasks; -extern FLineFlagTrans LineFlagTranslations[16]; -extern const int* (*XlatExprEval[XEXP_COUNT])(int *dest, const int *xnode, FXlatExprState *state); +struct FTranslator +{ + bool loaded = false; + TAutoGrowArray SimpleLineTranslations; + TArray XlatExpressions; + FBoomTranslator Boomish[MAX_BOOMISH]; + int NumBoomish = 0; + TAutoGrowArray SectorTranslations; + TArray SectorMasks; + FLineFlagTrans LineFlagTranslations[16] = {}; +}; + +FTranslator *P_LoadTranslator(const char *lumpname); #endif diff --git a/src/xlat/xlat_parser.y b/src/gamedata/xlat/xlat_parser.y similarity index 72% rename from src/xlat/xlat_parser.y rename to src/gamedata/xlat/xlat_parser.y index e92107f7b..6c6575ab2 100644 --- a/src/xlat/xlat_parser.y +++ b/src/gamedata/xlat/xlat_parser.y @@ -130,7 +130,7 @@ linetype_exp(Z) ::= expr(A). linetype_declaration ::= linetype_exp(linetype) EQUALS expr(flags) COMMA expr(special) LPAREN special_args(arg) RPAREN. { - SimpleLineTranslations.SetVal(linetype, + static_cast(context)->Translator->SimpleLineTranslations.SetVal(linetype, FLineTrans(special&0xffff, flags+arg.addflags, arg.args[0], arg.args[1], arg.args[2], arg.args[3], arg.args[4])); static_cast(context)->DefiningLineType = -1; } @@ -142,17 +142,17 @@ linetype_declaration ::= linetype_exp EQUALS expr COMMA SYM(S) LPAREN special_ar } %type exp_with_tag {int} -exp_with_tag(A) ::= NUM(B). { XlatExpressions.Push(B.val); A = XlatExpressions.Push(XEXP_Const); } -exp_with_tag(A) ::= TAG. { A = XlatExpressions.Push(XEXP_Tag); } -exp_with_tag(A) ::= exp_with_tag PLUS exp_with_tag. { A = XlatExpressions.Push(XEXP_Add); } -exp_with_tag(A) ::= exp_with_tag MINUS exp_with_tag. { A = XlatExpressions.Push(XEXP_Sub); } -exp_with_tag(A) ::= exp_with_tag MULTIPLY exp_with_tag. { A = XlatExpressions.Push(XEXP_Mul); } -exp_with_tag(A) ::= exp_with_tag DIVIDE exp_with_tag. { A = XlatExpressions.Push(XEXP_Div); } -exp_with_tag(A) ::= exp_with_tag MODULUS exp_with_tag. { A = XlatExpressions.Push(XEXP_Mod); } -exp_with_tag(A) ::= exp_with_tag OR exp_with_tag. { A = XlatExpressions.Push(XEXP_Or); } -exp_with_tag(A) ::= exp_with_tag AND exp_with_tag. { A = XlatExpressions.Push(XEXP_And); } -exp_with_tag(A) ::= exp_with_tag XOR exp_with_tag. { A = XlatExpressions.Push(XEXP_Xor); } -exp_with_tag(A) ::= MINUS exp_with_tag. [NEG] { A = XlatExpressions.Push(XEXP_Neg); } +exp_with_tag(A) ::= NUM(B). { static_cast(context)->Translator->XlatExpressions.Push(B.val); A = static_cast(context)->Translator->XlatExpressions.Push(XEXP_Const); } +exp_with_tag(A) ::= TAG. { A = static_cast(context)->Translator->XlatExpressions.Push(XEXP_Tag); } +exp_with_tag(A) ::= exp_with_tag PLUS exp_with_tag. { A = static_cast(context)->Translator->XlatExpressions.Push(XEXP_Add); } +exp_with_tag(A) ::= exp_with_tag MINUS exp_with_tag. { A = static_cast(context)->Translator->XlatExpressions.Push(XEXP_Sub); } +exp_with_tag(A) ::= exp_with_tag MULTIPLY exp_with_tag. { A = static_cast(context)->Translator->XlatExpressions.Push(XEXP_Mul); } +exp_with_tag(A) ::= exp_with_tag DIVIDE exp_with_tag. { A = static_cast(context)->Translator->XlatExpressions.Push(XEXP_Div); } +exp_with_tag(A) ::= exp_with_tag MODULUS exp_with_tag. { A = static_cast(context)->Translator->XlatExpressions.Push(XEXP_Mod); } +exp_with_tag(A) ::= exp_with_tag OR exp_with_tag. { A = static_cast(context)->Translator->XlatExpressions.Push(XEXP_Or); } +exp_with_tag(A) ::= exp_with_tag AND exp_with_tag. { A = static_cast(context)->Translator->XlatExpressions.Push(XEXP_And); } +exp_with_tag(A) ::= exp_with_tag XOR exp_with_tag. { A = static_cast(context)->Translator->XlatExpressions.Push(XEXP_Xor); } +exp_with_tag(A) ::= MINUS exp_with_tag. [NEG] { A = static_cast(context)->Translator->XlatExpressions.Push(XEXP_Neg); } exp_with_tag(A) ::= LPAREN exp_with_tag(B) RPAREN. { A = B; } @@ -160,11 +160,11 @@ exp_with_tag(A) ::= LPAREN exp_with_tag(B) RPAREN. { A = B; } special_arg(Z) ::= exp_with_tag(A). { - if (XlatExpressions[A] == XEXP_Tag) + if (static_cast(context)->Translator->XlatExpressions[A] == XEXP_Tag) { // Store tags directly Z.arg = 0; Z.argop = ARGOP_Tag; - XlatExpressions.Delete(A); + static_cast(context)->Translator->XlatExpressions.Delete(A); } else { // Try and evaluate it. If it's a constant, store it and erase the @@ -178,15 +178,15 @@ special_arg(Z) ::= exp_with_tag(A). state.linetype = static_cast(context)->DefiningLineType; state.tag = 0; state.bIsConstant = true; - xnode = &XlatExpressions[A]; + xnode = &static_cast(context)->Translator->XlatExpressions[A]; endpt = XlatExprEval[*xnode](&val, xnode, &state); if (state.bIsConstant) { Z.arg = val; Z.argop = ARGOP_Const; endpt++; - assert(endpt >= &XlatExpressions[0]); - XlatExpressions.Resize((unsigned)(endpt - &XlatExpressions[0])); + assert(endpt >= &static_cast(context)->Translator->XlatExpressions[0]); + static_cast(context)->Translator->XlatExpressions.Resize((unsigned)(endpt - &static_cast(context)->Translator->XlatExpressions[0])); } else { @@ -257,7 +257,7 @@ boom_declaration ::= LBRACKET expr(special) RBRACKET LPAREN expr(firsttype) COMM int i; MoreLines *probe; - if (NumBoomish == MAX_BOOMISH) + if (static_cast(context)->Translator->NumBoomish == MAX_BOOMISH) { MoreLines *probe = stores; @@ -271,18 +271,18 @@ boom_declaration ::= LBRACKET expr(special) RBRACKET LPAREN expr(firsttype) COMM } else { - Boomish[NumBoomish].FirstLinetype = firsttype; - Boomish[NumBoomish].LastLinetype = lasttype; - Boomish[NumBoomish].NewSpecial = special; + static_cast(context)->Translator->Boomish[static_cast(context)->Translator->NumBoomish].FirstLinetype = firsttype; + static_cast(context)->Translator->Boomish[static_cast(context)->Translator->NumBoomish].LastLinetype = lasttype; + static_cast(context)->Translator->Boomish[static_cast(context)->Translator->NumBoomish].NewSpecial = special; for (i = 0, probe = stores; probe != NULL; i++) { MoreLines *next = probe->next; - Boomish[NumBoomish].Args.Push(probe->arg); + static_cast(context)->Translator->Boomish[static_cast(context)->Translator->NumBoomish].Args.Push(probe->arg); delete probe; probe = next; } - NumBoomish++; + static_cast(context)->Translator->NumBoomish++; } } @@ -379,7 +379,7 @@ maxlinespecial_def ::= MAXLINESPECIAL EQUALS expr(mx) SEMICOLON. { // Just kill all specials higher than the max. // If the translator wants to redefine some later, just let it. - SimpleLineTranslations.Resize(mx+1); + static_cast(context)->Translator->SimpleLineTranslations.Resize(mx+1); } //========================================================================== @@ -393,7 +393,7 @@ maxlinespecial_def ::= MAXLINESPECIAL EQUALS expr(mx) SEMICOLON. sector_declaration ::= SECTOR expr(from) EQUALS expr(to) SEMICOLON. { FSectorTrans tr(to, true); - SectorTranslations.SetVal(from, tr); + static_cast(context)->Translator->SectorTranslations.SetVal(from, tr); } sector_declaration ::= SECTOR expr EQUALS SYM(sy) SEMICOLON. @@ -404,25 +404,25 @@ sector_declaration ::= SECTOR expr EQUALS SYM(sy) SEMICOLON. sector_declaration ::= SECTOR expr(from) EQUALS expr(to) NOBITMASK SEMICOLON. { FSectorTrans tr(to, false); - SectorTranslations.SetVal(from, tr); + static_cast(context)->Translator->SectorTranslations.SetVal(from, tr); } sector_bitmask ::= SECTOR BITMASK expr(mask) sector_op(op) expr(shift) SEMICOLON. { FSectorMask sm = { mask, op, shift}; - SectorMasks.Push(sm); + static_cast(context)->Translator->SectorMasks.Push(sm); } sector_bitmask ::= SECTOR BITMASK expr(mask) SEMICOLON. { FSectorMask sm = { mask, 0, 0}; - SectorMasks.Push(sm); + static_cast(context)->Translator->SectorMasks.Push(sm); } sector_bitmask ::= SECTOR BITMASK expr(mask) CLEAR SEMICOLON. { FSectorMask sm = { mask, 0, 1}; - SectorMasks.Push(sm); + static_cast(context)->Translator->SectorMasks.Push(sm); } sector_op(A) ::= LSHASSIGN. { A = 1; } @@ -434,8 +434,8 @@ lineflag_declaration ::= LINEFLAG expr(from) EQUALS expr(to) SEMICOLON. { if (from >= 0 && from < 16) { - LineFlagTranslations[from].newvalue = to; - LineFlagTranslations[from].ismask = false; + static_cast(context)->Translator->LineFlagTranslations[from].newvalue = to; + static_cast(context)->Translator->LineFlagTranslations[from].ismask = false; } } @@ -443,7 +443,7 @@ lineflag_declaration ::= LINEFLAG expr(from) AND expr(mask) SEMICOLON. { if (from >= 0 && from < 16) { - LineFlagTranslations[from].newvalue = mask; - LineFlagTranslations[from].ismask = true; + static_cast(context)->Translator->LineFlagTranslations[from].newvalue = mask; + static_cast(context)->Translator->LineFlagTranslations[from].ismask = true; } } \ No newline at end of file diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index de52b0424..91ddaca49 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -78,6 +78,7 @@ #include "fragglescript/t_fs.h" #include "swrenderer/r_swrenderer.h" #include "hwrenderer/data/flatvertices.h" +#include "xlat/xlat.h" enum { @@ -1080,7 +1081,7 @@ void MapLoader::LoadSectors (MapData *map, FMissingTextureTracker &missingtex) if (map->HasBehavior) ss->special = LittleShort(ms->special); else // [RH] Translate to new sector special - ss->special = P_TranslateSectorSpecial (LittleShort(ms->special)); + ss->special = Level->TranslateSectorSpecial (LittleShort(ms->special)); Level->tagManager.AddSectorTag(i, LittleShort(ms->tag)); ss->thinglist = nullptr; ss->touching_thinglist = nullptr; // phares 3/14/98 @@ -2977,7 +2978,7 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position) translator = gameinfo.translator.GetChars(); } } - P_LoadTranslator(translator); + Level->Translator = P_LoadTranslator(translator); Level->maptype = MAPTYPE_DOOM; } if (map->isText) diff --git a/src/maploader/udmf.cpp b/src/maploader/udmf.cpp index a35f555b1..3a86bfcdf 100644 --- a/src/maploader/udmf.cpp +++ b/src/maploader/udmf.cpp @@ -49,6 +49,7 @@ #include "g_levellocals.h" #include "info.h" #include "vm.h" +#include "xlat/xlat.h" #include "maploader.h" //=========================================================================== @@ -1491,7 +1492,7 @@ public: case NAME_Special: sec->special = (short)CheckInt(key); - if (isTranslated) sec->special = P_TranslateSectorSpecial(sec->special); + if (isTranslated) sec->special = Level->TranslateSectorSpecial(sec->special); else if (namespc == NAME_Hexen) { if (sec->special < 0 || sec->special > 140 || !HexenSectorSpecialOk[sec->special]) @@ -2147,19 +2148,19 @@ public: break; case NAME_Doom: namespace_bits = Dm; - P_LoadTranslator("xlat/doom_base.txt"); + Level->Translator = P_LoadTranslator("xlat/doom_base.txt"); Level->flags2 |= LEVEL2_DUMMYSWITCHES; floordrop = true; break; case NAME_Heretic: namespace_bits = Ht; - P_LoadTranslator("xlat/heretic_base.txt"); + Level->Translator = P_LoadTranslator("xlat/heretic_base.txt"); Level->flags2 |= LEVEL2_DUMMYSWITCHES; floordrop = true; break; case NAME_Strife: namespace_bits = St; - P_LoadTranslator("xlat/strife_base.txt"); + Level->Translator = P_LoadTranslator("xlat/strife_base.txt"); Level->flags2 |= LEVEL2_DUMMYSWITCHES|LEVEL2_RAILINGHACK; floordrop = true; break; @@ -2171,15 +2172,15 @@ public: case GAME_Doom: case GAME_Chex: namespace_bits = Dm; - P_LoadTranslator("xlat/doom_base.txt"); + Level->Translator = P_LoadTranslator("xlat/doom_base.txt"); break; case GAME_Heretic: namespace_bits = Ht; - P_LoadTranslator("xlat/heretic_base.txt"); + Level->Translator = P_LoadTranslator("xlat/heretic_base.txt"); break; case GAME_Strife: namespace_bits = St; - P_LoadTranslator("xlat/strife_base.txt"); + Level->Translator = P_LoadTranslator("xlat/strife_base.txt"); break; case GAME_Hexen: namespace_bits = Hx; diff --git a/src/p_setup.h b/src/p_setup.h index 12bffa6fb..0cae8124c 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -150,9 +150,6 @@ void P_Init (void); struct line_t; struct maplinedef_t; -void P_LoadTranslator(const char *lumpname); -int P_TranslateSectorSpecial (int); - int GetUDMFInt(FLevelLocals *Level, int type, int index, FName key); double GetUDMFFloat(FLevelLocals *Level, int type, int index, FName key); FString GetUDMFString(FLevelLocals *Level, int type, int index, FName key); diff --git a/src/utility/tflags.h b/src/utility/tflags.h new file mode 100644 index 000000000..18c2becaf --- /dev/null +++ b/src/utility/tflags.h @@ -0,0 +1,109 @@ +/* +** tflags.h +** +**--------------------------------------------------------------------------- +** Copyright 2015 Teemu Piippo +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#pragma once +#include "doomtype.h" + +/* + * TFlags + * + * A Qt-inspired type-safe flagset type. + * + * T is the enum type of individual flags, + * TT is the underlying integer type used (defaults to uint32_t) + */ +template +class TFlags +{ + struct ZeroDummy {}; + +public: + typedef TFlags Self; + typedef T EnumType; + typedef TT IntType; + + TFlags() = default; + TFlags(const Self& other) = default; + TFlags (T value) : Value (static_cast (value)) {} + + // This allows initializing the flagset with 0, as 0 implicitly converts into a null pointer. + TFlags (ZeroDummy*) : Value (0) {} + + // Relation operators + Self operator| (Self other) const { return Self::FromInt (Value | other.GetValue()); } + Self operator& (Self other) const { return Self::FromInt (Value & other.GetValue()); } + Self operator^ (Self other) const { return Self::FromInt (Value ^ other.GetValue()); } + Self operator| (T value) const { return Self::FromInt (Value | value); } + Self operator& (T value) const { return Self::FromInt (Value & value); } + Self operator^ (T value) const { return Self::FromInt (Value ^ value); } + Self operator~() const { return Self::FromInt (~Value); } + + // Assignment operators + Self& operator= (Self other) { Value = other.GetValue(); return *this; } + Self& operator|= (Self other) { Value |= other.GetValue(); return *this; } + Self& operator&= (Self other) { Value &= other.GetValue(); return *this; } + Self& operator^= (Self other) { Value ^= other.GetValue(); return *this; } + Self& operator= (T value) { Value = value; return *this; } + Self& operator|= (T value) { Value |= value; return *this; } + Self& operator&= (T value) { Value &= value; return *this; } + Self& operator^= (T value) { Value ^= value; return *this; } + + // Access the value of the flagset + TT GetValue() const { return Value; } + operator TT() const { return Value; } + + // Set the value of the flagset manually with an integer. + // Please think twice before using this. + static Self FromInt (TT value) { return Self (static_cast (value)); } + +private: + template Self operator| (X value) const { return Self::FromInt (Value | value); } + template Self operator& (X value) const { return Self::FromInt (Value & value); } + template Self operator^ (X value) const { return Self::FromInt (Value ^ value); } + +public: // to be removed. + TT Value; +}; + +/* + * Additional operators for TFlags types. + */ +#define DEFINE_TFLAGS_OPERATORS(T) \ +inline T operator| (T::EnumType a, T::EnumType b) { return T::FromInt (T::IntType (a) | T::IntType (b)); } \ +inline T operator& (T::EnumType a, T::EnumType b) { return T::FromInt (T::IntType (a) & T::IntType (b)); } \ +inline T operator^ (T::EnumType a, T::EnumType b) { return T::FromInt (T::IntType (a) ^ T::IntType (b)); } \ +inline T operator| (T::EnumType a, T b) { return T::FromInt (T::IntType (a) | T::IntType (b)); } \ +inline T operator& (T::EnumType a, T b) { return T::FromInt (T::IntType (a) & T::IntType (b)); } \ +inline T operator^ (T::EnumType a, T b) { return T::FromInt (T::IntType (a) ^ T::IntType (b)); } \ +inline T operator~ (T::EnumType a) { return T::FromInt (~T::IntType (a)); } +