Пример #1
0
void FTextureManager::InitPalettedVersions()
{
	int lump, lastlump = 0;

	PalettedVersions.Clear();
	while ((lump = Wads.FindLump("PALVERS", &lastlump)) != -1)
	{
		FMemLump data = Wads.ReadLump(lump);
		Scanner sc((const char*)data.GetMem(), data.GetSize());

		while (sc.GetNextToken())
		{
			FTextureID pic1 = CheckForTexture(sc->str, FTexture::TEX_Any);
			if (!pic1.isValid())
			{
				sc.ScriptMessage(Scanner::WARNING, "Unknown texture %s to replace", sc->str.GetChars());
			}
			sc.GetNextToken();
			FTextureID pic2 = CheckForTexture(sc->str, FTexture::TEX_Any);
			if (!pic2.isValid())
			{
				sc.ScriptMessage(Scanner::WARNING, "Unknown texture %s to use as replacement", sc->str.GetChars());
			}
			if (pic1.isValid() && pic2.isValid())
			{
				PalettedVersions[pic1.GetIndex()] = pic2.GetIndex();
			}
		}
	}
}
Пример #2
0
void FTextureManager::Init()
{
	DeleteAll();
	// Init Build Tile data if it hasn't been done already
	//if (BuildTileFiles.Size() == 0) CountBuildTiles ();
	FTexture::InitGrayMap();

	// Texture 0 is a dummy texture used to indicate "no texture"
	AddTexture (new FDummyTexture);

	int wadcnt = Wads.GetNumWads();
	for(int i = 0; i< wadcnt; i++)
	{
		AddTexturesForWad(i);
	}

	// Add one marker so that the last WAD is easier to handle and treat
	// Build tiles as a completely separate block.
	//FirstTextureForFile.Push(Textures.Size());
	//InitBuildTiles ();
	//FirstTextureForFile.Push(Textures.Size());

	DefaultTexture = CheckForTexture ("-NOFLAT-", FTexture::TEX_Override, 0);

	//InitAnimated();
	InitAnimDefs();
	FixAnimations();
	InitSwitchList();
	InitPalettedVersions();
}
Пример #3
0
void FTextureManager::ParseCameraTexture(FScanner &sc)
{
	const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny | TEXMAN_ShortNameOnly;
	int width, height;
	int fitwidth, fitheight;
	FString picname;

	sc.MustGetString ();
	picname = sc.String;
	sc.MustGetNumber ();
	width = sc.Number;
	sc.MustGetNumber ();
	height = sc.Number;
	FTextureID picnum = CheckForTexture (picname, FTexture::TEX_Flat, texflags);
	FTexture *viewer = new FCanvasTexture (picname, width, height);
	if (picnum.Exists())
	{
		FTexture *oldtex = Texture(picnum);
		fitwidth = oldtex->GetScaledWidth ();
		fitheight = oldtex->GetScaledHeight ();
		viewer->UseType = oldtex->UseType;
		ReplaceTexture (picnum, viewer, true);
	}
	else
	{
		fitwidth = width;
		fitheight = height;
		// [GRB] No need for oldtex
		viewer->UseType = FTexture::TEX_Wall;
		AddTexture (viewer);
	}
	if (sc.GetString())
	{
		if (sc.Compare ("fit"))
		{
			sc.MustGetNumber ();
			fitwidth = sc.Number;
			sc.MustGetNumber ();
			fitheight = sc.Number;
		}
		else
		{
			sc.UnGet ();
		}
	}
	if (sc.GetString())
	{
		if (sc.Compare("WorldPanning"))
		{
			viewer->bWorldPanning = true;
		}
		else
		{
			sc.UnGet();
		}
	}
	viewer->SetScaledSize(fitwidth, fitheight);
}
Пример #4
0
void FTextureManager::ParseWarp(FScanner &sc)
{
	const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny | TEXMAN_ShortNameOnly;
	bool isflat = false;
	bool type2 = sc.Compare ("warp2");	// [GRB]
	sc.MustGetString ();
	if (sc.Compare ("flat"))
	{
		isflat = true;
		sc.MustGetString ();
	}
	else if (sc.Compare ("texture"))
	{
		isflat = false;
		sc.MustGetString ();
	}
	else
	{
		sc.ScriptError (NULL);
	}
	FTextureID picnum = CheckForTexture (sc.String, isflat ? FTexture::TEX_Flat : FTexture::TEX_Wall, texflags);
	if (picnum.isValid())
	{
		FTexture *warper = Texture(picnum);

		// don't warp a texture more than once
		if (!warper->bWarped)
		{
			if (type2) warper = new FWarp2Texture (warper);
			else warper = new FWarpTexture (warper);

			ReplaceTexture (picnum, warper, false);
		}

		if (sc.CheckFloat())
		{
			static_cast<FWarpTexture*>(warper)->SetSpeed(float(sc.Float));
		}

		// No decals on warping textures, by default.
		// Warping information is taken from the last warp 
		// definition for this texture.
		warper->bNoDecals = true;
		if (sc.GetString ())
		{
			if (sc.Compare ("allowdecals"))
			{
				warper->bNoDecals = false;
			}
			else
			{
				sc.UnGet ();
			}
		}
	}
}
Пример #5
0
void FTextureManager::InitAnimDefs ()
{
	const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny;
	int lump, lastlump = 0;
	
	while ((lump = Wads.FindLump ("ANIMDEFS", &lastlump)) != -1)
	{
		FScanner sc(lump);

		while (sc.GetString ())
		{
			if (sc.Compare ("flat"))
			{
				ParseAnim (sc, FTexture::TEX_Flat);
			}
			else if (sc.Compare ("texture"))
			{
				ParseAnim (sc, FTexture::TEX_Wall);
			}
			else if (sc.Compare ("switch"))
			{
				ProcessSwitchDef (sc);
			}
			// [GRB] Added warping type 2
			else if (sc.Compare ("warp") || sc.Compare ("warp2"))
			{
				ParseWarp(sc);
			}
			else if (sc.Compare ("cameratexture"))
			{
				ParseCameraTexture(sc);
			}
			else if (sc.Compare ("animatedDoor"))
			{
				ParseAnimatedDoor (sc);
			}
			else if (sc.Compare("skyoffset"))
			{
				sc.MustGetString ();
				FTextureID picnum = CheckForTexture (sc.String, FTexture::TEX_Wall, texflags);
				sc.MustGetNumber();
				if (picnum.Exists())
				{
					Texture(picnum)->SkyOffset = sc.Number;
				}
			}
			else
			{
				sc.ScriptError (NULL);
			}
		}
	}
}
Пример #6
0
void FTextureManager::InitSwitchList ()
{
	const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny;
	int lump = Wads.CheckNumForName ("SWITCHES");

	if (lump != -1)
	{
		FMemLump lumpdata = Wads.ReadLump (lump);
		const char *alphSwitchList = (const char *)lumpdata.GetMem();
		const char *list_p;
		FSwitchDef *def1, *def2;

		for (list_p = alphSwitchList; list_p[18] || list_p[19]; list_p += 20)
		{
			// [RH] Check for switches that aren't really switches
			if (stricmp (list_p, list_p+9) == 0)
			{
				Printf ("Switch %s in SWITCHES has the same 'on' state\n", list_p);
				continue;
			}
			// [RH] Skip this switch if its textures can't be found.
			if (CheckForTexture (list_p /* .name1 */, FTexture::TEX_Wall, texflags).Exists() &&
				CheckForTexture (list_p + 9 /* .name2 */, FTexture::TEX_Wall, texflags).Exists())
			{
				def1 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef));
				def2 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef));
				def1->PreTexture = def2->frames[0].Texture = CheckForTexture (list_p /* .name1 */, FTexture::TEX_Wall, texflags);
				def2->PreTexture = def1->frames[0].Texture = CheckForTexture (list_p + 9, FTexture::TEX_Wall, texflags);
				def1->Sound = def2->Sound = 0;
				def1->NumFrames = def2->NumFrames = 1;
				def1->frames[0].TimeMin = def2->frames[0].TimeMin = 0;
				def1->frames[0].TimeRnd = def2->frames[0].TimeRnd = 0;
				AddSwitchPair(def1, def2);
			}
		}
	}

	mSwitchDefs.ShrinkToFit ();
	qsort (&mSwitchDefs[0], mSwitchDefs.Size(), sizeof(FSwitchDef *), SortSwitchDefs);
}
Пример #7
0
FTextureID FTextureManager::ParseFramenum (FScanner &sc, FTextureID basepicnum, int usetype, bool allowMissing)
{
	const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny;
	FTextureID framenum;

	sc.MustGetString ();
	if (IsNum (sc.String))
	{
		framenum = basepicnum + (atoi(sc.String) - 1);
	}
	else
	{
		framenum = CheckForTexture (sc.String, usetype, texflags);
		if (!framenum.Exists() && !allowMissing)
		{
			sc.ScriptError ("Unknown texture %s", sc.String);
		}
	}
	return framenum;
}
Пример #8
0
FTextureID FTextureManager::GetTexture (const char *name, int usetype, BITFIELD flags)
{
	FTextureID i;

	if (name == NULL || name[0] == 0)
	{
		return FTextureID(0);
	}
	else
	{
		i = CheckForTexture (name, usetype, flags | TEXMAN_TryAny);
	}

	if (!i.Exists())
	{
		// Use a default texture instead of aborting like Doom did
		Printf ("Unknown texture: \"%s\"\n", name);
		i = DefaultTexture;
	}
	return FTextureID(i);
}
Пример #9
0
void FTextureManager::AddPatches (int lumpnum)
{
	FWadLump *file = Wads.ReopenLumpNum (lumpnum);
	DWORD numpatches, i;
	char name[9];

	*file >> numpatches;
	name[8] = 0;

	for (i = 0; i < numpatches; ++i)
	{
		file->Read (name, 8);

		if (CheckForTexture (name, FTexture::TEX_WallPatch, 0) == -1)
		{
			CreateTexture (Wads.CheckNumForName (name, ns_patches), FTexture::TEX_WallPatch);
		}
		//StartScreen->Progress();
	}

	delete file;
}
Пример #10
0
void FTextureManager::ProcessSwitchDef (FScanner &sc)
{
	const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny;
	FString picname;
	FSwitchDef *def1, *def2;
	FTextureID picnum;
	int gametype;
	bool quest = false;

	def1 = def2 = NULL;
	sc.MustGetString ();
	if (sc.Compare ("doom"))
	{
		gametype = GAME_DoomChex;
		sc.CheckNumber();	// skip the gamemission filter
	}
	else if (sc.Compare ("heretic"))
	{
		gametype = GAME_Heretic;
	}
	else if (sc.Compare ("hexen"))
	{
		gametype = GAME_Hexen;
	}
	else if (sc.Compare ("strife"))
	{
		gametype = GAME_Strife;
	}
	else if (sc.Compare ("any"))
	{
		gametype = GAME_Any;
	}
	else
	{
		// There is no game specified; just treat as any
		//max = 240;
		gametype = GAME_Any;
		sc.UnGet ();
	}

	sc.MustGetString ();
	picnum = CheckForTexture (sc.String, FTexture::TEX_Wall, texflags);
	picname = sc.String;
	while (sc.GetString ())
	{
		if (sc.Compare ("quest"))
		{
			quest = true;
		}
		else if (sc.Compare ("on"))
		{
			if (def1 != NULL)
			{
				sc.ScriptError ("Switch already has an on state");
			}
			def1 = ParseSwitchDef (sc, !picnum.Exists());
		}
		else if (sc.Compare ("off"))
		{
			if (def2 != NULL)
			{
				sc.ScriptError ("Switch already has an off state");
			}
			def2 = ParseSwitchDef (sc, !picnum.Exists());
		}
		else
		{
			sc.UnGet ();
			break;
		}
	}

	if (def1 == NULL || !picnum.Exists() ||
		(gametype != GAME_Any && !(gametype & gameinfo.gametype)))
	{
		if (def2 != NULL)
		{
			M_Free (def2);
		}
		if (def1 != NULL)
		{
			M_Free (def1);
		}
		return;
	}

	// If the switch did not have an off state, create one that just returns
	// it to the original texture without doing anything interesting
	if (def2 == NULL)
	{
		def2 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef));
		def2->Sound = def1->Sound;
		def2->NumFrames = 1;
		def2->frames[0].TimeMin = 0;
		def2->frames[0].TimeRnd = 0;
		def2->frames[0].Texture = picnum;
	}

	def1->PreTexture = picnum;
	def2->PreTexture = def1->frames[def1->NumFrames-1].Texture;
	if (def1->PreTexture == def2->PreTexture)
	{
		sc.ScriptError ("The on state for switch %s must end with a texture other than %s", picname.GetChars(), picname.GetChars());
	}
	AddSwitchPair(def1, def2);
	def1->QuestPanel = def2->QuestPanel = quest;
}
Пример #11
0
void FTextureManager::AddTexturesForWad(int wadnum)
{
	int firsttexture = Textures.Size();
	int lumpcount = Wads.GetNumLumps();

	FirstTextureForFile.Push(firsttexture);

	// First step: Load sprites
	AddGroup(wadnum, ns_sprites, FTexture::TEX_Sprite);

	// When loading a Zip, all graphics in the patches/ directory should be
	// added as well.
	AddGroup(wadnum, ns_patches, FTexture::TEX_WallPatch);

	// Second step: TEXTUREx lumps
	//LoadTextureX(wadnum);

	// Third step: Flats
	AddGroup(wadnum, ns_flats, FTexture::TEX_Flat);

	// Fourth step: Textures (TX_)
	AddGroup(wadnum, ns_newtextures, FTexture::TEX_Override);

	// Sixth step: Try to find any lump in the WAD that may be a texture and load as a TEX_MiscPatch
	int firsttx = Wads.GetFirstLump(wadnum);
	int lasttx = Wads.GetLastLump(wadnum);

	for (int i= firsttx; i <= lasttx; i++)
	{
		char name[9];
		Wads.GetLumpName(name, i);
		name[8]=0;

		// Ignore anything not in the global namespace
		int ns = Wads.GetLumpNamespace(i);
		if (ns == ns_global)
		{
			// In Zips all graphics must be in a separate namespace.
			if (Wads.GetLumpFlags(i) & LUMPF_ZIPFILE) continue;

			// Ignore lumps with empty names.
			if (Wads.CheckLumpName(i, "")) continue;

			// Ignore anything belonging to a map
			if (Wads.CheckLumpName(i, "PLANES")) continue;

			// Don't bother looking at this lump if something later overrides it.
			if (Wads.CheckNumForName(name, ns_graphics) != i) continue;

			// skip this if it has already been added as a wall patch.
			if (CheckForTexture(name, FTexture::TEX_WallPatch, 0).Exists()) continue;
		}
		else if (ns == ns_graphics)
		{
			// Don't bother looking this lump if something later overrides it.
			if (Wads.CheckNumForName(name, ns_graphics) != i) continue;
		}
		else continue;

		// Try to create a texture from this lump and add it.
		// Unfortunately we have to look at everything that comes through here...
		FTexture *out = FTexture::CreateTexture(i, FTexture::TEX_MiscPatch);

		if (out != NULL) 
		{
			AddTexture (out);
		}
	}

	// Check for text based texture definitions
	LoadTextureDefs(wadnum, "TEXTURES");
	//LoadTextureDefs(wadnum, "HIRESTEX");

	// Seventh step: Check for hires replacements.
	AddHiresTextures(wadnum);

	SortTexturesByType(firsttexture, Textures.Size());
}
Пример #12
0
FTexture *FTextureManager::FindTexture(const char *texname, int usetype, BITFIELD flags)
{
	FTextureID texnum = CheckForTexture (texname, usetype, flags);
	return !texnum.isValid()? NULL : Textures[texnum.GetIndex()].Texture;
}
Пример #13
0
void FTextureManager::ParseAnimatedDoor(FScanner &sc)
{
	const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny;
	FDoorAnimation anim;
	TArray<FTextureID> frames;
	bool error = false;
	FTextureID v;

	sc.MustGetString();
	anim.BaseTexture = CheckForTexture (sc.String, FTexture::TEX_Wall, texflags);

	if (!anim.BaseTexture.Exists())
	{
		error = true;
	}
	else
	{
		Texture(anim.BaseTexture)->bNoDecals = true;
	}
	while (sc.GetString())
	{
		if (sc.Compare ("opensound"))
		{
			sc.MustGetString ();
			anim.OpenSound = sc.String;
		}
		else if (sc.Compare ("closesound"))
		{
			sc.MustGetString ();
			anim.CloseSound = sc.String;
		}
		else if (sc.Compare ("pic"))
		{
			sc.MustGetString ();
			if (IsNum (sc.String))
			{
				v = anim.BaseTexture + (atoi(sc.String) - 1);
			}
			else
			{
				v = CheckForTexture (sc.String, FTexture::TEX_Wall, texflags);
				if (!v.Exists() && anim.BaseTexture.Exists() && !error)
				{
					sc.ScriptError ("Unknown texture %s", sc.String);
				}
			}
			frames.Push(v);
		}
		else if (sc.Compare("allowdecals"))
		{
			if (anim.BaseTexture.Exists()) Texture(anim.BaseTexture)->bNoDecals = false;
		}
		else
		{
			sc.UnGet ();
			break;
		}
	}
	if (!error)
	{
		anim.TextureFrames = new FTextureID[frames.Size()];
		memcpy (anim.TextureFrames, &frames[0], sizeof(FTextureID) * frames.Size());
		anim.NumTextureFrames = frames.Size();
		mAnimatedDoors.Push (anim);
	}
}
Пример #14
0
void FTextureManager::ParseAnim (FScanner &sc, int usetype)
{
	const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny;
	TArray<FAnimDef::FAnimFrame> frames (32);
	FTextureID picnum;
	int defined = 0;
	bool optional = false, missing = false;
	FAnimDef *ani = NULL;
	BYTE type = FAnimDef::ANIM_Forward;

	sc.MustGetString ();
	if (sc.Compare ("optional"))
	{
		optional = true;
		sc.MustGetString ();
	}
	picnum = CheckForTexture (sc.String, usetype, texflags);

	if (!picnum.Exists())
	{
		if (optional)
		{
			missing = true;
		}
		else
		{
			Printf (PRINT_BOLD, "ANIMDEFS: Can't find %s\n", sc.String);
		}
	}

	// no decals on animating textures, by default
	if (picnum.isValid())
	{
		Texture(picnum)->bNoDecals = true;
	}

	while (sc.GetString ())
	{
		if (sc.Compare ("allowdecals"))
		{
			if (picnum.isValid())
			{
				Texture(picnum)->bNoDecals = false;
			}
			continue;
		}
		else if (sc.Compare ("Oscillate"))
		{
			if (type == FAnimDef::ANIM_Random)
			{
				sc.ScriptError ("You cannot use \"random\" and \"oscillate\" together in a single animation.");
			}
			type = FAnimDef::ANIM_OscillateUp;
		}
		else if (sc.Compare("Random"))
		{
			if (type == FAnimDef::ANIM_OscillateUp)
			{
				sc.ScriptError ("You cannot use \"random\" and \"oscillate\" together in a single animation.");
			}
			type = FAnimDef::ANIM_Random;
		}
		else if (sc.Compare ("range"))
		{
			if (picnum.Exists() && Texture(picnum)->Name.IsEmpty())
			{
				// long texture name: We cannot do ranged anims on these because they have no defined order
				sc.ScriptError ("You cannot use \"range\" for long texture names.");
			}
			if (defined == 2)
			{
				sc.ScriptError ("You cannot use \"pic\" and \"range\" together in a single animation.");
			}
			if (defined == 1)
			{
				sc.ScriptError ("You can only use one \"range\" per animation.");
			}
			defined = 1;
			ani = ParseRangeAnim (sc, picnum, usetype, missing);
		}
		else if (sc.Compare ("pic"))
		{
			if (defined == 1)
			{
				sc.ScriptError ("You cannot use \"pic\" and \"range\" together in a single animation.");
			}
			defined = 2;
			ParsePicAnim (sc, picnum, usetype, missing, frames);
		}
		else
		{
			sc.UnGet ();
			break;
		}
	}

	// If base pic is not present, don't add this anim
	// ParseRangeAnim adds the anim itself, but ParsePicAnim does not.
	if (picnum.isValid() && defined == 2)
	{
		if (frames.Size() < 2)
		{
			sc.ScriptError ("Animation needs at least 2 frames");
		}
		ani = AddComplexAnim (picnum, frames);
	}
	if (ani != NULL && type != FAnimDef::ANIM_Forward)
	{
		if (ani->AnimType == FAnimDef::ANIM_Backward && type == FAnimDef::ANIM_OscillateUp) ani->AnimType = FAnimDef::ANIM_OscillateDown;
		else ani->AnimType = type;
	}
}
Пример #15
0
FSwitchDef *FTextureManager::ParseSwitchDef (FScanner &sc, bool ignoreBad)
{
	const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny;
	FSwitchDef *def;
	TArray<FSwitchDef::frame> frames;
	FSwitchDef::frame thisframe;
	FTextureID picnum;
	bool bad;
	FSoundID sound;

	bad = false;

	while (sc.GetString ())
	{
		if (sc.Compare ("sound"))
		{
			if (sound != 0)
			{
				sc.ScriptError ("Switch state already has a sound");
			}
			sc.MustGetString ();
			sound = sc.String;
		}
		else if (sc.Compare ("pic"))
		{
			sc.MustGetString ();
			picnum = CheckForTexture (sc.String, FTexture::TEX_Wall, texflags);
			if (!picnum.Exists() && !ignoreBad)
			{
				//Printf ("Unknown switch texture %s\n", sc.String);
				bad = true;
			}
			thisframe.Texture = picnum;
			sc.MustGetString ();
			if (sc.Compare ("tics"))
			{
				sc.MustGetNumber ();
				thisframe.TimeMin = sc.Number & 65535;
				thisframe.TimeRnd = 0;
			}
			else if (sc.Compare ("rand"))
			{
				int min, max;

				sc.MustGetNumber ();
				min = sc.Number & 65535;
				sc.MustGetNumber ();
				max = sc.Number & 65535;
				if (min > max)
				{
					swapvalues (min, max);
				}
				thisframe.TimeMin = min;
				thisframe.TimeRnd = (max - min + 1);
			}
			else
			{
			    thisframe.TimeMin = 0;     // Shush, GCC.
				thisframe.TimeRnd = 0;
				sc.ScriptError ("Must specify a duration for switch frame");
			}
			frames.Push(thisframe);
		}
		else
		{
			sc.UnGet ();
			break;
		}
	}
	if (frames.Size() == 0)
	{
		sc.ScriptError ("Switch state needs at least one frame");
	}
	if (bad)
	{
		return NULL;
	}

	def = (FSwitchDef *)M_Malloc (myoffsetof (FSwitchDef, frames[0]) + frames.Size()*sizeof(frames[0]));
	def->Sound = sound;
	def->NumFrames = frames.Size();
	memcpy (&def->frames[0], &frames[0], frames.Size() * sizeof(frames[0]));
	def->PairDef = NULL;
	return def;
}
Пример #16
0
void FTextureManager::ParseAnim (FScanner &sc, int usetype)
{
	const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny;
	TArray<FAnimDef::FAnimFrame> frames (32);
	FTextureID picnum;
	int defined = 0;
	bool optional = false, missing = false;

	sc.MustGetString ();
	if (sc.Compare ("optional"))
	{
		optional = true;
		sc.MustGetString ();
	}
	picnum = CheckForTexture (sc.String, usetype, texflags);

	if (!picnum.Exists())
	{
		if (optional)
		{
			missing = true;
		}
		else
		{
			Printf (PRINT_BOLD, "ANIMDEFS: Can't find %s\n", sc.String);
		}
	}

	// no decals on animating textures, by default
	if (picnum.isValid())
	{
		Texture(picnum)->bNoDecals = true;
	}

	while (sc.GetString ())
	{
		if (sc.Compare ("allowdecals"))
		{
			if (picnum.isValid())
			{
				Texture(picnum)->bNoDecals = false;
			}
			continue;
		}
		else if (sc.Compare ("range"))
		{
			if (defined == 2)
			{
				sc.ScriptError ("You cannot use \"pic\" and \"range\" together in a single animation.");
			}
			if (defined == 1)
			{
				sc.ScriptError ("You can only use one \"range\" per animation.");
			}
			defined = 1;
			ParseRangeAnim (sc, picnum, usetype, missing);
		}
		else if (sc.Compare ("pic"))
		{
			if (defined == 1)
			{
				sc.ScriptError ("You cannot use \"pic\" and \"range\" together in a single animation.");
			}
			defined = 2;
			ParsePicAnim (sc, picnum, usetype, missing, frames);
		}
		else
		{
			sc.UnGet ();
			break;
		}
	}

	// If base pic is not present, don't add this anim
	// ParseRangeAnim adds the anim itself, but ParsePicAnim does not.
	if (picnum.isValid() && defined == 2)
	{
		if (frames.Size() < 2)
		{
			sc.ScriptError ("Animation needs at least 2 frames");
		}
		AddComplexAnim (picnum, frames);
	}
}
Пример #17
0
void FTextureManager::InitAnimated (void)
{
	const BITFIELD texflags = TEXMAN_Overridable;
		// I think better not! This is only for old ANIMATED definitions that
		// don't know about ZDoom's more flexible texture system.
		// | FTextureManager::TEXMAN_TryAny;

	int lumpnum = Wads.CheckNumForName ("ANIMATED");
	if (lumpnum != -1)
	{
		FMemLump animatedlump = Wads.ReadLump (lumpnum);
		int animatedlen = Wads.LumpLength(lumpnum);
		const char *animdefs = (const char *)animatedlump.GetMem();
		const char *anim_p;
		FTextureID pic1, pic2;
		int animtype;
		DWORD animspeed;

		// Init animation
		animtype = FAnimDef::ANIM_Forward;

		for (anim_p = animdefs; *anim_p != -1; anim_p += 23)
		{
			// make sure the current chunk of data is inside the lump boundaries.
			if (anim_p + 22 >= animdefs + animatedlen)
			{
				I_Error("Tried to read past end of ANIMATED lump.");
			}
			if (*anim_p /* .istexture */ & 1)
			{
				// different episode ?
				if (!(pic1 = CheckForTexture (anim_p + 10 /* .startname */, FTexture::TEX_Wall, texflags)).Exists() ||
					!(pic2 = CheckForTexture (anim_p + 1 /* .endname */, FTexture::TEX_Wall, texflags)).Exists())
					continue;		

				// [RH] Bit 1 set means allow decals on walls with this texture
				Texture(pic2)->bNoDecals = Texture(pic1)->bNoDecals = !(*anim_p & 2);
			}
			else
			{
				if (!(pic1 = CheckForTexture (anim_p + 10 /* .startname */, FTexture::TEX_Flat, texflags)).Exists() ||
					!(pic2 = CheckForTexture (anim_p + 1 /* .startname */, FTexture::TEX_Flat, texflags)).Exists())
					continue;
			}

			FTexture *tex1 = Texture(pic1);
			FTexture *tex2 = Texture(pic2);

			animspeed = (BYTE(anim_p[19]) << 0)  | (BYTE(anim_p[20]) << 8) |
						(BYTE(anim_p[21]) << 16) | (BYTE(anim_p[22]) << 24);

			// SMMU-style swirly hack? Don't apply on already-warping texture
			if (animspeed > 65535 && tex1 != NULL && !tex1->bWarped)
			{
				FTexture *warper = new FWarp2Texture (tex1);
				ReplaceTexture (pic1, warper, false);
			}
			// These tests were not really relevant for swirling textures, or even potentially
			// harmful, so they have been moved to the else block.
			else
			{
				if (tex1->UseType != tex2->UseType)
				{
					// not the same type - 
					continue;
				}

				if (debuganimated)
				{
					Printf("Defining animation '%s' (texture %d, lump %d, file %d) to '%s' (texture %d, lump %d, file %d)\n",
						tex1->Name, pic1.GetIndex(), tex1->GetSourceLump(), Wads.GetLumpFile(tex1->GetSourceLump()),
						tex2->Name, pic2.GetIndex(), tex2->GetSourceLump(), Wads.GetLumpFile(tex2->GetSourceLump()));
				}

				if (pic1 == pic2)
				{
					// This animation only has one frame. Skip it. (Doom aborted instead.)
					Printf ("Animation %s in ANIMATED has only one frame\n", anim_p + 10);
					continue;
				}
				// [RH] Allow for backward animations as well as forward.
				else if (pic1 > pic2)
				{
					swapvalues (pic1, pic2);
					animtype = FAnimDef::ANIM_Backward;
				}

				// Speed is stored as tics, but we want ms so scale accordingly.
				AddSimpleAnim (pic1, pic2 - pic1 + 1, animtype, Scale (animspeed, 1000, 35));
			}
		}
	}
}
Пример #18
0
void FTextureManager::ParseWarp(FScanner &sc)
{
	const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny;
	bool isflat = false;
	bool type2 = sc.Compare ("warp2");	// [GRB]
	sc.MustGetString ();
	if (sc.Compare ("flat"))
	{
		isflat = true;
		sc.MustGetString ();
	}
	else if (sc.Compare ("texture"))
	{
		isflat = false;
		sc.MustGetString ();
	}
	else
	{
		sc.ScriptError (NULL);
	}
	FTextureID picnum = CheckForTexture (sc.String, isflat ? FTexture::TEX_Flat : FTexture::TEX_Wall, texflags);
	if (picnum.isValid())
	{

		FTexture *warper = Texture(picnum);

		if (warper->Name.IsEmpty())
		{
			// long texture name: We cannot do warps on these due to the way the texture manager implements warping as a texture replacement.
			sc.ScriptError ("You cannot use \"warp\" for long texture names.");
		}


		// don't warp a texture more than once
		if (!warper->bWarped)
		{
			warper = new FWarpTexture (warper, type2? 2:1);
			ReplaceTexture (picnum, warper, false);
		}

		if (sc.CheckFloat())
		{
			static_cast<FWarpTexture*>(warper)->SetSpeed(float(sc.Float));
		}

		// No decals on warping textures, by default.
		// Warping information is taken from the last warp 
		// definition for this texture.
		warper->bNoDecals = true;
		if (sc.GetString ())
		{
			if (sc.Compare ("allowdecals"))
			{
				warper->bNoDecals = false;
			}
			else
			{
				sc.UnGet ();
			}
		}
	}
}