editor.c

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

C
211
字号
// editor for GBA v1.0
#include <CsAgb.h>
#define max_block_id 1024 //最大可用块数(也是无效字符块编号)
#define length_of_block 30 //字符块长度
#define max_segment_id 1024 //最大允许文本段数(也是无效文本段编号)
#define opt_error 100 //操作产生错误返回代码
#define opt_add 1 //操作使得操作对象数目增1返回代码
#define opt_dec -1 //操作使得操作对象数目减1返回代码
#define opt_null 0 //操作不改变操作对象数目返回代码
typedef struct
{
   //u16 block_num;//段内所含字符块个数
   u16 size;//段大小(段内所含字符总数)
   u16 first_block_id;//首个字符块编号
}text_segment;//文本段

typedef struct
{
   u8 length;//字符块长度(所含字符个数)
   u16 pre_block_id;//上一个字符块编号
   u16 next_block_id;//下一个字符块编号
   char mes[length_of_block];//字符块数据区
}text_block;//文本块

typedef struct
{
   u16 id;//编号
   u16 loc;//位置
} text_found_dat;//查询数据
u16 new_block(u8 *BUMT) //申请一个新的字符块 BUMT 为字符块占用情况表 Block Using Messege Table
{
   u16 i;
   for (i=0;i<max_block_id;i++) if (BUMT[i]==0) break;//找寻首个空闭字符块
   if (i!=max_block_id) BUMT[i]=1;//标识该字符块已被分配
   return i;
}

void free_block(u8 *BUMT,u16 id) //释放不再占用的字符块
{
   if (id<max_block_id) BUMT[id]=0;//置字符块空闲标志
}

int block_insert_char(text_block *blocks,u8 *BUMT,u16 block_id,u8 loc,char ch) //在字符块中插入一字符
{
   int new_block_id;
   int i;
   if (block_id>=max_block_id) return opt_error;//无效的字符块编号
   if (loc>=length_of_block) return opt_error;//字符块溢出
   if (loc==blocks[block_id].length)//在尾部追加
   {
      blocks[block_id].mes[loc]=ch;//写入内存
      blocks[block_id].length++;//指针后移
      return opt_null;
   }
   else if (blocks[block_id].length<length_of_block)//该字符块尚有数据空闲
   {
      for (i=blocks[block_id].length;i>loc;i--) blocks[block_id].mes[i]=blocks[block_id].mes[i-1];//后移字符
      blocks[block_id].mes[loc]=ch;//写入新字符
      blocks[block_id].length++;
      return opt_null;
   }
   else //当前字符块已満
   {
      new_block_id=blocks[block_id].pre_block_id;
      if (loc==0 && new_block_id<max_block_id && blocks[new_block_id].length<length_of_block)//在块头部插入字符检查前一字符块是否有数据空闲
      {
         loc=blocks[new_block_id].length;//上一字符块字符占用数
         blocks[new_block_id].mes[loc]=ch;//写入数据
         blocks[new_block_id].length++;
         return opt_null;
      }//在前一字符块中写入字符
      else //前一字符块数据已满
      {
         new_block_id=new_block(BUMT);//申请一个新的字符块
         if (new_block_id>=max_block_id) return 1;//申请字符块失败
         blocks[new_block_id].pre_block_id=block_id;
         blocks[new_block_id].next_block_id=blocks[block_id].next_block_id;//交换链接
         for (i=loc;i<blocks[block_id].length;i++) blocks[new_block_id].mes[i-loc]=blocks[block_id].mes[i];//移动数据
         blocks[new_block_id].length=blocks[block_id].length-loc;
         blocks[block_id].next_block_id=new_block_id;
         blocks[block_id].mes[loc]=ch;//写入数据
         blocks[block_id].length=loc+1;
         return opt_add;
      }
   }
}
int block_delet_char(text_block *blocks,u8 *BUMT,u16 block_id,u8 loc)//从字符块loc位置删去一字符
{
   int i;
   u8 temp_block_id;
   if (block_id>=max_block_id) return opt_error;//无效字符块
   if (loc>=length_of_block) return opt_error;//删除溢出
   for (i=loc+1;i<blocks[block_id].length;i++) blocks[block_id].mes[i-1]=blocks[block_id].mes[i];//移动数据
   if (blocks[block_id].length) blocks[block_id].length--;//字符块字符数减1
   if (blocks[block_id].length==0)//字符块已无有效数据则应释放
   {
      temp_block_id=blocks[block_id].pre_block_id;
      if (temp_block_id<max_block_id)//不是头结点(非第一个字符块)
      {
         blocks[temp_block_id].next_block_id=blocks[block_id].next_block_id;//修改链接
         free_block(BUMT,block_id);//释放该字符块
      }
      else //是头结点则将第二个结点内容复制到头结点并删除第二个结点(为的是保持文本段第一个字符块链接不变)
      {
         temp_block_id=blocks[block_id].next_block_id;
         if (temp_block_id<max_block_id) blocks[block_id]=blocks[temp_block_id];
      }
      return opt_dec;
   }
   return opt_null;
}
int new_segment(text_block *blocks,u8 *BUMT,text_segment *seg,u16 id)//添加新文本段
{
   int i;
   u16 new_block_id;
   if (id>=seg[max_segment_id].size) return opt_error;//溢出
   for (i=seg[max_segment_id].size;i>id;i--) seg[i]=seg[i-1];//移动数据
   new_block_id=new_block(BUMT);//为文本段申请一个文本块
   if (new_block_id==max_block_id) return opt_error;//申请字符块失败
   blocks[new_block_id].length=0;
   blocks[new_block_id].pre_block_id=max_block_id;
   blocks[new_block_id].next_block_id=max_block_id;//文本块数据初始化
   seg[id].size=0;
   //seg[id].block_num=1;
   seg[id].first_block_id=new_block_id;//文本段数据初始化
   seg[max_segment_id].size++;//文本段总数加1
   return opt_add;
}
void del_segment(text_block *blocks,u8 *BUMT,text_segment *seg,u16 id)//删除文本段
{
   int i;
   u16 block_id;
   if (id>=seg[max_segment_id].size || id>=max_segment_id) return;//删除溢出
   block_id=seg[id].first_block_id;
   while (block_id<max_block_id)
   {
      free_block(BUMT,block_id);
      block_id=blocks[block_id].next_block_id;
   }//释放文本段所有占用的文本块
   for (i=id;i<seg[max_segment_id].size;i++) seg[i]=seg[i+1];//移动数据
   seg[max_segment_id].size--;//文本段减少一个
}

text_found_dat loc_in_seg(text_block *blocks,text_segment *seg,u16 seg_id,u16 loc)//文本段地址变换
{
   u16 count=0;
   text_found_dat res;
   res.id=seg[seg_id].first_block_id;
   while (blocks[res.id].next_block_id<max_block_id && count<=loc)
   {
      count+=blocks[res.id].length;
      res.id=blocks[res.id].next_block_id;
   }
   if (count<loc) res.loc=loc-count;
   else
   {
      res.id=blocks[res.id].pre_block_id;
      count-=blocks[res.id].length;
      res.loc=loc-count;
   }
   return res;
}
      
int seg_insert_char(text_block *blocks,u8 *BUMT,text_segment *seg,u16 seg_id,u16 loc,char ch)//在文本段中插入一字符
{
   u16 block_id;
   int opt_val;
   text_found_dat get;//地址转换数据
   if (loc>seg[seg_id].size) return opt_error;//插入溢出
   get=loc_in_seg(blocks,seg,seg_id,loc);
   if (get.loc==length_of_block)//在尾部追加一新字符块
   {
      block_id=new_block(BUMT);
      if (block_id==max_block_id) return opt_error;//申请字符块失败
      blocks[get.id].next_block_id=block_id;
      seg[seg_id].size++;
      blocks[block_id].pre_block_id=get.id;
      blocks[block_id].next_block_id=max_block_id;
      blocks[block_id].mes[0]=ch;
      blocks[block_id].length=1;
      return opt_null;
   }
   opt_val=block_insert_char(blocks,BUMT,get.id,get.loc,ch);//将字符插入相应的字符块中
   if (opt_val==opt_error) return opt_error;
   seg[seg_id].size++;
   return opt_null;
}
int seg_delet_char(text_block *blocks,u8 *BUMT,text_segment *seg,u16 seg_id,u16 loc)//在文本段中删除一字符
{
   int opt_val;
   text_found_dat get;//地址转换数据
   if (loc>=seg[seg_id].size) return opt_error;//删除溢出
   get=loc_in_seg(blocks,seg,seg_id,loc);
   if (get.loc==length_of_block) get.loc--;
   opt_val=block_delet_char(blocks,BUMT,get.id,get.loc);//删除字符
   if (opt_val==opt_error) return opt_error;
   if (seg[seg_id].size) seg[seg_id].size--;
   return opt_null;
}
   

   
   






   

⌨️ 快捷键说明

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