TwlToolsRED/build/tools/MasterEditor/RomFilenameDecoderTWL/RomFilenameDecoderTWL/rfd_context.h
nishikawa_takeshi d0c2672f63 ROMファイルデコーダ:初版。マスターROMファイル名からリマスターバージョンと提出バージョンを取得するプログラム。
perlのほうが楽だけど、cygwin入れるの嫌がられるのでVCで作成。

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlToolsRED@107 7061adef-622a-194b-ae81-725974e89856
2009-01-08 10:53:45 +00:00

272 lines
6.8 KiB
C++

#pragma once
#include <twl/types.h>
#include <twl/os/common/format_rom.h>
#include <cstdio>
#include <cstring>
#include "rfd_util.h"
namespace RomFilenameDecoderTWL
{
// -----------------------------------------------------------
// エラーコード
// -----------------------------------------------------------
enum class ECError
{
NOERROR = 0,
ERROR_READ_FILE = -1,
ERROR_FILE_NAME = -2,
// -3..-7 予約
ERROR_INITIAL_CODE = -8,
ERROR_REMASTER_VERSION = -9,
};
// -----------------------------------------------------------
// 実行context
// -----------------------------------------------------------
ref class RCContext
{
private:
// 引数の解析結果
System::String ^romfile; // 入力ファイル名
System::Int32 argc; // 引数の数
// オプションを表すフラグ
System::Boolean isSubmitVersion;
System::Boolean isTadVersion;
public:
// ReadOnlyにする
property System::String^ Romfile
{
System::String^ get(void)
{
if( !romfile )
{
return nullptr;
}
return System::String::Copy( this->romfile );
}
}
property System::Int32 Argc
{
System::Int32 get(void){ return this->argc; }
}
property System::Boolean IsSubmitVersion
{
System::Boolean get(void){ return this->isSubmitVersion; }
}
property System::Boolean IsTadVersion
{
System::Boolean get(void){ return this->isTadVersion; }
}
private:
RCContext(){} // 封じる
public:
// コンストラクタでは引数をもらってフラグを解析する
RCContext( cli::array<System::String ^> ^args )
{
this->parseArgs( args );
}
private:
// 引数解析
void parseArgs( cli::array<System::String ^> ^args )
{
System::Collections::Generic::List<System::Int32> ^indexList
= gcnew System::Collections::Generic::List<System::Int32>;
int numopt = 0;
int i;
for( i=0; i < args->Length; i++ )
{
if( args[i]->StartsWith( "-s" ) )
{
this->isSubmitVersion = true;
numopt++;
}
else if( args[i]->StartsWith( "-t" ) )
{
this->isTadVersion = true;
numopt++;
}
else if( !args[i]->StartsWith( "-" ) ) // オプションでない引数のindexを記録
{
indexList->Add(i);
}
}
i=0;
for each( System::Int32 index in indexList ) // オプションでない引数を前につめていく
{
args[i] = args[index];
i++;
}
this->argc = args->Length - numopt; // 引数の数からオプションの数を除く
if( this->argc > 0 )
{
this->romfile = System::String::Copy( args[0] );
}
else
{
this->romfile = nullptr;
}
}
}; //ref class RCContext
// -----------------------------------------------------------
// ファイル名から取得できる情報
// -----------------------------------------------------------
ref class RCFilenameItems
{
private:
// ファイル名から取得できる情報
System::String^ initialCode;
System::Byte remasterVersion;
System::Byte submissionVersion;
// ファイルから読み込んだROMヘッダ
ROM_Header *rh;
// エラー情報
RomFilenameDecoderTWL::ECError error;
public:
property System::String^ InitialCode
{
System::String^ get(void){ return System::String::Copy(this->initialCode); }
}
property System::Byte RemasterVersion
{
System::Byte get(void){ return this->remasterVersion; }
}
property System::Byte SubmissionVersion
{
System::Byte get(void){ return this->submissionVersion; }
}
property const ROM_Header* Rh
{
const ROM_Header* get(void){ return this->rh; }
}
property RomFilenameDecoderTWL::ECError Error
{
RomFilenameDecoderTWL::ECError get(void){ return this->error; }
}
private:
RCFilenameItems(){}
public:
RCFilenameItems( System::String ^filepath )
{
this->initialCode = gcnew System::String("");
this->remasterVersion = 0;
this->submissionVersion = 0;
this->rh = new ROM_Header;
memset( this->rh, 0, sizeof(ROM_Header) );
this->error = RomFilenameDecoderTWL::ECError::NOERROR;
this->parseFilename( filepath );
if( this->error == RomFilenameDecoderTWL::ECError::NOERROR )
{
this->readRomHeader( filepath );
}
}
~RCFilenameItems()
{
this->!RCFilenameItems();
}
!RCFilenameItems()
{
delete this->rh;
}
private:
// ROMヘッダを読み込む
void readRomHeader( System::String ^filepath )
{
if( !RomFilenameDecoderTWL::readRomHeader( filepath, this->rh ) )
{
this->error = RomFilenameDecoderTWL::ECError::ERROR_READ_FILE;
}
}
// ファイル名を解析してメンバ変数を設定する
void parseFilename( System::String ^filepath )
{
if( !filepath ) // 指定されていない場合
{
this->error = RomFilenameDecoderTWL::ECError::ERROR_FILE_NAME;
return;
}
System::String^ prefix = System::IO::Path::GetFileNameWithoutExtension( filepath ); // 拡張子とディレクトリパスを除く
if( prefix->Length < 7 ) // T****@#.SRL / T****0#E.SRL のいずれか
{
this->error = RomFilenameDecoderTWL::ECError::ERROR_FILE_NAME;
return;
}
this->initialCode = prefix->Substring(1,4);
this->remasterVersion = this->parseStrToByte( prefix->Substring(5,1) );
if( prefix->Length >= 8 )
{
if( ((char)prefix[7] == 'E') && (this->remasterVersion == 0) )
{
this->remasterVersion = 0xE0;
}
}
this->submissionVersion = this->parseStrToByte( prefix->Substring(6,1) );
} //void parseFilename()
public:
// 1桁の数字を数値に変換
System::Byte parseStrToByte( System::String ^str )
{
if( str->Length > 1 )
{
return 0xff;
}
System::Byte val;
// 通常 0..F だが その上を G..Z で表す可能性がある
char c = (char)str[0];
if( ('G' <= c) && (c <= 'Z') ) // Fより上はG..Zで表現されていく(可能性あり)
{
val = c - 'G' + 16;
}
else if( ('g' <= c) && (c <= 'z') )
{
val = c - 'g' + 16;
}
else
{
try
{
val = System::Byte::Parse( str, System::Globalization::NumberStyles::AllowHexSpecifier );
}
catch(System::Exception ^e )
{
(void)e;
val = 0xff;
}
}
return val;
} //parseStrToByte()
public:
// ROMヘッダの情報と自身の情報を比較(エラー情報はメンバ変数に設定)
void compareRomHeader()
{
// すでにエラーがある場合には何もしない
if( this->error != RomFilenameDecoderTWL::ECError::NOERROR )
{
return;
}
// イニシャルコードの比較
char inicode[4];
RomFilenameDecoderTWL::setStringToChars( inicode, this->initialCode, 4, 0 );
if( memcmp( this->rh->s.game_code, inicode, 4 ) != 0 )
{
this->error = RomFilenameDecoderTWL::ECError::ERROR_INITIAL_CODE;
return;
}
// リマスターバージョンの比較
if( this->rh->s.rom_version != this->remasterVersion )
{
this->error = RomFilenameDecoderTWL::ECError::ERROR_REMASTER_VERSION;
return;
}
// 提出バージョンはROMヘッダにないので比較できない
this->error = RomFilenameDecoderTWL::ECError::NOERROR;
return;
} //void compareRomHeader()
}; //ref class RCFilenameItems
} //namespace RomFilenameDecoderTWL