- intermission parser complete. The current definitions get parsed without error messages.

SVN r2877 (finale)
This commit is contained in:
Christoph Oelckers 2010-10-02 10:32:16 +00:00
parent 854e236c86
commit a9632c2694
10 changed files with 404 additions and 137 deletions

View file

@ -54,6 +54,7 @@ class FScanner;
#define GCC_YSEG __attribute__((section(SECTION_YREG)))
#endif
struct FIntermissionAction;
struct FMapInfoParser
{
@ -99,6 +100,7 @@ struct FMapInfoParser
void SkipToNext();
void CheckEndOfFile(const char *block);
FIntermissionAction *ParseIntermissionAction();
void ParseIntermission();
FName CheckEndSequence();
FName ParseEndGame();

View file

@ -37,10 +37,13 @@
#include "w_wad.h"
#include "intermission/intermission.h"
FIntermissionDescriptorList IntermissionDescriptors;
IMPLEMENT_CLASS(DIntermissionScreen)
IMPLEMENT_CLASS(DIntermissionScreenFader)
IMPLEMENT_CLASS(DIntermissionScreenText)
IMPLEMENT_CLASS(DIntermissionScreenCast)
IMPLEMENT_CLASS(DIntermissionScreenScroller)
IMPLEMENT_CLASS(DIntermissionController)
void DIntermissionScreen::Init(FIntermissionDescriptor *desc)

View file

@ -39,6 +39,32 @@ struct FICastSound
FSoundID mSound;
};
enum EFadeType
{
FADE_In,
FADE_Out,
};
enum EWipeType
{
WIPE_Default,
WIPE_Cross,
WIPE_Melt,
WIPE_Burn
};
enum EScrollDir
{
SCROLL_Left,
SCROLL_Right,
SCROLL_Up,
SCROLL_Down,
};
// actions that don't create objects
#define WIPER_ID ((const PClass*)intptr_t(-1))
#define TITLE_ID ((const PClass*)intptr_t(-2))
//==========================================================================
struct FIntermissionAction
@ -51,6 +77,7 @@ struct FIntermissionAction
int mCdId;
int mDuration;
FString mBackground;
FString mPalette;
FString mSound;
bool mFlatfill;
TArray<FIntermissionPatch> mOverlays;
@ -62,16 +89,6 @@ struct FIntermissionAction
struct FIntermissionActionFader : public FIntermissionAction
{
enum EFadeType
{
FADE_In,
FADE_Out,
FADE_Cross,
FADE_Melt,
FADE_Burn,
FADE_Wipe
};
typedef FIntermissionAction Super;
EFadeType mFadeType;
@ -80,6 +97,16 @@ struct FIntermissionActionFader : public FIntermissionAction
virtual bool ParseKey(FScanner &sc);
};
struct FIntermissionActionWiper : public FIntermissionAction
{
typedef FIntermissionAction Super;
EWipeType mWipeType;
FIntermissionActionWiper();
virtual bool ParseKey(FScanner &sc);
};
struct FIntermissionActionTextscreen : public FIntermissionAction
{
typedef FIntermissionAction Super;
@ -96,10 +123,8 @@ struct FIntermissionActionCast : public FIntermissionAction
{
typedef FIntermissionAction Super;
FString mWalking;
FString mAttacking1;
FString mAttacking2;
FString mDying;
FString mName;
FName mCastClass;
TArray<FCastSound> mCastSounds;
FIntermissionActionCast();
@ -158,7 +183,7 @@ class DIntermissionScreenFader : public DIntermissionScreen
int mTotalTime;
int mCounter;
int mType;
EFadeType mType;
public:
@ -192,10 +217,7 @@ class DIntermissionScreenCast : public DIntermissionScreen
{
DECLARE_CLASS (DIntermissionScreenCast, DIntermissionScreen)
FState *mWalking;
FState *mAttacking1;
FState *mAttacking2;
FState *mDying;
FString mName;
TArray<FICastSound> mCastSounds;
public:

View file

@ -89,7 +89,7 @@ bool FIntermissionAction::ParseKey(FScanner &sc)
sc.MustGetToken('=');
if (!sc.CheckToken('-'))
{
sc.MustGetToken(TK_FloatConst);
sc.MustGetFloat();
mDuration = xs_RoundToInt(sc.Float*TICRATE);
}
else
@ -109,6 +109,11 @@ bool FIntermissionAction::ParseKey(FScanner &sc)
{
sc.MustGetToken(TK_IntConst);
mFlatfill = !!sc.Number;
if (sc.CheckToken(','))
{
sc.MustGetToken(TK_StringConst);
mPalette = sc.String;
}
}
return true;
}
@ -151,7 +156,9 @@ bool FIntermissionAction::ParseKey(FScanner &sc)
FIntermissionActionFader::FIntermissionActionFader()
{
mFadeType = FADE_Cross;
mSize = sizeof(FIntermissionActionFader);
mClass = RUNTIME_CLASS(DIntermissionScreenFader);
mFadeType = FADE_In;
}
bool FIntermissionActionFader::ParseKey(FScanner &sc)
@ -164,10 +171,6 @@ bool FIntermissionActionFader::ParseKey(FScanner &sc)
const FT[] = {
{ "FadeIn", FADE_In },
{ "FadeOut", FADE_Out },
{ "Crossfade", FADE_Cross },
{ "Melt", FADE_Melt },
{ "Burn", FADE_Burn },
{ "Wipe", FADE_Wipe },
{ NULL, FADE_In }
};
@ -175,13 +178,52 @@ bool FIntermissionActionFader::ParseKey(FScanner &sc)
{
sc.MustGetToken('=');
sc.MustGetToken(TK_Identifier);
int v = sc.MustMatchString(&FT[0].Name, sizeof(FT[0]));
int v = sc.MatchString(&FT[0].Name, sizeof(FT[0]));
if (v != -1) mFadeType = FT[v].Type;
return true;
}
else return Super::ParseKey(sc);
}
//==========================================================================
//
// FIntermissionActionWiper
//
//==========================================================================
FIntermissionActionWiper::FIntermissionActionWiper()
{
mSize = sizeof(FIntermissionActionWiper);
mClass = WIPER_ID;
mWipeType = WIPE_Default;
}
bool FIntermissionActionWiper::ParseKey(FScanner &sc)
{
struct WipeType
{
const char *Name;
EWipeType Type;
}
const FT[] = {
{ "Crossfade", WIPE_Cross },
{ "Melt", WIPE_Melt },
{ "Burn", WIPE_Burn },
{ "Default", WIPE_Default },
{ NULL, WIPE_Default }
};
if (sc.Compare("WipeType"))
{
sc.MustGetToken('=');
sc.MustGetToken(TK_Identifier);
int v = sc.MatchString(&FT[0].Name, sizeof(FT[0]));
if (v != -1) mWipeType = FT[v].Type;
return true;
}
else return Super::ParseKey(sc);
}
//==========================================================================
//
// FIntermissionActionFader
@ -190,6 +232,8 @@ bool FIntermissionActionFader::ParseKey(FScanner &sc)
FIntermissionActionTextscreen::FIntermissionActionTextscreen()
{
mSize = sizeof(FIntermissionActionTextscreen);
mClass = RUNTIME_CLASS(DIntermissionScreenText);
mTextSpeed = 2;
mTextX = -1; // use gameinfo defaults
mTextY = -1;
@ -218,8 +262,10 @@ bool FIntermissionActionTextscreen::ParseKey(FScanner &sc)
}
else
{
sc.ScriptMessage("Unknown text lump '%s'", sc.String);
mText = "(no message)";
// only print an error if coming from a PWAD
if (Wads.GetLumpFile(sc.LumpNum) > 1)
sc.ScriptMessage("Unknown text lump '%s'", sc.String);
mText.Format("Unknown text lump '%s'", sc.String);
}
return true;
}
@ -244,44 +290,226 @@ bool FIntermissionActionTextscreen::ParseKey(FScanner &sc)
else return Super::ParseKey(sc);
}
//==========================================================================
//
// FIntermissionAction
//
//==========================================================================
void FMapInfoParser::ParseIntermission()
FIntermissionActionCast::FIntermissionActionCast()
{
FIntermissionAction *desc;
mSize = sizeof(FIntermissionActionCast);
mClass = RUNTIME_CLASS(DIntermissionScreenCast);
}
while (!sc.CheckString("}"))
bool FIntermissionActionCast::ParseKey(FScanner &sc)
{
if (sc.Compare("CastName"))
{
sc.MustGetString();
if (sc.Compare("image"))
{
desc = new FIntermissionAction;
}
else if (sc.Compare("scroller"))
{
}
else if (sc.Compare("cast"))
{
}
else if (sc.Compare("Fader"))
{
desc = new FIntermissionActionFader;
}
else if (sc.Compare("TextScreen"))
{
desc = new FIntermissionActionTextscreen;
}
else if (sc.Compare("GotoTitle"))
sc.MustGetToken('=');
sc.MustGetToken(TK_StringConst);
mName = sc.String;
return true;
}
else if (sc.Compare("CastClass"))
{
sc.MustGetToken('=');
sc.MustGetToken(TK_StringConst);
mCastClass = sc.String;
return true;
}
else if (sc.Compare("AttackSound"))
{
static const char *const seqs[] = {"Missile", "Melee", NULL};
FCastSound *cs = &mCastSounds[mCastSounds.Reserve(1)];
sc.MustGetToken('=');
sc.MustGetToken(TK_StringConst);
cs->mSequence = (BYTE)sc.MatchString(seqs);
sc.MustGetToken(',');
sc.MustGetToken(TK_IntConst);
cs->mIndex = (BYTE)sc.Number;
sc.MustGetToken(',');
sc.MustGetToken(TK_StringConst);
cs->mSound = sc.String;
return true;
}
else return Super::ParseKey(sc);
}
//==========================================================================
//
// FIntermissionActionScroller
//
//==========================================================================
FIntermissionActionScroller::FIntermissionActionScroller()
{
mSize = sizeof(FIntermissionActionScroller);
mClass = RUNTIME_CLASS(DIntermissionScreenScroller);
mScrollDelay = 0;
mScrollTime = 640;
mScrollDir = SCROLL_Right;
}
bool FIntermissionActionScroller::ParseKey(FScanner &sc)
{
struct ScrollType
{
const char *Name;
EScrollDir Type;
}
const ST[] = {
{ "Left", SCROLL_Left },
{ "Right", SCROLL_Right },
{ "Up", SCROLL_Up },
{ "Down", SCROLL_Down },
{ NULL, SCROLL_Left }
};
if (sc.Compare("ScrollDirection"))
{
sc.MustGetToken('=');
sc.MustGetToken(TK_Identifier);
int v = sc.MatchString(&ST[0].Name, sizeof(ST[0]));
if (v != -1) mScrollDir = ST[v].Type;
return true;
}
else if (sc.Compare("InitialDelay"))
{
sc.MustGetToken('=');
if (!sc.CheckToken('-'))
{
sc.MustGetFloat();
mScrollDelay = xs_RoundToInt(sc.Float*TICRATE);
}
else
{
sc.ScriptMessage("Unknown intermission type '%s'", sc.String);
sc.MustGetToken(TK_IntConst);
mScrollDelay = sc.Number;
}
return true;
}
else if (sc.Compare("ScrollTime"))
{
sc.MustGetToken('=');
if (!sc.CheckToken('-'))
{
sc.MustGetFloat();
mScrollTime = xs_RoundToInt(sc.Float*TICRATE);
}
else
{
sc.MustGetToken(TK_IntConst);
mScrollTime = sc.Number;
}
return true;
}
else if (sc.Compare("Background2"))
{
sc.MustGetToken('=');
sc.MustGetToken(TK_StringConst);
mSecondPic = sc.String;
return true;
}
else return Super::ParseKey(sc);
}
//==========================================================================
//
// ParseIntermission
//
//==========================================================================
FIntermissionAction *FMapInfoParser::ParseIntermissionAction()
{
FIntermissionAction *desc = NULL;
sc.MustGetToken(TK_Identifier);
if (sc.Compare("image"))
{
desc = new FIntermissionAction;
}
else if (sc.Compare("scroller"))
{
desc = new FIntermissionActionScroller;
}
else if (sc.Compare("cast"))
{
desc = new FIntermissionActionCast;
}
else if (sc.Compare("Fader"))
{
desc = new FIntermissionActionFader;
}
else if (sc.Compare("Wiper"))
{
desc = new FIntermissionActionWiper;
}
else if (sc.Compare("TextScreen"))
{
desc = new FIntermissionActionTextscreen;
}
else if (sc.Compare("GotoTitle"))
{
desc = new FIntermissionAction;
desc->mClass = TITLE_ID;
}
else
{
sc.ScriptMessage("Unknown intermission type '%s'", sc.String);
}
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
{
bool success = false;
if (!sc.CheckToken(TK_Sound))
{
sc.MustGetToken(TK_Identifier);
}
if (desc != NULL)
{
success = desc->ParseKey(sc);
if (!success)
{
sc.ScriptMessage("Unknown key name '%s'\n", sc.String);
}
}
if (!success) SkipToNext();
}
return desc;
}
//==========================================================================
//
// ParseIntermission
//
//==========================================================================
void FMapInfoParser::ParseIntermission()
{
sc.MustGetString();
FName intname = sc.String;
FIntermissionDescriptor ** pDesc = IntermissionDescriptors.CheckKey(intname);
if (pDesc != NULL && *pDesc != NULL) delete *pDesc;
FIntermissionDescriptor *desc = new FIntermissionDescriptor();
IntermissionDescriptors[intname] = desc;
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
{
FIntermissionAction *ac = ParseIntermissionAction();
if (ac != NULL) desc->mActions.Push(ac);
}
}
//==========================================================================
//
// Parse old style endsequence
//
//==========================================================================
struct EndSequence
{
@ -383,6 +611,12 @@ FName FMapInfoParser::ParseEndGame()
return FName(seq);
}
//==========================================================================
//
// Checks map name for end sequence
//
//==========================================================================
FName FMapInfoParser::CheckEndSequence()
{
const char *seqname = NULL;

View file

@ -1,5 +1,5 @@
// MAPINFO for Chex Quest
#include "mapinfo/common.txt"
include "mapinfo/common.txt"
gameinfo
{

View file

@ -27,7 +27,7 @@ Intermission Inter_Bunny
{
Scroller
{
FadeType = Right
ScrollDirection = Right
Background = "PFUB1"
Background2 = "PFUB2"
Music = "$MUSIC_BUNNY"
@ -94,8 +94,7 @@ Intermission Inter_Underwater
{
Image
{
Background = "E2END"
Palette = "E2PAL"
Background = "E2END", 0, "E2PAL"
Time = 10000000 // advance only manually
}
GotoTitle
@ -107,7 +106,7 @@ Intermission Inter_Demonscroll
{
Scroller
{
FadeType = Up
ScrollDirection = Up
Background = "FINAL1"
Background2 = "FINAL2"
InitialDelay = 2
@ -119,7 +118,7 @@ Intermission Inter_BuyStrife
{
Scroller
{
FadeType = Right
ScrollDirection = Right
Background = "CREDIT"
Background2 = "VELLOGO"
InitialDelay = -230
@ -131,125 +130,126 @@ Intermission Inter_Cast
{
Image
{
// This is only here to initialize the background
// This is only here to initialize the background and the music
Background = "$bgcastcall"
Time = -1
Music = "$MUSIC_EVIL"
Link = Doom2Cast
}
}
Intermission Doom2Cast
{
Cast
{
Class = "Zombieman"
Name = "$CC_ZOMBIE"
Sound = "Missile", 1, "grunt/attack"
CastClass = "Zombieman"
CastName = "$CC_ZOMBIE"
AttackSound = "Missile", 1, "grunt/attack"
}
Cast
{
Class = "ShotgunGuy"
Name = "$CC_SHOTGUN"
Sound = "Missile", 1, "shotguy/attack"
CastClass = "ShotgunGuy"
CastName = "$CC_SHOTGUN"
AttackSound = "Missile", 1, "shotguy/attack"
}
Cast
{
Class = "ChaingunGuy"
Name = "$CC_HEAVY"
Sound = "Missile", 1, "chainguy/attack"
Sound = "Missile", 2, "chainguy/attack"
Sound = "Missile", 3, "chainguy/attack"
CastClass = "ChaingunGuy"
CastName = "$CC_HEAVY"
AttackSound = "Missile", 1, "chainguy/attack"
AttackSound = "Missile", 2, "chainguy/attack"
AttackSound = "Missile", 3, "chainguy/attack"
}
Cast
{
Class = "DoomImp"
Name = "$CC_IMP"
Sound = "Missile", 2, "imp/attack"
CastClass = "DoomImp"
CastName = "$CC_IMP"
AttackSound = "Missile", 2, "imp/attack"
}
Cast
{
Class = "Demon"
Name = "$CC_DEMON"
Sound = "Melee", 1, "demon/melee"
CastClass = "Demon"
CastName = "$CC_DEMON"
AttackSound = "Melee", 1, "demon/melee"
}
Cast
{
Class = "LostSoul"
Name = "$CC_LOST"
Sound = "Missile", 1, "grunt/attack"
CastClass = "LostSoul"
CastName = "$CC_LOST"
AttackSound = "Missile", 1, "grunt/attack"
}
Cast
{
Class = "Cacodemon"
Name = "$CC_CACO"
Sound = "Missile", 1, "caco/attack"
CastClass = "Cacodemon"
CastName = "$CC_CACO"
AttackSound = "Missile", 1, "caco/attack"
}
Cast
{
Class = "HellKnight"
Name = "$CC_HELL"
Sound = "Missile", 1, "baron/attack"
CastClass = "HellKnight"
CastName = "$CC_HELL"
AttackSound = "Missile", 1, "baron/attack"
}
Cast
{
Class = "BaronOfHell"
Name = "$CC_BARON"
Sound = "Missile", 1, "baron/attack"
CastClass = "BaronOfHell"
CastName = "$CC_BARON"
AttackSound = "Missile", 1, "baron/attack"
}
Cast
{
Class = "Arachnotron"
Name = "$CC_ARACH"
Sound = "Missile", 1, "baby/attack"
CastClass = "Arachnotron"
CastName = "$CC_ARACH"
AttackSound = "Missile", 1, "baby/attack"
}
Cast
{
Class = "PainElemental"
Name = "$CC_PAIN"
Sound = "Missile", 2, "skull/melee"
CastClass = "PainElemental"
CastName = "$CC_PAIN"
AttackSound = "Missile", 2, "skull/melee"
}
Cast
{
Class = "Revenant"
Name = "$CC_REVEN"
Sound = "Missile", 1, "skeleton/attack"
Sound = "Melee", 1, "skeleton/swing"
Sound = "Melee", 3, "skeleton/melee"
CastClass = "Revenant"
CastName = "$CC_REVEN"
AttackSound = "Missile", 1, "skeleton/attack"
AttackSound = "Melee", 1, "skeleton/swing"
AttackSound = "Melee", 3, "skeleton/melee"
}
Cast
{
Class = "Fatso"
Name = "$CC_FATSO"
Sound = "Missile", 1, "fatso/attack"
Sound = "Missile", 4, "fatso/attack"
Sound = "Missile", 7, "fatso/attack"
CastClass = "Fatso"
CastName = "$CC_FATSO"
AttackSound = "Missile", 1, "fatso/attack"
AttackSound = "Missile", 4, "fatso/attack"
AttackSound = "Missile", 7, "fatso/attack"
}
Cast
{
Class = "Archvile"
Name = "$CC_ARCH"
Sound = "Missile", 1, "vile/start"
CastClass = "Archvile"
CastName = "$CC_ARCH"
AttackSound = "Missile", 1, "vile/start"
}
Cast
{
Class = "SpiderMastermind"
Name = "$CC_SPIDER"
Sound = "Missile", 1, "spider/attack"
Sound = "Missile", 2, "spider/attack"
CastClass = "SpiderMastermind"
CastName = "$CC_SPIDER"
AttackSound = "Missile", 1, "spider/attack"
AttackSound = "Missile", 2, "spider/attack"
}
Cast
{
Class = "Cyberdemon"
Name = "$CC_CYBER"
Sound = "Missile", 1, "weapons/rocklf"
Sound = "Missile", 3, "weapons/rocklf"
Sound = "Missile", 5, "weapons/rocklf"
CastClass = "Cyberdemon"
CastName = "$CC_CYBER"
AttackSound = "Missile", 1, "weapons/rocklf"
AttackSound = "Missile", 3, "weapons/rocklf"
AttackSound = "Missile", 5, "weapons/rocklf"
}
Cast
{
Class = "DoomPlayer"
Name = "$CC_HERO"
Sound = "Missile", 0, "weapons/sshotf"
CastClass = "DoomPlayer"
CastName = "$CC_HERO"
AttackSound = "Missile", 0, "weapons/sshotf"
Link = Doom2Cast // restart cast call
}
}
@ -338,12 +338,14 @@ Intermission Inter_Strife_Good
Background = "SS4F4"
Time = 28
}
Fader
Wiper
{
WipeType = Crossfade
}
Image
{
Background = "CREDIT"
Music = "D_FAST"
Time = 2
FadeType = Crossfade
Background = "CREDIT"
}
}
@ -369,12 +371,14 @@ Intermission Inter_Strife_Sad
Sound = "svox/ss603a"
Time = 9
}
Fader
Wiper
{
WipeType = Crossfade
}
Image
{
Background = "CREDIT"
Music = "D_FAST"
Time = 2
FadeType = Crossfade
Background = "CREDIT"
}
}
@ -399,12 +403,14 @@ Intermission Inter_Strife_Lose
Sound = "svox/ss503b"
Time = 11
}
Fader
Wiper
{
WipeType = Crossfade
}
Image
{
Background = "CREDIT"
Music = "D_FAST"
Time = 2
FadeType = Crossfade
Background = "CREDIT"
}
}

View file

@ -1,4 +1,4 @@
#include "mapinfo/common.txt"
include "mapinfo/common.txt"
gameinfo
{

View file

@ -1,5 +1,5 @@
// MAPINFO for Heretic (Shareware and Retail)
#include "mapinfo/common.txt"
include "mapinfo/common.txt"
gameinfo
{

View file

@ -1,5 +1,5 @@
// A bare-bones MAPINFO for Hexen.
#include "mapinfo/common.txt"
include "mapinfo/common.txt"
// Most of the MAPINFO is still in hexen.wad.

View file

@ -1,5 +1,5 @@
// MAPINFO for Strife (full version and teaser)
#include "mapinfo/common.txt"
include "mapinfo/common.txt"
gameinfo
{