diff --git a/source/duke3d/src/gamevars.h b/source/duke3d/src/gamevars.h index 2f3362585..c45c194e1 100644 --- a/source/duke3d/src/gamevars.h +++ b/source/duke3d/src/gamevars.h @@ -208,82 +208,74 @@ static FORCE_INLINE void __fastcall VM_SetStruct(uint32_t const flags, intptr_t } } -#define VM_GAMEVAR_OPERATOR(func, operator) \ - static FORCE_INLINE void __fastcall func(int const id, int32_t const operand) \ - { \ - auto &var = aGameVars[id]; \ - \ - switch (var.flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) \ - { \ - default: var.global operator operand; break; \ - case GAMEVAR_PERPLAYER: \ - if (EDUKE32_PREDICT_FALSE((unsigned)vm.playerNum > MAXPLAYERS - 1)) \ - break; \ - var.pValues[vm.playerNum] operator operand; \ - break; \ - case GAMEVAR_PERACTOR: \ - if (EDUKE32_PREDICT_FALSE((unsigned)vm.spriteNum > MAXSPRITES - 1)) \ - break; \ - var.pValues[vm.spriteNum] operator operand; \ - break; \ - case GAMEVAR_INT32PTR: *(int32_t *)var.pValues operator(int32_t) operand; break; \ - case GAMEVAR_INT16PTR: *(int16_t *)var.pValues operator(int16_t) operand; break; \ - case GAMEVAR_Q16PTR: \ - { \ - Fix16 *pfix = (Fix16 *)var.global; \ - *pfix operator fix16_from_int(operand); \ - break; \ - } \ - } \ +#define VM_GAMEVAR_OPERATOR(func, operator) \ + static FORCE_INLINE ATTRIBUTE((flatten)) void __fastcall func(int const id, int32_t const operand) \ + { \ + auto &var = aGameVars[id]; \ + \ + switch (var.flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) \ + { \ + default: \ + var.global operator operand; \ + break; \ + case GAMEVAR_PERPLAYER: \ + var.pValues[vm.playerNum & (MAXPLAYERS-1)] operator operand; \ + break; \ + case GAMEVAR_PERACTOR: \ + var.pValues[vm.spriteNum & (MAXSPRITES-1)] operator operand; \ + break; \ + case GAMEVAR_INT32PTR: *(int32_t *)var.pValues operator(int32_t) operand; break; \ + case GAMEVAR_INT16PTR: *(int16_t *)var.pValues operator(int16_t) operand; break; \ + case GAMEVAR_Q16PTR: \ + { \ + Fix16 *pfix = (Fix16 *)var.global; \ + *pfix operator fix16_from_int(operand); \ + break; \ + } \ + } \ } -static FORCE_INLINE void __fastcall Gv_DivVar(int const id, int32_t const operand) +static FORCE_INLINE void __fastcall Gv_DivVar(int const id, int32_t const d) { - auto &var = aGameVars[id]; + using namespace libdivide; - if (EDUKE32_PREDICT_FALSE((var.flags & GAMEVAR_PERPLAYER && (unsigned) vm.playerNum > MAXPLAYERS - 1) || - (var.flags & GAMEVAR_PERACTOR && (unsigned) vm.spriteNum > MAXSPRITES - 1))) - return; - - int const foundInTable = (unsigned) operand < DIVTABLESIZE; - static libdivide::libdivide_s32_t sdiv; - intptr_t *iptr = &var.global; + static libdivide_s32_t sdiv; static int32_t lastValue; - auto dptr = foundInTable ? (libdivide::libdivide_s32_t *) &divtable32[operand] : &sdiv; - if (operand == lastValue || foundInTable) - goto skip; + auto &var = aGameVars[id]; + auto *dptr = &sdiv; + auto iptr = &var.global; - sdiv = libdivide::libdivide_s32_gen((lastValue = operand)); - -skip: + if ((unsigned)d < DIVTABLESIZE) + dptr = &divtable32[d]; + else if (d != lastValue) + sdiv = libdivide_s32_gen((lastValue = d)); + switch (var.flags & (GAMEVAR_USER_MASK | GAMEVAR_PTR_MASK)) { - case GAMEVAR_PERACTOR: iptr = &var.pValues[vm.spriteNum]; break; - case GAMEVAR_PERPLAYER: iptr = &var.pValues[vm.playerNum]; - default: break; + case GAMEVAR_PERACTOR: iptr = &var.pValues[vm.spriteNum & (MAXSPRITES-1)]; goto jmp; + case GAMEVAR_PERPLAYER: iptr = &var.pValues[vm.playerNum & (MAXPLAYERS-1)]; fallthrough__; + jmp: default: *iptr = libdivide_s32_do(*iptr, dptr); break; case GAMEVAR_INT32PTR: { - int32_t &value = *(int32_t *)var.pValues; - value = (int32_t)libdivide::libdivide_s32_do(value, dptr); - return; + auto &value = *(int32_t *)var.pValues; + value = libdivide_s32_do(value, dptr); + break; } case GAMEVAR_INT16PTR: { - int16_t &value = *(int16_t *)var.pValues; - value = (int16_t)libdivide::libdivide_s32_do(value, dptr); - return; + auto &value = *(int16_t *)var.pValues; + value = (int16_t)libdivide_s32_do(value, dptr); + break; } case GAMEVAR_Q16PTR: { - fix16_t &value = *(fix16_t *)var.pValues; - value = fix16_div(value, fix16_from_int(operand)); - return; + auto &value = *(fix16_t *)var.pValues; + value = fix16_div(value, fix16_from_int(d)); + break; } } - - *iptr = libdivide_s32_do(*iptr, dptr); } VM_GAMEVAR_OPERATOR(Gv_AddVar, +=)