\documentclass[10pt, a4paper, oneside, opensame]{book}

\usepackage[utf8]{inputenc}

\newcommand*{\goldforgeversion}{0.7.0}

\newcommand*{\rulewidth}{0.4pt}

\usepackage[margin=2cm]{geometry}

\usepackage[british]{babel}

\usepackage{array}
\usepackage[T1]{fontenc}
\usepackage{lastpage}
\usepackage{mathptmx}
\usepackage{mdframed}
\usepackage{parskip}
\usepackage{tabularx}
\usepackage{tocbibind}

\usepackage{fancyhdr}
	\pagestyle{fancy}
	\fancypagestyle{plain}{\pagestyle{fancy}}
	\renewcommand*{\headrulewidth}{\rulewidth}
	\renewcommand*{\footrulewidth}{\rulewidth}
	\renewcommand*{\chaptermark}[1]{\markboth{#1}{}}
	\fancyhf{}
	\fancyhead[l]{\small\itshape\bfseries GoldForge Reference}
	\fancyfoot[c]{\small\bfseries \thepage\ / \pageref*{LastPage}}

\usepackage{multicol}
	\setlength{\columnsep}{1cm}

\usepackage{titlesec}
	\renewcommand{\thesection}{\thechapter.\oldstylenums{\arabic{section}}}

	\titleformat{\chapter}{\bfseries\huge}{\thechapter\quad}{0pt}{}
	\titleformat{\section}{\bfseries\large}{\thesection\quad}{0pt}{}

	\titlespacing*{\chapter}{0pt}{1em}{1em}
	\titlespacing*{\section}{0pt}{1em}{1em}

% Apparently must be last.
\usepackage[hidelinks, pdfusetitle]{hyperref}

\renewcommand*{\cleardoublepage}{}

\everymath{\displaystyle}

\title{GoldForge Reference \goldforgeversion}
\author{Gabriel Bjørnager Jensen}

\begin{document}
	\clearpage
		% Do not enumerate the first two pages.
		\pagenumbering{gobble}

		\thispagestyle{empty}

		\begin{center}
		\vspace*{\fill}
			{\huge\bfseries \textsc{GoldForge}}

			{\huge\itshape\bfseries Reference}

			{\large\bfseries v. \goldforgeversion}

			\vspace*{\fill}
			{\small\bfseries\oldstylenums{2025}-\oldstylenums{11}-\oldstylenums{19}}
		\end{center}

	\clearpage
		\thispagestyle{empty}

		\begin{center}
			Copyright \textcopyright\ \oldstylenums{2025} Gabriel Bj{\o}rnager Jensen.
			This manual is licensed under a Creative Commons Attribution-ShareAlike \oldstylenums{4}.\oldstylenums{0} International licence.
			See more at <\url{https://creativecommons.org/licenses/by-sa/4.0/}>.

			The \textsc{GoldForge} library is copyright \textcopyright\ \oldstylenums{2025} Gabriel Bj{\o}rnager Jensen and licensed under the Mozilla Public License, version \oldstylenums{2}.\oldstylenums{0}.
			See more at <\url{https://mozilla.org/MPL/2.0/}>.

			\rule{\linewidth}{\rulewidth}

			DOOM and Quake are registered trade marks of ZeniMax Media Inc. in the E.U., the U.K., and the U.S.A.
			Half-Life and Left 4 Dead are registered trade marks of Valve Corporation in the E.U., the U.K., and the U.S.A.

			\rule{\linewidth}{\rulewidth}
		\end{center}

		This reference uses source code snippets from the following projects.

		\begin{itemize}
			\item DOOM (see <\url{https://github.com/id-Software/DOOM/}>)
			\item Half-Life SDK (see <\url{https://github.com/ValveSoftware/halflife/}>)
			\item Quake (see <\url{https://github.com/id-Software/Quake/}>)
		\end{itemize}

		\begin{center}
			\vspace*{\fill}
			{\small\bfseries This document is intended for printing on A5-class paper.}

			{\small\bfseries :)}
		\end{center}

	\clearpage
		% Enumerate pages from hereonout.
		\pagenumbering{arabic}

		\tableofcontents

	\clearpage
		% Count first chapter alphabetically.
		\renewcommand{\thechapter}{\alph{chapter}}
		\fancyhead[r]{\small\itshape\bfseries \thechapter\quad \leftmark}

		\chapter{Introduction}
				\label{c:introduction}

			\begin{multicols*}{2}
				\section{Brief}
					\label{s:introduction:brief}

					This specification describes the file formats supported by the \textsc{GoldForge} library, a library intended for handling the different file formats used by the id Tech 1 \& 2, GoldSrc, Source, and Source 2 engines -- as well as how they may be used in conjunction with \textsc{GoldForge}.

					Information not strictly pertaining to \textsc{GoldForge} is written agnostically of the file handler.
					Thus, this specification can be used as a reference to write additional software for handling these file formats, and \textsc{GoldForge} can then be seen as a reference implementation.

					\textsc{GoldForge} may be downloaded in source form for free at <\url{https://mandelbrot.dk/bjoernager/goldforge.git}>.

				\section{Data structures}
					\label{s:introduction:data-structures}

					For many data types in this specification, a synopsis is given for the equivalent definition in the original source code (if known).
					As DOOM\textsuperscript{\textregistered} was written in C and initially targeted the IBM PC only (including the x88 core), assume the following data model for C types unless otherwise is noted:

					\begin{tabularx}{\linewidth}{|>{\ttfamily}X|>{\ttfamily}X|}
						\hline
						\multicolumn{1}{|>{\bfseries}l|}{Primitive type} & \multicolumn{1}{>{\bfseries}c|}{Fixed-width type} \\
						\hline
						char           & int8\_t \\
						{}             & {} \\
						signed char    & int8\_t \\
						short          & int16\_t \\
						int            & int32\_t \\
						long           & int32\_t \\
						{}             & {} \\
						unsigned char  & uint8\_t \\
						unsigned short & uint16\_t \\
						unsigned int   & uint32\_t \\
						unsigned long  & uint32\_t \\
						{}             & {} \\
						float          & \_Float32 \\
						double         & \_Float64 \\
						\hline
					\end{tabularx}

					Conversely, ``a byte'' will always refer to an \texttt{8}-bit, unsigned, and unaligned integer.
			\end{multicols*}

	\clearpage
		% Count chapters numerically.
		\renewcommand{\thechapter}{\oldstylenums{\arabic{chapter}}}
		\setcounter{chapter}{0}

		\begin{multicols*}{2}
			\chapter{WAD}
				\label{c:wad}

				\section{Description}
					\label{s:wad:description}

					WAD (\textit{Where's All the Data}) is a package format introduced by DOOM and subsequently succeeded by WAD2 in Quake and Half-Life.
					It was supersceeded as WAD2 in Quake and as WAD3 in Half-Life.

					WAD as a whole was partially replaced by PAK in Quake, by GFC starting with Steam, and finally by VPK starting with Left 4 Dead.

				\section{Synopsis}
					\label{s:wad:synopsis}

\begin{verbatim}
// DOOM/linuxdoom-1.10/w_wad.h

typedef struct
{
    // Should be "IWAD" or "PWAD".
    char        identification[4];
    int         numlumps;
    int         infotableofs;

} wadinfo_t;

typedef struct
{
    int         filepos;
    int         size;
    char        name[8];

} filelump_t;
\end{verbatim}

				\section{File structure}
					\label{s:wad:file-structure}

					The first \texttt{12} bytes of a WAD file denote a \texttt{wadinfo\_t} object that serves as the file header:

					WAD has an unspecified endianness, although little-endian is the most commonly used.
					New software should prefer to use little-endian even on big-endian hardware -- for the sake of portability and compatibility with existing WAD files.

				\section{Header}
					\label{s:wad:header}

					\begin{itemize}
						\item \texttt{identification}, a.k.a. the magic, denotes whether the file is internal or a patch.
						\item \texttt{numlumps} denotes the count of lumps.
						\item \texttt{infotableofs} denotes the offset of the WAD directory.
					\end{itemize}

					The \texttt{identification} field of the header must be a 4-character ASCII string that is either \texttt{IWAD} or \texttt{DAWI} for internal files or \texttt{PWAD} or \texttt{DAWP} for patch files.

					Neither the \texttt{numlumps} or \texttt{infotableofs} fields of the header may be negative.
					\texttt{infotableofs} must point within the bounds of the WAD file, and the value of \texttt{infotableofs + sizeof filelump\_t * numlumps} must itself also be a valid offset or a one-past-the-end offset for the file.

				\section{Directory}
					\label{s:wad:directory}

					The WAD directory is a \texttt{numlumps}-long array of \texttt{filelump\_t} objects, each of which describing a lump in the WAD file:

					\begin{itemize}
						\item \texttt{filepos} denotes the byte index of the lump's data in file.
						\item \texttt{size} denotes the length of the lump's date, in bytes.
						\item \texttt{name} denotes the identifier used for the lump.
					\end{itemize}

					For each directory entry, the \texttt{filepos} and \texttt{size} fields must equivalently be non-zero and represent valid data ranges inside the WAD file.

					The header, directory, and raw lump data may overlap with each other in any combination.
		\end{multicols*}
\end{document}
