- Fixed Art and TexMap to no longer get loaded if their Size is <= 0
This commit is contained in:
parent
5c3de09d10
commit
34765f7235
|
@ -56,7 +56,7 @@
|
||||||
<MinVersion Major="4" Minor="5" Release="1" Valid="True"/>
|
<MinVersion Major="4" Minor="5" Release="1" Valid="True"/>
|
||||||
</Item5>
|
</Item5>
|
||||||
</RequiredPackages>
|
</RequiredPackages>
|
||||||
<Units Count="40">
|
<Units Count="42">
|
||||||
<Unit0>
|
<Unit0>
|
||||||
<Filename Value="CentrED.lpr"/>
|
<Filename Value="CentrED.lpr"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
|
@ -298,6 +298,16 @@
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
<UnitName Value="UMulManager"/>
|
<UnitName Value="UMulManager"/>
|
||||||
</Unit39>
|
</Unit39>
|
||||||
|
<Unit40>
|
||||||
|
<Filename Value="../MulProvider/UArtProvider.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="UArtProvider"/>
|
||||||
|
</Unit40>
|
||||||
|
<Unit41>
|
||||||
|
<Filename Value="../MulProvider/UTexmapProvider.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="UTexmapProvider"/>
|
||||||
|
</Unit41>
|
||||||
</Units>
|
</Units>
|
||||||
</ProjectOptions>
|
</ProjectOptions>
|
||||||
<CompilerOptions>
|
<CompilerOptions>
|
||||||
|
|
|
@ -42,7 +42,7 @@ uses
|
||||||
UGUIPlatformUtils, UPlatformTypes, UfrmRegionControl, UPackets,
|
UGUIPlatformUtils, UPlatformTypes, UfrmRegionControl, UPackets,
|
||||||
UPacketHandlers, UAdminHandling, UGameResources, ULandscape, UfrmToolWindow,
|
UPacketHandlers, UAdminHandling, UGameResources, ULandscape, UfrmToolWindow,
|
||||||
Logging, UTileDataProvider, UMap, UWorldItem, UStatics, UTiledata, UAnimData,
|
Logging, UTileDataProvider, UMap, UWorldItem, UStatics, UTiledata, UAnimData,
|
||||||
UGLFont, UAnimDataProvider, UMulManager;
|
UGLFont, UAnimDataProvider, UMulManager, UArtProvider, UTexmapProvider;
|
||||||
|
|
||||||
{$IFDEF WINDOWS}{$R CentrED.rc}{$ENDIF}
|
{$IFDEF WINDOWS}{$R CentrED.rc}{$ENDIF}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ type
|
||||||
|
|
||||||
{ TGameResourceManager }
|
{ TGameResourceManager }
|
||||||
|
|
||||||
TGameResourceManager = class(TObject)
|
TGameResourceManager = class
|
||||||
constructor Create(ADataDir: string);
|
constructor Create(ADataDir: string);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
protected
|
protected
|
||||||
|
|
|
@ -1,97 +1,97 @@
|
||||||
(*
|
(*
|
||||||
* CDDL HEADER START
|
* CDDL HEADER START
|
||||||
*
|
*
|
||||||
* The contents of this file are subject to the terms of the
|
* The contents of this file are subject to the terms of the
|
||||||
* Common Development and Distribution License, Version 1.0 only
|
* Common Development and Distribution License, Version 1.0 only
|
||||||
* (the "License"). You may not use this file except in compliance
|
* (the "License"). You may not use this file except in compliance
|
||||||
* with the License.
|
* with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at
|
* You can obtain a copy of the license at
|
||||||
* http://www.opensource.org/licenses/cddl1.php.
|
* http://www.opensource.org/licenses/cddl1.php.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
* When distributing Covered Code, include this CDDL HEADER in each
|
* When distributing Covered Code, include this CDDL HEADER in each
|
||||||
* file and include the License file at
|
* file and include the License file at
|
||||||
* http://www.opensource.org/licenses/cddl1.php. If applicable,
|
* http://www.opensource.org/licenses/cddl1.php. If applicable,
|
||||||
* add the following below this CDDL HEADER, with the fields enclosed
|
* add the following below this CDDL HEADER, with the fields enclosed
|
||||||
* by brackets "[]" replaced with your own identifying * information:
|
* by brackets "[]" replaced with your own identifying * information:
|
||||||
* Portions Copyright [yyyy] [name of copyright owner]
|
* Portions Copyright [yyyy] [name of copyright owner]
|
||||||
*
|
*
|
||||||
* CDDL HEADER END
|
* CDDL HEADER END
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Portions Copyright 2007 Andreas Schneider
|
* Portions Copyright 2009 Andreas Schneider
|
||||||
*)
|
*)
|
||||||
unit UArtProvider;
|
unit UArtProvider;
|
||||||
|
|
||||||
{$mode objfpc}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Graphics, UMulProvider, UMulBlock, UGenericIndex, UArt, UHue;
|
Graphics, UMulProvider, UMulBlock, UGenericIndex, UArt, UHue;
|
||||||
|
|
||||||
type
|
type
|
||||||
TArtProvider = class(TIndexedMulProvider)
|
TArtProvider = class(TIndexedMulProvider)
|
||||||
protected
|
protected
|
||||||
function GetData(AID: Integer; AIndex: TGenericIndex): TMulBlock; override;
|
function GetData(AID: Integer; AIndex: TGenericIndex): TMulBlock; override;
|
||||||
function GetArtData(AID: Integer; AIndex: TGenericIndex; AColor: Word; AHue: THue; APartialHue: Boolean): TArt;
|
function GetArtData(AID: Integer; AIndex: TGenericIndex; AColor: Word; AHue: THue; APartialHue: Boolean): TArt;
|
||||||
public
|
public
|
||||||
function GetArt(AID: Integer; AColor: Word; AHue: THue; APartialHue: Boolean): TArt;
|
function GetArt(AID: Integer; AColor: Word; AHue: THue; APartialHue: Boolean): TArt;
|
||||||
function GetFlatLand(AID: Integer): TArt;
|
function GetFlatLand(AID: Integer): TArt;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
{ TArtProvider }
|
{ TArtProvider }
|
||||||
|
|
||||||
function TArtProvider.GetData(AID: Integer; AIndex: TGenericIndex): TMulBlock;
|
function TArtProvider.GetData(AID: Integer; AIndex: TGenericIndex): TMulBlock;
|
||||||
begin
|
begin
|
||||||
Result := GetArtData(AID, AIndex, clBlack, nil, False);
|
Result := GetArtData(AID, AIndex, clBlack, nil, False);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TArtProvider.GetArtData(AID: Integer; AIndex: TGenericIndex;
|
function TArtProvider.GetArtData(AID: Integer; AIndex: TGenericIndex;
|
||||||
AColor: Word; AHue: THue; APartialHue: Boolean): TArt;
|
AColor: Word; AHue: THue; APartialHue: Boolean): TArt;
|
||||||
begin
|
begin
|
||||||
if AIndex.Lookup <> LongInt($FFFFFFFF) then
|
if (AIndex.Lookup > -1) and (AIndex.Size > 0) then
|
||||||
begin
|
begin
|
||||||
if AID < $4000 then
|
if AID < $4000 then
|
||||||
Result := TArt.Create(FData, AIndex, atLand, AColor, AHue, APartialHue)
|
Result := TArt.Create(FData, AIndex, atLand, AColor, AHue, APartialHue)
|
||||||
else
|
else
|
||||||
Result := TArt.Create(FData, AIndex, atStatic, AColor, AHue, APartialHue);
|
Result := TArt.Create(FData, AIndex, atStatic, AColor, AHue, APartialHue);
|
||||||
end else
|
end else
|
||||||
begin
|
begin
|
||||||
if AID < $4000 then
|
if AID < $4000 then
|
||||||
Result := TArt.Create(nil, nil, atLand, AColor, AHue, APartialHue)
|
Result := TArt.Create(nil, nil, atLand, AColor, AHue, APartialHue)
|
||||||
else
|
else
|
||||||
Result := TArt.Create(nil, nil, atStatic, AColor, AHue, APartialHue);
|
Result := TArt.Create(nil, nil, atStatic, AColor, AHue, APartialHue);
|
||||||
end;
|
end;
|
||||||
Result.ID := AID;
|
Result.ID := AID;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TArtProvider.GetArt(AID: Integer; AColor: Word; AHue: THue; APartialHue: Boolean): TArt;
|
function TArtProvider.GetArt(AID: Integer; AColor: Word; AHue: THue; APartialHue: Boolean): TArt;
|
||||||
var
|
var
|
||||||
genericIndex: TGenericIndex;
|
genericIndex: TGenericIndex;
|
||||||
begin
|
begin
|
||||||
FIndex.Position := CalculateIndexOffset(AID);
|
FIndex.Position := CalculateIndexOffset(AID);
|
||||||
genericIndex := TGenericIndex.Create(FIndex);
|
genericIndex := TGenericIndex.Create(FIndex);
|
||||||
Result := GetArtData(AID, genericIndex, AColor, AHue, APartialHue);
|
Result := GetArtData(AID, genericIndex, AColor, AHue, APartialHue);
|
||||||
genericIndex.Free;
|
genericIndex.Free;
|
||||||
Result.OnChanged := @OnChanged;
|
Result.OnChanged := @OnChanged;
|
||||||
Result.OnFinished := @OnFinished;
|
Result.OnFinished := @OnFinished;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TArtProvider.GetFlatLand(AID: Integer): TArt;
|
function TArtProvider.GetFlatLand(AID: Integer): TArt;
|
||||||
var
|
var
|
||||||
genericIndex: TGenericIndex;
|
genericIndex: TGenericIndex;
|
||||||
begin
|
begin
|
||||||
FIndex.Position := CalculateIndexOffset(AID);
|
FIndex.Position := CalculateIndexOffset(AID);
|
||||||
genericIndex := TGenericIndex.Create(FIndex);
|
genericIndex := TGenericIndex.Create(FIndex);
|
||||||
Result := TArt.Create(FData, genericIndex, atLandFlat);
|
Result := TArt.Create(FData, genericIndex, atLandFlat);
|
||||||
genericIndex.Free;
|
genericIndex.Free;
|
||||||
Result.OnChanged := @OnChanged;
|
Result.OnChanged := @OnChanged;
|
||||||
Result.OnFinished := @OnFinished;
|
Result.OnFinished := @OnFinished;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
|
@ -1,378 +1,387 @@
|
||||||
(*
|
(*
|
||||||
* CDDL HEADER START
|
* CDDL HEADER START
|
||||||
*
|
*
|
||||||
* The contents of this file are subject to the terms of the
|
* The contents of this file are subject to the terms of the
|
||||||
* Common Development and Distribution License, Version 1.0 only
|
* Common Development and Distribution License, Version 1.0 only
|
||||||
* (the "License"). You may not use this file except in compliance
|
* (the "License"). You may not use this file except in compliance
|
||||||
* with the License.
|
* with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at
|
* You can obtain a copy of the license at
|
||||||
* http://www.opensource.org/licenses/cddl1.php.
|
* http://www.opensource.org/licenses/cddl1.php.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
* When distributing Covered Code, include this CDDL HEADER in each
|
* When distributing Covered Code, include this CDDL HEADER in each
|
||||||
* file and include the License file at
|
* file and include the License file at
|
||||||
* http://www.opensource.org/licenses/cddl1.php. If applicable,
|
* http://www.opensource.org/licenses/cddl1.php. If applicable,
|
||||||
* add the following below this CDDL HEADER, with the fields enclosed
|
* add the following below this CDDL HEADER, with the fields enclosed
|
||||||
* by brackets "[]" replaced with your own identifying * information:
|
* by brackets "[]" replaced with your own identifying * information:
|
||||||
* Portions Copyright [yyyy] [name of copyright owner]
|
* Portions Copyright [yyyy] [name of copyright owner]
|
||||||
*
|
*
|
||||||
* CDDL HEADER END
|
* CDDL HEADER END
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Portions Copyright 2007 Andreas Schneider
|
* Portions Copyright 2009 Andreas Schneider
|
||||||
*)
|
*)
|
||||||
unit UMulProvider;
|
unit UMulProvider;
|
||||||
|
|
||||||
{$mode objfpc}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
SysUtils, Classes, UBufferedStreams, UMulBlock, UGenericIndex;
|
SysUtils, Classes, UBufferedStreams, UMulBlock, UGenericIndex;
|
||||||
|
|
||||||
type
|
type
|
||||||
TOnProgressEvent = procedure(Total, Current: Integer) of object;
|
TOnProgressEvent = procedure(Total, Current: Integer) of object;
|
||||||
TMulEventHandler = class(TObject)
|
|
||||||
constructor Create;
|
{ TMulEventHandler }
|
||||||
destructor Destroy; override;
|
|
||||||
protected
|
TMulEventHandler = class
|
||||||
FEvents: TList;
|
constructor Create;
|
||||||
public
|
destructor Destroy; override;
|
||||||
procedure RegisterEvent(AEvent: TMulBlockChanged);
|
protected
|
||||||
procedure UnregisterEvent(AEvent: TMulBlockChanged);
|
FEvents: TList;
|
||||||
procedure FireEvents(ABlock: TMulBlock);
|
public
|
||||||
end;
|
procedure RegisterEvent(AEvent: TMulBlockChanged);
|
||||||
TMulProvider = class(TObject)
|
procedure UnregisterEvent(AEvent: TMulBlockChanged);
|
||||||
constructor Create; overload; virtual;
|
procedure FireEvents(ABlock: TMulBlock);
|
||||||
constructor Create(AData: TStream; AReadOnly: Boolean = False); overload; virtual;
|
end;
|
||||||
constructor Create(AData: string; AReadOnly: Boolean = False); overload; virtual;
|
|
||||||
destructor Destroy; override;
|
{ TMulProvider }
|
||||||
protected
|
|
||||||
FData: TStream;
|
TMulProvider = class
|
||||||
FOwnsData: Boolean;
|
constructor Create; overload; virtual;
|
||||||
FReadOnly: Boolean;
|
constructor Create(AData: TStream; AReadOnly: Boolean = False); overload; virtual;
|
||||||
FChangeEvents: TMulEventHandler;
|
constructor Create(AData: string; AReadOnly: Boolean = False); overload; virtual;
|
||||||
FFinishedEvents: TMulEventHandler;
|
destructor Destroy; override;
|
||||||
function CalculateOffset(AID: Integer): Integer; virtual; abstract;
|
protected
|
||||||
function GetData(AID, AOffset: Integer): TMulBlock; virtual; abstract;
|
FData: TStream;
|
||||||
procedure SetData(AID, AOffset: Integer; ABlock: TMulBlock); virtual;
|
FOwnsData: Boolean;
|
||||||
procedure OnChanged(ABlock: TMulBlock);
|
FReadOnly: Boolean;
|
||||||
procedure OnFinished(ABlock: TMulBlock);
|
FChangeEvents: TMulEventHandler;
|
||||||
public
|
FFinishedEvents: TMulEventHandler;
|
||||||
function GetBlock(AID: Integer): TMulBlock; virtual;
|
function CalculateOffset(AID: Integer): Integer; virtual; abstract;
|
||||||
procedure SetBlock(AID: Integer; ABlock: TMulBlock); virtual;
|
function GetData(AID, AOffset: Integer): TMulBlock; virtual; abstract;
|
||||||
procedure RegisterOnChangeEvent(AEvent: TMulBlockChanged);
|
procedure SetData(AID, AOffset: Integer; ABlock: TMulBlock); virtual;
|
||||||
procedure UnregisterOnChangeEvent(AEvent: TMulBlockChanged);
|
procedure OnChanged(ABlock: TMulBlock);
|
||||||
procedure RegisterOnFinishedEvent(AEvent: TMulBlockChanged);
|
procedure OnFinished(ABlock: TMulBlock);
|
||||||
procedure UnregisterOnFinishedEvent(AEvent: TMulBlockChanged);
|
public
|
||||||
property Block[ID: Integer]: TMulBlock read GetBlock write SetBlock;
|
function GetBlock(AID: Integer): TMulBlock; virtual;
|
||||||
property Data: TStream read FData;
|
procedure SetBlock(AID: Integer; ABlock: TMulBlock); virtual;
|
||||||
end;
|
procedure RegisterOnChangeEvent(AEvent: TMulBlockChanged);
|
||||||
TIndexedMulProvider = class(TMulProvider)
|
procedure UnregisterOnChangeEvent(AEvent: TMulBlockChanged);
|
||||||
constructor Create(AData, AIndex: TStream; AReadOnly: Boolean = False); overload; virtual;
|
procedure RegisterOnFinishedEvent(AEvent: TMulBlockChanged);
|
||||||
constructor Create(AData, AIndex: string; AReadOnly: Boolean = False); overload; virtual;
|
procedure UnregisterOnFinishedEvent(AEvent: TMulBlockChanged);
|
||||||
destructor Destroy; override;
|
property Block[ID: Integer]: TMulBlock read GetBlock write SetBlock;
|
||||||
protected
|
property Data: TStream read FData;
|
||||||
FIndex: TBufferedReader;
|
end;
|
||||||
function CalculateIndexOffset(AID: Integer): Integer; virtual;
|
|
||||||
function GetData(AID: Integer; AIndex: TGenericIndex): TMulBlock; reintroduce; virtual; abstract;
|
{ TIndexedMulProvider }
|
||||||
procedure SetData(AID: Integer; AIndex: TGenericIndex; ABlock: TMulBlock); reintroduce; virtual;
|
|
||||||
function GetVarious(AID: Integer; ABlock: TMulBlock; ADefault: Integer): Integer; virtual;
|
TIndexedMulProvider = class(TMulProvider)
|
||||||
public
|
constructor Create(AData, AIndex: TStream; AReadOnly: Boolean = False); overload; virtual;
|
||||||
function GetBlock(AID: Integer): TMulBlock; override;
|
constructor Create(AData, AIndex: string; AReadOnly: Boolean = False); overload; virtual;
|
||||||
procedure GetBlockEx(AID: Integer; var ABlock: TMulBlock; var AIndex: TGenericIndex); virtual;
|
destructor Destroy; override;
|
||||||
procedure SetBlock(AID: Integer; ABlock: TMulBlock); override;
|
protected
|
||||||
function Exists(AID: Integer): Boolean; virtual;
|
FIndex: TBufferedReader;
|
||||||
procedure Defragment(ATempStream: TStream; AOnProgress: TOnProgressEvent = nil); virtual;
|
function CalculateIndexOffset(AID: Integer): Integer; virtual;
|
||||||
property Index: TBufferedReader read FIndex;
|
function GetData(AID: Integer; AIndex: TGenericIndex): TMulBlock; reintroduce; virtual; abstract;
|
||||||
end;
|
procedure SetData(AID: Integer; AIndex: TGenericIndex; ABlock: TMulBlock); reintroduce; virtual;
|
||||||
|
function GetVarious(AID: Integer; ABlock: TMulBlock; ADefault: Integer): Integer; virtual;
|
||||||
implementation
|
public
|
||||||
|
function GetBlock(AID: Integer): TMulBlock; override;
|
||||||
type
|
procedure GetBlockEx(AID: Integer; var ABlock: TMulBlock; var AIndex: TGenericIndex); virtual;
|
||||||
PMethod = ^TMethod;
|
procedure SetBlock(AID: Integer; ABlock: TMulBlock); override;
|
||||||
|
function Exists(AID: Integer): Boolean; virtual;
|
||||||
{ TMulEventHandler }
|
procedure Defragment(ATempStream: TStream; AOnProgress: TOnProgressEvent = nil); virtual;
|
||||||
|
property Index: TBufferedReader read FIndex;
|
||||||
constructor TMulEventHandler.Create;
|
end;
|
||||||
begin
|
|
||||||
inherited;
|
implementation
|
||||||
FEvents := TList.Create;
|
|
||||||
end;
|
type
|
||||||
|
PMethod = ^TMethod;
|
||||||
destructor TMulEventHandler.Destroy;
|
|
||||||
var
|
{ TMulEventHandler }
|
||||||
i: Integer;
|
|
||||||
begin
|
constructor TMulEventHandler.Create;
|
||||||
if Assigned(FEvents) then
|
begin
|
||||||
begin
|
inherited;
|
||||||
for i := 0 to FEvents.Count - 1 do
|
FEvents := TList.Create;
|
||||||
Dispose(PMethod(FEvents.Items[i]));
|
end;
|
||||||
FreeAndNil(FEvents);
|
|
||||||
end;
|
destructor TMulEventHandler.Destroy;
|
||||||
inherited;
|
var
|
||||||
end;
|
i: Integer;
|
||||||
|
begin
|
||||||
procedure TMulEventHandler.FireEvents(ABlock: TMulBlock);
|
if Assigned(FEvents) then
|
||||||
var
|
begin
|
||||||
i: Integer;
|
for i := 0 to FEvents.Count - 1 do
|
||||||
begin
|
Dispose(PMethod(FEvents.Items[i]));
|
||||||
for i := 0 to FEvents.Count - 1 do
|
FreeAndNil(FEvents);
|
||||||
TMulBlockChanged(FEvents.Items[i]^)(ABlock);
|
end;
|
||||||
end;
|
inherited;
|
||||||
|
end;
|
||||||
procedure TMulEventHandler.RegisterEvent(AEvent: TMulBlockChanged);
|
|
||||||
var
|
procedure TMulEventHandler.FireEvents(ABlock: TMulBlock);
|
||||||
eventInfo: PMethod;
|
var
|
||||||
begin
|
i: Integer;
|
||||||
UnregisterEvent(AEvent);
|
begin
|
||||||
New(eventInfo);
|
for i := 0 to FEvents.Count - 1 do
|
||||||
eventInfo^.Code := TMethod(AEvent).Code;
|
TMulBlockChanged(FEvents.Items[i]^)(ABlock);
|
||||||
eventInfo^.Data := TMethod(AEvent).Data;
|
end;
|
||||||
FEvents.Add(eventInfo);
|
|
||||||
end;
|
procedure TMulEventHandler.RegisterEvent(AEvent: TMulBlockChanged);
|
||||||
|
var
|
||||||
procedure TMulEventHandler.UnregisterEvent(AEvent: TMulBlockChanged);
|
eventInfo: PMethod;
|
||||||
var
|
begin
|
||||||
i: Integer;
|
UnregisterEvent(AEvent);
|
||||||
|
New(eventInfo);
|
||||||
function RemoveEntry: Boolean;
|
eventInfo^.Code := TMethod(AEvent).Code;
|
||||||
begin
|
eventInfo^.Data := TMethod(AEvent).Data;
|
||||||
Dispose(PMethod(FEvents.Items[i]));
|
FEvents.Add(eventInfo);
|
||||||
FEvents.Delete(i);
|
end;
|
||||||
Result := True;
|
|
||||||
end;
|
procedure TMulEventHandler.UnregisterEvent(AEvent: TMulBlockChanged);
|
||||||
|
var
|
||||||
begin
|
i: Integer;
|
||||||
i := 0;
|
|
||||||
while (i < FEvents.Count) and ((TMethod(AEvent).Code <> TMethod(FEvents.Items[i]^).Code) or (TMethod(AEvent).Data <> TMethod(FEvents.Items[i]^).Data) or not RemoveEntry) do
|
function RemoveEntry: Boolean;
|
||||||
Inc(i);
|
begin
|
||||||
end;
|
Dispose(PMethod(FEvents.Items[i]));
|
||||||
|
FEvents.Delete(i);
|
||||||
{ TMulProvider }
|
Result := True;
|
||||||
|
end;
|
||||||
constructor TMulProvider.Create(AData: TStream; AReadOnly: Boolean = False);
|
|
||||||
begin
|
begin
|
||||||
Create;
|
i := 0;
|
||||||
FData := AData;
|
while (i < FEvents.Count) and ((TMethod(AEvent).Code <> TMethod(FEvents.Items[i]^).Code) or (TMethod(AEvent).Data <> TMethod(FEvents.Items[i]^).Data) or not RemoveEntry) do
|
||||||
FOwnsData := False;
|
Inc(i);
|
||||||
FReadOnly := AReadOnly;
|
end;
|
||||||
end;
|
|
||||||
|
{ TMulProvider }
|
||||||
constructor TMulProvider.Create(AData: string; AReadOnly: Boolean = False);
|
|
||||||
var
|
constructor TMulProvider.Create(AData: TStream; AReadOnly: Boolean = False);
|
||||||
mode: Word;
|
begin
|
||||||
begin
|
Create;
|
||||||
Create;
|
FData := AData;
|
||||||
if AReadOnly then
|
FOwnsData := False;
|
||||||
mode := fmOpenRead or fmShareDenyWrite
|
FReadOnly := AReadOnly;
|
||||||
else
|
end;
|
||||||
mode := fmOpenReadWrite or fmShareDenyWrite;
|
|
||||||
FData := TFileStream.Create(AData, mode);
|
constructor TMulProvider.Create(AData: string; AReadOnly: Boolean = False);
|
||||||
FOwnsData := True;
|
var
|
||||||
FReadOnly := AReadOnly;
|
mode: Word;
|
||||||
end;
|
begin
|
||||||
|
Create;
|
||||||
constructor TMulProvider.Create;
|
if AReadOnly then
|
||||||
begin
|
mode := fmOpenRead or fmShareDenyWrite
|
||||||
inherited;
|
else
|
||||||
FChangeEvents := TMulEventHandler.Create;
|
mode := fmOpenReadWrite or fmShareDenyWrite;
|
||||||
FFinishedEvents := TMulEventHandler.Create;
|
FData := TFileStream.Create(AData, mode);
|
||||||
end;
|
FOwnsData := True;
|
||||||
|
FReadOnly := AReadOnly;
|
||||||
destructor TMulProvider.Destroy;
|
end;
|
||||||
begin
|
|
||||||
if FOwnsData and Assigned(FData) then FreeAndNil(FData);
|
constructor TMulProvider.Create;
|
||||||
if Assigned(FChangeEvents) then FreeAndNil(FChangeEvents);
|
begin
|
||||||
if Assigned(FFinishedEvents) then FreeAndNil(FFinishedEvents);
|
inherited;
|
||||||
inherited;
|
FChangeEvents := TMulEventHandler.Create;
|
||||||
end;
|
FFinishedEvents := TMulEventHandler.Create;
|
||||||
|
end;
|
||||||
function TMulProvider.GetBlock(AID: Integer): TMulBlock;
|
|
||||||
begin
|
destructor TMulProvider.Destroy;
|
||||||
Result := GetData(AID, CalculateOffset(AID));
|
begin
|
||||||
Result.OnChanged := @OnChanged;
|
if FOwnsData and Assigned(FData) then FreeAndNil(FData);
|
||||||
Result.OnFinished := @OnFinished;
|
if Assigned(FChangeEvents) then FreeAndNil(FChangeEvents);
|
||||||
end;
|
if Assigned(FFinishedEvents) then FreeAndNil(FFinishedEvents);
|
||||||
|
inherited;
|
||||||
procedure TMulProvider.OnChanged(ABlock: TMulBlock);
|
end;
|
||||||
begin
|
|
||||||
SetBlock(ABlock.ID, ABlock);
|
function TMulProvider.GetBlock(AID: Integer): TMulBlock;
|
||||||
FChangeEvents.FireEvents(ABlock);
|
begin
|
||||||
end;
|
Result := GetData(AID, CalculateOffset(AID));
|
||||||
|
Result.OnChanged := @OnChanged;
|
||||||
procedure TMulProvider.OnFinished(ABlock: TMulBlock);
|
Result.OnFinished := @OnFinished;
|
||||||
begin
|
end;
|
||||||
FFinishedEvents.FireEvents(ABlock);
|
|
||||||
ABlock.Free;
|
procedure TMulProvider.OnChanged(ABlock: TMulBlock);
|
||||||
end;
|
begin
|
||||||
|
SetBlock(ABlock.ID, ABlock);
|
||||||
procedure TMulProvider.RegisterOnChangeEvent(AEvent: TMulBlockChanged);
|
FChangeEvents.FireEvents(ABlock);
|
||||||
begin
|
end;
|
||||||
FChangeEvents.RegisterEvent(AEvent);
|
|
||||||
end;
|
procedure TMulProvider.OnFinished(ABlock: TMulBlock);
|
||||||
|
begin
|
||||||
procedure TMulProvider.RegisterOnFinishedEvent(AEvent: TMulBlockChanged);
|
FFinishedEvents.FireEvents(ABlock);
|
||||||
begin
|
ABlock.Free;
|
||||||
FFinishedEvents.RegisterEvent(AEvent);
|
end;
|
||||||
end;
|
|
||||||
|
procedure TMulProvider.RegisterOnChangeEvent(AEvent: TMulBlockChanged);
|
||||||
procedure TMulProvider.SetBlock(AID: Integer; ABlock: TMulBlock);
|
begin
|
||||||
begin
|
FChangeEvents.RegisterEvent(AEvent);
|
||||||
if FReadOnly then Exit;
|
end;
|
||||||
SetData(AID, CalculateOffset(AID), ABlock);
|
|
||||||
end;
|
procedure TMulProvider.RegisterOnFinishedEvent(AEvent: TMulBlockChanged);
|
||||||
|
begin
|
||||||
procedure TMulProvider.SetData(AID, AOffset: Integer; ABlock: TMulBlock);
|
FFinishedEvents.RegisterEvent(AEvent);
|
||||||
begin
|
end;
|
||||||
if FReadOnly then Exit;
|
|
||||||
FData.Position := AOffset;
|
procedure TMulProvider.SetBlock(AID: Integer; ABlock: TMulBlock);
|
||||||
ABlock.Write(FData);
|
begin
|
||||||
end;
|
if FReadOnly then Exit;
|
||||||
|
SetData(AID, CalculateOffset(AID), ABlock);
|
||||||
procedure TMulProvider.UnregisterOnChangeEvent(AEvent: TMulBlockChanged);
|
end;
|
||||||
begin
|
|
||||||
FChangeEvents.UnregisterEvent(AEvent);
|
procedure TMulProvider.SetData(AID, AOffset: Integer; ABlock: TMulBlock);
|
||||||
end;
|
begin
|
||||||
|
if FReadOnly then Exit;
|
||||||
procedure TMulProvider.UnregisterOnFinishedEvent(AEvent: TMulBlockChanged);
|
FData.Position := AOffset;
|
||||||
begin
|
ABlock.Write(FData);
|
||||||
FFinishedEvents.UnregisterEvent(AEvent);
|
end;
|
||||||
end;
|
|
||||||
|
procedure TMulProvider.UnregisterOnChangeEvent(AEvent: TMulBlockChanged);
|
||||||
{ TIndexedMulProvider }
|
begin
|
||||||
|
FChangeEvents.UnregisterEvent(AEvent);
|
||||||
function TIndexedMulProvider.CalculateIndexOffset(AID: Integer): Integer;
|
end;
|
||||||
begin
|
|
||||||
Result := 12 * AID;
|
procedure TMulProvider.UnregisterOnFinishedEvent(AEvent: TMulBlockChanged);
|
||||||
end;
|
begin
|
||||||
|
FFinishedEvents.UnregisterEvent(AEvent);
|
||||||
constructor TIndexedMulProvider.Create(AData, AIndex: TStream; AReadOnly: Boolean = False);
|
end;
|
||||||
begin
|
|
||||||
inherited Create(AData, AReadOnly);
|
{ TIndexedMulProvider }
|
||||||
FIndex := TBufferedReader.Create(AIndex);
|
|
||||||
end;
|
function TIndexedMulProvider.CalculateIndexOffset(AID: Integer): Integer;
|
||||||
|
begin
|
||||||
constructor TIndexedMulProvider.Create(AData, AIndex: string; AReadOnly: Boolean = False);
|
Result := 12 * AID;
|
||||||
var
|
end;
|
||||||
mode: Word;
|
|
||||||
begin
|
constructor TIndexedMulProvider.Create(AData, AIndex: TStream; AReadOnly: Boolean = False);
|
||||||
inherited Create(AData, AReadOnly);
|
begin
|
||||||
if AReadOnly then
|
inherited Create(AData, AReadOnly);
|
||||||
mode := fmOpenRead or fmShareDenyWrite
|
FIndex := TBufferedReader.Create(AIndex);
|
||||||
else
|
end;
|
||||||
mode := fmOpenReadWrite or fmShareDenyWrite;
|
|
||||||
FIndex := TBufferedReader.Create(TFileStream.Create(AIndex, mode), True);
|
constructor TIndexedMulProvider.Create(AData, AIndex: string; AReadOnly: Boolean = False);
|
||||||
end;
|
var
|
||||||
|
mode: Word;
|
||||||
procedure TIndexedMulProvider.Defragment(ATempStream: TStream; AOnProgress: TOnProgressEvent = nil);
|
begin
|
||||||
var
|
inherited Create(AData, AReadOnly);
|
||||||
genericIndex: TGenericIndex;
|
if AReadOnly then
|
||||||
begin
|
mode := fmOpenRead or fmShareDenyWrite
|
||||||
if FReadOnly then Exit;
|
else
|
||||||
ATempStream.Size := FData.Size;
|
mode := fmOpenReadWrite or fmShareDenyWrite;
|
||||||
ATempStream.Position := 0;
|
FIndex := TBufferedReader.Create(TFileStream.Create(AIndex, mode), True);
|
||||||
FIndex.Position := 0;
|
end;
|
||||||
while FIndex.Position < FIndex.Size do
|
|
||||||
begin
|
procedure TIndexedMulProvider.Defragment(ATempStream: TStream; AOnProgress: TOnProgressEvent = nil);
|
||||||
genericIndex := TGenericIndex.Create(FIndex);
|
var
|
||||||
if genericIndex.Lookup <> LongInt($FFFFFFFF) then
|
genericIndex: TGenericIndex;
|
||||||
begin
|
begin
|
||||||
FData.Position := genericIndex.Lookup;
|
if FReadOnly then Exit;
|
||||||
genericIndex.Lookup := ATempStream.Position;
|
ATempStream.Size := FData.Size;
|
||||||
ATempStream.CopyFrom(FData, genericIndex.Size);
|
ATempStream.Position := 0;
|
||||||
FIndex.Seek(-12, soFromCurrent);
|
FIndex.Position := 0;
|
||||||
genericIndex.Write(FIndex);
|
while FIndex.Position < FIndex.Size do
|
||||||
end;
|
begin
|
||||||
genericIndex.Free;
|
genericIndex := TGenericIndex.Create(FIndex);
|
||||||
if Assigned(AOnProgress) and (FIndex.Position mod 1200 = 0) then
|
if genericIndex.Lookup <> LongInt($FFFFFFFF) then
|
||||||
AOnProgress(FIndex.Size, FIndex.Position);
|
begin
|
||||||
end;
|
FData.Position := genericIndex.Lookup;
|
||||||
FData.Size := ATempStream.Position;
|
genericIndex.Lookup := ATempStream.Position;
|
||||||
FData.Position := 0;
|
ATempStream.CopyFrom(FData, genericIndex.Size);
|
||||||
ATempStream.Position := 0;
|
FIndex.Seek(-12, soFromCurrent);
|
||||||
FData.CopyFrom(ATempStream, FData.Size);
|
genericIndex.Write(FIndex);
|
||||||
end;
|
end;
|
||||||
|
genericIndex.Free;
|
||||||
destructor TIndexedMulProvider.Destroy;
|
if Assigned(AOnProgress) and (FIndex.Position mod 1200 = 0) then
|
||||||
begin
|
AOnProgress(FIndex.Size, FIndex.Position);
|
||||||
if Assigned(FIndex) then FreeAndNil(FIndex);
|
end;
|
||||||
inherited;
|
FData.Size := ATempStream.Position;
|
||||||
end;
|
FData.Position := 0;
|
||||||
|
ATempStream.Position := 0;
|
||||||
function TIndexedMulProvider.Exists(AID: Integer): Boolean;
|
FData.CopyFrom(ATempStream, FData.Size);
|
||||||
var
|
end;
|
||||||
genericIndex: TGenericIndex;
|
|
||||||
begin
|
destructor TIndexedMulProvider.Destroy;
|
||||||
FIndex.Position := CalculateIndexOffset(AID);
|
begin
|
||||||
genericIndex := TGenericIndex.Create(FIndex);
|
if Assigned(FIndex) then FreeAndNil(FIndex);
|
||||||
Result := genericIndex.Lookup <> LongInt($FFFFFFFF);
|
inherited;
|
||||||
genericIndex.Free;
|
end;
|
||||||
end;
|
|
||||||
|
function TIndexedMulProvider.Exists(AID: Integer): Boolean;
|
||||||
function TIndexedMulProvider.GetBlock(AID: Integer): TMulBlock;
|
var
|
||||||
var
|
genericIndex: TGenericIndex;
|
||||||
genericIndex: TGenericIndex;
|
begin
|
||||||
begin
|
FIndex.Position := CalculateIndexOffset(AID);
|
||||||
GetBlockEx(AID, Result, genericIndex);
|
genericIndex := TGenericIndex.Create(FIndex);
|
||||||
genericIndex.Free;
|
Result := (genericIndex.Lookup > -1) and (genericIndex.Size > 0);
|
||||||
end;
|
genericIndex.Free;
|
||||||
|
end;
|
||||||
procedure TIndexedMulProvider.GetBlockEx(AID: Integer;
|
|
||||||
var ABlock: TMulBlock; var AIndex: TGenericIndex);
|
function TIndexedMulProvider.GetBlock(AID: Integer): TMulBlock;
|
||||||
begin
|
var
|
||||||
FIndex.Position := CalculateIndexOffset(AID);
|
genericIndex: TGenericIndex;
|
||||||
AIndex := TGenericIndex.Create(FIndex);
|
begin
|
||||||
ABlock := GetData(AID, AIndex);
|
GetBlockEx(AID, Result, genericIndex);
|
||||||
ABlock.OnChanged := @OnChanged;
|
genericIndex.Free;
|
||||||
ABlock.OnFinished := @OnFinished;
|
end;
|
||||||
end;
|
|
||||||
|
procedure TIndexedMulProvider.GetBlockEx(AID: Integer;
|
||||||
function TIndexedMulProvider.GetVarious(AID: Integer; ABlock: TMulBlock;
|
var ABlock: TMulBlock; var AIndex: TGenericIndex);
|
||||||
ADefault: Integer): Integer;
|
begin
|
||||||
begin
|
FIndex.Position := CalculateIndexOffset(AID);
|
||||||
Result := ADefault;
|
AIndex := TGenericIndex.Create(FIndex);
|
||||||
end;
|
ABlock := GetData(AID, AIndex);
|
||||||
|
ABlock.OnChanged := @OnChanged;
|
||||||
procedure TIndexedMulProvider.SetBlock(AID: Integer; ABlock: TMulBlock);
|
ABlock.OnFinished := @OnFinished;
|
||||||
var
|
end;
|
||||||
genericIndex: TGenericIndex;
|
|
||||||
begin
|
function TIndexedMulProvider.GetVarious(AID: Integer; ABlock: TMulBlock;
|
||||||
if FReadOnly then Exit;
|
ADefault: Integer): Integer;
|
||||||
FIndex.Position := CalculateIndexOffset(AID);
|
begin
|
||||||
genericIndex := TGenericIndex.Create(FIndex);
|
Result := ADefault;
|
||||||
SetData(AID, genericIndex, ABlock);
|
end;
|
||||||
FIndex.Position := CalculateIndexOffset(AID);
|
|
||||||
genericIndex.Various := GetVarious(AID, ABlock, genericIndex.Various);
|
procedure TIndexedMulProvider.SetBlock(AID: Integer; ABlock: TMulBlock);
|
||||||
genericIndex.Write(FIndex);
|
var
|
||||||
genericIndex.Free;
|
genericIndex: TGenericIndex;
|
||||||
end;
|
begin
|
||||||
|
if FReadOnly then Exit;
|
||||||
procedure TIndexedMulProvider.SetData(AID: Integer; AIndex: TGenericIndex;
|
FIndex.Position := CalculateIndexOffset(AID);
|
||||||
ABlock: TMulBlock);
|
genericIndex := TGenericIndex.Create(FIndex);
|
||||||
var
|
SetData(AID, genericIndex, ABlock);
|
||||||
size: Integer;
|
FIndex.Position := CalculateIndexOffset(AID);
|
||||||
begin
|
genericIndex.Various := GetVarious(AID, ABlock, genericIndex.Various);
|
||||||
if FReadOnly then Exit;
|
genericIndex.Write(FIndex);
|
||||||
size := ABlock.GetSize;
|
genericIndex.Free;
|
||||||
if size = 0 then
|
end;
|
||||||
begin
|
|
||||||
AIndex.Lookup := LongInt($FFFFFFFF);
|
procedure TIndexedMulProvider.SetData(AID: Integer; AIndex: TGenericIndex;
|
||||||
AIndex.Various := LongInt($FFFFFFFF);
|
ABlock: TMulBlock);
|
||||||
end else if (size > AIndex.Size) or (AIndex.Lookup = LongInt($FFFFFFFF)) then
|
var
|
||||||
begin
|
size: Integer;
|
||||||
FData.Position := FData.Size;
|
begin
|
||||||
AIndex.Lookup := FData.Position;
|
if FReadOnly then Exit;
|
||||||
ABlock.Write(FData);
|
size := ABlock.GetSize;
|
||||||
end else
|
if size = 0 then
|
||||||
begin
|
begin
|
||||||
FData.Position := AIndex.Lookup;
|
AIndex.Lookup := LongInt($FFFFFFFF);
|
||||||
ABlock.Write(FData);
|
AIndex.Various := LongInt($FFFFFFFF);
|
||||||
end;
|
end else if (size > AIndex.Size) or (AIndex.Lookup = LongInt($FFFFFFFF)) then
|
||||||
AIndex.Size := size;
|
begin
|
||||||
end;
|
FData.Position := FData.Size;
|
||||||
|
AIndex.Lookup := FData.Position;
|
||||||
end.
|
ABlock.Write(FData);
|
||||||
|
end else
|
||||||
|
begin
|
||||||
|
FData.Position := AIndex.Lookup;
|
||||||
|
ABlock.Write(FData);
|
||||||
|
end;
|
||||||
|
AIndex.Size := size;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
|
@ -1,56 +1,56 @@
|
||||||
(*
|
(*
|
||||||
* CDDL HEADER START
|
* CDDL HEADER START
|
||||||
*
|
*
|
||||||
* The contents of this file are subject to the terms of the
|
* The contents of this file are subject to the terms of the
|
||||||
* Common Development and Distribution License, Version 1.0 only
|
* Common Development and Distribution License, Version 1.0 only
|
||||||
* (the "License"). You may not use this file except in compliance
|
* (the "License"). You may not use this file except in compliance
|
||||||
* with the License.
|
* with the License.
|
||||||
*
|
*
|
||||||
* You can obtain a copy of the license at
|
* You can obtain a copy of the license at
|
||||||
* http://www.opensource.org/licenses/cddl1.php.
|
* http://www.opensource.org/licenses/cddl1.php.
|
||||||
* See the License for the specific language governing permissions
|
* See the License for the specific language governing permissions
|
||||||
* and limitations under the License.
|
* and limitations under the License.
|
||||||
*
|
*
|
||||||
* When distributing Covered Code, include this CDDL HEADER in each
|
* When distributing Covered Code, include this CDDL HEADER in each
|
||||||
* file and include the License file at
|
* file and include the License file at
|
||||||
* http://www.opensource.org/licenses/cddl1.php. If applicable,
|
* http://www.opensource.org/licenses/cddl1.php. If applicable,
|
||||||
* add the following below this CDDL HEADER, with the fields enclosed
|
* add the following below this CDDL HEADER, with the fields enclosed
|
||||||
* by brackets "[]" replaced with your own identifying * information:
|
* by brackets "[]" replaced with your own identifying * information:
|
||||||
* Portions Copyright [yyyy] [name of copyright owner]
|
* Portions Copyright [yyyy] [name of copyright owner]
|
||||||
*
|
*
|
||||||
* CDDL HEADER END
|
* CDDL HEADER END
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Portions Copyright 2007 Andreas Schneider
|
* Portions Copyright 2009 Andreas Schneider
|
||||||
*)
|
*)
|
||||||
unit UTexmapProvider;
|
unit UTexmapProvider;
|
||||||
|
|
||||||
{$mode objfpc}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
UMulProvider, UMulBlock, UGenericIndex, UTexture;
|
UMulProvider, UMulBlock, UGenericIndex, UTexture;
|
||||||
|
|
||||||
type
|
type
|
||||||
TTexmapProvider = class(TIndexedMulProvider)
|
TTexmapProvider = class(TIndexedMulProvider)
|
||||||
protected
|
protected
|
||||||
function GetData(AID: Integer; AIndex: TGenericIndex): TMulBlock; override;
|
function GetData(AID: Integer; AIndex: TGenericIndex): TMulBlock; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
{ TTexmapProvider }
|
{ TTexmapProvider }
|
||||||
|
|
||||||
function TTexmapProvider.GetData(AID: Integer; AIndex: TGenericIndex): TMulBlock;
|
function TTexmapProvider.GetData(AID: Integer; AIndex: TGenericIndex): TMulBlock;
|
||||||
begin
|
begin
|
||||||
if AIndex.Lookup <> LongInt($FFFFFFFF) then
|
if (AIndex.Lookup > -1) and (AIndex.Size > 0) then
|
||||||
Result := TTexture.Create(FData, AIndex)
|
Result := TTexture.Create(FData, AIndex)
|
||||||
else
|
else
|
||||||
Result := TTexture.Create(-1);
|
Result := TTexture.Create(-1);
|
||||||
Result.ID := AID;
|
Result.ID := AID;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue