diff --git a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL.ncb b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL.ncb index 882211e..2e8fb5a 100644 Binary files a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL.ncb and b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL.ncb differ diff --git a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL.suo b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL.suo index 407fc4b..ca7e3be 100644 Binary files a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL.suo and b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL.suo differ diff --git a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Debug/BuildLog.htm b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Debug/BuildLog.htm index a36f1a3..e51ff9c 100644 Binary files a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Debug/BuildLog.htm and b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Debug/BuildLog.htm differ diff --git a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form1.h b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form1.h index d1f5fe8..5a4373a 100644 --- a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form1.h +++ b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form1.h @@ -2831,6 +2831,23 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; // ミドルウェアリストの保存(XSL埋め込み) System::Boolean saveMiddlewareListXmlEmbeddedXsl( System::String ^filename ); + // tadの読み出し + System::Void loadTad( System::String ^tadfile ); + + // 提出ファイル名をゲームコードなどから決定 + System::String^ getSubmitFilePrefix(void) + { + System::Byte romver = *this->hSrl->hRomVersion & 0x0F; // 下位1桁 + System::Byte subver = System::Decimal::ToByte(this->numSubmitVersion->Value) & 0x0F; + + System::String ^prefix = "T" + this->hSrl->hGameCode + romver.ToString("X") + subver.ToString("X"); + if( this->isPreliminary() == true ) + { + prefix += "E"; + } + return prefix; + } + private: // ---------------------------------------------- // 一時ファイルの取り扱い @@ -2924,6 +2941,12 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; // フォームの入力をチェックする System::Boolean checkSrlForms(void); + // 事前版かどうか確認する + bool isPreliminary() + { + return this->cboxRemasterVerE->Checked; + } + private: // --------------------------------------------------------------------- // リージョン設定は複雑なので別に切り出す @@ -2997,7 +3020,7 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; void sucMsg( System::String ^msgJ, System::String ^msgE ) { - if( this->stripItemJapanese->Checked ) + if( this->isJapanese() ) MessageBox::Show( msgJ, "Information", MessageBoxButtons::OK, MessageBoxIcon::None ); else MessageBox::Show( msgE, "Information", MessageBoxButtons::OK, MessageBoxIcon::None ); @@ -3006,7 +3029,7 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; // エラーメッセージを出力 void errMsg( System::String ^msgJ, System::String ^msgE ) { - if( this->stripItemJapanese->Checked ) + if( this->isJapanese() ) MessageBox::Show( msgJ, "Error", MessageBoxButtons::OK, MessageBoxIcon::Error ); else MessageBox::Show( msgE, "Error", MessageBoxButtons::OK, MessageBoxIcon::Error ); @@ -3029,6 +3052,16 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; // 言語リソース切り替え void changeLanguage( System::String ^langname ); + // 日本語版かどうか確認する + bool isJapanese() + { + return (this->stripItemJapanese->Checked); + } + bool isEnglish() + { + return (!this->isJapanese()); + } + // -------------------------------------------------------- // エラー情報の登録 // -------------------------------------------------------- @@ -3061,6 +3094,32 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; // SRLのバイナリに影響する項目の中で修正可能なエラーだけをチェック System::Boolean isValidAffectRomModified(void); + private: + // ---------------------------------------------- + // ファイル操作ユーティリティ + // ---------------------------------------------- + + // 直前にアクセスしたディレクトリを記憶して次回のデフォルトにする + System::String ^prevDir; // 初期値はnullptr + + // ファイルをダイアログで取得 + // @arg [in] 拡張子フィルタ + // @ret 取得したファイル名 エラーのとき nullptr + System::String^ openFileDlg( System::String ^filter ); + + // セーブするファイルをダイアログで取得 + // @arg [in] 拡張子フィルタ + // @arg [in] ファイルの拡張子が不正なときに追加するときの正しい拡張子 + // @ret 取得したファイル名 エラーのとき nullptr + System::String^ saveFileDlg( System::String ^filter, System::String ^extension ); + + // セーブするディレクトリをダイアログで取得 + // @ret 取得したディレクトリ名(\\で終わるように調整される) エラーのときnullptr + System::String^ saveDirDlg( System::String ^msgJ, System::String ^msgE ); + + // ファイルが存在するかを調べて上書き確認をする + bool isOverwriteFile( System::String ^path ); + ///////////////////////////////////////////// // タイトルバー操作メソッド ///////////////////////////////////////////// @@ -3089,22 +3148,24 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; System::String^ filename; // ドラッグアンドドロップ以外ではダイアログから入力する + filename = this->openFileDlg( "rom format (*.srl;*.tad)|*.srl;*.tad|All files (*.*)|*.*" ); + if( filename == nullptr ) { - System::Windows::Forms::OpenFileDialog ^dlg = gcnew (OpenFileDialog); - - dlg->InitialDirectory = System::Environment::GetFolderPath( System::Environment::SpecialFolder::Desktop );//"c:\\"; - dlg->Filter = "srl format (*.srl)|*.srl|All files (*.*)|*.*"; - dlg->FilterIndex = 1; - dlg->RestoreDirectory = true; - - if( dlg->ShowDialog() != System::Windows::Forms::DialogResult::OK ) - { - //this->errMsg( "ROMデータファイルのオープンがキャンセルされました。", "Opening the ROM data file is canceled by user." ); - return; - } - filename = dlg->FileName; + //this->errMsg( "ROMデータファイルのオープンがキャンセルされました。", "Opening the ROM data file is canceled by user." ); + return; } - this->loadSrl( filename ); + + // 拡張子で tad 読み込みにするかを判定 + if( System::IO::Path::GetExtension( filename )->ToLower()->Equals( ".tad" ) ) + { + this->loadTad( filename ); + } + else + { + this->loadSrl( filename ); + } + this->tboxFile->Text = filename; + this->clearOtherForms(); //this->sucMsg( "ROMデータファイルのオープンに成功しました。", "The ROM data file is opened successfully." ); } //stripItemOpenRom_Click() @@ -3112,8 +3173,6 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; private: System::Void stripItemMasterRom_Click(System::Object^ sender, System::EventArgs^ e) { - System::String^ filename; - // SRLが読み込まれていないときにはリードさせない if( System::String::IsNullOrEmpty( this->tboxFile->Text ) ) { @@ -3132,76 +3191,47 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; return; } - // SRL名を提出手順書に従わせる - { - filename = gcnew System::String(""); + // 出力ファイル名をゲームコードなどから強制的に決める + System::String ^prefix = this->getSubmitFilePrefix(); + System::String ^srlfile = prefix + ".SRL"; - if( this->cboxRemasterVerE->Checked == true ) - { - filename = "T" + this->hSrl->hGameCode + "E" - + System::Decimal::ToByte(this->numSubmitVersion->Value).ToString("X") + ".SRL"; - } - else - { - filename = "T" + this->hSrl->hGameCode + this->hSrl->hRomVersion->ToString("X") - + System::Decimal::ToByte(this->numSubmitVersion->Value).ToString("X") + ".SRL"; - } - } + // 注意書き + this->sucMsg( + "以下のファイルが作成されます。\n\n" + + srlfile + " (マスターROM)\n", + + "Following file for submission will be made. \n\n" + + srlfile + " (Master ROM)\n" + ); - // 注意書き - { - this->sucMsg( - "提出手順書にしたがい、ROMデータファイル名は \"" + filename + "\"となります。\n" + "\nROMデータファイルを保存するフォルダを選択してください。", - "ROM data file name is \"" + filename + "\".\n" + "\nPlease select a folder in which the ROM data is saved." - ); - } // ダイアログからSRLを保存するディレクトリを取得する + System::String ^dir = this->saveDirDlg( "保存先フォルダを選択してください。", "Please select a folder for saving the file" ); + if( !dir ) { - System::Windows::Forms::FolderBrowserDialog ^dlg = gcnew (System::Windows::Forms::FolderBrowserDialog); - - if( dlg->ShowDialog() != System::Windows::Forms::DialogResult::OK ) - { - this->errMsg( "フォルダの選択がキャンセルされましたのでマスターROMは作成されません。", - "A submission sheet can not be made, since selecting folder is canceled." ); - return; - } - else - { - if( !dlg->SelectedPath->EndsWith("\\") ) - { - filename = dlg->SelectedPath + "\\" + filename; - } - else - { - filename = dlg->SelectedPath + filename; - } - } - if( System::IO::File::Exists( filename ) ) - { - System::String ^msg; - if( this->stripItemJapanese->Checked ) - msg = gcnew System::String( filename + "はすでに存在します。上書きしますか?" ); - else - msg = gcnew System::String( filename + "already exists. Overwrite it?" ); - if( MessageBox::Show( msg, "Information", MessageBoxButtons::YesNo, MessageBoxIcon::None ) - == System::Windows::Forms::DialogResult::No ) - { - this->errMsg( "マスターROMの作成をキャンセルしました。", - "Making a master ROM is canceled." ); - return; - } - } + this->errMsg( "フォルダの選択がキャンセルされましたのでマスターROMは作成されません。", + "A master ROM isn't made, since selecting folder is canceled." ); + return; } + srlfile = dir + srlfile; + + // ファイルが存在するかを調べて上書き確認をする + if( !this->isOverwriteFile(srlfile) ) + { + this->errMsg( "ファイルの上書きがキャンセルされましたのでマスターROMは作成されません。", + "Since overwriting a file is canceled, a master ROM isn't made." ); + return; + } + try { - if( !this->saveSrl( filename ) ) + if( !this->saveSrl( srlfile ) ) { this->errMsg( "マスターROMの作成に失敗しました。", "Making a master ROM failed." ); return; } - this->sucMsg( "マスターROMの作成が成功しました。", "Making the ROM data file succeeded." ); - this->tboxFile->Text = filename; + this->sucMsg( "マスターROMの作成が成功しました。", "A master ROM is made successfully." ); + this->tboxFile->Text = srlfile; } catch( System::Exception ^ex ) { @@ -3240,132 +3270,52 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; return; } - // SRL名を提出手順書に従わせる - System::String ^srlfile; - { - srlfile = gcnew System::String(""); + // 出力ファイル名をゲームコードなどから強制的に決める + System::String ^prefix = this->getSubmitFilePrefix(); + System::String ^srlfile = prefix + ".SRL"; + System::String ^delivfile = prefix + "_SHEET.XML"; + System::String ^middlefile = prefix + "_MIDDLEWARE.XML"; + System::String ^middlefilePrint = prefix + "_MIDDLEWARE.HTML"; - if( this->cboxRemasterVerE->Checked == true ) - { - srlfile = "T" + this->hSrl->hGameCode + "E" - + System::Decimal::ToByte(this->numSubmitVersion->Value).ToString("X") + ".SRL"; - } - else - { - srlfile = "T" + this->hSrl->hGameCode + this->hSrl->hRomVersion->ToString("X") - + System::Decimal::ToByte(this->numSubmitVersion->Value).ToString("X") + ".SRL"; - } - } + // 注意書き + this->sucMsg( + "以下の提出ファイルが一度に作成されます。\n\n" + + srlfile + " (マスターROM)\n" + + delivfile + " (マスターROM提出確認書)\n" + + middlefile + " (ミドルウェア一覧)\n" + + middlefilePrint + " (ミドルウェア一覧 印刷用)\n" + + "\n", - // 注意書き - { - this->sucMsg( - "Step1/3: ROMデータファイルと提出確認書の情報を一致させるため、まず、入力情報を反映させたマスターROMデータファイルを作成します。\n(キャンセルされたとき、提出データ一式は作成されません。)\n" - + "\n マスターROMデータファイル名は \"" + srlfile + "\"となります。\n" + "\nマスターROMデータファイルを保存するフォルダを選択してください。", - "Step1/3: Firstly, We make a master ROM file because all information in a submission sheet are match those in the ROM data file.\n(When it is canceled, both A set of submission data is not made.)\n" - + "\n The name of the master ROM data file is \"" + srlfile + "\".\n" + "\nPlease select a folder in which the ROM data is saved." - ); - } + "Following files for submission will be made. \n\n" + + srlfile + " (Master ROM)\n" + + delivfile + " (Submission Sheet)\n" + + middlefile + " (Middleware List)\n" + + middlefilePrint + " (Middleware List For Print)\n" + + "\n" + ); // ダイアログからSRLを保存するディレクトリを取得する - System::String ^delivfile; + System::String ^dir = this->saveDirDlg( "保存先フォルダを選択してください。", "Please select a folder for saving files" ); + if( !dir ) { - System::Windows::Forms::FolderBrowserDialog ^dlg = gcnew (System::Windows::Forms::FolderBrowserDialog); - - if( dlg->ShowDialog() != System::Windows::Forms::DialogResult::OK ) - { - this->errMsg( "フォルダの選択がキャンセルされましたので提出データ一式は作成されません。", - "A set of submission data can not be made, since selecting folder is canceled." ); - return; - } - else - { - if( !dlg->SelectedPath->EndsWith("\\") ) - { - srlfile = dlg->SelectedPath + "\\" + srlfile; - } - else - { - srlfile = dlg->SelectedPath + srlfile; - } - } - if( System::IO::File::Exists( srlfile ) ) - { - System::String ^msg; - if( this->stripItemJapanese->Checked ) - msg = gcnew System::String( srlfile + "はすでに存在します。上書きしますか?" ); - else - msg = gcnew System::String( srlfile + "already exists. Overwrite it?" ); - if( MessageBox::Show( msg, "Information", MessageBoxButtons::YesNo, MessageBoxIcon::None ) - == System::Windows::Forms::DialogResult::No ) - { - this->errMsg( "ファイルの上書きがキャンセルされましたので提出データ一式は作成されません。", - "Since overwriting a file is canceled, a set of submission data can not be made." ); - return; - } - } - + this->errMsg( "フォルダの選択がキャンセルされましたので提出データ一式は作成されません。", + "A set of submission data can not be made, since selecting folder is canceled." ); + return; } + srlfile = dir + srlfile; + delivfile = dir + delivfile; + middlefile = dir + middlefile; + middlefilePrint = dir + middlefilePrint; - // 注意書き + // ファイルが存在するかを調べて上書き確認をする + if( !this->isOverwriteFile(srlfile) || !this->isOverwriteFile(delivfile) || + !this->isOverwriteFile(middlefile) || !this->isOverwriteFile(middlefilePrint) ) { - this->sucMsg( - "Step2/3: 続いて、使用されているミドルウェアのリストを作成します。\nここでキャンセルされたとき、提出データ一式は作成されませんのでご注意ください。", - "Step2/3: Secondly, We should make a list of middlewares used by the ROM. \n(CAUTION: When it is canceled, A set of submission data is not made.)" - ); + this->errMsg( "ファイルの上書きがキャンセルされましたので提出データ一式は作成されません。", + "Since overwriting a file is canceled, a set of submission data can not be made." ); + return; } - // ダイアログでファイルパスを決定 - System::String ^middlefile; - { - System::Windows::Forms::SaveFileDialog ^dlg = gcnew (SaveFileDialog); - - dlg->InitialDirectory = System::Environment::GetFolderPath( System::Environment::SpecialFolder::Desktop );//"c:\\"; - dlg->Filter = "xml format (*.xml)|*.xml"; - dlg->FilterIndex = 1; - dlg->RestoreDirectory = true; - - if( dlg->ShowDialog() != System::Windows::Forms::DialogResult::OK ) - { - this->errMsg( "ミドルウェアリストの作成がキャンセルされました。提出データ一式は作成されません。", - "Making a list of middlewares is canceled. A set of submission data is not made." ); - return; - } - middlefile = dlg->FileName; - if( !(dlg->FileName->EndsWith( ".xml" )) ) - { - middlefile += ".xml"; - } - } - - // 注意書き - { - this->sucMsg( - "Step3/3: 続いて、提出確認書を作成します。\nここでキャンセルされたとき、提出データ一式は作成されませんのでご注意ください。", - "Step3/3: Finally, We should make a submission sheet. \n(CAUTION: When it is canceled, A set of submission data is not made, but also the master ROM data and a list of middleware are not made.)" - ); - } - // ダイアログでファイルパスを決定 - { - System::Windows::Forms::SaveFileDialog ^dlg = gcnew (SaveFileDialog); - - dlg->InitialDirectory = System::Environment::GetFolderPath( System::Environment::SpecialFolder::Desktop );//"c:\\"; - dlg->Filter = "xml format (*.xml)|*.xml"; - dlg->FilterIndex = 1; - dlg->RestoreDirectory = true; - - if( dlg->ShowDialog() != System::Windows::Forms::DialogResult::OK ) - { - this->errMsg( "提出確認書の作成がキャンセルされました。提出データ一式は作成されません。", - "Making a submission sheet is canceled. A set of submission data is not made." ); - return; - } - delivfile = dlg->FileName; - if( !(dlg->FileName->EndsWith( ".xml" )) ) - { - delivfile += ".xml"; - } - } - + // マスタ提出確認書に必要な情報をフォームから取得して更新 this->setSrlProperties(); // 先にSrlを更新しておく this->setDeliverableProperties(); @@ -3375,8 +3325,8 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; { if( !this->saveSrl( srlfile ) ) { - this->errMsg( "マスターROMの作成に失敗しました。提出確認書およびミドルウェアリストは作成されません。", - "Making a master ROM failed. And a submission sheet and a list of middlewares are not made." ); + this->errMsg( "マスターROMの作成に失敗しました。作成を中止するため一部のファイルは作成されません。", + "Making a master ROM failed. Therefore, a part of files can't be made." ); return; } this->tboxFile->Text = srlfile; @@ -3384,15 +3334,15 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; catch( System::Exception ^ex ) { (void)ex; - this->errMsg( "マスターROMの作成に失敗しました。提出確認書およびミドルウェアリストは作成されません。", - "Making a master ROM failed. And a submission sheet and a list of middlewares are not made." ); + this->errMsg( "マスターROMの作成に失敗しました。作成を中止するため一部のファイルは作成されません。", + "Making a master ROM failed. Therefore, a part of files can't be made." ); return; } u16 crc; // SRL全体のCRCを計算する(書類に記述するため) if( !getWholeCRCInFile( srlfile, &crc ) ) { - this->errMsg( "CRCの計算に失敗しました。提出確認書およびミドルウェアリストは作成されません。", - "Calc CRC is failed. Therefore, And a submission sheet and a list of middlewares are not made." ); + this->errMsg( "CRCの計算に失敗しました。作成を中止するため一部のファイルは作成されません。", + "Calculating CRC is failed. Therefore, a part of files can't be made." ); return; } System::UInt16 ^hcrc = gcnew System::UInt16( crc ); @@ -3401,18 +3351,17 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; this->tboxWholeCRC->AppendText( hcrc->ToString("X") ); // ミドルウェアのリストを作成 - if( !this->saveMiddlewareListXmlEmbeddedXsl( middlefile ) ) + if( !this->saveMiddlewareListXmlEmbeddedXsl( middlefile ) || !this->saveMiddlewareListHtml( middlefilePrint ) ) { - this->errMsg( "ミドルウェアのリストが作成できませんでした。提出確認書は作成されません。", - "Making a list of middleware failed. And a submission sheet is not made."); + this->errMsg( "ミドルウェアのリストが作成できませんでした。作成を中止するため一部のファイルは作成されません。", + "Making a list of middleware failed. Therefore, a part of files can't be made."); return; } // 書類作成 - cli::array ^paths = srlfile->Split(L'\\'); // 余分なパスを削除 - srlfile = paths[ paths->Length - 1 ]; - //result = this->hDeliv->write( delivfile, this->hSrl, hcrc, srlfile, !(this->stripItemJapanese->Checked) ); - result = this->hDeliv->writeSpreadsheet( delivfile, this->hSrl, hcrc, srlfile, !(this->stripItemJapanese->Checked) ); + srlfile = System::IO::Path::GetFileName( srlfile ); + //result = this->hDeliv->write( delivfile, this->hSrl, hcrc, srlfile, !this->isJapanese() ); + result = this->hDeliv->writeSpreadsheet( delivfile, this->hSrl, hcrc, srlfile, !this->isJapanese() ); if( result != ECDeliverableResult::NOERROR ) { switch( result ) @@ -3433,33 +3382,18 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; } return; } - this->sucMsg( "提出データ一式の作成に成功しました。", "The submission sheet is made successfully." ); + this->sucMsg( "提出データ一式の作成に成功しました。", "A set of submission data is made successfully." ); } //stripItemSheet_Click() private: System::Void stripItemSaveTemp_Click(System::Object^ sender, System::EventArgs^ e) { - System::String ^filename = gcnew System::String(""); + System::String ^filename = this->saveFileDlg( "xml format (*.xml)|*.xml", ".xml" ); - // ダイアログでファイルパスを決定 + if( !filename ) { - System::Windows::Forms::SaveFileDialog ^dlg = gcnew (SaveFileDialog); - - dlg->InitialDirectory = System::Environment::GetFolderPath( System::Environment::SpecialFolder::Desktop );//"c:\\"; - dlg->Filter = "xml format (*.xml)|*.xml"; - dlg->FilterIndex = 1; - dlg->RestoreDirectory = true; - - if( dlg->ShowDialog() != System::Windows::Forms::DialogResult::OK ) - { - return; - } - filename = dlg->FileName; - if( !(dlg->FileName->EndsWith( ".xml" )) ) - { - filename += ".xml"; - } + return; } this->saveTmp( filename ); } //stripItemSaveTemp_Click() @@ -3467,26 +3401,11 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; private: System::Void stripItemLoadTemp_Click(System::Object^ sender, System::EventArgs^ e) { - System::String ^filename = gcnew System::String(""); + System::String ^filename = this->openFileDlg( "xml format (*.xml)|*.xml" ); - // ダイアログでファイルパスを決定 + if( filename == nullptr ) { - System::Windows::Forms::OpenFileDialog ^dlg = gcnew (OpenFileDialog); - - dlg->InitialDirectory = System::Environment::GetFolderPath( System::Environment::SpecialFolder::Desktop );//"c:\\"; - dlg->Filter = "xml format (*.xml)|*.xml"; - dlg->FilterIndex = 1; - dlg->RestoreDirectory = true; - - if( dlg->ShowDialog() != System::Windows::Forms::DialogResult::OK ) - { - return; - } - filename = dlg->FileName; - if( !(dlg->FileName->EndsWith( ".xml" )) ) - { - filename += ".xml"; - } + return; } this->loadTmp( filename ); } //stripItemLoadTemp_Click() @@ -3494,34 +3413,15 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; private: System::Void stripItemMiddlewareXml_Click(System::Object^ sender, System::EventArgs^ e) { - System::String ^filename = gcnew System::String(""); - if( System::String::IsNullOrEmpty(this->tboxFile->Text) ) { this->errMsg( "ROMデータファイルが読み込まれていません。", "ROM file has not opened yet." ); return; } - // ダイアログでファイルパスを決定 - { - System::Windows::Forms::SaveFileDialog ^dlg = gcnew (SaveFileDialog); + System::String ^filename = this->saveFileDlg( "xml format (*.xml)|*.xml", ".xml" ); - dlg->InitialDirectory = System::Environment::GetFolderPath( System::Environment::SpecialFolder::Desktop );//"c:\\"; - dlg->Filter = "xml format (*.xml)|*.xml"; - dlg->FilterIndex = 1; - dlg->RestoreDirectory = true; - - if( dlg->ShowDialog() != System::Windows::Forms::DialogResult::OK ) - { - return; - } - filename = dlg->FileName; - if( !(dlg->FileName->EndsWith( ".xml" )) ) - { - filename += ".xml"; - } - } - if( !this->saveMiddlewareListXmlEmbeddedXsl(filename) ) + if( !filename || !this->saveMiddlewareListXmlEmbeddedXsl(filename) ) { this->errMsg( "ミドルウェアリストの作成に失敗しました。","Making a middleware list failed." ); } @@ -3530,34 +3430,15 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; private: System::Void stripItemMiddlewareHtml_Click(System::Object^ sender, System::EventArgs^ e) { - System::String ^filename = gcnew System::String(""); - if( System::String::IsNullOrEmpty(this->tboxFile->Text) ) { this->errMsg( "ROMデータファイルがオープンされていません。", "ROM file has not opened yet." ); return; } - // ダイアログでファイルパスを決定 - { - System::Windows::Forms::SaveFileDialog ^dlg = gcnew (SaveFileDialog); + System::String ^filename = this->saveFileDlg( "html format (*.html)|*.html", ".html" ); - dlg->InitialDirectory = System::Environment::GetFolderPath( System::Environment::SpecialFolder::Desktop );//"c:\\"; - dlg->Filter = "html format (*.html)|*.html"; - dlg->FilterIndex = 1; - dlg->RestoreDirectory = true; - - if( dlg->ShowDialog() != System::Windows::Forms::DialogResult::OK ) - { - return; - } - filename = dlg->FileName; - if( !(dlg->FileName->EndsWith( ".html" )) ) - { - filename += ".html"; - } - } - if( !this->saveMiddlewareListHtml(filename) ) + if( !filename || !this->saveMiddlewareListXmlEmbeddedXsl(filename) ) { this->errMsg( "ミドルウェアリストの作成に失敗しました。","Making a middleware list failed." ); } @@ -3591,6 +3472,7 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; return; } this->loadSrl( filename ); // ドラッグアンドドロップの時点でボタンを押さなくてもファイルを開く + this->tboxFile->Text = filename; this->clearOtherForms(); //this->sucMsg( "ROMデータファイルのオープンに成功しました。", "The ROM data file is opened successfully." ); } @@ -3635,8 +3517,8 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; private: System::Void cboxRemasterVerE_CheckedChanged(System::Object^ sender, System::EventArgs^ e) { - //this->numRemasterVer->Enabled = !(this->cboxRemasterVerE->Checked); - //if( this->cboxRemasterVerE->Checked == false ) + //this->numRemasterVer->Enabled = !(this->isEngilsh()); + //if( this->isEngilsh() == false ) //{ // this->numRemasterVer->Value = 0; //} @@ -3726,10 +3608,6 @@ private: System::Windows::Forms::DataGridViewTextBoxColumn^ colWarnCause; this->loadOtherForms(); // SRLに登録されていないROM仕様のフォームも戻す } - - - - }; // enf of ref class Form1 } // end of namespace MasterEditorTWL diff --git a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_deliv.cpp b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_deliv.cpp index c8ce7dc..1755313 100644 --- a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_deliv.cpp +++ b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_deliv.cpp @@ -104,7 +104,7 @@ void Form1::setDeliverableProperties(void) // 会社情報 this->hDeliv->hCompany1 = this->tboxCompany1->Text + " " + this->tboxDepart1->Text; this->hDeliv->hPerson1 = this->tboxPerson1->Text; - if( this->stripItemJapanese->Checked == true ) + if( this->isJapanese() == true ) { this->hDeliv->hFurigana1 = this->tboxFurigana1->Text; } @@ -115,7 +115,7 @@ void Form1::setDeliverableProperties(void) this->hDeliv->hTel1 = this->tboxTel1->Text; this->hDeliv->hFax1 = this->tboxFax1->Text; this->hDeliv->hMail1 = this->tboxMail1->Text; - if( this->stripItemJapanese->Checked == true ) + if( this->isJapanese() == true ) { this->hDeliv->hNTSC1 = this->tboxNTSC1->Text; } @@ -127,7 +127,7 @@ void Form1::setDeliverableProperties(void) { this->hDeliv->hCompany2 = this->tboxCompany2->Text + " " + this->tboxDepart2->Text; this->hDeliv->hPerson2 = this->tboxPerson2->Text; - if( this->stripItemJapanese->Checked == true ) + if( this->isJapanese() == true ) { this->hDeliv->hFurigana2 = this->tboxFurigana2->Text; } @@ -138,7 +138,7 @@ void Form1::setDeliverableProperties(void) this->hDeliv->hTel2 = this->tboxTel2->Text; this->hDeliv->hFax2 = this->tboxFax2->Text; this->hDeliv->hMail2 = this->tboxMail2->Text; - if( this->stripItemJapanese->Checked == true ) + if( this->isJapanese() == true ) { this->hDeliv->hNTSC2 = this->tboxNTSC2->Text; } @@ -202,7 +202,7 @@ void Form1::setDeliverableProperties(void) // SRL情報を文字列で登録 if( this->combRegion->SelectedIndex < 0 ) { - if( this->stripItemJapanese->Checked == true ) + if( this->isJapanese() == true ) this->hDeliv->hRegion = gcnew System::String("不明"); else this->hDeliv->hRegion = gcnew System::String("Undefined"); @@ -213,7 +213,7 @@ void Form1::setDeliverableProperties(void) } if( this->combCERO->SelectedIndex < 0 ) { - if( this->stripItemJapanese->Checked == true ) + if( this->isJapanese() == true ) this->hDeliv->hCERO = gcnew System::String("不可"); else this->hDeliv->hCERO = gcnew System::String("Undefined"); @@ -224,7 +224,7 @@ void Form1::setDeliverableProperties(void) } if( this->combESRB->SelectedIndex < 0 ) { - if( this->stripItemJapanese->Checked == true ) + if( this->isJapanese() == true ) this->hDeliv->hESRB = gcnew System::String("不可"); else this->hDeliv->hESRB = gcnew System::String("Undefined"); @@ -235,7 +235,7 @@ void Form1::setDeliverableProperties(void) } if( this->combUSK->SelectedIndex < 0 ) { - if( this->stripItemJapanese->Checked == true ) + if( this->isJapanese() == true ) this->hDeliv->hUSK = gcnew System::String("不可"); else this->hDeliv->hUSK = gcnew System::String("Undefined"); @@ -246,7 +246,7 @@ void Form1::setDeliverableProperties(void) } if( this->combPEGI->SelectedIndex < 0 ) { - if( this->stripItemJapanese->Checked == true ) + if( this->isJapanese() == true ) this->hDeliv->hPEGI = gcnew System::String("不可"); else this->hDeliv->hPEGI = gcnew System::String("Undefined"); @@ -257,7 +257,7 @@ void Form1::setDeliverableProperties(void) } if( this->combPEGI_PRT->SelectedIndex < 0 ) { - if( this->stripItemJapanese->Checked == true ) + if( this->isJapanese() == true ) this->hDeliv->hPEGI_PRT = gcnew System::String("不可"); else this->hDeliv->hPEGI_PRT = gcnew System::String("Undefined"); @@ -268,7 +268,7 @@ void Form1::setDeliverableProperties(void) } if( this->combPEGI_BBFC->SelectedIndex < 0 ) { - if( this->stripItemJapanese->Checked == true ) + if( this->isJapanese() == true ) this->hDeliv->hPEGI_BBFC = gcnew System::String("不可"); else this->hDeliv->hPEGI_BBFC = gcnew System::String("Undefined"); @@ -279,7 +279,7 @@ void Form1::setDeliverableProperties(void) } if( this->combOFLC->SelectedIndex < 0 ) { - if( this->stripItemJapanese->Checked == true ) + if( this->isJapanese() == true ) this->hDeliv->hOFLC = gcnew System::String("不可"); else this->hDeliv->hOFLC = gcnew System::String("Undefined"); @@ -321,14 +321,14 @@ System::Boolean Form1::checkDeliverableForms(void) this->checkTextForm( this->tboxPerson1->Text, LANG_PERSON_J, LANG_PERSON_E, false ); this->checkTextForm( this->tboxCompany1->Text, LANG_COMPANY_J, LANG_COMPANY_E, false ); this->checkTextForm( this->tboxDepart1->Text, LANG_DEPART_J, LANG_DEPART_E, false ); - if( this->stripItemJapanese->Checked == true ) + if( this->isJapanese() == true ) { this->checkTextForm( this->tboxFurigana1->Text, LANG_FURIGANA_J, LANG_FURIGANA_J, false ); } this->checkTextForm( this->tboxTel1->Text, LANG_TEL_J, LANG_TEL_E, false ); //this->checkTextForm( this->tboxFax1->Text, LANG_FAX_J, LANG_FAX_E, false ); this->checkTextForm( this->tboxMail1->Text, LANG_MAIL_J, LANG_MAIL_E, false ); - //if( this->stripItemJapanese->Checked == true ) + //if( this->isJapanese() == true ) //{ // this->checkTextForm( this->tboxNTSC1->Text, LANG_NTSC_1_J + " " + LANG_NTSC_2_J, LANG_NTSC_1_J + " " + LANG_NTSC_2_J, false ); //} @@ -338,14 +338,14 @@ System::Boolean Form1::checkDeliverableForms(void) this->checkTextForm( this->tboxPerson2->Text, LANG_PERSON_J, LANG_PERSON_E, false ); this->checkTextForm( this->tboxCompany2->Text, LANG_COMPANY_J, LANG_COMPANY_E, false ); this->checkTextForm( this->tboxDepart2->Text, LANG_DEPART_J, LANG_DEPART_E, false ); - if( this->stripItemJapanese->Checked == true ) + if( this->isJapanese() == true ) { this->checkTextForm( this->tboxFurigana2->Text, LANG_FURIGANA_J, LANG_FURIGANA_J, false ); } this->checkTextForm( this->tboxTel2->Text, LANG_TEL_J, LANG_TEL_E, false ); //this->checkTextForm( this->tboxFax2->Text, LANG_FAX_J, LANG_FAX_E, false ); this->checkTextForm( this->tboxMail2->Text, LANG_MAIL_J, LANG_MAIL_E, false ); - //if( this->stripItemJapanese->Checked == true ) + //if( this->isJapanese() == true ) //{ // this->checkTextForm( this->tboxNTSC2->Text, LANG_NTSC_1_J + " " + LANG_NTSC_2_J, LANG_NTSC_1_J + " " + LANG_NTSC_2_J, false ); //} diff --git a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_file.cpp b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_file.cpp index 340020e..160b9e9 100644 --- a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_file.cpp +++ b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_file.cpp @@ -10,6 +10,7 @@ #include "crc_whole.h" #include "utility.h" #include "lang.h" +#include "split_tad.h" #include "FormError.h" #include "Form1.h" @@ -21,7 +22,10 @@ using namespace System::Data; using namespace System::Drawing; using namespace MasterEditorTWL; +// ---------------------------------------------- // 設定ファイルの読み込み +// ---------------------------------------------- + void Form1::loadInit(void) { System::Xml::XmlDocument ^doc = gcnew System::Xml::XmlDocument(); @@ -137,7 +141,10 @@ void Form1::loadInit(void) } } // loadInit() +// ---------------------------------------------- // SRLのオープン +// ---------------------------------------------- + System::Void Form1::loadSrl( System::String ^filename ) { ECSrlResult result = this->hSrl->readFromFile( filename ); @@ -163,7 +170,6 @@ System::Void Form1::loadSrl( System::String ^filename ) } return; } - this->tboxFile->Text = filename; // GUIにROM情報を格納 this->setSrlForms(); @@ -203,7 +209,10 @@ System::Void Form1::loadSrl( System::String ^filename ) return; } // loadSrl() +// ---------------------------------------------- // SRLの保存 +// ---------------------------------------------- + System::Boolean Form1::saveSrl( System::String ^filename ) { // コピーしたファイルにROMヘッダを上書き @@ -214,10 +223,10 @@ System::Boolean Form1::saveSrl( System::String ^filename ) // 再リード this->loadSrl( filename ); + this->tboxFile->Text = filename; return true; } // saveSrl() -// SRLの保存 System::Boolean Form1::saveSrlCore( System::String ^filename ) { // ROM情報をフォームから取得してSRLバイナリに反映させる @@ -237,7 +246,21 @@ System::Boolean Form1::saveSrlCore( System::String ^filename ) return true; } +// ---------------------------------------------- +// tadのオープン +// ---------------------------------------------- + +System::Void Form1::loadTad( System::String ^tadfile ) +{ + System::String ^srlfile = System::IO::Path::GetDirectoryName( System::Reflection::Assembly::GetEntryAssembly()->Location ) + + "\\tmp.srl"; + splitTad( tadfile, srlfile ); +} + +// ---------------------------------------------- // ミドルウェアリストの作成 +// ---------------------------------------------- + System::Void Form1::makeMiddlewareListXml(System::Xml::XmlDocument^ doc) { System::Xml::XmlElement ^root = doc->CreateElement( "twl-master-editor" ); @@ -276,7 +299,10 @@ System::Void Form1::makeMiddlewareListXml(System::Xml::XmlDocument^ doc) } } -// ミドルウェアリストの保存 +// ---------------------------------------------- +// ミドルウェアリストの保存(XML) +// ---------------------------------------------- + System::Boolean Form1::saveMiddlewareListXml( System::String ^filename ) { System::Xml::XmlDocument ^doc = gcnew System::Xml::XmlDocument(); @@ -296,7 +322,10 @@ System::Boolean Form1::saveMiddlewareListXml( System::String ^filename ) return true; } -// ミドルウェアリストの保存 +// ---------------------------------------------- +// ミドルウェアリストの保存(XSL埋め込みXML) +// ---------------------------------------------- + System::Boolean Form1::saveMiddlewareListXmlEmbeddedXsl( System::String ^filename ) { System::Xml::XmlDocument ^doc = gcnew System::Xml::XmlDocument(); @@ -336,7 +365,10 @@ System::Boolean Form1::saveMiddlewareListXmlEmbeddedXsl( System::String ^filenam return true; } +// ---------------------------------------------- // ミドルウェアリストの保存(XML->HTML変換) +// ---------------------------------------------- + System::Boolean Form1::saveMiddlewareListHtml( System::String ^filename ) { System::Xml::Xsl::XslCompiledTransform ^xslt = gcnew System::Xml::Xsl::XslCompiledTransform; @@ -361,3 +393,4 @@ System::Boolean Form1::saveMiddlewareListHtml( System::String ^filename ) System::IO::File::Delete( tmpxml ); return true; } + diff --git a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_srl.cpp b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_srl.cpp index 44f12e0..1e06546 100644 --- a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_srl.cpp +++ b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_srl.cpp @@ -232,14 +232,14 @@ void Form1::setSrlFormsCaptionEx() System::String ^appother = gcnew System::String(""); if( *(this->hSrl->hIsLaunch) == false ) { - if( this->stripItemJapanese->Checked == true ) + if( this->isJapanese() == true ) appother += "ランチャー非表示.\r\n"; else appother += "Not Display On the Launcher.\r\n"; } if( *(this->hSrl->hIsDataOnly) == true ) { - if( this->stripItemJapanese->Checked == true ) + if( this->isJapanese() == true ) appother += "データ専用.\r\n"; else appother += "Data Only.\r\n"; @@ -249,14 +249,14 @@ void Form1::setSrlFormsCaptionEx() this->tboxCaptionEx->Clear(); if( (this->hSrl->hHasDSDLPlaySign != nullptr) && (*(this->hSrl->hHasDSDLPlaySign) == true) ) { - if( this->stripItemJapanese->Checked == true ) + if( this->isJapanese() == true ) this->tboxCaptionEx->Text += gcnew System::String( "DSクローンブート対応.\r\n" ); else this->tboxCaptionEx->Text += gcnew System::String( "DS Clone Boot.\r\n" ); } if( (this->hSrl->hIsSCFGAccess != nullptr) && (*(this->hSrl->hIsSCFGAccess) == true) ) { - if( this->stripItemJapanese->Checked == true ) + if( this->isJapanese() == true ) this->tboxCaptionEx->Text += gcnew System::String( "SCFGレジスタアクセス可能.\r\n" ); else this->tboxCaptionEx->Text += gcnew System::String( "SDFC Register Accessible.\r\n" ); diff --git a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_tmp.cpp b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_tmp.cpp index 0d3261f..6a6d830 100644 --- a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_tmp.cpp +++ b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_tmp.cpp @@ -34,7 +34,7 @@ System::Void Form1::saveTmp( System::String ^filename ) MasterEditorTWL::appendXmlTag( doc, root, "Srl", this->tboxFile->Text ); // 言語 - MasterEditorTWL::appendXmlTag( doc, root, "Lang", (this->stripItemJapanese->Checked)?"J":"E" ); + MasterEditorTWL::appendXmlTag( doc, root, "Lang", (this->isJapanese())?"J":"E" ); // フォーム System::Xml::XmlElement ^form = doc->CreateElement( "Form" ); @@ -136,6 +136,7 @@ void Form1::loadTmp( System::String ^filename ) if( !System::String::IsNullOrEmpty(text) ) // SRLファイル名がないときはスルー { this->loadSrl(text); + this->tboxFile->Text = filename; } // 言語 diff --git a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_util.cpp b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_util.cpp index 6c67019..39381c2 100644 --- a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_util.cpp +++ b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/Form_util.cpp @@ -90,7 +90,7 @@ void Form1::setGridError( void ) { for each( RCMrcError ^err in this->hSrl->hErrorList ) { - this->gridError->Rows->Add( err->getAll( this->stripItemJapanese->Checked ) ); + this->gridError->Rows->Add( err->getAll(this->isJapanese()) ); this->colorGridError( err ); } } @@ -103,7 +103,7 @@ void Form1::setGridWarn( void ) { for each( RCMrcError ^err in this->hSrl->hWarnList ) { - this->gridWarn->Rows->Add( err->getAll( this->stripItemJapanese->Checked ) ); + this->gridWarn->Rows->Add( err->getAll(this->isJapanese()) ); this->colorGridWarn( err ); } } @@ -119,7 +119,7 @@ void Form1::overloadGridError( void ) { if( !err->EnableModify ) // 修正可能な情報は表示しない { - this->gridError->Rows->Add( err->getAll( this->stripItemJapanese->Checked ) ); + this->gridError->Rows->Add( err->getAll(this->isJapanese()) ); this->colorGridError( err ); } } @@ -128,7 +128,7 @@ void Form1::overloadGridError( void ) { for each( RCMrcError ^err in this->hErrorList ) { - this->gridError->Rows->Add( err->getAll( this->stripItemJapanese->Checked ) ); + this->gridError->Rows->Add( err->getAll(this->isJapanese()) ); this->colorGridError( err ); } } @@ -142,7 +142,7 @@ void Form1::overloadGridWarn( void ) { if( !err->EnableModify ) { - this->gridWarn->Rows->Add( err->getAll( this->stripItemJapanese->Checked ) ); + this->gridWarn->Rows->Add( err->getAll(this->isJapanese()) ); this->colorGridWarn( err ); } } @@ -151,7 +151,7 @@ void Form1::overloadGridWarn( void ) { for each( RCMrcError ^err in this->hWarnList ) { - this->gridWarn->Rows->Add( err->getAll( this->stripItemJapanese->Checked ) ); + this->gridWarn->Rows->Add( err->getAll(this->isJapanese()) ); this->colorGridWarn( err ); } } @@ -262,4 +262,125 @@ System::Boolean Form1::isValidAffectRomModified(void) return (count == 0); } +// ---------------------------------------------- +// ファイル操作ユーティリティ +// ---------------------------------------------- + +// ファイルをダイアログで取得 +// @arg [in] 拡張子フィルタ +// @ret 取得したファイル名 エラーのとき nullptr +System::String^ Form1::openFileDlg( System::String ^filter ) +{ + System::Windows::Forms::OpenFileDialog ^dlg = gcnew (OpenFileDialog); + if( System::String::IsNullOrEmpty( this->prevDir ) || !System::IO::Directory::Exists( this->prevDir ) ) + { + dlg->InitialDirectory = System::Environment::GetFolderPath( System::Environment::SpecialFolder::Desktop ); + } + else + { + dlg->InitialDirectory = this->prevDir; // 前に選んだディレクトリをデフォルトにする + } + dlg->Filter = filter; + dlg->FilterIndex = 1; + dlg->RestoreDirectory = true; + + if( dlg->ShowDialog() != System::Windows::Forms::DialogResult::OK ) + { + return nullptr; + } + this->prevDir = System::IO::Path::GetDirectoryName( dlg->FileName ); // デフォルトディレクトリの更新 + return System::String::Copy(dlg->FileName); +} + +// セーブするファイルをダイアログで取得 +// @arg [in] 拡張子フィルタ +// @arg [in] ファイルの拡張子が不正なときに追加するときの正しい拡張子 +// @ret 取得したファイル名 エラーのとき nullptr +System::String^ Form1::saveFileDlg( System::String ^filter, System::String ^extension ) +{ + System::String ^retfile; + System::Windows::Forms::SaveFileDialog ^dlg = gcnew (SaveFileDialog); + + if( System::String::IsNullOrEmpty( this->prevDir ) || !System::IO::Directory::Exists( this->prevDir ) ) + { + dlg->InitialDirectory = System::Environment::GetFolderPath( System::Environment::SpecialFolder::Desktop ); + } + else + { + dlg->InitialDirectory = this->prevDir; + } + dlg->Filter = filter; + dlg->FilterIndex = 1; + dlg->RestoreDirectory = true; + + if( dlg->ShowDialog() != System::Windows::Forms::DialogResult::OK ) + { + return nullptr; + } + this->prevDir = System::IO::Path::GetDirectoryName( dlg->FileName ); + retfile = dlg->FileName; + if( !System::String::IsNullOrEmpty(extension) && !(dlg->FileName->EndsWith( extension )) ) + { + retfile += extension; + } + return retfile; +} + +// セーブするディレクトリをダイアログで取得 +// @ret 取得したディレクトリ名(\\で終わるように調整される) エラーのときnullptr +System::String^ Form1::saveDirDlg( System::String ^msgJ, System::String ^msgE ) +{ + System::String ^dir; + System::Windows::Forms::FolderBrowserDialog ^dlg = gcnew (System::Windows::Forms::FolderBrowserDialog); + + if( this->isEnglish() && msgE ) + { + dlg->Description = msgE; + } + else if( msgJ ) + { + dlg->Description = msgJ; + } + + if( dlg->ShowDialog() != System::Windows::Forms::DialogResult::OK ) + { + return nullptr; + } + + if( !dlg->SelectedPath->EndsWith("\\") ) + { + dir = dlg->SelectedPath + "\\"; + } + else + { + dir = System::String::Copy(dlg->SelectedPath); + } + return dir; +} + +// ファイルが存在するかを調べて上書き確認をする +bool Form1::isOverwriteFile( System::String ^path ) +{ + if( System::IO::File::Exists( path ) ) + { + System::String ^msg; + if( this->isJapanese() ) + { + msg = gcnew System::String( path + "はすでに存在します。上書きしますか?" ); + } + else + { + msg = gcnew System::String( path + "already exists. Overwrite it?" ); + } + + if( MessageBox::Show( msg, "Information", MessageBoxButtons::YesNo, MessageBoxIcon::None ) + == System::Windows::Forms::DialogResult::No ) + { + return false; + } + } + return true; // ファイルが存在しない場合 || 上書きOKの場合 ファイルを作成してもよい +} + + // end of file \ No newline at end of file diff --git a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/MasterEditorTWL.vcproj b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/MasterEditorTWL.vcproj index 948c5d4..7431d98 100644 --- a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/MasterEditorTWL.vcproj +++ b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/MasterEditorTWL.vcproj @@ -247,6 +247,14 @@ RelativePath=".\MasterEditorTWL.cpp" > + + + + @@ -334,6 +342,14 @@ RelativePath=".\resource.h" > + + + + diff --git a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/split_tad.cpp b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/split_tad.cpp new file mode 100644 index 0000000..9f00e7a --- /dev/null +++ b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/split_tad.cpp @@ -0,0 +1,275 @@ +#include "stdafx.h" +#include "twl/types.h" +#include +#include +#include "split_tad.h" +#include "split_tad_util.h" + + +// ------------------------------------------------------ +// 宣言と定数 +// ------------------------------------------------------ + +// internal functions +cli::array^ readTitleKey( cli::array ^ticket ); +cli::array^ decCBC( cli::array ^ Key, cli::array ^ IV, cli::array ^cipherText ); +cli::array ^readContentsInfo( cli::array ^tmd ); + +// tad外し用の鍵 +const u8 commonKey[] = +{ + 0xA1,0x60,0x4A,0x6A,0x71,0x23,0xB5,0x29,0xAE,0x8B,0xEC,0x32,0xC8,0x16,0xFC,0xAA +}; + + +// ------------------------------------------------------ +// tad外し処理本体 +// ------------------------------------------------------ + +// +// tad ファイルから srl(0番目のコンテンツ)を抜き出す +// (split_tad_dev.pl の移植) +// +// @arg [in] 入力 tad ファイル名 +// @arg [out] 出力 srl ファイル名 +// +// @ret 成功したとき0 失敗したら負の値 +// +int splitTad( System::String ^tadpath, System::String ^srlpath ) +{ + FILE *fp = NULL; + const char *pchFilename = + (const char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi( tadpath ).ToPointer(); + + if( fopen_s( &fp, pchFilename, "rb" ) != NULL ) + { + return -1; + } + + cli::array ^mbuf = subStr( fp, 0, 32 ); + + u32 hdrSize = reverseEndian( unpack32(mbuf, 0) ); // 基本的にビッグエンディアン + u16 tadType = reverseEndian( unpack16(mbuf, 4) ); + u16 tadVersion = reverseEndian( unpack16(mbuf, 6) ); + u32 certSize = reverseEndian( unpack32(mbuf, 8) ); + u32 crlSize = reverseEndian( unpack32(mbuf, 12) ); + u32 ticketSize = reverseEndian( unpack32(mbuf, 16) ); + u32 tmdSize = reverseEndian( unpack32(mbuf, 20) ); + u32 contentSize = reverseEndian( unpack32(mbuf, 24) ); + u32 metaSize = reverseEndian( unpack32(mbuf, 28) ); + + printf( "hdrSize %d\n", hdrSize ); + printf( "tadType %c%c\n", tadType>>8, tadType&0xFF ); + printf( "tadVersion %d\n", tadVersion ); + printf( "certSize %d\n", certSize ); + printf( "crlSize %d\n", crlSize ); + printf( "ticketSize %d\n", ticketSize ); + printf( "tmdSize %d\n", tmdSize ); + printf( "contentSize %d\n", contentSize ); + printf( "metaSize %d\n", metaSize ); + + u32 certOffset = roundUp( hdrSize, 64); + u32 crlOffset = roundUp( certOffset + certSize, 64); + u32 ticketOffset = roundUp( crlOffset + crlSize, 64); + u32 tmdOffset = roundUp( ticketOffset + ticketSize, 64); + u32 contentOffset = roundUp( tmdOffset + tmdSize, 64); + u32 metaOffset = roundUp( contentOffset + contentSize, 64); + u32 fileSize = roundUp( metaOffset + metaSize, 64); + + fseek( fp, 0, SEEK_END ); + u32 orgFileSize = ftell( fp ); + if( fileSize != orgFileSize ) + { + printf( "file size is not expected size(=%d)", fileSize ); + fclose( fp ); + return -1; + } + cli::array ^ticket = subStr( fp, ticketOffset, ticketSize ); + cli::array ^tmd = subStr( fp, tmdOffset, tmdSize ); + cli::array ^content = subStr( fp, contentOffset, contentSize ); + + //saveFile( "cert.bin", subStr( fp, certOffset, certSize ) ); + //saveFile( "crl.bin", subStr( fp, crlOffset, crlSize ) ); + //saveFile( "ticket.bin", ticket ); + //saveFile( "tmd.bin", tmd ); + //saveFile( "meta.bin", subStr( fp, metaOffset, metaSize ) ); + + cli::array ^title_key = readTitleKey( ticket ); + cli::array ^rci = readContentsInfo( tmd ); + dumpBytes( title_key ); + + // 通常は tad は srl (コンテンツ No.0) しか含まないが + // マルチコンテンツ を含む場合のために No.1 以降も別ファイルとして保存する + // srl 名が out.srl のとき out_1.bin out_2.bin ... として出力する + System::String ^srl_dir = System::IO::Path::GetDirectoryName( srlpath ); // 格納ディレクトリ名 + System::String ^srl_prefix = System::IO::Path::GetFileNameWithoutExtension( srlpath ); // 拡張子よりも前のファイル名 + System::String ^srl_ext = System::IO::Path::GetExtension( srlpath ); // 拡張子 + + int result = 0; + u32 offset = 0; + for each( rcContentsInfo ^ci in rci ) + { + u32 size = roundUp( (u32)ci->size, 16 ); + cli::array ^enc_content_x = subStr( content, offset, size ); + cli::array ^content_x_iv = resizeBytes( pack16( reverseEndian(ci->idx) ), 14 ); // ビッグエンディアンにしておく + cli::array ^dec_content_x = decCBC( title_key, content_x_iv, enc_content_x ); + cli::array ^dec_content = subStr( dec_content_x, 0, ci->size ); + System::Security::Cryptography::SHA1 ^sha1 = gcnew System::Security::Cryptography::SHA1Managed(); + cli::array ^hash = sha1->ComputeHash( dec_content ); + + dumpBytes( hash ); + pin_ptr calc = &hash[0]; // 計算で求めたハッシュ + pin_ptr extr = &ci->hash[0]; // 抽出したハッシュ + if( memcmp( calc, extr, 20 ) == 0 ) + { + printf( "hash OK\n" ); + } + else + { + printf( "hash mismatch\n" ); + result = -1; // エラーとする 中断はせず最後まで作成 + } + + //saveFile( "content_" + ci->idx.ToString() + ".encrypted.bin", enc_content_x ); + //saveFile( "content_" + ci->idx.ToString() + ".bin", dec_content ); + if( ci->idx == 0 ) + { + saveFile( srlpath, dec_content ); // コンテンツ No.0 が srl にあたる + } + else + { + System::String ^tmppath = srl_dir + "\\" + srl_prefix + "_" + ci->idx.ToString() + ".bin"; + saveFile( tmppath, dec_content ); + } + offset += roundUp( size, 64 ); + } + fclose( fp ); + return result; +} + +// ------------------------------------------------------ +// internal functions +// ------------------------------------------------------ + +// +// title_key の復号 +// +// @ret title_key のバイト列 +// +cli::array^ readTitleKey( cli::array ^ticket ) +{ + cli::array ^encTitleKey = subStr( ticket, 0x1BF, 16 ); + cli::array ^IV = resizeBytes( subStr( ticket, 0x1DC, 8 ), 8 ); // 16バイトに拡張してケツの8バイトを0で埋める + + cli::array ^comKey = gcnew cli::array(16); + pin_ptr pComKey = &comKey[0]; + memcpy( pComKey, commonKey, 16 ); + + cli::array ^plain; + try + { + plain = decCBC( comKey, IV, encTitleKey ); + } + catch (System::Exception ^ e) + { + System::Console::WriteLine("Exception in readTitleKey(): {0}", e->Message); + } + return plain; +} + +// +// tmd から各コンテンツファイルの情報を抜き出す +// +// @ret 各コンテンツファイルの情報をまとめた Array +// +cli::array ^readContentsInfo( cli::array ^tmd ) +{ + u16 nContent = reverseEndian( unpack16(tmd, 0x1DE) ); + cli::array ^ci = gcnew cli::array( nContent ); + + u16 i; + for( i=0; i < nContent; i++ ) + { + u32 offset = 0x1E4 + 36*i; + ci[i] = gcnew rcContentsInfo; + ci[i]->cid = reverseEndian( unpack32(tmd, offset) ); + ci[i]->idx = reverseEndian( unpack16(tmd, offset + 4) ); + ci[i]->type = reverseEndian( unpack16(tmd, offset + 6) ); + ci[i]->size = reverseEndian( unpack32(tmd, offset + 12) ); + ci[i]->hash = subStr( tmd, offset + 16, 20 ); + } + return ci; +} + +// +// AES復号 : System::Security::Cryptography::RijndaelManaged のヘルプのサンプルをコピペ +// +// @ret 復号後のデータ +// +cli::array^ decCBC( cli::array ^ Key, cli::array ^ IV, cli::array ^cipherText ) +{ + // Check arguments. + if (!cipherText || cipherText->Length <= 0) + throw gcnew System::ArgumentNullException("cipherText"); + if (!Key || Key->Length <= 0) + throw gcnew System::ArgumentNullException("Key"); + if (!IV || IV->Length <= 0) + throw gcnew System::ArgumentNullException("Key"); + + // TDeclare the streams used + // to decrypt to an in memory + // array of bytes. + System::IO::MemoryStream ^msDecrypt; + System::Security::Cryptography::CryptoStream ^csDecrypt; + + // Declare the RijndaelManaged object + // used to decrypt the data. + System::Security::Cryptography::RijndaelManaged ^aesAlg; + + // Declare the string used to hold + // the decrypted text. + cli::array ^plain = gcnew cli::array(cipherText->Length); + + try + { + // Create a RijndaelManaged object + // with the specified key and IV. + aesAlg = gcnew System::Security::Cryptography::RijndaelManaged(); + aesAlg->Mode = System::Security::Cryptography::CipherMode::CBC; // CBCモード + aesAlg->Key = Key; + aesAlg->IV = IV; + aesAlg->Padding = System::Security::Cryptography::PaddingMode::Zeros; + + // Create a decrytor to perform the stream transform. + System::Security::Cryptography::ICryptoTransform ^ decryptor + = aesAlg->CreateDecryptor(aesAlg->Key, aesAlg->IV); + + // Create the streams used for decryption. + msDecrypt = gcnew System::IO::MemoryStream(cipherText); + csDecrypt = gcnew System::Security::Cryptography::CryptoStream + (msDecrypt, decryptor, System::Security::Cryptography::CryptoStreamMode::Read); + csDecrypt->Read( plain, 0, cipherText->Length ); + //srDecrypt = gcnew System::IO::StreamReader(csDecrypt); + + //// Read the decrypted bytes from the decrypting stream + //// and place them in a string. + //plaintext = srDecrypt->ReadToEnd(); + } + finally + { + // Clean things up. + + // Close the streams. + if (csDecrypt) + csDecrypt->Close(); + if (msDecrypt) + msDecrypt->Close(); + + // Clear the RijndaelManaged object. + if (aesAlg) + aesAlg->Clear(); + } + return plain; +} + +// end of file diff --git a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/split_tad.h b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/split_tad.h new file mode 100644 index 0000000..b08bdb0 --- /dev/null +++ b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/split_tad.h @@ -0,0 +1,80 @@ +#pragma once + +#include "twl/types.h" +#include +#include + + +// ------------------------------------------------------ +// APIs +// ------------------------------------------------------ + +// +// tad ファイルから srl(0番目のコンテンツ)を抜き出す +// (split_tad_dev.pl の移植) +// +// @arg [in] 入力 tad ファイルのパス +// @arg [out] 出力 srl ファイルのパス +// +// @ret 成功したとき0 失敗したら負の値 +// +int splitTad( System::String ^tadpath, System::String ^srlpath ); + + +// ------------------------------------------------------ +// 内部処理用の構造体(プロトタイプ宣言できないのでヘッダに置く) +// ------------------------------------------------------ + +// コンテンツ情報の構造体 +ref class rcContentsInfo +{ +private: + System::UInt32 ^h_cid; + System::UInt16 ^h_idx; + System::UInt16 ^h_type; + System::UInt32 ^h_size; + cli::array ^h_hash; +public: + rcContentsInfo() + { + this->h_cid = gcnew System::UInt32; // 解放の必要なし + this->h_idx = gcnew System::UInt16; + this->h_type = gcnew System::UInt16; + this->h_size = gcnew System::UInt32; + this->h_hash = gcnew cli::array(20); // 固定長 + } +public: + property System::UInt32 cid + { + void set( System::UInt32 v ){ *this->h_cid = v; }; + System::UInt32 get(void){ return *this->h_cid; } + } + property System::UInt16 idx + { + void set( System::UInt16 v ){ *this->h_idx = v; }; + System::UInt16 get(void){ return *this->h_idx; } + } + property System::UInt16 type + { + void set( System::UInt16 v ){ *this->h_type = v; }; + System::UInt16 get(void){ return *this->h_type; } + } + property System::UInt32 size + { + void set( System::UInt32 v ){ *this->h_size = v; }; + System::UInt32 get(void){ return *this->h_size; } + } + property cli::array ^hash + { + void set( cli::array ^h ) + { + cli::array::Copy( h, this->h_hash, 20 ); + } + cli::array ^get(void) + { + cli::array ^cp = gcnew cli::array(20); // コピーを返す + cli::array::Copy( this->h_hash, cp, 20 ); + return cp; + } + } +}; diff --git a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/split_tad_util.cpp b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/split_tad_util.cpp new file mode 100644 index 0000000..7af50c7 --- /dev/null +++ b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/split_tad_util.cpp @@ -0,0 +1,186 @@ +#include "stdafx.h" +#include "twl/types.h" +#include +#include +#include "split_tad_util.h" + + +// ------------------------------------------------------------------------ +// 部分バイト列を抜き出す +// ------------------------------------------------------------------------ + +// @ret 抜き出したバイト列 +cli::array^ subStr( FILE *fp, const int offset, const int size ) +{ + if( size <= 0 ) + { + return nullptr; + } + cli::array ^mbuf = gcnew cli::array(size); // メモリ解放の必要なし + pin_ptr buf = &mbuf[0]; // fread が unmanaged 配列を引数にするので変換 + + (void)fseek( fp, offset, SEEK_SET ); + if( fread( buf, 1, size, fp ) != size ) + { + return nullptr; + } + return mbuf; // managed のほうを返す +} + +// @ret 抜き出したバイト列 +cli::array^ subStr( cli::array ^bytes, const int offset, const int size ) +{ + cli::array ^sub = gcnew cli::array(size); + + cli::array::Copy( bytes, offset, sub, 0, size ); + return sub; +} + +// ------------------------------------------------------------------------ +// ファイルを作成してバイト列を格納する +// ------------------------------------------------------------------------ + +// @ret 成功したら0 失敗したら負の値 +int saveFp( FILE *fp, cli::array ^bytes ) +{ + if( bytes == nullptr ) + { + return 0; // 空のファイルをつくりたいということなので正常終了とみなす + } + pin_ptr tmp = &bytes[0]; // array型はふつうの配列ではないのでバイト配列に変換 + int size = bytes->Length; + + if( fwrite( tmp, 1, size, fp ) != size ) + { + return -1; + } + return 0; +} + +// @ret 成功したら0 失敗したら負の値 +int saveFile( System::String ^filename, cli::array ^bytes ) +{ + FILE *fp = NULL; + const char *pchFilename = + (const char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi( filename ).ToPointer(); + + // ファイルにROMヘッダをライト + if( fopen_s( &fp, pchFilename, "wb" ) != NULL ) // 同名ファイルを削除して新規にライト・バイナリ + { + return -1; + } + fseek( fp, 0, SEEK_SET ); + int r = saveFp( fp, bytes ); + fclose( fp ); + + return r; +} + +// ------------------------------------------------------------------------ +// エンディアンを逆転させる(tadはビッグエンディアンなのであったほうが便利) +// ------------------------------------------------------------------------ + +// @ret エンディアン逆転後の値 +u32 reverseEndian( const u32 v ) +{ + u32 ret = (v<<24) | ((v<<8) & 0x00FF0000) | ((v>>8) & 0x0000FF00) | (v>>24); + return ret; +} + +u16 reverseEndian( const u16 v ) +{ + u16 ret = (v<<8) | (v>>8); + return ret; +} + +// ------------------------------------------------------------------------ +// 多バイト値をバイト列に変換(リトルエンディアン) +// *** perlのpackを意識 *** +// ------------------------------------------------------------------------ + +// @ret 変換後のバイト列 +cli::array ^pack32( u32 v ) +{ + cli::array ^bytes = gcnew cli::array(4); + bytes[0] = v & 0xFF; + bytes[1] = (v >> 8) & 0xFF; + bytes[2] = (v >> 16) & 0xFF; + bytes[3] = (v >> 24) & 0xFF; + return bytes; +} + +cli::array ^pack16( u16 v ) +{ + cli::array ^bytes = gcnew cli::array(2); + bytes[0] = v & 0xFF; + bytes[1] = v >>8; + return bytes; +} + +// ------------------------------------------------------------------------ +// バイト列の部分バイト列から多バイト値として解釈(リトルエンディアン) +// *** perlのunpackを意識 *** +// ------------------------------------------------------------------------ + +// @arg [in] バイト列 +// @arg [in] 何バイト目からを多バイト値とみなすか +// @ret 解釈した後の多バイト値 +u32 unpack32( cli::array ^bytes, const int index ) +{ + pin_ptr tmp = &bytes[0]; + u32 v = (u32)*((u32*)(tmp+index)); + return v; +} + +u16 unpack16( cli::array ^bytes, const int index ) +{ + pin_ptr tmp = &bytes[0]; + u16 v = (u16)*((u16*)(tmp+index)); + return v; +} + +// ------------------------------------------------------------------------ +// 丸める +// ------------------------------------------------------------------------ + +u32 roundUp( const u32 v, const u32 align ) +{ + u32 r = ((v + align - 1) / align) * align; + return r; +} + +u16 roundUp( const u16 v, const u16 align ) +{ + u16 r = ((v + align - 1) / align) * align; + return r; +} + +// ------------------------------------------------------------------------ +// バイト列の長さを拡張して末尾を0で埋める +// (0x12345678 => 0x1234567800000000) +// ------------------------------------------------------------------------ + +// @arg [in] 拡張前のバイト列 +// @arg [in] 何バイト拡張するか(拡張分だけを指定 例えば4バイトを5バイトにする場合には1を指定) +// @ret 拡張後のバイト列(新たなバイト列を内部で生成) +cli::array ^resizeBytes( cli::array ^org, const int difSize ) +{ + cli::array ^r = gcnew cli::array( org->Length + difSize ); + cli::array::Copy( org, 0, r, 0, org->Length ); + return r; +} + +// ------------------------------------------------------------------------ +// バイト列を16進で表示 +// ------------------------------------------------------------------------ + +void dumpBytes( cli::array ^bytes ) +{ + for each( System::Byte b in bytes ) + { + printf( "%02x", b ); + } + printf( "\n" ); +} + +// end of file diff --git a/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/split_tad_util.h b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/split_tad_util.h new file mode 100644 index 0000000..354eeac --- /dev/null +++ b/build/tools/MasterEditor/MasterEditorTWL/MasterEditorTWL/split_tad_util.h @@ -0,0 +1,73 @@ +#pragma once + +#include "twl/types.h" +#include +#include + + +// ------------------------------------------------------------------------ +// 部分バイト列を抜き出す +// ------------------------------------------------------------------------ + +// @ret 抜き出したバイト列 +cli::array^ subStr( FILE *fp, const int offset, const int size ); +cli::array^ subStr( cli::array ^bytes, const int offset, const int size ); + +// ------------------------------------------------------------------------ +// ファイルを作成してバイト列を格納する +// ------------------------------------------------------------------------ + +// @ret 成功したら0 失敗したら負の値 +int saveFp( FILE *fp, cli::array ^bytes ); +int saveFile( System::String ^filename, cli::array ^bytes ); + +// ------------------------------------------------------------------------ +// エンディアンを逆転させる(tadはビッグエンディアンなのであったほうが便利) +// ------------------------------------------------------------------------ + +// @ret エンディアン逆転後の値 +u32 reverseEndian( const u32 v ); +u16 reverseEndian( const u16 v ); + +// ------------------------------------------------------------------------ +// 多バイト値をバイト列に変換(リトルエンディアン) +// *** perlのpackを意識 *** +// ------------------------------------------------------------------------ + +// @ret 変換後のバイト列 +cli::array ^pack32( u32 v ); +cli::array ^pack16( u16 v ); + +// ------------------------------------------------------------------------ +// バイト列の部分バイト列から多バイト値として解釈(リトルエンディアン) +// *** perlのunpackを意識 *** +// ------------------------------------------------------------------------ + +// @arg [in] バイト列 +// @arg [in] 何バイト目からを多バイト値とみなすか +// @ret 解釈した後の多バイト値 +u32 unpack32( cli::array ^bytes, const int index ); +u16 unpack16( cli::array ^bytes, const int index ); + +// ------------------------------------------------------------------------ +// 丸める +// ------------------------------------------------------------------------ + +u32 roundUp( const u32 v, const u32 align ); +u16 roundUp( const u16 v, const u16 align ); + +// ------------------------------------------------------------------------ +// バイト列の長さを拡張して末尾を0で埋める +// (0x12345678 => 0x1234567800000000) +// ------------------------------------------------------------------------ + +// @arg [in] 拡張前のバイト列 +// @arg [in] 何バイト拡張するか(拡張分だけを指定 例えば4バイトを5バイトにする場合には1を指定) +// @ret 拡張後のバイト列(新たなバイト列を内部で生成) +cli::array ^resizeBytes( cli::array ^org, const int difSize ); + +// ------------------------------------------------------------------------ +// バイト列を16進で表示 +// ------------------------------------------------------------------------ +void dumpBytes( cli::array ^bytes ); +