* Refactored tiledata cloning

* Added support for new tiledata format (from the High Seas expansion)
This commit is contained in:
Andreas Schneider 2012-01-07 13:48:59 +01:00
parent 88e18b7659
commit 811d91cc8a
2 changed files with 96 additions and 34 deletions

View File

@ -21,7 +21,7 @@
* CDDL HEADER END * CDDL HEADER END
* *
* *
* Portions Copyright 2009 Andreas Schneider * Portions Copyright 2012 Andreas Schneider
*) *)
unit UTileDataProvider; unit UTileDataProvider;
@ -114,14 +114,24 @@ end;
procedure TTiledataProvider.InitArray; procedure TTiledataProvider.InitArray;
var var
i: Integer; i: Integer;
version: TTileDataVersion;
begin begin
//Guess the version by looking at the filesize.
if FData.Size >= 3188736 then
version := tdvHighSeas
else
version := tdvLegacy;
FData.Position := 0; FData.Position := 0;
Logger.Send([lcInfo], 'Loading $4000 LandTiledata Entries'); Logger.Send([lcInfo], 'Loading $4000 LandTiledata Entries');
for i := $0 to $3FFF do for i := $0 to $3FFF do
begin begin
if i mod 32 = 0 then //In High Seas, the first header comes AFTER the unknown tile (for whatever
//reason). Therefore special handling is required.
if ((version = tdvLegacy) and (i mod 32 = 0)) or
((version >= tdvHighSeas) and ((i = 1) or ((i > 1) and (i mod 32 = 0)))) then
FData.Seek(4, soFromCurrent); FData.Seek(4, soFromCurrent);
FLandTiles[i] := TLandTileData.Create(FData); FLandTiles[i] := TLandTileData.Create(FData, version);
end; end;
FStaticCount := ((FData.Size - FData.Position) div StaticTileGroupSize) * 32; FStaticCount := ((FData.Size - FData.Position) div StaticTileGroupSize) * 32;
@ -132,7 +142,7 @@ begin
begin begin
if i mod 32 = 0 then if i mod 32 = 0 then
FData.Seek(4, soFromCurrent); FData.Seek(4, soFromCurrent);
FStaticTiles[i] := TStaticTileData.Create(FData); FStaticTiles[i] := TStaticTileData.Create(FData, version);
end; end;
end; end;

View File

@ -21,7 +21,7 @@
* CDDL HEADER END * CDDL HEADER END
* *
* *
* Portions Copyright 2009 Andreas Schneider * Portions Copyright 2012 Andreas Schneider
*) *)
unit UTiledata; unit UTiledata;
@ -49,12 +49,19 @@ type
tdfStairRight); tdfStairRight);
TTileDataFlags = set of TTileDataFlag; TTileDataFlags = set of TTileDataFlag;
TTileDataVersion = (tdvLegacy, tdvHighSeas);
{ TTiledata } { TTiledata }
TTiledata = class(TMulBlock) TTiledata = class(TMulBlock)
protected protected
FVersion: TTileDataVersion;
FFlags: TTileDataFlags; FFlags: TTileDataFlags;
FNewFlags: LongWord; //HighSeas added new flags
FTileName: string; FTileName: string;
procedure ReadFlags(AData: TStream);
procedure WriteFlags(AData: TStream);
procedure PopulateClone(const AClone: TTiledata);
public public
property Flags: TTileDataFlags read FFlags write FFlags; property Flags: TTileDataFlags read FFlags write FFlags;
property TileName: string read FTileName write FTileName; property TileName: string read FTileName write FTileName;
@ -63,13 +70,14 @@ type
{ TLandTiledata } { TLandTiledata }
TLandTiledata = class(TTiledata) TLandTiledata = class(TTiledata)
constructor Create(AData: TStream); constructor Create(AData: TStream; AVersion: TTileDataVersion = tdvLegacy);
destructor Destroy; override; destructor Destroy; override;
function Clone: TLandTiledata; override; function Clone: TLandTiledata; override;
function GetSize: Integer; override; function GetSize: Integer; override;
procedure Write(AData: TStream); override; procedure Write(AData: TStream); override;
protected protected
FTextureID: Word; FTextureID: Word;
procedure PopulateClone(const AClone: TLandTiledata);
public public
property TextureID: Word read FTextureID write FTextureID; property TextureID: Word read FTextureID write FTextureID;
end; end;
@ -77,7 +85,7 @@ type
{ TStaticTiledata } { TStaticTiledata }
TStaticTiledata = class(TTiledata) TStaticTiledata = class(TTiledata)
constructor Create(AData: TStream); constructor Create(AData: TStream; AVersion: TTileDataVersion = tdvLegacy);
destructor Destroy; override; destructor Destroy; override;
function Clone: TStaticTiledata; override; function Clone: TStaticTiledata; override;
function GetSize: Integer; override; function GetSize: Integer; override;
@ -93,6 +101,7 @@ type
FHue: Byte; FHue: Byte;
FUnknown4: Word; FUnknown4: Word;
FHeight: Byte; FHeight: Byte;
procedure PopulateClone(const AClone: TStaticTiledata);
public public
property Weight: Byte read FWeight write FWeight; property Weight: Byte read FWeight write FWeight;
property Quality: Byte read FQuality write FQuality; property Quality: Byte read FQuality write FQuality;
@ -109,7 +118,7 @@ type
{ TLandTileGroup } { TLandTileGroup }
TLandTileGroup = class(TMulBlock) TLandTileGroup = class(TMulBlock)
constructor Create(AData: TStream); constructor Create(AData: TStream; AVersion: TTileDataVersion = tdvLegacy);
destructor Destroy; override; destructor Destroy; override;
function Clone: TLandTileGroup; override; function Clone: TLandTileGroup; override;
function GetSize: Integer; override; function GetSize: Integer; override;
@ -124,7 +133,7 @@ type
{ TStaticTileGroup } { TStaticTileGroup }
TStaticTileGroup = class(TMulBlock) TStaticTileGroup = class(TMulBlock)
constructor Create(AData: TStream); constructor Create(AData: TStream; AVersion: TTileDataVersion = tdvLegacy);
destructor Destroy; override; destructor Destroy; override;
function Clone: TStaticTileGroup; override; function Clone: TStaticTileGroup; override;
function GetSize: Integer; override; function GetSize: Integer; override;
@ -161,14 +170,43 @@ begin
end; end;
end; end;
{ TTiledata }
procedure TTiledata.ReadFlags(AData: TStream);
begin
AData.Read(FFlags, SizeOf(LongWord));
if FVersion >= tdvHighSeas then
AData.Read(FNewFlags, SizeOf(LongWord));
end;
procedure TTiledata.WriteFlags(AData: TStream);
begin
AData.Write(FFlags, SizeOf(LongWord));
if FVersion >= tdvHighSeas then
AData.Write(FNewFlags, SizeOf(LongWord));
end;
procedure TTiledata.PopulateClone(const AClone: TTiledata);
begin
AClone.FVersion := FVersion;
AClone.FFlags := FFlags;
AClone.FNewFlags := FNewFlags;
AClone.FTileName := FTileName;
end;
{ TLandTiledata } { TLandTiledata }
constructor TLandTiledata.Create(AData: TStream); constructor TLandTiledata.Create(AData: TStream;
AVersion: TTileDataVersion = tdvLegacy);
var
legacyFlags: LongWord;
highSeasFlags: QWord;
begin begin
FVersion := AVersion;
SetLength(FTileName, 20); SetLength(FTileName, 20);
if assigned(AData) then if assigned(AData) then
begin begin
AData.Read(FFlags, SizeOf(LongWord)); ReadFlags(AData);
AData.Read(FTextureID, SizeOf(Word)); AData.Read(FTextureID, SizeOf(Word));
AData.Read(PChar(FTileName)^, 20); AData.Read(PChar(FTileName)^, 20);
end; end;
@ -184,9 +222,7 @@ end;
function TLandTiledata.Clone: TLandTiledata; function TLandTiledata.Clone: TLandTiledata;
begin begin
Result := TLandTiledata.Create(nil); Result := TLandTiledata.Create(nil);
Result.FFlags := FFlags; PopulateClone(Result);
Result.FTextureID := FTextureID;
Result.FTileName := FTileName;
end; end;
procedure TLandTiledata.Write(AData: TStream); procedure TLandTiledata.Write(AData: TStream);
@ -196,11 +232,18 @@ begin
if Length(FTileName) < 20 then if Length(FTileName) < 20 then
for i := Length(FTileName) to 20 do for i := Length(FTileName) to 20 do
FTileName := FTileName + #0; FTileName := FTileName + #0;
AData.Write(FFlags, SizeOf(LongWord));
WriteFlags(AData);
AData.Write(FTextureID, SizeOf(Word)); AData.Write(FTextureID, SizeOf(Word));
AData.Write(PChar(FTileName)^, 20); AData.Write(PChar(FTileName)^, 20);
end; end;
procedure TLandTiledata.PopulateClone(const AClone: TLandTiledata);
begin
inherited PopulateClone(AClone);
AClone.FTextureID := FTextureID;
end;
function TLandTiledata.GetSize: Integer; function TLandTiledata.GetSize: Integer;
begin begin
GetSize := LandTileDataSize; GetSize := LandTileDataSize;
@ -208,12 +251,14 @@ end;
{ TStaticTiledata} { TStaticTiledata}
constructor TStaticTiledata.Create(AData: TStream); constructor TStaticTiledata.Create(AData: TStream;
AVersion: TTileDataVersion = tdvLegacy);
begin begin
FVersion := AVersion;
SetLength(FTileName, 20); SetLength(FTileName, 20);
if AData <> nil then if AData <> nil then
begin begin
AData.Read(FFlags, SizeOf(LongWord)); ReadFlags(AData);
AData.Read(FWeight, SizeOf(Byte)); AData.Read(FWeight, SizeOf(Byte));
AData.Read(FQuality, SizeOf(Byte)); AData.Read(FQuality, SizeOf(Byte));
AData.Read(FUnknown1, SizeOf(Word)); AData.Read(FUnknown1, SizeOf(Word));
@ -238,18 +283,7 @@ end;
function TStaticTiledata.Clone: TStaticTiledata; function TStaticTiledata.Clone: TStaticTiledata;
begin begin
Result := TStaticTiledata.Create(nil); Result := TStaticTiledata.Create(nil);
Result.FFlags := FFlags; PopulateClone(Result);
Result.FWeight := FWeight;
Result.FQuality := FQuality;
Result.FUnknown1 := FUnknown1;
Result.FUnknown2 := FUnknown2;
Result.FQuantity := FQuantity;
Result.FAnimID := FAnimID;
Result.FUnknown3 := FUnknown3;
Result.FHue := FHue;
Result.FUnknown4 := FUnknown4;
Result.FHeight := FHeight;
Result.FTileName := FTileName;
end; end;
procedure TStaticTiledata.Write(AData: TStream); procedure TStaticTiledata.Write(AData: TStream);
@ -259,7 +293,8 @@ begin
if Length(FTileName) < 20 then if Length(FTileName) < 20 then
for i := Length(FTileName) to 20 do for i := Length(FTileName) to 20 do
FTileName := FTileName + #0; FTileName := FTileName + #0;
AData.Write(FFlags, SizeOf(LongWord));
WriteFlags(AData);
AData.Write(FWeight, SizeOf(Byte)); AData.Write(FWeight, SizeOf(Byte));
AData.Write(FQuality, SizeOf(Byte)); AData.Write(FQuality, SizeOf(Byte));
AData.Write(FUnknown1, SizeOf(Word)); AData.Write(FUnknown1, SizeOf(Word));
@ -273,6 +308,21 @@ begin
AData.Write(PChar(FTileName)^, 20); AData.Write(PChar(FTileName)^, 20);
end; end;
procedure TStaticTiledata.PopulateClone(const AClone: TStaticTiledata);
begin
inherited PopulateClone(AClone);
AClone.FWeight := FWeight;
AClone.FQuality := FQuality;
AClone.FUnknown1 := FUnknown1;
AClone.FUnknown2 := FUnknown2;
AClone.FQuantity := FQuantity;
AClone.FAnimID := FAnimID;
AClone.FUnknown3 := FUnknown3;
AClone.FHue := FHue;
AClone.FUnknown4 := FUnknown4;
AClone.FHeight := FHeight;
end;
function TStaticTiledata.GetSize: Integer; function TStaticTiledata.GetSize: Integer;
begin begin
GetSize := StaticTileDataSize; GetSize := StaticTileDataSize;
@ -280,7 +330,8 @@ end;
{ TLandTileGroup } { TLandTileGroup }
constructor TLandTileGroup.Create(AData: TStream); constructor TLandTileGroup.Create(AData: TStream;
AVersion: TTileDataVersion = tdvLegacy);
var var
i: Integer; i: Integer;
begin begin
@ -289,7 +340,7 @@ begin
AData.Read(FUnknown, SizeOf(LongInt)); AData.Read(FUnknown, SizeOf(LongInt));
end; end;
for i := 0 to 31 do for i := 0 to 31 do
LandTileData[i] := TLandTiledata.Create(AData); LandTileData[i] := TLandTiledata.Create(AData, AVersion);
end; end;
destructor TLandTileGroup.Destroy; destructor TLandTileGroup.Destroy;
@ -327,7 +378,8 @@ end;
{ TStaticTileGroup } { TStaticTileGroup }
constructor TStaticTileGroup.Create(AData: TStream); constructor TStaticTileGroup.Create(AData: TStream;
AVersion: TTileDataVersion = tdvLegacy);
var var
i: Integer; i: Integer;
begin begin
@ -336,7 +388,7 @@ begin
AData.Read(FUnknown, SizeOf(LongInt)); AData.Read(FUnknown, SizeOf(LongInt));
end; end;
for i := 0 to 31 do for i := 0 to 31 do
StaticTileData[i] := TStaticTiledata.Create(AData); StaticTileData[i] := TStaticTiledata.Create(AData, AVersion);
end; end;
destructor TStaticTileGroup.Destroy; destructor TStaticTileGroup.Destroy;