Files
SyncHome/trunk/ulp/plugins/calculator.plugin.h
paolo.iocco ab6f495c89
2023-03-09 10:24:21 +00:00

298 lines
5.2 KiB
C

/**********************************************************
*
* A basic calculator.
*
* Plugin Definitions
* NAME = calculator
* DESC = Basic calculator
* AUTHOR = John Johnson
* TAB_NAME = Plugins
**********************************************************/
int UNARY_BEGIN = 0x80;
int ANGLE_IN = 0x40;
int ANGLE_OUT = 0x20;
enum {
OP_INVALID,
OP_CLEAR,
OP_ENTER,
OP_ADD,
OP_SUBTRACT,
OP_DIVIDE,
OP_MULTIPLY,
OP_RADIAN,
OP_DEGREE
};
enum {
OP_MEMORY_PLUS = 0x80 /* UNARY_BEGIN */,
OP_MEMORY_STORE,
OP_MEMORY_RECALL,
OP_MEMORY_CLEAR
};
enum {
OP_SINE = 0xC0 /* UNARY_BEGIN + ANGLE_IN */,
OP_COSINE,
OP_TANGENT,
OP_ARC_SINE,
OP_ARC_COSINE,
OP_ARC_TANGENT
};
enum {
OP_INV_SINE = 0xA0 /* UNARY_BEGIN + ANGLE_OUT */,
OP_INV_COSINE,
OP_INV_TANGENT
};
enum {
ANG_INVALID,
ANG_RADIAN,
ANG_DEGREE
/* ANG_GRADIANS - sorry */
};
int m_angle_mode;
string g_angle_mode_str;
int g_memory;
real accum;
real depth;
int passes;
string nc_file;
int unit_metric;
real length;
string result;
string m_result = "0";
string m_entry = "0";
string format_number(real n)
{
string tmp;
sprintf(tmp, "%f", n);
return tmp;
}
real set_accum(string s)
{
accum = strtod(s);
return accum;
}
string set_result(real r)
{
m_result = format_number(r);
// set_nv_param("calc_result", m_result);
return m_result;
}
real set_angle_mode(int mode)
{
real result;
string num;
int used_entry;
result = strtod(m_result);
if (m_entry != "") {
num = m_entry;
used_entry = 1;
}
else if (m_result != "") {
num = m_result;
}
else {
num = m_result;
}
if (m_angle_mode == ANG_DEGREE && mode == ANG_RADIAN) {
result = strtod(num) / 180 * PI;
}
else if (m_angle_mode == ANG_RADIAN && mode == ANG_DEGREE) {
result = strtod(num) / PI * 180;
}
m_angle_mode = mode;
switch (m_angle_mode) {
case ANG_RADIAN:
g_angle_mode_str = "rad";
break;
case ANG_DEGREE:
g_angle_mode_str = "deg";
break;
}
// set_nv_param("calc_angle_mode", g_angle_mode_str);
// if (used_entry) {
m_entry = format_number(result);
// }
// else {
set_result(result);
// }*/
return result;
}
string get_mode_str()
{
return (m_angle_mode == ANG_RADIAN) ? "rad" : "deg";
}
real rad(real n)
{
return (m_angle_mode == ANG_RADIAN) ? n : n / 180 * PI;
}
real unrad(real n)
{
return (m_angle_mode == ANG_RADIAN) ? n : n / PI * 180;
}
int is_unary(int op)
{
return (op & UNARY_BEGIN) ? 1 : 0;
}
void set_memory(real n)
{
string tmp;
g_memory = n;
// set_nv_param("calc_memory", format_number(n));
}
real get_memory()
{
return g_memory;
}
void clear_memory()
{
g_memory = 0;
}
int m_entering;
void calc_enter(string n)
{
if (!m_entering) {
m_entry = n;
m_entering = 1;
}
else {
m_entry += n;
}
}
real calc(string a, int OPERATION)
{
real ra;
int no_clear;
m_entering = 0;
ra = strtod(a);
if (m_entry == "" && m_result != "" && is_unary(OPERATION))
ra = strtod(m_result);
if (OPERATION & ANGLE_IN) {
ra = rad(ra);
}
switch(OPERATION) {
case OP_ENTER:
accum = ra;
set_result(accum);
break;
case OP_ADD:
accum = accum + ra;
break;
case OP_SUBTRACT:
accum = accum - ra;
break;
case OP_DIVIDE:
accum = accum / ra;
break;
case OP_MULTIPLY:
accum = accum * ra;
break;
case OP_DEGREE:
accum = set_angle_mode(ANG_DEGREE);
break;
case OP_RADIAN:
accum = set_angle_mode(ANG_RADIAN);
break;
case OP_MEMORY_PLUS:
set_memory(ra + get_memory());
accum = ra;
break;
case OP_MEMORY_STORE:
set_memory(ra);
accum = ra;
break;
case OP_MEMORY_RECALL:
m_entry = format_number(get_memory());
no_clear = 1;
accum = ra;
break;
case OP_MEMORY_CLEAR:
clear_memory();
accum = ra;
break;
case OP_COSINE:
accum = cos(ra);
break;
case OP_SINE:
accum = sin(ra);
break;
case OP_TANGENT:
accum = tan(ra);
break;
case OP_ARC_COSINE:
accum = acos(ra);
break;
case OP_ARC_SINE:
accum = asin(ra);
break;
case OP_ARC_TANGENT:
accum = atan(ra);
break;
case OP_CLEAR:
accum = 0;
break;
default:
dlgMessageBox("Invalid OPERATION");
}
if (OPERATION & ANGLE_OUT) {
accum = unrad(accum);
}
set_result(accum);
if (!no_clear) m_entry = "";
return accum;
}
/**********************************
* Initialization.
**********************************/
set_angle_mode(ANG_DEGREE);
//~ set_memory(strtod(get_nv_param("calc_memory", "0.0", 0 /* don't abort */)));
//~ if (get_nv_param("calc_angle_mode", "deg", 0 /* don't abort */) == "deg")
//~ set_angle_mode(ANG_DEGREE);
//~ else
//~ set_angle_mode(ANG_RADIAN);
//~ set_result(strtod(get_nv_param("calc_result", "0.0", 0 /* don't abort */)));