Another non-Latin fixes. StatusBar with TIM-info. Stability fixes.

This commit is contained in:
meffi@lab313.ru
2014-04-17 23:14:46 +00:00
parent 6c32010405
commit 83bedc86af
7 changed files with 186 additions and 219 deletions

View File

@@ -128,18 +128,7 @@
<UseAnsiStrings Value="False"/> <UseAnsiStrings Value="False"/>
</SyntaxOptions> </SyntaxOptions>
</Parsing> </Parsing>
<CodeGeneration>
<SmartLinkUnit Value="True"/>
<RelocatableUnit Value="True"/>
<Optimizations>
<OptimizationLevel Value="3"/>
</Optimizations>
</CodeGeneration>
<Linking> <Linking>
<Debugging>
<GenerateDebugInfo Value="False"/>
</Debugging>
<LinkSmart Value="True"/>
<Options> <Options>
<Win32> <Win32>
<GraphicApplication Value="True"/> <GraphicApplication Value="True"/>

View File

@@ -9,7 +9,13 @@
<Filename Value="tim2view.lpr"/> <Filename Value="tim2view.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="tim2view"/> <UnitName Value="tim2view"/>
<UsageCount Value="23"/> <IsVisibleTab Value="True"/>
<EditorIndex Value="3"/>
<WindowIndex Value="0"/>
<TopLine Value="1"/>
<CursorPos X="46" Y="9"/>
<UsageCount Value="32"/>
<Loaded Value="True"/>
</Unit0> </Unit0>
<Unit1> <Unit1>
<Filename Value="umain.pas"/> <Filename Value="umain.pas"/>
@@ -20,9 +26,9 @@
<UnitName Value="umain"/> <UnitName Value="umain"/>
<EditorIndex Value="0"/> <EditorIndex Value="0"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="568"/> <TopLine Value="108"/>
<CursorPos X="49" Y="578"/> <CursorPos X="65" Y="113"/>
<UsageCount Value="23"/> <UsageCount Value="32"/>
<Loaded Value="True"/> <Loaded Value="True"/>
<LoadedDesigner Value="True"/> <LoadedDesigner Value="True"/>
</Unit1> </Unit1>
@@ -30,93 +36,94 @@
<Filename Value="edc.pas"/> <Filename Value="edc.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="edc"/> <UnitName Value="edc"/>
<UsageCount Value="23"/> <UsageCount Value="32"/>
</Unit2> </Unit2>
<Unit3> <Unit3>
<Filename Value="ecc.pas"/> <Filename Value="ecc.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="ecc"/> <UnitName Value="ecc"/>
<UsageCount Value="23"/> <UsageCount Value="32"/>
</Unit3> </Unit3>
<Unit4> <Unit4>
<Filename Value="ucommon.pas"/> <Filename Value="ucommon.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="ucommon"/> <UnitName Value="ucommon"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="1"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="1"/> <TopLine Value="1"/>
<CursorPos X="35" Y="6"/> <CursorPos X="35" Y="6"/>
<UsageCount Value="23"/> <UsageCount Value="32"/>
<Loaded Value="True"/>
</Unit4> </Unit4>
<Unit5> <Unit5>
<Filename Value="utim.pas"/> <Filename Value="utim.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="utim"/> <UnitName Value="utim"/>
<EditorIndex Value="5"/> <EditorIndex Value="2"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="259"/> <TopLine Value="311"/>
<CursorPos X="28" Y="283"/> <CursorPos X="7" Y="323"/>
<UsageCount Value="23"/> <UsageCount Value="32"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit5> </Unit5>
<Unit6> <Unit6>
<Filename Value="ucdimage.pas"/> <Filename Value="ucdimage.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="ucdimage"/> <UnitName Value="ucdimage"/>
<EditorIndex Value="2"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="81"/> <TopLine Value="81"/>
<CursorPos X="95" Y="89"/> <CursorPos X="95" Y="89"/>
<UsageCount Value="23"/> <UsageCount Value="32"/>
<Loaded Value="True"/>
</Unit6> </Unit6>
<Unit7> <Unit7>
<Filename Value="usettings.pas"/> <Filename Value="usettings.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="usettings"/> <UnitName Value="usettings"/>
<EditorIndex Value="4"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="17"/> <TopLine Value="17"/>
<CursorPos X="76" Y="31"/> <CursorPos X="76" Y="31"/>
<UsageCount Value="23"/> <UsageCount Value="32"/>
<Loaded Value="True"/>
</Unit7> </Unit7>
<Unit8> <Unit8>
<Filename Value="uscanresult.pas"/> <Filename Value="uscanresult.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="uscanresult"/> <UnitName Value="uscanresult"/>
<UsageCount Value="23"/> <EditorIndex Value="4"/>
<WindowIndex Value="0"/>
<TopLine Value="52"/>
<CursorPos X="64" Y="25"/>
<UsageCount Value="32"/>
<Loaded Value="True"/>
</Unit8> </Unit8>
<Unit9> <Unit9>
<Filename Value="uscanthread.pas"/> <Filename Value="uscanthread.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="uscanthread"/> <UnitName Value="uscanthread"/>
<EditorIndex Value="3"/> <EditorIndex Value="1"/>
<WindowIndex Value="0"/> <WindowIndex Value="0"/>
<TopLine Value="192"/> <TopLine Value="79"/>
<CursorPos X="78" Y="212"/> <CursorPos X="75" Y="120"/>
<UsageCount Value="23"/> <UsageCount Value="32"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit9> </Unit9>
<Unit10> <Unit10>
<Filename Value="ucpucount.pas"/> <Filename Value="ucpucount.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="ucpucount"/> <UnitName Value="ucpucount"/>
<UsageCount Value="23"/> <UsageCount Value="32"/>
</Unit10> </Unit10>
<Unit11> <Unit11>
<Filename Value="udrawtim.pas"/> <Filename Value="udrawtim.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="udrawtim"/> <UnitName Value="udrawtim"/>
<UsageCount Value="23"/> <WindowIndex Value="0"/>
<TopLine Value="220"/>
<CursorPos X="30" Y="233"/>
<UsageCount Value="32"/>
</Unit11> </Unit11>
<Unit12> <Unit12>
<Filename Value="bgrabitmap\bgrabitmap.pas"/> <Filename Value="bgrabitmap\bgrabitmap.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="BGRABitmap"/> <UnitName Value="BGRABitmap"/>
<UsageCount Value="23"/> <UsageCount Value="32"/>
</Unit12> </Unit12>
</Units> </Units>
<General> <General>

View File

@@ -19,7 +19,7 @@ procedure ClearGrid(Grid: PDrawGrid);
implementation implementation
uses uses
ucommon, BGRABitmapTypes; ucommon, BGRABitmapTypes, Math;
function PrepareCLUT(TIM: PTIM; CLUT_NUM: Integer): PCLUT_COLORS; function PrepareCLUT(TIM: PTIM; CLUT_NUM: Integer): PCLUT_COLORS;
var var
@@ -224,19 +224,26 @@ var
CLUT_COLOR: PCLUT_COLOR; CLUT_COLOR: PCLUT_COLOR;
R, G, B, STP, ALPHA: Byte; R, G, B, STP, ALPHA: Byte;
Rect: TRect; Rect: TRect;
COLS: Integer; COLS, Colors: Integer;
begin begin
Colors := GetTimColorsCount(TIM);
COLS := Min(Colors, cCLUTGridColsCount);
Rect := Grid^.CellRect(X, Y);
if (Y * COLS + X) >= Colors then
begin
ClearCanvas(@Grid^.Canvas, Rect);
Exit;
end;
New(CLUT_COLOR); New(CLUT_COLOR);
COLS := Min(GetTimColorsCount(TIM), cCLUTGridColsCount);
CLUT_COLOR^ := GetCLUTColor(TIM, CLUT_NUM, Y * COLS + X); CLUT_COLOR^ := GetCLUTColor(TIM, CLUT_NUM, Y * COLS + X);
R := CLUT_COLOR^.R; R := CLUT_COLOR^.R;
G := CLUT_COLOR^.G; G := CLUT_COLOR^.G;
B := CLUT_COLOR^.B; B := CLUT_COLOR^.B;
STP := CLUT_COLOR^.STP; STP := CLUT_COLOR^.STP;
Rect := Grid^.CellRect(X, Y);
Grid^.Canvas.Brush.COLOR := RGBToColor(R, G, B); Grid^.Canvas.Brush.COLOR := RGBToColor(R, G, B);
Grid^.Canvas.FillRect(Rect); Grid^.Canvas.FillRect(Rect);
@@ -272,7 +279,7 @@ begin
COLORS := GetTimColorsCount(TIM); COLORS := GetTimColorsCount(TIM);
COLS := Min(COLORS, cCLUTGridColsCount); COLS := Min(COLORS, cCLUTGridColsCount);
Grid^.ColCount := COLS; Grid^.ColCount := COLS;
ROWS := COLORS div COLS; ROWS := Ceil(COLORS / COLS);
Grid^.RowCount := ROWS; Grid^.RowCount := ROWS;

View File

@@ -497,7 +497,7 @@ object frmMain: TfrmMain
object pnlStatus: TPanel object pnlStatus: TPanel
Left = 0 Left = 0
Height = 30 Height = 30
Top = 540 Top = 517
Width = 780 Width = 780
Align = alBottom Align = alBottom
BevelOuter = bvLowered BevelOuter = bvLowered
@@ -550,33 +550,33 @@ object frmMain: TfrmMain
end end
object pnlMain: TPanel object pnlMain: TPanel
Left = 0 Left = 0
Height = 519 Height = 496
Top = 21 Top = 21
Width = 780 Width = 780
Align = alClient Align = alClient
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 519 ClientHeight = 496
ClientWidth = 780 ClientWidth = 780
TabOrder = 1 TabOrder = 1
object splMain: TSplitter object splMain: TSplitter
Left = 253 Left = 253
Height = 519 Height = 496
Top = 0 Top = 0
Width = 5 Width = 5
end end
object pnlList: TPanel object pnlList: TPanel
Left = 0 Left = 0
Height = 519 Height = 496
Top = 0 Top = 0
Width = 253 Width = 253
Align = alLeft Align = alLeft
BevelOuter = bvNone BevelOuter = bvNone
ClientHeight = 519 ClientHeight = 496
ClientWidth = 253 ClientWidth = 253
TabOrder = 0 TabOrder = 0
object lvList: TListView object lvList: TListView
Left = 0 Left = 0
Height = 491 Height = 468
Top = 28 Top = 28
Width = 253 Width = 253
Align = alClient Align = alClient
@@ -644,12 +644,12 @@ object frmMain: TfrmMain
end end
object pnlImage: TPanel object pnlImage: TPanel
Left = 258 Left = 258
Height = 519 Height = 496
Top = 0 Top = 0
Width = 522 Width = 522
Align = alClient Align = alClient
BevelOuter = bvLowered BevelOuter = bvLowered
ClientHeight = 519 ClientHeight = 496
ClientWidth = 522 ClientWidth = 522
Color = clBtnFace Color = clBtnFace
ParentColor = False ParentColor = False
@@ -669,9 +669,10 @@ object frmMain: TfrmMain
object grdCurrClut: TDrawGrid object grdCurrClut: TDrawGrid
Left = 1 Left = 1
Height = 150 Height = 150
Top = 343 Top = 320
Width = 520 Width = 520
Align = alBottom Align = alBottom
AutoEdit = False
ColCount = 1 ColCount = 1
DefaultColWidth = 14 DefaultColWidth = 14
DefaultRowHeight = 14 DefaultRowHeight = 14
@@ -681,7 +682,7 @@ object frmMain: TfrmMain
FixedRows = 0 FixedRows = 0
Options = [goFixedVertLine, goFixedHorzLine, goDrawFocusSelected] Options = [goFixedVertLine, goFixedHorzLine, goDrawFocusSelected]
RowCount = 1 RowCount = 1
ScrollBars = ssNone ScrollBars = ssAutoVertical
TabOrder = 0 TabOrder = 0
TitleFont.Color = clWindowText TitleFont.Color = clWindowText
TitleFont.Height = -11 TitleFont.Height = -11
@@ -694,7 +695,7 @@ object frmMain: TfrmMain
object pnlImageOptions: TPanel object pnlImageOptions: TPanel
Left = 1 Left = 1
Height = 25 Height = 25
Top = 493 Top = 470
Width = 520 Width = 520
Align = alBottom Align = alBottom
AutoSize = True AutoSize = True
@@ -774,16 +775,52 @@ object frmMain: TfrmMain
end end
object imgTim: TImage object imgTim: TImage
Left = 1 Left = 1
Height = 339 Height = 316
Top = 4 Top = 4
Width = 520 Width = 520
AntialiasingMode = amOff AntialiasingMode = amOff
Align = alClient Align = alClient
Center = True Center = True
PopupMenu = pmImage PopupMenu = pmImage
Proportional = True
end end
end end
end end
object sbMain: TStatusBar
Left = 0
Height = 23
Top = 547
Width = 780
Panels = <
item
Width = 50
end
item
Width = 50
end
item
Width = 50
end
item
Width = 50
end
item
Width = 50
end
item
Width = 50
end
item
Width = 50
end
item
Width = 50
end
item
Width = 50
end>
SimplePanel = False
end
object dlgOpenFile: TOpenDialog object dlgOpenFile: TOpenDialog
Title = 'Please, select File...' Title = 'Please, select File...'
DefaultExt = '.bin' DefaultExt = '.bin'
@@ -818,15 +855,6 @@ object frmMain: TfrmMain
end end
object mnTIM: TMenuItem object mnTIM: TMenuItem
Caption = '&TIM' Caption = '&TIM'
object mnExtractAllTims: TMenuItem
Action = actExtractTIMs
end
object mnExtractAllPngs: TMenuItem
Action = actExtractPNGs
end
object N6: TMenuItem
Caption = '-'
end
object mnSaveTIM: TMenuItem object mnSaveTIM: TMenuItem
Action = actExtractTim Action = actExtractTim
end end
@@ -836,12 +864,6 @@ object frmMain: TfrmMain
object mnSaveToPNG: TMenuItem object mnSaveToPNG: TMenuItem
Action = actTim2Png Action = actTim2Png
end end
object N4: TMenuItem
Caption = '-'
end
object mnTimInfoMain: TMenuItem
Action = actTimInfo
end
end end
object mnOptions: TMenuItem object mnOptions: TMenuItem
Caption = '&Options' Caption = '&Options'
@@ -978,11 +1000,6 @@ object frmMain: TfrmMain
Caption = '&Stretch Image' Caption = '&Stretch Image'
OnExecute = actStretchExecute OnExecute = actStretchExecute
end end
object actTimInfo: TAction
Caption = '&TIM Info...'
Enabled = False
OnExecute = actTimInfoExecute
end
object actAssocTims: TAction object actAssocTims: TAction
Caption = '&Open TIMs with T2V' Caption = '&Open TIMs with T2V'
OnExecute = actAssocTimsExecute OnExecute = actAssocTimsExecute
@@ -1037,12 +1054,6 @@ object frmMain: TfrmMain
object mnExtractAllPngs2: TMenuItem object mnExtractAllPngs2: TMenuItem
Action = actExtractPNGs Action = actExtractPNGs
end end
object N2: TMenuItem
Caption = '-'
end
object mnTIMInfo: TMenuItem
Action = actTimInfo
end
end end
object pmImage: TPopupMenu object pmImage: TPopupMenu
left = 472 left = 472

139
umain.pas
View File

@@ -36,7 +36,6 @@ type
actList: TActionList; actList: TActionList;
actStretch: TAction; actStretch: TAction;
actTim2Png: TAction; actTim2Png: TAction;
actTimInfo: TAction;
btnExtractAllTims: TButton; btnExtractAllTims: TButton;
btnExtractPNGs: TButton; btnExtractPNGs: TButton;
btnShowClut: TButton; btnShowClut: TButton;
@@ -62,9 +61,6 @@ type
mnExtractAllTims2: TMenuItem; mnExtractAllTims2: TMenuItem;
N7: TMenuItem; N7: TMenuItem;
mnStretchImage: TMenuItem; mnStretchImage: TMenuItem;
mnExtractAllPngs: TMenuItem;
mnExtractAllTims: TMenuItem;
N6: TMenuItem;
mnSaveAsPng: TMenuItem; mnSaveAsPng: TMenuItem;
mnAbout: TMenuItem; mnAbout: TMenuItem;
mnAssociate: TMenuItem; mnAssociate: TMenuItem;
@@ -84,12 +80,8 @@ type
mnStretch: TMenuItem; mnStretch: TMenuItem;
mnSVN: TMenuItem; mnSVN: TMenuItem;
mnTIM: TMenuItem; mnTIM: TMenuItem;
mnTIMInfo: TMenuItem;
mnTimInfoMain: TMenuItem;
N1: TMenuItem; N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem; N3: TMenuItem;
N4: TMenuItem;
N5: TMenuItem; N5: TMenuItem;
pbProgress: TProgressBar; pbProgress: TProgressBar;
pnlExtractAll: TPanel; pnlExtractAll: TPanel;
@@ -105,6 +97,7 @@ type
dlgSelectDir: TSelectDirectoryDialog; dlgSelectDir: TSelectDirectoryDialog;
splImageClut: TSplitter; splImageClut: TSplitter;
splMain: TSplitter; splMain: TSplitter;
sbMain: TStatusBar;
procedure actAboutExecute(Sender: TObject); procedure actAboutExecute(Sender: TObject);
procedure actAssocTimsExecute(Sender: TObject); procedure actAssocTimsExecute(Sender: TObject);
procedure actChangeBackColorExecute(Sender: TObject); procedure actChangeBackColorExecute(Sender: TObject);
@@ -125,7 +118,6 @@ type
procedure actStopScanExecute(Sender: TObject); procedure actStopScanExecute(Sender: TObject);
procedure actStretchExecute(Sender: TObject); procedure actStretchExecute(Sender: TObject);
procedure actTim2PngExecute(Sender: TObject); procedure actTim2PngExecute(Sender: TObject);
procedure actTimInfoExecute(Sender: TObject);
procedure btnShowClutClick(Sender: TObject); procedure btnShowClutClick(Sender: TObject);
procedure cbbBitModeChange(Sender: TObject); procedure cbbBitModeChange(Sender: TObject);
procedure cbbTranspModeChange(Sender: TObject); procedure cbbTranspModeChange(Sender: TObject);
@@ -133,11 +125,9 @@ type
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure FormDropFiles(Sender: TObject; const FileNames: array of string); procedure FormDropFiles(Sender: TObject; const FileNames: array of string);
procedure grdCurrClutDblClick(Sender: TObject); procedure grdCurrClutDblClick(Sender: TObject);
procedure grdCurrClutDrawCell(Sender: TObject; aCol, aRow: Integer; procedure grdCurrClutDrawCell(Sender: TObject; aCol, aRow: Integer; aRect: TRect; aState: TGridDrawState);
aRect: TRect; aState: TGridDrawState);
procedure lvListData(Sender: TObject; Item: TListItem); procedure lvListData(Sender: TObject; Item: TListItem);
procedure lvListSelectItem(Sender: TObject; Item: TListItem; procedure lvListSelectItem(Sender: TObject; Item: TListItem; Selected: Boolean);
Selected: Boolean);
private private
{ private declarations } { private declarations }
StartedScans: Integer; //Count of currently started scans StartedScans: Integer; //Count of currently started scans
@@ -174,6 +164,7 @@ type
function FormatTimName(const FileName: string; ListIdx_, BitMode: Integer): string; function FormatTimName(const FileName: string; ListIdx_, BitMode: Integer): string;
function FormatPngName(const FileName: string; ListIdx_, BitMode, Clut: Integer): string; function FormatPngName(const FileName: string; ListIdx_, BitMode, Clut: Integer): string;
procedure ShowTim; procedure ShowTim;
procedure ShowTimInfo(ShowInfo: Boolean);
public public
{ public declarations } { public declarations }
ScanResults: TScanResultList; //List of finished scan results ScanResults: TScanResultList; //List of finished scan results
@@ -186,7 +177,7 @@ var
implementation implementation
uses ucdimage, ucpucount, lcltype, ucommon, LCLIntf, Clipbrd uses ucdimage, ucpucount, lcltype, ucommon, LCLIntf
{$IFDEF windows} {$IFDEF windows}
,registry ,registry
@@ -240,63 +231,6 @@ begin
Surf^.SaveToFile(UTF8ToSys(dlgSavePNG.FileName)); Surf^.SaveToFile(UTF8ToSys(dlgSavePNG.FileName));
end; end;
procedure TfrmMain.actTimInfoExecute(Sender: TObject);
const
Tab = #$09;
Row = #10;
var
Info, IsGoodTIM: string;
Index: Integer;
TIM: PTIM;
begin
if actTimInfo.Enabled then
begin
Index := SelectedTimIdx;
TIM := SelectedTim;
if TIMIsGood(TIM) then
IsGoodTIM := 'YES'
else
IsGoodTIM := 'NO';
Info := Format('"%s" Information' + Row + 'Number:' + Tab + '%d' + Row +
'Position:' + Tab + '0x%x' + Row + 'BitMode:' + Tab + '%d' + Row + 'Good:'
+ Tab + '%s' + Row + Row +
'HEADER INFO' + Row + 'Version:' + Tab + '%d' + Row + 'BPP:' + Tab + '%d'
+ Row + Row, [FormatTimName(SelectedScanResult.ScanFile, Index, SelectedTimInfo.BitMode),
Index + 1, SelectedTimInfo.Position, BppToBitMode(TIM), IsGoodTIM,
GetTimVersion(TIM), GetTimBPP(TIM)]);
if TIMHasCLUT(TIM) then
Info := Format(Info + 'CLUT INFO' + Row + 'Size (Header):' + Tab + '%d' +
Row + 'Size (Real):' + Tab + '%d' + Row + 'VRAM X Pos:' + Tab + '%d' +
Row + 'VRAM Y Pos:' + Tab + '%d' + Row + 'CLUTs Count:' + Tab + '%d' +
Row + 'Colors in 1 CLUT:' + Tab + '%d' + Row + Row,
[GetTimClutSizeHeader(TIM), GetTimClutSize(TIM), GetTimClutVRAMX(TIM),
GetTimClutVRAMY(TIM), GetTIMClutsCount(TIM), GetTimColorsCount(TIM)]);
Info := Format(Info + 'IMAGE INFO' + Row + 'Size (Header):' + Tab + '%d' +
Row + 'Size (Real):' + Tab + '%d' + Row + 'VRAM X Pos:' + Tab + '%d' + Row
+ 'VRAM Y Pos:' + Tab + '%d' + Row + 'Width (Header):' + Tab + '%d' + Row
+ 'Width (Real):' + Tab + '%d' + Row + 'Height (Real):' + Tab + '%d',
[GetTimImageSizeHeader(TIM), GetTimImageSize(TIM), GetTimImageVRAMX(TIM),
GetTimImageVRAMY(TIM), GetTimWidth(TIM), GetTimRealWidth(TIM),
GetTimHeight(TIM)]);
case Application.MessageBox(
PChar(Info + Row + Row +
'If you want to copy this info to clipboard press "YES" button.'),
'Information', MB_OKCANCEL + MB_ICONINFORMATION) of
IDOK:
Clipboard.AsText := Info;
end;
FreeTIM(TIM);
end;
end;
procedure TfrmMain.btnShowClutClick(Sender: TObject); procedure TfrmMain.btnShowClutClick(Sender: TObject);
begin begin
grdCurrClut.Visible := not grdCurrClut.Visible; grdCurrClut.Visible := not grdCurrClut.Visible;
@@ -380,7 +314,7 @@ begin
ScanResults.Delete(cbbFiles.ItemIndex); ScanResults.Delete(cbbFiles.ItemIndex);
lblStatus.Caption := ''; lblStatus.Caption := '';
actTimInfo.Enabled := False; ShowTimInfo(False);
SetTimsListCount(0); SetTimsListCount(0);
UpdateCLUTInfo; UpdateCLUTInfo;
@@ -621,7 +555,7 @@ begin
SELECTED_CELL := grdCurrCLUT.Row * grdCurrCLUT.ColCount + grdCurrCLUT.Col; SELECTED_CELL := grdCurrCLUT.Row * grdCurrCLUT.ColCount + grdCurrCLUT.Col;
W := GetTimColorsCount(TIM); W := GetTimColorsCount(TIM);
if (SELECTED_CELL + 1) > W then if SELECTED_CELL >= W then
begin begin
FreeTIM(TIM); FreeTIM(TIM);
Exit; Exit;
@@ -809,20 +743,20 @@ var
Dir: string; Dir: string;
begin begin
Dir := IncludeTrailingPathDelimiter(Directory); Dir := IncludeTrailingPathDelimiter(Directory);
isFound := FindFirstUTF8(Dir + '*', faAnyFile, sRec) = 0; isFound := FindFirst(UTF8ToSys(Dir + '*'), faAnyFile, sRec) = 0;
while isFound do while isFound do
begin begin
if (sRec.Name <> '.') and (sRec.Name <> '..') then if (sRec.Name <> '.') and (sRec.Name <> '..') then
begin begin
if (sRec.Attr and faDirectory) = faDirectory then if (sRec.Attr and faDirectory) = faDirectory then
ScanDirectory(Dir + sRec.Name) ScanDirectory(Dir + SysToUTF8(sRec.Name))
else else
ScanFile(Dir + sRec.Name); ScanFile(Dir + SysToUTF8(sRec.Name));
end; end;
Application.ProcessMessages; Application.ProcessMessages;
isFound := FindNextUTF8(sRec) = 0; isFound := FindNext(sRec) = 0;
end; end;
FindCloseUTF8(sRec); FindClose(sRec);
end; end;
procedure TfrmMain.CheckButtonsAndMainMenu; procedure TfrmMain.CheckButtonsAndMainMenu;
@@ -1011,10 +945,57 @@ begin
DrawSelTim; DrawSelTim;
DrawSelClut; DrawSelClut;
actTimInfo.Enabled := True; ShowTimInfo(True);
CheckButtonsAndMainMenu; CheckButtonsAndMainMenu;
end; end;
procedure TfrmMain.ShowTimInfo(ShowInfo: Boolean);
var
I: Integer;
TIM: PTIM;
ScanRes: TScanResult;
TimInfo: TTimInfo;
begin
for I := 1 to sbMain.Panels.Count do
sbMain.Panels[I - 1].Text := '';
if not ShowInfo then Exit;
ScanRes := SelectedScanResult;
TimInfo := SelectedTimInfo;
TIM := SelectedTim;
I := 0;
sbMain.Panels[I].Text := Format('Position: 0x%x', [TimInfo.Position]);
sbMain.Panels[I].Width := Canvas.GetTextWidth(sbMain.Panels[I].Text) + 8; Inc(I);
sbMain.Panels[I].Text := Format('Version: %d', [GetTimVersion(TIM)]);
sbMain.Panels[I].Width := Canvas.GetTextWidth(sbMain.Panels[I].Text) + 8; Inc(I);
if TIMHasCLUT(TIM) then
begin
sbMain.Panels[I].Alignment := taRightJustify;
sbMain.Panels[I].Text := 'CLUT:';
sbMain.Panels[I].Width := Canvas.GetTextWidth(sbMain.Panels[I].Text) + 20; Inc(I);
sbMain.Panels[I].Text := Format('VRAM.X: %d', [GetTimClutVRAMX(TIM)]);
sbMain.Panels[I].Width := Canvas.GetTextWidth(sbMain.Panels[I].Text) + 8; Inc(I);
sbMain.Panels[I].Text := Format('VRAM.Y: %d', [GetTimClutVRAMY(TIM)]);
sbMain.Panels[I].Width := Canvas.GetTextWidth(sbMain.Panels[I].Text) + 8; Inc(I);
sbMain.Panels[I].Text := Format('Colors/CLUT: %d', [GetTimColorsCount(TIM)]);
sbMain.Panels[I].Width := Canvas.GetTextWidth(sbMain.Panels[I].Text) + 8; Inc(I);
end;
sbMain.Panels[I].Alignment := taRightJustify;
sbMain.Panels[I].Text := 'IMAGE:';
sbMain.Panels[I].Width := Canvas.GetTextWidth(sbMain.Panels[I].Text) + 20; Inc(I);
sbMain.Panels[I].Text := Format('VRAM.X: %d', [GetTimImageVRAMX(TIM)]);
sbMain.Panels[I].Width := Canvas.GetTextWidth(sbMain.Panels[I].Text) + 8; Inc(I);
sbMain.Panels[I].Text := Format('VRAM.Y: %d', [GetTimImageVRAMY(TIM)]);
sbMain.Panels[I].Width := Canvas.GetTextWidth(sbMain.Panels[I].Text) + 8; Inc(I);
FreeTIM(TIM);
end;
end. end.

View File

@@ -116,7 +116,7 @@ begin
pScanFinished := False; pScanFinished := False;
pTIMNumber := 0; pTIMNumber := 0;
while (not pStopScan) or (not Terminated) do while (not pStopScan) and (not Terminated) do
begin begin
if LoadTimFromBuf(ClearBuffer, TIM, pClearBufferPosition) then if LoadTimFromBuf(ClearBuffer, TIM, pClearBufferPosition) then
begin begin

View File

@@ -24,8 +24,7 @@ const
cTIMWrongBads = [cTIM4NC, cTIM8NC, cTIMMix]; cTIMWrongBads = [cTIM4NC, cTIM8NC, cTIMMix];
cTIMCLUT = [cTIM4C, cTIM8C, cTIM16C, cTIM24C]; cTIMCLUT = [cTIM4C, cTIM8C, cTIM16C, cTIM24C];
cTIMNOCLUT = [cTIM4NC, cTIM8NC, cTIM16NC, cTIM24NC, cTIMMix]; cTIMNOCLUT = [cTIM4NC, cTIM8NC, cTIM16NC, cTIM24NC, cTIMMix];
cTIMBpp = [cTIM4C, cTIM8C, cTIM16C, cTIM24C, cTIM4NC, cTIM8NC, cTIM16NC, cTIMBpp = [cTIM4C, cTIM8C, cTIM16C, cTIM24C, cTIM4NC, cTIM8NC, cTIM16NC, cTIM24NC, cTIMMix];
cTIM24NC, cTIMMix];
cCLUTColorsMax = 1024; cCLUTColorsMax = 1024;
cCLUTCountMax = 512; cCLUTCountMax = 512;
@@ -35,8 +34,7 @@ const
cIMAGEHeadSize = $0C; cIMAGEHeadSize = $0C;
cTIMHeadSize = 8; cTIMHeadSize = 8;
cRandomPaletteSize = $100; cRandomPaletteSize = $100;
cTIMMaxSize = cTIMHeadSize + cCLUTColorsMax * cCLUTCountMax * 2 + cTIMMaxSize = cTIMHeadSize + cCLUTColorsMax * cCLUTCountMax * 2 + cCLUTHeadSize + cIMAGEWidthMax * cIMAGEHeightMax * 2 + cIMAGEHeadSize;
cCLUTHeadSize + cIMAGEWidthMax * cIMAGEHeightMax * 2 + cIMAGEHeadSize;
type type
TTIMHeader = packed record // TIM Header (8 bytes) TTIMHeader = packed record // TIM Header (8 bytes)
@@ -92,8 +90,7 @@ type
PCLUT_COLORS = ^TCLUT_COLORS; PCLUT_COLORS = ^TCLUT_COLORS;
type type
TIMAGE_INDEXES = array [0 .. cIMAGEWidthMax * cIMAGEHeightMax * 4 - TIMAGE_INDEXES = array [0 .. cIMAGEWidthMax * cIMAGEHeightMax * 4 - 1] of Integer;
1] of Integer;
PIMAGE_INDEXES = ^TIMAGE_INDEXES; PIMAGE_INDEXES = ^TIMAGE_INDEXES;
type type
@@ -117,10 +114,8 @@ function GetTimWidth(TIM: PTIM): word;
function GetTimRealWidth(TIM: PTIM): word; function GetTimRealWidth(TIM: PTIM): word;
function GetTimHeight(TIM: PTIM): word; function GetTimHeight(TIM: PTIM): word;
function TIMIsGood(TIM: PTIM): Boolean; function TIMIsGood(TIM: PTIM): Boolean;
function LoadTimFromBuf(BUFFER: pointer; var TIM: PTIM; function LoadTimFromBuf(BUFFER: pointer; var TIM: PTIM; var Position: Integer): Boolean;
var Position: Integer): Boolean; function LoadTimFromFile(const FileName: string; var Position: Integer; ImageScan: Boolean; dwSize: Integer): PTIM;
function LoadTimFromFile(const FileName: string; var Position: Integer;
ImageScan: Boolean; dwSize: Integer): PTIM;
procedure SaveTimToFile(const FileName: string; TIM: PTIM); procedure SaveTimToFile(const FileName: string; TIM: PTIM);
function CreateTIM: PTIM; function CreateTIM: PTIM;
procedure FreeTIM(TIM: PTIM); procedure FreeTIM(TIM: PTIM);
@@ -137,8 +132,7 @@ function GetTimImageVRAMX(TIM: PTIM): word;
function GetTimImageVRAMY(TIM: PTIM): word; function GetTimImageVRAMY(TIM: PTIM): word;
function GetTIMIMAGESize(TIM: PTIM): Integer; function GetTIMIMAGESize(TIM: PTIM): Integer;
function GetCLUTColor(TIM: PTIM; CLUT_NUM, COLOR_NUM: Integer): TCLUT_COLOR; function GetCLUTColor(TIM: PTIM; CLUT_NUM, COLOR_NUM: Integer): TCLUT_COLOR;
procedure WriteCLUTColor(TIM: PTIM; CLUT_NUM, COLOR_NUM: Integer; procedure WriteCLUTColor(TIM: PTIM; CLUT_NUM, COLOR_NUM: Integer; COLOR: TCLUT_COLOR);
COLOR: TCLUT_COLOR);
function ConvertTIMColor(COLOR: word): TCLUT_COLOR; function ConvertTIMColor(COLOR: word): TCLUT_COLOR;
function ConvertCLUTColor(COLOR: TCLUT_COLOR): word; function ConvertCLUTColor(COLOR: TCLUT_COLOR): word;
@@ -190,8 +184,7 @@ begin
CLUT_OFFSET := CLUT_NUM * GetTimColorsCount(TIM) * 2; CLUT_OFFSET := CLUT_NUM * GetTimColorsCount(TIM) * 2;
COLOR_TO_WRITE := ConvertCLUTColor(COLOR); COLOR_TO_WRITE := ConvertCLUTColor(COLOR);
Move(COLOR_TO_WRITE, TIM^.DATA^[cTIMHeadSize + cCLUTHeadSize + COLOR_NUM * 2 + Move(COLOR_TO_WRITE, TIM^.DATA^[cTIMHeadSize + cCLUTHeadSize + COLOR_NUM * 2 + CLUT_OFFSET], 2);
CLUT_OFFSET], 2);
end; end;
function GetTimHeight(TIM: PTIM): word; function GetTimHeight(TIM: PTIM): word;
@@ -203,10 +196,8 @@ function GetTIMCLUTSize(TIM: PTIM): Integer;
begin begin
Result := 0; Result := 0;
if not TIMHasCLUT(TIM) then if not TIMHasCLUT(TIM) then Exit;
Exit; Result := TIM^.CLUT^.wColorsCount * TIM^.CLUT^.wClutsCount * 2 + cCLUTHeadSize;
Result := TIM^.CLUT^.wColorsCount * TIM^.CLUT^.wClutsCount * 2 +
cCLUTHeadSize;
end; end;
function GetTIMIMAGESize(TIM: PTIM): Integer; function GetTIMIMAGESize(TIM: PTIM): Integer;
@@ -246,27 +237,21 @@ end;
function CheckCLUTColors(TIM: PTIM): Boolean; function CheckCLUTColors(TIM: PTIM): Boolean;
begin begin
Result := (TIM^.CLUT^.wColorsCount >= 1) and Result := (TIM^.CLUT^.wColorsCount >= 1) and (TIM^.CLUT^.wColorsCount <= cCLUTColorsMax);
(TIM^.CLUT^.wColorsCount <= cCLUTColorsMax);
end; end;
function CheckCLUTCount(TIM: PTIM): Boolean; function CheckCLUTCount(TIM: PTIM): Boolean;
begin begin
Result := (TIM^.CLUT^.wClutsCount >= 1) and Result := (TIM^.CLUT^.wClutsCount >= 1) and (TIM^.CLUT^.wClutsCount <= cCLUTCountMax);
(TIM^.CLUT^.wClutsCount <= cCLUTCountMax);
end; end;
function IWidthToRWidth(TIM: PTIM): word; function IWidthToRWidth(TIM: PTIM): word;
begin begin
case TIM^.HEAD^.bBPP of case TIM^.HEAD^.bBPP of
cTIM4C, cTIM4NC: cTIM4C, cTIM4NC: Result := (TIM^.IMAGE^.wWidth * 4) and $FFFF;
Result := (TIM^.IMAGE^.wWidth * 4) and $FFFF; cTIM8C, cTIM8NC: Result := (TIM^.IMAGE^.wWidth * 2) and $FFFF;
cTIM8C, cTIM8NC: cTIM16C, cTIM16NC, cTIMMix: Result := TIM^.IMAGE^.wWidth;
Result := (TIM^.IMAGE^.wWidth * 2) and $FFFF; cTIM24C, cTIM24NC: Result := (Round(TIM^.IMAGE^.wWidth * 2 / 3)) and $FFFF;
cTIM16C, cTIM16NC, cTIMMix:
Result := TIM^.IMAGE^.wWidth;
cTIM24C, cTIM24NC:
Result := (Round(TIM^.IMAGE^.wWidth * 2 / 3)) and $FFFF;
else else
Result := 0; Result := 0;
end; end;
@@ -274,8 +259,7 @@ end;
function CheckHEAD(TIM: PTIM): Boolean; function CheckHEAD(TIM: PTIM): Boolean;
begin begin
Result := (CheckMagic(TIM) and CheckVersion(TIM) and CheckBpp(TIM) and Result := (CheckMagic(TIM) and CheckVersion(TIM) and CheckBpp(TIM) and CheckReserved(TIM))
CheckReserved(TIM))
end; end;
function CheckCLUT(TIM: PTIM): Boolean; function CheckCLUT(TIM: PTIM): Boolean;
@@ -299,12 +283,9 @@ function CheckIMAGE(TIM: PTIM): Boolean;
begin begin
Result := False; Result := False;
if (TIM^.IMAGE^.wWidth = 0) or (TIM^.IMAGE^.wHeight = 0) then if (TIM^.IMAGE^.wWidth = 0) or (TIM^.IMAGE^.wHeight = 0) then Exit;
Exit;
if (TIM^.IMAGE^.wWidth > cIMAGEWidthMax) or if (TIM^.IMAGE^.wWidth > cIMAGEWidthMax) or (TIM^.IMAGE^.wHeight > cIMAGEHeightMax) then Exit;
(TIM^.IMAGE^.wHeight > cIMAGEHeightMax) then
Exit;
Result := (not(TIM^.HEAD^.bBPP in cTIMWrongBads)) or TIMIsGood(TIM); Result := (not(TIM^.HEAD^.bBPP in cTIMWrongBads)) or TIMIsGood(TIM);
end; end;
@@ -317,8 +298,7 @@ begin
FillChar(TIM^.DATA^, cTIMMaxSize, 0); FillChar(TIM^.DATA^, cTIMMaxSize, 0);
end; end;
function LoadTimFromBuf(BUFFER: pointer; var TIM: PTIM; function LoadTimFromBuf(BUFFER: pointer; var TIM: PTIM; var Position: Integer): Boolean;
var Position: Integer): Boolean;
var var
P: Integer; P: Integer;
TIM_POS: Integer; TIM_POS: Integer;
@@ -329,28 +309,23 @@ begin
Inc(Position); Inc(Position);
TIM_POS := P; TIM_POS := P;
if TIM = nil then if TIM = nil then TIM := CreateTIM;
TIM := CreateTIM;
Move(PBytesArray(BUFFER)^[P], TIM^.HEAD^, cTIMHeadSize); Move(PBytesArray(BUFFER)^[P], TIM^.HEAD^, cTIMHeadSize);
if not CheckHEAD(TIM) then if not CheckHEAD(TIM) then Exit;
Exit;
Inc(P, cTIMHeadSize); Inc(P, cTIMHeadSize);
if TIMHasCLUT(TIM) then if TIMHasCLUT(TIM) then
begin begin
Move(PBytesArray(BUFFER)^[P], TIM^.CLUT^, cCLUTHeadSize); Move(PBytesArray(BUFFER)^[P], TIM^.CLUT^, cCLUTHeadSize);
if not CheckCLUT(TIM) then if not CheckCLUT(TIM) then Exit;
Exit;
Inc(P, GetTIMCLUTSize(TIM)); Inc(P, GetTIMCLUTSize(TIM));
end; end;
Move(PBytesArray(BUFFER)^[P], TIM^.IMAGE^, cIMAGEHeadSize); Move(PBytesArray(BUFFER)^[P], TIM^.IMAGE^, cIMAGEHeadSize);
if not CheckIMAGE(TIM) then if not CheckIMAGE(TIM) then Exit;
Exit; if not CheckTIMSize(TIM) then Exit;
if not CheckTIMSize(TIM) then
Exit;
TIM^.dwSize := GetTIMSize(TIM); TIM^.dwSize := GetTIMSize(TIM);
TIM^.bGOOD := TIMIsGood(TIM); TIM^.bGOOD := TIMIsGood(TIM);
@@ -381,8 +356,7 @@ begin
New(TIM_BUF); New(TIM_BUF);
P := 0; P := 0;
if SIZE < FirstPartSize then if SIZE < FirstPartSize then FirstPartSize := SIZE;
FirstPartSize := SIZE;
sImageStream.Seek(TimStartSectorPos, soBeginning); sImageStream.Seek(TimStartSectorPos, soBeginning);
sImageStream.Read(Sector, cSectorSize); sImageStream.Read(Sector, cSectorSize);
@@ -432,8 +406,7 @@ var
begin begin
Result := nil; Result := nil;
if dwSize > cTIMMaxSize then if dwSize > cTIMMaxSize then Exit;
Exit;
New(BUF); New(BUF);
Result := CreateTIM; Result := CreateTIM;
@@ -442,8 +415,7 @@ begin
Stream.Read(BUF^[0], dwSize); Stream.Read(BUF^[0], dwSize);
P := 0; P := 0;
if not LoadTimFromBuf(BUF, Result, P) then if not LoadTimFromBuf(BUF, Result, P) then FreeTIM(Result);
FreeTIM(Result);
Dispose(BUF); Dispose(BUF);
end; end;