git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@181 385bec56-5757-e545-9c3a-d8741f4650f1

This commit is contained in:
mizu 2011-04-06 08:24:23 +00:00
parent 2077c8badb
commit fd584886f5
37 changed files with 523 additions and 1442 deletions

View File

@ -29,7 +29,7 @@ SOURCES[] =
../common/shfnt.cpp
OBJECTS[] =
$`(ObjectFromBinary $(TARGET), ./Imp_list/Public_Key.der)
$`(ObjectFromBinary $(TARGET), ./Imp_list/key/Public_Key.der)
TARGET_PROGRAM = CtrSaveDataMover_imp

View File

@ -0,0 +1,2 @@
-p
-t

View File

@ -0,0 +1,8 @@
#コメント
000000100000000
0000001000
EJF10000237
CJN10001372
000000000000
0
#-- END --

View File

@ -0,0 +1,3 @@
#コメント
CJN10001372
#-- END --

View File

@ -0,0 +1,2 @@
)Z†˘Ŕą6Ť®‰7çĚuÚlëĘ“·&ţżđ‚TďÝçfi¶ ĚŐć®RŮŚś,kţgTěf×gŰ•<1C>P`Q(şŻ^}ňî$0ćXw°ą;xXwk¸V3>z_Ő6J­GcÄĆ0U+gř*^˛Ű{ăĹiЦáńQůT¸pĺFÔ÷9Đɲؕ„‰Ň•CĆ<15>Ú€8wÜKAĹD}{Rl<52>éf=mšŘÎő‹‰˘KÓW9
Ů/8ű' e ö9$íGŰR<C5B0>~[ ×-%„e°x<=xęC4(r®s <>ţ*lďůpŠŠĺŻ óÎąŘ

View File

@ -0,0 +1,3 @@
rem ver1.0.0—p
openssl genpkey -out private_key.der -outform DER -algorithm rsa -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537
openssl rsa -pubout -inform DER -outform DER -in private_key.der -out public_key.der

View File

@ -0,0 +1,7 @@
@echo off
if "%1"=="" goto 1
openssl dgst -sha256 -binary -keyform DER -sign ../key/private_key.der -out csm_sign.dat %1
goto end
:1
openssl dgst -sha256 -binary -keyform DER -sign ../key/private_key.der -out csm_sign.dat csm_list.txt
:end

View File

@ -0,0 +1,5 @@
秘密鍵の扱いは注意
署名作成する必要の無い所には出さない
署名作成時は、配布先で使用するバージョンに入っている
鍵とペアの秘密鍵を使うこと

View File

@ -1,2 +0,0 @@
000000000000000
EJF100002379

View File

@ -0,0 +1,45 @@
本体印刷のシリアル最後尾の四角い枠に入った数字は
digitというものらしい
リスト作成時に入力違いをチェックするのに使えそう
コマンドラインでファイル指定する簡単なチェッカーとか
以下、長谷川さんメール抜粋
----------------
チェックデジットの計算方法は一般的なものらしく、
"モジュラス10 ウェイト3・1M10W31"というものらしいです。
// NULL終端されたシリアルナンバーを受け取る
// NULL文字の場所にチェックデジットを付加して新たにNULL終端する
void AddCheckDigit(char* serial)
{
size_t len = std::strlen(serial);
u8 digit = 0;
bool odd = true;
for(u8 i = len - 1; i > 0 && std::isdigit(serial[i]); i--)
{
if(odd)
{
digit += (serial[i] - '0') * 3;
}
else
{
digit += (serial[i] - '0');
}
odd = !odd;
}
if(digit % 10 != 0)
{
serial[len] = 10 - (digit % 10) + '0';
}
else
{
serial[len] = '0';
}
serial[len + 1] = '\0';
}

View File

@ -1,6 +1,4 @@
<運用イメージ>
目的:許可した本体のみインポート
公開鍵はROMから読み込む
@ -16,6 +14,14 @@ RED)
署名はOpeneelで作成
特に手を加えずそのまま使います
鍵と署名をペアで読ます方法がないので
たとえば、勝手署名を読んだとしても問題ないはず。
特に手を加えずSDルートに置く
リストの書き方
インポート許可シリアルをテキストで羅列
---
aaaaaaaa
bbbbbbbb
----
本体裏シリアル終端のdigit(四角い枠の数字)は省く
digit確認したい場合はリスト作成時にやっとく
ファイルサイズは64Kまで(シリアルのみ記載で、およそ4000台)

View File

@ -1,7 +0,0 @@
@echo off
if "%1"=="" goto 1
openssl dgst -sha256 -binary -keyform DER -sign private_key.der -out csm_sign.dat %1
goto end
:1
openssl dgst -sha256 -binary -keyform DER -sign private_key.der -out csm_sign.dat csm_list.txt
:end

View File

@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAvtK3JukAe7DQB3GRpQk3AZ2vTTbRpP5RkAp5x+bmGhK5Y0VL
F7mefRh/69NYhyF1i0pOBMVRuxl9CFLQc+JM59xqyUK3wL1j7Cncrq+vlndz0b0m
ZGGUN1rHbgyJTWxoNehBu6ZXb636gD4ElCfM1oIZa4TjoKMxdzZtVKFSJr5KvCtM
mhtmAeBZVGyZ8em+fS+II6YdmAf4ezetVwqTQ1i+VrfDFL2EFOYB0JP9pzZf31Pl
g3Nkvc/OCMDV0M2T5ScNFZEiZAhSWf+HF/ReJKAd2jf8vV7CTVvUoYaf6KQ7vGih
WhNjRFSHMzoKE4gTg/Mj6Inca+RzOUgK1S18wwIDAQABAoIBAHVs46n9DgAPoSRD
fdWqIwBKkZqZVk8K9RQHbkNWUljPFugAtyIFZoMidW2gY8TcESJC+lmzNwVEvQ1H
MOFu69ZubAQnmz3vDbNBW3zfvdSA83OoyxxQc83QfhK5gjBzunkZ0IFx7jJaRGFw
SI8HIuUJsCza3Nx4MDNk+chvcUdHFmnqYNv151iLTL/BHCebZoHEFAwlVP91V5Dw
WMGHIO85FJtXJBuaUAX71MKFFXH+WCNKC/MZHNDPB5xd/u6EL1p3R3PRpjtjWRtn
DbdgzrJN/po9VLbAL1AIsL8oV+D2B6FceCE+HpEgkp6qDVoQWFvKnzoS6Zsr+6DR
WixtFWECgYEA+SuA0e/gPE6N40ciPOq9I2eQdVRMQAmqSlckspDiqiID2Uuatvph
3XVMLFspzRJc188OtQQcx407MOSGDlF9dBcIDkx0jCojADM0Vlvl+pNohTTxTTHt
bJRpqoEQY+1gOrNeQqnZTF6uEqXP08xhXpmM/pmfwfwQckGBELSw5LECgYEAxA3G
nS6dols+EFdH/Wm+269SsrP4egysDmWieSpp4vu6Kx0uTdegm/nv7jZ6Oxln1d1I
naCwcS/43J+M9LP5N6zRCd/jCzWWmuyW/eLU3wMStbktRpvfFnWALB74NH7bHALM
zK9JLemff+0XQk5m/PMQWVFQI8E9u9xa3I9wJbMCgYEA4ksgM4onnJ27Py7baXfH
TuA/0k888OvWPK3oJkRvlxRNaou/d27ucrKU+7PPwu9qYpUqRjv150Xc/AqPtXFM
/qHsLxBAyQt7vjLC1augsnIt+syaWgF+H56qWK/esuJjAuzkLqcTMsjKTyVIGpMD
22aZJqFe9k52oU3cac+w2AECgYEAjbE7GzymlsGE4ICEOgUj+FgE17y0V1kzPJB9
1T4vGuo9iY1kesPdgv0nR629t1rMLcfpBGsvOg6muKTjVbOA6ZkP1yglSmOnfj6B
fepjWO46pnW34DElEXFIehrD3gTUzLDFXSVOKU2Qhf9PcQ+C5UuyRCs9VSoDOPOw
A3nzXnsCgYEAwIcRe+tosEo80Lsc/o3pSaTRBgHTHo8xw98X/xZNRD/18ytEMcHp
YplKMsdeBvbhHxCHEzbyvWSbQphFvE7HdqFKN4uZq1z6HzngUeXUH/exTKpQV5eG
W2KWZx8nSJZePxmhUkcSwKb07VYZ8mELxQCeHAM0dANstadD9uX8jN0=
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,11 @@
<インポータのオプション有効化>
cms_inf.txtの名前でファイル作成しSDのルート下に配置
以下の記述でオプションが有効になる
デバグや不具合調査時用、通常はいらない
-t: テストメニュー
   カード上のセーブにテストパターン書き込み&ベリファイ
-p: 本体シリアルを表示

View File

@ -51,16 +51,26 @@ extern "C" {
demo::RenderSystemDrawing s_RenderSystem;
nn::fnd::ExpHeap appHeap;
uptr heapForGx;
void ErrorStop(char *s);
void ErrorPOff(char *s);
const size_t ROMFS_BUFFER_SIZE = 64*1024;//ROMマウント用
const size_t READ_BUFFER_SIZE = 64*1024;
#define SDK_SER_LEN nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN
namespace
{
u8* readBuf;
u8* romfsBuf;
}
nn::Result result;
bool ImportFile(nn::fs::MediaType mediaType, wchar_t* filename)
{
nn::Result result;
//nn::Result result;
nn::fs::FileOutputStream* stream;
result = nn::am::BeginImportProgram(&stream, mediaType);
@ -69,7 +79,7 @@ bool ImportFile(nn::fs::MediaType mediaType, wchar_t* filename)
//NN_LOG("Importing: %ls...", filename);
nn::fs::FileInputStream in(filename);
while(s32 read = in.Read(readBuf, sizeof(readBuf)))
while(s32 read = in.Read(readBuf, READ_BUFFER_SIZE))
{
stream->Write(readBuf, read);
}
@ -79,18 +89,21 @@ bool ImportFile(nn::fs::MediaType mediaType, wchar_t* filename)
}
#define LIST_MAX 4000
u8 s_list[LIST_MAX][nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN+1] NN_ATTRIBUTE_ALIGN(32);//シリアルリスト
u8 sign[256] NN_ATTRIBUTE_ALIGN(32);//署名
//u8 key[1024*10] NN_ATTRIBUTE_ALIGN(32);//署名
#define LIST_LENGTH (LIST_MAX * (nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN+1))
u8 s_list[LIST_MAX][nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN+1];//シリアルリスト
u8 sign[256];//署名
u8 serialNo[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN+1];
//本体シリアル取得
int GettedSerLen;
bool GetSerial(){
nn::cfg::CTR::init::Initialize();
nn::cfg::CTR::system::Initialize();
nn::Result result = nn::cfg::CTR::system::GetSerialNo(serialNo);
serialNo[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN] = 0;
result = nn::cfg::CTR::system::GetSerialNo(serialNo);
nn::cfg::CTR::system::Finalize();
nn::cfg::CTR::init::Finalize();
serialNo[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN] = 0;
GettedSerLen = strlen((char*)serialNo);
return result.IsSuccess();
}
@ -105,7 +118,7 @@ void drawText(u16 x,u16 y,char *s){ shf_DrawText_0( x,y,s);}
nn::hid::PadReader *hpr;
//---------------------------------------------------------------- 入力待ち
//入力待ち
nn::hid::PadStatus padStatus;
u32 WaitKey(u32 mask)
{
@ -117,12 +130,14 @@ u32 WaitKey(u32 mask)
}
}
//終了
void endfunc()
{
appHeap.Free(reinterpret_cast<void*>(readBuf));
appHeap.Free(reinterpret_cast<void*>(romfsBuf));
nn::hid::Finalize();
SharedFontFinalize();
nngxWaitVSync(NN_GX_DISPLAY_BOTH);//SDK2.0以降では不要かも
nngxWaitVSync(NN_GX_DISPLAY_BOTH);//SDK2.0以降では不要
s_RenderSystem.Finalize();
}
@ -132,42 +147,82 @@ bool VeriRsa(u8* src,size_t sz,u8* sig)
nn::crypto::RsaKey key;
//nn::crypto::Initialize();
nn::ps::CTR::Initialize();
nn::Result res = key.InitializePublicKey(PUBLIC_KEY_BEGIN,KEY_LENGTH);
NN_LOG("inipubkey desc= %d\n",res.GetDescription());
if (res.IsSuccess())
result = key.InitializePublicKey(PUBLIC_KEY_BEGIN,KEY_LENGTH);
if (result.IsSuccess())
{
res = nn::ps::CTR::VerifyRsaSha256(src,sz,sig,key);
NN_LOG("verisig desc= %d\n",res.GetDescription());
result = nn::ps::CTR::VerifyRsaSha256(src,sz,sig,key);
}
//nn::crypto::Finalize();
nn::ps::CTR::Finalize();
return res.IsSuccess();
return result.IsSuccess();
}
//エラー
void ErrorCommon(char *s,char *ss)
{
char str[128];
nn::am::FinalizeForLocalImporter();
nn::fs::Unmount("sdmc:");
nn::fs::Unmount("rom:");
NN_LOG(s);
NN_LOG(" result = %d\n",result.GetDescription());
shf_SetScale(0.7,0.7);
setColor(1.0, 0.0, 0.0,1.0);
strcpy(str,"Error: ");
strcat(str,s);
drawText(10,100,str);
drawText(10,140,ss);
}
void ErrorStop(char *s)
{
shf_SetScale(0.7,0.7);
setColor(1.0, 0.0, 0.0,1.0);
drawText(10,100,s);
drawText(10,140,"Push Power Button & Power Off");
ErrorCommon(s,"Push Home Button & end");
s_RenderSystem.SwapBuffers();
WaitKey(0);
}
void ErrorPoff(char *s)
{
ErrorCommon(s,"Push Power Button & Power Off");
drawText(10,160,"Home Button is invalid");
s_RenderSystem.SwapBuffers();
WaitKey(0);
}
//改行後の位置を返す、0=見つからなかった
int CrLf(int n,int max)
{
u8 d;
while(n < max)
{
d = readBuf[n];
if (d==0x0a)return n+1;//LF
if (d==0x0d)//CR
{
if (n == max-1)return 0;//終端
n++;
if (readBuf[n]==0x0a)return n+1;//CR+LF
ErrorStop("list broken");//CRのみは異常、署名時にファイル壊れてた
}
n++;
}
return 0;
}
nn::fs::FileInputStream fi;
//ファイルリード
s32 FileRead(char* fname)
{
s32 size;
nn::Result result = fi.TryInitialize(fname);
result = fi.TryInitialize(fname);
if (result.IsFailure()){//open error
//NN_LOG("desc= %d\n",result.GetDescription());
return 0;
}
result = fi.TryRead(&size,readBuf,sizeof(readBuf));
result = fi.TryRead(&size,readBuf,READ_BUFFER_SIZE);
fi.Finalize();
if (result.IsFailure()){
//NN_LOG("desc= %d\n",result.GetDescription());
@ -181,10 +236,13 @@ char ver[16];
char seri[32];
void nnMain( void )
{
nn::Result result;
//nn::Result result;
bool flg_applove=false;
bool flg_test=false;
int i,j,n;
s32 fsize;
extern bool prohibitHome;// HOME ボタン禁止
nn::os::Initialize();
nn::fs::Initialize();
@ -208,9 +266,6 @@ void nnMain( void )
nn::applet::DisableSleep();//スリープ非対応
const size_t ROMFS_BUFFER_SIZE = 1024 * 64;
static char buffer[ROMFS_BUFFER_SIZE];
// ヒープの確保
appHeap.Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize(), nn::os::ALLOCATE_OPTION_LINEAR);
@ -240,121 +295,136 @@ void nnMain( void )
drawText(250,40,ver);
shf_SetScale(0.7,0.7);
if (result.IsFailure())ErrorStop("Initialize Error");//am 初期化に失敗
if (result.IsFailure())ErrorStop("Initialize");//初期化に失敗
if (READ_BUFFER_SIZE < LIST_LENGTH)ErrorStop("buffer size");//バッファサイズのチェック
//ファイルバッファ
const size_t READ_BUFFER_SIZE = 64*1024;
if (READ_BUFFER_SIZE > appHeap.GetTotalFreeSize())ErrorStop("memory allocate fail");
//カゲマイ上のSDリード速度比較実験で32アラインが良かったので、おまじない
//回数もサイズも少ないので気にする必要ないかも
if (READ_BUFFER_SIZE > appHeap.GetTotalFreeSize())ErrorStop("memory alloc");
readBuf = reinterpret_cast<u8*>(appHeap.Allocate(READ_BUFFER_SIZE,32));
if (ROMFS_BUFFER_SIZE > appHeap.GetTotalFreeSize())ErrorStop("memory alloc");
romfsBuf = reinterpret_cast<u8*>(appHeap.Allocate(ROMFS_BUFFER_SIZE,32));
//シリアルチェック
if( GetSerial() )
{//シリアル取得成功
result = nn::fs::MountSdmc();
if (result.IsSuccess())
//シリアルチェック
if( GetSerial() == false)ErrorStop("Get Serial");//本体シリの取得に失敗
result = nn::fs::MountSdmc();//ダイレクトでマウント..マスタリング時にワーニング
if (result.IsFailure())ErrorStop("Mount SD");
fsize = FileRead(INF_FILE);//設定ファイルがあるか
if((fsize < 1024) && (fsize > 0))//サイズチェック,増えても1Kは超えない
{//不具合調査時に状況にあわせて現場で作成&変更を想定したオプション
//通常は不要なので無しでも動くようしとく
n = 0;
while(n < fsize)
{
int i,j,n;
s32 fsize = FileRead(INF_FILE);//設定ファイルがあるか
if((fsize < 1024) && (fsize > 0))//サイズチェック
{
n = 0;
while(n < fsize)
{
if (readBuf[n] == '-'){
if (n == fsize-1)break;//終端
n++;
switch (readBuf[n]){
case 'p':// -p .. 本体シリアル表示
strcpy(seri,"s/n: ");
strcat(seri,(char *)serialNo);
shf_SetScale(0.5,0.5);
drawText(10,40,(char*)seri);
shf_SetScale(0.7,0.7);
break;
case 't':// -t .. テストメニュー有効
flg_test = true;
break;
}
}
n++;
if (readBuf[n] == '-'){
if (n == fsize-1)break;//終端
n++;
switch (readBuf[n]){
case 'p':// -p .. 本体シリアル表示
strcpy(seri,"s/n: ");
strcat(seri,(char *)serialNo);
shf_SetScale(0.5,0.5);
drawText(10,40,(char*)seri);
shf_SetScale(0.7,0.7);
break;
case 't':// -t .. テストメニュー有効
flg_test = true;
break;
}
}
n++;
}
}
fsize = FileRead(SIGN_FILE);//署名リード
if(fsize == 256)//サイズチェック
//シリアル表示(オプション)後にチェック
//デバッガ=15,実機=11
if (GettedSerLen < 11)ErrorStop("invalid Serial");
fsize = FileRead(SIGN_FILE);//署名リード
if(fsize != 256)ErrorStop("sign file");//鍵のbit長は2046固定
memcpy(sign,readBuf,256);//readBuf -> sign
fsize = FileRead(LIST_FILE);//リストリード
if((fsize > LIST_LENGTH ) || (fsize == 0))ErrorStop("list file");
nn::fs::Unmount("sdmc:"); //検証後はSDから読まないでメモリバッファ上のデータを使う: 差替え対策
if (VeriRsa(readBuf,fsize,sign) == false)ErrorStop("sign verify");
//署名検証OK
int list_ct = 0;
n=0;
while(n < fsize)//リスト作成
{
if (readBuf[n] == '#')//コメント行を無視、ワイド文字非対応
{
i = CrLf(n,fsize);//コメントの次行
if (i == 0)break;//ファイル終わりまで改行が見つからない
}else
{
//改行さがし
if ((fsize-n) > (SDK_SER_LEN+2))
{//シリアルは改行つける
i = CrLf(n,n+SDK_SER_LEN+2);
if (i == 0)ErrorStop("list broken");//改行が見つからない
}else{
i = CrLf(n,fsize);
if (i ==0)i = fsize;//改行以外でファイル終
}
if ((i-n) > GettedSerLen)//シリアルをリスト化
{
memcpy(sign,readBuf,256);//readBuf -> sign
j = 0;
while(n<i)
{
fsize = FileRead(LIST_FILE);//リストリード
if((fsize < LIST_MAX * (nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN+1)) && (fsize > 0))//サイズチェック
{
if (VeriRsa(readBuf,fsize,sign))
{//署名検証OK
int list_ct = 0;
n=0;
u8 d;
while(n < fsize)//リスト作成
{
if ((fsize-n) > nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN)j = nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN;
else j = fsize-n;
for (i=0;i<j;i++)
{
d = readBuf[n];
n++;
if ((d==0x0d)||(d==0x0a)) //改行コード
{
if (readBuf[n]==0x0a)n++;//CR+LF,LF+LF
else ErrorStop("list broken");//CRのみは異常、署名時にファイル壊れてた
break;
}
s_list[list_ct][i] = d;
}
if (i>0){
s_list[list_ct][i] = 0;//終端
list_ct++;
if (list_ct>=LIST_MAX)
{//上限オーバー: おそらくリスト作成ミス
ErrorStop("List too Long");
}
}
}
//本体シリアルがリストにあるかチェック
n =0;
int len = strlen((char*)serialNo);
if (len > nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN)len = nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN;
while(n<list_ct){
for(i=0;i<len;i++)
{
if (serialNo[i] != s_list[n][i])break;
}
if (i == len)
{
flg_applove = true;
break;
}
}
}//Verify
}//LIST_FILE
}//PUBK_FILE
}//SIGN_FILE
nn::fs::Unmount("sdmc:");
}//MountSdmc
}//GetSerial
if ((readBuf[n] == 0x0d) || (readBuf[n] == 0x0a))break;
s_list[list_ct][j] = readBuf[n];
j++;n++;
}
s_list[list_ct][j] = 0;//終端
list_ct++;
if (list_ct>=LIST_MAX)ErrorStop("List too Long");
}
}
if ((fsize-i) < GettedSerLen)break;//ファイル終
n=i;//ポインタを改行の次へ
}
NN_LOG("result = %d\n",result.GetDescription());
//プログラムミス、コードバグ対策
//値が小さいと判定が緩くなるが、動作確認時にスルーしそうなので
//念の為チェック
if (GettedSerLen < 11)ErrorStop("invalid Serial");
//本体シリアルがリストにあるかチェック
n =0;
while(n<list_ct)
{
if (GettedSerLen == strlen((char*)s_list[n]))
{
for(i=0;i<GettedSerLen;i++)
{
if (serialNo[i] != s_list[n][i])break;
}
if (i == GettedSerLen)
{
flg_applove = true;
break;
}
}
n++;
}
u32 mask = 0;
if (flg_applove)//インポート許可本体
{
//メニュー表示
if (flg_applove){//インポート許可本体
drawText(80,100,"Push X : Import");
drawText(80,140,"Push Y : Delete");
mask |= nn::hid::BUTTON_X | nn::hid::BUTTON_Y;
}
//1stNup以降は本体設定で消せるので、そっちの方がよさげ
//将来的にdeleteは省いていいかも
if (flg_test)//テストメニュー
{
@ -363,7 +433,7 @@ void nnMain( void )
}
s_RenderSystem.SwapBuffers();
if (mask == 0)ErrorStop("Serial number Check Failed");
if (mask == 0)ErrorStop("Serial Check");//実行できるメニューないときトラップ
u32 trg = WaitKey(mask);
if (trg & nn::hid::BUTTON_R){
@ -371,47 +441,40 @@ void nnMain( void )
TestMain();//テストデータへ
}
nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE);
nn::fs::MountRom(16, 16, romfsBuf, ROMFS_BUFFER_SIZE);
shf_SetScale(0.8,0.8);
// CIA のプログラム ID を取得する。
nn::am::ProgramInfo programInfo;
if (nn::am::GetProgramInfoFromCia(&programInfo, ROMFS_IMPORTEE_PATH).IsFailure())
{
s_RenderSystem.Clear();
setColor(1.0, 0.0, 0.0,1.0);
drawText(10,50,"cia infomation Error");
} else
{
s_RenderSystem.Clear();
if(trg & nn::hid::BUTTON_X) drawText(10,120,"Importing");
else drawText(10,120,"Delete");
s_RenderSystem.SwapBuffers();
if (nn::am::GetProgramInfoFromCia(&programInfo, ROMFS_IMPORTEE_PATH).IsFailure())ErrorStop("cia infomation");
// 既に存在するものをインポートするとエラーが返ってくるので、あらかじめ消しておく。
nn::am::DeleteProgram(nn::fs::MEDIA_TYPE_NAND, programInfo.id);
// タイトル鍵が違うケースに対応するために、チケットも消しておく。
nn::am::DeleteTicket(programInfo.id);
if(trg & nn::hid::BUTTON_X)
{
// CIA をインポート
if (ImportFile(nn::fs::MEDIA_TYPE_NAND, ROMFS_IMPORTEE_PATH)==false)
{
s_RenderSystem.Clear();
setColor(1.0, 0.0, 0.0,1.0);
drawText(10,50,"Impoprt fail");
s_RenderSystem.SwapBuffers();
}
}
s_RenderSystem.Clear();
drawText(10,50,"Complate");
}
drawText(10,120,"Push Power Button & Power Off");
// Imprting/Delete 表示
s_RenderSystem.Clear();
if(trg & nn::hid::BUTTON_X) drawText(10,120,"Importing");
else drawText(10,120,"Delete");
s_RenderSystem.SwapBuffers();
// HOME ボタン禁止
//Homeで中断するとアイコンが更新されない、電源OFF画面からHomeは問題なし
prohibitHome = true;
// 既に存在するものをインポートするとエラーが返ってくるので、あらかじめ消しておく。
nn::am::DeleteProgram(nn::fs::MEDIA_TYPE_NAND, programInfo.id);
// タイトル鍵が違うケースに対応するために、チケットも消しておく。
nn::am::DeleteTicket(programInfo.id);
if(trg & nn::hid::BUTTON_X)
{
// CIA をインポート
if (ImportFile(nn::fs::MEDIA_TYPE_NAND, ROMFS_IMPORTEE_PATH)==false)ErrorPoff("Import");
}
nn::fs::Unmount("rom:");
s_RenderSystem.Clear();
drawText(10,50,"Complate");
drawText(10,120,"Push Power Button & Power Off");
drawText(10,140,"Home Button is invalid");
s_RenderSystem.SwapBuffers();
WaitKey(0);
}

View File

@ -33,11 +33,12 @@ SOURCES[] =
./source/savefile/savefile.cpp
./source/screen/screen.cpp
./source/gui/gui.cpp
./source/gui/shfnt.cpp
../common/shfnt.cpp
../common/sleep.cpp
../common/common.cpp
#LIBS += lib_demo libnn_am
#LIBS += libnn_ps
TARGET_PROGRAM = CtrSaveDataMover
@ -56,7 +57,7 @@ CTR_BANNER_SPEC = banner.bsf
#Cia バージョン:マスタリング毎に更新すること
#メジャーはrsfで指定(Remasterversion)
MAKECIAFLAGS = -minor 0 -micro 6
MAKECIAFLAGS = -minor 0 -micro 8
include $(ROOT_OMAKE)/modulerules

View File

@ -5,6 +5,7 @@ BasicInfo:
# BackupMemoryType: 128KB
BackupMemoryType: None
Logo : Nintendo
# CompanyCode: "00"
ProductCode : "CTR-N-22NA"
TitleInfo:

View File

@ -18,7 +18,7 @@
#include <nn/hid.h>
#include "demo.h"
#include "gui.h"
#include "shfnt.h"
#include "../../../common/shfnt.h"
//----------- types etc ---------------
typedef struct{
@ -158,18 +158,35 @@ static cmMemo s_Memo[MEMO_MAX];
static demo::RenderSystemDrawing s_RenderSystem;
void ColorFromCode(eColor c,tCol *col);
//(2011.3.10)本体内蔵フォントに変更
//作成時のフォントで画面&タッチ位置を調整
int pos2tpx(int x)
{
if (x > 80 )
{
if (x < 160) return -10;
else if (x <230) return -30;
else return -50;
}
return 0;
}
//PANEL上の座標かチェック
bool onPanel(u16 x,u16 y,cmPanel *p)
{
if (x <= p->pos.x)return false;
if (x >= (p->pos.x + p->size.x))return false;
if (y <= p->pos.y)return false;
int px = pos2tpx(p->pos.x);
int pw = pos2tpx(p->size.x);
int py = 20;
if (x <= (p->pos.x + px))return false;
if (x >= (p->pos.x + p->size.x + pw))return false;
if (y <= p->pos.y + py )return false;
if (y >= (p->pos.y + p->size.y))return false;
return true;
}
//(2011.3.10)本体内蔵フォントに変更
//作成時のフォントで画面位置を調整
#define setText(x,y,s) shf_DrawText_0(x,y,s)
#define setSize(sz) shf_SetSize(sz)
@ -412,7 +429,7 @@ void thUpdate(nn::os::LightEvent* pEvnt)
if (s_Button.enable && (s_Button.callback !=0))//PADボタン
{
padReader.ReadLatest(&padStatus);
value = padStatus.trigger & s_Button.mask;
value = (padStatus.trigger & s_Button.mask) | ((padStatus.hold & s_Button.mask) << 16);
if (value)(*s_Button.callback)(value);
}
@ -423,6 +440,7 @@ void thUpdate(nn::os::LightEvent* pEvnt)
tpOld.y = tpStatus.y;
if (tpStatus.touch)
{
NN_LOG("x =%d , y=%d\n",tpStatus.x,tpStatus.y);
for (i=0;i<PANEL_MAX;i++)//PANEL枠内か
{
if (s_Panel[i].enable && (s_Panel[i].callback !=0))

View File

@ -26,9 +26,8 @@ typedef struct
char* caption;
u16 x,y;
u16 width,height;
u8 id;
u8 scr;//0:up,else down screen
u8 padding[2];
u16 id;
u16 scr;//0:up,else down screen
}tPanel;
typedef enum {

View File

@ -1,350 +0,0 @@

#include <nn.h>
#include <nn/fs.h>
#include <nn/font.h>
#include <nn/math.h>
#include <nn/pl.h>
#include <nn/util.h>
#include "demo.h"
const char s_ShaderBinaryFilePath[] = "rom:/nnfont_RectDrawerShader.shbin";
extern nn::fnd::ExpHeap appHeap;
//---------------------------------------------------------------------------
//! @brief シェーダの初期化を行います。
//!
//! @param[in,out] pResource 描画用リソースを管理するオブジェクトへのポインタ。
//---------------------------------------------------------------------------
void*
InitShaders(nn::font::RectDrawer* pDrawer)
{
const size_t ROMFS_BUFFER_SIZE = 1024 * 64;
static char buffer[ROMFS_BUFFER_SIZE];
nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE);
nn::fs::FileReader shaderReader(s_ShaderBinaryFilePath);
const u32 fileSize = (u32)shaderReader.GetSize();
void* shaderBinary = appHeap.Allocate(fileSize);
NN_NULL_ASSERT(shaderBinary);
shaderReader.Read(shaderBinary, fileSize);
const u32 vtxBufCmdBufSize =
nn::font::RectDrawer::GetVertexBufferCommandBufferSize(shaderBinary, fileSize);
void *const vtxBufCmdBuf = appHeap.Allocate(vtxBufCmdBufSize);
NN_NULL_ASSERT(vtxBufCmdBuf);
pDrawer->Initialize(vtxBufCmdBuf, shaderBinary, fileSize);
appHeap.Free(shaderBinary);
shaderReader.Finalize();
nn::fs::Unmount("rom:");
return vtxBufCmdBuf;
}
/*---------------------------------------------------------------------------*
@brief
*---------------------------------------------------------------------------*/
void
InitGX()
{
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
}
//---------------------------------------------------------------------------
//! @brief 描画の初期設定を行います。
//!
//! @param[in] width 画面の幅。
//! @param[in] height 画面の高さ。
//---------------------------------------------------------------------------
void
InitDraw(
int width,
int height
)
{
// カラーバッファ情報
// LCDの向きに合わせて、幅と高さを入れ替えています。
const nn::font::ColorBufferInfo colBufInfo = { width, height, PICA_DATA_DEPTH24_STENCIL8_EXT };
const u32 screenSettingCommands[] =
{
// ビューポートの設定
NN_FONT_CMD_SET_VIEWPORT( 0, 0, colBufInfo.width, colBufInfo.height ),
// シザー処理を無効
NN_FONT_CMD_SET_DISABLE_SCISSOR( colBufInfo ),
// wバッファの無効化
// デプスレンジの設定
// ポリゴンオフセットの無効化
NN_FONT_CMD_SET_WBUFFER_DEPTHRANGE_POLYGONOFFSET(
0.0f, // wScale : 0.0 でWバッファが無効
0.0f, // depth range near
1.0f, // depth range far
0, // polygon offset units : 0.0 で ポリゴンオフセットが無効
colBufInfo),
};
nngxAdd3DCommand(screenSettingCommands, sizeof(screenSettingCommands), true);
static const u32 s_InitCommands[] =
{
// カリングを無効
NN_FONT_CMD_SET_CULL_FACE( NN_FONT_CMD_CULL_FACE_DISABLE ),
// ステンシルテストを無効
NN_FONT_CMD_SET_DISABLE_STENCIL_TEST(),
// デプステストを無効
// カラーバッファの全ての成分を書き込み可
NN_FONT_CMD_SET_DEPTH_FUNC_COLOR_MASK(
false, // isDepthTestEnabled
0, // depthFunc
true, // depthMask
true, // red
true, // green
true, // blue
true), // alpha
// アーリーデプステストを無効
NN_FONT_CMD_SET_ENABLE_EARLY_DEPTH_TEST( false ),
// フレームバッファアクセス制御
NN_FONT_CMD_SET_FBACCESS(
true, // colorRead
true, // colorWrite
false, // depthRead
false, // depthWrite
false, // stencilRead
false), // stencilWrite
};
nngxAdd3DCommand(s_InitCommands, sizeof(s_InitCommands), true);
}
//---------------------------------------------------------------------------
//! @brief ResFontを構築します。
//!
//! @param[out] pFont 構築するフォントへのポインタ。
//! @param[in] filePath ロードするフォントリソースファイル名。
//!
//! @return ResFont構築の成否を返します。
//---------------------------------------------------------------------------
bool
InitFont(
nn::font::ResFont* pFont,
void* pBuffer
)
{
// フォントリソースをセットします
bool bSuccess = pFont->SetResource(pBuffer);
// 描画用バッファを設定します。
const u32 drawBufferSize = nn::font::ResFont::GetDrawBufferSize(pBuffer);
void* drawBuffer = appHeap.Allocate(drawBufferSize, 4);
pFont->SetDrawBuffer(drawBuffer);
NN_NULL_ASSERT(drawBuffer);
return bSuccess;
}
//---------------------------------------------------------------------------
//! @brief ResFontを破棄します。
//!
//! @param[in] pFont 破棄するフォントへのポインタ。
//---------------------------------------------------------------------------
void
CleanupFont(nn::font::ResFont* pFont)
{
// 描画用バッファの無効化
// 描画用バッファがセットされているなら 構築時に SetDrawBuffer に渡したバッファへの
// ポインタが返ってきます。
void *const drawBuffer = pFont->SetDrawBuffer(NULL);
if (drawBuffer != NULL)
{
appHeap.Free(drawBuffer);
}
}
//---------------------------------------------------------------------------
//! @brief 表示文字列用バッファを確保します。
//!
//! @param[in] charMax 表示する文字列の最大文字数。
//!
//! @return 確保した表示文字列用バッファへのポインタを返します。
//---------------------------------------------------------------------------
nn::font::DispStringBuffer*
AllocDispStringBuffer(int charMax)
{
const u32 DrawBufferSize = nn::font::CharWriter::GetDispStringBufferSize(charMax);
void *const bufMem = appHeap.Allocate(DrawBufferSize);
NN_NULL_ASSERT(bufMem);
return nn::font::CharWriter::InitDispStringBuffer(bufMem, charMax);
}
//---------------------------------------------------------------------------
//! @brief 文字列表示用にモデルビュー行列と射影行列を設定します。
//!
//! @param[in] pDrawer RectDrawerオブジェクトへのポインタ。
//! @param[in] width 画面の幅。
//! @param[in] height 画面の高さ。
//---------------------------------------------------------------------------
void
SetupTextCamera(
nn::font::RectDrawer* pDrawer,
int width,
int height
)
{
// 射影行列を正射影に設定
{
// 左上原点とし、Y軸とZ軸の向きが逆になるように設定します。
nn::math::MTX44 proj;
f32 znear = 0.0f;
f32 zfar = -1.0f;
f32 t = 0;
f32 b = static_cast<f32>(width);
f32 l = 0;
f32 r = static_cast<f32>(height);
nn::math::MTX44OrthoPivot(&proj, l, r, b, t, znear, zfar, nn::math::PIVOT_UPSIDE_TO_TOP);
pDrawer->SetProjectionMtx(proj);
}
// モデルビュー行列を単位行列に設定
{
nn::math::MTX34 mv;
nn::math::MTX34Identity(&mv);
pDrawer->SetViewMtxForText(mv);
}
}
nn::font::RectDrawer drawer;
void *drawerBuf;
nn::font::DispStringBuffer *pDrawStringBuf0;
nn::font::DispStringBuffer *pDrawStringBuf1;
nn::font::ResFont font;
nn::font::TextWriter writer;
//---------------------------------------------------------------------------
//! @brief ASCII文字列を描画します。
//---------------------------------------------------------------------------
void
shf_DrawText_0( u16 x,u16 y,char *s)
{
writer.SetCursor(x, y);
writer.StartPrint();
(void)writer.Print(s);
writer.EndPrint();
drawer.BuildTextCommand(&writer);
drawer.DrawBegin();
SetupTextCamera(&drawer, NN_GX_DISPLAY0_WIDTH, NN_GX_DISPLAY0_HEIGHT);
writer.UseCommandBuffer();
drawer.DrawEnd();
}
void shf_SetSize(f32 sz)
{
writer.SetScale(sz/14,sz/20);
}
void shf_SetScale(f32 h,f32 v)
{
writer.SetScale(h,v);
}
void shf_SetFontSize(f32 sz)
{
writer.SetFontSize(sz);
}
f32 shf_GetFontWidth()
{
return writer.GetFontWidth();
}
f32 shf_GetFontHeight()
{
return writer.GetFontHeight();
}
void shf_SetColor(f32 r,f32 g,f32 b,f32 a)
{
writer.SetTextColor(nn::util::FloatColor(r,g,b,a));
}
//初期化
//AppHeap確保、RenderSystem.Inititの後に呼ぶ
void SharedFontInit()
{
InitGX();
// 共有フォントの初期化
NN_UTIL_PANIC_IF_FAILED(nn::pl::InitializeSharedFont());
// 共有フォントのロードが完了するまで待機
while (nn::pl::GetSharedFontLoadState() != nn::pl::SHARED_FONT_LOAD_STATE_LOADED)
{
// 共有フォントのロードに失敗していないか確認
if (nn::pl::GetSharedFontLoadState() == nn::pl::SHARED_FONT_LOAD_STATE_FAILED)
{
NN_TPANIC_("failed to load shared font!\n");
}
nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(1));
}
// 共有フォントの種類を取得
//nn::pl::SharedFontType sharedFontType = nn::pl::GetSharedFontType();
// 共有フォントデータのアドレスを取得
void* pFontBuffer = nn::pl::GetSharedFontAddress();
InitFont(&font, pFontBuffer);
// 描画リソースの構築
drawerBuf = InitShaders(&drawer);
// 描画文字列用バッファの確保
pDrawStringBuf0 = AllocDispStringBuffer(1024);
pDrawStringBuf1 = AllocDispStringBuffer(512);
writer.SetDispStringBuffer(pDrawStringBuf0);
writer.SetFont(&font);
SetupTextCamera(&drawer, NN_GX_DISPLAY0_WIDTH, NN_GX_DISPLAY0_HEIGHT);
}
void SharedFontFinalize()
{
drawer.Finalize();
// 描画リソースの破棄
appHeap.Free(drawerBuf);
// フォントの破棄
CleanupFont(&font);
// 描画文字列用バッファの解放
appHeap.Free(pDrawStringBuf1);
appHeap.Free(pDrawStringBuf0);
}
/*---------------------------------------------------------------------------*
End of file
*---------------------------------------------------------------------------*/

View File

@ -1,29 +0,0 @@
/*---------------------------------------------------------------------------*
Project: Horizon
File: irp.h
Copyright (C)2009 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.
$Rev$
*---------------------------------------------------------------------------*/
#ifndef GUI_SHFNT_H_
#define GUI_SHFNT_H_
void SharedFontInit();
void SharedFontFinalize();
void shf_DrawText_0(u16 x,u16 y,char* s);
void shf_SetSize(f32 sz);
void shf_SetScale(f32 h,f32 v);
void shf_SetColor(f32 r,f32 g,f32 b,f32 a);
void shf_SetFontSize(f32 sz);
f32 shf_GetFontWidth();
f32 shf_GetFontHeight();
#endif

View File

@ -22,6 +22,7 @@
#include <nn/ndm.h>
#include <nn/fs/ctr/mpcore/fs_FileSystemBasePrivate.h>
#include <nn/fs/fs_Parameters.h>
#include <nn/fs/fs_ApiProcessInfo.h>
#include "./savefile/savefile.h"
#include "./savefile/savedata.h"
#ifdef BKUP_NOTMEM

View File

@ -82,31 +82,63 @@ void ScrClr()
gui.Draw();
}
nn::os::Tick holdTck;
u32 holdVal;
//---------------------------------イベントコールバック
//----------------PADボタン
void pushButton(u32 button)
void pushButton(u32 sts)
{
//NN_LOG("button > %4x\n",button);
if (button & nn::hid::BUTTON_LEFT)//“¯Žž‰Ÿ‚µ
u32 trg = sts & 0x0ffff;
u32 hld = sts >> 16;
/*
if (holdVal)//同時押し猶予期間
{
if (button & nn::hid::BUTTON_X)
if (nn::fnd::TimeSpan::FromMilliSeconds(100) > (nn::os::Tick::GetSystemCurrent()-holdTck)){
holdVal |= trg;
if (holdVal == nn::hid::BUTTON_LEFT | holdVal & nn::hid::BUTTON_X ){
holdVal = 0;
scr_evnt = EVNT_PUSH_LEFT_X;
}
}else holdVal = 0;
}else if( (holdVal = trg & (nn::hid::BUTTON_LEFT | nn::hid::BUTTON_X ))>0)
{//一定時間どっちかのボタン押し維持
holdTck = nn::os::Tick::GetSystemCurrent();
}
#ifdef DEBUG_ENABLE
else if (button & nn::hid::BUTTON_DOWN)//“¯Žž‰Ÿ‚µ
*/
if( holdVal )//押し続け判定
{
if (button & nn::hid::BUTTON_Y)
if (button & nn::hid::BUTTON_X)
if (hld != holdVal)
{
holdVal = 0;
}else
if (nn::fnd::TimeSpan::FromMilliSeconds(4000) < (nn::os::Tick::GetSystemCurrent()-holdTck))
{
holdVal = 0;
scr_evnt = EVNT_PUSH_LEFT_X;
}
}else if (hld == ( nn::hid::BUTTON_LEFT | nn::hid::BUTTON_X ))
{
holdVal = hld;
holdTck = nn::os::Tick::GetSystemCurrent();
}
#ifdef DEBUG_ENABLE
else if (hld & nn::hid::BUTTON_DOWN)//同時押し
{
if (hld & nn::hid::BUTTON_Y)
if (hld & nn::hid::BUTTON_X)
scr_evnt = EVNT_PUSH_DOWN_Y;
}
else if (button & nn::hid::BUTTON_R)scr_evnt = EVNT_PUSH_R;
else if (button & nn::hid::BUTTON_L)scr_evnt = EVNT_PUSH_L;
else if (trg & nn::hid::BUTTON_R)scr_evnt = EVNT_PUSH_R;
else if (trg & nn::hid::BUTTON_L)scr_evnt = EVNT_PUSH_L;
#endif
#ifdef ENABLE_CRUSH
else if (button & nn::hid::BUTTON_Y)scr_evnt = EVNT_PUSH_Y;
else if (trg & nn::hid::BUTTON_Y)scr_evnt = EVNT_PUSH_Y;
#endif
else if (button & nn::hid::BUTTON_B)scr_evnt = EVNT_PUSH_B;
else if (trg & nn::hid::BUTTON_B)scr_evnt = EVNT_PUSH_B;
}
//-----------------パネルをタッチ
@ -276,9 +308,10 @@ char scr_debug[32];
bool ScrInitialize(uptr heap,u32 size)
{
scr_evnt = EVNT_NONE;
if (gui.Initialize(heap,size,&stopEvnt)==false)return false;
holdVal = 0;
holdTck = nn::fnd::TimeSpan(0);
if (gui.Initialize(heap,size,&stopEvnt)==false)return false;
gui.ButtonCallback((uptr)pushButton);
//コンポーネント登録
@ -486,6 +519,7 @@ void scr_TopMenu(bool formatted,bool inserted,bool exfm,bool bkupins,int err)
scr_evnt = EVNT_NONE;
u32 mask = 0;
mask |= (nn::hid::BUTTON_LEFT | nn::hid::BUTTON_X);//LEFT+X = Delete 有効
#ifdef DEBUG_ENABLE
mask | = ( nn::hid::BUTTON_DOWN | nn::hid::BUTTON_Y |nn::hid::BUTTON_X|nn::hid::BUTTON_L | nn::hid::BUTTON_R);
#endif

View File

@ -1,791 +0,0 @@
#include <nn.h>
#include "screen.h"
#include <stdio.h>
#include "../my_defs.h"
#include "../common/ver.h"
//todo: 初期仕様の名残の"SD"が関数や変数名
// に残ってるので気になるなら掃除
Gui gui;
u8 scr_evnt;
enum{
//PANEL_END,
PANEL_ERROR,
PANEL_SUCCESS,
PANEL_TOPMENU,
PANEL_TITLE,
PANEL_QUIT,
PANEL_READ,
PANEL_WRITE,
PANEL_YES,
PANEL_NO,
PANEL_CONFIRM,
PANEL_DELCONF,
PANEL_MENU,
PANEL_BKUP,
PANEL_INSEXIT,
PANEL_DBGLOG
};
enum{
MESSAGE_VERSION,
MESSAGE_PRODUCT,
MESSAGE_PRODUCT2,
MESSAGE_ERROR_TITLE,
MESSAGE_ERROR_INFO,
MESSAGE_ERROR_INFO2,
MESSAGE_ERROR_INFO3,
MESSAGE_SUCCESS_TITLE,
MESSAGE_SUCCESS_INFO,
MESSAGE_SUCCESS_INFO2,
MESSAGE_CONFIRM_TITLE,
MESSAGE_CONFIRM_MSG,
MESSAGE_DELCONF_TITLE,
MESSAGE_DELCONF_MSG,
MESSAGE_DELCONF_MSG2,
MESSAGE_DELCONF_MSG3,
//MESSAGE_TOPMENU_HELP_TITLE,
MESSAGE_TOPMENU_HELP_READ,
MESSAGE_TOPMENU_HELP_WRITE,
MESSAGE_TOPMENU_HELP_END,
MESSAGE_TOPMENU_HELP_OPERATE,
MESSAGE_TITLE,
MESSAGE_MENU_READ,
MESSAGE_MENU_WRITE,
//MESSAGE_MENU_END,
MESSAGE_MENU_OPERATE,
MESSAGE_MENU_CAUTION,
MESSAGE_MENU_ERROR,
MESSAGE_MENU_DEBUG,
MESSAGE_INSEXT_1,
MESSAGE_INSEXT_2,
MESSAGE_INSEXT_3,
MESSAGE_OPERATE,
MESSAGE_RESULT,
MESSAGE_QUIT_OPERATE,
MESSAGE_CONF,
MESSAGE_COUNT,
MESSAGE_COUNT2,
MESSAGE_STATUS
};
enum{
MEMO_DBGLOG
};
//画面消去、コンポーネントをディセーブル
void ScrClr()
{
gui.ButtonMask(0);
gui.DisableAll();
gui.Draw();
}
//---------------------------------イベントコールバック
//----------------PADボタン
void pushButton(u32 button)
{
//NN_LOG("button > %4x\n",button);
if (button & nn::hid::BUTTON_LEFT)//同時押し
{
if (button & nn::hid::BUTTON_X)
scr_evnt = EVNT_PUSH_LEFT_X;
}
#ifdef DEBUG_ENABLE
else if (button & nn::hid::BUTTON_DOWN)//同時押し
{
if (button & nn::hid::BUTTON_Y)
if (button & nn::hid::BUTTON_X)
scr_evnt = EVNT_PUSH_DOWN_Y;
}
else if (button & nn::hid::BUTTON_R)scr_evnt = EVNT_PUSH_R;
else if (button & nn::hid::BUTTON_L)scr_evnt = EVNT_PUSH_L;
#endif
#ifdef ENABLE_CRUSH
else if (button & nn::hid::BUTTON_Y)scr_evnt = EVNT_PUSH_Y;
#endif
else if (button & nn::hid::BUTTON_B)scr_evnt = EVNT_PUSH_B;
}
//-----------------パネルをタッチ
// ---- Top Menu :READ
void touchRead(u32 pos NN_IS_UNUSED_VAR)
{
scr_evnt = EVNT_SEL_READ;
}
// ---- Top Menu :WRITE
void touchWrite(u32 pos NN_IS_UNUSED_VAR)
{
scr_evnt = EVNT_SEL_WRITE;
}
//---- Top Menu :END
//void touchEnd(u32 pos NN_IS_UNUSED_VAR)
//{
// scr_evnt = EVNT_SEL_END;
//}
//---- YES
void touchYes(u32 pos NN_IS_UNUSED_VAR)
{
scr_evnt = EVNT_YES;
}
//---- NO
void touchNo(u32 pos NN_IS_UNUSED_VAR)
{
scr_evnt = EVNT_NO;
}
void touchQuit(u32 pos NN_IS_UNUSED_VAR)
{
scr_evnt = EVNT_QUIT;
}
#define NULL_PTR 0
#define NULL_STR 0
#define SCREEN_UPPER 0
#define SCREEN_LOWER 1
#define LOC_CONF_X 60
#define LOC_CONF_Y 20
#define LOC_CONF_W (400 - LOC_CONF_X*2)
#define LOC_CONF_H 70
#define LOC_LOG_X 50
#define LOC_LOG_W (400 - LOC_LOG_X*2)
#define LOC_LOG_Y (LOC_CONF_Y + LOC_CONF_H + 10)
#define LOC_LOG_H (240 - LOC_LOG_Y - 10)
#define LOG_MAX 10
// -------------------------------------------------- コンポーネント設計
//下画面
//Top Menu
const tPanel panel_Read = {(uptr)touchRead,"Backup",80,30,160,60,PANEL_READ,SCREEN_LOWER};
const tPanel panel_Write = {(uptr)touchWrite,"Restore",80,150,160,60,PANEL_WRITE,SCREEN_LOWER};
//const tPanel panel_End = {(uptr)touchEnd,"End",80,180,160,30,PANEL_END,SCREEN_LOWER};
//Yes No
const tPanel panel_Yes = {(uptr)touchYes,"YES",40,60,80,120,PANEL_YES,SCREEN_LOWER};
const tPanel panel_No = {(uptr)touchNo,"NO",200,60,80,120,PANEL_NO,SCREEN_LOWER};
//Quit
const tPanel panel_Quit = {(uptr)touchQuit,"Quit",80,60,160,120,PANEL_QUIT,SCREEN_LOWER};
//上画面
//デバグ用
//エラー表示
const tPanel panel_Error = {NULL_PTR,NULL_STR,LOC_CONF_X,LOC_CONF_Y,LOC_CONF_W,LOC_CONF_H,PANEL_ERROR,SCREEN_UPPER};
const tMessage mess_Title_Err = {"title",10,10,COLOR_RED,8,MESSAGE_ERROR_TITLE,PANEL_ERROR};
const tMessage mess_Info_Err = {"info",10,22,COLOR_RED,8,MESSAGE_ERROR_INFO,PANEL_ERROR};
const tMessage mess_Info2_Err = {"info2",10,40,COLOR_RED,8,MESSAGE_ERROR_INFO2,PANEL_ERROR};
const tMessage mess_Info3_Err = {"info3",10,50,COLOR_RED,8,MESSAGE_ERROR_INFO3,PANEL_ERROR};
//成功
const tPanel panel_Success = {NULL_PTR,NULL_STR,LOC_CONF_X,LOC_CONF_Y,LOC_CONF_W,LOC_CONF_H,PANEL_SUCCESS,SCREEN_UPPER};
const tMessage mess_Title_Suc = {"title",10,10,COLOR_GREEN,8,MESSAGE_SUCCESS_TITLE,PANEL_SUCCESS};
const tMessage mess_Info_Suc = {"info",10,40,COLOR_WHITE,8,MESSAGE_SUCCESS_INFO,PANEL_SUCCESS};
const tMessage mess_Info2_Suc = {"info2",10,50,COLOR_WHITE,8,MESSAGE_SUCCESS_INFO2,PANEL_SUCCESS};
//実行確認
const tPanel panel_Confirm = {NULL_PTR,NULL_STR,LOC_CONF_X,LOC_CONF_Y,LOC_CONF_W,LOC_CONF_H,PANEL_CONFIRM,SCREEN_UPPER};
const tMessage mess_conf_Title = {"title",10,10,COLOR_YELLO,8,MESSAGE_CONFIRM_TITLE,PANEL_CONFIRM};
const tMessage mess_conf_Msg = {"Do you execute?",10,40,COLOR_WHITE,8,MESSAGE_CONFIRM_MSG,PANEL_CONFIRM};
//トップメニュー
const tPanel panel_topmenu_help = {NULL_PTR,NULL_STR,LOC_CONF_X,LOC_CONF_Y,LOC_CONF_W,LOC_CONF_H,PANEL_TOPMENU,SCREEN_UPPER};
const tMessage mess_topmenu_help_read = {"[Backup] Card -> bkup",10,4,COLOR_WHITE,8,MESSAGE_TOPMENU_HELP_READ,PANEL_TOPMENU};
const tMessage mess_topmenu_help_notread = {"[Backup] is Invalid",10,4,COLOR_RED,8,MESSAGE_TOPMENU_HELP_READ,PANEL_TOPMENU};
const tMessage mess_topmenu_help_write = {"[Restore] bkup -> Card",10,16,COLOR_WHITE,8,MESSAGE_TOPMENU_HELP_WRITE,PANEL_TOPMENU};
const tMessage mess_topmenu_help_notwrite = {"[Restore] is Invalid",10,16,COLOR_RED,8,MESSAGE_TOPMENU_HELP_WRITE,PANEL_TOPMENU};
const tMessage mess_topmenu_help_end = {"[End] return to SystemMenu",10,28,COLOR_WHITE,8,MESSAGE_TOPMENU_HELP_END,PANEL_TOPMENU};
const tMessage mess_topmenu_help_operate = {"touch below",10,48,COLOR_GREEN,8,MESSAGE_TOPMENU_HELP_OPERATE,PANEL_TOPMENU};
//ログ表示
const tPanel panel_dbglog = {NULL_PTR,NULL_STR,LOC_LOG_X,LOC_LOG_Y,LOC_LOG_W,LOC_LOG_H,PANEL_DBGLOG,SCREEN_UPPER};
const tMemo memo_dbglog = {LOG_MAX,10,10,COLOR_WHITE,8,MEMO_DBGLOG,PANEL_DBGLOG};
//通常時
//タイトル
#define FONT_SIZE_TITLE 12
#define LOC_TITL_X (40-FONT_SIZE_TITLE*2)
#define LOC_TITL_Y 20
#define LOC_TITL_W (400 - LOC_CONF_X*2)
#define LOC_TITL_H 50
#define FONT_SIZE_PRODUCT 10
const tPanel panel_title = {NULL_PTR,NULL_STR,LOC_TITL_X,LOC_TITL_Y,LOC_TITL_W,LOC_TITL_H,PANEL_TITLE,SCREEN_UPPER};
const tMessage mess_title = {"title",0,0,COLOR_WHITE,FONT_SIZE_TITLE,MESSAGE_TITLE,PANEL_TITLE};
const tMessage mess_product = {"product",0,LOC_TITL_H - 20,COLOR_WHITE,FONT_SIZE_PRODUCT,MESSAGE_PRODUCT,PANEL_TITLE};
const tMessage mess_product2 = {"product2",0,LOC_TITL_H - 10,COLOR_WHITE,FONT_SIZE_PRODUCT,MESSAGE_PRODUCT2,PANEL_TITLE};
const tMessage mess_version = {"version",LOC_TITL_W-FONT_SIZE_PRODUCT*6,FONT_SIZE_TITLE+2,COLOR_WHITE,FONT_SIZE_PRODUCT,MESSAGE_VERSION,PANEL_TITLE};
#define LOC_MESS_X 20
#define LOC_MESS_W (400 - LOC_MESS_X*2)
#define LOC_MESS_Y (LOC_TITL_Y + LOC_TITL_H + 10)
#define LOC_MESS_H (240 - LOC_MESS_Y - 10)
//TOPメニュー
//情報表示はログと排他
#define FONT_SIZE 10
#define STR_LINE(ln) (FONT_SIZE + 2)*ln
const tPanel panel_menu = {NULL_PTR,NULL_STR,LOC_MESS_X,LOC_MESS_Y,LOC_MESS_W,LOC_MESS_H,PANEL_MENU,SCREEN_UPPER};
const tMessage mess_menu_read = {"[Backup] Card savedata Backup",10,STR_LINE(1),COLOR_WHITE,FONT_SIZE,MESSAGE_MENU_READ,PANEL_MENU};
const tMessage mess_menu_write = {"[Restore] restore to Card",10,STR_LINE(2),COLOR_WHITE,FONT_SIZE,MESSAGE_MENU_WRITE,PANEL_MENU};
//const tMessage mess_menu_end = {"[End] close this apprication",10,STR_LINE(3),COLOR_WHITE,FONT_SIZE,MESSAGE_MENU_END,PANEL_MENU};
const tMessage mess_menu_operate = {"touch below",10,STR_LINE(4),COLOR_GREEN,FONT_SIZE,MESSAGE_MENU_OPERATE,PANEL_MENU};
const tMessage mess_sderr = {"Backup error",10,STR_LINE(6),COLOR_RED,FONT_SIZE,MESSAGE_MENU_ERROR,PANEL_MENU};
const tMessage mess_carderr = {"CARD error",10,STR_LINE(7),COLOR_YELLO,FONT_SIZE,MESSAGE_MENU_CAUTION,PANEL_MENU};
const tMessage mess_debug = {"Crush Mode",10,STR_LINE(3),COLOR_YELLO,FONT_SIZE,MESSAGE_MENU_DEBUG,PANEL_MENU};
//Backup
const tPanel panel_bkup = {NULL_PTR,NULL_STR,LOC_LOG_X,LOC_LOG_Y,LOC_LOG_W,LOC_LOG_H,PANEL_BKUP,SCREEN_UPPER};
const tMessage mess_quit_operate = {"touch [Quit],or Push B",10,STR_LINE(4),COLOR_SKY,FONT_SIZE,MESSAGE_QUIT_OPERATE,PANEL_BKUP};
const tMessage mess_conf = {"Do you execute?",10,STR_LINE(2),COLOR_WHITE,FONT_SIZE,MESSAGE_CONF,PANEL_BKUP};
const tMessage mess_result = {"result",10,STR_LINE(2),COLOR_WHITE,FONT_SIZE,MESSAGE_RESULT,PANEL_BKUP};
const tMessage mess_operate = {"touch below",10,STR_LINE(4),COLOR_GREEN,FONT_SIZE,MESSAGE_OPERATE,PANEL_BKUP};
const tMessage mess_status = {"status",10,STR_LINE(7),COLOR_WHITE,FONT_SIZE,MESSAGE_STATUS,PANEL_BKUP};
const tMessage mess_count = {"count",10,STR_LINE(8),COLOR_WHITE,FONT_SIZE,MESSAGE_COUNT,PANEL_BKUP};
const tMessage mess_count2 = {"count2",10,STR_LINE(9),COLOR_GREEN,FONT_SIZE,MESSAGE_COUNT2,PANEL_BKUP};
//挿抜発生時
const tPanel panel_insexit = {NULL_PTR,NULL_STR,LOC_LOG_X,LOC_LOG_Y,LOC_LOG_W,LOC_LOG_H,PANEL_INSEXIT,SCREEN_UPPER};
const tMessage mess_insexit = {"device insert or pull out is detected",10,STR_LINE(3),COLOR_RED,8,MESSAGE_INSEXT_1,PANEL_INSEXIT};
const tMessage mess_insexit2 = {"return to top menu",10,STR_LINE(5),COLOR_WHITE,8,MESSAGE_INSEXT_2,PANEL_INSEXIT};
const tMessage mess_insexit3 = {"please touch or push B",10,STR_LINE(6),COLOR_WHITE,8,MESSAGE_INSEXT_3,PANEL_INSEXIT};
//削除確認
const tPanel panel_delconf = {NULL_PTR,NULL_STR,LOC_CONF_X-10,LOC_CONF_Y,LOC_CONF_W+10,LOC_CONF_H*2,PANEL_DELCONF,SCREEN_UPPER};
const tMessage mess_delconf_Title = {" *** DELETE *** ",10,10,COLOR_YELLO,16,MESSAGE_DELCONF_TITLE,PANEL_DELCONF};
const tMessage mess_delconf_Msg = {" caution!",10,50,COLOR_YELLO,12,MESSAGE_DELCONF_MSG,PANEL_DELCONF};
const tMessage mess_delconf_Msg2 = {"this is delete backup",10,70,COLOR_YELLO,12,MESSAGE_DELCONF_MSG2,PANEL_DELCONF};
const tMessage mess_delconf_Msg3 = {"Do you execute?",10,90,COLOR_YELLO,12,MESSAGE_DELCONF_MSG3,PANEL_DELCONF};
nn::os::LightEvent stopEvnt(true);
char scr_ver[16];
char scr_err[32];
char scr_debug[32];
//menu
bool ScrInitialize(uptr heap,u32 size)
{
scr_evnt = EVNT_NONE;
if (gui.Initialize(heap,size,&stopEvnt)==false)return false;
gui.ButtonCallback((uptr)pushButton);
//コンポーネント登録
gui.PanelSet(&panel_Read);
gui.PanelSet(&panel_Write);
// gui.PanelSet(&panel_End);
gui.PanelSet(&panel_Yes);
gui.PanelSet(&panel_No);
gui.PanelSet(&panel_Quit);
gui.PanelSet(&panel_Error);
gui.PanelSet(&panel_Success);
gui.PanelSet(&panel_Confirm);
gui.PanelSet(&panel_delconf);
gui.PanelSet(&panel_topmenu_help);
gui.PanelSet(&panel_title);
gui.PanelSet(&panel_menu);
gui.PanelSet(&panel_bkup);
gui.PanelSet(&panel_dbglog);
gui.PanelSet(&panel_insexit);
gui.PanelLineStyle(PANEL_TITLE,COLOR_BLACK);
gui.MessSet(&mess_Title_Err);
gui.MessSet(&mess_Info_Err);
gui.MessSet(&mess_Info2_Err);
gui.MessSet(&mess_Info3_Err);
gui.MessSet(&mess_Title_Suc);
gui.MessSet(&mess_Info_Suc);
gui.MessSet(&mess_Info2_Suc);
gui.MessSet(&mess_conf_Title);
gui.MessSet(&mess_conf_Msg);
gui.MessSet(&mess_delconf_Title);
gui.MessSet(&mess_delconf_Msg);
gui.MessSet(&mess_delconf_Msg2);
gui.MessSet(&mess_delconf_Msg3);
gui.MessSet(&mess_topmenu_help_read);
gui.MessSet(&mess_topmenu_help_write);
gui.MessSet(&mess_topmenu_help_end);
gui.MessSet(&mess_topmenu_help_operate);
gui.MessSet(&mess_title);
gui.MessSet(&mess_version);
gui.MessSet(&mess_product);
gui.MessSet(&mess_product2);
gui.MessSet(&mess_menu_read);
gui.MessSet(&mess_menu_write);
// gui.MessSet(&mess_menu_end);
gui.MessSet(&mess_menu_operate);
gui.MessSet(&mess_quit_operate);
gui.MessSet(&mess_conf);
gui.MessSet(&mess_operate);
gui.MessSet(&mess_sderr);
gui.MessSet(&mess_carderr);
gui.MessSet(&mess_debug);
gui.MessSet(&mess_result);
gui.MessSet(&mess_status);
gui.MessSet(&mess_count);
gui.MessSet(&mess_count2);
gui.MessSet(&mess_insexit);
gui.MessSet(&mess_insexit2);
gui.MessSet(&mess_insexit3);
gui.MemoSet(&memo_dbglog);
gui.MemoEffective(MESSAGE_PRODUCT);
gui.MessEffective(MESSAGE_ERROR_TITLE);
gui.MessEffective(MESSAGE_ERROR_INFO);
gui.MessEffective(MESSAGE_ERROR_INFO2);
gui.MessEffective(MESSAGE_ERROR_INFO3);
gui.MessEffective(MESSAGE_SUCCESS_TITLE);
gui.MessEffective(MESSAGE_SUCCESS_INFO);
gui.MessEffective(MESSAGE_SUCCESS_INFO2);
gui.MessEffective(MESSAGE_CONFIRM_TITLE);
gui.MessEffective(MESSAGE_CONFIRM_MSG);
gui.MessEffective(MESSAGE_DELCONF_TITLE);
gui.MessEffective(MESSAGE_DELCONF_MSG);
gui.MessEffective(MESSAGE_DELCONF_MSG2);
gui.MessEffective(MESSAGE_DELCONF_MSG3);
gui.MessEffective(MESSAGE_TOPMENU_HELP_READ);
gui.MessEffective(MESSAGE_TOPMENU_HELP_WRITE);
gui.MessEffective(MESSAGE_TOPMENU_HELP_END);
gui.MessEffective(MESSAGE_TOPMENU_HELP_OPERATE);
gui.MessEffective(MESSAGE_MENU_READ);
gui.MessEffective(MESSAGE_MENU_WRITE);
// gui.MessEffective(MESSAGE_MENU_END);
gui.MessEffective(MESSAGE_MENU_OPERATE);
gui.MessEffective(MESSAGE_INSEXT_1);
gui.MessEffective(MESSAGE_INSEXT_2);
gui.MessEffective(MESSAGE_INSEXT_3);
gui.MessEffective(MESSAGE_TITLE);
gui.MessEffective(MESSAGE_VERSION);
gui.MemoEffective(MEMO_DBGLOG);
gui.PanelLineStyle(PANEL_DELCONF,COLOR_YELLO);
sprintf(scr_ver,"ver %.2f",VERSION);
gui.MessStr(MESSAGE_VERSION,scr_ver);
gui.MessStr(MESSAGE_MENU_CAUTION,scr_err);
gui.MessStr(MESSAGE_MENU_ERROR,scr_err);
gui.MessStr(MESSAGE_MENU_DEBUG,scr_debug);
return true;
}
void ScrFinalize()
{
stopEvnt.Signal();
while(stopEvnt.TryWait()){
nn::os::Thread::Yield();
};
gui.Finalize();
}
//YES-NO ボタン
void YesNo()
{
gui.ButtonMask(nn::hid::BUTTON_A | nn::hid::BUTTON_B);
gui.PanelEffective(PANEL_YES);
gui.PanelEffective(PANEL_NO);
gui.Draw();
}
void Quit()
{
gui.ButtonMask(nn::hid::BUTTON_A | nn::hid::BUTTON_B);
gui.PanelEffective(PANEL_QUIT);
gui.Draw();
}
//トップメニュー画面
//引数:カード状態
void scr_TopMenuDbg(bool formatted,bool insertted)//デバッグ用
{
scr_evnt = EVNT_NONE;
gui.ButtonMask(nn::hid::BUTTON_A | nn::hid::BUTTON_R | nn::hid::BUTTON_L);
if (formatted)
{//リード可能
gui.MessSet(&mess_topmenu_help_read);
gui.PanelEffective(PANEL_READ);
}else{//リード不可
gui.MessSet(&mess_topmenu_help_notread);
gui.PanelEffective(PANEL_READ,false);
}
if (insertted)
{//書き込み可
gui.MessSet(&mess_topmenu_help_write);
gui.PanelEffective(PANEL_WRITE);
}else{//書き込み不可
gui.MessSet(&mess_topmenu_help_notwrite);
gui.PanelEffective(PANEL_WRITE,false);
}
gui.MessEffective(MESSAGE_TOPMENU_HELP_READ);
gui.MessEffective(MESSAGE_TOPMENU_HELP_WRITE);
// gui.PanelEffective(PANEL_END);
gui.PanelEffective(PANEL_TOPMENU);
gui.Draw();
}
//通常時
//プロダクトコード
//引数:カード、拡張セーブに記録されたもの
char scr_pcode[32];
void scr_PrdCode(char *s)
{
strcpy(scr_pcode,"CARD : ");
if (s[0]==0) strcat(scr_pcode,"----");
else strcat(scr_pcode,s);
gui.MessStr(MESSAGE_PRODUCT,scr_pcode);
}
char scr_pcode2[64];
void scr_PrdCodeEx(char *s)
{
strcpy(scr_pcode2,"BKUP : ");
if (s[0]==0) strcat(scr_pcode2,"----");
else strcat(scr_pcode2,s);
gui.MessStr(MESSAGE_PRODUCT2,scr_pcode2);
}
//削除の実行確認
void scr_DelConf()
{
scr_evnt = EVNT_NONE;
gui.PanelEffective(PANEL_DELCONF);
YesNo();
}
//Top menu
//引数:デバイス状態
//arg : プロダクトコード一致
void scr_TopMenu(bool formatted,bool inserted,bool exfm,bool sdins,int err)
{
int i;
scr_evnt = EVNT_NONE;
//gui.ButtonMask(nn::hid::BUTTON_A | nn::hid::BUTTON_L nn::hid::BUTTON_LEFT | nn::hid::BUTTON_X);
#ifdef ENABLE_CRUSH
extern bool CrashForDebug;
//デバグ用 Y-> クラッシュモード,L -> デバグモード
gui.ButtonMask(nn::hid::BUTTON_Y | nn::hid::BUTTON_L | nn::hid::BUTTON_LEFT | nn::hid::BUTTON_X);
if (CrashForDebug==0) gui.MessEffective(MESSAGE_MENU_DEBUG,false,false);
else{
sprintf(scr_debug,"Crush mode %d",CrashForDebug);
gui.MessEffective(MESSAGE_MENU_DEBUG);
}
#else//DOWN+Y = debug
gui.ButtonMask( nn::hid::BUTTON_DOWN | nn::hid::BUTTON_LEFT | nn::hid::BUTTON_X | nn::hid::BUTTON_Y);
#endif
//gui.PanelLineStyle(PANEL_MENU,COLOR_WHITE);
//gui.PanelLineStyle(PANEL_TITLE,COLOR_BLACK);
gui.MessStr(MESSAGE_TITLE," < CTR Card Savedata Mover >");
//bool flg = formatted && sdins;
// gui.PanelEffective(PANEL_READ,flg,flg);//savedata & SD exist
//bool flg2= inserted && exfm;
// gui.PanelEffective(PANEL_WRITE,flg2,flg2);//CARD & exsave exist
gui.MessEffective(MESSAGE_MENU_ERROR,false,false);
gui.MessEffective(MESSAGE_MENU_CAUTION,false,false);
gui.MessEffective(MESSAGE_MENU_OPERATE,false,false);
//片方のみ有効
if (formatted && sdins && (exfm == false))
{//バックアップ
gui.MessEffective(MESSAGE_MENU_OPERATE);
gui.PanelEffective(PANEL_READ);
gui.PanelEffective(PANEL_WRITE,false,false);
}else if (exfm && inserted)
{//リストア
gui.PanelEffective(PANEL_READ,false,false);
i =0;
if (err & SDATA_ERRPUT_MEDIA) i = ERC_MEDIA + ERC_DEV_CARD;//バックアップがない
else
if (err & SDATA_ERRPUT_PCODE) i = ERC_DEV_OTHER + ERC_PRODCODE;//プロダクトコード不一致
if (i !=0 )
{
gui.PanelEffective(PANEL_WRITE,false,false);
sprintf(scr_err,"ERROR %d",i);
gui.MessEffective(MESSAGE_MENU_ERROR);
}
else{
gui.MessEffective(MESSAGE_MENU_OPERATE);
gui.PanelEffective(PANEL_WRITE);
}
}else{//なし
gui.PanelEffective(PANEL_WRITE,false,false);
gui.PanelEffective(PANEL_READ,false,false);
//if (inserted == false) i = ERC_DEVICE + ERC_DEV_CARD;//カードが無い
//else
if (inserted == false)
{
strcpy(scr_err,"Please Insert Card");
gui.MessEffective(MESSAGE_MENU_CAUTION);
}else{
if (err & SDATA_ERRPUT_MEDIA) i = ERC_MEDIA + ERC_DEV_CARD;//バックアップがない
else
if (err & SDATA_ERRPUT_VERIFI) i = ERC_SDK_VERIFI + ERC_DEV_CARD;//データが壊れている
else if (sdins == false) i = ERC_DEVICE + ERC_DEV_OUT;//書出し先デバイスが無い
else i = ERC_FORMAT + ERC_DEV_CARD;//フォーマットエラー
sprintf(scr_err,"ERROR %d",i);
gui.MessEffective(MESSAGE_MENU_ERROR);
}
//}else if ((flg ==false) || (flg2 == false))
//{//どっちかダメ
// if (formatted == false) i = ERC_FORMAT + ERC_DEV_CARD;//カード未フオーマット
// else i = ERC_FORMAT + ERC_DEV_OUT;//バックアップ先が未フオーマット
// sprintf(scr_err,"CAUTION %d",i);
// gui.MessEffective(MESSAGE_MENU_CAUTION);
//}else if(agr==false)
}
gui.MessEffective(MESSAGE_PRODUCT);
gui.MessEffective(MESSAGE_PRODUCT2);
/*
eColor col;
if ((flg == false) && (flg2 == false))col = COLOR_RED;
else if ((flg == false) || (flg2 == false))col = COLOR_YELLO;
if (formatted) gui.MessEffective(MESSAGE_MENU_CARDERR,false,false);
else{
gui.MessCol(MESSAGE_MENU_CARDERR,col);
if (inserted) gui.MessStr(MESSAGE_MENU_CARDERR,"savedata is not format or broken");
else gui.MessStr(MESSAGE_MENU_CARDERR,"CARD is not found");
gui.MessEffective(MESSAGE_MENU_CARDERR);
}
if (exfm) gui.MessEffective(MESSAGE_MENU_SDERR,false,false);
else{
gui.MessCol(MESSAGE_MENU_SDERR,col);
if (sdins) gui.MessStr(MESSAGE_MENU_SDERR,"backup data is not in SD");
else gui.MessStr(MESSAGE_MENU_SDERR,"SD is not found");
gui.MessEffective(MESSAGE_MENU_SDERR);
}
*/
// gui.PanelEffective(PANEL_END);
gui.PanelEffective(PANEL_TITLE);
gui.PanelEffective(PANEL_MENU);
gui.Draw();
}
//デバッグ用、ボタン待ち
void ScrStep()
{
scr_evnt = EVNT_NONE;
gui.ButtonMask(nn::hid::BUTTON_B);
}
void ClearBkupMess()
{
gui.MessEffective(MESSAGE_CONF,false,false);
gui.MessEffective(MESSAGE_RESULT,false,false);
gui.MessEffective(MESSAGE_OPERATE,false,false);
gui.MessEffective(MESSAGE_QUIT_OPERATE,false,false);
gui.MessEffective(MESSAGE_STATUS,false,false);
gui.MessEffective(MESSAGE_COUNT,false,false);
gui.MessEffective(MESSAGE_COUNT2,false,false);
gui.PanelEffective(PANEL_BKUP);
}
//Backup
void scr_Backup()
{
scr_evnt = EVNT_NONE;
gui.PanelLineStyle(PANEL_BKUP,COLOR_SKY);
gui.MessStr(MESSAGE_TITLE," --- Backup Card Savedata ---");
gui.PanelEffective(PANEL_TITLE);
ClearBkupMess();
gui.Draw();
}
void scr_BackupYesNo()
{
scr_Backup();
gui.MessEffective(MESSAGE_CONF);
gui.MessEffective(MESSAGE_OPERATE);
YesNo();
}
//restore
void scr_Restore()
{
scr_evnt = EVNT_NONE;
gui.PanelLineStyle(PANEL_BKUP,COLOR_PARPL);
gui.MessStr(MESSAGE_TITLE,"--- Restore Card Savedata ---");
gui.PanelEffective(PANEL_TITLE);
ClearBkupMess();//backupと同じパネルを使う
gui.Draw();
}
void scr_RestoreYesNo()
{
scr_Restore();
gui.MessEffective(MESSAGE_CONF);
gui.MessEffective(MESSAGE_OPERATE);
YesNo();
}
void scr_Status(char *s,eColor col)
{
gui.MessCol(MESSAGE_STATUS,col);
gui.MessStr(MESSAGE_STATUS,s);
gui.MessEffective(MESSAGE_STATUS);
gui.Draw();
}
void scr_ResultQuit(char *s,eColor col)
{
gui.MessCol(MESSAGE_RESULT,col);
gui.MessStr(MESSAGE_RESULT,s);
gui.MessEffective(MESSAGE_RESULT);
gui.MessEffective(MESSAGE_QUIT_OPERATE);
Quit();
}
void scr_InsExitQuit()
{
ClearBkupMess();
gui.PanelLineStyle(PANEL_INSEXIT,COLOR_RED);
gui.PanelEffective(PANEL_INSEXIT);
Quit();
}
// カウント/MAX 表示
char str_Counter[128];
char str_Counter2[128];
void scr_CountPerMax(int ct,int max)
{
sprintf(str_Counter,"%d / %d",ct,max);
gui.MessStr(MESSAGE_COUNT,str_Counter);
gui.MessEffective(MESSAGE_COUNT);
gui.Draw();
}
//ゲージtotal
void scr_CountPerMax2(int ct,int max,int total)
{
if (total == -1) str_Counter2[0]=0;
else if (total != 0){
// gui.MessCol(MESSAGE_COUNT2,COLOR_WHITE);
sprintf(str_Counter2,"total size %d",total);
}else{
// gui.MessCol(MESSAGE_COUNT2,COLOR_YELLO);
int i;
int lv = ct/(max/25);
for (i =0;i<lv;i++)str_Counter2[i] = '>';
while ( i < 25 )str_Counter2[i++] = '|';
str_Counter2[i] = 0;
}
//sprintf(str_Counter2,"%d / %d",ct,max);
gui.MessStr(MESSAGE_COUNT2,str_Counter2);
gui.MessEffective(MESSAGE_COUNT2);
gui.Draw();
}
void scr_MessOnCount2(char *str)
{
// gui.MessCol(MESSAGE_COUNT2,COLOR_YELLO);
gui.MessStr(MESSAGE_COUNT2,str);
gui.MessEffective(MESSAGE_COUNT2);
gui.Draw();
}
//実行確認
void scr_ConfirmDbg(char *str)
{
scr_evnt = EVNT_NONE;
gui.MessStr(MESSAGE_CONFIRM_TITLE,str);
gui.PanelEffective(PANEL_CONFIRM);
YesNo();
}
//エラー表示とQuitボタン
void scr_ErrorQuitDbg(tColStr **s)
{
scr_evnt = EVNT_NONE;
gui.MessStr(MESSAGE_ERROR_TITLE,s[0]->str);
gui.MessCol(MESSAGE_ERROR_TITLE,s[0]->color);
gui.MessStr(MESSAGE_ERROR_INFO,s[1]->str);
gui.MessCol(MESSAGE_ERROR_INFO,s[1]->color);
gui.MessStr(MESSAGE_ERROR_INFO2,s[2]->str);
gui.MessCol(MESSAGE_ERROR_INFO2,s[2]->color);
gui.MessStr(MESSAGE_ERROR_INFO3,s[3]->str);
gui.MessCol(MESSAGE_ERROR_INFO3,s[3]->color);
gui.PanelEffective(PANEL_ERROR);
Quit();
}
//成功表示とQuitボタン
void scr_SuccessQuitDbg(tColStr **s)
{
scr_evnt = EVNT_NONE;
gui.MessStr(MESSAGE_SUCCESS_TITLE,s[0]->str);
gui.MessCol(MESSAGE_SUCCESS_TITLE,s[0]->color);
gui.MessStr(MESSAGE_SUCCESS_INFO,s[1]->str);
gui.MessCol(MESSAGE_SUCCESS_INFO,s[1]->color);
gui.MessStr(MESSAGE_SUCCESS_INFO2,s[2]->str);
gui.MessCol(MESSAGE_SUCCESS_INFO2,s[2]->color);
gui.PanelEffective(PANEL_SUCCESS);
Quit();
}
//デバッグログ
void scr_DgbLog(cStrLst *p)
{
gui.PanelLineStyle(PANEL_DBGLOG,COLOR_BLUE);
for (int i=0;i<p->getpos()+1;i++)gui.MemoStr(MEMO_DBGLOG,p->line(i),i);
gui.PanelEffective(PANEL_DBGLOG);
gui.Draw();
}
int ScrDbgLogGetMax()
{
return LOG_MAX;
}
void scr_Draw()
{
gui.Draw();
}
void scr_GetEvnt()
{
// gui.thUpdate();
}

View File

@ -9,6 +9,8 @@ extern demo::RenderSystemDrawing s_RenderSystem;
extern nn::fnd::ExpHeap appHeap;
extern uptr heapForGx;
bool prohibitHome = false;// HOME ボタン禁止
// ファイルシステム処理と遷移やスリープ処理との排他制御に利用
//nn::os::CriticalSection g_SleepCS;
// HOME ボタン遷移とファイルシステム処理の排他制御に利用(手動リセット)
@ -112,38 +114,40 @@ void CheckSysBreak(){
// HOMEボタン処理グラフィックスライブラリが初期化済みでなければならない
if ( nn::applet::IsExpectedToProcessHomeButton() )
{
// ここでフラグなどを判定してブロックを抜けるようにすれば HOME ボタン禁止区間を実現できる
// nn::applet::ClearHomeButtonState() による HOME ボタンフラグ削除も必要
g_TransitionEvent.ClearSignal();
// ファイルシステム処理中は遷移を待つ
//if ( g_SleepCS.TryEnter() )
if (prohibitHome){ // HOME ボタン禁止
nn::applet::ClearHomeButtonState();//HOME ボタンフラグ削除
}else
{
// スリープ要求を REJECT するように
nn::applet::DisableSleep();
//nngxWaitCmdlistDone();
nn::applet::ProcessHomeButton();
nn::applet::AppletWakeupState wState = nn::applet::WaitForStarting();
NN_UNUSED_VAR(wState);
//g_SleepCS.Leave();
g_TransitionEvent.Signal();
g_TransitionEvent.ClearSignal();
// HOME メニューからの中断やバッテリー不足の要因により
// アプリ終了と判断された場合、アプリのメインループを抜けて終了処理へ
if ( nn::applet::IsExpectedToCloseApplication() )
// ファイルシステム処理中は遷移を待つ
//if ( g_SleepCS.TryEnter() )
{
// 描画権は渡されていない
finish();
}
// スリープ要求を REJECT するように
nn::applet::DisableSleep();
nn::applet::EnableSleep(true);
//nngxWaitCmdlistDone();
nn::applet::ProcessHomeButton();
nn::applet::AppletWakeupState wState = nn::applet::WaitForStarting();
NN_UNUSED_VAR(wState);
//g_SleepCS.Leave();
g_TransitionEvent.Signal();
// グラフィックの設定を戻す
restoreGraphicSetting();
}
// HOME メニューからの中断やバッテリー不足の要因により
// アプリ終了と判断された場合、アプリのメインループを抜けて終了処理へ
if ( nn::applet::IsExpectedToCloseApplication() )
{
// 描画権は渡されていない
finish();
}
nn::applet::EnableSleep(true);
// グラフィックの設定を戻す
restoreGraphicSetting();
}
}
}

View File

@ -16,7 +16,7 @@
#ifndef VER_H_
#define VER_H_
#define VERSION 1.02
#define VERSION 1.03
#endif

View File

@ -2,40 +2,56 @@
ARM製 RVC_Nintendo 4.1
omake 0.9.8.5
CTR SDK2.0 + Repairtoolプライベートパッチ
動作要件上SDK以降のバージョンにシステムアップデートされた本体
v1.03以降は ps_api.h と libnn_psも(SystemProgramKitに入っている)
動作要件SDK2.0以降のシステム本体
準備)
SDK2.0用のSampledemos のcommon,gxをビルドしておく
omakerootのあるディレクトリにあるomakeファイルで
SAMPLED_DEMOS_COMMON_INCLUDE_DIR に 
sampledemos/common/includeの位置を指定しておく
公開鍵pubkeyをimp/omakeで指定
ビルド)
omakerootのあるディレクトリでomake実行
個別の場合
body下でビルドし出来たcia を、Imp下のomakeで指定
body下でビルドし出来たcia を、Imp下のomake(SRC_IMPORTEE_PATH)で指定
(量産機で使うには、マスタリング後のciaを指定)
ビルドするとNANDインポート用のcciができる
インポート先:
ciaをからインポート -> SD .. DevMenu使用,DevMenufullならnandにも入れられる
カード起動しインポート -> NAND
量産実機での実行にはマスタリング必須
cia をOLS付でマスタリングし
そのcia作成したcciをマスタリング
body下で作成したcia をOLS付でマスタリングし
そのciaを使って作成したcciをマスタリング
カードインポートで失敗する場合はciaをチェック
ciaのマスタリングはSDインポート可否で確認できる
マスタリングの流れ:
・body/images下に出来たciaをマスタリングしOLSを付ける
・このciaをImpのomakeで指定、もしくは指定場所に置く
bodyのビルドで上書きされないよう場所かファイル名変えたほうが安全
・imp/omake実行し、cci作成
・cciをマスタリング
1.03以降はインポート本体をシリアル番号で制限するようなりました
imp_lis/下にリストと署名サンプルを置いてます
OpenSSL0.9.6k,r で動作確認
OLSごとリマスタバージョン更新が必要
common/ver.hは表示バージョン、ここだけ変更してもダメ
body/omekeのコメントを参考
NANDインポートで失敗する場合はciaをチェック
SDインポートし
開発実機で動く- マスタリングしてない
量産実機で動く- OLSが付いてない
1.03以降はインポート先の本体をシリアル番号で制限
"imp/imp_lis/"下にリストと署名サンプル
OpenSSL0.9.6k,rと 1.0.0d で動作確認
imp/imp_list 下にコマンドラインツール(win32版)用バッチ
使い方はcygwinでも同じ
pubkeyをimp/omakeで指定しており、romに組み込まれる
ユーザにはpubkeyと組のprivatekeyで作った署名を渡す
リリースバージョンと対応する鍵を保存&管理
ユーザにはomake指定のpubkeyと組のprivatekeyで作った署名を渡す
本ツール開発時のマスタリングは推進G(高橋さん)に依頼した
マスタリング済みDevMenu(full)および
CUP作成は飯島さんに聞く

View File

@ -0,0 +1,10 @@
<インポータのオプション有効化>
cms_inf.txtの名前でファイル作成
以下の記述でオプションが有効になる
-t: テストメニュー
   カード上のセーブにテストパターン書き込み&ベリファイ
-p: 本体シリアルを表示

View File

@ -4,6 +4,9 @@
////////////////////////////////////////////////////////////////
NANDインポートしてから、内臓アプリ同様の手順で起動
本体システム2.0以降にしておく
CUP版(v1.02以降)は本体システムが古い場合自動更新メニュー起動
ただし、UPP(?)はHomeメニュー起動でないと使えない
(インポート手順)
・デバッガもしくはライタで"cci"をカードに書き込む
@ -37,12 +40,22 @@ Home
[Histry]
1.02 Remaster 2.0.6(予定)
#表示ver マスタリング時のver
# 変更内容
1.03 Remaster 2.0.8
"LEFT+X"同時押を4秒押し続けに変更
タッチ判定の調整
インポート先を本体シリアル番号で制限
設定ファイルでオプション有効化するようした
SDK2.0+ロンチメニューで動作確認
1.02 Remaster 2.0.6
正式版SDK_2.0 でビルド
起動時に無線デーモンOFF -> DEA-SUPで出ていたフリーズ暫定対策、本ツールでは発生して無いが一応
(いつのまに通信は切れない、完全な停止は本体スイッチ)
バナー、アイコンをデフォルトから変更
Homeメニュー環境で動作確認
本体システムがローンチ&Homeメニュー環境で動作確認
フォントを本体内蔵フォントに変更
1.01 Remaster 2.0.5
Homeボタン、電源での中断終了に対応

View File

@ -1,7 +1,8 @@
量産実機での動作にはマスタリングが必要
ciaはサーバ認証OLS必須で
取得には前回取得時よりリマスタバージョンを上げる必要あり(2011/2月現在)
ciaはサーバ認証OLS必須
OLSは前回取得時からリマスタバージョンを上げる必要あり(2011/2月現在)
(例えば、前回 1.0.0 なら 1.0.1 )
メジャーはrsfで指定(Remasterversion)
マイナとマイクロはOmakefile
MAKECIAFLAGS = -minor 0 -micro 1

View File

@ -0,0 +1,34 @@
ビルド時に組み込んだ公開鍵のペアとなるプライベート鍵を使って署名を行う
バージョンで鍵を識別する
鍵変更だけの場合でもバージョンを変えること
Openssl.exe : cygwinのインスト、Win版がある
RSA鍵、ビット長はのみ
SHA256のダイジェストに署名する
Openssl0.9.6.k(r),1.0.0d作成の書名で動作確認
(鍵作成)
openssl genrsa -out private_key.pem 2048
openssl enc -d -base64 -in private_key.pem -out private_key.der
openssl rsa -pubout -inform DER -outform DER -in private_key.der -out public_key.der
(1.0.0の場合)
openssl genpkey -out private_key.der -outform DER -algorithm rsa -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537
openssl rsa -pubout -inform DER -outform DER -in private_key.der -out public_key.der
(署名)
openssl dgst -sha256 -binary -keyform DER -sign private_key.der -out csm_sign.dat csm_list.txt
プライベート鍵のバイナリが不要なら
openssl genrsa -out private_key.pem 2048
openssl rsa -pubout -outform DER -in private_key.pem -out public_key.der
openssl dgst -sha256 -binary -sign private_key.pem -out csm_sign.dat csm_list.txt
作成したpub鍵をインポートアプリのomakeで指定
OBJECTS[] =
$`(ObjectFromBinary $(TARGET), ./Imp_list/Public_Key.der)
リストをプライベート鍵で署名作成、リストと署名をインポート時にSDから読む