New commands: "divr", "divru", "divrd"

divr <dividend> <divisor>

Divide gamevar <dividend> by <divisor> and round (aka round to nearest) the result. A result of 0.5 will equal 1.

divru <dividend> <divisor>

Divide gamevar <dividend> by <divisor> and round up (aka round away from zero) the result.

Additionally "divrd" can be used to round down (aka round toward zero), which is equivalent to the current div command as tested on x86, ARM, and PowerPC.

Note that "shiftr" rounds up negative values.

Patch from Fox.

git-svn-id: https://svn.eduke32.com/eduke32@6611 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
hendricks266 2018-01-29 02:14:04 +00:00
parent 29de10fc91
commit e1e5e338dc
3 changed files with 43 additions and 0 deletions

View file

@ -181,6 +181,9 @@ static tokenmap_t const vm_keywords[] =
{ "displayrandvar", CON_DISPLAYRANDVAR },
{ "displayrandvarvar", CON_DISPLAYRANDVARVAR },
{ "dist", CON_DIST },
{ "divr", CON_DIVR },
{ "divrd", CON_DIVVARVAR }, // div round toward zero -- alias until proven otherwise
{ "divru", CON_DIVRU },
{ "divscale", CON_DIVSCALE },
{ "divvar", CON_DIVVAR },
{ "divvarvar", CON_DIVVARVAR },
@ -4080,6 +4083,8 @@ DO_DEFSTATE:
case CON_PREVSPRITESECT:
case CON_NEXTSPRITESECT:
case CON_SECTOROFWALL:
case CON_DIVR:
case CON_DIVRU:
C_GetNextVarType(GAMEVAR_READONLY);
fallthrough__;
case CON_ADDLOGVAR:

View file

@ -1169,6 +1169,8 @@ enum ScriptKeywords_t
CON_STARTSCREEN, // 409
CON_SCREENPAL, // 410
CON_QSTRCMP, // 411
CON_DIVR, // 412
CON_DIVRU, // 413
CON_END
};
// KEEPINSYNC with the keyword list in lunatic/con_lang.lua

View file

@ -4886,6 +4886,42 @@ finish_qsprintf:
continue;
}
case CON_DIVR: // div round to nearest
insptr++;
{
tw = *insptr++;
int const dividend = Gv_GetVarX(tw);
int const divisor = Gv_GetVarX(*insptr++);
if (EDUKE32_PREDICT_FALSE(!divisor))
{
CON_CRITICALERRPRINTF("divide by zero!\n");
continue;
}
Gv_SetVarX(tw, tabledivide32((dividend - ksgn(dividend) * klabs(divisor / 2)), divisor));
continue;
}
case CON_DIVRU: // div round away from zero
insptr++;
{
tw = *insptr++;
int const dividend = Gv_GetVarX(tw);
int const divisor = Gv_GetVarX(*insptr++);
if (EDUKE32_PREDICT_FALSE(!divisor))
{
CON_CRITICALERRPRINTF("divide by zero!\n");
continue;
}
Gv_SetVarX(tw, tabledivide32((dividend - ksgn(dividend) * klabs(divisor) + 1), divisor));
continue;
}
case CON_MODVARVAR:
insptr++;
{