c13693e7b0bc3aa3cefd820bfdd433fb35446973
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, either version 3 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 MAPSTRUCT
, BinEditor
, g_textures
;
25 TAddTextureArray
= Array of
31 TPanel
= Class (TObject
)
40 False: (Tex
: Cardinal);
41 True: (AnTex
: TAnimation
);
45 FCurTexture
: Integer; // Íîìåð òåêóùåé òåêñòóðû
51 SaveIt
: Boolean; // Ñîõðàíÿòü ïðè SaveState?
57 constructor Create(PanelRec
: TPanelRec_1
;
58 AddTextures
: TAddTextureArray
;
60 var Textures
: TLevelTextureArray
);
61 destructor Destroy(); override;
65 procedure SetFrame(Frame
: Integer; Count
: Byte);
66 procedure NextTexture(AnimLoop
: Byte = 0);
67 procedure SetTexture(ID
: Integer; AnimLoop
: Byte = 0);
68 function GetTextureID(): Cardinal;
69 function GetTextureCount(): Integer;
71 procedure SaveState(var Mem
: TBinMemoryWriter
);
72 procedure LoadState(var Mem
: TBinMemoryReader
);
75 TPanelArray
= Array of TPanel
;
80 SysUtils
, g_basic
, g_map
, MAPDEF
, g_game
, e_graphics
,
81 g_console
, g_language
, e_log
;
84 PANEL_SIGNATURE
= $4C4E4150; // 'PANL'
88 constructor TPanel
.Create(PanelRec
: TPanelRec_1
;
89 AddTextures
: TAddTextureArray
;
91 var Textures
: TLevelTextureArray
);
97 Width
:= PanelRec
.Width
;
98 Height
:= PanelRec
.Height
;
106 PanelType
:= PanelRec
.PanelType
;
144 if ByteBool(PanelRec
.Flags
and PANEL_FLAG_HIDE
) then
146 SetLength(FTextureIDs
, 0);
150 // Ïàíåëè, íå èñïîëüçóþùèå òåêñòóðû:
151 if ByteBool(PanelType
and
156 PANEL_BLOCKMON
)) then
158 SetLength(FTextureIDs
, 0);
163 // Åñëè ýòî æèäêîñòü áåç òåêñòóðû - ñïåöòåêñòóðó:
164 if WordBool(PanelType
and (PANEL_WATER
or PANEL_ACID1
or PANEL_ACID2
)) and
165 (not ByteBool(PanelRec
.Flags
and PANEL_FLAG_WATERTEXTURES
)) then
167 SetLength(FTextureIDs
, 1);
168 FTextureIDs
[0].Anim
:= False;
170 case PanelRec
.PanelType
of
172 FTextureIDs
[0].Tex
:= TEXTURE_SPECIAL_WATER
;
174 FTextureIDs
[0].Tex
:= TEXTURE_SPECIAL_ACID1
;
176 FTextureIDs
[0].Tex
:= TEXTURE_SPECIAL_ACID2
;
183 SetLength(FTextureIDs
, Length(AddTextures
));
188 if CurTex
>= Length(FTextureIDs
) then
189 FCurTexture
:= Length(FTextureIDs
) - 1
191 FCurTexture
:= CurTex
;
193 for i
:= 0 to Length(FTextureIDs
)-1 do
195 FTextureIDs
[i
].Anim
:= AddTextures
[i
].Anim
;
196 if FTextureIDs
[i
].Anim
then
197 begin // Àíèìèðîâàííàÿ òåêñòóðà
198 FTextureIDs
[i
].AnTex
:=
199 TAnimation
.Create(Textures
[AddTextures
[i
].Texture
].FramesID
,
200 True, Textures
[AddTextures
[i
].Texture
].Speed
);
201 FTextureIDs
[i
].AnTex
.Blending
:= ByteBool(PanelRec
.Flags
and PANEL_FLAG_BLENDING
);
202 FTextureIDs
[i
].AnTex
.Alpha
:= PanelRec
.Alpha
;
206 begin // Îáû÷íàÿ òåêñòóðà
207 FTextureIDs
[i
].Tex
:= Textures
[AddTextures
[i
].Texture
].TextureID
;
211 // Òåêñòóð íåñêîëüêî - íóæíî ñîõðàíÿòü òåêóùóþ:
212 if Length(FTextureIDs
) > 1 then
215 // Åñëè íå ñïåöòåêñòóðà, òî çàäàåì ðàçìåðû:
216 if PanelRec
.TextureNum
> High(Textures
) then
218 e_WriteLog(Format('WTF?! PanelRec.TextureNum is out of limits! (%d : %d)', [PanelRec
.TextureNum
, High(Textures
)]), MSG_FATALERROR
);
222 FBlending
:= ByteBool(0);
224 else if not g_Map_IsSpecialTexture(Textures
[PanelRec
.TextureNum
].TextureName
) then
226 FTextureWidth
:= Textures
[PanelRec
.TextureNum
].Width
;
227 FTextureHeight
:= Textures
[PanelRec
.TextureNum
].Height
;
228 FAlpha
:= PanelRec
.Alpha
;
229 FBlending
:= ByteBool(PanelRec
.Flags
and PANEL_FLAG_BLENDING
);
233 destructor TPanel
.Destroy();
237 for i
:= 0 to High(FTextureIDs
) do
238 if FTextureIDs
[i
].Anim
then
239 FTextureIDs
[i
].AnTex
.Free();
240 SetLength(FTextureIDs
, 0);
245 procedure TPanel
.Draw();
251 if Enabled
and (FCurTexture
>= 0) and
252 (Width
> 0) and (Height
> 0) and (FAlpha
< 255) and
253 g_Collide(X
, Y
, Width
, Height
,
254 sX
, sY
, sWidth
, sHeight
) then
256 if FTextureIDs
[FCurTexture
].Anim
then
257 begin // Àíèìèðîâàííàÿ òåêñòóðà
258 if FTextureIDs
[FCurTexture
].AnTex
= nil then
261 for xx
:= 0 to (Width
div FTextureWidth
)-1 do
262 for yy
:= 0 to (Height
div FTextureHeight
)-1 do
263 FTextureIDs
[FCurTexture
].AnTex
.Draw(
264 X
+ xx
*FTextureWidth
,
265 Y
+ yy
*FTextureHeight
, M_NONE
);
268 begin // Îáû÷íàÿ òåêñòóðà
269 case FTextureIDs
[FCurTexture
].Tex
of
270 TEXTURE_SPECIAL_WATER
:
271 e_DrawFillQuad(X
, Y
, X
+Width
-1, Y
+Height
-1,
272 0, 0, 255, 0, B_FILTER
);
273 TEXTURE_SPECIAL_ACID1
:
274 e_DrawFillQuad(X
, Y
, X
+Width
-1, Y
+Height
-1,
275 0, 128, 0, 0, B_FILTER
);
276 TEXTURE_SPECIAL_ACID2
:
277 e_DrawFillQuad(X
, Y
, X
+Width
-1, Y
+Height
-1,
278 128, 0, 0, 0, B_FILTER
);
280 if g_Texture_Get('NOTEXTURE', NoTextureID
) then
282 e_GetTextureSize(NoTextureID
, @NW
, @NH
);
283 e_DrawFill(NoTextureID
, X
, Y
, Width
div NW
, Height
div NH
,
287 xx
:= X
+ (Width
div 2);
288 yy
:= Y
+ (Height
div 2);
289 e_DrawFillQuad(X
, Y
, xx
, yy
,
291 e_DrawFillQuad(xx
, Y
, X
+Width
-1, yy
,
293 e_DrawFillQuad(X
, yy
, xx
, Y
+Height
-1,
295 e_DrawFillQuad(xx
, yy
, X
+Width
-1, Y
+Height
-1,
300 e_DrawFill(FTextureIDs
[FCurTexture
].Tex
, X
, Y
,
301 Width
div FTextureWidth
,
302 Height
div FTextureHeight
,
303 FAlpha
, True, FBlending
);
309 procedure TPanel
.Update();
311 if Enabled
and (FCurTexture
>= 0) and
312 (FTextureIDs
[FCurTexture
].Anim
) and
313 (FTextureIDs
[FCurTexture
].AnTex
<> nil) and
314 (Width
> 0) and (Height
> 0) and (FAlpha
< 255) then
316 FTextureIDs
[FCurTexture
].AnTex
.Update();
317 FCurFrame
:= FTextureIDs
[FCurTexture
].AnTex
.CurrentFrame
;
318 FCurFrameCount
:= FTextureIDs
[FCurTexture
].AnTex
.CurrentCounter
;
322 procedure TPanel
.SetFrame(Frame
: Integer; Count
: Byte);
324 function ClampInt(X
, A
, B
: Integer): Integer;
327 if X
< A
then Result
:= A
else if X
> B
then Result
:= B
;
331 if Enabled
and (FCurTexture
>= 0) and
332 (FTextureIDs
[FCurTexture
].Anim
) and
333 (FTextureIDs
[FCurTexture
].AnTex
<> nil) and
334 (Width
> 0) and (Height
> 0) and (FAlpha
< 255) then
336 FCurFrame
:= ClampInt(Frame
, 0, FTextureIDs
[FCurTexture
].AnTex
.TotalFrames
);
337 FCurFrameCount
:= Count
;
338 FTextureIDs
[FCurTexture
].AnTex
.CurrentFrame
:= FCurFrame
;
339 FTextureIDs
[FCurTexture
].AnTex
.CurrentCounter
:= FCurFrameCount
;
343 procedure TPanel
.NextTexture(AnimLoop
: Byte = 0);
345 Assert(FCurTexture
>= -1, 'FCurTexture < -1');
348 if Length(FTextureIDs
) = 0 then
351 // Òîëüêî îäíà òåêñòóðà:
352 if Length(FTextureIDs
) = 1 then
354 if FCurTexture
= 0 then
360 // Áîëüøå îäíîé òåêñòóðû:
364 // Ñëåäóþùåé íåò - âîçâðàò ê íà÷àëó:
365 if FCurTexture
>= Length(FTextureIDs
) then
369 // Ïåðåêëþ÷èëèñü íà âèäèìóþ àíèì. òåêñòóðó:
370 if (FCurTexture
>= 0) and FTextureIDs
[FCurTexture
].Anim
then
372 if (FTextureIDs
[FCurTexture
].AnTex
= nil) then
374 g_FatalError(_lc
[I_GAME_ERROR_SWITCH_TEXTURE
]);
379 FTextureIDs
[FCurTexture
].AnTex
.Loop
:= True
382 FTextureIDs
[FCurTexture
].AnTex
.Loop
:= False;
384 FTextureIDs
[FCurTexture
].AnTex
.Reset();
387 LastAnimLoop
:= AnimLoop
;
390 procedure TPanel
.SetTexture(ID
: Integer; AnimLoop
: Byte = 0);
393 if Length(FTextureIDs
) = 0 then
396 // Òîëüêî îäíà òåêñòóðà:
397 if Length(FTextureIDs
) = 1 then
399 if (ID
= 0) or (ID
= -1) then
403 // Áîëüøå îäíîé òåêñòóðû:
405 if (ID
>= -1) and (ID
<= High(FTextureIDs
)) then
409 // Ïåðåêëþ÷èëèñü íà âèäèìóþ àíèì. òåêñòóðó:
410 if (FCurTexture
>= 0) and FTextureIDs
[FCurTexture
].Anim
then
412 if (FTextureIDs
[FCurTexture
].AnTex
= nil) then
414 g_FatalError(_lc
[I_GAME_ERROR_SWITCH_TEXTURE
]);
419 FTextureIDs
[FCurTexture
].AnTex
.Loop
:= True
422 FTextureIDs
[FCurTexture
].AnTex
.Loop
:= False;
424 FTextureIDs
[FCurTexture
].AnTex
.Reset();
427 LastAnimLoop
:= AnimLoop
;
430 function TPanel
.GetTextureID(): DWORD
;
432 Result
:= TEXTURE_NONE
;
434 if (FCurTexture
>= 0) then
436 if FTextureIDs
[FCurTexture
].Anim
then
437 Result
:= FTextureIDs
[FCurTexture
].AnTex
.FramesID
439 Result
:= FTextureIDs
[FCurTexture
].Tex
;
443 function TPanel
.GetTextureCount(): Integer;
445 Result
:= Length(FTextureIDs
);
446 if Enabled
and (FCurTexture
>= 0) then
447 if (FTextureIDs
[FCurTexture
].Anim
) and
448 (FTextureIDs
[FCurTexture
].AnTex
<> nil) and
449 (Width
> 0) and (Height
> 0) and (FAlpha
< 255) then
450 Result
:= Result
+ 100;
453 procedure TPanel
.SaveState(Var Mem
: TBinMemoryWriter
);
458 if (not SaveIt
) or (Mem
= nil) then
462 sig
:= PANEL_SIGNATURE
; // 'PANL'
464 // Îòêðûòà/çàêðûòà, åñëè äâåðü:
465 Mem
.WriteBoolean(Enabled
);
466 // Íàïðàâëåíèå ëèôòà, åñëè ëèôò:
467 Mem
.WriteByte(LiftType
);
468 // Íîìåð òåêóùåé òåêñòóðû:
469 Mem
.WriteInt(FCurTexture
);
470 // Àíèìèðîâàííàÿ ëè òåêóùàÿ òåêñòóðà:
471 if (FCurTexture
>= 0) and (FTextureIDs
[FCurTexture
].Anim
) then
473 Assert(FTextureIDs
[FCurTexture
].AnTex
<> nil,
474 'TPanel.SaveState: No animation object');
479 Mem
.WriteBoolean(anim
);
480 // Åñëè äà - ñîõðàíÿåì àíèìàöèþ:
482 FTextureIDs
[FCurTexture
].AnTex
.SaveState(Mem
);
485 procedure TPanel
.LoadState(var Mem
: TBinMemoryReader
);
490 if (not SaveIt
) or (Mem
= nil) then
495 if sig
<> PANEL_SIGNATURE
then // 'PANL'
497 raise EBinSizeError
.Create('TPanel.LoadState: Wrong Panel Signature');
499 // Îòêðûòà/çàêðûòà, åñëè äâåðü:
500 Mem
.ReadBoolean(Enabled
);
501 // Íàïðàâëåíèå ëèôòà, åñëè ëèôò:
502 Mem
.ReadByte(LiftType
);
503 // Íîìåð òåêóùåé òåêñòóðû:
504 Mem
.ReadInt(FCurTexture
);
505 // Àíèìèðîâàííàÿ ëè òåêóùàÿ òåêñòóðà:
506 Mem
.ReadBoolean(anim
);
507 // Åñëè äà - çàãðóæàåì àíèìàöèþ:
510 Assert((FCurTexture
>= 0) and
511 (FTextureIDs
[FCurTexture
].Anim
) and
512 (FTextureIDs
[FCurTexture
].AnTex
<> nil),
513 'TPanel.LoadState: No animation object');
514 FTextureIDs
[FCurTexture
].AnTex
.LoadState(Mem
);