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@709 385bec56-5757-e545-9c3a-d8741f4650f1
392 lines
13 KiB
C++
392 lines
13 KiB
C++
/*---------------------------------------------------------------------------*
|
|
Project: Horizon
|
|
File: main.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/os.h>
|
|
#include <nn/dbg.h>
|
|
#include <nn/CTR.h>
|
|
#include <nn/ns.h>
|
|
#include <nn/ns/CTR/ns_ApiShell.h>
|
|
#include <nn/ns/CTR/ns_Shell.h>
|
|
#include <nn/fs/fs_FileSystemBase.h>
|
|
#include <nn/fs/CTR/MPCore/fs_FileSystemBasePrivate.h>
|
|
#include <nn/applet/CTR/applet_APIForSystem.h>
|
|
#include <nn/am.h>
|
|
#include <nn/ndm.h>
|
|
#include <nn/cfg.h>
|
|
#include <nn/ptm_Private.h>
|
|
|
|
#include <nn/cup.h>
|
|
|
|
#include "demo.h"
|
|
#include "scrollBuffer.h"
|
|
#include "VersionDetect.h"
|
|
#include "HeapManager.h"
|
|
|
|
namespace
|
|
{
|
|
const s32 s_GxHeapSize = 0x800000;
|
|
uptr s_GxHeap;
|
|
|
|
demo::RenderSystemDrawing s_RenderSystem;
|
|
ScrollBuffer s_scrollBufferInstance;
|
|
ScrollBuffer *s_scrollBuffer;
|
|
|
|
char s_updaterBuffer[1 << 20] NN_ATTRIBUTE_ALIGN(4096);
|
|
|
|
const u8 CUP_MAJOR_VER_3ND_NUP = 4;
|
|
|
|
bool IsOver3rdNup(u8 cupMajor)
|
|
{
|
|
return CUP_MAJOR_VER_3ND_NUP <= cupMajor;
|
|
}
|
|
|
|
nn::ProgramId GetHomeMenuProgramId(nn::cfg::CTR::CfgRegionCode region)
|
|
{
|
|
nn::ProgramId pid;
|
|
bit32 uid = nn::CTR::PROGRAM_ID_UNIQUE_ID_HOMEMENU;
|
|
bit8 ver = nn::CTR::PROGRAM_ID_VERSION_HOMEMENU;
|
|
|
|
switch( region )
|
|
{
|
|
case nn::cfg::CTR::CFG_REGION_AMERICA:
|
|
uid = nn::CTR::PROGRAM_ID_UNIQUE_ID_SYSMENU_US;
|
|
ver = nn::CTR::PROGRAM_ID_VERSION_SYSMENU_US;
|
|
break;
|
|
|
|
case nn::cfg::CTR::CFG_REGION_EUROPE:
|
|
case nn::cfg::CTR::CFG_REGION_AUSTRALIA:
|
|
uid = nn::CTR::PROGRAM_ID_UNIQUE_ID_SYSMENU_EU;
|
|
ver = nn::CTR::PROGRAM_ID_VERSION_SYSMENU_EU;
|
|
break;
|
|
|
|
case nn::cfg::CTR::CFG_REGION_CHINA:
|
|
uid = nn::CTR::PROGRAM_ID_UNIQUE_ID_SYSMENU_CN;
|
|
ver = nn::CTR::PROGRAM_ID_VERSION_SYSMENU_CN;
|
|
break;
|
|
|
|
case nn::cfg::CTR::CFG_REGION_KOREA:
|
|
uid = nn::CTR::PROGRAM_ID_UNIQUE_ID_SYSMENU_KR;
|
|
ver = nn::CTR::PROGRAM_ID_VERSION_SYSMENU_KR;
|
|
break;
|
|
|
|
case nn::cfg::CTR::CFG_REGION_TAIWAN:
|
|
uid = nn::CTR::PROGRAM_ID_UNIQUE_ID_SYSMENU_TW;
|
|
ver = nn::CTR::PROGRAM_ID_VERSION_SYSMENU_TW;
|
|
break;
|
|
}
|
|
|
|
pid = nn::CTR::MakeProgramId( nn::CTR::PROGRAM_ID_CATEGORY_APPLET,
|
|
uid,
|
|
ver ); // プログラムID
|
|
return pid;
|
|
}
|
|
|
|
// デモの初期化
|
|
void Initialize()
|
|
{
|
|
// NuiShellの初期化 (CUPに必須)
|
|
NN_UTIL_PANIC_IF_FAILED(nn::ns::CTR::InitializeForShell());
|
|
|
|
// ndmの初期化
|
|
nn::ndm::Initialize();
|
|
|
|
// 全デーモンの自律動作をacの自動接続も含めて止める
|
|
nn::ndm::SuspendScheduler();
|
|
|
|
// amの初期化
|
|
nn::am::InitializeForSystemMenu();
|
|
|
|
// fsの初期化 (カード確認用)
|
|
nn::fs::Initialize();
|
|
|
|
// appletの初期化
|
|
//nn::applet::InitializeForSystem( nn::applet::PHOME_MENU_APPLET_ID, nn::applet::TYPE_SYS );
|
|
//nn::applet::Initialize( nn::applet::TEST2_APPLET_ID);
|
|
//nn::applet::SetAppletMode();
|
|
nn::applet::Enable();
|
|
|
|
nn::cfg::Initialize();
|
|
|
|
// デバイスメモリの設定
|
|
const s32 DEVICE_MEMORY_SIZE = 32 * 1024 * 1024;
|
|
NN_UTIL_PANIC_IF_FAILED(nn::os::SetDeviceMemorySize(DEVICE_MEMORY_SIZE));
|
|
|
|
// ヒープの初期化
|
|
InitializeHeap();
|
|
|
|
// 描画インスタンスの初期化
|
|
s_GxHeap = reinterpret_cast<uptr>(ForceAllocate(s_GxHeapSize));
|
|
s_RenderSystem.Initialize(s_GxHeap, s_GxHeapSize);
|
|
|
|
// 描画インスタンスの初期化
|
|
s_scrollBufferInstance.Initialize(&s_RenderSystem);
|
|
s_scrollBuffer = &s_scrollBufferInstance;
|
|
s_RenderSystem.SetColor(1, 1, 1);
|
|
|
|
// GPU利用宣言
|
|
nn::applet::AssignGpuRight();
|
|
}
|
|
|
|
// 消費時間取得用関数群
|
|
s64 s_StartTick;
|
|
void SetTick()
|
|
{
|
|
s_StartTick = nn::os::Tick::GetSystemCurrent();
|
|
}
|
|
s64 GetConsumedMillisec()
|
|
{
|
|
s64 endTick = nn::os::Tick::GetSystemCurrent();
|
|
nn::os::Tick consumed(endTick - s_StartTick);
|
|
return ((nn::fnd::TimeSpan) consumed).GetMilliSeconds();
|
|
}
|
|
|
|
// 動いていることを知らせるための、くるくる画面表示取得用メソッド
|
|
const char s_progress[] = "-\\|/";
|
|
s32 s_progressIndex = 0;
|
|
char GetProgressChar()
|
|
{
|
|
s_progressIndex = (s_progressIndex + 1) % (sizeof(s_progress) - 1);
|
|
return s_progress[s_progressIndex];
|
|
}
|
|
|
|
nn::Result UpdateCore()
|
|
{
|
|
nn::Result result;
|
|
nn::cup::ProgressInfo info;
|
|
|
|
/********************** アップデート*******************/
|
|
SetTick();
|
|
s_scrollBuffer->AppendText("Start Card Update")->Render();
|
|
NN_UTIL_RETURN_IF_FAILED(nn::cup::CTR::DoUpdate());
|
|
|
|
// ステータスがStartedになるまで、プログレスは取得できない
|
|
s_scrollBuffer->AppendText("");
|
|
do
|
|
{
|
|
s_scrollBuffer->ReplaceText(" %c Initializing", GetProgressChar())->Render();
|
|
result = nn::cup::CTR::GetProgressInfo(&info);
|
|
NN_UTIL_RETURN_IF_FAILED(result);
|
|
nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(40));
|
|
} while (info.state == nn::cup::CTR::UPDATE_STATE_INITIALIZING);
|
|
|
|
// 抜けた際のstateがFAILEDかどうか確認
|
|
if (info.state == nn::cup::CTR::UPDATE_STATE_FAILED)
|
|
{
|
|
NN_UTIL_RETURN_IF_FAILED(info.lastResult);
|
|
}
|
|
s_scrollBuffer->ReplaceText(" - Initialized (%lldmsec)", GetConsumedMillisec());
|
|
|
|
/********************* アップデート中 ******************/
|
|
SetTick();
|
|
s_scrollBuffer->AppendText("")->Render();
|
|
do
|
|
{
|
|
result = nn::cup::CTR::GetProgressInfo(&info);
|
|
NN_UTIL_RETURN_IF_FAILED(result);
|
|
s_scrollBuffer->ReplaceText(" %c Title %d/%d, size %lld/%lld", GetProgressChar(), info.numImportedTitles,
|
|
info.numTotalTitles, info.importedSize, info.totalSize)->Render();
|
|
nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(40));
|
|
|
|
} while (info.state == nn::cup::CTR::UPDATE_STATE_STARTED);
|
|
// 抜けた際のstateがFAILEDかどうか確認
|
|
if (info.state == nn::cup::CTR::UPDATE_STATE_FAILED)
|
|
{
|
|
NN_UTIL_RETURN_IF_FAILED(info.lastResult);
|
|
}
|
|
s_scrollBuffer->AppendText(" - Imported (%lldmsec)", GetConsumedMillisec())->Render();
|
|
|
|
/***************** アップデート終了中 ******************/
|
|
SetTick();
|
|
s_scrollBuffer->AppendText("")->Render();
|
|
do
|
|
{
|
|
result = nn::cup::CTR::GetProgressInfo(&info);
|
|
NN_UTIL_RETURN_IF_FAILED(result);
|
|
s_scrollBuffer->ReplaceText(" %c Update Finalizing", GetProgressChar())->Render();
|
|
nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(40));
|
|
} while (info.state == nn::cup::CTR::UPDATE_STATE_FINALIZING);
|
|
// 抜けた際のstateがFAILEDかどうか確認
|
|
if (info.state == nn::cup::CTR::UPDATE_STATE_FAILED)
|
|
{
|
|
NN_UTIL_RETURN_IF_FAILED(info.lastResult);
|
|
}
|
|
|
|
/******************* アップデート終了 *******************/
|
|
s_scrollBuffer->AppendText(" - Finalized (%lldmsec)", GetConsumedMillisec())->Render();
|
|
s_scrollBuffer->AppendText("");
|
|
|
|
return nn::ResultSuccess();
|
|
}
|
|
|
|
nn::Result UpdateSequence(bool *isHandledError)
|
|
{
|
|
nn::Result result;
|
|
nn::Result lastResult = nn::ResultSuccess();
|
|
|
|
/********************* CUPの初期化 *******************/
|
|
s_scrollBuffer->AppendText("Initializing Cup Library")->Render();
|
|
SetTick(); // 初期化開始前の時間をセット
|
|
result = nn::cup::CTR::Initialize(s_updaterBuffer, sizeof(s_updaterBuffer));
|
|
if (result == nn::cup::CTR::ResultUpdatePartitionNotFound())
|
|
{
|
|
s_scrollBuffer->AppendText(" - Update Partition Not Found (%lldmsec)", GetConsumedMillisec())->Render();
|
|
s_scrollBuffer->AppendText("")->Render();
|
|
*isHandledError = true;
|
|
return result;
|
|
}
|
|
if (result == nn::cup::CTR::ResultUpdateNotRequired())
|
|
{
|
|
s_scrollBuffer->AppendText(" - Already Updated (%lldmsec)", GetConsumedMillisec())->Render();
|
|
s_scrollBuffer->AppendText("")->Render();
|
|
*isHandledError = true;
|
|
return result;
|
|
}
|
|
if (result == nn::cup::CTR::ResultInvalidUpdatePartitionFormat())
|
|
{
|
|
s_scrollBuffer->AppendText(" - Invalid Update Partition (%lldmsec)", GetConsumedMillisec())->Render();
|
|
s_scrollBuffer->AppendText("")->Render();
|
|
*isHandledError = true;
|
|
return result;
|
|
}NN_UTIL_RETURN_IF_FAILED(result);
|
|
|
|
s_scrollBuffer->AppendText(" - Need Update (%lldmsec)", GetConsumedMillisec())->Render();
|
|
s_scrollBuffer->AppendText("")->Render();
|
|
|
|
lastResult = UpdateCore();
|
|
|
|
// Initializeに成功した場合のみ、再びInitializeするためにFinalizeが必要
|
|
SetTick();
|
|
s_scrollBuffer->AppendText("Finalizing Cup Library")->Render();
|
|
NN_UTIL_RETURN_IF_FAILED(nn::cup::CTR::Finalize());
|
|
s_scrollBuffer->AppendText(" - Complete (%lldmsec)", GetConsumedMillisec())->Render();
|
|
s_scrollBuffer->AppendText("")->Render();
|
|
|
|
return lastResult;
|
|
}
|
|
}
|
|
|
|
nn::Result ExecuteCup(ScrollBuffer* scrollBuf)
|
|
{
|
|
nn::Result result;
|
|
bool isHandledError = false;
|
|
result = UpdateSequence(&isHandledError);
|
|
if (isHandledError == false && result.IsFailure())
|
|
{
|
|
{
|
|
// それ以外の場合は、Resultを表示
|
|
scrollBuf->AppendText(" - Unhandled Error: 0x%08x", result.GetPrintableBits());
|
|
scrollBuf->AppendText("")->Render();
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void ShowError(const char* str)
|
|
{
|
|
s_scrollBuffer->AppendText(str);
|
|
for (;;)
|
|
{
|
|
s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
|
|
s_RenderSystem.SetClearColor(NN_GX_DISPLAY0, 1, 1, 0, 1);
|
|
s_RenderSystem.SetColor(0, 0, 0);
|
|
s_RenderSystem.Clear();
|
|
s_RenderSystem.SwapBuffers();
|
|
s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1);
|
|
s_RenderSystem.SetClearColor(NN_GX_DISPLAY1, 1, 1, 0, 1);
|
|
s_RenderSystem.Clear();
|
|
s_RenderSystem.SetColor(0, 0, 0);
|
|
s_scrollBuffer->Render();
|
|
s_RenderSystem.SwapBuffers();
|
|
|
|
if (nn::applet::IsExpectedToCloseApplication())
|
|
{
|
|
nn::applet::PrepareToCloseApplication();
|
|
nn::applet::CloseApplication();
|
|
}
|
|
}
|
|
}
|
|
|
|
extern "C" void nnMain()
|
|
{
|
|
NN_LOG("Start Self Cup\n");
|
|
nn::Result result;
|
|
Initialize();
|
|
VerDef versionData;
|
|
|
|
nn::cfg::CfgRegionCode region = nn::cfg::GetRegion();
|
|
nn::ProgramId MMEN_PROGRAM_ID = GetHomeMenuProgramId(region);
|
|
GetSystemVersion(&versionData, region);
|
|
s_scrollBuffer->AppendText("Version: %d.%d.%d-%d%c", versionData.cup.majorVersion, versionData.cup.minorVersion,
|
|
versionData.cup.microVersion, versionData.nup.majorVersion, nn::cfg::GetRegionCodeA3(region)[0]);
|
|
|
|
if(IsOver3rdNup(versionData.cup.majorVersion))
|
|
{
|
|
ShowError("Cannot Update");
|
|
}
|
|
|
|
nn::am::ProgramInfo outInfos;
|
|
result = nn::am::GetProgramInfos(&outInfos, nn::fs::MEDIA_TYPE_NAND, &MMEN_PROGRAM_ID, 1);
|
|
if (result.IsSuccess())
|
|
{
|
|
result = ExecuteCup(s_scrollBuffer);
|
|
}
|
|
else if (result == nn::am::ResultNotFound())
|
|
{
|
|
s_scrollBuffer->AppendText("Cannot find Home Menu");
|
|
}
|
|
|
|
s_scrollBuffer->AppendText("")->Render();
|
|
GetSystemVersion(&versionData, region);
|
|
|
|
s_scrollBuffer->AppendText("Version: %d.%d.%d-%d%c", versionData.cup.majorVersion, versionData.cup.minorVersion,
|
|
versionData.cup.microVersion, versionData.nup.majorVersion, nn::cfg::GetRegionCodeA3(region)[0]);
|
|
|
|
s_scrollBuffer->AppendText("")->Render();
|
|
|
|
for (;;)
|
|
{
|
|
s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
|
|
if (result.IsSuccess() || result == nn::cup::CTR::ResultUpdateNotRequired())
|
|
{
|
|
s_RenderSystem.SetClearColor(NN_GX_DISPLAY0, 0, 1, 0, 1);
|
|
}
|
|
else
|
|
{
|
|
s_RenderSystem.SetClearColor(NN_GX_DISPLAY0, 1, 0, 0, 1);
|
|
}
|
|
s_RenderSystem.Clear();
|
|
s_RenderSystem.SwapBuffers();
|
|
s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1);
|
|
if (result.IsSuccess() || result == nn::cup::CTR::ResultUpdateNotRequired())
|
|
{
|
|
s_RenderSystem.SetClearColor(NN_GX_DISPLAY1, 0, 1, 0, 1);
|
|
}
|
|
else
|
|
{
|
|
s_RenderSystem.SetClearColor(NN_GX_DISPLAY1, 1, 0, 0, 1);
|
|
}
|
|
s_scrollBuffer->ReplaceText("%c Finished", GetProgressChar())->Render();
|
|
|
|
if (nn::applet::IsExpectedToCloseApplication())
|
|
{
|
|
nn::applet::PrepareToCloseApplication();
|
|
nn::applet::CloseApplication();
|
|
}
|
|
|
|
}
|
|
}
|