mirror of
https://github.com/rvtr/TwlToolsRED.git
synced 2025-10-31 06:41:18 -04:00
324 lines
12 KiB
Plaintext
324 lines
12 KiB
Plaintext
unit main;
|
||
|
||
interface
|
||
|
||
uses
|
||
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
|
||
Dialogs, StdCtrls, FileCtrl, ComCtrls, ShellCtrls, ExtCtrls;
|
||
|
||
type
|
||
TForm1 = class(TForm)
|
||
ListBox_log: TListBox;
|
||
Button1: TButton;
|
||
DriveBox: TDriveComboBox;
|
||
DirListBox: TDirectoryListBox;
|
||
StatusBar: TStatusBar;
|
||
StaticText3: TStaticText;
|
||
RG_select: TRadioGroup;
|
||
StatusBar1: TStatusBar;
|
||
procedure Button1Click(Sender: TObject);
|
||
procedure DriveBoxChange(Sender: TObject);
|
||
procedure DirListBoxChange(Sender: TObject);
|
||
procedure FormCreate(Sender: TObject);
|
||
private
|
||
{ Private 宣言 }
|
||
function CheckSrlHeader:integer;
|
||
public
|
||
{ Public 宣言 }
|
||
end;
|
||
|
||
TRom_Fat = record
|
||
top:Longword; // file region start
|
||
bottom:Longword; // end;
|
||
end;
|
||
|
||
TRomh = record //ROMヘッダ(nitro_romheader.hより)
|
||
title: array[1..12] of Char;
|
||
game_code: array[1..4] of Char;
|
||
//0x10
|
||
maker_code: array[1..2] of Byte;
|
||
machine_code: Byte;
|
||
rom_type: Byte;
|
||
rom_size: Byte;
|
||
resv_A: array[1..8] of Byte; //Reserve(All 0)
|
||
region: Byte;
|
||
// b0 = china,b1 = koria
|
||
|
||
rom_version: Byte;
|
||
comp_boot_area: Byte;//b7 =A9,b6=A7
|
||
|
||
//
|
||
// 0x020 for Static modules (Section:B)
|
||
//ARM9
|
||
A9_main_rom_offset: Longword; // ROM offset
|
||
A9_main_entry_address: Longword; // Entry point
|
||
A9_main_ram_address: Longword; // RAM address
|
||
A9_main_size: Longword; // Module size
|
||
|
||
//ARM7
|
||
A7_main_rom_offset: Longword; // ROM offset
|
||
A7_main_entry_address: Longword; // Entry point
|
||
A7_main_ram_address: Longword; // RAM address
|
||
A7_main_size: Longword; // Module size
|
||
|
||
//0x40
|
||
dumy2:array[1..8] of Byte;//ツールで使用しない部分
|
||
|
||
//
|
||
// 0x048 for File Allocation Table[FAT] (Section:E)
|
||
//
|
||
fat_offset: Longword; // ROM offset
|
||
fat_size:Longword; // Table size
|
||
|
||
//
|
||
// 0x050 for Overlay Tables[OVT] (Section:D)
|
||
//
|
||
// ARM9
|
||
main_ovt_offset: Longword; // ROM offset
|
||
main_ovt_size:Longword; // Table size
|
||
|
||
end;
|
||
|
||
var
|
||
Form1: TForm1;
|
||
LogDir,SrlDir: String;//ディレクトリパス
|
||
ng_all: longword;//総NGエントリ数
|
||
|
||
implementation
|
||
|
||
function TForm1.CheckSrlHeader: integer;
|
||
var
|
||
Rec: TSearchRec;
|
||
sf,s,ss: String;
|
||
i,n,Count,err_files,ng_entry: integer;
|
||
fsrl: file;
|
||
flog:TextFile;
|
||
romh: TRomh;
|
||
noc_size,noc_sectors,size,sectors,nums,max_sectors,total_sectors: integer;
|
||
fat: TRom_Fat;
|
||
top,btm,all_sectors: Longword;
|
||
ng_flg:boolean;
|
||
|
||
begin
|
||
{$I-}
|
||
//ログファイル作成
|
||
ListBox_log.Items.Add('Create Log file');
|
||
s := ExtractFilePath(Application.Exename)+'log.txt';
|
||
AssignFile (flog,s);
|
||
Rewrite(flog);
|
||
if IOResult <> 0 then begin
|
||
Count := -1;
|
||
ListBox_log.Items.Add('faild')
|
||
end else begin
|
||
Count := 0;
|
||
err_files := 0;
|
||
ng_all := 0;
|
||
//指定ディレクトリからファイルを取り出す
|
||
// ** 内容で判別しないので違うファイル置かないよう注意 **
|
||
if FindFirst(SrlDir + '*.*', faAnyFile, Rec) = 0 then
|
||
try
|
||
repeat
|
||
//フォルダやカレントディレクトリや親ディレクトリは対象外
|
||
if not((Rec.Attr and faDirectory > 0)) and
|
||
(Rec.Name <> '.') and (Rec.Name <> '..') and (Rec.name<>'log.txt')then
|
||
begin
|
||
//ListBox_log.Items.Add('**********************************');
|
||
Writeln(flog,'**********************************');
|
||
sf := 'file: '+Rec.Name;
|
||
//ListBox_log.Items.Add(sf);
|
||
Writeln(flog,sf);
|
||
AssignFile (fsrl,SrlDir+Rec.Name);
|
||
FileMode := fmOpenRead;//リード専用指定
|
||
Reset(fsrl,1);//ファイル開く
|
||
if IOResult = 0 then begin
|
||
BlockRead(fsrl,romh,SizeOf(TRomh),n);//ヘッダリード
|
||
if SizeOf(TRomh) <> n then
|
||
s := ' header read error'
|
||
else begin
|
||
//SetLength(s,12);
|
||
s := '[ ( )]';
|
||
for i:=1 to 12 do begin
|
||
if romh.title[i] = char(0) then break;
|
||
s[i+1] := romh.title[i];
|
||
end;
|
||
s[15] := romh.game_code[4];//idの4文字目(仕向地)
|
||
//ListBox_log.Items.Add(s); //title
|
||
Writeln(flog,s);
|
||
s := 'game_code = ';
|
||
for i:=1 to 4 do s[12+i] := romh.game_code[i];
|
||
//ListBox_log.Items.Add(s); //game code
|
||
//ListBox_log.Items.Add('version = '+inttostr(romh.rom_version));
|
||
//ListBox_log.Items.Add(' ');
|
||
Writeln(flog,s);
|
||
Writeln(flog,'version = '+inttostr(romh.rom_version));
|
||
Writeln(flog);//改行
|
||
|
||
//オーバレイチェック
|
||
if romh.main_ovt_size >31 then begin
|
||
//DHT_OVERLAY_MAX (512*1024)
|
||
ng_entry := 0;
|
||
total_sectors := 0;
|
||
all_sectors := 0;
|
||
nums := romh.main_ovt_size div 32;//Ovl count
|
||
noc_size :=0;//範囲外トータルsize
|
||
noc_sectors := 0;// 同セクタ
|
||
for i := 0 to nums-1 do begin
|
||
top := 0;btm := 0;
|
||
seek( fsrl,romh.fat_offset+sizeof(TRom_Fat)*i);
|
||
BlockRead( fsrl,fat,sizeof(fat),n);//top,bottom取得
|
||
if n <> sizeof(fat) then begin
|
||
s := 'file error';
|
||
break;
|
||
end;
|
||
ng_flg:=false;
|
||
ss := '(A9 Overlay'+inttostr(i);
|
||
//max_sectors = (DHT_OVERLAY_MAX/512 - total_sectors) / (nums-i);
|
||
if (total_sectors < 1024)then max_sectors := (1024 - total_sectors) div (nums-i)
|
||
else max_sectors := 0;
|
||
btm := fat.bottom and $fffffe00; //512単位
|
||
if (fat.bottom and $1ff)<>0 then inc(btm,512);//上方向に丸める
|
||
if max_sectors = 0 then begin//最大達したら丸ごと検証外
|
||
top := fat.top;
|
||
sectors := (btm-top) shr 9;//div 512
|
||
if (top and $1ff)<>0 then inc(sectors);
|
||
ss := ss+' の全部)';
|
||
ng_flg:=true;
|
||
end else begin
|
||
ss := ss+' の一部)';
|
||
top := fat.top and $fffffe00; //512単位
|
||
size := fat.top and $01ff;
|
||
if size<>0 then begin
|
||
inc(top,512);////上方向に丸める
|
||
//先頭の未検証部分 .. 不要?
|
||
s := 'offset'+inttostr(i)+' = 0x'+ inttohex(fat.top,8)
|
||
+' ; 0x'+ inttohex(fat.top,8)
|
||
+'-0x' + inttohex(top-1,8)+ss;
|
||
//ListBox_log.Items.Add(s);
|
||
Writeln(flog,s);
|
||
s := 'length'+ inttostr(i) + ' = 0x' + inttohex(size,4)
|
||
+ ' ; '+ inttostr(size)+' bytes';
|
||
//ListBox_log.Items.Add(s);
|
||
Writeln(flog,s);
|
||
inc(noc_size,512);
|
||
inc(noc_sectors);
|
||
inc(all_sectors);
|
||
ng_flg:=true;
|
||
end;
|
||
size := btm - top;
|
||
sectors := size shr 9;//div 512
|
||
inc(all_sectors,sectors);
|
||
if sectors > max_sectors then begin //最大割当サイズ超
|
||
sectors := sectors - max_sectors;//残りセクタ数
|
||
inc(top,max_sectors*512);//残り先頭
|
||
inc(total_sectors,max_sectors);
|
||
ng_flg:=true;
|
||
end else begin //超過なし
|
||
inc(total_sectors,sectors);
|
||
sectors := 0;
|
||
end;
|
||
end;
|
||
if sectors > 0 then begin//残りあり
|
||
size := sectors shl 9;
|
||
s := 'offset'+inttostr(i)+' = 0x'+ inttohex(top,8)
|
||
+' ; 0x'+ inttohex(top,8)
|
||
+'-0x' + inttohex(btm-1,8)+ss;
|
||
//ListBox_log.Items.Add(s);
|
||
Writeln(flog,s);
|
||
s := 'length'+ inttostr(i) + ' = 0x' + inttohex(size,4)
|
||
+ ' ; '+ inttostr(size)+' bytes';
|
||
//ListBox_log.Items.Add(s);
|
||
Writeln(flog,s);
|
||
inc(noc_size,size);
|
||
inc(noc_sectors,sectors);
|
||
end;
|
||
if ng_flg then inc(ng_entry);
|
||
end;
|
||
if i = nums then begin //中断なし
|
||
//ListBox_log.Items.Add(' ');
|
||
//ListBox_log.Items.Add('total sectors = '+inttostr(all_sectors));
|
||
//ListBox_log.Items.Add('no check sectors = '+inttostr(noc_sectors));
|
||
//ListBox_log.Items.Add('no check size = '+inttostr(noc_size));
|
||
Writeln(flog); //改行
|
||
Writeln(flog,'total sectors = '+inttostr(all_sectors));
|
||
Writeln(flog,'check sectors = '+inttostr(total_sectors));
|
||
Writeln(flog,'no check sectors = '+inttostr(noc_sectors));
|
||
Writeln(flog,'no check size = '+inttostr(noc_size));
|
||
if noc_size <> 0 then s:= 'NG'
|
||
else s:= 'OK';
|
||
end;
|
||
end else s := 'no OVL';
|
||
end;
|
||
end else s := ' Open Error';
|
||
CloseFile(fsrl);
|
||
Writeln(flog,s);//結果
|
||
if (s='OK') or (s='NG') then begin
|
||
if s = 'NG' then begin
|
||
s := 'done, '+ inttostr(ng_entry) + ' enties NG';
|
||
inc(ng_all,ng_entry);
|
||
end else s := 'done, OK';
|
||
Inc(Count);
|
||
end else inc(err_files);
|
||
ss := sf + ' : ' + s;
|
||
ListBox_log.Items.Add(ss);
|
||
end;
|
||
until (FindNext(Rec) <> 0);
|
||
finally
|
||
FindClose(Rec);
|
||
end;
|
||
Writeln(flog,'********************************');
|
||
Writeln(flog,'check files = '+ inttostr(Count));
|
||
Writeln(flog,'error files = '+ inttostr(err_files));
|
||
|
||
CloseFile(flog);
|
||
end;
|
||
{$I+}
|
||
Result :=Count;
|
||
end;
|
||
|
||
{$R *.dfm}
|
||
|
||
procedure TForm1.Button1Click(Sender: TObject);
|
||
var
|
||
FileCount :integer;
|
||
s :string;
|
||
begin
|
||
ListBox_log.Clear;
|
||
//指定ディレクトリのsrlファイルをチェック
|
||
FileCount := CheckSrlHeader;
|
||
if FileCount>=0 then begin
|
||
ListBox_log.Items.Add(' ------------------------------ ');
|
||
s := ' '+inttostr(FileCount)+' files done, '
|
||
+ inttostr(ng_all)+' entries NG';
|
||
ListBox_log.Items.Add(s);
|
||
end;
|
||
end;
|
||
|
||
|
||
|
||
procedure TForm1.DriveBoxChange(Sender: TObject);
|
||
begin
|
||
DirListBox.Drive := DriveBox.Drive;
|
||
end;
|
||
|
||
procedure TForm1.DirListBoxChange(Sender: TObject);
|
||
begin
|
||
if RG_select.ItemIndex = 0 then begin
|
||
SrlDir := IncludeTrailingPathDelimiter(DirListBox.Directory);
|
||
StatusBar.SimpleText := '[srl dir] ' + DirListBox.Directory;
|
||
end else begin
|
||
LogDir := IncludeTrailingPathDelimiter(DirListBox.Directory);
|
||
StatusBar1.SimpleText := '[log dir] ' + DirListBox.Directory;
|
||
end;
|
||
end;
|
||
|
||
procedure TForm1.FormCreate(Sender: TObject);
|
||
begin
|
||
SrlDir := IncludeTrailingPathDelimiter(DirListBox.Directory);
|
||
StatusBar.SimpleText := '[srl dir] ' + DirListBox.Directory;
|
||
LogDir := IncludeTrailingPathDelimiter(DirListBox.Directory);
|
||
StatusBar1.SimpleText := '[log dir] ' + DirListBox.Directory;
|
||
end;
|
||
|
||
|
||
end.
|