summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 2e947b5)
raw | patch | inline | side by side (parent: 2e947b5)
author | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Fri, 22 Apr 2016 15:03:11 +0000 (18:03 +0300) | ||
committer | Ketmar Dark <ketmar@ketmar.no-ip.org> | |
Fri, 22 Apr 2016 15:06:39 +0000 (18:06 +0300) |
diff --git a/src/game/g_gui.pas b/src/game/g_gui.pas
index 9319e45a7b9e29550da578fa07bf4af5ac32dc25..cd9d3b93244a371f0c89cc751575f78bb0106474 100644 (file)
--- a/src/game/g_gui.pas
+++ b/src/game/g_gui.pas
end;
//k8: ignores path again
- if not WAD.GetResource(g_ExtractFileName(Res), Data, Len) then
+ if not WAD.GetMapResource(g_ExtractFileName(Res), Data, Len) then
begin
WAD.Free();
Exit;
diff --git a/src/game/g_map.pas b/src/game/g_map.pas
index 6c156caf5c973912a371ba6e4c0fc9397dce1467..2c611442025585a94d1c42d998ff5c900c6d2f6d 100644 (file)
--- a/src/game/g_map.pas
+++ b/src/game/g_map.pas
end;
//k8: why loader ignores path here?
mapResName := g_ExtractFileName(Res);
- if not WAD.GetResource(mapResName, Data, Len) then
+ if not WAD.GetMapResource(mapResName, Data, Len) then
begin
g_FatalError(Format(_lc[I_GAME_ERROR_MAP_RES], [mapResName]));
WAD.Free();
end;
//k8: it ignores path again
- if not WAD.GetResource(g_ExtractFileName(Res), Data, Len) then
+ if not WAD.GetMapResource(g_ExtractFileName(Res), Data, Len) then
begin
WAD.Free();
Exit;
WAD: TWADFile;
a: Integer;
ResList: SArray;
- Data: Pointer;
- Len: Integer;
- Sign: Array [0..2] of Char;
begin
Result := nil;
-
WAD := TWADFile.Create();
if not WAD.ReadFile(WADName) then
begin
WAD.Free();
Exit;
end;
-
- ResList := WAD.GetRootResources();
-
+ ResList := WAD.GetMapResources();
if ResList <> nil then
+ begin
for a := 0 to High(ResList) do
begin
- if not WAD.GetResource(ResList[a], Data, Len) then Continue;
- CopyMemory(@Sign[0], Data, 3);
- FreeMem(Data);
-
- if Sign = MAP_SIGNATURE then
- begin
- SetLength(Result, Length(Result)+1);
- Result[High(Result)] := ResList[a];
- end;
-
- Sign := '';
+ SetLength(Result, Length(Result)+1);
+ Result[High(Result)] := ResList[a];
end;
-
+ end;
WAD.Free();
end;
Exit;
end;
- ResList := WAD.GetRootResources();
+ ResList := WAD.GetMapResources();
WAD.Free();
mnn := g_ExtractFileName(Res);
diff --git a/src/sfs/sfs.pas b/src/sfs/sfs.pas
index 948b470c4f554901e00fce4f6a8b2e640c675498..d4ebdebe6c8cd1cc0bba60e9d61f3468dc625e97 100644 (file)
--- a/src/sfs/sfs.pas
+++ b/src/sfs/sfs.pas
// íèêàêèõ ïàäåíèé íà íåïðàâèëüíûå èíäåêñû!
function GetFiles (index: Integer): TSFSFileInfo; virtual;
- procedure removeCommonPath (); virtual;
-
public
// pSt íå îáÿçàòåëüíî çàïîìèíàòü, åñëè îí íå íóæåí.
constructor Create (const pFileName: AnsiString; pSt: TStream); virtual;
fFiles := TObjectList.Create(true);
end;
-procedure TSFSVolume.removeCommonPath ();
-begin
-end;
-
procedure TSFSVolume.DoDirectoryRead ();
var
f, c: Integer;
sfi.fPath := normalizePath(sfi.fPath);
if (length(sfi.fPath) = 0) and (length(sfi.fName) = 0) then sfi.Free else Inc(f);
end;
- removeCommonPath();
end;
destructor TSFSVolume.Destroy ();
diff --git a/src/sfs/sfsZipFS.pas b/src/sfs/sfsZipFS.pas
index c39eb4361e3e5fcfd4ff67ac4de62eacffa54734..d76114c5f5bb760a5f6152708e6a32eca66079af 100644 (file)
--- a/src/sfs/sfsZipFS.pas
+++ b/src/sfs/sfsZipFS.pas
procedure DFWADReadDirectory ();
procedure ReadDirectory (); override;
- procedure removeCommonPath (); override;
public
function OpenFileByIndex (const index: Integer): TStream; override;
end;
-function maxPrefix (s0: string; s1: string): Integer;
-var
- f: Integer;
-begin
- for f := 1 to length(s0) do
- begin
- if f > length(s1) then begin result := f; exit; end;
- if UpCase1251(s0[f]) <> UpCase1251(s1[f]) then begin result := f; exit; end;
- end;
- result := length(s0);
-end;
-
-
-procedure TSFSZipVolume.removeCommonPath ();
-var
- f, pl, maxsc, sc, c: integer;
- cp, s: string;
- fi: TSFSZipFileInfo;
-begin
- if fType <> sfszvZIP then exit;
- maxsc := 0;
- if fFiles.Count = 0 then exit;
- cp := '';
- for f := 0 to fFiles.Count-1 do
- begin
- fi := TSFSZipFileInfo(fFiles[f]);
- s := fi.fPath;
- if length(s) > 0 then begin cp := s; break; end;
- end;
- if length(cp) = 0 then exit;
- for f := 0 to fFiles.Count-1 do
- begin
- fi := TSFSZipFileInfo(fFiles[f]);
- s := fi.fPath;
- if length(s) = 0 then continue;
- pl := maxPrefix(cp, s);
- //writeln('s=[', s, ']; cp=[', cp, ']; pl=', pl);
- if pl = 0 then exit; // no common prefix at all
- cp := Copy(cp, 1, pl);
- sc := 0;
- for c := 1 to length(s) do if s[c] = '/' then Inc(sc);
- if sc > maxsc then maxsc := sc;
- end;
- if maxsc < 2 then exit; // alas
- while (length(cp) > 0) and (cp[length(cp)] <> '/') do cp := Copy(cp, 1, length(cp)-1);
- if length(cp) < 2 then exit; // nothing to do
- for f := 0 to fFiles.Count-1 do
- begin
- fi := TSFSZipFileInfo(fFiles[f]);
- if length(fi.fPath) >= length(cp) then
- begin
- s := fi.fPath;
- fi.fPath := Copy(fi.fPath, length(cp)+1, length(fi.fPath));
- //writeln('FIXED [', s, '] -> [', fi.fPath, ']');
- end;
- end;
-end;
-
-
{ TSFSZipVolume }
procedure TSFSZipVolume.ZIPReadDirectory ();
var
index ade53adcf7f9343c6ed882a20c7df2b626b0ac7e..1c5fb19e123bded268c49037fb551d2efac87d9f 100644 (file)
--- a/src/shared/wadreader.pas
+++ b/src/shared/wadreader.pas
unit wadreader;
{$DEFINE SFS_DWFAD_DEBUG}
+{$DEFINE SFS_MAPDETECT_FX}
interface
fIter: TSFSFileList;
function getIsOpen (): Boolean;
+ function isMapResource (idx: Integer): Boolean;
+
+ function GetResourceEx (name: AnsiString; wantMap: Boolean; var pData: Pointer; var Len: Integer): Boolean;
public
constructor Create();
function ReadMemory (Data: Pointer; Len: LongWord): Boolean;
function GetResource (name: AnsiString; var pData: Pointer; var Len: Integer): Boolean;
- function GetRootResources (): SArray;
+ function GetMapResource (name: AnsiString; var pData: Pointer; var Len: Integer): Boolean;
+ function GetMapResources (): SArray;
property isOpen: Boolean read getIsOpen;
end;
implementation
uses
- SysUtils, Classes, BinEditor, e_log, g_options, utils;
+ SysUtils, Classes, BinEditor, e_log, g_options, utils, MAPSTRUCT;
function findDiskWad (fname: AnsiString): AnsiString;
fFileName := '';
end;
+function TWADFile.isMapResource (idx: Integer): Boolean;
+var
+ sign: packed array [0..2] of Char;
+ fs: TStream;
+begin
+ result := false;
+ if not isOpen or (fIter = nil) then exit;
+ if (idx < 0) or (idx >= fIter.Count) then exit;
+ fs := nil;
+ try
+ fs := fIter.volume.OpenFileByIndex(idx);
+ fs.readBuffer(sign, 3);
+ result := (sign = MAP_SIGNATURE);
+ except
+ if fs <> nil then fs.Free();
+ exit;
+ end;
+ fs.Free();
+end;
function removeExt (s: AnsiString): AnsiString;
var
result := s;
end;
-function TWADFile.GetResource (name: AnsiString; var pData: Pointer; var Len: Integer): Boolean;
+function TWADFile.GetResourceEx (name: AnsiString; wantMap: Boolean; var pData: Pointer; var Len: Integer): Boolean;
var
f, lastSlash: Integer;
fi: TSFSFileInfo;
fs: TStream;
fpp: Pointer;
rpath, rname: AnsiString;
- //fn: AnsiString;
+ sign: array [0..2] of Char;
+ goodMap: Boolean;
begin
Result := False;
if not isOpen or (fIter = nil) then Exit;
begin
fi := fIter.Files[f];
if fi = nil then continue;
- //e_WriteLog(Format('DFWAD: searching for [%s : %s] in [%s]; current is [%s : %s]', [Section, Resource, fFileName, fi.path, fi.name]), MSG_NOTIFY);
- if StrEquCI1251(fi.path, rpath) and StrEquCI1251(removeExt(fi.name), rname) then
+ if StrEquCI1251(removeExt(fi.name), rname) then
begin
- // i found her!
- //fn := fFileName+'::'+fi.path+fi.name;
- //fs := SFSFileOpen(fn);
+ // i found her (maybe)
+ if not wantMap then
+ begin
+ if length(fi.path) < length(rpath) then continue; // alas
+ if length(fi.path) = length(rpath) then
+ begin
+ if not StrEquCI1251(fi.path, rpath) then continue; // alas
+ end
+ else
+ begin
+ if fi.path[length(fi.path)-length(rpath)] <> '/' then continue; // alas
+ if not StrEquCI1251(Copy(fi.path, length(fi.path)+1-length(rpath), length(fi.path)), rpath) then continue; // alas
+ end;
+ end;
try
fs := fIter.volume.OpenFileByIndex(f);
except
end;
if fs = nil then
begin
+ if wantMap then continue;
e_WriteLog(Format('DFWAD: can''t open file [%s] in [%s]', [name, fFileName]), MSG_WARNING);
break;
end;
+ // if we want only maps, check if this is map
+{$IFDEF SFS_MAPDETECT_FX}
+ if wantMap then
+ begin
+ goodMap := false;
+ e_WriteLog(Format('DFWAD: checking for good map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]), MSG_NOTIFY);
+ try
+ fs.readBuffer(sign, 3);
+ goodMap := (sign = MAP_SIGNATURE);
+ if goodMap then
+ e_WriteLog(Format(' GOOD map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]), MSG_NOTIFY)
+ else
+ e_WriteLog(Format(' BAD map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]), MSG_NOTIFY);
+ except
+ end;
+ if not goodMap then
+ begin
+ e_WriteLog(Format(' not a map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]), MSG_NOTIFY);
+ fs.Free();
+ continue;
+ end;
+ fs.position := 0;
+ end;
+{$ENDIF}
Len := Integer(fs.size);
GetMem(pData, Len);
fpp := pData;
end;
fs.Free;
end;
+{$IFNDEF SFS_MAPDETECT_FX}
+ if wantMap then
+ begin
+ goodMap := false;
+ if Len >= 3 then
+ begin
+ Move(pData^, sign, 3);
+ goodMap := (sign = MAP_SIGNATURE);
+ end;
+ if not goodMap then
+ begin
+ e_WriteLog(Format(' not a map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]), MSG_NOTIFY);
+ FreeMem(pData);
+ pData := nil;
+ Len := 0;
+ continue;
+ end;
+ end;
+{$ENDIF}
result := true;
{$IFDEF SFS_DWFAD_DEBUG}
if gSFSDebug then
e_WriteLog(Format('DFWAD: file [%s] not found in [%s]', [name, fFileName]), MSG_WARNING);
end;
+function TWADFile.GetResource (name: AnsiString; var pData: Pointer; var Len: Integer): Boolean;
+begin
+ result := GetResourceEx(name, false, pData, Len);
+end;
-function TWADFile.GetRootResources (): SArray;
+function TWADFile.GetMapResource (name: AnsiString; var pData: Pointer; var Len: Integer): Boolean;
+begin
+ result := GetResourceEx(name, true, pData, Len);
+end;
+
+function TWADFile.GetMapResources (): SArray;
var
- f: Integer;
+ f, c: Integer;
fi: TSFSFileInfo;
+ s: AnsiString;
begin
Result := nil;
if not isOpen or (fIter = nil) then Exit;
- for f := 0 to fIter.Count-1 do
+ for f := fIter.Count-1 downto 0 do
begin
fi := fIter.Files[f];
if fi = nil then continue;
if length(fi.name) = 0 then continue;
- if length(fi.path) = 0 then
+ e_WriteLog(Format('DFWAD: checking for map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]), MSG_NOTIFY);
+ if isMapResource(f) then
begin
- SetLength(result, Length(result)+1);
- result[high(result)] := removeExt(fi.name);
+ s := removeExt(fi.name);
+ c := High(result);
+ while c >= 0 do
+ begin
+ if StrEquCI1251(result[c], s) then break;
+ Dec(c);
+ end;
+ if c < 0 then
+ begin
+ SetLength(result, Length(result)+1);
+ result[high(result)] := removeExt(fi.name);
+ end;
end;
end;
end;