diff --git a/trunk/Initializer2ndNUP/AcChanger.cpp b/trunk/Initializer2ndNUP/AcChanger.cpp new file mode 100644 index 0000000..186feb7 --- /dev/null +++ b/trunk/Initializer2ndNUP/AcChanger.cpp @@ -0,0 +1,205 @@ +/*---------------------------------------------------------------------------* + Project: Horizon + File: AcChanger.cpp + + Copyright 2009-2011 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 "AcChanger.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + +struct SaveData +{ +// インターネット接続設定 +nn::ac::CTR::NetworkSetting m_NetworkSetting[3]; +}; + +SaveData s_SaveData; + +} + +AcChanger::AcChanger() +{ + // TODO 自動生成されたコンストラクター・スタブ + +} + +AcChanger::~AcChanger() +{ + // TODO Auto-generated destructor stub +} + +nn::Result AcChanger::RestoreFromBackup() +{ + NN_UTIL_RETURN_IF_FAILED( + nn::fs::MountSaveData("data:") + ); + + NN_UTIL_RETURN_IF_FAILED( + CheckBackupFormat() + ); + + NN_UTIL_RETURN_IF_FAILED( + RestoreAcDataFromBackup() + ); + + NN_UTIL_RETURN_IF_FAILED( + nn::fs::Unmount("data:") + ); + + return nn::ResultSuccess(); +} + +nn::Result AcChanger::CheckBackupFormat() +{ + size_t maxFiles; + size_t maxDirectories; + bool isDuplicateAll; + NN_UTIL_RETURN_IF_FAILED( + nn::fs::GetSaveDataFormatInfo(&maxFiles, &maxDirectories, &isDuplicateAll) + ); + + NN_LOG("MaxFile = %d, MaxDirectory = %d, Duplicate = %d\n", maxFiles, maxDirectories, isDuplicateAll); + + if(maxFiles != FILE_NUM || + maxDirectories != DIR_NUM || + isDuplicateAll != DUPLICATE + ) + { + return nn::MakePermanentResult(nn::Result::SUMMARY_INVALID_STATE, nn::Result::MODULE_APPLICATION, + nn::Result::DESCRIPTION_INVALID_RESULT_VALUE); + } + + return nn::ResultSuccess(); +} + +nn::Result AcChanger::ImportToBackup() +{ + NN_UTIL_RETURN_IF_FAILED( + GetAcData() + ); + + // バックアップメモリをフォーマットします + NN_UTIL_RETURN_IF_FAILED( + nn::fs::FormatSaveData(FILE_NUM, DIR_NUM, DUPLICATE) + ); + + NN_UTIL_RETURN_IF_FAILED( + ImportAcDatatoBackup() + ); + + return nn::ResultSuccess(); +} + +nn::Result AcChanger::GetAcData() +{ + nn::Result result; + + // インターネット接続設定取得 + result = nn::ac::CTR::InitializeInternal(); + if (result.IsSuccess()) + { + for(s32 i = 0; i < 3; i++) + { + result = nn::ac::CTR::LoadNetworkSetting(i, s_SaveData.m_NetworkSetting[i]); + if(result.IsFailure()) + { + std::memset(&s_SaveData.m_NetworkSetting[i], 0 , sizeof(s_SaveData.m_NetworkSetting[i])); + } + } + NN_UTIL_RETURN_IF_FAILED( + nn::ac::CTR::FinalizeInternal() + ); + } + else + { + std::memset(s_SaveData.m_NetworkSetting, 0, sizeof(s_SaveData.m_NetworkSetting)); + } + + return nn::ResultSuccess(); +} + +nn::Result AcChanger::ImportAcDatatoBackup() +{ + NN_UTIL_RETURN_IF_FAILED( + nn::fs::MountSaveData("data:") + ); + + nn::fs::FileOutputStream file; + NN_UTIL_RETURN_IF_FAILED( + file.TryInitialize(L"data:/savedata.bin", true) + ); + + s32 writeSize; + NN_UTIL_RETURN_IF_FAILED( + file.TryWrite(&writeSize, &s_SaveData, sizeof(s_SaveData), true) + ); + + NN_UTIL_RETURN_IF_FAILED( + nn::fs::CommitSaveData("data:") + ); + + NN_UTIL_RETURN_IF_FAILED( + nn::fs::Unmount("data:") + ); + + return nn::ResultSuccess(); +} + +nn::Result AcChanger::RestoreAcDataFromBackup() +{ + nn::fs::FileInputStream file; + NN_UTIL_RETURN_IF_FAILED( + file.TryInitialize(L"data:/savedata.bin") + ); + + s32 readSize; + NN_UTIL_RETURN_IF_FAILED( + file.TryRead(&readSize, &s_SaveData, sizeof(s_SaveData)) + ); + + // インターネット接続設定 + nn::Result result = nn::ac::CTR::InitializeInternal(); + if (result.IsSuccess()) + { + for(s32 i = 0; i < 3; i++) + { + result = nn::ac::CTR::UpdateNetworkSetting(i, s_SaveData.m_NetworkSetting[i]); + if(result.IsFailure()) + { + std::memset(&s_SaveData.m_NetworkSetting[i], 0 , sizeof(s_SaveData.m_NetworkSetting[i])); + } + } + NN_UTIL_RETURN_IF_FAILED( + nn::ac::CTR::FlushNetworkSetting() + ); + + NN_UTIL_RETURN_IF_FAILED( + nn::ac::CTR::FinalizeInternal() + ); + } + else + { + std::memset(s_SaveData.m_NetworkSetting, 0, sizeof(s_SaveData.m_NetworkSetting)); + } + + return nn::ResultSuccess(); +} diff --git a/trunk/Initializer2ndNUP/AcChanger.h b/trunk/Initializer2ndNUP/AcChanger.h new file mode 100644 index 0000000..e06c66a --- /dev/null +++ b/trunk/Initializer2ndNUP/AcChanger.h @@ -0,0 +1,52 @@ +/*---------------------------------------------------------------------------* + Project: Horizon + File: AcChanger.h + + Copyright 2009-2011 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$ + *---------------------------------------------------------------------------*/ + +#ifndef ACCHANGER_H_ +#define ACCHANGER_H_ + +#include + +class AcChanger +{ +public: + AcChanger(); + virtual ~AcChanger(); + + // バックアップメモリからデータを読み取ってacに反映します + nn::Result RestoreFromBackup(); + + // 現在のacの値をバックアップメモリに取り込みます。 + // バックアップメモリは初期化されます + nn::Result ImportToBackup(); + +private: + // バックアップメモリのフォーマットをチェックします + nn::Result CheckBackupFormat(); + + // acデータを読み込みます + nn::Result GetAcData(); + + // 読み込んだacデータをバックアップメモリに書き込みます + nn::Result ImportAcDatatoBackup(); + + // acのデータをバックアップメモリから書き込みます + nn::Result RestoreAcDataFromBackup(); + + static const size_t FILE_NUM = 1; + static const size_t DIR_NUM = 1; + static const bool DUPLICATE = true; +}; + +#endif /* ACCHANGER_H_ */ diff --git a/trunk/Initializer2ndNUP/ConsoleInitializer.rsf b/trunk/Initializer2ndNUP/ConsoleInitializer.rsf index 3061b7a..fe8a11b 100644 --- a/trunk/Initializer2ndNUP/ConsoleInitializer.rsf +++ b/trunk/Initializer2ndNUP/ConsoleInitializer.rsf @@ -13,6 +13,8 @@ Rom: # ROMに含めるファイルのルートを記述します。 # このパス以下のファイルは、ROMに含まれファイルシステムから読み込めます。 HostRoot : "$(ROMFS_ROOT)" - + SaveDataSize : 512KB + CardInfo: - CardDevice: None + CardDevice : NorFlash + MediaType : Card1 \ No newline at end of file diff --git a/trunk/Initializer2ndNUP/OMakefile b/trunk/Initializer2ndNUP/OMakefile index aa24b90..a8c2b2a 100644 --- a/trunk/Initializer2ndNUP/OMakefile +++ b/trunk/Initializer2ndNUP/OMakefile @@ -18,6 +18,7 @@ CTR_APPTYPE = CARD TARGET_PROGRAM = ConsoleInitializer ROM_SPEC_FILE = $(TARGET_PROGRAM).rsf +DESCRIPTOR = $(HORIZON_ROOT)/resources/specfiles/private/InitializeTool.desc ROMFS_ROOT = romfiles CTR_BANNER_SPEC = AutoBoot.bsf @@ -28,6 +29,7 @@ INCLUDES += $(SAMPLED_DEMOS_COMMON_INCLUDE_DIR) \ SOURCES[] = main.cpp + AcChanger.cpp LIBS += lib_demo diff --git a/trunk/Initializer2ndNUP/Readme.txt b/trunk/Initializer2ndNUP/Readme.txt index 1e12715..85f70ce 100644 --- a/trunk/Initializer2ndNUP/Readme.txt +++ b/trunk/Initializer2ndNUP/Readme.txt @@ -1,4 +1,4 @@ yrh‹z ESDK -CTR_SDK-3_3 branch r45337 +CTR_SDK-3_3 branch r54451 diff --git a/trunk/Initializer2ndNUP/main.cpp b/trunk/Initializer2ndNUP/main.cpp index 1c3e5bf..aaa66e4 100644 --- a/trunk/Initializer2ndNUP/main.cpp +++ b/trunk/Initializer2ndNUP/main.cpp @@ -22,13 +22,21 @@ #include #include "demo.h" +#include "AcChanger.h" namespace { demo::RenderSystemDrawing s_RenderSystem; -nn::os::StackBuffer<1024> s_StackBuffer; std::vector s_DispMessage; +AcChanger s_AcChanger; + +enum Mode +{ + MODE_IMPORT, + MODE_JUMP_TO_INITIALIZE +}; + } #define HANDLE_RESULT(result) \ @@ -80,11 +88,12 @@ nn::ProgramId GetProgramIdMsetWithRegion_() void DrawResult(nn::Result result) { char buf[16]; - nn::nstd::TSNPrintf(buf, sizeof(buf), "%08X", result.GetPrintableBits()); + NN_LOG("%08X\n", result.GetPrintableBits()); + nn::nstd::TSNPrintf(buf, sizeof(buf), "Error: %08X", result.GetPrintableBits()); s_DispMessage.push_back(std::string(buf)); } -void JumpThreadFunc() +void Jump() { nn::Result result; @@ -106,16 +115,109 @@ void JumpThreadFunc() HANDLE_RESULT(result); } +bool IsImportMode() +{ + // 入力チェック + nn::hid::PadStatus pad; + nn::hid::PadReader padReader; + while( !padReader.ReadLatest(&pad) ) + { + nn::os::Thread::Sleep(nn::fnd::TimeSpan::FromMilliSeconds(100)); + } + + if((pad.hold & nn::hid::BUTTON_A) && + (pad.hold & nn::hid::BUTTON_B) && + (pad.hold & nn::hid::BUTTON_X) && + (pad.hold & nn::hid::BUTTON_Y)) + { + return true; + } + else + { + return false; + } +} + +bool Import() +{ + s_DispMessage.push_back(std::string("Import to Backup Memory")); + // 設定読み込み + nn::Result result = s_AcChanger.ImportToBackup(); + if (result.IsSuccess()) + { + s_DispMessage.push_back(std::string("Press Power Button to Shutdown")); + return true; + } + else + { + HANDLE_RESULT(result); + return false; + } +} + +bool Restore() +{ + s_DispMessage.push_back(std::string("Restore from Backup Memory")); + // 設定反映 + nn::Result result = s_AcChanger.RestoreFromBackup(); + if (result.IsSuccess()) + { + return true; + } + else + { + HANDLE_RESULT(result); + return false; + } +} + +bool ManageBackupMemory(Mode mode) +{ + if(mode == MODE_IMPORT) + { + return Import(); + } + else + { + return Restore(); + } +} + extern "C" void nnMain() { nn::applet::Enable(); + nn::fs::Initialize(); nn::cfg::Initialize(); + HANDLE_RESULT( + nn::hid::Initialize() + ); + s_DispMessage.clear(); - // ジャンプ用スレッドの生成 - nn::os::Thread drawThread; - drawThread.Start(JumpThreadFunc, s_StackBuffer, nn::os::DEFAULT_THREAD_PRIORITY + 1); + + Mode mode; + if(IsImportMode()) + { + mode = MODE_IMPORT; + } + else + { + mode = MODE_JUMP_TO_INITIALIZE; + } + + bool backupMemoryOperationSuccess; + backupMemoryOperationSuccess = ManageBackupMemory(mode); + + if(mode == MODE_JUMP_TO_INITIALIZE && backupMemoryOperationSuccess) + { + Jump(); + } + + + /////////////////////////////////////////////////////////////////////////// + // ここから先はImportモードか、Jumpに失敗した時のみ + /////////////////////////////////////////////////////////////////////////// // RenderSystem の準備 nn::fnd::ExpHeap appHeap; @@ -124,7 +226,15 @@ extern "C" void nnMain() uptr heapForGx = reinterpret_cast(appHeap.Allocate(s_GxHeapSize)); s_RenderSystem.Initialize(heapForGx, s_GxHeapSize); - s_RenderSystem.SetClearColor(NN_GX_DISPLAY_BOTH, 0, 0, 0, 1); + if(mode == MODE_IMPORT && backupMemoryOperationSuccess) + { + s_RenderSystem.SetClearColor(NN_GX_DISPLAY_BOTH, 0, 1, 0, 1); + } + else + { + s_RenderSystem.SetClearColor(NN_GX_DISPLAY_BOTH, 0, 0, 0, 1); + } + s_RenderSystem.SetColor(1, 1, 1); u32 counter = 0; @@ -137,7 +247,7 @@ extern "C" void nnMain() s32 i = 0; for(std::vector::iterator it = s_DispMessage.begin(); it != s_DispMessage.end(); it++) { - s_RenderSystem.DrawText(0, (i + 1) * 10, "%s", it->c_str()); + s_RenderSystem.DrawText(0, ++i * 10, "%s", it->c_str()); } s_RenderSystem.SwapBuffers();