mirror of https://github.com/arendst/Tasmota.git
Berry `scale_int`, equivalent of `scale_uint` for signed integers (#20090)
This commit is contained in:
parent
1cd13d7f66
commit
1c60527099
|
@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file.
|
||||||
- NeoPool store settings on unified file system (#19973)
|
- NeoPool store settings on unified file system (#19973)
|
||||||
- NeoPool command ``NPBoost`` (#19973)
|
- NeoPool command ``NPBoost`` (#19973)
|
||||||
- ESP32 Partition Wizard can be loaded dynamically (#19980)
|
- ESP32 Partition Wizard can be loaded dynamically (#19980)
|
||||||
|
- Berry `scale_int`, equivalent of `scale_uint` for signed integers
|
||||||
|
|
||||||
### Breaking Changed
|
### Breaking Changed
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ extern int l_yield(bvm *vm);
|
||||||
extern int l_delay(bvm *vm);
|
extern int l_delay(bvm *vm);
|
||||||
extern int l_delay_microseconds(bvm *vm);
|
extern int l_delay_microseconds(bvm *vm);
|
||||||
extern int l_scaleuint(bvm *vm);
|
extern int l_scaleuint(bvm *vm);
|
||||||
|
extern int l_scaleint(bvm *vm);
|
||||||
extern int l_logInfo(bvm *vm);
|
extern int l_logInfo(bvm *vm);
|
||||||
extern int l_loglevel(bvm *vm);
|
extern int l_loglevel(bvm *vm);
|
||||||
extern int l_save(bvm *vm);
|
extern int l_save(bvm *vm);
|
||||||
|
@ -118,6 +119,7 @@ class be_class_tasmota (scope: global, name: Tasmota) {
|
||||||
delay, func(l_delay)
|
delay, func(l_delay)
|
||||||
delay_microseconds, func(l_delay_microseconds)
|
delay_microseconds, func(l_delay_microseconds)
|
||||||
scale_uint, static_func(l_scaleuint)
|
scale_uint, static_func(l_scaleuint)
|
||||||
|
scale_int, static_func(l_scaleint)
|
||||||
log, func(l_logInfo)
|
log, func(l_logInfo)
|
||||||
loglevel, func(l_loglevel)
|
loglevel, func(l_loglevel)
|
||||||
save, func(l_save)
|
save, func(l_save)
|
||||||
|
|
|
@ -376,8 +376,8 @@ float sqrt1(const float x)
|
||||||
//
|
//
|
||||||
// New version, you don't need the "to_min < to_max" precondition anymore
|
// New version, you don't need the "to_min < to_max" precondition anymore
|
||||||
//
|
//
|
||||||
// PRE-CONDITIONS (if not satisfied, you may 'halt and catch fire')
|
// PRE-CONDITIONS (if not satisfied, returns the smallest between to_min and to_max')
|
||||||
// from_min < from_max (not checked)
|
// from_min < from_max (checked)
|
||||||
// from_min <= num <= from_max (checked)
|
// from_min <= num <= from_max (checked)
|
||||||
// POST-CONDITIONS
|
// POST-CONDITIONS
|
||||||
// to_min <= result <= to_max
|
// to_min <= result <= to_max
|
||||||
|
@ -427,6 +427,38 @@ uint16_t changeUIntScale(uint16_t inum, uint16_t ifrom_min, uint16_t ifrom_max,
|
||||||
return (uint32_t) (result > to_max ? to_max : (result < to_min ? to_min : result));
|
return (uint32_t) (result > to_max ? to_max : (result < to_min ? to_min : result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// changeIntScale
|
||||||
|
// Change a value for range a..b to c..d, for signed ints (16 bits max to avoid overflow)
|
||||||
|
//
|
||||||
|
// PRE-CONDITIONS (if not satisfied, returns the smallest between to_min and to_max')
|
||||||
|
// from_min < from_max (checked)
|
||||||
|
// from_min <= num <= from_max (checked)
|
||||||
|
// POST-CONDITIONS
|
||||||
|
// to_min <= result <= to_max
|
||||||
|
//
|
||||||
|
int16_t changeIntScale(int16_t num, int16_t from_min, int16_t from_max,
|
||||||
|
int16_t to_min, int16_t to_max) {
|
||||||
|
|
||||||
|
// guard-rails
|
||||||
|
if (from_min >= from_max) {
|
||||||
|
return (to_min > to_max ? to_max : to_min); // invalid input, return arbitrary value
|
||||||
|
}
|
||||||
|
int32_t from_offset = 0;
|
||||||
|
if (from_min < 0) {
|
||||||
|
from_offset = - from_min;
|
||||||
|
}
|
||||||
|
int32_t to_offset = 0;
|
||||||
|
if (to_min < 0) {
|
||||||
|
to_offset = - to_min;
|
||||||
|
}
|
||||||
|
if (to_max < (- to_offset)) {
|
||||||
|
to_offset = - to_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changeUIntScale(num + from_offset, from_min + from_offset, from_max + from_offset, to_min + to_offset, to_max + to_offset) - to_offset;
|
||||||
|
}
|
||||||
|
|
||||||
// Force a float value between two ranges, and adds or substract the range until we fit
|
// Force a float value between two ranges, and adds or substract the range until we fit
|
||||||
float ModulusRangef(float f, float a, float b) {
|
float ModulusRangef(float f, float a, float b) {
|
||||||
if (b <= a) { return a; } // inconsistent, do what we can
|
if (b <= a) { return a; } // inconsistent, do what we can
|
||||||
|
|
|
@ -409,6 +409,24 @@ extern "C" {
|
||||||
be_raise(vm, kTypeError, nullptr);
|
be_raise(vm, kTypeError, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Berry: tasmota.scale_int(int * 5) -> int
|
||||||
|
//
|
||||||
|
int32_t l_scaleint(struct bvm *vm);
|
||||||
|
int32_t l_scaleint(struct bvm *vm) {
|
||||||
|
int32_t top = be_top(vm); // Get the number of arguments
|
||||||
|
if (top == 5 && be_isint(vm, 1) && be_isint(vm, 2) && be_isint(vm, 3) && be_isint(vm, 4) && be_isint(vm, 5)) {
|
||||||
|
int32_t val = be_toint(vm, 1);
|
||||||
|
int32_t from_min = be_toint(vm, 2);
|
||||||
|
int32_t from_max = be_toint(vm, 3);
|
||||||
|
int32_t to_min = be_toint(vm, 4);
|
||||||
|
int32_t to_max = be_toint(vm, 5);
|
||||||
|
int32_t scaled = changeIntScale(val, from_min, from_max, to_min, to_max);
|
||||||
|
be_pushint(vm, scaled);
|
||||||
|
be_return(vm);
|
||||||
|
}
|
||||||
|
be_raise(vm, kTypeError, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t l_respCmnd(bvm *vm);
|
int32_t l_respCmnd(bvm *vm);
|
||||||
int32_t l_respCmnd(bvm *vm) {
|
int32_t l_respCmnd(bvm *vm) {
|
||||||
int32_t top = be_top(vm); // Get the number of arguments
|
int32_t top = be_top(vm); // Get the number of arguments
|
||||||
|
|
Loading…
Reference in New Issue