DEADSOFTWARE

gl: fix interpolation
[d2df-sdl.git] / src / game / renders / opengl / r_common.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_common;
18 interface
20 uses r_textures, g_player, g_phys;
22 type
23 TBasePoint = (
24 BP_LEFTUP, BP_UP, BP_RIGHTUP,
25 BP_LEFT, BP_CENTER, BP_RIGHT,
26 BP_LEFTDOWN, BP_DOWN, BP_RIGHTDOWN
27 );
29 THereTexture = record
30 name: AnsiString;
31 id: TGLTexture;
32 end;
34 var
35 stdfont: TGLFont;
36 smallfont: TGLFont;
37 menufont: TGLFont;
39 function r_Common_LoadThis (const name: AnsiString; var here: THereTexture): Boolean;
40 procedure r_Common_FreeThis (var here: THereTexture);
42 procedure r_Common_CalcAspect (ow, oh, nw, nh: LongInt; horizontal: Boolean; out ww, hh: LongInt);
44 procedure r_Common_GetBasePoint (x, y, w, h: Integer; p: TBasePoint; out xx, yy: Integer);
45 procedure r_Common_DrawText (const text: AnsiString; x, y: Integer; r, g, b, a: Byte; f: TGLFont; p: TBasePoint);
46 procedure r_Common_DrawTexture (img: TGLTexture; x, y, w, h: Integer; p: TBasePoint);
47 procedure r_Common_GetFormatTextSize (const text: AnsiString; f: TGLFont; out w, h: Integer);
48 procedure r_Common_DrawFormatText (const text: AnsiString; x, y: Integer; a: Byte; f: TGLFont; p: TBasePoint);
50 function r_Common_TimeToStr (t: LongWord): AnsiString;
52 procedure r_Common_GetObjectPos (const obj: TObj; out x, y: Integer);
53 procedure r_Common_GetPlayerPos (const p: TPlayer; out x, y: Integer);
54 procedure r_Common_GetCameraPos (const p: TPlayer; center: Boolean; out x, y: Integer);
55 function r_Common_GetPosByUID (uid: WORD; out obj: TObj; out x, y: Integer): Boolean;
57 procedure r_Common_Load;
58 procedure r_Common_Free;
60 implementation
62 uses
63 Math, SysUtils,
64 e_log, utils,
65 g_base, g_basic, g_options, g_game, g_map,
66 {$IFDEF ENABLE_CORPSES}
67 g_corpses,
68 {$ENDIF}
69 r_draw, r_fonts
70 ;
72 procedure r_Common_GetObjectPos (const obj: TObj; out x, y: Integer);
73 var fx, fy: Integer;
74 begin
75 obj.Lerp(gLerpFactor, fx, fy);
76 x := fx;
77 y := fy + obj.slopeUpLeft;
78 end;
80 procedure r_Common_GetPlayerPos (const p: TPlayer; out x, y: Integer);
81 var fx, fy, fSlope: Integer;
82 begin
83 ASSERT(p <> nil);
84 p.obj.Lerp(gLerpFactor, fx, fy);
85 fSlope := nlerp(p.SlopeOld, p.obj.slopeUpLeft, gLerpFactor);
86 x := fx;
87 y := fy + fSlope;
88 end;
90 {$IFDEF ENABLE_CORPSES}
91 function r_Common_GetPlayerCorpse (const p: TPlayer): TCorpse;
92 begin
93 result := nil;
94 if (p <> nil) and (p.Alive = false) and (p.Spectator = false) and (p.Corpse >= 0) then
95 if (gCorpses <> nil) and (gCorpses[p.Corpse] <> nil) and (gCorpses[p.Corpse].PlayerUID = p.UID) then
96 result := gCorpses[p.Corpse];
97 end;
98 {$ENDIF}
100 procedure r_Common_GetCameraPos (const p: TPlayer; center: Boolean; out x, y: Integer);
101 {$IFDEF ENABLE_CORPSES}
102 var corpse: TCorpse;
103 {$ENDIF}
104 begin
105 {$IFDEF ENABLE_CORPSES}
106 corpse := r_Common_GetPlayerCorpse(p);
107 if corpse <> nil then
108 begin
109 r_Common_GetObjectPos(corpse.obj, x, y);
110 if center then
111 begin
112 x := x + corpse.obj.rect.width div 2;
113 y := y + corpse.obj.rect.height div 2;
114 end;
115 end
116 else
117 {$ENDIF}
118 if p <> nil then
119 begin
120 r_Common_GetPlayerPos(p, x, y);
121 if center then
122 begin
123 x := x + p.obj.rect.width div 2;
124 y := y + p.obj.rect.height div 2;
125 end;
126 end
127 else
128 begin
129 x := 0;
130 y := 0;
131 if center then
132 begin
133 x := x + gMapInfo.Width div 2;
134 y := y + gMapInfo.Height div 2;
135 end;
136 end;
137 end;
139 function r_Common_GetPosByUID (uid: WORD; out obj: TObj; out x, y: Integer): Boolean;
140 var p: TPlayer; found: Boolean;
141 begin
142 found := false;
143 if g_GetUIDType(uid) = UID_PLAYER then
144 begin
145 p := g_Player_Get(uid);
146 found := p <> nil;
147 if found then
148 begin
149 r_Common_GetPlayerPos(p, x, y);
150 obj := p.obj;
151 end;
152 end
153 else if GetPos(uid, @obj) then
154 begin
155 found := true;
156 r_Common_GetObjectPos(obj, x, y);
157 end;
158 result := found;
159 end;
161 procedure r_Common_GetBasePoint (x, y, w, h: Integer; p: TBasePoint; out xx, yy: Integer);
162 begin
163 case p of
164 TBasePoint.BP_LEFTUP, TBasePoint.BP_LEFT, TBasePoint.BP_LEFTDOWN: xx := x;
165 TBasePoint.BP_UP, TBasePoint.BP_CENTER, TBasePoint.BP_DOWN: xx := x - w div 2;
166 TBasePoint.BP_RIGHTUP, TBasePoint.BP_RIGHT, TBasePoint.BP_RIGHTDOWN: xx := x - w;
167 end;
168 case p of
169 TBasePoint.BP_LEFTUP, TBasePoint.BP_UP, TBasePoint.BP_RIGHTUP: yy := y;
170 TBasePoint.BP_LEFT, TBasePoint.BP_CENTER, TBasePoint.BP_RIGHT: yy := y - h div 2;
171 TBasePoint.BP_LEFTDOWN, TBasePoint.BP_DOWN, TBasePoint.BP_RIGHTDOWN: yy := y - h;
172 end;
173 end;
175 procedure r_Common_DrawText (const text: AnsiString; x, y: Integer; r, g, b, a: Byte; f: TGLFont; p: TBasePoint);
176 var xx, yy, w, h: Integer;
177 begin
178 xx := x; yy := y;
179 if p <> TBasePoint.BP_LEFTUP then
180 begin
181 r_Draw_GetTextSize(text, f, w, h);
182 r_Common_GetBasePoint(x, y, w, h, p, xx, yy);
183 end;
184 r_Draw_Text(text, xx, yy, r, g, b, a, f);
185 end;
187 procedure r_Common_DrawTexture (img: TGLTexture; x, y, w, h: Integer; p: TBasePoint);
188 begin
189 r_Common_GetBasePoint(x, y, w, h, p, x, y);
190 r_Draw_TextureRepeat(img, x, y, w, h, false, 255, 255, 255, 255, false);
191 end;
193 procedure r_Common_GetFormatTextSize (const text: AnsiString; f: TGLFont; out w, h: Integer);
194 var i, cw, ch, cln, curw, curh, maxw, maxh: Integer;
195 begin
196 curw := 0; curh := 0; maxw := 0; maxh := 0;
197 r_Draw_GetTextSize('W', f, cw, cln);
198 for i := 1 to Length(text) do
199 begin
200 case text[i] of
201 #10:
202 begin
203 maxw := MAX(maxw, curw);
204 curh := curh + cln;
205 curw := 0;
206 end;
207 #1, #2, #3, #4, #18, #19, #20, #21:
208 begin
209 // skip color modifiers
210 end;
211 otherwise
212 begin
213 r_Draw_GetTextSize(text[i], f, cw, ch);
214 maxh := MAX(maxh, curh + ch);
215 curw := curw + cw;
216 end;
217 end;
218 end;
219 w := MAX(maxw, curw);
220 h := MAX(maxh, curh);
221 end;
223 procedure r_Common_DrawFormatText (const text: AnsiString; x, y: Integer; a: Byte; f: TGLFont; p: TBasePoint);
224 const
225 colors: array [boolean, 0..5] of TRGB = (
226 ((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)),
227 ((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))
228 );
229 var
230 i, xx, yy, cx, cy, w, h, cw, ch, cln, color: Integer; dark: Boolean;
231 begin
232 xx := x; yy := y;
233 if p <> TBasePoint.BP_LEFTUP then
234 begin
235 r_Common_GetFormatTextSize(text, f, w, h);
236 r_Common_GetBasePoint(x, y, w, h, p, xx, yy);
237 end;
238 cx := xx; cy := yy; color := 5; dark := false;
239 r_Draw_GetTextSize('W', f, cw, cln);
240 for i := 1 to Length(text) do
241 begin
242 case text[i] of
243 #10:
244 begin
245 cx := xx;
246 INC(cy, cln);
247 end;
248 #1: color := 0;
249 #2: color := 5;
250 #3: dark := true;
251 #4: dark := false;
252 #18: color := 1;
253 #19: color := 2;
254 #20: color := 4;
255 #21: color := 3;
256 otherwise
257 begin
258 r_Draw_GetTextSize(text[i], f, cw, ch);
259 r_Draw_Text(text[i], cx, cy, colors[dark, color].R, colors[dark, color].G, colors[dark, color].B, a, f);
260 INC(cx, cw);
261 end;
262 end;
263 end;
264 end;
266 function r_Common_TimeToStr (t: LongWord): AnsiString;
267 var h, m, s: Integer;
268 begin
269 h := t div 1000 div 3600;
270 m := t div 1000 div 60 mod 60;
271 s := t div 1000 mod 60;
272 result := Format('%d:%.2d:%.2d', [h, m, s]);
273 end;
275 (* --------- --------- *)
277 procedure r_Common_FreeThis (var here: THereTexture);
278 begin
279 here.name := '';
280 if here.id <> nil then
281 here.id.Free;
282 here.id := nil;
283 end;
285 function r_Common_LoadThis (const name: AnsiString; var here: THereTexture): Boolean;
286 begin
287 if name <> here.name then
288 r_Common_FreeThis(here);
289 if (name <> '') and (here.name <> name) then
290 here.id := r_Textures_LoadFromFile(name);
292 result := here.id <> nil;
294 if result then
295 here.name := name;
296 end;
298 procedure r_Common_CalcAspect (ow, oh, nw, nh: LongInt; horizontal: Boolean; out ww, hh: LongInt);
299 begin
300 if horizontal then
301 begin
302 ww := nw;
303 hh := nw * oh div ow;
304 end
305 else
306 begin
307 ww := nh * ow div oh;
308 hh := nh;
309 end;
310 end;
312 function r_Common_LoadFont (const name: AnsiString): TGLFont;
313 var info: TFontInfo; skiphack: Integer;
314 begin
315 result := nil;
316 if name = 'STD' then skiphack := 144 else skiphack := 0;
317 if r_Font_LoadInfoFromFile(GameWad + ':FONTS/' + name + 'TXT', info) then
318 result := r_Textures_LoadFontFromFile(GameWad + ':FONTS/' + name + 'FONT', info, skiphack, true);
319 if result = nil then
320 e_logwritefln('failed to load font %s', [name]);
321 end;
323 procedure r_Common_Load;
324 begin
325 stdfont := r_Common_LoadFont('STD');
326 smallfont := r_Common_LoadFont('SMALL');
327 menufont := r_Common_LoadFont('MENU');
328 end;
330 procedure r_Common_Free;
331 begin
332 menufont.Free;
333 smallfont.Free;
334 stdfont.Free;
335 end;
337 end.