X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_map.pas;h=3c380f9bb0a15ea2efba4516bc78d5f2b6bcefbd;hb=57b20a742f3db73dc84739d11ba35a16a27d5ab6;hp=91102f1d03044e07dbe904f98e978f590ca621a4;hpb=3e3656b8e0aae5d48e61910bcbed1652457b4fa9;p=d2df-sdl.git diff --git a/src/game/g_map.pas b/src/game/g_map.pas index 91102f1..3c380f9 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -13,15 +13,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . *) -{$MODE DELPHI} -{$modeswitch nestedprocvars} +{$INCLUDE ../shared/a_modes.inc} unit g_map; interface uses e_graphics, g_basic, MAPSTRUCT, g_textures, Classes, - g_phys, wadreader, BinEditor, g_panel, g_grid, md5; + g_phys, wadreader, BinEditor, g_panel, g_grid, g_sap, md5, xprofiler; type TMapInfo = record @@ -91,6 +90,9 @@ procedure g_Map_LoadState(Var Mem: TBinMemoryReader); procedure g_Map_DrawPanelShadowVolumes(lightX: Integer; lightY: Integer; radius: Integer); +procedure g_Map_ProfilersBegin (); +procedure g_Map_ProfilersEnd (); + const RESPAWNPOINT_PLAYER1 = 1; RESPAWNPOINT_PLAYER2 = 2; @@ -132,6 +134,12 @@ var BackID: DWORD = DWORD(-1); gExternalResources: TStringList; + gdbg_map_use_grid_render: Boolean = true; + gdbg_map_use_grid_coldet: Boolean = true; + gdbg_map_use_sap_draw: Boolean = true; + gdbg_map_use_sap_coldet: Boolean = false; + profMapCollision: TProfiler = nil; //WARNING: FOR DEBUGGING ONLY! + implementation uses @@ -139,7 +147,7 @@ uses GL, GLExt, g_weapons, g_game, g_sound, e_sound, CONFIG, g_options, MAPREADER, g_triggers, g_player, MAPDEF, Math, g_monsters, g_saveload, g_language, g_netmsg, - utils, sfs, + utils, sfs, binheap, ImagingTypes, Imaging, ImagingUtility, ImagingGif, ImagingNetworkGraphics; @@ -190,6 +198,27 @@ var FlagPoints: Array [FLAG_RED..FLAG_BLUE] of PFlagPoint; //DOMFlagPoints: Array of TFlagPoint; gMapGrid: TBodyGrid = nil; + gMapSAP: TSweepAndPrune = nil; + + +procedure g_Map_ProfilersBegin (); +begin + if (profMapCollision = nil) then profMapCollision := TProfiler.Create('MAP COLLISION', g_profile_history_size); + profMapCollision.mainBegin(g_profile_collision); + // create sections + if g_profile_collision then + begin + profMapCollision.sectionBegin('wall coldet'); + profMapCollision.sectionEnd(); + profMapCollision.sectionBegin('liquid coldet'); + profMapCollision.sectionEnd(); + end; +end; + +procedure g_Map_ProfilersEnd (); +begin + if (profMapCollision <> nil) then profMapCollision.mainEnd(); +end; function g_Map_IsSpecialTexture(Texture: String): Boolean; @@ -958,12 +987,15 @@ var for idx := High(panels) downto 0 do begin gMapGrid.insertBody(panels[idx], panels[idx].X, panels[idx].Y, panels[idx].Width, panels[idx].Height, tag); + gMapSAP.insertBody(panels[idx], panels[idx].X, panels[idx].Y, panels[idx].Width, panels[idx].Height, tag); end; end; begin gMapGrid.Free(); gMapGrid := nil; + gMapSAP.Free(); + gMapSAP := nil; fixMinMax(gWalls); fixMinMax(gRenderBackgrounds); @@ -982,6 +1014,7 @@ begin end; gMapGrid := TBodyGrid.Create(mapX0, mapY0, mapX1-mapX0+1, mapY1-mapY0+1); + gMapSAP := TSweepAndPrune.Create(); addPanelsToGrid(gWalls, PANEL_WALL); // and PANEL_CLOSEDOOR addPanelsToGrid(gRenderBackgrounds, PANEL_BACK); @@ -994,6 +1027,7 @@ begin addPanelsToGrid(gBlockMon, PANEL_BLOCKMON); gMapGrid.dumpStats(); + gMapSAP.dumpStats(); end; function g_Map_Load(Res: String): Boolean; @@ -1030,6 +1064,8 @@ var begin gMapGrid.Free(); gMapGrid := nil; + gMapSAP.Free(); + gMapSAP := nil; Result := False; gMapInfo.Map := Res; @@ -1870,10 +1906,13 @@ var if not (drawDoors xor panels[idx].Door) then begin pan := panels[idx]; + { if (pan.Width < 1) or (pan.Height < 1) then continue; if (pan.X+pan.Width <= x0) or (pan.Y+pan.Height <= y0) then continue; if (pan.X >= x0+wdt) or (pan.Y >= y0+hgt) then continue; - e_WriteLog(Format(' *body hit: (%d,%d)-(%dx%d) tag: %d; qtag:%d', [pan.X, pan.Y, pan.Width, pan.Height, PanelType, PanelType]), MSG_NOTIFY); + } + pan.Draw(); + //e_WriteLog(Format(' *body hit: (%d,%d)-(%dx%d) tag: %d; qtag:%d', [pan.X, pan.Y, pan.Width, pan.Height, PanelType, PanelType]), MSG_NOTIFY); end; end; end; @@ -1885,30 +1924,40 @@ begin //e_WriteLog(Format('***QQQ: qtag:%d', [PanelType]), MSG_NOTIFY); dplClear(); ptag := panelTypeToTag(PanelType); - gMapGrid.forEachInAABB(x0, y0, wdt, hgt, checker); - // debug - { - e_WriteLog(Format('+++QQQ: qtag:%d', [PanelType]), MSG_NOTIFY); - case PanelType of - PANEL_WALL: DrawPanels(0, gWalls); - PANEL_CLOSEDOOR: DrawPanels(0, gWalls, True); - PANEL_BACK: DrawPanels(1, gRenderBackgrounds); - PANEL_FORE: DrawPanels(2, gRenderForegrounds); - PANEL_WATER: DrawPanels(3, gWater); - PANEL_ACID1: DrawPanels(4, gAcid1); - PANEL_ACID2: DrawPanels(5, gAcid2); - PANEL_STEP: DrawPanels(6, gSteps); - end; - e_WriteLog('==================', MSG_NOTIFY); - } - - // sort and draw the list (we need to sort it, or rendering is fucked) - while gDrawPanelList.count > 0 do + if gdbg_map_use_grid_render then begin - (gDrawPanelList.front() as TPanel).Draw(); - gDrawPanelList.popFront(); + if gdbg_map_use_sap_draw then + begin + gMapSAP.forEachInAABB(x0, y0, wdt, hgt, checker); + end + else + begin + gMapGrid.forEachInAABB(x0, y0, wdt, hgt, checker); + end; + // sort and draw the list (we need to sort it, or rendering is fucked) + while gDrawPanelList.count > 0 do + begin + (gDrawPanelList.front() as TPanel).Draw(); + gDrawPanelList.popFront(); + end; + end + else + begin + //e_WriteLog(Format('+++QQQ: qtag:%d', [PanelType]), MSG_NOTIFY); + case PanelType of + PANEL_WALL: DrawPanels(0, gWalls); + PANEL_CLOSEDOOR: DrawPanels(0, gWalls, True); + PANEL_BACK: DrawPanels(1, gRenderBackgrounds); + PANEL_FORE: DrawPanels(2, gRenderForegrounds); + PANEL_WATER: DrawPanels(3, gWater); + PANEL_ACID1: DrawPanels(4, gAcid1); + PANEL_ACID2: DrawPanels(5, gAcid2); + PANEL_STEP: DrawPanels(6, gSteps); + end; end; + + //e_WriteLog('==================', MSG_NOTIFY); end; @@ -1924,7 +1973,14 @@ procedure g_Map_DrawPanelShadowVolumes(lightX: Integer; lightY: Integer; radius: end; begin - gMapGrid.forEachInAABB(lightX-radius, lightY-radius, radius*2, radius*2, checker); + if gdbg_map_use_sap_draw then + begin + gMapSAP.forEachInAABB(lightX-radius, lightY-radius, radius*2, radius*2, checker); + end + else + begin + gMapGrid.forEachInAABB(lightX-radius, lightY-radius, radius*2, radius*2, checker); + end; end; @@ -1936,7 +1992,6 @@ begin e_Clear(GL_COLOR_BUFFER_BIT, 0, 0, 0); end; -(* function g_Map_CollidePanelOld(X, Y: Integer; Width, Height: Word; PanelType: Word; b1x3: Boolean): Boolean; var @@ -2056,7 +2111,37 @@ begin end; end; end; -*) + +function g_Map_CollideLiquid_TextureOld(X, Y: Integer; Width, Height: Word): DWORD; +var + texid: DWORD; + + function checkPanels (var panels: TPanelArray): Boolean; + var + a: Integer; + begin + result := false; + if panels = nil then exit; + for a := 0 to High(panels) do + begin + if g_Collide(X, Y, Width, Height, panels[a].X, panels[a].Y, panels[a].Width, panels[a].Height) then + begin + result := true; + texid := panels[a].GetTextureID(); + exit; + end; + end; + end; + +begin + texid := TEXTURE_NONE; + result := texid; + if not checkPanels(gWater) then + if not checkPanels(gAcid1) then + if not checkPanels(gAcid2) then exit; + result := texid; +end; + function g_Map_CollidePanel(X, Y: Integer; Width, Height: Word; PanelType: Word; b1x3: Boolean): Boolean; @@ -2140,7 +2225,7 @@ function g_Map_CollidePanel(X, Y: Integer; Width, Height: Word; PanelType: Word; end; end; - if WordBool(PanelType and PANEL_BLOCKMON)and (tag = GridTagBlockMon) then + if WordBool(PanelType and PANEL_BLOCKMON) and (tag = GridTagBlockMon) then begin if ((not b1x3) or ((gBlockMon[a].Width + gBlockMon[a].Height) >= 64)) and g_Collide(X, Y, Width, Height, gBlockMon[a].X, gBlockMon[a].Y, gBlockMon[a].Width, gBlockMon[a].Height) then @@ -2152,7 +2237,27 @@ function g_Map_CollidePanel(X, Y: Integer; Width, Height: Word; PanelType: Word; end; begin - result := gMapGrid.forEachInAABB(X, Y, Width, Height, checker); + //TODO: detailed profile + if (profMapCollision <> nil) then profMapCollision.sectionBeginAccum('wall coldet'); + try + if gdbg_map_use_grid_coldet then + begin + if gdbg_map_use_sap_coldet then + begin + gMapSAP.forEachInAABB(X, Y, Width, Height, checker); + end + else + begin + result := gMapGrid.forEachInAABB(X, Y, Width, Height, checker); + end; + end + else + begin + result := g_Map_CollidePanelOld(X, Y, Width, Height, PanelType, b1x3); + end; + finally + if (profMapCollision <> nil) then profMapCollision.sectionEnd(); + end; end; @@ -2203,9 +2308,29 @@ var end; begin - texid := TEXTURE_NONE; - gMapGrid.forEachInAABB(X, Y, Width, Height, checker); - result := texid; + //TODO: detailed profile? + if (profMapCollision <> nil) then profMapCollision.sectionBeginAccum('liquid coldet'); + try + if gdbg_map_use_grid_coldet then + begin + texid := TEXTURE_NONE; + if gdbg_map_use_sap_coldet then + begin + gMapSAP.forEachInAABB(X, Y, Width, Height, checker); + end + else + begin + gMapGrid.forEachInAABB(X, Y, Width, Height, checker); + end; + result := texid; + end + else + begin + result := g_Map_CollideLiquid_TextureOld(X, Y, Width, Height); + end; + finally + if (profMapCollision <> nil) then profMapCollision.sectionEnd(); + end; end; procedure g_Map_EnableWall(ID: DWORD);