From 5049955303dc4c585bcafffc7c2cc2334bd93612 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 21 Dec 2009 00:13:26 +0100 Subject: [PATCH] - Added light loading - Use lights for the light sources --- Client/CentrED.lpi | 12 +- Client/CentrED.lpr | 2 +- Client/UGameResources.pas | 245 +++++++++++++++++---------------- Client/ULightManager.pas | 163 ++++++++++++++++++---- Client/UfrmMain.pas | 18 +-- MulProvider/UArtProvider.pas | 198 +++++++++++++------------- MulProvider/ULightProvider.pas | 62 +++++++++ UOLib/ULight.pas | 121 ++++++++++++++++ 8 files changed, 564 insertions(+), 257 deletions(-) create mode 100644 MulProvider/ULightProvider.pas create mode 100644 UOLib/ULight.pas diff --git a/Client/CentrED.lpi b/Client/CentrED.lpi index a256838..5c1612f 100644 --- a/Client/CentrED.lpi +++ b/Client/CentrED.lpi @@ -55,7 +55,7 @@ - + @@ -309,6 +309,16 @@ + + + + + + + + + + diff --git a/Client/CentrED.lpr b/Client/CentrED.lpr index cf861ef..ab2b16e 100644 --- a/Client/CentrED.lpr +++ b/Client/CentrED.lpr @@ -43,7 +43,7 @@ uses UPacketHandlers, UAdminHandling, UGameResources, ULandscape, UfrmToolWindow, Logging, UTileDataProvider, UMap, UWorldItem, UStatics, UTiledata, UAnimData, UGLFont, UAnimDataProvider, UMulManager, UArtProvider, UTexmapProvider, -ULightManager; +ULightManager, ULight, ULightProvider; {$IFDEF WINDOWS}{$R CentrED.rc}{$ENDIF} diff --git a/Client/UGameResources.pas b/Client/UGameResources.pas index 50c3cfd..f5302d8 100644 --- a/Client/UGameResources.pas +++ b/Client/UGameResources.pas @@ -1,120 +1,125 @@ -(* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at - * http://www.opensource.org/licenses/cddl1.php. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at - * http://www.opensource.org/licenses/cddl1.php. If applicable, - * add the following below this CDDL HEADER, with the fields enclosed - * by brackets "[]" replaced with your own identifying * information: - * Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * - * Portions Copyright 2009 Andreas Schneider - *) -unit UGameResources; - -{$mode objfpc}{$H+} - -interface - -uses - Classes, SysUtils, UArtProvider, UTileDataProvider, UTexmapProvider, - ULandscape, UHueProvider, UAnimDataProvider; - -type - - { TGameResourceManager } - - TGameResourceManager = class - constructor Create(ADataDir: string); - destructor Destroy; override; - protected - { Members } - FDataDir: string; - FArtProvider: TArtProvider; - FTiledataProvider: TTiledataProvider; - FAnimdataProvider: TAnimdataProvider; - FTexmapProvider: TTexmapProvider; - FHueProvider: THueProvider; - FLandscape: TLandscape; - public - { Fields } - property Art: TArtProvider read FArtProvider; - property Hue: THueProvider read FHueProvider; - property Landscape: TLandscape read FLandscape; - property Tiledata: TTiledataProvider read FTiledataProvider; - property Animdata: TAnimDataProvider read FAnimdataProvider; - property Texmaps: TTexmapProvider read FTexmapProvider; - - { Methods } - function GetFile(AFileName: string): string; - procedure InitLandscape(AWidth, AHeight: Word); - end; - -var - GameResourceManager: TGameResourceManager; - ResMan: TGameResourceManager absolute GameResourceManager; - -procedure InitGameResourceManager(ADataDir: string); - -implementation - -procedure InitGameResourceManager(ADataDir: string); -begin - FreeAndNil(GameResourceManager); - GameResourceManager := TGameResourceManager.Create(ADataDir); -end; - -{ TGameResourceManager } - -constructor TGameResourceManager.Create(ADataDir: string); -begin - inherited Create; - FDataDir := IncludeTrailingPathDelimiter(ADataDir); - - FArtProvider := TArtProvider.Create(GetFile('art.mul'), GetFile('artidx.mul'), True); - FTiledataProvider := TTiledataProvider.Create(GetFile('tiledata.mul'), True); - FAnimdataProvider := TAnimDataProvider.Create(GetFile('animdata.mul'), True); - FTexmapProvider := TTexmapProvider.Create(GetFile('texmaps.mul'), GetFile('texidx.mul'), True); - FHueProvider := THueProvider.Create(GetFile('hues.mul'), True); -end; - -destructor TGameResourceManager.Destroy; -begin - FreeAndNil(FArtProvider); - FreeAndNil(FTiledataProvider); - FreeAndNil(FAnimdataProvider); - FreeAndNil(FTexmapProvider); - FreeAndNil(FHueProvider); - FreeAndNil(FLandscape); - inherited Destroy; -end; - -function TGameResourceManager.GetFile(AFileName: string): string; -begin - Result := FDataDir + AFileName; -end; - -procedure TGameResourceManager.InitLandscape(AWidth, AHeight: Word); -begin - FreeAndNil(FLandscape); - FLandscape := TLandscape.Create(AWidth, AHeight); -end; - -finalization - FreeAndNil(GameResourceManager); - -end. - +(* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at + * http://www.opensource.org/licenses/cddl1.php. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at + * http://www.opensource.org/licenses/cddl1.php. If applicable, + * add the following below this CDDL HEADER, with the fields enclosed + * by brackets "[]" replaced with your own identifying * information: + * Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * + * Portions Copyright 2009 Andreas Schneider + *) +unit UGameResources; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, UArtProvider, UTileDataProvider, UTexmapProvider, + ULandscape, UHueProvider, UAnimDataProvider, ULightProvider; + +type + + { TGameResourceManager } + + TGameResourceManager = class + constructor Create(ADataDir: String); + destructor Destroy; override; + protected + { Members } + FDataDir: String; + FArtProvider: TArtProvider; + FTiledataProvider: TTiledataProvider; + FAnimdataProvider: TAnimdataProvider; + FTexmapProvider: TTexmapProvider; + FHueProvider: THueProvider; + FLightProvider: TLightProvider; + FLandscape: TLandscape; + public + { Fields } + property Art: TArtProvider read FArtProvider; + property Hue: THueProvider read FHueProvider; + property Landscape: TLandscape read FLandscape; + property Tiledata: TTiledataProvider read FTiledataProvider; + property Animdata: TAnimDataProvider read FAnimdataProvider; + property Texmaps: TTexmapProvider read FTexmapProvider; + property Lights: TLightProvider read FLightProvider; + + { Methods } + function GetFile(AFileName: String): String; + procedure InitLandscape(AWidth, AHeight: Word); + end; + +var + GameResourceManager: TGameResourceManager; + ResMan: TGameResourceManager absolute GameResourceManager; + +procedure InitGameResourceManager(ADataDir: String); + +implementation + +procedure InitGameResourceManager(ADataDir: String); +begin + FreeAndNil(GameResourceManager); + GameResourceManager := TGameResourceManager.Create(ADataDir); +end; + +{ TGameResourceManager } + +constructor TGameResourceManager.Create(ADataDir: String); +begin + inherited Create; + FDataDir := IncludeTrailingPathDelimiter(ADataDir); + + FArtProvider := TArtProvider.Create(GetFile('art.mul'), GetFile('artidx.mul'), True); + FTiledataProvider := TTiledataProvider.Create(GetFile('tiledata.mul'), True); + FAnimdataProvider := TAnimDataProvider.Create(GetFile('animdata.mul'), True); + FTexmapProvider := TTexmapProvider.Create(GetFile('texmaps.mul'), + GetFile('texidx.mul'), True); + FHueProvider := THueProvider.Create(GetFile('hues.mul'), True); + FLightProvider := TLightProvider.Create(GetFile('light.mul'), + GetFile('lightidx.mul'), True); +end; + +destructor TGameResourceManager.Destroy; +begin + FreeAndNil(FArtProvider); + FreeAndNil(FTiledataProvider); + FreeAndNil(FAnimdataProvider); + FreeAndNil(FTexmapProvider); + FreeAndNil(FHueProvider); + FreeAndNil(FLightProvider); + FreeAndNil(FLandscape); + inherited Destroy; +end; + +function TGameResourceManager.GetFile(AFileName: String): String; +begin + Result := FDataDir + AFileName; +end; + +procedure TGameResourceManager.InitLandscape(AWidth, AHeight: Word); +begin + FreeAndNil(FLandscape); + FLandscape := TLandscape.Create(AWidth, AHeight); +end; + +finalization + FreeAndNil(GameResourceManager); + +end. diff --git a/Client/ULightManager.pas b/Client/ULightManager.pas index 231c979..aed5884 100644 --- a/Client/ULightManager.pas +++ b/Client/ULightManager.pas @@ -31,25 +31,51 @@ interface uses Classes, SysUtils, Imaging, ImagingTypes, ImagingClasses, ImagingCanvases, - ImagingOpenGL, GL, fgl, ULandscape, UWorldItem; + ImagingOpenGL, GL, fgl, ULandscape, UWorldItem, UCacheManager; type - TCalculateOffset = procedure(ARelativeX, ARelativeY: Integer; out DrawX, - DrawY: Integer) of object; + TCalculateOffset = procedure(AX, AY: Integer; out DrawX, DrawY: Integer) of object; + + { TLightMaterial } + + TLightMaterial = class(ICacheable) + constructor Create(AGraphic: TBaseImage); + destructor Destroy; override; + protected + FRefCount: Integer; + FGraphic: TSingleImage; + FCanvas: TFastARGB32Canvas; + public + property Graphic: TSingleImage read FGraphic; + property Canvas: TFastARGB32Canvas read FCanvas; + procedure AddRef; + procedure DelRef; + + {ICacheable} + function CanBeRemoved: Boolean; + procedure RemoveFromCache; + end; + + TLightCache = specialize TCacheManager; + + TLightManager = class; { TLightSource } TLightSource = class - constructor Create(AWorldItem: TWorldItem); + constructor Create(AManager: TLightManager; AWorldItem: TWorldItem); + destructor Destroy; override; protected FX: Integer; FY: Integer; FZ: smallint; + FMaterial: TLightMaterial; public property X: Integer read FX; property Y: Integer read FY; property Z: smallint read FZ; + property Material: TLightMaterial read FMaterial; end; TLightSources = specialize TFPGObjectList; @@ -57,7 +83,8 @@ type { TLightManager } TLightManager = class - constructor Create(ACalculateOffset: TCalculateOffset); + constructor Create(ACalculateOffset: TCalculateOffset; + ALandTextureManager: TLandTextureManager); destructor Destroy; override; protected FLightSources: TLightSources; @@ -66,40 +93,65 @@ type FLightLevel: byte; FValid: Boolean; FCalculateOffset: TCalculateOffset; - procedure UpdateOverlay(AScreenRect: TRect; FX, FY: Integer); + FLightCache: TLightCache; + FLandTextureManager: TLandTextureManager; + function GetLight(AID: Integer): TLightMaterial; + procedure UpdateOverlay(AScreenRect: TRect); public procedure UpdateLightMap(ALeft, AWidth, ATop, AHeight: Integer; AScreenBuffer: TScreenBuffer); - procedure Draw(AScreenRect: TRect; FX, FY: Integer); + procedure Draw(AScreenRect: TRect); end; implementation uses - UGameResources, UTiledata, UStatics, Logging; + UGameResources, UTiledata, UStatics, ULight, Logging; { TLightManager } -constructor TLightManager.Create(ACalculateOffset: TCalculateOffset); +constructor TLightManager.Create(ACalculateOffset: TCalculateOffset; + ALandTextureManager: TLandTextureManager); begin FCalculateOffset := ACalculateOffset; FLightSources := TLightSources.Create(True); FLightLevel := 15; //TODO : 0 ... + FLightCache := TLightCache.Create(32); + FLandTextureManager := ALandTextureManager; end; destructor TLightManager.Destroy; begin FreeAndNil(FLightSources); FreeAndNil(FOverlay); + FreeAndNil(FLightCache); glDeleteTextures(1, @FOverlayTexture); inherited Destroy; end; -procedure TLightManager.UpdateOverlay(AScreenRect: TRect; FX, FY: Integer); +function TLightManager.GetLight(AID: Integer): TLightMaterial; var - canvas: TFastARGB32Canvas; + light: TLight; +begin + Result := nil; + if not FLightCache.QueryID(AID, Result) then + begin + if ResMan.Lights.Exists(AID) then + begin + light := ResMan.Lights.GetLight(AID); + Result := TLightMaterial.Create(light.Graphic); + FLightCache.StoreID(AID, Result); + light.Free; + end; + end; +end; + +procedure TLightManager.UpdateOverlay(AScreenRect: TRect); +var + canvas, lightCanvas: TFastARGB32Canvas; color: TColor32Rec; - i, drawX, drawY, drawZ: Integer; + i: Integer; + lightMaterial: TLightMaterial; begin FOverlay.Free; glDeleteTextures(1, @FOverlayTexture); @@ -121,16 +173,13 @@ begin for i := 0 to FLightSources.Count - 1 do begin - FCalculateOffset(FLightSources[i].X - FX, FLightSources[i].Y - FY, - drawX, drawY); - drawZ := FLightSources[i].Z * 4; - color.A := $20; - color.R := 220; - color.G := 0; - color.B := 0; - canvas.FillColor32 := color.Color; - canvas.FillRectBlend(Rect(drawX - 22, drawY - drawZ, drawX + 22, - drawY + 44 - drawZ), bfOne, bfOne); + lightMaterial := FLightSources[i].Material; + if lightMaterial <> nil then + begin + lightMaterial.Canvas.DrawAdd(lightMaterial.Canvas.ClipRect, canvas, + FLightSources[i].FX - lightMaterial.Graphic.Width div 2, + FLightSources[i].FY - lightMaterial.Graphic.Height div 2); + end; end; //TODO : PowerOfTwo!!! @@ -182,17 +231,17 @@ begin ((itemMap[x + 1, y + 1] = nil) or (itemMap[x + 1, y + 1].Z < lightMap[x, y].Z + 3)) or ((itemMap[x, y + 1] = nil) or (itemMap[x, y + 1].Z < lightMap[x, y].Z + 3)) then begin - FLightSources.Add(TLightSource.Create(lightMap[x, y])); + FLightSources.Add(TLightSource.Create(Self, lightMap[x, y])); end; end; FValid := False; //Logger.ExitMethod([lcClient, lcDebug], 'UpdateLightMap'); end; -procedure TLightManager.Draw(AScreenRect: TRect; FX, FY: Integer); +procedure TLightManager.Draw(AScreenRect: TRect); begin if not FValid then - UpdateOverlay(AScreenRect, FX, FY); + UpdateOverlay(AScreenRect); glBindTexture(GL_TEXTURE_2D, FOverlayTexture); glBlendFunc(GL_ZERO, GL_SRC_COLOR); @@ -210,11 +259,67 @@ end; { TLightSource } -constructor TLightSource.Create(AWorldItem: TWorldItem); +constructor TLightSource.Create(AManager: TLightManager; AWorldItem: TWorldItem); +var + lightID: Byte; + itemMaterial: TMaterial; begin - FX := AWorldItem.X; - FY := AWorldItem.Y; - FZ := AWorldItem.Z; + lightID := ResMan.Tiledata.StaticTiles[AWorldItem.TileID].Quality; + FMaterial := AManager.GetLight(lightID); + if FMaterial <> nil then + begin + itemMaterial := AManager.FLandTextureManager.GetStaticMaterial( + TStaticItem(AWorldItem)); + AManager.FCalculateOffset(AWorldItem.X, AWorldItem.Y, FX, FY); + FZ := AWorldItem.Z * 4; + FY := FY + 44 - FZ - itemMaterial.RealHeight div 2; + FMaterial.AddRef; + end; +end; + +destructor TLightSource.Destroy; +begin + if FMaterial <> nil then + FMaterial.DelRef; + inherited Destroy; +end; + +{ TLightMaterial } + +constructor TLightMaterial.Create(AGraphic: TBaseImage); +begin + FRefCount := 1; + FGraphic := TSingleImage.CreateFromImage(AGraphic); + FCanvas := TFastARGB32Canvas.CreateForImage(FGraphic); +end; + +destructor TLightMaterial.Destroy; +begin + FreeAndNil(FCanvas); + FreeAndNil(FGraphic); + inherited Destroy; +end; + +procedure TLightMaterial.AddRef; +begin + Inc(FRefCount); +end; + +procedure TLightMaterial.DelRef; +begin + Dec(FRefCount); + if FRefCount < 1 then + Free; +end; + +function TLightMaterial.CanBeRemoved: Boolean; +begin + Result := (FRefCount <= 1); +end; + +procedure TLightMaterial.RemoveFromCache; +begin + DelRef; end; end. diff --git a/Client/UfrmMain.pas b/Client/UfrmMain.pas index f9d2bd4..12b3055 100644 --- a/Client/UfrmMain.pas +++ b/Client/UfrmMain.pas @@ -329,8 +329,7 @@ type function ConfirmAction: Boolean; function FindRandomPreset(AName: String): TDOMElement; procedure ForceUpdateCurrentTile; - procedure GetDrawOffset(ARelativeX, ARelativeY: Integer; out DrawX, - DrawY: Integer); inline; + procedure GetDrawOffset(AX, AY: Integer; out DrawX, DrawY: Integer); inline; function GetInternalTileID(ATile: TWorldItem): Word; function GetSelectedRect: TRect; procedure InitRender; @@ -893,7 +892,7 @@ begin edX.MaxValue := FLandscape.CellWidth; edY.MaxValue := FLandscape.CellHeight; FOverlayUI := TOverlayUI.Create; - FLightManager := TLightManager.Create(@GetDrawOffset); + FLightManager := TLightManager.Create(@GetDrawOffset, FTextureManager); ProcessAccessLevel; @@ -2161,7 +2160,7 @@ begin item := ABlockInfo^.Item; - GetDrawOffset(item.X - FX, item.Y - FY, drawX, drawY); + GetDrawOffset(item.X , item.Y, drawX, drawY); if acFlat.Checked then begin @@ -2390,7 +2389,7 @@ begin blockInfo^.Text.Render(blockInfo^.ScreenRect); end; - FLightManager.Draw(oglGameWindow.ClientRect, FX, FY); + FLightManager.Draw(oglGameWindow.ClientRect); FOverlayUI.Draw(oglGameWindow); end; @@ -3079,11 +3078,12 @@ begin UpdateCurrentTile; end; -procedure TfrmMain.GetDrawOffset(ARelativeX, ARelativeY: Integer; out DrawX, - DrawY: Integer); inline; +procedure TfrmMain.GetDrawOffset(AX, AY: Integer; out DrawX, DrawY: Integer); inline; begin - DrawX := (oglGameWindow.Width div 2) + (ARelativeX - ARelativeY) * 22; - DrawY := (oglGamewindow.Height div 2) + (ARelativeX + ARelativeY) * 22; + Dec(AX, FX); + Dec(AY, FY); + DrawX := (oglGameWindow.Width div 2) + (AX - AY) * 22; + DrawY := (oglGamewindow.Height div 2) + (AX + AY) * 22; end; initialization diff --git a/MulProvider/UArtProvider.pas b/MulProvider/UArtProvider.pas index 46e3353..b9449d1 100644 --- a/MulProvider/UArtProvider.pas +++ b/MulProvider/UArtProvider.pas @@ -1,97 +1,101 @@ -(* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at - * http://www.opensource.org/licenses/cddl1.php. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at - * http://www.opensource.org/licenses/cddl1.php. If applicable, - * add the following below this CDDL HEADER, with the fields enclosed - * by brackets "[]" replaced with your own identifying * information: - * Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - * - * - * Portions Copyright 2009 Andreas Schneider - *) -unit UArtProvider; - -{$mode objfpc}{$H+} - -interface - -uses - Graphics, UMulProvider, UMulBlock, UGenericIndex, UArt, UHue; - -type - TArtProvider = class(TIndexedMulProvider) - protected - function GetData(AID: Integer; AIndex: TGenericIndex): TMulBlock; override; - function GetArtData(AID: Integer; AIndex: TGenericIndex; AColor: Word; AHue: THue; APartialHue: Boolean): TArt; - public - function GetArt(AID: Integer; AColor: Word; AHue: THue; APartialHue: Boolean): TArt; - function GetFlatLand(AID: Integer): TArt; - end; - -implementation - -{ TArtProvider } - -function TArtProvider.GetData(AID: Integer; AIndex: TGenericIndex): TMulBlock; -begin - Result := GetArtData(AID, AIndex, clBlack, nil, False); -end; - -function TArtProvider.GetArtData(AID: Integer; AIndex: TGenericIndex; - AColor: Word; AHue: THue; APartialHue: Boolean): TArt; -begin - if (AIndex.Lookup > -1) and (AIndex.Size > 0) then - begin - if AID < $4000 then - Result := TArt.Create(FData, AIndex, atLand, AColor, AHue, APartialHue) - else - Result := TArt.Create(FData, AIndex, atStatic, AColor, AHue, APartialHue); - end else - begin - if AID < $4000 then - Result := TArt.Create(nil, nil, atLand, AColor, AHue, APartialHue) - else - Result := TArt.Create(nil, nil, atStatic, AColor, AHue, APartialHue); - end; - Result.ID := AID; -end; - -function TArtProvider.GetArt(AID: Integer; AColor: Word; AHue: THue; APartialHue: Boolean): TArt; -var - genericIndex: TGenericIndex; -begin - FIndex.Position := CalculateIndexOffset(AID); - genericIndex := TGenericIndex.Create(FIndex); - Result := GetArtData(AID, genericIndex, AColor, AHue, APartialHue); - genericIndex.Free; - Result.OnChanged := @OnChanged; - Result.OnFinished := @OnFinished; -end; - -function TArtProvider.GetFlatLand(AID: Integer): TArt; -var - genericIndex: TGenericIndex; -begin - FIndex.Position := CalculateIndexOffset(AID); - genericIndex := TGenericIndex.Create(FIndex); - Result := TArt.Create(FData, genericIndex, atLandFlat); - genericIndex.Free; - Result.OnChanged := @OnChanged; - Result.OnFinished := @OnFinished; -end; - -end. +(* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at + * http://www.opensource.org/licenses/cddl1.php. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at + * http://www.opensource.org/licenses/cddl1.php. If applicable, + * add the following below this CDDL HEADER, with the fields enclosed + * by brackets "[]" replaced with your own identifying * information: + * Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * + * Portions Copyright 2009 Andreas Schneider + *) +unit UArtProvider; + +{$mode objfpc}{$H+} + +interface + +uses + Graphics, UMulProvider, UMulBlock, UGenericIndex, UArt, UHue; + +type + TArtProvider = class(TIndexedMulProvider) + protected + function GetData(AID: Integer; AIndex: TGenericIndex): TMulBlock; override; + function GetArtData(AID: Integer; AIndex: TGenericIndex; AColor: Word; + AHue: THue; APartialHue: Boolean): TArt; + public + function GetArt(AID: Integer; AColor: Word; AHue: THue; APartialHue: Boolean): TArt; + function GetFlatLand(AID: Integer): TArt; + end; + +implementation + +{ TArtProvider } + +function TArtProvider.GetData(AID: Integer; AIndex: TGenericIndex): TMulBlock; +begin + Result := GetArtData(AID, AIndex, clBlack, nil, False); +end; + +function TArtProvider.GetArtData(AID: Integer; AIndex: TGenericIndex; + AColor: Word; AHue: THue; APartialHue: Boolean): TArt; +begin + if (AIndex.Lookup > -1) and (AIndex.Size > 0) then + begin + if AID < $4000 then + Result := TArt.Create(FData, AIndex, atLand, AColor, AHue, APartialHue) + else + Result := TArt.Create(FData, AIndex, atStatic, AColor, AHue, APartialHue); + end + else + begin + if AID < $4000 then + Result := TArt.Create(nil, nil, atLand, AColor, AHue, APartialHue) + else + Result := TArt.Create(nil, nil, atStatic, AColor, AHue, APartialHue); + end; + Result.ID := AID; +end; + +function TArtProvider.GetArt(AID: Integer; AColor: Word; AHue: THue; + APartialHue: Boolean): TArt; +var + genericIndex: TGenericIndex; +begin + FIndex.Position := CalculateIndexOffset(AID); + genericIndex := TGenericIndex.Create(FIndex); + Result := GetArtData(AID, genericIndex, AColor, AHue, APartialHue); + genericIndex.Free; + Result.OnChanged := @OnChanged; + Result.OnFinished := @OnFinished; +end; + +function TArtProvider.GetFlatLand(AID: Integer): TArt; +var + genericIndex: TGenericIndex; +begin + FIndex.Position := CalculateIndexOffset(AID); + genericIndex := TGenericIndex.Create(FIndex); + Result := TArt.Create(FData, genericIndex, atLandFlat); + genericIndex.Free; + Result.OnChanged := @OnChanged; + Result.OnFinished := @OnFinished; +end; + +end. + diff --git a/MulProvider/ULightProvider.pas b/MulProvider/ULightProvider.pas new file mode 100644 index 0000000..fab1b9d --- /dev/null +++ b/MulProvider/ULightProvider.pas @@ -0,0 +1,62 @@ +(* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at + * http://www.opensource.org/licenses/cddl1.php. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at + * http://www.opensource.org/licenses/cddl1.php. If applicable, + * add the following below this CDDL HEADER, with the fields enclosed + * by brackets "[]" replaced with your own identifying * information: + * Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * + * Portions Copyright 2009 Andreas Schneider + *) +unit ULightProvider; + +{$mode objfpc}{$H+} + +interface + +uses + UMulProvider, UMulBlock, UGenericIndex, ULight; + +type + + { TLightProvider } + + TLightProvider = class(TIndexedMulProvider) + protected + function GetData(AID: Integer; AIndex: TGenericIndex): TLight; override; + public + function GetLight(AID: Integer): TLight; + end; + +implementation + +{ TLightProvider } + +function TLightProvider.GetData(AID: Integer; AIndex: TGenericIndex): TLight; +begin + Result := TLight.Create(FData, AIndex); + Result.ID := AID; +end; + +function TLightProvider.GetLight(AID: Integer): TLight; +begin + Result := TLight(GetBlock(AID)); +end; + +end. + diff --git a/UOLib/ULight.pas b/UOLib/ULight.pas new file mode 100644 index 0000000..b4f41c4 --- /dev/null +++ b/UOLib/ULight.pas @@ -0,0 +1,121 @@ +(* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at + * http://www.opensource.org/licenses/cddl1.php. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at + * http://www.opensource.org/licenses/cddl1.php. If applicable, + * add the following below this CDDL HEADER, with the fields enclosed + * by brackets "[]" replaced with your own identifying * information: + * Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + * + * + * Portions Copyright 2009 Andreas Schneider + *) +unit ULight; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Imaging, ImagingClasses, ImagingTypes, UMulBlock, + UGenericIndex; + +type + + { TLight } + + TLight = class(TMulBlock) + constructor Create(AData: TStream; AIndex: TGenericIndex); + destructor Destroy; override; + function Clone: TLight; override; + function GetSize: Integer; override; + procedure Write(AData: TStream); override; + protected + FGraphic: TSingleImage; + public + property Graphic: TSingleImage read FGraphic; + end; + +implementation + +{ TLight } + +constructor TLight.Create(AData: TStream; AIndex: TGenericIndex); +var + buffer: TMemoryStream; + Width, Height: Word; + color: Byte; + color32: TColor32Rec; + x, y: Integer; +begin + if (AIndex <> nil) and (AIndex.Lookup > -1) and (AIndex.Size > 0) then + begin + Width := word(AIndex.Various shr 16); + Height := AIndex.Various and $FFFF; + FGraphic := TSingleImage.CreateFromParams(Width, Height, ifA8R8G8B8); + + if AData <> nil then + begin + AData.Position := AIndex.Lookup; + buffer := TMemoryStream.Create; + buffer.CopyFrom(AData, AIndex.Size); + buffer.Position := 0; + for y := 0 to Height - 1 do + for x := 0 to Width - 1 do + begin + buffer.Read(color, SizeOf(byte)); + color32.R := color * 8; + color32.G := color32.R; + color32.B := color32.R; + if color > 0 then + color32.A := 255 + else + color32.A := 0; + PColor32(FGraphic.PixelPointers[x, y])^ := color32.Color; + end; + buffer.Free; + end; + end; + + if FGraphic = nil then + FGraphic := TSingleImage.CreateFromParams(0, 0, ifA8R8G8B8); +end; + +destructor TLight.Destroy; +begin + FreeAndNil(FGraphic); + inherited Destroy; +end; + +function TLight.Clone: TLight; +begin + Result := TLight.Create(nil, nil); + Result.Graphic.Assign(FGraphic); +end; + +function TLight.GetSize: Integer; +begin + Result := 0; + raise Exception.Create('Not implemented: TLight.GetSize'); +end; + +procedure TLight.Write(AData: TStream); +begin + raise Exception.Create('Not implemented: TLight.Write'); +end; + +end. +