# doom-wad-php

Small PHP toolkit for reading Doom WAD files and rendering patch/texture graphics.

It currently focuses on the graphics side of classic Doom data:

- WAD header + lump directory parsing
- Doom patch (`Picture`) parsing
- `TEXTURE1` / `TEXTURE2` (`TextureX`) parsing
- `PNAMES` parsing
- Texture resolution (`TEXTUREX + PNAMES + patch lumps`)
- PNG rendering through `intervention/image`

## Requirements

- PHP 8.2+
- Composer

## Install

```bash
composer install
```

## Run tests

```bash
composer test
```

## Quick start

### 1) Parse a WAD

```php
<?php

require_once 'vendor/autoload.php';

use Doom\Wad\File as WadFile;
use Shufflingpixels\IO\BinaryReader;
use Shufflingpixels\IO\File;
use Shufflingpixels\IO\FileMode;

$file = File::open('./data/test.wad', FileMode::READ);
$wad = WadFile::parse(BinaryReader::stream($file));
```

### 2) Render a single patch lump to PNG

```php
use Doom\Image\Renderer;

$renderer = new Renderer();
$pictureRenderer = $renderer->createPicture();

$patch = $wad->firstLumpByName('S3DUMMY');
if ($patch !== null) {
    $pictureRenderer->render($patch->asPicture())->save('output/S3DUMMY.png');
}
```

### 3) Resolve and render composite textures

```php
use Doom\Image\Renderer;

$renderer = new Renderer();
$textures = $wad->resolveTextures();

foreach ($textures as $texture) {
    $canvas = $renderer->createTexture($texture->width, $texture->height);

    foreach ($texture->patches as $patch) {
        if ($patch->patchName === null) {
            continue;
        }

        $path = sprintf('output/patches/%s.png', $patch->patchName);
        if (is_file($path)) {
            $canvas->blit($path, $patch->originX, $patch->originY);
        }
    }

    $canvas->image()->save(sprintf('output/textures/%s.png', $texture->name));
}
```

For a full runnable example, see `test.php`.

## Main API

- `Doom\Wad\File::parse(...)`
- `Doom\Wad\File::firstLumpByName(...)`
- `Doom\Wad\File::pNames()`
- `Doom\Wad\File::resolveTextures()`
- `Doom\Wad\Types\Lump::asPicture()`
- `Doom\Wad\Types\Lump::asTextureX()`
- `Doom\Image\Renderer`
  - `createPicture()` -> `Doom\Image\PictureRenderer`
  - `createTexture($width, $height)` -> `Doom\Image\TextureRenderer`

## Notes

- Rendering is palette-index based (Doom 8-bit graphics model).
- The default Doom palette is built in, and custom palettes are supported via `Doom\Picture\Palette`.

## References

- [Doom source code](https://github.com/id-Software/DOOM)
- [Doom Wiki](https://doomwiki.org)
- [Unofficial Doom specs](https://www.gamers.org/dhs/helpdocs/dmsp1666.html)
- [SLADE 3](https://github.com/sirjuddington/SLADE)
