DEADSOFTWARE

put "{$MODE ...}" directive in each source file; removed trailing spaces, and convert...
[d2df-sdl.git] / src / sheditor / WADEDITOR_full.pas
1 {$MODE DELPHI}
2 unit WADEDITOR_full;
4 {
5 -----------------------------------
6 WADEDITOR.PAS ÂÅÐÑÈß ÎÒ 26.08.08
8 Ïîääåðæêà âàäîâ âåðñèè 1
9 -----------------------------------
10 }
12 {
13 -----------------------------------
14 WADSTRUCT.PAS ÂÅÐÑÈß ÎÒ 24.09.06
16 Ïîääåðæêà âàäîâ âåðñèè 1
17 -----------------------------------
19 Ñòðóêòóðà DFWAD-ôàéëà âåðñèè 1:
20 ------------------------------------------
21 SIGNATURE | Byte[5] | 'DFWAD'
22 VERSION | Byte | $01
23 HEADER | TWADHeaderRec_1 |
24 RESRECORD1 | TResourceTableRec_1 |
25 ... | ................... |
26 RESRECORDN | TResourceTableRec_1 |
27 DATA | RAW |
28 ------------------------------------------
29 }
31 interface
33 type
34 SArray = array of ShortString;
35 Char16 = packed array[0..15] of Char;
37 TWADHeaderRec_1 = packed record
38 RecordsCount: Word;
39 end;
41 TResourceTableRec_1 = packed record
42 ResourceName: Char16;
43 Address: LongWord;
44 Length: LongWord;
45 end;
47 TWADEditor_1 = class(TObject)
48 private
49 FResData: Pointer;
50 FResTable: packed array of TResourceTableRec_1;
51 FHeader: TWADHeaderRec_1;
52 FDataSize: LongWord;
53 FOffset: LongWord;
54 FFileName: string;
55 FWADOpened: Byte;
56 FLastError: Integer;
57 FVersion: Byte;
58 function LastErrorString(): string;
59 function GetResName(ResName: string): Char16;
60 public
61 constructor Create();
62 destructor Destroy(); override;
63 procedure FreeWAD();
64 function ReadFile(FileName: string): Boolean;
65 function ReadMemory(Data: Pointer; Len: LongWord): Boolean;
66 procedure CreateImage();
67 function AddResource(Data: Pointer; Len: LongWord; Name: string;
68 Section: string): Boolean; overload;
69 function AddResource(FileName, Name, Section: string): Boolean; overload;
70 function AddAlias(Res, Alias: string): Boolean;
71 procedure AddSection(Name: string);
72 procedure RemoveResource(Section, Resource: string);
73 procedure SaveTo(FileName: string);
74 function HaveResource(Section, Resource: string): Boolean;
75 function HaveSection(Section: string): Boolean;
76 function GetResource(Section, Resource: string; var pData: Pointer;
77 var Len: Integer): Boolean;
78 function GetSectionList(): SArray;
79 function GetResourcesList(Section: string): SArray;
81 property GetLastError: Integer read FLastError;
82 property GetLastErrorStr: string read LastErrorString;
83 property GetResourcesCount: Word read FHeader.RecordsCount;
84 property GetVersion: Byte read FVersion;
85 end;
87 const
88 DFWAD_SIGNATURE = 'DFWAD';
89 DFWAD_VERSION = $01;
91 const
92 DFWAD_NOERROR = 0;
93 DFWAD_ERROR_WADNOTFOUND = -1;
94 DFWAD_ERROR_CANTOPENWAD = -2;
95 DFWAD_ERROR_RESOURCENOTFOUND = -3;
96 DFWAD_ERROR_FILENOTWAD = -4;
97 DFWAD_ERROR_WADNOTLOADED = -5;
98 DFWAD_ERROR_READRESOURCE = -6;
99 DFWAD_ERROR_READWAD = -7;
100 DFWAD_ERROR_WRONGVERSION = -8;
103 procedure g_ProcessResourceStr(ResourceStr: String; var FileName,
104 SectionName, ResourceName: String); overload;
105 procedure g_ProcessResourceStr(ResourceStr: String; FileName,
106 SectionName, ResourceName: PString); overload;
108 implementation
110 uses
111 SysUtils, BinEditor, ZLib;
113 const
114 DFWAD_OPENED_NONE = 0;
115 DFWAD_OPENED_FILE = 1;
116 DFWAD_OPENED_MEMORY = 2;
118 procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
119 OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
120 var
121 strm: TZStreamRec;
122 P: Pointer;
123 BufInc: Integer;
124 begin
125 FillChar(strm, sizeof(strm), 0);
126 BufInc := (InBytes + 255) and not 255;
127 if OutEstimate = 0 then
128 OutBytes := BufInc
129 else
130 OutBytes := OutEstimate;
131 GetMem(OutBuf, OutBytes);
132 try
133 strm.next_in := InBuf;
134 strm.avail_in := InBytes;
135 strm.next_out := OutBuf;
136 strm.avail_out := OutBytes;
137 inflateInit_(strm, zlib_version, sizeof(strm));
138 try
139 while inflate(strm, Z_FINISH) <> Z_STREAM_END do
140 begin
141 P := OutBuf;
142 Inc(OutBytes, BufInc);
143 ReallocMem(OutBuf, OutBytes);
144 strm.next_out := PByteF(PChar(OutBuf) + (PChar(strm.next_out) - PChar(P)));
145 strm.avail_out := BufInc;
146 end;
147 finally
148 inflateEnd(strm);
149 end;
150 ReallocMem(OutBuf, strm.total_out);
151 OutBytes := strm.total_out;
152 except
153 FreeMem(OutBuf);
154 raise
155 end;
156 end;
158 procedure g_ProcessResourceStr(ResourceStr: String; var FileName,
159 SectionName, ResourceName: String);
160 var
161 a, i: Integer;
163 begin
164 for i := Length(ResourceStr) downto 1 do
165 if ResourceStr[i] = ':' then
166 Break;
168 FileName := Copy(ResourceStr, 1, i-1);
170 for a := i+1 to Length(ResourceStr) do
171 if (ResourceStr[a] = '\') or (ResourceStr[a] = '/') then Break;
173 ResourceName := Copy(ResourceStr, a+1, Length(ResourceStr)-Abs(a));
174 SectionName := Copy(ResourceStr, i+1, Length(ResourceStr)-Length(ResourceName)-Length(FileName)-2);
175 end;
177 procedure g_ProcessResourceStr(ResourceStr: AnsiString; FileName,
178 SectionName, ResourceName: PAnsiString);
179 var
180 a, i, l1, l2: Integer;
182 begin
183 for i := Length(ResourceStr) downto 1 do
184 if ResourceStr[i] = ':' then
185 Break;
187 if FileName <> nil then
188 begin
189 FileName^ := Copy(ResourceStr, 1, i-1);
190 l1 := Length(FileName^);
191 end
192 else
193 l1 := 0;
195 for a := i+1 to Length(ResourceStr) do
196 if (ResourceStr[a] = '\') or (ResourceStr[a] = '/') then Break;
198 if ResourceName <> nil then
199 begin
200 ResourceName^ := Copy(ResourceStr, a+1, Length(ResourceStr)-Abs(a));
201 l2 := Length(ResourceName^);
202 end
203 else
204 l2 := 0;
206 if SectionName <> nil then
207 SectionName^ := Copy(ResourceStr, i+1, Length(ResourceStr)-l2-l1-2);
208 end;
210 { TWADEditor_1 }
212 function TWADEditor_1.AddResource(Data: Pointer; Len: LongWord; Name: string;
213 Section: string): Boolean;
214 var
215 ResCompressed: Pointer;
216 ResCompressedSize: Integer;
217 a, b: Integer;
218 begin
219 Result := False;
221 SetLength(FResTable, Length(FResTable)+1);
223 if Section = '' then
224 begin
225 if Length(FResTable) > 1 then
226 for a := High(FResTable) downto 1 do
227 FResTable[a] := FResTable[a-1];
229 a := 0;
230 end
231 else
232 begin
233 Section := AnsiUpperCase(Section);
234 b := -1;
236 for a := 0 to High(FResTable) do
237 if (FResTable[a].Length = 0) and (FResTable[a].ResourceName = Section) then
238 begin
239 for b := High(FResTable) downto a+2 do
240 FResTable[b] := FResTable[b-1];
242 b := a+1;
243 Break;
244 end;
246 if b = -1 then
247 begin
248 SetLength(FResTable, Length(FResTable)-1);
249 Exit;
250 end;
251 a := b;
252 end;
254 ResCompressed := nil;
255 ResCompressedSize := 0;
256 Compress(Data, @Len, ResCompressed, ResCompressedSize);
257 if ResCompressed = nil then Exit;
259 if FResData = nil then FResData := AllocMem(ResCompressedSize)
260 else ReallocMem(FResData, FDataSize+Cardinal(ResCompressedSize));
262 FDataSize := FDataSize+LongWord(ResCompressedSize);
264 CopyMemory(Pointer(PChar(FResData)+FDataSize-PChar(ResCompressedSize)),
265 ResCompressed, ResCompressedSize);
266 FreeMemory(ResCompressed);
268 Inc(FHeader.RecordsCount);
270 with FResTable[a] do
271 begin
272 ResourceName := GetResName(Name);
273 Address := FOffset;
274 Length := ResCompressedSize;
275 end;
277 FOffset := FOffset+Cardinal(ResCompressedSize);
279 Result := True;
280 end;
282 function TWADEditor_1.AddAlias(Res, Alias: string): Boolean;
283 var
284 a, b: Integer;
285 ares: Char16;
286 begin
287 Result := False;
289 if FResTable = nil then Exit;
291 b := -1;
292 ares := GetResName(Alias);
293 for a := 0 to High(FResTable) do
294 if FResTable[a].ResourceName = Res then
295 begin
296 b := a;
297 Break;
298 end;
300 if b = -1 then Exit;
302 Inc(FHeader.RecordsCount);
304 SetLength(FResTable, Length(FResTable)+1);
306 with FResTable[High(FResTable)] do
307 begin
308 ResourceName := ares;
309 Address := FResTable[b].Address;
310 Length := FResTable[b].Length;
311 end;
313 Result := True;
314 end;
316 function TWADEditor_1.AddResource(FileName, Name, Section: string): Boolean;
317 var
318 ResCompressed: Pointer;
319 ResCompressedSize: Integer;
320 ResourceFile: File;
321 TempResource: Pointer;
322 OriginalSize: Integer;
323 a, b: Integer;
324 begin
325 Result := False;
327 AssignFile(ResourceFile, FileName);
329 try
330 Reset(ResourceFile, 1);
331 except
332 FLastError := DFWAD_ERROR_CANTOPENWAD;
333 Exit;
334 end;
336 OriginalSize := FileSize(ResourceFile);
337 GetMem(TempResource, OriginalSize);
339 try
340 BlockRead(ResourceFile, TempResource^, OriginalSize);
341 except
342 FLastError := DFWAD_ERROR_READWAD;
343 FreeMemory(TempResource);
344 CloseFile(ResourceFile);
345 Exit;
346 end;
348 CloseFile(ResourceFile);
350 ResCompressed := nil;
351 ResCompressedSize := 0;
352 Compress(TempResource, @OriginalSize, ResCompressed, ResCompressedSize);
353 FreeMemory(TempResource);
354 if ResCompressed = nil then Exit;
356 SetLength(FResTable, Length(FResTable)+1);
358 if Section = '' then
359 begin
360 if Length(FResTable) > 1 then
361 for a := High(FResTable) downto 1 do
362 FResTable[a] := FResTable[a-1];
364 a := 0;
365 end
366 else
367 begin
368 Section := AnsiUpperCase(Section);
369 b := -1;
371 for a := 0 to High(FResTable) do
372 if (FResTable[a].Length = 0) and (FResTable[a].ResourceName = Section) then
373 begin
374 for b := High(FResTable) downto a+2 do
375 FResTable[b] := FResTable[b-1];
377 b := a+1;
378 Break;
379 end;
381 if b = -1 then
382 begin
383 FreeMemory(ResCompressed);
384 SetLength(FResTable, Length(FResTable)-1);
385 Exit;
386 end;
388 a := b;
389 end;
391 if FResData = nil then FResData := AllocMem(ResCompressedSize)
392 else ReallocMem(FResData, FDataSize+Cardinal(ResCompressedSize));
394 FDataSize := FDataSize+LongWord(ResCompressedSize);
395 CopyMemory(Pointer(PChar(FResData)+FDataSize-PChar(ResCompressedSize)),
396 ResCompressed, ResCompressedSize);
397 FreeMemory(ResCompressed);
399 Inc(FHeader.RecordsCount);
401 with FResTable[a] do
402 begin
403 ResourceName := GetResName(Name);
404 Address := FOffset;
405 Length := ResCompressedSize;
406 end;
408 FOffset := FOffset+Cardinal(ResCompressedSize);
410 Result := True;
411 end;
413 procedure TWADEditor_1.AddSection(Name: string);
414 begin
415 if Name = '' then Exit;
417 Inc(FHeader.RecordsCount);
419 SetLength(FResTable, Length(FResTable)+1);
420 with FResTable[High(FResTable)] do
421 begin
422 ResourceName := GetResName(Name);
423 Address := $00000000;
424 Length := $00000000;
425 end;
426 end;
428 constructor TWADEditor_1.Create();
429 begin
430 FResData := nil;
431 FResTable := nil;
432 FDataSize := 0;
433 FOffset := 0;
434 FHeader.RecordsCount := 0;
435 FFileName := '';
436 FWADOpened := DFWAD_OPENED_NONE;
437 FLastError := DFWAD_NOERROR;
438 FVersion := DFWAD_VERSION;
439 end;
441 procedure TWADEditor_1.CreateImage();
442 var
443 WADFile: File;
444 b: LongWord;
445 begin
446 if FWADOpened = DFWAD_OPENED_NONE then
447 begin
448 FLastError := DFWAD_ERROR_WADNOTLOADED;
449 Exit;
450 end;
452 if FWADOpened = DFWAD_OPENED_MEMORY then Exit;
454 if FResData <> nil then FreeMem(FResData);
456 try
457 AssignFile(WADFile, FFileName);
458 Reset(WADFile, 1);
460 b := 6+SizeOf(TWADHeaderRec_1)+SizeOf(TResourceTableRec_1)*Length(FResTable);
462 FDataSize := LongWord(FileSize(WADFile))-b;
464 GetMem(FResData, FDataSize);
466 Seek(WADFile, b);
467 BlockRead(WADFile, FResData^, FDataSize);
469 CloseFile(WADFile);
471 FOffset := FDataSize;
472 except
473 FLastError := DFWAD_ERROR_CANTOPENWAD;
474 CloseFile(WADFile);
475 Exit;
476 end;
478 FLastError := DFWAD_NOERROR;
479 end;
481 destructor TWADEditor_1.Destroy();
482 begin
483 FreeWAD();
485 inherited;
486 end;
488 procedure TWADEditor_1.FreeWAD();
489 begin
490 if FResData <> nil then FreeMem(FResData);
491 FResTable := nil;
492 FDataSize := 0;
493 FOffset := 0;
494 FHeader.RecordsCount := 0;
495 FFileName := '';
496 FWADOpened := DFWAD_OPENED_NONE;
497 FLastError := DFWAD_NOERROR;
498 FVersion := DFWAD_VERSION;
499 end;
501 function TWADEditor_1.GetResName(ResName: string): Char16;
502 begin
503 ZeroMemory(@Result[0], 16);
504 if ResName = '' then Exit;
506 ResName := Trim(UpperCase(ResName));
507 if Length(ResName) > 16 then SetLength(ResName, 16);
509 CopyMemory(@Result[0], @ResName[1], Length(ResName));
510 end;
512 function TWADEditor_1.HaveResource(Section, Resource: string): Boolean;
513 var
514 a: Integer;
515 CurrentSection: string;
516 begin
517 Result := False;
519 if FResTable = nil then Exit;
521 CurrentSection := '';
522 Section := AnsiUpperCase(Section);
523 Resource := AnsiUpperCase(Resource);
525 for a := 0 to High(FResTable) do
526 begin
527 if FResTable[a].Length = 0 then
528 begin
529 CurrentSection := FResTable[a].ResourceName;
530 Continue;
531 end;
533 if (FResTable[a].ResourceName = Resource) and
534 (CurrentSection = Section) then
535 begin
536 Result := True;
537 Break;
538 end;
539 end;
540 end;
542 function TWADEditor_1.HaveSection(Section: string): Boolean;
543 var
544 a: Integer;
545 begin
546 Result := False;
548 if FResTable = nil then Exit;
549 if Section = '' then
550 begin
551 Result := True;
552 Exit;
553 end;
555 Section := AnsiUpperCase(Section);
557 for a := 0 to High(FResTable) do
558 if (FResTable[a].Length = 0) and (FResTable[a].ResourceName = Section) then
559 begin
560 Result := True;
561 Exit;
562 end;
563 end;
565 function TWADEditor_1.GetResource(Section, Resource: string;
566 var pData: Pointer; var Len: Integer): Boolean;
567 var
568 a: LongWord;
569 i: Integer;
570 WADFile: File;
571 CurrentSection: string;
572 TempData: Pointer;
573 OutBytes: Integer;
574 begin
575 Result := False;
577 CurrentSection := '';
579 if FWADOpened = DFWAD_OPENED_NONE then
580 begin
581 FLastError := DFWAD_ERROR_WADNOTLOADED;
582 Exit;
583 end;
585 Section := UpperCase(Section);
586 Resource := UpperCase(Resource);
588 i := -1;
589 for a := 0 to High(FResTable) do
590 begin
591 if FResTable[a].Length = 0 then
592 begin
593 CurrentSection := FResTable[a].ResourceName;
594 Continue;
595 end;
597 if (FResTable[a].ResourceName = Resource) and
598 (CurrentSection = Section) then
599 begin
600 i := a;
601 Break;
602 end;
603 end;
605 if i = -1 then
606 begin
607 FLastError := DFWAD_ERROR_RESOURCENOTFOUND;
608 Exit;
609 end;
611 if FWADOpened = DFWAD_OPENED_FILE then
612 begin
613 try
614 AssignFile(WADFile, FFileName);
615 Reset(WADFile, 1);
617 Seek(WADFile, FResTable[i].Address+6+
618 LongWord(SizeOf(TWADHeaderRec_1)+SizeOf(TResourceTableRec_1)*Length(FResTable)));
619 TempData := GetMemory(FResTable[i].Length);
620 BlockRead(WADFile, TempData^, FResTable[i].Length);
621 DecompressBuf(TempData, FResTable[i].Length, 0, pData, OutBytes);
622 FreeMem(TempData);
624 Len := OutBytes;
626 CloseFile(WADFile);
627 except
628 FLastError := DFWAD_ERROR_CANTOPENWAD;
629 CloseFile(WADFile);
630 Exit;
631 end;
632 end
633 else
634 begin
635 TempData := GetMemory(FResTable[i].Length);
636 CopyMemory(TempData, Pointer(LongWord(FResData)+FResTable[i].Address+6+
637 LongWord(SizeOf(TWADHeaderRec_1)+SizeOf(TResourceTableRec_1)*Length(FResTable))),
638 FResTable[i].Length);
639 DecompressBuf(TempData, FResTable[i].Length, 0, pData, OutBytes);
640 FreeMem(TempData);
642 Len := OutBytes;
643 end;
645 FLastError := DFWAD_NOERROR;
646 Result := True;
647 end;
649 function TWADEditor_1.GetResourcesList(Section: string): SArray;
650 var
651 a: Integer;
652 CurrentSection: Char16;
653 begin
654 Result := nil;
656 if FResTable = nil then Exit;
657 if Length(Section) > 16 then Exit;
659 CurrentSection := '';
661 for a := 0 to High(FResTable) do
662 begin
663 if FResTable[a].Length = 0 then
664 begin
665 CurrentSection := FResTable[a].ResourceName;
666 Continue;
667 end;
669 if CurrentSection = Section then
670 begin
671 SetLength(Result, Length(Result)+1);
672 Result[High(Result)] := FResTable[a].ResourceName;
673 end;
674 end;
675 end;
677 function TWADEditor_1.GetSectionList(): SArray;
678 var
679 i: DWORD;
680 begin
681 Result := nil;
683 if FResTable = nil then Exit;
685 if FResTable[0].Length <> 0 then
686 begin
687 SetLength(Result, 1);
688 Result[0] := '';
689 end;
691 for i := 0 to High(FResTable) do
692 if FResTable[i].Length = 0 then
693 begin
694 SetLength(Result, Length(Result)+1);
695 Result[High(Result)] := FResTable[i].ResourceName;
696 end;
697 end;
699 function TWADEditor_1.LastErrorString(): string;
700 begin
701 case FLastError of
702 DFWAD_NOERROR: Result := '';
703 DFWAD_ERROR_WADNOTFOUND: Result := 'DFWAD file not found';
704 DFWAD_ERROR_CANTOPENWAD: Result := 'Can''t open DFWAD file';
705 DFWAD_ERROR_RESOURCENOTFOUND: Result := 'Resource not found';
706 DFWAD_ERROR_FILENOTWAD: Result := 'File is not DFWAD';
707 DFWAD_ERROR_WADNOTLOADED: Result := 'DFWAD file is not loaded';
708 DFWAD_ERROR_READRESOURCE: Result := 'Read resource error';
709 DFWAD_ERROR_READWAD: Result := 'Read DFWAD error';
710 else Result := 'Unknown DFWAD error';
711 end;
712 end;
714 function TWADEditor_1.ReadFile(FileName: string): Boolean;
715 var
716 WADFile: File;
717 Signature: array[0..4] of Char;
718 a: Integer;
719 begin
720 FreeWAD();
722 Result := False;
724 if not FileExists(FileName) then
725 begin
726 FLastError := DFWAD_ERROR_WADNOTFOUND;
727 Exit;
728 end;
730 FFileName := FileName;
732 AssignFile(WADFile, FFileName);
734 try
735 Reset(WADFile, 1);
736 except
737 FLastError := DFWAD_ERROR_CANTOPENWAD;
738 Exit;
739 end;
741 try
742 BlockRead(WADFile, Signature, 5);
743 if Signature <> DFWAD_SIGNATURE then
744 begin
745 FLastError := DFWAD_ERROR_FILENOTWAD;
746 CloseFile(WADFile);
747 Exit;
748 end;
750 BlockRead(WADFile, FVersion, 1);
751 if FVersion <> DFWAD_VERSION then
752 begin
753 FLastError := DFWAD_ERROR_WRONGVERSION;
754 CloseFile(WADFile);
755 Exit;
756 end;
758 BlockRead(WADFile, FHeader, SizeOf(TWADHeaderRec_1));
759 SetLength(FResTable, FHeader.RecordsCount);
760 if FResTable <> nil then
761 begin
762 BlockRead(WADFile, FResTable[0], SizeOf(TResourceTableRec_1)*FHeader.RecordsCount);
764 for a := 0 to High(FResTable) do
765 if FResTable[a].Length <> 0 then
766 FResTable[a].Address := FResTable[a].Address-6-(LongWord(SizeOf(TWADHeaderRec_1)+
767 SizeOf(TResourceTableRec_1)*Length(FResTable)));
768 end;
770 CloseFile(WADFile);
771 except
772 FLastError := DFWAD_ERROR_READWAD;
773 CloseFile(WADFile);
774 Exit;
775 end;
777 FWADOpened := DFWAD_OPENED_FILE;
778 FLastError := DFWAD_NOERROR;
779 Result := True;
780 end;
782 function TWADEditor_1.ReadMemory(Data: Pointer; Len: LongWord): Boolean;
783 var
784 Signature: array[0..4] of Char;
785 a: Integer;
786 begin
787 FreeWAD();
789 Result := False;
791 CopyMemory(@Signature[0], Data, 5);
792 if Signature <> DFWAD_SIGNATURE then
793 begin
794 FLastError := DFWAD_ERROR_FILENOTWAD;
795 Exit;
796 end;
798 CopyMemory(@FVersion, Pointer(LongWord(Data)+5), 1);
799 if FVersion <> DFWAD_VERSION then
800 begin
801 FLastError := DFWAD_ERROR_WRONGVERSION;
802 Exit;
803 end;
805 CopyMemory(@FHeader, Pointer(LongWord(Data)+6), SizeOf(TWADHeaderRec_1));
807 SetLength(FResTable, FHeader.RecordsCount);
808 if FResTable <> nil then
809 begin
810 CopyMemory(@FResTable[0], Pointer(LongWord(Data)+6+SizeOf(TWADHeaderRec_1)),
811 SizeOf(TResourceTableRec_1)*FHeader.RecordsCount);
813 for a := 0 to High(FResTable) do
814 if FResTable[a].Length <> 0 then
815 FResTable[a].Address := FResTable[a].Address-6-(LongWord(SizeOf(TWADHeaderRec_1)+
816 SizeOf(TResourceTableRec_1)*Length(FResTable)));
817 end;
819 GetMem(FResData, Len);
820 CopyMemory(FResData, Data, Len);
822 FWADOpened := DFWAD_OPENED_MEMORY;
823 FLastError := DFWAD_NOERROR;
825 Result := True;
826 end;
828 procedure TWADEditor_1.RemoveResource(Section, Resource: string);
829 var
830 a, i: Integer;
831 CurrentSection: Char16;
832 b, c, d: LongWord;
833 begin
834 if FResTable = nil then Exit;
836 i := -1;
837 b := 0;
838 c := 0;
839 CurrentSection := '';
841 for a := 0 to High(FResTable) do
842 begin
843 if FResTable[a].Length = 0 then
844 begin
845 CurrentSection := FResTable[a].ResourceName;
846 Continue;
847 end;
849 if (FResTable[a].ResourceName = Resource) and
850 (CurrentSection = Section) then
851 begin
852 i := a;
853 b := FResTable[a].Length;
854 c := FResTable[a].Address;
855 Break;
856 end;
857 end;
859 if i = -1 then Exit;
861 for a := i to High(FResTable)-1 do
862 FResTable[a] := FResTable[a+1];
864 SetLength(FResTable, Length(FResTable)-1);
866 d := 0;
867 for a := 0 to High(FResTable) do
868 if (FResTable[a].Length <> 0) and (FResTable[a].Address > c) then
869 begin
870 FResTable[a].Address := FResTable[a].Address-b;
871 d := d+FResTable[a].Length;
872 end;
874 CopyMemory(Pointer(LongWord(FResData)+c), Pointer(LongWord(FResData)+c+b), d);
876 FDataSize := FDataSize-b;
877 FOffset := FOffset-b;
878 ReallocMem(FResData, FDataSize);
880 FHeader.RecordsCount := FHeader.RecordsCount-1;
881 end;
883 procedure TWADEditor_1.SaveTo(FileName: string);
884 var
885 WADFile: File;
886 sign: string;
887 ver: Byte;
888 Header: TWADHeaderRec_1;
889 i: Integer;
890 begin
891 sign := DFWAD_SIGNATURE;
892 ver := DFWAD_VERSION;
894 Header.RecordsCount := Length(FResTable);
896 if FResTable <> nil then
897 for i := 0 to High(FResTable) do
898 if FResTable[i].Length <> 0 then
899 FResTable[i].Address := FResTable[i].Address+6+SizeOf(TWADHeaderRec_1)+
900 SizeOf(TResourceTableRec_1)*Header.RecordsCount;
902 AssignFile(WADFile, FileName);
903 Rewrite(WADFile, 1);
904 BlockWrite(WADFile, sign[1], 5);
905 BlockWrite(WADFile, ver, 1);
906 BlockWrite(WADFile, Header, SizeOf(TWADHeaderRec_1));
907 if FResTable <> nil then BlockWrite(WADFile, FResTable[0],
908 SizeOf(TResourceTableRec_1)*Header.RecordsCount);
909 if FResData <> nil then BlockWrite(WADFile, FResData^, FDataSize);
910 CloseFile(WADFile);
911 end;
913 end.