X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_holmes.pas;h=b7ad74b79db8028d84f2711100434655a9e5eebe;hb=6e01cec550eeb3390d2875b4f381f1653a0c2a85;hp=f4fe415cbf97a6f499b01b65e342e0ae1b12136e;hpb=ad4f5ec68b851b9b2dba627e3b199b93f529dc86;p=d2df-sdl.git diff --git a/src/game/g_holmes.pas b/src/game/g_holmes.pas index f4fe415..b7ad74b 100644 --- a/src/game/g_holmes.pas +++ b/src/game/g_holmes.pas @@ -2,8 +2,7 @@ * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * the Free Software Foundation, version 3 of the License ONLY. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -18,83 +17,100 @@ unit g_holmes; interface -uses - mempool, geom, - e_log, e_input, - g_textures, g_basic, e_graphics, g_phys, g_grid, g_player, g_monsters, - g_window, g_map, g_triggers, g_items, g_game, g_panel, g_console, g_gfx, - xprofiler, - sdlcarcass, - fui_common, fui_events, fui_ctls, - fui_gfx_gl; + procedure holmesInitCommands (); + procedure holmesInitBinds (); + function monsTypeToString (mt: Byte): AnsiString; + function monsBehToString (bt: Byte): AnsiString; + function monsStateToString (st: Byte): AnsiString; + function trigType2Str (ttype: Integer): AnsiString; -procedure g_Holmes_Draw (); -procedure g_Holmes_DrawUI (); - -procedure g_Holmes_OnEvent (var ev: TFUIEvent); - -// hooks for player -procedure g_Holmes_plrViewPos (viewPortX, viewPortY: Integer); -procedure g_Holmes_plrViewSize (viewPortW, viewPortH: Integer); -procedure g_Holmes_plrLaser (ax0, ay0, ax1, ay1: Integer); + var + g_holmes_imfunctional: Boolean = false; + g_holmes_enabled: Boolean = {$IF DEFINED(D2F_DEBUG)}true{$ELSE}false{$ENDIF}; + var + msX: Integer = -666; + msY: Integer = -666; + showGrid: Boolean = {$IF DEFINED(D2F_DEBUG)}false{$ELSE}false{$ENDIF}; + showMonsInfo: Boolean = false; + showMonsLOS2Plr: Boolean = false; + showAllMonsCells: Boolean = false; + showMapCurPos: Boolean = false; + showLayersWindow: Boolean = false; + showOutlineWindow: Boolean = false; + showTriggers: Boolean = {$IF DEFINED(D2F_DEBUG)}false{$ELSE}false{$ENDIF}; + showTraceBox: Boolean = {$IF DEFINED(D2F_DEBUG)}false{$ELSE}false{$ENDIF}; -var - g_holmes_imfunctional: Boolean = false; - g_holmes_enabled: Boolean = {$IF DEFINED(D2F_DEBUG)}true{$ELSE}false{$ENDIF}; + var + g_ol_nice: Boolean = false; + g_ol_fill_walls: Boolean = false; + g_ol_rlayer_back: Boolean = false; + g_ol_rlayer_step: Boolean = false; + g_ol_rlayer_wall: Boolean = false; + g_ol_rlayer_door: Boolean = false; + g_ol_rlayer_acid1: Boolean = false; + g_ol_rlayer_acid2: Boolean = false; + g_ol_rlayer_water: Boolean = false; + g_ol_rlayer_fore: Boolean = false; + var + monMarkedUID: Integer = -1; + platMarkedGUID: Integer = -1; implementation uses - {rttiobj,} typinfo, e_texture, - SysUtils, Classes, GL, SDL2, - MAPDEF, g_main, g_options, - utils, hashtable, xparser; + {mempool,} + e_log, e_input, + g_player, g_monsters, + g_map, g_triggers, g_game, g_panel, g_console, + {xprofiler,} + fui_common, fui_events, fui_ctls, + {$IFDEF ENABLE_RENDER} + r_render, + {$ENDIF} + {rttiobj,} typinfo, e_res, + SysUtils, Classes, + {$IFDEF USE_SDL2} + SDL2, + {$ENDIF} + MAPDEF, g_options, + hashtable, xparser; var - hlmContext: TGxContext = nil; //globalInited: Boolean = false; - msX: Integer = -666; - msY: Integer = -666; msB: Word = 0; // button state kbS: Word = 0; // keyboard modifiers state - showGrid: Boolean = {$IF DEFINED(D2F_DEBUG)}false{$ELSE}false{$ENDIF}; - showMonsInfo: Boolean = false; - showMonsLOS2Plr: Boolean = false; - showAllMonsCells: Boolean = false; - showMapCurPos: Boolean = false; - showLayersWindow: Boolean = false; - showOutlineWindow: Boolean = false; - showTriggers: Boolean = {$IF DEFINED(D2F_DEBUG)}false{$ELSE}false{$ENDIF}; - showTraceBox: Boolean = {$IF DEFINED(D2F_DEBUG)}false{$ELSE}false{$ENDIF}; // ////////////////////////////////////////////////////////////////////////// // {$INCLUDE g_holmes.inc} -{$INCLUDE g_holmes_ol.inc} // outliner // ////////////////////////////////////////////////////////////////////////// // {$INCLUDE g_holmes_cmd.inc} -procedure holmesInitCommands (); forward; -procedure holmesInitBinds (); forward; // ////////////////////////////////////////////////////////////////////////// // -var - g_ol_nice: Boolean = false; - g_ol_fill_walls: Boolean = false; - g_ol_rlayer_back: Boolean = false; - g_ol_rlayer_step: Boolean = false; - g_ol_rlayer_wall: Boolean = false; - g_ol_rlayer_door: Boolean = false; - g_ol_rlayer_acid1: Boolean = false; - g_ol_rlayer_acid2: Boolean = false; - g_ol_rlayer_water: Boolean = false; - g_ol_rlayer_fore: Boolean = false; + +{$IF NOT DEFINED(ENABLE_RENDER)} +function pmsCurMapX (): Integer; inline; +begin + result := round(msX/g_dbg_scale) +end; + +function pmsCurMapY (): Integer; inline; +begin + result := round(msY/g_dbg_scale) +end; + +function r_Render_HolmesViewIsSet (): Boolean; +begin + result := false +end; +{$ENDIF} // ////////////////////////////////////////////////////////////////////////// // @@ -509,846 +525,7 @@ end; // ////////////////////////////////////////////////////////////////////////// // -var - vpSet: Boolean = false; - vpx, vpy: Integer; - vpw, vph: Integer; - laserSet: Boolean = false; - laserX0, laserY0, laserX1, laserY1: Integer; - monMarkedUID: Integer = -1; - platMarkedGUID: Integer = -1; - - -procedure g_Holmes_plrViewPos (viewPortX, viewPortY: Integer); -begin - vpSet := true; - vpx := viewPortX; - vpy := viewPortY; -end; - -procedure g_Holmes_plrViewSize (viewPortW, viewPortH: Integer); -begin - vpSet := true; - vpw := viewPortW; - vph := viewPortH; -end; - -procedure g_Holmes_plrLaser (ax0, ay0, ax1, ay1: Integer); -begin - laserSet := true; - laserX0 := ax0; - laserY0 := ay0; - laserX1 := ax1; - laserY1 := ay1; - laserSet := laserSet; // shut up, fpc! -end; - - -function pmsCurMapX (): Integer; inline; begin result := round(msX/g_dbg_scale)+vpx; end; -function pmsCurMapY (): Integer; inline; begin result := round(msY/g_dbg_scale)+vpy; end; - - -{$IFDEF HOLMES_OLD_OUTLINES} -var - edgeBmp: array of Byte = nil; - - -procedure drawOutlines (); -var - r, g, b: Integer; - - procedure clearEdgeBmp (); - begin - SetLength(edgeBmp, (gWinSizeX+4)*(gWinSizeY+4)); - FillChar(edgeBmp[0], Length(edgeBmp)*sizeof(edgeBmp[0]), 0); - end; - - procedure drawPanel (pan: TPanel); - var - sx, len, y0, y1: Integer; - begin - if (pan = nil) or (pan.Width < 1) or (pan.Height < 1) then exit; - if (pan.X+pan.Width <= vpx-1) or (pan.Y+pan.Height <= vpy-1) then exit; - if (pan.X >= vpx+vpw+1) or (pan.Y >= vpy+vph+1) then exit; - if g_ol_nice or g_ol_fill_walls then - begin - sx := pan.X-(vpx-1); - len := pan.Width; - if (len > gWinSizeX+4) then len := gWinSizeX+4; - if (sx < 0) then begin len += sx; sx := 0; end; - if (sx+len > gWinSizeX+4) then len := gWinSizeX+4-sx; - if (len < 1) then exit; - assert(sx >= 0); - assert(sx+len <= gWinSizeX+4); - y0 := pan.Y-(vpy-1); - y1 := y0+pan.Height; - if (y0 < 0) then y0 := 0; - if (y1 > gWinSizeY+4) then y1 := gWinSizeY+4; - while (y0 < y1) do - begin - FillChar(edgeBmp[y0*(gWinSizeX+4)+sx], len*sizeof(edgeBmp[0]), 1); - Inc(y0); - end; - end - else - begin - drawRect(pan.X, pan.Y, pan.Width, pan.Height, r, g, b); - end; - end; - -var - lsx: Integer = -1; - lex: Integer = -1; - lsy: Integer = -1; - - procedure flushLine (); - begin - if (lsy > 0) and (lsx > 0) then - begin - if (lex = lsx) then - begin - glBegin(GL_POINTS); - glVertex2f(lsx-1+vpx+0.37, lsy-1+vpy+0.37); - glEnd(); - end - else - begin - glBegin(GL_LINES); - glVertex2f(lsx-1+vpx+0.37, lsy-1+vpy+0.37); - glVertex2f(lex-0+vpx+0.37, lsy-1+vpy+0.37); - glEnd(); - end; - end; - lsx := -1; - lex := -1; - end; - - procedure startLine (y: Integer); - begin - flushLine(); - lsy := y; - end; - - procedure putPixel (x: Integer); - begin - if (x < 1) then exit; - if (lex+1 <> x) then flushLine(); - if (lsx < 0) then lsx := x; - lex := x; - end; - - procedure drawEdges (); - var - x, y: Integer; - a: PByte; - begin - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - glLineWidth(1); - glPointSize(1); - glDisable(GL_LINE_SMOOTH); - glDisable(GL_POLYGON_SMOOTH); - glColor4f(r/255.0, g/255.0, b/255.0, 1.0); - for y := 1 to vph do - begin - a := @edgeBmp[y*(gWinSizeX+4)+1]; - startLine(y); - for x := 1 to vpw do - begin - if (a[0] <> 0) then - begin - if (a[-1] = 0) or (a[1] = 0) or (a[-(gWinSizeX+4)] = 0) or (a[gWinSizeX+4] = 0) or - (a[-(gWinSizeX+4)-1] = 0) or (a[-(gWinSizeX+4)+1] = 0) or - (a[gWinSizeX+4-1] = 0) or (a[gWinSizeX+4+1] = 0) then - begin - putPixel(x); - end; - end; - Inc(a); - end; - flushLine(); - end; - end; - - procedure drawFilledWalls (); - var - x, y: Integer; - a: PByte; - begin - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - glLineWidth(1); - glPointSize(1); - glDisable(GL_LINE_SMOOTH); - glDisable(GL_POLYGON_SMOOTH); - glColor4f(r/255.0, g/255.0, b/255.0, 1.0); - for y := 1 to vph do - begin - a := @edgeBmp[y*(gWinSizeX+4)+1]; - startLine(y); - for x := 1 to vpw do - begin - if (a[0] <> 0) then putPixel(x); - Inc(a); - end; - flushLine(); - end; - end; - - procedure doWallsOld (parr: array of TPanel; ptype: Word; ar, ag, ab: Integer); - var - f: Integer; - pan: TPanel; - begin - r := ar; - g := ag; - b := ab; - if g_ol_nice or g_ol_fill_walls then clearEdgeBmp(); - for f := 0 to High(parr) do - begin - pan := parr[f]; - if (pan = nil) or not pan.Enabled or (pan.Width < 1) or (pan.Height < 1) then continue; - if ((pan.PanelType and ptype) = 0) then continue; - drawPanel(pan); - end; - if g_ol_nice then drawEdges(); - if g_ol_fill_walls then drawFilledWalls(); - end; - -var - xptag: Word; - - function doWallCB (pan: TPanel; tag: Integer): Boolean; - begin - result := false; // don't stop - //if (pan = nil) or not pan.Enabled or (pan.Width < 1) or (pan.Height < 1) then exit; - if ((pan.PanelType and xptag) = 0) then exit; - drawPanel(pan); - end; - - procedure doWalls (parr: array of TPanel; ptype: Word; ar, ag, ab: Integer); - begin - r := ar; - g := ag; - b := ab; - xptag := ptype; - if ((ptype and (PANEL_WALL or PANEL_OPENDOOR or PANEL_CLOSEDOOR)) <> 0) then ptype := GridTagWall or GridTagDoor - else panelTypeToTag(ptype); - if g_ol_nice or g_ol_fill_walls then clearEdgeBmp(); - mapGrid.forEachInAABB(vpx-1, vpy-1, vpw+2, vph+2, doWallCB, ptype); - if g_ol_nice then drawEdges(); - if g_ol_fill_walls then drawFilledWalls(); - end; - -begin - if g_ol_rlayer_back then doWallsOld(gRenderBackgrounds, PANEL_BACK, 255, 127, 0); - if g_ol_rlayer_step then doWallsOld(gSteps, PANEL_STEP, 192, 192, 192); - if g_ol_rlayer_wall then doWallsOld(gWalls, PANEL_WALL, 255, 255, 255); - if g_ol_rlayer_door then doWallsOld(gWalls, PANEL_OPENDOOR or PANEL_CLOSEDOOR, 0, 255, 0); - if g_ol_rlayer_acid1 then doWallsOld(gAcid1, PANEL_ACID1, 255, 0, 0); - if g_ol_rlayer_acid2 then doWallsOld(gAcid2, PANEL_ACID2, 198, 198, 0); - if g_ol_rlayer_water then doWallsOld(gWater, PANEL_WATER, 0, 255, 255); - if g_ol_rlayer_fore then doWallsOld(gRenderForegrounds, PANEL_FORE, 210, 210, 210); -end; - -{$ELSE} -var - oliner: TOutliner = nil; - -procedure drawOutlines (); -var - r, g, b: Integer; - - procedure clearOliner (); - begin - //if (oliner <> nil) and ((oliner.height <> vph+2) or (oliner.width <> vpw+2)) then begin oliner.Free(); oliner := nil; end; - if (oliner = nil) then oliner := TOutliner.Create(vpw+2, vph+2) else oliner.setup(vpw+2, vph+2); - end; - - procedure drawOutline (ol: TOutliner; sx, sy: Integer); - procedure xline (x0, x1, y: Integer); - var - x: Integer; - begin - if (g_dbg_scale < 1.0) then - begin - glBegin(GL_POINTS); - for x := x0 to x1 do glVertex2f(sx+x+0.375, sy+y+0.375); - glEnd(); - end - else - begin - glBegin(GL_QUADS); - glVertex2f(sx+x0+0, sy+y+0); - glVertex2f(sx+x1+1, sy+y+0); - glVertex2f(sx+x1+1, sy+y+1); - glVertex2f(sx+x0+0, sy+y+1); - glEnd(); - end; - end; - var - y: Integer; - sp: TOutliner.TSpanX; - begin - if (ol = nil) then exit; - glPointSize(1); - glDisable(GL_POINT_SMOOTH); - for y := 0 to ol.height-1 do - begin - for sp in ol.eachSpanAtY(y) do - begin - if (g_dbg_scale <= 1.0) then - begin - glBegin(GL_POINTS); - glVertex2f(sx+sp.x0+0.375, sy+y+0.375); - glVertex2f(sx+sp.x1+0.375, sy+y+0.375); - glEnd(); - end - else - begin - glBegin(GL_QUADS); - glVertex2f(sx+sp.x0+0, sy+y+0); - glVertex2f(sx+sp.x0+1, sy+y+0); - glVertex2f(sx+sp.x0+1, sy+y+1); - glVertex2f(sx+sp.x0+0, sy+y+1); - - glVertex2f(sx+sp.x1+0, sy+y+0); - glVertex2f(sx+sp.x1+1, sy+y+0); - glVertex2f(sx+sp.x1+1, sy+y+1); - glVertex2f(sx+sp.x1+0, sy+y+1); - glEnd(); - end; - end; - for sp in ol.eachSpanEdgeAtY(y, -1) do - begin - xline(sp.x0, sp.x1, y); - { - glBegin(GL_QUADS); - glVertex2f(sx+sp.x0+0, sy+y+0); - glVertex2f(sx+sp.x1+1, sy+y+0); - glVertex2f(sx+sp.x1+1, sy+y+1); - glVertex2f(sx+sp.x0+0, sy+y+1); - glEnd(); - } - end; - for sp in ol.eachSpanEdgeAtY(y, +1) do - begin - xline(sp.x0, sp.x1, y); - { - glBegin(GL_QUADS); - glVertex2f(sx+sp.x0+0, sy+y+0); - glVertex2f(sx+sp.x1+1, sy+y+0); - glVertex2f(sx+sp.x1+1, sy+y+1); - glVertex2f(sx+sp.x0+0, sy+y+1); - glEnd(); - } - end; - end; - end; - - procedure doWallsOld (parr: array of TPanel; ptype: Word; ar, ag, ab: Integer); - var - f: Integer; - pan: TPanel; - begin - r := ar; - g := ag; - b := ab; - if g_ol_nice then clearOliner(); - hlmContext.color := TGxRGBA.Create(r, g, b); - for f := 0 to High(parr) do - begin - pan := parr[f]; - if (pan = nil) or not pan.Enabled or (pan.Width < 1) or (pan.Height < 1) then continue; - if ((pan.PanelType and ptype) = 0) then continue; - if (pan.X > vpx+vpw+41) or (pan.Y > vpy+vph+41) then continue; - if (pan.X+pan.Width < vpx-41) then continue; - if (pan.Y+pan.Height < vpy-41) then continue; - if g_ol_nice then - begin - oliner.addRect(pan.X-(vpx+1), pan.Y-(vpy+1), pan.Width, pan.Height); - end; - if g_ol_fill_walls then - begin - hlmContext.fillRect(pan.X, pan.Y, pan.Width, pan.Height); - end - else if not g_ol_nice then - begin - hlmContext.rect(pan.X, pan.Y, pan.Width, pan.Height); - end; - end; - if g_ol_nice then - begin - glColor4f(r/255.0, g/255.0, b/255.0, 1.0); - drawOutline(oliner, vpx+1, vpy+1); - end; - end; - -begin - if (vpw < 2) or (vph < 2) then exit; - if g_ol_rlayer_back then doWallsOld(gRenderBackgrounds, PANEL_BACK, 255, 127, 0); - if g_ol_rlayer_step then doWallsOld(gSteps, PANEL_STEP, 192, 192, 192); - if g_ol_rlayer_wall then doWallsOld(gWalls, PANEL_WALL, 255, 255, 255); - if g_ol_rlayer_door then doWallsOld(gWalls, PANEL_OPENDOOR or PANEL_CLOSEDOOR, 0, 255, 0); - if g_ol_rlayer_acid1 then doWallsOld(gAcid1, PANEL_ACID1, 255, 0, 0); - if g_ol_rlayer_acid2 then doWallsOld(gAcid2, PANEL_ACID2, 198, 198, 0); - if g_ol_rlayer_water then doWallsOld(gWater, PANEL_WATER, 0, 255, 255); - if g_ol_rlayer_fore then doWallsOld(gRenderForegrounds, PANEL_FORE, 210, 210, 210); -end; -{$ENDIF} - - -procedure plrDebugDraw (); - procedure drawTileGrid (); - var - x, y: Integer; - begin - hlmContext.color := TGxRGBA.Create(96, 96, 96); - for y := 0 to (mapGrid.gridHeight div mapGrid.tileSize) do - begin - hlmContext.line(mapGrid.gridX0, mapGrid.gridY0+y*mapGrid.tileSize, mapGrid.gridX0+mapGrid.gridWidth, mapGrid.gridY0+y*mapGrid.tileSize); - end; - - hlmContext.color := TGxRGBA.Create(96, 96, 96); - for x := 0 to (mapGrid.gridWidth div mapGrid.tileSize) do - begin - hlmContext.line(mapGrid.gridX0+x*mapGrid.tileSize, mapGrid.gridY0, mapGrid.gridX0+x*mapGrid.tileSize, mapGrid.gridY0+y*mapGrid.gridHeight); - end; - end; - - procedure drawAwakeCells (); - var - x, y: Integer; - begin - hlmContext.color := TGxRGBA.Create(128, 0, 128, 64); - for y := 0 to (mapGrid.gridHeight div mapGrid.tileSize) do - begin - for x := 0 to (mapGrid.gridWidth div mapGrid.tileSize) do - begin - if awmIsSetHolmes(x*mapGrid.tileSize+mapGrid.gridX0+1, y*mapGrid.tileSize++mapGrid.gridY0+1) then - begin - hlmContext.fillRect(x*mapGrid.tileSize++mapGrid.gridX0, y*mapGrid.tileSize++mapGrid.gridY0, monsGrid.tileSize, monsGrid.tileSize); - end; - end; - end; - end; - - procedure drawTraceBox (); - var - plr: TPlayer; - px, py, pw, ph: Integer; - pdx, pdy: Integer; - ex, ey: Integer; - pan: TPanel; - begin - if (Length(gPlayers) < 1) then exit; - plr := gPlayers[0]; - if (plr = nil) then exit; - plr.getMapBox(px, py, pw, ph); - hlmContext.color := TGxRGBA.Create(255, 0, 255, 200); - hlmContext.rect(px, py, pw, ph); - pdx := pmsCurMapX-(px+pw div 2); - pdy := pmsCurMapY-(py+ph div 2); - hlmContext.color := TGxRGBA.Create(255, 0, 255, 200); - hlmContext.line(px+pw div 2, py+ph div 2, px+pw div 2+pdx, py+ph div 2+pdy); - pan := mapGrid.traceBox(ex, ey, px, py, pw, ph, pdx, pdy, GridTagObstacle); - if (pan = nil) then - begin - hlmContext.color := TGxRGBA.Create(255, 255, 255, 180); - hlmContext.rect(px+pdx, py+pdy, pw, ph); - end - else - begin - hlmContext.color := TGxRGBA.Create(255, 255, 0, 180); - hlmContext.rect(px+pdx, py+pdy, pw, ph); - end; - hlmContext.color := TGxRGBA.Create(255, 127, 0, 180); - hlmContext.rect(ex, ey, pw, ph); - end; - - procedure hilightCell (cx, cy: Integer); - begin - hlmContext.color := TGxRGBA.Create(0, 128, 0, 64); - hlmContext.fillRect(cx, cy, monsGrid.tileSize, monsGrid.tileSize); - end; - - procedure hilightBodyCells (proxyId: Integer); - var - pmark: PoolMark; - hitcount: Integer; - pcellxy: PGridCellCoord; - begin - //monsGrid.forEachBodyCell(mon.proxyId, hilightCell); - pmark := framePool.mark(); - hitcount := monsGrid.forEachBodyCell(proxyId); - pcellxy := PGridCellCoord(framePool.getPtr(pmark)); - while (hitcount > 0) do - begin - hilightCell(pcellxy^.x, pcellxy^.y); - Inc(pcellxy); - Dec(hitcount); - end; - framePool.release(pmark); - end; - - procedure hilightCell1 (cx, cy: Integer); - begin - //e_WriteLog(Format('h1: (%d,%d)', [cx, cy]), MSG_NOTIFY); - cx := cx and (not (monsGrid.tileSize-1)); - cy := cy and (not (monsGrid.tileSize-1)); - hlmContext.color := TGxRGBA.Create(255, 255, 0, 92); - hlmContext.fillRect(cx, cy, monsGrid.tileSize, monsGrid.tileSize); - end; - - function hilightWallTrc (pan: TPanel; tag: Integer; x, y, prevx, prevy: Integer): Boolean; - begin - result := false; // don't stop - if (pan = nil) then exit; // cell completion, ignore - //e_WriteLog(Format('h1: (%d,%d)', [cx, cy]), MSG_NOTIFY); - hlmContext.color := TGxRGBA.Create(0, 128, 128, 64); - hlmContext.fillRect(pan.X, pan.Y, pan.Width, pan.Height); - end; - - procedure monsCollector (mon: TMonster); - var - ex, ey: Integer; - mx, my, mw, mh: Integer; - begin - mon.getMapBox(mx, my, mw, mh); - hlmContext.color := TGxRGBA.Create(255, 255, 0, 160); - hlmContext.rect(mx, my, mw, mh); - //e_DrawQuad(mx, my, mx+mw-1, my+mh-1, 255, 255, 0, 96); - if lineAABBIntersects(laserX0, laserY0, laserX1, laserY1, mx, my, mw, mh, ex, ey) then - begin - //e_DrawPoint(8, ex, ey, 0, 255, 0); - hlmContext.color := TGxRGBA.Create(0, 255, 0, 220); - hlmContext.fillRect(ex-2, ey-2, 7, 7); - end; - end; - - procedure drawMonsterInfo (mon: TMonster); - var - mx, my, mw, mh: Integer; - - procedure drawMonsterTargetLine (); - var - emx, emy, emw, emh: Integer; - enemy: TMonster; - eplr: TPlayer; - ex, ey: Integer; - begin - if (g_GetUIDType(mon.MonsterTargetUID) = UID_PLAYER) then - begin - eplr := g_Player_Get(mon.MonsterTargetUID); - if (eplr <> nil) then eplr.getMapBox(emx, emy, emw, emh) else exit; - end - else if (g_GetUIDType(mon.MonsterTargetUID) = UID_MONSTER) then - begin - enemy := g_Monsters_ByUID(mon.MonsterTargetUID); - if (enemy <> nil) then enemy.getMapBox(emx, emy, emw, emh) else exit; - end - else - begin - exit; - end; - mon.getMapBox(mx, my, mw, mh); - hlmContext.color := TGxRGBA.Create(255, 0, 0); - hlmContext.line(mx+mw div 2, my+mh div 2, emx+emw div 2, emy+emh div 2); - if (g_Map_traceToNearestWall(mx+mw div 2, my+mh div 2, emx+emw div 2, emy+emh div 2, @ex, @ey) <> nil) then - begin - hlmContext.color := TGxRGBA.Create(0, 255, 0); - hlmContext.line(mx+mw div 2, my+mh div 2, ex, ey); - end; - end; - - procedure drawLOS2Plr (); - var - emx, emy, emw, emh: Integer; - eplr: TPlayer; - ex, ey: Integer; - begin - eplr := gPlayers[0]; - if (eplr = nil) then exit; - eplr.getMapBox(emx, emy, emw, emh); - mon.getMapBox(mx, my, mw, mh); - hlmContext.color := TGxRGBA.Create(255, 0, 0); - hlmContext.line(mx+mw div 2, my+mh div 2, emx+emw div 2, emy+emh div 2); - {$IF DEFINED(D2F_DEBUG)} - mapGrid.dbgRayTraceTileHitCB := hilightCell1; - {$ENDIF} - if (g_Map_traceToNearestWall(mx+mw div 2, my+mh div 2, emx+emw div 2, emy+emh div 2, @ex, @ey) <> nil) then - //if (mapGrid.traceRay(ex, ey, mx+mw div 2, my+mh div 2, emx+emw div 2, emy+emh div 2, hilightWallTrc, (GridTagWall or GridTagDoor)) <> nil) then - begin - hlmContext.color := TGxRGBA.Create(0, 255, 0); - hlmContext.line(mx+mw div 2, my+mh div 2, ex, ey); - end; - {$IF DEFINED(D2F_DEBUG)} - mapGrid.dbgRayTraceTileHitCB := nil; - {$ENDIF} - end; - - begin - if (mon = nil) then exit; - mon.getMapBox(mx, my, mw, mh); - //mx += mw div 2; - - //monsGrid.forEachBodyCell(mon.proxyId, hilightCell); - hilightBodyCells(mon.proxyId); - - if showMonsInfo then - begin - //fillRect(mx-4, my-7*8-6, 110, 7*8+6, 0, 0, 94, 250); - hlmContext.font := 'msx6'; - hlmContext.color := TGxRGBA.Create(255, 127, 0); - - hlmContext.darkenRect(mx-4, my-7*hlmContext.charWidth(' ')-6, 110, 7*hlmContext.charWidth(' ')+6, 128); - my -= 8; - my -= 2; - - // type - hlmContext.drawText(mx, my, Format('%s(U:%u)', [monsTypeToString(mon.MonsterType), mon.UID])); my -= hlmContext.charWidth(' '); - // beh - hlmContext.drawText(mx, my, Format('Beh: %s', [monsBehToString(mon.MonsterBehaviour)])); my -= hlmContext.charWidth(' '); - // state - hlmContext.drawText(mx, my, Format('State:%s (%d)', [monsStateToString(mon.MonsterState), mon.MonsterSleep])); my -= hlmContext.charWidth(' '); - // health - hlmContext.drawText(mx, my, Format('Health:%d', [mon.MonsterHealth])); my -= hlmContext.charWidth(' '); - // ammo - hlmContext.drawText(mx, my, Format('Ammo:%d', [mon.MonsterAmmo])); my -= hlmContext.charWidth(' '); - // target - hlmContext.drawText(mx, my, Format('TgtUID:%u', [mon.MonsterTargetUID])); my -= hlmContext.charWidth(' '); - hlmContext.drawText(mx, my, Format('TgtTime:%d', [mon.MonsterTargetTime])); my -= hlmContext.charWidth(' '); - end; - - drawMonsterTargetLine(); - if showMonsLOS2Plr then drawLOS2Plr(); - { - property MonsterRemoved: Boolean read FRemoved write FRemoved; - property MonsterPain: Integer read FPain write FPain; - property MonsterAnim: Byte read FCurAnim write FCurAnim; - } - end; - - function highlightAllMonsterCells (mon: TMonster): Boolean; - begin - result := false; // don't stop - //monsGrid.forEachBodyCell(mon.proxyId, hilightCell); - hilightBodyCells(mon.proxyId); - end; - - procedure drawSelectedPlatformCells (); - var - pan: TPanel; - begin - if not showGrid then exit; - pan := g_Map_PanelByGUID(platMarkedGUID); - if (pan = nil) then exit; - //mapGrid.forEachBodyCell(pan.proxyId, hilightCell); - hilightBodyCells(pan.proxyId); - hlmContext.color := TGxRGBA.Create(0, 200, 0, 200); - hlmContext.rect(pan.x, pan.y, pan.width, pan.height); - end; - - procedure drawTrigger (var trig: TTrigger); - - procedure drawPanelDest (pguid: Integer); - var - pan: TPanel; - begin - pan := g_Map_PanelByGUID(pguid); - if (pan = nil) then exit; - hlmContext.color := TGxRGBA.Create(255, 0, 255, 220); - hlmContext.line(trig.trigCenter.x, trig.trigCenter.y, pan.x+pan.width div 2, pan.y+pan.height div 2); - end; - - var - tts: AnsiString; - tx: Integer; - begin - hlmContext.font := 'msx6'; - hlmContext.color := TGxRGBA.Create(255, 0, 255, 96); - hlmContext.fillRect(trig.x, trig.y, trig.width, trig.height); - tts := trigType2Str(trig.TriggerType); - tx := trig.x+(trig.width-Length(tts)*6) div 2; - hlmContext.darkenRect(tx-2, trig.y-10, Length(tts)*6+4, 10, 64); - hlmContext.color := TGxRGBA.Create(255, 127, 0); - hlmContext.drawText(tx, trig.y-9, tts); - tx := trig.x+(trig.width-Length(trig.mapId)*6) div 2; - hlmContext.darkenRect(tx-2, trig.y-20, Length(trig.mapId)*6+4, 10, 64); - hlmContext.color := TGxRGBA.Create(255, 255, 0); - hlmContext.drawText(tx, trig.y-19, trig.mapId); - drawPanelDest(trig.trigPanelGUID); - case trig.TriggerType of - TRIGGER_NONE: begin end; - TRIGGER_EXIT: begin end; - TRIGGER_TELEPORT: begin end; - TRIGGER_OPENDOOR: begin end; - TRIGGER_CLOSEDOOR: begin end; - TRIGGER_DOOR: begin end; - TRIGGER_DOOR5: begin end; - TRIGGER_CLOSETRAP: begin end; - TRIGGER_TRAP: begin end; - TRIGGER_SECRET: begin end; - TRIGGER_LIFTUP: begin end; - TRIGGER_LIFTDOWN: begin end; - TRIGGER_LIFT: begin end; - TRIGGER_TEXTURE: begin end; - TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF, TRIGGER_PRESS: - begin - if (trig.trigDataRec.trigTWidth > 0) and (trig.trigDataRec.trigTHeight > 0) then - begin - hlmContext.color := TGxRGBA.Create(0, 255, 255, 42); - hlmContext.fillRect( - trig.trigDataRec.trigTX, trig.trigDataRec.trigTY, - trig.trigDataRec.trigTWidth, trig.trigDataRec.trigTHeight); - hlmContext.color := TGxRGBA.Create(255, 0, 255, 220); - hlmContext.line( - trig.trigCenter.x, trig.trigCenter.y, - trig.trigDataRec.trigTX+trig.trigDataRec.trigTWidth div 2, - trig.trigDataRec.trigTY+trig.trigDataRec.trigTHeight div 2); - end; - end; - TRIGGER_SOUND: begin end; - TRIGGER_SPAWNMONSTER: begin end; - TRIGGER_SPAWNITEM: begin end; - TRIGGER_MUSIC: begin end; - TRIGGER_PUSH: begin end; - TRIGGER_SCORE: begin end; - TRIGGER_MESSAGE: begin end; - TRIGGER_DAMAGE: begin end; - TRIGGER_HEALTH: begin end; - TRIGGER_SHOT: begin end; - TRIGGER_EFFECT: begin end; - TRIGGER_SCRIPT: begin end; - end; - //trigType2Str - //trigPanelId: Integer; - end; - - procedure drawTriggers (); - var - f: Integer; - begin - for f := 0 to High(gTriggers) do drawTrigger(gTriggers[f]); - end; - - procedure drawGibsBoxes (); - var - f: Integer; - px, py, pw, ph: Integer; - gib: PGib; - begin - for f := 0 to High(gGibs) do - begin - gib := @gGibs[f]; - if gib.alive then - begin - gib.getMapBox(px, py, pw, ph); - hlmContext.color := TGxRGBA.Create(255, 0, 255); - hlmContext.rect(px, py, pw, ph); - end; - end; - end; - -var - mon: TMonster; - mx, my, mw, mh: Integer; - //pan: TPanel; - //ex, ey: Integer; - pmark: PoolMark; - hitcount: Integer; - pmon: PMonster; -begin - if (gPlayer1 = nil) then exit; - - if (hlmContext = nil) then hlmContext := TGxContext.Create(); - - gxSetContext(hlmContext); - try - //glScissor(0, gWinSizeY-gPlayerScreenSize.Y-1, vpw, vph); - //hlmContext.clip := TGxRect.Create(0, gScreenHeight-gPlayerScreenSize.Y-1, gPlayerScreenSize.X, gPlayerScreenSize.Y); - - { - glScalef(g_dbg_scale, g_dbg_scale, 1.0); - glTranslatef(-vpx, -vpy, 0); - } - hlmContext.glSetScaleTrans(g_dbg_scale, -vpx, -vpy); - glEnable(GL_SCISSOR_TEST); - glScissor(0, gScreenHeight-gPlayerScreenSize.Y-1, gPlayerScreenSize.X, gPlayerScreenSize.Y); - - if (showGrid) then drawTileGrid(); - drawOutlines(); - - if (laserSet) then - begin - //g_Mons_AlongLine(laserX0, laserY0, laserX1, laserY1, monsCollector, true); - pmark := framePool.mark(); - hitcount := monsGrid.forEachAlongLine(laserX0, laserY0, laserX1, laserY1, -1, true); - pmon := PMonster(framePool.getPtr(pmark)); - while (hitcount > 0) do - begin - monsCollector(pmon^); - Inc(pmon); - Dec(hitcount); - end; - framePool.release(pmark); - end; - - if (monMarkedUID <> -1) then - begin - mon := g_Monsters_ByUID(monMarkedUID); - if (mon <> nil) then - begin - mon.getMapBox(mx, my, mw, mh); - //e_DrawQuad(mx, my, mx+mw-1, my+mh-1, 255, 0, 0, 30); - hlmContext.color := TGxRGBA.Create(255, 0, 0, 220); - hlmContext.rect(mx, my, mw, mh); - drawMonsterInfo(mon); - end; - end; - - if showAllMonsCells and showGrid then g_Mons_ForEach(highlightAllMonsterCells); - if showTriggers then drawTriggers(); - if showGrid then drawSelectedPlatformCells(); - - //drawAwakeCells(); - - if showTraceBox then drawTraceBox(); - - //drawGibsBoxes(); - - - //pan := g_Map_traceToNearest(16, 608, 16, 8, (GridTagObstacle or GridTagLiquid), @ex, @ey); - (* - {$IF DEFINED(D2F_DEBUG)} - mapGrid.dbgRayTraceTileHitCB := hilightCell1; - {$ENDIF} - pan := mapGrid.traceRay(ex, ey, 16, 608, 16, 8, nil, (GridTagObstacle or GridTagLiquid)); - if (pan <> nil) then writeln('end=(', ex, ',', ey, ')'); - {$IF DEFINED(D2F_DEBUG)} - mapGrid.dbgRayTraceTileHitCB := nil; - {$ENDIF} - - pan := g_Map_PanelAtPoint(16, 608, (GridTagObstacle or GridTagLiquid)); - if (pan <> nil) then writeln('hit!'); - *) - - finally - gxSetContext(nil); - end; - - if showMapCurPos then - begin - gxSetContext(hlmContext); - hlmContext.font := 'win8'; - hlmContext.color := TGxRGBA.Create(255, 255, 0); - hlmContext.drawText(4, gWinSizeY-10, Format('mappos:(%d,%d)', [pmsCurMapX, pmsCurMapY])); - gxSetContext(nil); - end; -end; - - -// ////////////////////////////////////////////////////////////////////////// // +{$IFDEF USE_SDL2} procedure onKeyEvent (var ev: TFUIEvent); {$IF DEFINED(D2F_DEBUG)} var @@ -1394,16 +571,17 @@ begin {$ENDIF} end; end; +{$ELSE} +procedure onKeyEvent (var ev: TFUIEvent); +begin +end; +{$ENDIF} // ////////////////////////////////////////////////////////////////////////// // procedure g_Holmes_OnEvent (var ev: TFUIEvent); -{$IF not DEFINED(HEADLESS)} -var - doeat: Boolean = false; -{$ENDIF} + var doeat: Boolean = false; begin -{$IF not DEFINED(HEADLESS)} if g_Game_IsNet then exit; if not g_holmes_enabled then exit; if g_holmes_imfunctional then exit; @@ -1416,12 +594,14 @@ begin if (ev.key) then begin +{$IFDEF USE_SDL2} case ev.scan of SDL_SCANCODE_LCTRL, SDL_SCANCODE_RCTRL, SDL_SCANCODE_LALT, SDL_SCANCODE_RALT, SDL_SCANCODE_LSHIFT, SDL_SCANCODE_RSHIFT: doeat := true; end; +{$ENDIF} end else if (ev.mouse) then begin @@ -1437,7 +617,7 @@ begin if (ev.mouse) then begin - if (gPlayer1 <> nil) and (vpSet) then msbindExecute(ev); + if (gPlayer1 <> nil) and r_Render_HolmesViewIsSet() then msbindExecute(ev); ev.eat(); end else @@ -1447,53 +627,6 @@ begin end; if (doeat) then ev.eat(); -{$ENDIF} -end; - - -// ////////////////////////////////////////////////////////////////////////// // -procedure g_Holmes_Draw (); -begin - if g_Game_IsNet then exit; - if not g_holmes_enabled then exit; - if g_holmes_imfunctional then exit; - - {$IF not DEFINED(HEADLESS)} - holmesInitCommands(); - holmesInitBinds(); - - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // modify color buffer - glDisable(GL_STENCIL_TEST); - glDisable(GL_BLEND); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_TEXTURE_2D); - - if gGameOn then plrDebugDraw(); - {$ENDIF} - - laserSet := false; -end; - - -procedure g_Holmes_DrawUI (); -begin - if g_Game_IsNet then exit; - if not g_holmes_enabled then exit; - if g_holmes_imfunctional then exit; - - {$IF not DEFINED(HEADLESS)} - gGfxDoClear := false; - //if assigned(prerenderFrameCB) then prerenderFrameCB(); - uiDraw(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - try - //glLoadIdentity(); - if assigned(postrenderFrameCB) then postrenderFrameCB(); - finally - glPopMatrix(); - end; - {$ENDIF} end; @@ -1562,9 +695,8 @@ procedure cbAtcurSelectMonster (); var plr: TPlayer; x, y, w, h: Integer; - pmark: PoolMark; - hitcount: Integer; - pmon: PMonster; + mit: PMonster; + it: TMonsterGrid.Iter; begin monMarkedUID := -1; if (Length(gPlayers) > 0) then @@ -1580,16 +712,9 @@ begin end; end; //e_WriteLog('===========================', MSG_NOTIFY); - pmark := framePool.mark(); - hitcount := monsGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY); - pmon := PMonster(framePool.getPtr(pmark)); - while (hitcount > 0) do - begin - monsAtDump(pmon^); - Inc(pmon); - Dec(hitcount); - end; - framePool.release(pmark); + it := monsGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY); + for mit in it do monsAtDump(mit^); + it.release(); //e_WriteLog('---------------------------', MSG_NOTIFY); end; @@ -1600,25 +725,17 @@ procedure cbAtcurDumpMonsters (); e_WriteLog(Format('monster #%d (UID:%u) (proxyid:%d)', [mon.arrIdx, mon.UID, mon.proxyId]), TMsgType.Notify); end; var - pmark: PoolMark; - hitcount: Integer; - pmon: PMonster; + mit: PMonster; + it: TMonsterGrid.Iter; begin - pmark := framePool.mark(); - hitcount := monsGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY); - if (hitcount > 0) then + it := monsGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY); + if (it.length > 0) then begin e_WriteLog('===========================', TMsgType.Notify); - pmon := PMonster(framePool.getPtr(pmark)); - while (hitcount > 0) do - begin - monsAtDump(pmon^); - Inc(pmon); - Dec(hitcount); - end; + for mit in it do monsAtDump(mit^); e_WriteLog('---------------------------', TMsgType.Notify); end; - framePool.release(pmark); + it.release(); end; procedure cbAtcurDumpWalls (); @@ -1633,26 +750,18 @@ var hasTrigs: Boolean = false; f: Integer; trig: PTrigger; - pmark: PoolMark; - hitcount: Integer; - ppan: PPanel; + mwit: PPanel; + it: TPanelGrid.Iter; begin platMarkedGUID := -1; - pmark := framePool.mark(); - hitcount := mapGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY, (GridTagWall or GridTagDoor)); - if (hitcount > 0) then + it := mapGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY, (GridTagWall or GridTagDoor)); + if (it.length > 0) then begin e_WriteLog('=== TOGGLE WALL ===', TMsgType.Notify); - ppan := PPanel(framePool.getPtr(pmark)); - while (hitcount > 0) do - begin - wallToggle(ppan^); - Inc(ppan); - Dec(hitcount); - end; + for mwit in it do wallToggle(mwit^); e_WriteLog('--- toggle wall ---', TMsgType.Notify); end; - framePool.release(pmark); + it.release(); if showTriggers then begin for f := 0 to High(gTriggers) do @@ -1676,22 +785,14 @@ procedure cbAtcurToggleWalls (); if pan.Enabled then g_Map_DisableWallGUID(pan.guid) else g_Map_EnableWallGUID(pan.guid); end; var - pmark: PoolMark; - hitcount: Integer; - ppan: PPanel; + mwit: PPanel; + it: TPanelGrid.Iter; begin //e_WriteLog('=== TOGGLE WALL ===', MSG_NOTIFY); //e_WriteLog('--- toggle wall ---', MSG_NOTIFY); - pmark := framePool.mark(); - hitcount := mapGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY, (GridTagWall or GridTagDoor)); - ppan := PPanel(framePool.getPtr(pmark)); - while (hitcount > 0) do - begin - wallToggle(ppan^); - Inc(ppan); - Dec(hitcount); - end; - framePool.release(pmark); + it := mapGrid.forEachAtPoint(pmsCurMapX, pmsCurMapY, (GridTagWall or GridTagDoor)); + for mwit in it do wallToggle(mwit^); + it.release(); end; @@ -1777,7 +878,7 @@ begin // load bindings from file try - st := openDiskFileRO(GameDir+'holmes.rc'); + st := e_OpenResourceRO(ConfigDirs, 'holmes.rc'); pr := TFileTextParser.Create(st); conwriteln('parsing "holmes.rc"...'); while (pr.tokType <> pr.TTEOF) do @@ -1818,10 +919,7 @@ end; begin // shut up, fpc! msB := msB; - vpSet := vpSet; fuiEventCB := g_Holmes_OnEvent; //uiContext.font := 'win14'; - - conRegVar('hlm_ui_scale', @fuiRenderScale, 0.01, 5.0, 'Holmes UI scale', '', false); end.