X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fshared%2Fwadreader.pas;h=8207f602fcac68605e3d9d58194b117ddb4cc65c;hb=6d6df4e3427cd01e03e172984c9d0d391ff38032;hp=b8f14db952daaa900e0a6e85ce8d669519ad3c7f;hpb=997a94053b44d7b4c6e149cd3e50463386ef730c;p=d2df-sdl.git diff --git a/src/shared/wadreader.pas b/src/shared/wadreader.pas index b8f14db..8207f60 100644 --- a/src/shared/wadreader.pas +++ b/src/shared/wadreader.pas @@ -1,13 +1,28 @@ -{$MODE DELPHI} +(* Copyright (C) DooM 2D:Forever Developers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *) +{$INCLUDE a_modes.inc} unit wadreader; -{$DEFINE SFS_DWFAD_DEBUG} +{$DEFINE SFS_DFWAD_DEBUG} {$DEFINE SFS_MAPDETECT_FX} interface uses - sfs, xstreams; + sfs, xstreams, Classes; type @@ -36,6 +51,9 @@ type function GetMapResource (name: AnsiString; var pData: Pointer; var Len: Integer): Boolean; function GetMapResources (): SArray; + // returns `nil` if file wasn't found + function openFileStream (name: AnsiString): TStream; + property isOpen: Boolean read getIsOpen; end; @@ -50,10 +68,15 @@ function g_ExtractFilePathName (resourceStr: AnsiString): AnsiString; function findDiskWad (fname: AnsiString): AnsiString; +var + wadoptDebug: Boolean = false; + wadoptFast: Boolean = false; + + implementation uses - SysUtils, Classes, BinEditor, e_log, g_options, utils, MAPSTRUCT; + SysUtils, e_log, utils, MAPDEF; function findDiskWad (fname: AnsiString): AnsiString; @@ -135,7 +158,11 @@ begin if (lastSlash < 0) and (resourceStr[f] = '\') or (resourceStr[f] = '/') then lastSlash := f; if resourceStr[f] = ':' then begin - if lastSlash > 0 then result := normSlashes(Copy(resourceStr, f, lastSlash-f)); + if lastSlash > 0 then + begin + result := normSlashes(Copy(resourceStr, f, lastSlash-f)); + while (length(result) > 0) and (result[1] = '/') do Delete(result, 1, 1); + end; exit; end; end; @@ -170,9 +197,12 @@ begin if resourceStr[f] = ':' then begin result := normSlashes(Copy(resourceStr, f+1, length(resourceStr))); + while (length(result) > 0) and (result[1] = '/') do Delete(result, 1, 1); exit; end; end; + result := normSlashes(resourceStr); + while (length(result) > 0) and (result[1] = '/') do Delete(result, 1, 1); end; @@ -204,19 +234,21 @@ begin fFileName := ''; end; + +//FIXME: detect text maps properly here function TWADFile.isMapResource (idx: Integer): Boolean; var sign: packed array [0..2] of Char; - fs: TStream; + fs: TStream = nil; 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); + if not result then result := (sign[0] = 'm') and (sign[1] = 'a') and (sign[2] = 'p'); except if fs <> nil then fs.Free(); exit; @@ -224,6 +256,32 @@ begin fs.Free(); end; + +// returns `nil` if file wasn't found +function TWADFile.openFileStream (name: AnsiString): TStream; +var + f: Integer; + fi: TSFSFileInfo; +begin + result := nil; + // backwards, due to possible similar names and such + for f := fIter.Count-1 downto 0 do + begin + fi := fIter.Files[f]; + if fi = nil then continue; + if StrEquCI1251(fi.name, name) then + begin + try + result := fIter.volume.OpenFileByIndex(f); + except + result := nil; + end; + if (result <> nil) then exit; + end; + end; +end; + + function removeExt (s: AnsiString): AnsiString; var i: Integer; @@ -238,6 +296,7 @@ begin result := s; end; + function TWADFile.GetResourceEx (name: AnsiString; wantMap: Boolean; var pData: Pointer; var Len: Integer): Boolean; var f, lastSlash: Integer; @@ -245,7 +304,7 @@ var fs: TStream; fpp: Pointer; rpath, rname: AnsiString; - sign: array [0..2] of Char; + sign: packed array [0..2] of Char; goodMap: Boolean; begin Result := False; @@ -304,21 +363,26 @@ begin 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); + {$IF DEFINED(D2D_NEW_MAP_READER_DBG)} + e_LogWritefln('DFWAD: checking for good map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]); + {$ENDIF} try fs.readBuffer(sign, 3); goodMap := (sign = MAP_SIGNATURE); - { + if not goodMap then goodMap := (sign[0] = 'm') and (sign[1] = 'a') and (sign[2] = 'p'); + {$IF DEFINED(D2D_NEW_MAP_READER_DBG)} if goodMap then - e_WriteLog(Format(' GOOD map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]), MSG_NOTIFY) + e_LogWritefln(' GOOD map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]) else - e_WriteLog(Format(' BAD map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]), MSG_NOTIFY); - } + e_LogWritefln(' BAD map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]); + {$ENDIF} 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); + {$IF DEFINED(D2D_NEW_MAP_READER_DBG)} + e_LogWritefln(' not a map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]); + {$ENDIF} fs.Free(); continue; end; @@ -360,8 +424,8 @@ begin end; {$ENDIF} result := true; - {$IFDEF SFS_DWFAD_DEBUG} - if gSFSDebug then + {$IFDEF SFS_DFWAD_DEBUG} + if wadoptDebug then e_WriteLog(Format('DFWAD: file [%s] FOUND in [%s]; size is %d bytes', [name, fFileName, Len]), MSG_NOTIFY); {$ENDIF} exit; @@ -393,7 +457,9 @@ begin fi := fIter.Files[f]; if fi = nil then continue; if length(fi.name) = 0 then continue; - //e_WriteLog(Format('DFWAD: checking for map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]), MSG_NOTIFY); + {$IF DEFINED(D2D_NEW_MAP_READER)} + //e_LogWritefln('DFWAD: checking for map in wad [%s], file [%s] (#%d)', [fFileName, fi.fname, f]); + {$ENDIF} if isMapResource(f) then begin s := removeExt(fi.name); @@ -428,12 +494,12 @@ begin e_WriteLog(Format('TWADFile.ReadFile: error looking for [%s]', [FileName]), MSG_NOTIFY); exit; end; - {$IFDEF SFS_DWFAD_DEBUG} - if gSFSDebug then e_WriteLog(Format('TWADFile.ReadFile: FOUND [%s]', [rfn]), MSG_NOTIFY); + {$IFDEF SFS_DFWAD_DEBUG} + if wadoptDebug then e_WriteLog(Format('TWADFile.ReadFile: FOUND [%s]', [rfn]), MSG_NOTIFY); {$ENDIF} // cache this wad try - if gSFSFastMode then + if wadoptFast then begin if not SFSAddDataFile(rfn, true) then exit; end @@ -447,8 +513,8 @@ begin fIter := SFSFileList(rfn); if fIter = nil then Exit; fFileName := rfn; - {$IFDEF SFS_DWFAD_DEBUG} - if gSFSDebug then e_WriteLog(Format('TWADFile.ReadFile: [%s] opened', [fFileName]), MSG_NOTIFY); + {$IFDEF SFS_DFWAD_DEBUG} + if wadoptDebug then e_WriteLog(Format('TWADFile.ReadFile: [%s] opened', [fFileName]), MSG_NOTIFY); {$ENDIF} Result := True; end; @@ -474,8 +540,8 @@ begin fn := Format(' -- memwad %d -- ', [uniqueCounter]); Inc(uniqueCounter); - {$IFDEF SFS_DWFAD_DEBUG} - e_WriteLog(Format('TWADFile.ReadMemory: [%s]', [fn]), MSG_NOTIFY); + {$IFDEF SFS_DFWAD_DEBUG} + if wadoptDebug then e_WriteLog(Format('TWADFile.ReadMemory: [%s]', [fn]), MSG_NOTIFY); {$ENDIF} try @@ -494,8 +560,8 @@ begin if fIter = nil then Exit; fFileName := fn; - {$IFDEF SFS_DWFAD_DEBUG} - e_WriteLog(Format('TWADFile.ReadMemory: [%s] opened', [fFileName]), MSG_NOTIFY); + {$IFDEF SFS_DFWAD_DEBUG} + if wadoptDebug then e_WriteLog(Format('TWADFile.ReadMemory: [%s] opened', [fFileName]), MSG_NOTIFY); {$ENDIF} {