mirror of
https://github.com/rvtr/ctr_Repair.git
synced 2025-10-31 13:51:08 -04:00
1923 lines
59 KiB
C++
1923 lines
59 KiB
C++
/*---------------------------------------------------------------------------*
|
||
Project: Horizon
|
||
File: main.cpp
|
||
|
||
Copyright (C)2010 Nintendo Co., Ltd. All rights reserved.
|
||
|
||
These coded instructions, statements, and computer programs contain
|
||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||
Company Ltd., and are protected by Federal copyright law. They may
|
||
not be disclosed to third parties or copied or duplicated in any form,
|
||
in whole or in part, without the prior written consent of Nintendo.
|
||
|
||
*---------------------------------------------------------------------------*/
|
||
#include <wchar.h>
|
||
#include <string.h>
|
||
#include <stdlib.h>
|
||
#include <stdio.h>
|
||
#include <nn.h>
|
||
//#include <nn/os.h>
|
||
#include <nn/applet.h>
|
||
#include <nn/ndm.h>
|
||
#include <nn/cfg.h>
|
||
//#include <nn/ndm/ndm_DebugControl.h>
|
||
#include <nn/ndm/ndm_UserControl.h>
|
||
#include <nn/fs/ctr/mpcore/fs_FileSystemBasePrivate.h>
|
||
#include <nn/fs/fs_Parameters.h>
|
||
//#include <nn/fs/fs_ApiProcessInfo.h>
|
||
#include "../../../common/savefile/savefile.h"
|
||
#include "../../../common/savefile/savedata.h"
|
||
#include "../../../common/savefile/membak.h"
|
||
#include "./screen/screen.h"
|
||
#include "../../../common/common.h"
|
||
|
||
//ヘッダにフラグのみ、コメントアウトで旧版相当(SD非対応)
|
||
#include "main.h"
|
||
#ifdef CSM_FLAG_USE_SD
|
||
#include "../../../common/savefile/exsave.h"
|
||
#endif
|
||
|
||
nn::fnd::ExpHeap appHeap;
|
||
uptr heapForGx;
|
||
//Gui gui;
|
||
myResult errRes;
|
||
|
||
//char strBuff[128];
|
||
//bool exist;
|
||
|
||
SaveData savedata;
|
||
nn::os::LightEvent ejectEvnt(false);
|
||
nn::os::LightEvent insEvnt(false);
|
||
#ifdef CSM_FLAG_USE_SD
|
||
ExSave exsave;
|
||
nn::os::LightEvent ejectEvntSd(false);
|
||
nn::os::LightEvent insEvntSd(false);
|
||
bool BkupSd = false;//バックアップ先がSDか(ファイルサイズ合計で選択)
|
||
#endif
|
||
MemBak memsave;
|
||
|
||
//バックアップの状態
|
||
bool Active,Formatted;
|
||
bool exActive,exFormatted;
|
||
tArcInfo arcInfo,arcInfo2;//アーカイブ情報
|
||
tDcList dcList,dcList2;//ディレクトリ格納
|
||
|
||
|
||
//プロダクトコードの一致
|
||
bool isAgreePCode;
|
||
//SDあり起動
|
||
bool alive_Sd;
|
||
|
||
//Top画面エラー表示
|
||
int tmerr;
|
||
|
||
//結果
|
||
typedef enum {
|
||
SUCCESS
|
||
,ERROR
|
||
,CANCEL
|
||
,INSEXIT
|
||
}RetCode;
|
||
|
||
//挿抜イベント時に設定
|
||
typedef enum {
|
||
InEx_None
|
||
,InEx_InsCard
|
||
,InEx_EjcCard
|
||
,InEx_InsSd
|
||
,InEx_EjcSd
|
||
}tIsInsEject;
|
||
|
||
//メッセージ用タグ
|
||
enum eMesTag{
|
||
MT_Compair,//コンペア時
|
||
MT_ChkCard,//ユーザセーブの存在チェック時
|
||
MT_ChkBkup,//バックアップ先の存在チェック時
|
||
MT_CrtBkup,//保存先の作成
|
||
MT_FileNot,//ユーザセーブのマウント成功したがファイルが無い
|
||
MT_Reading,//リード中
|
||
MT_Complate,//終了
|
||
MT_CardFormat,//ユーザセーブのフォーマット時
|
||
MT_FormatOnly,//フォーマットのみ行ったとき(ファイルなし時)
|
||
MT_Writing,//ライト中
|
||
MT_CrtDir1,//ディレクトリ作成中その1
|
||
MT_CrtDir2,//その2(1,2を交互表示)
|
||
MT_Copy1,// ファイルコピー
|
||
MT_Copy2,//ファイルコピー
|
||
MT_Failed,//失敗
|
||
MT_Break,//中断
|
||
MT_Success,//成功
|
||
MT_END
|
||
};
|
||
|
||
tChar* MES_NULL = L"";
|
||
|
||
//文字数(終端込)
|
||
#define MESS_SIZE 32
|
||
//メッセージ格納
|
||
wchar_t Mess[MT_END*MESS_SIZE];
|
||
//メッセージ位置
|
||
int MessPos[MT_END];
|
||
|
||
#define MessTxt(i) (wchar_t*)&Mess[MessPos[i]]
|
||
|
||
tIsInsEject isInsEject;
|
||
extern u8 scr_evnt;
|
||
s64 sSize;
|
||
|
||
wchar_t wk_dir[20];//拡張セーブ上のリネームファイル用ディレクトリ
|
||
int rename_n =0;//リネーム番号
|
||
|
||
wchar_t file_pathw[MAX_PATH_LENGTH];
|
||
wchar_t file_pathw2[MAX_PATH_LENGTH];
|
||
char file_path[MAX_PATH_LENGTH];
|
||
//ドライバの仕様で速度的に4バイトアラインした方がいい(SDK 0.14.23 時点)
|
||
char fileBuffer[512] NN_ATTRIBUTE_ALIGN(4);//検証が512単位なので
|
||
char fileBuffer_ex[512] NN_ATTRIBUTE_ALIGN(4);
|
||
#define FILEBUFF_SIZE sizeof(fileBuffer)
|
||
|
||
|
||
void WaitUI();
|
||
void PutError(TgtDev dev,int cd=0);
|
||
RetCode Card2Sd();
|
||
RetCode Sd2Card();
|
||
void CheckSaveDataState();
|
||
void CheckExSaveState();
|
||
|
||
//------------------------------------------------------------ 挿抜チェック
|
||
bool CheckInsExit()
|
||
{
|
||
|
||
if (ejectEvnt.TryWait()){
|
||
//CARD抜け
|
||
CheckSaveDataState();
|
||
isInsEject = InEx_EjcCard;
|
||
return true;
|
||
}
|
||
if (insEvnt.TryWait()){
|
||
//CARD挿入
|
||
CheckSaveDataState();
|
||
isInsEject = InEx_InsCard;
|
||
return true;
|
||
}
|
||
#ifdef CSM_FLAG_USE_SD
|
||
if(alive_Sd){
|
||
if (ejectEvntSd.TryWait()){
|
||
//SD抜け
|
||
CheckExSaveState();
|
||
isInsEject = InEx_EjcSd;
|
||
return true;
|
||
}
|
||
if (insEvntSd.TryWait()){
|
||
//SD挿入
|
||
CheckExSaveState();
|
||
isInsEject = InEx_InsSd;
|
||
return true;
|
||
}
|
||
}
|
||
#endif
|
||
return false;
|
||
}
|
||
|
||
|
||
//---------------------------------------------------------------- 終了処理
|
||
void endfunc()
|
||
{
|
||
|
||
nn::fs::UnregisterCardEjectedEvent();
|
||
nn::fs::UnregisterCardInsertedEvent();
|
||
ejectEvnt.Finalize();
|
||
insEvnt.Finalize();
|
||
|
||
#ifdef CSM_FLAG_USE_SD
|
||
if (alive_Sd){
|
||
nn::fs::UnregisterSdmcEjectedEvent();
|
||
nn::fs::UnregisterSdmcInsertedEvent();
|
||
ejectEvntSd.Finalize();
|
||
insEvntSd.Finalize();
|
||
}
|
||
#endif
|
||
savedata.Finalize();
|
||
memsave.Finalize();
|
||
|
||
ScrFinalize();
|
||
|
||
}
|
||
|
||
//エラー停止
|
||
void failstop()
|
||
{
|
||
NN_LOG("fail %d,stop\n",errRes);
|
||
|
||
while(1){
|
||
CheckSysBreak();
|
||
}
|
||
}
|
||
|
||
//エラー表示
|
||
tChar sts[64];
|
||
void PutError(TgtDev dev,int cd)
|
||
{
|
||
nn::Result res;
|
||
switch (dev)
|
||
{
|
||
case TGT_CARD: res = savedata.LastNnResult;break;
|
||
case TGT_MEM: res = memsave.LastNnResult;break;
|
||
#ifdef CSM_FLAG_USE_SD
|
||
case TGT_SD: res = exsave.LastNnResult;break;
|
||
#endif
|
||
default: dev = TGT_NONE;//GetDescriptエラー対策
|
||
}
|
||
GetErrorStr(dev,res,cd,sts);
|
||
scr_Status(sts,COLOR_RED);
|
||
}
|
||
|
||
//表示テキストの読込(eMessTagの順)
|
||
//テキストはSJISやASCII不可、U-16で保存し文字列は改行(0a0d)で終える
|
||
//BOM(先頭2バイトのゴミ ^^; )は付けない事
|
||
void LoadMessText(wchar_t* path)
|
||
{
|
||
const size_t ROMFS_BUFFER_SIZE = 1024*8;
|
||
static char buffer[ROMFS_BUFFER_SIZE];
|
||
|
||
NN_LOG("reqsize = %d",nn::fs::GetRomRequiredMemorySize(8,8));
|
||
|
||
nn::fs::MountRom(4, 4, buffer, ROMFS_BUFFER_SIZE);
|
||
nn::fs::FileReader Reader;
|
||
if(Reader.TryInitialize(path).IsFailure())
|
||
{
|
||
NN_LOG("fail to read file $s\n",path);
|
||
endfunc();
|
||
}
|
||
|
||
const u32 size = (u32)Reader.GetSize();
|
||
if (size > (MT_END*MESS_SIZE*2))
|
||
{
|
||
NN_LOG("textfile:size over\n");
|
||
endfunc();
|
||
}
|
||
|
||
Reader.Read(Mess,size);
|
||
int i,n;
|
||
for (i=0;i<MT_END;i++)MessPos[i]=0;
|
||
//for (i=0;i<(MT_END*MESS_SIZE);i++)Mess[i]=0;
|
||
|
||
//Mess[0] = 0;MessPos[0]=0;//先頭(FEFF)をNULLに差替..BOMありのとき
|
||
//i=1;n=1;
|
||
i=0;n=0;
|
||
bool b=true;//最初の改行以外から開始
|
||
while( n < (size/2))
|
||
{
|
||
if ((Mess[n] == 0x0a)||(Mess[n] == 0x0d)){//改行?
|
||
Mess[n]=0;//終端に置換
|
||
b =true;
|
||
} else{
|
||
if(b){//改行直後の文字を先頭とみなす
|
||
MessPos[i]=n;
|
||
i++;
|
||
if (i == MT_END)break;
|
||
b=false;
|
||
}
|
||
}
|
||
n++;
|
||
}
|
||
if (i < MT_END){
|
||
NN_LOG("textfile: few strings\n");
|
||
endfunc();
|
||
}
|
||
|
||
//最後の文字列に終端付ける
|
||
n = MessPos[i-1]+1;
|
||
while( n < (size/2))
|
||
{
|
||
if ((Mess[n] == 0x000d) || (Mess[n] == 0x000a)){//改行?
|
||
Mess[n]=0;//終端に置換
|
||
//break;
|
||
}
|
||
n++;
|
||
}
|
||
Mess[size/2] = 0;//念の為、最後に終端
|
||
|
||
Reader.Finalize();
|
||
nn::fs::Unmount("rom:");
|
||
}
|
||
|
||
//ユーザセーブのブロックリード
|
||
//中身のデータが作成サイズに満たない場合に
|
||
//未書込み領域で検証エラー(desc=329)となる場合がある
|
||
//読めないブロックは0で置き換える(SDKツールのSaveFilerと同じ方法..ロンチ当時)
|
||
//size = サイズ
|
||
// 検証は512単位、読めてるとこまで置き換えないよう512以下で指定
|
||
// 尚、ユーザセーブ以外の検証は4096ごと
|
||
//pos = 位置指定
|
||
// SDK3.1(より?)エラー時にファイルポインタ更新しないので2.0より
|
||
bool ReadBlock(s64 pos,int size)
|
||
{
|
||
if ((size > 512) || (size < 0))return false;
|
||
savedata.SetPos(pos);
|
||
if(savedata.Read(fileBuffer,size) != size )
|
||
{
|
||
NN_LOG("%d\n",savedata.LastNnResult.GetDescription());
|
||
if(nn::fs::ResultVerificationFailed::Includes(savedata.LastNnResult))
|
||
{//検証エラー
|
||
for (int i = 0; i < size; i++) fileBuffer[i] = 0;//0埋め
|
||
}else return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
|
||
//-------------------------------------------------- Verifi
|
||
bool Verifi(bool flg)
|
||
{
|
||
myResult res;
|
||
int ct,i,msize,rsize;
|
||
s64 total=0,pos;
|
||
|
||
//セーブデータのマウント
|
||
res = savedata.Mount();
|
||
if(res != RESULT_OK){
|
||
//PutError(TGT_CARD);
|
||
return false;
|
||
}
|
||
|
||
|
||
//バッファデバイスのマウント
|
||
res = memsave.Mount();
|
||
if(res != RESULT_OK){
|
||
//PutError(TGT_MEM);
|
||
return false;
|
||
}
|
||
|
||
//ディレクトリの確認
|
||
//空ディレクトリチェックするアプリあり(マリカ7)
|
||
//ファイルなし状態ありえるので先に確認
|
||
if( dcList.num >0 )
|
||
{
|
||
nn::fs::Directory dc;
|
||
for(i=0;i<dcList.num;i++)
|
||
{
|
||
if(dc.TryInitialize(dcList.name[i]).IsFailure())
|
||
{
|
||
dc.Finalize();
|
||
return false;
|
||
}
|
||
dc.Finalize();
|
||
}
|
||
}
|
||
|
||
ct =0;
|
||
if (arcInfo.FileCount == 0)//ファイルが無い
|
||
{
|
||
savedata.Unmount();
|
||
memsave.Unmount();
|
||
return true;//フォーマット一致のみ
|
||
}else{
|
||
scr_Status(MessTxt(MT_Compair),COLOR_YELLO);
|
||
savedata.ResetPath();
|
||
memsave.ResetPath();
|
||
s64 fsize;
|
||
res = RESULT_OK;
|
||
while(res==RESULT_OK){
|
||
res = savedata.GetPath(file_pathw);
|
||
if (res != RESULT_OK)
|
||
{
|
||
if (res == RESULT_DIR_LEVEL_OVER){
|
||
break;
|
||
}
|
||
if (res == RESULT_PATH_LENGTH_OVER){
|
||
break;
|
||
}
|
||
res = RESULT_FAIL_OPEN;
|
||
break;
|
||
}
|
||
if (file_pathw[0] == 0)break;//root then end
|
||
if (ct>=arcInfo.FileCount)
|
||
{//カウンタ壊れ、メモリフローの可能性
|
||
res = RESULT_FAIL;
|
||
break;
|
||
}
|
||
scr_CountPerMax(ct,arcInfo.FileCount);
|
||
if (savedata.Open(file_pathw)==false)
|
||
{
|
||
res = RESULT_FAIL_OPEN;
|
||
break;
|
||
}
|
||
fsize = savedata.FileSize;
|
||
total += fsize;
|
||
if (memsave.Open(file_pathw)==false)
|
||
{
|
||
res = RESULT_FAIL_OPENW;
|
||
//savedata.Close();
|
||
break;
|
||
}
|
||
if (fsize != memsave.FileSize)//file size
|
||
{
|
||
res = RESULT_FAIL;
|
||
break;
|
||
}
|
||
msize=fsize;
|
||
if(msize <= FILEBUFF_SIZE ){//一回で読めるサイズならゲージは出さない
|
||
scr_CountPerMax2(0,0,-1);
|
||
}
|
||
pos = 0;
|
||
while(fsize)
|
||
{
|
||
if(msize > FILEBUFF_SIZE ){
|
||
scr_CountPerMax2(msize-fsize,msize,0);
|
||
}
|
||
if (fsize > FILEBUFF_SIZE)
|
||
{
|
||
rsize = FILEBUFF_SIZE;
|
||
fsize -= FILEBUFF_SIZE;
|
||
}else{
|
||
rsize = fsize;
|
||
fsize = 0;
|
||
}
|
||
if (ReadBlock(pos,rsize)==false)
|
||
{
|
||
res = RESULT_FAIL_READ;
|
||
break;
|
||
}
|
||
pos += rsize;
|
||
if(memsave.Read(fileBuffer_ex,rsize) != rsize )
|
||
{//メモリなので実行時バグ
|
||
res = RESULT_FAIL;
|
||
break;
|
||
}
|
||
//verifi
|
||
for (i = 0;i<rsize;i++)if (fileBuffer[i] != fileBuffer_ex[i])
|
||
{
|
||
res = RESULT_FAIL_VERIFI;
|
||
break;
|
||
}
|
||
}
|
||
savedata.Close();
|
||
memsave.Close();
|
||
if (res != RESULT_OK)break;
|
||
ct++;
|
||
}
|
||
savedata.Close();
|
||
memsave.Close();
|
||
}
|
||
|
||
//セーブ前後で構成が一致するか
|
||
if(flg){//読み込み時は無駄なのでフラグでキャンセル
|
||
if(savedata.GetInfo(&arcInfo2,&dcList2)==false)res = RESULT_FAIL_VERIFI;
|
||
else if (arcInfo.total != arcInfo2.total)res = RESULT_FAIL_VERIFI;
|
||
else if (arcInfo.DirEntry != arcInfo2.DirEntry)res = RESULT_FAIL_VERIFI;
|
||
else if (arcInfo.DirCount != arcInfo2.DirCount)res = RESULT_FAIL_VERIFI;
|
||
else if (arcInfo.FileEntry != arcInfo2.FileEntry)res = RESULT_FAIL_VERIFI;
|
||
else if (arcInfo.FileCount != arcInfo2.FileCount)res = RESULT_FAIL_VERIFI;
|
||
else if (arcInfo.Dup != arcInfo2.Dup)res = RESULT_FAIL_VERIFI;
|
||
if (res == RESULT_OK)
|
||
{
|
||
int j,k=0;
|
||
if(dcList.num != dcList2.num)res=RESULT_FAIL_VERIFI;
|
||
else {
|
||
for(i=0;i<dcList.num;i++){//いずれかに一致するか
|
||
for(j=0;j<dcList.num;j++){
|
||
if (CmpPathW(dcList.name[i],dcList2.name[j])){k++;break;}
|
||
}
|
||
}
|
||
if (k != dcList.num)res=RESULT_FAIL_VERIFI;//全一致?
|
||
}
|
||
}
|
||
}
|
||
savedata.Unmount();
|
||
memsave.Unmount();
|
||
scr_CountPerMax(ct,arcInfo.FileCount);
|
||
scr_CountPerMax2(0,0,total);
|
||
|
||
|
||
if (res != RESULT_OK){
|
||
//PutError(TGT_CARD,ERC_VERIFI);
|
||
return false;
|
||
}
|
||
|
||
|
||
return true;
|
||
}
|
||
|
||
//---------------------------------------------------------------------- from CARD
|
||
RetCode Card2Ctr()
|
||
{
|
||
myResult res;
|
||
int ct=0,msize,rsize;
|
||
s64 total=0,pos;
|
||
|
||
scr_BackupYesNo();//実行確認
|
||
WaitUI();//入力待ち
|
||
if(isInsEject != InEx_None )
|
||
{//挿抜?
|
||
//isInsEject = InEx_None;
|
||
return INSEXIT;//挿抜による中断
|
||
}
|
||
if (scr_evnt != EVNT_YES)return CANCEL;//キャンセル
|
||
scr_Backup();//画面表示
|
||
scr_Status(MessTxt(MT_ChkCard),COLOR_YELLO);
|
||
//セーブデータのマウント
|
||
res = savedata.Mount();
|
||
if(res != RESULT_OK){
|
||
PutError(TGT_CARD);
|
||
return ERROR;
|
||
}
|
||
|
||
//セーブデータの情報
|
||
//arcInfo <- フォーマット情報、ファイル、ディレクトリ数
|
||
//scList <- ディレクトリパス
|
||
if(savedata.GetInfo(&arcInfo,&dcList)==false)
|
||
{
|
||
savedata.Unmount();
|
||
PutError(TGT_CARD);
|
||
return ERROR;
|
||
}
|
||
|
||
//strcpy(arcInfo.Pcode,savedata.PrdCode);
|
||
|
||
//カウント異常なら実行エラー
|
||
if (arcInfo.FileCount > arcInfo.FileEntry)
|
||
{
|
||
savedata.Unmount();
|
||
PutError(TGT_NONE,ERC_EXEC);
|
||
return ERROR;
|
||
}
|
||
if (arcInfo.DirCount > arcInfo.DirEntry)
|
||
{
|
||
savedata.Unmount();
|
||
PutError(TGT_NONE,ERC_EXEC);
|
||
return ERROR;
|
||
}
|
||
|
||
if(arcInfo.DirCount >= MAX_DCLIST)
|
||
{//ディレクトリ数が多すぎ
|
||
savedata.Unmount();
|
||
PutError(TGT_MEM,ERC_EXEC);
|
||
return ERROR;
|
||
}
|
||
|
||
//メモリFSの予想占有サイズ
|
||
sSize = arcInfo.total+arcInfo.FileCount*512;
|
||
|
||
#ifdef CSM_FLAG_FORCE_SD
|
||
return Card2Sd();//デバグ用、強制でSDへ
|
||
//警告抑制 unreachable
|
||
#pragma diag_suppress 111
|
||
#endif
|
||
|
||
//簡易サイズチェック
|
||
if (sSize > MEM_BKUP_SIZE)
|
||
{
|
||
#ifdef CSM_FLAG_USE_SD
|
||
if (alive_Sd)return Card2Sd();//SD使用
|
||
#endif
|
||
savedata.Unmount();
|
||
PutError(TGT_MEM,ERC_NOSPACE);//容量オーバ
|
||
return ERROR;
|
||
}
|
||
#ifdef CSM_FLAG_USE_SD
|
||
//本体メモリ使用
|
||
BkupSd = false;
|
||
#endif
|
||
|
||
//一時保存が存在したら消す
|
||
scr_Status(MessTxt(MT_ChkBkup),COLOR_YELLO);
|
||
if(memsave.IsExist()){
|
||
if(memsave.Delete()==false)
|
||
{
|
||
savedata.Unmount();
|
||
PutError(TGT_MEM);
|
||
return ERROR;
|
||
}
|
||
}
|
||
|
||
//一時保存先の作成
|
||
scr_Status(MessTxt(MT_CrtBkup),COLOR_YELLO);
|
||
res = memsave.Create(arcInfo.DirEntry+1,arcInfo.FileEntry+1);
|
||
if (res != RESULT_OK){
|
||
savedata.Unmount();
|
||
PutError(TGT_MEM);
|
||
return ERROR;
|
||
}
|
||
|
||
if (arcInfo.FileCount == 0)//ファイルが無い
|
||
{
|
||
scr_Status(MessTxt(MT_FileNot),COLOR_YELLO);
|
||
savedata.Unmount();
|
||
memsave.Unmount();
|
||
strcpy(arcInfo.Pcode,savedata.PrdCode);
|
||
return SUCCESS;//フォーマットのみ
|
||
}else{
|
||
scr_Status(MessTxt(MT_Reading),COLOR_SKY);
|
||
savedata.ResetPath();
|
||
s64 fsize;
|
||
res = RESULT_OK;
|
||
while(res==RESULT_OK){
|
||
res = savedata.GetPath(file_pathw);
|
||
if (res != RESULT_OK)
|
||
{
|
||
if (res == RESULT_DIR_LEVEL_OVER){
|
||
//PutError(ERC_DEV_CARD,ERC_DIRDEPTH);
|
||
PutError(TGT_NONE,ERC_WORK);
|
||
break;
|
||
}
|
||
if (res == RESULT_PATH_LENGTH_OVER){
|
||
//PutError(ERC_DEV_CARD,ERC_PATH);
|
||
PutError(TGT_NONE,ERC_WORK);
|
||
break;
|
||
}
|
||
res = RESULT_FAIL_OPEN;
|
||
break;
|
||
}
|
||
if (file_pathw[0] == 0)break;//root then end
|
||
if (ct>=arcInfo.FileCount)
|
||
{//カウンタ壊れ、メモリフローの可能性
|
||
res = RESULT_FAIL;
|
||
break;
|
||
}
|
||
|
||
scr_CountPerMax(ct,arcInfo.FileCount);
|
||
if (savedata.Open(file_pathw)==false)
|
||
{
|
||
res = RESULT_FAIL_OPEN;
|
||
break;
|
||
}
|
||
fsize = savedata.FileSize;
|
||
total += fsize;
|
||
if (memsave.OpenW(file_pathw,fsize)==false)
|
||
{
|
||
res = RESULT_FAIL_OPENW;
|
||
//savedata.Close();
|
||
break;
|
||
}
|
||
|
||
|
||
//検証単位の512ずつ
|
||
msize=fsize;
|
||
pos = 0;
|
||
while(fsize)
|
||
{
|
||
if(msize > FILEBUFF_SIZE * 2){
|
||
scr_CountPerMax2(msize-fsize,msize,0);
|
||
}
|
||
if (fsize>FILEBUFF_SIZE)
|
||
{
|
||
rsize = FILEBUFF_SIZE;
|
||
fsize -= FILEBUFF_SIZE;
|
||
}else{
|
||
rsize = fsize;
|
||
fsize = 0;
|
||
}
|
||
if (ReadBlock(pos,rsize)==false)
|
||
{
|
||
res = RESULT_FAIL_READ;
|
||
break;
|
||
}
|
||
pos += rsize;
|
||
if(memsave.Write(fileBuffer,rsize) != rsize )
|
||
{
|
||
res = RESULT_FAIL_WRITE;
|
||
break;
|
||
}
|
||
}
|
||
|
||
savedata.Close();
|
||
memsave.CloseW();
|
||
//todo: ゲージ表示
|
||
ct++;
|
||
}
|
||
savedata.Close();
|
||
memsave.CloseW();
|
||
}
|
||
|
||
if (res == RESULT_OK){
|
||
if (ct != arcInfo.FileCount)//ファイル数に満たないパス検索終了
|
||
{//ディレクトリ情報かパス取得で失敗してると思われる
|
||
PutError(TGT_NONE,ERC_EXEC);
|
||
return ERROR;
|
||
}
|
||
}
|
||
savedata.Unmount();
|
||
//memsave.Commit(); Nand,SDはコミット入れる
|
||
memsave.Unmount();
|
||
scr_CountPerMax(ct,arcInfo.FileCount);
|
||
if(total>0)scr_CountPerMax2(0,0,total);
|
||
|
||
//結果
|
||
switch(res)
|
||
{
|
||
case RESULT_OK:
|
||
if (Verifi(false))
|
||
{
|
||
scr_Status(MessTxt(MT_Complate),COLOR_WHITE);
|
||
strcpy(arcInfo.Pcode,savedata.PrdCode);
|
||
return SUCCESS;
|
||
}
|
||
PutError(TGT_CARD,ERC_VERIFI);
|
||
break;
|
||
case RESULT_FAIL_WRITE:
|
||
case RESULT_FAIL_OPENW:
|
||
PutError(TGT_MEM,ERC_WRITE);
|
||
break;
|
||
case RESULT_FAIL_READ:
|
||
case RESULT_FAIL_OPEN:
|
||
PutError(TGT_CARD,ERC_READ);
|
||
break;
|
||
default:
|
||
PutError(TGT_NONE,ERC_EXEC);
|
||
break;
|
||
|
||
}
|
||
memsave.Delete();//バックアップを削除
|
||
return ERROR;
|
||
}
|
||
|
||
|
||
bool mkdir;
|
||
//---------------------------------------------------------------- to CARD
|
||
RetCode Ctr2Card()
|
||
{
|
||
myResult res;
|
||
int ct=0;
|
||
int msize,rsize;
|
||
s64 total = 0;
|
||
|
||
scr_RestoreYesNo();//実行確認
|
||
WaitUI();//入力待ち
|
||
if(isInsEject != InEx_None ){//挿抜?
|
||
//isInsEject = InEx_None;
|
||
return INSEXIT;//挿抜による中断
|
||
}
|
||
|
||
if (scr_evnt != EVNT_YES)return CANCEL;//キャンセル
|
||
scr_Restore();//画面表示
|
||
scr_Status(MessTxt(MT_ChkBkup),COLOR_YELLO);
|
||
|
||
#ifdef CSM_FLAG_USE_SD
|
||
if (BkupSd)return Sd2Card();//SD使用
|
||
#endif
|
||
|
||
//一時保存のマウント
|
||
res = memsave.Mount();
|
||
if(res != RESULT_OK){
|
||
PutError(TGT_MEM);
|
||
return ERROR;
|
||
}
|
||
|
||
//セーブデータのフォーマット&マウント
|
||
scr_Status(MessTxt(MT_CardFormat),COLOR_YELLO);
|
||
res = savedata.Format(&arcInfo);
|
||
if(res != RESULT_OK){
|
||
memsave.Unmount();
|
||
PutError(TGT_CARD);
|
||
return ERROR;
|
||
}
|
||
|
||
//ディレクトリ作成
|
||
//空ディレクトリもチェックするゲームあるので(マリカ7)
|
||
//ファイルの存在と関係なく作成
|
||
if(dcList.num >0)
|
||
{
|
||
int i,rev=0;
|
||
for (i=0;i<dcList.num;i++)
|
||
{
|
||
while(1){
|
||
if (savedata.MakeDir(dcList.name[i],&mkdir)==false)
|
||
{
|
||
if(mkdir==false)
|
||
{
|
||
res = RESULT_FAIL_OPENW;
|
||
break;
|
||
}
|
||
}else break;
|
||
}
|
||
if (res != RESULT_OK)break;
|
||
rev^=1;
|
||
if (rev & 1)scr_Status(MessTxt(MT_CrtDir1),COLOR_YELLO);
|
||
else scr_Status(MessTxt(MT_CrtDir2),COLOR_YELLO);
|
||
}
|
||
if (res != RESULT_OK)
|
||
{
|
||
memsave.Unmount();
|
||
savedata.Unmount();
|
||
PutError(TGT_CARD);
|
||
return ERROR;
|
||
}
|
||
}
|
||
|
||
//パラメータはバックアップ時
|
||
//Top画面開始時、挿入イベントなどで取得済み
|
||
if (arcInfo.FileCount == 0)
|
||
{ //ファイルが無い場合抜ける
|
||
scr_Status(MessTxt(MT_FormatOnly),COLOR_YELLO);
|
||
savedata.Unmount();
|
||
memsave.Unmount();
|
||
memsave.Delete();
|
||
return SUCCESS;
|
||
}else{
|
||
scr_Status(MessTxt(MT_Writing),COLOR_PARPL);
|
||
memsave.ResetPath();
|
||
s64 fsize;
|
||
res = RESULT_OK;
|
||
while(res==RESULT_OK){
|
||
res = memsave.GetPath(file_pathw);
|
||
if (res != RESULT_OK)
|
||
{
|
||
if (res == RESULT_DIR_LEVEL_OVER)break;
|
||
if (res == RESULT_PATH_LENGTH_OVER)break;
|
||
res = RESULT_FAIL_OPEN;
|
||
break;
|
||
}
|
||
if (file_pathw[0] == 0)break;//root then end
|
||
if (ct>=arcInfo.FileCount)
|
||
{//カウンタ壊れ、メモリフローの可能性
|
||
res = RESULT_FAIL;
|
||
break;
|
||
}
|
||
|
||
scr_CountPerMax(ct,arcInfo.FileCount);
|
||
if (memsave.Open(file_pathw)==false)
|
||
{
|
||
res = RESULT_FAIL_OPEN;
|
||
break;
|
||
}
|
||
fsize = memsave.FileSize;
|
||
total += fsize;
|
||
|
||
if (savedata.OpenC(file_pathw,fsize,&mkdir)==false)
|
||
{
|
||
//ディレクトリは作成済みなので作成されたらエラー
|
||
res = RESULT_FAIL_OPENW;
|
||
break;
|
||
}
|
||
/*
|
||
int rev = 0;
|
||
while(1){
|
||
if (savedata.OpenC(file_pathw,fsize,&mkdir)==false)
|
||
{
|
||
if(mkdir)//ディレクトリのみ作成
|
||
{//深い場合に作成が多いと画面が止まるので
|
||
rev++;
|
||
if (rev & 1)scr_MessOnCount2(MessTxt(MT_CrtDir1));
|
||
else scr_MessOnCount2(MessTxt(MT_CrtDir2));
|
||
|
||
}else{
|
||
res = RESULT_FAIL_OPENW;
|
||
//memsave.Close();
|
||
break;
|
||
}
|
||
}else break;
|
||
}
|
||
if (res != RESULT_OK)break;
|
||
*/
|
||
|
||
//メモリファイルで検証エラーはないので512ごとである必要は無いが
|
||
//メモリ節約のため同じ方法をとる
|
||
msize = fsize;
|
||
int itvl = 0;
|
||
while(fsize)
|
||
{
|
||
if(msize > FILEBUFF_SIZE * 2){
|
||
scr_CountPerMax2(msize-fsize,msize,0);
|
||
if (++itvl & 1)scr_Status(MessTxt(MT_Copy1),COLOR_PARPL);
|
||
else scr_Status(MessTxt(MT_Copy2),COLOR_PARPL);
|
||
}else scr_MessOnCount2(MES_NULL);
|
||
|
||
if (fsize>FILEBUFF_SIZE)
|
||
{
|
||
rsize = FILEBUFF_SIZE;
|
||
fsize -= FILEBUFF_SIZE;
|
||
}else{
|
||
rsize = fsize;
|
||
fsize = 0;
|
||
}
|
||
if(memsave.Read(fileBuffer,rsize) != rsize )
|
||
{
|
||
res = RESULT_FAIL_READ;
|
||
break;
|
||
}
|
||
if(savedata.Write(fileBuffer,rsize) != rsize )
|
||
{
|
||
res = RESULT_FAIL_WRITE;
|
||
break;
|
||
}
|
||
}
|
||
savedata.CloseW();
|
||
memsave.Close();
|
||
ct++;
|
||
}
|
||
savedata.Close();
|
||
memsave.CloseW();
|
||
}
|
||
|
||
savedata.Commit();
|
||
savedata.Unmount();
|
||
memsave.Unmount();
|
||
scr_CountPerMax(ct,arcInfo.FileCount);
|
||
scr_CountPerMax2(0,0,total);
|
||
|
||
//結果
|
||
switch(res){
|
||
case RESULT_OK:
|
||
if (Verifi(true)){
|
||
if(memsave.Delete()){//バックアップを削除
|
||
scr_Status(MessTxt(MT_Complate),COLOR_WHITE);
|
||
return SUCCESS;
|
||
}
|
||
}
|
||
PutError(TGT_CARD,ERC_VERIFI);
|
||
break;
|
||
|
||
case RESULT_FAIL_WRITE:
|
||
case RESULT_FAIL_OPENW:
|
||
PutError(TGT_CARD,ERC_WRITE);
|
||
break;
|
||
case RESULT_FAIL_READ:
|
||
case RESULT_FAIL_OPEN:
|
||
PutError(TGT_MEM,ERC_READ);
|
||
break;
|
||
default:
|
||
PutError(TGT_NONE,ERC_EXEC);
|
||
break;
|
||
}
|
||
return ERROR;
|
||
}
|
||
|
||
|
||
//******************************************** for SD
|
||
//パス長オーバのファイルはメモリ上に記録
|
||
//mem:/元ネーム <- リネーム名格納
|
||
//sd:/ワーク/リネーム名 <-データ格納
|
||
//20000ファイル程度まで
|
||
|
||
#ifdef CSM_FLAG_USE_SD
|
||
bool VerifiSd()
|
||
{
|
||
myResult res;
|
||
int ct,i,msize,rsize;
|
||
s64 total=0,pos;
|
||
wchar_t ws[20];//"/"+16文字+"\0"
|
||
|
||
|
||
//セーブデータのマウント
|
||
res = savedata.Mount();
|
||
if(res != RESULT_OK){
|
||
//PutError(TGT_CARD);
|
||
return false;
|
||
}
|
||
|
||
//出力デバイスのマウント
|
||
res = exsave.Mount();
|
||
if(res != RESULT_OK){
|
||
//PutError(TGT_SD);
|
||
return false;
|
||
}
|
||
memsave.Mount();
|
||
|
||
ct =0;
|
||
if (arcInfo.FileCount == 0)//ファイルが無い
|
||
{
|
||
savedata.Unmount();
|
||
exsave.Unmount();
|
||
return true;//フォーマット一致のみ
|
||
}else{
|
||
scr_Status(MessTxt(MT_Compair),COLOR_YELLO);
|
||
savedata.ResetPath();
|
||
exsave.ResetPath();
|
||
s64 fsize;
|
||
res = RESULT_OK;
|
||
while(res==RESULT_OK){
|
||
if(CheckInsExit())break;//挿抜による中断
|
||
res = savedata.GetPath(file_pathw);
|
||
if (res != RESULT_OK)
|
||
{
|
||
if (res == RESULT_DIR_LEVEL_OVER){
|
||
break;
|
||
}
|
||
if (res == RESULT_PATH_LENGTH_OVER){
|
||
break;
|
||
}
|
||
res = RESULT_FAIL_OPEN;
|
||
break;
|
||
}
|
||
if (file_pathw[0] == 0)break;//root then end
|
||
if (ct>=arcInfo.FileCount)
|
||
{//カウンタ壊れ、メモリフローの可能性
|
||
res = RESULT_FAIL;
|
||
break;
|
||
}
|
||
if(CheckInsExit())break;//挿抜による中断
|
||
scr_CountPerMax(ct,arcInfo.FileCount);
|
||
if (savedata.Open(file_pathw)==false)
|
||
{
|
||
res = RESULT_FAIL_OPEN;
|
||
break;
|
||
}
|
||
fsize = savedata.FileSize;
|
||
total += fsize;
|
||
|
||
if (memsave.Open(file_pathw))
|
||
{//リネーム対象
|
||
memsave.Read((char*)ws,18);//リネーム名
|
||
ws[9]=0;ws[10]=0;
|
||
wcscpy(file_pathw,wk_dir);//格納先ディレクトリ
|
||
wcscat(file_pathw,ws);//パス変換
|
||
memsave.Close();
|
||
}
|
||
if(CheckInsExit())break;//挿抜による中断
|
||
if (exsave.Open(file_pathw)==false)
|
||
{
|
||
res = RESULT_FAIL_OPENW;
|
||
//savedata.Close();
|
||
break;
|
||
}
|
||
if (fsize != exsave.FileSize)//file size
|
||
{
|
||
res = RESULT_FAIL;
|
||
break;
|
||
}
|
||
|
||
msize=fsize;
|
||
if(msize <= FILEBUFF_SIZE ){//一回で読めるサイズならゲージは出さない
|
||
scr_CountPerMax2(0,0,-1);
|
||
}
|
||
pos = 0;
|
||
while(fsize)
|
||
{
|
||
if(msize > FILEBUFF_SIZE ){
|
||
scr_CountPerMax2(msize-fsize,msize,0);
|
||
}
|
||
if (fsize > FILEBUFF_SIZE)
|
||
{
|
||
rsize = FILEBUFF_SIZE;
|
||
fsize -= FILEBUFF_SIZE;
|
||
}else{
|
||
rsize = fsize;
|
||
fsize = 0;
|
||
}
|
||
if(CheckInsExit())break;//挿抜による中断
|
||
if (ReadBlock(pos,rsize)==false)
|
||
{
|
||
res = RESULT_FAIL_READ;
|
||
break;
|
||
}
|
||
pos += rsize;
|
||
if(CheckInsExit())break;//挿抜による中断
|
||
if(exsave.Read(fileBuffer_ex,rsize) != rsize )
|
||
{
|
||
res = RESULT_FAIL;
|
||
break;
|
||
}
|
||
for (i = 0;i<rsize;i++)if (fileBuffer[i] != fileBuffer_ex[i])
|
||
{
|
||
res = RESULT_FAIL;
|
||
break;
|
||
}
|
||
}
|
||
savedata.Close();
|
||
exsave.Close();
|
||
memsave.Close();
|
||
if(isInsEject != InEx_None )break;//挿抜による中断
|
||
if (res != RESULT_OK)break;
|
||
//verifi
|
||
ct++;
|
||
}
|
||
savedata.Close();
|
||
exsave.Close();
|
||
memsave.Close();
|
||
}
|
||
|
||
savedata.Unmount();
|
||
exsave.Unmount();
|
||
memsave.Unmount();
|
||
scr_CountPerMax(ct,arcInfo.FileCount);
|
||
scr_CountPerMax2(0,0,total);
|
||
|
||
if (res != RESULT_OK){
|
||
// PutError(ERC_DEV_OTHER,ERC_VERIFI);
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
//エラー表示&リターン選択(抜け or ERROR)
|
||
RetCode PutErrRetCode(TgtDev dev,int erc = 0)
|
||
{
|
||
savedata.Unmount();
|
||
exsave.Unmount();
|
||
memsave.Unmount();
|
||
if(CheckInsExit())return INSEXIT;
|
||
PutError(dev,erc);
|
||
return ERROR;
|
||
}
|
||
|
||
|
||
//Ctr2Cardより呼ばれる
|
||
RetCode Sd2Card()
|
||
{
|
||
myResult res;
|
||
int ct=0,msize,rsize;
|
||
s64 total = 0;
|
||
wchar_t ws[20];//"/"+16文字+"\0"
|
||
|
||
//カードのフォーマット&マウント
|
||
scr_Status(MessTxt(MT_CardFormat),COLOR_YELLO);
|
||
res = savedata.Format(&arcInfo);
|
||
if(res != RESULT_OK) return PutErrRetCode(TGT_CARD,ERC_FORMAT);
|
||
|
||
//パラメータはバックアップ時
|
||
//Top画面開始時、挿入イベントで取得
|
||
if (arcInfo.FileCount == 0)//ファイルが無い
|
||
{
|
||
savedata.Unmount();
|
||
if(exsave.Delete()){//バックアップを削除
|
||
scr_Status(MessTxt(MT_FormatOnly),COLOR_YELLO);
|
||
return SUCCESS;
|
||
}
|
||
return PutErrRetCode(TGT_SD,ERC_ACCESS);
|
||
}
|
||
|
||
//拡張セーブのマウント
|
||
res = exsave.Mount();
|
||
if(res != RESULT_OK) return PutErrRetCode(TGT_SD);
|
||
memsave.Mount();
|
||
|
||
scr_Status(MessTxt(MT_Writing),COLOR_PARPL);
|
||
exsave.ResetPath();
|
||
s64 fsize;
|
||
res = RESULT_OK;
|
||
while(res==RESULT_OK){
|
||
res = exsave.GetPath(file_pathw);
|
||
if (res != RESULT_OK)
|
||
{
|
||
if ((res != RESULT_DIR_LEVEL_OVER)
|
||
&& (res != RESULT_PATH_LENGTH_OVER))res = RESULT_FAIL_OPEN;
|
||
break;
|
||
}
|
||
if (file_pathw[0] == 0)break;//root then end
|
||
if (ct>=arcInfo.FileCount)
|
||
{//カウンタ壊れ、メモリフローの可能性
|
||
res = RESULT_FAIL;
|
||
break;
|
||
}
|
||
|
||
scr_CountPerMax(ct,arcInfo.FileCount);//カウンタ表示
|
||
if (exsave.Open(file_pathw)==false)
|
||
{
|
||
res = RESULT_FAIL_OPEN;
|
||
break;
|
||
}
|
||
fsize = exsave.FileSize;
|
||
total += fsize;
|
||
|
||
if (savedata.CheckPathBit & cpb_ex )
|
||
{//違反パス名あり?
|
||
if (CmpDirW(file_pathw,wk_dir)==1)
|
||
{//リネームファイルなら元のパス名を探す
|
||
memsave.ResetPath();
|
||
int i=0;bool b=false;
|
||
ws[9]=0;ws[10]=0;
|
||
while(i<rename_n){
|
||
memsave.GetPath(file_pathw2);
|
||
if(file_pathw2[0]==0)break;
|
||
memsave.Open(file_pathw2);
|
||
memsave.Read((char*)ws,18);
|
||
if(CmpNameW(file_pathw,ws)){
|
||
wcscpy(file_pathw,file_pathw2);
|
||
b = true;
|
||
break;
|
||
}
|
||
i++;
|
||
}//while
|
||
if (b==false){//見つからない->差替?? or メモリ破壊??
|
||
res = RESULT_FAIL;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
int rev = 0;
|
||
while(1){
|
||
if (savedata.OpenC(file_pathw,fsize,&mkdir)==false)
|
||
{
|
||
if(mkdir)//ディレクトリのみ作成
|
||
{//深い場合に作成が多いと画面が止まるので
|
||
rev++;
|
||
if (rev & 1)scr_MessOnCount2(MessTxt(MT_CrtDir1));
|
||
else scr_MessOnCount2(MessTxt(MT_CrtDir2));
|
||
}else{
|
||
res = RESULT_FAIL_OPENW;
|
||
//exsave.Close();
|
||
break;
|
||
}
|
||
}else break;
|
||
}//while
|
||
if (res != RESULT_OK)break;
|
||
|
||
msize = fsize;
|
||
int itvl = 0;
|
||
while(fsize)
|
||
{
|
||
if(msize > FILEBUFF_SIZE * 2){
|
||
scr_CountPerMax2(msize-fsize,msize,0);
|
||
if (++itvl & 1)scr_Status(MessTxt(MT_Copy1),COLOR_PARPL);
|
||
else scr_Status(MessTxt(MT_Copy2),COLOR_PARPL);
|
||
}else scr_MessOnCount2(MES_NULL);
|
||
|
||
if (fsize>FILEBUFF_SIZE)
|
||
{
|
||
rsize = FILEBUFF_SIZE;
|
||
fsize -= FILEBUFF_SIZE;
|
||
}else{
|
||
rsize = fsize;
|
||
fsize = 0;
|
||
}
|
||
if(exsave.Read(fileBuffer,rsize) != rsize )
|
||
{
|
||
res = RESULT_FAIL_READ;
|
||
break;
|
||
}
|
||
if(savedata.Write(fileBuffer,rsize) != rsize )
|
||
{
|
||
res = RESULT_FAIL_WRITE;
|
||
break;
|
||
}
|
||
}//while
|
||
savedata.CloseW();
|
||
exsave.Close();
|
||
ct++;
|
||
}//while
|
||
savedata.Close();
|
||
exsave.CloseW();
|
||
if(res == RESULT_OK)savedata.Commit();
|
||
|
||
savedata.Unmount();
|
||
exsave.Unmount();
|
||
memsave.Unmount();
|
||
scr_CountPerMax(ct,arcInfo.FileCount);
|
||
scr_CountPerMax2(0,0,total);
|
||
|
||
//結果
|
||
TgtDev ercd;
|
||
int ercc;
|
||
switch(res){
|
||
case RESULT_OK:
|
||
if (VerifiSd()){
|
||
memsave.Delete();
|
||
if(exsave.Delete()){//バックアップを削除
|
||
scr_Status(MessTxt(MT_Complate),COLOR_WHITE);
|
||
return SUCCESS;
|
||
}
|
||
}
|
||
ercd =TGT_CARD;ercc = ERC_VERIFI;//ベリファイエラー
|
||
break;
|
||
case RESULT_FAIL_WRITE:
|
||
case RESULT_FAIL_OPENW:
|
||
ercd = TGT_CARD;ercc = ERC_WRITE;
|
||
break;
|
||
case RESULT_FAIL_READ:
|
||
case RESULT_FAIL_OPEN:
|
||
ercd = TGT_SD;ercc = ERC_READ;
|
||
break;
|
||
default:
|
||
ercd = TGT_NONE;ercc = ERC_EXEC;
|
||
break;
|
||
}
|
||
return PutErrRetCode(ercd,ercc);
|
||
}
|
||
|
||
|
||
|
||
//Crad2Ctrより呼ばれる
|
||
RetCode Card2Sd()
|
||
{
|
||
myResult res;
|
||
int ct=0,msize,rsize;
|
||
s64 total=0,fsize,pos;
|
||
|
||
int i;
|
||
wchar_t ws[20];//"/"+16文字+"\0"
|
||
|
||
BkupSd = true;
|
||
|
||
//拡張セーブが存在したら消す
|
||
scr_Status(MessTxt(MT_ChkBkup),COLOR_YELLO);
|
||
if(exsave.IsExist()){
|
||
if(exsave.Delete()==false) return PutErrRetCode(TGT_SD);
|
||
}
|
||
if(CheckInsExit())return INSEXIT;//抜けで"なし"判定の場合
|
||
|
||
//一時保存先の作成
|
||
scr_Status(MessTxt(MT_CrtBkup),COLOR_YELLO);
|
||
//拡張セーブで違反になるパス名あり?
|
||
if (savedata.CheckPathBit & cpb_ex )
|
||
{
|
||
//該当ファイルを変名保存するディレクトリ追加
|
||
res = exsave.Create(arcInfo.DirEntry+1,arcInfo.FileEntry);
|
||
}else res = exsave.Create(arcInfo.DirEntry,arcInfo.FileEntry);
|
||
if (res != RESULT_OK) return PutErrRetCode(TGT_SD);
|
||
|
||
if(CheckInsExit())return INSEXIT;//抜け
|
||
|
||
//パラメータはバックアップ時
|
||
//Top画面開始時、挿入イベントで取得
|
||
if (arcInfo.FileCount == 0)//ファイルが無い
|
||
{
|
||
scr_Status(MessTxt(MT_FileNot),COLOR_YELLO);
|
||
strcpy(arcInfo.Pcode,savedata.PrdCode);
|
||
savedata.Unmount();
|
||
return SUCCESS;//フォーマットのみ
|
||
}
|
||
|
||
|
||
//簡易サイズチェック
|
||
//SDのクラスタサイズやヘッダでメモリFSより多く占有する
|
||
//セクタサイズ4K:2GB、32K:4GB 余裕を見ておく(ファイル数上限での最悪)
|
||
//4GBデバイスの移行なら、8G以上のSDを使う
|
||
fsize = exsave.GetFreeSize();//取得APIがマウント必須なのでCreate後でないとダメ
|
||
//ヘッダ16k+4K(ファイル名+アライメント) ..SDセクタサイズ4Kの前提
|
||
sSize = arcInfo.total + arcInfo.FileCount*20480;
|
||
if ((sSize > fsize) || (fsize ==0)) return PutErrRetCode(TGT_SD,ERC_NOSPACE);
|
||
|
||
//メモリFS上に作成..ファイル名保存のため、中身はSD上のファイル名
|
||
//拡張セーブは最大パス長がユーザセーブより短いため超えるものは変名
|
||
//オリジナルファイル名で作成したファイルに変更後のファイル名を格納
|
||
//ワークの10MByteで1万ファイルくらい
|
||
memsave.Delete();
|
||
memsave.Create(1,arcInfo.FileCount);
|
||
memsave.Mount();
|
||
|
||
//read
|
||
scr_Status(MessTxt(MT_Reading),COLOR_PARPL);
|
||
savedata.ResetPath();
|
||
total=0;ct=0;rename_n=0;
|
||
res = RESULT_OK;
|
||
while(res==RESULT_OK){
|
||
res = savedata.GetPath(file_pathw);
|
||
if (res != RESULT_OK)
|
||
{
|
||
if ((res != RESULT_DIR_LEVEL_OVER)
|
||
&& (res != RESULT_PATH_LENGTH_OVER)) res = RESULT_FAIL_OPEN;
|
||
break;
|
||
}
|
||
if (file_pathw[0] == 0)break;//root then end
|
||
if (ct>=arcInfo.FileCount)
|
||
{//カウンタ壊れ、メモリフローの可能性
|
||
res = RESULT_FAIL;
|
||
break;
|
||
}
|
||
|
||
scr_CountPerMax(ct,arcInfo.FileCount);
|
||
if (savedata.Open(file_pathw)==false)
|
||
{
|
||
res = RESULT_FAIL_OPEN;
|
||
break;
|
||
}
|
||
fsize = savedata.FileSize;
|
||
total += fsize;
|
||
|
||
//パス名チェック
|
||
if (CheckPathEx(file_pathw) == false)
|
||
{//メモリFS上にファイル作成(パス名記録のみ目的)
|
||
savedata.Close();
|
||
if (memsave.OpenW(file_pathw,512)==false)
|
||
{
|
||
res = RESULT_FAIL_OPENW;
|
||
break;
|
||
}
|
||
|
||
//リネーム名の格納
|
||
swprintf(ws,16,L"/%8x",rename_n);//リネーム
|
||
for (i=1;i<8;i++)if(ws[i]==L' ')ws[i]=L'0';
|
||
rename_n++;
|
||
if(memsave.Write( (char*)ws,18) != 18)//wchar 9文字
|
||
{
|
||
res = RESULT_WORK_OVER;//ワーク不足
|
||
break;
|
||
}
|
||
memsave.CloseW();
|
||
}else
|
||
{
|
||
int rev = 0;
|
||
while(1){
|
||
if (exsave.OpenC(file_pathw,fsize,&mkdir)==false)
|
||
{
|
||
if(mkdir)//ディレクトリのみ作成
|
||
{//深い場合に作成が多いと画面が止まるので
|
||
rev++;
|
||
if (rev & 1)scr_MessOnCount2(MessTxt(MT_CrtDir1));
|
||
else scr_MessOnCount2(MessTxt(MT_CrtDir2));
|
||
}else{
|
||
res = RESULT_FAIL_OPENW;
|
||
//exsave.Close();
|
||
break;
|
||
}
|
||
}else break;
|
||
}
|
||
if (res != RESULT_OK)break;
|
||
msize = fsize;
|
||
int itvl = 0;
|
||
pos =0;
|
||
while(fsize)
|
||
{
|
||
if(msize > FILEBUFF_SIZE * 2)
|
||
{
|
||
scr_CountPerMax2(msize-fsize,msize,0);
|
||
if (++itvl & 1)scr_Status(MessTxt(MT_Copy1),COLOR_PARPL);
|
||
else scr_Status(MessTxt(MT_Copy2),COLOR_PARPL);
|
||
}else scr_MessOnCount2(MES_NULL);
|
||
|
||
if (fsize>FILEBUFF_SIZE)
|
||
{
|
||
rsize = FILEBUFF_SIZE;
|
||
fsize -= FILEBUFF_SIZE;
|
||
}else{
|
||
rsize = fsize;
|
||
fsize = 0;
|
||
}
|
||
if (ReadBlock(pos,rsize)==false)
|
||
{
|
||
res = RESULT_FAIL_READ;
|
||
break;
|
||
}
|
||
pos += rsize;
|
||
if(exsave.Write(fileBuffer,rsize) != rsize )
|
||
{
|
||
NN_LOG("desc = %d\n",savedata.LastNnResult.GetDescription());
|
||
res = RESULT_FAIL_WRITE;
|
||
break;
|
||
}
|
||
}//fsize
|
||
ct++;
|
||
savedata.Close();
|
||
exsave.CloseW();
|
||
}//else
|
||
}//while
|
||
|
||
if ((res == RESULT_OK) && (savedata.CheckPathBit & cpb_ex))
|
||
{//違反パスありなら、リネームして保存
|
||
nn::Result result;
|
||
nn::fnd::DateTime tm;
|
||
//ディレクトリ作成..既存名を避けるため作成後に行う
|
||
i = 0;
|
||
while(i++ < 10 ){//試行回数(無駄?)
|
||
tm = nn::fnd::DateTime::GetNow();
|
||
//退避先ディレクトリ名作成:SDK制限で16文字まで
|
||
swprintf(file_pathw,3,L"%3d",tm.GetMilliSecond());
|
||
if (file_pathw[0]==L' ')file_pathw[0] = L'0';
|
||
if (file_pathw[1]==L' ')file_pathw[1] = L'0';
|
||
wcscpy(wk_dir,L"/cSm_");//通常、使われないであろう名前にする
|
||
wcscat(wk_dir,file_pathw);
|
||
wcscat(wk_dir,L"_zzz");
|
||
exsave.GetRootPath(file_pathw);
|
||
wcscat(file_pathw,wk_dir);
|
||
result = nn::fs::TryCreateDirectory(file_pathw);
|
||
if (result.IsSuccess())break;
|
||
if(CheckInsExit())break;
|
||
}
|
||
if (result.IsFailure()){
|
||
exsave.Unmount();
|
||
memsave.Unmount();
|
||
savedata.Unmount();
|
||
exsave.Delete();//バックアップを削除
|
||
memsave.Delete();
|
||
if(isInsEject != InEx_None )return INSEXIT;
|
||
PutError(TGT_SD,ERC_WORK);//退避先が確保できない
|
||
return ERROR;
|
||
}
|
||
|
||
memsave.ResetPath();
|
||
while(res==RESULT_OK){
|
||
res = memsave.GetPath(file_pathw);//リネーム対象ファイル名
|
||
if (file_pathw[0] == 0)break;//root then end
|
||
if (ct>=arcInfo.FileCount)
|
||
{
|
||
res = RESULT_FAIL;
|
||
break;
|
||
}
|
||
|
||
scr_CountPerMax(ct,arcInfo.FileCount);
|
||
|
||
if (savedata.Open(file_pathw)==false)//ユーザセーブ開く
|
||
{
|
||
res = RESULT_FAIL_OPEN;
|
||
break;
|
||
}
|
||
fsize = savedata.FileSize;
|
||
|
||
//リネーム名取得
|
||
if (memsave.Open(file_pathw)==false)
|
||
{
|
||
res = RESULT_FAIL;//メモリからなので通常ありえない
|
||
break;
|
||
}
|
||
if(memsave.Read((char*)ws,18)!=18)//wchar 9文字
|
||
{
|
||
res = RESULT_FAIL;//メモリからなので通常ありえない
|
||
break;
|
||
}
|
||
memsave.Close();
|
||
ws[9]=0;//終端
|
||
ws[10]=0;
|
||
wcscpy(file_pathw2,wk_dir);
|
||
wcscat(file_pathw2,ws);
|
||
if (exsave.OpenC(file_pathw2,fsize,&mkdir)==false)
|
||
{//エラーもしくは、退避先ディレクトリが無い
|
||
res = RESULT_FAIL_OPENW;
|
||
break;
|
||
}
|
||
msize = fsize;
|
||
pos =0;
|
||
while(fsize)
|
||
{
|
||
if (fsize>FILEBUFF_SIZE)
|
||
{
|
||
rsize = FILEBUFF_SIZE;
|
||
fsize -= FILEBUFF_SIZE;
|
||
}else{
|
||
rsize = fsize;
|
||
fsize = 0;
|
||
}
|
||
if (ReadBlock(pos,rsize)==false)
|
||
{
|
||
res = RESULT_FAIL_READ;
|
||
break;
|
||
}
|
||
pos += rsize;
|
||
if(exsave.Write(fileBuffer,rsize) != rsize )
|
||
{
|
||
res = RESULT_FAIL_WRITE;
|
||
break;
|
||
}
|
||
}//while(fsize)
|
||
ct++;
|
||
savedata.Close();
|
||
exsave.CloseW();
|
||
memsave.Close();
|
||
}//while
|
||
}//if
|
||
savedata.Unmount();
|
||
exsave.Unmount();
|
||
memsave.Unmount();
|
||
scr_CountPerMax(ct,arcInfo.FileCount);
|
||
scr_CountPerMax2(0,0,total);
|
||
|
||
//結果
|
||
TgtDev ercd;
|
||
int ercc;
|
||
switch(res)
|
||
{
|
||
case RESULT_OK:
|
||
if (VerifiSd())
|
||
{
|
||
scr_Status(MessTxt(MT_Complate),COLOR_WHITE);
|
||
strcpy(arcInfo.Pcode,savedata.PrdCode);
|
||
return SUCCESS;
|
||
}
|
||
ercd = TGT_CARD;ercc = ERC_VERIFI;
|
||
break;
|
||
case RESULT_FAIL_WRITE:
|
||
case RESULT_FAIL_OPENW:
|
||
ercd = TGT_SD;ercc = ERC_WRITE;//ライト失敗
|
||
break;
|
||
case RESULT_FAIL_READ:
|
||
case RESULT_FAIL_OPEN:
|
||
ercd = TGT_CARD;ercc = ERC_READ;//リード
|
||
break;
|
||
case RESULT_WORK_OVER:
|
||
ercd = TGT_NONE;ercc = ERC_NOSPACE;//ワーク不足..違反フアイル多すぎ
|
||
break;
|
||
default:
|
||
ercd = TGT_NONE;ercc = ERC_EXEC;
|
||
break;
|
||
}
|
||
exsave.Delete();//バックアップを削除
|
||
memsave.Delete();
|
||
return PutErrRetCode(ercd,ercc);
|
||
}
|
||
|
||
#endif
|
||
|
||
//--------------------------------------------------------------- セーブデータの情報取得
|
||
//呼ぶ前に tmerr のクリアを忘れない事
|
||
void CheckSaveDataState()
|
||
{
|
||
Formatted = false;
|
||
Active = false;
|
||
|
||
if (savedata.GetPrdCode())
|
||
{
|
||
//NN_LOG("%d",savedata.LastNnResult.GetDescription());
|
||
Active = true;//カード
|
||
if (savedata.IsExist())//マウントで確認
|
||
{
|
||
Formatted=true;
|
||
}else{
|
||
tmerr |= SDATA_ERRPUT_MEDIA;
|
||
}
|
||
}
|
||
scr_PrdCode(savedata.PrdCode);
|
||
//プロダクトコードのチェック
|
||
isAgreePCode = strcmp(savedata.PrdCode,arcInfo.Pcode)==0;
|
||
}
|
||
|
||
void CheckExSaveState()
|
||
{
|
||
#ifdef CSM_FLAG_USE_SD
|
||
if (alive_Sd)exActive = nn::fs::IsSdmcWritable();
|
||
else exActive = true;
|
||
#else
|
||
exActive = true;
|
||
#endif
|
||
if (exActive){
|
||
#ifdef CSM_FLAG_USE_SD
|
||
if (BkupSd){
|
||
exFormatted = exsave.IsExist();
|
||
exsave.Unmount();
|
||
}else{
|
||
#endif
|
||
exFormatted = memsave.IsExist();
|
||
memsave.Unmount();
|
||
#ifdef CSM_FLAG_USE_SD
|
||
}
|
||
#endif
|
||
|
||
}else{
|
||
exFormatted = false;
|
||
}
|
||
//デバグ時は抜けてもクリアしない
|
||
#ifndef CSM_FLAG_DEBUG
|
||
if (exFormatted==false) arcInfo.Pcode[0] = 0;
|
||
#endif
|
||
scr_PrdCodeEx(arcInfo.Pcode);
|
||
//プロダクトコードのチェック
|
||
isAgreePCode = strcmp(savedata.PrdCode,arcInfo.Pcode)==0;
|
||
}
|
||
|
||
//SD挿抜
|
||
void Evt_SdInEx()
|
||
{
|
||
#ifndef CSM_FLAG_DEBUG
|
||
ScrClr();
|
||
scr_TopMenu(Formatted,Active,exFormatted,exActive,tmerr);
|
||
scr_Draw();
|
||
failstop();//停止
|
||
#else
|
||
CheckExSaveState();//状態更新
|
||
scr_evnt = EVNT_INEX;
|
||
#endif
|
||
}
|
||
|
||
|
||
//---------------------------------------------------------------- 入力待ち
|
||
void WaitUI()
|
||
{
|
||
tmerr = 0;
|
||
scr_Draw();//画面更新
|
||
scr_evnt = EVNT_NONE;
|
||
while(scr_evnt == EVNT_NONE)
|
||
{
|
||
//nn::os::Thread::Yield();//スレッド実行
|
||
//scr_GetEvnt();//入力イベント
|
||
|
||
CheckSysBreak();//中断処理
|
||
|
||
#ifdef CSM_FLAG_USE_SD
|
||
//挿抜を検知したらアプリ終了待ちするようする
|
||
if (ejectEvntSd.TryWait()){
|
||
isInsEject = InEx_EjcSd;
|
||
Evt_SdInEx();
|
||
return;
|
||
}
|
||
if (insEvntSd.TryWait()){
|
||
isInsEject = InEx_InsSd;
|
||
Evt_SdInEx();
|
||
return;
|
||
}
|
||
#endif
|
||
//挿抜を検知したら中断して抜ける
|
||
//トップ以外ではトップメニューへ戻るようする
|
||
if (ejectEvnt.TryWait()){
|
||
isInsEject = InEx_EjcCard;
|
||
CheckSaveDataState();
|
||
scr_evnt = EVNT_INEX;
|
||
return;
|
||
}
|
||
if (insEvnt.TryWait()){
|
||
isInsEject = InEx_InsCard;
|
||
CheckSaveDataState();
|
||
scr_evnt = EVNT_INEX;
|
||
return;
|
||
}
|
||
nn::os::Thread::Yield();//スレッド実行..タッチ&ボタン取得
|
||
}
|
||
ScrClr();//画面消去
|
||
nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(500));//チャタ対策
|
||
}
|
||
|
||
void InsExtErrPut(tIsInsEject n)
|
||
{
|
||
switch (n)
|
||
{
|
||
case InEx_EjcSd:
|
||
case InEx_InsSd://SD insert or exit
|
||
PutError(TGT_SD,ERC_PULLOUT);
|
||
#ifndef CSM_FLAG_DEBUG
|
||
failstop();//stop running
|
||
#endif
|
||
break;
|
||
case InEx_EjcCard:
|
||
PutError(TGT_CARD,ERC_DEVICE);
|
||
break;
|
||
case InEx_InsCard://素早い抜き差しでEjectイベント消える?
|
||
PutError(TGT_CARD,ERC_PULLOUT);
|
||
break;
|
||
default://通常ありえない .. 実行時エラー
|
||
PutError(TGT_NONE,ERC_EXEC);
|
||
failstop();//stop running
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
//---------------------- main loop --------------------------
|
||
void nnMain()
|
||
{
|
||
RetCode retc;
|
||
//tColStr *colstr[4];
|
||
//colstr[2] = &mess_WhenExc;
|
||
//colstr[3] = &mess_PoffSys;
|
||
isInsEject = InEx_None;
|
||
|
||
//NN_LOG("Start\n");
|
||
nn::os::Initialize();
|
||
nn::fs::Initialize();
|
||
|
||
//DEA-SUPにて推奨のフリーズ暫定対策:無線デーモンを停止 (2011.3.1 現在)
|
||
//ただし、スリープ時は止まらない
|
||
//心配なら本体スイッチで切っとく
|
||
nn::ndm::Initialize();
|
||
nn::ndm::SuspendScheduler();
|
||
|
||
//中断処理の準備
|
||
InitSysBreak((uptr)endfunc);
|
||
// グラフィックスライブラリの初期化は、以降で行わなければならない
|
||
// 他、アプリケーションの初期化処理
|
||
|
||
nn::applet::DisableSleep();//スリープ非対応
|
||
|
||
#ifdef CSM_FLAG_USE_SD
|
||
//起動時にSD確認
|
||
alive_Sd = nn::fs::IsSdmcWritable();
|
||
#else
|
||
alive_Sd = false;
|
||
#endif
|
||
//Heap
|
||
appHeap.Initialize(nn::os::GetDeviceMemoryAddress(),
|
||
nn::os::GetDeviceMemorySize(), nn::os::ALLOCATE_OPTION_LINEAR);
|
||
const u32 GxHeapSize = 0x800000;
|
||
heapForGx = reinterpret_cast<uptr>(appHeap.Allocate(GxHeapSize));
|
||
//画面初期化
|
||
|
||
//メッセージ用テキストの読み込み
|
||
bool jp;
|
||
// nn::cfg::CTR::Initialize();
|
||
// if (nn::cfg::GetLanguage() == nn::cfg::CFG_LANGUAGE_JAPANESE)
|
||
// {
|
||
// jp = true;
|
||
// LoadMessText(L"rom:/lang_jp.mes");
|
||
//}
|
||
//else{
|
||
jp = false;
|
||
LoadMessText(L"rom:/lang_en.mes");
|
||
// }
|
||
// nn::cfg::Finalize();
|
||
|
||
#ifdef CSM_FLAG_DEBUG
|
||
//リリース品と区別するためタイトルに[debug]を付ける(非セキュア品の流出予防)
|
||
if (ScrInitialize(heapForGx,GxHeapSize,jp,true) == false)finish();
|
||
#else
|
||
if (ScrInitialize(heapForGx,GxHeapSize,jp,false) == false)finish();
|
||
#endif
|
||
|
||
|
||
//挿抜イベント
|
||
ejectEvnt.ClearSignal();
|
||
insEvnt.ClearSignal();
|
||
nn::fs::RegisterCardEjectedEvent(&ejectEvnt);
|
||
nn::fs::RegisterCardInsertedEvent(&insEvnt);
|
||
#ifdef CSM_FLAG_USE_SD
|
||
if (alive_Sd){
|
||
ejectEvntSd.ClearSignal();
|
||
insEvntSd.ClearSignal();
|
||
nn::fs::RegisterSdmcEjectedEvent(&ejectEvntSd);
|
||
nn::fs::RegisterSdmcInsertedEvent(&insEvntSd);
|
||
//拡張セーブが存在したら消す
|
||
if(exsave.IsExist())exsave.Delete();
|
||
}
|
||
#endif
|
||
|
||
// スリープ要求に対する返答を有効にする
|
||
// また、蓋の状態チェックを行い蓋が閉じられているならスリープ要求が発生する
|
||
//nn::applet::EnableSleep(true);
|
||
|
||
extern u8 scr_evnt;
|
||
u8 scr_evntbk;
|
||
while(1)
|
||
{
|
||
tmerr = 0;
|
||
CheckSaveDataState(); //セーブデータの状態取得
|
||
CheckExSaveState(); //同バックアップ
|
||
if (isAgreePCode==false) tmerr |= SDATA_ERRPUT_PCODE;
|
||
scr_TopMenu(Formatted,Active,exFormatted,exActive,tmerr);
|
||
|
||
WaitUI();//入力待ち
|
||
scr_evntbk = scr_evnt;
|
||
switch(scr_evnt)
|
||
{
|
||
case EVNT_INEX:
|
||
isInsEject= InEx_None;
|
||
break;
|
||
case EVNT_PUSH_B:
|
||
case EVNT_PUSH_R:
|
||
case EVNT_PUSH_Y:
|
||
case EVNT_NONE:
|
||
break;
|
||
case EVNT_SEL_READ://**************************** リード
|
||
NN_LOG("select read\n");
|
||
retc = Card2Ctr();
|
||
switch (retc){
|
||
case SUCCESS:
|
||
//CheckExSaveState(); //状態の更新
|
||
scr_ResultQuit(MessTxt(MT_Success),COLOR_GREEN);//成功とQuitボタン
|
||
break;
|
||
case INSEXIT:
|
||
//scr_InsExitQuit();//挿抜検知表示 & Quit
|
||
ScrClr();//画面消去
|
||
scr_Backup();
|
||
InsExtErrPut(isInsEject);
|
||
scr_ResultQuit(MessTxt(MT_Break),COLOR_RED);//エラーとQuitボタン
|
||
break;
|
||
case CANCEL:
|
||
break;
|
||
default://errors
|
||
if (CheckInsExit())InsExtErrPut(isInsEject);//抜差イベント?
|
||
scr_ResultQuit(MessTxt(MT_Failed),COLOR_RED);//エラーとQuitボタン
|
||
break;
|
||
}
|
||
break;
|
||
case EVNT_SEL_WRITE:// **************************** リストア
|
||
NN_LOG("select write\n");
|
||
retc = Ctr2Card();
|
||
switch (retc){
|
||
case SUCCESS:
|
||
//CheckSaveDataState(); //状態の更新
|
||
//CheckExSaveState();
|
||
scr_ResultQuit(MessTxt(MT_Success),COLOR_GREEN);//成功とQuitボタン
|
||
break;
|
||
case INSEXIT:
|
||
//scr_InsExitQuit();//挿抜検知表示 & Quit
|
||
ScrClr();//画面消去
|
||
scr_Restore();
|
||
InsExtErrPut(isInsEject);
|
||
scr_ResultQuit(MessTxt(MT_Break),COLOR_RED);//エラーとQuitボタン
|
||
case CANCEL:
|
||
break;
|
||
default://errors
|
||
if (CheckInsExit())InsExtErrPut(isInsEject);//抜差イベント?
|
||
scr_ResultQuit(MessTxt(MT_Failed),COLOR_RED);//エラーとQuitボタン
|
||
break;
|
||
}
|
||
break;
|
||
case EVNT_PUSH_LEFT_X:// ------------------------------------- LEFT + X
|
||
//バックアップ削除
|
||
scr_DelConf();//実行確認
|
||
WaitUI();
|
||
if (scr_evnt != EVNT_YES)break;
|
||
memsave.Delete();
|
||
#ifdef CSM_FLAG_USE_SD
|
||
if(alive_Sd)exsave.Delete();
|
||
#endif
|
||
break;
|
||
|
||
default:
|
||
failstop();
|
||
break;
|
||
}
|
||
if (((scr_evntbk == EVNT_SEL_WRITE)||(scr_evntbk == EVNT_SEL_READ)) && (retc != CANCEL))
|
||
{
|
||
while(1){
|
||
WaitUI();
|
||
if (scr_evnt == EVNT_INEX)isInsEject = InEx_None;
|
||
if ((scr_evnt==EVNT_QUIT) || (scr_evnt==EVNT_PUSH_B))break;
|
||
}
|
||
}
|
||
}//while()
|
||
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
End of file
|
||
*---------------------------------------------------------------------------*/
|
||
|