diff --git a/src/game/g_map.pas b/src/game/g_map.pas
index bd949579204bebf3560f558c2d840ef49abd9a44..227835321cad0e6916b103de085d75eb0bafef5f 100644 (file)
--- a/src/game/g_map.pas
+++ b/src/game/g_map.pas
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
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();
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<TPanel, TBinHeapPanelDrawCmp>;
+
var
gWalls: TPanelArray;
gRenderBackgrounds: TPanelArray;
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
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;
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;
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;
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);
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;
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);
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);
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;
//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);
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);
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);
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);
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;
//moveActive: Boolean;
pan: TPanel;
mapOk: Boolean = false;
+ usedTextures: THashStrInt = nil; // key: mapTextureList
begin
mapGrid.Free();
mapGrid := nil;
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
end;
end;
+
// Çàãðóçêà òðèããåðîâ
gTriggerClientID := 0;
e_WriteLog(' Loading triggers...', TMsgType.Notify);
//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
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();
var
WAD: TWADFile;
FileName, mnn: string;
- ResList: SArray;
+ ResList: SSArray;
a: Integer;
begin
Result := False;
end;
+begin
+ DynWarningCB := mapWarningCB;
end.