From 6f92efc72cb87baee5550de42a2b0c489774f704 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 12 Oct 2016 12:43:26 +0200 Subject: [PATCH 01/23] - renamed thingdef_codeptr.cpp and moved it out of thingdef/. Ultimately, thingdef should only contain code that is directly related to the DECORATE parser, but that's not the case with this file. It's only function definitions which get used during gameplay and will also be accessed by ZScript. The change is intentionally on master so that pull requests can adjust to it now instead of creating conflicts later. --- src/CMakeLists.txt | 2 +- src/{thingdef/thingdef_codeptr.cpp => p_actionfunctions.cpp} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/{thingdef/thingdef_codeptr.cpp => p_actionfunctions.cpp} (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 03299bb0a..ebfac3050 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1090,6 +1090,7 @@ set (PCH_SOURCES p_3dfloors.cpp p_3dmidtex.cpp p_acs.cpp + p_actionfunctions.cpp p_buildmap.cpp p_ceiling.cpp p_conversation.cpp @@ -1227,7 +1228,6 @@ set (PCH_SOURCES textures/warptexture.cpp thingdef/olddecorations.cpp thingdef/thingdef.cpp - thingdef/thingdef_codeptr.cpp thingdef/thingdef_data.cpp thingdef/thingdef_exp.cpp thingdef/thingdef_expression.cpp diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/p_actionfunctions.cpp similarity index 100% rename from src/thingdef/thingdef_codeptr.cpp rename to src/p_actionfunctions.cpp From de56be6c01bdb2747b93a5072591f2af29363f2d Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Thu, 13 Oct 2016 21:41:54 -0500 Subject: [PATCH 02/23] Lemon update 2016-04-29 11:28:35 on branch trunk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit — Lemon bug fix: Do not merge action routines unless their destructors are also identical. Problem and suggested fix reported on the mailing list by Kelvin Sherlock. (user: drh) --- tools/lemon/lemon.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index 546cf515e..c796f4f12 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -4404,7 +4404,8 @@ void ReportTable( writeRuleText(out, rp); fprintf(out," */\n"); lineno++; for(rp2=rp->next; rp2; rp2=rp2->next){ - if( rp2->code==rp->code ){ + if( rp2->code==rp->code && rp2->codePrefix==rp->codePrefix + && rp2->codeSuffix == rp->codeSuffix ){ fprintf(out," case %d: /*",rp2->iRule); writeRuleText(out, rp2); fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp2->iRule); lineno++; @@ -4413,7 +4414,7 @@ void ReportTable( } emit_code(out,rp,lemp,&lineno); fprintf(out," break;\n"); lineno++; - rp->code = 0; + rp->code = 0; } /* Finally, output the default: rule. We choose as the default: all ** empty actions. */ From 45d441f103160e3a9f326b97d3b2ff23392aa7b2 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Thu, 13 Oct 2016 21:48:29 -0500 Subject: [PATCH 03/23] Lemon update 2016-04-29 11:28:35 on branch trunk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit — Lemon bug fix: Do not merge action routines unless their destructors are also identical. Problem and suggested fix reported on the mailing list by Kelvin Sherlock. (user: drh) --- tools/lemon/lemon.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index c796f4f12..56364f897 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -3559,10 +3559,7 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){ rp->line = rp->ruleline; } - if( rp->lhsalias==0 ){ - /* There is no LHS value symbol. */ - lhsdirect = 1; - }else if( rp->nrhs==0 ){ + if( rp->nrhs==0 ){ /* If there are no RHS symbols, then writing directly to the LHS is ok */ lhsdirect = 1; }else if( rp->rhsalias[0]==0 ){ @@ -3575,6 +3572,9 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){ rp->rhs[0]->index,1-rp->nrhs,0); rp->codePrefix = Strsafe(append_str(0,0,0,0,0)); } + }else if( rp->lhsalias==0 ){ + /* There is no LHS value symbol. */ + lhsdirect = 1; }else if( strcmp(rp->lhsalias,rp->rhsalias[0])==0 ){ /* The LHS symbol and the left-most RHS symbol are the same, so ** direct writing is allowed */ @@ -3717,7 +3717,7 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){ /* Suffix code generation complete */ cp = append_str(0,0,0,0,0); - if( cp ) rp->codeSuffix = Strsafe(cp); + if( cp && cp[0] ) rp->codeSuffix = Strsafe(cp); return rc; } @@ -4399,7 +4399,14 @@ void ReportTable( for(rp=lemp->rule; rp; rp=rp->next){ struct rule *rp2; /* Other rules with the same action */ if( rp->code==0 ) continue; - if( rp->code[0]=='\n' && rp->code[1]==0 ) continue; /* Will be default: */ + if( rp->code[0]=='\n' + && rp->code[1]==0 + && rp->codePrefix==0 + && rp->codeSuffix==0 + ){ + /* No actions, so this will be part of the "default:" rule */ + continue; + } fprintf(out," case %d: /* ",rp->iRule); writeRuleText(out, rp); fprintf(out," */\n"); lineno++; @@ -4422,6 +4429,8 @@ void ReportTable( for(rp=lemp->rule; rp; rp=rp->next){ if( rp->code==0 ) continue; assert( rp->code[0]=='\n' && rp->code[1]==0 ); + assert( rp->codePrefix==0 ); + assert( rp->codeSuffix==0 ); fprintf(out," /* (%d) ", rp->iRule); writeRuleText(out, rp); fprintf(out," */ yytestcase(yyruleno==%d);\n", rp->iRule); lineno++; From 0d67d107abb6d7de0a4305c18f506609cd925bb8 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Thu, 13 Oct 2016 22:07:01 -0500 Subject: [PATCH 04/23] Lemon update 2016-05-23 14:24:31 on branch trunk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit — Fix comment typos and improve clarity of presention in Lemon. The output should be identical. (user: drh) --- tools/lemon/lemon.c | 51 ++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index 56364f897..27487b160 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -192,6 +192,8 @@ struct rule { const char *code; /* The code executed when this rule is reduced */ const char *codePrefix; /* Setup code before code[] above */ const char *codeSuffix; /* Breakdown code after code[] above */ + int noCode; /* True if this rule has no associated C code */ + int codeEmitted; /* True if the code has been emitted already */ struct symbol *precsym; /* Precedence symbol for this rule */ int index; /* An index number for this rule */ int iRule; /* Rule number as used in the generated tables */ @@ -253,7 +255,7 @@ struct state { struct config *bp; /* The basis configurations for this state */ struct config *cfp; /* All configurations in this set */ int statenum; /* Sequential number for this state */ - struct action *ap; /* Array of actions for this state */ + struct action *ap; /* List of actions for this state */ int nTknAct, nNtAct; /* Number of actions on terminals and nonterminals */ int iTknOfst, iNtOfst; /* yy_action[] offset for terminals and nonterms */ int iDfltReduce; /* Default action is to REDUCE by this rule */ @@ -1483,7 +1485,7 @@ static void handle_C_option(char *z){ } } -/* Merge together to lists of rules order by rule.iRule */ +/* Merge together to lists of rules ordered by rule.iRule */ static struct rule *Rule_merge(struct rule *pA, struct rule *pB){ struct rule *pFirst = 0; struct rule **ppPrev = &pFirst; @@ -1627,7 +1629,10 @@ int main(int argc, char **argv) for(i=1; ISUPPER(lem.symbols[i]->name[0]); i++); lem.nterminal = i; - /* Assign sequential rule numbers */ + /* Assign sequential rule numbers. Start with 0. Put rules that have no + ** reduce action C-code associated with them last, so that the switch() + ** statement that selects reduction actions will have a smaller jump table. + */ for(i=0, rp=lem.rule; rp; rp=rp->next){ rp->iRule = rp->code ? i++ : -1; } @@ -2179,7 +2184,7 @@ static void parseonetoken(struct pstate *psp) "There is no prior rule upon which to attach the code \ fragment which begins on this line."); psp->errorcnt++; - }else if( psp->prevrule->code!=0 ){ + }else if( psp->prevrule->code!=0 ){ ErrorMsg(psp->filename,psp->tokenlineno, "Code fragment beginning on this line is not the first \ to follow the previous rule."); @@ -2187,7 +2192,8 @@ to follow the previous rule."); }else{ psp->prevrule->line = psp->tokenlineno; psp->prevrule->code = &x[1]; - } + psp->prevrule->noCode = 0; + } }else if( x[0]=='[' ){ psp->state = PRECEDENCE_MARK_1; }else{ @@ -2293,6 +2299,7 @@ to follow the previous rule."); rp->lhsalias = psp->lhsalias; rp->nrhs = psp->nrhs; rp->code = 0; + rp->noCode = 1; rp->precsym = 0; rp->index = psp->gp->nrule++; rp->nextlhs = rp->lhs->rule; @@ -3531,9 +3538,8 @@ PRIVATE char *append_str(const char *zText, int n, int p1, int p2, int bNoSubst) } /* -** zCode is a string that is the action associated with a rule. Expand -** the symbols in this string so that the refer to elements of the parser -** stack. +** Write and transform the rp->code string so that symbols are expanded. +** Populate the rp->codePrefix and rp->codeSuffix strings, as appropriate. ** ** Return 1 if the expanded code requires that "yylhsminor" local variable ** to be defined. @@ -3557,6 +3563,9 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){ static char newlinestr[2] = { '\n', '\0' }; rp->code = newlinestr; rp->line = rp->ruleline; + rp->noCode = 1; + }else{ + rp->noCode = 0; } if( rp->nrhs==0 ){ @@ -3571,6 +3580,7 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){ append_str(" yy_destructor(yypParser,%d,&yymsp[%d].minor);\n", 0, rp->rhs[0]->index,1-rp->nrhs,0); rp->codePrefix = Strsafe(append_str(0,0,0,0,0)); + rp->noCode = 0; } }else if( rp->lhsalias==0 ){ /* There is no LHS value symbol. */ @@ -3717,7 +3727,10 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){ /* Suffix code generation complete */ cp = append_str(0,0,0,0,0); - if( cp && cp[0] ) rp->codeSuffix = Strsafe(cp); + if( cp && cp[0] ){ + rp->codeSuffix = Strsafe(cp); + rp->noCode = 0; + } return rc; } @@ -4398,13 +4411,9 @@ void ReportTable( /* First output rules other than the default: rule */ for(rp=lemp->rule; rp; rp=rp->next){ struct rule *rp2; /* Other rules with the same action */ - if( rp->code==0 ) continue; - if( rp->code[0]=='\n' - && rp->code[1]==0 - && rp->codePrefix==0 - && rp->codeSuffix==0 - ){ - /* No actions, so this will be part of the "default:" rule */ + if( rp->codeEmitted ) continue; + if( rp->noCode ){ + /* No C code actions, so this will be part of the "default:" rule */ continue; } fprintf(out," case %d: /* ",rp->iRule); @@ -4416,21 +4425,19 @@ void ReportTable( fprintf(out," case %d: /*",rp2->iRule); writeRuleText(out, rp2); fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp2->iRule); lineno++; - rp2->code = 0; + rp2->codeEmitted = 1; } } emit_code(out,rp,lemp,&lineno); fprintf(out," break;\n"); lineno++; - rp->code = 0; + rp->codeEmitted = 1; } /* Finally, output the default: rule. We choose as the default: all ** empty actions. */ fprintf(out," default:\n"); lineno++; for(rp=lemp->rule; rp; rp=rp->next){ - if( rp->code==0 ) continue; - assert( rp->code[0]=='\n' && rp->code[1]==0 ); - assert( rp->codePrefix==0 ); - assert( rp->codeSuffix==0 ); + if( rp->codeEmitted ) continue; + assert( rp->noCode ); fprintf(out," /* (%d) ", rp->iRule); writeRuleText(out, rp); fprintf(out," */ yytestcase(yyruleno==%d);\n", rp->iRule); lineno++; From 64bd551d203c4f302ecb933a3773a282b01f4716 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Thu, 13 Oct 2016 22:09:13 -0500 Subject: [PATCH 05/23] Lemon update 2016-05-23 14:24:31 on branch trunk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit — Fix comment typos and improve clarity of presention in Lemon. The output should be identical. (user: drh) --- tools/lemon/lemon.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index 27487b160..9994b940f 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -245,6 +245,7 @@ struct action { struct state *stp; /* The new state, if a shift */ struct rule *rp; /* The rule, if a reduce */ } x; + struct symbol *spOpt; /* SHIFTREDUCE optimization to this symbol */ struct action *next; /* Next action for this state */ struct action *collide; /* Next action with the same hash */ }; @@ -435,6 +436,7 @@ void Action_add( *app = newaction; newaction->type = type; newaction->sp = sp; + newaction->spOpt = 0; if( type==SHIFT ){ newaction->x.stp = (struct state *)arg; }else{ @@ -3160,6 +3162,9 @@ int PrintAction( result = 0; break; } + if( result && ap->spOpt ){ + fprintf(fp," /* because %s==%s */", ap->sp->name, ap->spOpt->name); + } return result; } @@ -4513,7 +4518,7 @@ void ReportHeader(struct lemon *lemp) void CompressTables(struct lemon *lemp) { struct state *stp; - struct action *ap, *ap2; + struct action *ap, *ap2, *nextap; struct rule *rp, *rp2, *rbest; int nbest, n; int i; @@ -4590,6 +4595,36 @@ void CompressTables(struct lemon *lemp) } } } + + /* If a SHIFTREDUCE action specifies a rule that has a single RHS term + ** (meaning that the SHIFTREDUCE will land back in the state where it + ** started) and if there is no C-code associated with the reduce action, + ** then we can go ahead and convert the action to be the same as the + ** action for the RHS of the rule. + */ + for(i=0; instate; i++){ + stp = lemp->sorted[i]; + for(ap=stp->ap; ap; ap=nextap){ + nextap = ap->next; + if( ap->type!=SHIFTREDUCE ) continue; + rp = ap->x.rp; + if( rp->noCode==0 ) continue; + if( rp->nrhs!=1 ) continue; +#if 1 + /* Only apply this optimization to non-terminals. It would be OK to + ** apply it to terminal symbols too, but that makes the parser tables + ** larger. */ + if( ap->sp->indexnterminal ) continue; +#endif + /* If we reach this point, it means the optimization can be applied */ + nextap = ap; + for(ap2=stp->ap; ap2 && (ap2==ap || ap2->sp!=rp->lhs); ap2=ap2->next){} + assert( ap2!=0 ); + ap->spOpt = ap2->sp; + ap->type = ap2->type; + ap->x = ap2->x; + } + } } From 96afce241d6bc08cfdb0018ea6e5f0c23e8ba5c8 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Thu, 13 Oct 2016 22:18:20 -0500 Subject: [PATCH 06/23] Lemon update 2016-05-24 18:55:08 on branch trunk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit — Enhance Lemon and the parser template so that it can once again build parsers that have no unreachable branches. (user: drh) --- tools/lemon/lemon.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index 9994b940f..a1453716a 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -198,6 +198,7 @@ struct rule { int index; /* An index number for this rule */ int iRule; /* Rule number as used in the generated tables */ Boolean canReduce; /* True if this rule is ever reduced */ + Boolean doesReduce; /* Reduce actions occur after optimization */ struct rule *nextlhs; /* Next rule with the same LHS */ struct rule *next; /* Next rule in the global list */ }; @@ -4154,6 +4155,19 @@ void ReportTable( } free(ax); + /* Mark rules that are actually used for reduce actions after all + ** optimizations have been applied + */ + for(rp=lemp->rule; rp; rp=rp->next) rp->doesReduce = LEMON_FALSE; + for(i=0; inxstate; i++){ + struct action *ap; + for(ap=lemp->sorted[i]->ap; ap; ap=ap->next){ + if( ap->type==REDUCE || ap->type==SHIFTREDUCE ){ + ap->x.rp->doesReduce = i; + } + } + } + /* Finish rendering the constants now that the action table has ** been computed */ fprintf(out,"#define YYNSTATE %d\n",lemp->nxstate); lineno++; @@ -4445,7 +4459,12 @@ void ReportTable( assert( rp->noCode ); fprintf(out," /* (%d) ", rp->iRule); writeRuleText(out, rp); - fprintf(out," */ yytestcase(yyruleno==%d);\n", rp->iRule); lineno++; + if( rp->doesReduce ){ + fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->iRule); lineno++; + }else{ + fprintf(out, " (OPTIMIZED OUT) */ assert(yyruleno!=%d);\n", + rp->iRule); lineno++; + } } fprintf(out," break;\n"); lineno++; tplt_xfer(lemp->name,in,out,&lineno); From 3b1a04888506adf9b97424d9e31c185c51873798 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Thu, 13 Oct 2016 22:22:04 -0500 Subject: [PATCH 07/23] Lemon update 2016-05-24 18:55:08 on branch trunk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit — Enhance Lemon and the parser template so that it can once again build parsers that have no unreachable branches. (user: drh) --- tools/lemon/lemon.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index a1453716a..1e673be8a 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -4233,20 +4233,21 @@ void ReportTable( fprintf(out, "};\n"); lineno++; /* Output the yy_shift_ofst[] table */ - fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", mnTknOfst-1); lineno++; n = lemp->nxstate; while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--; - fprintf(out, "#define YY_SHIFT_COUNT (%d)\n", n-1); lineno++; - fprintf(out, "#define YY_SHIFT_MIN (%d)\n", mnTknOfst); lineno++; - fprintf(out, "#define YY_SHIFT_MAX (%d)\n", mxTknOfst); lineno++; + fprintf(out, "#define YY_SHIFT_USE_DFLT (%d)\n", lemp->nactiontab); lineno++; + fprintf(out, "#define YY_SHIFT_COUNT (%d)\n", n-1); lineno++; + fprintf(out, "#define YY_SHIFT_MIN (%d)\n", mnTknOfst); lineno++; + fprintf(out, "#define YY_SHIFT_MAX (%d)\n", mxTknOfst); lineno++; fprintf(out, "static const %s yy_shift_ofst[] = {\n", - minimum_size_type(mnTknOfst-1, mxTknOfst, &sz)); lineno++; + minimum_size_type(mnTknOfst, lemp->nterminal+lemp->nactiontab, &sz)); + lineno++; lemp->tablesize += n*sz; for(i=j=0; isorted[i]; ofst = stp->iTknOfst; - if( ofst==NO_OFFSET ) ofst = mnTknOfst - 1; + if( ofst==NO_OFFSET ) ofst = lemp->nactiontab; if( j==0 ) fprintf(out," /* %5d */ ", i); fprintf(out, " %4d,", ofst); if( j==9 || i==n-1 ){ From 696beca40f92e33d08ac976f1bf5a7753aa01089 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Thu, 13 Oct 2016 22:23:28 -0500 Subject: [PATCH 08/23] Lemon update 2016-08-16 16:46:40 on branch trunk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit — Fix a bug in destructorprocessing of Lemon. That has no impact on the SQLite grammar. The bug was introduced by prior work to optimize the Lemon-generated parser used by SQLite. (user: drh) --- tools/lemon/lemon.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index 1e673be8a..f2da9c6f8 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -167,7 +167,8 @@ struct symbol { int useCnt; /* Number of times used */ char *destructor; /* Code which executes whenever this symbol is ** popped from the stack during error processing */ - int destLineno; /* Line number for start of destructor */ + int destLineno; /* Line number for start of destructor. Set to + ** -1 for duplicate destructors. */ char *datatype; /* The data type of information held by this ** object. Only used if type==NONTERMINAL */ int dtnum; /* The data type number. In the parser, the value @@ -4387,6 +4388,7 @@ void ReportTable( for(i=0; insymbol; i++){ struct symbol *sp = lemp->symbols[i]; if( sp==0 || sp->type==TERMINAL || sp->destructor==0 ) continue; + if( sp->destLineno<0 ) continue; /* Already emitted */ fprintf(out," case %d: /* %s */\n", sp->index, sp->name); lineno++; /* Combine duplicate destructors into a single case */ @@ -4397,7 +4399,7 @@ void ReportTable( && strcmp(sp->destructor,sp2->destructor)==0 ){ fprintf(out," case %d: /* %s */\n", sp2->index, sp2->name); lineno++; - sp2->destructor = 0; + sp2->destLineno = -1; /* Avoid emitting this destructor again */ } } From 97107b6b6d7704660e356bbb016f132e2bfebe91 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Thu, 13 Oct 2016 22:30:12 -0500 Subject: [PATCH 09/23] Update lempar.c to 2016-10-04 version - Every update rolled into one, because I'm pretty sure I missed some while updating lemon.c (not counting today's commits), since it wasn't always updated at the same time as lemon.c. - In particular, I think this check-in from 2016-06-06 was very important to us after commit 3d5867d29e8932d238084e5c66dead1b4502f82f (For the Lemon-generated parser, add a new action type SHIFTREDUCE and use it to further compress the parser tables and improve parser performance.): * Fix lempar.c so that the shift-reduce optimization works for error processing. --- src/zscript/zcc-parse.lemon | 2 +- tools/lemon/lempar.c | 263 +++++++++++++++++++----------------- 2 files changed, 141 insertions(+), 124 deletions(-) diff --git a/src/zscript/zcc-parse.lemon b/src/zscript/zcc-parse.lemon index ee8296ff6..12cbb6625 100644 --- a/src/zscript/zcc-parse.lemon +++ b/src/zscript/zcc-parse.lemon @@ -77,7 +77,7 @@ static void SetNodeLine(ZCC_TreeNode *name, int line) FString unexpected, expecting; int i; - int stateno = yypParser->yystack[yypParser->yyidx].stateno; + int stateno = yypParser->yytos->stateno; unexpected << "Unexpected " << ZCCTokenName(yymajor); diff --git a/tools/lemon/lempar.c b/tools/lemon/lempar.c index 0549a9dad..0e360bab9 100644 --- a/tools/lemon/lempar.c +++ b/tools/lemon/lempar.c @@ -41,6 +41,7 @@ ***************** Begin makeheaders token definitions *************************/ %% /**************** End makeheaders token definitions ***************************/ + /* The next section is a series of control #defines. ** various aspects of the generated parser. ** YYCODETYPE is the data type used to store the integer codes @@ -50,8 +51,6 @@ ** YYNOCODE is a number of type YYCODETYPE that is not used for ** any terminal or nonterminal symbol. ** YYFALLBACK If defined, this indicates that one or more tokens -** have fall-back values which should be used if the -** original value of the token will not parse. ** (also known as: "terminal symbols") have fall-back ** values which should be used if the original symbol ** would not parse. This permits keywords to sometimes @@ -126,7 +125,7 @@ ** ** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE ** and YY_MAX_REDUCE - +** ** N == YY_ERROR_ACTION A syntax error has occurred. ** ** N == YY_ACCEPT_ACTION The parser accepts its input. @@ -135,16 +134,20 @@ ** slots in the yy_action[] table. ** ** The action table is constructed as a single large table named yy_action[]. -** Given state S and lookahead X, the action is computed as +** Given state S and lookahead X, the action is computed as either: ** -** yy_action[ yy_shift_ofst[S] + X ] +** (A) N = yy_action[ yy_shift_ofst[S] + X ] +** (B) N = yy_default[S] ** -** If the index value yy_shift_ofst[S]+X is out of range or if the value -** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] -** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table -** and that yy_default[S] should be used instead. +** The (A) formula is preferred. The B formula is used instead if: +** (1) The yy_shift_ofst[S]+X value is out of range, or +** (2) yy_lookahead[yy_shift_ofst[S]+X] is not equal to X, or +** (3) yy_shift_ofst[S] equal YY_SHIFT_USE_DFLT. +** (Implementation note: YY_SHIFT_USE_DFLT is chosen so that +** YY_SHIFT_USE_DFLT+X will be out of range for all possible lookaheads X. +** Hence only tests (1) and (2) need to be evaluated.) ** -** The formula above is for computing the action when the lookahead is +** The formulas above are for computing the action when the lookahead is ** a terminal symbol. If the lookahead is a non-terminal (as occurs after ** a reduce action) then the yy_reduce_ofst[] array is used in place of ** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of @@ -213,9 +216,9 @@ typedef struct yyStackEntry yyStackEntry; /* The state of the parser is completely contained in an instance of ** the following structure */ struct yyParser { - int yyidx; /* Index of top element in stack */ + yyStackEntry *yytos; /* Pointer to top element of the stack */ #ifdef YYTRACKMAXSTACKDEPTH - int yyidxMax; /* Maximum value of yyidx */ + int yyhwm; /* High-water mark of the stack */ #endif #ifndef YYNOERRORRECOVERY int yyerrcnt; /* Shifts left before out of the error */ @@ -224,6 +227,7 @@ struct yyParser { #if YYSTACKDEPTH<=0 int yystksz; /* Current side of the stack */ yyStackEntry *yystack; /* The parser's stack */ + yyStackEntry yystk0; /* First stack entry */ #else yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ #endif @@ -278,26 +282,37 @@ static const char *const yyRuleName[] = { }; #endif /* NDEBUG */ + #if YYSTACKDEPTH<=0 /* -** Try to increase the size of the parser stack. +** Try to increase the size of the parser stack. Return the number +** of errors. Return 0 on success. */ -static void yyGrowStack(yyParser *p){ +static int yyGrowStack(yyParser *p){ int newSize; + int idx; yyStackEntry *pNew; newSize = p->yystksz*2 + 100; - pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); + idx = p->yytos ? (int)(p->yytos - p->yystack) : 0; + if( p->yystack==&p->yystk0 ){ + pNew = malloc(newSize*sizeof(pNew[0])); + if( pNew ) pNew[0] = p->yystk0; + }else{ + pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); + } if( pNew ){ p->yystack = pNew; - p->yystksz = newSize; + p->yytos = &p->yystack[idx]; #ifndef NDEBUG if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", - yyTracePrompt, p->yystksz); + fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n", + yyTracePrompt, p->yystksz, newSize); } #endif + p->yystksz = newSize; } + return pNew==0; } #endif @@ -326,15 +341,24 @@ void *ParseAlloc(void *(CDECL *mallocProc)(YYMALLOCARGTYPE)){ yyParser *pParser; pParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); if( pParser ){ - pParser->yyidx = -1; #ifdef YYTRACKMAXSTACKDEPTH - pParser->yyidxMax = 0; + pParser->yyhwm = 0; #endif #if YYSTACKDEPTH<=0 + pParser->yytos = NULL; pParser->yystack = NULL; pParser->yystksz = 0; - yyGrowStack(pParser); + if( yyGrowStack(pParser) ){ + pParser->yystack = &pParser->yystk0; + pParser->yystksz = 1; + } #endif +#ifndef YYNOERRORRECOVERY + pParser->yyerrcnt = -1; +#endif + pParser->yytos = pParser->yystack; + pParser->yystack[0].stateno = 0; + pParser->yystack[0].major = 0; } return pParser; } @@ -378,8 +402,9 @@ static void yy_destructor( */ static void yy_pop_parser_stack(yyParser *pParser){ yyStackEntry *yytos; - assert( pParser->yyidx>=0 ); - yytos = &pParser->yystack[pParser->yyidx--]; + assert( pParser->yytos!=0 ); + assert( pParser->yytos > pParser->yystack ); + yytos = pParser->yytos--; #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sPopping %s\n", @@ -390,10 +415,10 @@ static void yy_pop_parser_stack(yyParser *pParser){ yy_destructor(pParser, yytos->major, &yytos->minor); } -/* +/* ** Deallocate and destroy a parser. Destructors are called for ** all stack elements before shutting the parser down. -* +** ** If the YYPARSEFREENEVERNULL macro exists (for example because it ** is defined in a %include section of the input grammar) then it is ** assumed that the input pointer is never NULL. @@ -406,9 +431,9 @@ void ParseFree( #ifndef YYPARSEFREENEVERNULL if( pParser==0 ) return; #endif - while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); + while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser); #if YYSTACKDEPTH<=0 - free(pParser->yystack); + if( pParser->yystack!=&pParser->yystk0 ) free(pParser->yystack); #endif (*freeProc)((void*)pParser); } @@ -419,7 +444,7 @@ void ParseFree( #ifdef YYTRACKMAXSTACKDEPTH int ParseStackPeak(void *p){ yyParser *pParser = (yyParser*)p; - return pParser->yyidxMax; + return pParser->yyhwm; } #endif @@ -432,56 +457,53 @@ static unsigned int yy_find_shift_action( YYCODETYPE iLookAhead /* The look-ahead token */ ){ int i; - int stateno = pParser->yystack[pParser->yyidx].stateno; + int stateno = pParser->yytos->stateno; if( stateno>=YY_MIN_REDUCE ) return stateno; assert( stateno <= YY_SHIFT_COUNT ); do{ i = yy_shift_ofst[stateno]; - if( i==YY_SHIFT_USE_DFLT ) return yy_default[stateno]; assert( iLookAhead!=YYNOCODE ); i += iLookAhead; if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){ - if( iLookAhead>0 ){ #ifdef YYFALLBACK - YYCODETYPE iFallback; /* Fallback token */ - if( iLookAhead %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); - } -#endif - assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */ - iLookAhead = iFallback; - continue; + if( yyTraceFILE ){ + fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); } +#endif + assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */ + iLookAhead = iFallback; + continue; + } #endif #ifdef YYWILDCARD - { - int j = i - iLookAhead + YYWILDCARD; - if( + { + int j = i - iLookAhead + YYWILDCARD; + if( #if YY_SHIFT_MIN+YYWILDCARD<0 - j>=0 && + j>=0 && #endif #if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT - j0 + ){ #ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", - yyTracePrompt, yyTokenName[iLookAhead], - yyTokenName[YYWILDCARD]); - } -#endif /* NDEBUG */ - return yy_action[j]; + if( yyTraceFILE ){ + fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", + yyTracePrompt, yyTokenName[iLookAhead], + yyTokenName[YYWILDCARD]); } +#endif /* NDEBUG */ + return yy_action[j]; } -#endif /* YYWILDCARD */ } +#endif /* YYWILDCARD */ return yy_default[stateno]; }else{ return yy_action[i]; @@ -500,7 +522,7 @@ static int yy_find_reduce_action( int i; #ifdef YYERRORSYMBOL if( stateno>YY_REDUCE_COUNT ){ - return yy_default[stateno]; + return yy_default[stateno]; } #else assert( stateno<=YY_REDUCE_COUNT ); @@ -525,15 +547,15 @@ static int yy_find_reduce_action( */ static void yyStackOverflow(yyParser *yypParser){ ParseARG_FETCH; - yypParser->yyidx--; + yypParser->yytos--; #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); } #endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); /* Here code is inserted which will execute if the parser - ** stack ever overflows */ + ** stack every overflows */ /******** Begin %stack_overflow code ******************************************/ %% /******** End %stack_overflow code ********************************************/ @@ -548,11 +570,11 @@ static void yyTraceShift(yyParser *yypParser, int yyNewState){ if( yyTraceFILE ){ if( yyNewStateyystack[yypParser->yyidx].major], + yyTracePrompt,yyTokenName[yypParser->yytos->major], yyNewState); }else{ fprintf(yyTraceFILE,"%sShift '%s'\n", - yyTracePrompt,yyTokenName[yypParser->yystack[yypParser->yyidx].major]); + yyTracePrompt,yyTokenName[yypParser->yytos->major]); } } } @@ -570,27 +592,30 @@ static void yy_shift( ParseTOKENTYPE yyMinor /* The minor token to shift in */ ){ yyStackEntry *yytos; - yypParser->yyidx++; + yypParser->yytos++; #ifdef YYTRACKMAXSTACKDEPTH - if( yypParser->yyidx>yypParser->yyidxMax ){ - yypParser->yyidxMax = yypParser->yyidx; + if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){ + yypParser->yyhwm++; + assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack) ); } #endif -#if YYSTACKDEPTH>0 - if( yypParser->yyidx>=YYSTACKDEPTH ){ +#if YYSTACKDEPTH>0 + if( yypParser->yytos>=&yypParser->yystack[YYSTACKDEPTH] ){ yyStackOverflow(yypParser); return; } #else - if( yypParser->yyidx>=yypParser->yystksz ){ - yyGrowStack(yypParser); - if( yypParser->yyidx>=yypParser->yystksz ){ + if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz] ){ + if( yyGrowStack(yypParser) ){ yyStackOverflow(yypParser); return; } } #endif - yytos = &yypParser->yystack[yypParser->yyidx]; + if( yyNewState > YY_MAX_SHIFT ){ + yyNewState += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; + } + yytos = yypParser->yytos; yytos->stateno = (YYACTIONTYPE)yyNewState; yytos->major = (YYCODETYPE)yyMajor; yytos->minor.yy0 = yyMinor; @@ -622,7 +647,7 @@ static void yy_reduce( yyStackEntry *yymsp; /* The top of the parser's stack */ int yysize; /* Amount to pop the stack */ ParseARG_FETCH; - yymsp = &yypParser->yystack[yypParser->yyidx]; + yymsp = yypParser->yytos; #ifndef NDEBUG if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ yysize = yyRuleInfo[yyruleno].nrhs; @@ -636,22 +661,23 @@ static void yy_reduce( ** enough on the stack to push the LHS value */ if( yyRuleInfo[yyruleno].nrhs==0 ){ #ifdef YYTRACKMAXSTACKDEPTH - if( yypParser->yyidx>yypParser->yyidxMax ){ - yypParser->yyidxMax = yypParser->yyidx; + if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){ + yypParser->yyhwm++; + assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack)); } #endif -#if YYSTACKDEPTH>0 - if( yypParser->yyidx>=YYSTACKDEPTH-1 ){ +#if YYSTACKDEPTH>0 + if( yypParser->yytos>=&yypParser->yystack[YYSTACKDEPTH-1] ){ yyStackOverflow(yypParser); return; } #else - if( yypParser->yyidx>=yypParser->yystksz-1 ){ - yyGrowStack(yypParser); - if( yypParser->yyidx>=yypParser->yystksz-1 ){ + if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ + if( yyGrowStack(yypParser) ){ yyStackOverflow(yypParser); return; } + yymsp = yypParser->yytos; } #endif } @@ -674,15 +700,17 @@ static void yy_reduce( yysize = yyRuleInfo[yyruleno].nrhs; yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto); if( yyact <= YY_MAX_SHIFTREDUCE ){ - if( yyact>YY_MAX_SHIFT ) yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; - yypParser->yyidx -= yysize - 1; + if( yyact>YY_MAX_SHIFT ){ + yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; + } yymsp -= yysize-1; + yypParser->yytos = yymsp; yymsp->stateno = (YYACTIONTYPE)yyact; yymsp->major = (YYCODETYPE)yygoto; yyTraceShift(yypParser, yyact); }else{ assert( yyact == YY_ACCEPT_ACTION ); - yypParser->yyidx -= yysize; + yypParser->yytos -= yysize; yy_accept(yypParser); } } @@ -700,7 +728,7 @@ static void yy_parse_failed( fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); } #endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); /* Here code is inserted which will be executed whenever the ** parser fails */ /************ Begin %parse_failure code ***************************************/ @@ -738,7 +766,10 @@ static void yy_accept( fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); } #endif - while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; +#endif + assert( yypParser->yytos==yypParser->yystack ); /* Here code is inserted which will be executed whenever the ** parser accepts */ /*********** Begin %parse_accept code *****************************************/ @@ -782,28 +813,8 @@ void Parse( #endif yyParser *yypParser; /* The parser */ - /* (re)initialize the parser, if necessary */ yypParser = (yyParser*)yyp; - if( yypParser->yyidx<0 ){ -#if YYSTACKDEPTH<=0 - if( yypParser->yystksz <=0 ){ - yyStackOverflow(yypParser); - return; - } -#endif - yypParser->yyidx = 0; -#ifndef YYNOERRORRECOVERY - yypParser->yyerrcnt = -1; -#endif - yypParser->yystack[0].stateno = 0; - yypParser->yystack[0].major = 0; -#ifndef NDEBUG - if( yyTraceFILE ){ - fprintf(yyTraceFILE,"%sInitialize. Empty stack. State 0\n", - yyTracePrompt); - } -#endif - } + assert( yypParser->yytos!=0 ); #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) yyendofinput = (yymajor==0); #endif @@ -818,7 +829,6 @@ void Parse( do{ yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); if( yyact <= YY_MAX_SHIFTREDUCE ){ - if( yyact > YY_MAX_SHIFT ) yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE; yy_shift(yypParser,yyact,yymajor,yyminor); #ifndef YYNOERRORRECOVERY yypParser->yyerrcnt--; @@ -827,11 +837,11 @@ void Parse( }else if( yyact <= YY_MAX_REDUCE ){ yy_reduce(yypParser,yyact-YY_MIN_REDUCE); }else{ + assert( yyact == YY_ERROR_ACTION ); + yyminorunion.yy0 = yyminor; #ifdef YYERRORSYMBOL int yymx; #endif - assert( yyact == YY_ERROR_ACTION ); - yyminorunion.yy0 = yyminor; #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); @@ -840,7 +850,7 @@ void Parse( #ifdef YYERRORSYMBOL /* A syntax error has occurred. ** The response to an error depends upon whether or not the - ** grammar defines an error token "ERROR". + ** grammar defines an error token "ERROR". ** ** This is what we do if the grammar does define ERROR: ** @@ -860,7 +870,7 @@ void Parse( if( yypParser->yyerrcnt<0 ){ yy_syntax_error(yypParser,yymajor,yyminor); } - yymx = yypParser->yystack[yypParser->yyidx].major; + yymx = yypParser->yytos->major; if( yymx==YYERRORSYMBOL || yyerrorhit ){ #ifndef NDEBUG if( yyTraceFILE ){ @@ -871,18 +881,20 @@ void Parse( yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion); yymajor = YYNOCODE; }else{ - while( - yypParser->yyidx >= 0 && - yymx != YYERRORSYMBOL && - (yyact = yy_find_reduce_action( - yypParser->yystack[yypParser->yyidx].stateno, + while( yypParser->yytos >= yypParser->yystack + && yymx != YYERRORSYMBOL + && (yyact = yy_find_reduce_action( + yypParser->yytos->stateno, YYERRORSYMBOL)) >= YY_MIN_REDUCE ){ yy_pop_parser_stack(yypParser); } - if( yypParser->yyidx < 0 || yymajor==0 ){ + if( yypParser->yytos < yypParser->yystack || yymajor==0 ){ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); yy_parse_failed(yypParser); +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; +#endif yymajor = YYNOCODE; }else if( yymx!=YYERRORSYMBOL ){ yy_shift(yypParser,yyact,YYERRORSYMBOL,yyminor); @@ -901,7 +913,7 @@ void Parse( yy_syntax_error(yypParser,yymajor, yyminor); yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); yymajor = YYNOCODE; - + #else /* YYERRORSYMBOL is not defined */ /* This is what we do if the grammar does not define ERROR: ** @@ -919,18 +931,23 @@ void Parse( yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); if( yyendofinput ){ yy_parse_failed(yypParser); +#ifndef YYNOERRORRECOVERY + yypParser->yyerrcnt = -1; +#endif } yymajor = YYNOCODE; #endif } - }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); + }while( yymajor!=YYNOCODE && yypParser->yytos>yypParser->yystack ); #ifndef NDEBUG if( yyTraceFILE ){ - int i; + yyStackEntry *i; + char cDiv = '['; fprintf(yyTraceFILE,"%sReturn. Stack=",yyTracePrompt); - for(i=1; i<=yypParser->yyidx; i++) - fprintf(yyTraceFILE,"%c%s", i==1 ? '[' : ' ', - yyTokenName[yypParser->yystack[i].major]); + for(i=&yypParser->yystack[1]; i<=yypParser->yytos; i++){ + fprintf(yyTraceFILE,"%c%s", cDiv, yyTokenName[i->major]); + cDiv = ' '; + } fprintf(yyTraceFILE,"]\n"); } #endif From d6b3cbe0c9aae8549670dc6f28dcdff55c10f260 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Fri, 14 Oct 2016 13:39:19 +0300 Subject: [PATCH 10/23] Fixed serialization of MovePoly class objects See http://forum.zdoom.org/viewtopic.php?t=53787 Removed "speed" field which is serialized in the parent class --- src/po_man.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/po_man.cpp b/src/po_man.cpp index 2eed96596..c779a8049 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -265,7 +265,6 @@ void DMovePoly::Serialize(FSerializer &arc) { Super::Serialize (arc); arc("angle", m_Angle) - ("speed", m_Speed); ("speedv", m_Speedv); } From 657abb374b8682ea1b36ae89622d11ac697d08f8 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 14 Oct 2016 11:24:03 +0200 Subject: [PATCH 11/23] Fix SkyViewpoint skyboxes not being rendered --- src/r_plane.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_plane.cpp b/src/r_plane.cpp index ff23492ab..07001bf1b 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -1314,7 +1314,7 @@ void R_DrawPortals () vissprite_p = firstvissprite; visplaneStack.Pop (pl); - if (pl->Alpha > 0) + if (pl->Alpha > 0 && pl->picnum != skyflatnum) { R_DrawSinglePlane (pl, pl->Alpha, pl->Additive, true); } From 36aff68501d4e21c9ea6d24474dafd7bf68b108b Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 14 Oct 2016 15:23:23 +0200 Subject: [PATCH 12/23] Fix divide by zero if yscale is too small a number --- src/r_things.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_things.cpp b/src/r_things.cpp index ab75c15b0..99ca68b60 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -408,7 +408,7 @@ void R_DrawVisSprite (vissprite_t *vis) ESPSResult mode; bool ispsprite = (!vis->sector && vis->gpos != FVector3(0, 0, 0)); - if (vis->xscale == 0 || vis->yscale == 0) + if (vis->xscale == 0 || fabs(vis->yscale) < (1.0f / 32000.0f)) { // scaled to 0; can't see return; } From 0370592422830fcf22796d86977df53d4b5d52b1 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Fri, 14 Oct 2016 14:31:58 +0300 Subject: [PATCH 13/23] Fixed serialization of DSeqPolyNode class objects Polyobject pointer was not serialized at all --- src/s_sndseq.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/s_sndseq.cpp b/src/s_sndseq.cpp index 23837c28b..3b39965ff 100644 --- a/src/s_sndseq.cpp +++ b/src/s_sndseq.cpp @@ -442,7 +442,7 @@ IMPLEMENT_CLASS (DSeqPolyNode) void DSeqPolyNode::Serialize(FSerializer &arc) { Super::Serialize (arc); - //arc << m_Poly; + arc("poly", m_Poly); } IMPLEMENT_CLASS (DSeqSectorNode) From 0df6ba69516d239a3a5f255a72e1b0edb0673c72 Mon Sep 17 00:00:00 2001 From: FishyClockwork Date: Fri, 14 Oct 2016 09:13:31 +0200 Subject: [PATCH 14/23] First, take care of usdf.txt Updated about the new 'goodbye' property. --- specs/usdf.txt | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/specs/usdf.txt b/specs/usdf.txt index 1367ccfbf..c3c286f20 100644 --- a/specs/usdf.txt +++ b/specs/usdf.txt @@ -87,14 +87,16 @@ conversation // Starts a dialog. page // Starts a new page. Pages are automatically numbered starting at 1. { - name = ; // Name that goes in the upper left hand corner - panel = ; // Name of lump to render as the background. - voice = ; // Narration sound lump. - dialog = ; // Dialog of the page. - drop = ; // mobj for the object to drop if the actor is - // killed. - link = ; // Page to jump to if all ifitem conditions are - // satisified. + name = ; // Name that goes in the upper left hand corner + panel = ; // Name of lump to render as the background. + voice = ; // Narration sound lump. + dialog = ; // Dialog of the page. + goodbye = ; // Custom goodbye message. If omitted then the + // generic goodbyes will be displayed instead. + drop = ; // mobj for the object to drop if the actor is + // killed. + link = ; // Page to jump to if all ifitem conditions are + // satisified. // jumps to the specified page if the player has the specified amount // or more of item in their inventory. This can be repeated as many From 1ab990f81f2021b4912635cda5321c89e7e0fd84 Mon Sep 17 00:00:00 2001 From: FishyClockwork Date: Fri, 14 Oct 2016 09:17:35 +0200 Subject: [PATCH 15/23] Again... --- specs/usdf.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/usdf.txt b/specs/usdf.txt index c3c286f20..093c9e7d7 100644 --- a/specs/usdf.txt +++ b/specs/usdf.txt @@ -91,7 +91,7 @@ conversation // Starts a dialog. panel = ; // Name of lump to render as the background. voice = ; // Narration sound lump. dialog = ; // Dialog of the page. - goodbye = ; // Custom goodbye message. If omitted then the + goodbye = ; // Custom goodbye message. If omitted then the // generic goodbyes will be displayed instead. drop = ; // mobj for the object to drop if the actor is // killed. From ecffd0bea653e04a5a2deb648c70eee546371336 Mon Sep 17 00:00:00 2001 From: FishyClockwork Date: Fri, 14 Oct 2016 11:55:50 +0200 Subject: [PATCH 16/23] Done the code changes. This time only nulls I've added are nullptrs --- src/namedef.h | 1 + src/p_conversation.cpp | 25 +++++++++++++++++++++---- src/p_conversation.h | 1 + src/p_usdf.cpp | 6 +++++- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/namedef.h b/src/namedef.h index 36953e385..eab87c503 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -584,6 +584,7 @@ xx(Dialog) xx(Ifitem) xx(Choice) xx(Link) +xx(Goodbye) // Special menus xx(Mainmenu) diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index a697223e7..31fa25030 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -556,6 +556,7 @@ FStrifeDialogueNode::~FStrifeDialogueNode () { if (SpeakerName != NULL) delete[] SpeakerName; if (Dialogue != NULL) delete[] Dialogue; + if (Goodbye != nullptr) delete[] Goodbye; FStrifeDialogueReply *tokill = Children; while (tokill != NULL) { @@ -743,10 +744,26 @@ public: ++i; V_FreeBrokenLines (ReplyLines); } - char goodbye[25]; - mysnprintf(goodbye, countof(goodbye), "TXT_RANDOMGOODBYE_%d", 1+(pr_randomspeech() % NUM_RANDOM_GOODBYES)); - const char *goodbyestr = GStrings[goodbye]; - if (goodbyestr == NULL) goodbyestr = "Bye."; + const char *goodbyestr = CurNode->Goodbye; + if (goodbyestr == nullptr) + { + char goodbye[25]; + mysnprintf(goodbye, countof(goodbye), "TXT_RANDOMGOODBYE_%d", 1 + (pr_randomspeech() % NUM_RANDOM_GOODBYES)); + goodbyestr = GStrings[goodbye]; + if (goodbyestr == nullptr) goodbyestr = "Bye."; + } + else if (strncmp(goodbyestr, "RANDOM_", 7) == 0) + { + FString byetext; + + byetext.Format("TXT_%s_%02d", goodbyestr, 1 + (pr_randomspeech() % NUM_RANDOM_LINES)); + goodbyestr = GStrings[byetext]; + if (goodbyestr == nullptr) goodbyestr = "Bye."; + } + else if (goodbyestr[0] == '$') + { + goodbyestr = GStrings(goodbyestr + 1); + } mResponses.Push(mResponseLines.Size()); mResponseLines.Push(FString(goodbyestr)); diff --git a/src/p_conversation.h b/src/p_conversation.h index d6ba65d78..5b068fb04 100644 --- a/src/p_conversation.h +++ b/src/p_conversation.h @@ -30,6 +30,7 @@ struct FStrifeDialogueNode FSoundID SpeakerVoice; FTextureID Backdrop; char *Dialogue; + char *Goodbye = nullptr; // must init to null for binary scripts to work as intended FStrifeDialogueReply *Children; }; diff --git a/src/p_usdf.cpp b/src/p_usdf.cpp index 13a02b964..dccec7c21 100644 --- a/src/p_usdf.cpp +++ b/src/p_usdf.cpp @@ -286,6 +286,7 @@ class USDFParser : public UDMFParserBase FString SpeakerName; FString Dialogue; + FString Goodbye; while (!sc.CheckToken('}')) { @@ -331,7 +332,9 @@ class USDFParser : public UDMFParserBase node->ItemCheckNode = CheckInt(key); break; - + case NAME_Goodbye: + Goodbye = CheckString(key); + break; } } else @@ -354,6 +357,7 @@ class USDFParser : public UDMFParserBase } node->SpeakerName = ncopystring(SpeakerName); node->Dialogue = ncopystring(Dialogue); + node->Goodbye = ncopystring(Goodbye); return true; } From 08504dcbe235415a4243e8c76f26ed54b0255a04 Mon Sep 17 00:00:00 2001 From: FishyClockwork Date: Fri, 14 Oct 2016 15:17:19 +0200 Subject: [PATCH 17/23] Added a small check just in case... --- src/p_conversation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 31fa25030..1762ae98e 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -763,6 +763,7 @@ public: else if (goodbyestr[0] == '$') { goodbyestr = GStrings(goodbyestr + 1); + if (goodbyestr == nullptr) goodbyestr = "Bye."; } mResponses.Push(mResponseLines.Size()); mResponseLines.Push(FString(goodbyestr)); From 2e882a41a33f0a7d45d229a817e5a9db2ce4e725 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 14 Oct 2016 23:13:08 +0200 Subject: [PATCH 18/23] - removed some redundancy. --- src/p_conversation.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 1762ae98e..f216d9d78 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -750,7 +750,6 @@ public: char goodbye[25]; mysnprintf(goodbye, countof(goodbye), "TXT_RANDOMGOODBYE_%d", 1 + (pr_randomspeech() % NUM_RANDOM_GOODBYES)); goodbyestr = GStrings[goodbye]; - if (goodbyestr == nullptr) goodbyestr = "Bye."; } else if (strncmp(goodbyestr, "RANDOM_", 7) == 0) { @@ -758,13 +757,12 @@ public: byetext.Format("TXT_%s_%02d", goodbyestr, 1 + (pr_randomspeech() % NUM_RANDOM_LINES)); goodbyestr = GStrings[byetext]; - if (goodbyestr == nullptr) goodbyestr = "Bye."; } else if (goodbyestr[0] == '$') { goodbyestr = GStrings(goodbyestr + 1); - if (goodbyestr == nullptr) goodbyestr = "Bye."; } + if (goodbyestr == nullptr) goodbyestr = "Bye."; mResponses.Push(mResponseLines.Size()); mResponseLines.Push(FString(goodbyestr)); From f23e5d26775c7e5af8f60f9dc66dee2a469c0f46 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Fri, 14 Oct 2016 22:02:55 -0500 Subject: [PATCH 19/23] Fixed: XLAT would not parse - Disable the changes from commit 96afce241d6bc08cfdb0018ea6e5f0c23e8ba5c8 because it appears to not recognize default rules that reduce as reducing. - When tracing a parser, flush after every line output in case an assert is hit so you can actually see what it did up to that point. --- tools/lemon/lemon.c | 8 ++++++++ tools/lemon/lempar.c | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index f2da9c6f8..bdc004a17 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -199,7 +199,9 @@ struct rule { int index; /* An index number for this rule */ int iRule; /* Rule number as used in the generated tables */ Boolean canReduce; /* True if this rule is ever reduced */ +#if 0 Boolean doesReduce; /* Reduce actions occur after optimization */ +#endif struct rule *nextlhs; /* Next rule with the same LHS */ struct rule *next; /* Next rule in the global list */ }; @@ -4156,6 +4158,7 @@ void ReportTable( } free(ax); +#if 0 /* Mark rules that are actually used for reduce actions after all ** optimizations have been applied */ @@ -4168,6 +4171,7 @@ void ReportTable( } } } +#endif /* Finish rendering the constants now that the action table has ** been computed */ @@ -4462,12 +4466,16 @@ void ReportTable( assert( rp->noCode ); fprintf(out," /* (%d) ", rp->iRule); writeRuleText(out, rp); +#if 0 if( rp->doesReduce ){ +#endif fprintf(out, " */ yytestcase(yyruleno==%d);\n", rp->iRule); lineno++; +#if 0 }else{ fprintf(out, " (OPTIMIZED OUT) */ assert(yyruleno!=%d);\n", rp->iRule); lineno++; } +#endif } fprintf(out," break;\n"); lineno++; tplt_xfer(lemp->name,in,out,&lineno); diff --git a/tools/lemon/lempar.c b/tools/lemon/lempar.c index 0e360bab9..93b612017 100644 --- a/tools/lemon/lempar.c +++ b/tools/lemon/lempar.c @@ -308,6 +308,7 @@ static int yyGrowStack(yyParser *p){ if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n", yyTracePrompt, p->yystksz, newSize); + fflush(yyTraceFILE); } #endif p->yystksz = newSize; @@ -410,6 +411,7 @@ static void yy_pop_parser_stack(yyParser *pParser){ fprintf(yyTraceFILE,"%sPopping %s\n", yyTracePrompt, yyTokenName[yytos->major]); + fflush(yyTraceFILE); } #endif yy_destructor(pParser, yytos->major, &yytos->minor); @@ -474,6 +476,7 @@ static unsigned int yy_find_shift_action( if( yyTraceFILE ){ fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n", yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); + fflush(yyTraceFILE); } #endif assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */ @@ -498,6 +501,7 @@ static unsigned int yy_find_shift_action( fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); + fflush(yyTraceFILE); } #endif /* NDEBUG */ return yy_action[j]; @@ -551,6 +555,7 @@ static void yyStackOverflow(yyParser *yypParser){ #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); + fflush(yyTraceFILE); } #endif while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); @@ -576,6 +581,7 @@ static void yyTraceShift(yyParser *yypParser, int yyNewState){ fprintf(yyTraceFILE,"%sShift '%s'\n", yyTracePrompt,yyTokenName[yypParser->yytos->major]); } + fflush(yyTraceFILE); } } #else @@ -653,6 +659,7 @@ static void yy_reduce( yysize = yyRuleInfo[yyruleno].nrhs; fprintf(yyTraceFILE, "%sReduce [%s], go to state %d.\n", yyTracePrompt, yyRuleName[yyruleno], yymsp[-yysize].stateno); + fflush(yyTraceFILE); } #endif /* NDEBUG */ @@ -726,6 +733,7 @@ static void yy_parse_failed( #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); + fflush(yyTraceFILE); } #endif while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); @@ -764,12 +772,17 @@ static void yy_accept( #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); + fflush(yyTraceFILE); } #endif #ifndef YYNOERRORRECOVERY yypParser->yyerrcnt = -1; #endif +#if 0 assert( yypParser->yytos==yypParser->yystack ); +#else + while (yypParser->yytos>yypParser->yystack) yy_pop_parser_stack(yypParser); +#endif /* Here code is inserted which will be executed whenever the ** parser accepts */ /*********** Begin %parse_accept code *****************************************/ @@ -823,6 +836,7 @@ void Parse( #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sInput '%s'\n",yyTracePrompt,yyTokenName[yymajor]); + fflush(yyTraceFILE); } #endif @@ -845,6 +859,7 @@ void Parse( #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); + fflush(yyTraceFILE); } #endif #ifdef YYERRORSYMBOL @@ -876,6 +891,7 @@ void Parse( if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sDiscard input token %s\n", yyTracePrompt,yyTokenName[yymajor]); + fflush(yyTraceFILE); } #endif yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion); @@ -949,6 +965,7 @@ void Parse( cDiv = ' '; } fprintf(yyTraceFILE,"]\n"); + fflush(yyTraceFILE); } #endif return; From 162da2fcafbb4c9e55d2272470c81b0a29e2ad9a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Oct 2016 10:51:48 +0200 Subject: [PATCH 20/23] - allow to specify "none" to set an actor's translation to the identity table. --- src/r_data/r_translate.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index bf9365002..983baea58 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -1207,6 +1207,10 @@ int R_FindCustomTranslation(const char *name) { return TRANSLATION(TRANSLATION_Standard, 7); } + else if (!stricmp(name, "None")) + { + return 0; + } int *t = customTranslationMap.CheckKey(FName(name, true)); return (t != nullptr)? *t : -1; } From 58ec0e4594d2cd112e9da5ba1d5f764edc35290f Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Sat, 15 Oct 2016 20:57:56 -0500 Subject: [PATCH 21/23] Add OF_Transient flag for objects that shouldn't be written to disk --- src/dobject.h | 4 ++++ src/serializer.cpp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/dobject.h b/src/dobject.h index 51102bc4c..91a80f9d0 100644 --- a/src/dobject.h +++ b/src/dobject.h @@ -201,6 +201,7 @@ enum EObjectFlags OF_EuthanizeMe = 1 << 5, // Object wants to die OF_Cleanup = 1 << 6, // Object is now being deleted by the collector OF_YesReallyDelete = 1 << 7, // Object is being deleted outside the collector, and this is okay, so don't print a warning + OF_Transient = 1 << 11, // Object should not be archived (references to it will be nulled on disk) OF_WhiteBits = OF_White0 | OF_White1, OF_MarkBits = OF_WhiteBits | OF_Black, @@ -573,6 +574,9 @@ protected: } }; +// When you write to a pointer to an Object, you must call this for +// proper bookkeeping in case the Object holding this pointer has +// already been processed by the GC. static inline void GC::WriteBarrier(DObject *pointing, DObject *pointed) { if (pointed != NULL && pointed->IsWhite() && pointing->IsBlack()) diff --git a/src/serializer.cpp b/src/serializer.cpp index 7861701c0..3a66a8397 100644 --- a/src/serializer.cpp +++ b/src/serializer.cpp @@ -1451,7 +1451,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, DObject *&value, DObje { ndx = -1; } - else if (value->ObjectFlags & OF_EuthanizeMe) + else if (value->ObjectFlags & (OF_EuthanizeMe | OF_Transient)) { return arc; } From ae14993ba44dff703a190782bcf03594fb74d901 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Sat, 15 Oct 2016 21:14:34 -0500 Subject: [PATCH 22/23] Fixed: Possible invalid processing for Crash states that immediately destroy the actor - Setting an actor's Crash state has the potential to destroy the actor if the Crash state has one or more 0-tic states that end with Stop. This was not taken into account when the object's Z velocity was 0, but it was under the floor anyway. --- src/p_mobj.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 1ebec242e..8f926ea77 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3799,6 +3799,8 @@ void AActor::Tick () else if (Z() <= floorz) { Crash(); + if (ObjectFlags & OF_EuthanizeMe) + return; // actor was destroyed } CheckPortalTransition(true); From e4281454ceebb8714020e6bf1a2c0274d72e5723 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Sat, 15 Oct 2016 21:40:24 -0500 Subject: [PATCH 23/23] Split ANIMATED into three parts, filtered by game that uses them - ANIMATED contained definitions for Doom, Heretic, and Strife, all crammed into a single file. This meant that animations from one game could erroneously make their way into maps for another game that provided custom textures with names that matched textures that animated in the other game. There are now three separate ANIMATED lumps with only the animations defined for the original game and no others. The one that gets loaded depends on the game being played. - Added documentation for the ANIMATED file format to the comment for FTextureManager::InitAnimated(), since I had to figure it out from the code. --- src/textures/animations.cpp | 10 ++++++++++ wadsrc/static/animated.lmp | Bin 1450 -> 0 bytes wadsrc/static/filter/game-doomchex/animated.lmp | Bin 0 -> 507 bytes wadsrc/static/filter/game-heretic/animated.lmp | Bin 0 -> 185 bytes wadsrc/static/filter/game-strife/animated.lmp | Bin 0 -> 760 bytes 5 files changed, 10 insertions(+) delete mode 100644 wadsrc/static/animated.lmp create mode 100644 wadsrc/static/filter/game-doomchex/animated.lmp create mode 100644 wadsrc/static/filter/game-heretic/animated.lmp create mode 100644 wadsrc/static/filter/game-strife/animated.lmp diff --git a/src/textures/animations.cpp b/src/textures/animations.cpp index 74f9b1f55..f46289f07 100644 --- a/src/textures/animations.cpp +++ b/src/textures/animations.cpp @@ -161,6 +161,16 @@ FAnimDef *FTextureManager::AddComplexAnim (FTextureID picnum, const TArray entries, terminated by a 0xFF byte. Each entry +// is 23 bytes long and consists of the following fields: +// Byte 0: Bit 1 set for wall texture, clear for flat texture. +// Bytes 1-9: '\0'-terminated name of first texture. +// Bytes 10-18: '\0'-terminated name of last texture. +// Bytes 19-22: Tics per frame (stored in little endian order). +// //========================================================================== CVAR(Bool, debuganimated, false, 0) diff --git a/wadsrc/static/animated.lmp b/wadsrc/static/animated.lmp deleted file mode 100644 index 100c804c8a8aa4148ed05df34bccf8de671248b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1450 zcmY+E%Z{Tk5Jio8G@939J|zbFwKN2iC=Nu11oevl|B9J=t89|A6zTYM<+^N&nBjVI zeODQyV2$}<@aGpdcd^cp^^~7!(CG$m{~M7V#J=lfas9lD$r?8{&uY3a?qSY==%( zf!z0c;gVXwn%@s0=tM&_yI?XW(+FVJB)gcFIi7oDCwQ#p(~)Z4HybS4@qFPN8-Zud zY|+e?Q*y;QR*gB91|`J4C2jc<{lQ0cxy$`HfTY3S<*vjvT7r+VR>F5f_P{5_A#)Ib}j0fN}D{5Xx}B0vMhK8OOVQ;iq5~*h1po1-!3*6;S=}KTg2= AssI20 diff --git a/wadsrc/static/filter/game-doomchex/animated.lmp b/wadsrc/static/filter/game-doomchex/animated.lmp new file mode 100644 index 0000000000000000000000000000000000000000..016ce1fa3ff2b51f2f3f9b30f7919609cfdae182 GIT binary patch literal 507 zcmY+AOAdlS5Ja1}@i@R>qRU1GLKwizfZYEi+S4DRtR63wqA6JR2?y^01S)_l(9<8d z`PdkkPNoG+2Ye%C0Wy%(k~XYsN7cZPJ$J{rKBw{yAaGNi!Z`bqY6PrX-Y6~bm#%8l z4=K6Om%1U}EubZr6tIiq%TWnK#g}lJbi-)^(M3N-e_#lpfRY~4*00OvK;b8y|C`eU zj?-K+ccd{sk=7fxKN9LZu0p8 Dh$dJa literal 0 HcmV?d00001 diff --git a/wadsrc/static/filter/game-heretic/animated.lmp b/wadsrc/static/filter/game-heretic/animated.lmp new file mode 100644 index 0000000000000000000000000000000000000000..80102c88e203ad1ccffd5f13a6e480f81111b5b1 GIT binary patch literal 185 zcmYL>K@NZ*39gl6-&O=>w zaqkjr+>67nou_Jyd12t)o9dpPTEM#x)e=%#h?kIzGT);>U;|)wHcVr@o{*j3e|2fq z-m2@{wa=*q)|%O(nf;0{AdKiKfp z*s$slR8Q5V$I%9tz`HND#A-uUUFr&BDBw_3T`)6Rs{5-Wr