DEADSOFTWARE

cec3571c4e7f146b8fcc145699d15f899167999c
[d2df-sdl.git] / src / sheditor / WADEDITOR_full.pas
1 unit WADEDITOR_full;
3 {
4 -----------------------------------
5 WADEDITOR.PAS ÂÅÐÑÈß ÎÒ 26.08.08
7 Ïîääåðæêà âàäîâ âåðñèè 1
8 -----------------------------------
9 }
11 {
12 -----------------------------------
13 WADSTRUCT.PAS ÂÅÐÑÈß ÎÒ 24.09.06
15 Ïîääåðæêà âàäîâ âåðñèè 1
16 -----------------------------------
18 Ñòðóêòóðà DFWAD-ôàéëà âåðñèè 1:
19 ------------------------------------------
20 SIGNATURE | Byte[5] | 'DFWAD'
21 VERSION | Byte | $01
22 HEADER | TWADHeaderRec_1 |
23 RESRECORD1 | TResourceTableRec_1 |
24 ... | ................... |
25 RESRECORDN | TResourceTableRec_1 |
26 DATA | RAW |
27 ------------------------------------------
28 }
30 interface
32 type
33 SArray = array of ShortString;
34 Char16 = packed array[0..15] of Char;
36 TWADHeaderRec_1 = packed record
37 RecordsCount: Word;
38 end;
40 TResourceTableRec_1 = packed record
41 ResourceName: Char16;
42 Address: LongWord;
43 Length: LongWord;
44 end;
46 TWADEditor_1 = class(TObject)
47 private
48 FResData: Pointer;
49 FResTable: packed array of TResourceTableRec_1;
50 FHeader: TWADHeaderRec_1;
51 FDataSize: LongWord;
52 FOffset: LongWord;
53 FFileName: string;
54 FWADOpened: Byte;
55 FLastError: Integer;
56 FVersion: Byte;
57 function LastErrorString(): string;
58 function GetResName(ResName: string): Char16;
59 public
60 constructor Create();
61 destructor Destroy(); override;
62 procedure FreeWAD();
63 function ReadFile(FileName: string): Boolean;
64 function ReadMemory(Data: Pointer; Len: LongWord): Boolean;
65 procedure CreateImage();
66 function AddResource(Data: Pointer; Len: LongWord; Name: string;
67 Section: string): Boolean; overload;
68 function AddResource(FileName, Name, Section: string): Boolean; overload;
69 function AddAlias(Res, Alias: string): Boolean;
70 procedure AddSection(Name: string);
71 procedure RemoveResource(Section, Resource: string);
72 procedure SaveTo(FileName: string);
73 function HaveResource(Section, Resource: string): Boolean;
74 function HaveSection(Section: string): Boolean;
75 function GetResource(Section, Resource: string; var pData: Pointer;
76 var Len: Integer): Boolean;
77 function GetSectionList(): SArray;
78 function GetResourcesList(Section: string): SArray;
80 property GetLastError: Integer read FLastError;
81 property GetLastErrorStr: string read LastErrorString;
82 property GetResourcesCount: Word read FHeader.RecordsCount;
83 property GetVersion: Byte read FVersion;
84 end;
86 const
87 DFWAD_SIGNATURE = 'DFWAD';
88 DFWAD_VERSION = $01;
90 const
91 DFWAD_NOERROR = 0;
92 DFWAD_ERROR_WADNOTFOUND = -1;
93 DFWAD_ERROR_CANTOPENWAD = -2;
94 DFWAD_ERROR_RESOURCENOTFOUND = -3;
95 DFWAD_ERROR_FILENOTWAD = -4;
96 DFWAD_ERROR_WADNOTLOADED = -5;
97 DFWAD_ERROR_READRESOURCE = -6;
98 DFWAD_ERROR_READWAD = -7;
99 DFWAD_ERROR_WRONGVERSION = -8;
102 procedure g_ProcessResourceStr(ResourceStr: String; var FileName,
103 SectionName, ResourceName: String); overload;
104 procedure g_ProcessResourceStr(ResourceStr: String; FileName,
105 SectionName, ResourceName: PString); overload;
107 implementation
109 uses
110 SysUtils, BinEditor, ZLib;
112 const
113 DFWAD_OPENED_NONE = 0;
114 DFWAD_OPENED_FILE = 1;
115 DFWAD_OPENED_MEMORY = 2;
117 procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
118 OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
119 var
120 strm: TZStreamRec;
121 P: Pointer;
122 BufInc: Integer;
123 begin
124 FillChar(strm, sizeof(strm), 0);
125 BufInc := (InBytes + 255) and not 255;
126 if OutEstimate = 0 then
127 OutBytes := BufInc
128 else
129 OutBytes := OutEstimate;
130 GetMem(OutBuf, OutBytes);
131 try
132 strm.next_in := InBuf;
133 strm.avail_in := InBytes;
134 strm.next_out := OutBuf;
135 strm.avail_out := OutBytes;
136 inflateInit_(strm, zlib_version, sizeof(strm));
137 try
138 while inflate(strm, Z_FINISH) <> Z_STREAM_END do
139 begin
140 P := OutBuf;
141 Inc(OutBytes, BufInc);
142 ReallocMem(OutBuf, OutBytes);
143 strm.next_out := PByteF(PChar(OutBuf) + (PChar(strm.next_out) - PChar(P)));
144 strm.avail_out := BufInc;
145 end;
146 finally
147 inflateEnd(strm);
148 end;
149 ReallocMem(OutBuf, strm.total_out);
150 OutBytes := strm.total_out;
151 except
152 FreeMem(OutBuf);
153 raise
154 end;
155 end;
157 procedure g_ProcessResourceStr(ResourceStr: String; var FileName,
158 SectionName, ResourceName: String);
159 var
160 a, i: Integer;
162 begin
163 for i := Length(ResourceStr) downto 1 do
164 if ResourceStr[i] = ':' then
165 Break;
167 FileName := Copy(ResourceStr, 1, i-1);
169 for a := i+1 to Length(ResourceStr) do
170 if (ResourceStr[a] = '\') or (ResourceStr[a] = '/') then Break;
172 ResourceName := Copy(ResourceStr, a+1, Length(ResourceStr)-Abs(a));
173 SectionName := Copy(ResourceStr, i+1, Length(ResourceStr)-Length(ResourceName)-Length(FileName)-2);
174 end;
176 procedure g_ProcessResourceStr(ResourceStr: AnsiString; FileName,
177 SectionName, ResourceName: PAnsiString);
178 var
179 a, i, l1, l2: Integer;
181 begin
182 for i := Length(ResourceStr) downto 1 do
183 if ResourceStr[i] = ':' then
184 Break;
186 if FileName <> nil then
187 begin
188 FileName^ := Copy(ResourceStr, 1, i-1);
189 l1 := Length(FileName^);
190 end
191 else
192 l1 := 0;
194 for a := i+1 to Length(ResourceStr) do
195 if (ResourceStr[a] = '\') or (ResourceStr[a] = '/') then Break;
197 if ResourceName <> nil then
198 begin
199 ResourceName^ := Copy(ResourceStr, a+1, Length(ResourceStr)-Abs(a));
200 l2 := Length(ResourceName^);
201 end
202 else
203 l2 := 0;
205 if SectionName <> nil then
206 SectionName^ := Copy(ResourceStr, i+1, Length(ResourceStr)-l2-l1-2);
207 end;
209 { TWADEditor_1 }
211 function TWADEditor_1.AddResource(Data: Pointer; Len: LongWord; Name: string;
212 Section: string): Boolean;
213 var
214 ResCompressed: Pointer;
215 ResCompressedSize: Integer;
216 a, b: Integer;
217 begin
218 Result := False;
220 SetLength(FResTable, Length(FResTable)+1);
222 if Section = '' then
223 begin
224 if Length(FResTable) > 1 then
225 for a := High(FResTable) downto 1 do
226 FResTable[a] := FResTable[a-1];
228 a := 0;
229 end
230 else
231 begin
232 Section := AnsiUpperCase(Section);
233 b := -1;
235 for a := 0 to High(FResTable) do
236 if (FResTable[a].Length = 0) and (FResTable[a].ResourceName = Section) then
237 begin
238 for b := High(FResTable) downto a+2 do
239 FResTable[b] := FResTable[b-1];
241 b := a+1;
242 Break;
243 end;
245 if b = -1 then
246 begin
247 SetLength(FResTable, Length(FResTable)-1);
248 Exit;
249 end;
250 a := b;
251 end;
253 ResCompressed := nil;
254 ResCompressedSize := 0;
255 Compress(Data, @Len, ResCompressed, ResCompressedSize);
256 if ResCompressed = nil then Exit;
258 if FResData = nil then FResData := AllocMem(ResCompressedSize)
259 else ReallocMem(FResData, FDataSize+Cardinal(ResCompressedSize));
261 FDataSize := FDataSize+LongWord(ResCompressedSize);
263 CopyMemory(Pointer(PChar(FResData)+FDataSize-PChar(ResCompressedSize)),
264 ResCompressed, ResCompressedSize);
265 FreeMemory(ResCompressed);
267 Inc(FHeader.RecordsCount);
269 with FResTable[a] do
270 begin
271 ResourceName := GetResName(Name);
272 Address := FOffset;
273 Length := ResCompressedSize;
274 end;
276 FOffset := FOffset+Cardinal(ResCompressedSize);
278 Result := True;
279 end;
281 function TWADEditor_1.AddAlias(Res, Alias: string): Boolean;
282 var
283 a, b: Integer;
284 ares: Char16;
285 begin
286 Result := False;
288 if FResTable = nil then Exit;
290 b := -1;
291 ares := GetResName(Alias);
292 for a := 0 to High(FResTable) do
293 if FResTable[a].ResourceName = Res then
294 begin
295 b := a;
296 Break;
297 end;
299 if b = -1 then Exit;
301 Inc(FHeader.RecordsCount);
303 SetLength(FResTable, Length(FResTable)+1);
305 with FResTable[High(FResTable)] do
306 begin
307 ResourceName := ares;
308 Address := FResTable[b].Address;
309 Length := FResTable[b].Length;
310 end;
312 Result := True;
313 end;
315 function TWADEditor_1.AddResource(FileName, Name, Section: string): Boolean;
316 var
317 ResCompressed: Pointer;
318 ResCompressedSize: Integer;
319 ResourceFile: File;
320 TempResource: Pointer;
321 OriginalSize: Integer;
322 a, b: Integer;
323 begin
324 Result := False;
326 AssignFile(ResourceFile, FileName);
328 try
329 Reset(ResourceFile, 1);
330 except
331 FLastError := DFWAD_ERROR_CANTOPENWAD;
332 Exit;
333 end;
335 OriginalSize := FileSize(ResourceFile);
336 GetMem(TempResource, OriginalSize);
338 try
339 BlockRead(ResourceFile, TempResource^, OriginalSize);
340 except
341 FLastError := DFWAD_ERROR_READWAD;
342 FreeMemory(TempResource);
343 CloseFile(ResourceFile);
344 Exit;
345 end;
347 CloseFile(ResourceFile);
349 ResCompressed := nil;
350 ResCompressedSize := 0;
351 Compress(TempResource, @OriginalSize, ResCompressed, ResCompressedSize);
352 FreeMemory(TempResource);
353 if ResCompressed = nil then Exit;
355 SetLength(FResTable, Length(FResTable)+1);
357 if Section = '' then
358 begin
359 if Length(FResTable) > 1 then
360 for a := High(FResTable) downto 1 do
361 FResTable[a] := FResTable[a-1];
363 a := 0;
364 end
365 else
366 begin
367 Section := AnsiUpperCase(Section);
368 b := -1;
370 for a := 0 to High(FResTable) do
371 if (FResTable[a].Length = 0) and (FResTable[a].ResourceName = Section) then
372 begin
373 for b := High(FResTable) downto a+2 do
374 FResTable[b] := FResTable[b-1];
376 b := a+1;
377 Break;
378 end;
380 if b = -1 then
381 begin
382 FreeMemory(ResCompressed);
383 SetLength(FResTable, Length(FResTable)-1);
384 Exit;
385 end;
387 a := b;
388 end;
390 if FResData = nil then FResData := AllocMem(ResCompressedSize)
391 else ReallocMem(FResData, FDataSize+Cardinal(ResCompressedSize));
393 FDataSize := FDataSize+LongWord(ResCompressedSize);
394 CopyMemory(Pointer(PChar(FResData)+FDataSize-PChar(ResCompressedSize)),
395 ResCompressed, ResCompressedSize);
396 FreeMemory(ResCompressed);
398 Inc(FHeader.RecordsCount);
400 with FResTable[a] do
401 begin
402 ResourceName := GetResName(Name);
403 Address := FOffset;
404 Length := ResCompressedSize;
405 end;
407 FOffset := FOffset+Cardinal(ResCompressedSize);
409 Result := True;
410 end;
412 procedure TWADEditor_1.AddSection(Name: string);
413 begin
414 if Name = '' then Exit;
416 Inc(FHeader.RecordsCount);
418 SetLength(FResTable, Length(FResTable)+1);
419 with FResTable[High(FResTable)] do
420 begin
421 ResourceName := GetResName(Name);
422 Address := $00000000;
423 Length := $00000000;
424 end;
425 end;
427 constructor TWADEditor_1.Create();
428 begin
429 FResData := nil;
430 FResTable := nil;
431 FDataSize := 0;
432 FOffset := 0;
433 FHeader.RecordsCount := 0;
434 FFileName := '';
435 FWADOpened := DFWAD_OPENED_NONE;
436 FLastError := DFWAD_NOERROR;
437 FVersion := DFWAD_VERSION;
438 end;
440 procedure TWADEditor_1.CreateImage();
441 var
442 WADFile: File;
443 b: LongWord;
444 begin
445 if FWADOpened = DFWAD_OPENED_NONE then
446 begin
447 FLastError := DFWAD_ERROR_WADNOTLOADED;
448 Exit;
449 end;
451 if FWADOpened = DFWAD_OPENED_MEMORY then Exit;
453 if FResData <> nil then FreeMem(FResData);
455 try
456 AssignFile(WADFile, FFileName);
457 Reset(WADFile, 1);
459 b := 6+SizeOf(TWADHeaderRec_1)+SizeOf(TResourceTableRec_1)*Length(FResTable);
461 FDataSize := LongWord(FileSize(WADFile))-b;
463 GetMem(FResData, FDataSize);
465 Seek(WADFile, b);
466 BlockRead(WADFile, FResData^, FDataSize);
468 CloseFile(WADFile);
470 FOffset := FDataSize;
471 except
472 FLastError := DFWAD_ERROR_CANTOPENWAD;
473 CloseFile(WADFile);
474 Exit;
475 end;
477 FLastError := DFWAD_NOERROR;
478 end;
480 destructor TWADEditor_1.Destroy();
481 begin
482 FreeWAD();
484 inherited;
485 end;
487 procedure TWADEditor_1.FreeWAD();
488 begin
489 if FResData <> nil then FreeMem(FResData);
490 FResTable := nil;
491 FDataSize := 0;
492 FOffset := 0;
493 FHeader.RecordsCount := 0;
494 FFileName := '';
495 FWADOpened := DFWAD_OPENED_NONE;
496 FLastError := DFWAD_NOERROR;
497 FVersion := DFWAD_VERSION;
498 end;
500 function TWADEditor_1.GetResName(ResName: string): Char16;
501 begin
502 ZeroMemory(@Result[0], 16);
503 if ResName = '' then Exit;
505 ResName := Trim(UpperCase(ResName));
506 if Length(ResName) > 16 then SetLength(ResName, 16);
508 CopyMemory(@Result[0], @ResName[1], Length(ResName));
509 end;
511 function TWADEditor_1.HaveResource(Section, Resource: string): Boolean;
512 var
513 a: Integer;
514 CurrentSection: string;
515 begin
516 Result := False;
518 if FResTable = nil then Exit;
520 CurrentSection := '';
521 Section := AnsiUpperCase(Section);
522 Resource := AnsiUpperCase(Resource);
524 for a := 0 to High(FResTable) do
525 begin
526 if FResTable[a].Length = 0 then
527 begin
528 CurrentSection := FResTable[a].ResourceName;
529 Continue;
530 end;
532 if (FResTable[a].ResourceName = Resource) and
533 (CurrentSection = Section) then
534 begin
535 Result := True;
536 Break;
537 end;
538 end;
539 end;
541 function TWADEditor_1.HaveSection(Section: string): Boolean;
542 var
543 a: Integer;
544 begin
545 Result := False;
547 if FResTable = nil then Exit;
548 if Section = '' then
549 begin
550 Result := True;
551 Exit;
552 end;
554 Section := AnsiUpperCase(Section);
556 for a := 0 to High(FResTable) do
557 if (FResTable[a].Length = 0) and (FResTable[a].ResourceName = Section) then
558 begin
559 Result := True;
560 Exit;
561 end;
562 end;
564 function TWADEditor_1.GetResource(Section, Resource: string;
565 var pData: Pointer; var Len: Integer): Boolean;
566 var
567 a: LongWord;
568 i: Integer;
569 WADFile: File;
570 CurrentSection: string;
571 TempData: Pointer;
572 OutBytes: Integer;
573 begin
574 Result := False;
576 CurrentSection := '';
578 if FWADOpened = DFWAD_OPENED_NONE then
579 begin
580 FLastError := DFWAD_ERROR_WADNOTLOADED;
581 Exit;
582 end;
584 Section := UpperCase(Section);
585 Resource := UpperCase(Resource);
587 i := -1;
588 for a := 0 to High(FResTable) do
589 begin
590 if FResTable[a].Length = 0 then
591 begin
592 CurrentSection := FResTable[a].ResourceName;
593 Continue;
594 end;
596 if (FResTable[a].ResourceName = Resource) and
597 (CurrentSection = Section) then
598 begin
599 i := a;
600 Break;
601 end;
602 end;
604 if i = -1 then
605 begin
606 FLastError := DFWAD_ERROR_RESOURCENOTFOUND;
607 Exit;
608 end;
610 if FWADOpened = DFWAD_OPENED_FILE then
611 begin
612 try
613 AssignFile(WADFile, FFileName);
614 Reset(WADFile, 1);
616 Seek(WADFile, FResTable[i].Address+6+
617 LongWord(SizeOf(TWADHeaderRec_1)+SizeOf(TResourceTableRec_1)*Length(FResTable)));
618 TempData := GetMemory(FResTable[i].Length);
619 BlockRead(WADFile, TempData^, FResTable[i].Length);
620 DecompressBuf(TempData, FResTable[i].Length, 0, pData, OutBytes);
621 FreeMem(TempData);
623 Len := OutBytes;
625 CloseFile(WADFile);
626 except
627 FLastError := DFWAD_ERROR_CANTOPENWAD;
628 CloseFile(WADFile);
629 Exit;
630 end;
631 end
632 else
633 begin
634 TempData := GetMemory(FResTable[i].Length);
635 CopyMemory(TempData, Pointer(LongWord(FResData)+FResTable[i].Address+6+
636 LongWord(SizeOf(TWADHeaderRec_1)+SizeOf(TResourceTableRec_1)*Length(FResTable))),
637 FResTable[i].Length);
638 DecompressBuf(TempData, FResTable[i].Length, 0, pData, OutBytes);
639 FreeMem(TempData);
641 Len := OutBytes;
642 end;
644 FLastError := DFWAD_NOERROR;
645 Result := True;
646 end;
648 function TWADEditor_1.GetResourcesList(Section: string): SArray;
649 var
650 a: Integer;
651 CurrentSection: Char16;
652 begin
653 Result := nil;
655 if FResTable = nil then Exit;
656 if Length(Section) > 16 then Exit;
658 CurrentSection := '';
660 for a := 0 to High(FResTable) do
661 begin
662 if FResTable[a].Length = 0 then
663 begin
664 CurrentSection := FResTable[a].ResourceName;
665 Continue;
666 end;
668 if CurrentSection = Section then
669 begin
670 SetLength(Result, Length(Result)+1);
671 Result[High(Result)] := FResTable[a].ResourceName;
672 end;
673 end;
674 end;
676 function TWADEditor_1.GetSectionList(): SArray;
677 var
678 i: DWORD;
679 begin
680 Result := nil;
682 if FResTable = nil then Exit;
684 if FResTable[0].Length <> 0 then
685 begin
686 SetLength(Result, 1);
687 Result[0] := '';
688 end;
690 for i := 0 to High(FResTable) do
691 if FResTable[i].Length = 0 then
692 begin
693 SetLength(Result, Length(Result)+1);
694 Result[High(Result)] := FResTable[i].ResourceName;
695 end;
696 end;
698 function TWADEditor_1.LastErrorString(): string;
699 begin
700 case FLastError of
701 DFWAD_NOERROR: Result := '';
702 DFWAD_ERROR_WADNOTFOUND: Result := 'DFWAD file not found';
703 DFWAD_ERROR_CANTOPENWAD: Result := 'Can''t open DFWAD file';
704 DFWAD_ERROR_RESOURCENOTFOUND: Result := 'Resource not found';
705 DFWAD_ERROR_FILENOTWAD: Result := 'File is not DFWAD';
706 DFWAD_ERROR_WADNOTLOADED: Result := 'DFWAD file is not loaded';
707 DFWAD_ERROR_READRESOURCE: Result := 'Read resource error';
708 DFWAD_ERROR_READWAD: Result := 'Read DFWAD error';
709 else Result := 'Unknown DFWAD error';
710 end;
711 end;
713 function TWADEditor_1.ReadFile(FileName: string): Boolean;
714 var
715 WADFile: File;
716 Signature: array[0..4] of Char;
717 a: Integer;
718 begin
719 FreeWAD();
721 Result := False;
723 if not FileExists(FileName) then
724 begin
725 FLastError := DFWAD_ERROR_WADNOTFOUND;
726 Exit;
727 end;
729 FFileName := FileName;
731 AssignFile(WADFile, FFileName);
733 try
734 Reset(WADFile, 1);
735 except
736 FLastError := DFWAD_ERROR_CANTOPENWAD;
737 Exit;
738 end;
740 try
741 BlockRead(WADFile, Signature, 5);
742 if Signature <> DFWAD_SIGNATURE then
743 begin
744 FLastError := DFWAD_ERROR_FILENOTWAD;
745 CloseFile(WADFile);
746 Exit;
747 end;
749 BlockRead(WADFile, FVersion, 1);
750 if FVersion <> DFWAD_VERSION then
751 begin
752 FLastError := DFWAD_ERROR_WRONGVERSION;
753 CloseFile(WADFile);
754 Exit;
755 end;
757 BlockRead(WADFile, FHeader, SizeOf(TWADHeaderRec_1));
758 SetLength(FResTable, FHeader.RecordsCount);
759 if FResTable <> nil then
760 begin
761 BlockRead(WADFile, FResTable[0], SizeOf(TResourceTableRec_1)*FHeader.RecordsCount);
763 for a := 0 to High(FResTable) do
764 if FResTable[a].Length <> 0 then
765 FResTable[a].Address := FResTable[a].Address-6-(LongWord(SizeOf(TWADHeaderRec_1)+
766 SizeOf(TResourceTableRec_1)*Length(FResTable)));
767 end;
769 CloseFile(WADFile);
770 except
771 FLastError := DFWAD_ERROR_READWAD;
772 CloseFile(WADFile);
773 Exit;
774 end;
776 FWADOpened := DFWAD_OPENED_FILE;
777 FLastError := DFWAD_NOERROR;
778 Result := True;
779 end;
781 function TWADEditor_1.ReadMemory(Data: Pointer; Len: LongWord): Boolean;
782 var
783 Signature: array[0..4] of Char;
784 a: Integer;
785 begin
786 FreeWAD();
788 Result := False;
790 CopyMemory(@Signature[0], Data, 5);
791 if Signature <> DFWAD_SIGNATURE then
792 begin
793 FLastError := DFWAD_ERROR_FILENOTWAD;
794 Exit;
795 end;
797 CopyMemory(@FVersion, Pointer(LongWord(Data)+5), 1);
798 if FVersion <> DFWAD_VERSION then
799 begin
800 FLastError := DFWAD_ERROR_WRONGVERSION;
801 Exit;
802 end;
804 CopyMemory(@FHeader, Pointer(LongWord(Data)+6), SizeOf(TWADHeaderRec_1));
806 SetLength(FResTable, FHeader.RecordsCount);
807 if FResTable <> nil then
808 begin
809 CopyMemory(@FResTable[0], Pointer(LongWord(Data)+6+SizeOf(TWADHeaderRec_1)),
810 SizeOf(TResourceTableRec_1)*FHeader.RecordsCount);
812 for a := 0 to High(FResTable) do
813 if FResTable[a].Length <> 0 then
814 FResTable[a].Address := FResTable[a].Address-6-(LongWord(SizeOf(TWADHeaderRec_1)+
815 SizeOf(TResourceTableRec_1)*Length(FResTable)));
816 end;
818 GetMem(FResData, Len);
819 CopyMemory(FResData, Data, Len);
821 FWADOpened := DFWAD_OPENED_MEMORY;
822 FLastError := DFWAD_NOERROR;
824 Result := True;
825 end;
827 procedure TWADEditor_1.RemoveResource(Section, Resource: string);
828 var
829 a, i: Integer;
830 CurrentSection: Char16;
831 b, c, d: LongWord;
832 begin
833 if FResTable = nil then Exit;
835 i := -1;
836 b := 0;
837 c := 0;
838 CurrentSection := '';
840 for a := 0 to High(FResTable) do
841 begin
842 if FResTable[a].Length = 0 then
843 begin
844 CurrentSection := FResTable[a].ResourceName;
845 Continue;
846 end;
848 if (FResTable[a].ResourceName = Resource) and
849 (CurrentSection = Section) then
850 begin
851 i := a;
852 b := FResTable[a].Length;
853 c := FResTable[a].Address;
854 Break;
855 end;
856 end;
858 if i = -1 then Exit;
860 for a := i to High(FResTable)-1 do
861 FResTable[a] := FResTable[a+1];
863 SetLength(FResTable, Length(FResTable)-1);
865 d := 0;
866 for a := 0 to High(FResTable) do
867 if (FResTable[a].Length <> 0) and (FResTable[a].Address > c) then
868 begin
869 FResTable[a].Address := FResTable[a].Address-b;
870 d := d+FResTable[a].Length;
871 end;
873 CopyMemory(Pointer(LongWord(FResData)+c), Pointer(LongWord(FResData)+c+b), d);
875 FDataSize := FDataSize-b;
876 FOffset := FOffset-b;
877 ReallocMem(FResData, FDataSize);
879 FHeader.RecordsCount := FHeader.RecordsCount-1;
880 end;
882 procedure TWADEditor_1.SaveTo(FileName: string);
883 var
884 WADFile: File;
885 sign: string;
886 ver: Byte;
887 Header: TWADHeaderRec_1;
888 i: Integer;
889 begin
890 sign := DFWAD_SIGNATURE;
891 ver := DFWAD_VERSION;
893 Header.RecordsCount := Length(FResTable);
895 if FResTable <> nil then
896 for i := 0 to High(FResTable) do
897 if FResTable[i].Length <> 0 then
898 FResTable[i].Address := FResTable[i].Address+6+SizeOf(TWADHeaderRec_1)+
899 SizeOf(TResourceTableRec_1)*Header.RecordsCount;
901 AssignFile(WADFile, FileName);
902 Rewrite(WADFile, 1);
903 BlockWrite(WADFile, sign[1], 5);
904 BlockWrite(WADFile, ver, 1);
905 BlockWrite(WADFile, Header, SizeOf(TWADHeaderRec_1));
906 if FResTable <> nil then BlockWrite(WADFile, FResTable[0],
907 SizeOf(TResourceTableRec_1)*Header.RecordsCount);
908 if FResData <> nil then BlockWrite(WADFile, FResData^, FDataSize);
909 CloseFile(WADFile);
910 end;
912 end.