#include #include #include "common.h" #include "sleep.h" #include "demo.h" #include #include #include #include extern demo::RenderSystemDrawing s_RenderSystem; extern nn::fnd::ExpHeap appHeap; extern uptr heapForGx; //エラー表示用文字列生成 void GetErrorStr(TgtDev dev,nn::Result res,int cd,tChar* s) { int desc=0,code; if ( (cd ==0 ) && ((dev == TGT_SD) || (dev == TGT_CARD))) { desc = res.GetDescription(); if (desc < 100 ) code = ERC_UNKNOWN;//キー検索完了 .. ありえない else if (desc < 180 ) code = ERC_READ;//ファイルが見つからないか不正 else if (desc < 200 ) code = ERC_WRITE;//ファイルが存在 else if (desc < 220 ) code = ERC_NOSPACE;//空きが無い else if (desc < 260 ) code = ERC_ACCESS;//操作拒否 else if (desc < 280 ) code = ERC_WRITE_PROTECT;//書き込み禁止 else if (desc < 340 ) code = ERC_ACCESS;//アクセスエラー else if (desc < 390 ) code = ERC_FORMAT;//フォーマットエラー else if (desc < 400 ) code = ERC_SDK_VERIFI;//改竄 else if (desc < 580 ) code = ERC_ROM;//ROM情報エラー else if (desc < 590 ) code = ERC_RETRY;//リトライ要求 else if (desc < 600 ) code = ERC_UNKNOWN;//CCI,CXI不正 .. ありえない else if (desc < 900 ) code = ERC_EXEC;//実行時エラー、ソフトバグ else code = ERC_FATAL;//本体に問題の可能性 }else code = cd; //if (desc>=600){ // sprintf(s,"ERROR %d, desc %d",dev+code,desc); //}else{ #ifdef USE_WCHAR swprintf(s,16,L"ERROR %d",dev+code); #else sprintf(s,"ERROR %d",dev+code); #endif // } } bool prohibitHome = false;// HOME ボタン禁止 // HOME ボタン遷移とファイルシステム処理の排他制御に利用(手動リセット) //nn::os::LightEvent g_TransitionEvent; // スリープとファイルシステム処理の排他制御に利用(手動リセット) nn::os::LightEvent g_AwakeEvent; nn::os::CriticalSection g_CriticalSection; nn::os::CriticalSection g_CriticalSectionForSleep; void restoreGraphicSetting() { // GPU レジスタ設定の復帰 // ただし、下記は DMPGL API を使用して設定した状態の復帰のみ // 他のライブラリを利用する場合は、それぞれの方法でレジスタ設定コマンドを全て再発行する必要があります。 // (参考)GD ライブラリによる設定を復元する // nn::gd::System::ForceDirty(nn::gd::MODULE_ALL); nngxUpdateState(NN_GX_STATE_ALL); //nngxValidateState(NN_GX_STATE_ALL,GL_TRUE); //delete 2012.8.22, cause error SDK4.x firm } FUNCP end_func; void InitSysBreak(uptr adrs){ end_func = (FUNCP)adrs; SleepHandler::Initialize(); g_AwakeEvent.Initialize(true); // g_TransitionEvent.Initialize(true); g_CriticalSection.Initialize(); g_CriticalSectionForSleep.Initialize(); // 起床中は常に Signal 状態にしておく g_AwakeEvent.Signal(); // g_TransitionEvent.Signal(); // アプレットライブラリに関する機能を有効にする nn::applet::Enable(false); // gx, snd, dsp 各ライブラリの Initialize 関数は applet::Enable() の後に呼ばれなければならない // 特に、gx の初期化である nngxInitialize 関数は、Enable() 直後の終了判定の後に行われるべき // ロゴ表示時に電源ボタンが押されたなど、既に終了条件が立っていた場合、ここでアプリを終了させる if ( nn::applet::IsExpectedToCloseApplication() ) { g_AwakeEvent.Finalize(); g_CriticalSection.Finalize(); g_CriticalSectionForSleep.Finalize(); SleepHandler::Finalize(); // nn::Result result = nn::applet::PrepareToCloseApplication(); // NN_UTIL_PANIC_IF_FAILED( result ); nn::applet::CloseApplication(); } // グラフィックスライブラリの初期化は、以降で行わなければならない // 他、アプリケーションの初期化処理 } //終了処理 void finish() { // SleepHandler::Finalize();//SLEEP (*end_func)(); g_AwakeEvent.Finalize(); //g_TransitionEvent.Finalize(); g_CriticalSection.Finalize(); g_CriticalSectionForSleep.Finalize(); SleepHandler::Finalize();//SLEEP //nn::fs::Finalize(); appHeap.Free(reinterpret_cast(heapForGx)); appHeap.Finalize(); nn::os::SetDeviceMemorySize(0); // nn::os::SetHeapSize(0); NN_LOG("End\n"); //nn::applet::PrepareToCloseApplication(); nn::applet::CloseApplication(); } void CheckSysBreak(){ // スリープからの起床時は、1フレーム分の描画完了を待ってから LCD を有効にする if ( SleepHandler::s_IsAfterWakeUp ) { nn::gx::StartLcdDisplay(); SleepHandler::s_IsAfterWakeUp = false; } // GPU のレジスタ設定の整合性を考慮した場合、 // 各種遷移、スリープ要求への返答は描画終了後に行うべき // 本体スリープ判定 if ( SleepHandler::IsSleepRequested() ) { SleepHandler::SleepSystem(); } // 終了要求をチェック if ( nn::applet::IsExpectedToCloseApplication() ) { finish(); } // アプリケーションの遷移処理を行う // HOMEボタン処理(グラフィックスライブラリが初期化済みでなければならない) if ( nn::applet::IsExpectedToProcessHomeButton() ) { if (prohibitHome){ // HOME ボタン禁止 nn::applet::ClearHomeButtonState();//HOME ボタンフラグ削除 }else { //g_TransitionEvent.ClearSignal(); // ファイルシステム処理中は遷移を待つ //if ( g_SleepCS.TryEnter() ) { // スリープ要求を REJECT するように nn::applet::DisableSleep(); //nngxWaitCmdlistDone(); nn::applet::ProcessHomeButton(); nn::applet::AppletWakeupState wState = nn::applet::WaitForStarting(); NN_UNUSED_VAR(wState); //g_TransitionEvent.Signal(); // HOME メニューからの中断やバッテリー不足の要因により // アプリ終了と判断された場合、アプリのメインループを抜けて終了処理へ if ( nn::applet::IsExpectedToCloseApplication() ) { // 描画権は渡されていない finish(); } nn::applet::EnableSleep(true); // グラフィックの設定を戻す restoreGraphicSetting(); } } } // 電源ボタン処理(グラフィックスライブラリが初期化済みでなければならない) if ( nn::applet::IsExpectedToProcessPowerButton() ) { //g_TransitionEvent.ClearSignal(); // ファイルシステム処理中は遷移を待つ //if ( g_SleepCS.TryEnter() ) { nn::applet::DisableSleep(); nngxWaitCmdlistDone(); nn::applet::ProcessPowerButton(); //nn::applet::AppletWakeupState wState = nn::applet::WaitForStarting(); //NN_UNUSED_VAR(wState); nn::applet::WaitForStarting(); //g_TransitionEvent.Signal(); // アプリ終了と判断された場合、アプリのメインループを抜けて終了処理へ if ( nn::applet::IsExpectedToCloseApplication() ) { // 描画権は渡されていない finish(); } nn::applet::EnableSleep(true); // グラフィックの設定を戻す restoreGraphicSetting(); } } }