formatted, attempt to fix rfid fuzzer crash

crash doesn’t fixed with this commit
This commit is contained in:
MX
2022-09-03 23:10:07 +03:00
parent f99c1a8c0a
commit 8323877120
16 changed files with 996 additions and 715 deletions

View File

@@ -1,6 +1,6 @@
App( App(
appid="flipfrid", appid="flipfrid",
name="Rfid Fuzzer", name="RFID Fuzzer",
apptype=FlipperAppType.PLUGIN, apptype=FlipperAppType.PLUGIN,
entry_point="flipfrid_start", entry_point="flipfrid_start",
cdefines=["APP_FLIP_FRID"], cdefines=["APP_FLIP_FRID"],

View File

@@ -114,7 +114,10 @@ int32_t flipfrid_start(void* p) {
if(!init_mutex(&flipfrid_state_mutex, flipfrid_state, sizeof(FlipFridState))) { if(!init_mutex(&flipfrid_state_mutex, flipfrid_state, sizeof(FlipFridState))) {
FURI_LOG_E(TAG, "cannot create mutex\r\n"); FURI_LOG_E(TAG, "cannot create mutex\r\n");
furi_message_queue_free(event_queue); furi_message_queue_free(event_queue);
furi_record_close(RECORD_NOTIFICATION);
furi_record_close(RECORD_DIALOGS);
free(flipfrid_state); free(flipfrid_state);
return 255;
} }
// Configure view port // Configure view port
@@ -228,6 +231,7 @@ int32_t flipfrid_start(void* p) {
view_port_free(view_port); view_port_free(view_port);
furi_message_queue_free(event_queue); furi_message_queue_free(event_queue);
furi_record_close(RECORD_GUI); furi_record_close(RECORD_GUI);
furi_record_close(RECORD_NOTIFICATION);
flipfrid_free(flipfrid_state); flipfrid_free(flipfrid_state);
return 0; return 0;

View File

@@ -27,7 +27,7 @@ void flipfrid_scene_entrypoint_menu_callback(FlipFridState* context, uint32_t in
void flipfrid_scene_entrypoint_on_enter(FlipFridState* context) { void flipfrid_scene_entrypoint_on_enter(FlipFridState* context) {
context->menu_index = 0; context->menu_index = 0;
for (uint32_t i = 0; i < 3; i++) { for(uint32_t i = 0; i < 3; i++) {
string_init(menu_items[i]); string_init(menu_items[i]);
} }
@@ -38,7 +38,7 @@ void flipfrid_scene_entrypoint_on_enter(FlipFridState* context) {
void flipfrid_scene_entrypoint_on_exit(FlipFridState* context) { void flipfrid_scene_entrypoint_on_exit(FlipFridState* context) {
UNUSED(context); UNUSED(context);
for (uint32_t i = 0; i < 3; i++) { for(uint32_t i = 0; i < 3; i++) {
string_clear(menu_items[i]); string_clear(menu_items[i]);
} }
} }
@@ -63,6 +63,7 @@ void flipfrid_scene_entrypoint_on_event(FlipFridEvent event, FlipFridState* cont
break; break;
case InputKeyLeft: case InputKeyLeft:
case InputKeyRight: case InputKeyRight:
break;
case InputKeyOk: case InputKeyOk:
flipfrid_scene_entrypoint_menu_callback(context, context->menu_index); flipfrid_scene_entrypoint_menu_callback(context, context->menu_index);
break; break;
@@ -84,14 +85,27 @@ void flipfrid_scene_entrypoint_on_draw(Canvas* canvas, FlipFridState* context) {
if(context->menu_index > FlipFridAttackDefaultValues) { if(context->menu_index > FlipFridAttackDefaultValues) {
canvas_set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(canvas, 64, 24, AlignCenter, AlignTop, string_get_cstr(menu_items[context->menu_index - 1])); canvas_draw_str_aligned(
canvas,
64,
24,
AlignCenter,
AlignTop,
string_get_cstr(menu_items[context->menu_index - 1]));
} }
canvas_set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, 64, 36, AlignCenter, AlignTop, string_get_cstr(menu_items[context->menu_index])); canvas_draw_str_aligned(
canvas, 64, 36, AlignCenter, AlignTop, string_get_cstr(menu_items[context->menu_index]));
if(context->menu_index < FlipFridAttackLoadFile) { if(context->menu_index < FlipFridAttackLoadFile) {
canvas_set_font(canvas, FontSecondary); canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(canvas, 64, 48, AlignCenter, AlignTop, string_get_cstr(menu_items[context->menu_index + 1])); canvas_draw_str_aligned(
canvas,
64,
48,
AlignCenter,
AlignTop,
string_get_cstr(menu_items[context->menu_index + 1]));
} }
} }

View File

@@ -34,7 +34,7 @@ bool flipfrid_load(FlipFridState* context, const char* file_path) {
break; break;
} else { } else {
FURI_LOG_I(TAG, "Key type: %s", string_get_cstr(temp_str)); FURI_LOG_I(TAG, "Key type: %s", string_get_cstr(temp_str));
if (strcmp(string_get_cstr(temp_str), "EM4100") != 0) { if(strcmp(string_get_cstr(temp_str), "EM4100") != 0) {
FURI_LOG_E(TAG, "Unsupported Key type"); FURI_LOG_E(TAG, "Unsupported Key type");
string_reset(context->notification_msg); string_reset(context->notification_msg);
string_set_str(context->notification_msg, "Unsupported Key type"); string_set_str(context->notification_msg, "Unsupported Key type");
@@ -52,21 +52,20 @@ bool flipfrid_load(FlipFridState* context, const char* file_path) {
FURI_LOG_I(TAG, "Key: %s", string_get_cstr(context->data_str)); FURI_LOG_I(TAG, "Key: %s", string_get_cstr(context->data_str));
// Check data size // Check data size
if (string_size(context->data_str) != 14) { if(string_size(context->data_str) != 14) {
FURI_LOG_E(TAG, "Incorrect Key length"); FURI_LOG_E(TAG, "Incorrect Key length");
string_reset(context->notification_msg); string_reset(context->notification_msg);
string_set_str(context->notification_msg, "Incorrect Key length"); string_set_str(context->notification_msg, "Incorrect Key length");
break; break;
} }
// String to uint8_t // String to uint8_t
for (uint8_t i = 0; i < 5; i++) { for(uint8_t i = 0; i < 5; i++) {
char temp_str2[3]; char temp_str2[3];
temp_str2[0] = string_get_cstr(context->data_str)[i*3]; temp_str2[0] = string_get_cstr(context->data_str)[i * 3];
temp_str2[1] = string_get_cstr(context->data_str)[i*3+1]; temp_str2[1] = string_get_cstr(context->data_str)[i * 3 + 1];
temp_str2[2] = '\0'; temp_str2[2] = '\0';
context->data[i] = (uint8_t)strtol(temp_str2, NULL, 16); context->data[i] = (uint8_t)strtol(temp_str2, NULL, 16);
} }
} }
result = true; result = true;
@@ -130,7 +129,7 @@ bool flipfrid_load_protocol_from_file(FlipFridState* context) {
context->file_path, context->file_path,
LFRFID_APP_EXTENSION, LFRFID_APP_EXTENSION,
true, true,
&I_sub1_10px, &I_125_10px,
true); true);
if(res) { if(res) {

View File

@@ -57,6 +57,10 @@ void flipfrid_scene_run_attack_on_tick(FlipFridState* context) {
if(context->attack_step == 15) { if(context->attack_step == 15) {
context->attack_step = 0; context->attack_step = 0;
counter = 0;
context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_single_vibro);
} else { } else {
context->attack_step++; context->attack_step++;
} }
@@ -71,6 +75,10 @@ void flipfrid_scene_run_attack_on_tick(FlipFridState* context) {
if(context->attack_step == 255) { if(context->attack_step == 255) {
context->attack_step = 0; context->attack_step = 0;
counter = 0;
context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_single_vibro);
} else { } else {
context->attack_step++; context->attack_step++;
} }
@@ -86,6 +94,10 @@ void flipfrid_scene_run_attack_on_tick(FlipFridState* context) {
if(context->attack_step == 255) { if(context->attack_step == 255) {
context->attack_step = 0; context->attack_step = 0;
counter = 0;
context->is_attacking = false;
notification_message(context->notify, &sequence_blink_stop);
notification_message(context->notify, &sequence_single_vibro);
} else { } else {
context->attack_step++; context->attack_step++;
} }
@@ -94,10 +106,10 @@ void flipfrid_scene_run_attack_on_tick(FlipFridState* context) {
} }
if(counter > TIME_BETWEEN_CARDS) { if(counter > TIME_BETWEEN_CARDS) {
counter = 0; counter = 0;
} else { } else {
counter++; counter++;
} }
} }
} }
@@ -109,6 +121,7 @@ void flipfrid_scene_run_attack_on_event(FlipFridEvent event, FlipFridState* cont
case InputKeyUp: case InputKeyUp:
case InputKeyLeft: case InputKeyLeft:
case InputKeyRight: case InputKeyRight:
break;
case InputKeyOk: case InputKeyOk:
counter = 0; counter = 0;
if(!context->is_attacking) { if(!context->is_attacking) {

View File

@@ -4,7 +4,8 @@ void flipfrid_center_displayed_key(FlipFridState* context, uint8_t index) {
const char* key_cstr = string_get_cstr(context->data_str); const char* key_cstr = string_get_cstr(context->data_str);
uint8_t str_index = (index * 3); uint8_t str_index = (index * 3);
char display_menu[17] = {'X', 'X', ' ', 'X', 'X', ' ', '<', 'X', 'X', '>', ' ', 'X', 'X', ' ', 'X', 'X', '\0'}; char display_menu[17] = {
'X', 'X', ' ', 'X', 'X', ' ', '<', 'X', 'X', '>', ' ', 'X', 'X', ' ', 'X', 'X', '\0'};
if(index > 1) { if(index > 1) {
display_menu[0] = key_cstr[str_index - 6]; display_menu[0] = key_cstr[str_index - 6];
@@ -25,7 +26,7 @@ void flipfrid_center_displayed_key(FlipFridState* context, uint8_t index) {
display_menu[7] = key_cstr[str_index]; display_menu[7] = key_cstr[str_index];
display_menu[8] = key_cstr[str_index + 1]; display_menu[8] = key_cstr[str_index + 1];
if((str_index + 4) <= (uint8_t) strlen(key_cstr)) { if((str_index + 4) <= (uint8_t)strlen(key_cstr)) {
display_menu[11] = key_cstr[str_index + 3]; display_menu[11] = key_cstr[str_index + 3];
display_menu[12] = key_cstr[str_index + 4]; display_menu[12] = key_cstr[str_index + 4];
} else { } else {
@@ -33,7 +34,7 @@ void flipfrid_center_displayed_key(FlipFridState* context, uint8_t index) {
display_menu[12] = ' '; display_menu[12] = ' ';
} }
if((str_index + 8) <= (uint8_t) strlen(key_cstr)) { if((str_index + 8) <= (uint8_t)strlen(key_cstr)) {
display_menu[14] = key_cstr[str_index + 6]; display_menu[14] = key_cstr[str_index + 6];
display_menu[15] = key_cstr[str_index + 7]; display_menu[15] = key_cstr[str_index + 7];
} else { } else {

View File

@@ -46,8 +46,8 @@ App(
provides=[ provides=[
"snake_game", "snake_game",
"tetris_game", "tetris_game",
"arkanoid_game", #"arkanoid_game",
"tictactoe_game", #"tictactoe_game",
], ],
) )
@@ -68,7 +68,7 @@ App(
apptype=FlipperAppType.METAPACKAGE, apptype=FlipperAppType.METAPACKAGE,
provides=[ provides=[
"picopass", "picopass",
"barcode_generator", #"barcode_generator",
"mouse_jacker", "mouse_jacker",
"nrf_sniff", "nrf_sniff",
"sentry_safe", "sentry_safe",

View File

@@ -8,152 +8,158 @@
#include "multi_converter_mode_select.h" #include "multi_converter_mode_select.h"
static void multi_converter_render_callback(Canvas* const canvas, void* ctx) { static void multi_converter_render_callback(Canvas* const canvas, void* ctx) {
const MultiConverterState* multi_converter_state = acquire_mutex((ValueMutex*)ctx, 25);
if(multi_converter_state == NULL) {
return;
}
const MultiConverterState* multi_converter_state = acquire_mutex((ValueMutex*)ctx, 25); if(multi_converter_state->mode == ModeDisplay) {
if(multi_converter_state == NULL) { multi_converter_mode_display_draw(canvas, multi_converter_state);
return; } else {
} multi_converter_mode_select_draw(canvas, multi_converter_state);
}
if (multi_converter_state->mode == ModeDisplay) { release_mutex((ValueMutex*)ctx, multi_converter_state);
multi_converter_mode_display_draw(canvas, multi_converter_state);
} else {
multi_converter_mode_select_draw(canvas, multi_converter_state);
}
release_mutex((ValueMutex*)ctx, multi_converter_state);
} }
static void multi_converter_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { static void
furi_assert(event_queue); multi_converter_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
furi_assert(event_queue);
MultiConverterEvent event = {.type = EventTypeKey, .input = *input_event}; MultiConverterEvent event = {.type = EventTypeKey, .input = *input_event};
furi_message_queue_put(event_queue, &event, FuriWaitForever); furi_message_queue_put(event_queue, &event, FuriWaitForever);
} }
static void multi_converter_init(MultiConverterState* const multi_converter_state) { static void multi_converter_init(MultiConverterState* const multi_converter_state) {
// initial default values // initial default values
multi_converter_state->buffer_orig[MULTI_CONVERTER_NUMBER_DIGITS] = '\0'; multi_converter_state->buffer_orig[MULTI_CONVERTER_NUMBER_DIGITS] = '\0';
multi_converter_state->buffer_dest[MULTI_CONVERTER_NUMBER_DIGITS] = '\0'; // null terminators multi_converter_state->buffer_dest[MULTI_CONVERTER_NUMBER_DIGITS] = '\0'; // null terminators
multi_converter_state->unit_type_orig = UnitTypeDec; multi_converter_state->unit_type_orig = UnitTypeDec;
multi_converter_state->unit_type_dest = UnitTypeHex; multi_converter_state->unit_type_dest = UnitTypeHex;
multi_converter_state->keyboard_lock = 0; multi_converter_state->keyboard_lock = 0;
// init the display view // init the display view
multi_converter_mode_display_reset(multi_converter_state); multi_converter_mode_display_reset(multi_converter_state);
// init the select view // init the select view
multi_converter_mode_select_reset(multi_converter_state); multi_converter_mode_select_reset(multi_converter_state);
// set ModeDisplay as the current mode // set ModeDisplay as the current mode
multi_converter_state->mode = ModeDisplay; multi_converter_state->mode = ModeDisplay;
} }
// main entry point // main entry point
int32_t multi_converter_app(void* p) { int32_t multi_converter_app(void* p) {
UNUSED(p); UNUSED(p);
// get event queue // get event queue
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(MultiConverterEvent)); FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(MultiConverterEvent));
// allocate state // allocate state
MultiConverterState* multi_converter_state = malloc(sizeof(MultiConverterState)); MultiConverterState* multi_converter_state = malloc(sizeof(MultiConverterState));
// set mutex for plugin state (different threads can access it) // set mutex for plugin state (different threads can access it)
ValueMutex state_mutex; ValueMutex state_mutex;
if(!init_mutex(&state_mutex, multi_converter_state, sizeof(multi_converter_state))) { if(!init_mutex(&state_mutex, multi_converter_state, sizeof(multi_converter_state))) {
FURI_LOG_E("MultiConverter", "cannot create mutex\r\n"); FURI_LOG_E("MultiConverter", "cannot create mutex\r\n");
free(multi_converter_state); furi_message_queue_free(event_queue);
return 255; free(multi_converter_state);
} return 255;
}
// register callbacks for drawing and input processing // register callbacks for drawing and input processing
ViewPort* view_port = view_port_alloc(); ViewPort* view_port = view_port_alloc();
view_port_draw_callback_set(view_port, multi_converter_render_callback, &state_mutex); view_port_draw_callback_set(view_port, multi_converter_render_callback, &state_mutex);
view_port_input_callback_set(view_port, multi_converter_input_callback, event_queue); view_port_input_callback_set(view_port, multi_converter_input_callback, event_queue);
// open GUI and register view_port // open GUI and register view_port
Gui* gui = furi_record_open("gui"); Gui* gui = furi_record_open("gui");
gui_add_view_port(gui, view_port, GuiLayerFullscreen); gui_add_view_port(gui, view_port, GuiLayerFullscreen);
multi_converter_init(multi_converter_state); multi_converter_init(multi_converter_state);
// main loop // main loop
MultiConverterEvent event; MultiConverterEvent event;
for (bool processing = true; processing;) { for(bool processing = true; processing;) {
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
MultiConverterState* multi_converter_state = (MultiConverterState*)acquire_mutex_block(&state_mutex); MultiConverterState* multi_converter_state =
(MultiConverterState*)acquire_mutex_block(&state_mutex);
if (event_status == FuriStatusOk) { if(event_status == FuriStatusOk) {
// press events // press events
if (event.type == EventTypeKey && !multi_converter_state->keyboard_lock) { if(event.type == EventTypeKey && !multi_converter_state->keyboard_lock) {
if (multi_converter_state->mode == ModeDisplay) { if(multi_converter_state->mode == ModeDisplay) {
if(event.input.key == InputKeyBack) {
if(event.input.type == InputTypePress) processing = false;
} else if(event.input.key == InputKeyOk) { // the "ok" press can be short or long
MultiConverterModeTrigger t = None;
if (event.input.key == InputKeyBack) { if(event.input.type == InputTypeLong)
if (event.input.type == InputTypePress) processing = false; t = multi_converter_mode_display_ok(1, multi_converter_state);
} else if (event.input.key == InputKeyOk) { // the "ok" press can be short or long else if(event.input.type == InputTypeShort)
MultiConverterModeTrigger t = None; t = multi_converter_mode_display_ok(0, multi_converter_state);
if (event.input.type == InputTypeLong) t = multi_converter_mode_display_ok(1, multi_converter_state); if(t == Reset) {
else if (event.input.type == InputTypeShort) t = multi_converter_mode_display_ok(0, multi_converter_state); multi_converter_mode_select_reset(multi_converter_state);
multi_converter_state->mode = ModeSelector;
}
} else {
if(event.input.type == InputTypePress)
multi_converter_mode_display_navigation(
event.input.key, multi_converter_state);
}
if (t == Reset) { } else { // ModeSelect
multi_converter_mode_select_reset(multi_converter_state); if(event.input.type == InputTypePress) {
multi_converter_state->mode = ModeSelector; switch(event.input.key) {
} default:
} else { break;
if (event.input.type == InputTypePress) multi_converter_mode_display_navigation(event.input.key, multi_converter_state); case InputKeyBack:
} case InputKeyOk: {
MultiConverterModeTrigger t = multi_converter_mode_select_exit(
} else { // ModeSelect event.input.key == InputKeyOk ? 1 : 0, multi_converter_state);
if (event.input.type == InputTypePress) {
switch (event.input.key) {
default:
break;
case InputKeyBack:
case InputKeyOk: {
MultiConverterModeTrigger t = multi_converter_mode_select_exit(event.input.key == InputKeyOk ? 1 : 0, multi_converter_state);
if (t == Reset) { if(t == Reset) {
multi_converter_mode_display_reset(multi_converter_state); multi_converter_mode_display_reset(multi_converter_state);
} else if (t == Convert) { } else if(t == Convert) {
multi_converter_mode_display_convert(multi_converter_state); multi_converter_mode_display_convert(multi_converter_state);
} }
multi_converter_state->keyboard_lock = 1; multi_converter_state->keyboard_lock = 1;
multi_converter_state->mode = ModeDisplay; multi_converter_state->mode = ModeDisplay;
break; break;
} }
case InputKeyLeft: case InputKeyLeft:
case InputKeyRight: case InputKeyRight:
multi_converter_mode_select_switch(multi_converter_state); multi_converter_mode_select_switch(multi_converter_state);
break; break;
case InputKeyUp: case InputKeyUp:
multi_converter_mode_select_change_unit(-1, multi_converter_state); multi_converter_mode_select_change_unit(-1, multi_converter_state);
break; break;
case InputKeyDown: case InputKeyDown:
multi_converter_mode_select_change_unit(1, multi_converter_state); multi_converter_mode_select_change_unit(1, multi_converter_state);
break; break;
} }
} }
} }
} else if (multi_converter_state->keyboard_lock) { } else if(multi_converter_state->keyboard_lock) {
multi_converter_state->keyboard_lock = 0; multi_converter_state->keyboard_lock = 0;
} }
} else { } else {
// event timeout // event timeout
} }
view_port_update(view_port);
release_mutex(&state_mutex, multi_converter_state);
}
view_port_enabled_set(view_port, false); view_port_update(view_port);
gui_remove_view_port(gui, view_port); release_mutex(&state_mutex, multi_converter_state);
furi_record_close("gui"); }
view_port_free(view_port);
view_port_enabled_set(view_port, false);
gui_remove_view_port(gui, view_port);
furi_record_close("gui");
view_port_free(view_port);
furi_message_queue_free(event_queue); furi_message_queue_free(event_queue);
delete_mutex(&state_mutex); delete_mutex(&state_mutex);
free(multi_converter_state); free(multi_converter_state);

View File

@@ -1,82 +1,82 @@
#pragma once #pragma once
#define MULTI_CONVERTER_NUMBER_DIGITS 9 #define MULTI_CONVERTER_NUMBER_DIGITS 9
typedef enum { typedef enum {
EventTypeKey, EventTypeKey,
} EventType; } EventType;
typedef struct { typedef struct {
InputEvent input; InputEvent input;
EventType type; EventType type;
} MultiConverterEvent; } MultiConverterEvent;
typedef enum { typedef enum {
ModeDisplay, ModeDisplay,
ModeSelector, ModeSelector,
} MultiConverterMode; } MultiConverterMode;
typedef enum { typedef enum {
None, None,
Reset, Reset,
Convert, Convert,
} MultiConverterModeTrigger; } MultiConverterModeTrigger;
// new units goes here, used as index to the main multi_converter_available_units array (multi_converter_units.h) // new units goes here, used as index to the main multi_converter_available_units array (multi_converter_units.h)
typedef enum { typedef enum {
UnitTypeDec, UnitTypeDec,
UnitTypeHex, UnitTypeHex,
UnitTypeBin, UnitTypeBin,
UnitTypeCelsius, UnitTypeCelsius,
UnitTypeFahernheit, UnitTypeFahernheit,
UnitTypeKelvin, UnitTypeKelvin,
UnitTypeKilometers, UnitTypeKilometers,
UnitTypeMeters, UnitTypeMeters,
UnitTypeCentimeters, UnitTypeCentimeters,
UnitTypeMiles, UnitTypeMiles,
UnitTypeFeet, UnitTypeFeet,
UnitTypeInches, UnitTypeInches,
UnitTypeDegree, UnitTypeDegree,
UnitTypeRadian, UnitTypeRadian,
} MultiConverterUnitType; } MultiConverterUnitType;
typedef struct { typedef struct {
MultiConverterUnitType selected_unit_type_orig; MultiConverterUnitType selected_unit_type_orig;
MultiConverterUnitType selected_unit_type_dest; MultiConverterUnitType selected_unit_type_dest;
uint8_t select_orig; uint8_t select_orig;
} MultiConverterModeSelect; } MultiConverterModeSelect;
typedef struct { typedef struct {
uint8_t cursor; // cursor position when typing uint8_t cursor; // cursor position when typing
int8_t key; // hover key int8_t key; // hover key
uint8_t comma; // comma already added? (only one comma allowed) uint8_t comma; // comma already added? (only one comma allowed)
uint8_t negative; // is negative? uint8_t negative; // is negative?
} MultiConverterModeDisplay; } MultiConverterModeDisplay;
typedef struct MultiConverterUnit MultiConverterUnit; typedef struct MultiConverterUnit MultiConverterUnit;
typedef struct MultiConverterState MultiConverterState; typedef struct MultiConverterState MultiConverterState;
struct MultiConverterUnit { struct MultiConverterUnit {
uint8_t allow_comma; uint8_t allow_comma;
uint8_t allow_negative; uint8_t allow_negative;
uint8_t max_number_keys; uint8_t max_number_keys;
char mini_name[4]; char mini_name[4];
char name[12]; char name[12];
void (*convert_function)(MultiConverterState * const); void (*convert_function)(MultiConverterState* const);
uint8_t (*allowed_function)(MultiConverterUnitType); uint8_t (*allowed_function)(MultiConverterUnitType);
}; };
struct MultiConverterState { struct MultiConverterState {
char buffer_orig[MULTI_CONVERTER_NUMBER_DIGITS + 1]; char buffer_orig[MULTI_CONVERTER_NUMBER_DIGITS + 1];
char buffer_dest[MULTI_CONVERTER_NUMBER_DIGITS + 1]; char buffer_dest[MULTI_CONVERTER_NUMBER_DIGITS + 1];
MultiConverterUnitType unit_type_orig; MultiConverterUnitType unit_type_orig;
MultiConverterUnitType unit_type_dest; MultiConverterUnitType unit_type_dest;
MultiConverterMode mode; MultiConverterMode mode;
MultiConverterModeDisplay display; MultiConverterModeDisplay display;
MultiConverterModeSelect select; MultiConverterModeSelect select;
uint8_t keyboard_lock; // used to create a small lock when switching from SELECT to DISPLAY modes uint8_t keyboard_lock; // used to create a small lock when switching from SELECT to DISPLAY modes
// (debouncing, basically; otherwise it switch modes twice 'cause it's too fast!) // (debouncing, basically; otherwise it switch modes twice 'cause it's too fast!)
}; };

View File

@@ -1,284 +1,326 @@
#include "multi_converter_mode_display.h" #include "multi_converter_mode_display.h"
#define MULTI_CONVERTER_DISPLAY_KEYS 18 // [0] to [F] + [BACK] + [SELECT] #define MULTI_CONVERTER_DISPLAY_KEYS 18 // [0] to [F] + [BACK] + [SELECT]
#define MULTI_CONVERTER_DISPLAY_KEY_NEGATIVE 0 // long press
#define MULTI_CONVERTER_DISPLAY_KEY_COMMA 1 // long press
#define MULTI_CONVERTER_DISPLAY_KEY_DEL 16
#define MULTI_CONVERTER_DISPLAY_KEY_SELECT 17
#define MULTI_CONVERTER_DISPLAY_CHAR_COMMA '.' #define MULTI_CONVERTER_DISPLAY_KEY_NEGATIVE 0 // long press
#define MULTI_CONVERTER_DISPLAY_CHAR_NEGATIVE '-' #define MULTI_CONVERTER_DISPLAY_KEY_COMMA 1 // long press
#define MULTI_CONVERTER_DISPLAY_CHAR_DEL '<' #define MULTI_CONVERTER_DISPLAY_KEY_DEL 16
#define MULTI_CONVERTER_DISPLAY_CHAR_SELECT '#' #define MULTI_CONVERTER_DISPLAY_KEY_SELECT 17
#define MULTI_CONVERTER_DISPLAY_CHAR_BLANK ' '
#define MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN 3 #define MULTI_CONVERTER_DISPLAY_CHAR_COMMA '.'
#define MULTI_CONVERTER_DISPLAY_KEY_CHAR_HEIGHT 8 #define MULTI_CONVERTER_DISPLAY_CHAR_NEGATIVE '-'
#define MULTI_CONVERTER_DISPLAY_CHAR_DEL '<'
#define MULTI_CONVERTER_DISPLAY_CHAR_SELECT '#'
#define MULTI_CONVERTER_DISPLAY_CHAR_BLANK ' '
#define MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN 3
#define MULTI_CONVERTER_DISPLAY_KEY_CHAR_HEIGHT 8
void multi_converter_mode_display_convert(MultiConverterState* const multi_converter_state) { void multi_converter_mode_display_convert(MultiConverterState* const multi_converter_state) {
// 1.- if origin == destination (in theory user won't be allowed to choose the same options, but it's kinda "valid"...)
// just copy buffer_orig to buffer_dest and that's it
// 1.- if origin == destination (in theory user won't be allowed to choose the same options, but it's kinda "valid"...) if(multi_converter_state->unit_type_orig == multi_converter_state->unit_type_dest) {
// just copy buffer_orig to buffer_dest and that's it memcpy(
multi_converter_state->buffer_dest,
if (multi_converter_state->unit_type_orig == multi_converter_state->unit_type_dest) { multi_converter_state->buffer_orig,
memcpy(multi_converter_state->buffer_dest, multi_converter_state->buffer_orig, MULTI_CONVERTER_NUMBER_DIGITS); MULTI_CONVERTER_NUMBER_DIGITS);
return; return;
} }
// 2.- origin_buffer has not null functions // 2.- origin_buffer has not null functions
if (multi_converter_get_unit(multi_converter_state->unit_type_orig).convert_function == NULL || multi_converter_get_unit(multi_converter_state->unit_type_orig).allowed_function == NULL) return; if(multi_converter_get_unit(multi_converter_state->unit_type_orig).convert_function == NULL ||
multi_converter_get_unit(multi_converter_state->unit_type_orig).allowed_function == NULL)
return;
// 3.- valid destination type (using allowed_destinations function) // 3.- valid destination type (using allowed_destinations function)
if (!multi_converter_get_unit(multi_converter_state->unit_type_orig).allowed_function(multi_converter_state->unit_type_dest)) return; if(!multi_converter_get_unit(multi_converter_state->unit_type_orig)
.allowed_function(multi_converter_state->unit_type_dest))
multi_converter_get_unit(multi_converter_state->unit_type_orig).convert_function(multi_converter_state); return;
multi_converter_get_unit(multi_converter_state->unit_type_orig)
.convert_function(multi_converter_state);
} }
void multi_converter_mode_display_draw(Canvas* const canvas, const MultiConverterState* multi_converter_state) { void multi_converter_mode_display_draw(
Canvas* const canvas,
canvas_set_color(canvas, ColorBlack); const MultiConverterState* multi_converter_state) {
canvas_set_color(canvas, ColorBlack);
// ORIGIN // ORIGIN
canvas_set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
canvas_draw_str(canvas, 2, 10, multi_converter_get_unit(multi_converter_state->unit_type_orig).mini_name); canvas_draw_str(
canvas, 2, 10, multi_converter_get_unit(multi_converter_state->unit_type_orig).mini_name);
canvas_set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
canvas_draw_str(canvas, 2 + 30, 10, multi_converter_state->buffer_orig); canvas_draw_str(canvas, 2 + 30, 10, multi_converter_state->buffer_orig);
// DESTINATION // DESTINATION
canvas_set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
canvas_draw_str(canvas, 2, 10 + 12, multi_converter_get_unit(multi_converter_state->unit_type_dest).mini_name); canvas_draw_str(
canvas,
2,
10 + 12,
multi_converter_get_unit(multi_converter_state->unit_type_dest).mini_name);
canvas_set_font(canvas, FontPrimary); canvas_set_font(canvas, FontPrimary);
canvas_draw_str(canvas, 2 + 30, 10 + 12, multi_converter_state->buffer_dest); canvas_draw_str(canvas, 2 + 30, 10 + 12, multi_converter_state->buffer_dest);
// SEPARATOR_LINE // SEPARATOR_LINE
canvas_draw_line(canvas, 2, 25, 128 - 3, 25); canvas_draw_line(canvas, 2, 25, 128 - 3, 25);
// KEYBOARD // KEYBOARD
uint8_t _x = 5; uint8_t _x = 5;
uint8_t _y = 25 + 15; // line + 10 uint8_t _y = 25 + 15; // line + 10
for (int i = 0; i < MULTI_CONVERTER_DISPLAY_KEYS; i++) { for(int i = 0; i < MULTI_CONVERTER_DISPLAY_KEYS; i++) {
char g;
if(i < 10)
g = (i + '0');
else if(i < 16)
g = ((i - 10) + 'A');
else if(i == MULTI_CONVERTER_DISPLAY_KEY_DEL)
g = MULTI_CONVERTER_DISPLAY_CHAR_DEL;
else
g = MULTI_CONVERTER_DISPLAY_CHAR_SELECT;
char g; uint8_t g_w = canvas_glyph_width(canvas, g);
if (i < 10) g = (i + '0');
else if (i < 16) g = ((i - 10) + 'A');
else if (i == MULTI_CONVERTER_DISPLAY_KEY_DEL) g = MULTI_CONVERTER_DISPLAY_CHAR_DEL;
else g = MULTI_CONVERTER_DISPLAY_CHAR_SELECT;
uint8_t g_w = canvas_glyph_width(canvas, g);
if (i < 16 && i > multi_converter_get_unit(multi_converter_state->unit_type_orig).max_number_keys-1) { if(i < 16 &&
// some units won't use the full [0] - [F] keyboard, in those situations just hide the char i > multi_converter_get_unit(multi_converter_state->unit_type_orig).max_number_keys -
// (won't be selectable anyway, so no worries here; this is just about drawing stuff) 1) {
g = MULTI_CONVERTER_DISPLAY_CHAR_BLANK; // some units won't use the full [0] - [F] keyboard, in those situations just hide the char
} // (won't be selectable anyway, so no worries here; this is just about drawing stuff)
g = MULTI_CONVERTER_DISPLAY_CHAR_BLANK;
}
// currently hover key is highlighted // currently hover key is highlighted
if ((multi_converter_state->display).key == i) { if((multi_converter_state->display).key == i) {
canvas_draw_box(canvas, canvas_draw_box(
_x - MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN, canvas,
_y - (MULTI_CONVERTER_DISPLAY_KEY_CHAR_HEIGHT + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN), _x - MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN,
MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN + g_w + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN, _y - (MULTI_CONVERTER_DISPLAY_KEY_CHAR_HEIGHT +
MULTI_CONVERTER_DISPLAY_KEY_CHAR_HEIGHT + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN * 2 MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN),
); MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN + g_w +
canvas_set_color(canvas, ColorWhite); MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN,
} else { MULTI_CONVERTER_DISPLAY_KEY_CHAR_HEIGHT +
canvas_draw_frame(canvas, MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN * 2);
_x - MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN, canvas_set_color(canvas, ColorWhite);
_y - (MULTI_CONVERTER_DISPLAY_KEY_CHAR_HEIGHT + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN), } else {
MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN + g_w + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN, canvas_draw_frame(
MULTI_CONVERTER_DISPLAY_KEY_CHAR_HEIGHT + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN * 2 canvas,
); _x - MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN,
} _y - (MULTI_CONVERTER_DISPLAY_KEY_CHAR_HEIGHT +
MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN),
MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN + g_w +
MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN,
MULTI_CONVERTER_DISPLAY_KEY_CHAR_HEIGHT +
MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN * 2);
}
// draw key // draw key
canvas_draw_glyph(canvas, _x, _y, g); canvas_draw_glyph(canvas, _x, _y, g);
// certain keys have long_press features, draw whatever they're using there too // certain keys have long_press features, draw whatever they're using there too
if (i == MULTI_CONVERTER_DISPLAY_KEY_NEGATIVE) { if(i == MULTI_CONVERTER_DISPLAY_KEY_NEGATIVE) {
canvas_draw_box(canvas, canvas_draw_box(
_x + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN + g_w - 4, canvas,
_y + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN - 2, _x + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN + g_w - 4,
4, _y + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN - 2,
2 4,
); 2);
} else if (i == MULTI_CONVERTER_DISPLAY_KEY_COMMA) { } else if(i == MULTI_CONVERTER_DISPLAY_KEY_COMMA) {
canvas_draw_box(canvas, canvas_draw_box(
_x + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN + g_w - 2, canvas,
_y + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN - 2, _x + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN + g_w - 2,
2, _y + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN - 2,
2 2,
); 2);
} }
// back to black // back to black
canvas_set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
if (i < 8) {
_x += g_w + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN * 2 + 2;
} else if (i == 8) {
_y += (MULTI_CONVERTER_DISPLAY_KEY_CHAR_HEIGHT + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN * 2) + 3;
_x = 8; // some padding at the beginning on second line
} else {
_x += g_w + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN * 2 + 1;
}
}
if(i < 8) {
_x += g_w + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN * 2 + 2;
} else if(i == 8) {
_y += (MULTI_CONVERTER_DISPLAY_KEY_CHAR_HEIGHT +
MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN * 2) +
3;
_x = 8; // some padding at the beginning on second line
} else {
_x += g_w + MULTI_CONVERTER_DISPLAY_KEY_FRAME_MARGIN * 2 + 1;
}
}
} }
void multi_converter_mode_display_navigation(InputKey key, MultiConverterState* const multi_converter_state) { void multi_converter_mode_display_navigation(
InputKey key,
MultiConverterState* const multi_converter_state) {
// first move to keyboard position, then check if the ORIGIN allows that specific key, if not jump to the "closest one"
switch(key) {
default:
break;
// first move to keyboard position, then check if the ORIGIN allows that specific key, if not jump to the "closest one" case InputKeyUp:
switch (key) { case InputKeyDown:
if((multi_converter_state->display).key >= 9)
(multi_converter_state->display).key -= 9;
else
(multi_converter_state->display).key += 9;
break;
default: case InputKeyLeft:
break; case InputKeyRight:
case InputKeyUp: (multi_converter_state->display).key += (key == InputKeyLeft ? -1 : 1);
case InputKeyDown:
if ((multi_converter_state->display).key >= 9) (multi_converter_state->display).key -= 9;
else (multi_converter_state->display).key += 9;
break;
case InputKeyLeft: if((multi_converter_state->display).key > MULTI_CONVERTER_DISPLAY_KEYS - 1)
case InputKeyRight: (multi_converter_state->display).key = 0;
else if((multi_converter_state->display).key < 0)
(multi_converter_state->display).key = MULTI_CONVERTER_DISPLAY_KEYS - 1;
break;
}
(multi_converter_state->display).key += (key == InputKeyLeft ? -1 : 1); // if destination key is disabled by max_number_keys, move to the closest one
// (this could be improved with more accurate keys movements, probably...)
if(multi_converter_get_unit(multi_converter_state->unit_type_orig).max_number_keys >= 16)
return; // weird, since this means "do not show any number on the keyboard, but just in case..."
if ((multi_converter_state->display).key > MULTI_CONVERTER_DISPLAY_KEYS-1) (multi_converter_state->display).key = 0; int8_t i = -1;
else if ((multi_converter_state->display).key < 0) (multi_converter_state->display).key = MULTI_CONVERTER_DISPLAY_KEYS-1; if(key == InputKeyRight || key == InputKeyDown) i = 1;
break;
}
// if destination key is disabled by max_number_keys, move to the closest one
// (this could be improved with more accurate keys movements, probably...)
if (multi_converter_get_unit(multi_converter_state->unit_type_orig).max_number_keys >= 16) return; // weird, since this means "do not show any number on the keyboard, but just in case..."
int8_t i = -1;
if (key == InputKeyRight || key == InputKeyDown) i = 1;
while ((multi_converter_state->display).key < 16 && (multi_converter_state->display).key > multi_converter_get_unit(multi_converter_state->unit_type_orig).max_number_keys-1) {
(multi_converter_state->display).key += i;
if ((multi_converter_state->display).key > MULTI_CONVERTER_DISPLAY_KEYS-1) (multi_converter_state->display).key = 0;
else if ((multi_converter_state->display).key < 0) (multi_converter_state->display).key = MULTI_CONVERTER_DISPLAY_KEYS-1;
}
while((multi_converter_state->display).key < 16 &&
(multi_converter_state->display).key >
multi_converter_get_unit(multi_converter_state->unit_type_orig).max_number_keys -
1) {
(multi_converter_state->display).key += i;
if((multi_converter_state->display).key > MULTI_CONVERTER_DISPLAY_KEYS - 1)
(multi_converter_state->display).key = 0;
else if((multi_converter_state->display).key < 0)
(multi_converter_state->display).key = MULTI_CONVERTER_DISPLAY_KEYS - 1;
}
} }
void multi_converter_mode_display_reset(MultiConverterState* const multi_converter_state) { void multi_converter_mode_display_reset(MultiConverterState* const multi_converter_state) {
// clean the buffers
for(int i = 0; i < MULTI_CONVERTER_NUMBER_DIGITS; i++) {
multi_converter_state->buffer_orig[i] = MULTI_CONVERTER_DISPLAY_CHAR_BLANK;
multi_converter_state->buffer_dest[i] = MULTI_CONVERTER_DISPLAY_CHAR_BLANK;
}
// clean the buffers // reset the display flags and index
for (int i = 0; i < MULTI_CONVERTER_NUMBER_DIGITS; i++) { multi_converter_state->display.cursor = 0;
multi_converter_state->buffer_orig[i] = MULTI_CONVERTER_DISPLAY_CHAR_BLANK; multi_converter_state->display.key = 0;
multi_converter_state->buffer_dest[i] = MULTI_CONVERTER_DISPLAY_CHAR_BLANK; multi_converter_state->display.comma = 0;
} multi_converter_state->display.negative = 0;
// reset the display flags and index
multi_converter_state->display.cursor = 0;
multi_converter_state->display.key = 0;
multi_converter_state->display.comma = 0;
multi_converter_state->display.negative = 0;
} }
void multi_converter_mode_display_toggle_negative(MultiConverterState* const multi_converter_state) { void multi_converter_mode_display_toggle_negative(
if (multi_converter_get_unit(multi_converter_state->unit_type_orig).allow_negative) { MultiConverterState* const multi_converter_state) {
if(multi_converter_get_unit(multi_converter_state->unit_type_orig).allow_negative) {
if (!(multi_converter_state->display).negative) { if(!(multi_converter_state->display).negative) {
// shift origin buffer one to right + add the "-" sign (last digit will be lost) // shift origin buffer one to right + add the "-" sign (last digit will be lost)
for (int i = MULTI_CONVERTER_NUMBER_DIGITS-1; i > 0; i--) { for(int i = MULTI_CONVERTER_NUMBER_DIGITS - 1; i > 0; i--) {
// we could avoid the blanks, but nevermind // we could avoid the blanks, but nevermind
multi_converter_state->buffer_orig[i] = multi_converter_state->buffer_orig[i-1]; multi_converter_state->buffer_orig[i] = multi_converter_state->buffer_orig[i - 1];
} }
multi_converter_state->buffer_orig[0] = MULTI_CONVERTER_DISPLAY_CHAR_NEGATIVE; multi_converter_state->buffer_orig[0] = MULTI_CONVERTER_DISPLAY_CHAR_NEGATIVE;
// only increment cursor if we're not out of bound // only increment cursor if we're not out of bound
if ((multi_converter_state->display).cursor < MULTI_CONVERTER_NUMBER_DIGITS) (multi_converter_state->display).cursor++; if((multi_converter_state->display).cursor < MULTI_CONVERTER_NUMBER_DIGITS)
} else { (multi_converter_state->display).cursor++;
// shift origin buffer one to left, append ' ' on the end } else {
for (int i = 0; i < MULTI_CONVERTER_NUMBER_DIGITS-1; i++) { // shift origin buffer one to left, append ' ' on the end
if (multi_converter_state->buffer_orig[i] == MULTI_CONVERTER_DISPLAY_CHAR_BLANK) break; for(int i = 0; i < MULTI_CONVERTER_NUMBER_DIGITS - 1; i++) {
if(multi_converter_state->buffer_orig[i] == MULTI_CONVERTER_DISPLAY_CHAR_BLANK)
break;
multi_converter_state->buffer_orig[i] = multi_converter_state->buffer_orig[i+1]; multi_converter_state->buffer_orig[i] = multi_converter_state->buffer_orig[i + 1];
} }
multi_converter_state->buffer_orig[MULTI_CONVERTER_NUMBER_DIGITS-1] = MULTI_CONVERTER_DISPLAY_CHAR_BLANK; multi_converter_state->buffer_orig[MULTI_CONVERTER_NUMBER_DIGITS - 1] =
MULTI_CONVERTER_DISPLAY_CHAR_BLANK;
(multi_converter_state->display).cursor--; (multi_converter_state->display).cursor--;
} }
// toggle flag // toggle flag
(multi_converter_state->display).negative ^= 1; (multi_converter_state->display).negative ^= 1;
} }
} }
void multi_converter_mode_display_add_comma(MultiConverterState* const multi_converter_state) { void multi_converter_mode_display_add_comma(MultiConverterState* const multi_converter_state) {
if ( if(!multi_converter_get_unit(multi_converter_state->unit_type_orig).allow_comma ||
!multi_converter_get_unit(multi_converter_state->unit_type_orig).allow_comma || (multi_converter_state->display).comma || !(multi_converter_state->display).cursor ||
(multi_converter_state->display).comma || ((multi_converter_state->display).cursor == (MULTI_CONVERTER_NUMBER_DIGITS - 1)))
!(multi_converter_state->display).cursor || return; // maybe not allowerd; or one comma already in place; also cannot add commas as first or last chars
((multi_converter_state->display).cursor == (MULTI_CONVERTER_NUMBER_DIGITS - 1))
) return; // maybe not allowerd; or one comma already in place; also cannot add commas as first or last chars
// set flag to one // set flag to one
(multi_converter_state->display).comma = 1; (multi_converter_state->display).comma = 1;
multi_converter_state->buffer_orig[(multi_converter_state->display).cursor] = MULTI_CONVERTER_DISPLAY_CHAR_COMMA; multi_converter_state->buffer_orig[(multi_converter_state->display).cursor] =
(multi_converter_state->display).cursor++; MULTI_CONVERTER_DISPLAY_CHAR_COMMA;
(multi_converter_state->display).cursor++;
} }
void multi_converter_mode_display_add_number(MultiConverterState* const multi_converter_state) { void multi_converter_mode_display_add_number(MultiConverterState* const multi_converter_state) {
if ((multi_converter_state->display).key > multi_converter_get_unit(multi_converter_state->unit_type_orig).max_number_keys-1) return; if((multi_converter_state->display).key >
multi_converter_get_unit(multi_converter_state->unit_type_orig).max_number_keys - 1)
return;
if ((multi_converter_state->display).key < 10) { if((multi_converter_state->display).key < 10) {
multi_converter_state->buffer_orig[(multi_converter_state->display).cursor] = (multi_converter_state->display).key + '0'; multi_converter_state->buffer_orig[(multi_converter_state->display).cursor] =
} else { (multi_converter_state->display).key + '0';
multi_converter_state->buffer_orig[(multi_converter_state->display).cursor] = ((multi_converter_state->display).key - 10) + 'A'; } else {
} multi_converter_state->buffer_orig[(multi_converter_state->display).cursor] =
((multi_converter_state->display).key - 10) + 'A';
}
(multi_converter_state->display).cursor++; (multi_converter_state->display).cursor++;
} }
MultiConverterModeTrigger multi_converter_mode_display_ok(uint8_t long_press, MultiConverterState* const multi_converter_state) { MultiConverterModeTrigger multi_converter_mode_display_ok(
uint8_t long_press,
MultiConverterState* const multi_converter_state) {
if((multi_converter_state->display).key < MULTI_CONVERTER_DISPLAY_KEY_DEL) {
if((multi_converter_state->display).cursor >= MULTI_CONVERTER_NUMBER_DIGITS)
return None; // limit reached, ignore
if ((multi_converter_state->display).key < MULTI_CONVERTER_DISPLAY_KEY_DEL) { // long press on 0 toggle NEGATIVE if allowed, on 1 adds COMMA if allowed
if ((multi_converter_state->display).cursor >= MULTI_CONVERTER_NUMBER_DIGITS) return None; // limit reached, ignore if(long_press) {
if((multi_converter_state->display).key == MULTI_CONVERTER_DISPLAY_KEY_NEGATIVE) {
// toggle negative
multi_converter_mode_display_toggle_negative(multi_converter_state);
} else if((multi_converter_state->display).key == MULTI_CONVERTER_DISPLAY_KEY_COMMA) {
// add comma
multi_converter_mode_display_add_comma(multi_converter_state);
}
// long press on 0 toggle NEGATIVE if allowed, on 1 adds COMMA if allowed } else {
if (long_press) { // regular keys
multi_converter_mode_display_add_number(multi_converter_state);
}
if ((multi_converter_state->display).key == MULTI_CONVERTER_DISPLAY_KEY_NEGATIVE) { multi_converter_mode_display_convert(multi_converter_state);
// toggle negative
multi_converter_mode_display_toggle_negative(multi_converter_state);
} else if ((multi_converter_state->display).key == MULTI_CONVERTER_DISPLAY_KEY_COMMA) {
// add comma
multi_converter_mode_display_add_comma(multi_converter_state);
}
} else { } else if((multi_converter_state->display).key == MULTI_CONVERTER_DISPLAY_KEY_DEL) {
// regular keys if((multi_converter_state->display).cursor > 0) (multi_converter_state->display).cursor--;
multi_converter_mode_display_add_number(multi_converter_state);
}
multi_converter_mode_display_convert(multi_converter_state); if(multi_converter_state->buffer_orig[(multi_converter_state->display).cursor] ==
MULTI_CONVERTER_DISPLAY_CHAR_COMMA)
(multi_converter_state->display).comma = 0;
if(multi_converter_state->buffer_orig[(multi_converter_state->display).cursor] ==
MULTI_CONVERTER_DISPLAY_CHAR_NEGATIVE)
(multi_converter_state->display).negative = 0;
} else if ((multi_converter_state->display).key == MULTI_CONVERTER_DISPLAY_KEY_DEL) { multi_converter_state->buffer_orig[(multi_converter_state->display).cursor] =
if ((multi_converter_state->display).cursor > 0) (multi_converter_state->display).cursor--; MULTI_CONVERTER_DISPLAY_CHAR_BLANK;
if (multi_converter_state->buffer_orig[(multi_converter_state->display).cursor] == MULTI_CONVERTER_DISPLAY_CHAR_COMMA) (multi_converter_state->display).comma = 0; multi_converter_mode_display_convert(multi_converter_state);
if (multi_converter_state->buffer_orig[(multi_converter_state->display).cursor] == MULTI_CONVERTER_DISPLAY_CHAR_NEGATIVE) (multi_converter_state->display).negative = 0;
multi_converter_state->buffer_orig[(multi_converter_state->display).cursor] = MULTI_CONVERTER_DISPLAY_CHAR_BLANK; } else { // MULTI_CONVERTER_DISPLAY_KEY_SELECT
return Reset;
multi_converter_mode_display_convert(multi_converter_state); }
} else { // MULTI_CONVERTER_DISPLAY_KEY_SELECT
return Reset;
}
return None;
return None;
} }

View File

@@ -16,12 +16,16 @@ void multi_converter_mode_display_convert(MultiConverterState* const multi_conve
// //
// draw the main DISPLAY view with the current multi_converter_state values // draw the main DISPLAY view with the current multi_converter_state values
// //
void multi_converter_mode_display_draw(Canvas* const canvas, const MultiConverterState* multi_converter_state); void multi_converter_mode_display_draw(
Canvas* const canvas,
const MultiConverterState* multi_converter_state);
// //
// keyboard navigation on DISPLAY mode (NAVIGATION only, no BACK nor OK - InputKey guaranteed to be left/right/up/down) // keyboard navigation on DISPLAY mode (NAVIGATION only, no BACK nor OK - InputKey guaranteed to be left/right/up/down)
// //
void multi_converter_mode_display_navigation(InputKey key, MultiConverterState* const multi_converter_state); void multi_converter_mode_display_navigation(
InputKey key,
MultiConverterState* const multi_converter_state);
// //
// reset the DISPLAY mode with the current units, cleaning the buffers and different flags; // reset the DISPLAY mode with the current units, cleaning the buffers and different flags;
@@ -52,4 +56,6 @@ void multi_converter_mode_display_add_number(MultiConverterState* const multi_co
// handle the OK action when selecting a specific key on the keyboard (add a number, a symbol, change mode...) // handle the OK action when selecting a specific key on the keyboard (add a number, a symbol, change mode...)
// returns a ModeTrigger enum value: may or may not let to a mode change on the main loop (WON'T change the mode here) // returns a ModeTrigger enum value: may or may not let to a mode change on the main loop (WON'T change the mode here)
// //
MultiConverterModeTrigger multi_converter_mode_display_ok(uint8_t long_press, MultiConverterState* const multi_converter_state); MultiConverterModeTrigger multi_converter_mode_display_ok(
uint8_t long_press,
MultiConverterState* const multi_converter_state);

View File

@@ -1,160 +1,210 @@
#include "multi_converter_mode_select.h" #include "multi_converter_mode_select.h"
#define MULTI_CONVERTER_LIST_ENTRIES_COUNT 3 #define MULTI_CONVERTER_LIST_ENTRIES_COUNT 3
#define MULTI_CONVERTER_INFO_STRING_FROM "FROM:" #define MULTI_CONVERTER_INFO_STRING_FROM "FROM:"
#define MULTI_CONVERTER_INFO_STRING_TO "TO:" #define MULTI_CONVERTER_INFO_STRING_TO "TO:"
#define MULTI_CONVERTER_INFO_STRING_OK "OK: Change" #define MULTI_CONVERTER_INFO_STRING_OK "OK: Change"
#define MULTI_CONVERTER_INFO_STRING_BACK "BACK: Cancel" #define MULTI_CONVERTER_INFO_STRING_BACK "BACK: Cancel"
void multi_converter_mode_select_draw_destination_offset(uint8_t x, uint8_t y, int8_t d, Canvas* const canvas, const MultiConverterState* multi_converter_state) { void multi_converter_mode_select_draw_destination_offset(
int i = 1; uint8_t x,
while (i < MULTI_CONVERTER_AVAILABLE_UNITS) { // in case there's no match, to avoid an endless loop (in theory shouldn't happen, but...) uint8_t y,
int ut = multi_converter_get_unit_type_offset((multi_converter_state->select).selected_unit_type_dest, i * d); int8_t d,
if ( Canvas* const canvas,
multi_converter_available_units[(multi_converter_state->select).selected_unit_type_orig].allowed_function(ut) && const MultiConverterState* multi_converter_state) {
(multi_converter_state->select).selected_unit_type_orig != ut int i = 1;
) { while(
canvas_draw_str(canvas, x, y, multi_converter_available_units[ut].name); i <
break; MULTI_CONVERTER_AVAILABLE_UNITS) { // in case there's no match, to avoid an endless loop (in theory shouldn't happen, but...)
} int ut = multi_converter_get_unit_type_offset(
i++; (multi_converter_state->select).selected_unit_type_dest, i * d);
} if(multi_converter_available_units[(multi_converter_state->select).selected_unit_type_orig]
.allowed_function(ut) &&
(multi_converter_state->select).selected_unit_type_orig != ut) {
canvas_draw_str(canvas, x, y, multi_converter_available_units[ut].name);
break;
}
i++;
}
} }
void multi_converter_mode_select_draw_selected_unit(uint8_t x, uint8_t y, MultiConverterUnitType unit_type, Canvas* const canvas) { void multi_converter_mode_select_draw_selected_unit(
canvas_draw_box(canvas, x - 2 , y - 10, canvas_string_width(canvas, multi_converter_available_units[unit_type].name) + 4, 13); uint8_t x,
canvas_set_color(canvas, ColorWhite); uint8_t y,
canvas_draw_str(canvas, x, y, multi_converter_available_units[unit_type].name); MultiConverterUnitType unit_type,
canvas_set_color(canvas, ColorBlack); Canvas* const canvas) {
canvas_draw_box(
canvas,
x - 2,
y - 10,
canvas_string_width(canvas, multi_converter_available_units[unit_type].name) + 4,
13);
canvas_set_color(canvas, ColorWhite);
canvas_draw_str(canvas, x, y, multi_converter_available_units[unit_type].name);
canvas_set_color(canvas, ColorBlack);
} }
void multi_converter_mode_select_draw(Canvas* const canvas, const MultiConverterState* multi_converter_state) { void multi_converter_mode_select_draw(
Canvas* const canvas,
const MultiConverterState* multi_converter_state) {
int y = 10;
int x = 10;
int y = 10; canvas_set_color(canvas, ColorBlack);
int x = 10;
canvas_set_color(canvas, ColorBlack); // FROM
canvas_set_font(canvas, FontPrimary);
canvas_draw_str(canvas, x, y, MULTI_CONVERTER_INFO_STRING_FROM);
// FROM canvas_set_font(canvas, FontSecondary);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str(canvas, x, y, MULTI_CONVERTER_INFO_STRING_FROM);
canvas_set_font(canvas, FontSecondary); // offset -1
y += 12;
// offset -1 canvas_draw_str(
y += 12; canvas,
x,
y,
multi_converter_available_units[multi_converter_get_unit_type_offset(
(multi_converter_state->select).selected_unit_type_orig,
-1)]
.name);
canvas_draw_str(canvas, x, y, multi_converter_available_units[ multi_converter_get_unit_type_offset((multi_converter_state->select).selected_unit_type_orig, -1) ].name); // current selected element
y += 12;
// current selected element multi_converter_mode_select_draw_selected_unit(
y += 12; x, y, (multi_converter_state->select).selected_unit_type_orig, canvas);
multi_converter_mode_select_draw_selected_unit(x, y, (multi_converter_state->select).selected_unit_type_orig, canvas); if((multi_converter_state->select).select_orig) canvas_draw_str(canvas, x - 6, y, ">");
if ((multi_converter_state->select).select_orig) canvas_draw_str(canvas, x - 6, y, ">"); // offset +1
y += 12;
// offset +1 canvas_draw_str(
y += 12; canvas,
x,
y,
multi_converter_available_units[multi_converter_get_unit_type_offset(
(multi_converter_state->select).selected_unit_type_orig,
1)]
.name);
canvas_draw_str(canvas, x, y, multi_converter_available_units[ multi_converter_get_unit_type_offset((multi_converter_state->select).selected_unit_type_orig, 1) ].name); // TO
y = 10;
x = 70;
// TO canvas_set_font(canvas, FontPrimary);
y = 10; canvas_draw_str(canvas, x, y, MULTI_CONVERTER_INFO_STRING_TO);
x = 70;
canvas_set_font(canvas, FontPrimary); canvas_set_font(canvas, FontSecondary);
canvas_draw_str(canvas, x, y, MULTI_CONVERTER_INFO_STRING_TO);
canvas_set_font(canvas, FontSecondary);
// offset -1: go back from current selected destination and find the first one valid (even if it's itself) // offset -1: go back from current selected destination and find the first one valid (even if it's itself)
y += 12; y += 12;
multi_converter_mode_select_draw_destination_offset(x, y, -1, canvas, multi_converter_state); multi_converter_mode_select_draw_destination_offset(x, y, -1, canvas, multi_converter_state);
// current selected element // current selected element
y += 12; y += 12;
multi_converter_mode_select_draw_selected_unit(x, y, (multi_converter_state->select).selected_unit_type_dest, canvas); multi_converter_mode_select_draw_selected_unit(
x, y, (multi_converter_state->select).selected_unit_type_dest, canvas);
if (!(multi_converter_state->select).select_orig) canvas_draw_str(canvas, x - 6, y, ">"); if(!(multi_converter_state->select).select_orig) canvas_draw_str(canvas, x - 6, y, ">");
// offset +1: same but on the opposite direction // offset +1: same but on the opposite direction
y += 12; y += 12;
multi_converter_mode_select_draw_destination_offset(x, y, 1, canvas, multi_converter_state); multi_converter_mode_select_draw_destination_offset(x, y, 1, canvas, multi_converter_state);
// OK / CANCEL // OK / CANCEL
canvas_set_color(canvas, ColorBlack); canvas_set_color(canvas, ColorBlack);
canvas_draw_box(canvas, 0, 64 - 12, canvas_string_width(canvas, MULTI_CONVERTER_INFO_STRING_OK) + 4, 12); canvas_draw_box(
canvas_draw_box(canvas, 128 - 4 - canvas_string_width(canvas, MULTI_CONVERTER_INFO_STRING_BACK), 64 - 12, canvas_string_width(canvas, "BACK: Cancel") + 4, 12); canvas, 0, 64 - 12, canvas_string_width(canvas, MULTI_CONVERTER_INFO_STRING_OK) + 4, 12);
canvas_draw_box(
canvas,
128 - 4 - canvas_string_width(canvas, MULTI_CONVERTER_INFO_STRING_BACK),
64 - 12,
canvas_string_width(canvas, "BACK: Cancel") + 4,
12);
canvas_set_color(canvas, ColorWhite); canvas_set_color(canvas, ColorWhite);
canvas_draw_str(canvas, 2, 64 - 3, MULTI_CONVERTER_INFO_STRING_OK); canvas_draw_str(canvas, 2, 64 - 3, MULTI_CONVERTER_INFO_STRING_OK);
canvas_draw_str(canvas, 128 - 2 - canvas_string_width(canvas, MULTI_CONVERTER_INFO_STRING_BACK), 64 - 3, MULTI_CONVERTER_INFO_STRING_BACK); canvas_draw_str(
canvas,
128 - 2 - canvas_string_width(canvas, MULTI_CONVERTER_INFO_STRING_BACK),
64 - 3,
MULTI_CONVERTER_INFO_STRING_BACK);
} }
void multi_converter_mode_select_reset(MultiConverterState* const multi_converter_state) { void multi_converter_mode_select_reset(MultiConverterState* const multi_converter_state) {
// initial pre-selected values are equal to the current selected values
(multi_converter_state->select).selected_unit_type_orig =
multi_converter_state->unit_type_orig;
(multi_converter_state->select).selected_unit_type_dest =
multi_converter_state->unit_type_dest;
// initial pre-selected values are equal to the current selected values (multi_converter_state->select).select_orig = 1;
(multi_converter_state->select).selected_unit_type_orig = multi_converter_state->unit_type_orig;
(multi_converter_state->select).selected_unit_type_dest = multi_converter_state->unit_type_dest;
(multi_converter_state->select).select_orig = 1;
} }
MultiConverterModeTrigger multi_converter_mode_select_exit(uint8_t save_changes, MultiConverterState* const multi_converter_state) { MultiConverterModeTrigger multi_converter_mode_select_exit(
if (save_changes) { uint8_t save_changes,
MultiConverterState* const multi_converter_state) {
if(save_changes) {
multi_converter_state->unit_type_dest =
(multi_converter_state->select).selected_unit_type_dest;
multi_converter_state->unit_type_dest = (multi_converter_state->select).selected_unit_type_dest; if(multi_converter_state->unit_type_orig ==
(multi_converter_state->select).selected_unit_type_orig) {
// if the ORIGIN unit didn't changed, just trigger the convert
if (multi_converter_state->unit_type_orig == (multi_converter_state->select).selected_unit_type_orig) { return Convert;
// if the ORIGIN unit didn't changed, just trigger the convert } else {
multi_converter_state->unit_type_orig =
(multi_converter_state->select).selected_unit_type_orig;
multi_converter_state->unit_type_dest =
(multi_converter_state->select).selected_unit_type_dest;
return Convert; return Reset;
} else { }
multi_converter_state->unit_type_orig = (multi_converter_state->select).selected_unit_type_orig; }
multi_converter_state->unit_type_dest = (multi_converter_state->select).selected_unit_type_dest;
return Reset; return None;
}
}
return None;
} }
void multi_converter_mode_select_switch(MultiConverterState* const multi_converter_state) { void multi_converter_mode_select_switch(MultiConverterState* const multi_converter_state) {
(multi_converter_state->select).select_orig ^= 1; (multi_converter_state->select).select_orig ^= 1;
} }
void multi_converter_mode_select_change_unit(int8_t direction, MultiConverterState* const multi_converter_state) { void multi_converter_mode_select_change_unit(
int8_t direction,
MultiConverterState* const multi_converter_state) {
MultiConverterUnitType d;
if((multi_converter_state->select).select_orig) {
(multi_converter_state->select).selected_unit_type_orig =
multi_converter_get_unit_type_offset(
(multi_converter_state->select).selected_unit_type_orig, direction);
d = (multi_converter_state->select).selected_unit_type_dest;
} else {
d = ((multi_converter_state->select).selected_unit_type_dest + direction) %
MULTI_CONVERTER_AVAILABLE_UNITS;
}
MultiConverterUnitType d; // check each unit with the ORIGIN allowed_function() to make sure we're selecting a valid DESTINATION
if ((multi_converter_state->select).select_orig) { // (when changing the ORIGIN unit the DIRECTION in which we'll switch the DESTINATION will be the SAME);
(multi_converter_state->select).selected_unit_type_orig = multi_converter_get_unit_type_offset((multi_converter_state->select).selected_unit_type_orig, direction); // also notice that ORIGIN must be DIFFERENT than DESTINATION
d = (multi_converter_state->select).selected_unit_type_dest; int i = 0;
} else { while(i < MULTI_CONVERTER_AVAILABLE_UNITS) {
d = ((multi_converter_state->select).selected_unit_type_dest + direction) % MULTI_CONVERTER_AVAILABLE_UNITS; if(multi_converter_available_units[(multi_converter_state->select).selected_unit_type_orig]
} .allowed_function(d) &&
(multi_converter_state->select).selected_unit_type_orig != d) {
// check each unit with the ORIGIN allowed_function() to make sure we're selecting a valid DESTINATION (multi_converter_state->select).selected_unit_type_dest = d;
// (when changing the ORIGIN unit the DIRECTION in which we'll switch the DESTINATION will be the SAME); break;
// also notice that ORIGIN must be DIFFERENT than DESTINATION }
int i = 0;
while (i < MULTI_CONVERTER_AVAILABLE_UNITS) {
if (
multi_converter_available_units[(multi_converter_state->select).selected_unit_type_orig].allowed_function(d) &&
(multi_converter_state->select).selected_unit_type_orig != d
) {
(multi_converter_state->select).selected_unit_type_dest = d;
break;
}
d = multi_converter_get_unit_type_offset(d, direction);
i++;
}
d = multi_converter_get_unit_type_offset(d, direction);
i++;
}
} }

View File

@@ -10,14 +10,25 @@
// //
// aux draw function for units offsets and draw stuff // aux draw function for units offsets and draw stuff
// //
void multi_converter_mode_select_draw_destination_offset(uint8_t x, uint8_t y, int8_t d, Canvas* const canvas, const MultiConverterState* multi_converter_state); void multi_converter_mode_select_draw_destination_offset(
uint8_t x,
uint8_t y,
int8_t d,
Canvas* const canvas,
const MultiConverterState* multi_converter_state);
void multi_converter_mode_select_draw_selected_unit(uint8_t x, uint8_t y, MultiConverterUnitType unit_type, Canvas* const canvas); void multi_converter_mode_select_draw_selected_unit(
uint8_t x,
uint8_t y,
MultiConverterUnitType unit_type,
Canvas* const canvas);
// //
// draw the main SELECT view with the current multi_converter_state values // draw the main SELECT view with the current multi_converter_state values
// //
void multi_converter_mode_select_draw(Canvas* const canvas, const MultiConverterState* multi_converter_state); void multi_converter_mode_select_draw(
Canvas* const canvas,
const MultiConverterState* multi_converter_state);
// //
// reset the SELECT mode view, showing as "pre-selected" the current working units // reset the SELECT mode view, showing as "pre-selected" the current working units
@@ -33,11 +44,13 @@ void multi_converter_mode_select_reset(MultiConverterState* const multi_converte
// prevent weird behaviours, so for now we're trusting the selected_unit_orig/dest_type values) // prevent weird behaviours, so for now we're trusting the selected_unit_orig/dest_type values)
// //
// returns an enum code MultiConverterDisplayTrigger based on doing nothing (cancel), triggering the display // returns an enum code MultiConverterDisplayTrigger based on doing nothing (cancel), triggering the display
// convert method or reseting the whole display mode (when fully changing the units) // convert method or reseting the whole display mode (when fully changing the units)
// //
// notice the MODE CHANGE itself is not done here but in the main loop (outside the call) via the ModeTrigger enum element // notice the MODE CHANGE itself is not done here but in the main loop (outside the call) via the ModeTrigger enum element
// //
MultiConverterModeTrigger multi_converter_mode_select_exit(uint8_t save_changes, MultiConverterState* const multi_converter_state); MultiConverterModeTrigger multi_converter_mode_select_exit(
uint8_t save_changes,
MultiConverterState* const multi_converter_state);
// //
// switch between selecting the ORIGIN or the DESTINATION unit on DISPLAY mode (since there're only // switch between selecting the ORIGIN or the DESTINATION unit on DISPLAY mode (since there're only
@@ -48,11 +61,13 @@ void multi_converter_mode_select_switch(MultiConverterState* const multi_convert
// //
// change the selected unit on SELECTED mode, using the select_orig flag to check if we're switching the // change the selected unit on SELECTED mode, using the select_orig flag to check if we're switching the
// ORIGIN or the DESTINATION unit; the DIRECTION (up or down to travel the array) is set as a param // ORIGIN or the DESTINATION unit; the DIRECTION (up or down to travel the array) is set as a param
// //
// when switching the ORIGIN one, reset the DESTINATION to the first valid unit (if the current one is not // when switching the ORIGIN one, reset the DESTINATION to the first valid unit (if the current one is not
// valid anymore); when switching the DESTINATION one, an allowed_function() check is performed in order to // valid anymore); when switching the DESTINATION one, an allowed_function() check is performed in order to
// properly set a valid destination unit. // properly set a valid destination unit.
// //
// (notice the draw step also perform which units are valid to display, so no worries about that here) // (notice the draw step also perform which units are valid to display, so no worries about that here)
// //
void multi_converter_mode_select_change_unit(int8_t direction, MultiConverterState* const multi_converter_state); void multi_converter_mode_select_change_unit(
int8_t direction,
MultiConverterState* const multi_converter_state);

View File

@@ -1,124 +1,126 @@
#include "multi_converter_units.h" #include "multi_converter_units.h"
#define MULTI_CONVERTER_CHAR_OVERFLOW '#' #define MULTI_CONVERTER_CHAR_OVERFLOW '#'
#define MULTI_CONVERTER_MAX_SUPORTED_INT 999999999 #define MULTI_CONVERTER_MAX_SUPORTED_INT 999999999
#define multi_converter_unit_set_overflow(b) for (int _i = 0; _i < MULTI_CONVERTER_NUMBER_DIGITS; _i++) b[_i] = MULTI_CONVERTER_CHAR_OVERFLOW; #define multi_converter_unit_set_overflow(b) \
for(int _i = 0; _i < MULTI_CONVERTER_NUMBER_DIGITS; _i++) \
b[_i] = MULTI_CONVERTER_CHAR_OVERFLOW;
// //
// DEC / HEX / BIN conversion // DEC / HEX / BIN conversion
// //
void multi_converter_unit_dec_hex_bin_convert(MultiConverterState* const multi_converter_state) { void multi_converter_unit_dec_hex_bin_convert(MultiConverterState* const multi_converter_state) {
char dest[MULTI_CONVERTER_NUMBER_DIGITS];
char dest[MULTI_CONVERTER_NUMBER_DIGITS]; int i = 0;
uint8_t overflow = 0;
int i = 0; int a = 0;
uint8_t overflow = 0; int r = 0;
uint8_t f = 1;
int a = 0;
int r = 0;
uint8_t f = 1;
switch(multi_converter_state->unit_type_orig) { switch(multi_converter_state->unit_type_orig) {
default: default:
break; break;
case UnitTypeDec: { case UnitTypeDec: {
a = atoi(multi_converter_state->buffer_orig); a = atoi(multi_converter_state->buffer_orig);
f = (multi_converter_state->unit_type_dest == UnitTypeHex ? 16 : 2); f = (multi_converter_state->unit_type_dest == UnitTypeHex ? 16 : 2);
break; break;
} }
case UnitTypeHex: case UnitTypeHex:
a = strtol(multi_converter_state->buffer_orig, NULL, 16); a = strtol(multi_converter_state->buffer_orig, NULL, 16);
f = (multi_converter_state->unit_type_dest == UnitTypeDec ? 10 : 2); f = (multi_converter_state->unit_type_dest == UnitTypeDec ? 10 : 2);
break; break;
case UnitTypeBin: case UnitTypeBin:
a = strtol(multi_converter_state->buffer_orig, NULL, 2); a = strtol(multi_converter_state->buffer_orig, NULL, 2);
f = (multi_converter_state->unit_type_dest == UnitTypeDec ? 10 : 16); f = (multi_converter_state->unit_type_dest == UnitTypeDec ? 10 : 16);
break; break;
} }
while (a > 0) { while(a > 0) {
r = a % f; r = a % f;
dest[i] = r + (r < 10 ? '0' : ('A' - 10) ); dest[i] = r + (r < 10 ? '0' : ('A' - 10));
a /= f; a /= f;
if (i++ >= MULTI_CONVERTER_NUMBER_DIGITS) { if(i++ >= MULTI_CONVERTER_NUMBER_DIGITS) {
overflow = 1; overflow = 1;
break; break;
} }
} }
if (overflow) {
multi_converter_unit_set_overflow(multi_converter_state->buffer_dest);
} else {
// copy DEST (reversed) to destination and append empty chars at the end
for (int j = 0; j < MULTI_CONVERTER_NUMBER_DIGITS; j++) {
if (i >= 1) multi_converter_state->buffer_dest[j] = dest[--i];
else multi_converter_state->buffer_dest[j] = ' ';
}
}
if(overflow) {
multi_converter_unit_set_overflow(multi_converter_state->buffer_dest);
} else {
// copy DEST (reversed) to destination and append empty chars at the end
for(int j = 0; j < MULTI_CONVERTER_NUMBER_DIGITS; j++) {
if(i >= 1)
multi_converter_state->buffer_dest[j] = dest[--i];
else
multi_converter_state->buffer_dest[j] = ' ';
}
}
} }
uint8_t multi_converter_unit_dec_hex_bin_allowed(MultiConverterUnitType unit_type) { uint8_t multi_converter_unit_dec_hex_bin_allowed(MultiConverterUnitType unit_type) {
return (unit_type == UnitTypeDec || unit_type == UnitTypeHex || unit_type == UnitTypeBin); return (unit_type == UnitTypeDec || unit_type == UnitTypeHex || unit_type == UnitTypeBin);
} }
// //
// CEL / FAR / KEL // CEL / FAR / KEL
// //
void multi_converter_unit_temperature_convert(MultiConverterState* const multi_converter_state) { void multi_converter_unit_temperature_convert(MultiConverterState* const multi_converter_state) {
double a = strtof(multi_converter_state->buffer_orig, NULL);
uint8_t overflow = 0;
double a = strtof(multi_converter_state->buffer_orig, NULL); switch(multi_converter_state->unit_type_orig) {
uint8_t overflow = 0; default:
break;
case UnitTypeCelsius:
if(multi_converter_state->unit_type_dest == UnitTypeFahernheit) {
// celsius to fahrenheit
a = (a * ((double)1.8)) + 32;
} else { // UnitTypeKelvin
a += ((double)273.15);
}
switch(multi_converter_state->unit_type_orig) { break;
default: case UnitTypeFahernheit:
break; // fahrenheit to celsius, always
case UnitTypeCelsius: a = (a - 32) / ((double)1.8);
if (multi_converter_state->unit_type_dest == UnitTypeFahernheit) { if(multi_converter_state->unit_type_dest == UnitTypeKelvin) {
// celsius to fahrenheit // if kelvin, add
a = (a * ((double) 1.8)) + 32; a += ((double)273.15);
} else { // UnitTypeKelvin }
a += ((double) 273.15);
}
break; break;
case UnitTypeFahernheit: case UnitTypeKelvin:
// fahrenheit to celsius, always // kelvin to celsius, always
a = (a - 32) / ((double) 1.8); a -= ((double)273.15);
if (multi_converter_state->unit_type_dest == UnitTypeKelvin) { if(multi_converter_state->unit_type_dest == UnitTypeFahernheit) {
// if kelvin, add // if fahernheit, convert
a += ((double) 273.15); a = (a * ((double)1.8)) + 32;
} }
break; break;
case UnitTypeKelvin: }
// kelvin to celsius, always
a -= ((double) 273.15);
if (multi_converter_state->unit_type_dest == UnitTypeFahernheit) {
// if fahernheit, convert
a = (a * ((double) 1.8)) + 32;
}
break; if(overflow) {
} multi_converter_unit_set_overflow(multi_converter_state->buffer_dest);
} else {
if (overflow) { int ret = snprintf(
multi_converter_unit_set_overflow(multi_converter_state->buffer_dest); multi_converter_state->buffer_dest, MULTI_CONVERTER_NUMBER_DIGITS + 1, "%.3lf", a);
} else {
int ret = snprintf(multi_converter_state->buffer_dest, MULTI_CONVERTER_NUMBER_DIGITS + 1, "%.3lf", a);
if (ret < 0) multi_converter_unit_set_overflow(multi_converter_state->buffer_dest);
}
if(ret < 0) multi_converter_unit_set_overflow(multi_converter_state->buffer_dest);
}
} }
uint8_t multi_converter_unit_temperature_allowed(MultiConverterUnitType unit_type) { uint8_t multi_converter_unit_temperature_allowed(MultiConverterUnitType unit_type) {
return (unit_type == UnitTypeCelsius || unit_type == UnitTypeFahernheit || unit_type == UnitTypeKelvin); return (
unit_type == UnitTypeCelsius || unit_type == UnitTypeFahernheit ||
unit_type == UnitTypeKelvin);
} }
// //
@@ -126,73 +128,102 @@ uint8_t multi_converter_unit_temperature_allowed(MultiConverterUnitType unit_typ
// //
void multi_converter_unit_distance_convert(MultiConverterState* const multi_converter_state) { void multi_converter_unit_distance_convert(MultiConverterState* const multi_converter_state) {
double a = strtof(multi_converter_state->buffer_orig, NULL); double a = strtof(multi_converter_state->buffer_orig, NULL);
uint8_t overflow = 0; uint8_t overflow = 0;
switch(multi_converter_state->unit_type_orig) { switch(multi_converter_state->unit_type_orig) {
default: default:
break; break;
case UnitTypeKilometers: case UnitTypeKilometers:
if (multi_converter_state->unit_type_dest == UnitTypeMeters) a *= ((double) 1000); if(multi_converter_state->unit_type_dest == UnitTypeMeters)
else if (multi_converter_state->unit_type_dest == UnitTypeCentimeters) a *= ((double) 100000); a *= ((double)1000);
else if (multi_converter_state->unit_type_dest == UnitTypeMiles) a *= ((double) 0.6213711); else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters)
else if (multi_converter_state->unit_type_dest == UnitTypeFeet) a *= ((double) 3280.839895013); a *= ((double)100000);
else if (multi_converter_state->unit_type_dest == UnitTypeInches) a *= ((double) 39370.078740157); else if(multi_converter_state->unit_type_dest == UnitTypeMiles)
break; a *= ((double)0.6213711);
case UnitTypeMeters: else if(multi_converter_state->unit_type_dest == UnitTypeFeet)
if (multi_converter_state->unit_type_dest == UnitTypeKilometers) a /= ((double) 1000); a *= ((double)3280.839895013);
else if (multi_converter_state->unit_type_dest == UnitTypeCentimeters) a *= ((double) 100); else if(multi_converter_state->unit_type_dest == UnitTypeInches)
else if (multi_converter_state->unit_type_dest == UnitTypeMiles) a *= ((double) 0.0006213711); a *= ((double)39370.078740157);
else if (multi_converter_state->unit_type_dest == UnitTypeFeet) a *= ((double) 3.280839895013); break;
else if (multi_converter_state->unit_type_dest == UnitTypeInches) a *= ((double) 39.370078740157); case UnitTypeMeters:
break; if(multi_converter_state->unit_type_dest == UnitTypeKilometers)
case UnitTypeCentimeters: a /= ((double)1000);
if (multi_converter_state->unit_type_dest == UnitTypeKilometers) a /= ((double) 100000); else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters)
else if (multi_converter_state->unit_type_dest == UnitTypeMeters) a /= ((double) 100); a *= ((double)100);
else if (multi_converter_state->unit_type_dest == UnitTypeMiles) a *= ((double) 0.000006213711); else if(multi_converter_state->unit_type_dest == UnitTypeMiles)
else if (multi_converter_state->unit_type_dest == UnitTypeFeet) a *= ((double) 0.03280839895013); a *= ((double)0.0006213711);
else if (multi_converter_state->unit_type_dest == UnitTypeInches) a *= ((double) 0.39370078740157); else if(multi_converter_state->unit_type_dest == UnitTypeFeet)
break; a *= ((double)3.280839895013);
else if(multi_converter_state->unit_type_dest == UnitTypeInches)
a *= ((double)39.370078740157);
break;
case UnitTypeCentimeters:
if(multi_converter_state->unit_type_dest == UnitTypeKilometers)
a /= ((double)100000);
else if(multi_converter_state->unit_type_dest == UnitTypeMeters)
a /= ((double)100);
else if(multi_converter_state->unit_type_dest == UnitTypeMiles)
a *= ((double)0.000006213711);
else if(multi_converter_state->unit_type_dest == UnitTypeFeet)
a *= ((double)0.03280839895013);
else if(multi_converter_state->unit_type_dest == UnitTypeInches)
a *= ((double)0.39370078740157);
break;
case UnitTypeMiles: case UnitTypeMiles:
if (multi_converter_state->unit_type_dest == UnitTypeKilometers) a *= ((double) 1.609344); if(multi_converter_state->unit_type_dest == UnitTypeKilometers)
else if (multi_converter_state->unit_type_dest == UnitTypeMeters) a *= ((double) 1609.344); a *= ((double)1.609344);
else if (multi_converter_state->unit_type_dest == UnitTypeCentimeters) a *= ((double) 160934.4); else if(multi_converter_state->unit_type_dest == UnitTypeMeters)
else if (multi_converter_state->unit_type_dest == UnitTypeFeet) a *= ((double) 5280); a *= ((double)1609.344);
else if (multi_converter_state->unit_type_dest == UnitTypeInches) a *= ((double) 63360); else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters)
break; a *= ((double)160934.4);
case UnitTypeFeet: else if(multi_converter_state->unit_type_dest == UnitTypeFeet)
if (multi_converter_state->unit_type_dest == UnitTypeKilometers) a *= ((double) 0.0003048); a *= ((double)5280);
else if (multi_converter_state->unit_type_dest == UnitTypeMeters) a *= ((double) 0.3048); else if(multi_converter_state->unit_type_dest == UnitTypeInches)
else if (multi_converter_state->unit_type_dest == UnitTypeCentimeters) a *= ((double) 30.48); a *= ((double)63360);
else if (multi_converter_state->unit_type_dest == UnitTypeMiles) a *= ((double) 0.000189393939394); break;
else if (multi_converter_state->unit_type_dest == UnitTypeInches) a *= ((double) 12); case UnitTypeFeet:
break; if(multi_converter_state->unit_type_dest == UnitTypeKilometers)
case UnitTypeInches: a *= ((double)0.0003048);
if (multi_converter_state->unit_type_dest == UnitTypeKilometers) a *= ((double) 0.0000254); else if(multi_converter_state->unit_type_dest == UnitTypeMeters)
else if (multi_converter_state->unit_type_dest == UnitTypeMeters) a *= ((double) 0.0254); a *= ((double)0.3048);
else if (multi_converter_state->unit_type_dest == UnitTypeCentimeters) a *= ((double) 2.54); else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters)
else if (multi_converter_state->unit_type_dest == UnitTypeMiles) a *= ((double) 0.0000157828282828); a *= ((double)30.48);
else if (multi_converter_state->unit_type_dest == UnitTypeFeet) a *= ((double) 0.0833333333333); else if(multi_converter_state->unit_type_dest == UnitTypeMiles)
break; a *= ((double)0.000189393939394);
else if(multi_converter_state->unit_type_dest == UnitTypeInches)
a *= ((double)12);
break;
case UnitTypeInches:
if(multi_converter_state->unit_type_dest == UnitTypeKilometers)
a *= ((double)0.0000254);
else if(multi_converter_state->unit_type_dest == UnitTypeMeters)
a *= ((double)0.0254);
else if(multi_converter_state->unit_type_dest == UnitTypeCentimeters)
a *= ((double)2.54);
else if(multi_converter_state->unit_type_dest == UnitTypeMiles)
a *= ((double)0.0000157828282828);
else if(multi_converter_state->unit_type_dest == UnitTypeFeet)
a *= ((double)0.0833333333333);
break;
}
} if(overflow) {
multi_converter_unit_set_overflow(multi_converter_state->buffer_dest);
} else {
int ret = snprintf(
multi_converter_state->buffer_dest, MULTI_CONVERTER_NUMBER_DIGITS + 1, "%lf", a);
if (overflow) { if(ret < 0) multi_converter_unit_set_overflow(multi_converter_state->buffer_dest);
multi_converter_unit_set_overflow(multi_converter_state->buffer_dest); }
} else {
int ret = snprintf(multi_converter_state->buffer_dest, MULTI_CONVERTER_NUMBER_DIGITS + 1, "%lf", a);
if (ret < 0) multi_converter_unit_set_overflow(multi_converter_state->buffer_dest);
}
} }
uint8_t multi_converter_unit_distance_allowed(MultiConverterUnitType unit_type) { uint8_t multi_converter_unit_distance_allowed(MultiConverterUnitType unit_type) {
return ( return (
unit_type == UnitTypeKilometers || unit_type == UnitTypeMeters || unit_type == UnitTypeCentimeters || unit_type == UnitTypeKilometers || unit_type == UnitTypeMeters ||
unit_type == UnitTypeMiles || unit_type == UnitTypeFeet || unit_type == UnitTypeInches unit_type == UnitTypeCentimeters || unit_type == UnitTypeMiles ||
); unit_type == UnitTypeFeet || unit_type == UnitTypeInches);
} }
// //
@@ -200,31 +231,31 @@ uint8_t multi_converter_unit_distance_allowed(MultiConverterUnitType unit_type)
// //
void multi_converter_unit_angle_convert(MultiConverterState* const multi_converter_state) { void multi_converter_unit_angle_convert(MultiConverterState* const multi_converter_state) {
double a = strtof(multi_converter_state->buffer_orig, NULL); double a = strtof(multi_converter_state->buffer_orig, NULL);
uint8_t overflow = 0; uint8_t overflow = 0;
switch(multi_converter_state->unit_type_orig) { switch(multi_converter_state->unit_type_orig) {
default: default:
break; break;
case UnitTypeDegree: case UnitTypeDegree:
if (multi_converter_state->unit_type_dest == UnitTypeRadian) a *= ((double) 0.0174532925199); if(multi_converter_state->unit_type_dest == UnitTypeRadian) a *= ((double)0.0174532925199);
break; break;
case UnitTypeRadian: case UnitTypeRadian:
if (multi_converter_state->unit_type_dest == UnitTypeDegree) a *= ((double) 57.2957795131); if(multi_converter_state->unit_type_dest == UnitTypeDegree) a *= ((double)57.2957795131);
break; break;
} }
if (overflow) { if(overflow) {
multi_converter_unit_set_overflow(multi_converter_state->buffer_dest); multi_converter_unit_set_overflow(multi_converter_state->buffer_dest);
} else { } else {
int ret = snprintf(
multi_converter_state->buffer_dest, MULTI_CONVERTER_NUMBER_DIGITS + 1, "%lf", a);
int ret = snprintf(multi_converter_state->buffer_dest, MULTI_CONVERTER_NUMBER_DIGITS + 1, "%lf", a); if(ret < 0) multi_converter_unit_set_overflow(multi_converter_state->buffer_dest);
}
if (ret < 0) multi_converter_unit_set_overflow(multi_converter_state->buffer_dest);
}
} }
uint8_t multi_converter_unit_angle_allowed(MultiConverterUnitType unit_type) { uint8_t multi_converter_unit_angle_allowed(MultiConverterUnitType unit_type) {
return (unit_type == UnitTypeDegree || unit_type == UnitTypeRadian); return (unit_type == UnitTypeDegree || unit_type == UnitTypeRadian);
} }

View File

@@ -8,7 +8,9 @@
#define MULTI_CONVERTER_AVAILABLE_UNITS 14 #define MULTI_CONVERTER_AVAILABLE_UNITS 14
#define multi_converter_get_unit(unit_type) multi_converter_available_units[unit_type] #define multi_converter_get_unit(unit_type) multi_converter_available_units[unit_type]
#define multi_converter_get_unit_type_offset(unit_type, offset) (((unit_type + offset) % MULTI_CONVERTER_AVAILABLE_UNITS + MULTI_CONVERTER_AVAILABLE_UNITS) % MULTI_CONVERTER_AVAILABLE_UNITS) #define multi_converter_get_unit_type_offset(unit_type, offset) \
(((unit_type + offset) % MULTI_CONVERTER_AVAILABLE_UNITS + MULTI_CONVERTER_AVAILABLE_UNITS) % \
MULTI_CONVERTER_AVAILABLE_UNITS)
// the modulo operation will fail with extremely large values on the units array // the modulo operation will fail with extremely large values on the units array
// DEC / HEX / BIN // DEC / HEX / BIN
@@ -31,41 +33,139 @@ uint8_t multi_converter_unit_angle_allowed(MultiConverterUnitType unit_type);
// each unit is made of comma? + negative? + keyboard_length + mini_name + name + convert function + allowed function // each unit is made of comma? + negative? + keyboard_length + mini_name + name + convert function + allowed function
// (setting functions as NULL will cause convert / select options to be ignored) // (setting functions as NULL will cause convert / select options to be ignored)
// //
static const MultiConverterUnit multi_converter_unit_dec = { 0, 0, 10, "DEC\0", "Decimal\0", multi_converter_unit_dec_hex_bin_convert, multi_converter_unit_dec_hex_bin_allowed }; static const MultiConverterUnit multi_converter_unit_dec = {
static const MultiConverterUnit multi_converter_unit_hex = { 0, 0, 16, "HEX\0", "Hexadecimal\0", multi_converter_unit_dec_hex_bin_convert, multi_converter_unit_dec_hex_bin_allowed }; 0,
static const MultiConverterUnit multi_converter_unit_bin = { 0, 0, 2, "BIN\0", "Binary\0", multi_converter_unit_dec_hex_bin_convert, multi_converter_unit_dec_hex_bin_allowed }; 0,
10,
"DEC\0",
"Decimal\0",
multi_converter_unit_dec_hex_bin_convert,
multi_converter_unit_dec_hex_bin_allowed};
static const MultiConverterUnit multi_converter_unit_hex = {
0,
0,
16,
"HEX\0",
"Hexadecimal\0",
multi_converter_unit_dec_hex_bin_convert,
multi_converter_unit_dec_hex_bin_allowed};
static const MultiConverterUnit multi_converter_unit_bin = {
0,
0,
2,
"BIN\0",
"Binary\0",
multi_converter_unit_dec_hex_bin_convert,
multi_converter_unit_dec_hex_bin_allowed};
static const MultiConverterUnit multi_converter_unit_cel = { 1, 1, 10, "CEL\0", "Celsius\0", multi_converter_unit_temperature_convert, multi_converter_unit_temperature_allowed }; static const MultiConverterUnit multi_converter_unit_cel = {
static const MultiConverterUnit multi_converter_unit_far = { 1, 1, 10, "FAR\0", "Fahernheit\0", multi_converter_unit_temperature_convert, multi_converter_unit_temperature_allowed }; 1,
static const MultiConverterUnit multi_converter_unit_kel = { 1, 1, 10, "KEL\0", "Kelvin\0", multi_converter_unit_temperature_convert, multi_converter_unit_temperature_allowed }; 1,
10,
"CEL\0",
"Celsius\0",
multi_converter_unit_temperature_convert,
multi_converter_unit_temperature_allowed};
static const MultiConverterUnit multi_converter_unit_far = {
1,
1,
10,
"FAR\0",
"Fahernheit\0",
multi_converter_unit_temperature_convert,
multi_converter_unit_temperature_allowed};
static const MultiConverterUnit multi_converter_unit_kel = {
1,
1,
10,
"KEL\0",
"Kelvin\0",
multi_converter_unit_temperature_convert,
multi_converter_unit_temperature_allowed};
static const MultiConverterUnit multi_converter_unit_km = { 1, 0, 10, "KM\0", "Kilometers\0", multi_converter_unit_distance_convert, multi_converter_unit_distance_allowed }; static const MultiConverterUnit multi_converter_unit_km = {
static const MultiConverterUnit multi_converter_unit_m = { 1, 0, 10, "M\0", "Meters\0", multi_converter_unit_distance_convert, multi_converter_unit_distance_allowed }; 1,
static const MultiConverterUnit multi_converter_unit_cm = { 1, 0, 10, "CM\0", "Centimeters\0", multi_converter_unit_distance_convert, multi_converter_unit_distance_allowed }; 0,
static const MultiConverterUnit multi_converter_unit_mi = { 1, 0, 10, "MI\0", "Miles\0", multi_converter_unit_distance_convert, multi_converter_unit_distance_allowed }; 10,
static const MultiConverterUnit multi_converter_unit_ft = { 1, 0, 10, "FT\0", "Feet\0", multi_converter_unit_distance_convert, multi_converter_unit_distance_allowed }; "KM\0",
static const MultiConverterUnit multi_converter_unit_in = { 1, 0, 10, " \"\0", "Inches\0", multi_converter_unit_distance_convert, multi_converter_unit_distance_allowed }; "Kilometers\0",
multi_converter_unit_distance_convert,
multi_converter_unit_distance_allowed};
static const MultiConverterUnit multi_converter_unit_m = {
1,
0,
10,
"M\0",
"Meters\0",
multi_converter_unit_distance_convert,
multi_converter_unit_distance_allowed};
static const MultiConverterUnit multi_converter_unit_cm = {
1,
0,
10,
"CM\0",
"Centimeters\0",
multi_converter_unit_distance_convert,
multi_converter_unit_distance_allowed};
static const MultiConverterUnit multi_converter_unit_mi = {
1,
0,
10,
"MI\0",
"Miles\0",
multi_converter_unit_distance_convert,
multi_converter_unit_distance_allowed};
static const MultiConverterUnit multi_converter_unit_ft = {
1,
0,
10,
"FT\0",
"Feet\0",
multi_converter_unit_distance_convert,
multi_converter_unit_distance_allowed};
static const MultiConverterUnit multi_converter_unit_in = {
1,
0,
10,
" \"\0",
"Inches\0",
multi_converter_unit_distance_convert,
multi_converter_unit_distance_allowed};
static const MultiConverterUnit multi_converter_unit_deg = { 1, 0, 10, "DEG\0", "Degree\0", multi_converter_unit_angle_convert, multi_converter_unit_angle_allowed }; static const MultiConverterUnit multi_converter_unit_deg = {
static const MultiConverterUnit multi_converter_unit_rad = { 1, 0, 10, "RAD\0", "Radian\0", multi_converter_unit_angle_convert, multi_converter_unit_angle_allowed }; 1,
0,
10,
"DEG\0",
"Degree\0",
multi_converter_unit_angle_convert,
multi_converter_unit_angle_allowed};
static const MultiConverterUnit multi_converter_unit_rad = {
1,
0,
10,
"RAD\0",
"Radian\0",
multi_converter_unit_angle_convert,
multi_converter_unit_angle_allowed};
// index order set by the MultiConverterUnitType enum element (multi_converter_definitions.h) // index order set by the MultiConverterUnitType enum element (multi_converter_definitions.h)
static const MultiConverterUnit multi_converter_available_units[MULTI_CONVERTER_AVAILABLE_UNITS] = { static const MultiConverterUnit multi_converter_available_units[MULTI_CONVERTER_AVAILABLE_UNITS] = {
[UnitTypeDec] = multi_converter_unit_dec, [UnitTypeDec] = multi_converter_unit_dec,
[UnitTypeHex] = multi_converter_unit_hex, [UnitTypeHex] = multi_converter_unit_hex,
[UnitTypeBin] = multi_converter_unit_bin, [UnitTypeBin] = multi_converter_unit_bin,
[UnitTypeCelsius] = multi_converter_unit_cel, [UnitTypeCelsius] = multi_converter_unit_cel,
[UnitTypeFahernheit] = multi_converter_unit_far, [UnitTypeFahernheit] = multi_converter_unit_far,
[UnitTypeKelvin] = multi_converter_unit_kel, [UnitTypeKelvin] = multi_converter_unit_kel,
[UnitTypeKilometers] = multi_converter_unit_km, [UnitTypeKilometers] = multi_converter_unit_km,
[UnitTypeMeters] = multi_converter_unit_m, [UnitTypeMeters] = multi_converter_unit_m,
[UnitTypeCentimeters] = multi_converter_unit_cm, [UnitTypeCentimeters] = multi_converter_unit_cm,
[UnitTypeMiles] = multi_converter_unit_mi, [UnitTypeMiles] = multi_converter_unit_mi,
[UnitTypeFeet] = multi_converter_unit_ft, [UnitTypeFeet] = multi_converter_unit_ft,
[UnitTypeInches] = multi_converter_unit_in, [UnitTypeInches] = multi_converter_unit_in,
[UnitTypeDegree] = multi_converter_unit_deg, [UnitTypeDegree] = multi_converter_unit_deg,
[UnitTypeRadian] = multi_converter_unit_rad, [UnitTypeRadian] = multi_converter_unit_rad,
}; };

0
lib/nfc/nfc_worker_i.h Executable file → Normal file
View File