- 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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user