/*---------------------------------------------------------------------------* Project: Horizon File: ConsoleRestore.cpp 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$ *---------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "demo.h" #include #include #include "DrawSystemState.h" #include "Controller.h" #include "SimplePlayer.h" #include "CommonLogger.h" #include "SDMountManager.h" #include "HeapManager.h" #include "VersionDetect.h" #include "Util.h" #include "ResFont.h" #include "HardwareStateManager.h" #include "OperationMessage.h" #include "QrImage.h" // バージョン表示用 #include "version.h" namespace { // グラフィックスに割り当てるメモリ const size_t s_GxHeapSize = 0x800000; common::Util s_HwUtility; demo::RenderSystemDrawing s_RenderSystem; } // namespace namespace ConsoleRestore{ void FinalizeAll() { common::FinalizeSimplePlayer(); common::Logger::GetLoggerInstance()->Finalize(); // アンマウント nn::fs::Unmount("nand:"); nn::fs::Unmount("sdmc:"); s_RenderSystem.Finalize(); s_HwUtility.FinalizeForRestore(); nn::ps::Finalize(); nn::am::FinalizeForNetworkImporter(); nn::ptm::CTR::FinalizeForSystemMenu(); nn::cfg::CTR::system::Finalize(); nn::cfg::CTR::init::Finalize(); nn::hid::Finalize(); nn::fs::Finalize(); nn::applet::PrepareToCloseApplication(); nn::applet::CloseApplication(); } extern "C" void nnMain(void) { nn::Result result; // fs の初期化 nn::fs::Initialize(); // appletの初期化 nn::applet::Enable( false ); // hid の初期化 result = nn::hid::Initialize(); NN_ERR_THROW_FATAL_IF_FATAL_ONLY(result); // ndmの初期化 result = nn::ndm::Initialize(); NN_ERR_THROW_FATAL_IF_FATAL_ONLY(result); // デーモンの自律動作を停止 result = nn::ndm::Suspend(nn::ndm::DN_CEC); NN_ERR_THROW_FATAL_IF_FATAL_ONLY(result); result = nn::ndm::Suspend(nn::ndm::DN_BOSS); NN_ERR_THROW_FATAL_IF_FATAL_ONLY(result); result = nn::ndm::Suspend(nn::ndm::DN_FRIENDS); NN_ERR_THROW_FATAL_IF_FATAL_ONLY(result); result = nn::ndm::Suspend(nn::ndm::DN_NIM); NN_ERR_THROW_FATAL_IF_FATAL_ONLY(result); // cfg の初期化 nn::cfg::CTR::init::Initialize(); nn::cfg::CTR::system::Initialize(); // 時計設定用ptm初期化 nn::ptm::CTR::InitializeForSystemMenu(); // ps の初期化 nn::ps::Initialize(); // amの初期化 nn::am::InitializeForNetworkImporter(); // ヒープの確保 common::InitializeHeap(); // RenderSystem の準備 common::HeapManager gxHeap(s_GxHeapSize); uptr heapForGx = reinterpret_cast(gxHeap.GetAddr()); s_RenderSystem.Initialize(heapForGx, s_GxHeapSize); // ResFontの初期化 common::InitializeResFont(); // サウンドスレッドの起動 common::InitializeSimplePlayer(); // ログ描画の初期化 common::Logger::GetLoggerInstance()->Initialize(common::CONSOLE_WIDTH, common::CONSOLE_HEIGHT, common::CONSOLE_MAX_LINE, &s_RenderSystem); // RenderSystemを作ってからログが出せる common::Logger::InitializeEjectThread(); common::Logger::SetEjectHandler(OnSdEjected); common::Logger::SetInsertHandler(OnSdInserted); COMMON_LOGGER("\n"); COMMON_LOGGER("CTR Console Restore start\n"); // ボタン入力 nn::hid::PadReader s_PadReader; nn::hid::PadStatus padStatus; // データの準備 s_HwUtility.InitializeForRestore(); common::HardwareStateManager manager(s_HwUtility); // 無線ON s_HwUtility.SetWifiOn(); // 情報出力 COMMON_LOGGER("CTR Console Restore %s-%s-%s\n", CONSOLE_REPAIR_VERSION_MAJOR, CONSOLE_REPAIR_VERSION_MINOR, CONSOLE_REPAIR_VERSION_MICRO); COMMON_LOGGER("System Ver. %d.%d.%d-%d\n", s_HwUtility.GetCupMajorVersion(), s_HwUtility.GetCupMinorVersion(), s_HwUtility.GetCupMicroVersion(), s_HwUtility.GetNupVersion()); COMMON_LOGGER("System Region %s\n", s_HwUtility.GetRegionCodeA3()); COMMON_LOGGER("Serial Number %s\n", s_HwUtility.GetSerialNumber()); COMMON_LOGGER("Device ID %llu\n", s_HwUtility.GetInfraDeviceId()); COMMON_LOGGER("MAC Address %s\n", s_HwUtility.GetMacAddress()); COMMON_LOGGER("Friend Code %04u-%04u-%04u\n", static_cast(s_HwUtility.GetFriendcode() / 100000000ULL % 10000ULL), static_cast(s_HwUtility.GetFriendcode() / 10000ULL % 10000ULL), static_cast(s_HwUtility.GetFriendcode() % 10000ULL) ); bool flip = false; bool qr = false; InitializeState(); for(;;) { bool nextStep = false; bool operateBmsDone = false; bool forcePreinstall = false; bool unregister = false; s_PadReader.ReadLatest(&padStatus); // AまたはSTARTボタンで進行 if(padStatus.trigger & nn::hid::BUTTON_A || padStatus.trigger & nn::hid::BUTTON_START) { nextStep = true; } // YボタンでBMS操作完了 // Yボタンで強制プリインストール if(padStatus.trigger & nn::hid::BUTTON_Y) { operateBmsDone = true; forcePreinstall = true; unregister = true; } // LまたはRボタンで上下画面フリップ if(padStatus.trigger & nn::hid::BUTTON_R || padStatus.trigger & nn::hid::BUTTON_L) { flip = !flip; } // 左ボタンでQR切替 if(padStatus.trigger & nn::hid::BUTTON_RIGHT) { qr = !qr; } // コンソールスクロール if(padStatus.hold & nn::hid::BUTTON_UP) { common::Logger::GetLoggerInstance()->ScrollUp(); } // コンソールスクロール if(padStatus.hold & nn::hid::BUTTON_DOWN) { common::Logger::GetLoggerInstance()->ScrollDown(); } // 情報更新 // ACアダプタ std::string adapterState; if(manager.IsAdapterConnected()) { adapterState += ::std::string("Connected"); } else { adapterState += ::std::string("Not Connected"); } // 操作用メッセージ // 進捗確認メッセージを兼ねる? common::OperationMessage operationMessage; if(qr) { u8 serial[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN]; s_HwUtility.GetSerialNumberWithoutCD(serial); common::QrImage::Draw(s_RenderSystem, s_HwUtility.GetInfraDeviceId(), serial, flip); } else { ControlState(manager, operationMessage, nextStep, operateBmsDone, forcePreinstall, unregister); nn::util::FloatColor titleColor; if (GetRestoreMode() == RESTORE_MODE_RESTORE) { titleColor.r = 0.1f; titleColor.g = 0.25f; titleColor.b = 0.1f; } else if (GetRestoreMode() == RESTORE_MODE_NUP_ONLY) { titleColor.r = 0.35f; titleColor.g = 0.35f; titleColor.b = 0.f; } else if (GetRestoreMode() == RESTORE_MODE_GET_IVS) { titleColor.r = 1.0f; titleColor.g = 0.2f; titleColor.b = 0.2f; } else if (GetRestoreMode() == RESTORE_MODE_CHECK_SD) { titleColor.r = 0.2f; titleColor.g = 0.2f; titleColor.b = 1.2f; } else if (GetRestoreMode() == RESTORE_MODE_DOWNLOAD_PREINSTALL) { titleColor.r = 1.0f; titleColor.g = 0.55f; titleColor.b = 1.0f; } else if (GetRestoreMode() == RESTORE_MODE_CHECK_SALVAGE) { titleColor.r = 0.33f; titleColor.g = 0.10f; titleColor.b = 0.55f; } // 上画面表示 common::DrawSystemState("CTR Console Restore", s_RenderSystem, titleColor, flip, adapterState, s_HwUtility.GetCupMajorVersion(), s_HwUtility.GetCupMinorVersion(), s_HwUtility.GetCupMicroVersion(), s_HwUtility.GetNupVersion(), s_HwUtility.GetBatteryRemain(), s_HwUtility.GetInfraDeviceId(), s_HwUtility.GetFriendcode(), GetProgress(), IsRestoreFailed(), IsRestoreSucceeded(), false, s_HwUtility.GetMacAddress(), operationMessage, s_HwUtility.GetRegion(), s_HwUtility.GetSerialNumber(), s_HwUtility.HasReadFriendCode(), s_HwUtility.IsWifiOn()); if (GetRestoreMode() != RESTORE_MODE_RESTORE) { const u8 spaceSize = 10; const u8 lineBottom = 23; const u32 screenWidth = 400; s_RenderSystem.SetColor(1.f, 1.f, 1.f); if (GetRestoreMode() == RESTORE_MODE_NUP_ONLY) { s_RenderSystem.DrawText(0, lineBottom * spaceSize, "NUP-Only Mode"); } else if (GetRestoreMode() == RESTORE_MODE_GET_IVS) { s_RenderSystem.DrawText(0, lineBottom * spaceSize, "GET-SDCI Mode"); } else if (GetRestoreMode() == RESTORE_MODE_CHECK_SD) { s_RenderSystem.DrawText(0, lineBottom * spaceSize, "CHECK-SD Mode"); } else if (GetRestoreMode() == RESTORE_MODE_DOWNLOAD_PREINSTALL) { s_RenderSystem.DrawText(0, lineBottom * spaceSize, "DL_PREINATALL Mode"); } else if (GetRestoreMode() == RESTORE_MODE_CHECK_SALVAGE) { s_RenderSystem.DrawText(0, lineBottom * spaceSize, "GET_SDCI + CHECK_SALVAGE Mode"); } s_RenderSystem.SetColor(titleColor.r, titleColor.g, titleColor.b); s_RenderSystem.FillRectangle(0, lineBottom * spaceSize, screenWidth, spaceSize); s_RenderSystem.SetColor(1.f, 1.f, 1.f); } s_RenderSystem.SwapBuffers(); // デフォルトで下画面に描画するもの s_RenderSystem.SetRenderTarget(common::Util::GetRenderTarget(NN_GX_DISPLAY1, flip)); if (IsRestoreSucceeded()) { s_RenderSystem.SetClearColor(common::Util::GetRenderTarget(NN_GX_DISPLAY1, flip), SUCCESS_COLOR); } else if (IsRestoreFailed()) { s_RenderSystem.SetClearColor(common::Util::GetRenderTarget(NN_GX_DISPLAY1, flip), FAIL_COLOR); } else { s_RenderSystem.SetClearColor(common::Util::GetRenderTarget(NN_GX_DISPLAY1, flip), NORMAL_COLOR); } s_RenderSystem.Clear(); s_RenderSystem.SetColor(1.f, 1.f, 1.f); common::Logger::GetLoggerInstance()->DrawConsole(); s_RenderSystem.SwapBuffers(); } s_RenderSystem.WaitVsync(NN_GX_DISPLAY_BOTH); // 電源長押しで終了 if ( nn::applet::IsExpectedToCloseApplication()) { FinalizeAll(); } } } }