-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWADData.cs
More file actions
138 lines (118 loc) · 4.26 KB
/
WADData.cs
File metadata and controls
138 lines (118 loc) · 4.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
using System;
using Microsoft.Xna.Framework;
namespace Doom;
public class WADData
{
private readonly DoomEngine _engine;
private readonly WADReader _reader;
public WADData(DoomEngine engine, string mapName = "E1M1")
{
_engine = engine;
_reader = new WADReader(engine.WADPath);
MapName = mapName;
MapIndex = GetLumpIndex(mapName);
Vertexes = GetLumpData(_reader.ReadVertex, MapIndex + LumpIndices.VERTEXES, 4, 0);
Linedefs = GetLumpData(_reader.ReadLinedef, MapIndex + LumpIndices.LINEDEFS, 14, 0);
Nodes = GetLumpData(_reader.ReadNode, MapIndex + LumpIndices.NODES, 28, 0);
SubSectors = GetLumpData(_reader.ReadSubSector, MapIndex + LumpIndices.SSECTORS, 4, 0);
Segs = GetLumpData(_reader.ReadSeg, MapIndex + LumpIndices.SEGS, 12, 0);
Things = GetLumpData(_reader.ReadThing, MapIndex + LumpIndices.THINGS, 10, 0);
Sidedefs = GetLumpData(_reader.ReadSidedef, MapIndex + LumpIndices.SIDEDEFS, 30, 0);
Sectors = GetLumpData(_reader.ReadSector, MapIndex + LumpIndices.SECTORS, 26, 0);
_reader.Close();
UpdateData();
}
public string MapName { get; init; }
public int MapIndex { get; init; }
public Vector2[] Vertexes { get; init; }
public Linedef[] Linedefs { get; init; }
public Node[] Nodes { get; init; }
public SubSector[] SubSectors { get; init; }
public Seg[] Segs { get; init; }
public Thing[] Things { get; init; }
public Sidedef[] Sidedefs { get; init; }
public Sector[] Sectors { get; init; }
private void UpdateData()
{
UpdateLinedefs();
UpdateSidedefs();
UpdateSegs();
}
private void UpdateLinedefs()
{
foreach (var line in Linedefs)
{
line.FrontSidedef = Sidedefs[line.FrontSidedefId];
// 65535 or 0xFFFF represents undefined sidedef
line.BackSidedef = line.BackSidedefId == ushort.MaxValue
? null
: Sidedefs[line.BackSidedefId];
}
}
private void UpdateSidedefs()
{
foreach (var side in Sidedefs)
{
side.Sector = Sectors[side.SectorId];
}
}
private void UpdateSegs()
{
foreach (var seg in Segs)
{
seg.StartVertex = Vertexes[seg.StartVertexId];
seg.EndVertex = Vertexes[seg.EndVertexId];
seg.Linedef = Linedefs[seg.LinedefId];
// 0 = front is frontside
// 1 = back is frontside
Sector frontSector;
Sector backSector;
if (seg.Direction == 0)
{
frontSector = seg.Linedef.FrontSidedef.Sector;
backSector = seg.Linedef.BackSidedef?.Sector;
}
else
{
frontSector = seg.Linedef.BackSidedef.Sector;
backSector = seg.Linedef.FrontSidedef?.Sector;
}
seg.FrontSector = frontSector;
seg.BackSector = (LindefFlags.TwoSided & seg.Linedef.Flags) > 0
? backSector
: null;
var degs = FromBAMToDegrees(seg.Angle);
seg.Angle = seg.Angle < 0 ? (short)(360 + degs) : (short)degs;
}
}
public static float FromBAMToRadians(short bamAngle)
{
const float radiansPerBAM = MathHelper.TwoPi / 65536f;
return radiansPerBAM * bamAngle;
}
public static float FromBAMToDegrees(short bamAngle) =>
MathHelper.ToDegrees(FromBAMToRadians(bamAngle));
private T[] GetLumpData<T>(Func<int, T> read, int lumpIndex, int numberOfBytes, int headerLength)
{
var lumpInfo = _reader.Directory[lumpIndex];
var count = lumpInfo.LumpSize / numberOfBytes;
var data = new T[count];
for (var i = 0; i < count; i++)
{
var offset = lumpInfo.LumpOffset + i * numberOfBytes + headerLength;
data[i] = read(offset);
}
return data;
}
private int GetLumpIndex(string lumpName)
{
for (var i = 0; i < _reader.Directory.Length; i++)
{
if (_reader.Directory[i].LumpName == lumpName)
{
return i;
}
}
throw new Exception($"Lump {lumpName} not found");
}
}