DEADSOFTWARE

system: implement zip support again
[d2df-editor.git] / src / shared / WADEDITOR_dfwad.pas
1 unit WADEDITOR_dfwad;
3 {
4 -----------------------------------
5 WADEDITOR.PAS ÂÅÐÑÈß ÎÒ 26.08.08
7 Ïîääåðæêà âàäîâ âåðñèè 1
8 -----------------------------------
9 }
11 interface
13 uses WADEDITOR, WADSTRUCT;
15 type
16 TWADEditor_1 = class sealed(WADEDITOR.TWADEditor)
17 private
18 FResData: Pointer;
19 FResTable: packed array of TResourceTableRec_1;
20 FHeader: TWADHeaderRec_1;
21 FDataSize: LongWord;
22 FOffset: LongWord;
23 FFileName: string;
24 FWADOpened: Byte;
25 FLastError: Integer;
26 FVersion: Byte;
27 function LastErrorString(): string;
28 function GetResName(ResName: string): Char16;
29 public
30 constructor Create();
31 destructor Destroy(); override;
32 procedure FreeWAD(); override;
33 function ReadFile2(FileName: string): Boolean; override;
34 function ReadMemory(Data: Pointer; Len: LongWord): Boolean; override;
35 procedure CreateImage(); override;
36 function AddResource(Data: Pointer; Len: LongWord; Name: string;
37 Section: string): Boolean; override; overload;
38 function AddResource(FileName, Name, Section: string): Boolean; override; overload;
39 function AddAlias(Res, Alias: string): Boolean; override;
40 procedure AddSection(Name: string); override;
41 procedure RemoveResource(Section, Resource: string); override;
42 procedure SaveTo(FileName: string); override;
43 function HaveResource(Section, Resource: string): Boolean; override;
44 function HaveSection(Section: string): Boolean; override;
45 function GetResource(Section, Resource: string; var pData: Pointer;
46 var Len: Integer): Boolean; override;
47 function GetSectionList(): SArray; override;
48 function GetResourcesList(Section: string): SArray; override;
50 function GetLastError: Integer; override;
51 function GetLastErrorStr: String; override;
52 function GetResourcesCount: Word; override;
53 function GetVersion: Byte; override;
55 // property GetLastError: Integer read FLastError;
56 // property GetLastErrorStr: string read LastErrorString;
57 // property GetResourcesCount: Word read FHeader.RecordsCount;
58 // property GetVersion: Byte read FVersion;
59 end;
61 const
62 DFWAD_NOERROR = 0;
63 DFWAD_ERROR_WADNOTFOUND = -1;
64 DFWAD_ERROR_CANTOPENWAD = -2;
65 DFWAD_ERROR_RESOURCENOTFOUND = -3;
66 DFWAD_ERROR_FILENOTWAD = -4;
67 DFWAD_ERROR_WADNOTLOADED = -5;
68 DFWAD_ERROR_READRESOURCE = -6;
69 DFWAD_ERROR_READWAD = -7;
70 DFWAD_ERROR_WRONGVERSION = -8;
72 implementation
74 uses
75 SysUtils, BinEditor, ZLib, utils, e_log;
77 const
78 DFWAD_OPENED_NONE = 0;
79 DFWAD_OPENED_FILE = 1;
80 DFWAD_OPENED_MEMORY = 2;
82 procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
83 OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
84 var
85 strm: TZStreamRec;
86 P: Pointer;
87 BufInc: Integer;
88 begin
89 FillChar(strm, sizeof(strm), 0);
90 BufInc := (InBytes + 255) and not 255;
91 if OutEstimate = 0 then
92 OutBytes := BufInc
93 else
94 OutBytes := OutEstimate;
95 GetMem(OutBuf, OutBytes);
96 try
97 strm.next_in := InBuf;
98 strm.avail_in := InBytes;
99 strm.next_out := OutBuf;
100 strm.avail_out := OutBytes;
101 inflateInit_(strm, zlib_version, sizeof(strm));
102 try
103 while inflate(strm, Z_FINISH) <> Z_STREAM_END do
104 begin
105 P := OutBuf;
106 Inc(OutBytes, BufInc);
107 ReallocMem(OutBuf, OutBytes);
108 strm.next_out := PByteF(PChar(OutBuf) + (PChar(strm.next_out) - PChar(P)));
109 strm.avail_out := BufInc;
110 end;
111 finally
112 inflateEnd(strm);
113 end;
114 ReallocMem(OutBuf, strm.total_out);
115 OutBytes := strm.total_out;
116 except
117 FreeMem(OutBuf);
118 raise
119 end;
120 end;
122 procedure CompressBuf(const InBuf: Pointer; InBytes: Integer;
123 out OutBuf: Pointer; out OutBytes: Integer);
124 var
125 strm: TZStreamRec;
126 P: Pointer;
127 begin
128 FillChar(strm, sizeof(strm), 0);
129 OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255;
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 deflateInit_(strm, Z_BEST_COMPRESSION, zlib_version, sizeof(strm));
137 try
138 while deflate(strm, Z_FINISH) <> Z_STREAM_END do
139 begin
140 P := OutBuf;
141 Inc(OutBytes, 256);
142 ReallocMem(OutBuf, OutBytes);
143 strm.next_out := PByteF(PtrUInt(OutBuf + (strm.next_out - P)));
144 strm.avail_out := 256;
145 end;
146 finally
147 deflateEnd(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 { TWADEditor_1 }
159 function TWADEditor_1.AddResource(Data: Pointer; Len: LongWord; Name: string;
160 Section: string): Boolean;
161 var
162 ResCompressed: Pointer;
163 ResCompressedSize: Integer;
164 a, b: Integer;
165 begin
166 Result := False;
168 SetLength(FResTable, Length(FResTable)+1);
170 if Section = '' then
171 begin
172 if Length(FResTable) > 1 then
173 for a := High(FResTable) downto 1 do
174 FResTable[a] := FResTable[a-1];
176 a := 0;
177 end
178 else
179 begin
180 Section := AnsiUpperCase(Section);
181 b := -1;
183 for a := 0 to High(FResTable) do
184 if (FResTable[a].Length = 0) and (FResTable[a].ResourceName = Section) then
185 begin
186 for b := High(FResTable) downto a+2 do
187 FResTable[b] := FResTable[b-1];
189 b := a+1;
190 Break;
191 end;
193 if b = -1 then
194 begin
195 SetLength(FResTable, Length(FResTable)-1);
196 Exit;
197 end;
198 a := b;
199 end;
201 ResCompressed := nil;
202 ResCompressedSize := 0;
203 CompressBuf(Data, Len, ResCompressed, ResCompressedSize);
204 if ResCompressed = nil then Exit;
205 e_WriteLog('Fuck me (D)', MSG_NOTIFY);
207 if FResData = nil then FResData := AllocMem(ResCompressedSize)
208 else ReallocMem(FResData, FDataSize+Cardinal(ResCompressedSize));
210 FDataSize := FDataSize+LongWord(ResCompressedSize);
212 CopyMemory(Pointer(PChar(FResData)+FDataSize-PChar(ResCompressedSize)),
213 ResCompressed, ResCompressedSize);
214 FreeMemory(ResCompressed);
216 Inc(FHeader.RecordsCount);
218 with FResTable[a] do
219 begin
220 ResourceName := GetResName(Name);
221 Address := FOffset;
222 Length := ResCompressedSize;
223 end;
225 FOffset := FOffset+Cardinal(ResCompressedSize);
227 Result := True;
228 end;
230 function TWADEditor_1.AddAlias(Res, Alias: string): Boolean;
231 var
232 a, b: Integer;
233 ares: Char16;
234 begin
235 Result := False;
237 if FResTable = nil then Exit;
239 b := -1;
240 ares := GetResName(Alias);
241 for a := 0 to High(FResTable) do
242 if FResTable[a].ResourceName = Res then
243 begin
244 b := a;
245 Break;
246 end;
248 if b = -1 then Exit;
250 Inc(FHeader.RecordsCount);
252 SetLength(FResTable, Length(FResTable)+1);
254 with FResTable[High(FResTable)] do
255 begin
256 ResourceName := ares;
257 Address := FResTable[b].Address;
258 Length := FResTable[b].Length;
259 end;
261 Result := True;
262 end;
264 function TWADEditor_1.AddResource(FileName, Name, Section: string): Boolean;
265 var
266 ResCompressed: Pointer;
267 ResCompressedSize: Integer;
268 ResourceFile: File;
269 TempResource: Pointer;
270 OriginalSize: Integer;
271 a, b: Integer;
272 begin
273 Result := False;
275 AssignFile(ResourceFile, FileName);
277 try
278 Reset(ResourceFile, 1);
279 except
280 FLastError := DFWAD_ERROR_CANTOPENWAD;
281 Exit;
282 end;
284 OriginalSize := FileSize(ResourceFile);
285 GetMem(TempResource, OriginalSize);
287 try
288 BlockRead(ResourceFile, TempResource^, OriginalSize);
289 except
290 FLastError := DFWAD_ERROR_READWAD;
291 FreeMemory(TempResource);
292 CloseFile(ResourceFile);
293 Exit;
294 end;
296 CloseFile(ResourceFile);
298 ResCompressed := nil;
299 ResCompressedSize := 0;
300 CompressBuf(TempResource, OriginalSize, ResCompressed, ResCompressedSize);
301 FreeMemory(TempResource);
302 if ResCompressed = nil then Exit;
304 SetLength(FResTable, Length(FResTable)+1);
306 if Section = '' then
307 begin
308 if Length(FResTable) > 1 then
309 for a := High(FResTable) downto 1 do
310 FResTable[a] := FResTable[a-1];
312 a := 0;
313 end
314 else
315 begin
316 Section := AnsiUpperCase(Section);
317 b := -1;
319 for a := 0 to High(FResTable) do
320 if (FResTable[a].Length = 0) and (FResTable[a].ResourceName = Section) then
321 begin
322 for b := High(FResTable) downto a+2 do
323 FResTable[b] := FResTable[b-1];
325 b := a+1;
326 Break;
327 end;
329 if b = -1 then
330 begin
331 FreeMemory(ResCompressed);
332 SetLength(FResTable, Length(FResTable)-1);
333 Exit;
334 end;
336 a := b;
337 end;
339 if FResData = nil then FResData := AllocMem(ResCompressedSize)
340 else ReallocMem(FResData, FDataSize+Cardinal(ResCompressedSize));
342 FDataSize := FDataSize+LongWord(ResCompressedSize);
343 CopyMemory(Pointer(PChar(FResData)+FDataSize-PChar(ResCompressedSize)),
344 ResCompressed, ResCompressedSize);
345 FreeMemory(ResCompressed);
347 Inc(FHeader.RecordsCount);
349 with FResTable[a] do
350 begin
351 ResourceName := GetResName(Name);
352 Address := FOffset;
353 Length := ResCompressedSize;
354 end;
356 FOffset := FOffset+Cardinal(ResCompressedSize);
358 Result := True;
359 end;
361 procedure TWADEditor_1.AddSection(Name: string);
362 begin
363 if Name = '' then Exit;
365 Inc(FHeader.RecordsCount);
367 SetLength(FResTable, Length(FResTable)+1);
368 with FResTable[High(FResTable)] do
369 begin
370 ResourceName := GetResName(Name);
371 Address := $00000000;
372 Length := $00000000;
373 end;
374 end;
376 constructor TWADEditor_1.Create();
377 begin
378 FResData := nil;
379 FResTable := nil;
380 FDataSize := 0;
381 FOffset := 0;
382 FHeader.RecordsCount := 0;
383 FFileName := '';
384 FWADOpened := DFWAD_OPENED_NONE;
385 FLastError := DFWAD_NOERROR;
386 FVersion := DFWAD_VERSION;
387 end;
389 procedure TWADEditor_1.CreateImage();
390 var
391 WADFile: File;
392 b: LongWord;
393 begin
394 if FWADOpened = DFWAD_OPENED_NONE then
395 begin
396 FLastError := DFWAD_ERROR_WADNOTLOADED;
397 Exit;
398 end;
400 if FWADOpened = DFWAD_OPENED_MEMORY then Exit;
402 if FResData <> nil then FreeMem(FResData);
404 try
405 AssignFile(WADFile, FFileName);
406 Reset(WADFile, 1);
408 b := 6+SizeOf(TWADHeaderRec_1)+SizeOf(TResourceTableRec_1)*Length(FResTable);
410 FDataSize := LongWord(FileSize(WADFile))-b;
412 GetMem(FResData, FDataSize);
414 Seek(WADFile, b);
415 BlockRead(WADFile, FResData^, FDataSize);
417 CloseFile(WADFile);
419 FOffset := FDataSize;
420 except
421 FLastError := DFWAD_ERROR_CANTOPENWAD;
422 CloseFile(WADFile);
423 Exit;
424 end;
426 FLastError := DFWAD_NOERROR;
427 end;
429 destructor TWADEditor_1.Destroy();
430 begin
431 FreeWAD();
433 inherited;
434 end;
436 procedure TWADEditor_1.FreeWAD();
437 begin
438 if FResData <> nil then FreeMem(FResData);
439 FResTable := nil;
440 FDataSize := 0;
441 FOffset := 0;
442 FHeader.RecordsCount := 0;
443 FFileName := '';
444 FWADOpened := DFWAD_OPENED_NONE;
445 FLastError := DFWAD_NOERROR;
446 FVersion := DFWAD_VERSION;
447 end;
449 function TWADEditor_1.GetResName(ResName: string): Char16;
450 begin
451 ZeroMemory(@Result[0], 16);
452 if ResName = '' then Exit;
454 ResName := Trim(UpperCase(ResName));
455 if Length(ResName) > 16 then SetLength(ResName, 16);
457 CopyMemory(@Result[0], @ResName[1], Length(ResName));
458 end;
460 function TWADEditor_1.HaveResource(Section, Resource: string): Boolean;
461 var
462 a: Integer;
463 CurrentSection: string;
464 begin
465 Result := False;
467 if FResTable = nil then Exit;
469 CurrentSection := '';
470 Section := AnsiUpperCase(Section);
471 Resource := AnsiUpperCase(Resource);
473 for a := 0 to High(FResTable) do
474 begin
475 if FResTable[a].Length = 0 then
476 begin
477 CurrentSection := FResTable[a].ResourceName;
478 Continue;
479 end;
481 if (FResTable[a].ResourceName = Resource) and
482 (CurrentSection = Section) then
483 begin
484 Result := True;
485 Break;
486 end;
487 end;
488 end;
490 function TWADEditor_1.HaveSection(Section: string): Boolean;
491 var
492 a: Integer;
493 begin
494 Result := False;
496 if FResTable = nil then Exit;
497 if Section = '' then
498 begin
499 Result := True;
500 Exit;
501 end;
503 Section := AnsiUpperCase(Section);
505 for a := 0 to High(FResTable) do
506 if (FResTable[a].Length = 0) and (FResTable[a].ResourceName = Section) then
507 begin
508 Result := True;
509 Exit;
510 end;
511 end;
513 function TWADEditor_1.GetResource(Section, Resource: string;
514 var pData: Pointer; var Len: Integer): Boolean;
515 var
516 a: LongWord;
517 i: Integer;
518 WADFile: File;
519 CurrentSection: string;
520 TempData: Pointer;
521 OutBytes: Integer;
522 begin
523 Result := False;
525 CurrentSection := '';
527 if FWADOpened = DFWAD_OPENED_NONE then
528 begin
529 FLastError := DFWAD_ERROR_WADNOTLOADED;
530 Exit;
531 end;
533 Section := toLowerCase1251(Section);
534 Resource := toLowerCase1251(Resource);
536 i := -1;
537 for a := 0 to High(FResTable) do
538 begin
539 if FResTable[a].Length = 0 then
540 begin
541 CurrentSection := toLowerCase1251(FResTable[a].ResourceName);
542 Continue;
543 end;
545 if (toLowerCase1251(FResTable[a].ResourceName) = Resource) and
546 (CurrentSection = Section) then
547 begin
548 i := a;
549 Break;
550 end;
551 end;
553 if i = -1 then
554 begin
555 FLastError := DFWAD_ERROR_RESOURCENOTFOUND;
556 Exit;
557 end;
559 if FWADOpened = DFWAD_OPENED_FILE then
560 begin
561 try
562 AssignFile(WADFile, FFileName);
563 Reset(WADFile, 1);
565 Seek(WADFile, FResTable[i].Address+6+
566 LongWord(SizeOf(TWADHeaderRec_1)+SizeOf(TResourceTableRec_1)*Length(FResTable)));
567 TempData := GetMemory(FResTable[i].Length);
568 BlockRead(WADFile, TempData^, FResTable[i].Length);
569 DecompressBuf(TempData, FResTable[i].Length, 0, pData, OutBytes);
570 FreeMem(TempData);
572 Len := OutBytes;
574 CloseFile(WADFile);
575 except
576 FLastError := DFWAD_ERROR_CANTOPENWAD;
577 CloseFile(WADFile);
578 Exit;
579 end;
580 end
581 else
582 begin
583 TempData := GetMemory(FResTable[i].Length);
584 CopyMemory(TempData, Pointer(PtrUInt(FResData)+FResTable[i].Address+6+
585 PtrUInt(SizeOf(TWADHeaderRec_1)+SizeOf(TResourceTableRec_1)*Length(FResTable))),
586 FResTable[i].Length);
587 DecompressBuf(TempData, FResTable[i].Length, 0, pData, OutBytes);
588 FreeMem(TempData);
590 Len := OutBytes;
591 end;
593 FLastError := DFWAD_NOERROR;
594 Result := True;
595 end;
597 function TWADEditor_1.GetResourcesList(Section: string): SArray;
598 var
599 a: Integer;
600 CurrentSection: Char16;
601 begin
602 Result := nil;
604 if FResTable = nil then Exit;
605 if Length(Section) > 16 then Exit;
607 CurrentSection := '';
609 for a := 0 to High(FResTable) do
610 begin
611 if FResTable[a].Length = 0 then
612 begin
613 CurrentSection := FResTable[a].ResourceName;
614 Continue;
615 end;
617 if CurrentSection = Section then
618 begin
619 SetLength(Result, Length(Result)+1);
620 Result[High(Result)] := FResTable[a].ResourceName;
621 end;
622 end;
623 end;
625 function TWADEditor_1.GetSectionList(): SArray;
626 var
627 i: DWORD;
628 begin
629 Result := nil;
631 if FResTable = nil then Exit;
633 if FResTable[0].Length <> 0 then
634 begin
635 SetLength(Result, 1);
636 Result[0] := '';
637 end;
639 for i := 0 to High(FResTable) do
640 if FResTable[i].Length = 0 then
641 begin
642 SetLength(Result, Length(Result)+1);
643 Result[High(Result)] := FResTable[i].ResourceName;
644 end;
645 end;
647 function TWADEditor_1.LastErrorString(): string;
648 begin
649 case FLastError of
650 DFWAD_NOERROR: Result := '';
651 DFWAD_ERROR_WADNOTFOUND: Result := 'DFWAD file not found';
652 DFWAD_ERROR_CANTOPENWAD: Result := 'Can''t open DFWAD file';
653 DFWAD_ERROR_RESOURCENOTFOUND: Result := 'Resource not found';
654 DFWAD_ERROR_FILENOTWAD: Result := 'File is not DFWAD';
655 DFWAD_ERROR_WADNOTLOADED: Result := 'DFWAD file is not loaded';
656 DFWAD_ERROR_READRESOURCE: Result := 'Read resource error';
657 DFWAD_ERROR_READWAD: Result := 'Read DFWAD error';
658 end;
659 end;
661 function TWADEditor_1.ReadFile2(FileName: string): Boolean;
662 var
663 WADFile: File;
664 Signature: array[0..4] of Char;
665 a: Integer;
666 begin
667 FreeWAD();
669 Result := False;
671 if not FileExists(FileName) then
672 begin
673 FLastError := DFWAD_ERROR_WADNOTFOUND;
674 Exit;
675 end;
677 FFileName := FileName;
679 AssignFile(WADFile, FFileName);
681 try
682 Reset(WADFile, 1);
683 except
684 FLastError := DFWAD_ERROR_CANTOPENWAD;
685 Exit;
686 end;
688 try
689 BlockRead(WADFile, Signature, 5);
690 if Signature <> DFWAD_SIGNATURE then
691 begin
692 FLastError := DFWAD_ERROR_FILENOTWAD;
693 CloseFile(WADFile);
694 Exit;
695 end;
697 BlockRead(WADFile, FVersion, 1);
698 if FVersion <> DFWAD_VERSION then
699 begin
700 FLastError := DFWAD_ERROR_WRONGVERSION;
701 CloseFile(WADFile);
702 Exit;
703 end;
705 BlockRead(WADFile, FHeader, SizeOf(TWADHeaderRec_1));
706 SetLength(FResTable, FHeader.RecordsCount);
707 if FResTable <> nil then
708 begin
709 BlockRead(WADFile, FResTable[0], SizeOf(TResourceTableRec_1)*FHeader.RecordsCount);
711 for a := 0 to High(FResTable) do
712 if FResTable[a].Length <> 0 then
713 FResTable[a].Address := FResTable[a].Address-6-(LongWord(SizeOf(TWADHeaderRec_1)+
714 SizeOf(TResourceTableRec_1)*Length(FResTable)));
715 end;
717 CloseFile(WADFile);
718 except
719 FLastError := DFWAD_ERROR_READWAD;
720 CloseFile(WADFile);
721 Exit;
722 end;
724 FWADOpened := DFWAD_OPENED_FILE;
725 FLastError := DFWAD_NOERROR;
726 Result := True;
727 end;
729 function TWADEditor_1.ReadMemory(Data: Pointer; Len: LongWord): Boolean;
730 var
731 Signature: array[0..4] of Char;
732 a: Integer;
733 begin
734 FreeWAD();
736 Result := False;
738 CopyMemory(@Signature[0], Data, 5);
739 if Signature <> DFWAD_SIGNATURE then
740 begin
741 FLastError := DFWAD_ERROR_FILENOTWAD;
742 Exit;
743 end;
745 CopyMemory(@FVersion, Pointer(PtrUInt(Data)+5), 1);
746 if FVersion <> DFWAD_VERSION then
747 begin
748 FLastError := DFWAD_ERROR_WRONGVERSION;
749 Exit;
750 end;
752 CopyMemory(@FHeader, Pointer(PtrUInt(Data)+6), SizeOf(TWADHeaderRec_1));
754 SetLength(FResTable, FHeader.RecordsCount);
755 if FResTable <> nil then
756 begin
757 CopyMemory(@FResTable[0], Pointer(PtrUInt(Data)+6+SizeOf(TWADHeaderRec_1)),
758 SizeOf(TResourceTableRec_1)*FHeader.RecordsCount);
760 for a := 0 to High(FResTable) do
761 if FResTable[a].Length <> 0 then
762 FResTable[a].Address := FResTable[a].Address-6-(LongWord(SizeOf(TWADHeaderRec_1)+
763 SizeOf(TResourceTableRec_1)*Length(FResTable)));
764 end;
766 GetMem(FResData, Len);
767 CopyMemory(FResData, Data, Len);
769 FWADOpened := DFWAD_OPENED_MEMORY;
770 FLastError := DFWAD_NOERROR;
772 Result := True;
773 end;
775 procedure TWADEditor_1.RemoveResource(Section, Resource: string);
776 var
777 a, i: Integer;
778 CurrentSection: Char16;
779 b, c, d: LongWord;
780 begin
781 if FResTable = nil then Exit;
783 e_WriteLog('Fuck me (B) ' + Section + ' ' + Resource, MSG_NOTIFY);
785 i := -1;
786 b := 0;
787 c := 0;
788 CurrentSection := '';
790 for a := 0 to High(FResTable) do
791 begin
792 if FResTable[a].Length = 0 then
793 begin
794 CurrentSection := FResTable[a].ResourceName;
795 Continue;
796 end;
798 if (FResTable[a].ResourceName = Resource) and
799 (CurrentSection = Section) then
800 begin
801 i := a;
802 b := FResTable[a].Length;
803 c := FResTable[a].Address;
804 Break;
805 end;
806 end;
808 if i = -1 then Exit;
810 e_WriteLog('Fuck me (C) ' + Section + ' ' + Resource, MSG_NOTIFY);
812 for a := i to High(FResTable)-1 do
813 FResTable[a] := FResTable[a+1];
815 SetLength(FResTable, Length(FResTable)-1);
817 d := 0;
818 for a := 0 to High(FResTable) do
819 if (FResTable[a].Length <> 0) and (FResTable[a].Address > c) then
820 begin
821 FResTable[a].Address := FResTable[a].Address-b;
822 d := d+FResTable[a].Length;
823 end;
825 CopyMemory(Pointer(PtrUInt(FResData)+c), Pointer(PtrUInt(FResData)+c+b), d);
827 FDataSize := FDataSize-b;
828 FOffset := FOffset-b;
829 ReallocMem(FResData, FDataSize);
831 FHeader.RecordsCount := FHeader.RecordsCount-1;
832 end;
834 procedure TWADEditor_1.SaveTo(FileName: string);
835 var
836 WADFile: File;
837 sign: string;
838 ver: Byte;
839 Header: TWADHeaderRec_1;
840 i: Integer;
841 begin
842 sign := DFWAD_SIGNATURE;
843 ver := DFWAD_VERSION;
845 Header.RecordsCount := Length(FResTable);
847 if FResTable <> nil then
848 for i := 0 to High(FResTable) do
849 if FResTable[i].Length <> 0 then
850 FResTable[i].Address := FResTable[i].Address+6+SizeOf(TWADHeaderRec_1)+
851 SizeOf(TResourceTableRec_1)*Header.RecordsCount;
853 AssignFile(WADFile, FileName);
854 Rewrite(WADFile, 1);
855 BlockWrite(WADFile, sign[1], 5);
856 BlockWrite(WADFile, ver, 1);
857 BlockWrite(WADFile, Header, SizeOf(TWADHeaderRec_1));
858 if FResTable <> nil then BlockWrite(WADFile, FResTable[0],
859 SizeOf(TResourceTableRec_1)*Header.RecordsCount);
860 if FResData <> nil then BlockWrite(WADFile, FResData^, FDataSize);
861 CloseFile(WADFile);
862 end;
864 function TWADEditor_1.GetLastError: Integer;
865 begin
866 Result := FLastError;
867 end;
869 function TWADEditor_1.GetLastErrorStr: String;
870 begin
871 Result := LastErrorString();
872 end;
874 function TWADEditor_1.GetResourcesCount: Word;
875 begin
876 Result := FHeader.RecordsCount;
877 end;
879 function TWADEditor_1.GetVersion: Byte;
880 begin
881 Result := FVersion;
882 end;
884 begin
885 gWADEditorFactory.RegisterEditor('DFWAD', TWADEditor_1);
886 end.