formula.c

来自「redboy for gba 是BPNS为GBA编写的一个小软件。软件的邹形是B」· C语言 代码 · 共 396 行

C
396
字号
#include <CsAgb.h>
#include <string.h>
#include <rb_string.h>
#include <Qgraph.h>
#include <graph.h>
#include <rb_stdio.h>
#include <rb_var.h>
#include <rbasic.h>
#include <rb_mem.h>
#define mVSV (u16 *) 0x06012C00
#define num_max_len 15
#define item_max_len 6
#define font_color RGB(0,15,5)
#define item_bg RGB(26,26,26)
#define item_select RGB(30,30,30)
#define name_max_len 13
#define exp_max_len 80
#define max_item 7
#define float_tp 1
typedef struct
{
	char ftype[4];
	u32 cnt;
} fml_head;
typedef struct
{
	char name[name_max_len];//中文名
	u8 para_cnt;//参数个数
	char paras[max_item][item_max_len];//参数列表
	char exp[exp_max_len];//表达式
} fml_record;

#define formula_bas 11368 //公式基址
extern int IsOpt(char ch);//是否为运算符

extern void n_box(u8 xp,u8 yp,u8 xsp,u8 ysp,u16 co,u16 bg);
extern void win_plate(char *tit,char *mes,u16 bg);
extern void (*sys_deamon)();
extern double str_to_num(char *exp);
extern void num_to_str(double x,char *str);
extern double rb_calcu(char *exp);
extern u8 arlt(char *tit,char *mes);

extern void formula_set(char *M,u8 act); //公式集设置
extern char _folder[40];//当前目录
extern char _file[40];//选定文件
extern u32 _file_loc;
extern u32 myfopen(char *fname,u32 *size);
void nkb_deamon()
{
   r_box(rb_xp+rb_error*7,rb_yp,rb_xp+rb_error*7+6,rb_yp+10,0,5);
}

char num_key_board(u8 xp,u8 yp,u8 xsp,u8 ysp,u16 color,u16 bg,char *str)//数字键盘
{
   u8 sel=0,old=0;
   u8 done=1;
   u8 len=str_len(str);
   int i;
   const char num[16]="12345-.67890=E";
   rb_xp=xsp;
   rb_yp=ysp;
   rb_error=0;
   CS_BackupScreenMem(&gScreen,xp,yp,xp+104,yp+30,mVSV,MODE_3);//保护屏幂
   Q_box(xsp,ysp,xsp+15*7,ysp+10,bg);
   cwrite(xsp,ysp,color,str);
   sys_deamon=nkb_deamon;
   r_box(xp+1,yp+1,xp+104,yp+30,0,0);
   Q_box(xp,yp,xp+103,yp+29,RGB(3,7,15));
   r_box(xp,yp,xp+103,yp+29,RGB(0,15,5),0);
   xp+=4;
   yp+=4;
   for (i=0;i<7;i++)
   {
      n_box(xp+i*14,yp,xp+i*14+10,yp+10,RGB(0,15,5),RGB(3,7,15));
      paint_en(xp+i*14+2,yp+2,RGB(0,15,5),num[i]);
      n_box(xp+i*14,yp+12,xp+i*14+10,yp+22,RGB(0,15,5),RGB(3,7,15));
      paint_en(xp+i*14+2,yp+14,RGB(0,15,5),num[7+i]);
   }
   while (1)
   {
      readkey();
      if (CS_IsKeyDown(KEY_UP) || CS_IsKeyDown(KEY_DOWN))
      {
         sel=(sel+7)%14;
         done=1;
      }
      else if(CS_IsKeyDown(KEY_LEFT))
      {
         sel=(sel+13)%14;
         done=1;
      }
      else if(CS_IsKeyDown(KEY_RIGHT))
      {
         sel=(sel+1)%14;
         done=1;
      }
      else if (CS_IsKeyDown(KEY_R) && rb_error<len)//右移光标
      {
         rb_error++;
         done=2;
      }
      else if (CS_IsKeyDown(KEY_L) && rb_error)//左移光标
      {
         rb_error--;
         done=2;
      }
      else if (CS_IsKeyDown(KEY_B) && rb_error && len)//删除字符
      {
         sys_deamon=NULL;
         for (i=rb_error;i<=len;i++) str[i-1]=str[i];
         len--;
         rb_error--;
         Q_box(xsp,ysp,xsp+15*7,ysp+10,bg);
         cwrite(xsp,ysp,color,str);
         sys_deamon=nkb_deamon;
      }
      else if ( (CS_IsKeyDown(KEY_A) && num[sel]=='=') || CS_IsKeyDown(KEY_START))//结束输入
      {
         sys_deamon=0;
         rb_error=0;
         rb_xp=0;
         rb_yp=0;
         Q_box(xsp,ysp,xsp+15*7,ysp+10,bg);
         cwrite(xsp,ysp,color,str);
         CS_RestoreScreenMem(&gScreen,xp-4,yp-4,xp-4+104,yp+30-4,mVSV,MODE_3);//恢复屏幂
         return;//返回
      }
      else if (CS_IsKeyDown(KEY_A) && len<14) //增加字符
      {
         sys_deamon=NULL;
         for (i=len;i>=rb_error;i--) str[i+1]=str[i];
         str[rb_error]=num[sel];
         rb_error++;
         len++;
         Q_box(xsp,ysp,xsp+15*7,ysp+10,bg);
         cwrite(xsp,ysp,color,str);
         sys_deamon=nkb_deamon;
      }
      if (done==1)
      {
         done=0;
         paint_en(xp+14*(old%7)+2,yp+12*(int)(old/7)+2,RGB(0,15,5),num[old]);
         paint_en(xp+14*(sel%7)+2,yp+12*(int)(sel/7)+2,RGB(30,10,20),num[sel]);
         old=sel;
      }
      else if (done==2)
      {
         done=0;
         sys_deamon=0;
         Q_box(xsp,ysp,xsp+15*7,ysp+10,bg);
         cwrite(xsp,ysp,color,str);
         sys_deamon=nkb_deamon;
      }
   }
         
}
void formula_items(char *items,char *nums,u8 cnt,char *exp,char *res)//输入参数
{
   u8 sel=0,old=0;
   u8 done=1;
   int i;
   char result[30];
   char temp[40];
   if (!cnt) return;
   n_box(65,20,235,135,RGB(0,15,5),RGB(27,27,26));
   Q_box(66,21,234,134,RGB(23,23,23));
   for (i=0;i<cnt;i++)
   {
      cwrite(68,26+i*15,font_color,items+i*item_max_len);
      paint_en(61+7*item_max_len,28+i*15,font_color,':');
      n_box(115,24+i*15,230,24+i*15+13,font_color,RGB(27,27,26));
      Q_box(116,25+i*15,229,24+i*15+12,item_bg);
      cwrite(118,26+i*15,font_color,nums+num_max_len*i);
   }
   while (1)
   {
      readkey();
      if (CS_IsKeyDown(KEY_UP)||CS_IsKeyDown(KEY_LEFT))
      {
         sel=(sel+cnt-1)%cnt;
         done=1;
      }
      else if(CS_IsKeyDown(KEY_DOWN)||CS_IsKeyDown(KEY_RIGHT))
      {
         sel=(sel+1)%cnt;
         done=1;
      }
      else if(CS_IsKeyDown(KEY_A))//输入
      {
         if (sel>3)
         num_key_board(100,25,118,26+sel*15,font_color,item_select,nums+num_max_len*sel);
         else num_key_board(100,105,118,26+sel*15,font_color,item_select,nums+num_max_len*sel);
      }
      else if(CS_IsKeyDown(KEY_B)) return;//退出
      else if(CS_IsKeyDown(KEY_R))//清空相应项目
      {
         nums[num_max_len*sel]='\0';
         Q_box(116,25+sel*15,229,24+sel*15+12,item_select);
         cwrite(118,26+sel*15,font_color,nums+num_max_len*sel);
      }
      else if (CS_IsKeyDown(KEY_L))//计算结果
      {
         for (i=0;i<cnt;i++) give_float_val(i,str_to_num(nums+i*num_max_len));//计算参数
         //if (rb_error) arlt("AAA","VVV");
         num_to_str(rb_calcu(exp),result);
         if (rb_error)
         {
            arlt("系统提示","计算出错!\n请检查输入是否有误。");
            rb_error=0;
         }
         else
         {
            str_copy(temp,res);
            str_cat(temp,"\n");
            str_cat(temp,result);
            arlt("运算结果:",temp);
         }
      }
      //else if (CS_IsKeyDown(KEY_START)) return;//返回计算结果
      if (done)
      {
         Q_box(116,25+old*15,229,24+old*15+12,item_bg);
         cwrite(118,26+old*15,font_color,nums+num_max_len*old);
         Q_box(116,25+sel*15,229,24+sel*15+12,item_select);
         cwrite(118,26+sel*15,font_color,nums+num_max_len*sel);
         old=sel;
         done=0;
      }
   }
}
fml_head load_formula(u32 loc)//载入公式
{
   int i;
   fml_head head;
   char *temp=(char *)&head;
   for (i=0;i<sizeof(fml_head);i++) temp[i]=*(char *)(loc+i);
   if (strcmp(head.ftype,"FML")!=0) head.cnt=0;
   return head;
}
void list_fml_rec(fml_record *rec,u8 i)
{
   Q_box(6,21+i*15,94,36+i*15,RGB(30,30,30));
   cwrite(7,23+i*15,font_color,rec->name);
}
void list_fml_rev(u8 i)
{
   r_box(6,21+i*15,94,36+i*15,0,5);
}
void show_fml_exp(char *exp)
{
   int i=0;
   int xp=108,yp=25;
   Q_box(106,21,234,126,RGB(30,30,30));
   while (exp[i]!='\0')
   {
      paint_eng(xp,yp,font_color,exp[i]);
      xp+=7;
      if (xp>230) {xp=108;yp+=15;}
      i++;
   }
}
int list_formula(fml_record *rec,u32 cnt,u32 *n_p,u32 *n_sel)
{
   int i;
   u8 done=1;
   u8 old,sel;
   u32 np=*n_p,select=*n_sel;
   fml_record blank={"\0",0};
   sel=select-np;
   old=sel;
   n_box(5,20,95,127,RGB(0,15,5),RGB(27,27,26));
   Q_box(6,21,94,126,RGB(30,30,30));
   n_box(105,20,235,127,RGB(0,15,5),RGB(27,27,26));
   Q_box(106,21,234,126,RGB(30,30,30));
   while (1)
   {
      readkey();
      if (CS_IsKeyDown(KEY_UP))
      {
         if (sel) {sel--;select--;done=2;}
         else if (np) {np--;select--;done=1;}
      }
      else if(CS_IsKeyDown(KEY_DOWN) && select+1<cnt)
      {
         if (sel<max_item-1) {sel++;select++;done=2;}
         else {np++;select++;done=1;}
      }
      else if(CS_IsKeyDown(KEY_LEFT))
      {
         if (np>=max_item) {select-=max_item;np-=max_item;done=1;}
         else if (select) {np=0;select=0;sel=0;done=1;}
      }
      else if(CS_IsKeyDown(KEY_RIGHT))
      {
         if (select+max_item<cnt) {np+=max_item;select+=max_item;done=1;}
         else if (select<cnt-1) {select=cnt-1;np=select;sel=0;done=1;}
      }
      else if(CS_IsKeyDown(KEY_A))//计算
      {
         *n_p=np;
         *n_sel=select;
         return 0;
      }
      else if(CS_IsKeyDown(KEY_B)) {*n_p=np;*n_sel=select;return 1;}//结束
      if (done==1)
      {
         done=0;
         for (i=0;i<max_item;i++)
         {
            if (np+i>=cnt) list_fml_rec(&blank,i);
            else list_fml_rec(rec+(np+i),i);
         }
         list_fml_rev(sel);
         show_fml_exp(rec[select].exp);
         old=sel;
      }
      else if(done==2)
      {
         if (old!=sel) list_fml_rev(old);
         list_fml_rev(sel);
         show_fml_exp(rec[select].exp);
         old=sel;
         done=0;
      }
   }
}
void fml_par_reg(fml_record *rec)//注册参数
{
   int i;
   for (i=0;i<rec->para_cnt;i++)
   {
      if (i==7) break;
      str_up(rec->paras[i]);
      str_copy((char *)(rb_mes[float_tp]+10*i),rec->paras[i]);
   }
   rb_float_cnt=rec->para_cnt;
}
void set_to_fml()//将选定文件将为默认公式集
{
   char say[80]="真的要将文件";
   str_cat(say,_file);
   str_cat(say,"设置为默认公式集吗?\n   [A:确定][B:取消]");
   if (arlt("系统提示:",say))
   {
      formula_set((char *)&_file_loc,1);
      arlt("系统提示:","操作成功!");
   }
}
void formula()
{
   u32 loc;
   u32 np=0,select=0;
   int i,j;
   fml_head head;
   fml_record rec;
   char exp[exp_max_len];
   char res[exp_max_len];
   char nums[max_item][num_max_len];
   win_plate("公式计算器 V1.0","Powerd by BPNS,2005",RGB(27,27,26));
   formula_set((char *)&loc,2);//获得公式集路径
   head=load_formula(loc);
   if (head.cnt==0)
   {
      arlt("系统提示:","您打开的文件不是FML格式或者文件存在错误.\n请重新设置公式集.");
      return;
   }
   rb_mes=(u32 *)mymalloc(7*4);
   rb_mes[float_tp]=(u32)mymalloc(max_item*10);
   rb_float_var=(double *)mymalloc(max_item*sizeof(double));//分配空间
again:
   for (i=0;i<max_item;i++) nums[i][0]='\0';
   if (list_formula((fml_record *)(loc+sizeof(fml_head)),head.cnt,&np,&select))
   {
      if (arlt("系统提示:","您真的想退出公式计算吗?\n  [A:确定][B:取消]"))
      {
         myfree(rb_float_var);
         myfree((void *)rb_mes[float_tp]);
         myfree(rb_mes);
         return;
      }
      goto again;
   }
   rec=*(fml_record *)(loc+sizeof(fml_head)+select*sizeof(fml_record));
   fml_par_reg(&rec);
   i=0;j=0;
   while(rec.exp[i]!='=' && rec.exp[i]!='\0') {res[i]=rec.exp[i];i++;}
   res[i]='=';
   i++;
   res[i]='\0';
   while (rec.exp[i]!='\0') {exp[j]=rec.exp[i];i++;j++;}
   exp[j]='\0';
   formula_items(rec.paras,nums,rec.para_cnt,exp,res);
   goto again;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?