X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_map.pas;h=0df83bb087e16cf1c7b3fd090426c584c30669ea;hb=a4f25c41dfd783a925aa2dab4b9b84753d5c3f18;hp=6b64d8818ead94d6f3c925bd0dabfd68589e242f;hpb=b0369ee9442a79c9ace3454e7e1709cd61ed6a8e;p=d2df-sdl.git diff --git a/src/game/g_map.pas b/src/game/g_map.pas index 6b64d88..0df83bb 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -60,7 +60,7 @@ function g_Map_Load(Res: String): Boolean; function g_Map_GetMapInfo(Res: String): TMapInfo; function g_Map_GetMapsList(WADName: String): SArray; function g_Map_Exist(Res: String): Boolean; -procedure g_Map_Free(); +procedure g_Map_Free(freeTextures: Boolean=true); procedure g_Map_Update(); procedure g_Map_DrawPanels (PanelType: Word); // unaccelerated @@ -85,8 +85,6 @@ function g_Map_HaveFlagPoints(): Boolean; procedure g_Map_ResetFlag(Flag: Byte); procedure g_Map_DrawFlags(); -function g_Map_PanelForPID(PanelID: Integer; var PanelArrayID: Integer): PPanel; - procedure g_Map_SaveState(Var Mem: TBinMemoryWriter); procedure g_Map_LoadState(Var Mem: TBinMemoryReader); @@ -202,6 +200,7 @@ var gDrawPanelList: TBinaryHeapObj = nil; // binary heap of all walls we have to render, populated by `g_Map_CollectDrawPanels()` gCurrentMap: TDynRecord = nil; + gCurrentMapFileName: AnsiString = ''; // so we can skip texture reloading function panelTypeToTag (panelType: Word): Integer; // returns GridTagXXX @@ -217,7 +216,7 @@ var implementation uses - g_main, e_log, SysUtils, g_items, g_gfx, g_console, + e_input, g_main, e_log, SysUtils, g_items, g_gfx, g_console, GL, GLExt, g_weapons, g_game, g_sound, e_sound, CONFIG, g_options, g_triggers, g_player, Math, g_monsters, g_saveload, g_language, g_netmsg, @@ -438,7 +437,9 @@ type var PanelById: array of TPanelID; - Textures: TLevelTextureArray; + Textures: TLevelTextureArray = nil; + TextNameHash: THashStrInt = nil; // key: texture name; value: index in `Textures` + BadTextNameHash: THashStrInt = nil; // set; so we won't spam with non-existing texture messages RespawnPoints: Array of TRespawnPoint; FlagPoints: Array [FLAG_RED..FLAG_BLUE] of PFlagPoint; //DOMFlagPoints: Array of TFlagPoint; @@ -784,8 +785,13 @@ begin PanelByID[len].PArrID := Result; end; + function CreateNullTexture(RecName: String): Integer; begin + RecName := toLowerCase1251(RecName); + if (TextNameHash = nil) then TextNameHash := hashNewStrInt(); + if TextNameHash.get(RecName, result) then exit; // i found her! + SetLength(Textures, Length(Textures)+1); result := High(Textures); @@ -797,26 +803,47 @@ begin Anim := False; TextureID := LongWord(TEXTURE_NONE); end; + + TextNameHash.put(RecName, result); end; -function CreateTexture(RecName: String; Map: string; log: Boolean): Integer; + +function CreateTexture(RecName: AnsiString; Map: string; log: Boolean): Integer; var WAD: TWADFile; TextureData: Pointer; - WADName, txname: String; + WADName: String; a, ResLength: Integer; begin + RecName := toLowerCase1251(RecName); + if (TextNameHash = nil) then TextNameHash := hashNewStrInt(); + if TextNameHash.get(RecName, result) then + begin + // i found her! + //e_LogWritefln('texture ''%s'' already loaded', [RecName]); + exit; + end; + Result := -1; + if (BadTextNameHash <> nil) and BadTextNameHash.has(RecName) then exit; // don't do it again and again + + { if Textures <> nil then + begin for a := 0 to High(Textures) do - if Textures[a].TextureName = RecName then + begin + if (Textures[a].TextureName = RecName) then begin // Òåêñòóðà ñ òàêèì èìåíåì óæå åñòü + e_LogWritefln('texture ''%s'' already loaded', [RecName]); Result := a; Exit; end; + end; + end; + } -// Òåêñòóðû ñî ñïåöèàëüíûìè èìåíàìè (âîäà, ëàâà, êèñëîòà): + // Òåêñòóðû ñî ñïåöèàëüíûìè èìåíàìè (âîäà, ëàâà, êèñëîòà): if (RecName = TEXTURE_NAME_WATER) or (RecName = TEXTURE_NAME_ACID1) or (RecName = TEXTURE_NAME_ACID2) then @@ -826,36 +853,28 @@ begin with Textures[High(Textures)] do begin TextureName := RecName; - - if TextureName = TEXTURE_NAME_WATER then - TextureID := LongWord(TEXTURE_SPECIAL_WATER) - else - if TextureName = TEXTURE_NAME_ACID1 then - TextureID := LongWord(TEXTURE_SPECIAL_ACID1) - else - if TextureName = TEXTURE_NAME_ACID2 then - TextureID := LongWord(TEXTURE_SPECIAL_ACID2); + if (TextureName = TEXTURE_NAME_WATER) then TextureID := LongWord(TEXTURE_SPECIAL_WATER) + else if (TextureName = TEXTURE_NAME_ACID1) then TextureID := LongWord(TEXTURE_SPECIAL_ACID1) + else if (TextureName = TEXTURE_NAME_ACID2) then TextureID := LongWord(TEXTURE_SPECIAL_ACID2); Anim := False; end; result := High(Textures); + TextNameHash.put(RecName, result); Exit; end; -// Çàãðóæàåì ðåñóðñ òåêñòóðû â ïàìÿòü èç WAD'à: + // Çàãðóæàåì ðåñóðñ òåêñòóðû â ïàìÿòü èç WAD'à: WADName := g_ExtractWadName(RecName); WAD := TWADFile.Create(); - if WADName <> '' then - WADName := GameDir+'/wads/'+WADName - else - WADName := Map; + if WADName <> '' then WADName := GameDir+'/wads/'+WADName else WADName := Map; WAD.ReadFile(WADName); - txname := RecName; + //txname := RecName; { if (WADName = Map) and WAD.GetResource(g_ExtractFilePathName(RecName), TextureData, ResLength) then begin @@ -864,33 +883,38 @@ begin end; } - if WAD.GetResource(g_ExtractFilePathName(RecName), TextureData, ResLength) then + if WAD.GetResource(g_ExtractFilePathName(RecName), TextureData, ResLength, log) then + begin + SetLength(Textures, Length(Textures)+1); + if not e_CreateTextureMem(TextureData, ResLength, Textures[High(Textures)].TextureID) then begin - SetLength(Textures, Length(Textures)+1); - if not e_CreateTextureMem(TextureData, ResLength, Textures[High(Textures)].TextureID) then - Exit; - e_GetTextureSize(Textures[High(Textures)].TextureID, - @Textures[High(Textures)].Width, - @Textures[High(Textures)].Height); - FreeMem(TextureData); - Textures[High(Textures)].TextureName := {RecName}txname; - Textures[High(Textures)].Anim := False; - - result := High(Textures); - end + SetLength(Textures, Length(Textures)-1); + Exit; + end; + e_GetTextureSize(Textures[High(Textures)].TextureID, @Textures[High(Textures)].Width, @Textures[High(Textures)].Height); + FreeMem(TextureData); + Textures[High(Textures)].TextureName := RecName; + Textures[High(Textures)].Anim := False; + + result := High(Textures); + TextNameHash.put(RecName, result); + end else // Íåò òàêîãî ðåóñðñà â WAD'å begin - //e_WriteLog(Format('SHIT! Error loading texture %s : %s : %s', [RecName, txname, g_ExtractFilePathName(RecName)]), MSG_WARNING); - if log then - begin - e_WriteLog(Format('Error loading texture %s', [RecName]), MSG_WARNING); - //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING); - end; + //e_WriteLog(Format('SHIT! Error loading texture %s : %s', [RecName, g_ExtractFilePathName(RecName)]), MSG_WARNING); + if (BadTextNameHash = nil) then BadTextNameHash := hashNewStrInt(); + if log and (not BadTextNameHash.get(RecName, a)) then + begin + e_WriteLog(Format('Error loading texture %s', [RecName]), MSG_WARNING); + //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING); + end; + BadTextNameHash.put(RecName, -1); end; WAD.Free(); end; + function CreateAnimTexture(RecName: String; Map: string; log: Boolean): Integer; var WAD: TWADFile; @@ -907,29 +931,44 @@ var ia: TDynImageDataArray = nil; f, c, frdelay, frloop: Integer; begin + RecName := toLowerCase1251(RecName); + if (TextNameHash = nil) then TextNameHash := hashNewStrInt(); + if TextNameHash.get(RecName, result) then + begin + // i found her! + //e_LogWritefln('animated texture ''%s'' already loaded', [RecName]); + exit; + end; + result := -1; - //e_WriteLog(Format('*** Loading animated texture "%s"', [RecName]), MSG_NOTIFY); + //e_LogWritefln('*** Loading animated texture "%s"', [RecName]); + + if (BadTextNameHash = nil) then BadTextNameHash := hashNewStrInt(); + if BadTextNameHash.get(RecName, f) then + begin + //e_WriteLog(Format('no animation texture %s (don''t worry)', [RecName]), MSG_NOTIFY); + exit; + end; // ×èòàåì WAD-ðåñóðñ àíèì.òåêñòóðû èç WAD'à â ïàìÿòü: WADName := g_ExtractWadName(RecName); WAD := TWADFile.Create(); try - if WADName <> '' then - WADName := GameDir+'/wads/'+WADName - else - WADName := Map; + if WADName <> '' then WADName := GameDir+'/wads/'+WADName else WADName := Map; WAD.ReadFile(WADName); - if not WAD.GetResource(g_ExtractFilePathName(RecName), TextureWAD, ResLength) then + if not WAD.GetResource(g_ExtractFilePathName(RecName), TextureWAD, ResLength, log) then begin - if log then + if (BadTextNameHash = nil) then BadTextNameHash := hashNewStrInt(); + if log and (not BadTextNameHash.get(RecName, f)) then begin e_WriteLog(Format('Error loading animation texture %s', [RecName]), MSG_WARNING); //e_WriteLog(Format('WAD Reader error: %s', [WAD.GetLastErrorStr]), MSG_WARNING); end; + BadTextNameHash.put(RecName, -1); exit; end; @@ -946,6 +985,7 @@ begin if ResLength < 6 then begin e_WriteLog(Format('Animated texture file "%s" too short', [RecName]), MSG_WARNING); + BadTextNameHash.put(RecName, -1); exit; end; @@ -957,6 +997,7 @@ begin if not WAD.ReadMemory(TextureWAD, ResLength) then begin e_WriteLog(Format('Animated texture WAD file "%s" is invalid', [RecName]), MSG_WARNING); + BadTextNameHash.put(RecName, -1); exit; end; @@ -964,6 +1005,7 @@ begin if not WAD.GetResource('TEXT/ANIM', TextData, ResLength) then begin e_WriteLog(Format('Animated texture file "%s" has invalid INI', [RecName]), MSG_WARNING); + BadTextNameHash.put(RecName, -1); exit; end; @@ -973,6 +1015,7 @@ begin if TextureResource = '' then begin e_WriteLog(Format('Animated texture WAD file "%s" has no "resource"', [RecName]), MSG_WARNING); + BadTextNameHash.put(RecName, -1); exit; end; @@ -989,6 +1032,7 @@ begin if not WAD.GetResource('TEXTURES/'+TextureResource, TextureData, ResLength) then begin e_WriteLog(Format('Animated texture WAD file "%s" has no texture "%s"', [RecName, 'TEXTURES/'+TextureResource]), MSG_WARNING); + BadTextNameHash.put(RecName, -1); exit; end; @@ -1008,10 +1052,16 @@ begin FramesCount := _framecount; Speed := _speed; result := High(Textures); + TextNameHash.put(RecName, result); end else begin - if log then e_WriteLog(Format('Error loading animation texture %s', [RecName]), MSG_WARNING); + if (BadTextNameHash = nil) then BadTextNameHash := hashNewStrInt(); + if log and (not BadTextNameHash.get(RecName, f)) then + begin + e_WriteLog(Format('Error loading animation texture %s', [RecName]), MSG_WARNING); + end; + BadTextNameHash.put(RecName, -1); end; end; end @@ -1031,11 +1081,13 @@ begin if not LoadMultiImageFromMemory(TextureWAD, ResLength, ia) then begin e_WriteLog(Format('Animated texture file "%s" cannot be loaded', [RecName]), MSG_WARNING); + BadTextNameHash.put(RecName, -1); exit; end; if length(ia) = 0 then begin e_WriteLog(Format('Animated texture file "%s" has no frames', [RecName]), MSG_WARNING); + BadTextNameHash.put(RecName, -1); exit; end; @@ -1091,20 +1143,26 @@ begin Textures[High(Textures)].FramesCount := length(ia); Textures[High(Textures)].Speed := _speed; result := High(Textures); + TextNameHash.put(RecName, result); //writeln(' CREATED!'); end else begin - if log then e_WriteLog(Format('Error loading animation texture "%s" images', [RecName]), MSG_WARNING); + if (BadTextNameHash = nil) then BadTextNameHash := hashNewStrInt(); + if log and (not BadTextNameHash.get(RecName, f)) then + begin + e_WriteLog(Format('Error loading animation texture "%s" images', [RecName]), MSG_WARNING); + end; + BadTextNameHash.put(RecName, -1); end; end; finally for f := 0 to High(ia) do FreeImage(ia[f]); WAD.Free(); cfg.Free(); - if TextureWAD <> nil then FreeMem(TextureWAD); - if TextData <> nil then FreeMem(TextData); - if TextureData <> nil then FreeMem(TextureData); + if (TextureWAD <> nil) then FreeMem(TextureWAD); + if (TextData <> nil) then FreeMem(TextData); + if (TextureData <> nil) then FreeMem(TextureData); end; end; @@ -1190,7 +1248,7 @@ begin end; end; -procedure CreateTrigger(Trigger: TDynRecord; atpanid, atrigpanid: Integer; fTexturePanel1Type, fTexturePanel2Type: Word); +procedure CreateTrigger (amapIdx: Integer; Trigger: TDynRecord; atpanid, atrigpanid: Integer; fTexturePanel1Type, fTexturePanel2Type: Word); var _trigger: TTrigger; begin @@ -1199,6 +1257,7 @@ begin with _trigger do begin mapId := Trigger.id; + mapIndex := amapIdx; X := Trigger.X; Y := Trigger.Y; Width := Trigger.Width; @@ -1264,6 +1323,7 @@ procedure g_Map_ReAdd_DieTriggers(); function monsDieTrig (mon: TMonster): Boolean; var a: Integer; + //tw: TStrTextWriter; begin result := false; // don't stop mon.ClearTriggers(); @@ -1272,6 +1332,15 @@ procedure g_Map_ReAdd_DieTriggers(); if gTriggers[a].TriggerType in [TRIGGER_PRESS, TRIGGER_ON, TRIGGER_OFF, TRIGGER_ONOFF] then begin //if (gTriggers[a].Data.MonsterID-1) = Integer(mon.StartID) then mon.AddTrigger(a); + { + tw := TStrTextWriter.Create(); + try + gTriggers[a].trigData.writeTo(tw); + e_LogWritefln('=== trigger #%s ==='#10'%s'#10'---', [a, tw.str]); + finally + tw.Free(); + end; + } if (gTriggers[a].trigData.trigMonsterId) = Integer(mon.StartID) then mon.AddTrigger(a); end; end; @@ -1494,6 +1563,7 @@ var rec, texrec: TDynRecord; pttit: PTRec; pannum, trignum, cnt, tgpid: Integer; + stt: UInt64; begin mapGrid.Free(); mapGrid := nil; @@ -1543,6 +1613,8 @@ begin e_LogWritefln('Loading map: %s', [mapResName], MSG_NOTIFY); g_Game_SetLoadingText(_lc[I_LOAD_MAP], 0, False); + stt := curTimeMicro(); + try mapReader := g_Map_ParseMap(Data, Len); except @@ -1684,6 +1756,11 @@ begin pttit.shotPan := mapReader.panel[rec.trigRec.tgShotPanelID]; end; + if (pttit.texPan <> nil) then pttit.texPan.userPanelTrigRef := true; + if (pttit.liftPan <> nil) then pttit.liftPan.userPanelTrigRef := true; + if (pttit.doorPan <> nil) then pttit.doorPan.userPanelTrigRef := true; + if (pttit.shotPan <> nil) then pttit.shotPan.userPanelTrigRef := true; + g_Game_StepLoading(); end; end; @@ -1698,6 +1775,7 @@ begin for rec in panels do begin Inc(pannum); + //e_LogWritefln('PANSTART: pannum=%s', [pannum]); texrec := nil; SetLength(AddTextures, 0); trigRef := False; @@ -1717,6 +1795,7 @@ begin ok := false; if (TriggersTable <> nil) and (mapTextureList <> nil) then begin + { for b := 0 to High(TriggersTable) do begin if (TriggersTable[b].texPan = rec) or (TriggersTable[b].shotPan = rec) then @@ -1726,6 +1805,13 @@ begin break; end; end; + } + if rec.userPanelTrigRef then + begin + // e_LogWritefln('trigref for panel %s', [pannum]); + trigRef := True; + ok := True; + end; end; end; @@ -1762,30 +1848,39 @@ begin begin // Íà÷àëüíàÿ - àíèìèðîâàííàÿ, èùåì àíèìèðîâàííóþ isAnim := True; + //e_LogWritefln('000: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]); ok := CreateAnimTexture(TexName, FileName, False) >= 0; + //e_LogWritefln('001: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]); if not ok then begin // Íåò àíèìèðîâàííîé, èùåì îáû÷íóþ isAnim := False; + //e_LogWritefln('002: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]); ok := CreateTexture(TexName, FileName, False) >= 0; + //e_LogWritefln('003: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]); end; end else begin // Íà÷àëüíàÿ - îáû÷íàÿ, èùåì îáû÷íóþ isAnim := False; + //e_LogWritefln('004: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]); ok := CreateTexture(TexName, FileName, False) >= 0; + //e_LogWritefln('005: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]); if not ok then begin // Íåò îáû÷íîé, èùåì àíèìèðîâàííóþ isAnim := True; + //e_LogWritefln('006: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]); ok := CreateAnimTexture(TexName, FileName, False) >= 0; + //e_LogWritefln('007: pannum=%s; TexName=[%s]; FileName=[%s]', [pannum, TexName, FileName]); end; end; // Îíà ñóùåñòâóåò. Çàíîñèì åå ID â ñïèñîê ïàíåëè if ok then begin + { for c := 0 to High(Textures) do begin if (Textures[c].TextureName = TexName) then @@ -1796,6 +1891,13 @@ begin break; end; end; + } + if (TextNameHash <> nil) and TextNameHash.get(toLowerCase1251(TexName), c) then + begin + SetLength(AddTextures, Length(AddTextures)+1); + AddTextures[High(AddTextures)].Texture := c; + AddTextures[High(AddTextures)].Anim := isAnim; + end; end; end else @@ -1832,11 +1934,15 @@ begin //e_WriteLog(Format('panel #%d: TextureNum=%d; ht=%d; ht1=%d; atl=%d', [a, panels[a].TextureNum, High(mapTextureList), High(Textures), High(AddTextures)]), MSG_NOTIFY); + //e_LogWritefln('PANADD: pannum=%s', [pannum]); + // Ñîçäàåì ïàíåëü è çàïîìèíàåì åå íîìåð PanelID := CreatePanel(rec, AddTextures, CurTex, trigRef); //e_LogWritefln('panel #%s of type %s got id #%s', [pannum, rec.PanelType, PanelID]); // set 'gamePanelId' field to panel id - rec.gamePanelId := PanelID; // remember game panel id, we'll fix triggers later + rec.userPanelId := PanelID; // remember game panel id, we'll fix triggers later + + //e_LogWritefln('PANEND: pannum=%s', [pannum]); g_Game_StepLoading(); end; @@ -1845,10 +1951,10 @@ begin // ×èíèì ID'û ïàíåëåé, êîòîðûå èñïîëüçóþòñÿ â òðèããåðàõ for b := 0 to High(TriggersTable) do begin - if (TriggersTable[b].texPan <> nil) then TriggersTable[b].texPanIdx := TriggersTable[b].texPan.gamePanelId; - if (TriggersTable[b].liftPan <> nil) then TriggersTable[b].LiftPanelIdx := TriggersTable[b].liftPan.gamePanelId; - if (TriggersTable[b].doorPan <> nil) then TriggersTable[b].DoorPanelIdx := TriggersTable[b].doorPan.gamePanelId; - if (TriggersTable[b].shotPan <> nil) then TriggersTable[b].ShotPanelIdx := TriggersTable[b].shotPan.gamePanelId; + if (TriggersTable[b].texPan <> nil) then TriggersTable[b].texPanIdx := TriggersTable[b].texPan.userPanelId; + if (TriggersTable[b].liftPan <> nil) then TriggersTable[b].LiftPanelIdx := TriggersTable[b].liftPan.userPanelId; + if (TriggersTable[b].doorPan <> nil) then TriggersTable[b].DoorPanelIdx := TriggersTable[b].doorPan.userPanelId; + if (TriggersTable[b].shotPan <> nil) then TriggersTable[b].ShotPanelIdx := TriggersTable[b].shotPan.userPanelId; end; // create map grid, init other grids (for monsters, for example) @@ -1873,7 +1979,7 @@ begin else if (TriggersTable[trignum].ShotPanelIdx <> -1) then tgpid := TriggersTable[trignum].ShotPanelIdx else tgpid := -1; //e_LogWritefln('creating trigger #%s; texpantype=%s; shotpantype=%s (%d,%d)', [trignum, b, c, TriggersTable[trignum].texPanIdx, TriggersTable[trignum].ShotPanelIdx]); - CreateTrigger(rec, TriggersTable[trignum].texPanIdx, tgpid, Word(b), Word(c)); + CreateTrigger(trignum, rec, TriggersTable[trignum].texPanIdx, tgpid, Word(b), Word(c)); end; end; @@ -1916,6 +2022,7 @@ begin end; gCurrentMap := mapReader; // this will be our current map now + gCurrentMapFileName := Res; mapReader := nil; // Çàãðóçêà íåáà @@ -1993,9 +2100,13 @@ begin begin gMusic.SetByName(''); end; + + stt := curTimeMicro()-stt; + e_LogWritefln('map loaded in %s.%s milliseconds', [Integer(stt div 1000), Integer(stt mod 1000)]); finally sfsGCEnable(); // enable releasing unused volumes mapReader.Free(); + e_ClearInputBuffer(); // why not? end; e_WriteLog('Done loading map.', MSG_NOTIFY); @@ -2031,22 +2142,6 @@ begin WAD.Free(); - { - MapReader := TMapReader_1.Create(); - if not MapReader.LoadMap(Data) then - begin - g_Console_Add(Format(_lc[I_GAME_ERROR_MAP_LOAD], [Res]), True); - ZeroMemory(@Header, SizeOf(Header)); - Result.Name := _lc[I_GAME_ERROR_MAP_SELECT]; - Result.Description := _lc[I_GAME_ERROR_MAP_SELECT]; - end - else - begin - Header := MapReader.GetMapHeader(); - Result.Name := Header.MapName; - Result.Description := Header.MapDescription; - end; - } try mapReader := g_Map_ParseMap(Data, Len); except @@ -2054,10 +2149,6 @@ begin end; FreeMem(Data); - //MapReader.Free(); - - //if (mapReader <> nil) then Header := GetMapHeader(mapReader) else FillChar(Header, sizeof(Header), 0); - //MapReader.Free(); if (mapReader.Width > 0) and (mapReader.Height > 0) then begin @@ -2138,7 +2229,7 @@ begin end; end; -procedure g_Map_Free(); +procedure g_Map_Free(freeTextures: Boolean=true); var a: Integer; @@ -2177,17 +2268,42 @@ begin //gDOMFlags := nil; - if Textures <> nil then + if (Length(gCurrentMapFileName) <> 0) then begin - for a := 0 to High(Textures) do - if not g_Map_IsSpecialTexture(Textures[a].TextureName) then - if Textures[a].Anim then - g_Frames_DeleteByID(Textures[a].FramesID) - else - if Textures[a].TextureID <> LongWord(TEXTURE_NONE) then - e_DeleteTexture(Textures[a].TextureID); - - Textures := nil; + e_LogWritefln('g_Map_Free: previous map was ''%s''...', [gCurrentMapFileName]); + end + else + begin + e_LogWritefln('g_Map_Free: no previous map.', []); + end; + if freeTextures then + begin + e_LogWritefln('g_Map_Free: clearing textures...', []); + if (Textures <> nil) then + begin + for a := 0 to High(Textures) do + begin + if not g_Map_IsSpecialTexture(Textures[a].TextureName) then + begin + if Textures[a].Anim then + begin + g_Frames_DeleteByID(Textures[a].FramesID) + end + else + begin + if (Textures[a].TextureID <> LongWord(TEXTURE_NONE)) then + begin + e_DeleteTexture(Textures[a].TextureID); + end; + end; + end; + end; + Textures := nil; + end; + TextNameHash.Free(); + TextNameHash := nil; + BadTextNameHash.Free(); + BadTextNameHash := nil; end; FreePanelArray(gWalls); @@ -3113,17 +3229,6 @@ begin ///// ///// end; -function g_Map_PanelForPID(PanelID: Integer; var PanelArrayID: Integer): PPanel; -var - Arr: TPanelArray; -begin - Result := nil; - if (PanelID < 0) or (PanelID > High(PanelByID)) then Exit; - Arr := PanelByID[PanelID].PWhere^; - PanelArrayID := PanelByID[PanelID].PArrID; - Result := Addr(Arr[PanelByID[PanelID].PArrID]); -end; - // trace liquid, stepping by `dx` and `dy` // return last seen liquid coords, and `false` if we're started outside of the liquid