//#include #include "sub.h" #include "./screen/screen.h" //何故かクラス関数でイベント登録出来ないので外部参照 extern bool CheckInsEject();//挿抜チェック //------------------------------------------------------- メンバ関数 //**** ラッピング *** //コンストラクタ CsmSaveFile::CsmSaveFile() { finalized = false; pos_card = 0; } //終了 void CsmSaveFile::Finalize() { if (finalized)return; savedata.Finalize(); exsave.Finalize(); memsave.Finalize(); finalized = true; } //デストラクタ CsmSaveFile:: ~CsmSaveFile() { Finalize(); } //存在チェック bool CsmSaveFile::IsExist(TgtDev dev) { if(dev == TGT_CARD)return savedata.IsExist(); if(dev == TGT_SD)return exsave.IsExist(); if(dev == TGT_MEM)return memsave.IsExist(); return false; } //削除 bool CsmSaveFile::Delete(TgtDev dev) { //if(dev == TGT_CARD)return false; if(dev == TGT_SD)return exsave.Delete(); if(dev == TGT_MEM)return memsave.Delete(); return false; } //Result nn::Result CsmSaveFile::LastNnResult(TgtDev dev) { nn::Result res; if(dev == TGT_CARD)res = savedata.LastNnResult; else if(dev == TGT_SD)res = exsave.LastNnResult; else if(dev == TGT_MEM)res = memsave.LastNnResult; return res; } //Mount myResult CsmSaveFile::Mount(TgtDev dev) { myResult res; if(dev == TGT_CARD)res = savedata.Mount(); else if(dev == TGT_SD)res = exsave.Mount(); else if(dev == TGT_MEM)res = memsave.Mount(); return res; } //Unmoun void CsmSaveFile::Unmount(TgtDev dev) { if(dev == TGT_CARD)savedata.Unmount(); else if(dev == TGT_SD)exsave.Unmount(); else if(dev == TGT_MEM)memsave.Unmount(); } void CsmSaveFile::Unmount() { savedata.Unmount(); exsave.Unmount(); memsave.Unmount(); } //ワークの作成 myResult CsmSaveFile::Create(TgtDev dev,u32 entryDir,u32 entryFile) { if(dev == TGT_SD)return exsave.Create(entryDir,entryFile); else if(dev == TGT_MEM)return memsave.Create(entryDir,entryFile); return RESULT_FAIL; } //パス取得位置リセット void CsmSaveFile::ResetPath(TgtDev dev) { if(dev == TGT_CARD)savedata.ResetPath(); else if(dev == TGT_SD)exsave.ResetPath(); else if(dev == TGT_MEM)memsave.ResetPath(); } //パス取得 myResult CsmSaveFile::GetPath(TgtDev dev,wchar_t *path) { if(dev == TGT_CARD)return savedata.GetPath(path); if(dev == TGT_SD)return exsave.GetPath(path); if(dev == TGT_MEM)return memsave.GetPath(path); return RESULT_FAIL; } //フラッシュ bool CsmSaveFile::Flush(TgtDev dev) { if(dev == TGT_CARD)return savedata.Flush(); if(dev == TGT_SD)return exsave.Flush(); if(dev == TGT_MEM)return true; return false; } //オープンファイル bool CsmSaveFile::Open(TgtDev dev,wchar_t *path) { if(dev == TGT_CARD){ pos_card = 0; return savedata.Open(path); }else if(dev == TGT_SD)return exsave.Open(path); else if(dev == TGT_MEM)return memsave.Open(path); return false; } bool CsmSaveFile::OpenW(TgtDev dev,wchar_t *path,s64 size) { if(dev == TGT_CARD)return savedata.OpenW(path,true);//作成あり else if(dev == TGT_SD)return exsave.OpenW(path,false);//拡張セーブは先にCreateしとく else if(dev == TGT_MEM)if(size>0)return memsave.OpenW(path,size); return false; } bool CsmSaveFile::CreateFile(TgtDev dev,wchar_t *path,s64 size) { if(dev == TGT_CARD)return savedata.CreateFile(path,size); else if(dev == TGT_SD)return exsave.CreateFile(path,size); return false; } //クローズ void CsmSaveFile::Close(TgtDev dev) { if(dev == TGT_CARD)savedata.Close(); else if(dev == TGT_SD)exsave.Close(); else if(dev == TGT_MEM)memsave.Close(); } void CsmSaveFile::Close() { savedata.Close(); exsave.Close(); memsave.Close(); } void CsmSaveFile::CloseW(TgtDev dev) { if(dev == TGT_CARD)savedata.CloseW(); else if(dev == TGT_SD)exsave.CloseW(); else if(dev == TGT_MEM)memsave.CloseW(); } //ファイルサイズ取得 s64 CsmSaveFile::FileSize(TgtDev dev) { if(dev == TGT_CARD)return savedata.FileSize; else if(dev == TGT_SD)return exsave.FileSize; else if(dev == TGT_MEM)return memsave.FileSize; return 0; } //ライト s32 CsmSaveFile::Write(TgtDev dev,char *buffer,size_t size) { if(dev == TGT_CARD)return savedata.Write(buffer,size); else if(dev == TGT_SD)return exsave.Write(buffer,size); else if(dev == TGT_MEM)return memsave.Write(buffer,size); return 0; } //リード s32 CsmSaveFile::Read(TgtDev dev,char *buffer,size_t size) { if(dev == TGT_CARD)return savedata.Read(buffer,size); else if(dev == TGT_SD)return exsave.Read(buffer,size); else if(dev == TGT_MEM)return memsave.Read(buffer,size); return 0; } //**** カード専用 *** //プロダクトコード取得 bool CsmSaveFile::GetPrdCode() { PrdCode[0] = 0;//Clear if (savedata.GetPrdCode()){ strcpy(PrdCode,savedata.PrdCode); return true; } return false; } //セーブデータの情報 //arcInfo <- フォーマット情報、ファイル、ディレクトリ数 //scList <- ディレクトリパス bool CsmSaveFile::GetInfo(tArcInfo *pinfo,tDcList *pDcList,size_t clsz) { return savedata.GetInfo(pinfo,pDcList,clsz); } //ユーザセーブのブロックリード //中身のデータが作成サイズに満たない場合に //未書込み領域で検証エラー(desc=329)となる場合がある //読めないブロックは0で置き換える(SDKツールのSaveFilerと同じ方法..ロンチ当時) //size = サイズ // 検証は512単位、読めてるとこまで置き換えないよう512以下で指定 // 尚、ユーザセーブ以外の検証は4096ごと //pos = 位置指定 // SDK3.1(より?)エラー時にファイルポインタ更新しないので2.0より bool CsmSaveFile::ReadBlock(char* buffer,size_t size) { if ((size > 512) || (size < 0))return false; savedata.SetPos(pos_card); if(savedata.Read(buffer,size) != size ) { NN_LOG("%d\n",LastNnResult(TGT_CARD).GetDescription()); if(nn::fs::ResultVerificationFailed::Includes(LastNnResult(TGT_CARD))) {//検証エラー for (int i = 0; i < size; i++) buffer[i] = 0;//0埋め }else return false; } pos_card += size; return true; } //*** 状態取得 *** bool CsmSaveFile::stsActive(TgtDev dev) { if (dev == TGT_CARD)return GetPrdCode(); if (dev == TGT_MEM)return true; if (dev == TGT_SD)return nn::fs::IsSdmcWritable(); return false; } bool CsmSaveFile::stsFormatted(TgtDev dev) { return IsExist(dev); } extern void Icon(eColor col); //*** ファイルコピー *** myResult CsmSaveFile::Copy(TgtDev dest,TgtDev src,wchar_t *path,wchar_t *pathw) { myResult res; int rsize; s64 fsize,msize; if (Open(src,path)==false)return RESULT_FAIL_OPEN; fsize = FileSize(src); if (pathw == 0)pathw = path; if (OpenW(dest,pathw,fsize)==false)return RESULT_FAIL_OPENW; //カードは検証単位の512ずつ読むべし msize=fsize; res = RESULT_OK; while(fsize) { if(CheckInsEject()){ res = RESULT_INSEJECT; break; } if(dest == TGT_CARD)Icon(COLOR_PARPL);//動作中アイコン"-","|" else Icon(COLOR_SKY); if(msize > FILEBUFF_SIZE * 2){ scr_Gage(msize-fsize,msize); } if (fsize>FILEBUFF_SIZE) { rsize = FILEBUFF_SIZE; fsize -= FILEBUFF_SIZE; }else{ rsize = fsize; fsize = 0; } if (src == TGT_CARD){//カードは空き領域補正つきリード if(ReadBlock(fileBuffer,rsize)==false){ res = RESULT_FAIL_READ; break; } }else{ if(Read(src,fileBuffer,rsize)!=rsize){ res = RESULT_FAIL_READ; break; } } if(Write(dest,fileBuffer,rsize) != rsize ){ res= RESULT_FAIL_WRITE; break; } } Close(src); CloseW(dest); if (res != RESULT_OK)return res; else if (fsize != 0)res = RESULT_FAIL;//想定外のループ抜け return res; } //*** オープン済ファイル間のコピー *** myResult CsmSaveFile::OpnCpy(TgtDev dest,TgtDev src,size_t size) { myResult res; int rsize; s64 msize; //カードは検証単位の512ずつ読むべし msize=size; res = RESULT_OK; while(size) { if(CheckInsEject()){ res = RESULT_INSEJECT; break; } if(msize > FILEBUFF_SIZE * 2){ scr_Gage(msize-size,msize);//ゲージ } if(dest == TGT_CARD)Icon(COLOR_PARPL);//動作中アイコン"-","|" else Icon(COLOR_SKY); if (size>FILEBUFF_SIZE) { rsize = FILEBUFF_SIZE; size -= FILEBUFF_SIZE; }else{ rsize = size; size = 0; } if (src == TGT_CARD){//カードは空き領域補正つきリード if(ReadBlock(fileBuffer,rsize)==false){ res = RESULT_FAIL_READ; break; } }else{ if(Read(src,fileBuffer,rsize)!=rsize){ res = RESULT_FAIL_READ; break; } } if(Write(dest,fileBuffer,rsize) != rsize ){ res= RESULT_FAIL_WRITE; break; } } if ((res == RESULT_OK) && (size != 0))res = RESULT_FAIL;//想定外のループ抜け return res; } //*** オープン済ファイル間のコンペア *** myResult CsmSaveFile::OpnCmp(TgtDev dest,TgtDev src,size_t size) { myResult res; int rsize; s64 msize; //カードは検証単位の512ずつ読むべし msize=size; res = RESULT_OK; while(size) { if(CheckInsEject()){ res = RESULT_INSEJECT; break; } if(msize > FILEBUFF_SIZE * 2){ scr_Gage(msize-size,msize);//ゲージ } Icon(COLOR_YELLO);//動作中アイコン"-","|" if (size>FILEBUFF_SIZE) { rsize = FILEBUFF_SIZE; size -= FILEBUFF_SIZE; }else{ rsize = size; size = 0; } if (src == TGT_CARD){//カードは空き領域補正つきリード if(ReadBlock(fileBuffer,rsize)==false){ res = RESULT_FAIL_READ; break; } }else{ if(Read(src,fileBuffer,rsize)!=rsize){ res = RESULT_FAIL_READ; break; } } //destにカード指定のときはライト後とみなし通常リード if(Read(dest,fileBuffer2,rsize)!=rsize){ res = RESULT_FAIL_READ; break; } //比較 if(memcmp(fileBuffer,fileBuffer2,rsize)!=0){ res = RESULT_FAIL_VERIFI; break; } } if ((res == RESULT_OK) && (size != 0))res = RESULT_FAIL;//想定外のループ抜け return res; } //ディレクトリ作成 bool CsmSaveFile::MakeDir(TgtDev dev,wchar_t *path,bool *mkdir) { if(dev == TGT_CARD)return savedata.MakeDir(path,mkdir); if(dev == TGT_SD)return exsave.MakeDir(path,mkdir); //if(dev == TGT_MEM)return memsave.MakeDir(path,mkdir); return false; } //ファイル削除 bool CsmSaveFile::DeleteFile(TgtDev dev,wchar_t *path) { if(dev == TGT_CARD)return savedata.DeleteFile(path); if(dev == TGT_SD)return exsave.DeleteFile(path); //if(dev == TGT_MEM)return memsave.MakeDir(path,mkdir); return false; } /*---------------------------------------------------------------------------* End of file *---------------------------------------------------------------------------*/