input_py.c

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

C
402
字号
#include <csagb.h>
#include <string.h>
#include <rb_stdio.h>
#include <rb_string.h>
#include <Qgraph.h>
#include <graph.h>
#include <rb_mem.h>
#define sdel 0xffff //删除信号
#define sok 0xfffe //确定信号
#define cdel 0xfffd //汉字删除信号
typedef struct
{
	char name;//结点名称,其值为#时表示改结点为终结点
	u16 bid;//下一个兄弟结点ID编号,当其值为自身编号时表示其兄弟结点结束
	u16 cid;//第一个子孙结点ID编号,当结点为终结点时,其值表示拼音编号
	u16 pid;//父结点ID编号,其值为自身编号时表示为根结点(老大)
} node;
typedef struct
{
	u16 id;//此拼音对应的汉字在整个汉字中的编号
	u8	length;//此拼音所对应的汉字个数
	u8	index[4];//第二,三,四,轻音所对应的索引
} py_mes;//拼音信息
extern const node py_nodes[];
extern const py_mes pys[];
extern const u16 hzs[];
extern void save_scr(u16 *sav,u8 xp,u8 yp,u8 xsp,u8 ysp);
extern void load_scr(u16 *sav,u8 xp,u8 yp,u8 xsp,u8 ysp);
extern u8 rb_xp;
extern u8 rb_yp;
extern u8 rb_error;
extern void (*sys_deamon)();
u16 is_child(char name,u16 pid)//检查结点是否为父结点的子孙
{
	u16 id=py_nodes[pid].cid;
	if (id==0) return 0;//不是
	while (py_nodes[id].bid!=id)//开始查找
	{
		if (py_nodes[id].name==name) return id;
		id=py_nodes[id].bid;
	}
	if (py_nodes[id].name==name) return id;
	return 0;//没有找到
}
int get_child(u16 *child,u16 pid)
{
   int i=0;
   u16 id=py_nodes[pid].cid;
   if (py_nodes[pid].name=='#') return 0;//终结点无子孙结点
   while (py_nodes[id].bid!=id)//开始查找
   {
      child[i]=id;
      i++;
      id=py_nodes[id].bid;
   }
   child[i]=id;
   i++;
   return i;
}
u16 list_child(u16 pid)//列出结点子孙
{
   int cnt;
   int i;
   int xp=3;//yp=145;
   u16 child[30];
   u16 sel=0,old=0,done=1;
   cnt=get_child(child,pid);
   if (cnt==0) return 0;
   Q_box(0,142,3+8*cnt+2,159,RGB(0,7,17));
   r_box(0,142,3+8*cnt+2,159,RGB(30,30,30),0);
   for (i=0;i<cnt;i++)
   {
      paint_eng(xp,145,RGB(30,30,30),py_nodes[child[i]].name);
      xp+=8;
   }
   while (1)
   {
      readkey();
      if (CS_IsKeyDown(KEY_LEFT))
      {
         sel=(sel+cnt-1)%cnt;;
         done=1;
      }
      else if(CS_IsKeyDown(KEY_RIGHT))
      {
         sel=(sel+1)%cnt;
         done=1;
      }
      else if(CS_IsKeyDown(KEY_UP))
      {
         sel=(sel+cnt-cnt/4)%cnt;
         done=1;
      }
      else if(CS_IsKeyDown(KEY_DOWN))
      {
         sel=(sel+cnt/4)%cnt;
         done=1;
      }
      else if(CS_IsKeyDown(KEY_A)) return child[sel];
      else if(CS_IsKeyDown(KEY_B)) return sdel;
      else if(CS_IsKeyDown(KEY_START)) return sok;
      else if(CS_IsKeyDown(KEY_SELECT)) return cdel;//汉字删除信号
      if (done)
      {
         done=0;
         if (old!=sel) r_box(old*8+3,143,old*8+10,158,0,5);
         r_box(sel*8+3,143,sel*8+10,158,0,5);
         old=sel;
      }
   }
}
u16 py_input()
{
   u16 id=0;
   char py[30];
   int pp=0;
   u16 nodes[30];
   u16 *vsv=(u16 *)new_malloc(20*1024);
   save_scr(vsv,0,125,239,159);
   while (1)
   {
      nodes[pp]=id;
      id=list_child(id);
      load_scr(vsv,0,125,239,159);
      if (id==sdel)//是删除信号
      {
         if(pp)
         {
            pp--;
            py[pp]='\0';
            id=nodes[pp];
         }
         else
         {
            new_free(vsv);
            return 0;
         }
      }
      else if(id==sok || id==cdel)
      {
         new_free(vsv);
         return id;
      }
      else
      {
         py[pp]=py_nodes[id].name;
         pp++;
         py[pp]='\0';
         if (py[pp-1]=='#')
         {
            new_free(vsv);
            return id;
         }
      }
      Q_box(0,125,2+pp*7,141,RGB(0,7,17));
      r_box(0,125,2+pp*7,141,RGB(0,30,30),0);
      cwrite(1,127,RGB(30,30,30),py);
   }
}
u16 is_pyin(char *word)//是否为合法拼音
{
	int i=0;
	u16 id=0;
	while (word[i]!='\0')
	{
		//cout<<i<<",";
		id=is_child(word[i],id);
		if (id==0) return 0;
		i++;
	}
	id=is_child('#',id);
	return id;
}
u16 get_hz(u16 nid,char *word)
{
	int i;
	int index;
	u16 cnt;
	u16 pid=py_nodes[nid].cid;
	if (py_nodes[nid].name!='#') return 0;//非终结点,无对应汉字
	index=pys[pid].id;
	if (pys[pid+1].id) cnt=pys[pid+1].id-pys[pid].id;
	else cnt=pys[pid].id;
	//show_float(cnt,RGB(30,30,30));
	for (i=0;i<cnt;i++)
	{
      word[2*i]=(hzs[index+i]&0xff00)>>8;
      word[2*i+1]=hzs[index+i]&0x00ff;
	}
	word[2*i+1]='\0';
	return cnt;
}
u16 input_c(char *str)//汉字输入
{
   u16 id=py_input();
   u16 cnt,pid;
   u16 bas=0;
   u16 sel=0,old=0,done=2;
   u16 *vsv=NULL;
   int i;
   char word[300];
   if (id==0) return 0;//放弃输入
   if (id==sok || id==cdel) return id;
   cnt=get_hz(id,word);
   if (cnt==0) return 0;
   pid=py_nodes[id].cid;
   vsv=new_malloc(10*1024);
   save_scr(vsv,0,145,239,159);
   while (1)
   {
      readkey();

      if(CS_IsKeyHold(KEY_R) && CS_IsKeyDown(KEY_UP))
      {
         done=2;
         sel=0;
         bas=pys[pid].index[0];
         if (bas) bas--;
      }
      else if(CS_IsKeyHold(KEY_R) && CS_IsKeyDown(KEY_DOWN))
      {
         done=2;
         sel=0;
         bas=pys[pid].index[1];
         if (bas) bas--;
      }
      else if(CS_IsKeyHold(KEY_R) && CS_IsKeyDown(KEY_LEFT))
      {
         done=2;
         sel=0;
         bas=pys[pid].index[2];
         if (bas) bas--;
      }
      else if(CS_IsKeyHold(KEY_R) && CS_IsKeyDown(KEY_RIGHT))
      {
         done=2;
         sel=0;
         bas=pys[pid].index[3];
         if (bas) bas--;
      }
      else if(CS_IsKeyDown(KEY_L))
      {
         done=2;
         sel=0;
         bas=0;
      }
      else if (CS_IsKeyDown(KEY_RIGHT) && sel+bas+1<cnt)
      {
         sel+=1;
         done=1;
         if (sel==20)
         {
            sel=19;
            bas++;
            done=2;
         }
      }
      else if(CS_IsKeyDown(KEY_LEFT) && sel+bas>0)
      {
         if (sel>0)
         {
            sel--;
            done=1;
         }
         else
         {
            bas--;
            done=2;
         }
      }
      else if(CS_IsKeyDown(KEY_UP) && sel+bas>0)
      {
         if (bas)
         {
            if (bas>=20) bas-=20;
            else {bas=0;sel=0;}
            done=2;
         }
         else
         {
            sel=0;
            done=1;
         }
      }
      else if(CS_IsKeyDown(KEY_DOWN) && sel+bas+1<cnt)
      {
         if (sel+bas+20<cnt)
         {
            bas+=20;
            done=2;
         }
         else if(bas+20<cnt)
         {
            bas+=20;
            sel=0;
            done=2;
         }
         else
         {
            sel=cnt-bas-1;
            done=1;
         }
      }
      else if(CS_IsKeyDown(KEY_A))//选定汉字
      {
         str[0]=word[2*(bas+sel)];
         str[1]=word[2*(bas+sel)+1];
         load_scr(vsv,0,145,239,159);
         new_free(vsv);
         return 1;
      }
      else if(CS_IsKeyDown(KEY_START))//结束输入
      {
         load_scr(vsv,0,145,239,159);
         new_free(vsv);
         return sok;
      }
      else if(CS_IsKeyDown(KEY_B))//取消输入
      {
         load_scr(vsv,0,145,239,159);
         new_free(vsv);
         return 0;
      }
      if (done==2)
      {
         done=0;
         Q_box(0,145,239,159,RGB(0,7,17));
         for (i=0;i<20;i++)
         {
            if (bas+i+1>cnt) break;
            paint_ch(i*12,147,RGB(30,30,30),&word[(bas+i)*2]);
         }
         r_box(12*sel,145,12*sel+11,159,0,5);
         old=sel;
      }
      else if(done==1)
      {
         done=0;
         if (old!=sel) r_box(12*old,145,12*old+11,159,0,5);
         r_box(12*sel,145,12*sel+11,159,0,5);
         old=sel;
      }
   }

}
void hz_deamon()
{
   r_box(rb_xp+12*rb_error,rb_yp,rb_xp+12*rb_error+11,rb_yp+11,0,5);
}
u8 input_hz(u8 xsp,u8 ysp,u16 color,u16 bg,u8 len,char *word)//输入汉字
{
   u8 xp=rb_xp,yp=rb_yp,error=rb_error;//保存变量
   u8 sp=0;//汉字指针
   u8 done=1;
   u16 id;
   rb_xp=xsp;
   rb_yp=ysp;
   rb_error=sp;
   Q_box(xsp,ysp,xsp+len*12,ysp+11,bg);
   sys_deamon=hz_deamon;
   while(1)
   {
      id=input_c(word+sp*2);
      if (id==sok)//输入结束
      {
         sys_deamon=NULL;
         rb_xp=xp;
         rb_yp=yp;
         rb_error=error;
         return sp;
      }
      else if(id==cdel && sp)//删除汉字
      {
         sp--;
         rb_error--;
         word[sp*2]='\0';
         done=1;
      }
      else if(id==1 && sp<len)//新的汉字
      {
         sp++;
         rb_error++;
         word[2*sp]='\0';
         done=1;
      }
      if (done)
      {
         done=0;
         sys_deamon=NULL;
         Q_box(xsp,ysp,xsp+len*12,ysp+11,bg);
         cwrite(xsp,ysp,color,word);
         sys_deamon=hz_deamon;
      }
   }
   return 0;
}
/*void ptest()
{
   char word[100];
   input_hz(10,10,RGB(30,30,30),RGB(0,7,17),5,word);
}*/

⌨️ 快捷键说明

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