From 01d92aeed2fb3f55254f27b9a69f8c4725d6b318 Mon Sep 17 00:00:00 2001 From: terminx Date: Tue, 11 Jul 2017 04:02:52 +0000 Subject: [PATCH] Syntax changes for gamevar and gamearray declarations: Gamevar: default value and flags are now optional. A var declared without a value will default to 0 and a var declared without flags will default to global. Multiple flags can now be stacked one after another in a var declaration, and the most useful ones (GAMEVAR_PERPLAYER, GAMEVAR_PERACTOR, GAMEVAR_NODEFAULT, and GAMEVAR_NORESET) are now pre-defined tokens for easy use. Gamearray: flags field now allows stacking of multiple flags as described above. Arrays can now be defined with specific data types, including int16_t, uint8_t, and a new bit-packed boolean data type. The tokens GAMEARRAY_RESTORE, GAMEARRAY_INT16, GAMEARRAY_UINT8, and GAMEARRAY_BOOLEAN are pre-defined for use of this feature. This is all still pretty experimental. git-svn-id: https://svn.eduke32.com/eduke32@6356 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/duke3d/src/gamedef.cpp | 67 +++++++++++----- source/duke3d/src/gamevars.cpp | 138 ++++++++++++++++----------------- source/duke3d/src/gamevars.h | 68 ++++++++-------- source/duke3d/src/savegame.cpp | 4 +- 4 files changed, 153 insertions(+), 124 deletions(-) diff --git a/source/duke3d/src/gamedef.cpp b/source/duke3d/src/gamedef.cpp index c4242c164..3ee9a5a25 100644 --- a/source/duke3d/src/gamedef.cpp +++ b/source/duke3d/src/gamedef.cpp @@ -2824,8 +2824,7 @@ static inline void C_BitOrNextValue(int32_t *valptr) static inline void C_FinishBitOr(int32_t value) { BITPTR_CLEAR(g_scriptPtr-apScript); - *g_scriptPtr = value; - g_scriptPtr++; + *g_scriptPtr++ = value; } static void C_FillEventBreakStackWithJump(intptr_t *breakPtr, intptr_t destination) @@ -2991,6 +2990,7 @@ DO_DEFSTATE: } case CON_GAMEVAR: + { // syntax: gamevar // defines var1 and sets initial value. // flags are used to define usage @@ -3002,33 +3002,52 @@ DO_DEFSTATE: g_errorCnt++; C_ReportError(ERROR_SYNTAXERROR); C_GetNextValue(LABEL_DEFINE); - C_GetNextValue(LABEL_DEFINE); + j = 0; + while (C_GetKeyword() == -1) + C_BitOrNextValue(&j); + C_FinishBitOr(j); g_scriptPtr -= 3; // we complete the process anyways just to skip past the fucked up section continue; } + g_scriptPtr--; + C_GetNextLabelName(); - if (EDUKE32_PREDICT_FALSE(hash_find(&h_keywords,label+(g_labelCnt<<6))>=0)) + if (EDUKE32_PREDICT_FALSE(hash_find(&h_keywords, label+(g_labelCnt<<6))>=0)) { g_warningCnt++; C_ReportError(WARNING_VARMASKSKEYWORD); hash_delete(&h_keywords, label+(g_labelCnt<<6)); } - C_GetNextValue(LABEL_DEFINE); // get initial value - C_GetNextValue(LABEL_DEFINE); // get flags + int32_t defaultValue = 0; + int32_t varFlags = 0; - if (EDUKE32_PREDICT_FALSE((*(g_scriptPtr-1)&GAMEVAR_USER_MASK)==3)) + if (C_GetKeyword() == -1) { - g_warningCnt++; - *(g_scriptPtr-1)^=GAMEVAR_PERPLAYER; - C_ReportError(WARNING_BADGAMEVAR); + C_GetNextValue(LABEL_DEFINE); // get initial value + defaultValue = *(--g_scriptPtr); + + j = 0; + + while (C_GetKeyword() == -1) + C_BitOrNextValue(&j); + + C_FinishBitOr(j); + varFlags = *(--g_scriptPtr); + + if (EDUKE32_PREDICT_FALSE((*(g_scriptPtr)&GAMEVAR_USER_MASK)==(GAMEVAR_PERPLAYER|GAMEVAR_PERACTOR))) + { + g_warningCnt++; + varFlags ^= GAMEVAR_PERPLAYER; + C_ReportError(WARNING_BADGAMEVAR); + } } - Gv_NewVar(label+(g_labelCnt<<6), *(g_scriptPtr-2), (*(g_scriptPtr-1)) & (~GAMEVAR_DEFAULT)); - g_scriptPtr -= 3; + Gv_NewVar(label+(g_labelCnt<<6), defaultValue, varFlags); continue; + } case CON_GAMEARRAY: { @@ -3061,14 +3080,15 @@ DO_DEFSTATE: C_GetNextValue(LABEL_DEFINE); char const * const arrayName = label+(g_labelCnt<<6); - int arrayFlags = GAMEARRAY_NORMAL; + int arrayFlags = 0; - if (C_GetKeyword() == -1) - { - C_GetNextValue(LABEL_DEFINE); - arrayFlags = GAMEARRAY_NORMAL | *(g_scriptPtr-1); - g_scriptPtr--; - } + while (C_GetKeyword() == -1) + C_BitOrNextValue(&arrayFlags); + + C_FinishBitOr(arrayFlags); + + arrayFlags = *(g_scriptPtr-1); + g_scriptPtr--; Gv_NewArray(arrayName, NULL, *(g_scriptPtr-1), arrayFlags); @@ -6245,7 +6265,16 @@ static void C_AddDefaultDefinitions(void) C_AddDefinition("PROJ_XREPEAT", PROJ_XREPEAT, LABEL_DEFINE); C_AddDefinition("PROJ_YREPEAT", PROJ_YREPEAT, LABEL_DEFINE); + C_AddDefinition("GAMEVAR_PERPLAYER", GAMEVAR_PERPLAYER, LABEL_DEFINE); + C_AddDefinition("GAMEVAR_PERACTOR", GAMEVAR_PERACTOR, LABEL_DEFINE); + C_AddDefinition("GAMEVAR_NODEFAULT", GAMEVAR_NODEFAULT, LABEL_DEFINE); + C_AddDefinition("GAMEVAR_NORESET", GAMEVAR_NORESET, LABEL_DEFINE); + C_AddDefinition("GAMEVAR_NOMULTI", GAMEVAR_NOMULTI, LABEL_DEFINE); + C_AddDefinition("GAMEARRAY_RESTORE", GAMEARRAY_RESTORE, LABEL_DEFINE); + C_AddDefinition("GAMEARRAY_INT16", GAMEARRAY_INT16, LABEL_DEFINE); + C_AddDefinition("GAMEARRAY_UINT8", GAMEARRAY_UINT8, LABEL_DEFINE); + C_AddDefinition("GAMEARRAY_BOOLEAN", GAMEARRAY_BITMAP, LABEL_DEFINE); C_AddDefinition("MAXSPRITESONSCREEN", MAXSPRITESONSCREEN, LABEL_DEFINE); } diff --git a/source/duke3d/src/gamevars.cpp b/source/duke3d/src/gamevars.cpp index 17db023de..cf9980b64 100644 --- a/source/duke3d/src/gamevars.cpp +++ b/source/duke3d/src/gamevars.cpp @@ -74,7 +74,7 @@ static int Gv_Free(void) for (bssize_t i=0; i MAXPLAYERS - 1)) \ - break; \ - aGameVars[id].pValues[vm.playerNum] operator operand; \ - break; \ - case GAMEVAR_PERACTOR: \ - if (EDUKE32_PREDICT_FALSE((unsigned)vm.spriteNum > MAXSPRITES - 1)) \ - break; \ - aGameVars[id].pValues[vm.spriteNum] operator operand; \ - break; \ - case GAMEVAR_INTPTR: *((int32_t *)aGameVars[id].global) operator(int32_t) operand; break; \ - case GAMEVAR_SHORTPTR: *((int16_t *)aGameVars[id].global) operator(int16_t) operand; break; \ - case GAMEVAR_CHARPTR: *((uint8_t *)aGameVars[id].global) operator(uint8_t) operand; break; \ - } \ +#define VM_GAMEVAR_OPERATOR(func, operator) \ + static FORCE_INLINE void __fastcall func(int const id, int32_t const operand) \ + { \ + switch (aGameVars[id].flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) \ + { \ + default: aGameVars[id].global operator operand; break; \ + case GAMEVAR_PERPLAYER: \ + if (EDUKE32_PREDICT_FALSE((unsigned)vm.playerNum > MAXPLAYERS - 1)) \ + break; \ + aGameVars[id].pValues[vm.playerNum] operator operand; \ + break; \ + case GAMEVAR_PERACTOR: \ + if (EDUKE32_PREDICT_FALSE((unsigned)vm.spriteNum > MAXSPRITES - 1)) \ + break; \ + aGameVars[id].pValues[vm.spriteNum] operator operand; \ + break; \ + case GAMEVAR_INT32PTR: *((int32_t *)aGameVars[id].global) operator(int32_t) operand; break; \ + case GAMEVAR_INT16PTR: *((int16_t *)aGameVars[id].global) operator(int16_t) operand; break; \ + case GAMEVAR_UINT8PTR: *((uint8_t *)aGameVars[id].global) operator(uint8_t) operand; break; \ + } \ } #if defined(__arm__) || defined(LIBDIVIDE_ALWAYS) @@ -193,15 +193,15 @@ skip: case GAMEVAR_PERPLAYER: iptr = &aGameVars[id].pValues[vm.playerNum]; default: break; case GAMEVAR_PERACTOR: iptr = &aGameVars[id].pValues[vm.spriteNum]; break; - case GAMEVAR_INTPTR: + case GAMEVAR_INT32PTR: *((int32_t *)aGameVars[id].global) = (int32_t)libdivide_s32_do(*((int32_t *)aGameVars[id].global), dptr); return; - case GAMEVAR_SHORTPTR: + case GAMEVAR_INT16PTR: *((int16_t *)aGameVars[id].global) = (int16_t)libdivide_s32_do(*((int16_t *)aGameVars[id].global), dptr); return; - case GAMEVAR_CHARPTR: + case GAMEVAR_UINT8PTR: *((uint8_t *)aGameVars[id].global) = (uint8_t)libdivide_s32_do(*((uint8_t *)aGameVars[id].global), dptr); return; diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index a03771836..8688337e8 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -1190,8 +1190,8 @@ static uint8_t *svdiff; #include "gamedef.h" #if !defined LUNATIC -# define SV_SKIPMASK (/*GAMEVAR_SYSTEM|*/GAMEVAR_READONLY|GAMEVAR_INTPTR| \ - GAMEVAR_SHORTPTR|GAMEVAR_CHARPTR /*|GAMEVAR_NORESET*/ |GAMEVAR_SPECIAL) +# define SV_SKIPMASK (/*GAMEVAR_SYSTEM|*/GAMEVAR_READONLY|GAMEVAR_INT32PTR| \ + GAMEVAR_INT16PTR|GAMEVAR_UINT8PTR /*|GAMEVAR_NORESET*/ |GAMEVAR_SPECIAL) static char svgm_vars_string [] = "blK:vars"; // setup gamevar data spec for snapshotting and diffing... gamevars must be loaded when called