#include #include #include "common.h" #include "sleep.h" #include "demo.h" extern demo::RenderSystemDrawing s_RenderSystem; extern nn::fnd::ExpHeap appHeap; extern uptr heapForGx; bool prohibitHome = false;// HOME ボタン禁止 // ファイルシステム処理と遷移やスリープ処理との排他制御に利用 //nn::os::CriticalSection g_SleepCS; // HOME ボタン遷移とファイルシステム処理の排他制御に利用(手動リセット) nn::os::LightEvent g_TransitionEvent; // スリープとファイルシステム処理の排他制御に利用(手動リセット) nn::os::LightEvent g_AwakeEvent; void restoreGraphicSetting() { // GPU レジスタ設定の復帰 // ただし、下記は DMPGL API を使用して設定した状態の復帰のみ // レジスタ設定コマンドは全て再発行するべき nngxUpdateState(NN_GX_STATE_ALL); nngxValidateState(NN_GX_STATE_ALL,GL_TRUE); } FUNCP end_func; void InitSysBreak(uptr adrs){ end_func = (FUNCP)adrs; SleepHandler::Initialize(); //g_SleepCS.Initialize(); g_AwakeEvent.Initialize(true); g_TransitionEvent.Initialize(true); // 起床中は常に Signal 状態にしておく g_AwakeEvent.Signal(); g_TransitionEvent.Signal(); // アプレットライブラリに関する機能を有効にする nn::applet::Enable(false); // gx, snd, dsp 各ライブラリの Initialize 関数は applet::Enable() の後に呼ばれなければならない // 特に、gx の初期化である nngxInitialize 関数は、Enable() 直後の終了判定の後に行われるべき // ロゴ表示時に電源ボタンが押されたなど、既に終了条件が立っていた場合、ここでアプリを終了させる if ( nn::applet::IsExpectedToCloseApplication() ) { SleepHandler::Finalize(); nn::Result result = nn::applet::PrepareToCloseApplication(); NN_UTIL_PANIC_IF_FAILED( result ); nn::applet::CloseApplication(); } // グラフィックスライブラリの初期化は、以降で行わなければならない // 他、アプリケーションの初期化処理 } //終了処理 void finish() { SleepHandler::Finalize();//SLEEP //g_SleepCS.Finalize(); (*end_func)(); g_AwakeEvent.Finalize(); g_TransitionEvent.Finalize(); 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_SleepCS.Leave(); 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); //g_SleepCS.Leave(); g_TransitionEvent.Signal(); // アプリ終了と判断された場合、アプリのメインループを抜けて終了処理へ if ( nn::applet::IsExpectedToCloseApplication() ) { // 描画権は渡されていない finish(); } nn::applet::EnableSleep(true); // グラフィックの設定を戻す restoreGraphicSetting(); } } }