diff --git a/src/dehacked.c b/src/dehacked.c index af982662d..345184048 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2890,7 +2890,7 @@ static void readpatch(MYFILE *f, const char *name, UINT16 wad) char *word2; char *tmp; INT32 i = 0, j = 0, value; - texpatch_t patch = {0, 0, UINT16_MAX, UINT16_MAX, 0}; + texpatch_t patch = {0, 0, UINT16_MAX, UINT16_MAX, 0, 255, AST_COPY}; // Jump to the texture this patch belongs to, which, // coincidentally, is always the last one on the buffer cache. diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 840af9c57..f6275631c 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -198,21 +198,6 @@ void HU_LoadGraphics(void) tny_font[i] = (patch_t *)W_CachePatchName(buffer, PU_HUDGFX); } - // cache the level title font for entire game execution - lt_font[0] = (patch_t *)W_CachePatchName("LTFNT039", PU_HUDGFX); /// \note fake start hack - - // Number support - lt_font[9] = (patch_t *)W_CachePatchName("LTFNT048", PU_HUDGFX); - lt_font[10] = (patch_t *)W_CachePatchName("LTFNT049", PU_HUDGFX); - lt_font[11] = (patch_t *)W_CachePatchName("LTFNT050", PU_HUDGFX); - lt_font[12] = (patch_t *)W_CachePatchName("LTFNT051", PU_HUDGFX); - lt_font[13] = (patch_t *)W_CachePatchName("LTFNT052", PU_HUDGFX); - lt_font[14] = (patch_t *)W_CachePatchName("LTFNT053", PU_HUDGFX); - lt_font[15] = (patch_t *)W_CachePatchName("LTFNT054", PU_HUDGFX); - lt_font[16] = (patch_t *)W_CachePatchName("LTFNT055", PU_HUDGFX); - lt_font[17] = (patch_t *)W_CachePatchName("LTFNT056", PU_HUDGFX); - lt_font[18] = (patch_t *)W_CachePatchName("LTFNT057", PU_HUDGFX); - j = LT_FONTSTART; for (i = 0; i < LT_FONTSIZE; i++) { diff --git a/src/r_data.c b/src/r_data.c index cd9ff6273..4df5209a5 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -141,11 +141,14 @@ static INT32 tidcachelen = 0; // R_DrawColumnInCache // Clip and draw a column from a patch into a cached post. // -static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, INT32 originy, INT32 cacheheight) +static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight) { INT32 count, position; UINT8 *source; INT32 topdelta, prevdelta = -1; + INT32 originy = originPatch->originy; + + (void)patchheight; // This parameter is unused while (patch->topdelta != 0xff) { @@ -174,11 +177,16 @@ static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, INT32 orig } } -static inline void R_DrawFlippedColumnInCache(column_t *patch, UINT8 *cache, INT32 originy, INT32 cacheheight, INT32 patchheight) +// +// R_DrawFlippedColumnInCache +// Similar to R_DrawColumnInCache; it draws the column inverted, however. +// +static inline void R_DrawFlippedColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight) { INT32 count, position; UINT8 *source, *dest; INT32 topdelta, prevdelta = -1; + INT32 originy = originPatch->originy; while (patch->topdelta != 0xff) { @@ -212,6 +220,95 @@ static inline void R_DrawFlippedColumnInCache(column_t *patch, UINT8 *cache, INT } } +// +// R_DrawTransColumnInCache +// Draws a translucent column into the cache, applying a half-cooked equation to get a proper translucency value (Needs code in R_GenerateTexture()). +// +static inline void R_DrawTransColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight) +{ + INT32 count, position; + UINT8 *source, *dest; + UINT8 *mytransmap = transtables + ((8*(originPatch->alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT); // The equation's not exact but it works as intended. I'll call it a day for now. + INT32 topdelta, prevdelta = -1; + INT32 originy = originPatch->originy; + + (void)patchheight; // This parameter is unused + + while (patch->topdelta != 0xff) + { + topdelta = patch->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + source = (UINT8 *)patch + 3; + count = patch->length; + position = originy + topdelta; + + if (position < 0) + { + count += position; + source -= position; // start further down the column + position = 0; + } + + if (position + count > cacheheight) + count = cacheheight - position; + + dest = cache + position; + if (count > 0) + { + for (; dest < cache + position + count; source++, dest++) + if (*dest != 0xFF) *dest = *(mytransmap + ((*dest)<<8) + (*source)); + } + + patch = (column_t *)((UINT8 *)patch + patch->length + 4); + } +} + +// +// R_DrawTransColumnInCache +// Similar to the one above except that the column is inverted. +// +static inline void R_DrawTransFlippedColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight) +{ + INT32 count, position; + UINT8 *source, *dest; + UINT8 *mytransmap = transtables + ((8*(originPatch->alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT); // The equation's not exact but it works as intended. I'll call it a day for now. + INT32 topdelta, prevdelta = -1; + INT32 originy = originPatch->originy; + + while (patch->topdelta != 0xff) + { + topdelta = patch->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + topdelta = patchheight-patch->length-topdelta; + source = (UINT8 *)patch + 2 + patch->length; // patch + 3 + (patch->length-1) + count = patch->length; + position = originy + topdelta; + + if (position < 0) + { + count += position; + source += position; // start further UP the column + position = 0; + } + + if (position + count > cacheheight) + count = cacheheight - position; + + dest = cache + position; + if (count > 0) + { + for (; dest < cache + position + count; --source, dest++) + if (*dest != 0xFF) *dest = *(mytransmap + ((*dest)<<8) + (*source)); + } + + patch = (column_t *)((UINT8 *)patch + patch->length + 4); + } +} + // // R_GenerateTexture // @@ -324,6 +421,18 @@ static UINT8 *R_GenerateTexture(size_t texnum) // Composite the columns together. for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) { + static void (*ColumnDrawerPointer)(column_t *, UINT8 *, texpatch_t *, INT32, INT32); // Column drawing function pointer. + if ((patch->style == AST_TRANSLUCENT) && (patch->alpha <= (10*255/11))) // Alpha style set to translucent? Is the alpha small enough for translucency? + { + if (patch->alpha < 255/11) // Is the patch way too translucent? Don't render then. + continue; + ColumnDrawerPointer = (patch->flip & 2) ? R_DrawTransFlippedColumnInCache : R_DrawTransColumnInCache; + } + else + { + ColumnDrawerPointer = (patch->flip & 2) ? R_DrawFlippedColumnInCache : R_DrawColumnInCache; + } + realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); x1 = patch->originx; width = SHORT(realpatch->width); @@ -347,10 +456,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) // generate column ofset lookup colofs[x] = LONG((x * texture->height) + (texture->width*4)); - if (patch->flip & 2) - R_DrawFlippedColumnInCache(patchcol, block + LONG(colofs[x]), patch->originy, texture->height, height); - else - R_DrawColumnInCache(patchcol, block + LONG(colofs[x]), patch->originy, texture->height); + ColumnDrawerPointer(patchcol, block + LONG(colofs[x]), patch, texture->height, height); } } @@ -490,11 +596,11 @@ void R_LoadTextures(void) // Allocate texture column offset table. texturecolumnofs = (void *)((UINT8 *)textures + (numtextures * sizeof(void *))); // Allocate texture referencing cache. - texturecache = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 2)); + texturecache = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 2)); // Allocate texture width mask table. texturewidthmask = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 3)); // Allocate texture height mask table. - textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4)); + textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4)); // Create translation table for global animation. texturetranslation = Z_Malloc((numtextures + 1) * sizeof(*texturetranslation), PU_STATIC, NULL); @@ -588,6 +694,8 @@ static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch) INT16 patchXPos; INT16 patchYPos; UINT8 flip = 0; + UINT8 alpha = 255; + enum patchalphastyle style = AST_COPY; texpatch_t *resultPatch = NULL; lumpnum_t patchLumpNum; @@ -703,7 +811,20 @@ static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch) } while (strcmp(texturesToken,"}")!=0) { - if (stricmp(texturesToken, "FLIPX")==0) + if (stricmp(texturesToken, "ALPHA")==0) + { + Z_Free(texturesToken); + texturesToken = M_GetToken(NULL); + alpha = 255*strtof(texturesToken, NULL); + } + else if (stricmp(texturesToken, "STYLE")==0) + { + Z_Free(texturesToken); + texturesToken = M_GetToken(NULL); + if(stricmp(texturesToken, "TRANSLUCENT")==0) + style = AST_TRANSLUCENT; + } + else if (stricmp(texturesToken, "FLIPX")==0) flip |= 1; else if (stricmp(texturesToken, "FLIPY")==0) flip |= 2; @@ -736,6 +857,8 @@ static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch) resultPatch->lump = patchLumpNum & 65535; resultPatch->wad = patchLumpNum>>16; resultPatch->flip = flip; + resultPatch->alpha = alpha; + resultPatch->style = style; // Clean up a little after ourselves Z_Free(patchName); // Then return it diff --git a/src/r_data.h b/src/r_data.h index bea1cba3b..2d984c1c8 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -21,6 +21,9 @@ #pragma interface #endif +// Possible alpha types for a patch. +enum patchalphastyle {AST_COPY, AST_TRANSLUCENT}; // , AST_ADD, AST_SUBTRACT, AST_REVERSESUBTRACT, AST_MODULATE, AST_OVERLAY}; + // moved here for r_sky.c (texpatch_t is used) // A single patch from a texture definition, @@ -32,6 +35,8 @@ typedef struct INT16 originx, originy; UINT16 wad, lump; UINT8 flip; // 1 = flipx, 2 = flipy, 3 = both + UINT8 alpha; // Translucency value + enum patchalphastyle style; } texpatch_t; // A maptexturedef_t describes a rectangular texture, diff --git a/src/st_stuff.c b/src/st_stuff.c index 72ee20d99..f1d6bc76a 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -67,7 +67,7 @@ static patch_t *sborings; static patch_t *sboover; static patch_t *timeover; static patch_t *stlivex; -static patch_t *rrings; +static patch_t *sboredrings; static patch_t *getall; // Special Stage HUD static patch_t *timeup; // Special Stage HUD static patch_t *hunthoming[6]; @@ -143,7 +143,7 @@ hudinfo_t hudinfo[NUMHUDITEMS] = { 16, 10}, // HUD_SCORE { 128, 10}, // HUD_SCORENUM - { 17, 26}, // HUD_TIME + { 16, 26}, // HUD_TIME { 136, 10}, // HUD_TIMESPLIT { 88, 26}, // HUD_MINUTES { 188, 10}, // HUD_MINUTESSPLIT @@ -251,16 +251,19 @@ void ST_LoadGraphics(void) // but load them in R_AddSkins, that gets called // first anyway // cache the status bar overlay icons (fullscreen mode) - sborings = W_CachePatchName("SBORINGS", PU_HUDGFX); - sboscore = W_CachePatchName("SBOSCORE", PU_HUDGFX); + + // Prefix "STT" is whitelisted (doesn't trigger ISGAMEMODIFIED), btw + sborings = W_CachePatchName("STTRINGS", PU_HUDGFX); + sboredrings = W_CachePatchName("STTRRING", PU_HUDGFX); + sboscore = W_CachePatchName("STTSCORE", PU_HUDGFX); + sbotime = W_CachePatchName("STTTIME", PU_HUDGFX); // Time logo + sbocolon = W_CachePatchName("STTCOLON", PU_HUDGFX); // Colon for time + sboperiod = W_CachePatchName("STTPERIO", PU_HUDGFX); // Period for time centiseconds + sboover = W_CachePatchName("SBOOVER", PU_HUDGFX); timeover = W_CachePatchName("TIMEOVER", PU_HUDGFX); stlivex = W_CachePatchName("STLIVEX", PU_HUDGFX); livesback = W_CachePatchName("STLIVEBK", PU_HUDGFX); - rrings = W_CachePatchName("RRINGS", PU_HUDGFX); - sbotime = W_CachePatchName("SBOTIME", PU_HUDGFX); // Time logo - sbocolon = W_CachePatchName("SBOCOLON", PU_HUDGFX); // Colon for time - sboperiod = W_CachePatchName("SBOPERIO", PU_HUDGFX); // Period for time centiseconds nrec_timer = W_CachePatchName("NGRTIMER", PU_HUDGFX); // Timer for NiGHTS getall = W_CachePatchName("GETALL", PU_HUDGFX); // Special Stage HUD timeup = W_CachePatchName("TIMEUP", PU_HUDGFX); // Special Stage HUD @@ -681,7 +684,7 @@ static inline void ST_drawRings(void) { INT32 ringnum = max(stplyr->rings, 0); - ST_DrawPatchFromHudWS(HUD_RINGS, ((stplyr->rings <= 0 && leveltime/5 & 1) ? rrings : sborings)); + ST_DrawPatchFromHudWS(HUD_RINGS, ((stplyr->rings <= 0 && leveltime/5 & 1) ? sboredrings : sborings)); if (objectplacing) ringnum = op_currentdoomednum; diff --git a/src/w_wad.c b/src/w_wad.c index e4cb93050..ecba4064f 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1215,15 +1215,25 @@ int W_VerifyNMUSlumps(const char *filename) // ENDOOM text and palette lumps lumpchecklist_t NMUSlist[] = { - {"D_", 2}, - {"O_", 2}, - {"DS", 2}, - {"ENDOOM", 6}, - {"PLAYPAL", 7}, - {"COLORMAP", 8}, - {"PAL", 3}, - {"CLM", 3}, - {"TRANS", 5}, + {"D_", 2}, // MIDI music + {"O_", 2}, // Digital music + {"DS", 2}, // Sound effects + + {"ENDOOM", 6}, // ENDOOM text lump + + {"PLAYPAL", 7}, // Palette changes + {"PAL", 3}, // Palette changes + {"COLORMAP", 8}, // Colormap changes + {"CLM", 3}, // Colormap changes + {"TRANS", 5}, // Translucency map changes + + {"LTFNT", 5}, // Level title font changes + {"TTL", 3}, // Act number changes + {"STCFN", 5}, // Console font changes + {"TNYFN", 5}, // Tiny console font changes + {"STT", 3}, // Acceptable HUD changes (Score Time Rings) + {"YB_", 3}, // Intermission graphics, goes with the above + {NULL, 0}, }; return W_VerifyFile(filename, NMUSlist, false);