conveyor graphics fix
[jetset.git] / wadarc.d
blob6b0fa32e15aa628acafb10ca71174a15558dbeca
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/>.
19 module wadarc;
20 private:
22 import std.stdio;
25 // ////////////////////////////////////////////////////////////////////////// //
26 public struct PakFileInfo {
27 string name;
28 uint size;
32 // ////////////////////////////////////////////////////////////////////////// //
33 private struct WadFileInfo {
34 uint ofs;
35 uint size;
36 string name;
37 File wadfl;
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);
57 uint pos = 0;
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;
65 return res;
67 throw new Exception("file not found");
71 // ////////////////////////////////////////////////////////////////////////// //
72 uint readUInt (File fl) {
73 uint v;
74 foreach (immutable shift; 0..4) {
75 ubyte b;
76 if (fl.rawRead((&b)[0..1]).length != 1) throw new Exception("read error");
77 v |= b<<(shift*8);
79 return v;
82 void readBuf(T) (File fl, T[] buf) {
83 if (buf.length == 0) return;
84 if (buf.length > int.max/2) assert(0, "wtf?!");
85 int pos = 0;
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) {
96 char[4] sign;
97 File fl;
98 try {
99 fl = File(pak);
100 } catch (Exception e) {
101 if (optional) return;
102 throw e;
104 fl.readBuf(sign[]);
105 if (firstWad) {
106 if (sign != "IWAD") throw new Exception("invalid wad");
107 firstWad = false;
108 } else {
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");
115 fl.seek(dofs);
116 while (fcount--) {
117 char[8] nbuf = 0;
118 uint ofs = fl.readUInt;
119 uint size = fl.readUInt;
120 fl.readBuf(nbuf[]);
121 const(char)[] nm;
122 foreach (immutable idx, ref char ch; nbuf[]) {
123 if (ch == 0) break;
124 if (ch >= 'A' && ch <= 'Z') ch += 32;
125 nm = nbuf[0..idx+1];
127 string name = nm.idup;
128 files[name] = WadFileInfo(ofs, size, name, fl);