// // TextureManager::readAnimatedLump // // Reads animation definitions from the ANIMATED lump. // // Load the table of animation definitions, checking for existence of // the start and end of each frame. If the start doesn't exist the sequence // is skipped, if the last doesn't exist, BOOM exits. // // Wall/Flat animation sequences, defined by name of first and last frame, // The full animation sequence is given using all lumps between the start // and end entry, in the order found in the WAD file. // // This routine modified to read its data from a predefined lump or // PWAD lump called ANIMATED rather than a static table in this module to // allow wad designers to insert or modify animation sequences. // // Lump format is an array of byte packed animdef_t structures, terminated // by a structure with istexture == -1. The lump can be generated from a // text source file using SWANTBLS.EXE, distributed with the BOOM utils. // The standard list of switches and animations is contained in the example // source text file DEFSWANI.DAT also in the BOOM util distribution. // // [RH] Rewritten to support BOOM ANIMATED lump but also make absolutely // no assumptions about how the compiler packs the animdefs array. // void TextureManager::readAnimatedLump() { int lumpnum = W_CheckNumForName("ANIMATED"); if (lumpnum == -1) return; size_t lumplen = W_LumpLength(lumpnum); if (lumplen == 0) return; byte* lumpdata = new byte[lumplen]; W_ReadLump(lumpnum, lumpdata); for (byte* ptr = lumpdata; *ptr != 255; ptr += 23) { anim_t anim; Texture::TextureSourceType texture_type = *(ptr + 0) == 1 ? Texture::TEX_WALLTEXTURE : Texture::TEX_FLAT; const char* startname = (const char*)(ptr + 10); const char* endname = (const char*)(ptr + 1); texhandle_t start_texhandle = texturemanager.getHandle(startname, texture_type); texhandle_t end_texhandle = texturemanager.getHandle(endname, texture_type); if (start_texhandle == TextureManager::NOT_FOUND_TEXTURE_HANDLE || start_texhandle == TextureManager::NO_TEXTURE_HANDLE || end_texhandle == TextureManager::NOT_FOUND_TEXTURE_HANDLE || end_texhandle == TextureManager::NO_TEXTURE_HANDLE) continue; anim.basepic = start_texhandle; anim.numframes = end_texhandle - start_texhandle + 1; if (anim.numframes <= 0) continue; anim.curframe = 0; int speed = LELONG(*(int*)(ptr + 19)); anim.countdown = speed - 1; for (int i = 0; i < anim.numframes; i++) { anim.framepic[i] = anim.basepic + i; anim.speedmin[i] = anim.speedmax[i] = speed; } mAnimDefs.push_back(anim); } delete [] lumpdata; }
// // TextureManager::readAnimDefLump // // [RH] This uses a Hexen ANIMDEFS lump to define the animation sequences. // void TextureManager::readAnimDefLump() { int lump = -1; while ((lump = W_FindLump("ANIMDEFS", lump)) != -1) { SC_OpenLumpNum(lump, "ANIMDEFS"); while (SC_GetString()) { if (SC_Compare("flat") || SC_Compare("texture")) { anim_t anim; Texture::TextureSourceType texture_type = Texture::TEX_WALLTEXTURE; if (SC_Compare("flat")) texture_type = Texture::TEX_FLAT; SC_MustGetString(); anim.basepic = texturemanager.getHandle(sc_String, texture_type); anim.curframe = 0; anim.numframes = 0; memset(anim.speedmin, 1, anim_t::MAX_ANIM_FRAMES * sizeof(*anim.speedmin)); memset(anim.speedmax, 1, anim_t::MAX_ANIM_FRAMES * sizeof(*anim.speedmax)); while (SC_GetString()) { if (!SC_Compare("pic")) { SC_UnGet(); break; } if ((unsigned)anim.numframes == anim_t::MAX_ANIM_FRAMES) SC_ScriptError ("Animation has too many frames"); byte min = 1, max = 1; SC_MustGetNumber(); int frame = sc_Number; SC_MustGetString(); if (SC_Compare("tics")) { SC_MustGetNumber(); sc_Number = clamp(sc_Number, 0, 255); min = max = sc_Number; } else if (SC_Compare("rand")) { SC_MustGetNumber(); min = MAX(sc_Number, 0); SC_MustGetNumber(); max = MIN(sc_Number, 255); if (min > max) min = max = 1; } else { SC_ScriptError ("Must specify a duration for animation frame"); } anim.speedmin[anim.numframes] = min; anim.speedmax[anim.numframes] = max; anim.framepic[anim.numframes] = frame + anim.basepic - 1; anim.numframes++; } anim.countdown = anim.speedmin[0]; if (anim.basepic != TextureManager::NOT_FOUND_TEXTURE_HANDLE && anim.basepic != TextureManager::NO_TEXTURE_HANDLE) mAnimDefs.push_back(anim); } else if (SC_Compare ("switch")) // Don't support switchdef yet... { //P_ProcessSwitchDef (); SC_ScriptError("switchdef not supported."); } else if (SC_Compare("warp")) { SC_MustGetString(); if (SC_Compare("flat") || SC_Compare("texture")) { Texture::TextureSourceType texture_type = Texture::TEX_WALLTEXTURE; if (SC_Compare("flat")) texture_type = Texture::TEX_FLAT; SC_MustGetString(); texhandle_t texhandle = texturemanager.getHandle(sc_String, texture_type); if (texhandle == TextureManager::NOT_FOUND_TEXTURE_HANDLE || texhandle == TextureManager::NO_TEXTURE_HANDLE) continue; warp_t warp; // backup the original texture warp.original_texture = getTexture(texhandle); int width = 1 << warp.original_texture->getWidthBits(); int height = 1 << warp.original_texture->getHeightBits(); // create a new texture of the same size for the warped image warp.warped_texture = createTexture(texhandle, width, height); mWarpDefs.push_back(warp); } else { SC_ScriptError(NULL, NULL); } } } SC_Close (); } }
const Texture* R_LoadTexture(const char* name) { texhandle_t texhandle = texturemanager.getHandle(name, Texture::TEX_PATCH); return texturemanager.getTexture(texhandle); }