Skip to content

Wad Reading Basics

Kaelan Evans edited this page Sep 4, 2020 · 21 revisions

Written for Alpha 0.0.6

Wads are the external data format that id Tech 1 uses. Anything that isn't related to how the engine functions is stored here, graphics, audio, and map data primarily. Modern wad formats can hold other assets inside of them, and are typically nothing more than a .zip file. Sometimes these wads can contain wads inside of them, though this practice is heavily discouraged. This wiki page should help explain how to load a wad and read it's contents.

Code reference

Implementation

HxDoom will automatically parse a provided wad when loaded. The user can then utilize the classes found in hxdoom.core to access specific assets within the wad. HxDoom organizes loaded wad data by the name provided to them in the second argument for addWadBytes/addWadString. It is heavily discouraged allowing wads of the same name to be loaded into the engine.

If your target/framework reads files as haxe.io.bytes:

#import hxdoom.Engine;

var hxd:Engine;

public function main() {
   hxd = new Engine();
   hxd.addWadBytes(haxe.io.bytes, "filename.wad");
}

If your target/framework reads files as String:

#import hxdoom.Engine;

var hxd:Engine;

public function main() {
   hxd = new Engine();
   hxd.addWadString(FileString, "filename.wad");
}

Once this has been called, the user can then access specific assets and functions going through the core handlers located in hxdoom.Engine.hx as static vars. These core classes provide some minor abstractions to make specific asset grabbing much easier on the user.

  • Engine.TEXTURES for graphical assets.
  • Engine.LEVELS for map related assets and functions.

For game related behaviors, it is recommended that an IWAD is loaded first, followed by any PWADs desired. The default behavior in HxDoom is to disallow loading in multiple IWADS (To avoid critical name conflicts). Users can call CVarCore.setCVar("ALLOW_MULTIPLE_IWADS", true); before loading in an IWAD to disable this prevention.

For wads that contain several assets with overlapping names, accessing assets through the core handlers will provide the latest loaded asset. This is to mimic vanilla and modern behavior of Doom engines.

Manual asset retrieval

In the events a user may need more direct control of loading specific assets, hxdoom.core.WadCore can be used. This can be more easily accessed through Engine.WADDATA. Assets within a wad are preloaded through data wrappers referred to as Directories. They contain the name of the asset, their size in bytes, and the data offset of where the actual data is located in it's corresponding wad. HxDoom organizes these through a Map<String, Array<Directory>>.

To load a specific directory:

var directory = Engine.WADDATA.getGeneralDir(String, Optional Integer);

The first argument expects the asset name, while the second argument denotes the loaded order, the default value being 0. If the user is unsure if multiple assets have been loaded under the same given name, the length of the array can be checked with Engine.WADDATA.directory_name_map[Asset Name].length. Assets are stored in reverse order that they were loaded in, latest loaded asset being at index 0. Once called, the function will return a hxdoom.lumps.Directory.hx and contain the needed properties

Retrieving the corresponding wad data:

var data = Engine.WADDATA.getWadByteArray(directory.wad);

Once this is retrieved, we can then point the info gathered towards hxdoom.core.Reader.hx. Reader handles the data parsing and interpreting. The engine is incapable of detecting an asset type automatically, so it is within the users best interest to either solve what type it is or know ahead of time what sort of asset it is.

var patch = Reader.readPatch(data, directory.dataOffset); //hxdoom.lumps.graphic.Patch;

Some aspects may need further solving in order to be read correctly, as in the case for reading vertices for a map (From hxdoom.core.LevelCore.hx):

numitems = Std.int(mapDir.size / Vertex.BYTE_SIZE);
for (a in 0...numitems) {
   _map.vertexes[a] = Reader.readVertex(byteData, mapDir.dataOffset + a * Vertex.BYTE_SIZE); //hxdoom.lumps.map.Vertex;
}

In this case, directory.size can be used to solve the number of items within the chunk of data.


HxDoom tip! All classes in the hxdoom.lumps package have a toString() function within them, this can be used to make sure assets are being read correctly in the program.


Clone this wiki locally