diff --git a/Client/CentrED.lpi b/Client/CentrED.lpi
index 076f0fa..a256838 100644
--- a/Client/CentrED.lpi
+++ b/Client/CentrED.lpi
@@ -55,7 +55,7 @@
-
+
@@ -304,6 +304,11 @@
+
+
+
+
+
@@ -332,7 +337,6 @@
-
diff --git a/Client/CentrED.lpr b/Client/CentrED.lpr
index c529ee7..cf861ef 100644
--- a/Client/CentrED.lpr
+++ b/Client/CentrED.lpr
@@ -42,7 +42,8 @@ uses
UGUIPlatformUtils, UPlatformTypes, UfrmRegionControl, UPackets,
UPacketHandlers, UAdminHandling, UGameResources, ULandscape, UfrmToolWindow,
Logging, UTileDataProvider, UMap, UWorldItem, UStatics, UTiledata, UAnimData,
- UGLFont, UAnimDataProvider, UMulManager, UArtProvider, UTexmapProvider;
+ UGLFont, UAnimDataProvider, UMulManager, UArtProvider, UTexmapProvider,
+ULightManager;
{$IFDEF WINDOWS}{$R CentrED.rc}{$ENDIF}
diff --git a/Client/ULightManager.pas b/Client/ULightManager.pas
new file mode 100644
index 0000000..231c979
--- /dev/null
+++ b/Client/ULightManager.pas
@@ -0,0 +1,221 @@
+(*
+ * 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 ULightManager;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, Imaging, ImagingTypes, ImagingClasses, ImagingCanvases,
+ ImagingOpenGL, GL, fgl, ULandscape, UWorldItem;
+
+type
+
+ TCalculateOffset = procedure(ARelativeX, ARelativeY: Integer; out DrawX,
+ DrawY: Integer) of object;
+
+ { TLightSource }
+
+ TLightSource = class
+ constructor Create(AWorldItem: TWorldItem);
+ protected
+ FX: Integer;
+ FY: Integer;
+ FZ: smallint;
+ public
+ property X: Integer read FX;
+ property Y: Integer read FY;
+ property Z: smallint read FZ;
+ end;
+
+ TLightSources = specialize TFPGObjectList;
+
+ { TLightManager }
+
+ TLightManager = class
+ constructor Create(ACalculateOffset: TCalculateOffset);
+ destructor Destroy; override;
+ protected
+ FLightSources: TLightSources;
+ FOverlay: TSingleImage;
+ FOverlayTexture: GLuint;
+ FLightLevel: byte;
+ FValid: Boolean;
+ FCalculateOffset: TCalculateOffset;
+ procedure UpdateOverlay(AScreenRect: TRect; FX, FY: Integer);
+ public
+ procedure UpdateLightMap(ALeft, AWidth, ATop, AHeight: Integer;
+ AScreenBuffer: TScreenBuffer);
+ procedure Draw(AScreenRect: TRect; FX, FY: Integer);
+ end;
+
+implementation
+
+uses
+ UGameResources, UTiledata, UStatics, Logging;
+
+{ TLightManager }
+
+constructor TLightManager.Create(ACalculateOffset: TCalculateOffset);
+begin
+ FCalculateOffset := ACalculateOffset;
+ FLightSources := TLightSources.Create(True);
+ FLightLevel := 15; //TODO : 0 ...
+end;
+
+destructor TLightManager.Destroy;
+begin
+ FreeAndNil(FLightSources);
+ FreeAndNil(FOverlay);
+ glDeleteTextures(1, @FOverlayTexture);
+ inherited Destroy;
+end;
+
+procedure TLightManager.UpdateOverlay(AScreenRect: TRect; FX, FY: Integer);
+var
+ canvas: TFastARGB32Canvas;
+ color: TColor32Rec;
+ i, drawX, drawY, drawZ: Integer;
+begin
+ FOverlay.Free;
+ glDeleteTextures(1, @FOverlayTexture);
+
+ color.A := $FF;
+ color.R := ((32 - FLightLevel) * 255) div 32;
+ color.G := color.R;
+ color.B := color.R;
+
+ FOverlay := TSingleImage.CreateFromParams(AScreenRect.Right, AScreenRect.Bottom,
+ ifA8R8G8B8);
+ canvas := TFastARGB32Canvas.CreateForImage(FOverlay);
+ try
+ canvas.FillColor32 := color.Color;
+ canvas.FillRect(AScreenRect);
+ finally
+ canvas.Free;
+ end;
+
+ 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);
+ end;
+
+ //TODO : PowerOfTwo!!!
+ FOverlayTexture := CreateGLTextureFromImage(FOverlay.ImageDataPointer^);
+
+ FValid := True;
+end;
+
+procedure TLightManager.UpdateLightMap(ALeft, AWidth, ATop, AHeight: Integer;
+ AScreenBuffer: TScreenBuffer);
+var
+ blockInfo: PBlockInfo;
+ itemMap, lightMap: array of array of TWorldItem;
+ x, y: Integer;
+begin
+ //Logger.EnterMethod([lcClient, lcDebug], 'UpdateLightMap');
+ FLightSources.Clear;
+ {Logger.Send([lcClient, lcDebug], 'AWidth', AWidth);
+ Logger.Send([lcClient, lcDebug], 'AHeight', AHeight);}
+ SetLength(itemMap, AWidth, AHeight);
+ SetLength(lightMap, AWidth, AHeight);
+ for x := 0 to AWidth - 1 do
+ for y := 0 to AHeight - 1 do
+ begin
+ itemMap[x, y] := nil;
+ lightMap[x, y] := nil;
+ end;
+
+ blockInfo := nil;
+ while AScreenBuffer.Iterate(blockInfo) do
+ begin
+ if blockInfo^.State = ssNormal then
+ begin
+ x := blockInfo^.Item.X - ALeft;
+ y := blockInfo^.Item.Y - ATop;
+ itemMap[x, y] := blockInfo^.Item;
+ if (blockInfo^.Item is TStaticItem) and (tdfLightSource in
+ ResMan.Tiledata.StaticTiles[blockInfo^.Item.TileID].Flags) then
+ lightMap[x, y] := blockInfo^.Item;
+ end;
+ end;
+
+ for x := 0 to AWidth - 2 do
+ for y := 0 to AHeight - 2 do
+ if lightMap[x, y] <> nil then
+ begin
+ if ((itemMap[x, y] = nil) or (itemMap[x, y].Z < lightMap[x, y].Z + 3)) or
+ ((itemMap[x + 1, y] = nil) or (itemMap[x + 1, y].Z < lightMap[x, y].Z + 3)) or
+ ((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]));
+ end;
+ end;
+ FValid := False;
+ //Logger.ExitMethod([lcClient, lcDebug], 'UpdateLightMap');
+end;
+
+procedure TLightManager.Draw(AScreenRect: TRect; FX, FY: Integer);
+begin
+ if not FValid then
+ UpdateOverlay(AScreenRect, FX, FY);
+
+ glBindTexture(GL_TEXTURE_2D, FOverlayTexture);
+ glBlendFunc(GL_ZERO, GL_SRC_COLOR);
+ glBegin(GL_QUADS);
+ glTexCoord2i(0, 0);
+ glVertex2i(AScreenRect.Left, AScreenRect.Top);
+ glTexCoord2i(0, 1);
+ glVertex2i(AScreenRect.Left, AScreenRect.Bottom);
+ glTexCoord2i(1, 1);
+ glVertex2i(AScreenRect.Right, AScreenRect.Bottom);
+ glTexCoord2i(1, 0);
+ glVertex2i(AScreenRect.Right, AScreenRect.Top);
+ glEnd;
+end;
+
+{ TLightSource }
+
+constructor TLightSource.Create(AWorldItem: TWorldItem);
+begin
+ FX := AWorldItem.X;
+ FY := AWorldItem.Y;
+ FZ := AWorldItem.Z;
+end;
+
+end.
+
diff --git a/Client/UOverlayUI.pas b/Client/UOverlayUI.pas
index b85c4ce..80757fa 100644
--- a/Client/UOverlayUI.pas
+++ b/Client/UOverlayUI.pas
@@ -1,252 +1,255 @@
-(*
- * 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 2007 Andreas Schneider
- *)
-unit UOverlayUI;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
- Classes, SysUtils, Gl, GLU, Imaging, ImagingTypes, ImagingClasses,
- ImagingOpenGL, OpenGLContext, ImagingUtility;
-
-type
-
- { TGLArrow }
-
- TGLArrow = class(TObject)
- constructor Create(AGraphic: TSingleImage);
- destructor Destroy; override;
- protected
- FGraphic: TSingleImage;
- FTexture: GLuint;
- FRealWidth: Integer;
- FRealHeight: Integer;
- FWidth: Integer;
- FHeight: Integer;
- FCurrentX: Integer;
- FCurrentY: Integer;
- procedure UpdateTexture;
- public
- property Width: Integer read FWidth;
- property Height: Integer read FHeight;
- property CurrentX: Integer read FCurrentX;
- property CurrentY: Integer read FCurrentY;
-
- function HitTest(AX, AY: Integer): Boolean;
- procedure DrawGL(AX, AY: Integer; AActive: Boolean = False);
- end;
-
- { TOverlayUI }
-
- TOverlayUI = class(TObject)
- constructor Create;
- destructor Destroy; override;
- protected
- FArrows: array[0..7] of TGLArrow;
- FActiveArrow: Integer;
- FVisible: Boolean;
- public
- property ActiveArrow: Integer read FActiveArrow write FActiveArrow;
- property Visible: Boolean read FVisible write FVisible;
- function HitTest(AX, AY: Integer): Integer;
- procedure Draw(AContext: TOpenGLControl);
- end;
-
-implementation
-
-uses
- UResourceManager;
-
-{ TGLArrow }
-
-constructor TGLArrow.Create(AGraphic: TSingleImage);
-var
- caps: TGLTextureCaps;
-begin
- inherited Create;
- FRealWidth := AGraphic.Width;
- FRealHeight := AGraphic.Height;
- GetGLTextureCaps(caps);
- if caps.NonPowerOfTwo then
- begin
- FWidth := FRealWidth;
- FHeight := FRealHeight;
- end else
- begin
- if IsPow2(FRealWidth) then FWidth := FRealWidth else FWidth := NextPow2(FRealWidth);
- if IsPow2(FRealHeight) then FHeight := FRealHeight else FHeight := NextPow2(FRealHeight);
- end;
- FGraphic := TSingleImage.CreateFromParams(FWidth, FHeight, ifA8R8G8B8);
- AGraphic.CopyTo(0, 0, FRealWidth, FRealHeight, FGraphic, 0, 0);
- FTexture := 0;
-end;
-
-destructor TGLArrow.Destroy;
-begin
- if FGraphic <> nil then FreeAndNil(FGraphic);
- if FTexture <> 0 then glDeleteTextures(1, @FTexture);
- inherited Destroy;
-end;
-
-procedure TGLArrow.UpdateTexture;
-begin
- if (FGraphic <> nil) and (FRealWidth > 0) and (FRealWidth > 0) then
- begin
- FTexture := CreateGLTextureFromImage(FGraphic.ImageDataPointer^, 0, 0, False);
-
- glBindTexture(GL_TEXTURE_2D, FTexture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- end;
-end;
-
-function TGLArrow.HitTest(AX, AY: Integer): Boolean;
-var
- pixel: TColor32Rec;
-begin
- if (AX > -1) and (AX < FRealWidth) and (AY > -1) and (AY < FRealHeight) then
- begin
- pixel := GetPixel32(FGraphic.ImageDataPointer^, AX, AY);
- Result := pixel.A > 0;
- end else
- Result := False;
-end;
-
-procedure TGLArrow.DrawGL(AX, AY: Integer; AActive: Boolean = False);
-begin
- FCurrentX := AX;
- FCurrentY := AY;
-
- if FTexture = 0 then UpdateTexture;
-
- if FTexture <> 0 then
- begin
- if AActive then
- begin
- glEnable(GL_COLOR_LOGIC_OP);
- glLogicOp(GL_COPY_INVERTED);
- end;
-
- glBindTexture(GL_TEXTURE_2D, FTexture);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2d(AX, AY);
- glTexCoord2f(1, 0); glVertex2d(AX + FWidth, AY);
- glTexCoord2f(1, 1); glVertex2d(AX + FWidth, AY + FHeight);
- glTexCoord2f(0, 1); glVertex2d(AX, AY + FHeight);
- glEnd;
-
- if AActive then
- glDisable(GL_COLOR_LOGIC_OP);
- end;
-end;
-
-{ TOverlayUI }
-
-constructor TOverlayUI.Create;
-var
- i: Integer;
- arrow: TSingleImage;
-begin
- inherited Create;
- FActiveArrow := -1;
- FVisible := False;
-
- arrow := TSingleImage.CreateFromStream(ResourceManager.GetResource(0));
- for i := 0 to 3 do
- begin
- FArrows[2*i] := TGLArrow.Create(arrow);
- if i < 3 then
- arrow.Rotate(-90);
- end;
- arrow.Free;
-
- arrow := TSingleImage.CreateFromStream(ResourceManager.GetResource(1));
- for i := 0 to 3 do
- begin
- FArrows[2*i+1] := TGLArrow.Create(arrow);
- if i < 3 then
- arrow.Rotate(-90);
- end;
- arrow.Free;
-end;
-
-destructor TOverlayUI.Destroy;
-var
- i: Integer;
-begin
- for i := 0 to 7 do
- if FArrows[i] <> nil then FreeAndNil(FArrows[i]);
-
- inherited Destroy;
-end;
-
-function TOverlayUI.HitTest(AX, AY: Integer): Integer;
-var
- i: Integer;
-begin
- Result := -1;
- i := 0;
- while (i <= 7) and (Result = -1) do
- begin
- if FArrows[i].HitTest(AX - FArrows[i].CurrentX, AY - FArrows[i].CurrentY) then
- Result := i;
- Inc(i);
- end;
-end;
-
-procedure TOverlayUI.Draw(AContext: TOpenGLControl);
-begin
- if FVisible then
- begin
- FArrows[0].DrawGL(10, 10, FActiveArrow = 0);
- FArrows[1].DrawGL(AContext.Width div 2 - FArrows[1].Width div 2, 10,
- FActiveArrow = 1);
- FArrows[2].DrawGL(AContext.Width - 10 - FArrows[2].Width, 10,
- FActiveArrow = 2);
-
- FArrows[3].DrawGL(AContext.Width - 10 - FArrows[3].Width,
- AContext.Height div 2 - FArrows[3].Height div 2,
- FActiveArrow = 3);
-
- FArrows[4].DrawGL(AContext.Width - 10 - FArrows[4].Width,
- AContext.Height - 10 - FArrows[4].Height,
- FActiveArrow = 4);
- FArrows[5].DrawGL(AContext.Width div 2 - FArrows[5].Width div 2,
- AContext.Height - 10 - FArrows[5].Height,
- FActiveArrow = 5);
- FArrows[6].DrawGL(10, AContext.Height - 10 - FArrows[6].Height,
- FActiveArrow = 6);
-
- FArrows[7].DrawGL(10, AContext.Height div 2 - FArrows[7].Height div 2,
- FActiveArrow = 7);
- end;
-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 2007 Andreas Schneider
+ *)
+unit UOverlayUI;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, Gl, GLU, Imaging, ImagingTypes, ImagingClasses,
+ ImagingOpenGL, OpenGLContext, ImagingUtility;
+
+type
+
+ { TGLArrow }
+
+ TGLArrow = class(TObject)
+ constructor Create(AGraphic: TSingleImage);
+ destructor Destroy; override;
+ protected
+ FGraphic: TSingleImage;
+ FTexture: GLuint;
+ FRealWidth: Integer;
+ FRealHeight: Integer;
+ FWidth: Integer;
+ FHeight: Integer;
+ FCurrentX: Integer;
+ FCurrentY: Integer;
+ procedure UpdateTexture;
+ public
+ property Width: Integer read FWidth;
+ property Height: Integer read FHeight;
+ property CurrentX: Integer read FCurrentX;
+ property CurrentY: Integer read FCurrentY;
+
+ function HitTest(AX, AY: Integer): Boolean;
+ procedure DrawGL(AX, AY: Integer; AActive: Boolean = False);
+ end;
+
+ { TOverlayUI }
+
+ TOverlayUI = class(TObject)
+ constructor Create;
+ destructor Destroy; override;
+ protected
+ FArrows: array[0..7] of TGLArrow;
+ FActiveArrow: Integer;
+ FVisible: Boolean;
+ public
+ property ActiveArrow: Integer read FActiveArrow write FActiveArrow;
+ property Visible: Boolean read FVisible write FVisible;
+ function HitTest(AX, AY: Integer): Integer;
+ procedure Draw(AContext: TOpenGLControl);
+ end;
+
+implementation
+
+uses
+ UResourceManager;
+
+{ TGLArrow }
+
+constructor TGLArrow.Create(AGraphic: TSingleImage);
+var
+ caps: TGLTextureCaps;
+begin
+ inherited Create;
+ FRealWidth := AGraphic.Width;
+ FRealHeight := AGraphic.Height;
+ GetGLTextureCaps(caps);
+ if caps.NonPowerOfTwo then
+ begin
+ FWidth := FRealWidth;
+ FHeight := FRealHeight;
+ end else
+ begin
+ if IsPow2(FRealWidth) then FWidth := FRealWidth else FWidth := NextPow2(FRealWidth);
+ if IsPow2(FRealHeight) then FHeight := FRealHeight else FHeight := NextPow2(FRealHeight);
+ end;
+ FGraphic := TSingleImage.CreateFromParams(FWidth, FHeight, ifA8R8G8B8);
+ AGraphic.CopyTo(0, 0, FRealWidth, FRealHeight, FGraphic, 0, 0);
+ FTexture := 0;
+end;
+
+destructor TGLArrow.Destroy;
+begin
+ if FGraphic <> nil then FreeAndNil(FGraphic);
+ if FTexture <> 0 then glDeleteTextures(1, @FTexture);
+ inherited Destroy;
+end;
+
+procedure TGLArrow.UpdateTexture;
+begin
+ if (FGraphic <> nil) and (FRealWidth > 0) and (FRealWidth > 0) then
+ begin
+ FTexture := CreateGLTextureFromImage(FGraphic.ImageDataPointer^, 0, 0, False);
+
+ glBindTexture(GL_TEXTURE_2D, FTexture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ end;
+end;
+
+function TGLArrow.HitTest(AX, AY: Integer): Boolean;
+var
+ pixel: TColor32Rec;
+begin
+ if (AX > -1) and (AX < FRealWidth) and (AY > -1) and (AY < FRealHeight) then
+ begin
+ pixel := GetPixel32(FGraphic.ImageDataPointer^, AX, AY);
+ Result := pixel.A > 0;
+ end else
+ Result := False;
+end;
+
+procedure TGLArrow.DrawGL(AX, AY: Integer; AActive: Boolean = False);
+begin
+ FCurrentX := AX;
+ FCurrentY := AY;
+
+ if FTexture = 0 then UpdateTexture;
+
+ if FTexture <> 0 then
+ begin
+ if AActive then
+ begin
+ glEnable(GL_COLOR_LOGIC_OP);
+ glLogicOp(GL_COPY_INVERTED);
+ end;
+
+ glBindTexture(GL_TEXTURE_2D, FTexture);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2d(AX, AY);
+ glTexCoord2f(1, 0); glVertex2d(AX + FWidth, AY);
+ glTexCoord2f(1, 1); glVertex2d(AX + FWidth, AY + FHeight);
+ glTexCoord2f(0, 1); glVertex2d(AX, AY + FHeight);
+ glEnd;
+
+ if AActive then
+ glDisable(GL_COLOR_LOGIC_OP);
+ end;
+end;
+
+{ TOverlayUI }
+
+constructor TOverlayUI.Create;
+var
+ i: Integer;
+ arrow: TSingleImage;
+begin
+ inherited Create;
+ FActiveArrow := -1;
+ FVisible := False;
+
+ arrow := TSingleImage.CreateFromStream(ResourceManager.GetResource(0));
+ for i := 0 to 3 do
+ begin
+ FArrows[2*i] := TGLArrow.Create(arrow);
+ if i < 3 then
+ arrow.Rotate(-90);
+ end;
+ arrow.Free;
+
+ arrow := TSingleImage.CreateFromStream(ResourceManager.GetResource(1));
+ for i := 0 to 3 do
+ begin
+ FArrows[2*i+1] := TGLArrow.Create(arrow);
+ if i < 3 then
+ arrow.Rotate(-90);
+ end;
+ arrow.Free;
+end;
+
+destructor TOverlayUI.Destroy;
+var
+ i: Integer;
+begin
+ for i := 0 to 7 do
+ if FArrows[i] <> nil then FreeAndNil(FArrows[i]);
+
+ inherited Destroy;
+end;
+
+function TOverlayUI.HitTest(AX, AY: Integer): Integer;
+var
+ i: Integer;
+begin
+ Result := -1;
+ i := 0;
+ while (i <= 7) and (Result = -1) do
+ begin
+ if FArrows[i].HitTest(AX - FArrows[i].CurrentX, AY - FArrows[i].CurrentY) then
+ Result := i;
+ Inc(i);
+ end;
+end;
+
+procedure TOverlayUI.Draw(AContext: TOpenGLControl);
+begin
+ if FVisible then
+ begin
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ FArrows[0].DrawGL(10, 10, FActiveArrow = 0);
+ FArrows[1].DrawGL(AContext.Width div 2 - FArrows[1].Width div 2, 10,
+ FActiveArrow = 1);
+ FArrows[2].DrawGL(AContext.Width - 10 - FArrows[2].Width, 10,
+ FActiveArrow = 2);
+
+ FArrows[3].DrawGL(AContext.Width - 10 - FArrows[3].Width,
+ AContext.Height div 2 - FArrows[3].Height div 2,
+ FActiveArrow = 3);
+
+ FArrows[4].DrawGL(AContext.Width - 10 - FArrows[4].Width,
+ AContext.Height - 10 - FArrows[4].Height,
+ FActiveArrow = 4);
+ FArrows[5].DrawGL(AContext.Width div 2 - FArrows[5].Width div 2,
+ AContext.Height - 10 - FArrows[5].Height,
+ FActiveArrow = 5);
+ FArrows[6].DrawGL(10, AContext.Height - 10 - FArrows[6].Height,
+ FActiveArrow = 6);
+
+ FArrows[7].DrawGL(10, AContext.Height div 2 - FArrows[7].Height div 2,
+ FActiveArrow = 7);
+ end;
+end;
+
+end.
+
diff --git a/Client/UfrmMain.lfm b/Client/UfrmMain.lfm
index aa4e658..65b8bbd 100644
--- a/Client/UfrmMain.lfm
+++ b/Client/UfrmMain.lfm
@@ -1,7 +1,7 @@
object frmMain: TfrmMain
Left = 257
Height = 579
- Top = 135
+ Top = 141
Width = 755
ActiveControl = oglGameWindow
Caption = 'UO CentrED'
diff --git a/Client/UfrmMain.pas b/Client/UfrmMain.pas
index b684332..f9d2bd4 100644
--- a/Client/UfrmMain.pas
+++ b/Client/UfrmMain.pas
@@ -35,7 +35,7 @@ uses
StdCtrls, Spin, UEnums, VirtualTrees, Buttons, UMulBlock, UWorldItem, math,
LCLIntf, UOverlayUI, UStatics, UEnhancedMemoryStream, ActnList,
XMLPropStorage, fgl, ImagingClasses, dateutils, UPlatformTypes, UMap, UPacket,
- UGLFont, DOM, XMLRead, XMLWrite, strutils;
+ UGLFont, DOM, XMLRead, XMLWrite, strutils, ULightManager;
type
TAccessChangedListener = procedure(AAccessLevel: TAccessLevel) of object;
@@ -323,6 +323,7 @@ type
FGLFont: TGLFont;
FSelectionListeners: TSelectionListeners;
FTileHint: TTileHintInfo;
+ FLightManager: TLightManager;
{ Methods }
procedure BuildTileList;
function ConfirmAction: Boolean;
@@ -892,6 +893,7 @@ begin
edX.MaxValue := FLandscape.CellWidth;
edY.MaxValue := FLandscape.CellHeight;
FOverlayUI := TOverlayUI.Create;
+ FLightManager := TLightManager.Create(@GetDrawOffset);
ProcessAccessLevel;
@@ -1258,6 +1260,7 @@ begin
FreeAndNil(FTextureManager);
FreeAndNil(FScreenBuffer);
FreeAndNil(FOverlayUI);
+ FreeAndNil(FLightManager);
FreeAndNil(FVLayerImage);
FreeAndNil(FVLayerMaterial);
FreeAndNil(FVirtualTiles);
@@ -2387,7 +2390,7 @@ begin
blockInfo^.Text.Render(blockInfo^.ScreenRect);
end;
- glColor4f(1.0, 1.0, 1.0, 1.0);
+ FLightManager.Draw(oglGameWindow.ClientRect, FX, FY);
FOverlayUI.Draw(oglGameWindow);
end;
@@ -2729,6 +2732,10 @@ begin
end;
end;
Include(FScreenBufferState, sbsFiltered);
+
+ //TODO : Check lightlevel first
+ FLightManager.UpdateLightMap(FX + FLowOffsetX, FRangeX + 1, FY + FLowOffsetY,
+ FRangeY + 1, FScreenBuffer);
end;
procedure TfrmMain.UpdateSelection;