Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages | Examples

calc.c

Scientific calculator. Example of floating arithmetics and linking against -lm.
/*
 * Copyright (C) 2003 BLADOX, s.r.o.  All rights reserved.
 * 
 * This file is part of an example program for Turbo. This example
 * program may be used, distributed and modified without limitation.
 *
 */

#include <config.h>
#include <turbo/turbo.h>

#include <math.h>
#include <stdlib.h>

double result;

u8 calc_result (SCtx * ctx, u8 action);
u8 calc_plus (SCtx * ctx, u8 action);
u8 calc_sin (SCtx * ctx, u8 action);

SNode result_n = {
  NULL,
  calc_result,
  NULL
};

/* *INDENT-OFF* */

lc_char PROGMEM lc_Calc[]={
        LC_UN("SciCalc")
        LC_END
};

lc_char PROGMEM lc_Plus[]={
        LC_UN("+")
        LC_END
};

lc_char PROGMEM lc_Minus[]={
        LC_UN("-")
        LC_END
};

lc_char PROGMEM lc_Mult[]={
        LC_UN("*")
        LC_END
};

lc_char PROGMEM lc_Div[]={
        LC_UN("/")
        LC_END
};

lc_char PROGMEM lc_Cos[]={
        LC_UN("cos")
        LC_END
};

lc_char PROGMEM lc_Sin[]={
        LC_UN("sin")
        LC_END
};

/* *INDENT-ON* */

//#define DEBUG_X
#ifdef DEBUG_X

void __dbf (double f)
{
  u8 *s = &f;
  u8 r[20];

  dtostrf (f, 8, 4, r);
  dbs (r);
  dbsp (": ");
  dbch (s[0]);
  dbc (' ');
  dbch (s[1]);
  dbc (' ');
  dbch (s[2]);
  dbc (' ');
  dbch (s[3]);
  dbc ('\n');
}

#define dbf(a)  __dbf(a)
#else
#define dbf(a)
#endif

u8 calc_result (SCtx * ctx, u8 action)
{
  if (action == APP_ENTER)
  {
    u8 *res;
    u8 *t = buf_B ();

    res = t;
    res = sprinti (res, 0);
    res = sprintc (res, '\0');

    res = get_input (NULL, 1, 15, t, Q_GET_INPUT_ALPHABET);
    if (res == ENULL)
      return APP_END;
    if (res != NULL)
    {
      res[res[0] + 1] = '\0';
      result = atof (&res[2]);
    }
    return APP_BACK;
  }

  return APP_OK;
}

u8 calc_plus (SCtx * ctx, u8 action)
{
  if (action == APP_ENTER)
  {
    u8 *res;

    res = get_input (locale (lc_Plus), 1, 15, NULL, Q_GET_INPUT_ALPHABET);
    if (res == ENULL)
      return APP_END;
    if (res != NULL)
    {
      res[res[0] + 1] = '\0';
      result += atof (&res[2]);
    }
    return APP_BACK;
  }

  return APP_OK;
}

u8 calc_minus (SCtx * ctx, u8 action)
{
  if (action == APP_ENTER)
  {
    u8 *res;

    res = get_input (locale (lc_Minus), 1, 15, NULL, Q_GET_INPUT_ALPHABET);
    if (res == ENULL)
      return APP_END;
    if (res != NULL)
    {
      res[res[0] + 1] = '\0';
      result -= atof (&res[2]);
    }
    return APP_BACK;
  }

  return APP_OK;
}

u8 calc_mult (SCtx * ctx, u8 action)
{
  if (action == APP_ENTER)
  {
    u8 *res;

    res = get_input (locale (lc_Mult), 1, 15, NULL, Q_GET_INPUT_ALPHABET);
    if (res == ENULL)
      return APP_END;
    if (res != NULL)
    {
      res[res[0] + 1] = '\0';
      result *= atof (&res[2]);
    }
    return APP_BACK;
  }

  return APP_OK;
}

u8 calc_div (SCtx * ctx, u8 action)
{
  if (action == APP_ENTER)
  {
    u8 *res;

    res = get_input (locale (lc_Div), 1, 15, NULL, Q_GET_INPUT_ALPHABET);
    if (res == ENULL)
      return APP_END;
    if (res != NULL)
    {
      res[res[0] + 1] = '\0';
      result /= atof (&res[2]);
    }
    return APP_BACK;
  }

  return APP_OK;
}

u8 calc_cos (SCtx * ctx, u8 action)
{
  if (action == APP_ENTER)
  {
    result = cos (result);
    return APP_BACK;
  }
  return APP_OK;
}

u8 calc_sin (SCtx * ctx, u8 action)
{
  if (action == APP_ENTER)
  {
    result = sin (result);
    return APP_BACK;
  }
  return APP_OK;
}

u8 calc_ctx (SCtx * ctx, u8 action)
{
  if (action == APP_ENTER)
  {
    u8 *t, *r;
    double f;

#if 0
    u8 *s = &f;

    dbsp ("VALS\n");
    f = 0;
    dbf (f);
    f = 1;
    dbf (f);
    f = -1;
    dbf (f);
    f = 2;
    dbf (f);
    f = -2;
    dbf (f);
    f = 3;
    dbf (f);
    f = -3;
    dbf (f);
    f = sin (0.5);
    dbf (f);
#endif

    r = result_n.text = malloc (20);
    dtostrf (result, 8, 4, r);

    spider_set_order (ctx, ORDER_R, ORDER_P, ORDER_E, ORDER_D);
    spider_append_r (ctx, &result_n);
    ctx->n_default = 0;
    ctx->pref_item = 0;
  }
  else if (action == APP_LEAVE)
  {
    spider_clear_r (ctx);
    free (result_n.text);
  }

  return APP_OK;
}

SNodeP calc_n = { lc_Calc, calc_ctx };
SNodeP calc_n_sin = { lc_Sin, calc_sin };
SNodeP calc_n_cos = { lc_Cos, calc_cos };
SNodeP calc_n_plus = { lc_Plus, calc_plus };
SNodeP calc_n_minus = { lc_Minus, calc_minus };
SNodeP calc_n_mult = { lc_Mult, calc_mult };
SNodeP calc_n_div = { lc_Div, calc_div };

SEdgeP calc_edges_p[] = {
  {&calc_n, &calc_n_plus}
  ,
  {&calc_n, &calc_n_minus}
  ,
  {&calc_n, &calc_n_mult}
  ,
  {&calc_n, &calc_n_div}
  ,
  {&calc_n, &calc_n_sin}
  ,
  {&calc_n, &calc_n_cos}
  ,
  NULL
};

void action_menu (void *data)
{
  SCtx *c = spider_init ();

  if (c == NULL)
    return;
  c->n = &calc_n;
  c->eP = &calc_edges_p;

  spider (c);
}

void turbo_handler (u8 action, void *data)
{
  switch (action)
  {
    case ACTION_INSERT_MENU:
      insert_menu (locale (lc_Calc));
      break;
    case ACTION_MENU_SELECTION:
      result = 0;
      stk_thread (action_menu, data);
      break;
    default:
      break;
  }
}


Copyright © 2004-2006 BLADOX
Turbo version 1.2