mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-09-12 01:29:29 +00:00
Fixes (#3032)
This commit is contained in:
@@ -199,6 +199,7 @@ void BLETxView::send_packet() {
|
|||||||
generateRandomMacAddress(randomMac);
|
generateRandomMacAddress(randomMac);
|
||||||
|
|
||||||
char advertisementData[63] = {0};
|
char advertisementData[63] = {0};
|
||||||
|
packets[current_packet].advertisementData[62] = '\0';
|
||||||
strcpy(advertisementData, packets[current_packet].advertisementData);
|
strcpy(advertisementData, packets[current_packet].advertisementData);
|
||||||
|
|
||||||
// TODO: Make this a checkbox.
|
// TODO: Make this a checkbox.
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
void create_thread(int32_t (*fn)(void*), void* arg, size_t stack_size, int priority) {
|
void create_thread(int32_t (*fn)(void*), void* arg, size_t stack_size, int priority) {
|
||||||
// TODO: collect memory on terminate, once this is used
|
// TODO: collect memory on terminate, once this is used. This is a HUGE TODO! need to call chThdWait on all of them!
|
||||||
chThdCreateFromHeap(NULL, stack_size, priority, fn, arg);
|
chThdCreateFromHeap(NULL, stack_size, priority, fn, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -36,8 +36,11 @@ WipeSDView::WipeSDView(NavigationView& nav)
|
|||||||
}
|
}
|
||||||
|
|
||||||
WipeSDView::~WipeSDView() {
|
WipeSDView::~WipeSDView() {
|
||||||
if (thread)
|
if (thread) {
|
||||||
chThdTerminate(thread);
|
chThdTerminate(thread);
|
||||||
|
chThdWait(thread);
|
||||||
|
thread = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WipeSDView::focus() {
|
void WipeSDView::focus() {
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ Optional<File::Error> File::sync() {
|
|||||||
|
|
||||||
File::Result<std::string> File::read_file(const std::filesystem::path& filename) {
|
File::Result<std::string> File::read_file(const std::filesystem::path& filename) {
|
||||||
constexpr size_t buffer_size = 0x80;
|
constexpr size_t buffer_size = 0x80;
|
||||||
char* buffer[buffer_size];
|
char buffer[buffer_size];
|
||||||
|
|
||||||
File f;
|
File f;
|
||||||
auto error = f.open(filename);
|
auto error = f.open(filename);
|
||||||
@@ -205,6 +205,7 @@ static std::filesystem::path find_last_ordinal_match(
|
|||||||
const std::filesystem::path& pattern,
|
const std::filesystem::path& pattern,
|
||||||
pattern_range range) {
|
pattern_range range) {
|
||||||
auto last_match = std::filesystem::path();
|
auto last_match = std::filesystem::path();
|
||||||
|
if (range.start == std::string::npos || range.end == std::string::npos || range.start > range.end) return last_match;
|
||||||
auto can_increment = [range](const auto& path) {
|
auto can_increment = [range](const auto& path) {
|
||||||
for (auto i = range.start; i <= range.end; ++i)
|
for (auto i = range.start; i <= range.end; ++i)
|
||||||
if (!isdigit(path.native()[i]))
|
if (!isdigit(path.native()[i]))
|
||||||
@@ -230,7 +231,7 @@ static std::filesystem::path increment_filename_ordinal(
|
|||||||
const std::filesystem::path& path,
|
const std::filesystem::path& path,
|
||||||
pattern_range range) {
|
pattern_range range) {
|
||||||
auto name = path.filename().native();
|
auto name = path.filename().native();
|
||||||
|
if (range.start == std::string::npos || range.end == std::string::npos || range.start > range.end) return {name};
|
||||||
for (auto i = range.end; i >= range.start; --i) {
|
for (auto i = range.end; i >= range.start; --i) {
|
||||||
auto& c = name[i];
|
auto& c = name[i];
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ class BufferLineReader {
|
|||||||
std::strncpy(&it.line_data_[offset], buf, len);
|
std::strncpy(&it.line_data_[offset], buf, len);
|
||||||
offset += len;
|
offset += len;
|
||||||
|
|
||||||
if (len < buf_size)
|
if (len < buf_size || buf[len - 1] == '\n')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,8 +84,7 @@ void Gradient::step(int16_t index, int16_t r, int16_t g, int16_t b) {
|
|||||||
int16_t new_r = prev_r * y + r * x;
|
int16_t new_r = prev_r * y + r * x;
|
||||||
int16_t new_g = prev_g * y + g * x;
|
int16_t new_g = prev_g * y + g * x;
|
||||||
int16_t new_b = prev_b * y + b * x;
|
int16_t new_b = prev_b * y + b * x;
|
||||||
|
if (i <= 255) lut[i] = ui::Color(new_r, new_g, new_b);
|
||||||
lut[i] = ui::Color(new_r, new_g, new_b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_index = index;
|
prev_index = index;
|
||||||
|
|||||||
@@ -81,7 +81,8 @@ struct header_t {
|
|||||||
struct tags_t {
|
struct tags_t {
|
||||||
constexpr tags_t(
|
constexpr tags_t(
|
||||||
const std::string& title_str) {
|
const std::string& title_str) {
|
||||||
strcpy(title, title_str.c_str());
|
strncpy(title, title_str.c_str(), sizeof(title) - 1);
|
||||||
|
title[sizeof(title) - 1] = '\0';
|
||||||
cksize = sizeof(tags_t) - 8;
|
cksize = sizeof(tags_t) - 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ Continuous (Fox-oring)
|
|||||||
// TODO: ADS-B draw trajectory + GPS coordinates + scale, and playback
|
// TODO: ADS-B draw trajectory + GPS coordinates + scale, and playback
|
||||||
// TODO: RDS multiple groups (sequence)
|
// TODO: RDS multiple groups (sequence)
|
||||||
// TODO: Use ModalMessageView confirmation for TX ?
|
// TODO: Use ModalMessageView confirmation for TX ?
|
||||||
// TODO: Use msgpack for settings, lists... on sd card
|
// TODO: Use msgpack for settings, lists... on sd card. and make it safe, since now it has a lot of oob potentials
|
||||||
|
|
||||||
// Multimon-style stuff:
|
// Multimon-style stuff:
|
||||||
// TODO: DMR detector
|
// TODO: DMR detector
|
||||||
|
|||||||
@@ -108,9 +108,10 @@ void resetFilteredEntries(ContainerType& entries, KeySelector keySelector) {
|
|||||||
auto it = entries.begin();
|
auto it = entries.begin();
|
||||||
while (it != entries.end()) {
|
while (it != entries.end()) {
|
||||||
if (keySelector(*it)) {
|
if (keySelector(*it)) {
|
||||||
entries.erase(it); // Add a new entry to filteredEntries
|
it = entries.erase(it); // Add a new entry to filteredEntries
|
||||||
|
} else {
|
||||||
|
++it; // Move to the next element, outside of the if block
|
||||||
}
|
}
|
||||||
++it; // Move to the next element, outside of the if block
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,8 @@ std::string to_string_dec_uint(uint64_t n) {
|
|||||||
|
|
||||||
std::string to_string_bin(
|
std::string to_string_bin(
|
||||||
const uint32_t n,
|
const uint32_t n,
|
||||||
const uint8_t l) {
|
uint8_t l) {
|
||||||
|
if (l >= 33) l = 32;
|
||||||
char p[33];
|
char p[33];
|
||||||
for (uint8_t c = 0; c < l; c++) {
|
for (uint8_t c = 0; c < l; c++) {
|
||||||
if (n & (1 << (l - 1 - c)))
|
if (n & (1 << (l - 1 - c)))
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ char* to_string_dec_uint(uint64_t n, StringFormatBuffer& buffer, size_t& length)
|
|||||||
std::string to_string_dec_int(int64_t n);
|
std::string to_string_dec_int(int64_t n);
|
||||||
std::string to_string_dec_uint(uint64_t n);
|
std::string to_string_dec_uint(uint64_t n);
|
||||||
|
|
||||||
std::string to_string_bin(const uint32_t n, const uint8_t l = 0);
|
std::string to_string_bin(const uint32_t n, uint8_t l = 0);
|
||||||
std::string to_string_dec_uint(const uint32_t n, const int32_t l, const char fill = ' ');
|
std::string to_string_dec_uint(const uint32_t n, const int32_t l, const char fill = ' ');
|
||||||
std::string to_string_dec_int(const int32_t n, const int32_t l, const char fill = 0);
|
std::string to_string_dec_int(const int32_t n, const int32_t l, const char fill = 0);
|
||||||
std::string to_string_decimal(float decimal, int8_t precision);
|
std::string to_string_decimal(float decimal, int8_t precision);
|
||||||
|
|||||||
@@ -32,40 +32,40 @@ namespace ui {
|
|||||||
|
|
||||||
class ThemeTemplate {
|
class ThemeTemplate {
|
||||||
public:
|
public:
|
||||||
~ThemeTemplate();
|
virtual ~ThemeTemplate();
|
||||||
Style* bg_lightest;
|
Style* bg_lightest = nullptr;
|
||||||
Style* bg_lightest_small;
|
Style* bg_lightest_small = nullptr;
|
||||||
Style* bg_light;
|
Style* bg_light = nullptr;
|
||||||
Style* bg_medium;
|
Style* bg_medium = nullptr;
|
||||||
Style* bg_dark;
|
Style* bg_dark = nullptr;
|
||||||
Style* bg_darker;
|
Style* bg_darker = nullptr;
|
||||||
|
|
||||||
Style* bg_darkest;
|
Style* bg_darkest = nullptr;
|
||||||
Style* bg_darkest_small;
|
Style* bg_darkest_small = nullptr;
|
||||||
|
|
||||||
Style* bg_important_small;
|
Style* bg_important_small = nullptr;
|
||||||
|
|
||||||
Style* error_dark;
|
Style* error_dark = nullptr;
|
||||||
Style* warning_dark;
|
Style* warning_dark = nullptr;
|
||||||
Style* ok_dark;
|
Style* ok_dark = nullptr;
|
||||||
|
|
||||||
Style* fg_dark;
|
Style* fg_dark = nullptr;
|
||||||
Style* fg_medium;
|
Style* fg_medium = nullptr;
|
||||||
Style* fg_light;
|
Style* fg_light = nullptr;
|
||||||
|
|
||||||
Style* fg_red;
|
Style* fg_red = nullptr;
|
||||||
Style* fg_green;
|
Style* fg_green = nullptr;
|
||||||
Style* fg_yellow;
|
Style* fg_yellow = nullptr;
|
||||||
Style* fg_orange;
|
Style* fg_orange = nullptr;
|
||||||
Style* fg_blue;
|
Style* fg_blue = nullptr;
|
||||||
Style* fg_cyan;
|
Style* fg_cyan = nullptr;
|
||||||
Style* fg_darkcyan;
|
Style* fg_darkcyan = nullptr;
|
||||||
Style* fg_magenta;
|
Style* fg_magenta = nullptr;
|
||||||
|
|
||||||
Style* option_active;
|
Style* option_active = nullptr;
|
||||||
|
|
||||||
Color* status_active; // green, the status bar icons when active
|
Color* status_active = nullptr; // green, the status bar icons when active
|
||||||
Color* bg_table_header;
|
Color* bg_table_header = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ThemeDefault : public ThemeTemplate {
|
class ThemeDefault : public ThemeTemplate {
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ void BMPViewer::get_line(ui::Color* line, uint32_t bx, uint32_t by, uint32_t cnt
|
|||||||
for (uint32_t x = 0; x < cnt; x++) {
|
for (uint32_t x = 0; x < cnt; x++) {
|
||||||
uint32_t targetx = (zoom < 0) ? bx + x * -1 * zoom : bx + x / zoom; // on zoom out could probably avg the pixels, or apply some smoothing, but this is way faster.
|
uint32_t targetx = (zoom < 0) ? bx + x * -1 * zoom : bx + x / zoom; // on zoom out could probably avg the pixels, or apply some smoothing, but this is way faster.
|
||||||
if (last_targetx == targetx) {
|
if (last_targetx == targetx) {
|
||||||
line[x] = line[x - 1];
|
if (x > 0) line[x] = line[x - 1];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
last_targetx = targetx;
|
last_targetx = targetx;
|
||||||
@@ -123,7 +123,7 @@ void BMPViewer::paint(Painter& painter) {
|
|||||||
last_by = by;
|
last_by = by;
|
||||||
portapack::display.draw_pixels({rect.left(), rect.top() + y, d_width, 1}, line, d_width);
|
portapack::display.draw_pixels({rect.left(), rect.top() + y, d_width, 1}, line, d_width);
|
||||||
}
|
}
|
||||||
delete line;
|
delete[] line;
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t BMPViewer::get_zoom() {
|
int8_t BMPViewer::get_zoom() {
|
||||||
|
|||||||
@@ -1141,7 +1141,7 @@ static void cmd_gotenv(BaseSequentialStream* chp, int argc, char* argv[]) {
|
|||||||
uint16_t light = 0;
|
uint16_t light = 0;
|
||||||
if (argc > 1) humi = atof(argv[1]);
|
if (argc > 1) humi = atof(argv[1]);
|
||||||
if (argc > 2) pressure = atof(argv[2]);
|
if (argc > 2) pressure = atof(argv[2]);
|
||||||
if (argc > 3) light = strtol(argv[0], NULL, 10);
|
if (argc > 3) light = strtol(argv[3], NULL, 10);
|
||||||
EnvironmentDataMessage msg{temp, humi, pressure};
|
EnvironmentDataMessage msg{temp, humi, pressure};
|
||||||
EventDispatcher::send_message(msg);
|
EventDispatcher::send_message(msg);
|
||||||
// compatibility:
|
// compatibility:
|
||||||
|
|||||||
@@ -148,7 +148,11 @@ void cmd_sd_open(BaseSequentialStream* chp, int argc, char* argv[]) {
|
|||||||
auto path = path_from_string8((char*)full_fn_from_args(argc, argv).c_str());
|
auto path = path_from_string8((char*)full_fn_from_args(argc, argv).c_str());
|
||||||
shell_file = new File();
|
shell_file = new File();
|
||||||
auto error = shell_file->open(path, false, true);
|
auto error = shell_file->open(path, false, true);
|
||||||
if (report_on_error(chp, error)) return;
|
if (report_on_error(chp, error)) {
|
||||||
|
delete shell_file;
|
||||||
|
shell_file = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
chprintf(chp, "ok\r\n");
|
chprintf(chp, "ok\r\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ So include here the .hpp, and add a new element to the protos vector in the cons
|
|||||||
|
|
||||||
class SubCarProtos : public FProtoListGeneral {
|
class SubCarProtos : public FProtoListGeneral {
|
||||||
public:
|
public:
|
||||||
SubCarProtos(const SubCarProtos&) { SubCarProtos(); }; // won't use, but makes compiler happy
|
SubCarProtos(const SubCarProtos&) = delete;
|
||||||
SubCarProtos& operator=(const SubCarProtos&) { return *this; } // won't use, but makes compiler happy
|
SubCarProtos& operator=(const SubCarProtos&) = delete;
|
||||||
SubCarProtos() {
|
SubCarProtos() {
|
||||||
// add protos
|
// add protos
|
||||||
protos[FPC_SUZUKI] = new FProtoSubCarSuzuki();
|
protos[FPC_SUZUKI] = new FProtoSubCarSuzuki();
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ So include here the .hpp, and add a new element to the protos vector in the cons
|
|||||||
|
|
||||||
class SubGhzDProtos : public FProtoListGeneral {
|
class SubGhzDProtos : public FProtoListGeneral {
|
||||||
public:
|
public:
|
||||||
SubGhzDProtos(const SubGhzDProtos&) { SubGhzDProtos(); }; // won't use, but makes compiler happy
|
SubGhzDProtos(const SubGhzDProtos&) = delete;
|
||||||
SubGhzDProtos& operator=(const SubGhzDProtos&) { return *this; } // won't use, but makes compiler happy
|
SubGhzDProtos& operator=(const SubGhzDProtos&) = delete;
|
||||||
SubGhzDProtos() {
|
SubGhzDProtos() {
|
||||||
// add protos
|
// add protos
|
||||||
protos[FPS_PRINCETON] = new FProtoSubGhzDPrinceton();
|
protos[FPS_PRINCETON] = new FProtoSubGhzDPrinceton();
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ So include here the .hpp, and add a new element to the protos vector in the cons
|
|||||||
|
|
||||||
class WeatherProtos : public FProtoListGeneral {
|
class WeatherProtos : public FProtoListGeneral {
|
||||||
public:
|
public:
|
||||||
WeatherProtos(const WeatherProtos&) { WeatherProtos(); }; // won't use, but makes compiler happy
|
WeatherProtos(const WeatherProtos&) = delete;
|
||||||
WeatherProtos& operator=(const WeatherProtos&) { return *this; } // won't use, but makes compiler happy
|
WeatherProtos& operator=(const WeatherProtos&) = delete;
|
||||||
WeatherProtos() {
|
WeatherProtos() {
|
||||||
// add protos
|
// add protos
|
||||||
protos[FPW_NexusTH] = new FProtoWeatherNexusTH();
|
protos[FPW_NexusTH] = new FProtoWeatherNexusTH();
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ void BTLETxProcessor::scramble(char* bit_in, int num_bit, int channel_number, ch
|
|||||||
void BTLETxProcessor::disp_bit_in_hex(char* bit, int num_bit) {
|
void BTLETxProcessor::disp_bit_in_hex(char* bit, int num_bit) {
|
||||||
int i, a;
|
int i, a;
|
||||||
|
|
||||||
for (i = 0; i < num_bit; i = i + 8) {
|
for (i = 0; i + 7 < num_bit; i = i + 8) {
|
||||||
a = bit[i] + bit[i + 1] * 2 + bit[i + 2] * 4 + bit[i + 3] * 8 + bit[i + 4] * 16 + bit[i + 5] * 32 + bit[i + 6] * 64 + bit[i + 7] * 128;
|
a = bit[i] + bit[i + 1] * 2 + bit[i + 2] * 4 + bit[i + 3] * 8 + bit[i + 4] * 16 + bit[i + 5] * 32 + bit[i + 6] * 64 + bit[i + 7] * 128;
|
||||||
|
|
||||||
data_message.is_data = true;
|
data_message.is_data = true;
|
||||||
|
|||||||
@@ -101,6 +101,10 @@ void MicTXProcessor::on_message(const Message* const msg) {
|
|||||||
|
|
||||||
switch (msg->id) {
|
switch (msg->id) {
|
||||||
case Message::ID::AudioTXConfig:
|
case Message::ID::AudioTXConfig:
|
||||||
|
if (modulator) {
|
||||||
|
delete modulator;
|
||||||
|
modulator = NULL;
|
||||||
|
}
|
||||||
if (fm_enabled) {
|
if (fm_enabled) {
|
||||||
dsp::modulate::FM* fm = new dsp::modulate::FM();
|
dsp::modulate::FM* fm = new dsp::modulate::FM();
|
||||||
|
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ uint16_t I2cDev::read16_1(uint8_t reg) {
|
|||||||
}
|
}
|
||||||
uint32_t I2cDev::read24_1(uint8_t reg) {
|
uint32_t I2cDev::read24_1(uint8_t reg) {
|
||||||
uint8_t buffer[3];
|
uint8_t buffer[3];
|
||||||
i2c_read(®, 1, buffer, 2);
|
i2c_read(®, 1, buffer, 3);
|
||||||
return uint32_t(buffer[0]) << 16 | uint32_t(buffer[1]) << 8 | uint32_t(buffer[2]);
|
return uint32_t(buffer[0]) << 16 | uint32_t(buffer[1]) << 8 | uint32_t(buffer[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ size_t morse_encode(std::string& message, const uint32_t time_unit_ms, const uin
|
|||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
for (char& ch : message) {
|
for (char& ch : message) {
|
||||||
if (i > 256) return 0; // Message too long
|
if (i >= 256) return 0; // Message too long
|
||||||
|
|
||||||
if ((ch >= 'a') && (ch <= 'z')) // Make uppercase
|
if ((ch >= 'a') && (ch <= 'z')) // Make uppercase
|
||||||
ch -= 32;
|
ch -= 32;
|
||||||
|
|||||||
@@ -272,9 +272,8 @@ void View::add_child(Widget* const widget) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void View::add_children(const std::initializer_list<Widget*> children) {
|
void View::add_children(const std::initializer_list<Widget*> children) {
|
||||||
children_.insert(std::end(children_), children);
|
|
||||||
for (auto child : children) {
|
for (auto child : children) {
|
||||||
child->set_parent(this);
|
add_child(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,8 +621,8 @@ ProgressBar::ProgressBar(
|
|||||||
void ProgressBar::set_max(const uint32_t max) {
|
void ProgressBar::set_max(const uint32_t max) {
|
||||||
if (max == _max) return;
|
if (max == _max) return;
|
||||||
|
|
||||||
if (_value > _max)
|
if (_value > max)
|
||||||
_value = _max;
|
_value = max;
|
||||||
|
|
||||||
_max = max;
|
_max = max;
|
||||||
set_dirty();
|
set_dirty();
|
||||||
@@ -651,9 +650,11 @@ void ProgressBar::paint(Painter& painter) {
|
|||||||
|
|
||||||
const auto sr = screen_rect();
|
const auto sr = screen_rect();
|
||||||
const auto s = style();
|
const auto s = style();
|
||||||
|
if (_max == 0) {
|
||||||
v_scaled = (sr.size().width() * (uint64_t)_value) / _max;
|
v_scaled = 0;
|
||||||
|
} else {
|
||||||
|
v_scaled = (sr.size().width() * (uint64_t)_value) / _max;
|
||||||
|
}
|
||||||
painter.fill_rectangle({sr.location(), {v_scaled, sr.size().height()}}, style().foreground);
|
painter.fill_rectangle({sr.location(), {v_scaled, sr.size().height()}}, style().foreground);
|
||||||
painter.fill_rectangle({{sr.location().x() + v_scaled, sr.location().y()}, {sr.size().width() - v_scaled, sr.size().height()}}, s.background);
|
painter.fill_rectangle({{sr.location().x() + v_scaled, sr.location().y()}, {sr.size().width() - v_scaled, sr.size().height()}}, s.background);
|
||||||
|
|
||||||
@@ -1267,7 +1268,7 @@ bool ButtonWithEncoder::on_encoder(const EncoderEvent delta) {
|
|||||||
if (delta != 0) {
|
if (delta != 0) {
|
||||||
encoder_delta += delta;
|
encoder_delta += delta;
|
||||||
delta_change = true;
|
delta_change = true;
|
||||||
on_change();
|
if (on_change) on_change();
|
||||||
} else
|
} else
|
||||||
delta_change = 0;
|
delta_change = 0;
|
||||||
return true;
|
return true;
|
||||||
@@ -1904,6 +1905,7 @@ void OptionsField::on_focus() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool OptionsField::on_encoder(const EncoderEvent delta) {
|
bool OptionsField::on_encoder(const EncoderEvent delta) {
|
||||||
|
if (options_.empty()) return false;
|
||||||
int32_t new_value = selected_index() + delta;
|
int32_t new_value = selected_index() + delta;
|
||||||
if (new_value < 0)
|
if (new_value < 0)
|
||||||
new_value = options_.size() - 1;
|
new_value = options_.size() - 1;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
uint32_t gcd(const uint32_t u, const uint32_t v) {
|
uint32_t gcd(const uint32_t u, const uint32_t v) {
|
||||||
@@ -257,8 +258,23 @@ std::string join(char c, std::initializer_list<std::string_view> strings) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t simple_checksum(uint32_t buffer_address, uint32_t length) {
|
uint32_t simple_checksum(uint32_t buffer_address, uint32_t length) {
|
||||||
|
if (buffer_address == 0 || length == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
uint32_t checksum = 0;
|
uint32_t checksum = 0;
|
||||||
for (uint32_t i = 0; i < length; i += 4)
|
const uint8_t* ptr = (const uint8_t*)(uintptr_t)buffer_address;
|
||||||
checksum += *(uint32_t*)(buffer_address + i);
|
uint32_t i = 0;
|
||||||
|
for (; i + 3 < length; i += 4) {
|
||||||
|
uint32_t chunk;
|
||||||
|
// memcpy prevents unaligned access hard-faults on embedded processors
|
||||||
|
memcpy(&chunk, ptr + i, 4);
|
||||||
|
checksum += chunk;
|
||||||
|
}
|
||||||
|
// Leftover bytes (won't happen hopefully)
|
||||||
|
if (i < length) {
|
||||||
|
uint32_t remainder = 0;
|
||||||
|
memcpy(&remainder, ptr + i, length - i);
|
||||||
|
checksum += remainder;
|
||||||
|
}
|
||||||
return checksum;
|
return checksum;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user