diff --git a/polymer/eduke32/source/gamedef.c b/polymer/eduke32/source/gamedef.c index 09309bbe0..71bacf473 100644 --- a/polymer/eduke32/source/gamedef.c +++ b/polymer/eduke32/source/gamedef.c @@ -1,6 +1,6 @@ //------------------------------------------------------------------------- /* -Copyright (C) 2010 EDuke32 developers and contributors +Copyright (C) 2016 EDuke32 developers and contributors This file is part of EDuke32. @@ -119,11 +119,6 @@ static char *C_GetLabelType(int32_t type) return Xstrdup(x); } -typedef struct { - const char* token; - int32_t val; -} tokenmap_t; - const tokenmap_t altkeyw [] = { { "#define", CON_DEFINE }, @@ -575,6 +570,7 @@ const char *keyw[] = "ifvarge", // 393 "ifvarboth", // 394 "movesector", // 395 + "for", // 396 "" }; #endif @@ -1226,6 +1222,26 @@ const memberlabel_t PalDataLabels[]= { "", -1, 0, 0 } // END OF LIST }; +const tokenmap_t iter_tokens [] = +{ + { "allsprites", ITER_ALLSPRITES }, + { "allsectors", ITER_ALLSECTORS }, + { "allwalls", ITER_ALLWALLS }, + { "activelights", ITER_ACTIVELIGHTS }, + { "drawnsprites", ITER_DRAWNSPRITES }, + { "spritesofsector", ITER_SPRITESOFSECTOR }, + { "spritesofstatus", ITER_SPRITESOFSTATUS }, + { "loopofwall", ITER_LOOPOFWALL }, + { "wallsofsector", ITER_WALLSOFSECTOR }, + { "range", ITER_RANGE }, + // vvv alternatives go here vvv + { "lights", ITER_ACTIVELIGHTS }, + { "sprofsec", ITER_SPRITESOFSECTOR }, + { "sprofstat", ITER_SPRITESOFSTATUS }, + { "walofsec", ITER_WALLSOFSECTOR }, + { "", -1 } // END OF LIST +}; + #endif char *bitptr; // pointer to bitmap of which bytecode positions contain pointers @@ -1239,6 +1255,7 @@ hashtable_t h_arrays = { MAXGAMEARRAYS>>1, NULL }; hashtable_t h_labels = { 11264>>1, NULL }; static hashtable_t h_keywords = { CON_END>>1, NULL }; +static hashtable_t h_iter = { ITER_END>>1, NULL }; static hashtable_t h_sector = { SECTOR_END>>1, NULL }; static hashtable_t h_wall = { WALL_END>>1, NULL }; @@ -1255,12 +1272,14 @@ static hashtable_t h_paldata = { PALDATA_END>>1, NULL }; static hashtable_t * const tables[] = { &h_gamevars, &h_arrays, &h_labels, &h_keywords, &h_sector, &h_wall, &h_userdef, - &h_projectile, &h_player, &h_input, &h_actor, &h_tsprite, &h_tiledata, &h_paldata + &h_projectile, &h_player, &h_input, &h_actor, &h_tsprite, &h_tiledata, &h_paldata, + &h_iter }; static hashtable_t * const tables_free [] ={ &h_labels, &h_keywords, &h_sector, &h_wall, &h_userdef, - &h_projectile, &h_player, &h_input, &h_actor, &h_tsprite, &h_tiledata, &h_paldata + &h_projectile, &h_player, &h_input, &h_actor, &h_tsprite, &h_tiledata, &h_paldata, + &h_iter }; #define STRUCT_HASH_SETUP(table, labels) do { for (i=0; labels[i].lId >= 0; i++) hash_add(&table, labels[i].name, i, 0); } while (0) @@ -1288,6 +1307,9 @@ void C_InitHashes() STRUCT_HASH_SETUP(h_tsprite, TsprLabels); STRUCT_HASH_SETUP(h_tiledata, TileDataLabels); STRUCT_HASH_SETUP(h_paldata, PalDataLabels); + + for (i=0; iter_tokens[i].val >=0; i++) + hash_add(&h_iter, iter_tokens[i].token, iter_tokens[i].val, 0); } #undef STRUCT_HASH_SETUP @@ -4551,6 +4573,33 @@ DO_DEFSTATE: continue; } + case CON_FOR: // special-purpose iteration + { + C_GetNextVarType(GAMEVAR_READONLY); + + C_GetNextLabelName(); + + int32_t how = hash_find(&h_iter, label + (g_numLabels << 6)); + if (how < 0) + { + C_CUSTOMERROR("unknown iteration type `%s'.", label + (g_numLabels << 6)); + return 1; + } + *g_scriptPtr++ = how; + + if (how >= ITER_SPRITESOFSECTOR) + C_GetNextVar(); + + intptr_t offset = g_scriptPtr-script; + g_scriptPtr++; //Leave a spot for the location to jump to after completion + + C_ParseCommand(0); + + intptr_t *tscrptr = (intptr_t *) script+offset; + *tscrptr = (g_scriptPtr-script)-offset; // relative offset + continue; + } + case CON_ROTATESPRITE16: case CON_ROTATESPRITE: if (EDUKE32_PREDICT_FALSE(!g_parsingEventPtr && g_processingState == 0)) diff --git a/polymer/eduke32/source/gamedef.h b/polymer/eduke32/source/gamedef.h index f17b3d942..132aa429f 100644 --- a/polymer/eduke32/source/gamedef.h +++ b/polymer/eduke32/source/gamedef.h @@ -1,6 +1,6 @@ //------------------------------------------------------------------------- /* -Copyright (C) 2010 EDuke32 developers and contributors +Copyright (C) 2016 EDuke32 developers and contributors This file is part of EDuke32. @@ -40,6 +40,17 @@ extern "C" { #define VM_INSTMASK 0xfff +#define C_CUSTOMERROR(Text, ...) do { \ + C_ReportError(-1); \ + initprintf("%s:%d: error: " Text "\n", g_szScriptFileName, g_lineNumber, ## __VA_ARGS__); \ + g_numCompilerErrors++; \ + } while (0) +#define C_CUSTOMWARNING(Text, ...) do { \ + C_ReportError(-1); \ + initprintf("%s:%d: warning: " Text "\n", g_szScriptFileName, g_lineNumber, ## __VA_ARGS__); \ + g_numCompilerWarnings++; \ + } while (0) + extern intptr_t const * insptr; extern void VM_ScriptInfo(intptr_t const *ptr, int32_t range); @@ -166,6 +177,13 @@ extern int32_t g_errorLineNum; extern int32_t g_tw; extern const char *keyw[]; +typedef struct { + const char* token; + int32_t val; +} tokenmap_t; + +extern const tokenmap_t iter_tokens []; + // KEEPINSYNC lunatic/con_lang.lua enum SystemString_t { STR_MAPNAME, @@ -672,6 +690,22 @@ enum ProjectileLabel_t }; #if !defined LUNATIC +enum IterationTypes_t +{ + ITER_ALLSPRITES, + ITER_ALLSECTORS, + ITER_ALLWALLS, + ITER_ACTIVELIGHTS, + ITER_DRAWNSPRITES, + // --- + ITER_SPRITESOFSECTOR, + ITER_SPRITESOFSTATUS, + ITER_WALLSOFSECTOR, + ITER_LOOPOFWALL, + ITER_RANGE, + ITER_END +}; + enum ScriptKeywords_t { CON_DEFINELEVELNAME, // 0 @@ -1070,6 +1104,7 @@ enum ScriptKeywords_t CON_IFVARGE, // 393 CON_IFVARBOTH, // 394 CON_MOVESECTOR, // 395 + CON_FOR, // 396 CON_END }; // KEEPINSYNC with the keyword list in lunatic/con_lang.lua diff --git a/polymer/eduke32/source/gameexec.c b/polymer/eduke32/source/gameexec.c index 582c98990..48badf118 100644 --- a/polymer/eduke32/source/gameexec.c +++ b/polymer/eduke32/source/gameexec.c @@ -1,6 +1,6 @@ //------------------------------------------------------------------------- /* -Copyright (C) 2010 EDuke32 developers and contributors +Copyright (C) 2016 EDuke32 developers and contributors This file is part of EDuke32. @@ -19,6 +19,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ //------------------------------------------------------------------------- + #include "compat.h" #include @@ -5239,6 +5240,151 @@ finish_qsprintf: continue; } + case CON_FOR: // special-purpose iteration + insptr++; + { + const int32_t var = *insptr++, how = *insptr++; + const int32_t parm2 = how<=ITER_DRAWNSPRITES ? 0 : Gv_GetVarX(*insptr++); + intptr_t const *const end = insptr + *insptr, *const beg = ++insptr; + + switch (how) + { + case ITER_ALLSPRITES: + for (int jj=0; jj= MAXSECTORS) goto badindex; + for (int jj=headspritesect[parm2]; jj>=0; jj=nextspritesect[jj]) + { + Gv_SetVarX(var, jj); + insptr = beg; + VM_Execute(0); + } + break; + case ITER_SPRITESOFSTATUS: + if ((unsigned) parm2 >= MAXSTATUS) goto badindex; + for (int jj=headspritestat[parm2]; jj>=0; jj=nextspritestat[jj]) + { + Gv_SetVarX(var, jj); + insptr = beg; + VM_Execute(0); + } + break; + case ITER_WALLSOFSECTOR: + if ((unsigned) parm2 >= MAXSECTORS) goto badindex; + for (int jj=sector[parm2].wallptr, endwall=jj+sector[parm2].wallnum-1; + jj<=endwall; jj++) + { + Gv_SetVarX(var, jj); + insptr = beg; + VM_Execute(0); + } + break; + case ITER_LOOPOFWALL: + if ((unsigned) parm2 >= numwalls) goto badindex; + { + int jj = parm2; + do + { + Gv_SetVarX(var, jj); + insptr = beg; + VM_Execute(0); + jj = wall[jj].point2; + } while (jj != parm2); + } + break; + case ITER_RANGE: + for (int jj=0; jj