DEADSOFTWARE

8a2265af842d9a546aa5eea28bd1c384875b43b1
[d2df-sdl.git] / src / game / g_panel.pas
1 unit g_panel;
3 interface
5 uses
6 MAPSTRUCT, BinEditor, g_textures;
8 type
9 TAddTextureArray = Array of
10 record
11 Texture: Cardinal;
12 Anim: Boolean;
13 end;
15 TPanel = Class (TObject)
16 private
17 FTextureWidth: Word;
18 FTextureHeight: Word;
19 FAlpha: Byte;
20 FBlending: Boolean;
21 FTextureIDs: Array of
22 record
23 case Anim: Boolean of
24 False: (Tex: Cardinal);
25 True: (AnTex: TAnimation);
26 end;
28 public
29 FCurTexture: Integer; // Íîìåð òåêóùåé òåêñòóðû
30 FCurFrame: Integer;
31 FCurFrameCount: Byte;
32 X, Y: Integer;
33 Width, Height: Word;
34 PanelType: Word;
35 SaveIt: Boolean; // Ñîõðàíÿòü ïðè SaveState?
36 Enabled: Boolean;
37 Door: Boolean;
38 LiftType: Byte;
39 LastAnimLoop: Byte;
41 constructor Create(PanelRec: TPanelRec_1;
42 AddTextures: TAddTextureArray;
43 CurTex: Integer;
44 var Textures: TLevelTextureArray);
45 destructor Destroy(); override;
47 procedure Draw();
48 procedure Update();
49 procedure SetFrame(Frame: Integer; Count: Byte);
50 procedure NextTexture(AnimLoop: Byte = 0);
51 procedure SetTexture(ID: Integer; AnimLoop: Byte = 0);
52 function GetTextureID(): Cardinal;
53 function GetTextureCount(): Integer;
55 procedure SaveState(var Mem: TBinMemoryWriter);
56 procedure LoadState(var Mem: TBinMemoryReader);
57 end;
59 TPanelArray = Array of TPanel;
61 implementation
63 uses
64 g_basic, g_map, MAPDEF, g_game, e_graphics,
65 g_console, g_language;
67 const
68 PANEL_SIGNATURE = $4C4E4150; // 'PANL'
70 { T P a n e l : }
72 constructor TPanel.Create(PanelRec: TPanelRec_1;
73 AddTextures: TAddTextureArray;
74 CurTex: Integer;
75 var Textures: TLevelTextureArray);
76 var
77 i: Integer;
78 begin
79 X := PanelRec.X;
80 Y := PanelRec.Y;
81 Width := PanelRec.Width;
82 Height := PanelRec.Height;
83 FAlpha := 0;
84 FBlending := False;
85 FCurFrame := 0;
86 FCurFrameCount := 0;
87 LastAnimLoop := 0;
89 // Òèï ïàíåëè:
90 PanelType := PanelRec.PanelType;
91 Enabled := True;
92 Door := False;
93 LiftType := 0;
94 SaveIt := False;
96 case PanelType of
97 PANEL_OPENDOOR:
98 begin
99 Enabled := False;
100 Door := True;
101 SaveIt := True;
102 end;
103 PANEL_CLOSEDOOR:
104 begin
105 Door := True;
106 SaveIt := True;
107 end;
108 PANEL_LIFTUP:
109 SaveIt := True;
110 PANEL_LIFTDOWN:
111 begin
112 LiftType := 1;
113 SaveIt := True;
114 end;
115 PANEL_LIFTLEFT:
116 begin
117 LiftType := 2;
118 SaveIt := True;
119 end;
120 PANEL_LIFTRIGHT:
121 begin
122 LiftType := 3;
123 SaveIt := True;
124 end;
125 end;
127 // Íåâèäèìàÿ:
128 if ByteBool(PanelRec.Flags and PANEL_FLAG_HIDE) then
129 begin
130 SetLength(FTextureIDs, 0);
131 FCurTexture := -1;
132 Exit;
133 end;
134 // Ïàíåëè, íå èñïîëüçóþùèå òåêñòóðû:
135 if ByteBool(PanelType and
136 (PANEL_LIFTUP or
137 PANEL_LIFTDOWN or
138 PANEL_LIFTLEFT or
139 PANEL_LIFTRIGHT or
140 PANEL_BLOCKMON)) then
141 begin
142 SetLength(FTextureIDs, 0);
143 FCurTexture := -1;
144 Exit;
145 end;
147 // Åñëè ýòî æèäêîñòü áåç òåêñòóðû - ñïåöòåêñòóðó:
148 if WordBool(PanelType and (PANEL_WATER or PANEL_ACID1 or PANEL_ACID2)) and
149 (not ByteBool(PanelRec.Flags and PANEL_FLAG_WATERTEXTURES)) then
150 begin
151 SetLength(FTextureIDs, 1);
152 FTextureIDs[0].Anim := False;
154 case PanelRec.PanelType of
155 PANEL_WATER:
156 FTextureIDs[0].Tex := TEXTURE_SPECIAL_WATER;
157 PANEL_ACID1:
158 FTextureIDs[0].Tex := TEXTURE_SPECIAL_ACID1;
159 PANEL_ACID2:
160 FTextureIDs[0].Tex := TEXTURE_SPECIAL_ACID2;
161 end;
163 FCurTexture := 0;
164 Exit;
165 end;
167 SetLength(FTextureIDs, Length(AddTextures));
169 if CurTex < 0 then
170 FCurTexture := -1
171 else
172 if CurTex >= Length(FTextureIDs) then
173 FCurTexture := Length(FTextureIDs) - 1
174 else
175 FCurTexture := CurTex;
177 for i := 0 to Length(FTextureIDs)-1 do
178 begin
179 FTextureIDs[i].Anim := AddTextures[i].Anim;
180 if FTextureIDs[i].Anim then
181 begin // Àíèìèðîâàííàÿ òåêñòóðà
182 FTextureIDs[i].AnTex :=
183 TAnimation.Create(Textures[AddTextures[i].Texture].FramesID,
184 True, Textures[AddTextures[i].Texture].Speed);
185 FTextureIDs[i].AnTex.Blending := ByteBool(PanelRec.Flags and PANEL_FLAG_BLENDING);
186 FTextureIDs[i].AnTex.Alpha := PanelRec.Alpha;
187 SaveIt := True;
188 end
189 else
190 begin // Îáû÷íàÿ òåêñòóðà
191 FTextureIDs[i].Tex := Textures[AddTextures[i].Texture].TextureID;
192 end;
193 end;
195 // Òåêñòóð íåñêîëüêî - íóæíî ñîõðàíÿòü òåêóùóþ:
196 if Length(FTextureIDs) > 1 then
197 SaveIt := True;
199 // Åñëè íå ñïåöòåêñòóðà, òî çàäàåì ðàçìåðû:
200 if not g_Map_IsSpecialTexture(Textures[PanelRec.TextureNum].TextureName) then
201 begin
202 FTextureWidth := Textures[PanelRec.TextureNum].Width;
203 FTextureHeight := Textures[PanelRec.TextureNum].Height;
204 FAlpha := PanelRec.Alpha;
205 FBlending := ByteBool(PanelRec.Flags and PANEL_FLAG_BLENDING);
206 end;
207 end;
209 destructor TPanel.Destroy();
210 var
211 i: Integer;
212 begin
213 for i := 0 to High(FTextureIDs) do
214 if FTextureIDs[i].Anim then
215 FTextureIDs[i].AnTex.Free();
216 SetLength(FTextureIDs, 0);
218 Inherited;
219 end;
221 procedure TPanel.Draw();
222 var
223 xx, yy: Integer;
224 NoTextureID: DWORD;
225 NW, NH: Word;
226 begin
227 if Enabled and (FCurTexture >= 0) and
228 (Width > 0) and (Height > 0) and (FAlpha < 255) and
229 g_Collide(X, Y, Width, Height,
230 sX, sY, sWidth, sHeight) then
231 begin
232 if FTextureIDs[FCurTexture].Anim then
233 begin // Àíèìèðîâàííàÿ òåêñòóðà
234 if FTextureIDs[FCurTexture].AnTex = nil then
235 Exit;
237 for xx := 0 to (Width div FTextureWidth)-1 do
238 for yy := 0 to (Height div FTextureHeight)-1 do
239 FTextureIDs[FCurTexture].AnTex.Draw(
240 X + xx*FTextureWidth,
241 Y + yy*FTextureHeight, M_NONE);
242 end
243 else
244 begin // Îáû÷íàÿ òåêñòóðà
245 case FTextureIDs[FCurTexture].Tex of
246 TEXTURE_SPECIAL_WATER:
247 e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1,
248 0, 0, 255, 0, B_FILTER);
249 TEXTURE_SPECIAL_ACID1:
250 e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1,
251 0, 128, 0, 0, B_FILTER);
252 TEXTURE_SPECIAL_ACID2:
253 e_DrawFillQuad(X, Y, X+Width-1, Y+Height-1,
254 128, 0, 0, 0, B_FILTER);
255 TEXTURE_NONE:
256 if g_Texture_Get('NOTEXTURE', NoTextureID) then
257 begin
258 e_GetTextureSize(NoTextureID, @NW, @NH);
259 e_DrawFill(NoTextureID, X, Y, Width div NW, Height div NH,
260 0, False, False);
261 end else
262 begin
263 xx := X + (Width div 2);
264 yy := Y + (Height div 2);
265 e_DrawFillQuad(X, Y, xx, yy,
266 255, 0, 255, 0);
267 e_DrawFillQuad(xx, Y, X+Width-1, yy,
268 255, 255, 0, 0);
269 e_DrawFillQuad(X, yy, xx, Y+Height-1,
270 255, 255, 0, 0);
271 e_DrawFillQuad(xx, yy, X+Width-1, Y+Height-1,
272 255, 0, 255, 0);
273 end;
275 else
276 e_DrawFill(FTextureIDs[FCurTexture].Tex, X, Y,
277 Width div FTextureWidth,
278 Height div FTextureHeight,
279 FAlpha, True, FBlending);
280 end;
281 end;
282 end;
283 end;
285 procedure TPanel.Update();
286 begin
287 if Enabled and (FCurTexture >= 0) and
288 (FTextureIDs[FCurTexture].Anim) and
289 (FTextureIDs[FCurTexture].AnTex <> nil) and
290 (Width > 0) and (Height > 0) and (FAlpha < 255) then
291 begin
292 FTextureIDs[FCurTexture].AnTex.Update();
293 FCurFrame := FTextureIDs[FCurTexture].AnTex.CurrentFrame;
294 FCurFrameCount := FTextureIDs[FCurTexture].AnTex.CurrentCounter;
295 end;
296 end;
298 procedure TPanel.SetFrame(Frame: Integer; Count: Byte);
300 function ClampInt(X, A, B: Integer): Integer;
301 begin
302 Result := X;
303 if X < A then Result := A else if X > B then Result := B;
304 end;
306 begin
307 if Enabled and (FCurTexture >= 0) and
308 (FTextureIDs[FCurTexture].Anim) and
309 (FTextureIDs[FCurTexture].AnTex <> nil) and
310 (Width > 0) and (Height > 0) and (FAlpha < 255) then
311 begin
312 FCurFrame := ClampInt(Frame, 0, FTextureIDs[FCurTexture].AnTex.TotalFrames);
313 FCurFrameCount := Count;
314 FTextureIDs[FCurTexture].AnTex.CurrentFrame := FCurFrame;
315 FTextureIDs[FCurTexture].AnTex.CurrentCounter := FCurFrameCount;
316 end;
317 end;
319 procedure TPanel.NextTexture(AnimLoop: Byte = 0);
320 begin
321 Assert(FCurTexture >= -1, 'FCurTexture < -1');
323 // Íåò òåêñòóð:
324 if Length(FTextureIDs) = 0 then
325 FCurTexture := -1
326 else
327 // Òîëüêî îäíà òåêñòóðà:
328 if Length(FTextureIDs) = 1 then
329 begin
330 if FCurTexture = 0 then
331 FCurTexture := -1
332 else
333 FCurTexture := 0;
334 end
335 else
336 // Áîëüøå îäíîé òåêñòóðû:
337 begin
338 // Ñëåäóþùàÿ:
339 Inc(FCurTexture);
340 // Ñëåäóþùåé íåò - âîçâðàò ê íà÷àëó:
341 if FCurTexture >= Length(FTextureIDs) then
342 FCurTexture := 0;
343 end;
345 // Ïåðåêëþ÷èëèñü íà âèäèìóþ àíèì. òåêñòóðó:
346 if (FCurTexture >= 0) and FTextureIDs[FCurTexture].Anim then
347 begin
348 if (FTextureIDs[FCurTexture].AnTex = nil) then
349 begin
350 g_FatalError(_lc[I_GAME_ERROR_SWITCH_TEXTURE]);
351 Exit;
352 end;
354 if AnimLoop = 1 then
355 FTextureIDs[FCurTexture].AnTex.Loop := True
356 else
357 if AnimLoop = 2 then
358 FTextureIDs[FCurTexture].AnTex.Loop := False;
360 FTextureIDs[FCurTexture].AnTex.Reset();
361 end;
363 LastAnimLoop := AnimLoop;
364 end;
366 procedure TPanel.SetTexture(ID: Integer; AnimLoop: Byte = 0);
367 begin
368 // Íåò òåêñòóð:
369 if Length(FTextureIDs) = 0 then
370 FCurTexture := -1
371 else
372 // Òîëüêî îäíà òåêñòóðà:
373 if Length(FTextureIDs) = 1 then
374 begin
375 if (ID = 0) or (ID = -1) then
376 FCurTexture := ID;
377 end
378 else
379 // Áîëüøå îäíîé òåêñòóðû:
380 begin
381 if (ID >= -1) and (ID <= High(FTextureIDs)) then
382 FCurTexture := ID;
383 end;
385 // Ïåðåêëþ÷èëèñü íà âèäèìóþ àíèì. òåêñòóðó:
386 if (FCurTexture >= 0) and FTextureIDs[FCurTexture].Anim then
387 begin
388 if (FTextureIDs[FCurTexture].AnTex = nil) then
389 begin
390 g_FatalError(_lc[I_GAME_ERROR_SWITCH_TEXTURE]);
391 Exit;
392 end;
394 if AnimLoop = 1 then
395 FTextureIDs[FCurTexture].AnTex.Loop := True
396 else
397 if AnimLoop = 2 then
398 FTextureIDs[FCurTexture].AnTex.Loop := False;
400 FTextureIDs[FCurTexture].AnTex.Reset();
401 end;
403 LastAnimLoop := AnimLoop;
404 end;
406 function TPanel.GetTextureID(): DWORD;
407 begin
408 Result := TEXTURE_NONE;
410 if (FCurTexture >= 0) then
411 begin
412 if FTextureIDs[FCurTexture].Anim then
413 Result := FTextureIDs[FCurTexture].AnTex.FramesID
414 else
415 Result := FTextureIDs[FCurTexture].Tex;
416 end;
417 end;
419 function TPanel.GetTextureCount(): Integer;
420 begin
421 Result := Length(FTextureIDs);
422 if Enabled and (FCurTexture >= 0) then
423 if (FTextureIDs[FCurTexture].Anim) and
424 (FTextureIDs[FCurTexture].AnTex <> nil) and
425 (Width > 0) and (Height > 0) and (FAlpha < 255) then
426 Result := Result + 100;
427 end;
429 procedure TPanel.SaveState(Var Mem: TBinMemoryWriter);
430 var
431 sig: DWORD;
432 anim: Boolean;
433 begin
434 if (not SaveIt) or (Mem = nil) then
435 Exit;
437 // Ñèãíàòóðà ïàíåëè:
438 sig := PANEL_SIGNATURE; // 'PANL'
439 Mem.WriteDWORD(sig);
440 // Îòêðûòà/çàêðûòà, åñëè äâåðü:
441 Mem.WriteBoolean(Enabled);
442 // Íàïðàâëåíèå ëèôòà, åñëè ëèôò:
443 Mem.WriteByte(LiftType);
444 // Íîìåð òåêóùåé òåêñòóðû:
445 Mem.WriteInt(FCurTexture);
446 // Àíèìèðîâàííàÿ ëè òåêóùàÿ òåêñòóðà:
447 if (FCurTexture >= 0) and (FTextureIDs[FCurTexture].Anim) then
448 begin
449 Assert(FTextureIDs[FCurTexture].AnTex <> nil,
450 'TPanel.SaveState: No animation object');
451 anim := True;
452 end
453 else
454 anim := False;
455 Mem.WriteBoolean(anim);
456 // Åñëè äà - ñîõðàíÿåì àíèìàöèþ:
457 if anim then
458 FTextureIDs[FCurTexture].AnTex.SaveState(Mem);
459 end;
461 procedure TPanel.LoadState(var Mem: TBinMemoryReader);
462 var
463 sig: DWORD;
464 anim: Boolean;
465 begin
466 if (not SaveIt) or (Mem = nil) then
467 Exit;
469 // Ñèãíàòóðà ïàíåëè:
470 Mem.ReadDWORD(sig);
471 if sig <> PANEL_SIGNATURE then // 'PANL'
472 begin
473 raise EBinSizeError.Create('TPanel.LoadState: Wrong Panel Signature');
474 end;
475 // Îòêðûòà/çàêðûòà, åñëè äâåðü:
476 Mem.ReadBoolean(Enabled);
477 // Íàïðàâëåíèå ëèôòà, åñëè ëèôò:
478 Mem.ReadByte(LiftType);
479 // Íîìåð òåêóùåé òåêñòóðû:
480 Mem.ReadInt(FCurTexture);
481 // Àíèìèðîâàííàÿ ëè òåêóùàÿ òåêñòóðà:
482 Mem.ReadBoolean(anim);
483 // Åñëè äà - çàãðóæàåì àíèìàöèþ:
484 if anim then
485 begin
486 Assert((FCurTexture >= 0) and
487 (FTextureIDs[FCurTexture].Anim) and
488 (FTextureIDs[FCurTexture].AnTex <> nil),
489 'TPanel.LoadState: No animation object');
490 FTextureIDs[FCurTexture].AnTex.LoadState(Mem);
491 end;
492 end;
494 end.