X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_map.pas;h=f6921131b3be776cfa1b30f8d248b8fc5593e760;hb=ceef3cf5ed716aab604357b2805a978cb9c6bab6;hp=bd949579204bebf3560f558c2d840ef49abd9a44;hpb=d7d166dc3cd287276202e862746208892c4cc89f;p=d2df-sdl.git diff --git a/src/game/g_map.pas b/src/game/g_map.pas index bd94957..f692113 100644 --- a/src/game/g_map.pas +++ b/src/game/g_map.pas @@ -22,7 +22,7 @@ interface uses SysUtils, Classes, e_graphics, g_basic, MAPDEF, g_textures, - g_phys, wadreader, g_panel, g_grid, md5, binheap, xprofiler, xparser, xdynrec; + g_phys, utils, g_panel, g_grid, md5, binheap, xprofiler, xparser, xdynrec; type TMapInfo = record @@ -59,7 +59,7 @@ type function g_Map_Load(Res: String): Boolean; function g_Map_GetMapInfo(Res: String): TMapInfo; -function g_Map_GetMapsList(WADName: String): SArray; +function g_Map_GetMapsList(WADName: String): SSArray; function g_Map_Exist(Res: String): Boolean; procedure g_Map_Free(freeTextures: Boolean=true); procedure g_Map_Update(); @@ -202,6 +202,14 @@ const GridDrawableMask = (GridTagBack or GridTagStep or GridTagWall or GridTagDoor or GridTagAcid1 or GridTagAcid2 or GridTagWater or GridTagFore); +type + TBinHeapPanelDrawCmp = class + public + class function less (const a, b: TPanel): Boolean; inline; + end; + + TBinHeapPanelDraw = specialize TBinaryHeapBase; + var gWalls: TPanelArray; gRenderBackgrounds: TPanelArray; @@ -224,10 +232,11 @@ var gdbg_map_use_accel_render: Boolean = true; gdbg_map_use_accel_coldet: Boolean = true; profMapCollision: TProfiler = nil; //WARNING: FOR DEBUGGING ONLY! - gDrawPanelList: TBinaryHeapObj = nil; // binary heap of all walls we have to render, populated by `g_Map_CollectDrawPanels()` + gDrawPanelList: TBinHeapPanelDraw = 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 + gTestMap: String = ''; function panelTypeToTag (panelType: Word): Integer; // returns GridTagXXX @@ -247,7 +256,7 @@ uses 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, - utils, sfs, xstreams, hashtable, + sfs, xstreams, hashtable, wadreader, ImagingTypes, Imaging, ImagingUtility, ImagingGif, ImagingNetworkGraphics; @@ -257,6 +266,21 @@ const FLAG_SIGNATURE = $47414C46; // 'FLAG' +// ////////////////////////////////////////////////////////////////////////// // +procedure mapWarningCB (const msg: AnsiString; line, col: Integer); +begin + if (line > 0) then + begin + e_LogWritefln('parse error at (%s,%s): %s', [line, col, msg], TMsgType.Warning); + end + else + begin + e_LogWritefln('parse error: %s', [msg], TMsgType.Warning); + end; +end; + + +// ////////////////////////////////////////////////////////////////////////// // var panByGUID: array of TPanel = nil; @@ -491,20 +515,16 @@ begin end; -function dplLess (a, b: TObject): Boolean; -var - pa, pb: TPanel; +class function TBinHeapPanelDrawCmp.less (const a, b: TPanel): Boolean; inline; begin - pa := TPanel(a); - pb := TPanel(b); - if (pa.tag < pb.tag) then begin result := true; exit; end; - if (pa.tag > pb.tag) then begin result := false; exit; end; - result := (pa.arrIdx < pb.arrIdx); + if (a.tag < b.tag) then begin result := true; exit; end; + if (a.tag > b.tag) then begin result := false; exit; end; + result := (a.arrIdx < b.arrIdx); end; procedure dplClear (); begin - if (gDrawPanelList = nil) then gDrawPanelList := TBinaryHeapObj.Create(@dplLess) else gDrawPanelList.clear(); + if (gDrawPanelList = nil) then gDrawPanelList := TBinHeapPanelDraw.Create() else gDrawPanelList.clear(); end; @@ -854,7 +874,7 @@ end; function CreateNullTexture(RecName: String): Integer; begin RecName := toLowerCase1251(RecName); - if (TextNameHash = nil) then TextNameHash := hashNewStrInt(); + if (TextNameHash = nil) then TextNameHash := THashStrInt.Create(); if TextNameHash.get(RecName, result) then exit; // i found her! SetLength(Textures, Length(Textures)+1); @@ -881,11 +901,11 @@ var a, ResLength: Integer; begin RecName := toLowerCase1251(RecName); - if (TextNameHash = nil) then TextNameHash := hashNewStrInt(); + if (TextNameHash = nil) then TextNameHash := THashStrInt.Create(); if TextNameHash.get(RecName, result) then begin // i found her! - //e_LogWritefln('texture ''%s'' already loaded', [RecName]); + //e_LogWritefln('texture ''%s'' already loaded (%s)', [RecName, result]); exit; end; @@ -953,7 +973,9 @@ begin SetLength(Textures, Length(Textures)+1); if not e_CreateTextureMem(TextureData, ResLength, Textures[High(Textures)].TextureID) then begin + e_WriteLog(Format('Error loading texture %s', [RecName]), TMsgType.Warning); SetLength(Textures, Length(Textures)-1); + result := -1; Exit; end; e_GetTextureSize(Textures[High(Textures)].TextureID, @Textures[High(Textures)].Width, @Textures[High(Textures)].Height); @@ -967,7 +989,7 @@ begin else // Íåò òàêîãî ðåóñðñà â WAD'å begin //e_WriteLog(Format('SHIT! Error loading texture %s : %s', [RecName, g_ExtractFilePathName(RecName)]), MSG_WARNING); - if (BadTextNameHash = nil) then BadTextNameHash := hashNewStrInt(); + if (BadTextNameHash = nil) then BadTextNameHash := THashStrInt.Create(); if log and (not BadTextNameHash.get(RecName, a)) then begin e_WriteLog(Format('Error loading texture %s', [RecName]), TMsgType.Warning); @@ -997,11 +1019,11 @@ var f, c, frdelay, frloop: Integer; begin RecName := toLowerCase1251(RecName); - if (TextNameHash = nil) then TextNameHash := hashNewStrInt(); + if (TextNameHash = nil) then TextNameHash := THashStrInt.Create(); if TextNameHash.get(RecName, result) then begin // i found her! - //e_LogWritefln('animated texture ''%s'' already loaded', [RecName]); + //e_LogWritefln('animated texture ''%s'' already loaded (%s)', [RecName, result]); exit; end; @@ -1009,7 +1031,7 @@ begin //e_LogWritefln('*** Loading animated texture "%s"', [RecName]); - if (BadTextNameHash = nil) then BadTextNameHash := hashNewStrInt(); + if (BadTextNameHash = nil) then BadTextNameHash := THashStrInt.Create(); if BadTextNameHash.get(RecName, f) then begin //e_WriteLog(Format('no animation texture %s (don''t worry)', [RecName]), MSG_NOTIFY); @@ -1027,7 +1049,7 @@ begin if not WAD.GetResource(g_ExtractFilePathName(RecName), TextureWAD, ResLength, log) then begin - if (BadTextNameHash = nil) then BadTextNameHash := hashNewStrInt(); + if (BadTextNameHash = nil) then BadTextNameHash := THashStrInt.Create(); if log and (not BadTextNameHash.get(RecName, f)) then begin e_WriteLog(Format('Error loading animation texture %s', [RecName]), TMsgType.Warning); @@ -1121,7 +1143,7 @@ begin end else begin - if (BadTextNameHash = nil) then BadTextNameHash := hashNewStrInt(); + if (BadTextNameHash = nil) then BadTextNameHash := THashStrInt.Create(); if log and (not BadTextNameHash.get(RecName, f)) then begin e_WriteLog(Format('Error loading animation texture %s', [RecName]), TMsgType.Warning); @@ -1213,7 +1235,7 @@ begin end else begin - if (BadTextNameHash = nil) then BadTextNameHash := hashNewStrInt(); + if (BadTextNameHash = nil) then BadTextNameHash := THashStrInt.Create(); if log and (not BadTextNameHash.get(RecName, f)) then begin e_WriteLog(Format('Error loading animation texture "%s" images', [RecName]), TMsgType.Warning); @@ -1592,7 +1614,7 @@ type actPanel: TDynRecord; end; var - WAD: TWADFile; + WAD, TestWAD: TWADFile; //mapReader: TDynRecord = nil; mapTextureList: TDynField = nil; //TTexturesRec1Array; tagInt: texture index panels: TDynField = nil; //TPanelsRec1Array; @@ -1604,7 +1626,7 @@ var PanelID: DWORD; AddTextures: TAddTextureArray; TriggersTable: array of TTRec; - FileName, mapResName, s, TexName: String; + FileName, mapResName, TexName, s: AnsiString; Data: Pointer; Len: Integer; ok, isAnim: Boolean; @@ -1617,9 +1639,12 @@ var //moveActive: Boolean; pan: TPanel; mapOk: Boolean = false; + usedTextures: THashStrInt = nil; // key: mapTextureList begin mapGrid.Free(); mapGrid := nil; + TestWAD := nil; + Data := nil; //gCurrentMap.Free(); //gCurrentMap := nil; @@ -1648,13 +1673,41 @@ begin Exit; end; - //k8: why loader ignores path here? - mapResName := g_ExtractFileName(Res); - if not WAD.GetMapResource(mapResName, Data, Len) then + if gTestMap <> '' then begin - g_FatalError(Format(_lc[I_GAME_ERROR_MAP_RES], [mapResName])); - WAD.Free(); - Exit; + s := g_ExtractWadName(gTestMap); + TestWAD := TWADFile.Create(); + if not TestWAD.ReadFile(s) then + begin + g_SimpleError(Format(_lc[I_GAME_ERROR_MAP_WAD], [s])); + TestWAD.Free(); + TestWAD := nil; + end; + end; + + if TestWAD <> nil then + begin + mapResName := g_ExtractFileName(gTestMap); + if not TestWAD.GetMapResource(mapResName, Data, Len) then + begin + g_SimpleError(Format(_lc[I_GAME_ERROR_MAP_RES], [mapResName])); + Data := nil; + end else + e_WriteLog('Using test map: '+gTestMap, TMsgType.Notify); + TestWAD.Free(); + TestWAD := nil; + end; + + if Data = nil then + begin + //k8: why loader ignores path here? + mapResName := g_ExtractFileName(Res); + if not WAD.GetMapResource(mapResName, Data, Len) then + begin + g_FatalError(Format(_lc[I_GAME_ERROR_MAP_RES], [mapResName])); + WAD.Free(); + Exit; + end; end; WAD.Free(); @@ -1730,31 +1783,53 @@ begin e_WriteLog(' Loading textures:', TMsgType.Notify); g_Game_SetLoadingText(_lc[I_LOAD_TEXTURES], mapTextureList.count-1, False); - cnt := -1; - for rec in mapTextureList do - begin - Inc(cnt); - s := rec.Resource; - {$IF DEFINED(D2F_DEBUG_TXLOAD)} - e_WriteLog(Format(' Loading texture #%d: %s', [cnt, s]), TMsgType.Notify); - {$ENDIF} - //if g_Map_IsSpecialTexture(s) then e_WriteLog(' SPECIAL!', MSG_NOTIFY); - if rec.Anim then - begin - // Àíèìèðîâàííàÿ òåêñòóðà - ntn := CreateAnimTexture(rec.Resource, FileName, True); - if (ntn < 0) then g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_ANIM], [s])); - end - else + // find used textures + usedTextures := THashStrInt.Create(); + try + if (panels <> nil) and (panels.count > 0) then begin - // Îáû÷íàÿ òåêñòóðà - ntn := CreateTexture(rec.Resource, FileName, True); - if (ntn < 0) then g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_SIMPLE], [s])); + for rec in panels do + begin + texrec := rec.TextureRec; + if (texrec <> nil) then usedTextures.put(toLowerCase1251(texrec.Resource), 42); + end; end; - if (ntn < 0) then ntn := CreateNullTexture(rec.Resource); - rec.tagInt := ntn; // remember texture number - g_Game_StepLoading(); + cnt := -1; + for rec in mapTextureList do + begin + Inc(cnt); + if not usedTextures.has(toLowerCase1251(rec.Resource)) then + begin + rec.tagInt := -1; // just in case + e_LogWritefln(' Unused texture #%d: %s', [cnt, rec.Resource]); + end + else + begin + {$IF DEFINED(D2F_DEBUG_TXLOAD)} + e_LogWritefln(' Loading texture #%d: %s', [cnt, rec.Resource]); + {$ENDIF} + //if g_Map_IsSpecialTexture(s) then e_WriteLog(' SPECIAL!', MSG_NOTIFY); + if rec.Anim then + begin + // Àíèìèðîâàííàÿ òåêñòóðà + ntn := CreateAnimTexture(rec.Resource, FileName, True); + if (ntn < 0) then g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_ANIM], [rec.Resource])); + end + else + begin + // Îáû÷íàÿ òåêñòóðà + ntn := CreateTexture(rec.Resource, FileName, True); + if (ntn < 0) then g_SimpleError(Format(_lc[I_GAME_ERROR_TEXTURE_SIMPLE], [rec.Resource])); + end; + if (ntn < 0) then ntn := CreateNullTexture(rec.Resource); + + rec.tagInt := ntn; // remember texture number + end; + g_Game_StepLoading(); + end; + finally + usedTextures.Free(); end; // set panel tagInt to texture index @@ -1768,6 +1843,7 @@ begin end; end; + // Çàãðóçêà òðèããåðîâ gTriggerClientID := 0; e_WriteLog(' Loading triggers...', TMsgType.Notify); @@ -1981,6 +2057,7 @@ begin //e_LogWritefln('PANADD: pannum=%s', [pannum]); // Ñîçäàåì ïàíåëü è çàïîìèíàåì åå GUID + //e_LogWritefln('new panel; tcount=%s; curtex=%s', [Length(AddTextures), CurTex]); PanelID := CreatePanel(rec, AddTextures, CurTex); //e_LogWritefln('panel #%s of type %s got guid #%s', [pannum, rec.PanelType, PanelID]); rec.userPanelId := PanelID; // remember game panel id, we'll fix triggers later @@ -2248,11 +2325,11 @@ begin mapReader.Free(); end; -function g_Map_GetMapsList(WADName: string): SArray; +function g_Map_GetMapsList(WADName: string): SSArray; var WAD: TWADFile; a: Integer; - ResList: SArray; + ResList: SSArray; begin Result := nil; WAD := TWADFile.Create(); @@ -2277,7 +2354,7 @@ function g_Map_Exist(Res: string): Boolean; var WAD: TWADFile; FileName, mnn: string; - ResList: SArray; + ResList: SSArray; a: Integer; begin Result := False; @@ -3253,4 +3330,6 @@ begin end; +begin + DynWarningCB := mapWarningCB; end.