1 /* coded by Ketmar // Invisible Vector <ketmar@ketmar.no-ip.org>
2 * Understanding is not required. Only obedience.
3 * Based on Jet-Set Willy, v1.0.1 by <Florent.Guillaume@ens.fr>
4 * Linux port and preliminary sound by jmd@dcs.ed.ac.uk
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 // ////////////////////////////////////////////////////////////////////////// //
26 public struct PakFileInfo
{
32 // ////////////////////////////////////////////////////////////////////////// //
33 private struct WadFileInfo
{
41 __gshared WadFileInfo
[string
] files
;
42 __gshared
bool firstWad
= true;
45 // ////////////////////////////////////////////////////////////////////////// //
46 public void forEachWadFile (void delegate (string name
, uint size
) dg
) {
47 foreach (const ref fi
; files
.byValue
) dg(fi
.name
, fi
.size
);
51 // ////////////////////////////////////////////////////////////////////////// //
52 public ubyte[] wadLoadFile (const(char)[] name
) {
53 if (auto fi
= name
in files
) {
54 if (fi
.size
> 1024*1024*16) throw new Exception("file too big");
55 if (fi
.size
== 0) return null;
56 auto res
= new ubyte[](fi
.size
);
58 fi
.wadfl
.seek(fi
.ofs
);
59 while (pos
< res
.length
) {
60 //writeln(name, ": pos=", pos, "; len=", res.length);
61 auto rd
= fi
.wadfl
.rawRead(res
[pos
..$]);
62 if (rd
.length
== 0) throw new Exception("read error ("~name
.idup
~")");
63 pos
+= cast(uint)rd
.length
;
67 throw new Exception("file not found");
71 // ////////////////////////////////////////////////////////////////////////// //
72 uint readUInt (File fl
) {
74 foreach (immutable shift
; 0..4) {
76 if (fl
.rawRead((&b
)[0..1]).length
!= 1) throw new Exception("read error");
82 void readBuf(T
) (File fl
, T
[] buf
) {
83 if (buf
.length
== 0) return;
84 if (buf
.length
> int.max
/2) assert(0, "wtf?!");
86 while (pos
< buf
.length
) {
87 auto rd
= fl
.rawRead(buf
[pos
..$]);
88 if (rd
.length
== 0) throw new Exception("read error");
89 pos
+= cast(uint)rd
.length
;
94 // ////////////////////////////////////////////////////////////////////////// //
95 public void registerWad (string pak
, bool optional
=false) {
100 } catch (Exception e
) {
101 if (optional
) return;
106 if (sign
!= "IWAD") throw new Exception("invalid wad");
109 if (sign
!= "PWAD") throw new Exception("invalid wad");
111 uint fcount
= fl
.readUInt
;
112 uint dofs
= fl
.readUInt
;
113 if (fcount
== 0) return;
114 if (fcount
> 1024) throw new Exception("invalid wad");
118 uint ofs
= fl
.readUInt
;
119 uint size
= fl
.readUInt
;
122 foreach (immutable idx
, ref char ch
; nbuf
[]) {
124 if (ch
>= 'A' && ch
<= 'Z') ch
+= 32;
127 string name
= nm
.idup
;
128 files
[name
] = WadFileInfo(ofs
, size
, name
, fl
);