static int WI_DrawName (const char *str, int x, int y) { int lump; patch_t *p = NULL; char charname[9]; while (*str) { sprintf (charname, "FONTB%02u", toupper(*str) - 32); lump = W_CheckNumForName (charname); if (lump != -1) { p = W_CachePatch (lump); FB->DrawPatchClean (p, x, y); x += p->width() - 1; } else { x += 12; } str++; } p = W_CachePatch ("FONTB39"); return (5*(p->height()-p->topoffset()))/4; }
// // Draw border for the savegame description // [RH] Width of the border is variable // void M_DrawSaveLoadBorder (int x, int y, int len) { int i; screen->DrawPatchClean (W_CachePatch ("M_LSLEFT"), x-8, y+7); for (i = 0; i < len; i++) { screen->DrawPatchClean (W_CachePatch ("M_LSCNTR"), x, y+7); x += 8; } screen->DrawPatchClean (W_CachePatch ("M_LSRGHT"), x, y+7); }
void I_BeginRead(void) { // NOTE(jsd): This is called before V_Palette is set causing crash in 32bpp mode. // [SL] Check that V_Palette has been properly initalized to work around this if (r_loadicon && V_Palette.isValid()) { patch_t *diskpatch = W_CachePatch("STDISK"); if (!screen || !diskpatch || in_endoom) return; screen->Lock(); int scale = MIN(CleanXfac, CleanYfac); int w = diskpatch->width() * scale; int h = diskpatch->height() * scale; // offset x and y for the lower right corner of the screen int ofsx = screen->width - w + (scale * diskpatch->leftoffset()); int ofsy = screen->height - h + (scale * diskpatch->topoffset()); screen->DrawPatchStretched(diskpatch, ofsx, ofsy, w, h); screen->Unlock(); } }
// // M_Options // void M_DrawOptions(void) { if (gameinfo.gametype & GAME_Heretic) screen->DrawTextLargeClean (0, 108, 15, "OPTIONS"); else screen->DrawPatchClean (W_CachePatch("M_OPTTTL"), 108, 15); }
void M_DrawHereticMainMenu (void) { int frame; frame = (MenuTime / 3) % 18; screen->DrawPatchIndirect (W_CachePatch("M_HTIC"), 88, 0); screen->DrawPatchIndirect ((patch_t *)W_CacheLumpNum(SkullBaseLump + (17 - frame), PU_CACHE), 40, 10); screen->DrawPatchIndirect ((patch_t *)W_CacheLumpNum(SkullBaseLump + frame, PU_CACHE), 232, 10); }
// // Draw border for the savegame description // [RH] Width of the border is variable // void M_DrawSaveLoadBorder (int x, int y, int len) { int i; if (gameinfo.gametype & GAME_Heretic) screen->DrawPatchClean(W_CachePatch("M_FSLOT"), x-8, y+7); else { screen->DrawPatchClean (W_CachePatch ("M_LSLEFT"), x-8, y+7); for (i = 0; i < len; i++) { screen->DrawPatchClean (W_CachePatch ("M_LSCNTR"), x, y+7); x += 8; } screen->DrawPatchClean (W_CachePatch ("M_LSRGHT"), x, y+7); } }
// // M_LoadGame & Cie. // void M_DrawLoad (void) { int i; screen->DrawPatchClean ((patch_t *)W_CachePatch("M_LOADG"), 72, 28); for (i = 0; i < load_end; i++) { M_DrawSaveLoadBorder (LoadDef.x, LoadDef.y+LINEHEIGHT*i, 24); screen->DrawTextCleanMove (CR_RED, LoadDef.x, LoadDef.y+LINEHEIGHT*i, savegamestrings[i]); } }
// Convert the CONCHARS patch into the internal format used by // the console font drawer. void V_InitConChars (byte transcolor) { // Load the CONCHARS lump and convert it from patch_t format // to a raw linear byte buffer with a background color of 'transcolor' DCanvas* temp_screen = I_AllocateScreen(128, 128, 8); patch_t* chars_patch = W_CachePatch("CONCHARS"); temp_screen->Lock(); // fill with color 'transcolor' for (int y = 0; y < 128; y++) memset(temp_screen->buffer + temp_screen->pitch * y, transcolor, 128); // paste the patch into the linear byte bufer temp_screen->DrawPatch(chars_patch, 0, 0); ConChars = new byte[256*8*8*2]; byte* dest = ConChars; for (int y = 0; y < 16; y++) { for (int x = 0; x < 16; x++) { const byte* source = temp_screen->buffer + x * 8 + (y * 8 * temp_screen->pitch); for (int z = 0; z < 8; z++) { for (int a = 0; a < 8; a++) { byte val = source[a]; if (val == transcolor) { dest[a] = 0x00; dest[a + 8] = 0xff; } else { dest[a] = val; dest[a + 8] = 0x00; } } dest += 16; source += temp_screen->pitch; } } } temp_screen->Unlock(); I_FreeScreen(temp_screen); }
// // Read This Menus - shareware third page. // void M_DrawReadThis3 (void) { if (gameinfo.flags & GI_PAGESARERAW) { readpage->Lock (); readpage->DrawBlock (0, 0, pwidth, pheight, (byte *)W_CachePatch (gameinfo.info.infoPage[2])); readpage->Unlock (); readpage->Blit (0, 0, readpage->width, readpage->height, screen, 0, 0, screen->width, screen->height); } else screen->DrawPatchIndirect ((patch_t *)W_CacheLumpName (gameinfo.info.infoPage[2], PU_CACHE), 0, 0); }
// // R_GetTextureColumn // tallpost_t* R_GetTextureColumn(int texnum, int colnum) { colnum &= texturewidthmask[texnum]; int lump = texturecolumnlump[texnum][colnum]; int ofs = texturecolumnofs[texnum][colnum]; if (lump > 0) return (tallpost_t*)((byte *)W_CachePatch(lump, PU_CACHE) + ofs); if (!texturecomposite[texnum]) R_GenerateComposite(texnum); return (tallpost_t*)(texturecomposite[texnum] + ofs); }
// // M_SaveGame & Cie. // [ML] 7 Sept 08: Bringing game saving/loading in from // zdoom 1.22 source, see MAINTAINERS // void M_DrawSave(void) { int i; screen->DrawPatchClean ((patch_t *)W_CachePatch("M_SAVEG"), 72, 28); for (i = 0; i < load_end; i++) { M_DrawSaveLoadBorder(LoadDef.x,LoadDef.y+LINEHEIGHT*i,24); screen->DrawTextCleanMove (CR_RED, LoadDef.x, LoadDef.y+LINEHEIGHT*i, savegamestrings[i]); } if (genStringEnter) { i = V_StringWidth(savegamestrings[saveSlot]); screen->DrawTextCleanMove (CR_RED, LoadDef.x + i, LoadDef.y+LINEHEIGHT*saveSlot, "_"); } }
// // R_GetColumn // tallpost_t* R_GetColumn(int tex, int col) { int lump; int ofs; col &= texturewidthmask[tex]; lump = texturecolumnlump[tex][col]; ofs = texturecolumnofs[tex][col]; dc_textureheight = textureheight[tex]; if (lump > 0) return (tallpost_t*)((byte *)W_CachePatch(lump,PU_CACHE) + ofs); if (!texturecomposite[tex]) R_GenerateComposite (tex); return (tallpost_t*)(texturecomposite[tex] + ofs); }
void I_BeginRead(void) { patch_t *diskpatch = W_CachePatch("STDISK"); if (!screen || !diskpatch || in_endoom) return; screen->Lock(); int scale = MIN(CleanXfac, CleanYfac); int w = diskpatch->width() * scale; int h = diskpatch->height() * scale; // offset x and y for the lower right corner of the screen int ofsx = screen->width - w + (scale * diskpatch->leftoffset()); int ofsy = screen->height - h + (scale * diskpatch->topoffset()); screen->DrawPatchStretched(diskpatch, ofsx, ofsy, w, h); screen->Unlock(); }
// // I_BlitLoadingIcon // // Takes care of the actual drawing of the loading icon. // static void I_BlitLoadingIcon() { const patch_t* diskpatch = W_CachePatch("STDISK"); IWindowSurface* surface = I_GetPrimarySurface(); surface->lock(); int bpp = surface->getBitsPerPixel(); int scale = std::min(CleanXfac, CleanYfac); int w = diskpatch->width() * scale; int h = diskpatch->height() * scale; int x = surface->getWidth() - w; int y = surface->getHeight() - h; // offset x and y for the lower right corner of the screen int ofsx = x + (scale * diskpatch->leftoffset()); int ofsy = y + (scale * diskpatch->topoffset()); // save the area where the icon will be drawn to an off-screen surface // so that it can be restored after the frame is blitted if (!loading_icon_background_surface || loading_icon_background_surface->getWidth() != w || loading_icon_background_surface->getHeight() != h || loading_icon_background_surface->getBitsPerPixel() != bpp) { if (loading_icon_background_surface) I_FreeSurface(loading_icon_background_surface); loading_icon_background_surface = I_AllocateSurface(w, h, bpp); } loading_icon_background_surface->lock(); loading_icon_background_surface->blit(surface, x, y, w, h, 0, 0, w, h); surface->getDefaultCanvas()->DrawPatchStretched(diskpatch, ofsx, ofsy, w, h); loading_icon_background_surface->unlock(); surface->unlock(); }
// // Read This Menus // Had a "quick hack to fix romero bug" // void M_DrawReadThis1 (void) { if (gameinfo.flags & GI_PAGESARERAW) { if (readpage && (readpage->width != pwidth || readpage->height != pheight)) { I_FreeScreen(readpage); readpage = NULL; } if (readpage == NULL) readpage = I_AllocateScreen(pwidth,pheight,screen->bits); readpage->Lock (); readpage->DrawBlock (0, 0, pwidth, pheight, (byte *)W_CachePatch (gameinfo.info.infoPage[0])); readpage->Unlock (); readpage->Blit (0, 0, readpage->width, readpage->height, screen, 0, 0, screen->width, screen->height); } else screen->DrawPatchIndirect ((patch_t *)W_CacheLumpName (gameinfo.info.infoPage[0], PU_CACHE), 0, 0); }
void R_CacheSprite (spritedef_t *sprite) { int i, r; patch_t *patch; DPrintf ("cache sprite %s\n", sprite - sprites < NUMSPRITES ? sprnames[sprite - sprites] : ""); for (i = 0; i < sprite->numframes; i++) { for (r = 0; r < 8; r++) { if (sprite->spriteframes[i].width[r] == SPRITE_NEEDS_INFO) { if (sprite->spriteframes[i].lump[r] == -1) I_Error ("Sprite %d, rotation %d has no lump", i, r); patch = W_CachePatch (sprite->spriteframes[i].lump[r]); sprite->spriteframes[i].width[r] = patch->width()<<FRACBITS; sprite->spriteframes[i].offset[r] = patch->leftoffset()<<FRACBITS; sprite->spriteframes[i].topoffset[r] = patch->topoffset()<<FRACBITS; } } } }
static int WI_CalcWidth (const char *str) { int w = 0; int lump; patch_t *p; char charname[9]; if (!str) return 0; while (*str) { sprintf (charname, "FONTB%02u", toupper(*str) - 32); lump = W_CheckNumForName (charname); if (lump != -1) { p = W_CachePatch (lump); w += p->width() - 1; } else { w += 12; } str++; } return w; }
// // M_Options // void M_DrawOptions(void) { screen->DrawPatchClean (W_CachePatch("M_OPTTTL"), 108, 15); }
void M_DrawNewGame(void) { screen->DrawPatchClean ((patch_t *)W_CachePatch("M_NEWG"), 96, 14); screen->DrawPatchClean ((patch_t *)W_CachePatch("M_SKILL"), 54, 38); }
// // Read This Menus - shareware third page. // void M_DrawReadThis3 (void) { screen->DrawPatchIndirect ((patch_t *)W_CachePatch(gameinfo.info.infoPage[2]), 0, 0); }
void M_DrawEpisode(void) { screen->DrawPatchClean ((patch_t *)W_CachePatch("M_EPISOD"), 54, 38); }
patch_t* W_CachePatch ( const char* name, int tag ) { return W_CachePatch(W_GetNumForName(name), tag); // denis - todo - would be good to replace non-existant patches with a default '404' patch }
// // R_GetPatchColumn // tallpost_t* R_GetPatchColumn(int lumpnum, int colnum) { patch_t* patch = W_CachePatch(lumpnum, PU_CACHE); return (tallpost_t*)((byte*)patch + LELONG(patch->columnofs[colnum])); }
static void R_GenerateLookup(int texnum, int *const errors) { const texture_t *texture = textures[texnum]; // Composited texture not created yet. short *collump = texturecolumnlump[texnum]; // killough 4/9/98: keep count of posts in addition to patches. // Part of fix for medusa bug for multipatched 2s normals. unsigned short *patchcount = new unsigned short[texture->width]; unsigned short *postcount = new unsigned short[texture->width]; memset(patchcount, 0, sizeof(unsigned short) * texture->width); memset(postcount, 0, sizeof(unsigned short) * texture->width); const texpatch_t *texpatch = texture->patches; for (int i = 0; i < texture->patchcount; i++) { const int patchnum = texpatch->patch; const patch_t *patch = W_CachePatch(patchnum); int x1 = texpatch++->originx, x2 = x1 + patch->width(), x = x1; const int *cofs = patch->columnofs-x1; if (x2 > texture->width) x2 = texture->width; if (x1 < 0) x = 0; for (; x < x2; x++) { // killough 4/9/98: keep a count of the number of posts in column, // to fix Medusa bug while allowing for transparent multipatches. const tallpost_t *post = (tallpost_t*)((byte*)patch + LELONG(cofs[x])); // NOTE: this offset will be rewritten later if a composite is generated // for this texture (eg, there's more than one patch) texturecolumnofs[texnum][x] = (byte *)post - (byte *)patch; patchcount[x]++; collump[x] = patchnum; while (!post->end()) { postcount[x]++; post = post->next(); } } } // Now count the number of columns that are covered by more than one patch. // Fill in the lump / offset, so columns with only a single patch are all done. texturecomposite[texnum] = 0; int csize = 0; // [RH] Always create a composite texture for multipatch textures // or tall textures in order to keep things simpler. bool needcomposite = (texture->patchcount > 1 || texture->height > 254); // [SL] Check for columns without patches. // If a texture has columns without patches, generate a composite for // the texture, which will create empty posts and prevent crashes. for (int x = 0; x < texture->width && !needcomposite; x++) { if (patchcount[x] == 0) needcomposite = true; } if (needcomposite) { int x = texture->width; while (--x >= 0) { // killough 1/25/98, 4/9/98: // // Fix Medusa bug, by adding room for column header // and trailer bytes for each post in merged column. // For now, just allocate conservatively 4 bytes // per post per patch per column, since we don't // yet know how many posts the merged column will // require, and it's bounded above by this limit. collump[x] = -1; // mark lump as multipatched texturecolumnofs[texnum][x] = csize; // 4 header bytes per post + column height + 2 byte terminator csize += 4 * postcount[x] + 2 + texture->height; } } texturecompositesize[texnum] = csize; delete [] patchcount; delete [] postcount; }
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); }
static void R_GenerateLookup(int texnum, int *const errors) { const texture_t *texture = textures[texnum]; const bool nottall = texture->height < 256; // Composited texture not created yet. short *collump = texturecolumnlump[texnum]; unsigned *colofs = texturecolumnofs[texnum]; // killough 4/9/98: make 32-bit // killough 4/9/98: keep count of posts in addition to patches. // Part of fix for medusa bug for multipatched 2s normals. struct cs { unsigned short patches, posts; } *count = (cs *)Calloc (sizeof *count, texture->width); { int i = texture->patchcount; const texpatch_t *patch = texture->patches; while (--i >= 0) { int pat = patch->patch; const patch_t *realpatch = W_CachePatch (pat); int x1 = patch++->originx, x2 = x1 + realpatch->width(), x = x1; const int *cofs = realpatch->columnofs-x1; if (x2 > texture->width) x2 = texture->width; if (x1 < 0) x = 0; for ( ; x<x2 ; x++) { // killough 4/9/98: keep a count of the number of posts in column, // to fix Medusa bug while allowing for transparent multipatches. const column_t *col = (column_t*)((byte*)realpatch+LONG(cofs[x])); for (;col->topdelta != 0xff; count[x].posts++) { col = (column_t *)((byte *) col + (col->length || nottall ? col->length : 256) + 4); // denis - prevent a crash when col goes out of range unsigned int n = (const byte *)col - (const byte *)realpatch; if(n >= W_LumpLength(pat)) { if(texture->height < 256) // bigger textures are assumed to have a single post anyway Printf(PRINT_HIGH, "R_GenerateLookup warning: post truncated for texture %d\n", texnum); count[x].posts--; break; } } count[x].patches++; collump[x] = pat; colofs[x] = LONG(cofs[x])+3; } } } // Now count the number of columns // that are covered by more than one patch. // Fill in the lump / offset, so columns // with only a single patch are all done. texturecomposite[texnum] = 0; { int x = texture->width; int height = texture->height; int csize = 0; while (--x >= 0) { if (!count[x].patches) // killough 4/9/98 { Printf (PRINT_HIGH, "R_GenerateLookup: Column %d is without a patch in texture %.8s\n", x, texture->name); ++*errors; // denis - todo - commented this line before to allow freedoom 0.4.0 doom2.wad to work } if (count[x].patches > 1) // killough 4/9/98 { // killough 1/25/98, 4/9/98: // // Fix Medusa bug, by adding room for column header // and trailer bytes for each post in merged column. // For now, just allocate conservatively 4 bytes // per post per patch per column, since we don't // yet know how many posts the merged column will // require, and it's bounded above by this limit. collump[x] = -1; // mark lump as multipatched colofs[x] = csize + 3; // three header bytes in a column csize += 4*count[x].posts+1; // 1 stop byte plus 4 bytes per post } csize += height; // height bytes of texture data } texturecompositesize[texnum] = csize; } M_Free(count); // killough 4/9/98 }
// Convert the CONCHARS patch into the internal format used by // the console font drawer. void V_InitConChars (byte transcolor) { byte *d, *s, v, *src; patch_t *chars; int x, y, z, a; DCanvas *scrn = I_AllocateScreen(128, 128, 8); DCanvas &temp = *scrn; chars = W_CachePatch ("CONCHARS"); temp.Lock (); { DWORD *scrn, fill; fill = (transcolor << 24) | (transcolor << 16) | (transcolor << 8) | transcolor; for (y = 0; y < 128; y++) { scrn = (DWORD *)(temp.buffer + temp.pitch * y); for (x = 0; x < 128/4; x++) { *scrn++ = fill; } } temp.DrawPatch (chars, 0, 0); } src = temp.buffer; if ( (ConChars = new byte[256*8*8*2]) ) { d = ConChars; for (y = 0; y < 16; y++) { for (x = 0; x < 16; x++) { s = src + x * 8 + (y * 8 * temp.pitch); for (z = 0; z < 8; z++) { for (a = 0; a < 8; a++) { v = s[a]; if (v == transcolor) { d[a] = 0x00; d[a+8] = 0xff; } else { d[a] = v; d[a+8] = 0x00; } } d += 16; s += temp.pitch; } } } } temp.Unlock (); I_FreeScreen(scrn); }
void WI_loadData (void) { int i, j; char name[9]; anim_t *a; patch_t *bg; if ((gameinfo.flags & GI_MAPxx) || ((gameinfo.flags & GI_MENUHACK_RETAIL) && wbs->epsd >= 3)) strcpy (name, "INTERPIC"); else sprintf (name, "WIMAP%d", wbs->epsd); // background bg = W_CachePatch (name); background = I_AllocateScreen (bg->width(), bg->height(), 8); background->Lock (); background->DrawPatch (bg, 0, 0); background->Unlock (); for (i = 0; i < 2; i++) { char *lname = (i == 0 ? wbs->lname0 : wbs->lname1); if (lname) j = W_CheckNumForName (lname); else j = -1; if (j >= 0) { lnames[i] = W_CachePatch (j, PU_STATIC); } else { lnames[i] = NULL; lnametexts[i] = FindLevelInfo (i == 0 ? wbs->current : wbs->next)->level_name; lnamewidths[i] = WI_CalcWidth (lnametexts[i]); } } if (gamemode != commercial && gamemode != commercial_bfg ) { // you are here yah[0] = W_CachePatch ("WIURH0", PU_STATIC); // you are here (alt.) yah[1] = W_CachePatch ("WIURH1", PU_STATIC); // splat splat = W_CachePatch ("WISPLAT", PU_STATIC); if (wbs->epsd < 3) { for (j=0; j<NUMANIMS[wbs->epsd]; j++) { a = &anims[wbs->epsd][j]; for (i=0; i<a->nanims; i++) { // MONDO HACK! if (wbs->epsd != 1 || j != 8) { // animations sprintf (name, "WIA%d%.2d%.2d", wbs->epsd, j, i); a->p[i] = W_CachePatch (name, PU_STATIC); } else { // HACK ALERT! a->p[i] = anims[1][4].p[i]; } } } } } for (i=0; i<10; i++) { // numbers 0-9 sprintf(name, "WINUM%d", i); num[i] = W_CachePatch (name, PU_STATIC); } wiminus = W_CachePatch ("WIMINUS", PU_STATIC); // percent sign percent = W_CachePatch ("WIPCNT", PU_STATIC); // ":" colon = W_CachePatch ("WICOLON", PU_STATIC); // "finished" finished = W_CachePatch ("WIF", PU_STATIC); // (Removed) Dan - Causes GUI Issues |FIX-ME| // "entering" entering = W_CachePatch ("WIENTER", PU_STATIC); // "kills" kills = W_CachePatch ("WIOSTK", PU_STATIC); // "items" items = W_CachePatch ("WIOSTI", PU_STATIC); // "scrt" scrt = W_CachePatch ("WIOSTS", PU_STATIC); // "secret" secret = W_CachePatch ("WISCRT2", PU_STATIC); // "frgs" frags = (patch_t *)W_CachePatch ("WIFRGS", PU_STATIC); // "time" timepatch = W_CachePatch ("WITIME", PU_STATIC); // "sucks" sucks =W_CachePatch ("WISUCKS", PU_STATIC); // "par" par = W_CachePatch ("WIPAR", PU_STATIC); // "total" total = (patch_t *)W_CachePatch ("WIMSTT", PU_STATIC); // your face star = (patch_t *)W_CachePatch ("STFST01", PU_STATIC); // dead face bstar = (patch_t *)W_CachePatch("STFDEAD0", PU_STATIC); p = W_CachePatch ("STPBANY", PU_STATIC); // [Nes] Classic vanilla lifebars. for (i = 0; i < 4; i++) { sprintf(name, "STPB%d", i); faceclassic[i] = W_CachePatch(name, PU_STATIC); } }
// // M_DrawMainMenu // void M_DrawMainMenu (void) { screen->DrawPatchClean (W_CachePatch("M_DOOM"), 94, 2); }
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); }