/*---------------------------------------------------------------------------* Project: Horizon File: main.cpp Copyright 2009-2011 Nintendo. 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$ *---------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include "demo.h" #include "AcChanger.h" namespace { demo::RenderSystemDrawing s_RenderSystem; std::vector s_DispMessage; AcChanger s_AcChanger; enum Mode { MODE_IMPORT, MODE_JUMP_TO_INITIALIZE }; } #define HANDLE_RESULT(result) \ if(result.IsFailure()) \ { \ DrawResult(result); \ } \ //========================================================================== // MSET ProgramId取得 //========================================================================== nn::ProgramId GetProgramIdMsetWithRegion_() { bit32 pid = nn::CTR::PROGRAM_ID_UNIQUE_ID_MSET; // JP switch (nn::cfg::GetRegion()) { case nn::cfg::CTR::CFG_REGION_AMERICA: { pid = nn::CTR::PROGRAM_ID_UNIQUE_ID_MSET_US; // US } break; case nn::cfg::CTR::CFG_REGION_EUROPE: case nn::cfg::CTR::CFG_REGION_AUSTRALIA: { pid = nn::CTR::PROGRAM_ID_UNIQUE_ID_MSET_EU; // EU } break; case nn::cfg::CTR::CFG_REGION_CHINA: { pid = nn::CTR::PROGRAM_ID_UNIQUE_ID_MSET_CN; // CN } break; case nn::cfg::CTR::CFG_REGION_KOREA: { pid = nn::CTR::PROGRAM_ID_UNIQUE_ID_MSET_KR; // KR } break; case nn::cfg::CTR::CFG_REGION_TAIWAN: { pid = nn::CTR::PROGRAM_ID_UNIQUE_ID_MSET_TW; // TW } break; } return nn::CTR::MakeProgramId(nn::CTR::PROGRAM_ID_CATEGORY_SYSTEM_APPLICATION, pid, nn::CTR::PROGRAM_ID_VERSION_APP); } void DrawResult(nn::Result result) { char buf[16]; NN_LOG("%08X\n", result.GetPrintableBits()); nn::nstd::TSNPrintf(buf, sizeof(buf), "Error: %08X", result.GetPrintableBits()); s_DispMessage.push_back(std::string(buf)); } void Jump() { nn::Result result; // 規定サイズの配列としてパラメータバッファを確保 u8 jumpParam[NN_APPLET_PARAM_BUF_SIZE]; *reinterpret_cast(jumpParam) = 124; // 本体初期化画面 s_DispMessage.push_back(std::string("Prepare jump to mset")); // MSETにジャンプすることを宣言 nn::Result rseult; result = nn::applet::PrepareToJumpToOtherApplication(GetProgramIdMsetWithRegion_(), nn::fs::MEDIA_TYPE_NAND); HANDLE_RESULT(result); s_DispMessage.push_back(std::string("Jump to mset")); // MSETにジャンプするためのパラメータを渡してジャンプ // この関数からは返ってこない result = nn::applet::JumpToOtherApplication(jumpParam); HANDLE_RESULT(result); } bool IsImportMode() { // 入力チェック nn::hid::PadStatus pad; nn::hid::PadReader padReader; while( !padReader.ReadLatest(&pad) ) { nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(100)); } if((pad.hold & nn::hid::BUTTON_A) && (pad.hold & nn::hid::BUTTON_B) && (pad.hold & nn::hid::BUTTON_X) && (pad.hold & nn::hid::BUTTON_Y)) { return true; } else { return false; } } bool Import() { s_DispMessage.push_back(std::string("Import to Backup Memory")); // 設定読み込み nn::Result result = s_AcChanger.ImportToBackup(); if (result.IsSuccess()) { s_DispMessage.push_back(std::string("Press Power Button to Shutdown")); return true; } else { HANDLE_RESULT(result); return false; } } bool Restore() { s_DispMessage.push_back(std::string("Restore from Backup Memory")); // 設定反映 nn::Result result = s_AcChanger.RestoreFromBackup(); if (result.IsSuccess()) { return true; } else { HANDLE_RESULT(result); return false; } } bool ManageBackupMemory(Mode mode) { if(mode == MODE_IMPORT) { return Import(); } else { return Restore(); } } extern "C" void nnMain() { nn::applet::Enable(); nn::fs::Initialize(); nn::cfg::Initialize(); HANDLE_RESULT( nn::hid::Initialize() ); s_DispMessage.clear(); Mode mode; if(IsImportMode()) { mode = MODE_IMPORT; } else { mode = MODE_JUMP_TO_INITIALIZE; } bool backupMemoryOperationSuccess; backupMemoryOperationSuccess = ManageBackupMemory(mode); if(mode == MODE_JUMP_TO_INITIALIZE && backupMemoryOperationSuccess) { Jump(); } /////////////////////////////////////////////////////////////////////////// // ここから先はImportモードか、Jumpに失敗した時のみ /////////////////////////////////////////////////////////////////////////// // RenderSystem の準備 nn::fnd::ExpHeap appHeap; appHeap.Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize()); const size_t s_GxHeapSize = 8 * 1024 * 1024; uptr heapForGx = reinterpret_cast(appHeap.Allocate(s_GxHeapSize)); s_RenderSystem.Initialize(heapForGx, s_GxHeapSize); if(mode == MODE_IMPORT && backupMemoryOperationSuccess) { s_RenderSystem.SetClearColor(NN_GX_DISPLAY_BOTH, 0, 1, 0, 1); } else { s_RenderSystem.SetClearColor(NN_GX_DISPLAY_BOTH, 0, 0, 0, 1); } s_RenderSystem.SetColor(1, 1, 1); u32 counter = 0; for (;;) { s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0); s_RenderSystem.Clear(); s_RenderSystem.DrawText(0, 0, "count = %d", counter++); s32 i = 0; for(std::vector::iterator it = s_DispMessage.begin(); it != s_DispMessage.end(); it++) { s_RenderSystem.DrawText(0, ++i * 10, "%s", it->c_str()); } s_RenderSystem.SwapBuffers(); s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1); s_RenderSystem.Clear(); s_RenderSystem.SwapBuffers(); s_RenderSystem.WaitVsync(NN_GX_DISPLAY_BOTH); } }