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@337 385bec56-5757-e545-9c3a-d8741f4650f1
315 lines
9.7 KiB
C++
315 lines
9.7 KiB
C++
/*---------------------------------------------------------------------------*
|
|
Project: Horizon
|
|
File: main.cpp
|
|
|
|
Copyright 2009 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 <nn.h>
|
|
#include <nn/am/am_ApiLocalImporter.h>
|
|
#include <nn/am/am_ApiSystemMenu.h>
|
|
#include <nn/am/am_Result.h>
|
|
#include <nn/cfg/CTR/cfg_Api.h>
|
|
#include <nn/cfg/CTR/cfg_ApiInit.h>
|
|
#include <nn/cfg/CTR/cfg_ApiSys.h>
|
|
|
|
#include <vector>
|
|
#include <string>
|
|
|
|
#include "demo.h"
|
|
#include "ResFont.h"
|
|
#include "HeapManager.h"
|
|
|
|
#define UTIL_RETURN_IF_NOT_AM_NOT_FOUND(result) \
|
|
if(result.IsFailure()) \
|
|
{ \
|
|
if(result != nn::am::ResultNotFound()) \
|
|
{ \
|
|
return result; \
|
|
} \
|
|
nn::dbg::PrintResult(result); \
|
|
} \
|
|
|
|
// リリースする際には↓をコメントアウトしてReleaseビルドすること
|
|
//#define USE_PROD_CIA
|
|
|
|
namespace {
|
|
|
|
nn::Result DeleteBoxyard(nn::ProgramId programId);
|
|
nn::Result DownGradeNupVersion(nn::cfg::CTR::CfgRegionCode region);
|
|
void FatalDrawing(nn::Result result);
|
|
|
|
const size_t ERASE_THREAD_STACK_SIZE = 0x1000;
|
|
nn::os::Thread s_EraseThread;
|
|
nn::os::StackBuffer<ERASE_THREAD_STACK_SIZE> s_EraseThreadStack;
|
|
|
|
demo::RenderSystemDrawing s_RenderSystem;
|
|
|
|
// グラフィックスに割り当てるメモリ
|
|
const size_t s_GxHeapSize = 0x800000;
|
|
|
|
::std::vector<std::string>* s_pOperationMessage;
|
|
|
|
// インポートする
|
|
bit8 s_ReadBuf[64 * 1024];
|
|
|
|
const nn::ProgramId BOXYARD_PROGRAM_ID[] =
|
|
{
|
|
0x0004001000023000ULL, // JP
|
|
0x0004001000024000ULL, // US
|
|
0x0004001000025000ULL // EU
|
|
};
|
|
|
|
const nn::ProgramId NUP_VERSION_PROGRAM_ID[] =
|
|
{
|
|
0x000400DB00016202ULL, // JP
|
|
0x000400DB00016302ULL, // US
|
|
0x000400DB00016102ULL // EU
|
|
};
|
|
|
|
const wchar_t* ROM_NUP_VERSION_PATH[] =
|
|
{
|
|
#ifndef USE_PROD_CIA
|
|
L"rom:/000400DB00016202-0_0_0-nup.version.JP-UnfixedKey.cia", // JP
|
|
L"rom:/000400DB00016302-0_0_0-nup.version.US-UnfixedKey.cia", // US
|
|
L"rom:/000400DB00016102-0_0_0-nup.version.EU-UnfixedKey.cia" // EU
|
|
#ifdef NN_BUILD_RELEASE
|
|
#warning !! Using Development Nup Version cia on Release Build !!
|
|
#endif
|
|
#else
|
|
#ifndef NN_BUILD_RELEASE
|
|
#warning !! Using Product Nup Version cia on Development Build !!
|
|
#endif
|
|
|
|
L"rom:/000400DB00016202-0_0_0-nup.version.JP.master.ols.cia", // JP
|
|
L"rom:/000400DB00016302-0_0_0-nup.version.US.master.ols.cia", // US
|
|
L"rom:/000400DB00016102-0_0_0-nup.version.EU.master.ols.cia" // EU
|
|
#endif
|
|
};
|
|
|
|
void EraseThreadFunc(nn::cfg::CTR::CfgRegionCode region)
|
|
{
|
|
nn::Result result;
|
|
|
|
s_pOperationMessage->push_back(std::string(""));
|
|
s_pOperationMessage->push_back(std::string("Deleting..."));
|
|
// BOXYARDを消去する
|
|
result = DeleteBoxyard(BOXYARD_PROGRAM_ID[region]);
|
|
if(result.IsFailure())
|
|
{
|
|
nn::dbg::PrintResult(result);
|
|
s_pOperationMessage->push_back(std::string("Failed Delete Program"));
|
|
FatalDrawing(result);
|
|
}
|
|
s_pOperationMessage->push_back(std::string("Done."));
|
|
s_pOperationMessage->push_back(std::string(""));
|
|
|
|
s_pOperationMessage->push_back(std::string("Updating System..."));
|
|
// NUPバージョンを更新する
|
|
result = DownGradeNupVersion(region);
|
|
if (result.IsFailure())
|
|
{
|
|
nn::dbg::PrintResult(result);
|
|
s_pOperationMessage->push_back(std::string("Failed DownGrade NUP Version"));
|
|
FatalDrawing(result);
|
|
}
|
|
|
|
|
|
s_pOperationMessage->push_back(std::string("Done."));
|
|
s_pOperationMessage->push_back(std::string(""));
|
|
|
|
s_pOperationMessage->push_back(std::string("Finished."));
|
|
s_RenderSystem.SetClearColor(NN_GX_DISPLAY0, 0, 1, 0, 0);
|
|
s_RenderSystem.SetClearColor(NN_GX_DISPLAY1, 0, 1, 0, 0);
|
|
}
|
|
|
|
nn::Result DownGradeNupVersion(nn::cfg::CTR::CfgRegionCode region)
|
|
{
|
|
nn::Result result = nn::ResultSuccess();
|
|
|
|
if(region > sizeof(NUP_VERSION_PROGRAM_ID) / sizeof(NUP_VERSION_PROGRAM_ID[0]) - 1)
|
|
{
|
|
return nn::Result(nn::Result::LEVEL_STATUS, nn::Result::SUMMARY_INVALID_ARGUMENT, nn::Result::MODULE_COMMON,
|
|
nn::Result::DESCRIPTION_INVALID_ENUM_VALUE);
|
|
}
|
|
nn::ProgramID programId = NUP_VERSION_PROGRAM_ID[region];
|
|
|
|
// リージョンに合わせて削除する
|
|
result = nn::am::DeleteProgram(nn::fs::MEDIA_TYPE_NAND, programId);
|
|
UTIL_RETURN_IF_NOT_AM_NOT_FOUND(result);
|
|
|
|
nn::fs::FileOutputStream* stream;
|
|
result = nn::am::BeginImportProgram(&stream, nn::fs::MEDIA_TYPE_NAND);
|
|
NN_UTIL_RETURN_IF_FAILED(result);
|
|
|
|
NN_LOG("Importing: %ls...", ROM_NUP_VERSION_PATH[region]);
|
|
nn::fs::FileInputStream in;
|
|
|
|
const size_t ROMFS_BUFFER_SIZE = 1024 * 64;
|
|
static char buffer[ROMFS_BUFFER_SIZE];
|
|
NN_UTIL_PANIC_IF_FAILED(
|
|
nn::fs::MountRom(16, 16, buffer, ROMFS_BUFFER_SIZE));
|
|
|
|
result = in.TryInitialize(ROM_NUP_VERSION_PATH[region]);
|
|
NN_UTIL_RETURN_IF_FAILED(result);
|
|
|
|
s64 fileSize = in.GetSize();
|
|
s32 totalRead = 0;
|
|
s32 readSize = 0;
|
|
do
|
|
{
|
|
result = in.TryRead(&readSize, s_ReadBuf, sizeof(s_ReadBuf));
|
|
stream->Write(s_ReadBuf, readSize);
|
|
totalRead += readSize;
|
|
} while (totalRead < fileSize);
|
|
|
|
in.Finalize();
|
|
nn::fs::Unmount("rom:");
|
|
|
|
result = nn::am::EndImportProgram(stream);
|
|
NN_UTIL_RETURN_IF_FAILED(result);
|
|
NN_LOG(" done.\n");
|
|
|
|
return result;
|
|
}
|
|
|
|
nn::Result DeleteBoxyard(nn::ProgramId programId)
|
|
{
|
|
nn::Result result;
|
|
|
|
NN_LOG("Deleting Boxyard Program...");
|
|
// リージョンに合わせて削除する
|
|
result = nn::am::DeleteProgram(nn::fs::MEDIA_TYPE_NAND, programId);
|
|
UTIL_RETURN_IF_NOT_AM_NOT_FOUND(result);
|
|
NN_LOG("Done\n");
|
|
|
|
NN_LOG("Deleting Boxyard eTicket...");
|
|
// チケットを削除する
|
|
result = nn::am::DeleteTicket(programId);
|
|
UTIL_RETURN_IF_NOT_AM_NOT_FOUND(result);
|
|
NN_LOG("Done\n");
|
|
|
|
return result;
|
|
}
|
|
|
|
void SetTextWriterCore()
|
|
{
|
|
using namespace common;
|
|
|
|
GetTextWriter()->Print("3DMovie Eraser\n\n");
|
|
::std::vector<std::string>::iterator it;
|
|
for (it = s_pOperationMessage->begin(); it != s_pOperationMessage->end(); it++)
|
|
{
|
|
GetTextWriter()->Printf("%s\n", it->c_str());
|
|
}
|
|
|
|
}
|
|
|
|
void FatalDrawing(nn::Result result)
|
|
{
|
|
char resultStr[32];
|
|
std::snprintf(resultStr, sizeof(resultStr), "%X", result.GetPrintableBits());
|
|
s_pOperationMessage->push_back(resultStr);
|
|
|
|
for(;;)
|
|
{
|
|
s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
|
|
s_RenderSystem.SetClearColor(NN_GX_DISPLAY0, 1.f, 0, 0, 0);
|
|
s_RenderSystem.Clear();
|
|
|
|
common::SetDrawTextHandler(SetTextWriterCore);
|
|
common::DrawResFont(NN_GX_DISPLAY0);
|
|
s_RenderSystem.SwapBuffers();
|
|
|
|
s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1);
|
|
s_RenderSystem.SetClearColor(NN_GX_DISPLAY1, 1.f, 0, 0, 0);
|
|
s_RenderSystem.Clear();
|
|
|
|
s_RenderSystem.SwapBuffers();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
extern "C" void nnMain(void)
|
|
{
|
|
// os の初期化
|
|
nn::os::Initialize();
|
|
|
|
// fs の初期化
|
|
nn::fs::Initialize();
|
|
|
|
// appletの初期化
|
|
nn::applet::Enable( false );
|
|
|
|
// hid の初期化
|
|
nn::Result result = nn::hid::Initialize();
|
|
NN_UTIL_PANIC_IF_FAILED(result);
|
|
|
|
// cfg の初期化
|
|
nn::cfg::CTR::Initialize();
|
|
|
|
// リージョンの取得
|
|
nn::cfg::CTR::CfgRegionCode region;
|
|
region = nn::cfg::CTR::GetRegion();
|
|
|
|
// am の初期化
|
|
nn::am::InitializeForLocalImporter();
|
|
|
|
// ヒープの確保
|
|
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();
|
|
|
|
std::vector<std::string> operationMessage;
|
|
s_pOperationMessage = &operationMessage;
|
|
|
|
operationMessage.push_back(std::string("Region: ") + std::string(nn::cfg::CTR::GetRegionCodeA3(region)));
|
|
|
|
s_EraseThread.Start(EraseThreadFunc, region, s_EraseThreadStack);
|
|
|
|
// ボタン入力
|
|
nn::hid::PadReader padReader;
|
|
nn::hid::PadStatus padStatus;
|
|
|
|
s_RenderSystem.SetClearColor(NN_GX_DISPLAY0, 0, 0, 0, 0);
|
|
s_RenderSystem.SetClearColor(NN_GX_DISPLAY1, 0, 0, 0, 0);
|
|
|
|
for(;;)
|
|
{
|
|
padReader.ReadLatest(&padStatus);
|
|
|
|
s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
|
|
s_RenderSystem.Clear();
|
|
|
|
common::SetDrawTextHandler(SetTextWriterCore);
|
|
common::DrawResFont(NN_GX_DISPLAY0);
|
|
s_RenderSystem.SwapBuffers();
|
|
|
|
s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1);
|
|
s_RenderSystem.Clear();
|
|
s_RenderSystem.SwapBuffers();
|
|
nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(10));
|
|
|
|
if ( nn::applet::IsExpectedToCloseApplication() )
|
|
{
|
|
nn::applet::PrepareToCloseApplication();
|
|
nn::applet::CloseApplication();
|
|
}
|
|
|
|
}
|
|
}
|