shitty title
[mmd.git] / wadarc.d
blob5118d9d4dc2217e39f1c0df7bdd9147bf01683bc
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/>.
17 module wadarc;
18 private:
20 import std.stdio;
23 // ////////////////////////////////////////////////////////////////////////// //
24 public struct PakFileInfo {
25 string name;
26 uint size;
30 // ////////////////////////////////////////////////////////////////////////// //
31 private struct WadFileInfo {
32 uint ofs;
33 uint size;
34 string name;
35 File wadfl;
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);
55 uint pos = 0;
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;
63 return res;
65 throw new Exception("file not found");
69 // ////////////////////////////////////////////////////////////////////////// //
70 uint readUInt (File fl) {
71 uint v;
72 foreach (immutable shift; 0..4) {
73 ubyte b;
74 if (fl.rawRead((&b)[0..1]).length != 1) throw new Exception("read error");
75 v |= b<<(shift*8);
77 return v;
80 void readBuf(T) (File fl, T[] buf) {
81 if (buf.length == 0) return;
82 if (buf.length > int.max/2) assert(0, "wtf?!");
83 int pos = 0;
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) {
94 char[4] sign;
95 auto fl = File(pak);
96 fl.readBuf(sign[]);
97 if (firstWad) {
98 if (sign != "IWAD") throw new Exception("invalid wad");
99 firstWad = false;
100 } else {
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");
107 fl.seek(dofs);
108 while (fcount--) {
109 char[8] nbuf = 0;
110 uint ofs = fl.readUInt;
111 uint size = fl.readUInt;
112 fl.readBuf(nbuf[]);
113 const(char)[] nm;
114 foreach (immutable idx, ref char ch; nbuf[]) {
115 if (ch == 0) break;
116 if (ch >= 'A' && ch <= 'Z') ch += 32;
117 nm = nbuf[0..idx+1];
119 string name = nm.idup;
120 files[name] = WadFileInfo(ofs, size, name, fl);