DEADSOFTWARE

render: use only r_render to access render-specific info
[d2df-sdl.git] / src / game / opengl / r_gui.pas
1 (* Copyright (C) Doom 2D: Forever Developers
2 *
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.
6 *
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.
11 *
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/>.
14 *)
15 {$INCLUDE ../../shared/a_modes.inc}
16 unit r_gui;
18 interface
20 uses g_gui;
22 procedure r_GUI_Load;
23 procedure r_GUI_Free;
25 procedure r_GUI_GetSize (ctrl: TGUIControl; out w, h: Integer);
26 procedure r_GUI_GetLogoSize (out w, h: Integer);
27 procedure r_GUI_GetMaxFontSize (BigFont: Boolean; out w, h: Integer);
28 procedure r_GUI_GetStringSize (BigFont: Boolean; str: String; out w, h: Integer);
30 procedure r_GUI_Draw_Window (win: TGUIWindow);
32 implementation
34 uses
35 Classes, Math,
36 MAPDEF, utils,
37 g_basic, g_base, e_input, g_options,
38 r_graphics, r_textures, r_playermodel, r_game,
39 g_game, g_menu
40 ;
42 const
43 BOX1 = 'BOX1';
44 BOX2 = 'BOX2';
45 BOX3 = 'BOX3';
46 BOX4 = 'BOX4';
47 BOX5 = 'BOX5';
48 BOX6 = 'BOX6';
49 BOX7 = 'BOX7';
50 BOX8 = 'BOX8';
51 BOX9 = 'BOX9';
53 MAINMENU_MARKER1 = 'MAINMENU_MARKER1';
54 MAINMENU_MARKER2 = 'MAINMENU_MARKER2';
55 SCROLL_LEFT = 'SCROLL_LEFT';
56 SCROLL_RIGHT = 'SCROLL_RIGHT';
57 SCROLL_MIDDLE = 'SCROLL_MIDDLE';
58 SCROLL_MARKER = 'SCROLL_MARKER';
59 EDIT_LEFT = 'EDIT_LEFT';
60 EDIT_RIGHT = 'EDIT_RIGHT';
61 EDIT_MIDDLE = 'EDIT_MIDDLE';
62 EDIT_CURSORCOLOR: TRGB = (R:200; G:0; B:0);
63 EDIT_CURSORLEN = 10;
64 BSCROLL_UPA = 'BSCROLL_UP_A';
65 BSCROLL_UPU = 'BSCROLL_UP_U';
66 BSCROLL_DOWNA = 'BSCROLL_DOWN_A';
67 BSCROLL_DOWNU = 'BSCROLL_DOWN_U';
68 BSCROLL_MIDDLE = 'BSCROLL_MIDDLE';
70 type
71 TFontType = (Texture, Character);
73 TFont = class{$IFDEF USE_MEMPOOL}(TPoolObject){$ENDIF}
74 private
75 FID: DWORD;
76 FScale: Single;
77 FFontType: TFontType;
78 public
79 constructor Create(FontID: DWORD; FontType: TFontType);
80 destructor Destroy; override;
81 procedure Draw(X, Y: Integer; Text: string; R, G, B: Byte);
82 procedure GetTextSize(Text: string; var w, h: Word);
83 property Scale: Single read FScale write FScale;
84 property ID: DWORD read FID;
85 end;
87 var
88 Box: Array [0..8] of DWORD;
89 MarkerID: array [Boolean] of DWORD;
90 ScrollLeft, ScrollRight, ScrollMiddle, ScrollMarker: DWORD;
91 EditLeft, EditRight, EditMiddle: DWORD;
93 Font: array [boolean] of TFont; (* Small[FALSE] / Big[TRUE] *)
94 LogoTex: DWORD;
96 constructor TFont.Create (FontID: DWORD; FontType: TFontType);
97 begin
98 FID := FontID;
99 FScale := 1;
100 FFontType := FontType;
101 end;
103 destructor TFont.Destroy;
104 begin
105 inherited;
106 end;
108 procedure TFont.Draw (X, Y: Integer; Text: string; R, G, B: Byte);
109 begin
110 if FFontType = TFontType.Character then
111 e_CharFont_PrintEx(ID, X, Y, Text, _RGB(R, G, B), FScale)
112 else
113 e_TextureFontPrintEx(X, Y, Text, ID, R, G, B, FScale)
114 end;
116 procedure TFont.GetTextSize (Text: string; var w, h: Word);
117 var cw, ch: Byte;
118 begin
119 if FFontType = TFontType.Character then
120 e_CharFont_GetSize(ID, Text, w, h)
121 else
122 begin
123 e_TextureFontGetSize(ID, cw, ch);
124 w := cw * Length(Text);
125 h := ch;
126 end;
127 w := Round(w * FScale);
128 h := Round(h * FScale);
129 end;
131 procedure r_GUI_GetMaxFontSize (BigFont: Boolean; out w, h: Integer);
132 var f: TFont;
133 begin
134 f := Font[BigFont];
135 w := e_CharFont_GetMaxWidth(f.ID);
136 h := e_CharFont_GetMaxHeight(f.ID);
137 end;
139 procedure r_GUI_GetStringSize (BigFont: Boolean; str: String; out w, h: Integer);
140 var ww, hh: WORD;
141 begin
142 e_CharFont_GetSize(Font[BigFont].ID, str, ww, hh);
143 w := ww;
144 h := hh;
145 end;
147 procedure r_GUI_GetLogoSize (out w, h: Integer);
148 var ww, hh: WORD;
149 begin
150 ww := 0;
151 hh := 0;
152 if LogoTex <> 0 then
153 e_GetTextureSize(LogoTex, @ww, @hh);
154 w := ww;
155 h := hh;
156 end;
158 procedure r_GUI_Load;
159 begin
160 g_Texture_CreateWADEx('MAINMENU_LOGO', GameWAD + ':TEXTURES\MAINLOGO');
161 g_Texture_CreateWADEx('MAINMENU_MARKER1', GameWAD + ':TEXTURES\MARKER1');
162 g_Texture_CreateWADEx('MAINMENU_MARKER2', GameWAD + ':TEXTURES\MARKER2');
163 g_Texture_CreateWADEx('SCROLL_LEFT', GameWAD + ':TEXTURES\SLEFT');
164 g_Texture_CreateWADEx('SCROLL_RIGHT', GameWAD + ':TEXTURES\SRIGHT');
165 g_Texture_CreateWADEx('SCROLL_MIDDLE', GameWAD + ':TEXTURES\SMIDDLE');
166 g_Texture_CreateWADEx('SCROLL_MARKER', GameWAD + ':TEXTURES\SMARKER');
167 g_Texture_CreateWADEx('EDIT_LEFT', GameWAD + ':TEXTURES\ELEFT');
168 g_Texture_CreateWADEx('EDIT_RIGHT', GameWAD + ':TEXTURES\ERIGHT');
169 g_Texture_CreateWADEx('EDIT_MIDDLE', GameWAD + ':TEXTURES\EMIDDLE');
170 g_Texture_CreateWADEx('BOX1', GameWAD + ':TEXTURES\BOX1');
171 g_Texture_CreateWADEx('BOX2', GameWAD + ':TEXTURES\BOX2');
172 g_Texture_CreateWADEx('BOX3', GameWAD + ':TEXTURES\BOX3');
173 g_Texture_CreateWADEx('BOX4', GameWAD + ':TEXTURES\BOX4');
174 g_Texture_CreateWADEx('BOX5', GameWAD + ':TEXTURES\BOX5');
175 g_Texture_CreateWADEx('BOX6', GameWAD + ':TEXTURES\BOX6');
176 g_Texture_CreateWADEx('BOX7', GameWAD + ':TEXTURES\BOX7');
177 g_Texture_CreateWADEx('BOX8', GameWAD + ':TEXTURES\BOX8');
178 g_Texture_CreateWADEx('BOX9', GameWAD + ':TEXTURES\BOX9');
179 g_Texture_CreateWADEx('BSCROLL_UP_A', GameWAD + ':TEXTURES\SCROLLUPA');
180 g_Texture_CreateWADEx('BSCROLL_UP_U', GameWAD + ':TEXTURES\SCROLLUPU');
181 g_Texture_CreateWADEx('BSCROLL_DOWN_A', GameWAD + ':TEXTURES\SCROLLDOWNA');
182 g_Texture_CreateWADEx('BSCROLL_DOWN_U', GameWAD + ':TEXTURES\SCROLLDOWNU');
183 g_Texture_CreateWADEx('BSCROLL_MIDDLE', GameWAD + ':TEXTURES\SCROLLMIDDLE');
184 g_Texture_CreateWADEx('NOPIC', GameWAD + ':TEXTURES\NOPIC');
186 g_Texture_Get(MAINMENU_MARKER1, MarkerID[FALSE]);
187 g_Texture_Get(MAINMENU_MARKER2, MarkerID[TRUE]);
189 g_Texture_Get(BOX1, Box[0]);
190 g_Texture_Get(BOX2, Box[1]);
191 g_Texture_Get(BOX3, Box[2]);
192 g_Texture_Get(BOX4, Box[3]);
193 g_Texture_Get(BOX5, Box[4]);
194 g_Texture_Get(BOX6, Box[5]);
195 g_Texture_Get(BOX7, Box[6]);
196 g_Texture_Get(BOX8, Box[7]);
197 g_Texture_Get(BOX9, Box[8]);
199 g_Texture_Get(SCROLL_LEFT, ScrollLeft);
200 g_Texture_Get(SCROLL_RIGHT, ScrollRight);
201 g_Texture_Get(SCROLL_MIDDLE, ScrollMiddle);
202 g_Texture_Get(SCROLL_MARKER, ScrollMarker);
204 g_Texture_Get(EDIT_LEFT, EditLeft);
205 g_Texture_Get(EDIT_RIGHT, EditRight);
206 g_Texture_Get(EDIT_MIDDLE, EditMiddle);
208 Font[FALSE] := TFont.Create(gMenuSmallFont, TFontType.Character);
209 Font[TRUE] := TFont.Create(gMenuFont, TFontType.Character);
211 g_Texture_Get('MAINMENU_LOGO', LogoTex)
212 end;
214 procedure r_GUI_Free;
215 begin
216 g_Texture_Delete('MAINMENU_LOGO');
217 g_Texture_Delete('MAINMENU_MARKER1');
218 g_Texture_Delete('MAINMENU_MARKER2');
219 g_Texture_Delete('SCROLL_LEFT');
220 g_Texture_Delete('SCROLL_RIGHT');
221 g_Texture_Delete('SCROLL_MIDDLE');
222 g_Texture_Delete('SCROLL_MARKER');
223 g_Texture_Delete('EDIT_LEFT');
224 g_Texture_Delete('EDIT_RIGHT');
225 g_Texture_Delete('EDIT_MIDDLE');
226 g_Texture_Delete('BOX1');
227 g_Texture_Delete('BOX2');
228 g_Texture_Delete('BOX3');
229 g_Texture_Delete('BOX4');
230 g_Texture_Delete('BOX5');
231 g_Texture_Delete('BOX6');
232 g_Texture_Delete('BOX7');
233 g_Texture_Delete('BOX8');
234 g_Texture_Delete('BOX9');
235 g_Texture_Delete('BSCROLL_UP_A');
236 g_Texture_Delete('BSCROLL_UP_U');
237 g_Texture_Delete('BSCROLL_DOWN_A');
238 g_Texture_Delete('BSCROLL_DOWN_U');
239 g_Texture_Delete('BSCROLL_MIDDLE');
240 g_Texture_Delete('NOPIC');
241 end;
243 procedure r_GUI_GetSize_TextButton (ctrl: TGUITextButton; out w, h: Integer);
244 var ww, hh: WORD; f: TFont;
245 begin
246 f := Font[ctrl.BigFont];
247 f.GetTextSize(ctrl.Caption, ww, hh);
248 w := ww;
249 h := hh;
250 end;
252 procedure r_GUI_GetSize_Label (ctrl: TGUILabel; out w, h: Integer);
253 var ww, hh: WORD; f: TFont;
254 begin
255 f := Font[ctrl.BigFont];
256 f.GetTextSize(ctrl.Text, ww, hh);
257 h := hh;
258 if ctrl.FixedLength = 0 then
259 w := ww
260 else
261 w := e_CharFont_GetMaxWidth(f.ID) * ctrl.FixedLength
262 end;
264 procedure r_GUI_GetSize_Switch (ctrl: TGUISwitch; out w, h: Integer);
265 var i: Integer; ww, hh: WORD; f: TFont;
266 begin
267 w := 0;
268 h := 0;
269 if ctrl.Items <> nil then
270 begin
271 for i := 0 to High(ctrl.Items) do
272 begin
273 f := Font[ctrl.BigFont];
274 f.GetTextSize(ctrl.Items[i], ww, hh);
275 if ww > w then
276 w := ww;
277 end;
278 end;
279 end;
281 procedure r_GUI_GetSize_KeyRead (ctrl: TGUIKeyRead; out w, h: Integer);
282 var i: Integer; ww, hh: WORD; f: TFont;
283 begin
284 w := 0;
285 h := 0; // ??? always 0
286 f := Font[ctrl.BigFont];
287 for i := 0 to 255 do
288 begin
289 f.GetTextSize(e_KeyNames[i], ww, hh);
290 w := MAX(w, ww);
291 end;
292 f.GetTextSize(KEYREAD_QUERY, ww, hh);
293 if ww > w then w := ww;
294 f.GetTextSize(KEYREAD_CLEAR, ww, hh);
295 if ww > w then w := ww;
296 end;
298 procedure r_GUI_GetSize (ctrl: TGUIControl; out w, h: Integer);
299 begin
300 w := 0;
301 h := 0;
302 if ctrl is TGUITextButton then
303 r_GUI_GetSize_TextButton(ctrl as TGUITextButton, w, h)
304 else if ctrl is TGUILabel then
305 r_GUI_GetSize_Label(ctrl as TGUILabel, w, h)
306 else if ctrl is TGUIScroll then
307 w := 16 + ((ctrl as TGUIScroll).Max + 1) * 8 // ??? but h = 0
308 else if ctrl is TGUISwitch then
309 r_GUI_GetSize_Switch(ctrl as TGUISwitch, w, h)
310 else if ctrl is TGUIEdit then
311 w := 16 + (ctrl as TGUIEdit).Width * 16 // ??? but h = 0
312 else if ctrl is TGUIKeyRead then
313 r_GUI_GetSize_KeyRead(ctrl as TGUIKeyRead, w, h)
314 else if ctrl is TGUIKeyRead2 then
315 w := (ctrl as TGUIKeyRead2).MaxKeyNameWdt * 2 + 8 + 8 + 16 // ??? but h = 0
316 else if ctrl is TGUIListBox then
317 begin
318 w := 8 + ((ctrl as TGUIListBox).Width + 1) * 16; // recheck w & h
319 h := 8 + (ctrl as TGUIListBox).Height * 16;
320 end
321 else if ctrl is TGUIMemo then
322 begin
323 w := 8 + ((ctrl as TGUIMemo).Width + 1) * 16;
324 h := 8 + (ctrl as TGUIMemo).Height * 16;
325 end
326 else
327 begin
328 w := ctrl.GetWidth();
329 h := ctrl.GetHeight();
330 end;
331 end;
333 procedure r_GUI_Draw_Control (ctrl: TGUIControl); forward;
335 procedure r_GUI_Draw_TextButton (ctrl: TGUITextButton);
336 var f: TFont;
337 begin
338 f := Font[ctrl.BigFont];
339 f.Draw(ctrl.X, ctrl.Y, ctrl.Caption, ctrl.Color.R, ctrl.Color.G, ctrl.Color.B)
340 end;
342 procedure r_GUI_Draw_Label (ctrl: TGUILabel);
343 var w, h: Word; f: TFont;
344 begin
345 f := Font[ctrl.BigFont];
346 if ctrl.RightAlign then
347 begin
348 f.GetTextSize(ctrl.Text, w, h);
349 f.Draw(ctrl.X + ctrl.CMaxWidth - w, ctrl.Y, ctrl.Text, ctrl.Color.R, ctrl.Color.G, ctrl.Color.B);
350 end
351 else
352 f.Draw(ctrl.X, ctrl.Y, ctrl.Text, ctrl.Color.R, ctrl.Color.G, ctrl.Color.B);
353 end;
355 procedure r_GUI_Draw_Scroll (ctrl: TGUIScroll);
356 var a: Integer;
357 begin
358 e_Draw(ScrollLeft, ctrl.X, ctrl.Y, 0, True, False);
359 e_Draw(ScrollRight, ctrl.X + 8 + (ctrl.Max + 1) * 8, ctrl.Y, 0, True, False);
360 for a := 0 to ctrl.Max do
361 e_Draw(ScrollMiddle, ctrl.X + 8 + a * 8, ctrl.Y, 0, True, False);
362 e_Draw(ScrollMarker, ctrl.X + 8 + ctrl.Value * 8, ctrl.Y, 0, True, False);
363 end;
365 procedure r_GUI_Draw_Switch (ctrl: TGUISwitch);
366 var f: TFont;
367 begin
368 f := Font[ctrl.BigFont];
369 f.Draw(ctrl.X, ctrl.Y, ctrl.Items[ctrl.ItemIndex], ctrl.Color.R, ctrl.Color.G, ctrl.Color.B);
370 end;
372 procedure r_GUI_Draw_Edit (ctrl: TGUIEdit);
373 var c, w, h: Word; r, g, b: Byte; f: TFont;
374 begin
375 e_Draw(EditLeft, ctrl.X, ctrl.Y, 0, True, False);
376 e_Draw(EditRight, ctrl.X + 8 + ctrl.Width * 16, ctrl.Y, 0, True, False);
377 for c := 0 to ctrl.Width - 1 do
378 e_Draw(EditMiddle, ctrl.X + 8 + c * 16, ctrl.Y, 0, True, False);
379 r := ctrl.Color.R;
380 g := ctrl.Color.G;
381 b := ctrl.Color.B;
382 if ctrl.Invalid and (ctrl.Window.ActiveControl <> ctrl) then
383 begin
384 r := 128;
385 g := 128;
386 b := 128;
387 end;
388 f := Font[ctrl.BigFont];
389 f.Draw(ctrl.X + 8, ctrl.Y, ctrl.Text, r, g, b);
390 if ctrl.Window.ActiveControl = ctrl then
391 begin
392 f.GetTextSize(Copy(ctrl.Text, 1, ctrl.CaretPos), w, h);
393 h := e_CharFont_GetMaxHeight(f.ID);
394 e_DrawLine(2, ctrl.X + 8 + w, ctrl.Y + h - 3, ctrl.X + 8 + w + EDIT_CURSORLEN, ctrl.Y + h - 3, EDIT_CURSORCOLOR.R, EDIT_CURSORCOLOR.G, EDIT_CURSORCOLOR.B);
395 end;
396 end;
398 procedure r_GUI_Draw_KeyRead (ctrl: TGUIKeyRead);
399 var k: AnsiString; f: TFont;
400 begin
401 if ctrl.IsQuery then
402 k := KEYREAD_QUERY
403 else if ctrl.Key <> 0 then
404 k := e_KeyNames[ctrl.Key]
405 else
406 k := KEYREAD_CLEAR;
407 f := Font[ctrl.BigFont];
408 f.Draw(ctrl.X, ctrl.Y, k, ctrl.Color.R, ctrl.Color.G, ctrl.Color.B);
409 end;
411 procedure r_GUI_Draw_KeyRead2 (ctrl: TGUIKeyRead2);
413 procedure drawText (idx: Integer);
414 var x, y: Integer; r, g, b: Byte; kk: DWORD; str: AnsiString; f: TFont;
415 begin
416 if idx = 0 then kk := ctrl.Key0 else kk := ctrl.Key1;
417 y := ctrl.Y;
418 if idx = 0 then x := ctrl.X + 8 else x := ctrl.X + 8 + ctrl.MaxKeyNameWdt + 16;
419 r := 255;
420 g := 0;
421 b := 0;
422 if ctrl.KeyIdx = idx then
423 begin
424 r := 255; g := 255; b := 255;
425 end;
426 f := Font[ctrl.BigFont];
427 if ctrl.IsQuery and (ctrl.KeyIdx = idx) then
428 begin
429 f.Draw(x, y, KEYREAD_QUERY, r, g, b)
430 end
431 else
432 begin
433 if kk <> 0 then
434 str := e_KeyNames[kk]
435 else
436 str := KEYREAD_CLEAR;
437 f.Draw(x, y, str, r, g, b);
438 end
439 end;
441 begin
442 drawText(0);
443 drawText(1);
444 end;
446 procedure DrawBox(X, Y: Integer; Width, Height: Word);
447 begin
448 e_Draw(Box[0], X, Y, 0, False, False);
449 e_DrawFill(Box[1], X + 4, Y, Width * 4, 1, 0, False, False);
450 e_Draw(Box[2], X + 4 + Width * 16, Y, 0, False, False);
451 e_DrawFill(Box[3], X, Y + 4, 1, Height * 4, 0, False, False);
452 e_DrawFill(Box[4], X + 4, Y + 4, Width, Height, 0, False, False);
453 e_DrawFill(Box[5], X + 4 + Width * 16, Y + 4, 1, Height * 4, 0, False, False);
454 e_Draw(Box[6], X, Y + 4 + Height * 16, 0, False, False);
455 e_DrawFill(Box[7], X + 4, Y + 4 + Height * 16, Width * 4, 1, 0, False, False);
456 e_Draw(Box[8], X + 4 + Width * 16, Y + 4 + Height * 16, 0, False, False);
457 end;
459 procedure r_GUI_Draw_ModelView (ctrl: TGUIModelView);
460 begin
461 DrawBox(ctrl.X, ctrl.Y, 4, 4);
462 if ctrl.Model <> nil then
463 r_PlayerModel_Draw(ctrl.Model, ctrl.X + 4, ctrl.Y + 4);
464 end;
466 procedure r_GUI_Draw_MapPreview (ctrl: TGUIMapPreview);
467 var a: Integer; r, g, b: Byte;
468 begin
469 DrawBox(ctrl.X, ctrl.Y, MAPPREVIEW_WIDTH, MAPPREVIEW_HEIGHT);
470 if (ctrl.MapSize.X <= 0) or (ctrl.MapSize.Y <= 0) then
471 Exit;
472 e_DrawFillQuad(ctrl.X + 4, ctrl.Y + 4, ctrl.X + 4 + Trunc(ctrl.MapSize.X / ctrl.Scale) - 1, ctrl.Y + 4 + Trunc(ctrl.MapSize.Y / ctrl.Scale) - 1, 32, 32, 32, 0);
473 if ctrl.MapData <> nil then
474 for a := 0 to High(ctrl.MapData) do
475 with ctrl.MapData[a] do
476 begin
477 if X1 > MAPPREVIEW_WIDTH * 16 then Continue;
478 if Y1 > MAPPREVIEW_HEIGHT * 16 then Continue;
479 if X2 < 0 then Continue;
480 if Y2 < 0 then Continue;
481 if X2 > MAPPREVIEW_WIDTH * 16 then X2 := MAPPREVIEW_WIDTH * 16;
482 if Y2 > MAPPREVIEW_HEIGHT * 16 then Y2 := MAPPREVIEW_HEIGHT * 16;
483 if X1 < 0 then X1 := 0;
484 if Y1 < 0 then Y1 := 0;
485 case PanelType of
486 PANEL_WALL:
487 begin
488 r := 255; g := 255; b := 255;
489 end;
490 PANEL_CLOSEDOOR:
491 begin
492 r := 255; g := 255; b := 0;
493 end;
494 PANEL_WATER:
495 begin
496 r := 0; g := 0; b := 192;
497 end;
498 PANEL_ACID1:
499 begin
500 r := 0; g := 176; b := 0;
501 end;
502 PANEL_ACID2:
503 begin
504 r := 176; g := 0; b := 0;
505 end;
506 else
507 r := 128; g := 128; b := 128;
508 end;
509 if ((X2 - X1) > 0) and ((Y2 - Y1) > 0) then
510 e_DrawFillQuad(ctrl.X + 4 + X1, ctrl.Y + 4 + Y1, ctrl.X + 4 + X2 - 1, ctrl.Y + 4 + Y2 - 1, r, g, b, 0);
511 end;
512 end;
514 procedure r_GUI_Draw_Image (ctrl: TGUIImage);
515 var ID: DWORD;
516 begin
517 if ctrl.ImageRes = '' then
518 begin
519 if g_Texture_Get(ctrl.DefaultRes, ID) then
520 e_Draw(ID, ctrl.X, ctrl.Y, 0, True, False);
521 end
522 else
523 begin
524 if g_Texture_CreateWADEx(ctrl.ImageRes, ctrl.ImageRes) then
525 begin
526 if g_Texture_Get(ctrl.ImageRes, ID) then
527 e_Draw(ID, ctrl.X, ctrl.Y, 0, True, False);
528 g_Texture_Delete(ctrl.ImageRes);
529 end;
530 end;
531 end;
533 procedure DrawScroll(X, Y: Integer; Height: Word; Up, Down: Boolean);
534 var ID: DWORD;
535 begin
536 if Height < 3 then
537 Exit;
538 if Up then
539 g_Texture_Get(BSCROLL_UPA, ID)
540 else
541 g_Texture_Get(BSCROLL_UPU, ID);
542 e_Draw(ID, X, Y, 0, False, False);
543 if Down then
544 g_Texture_Get(BSCROLL_DOWNA, ID)
545 else
546 g_Texture_Get(BSCROLL_DOWNU, ID);
547 e_Draw(ID, X, Y + (Height - 1) * 16, 0, False, False);
548 g_Texture_Get(BSCROLL_MIDDLE, ID);
549 e_DrawFill(ID, X, Y + 16, 1, Height - 2, 0, False, False);
550 end;
552 procedure r_GUI_Draw_ListBox (ctrl: TGUIListBox); // + TGUIFileListBox
553 var w2, h2: Word; a: Integer; s: string; f: TFont;
554 begin
555 if ctrl.DrawBack then
556 DrawBox(ctrl.X, ctrl.Y, ctrl.Width + 1, ctrl.Height);
557 if ctrl.DrawScrollBar then
558 DrawScroll(ctrl.X + 4 + ctrl.Width * 16, ctrl.Y + 4, ctrl.Height, (ctrl.StartLine > 0) and (ctrl.Items <> nil), (ctrl.StartLine + ctrl.Height - 1 < High(ctrl.Items)) and (ctrl.Items <> nil));
559 if ctrl.Items <> nil then
560 begin
561 f := Font[ctrl.BigFont];
562 for a := ctrl.StartLine to Min(High(ctrl.Items), ctrl.StartLine + ctrl.Height - 1) do
563 begin
564 s := ctrl.Items[a];
565 f.GetTextSize(s, w2, h2);
566 while (Length(s) > 0) and (w2 > ctrl.Width * 16) do
567 begin
568 SetLength(s, Length(s) - 1);
569 f.GetTextSize(s, w2, h2);
570 end;
571 if a = ctrl.ItemIndex then
572 f.Draw(ctrl.X + 4, ctrl.Y + 4 + (a - ctrl.StartLine) * 16, s, ctrl.ActiveColor.R, ctrl.ActiveColor.G, ctrl.ActiveColor.B)
573 else
574 f.Draw(ctrl.X + 4, ctrl.Y + 4 + (a - ctrl.StartLine) * 16, s, ctrl.UnActiveColor.R, ctrl.UnActiveColor.G, ctrl.UnActiveColor.B);
575 end;
576 end;
577 end;
579 procedure r_GUI_Draw_Memo (ctrl: TGUIMemo);
580 var a: Integer; f: TFont;
581 begin
582 f := Font[ctrl.BigFont];
583 if ctrl.DrawBack then
584 DrawBox(ctrl.X, ctrl.Y, ctrl.Width + 1, ctrl.Height);
585 if ctrl.DrawScrollBar then
586 DrawScroll(ctrl.X + 4 + ctrl.Width * 16, ctrl.Y + 4, ctrl.Height, (ctrl.StartLine > 0) and (ctrl.Lines <> nil), (ctrl.StartLine + ctrl.Height - 1 < High(ctrl.Lines)) and (ctrl.Lines <> nil));
587 if ctrl.Lines <> nil then
588 for a := ctrl.StartLine to Min(High(ctrl.Lines), ctrl.StartLine + ctrl.Height - 1) do
589 f.Draw(ctrl.X + 4, ctrl.Y + 4 + (a - ctrl.StartLine) * 16, ctrl.Lines[a], ctrl.Color.R, ctrl.Color.G, ctrl.Color.B);
590 end;
592 procedure r_GUI_Draw_MainMenu (ctrl: TGUIMainMenu);
593 var a: Integer; w, h: Word; ID: DWORD;
594 begin
595 if ctrl.Header <> nil then
596 begin
597 r_GUI_Draw_Label(ctrl.Header)
598 end
599 else if LogoTex <> 0 then
600 begin
601 e_GetTextureSize(LogoTex, @w, @h);
602 e_Draw(LogoTex, ((gScreenWidth div 2) - (w div 2)), ctrl.Buttons[0].Y - ctrl.Buttons[0].GetHeight - h, 0, True, False);
603 end;
604 if ctrl.Buttons <> nil then
605 begin
606 for a := 0 to High(ctrl.Buttons) do
607 if ctrl.Buttons[a] <> nil then
608 r_GUI_Draw_TextButton(ctrl.Buttons[a]);
609 if ctrl.Index <> -1 then
610 begin
611 ID := MarkerID[ctrl.Counter DIV MAINMENU_MARKERDELAY MOD 2 <> 0];
612 e_Draw(ID, ctrl.Buttons[ctrl.Index].X - 48, ctrl.Buttons[ctrl.Index].Y, 0, True, False);
613 end
614 end;
615 end;
617 procedure r_GUI_Draw_Menu (ctrl: TGUIMenu);
618 var a, locx, locy: Integer; f: TFont;
619 begin
620 if ctrl.Header <> nil then
621 r_GUI_Draw_Label(ctrl.Header);
622 if ctrl.Items <> nil then
623 begin
624 for a := 0 to High(ctrl.Items) do
625 begin
626 if ctrl.Items[a].Text <> nil then
627 r_GUI_Draw_Control(ctrl.Items[a].Text);
628 if ctrl.Items[a].Control <> nil then
629 r_GUI_Draw_Control(ctrl.Items[a].Control);
630 end;
631 end;
632 if (ctrl.Index <> -1) and (ctrl.Counter > MENU_MARKERDELAY div 2) then
633 begin
634 locx := 0;
635 locy := 0;
636 if ctrl.Items[ctrl.Index].Text <> nil then
637 begin
638 locx := ctrl.Items[ctrl.Index].Text.X;
639 locy := ctrl.Items[ctrl.Index].Text.Y;
640 //HACK!
641 if ctrl.Items[ctrl.Index].Text.RightAlign then
642 begin
643 locx := locx + ctrl.Items[ctrl.Index].Text.CMaxWidth - ctrl.Items[ctrl.Index].Text.GetWidth;
644 end;
645 end
646 else if ctrl.Items[ctrl.Index].Control <> nil then
647 begin
648 locx := ctrl.Items[ctrl.Index].Control.X;
649 locy := ctrl.Items[ctrl.Index].Control.Y;
650 end;
651 f := Font[ctrl.BigFont];
652 locx := locx - e_CharFont_GetMaxWidth(f.ID);
653 e_CharFont_PrintEx(f.ID, locx, locy, #16, _RGB(255, 0, 0));
654 end;
655 end;
657 procedure r_GUI_Draw_Control (ctrl: TGUIControl);
658 begin
659 if ctrl is TGUITextButton then
660 r_GUI_Draw_TextButton(TGUITextButton(ctrl))
661 else if ctrl is TGUILabel then
662 r_GUI_Draw_Label(TGUILabel(ctrl))
663 else if ctrl is TGUIScroll then
664 r_GUI_Draw_Scroll(TGUIScroll(ctrl))
665 else if ctrl is TGUISwitch then
666 r_GUI_Draw_Switch(TGUISwitch(ctrl))
667 else if ctrl is TGUIEdit then
668 r_GUI_Draw_Edit(TGUIEdit(ctrl))
669 else if ctrl is TGUIKeyRead then
670 r_GUI_Draw_KeyRead(TGUIKeyRead(ctrl))
671 else if ctrl is TGUIKeyRead2 then
672 r_GUI_Draw_KeyRead2(TGUIKeyRead2(ctrl))
673 else if ctrl is TGUIModelView then
674 r_GUI_Draw_ModelView(TGUIModelView(ctrl))
675 else if ctrl is TGUIMapPreview then
676 r_GUI_Draw_MapPreview(TGUIMapPreview(ctrl))
677 else if ctrl is TGUIImage then
678 r_GUI_Draw_Image(TGUIImage(ctrl))
679 else if ctrl is TGUIListBox then
680 r_GUI_Draw_ListBox(TGUIListBox(ctrl)) // + TGUIFileListBox
681 else if ctrl is TGUIMemo then
682 r_GUI_Draw_Memo(TGUIMemo(ctrl))
683 else if ctrl is TGUIMainMenu then
684 r_GUI_Draw_MainMenu(TGUIMainMenu(ctrl))
685 else if ctrl is TGUIMenu then
686 r_GUI_Draw_Menu(TGUIMenu(ctrl))
687 else
688 Assert(False)
689 end;
691 procedure r_GUI_Draw_Window (win: TGUIWindow);
692 var i: Integer; ID: DWORD; tw, th: Word;
693 begin
694 // Here goes code duplication from g_game.pas:DrawMenuBackground()
695 if win.BackTexture <> '' then
696 if g_Texture_Get(win.BackTexture, ID) then
697 begin
698 e_Clear(0, 0, 0);
699 e_GetTextureSize(ID, @tw, @th);
700 if tw = th then
701 tw := round(tw * 1.333 * (gScreenHeight / th))
702 else
703 tw := trunc(tw * (gScreenHeight / th));
704 e_DrawSize(ID, (gScreenWidth - tw) div 2, 0, 0, False, False, tw, gScreenHeight);
705 end
706 else
707 e_Clear(0.5, 0.5, 0.5);
709 // small hack here
710 if win.Name = 'AuthorsMenu' then
711 e_DarkenQuadWH(0, 0, gScreenWidth, gScreenHeight, 150);
712 for i := 0 to High(win.Childs) do
713 if win.Childs[i] <> nil then
714 r_GUI_Draw_Control(win.Childs[i]);
715 end;
717 end.