DEADSOFTWARE

no more d2d:f built-in dfwad reader, it now using sfs (and can't load map, lol)
[d2df-sdl.git] / src / shared / WADEDITOR.pas
1 unit WADEDITOR;
3 {
4 -----------------------------------
5 WADEDITOR.PAS ÂÅÐÑÈß ÎÒ 26.08.08
7 Ïîääåðæêà âàäîâ âåðñèè 1
8 -----------------------------------
9 }
11 interface
13 uses
14 sfs, xstreams;
17 type
18 SArray = array of ShortString;
20 TWADEditor_1 = class(TObject)
21 private
22 fFileName: string; // empty: not opened
23 fIter: TSFSFileList;
25 function getIsOpen (): Boolean;
27 public
28 constructor Create();
29 destructor Destroy(); override;
31 procedure FreeWAD();
33 function ReadFile (FileName: string): Boolean;
34 function ReadMemory (Data: Pointer; Len: LongWord): Boolean;
35 function GetResource (Section, Resource: string; var pData: Pointer; var Len: Integer): Boolean;
36 function GetResourcesList (Section: string): SArray;
38 property isOpen: Boolean read getIsOpen;
39 end;
41 {
42 const
43 DFWAD_NOERROR = 0;
44 DFWAD_ERROR_WADNOTFOUND = -1;
45 DFWAD_ERROR_CANTOPENWAD = -2;
46 DFWAD_ERROR_RESOURCENOTFOUND = -3;
47 DFWAD_ERROR_FILENOTWAD = -4;
48 DFWAD_ERROR_WADNOTLOADED = -5;
49 DFWAD_ERROR_READRESOURCE = -6;
50 DFWAD_ERROR_READWAD = -7;
51 DFWAD_ERROR_WRONGVERSION = -8;
52 }
55 procedure g_ProcessResourceStr (ResourceStr: String; var FileName, SectionName, ResourceName: String); overload;
56 procedure g_ProcessResourceStr (ResourceStr: String; FileName, SectionName, ResourceName: PString); overload;
59 implementation
61 uses
62 SysUtils, Classes, BinEditor, e_log;
65 procedure g_ProcessResourceStr (ResourceStr: String; var FileName, SectionName, ResourceName: String);
66 var
67 a, i: Integer;
69 begin
70 //e_WriteLog(Format('g_ProcessResourceStr0: [%s]', [ResourceStr]), MSG_NOTIFY);
71 for i := Length(ResourceStr) downto 1 do
72 if ResourceStr[i] = ':' then
73 Break;
75 FileName := Copy(ResourceStr, 1, i-1);
77 for a := i+1 to Length(ResourceStr) do
78 if (ResourceStr[a] = '\') or (ResourceStr[a] = '/') then Break;
80 ResourceName := Copy(ResourceStr, a+1, Length(ResourceStr)-Abs(a));
81 SectionName := Copy(ResourceStr, i+1, Length(ResourceStr)-Length(ResourceName)-Length(FileName)-2);
82 end;
85 procedure g_ProcessResourceStr (ResourceStr: AnsiString; FileName, SectionName, ResourceName: PAnsiString);
86 var
87 a, i, l1, l2: Integer;
89 begin
90 //e_WriteLog(Format('g_ProcessResourceStr1: [%s]', [ResourceStr]), MSG_NOTIFY);
91 for i := Length(ResourceStr) downto 1 do
92 if ResourceStr[i] = ':' then
93 Break;
95 if FileName <> nil then
96 begin
97 FileName^ := Copy(ResourceStr, 1, i-1);
98 l1 := Length(FileName^);
99 end
100 else
101 l1 := 0;
103 for a := i+1 to Length(ResourceStr) do
104 if (ResourceStr[a] = '\') or (ResourceStr[a] = '/') then Break;
106 if ResourceName <> nil then
107 begin
108 ResourceName^ := Copy(ResourceStr, a+1, Length(ResourceStr)-Abs(a));
109 l2 := Length(ResourceName^);
110 end
111 else
112 l2 := 0;
114 if SectionName <> nil then
115 SectionName^ := Copy(ResourceStr, i+1, Length(ResourceStr)-l2-l1-2);
116 end;
119 { TWADEditor_1 }
120 constructor TWADEditor_1.Create();
121 begin
122 fFileName := '';
123 end;
126 destructor TWADEditor_1.Destroy();
127 begin
128 FreeWAD();
129 inherited;
130 end;
133 function TWADEditor_1.getIsOpen (): Boolean;
134 begin
135 result := (fFileName <> '');
136 end;
139 procedure TWADEditor_1.FreeWAD();
140 begin
141 if fIter <> nil then FreeAndNil(fIter);
142 if fFileName <> '' then e_WriteLog(Format('TWADEditor_1.ReadFile: [%s] closed', [fFileName]), MSG_NOTIFY);
143 fFileName := '';
144 end;
147 function TWADEditor_1.GetResource (Section, Resource: string; var pData: Pointer; var Len: Integer): Boolean;
148 var
149 f: Integer;
150 fi: TSFSFileInfo;
151 fs: TStream;
152 fn: string;
153 begin
154 Result := False;
155 if not isOpen or (fIter = nil) then Exit;
156 if (length(Section) <> 0) and (Section[length(Section)] <> '/') then Section := Section+'/';
157 for f := 0 to fIter.Count-1 do
158 begin
159 fi := fIter.Files[f];
160 if fi = nil then continue;
161 //e_WriteLog(Format('DFWAD: searching for [%s : %s] in [%s]; current is [%s : %s] (%d, %d)', [Section, Resource, fFileName, fi.path, fi.name, SFSStrComp(fi.path, Section), SFSStrComp(fi.name, Resource)]), MSG_NOTIFY);
162 if (SFSStrComp(fi.path, Section) = 0) and (SFSStrComp(fi.name, Resource) = 0) then
163 begin
164 // i found her!
165 fn := fFileName+'::'+fi.path+fi.name;
166 fs := SFSFileOpen(fn);
167 if fs = nil then
168 begin
169 e_WriteLog(Format('DFWAD: can''t open file [%s]', [fn]), MSG_NOTIFY);
170 break;
171 end;
172 Len := Integer(fs.size);
173 GetMem(pData, Len);
174 fs.ReadBuffer(pData^, Len);
175 fs.Free;
176 result := true;
177 e_WriteLog(Format('DFWAD: file [%s%s] FOUND in [%s]; size is %d bytes', [Section, Resource, fFileName, Len]), MSG_NOTIFY);
178 exit;
179 end;
180 end;
181 e_WriteLog(Format('DFWAD: file [%s%s] not found in [%s]', [Section, Resource, fFileName]), MSG_WARNING);
182 end;
185 function TWADEditor_1.GetResourcesList (Section: string): SArray;
186 var
187 f: Integer;
188 fi: TSFSFileInfo;
189 begin
190 Result := nil;
191 if not isOpen or (fIter = nil) then Exit;
192 if (length(Section) <> 0) and (Section[length(Section)] <> '/') then Section := Section+'/';
193 for f := 0 to fIter.Count-1 do
194 begin
195 fi := fIter.Files[f];
196 if fi = nil then continue;
197 if SFSStrComp(fi.path, Section) = 0 then
198 begin
199 SetLength(result, Length(result)+1);
200 result[high(result)] := fi.name;
201 end;
202 end;
203 end;
206 function TWADEditor_1.ReadFile (FileName: string): Boolean;
207 begin
208 Result := False;
209 e_WriteLog(Format('TWADEditor_1.ReadFile: [%s]', [FileName]), MSG_NOTIFY);
210 FreeWAD();
211 if not FileExists(FileName) then Exit;
212 fIter := SFSFileList(FileName);
213 if fIter = nil then Exit;
214 fFileName := FileName;
215 e_WriteLog(Format('TWADEditor_1.ReadFile: [%s] opened', [fFileName]), MSG_NOTIFY);
216 Result := True;
217 end;
220 var
221 uniqueCounter: Integer = 0;
223 function TWADEditor_1.ReadMemory (Data: Pointer; Len: LongWord): Boolean;
224 var
225 Signature: array[0..4] of Char;
226 a: Integer;
227 fn: string;
228 st: TStream = nil;
229 begin
230 Result := False;
231 FreeWAD();
232 if (Data = nil) or (Len = 0) then Exit;
234 fn := Format(' -- memwad %d -- ', [uniqueCounter]);
235 Inc(uniqueCounter);
236 e_WriteLog(Format('TWADEditor_1.ReadMemory: [%s]', [fn]), MSG_NOTIFY);
238 try
239 st := TSFSMemoryStreamRO.Create(Data, Len);
240 if not SFSAddSubDataFile(fn, st) then
241 begin
242 st.Free;
243 Exit;
244 end;
245 except
246 st.Free;
247 Exit;
248 end;
250 fIter := SFSFileList(fn);
251 if fIter = nil then Exit;
253 fFileName := fn;
254 e_WriteLog(Format('TWADEditor_1.ReadMemory: [%s] opened', [fFileName]), MSG_NOTIFY);
256 Result := True;
257 end;
260 begin
261 sfsDiskDirs := '<exedir>/data'; //FIXME
262 end.