DEADSOFTWARE

afdadd97d76198e4f20e8ebfaabe35ea02262811
[d2df-sdl.git] / src / game / opengl / r_gfx.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_gfx;
18 interface
20 {
21 const
22 R_GFX_FLAME_WIDTH = 32;
23 R_GFX_FLAME_HEIGHT = 32;
24 R_GFX_SMOKE_WIDTH = 32;
25 R_GFX_SMOKE_HEIGHT = 32;
26 }
28 procedure r_GFX_Load;
29 procedure r_GFX_Free;
30 procedure r_GFX_Draw;
31 procedure r_GFX_Update;
33 procedure r_GFX_OnceAnim (AnimType, X, Y: Integer);
35 implementation
37 uses
38 {$INCLUDE ../nogl/noGLuses.inc}
39 SysUtils, Classes, Math,
40 utils,
41 g_base, r_graphics, g_options, r_animations,
42 g_game, g_textures,
43 g_gfx
44 ;
46 type
47 TOnceAnim = record
48 AnimType: Byte;
49 Alpha: Byte;
50 x, y: Integer;
51 oldX, oldY: Integer;
52 Animation: TAnimState;
53 end;
55 var
56 OnceAnims: array of TOnceAnim = nil;
57 gfxFrames: array [0..R_GFX_LAST] of DWORD;
59 procedure r_GFX_Load;
60 begin
61 g_Frames_CreateWAD(nil, 'FRAMES_TELEPORT', GameWAD+':TEXTURES\TELEPORT', 64, 64, 10, False);
62 g_Frames_Get(gfxFrames[R_GFX_TELEPORT], 'FRAMES_TELEPORT');
63 g_Frames_Get(gfxFrames[R_GFX_FLAME], 'FRAMES_FLAME');
64 g_Frames_Get(gfxFrames[R_GFX_EXPLODE_ROCKET], 'FRAMES_EXPLODE_ROCKET');
65 g_Frames_Get(gfxFrames[R_GFX_EXPLODE_BFG], 'FRAMES_EXPLODE_BFG');
66 g_Frames_Get(gfxFrames[R_GFX_BFG_HIT], 'FRAMES_BFGHIT');
67 g_Frames_Get(gfxFrames[R_GFX_FIRE], 'FRAMES_FIRE');
68 g_Frames_Get(gfxFrames[R_GFX_ITEM_RESPAWN], 'FRAMES_ITEM_RESPAWN');
69 g_Frames_Get(gfxFrames[R_GFX_SMOKE], 'FRAMES_SMOKE');
70 g_Frames_Get(gfxFrames[R_GFX_EXPLODE_SKELFIRE], 'FRAMES_EXPLODE_SKELFIRE');
71 g_Frames_Get(gfxFrames[R_GFX_EXPLODE_PLASMA], 'FRAMES_EXPLODE_PLASMA');
72 g_Frames_Get(gfxFrames[R_GFX_EXPLODE_BSPFIRE], 'FRAMES_EXPLODE_BSPFIRE');
73 g_Frames_Get(gfxFrames[R_GFX_EXPLODE_IMPFIRE], 'FRAMES_EXPLODE_IMPFIRE');
74 g_Frames_Get(gfxFrames[R_GFX_EXPLODE_CACOFIRE], 'FRAMES_EXPLODE_CACOFIRE');
75 g_Frames_Get(gfxFrames[R_GFX_EXPLODE_BARONFIRE], 'FRAMES_EXPLODE_BARONFIRE');
76 end;
78 procedure r_GFX_Free;
79 begin
80 g_Frames_DeleteByName('FRAMES_TELEPORT');
81 OnceAnims := nil;
82 end;
84 function FindOnceAnim (): DWORD;
85 var i: Integer;
86 begin
87 if OnceAnims <> nil then
88 for i := 0 to High(OnceAnims) do
89 if OnceAnims[i].Animation.IsInvalid() then
90 begin
91 Result := i;
92 Exit;
93 end;
94 if OnceAnims = nil then
95 begin
96 SetLength(OnceAnims, 16);
97 Result := 0;
98 end
99 else
100 begin
101 Result := High(OnceAnims) + 1;
102 SetLength(OnceAnims, Length(OnceAnims) + 16);
103 end;
104 end;
106 procedure r_GFX_OnceAnim (AnimType, x, y: Integer);
107 var find_id: DWORD; a: TAnimState; alpha: Byte;
108 begin
109 if not gpart_dbg_enabled then exit;
110 find_id := FindOnceAnim();
111 alpha := 0;
112 case AnimType of
113 R_GFX_NONE: a := TAnimState.Create(false, 0, 0);
114 R_GFX_TELEPORT: a := TAnimState.Create(false, 6, 10);
115 R_GFX_TELEPORT_FAST:
116 begin
117 AnimType := R_GFX_TELEPORT;
118 a := TAnimState.Create(false, 3, 10);
119 end;
120 R_GFX_FLAME: a := TAnimState.Create(false, 3, 11);
121 R_GFX_FLAME_RAND:
122 begin
123 AnimType := R_GFX_FLAME;
124 a := TAnimState.Create(false, 2 + Random(2), 10);
125 end;
126 R_GFX_EXPLODE_ROCKET: a := TAnimState.Create(false, 6, 6);
127 R_GFX_EXPLODE_BFG: a := TAnimState.Create(false, 6, 6);
128 R_GFX_BFG_HIT: a := TAnimState.Create(false, 4, 4);
129 R_GFX_FIRE: a := TAnimState.Create(false, 4, 8); // !!! TODO: random speed
130 R_GFX_ITEM_RESPAWN: a := TAnimState.Create(false, 4, 5);
131 R_GFX_SMOKE: a := TAnimState.Create(false, 3, 10);
132 R_GFX_SMOKE_TRANS:
133 begin
134 AnimType := R_GFX_SMOKE;
135 a := TAnimState.Create(false, 3, 10);
136 alpha := 150;
137 end;
138 R_GFX_EXPLODE_SKELFIRE: a := TAnimState.Create(false, 8, 3);
139 R_GFX_EXPLODE_PLASMA: a := TAnimState.Create(false, 3, 4);
140 R_GFX_EXPLODE_BSPFIRE: a := TAnimState.Create(false, 3, 5);
141 R_GFX_EXPLODE_IMPFIRE: a := TAnimState.Create(false, 6, 3);
142 R_GFX_EXPLODE_CACOFIRE: a := TAnimState.Create(false, 6, 3);
143 R_GFX_EXPLODE_BARONFIRE: a := TAnimState.Create(false, 6, 3);
144 else
145 a := TAnimState.Create(false, 0, 0);
146 raise Exception.Create('invalid anim type');
147 end;
148 OnceAnims[find_id].AnimType := AnimType;
149 OnceAnims[find_id].Alpha := alpha;
150 OnceAnims[find_id].Animation := a;
151 OnceAnims[find_id].Animation.Reset();
152 OnceAnims[find_id].Animation.Enable();
153 OnceAnims[find_id].x := x;
154 OnceAnims[find_id].y := y;
155 end;
157 procedure r_GFX_Update;
158 var a: Integer;
159 begin
160 if OnceAnims <> nil then
161 begin
162 for a := 0 to High(OnceAnims) do
163 begin
164 if OnceAnims[a].Animation.IsValid() then
165 begin
166 OnceAnims[a].oldx := OnceAnims[a].x;
167 OnceAnims[a].oldy := OnceAnims[a].y;
168 case OnceAnims[a].AnimType of
169 R_GFX_FLAME, R_GFX_SMOKE: (*ONCEANIM_SMOKE:*)
170 begin
171 if Random(3) = 0 then
172 OnceAnims[a].x := OnceAnims[a].x-1+Random(3);
173 if Random(2) = 0 then
174 OnceAnims[a].y := OnceAnims[a].y-Random(2);
175 end;
176 end;
177 if OnceAnims[a].Animation.Played then
178 OnceAnims[a].Animation.Invalidate()
179 else
180 OnceAnims[a].Animation.Update();
181 end;
182 end;
183 end;
184 end;
186 procedure r_GFX_Draw;
187 var
188 a, len, fx, fy: Integer;
189 begin
190 if not gpart_dbg_enabled then exit;
192 if (Particles <> nil) then
193 begin
194 glDisable(GL_TEXTURE_2D);
195 if (g_dbg_scale < 0.6) then glPointSize(1)
196 else if (g_dbg_scale > 1.3) then glPointSize(g_dbg_scale+1)
197 else glPointSize(2);
198 glDisable(GL_POINT_SMOOTH);
200 glEnable(GL_BLEND);
201 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
203 glBegin(GL_POINTS);
205 len := High(Particles);
206 for a := 0 to len do
207 begin
208 with Particles[a] do
209 begin
210 if not alive then continue;
211 if (x >= sX) and (y >= sY) and (x <= sX+sWidth) and (sY <= sY+sHeight) then
212 begin
213 fx := nlerp(oldx, x, gLerpFactor);
214 fy := nlerp(oldy, y, gLerpFactor);
215 glColor4ub(red, green, blue, alpha);
216 glVertex2f(fx+0.37, fy+0.37);
217 end;
218 end;
219 end;
221 glEnd();
223 glDisable(GL_BLEND);
224 end;
226 if (OnceAnims <> nil) then
227 begin
228 len := High(OnceAnims);
229 for a := 0 to len do
230 begin
231 if OnceAnims[a].Animation.IsValid() then
232 begin
233 with OnceAnims[a] do
234 begin
235 fx := nlerp(oldx, x, gLerpFactor);
236 fy := nlerp(oldy, y, gLerpFactor);
237 r_AnimState_Draw(gfxFrames[AnimType], Animation, x, y, Alpha, TMirrorType.None, False);
238 end;
239 end;
240 end;
241 end;
242 end;
244 end.