Type: Package
Title: Read and Write 'wal' Bitmap Image Files and Other 'Quake' Assets
Version: 0.1.1
Maintainer: Tim Schäfer <ts+code@rcmd.org>
Description: Read 'Quake' assets including bitmap images and textures in 'wal' file format. This package also provides support for extracting these assets from 'WAD' and 'PAK' file archives. It can also read models in 'MDL' and 'MD2' formats.
License: GPL-2
Encoding: UTF-8
URL: https://github.com/dfsp-spirit/wal
BugReports: https://github.com/dfsp-spirit/wal/issues
Imports: freesurferformats (≥ 0.1.12), imager, jpeg, png, spacesXYZ
Suggests: knitr, rmarkdown, testthat (≥ 2.1.0),
VignetteBuilder: knitr
RoxygenNote: 7.2.3
NeedsCompilation: no
Packaged: 2024-02-02 17:59:56 UTC; spirit
Author: Tim Schäfer ORCID iD [aut, cre]
Repository: CRAN
Date/Publication: 2024-02-02 18:50:02 UTC

Apply a palette to index data to create a 2D image.

Description

Apply a palette to index data to create a 2D image.

Usage

apply.palette.to.rawdata(raw_data, apply_palette, img_width, img_height)

Arguments

raw_data

integer vector of pixel data, each entry represents an index into the palette.

apply_palette

integer matrix, the palette.

img_width

integer, the width of the image to create.

img_height

integer, the height of the image to create.


Check palette, stop on invalid data.

Description

Check palette, stop on invalid data.

Usage

check.palette(pal)

Arguments

pal

a palette, i.e., a 256 x 3 integer matrix, with values in range 0..255L.


Find closest color from palette for each RGB color.

Description

Find closest color from a palette for given colors. The similarity method used to define 'closest' is deltaE, and the input RGB colors are transformed to LAB space for the computation, assuming they are given in sRGB space.

Usage

closest.color.from.palette(colors_rgb, fixed_palette_rgb)

Arguments

colors_rgb

n x 3 integer matrix, the truecolor (arbitrary) input RGB colors for which you want to find the most similar colors included in the fixed palette. Range 0..255.

fixed_palette_rgb

the fixed palette, an n x 3 matrix of integers, representing the fixed palette colors in RGB values in range 0..255.

Value

vector of n integers, the index of the closest color into the palette for each of the colors_rgb.

Examples

    colors_rgb = matrix(c(255, 0, 0, 100, 100, 100, 10, 10, 10, 5, 5, 5),
     ncol = 3, byrow = TRUE);
    fixed_palette_rgb = matrix(c(255, 0, 0, 255, 5, 0, 11, 11, 11, 0, 0, 0,
     255, 255, 255), ncol = 3, byrow = TRUE);
    pal_similar_colors = closest.color.from.palette(colors_rgb,
     fixed_palette_rgb);


Given the pixel data for the largest image, generate the full data for all mipmaps.

Description

Given the pixel data for the largest image, generate the full data for all mipmaps.

Usage

expand.rawdata.to.mipmaps(raw_data_mip_level0, width, height, byrow = TRUE)

Arguments

raw_data_mip_level0

integer vector or matrix, the image data for the largest mipmap.

width

integer, width of image for mip level 0

height

integer, width of image for mip level 0


Compute length of mipmaps in bytes from width and height of largest image (mipmap0).

Description

Compute length of mipmaps in bytes from width and height of largest image (mipmap0).

Usage

get.mipmap.data.lengths(mm0_width, mm0_height)

Arguments

mm0_width

integer, width of mipmap 0

mm0_height

integer, height of mipmap 0

Value

integer vector of length 4, the lengths.


Get mipmap offsets for WAL header, based on mipmap sizes and start offset.

Description

Get mipmap offsets for WAL header, based on mipmap sizes and start offset.

Usage

get.mipmap.data.offsets(mm0_width, mm0_height, start_at = 100L)

Arguments

mm0_width

integer, width of mipmap 0

mm0_height

integer, height of mipmap 0

start_at

integer, the offset at which the data starts in the file. Must be 100L for WAL format.

Value

integer vector of length 4, the offsets.


Translate wad directory entry types from the integer to the string representation.

Description

Translate wad directory entry types from the integer to the string representation.

Usage

get.wadentry.type.strings(wadentry_type_int)

Arguments

wadentry_type_int

integer, WAD entry type code

Value

type string


Retrieve raw data for given mipmap level from WAL instance.

Description

Retrieve raw data for given mipmap level from WAL instance.

Usage

get.wal.mipmap.data(wal, mip_level)

Arguments

wal

a WAL image instance, as returned by read.wal.

mip_level

integer in range 0..3, the mipmap to plot. Level 0 is the original full-size image, the other ones get smaller and smaller (by factor 2 on each dimension, so 1/4th the size of their predecessor).


Compute widths of the 4 mipimap levels from base width.

Description

Compute widths of the 4 mipimap levels from base width.

Usage

get.wal.mipmap.heights(height_mm)

Arguments

height_mm

integer, the base mipmap height.

Value

integer vector of length 4, the mipmap heights.


Compute widths of the 4 mipimap levels from base width.

Description

Compute widths of the 4 mipimap levels from base width.

Usage

get.wal.mipmap.widths(width_mm)

Arguments

width_mm

integer, the base mipmap width.

Value

integer vector of length 4, the mipmap widths.


Reduce image size by 2 along both axes by dropping pixels.

Description

Reduce image size by 2 along both axes by dropping pixels.

Usage

half.image(image_data, byrow = TRUE)

Arguments

image_data

integer matrix, a 1-channel image.


Convert image to WAL instance.

Description

Convert an input RGB image to a WAL instance, re-mapping its colors to the WAL palette in the process and generating the mipmaps.

Usage

img.to.wal(in_image, apply_palette = wal::pal_q2(), wal = wal.template())

Arguments

in_image

numeric matrix with 3 dimensions: widt, height, channels. Values must be in range 0..1. This is the image format returned by jpeg::readJPEG and png::readPNG. The image can have arbitrary colors, but the colors in the final WAL image will be limited to the palette. Both the width and height must be multiples of 8. Typical idtech1/2 textures use 32, 64, ..., 512. The reason is the mipmaps.

apply_palette

n x 3 integer matrix, the palette for the WAL image. This is not saved to the wal image, but still required because the colors from the in_image will be adapted to the palette colors (replaced with the most similar ones). If the palette does not cover the colors in the source image well, the resulting WAL image will look bad (dissimilar to the source image).

wal

a wal instance. Note that 1 will be substracted from the data when it is written, as indices are stored 0-based in the file.

Value

wal instance

Examples

## Not run: 
   wal = img.to.wal(jpeg::readJPEG("~/mytex.jpg"));

## End(Not run)


Check whether object is a Quake 1 or 2 alias model.

Description

Check whether object is a Quake 1 or 2 alias model.

Usage

is.quakemodel(x)

Arguments

x

any R object


Check whether object is Quake 2 MD2 model

Description

Check whether object is Quake 2 MD2 model

Usage

is.quakemodel_md2(x)

Arguments

x

any R object


Check whether object is Quake 1 MDL model

Description

Check whether object is Quake 1 MDL model

Usage

is.quakemodel_mdl(x)

Arguments

x

any R object


Lookup Quake I normals by index.

Description

Lookup Quake I normals by index.

Usage

lookup.q1.normals(normal_indices)

Arguments

normal_indices

integer vector of length n, the normal indices (0-based).

Value

n x 3 matrix of doubles, the normals


Extract PAK contents into existing directory.

Description

Extract PAK contents into existing directory.

Usage

pak.extract(pak_filepath, outdir = getwd())

Arguments

pak_filepath

character string, path to input PAK file.

outdir

character string, the output directory in which the files should be created. Must be writeable. The sub directories and filenames are derived from the data in the WAD.

Note

PAK files can contain a directory structure, and new subdirectories will be created under outdir as needed to preserve it.


Get Q1 palette.

Description

Get Q1 palette.

Usage

pal_q1()

Value

256 x 3 integer matrix, representing the RGB color values for an index into the palette.

Examples

   pal = pal_q1();
   dim(pal);


Get Q2 palette.

Description

Get Q2 palette.

Usage

pal_q2()

Value

256 x 3 integer matrix, representing the RGB color values for an index into the palette.

Examples

   pal = pal_q2();
   dim(pal);


S3 plot function for wal image.

Description

S3 plot function for wal image.

Usage

## S3 method for class 'wal'
plot(x, ...)

Arguments

x

a wal instance.

...

extra args, not used.


Plot a mipmap level from a WAL image.

Description

Plot a mipmap level from a WAL image.

Usage

plotwal.mipmap(wal, mip_level = 0L, apply_palette = wal::pal_q2())

Arguments

wal

a WAL image instance, as returned by read.wal.

mip_level

integer in range 0..3, the mipmap to plot. Level 0 is the original full-size image, the other ones get smaller and smaller (by factor 2 on each dimension, so 1/4th the size of their predecessor).

apply_palette

optional 256 x 3 integer matrix, the palette. Must contain values in range 0..255. Pass NULL if you do not want to apply any palette. The resulting wal object will not have an 'image' entry then.

Examples

## Not run: 
   walf = '~/data/q2_pak0_extracted/textures/e1u2/basic1_7.wal';
   wal = read.wal(walf);
   plotwal.mipmap(wal, mip_level = 3);

## End(Not run)


Plot raw pixel index data as image.

Description

Plot raw pixel index data as image.

Usage

plotwal.rawdata(raw_data, width, height, apply_palette = wal::pal_q2())

Arguments

raw_data

integer vector in containing width * height values in range 0..255, and optionally additional mipmap data at the end (which will be ignored). The raw image data. Can be a Q2 WAL data, Q1 miptex data, or anything else.

width

positive integer, the image width.

height

positive integer, the image height.

apply_palette

optional 256 x 3 integer matrix, the palette. Must contain values in range 0..255. Pass NULL if you do not want to apply any palette. The resulting wal object will not have an 'image' entry then.

Examples

## Not run: 
# Plot the Q1 shambler skin:
mdl = read.quake.mdl("~/data/q1_pak/progs/shambler.mdl");
plotwal.rawdata(mdl$skins$skin_pic, mdl$header$skin_width,
 mdl$header$skin_height, apply_palette = pal_q1());

## End(Not run)


Predefined MD2 normals from Quake 2.

Description

Predefined MD2 normals from Quake 2.

Usage

predefined.md2.normals()

Value

3xn matrix of normals.


Return list of pre-defined Quake I normals.

Description

Return list of pre-defined Quake I normals.

Usage

predefined.mdl.normals()

Value

n x 3 matrix of doubles, the normals. Hardcoded.


S3 print function for WAD

Description

S3 print function for WAD

Usage

## S3 method for class 'wad'
print(x, ...)

Arguments

x

wad instance

...

extra arguments, ignored


Extract any of the supported Quake archives.

Description

Extract any of the supported Quake archives.

Usage

qarchive.extract(filepath, outdir, format = "auto", do_pre_checks = TRUE)

Arguments

filepath

character string, path to existing and readable file in PAK or WAD2 format.

outdir

character string, path to an existing and writeable output directory into which to extract the archive.

format

character string, of one 'auto' to detect from filename, 'QARCHIVE_TYPE_WAD' for WAD2, or 'QARCHIVE_TYPE_PAK' for PACK.

do_pre_checks

logical, whether to perform extra sanity checks on the other parameters.


Determine archive type from file name extension.

Description

Determine archive type from file name extension.

Usage

qarchive.type.from.filename(filepath)

Arguments

filepath

character string, path to existing and readable file in PAK or WAD2 format.

Value

character string, one of 'QARCHIVE_TYPE_WAD' or 'QARCHIVE_TYPE_PAK'.


Convert Quake Model to 'fs.surface' instance.

Description

Convert Quake Model to 'fs.surface' instance.

Usage

quakemodel.to.fs.surface(quakemodel, frame_idx = 1L)

Arguments

quakemodel

an instance of quakemodel_mdl or quakemodel_md2.

frame_idx

integer, the frame to export. Quake models may contain animations made up of several frames. The mesh connectivity is unaltered between frames, but the vertex positions differ.

Value

fs.surface mesh instance, as used by the freesurferformats package.


Read binary lump, or 'lmp' files.

Description

Read binary lump, or 'lmp' files.

Usage

read.lmp(filepath, dlength = 768L)

Arguments

filepath

character string, path to the input file.

dlength

the expected data length, in bytes.

Value

vector of dlength unsigned integers in range 0..255.


Read Quake PAK archive.

Description

Read Quake PAK archive.

Usage

read.pak(filepath)

Arguments

filepath

character string, path to the file including extension.

Value

a 'pak' instance.

Examples

## Not run: 
   pakf = '~/.steam/steam/steamapps/common/Quake/Id1/PAK0.PAK';
   pak = read.pak(pakf);

## End(Not run)


Read Quake II model in MD2 format.

Description

Read Quake II model in MD2 format.

Usage

read.quake.md2(filepath, anim = FALSE)

Arguments

filepath

character string, the path to the MD2 file

anim

logical, whether to load the whole animation (if present). Returns a list of models, the animation frames. If FALSE, only the first frame is returned.

Note

Ignore this function, it will be moved to a different package.


Read Quake model in MDL format.

Description

Read Quake model in MDL format.

Usage

read.quake.mdl(filepath, do_checks = FALSE)

Arguments

filepath

character string, the path to the MDL file

do_checks

logical, whether to perform some sanity checks on the data and warn on suspicious results.

Note

Ignore this function, it will be moved to a different package.

Examples

## Not run: 
   mdlf = "~/data/q1_pak/progs/quaddama.mdl"
   mdl = read.quake.mdl(mdlf);

## End(Not run)


Read a Quake mipmap texture from a WAD2 file.

Description

Read a Quake mipmap texture from a WAD2 file.

Usage

read.quake1miptex(filepath, at_offset = 0L)

Arguments

filepath

character string, path to WAD file.

at_offset

integer, the index in the WAD file where the texture starts.

Value

a 'qmiptex' instance, its like a wall with shorter name field (16 instead of 32) and some fields (anim_name, flags, contents, value) missing.

Examples

## Not run: 
    qm = read.quake1miptex("~/knave.wad", at_offset = 1317632);
    plotwal.mipmap(qm, apply_palette = pal_q1());

## End(Not run)


Read Quake WAD file.

Description

Read Quake WAD file.

Usage

read.wad(filepath)

Arguments

filepath

character string, path to the file.

Value

a wad instance, can be used to extract data or list contents.

Examples

## Not run: 
   wadf = '~/knave.wad';
   wad = read.wad(wadf);
   wad.contents(wad);

## End(Not run)


Read bitmap file in WAL format.

Description

Read bitmap file in WAL format.

Usage

read.wal(filepath, hdr = TRUE, hdr_only = FALSE, apply_palette = wal::pal_q2())

Arguments

filepath

character string, path to the file including extension

hdr

logical, whether to return full list with header

hdr_only

logical, whether to read only the header

apply_palette

optional 256 x 3 integer matrix, the palette. Must contain values in range 0..255. Pass NULL if you do not want to apply any palette. The resulting wal object will not have an 'image' entry then.

Value

integer pixel matrix, each pixel value is in range 0-255 and refers to an index in a palette. The palette is NOT included in the file, so you will need to define one or get it from elsewhere to see the final image.

Examples

## Not run: 
   walf = '~/data/q2_pak0_extracted/textures/e1u2/basic1_7.wal';
   wal = read.wal(walf);
   plot(wal);

## End(Not run)


Read bitmap image in WAL format, returning image data only.

Description

Read a bitmap image in WAL format, and return data in the same format as png::readPNG and jpeg::readJPEG do.

Usage

readWAL(filepath, apply_palette = wal::pal_q2())

Arguments

filepath

character string, path to the file including extension

apply_palette

optional 256 x 3 integer matrix, the palette. Must contain values in range 0..255. Pass NULL if you do not want to apply any palette. The resulting wal object will not have an 'image' entry then.

Value

numeric matrix with dimension width x height x channels, with all color values in range 0..1.

See Also

read.wal if you want to read the header and have more control.

Examples

## Not run: 
   walf = '~/data/q2_pak0_extracted/textures/e1u2/basic1_7.wal';
   wal_image = readWAL(walf);
   dim(wal_image);

## End(Not run)


Read part of binary file and save as new file.

Description

Read part of binary file and save as new file.

Usage

save.filepart(infile, read_from, read_len, outfile)

Arguments

infile

for input file, part of it gets read.

read_from

integer, index at which to start reading, from start of file. Used to seek to the position.

read_len

integer, the number of bytes to read.

outfile

character string, the output filename.


Unpack vertex coords from Q1 0-255 representation.

Description

Unpack vertex coords from Q1 0-255 representation.

Usage

unpack.vertex.coords(coords_packed, mdl_header)

Arguments

coords_packed

matrix of n x 3 integers in range 0..255, the packed coords from an MDL file.

mdl_header

MDL header or named list, only the fields 'header$scale' and 'header$origin' are used.


List WAD file contents.

Description

List WAD file contents.

Usage

wad.contents(wad)

Arguments

wad

a wad instance, see read.wad. Alternatively a character string, which will be interpreted as a filepath to a WAD file that should be loaded.

Value

data.frame, info on the files inside the wad.


Extract WAD contents into existing directory.

Description

Extract WAD contents into existing directory.

Usage

wad.extract(
  wad_filepath,
  outdir = getwd(),
  file_ext_mapping = wad_dir.fileext.mapping()
)

Arguments

wad_filepath

character string, path to input WAD file.

outdir

character string, the output directory in which the files should be created. The filenames are derived from the data in the WAD.

file_ext_mapping

named list, with keys corresponding to the type names and values are file extensions, including the dot, to use for them.

Note

One can read extracted textures with read.quake1miptex().


Replace special chars in texture names to turn it into a valid filename.

Description

Replace special chars in texture names to turn it into a valid filename.

Usage

wad.texname.clean(texnames)

Arguments

texnames

character string, texture names from a WAD file. The textures may contain the special characters '*' and '+', which are used to indicate sequences (textures that change on an event, like a pressed button turning from red to green) and other things.

Value

character strings usable as filenames.


Get file extensions for WAD dir entry type strings.

Description

Get file extensions for WAD dir entry type strings.

Usage

wad_dir.fileext.mapping()

Value

named list, which maps wad_dir.types.strings to file extensions. Afaik, there are not standard file extensions for these file types, and I made the ones used here up.

See Also

wad_dir.types.string


Get integers representing WAD dir entry types.

Description

Get integers representing WAD dir entry types.

Usage

wad_dir.types.int()

See Also

wad_dir.types.string


Get strings describing WAD dir entry types.

Description

Get strings describing WAD dir entry types.

Usage

wad_dir.types.string()

See Also

wad_dir.types.int


Export wal instance to JPEG format image file.

Description

Export wal instance to JPEG format image file.

Usage

wal.export.to.jpeg(wal, filepath, apply_palette = wal::pal_q2(), ...)

Arguments

wal

a wal instance, as returned by read.wal

filepath

character string, path to the JPEG file to write, including the file extension.

apply_palette

optional 256 x 3 integer matrix, the palette. Must contain values in range 0..255. Pass NULL if you do not want to apply any palette. The resulting wal object will not have an 'image' entry then.

...

extra parameters passed to jpeg::writeJPEG. Can be used to set JPEG quality.

Examples

## Not run: 
   walf = '~/data/q2_pak0_extracted/textures/e1u2/basic1_7.wal';
   wal = read.wal(walf);
   wal.export.to.jpeg(wal, "~/basic1_7.jpg");

## End(Not run)


Export wal instance to PNG format image file.

Description

Export wal instance to PNG format image file.

Usage

wal.export.to.png(wal, filepath, apply_palette = wal::pal_q2(), ...)

Arguments

wal

a wal instance, as returned by read.wal

filepath

character string, path to the PNG file to write, including the file extension.

apply_palette

optional 256 x 3 integer matrix, the palette. Must contain values in range 0..255. Pass NULL if you do not want to apply any palette. The resulting wal object will not have an 'image' entry then.

...

extra parameters passed to png::writePNG.

Examples

## Not run: 
   walf = '~/data/q2_pak0_extracted/textures/e1u2/basic1_7.wal';
   wal = read.wal(walf);
   wal.export.to.png(wal, "~/basic1_7.png");

## End(Not run)


Generate a WAL structure template.

Description

Generates a WAL instance that can be modified and filled with new data. The template represents a black 32x32 image (if the palette used to display it adhers to the convention that the first color is black). The indices used are 1-based (black is at index 1, not 0).

Usage

wal.template()

Write WAL instance to bitmap file in WAL format.

Description

Write WAL instance to bitmap file in WAL format.

Usage

writeWAL(filepath, wal)

Arguments

filepath

character string, path to the file including extension

wal

a wal instance. Note that 1 will be substracted from the data when it is written, as indices are stored 0-based in the file.

Examples

## Not run: 
   walf = '~/data/q2_pak0_extracted/textures/e1u2/basic1_7.wal';
   wal = read.wal(walf);
   writeWAL(tempfile(fileext = ".wal"), wal);

## End(Not run)