diff options
Diffstat (limited to 'keyboards/rubi/lib/calc.c')
-rw-r--r-- | keyboards/rubi/lib/calc.c | 261 |
1 files changed, 0 insertions, 261 deletions
diff --git a/keyboards/rubi/lib/calc.c b/keyboards/rubi/lib/calc.c deleted file mode 100644 index 7796a9be45..0000000000 --- a/keyboards/rubi/lib/calc.c +++ /dev/null @@ -1,261 +0,0 @@ -/* -This is the modified version of [calculator by MWWorks](https://github.com/MWWorks/mw_calc_numpad/blob/master/calc.c). Below is the quote from [MWWorks](https://github.com/MWWorks). - - Calculator for QMK-based keyboard by MWWorks, https://mwworks.uk - This is free, usual disclaimers, don't use it to calculate megaton yields, surgery plans, etc - - I did not plan to reinvent the wheel for this - I figured surely somebody somewhere has working calculator code? - Found lots but none that actually work like you expect a calculator to, hence DIYing it - - As such, this is probably a bit janky, especially as I am a bit of a hack at C - Seems to be working well, with occasional glitchs, solved by clearing it - And some occasional floating-point issues - eg get a long decimal rather than the whole number you were expecting - Feel free to fix it! I think it needs to detect the precision of the two operands and then figure out what the precision of the result should be - -*/ -#include "rubi.h" - -static uint8_t calc_current_operand = 0; -static char calc_operand_0[CALC_DIGITS+1] = ""; -static char calc_operand_1[CALC_DIGITS+1] = ""; -char calc_result[CALC_DIGITS+1] = ""; -static char calc_status[CALC_DIGITS+1] = ""; -static char calc_operator = ' '; -static bool calc_reset = false; - - -void calcBegin(void){ -} - -//update display -void calcUpdate(void){ - if (calc_display_lines == 2) { - if((calc_current_operand == 1) || (calc_reset)){ - strcpy(calc_status, calc_operand_0); - if((strlen(calc_operand_0)>0) || (strlen(calc_operand_1)>0)){ - uint8_t len = strlen(calc_status); - if (!(calc_operator == 's' || calc_operator == 'r' || calc_operator == 'n')) { - calc_status[len] = calc_operator; - } - calc_status[len+1] = 0; - if(calc_reset - && !(calc_operator == 's' || calc_operator == 'r' || calc_operator == 'n')){ - strncat(calc_status, calc_operand_1, CALC_DIGITS-strlen(calc_status)); - calc_operator = ' '; - } - } - strcpy(calc_status_display, calc_status); - } - } else if (calc_display_lines == 1) { - if(calc_reset - && !(calc_operator == 's' || calc_operator == 'r' || calc_operator == 'n')){ - calc_operator = ' '; - } - } - calc_operator_display = calc_operator; - strcpy(calc_result_display, calc_result); -} - -//perform calculation on the 2 operands -void calcOperands(void){ - float result = 0; - switch (calc_operator){ - - //standard operators - case '+': - result = strtod(calc_operand_0, NULL) + strtod(calc_operand_1, NULL); - break; - - case '-': - result = strtod(calc_operand_0, NULL) - strtod(calc_operand_1, NULL); - break; - - case '/': - result = strtod(calc_operand_0, NULL) / strtod(calc_operand_1, NULL); - break; - - case '*': - result = strtod(calc_operand_0, NULL) * strtod(calc_operand_1, NULL); - break; - - //single operand operators - these are all in 2 - case 's': - result = sqrt(strtod(calc_operand_0, NULL)); - break; - - case 'r': - result = 1/(strtod(calc_operand_0, NULL)); - break; - - } - - //now convert the float result into a string - //we know the total string size but we need to find the size of the integer component to know how much we have for decimals - uint8_t magnitude = ceil(log10(result)); - uint8_t max_decimals = CALC_DIGITS-magnitude-1; - //but max it at 7 because that seems the useful limit of our floats - if(max_decimals>7){ - max_decimals = 7; - } - dtostrf(result, CALC_DIGITS, max_decimals, calc_result); - - //now to clean up the result - we need it clean as it may be the input of next calculation - //this seems a lot of code to format this string :| note that this c doesn't support float in sprintf - uint8_t i; - - //first find if theres a dot - uint8_t dotpos = CALC_DIGITS+1; - for(i=0; i<strlen(calc_result); i++){ - if(calc_result[i] == '.'){ - dotpos = i; - break; - } - } - - //if there is, work back to it and remove trailing 0 or . - if(dotpos>=0){ - for(i=strlen(calc_result)-1; i>=dotpos; i--){ - if((calc_result[i] == '0') || (calc_result[i] == '.')){ - calc_result[i] = 0; - }else{ - break; - } - } - } - - //now find how many leading spaces - uint8_t spaces = 0; - for(i=0; i<strlen(calc_result); i++){ - if(calc_result[i] == ' '){ - spaces++; - }else{ - break; - } - } - - //and shift the string - for(i=0; i<strlen(calc_result)-spaces; i++){ - calc_result[i] = calc_result[i+spaces]; - } - calc_result[strlen(calc_result)-spaces] = 0; - - calcUpdate(); - //the result is available as the first operand for another calculation - strcpy(calc_operand_0, calc_result); - calc_operand_1[0] = 0; - -} - -void calcInput(char input){ - char *operand = calc_operand_0; - if(calc_current_operand == 1){ - operand = calc_operand_1; - } - uint8_t len = strlen(operand); - - if( - ((input >= 48) && (input <= 57)) || - (input == '.') - ){ - //if this is following an equals, then we start from scratch as if new calculation - if(calc_reset == true){ - calc_reset = false; - calc_current_operand = 0; - calc_operand_0[0] = 0; - calc_operand_1[0] = 0; - operand = calc_operand_0; - len = 0; - } - - if(len<CALC_DIGITS){ - operand[len] = input; - operand[len+1] = 0; - strcpy(calc_result, operand); - calcUpdate(); - } - - //special input to backspace - }else if(input == 'x'){ - operand[len-1] = 0; - strcpy(calc_result, operand); - calcUpdate(); - - //clear - }else if(input == 'c'){ - operand[0] = 0; - calc_operand_0[0] = 0; - calc_operand_1[0] = 0; - calc_operator = ' '; - calc_reset = true; - strcpy(calc_result, operand); - calcUpdate(); - - //special input switch neg/pos - }else if((input == 'n') && (len>0)){ - uint8_t i; - - if(operand[0] == '-'){ - for(i=1; i<=len; i++){ - operand[i-1] = operand[i]; - } - }else if(len<CALC_DIGITS){ - for(i=0; i<=len; i++){ - operand[len-i+1] = operand[len-i]; - } - operand[0] = '-'; - } - calc_operator = input; - strcpy(calc_result, operand); - calcUpdate(); - - - //standard 2 operand operators - }else if((input == '+') || (input == '-') || (input == '*') || (input == '/')){ - - //get ready for second operand - if(calc_current_operand == 0){ - calc_operator = input; - calc_current_operand = 1; - calcUpdate(); - - //we pressed = we now expect a new second operand - }else if(calc_reset){ - calc_operator = input; - calc_reset = false; - calc_operand_1[0] = 0; - calcUpdate(); - - }else { - //if we use this on the second operand, calculate first, then ready for a second operand again - if (strlen(calc_operand_1)>0){ - calcOperands(); - } - calc_operand_1[0] = 0; - calc_operator = input; - calcUpdate(); - } - - - }else if(input == '='){ - //only accept = if we are on the second operand - if(calc_current_operand == 1){ - //keep the second operand for a subsequent press of =; but flag to reset if start entry of new operand - calc_reset = true; - calcOperands(); - } - - //single operands - square root and reciprocal - needs to operate on 0 so it works after a previous = result - }else if((input == 's') || (input == 'r')){ - //but maybe we started entering 1 - if(calc_current_operand == 1 && !calc_reset){ - strcpy(calc_operand_0, calc_operand_1); - } - calc_current_operand = 1; - calc_operand_1[0] = 0; - calc_operator = input; - calc_reset = true; //simulate another = - calcOperands(); - - } - -} |