mirror of
https://github.com/rvtr/ctr_Repair.git
synced 2025-10-31 13:51:08 -04:00
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@216 385bec56-5757-e545-9c3a-d8741f4650f1
471 lines
13 KiB
C++
471 lines
13 KiB
C++
/*---------------------------------------------------------------------------*
|
|
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 <nn.h>
|
|
#include <nn/version.h>
|
|
#include <nn/ptm/CTR/ptm_ApiSysmenu.h>
|
|
#include <nn/mcu.h>
|
|
#include <nn/cfg/CTR/cfg_Api.h>
|
|
#include <nn/cfg/CTR/cfg_ApiInit.h>
|
|
#include <nn/cfg/CTR/cfg_ApiSys.h>
|
|
#include <nn/ps.h>
|
|
#include <nn/nwm.h>
|
|
#include <nn/ac.h>
|
|
#include <nn/friends.h>
|
|
#include <nn/friends/CTR/friends_ApiPrivate.h>
|
|
#include <nn/fs/CTR/fs_ArchiveTypesForSystem.h>
|
|
#include <nn/fs/CTR/MPCore/fs_FileSystemBasePrivate.h>
|
|
#include <nn/fs/fs_ApiSysSaveData.h>
|
|
#include <nn/cfg/CTR/cfg_ApiNor.h>
|
|
#include <nn/am/am_ApiSystemMenu.h>
|
|
#include <nn/os/os_SharedInfo.h>
|
|
#include <nn/ndm.h>
|
|
#include <nn/nim.h>
|
|
#include "demo.h"
|
|
|
|
#include <vector>
|
|
#include <string>
|
|
|
|
#include "ConsoleRestore.h"
|
|
#include "DrawSystemState.h"
|
|
#include "Controller.h"
|
|
#include "SimplePlayer.h"
|
|
#include "CommonLogger.h"
|
|
#include "SDMountManager.h"
|
|
#include "HeapManager.h"
|
|
#include "VersionDetect.h"
|
|
#include "HardwareInfo.h"
|
|
#include "ResFont.h"
|
|
|
|
// svnリビジョン埋め込み用
|
|
#include "version.h"
|
|
#ifndef RESTORE_VERSION_NUM
|
|
#define RESOTRE_VERSION_NUM 0
|
|
#endif
|
|
|
|
namespace {
|
|
|
|
// グラフィックスに割り当てるメモリ
|
|
const size_t s_GxHeapSize = 0x800000;
|
|
|
|
demo::RenderSystemDrawing s_RenderSystem;
|
|
nn::Handle s_McuSession;
|
|
|
|
// バッテリ残量
|
|
u8 batteryRemain = 100;
|
|
|
|
// シリアルナンバー
|
|
u8 s_SerialNo[nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN];
|
|
|
|
// デバイスID
|
|
bit32 s_DeviceId;
|
|
|
|
// シリアルナンバーが読めるかどうか
|
|
bool s_CanReadSerialNumber = false;
|
|
|
|
// IVSへのポインタ
|
|
void* sp_Ivs;
|
|
|
|
size_t s_SizeofIvs;
|
|
|
|
// IVSが読めるかどうか
|
|
bool s_CanReadIvs = false;
|
|
|
|
// バージョン情報
|
|
common::VerDef s_VerData;
|
|
|
|
} // namespace <unnamed>
|
|
|
|
namespace ConsoleRestore{
|
|
|
|
bool IsAdapterConnected()
|
|
{
|
|
return nn::ptm::CTR::GetAdapterState() == nn::ptm::CTR::ADAPTERSTATE_CONNECTED;
|
|
}
|
|
|
|
bool IsBatteryLower()
|
|
{
|
|
return batteryRemain <= 10;
|
|
}
|
|
|
|
bool CanReadIVS()
|
|
{
|
|
return s_CanReadIvs;
|
|
}
|
|
|
|
bool CanReadSerialNumber()
|
|
{
|
|
return s_CanReadSerialNumber;
|
|
}
|
|
|
|
void GetSerialNumber(u8** serial, size_t* size)
|
|
{
|
|
*serial = s_SerialNo;
|
|
*size = nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN;
|
|
}
|
|
|
|
void GetIvs(void** ivs, size_t* size)
|
|
{
|
|
*ivs = sp_Ivs;
|
|
*size = s_SizeofIvs;
|
|
}
|
|
|
|
bit32 GetDeviceId()
|
|
{
|
|
return s_DeviceId;
|
|
}
|
|
|
|
void GetVersionData(common::VerDef* version)
|
|
{
|
|
*version = s_VerData;
|
|
}
|
|
|
|
void FinalizeAll()
|
|
{
|
|
common::Logger::GetLoggerInstance()->Finalize();
|
|
// アンマウント
|
|
nn::fs::Unmount("nand:");
|
|
nn::fs::Unmount("sdmc:");
|
|
s_RenderSystem.Finalize();
|
|
|
|
nn::mcu::CTR::FinalizeHwCheck(&s_McuSession);
|
|
nn::friends::detail::Finalize();
|
|
nn::ps::Finalize();
|
|
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();
|
|
}
|
|
|
|
nn::Handle GetMcuHandle()
|
|
{
|
|
return s_McuSession;
|
|
}
|
|
|
|
extern "C" void nnMain(void)
|
|
{
|
|
nn::Result result;
|
|
|
|
// os の初期化
|
|
nn::os::Initialize();
|
|
|
|
// 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();
|
|
|
|
// friendsの初期化
|
|
result = nn::friends::detail::Initialize();
|
|
|
|
// mcuの初期化
|
|
nn::mcu::CTR::InitializeHwCheck(&s_McuSession);
|
|
nn::mcu::CTR::HwCheck mcu(s_McuSession);
|
|
|
|
// amの初期化
|
|
nn::am::InitializeForSystemMenu();
|
|
|
|
// ヒープの確保
|
|
common::HeapManager::GetHeap()->Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize(), nn::os::ALLOCATE_OPTION_LINEAR);
|
|
|
|
// RenderSystem の準備
|
|
uptr heapForGx = reinterpret_cast<uptr>(common::HeapManager::GetHeap()->Allocate(s_GxHeapSize));
|
|
s_RenderSystem.Initialize(heapForGx, s_GxHeapSize);
|
|
|
|
// ResFontの初期化
|
|
common::InitializeResFont();
|
|
|
|
// サウンドスレッドの起動
|
|
common::InitializeSimplePlayer();
|
|
|
|
// ログ描画の初期化
|
|
common::Logger::GetLoggerInstance()->Initialize(CONSOLE_WIDTH, CONSOLE_HEIGHT, CONSOLE_MAX_LINE, &s_RenderSystem);
|
|
|
|
// RenderSystemを作ってからログが出せる
|
|
common::Logger::InitializeEjectThread();
|
|
common::Logger::SetEjectHandler(OnSdEjected);
|
|
COMMON_LOGGER("\n");
|
|
COMMON_LOGGER("CTR Console Restore start\n");
|
|
|
|
// ボタン入力
|
|
nn::hid::PadReader s_PadReader;
|
|
nn::hid::PadStatus padStatus;
|
|
|
|
// データの準備
|
|
|
|
// 完全性検証SEEDの取得
|
|
result = nn::fs::MountSpecialArchive("nand:", nn::fs::CTR::ARCHIVE_TYPE_CTR_NAND);
|
|
if (result.IsSuccess())
|
|
{
|
|
nn::fs::FileInputStream fis;
|
|
|
|
result = fis.TryInitialize(L"nand:/private/movable.sed");
|
|
if (result.IsSuccess())
|
|
{
|
|
s64 fileSize = fis.GetSize();
|
|
s32 ret;
|
|
void* addr = NULL;
|
|
addr = common::HeapManager::GetHeap()->Allocate(fileSize);
|
|
if (addr != NULL)
|
|
{
|
|
sp_Ivs = addr;
|
|
s_SizeofIvs = fileSize;
|
|
result = fis.TryRead(&ret, addr, fileSize);
|
|
if (result.IsSuccess())
|
|
{
|
|
s_CanReadIvs = true;
|
|
}
|
|
}
|
|
}
|
|
fis.Finalize();
|
|
}
|
|
// 一旦アンマウントしておく
|
|
nn::fs::Unmount("nand:");
|
|
|
|
// リージョンの取得
|
|
nn::cfg::CTR::CfgRegionCode region;
|
|
region = nn::cfg::CTR::GetRegion();
|
|
|
|
// シリアルナンバーの取得
|
|
std::memset(s_SerialNo, '\0',
|
|
nn::cfg::CTR::CFG_SECURE_INFO_SERIAL_NO_LEN);
|
|
result = nn::cfg::CTR::system::GetSerialNo(s_SerialNo);
|
|
common::HardwareInfo hwInfo;
|
|
hwInfo.AddCheckDigit(reinterpret_cast<char*>(s_SerialNo));
|
|
if(result.IsSuccess())
|
|
{
|
|
s_CanReadSerialNumber = true;
|
|
}
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
// デバイスIDの取得
|
|
result = nn::ps::CTR::GetDeviceId(&s_DeviceId);
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
bit64 infraDeviceId;
|
|
infraDeviceId = s_DeviceId + common::INFRA_DEVICE_ID_OFFSET;
|
|
|
|
// MACアドレスの取得
|
|
nn::nwm::Mac mac;
|
|
char8 macAddress[nn::nwm::Mac::MAC_STRING_SIZE];
|
|
|
|
result = nn::nwm::GetMacAddress(mac);
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
mac.GetString(macAddress);
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
|
|
// フレンドコードの取得
|
|
nn::friends::CTR::FriendKey friendKey;
|
|
result = nn::friends::CTR::GetMyFriendKey(&friendKey);
|
|
COMMON_LOGGER_RESULT_IF_FAILED_WITH_LINE(result);
|
|
u64 friendCode = nn::friends::CTR::FriendKeyToFriendCode(friendKey);
|
|
|
|
// バージョンの取得
|
|
common::GetSystemVersion(&s_VerData, region);
|
|
|
|
// 情報出力
|
|
COMMON_LOGGER("CTR Console Restore %s Rev.%s\n", __DATE__, RESTORE_VERSION_NUM);
|
|
COMMON_LOGGER("System Ver. %d.%d.%d-%d\n", s_VerData.cup.majorVersion, s_VerData.cup.minorVersion, s_VerData.cup.microVersion,
|
|
s_VerData.nup.majorVersion);
|
|
COMMON_LOGGER("System Region %s\n", nn::cfg::CTR::GetRegionCodeA3(region));
|
|
COMMON_LOGGER("Serial Number %s\n", s_SerialNo);
|
|
COMMON_LOGGER("Device ID %llu\n", infraDeviceId);
|
|
COMMON_LOGGER("MAC Address %s\n", macAddress);
|
|
COMMON_LOGGER("Friend Code %04u-%04u-%04u\n",
|
|
static_cast<u32>(friendCode / 100000000ULL % 10000ULL),
|
|
static_cast<u32>(friendCode / 10000ULL % 10000ULL),
|
|
static_cast<u32>(friendCode % 10000ULL) );
|
|
|
|
|
|
bool flip = false;
|
|
InitializeState();
|
|
|
|
for(;;)
|
|
{
|
|
bool nextStep = false;
|
|
|
|
s_PadReader.ReadLatest(&padStatus);
|
|
|
|
// AまたはSTARTボタンで進行
|
|
if(padStatus.trigger & nn::hid::BUTTON_A ||
|
|
padStatus.trigger & nn::hid::BUTTON_START)
|
|
{
|
|
nextStep = true;
|
|
}
|
|
|
|
// LまたはRボタンで上下画面フリップ
|
|
if(padStatus.trigger & nn::hid::BUTTON_R ||
|
|
padStatus.trigger & nn::hid::BUTTON_L)
|
|
{
|
|
flip = !flip;
|
|
}
|
|
|
|
// コンソールスクロール
|
|
if(padStatus.hold & nn::hid::BUTTON_UP)
|
|
{
|
|
common::Logger::GetLoggerInstance()->ScrollUp();
|
|
}
|
|
|
|
// コンソールスクロール
|
|
if(padStatus.hold & nn::hid::BUTTON_DOWN)
|
|
{
|
|
common::Logger::GetLoggerInstance()->ScrollDown();
|
|
}
|
|
|
|
if(padStatus.hold & nn::hid::BUTTON_LEFT)
|
|
{
|
|
common::Logger::GetLoggerInstance()->ScrollToBegin();
|
|
}
|
|
|
|
if(padStatus.hold & nn::hid::BUTTON_RIGHT)
|
|
{
|
|
common::Logger::GetLoggerInstance()->ScrollToEnd();
|
|
}
|
|
|
|
// 情報更新
|
|
// バッテリ
|
|
mcu.GetBatteryRemain(&batteryRemain);
|
|
// ACアダプタ
|
|
std::string adapterState;
|
|
if(IsAdapterConnected())
|
|
{
|
|
adapterState += ::std::string("Connected");
|
|
}
|
|
else
|
|
{
|
|
adapterState += ::std::string("Not Connected");
|
|
}
|
|
|
|
// 操作用メッセージ
|
|
// 進捗確認メッセージを兼ねる?
|
|
::std::vector<std::string> operationMessage;
|
|
|
|
ControlState(operationMessage, nextStep);
|
|
|
|
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;
|
|
}
|
|
|
|
// 上画面表示
|
|
common::DrawSystemState("CTR Console Restore",
|
|
s_RenderSystem,
|
|
titleColor,
|
|
flip,
|
|
adapterState,
|
|
RESTORE_VERSION_NUM,
|
|
&s_VerData,
|
|
batteryRemain,
|
|
infraDeviceId,
|
|
friendCode,
|
|
GetProgress(),
|
|
IsRestoreFailed(),
|
|
IsRestoreSucceeded(),
|
|
macAddress,
|
|
operationMessage,
|
|
region,
|
|
s_SerialNo
|
|
);
|
|
|
|
if (GetRestoreMode() == RESTORE_MODE_NUP_ONLY)
|
|
{
|
|
const u8 spaceSize = 10;
|
|
const u8 lineBottom = 23;
|
|
const u32 screenWidth = 400;
|
|
|
|
s_RenderSystem.SetColor(1.f, 1.f, 1.f);
|
|
s_RenderSystem.DrawText(0, lineBottom * spaceSize, "NUP-Only 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::GetRenderTarget(NN_GX_DISPLAY1, flip));
|
|
if(IsRestoreSucceeded())
|
|
{
|
|
s_RenderSystem.SetClearColor(common::GetRenderTarget(NN_GX_DISPLAY1, flip), SUCCESS_COLOR);
|
|
}
|
|
else if(IsRestoreFailed())
|
|
{
|
|
s_RenderSystem.SetClearColor(common::GetRenderTarget(NN_GX_DISPLAY1, flip), FAIL_COLOR);
|
|
}
|
|
else
|
|
{
|
|
s_RenderSystem.SetClearColor(common::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();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|