ctr_Repair/branches/CardCupForNBD/CardCup/main.cpp
N2614 4a778bf6e2 セーフモードで起動するように
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_Repair@697 385bec56-5757-e545-9c3a-d8741f4650f1
2012-04-27 07:35:37 +00:00

284 lines
9.0 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/cfg.h>
#include <nn/ptm_Private.h>
#include <nn/cup.h>
#include "Drawer.h"
#include "demo.h"
namespace
{
char s_updaterBuffer[1<<20] NN_ATTRIBUTE_ALIGN(4096);
const s32 s_GxHeapSize = 0x800000;
nn::fnd::ExpHeap s_appHeap;
demo::RenderSystemDrawing s_RenderSystem;
void ClearDisplay()
{
// ヒープの初期化
s_appHeap.Initialize(nn::os::GetDeviceMemoryAddress(), nn::os::GetDeviceMemorySize(), nn::os::ALLOCATE_OPTION_LINEAR);
// 描画クリア
void* gxHeap = s_appHeap.Allocate(s_GxHeapSize);
s_RenderSystem.Initialize(reinterpret_cast<uptr>(gxHeap), s_GxHeapSize);
s_RenderSystem.SetClearColor(NN_GX_DISPLAY0, 0, 0, 0, 1);
s_RenderSystem.SetClearColor(NN_GX_DISPLAY1, 0, 0, 0, 1);
s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY0);
s_RenderSystem.Clear();
s_RenderSystem.SwapBuffers();
s_RenderSystem.SetRenderTarget(NN_GX_DISPLAY1);
s_RenderSystem.Clear();
s_RenderSystem.SwapBuffers();
s_RenderSystem.Finalize();
s_appHeap.Free(gxHeap);
}
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()
{
// os の初期化
nn::os::Initialize();
// NuiShellの初期化 (CUPに必須)
NN_UTIL_PANIC_IF_FAILED(nn::ns::CTR::InitializeForShell());
// amの初期化
nn::am::InitializeForSystemMenu();
// fsの初期化 (カード確認用)
nn::fs::Initialize();
// appletの初期化
nn::applet::Enable();
nn::cfg::Initialize();
// DMPGLでクリアしておく
ClearDisplay();
}
nn::Result UpdateCore()
{
nn::Result result;
nn::cup::ProgressInfo info;
/********************** アップデート*******************/
NN_UTIL_RETURN_IF_FAILED(nn::cup::CTR::DoUpdate());
// ステータスがStartedになるまで、プログレスは取得できない
do{
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);
}
/********************* アップデート中 ******************/
do{
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_STARTED);
// 抜けた際のstateがFAILEDかどうか確認
if(info.state==nn::cup::CTR::UPDATE_STATE_FAILED){
NN_UTIL_RETURN_IF_FAILED(info.lastResult);
}
/***************** アップデート終了中 ******************/
do{
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_FINALIZING);
// 抜けた際のstateがFAILEDかどうか確認
if(info.state==nn::cup::CTR::UPDATE_STATE_FAILED){
NN_UTIL_RETURN_IF_FAILED(info.lastResult);
}
/******************* アップデート終了 *******************/
return nn::ResultSuccess();
}
nn::Result UpdateSequence(bool *isHandledError)
{
nn::Result result;
nn::Result lastResult=nn::ResultSuccess();
/********************* CUPの初期化 *******************/
result=nn::cup::CTR::Initialize(s_updaterBuffer,sizeof(s_updaterBuffer));
if(result==nn::cup::CTR::ResultUpdatePartitionNotFound()){
*isHandledError=true;
return result;
}
if(result==nn::cup::CTR::ResultUpdateNotRequired()){
*isHandledError=true;
return result;
}
if(result==nn::cup::CTR::ResultInvalidUpdatePartitionFormat()){
*isHandledError=true;
return result;
}
NN_UTIL_RETURN_IF_FAILED(result);
lastResult=UpdateCore();
// Initializeに成功した場合のみ、再びInitializeするためにFinalizeが必要
NN_UTIL_RETURN_IF_FAILED(nn::cup::CTR::Finalize());
return lastResult;
}
void WaitAndNotifyResult(nn::Result result)
{
while (!IsReadyforShowError())
{
nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(1));
}
NotifyFailed(result.GetPrintableBits());
}
}
extern "C" void nnMain()
{
NN_LOG("Start cup demo\n");
nn::Result result;
Initialize();
// ロゴ表示開始
StartDrawerThread();
nn::cfg::CfgRegionCode region = nn::cfg::GetRegion();
nn::ProgramId MMEN_PROGRAM_ID = GetHomeMenuProgramId(region);
nn::am::ProgramInfo outInfos;
result = nn::am::GetProgramInfos(&outInfos, nn::fs::MEDIA_TYPE_NAND, &MMEN_PROGRAM_ID, 1);
if (result.IsSuccess())
{
/******************** CUPの実行 *******************/
bool isHandledError = false;
result = UpdateSequence(&isHandledError);
// エラーが発生する可能性があるがユーザに見せない
}
else if(result == nn::am::ResultNotFound())
{
// HOMEメニューが無いエラーをエラーアプレットで表示する
WaitAndNotifyResult(result);
}
if (!(result.IsSuccess() || result == nn::cup::CTR::ResultUpdateNotRequired()))
{
NotifyFailed(0);
}
for(;;)
{
// 画面描画
if (result.IsSuccess() || result == nn::cup::CTR::ResultUpdateNotRequired())
{
// 成功したので終了処理に入る
NotifyFinished();
break;
}
if (nn::applet::IsExpectedToProcessPowerButton())
{
NotifyFinished();
break;
}
nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(16));
}
FinalizeDrawerThread();
nn::ns::ShutdownAsync();
for (;;)
{
if (nn::applet::IsExpectedToCloseApplication())
{
nn::cfg::Finalize();
nn::fs::Finalize();
nn::am::FinalizeForSystemMenu();
nn::ns::FinalizeForShell();
nn::applet::PrepareToCloseApplication();
nn::applet::CloseApplication();
}
}
}