// // R_GenerateComposite // Using the texture definition, // the composite texture is created from the patches, // and each column is cached. // void R_GenerateComposite (int texnum) { byte* block; texture_t* texture; texpatch_t* patch; patch_t* realpatch; int x; int x1; int x2; int i; postColumn_t* patchcol; short* collump; unsigned short* colofs; texture = ::g->s_textures[texnum]; block = (byte*)DoomLib::Z_Malloc (::g->s_texturecompositesize[texnum], PU_CACHE_SHARED, &::g->s_texturecomposite[texnum]); collump = ::g->s_texturecolumnlump[texnum]; colofs = ::g->s_texturecolumnofs[texnum]; // Composite the columns together. patch = texture->patches; for (i=0 , patch = texture->patches; i<texture->patchcount; i++, patch++) { realpatch = (patch_t*)W_CacheLumpNum (patch->patch, PU_CACHE_SHARED); x1 = patch->originx; x2 = x1 + SHORT(realpatch->width); if (x1<0) x = 0; else x = x1; if (x2 > texture->width) x2 = texture->width; for ( ; x<x2 ; x++) { // Column does not have multiple patches? if (collump[x] >= 0) continue; patchcol = (postColumn_t *)((byte *)realpatch + LONG(realpatch->columnofs[x-x1])); R_DrawColumnInCache (patchcol, block + colofs[x], patch->originy, texture->height); } } }
// // R_GenerateComposite // Using the texture definition, // the composite texture is created from the patches, // and each column is cached. // void R_GenerateComposite (int texnum) { texture_t* texture; texpatch_t* patch; patch_t* realpatch; int x; int x1; int x2; int i; column_t* patchcol; short* collump; unsigned short* colofs; texture = textures[texnum]; texturecomposite[texnum] = (unsigned char*)malloc (texturecompositesize[texnum]); collump = texturecolumnlump[texnum]; colofs = texturecolumnofs[texnum]; // Composite the columns together. patch = texture->patches; for (i=0 , patch = texture->patches; i<texture->patchcount; i++, patch++) { realpatch = (patch_t*)WadManager::getLump (patch->patch); x1 = patch->originx; x2 = x1 + realpatch->width; if (x1<0) x = 0; else x = x1; if (x2 > texture->width) x2 = texture->width; for ( ; x<x2 ; x++) { // Column does not have multiple patches? if (collump[x] >= 0) continue; patchcol = (column_t *)((unsigned char *)realpatch + realpatch->columnofs[x-x1]); R_DrawColumnInCache (patchcol, texturecomposite[texnum] + colofs[x], patch->originy, texture->height); } } }
/* =================== = = R_GenerateComposite = =================== */ void R_GenerateComposite (int texnum) { byte *block; texture_t *texture; texpatch_t *patch; patch_t *realpatch; int x, x1, x2; int i; column_t *patchcol; short *collump; unsigned short *colofs; texture = textures[texnum]; block = Z_Malloc (texturecompositesize[texnum], PU_STATIC, &texturecomposite[texnum]); collump = texturecolumnlump[texnum]; colofs = texturecolumnofs[texnum]; // // composite the columns together // patch = texture->patches; for (i=0 , patch = texture->patches; i<texture->patchcount ; i++, patch++) { realpatch = W_CacheLumpNum (patch->patch, PU_CACHE); x1 = patch->originx; x2 = x1 + SHORT(realpatch->width); if (x1<0) x = 0; else x = x1; if (x2 > texture->width) x2 = texture->width; for ( ; x<x2 ; x++) { if (collump[x] >= 0) continue; // column does not have multiple patches patchcol = (column_t *)((byte *)realpatch + LONG(realpatch->columnofs[x-x1])); R_DrawColumnInCache (patchcol, block + colofs[x], patch->originy, texture->height); } } // now that the texture has been built, it is purgable Z_ChangeTag (block, PU_CACHE);
void R_GenerateComposite (int texnum) { byte *block = (byte *)Z_Malloc (texturecompositesize[texnum], PU_STATIC, (void **) &texturecomposite[texnum]); texture_t *texture = textures[texnum]; // Composite the columns together. texpatch_t *texpatch = texture->patches; short *collump = texturecolumnlump[texnum]; // killough 4/9/98: marks to identify transparent regions in merged textures byte *marks = new byte[texture->width * texture->height]; memset(marks, 0, texture->width * texture->height); for (int i = texture->patchcount; --i >=0; texpatch++) { patch_t *patch = W_CachePatch(texpatch->patch); int x1 = texpatch->originx, x2 = x1 + patch->width(); const int *cofs = patch->columnofs-x1; if (x1<0) x1 = 0; if (x2 > texture->width) x2 = texture->width; for (; x1 < x2 ; x1++) { if (collump[x1] == -1) // Column has multiple patches? { // killough 1/25/98, 4/9/98: Fix medusa bug. tallpost_t *srcpost = (tallpost_t*)((byte*)patch + LELONG(cofs[x1])); tallpost_t *destpost = (tallpost_t*)(block + texturecolumnofs[texnum][x1]); R_DrawColumnInCache(srcpost, destpost->data(), texpatch->originy, texture->height, marks + x1 * texture->height); } } } // killough 4/9/98: Next, convert multipatched columns into true columns, // to fix Medusa bug while still allowing for transparent regions. byte *tmpdata = new byte[texture->height]; // temporary post data for (int i = 0; i < texture->width; i++) { if (collump[i] != -1) // process only multipatched columns continue; tallpost_t *post = (tallpost_t *)(block + texturecolumnofs[texnum][i]); const byte *mark = marks + i * texture->height; int j = 0; // save column in temporary so we can shuffle it around memcpy(tmpdata, post->data(), texture->height); // reconstruct the column by scanning transparency marks while (true) { while (j < texture->height && !mark[j]) // skip transparent pixels j++; if (j >= texture->height) // if at end of column { post->writeend(); // end-of-column marker break; } post->topdelta = j; // starting offset of post // count opaque pixels for (post->length = 0; j < texture->height && mark[j]; j++) post->length++; // copy opaque pixels from the temporary back into the column memcpy(post->data(), tmpdata + post->topdelta, post->length); post = post->next(); } } delete [] marks; delete [] tmpdata; // Now that the texture has been built in column cache, // it is purgable from zone memory. Z_ChangeTag(block, PU_CACHE); }
void R_GenerateComposite (int texnum) { byte *block = (byte *)Z_Malloc (texturecompositesize[texnum], PU_STATIC, (void **) &texturecomposite[texnum]); texture_t *texture = textures[texnum]; // Composite the columns together. texpatch_t *patch = texture->patches; short *collump = texturecolumnlump[texnum]; unsigned *colofs = texturecolumnofs[texnum]; // killough 4/9/98: make 32-bit int i = texture->patchcount; // killough 4/9/98: marks to identify transparent regions in merged textures byte *marks = (byte *)Calloc (texture->width, texture->height), *source; for (; --i >=0; patch++) { patch_t *realpatch = W_CachePatch (patch->patch); int x1 = patch->originx, x2 = x1 + realpatch->width(); const int *cofs = realpatch->columnofs-x1; if (x1<0) x1 = 0; if (x2 > texture->width) x2 = texture->width; for (; x1<x2 ; x1++) if (collump[x1] == -1) // Column has multiple patches? // killough 1/25/98, 4/9/98: Fix medusa bug. R_DrawColumnInCache((column_t*)((byte*)realpatch+LONG(cofs[x1])), block+colofs[x1],patch->originy,texture->height, marks + x1 * texture->height); } // killough 4/9/98: Next, convert multipatched columns into true columns, // to fix Medusa bug while still allowing for transparent regions. source = (byte *)Malloc (texture->height); // temporary column for (i=0; i < texture->width; i++) if (collump[i] == -1) // process only multipatched columns { column_t *col = (column_t *)(block + colofs[i] - 3); // cached column const byte *mark = marks + i * texture->height; int j = 0; // save column in temporary so we can shuffle it around memcpy(source, (byte *) col + 3, texture->height); for (;;) // reconstruct the column by scanning transparency marks { while (j < texture->height && !mark[j]) // skip transparent cells j++; if (j >= texture->height) // if at end of column { col->topdelta = 255; // end-of-column marker break; } col->topdelta = j; // starting offset of post for (col->length=0; j < texture->height && mark[j]; j++) col->length++; // count opaque cells // copy opaque cells from the temporary back into the column memcpy((byte *) col + 3, source + col->topdelta, col->length); col = (column_t *)((byte *) col + col->length + 4); // next post } } M_Free(source); // free temporary column M_Free(marks); // free transparency marks // Now that the texture has been built in column cache, // it is purgable from zone memory. Z_ChangeTag(block, PU_CACHE); }
// // R_GenerateComposite // Using the texture definition, // the composite texture is created from the patches, // and each column is cached. // // Rewritten by Lee Killough for performance and to fix Medusa bug // static void R_GenerateComposite(int texnum) { byte *block = Z_Malloc(texturecompositesize[texnum], PU_STATIC, (void **)&texturecomposite[texnum]); texture_t *texture = textures[texnum]; // Composite the columns together. texpatch_t *patch = texture->patches; short *collump = texturecolumnlump[texnum]; unsigned int *colofs = texturecolumnofs[texnum]; int i = texture->patchcount; // killough 4/9/98: marks to identify transparent regions in merged textures byte *marks = calloc(texture->width, texture->height), *source; boolean tekwall1 = (texnum == R_CheckTextureNumForName("TEKWALL1")); for (; --i >= 0; patch++) { patch_t *realpatch = W_CacheLumpNum(patch->patch, PU_CACHE); int x1 = MAX(0, patch->originx); int x2 = MIN(x1 + SHORT(realpatch->width), texture->width); const int *cofs = realpatch->columnofs - x1; for (; x1 < x2 ; x1++) if (collump[x1] == -1) // Column has multiple patches? // killough 1/25/98, 4/9/98: Fix medusa bug. R_DrawColumnInCache((column_t *)((byte *)realpatch + LONG(cofs[x1])), block + colofs[x1], patch->originy, texture->height, marks + x1 * texture->height, tekwall1); } // killough 4/9/98: Next, convert multipatched columns into true columns, // to fix Medusa bug while still allowing for transparent regions. source = (byte *)malloc(texture->height); // temporary column for (i = 0; i < texture->width; i++) if (collump[i] == -1) // process only multipatched columns { column_t *col = (column_t *)(block + colofs[i] - 3); // cached column const byte *mark = marks + i * texture->height; int j = 0; // save column in temporary so we can shuffle it around memcpy(source, (byte *)col + 3, texture->height); for (;;) // reconstruct the column by scanning transparency marks { unsigned int len; // killough 12/98 while (j < texture->height && !mark[j]) // skip transparent cells j++; if (j >= texture->height) // if at end of column { col->topdelta = -1; // end-of-column marker break; } col->topdelta = j; // starting offset of post // killough 12/98: // Use 32-bit len counter, to support tall 1s multipatched textures for (len = 0; j < texture->height && mark[j]; j++) len++; // count opaque cells col->length = len; // killough 12/98: intentionally truncate length // copy opaque cells from the temporary back into the column memcpy((byte *)col + 3, source + col->topdelta, len); col = (column_t *)((byte *)col + len + 4); // next post } } free(source); // free temporary column free(marks); // free transparency marks // Now that the texture has been built in column cache, // it is purgable from zone memory. Z_ChangeTag(block, PU_CACHE); }
// // R_GenerateTexture // // Allocate space for full size texture, either single patch or 'composite' // Build the full textures from patches. // The texture caching system is a little more hungry of memory, but has // been simplified for the sake of highcolor, dynamic ligthing, & speed. // // This is not optimised, but it's supposed to be executed only once // per level, when enough memory is available. // static UINT8 *R_GenerateTexture(size_t texnum) { UINT8 *block; UINT8 *blocktex; texture_t *texture; texpatch_t *patch; patch_t *realpatch; int x, x1, x2, i; size_t blocksize; column_t *patchcol; UINT32 *colofs; I_Assert(texnum <= (size_t)numtextures); texture = textures[texnum]; I_Assert(texture != NULL); // allocate texture column offset lookup // single-patch textures can have holes in them and may be used on // 2sided lines so they need to be kept in 'packed' format // BUT this is wrong for skies and walls with over 255 pixels, // so check if there's holes and if not strip the posts. if (texture->patchcount == 1) { boolean holey = false; patch = texture->patches; realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); // Check the patch for holes. if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height)) holey = true; colofs = (UINT32 *)realpatch->columnofs; for (x = 0; x < texture->width && !holey; x++) { column_t *col = (column_t *)((UINT8 *)realpatch + LONG(colofs[x])); INT32 topdelta, prevdelta = -1, y = 0; while (col->topdelta != 0xff) { topdelta = col->topdelta; if (topdelta <= prevdelta) topdelta += prevdelta; prevdelta = topdelta; if (topdelta > y) break; y = topdelta + col->length + 1; col = (column_t *)((UINT8 *)col + col->length + 4); } if (y < texture->height) holey = true; // this texture is HOLEy! D: } // If the patch uses transparency, we have to save it this way. if (holey) { texture->holes = true; blocksize = W_LumpLengthPwad(patch->wad, patch->lump); block = Z_Calloc(blocksize, PU_STATIC, // will change tag at end of this function &texturecache[texnum]); M_Memcpy(block, realpatch, blocksize); texturememory += blocksize; // use the patch's column lookup colofs = (UINT32 *)(void *)(block + 8); texturecolumnofs[texnum] = colofs; blocktex = block; for (x = 0; x < texture->width; x++) colofs[x] = LONG(LONG(colofs[x]) + 3); goto done; } // Otherwise, do multipatch format. } // multi-patch textures (or 'composite') texture->holes = false; blocksize = (texture->width * 4) + (texture->width * texture->height); texturememory += blocksize; block = Z_Malloc(blocksize+1, PU_STATIC, &texturecache[texnum]); memset(block, 0xF7, blocksize+1); // Transparency hack // columns lookup table colofs = (UINT32 *)(void *)block; texturecolumnofs[texnum] = colofs; // texture data after the lookup table blocktex = block + (texture->width*4); // Composite the columns together. for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) { realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); x1 = patch->originx; x2 = x1 + SHORT(realpatch->width); if (x1 < 0) x = 0; else x = x1; if (x2 > texture->width) x2 = texture->width; for (; x < x2; x++) { patchcol = (column_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[x-x1])); // generate column ofset lookup colofs[x] = LONG((x * texture->height) + (texture->width*4)); R_DrawColumnInCache(patchcol, block + LONG(colofs[x]), patch->originy, texture->height); } } done: // Now that the texture has been built in column cache, it is purgable from zone memory. Z_ChangeTag(block, PU_CACHE); return blocktex; }