Added ability to extract all TIMs to PNG; Now PNG's name includes CLUT index.
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
<MainSource>tim2view.dpr</MainSource>
|
||||
<Base>True</Base>
|
||||
<Config Condition="'$(Config)'==''">Release</Config>
|
||||
<Platform Condition="'$(Platform)'==''">Win64</Platform>
|
||||
<Platform Condition="'$(Platform)'==''">Win32</Platform>
|
||||
<TargetedPlatforms>3</TargetedPlatforms>
|
||||
<AppType>Application</AppType>
|
||||
</PropertyGroup>
|
||||
|
||||
BIN
tim2view.res
BIN
tim2view.res
Binary file not shown.
@@ -78,12 +78,15 @@ begin
|
||||
Exit;
|
||||
|
||||
pFile := GetMemory(cSectorHeaderSize);
|
||||
|
||||
try
|
||||
tmp := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
|
||||
tmp.Read(pFile^[0], cSectorHeaderSize);
|
||||
Result := ((Sz mod cSectorSize) = 0) and
|
||||
(CompareMem(@cSectorHeader, pFile, cSectorHeaderSize));
|
||||
Result := ((Sz mod cSectorSize) = 0) and (CompareMem(@cSectorHeader, pFile, cSectorHeaderSize));
|
||||
finally
|
||||
tmp.free;
|
||||
FreeMemory(pFile);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure ReplaceTimInFileFromMemory(const FileName: string; TIM: PTIM;
|
||||
|
||||
@@ -7,16 +7,19 @@ uses
|
||||
|
||||
const
|
||||
cProgramName = 'Tim2View by [Lab 313]';
|
||||
cProgramVersion = '2.0 Stable';
|
||||
cProgramVersion = '2.0 Release';
|
||||
cExtractedTimsDir = 'TIMS';
|
||||
cExtractedPngsDir = 'PNGS';
|
||||
cMaxFileSize = $2EAEED80;
|
||||
|
||||
cAutoExtractionTimFormat = '%s_%.6d_%.2db' + '.tim';
|
||||
cAutoExtractionPngFormat = '%s_%.6d_%.2db_%.2dc' + '.png';
|
||||
cCLUTGridColsCount = 32;
|
||||
|
||||
sStatusBarScanningFile = 'Scanning File...';
|
||||
sStatusBarTimsExtracting = 'TIMs Extracting...';
|
||||
sStatusBarTimsExtracted = 'Exctracted Successfully!';
|
||||
sStatusBarPngsExtracting = 'PNGs Extracting...';
|
||||
sStatusBarExtracted = 'Exctracted Successfully!';
|
||||
sStatusBarParsingResult = 'Parsing Result...';
|
||||
sScanResultGood = 'Scan completed!';
|
||||
sSelectDirCaption = 'Please, select directory for scan...';
|
||||
|
||||
@@ -576,9 +576,9 @@ object frmMain: TfrmMain
|
||||
TabOrder = 0
|
||||
object lvList: TListView
|
||||
Left = 0
|
||||
Top = 0
|
||||
Top = 49
|
||||
Width = 240
|
||||
Height = 481
|
||||
Height = 432
|
||||
Align = alClient
|
||||
Columns = <
|
||||
item
|
||||
@@ -613,6 +613,39 @@ object frmMain: TfrmMain
|
||||
ViewStyle = vsReport
|
||||
OnChange = lvListChange
|
||||
OnData = lvListData
|
||||
ExplicitLeft = 1
|
||||
ExplicitTop = 28
|
||||
ExplicitHeight = 448
|
||||
end
|
||||
object pnlExtractAll: TPanel
|
||||
Left = 0
|
||||
Top = 0
|
||||
Width = 240
|
||||
Height = 49
|
||||
Align = alTop
|
||||
BevelOuter = bvLowered
|
||||
TabOrder = 1
|
||||
object btnExtractAllTims: TButton
|
||||
Left = 139
|
||||
Top = 1
|
||||
Width = 100
|
||||
Height = 47
|
||||
Action = actExtractPNGs
|
||||
Align = alRight
|
||||
TabOrder = 0
|
||||
WordWrap = True
|
||||
ExplicitLeft = 128
|
||||
end
|
||||
object btnExtractPNGs: TButton
|
||||
Left = 1
|
||||
Top = 1
|
||||
Width = 100
|
||||
Height = 47
|
||||
Action = actExtractTIMs
|
||||
Align = alLeft
|
||||
TabOrder = 1
|
||||
WordWrap = True
|
||||
end
|
||||
end
|
||||
end
|
||||
object pnlImage: TPanel
|
||||
@@ -923,11 +956,17 @@ object frmMain: TfrmMain
|
||||
Caption = '&Open TIMs with T2V'
|
||||
OnExecute = actAssocTimsExecute
|
||||
end
|
||||
object actExtractList: TAction
|
||||
Caption = '&Extract TIMs'
|
||||
object actExtractTIMs: TAction
|
||||
Caption = 'Extract all &TIMs'#13#10'(Shift+F2)'
|
||||
Enabled = False
|
||||
ShortCut = 112
|
||||
OnExecute = actExtractListExecute
|
||||
ShortCut = 8305
|
||||
OnExecute = actExtractTIMsExecute
|
||||
end
|
||||
object actExtractPNGs: TAction
|
||||
Caption = '&Extract all PNGs'#13#10'(Shift+F4)'
|
||||
Enabled = False
|
||||
ShortCut = 8307
|
||||
OnExecute = actExtractPNGsExecute
|
||||
end
|
||||
object actChangeClutIdx: TAction
|
||||
end
|
||||
@@ -941,12 +980,6 @@ object frmMain: TfrmMain
|
||||
object pmList: TPopupMenu
|
||||
Left = 640
|
||||
Top = 502
|
||||
object ExtractTIMs1: TMenuItem
|
||||
Action = actExtractList
|
||||
end
|
||||
object N6: TMenuItem
|
||||
Caption = '-'
|
||||
end
|
||||
object ExtractTIM1: TMenuItem
|
||||
Action = actExtractTim
|
||||
end
|
||||
|
||||
111
units/uMain.pas
111
units/uMain.pas
@@ -77,14 +77,16 @@ type
|
||||
mnTimInfoMain: TMenuItem;
|
||||
actAssocTims: TAction;
|
||||
mnAssociate: TMenuItem;
|
||||
N6: TMenuItem;
|
||||
actExtractList: TAction;
|
||||
ExtractTIMs1: TMenuItem;
|
||||
actExtractTIMs: TAction;
|
||||
pbTim: TImage;
|
||||
btnShowClut: TButton;
|
||||
cbbCLUT: TComboBox;
|
||||
actReturnFocus: TAction;
|
||||
actDrawSelectedTim: TAction;
|
||||
actExtractPNGs: TAction;
|
||||
pnlExtractAll: TPanel;
|
||||
btnExtractAllTims: TButton;
|
||||
btnExtractPNGs: TButton;
|
||||
procedure btnStopScanClick(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure lvListData(Sender: TObject; Item: TListItem);
|
||||
@@ -107,13 +109,14 @@ type
|
||||
procedure actStretchExecute(Sender: TObject);
|
||||
procedure actTimInfoExecute(Sender: TObject);
|
||||
procedure actAssocTimsExecute(Sender: TObject);
|
||||
procedure actExtractListExecute(Sender: TObject);
|
||||
procedure actExtractTIMsExecute(Sender: TObject);
|
||||
procedure cbbTranspModeChange(Sender: TObject);
|
||||
procedure btnShowClutClick(Sender: TObject);
|
||||
procedure lvListChange(Sender: TObject; Item: TListItem;
|
||||
Change: TItemChange);
|
||||
procedure actReturnFocusExecute(Sender: TObject);
|
||||
procedure actDrawSelectedTimExecute(Sender: TObject);
|
||||
procedure actExtractPNGsExecute(Sender: TObject);
|
||||
private
|
||||
{ Private declarations }
|
||||
// pResult: PNativeXml;
|
||||
@@ -134,7 +137,8 @@ type
|
||||
function ListIdx: Integer;
|
||||
function TimIdx(Index: Integer): TScanTim;
|
||||
function SelTim(NewBitMode: Integer = $FF): PTIM;
|
||||
function SelTimName: string;
|
||||
function FormatTimName(const FileName: string; ListIdx_, BitMode: Integer): string;
|
||||
function FormatPngName(const FileName: string; ListIdx_, BitMode, Clut: Integer): string;
|
||||
procedure DrawSelTim;
|
||||
procedure DrawSelClut;
|
||||
procedure UpdateCLUTInfo;
|
||||
@@ -158,7 +162,7 @@ var
|
||||
implementation
|
||||
|
||||
uses
|
||||
uCDIMAGE, uBrowseForFolder, System.Win.Registry;
|
||||
uCDIMAGE, uBrowseForFolder, System.Win.Registry, Vcl.Imaging.pngimage;
|
||||
|
||||
{$R *.dfm}
|
||||
|
||||
@@ -319,10 +323,10 @@ begin
|
||||
Close;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.actExtractListExecute(Sender: TObject);
|
||||
procedure TfrmMain.actExtractTIMsExecute(Sender: TObject);
|
||||
var
|
||||
I, OFFSET, BIT_MODE, SIZE: Integer;
|
||||
FName, TIM_NAME, Path: string;
|
||||
FName, Path: string;
|
||||
IsImage: Boolean;
|
||||
ScanTim: TScanTim;
|
||||
TIM: PTIM;
|
||||
@@ -332,6 +336,8 @@ begin
|
||||
FName := ScanRes.ScanFile;
|
||||
IsImage := ScanRes.IsImage;
|
||||
|
||||
pbProgress.Position := 0;
|
||||
pbProgress.Max := ScanRes.Count;
|
||||
for I := 1 to ScanRes.Count do
|
||||
begin
|
||||
ScanTim := TimIdx(I - 1);
|
||||
@@ -339,26 +345,79 @@ begin
|
||||
SIZE := ScanTim.Size;
|
||||
BIT_MODE := ScanTim.BitMode;
|
||||
|
||||
TIM_NAME := Format(cAutoExtractionTimFormat, [ExtractJustName(FName), I, BIT_MODE]);
|
||||
|
||||
Path := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)) + cExtractedTimsDir);
|
||||
CreateDir(Path);
|
||||
Path := IncludeTrailingPathDelimiter(Path + ExtractFileName(FName));
|
||||
CreateDir(Path);
|
||||
|
||||
TIM := LoadTimFromFile(FName, OFFSET, IsImage, SIZE);
|
||||
SaveTimToFile(Path + TIM_NAME, TIM);
|
||||
SaveTimToFile(Path + FormatTimName(FName, I - 1, BIT_MODE), TIM);
|
||||
FreeTIM(TIM);
|
||||
|
||||
pbProgress.Position := I;
|
||||
Application.ProcessMessages;
|
||||
end;
|
||||
lblStatus.Caption := sStatusBarTimsExtracted;
|
||||
lblStatus.Caption := sStatusBarExtracted;
|
||||
MessageBeep(MB_ICONINFORMATION);
|
||||
pbProgress.Position := 0;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.actExtractPNGsExecute(Sender: TObject);
|
||||
var
|
||||
I, OFFSET, BIT_MODE, SIZE: Integer;
|
||||
FName, Path: string;
|
||||
IsImage: Boolean;
|
||||
ScanTim: TScanTim;
|
||||
TIM: PTIM;
|
||||
PNG_: PPNGImage;
|
||||
begin
|
||||
lblStatus.Caption := sStatusBarPngsExtracting;
|
||||
|
||||
FName := ScanRes.ScanFile;
|
||||
IsImage := ScanRes.IsImage;
|
||||
|
||||
New(PNG_);
|
||||
|
||||
pbProgress.Position := 0;
|
||||
pbProgress.Max := ScanRes.Count;
|
||||
for I := 1 to ScanRes.Count do
|
||||
begin
|
||||
ScanTim := TimIdx(I - 1);
|
||||
OFFSET := ScanTim.Position;
|
||||
SIZE := ScanTim.Size;
|
||||
BIT_MODE := ScanTim.BitMode;
|
||||
|
||||
Path := IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)) + cExtractedPngsDir);
|
||||
CreateDir(Path);
|
||||
Path := IncludeTrailingPathDelimiter(Path + ExtractFileName(FName));
|
||||
CreateDir(Path);
|
||||
|
||||
PNG_^ := TPngImage.CreateBlank(COLOR_RGBALPHA, 16, ScanTim.Width, ScanTim.Height);
|
||||
PNG_^.CompressionLevel := 0;
|
||||
PNG_^.Filters := [];
|
||||
|
||||
TIM := LoadTimFromFile(FName, OFFSET, IsImage, SIZE);
|
||||
TimToPNG(TIM, cbbCLUT.ItemIndex, PNG_, cbbTranspMode.ItemIndex);
|
||||
|
||||
PNG_^.SaveToFile(Path + FormatPngName(FName, I - 1, BIT_MODE, 0));
|
||||
PNG_^.Free;
|
||||
|
||||
FreeTIM(TIM);
|
||||
|
||||
pbProgress.Position := I;
|
||||
Application.ProcessMessages;
|
||||
end;
|
||||
Dispose(PNG_);
|
||||
lblStatus.Caption := sStatusBarExtracted;
|
||||
MessageBeep(MB_ICONINFORMATION);
|
||||
pbProgress.Position := 0;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.actExtractTimExecute(Sender: TObject);
|
||||
var
|
||||
TIM: PTIM;
|
||||
begin
|
||||
dlgSaveTIM.FileName := SelTimName;
|
||||
dlgSaveTIM.FileName := FormatTimName(ScanRes.ScanFile, ListIdx, TimIdx(ListIdx).BitMode);
|
||||
|
||||
if not dlgSaveTIM.Execute then Exit;
|
||||
|
||||
@@ -423,12 +482,8 @@ begin
|
||||
end;
|
||||
|
||||
procedure TfrmMain.actTim2PngExecute(Sender: TObject);
|
||||
var
|
||||
FName: string;
|
||||
begin
|
||||
FName := SelTimName;
|
||||
FName := ChangeFileExt(FName, '.png');
|
||||
dlgSavePNG.FileName := FName;
|
||||
dlgSavePNG.FileName := FormatPngName(ScanRes.ScanFile, ListIdx, TimIdx(ListIdx).BitMode, cbbCLUT.ItemIndex);
|
||||
|
||||
if not dlgSavePNG.Execute then Exit;
|
||||
|
||||
@@ -459,8 +514,8 @@ begin
|
||||
+ Tab + '%s' + Row + Row +
|
||||
|
||||
'HEADER INFO' + Row + 'Version:' + Tab + '%d' + Row + 'BPP:' + Tab + '%d'
|
||||
+ Row + Row, [SelTimName, Index + 1, TimIdx(Index).Position,
|
||||
BppToBitMode(TIM), IsGoodTIM,
|
||||
+ Row + Row, [FormatTimName(ScanRes.ScanFile, Index, TimIdx(Index).BitMode),
|
||||
Index + 1, TimIdx(Index).Position, BppToBitMode(TIM), IsGoodTIM,
|
||||
|
||||
GetTimVersion(TIM), GetTimBPP(TIM)]);
|
||||
|
||||
@@ -558,7 +613,8 @@ begin
|
||||
cbbFiles.Enabled := (cbbFiles.Items.Count <> 0);
|
||||
|
||||
lvList.Enabled := cbbFiles.Enabled;
|
||||
actExtractList.Enabled := cbbFiles.Enabled;
|
||||
actExtractTIMs.Enabled := cbbFiles.Enabled;
|
||||
actExtractPNGs.Enabled := cbbFiles.Enabled;
|
||||
actCloseFile.Enabled := cbbFiles.Enabled;
|
||||
actCloseFiles.Enabled := cbbFiles.Enabled;
|
||||
actReplaceTim.Enabled := (lvList.SelCount = 1);
|
||||
@@ -587,9 +643,14 @@ begin
|
||||
Result^.HEAD^.bBPP := NewBitMode;
|
||||
end;
|
||||
|
||||
function TfrmMain.SelTimName: string;
|
||||
function TfrmMain.FormatTimName(const FileName: string; ListIdx_, BitMode: Integer): string;
|
||||
begin
|
||||
Result := Format(cAutoExtractionTimFormat, [ExtractJustName(ScanRes.ScanFile), ListIdx + 1, TimIdx(ListIdx).BitMode]);
|
||||
Result := Format(cAutoExtractionTimFormat, [ExtractJustName(FileName), ListIdx_ + 1, BitMode]);
|
||||
end;
|
||||
|
||||
function TfrmMain.FormatPngName(const FileName: string; ListIdx_, BitMode, Clut: Integer): string;
|
||||
begin
|
||||
Result := Format(cAutoExtractionPngFormat, [ExtractJustName(FileName), ListIdx_ + 1, BitMode, Clut + 1]);
|
||||
end;
|
||||
|
||||
procedure TfrmMain.DrawSelClut;
|
||||
@@ -647,10 +708,10 @@ begin
|
||||
PNG^ := nil;
|
||||
end;
|
||||
|
||||
if cbbCLUT.Text = sThisTimHasNoClut then
|
||||
(*if cbbCLUT.Text = sThisTimHasNoClut then
|
||||
Index := -1
|
||||
else
|
||||
Index := cbbCLUT.ItemIndex;
|
||||
*)Index := cbbCLUT.ItemIndex;
|
||||
|
||||
TimToPNG(TIM, Index, PNG, cbbTranspMode.ItemIndex);
|
||||
PNG.AssignTo(pbTim.Picture.Bitmap);
|
||||
|
||||
@@ -89,10 +89,7 @@ var
|
||||
begin
|
||||
Synchronize(StartScan);
|
||||
|
||||
pSrcFileStream := TFileStream.Create(pScanResult.ScanFile, fmOpenRead or
|
||||
fmShareDenyWrite);
|
||||
pSrcFileStream.Position := 0;
|
||||
|
||||
try
|
||||
if pScanResult.IsImage then
|
||||
pSectorBufferSize := cSectorBufferSize
|
||||
else
|
||||
@@ -103,6 +100,11 @@ begin
|
||||
SectorBuffer := GetMemory(pSectorBufferSize);
|
||||
ClearBuffer := GetMemory(pClearBufferSize);
|
||||
|
||||
pSrcFileStream := TFileStream.Create(pScanResult.ScanFile, fmOpenRead or
|
||||
fmShareDenyWrite);
|
||||
|
||||
pSrcFileStream.Position := 0;
|
||||
|
||||
TIM := CreateTIM;
|
||||
|
||||
pStatusText := sStatusBarScanningFile;
|
||||
@@ -160,6 +162,7 @@ begin
|
||||
ClearSectorBuffer(SectorBuffer, ClearBuffer);
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
FreeTIM(TIM);
|
||||
FreeMemory(SectorBuffer);
|
||||
FreeMemory(ClearBuffer);
|
||||
@@ -170,6 +173,7 @@ begin
|
||||
pStatusText := '';
|
||||
|
||||
Synchronize(FinishScan);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TScanThread.FinishScan;
|
||||
@@ -201,7 +205,8 @@ procedure TScanThread.StartScan;
|
||||
begin
|
||||
frmMain.cbbFiles.Enabled := False;
|
||||
frmMain.lvList.Enabled := False;
|
||||
frmMain.actExtractList.Enabled := False;
|
||||
frmMain.actExtractTIMs.Enabled := False;
|
||||
frmMain.actExtractPNGs.Enabled := False;
|
||||
|
||||
frmMain.pbProgress.Max := GetFileSizeAPI(pScanResult.ScanFile);
|
||||
frmMain.pbProgress.Position := 0;
|
||||
|
||||
@@ -35,19 +35,19 @@ unit uSettings;
|
||||
|
||||
{ TSettings }
|
||||
|
||||
procedure TCustomSettings.LoadFromFile() ;
|
||||
var
|
||||
procedure TCustomSettings.LoadFromFile() ;
|
||||
var
|
||||
Stream: TStream;
|
||||
begin
|
||||
begin
|
||||
if not FileExists(FFileName) then Exit;
|
||||
|
||||
Stream := TFileStream.Create(FFileName, fmOpenRead or fmShareDenyWrite) ;
|
||||
try
|
||||
Stream := TFileStream.Create(FFileName, fmOpenRead or fmShareDenyWrite) ;
|
||||
LoadFromStream(Stream) ;
|
||||
finally
|
||||
Stream.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCustomSettings.LoadFromStream(const Stream: TStream) ;
|
||||
var
|
||||
|
||||
@@ -372,6 +372,7 @@ var
|
||||
Sector: TCDSector;
|
||||
P, TIM_FULL_SECTORS: Integer;
|
||||
begin
|
||||
try
|
||||
sImageStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
|
||||
|
||||
TimSectorNumber := Position div cSectorSize + 1;
|
||||
@@ -416,12 +417,13 @@ begin
|
||||
LastPartSize := SIZE - P;
|
||||
Move(Sector.dwData[0], TIM_BUF^[P], LastPartSize);
|
||||
end;
|
||||
|
||||
finally
|
||||
P := 0;
|
||||
Result := nil;
|
||||
LoadTimFromBuf(TIM_BUF, Result, P);
|
||||
sImageStream.Free;
|
||||
Dispose(TIM_BUF);
|
||||
end;
|
||||
end;
|
||||
|
||||
function LoadTimFromStream(Stream: TStream; var Position: Integer;
|
||||
@@ -455,9 +457,12 @@ var
|
||||
begin
|
||||
if not ImageScan then
|
||||
begin
|
||||
try
|
||||
sTIM := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
|
||||
Result := LoadTimFromStream(sTIM, Position, dwSize);
|
||||
finally
|
||||
sTIM.Free;
|
||||
end;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
@@ -468,8 +473,7 @@ procedure SaveTimToFile(const FileName: string; TIM: PTIM);
|
||||
var
|
||||
tmp: TMemoryStream;
|
||||
begin
|
||||
if TIM = nil then
|
||||
Exit;
|
||||
if TIM = nil then Exit;
|
||||
|
||||
tmp := TMemoryStream.Create;
|
||||
tmp.Write(TIM^.DATA^[0], TIM^.dwSize);
|
||||
|
||||
Reference in New Issue
Block a user