summaryrefslogtreecommitdiffstats
path: root/keyboards/rubi/lib/calc.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/rubi/lib/calc.c')
-rw-r--r--keyboards/rubi/lib/calc.c261
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();
-
- }
-
-}