Here's an old post I made on the subject,
Looking at the source code of linuxdoom again, I can't understand where the 256-width limit for patches comes from, nor why/where there should be a 64K size limit to the entire patch.
The patch_t header uses 16-bit shorts for width/height/offset information, so at worst those are -32K/+32K. The column offset table itself is composed of 4-byte integers, and is typically read this way:
so there's nothing forbidding you from having up to 2^31-1 columns in a patch (and even negative offsets), or pointing in the "middle" of previously used columns and do partial redraws, if your compression tool is "smart" enough to detect and do that.
column = (column_t *)((byte *)patch + LONG(patch->columnofs[col]));
Speaking of such a tool, it should work more or less like a gzip/tar algorithm, by creating a "vocabulary" of columns as it compresses.
Edit: it seems that the the 64K limit for column offsets is not inherent in the patch_t format itself, but in the R_GenerateComposite method:
and before that, to the texturecolumnsofs array:
void R_GenerateComposite (int texnum)
unsigned short* colofs;
This affects both masked and unmasked texture, as the texturecolumnofs table is used for drawing both.
unsigned short** texturecolumnofs;
Other than saving memory and bandwidth, I can't think of any reason for them to be 16-bit in memory, when they are 32-bit on disk. If source ports change just this aspect, the 64K per-patch limit should be a non-issue.
The 256-pixel width limit mentioned by the wiki however must probably be an overgeneralization. I think skies are divided into 4 parts simply because it's a nice, power-of-2 number. Perhaps each part could be made 384 or 412 pixels wide each before hitting the 64K limit. After all, even in the case of the masked wall the part of the patch that renders correctly is longer than 256 pixels. There's still a 127 pixel height limitation per columnn, but that's another pair of socks (e.g. DeePSea tall patches).
The above being said...since each column offset is 4 bytes on disk, you can fit at most 16000 of them or so in a patch_t, thus putting the practical width limit near there (of course, you'll have to be super-economical with actual column data).
Last edited by Maes on Apr 30 2013 at 12:18