got rid of iv.vfs
[mmd.git] / wadarc.d
blob2a1b48e12e0a6b6423cb26207f561a62442ac8ad
1 module wadarc;
2 private:
4 import std.stdio;
7 // ////////////////////////////////////////////////////////////////////////// //
8 public struct PakFileInfo {
9 string name;
10 uint size;
14 // ////////////////////////////////////////////////////////////////////////// //
15 private struct WadFileInfo {
16 uint ofs;
17 uint size;
18 string name;
19 File wadfl;
23 __gshared WadFileInfo[string] files;
24 __gshared bool firstWad = true;
27 // ////////////////////////////////////////////////////////////////////////// //
28 public void forEachWadFile (void delegate (string name, uint size) dg) {
29 foreach (const ref fi; files.byValue) dg(fi.name, fi.size);
33 // ////////////////////////////////////////////////////////////////////////// //
34 public ubyte[] wadLoadFile (const(char)[] name) {
35 if (auto fi = name in files) {
36 if (fi.size > 1024*1024*8) throw new Exception("file too big");
37 if (fi.size == 0) return null;
38 auto res = new ubyte[](fi.size);
39 uint pos = 0;
40 fi.wadfl.seek(fi.ofs);
41 while (pos < res.length) {
42 //writeln(name, ": pos=", pos, "; len=", res.length);
43 auto rd = fi.wadfl.rawRead(res[pos..$]);
44 if (rd.length == 0) throw new Exception("read error ("~name.idup~")");
45 pos += cast(uint)rd.length;
47 return res;
49 throw new Exception("file not found");
53 // ////////////////////////////////////////////////////////////////////////// //
54 uint readUInt (File fl) {
55 uint v;
56 foreach (immutable shift; 0..4) {
57 ubyte b;
58 if (fl.rawRead((&b)[0..1]).length != 1) throw new Exception("read error");
59 v |= b<<(shift*8);
61 return v;
64 void readBuf(T) (File fl, T[] buf) {
65 if (buf.length == 0) return;
66 if (buf.length > int.max/2) assert(0, "wtf?!");
67 int pos = 0;
68 while (pos < buf.length) {
69 auto rd = fl.rawRead(buf[pos..$]);
70 if (rd.length == 0) throw new Exception("read error");
71 pos += cast(uint)rd.length;
76 // ////////////////////////////////////////////////////////////////////////// //
77 public void registerWad (string pak) {
78 char[4] sign;
79 auto fl = File(pak);
80 fl.readBuf(sign[]);
81 if (firstWad) {
82 if (sign != "IWAD") throw new Exception("invalid wad");
83 firstWad = false;
84 } else {
85 if (sign != "PWAD") throw new Exception("invalid wad");
87 uint fcount = fl.readUInt;
88 uint dofs = fl.readUInt;
89 if (fcount == 0) return;
90 if (fcount > 1024) throw new Exception("invalid wad");
91 fl.seek(dofs);
92 while (fcount--) {
93 char[8] nbuf = 0;
94 uint ofs = fl.readUInt;
95 uint size = fl.readUInt;
96 fl.readBuf(nbuf[]);
97 const(char)[] nm;
98 foreach (immutable idx, ref char ch; nbuf[]) {
99 if (ch == 0) break;
100 if (ch >= 'A' && ch <= 'Z') ch += 32;
101 nm = nbuf[0..idx+1];
103 string name = nm.idup;
104 files[name] = WadFileInfo(ofs, size, name, fl);