1 (* Copyright (C) Doom 2D: Forever Developers
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, version 3 of the License ONLY.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 {$INCLUDE ../../../shared/a_modes.inc}
23 left
, right
, up
: TAtlasNode
;
24 mL
, mT
, mR
, mB
: Integer;
29 destructor Destroy
; override;
33 function GetWidth (): Integer; inline;
34 function GetHeight (): Integer; inline;
36 property x
: Integer read mL
;
37 property y
: Integer read mT
;
38 property width
: Integer read GetWidth
;
39 property height
: Integer read GetHeight
;
41 property l
: Integer read mL
;
42 property t
: Integer read mT
;
43 property r
: Integer read mR
;
44 property b
: Integer read mB
;
49 constructor Create (w
, h
: Integer);
50 destructor Destroy
; override; (* also destroed attached nodes *)
52 (* never free TAtlasNode directly, use Dealloc method. *)
53 function CreateNode (): TAtlasNode
; virtual; (* allocate empty node (user defined type) *)
54 function Alloc (w
, h
: Integer): TAtlasNode
; (* allocate node and attach it *)
56 function GetWidth (): Integer; inline;
57 function GetHeight (): Integer; inline;
62 function NewNode (p
: TAtlasNode
; w
, h
: Integer): TAtlasNode
;
65 property w
: Integer read GetWidth
;
66 property h
: Integer read GetHeight
;
72 procedure FreeNodeRecursive (n
: TAtlasNode
);
76 FreeNodeRecursive(n
.left
);
77 FreeNodeRecursive(n
.right
);
82 function IsLeafTree (n
: TAtlasNode
): Boolean;
84 result
:= (n
<> nil) and (n
.leaf
or IsLeafTree(n
.left
) or IsLeafTree(n
.right
))
87 (* --------- TNode --------- *)
89 constructor TAtlasNode
.Create
;
94 destructor TAtlasNode
.Destroy
;
100 if p
.left
= self
then
102 else if p
.right
= self
then
106 if self
.left
<> nil then
108 if self
.right
<> nil then
113 procedure TAtlasNode
.Dealloc
;
116 ASSERT(self
.leaf
= true);
117 ASSERT(self
.right
= nil);
118 ASSERT(self
.left
= nil);
123 ASSERT(p
.leaf
= false);
124 ASSERT(p
.left
<> nil);
125 ASSERT(p
.right
<> nil);
126 if IsLeafTree(p
) = false then
128 FreeNodeRecursive(p
.left
); p
.left
:= nil;
129 FreeNodeRecursive(p
.right
); p
.right
:= nil;
139 function TAtlasNode
.GetWidth (): Integer;
141 result
:= self
.r
- self
.l
+ 1;
144 function TAtlasNode
.GetHeight (): Integer;
146 result
:= self
.b
- self
.t
+ 1;
149 (* --------- TAtlas --------- *)
151 constructor TAtlas
.Create (w
, h
: Integer);
154 self
.root
:= self
.CreateNode();
155 ASSERT(self
.root
<> nil);
156 self
.root
.mR
:= w
- 1;
157 self
.root
.mB
:= h
- 1;
160 destructor TAtlas
.Destroy
;
162 FreeNodeRecursive(self
.root
.left
);
163 FreeNodeRecursive(self
.root
.right
);
167 function TAtlas
.GetWidth (): Integer;
169 result
:= self
.root
.r
{- self.root.l} + 1;
172 function TAtlas
.GetHeight (): Integer;
174 result
:= self
.root
.b
{- self.root.t} + 1;
177 function TAtlas
.CreateNode (): TAtlasNode
;
179 result
:= TAtlasNode
.Create()
182 function TAtlas
.NewNode (p
: TAtlasNode
; w
, h
: Integer): TAtlasNode
;
188 if p
.left
<> nil then
190 ASSERT(p
.right
<> nil);
191 n
:= NewNode(p
.left
, w
, h
);
193 n
:= NewNode(p
.right
, w
, h
);
196 else if p
.leaf
or (p
.width
< w
) or (p
.height
< h
) then
200 else if (p
.width
= w
) and (p
.height
= h
) then
207 p
.left
:= self
.CreateNode();
208 p
.right
:= self
.CreateNode();
209 if (p
.left
= nil) or (p
.right
= nil) then
211 (* failed to allocate nodes *)
212 if p
.left
<> nil then
214 if p
.right
<> nil then
224 if p
.width
- w
> p
.height
- h
then
228 p
.left
.mR
:= p
.l
+ w
- 1;
230 p
.right
.mL
:= p
.l
+ w
;
240 p
.left
.mB
:= p
.t
+ h
- 1;
242 p
.right
.mT
:= p
.t
+ h
;
246 result
:= NewNode(p
.left
, w
, h
);
251 function TAtlas
.Alloc (w
, h
: Integer): TAtlasNode
;
257 if (w
<= self
.w
) and (h
<= self
.h
) then
259 n
:= NewNode(self
.root
, w
, h
);