- Removed Simple Mode;

- Fixed Different Bitmode View;
 - Fixed Directory Scan;
 - Other improvements.
This commit is contained in:
meffi@lab313.ru
2014-02-18 22:07:44 +00:00
parent b84a8264a2
commit 20f1dbf7ce
17 changed files with 445 additions and 11990 deletions

View File

@@ -14,7 +14,8 @@ uses
uTIM in 'units\uTIM.pas', uTIM in 'units\uTIM.pas',
uDrawTIM in 'units\uDrawTIM.pas', uDrawTIM in 'units\uDrawTIM.pas',
uEventWaitThread in 'units\uEventWaitThread.pas', uEventWaitThread in 'units\uEventWaitThread.pas',
uBrowseForFolder in 'units\uBrowseForFolder.pas'; uBrowseForFolder in 'units\uBrowseForFolder.pas',
uScanResult in 'units\uScanResult.pas';
{$R *.res} {$R *.res}
@@ -56,7 +57,7 @@ begin
Application.Initialize; Application.Initialize;
Application.MainFormOnTaskbar := True; Application.MainFormOnTaskbar := True;
Application.CreateForm(TfrmMainT2V, frmMain); Application.CreateForm(TfrmMain, frmMain);
Application.Run; Application.Run;
CloseHandle(ServerMailSlot); CloseHandle(ServerMailSlot);

View File

@@ -1,7 +1,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<ProjectGuid>{20D93FC8-189B-40E7-8CB2-DBD3BD57B0B5}</ProjectGuid> <ProjectGuid>{20D93FC8-189B-40E7-8CB2-DBD3BD57B0B5}</ProjectGuid>
<ProjectVersion>14.6</ProjectVersion> <ProjectVersion>15.1</ProjectVersion>
<FrameworkType>VCL</FrameworkType> <FrameworkType>VCL</FrameworkType>
<MainSource>tim2view.dpr</MainSource> <MainSource>tim2view.dpr</MainSource>
<Base>True</Base> <Base>True</Base>
@@ -83,8 +83,8 @@
<DCC_SUSPICIOUS_TYPECAST>false</DCC_SUSPICIOUS_TYPECAST> <DCC_SUSPICIOUS_TYPECAST>false</DCC_SUSPICIOUS_TYPECAST>
<DCC_MapFile>3</DCC_MapFile> <DCC_MapFile>3</DCC_MapFile>
<DCC_Optimize>true</DCC_Optimize> <DCC_Optimize>true</DCC_Optimize>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.435;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys> <VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.492;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<VerInfo_Build>435</VerInfo_Build> <VerInfo_Build>492</VerInfo_Build>
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File> <Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
<DCC_IOChecking>false</DCC_IOChecking> <DCC_IOChecking>false</DCC_IOChecking>
<DCC_IntegerOverflowCheck>true</DCC_IntegerOverflowCheck> <DCC_IntegerOverflowCheck>true</DCC_IntegerOverflowCheck>
@@ -99,13 +99,10 @@
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols> <DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define> <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo> <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_DebugInformation>false</DCC_DebugInformation> <DCC_DebugInformation>0</DCC_DebugInformation>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''"> <PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<DCC_MapFile>3</DCC_MapFile> <DCC_MapFile>3</DCC_MapFile>
<DCC_LocalDebugSymbols>true</DCC_LocalDebugSymbols>
<DCC_Define>madExcept;LeakChecking;$(DCC_Define)</DCC_Define>
<DCC_DebugInformation>true</DCC_DebugInformation>
<VerInfo_Locale>1033</VerInfo_Locale> <VerInfo_Locale>1033</VerInfo_Locale>
<DCC_IOChecking>false</DCC_IOChecking> <DCC_IOChecking>false</DCC_IOChecking>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo> <VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
@@ -126,6 +123,7 @@
<DCCReference Include="units\uDrawTIM.pas"/> <DCCReference Include="units\uDrawTIM.pas"/>
<DCCReference Include="units\uEventWaitThread.pas"/> <DCCReference Include="units\uEventWaitThread.pas"/>
<DCCReference Include="units\uBrowseForFolder.pas"/> <DCCReference Include="units\uBrowseForFolder.pas"/>
<DCCReference Include="units\uScanResult.pas"/>
<BuildConfiguration Include="Release"> <BuildConfiguration Include="Release">
<Key>Cfg_2</Key> <Key>Cfg_2</Key>
<CfgParent>Base</CfgParent> <CfgParent>Base</CfgParent>
@@ -174,10 +172,8 @@
<Source Name="MainSource">tim2view.dpr</Source> <Source Name="MainSource">tim2view.dpr</Source>
</Source> </Source>
<Excluded_Packages> <Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\bcboffice2k170.bpl">Embarcadero C++Builder Office 2000 Servers Package</Excluded_Packages> <Excluded_Packages Name="$(BDSBIN)\dcloffice2k180.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\bcbofficexp170.bpl">Embarcadero C++Builder Office XP Servers Package</Excluded_Packages> <Excluded_Packages Name="$(BDSBIN)\dclofficexp180.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k170.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp170.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages> </Excluded_Packages>
</Delphi.Personality> </Delphi.Personality>
<Deployment/> <Deployment/>

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<BorlandProject>
<Transactions>
<Transaction>1899.12.30 00:00:00.000.267,D:\Tim2View\units\uTIMClass.pas=</Transaction>
<Transaction>2014.02.18 01:41:36.622,=D:\TimView2\units\EventWaitThread.pas</Transaction>
<Transaction>2014.02.18 02:21:20.250,D:\TimView2\units\BrowseForFolderU.pas=</Transaction>
<Transaction>2014.02.18 02:21:57.121,=D:\TimView2\units\uEventWaitThread.pas</Transaction>
<Transaction>2014.02.18 02:22:03.673,=D:\TimView2\units\uBrowseForFolder.pas</Transaction>
</Transactions>
</BorlandProject>

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -1,219 +0,0 @@
{ unit sdDebug
universal method for debugging
Exceptions often are a hindrance, so instead use these classes
to give important info to the application or user with these
three basic classes
Besides debug methods, this unit also defines a few compatibility types:
The include file simdesign.inc defines $D5UP and after the
uses-clause these types for D5 are defined. This way, many simdesign
projects are compatible with Delphi 5.
fpc: if lazarus + freepascal is defined, Utf8String just reverts to "string".
Author: Nils Haeck M.Sc.
Original Date: 08nov2010
copyright (c) SimDesign BV (www.simdesign.nl)
}
unit sdDebug;
{$i simdesign.inc}
interface
uses
Classes;
{$ifdef D5UP}
// D5 compatibility types
const
MinsPerHour = 60;
MinsPerDay = MinsPerHour * 24;
soCurrent = soFromCurrent;
soBeginning = soFromBeginning;
soEnd = soFromEnd;
type
Utf8String = AnsiString;
TSeekOrigin = word;
PIntegerArray = ^TIntegerArray;
TIntegerArray = array of Integer;
PByte = ^Byte;
PInteger = ^Integer;
PSingle = ^Single;
PDouble = ^Double;
// TFormatSettings stub
TFormatSettings = record
end;
PWord = ^Word;
function StrToFloatDef(S: AnsiString; Default: Double; AFormatSettings: TFormatSettings): Double;
function StrToBool(S: AnsiString): Boolean;
function StrToBoolDef(S: AnsiString; Default: Boolean): Boolean;
{$endif}
// lazarus compatibility
{$ifdef fpc}
type
Utf8String = string;
{$endif fpc}
// Delphi unicode compatibility
{$ifndef UNICODE}
type
UnicodeString = WideString;
RawByteString = AnsiString;
{$endif UNICODE}
type
TsdWarnStyle = (wsInfo, wsHint, wsWarn, wsFail);
const
cWarnStyleNames: array[TsdWarnStyle] of Utf8String = ('info', 'hint', 'warn', 'fail');
type
// event with debug data
TsdDebugEvent = procedure(Sender: TObject; WarnStyle: TsdWarnStyle; const AMessage: Utf8String) of object;
// simple update event
TsdUpdateEvent = procedure(Sender: TObject) of object;
TDebugComponent = class(TComponent)
protected
FOnDebugOut: TsdDebugEvent;
public
procedure DoDebugOut(Sender: TObject; WarnStyle: TsdWarnStyle; const AMessage: Utf8String); virtual;
// Connect to OnDebugOut to get debug information in the client application
property OnDebugOut: TsdDebugEvent read FOnDebugOut write FOnDebugOut;
end;
TDebugObject = class(TObject)
protected
FOnDebugOut: TsdDebugEvent;
procedure DoDebugOut(Sender: TObject; WarnStyle: TsdWarnStyle; const AMessage: Utf8String); virtual;
public
property OnDebugOut: TsdDebugEvent read FOnDebugOut write FOnDebugOut;
end;
TDebugPersistent = class(TPersistent)
protected
FOwner: TDebugComponent;
procedure DoDebugOut(Sender: TObject; WarnStyle: TsdWarnStyle; const AMessage: Utf8String); virtual;
public
constructor CreateDebug(AOwner: TDebugComponent); virtual;
end;
{ Functions }
function sdDebugMessageToString(Sender: TObject; WarnStyle: TsdWarnStyle; const AMessage: Utf8String): Utf8String;
function sdClassName(AObject: TObject): Utf8String;
implementation
{$ifdef D5UP}
// D5 compatibility types
uses
SysUtils;
function StrToFloatDef(S: AnsiString; Default: Double; AFormatSettings: TFormatSettings): Double;
begin
try
Result:= StrToFloat(S);
except
Result:= Default;
end;
end;
// Only basic support
function StrToBool(S: AnsiString): Boolean;
begin
S := LowerCase(S);
if (S = 'no') or (S = '0') or (S = 'false') then
Result := False
else
if (S = 'yes') or (S = '1') or (S = 'true') then
Result:= True
else
raise EConvertError.Create('');
end;
function StrToBoolDef(S: AnsiString; Default: Boolean): Boolean;
begin
try
Result := StrToBool(S);
except
Result := Default;
end;
end;
{$endif}
{ TDebugComponent }
procedure TDebugComponent.DoDebugOut(Sender: TObject; WarnStyle: TsdWarnStyle; const AMessage: Utf8String);
var
AOwner: TComponent;
begin
AOwner := Self;
while AOwner is TDebugComponent do
begin
if assigned(TDebugComponent(AOwner).FOnDebugOut) then
begin
TDebugComponent(AOwner).FOnDebugOut(Sender, WarnStyle, AMessage);
exit;
end;
AOwner := AOwner.Owner;
end;
end;
{ TDebugObject }
procedure TDebugObject.DoDebugOut(Sender: TObject; WarnStyle: TsdWarnStyle; const AMessage: Utf8String);
begin
if assigned(FOnDebugOut) then
FOnDebugOut(Sender, WarnStyle, AMessage);
end;
{ TDebugPersistent }
constructor TDebugPersistent.CreateDebug(AOwner: TDebugComponent);
begin
inherited Create;
FOwner := AOwner;
end;
procedure TDebugPersistent.DoDebugOut(Sender: TObject; WarnStyle: TsdWarnStyle; const AMessage: Utf8String);
begin
if FOwner is TDebugComponent then
TDebugComponent(FOwner).DoDebugOut(Sender, WarnStyle, AMessage);
end;
{ Functions }
function sdDebugMessageToString(Sender: TObject; WarnStyle: TsdWarnStyle; const AMessage: Utf8String): Utf8String;
var
SenderString: Utf8String;
begin
if assigned(Sender) then
SenderString := Utf8String(Sender.ClassName)
else
SenderString := '';
Result := '[' + cWarnStyleNames[WarnStyle] + '] ' + SenderString + ': ' + AMessage;
end;
function sdClassName(AObject: TObject): Utf8String;
begin
Result := 'nil';
if assigned(AObject) then
Result := Utf8String(AObject.ClassName);
end;
end.

View File

@@ -1,309 +0,0 @@
{ sdStreams.pas
- TsdFastMemStream with improved capacity setting
- TsdStringStream
- TsdBufferWriter
Author: Nils Haeck M.Sc.
copyright (c) 2002 - 2011 SimDesign BV (www.simdesign.nl)
}
unit sdStreams;
{$ifdef lcl}{$MODE Delphi}{$endif}
{$define simdesign.inc}
interface
uses
Classes, SysUtils, sdDebug;
type
// TsdFastMemStream deals differently with capacity compared to a normal
// TMemoryStream; it increases the capacity with the natural growing function
// (fibonacci) each time, and has an initial capacity of $1000. The initial
// capacity is configurable with the create parameter.
TsdFastMemStream = class(TStream)
private
FMemory: Pointer;
FPosition: longint;
FFib1: longint;
FCapacity: longint;
FSize: longint;
protected
procedure SetCapacity(Value: longint);
procedure SetSize(NewSize: Longint); override;
public
constructor Create(InitialCapacity: longint = $1000);
destructor Destroy; override;
procedure Clear;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
function Seek(Offset: Longint; Origin: Word): Longint; override;
procedure LoadFromFile(AFilename: string);
procedure LoadFromStream(Stream: TStream);
procedure SaveToFile(AFilename: string);
procedure SaveToStream(Stream: TStream);
property Memory: Pointer read FMemory;
property Size: longint read FSize write SetSize;
end;
// Delphi's implementation of TStringStream is severely flawed, it does a SetLength
// on each write, which slows down everything to a crawl. This implementation over-
// comes this issue.
TsdStringStream = class(TsdFastMemStream)
public
constructor Create(const S: Utf8String);
function DataString: Utf8String;
end;
// TsdBufferWriter is a buffered stream that takes another stream (ASource)
// and writes only buffer-wise to it, and writes to the stream are first
// done to the buffer. This stream type can only support writing.
TsdBufferWriter = class(TsdFastMemStream)
private
FSource: TStream;
FChunkSize: integer;
FRawBuffer: array of byte;
FRawPosition: Integer;
protected
procedure WriteChunk(Count: integer);
public
// Create the buffered writer stream by passing the destination stream in ASource,
// this destination stream must already be initialized.
constructor Create(ASource: TStream; AChunkSize: integer);
destructor Destroy; override;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
end;
implementation
{ TsdFastMemStream }
procedure TsdFastMemStream.Clear;
begin
SetCapacity(0);
FSize := 0;
FPosition := 0;
end;
constructor TsdFastMemStream.Create(InitialCapacity: Integer);
begin
inherited Create;
FFib1 := InitialCapacity div 2;
FCapacity := InitialCapacity;
if FFib1 < 4 then
FFib1 := 4;
if FCapacity < 4 then
FCapacity := 4;
ReallocMem(FMemory, FCapacity);
end;
destructor TsdFastMemStream.Destroy;
begin
ReallocMem(FMemory, 0);
inherited;
end;
procedure TsdFastMemStream.LoadFromFile(AFilename: string);
var
Stream: TStream;
begin
Stream := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite);
try
LoadFromStream(Stream);
finally
Stream.Free;
end;
end;
procedure TsdFastMemStream.LoadFromStream(Stream: TStream);
var
Count: Longint;
begin
Stream.Position := 0;
Count := Stream.Size;
SetSize(Count);
if Count <> 0 then Stream.ReadBuffer(FMemory^, Count);
end;
function TsdFastMemStream.Read(var Buffer; Count: Integer): Longint;
begin
if (FPosition >= 0) and (Count >= 0) then
begin
Result := FSize - FPosition;
if Result > 0 then
begin
if Result > Count then
Result := Count;
Move(Pointer(Longint(FMemory) + FPosition)^, Buffer, Result);
Inc(FPosition, Result);
Exit;
end;
end;
Result := 0;
end;
procedure TsdFastMemStream.SaveToFile(AFilename: string);
var
Stream: TStream;
begin
Stream := TFileStream.Create(AFileName, fmCreate);
try
SaveToStream(Stream);
finally
Stream.Free;
end;
end;
procedure TsdFastMemStream.SaveToStream(Stream: TStream);
begin
if FSize <> 0 then Stream.WriteBuffer(FMemory^, FSize);
end;
function TsdFastMemStream.Seek(Offset: Integer; Origin: Word): Longint;
begin
case Origin of
soFromBeginning: FPosition := Offset;
soFromCurrent: Inc(FPosition, Offset);
soFromEnd: FPosition := FSize + Offset;
end;
Result := FPosition;
end;
procedure TsdFastMemStream.SetCapacity(Value: longint);
// Fibonacci 0,1,1,2,3,5,8,... FCapacity is Fib2.
// Fibonacci is a natural growing function where
// 0 + 1 = 1; 1 + 1 = 2; 1 + 2 = 3; 2 + 3 = 5; etc
var
Fib3: longint;
begin
while FCapacity < Value do
begin
Fib3 := FFib1 + FCapacity;
FFib1 := FCapacity;
FCapacity := Fib3;
end;
ReallocMem(FMemory, FCapacity);
end;
procedure TsdFastMemStream.SetSize(NewSize: longint);
var
OldPosition: Longint;
begin
OldPosition := FPosition;
SetCapacity(NewSize);
FSize := NewSize;
if OldPosition > NewSize then
Seek(0, soFromEnd);
end;
function TsdFastMemStream.Write(const Buffer; Count: Integer): Longint;
var
NewPos: Longint;
begin
if (FPosition >= 0) and (Count >= 0) then
begin
NewPos := FPosition + Count;
if NewPos > 0 then
begin
if NewPos > FSize then
begin
if NewPos > FCapacity then
SetCapacity(NewPos);
FSize := NewPos;
end;
System.Move(Buffer, Pointer(Longint(FMemory) + FPosition)^, Count);
FPosition := NewPos;
Result := Count;
Exit;
end;
end;
Result := 0;
end;
{ TsdStringStream }
constructor TsdStringStream.Create(const S: Utf8String);
begin
inherited Create;
SetSize(length(S));
if Size > 0 then
begin
Write(S[1], Size);
Position := 0;
end;
end;
function TsdStringStream.DataString: Utf8String;
begin
SetLength(Result, Size);
if Size > 0 then
begin
Position := 0;
Read(Result[1], length(Result));
end;
end;
{ TsdBufferWriter }
constructor TsdBufferWriter.Create(ASource: TStream; AChunkSize: integer);
begin
inherited Create;
FSource := ASource;
FChunkSize := AChunkSize;
SetLength(FRawBuffer, FChunkSize);
end;
destructor TsdBufferWriter.Destroy;
begin
// write the last chunk, if any
WriteChunk(FRawPosition);
// free the rawbuffer
SetLength(FRawBuffer, 0);
inherited;
end;
function TsdBufferWriter.Read(var Buffer; Count: Integer): Longint;
begin
// not implemented
raise Exception.Create('not implemented');
end;
function TsdBufferWriter.Write(const Buffer; Count: Integer): Longint;
var
Idx, Siz: integer;
begin
// index in the source buffer
Idx := 0;
// remaining size
Siz := Count;
// surplus
while FRawPosition + Siz >= FChunkSize do
begin
Move(TByteArray(Buffer)[Idx], FRawBuffer[FRawPosition], FChunkSize - FRawPosition);
WriteChunk(FChunkSize);
dec(Siz, FChunkSize - FRawPosition);
inc(Idx, FChunkSize - FRawPosition);
FRawPosition := 0;
end;
// copy the raw buffer
Move(TByteArray(Buffer)[Idx], FRawBuffer[FRawPosition], Siz);
inc(FRawPosition, Siz);
Result := Count;
end;
procedure TsdBufferWriter.WriteChunk(Count: integer);
begin
if Count > 0 then
begin
FSource.WriteBuffer(FRawBuffer[0], Count);
end;
end;
end.

View File

@@ -1,765 +0,0 @@
{ unit sdStringTable
An optimized table of *unique* strings, using two separate sorted indices:
- by (string) ID
- by sdCompareRefString method
The sdCompareRefString method does not use common alphabetical compare, but
rather a comparison from first character, then last character, then 2nd,
then before-last, etc. until all characters are compared, or a mismatch is
found.
Since many (programmer) strings have numbers at the end of the string,
(e.g. "MyNewNode1", "MyNewNode2", etc), the comparison terminates earlier than
with a common alphabetical compare.
sdStringTable is used by NativeXml but can also be used independently in
your projects.
Author: Nils Haeck M.Sc. (n.haeck@simdesign.nl)
Original Date: 28 May 2007
Modified:
05jan2011: enhancement, no longer uses stringrec
17jun2011: changed TStringTable ancestor from TDebugPersistent to TDebugComponent
24jun2011: "find" fix
18jul2011: renamed TsdStringTable to TsdSymbolTable and added TsdSymbolStyle
It is NOT allowed under ANY circumstances to publish or copy this code
without accepting the license conditions in accompanying LICENSE.txt
first!
This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
ANY KIND, either express or implied.
Please visit http://www.simdesign.nl/xml.html for more information.
Copyright (c) 2007 - 2011 Simdesign BV
}
unit sdStringTable;
{$ifdef lcl}{$MODE Delphi}{$endif}
interface
uses
Classes, SysUtils, Contnrs, sdDebug;
// symbol styles (cardinal)
// Default symbol style is ssUnknown, but highlevel code can
// distinguish between symbol styles. TsdSymbolTable just stores
// the symbol as counted Utf8String.
const
ssUnknown = 0; // data not determined yet
ssString = 1; // data is a string
ssBase64Binary = 2; // data is binary and will be handled by Base64 funcs
ssHexBinary = 3; // data is binary and will be handled by BinHex funcs
ssBoolean = 4; // boolean (stored in a byte, just 0 and 1 of cardinal)
ssCardinal = 5; // cardinal (1..N bytes, see TBinaryXml.ReadCardinal)
ssInteger = 6; // integer (1..N bytes)
ssDecimal = 7; // decimal value (see TNativeXml.EncodeDecimalSymbol)
ssDate = 8; // date (see TNativeXml.EncodeDateSymbol)
ssTime = 9; // time (see TNativeXml.EncodeTimeSymbol)
ssDateTime = 10; // datetime (see TNativeXml.EncodeDateTimeSymbol)
// These were the default symbol styles as used by NativeXml. Other units may
// define more symbols after the last default symbol
type
// A symbol table, holding a collection of unique strings, sorted in 2 ways
// for fast access. Strings can be added with AddString or AddStringRec.
// When a string is added or updated, an ID is returned which the application
// can use to retrieve the string, using GetString.
TsdSymbolTable = class(TDebugComponent)
private
FByID: TObjectList;
FBySymbol: TObjectList;
FPluralSymbolCount: integer;
function GetSymbolCount: integer;
protected
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
// Clear the string table
procedure Clear;
// Add a potentially new string S to the table, the function
// returns its string ID.
function AddString(const S: Utf8String): integer;
// retrieve the string based on its string ID. The string ID is only unique
// within this string table, so do not use IDs from other tables.
function GetString(ID: integer): Utf8String;
// total number of symbols in the table
property SymbolCount: integer read GetSymbolCount;
// plural symbols in the table. plural symbols are symbols that have
// a frequency > 1. ie the symbol is found more than once in the app.
// PluralCount is only valid after method SortByFrequency.
property PluralSymbolCount: integer read FPluralSymbolCount;
procedure LoadFromFile(const AFileName: string);
procedure LoadFromStream(S: TStream);
function LoadSymbol(S: TStream): Cardinal;
procedure SaveToFile(const AFileName: string);
procedure SaveToStream(S: TStream; ACount: integer);
procedure SaveSymbol(S: TStream; ASymbolID: Cardinal);
procedure ClearFrequency;
procedure IncrementFrequency(ID: integer);
procedure SortByFrequency(var ANewIDs: array of Cardinal);
end;
{utility functions}
// compare two bytes
function sdCompareByte(Byte1, Byte2: byte): integer;
// compare two integers
function sdCompareInteger(Int1, Int2: integer): integer;
// unicode UTF8 <> UTF16LE coversion functions
function sdUtf16ToUtf8Mem(Src: Pword; Dst: Pbyte; Count: integer): integer;
function sdUtf8ToUtf16Mem(var Src: Pbyte; Dst: Pword; Count: integer): integer;
// stream methods
function sdStreamReadCardinal(S: TStream): Cardinal;
function sdStreamReadString(S: TStream; ACharCount: Cardinal): Utf8String;
procedure sdStreamWriteCardinal(S: TStream; ACardinal: Cardinal);
procedure sdStreamWriteString(S: TStream; const AString: Utf8String);
implementation
type
// A symbol item used in symbol lists (do not use directly)
TsdSymbol = class
private
FID: integer;
FFreq: Cardinal;
FSymbolStyle: Cardinal;
FFirst: Pbyte;
FCharCount: integer;
public
destructor Destroy; override;
function AsString: Utf8String;
property SymbolStyle: Cardinal read FSymbolStyle;
property CharCount: integer read FCharCount;
end;
// A list of symbols (do not use directly)
TsdSymbolList = class(TObjectList)
private
function GetItems(Index: integer): TsdSymbol;
protected
// Assumes list is sorted by refstring
function Find(ASymbol: TsdSymbol; var Index: integer): boolean;
public
property Items[Index: integer]: TsdSymbol read GetItems; default;
end;
// compare two symbols. This is NOT an alphabetic compare. symbols are first
// compared by length, then by first byte, then last byte then second, then
// N-1, until all bytes are compared.
function sdCompareSymbol(Symbol1, Symbol2: TsdSymbol): integer;
var
CharCount: integer;
First1, First2, Last1, Last2: Pbyte;
IsEqual: boolean;
begin
// Compare string length first
Result := sdCompareInteger(Symbol1.CharCount, Symbol2.CharCount);
if Result <> 0 then
exit;
// Compare FFirst
Result := sdCompareByte(Symbol1.FFirst^, Symbol2.FFirst^);
if Result <> 0 then
exit;
// CharCount of RS1 (and RS2, since they are equal)
CharCount := Symbol1.CharCount;
// Setup First & Last pointers
First1 := Symbol1.FFirst;
First2 := Symbol2.FFirst;
// compare memory (boolean op). CompareMem might have optimized code depending
// on memory manager (ASM, MMX, SSE etc) to binary compare the block.
// Since sdCompareRefString may be used to compare relatively large blocks of
// text, which are often exact copies, using CompareMem before special comparison
// is warrented.
IsEqual := CompareMem(First1, First2, CharCount);
if IsEqual then
begin
Result := 0;
exit;
end;
// finally the special conparison: Compare each time last ptrs then first ptrs,
// until they meet in the middle
Last1 := First1;
inc(Last1, CharCount);
Last2 := First2;
inc(Last2, CharCount);
repeat
dec(Last1);
dec(Last2);
if First1 = Last1 then
exit;
Result := sdCompareByte(Last1^, Last2^);
if Result <> 0 then
exit;
inc(First1);
inc(First2);
if First1 = Last1 then
exit;
Result := sdCompareByte(First1^, First2^);
if Result <> 0 then
exit;
until False;
end;
{ TsdSymbol }
function TsdSymbol.AsString: Utf8String;
begin
SetString(Result, PAnsiChar(FFirst), FCharCount);
end;
destructor TsdSymbol.Destroy;
begin
FreeMem(FFirst);
inherited;
end;
{ TsdSymbolList }
function TsdSymbolList.GetItems(Index: integer): TsdSymbol;
begin
Result := Get(Index);
end;
function TsdSymbolList.Find(ASymbol: TsdSymbol; var Index: integer): boolean;
var
AMin, AMax: integer;
begin
Result := False;
// Find position - binary method
AMin := 0;
AMax := Count;
while AMin < AMax do
begin
Index := (AMin + AMax) div 2;
case sdCompareSymbol(Items[Index], ASymbol) of
-1: AMin := Index + 1;
0: begin
Result := True;
exit;
end;
1: AMax := Index;
end;
end;
Index := AMin;
end;
{ TsdSymbolTable }
function TsdSymbolTable.AddString(const S: Utf8String): integer;
var
Found: boolean;
L, BySymbolIndex: integer;
ASymbol, Item: TsdSymbol;
begin
Result := 0;
L := length(S);
// zero-length string
if L = 0 then
exit;
ASymbol := TsdSymbol.Create;
try
ASymbol.FFirst := PByte(@S[1]);
ASymbol.FCharCount := L;
// Try to find the new string
Found := TsdSymbolList(FBySymbol).Find(ASymbol, BySymbolIndex);
if Found then
begin
// yes it is found
Item := TsdSymbol(FBySymbol[BySymbolIndex]);
Result := Item.FID;
exit;
end;
// Not found.. must make new item
Item := TsdSymbol.Create;
Item.FCharCount := ASymbol.FCharCount;
// reallocate memory and copy the string data
ReallocMem(Item.FFirst, Item.FCharCount);
Move(S[1], Item.FFirst^, Item.FCharCount);
// add to the ByID objectlist
FByID.Add(Item);
Item.FID := FByID.Count;
Result := Item.FID;
// insert into the ByRS list
FBySymbol.Insert(BySymbolIndex, Item);
finally
// this ensures we do not deallocate the memory that may be in use elsewhere
ASymbol.FFirst := nil;
ASymbol.Free;
end;
end;
procedure TsdSymbolTable.Clear;
begin
FByID.Clear;
FBySymbol.Clear;
end;
procedure TsdSymbolTable.ClearFrequency;
var
i: integer;
begin
for i := 0 to FByID.Count - 1 do
TsdSymbol(FByID[i]).FFreq := 0;
end;
constructor TsdSymbolTable.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FByID := TObjectList.Create(True);
FBySymbol := TsdSymbolList.Create(False);
end;
destructor TsdSymbolTable.Destroy;
begin
FreeAndNil(FBySymbol);
FreeAndNil(FByID);
inherited;
end;
function TsdSymbolTable.GetSymbolCount: integer;
begin
Result := FByID.Count;
end;
function TsdSymbolTable.GetString(ID: integer): Utf8String;
begin
// Find the ID
// zero string
if ID <= 0 then
begin
Result := '';
exit;
end;
// out of bounds?
if ID > FByID.Count then
begin
// output warning
DoDebugOut(Self, wsWarn, 'string ID not found');
Result := '';
end;
Result := TsdSymbol(FByID[ID - 1]).AsString;
end;
procedure TsdSymbolTable.IncrementFrequency(ID: integer);
var
RS: TsdSymbol;
begin
RS := TsdSymbol(FByID[ID - 1]);
inc(RS.FFreq);
end;
procedure TsdSymbolTable.LoadFromFile(const AFileName: string);
var
S: TMemoryStream;
begin
S := TMemoryStream.Create;
try
S.LoadFromFile(AFileName);
LoadFromStream(S);
finally
S.Free;
end;
end;
procedure TsdSymbolTable.LoadFromStream(S: TStream);
var
i: integer;
TableCount: Cardinal;
begin
Clear;
// DoDebugOut(Self, wsInfo, format('stream position: %d', [S.Position]));
// table count
TableCount := sdStreamReadCardinal(S);
if TableCount = 0 then
exit;
for i := 0 to TableCount - 1 do
begin
LoadSymbol(S);
end;
end;
function TsdSymbolTable.LoadSymbol(S: TStream): Cardinal;
var
Symbol: TsdSymbol;
BySymbolIndex: integer;
Found: boolean;
begin
Symbol := TsdSymbol.Create;
// For now, we just use ssString uniquely as symbol style,.
// In updates, different symbol styles can be added.
Symbol.FSymbolStyle := sdStreamReadCardinal(S);
Symbol.FCharCount := sdStreamReadCardinal(S);
if Symbol.FCharCount > 0 then
begin
// reallocate memory and copy the string data
ReallocMem(Symbol.FFirst, Symbol.FCharCount);
S.Read(Symbol.FFirst^, Symbol.FCharCount);
end;
// add to the ByID objectlist
FByID.Add(Symbol);
Symbol.FID := FByID.Count;
Result := Symbol.FID;
// find the symbol
Found := TsdSymbolList(FBySymbol).Find(Symbol, BySymbolIndex);
if Found then
begin
DoDebugOut(Self, wsFail, 'duplicate symbol!');
exit;
end;
// insert into the ByRS list
FBySymbol.Insert(BySymbolIndex, Symbol);
end;
procedure TsdSymbolTable.SaveToFile(const AFileName: string);
var
S: TMemoryStream;
begin
S := TMemoryStream.Create;
try
SaveToStream(S, SymbolCount);
S.SaveToFile(AFileName);
finally
S.Free;
end;
end;
procedure TsdSymbolTable.SaveToStream(S: TStream; ACount: integer);
var
i: integer;
begin
// write (part of the) symbol table
sdStreamWriteCardinal(S, ACount);
for i := 0 to ACount - 1 do
begin
SaveSymbol(S, i + 1);
end;
end;
procedure TsdSymbolTable.SaveSymbol(S: TStream; ASymbolID: Cardinal);
var
RS: TsdSymbol;
StringVal: Utf8String;
CharCount: Cardinal;
begin
if ASymbolID <= 0 then
DoDebugOut(Self, wsFail, 'symbol ID <= 0');
RS := TsdSymbol(FByID[ASymbolID - 1]);
// For now, we just use ssString uniquely as symbol style.
// In updates, different symbol styles can be added.
sdStreamWriteCardinal(S, RS.SymbolStyle);
StringVal := RS.AsString;
CharCount := length(StringVal);
sdStreamWriteCardinal(S, CharCount);
sdStreamWriteString(S, StringVal);
end;
procedure TsdSymbolTable.SortByFrequency(var ANewIDs: array of Cardinal);
// local
function CompareFreq(Pos1, Pos2: integer): integer;
var
RS1, RS2: TsdSymbol;
begin
RS1 := TsdSymbol(FByID[Pos1]);
RS2 := TsdSymbol(FByID[Pos2]);
if RS1.FFreq > RS2.FFreq then
Result := -1
else
if RS1.FFreq < RS2.FFreq then
Result := 1
else
Result := 0;
end;
// local
procedure QuickSort(iLo, iHi: Integer);
var
Lo, Hi, Mid: longint;
begin
Lo := iLo;
Hi := iHi;
Mid:= (Lo + Hi) div 2;
repeat
while CompareFreq(Lo, Mid) < 0 do
Inc(Lo);
while CompareFreq(Hi, Mid) > 0 do
Dec(Hi);
if Lo <= Hi then
begin
// Swap pointers;
FByID.Exchange(Lo, Hi);
if Mid = Lo then
Mid := Hi
else
if Mid = Hi then
Mid := Lo;
Inc(Lo);
Dec(Hi);
end;
until Lo > Hi;
if Hi > iLo then
QuickSort(iLo, Hi);
if Lo < iHi then
QuickSort(Lo, iHi);
end;
// main
var
i: integer;
begin
// sort by frequency
QuickSort(0, FByID.Count - 1);
// plural count
FPluralSymbolCount := 0;
i := 0;
while i < FByID.Count do
begin
if TsdSymbol(FByID[i]).FFreq >= 2 then
inc(FPluralSymbolCount)
else
break;
inc(i);
end;
// tell app about new ID
for i := 0 to FByID.Count - 1 do
begin
ANewIDs[TsdSymbol(FByID[i]).FID] := i + 1;
end;
// then rename IDs
for i := 0 to FByID.Count - 1 do
begin
TsdSymbol(FByID[i]).FID := i + 1;
end;
end;
{utility functions}
function sdCompareByte(Byte1, Byte2: byte): integer;
begin
if Byte1 < Byte2 then
Result := -1
else
if Byte1 > Byte2 then
Result := 1
else
Result := 0;
end;
function sdCompareInteger(Int1, Int2: integer): integer;
begin
if Int1 < Int2 then
Result := -1
else
if Int1 > Int2 then
Result := 1
else
Result := 0;
end;
function sdUtf16ToUtf8Mem(Src: Pword; Dst: Pbyte; Count: integer): integer;
// Convert an Unicode (UTF16 LE) memory block to UTF8. This routine will process
// Count wide characters (2 bytes size) to Count UTF8 characters (1-3 bytes).
// Therefore, the block at Dst must be at least 1.5 the size of the source block.
// The function returns the number of *bytes* written.
var
W: word;
DStart: Pbyte;
begin
DStart := Dst;
while Count > 0 do
begin
W := Src^;
inc(Src);
if W <= $7F then
begin
Dst^ := byte(W);
inc(Dst);
end else
begin
if W > $7FF then
begin
Dst^ := byte($E0 or (W shr 12));
inc(Dst);
Dst^ := byte($80 or ((W shr 6) and $3F));
inc(Dst);
Dst^ := byte($80 or (W and $3F));
inc(Dst);
end else
begin // $7F < W <= $7FF
Dst^ := byte($C0 or (W shr 6));
inc(Dst);
Dst^ := byte($80 or (W and $3F));
inc(Dst);
end;
end;
dec(Count);
end;
Result := integer(Dst) - integer(DStart);
end;
function sdUtf8ToUtf16Mem(var Src: Pbyte; Dst: Pword; Count: integer): integer;
// Convert an UTF8 memory block to Unicode (UTF16 LE). This routine will process
// Count *bytes* of UTF8 (each character 1-3 bytes) into UTF16 (each char 2 bytes).
// Therefore, the block at Dst must be at least 2 times the size of Count, since
// many UTF8 characters consist of just one byte, and are mapped to 2 bytes. The
// function returns the number of *wide chars* written. Note that the Src block must
// have an exact number of UTF8 characters in it, if Count doesn't match then
// the last character will be converted anyway (going past the block boundary!)
var
W: word;
C: byte;
DStart: Pword;
SClose: Pbyte;
begin
DStart := Dst;
SClose := Src;
inc(SClose, Count);
while integer(Src) < integer(SClose) do
begin
// 1st byte
W := Src^;
inc(Src);
if W and $80 <> 0 then
begin
W := W and $3F;
if W and $20 <> 0 then
begin
// 2nd byte
C := Src^;
inc(Src);
if C and $C0 <> $80 then
// malformed trail byte or out of range char
Continue;
W := (W shl 6) or (C and $3F);
end;
// 2nd or 3rd byte
C := Src^;
inc(Src);
if C and $C0 <> $80 then
// malformed trail byte
Continue;
Dst^ := (W shl 6) or (C and $3F);
inc(Dst);
end else
begin
Dst^ := W;
inc(Dst);
end;
end;
Result := (integer(Dst) - integer(DStart)) div 2;
end;
{ stream methods }
function sdStreamReadCardinal(S: TStream): Cardinal;
var
C: byte;
Bits: integer;
begin
Result := 0;
Bits := 0;
repeat
S.Read(C, 1);
if C > 0 then
begin
inc(Result, (C and $7F) shl Bits);
inc(Bits, 7)
end;
until(C and $80) = 0;
end;
function sdStreamReadString(S: TStream; ACharCount: Cardinal): Utf8String;
begin
SetLength(Result, ACharCount);
if ACharCount = 0 then
exit;
S.Read(Result[1], ACharCount);
end;
procedure sdStreamWriteCardinal(S: TStream; ACardinal: Cardinal);
var
C: byte;
begin
repeat
if ACardinal <= $7F then
begin
C := ACardinal;
S.Write(C, 1);
exit;
end else
C := (ACardinal and $7F) or $80;
S.Write(C, 1);
ACardinal := ACardinal shr 7;
until ACardinal = 0;
end;
procedure sdStreamWriteString(S: TStream; const AString: Utf8String);
var
L: integer;
begin
L := Length(AString);
if L > 0 then
begin
S.Write(AString[1], L);
end;
end;
end.

View File

@@ -1,95 +0,0 @@
{ simdesign.inc
include file for many simdesign projects
default path: \simlib\general
Author: Nils Haeck M.Sc.
Copyright (c) 2007 - 2011 Simdesign B.V.
}
// unicode avoid implicit string cast warning
{$ifdef UNICODE}
{$WARN IMPLICIT_STRING_CAST OFF}
{$endif UNICODE}
// Delphi and FPC versions
// Freepascal
{$ifdef FPC}
{$MODE DELPHI}
{$define D7UP}
{$endif FPC}
// Delphi 5
{$ifdef VER130}
{$define D5UP}
{$endif}
//Delphi 6
{$ifdef VER140}
{$define D5UP}
{$endif}
//Delphi 7
{$ifdef VER150}
{$define D7UP}
{$endif}
//Delphi 8
{$ifdef VER160}
{$define D7UP}
{$endif}
// Delphi 2005 / 9
{$ifdef VER170}
{$define D7UP}
{$endif}
// Delphi 2006 / 10
{$ifdef VER180}
{$define D7UP}
// D10 publishes OnMouseEnter / OnMouseLeave
{$define D10UP}
{$endif}
// Delphi 2007 Rad studio / 11?
{$ifdef VER185}
{$define D7UP}
{$define D10UP}
{$endif}
// Delphi 2007 - NET / 11?
{$ifdef VER190}
{$define D7UP}
{$define D10UP}
{$endif}
// Delphi 2009 / 12
// first UNICODE version, so then directive UNICODE is defined, no need for directive D12UP
{$ifdef VER200}
{$define D7UP}
{$define D10UP}
{$endif}
// Delphi 2010 / 14?
{$ifdef VER210}
{$define D7UP}
{$define D10UP}
{$endif}
// Delphi XE / 15
{$ifdef VER220}
{$define D7UP}
{$define D10UP}
{$define D15UP}
{$endif}
// Delphi XE2 / 16
{$ifdef VER230}
{$define D7UP}
{$define D10UP}
{$define D15UP}
{$endif}

View File

@@ -32,10 +32,10 @@ type
PCDSector = ^TCDSector; PCDSector = ^TCDSector;
function GetImageScan(const FileName: string): Boolean; function GetImageScan(const FileName: string): Boolean;
function ReplaceTimInFile(const FileName, TimToInsert: string; InsertTo: DWORD; function ReplaceTimInFile(const FileName, TimToInsert: string; InsertTo: Integer;
ImageScan: Boolean): Boolean; ImageScan: Boolean): Boolean;
procedure ReplaceTimInFileFromMemory(const FileName: string; TIM: PTIM; procedure ReplaceTimInFileFromMemory(const FileName: string; TIM: PTIM;
InsertTo: DWORD; ImageScan: Boolean); InsertTo: Integer; ImageScan: Boolean);
implementation implementation
@@ -87,16 +87,16 @@ begin
end; end;
procedure ReplaceTimInFileFromMemory(const FileName: string; TIM: PTIM; procedure ReplaceTimInFileFromMemory(const FileName: string; TIM: PTIM;
InsertTo: DWORD; ImageScan: Boolean); InsertTo: Integer; ImageScan: Boolean);
type type
TSecAddrAndMode = array [0 .. cSectorAddressSize + cSectorModeSize - 1] of byte; TSecAddrAndMode = array [0 .. cSectorAddressSize + cSectorModeSize - 1] of byte;
var var
sImageStream: TFileStream; sImageStream: TFileStream;
TimOffsetInSector, FirstPartSize, LastPartSize: DWORD; TimOffsetInSector, FirstPartSize, LastPartSize: Integer;
TimSectorNumber, TimStartSectorPos: DWORD; TimSectorNumber, TimStartSectorPos: Integer;
Sector: TCDSector; Sector: TCDSector;
ecc: DWORD; ecc: DWORD;
P, TIM_FULL_SECTORS: DWORD; P, TIM_FULL_SECTORS: Integer;
SecAddrAndMode: TSecAddrAndMode; SecAddrAndMode: TSecAddrAndMode;
begin begin
sImageStream := TFileStream.Create(FileName, fmOpenReadWrite or sImageStream := TFileStream.Create(FileName, fmOpenReadWrite or
@@ -202,11 +202,11 @@ begin
sImageStream.free; sImageStream.free;
end; end;
function ReplaceTimInFile(const FileName, TimToInsert: string; InsertTo: DWORD; function ReplaceTimInFile(const FileName, TimToInsert: string; InsertTo: Integer;
ImageScan: Boolean): Boolean; ImageScan: Boolean): Boolean;
var var
SIZE, P: DWORD; SIZE, P: Integer;
TIM: PTIM; TIM: PTIM;
begin begin
Result := False; Result := False;

View File

@@ -3,40 +3,25 @@ unit uCommon;
interface interface
uses uses
NativeXML, Windows; Windows;
const const
cProgramName = 'Tim2View by [Lab 313]'; cProgramName = 'Tim2View by [Lab 313]';
cProgramVersion = '2.0'; cProgramVersion = '2.0';
cMaxFileSize = $2EAEED80;
cExtractedTimsDir = 'TIMS'; cExtractedTimsDir = 'TIMS';
cResRootName = 'TVSCANRESULT'; cMaxFileSize = $2EAEED80;
cResInfoNode = 'INFO';
cResAttrFile = 'FILENAME';
cResAttrVersion = 'VERSION';
cResAttrImageFile = 'CDIMAGE';
cResAttrTimsCount = 'TIMSCOUNT';
cResTimsNode = 'TIMS';
cResTimNode = 'TIM';
cResTimAttrPos = 'POSITION';
cResTimAttrSize = 'SIZE';
cResTimAttrWidth = 'WIDTH';
cResTimAttrHeight = 'HEIGHT';
cResTimAttrBitMode = 'BITMODE';
cResTimAttrGood = 'GOODTIM';
cAutoExtractionTimFormat = '%s_%.6d_%.2db' + '.tim'; cAutoExtractionTimFormat = '%s_%.6d_%.2db' + '.tim';
cCLUTGridColsCount = 32; cCLUTGridColsCount = 32;
sStatusBarScanningFile = 'Scanning File...'; sStatusBarScanningFile = 'Scanning File...';
sStatusBarTimsExtracting = 'TIM''s Extracting...'; sStatusBarTimsExtracting = 'TIMs Extracting...';
sStatusBarTimsExtracted = 'Exctracted Successfully!';
sStatusBarParsingResult = 'Parsing Result...'; sStatusBarParsingResult = 'Parsing Result...';
sScanResultGood = 'Scan completed!'; sScanResultGood = 'Scan completed!';
sSelectDirCaption = 'Please, select directory for scan...'; sSelectDirCaption = 'Please, select directory for scan...';
sThisTimHasNoCLUT = 'This TIM has no CLUT'; sThisTimHasNoCLUT = 'This TIM has no CLUT';
type
PNativeXML = ^TNativeXML;
type type
TBytesArray = array [0 .. cMaxFileSize - 1] of byte; TBytesArray = array [0 .. cMaxFileSize - 1] of byte;
PBytesArray = ^TBytesArray; PBytesArray = ^TBytesArray;
@@ -48,11 +33,12 @@ function CheckFileExists(const FileName: string): boolean;
function ExtractFileNameWOext(const Path: string): string; function ExtractFileNameWOext(const Path: string): string;
procedure Text2Clipboard(const S: string); procedure Text2Clipboard(const S: string);
function Min(A, B: Integer): Integer; function Min(A, B: Integer): Integer;
function Max(A, B: Integer): Integer;
implementation implementation
uses uses
uCDIMAGE, System.SysUtils, System.Classes, Clipbrd; System.SysUtils, Clipbrd;
function Min(A, B: Integer): Integer; function Min(A, B: Integer): Integer;
begin begin
@@ -62,6 +48,14 @@ begin
Result := B; Result := B;
end; end;
function Max(A, B: Integer): Integer;
begin
if A >= B then
Result := A
else
Result := B;
end;
procedure Text2Clipboard(const S: string); procedure Text2Clipboard(const S: string);
begin begin
Clipboard.AsText := S; Clipboard.AsText := S;

View File

@@ -53,7 +53,7 @@ function PrepareIMAGE(TIM: PTIM): PIMAGE_INDEXES;
var var
I, OFFSET: Integer; I, OFFSET: Integer;
RW: Word; RW: Word;
P24: DWORD; P24: Integer;
begin begin
New(Result); New(Result);
OFFSET := cTIMHeadSize + GetTIMCLUTSize(TIM) + cIMAGEHeadSize; OFFSET := cTIMHeadSize + GetTIMCLUTSize(TIM) + cIMAGEHeadSize;
@@ -104,7 +104,7 @@ var
X, Y, INDEX, IMAGE_DATA_POS: Integer; X, Y, INDEX, IMAGE_DATA_POS: Integer;
R, G, B, STP, ALPHA: Byte; R, G, B, STP, ALPHA: Byte;
COLOR: TCLUT_COLOR; COLOR: TCLUT_COLOR;
CL: DWORD; CL: Integer;
Transparent, SemiTransparent: boolean; Transparent, SemiTransparent: boolean;
begin begin
RW := GetTimRealWidth(TIM); RW := GetTimRealWidth(TIM);

View File

@@ -1,4 +1,4 @@
object frmMainT2V: TfrmMainT2V object frmMain: TfrmMain
Left = 0 Left = 0
Top = 0 Top = 0
Width = 754 Width = 754
@@ -44,6 +44,7 @@ object frmMainT2V: TfrmMainT2V
Width = 504 Width = 504
Height = 28 Height = 28
Align = alRight Align = alRight
Anchors = [akLeft, akTop, akRight, akBottom]
Smooth = True Smooth = True
TabOrder = 1 TabOrder = 1
end end
@@ -69,6 +70,7 @@ object frmMainT2V: TfrmMainT2V
AutoCloseUp = True AutoCloseUp = True
Style = csDropDownList Style = csDropDownList
DropDownCount = 30 DropDownCount = 30
Enabled = False
TabOrder = 0 TabOrder = 0
OnChange = cbbFilesChange OnChange = cbbFilesChange
end end
@@ -127,7 +129,7 @@ object frmMainT2V: TfrmMainT2V
ViewStyle = vsReport ViewStyle = vsReport
OnClick = lvListClick OnClick = lvListClick
OnData = lvListData OnData = lvListData
OnKeyDown = lvListKeyDown OnSelectItem = lvListSelectItem
end end
end end
object pnlImage: TPanel object pnlImage: TPanel
@@ -149,21 +151,23 @@ object frmMainT2V: TfrmMainT2V
ResizeStyle = rsUpdate ResizeStyle = rsUpdate
ExplicitTop = 274 ExplicitTop = 274
end end
object imgTIM: TImage object pbTim: TImage
Left = 1 AlignWithMargins = True
Top = 4 Left = 4
Width = 500 Top = 7
Height = 296 Width = 494
Height = 290
Align = alClient Align = alClient
Center = True Center = True
IncrementalDisplay = True IncrementalDisplay = True
Proportional = True Proportional = True
ExplicitLeft = 152 Transparent = True
ExplicitTop = 112 ExplicitLeft = 168
ExplicitTop = 80
ExplicitWidth = 105 ExplicitWidth = 105
ExplicitHeight = 105 ExplicitHeight = 105
end end
object grdCurrCLUT: TDrawGrid object grdCurrClut: TDrawGrid
Left = 1 Left = 1
Top = 330 Top = 330
Width = 500 Width = 500
@@ -181,8 +185,8 @@ object frmMainT2V: TfrmMainT2V
ParentDoubleBuffered = False ParentDoubleBuffered = False
ScrollBars = ssNone ScrollBars = ssNone
TabOrder = 0 TabOrder = 0
OnDblClick = grdCurrCLUTDblClick OnDblClick = grdCurrClutDblClick
OnDrawCell = grdCurrCLUTDrawCell OnDrawCell = grdCurrClutDrawCell
end end
object pnlImageOptions: TPanel object pnlImageOptions: TPanel
Left = 1 Left = 1
@@ -216,7 +220,7 @@ object frmMainT2V: TfrmMainT2V
ItemIndex = 0 ItemIndex = 0
TabOrder = 1 TabOrder = 1
Text = 'Full transparence' Text = 'Full transparence'
OnClick = cbbTransparenceModeClick OnChange = cbbTransparenceModeChange
Items.Strings = ( Items.Strings = (
'Full transparence' 'Full transparence'
'Black Transparence' 'Black Transparence'
@@ -241,14 +245,16 @@ object frmMainT2V: TfrmMainT2V
'8 BPP' '8 BPP'
'16 BPP' '16 BPP'
'24 BPP') '24 BPP')
ExplicitTop = 3
end end
object chkStretch: TCheckBox object chkStretch: TCheckBox
Left = 404 AlignWithMargins = True
Top = 1 Left = 407
Width = 97 Top = 4
Height = 28 Width = 89
Height = 22
Action = actStretch Action = actStretch
Align = alLeft Align = alClient
TabOrder = 3 TabOrder = 3
end end
end end
@@ -306,33 +312,6 @@ object frmMainT2V: TfrmMainT2V
end end
object mnConfig: TMenuItem object mnConfig: TMenuItem
Caption = '&Options' Caption = '&Options'
object mnAutoExtract: TMenuItem
AutoCheck = True
Caption = '&Auto Extraction'
end
object Stretch1: TMenuItem
Action = actStretch
AutoCheck = True
end
object mnViewMode: TMenuItem
Caption = '&View Mode'
object mnSimpleMode: TMenuItem
AutoCheck = True
Caption = '&Simple Mode'
RadioItem = True
OnClick = mnSimpleModeClick
end
object mnAdvancedMode: TMenuItem
AutoCheck = True
Caption = '&Advanced Mode'
Checked = True
RadioItem = True
OnClick = mnAdvancedModeClick
end
end
object N5: TMenuItem
Caption = '-'
end
object mnAssociate: TMenuItem object mnAssociate: TMenuItem
Action = actAssocTims Action = actAssocTims
end end
@@ -427,7 +406,6 @@ object frmMainT2V: TfrmMainT2V
end end
object actAbout: TAction object actAbout: TAction
Caption = 'About...' Caption = 'About...'
ShortCut = 112
OnExecute = actAboutExecute OnExecute = actAboutExecute
end end
object actStretch: TAction object actStretch: TAction
@@ -444,10 +422,22 @@ object frmMainT2V: TfrmMainT2V
Caption = 'Open TIMs with T2V' Caption = 'Open TIMs with T2V'
OnExecute = actAssocTimsExecute OnExecute = actAssocTimsExecute
end end
object actExtractList: TAction
Caption = 'Extract TIMs'
Enabled = False
ShortCut = 112
OnExecute = actExtractListExecute
end
end end
object pmList: TPopupMenu object pmList: TPopupMenu
Left = 640 Left = 640
Top = 502 Top = 502
object ExtractTIMs1: TMenuItem
Action = actExtractList
end
object N6: TMenuItem
Caption = '-'
end
object ExtractTIM1: TMenuItem object ExtractTIM1: TMenuItem
Action = actExtractTim Action = actExtractTim
end end

File diff suppressed because it is too large Load Diff

75
units/uScanResult.pas Normal file
View File

@@ -0,0 +1,75 @@
unit uScanResult;
interface
type
TScanTim = record
Position: Integer;
Size: Integer;
Width: Integer;
Height: Integer;
BitMode: Byte;
Good: Boolean;
end;
type
TScanResult = class(TObject)
private
pScanFile: string;
pIsImage: Boolean;
pCount: Integer;
pTims: array of TScanTim;
procedure fSetCount(Value: Integer);
function fGetTim(Index: Integer): TScanTim;
procedure fSetTim(Index: Integer; Value: TScanTim);
public
constructor Create;
destructor Destroy; override;
property ScanFile: string read pScanFile write pScanFile;
property IsImage: Boolean read pIsImage write pIsImage;
property Count: Integer read pCount write fSetCount;
property ScanTim[index: Integer]: TScanTim read fGetTim write fSetTim;
end;
implementation
{ TScanResult }
constructor TScanResult.Create;
begin
inherited;
pScanFile := '';
pIsImage := False;
pCount := 0;
pTims := nil;
end;
destructor TScanResult.Destroy;
begin
inherited;
end;
function TScanResult.fGetTim(Index: Integer): TScanTim;
begin
Result := pTims[Index];
end;
procedure TScanResult.fSetCount(Value: Integer);
begin
pCount := Value;
SetLength(pTims, Value);
end;
procedure TScanResult.fSetTim(Index: Integer; Value: TScanTim);
begin
pTims[Index] := Value;
end;
end.

View File

@@ -3,35 +3,33 @@ unit uScanThread;
interface interface
uses uses
Classes, Windows, uCommon, uTIM; Classes, Windows, uCommon, uTIM, uScanResult;
type type
PScanThread = ^TScanThread;
TScanThread = class(Classes.TThread) TScanThread = class(Classes.TThread)
private private
{ Private declarations } { Private declarations }
pScanFile: string;
pIsImage: boolean;
pScanResult: TScanResult;
pTims: Integer; pTims: Integer;
pFileToScan: string; pFileSize: Integer;
pImageScan: boolean; pFilePos: Integer;
pResult: PNativeXml;
pFileSize: DWORD;
pFilePos: DWORD;
pStatusText: string; pStatusText: string;
pClearBufferPosition: DWORD; pClearBufferPosition: Integer;
pClearBufferSize: DWORD; pClearBufferSize: Integer;
pSectorBufferSize: DWORD; pSectorBufferSize: Integer;
pSrcFileStream: TFileStream; pSrcFileStream: TFileStream;
pStopScan: boolean; pStopScan: boolean;
procedure SetStatusText; procedure SetStatusText;
procedure StartScan;
procedure UpdateProgressBar; procedure UpdateProgressBar;
procedure AddResult(TIM: PTIM); procedure AddResult(TIM: PTIM);
procedure ClearSectorBuffer(SectorBuffer, ClearBuffer: PBytesArray); procedure ClearSectorBuffer(SectorBuffer, ClearBuffer: PBytesArray);
protected protected
procedure Execute; override; procedure Execute; override;
public public
constructor Create(const FileToScan: string; fResult: pointer; constructor Create(const FileToScan: string; ImageScan: boolean);
ImageScan: boolean);
property Terminated; property Terminated;
property StopScan: boolean write pStopScan; property StopScan: boolean write pStopScan;
end; end;
@@ -39,7 +37,7 @@ type
implementation implementation
uses uses
uMain, uCDIMAGE, System.SysUtils, NativeXml; uMain, uCDIMAGE, System.SysUtils;
const const
cClearBufferSize = ((cTIMMaxSize div cSectorDataSize) + 1) * cClearBufferSize = ((cTIMMaxSize div cSectorDataSize) + 1) *
@@ -48,46 +46,34 @@ const
{ TScanThread } { TScanThread }
constructor TScanThread.Create(const FileToScan: string; fResult: pointer; constructor TScanThread.Create(const FileToScan: string; ImageScan: boolean);
ImageScan: boolean);
var
Node: TXmlNode;
begin begin
inherited Create(True); inherited Create(True);
FreeOnTerminate := True; FreeOnTerminate := True;
pClearBufferPosition := 0; pClearBufferPosition := 0;
pFilePos := 0; pFilePos := 0;
pTims := 0; pTims := 0;
pFileToScan := FileToScan; pFileSize := GetFileSizeAPI(FileToScan);
pFileSize := GetFileSizeAPI(pFileToScan);
pStatusText := ''; pStatusText := '';
pStopScan := False; pStopScan := False;
pImageScan := ImageScan;
pResult := fResult; pScanFile := FileToScan;
Node := pResult^.Root.NodeNew(cResInfoNode); pIsImage := ImageScan;
Node.WriteAttributeUnicodeString(cResAttrFile, pFileToScan);
Node.WriteAttributeBool(cResAttrImageFile, ImageScan);
Node.WriteAttributeInteger(cResAttrTimsCount, 0);
end; end;
procedure TScanThread.AddResult(TIM: PTIM); procedure TScanThread.AddResult(TIM: PTIM);
var var
Node, AddedNode: TXmlNode; ScanTim: TScanTim;
begin begin
Node := pResult^.Root.NodeFindOrCreate(cResInfoNode); ScanTim.Position := TIM^.dwTimPosition;
Node.WriteAttributeInteger(cResAttrTimsCount, TIM^.dwTimNumber); ScanTim.Size := TIM^.dwSIZE;
ScanTim.Width := GetTimRealWidth(TIM);
Node := pResult^.Root.NodeFindOrCreate(cResTimsNode); ScanTim.Height := GetTimHeight(TIM);
ScanTim.Bitmode := BppToBitMode(TIM);
AddedNode := Node.NodeNew(cResTimNode); ScanTim.Good := TIMIsGood(TIM);
AddedNode.WriteAttributeInteger(cResTimAttrPos, TIM^.dwTimPosition);
AddedNode.WriteAttributeInteger(cResTimAttrSize, TIM^.dwSIZE);
AddedNode.WriteAttributeInteger(cResTimAttrWidth, GetTimRealWidth(TIM));
AddedNode.WriteAttributeInteger(cResTimAttrHeight, GetTimHeight(TIM));
AddedNode.WriteAttributeInteger(cResTimAttrBitMode, BppToBitMode(TIM));
AddedNode.WriteAttributeBool(cResTimAttrGood, TIMIsGood(TIM));
pScanResult.Count := TIM^.dwTimNumber;
pScanResult.ScanTim[pScanResult.Count - 1] := ScanTim;
Inc(pTims); Inc(pTims);
end; end;
@@ -96,13 +82,15 @@ var
SectorBuffer, ClearBuffer: PBytesArray; SectorBuffer, ClearBuffer: PBytesArray;
TIM: PTIM; TIM: PTIM;
pScanFinished: boolean; pScanFinished: boolean;
pRealBufSize, pTimPosition, pTIMNumber: DWORD; pRealBufSize, pTimPosition, pTIMNumber: Integer;
begin begin
pSrcFileStream := TFileStream.Create(pFileToScan, fmOpenRead or Synchronize(StartScan);
pSrcFileStream := TFileStream.Create(pScanResult.ScanFile, fmOpenRead or
fmShareDenyWrite); fmShareDenyWrite);
pSrcFileStream.Position := 0; pSrcFileStream.Position := 0;
if pImageScan then if pScanResult.IsImage then
pSectorBufferSize := cSectorBufferSize pSectorBufferSize := cSectorBufferSize
else else
pSectorBufferSize := cClearBufferSize; pSectorBufferSize := cClearBufferSize;
@@ -127,15 +115,14 @@ begin
repeat repeat
if LoadTimFromBuf(ClearBuffer, TIM, pClearBufferPosition) then if LoadTimFromBuf(ClearBuffer, TIM, pClearBufferPosition) then
begin begin
if pImageScan then if pScanResult.IsImage then
pTimPosition := pFilePos - pRealBufSize + pTimPosition := pFilePos - pRealBufSize +
((pClearBufferPosition - 1) div cSectorDataSize) * cSectorSize + ((pClearBufferPosition - 1) div cSectorDataSize) * cSectorSize +
((pClearBufferPosition - 1) mod cSectorDataSize) + cSectorInfoSize ((pClearBufferPosition - 1) mod cSectorDataSize) + cSectorInfoSize
else else
pTimPosition := pFilePos - pRealBufSize + (pClearBufferPosition - 1); pTimPosition := pFilePos - pRealBufSize + (pClearBufferPosition - 1);
if pTimPosition >= pFileSize then if pTimPosition >= pFileSize then Break;
Break;
TIM^.dwTimPosition := pTimPosition; TIM^.dwTimPosition := pTimPosition;
Inc(pTIMNumber); Inc(pTIMNumber);
@@ -145,13 +132,11 @@ begin
if pClearBufferPosition = (pClearBufferSize div 2) then if pClearBufferPosition = (pClearBufferSize div 2) then
begin begin
if pScanFinished then if pScanFinished then Break;
Break;
pScanFinished := (pFilePos = pFileSize); pScanFinished := (pFilePos = pFileSize);
pClearBufferPosition := 0; pClearBufferPosition := 0;
Move(SectorBuffer^[pSectorBufferSize div 2], SectorBuffer^[0], Move(SectorBuffer^[pSectorBufferSize div 2], SectorBuffer^[0], pSectorBufferSize div 2);
pSectorBufferSize div 2);
if pScanFinished then if pScanFinished then
begin begin
@@ -161,8 +146,7 @@ begin
end end
else else
begin begin
pRealBufSize := pSrcFileStream. pRealBufSize := pSrcFileStream.Read(SectorBuffer^[pSectorBufferSize div 2], pSectorBufferSize div 2);
Read(SectorBuffer^[pSectorBufferSize div 2], pSectorBufferSize div 2);
Inc(pFilePos, pRealBufSize); Inc(pFilePos, pRealBufSize);
pRealBufSize := pRealBufSize + (pSectorBufferSize div 2); pRealBufSize := pRealBufSize + (pSectorBufferSize div 2);
end; end;
@@ -191,6 +175,22 @@ begin
frmMain.lblStatus.Caption := pStatusText; frmMain.lblStatus.Caption := pStatusText;
end; end;
procedure TScanThread.StartScan;
begin
frmMain.btnStopScan.Enabled := True;
frmMain.cbbFiles.Enabled := False;
frmMain.pnlList.Enabled := False;
frmMain.actExtractList.Enabled := False;
frmMain.pbProgress.Max := GetFileSizeAPI(pScanFile);
frmMain.pbProgress.Position := 0;
frmMain.ScanResult.Add(TScanResult.Create);
pScanResult := frmMain.ScanResult.Last;
pScanResult.ScanFile := pScanFile;
pScanResult.IsImage := pIsImage;
end;
procedure TScanThread.UpdateProgressBar; procedure TScanThread.UpdateProgressBar;
begin begin
frmMain.pbProgress.Position := pFilePos; frmMain.pbProgress.Position := pFilePos;
@@ -199,10 +199,10 @@ end;
procedure TScanThread.ClearSectorBuffer(SectorBuffer, ClearBuffer: PBytesArray); procedure TScanThread.ClearSectorBuffer(SectorBuffer, ClearBuffer: PBytesArray);
var var
i: DWORD; i: Integer;
begin begin
FillChar(ClearBuffer^[0], pClearBufferSize, 0); FillChar(ClearBuffer^[0], pClearBufferSize, 0);
if not pImageScan then if not pScanResult.IsImage then
begin begin
Move(SectorBuffer^[0], ClearBuffer^[0], pClearBufferSize); Move(SectorBuffer^[0], ClearBuffer^[0], pClearBufferSize);
Exit; Exit;

View File

@@ -44,7 +44,7 @@ type
bVersion: byte; // Any? (1 byte) bVersion: byte; // Any? (1 byte)
bReserved1: byte; // Reserved byte 1 (1 byte) bReserved1: byte; // Reserved byte 1 (1 byte)
bReserved2: byte; // Reserved byte 2 (1 byte) bReserved2: byte; // Reserved byte 2 (1 byte)
bBPP: DWORD; // Bit per Pixel (4 bytes) bBPP: Integer; // Bit per Pixel (4 bytes)
// variants: // variants:
// [$08, $09, $0A, $0B, $02, $03, $00, $01] // [$08, $09, $0A, $0B, $02, $03, $00, $01]
end; end;
@@ -53,7 +53,7 @@ type
type type
TCLUTHeader = packed record // CLUT header (12+ bytes) TCLUTHeader = packed record // CLUT header (12+ bytes)
dwSize: DWORD; // Length of CLUT (4 bytes) dwSize: Integer; // Length of CLUT (4 bytes)
wVRAMX: word; // Palette coordinates in VRAM (by X) (2 bytes) wVRAMX: word; // Palette coordinates in VRAM (by X) (2 bytes)
wVRAMY: word; // Palette coordinates in VRAM (by Y) (2 bytes) wVRAMY: word; // Palette coordinates in VRAM (by Y) (2 bytes)
wColorsCount: word; // Number of CLUT Colors (2 bytes) wColorsCount: word; // Number of CLUT Colors (2 bytes)
@@ -64,7 +64,7 @@ type
type type
TIMAGEHeader = packed record // IMAGE Block Header (12+ bytes) TIMAGEHeader = packed record // IMAGE Block Header (12+ bytes)
dwSize: DWORD; // Length of Image Block (4 bytes) dwSize: Integer; // Length of Image Block (4 bytes)
wVRAMX: word; // Image Block Coordinates in VRAM (by X) (2 bytes) wVRAMX: word; // Image Block Coordinates in VRAM (by X) (2 bytes)
wVRAMY: word; // Image Block Coordinates in VRAM (by Y) (2 bytes) wVRAMY: word; // Image Block Coordinates in VRAM (by Y) (2 bytes)
wWidth: word; // Image Width (not Real) (2 bytes) wWidth: word; // Image Width (not Real) (2 bytes)
@@ -93,17 +93,17 @@ type
type type
TIMAGE_INDEXES = array [0 .. cIMAGEWidthMax * cIMAGEHeightMax * 4 - TIMAGE_INDEXES = array [0 .. cIMAGEWidthMax * cIMAGEHeightMax * 4 -
1] of DWORD; 1] of Integer;
PIMAGE_INDEXES = ^TIMAGE_INDEXES; PIMAGE_INDEXES = ^TIMAGE_INDEXES;
type type
TTIM = record TTIM = record
dwTimNumber: DWORD; dwTimNumber: Integer;
dwTimPosition: DWORD; dwTimPosition: Integer;
HEAD: PTIMHeader; HEAD: PTIMHeader;
CLUT: PCLUTHeader; CLUT: PCLUTHeader;
IMAGE: PIMAGEHeader; IMAGE: PIMAGEHeader;
dwSize: DWORD; dwSize: Integer;
DATA: PTIMDataArray; DATA: PTIMDataArray;
bGOOD: Boolean; bGOOD: Boolean;
end; end;
@@ -111,16 +111,16 @@ type
PTIM = ^TTIM; PTIM = ^TTIM;
function TIMHasCLUT(TIM: PTIM): Boolean; function TIMHasCLUT(TIM: PTIM): Boolean;
function GetTIMCLUTSize(TIM: PTIM): DWORD; function GetTIMCLUTSize(TIM: PTIM): Integer;
function GetTIMSize(TIM: PTIM): DWORD; function GetTIMSize(TIM: PTIM): Integer;
function GetTimWidth(TIM: PTIM): word; 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: DWORD): Boolean; var Position: Integer): Boolean;
function LoadTimFromFile(const FileName: string; var Position: DWORD; function LoadTimFromFile(const FileName: string; var Position: Integer;
ImageScan: Boolean; dwSize: DWORD): PTIM; 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);
@@ -128,14 +128,14 @@ function BppToBitMode(TIM: PTIM): byte;
function GetTimColorsCount(TIM: PTIM): word; function GetTimColorsCount(TIM: PTIM): word;
function GetTimClutsCount(TIM: PTIM): word; function GetTimClutsCount(TIM: PTIM): word;
function GetTimVersion(TIM: PTIM): byte; function GetTimVersion(TIM: PTIM): byte;
function GetTimBPP(TIM: PTIM): DWORD; function GetTimBPP(TIM: PTIM): Integer;
function GetTimClutSizeHeader(TIM: PTIM): DWORD; function GetTimClutSizeHeader(TIM: PTIM): Integer;
function GetTimClutVRAMX(TIM: PTIM): word; function GetTimClutVRAMX(TIM: PTIM): word;
function GetTimClutVRAMY(TIM: PTIM): word; function GetTimClutVRAMY(TIM: PTIM): word;
function GetTimImageSizeHeader(TIM: PTIM): DWORD; function GetTimImageSizeHeader(TIM: PTIM): Integer;
function GetTimImageVRAMX(TIM: PTIM): word; function GetTimImageVRAMX(TIM: PTIM): word;
function GetTimImageVRAMY(TIM: PTIM): word; function GetTimImageVRAMY(TIM: PTIM): word;
function GetTIMIMAGESize(TIM: PTIM): DWORD; 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);
@@ -201,7 +201,7 @@ begin
Result := TIM^.IMAGE^.wHeight; Result := TIM^.IMAGE^.wHeight;
end; end;
function GetTIMCLUTSize(TIM: PTIM): DWORD; function GetTIMCLUTSize(TIM: PTIM): Integer;
begin begin
Result := 0; Result := 0;
@@ -211,12 +211,12 @@ begin
cCLUTHeadSize; cCLUTHeadSize;
end; end;
function GetTIMIMAGESize(TIM: PTIM): DWORD; function GetTIMIMAGESize(TIM: PTIM): Integer;
begin begin
Result := TIM^.IMAGE^.wWidth * TIM^.IMAGE^.wHeight * 2 + cIMAGEHeadSize; Result := TIM^.IMAGE^.wWidth * TIM^.IMAGE^.wHeight * 2 + cIMAGEHeadSize;
end; end;
function GetTIMSize(TIM: PTIM): DWORD; function GetTIMSize(TIM: PTIM): Integer;
begin begin
Result := GetTIMCLUTSize(TIM) + GetTIMIMAGESize(TIM) + cTIMHeadSize; Result := GetTIMCLUTSize(TIM) + GetTIMIMAGESize(TIM) + cTIMHeadSize;
end; end;
@@ -320,10 +320,10 @@ begin
end; end;
function LoadTimFromBuf(BUFFER: pointer; var TIM: PTIM; function LoadTimFromBuf(BUFFER: pointer; var TIM: PTIM;
var Position: DWORD): Boolean; var Position: Integer): Boolean;
var var
P: DWORD; P: Integer;
TIM_POS: DWORD; TIM_POS: Integer;
begin begin
Result := False; Result := False;
@@ -362,15 +362,15 @@ begin
Result := True; Result := True;
end; end;
function LoadTimFromCDFile(const FileName: string; var Position: DWORD; function LoadTimFromCDFile(const FileName: string; var Position: Integer;
SIZE: DWORD): PTIM; SIZE: Integer): PTIM;
var var
TimOffsetInSector, FirstPartSize, LastPartSize: DWORD; TimOffsetInSector, FirstPartSize, LastPartSize: Integer;
TimSectorNumber, TimStartSectorPos: DWORD; TimSectorNumber, TimStartSectorPos: Integer;
TIM_BUF: PTIMDataArray; TIM_BUF: PTIMDataArray;
sImageStream: TFileStream; sImageStream: TFileStream;
Sector: TCDSector; Sector: TCDSector;
P, TIM_FULL_SECTORS: DWORD; P, TIM_FULL_SECTORS: Integer;
begin begin
sImageStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); sImageStream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
@@ -424,11 +424,11 @@ begin
Dispose(TIM_BUF); Dispose(TIM_BUF);
end; end;
function LoadTimFromStream(Stream: TStream; var Position: DWORD; function LoadTimFromStream(Stream: TStream; var Position: Integer;
dwSize: DWORD): PTIM; dwSize: Integer): PTIM;
var var
BUF: PTIMDataArray; BUF: PTIMDataArray;
P: DWORD; P: Integer;
begin begin
Result := nil; Result := nil;
@@ -448,8 +448,8 @@ begin
Dispose(BUF); Dispose(BUF);
end; end;
function LoadTimFromFile(const FileName: string; var Position: DWORD; function LoadTimFromFile(const FileName: string; var Position: Integer;
ImageScan: Boolean; dwSize: DWORD): PTIM; ImageScan: Boolean; dwSize: Integer): PTIM;
var var
sTIM: TFileStream; sTIM: TFileStream;
begin begin
@@ -560,12 +560,12 @@ begin
Result := TIM^.CLUT^.wClutsCount; Result := TIM^.CLUT^.wClutsCount;
end; end;
function GetTimBPP(TIM: PTIM): DWORD; function GetTimBPP(TIM: PTIM): Integer;
begin begin
Result := TIM^.HEAD^.bBPP; Result := TIM^.HEAD^.bBPP;
end; end;
function GetTimClutSizeHeader(TIM: PTIM): DWORD; function GetTimClutSizeHeader(TIM: PTIM): Integer;
begin begin
Result := TIM^.CLUT^.dwSize; Result := TIM^.CLUT^.dwSize;
end; end;
@@ -580,7 +580,7 @@ begin
Result := TIM^.CLUT^.wVRAMY; Result := TIM^.CLUT^.wVRAMY;
end; end;
function GetTimImageSizeHeader(TIM: PTIM): DWORD; function GetTimImageSizeHeader(TIM: PTIM): Integer;
begin begin
Result := TIM^.IMAGE^.dwSize; Result := TIM^.IMAGE^.dwSize;
end; end;