Menus: Clean up MenuRanges.

git-svn-id: https://svn.eduke32.com/eduke32@6402 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
hendricks266 2017-07-29 20:39:53 +00:00
parent 33c138fdf9
commit 88d5da2859
2 changed files with 91 additions and 83 deletions

View file

@ -123,6 +123,17 @@ static inline int32_t scale(int32_t eax, int32_t edx, int32_t ecx)
return dw(tabledivide64(numer, ecx)); return dw(tabledivide64(numer, ecx));
} }
static inline int32_t scaleadd(int32_t eax, int32_t edx, int32_t addend, int32_t ecx)
{
const int64_t numer = qw(eax) * edx + addend;
return dw(tabledivide64(numer, ecx));
}
static FORCE_INLINE int32_t roundscale(int32_t eax, int32_t edx, int32_t ecx)
{
return scaleadd(eax, edx, ecx / 2, ecx);
}
static FORCE_INLINE int32_t sqr(int32_t a) { return a * a; } static FORCE_INLINE int32_t sqr(int32_t a) { return a * a; }
#if defined(__GNUC__) && defined(GEKKO) #if defined(__GNUC__) && defined(GEKKO)

View file

@ -4360,23 +4360,20 @@ static int32_t M_RunMenu_Menu(Menu_t *cm, MenuMenu_t *menu, MenuEntry_t *current
{ {
status |= MT_XRight; status |= MT_XRight;
if (object->onehundredpercent == 0) int32_t onehundredpercent = object->onehundredpercent;
object->onehundredpercent = object->max; if (onehundredpercent == 0)
onehundredpercent = object->max;
switch (object->flags & DisplayTypeMask) switch (object->flags & DisplayTypeMask)
{ {
case 1: case DisplayTypeInteger:
Bsprintf(tempbuf, "%d", *object->variable); Bsprintf(tempbuf, "%d", *object->variable);
break; break;
case 2: case DisplayTypePercent:
{ Bsprintf(tempbuf, "%d%%", roundscale(*object->variable, 100, onehundredpercent));
int32_t v;
v = Blrintf(((float) *object->variable * 100.f) / (float) object->onehundredpercent);
Bsprintf(tempbuf, "%d%%", v);
break; break;
} case DisplayTypeNormalizedDecimal:
case 3: Bsprintf(tempbuf, "%.2f", (double) *object->variable / (double) onehundredpercent);
Bsprintf(tempbuf, "%.2f", (double) *object->variable / (double) object->onehundredpercent);
break; break;
} }
@ -4405,7 +4402,7 @@ static int32_t M_RunMenu_Menu(Menu_t *cm, MenuMenu_t *menu, MenuEntry_t *current
// region between the x-midline of the slidepoint at the extremes slides proportionally // region between the x-midline of the slidepoint at the extremes slides proportionally
if (!Menu_MouseOutsideBounds(&m_mousepos, slideregionx, mousey, slideregionwidth, height)) if (!Menu_MouseOutsideBounds(&m_mousepos, slideregionx, mousey, slideregionwidth, height))
{ {
Menu_RunInput_EntryRangeInt32_MovementArbitrary(entry, object, Blrintf((float)((object->max - object->min) * (m_mousepos.x - slideregionx)) / slideregionwidth + object->min)); Menu_RunInput_EntryRangeInt32_MovementArbitrary(entry, object, roundscale(object->max - object->min, m_mousepos.x - slideregionx, slideregionwidth) + object->min);
m_mousecaught = 1; m_mousecaught = 1;
} }
@ -4446,7 +4443,7 @@ static int32_t M_RunMenu_Menu(Menu_t *cm, MenuMenu_t *menu, MenuEntry_t *current
rotatesprite_ybounds(slidebarx, slidebary, z, 0, SLIDEBAR, s, (entry->flags & (MEF_Disabled|MEF_LookDisabled)) ? 1 : 0, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower); rotatesprite_ybounds(slidebarx, slidebary, z, 0, SLIDEBAR, s, (entry->flags & (MEF_Disabled|MEF_LookDisabled)) ? 1 : 0, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower);
const int32_t slideregionwidth = mulscale16((tilesiz[SLIDEBAR].x-2-tilesiz[SLIDEBAR+1].x)<<16, z); const int32_t slideregionwidth = mulscale16((tilesiz[SLIDEBAR].x-2-tilesiz[SLIDEBAR+1].x)<<16, z);
const int32_t slidepointx = slidebarx + (1<<16) + (int32_t)((float) slideregionwidth * (*object->variable - object->min) / (object->max - object->min)); const int32_t slidepointx = slidebarx + (1<<16) + Blrintf((float) slideregionwidth * (*object->variable - object->min) / (object->max - object->min));
const int32_t slidepointy = slidebary + mulscale16((tilesiz[SLIDEBAR].y-tilesiz[SLIDEBAR+1].y)<<15, z); const int32_t slidepointy = slidebary + mulscale16((tilesiz[SLIDEBAR].y-tilesiz[SLIDEBAR+1].y)<<15, z);
rotatesprite_ybounds(slidepointx, slidepointy, z, 0, SLIDEBAR+1, s, (entry->flags & (MEF_Disabled|MEF_LookDisabled)) ? 1 : 0, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower); rotatesprite_ybounds(slidepointx, slidepointy, z, 0, SLIDEBAR+1, s, (entry->flags & (MEF_Disabled|MEF_LookDisabled)) ? 1 : 0, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower);
@ -4455,23 +4452,20 @@ static int32_t M_RunMenu_Menu(Menu_t *cm, MenuMenu_t *menu, MenuEntry_t *current
{ {
status |= MT_XRight; status |= MT_XRight;
if (object->onehundredpercent == 0) float onehundredpercent = object->onehundredpercent;
object->onehundredpercent = 1.f; if (onehundredpercent == 0.f)
onehundredpercent = 1.f;
switch (object->flags & DisplayTypeMask) switch (object->flags & DisplayTypeMask)
{ {
case 1: case DisplayTypeInteger:
Bsprintf(tempbuf, "%.2f", *object->variable); Bsprintf(tempbuf, "%.2f", *object->variable);
break; break;
case 2: case DisplayTypePercent:
{ Bsprintf(tempbuf, "%d%%", Blrintf(*object->variable * 100.f / onehundredpercent));
int32_t v;
v = Blrintf((*object->variable * 100.f) / object->onehundredpercent);
Bsprintf(tempbuf, "%d%%", v);
break; break;
} case DisplayTypeNormalizedDecimal:
case 3: Bsprintf(tempbuf, "%.2f", *object->variable / onehundredpercent);
Bsprintf(tempbuf, "%.2f", *object->variable / object->onehundredpercent);
break; break;
} }
@ -4541,7 +4535,7 @@ static int32_t M_RunMenu_Menu(Menu_t *cm, MenuMenu_t *menu, MenuEntry_t *current
rotatesprite_ybounds(slidebarx, slidebary, z, 0, SLIDEBAR, s, (entry->flags & (MEF_Disabled|MEF_LookDisabled)) ? 1 : 0, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower); rotatesprite_ybounds(slidebarx, slidebary, z, 0, SLIDEBAR, s, (entry->flags & (MEF_Disabled|MEF_LookDisabled)) ? 1 : 0, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower);
const int32_t slideregionwidth = mulscale16((tilesiz[SLIDEBAR].x-2-tilesiz[SLIDEBAR+1].x)<<16, z); const int32_t slideregionwidth = mulscale16((tilesiz[SLIDEBAR].x-2-tilesiz[SLIDEBAR+1].x)<<16, z);
const int32_t slidepointx = slidebarx + (1<<16) + (int32_t)((double) slideregionwidth * (*object->variable - object->min) / (object->max - object->min)); const int32_t slidepointx = slidebarx + (1<<16) + lrint((double) slideregionwidth * (*object->variable - object->min) / (object->max - object->min));
const int32_t slidepointy = slidebary + mulscale16((tilesiz[SLIDEBAR].y-tilesiz[SLIDEBAR+1].y)<<15, z); const int32_t slidepointy = slidebary + mulscale16((tilesiz[SLIDEBAR].y-tilesiz[SLIDEBAR+1].y)<<15, z);
rotatesprite_ybounds(slidepointx, slidepointy, z, 0, SLIDEBAR+1, s, (entry->flags & (MEF_Disabled|MEF_LookDisabled)) ? 1 : 0, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower); rotatesprite_ybounds(slidepointx, slidepointy, z, 0, SLIDEBAR+1, s, (entry->flags & (MEF_Disabled|MEF_LookDisabled)) ? 1 : 0, 2|8|16|ROTATESPRITE_FULL16, ydim_upper, ydim_lower);
@ -4550,23 +4544,20 @@ static int32_t M_RunMenu_Menu(Menu_t *cm, MenuMenu_t *menu, MenuEntry_t *current
{ {
status |= MT_XRight; status |= MT_XRight;
if (object->onehundredpercent == 0) double onehundredpercent = object->onehundredpercent;
object->onehundredpercent = 1.; if (onehundredpercent == 0.)
onehundredpercent = 1.;
switch (object->flags & DisplayTypeMask) switch (object->flags & DisplayTypeMask)
{ {
case 1: case DisplayTypeInteger:
Bsprintf(tempbuf, "%.2f", *object->variable); Bsprintf(tempbuf, "%.2f", *object->variable);
break; break;
case 2: case DisplayTypePercent:
{ Bsprintf(tempbuf, "%ld%%", lrint(*object->variable * 100. / onehundredpercent));
int32_t v;
v = Blrintf((*object->variable * 100.) / object->onehundredpercent);
Bsprintf(tempbuf, "%d%%", v);
break; break;
} case DisplayTypeNormalizedDecimal:
case 3: Bsprintf(tempbuf, "%.2f", *object->variable / onehundredpercent);
Bsprintf(tempbuf, "%.2f", *object->variable / object->onehundredpercent);
break; break;
} }
@ -5357,10 +5348,10 @@ static void Menu_RunInput_EntryRangeInt32_MovementArbitrary(MenuEntry_t *entry,
{ {
if (object->flags & EnforceIntervals) if (object->flags & EnforceIntervals)
{ {
const float interval = ((float) (object->max - object->min)) / (object->steps - 1); int32_t const range = object->max - object->min;
const float currentPos = (float) (newValue - object->min) / interval; int32_t const maxInterval = object->steps - 1;
const int32_t newValueIndex = Blrintf(currentPos); int32_t const newValueIndex = roundscale(newValue - object->min, maxInterval, range);
newValue = Blrintf(interval * newValueIndex + object->min); newValue = roundscale(newValueIndex, range, maxInterval) + object->min;
} }
Menu_RunInput_EntryRangeInt32_MovementVerify(entry, object, newValue); Menu_RunInput_EntryRangeInt32_MovementVerify(entry, object, newValue);
@ -5368,15 +5359,16 @@ static void Menu_RunInput_EntryRangeInt32_MovementArbitrary(MenuEntry_t *entry,
static void Menu_RunInput_EntryRangeInt32_Movement(MenuEntry_t *entry, MenuRangeInt32_t *object, MenuMovement_t direction) static void Menu_RunInput_EntryRangeInt32_Movement(MenuEntry_t *entry, MenuRangeInt32_t *object, MenuMovement_t direction)
{ {
const float interval = ((float) (object->max - object->min)) / (object->steps - 1); int32_t const oldValue = *object->variable;
const float currentPos = (float) (*object->variable - object->min) / interval; int32_t const range = object->max - object->min;
int32_t newValueIndex = Blrintf(currentPos); int32_t const maxInterval = object->steps - 1;
const int32_t newValueProjected = Blrintf(interval * newValueIndex + object->min); int32_t newValueIndex = roundscale(oldValue - object->min, maxInterval, range);
int32_t const newValueProjected = roundscale(newValueIndex, range, maxInterval) + object->min;
switch (direction) switch (direction)
{ {
case MM_Left: case MM_Left:
if (newValueIndex >= currentPos || *object->variable == newValueProjected) if (newValueProjected >= oldValue)
--newValueIndex; --newValueIndex;
if (newValueIndex >= 0) if (newValueIndex >= 0)
break; break;
@ -5386,20 +5378,21 @@ static void Menu_RunInput_EntryRangeInt32_Movement(MenuEntry_t *entry, MenuRange
break; break;
case MM_Right: case MM_Right:
if (newValueIndex <= currentPos || *object->variable == newValueProjected) if (newValueProjected <= oldValue)
++newValueIndex; ++newValueIndex;
if (newValueIndex < object->steps) if (newValueIndex <= maxInterval)
break; break;
fallthrough__; fallthrough__;
case MM_AllTheWayRight: case MM_AllTheWayRight:
newValueIndex = object->steps-1; newValueIndex = maxInterval;
break; break;
default: default:
break; break;
} }
Menu_RunInput_EntryRangeInt32_MovementVerify(entry, object, Blrintf(interval * newValueIndex + object->min)); int32_t const newValue = roundscale(newValueIndex, range, maxInterval) + object->min;
Menu_RunInput_EntryRangeInt32_MovementVerify(entry, object, newValue);
} }
static void Menu_RunInput_EntryRangeFloat_MovementVerify(MenuEntry_t *entry, MenuRangeFloat_t *object, float newValue) static void Menu_RunInput_EntryRangeFloat_MovementVerify(MenuEntry_t *entry, MenuRangeFloat_t *object, float newValue)
@ -5415,10 +5408,10 @@ static void Menu_RunInput_EntryRangeFloat_MovementArbitrary(MenuEntry_t *entry,
{ {
if (object->flags & EnforceIntervals) if (object->flags & EnforceIntervals)
{ {
const float interval = (object->max - object->min) / (object->steps - 1); float const range = object->max - object->min;
const float currentPos = (newValue - object->min) / interval; float const maxInterval = object->steps - 1;
const int32_t newValueIndex = Blrintf(currentPos); float const newValueIndex = rintf((newValue - object->min) * maxInterval / range);
newValue = interval * newValueIndex + object->min; newValue = newValueIndex * range / maxInterval + object->min;
} }
Menu_RunInput_EntryRangeFloat_MovementVerify(entry, object, newValue); Menu_RunInput_EntryRangeFloat_MovementVerify(entry, object, newValue);
@ -5426,38 +5419,40 @@ static void Menu_RunInput_EntryRangeFloat_MovementArbitrary(MenuEntry_t *entry,
static void Menu_RunInput_EntryRangeFloat_Movement(MenuEntry_t *entry, MenuRangeFloat_t *object, MenuMovement_t direction) static void Menu_RunInput_EntryRangeFloat_Movement(MenuEntry_t *entry, MenuRangeFloat_t *object, MenuMovement_t direction)
{ {
const float interval = (object->max - object->min) / (object->steps - 1); float const oldValue = *object->variable;
const float currentPos = (*object->variable - object->min) / interval; float const range = object->max - object->min;
int32_t newValueIndex = Blrintf(currentPos); float const maxInterval = object->steps - 1;
const float newValueProjected = interval * newValueIndex + object->min; float newValueIndex = rintf((oldValue - object->min) * maxInterval / range);
float const newValueProjected = newValueIndex * range / maxInterval + object->min;
switch (direction) switch (direction)
{ {
case MM_Left: case MM_Left:
if (newValueIndex >= currentPos || *object->variable == newValueProjected) if (newValueProjected >= oldValue)
--newValueIndex; newValueIndex -= 1.f;
if (newValueIndex >= 0) if (newValueIndex >= 0.f)
break; break;
fallthrough__; fallthrough__;
case MM_AllTheWayLeft: case MM_AllTheWayLeft:
newValueIndex = 0; newValueIndex = 0.f;
break; break;
case MM_Right: case MM_Right:
if (newValueIndex <= currentPos || *object->variable == newValueProjected) if (newValueProjected <= oldValue)
++newValueIndex; newValueIndex += 1.f;
if (newValueIndex < object->steps) if (newValueIndex <= maxInterval)
break; break;
fallthrough__; fallthrough__;
case MM_AllTheWayRight: case MM_AllTheWayRight:
newValueIndex = object->steps-1; newValueIndex = maxInterval;
break; break;
default: default:
break; break;
} }
Menu_RunInput_EntryRangeFloat_MovementVerify(entry, object, interval * newValueIndex + object->min); float const newValue = newValueIndex * range / maxInterval + object->min;
Menu_RunInput_EntryRangeFloat_MovementVerify(entry, object, newValue);
} }
static void Menu_RunInput_EntryRangeDouble_MovementVerify(/*MenuEntry_t *entry, */MenuRangeDouble_t *object, double newValue) static void Menu_RunInput_EntryRangeDouble_MovementVerify(/*MenuEntry_t *entry, */MenuRangeDouble_t *object, double newValue)
@ -5470,10 +5465,10 @@ static void Menu_RunInput_EntryRangeDouble_MovementArbitrary(/*MenuEntry_t *entr
{ {
if (object->flags & EnforceIntervals) if (object->flags & EnforceIntervals)
{ {
const double interval = (object->max - object->min) / (object->steps - 1); double const range = object->max - object->min;
const double currentPos = (newValue - object->min) / interval; double const maxInterval = object->steps - 1;
const int32_t newValueIndex = Blrintf(currentPos); double const newValueIndex = rint((newValue - object->min) * maxInterval / range);
newValue = interval * newValueIndex + object->min; newValue = newValueIndex * range / maxInterval + object->min;
} }
Menu_RunInput_EntryRangeDouble_MovementVerify(/*entry, */object, newValue); Menu_RunInput_EntryRangeDouble_MovementVerify(/*entry, */object, newValue);
@ -5481,38 +5476,40 @@ static void Menu_RunInput_EntryRangeDouble_MovementArbitrary(/*MenuEntry_t *entr
static void Menu_RunInput_EntryRangeDouble_Movement(/*MenuEntry_t *entry, */MenuRangeDouble_t *object, MenuMovement_t direction) static void Menu_RunInput_EntryRangeDouble_Movement(/*MenuEntry_t *entry, */MenuRangeDouble_t *object, MenuMovement_t direction)
{ {
const double interval = (object->max - object->min) / (object->steps - 1); double const oldValue = *object->variable;
const double currentPos = (*object->variable - object->min) / interval; double const range = object->max - object->min;
int32_t newValueIndex = Blrintf(currentPos); double const maxInterval = object->steps - 1;
const double newValueProjected = interval * newValueIndex + object->min; double newValueIndex = rint((oldValue - object->min) * maxInterval / range);
double const newValueProjected = newValueIndex * range / maxInterval + object->min;
switch (direction) switch (direction)
{ {
case MM_Left: case MM_Left:
if (newValueIndex >= currentPos || *object->variable == newValueProjected) if (newValueProjected >= oldValue)
--newValueIndex; newValueIndex -= 1.;
if (newValueIndex >= 0) if (newValueIndex >= 0.)
break; break;
fallthrough__; fallthrough__;
case MM_AllTheWayLeft: case MM_AllTheWayLeft:
newValueIndex = 0; newValueIndex = 0.;
break; break;
case MM_Right: case MM_Right:
if (newValueIndex <= currentPos || *object->variable == newValueProjected) if (newValueProjected <= oldValue)
++newValueIndex; newValueIndex += 1.;
if (newValueIndex < object->steps) if (newValueIndex <= maxInterval)
break; break;
fallthrough__; fallthrough__;
case MM_AllTheWayRight: case MM_AllTheWayRight:
newValueIndex = object->steps-1; newValueIndex = maxInterval;
break; break;
default: default:
break; break;
} }
Menu_RunInput_EntryRangeDouble_MovementVerify(/*entry, */object, interval * newValueIndex + object->min); double const newValue = newValueIndex * range / maxInterval + object->min;
Menu_RunInput_EntryRangeDouble_MovementVerify(/*entry, */object, newValue);
} }
static void Menu_RunInput_EntryString_Activate(MenuEntry_t *entry) static void Menu_RunInput_EntryString_Activate(MenuEntry_t *entry)