diff --git a/polymer/eduke32/source/duke3d.h b/polymer/eduke32/source/duke3d.h index f89b4a918..6adca470a 100644 --- a/polymer/eduke32/source/duke3d.h +++ b/polymer/eduke32/source/duke3d.h @@ -798,9 +798,13 @@ enum events { // store global game definitions + + enum gamevarflags { - MAXGAMEVARS = 2048, + MAXGAMEVARS = 2048, // must be a power of two + MAXGAMEARRAYS = 256, // must be lower than MAXGAMEVARS MAXVARLABEL = 26, + MAXARRAYLABEL = 26, GAMEVAR_FLAG_NORMAL = 0, // normal GAMEVAR_FLAG_PERPLAYER = 1, // per-player variable GAMEVAR_FLAG_PERACTOR = 2, // per-actor variable @@ -824,9 +828,16 @@ typedef struct { char *szLabel; char bReset; } gamevar_t; - +typedef struct { + char *szLabel; + int *plValues; // array of values + int size; + char bReset; +} gamearray_t; extern gamevar_t aGameVars[MAXGAMEVARS]; +extern gamearray_t aGameArrays[MAXGAMEARRAYS]; extern int iGameVarCount; +extern int iGameArrayCount; extern int spriteflags[MAXTILES]; diff --git a/polymer/eduke32/source/funct.h b/polymer/eduke32/source/funct.h index b3c5210fa..71e3961bc 100644 --- a/polymer/eduke32/source/funct.h +++ b/polymer/eduke32/source/funct.h @@ -220,7 +220,10 @@ extern int ReadGameVars(int fil); extern int GetGameVarID(int id, int iActor, int iPlayer); extern void SetGameVarID(int id, int lValue, int iActor, int iPlayer); +extern void SetGameArrayID(int id,int index, int lValue); + extern int AddGameVar(const char *pszLabel, int lValue, unsigned int dwFlags); +extern int AddGameArray(const char *pszLabel, int asize); extern void ReportError(int iError); extern void onvideomodechange(int newmode); diff --git a/polymer/eduke32/source/game.c b/polymer/eduke32/source/game.c index 96f58b198..9c42f9966 100644 --- a/polymer/eduke32/source/game.c +++ b/polymer/eduke32/source/game.c @@ -9648,6 +9648,14 @@ static void freeconmem(void) Bfree(aGameVars[i].plValues); } + for (i=iGameArrayCount-1;i>=0;i--) + { + if (aGameArrays[i].szLabel != NULL) + Bfree(aGameArrays[i].szLabel); + if (aGameArrays[i].plValues != NULL) + Bfree(aGameArrays[i].plValues); + } + for (i=MAXPLAYERS-1;i>=0;i--) { if (g_player[i].ps != NULL) diff --git a/polymer/eduke32/source/gamedef.c b/polymer/eduke32/source/gamedef.c index 16ae9ba9a..eddde06e0 100644 --- a/polymer/eduke32/source/gamedef.c +++ b/polymer/eduke32/source/gamedef.c @@ -80,7 +80,9 @@ intptr_t *apScriptGameEvent[MAXGAMEEVENTS]; intptr_t *parsing_event=NULL; gamevar_t aGameVars[MAXGAMEVARS]; +gamearray_t aGameArrays[MAXGAMEARRAYS]; int iGameVarCount=0; +int iGameArrayCount=0; extern int qsetmode; @@ -443,6 +445,8 @@ static const char *keyw[] = "spritenopal", // 313 "hitradiusvar", // 314 "rotatesprite16", // 315 + "gamearray", // 316 + "setarray", // 317 "" }; @@ -1203,7 +1207,23 @@ static int GetDefID(const char *szGameLabel) } return -1; } - +static int GetADefID(const char *szGameLabel) +{ + int i; +// initprintf("iGameArrayCount is %i\n",iGameArrayCount); + for (i=0;i= 0) + { + *scriptptr++=i+1+MAXGAMEVARS; + transvartype(0); + + } + else + { + error++; + ReportError(ERROR_NOTAGAMEARRAY); + return; + } + + skipcomments(); //skip comments and whitespace + if (*textptr != ']') + { + error++; + ReportError(ERROR_GAMEARRAYBNC); + return; + } + textptr++; + if (type) //writing arrays in this way is not supported because it would require too many changes to other code + { + error++; + ReportError(ERROR_INVALIDARRAYWRITE); + return; + } + return; + } +// initprintf("not an array"); i=GetDefID(label+(labelcnt<<6)); - if (i<0) + if (i<0) //gamevar not found { if (!type && !labelsonly) { + //try looking for a define instead Bstrcpy(tempbuf,label+(labelcnt<<6)); for (i=0;i (-1)) + { + *scriptptr++=i; + } + else + ReportError(ERROR_NOTAGAMEARRAY); + skipcomments();// skip comments and whitespace + if (*textptr != '[') + { + error++; + ReportError(ERROR_GAMEARRAYBNO); + return 1; + } + textptr++; + transvar(); + skipcomments();// skip comments and whitespace + if (*textptr != ']') + { + error++; + ReportError(ERROR_GAMEARRAYBNC); + return 1; + } + textptr++; + transvar(); + return 0; case CON_RANDVARVAR: if (!CheckEventSync(current_event)) ReportError(WARNING_EVENTSYNC); @@ -3697,7 +3813,9 @@ static int parsecommand(void) j=CountCaseStatements(); // initprintf("Done Counting Case Statements for switch %d: found %d.\n", checking_switch,j); - scriptptr+=j*2;skipcomments();scriptptr-=j*2; // allocate buffer for the table + scriptptr+=j*2; + skipcomments(); + scriptptr-=j*2; // allocate buffer for the table tempscrptr = (intptr_t *)(script+tempoffset); //AddLog(g_szBuf); @@ -5127,6 +5245,18 @@ void ReportError(int iError) case ERROR_NOTAGAMEVAR: initprintf("%s:%d: error: symbol `%s' is not a game variable.\n",compilefile,line_number,label+(labelcnt<<6)); break; + case ERROR_NOTAGAMEARRAY: + initprintf("%s:%d: error: symbol `%s' is not a game array.\n",compilefile,line_number,label+(labelcnt<<6)); + break; + case ERROR_GAMEARRAYBNC: + initprintf("%s:%d: error: square brackets for index of game array not closed, expected ] found %c\n",compilefile,line_number,*textptr); + break; + case ERROR_GAMEARRAYBNO: + initprintf("%s:%d: error: square brackets for index of game array not opened, expected [ found %c\n",compilefile,line_number,*textptr); + break; + case ERROR_INVALIDARRAYWRITE: + initprintf("%s:%d: error: arrays can only be written using setarray %c\n",compilefile,line_number,*textptr); + break; case ERROR_OPENBRACKET: initprintf("%s:%d: error: found more `{' than `}' before `%s'.\n",compilefile,line_number,tempbuf); break; diff --git a/polymer/eduke32/source/gamedef.h b/polymer/eduke32/source/gamedef.h index af4f67211..f2be415ab 100644 --- a/polymer/eduke32/source/gamedef.h +++ b/polymer/eduke32/source/gamedef.h @@ -83,6 +83,10 @@ enum errors ERROR_NOENDSWITCH, ERROR_NOTAGAMEDEF, ERROR_NOTAGAMEVAR, + ERROR_NOTAGAMEARRAY, + ERROR_GAMEARRAYBNC, + ERROR_GAMEARRAYBNO, + ERROR_INVALIDARRAYWRITE, ERROR_OPENBRACKET, ERROR_PARAMUNDEFINED, ERROR_SYMBOLNOTRECOGNIZED, @@ -801,5 +805,6 @@ enum keywords CON_SPRITENOPAL, // 313 CON_HITRADIUSVAR, // 314 CON_ROTATESPRITE16, // 315 - END + CON_GAMEARRAY, // 316 + CON_SETARRAY, // 317 }; diff --git a/polymer/eduke32/source/gameexec.c b/polymer/eduke32/source/gameexec.c index bdf6ed0f6..578e02d69 100644 --- a/polymer/eduke32/source/gameexec.c +++ b/polymer/eduke32/source/gameexec.c @@ -6758,6 +6758,16 @@ static int parse(void) SetGameVarID(*insptr, *(insptr+1), g_i, g_p); insptr += 2; break; + case CON_SETARRAY: + insptr++; + j=*insptr++; + { + int index = GetGameVarID(*insptr++, g_i, g_p); + int value = GetGameVarID(*insptr++, g_i, g_p); + + SetGameArrayID(j,index,value); + break; + } case CON_RANDVAR: insptr++; @@ -7273,8 +7283,13 @@ static int parse(void) break; default: - OSD_Printf("fatal error: default processing: prev inst: %d, curr inst: %d, next inst: %d\ncurrent actor: %d (%d)\n",*(insptr-1),*insptr,*(insptr+1),g_i,g_sp->picnum); - gameexit("An error has occurred in the EDuke32 CON executor.\n\nPlease mail all of your CON files along with the file eduke32.log\nto terminx@gmail.com.\n\nThank you."); + OSD_Printf("fatal error: default processing: previous five values: %d, %d, %d, %d, %d, currrent opcode: %d, next five values: %d, %d, %d, %d, %d\ncurrent actor: %d (%d)\n",*(insptr-5),*(insptr-4),*(insptr-3),*(insptr-2),*(insptr-1),*insptr,*(insptr+1),*(insptr+2),*(insptr+3),*(insptr+4),*(insptr+5),g_i,g_sp->picnum); + gameexit("An error has occurred in the EDuke32 CON executor.\n\n\ + If you are an end user, please e-mail the file eduke32.log\n\ + along with links to any mods you're using to terminx@gmail.com.\n\n\ + If you are a mod developer, please attach all of your CON files\n\ + along with instructions on how to reproduce this error.\n\n\ + Thank you."); break; } return 0; diff --git a/polymer/eduke32/source/gamevars.c b/polymer/eduke32/source/gamevars.c index cf3e10324..2797fc630 100755 --- a/polymer/eduke32/source/gamevars.c +++ b/polymer/eduke32/source/gamevars.c @@ -49,6 +49,14 @@ static void FreeGameVars(void) aGameVars[i].bReset=1; } iGameVarCount=0; + for (i=0;i (MAXARRAYLABEL-1)) + { + error++; + ReportError(-1); + initprintf("%s:%d: error: array name `%s' exceeds limit of %d characters.\n",compilefile,line_number,pszLabel, MAXARRAYLABEL); + return 0; + } + for (i=0;i= iGameVarCount) { if (id==MAXGAMEVARS) + { +// OSD_Printf("GetGameVarID(): reading gamevar constant\n"); return(*insptr++); - + } + if (id < MAXGAMEVARS+1+MAXGAMEARRAYS) + { + int index=0; +// OSD_Printf("GetGameVarID(): reading from array\n"); + index=GetGameVarID(*insptr++,iActor,iPlayer); + if ((index < aGameArrays[id-MAXGAMEVARS-1].size)&&(index>=0)) + inv =aGameArrays[id-MAXGAMEVARS-1].plValues[index]; + else + gameexit("array"); + return(inv); + } if (!(id&(MAXGAMEVARS<<1))) { OSD_Printf("GetGameVarID(): invalid gamevar ID (%d)\n",id); @@ -491,7 +612,18 @@ int GetGameVarID(int id, int iActor, int iPlayer) if (inv) return(-aGameVars[id].lValue); return (aGameVars[id].lValue); } - +void SetGameArrayID(int id,int index, int lValue) +{ + if (id<0 || id >= iGameArrayCount) + { + OSD_Printf("SetGameVarID(): tried to set invalid gamevar ID (%d) from sprite %d (%d), player %d\n",id,g_i,sprite[g_i].picnum,g_p); + return; + } + if ((index < aGameArrays[id].size)&&(index>=0)) + aGameArrays[id].plValues[index]=lValue; + else + gameexit("array1"); +} void SetGameVarID(int id, int lValue, int iActor, int iPlayer) { if (id<0 || id >= iGameVarCount)