📄 fat.c
字号:
}
}
}
else//其他文件夹/FAT32系统
{
tempclust=cluster;
while(1)
{
sector=fatClustToSect(tempclust);
for(cnt=0;cnt<SectorsPerClust;cnt++)
{
if(SD_ReadSingleBlock(sector+cnt,fat_buffer))return 1;
for(offset=0;offset<512;offset+=32)
{
item=(direntry *)(&fat_buffer[offset]);
if((item->deName[0]!=0x2E)&&(item->deName[0]!=0x00)&&(item->deName[0]!=0xe5)
||((item->deName[0]==0x2E)&&(item->deName[1]==0x2E)))//找到一个合法文件.忽略".",使用".."
{
if(item->deAttributes == 0x0f) //得到一个长文件名
{
we = (winentry *)(&fat_buffer[offset]);
j = 26 *( (we->weCnt-1) & WIN_CNT);
if(j<MAX_LONG_NAME_SIZE-25)
{
p = &LongNameBuffer[j];//p指向长文件名的存放地址
for (j=0;j<10;j++) *p++ = we->wePart1[j];
for (j=0;j<12;j++) *p++ = we->wePart2[j];
for (j=0;j<4;j++) *p++ = we->wePart3[j];
if (we->weCnt & 0x40) (*(unsigned int *)p) = 0;
if ((we->weCnt & WIN_CNT) == 1) LongNameFlag = 1;
}
}
else
{
if(type&FileType_Tell(item->deExtension))//找到一个目标文件
{
cont++;//文件索引增加
}
//查找该目录下,type类型的文件个数
if(*count&&cont==*count)
{
CopyDirentruyItem(FileInfo,item);//复制目录项,提取详细信息
return 1;//找到目标文件成功
}
LongNameFlag=0;//清空长文件名
}
}
}
}
tempclust=FAT_NextCluster(tempclust);//查找下一个簇号
if(tempclust==0x0fffffff||tempclust==0x0ffffff8 ||(FAT32_Enable==0&&tempclust==0xffff))break;
}
}
if(*count==0)
{
*count=cont;//得到总共文件数目
return 1; //操作成功,找到cont个符合条件的文件了
}else return 0; //操作失败,没找到文件,或者出错
}
//打开文件
void F_Open(FileInfoStruct *FileInfo)
{
FileInfo->F_CurClust=FileInfo->F_StartCluster;//当前簇为首簇
FileInfo->F_Offset=0;//偏移扇区为0
}
//读取512个字节
//FileInfo:要读取的文件
//buf :数据缓存区
//返回值 :0,操作失败,1,操作成功
unsigned char F_Read(FileInfoStruct *FileInfo,u8 *buf)
{
DWORD sector;
sector=fatClustToSect(FileInfo->F_CurClust);//得到当前簇号对应的扇区号
if(SD_ReadSingleBlock(sector+FileInfo->F_Offset,buf))return 0;//读数错误
FileInfo->F_Offset++;
if(FileInfo->F_Offset==SectorsPerClust) //簇的尽头,换簇
{
FileInfo->F_Offset=0;
FileInfo->F_CurClust=FAT_NextCluster(FileInfo->F_CurClust);//读取下一个簇号
if((FAT32_Enable==0&&FileInfo->F_CurClust==0xffff) \
||FileInfo->F_CurClust==0x0ffffff8||FileInfo->F_CurClust == 0x0fffffff)return 0;//error
}
return 1;//读取成功
}
//读取前512个字节
//FileInfo:要读取的文件
//buf :数据缓存区
//返回值 :0,操作失败,1,操作成功
unsigned char F_PrevRead(FileInfoStruct *FileInfo,u8 *buf)
{
DWORD sector;
if(FileInfo->F_Offset>1)FileInfo->F_Offset-=2;//未超簇,直接跳到上一扇区
else //超簇了,换到上一簇
{
FileInfo->F_CurClust=FAT_PrevCluster(FileInfo->F_CurClust,FileInfo->F_StartCluster);//读取上一个簇号
if((FAT32_Enable==0&&FileInfo->F_CurClust==0xffff) \
||FileInfo->F_CurClust==0x0ffffff8||FileInfo->F_CurClust == 0x0fffffff)return 0;//读数错误
if(FileInfo->F_Offset==1)FileInfo->F_Offset=SectorsPerClust-1;//跳到最后一个扇区
else FileInfo->F_Offset=SectorsPerClust-2;//读倒数第二簇
}
sector=fatClustToSect(FileInfo->F_CurClust);//得到当前簇号对应的扇区号
if(SD_ReadSingleBlock(sector+FileInfo->F_Offset,buf))return 0;//读数错误
return 1;//读取成功
}
//比较两个字符串相等不
//相等,返回1,不相等,返回0;
u8 mystrcmp(u8*s1,u8*s2)
{
u8 len1,len2;
len1=len2=0;
while(*s1!='\0')
{
len1++;s1++;
}
while(*s2!='\0')
{
len2++;s2++;
}
if(len1!=len2)return 0;//不相等
s1-=len1;s2-=len1;
while(*s1!='\0')
{
if(*s1!=*s2)return 0;//不相等
s1++;s2++;
}
return 1;
}
//查找系统文件
//在指定目录下,找寻一个指定类型的指定名字的文件
//cluster:文件夹的簇号!!!
//Name :文件的名字
//type :文件类型
//返回值 :该文件的开始簇号
u32 F_Search(u32 cluster,unsigned char *Name,u16 type)
{
DWORD sector;
DWORD tempclust;
unsigned char cnt;
unsigned int offset;
direntry *item = 0;
FileInfoStruct FileInfo;
if(cluster==0 && FAT32_Enable==0)//FAT16根目录读取
{
for(cnt=0;cnt<RootDirSectors;cnt++)
{
if(SD_ReadSingleBlock(FirstDirSector+cnt,fat_buffer))return 1;//读数错误
for(offset=0;offset<512;offset+=32)
{
item=(direntry *)(&fat_buffer[offset]);//指针转换
//找到一个可用的文件
if((item->deName[0] != 0x00) && (item->deName[0] != 0xe5))//找到一个合法文件
{
if(item->deAttributes != AM_LFN)//忽略长文件名
{
CopyDirentruyItem(&FileInfo,item);//复制目录项,提取详细信息
if(FileInfo.F_Type&type)//找到一个合适的类型了
{
// printf("File Name:%s\n",FileInfo.F_Name);
//找到了文件,返回这个文件的首簇
if(mystrcmp(Name,FileInfo.F_Name))return FileInfo.F_StartCluster;
}
LongNameFlag=0;//清空长文件名
}
}
}
}
}
else//其他文件夹/FAT32系统
{
tempclust=cluster;
while(1)
{
sector=fatClustToSect(tempclust);
for(cnt=0;cnt<SectorsPerClust;cnt++)
{
if(SD_ReadSingleBlock(sector+cnt,fat_buffer))return 1;
for(offset=0;offset<512;offset+=32)
{
item=(direntry *)(&fat_buffer[offset]);
if((item->deName[0] != 0x00) && (item->deName[0] != 0xe5))
{
if(item->deAttributes != AM_LFN) //忽略长文件名
{
CopyDirentruyItem(&FileInfo,item);//复制目录项,提取详细信息
if(FileInfo.F_Type&type)//找到一个合适的类型了
{ /*
printf("F_Info->F_Name:%s\n",FileInfo.F_Name);
printf("F_Info->F_Type:%d\n",FileInfo.F_Type);
printf("F_Info->F_Size:%d\n",FileInfo.F_Size);
printf("F_Info->F_StartClusterH:%x\n",FileInfo.F_StartCluster>>8);
printf("F_Info->F_StartClusterL:%x\n\n",FileInfo.F_StartCluster&0xff); */
//找到了文件,返回这个文件的首簇
if(mystrcmp(Name,FileInfo.F_Name))return FileInfo.F_StartCluster;
}
LongNameFlag=0;//清空长文件名
}
}
}
}
tempclust=FAT_NextCluster(tempclust);//查找下一个簇号
if(tempclust==0x0fffffff||tempclust==0x0ffffff8 ||(FAT32_Enable==0&&tempclust==0xffff))break;
}
}
return 0;//失败
}
//分块图片编号获取算法
//得到 IMGXX BMP
//XX:00~16
void Get_Game_Pic_Str(u8 t,u8 *str)
{
*str++='I';
*str++='M';
*str++='G';
*str++=(t/10)%10+'0';
*str++=t%10+'0';
*str++=' ';
*str++=' ';
*str++=' ';
*str++='B';
*str++='M';
*str++='P';
*str='\0';//加入结束符
}
//获取系统文件的存储地址
//次步出错,则无法启动!!!
//返回0,失败。返回1,成功
//sel:bit7:0,查找系统文件
//sel:bit7:1,查找游戏文件
//sel:bit 0~6 编号
u8 SysInfoGet(u8 sel)
{
u32 cluster=0;
u32 syscluster=0;
u8 t=0;
u8 imgx[9];
u8 sizex; //图片大小 也就是难度的大小
//得到根目录的簇号
if(FAT32_Enable)cluster=FirstDirClust;
else cluster=0;
cluster=F_Search(cluster,(unsigned char *)folder[0],T_FILE);//查找system文件夹
if(cluster==0)return 0;//系统文件夹丢失
syscluster=cluster;//保存系统文件夹所在簇号
if(sel&0x80)//查找游戏文件
{
sizex=sel&0x7F;//得到size 3*3、4*4、5*5
cluster=F_Search(cluster,(unsigned char *)folder[3],T_FILE);//在system文件夹下查找game文件夹
if(cluster==0)return 0;
cluster=F_Search(cluster,(unsigned char *)folder[sizex+1],T_FILE);//在game文件夹下查找LEVEL(sizex-2)文件夹
if(cluster==0)return 0;//系统文件夹丢失
sizex*=sizex;//取平方
for(t=0;t<sizex+1;t++) //X*X图片地址获取
{
Get_Game_Pic_Str(t,imgx);//得到图片编号
Pic_Addr[t]=F_Search(cluster,imgx,T_BMP);//在LEVEL1文件夹下查找BMP图片
if(Pic_Addr[t]==0)return 0;//系统文件夹丢失
}
printf("level ok\n");
}else//查找系统文件
{
//先查找字体
cluster=F_Search(syscluster,(unsigned char *)folder[1],T_FILE);//在system文件夹下查找FONT文件夹
if(cluster==0)return 0;//字体文件夹丢失
//printf("SYSTEM FILE FOUND OK!\n");
FONT16CLUSTER=F_Search(cluster,(unsigned char *)sysfile[0],T_FON);//在system文件夹下查找FONT16字体文件
if(FONT16CLUSTER==0)return 0;//FONT16字体文件丢失
//printf("FONT16 FOUND OK!\n");
FONT12CLUSTER=F_Search(cluster,(unsigned char *)sysfile[1],T_FON);//在system文件夹下查找FONT12字体文件
if(FONT12CLUSTER==0)return 0;//FONT12字体文件丢失
//printf("FONT12 FILE FOUND OK!\n");
cluster=F_Search(syscluster,(unsigned char *)folder[2],T_FILE);//在system文件夹下查找SYSICO文件夹
if(cluster==0)return 0;
for(t=0;t<9;t++)//查找系统图标,九个
{
sys_ico[t]=F_Search(cluster,(unsigned char *)sysfile[t+2],T_BMP);//在SYSICO文件夹下查找系统图标
if(sys_ico[t]==0)return 0;//失败
}
for(t=11;t<15;t++)//查找系统图标,4个
{
file_ico[t-11]=F_Search(cluster,(unsigned char *)sysfile[t],T_BMP);//在SYSICO文件夹下查找文件图标
if(file_ico[t-11]==0)return 0;//失败
}
}
return 1;//成功
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -