Implement Mapster32's CON_FOR into EDuke32.

git-svn-id: https://svn.eduke32.com/eduke32@5604 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
terminx 2016-02-02 00:21:24 +00:00
parent 2ad6e2811a
commit 03b0335130
3 changed files with 240 additions and 10 deletions

View file

@ -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
"<null>"
};
#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))

View file

@ -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

View file

@ -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 <time.h>
@ -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<MAXSPRITES; jj++)
{
if (sprite[jj].statnum == MAXSTATUS)
continue;
Gv_SetVarX(var, jj);
insptr = beg;
VM_Execute(0);
}
break;
case ITER_ALLSECTORS:
for (int jj=0; jj<numsectors; jj++)
{
Gv_SetVarX(var, jj);
insptr = beg;
VM_Execute(0);
}
break;
case ITER_ALLWALLS:
for (int jj=0; jj<numwalls; jj++)
{
Gv_SetVarX(var, jj);
insptr = beg;
VM_Execute(0);
}
break;
case ITER_ACTIVELIGHTS:
#ifdef POLYMER
for (int jj=0; jj<PR_MAXLIGHTS; jj++)
{
if (!prlights[jj].flags.active)
continue;
Gv_SetVarX(var, jj);
insptr = beg;
VM_Execute(0);
}
#endif
break;
case ITER_DRAWNSPRITES:
{
/*
tspritetype lastSpriteBackup;
tspritetype *const lastSpritePtr = (tspritetype *) &sprite[MAXSPRITES-1];
*/
// Back up sprite MAXSPRITES-1.
/*
Bmemcpy(&lastSpriteBackup, lastSpritePtr, sizeof(tspritetype));
*/
for (int ii=0; ii<spritesortcnt; ii++)
{
/*
Bmemcpy(lastSpritePtr, &tsprite[ii], sizeof(tspritetype));
*/
Gv_SetVarX(var, ii);
insptr = beg;
VM_Execute(0);
// Copy over potentially altered tsprite.
/*
Bmemcpy(&tsprite[ii], lastSpritePtr, sizeof(tspritetype));
*/
}
// Restore sprite MAXSPRITES-1.
/*
Bmemcpy(lastSpritePtr, &lastSpriteBackup, sizeof(tspritetype));
*/
break;
}
case ITER_SPRITESOFSECTOR:
if ((unsigned)parm2 >= 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<parm2; jj++)
{
Gv_SetVarX(var, jj);
insptr = beg;
VM_Execute(0);
}
break;
default:
CON_ERRPRINTF("Unknown iteration type %d!", how);
continue;
badindex:
OSD_Printf(OSD_ERROR "Line %d, %s %s: index %d out of range!\n", g_errorLineNum, keyw[g_tw],
iter_tokens[how].token, parm2);
continue;
}
insptr = end;
}
continue;
case CON_IFVARAND:
insptr++;
tw = Gv_GetVarX(*insptr++);