DEADSOFTWARE

44f9d87c524afed68c19cb850fc5731d5c81137e
[d2df-sdl.git] / src / flexui / fui_wadread.pas
1 (* coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
2 * Understanding is not required. Only obedience.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *)
17 {$INCLUDE ../shared/a_modes.inc}
18 {.$DEFINE FUI_WADREAD_DEBUG}
19 unit fui_wadread;
21 interface
23 uses
24 SysUtils, Classes;
27 function fuiAddWad (const wadfile: AnsiString): Boolean;
29 // returns `nil` if file wasn't found
30 function fuiOpenFile (const fname: AnsiString): TStream;
33 var
34 fuiDiskFirst: Boolean = true;
37 implementation
39 uses
40 sfs, utils;
43 // ////////////////////////////////////////////////////////////////////////// //
44 type
45 TFUIWad = class
46 public
47 wadname: AnsiString;
48 iter: TSFSFileList;
50 public
51 constructor Create (const awadname: AnsiString);
52 destructor Destroy (); override;
54 // returns `nil` if file wasn't found
55 function openFile (const fname: AnsiString): TStream;
56 end;
59 constructor TFUIWad.Create (const awadname: AnsiString);
60 {$IFDEF FUI_WADREAD_DEBUG}
61 var
62 f: Integer;
63 {$ENDIF}
64 begin
65 if not SFSAddDataFile(awadname, true) then raise Exception.Create('cannot open wad');
66 wadname := awadname;
67 iter := SFSFileList(awadname);
68 {$IFDEF FUI_WADREAD_DEBUG}
69 if (iter <> nil) then
70 begin
71 writeln('==== ', awadname, ' ====');
72 for f := 0 to iter.Count-1 do
73 begin
74 if (iter.Files[f] = nil) then continue;
75 writeln(' ', f, ': ', iter.Files[f].path, iter.Files[f].name);
76 end;
77 writeln('========');
78 end;
79 {$ENDIF}
80 end;
83 destructor TFUIWad.Destroy ();
84 begin
85 wadname := '';
86 FreeAndNil(iter);
87 inherited;
88 end;
91 function TFUIWad.openFile (const fname: AnsiString): TStream;
92 var
93 f: Integer;
94 fi: TSFSFileInfo;
95 begin
96 result := nil;
97 if (iter = nil) then exit;
98 // backwards, due to possible similar names and such
99 for f := iter.Count-1 downto 0 do
100 begin
101 fi := iter.Files[f];
102 if (fi = nil) then continue;
103 if (StrEquCI1251(fi.path+fi.name, fname)) then
104 begin
105 try
106 result := iter.volume.OpenFileByIndex(f);
107 except
108 result := nil;
109 end;
110 if (result <> nil) then exit;
111 end;
112 end;
113 end;
117 // ////////////////////////////////////////////////////////////////////////// //
118 function getExeDataPath (): AnsiString;
119 begin
120 result := getFilenamePath(ParamStr(0))+'data/';
121 end;
124 // ////////////////////////////////////////////////////////////////////////// //
125 var
126 wadlist: array of TFUIWad = nil;
129 function fuiAddWad (const wadfile: AnsiString): Boolean;
130 var
131 exepath: AnsiString;
132 awadname: AnsiString;
133 f, c: Integer;
134 wad: TFUIWad;
135 begin
136 result := false;
138 // find disk file
139 if (Length(wadfile) = 0) then exit;
141 if (Length(wadfile) > 2) and (wadfile[1] = '.') and ((wadfile[2] = '/') or (wadfile[2] = '\')) then
142 begin
143 awadname := wadfile;
144 awadname := findDiskWad(awadname);
145 if (Length(awadname) = 0) then
146 begin
147 writeln('WARNING: FlexUI WAD ''', wadfile, ''' not found');
148 exit;
149 end;
150 end
151 else
152 begin
153 exepath := getExeDataPath();
154 awadname := exepath+wadfile;
155 awadname := findDiskWad(awadname);
156 if (Length(awadname) = 0) then
157 begin
158 awadname := wadfile;
159 awadname := findDiskWad(awadname);
160 if (Length(awadname) = 0) then
161 begin
162 writeln('WARNING: FlexUI WAD ''', exepath+wadfile, ''' not found');
163 exit;
164 end;
165 end;
166 end;
168 // check if we already have this file opened
169 for f := 0 to High(wadlist) do
170 begin
171 wad := wadlist[f];
172 if (strEquCI1251(awadname, wad.wadname)) then
173 begin
174 // i found her! move it to the bottom of the list, so it will be checked first
175 for c := f+1 to High(wadlist) do wadlist[c-1] := wadlist[c];
176 wadlist[High(wadlist)] := wad;
177 exit;
178 end;
179 end;
181 // create new wad file
182 try
183 wad := TFUIWad.Create(awadname);
184 except // sorry
185 writeln('WARNING: error opening FlexUI WAD ''', wadfile, '''');
186 exit;
187 end;
189 SetLength(wadlist, Length(wadlist)+1);
190 wadlist[High(wadlist)] := wad;
191 {$IFDEF FUI_WADREAD_DEBUG}writeln('FUI: added WAD: ''', wad.wadname, '''');{$ENDIF}
193 result := true;
194 end;
197 // ////////////////////////////////////////////////////////////////////////// //
198 // returns `nil` if file wasn't found
199 function tryDiskFile (const fname: AnsiString): TStream;
200 var
201 fn: AnsiString;
202 begin
203 fn := getExeDataPath()+fname;
204 try
205 result := openDiskFileRO(fn);
206 {$IFDEF FUI_WADREAD_DEBUG}writeln('FUI: opened DISK file: ''', fn, '''');{$ENDIF}
207 except
208 result := nil;
209 end;
210 end;
213 // returns `nil` if file wasn't found
214 function fuiOpenFile (const fname: AnsiString): TStream;
215 var
216 f: Integer;
217 begin
218 // disk
219 if (fuiDiskFirst) then
220 begin
221 result := tryDiskFile(fname);
222 if (result <> nil) then exit;
223 end;
224 // wads
225 for f := High(wadlist) downto 0 do
226 begin
227 result := wadlist[f].openFile(fname);
228 if (result <> nil) then
229 begin
230 {$IFDEF FUI_WADREAD_DEBUG}writeln('FUI: opened WAD file: ''', fname, ''' (from ''', wadlist[f].wadname, ''')');{$ENDIF}
231 exit;
232 end;
233 end;
234 // disk
235 if (not fuiDiskFirst) then
236 begin
237 result := tryDiskFile(fname);
238 if (result <> nil) then exit;
239 end;
240 {$IFDEF FUI_WADREAD_DEBUG}writeln('FUI: file: ''', fname, ''' NOT FOUND!');{$ENDIF}
241 result := nil;
242 end;
245 end.