- Refined state handling for TBlockInfo
- Added caching of normals into TBlockInfo - Added differentiation for low and high res materials to TBlockInfo - Removed draw list clearing from FillDrawList - Changed TScreenBuffer.Store to return a reference to the stored TBlockInfo - Added missing ; to GetSerial - More cleanups in ULandscape.pas - Moved several local variables of TfrmMain.Render into TfrmMain members - Moved several size related variable initializations from Render into OnResize - Extracted GetDrawOffset - Added seperate RebuildScreenBuffer
This commit is contained in:
parent
61db743ee5
commit
fee66eada8
|
@ -248,7 +248,7 @@
|
|||
<CodeGeneration>
|
||||
<SmartLinkUnit Value="True"/>
|
||||
<Optimizations>
|
||||
<OptimizationLevel Value="3"/>
|
||||
<OptimizationLevel Value="0"/>
|
||||
</Optimizations>
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
|
|
|
@ -38,6 +38,7 @@ uses
|
|||
UCacheManager;
|
||||
|
||||
type
|
||||
PNormals = ^TNormals;
|
||||
TNormals = array[0..3] of TVector;
|
||||
PRadarBlock = ^TRadarBlock;
|
||||
TRadarBlock = array[0..7, 0..7] of Word;
|
||||
|
@ -149,12 +150,17 @@ type
|
|||
procedure UpdateStaticsPriority(AStaticItem: TStaticItem;
|
||||
APrioritySolver: Integer);
|
||||
end;
|
||||
|
||||
TScreenState = (tsNormal, tsFiltered, tsGhost);
|
||||
|
||||
PBlockInfo = ^TBlockInfo;
|
||||
TBlockInfo = record
|
||||
ScreenRect: TRect;
|
||||
Item: TWorldItem;
|
||||
Material: TMaterial;
|
||||
Ghost: Boolean;
|
||||
HighRes: TMaterial;
|
||||
LowRes: TMaterial;
|
||||
Normals: PNormals;
|
||||
State: TScreenState;
|
||||
Next: PBlockInfo;
|
||||
end;
|
||||
|
||||
|
@ -188,8 +194,7 @@ type
|
|||
procedure Clear; override;
|
||||
function Find(AScreenPosition: TPoint): PBlockInfo;
|
||||
function GetSerial: Cardinal;
|
||||
procedure Store(AItem: TWorldItem; AMaterial: TMaterial = nil;
|
||||
AGhost: Boolean = False);
|
||||
function Store(AItem: TWorldItem): PBlockInfo;
|
||||
{ Events }
|
||||
procedure OnTileRemoved(ATile: TMulBlock);
|
||||
end;
|
||||
|
@ -772,7 +777,6 @@ var
|
|||
drawStatics: TList;
|
||||
i, x, y: Integer;
|
||||
begin
|
||||
ADrawList.Clear;
|
||||
for x := AX to AX + AWidth do
|
||||
for y := AY to AY + AWidth do
|
||||
begin
|
||||
|
@ -1026,10 +1030,15 @@ begin
|
|||
if FFirst = current then FFirst := current^.Next;
|
||||
if FLastBlock = current then FLastBlock := last;
|
||||
if last <> nil then last^.Next := current^.Next;
|
||||
|
||||
if current^.Normals <> nil then
|
||||
Dispose(current^.Normals);
|
||||
|
||||
Dispose(current);
|
||||
next := nil;
|
||||
end else
|
||||
next := current^.Next;
|
||||
|
||||
last := current;
|
||||
current := next;
|
||||
end;
|
||||
|
@ -1053,6 +1062,8 @@ begin
|
|||
next := current^.Next;
|
||||
current^.Item.Locked := False;
|
||||
current^.Item.OnDestroy.UnregisterEvent(@OnTileRemoved);
|
||||
if current^.Normals <> nil then
|
||||
Dispose(current^.Normals);
|
||||
Dispose(current);
|
||||
current := next;
|
||||
end;
|
||||
|
@ -1070,8 +1081,9 @@ begin
|
|||
current := FFirst;
|
||||
while (current <> nil) and (Result = nil) do
|
||||
begin
|
||||
if (not current^.Ghost) and PtInRect(current^.ScreenRect, AScreenPosition) and
|
||||
current^.Material.HitTest(AScreenPosition.x - current^.ScreenRect.Left,
|
||||
if (current^.State = tsNormal) and
|
||||
PtInRect(current^.ScreenRect, AScreenPosition) and
|
||||
current^.LowRes.HitTest(AScreenPosition.x - current^.ScreenRect.Left,
|
||||
AScreenPosition.y - current^.ScreenRect.Top) then
|
||||
begin
|
||||
Result := current;
|
||||
|
@ -1082,65 +1094,49 @@ end;
|
|||
|
||||
function TScreenBuffer.GetSerial: Cardinal;
|
||||
begin
|
||||
Result := FSerial
|
||||
Result := FSerial;
|
||||
Inc(FSerial);
|
||||
end;
|
||||
|
||||
procedure TScreenBuffer.Store(AItem: TWorldItem; AMaterial: TMaterial = nil;
|
||||
AGhost: Boolean = False);
|
||||
function TScreenBuffer.Store(AItem: TWorldItem): PBlockInfo;
|
||||
var
|
||||
current, existing: PBlockInfo;
|
||||
current: PBlockInfo;
|
||||
begin
|
||||
New(current);
|
||||
New(Result);
|
||||
AItem.Locked := True;
|
||||
AItem.OnDestroy.RegisterEvent(@OnTileRemoved);
|
||||
current^.Item := AItem;
|
||||
current^.Material := AMaterial;
|
||||
current^.Ghost := AGhost;
|
||||
Result^.Item := AItem;
|
||||
Result^.HighRes := nil;
|
||||
Result^.LowRes := nil;
|
||||
Result^.Normals := nil;
|
||||
Result^.State := tsNormal;
|
||||
|
||||
if (FFirst = nil) or (CompareWorldItems(AItem, FFirst) > 0) then
|
||||
begin
|
||||
current^.Next := FFirst;
|
||||
Result^.Next := FFirst;
|
||||
if FFirst = nil then
|
||||
FLastBlock := current;
|
||||
FFirst := current;
|
||||
FLastBlock := Result;
|
||||
FFirst := Result;
|
||||
end else
|
||||
begin
|
||||
existing := FFirst;
|
||||
while (existing^.Next = nil) and
|
||||
(CompareWorldItems(AItem, existing^.Next^.Item) > 0) do
|
||||
current := FFirst;
|
||||
while (current^.Next = nil) and
|
||||
(CompareWorldItems(AItem, current^.Next^.Item) > 0) do
|
||||
begin
|
||||
existing := existing^.Next;
|
||||
current := current^.Next;
|
||||
end;
|
||||
|
||||
if existing^.Next = nil then
|
||||
FLastBlock := current;
|
||||
if current^.Next = nil then
|
||||
FLastBlock := Result;
|
||||
|
||||
current^.Next := existing^.Next;
|
||||
existing^.Next := current;
|
||||
Result^.Next := current^.Next;
|
||||
current^.Next := Result;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TScreenBuffer.OnTileRemoved(ATile: TMulBlock);
|
||||
var
|
||||
currentItem, lastItem, nextItem: PBlockInfo;
|
||||
begin
|
||||
lastItem := nil;
|
||||
currentItem := FFirst;
|
||||
while currentItem <> nil do
|
||||
begin
|
||||
if currentItem^.Item = ATile then
|
||||
begin
|
||||
if FFirst = currentItem then FFirst := currentItem^.Next;
|
||||
if FLastBlock = currentItem then FLastBlock := lastItem;
|
||||
if lastItem <> nil then lastItem^.Next := currentItem^.Next;
|
||||
Dispose(currentItem);
|
||||
nextItem := nil;
|
||||
end else
|
||||
nextItem := currentItem^.Next;
|
||||
lastItem := currentItem;
|
||||
currentItem := nextItem;
|
||||
end;
|
||||
Delete(TWorldItem(ATile));
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
|
@ -971,6 +971,7 @@ object frmMain: TfrmMain
|
|||
OnMouseUp = oglGameWindowMouseUp
|
||||
OnMouseWheel = oglGameWindowMouseWheel
|
||||
OnPaint = oglGameWindowPaint
|
||||
OnResize = oglGameWindowResize
|
||||
end
|
||||
object pnlChatHeader: TPanel
|
||||
Left = 0
|
||||
|
|
|
@ -217,6 +217,7 @@ type
|
|||
procedure oglGameWindowMouseWheel(Sender: TObject; Shift: TShiftState;
|
||||
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
|
||||
procedure oglGameWindowPaint(Sender: TObject);
|
||||
procedure oglGameWindowResize(Sender: TObject);
|
||||
procedure pmGrabTileInfoPopup(Sender: TObject);
|
||||
procedure tbFilterMouseMove(Sender: TObject; Shift: TShiftState; X,
|
||||
Y: Integer);
|
||||
|
@ -265,8 +266,16 @@ type
|
|||
procedure vstLocationsSaveNode(Sender: TBaseVirtualTree;
|
||||
Node: PVirtualNode; Stream: TStream);
|
||||
protected
|
||||
{ Members }
|
||||
FX: Integer;
|
||||
FY: Integer;
|
||||
FDrawDistance: Integer;
|
||||
FLowOffsetX: Integer;
|
||||
FLowOffsetY: Integer;
|
||||
FHighOffsetX: Integer;
|
||||
FHighOffsetY: Integer;
|
||||
FRangeX: Integer;
|
||||
FRangeY: Integer;
|
||||
FLandscape: TLandscape;
|
||||
FTextureManager: TLandTextureManager;
|
||||
FScreenBuffer: TScreenBuffer;
|
||||
|
@ -280,38 +289,44 @@ type
|
|||
FRandomPresetLocation: string;
|
||||
FLastDraw: TDateTime;
|
||||
FAccessChangedListeners: array of TAccessChangedListener;
|
||||
procedure SetX(const AValue: Integer);
|
||||
procedure SetY(const AValue: Integer);
|
||||
procedure SetCurrentTile(const AValue: TWorldItem);
|
||||
procedure SetSelectedTile(const AValue: TWorldItem);
|
||||
procedure SetNormalLights; inline;
|
||||
procedure SetDarkLights; inline;
|
||||
procedure InitRender;
|
||||
procedure InitSize;
|
||||
procedure Render;
|
||||
procedure OnLandscapeChanged;
|
||||
{ Methods }
|
||||
procedure BuildTileList;
|
||||
procedure ProcessToolState;
|
||||
procedure ProcessAccessLevel;
|
||||
procedure UpdateCurrentTile;
|
||||
procedure UpdateCurrentTile(AX, AY: Integer);
|
||||
procedure TileRemoved(ATile: TMulBlock);
|
||||
procedure WriteChatMessage(ASender, AMessage: string);
|
||||
procedure PrepareVirtualLayer(AWidth, AHeight: Word);
|
||||
procedure OnClientHandlingPacket(ABuffer: TEnhancedMemoryStream);
|
||||
function CanBeModified(ATile: TWorldItem): Boolean;
|
||||
function ConfirmAction: Boolean;
|
||||
procedure GetDrawOffset(ARelativeX, ARelativeY: Integer; out DrawX,
|
||||
DrawY: Single);
|
||||
function GetInternalTileID(ATile: TWorldItem): Word;
|
||||
function GetSelectedRect: TRect;
|
||||
function ConfirmAction: Boolean;
|
||||
function CanBeModified(ATile: TWorldItem): Boolean;
|
||||
procedure InitRender;
|
||||
procedure InitSize;
|
||||
procedure PrepareVirtualLayer(AWidth, AHeight: Word);
|
||||
procedure ProcessToolState;
|
||||
procedure ProcessAccessLevel;
|
||||
procedure RebuildScreenBuffer;
|
||||
procedure Render;
|
||||
procedure SetCurrentTile(const AValue: TWorldItem);
|
||||
procedure SetDarkLights; inline;
|
||||
procedure SetNormalLights; inline;
|
||||
procedure SetSelectedTile(const AValue: TWorldItem);
|
||||
procedure SetX(const AValue: Integer);
|
||||
procedure SetY(const AValue: Integer);
|
||||
procedure UpdateCurrentTile;
|
||||
procedure UpdateCurrentTile(AX, AY: Integer);
|
||||
procedure WriteChatMessage(ASender, AMessage: string);
|
||||
{ Events }
|
||||
procedure OnClientHandlingPacket(ABuffer: TEnhancedMemoryStream);
|
||||
procedure OnLandscapeChanged;
|
||||
procedure OnTileRemoved(ATile: TMulBlock);
|
||||
public
|
||||
{ Fields }
|
||||
property X: Integer read FX write SetX;
|
||||
property Y: Integer read FY write SetY;
|
||||
property Landscape: TLandscape read FLandscape;
|
||||
property CurrentTile: TWorldItem read FCurrentTile write SetCurrentTile;
|
||||
property SelectedTile: TWorldItem read FSelectedTile write SetSelectedTile;
|
||||
|
||||
procedure SetPos(AX, AY: Word);
|
||||
{ Methods }
|
||||
procedure RegisterAccessChangedListener(AListener: TAccessChangedListener);
|
||||
procedure SetPos(AX, AY: Word);
|
||||
procedure UnregisterAccessChangedListener(AListener: TAccessChangedListener);
|
||||
end;
|
||||
|
||||
|
@ -1149,6 +1164,21 @@ begin
|
|||
oglGameWindow.SwapBuffers;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.oglGameWindowResize(Sender: TObject);
|
||||
begin
|
||||
FDrawDistance := Trunc(Sqrt(oglGameWindow.Width * oglGameWindow.Width + oglGamewindow.Height * oglGamewindow.Height) / 44);
|
||||
|
||||
{$HINTS off}{$WARNINGS off}
|
||||
if FX - FDrawDistance < 0 then FLowOffsetX := -FX else FLowOffsetX := -FDrawDistance;
|
||||
if FY - FDrawDistance < 0 then FLowOffsetY := -FY else FLowOffsetY := -FDrawDistance;
|
||||
if FX + FDrawDistance >= FLandscape.Width * 8 then FHighOffsetX := FLandscape.Width * 8 - FX - 1 else FHighOffsetX := FDrawDistance;
|
||||
if FY + FDrawDistance >= FLandscape.Height * 8 then FHighOffsetY := FLandscape.Height * 8 - FY - 1 else FHighOffsetY := FDrawDistance;
|
||||
{$HINTS on}{$WARNINGS on}
|
||||
|
||||
FRangeX := FHighOffsetX - FLowOffsetX;
|
||||
FRangeY := FHighOffsetY - FLowOffsetY;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.pmGrabTileInfoPopup(Sender: TObject);
|
||||
begin
|
||||
mnuGrabHue.Enabled := CurrentTile is TStaticItem;
|
||||
|
@ -1559,19 +1589,19 @@ end;
|
|||
procedure TfrmMain.SetCurrentTile(const AValue: TWorldItem);
|
||||
begin
|
||||
if FCurrentTile <> nil then
|
||||
FCurrentTile.OnDestroy.UnregisterEvent(@TileRemoved);
|
||||
FCurrentTile.OnDestroy.UnregisterEvent(@OnTileRemoved);
|
||||
FCurrentTile := AValue;
|
||||
if FCurrentTile <> nil then
|
||||
FCurrentTile.OnDestroy.RegisterEvent(@TileRemoved);
|
||||
FCurrentTile.OnDestroy.RegisterEvent(@OnTileRemoved);
|
||||
end;
|
||||
|
||||
procedure TfrmMain.SetSelectedTile(const AValue: TWorldItem);
|
||||
begin
|
||||
if FSelectedTile <> nil then
|
||||
FSelectedTile.OnDestroy.UnregisterEvent(@TileRemoved);
|
||||
FSelectedTile.OnDestroy.UnregisterEvent(@OnTileRemoved);
|
||||
FSelectedTile := AValue;
|
||||
if FSelectedTile <> nil then
|
||||
FSelectedTile.OnDestroy.RegisterEvent(@TileRemoved);
|
||||
FSelectedTile.OnDestroy.RegisterEvent(@OnTileRemoved);
|
||||
end;
|
||||
|
||||
procedure TfrmMain.SetNormalLights;
|
||||
|
@ -1623,17 +1653,12 @@ end;
|
|||
|
||||
procedure TfrmMain.Render;
|
||||
var
|
||||
drawDistance: Integer;
|
||||
lowOffX, lowOffY, highOffX, highOffY: Integer;
|
||||
z: ShortInt;
|
||||
mat: TMaterial;
|
||||
cell: TMapCell;
|
||||
west, south, east: Single;
|
||||
drawX, drawY: Single;
|
||||
draw: TList;
|
||||
staticItem: TStaticItem;
|
||||
i, j, k: Integer;
|
||||
startOffX, endOffX, rangeX, rangeY: Integer;
|
||||
normals: TNormals;
|
||||
staticTileData: TStaticTileData;
|
||||
hue: THue;
|
||||
|
@ -1644,47 +1669,24 @@ var
|
|||
staticsFilter: TStaticFilter;
|
||||
editing: Boolean;
|
||||
intensity: GLfloat;
|
||||
blockInfo: PBlockInfo;
|
||||
item: TWorldItem;
|
||||
|
||||
procedure GetMapDrawOffset(x, y: Integer; out drawX, drawY: Single);
|
||||
begin
|
||||
drawX := (oglGameWindow.Width div 2) + (x - y) * 22;
|
||||
drawY := (oglGamewindow.Height div 2) + (x + y) * 22;
|
||||
end;
|
||||
begin
|
||||
drawDistance := Trunc(Sqrt(oglGameWindow.Width * oglGameWindow.Width + oglGamewindow.Height * oglGamewindow.Height) / 44);
|
||||
|
||||
{$HINTS off}{$WARNINGS off}
|
||||
if FX - drawDistance < 0 then lowOffX := -FX else lowOffX := -drawDistance;
|
||||
if FY - drawDistance < 0 then lowOffY := -FY else lowOffY := -drawDistance;
|
||||
if FX + drawDistance >= FLandscape.Width * 8 then highOffX := FLandscape.Width * 8 - FX - 1 else highOffX := drawDistance;
|
||||
if FY + drawDistance >= FLandscape.Height * 8 then highOffY := FLandscape.Height * 8 - FY - 1 else highOffY := drawDistance;
|
||||
{$HINTS on}{$WARNINGS on}
|
||||
|
||||
FLandscape.PrepareBlocks((FX + lowOffX) div 8, (FY + lowOffY) div 8, (FX + highOffX) div 8 + 1, (FY + highOffY) div 8 + 1);
|
||||
PrepareVirtualLayer(drawDistance * 2 + 1, drawDistance * 2 + 1);
|
||||
|
||||
tileRect := GetSelectedRect;
|
||||
FScreenBuffer.Clear;
|
||||
|
||||
rangeX := highOffX - lowOffX;
|
||||
rangeY := highOffY - lowOffY;
|
||||
RebuildScreenBuffer;
|
||||
|
||||
{if acFilter.Checked then
|
||||
staticsFilter := @frmFilter.Filter
|
||||
else
|
||||
staticsFilter := nil;} //TODO : update list on change
|
||||
staticsFilter := nil;} //TODO : update list on change}
|
||||
|
||||
{draw := FLandscape.GetDrawList(FX + lowOffX, FY + lowOffY, rangeX, rangeY,
|
||||
frmBoundaries.tbMinZ.Position, frmBoundaries.tbMaxZ.Position,
|
||||
nil, nil, tbTerrain.Down, tbStatics.Down, //TODO : ghost tile and virtual tile!
|
||||
acNoDraw.Checked, nil); //TODO : statics filter!
|
||||
|
||||
for i := 0 to draw.Count - 1 do
|
||||
blockInfo := nil;
|
||||
while FScreenBuffer.Iterate(blockInfo) do
|
||||
begin
|
||||
item := TWorldItem(draw[i]);
|
||||
item := blockInfo^.Item;
|
||||
|
||||
GetMapDrawOffset(item.X - FX, item.Y - FY, drawX, drawY);
|
||||
{GetMapDrawOffset(item.X - FX, item.Y - FY, drawX, drawY);
|
||||
|
||||
singleTarget := (CurrentTile <> nil) and
|
||||
(item.X = CurrentTile.X) and
|
||||
|
@ -1868,11 +1870,9 @@ begin
|
|||
end;
|
||||
|
||||
if highlight then
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
glDisable(GL_COLOR_LOGIC_OP);}
|
||||
end;
|
||||
|
||||
draw.Free;}
|
||||
|
||||
FOverlayUI.Draw(oglGameWindow);
|
||||
end;
|
||||
|
||||
|
@ -1995,6 +1995,20 @@ begin
|
|||
Caption := Format('UO CentrED - [%s (%s)]', [dmNetwork.Username, GetAccessLevelString(dmNetwork.AccessLevel)]);
|
||||
end;
|
||||
|
||||
procedure TfrmMain.RebuildScreenBuffer;
|
||||
begin
|
||||
FLandscape.PrepareBlocks((FX + FLowOffsetX) div 8, (FY + FLowOffsetY) div 8, (FX + FHighOffsetX) div 8 + 1, (FY + FHighOffsetY) div 8 + 1);
|
||||
PrepareVirtualLayer(FDrawDistance * 2 + 1, FDrawDistance * 2 + 1);
|
||||
|
||||
FScreenBuffer.Clear;
|
||||
//TODO : Virtual Layer
|
||||
FLandscape.FillDrawList(FScreenBuffer, FX + FLowOffsetX, FY + FLowOffsetY,
|
||||
FRangeX, FRangeY, frmBoundaries.tbMinZ.Position,
|
||||
frmBoundaries.tbMaxZ.Position, tbTerrain.Down, tbStatics.Down,
|
||||
acNoDraw.Checked, nil); //TODO : statics filter
|
||||
//TODO : ghost tile
|
||||
end;
|
||||
|
||||
procedure TfrmMain.UpdateCurrentTile;
|
||||
var
|
||||
localPos: TPoint;
|
||||
|
@ -2041,7 +2055,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure TfrmMain.TileRemoved(ATile: TMulBlock);
|
||||
procedure TfrmMain.OnTileRemoved(ATile: TMulBlock);
|
||||
begin
|
||||
if ATile = FCurrentTile then
|
||||
FCurrentTile := nil
|
||||
|
@ -2229,6 +2243,13 @@ begin
|
|||
oglGameWindowMouseLeave(nil);
|
||||
end;
|
||||
|
||||
procedure TfrmMain.GetDrawOffset(ARelativeX, ARelativeY: Integer; out DrawX,
|
||||
DrawY: Single);
|
||||
begin
|
||||
DrawX := (oglGameWindow.Width div 2) + (ARelativeX - ARelativeY) * 22;
|
||||
DrawY := (oglGamewindow.Height div 2) + (ARelativeX + ARelativeY) * 22;
|
||||
end;
|
||||
|
||||
function TfrmMain.CanBeModified(ATile: TWorldItem): Boolean;
|
||||
begin
|
||||
Result := (not (ATile is TVirtualTile)) and
|
||||
|
|
Loading…
Reference in New Issue