1 /* coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
2 * Understanding is not required. Only obedience.
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.
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.
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/>.
23 // ////////////////////////////////////////////////////////////////////////// //
24 public struct PakFileInfo
{
30 // ////////////////////////////////////////////////////////////////////////// //
31 private struct WadFileInfo
{
39 __gshared WadFileInfo
[string
] files
;
40 __gshared
bool firstWad
= true;
43 // ////////////////////////////////////////////////////////////////////////// //
44 public void forEachWadFile (void delegate (string name
, uint size
) dg
) {
45 foreach (const ref fi
; files
.byValue
) dg(fi
.name
, fi
.size
);
49 // ////////////////////////////////////////////////////////////////////////// //
50 public ubyte[] wadLoadFile (const(char)[] name
) {
51 if (auto fi
= name
in files
) {
52 if (fi
.size
> 1024*1024*8) throw new Exception("file too big");
53 if (fi
.size
== 0) return null;
54 auto res
= new ubyte[](fi
.size
);
56 fi
.wadfl
.seek(fi
.ofs
);
57 while (pos
< res
.length
) {
58 //writeln(name, ": pos=", pos, "; len=", res.length);
59 auto rd
= fi
.wadfl
.rawRead(res
[pos
..$]);
60 if (rd
.length
== 0) throw new Exception("read error ("~name
.idup
~")");
61 pos
+= cast(uint)rd
.length
;
65 throw new Exception("file not found");
69 // ////////////////////////////////////////////////////////////////////////// //
70 uint readUInt (File fl
) {
72 foreach (immutable shift
; 0..4) {
74 if (fl
.rawRead((&b
)[0..1]).length
!= 1) throw new Exception("read error");
80 void readBuf(T
) (File fl
, T
[] buf
) {
81 if (buf
.length
== 0) return;
82 if (buf
.length
> int.max
/2) assert(0, "wtf?!");
84 while (pos
< buf
.length
) {
85 auto rd
= fl
.rawRead(buf
[pos
..$]);
86 if (rd
.length
== 0) throw new Exception("read error");
87 pos
+= cast(uint)rd
.length
;
92 // ////////////////////////////////////////////////////////////////////////// //
93 public void registerWad (string pak
) {
98 if (sign
!= "IWAD") throw new Exception("invalid wad");
101 if (sign
!= "PWAD") throw new Exception("invalid wad");
103 uint fcount
= fl
.readUInt
;
104 uint dofs
= fl
.readUInt
;
105 if (fcount
== 0) return;
106 if (fcount
> 1024) throw new Exception("invalid wad");
110 uint ofs
= fl
.readUInt
;
111 uint size
= fl
.readUInt
;
114 foreach (immutable idx
, ref char ch
; nbuf
[]) {
116 if (ch
>= 'A' && ch
<= 'Z') ch
+= 32;
119 string name
= nm
.idup
;
120 files
[name
] = WadFileInfo(ofs
, size
, name
, fl
);