DEADSOFTWARE

gl: align hud elements
[d2df-sdl.git] / src / game / renders / opengl / r_render.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_render;
18 interface
20 uses
21 {$IFDEF ENABLE_MENU}
22 g_gui,
23 {$ENDIF}
24 g_base // TRectWH
25 ;
27 (* render startup *)
28 procedure r_Render_Initialize;
29 procedure r_Render_Finalize;
31 (* load globally used textures *)
32 procedure r_Render_Load;
33 procedure r_Render_Free;
35 (* load map specific textures *)
36 procedure r_Render_LoadTextures;
37 procedure r_Render_FreeTextures;
39 procedure r_Render_Update;
40 procedure r_Render_Draw;
42 procedure r_Render_Resize (w, h: Integer);
43 procedure r_Render_Apply;
45 function r_Render_WriteScreenShot (filename: String): Boolean;
47 {$IFDEF ENABLE_GIBS}
48 function r_Render_GetGibRect (m, id: Integer): TRectWH;
49 {$ENDIF}
51 {$IFDEF ENABLE_GFX}
52 procedure r_Render_QueueEffect (AnimType, X, Y: Integer);
53 {$ENDIF}
55 {$IFDEF ENABLE_TOUCH}
56 // touch screen button location and size
57 procedure r_Render_GetKeyRect (key: Integer; out x, y, w, h: Integer; out founded: Boolean);
58 {$ENDIF}
60 {$IFDEF ENABLE_MENU}
61 procedure r_Render_GetControlSize (ctrl: TGUIControl; out w, h: Integer);
62 procedure r_Render_GetLogoSize (out w, h: Integer);
63 procedure r_Render_GetMaxFontSize (BigFont: Boolean; out w, h: Integer);
64 procedure r_Render_GetStringSize (BigFont: Boolean; str: String; out w, h: Integer);
65 {$ENDIF}
67 procedure r_Render_DrawLoading (force: Boolean); // !!! remove it
69 implementation
71 uses
72 {$IFDEF USE_GLES1}
73 GLES11,
74 {$ELSE}
75 GL, GLEXT,
76 {$ENDIF}
77 {$IFDEF ENABLE_SYSTEM}
78 g_system,
79 {$ENDIF}
80 SysUtils, Classes, Math,
81 e_log, utils,
82 g_game, g_options, g_console, g_player, g_weapons, g_language,
83 g_net,
84 r_draw, r_textures, r_fonts, r_map
85 ;
87 type
88 TBasePoint = (
89 BP_LEFTUP, BP_UP, BP_RIGHTUP,
90 BP_LEFT, BP_CENTER, BP_RIGHT,
91 BP_LEFTDOWN, BP_DOWN, BP_RIGHTDOWN
92 );
94 var
95 menuBG: TGLTexture;
97 stdfont: TGLFont;
98 smallfont: TGLFont;
99 menufont: TGLFont;
101 hud, hudbg: TGLTexture;
102 hudhp: array [Boolean] of TGLTexture;
103 hudap: TGLTexture;
104 hudwp: array [0..WP_LAST] of TGLTexture;
105 hudkey: array [0..2] of TGLTexture;
106 hudair: TGLTexture;
107 hudjet: TGLTexture;
109 procedure r_Render_LoadTextures;
110 begin
111 r_Map_LoadTextures;
112 end;
114 procedure r_Render_FreeTextures;
115 begin
116 r_Map_FreeTextures;
117 end;
119 function r_Render_LoadFont (const name: AnsiString): TGLFont;
120 var info: TFontInfo; skiphack: Integer;
121 begin
122 result := nil;
123 if name = 'STD' then skiphack := 144 else skiphack := 0;
124 if r_Font_LoadInfoFromFile(GameWad + ':FONTS/' + name + 'TXT', info) then
125 result := r_Textures_LoadFontFromFile(GameWad + ':FONTS/' + name + 'FONT', info, skiphack, true);
126 if result = nil then
127 e_logwritefln('failed to load font %s', [name]);
128 end;
130 procedure r_Render_Load;
131 const
132 WeapName: array [0..WP_LAST] of AnsiString = ('KASTET', 'SAW', 'PISTOL', 'SHOTGUN1', 'SHOTGUN2', 'MGUN', 'RLAUNCHER', 'PGUN', 'BFG', 'SPULEMET', 'FLAMETHROWER');
133 var
134 i: Integer;
135 begin
136 menuBG := r_Textures_LoadFromFile(GameWAD + ':TEXTURES/TITLE');
137 stdfont := r_Render_LoadFont('STD');
138 smallfont := r_Render_LoadFont('SMALL');
139 menufont := r_Render_LoadFont('MENU');
140 hud := r_Textures_LoadFromFile(GameWAD + ':TEXTURES/HUD');
141 hudbg := r_Textures_LoadFromFile(GameWAD + ':TEXTURES/HUDBG');
142 hudhp[false] := r_Textures_LoadFromFile(GameWAD + ':TEXTURES/MED2');
143 hudhp[true] := r_Textures_LoadFromFile(GameWAD + ':TEXTURES/BMED');
144 hudap := r_Textures_LoadFromFile(GameWAD + ':TEXTURES/ARMORHUD');
145 for i := 0 to WP_LAST do
146 hudwp[i] := r_Textures_LoadFromFile(GameWAD + ':TEXTURES/' + WeapName[i]);
147 hudkey[0] := r_Textures_LoadFromFile(GameWAD + ':TEXTURES/KEYR');
148 hudkey[1] := r_Textures_LoadFromFile(GameWAD + ':TEXTURES/KEYG');
149 hudkey[2] := r_Textures_LoadFromFile(GameWAD + ':TEXTURES/KEYB');
150 hudair := r_Textures_LoadFromFile(GameWAD + ':TEXTURES/AIRBAR');
151 hudjet := r_Textures_LoadFromFile(GameWAD + ':TEXTURES/JETBAR');
152 r_Map_Load;
153 end;
155 procedure r_Render_Free;
156 var i: Integer;
157 begin
158 r_Map_Free;
159 hudjet.Free;
160 hudair.Free;
161 hudkey[0].Free;
162 hudkey[1].Free;
163 hudkey[2].Free;
164 for i := 0 to WP_LAST do
165 begin
166 if hudwp[i] <> nil then
167 hudwp[i].Free;
168 hudwp[i] := nil;
169 end;
170 hudap.Free;
171 hudhp[true].Free;
172 hudhp[false].Free;
173 hudbg.Free;
174 hud.Free;
175 menufont.Free;
176 smallfont.Free;
177 stdfont.Free;
178 menuBG.Free;
179 end;
181 {$IFDEF ENABLE_SYSTEM}
182 function GetInfo (): TGLDisplayInfo;
183 var info: TGLDisplayInfo;
184 begin
185 info := Default(TGLDisplayInfo);
186 info.w := Max(1, gRC_Width);
187 info.h := Max(1, gRC_Height);
188 info.bpp := Max(1, gBPP);
189 info.fullscreen := gRC_FullScreen;
190 info.maximized := gRC_Maximized;
191 info.major := 1;
192 info.minor := 1;
193 info.profile := TGLProfile.Compat;
194 result := info;
195 end;
196 {$ENDIF}
198 procedure r_Render_Initialize;
199 begin
200 {$IFDEF ENABLE_SYSTEM}
201 if sys_SetDisplayModeGL(GetInfo()) = False then
202 raise Exception.Create('Failed to set videomode on startup.');
203 sys_EnableVSync(gVSync);
204 {$ENDIF}
205 r_Textures_Initialize;
206 r_Map_Initialize;
207 end;
209 procedure r_Render_Finalize;
210 begin
211 r_Map_Finalize;
212 r_Textures_Finalize;
213 end;
215 procedure r_Render_Update;
216 begin
217 r_Map_Update;
218 end;
220 procedure SetupMatrix;
221 begin
222 glViewport(0, 0, gScreenWidth, gScreenHeight);
223 glScissor(0, 0, gScreenWidth, gScreenHeight);
224 glMatrixMode(GL_PROJECTION);
225 glLoadIdentity;
226 glOrtho(0, gScreenWidth, gScreenHeight, 0, 0, 1);
227 glMatrixMode(GL_MODELVIEW);
228 glLoadIdentity;
229 end;
231 procedure r_Render_GetBasePoint (x, y, w, h: Integer; p: TBasePoint; out xx, yy: Integer);
232 begin
233 case p of
234 TBasePoint.BP_LEFTUP, TBasePoint.BP_LEFT, TBasePoint.BP_LEFTDOWN: xx := x;
235 TBasePoint.BP_UP, TBasePoint.BP_CENTER, TBasePoint.BP_DOWN: xx := x - w div 2;
236 TBasePoint.BP_RIGHTUP, TBasePoint.BP_RIGHT, TBasePoint.BP_RIGHTDOWN: xx := x - w;
237 end;
238 case p of
239 TBasePoint.BP_LEFTUP, TBasePoint.BP_UP, TBasePoint.BP_RIGHTUP: yy := y;
240 TBasePoint.BP_LEFT, TBasePoint.BP_CENTER, TBasePoint.BP_RIGHT: yy := y - h div 2;
241 TBasePoint.BP_LEFTDOWN, TBasePoint.BP_DOWN, TBasePoint.BP_RIGHTDOWN: yy := y - h;
242 end;
243 end;
245 procedure r_Render_DrawText (const text: AnsiString; x, y: Integer; r, g, b, a: Byte; f: TGLFont; p: TBasePoint);
246 var w, h: Integer;
247 begin
248 if p <> TBasePoint.BP_LEFTUP then
249 begin
250 r_Draw_GetTextSize(text, f, w, h);
251 r_Render_GetBasePoint(x, y, w, h, p, x, y);
252 end;
253 r_Draw_Text(text, x, y, r, g, b, a, f);
254 end;
256 procedure r_Render_DrawTexture (img: TGLTexture; x, y, w, h: Integer; p: TBasePoint);
257 begin
258 r_Render_GetBasePoint(x, y, w, h, p, x, y);
259 r_Draw_TextureRepeat(img, x, y, w, h, false, 255, 255, 255, 255, false);
260 end;
262 procedure r_Render_DrawHUD (x, y: Integer; p: TPlayer);
263 var t: TGLTexture; s: AnsiString;
264 begin
265 ASSERT(p <> nil);
267 // hud area is 196 x 240 pixels
268 r_Render_DrawTexture(hud, x, y, hud.width, hud.height, TBasePoint.BP_LEFTUP);
269 r_Render_DrawText(p.name, x + 98, y + 16, 255, 0, 0, 255, smallfont, TBasePoint.BP_CENTER);
271 t := hudhp[R_BERSERK in p.FRulez];
272 r_Render_DrawTexture(t, x + 51, y + 61, t.width, t.height, TBasePoint.BP_CENTER);
273 r_Render_DrawTexture(hudap, x + 50, y + 85, hudap.width, hudap.height, TBasePoint.BP_CENTER);
275 r_Render_DrawText(IntToStr(MAX(0, p.health)), x + 174, y + 56, 255, 0, 0, 255, menufont, TBasePoint.BP_RIGHT);
276 r_Render_DrawText(IntToStr(MAX(0, p.armor)), x + 174, y + 84, 255, 0, 0, 255, menufont, TBasePoint.BP_RIGHT);
278 case p.CurrWeap of
279 WEAPON_KASTET, WEAPON_SAW: s := '--';
280 else s := IntToStr(p.GetAmmoByWeapon(p.CurrWeap));
281 end;
282 r_Render_DrawText(s, x + 174, y + 174, 255, 0, 0, 255, menufont, TBasePoint.BP_RIGHT);
284 if p.CurrWeap <= WP_LAST then
285 begin
286 t := hudwp[p.CurrWeap];
287 r_Render_DrawTexture(t, x + 18, y + 160, t.width, t.height, TBasePoint.BP_LEFTUP);
288 end;
290 if R_KEY_RED in p.FRulez then
291 r_Render_DrawTexture(hudkey[0], x + 76, y + 214, 16, 16, TBasePoint.BP_LEFTUP);
292 if R_KEY_GREEN in p.FRulez then
293 r_Render_DrawTexture(hudkey[1], x + 93, y + 214, 16, 16, TBasePoint.BP_LEFTUP);
294 if R_KEY_BLUE in p.FRulez then
295 r_Render_DrawTexture(hudkey[2], x + 110, y + 214, 16, 16, TBasePoint.BP_LEFTUP);
297 if p.JetFuel > 0 then
298 begin
299 r_Render_DrawTexture(hudair, x, y + 116, hudair.width, hudair.height, TBasePoint.BP_LEFTUP);
300 if p.air > 0 then
301 r_Draw_FillRect(x + 14, y + 116 + 4, x + 14 + 168 * p.air div AIR_MAX, y + 116 + 4 + 4, 0, 0, 196, 255);
302 r_Render_DrawTexture(hudjet, x, y + 126, hudjet.width, hudjet.height, TBasePoint.BP_LEFTUP);
303 r_Draw_FillRect(x + 14, y + 126 + 4, x + 14 + 168 * p.JetFuel div JET_MAX, y + 126 + 4 + 4, 208, 0, 0, 255);
304 end
305 else
306 begin
307 r_Render_DrawTexture(hudair, x, y + 124, hudair.width, hudair.height, TBasePoint.BP_LEFTUP);
308 if p.air > 0 then
309 r_Draw_FillRect(x + 14, y + 124 + 4, x + 14 + 168 * p.air div AIR_MAX, y + 124 + 4 + 4, 0, 0, 196, 255);
310 end;
311 end;
313 procedure r_Render_DrawHUDArea (x, y, w, h: Integer; p: TPlayer);
314 var s: AnsiString;
315 begin
316 r_Render_DrawTexture(hudbg, x, y, w, h, TBasePoint.BP_LEFTUP);
318 if p <> nil then
319 r_Render_DrawHUD(x + w - 196 + 2, y, p);
321 if gShowPing and g_Game_IsClient then
322 begin
323 s := _lc[I_GAME_PING_HUD] + IntToStr(NetPeer.lastRoundTripTime) + _lc[I_NET_SLIST_PING_MS];
324 r_Render_DrawText(s, x + 4, y + 242, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP);
325 end;
327 if p.Spectator then
328 begin
329 r_Render_DrawText(_lc[I_PLAYER_SPECT], x + 4, y + 242, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP);
330 r_Render_DrawText(_lc[I_PLAYER_SPECT2], x + 4, y + 258, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP);
331 r_Render_DrawText(_lc[I_PLAYER_SPECT1], x + 4, y + 274, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP);
332 if p.NoRespawn then
333 r_Render_DrawText(_lc[I_PLAYER_SPECT1S], x + 4, y + 290, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP);
334 end;
335 end;
337 procedure r_Render_DrawView (x, y, w, h: Integer; p: TPlayer);
338 begin
339 if p <> nil then
340 r_Map_Draw(x, y, w, h, p.obj.x + PLAYER_RECT_CX, p.obj.y + PLAYER_RECT_CY, p)
341 else
342 r_Map_Draw(x, y, w, h, 0, 0, nil);
344 // TODO draw stats
346 if p <> nil then
347 begin
348 if p.Spectator and p.NoRespawn then
349 r_Render_DrawText(_lc[I_PLAYER_SPECT4], x div 2 + w div 2, y div 2 + h div 2, 255, 255, 255, 255, stdfont, TBasePoint.BP_CENTER);
350 end;
351 end;
353 procedure r_Render_DrawPlayerView (x, y, w, h: Integer; p: TPlayer);
354 begin
355 r_Render_DrawView(x, y, w - 196, h, p);
356 r_Render_DrawHUDArea(x + w - 196, y, 196, h, p);
357 end;
359 procedure r_Render_Draw;
360 begin
361 if gExit = EXIT_QUIT then
362 exit;
364 SetupMatrix;
366 glClearColor(0.0, 0.0, 0.0, 0.0);
367 glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
369 glColor4ub(255, 255, 255, 255);
371 //e_LogWritefln('r_render_draw: %sx%s', [gScreenWidth, gScreenHeight]);
373 if gGameOn or (gState = STATE_FOLD) then
374 begin
375 // TODO setup player view
376 // TODO setup sectator mode
377 // TODO setup player hear point
378 // TODO setup player view siz
380 // TODO draw player view + setup screen coords
381 r_Render_DrawPlayerView(0, 0, gScreenWidth, gScreenHeight, gPlayer1);
383 // TODO draw holmes inspector
385 // TODO draw messages
386 // TODO draw stats (?)
387 // TODO draw spectator hud
388 end;
390 if gPauseMain and gGameOn {$IFDEF ENABLE_MENU}and (g_ActiveWindow = nil){$ENDIF} then
391 begin
392 // TODO draw pause screen
393 end;
395 if not gGameOn then
396 begin
397 case gState of
398 STATE_MENU: ; // TODO draw menu bg
399 STATE_FOLD: ;
400 STATE_INTERCUSTOM: ;
401 STATE_INTERSINGLE: ;
402 STATE_ENDPIC: ;
403 STATE_SLIST: ;
404 end;
405 end;
407 {$IFDEF ENABLE_MENU}
408 if g_ActiveWindow <> nil then
409 begin
410 // TODO draw menu widgets
411 end;
412 {$ENDIF}
414 // TODO draw console
416 // TODO draw holmes interface
418 glFinish();
419 glFlush();
420 sys_Repaint;
421 end;
423 procedure r_Render_Resize (w, h: Integer);
424 begin
425 gWinSizeX := w;
426 gWinSizeY := h;
427 gRC_Width := w;
428 gRC_Height := h;
429 gScreenWidth := w;
430 gScreenHeight := h;
431 end;
433 procedure r_Render_Apply;
434 begin
435 {$IFDEF ENABLE_SYSTEM}
436 if sys_SetDisplayModeGL(GetInfo()) then
437 e_LogWriteln('resolution changed')
438 else
439 e_LogWriteln('resolution not changed');
440 sys_EnableVSync(gVSync)
441 {$ENDIF}
442 end;
444 function r_Render_WriteScreenShot (filename: String): Boolean;
445 begin
446 Result := False;
447 end;
449 {$IFDEF ENABLE_GIBS}
450 function r_Render_GetGibRect (m, id: Integer): TRectWH;
451 begin
452 result := r_Map_GetGibSize(m, id);
453 end;
454 {$ENDIF}
456 {$IFDEF ENABLE_GFX}
457 procedure r_Render_QueueEffect (AnimType, X, Y: Integer);
458 begin
459 r_Map_NewGFX(AnimType, X, Y);
460 end;
461 {$ENDIF}
463 {$IFDEF ENABLE_TOUCH}
464 procedure r_Render_GetKeyRect (key: Integer; out x, y, w, h: Integer; out founded: Boolean);
465 begin
466 founded := False;
467 end;
468 {$ENDIF}
470 {$IFDEF ENABLE_MENU}
471 procedure r_Render_GetControlSize (ctrl: TGUIControl; out w, h: Integer);
472 begin
473 w := 0; h := 0;
474 end;
476 procedure r_Render_GetLogoSize (out w, h: Integer);
477 begin
478 w := 0; h := 0;
479 end;
481 procedure r_Render_GetMaxFontSize (BigFont: Boolean; out w, h: Integer);
482 begin
483 w := 0; h := 0;
484 end;
486 procedure r_Render_GetStringSize (BigFont: Boolean; str: String; out w, h: Integer);
487 begin
488 w := 0; h := 0;
489 end;
490 {$ENDIF}
492 procedure r_Render_DrawLoading (force: Boolean);
493 begin
494 end;
496 end.