159 lines
3.3 KiB
Plaintext
159 lines
3.3 KiB
Plaintext
|
unit UUoaDesigns;
|
||
|
|
||
|
{$mode ObjFPC}{$H+}
|
||
|
{$modeSwitch advancedRecords}
|
||
|
|
||
|
interface
|
||
|
|
||
|
uses
|
||
|
Classes, SysUtils, Generics.Collections, UStatics;
|
||
|
|
||
|
type
|
||
|
|
||
|
{ TUoaDesignHeader }
|
||
|
|
||
|
TUoaDesignHeader = record
|
||
|
Name: String;
|
||
|
Category: String;
|
||
|
Subcategory: String;
|
||
|
Width: Int32;
|
||
|
Height: Int32;
|
||
|
UserWidth: Int32;
|
||
|
UserHeight: Int32;
|
||
|
FilePosition: Int64;
|
||
|
TileCount: Int32;
|
||
|
public
|
||
|
constructor CreateFromStream(AStream: TStream);
|
||
|
end;
|
||
|
|
||
|
{ TUoaDesignHeaders }
|
||
|
|
||
|
TUoaDesignHeaders = class(specialize TList<TUoaDesignHeader>)
|
||
|
constructor CreateFromStream(AStream: TStream);
|
||
|
end;
|
||
|
|
||
|
{ TUoaDesigns }
|
||
|
|
||
|
TUoaDesigns = class
|
||
|
private
|
||
|
FHeaders: TUoaDesignHeaders;
|
||
|
FData: TFileStream;
|
||
|
public
|
||
|
constructor Create(AIdxFile, ABinFile: String);
|
||
|
destructor Destroy; override;
|
||
|
|
||
|
function LoadTiles(AHeader: TUoaDesignHeader; AOffsetX, AOffsetY: Word): TStaticItemList;
|
||
|
public
|
||
|
property Headers: TUoaDesignHeaders read FHeaders;
|
||
|
end;
|
||
|
|
||
|
implementation
|
||
|
|
||
|
function ReadString(AStream: TStream): String;
|
||
|
var
|
||
|
nonNullFlag: Byte;
|
||
|
length: Byte;
|
||
|
begin
|
||
|
nonNullFlag := AStream.ReadByte;
|
||
|
if nonNullFlag = 1 then
|
||
|
begin
|
||
|
length := AStream.ReadByte;
|
||
|
SetLength(Result, length);
|
||
|
if length > 0 then
|
||
|
AStream.Read(PChar(Result)^, length);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
{ TUoaDesignHeaders }
|
||
|
|
||
|
constructor TUoaDesignHeaders.CreateFromStream(AStream: TStream);
|
||
|
var
|
||
|
headerCount, version: Int32;
|
||
|
i: Integer;
|
||
|
begin
|
||
|
AStream.Read(headerCount, SizeOf(headerCount));
|
||
|
AStream.Read(version, SizeOf(version));
|
||
|
|
||
|
if version <> 0 then
|
||
|
raise Exception.Create('Unknown UOA design index version');
|
||
|
|
||
|
inherited Create;
|
||
|
|
||
|
for i := 0 to headerCount-1 do
|
||
|
Add(TUoaDesignHeader.CreateFromStream(AStream));
|
||
|
end;
|
||
|
|
||
|
{ TUoaDesignHeader }
|
||
|
|
||
|
constructor TUoaDesignHeader.CreateFromStream(AStream: TStream);
|
||
|
begin
|
||
|
Name := ReadString(AStream);
|
||
|
Category := ReadString(AStream);
|
||
|
Subcategory := ReadString(AStream);
|
||
|
AStream.Read(Width, SizeOf(Width));
|
||
|
AStream.Read(Height, SizeOf(Height));
|
||
|
AStream.Read(UserWidth, SizeOf(UserWidth));
|
||
|
AStream.Read(UserHeight, SizeOf(UserHeight));
|
||
|
AStream.Read(FilePosition, SizeOf(FilePosition));
|
||
|
AStream.Read(TileCount, SizeOf(TileCount));
|
||
|
end;
|
||
|
|
||
|
{ TUoaDesigns }
|
||
|
|
||
|
constructor TUoaDesigns.Create(AIdxFile, ABinFile: String);
|
||
|
var
|
||
|
idxStream: TFileStream;
|
||
|
begin
|
||
|
idxStream := TFileStream.Create(AIdxFile, fmOpenRead);
|
||
|
try
|
||
|
FHeaders := TUoaDesignHeaders.CreateFromStream(idxStream);
|
||
|
finally
|
||
|
idxStream.Free;
|
||
|
end;
|
||
|
|
||
|
FData := TFileStream.Create(ABinFile, fmOpenRead);
|
||
|
end;
|
||
|
|
||
|
destructor TUoaDesigns.Destroy;
|
||
|
begin
|
||
|
Headers.Free;
|
||
|
end;
|
||
|
|
||
|
function TUoaDesigns.LoadTiles(AHeader: TUoaDesignHeader; AOffsetX,
|
||
|
AOffsetY: Word): TStaticItemList;
|
||
|
var
|
||
|
i: Integer;
|
||
|
tile: TStaticItem;
|
||
|
version: Int32;
|
||
|
|
||
|
function ReadInt: Int32;
|
||
|
begin
|
||
|
FData.Read(Result, SizeOf(Result));
|
||
|
end;
|
||
|
|
||
|
begin
|
||
|
Result := TStaticItemList.Create(True);
|
||
|
FData.Seek(AHeader.FilePosition, soFromBeginning);
|
||
|
for i := 0 to AHeader.TileCount - 1 do
|
||
|
begin
|
||
|
FData.Read(version, SizeOf(version));
|
||
|
if (version < 0) or (version > 1) then
|
||
|
raise Exception.Create('Unsupported binary version');
|
||
|
|
||
|
tile := TStaticItem.Create(nil);
|
||
|
tile.TileID := ReadInt;
|
||
|
tile.X := AOffsetX + ReadInt;
|
||
|
tile.Y := AOffsetY + ReadInt;
|
||
|
tile.Z := ReadInt;
|
||
|
ReadInt; // TODO: Level??
|
||
|
|
||
|
if version = 1 then
|
||
|
tile.Hue := ReadInt;
|
||
|
|
||
|
Result.Add(tile);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
end.
|
||
|
|