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}
18 interface
20 uses
21 {$IFDEF ENABLE_MENU}
22 g_gui,
23 {$ENDIF}
24 g_base // TRectWH
25 ;
27 (* render startup *)
31 (* load globally used textures *)
35 (* load map specific textures *)
47 {$IFDEF ENABLE_GIBS}
49 {$ENDIF}
51 {$IFDEF ENABLE_GFX}
53 {$ENDIF}
55 {$IFDEF ENABLE_TOUCH}
56 // touch screen button location and size
58 {$ENDIF}
60 {$IFDEF ENABLE_MENU}
65 {$ENDIF}
69 implementation
71 uses
72 {$IFDEF USE_GLES1}
73 GLES11,
74 {$ELSE}
76 {$ENDIF}
77 {$IFDEF ENABLE_MENU}
78 r_gui,
79 {$ENDIF}
80 {$IFDEF ENABLE_SYSTEM}
81 g_system,
82 {$ENDIF}
84 g_basic,
89 ;
91 type
92 TBasePoint = (
96 );
98 var
112 begin
113 r_Map_LoadTextures;
117 begin
118 r_Map_FreeTextures;
122 const
123 WeapName: array [0..WP_LAST] of AnsiString = ('KASTET', 'SAW', 'PISTOL', 'SHOTGUN1', 'SHOTGUN2', 'MGUN', 'RLAUNCHER', 'PGUN', 'BFG', 'SPULEMET', 'FLAMETHROWER');
124 var
126 begin
127 r_Common_Load;
147 r_Console_Load;
148 r_Map_Load;
149 {$IFDEF ENABLE_MENU}
150 r_GUI_Load;
151 {$ENDIF}
156 begin
157 {$IFDEF ENABLE_MENU}
158 r_GUI_Free;
159 {$ENDIF}
160 r_Map_Free;
161 r_Console_Free;
174 begin
185 r_Common_Free;
188 {$IFDEF ENABLE_SYSTEM}
191 begin
203 {$ENDIF}
206 begin
207 {$IFDEF ENABLE_SYSTEM}
211 {$ENDIF}
212 r_Textures_Initialize;
213 r_Console_Initialize;
214 r_Map_Initialize;
218 begin
219 r_Map_Finalize;
220 r_Console_Finalize;
221 r_Textures_Finalize;
225 begin
226 r_Console_Update;
227 r_Map_Update;
231 begin
244 procedure r_Render_DrawText (const text: AnsiString; x, y: Integer; r, g, b, a: Byte; f: TGLFont; p: TBasePoint);
246 begin
249 begin
257 begin
264 begin
268 begin
271 begin
277 begin
278 // skip color modifiers
280 otherwise
281 begin
292 procedure r_Render_DrawFormatText (const text: AnsiString; x, y: Integer; a: Byte; f: TGLFont; p: TBasePoint);
293 const
295 ((R:$00; G:$00; B:$00), (R:$FF; G:$00; B:$00), (R:$00; G:$FF; B:$00), (R:$FF; G:$FF; B:$00), (R:$00; G:$00; B:$FF), (R:$FF; G:$FF; B:$FF)),
296 ((R:$00; G:$00; B:$00), (R:$7F; G:$00; B:$00), (R:$00; G:$7F; B:$00), (R:$FF; G:$7F; B:$00), (R:$00; G:$00; B:$7F), (R:$7F; G:$7F; B:$7F))
297 );
298 var
300 begin
303 begin
310 begin
313 begin
325 otherwise
326 begin
328 r_Draw_Text(text[i], cx, cy, colors[dark, color].R, colors[dark, color].G, colors[dark, color].B, a, f);
337 begin
340 // hud area is 196 x 240 pixels
348 r_Render_DrawText(IntToStr(MAX(0, p.health)), x + 174, y + 56, 255, 0, 0, 255, menufont, TBasePoint.BP_RIGHT);
349 r_Render_DrawText(IntToStr(MAX(0, p.armor)), x + 174, y + 84, 255, 0, 0, 255, menufont, TBasePoint.BP_RIGHT);
358 begin
371 begin
374 r_Draw_FillRect(x + 14, y + 116 + 4, x + 14 + 168 * p.air div AIR_MAX, y + 116 + 4 + 4, 0, 0, 196, 255);
376 r_Draw_FillRect(x + 14, y + 126 + 4, x + 14 + 168 * p.JetFuel div JET_MAX, y + 126 + 4 + 4, 208, 0, 0, 255);
377 end
378 else
379 begin
382 r_Draw_FillRect(x + 14, y + 124 + 4, x + 14 + 168 * p.air div AIR_MAX, y + 124 + 4 + 4, 0, 0, 196, 255);
388 begin
392 begin
395 begin
396 r_Render_DrawText(_lc[I_PLAYER_SPECT], x + 4, y + 242, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP);
397 r_Render_DrawText(_lc[I_PLAYER_SPECT2], x + 4, y + 258, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP);
398 r_Render_DrawText(_lc[I_PLAYER_SPECT1], x + 4, y + 274, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP);
400 r_Render_DrawText(_lc[I_PLAYER_SPECT1S], x + 4, y + 290, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP);
405 begin
412 var fw, i, maxFrags, top, totalPlayers: Integer; sign: Char; stat: TPlayerStatArray; f: TGLTexture;
413 begin
417 begin
418 (* RED TEAM GOALS *)
421 begin
428 begin
430 r_Render_DrawTexture(f, x + w - 16, y + 240 - 72 - 4, f.width, f.height, TBasePoint.BP_RIGHTUP);
433 r_Render_DrawText(IntToStr(gTeamStat[TEAM_RED].Score), x + w - 16 - fw, y + 240 - 72 - 4, TEAMCOLOR[TEAM_RED].R, TEAMCOLOR[TEAM_RED].G, TEAMCOLOR[TEAM_RED].B, 255, menufont, TBasePoint.BP_RIGHTUP);
435 (* BLUE TEAM GOALS *)
438 begin
445 begin
447 r_Render_DrawTexture(f, x + w - 16, y + 240 - 32 - 4, f.width, f.height, TBasePoint.BP_RIGHTUP);
450 r_Render_DrawText(IntToStr(gTeamStat[TEAM_BLUE].Score), x + w - 16 - fw, y + 240 - 32 - 4, TEAMCOLOR[TEAM_BLUE].R, TEAMCOLOR[TEAM_BLUE].G, TEAMCOLOR[TEAM_BLUE].B, 255, menufont, TBasePoint.BP_RIGHTUP);
454 begin
456 begin
457 r_Render_DrawText(IntToStr(p.Frags), x + w - 16, y, 255, 0, 0, 255, menufont, TBasePoint.BP_RIGHTUP);
464 begin
467 begin
469 begin
477 r_Render_DrawText(IntToStr(top) + ' / ' + IntToStr(totalPlayers) + ' ' + sign + IntToStr(ABS(p.Frags - maxFrags)), x + w - 16, y + 32, 255, 0, 0, 255, smallfont, TBasePoint.BP_RIGHTUP);
481 begin
482 r_Render_DrawText(_lc[I_GAME_WARMUP], x + w - 16 - 64, y + h, 0, 255, 0, 255, menufont, TBasePoint.BP_RIGHTDOWN);
483 r_Render_DrawText(': ' + IntToStr((gLMSRespawnTime - gTime) div 1000), x + w - 16 - 64, y + h, 0, 255, 0, 255, menufont, TBasePoint.BP_LEFTDOWN);
484 end
486 begin
487 r_Render_DrawText(IntToStr(p.Lives), x + w - 16, y + h, 0, 255, 0, 255, menufont, TBasePoint.BP_RIGHTDOWN);
494 begin
499 begin
503 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);
504 end
505 else
506 begin
515 begin
524 begin
534 begin
536 begin
538 if img.width = img.height then fw := img.width * 4 div 3 else fw := img.width; // fix aspect 4:3
541 end
545 begin
551 var ip: AnsiString; ww, hh, cw, ch, mw, mh, motdh, scrx, scry, i, mx, y: Integer; msg: SSArray; Srv: TNetServer;
552 begin
557 r_Render_DrawText(_lc[I_NET_SLIST], gScreenWidth div 2, 16, 255, 255, 255, 255, menufont, TBasePoint.BP_UP);
565 r_Render_DrawText(_lc[I_NET_SLIST_HELP], gScreenWidth div 2, gScreenHeight - 8, 255, 255, 255, 255, stdfont, TBasePoint.BP_DOWN);
568 begin
575 begin
580 r_Render_DrawText(_lc[I_NET_SLIST_URGENT], scrx, scry - 58, 255, 255, 255, 255, stdfont, TBasePoint.BP_UP);
581 r_Render_DrawFormatText(slUrgent, scrx - 253, scry - 38 + ch * i, 255, stdfont, TBasePoint.BP_LEFTUP);
582 r_Render_DrawText(_lc[I_NET_SLIST_URGENT_CONT], scrx, scry + 41, 255, 255, 255, 255, stdfont, TBasePoint.BP_UP);
584 end
586 begin
590 end
591 else
592 begin
595 begin
625 begin
631 r_Render_DrawText('<1' + _lc[I_NET_SLIST_PING_MS], mx - 68, y, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP)
633 r_Render_DrawText(IntToStr(Srv.Ping) + _lc[I_NET_SLIST_PING_MS], mx - 68, y, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP)
634 else
635 r_Render_DrawText(_lc[I_NET_SLIST_NO_ACCESS], mx - 68, y, 255, 0, 0, 255, stdfont, TBasePoint.BP_LEFTUP);
637 r_Render_DrawText('<' + IntToStr(Length(ST[I].Indices)) + '>', mx - 68, y + 16, 210, 210, 210, 255, stdfont, TBasePoint.BP_LEFTUP);
639 r_Render_DrawText(g_Game_ModeToText(Srv.GameMode), mx + 2, y, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP);
641 r_Render_DrawText(IntToStr(Srv.Players) + '/' + IntToStr(Srv.MaxPlayers), mx + 54, y, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP);
642 r_Render_DrawText(IntToStr(Srv.LocalPl) + '+' + IntToStr(Srv.Bots), mx + 54, y + 16, 210, 210, 210, 255, stdfont, TBasePoint.BP_LEFTUP);
644 r_Render_DrawText(IntToStr(Srv.Protocol), mx + 106, y, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP);
650 r_Render_DrawText(IntToStr(Length(ST)) + _lc[I_NET_SLIST_SERVERS], gScreenWidth - 48, motdh - 20 + 3, 255, 255, 255, 255, stdfont, TBasePoint.BP_RIGHTUP);
656 begin
663 procedure r_Render_DrawStatsColumns (constref cs: TEndCustomGameStat; x, y, w: Integer; endview: Boolean);
664 var i, cw, ch, yy, team, players, w1, w2, w3, w4, tw: Integer; r, g, b, rr, gg, bb: Byte; s: AnsiString;
665 begin
675 begin
677 begin
679 TEAM_RED:
680 begin
684 TEAM_BLUE:
685 begin
691 r_Render_DrawText(IntToStr(cs.TeamStat[team].Score), x + tw, yy, r, g, b, 255, stdfont, TBasePoint.BP_UP);
695 r_Render_DrawText(_lc[I_GAME_DEATHS], x + w1 + w2 + w3, yy, r, g, b, 255, stdfont, TBasePoint.BP_UP);
703 begin
705 begin
708 begin
712 // Player name
713 if gShowPIDs then s := Format('[%5d] %s', [cs.PlayerStat[i].UID, cs.PlayerStat[i].Name]) else s := cs.PlayerStat[i].Name;
714 if (gPlayers[cs.PlayerStat[i].Num] <> nil) and (gPlayers[cs.PlayerStat[i].Num].FReady) then s := s + ' *';
717 begin
718 // Player ping/loss
722 // Player frags
725 // Player deaths
734 end
736 begin
737 r_Render_DrawText(_lc[I_GAME_PLAYER_NAME], x, yy, 255, 127, 0, 255, stdfont, TBasePoint.BP_LEFTUP);
740 r_Render_DrawText(_lc[I_GAME_FRAGS], x + w1 + w2, yy, 255, 127, 0, 255, stdfont, TBasePoint.BP_UP);
741 r_Render_DrawText(_lc[I_GAME_DEATHS], x + w1 + w2 + w3, yy, 255, 127, 0, 255, stdfont, TBasePoint.BP_UP);
744 begin
745 // rr := 255; gg := 127; bb := 0;
748 begin
752 // Player color
754 r_Draw_FillRect(x + 1, yy + 1, x + 16 - 1, yy + 16 - 1, cs.PlayerStat[i].Color.R, cs.PlayerStat[i].Color.G, cs.PlayerStat[i].Color.B, 255);
755 // Player name
756 if gShowPIDs then s := Format('[%5d] %s', [cs.PlayerStat[i].UID, cs.PlayerStat[i].Name]) else s := cs.PlayerStat[i].Name;
757 if (gPlayers[cs.PlayerStat[i].Num] <> nil) and (gPlayers[cs.PlayerStat[i].Num].FReady) then s := s + ' *';
760 begin
761 // Player ping/loss
765 // Player frags
768 // Player deaths
777 procedure r_Render_DrawStatsWindow (x, y, w, h: Integer; cs: TEndCustomGameStat; endview: Boolean);
779 begin
785 (* LINE 1 *)
788 begin
807 begin
814 (* LINE 2/3 *)
821 begin
827 GM_COOP: s := _lc[I_GAME_MONSTERS] + ' ' + IntToStr(gCoopMonstersKilled) + '/' + IntToStr(gTotalMonsters);
832 GM_DM, GM_TDM, GM_CTF: s := Format(_lc[I_GAME_TIME_LIMIT], [gGameSettings.TimeLimit div 3600, (gGameSettings.TimeLimit div 60) mod 60, gGameSettings.TimeLimit mod 60]);
833 GM_COOP: s := _lc[I_GAME_SECRETS] + ' ' + IntToStr(gCoopSecretsFound) + '/' + IntToStr(gSecretsCount);
838 end
839 else
840 begin
842 r_Render_DrawText(_lc[I_MENU_MAP], x + 16, y + yoff, 255, 127, 0, 255, stdfont, TBasePoint.BP_LEFTUP);
843 r_Render_DrawText(s, x + 16 + xoff, y + yoff, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP);
845 r_Render_DrawText(_lc[I_GAME_GAME_TIME], x + 16, y + yoff, 255, 127, 0, 255, stdfont, TBasePoint.BP_LEFTUP);
846 r_Render_DrawText(r_Render_TimeToStr(cs.GameTime), x + 16 + xoff, y + yoff, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP);
852 (* LINE 4/5 *)
855 begin
857 r_Render_DrawText(_lc[I_GAME_MONSTERS], x + 16, y + yoff, 255, 127, 0, 255, stdfont, TBasePoint.BP_LEFTUP);
858 r_Render_DrawText(IntToStr(gCoopMonstersKilled) + '/' + IntToStr(gTotalMonsters), x + 16 + xoff, y + yoff, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP);
860 r_Render_DrawText(_lc[I_GAME_SECRETS], x + 16, y + yoff, 255, 127, 0, 255, stdfont, TBasePoint.BP_LEFTUP);
861 r_Render_DrawText(IntToStr(gCoopSecretsFound) + '/' + IntToStr(gSecretsCount), x + 16 + xoff, y + yoff, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP);
866 (* LINE 6/7 *)
869 begin
870 xoff := MAX(Length(_lc[I_GAME_MONSTERS_TOTAL]) + 1, Length(_lc[I_GAME_SECRETS_TOTAL]) + 1) * cw;
871 r_Render_DrawText(_lc[I_GAME_MONSTERS_TOTAL], x + 16, y + yoff, 255, 127, 0, 255, stdfont, TBasePoint.BP_LEFTUP);
872 r_Render_DrawText(IntToStr(gCoopTotalMonstersKilled) + '/' + IntToStr(gCoopTotalMonsters), x + 16 + xoff, y + yoff, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP);
874 r_Render_DrawText(_lc[I_GAME_SECRETS_TOTAL], x + 16, y + yoff, 255, 127, 0, 255, stdfont, TBasePoint.BP_LEFTUP);
875 r_Render_DrawText(IntToStr(gCoopTotalSecretsFound) + '/' + IntToStr(gCoopTotalSecrets), x + 16 + xoff, y + yoff, 255, 255, 255, 255, stdfont, TBasePoint.BP_LEFTUP);
880 (* LINE *)
883 begin
885 else if cs.TeamStat[TEAM_BLUE].Score > cs.TeamStat[TEAM_RED].Score then s := _lc[I_GAME_WIN_BLUE]
892 (* LINE n *)
899 begin
910 begin
928 begin
930 begin
931 r_Render_DrawText(_lc[I_MENU_INTER_NOTICE_TAB], gScreenWidth div 2, 8, 255, 255, 255, 255, stdfont, TBasePoint.BP_UP);
932 end
933 else
934 begin
936 GM_COOP: if gMissionFailed then s := _lc[I_MENU_INTER_MISSION_FAIL] else s := _lc[I_MENU_INTER_LEVEL_COMPLETE];
942 begin
943 if g_Game_IsClient then s := _lc[I_MENU_INTER_NOTICE_MAP] else s := _lc[I_MENU_INTER_NOTICE_SPACE];
944 r_Render_DrawText(s, gScreenWidth div 2, gScreenHeight - 4, 255, 255, 255, 255, stdfont, TBasePoint.BP_DOWN);
946 begin
948 r_Render_DrawText(s, gScreenWidth div 2, gScreenHeight - 16 - 4, 255, 255, 255, 255, stdfont, TBasePoint.BP_DOWN);
952 r_Render_DrawStatsWindow(32, 64, gScreenWidth - 32 * 2, gScreenHeight - 64 * 2, CustomStat, true);
958 begin
970 begin
971 r_Render_DrawText(_lc[I_MENU_INTER_KILLS], x, y, 255, 255, 255, 255, menufont, TBasePoint.BP_LEFTUP);
973 r_Render_DrawText(_lc[I_MENU_INTER_KPM], x, y + 32, 255, 255, 255, 255, menufont, TBasePoint.BP_LEFTUP);
977 r_Render_DrawText(Format('%.1f', [kpm]), x + w1, y + 32, 255, 0, 0, 255, menufont, TBasePoint.BP_LEFTUP);
978 r_Render_DrawText(_lc[I_MENU_INTER_SECRETS], x, y + 64, 255, 255, 255, 255, menufont, TBasePoint.BP_LEFTUP);
979 r_Render_DrawValueOf(SingleStat.PlayerStat[player].Secrets, SingleStat.TotalSecrets, x + w1, y + 64, MenuFont);
984 begin
985 r_Render_DrawText(_lc[I_MENU_INTER_LEVEL_COMPLETE], gScreenWidth div 2, 32, 255, 255, 255, 255, menufont, TBasePoint.BP_UP);
993 r_Render_DrawText(_lc[I_MENU_INTER_TIME], xx, 80, 255, 255, 255, 255, menufont, TBasePoint.BP_LEFTUP);
997 begin
998 r_Render_DrawText(_lc[I_MENU_PLAYER_1], gScreenWidth div 2, 128, 255, 255, 255, 255, menufont, TBasePoint.BP_UP);
1000 r_Render_DrawText(_lc[I_MENU_PLAYER_2], gScreenWidth div 2, 288, 255, 255, 255, 255, menufont, TBasePoint.BP_UP);
1002 end
1003 else
1004 begin
1014 begin
1018 r_Render_DrawText(s1, xoff + ww div 2, gScreenHeight - ch, 255, 255, 255, 255, stdfont, TBasePoint.BP_DOWN);
1019 r_Render_DrawText(s2, xoff + ww div 2, gScreenHeight - ch, 255, 255, 255, 255, stdfont, TBasePoint.BP_UP);
1023 begin
1037 begin
1047 begin
1050 begin
1052 while (i < len) and ((IsActivePlayer(gPlayers[i]) = false) or (gPlayers[i].UID <> id)) do INC(i);
1060 begin
1062 exit;
1073 //e_LogWritefln('r_render_draw: %sx%s', [gScreenWidth, gScreenHeight]);
1078 begin
1080 begin
1082 begin
1085 end
1086 else
1087 begin
1091 end
1093 begin
1095 end
1097 begin
1101 begin
1106 begin
1115 begin
1116 // TODO setup player hear point
1119 begin
1120 r_Render_DrawMapView(0, 0, gScreenWidth, gScreenHeight, gSpectX + gScreenWidth div 2, gSpectY + gScreenHeight div 2);
1121 end
1123 begin
1126 end
1128 begin
1130 end
1132 begin
1136 // TODO draw holmes inspector
1139 r_Render_DrawFormatText(MessageText, (gScreenWidth - 196) div 2, gScreenHeight div 2, 255, menufont, TBasePoint.BP_CENTER);
1142 r_Render_DrawStats;
1144 if gSpectHUD and (gChatShow = false) and (gSpectMode <> SPECT_NONE) and (gSpectAuto = false) then
1145 r_Render_DrawSpectHud;
1149 begin
1150 // TODO draw pause screen
1154 begin
1158 STATE_FOLD:
1159 begin
1161 r_Draw_FillRect(0, 0, gScreenWidth - 1, gScreenHeight - 1, 0, 0, 0, MIN(MAX(255 - EndingGameCounter, 0), 255));
1163 STATE_INTERCUSTOM:
1164 begin
1168 else
1170 else
1173 r_Render_DrawCustomStats;
1175 {$IFDEF ENABLE_MENU}
1178 {$ENDIF}
1181 begin
1183 begin
1184 r_Draw_FillRect(0, 0, gScreenWidth - 1, gScreenHeight - 1, 0, 0, 0, MIN(MAX(255 - EndingGameCounter, 0), 255));
1185 end
1186 else
1187 begin
1189 r_Render_DrawSingleStats;
1190 {$IFDEF ENABLE_MENU}
1193 {$ENDIF}
1196 STATE_ENDPIC:
1197 begin
1200 else
1202 {$IFDEF ENABLE_MENU}
1205 {$ENDIF}
1207 STATE_SLIST:
1208 begin
1216 {$IFDEF ENABLE_MENU}
1218 begin
1223 {$ENDIF}
1227 // TODO draw holmes interface
1231 sys_Repaint;
1235 begin
1245 begin
1246 {$IFDEF ENABLE_SYSTEM}
1249 else
1252 {$ENDIF}
1256 begin
1260 {$IFDEF ENABLE_GIBS}
1262 begin
1265 {$ENDIF}
1267 {$IFDEF ENABLE_GFX}
1269 begin
1272 {$ENDIF}
1274 {$IFDEF ENABLE_TOUCH}
1276 begin
1279 {$ENDIF}
1281 {$IFDEF ENABLE_MENU}
1283 begin
1288 begin
1293 begin
1298 begin
1301 {$ENDIF}
1304 begin
1305 // TODO draw loading screen