DEADSOFTWARE

moved debug inspector to g_holmes.pas
[d2df-sdl.git] / src / game / g_holmes.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, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *)
16 {$INCLUDE ../shared/a_modes.inc}
17 unit g_holmes;
18
19 interface
20
21 uses
22 e_log,
23 g_textures, g_basic, e_graphics, g_phys, g_grid, g_player, g_monsters,
24 g_window, g_map, g_triggers, g_items, g_game, g_panel, g_console,
25 xprofiler;
26
27
28 type
29 THMouseEvent = record
30 public
31 const
32 // both for but and for bstate
33 Left = $0001;
34 Right = $0002;
35 Middle = $0004;
36 WheelUp = $0008;
37 WheelDown = $0010;
38
39 // event types
40 Motion = 0;
41 Press = 1;
42 Release = 2;
43
44 public
45 kind: Byte; // motion, press, release
46 x, y: Integer;
47 dx, dy: Integer; // for wheel this is wheel motion, otherwise this is relative mouse motion
48 but: Word; // current pressed button or 0
49 bstate: Word; // button state
50 kstate: Word; // keyboard state (see THKeyEvent);
51 end;
52
53 THKeyEvent = record
54 public
55 const
56 ModCtrl = $0001;
57 ModAlt = $0002;
58 ModShift = $0004;
59 end;
60
61
62 procedure g_Holmes_VidModeChanged ();
63 procedure g_Holmes_WindowFocused ();
64 procedure g_Holmes_WindowBlured ();
65
66 procedure g_Holmes_Draw ();
67
68 function g_Holmes_mouseEvent (var ev: THMouseEvent): Boolean; // returns `true` if event was eaten
69 function g_Holmes_KeyEvent (var ev: THKeyEvent): Boolean; // returns `true` if event was eaten
70
71 // hooks for player
72 procedure g_Holmes_plrView (viewPortX, viewPortY, viewPortW, viewPortH: Integer);
73 procedure g_Holmes_plrLaser (ax0, ay0, ax1, ay1: Integer);
74
75
76 implementation
77
78 uses
79 SysUtils, GL,
80 g_options;
81
82
83 var
84 //globalInited: Boolean = false;
85 msX: Integer = -666;
86 msY: Integer = -666;
87 msB: Word = 0; // button state
88 kbS: Word = 0; // keyboard modifiers state
89
90
91 // ////////////////////////////////////////////////////////////////////////// //
92 // cursor (hi, Death Track!)
93 const curWidth = 17;
94 const curHeight = 23;
95
96 const cursorImg: array[0..curWidth*curHeight-1] of Byte = (
97 0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
98 0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,
99 1,0,3,2,2,0,0,0,0,0,0,0,0,0,0,0,0,
100 1,1,3,3,2,2,0,0,0,0,0,0,0,0,0,0,0,
101 1,1,3,3,4,2,2,0,0,0,0,0,0,0,0,0,0,
102 1,1,3,3,4,4,2,2,0,0,0,0,0,0,0,0,0,
103 1,1,3,3,4,4,4,2,2,0,0,0,0,0,0,0,0,
104 1,1,3,3,4,4,4,4,2,2,0,0,0,0,0,0,0,
105 1,1,3,3,4,4,4,5,6,2,2,0,0,0,0,0,0,
106 1,1,3,3,4,4,5,6,7,5,2,2,0,0,0,0,0,
107 1,1,3,3,4,5,6,7,5,4,5,2,2,0,0,0,0,
108 1,1,3,3,5,6,7,5,4,5,6,7,2,2,0,0,0,
109 1,1,3,3,6,7,5,4,5,6,7,7,7,2,2,0,0,
110 1,1,3,3,7,5,4,5,6,7,7,7,7,7,2,2,0,
111 1,1,3,3,5,4,5,6,8,8,8,8,8,8,8,8,2,
112 1,1,3,3,4,5,6,3,8,8,8,8,8,8,8,8,8,
113 1,1,3,3,5,6,3,3,1,1,1,1,1,1,1,0,0,
114 1,1,3,3,6,3,3,1,1,1,1,1,1,1,1,0,0,
115 1,1,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,
116 1,1,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,
117 1,1,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,
118 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
119 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
120 );
121 const cursorPal: array[0..9*4-1] of Byte = (
122 0, 0, 0, 0,
123 0, 0, 0,163,
124 85,255,255,255,
125 85, 85,255,255,
126 255, 85, 85,255,
127 170, 0,170,255,
128 85, 85, 85,255,
129 0, 0, 0,255,
130 0, 0,170,255
131 );
132
133
134 var
135 curtexid: GLuint = 0;
136
137 procedure createCursorTexture ();
138 var
139 tex, tpp: PByte;
140 c: Integer;
141 x, y: Integer;
142 begin
143 if (curtexid <> 0) then exit; //begin glDeleteTextures(1, @curtexid); curtexid := 0; end;
144
145 GetMem(tex, curWidth*curHeight*4);
146
147 tpp := tex;
148 for y := 0 to curHeight-1 do
149 begin
150 for x := 0 to curWidth-1 do
151 begin
152 c := cursorImg[y*curWidth+x]*4;
153 tpp^ := cursorPal[c+0]; Inc(tpp);
154 tpp^ := cursorPal[c+1]; Inc(tpp);
155 tpp^ := cursorPal[c+2]; Inc(tpp);
156 tpp^ := cursorPal[c+3]; Inc(tpp);
157 end;
158 end;
159
160 glGenTextures(1, @curtexid);
161 if (curtexid = 0) then raise Exception.Create('can''t create Holmes texture');
162
163 glBindTexture(GL_TEXTURE_2D, curtexid);
164 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
165 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
166 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
167 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
168
169 //GLfloat[4] bclr = 0.0;
170 //glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, bclr.ptr);
171
172 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, curWidth, curHeight, 0, GL_RGBA{gltt}, GL_UNSIGNED_BYTE, tex);
173
174 //FreeMem(tex);
175 end;
176
177
178 procedure drawCursor ();
179 begin
180 if (curtexid = 0) then createCursorTexture() else glBindTexture(GL_TEXTURE_2D, curtexid);
181 // blend it
182 glEnable(GL_BLEND);
183 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
184 glEnable(GL_TEXTURE_2D);
185 // color and opacity
186 glColor4f(1, 1, 1, 0.9);
187 Dec(msX, 2);
188 glBegin(GL_QUADS);
189 glTexCoord2f(0.0, 0.0); glVertex2i(msX, msY); // top-left
190 glTexCoord2f(1.0, 0.0); glVertex2i(msX+curWidth, msY); // top-right
191 glTexCoord2f(1.0, 1.0); glVertex2i(msX+curWidth, msY+curHeight); // bottom-right
192 glTexCoord2f(0.0, 1.0); glVertex2i(msX, msY+curHeight); // bottom-left
193 glEnd();
194 Inc(msX, 2);
195 glDisable(GL_BLEND);
196 glDisable(GL_TEXTURE_2D);
197 glColor4f(1, 1, 1, 1);
198 glBindTexture(GL_TEXTURE_2D, 0);
199 end;
200
201
202 // ////////////////////////////////////////////////////////////////////////// //
203 procedure g_Holmes_VidModeChanged ();
204 begin
205 e_WriteLog(Format('Inspector: videomode changed: %dx%d', [gScreenWidth, gScreenHeight]), MSG_NOTIFY);
206 curtexid := 0; // texture is possibly lost here, idc
207 //createCursorTexture();
208 end;
209
210 procedure g_Holmes_WindowFocused ();
211 begin
212 msB := 0;
213 kbS := 0;
214 end;
215
216 procedure g_Holmes_WindowBlured ();
217 begin
218 end;
219
220
221 // ////////////////////////////////////////////////////////////////////////// //
222 var
223 vpSet: Boolean = false;
224 vpx, vpy: Integer;
225 vpw, vph: Integer;
226 laserSet: Boolean = false;
227 laserX0, laserY0, laserX1, laserY1: Integer;
228 monMarkedUID: Integer = -1;
229
230 procedure g_Holmes_plrView (viewPortX, viewPortY, viewPortW, viewPortH: Integer);
231 begin
232 vpSet := true;
233 vpx := viewPortX;
234 vpy := viewPortY;
235 vpw := viewPortW;
236 vph := viewPortH;
237 end;
238
239 procedure g_Holmes_plrLaser (ax0, ay0, ax1, ay1: Integer);
240 begin
241 laserSet := true;
242 laserX0 := ax0;
243 laserY0 := ay0;
244 laserX1 := ax1;
245 laserY1 := ay1;
246 end;
247
248
249 function pmsCurMapX (): Integer; inline; begin result := msX+vpx; end;
250 function pmsCurMapY (): Integer; inline; begin result := msY+vpy; end;
251
252
253 procedure plrDebugMouse (var ev: THMouseEvent);
254
255 function wallToggle (pan: TPanel; tag: Integer): Boolean;
256 begin
257 result := false; // don't stop
258 if pan.Enabled then g_Map_DisableWall(pan.arrIdx) else g_Map_EnableWall(pan.arrIdx);
259 end;
260
261 function monsAtDump (mon: TMonster; tag: Integer): Boolean;
262 begin
263 result := false; // don't stop
264 e_WriteLog(Format('monster #%d; UID=%d', [mon.arrIdx, mon.UID]), MSG_NOTIFY);
265 monMarkedUID := mon.UID;
266 //if pan.Enabled then g_Map_DisableWall(pan.arrIdx) else g_Map_EnableWall(pan.arrIdx);
267 end;
268
269 begin
270 //e_WriteLog(Format('mouse: x=%d; y=%d; but=%d; bstate=%d', [msx, msy, but, bstate]), MSG_NOTIFY);
271 if (gPlayer1 = nil) then exit;
272 if (ev.kind <> THMouseEvent.Press) then exit;
273
274 if (ev.but = THMouseEvent.Left) then
275 begin
276 mapGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY, wallToggle, (GridTagWall or GridTagDoor));
277 exit;
278 end;
279
280 if (ev.but = THMouseEvent.Right) then
281 begin
282 monMarkedUID := -1;
283 e_WriteLog('===========================', MSG_NOTIFY);
284 monsGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY, monsAtDump);
285 e_WriteLog('---------------------------', MSG_NOTIFY);
286 exit;
287 end;
288 end;
289
290
291 procedure plrDebugDraw ();
292
293 function monsCollector (mon: TMonster; tag: Integer): Boolean;
294 var
295 ex, ey: Integer;
296 mx, my, mw, mh: Integer;
297 begin
298 result := false;
299 mon.getMapBox(mx, my, mw, mh);
300 e_DrawQuad(mx, my, mx+mw-1, my+mh-1, 255, 255, 0, 96);
301 if lineAABBIntersects(laserX0, laserY0, laserX1, laserY1, mx, my, mw, mh, ex, ey) then
302 begin
303 e_DrawPoint(8, ex, ey, 0, 255, 0);
304 end;
305 end;
306
307 var
308 mon: TMonster;
309 mx, my, mw, mh: Integer;
310 begin
311 //e_DrawPoint(4, plrMouseX, plrMouseY, 255, 0, 255);
312 if (gPlayer1 = nil) then exit;
313
314 //e_WriteLog(Format('(%d,%d)-(%d,%d)', [laserX0, laserY0, laserX1, laserY1]), MSG_NOTIFY);
315
316 glPushMatrix();
317 glTranslatef(-vpx, -vpy, 0);
318
319 g_Mons_AlongLine(laserX0, laserY0, laserX1, laserY1, monsCollector, true);
320
321 if (monMarkedUID <> -1) then
322 begin
323 mon := g_Monsters_ByUID(monMarkedUID);
324 if (mon <> nil) then
325 begin
326 mon.getMapBox(mx, my, mw, mh);
327 e_DrawQuad(mx, my, mx+mw-1, my+mh-1, 255, 0, 0, 30);
328 end;
329 end;
330
331 //e_DrawPoint(16, laserX0, laserY0, 255, 255, 255);
332
333 glPopMatrix();
334 end;
335
336
337 {
338 procedure drawTileGrid ();
339 var
340 x, y: Integer;
341 begin
342 y := mapGrid.gridY0;
343 while (y < mapGrid.gridY0+mapGrid.gridHeight) do
344 begin
345 x := mapGrid.gridX0;
346 while (x < mapGrid.gridX0+mapGrid.gridWidth) do
347 begin
348 if (x+mapGrid.tileSize > vpx) and (y+mapGrid.tileSize > vpy) and
349 (x < vpx+vpw) and (y < vpy+vph) then
350 begin
351 e_DrawQuad(x, y, x+mapGrid.tileSize-1, y+mapGrid.tileSize-1, 96, 96, 96, 96);
352 end;
353 Inc(x, mapGrid.tileSize);
354 end;
355 Inc(y, mapGrid.tileSize);
356 end;
357 end;
358 }
359
360
361 // ////////////////////////////////////////////////////////////////////////// //
362 function g_Holmes_mouseEvent (var ev: THMouseEvent): Boolean;
363 begin
364 result := true;
365 msX := ev.x;
366 msY := ev.y;
367 msB := ev.bstate;
368 kbS := ev.kstate;
369 plrDebugMouse(ev);
370 end;
371
372
373 function g_Holmes_KeyEvent (var ev: THKeyEvent): Boolean;
374 begin
375 result := false;
376 end;
377
378
379 // ////////////////////////////////////////////////////////////////////////// //
380 procedure g_Holmes_Draw ();
381 begin
382 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // modify color buffer
383 glDisable(GL_STENCIL_TEST);
384 glDisable(GL_BLEND);
385 glDisable(GL_SCISSOR_TEST);
386 glDisable(GL_TEXTURE_2D);
387
388 plrDebugDraw();
389
390 drawCursor();
391 end;
392
393
394 end.