/*---------------------------------------------------------------------------* Project: Horizon File: Controller.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 "Controller.h" #include "FileChecker.h" #include "Exporter.h" #include "SimplePlayer.h" #include "CommonLogger.h" #include namespace ConsoleBackup { namespace { typedef enum BackupState { STARTUP, // 初期値 EXPORT_TWL_LIST, // TWLアプリのリストを書き出し中 EXPORT_TWL_NAND, // TWLセーブデータ領域の吸出し中 EXPORT_TWL_SOUND, // TWLサウンド領域の吸出し中 EXPORT_TWL_PHOTO, // TWL写真領域の吸出し中 EXPORT_CTR_NAND, // 吸出し中 DELETE_NIM, // nimのシステムセーブデータ削除 DONE, // 吸出し完了 FINISHED, // SDカード抜き完了 FAIL // 失敗 } BackupState; // APSettingの書式が無い警告サウンドを鳴らしたかどうか bool s_ExistAPSettingAnnotation = false; // SDに書き込みできない警告サウンドを鳴らしたかどうか bool s_SdWriteProetctAnnotation = false; BackupState s_BackupState = STARTUP; bool s_PlayedStartCursor = false; bool s_PlayedSdPullOutCursor = false; bool s_PlayedFinishedSound = false; bool s_PlayedFailSound = false; } // namespace bool NeedsAcAdapter(common::HardwareStateManager& manager) { return manager.IsBatteryLower() && !manager.IsAdapterConnected(); } void ControlState(common::HardwareStateManager& manager, ::std::vector& operationMessage, bool& nextStep, bool& continueBackup) { // 状態遷移Controller switch (s_BackupState) { // 起動時 case STARTUP: { bool error = false; // 完全性検証SEEDを読めるか? if (manager.CanReadIvs()) { // SDカードが挿入されているか? if (nn::fs::IsSdmcInserted()) { // SDカードに書き込みできるか? if (!nn::fs::IsSdmcWritable()) { if (!s_SdWriteProetctAnnotation) { s_SdWriteProetctAnnotation = true; common::PlaySound(common::SOUND_ANNOTATION); } operationMessage.push_back(::std::string("Can*t Write SD Card!!\n")); break; } // 無線設定ファイルがあるか? if (common::ExistsAPSetting()) { // 書き込み中に抜かないように if (nextStep) { // シリアルナンバーを読み取れるか? if (!manager.CanReadSerialNumber()) { common::PlaySound(common::SOUND_ANNOTATION); COMMON_LOGGER("Can't Read Serial Number\n"); } } } else { error = true; if (!s_ExistAPSettingAnnotation) { s_ExistAPSettingAnnotation = true; common::PlaySound(common::SOUND_ANNOTATION); } operationMessage.push_back(::std::string("Accsess_Point_Setting does not exist!")); } } else { error = true; operationMessage.push_back(::std::string("Insert SD Card!!")); } } else { error = true; operationMessage.push_back(::std::string("Can't Read IVS!!")); } // ACアダプタが必要か? if (NeedsAcAdapter(manager)) { error = true; operationMessage.push_back(::std::string("Connect AC Adapter!!")); } // エラーが無ければ進行用メッセージ表示 if(!error) { operationMessage.push_back(::std::string("Push A or START Button")); if(!s_PlayedStartCursor) { common::PlaySound(common::SOUND_CURSOR); s_PlayedStartCursor = true; } } if (nextStep && !error) { COMMON_LOGGER("Start Export Data\n"); s_BackupState = EXPORT_TWL_LIST; } } break; // TWLセーブデータ領域のリスト作成中 case EXPORT_TWL_LIST: { static bool init = true; if(init) { // データを書き込む ExportTwlTitleList(); init = false; } // 処理が完了した if (IsExportFinished()) { FinalizeExportThread(); s_BackupState = EXPORT_TWL_NAND; } } break; // TWLセーブデータ領域の吸出し中 case EXPORT_TWL_NAND: { static bool init = true; if(init) { // コンテキストを初期化する InitializeFileListContext(); // データを書き込む ExportTwlSaveData(); init = false; } // 処理が完了した if (IsExportFinished()) { FinalizeExportThread(); s_BackupState = EXPORT_TWL_SOUND; } } break; // TWLサウンド領域の吸出し中 case EXPORT_TWL_SOUND: { static bool init = true; if(init) { // データを書き込む ExportTwlSoundData(); init = false; } // 処理が完了した if (IsExportFinished()) { FinalizeExportThread(); s_BackupState = EXPORT_TWL_PHOTO; } } break; // TWL写真領域の吸出し中 case EXPORT_TWL_PHOTO: { static bool init = true; if(init) { // データを書き込む ExportTwlPhotoData(); init = false; } // 処理が完了した if (IsExportFinished()) { FinalizeExportThread(); s_BackupState = EXPORT_CTR_NAND; } } break; // 吸出し中 case EXPORT_CTR_NAND: { continueBackup = true; // ACアダプタが必要か? if (NeedsAcAdapter(manager)) { continueBackup = false; operationMessage.push_back(::std::string("Connect AC Adapter!!")); } // データを書き込む ExportData(manager); // 処理が完了した if (continueBackup && IsExportFinished()) { FinalizeExportThread(); COMMON_LOGGER("Export NAND Data Finished.\n"); if(GetProgress() > 99) { s_BackupState = DELETE_NIM; } else { s_BackupState = FAIL; } } } break; // nimのシステムセーブデータ削除 case DELETE_NIM: { DeleteNimSaveData(); s_BackupState = DONE; } break; // 吸出し完了 case DONE: { operationMessage.push_back(::std::string("Backup Done. Pull Out SD Card.")); if(!s_PlayedSdPullOutCursor) { common::PlaySound(common::SOUND_CURSOR); s_PlayedSdPullOutCursor = true; } } break; // SDカード抜き完了 case FINISHED: { operationMessage.push_back(::std::string("Backup Succeeded!!\n")); if(!s_PlayedFinishedSound) { common::PlaySound(common::SOUND_OK); s_PlayedFinishedSound = true; } } break; // 吸出し失敗 case FAIL: { operationMessage.push_back(::std::string("Backup Failed.")); if(!s_PlayedFailSound) { common::PlaySound(common::SOUND_NG); s_PlayedFailSound = true; } } break; } } bool InProgress() { return s_BackupState == EXPORT_CTR_NAND; } bool IsBackupSucceeded() { return s_BackupState == FINISHED; } bool IsBackupFailed() { return s_BackupState == FAIL; } void OnSdEjected() { if(s_BackupState == DONE || s_BackupState == FINISHED) { s_BackupState = FINISHED; } else { common::InitializeFileCheck(); InitializeState(); } } void InitializeState() { s_BackupState = STARTUP; s_PlayedFailSound = false; s_PlayedFinishedSound = false; s_ExistAPSettingAnnotation = false; s_PlayedStartCursor = false; s_PlayedSdPullOutCursor = false; s_SdWriteProetctAnnotation = false; } } // namespace ConsoleBackup