- Updated lempar.c to v1.31.

- Added .txt files to the list of types (wad, zip, and pk3) that can be
  loaded without listing them after -file.
- Fonts that are created by the ACS setfont command to wrap a texture now
  support animated textures.
- FON2 fonts can now use their full palette for CR_UNTRANSLATED when drawn
  with the hardware 2D path instead of being restricted to the game palette.
- Fixed: Toggling vid_vsync would reset the displayed fullscreen gamma to 1
  on a Radeon 9000.
- Added back the off-by-one palette handling, but in a much more limited
  scope than before. The skipped entry is assumed to always be at 248, and
  it is assumed that all Shader Model 1.4 cards suffer from this. That's
  because all SM1.4 cards are based on variants of the ATI R200 core, and the
  RV250 in a Radeon 9000 craps up like this. I see no reason to assume that
  other flavors of the R200 are any different. (Interesting note: With the
  Radeon 9000, D3DTADDRESS_CLAMP is an invalid address mode when using the
  debug Direct3D 9 runtime, but it works perfectly fine with the retail
  Direct3D 9 runtime.) (Insight: The R200 probably uses bytes for all its
  math inside pixel shaders. That would explain perfectly why I can't use
  constants greater than 1 with PS1.4 and why it can't do an exact mapping to
  every entry in the color palette.
- Fixed: The software shaded drawer did not work for 2D, because its selected
  "color"map was replaced with the identitymap before being used.
- Fixed: I cannot use Printf to output messages before the framebuffer was
  completely setup, meaning that Shader Model 1.4 cards could not change
  resolution.
- I have decided to let remap palettes specify variable alpha values for
  their colors. D3DFB no longer forces them to 255.
- Updated re2c to version 0.12.3.
- Fixed: A_Wander used threshold as a timer, when it should have used
  reactiontime.
- Fixed: A_CustomRailgun would not fire at all for actors without a target
  when the aim parameter was disabled.
- Made the warp command work in multiplayer, again courtesy of Karate Chris.
- Fixed: Trying to spawn a bot while not in a game made for a crashing time.
  (Patch courtesy of Karate Chris.)
- Removed some floating point math from hu_scores.cpp that somebody's GCC
  gave warnings for (not mine, though).
- Fixed: The SBarInfo drawbar command crashed if the sprite image was
  unavailable.
- Fixed: FString::operator=(const char *) did not release its old buffer when
  being assigned to the null string.
- The scanner no longer has an upper limit on the length of strings it
  accepts, though short strings will be faster than long ones.
- Moved all the text scanning functions into a class. Mainly, this means that
  multiple script scanner states can be stored without being forced to do so
  recursively. I think I might be taking advantage of that in the near
  future. Possibly. Maybe.
- Removed some potential buffer overflows from the decal parser.
- Applied Blzut3's SBARINFO update #9:
  * Fixed: When using even length values in drawnumber it would cap to a 98
    value instead of a 99 as intended.
  * The SBarInfo parser can now accept negatives for coordinates. This
    doesn't allow much right now, but later I plan to add better fullscreen
    hud support in which the negatives will be more useful. This also cleans
    up the source a bit since all calls for (x, y) coordinates are with the
    function getCoordinates().
- Added support for stencilling actors.
- Added support for non-black colors specified with DTA_ColorOverlay to the
  software renderer.
- Fixed: The inverse, gold, red, and green fixed colormaps each allocated
  space for 32 different colormaps, even though each only used the first one.
- Added two new blending flags to make reverse subtract blending more useful:
  STYLEF_InvertSource and STYLEF_InvertOverlay. These invert the color that
  gets blended with the background, since that seems like a good idea for
  reverse subtraction. They also work with the other two blending operations.
- Added subtract and reverse subtract blending operations to the renderer.
  Since the ERenderStyle enumeration was getting rather unwieldy, I converted
  it into a new FRenderStyle structure that lets each parameter of the
  blending equation be set separately. This simplified the set up for the
  blend quite a bit, and it means a number of new combinations are available
  by setting the parameters properly.


SVN r710 (trunk)
This commit is contained in:
Randy Heit 2008-01-25 23:57:44 +00:00
parent 67afc9d4fc
commit e5572a1c4e
111 changed files with 10466 additions and 7801 deletions

View file

@ -1,7 +1,96 @@
January 25, 2008
- Lemon is now producing parsers that don't accept anything, so I'm going
back to v1.43 and trying each intermediate version to see where things
went wrong.
January 24, 2008
- Updated Lemon to its latest versions as of today.
(lemon.c: v1.53, lempar.c: v1.31)
- Added .txt files to the list of types (wad, zip, and pk3) that can be
loaded without listing them after -file.
- Fonts that are created by the ACS setfont command to wrap a texture now
support animated textures.
- FON2 fonts can now use their full palette for CR_UNTRANSLATED when drawn
with the hardware 2D path instead of being restricted to the game palette.
January 23, 2008
- Fixed: Toggling vid_vsync would reset the displayed fullscreen gamma to 1
on a Radeon 9000.
- Added back the off-by-one palette handling, but in a much more limited
scope than before. The skipped entry is assumed to always be at 248, and
it is assumed that all Shader Model 1.4 cards suffer from this. That's
because all SM1.4 cards are based on variants of the ATI R200 core, and the
RV250 in a Radeon 9000 craps up like this. I see no reason to assume that
other flavors of the R200 are any different. (Interesting note: With the
Radeon 9000, D3DTADDRESS_CLAMP is an invalid address mode when using the
debug Direct3D 9 runtime, but it works perfectly fine with the retail
Direct3D 9 runtime.) (Insight: The R200 probably uses bytes for all its
math inside pixel shaders. That would explain perfectly why I can't use
constants greater than 1 with PS1.4 and why it can't do an exact mapping to
every entry in the color palette.
- Fixed: The software shaded drawer did not work for 2D, because its selected
"color"map was replaced with the identitymap before being used.
- Fixed: I cannot use Printf to output messages before the framebuffer was
completely setup, meaning that Shader Model 1.4 cards could not change
resolution.
- I have decided to let remap palettes specify variable alpha values for
their colors. D3DFB no longer forces them to 255.
January 22, 2008
- Updated re2c to version 0.12.3.
- Fixed: A_Wander used threshold as a timer, when it should have used
reactiontime.
- Fixed: A_CustomRailgun would not fire at all for actors without a target
when the aim parameter was disabled.
- Made the warp command work in multiplayer, again courtesy of Karate Chris.
- Fixed: Trying to spawn a bot while not in a game made for a crashing time.
(Patch courtesy of Karate Chris.)
January 21, 2008
- Removed some floating point math from hu_scores.cpp that somebody's GCC
gave warnings for (not mine, though).
- Fixed: The SBarInfo drawbar command crashed if the sprite image was
unavailable.
- Fixed: FString::operator=(const char *) did not release its old buffer when
being assigned to the null string.
- The scanner no longer has an upper limit on the length of strings it
accepts, though short strings will be faster than long ones.
- Moved all the text scanning functions into a class. Mainly, this means that
multiple script scanner states can be stored without being forced to do so
recursively. I think I might be taking advantage of that in the near
future. Possibly. Maybe.
- Removed some potential buffer overflows from the decal parser.
January 18, 2008
- Applied Blzut3's SBARINFO update #9:
* Fixed: When using even length values in drawnumber it would cap to a 98
value instead of a 99 as intended.
* The SBarInfo parser can now accept negatives for coordinates. This
doesn't allow much right now, but later I plan to add better fullscreen
hud support in which the negatives will be more useful. This also cleans
up the source a bit since all calls for (x, y) coordinates are with the
function getCoordinates().
- Added support for stencilling actors.
- Added support for non-black colors specified with DTA_ColorOverlay to the
software renderer.
- Fixed: The inverse, gold, red, and green fixed colormaps each allocated
space for 32 different colormaps, even though each only used the first one.
- Added two new blending flags to make reverse subtract blending more useful:
STYLEF_InvertSource and STYLEF_InvertOverlay. These invert the color that
gets blended with the background, since that seems like a good idea for
reverse subtraction. They also work with the other two blending operations.
January 17, 2008
- Added subtract and reverse subtract blending operations to the renderer.
Since the ERenderStyle enumeration was getting rather unwieldy, I converted
it into a new FRenderStyle structure that lets each parameter of the
blending equation be set separately. This simplified the set up for the
blend quite a bit, and it means a number of new combinations are available
by setting the parameters properly.
January 16, 2008 (Changes by Graf Zahl)
- Fixed: The StatusBar pointer was not NULLed after being deleted.
January 15, 2008
- Plugged more leaks in SBARINFO.
- Spawned actors that have MF2_DORMANT set in their default instance now have

View file

@ -40,6 +40,7 @@
#include "info.h"
#include "doomdef.h"
#include "r_blend.h"
//
// NOTES: AActor
@ -330,24 +331,6 @@ enum
MF_STRIFEx8000000 = 0, // seems related to MF_SHADOW
};
enum ERenderStyle
{
STYLE_None, // Do not draw
STYLE_Normal, // Normal; just copy the image to the screen
STYLE_Fuzzy, // Draw silhouette using "fuzz" effect
STYLE_SoulTrans, // Draw translucent with amount in r_transsouls
STYLE_OptFuzzy, // Draw as fuzzy or translucent, based on user preference
STYLE_Stencil, // Fill image interior with alphacolor
// The following styles can affect visibility in P_CheckSight()
STYLE_Translucent=64, // Draw translucent
STYLE_Add, // Draw additive
STYLE_Shaded, // Treat patch data as alpha values for alphacolor
STYLE_TranslucentStencil,
STYLE_Count
};
#define TRANSLUC25 (FRACUNIT/4)
#define TRANSLUC33 (FRACUNIT/3)
#define TRANSLUC50 (FRACUNIT/2)
@ -623,13 +606,13 @@ public:
WORD sprite; // used to find patch_t and flip value
BYTE frame; // sprite frame to draw
fixed_t scaleX, scaleY; // Scaling values; FRACUNIT is normal size
BYTE RenderStyle; // Style to draw this actor with
FRenderStyle RenderStyle; // Style to draw this actor with
DWORD renderflags; // Different rendering flags
int picnum; // Draw this instead of sprite if != 0xffff
SWORD TIDtoHate; // TID of things to hate (0 if none)
DWORD effects; // [RH] see p_effect.h
fixed_t alpha;
DWORD alphacolor; // Color to draw when STYLE_Shaded
DWORD fillcolor; // Color to draw when STYLE_Shaded
// interaction info
fixed_t pitch, roll;

View file

@ -1653,7 +1653,7 @@ void AM_drawThings ()
}
static void DrawMarker (FTexture *tex, fixed_t x, fixed_t y, int yadjust,
INTBOOL flip, fixed_t xscale, fixed_t yscale, int translation, fixed_t alpha, DWORD alphacolor, int renderstyle)
INTBOOL flip, fixed_t xscale, fixed_t yscale, int translation, fixed_t alpha, DWORD fillcolor, FRenderStyle renderstyle)
{
if (tex == NULL || tex->UseType == FTexture::TEX_Null)
{
@ -1673,8 +1673,8 @@ static void DrawMarker (FTexture *tex, fixed_t x, fixed_t y, int yadjust,
DTA_FlipX, flip,
DTA_Translation, TranslationToTable(translation),
DTA_Alpha, alpha,
DTA_FillColor, alphacolor,
DTA_RenderStyle, renderstyle,
DTA_FillColor, fillcolor,
DTA_RenderStyle, DWORD(renderstyle),
TAG_DONE);
}
@ -1684,7 +1684,8 @@ void AM_drawMarks ()
{
if (markpoints[i].x != -1)
{
DrawMarker (TexMan(marknums[i]), markpoints[i].x, markpoints[i].y, -3, 0, FRACUNIT, FRACUNIT, 0, FRACUNIT, 0, STYLE_Normal);
DrawMarker (TexMan(marknums[i]), markpoints[i].x, markpoints[i].y, -3, 0,
FRACUNIT, FRACUNIT, 0, FRACUNIT, 0, LegacyRenderStyles[STYLE_Normal]);
}
}
}
@ -1743,7 +1744,7 @@ void AM_drawAuthorMarkers ()
{
DrawMarker (tex, marked->x >> FRACTOMAPBITS, marked->y >> FRACTOMAPBITS, 0,
flip, mark->scaleX, mark->scaleY, mark->Translation,
mark->alpha, mark->alphacolor, mark->RenderStyle);
mark->alpha, mark->fillcolor, mark->RenderStyle);
}
marked = mark->args[0] != 0 ? it.Next() : NULL;
}

View file

@ -25,6 +25,12 @@ END_POINTERS
CCMD (addbot)
{
if (gamestate != GS_LEVEL && gamestate != GS_INTERMISSION)
{
Printf ("Bots cannot be added when not in a game!\n");
return;
}
if (consoleplayer != Net_Arbitrator)
{
Printf ("Only player %d can add bots\n", Net_Arbitrator + 1);
@ -36,14 +42,7 @@ CCMD (addbot)
Printf ("addbot [botname] : add a bot to the game\n");
return;
}
/*
if (argc == 3) //Used force colornum
{
color = atoi (argv[2]);
if (color<0) color=0;
if (color>10) color=10;
}
*/
if (argv.argc() > 1)
bglobal.SpawnBot (argv[1]);
else

View file

@ -504,6 +504,7 @@ void DCajunMaster::ForgetBots ()
bool DCajunMaster::LoadBots ()
{
FScanner sc;
FString tmp;
bool gotteam = false;
@ -526,19 +527,19 @@ bool DCajunMaster::LoadBots ()
return false;
}
else
SC_OpenFile (SHARE_DIR BOTFILENAME);
sc.OpenFile (SHARE_DIR BOTFILENAME);
}
#endif
else
{
SC_OpenFile (tmp);
sc.OpenFile (tmp);
}
while (SC_GetString ())
while (sc.GetString ())
{
if (!SC_Compare ("{"))
if (!sc.Compare ("{"))
{
SC_ScriptError ("Unexpected token '%s'\n", sc_String);
sc.ScriptError ("Unexpected token '%s'\n", sc.String);
}
botinfo_t *newinfo = new botinfo_t;
@ -550,37 +551,37 @@ bool DCajunMaster::LoadBots ()
for (;;)
{
SC_MustGetString ();
if (SC_Compare ("}"))
sc.MustGetString ();
if (sc.Compare ("}"))
break;
switch (SC_MatchString (BotConfigStrings))
switch (sc.MatchString (BotConfigStrings))
{
case BOTCFG_NAME:
SC_MustGetString ();
sc.MustGetString ();
appendinfo (newinfo->info, "name");
appendinfo (newinfo->info, sc_String);
newinfo->name = copystring (sc_String);
appendinfo (newinfo->info, sc.String);
newinfo->name = copystring (sc.String);
break;
case BOTCFG_AIMING:
SC_MustGetNumber ();
newinfo->skill.aiming = sc_Number;
sc.MustGetNumber ();
newinfo->skill.aiming = sc.Number;
break;
case BOTCFG_PERFECTION:
SC_MustGetNumber ();
newinfo->skill.perfection = sc_Number;
sc.MustGetNumber ();
newinfo->skill.perfection = sc.Number;
break;
case BOTCFG_REACTION:
SC_MustGetNumber ();
newinfo->skill.reaction = sc_Number;
sc.MustGetNumber ();
newinfo->skill.reaction = sc.Number;
break;
case BOTCFG_ISP:
SC_MustGetNumber ();
newinfo->skill.isp = sc_Number;
sc.MustGetNumber ();
newinfo->skill.isp = sc.Number;
break;
case BOTCFG_TEAM:
@ -588,10 +589,10 @@ bool DCajunMaster::LoadBots ()
char teamstr[16];
BYTE teamnum;
SC_MustGetString ();
if (IsNum (sc_String))
sc.MustGetString ();
if (IsNum (sc.String))
{
teamnum = atoi (sc_String);
teamnum = atoi (sc.String);
if (!TEAMINFO_IsValidTeam (teamnum))
{
teamnum = TEAM_None;
@ -602,7 +603,7 @@ bool DCajunMaster::LoadBots ()
teamnum = TEAM_None;
for (int i = 0; i < int(teams.Size()); ++i)
{
if (stricmp (teams[i].name, sc_String) == 0)
if (stricmp (teams[i].name, sc.String) == 0)
{
teamnum = i;
break;
@ -617,13 +618,13 @@ bool DCajunMaster::LoadBots ()
}
default:
if (stricmp (sc_String, "playerclass") == 0)
if (stricmp (sc.String, "playerclass") == 0)
{
gotclass = true;
}
appendinfo (newinfo->info, sc_String);
SC_MustGetString ();
appendinfo (newinfo->info, sc_String);
appendinfo (newinfo->info, sc.String);
sc.MustGetString ();
appendinfo (newinfo->info, sc.String);
break;
}
}
@ -642,10 +643,7 @@ bool DCajunMaster::LoadBots ()
bglobal.botinfo = newinfo;
bglobal.loaded_bots++;
}
SC_Close ();
Printf ("%d bots read from %s\n", bglobal.loaded_bots, BOTFILENAME);
return true;
}

View file

@ -636,16 +636,15 @@ CCMD (r_visibility)
CCMD (warp)
{
if (CheckCheatmode ())
{
return;
}
if (gamestate != GS_LEVEL)
{
Printf ("You can only warp inside a level.\n");
return;
}
if (netgame)
{
Printf ("You cannot warp in a net game!\n");
return;
}
if (argv.argc() != 3)
{
Printf ("Usage: warp <x> <y>\n");

View file

@ -382,10 +382,11 @@ void CreatePath(const char * fn)
}
// [RH] Replaces the escape sequences in a string with actual escaped characters.
// This operation is done in-place.
// This operation is done in-place. The result is the new length of the string.
void strbin (char *str)
int strbin (char *str)
{
char *start;
char *p = str, c;
int i;
@ -468,4 +469,5 @@ void strbin (char *str)
}
}
*str = 0;
return str - start;
}

View file

@ -52,7 +52,7 @@ void FormatGUID (char *text, const GUID &guid);
const char *myasctime ();
void strbin (char *str);
int strbin (char *str);
void CreatePath(const char * fn);

View file

@ -811,7 +811,7 @@ static int PatchThing (int thingy)
int style = FindStyle (Line2);
if (style >= 0)
{
info->RenderStyle = style;
info->RenderStyle = ERenderStyle(style);
hadStyle = true;
}
}

View file

@ -2130,7 +2130,8 @@ void D_DoomMain (void)
DArgs *files = Args.GatherFiles ("-file", ".wad", true);
DArgs *files1 = Args.GatherFiles (NULL, ".zip", false);
DArgs *files2 = Args.GatherFiles (NULL, ".pk3", false);
if (files->NumArgs() > 0 || files1->NumArgs() > 0 || files2->NumArgs() > 0)
DArgs *files3 = Args.GatherFiles (NULL, ".txt", false);
if (files->NumArgs() > 0 || files1->NumArgs() > 0 || files2->NumArgs() > 0 || files3->NumArgs() > 0)
{
// Check for -file in shareware
if (gameinfo.flags & GI_SHAREWARE)
@ -2151,10 +2152,15 @@ void D_DoomMain (void)
{
D_AddWildFile (files2->GetArg (i));
}
for (int i = 0; i < files3->NumArgs(); i++)
{
D_AddWildFile (files3->GetArg (i));
}
}
delete files;
delete files1;
delete files2;
delete files3;
Printf ("W_Init: Init WADfiles.\n");
Wads.InitMultipleFiles (&wadfiles);

View file

@ -48,7 +48,7 @@
FDecalLib DecalLibrary;
static fixed_t ReadScale ();
static fixed_t ReadScale (FScanner &sc);
static TArray<BYTE> DecalTranslations;
// A decal group holds multiple decals and returns one randomly
@ -358,9 +358,8 @@ void FDecalLib::ReadAllDecals ()
while ((lump = Wads.FindLump ("DECALDEF", &lastlump)) != -1)
{
SC_OpenLumpNum (lump, "DECALDEF");
ReadDecals ();
SC_Close ();
FScanner sc(lump, "DECALDEF");
ReadDecals (sc);
}
// Supporting code to allow specifying decals directly in the DECORATE lump
for (i = 0; i < PClass::m_RuntimeActors.Size(); i++)
@ -375,79 +374,79 @@ void FDecalLib::ReadAllDecals ()
}
}
void FDecalLib::ReadDecals ()
void FDecalLib::ReadDecals(FScanner &sc)
{
while (SC_GetString ())
while (sc.GetString())
{
if (SC_Compare ("decal"))
if (sc.Compare("decal"))
{
ParseDecal ();
ParseDecal(sc);
}
else if (SC_Compare ("decalgroup"))
else if (sc.Compare("decalgroup"))
{
ParseDecalGroup ();
ParseDecalGroup(sc);
}
else if (SC_Compare ("generator"))
else if (sc.Compare("generator"))
{
ParseGenerator ();
ParseGenerator(sc);
}
else if (SC_Compare ("fader"))
else if (sc.Compare("fader"))
{
ParseFader ();
ParseFader(sc);
}
else if (SC_Compare ("stretcher"))
else if (sc.Compare("stretcher"))
{
ParseStretcher ();
ParseStretcher(sc);
}
else if (SC_Compare ("slider"))
else if (sc.Compare("slider"))
{
ParseSlider ();
ParseSlider(sc);
}
else if (SC_Compare ("combiner"))
else if (sc.Compare("combiner"))
{
ParseCombiner ();
ParseCombiner(sc);
}
else if (SC_Compare ("colorchanger"))
else if (sc.Compare("colorchanger"))
{
ParseColorchanger ();
ParseColorchanger(sc);
}
else
{
SC_ScriptError (NULL);
sc.MustGetStringName(NULL);
}
}
}
BYTE FDecalLib::GetDecalID ()
BYTE FDecalLib::GetDecalID (FScanner &sc)
{
SC_MustGetString ();
if (!IsNum (sc_String))
sc.MustGetString ();
if (!IsNum (sc.String))
{
SC_UnGet ();
sc.UnGet ();
return 0;
}
else
{
unsigned long num = strtoul (sc_String, NULL, 10);
unsigned long num = strtoul (sc.String, NULL, 10);
if (num < 1 || num > 255)
{
SC_ScriptError ("Decal ID must be between 1 and 255");
sc.MustGetStringName ("Decal ID must be between 1 and 255");
}
return (BYTE)num;
}
}
void FDecalLib::ParseDecal ()
void FDecalLib::ParseDecal (FScanner &sc)
{
char decalName[64];
FString decalName;
BYTE decalNum;
FDecalTemplate newdecal;
int code, picnum;
SC_MustGetString ();
strcpy (decalName, sc_String);
decalNum = GetDecalID ();
SC_MustGetStringName ("{");
sc.MustGetString ();
decalName = sc.String;
decalNum = GetDecalID (sc);
sc.MustGetStringName ("{");
memset (&newdecal, 0, sizeof(newdecal));
newdecal.PicNum = 0xffff;
@ -458,26 +457,26 @@ void FDecalLib::ParseDecal ()
for (;;)
{
SC_MustGetString ();
if (SC_Compare ("}"))
sc.MustGetString ();
if (sc.Compare ("}"))
{
AddDecal (decalName, decalNum, newdecal);
break;
}
switch ((code = SC_MustMatchString (DecalKeywords)))
switch ((code = sc.MustMatchString (DecalKeywords)))
{
case DECAL_XSCALE:
newdecal.ScaleX = ReadScale ();
newdecal.ScaleX = ReadScale (sc);
break;
case DECAL_YSCALE:
newdecal.ScaleY = ReadScale ();
newdecal.ScaleY = ReadScale (sc);
break;
case DECAL_PIC:
SC_MustGetString ();
picnum = TexMan.CheckForTexture (sc_String, FTexture::TEX_Any);
if (picnum < 0 && (picnum = Wads.CheckNumForName (sc_String, ns_graphics)) >= 0)
sc.MustGetString ();
picnum = TexMan.CheckForTexture (sc.String, FTexture::TEX_Any);
if (picnum < 0 && (picnum = Wads.CheckNumForName (sc.String, ns_graphics)) >= 0)
{
picnum = TexMan.CreateTexture (picnum, FTexture::TEX_Decal);
}
@ -489,14 +488,14 @@ void FDecalLib::ParseDecal ()
break;
case DECAL_ADD:
SC_MustGetFloat ();
newdecal.Alpha = (WORD)(32768.f * sc_Float);
sc.MustGetFloat ();
newdecal.Alpha = (WORD)(32768.f * sc.Float);
newdecal.RenderStyle = STYLE_Add;
break;
case DECAL_TRANSLUCENT:
SC_MustGetFloat ();
newdecal.Alpha = (WORD)(32768.f * sc_Float);
sc.MustGetFloat ();
newdecal.Alpha = (WORD)(32768.f * sc.Float);
newdecal.RenderStyle = STYLE_Translucent;
break;
@ -525,9 +524,9 @@ void FDecalLib::ParseDecal ()
break;
case DECAL_SHADE:
SC_MustGetString ();
sc.MustGetString ();
newdecal.RenderStyle = STYLE_Shaded;
newdecal.ShadeColor = V_GetColor (NULL, sc_String);
newdecal.ShadeColor = V_GetColor (NULL, sc.String);
newdecal.ShadeColor |=
ColorMatcher.Pick (RPART(newdecal.ShadeColor),
GPART(newdecal.ShadeColor), BPART(newdecal.ShadeColor)) << 24;
@ -536,42 +535,42 @@ void FDecalLib::ParseDecal ()
case DECAL_COLORS:
DWORD startcolor, endcolor;
SC_MustGetString (); startcolor = V_GetColor (NULL, sc_String);
SC_MustGetString (); endcolor = V_GetColor (NULL, sc_String);
sc.MustGetString (); startcolor = V_GetColor (NULL, sc.String);
sc.MustGetString (); endcolor = V_GetColor (NULL, sc.String);
newdecal.Translation = GenerateTranslation (startcolor, endcolor)->Index;
break;
case DECAL_ANIMATOR:
SC_MustGetString ();
newdecal.Animator = FindAnimator (sc_String);
sc.MustGetString ();
newdecal.Animator = FindAnimator (sc.String);
break;
case DECAL_LOWERDECAL:
SC_MustGetString ();
newdecal.LowerDecal = GetDecalByName (sc_String);
sc.MustGetString ();
newdecal.LowerDecal = GetDecalByName (sc.String);
break;
}
}
}
void FDecalLib::ParseDecalGroup ()
void FDecalLib::ParseDecalGroup (FScanner &sc)
{
char groupName[64];
FString groupName;
BYTE decalNum;
FDecalBase *targetDecal;
FDecalGroup *group;
SC_MustGetString ();
strcpy (groupName, sc_String);
decalNum = GetDecalID ();
SC_MustGetStringName ("{");
sc.MustGetString ();
groupName = sc.String;
decalNum = GetDecalID (sc);
sc.MustGetStringName ("{");
group = new FDecalGroup;
for (;;)
{
SC_MustGetString ();
if (SC_Compare ("}"))
sc.MustGetString ();
if (sc.Compare ("}"))
{
group->Name = groupName;
group->SpawnID = decalNum;
@ -579,44 +578,44 @@ void FDecalLib::ParseDecalGroup ()
break;
}
targetDecal = ScanTreeForName (sc_String, Root);
targetDecal = ScanTreeForName (sc.String, Root);
if (targetDecal == NULL)
{
SC_ScriptError ("%s has not been defined", sc_String);
sc.ScriptError ("%s has not been defined", sc.String);
}
SC_MustGetNumber ();
sc.MustGetNumber ();
group->AddDecal (targetDecal, sc_Number);
group->AddDecal (targetDecal, sc.Number);
}
}
void FDecalLib::ParseGenerator ()
void FDecalLib::ParseGenerator (FScanner &sc)
{
const PClass *type;
FDecalBase *decal;
AActor *actor;
// Get name of generator (actor)
SC_MustGetString ();
type = PClass::FindClass (sc_String);
sc.MustGetString ();
type = PClass::FindClass (sc.String);
if (type == NULL || type->ActorInfo == NULL)
{
SC_ScriptError ("%s is not an actor.", sc_String);
sc.ScriptError ("%s is not an actor.", sc.String);
}
actor = (AActor *)type->Defaults;
// Get name of generated decal
SC_MustGetString ();
if (stricmp (sc_String, "None") == 0)
sc.MustGetString ();
if (stricmp (sc.String, "None") == 0)
{
decal = NULL;
}
else
{
decal = ScanTreeForName (sc_String, Root);
decal = ScanTreeForName (sc.String, Root);
if (decal == NULL)
{
SC_ScriptError ("%s has not been defined.", sc_String);
sc.ScriptError ("%s has not been defined.", sc.String);
}
}
@ -624,19 +623,19 @@ void FDecalLib::ParseGenerator ()
decal->Users.Push (type);
}
void FDecalLib::ParseFader ()
void FDecalLib::ParseFader (FScanner &sc)
{
char faderName[64];
FString faderName;
int startTime = 0, decayTime = 0;
SC_MustGetString ();
strcpy (faderName, sc_String);
SC_MustGetStringName ("{");
sc.MustGetString ();
faderName = sc.String;
sc.MustGetStringName ("{");
for (;;)
{
SC_MustGetString ();
if (SC_Compare ("}"))
sc.MustGetString ();
if (sc.Compare ("}"))
{
FDecalFaderAnim *fader = new FDecalFaderAnim (faderName);
fader->DecayStart = startTime;
@ -644,37 +643,37 @@ void FDecalLib::ParseFader ()
Animators.Push (fader);
break;
}
else if (SC_Compare ("DecayStart"))
else if (sc.Compare ("DecayStart"))
{
SC_MustGetFloat ();
startTime = (int)(sc_Float * TICRATE);
sc.MustGetFloat ();
startTime = (int)(sc.Float * TICRATE);
}
else if (SC_Compare ("DecayTime"))
else if (sc.Compare ("DecayTime"))
{
SC_MustGetFloat ();
decayTime = (int)(sc_Float * TICRATE);
sc.MustGetFloat ();
decayTime = (int)(sc.Float * TICRATE);
}
else
{
SC_ScriptError ("Unknown fader parameter '%s'", sc_String);
sc.ScriptError ("Unknown fader parameter '%s'", sc.String);
}
}
}
void FDecalLib::ParseStretcher ()
void FDecalLib::ParseStretcher (FScanner &sc)
{
char stretcherName[64];
FString stretcherName;
fixed_t goalX = -1, goalY = -1;
int startTime = 0, takeTime = 0;
SC_MustGetString ();
strcpy (stretcherName, sc_String);
SC_MustGetStringName ("{");
sc.MustGetString ();
stretcherName = sc.String;
sc.MustGetStringName ("{");
for (;;)
{
SC_MustGetString ();
if (SC_Compare ("}"))
sc.MustGetString ();
if (sc.Compare ("}"))
{
if (goalX >= 0 || goalY >= 0)
{
@ -687,45 +686,45 @@ void FDecalLib::ParseStretcher ()
}
break;
}
else if (SC_Compare ("StretchStart"))
else if (sc.Compare ("StretchStart"))
{
SC_MustGetFloat ();
startTime = (int)(sc_Float * TICRATE);
sc.MustGetFloat ();
startTime = (int)(sc.Float * TICRATE);
}
else if (SC_Compare ("StretchTime"))
else if (sc.Compare ("StretchTime"))
{
SC_MustGetFloat ();
takeTime = (int)(sc_Float * TICRATE);
sc.MustGetFloat ();
takeTime = (int)(sc.Float * TICRATE);
}
else if (SC_Compare ("GoalX"))
else if (sc.Compare ("GoalX"))
{
goalX = ReadScale ();
goalX = ReadScale (sc);
}
else if (SC_Compare ("GoalY"))
else if (sc.Compare ("GoalY"))
{
goalY = ReadScale ();
goalY = ReadScale (sc);
}
else
{
SC_ScriptError ("Unknown stretcher parameter '%s'", sc_String);
sc.ScriptError ("Unknown stretcher parameter '%s'", sc.String);
}
}
}
void FDecalLib::ParseSlider ()
void FDecalLib::ParseSlider (FScanner &sc)
{
char sliderName[64];
FString sliderName;
fixed_t distX = 0, distY = 0;
int startTime = 0, takeTime = 0;
SC_MustGetString ();
strcpy (sliderName, sc_String);
SC_MustGetStringName ("{");
sc.MustGetString ();
sliderName = sc.String;
sc.MustGetStringName ("{");
for (;;)
{
SC_MustGetString ();
if (SC_Compare ("}"))
sc.MustGetString ();
if (sc.Compare ("}"))
{
if ((/*distX |*/ distY) != 0)
{
@ -738,48 +737,48 @@ void FDecalLib::ParseSlider ()
}
break;
}
else if (SC_Compare ("SlideStart"))
else if (sc.Compare ("SlideStart"))
{
SC_MustGetFloat ();
startTime = (int)(sc_Float * TICRATE);
sc.MustGetFloat ();
startTime = (int)(sc.Float * TICRATE);
}
else if (SC_Compare ("SlideTime"))
else if (sc.Compare ("SlideTime"))
{
SC_MustGetFloat ();
takeTime = (int)(sc_Float * TICRATE);
sc.MustGetFloat ();
takeTime = (int)(sc.Float * TICRATE);
}
else if (SC_Compare ("DistX"))
else if (sc.Compare ("DistX"))
{
SC_MustGetFloat ();
distX = (fixed_t)(sc_Float * FRACUNIT);
Printf ("DistX in slider decal %s is unsupported\n", sliderName);
sc.MustGetFloat ();
distX = (fixed_t)(sc.Float * FRACUNIT);
Printf ("DistX in slider decal %s is unsupported\n", sliderName.GetChars());
}
else if (SC_Compare ("DistY"))
else if (sc.Compare ("DistY"))
{
SC_MustGetFloat ();
distY = (fixed_t)(sc_Float * FRACUNIT);
sc.MustGetFloat ();
distY = (fixed_t)(sc.Float * FRACUNIT);
}
else
{
SC_ScriptError ("Unknown slider parameter '%s'", sc_String);
sc.ScriptError ("Unknown slider parameter '%s'", sc.String);
}
}
}
void FDecalLib::ParseColorchanger ()
void FDecalLib::ParseColorchanger (FScanner &sc)
{
char faderName[64];
FString faderName;
int startTime = 0, decayTime = 0;
PalEntry goal = 0;
SC_MustGetString ();
strcpy (faderName, sc_String);
SC_MustGetStringName ("{");
sc.MustGetString ();
faderName = sc.String;
sc.MustGetStringName ("{");
for (;;)
{
SC_MustGetString ();
if (SC_Compare ("}"))
sc.MustGetString ();
if (sc.Compare ("}"))
{
FDecalColorerAnim *fader = new FDecalColorerAnim (faderName);
fader->DecayStart = startTime;
@ -788,46 +787,46 @@ void FDecalLib::ParseColorchanger ()
Animators.Push (fader);
break;
}
else if (SC_Compare ("FadeStart"))
else if (sc.Compare ("FadeStart"))
{
SC_MustGetFloat ();
startTime = (int)(sc_Float * TICRATE);
sc.MustGetFloat ();
startTime = (int)(sc.Float * TICRATE);
}
else if (SC_Compare ("FadeTime"))
else if (sc.Compare ("FadeTime"))
{
SC_MustGetFloat ();
decayTime = (int)(sc_Float * TICRATE);
sc.MustGetFloat ();
decayTime = (int)(sc.Float * TICRATE);
}
else if (SC_Compare ("Color"))
else if (sc.Compare ("Color"))
{
SC_MustGetString ();
goal = V_GetColor (NULL, sc_String);
sc.MustGetString ();
goal = V_GetColor (NULL, sc.String);
}
else
{
SC_ScriptError ("Unknown color changer parameter '%s'", sc_String);
sc.ScriptError ("Unknown color changer parameter '%s'", sc.String);
}
}
}
void FDecalLib::ParseCombiner ()
void FDecalLib::ParseCombiner (FScanner &sc)
{
char combinerName[64];
FString combinerName;
size_t first = FDecalCombinerAnim::AnimatorList.Size ();
SC_MustGetString ();
strcpy (combinerName, sc_String);
SC_MustGetStringName ("{");
SC_MustGetString ();
while (!SC_Compare ("}"))
sc.MustGetString ();
combinerName = sc.String;
sc.MustGetStringName ("{");
sc.MustGetString ();
while (!sc.Compare ("}"))
{
FDecalAnimator *anim = FindAnimator (sc_String);
FDecalAnimator *anim = FindAnimator (sc.String);
if (anim == NULL)
{
SC_ScriptError ("Undefined animator %s", sc_String);
sc.ScriptError ("Undefined animator %s", sc.String);
}
FDecalCombinerAnim::AnimatorList.Push (anim);
SC_MustGetString ();
sc.MustGetString ();
}
size_t last = FDecalCombinerAnim::AnimatorList.Size ();
@ -1022,7 +1021,7 @@ FDecalBase::~FDecalBase ()
void FDecalTemplate::ApplyToDecal (DBaseDecal *decal, side_t *wall) const
{
if (RenderStyle == STYLE_Shaded)
if (RenderStyle.Flags & STYLEF_ColorIsFixed)
{
decal->SetShade (ShadeColor);
}
@ -1165,11 +1164,6 @@ void DDecalFader::Tick ()
int distanceToEnd = TimeToEndDecay - level.maptime;
int fadeDistance = TimeToEndDecay - TimeToStartDecay;
TheDecal->Alpha = Scale (StartTrans, distanceToEnd, fadeDistance);
if (TheDecal->RenderStyle < STYLE_Translucent)
{
TheDecal->RenderStyle = STYLE_Translucent;
}
}
}
@ -1364,7 +1358,7 @@ void DDecalColorer::Serialize (FArchive &arc)
void DDecalColorer::Tick ()
{
if (TheDecal == NULL || TheDecal->RenderStyle != STYLE_Shaded)
if (TheDecal == NULL || !(TheDecal->RenderStyle.Flags & STYLEF_ColorIsFixed))
{
Destroy ();
}
@ -1413,8 +1407,8 @@ DThinker *FDecalColorerAnim::CreateThinker (DBaseDecal *actor, side_t *wall) con
return Colorer;
}
static fixed_t ReadScale ()
static fixed_t ReadScale (FScanner &sc)
{
SC_MustGetFloat ();
return fixed_t(clamp (sc_Float * FRACUNIT, 256.0, 256.0*FRACUNIT));
sc.MustGetFloat ();
return fixed_t(clamp (sc.Float * FRACUNIT, 256.0, 256.0*FRACUNIT));
}

View file

@ -39,8 +39,9 @@
#include "doomtype.h"
#include "tarray.h"
#include "name.h"
#include "actor.h"
class AActor;
class FScanner;
class FDecalTemplate;
struct FDecalAnimator;
struct PClass;
@ -77,7 +78,7 @@ public:
fixed_t ScaleX, ScaleY;
DWORD ShadeColor;
DWORD Translation;
BYTE RenderStyle;
FRenderStyle RenderStyle;
WORD PicNum;
WORD RenderFlags;
WORD Alpha; // same as (actor->alpha >> 1)
@ -94,7 +95,7 @@ public:
~FDecalLib ();
void Clear ();
void ReadDecals (); // SC_Open() should have just been called
void ReadDecals (FScanner &sc);
void ReadAllDecals ();
const FDecalTemplate *GetDecalByNum (BYTE num) const;
@ -112,15 +113,15 @@ private:
void AddDecal (FDecalBase *decal);
FDecalAnimator *FindAnimator (const char *name);
BYTE GetDecalID ();
void ParseDecal ();
void ParseDecalGroup ();
void ParseGenerator ();
void ParseFader ();
void ParseStretcher ();
void ParseSlider ();
void ParseCombiner ();
void ParseColorchanger ();
BYTE GetDecalID (FScanner &sc);
void ParseDecal (FScanner &sc);
void ParseDecalGroup (FScanner &sc);
void ParseGenerator (FScanner &sc);
void ParseFader (FScanner &sc);
void ParseStretcher (FScanner &sc);
void ParseSlider (FScanner &sc);
void ParseCombiner (FScanner &sc);
void ParseColorchanger (FScanner &sc);
FDecalBase *Root;
FTranslation *Translations;

View file

@ -180,7 +180,7 @@ struct PalEntry
PalEntry (DWORD argb) { *(DWORD *)this = argb; }
operator DWORD () const { return *(DWORD *)this; }
PalEntry &operator= (DWORD other) { *(DWORD *)this = other; return *this; }
PalEntry InverseColor() const { PalEntry nc; nc.a = a; nc.r = 255 - r; nc.g = 255 - g; nc.b = 255 - b; return nc; }
#ifdef WORDS_BIGENDIAN
PalEntry (BYTE ir, BYTE ig, BYTE ib) : a(0), r(ir), g(ig), b(ib) {}
PalEntry (BYTE ia, BYTE ir, BYTE ig, BYTE ib) : a(ia), r(ir), g(ig), b(ib) {}

View file

@ -98,13 +98,13 @@ EXTERN_CVAR (Int, disableautosave)
static int FindEndSequence (int type, const char *picname);
static void SetEndSequence (char *nextmap, int type);
static void InitPlayerClasses ();
static void ParseEpisodeInfo ();
static void ParseEpisodeInfo (FScanner &sc);
static void G_DoParseMapInfo (int lump);
static void SetLevelNum (level_info_t *info, int num);
static void ClearEpisodes ();
static void ClearLevelInfoStrings (level_info_t *linfo);
static void ClearClusterInfoStrings (cluster_info_t *cinfo);
static void ParseSkill ();
static void ParseSkill (FScanner &sc);
static void G_VerifySkill();
static FRandom pr_classchoice ("RandomPlayerClassChoice");
@ -483,7 +483,8 @@ MapInfoHandler ClusterHandlers[] =
{ MITYPE_STRING, cioffset(clustername), 0 },
};
static void ParseMapInfoLower (MapInfoHandler *handlers,
static void ParseMapInfoLower (FScanner &sc,
MapInfoHandler *handlers,
const char *strings[],
level_info_t *levelinfo,
cluster_info_t *clusterinfo,
@ -605,28 +606,29 @@ static void G_DoParseMapInfo (int lump)
int clusterindex;
QWORD levelflags;
FScanner sc(lump, Wads.GetLumpFullName(lump));
SetLevelDefaults (&defaultinfo);
SC_OpenLumpNum (lump, Wads.GetLumpFullName(lump));
HexenHack = false;
while (SC_GetString ())
while (sc.GetString ())
{
switch (SC_MustMatchString (MapInfoTopLevel))
switch (sc.MustMatchString (MapInfoTopLevel))
{
case MITL_DEFAULTMAP:
if (defaultinfo.music != NULL) delete [] defaultinfo.music;
if (defaultinfo.intermusic != NULL) delete [] defaultinfo.intermusic;
SetLevelDefaults (&defaultinfo);
ParseMapInfoLower (MapHandlers, MapInfoMapLevel, &defaultinfo, NULL, defaultinfo.flags);
ParseMapInfoLower (sc, MapHandlers, MapInfoMapLevel, &defaultinfo, NULL, defaultinfo.flags);
break;
case MITL_MAP: // map <MAPNAME> <Nice Name>
levelflags = defaultinfo.flags;
SC_MustGetString ();
if (IsNum (sc_String))
sc.MustGetString ();
if (IsNum (sc.String))
{ // MAPNAME is a number; assume a Hexen wad
int map = atoi (sc_String);
sprintf (sc_String, "MAP%02d", map);
int map = atoi (sc.String);
sprintf (sc.String, "MAP%02d", map);
HexenHack = true;
// Hexen levels are automatically nointermission,
// no auto sound sequences, falling damage,
@ -639,7 +641,7 @@ static void G_DoParseMapInfo (int lump)
| LEVEL_MISSILESACTIVATEIMPACT
| LEVEL_INFINITE_FLIGHT;
}
levelindex = FindWadLevelInfo (sc_String);
levelindex = FindWadLevelInfo (sc.String);
if (levelindex == -1)
{
levelindex = wadlevelinfos.Reserve(1);
@ -662,17 +664,17 @@ static void G_DoParseMapInfo (int lump)
{
levelinfo->WallHorizLight = levelinfo->WallVertLight = 0;
}
uppercopy (levelinfo->mapname, sc_String);
SC_MustGetString ();
if (SC_Compare ("lookup"))
uppercopy (levelinfo->mapname, sc.String);
sc.MustGetString ();
if (sc.Compare ("lookup"))
{
SC_MustGetString ();
ReplaceString (&levelinfo->level_name, sc_String);
sc.MustGetString ();
ReplaceString (&levelinfo->level_name, sc.String);
levelflags |= LEVEL_LOOKUPLEVELNAME;
}
else
{
ReplaceString (&levelinfo->level_name, sc_String);
ReplaceString (&levelinfo->level_name, sc.String);
}
// Set up levelnum now so that you can use Teleport_NewMap specials
// to teleport to maps with standard names without needing a levelnum.
@ -692,7 +694,7 @@ static void G_DoParseMapInfo (int lump)
int mapnum = levelinfo->mapname[3] - '0';
levelinfo->levelnum = epinum*10 + mapnum;
}
ParseMapInfoLower (MapHandlers, MapInfoMapLevel, levelinfo, NULL, levelflags);
ParseMapInfoLower (sc, MapHandlers, MapInfoMapLevel, levelinfo, NULL, levelflags);
// When the second sky is -NOFLAT-, make it a copy of the first sky
if (strcmp (levelinfo->skypic2, "-NOFLAT-") == 0)
{
@ -713,8 +715,8 @@ static void G_DoParseMapInfo (int lump)
break;
case MITL_CLUSTERDEF: // clusterdef <clusternum>
SC_MustGetNumber ();
clusterindex = FindWadClusterInfo (sc_Number);
sc.MustGetNumber ();
clusterindex = FindWadClusterInfo (sc.Number);
if (clusterindex == -1)
{
clusterindex = wadclusterinfos.Reserve(1);
@ -741,20 +743,20 @@ static void G_DoParseMapInfo (int lump)
}
}
memset (clusterinfo, 0, sizeof(cluster_info_t));
clusterinfo->cluster = sc_Number;
ParseMapInfoLower (ClusterHandlers, MapInfoClusterLevel, NULL, clusterinfo, 0);
clusterinfo->cluster = sc.Number;
ParseMapInfoLower (sc, ClusterHandlers, MapInfoClusterLevel, NULL, clusterinfo, 0);
break;
case MITL_EPISODE:
ParseEpisodeInfo ();
ParseEpisodeInfo(sc);
break;
case MITL_CLEAREPISODES:
ClearEpisodes ();
ClearEpisodes();
break;
case MITL_SKILL:
ParseSkill();
ParseSkill(sc);
break;
case MITL_CLEARSKILLS:
@ -763,7 +765,6 @@ static void G_DoParseMapInfo (int lump)
}
}
SC_Close ();
if (defaultinfo.music != NULL)
{
delete [] defaultinfo.music;
@ -833,7 +834,8 @@ static void ClearEpisodes()
EpiDef.numitems = 0;
}
static void ParseMapInfoLower (MapInfoHandler *handlers,
static void ParseMapInfoLower (FScanner &sc,
MapInfoHandler *handlers,
const char *strings[],
level_info_t *levelinfo,
cluster_info_t *clusterinfo,
@ -845,52 +847,52 @@ static void ParseMapInfoLower (MapInfoHandler *handlers,
info = levelinfo ? (BYTE *)levelinfo : (BYTE *)clusterinfo;
while (SC_GetString ())
while (sc.GetString ())
{
if (SC_MatchString (MapInfoTopLevel) != -1)
if (sc.MatchString (MapInfoTopLevel) != -1)
{
SC_UnGet ();
sc.UnGet ();
break;
}
entry = SC_MustMatchString (strings);
entry = sc.MustMatchString (strings);
handler = handlers + entry;
switch (handler->type)
{
case MITYPE_EATNEXT:
SC_MustGetString ();
sc.MustGetString ();
break;
case MITYPE_IGNORE:
break;
case MITYPE_INT:
SC_MustGetNumber ();
*((int *)(info + handler->data1)) = sc_Number;
sc.MustGetNumber ();
*((int *)(info + handler->data1)) = sc.Number;
break;
case MITYPE_FLOAT:
SC_MustGetFloat ();
*((float *)(info + handler->data1)) = sc_Float;
sc.MustGetFloat ();
*((float *)(info + handler->data1)) = sc.Float;
break;
case MITYPE_HEX:
SC_MustGetString ();
*((int *)(info + handler->data1)) = strtoul (sc_String, NULL, 16);
sc.MustGetString ();
*((int *)(info + handler->data1)) = strtoul (sc.String, NULL, 16);
break;
case MITYPE_COLOR:
SC_MustGetString ();
*((DWORD *)(info + handler->data1)) = V_GetColor (NULL, sc_String);
sc.MustGetString ();
*((DWORD *)(info + handler->data1)) = V_GetColor (NULL, sc.String);
break;
case MITYPE_REDIRECT:
SC_MustGetString ();
levelinfo->RedirectType = sc_String;
sc.MustGetString ();
levelinfo->RedirectType = sc.String;
/*
if (levelinfo->RedirectType == NULL ||
!(levelinfo->RedirectType->IsDescendantOf (RUNTIME_CLASS(AInventory))))
{
SC_ScriptError ("%s is not an inventory item", sc_String);
SC_ScriptError ("%s is not an inventory item", sc.String);
}
*/
// Intentional fall-through
@ -899,24 +901,24 @@ static void ParseMapInfoLower (MapInfoHandler *handlers,
EndSequence newSeq;
bool useseq = false;
SC_MustGetString ();
if (IsNum (sc_String))
sc.MustGetString ();
if (IsNum (sc.String))
{
int map = atoi (sc_String);
int map = atoi (sc.String);
if (HexenHack)
{
sprintf (sc_String, "&wt@%02d", map);
sprintf (sc.String, "&wt@%02d", map);
}
else
{
sprintf (sc_String, "MAP%02d", map);
sprintf (sc.String, "MAP%02d", map);
}
}
if (strnicmp (sc_String, "EndGame", 7) == 0)
if (strnicmp (sc.String, "EndGame", 7) == 0)
{
int type;
switch (sc_String[7])
switch (sc.String[7])
{
case '1': type = END_Pic1; break;
case '2': type = END_Pic2; break;
@ -929,47 +931,47 @@ static void ParseMapInfoLower (MapInfoHandler *handlers,
newSeq.EndType = type;
useseq = true;
}
else if (SC_Compare ("endpic"))
else if (sc.Compare ("endpic"))
{
SC_MustGetString ();
sc.MustGetString ();
newSeq.EndType = END_Pic;
strncpy (newSeq.PicName, sc_String, 8);
strncpy (newSeq.PicName, sc.String, 8);
newSeq.PicName[8] = 0;
useseq = true;
}
else if (SC_Compare ("endbunny"))
else if (sc.Compare ("endbunny"))
{
newSeq.EndType = END_Bunny;
useseq = true;
}
else if (SC_Compare ("endcast"))
else if (sc.Compare ("endcast"))
{
newSeq.EndType = END_Cast;
useseq = true;
}
else if (SC_Compare ("enddemon"))
else if (sc.Compare ("enddemon"))
{
newSeq.EndType = END_Demon;
useseq = true;
}
else if (SC_Compare ("endchess"))
else if (sc.Compare ("endchess"))
{
newSeq.EndType = END_Chess;
useseq = true;
}
else if (SC_Compare ("endunderwater"))
else if (sc.Compare ("endunderwater"))
{
newSeq.EndType = END_Underwater;
useseq = true;
}
else if (SC_Compare ("endbuystrife"))
else if (sc.Compare ("endbuystrife"))
{
newSeq.EndType = END_BuyStrife;
useseq = true;
}
else
{
strncpy ((char *)(info + handler->data1), sc_String, 8);
strncpy ((char *)(info + handler->data1), sc.String, 8);
}
if (useseq)
{
@ -985,22 +987,22 @@ static void ParseMapInfoLower (MapInfoHandler *handlers,
}
case MITYPE_LUMPNAME:
SC_MustGetString ();
uppercopy ((char *)(info + handler->data1), sc_String);
sc.MustGetString ();
uppercopy ((char *)(info + handler->data1), sc.String);
flags |= handler->data2;
break;
case MITYPE_SKY:
SC_MustGetString (); // get texture name;
uppercopy ((char *)(info + handler->data1), sc_String);
SC_MustGetFloat (); // get scroll speed
sc.MustGetString (); // get texture name;
uppercopy ((char *)(info + handler->data1), sc.String);
sc.MustGetFloat (); // get scroll speed
if (HexenHack)
{
sc_Float /= 256;
sc.Float /= 256;
}
// Sky scroll speed is specified as pixels per tic, but we
// want pixels per millisecond.
*((float *)(info + handler->data2)) = sc_Float * 35 / 1000;
*((float *)(info + handler->data2)) = sc.Float * 35 / 1000;
break;
case MITYPE_SETFLAG:
@ -1018,18 +1020,18 @@ static void ParseMapInfoLower (MapInfoHandler *handlers,
break;
case MITYPE_CLUSTER:
SC_MustGetNumber ();
*((int *)(info + handler->data1)) = sc_Number;
sc.MustGetNumber ();
*((int *)(info + handler->data1)) = sc.Number;
// If this cluster hasn't been defined yet, add it. This is especially needed
// for Hexen, because it doesn't have clusterdefs. If we don't do this, every
// level on Hexen will sometimes be considered as being on the same hub,
// depending on the check done.
if (FindWadClusterInfo (sc_Number) == -1)
if (FindWadClusterInfo (sc.Number) == -1)
{
unsigned int clusterindex = wadclusterinfos.Reserve(1);
clusterinfo = &wadclusterinfos[clusterindex];
memset (clusterinfo, 0, sizeof(cluster_info_t));
clusterinfo->cluster = sc_Number;
clusterinfo->cluster = sc.Number;
if (gameinfo.gametype == GAME_Hexen)
{
clusterinfo->flags |= CLUSTER_HUB;
@ -1038,36 +1040,36 @@ static void ParseMapInfoLower (MapInfoHandler *handlers,
break;
case MITYPE_STRING:
SC_MustGetString ();
if (SC_Compare ("lookup"))
sc.MustGetString ();
if (sc.Compare ("lookup"))
{
flags |= handler->data2;
SC_MustGetString ();
sc.MustGetString ();
}
ReplaceString ((char **)(info + handler->data1), sc_String);
ReplaceString ((char **)(info + handler->data1), sc.String);
break;
case MITYPE_F1:
SC_MustGetString ();
sc.MustGetString ();
{
char *colon = strchr (sc_String, ':');
char *colon = strchr (sc.String, ':');
if (colon)
{
*colon = 0;
}
ReplaceString ((char **)(info + handler->data1), sc_String);
ReplaceString ((char **)(info + handler->data1), sc.String);
}
break;
case MITYPE_MUSIC:
SC_MustGetString ();
sc.MustGetString ();
{
char *colon = strchr (sc_String, ':');
char *colon = strchr (sc.String, ':');
if (colon)
{
*colon = 0;
}
ReplaceString ((char **)(info + handler->data1), sc_String);
ReplaceString ((char **)(info + handler->data1), sc.String);
*((int *)(info + handler->data2)) = colon ? atoi (colon + 1) : 0;
if (levelinfo != NULL)
{
@ -1078,8 +1080,8 @@ static void ParseMapInfoLower (MapInfoHandler *handlers,
break;
case MITYPE_RELLIGHT:
SC_MustGetNumber ();
*((SBYTE *)(info + handler->data1)) = (SBYTE)clamp (sc_Number / 2, -128, 127);
sc.MustGetNumber ();
*((SBYTE *)(info + handler->data1)) = (SBYTE)clamp (sc.Number / 2, -128, 127);
break;
case MITYPE_CLRBYTES:
@ -1095,29 +1097,29 @@ static void ParseMapInfoLower (MapInfoHandler *handlers,
FSpecialAction *sa = new FSpecialAction;
sa->Next = *so;
*so = sa;
SC_SetCMode(true);
SC_MustGetString();
sa->Type = FName(sc_String);
SC_CheckString(",");
SC_MustGetString();
strlwr(sc_String);
sa->Action = FindLineSpecial(sc_String);
sc.SetCMode(true);
sc.MustGetString();
sa->Type = FName(sc.String);
sc.CheckString(",");
sc.MustGetString();
strlwr(sc.String);
sa->Action = FindLineSpecial(sc.String);
int j = 0;
while (j < 5 && SC_CheckString(","))
while (j < 5 && sc.CheckString(","))
{
SC_MustGetNumber();
sa->Args[j++] = sc_Number;
sc.MustGetNumber();
sa->Args[j++] = sc.Number;
}
SC_SetCMode(false);
sc.SetCMode(false);
}
break;
case MITYPE_COMPATFLAG:
if (!SC_CheckNumber()) sc_Number = 1;
if (!sc.CheckNumber()) sc.Number = 1;
if (levelinfo != NULL)
{
if (sc_Number) levelinfo->compatflags |= (DWORD)handler->data1;
if (sc.Number) levelinfo->compatflags |= (DWORD)handler->data1;
else levelinfo->compatflags &= ~ (DWORD)handler->data1;
levelinfo->compatmask |= (DWORD)handler->data1;
}
@ -1143,7 +1145,7 @@ static void ParseMapInfoLower (MapInfoHandler *handlers,
// noskillmenu
// remove
static void ParseEpisodeInfo ()
static void ParseEpisodeInfo (FScanner &sc)
{
int i;
char map[9];
@ -1155,54 +1157,54 @@ static void ParseEpisodeInfo ()
bool noskill = false;
// Get map name
SC_MustGetString ();
uppercopy (map, sc_String);
sc.MustGetString ();
uppercopy (map, sc.String);
map[8] = 0;
SC_MustGetString ();
if (SC_Compare ("teaser"))
sc.MustGetString ();
if (sc.Compare ("teaser"))
{
SC_MustGetString ();
sc.MustGetString ();
if (gameinfo.flags & GI_SHAREWARE)
{
uppercopy (map, sc_String);
uppercopy (map, sc.String);
}
SC_MustGetString ();
sc.MustGetString ();
}
do
{
if (SC_Compare ("name"))
if (sc.Compare ("name"))
{
SC_MustGetString ();
ReplaceString (&pic, sc_String);
sc.MustGetString ();
ReplaceString (&pic, sc.String);
picisgfx = false;
}
else if (SC_Compare ("picname"))
else if (sc.Compare ("picname"))
{
SC_MustGetString ();
ReplaceString (&pic, sc_String);
sc.MustGetString ();
ReplaceString (&pic, sc.String);
picisgfx = true;
}
else if (SC_Compare ("remove"))
else if (sc.Compare ("remove"))
{
remove = true;
}
else if (SC_Compare ("key"))
else if (sc.Compare ("key"))
{
SC_MustGetString ();
key = sc_String[0];
sc.MustGetString ();
key = sc.String[0];
}
else if (SC_Compare("noskillmenu"))
else if (sc.Compare("noskillmenu"))
{
noskill = true;
}
else
{
SC_UnGet ();
sc.UnGet ();
break;
}
}
while (SC_GetString ());
while (sc.GetString ());
for (i = 0; i < EpiDef.numitems; ++i)
{
@ -3122,7 +3124,7 @@ static void InitPlayerClasses ()
}
static void ParseSkill ()
static void ParseSkill (FScanner &sc)
{
FSkillInfo skill;
@ -3142,106 +3144,106 @@ static void ParseSkill ()
skill.Shortcut = 0;
skill.TextColor = "";
SC_MustGetString();
skill.Name = sc_String;
sc.MustGetString();
skill.Name = sc.String;
while (SC_GetString ())
while (sc.GetString ())
{
if (SC_Compare ("ammofactor"))
if (sc.Compare ("ammofactor"))
{
SC_MustGetFloat ();
skill.AmmoFactor = FLOAT2FIXED(sc_Float);
sc.MustGetFloat ();
skill.AmmoFactor = FLOAT2FIXED(sc.Float);
}
else if (SC_Compare ("doubleammofactor"))
else if (sc.Compare ("doubleammofactor"))
{
SC_MustGetFloat ();
skill.DoubleAmmoFactor = FLOAT2FIXED(sc_Float);
sc.MustGetFloat ();
skill.DoubleAmmoFactor = FLOAT2FIXED(sc.Float);
}
else if (SC_Compare ("damagefactor"))
else if (sc.Compare ("damagefactor"))
{
SC_MustGetFloat ();
skill.DamageFactor = FLOAT2FIXED(sc_Float);
sc.MustGetFloat ();
skill.DamageFactor = FLOAT2FIXED(sc.Float);
}
else if (SC_Compare ("fastmonsters"))
else if (sc.Compare ("fastmonsters"))
{
skill.FastMonsters = true;
}
else if (SC_Compare ("disablecheats"))
else if (sc.Compare ("disablecheats"))
{
skill.DisableCheats = true;
}
else if (SC_Compare ("easybossbrain"))
else if (sc.Compare ("easybossbrain"))
{
skill.EasyBossBrain = true;
}
else if (SC_Compare("autousehealth"))
else if (sc.Compare("autousehealth"))
{
skill.AutoUseHealth = true;
}
else if (SC_Compare("respawntime"))
else if (sc.Compare("respawntime"))
{
SC_MustGetFloat ();
skill.RespawnCounter = int(sc_Float*TICRATE);
sc.MustGetFloat ();
skill.RespawnCounter = int(sc.Float*TICRATE);
}
else if (SC_Compare("Aggressiveness"))
else if (sc.Compare("Aggressiveness"))
{
SC_MustGetFloat ();
skill.Aggressiveness = FRACUNIT - FLOAT2FIXED(clamp<float>(sc_Float, 0,1));
sc.MustGetFloat ();
skill.Aggressiveness = FRACUNIT - FLOAT2FIXED(clamp<float>(sc.Float, 0,1));
}
else if (SC_Compare("SpawnFilter"))
else if (sc.Compare("SpawnFilter"))
{
SC_MustGetString ();
strlwr(sc_String);
if (strstr(sc_String, "easy")) skill.SpawnFilter|=MTF_EASY;
if (strstr(sc_String, "normal")) skill.SpawnFilter|=MTF_NORMAL;
if (strstr(sc_String, "hard")) skill.SpawnFilter|=MTF_HARD;
sc.MustGetString ();
strlwr(sc.String);
if (strstr(sc.String, "easy")) skill.SpawnFilter|=MTF_EASY;
if (strstr(sc.String, "normal")) skill.SpawnFilter|=MTF_NORMAL;
if (strstr(sc.String, "hard")) skill.SpawnFilter|=MTF_HARD;
}
else if (SC_Compare("ACSReturn"))
else if (sc.Compare("ACSReturn"))
{
SC_MustGetNumber ();
skill.ACSReturn = sc_Number;
sc.MustGetNumber ();
skill.ACSReturn = sc.Number;
}
else if (SC_Compare("Name"))
else if (sc.Compare("Name"))
{
SC_MustGetString ();
skill.MenuName = sc_String;
sc.MustGetString ();
skill.MenuName = sc.String;
skill.MenuNameIsLump = false;
}
else if (SC_Compare("PlayerClassName"))
else if (sc.Compare("PlayerClassName"))
{
SC_MustGetString ();
FName pc = sc_String;
SC_MustGetString ();
skill.MenuNamesForPlayerClass[pc]=sc_String;
sc.MustGetString ();
FName pc = sc.String;
sc.MustGetString ();
skill.MenuNamesForPlayerClass[pc]=sc.String;
}
else if (SC_Compare("PicName"))
else if (sc.Compare("PicName"))
{
SC_MustGetString ();
skill.MenuName = sc_String;
sc.MustGetString ();
skill.MenuName = sc.String;
skill.MenuNameIsLump = true;
}
else if (SC_Compare("MustConfirm"))
else if (sc.Compare("MustConfirm"))
{
skill.MustConfirm = true;
if (SC_CheckToken(TK_StringConst))
if (sc.CheckToken(TK_StringConst))
{
skill.MustConfirmText = sc_String;
skill.MustConfirmText = sc.String;
}
}
else if (SC_Compare("Key"))
else if (sc.Compare("Key"))
{
SC_MustGetString();
skill.Shortcut = tolower(sc_String[0]);
sc.MustGetString();
skill.Shortcut = tolower(sc.String[0]);
}
else if (SC_Compare("TextColor"))
else if (sc.Compare("TextColor"))
{
SC_MustGetString();
sc.MustGetString();
skill.TextColor = '[';
skill.TextColor << sc_String << ']';
skill.TextColor << sc.String << ']';
}
else
{
SC_UnGet ();
sc.UnGet ();
break;
}
}

View file

@ -61,28 +61,31 @@ IMPLEMENT_CLASS (DImpactDecal)
DBaseDecal::DBaseDecal ()
: DThinker(STAT_DECAL),
WallNext(0), WallPrev(0), LeftDistance(0), Z(0), ScaleX(FRACUNIT), ScaleY(FRACUNIT), Alpha(FRACUNIT),
AlphaColor(0), Translation(0), PicNum(0xFFFF), RenderFlags(0), RenderStyle(0)
AlphaColor(0), Translation(0), PicNum(0xFFFF), RenderFlags(0)
{
RenderStyle = STYLE_None;
}
DBaseDecal::DBaseDecal (fixed_t z)
: DThinker(STAT_DECAL),
WallNext(0), WallPrev(0), LeftDistance(0), Z(z), ScaleX(FRACUNIT), ScaleY(FRACUNIT), Alpha(FRACUNIT),
AlphaColor(0), Translation(0), PicNum(0xFFFF), RenderFlags(0), RenderStyle(0)
AlphaColor(0), Translation(0), PicNum(0xFFFF), RenderFlags(0)
{
RenderStyle = STYLE_None;
}
DBaseDecal::DBaseDecal (int statnum, fixed_t z)
: DThinker(statnum),
WallNext(0), WallPrev(0), LeftDistance(0), Z(z), ScaleX(FRACUNIT), ScaleY(FRACUNIT), Alpha(FRACUNIT),
AlphaColor(0), Translation(0), PicNum(0xFFFF), RenderFlags(0), RenderStyle(0)
AlphaColor(0), Translation(0), PicNum(0xFFFF), RenderFlags(0)
{
RenderStyle = STYLE_None;
}
DBaseDecal::DBaseDecal (const AActor *basis)
: DThinker(STAT_DECAL),
WallNext(0), WallPrev(0), LeftDistance(0), Z(basis->z), ScaleX(basis->scaleX), ScaleY(basis->scaleY),
Alpha(basis->alpha), AlphaColor(basis->alphacolor), Translation(basis->Translation), PicNum(basis->picnum),
Alpha(basis->alpha), AlphaColor(basis->fillcolor), Translation(basis->Translation), PicNum(basis->picnum),
RenderFlags(basis->renderflags), RenderStyle(basis->RenderStyle)
{
}

View file

@ -101,7 +101,7 @@ static const char * keywords_lock[]={
//
//===========================================================================
static void AddOneKey(Keygroup * keygroup, const PClass * mi)
static void AddOneKey(Keygroup *keygroup, const PClass *mi, FScanner &sc)
{
if (mi)
{
@ -123,12 +123,12 @@ static void AddOneKey(Keygroup * keygroup, const PClass * mi)
}
else
{
SC_ScriptError("'%s' is not an inventory item", sc_String);
sc.ScriptError("'%s' is not an inventory item", sc.String);
}
}
else
{
SC_ScriptError("Unknown item '%s'", sc_String);
sc.ScriptError("Unknown item '%s'", sc.String);
}
}
@ -138,20 +138,20 @@ static void AddOneKey(Keygroup * keygroup, const PClass * mi)
//
//===========================================================================
static Keygroup * ParseKeygroup()
static Keygroup * ParseKeygroup(FScanner &sc)
{
Keygroup * keygroup;
const PClass * mi;
SC_MustGetStringName("{");
keygroup=new Keygroup;
while (!SC_CheckString("}"))
sc.MustGetStringName("{");
keygroup = new Keygroup;
while (!sc.CheckString("}"))
{
SC_MustGetString();
mi=PClass::FindClass(sc_String);
AddOneKey(keygroup, mi);
sc.MustGetString();
mi = PClass::FindClass(sc.String);
AddOneKey(keygroup, mi, sc);
}
if (keygroup->anykeylist.Size()==0)
if (keygroup->anykeylist.Size() == 0)
{
delete keygroup;
return NULL;
@ -182,7 +182,7 @@ static void PrintMessage (const char *str)
//
//===========================================================================
static void ParseLock()
static void ParseLock(FScanner &sc)
{
int i,r,g,b;
int keynum;
@ -191,84 +191,90 @@ static void ParseLock()
Keygroup * keygroup;
const PClass * mi;
SC_MustGetNumber();
keynum=sc_Number;
sc.MustGetNumber();
keynum = sc.Number;
SC_MustGetString();
if (SC_Compare("DOOM"))
sc.MustGetString();
if (sc.Compare("DOOM"))
{
if (gameinfo.gametype != GAME_Doom) keynum=-1;
}
else if (SC_Compare("HERETIC"))
else if (sc.Compare("HERETIC"))
{
if (gameinfo.gametype != GAME_Heretic) keynum=-1;
}
else if (SC_Compare("HEXEN"))
else if (sc.Compare("HEXEN"))
{
if (gameinfo.gametype != GAME_Hexen) keynum=-1;
}
else if (SC_Compare("STRIFE"))
else if (sc.Compare("STRIFE"))
{
if (gameinfo.gametype != GAME_Strife) keynum=-1;
}
else SC_UnGet();
else sc.UnGet();
ignorekey=true;
if (keynum>0 && keynum<255)
ignorekey = true;
if (keynum > 0 && keynum < 255)
{
lock=new Lock;
if (locks[keynum]) delete locks[keynum];
locks[keynum]=lock;
lock = new Lock;
if (locks[keynum])
{
delete locks[keynum];
}
locks[keynum] = lock;
locks[keynum]->locksound = S_FindSound("misc/keytry");
ignorekey=false;
}
else if (keynum!=-1)
else if (keynum != -1)
{
SC_ScriptError("Lock index %d out of range", keynum);
sc.ScriptError("Lock index %d out of range", keynum);
}
SC_MustGetStringName("{");
while (!SC_CheckString("}"))
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
SC_MustGetString();
switch(i=SC_MatchString(keywords_lock))
sc.MustGetString();
switch(i = sc.MatchString(keywords_lock))
{
case 0: // Any
keygroup=ParseKeygroup();
if (keygroup) lock->keylist.Push(keygroup);
keygroup = ParseKeygroup(sc);
if (keygroup)
{
lock->keylist.Push(keygroup);
}
break;
case 1: // message
SC_MustGetString();
lock->message=copystring(sc_String);
sc.MustGetString();
lock->message = copystring(sc.String);
break;
case 2: // remotemsg
SC_MustGetString();
lock->remotemsg=copystring(sc_String);
sc.MustGetString();
lock->remotemsg = copystring(sc.String);
break;
case 3: // mapcolor
SC_MustGetNumber();
r=sc_Number;
SC_MustGetNumber();
g=sc_Number;
SC_MustGetNumber();
b=sc_Number;
lock->rgb=MAKERGB(r,g,b);
sc.MustGetNumber();
r = sc.Number;
sc.MustGetNumber();
g = sc.Number;
sc.MustGetNumber();
b = sc.Number;
lock->rgb = MAKERGB(r,g,b);
break;
case 4: // locksound
SC_MustGetString();
lock->locksound = S_FindSound(sc_String);
sc.MustGetString();
lock->locksound = S_FindSound(sc.String);
break;
default:
mi=PClass::FindClass(sc_String);
mi = PClass::FindClass(sc.String);
if (mi)
{
keygroup=new Keygroup;
AddOneKey(keygroup, mi);
keygroup = new Keygroup;
AddOneKey(keygroup, mi, sc);
if (keygroup)
{
keygroup->anykeylist.ShrinkToFit();
@ -279,8 +285,14 @@ static void ParseLock()
}
}
// copy the messages if the other one does not exist
if (!lock->remotemsg && lock->message) lock->remotemsg = copystring(lock->message);
if (!lock->message && lock->remotemsg) lock->message = copystring(lock->remotemsg);
if (!lock->remotemsg && lock->message)
{
lock->remotemsg = copystring(lock->message);
}
if (!lock->message && lock->remotemsg)
{
lock->message = copystring(lock->remotemsg);
}
lock->keylist.ShrinkToFit();
}
@ -332,24 +344,26 @@ void P_InitKeyMessages()
ClearLocks();
while ((lump = Wads.FindLump ("LOCKDEFS", &lastlump)) != -1)
{
SC_OpenLumpNum (lump, "LOCKDEFS");
while (SC_GetString ())
FScanner sc(lump, "LOCKDEFS");
while (sc.GetString ())
{
if (SC_Compare("LOCK"))
if (sc.Compare("LOCK"))
{
ParseLock();
ParseLock(sc);
}
else if (SC_Compare("CLEARLOCKS"))
else if (sc.Compare("CLEARLOCKS"))
{
// clear all existing lock defintions and key numbers
// clear all existing lock definitions and key numbers
ClearLocks();
}
else
SC_ScriptError("Unknown command %s in LockDef", sc_String);
else
{
sc.ScriptError("Unknown command %s in LockDef", sc.String);
}
}
SC_Close();
sc.Close();
}
keysdone=true;
keysdone = true;
}
//===========================================================================

View file

@ -51,7 +51,7 @@ public:
WORD Translation;
WORD PicNum;
DWORD RenderFlags;
BYTE RenderStyle;
FRenderStyle RenderStyle;
protected:
virtual DBaseDecal *CloneSelf (const FDecalTemplate *tpl, fixed_t x, fixed_t y, fixed_t z, side_s *wall) const;

File diff suppressed because it is too large Load diff

View file

@ -5,6 +5,7 @@
#include "v_collection.h"
class FBarTexture;
class FScanner;
struct SBarInfoCommand; //we need to be able to use this before it is defined.
@ -19,7 +20,7 @@ struct SBarInfoCommand
{
SBarInfoCommand();
~SBarInfoCommand();
void setString(const char* source, int strnum, int maxlength=-1, bool exact=false);
void setString(FScanner &sc, const char* source, int strnum, int maxlength=-1, bool exact=false);
int type;
int special;
@ -52,10 +53,11 @@ struct SBarInfo
int GetGameType() { return gameType; }
void ParseSBarInfo(int lump);
void ParseSBarInfoBlock(SBarInfoBlock &block);
void ParseSBarInfoBlock(FScanner &sc, SBarInfoBlock &block);
void getCoordinates(FScanner &sc, SBarInfoCommand &cmd); //retrieves the next two arguments as x and y.
int newImage(const char* patchname);
void Init();
EColorRange GetTranslation(char* translation);
EColorRange GetTranslation(FScanner &sc, char* translation);
SBarInfo();
SBarInfo(int lumpnum);
~SBarInfo();

View file

@ -928,42 +928,41 @@ void HUD_InitHud()
while ((lump = Wads.FindLump ("ALTHUDCF", &lastlump)) != -1)
{
SC_OpenLumpNum(lump, "ALTHUDCF");
while (SC_GetString())
FScanner sc(lump, "ALTHUDCF");
while (sc.GetString())
{
if (SC_Compare("Health"))
if (sc.Compare("Health"))
{
SC_MustGetString();
int tex = TexMan.AddPatch(sc_String);
if (tex<=0) tex = TexMan.AddPatch(sc_String, ns_sprites);
sc.MustGetString();
int tex = TexMan.AddPatch(sc.String);
if (tex<=0) tex = TexMan.AddPatch(sc.String, ns_sprites);
if (tex>0) healthpic = TexMan[tex];
}
else
{
const PClass * ti = PClass::FindClass(sc_String);
const PClass * ti = PClass::FindClass(sc.String);
if (!ti)
{
Printf("Unknown item class '%s' in ALTHUDCF\n", sc_String);
Printf("Unknown item class '%s' in ALTHUDCF\n", sc.String);
}
else if (!ti->IsDescendantOf(RUNTIME_CLASS(AInventory)))
{
Printf("Invalid item class '%s' in ALTHUDCF\n", sc_String);
Printf("Invalid item class '%s' in ALTHUDCF\n", sc.String);
ti=NULL;
}
SC_MustGetString();
sc.MustGetString();
int tex=0;
if (!SC_Compare("0") && !SC_Compare("NULL") && !SC_Compare(""))
if (!sc.Compare("0") && !sc.Compare("NULL") && !sc.Compare(""))
{
tex = TexMan.AddPatch(sc_String);
if (tex<=0) tex = TexMan.AddPatch(sc_String, ns_sprites);
tex = TexMan.AddPatch(sc.String);
if (tex<=0) tex = TexMan.AddPatch(sc.String, ns_sprites);
}
else tex=-1;
if (ti) const_cast<PClass*>(ti)->Meta.SetMetaInt(HUMETA_AltIcon, tex);
}
}
SC_Close();
}
}

View file

@ -423,7 +423,7 @@ void A_AcolyteBits (AActor *self)
}
else
{
self->RenderStyle = STYLE_None;
self->RenderStyle.BlendOp = STYLEOP_None;
}
}
}

View file

@ -290,7 +290,7 @@ void A_Beacon (AActor *self)
self->flags &= ~MF_SPECIAL;
static_cast<AInventory *>(self)->DropTime = 0;
// Set up the new rebel.
rebel->threshold = 100;
rebel->threshold = BASETHRESHOLD;
rebel->target = NULL;
rebel->flags4 |= MF4_INCOMBAT;
rebel->LastHeard = owner; // Make sure the rebels look for targets

View file

@ -180,7 +180,7 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
}
if (teamplay && deathmatch)
gamestate == GS_INTERMISSION ? y = SCREENHEIGHT / 3.5 : y = SCREENHEIGHT / 16;
gamestate == GS_INTERMISSION ? y = SCREENHEIGHT * 7 / 2 : y = SCREENHEIGHT / 16;
else
gamestate == GS_INTERMISSION ? y = SCREENHEIGHT / 4 : y = SCREENHEIGHT / 16;
@ -216,7 +216,7 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
sprintf (score, "%d", teams[i].score);
screen->SetFont (BigFont);
screen->DrawText (teams[i].GetTextColor (), scorexwidth, gamestate == GS_INTERMISSION ? y / 1.25 : y / 2, score,
screen->DrawText (teams[i].GetTextColor (), scorexwidth, gamestate == GS_INTERMISSION ? y * 4 / 5 : y / 2, score,
DTA_CleanNoMove, true, TAG_DONE);
scorexwidth += SCREENWIDTH / 8;
@ -337,7 +337,7 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int x, int y, int h
if (player->mo->ScoreIcon > 0)
{
screen->DrawTexture (TexMan[player->mo->ScoreIcon], SCREENWIDTH / 2.25, y,
screen->DrawTexture (TexMan[player->mo->ScoreIcon], SCREENWIDTH * 4 / 9, y,
DTA_CleanNoMove, true, TAG_DONE);
}
}

View file

@ -215,7 +215,7 @@ static void ApplyActorDefault (int defnum, const char *datastr, int dataint)
case ADEF_Flags4Clear: actor->flags4 &= ~dataint; break;
case ADEF_Flags5Clear: actor->flags5 &= ~dataint; break;
case ADEF_Alpha: actor->alpha = dataint; break;
case ADEF_RenderStyle: actor->RenderStyle = dataint; break;
case ADEF_RenderStyle: actor->RenderStyle = ERenderStyle(dataint); break;
case ADEF_RenderFlags: actor->renderflags = dataint; break;
case ADEF_Translation: actor->Translation = dataint; break;
case ADEF_MinMissileChance: actor->MinMissileChance = dataint; break;

View file

@ -3338,12 +3338,12 @@ void InitCrosshairsList()
while ((lump = Wads.FindLump("XHAIRS", &lastlump)) != -1)
{
SC_OpenLumpNum(lump, "XHAIRS");
while (SC_GetNumber())
FScanner sc(lump, "XHAIRS");
while (sc.GetNumber())
{
value.value = float(sc_Number);
SC_MustGetString();
value.name = sc_String;
value.value = float(sc.Number);
sc.MustGetString();
value.name = sc.String;
if (value.value != 0)
{ // Check if it already exists. If not, add it.
unsigned int i;
@ -3365,7 +3365,6 @@ void InitCrosshairsList()
}
}
}
SC_Close();
}
VideoItems[CROSSHAIR_INDEX].b.numvalues = float(Crosshairs.Size());
VideoItems[CROSSHAIR_INDEX].e.valuestrings = &Crosshairs[0];

View file

@ -555,20 +555,19 @@ void FBehavior::StaticLoadDefaultModules ()
while ((lump = Wads.FindLump ("LOADACS", &lastlump)) != -1)
{
SC_OpenLumpNum (lump, "LOADACS");
while (SC_GetString())
FScanner sc(lump, "LOADACS");
while (sc.GetString())
{
int acslump = Wads.CheckNumForName (sc_String, ns_acslibrary);
int acslump = Wads.CheckNumForName (sc.String, ns_acslibrary);
if (acslump >= 0)
{
StaticLoadModule (acslump);
}
else
{
Printf ("Could not find autoloaded ACS library %s\n", sc_String);
Printf ("Could not find autoloaded ACS library %s\n", sc.String);
}
}
SC_Close ();
}
}
@ -2200,7 +2199,7 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
break;
case APROP_RenderStyle:
actor->RenderStyle = value;
actor->RenderStyle = ERenderStyle(value);
break;
case APROP_Ambush:
@ -2290,7 +2289,16 @@ int DLevelScript::GetActorProperty (int tid, int property)
case APROP_Speed: return actor->Speed;
case APROP_Damage: return actor->Damage; // Should this call GetMissileDamage() instead?
case APROP_Alpha: return actor->alpha;
case APROP_RenderStyle: return actor->RenderStyle;
case APROP_RenderStyle: for (int style = STYLE_None; style < STYLE_Count; ++style)
{ // Check for a legacy render style that matches.
if (LegacyRenderStyles[style] == actor->RenderStyle)
{
return style;
}
}
// The current render style isn't expressable as a legacy style,
// so pretends it's normal.
return STYLE_Normal;
case APROP_Gravity: return actor->gravity;
case APROP_Ambush: return !!(actor->flags & MF_AMBUSH);
case APROP_ChaseGoal: return !!(actor->flags5 & MF5_CHASEGOAL);

View file

@ -802,7 +802,7 @@ bool EV_SlidingDoor (line_t *line, AActor *actor, int tag, int speed, int delay)
return rtn;
}
void P_ParseAnimatedDoor()
void P_ParseAnimatedDoor(FScanner &sc)
{
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny;
FDoorAnimation anim;
@ -810,8 +810,8 @@ void P_ParseAnimatedDoor()
bool error = false;
int v;
SC_MustGetString();
anim.BaseTexture = TexMan.CheckForTexture (sc_String, FTexture::TEX_Wall, texflags);
sc.MustGetString();
anim.BaseTexture = TexMan.CheckForTexture (sc.String, FTexture::TEX_Wall, texflags);
anim.OpenSound = NULL;
anim.CloseSound = NULL;
@ -820,38 +820,38 @@ void P_ParseAnimatedDoor()
error = true;
}
while (SC_GetString ())
while (sc.GetString ())
{
if (SC_Compare ("opensound"))
if (sc.Compare ("opensound"))
{
SC_MustGetString ();
anim.OpenSound = copystring (sc_String);
sc.MustGetString ();
anim.OpenSound = copystring (sc.String);
}
else if (SC_Compare ("closesound"))
else if (sc.Compare ("closesound"))
{
SC_MustGetString ();
anim.CloseSound = copystring (sc_String);
sc.MustGetString ();
anim.CloseSound = copystring (sc.String);
}
else if (SC_Compare ("pic"))
else if (sc.Compare ("pic"))
{
SC_MustGetString ();
if (IsNum (sc_String))
sc.MustGetString ();
if (IsNum (sc.String))
{
v = atoi(sc_String) + anim.BaseTexture -1;
v = atoi(sc.String) + anim.BaseTexture -1;
}
else
{
v = TexMan.CheckForTexture (sc_String, FTexture::TEX_Wall, texflags);
v = TexMan.CheckForTexture (sc.String, FTexture::TEX_Wall, texflags);
if (v == -1 && anim.BaseTexture >= 0 && !error)
{
SC_ScriptError ("Unknown texture %s", sc_String);
sc.ScriptError ("Unknown texture %s", sc.String);
}
frames.Push (v);
}
}
else
{
SC_UnGet ();
sc.UnGet ();
break;
}
}

View file

@ -1664,8 +1664,6 @@ void A_Look (AActor *actor)
//==========================================================================
void A_Wander (AActor *self)
{
int delta;
// [RH] Strife probably clears this flag somewhere, but I couldn't find where.
// This seems as good a place as any.
self->flags4 &= ~MF4_INCOMBAT;
@ -1673,9 +1671,9 @@ void A_Wander (AActor *self)
if (self->flags4 & MF4_STANDSTILL)
return;
if (self->threshold != 0)
if (self->reactiontime != 0)
{
self->threshold--;
self->reactiontime--;
return;
}
@ -1683,7 +1681,7 @@ void A_Wander (AActor *self)
if (self->movedir < DI_NODIR)
{
self->angle &= (angle_t)(7<<29);
delta = self->angle - (self->movedir << 29);
int delta = self->angle - (self->movedir << 29);
if (delta > 0)
{
self->angle -= ANG90/2;

View file

@ -245,7 +245,7 @@ void AActor::Serialize (FArchive &arc)
}
arc << effects
<< alpha
<< alphacolor
<< fillcolor
<< pitch
<< roll
<< Sector
@ -387,7 +387,7 @@ void AActor::Serialize (FArchive &arc)
touching_sectorlist = NULL;
LinkToWorld (Sector);
AddToHash ();
SetShade (alphacolor);
SetShade (fillcolor);
if (player)
{
if (playeringame[player - players] &&
@ -1125,7 +1125,7 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target)
}
else
{
mo->RenderStyle = deh.ExplosionStyle;
mo->RenderStyle = ERenderStyle(deh.ExplosionStyle);
mo->alpha = deh.ExplosionAlpha;
}
}
@ -2488,12 +2488,12 @@ bool AActor::IsOkayToAttack (AActor *link)
void AActor::SetShade (DWORD rgb)
{
PalEntry *entry = (PalEntry *)&rgb;
alphacolor = rgb | (ColorMatcher.Pick (entry->r, entry->g, entry->b) << 24);
fillcolor = rgb | (ColorMatcher.Pick (entry->r, entry->g, entry->b) << 24);
}
void AActor::SetShade (int r, int g, int b)
{
alphacolor = MAKEARGB(ColorMatcher.Pick (r, g, b), r, g, b);
fillcolor = MAKEARGB(ColorMatcher.Pick (r, g, b), r, g, b);
}
//
@ -2607,6 +2607,7 @@ void AActor::Tick ()
else if (flags & MF_STEALTH)
{
// [RH] Fade a stealth monster in and out of visibility
RenderStyle.Flags &= ~STYLEF_Alpha1;
if (visdir > 0)
{
alpha += 2*FRACUNIT/TICRATE;

View file

@ -493,10 +493,7 @@ sightcounts[0]++;
//
// [RH] Andy Baker's stealth monsters:
// Cannot see an invisible object
if ((flags & 1) == 0 &&
(t2->RenderStyle == STYLE_None ||
(t2->RenderStyle >= STYLE_Translucent && t2->alpha == 0) ||
(t2->renderflags & RF_INVISIBLE)))
if ((flags & 1) == 0 && ((t2->renderflags & RF_INVISIBLE) || !t2->RenderStyle.IsVisible(t2->alpha)))
{ // small chance of an attack being made anyway
if ((bglobal.m_Thinking ? pr_botchecksight() : pr_checksight()) > 50)
{

View file

@ -27,6 +27,8 @@
#include "dsectoreffect.h"
class FScanner;
//jff 2/23/98 identify the special classes that can share sectors
typedef enum
@ -385,7 +387,7 @@ void EV_StartLightFading (int tag, int value, int tics);
bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *quest=NULL);
void P_InitSwitchList ();
void P_ProcessSwitchDef ();
void P_ProcessSwitchDef (FScanner &sc);
//
// P_PLATS
@ -589,7 +591,7 @@ struct FDoorAnimation
char *CloseSound;
};
void P_ParseAnimatedDoor ();
void P_ParseAnimatedDoor (FScanner &sc);
class DAnimatedDoor : public DMovingCeiling
{

View file

@ -107,7 +107,7 @@ struct FSwitchDef
};
static int STACK_ARGS SortSwitchDefs (const void *a, const void *b);
static FSwitchDef *ParseSwitchDef (bool ignoreBad);
static FSwitchDef *ParseSwitchDef (FScanner &sc, bool ignoreBad);
static WORD AddSwitchDef (FSwitchDef *def);
//
@ -211,84 +211,83 @@ static int STACK_ARGS SortSwitchDefs (const void *a, const void *b)
}
// Parse a switch block in ANIMDEFS and add the definitions to SwitchList
void P_ProcessSwitchDef ()
void P_ProcessSwitchDef (FScanner &sc)
{
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny;
char *picname;
FString picname;
FSwitchDef *def1, *def2;
SWORD picnum;
BYTE max;
bool quest = false;
def1 = def2 = NULL;
SC_MustGetString ();
if (SC_Compare ("doom"))
sc.MustGetString ();
if (sc.Compare ("doom"))
{
max = 0;
}
else if (SC_Compare ("heretic"))
else if (sc.Compare ("heretic"))
{
max = 17;
}
else if (SC_Compare ("hexen"))
else if (sc.Compare ("hexen"))
{
max = 33;
}
else if (SC_Compare ("strife"))
else if (sc.Compare ("strife"))
{
max = 49;
}
else if (SC_Compare ("any"))
else if (sc.Compare ("any"))
{
max = 240;
}
else
{
//SC_ScriptError ("Unknown game");
// There is no game specified; just treat as any
max = 240;
SC_UnGet ();
sc.UnGet ();
}
if (max == 0)
{
SC_MustGetNumber ();
max |= sc_Number & 15;
sc.MustGetNumber ();
max |= sc.Number & 15;
}
SC_MustGetString ();
picnum = TexMan.CheckForTexture (sc_String, FTexture::TEX_Wall, texflags);
picname = copystring (sc_String);
while (SC_GetString ())
sc.MustGetString ();
picnum = TexMan.CheckForTexture (sc.String, FTexture::TEX_Wall, texflags);
picname = sc.String;
while (sc.GetString ())
{
if (SC_Compare ("quest"))
if (sc.Compare ("quest"))
{
quest = true;
}
else if (SC_Compare ("on"))
else if (sc.Compare ("on"))
{
if (def1 != NULL)
{
SC_ScriptError ("Switch already has an on state");
sc.ScriptError ("Switch already has an on state");
}
def1 = ParseSwitchDef (picnum == -1);
def1 = ParseSwitchDef (sc, picnum == -1);
}
else if (SC_Compare ("off"))
else if (sc.Compare ("off"))
{
if (def2 != NULL)
{
SC_ScriptError ("Switch already has an off state");
sc.ScriptError ("Switch already has an off state");
}
def2 = ParseSwitchDef (picnum == -1);
def2 = ParseSwitchDef (sc, picnum == -1);
}
else
{
SC_UnGet ();
sc.UnGet ();
break;
}
}
/*
if (def1 == NULL)
{
SC_ScriptError ("Switch must have an on state");
sc.ScriptError ("Switch must have an on state");
}
*/
if (def1 == NULL || picnum == -1 ||
@ -304,7 +303,6 @@ void P_ProcessSwitchDef ()
{
free (def1);
}
delete [] picname;
return;
}
@ -323,15 +321,14 @@ void P_ProcessSwitchDef ()
def2->PreTexture = def1->u.Textures[def1->NumFrames*2+def1->NumFrames-1];
if (def1->PreTexture == def2->PreTexture)
{
SC_ScriptError ("The on state for switch %s must end with a texture other than %s", picname, picname);
sc.ScriptError ("The on state for switch %s must end with a texture other than %s", picname.GetChars(), picname.GetChars());
}
def2->PairIndex = AddSwitchDef (def1);
def1->PairIndex = AddSwitchDef (def2);
def1->QuestPanel = def2->QuestPanel = quest;
delete [] picname;
}
FSwitchDef *ParseSwitchDef (bool ignoreBad)
FSwitchDef *ParseSwitchDef (FScanner &sc, bool ignoreBad)
{
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny;
FSwitchDef *def;
@ -346,45 +343,45 @@ FSwitchDef *ParseSwitchDef (bool ignoreBad)
sound = 0;
bad = false;
while (SC_GetString ())
while (sc.GetString ())
{
if (SC_Compare ("sound"))
if (sc.Compare ("sound"))
{
if (sound != 0)
{
SC_ScriptError ("Switch state already has a sound");
sc.ScriptError ("Switch state already has a sound");
}
SC_MustGetString ();
sound = S_FindSound (sc_String);
sc.MustGetString ();
sound = S_FindSound (sc.String);
}
else if (SC_Compare ("pic"))
else if (sc.Compare ("pic"))
{
if (numframes == MAX_FRAMES)
{
SC_ScriptError ("Switch has too many frames");
sc.ScriptError ("Switch has too many frames");
}
SC_MustGetString ();
picnum = TexMan.CheckForTexture (sc_String, FTexture::TEX_Wall, texflags);
sc.MustGetString ();
picnum = TexMan.CheckForTexture (sc.String, FTexture::TEX_Wall, texflags);
if (picnum < 0 && !ignoreBad)
{
//Printf ("Unknown switch texture %s\n", sc_String);
//Printf ("Unknown switch texture %s\n", sc.String);
bad = true;
}
pics[numframes] = picnum;
SC_MustGetString ();
if (SC_Compare ("tics"))
sc.MustGetString ();
if (sc.Compare ("tics"))
{
SC_MustGetNumber ();
times[numframes] = sc_Number & 65535;
sc.MustGetNumber ();
times[numframes] = sc.Number & 65535;
}
else if (SC_Compare ("rand"))
else if (sc.Compare ("rand"))
{
int min, max;
SC_MustGetNumber ();
min = sc_Number & 65535;
SC_MustGetNumber ();
max = sc_Number & 65535;
sc.MustGetNumber ();
min = sc.Number & 65535;
sc.MustGetNumber ();
max = sc.Number & 65535;
if (min > max)
{
swap (min, max);
@ -393,19 +390,19 @@ FSwitchDef *ParseSwitchDef (bool ignoreBad)
}
else
{
SC_ScriptError ("Must specify a duration for switch frame");
sc.ScriptError ("Must specify a duration for switch frame");
}
numframes++;
}
else
{
SC_UnGet ();
sc.UnGet ();
break;
}
}
if (numframes == 0)
{
SC_ScriptError ("Switch state needs at least one frame");
sc.ScriptError ("Switch state needs at least one frame");
}
if (bad)
{

View file

@ -103,7 +103,7 @@ struct FGenericParse
EGenericType Type;
union {
size_t Offset;
void (*Handler) (int type, void *fields);
void (*Handler) (FScanner &sc, int type, void *fields);
} u;
};
@ -114,16 +114,16 @@ struct FGenericParse
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
static void MakeDefaultTerrain ();
static void ParseOuter ();
static void ParseSplash ();
static void ParseTerrain ();
static void ParseFloor ();
static void ParseOuter (FScanner &sc);
static void ParseSplash (FScanner &sc);
static void ParseTerrain (FScanner &sc);
static void ParseFloor (FScanner &sc);
static int FindSplash (FName name);
static int FindTerrain (FName name);
static void GenericParse (FGenericParse *parser, const char **keywords,
static void GenericParse (FScanner &sc, FGenericParse *parser, const char **keywords,
void *fields, const char *type, FName name);
static void ParseDamage (int keyword, void *fields);
static void ParseFriction (int keyword, void *fields);
static void ParseDamage (FScanner &sc, int keyword, void *fields);
static void ParseFriction (FScanner &sc, int keyword, void *fields);
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
@ -264,9 +264,8 @@ void P_InitTerrainTypes ()
lastlump = 0;
while (-1 != (lump = Wads.FindLump ("TERRAIN", &lastlump)) )
{
SC_OpenLumpNum (lump, "TERRAIN");
ParseOuter ();
SC_Close ();
FScanner sc(lump, "TERRAIN");
ParseOuter (sc);
}
Splashes.ShrinkToFit ();
Terrains.ShrinkToFit ();
@ -294,51 +293,51 @@ static void MakeDefaultTerrain ()
//
//==========================================================================
static void ParseOuter ()
static void ParseOuter (FScanner &sc)
{
int bracedepth = 0;
bool ifskip = false;
while (SC_GetString ())
while (sc.GetString ())
{
if (ifskip)
{
if (bracedepth > 0)
{
if (SC_Compare ("}"))
if (sc.Compare ("}"))
{
bracedepth--;
continue;
}
}
else if (SC_Compare ("endif"))
else if (sc.Compare ("endif"))
{
ifskip = false;
continue;
}
if (SC_Compare ("{"))
if (sc.Compare ("{"))
{
bracedepth++;
}
else if (SC_Compare ("}"))
else if (sc.Compare ("}"))
{
SC_ScriptError ("Too many left braces ('}')");
sc.ScriptError ("Too many left braces ('}')");
}
}
else
{
switch (SC_MustMatchString (OuterKeywords))
switch (sc.MustMatchString (OuterKeywords))
{
case OUT_SPLASH:
ParseSplash ();
ParseSplash (sc);
break;
case OUT_TERRAIN:
ParseTerrain ();
ParseTerrain (sc);
break;
case OUT_FLOOR:
ParseFloor ();
ParseFloor (sc);
break;
case OUT_IFDOOM:
@ -403,15 +402,15 @@ static void SetSplashDefaults (FSplashDef *splashdef)
//
//==========================================================================
void ParseSplash ()
void ParseSplash (FScanner &sc)
{
int splashnum;
FSplashDef *splashdef;
bool isnew = false;
FName name;
SC_MustGetString ();
name = sc_String;
sc.MustGetString ();
name = sc.String;
splashnum = (int)FindSplash (name);
if (splashnum < 0)
{
@ -423,8 +422,8 @@ void ParseSplash ()
}
splashdef = &Splashes[splashnum];
SC_MustGetString ();
if (!SC_Compare ("modify"))
sc.MustGetString ();
if (!sc.Compare ("modify"))
{ // Set defaults
if (!isnew)
{ // New ones already have their defaults set before they're pushed.
@ -433,15 +432,15 @@ void ParseSplash ()
}
else
{
SC_MustGetString();
sc.MustGetString();
}
if (!SC_Compare ("{"))
if (!sc.Compare ("{"))
{
SC_ScriptError ("Expected {");
sc.ScriptError ("Expected {");
}
else
{
GenericParse (SplashParser, SplashKeywords, splashdef, "splash",
GenericParse (sc, SplashParser, SplashKeywords, splashdef, "splash",
splashdef->Name);
}
}
@ -452,13 +451,13 @@ void ParseSplash ()
//
//==========================================================================
void ParseTerrain ()
void ParseTerrain (FScanner &sc)
{
int terrainnum;
FName name;
SC_MustGetString ();
name = sc_String;
sc.MustGetString ();
name = sc.String;
terrainnum = (int)FindTerrain (name);
if (terrainnum < 0)
{
@ -470,8 +469,8 @@ void ParseTerrain ()
}
// Set defaults
SC_MustGetString ();
if (!SC_Compare ("modify"))
sc.MustGetString ();
if (!sc.Compare ("modify"))
{
name = Terrains[terrainnum].Name;
memset (&Terrains[terrainnum], 0, sizeof(FTerrainDef));
@ -480,17 +479,17 @@ void ParseTerrain ()
}
else
{
SC_MustGetString ();
sc.MustGetString ();
}
if (SC_Compare ("{"))
if (sc.Compare ("{"))
{
GenericParse (TerrainParser, TerrainKeywords, &Terrains[terrainnum],
GenericParse (sc, TerrainParser, TerrainKeywords, &Terrains[terrainnum],
"terrain", Terrains[terrainnum].Name);
}
else
{
SC_ScriptError ("Expected {");
sc.ScriptError ("Expected {");
}
}
@ -500,14 +499,14 @@ void ParseTerrain ()
//
//==========================================================================
static void ParseDamage (int keyword, void *fields)
static void ParseDamage (FScanner &sc, int keyword, void *fields)
{
FTerrainDef *def = (FTerrainDef *)fields;
SC_MustGetString ();
sc.MustGetString ();
// Lava is synonymous with Fire here!
if (SC_Compare("Lava")) def->DamageMOD=NAME_Fire;
else def->DamageMOD=sc_String;
if (sc.Compare("Lava")) def->DamageMOD=NAME_Fire;
else def->DamageMOD=sc.String;
}
//==========================================================================
@ -516,17 +515,17 @@ static void ParseDamage (int keyword, void *fields)
//
//==========================================================================
static void ParseFriction (int keyword, void *fields)
static void ParseFriction (FScanner &sc, int keyword, void *fields)
{
FTerrainDef *def = (FTerrainDef *)fields;
fixed_t friction, movefactor;
SC_MustGetFloat ();
sc.MustGetFloat ();
// These calculations should match those in P_SetSectorFriction().
// A friction of 1.0 is equivalent to ORIG_FRICTION.
friction = (fixed_t)(0x1EB8*(sc_Float*100))/0x80 + 0xD001;
friction = (fixed_t)(0x1EB8*(sc.Float*100))/0x80 + 0xD001;
friction = clamp<fixed_t> (friction, 0, FRACUNIT);
if (friction > ORIG_FRICTION) // ice
@ -547,7 +546,7 @@ static void ParseFriction (int keyword, void *fields)
//
//==========================================================================
static void GenericParse (FGenericParse *parser, const char **keywords,
static void GenericParse (FScanner &sc, FGenericParse *parser, const char **keywords,
void *fields, const char *type, FName name)
{
bool notdone = true;
@ -557,8 +556,8 @@ static void GenericParse (FGenericParse *parser, const char **keywords,
do
{
SC_MustGetString ();
keyword = SC_MustMatchString (keywords);
sc.MustGetString ();
keyword = sc.MustMatchString (keywords);
switch (parser[keyword].Type)
{
case GEN_End:
@ -566,69 +565,69 @@ static void GenericParse (FGenericParse *parser, const char **keywords,
break;
case GEN_Fixed:
SC_MustGetFloat ();
SET_FIELD (fixed_t, (fixed_t)(FRACUNIT * sc_Float));
sc.MustGetFloat ();
SET_FIELD (fixed_t, (fixed_t)(FRACUNIT * sc.Float));
break;
case GEN_Sound:
SC_MustGetString ();
val = S_FindSound (sc_String);
sc.MustGetString ();
val = S_FindSound (sc.String);
SET_FIELD (int, val);
if (val == 0)
{
Printf ("Unknown sound %s in %s %s\n",
sc_String, type, name.GetChars());
sc.String, type, name.GetChars());
}
break;
case GEN_Byte:
SC_MustGetNumber ();
SET_FIELD (BYTE, sc_Number);
sc.MustGetNumber ();
SET_FIELD (BYTE, sc.Number);
break;
case GEN_Class:
SC_MustGetString ();
if (SC_Compare ("None"))
sc.MustGetString ();
if (sc.Compare ("None"))
{
info = NULL;
}
else
{
info = PClass::FindClass (sc_String);
info = PClass::FindClass (sc.String);
if (!info->IsDescendantOf (RUNTIME_CLASS(AActor)))
{
Printf ("%s is not an Actor (in %s %s)\n",
sc_String, type, name.GetChars());
sc.String, type, name.GetChars());
info = NULL;
}
else if (info == NULL)
{
Printf ("Unknown actor %s in %s %s\n",
sc_String, type, name.GetChars());
sc.String, type, name.GetChars());
}
}
SET_FIELD (const PClass *, info);
break;
case GEN_Splash:
SC_MustGetString ();
val = FindSplash (sc_String);
sc.MustGetString ();
val = FindSplash (sc.String);
SET_FIELD (int, val);
if (val == -1)
{
Printf ("Splash %s is not defined yet (in %s %s)\n",
sc_String, type, name.GetChars());
sc.String, type, name.GetChars());
}
break;
case GEN_Float:
SC_MustGetFloat ();
SET_FIELD (float, sc_Float);
sc.MustGetFloat ();
SET_FIELD (float, sc.Float);
break;
case GEN_Time:
SC_MustGetFloat ();
SET_FIELD (int, (int)(sc_Float * TICRATE));
sc.MustGetFloat ();
SET_FIELD (int, (int)(sc.Float * TICRATE));
break;
case GEN_Bool:
@ -636,12 +635,12 @@ static void GenericParse (FGenericParse *parser, const char **keywords,
break;
case GEN_Int:
SC_MustGetNumber ();
SET_FIELD (int, sc_Number);
sc.MustGetNumber ();
SET_FIELD (int, sc.Number);
break;
case GEN_Custom:
parser[keyword].u.Handler (keyword, fields);
parser[keyword].u.Handler (sc, keyword, fields);
break;
}
} while (notdone);
@ -653,24 +652,24 @@ static void GenericParse (FGenericParse *parser, const char **keywords,
//
//==========================================================================
static void ParseFloor ()
static void ParseFloor (FScanner &sc)
{
int picnum;
int terrain;
SC_MustGetString ();
picnum = TexMan.CheckForTexture (sc_String, FTexture::TEX_Flat);
sc.MustGetString ();
picnum = TexMan.CheckForTexture (sc.String, FTexture::TEX_Flat);
if (picnum == -1)
{
Printf ("Unknown flat %s\n", sc_String);
SC_MustGetString ();
Printf ("Unknown flat %s\n", sc.String);
sc.MustGetString ();
return;
}
SC_MustGetString ();
terrain = FindTerrain (sc_String);
sc.MustGetString ();
terrain = FindTerrain (sc.String);
if (terrain == -1)
{
Printf ("Unknown terrain %s\n", sc_String);
Printf ("Unknown terrain %s\n", sc.String);
terrain = 0;
}
TerrainTypes[picnum] = terrain;

View file

@ -435,100 +435,99 @@ void P_ReadSectorSpecials()
lastlump = 0;
while ((lump = Wads.FindLump ("SECTORX", &lastlump)) != -1)
{
SC_OpenLumpNum (lump, "SECTORX");
SC_SetCMode(true);
while (SC_GetString())
FScanner sc(lump, "SECTORX");
sc.SetCMode(true);
while (sc.GetString())
{
if (SC_Compare("IFDOOM"))
if (sc.Compare("IFDOOM"))
{
SC_MustGetStringName("{");
sc.MustGetStringName("{");
if (gameinfo.gametype != GAME_Doom)
{
do
{
if (!SC_GetString())
if (!sc.GetString())
{
SC_ScriptError("Unexpected end of file");
sc.ScriptError("Unexpected end of file");
}
}
while (!SC_Compare("}"));
while (!sc.Compare("}"));
}
}
else if (SC_Compare("IFHERETIC"))
else if (sc.Compare("IFHERETIC"))
{
SC_MustGetStringName("{");
sc.MustGetStringName("{");
if (gameinfo.gametype != GAME_Heretic)
{
do
{
if (!SC_GetString())
if (!sc.GetString())
{
SC_ScriptError("Unexpected end of file");
sc.ScriptError("Unexpected end of file");
}
}
while (!SC_Compare("}"));
while (!sc.Compare("}"));
}
}
else if (SC_Compare("IFSTRIFE"))
else if (sc.Compare("IFSTRIFE"))
{
SC_MustGetStringName("{");
sc.MustGetStringName("{");
if (gameinfo.gametype != GAME_Strife)
{
do
{
if (!SC_GetString())
if (!sc.GetString())
{
SC_ScriptError("Unexpected end of file");
sc.ScriptError("Unexpected end of file");
}
}
while (!SC_Compare("}"));
while (!sc.Compare("}"));
}
}
else if (SC_Compare("}"))
else if (sc.Compare("}"))
{
// ignore
}
else if (SC_Compare("BOOMMASK"))
else if (sc.Compare("BOOMMASK"))
{
SC_MustGetNumber();
boommask = sc_Number;
SC_MustGetStringName(",");
SC_MustGetNumber();
boomshift = sc_Number;
sc.MustGetNumber();
boommask = sc.Number;
sc.MustGetStringName(",");
sc.MustGetNumber();
boomshift = sc.Number;
}
else if (SC_Compare("["))
else if (sc.Compare("["))
{
int start;
int end;
SC_MustGetNumber();
start = sc_Number;
SC_MustGetStringName(",");
SC_MustGetNumber();
end = sc_Number;
SC_MustGetStringName("]");
SC_MustGetStringName(":");
SC_MustGetNumber();
for(int j=start;j<=end;j++)
sc.MustGetNumber();
start = sc.Number;
sc.MustGetStringName(",");
sc.MustGetNumber();
end = sc.Number;
sc.MustGetStringName("]");
sc.MustGetStringName(":");
sc.MustGetNumber();
for(int j = start; j <= end; j++)
{
sectortables[!!boommask][j]=sc_Number + j - start;
sectortables[!!boommask][j]=sc.Number + j - start;
}
}
else if (IsNum(sc_String))
else if (IsNum(sc.String))
{
int start;
start = atoi(sc_String);
SC_MustGetStringName(":");
SC_MustGetNumber();
sectortables[!!boommask][start]=sc_Number;
start = atoi(sc.String);
sc.MustGetStringName(":");
sc.MustGetNumber();
sectortables[!!boommask][start] = sc.Number;
}
else
{
SC_ScriptError(NULL);
sc.ScriptError(NULL);
}
}
SC_Close ();
}
}

View file

@ -92,11 +92,11 @@ public:
static void R_InitAnimDefs ();
static void R_AddComplexAnim (int picnum, const TArray<FAnimDef::FAnimFrame> &frames);
static void ParseAnim (bool istex);
static void ParseRangeAnim (int picnum, int usetype, bool missing);
static void ParsePicAnim (int picnum, int usetype, bool missing, TArray<FAnimDef::FAnimFrame> &frames);
static int ParseFramenum (int basepicnum, int usetype, bool allowMissing);
static void ParseTime (DWORD &min, DWORD &max);
static void ParseAnim (FScanner &sc, bool istex);
static void ParseRangeAnim (FScanner &sc, int picnum, int usetype, bool missing);
static void ParsePicAnim (FScanner &sc, int picnum, int usetype, bool missing, TArray<FAnimDef::FAnimFrame> &frames);
static int ParseFramenum (FScanner &sc, int basepicnum, int usetype, bool allowMissing);
static void ParseTime (FScanner &sc, DWORD &min, DWORD &max);
// PUBLIC DATA DEFINITIONS -------------------------------------------------
@ -255,43 +255,43 @@ static void R_InitAnimDefs ()
while ((lump = Wads.FindLump ("ANIMDEFS", &lastlump)) != -1)
{
SC_OpenLumpNum (lump, "ANIMDEFS");
FScanner sc(lump, "ANIMDEFS");
while (SC_GetString ())
while (sc.GetString ())
{
if (SC_Compare ("flat"))
if (sc.Compare ("flat"))
{
ParseAnim (false);
ParseAnim (sc, false);
}
else if (SC_Compare ("texture"))
else if (sc.Compare ("texture"))
{
ParseAnim (true);
ParseAnim (sc, true);
}
else if (SC_Compare ("switch"))
else if (sc.Compare ("switch"))
{
P_ProcessSwitchDef ();
P_ProcessSwitchDef (sc);
}
// [GRB] Added warping type 2
else if (SC_Compare ("warp") || SC_Compare ("warp2"))
else if (sc.Compare ("warp") || sc.Compare ("warp2"))
{
bool isflat = false;
bool type2 = SC_Compare ("warp2"); // [GRB]
SC_MustGetString ();
if (SC_Compare ("flat"))
bool type2 = sc.Compare ("warp2"); // [GRB]
sc.MustGetString ();
if (sc.Compare ("flat"))
{
isflat = true;
SC_MustGetString ();
sc.MustGetString ();
}
else if (SC_Compare ("texture"))
else if (sc.Compare ("texture"))
{
isflat = false;
SC_MustGetString ();
sc.MustGetString ();
}
else
{
SC_ScriptError (NULL);
sc.ScriptError (NULL);
}
int picnum = TexMan.CheckForTexture (sc_String, isflat ? FTexture::TEX_Flat : FTexture::TEX_Wall, texflags);
int picnum = TexMan.CheckForTexture (sc.String, isflat ? FTexture::TEX_Flat : FTexture::TEX_Wall, texflags);
if (picnum != -1)
{
FTexture * warper = TexMan[picnum];
@ -310,31 +310,31 @@ static void R_InitAnimDefs ()
// Warping information is taken from the last warp
// definition for this texture.
warper->bNoDecals = true;
if (SC_GetString ())
if (sc.GetString ())
{
if (SC_Compare ("allowdecals"))
if (sc.Compare ("allowdecals"))
{
warper->bNoDecals = false;
}
else
{
SC_UnGet ();
sc.UnGet ();
}
}
}
}
else if (SC_Compare ("cameratexture"))
else if (sc.Compare ("cameratexture"))
{
int width, height;
int fitwidth, fitheight;
FString picname;
SC_MustGetString ();
picname = sc_String;
SC_MustGetNumber ();
width = sc_Number;
SC_MustGetNumber ();
height = sc_Number;
sc.MustGetString ();
picname = sc.String;
sc.MustGetNumber ();
width = sc.Number;
sc.MustGetNumber ();
height = sc.Number;
int picnum = TexMan.CheckForTexture (picname, FTexture::TEX_Flat, texflags);
FTexture *viewer = new FCanvasTexture (picname, width, height);
if (picnum != -1)
@ -353,32 +353,31 @@ static void R_InitAnimDefs ()
viewer->UseType = FTexture::TEX_Wall;
TexMan.AddTexture (viewer);
}
if (SC_GetString())
if (sc.GetString())
{
if (SC_Compare ("fit"))
if (sc.Compare ("fit"))
{
SC_MustGetNumber ();
fitwidth = sc_Number;
SC_MustGetNumber ();
fitheight = sc_Number;
sc.MustGetNumber ();
fitwidth = sc.Number;
sc.MustGetNumber ();
fitheight = sc.Number;
}
else
{
SC_UnGet ();
sc.UnGet ();
}
}
viewer->SetScaledSize(fitwidth, fitheight);
}
else if (SC_Compare ("animatedDoor"))
else if (sc.Compare ("animatedDoor"))
{
P_ParseAnimatedDoor ();
P_ParseAnimatedDoor (sc);
}
else
{
SC_ScriptError (NULL);
sc.ScriptError (NULL);
}
}
SC_Close ();
}
}
@ -391,7 +390,7 @@ static void R_InitAnimDefs ()
//
//==========================================================================
static void ParseAnim (bool istex)
static void ParseAnim (FScanner &sc, bool istex)
{
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny;
TArray<FAnimDef::FAnimFrame> frames (32);
@ -402,13 +401,13 @@ static void ParseAnim (bool istex)
usetype = istex ? FTexture::TEX_Wall : FTexture::TEX_Flat;
SC_MustGetString ();
if (SC_Compare ("optional"))
sc.MustGetString ();
if (sc.Compare ("optional"))
{
optional = true;
SC_MustGetString ();
sc.MustGetString ();
}
picnum = TexMan.CheckForTexture (sc_String, usetype, texflags);
picnum = TexMan.CheckForTexture (sc.String, usetype, texflags);
if (picnum < 0)
{
@ -418,7 +417,7 @@ static void ParseAnim (bool istex)
}
else
{
Printf (PRINT_BOLD, "ANIMDEFS: Can't find %s\n", sc_String);
Printf (PRINT_BOLD, "ANIMDEFS: Can't find %s\n", sc.String);
}
}
@ -428,9 +427,9 @@ static void ParseAnim (bool istex)
TexMan[picnum]->bNoDecals = true;
}
while (SC_GetString ())
while (sc.GetString ())
{
if (SC_Compare ("allowdecals"))
if (sc.Compare ("allowdecals"))
{
if (picnum >= 0)
{
@ -438,31 +437,31 @@ static void ParseAnim (bool istex)
}
continue;
}
else if (SC_Compare ("range"))
else if (sc.Compare ("range"))
{
if (defined == 2)
{
SC_ScriptError ("You cannot use \"pic\" and \"range\" together in a single animation.");
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.");
sc.ScriptError ("You can only use one \"range\" per animation.");
}
defined = 1;
ParseRangeAnim (picnum, usetype, missing);
ParseRangeAnim (sc, picnum, usetype, missing);
}
else if (SC_Compare ("pic"))
else if (sc.Compare ("pic"))
{
if (defined == 1)
{
SC_ScriptError ("You cannot use \"pic\" and \"range\" together in a single animation.");
sc.ScriptError ("You cannot use \"pic\" and \"range\" together in a single animation.");
}
defined = 2;
ParsePicAnim (picnum, usetype, missing, frames);
ParsePicAnim (sc, picnum, usetype, missing, frames);
}
else
{
SC_UnGet ();
sc.UnGet ();
break;
}
}
@ -473,7 +472,7 @@ static void ParseAnim (bool istex)
{
if (frames.Size() < 2)
{
SC_ScriptError ("Animation needs at least 2 frames");
sc.ScriptError ("Animation needs at least 2 frames");
}
R_AddComplexAnim (picnum, frames);
}
@ -488,14 +487,14 @@ static void ParseAnim (bool istex)
//
//==========================================================================
static void ParseRangeAnim (int picnum, int usetype, bool missing)
static void ParseRangeAnim (FScanner &sc, int picnum, int usetype, bool missing)
{
int type, framenum;
DWORD min, max;
type = FAnimDef::ANIM_Forward;
framenum = ParseFramenum (picnum, usetype, missing);
ParseTime (min, max);
framenum = ParseFramenum (sc, picnum, usetype, missing);
ParseTime (sc, min, max);
if (framenum == picnum || picnum < 0)
{
@ -507,15 +506,15 @@ static void ParseRangeAnim (int picnum, int usetype, bool missing)
TexMan[framenum]->bNoDecals = TexMan[picnum]->bNoDecals;
swap (framenum, picnum);
}
if (SC_GetString())
if (sc.GetString())
{
if (SC_Compare ("Oscillate"))
if (sc.Compare ("Oscillate"))
{
type = type == FAnimDef::ANIM_Forward ? FAnimDef::ANIM_OscillateUp : FAnimDef::ANIM_OscillateDown;
}
else
{
SC_UnGet ();
sc.UnGet ();
}
}
R_AddSimpleAnim (picnum, framenum - picnum + 1, type, min, max - min);
@ -529,13 +528,13 @@ static void ParseRangeAnim (int picnum, int usetype, bool missing)
//
//==========================================================================
static void ParsePicAnim (int picnum, int usetype, bool missing, TArray<FAnimDef::FAnimFrame> &frames)
static void ParsePicAnim (FScanner &sc, int picnum, int usetype, bool missing, TArray<FAnimDef::FAnimFrame> &frames)
{
int framenum;
DWORD min, max;
framenum = ParseFramenum (picnum, usetype, missing);
ParseTime (min, max);
framenum = ParseFramenum (sc, picnum, usetype, missing);
ParseTime (sc, min, max);
if (picnum >= 0)
{
@ -557,22 +556,22 @@ static void ParsePicAnim (int picnum, int usetype, bool missing, TArray<FAnimDef
//
//==========================================================================
static int ParseFramenum (int basepicnum, int usetype, bool allowMissing)
static int ParseFramenum (FScanner &sc, int basepicnum, int usetype, bool allowMissing)
{
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny;
int framenum;
SC_MustGetString ();
if (IsNum (sc_String))
sc.MustGetString ();
if (IsNum (sc.String))
{
framenum = basepicnum + atoi(sc_String) - 1;
framenum = basepicnum + atoi(sc.String) - 1;
}
else
{
framenum = TexMan.CheckForTexture (sc_String, usetype, texflags);
framenum = TexMan.CheckForTexture (sc.String, usetype, texflags);
if (framenum < 0 && !allowMissing)
{
SC_ScriptError ("Unknown texture %s", sc_String);
sc.ScriptError ("Unknown texture %s", sc.String);
}
}
return framenum;
@ -586,24 +585,24 @@ static int ParseFramenum (int basepicnum, int usetype, bool allowMissing)
//
//==========================================================================
static void ParseTime (DWORD &min, DWORD &max)
static void ParseTime (FScanner &sc, DWORD &min, DWORD &max)
{
SC_MustGetString ();
if (SC_Compare ("tics"))
sc.MustGetString ();
if (sc.Compare ("tics"))
{
SC_MustGetFloat ();
min = max = DWORD(sc_Float * 1000 / 35);
sc.MustGetFloat ();
min = max = DWORD(sc.Float * 1000 / 35);
}
else if (SC_Compare ("rand"))
else if (sc.Compare ("rand"))
{
SC_MustGetFloat ();
min = DWORD(sc_Float * 1000 / 35);
SC_MustGetFloat ();
max = DWORD(sc_Float * 1000 / 35);
sc.MustGetFloat ();
min = DWORD(sc.Float * 1000 / 35);
sc.MustGetFloat ();
max = DWORD(sc.Float * 1000 / 35);
}
else
{
SC_ScriptError ("Must specify a duration for animation frame");
sc.ScriptError ("Must specify a duration for animation frame");
}
}

144
src/r_blend.h Normal file
View file

@ -0,0 +1,144 @@
/*
** r_blend.h
** Constants and types for specifying texture blending.
**
**---------------------------------------------------------------------------
** Copyright 2008 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
// Legacy render styles
enum ERenderStyle
{
STYLE_None, // Do not draw
STYLE_Normal, // Normal; just copy the image to the screen
STYLE_Fuzzy, // Draw silhouette using "fuzz" effect
STYLE_SoulTrans, // Draw translucent with amount in r_transsouls
STYLE_OptFuzzy, // Draw as fuzzy or translucent, based on user preference
STYLE_Stencil, // Fill image interior with alphacolor
STYLE_Translucent, // Draw translucent
STYLE_Add, // Draw additive
STYLE_Shaded, // Treat patch data as alpha values for alphacolor
STYLE_TranslucentStencil,
STYLE_Count
};
// Flexible render styles (most possible combinations are supported in software)
enum ERenderOp
{
STYLEOP_None, // Do not draw
STYLEOP_Add, // Add source to destination
STYLEOP_Sub, // Subtract source from destination
STYLEOP_RevSub, // Subtract destination from source
STYLEOP_Fuzz, // Draw fuzzy on top of destination - ignores alpha and color
STYLEOP_FuzzOrAdd, // Draw fuzzy or add, based on user preference
STYLEOP_FuzzOrSub, // Draw fuzzy or subtract, based on user preference
STYLEOP_FuzzOrRevSub, // Draw fuzzy or reverse subtract, based on user preference
};
enum ERenderAlpha
{
STYLEALPHA_Zero, // Blend factor is 0.0
STYLEALPHA_One, // Blend factor is 1.0
STYLEALPHA_Src, // Blend factor is alpha
STYLEALPHA_InvSrc, // Blend factor is 1.0 - alpha
};
enum ERenderFlags
{
// Use value of transsouls as alpha.
STYLEF_TransSoulsAlpha = 1,
// Force alpha to 1. Not the same as STYLEALPHA_One, since that also
// ignores alpha from the texture.
STYLEF_Alpha1 = 2,
// Use red component from grayscale/RGB texture as alpha. If the texture
// is paletted, the palette is ignored and it is treated as grayscale.
// This should generally be combined with STYLEF_ColorIsFixed, since that's
// all the software renderer supports, but hardware acceleration can do
// them separately should you want to do that for some reason.
STYLEF_RedIsAlpha = 4,
// Ignore texture for RGB output. Color comes from fillcolor for actors
// or DTA_FillColor for DrawTexture().
STYLEF_ColorIsFixed = 8,
// Invert source color, either the texture color or the fixed color.
STYLEF_InvertSource = 16,
// Invert overlay color. This is the fade for actors and DTA_ColorOverlay
// for DrawTexture().
STYLEF_InvertOverlay = 32,
// Actors only: Ignore sector fade and fade to black. To fade to white,
// combine this with STYLEF_InvertOverlay.
STYLEF_FadeToBlack = 64,
};
union FRenderStyle
{
struct
{
BYTE BlendOp; // Of ERenderOp type
BYTE SrcAlpha; // Of ERenderAlpha type
BYTE DestAlpha; // Of ERenderAlpha type
BYTE Flags;
};
DWORD AsDWORD;
inline FRenderStyle &operator= (ERenderStyle legacy);
operator DWORD() const { return AsDWORD; }
bool operator==(const FRenderStyle &o) const { return AsDWORD == o.AsDWORD; }
bool IsVisible(fixed_t alpha) const throw();
private:
// Code that compares an actor's render style with a legacy render
// style value should be updated. Making these conversion operators
// private will catch those cases.
operator ERenderStyle() const { return STYLE_Normal; }
operator int() const { return STYLE_Normal; }
};
extern const FRenderStyle LegacyRenderStyles[STYLE_Count];
inline FRenderStyle &FRenderStyle::operator= (ERenderStyle legacy)
{
if (legacy < STYLE_None || legacy >= STYLE_Count)
{
legacy = STYLE_None;
}
*this = LegacyRenderStyles[legacy];
return *this;
}
inline FArchive &operator<< (FArchive &arc, FRenderStyle &style)
{
arc << style.BlendOp << style.SrcAlpha << style.DestAlpha << style.Flags;
return arc;
}

View file

@ -979,7 +979,7 @@ static bool R_CheckBBox (fixed_t *bspcoord) // killough 1/28/98: static
void R_GetExtraLight (int *light, const secplane_t &plane, FExtraLight *el)
{
BYTE *floodcolormap;
FDynamicColormap *floodcolormap;
int floodlight;
bool flooding;
vertex_t **triangle;
@ -1020,7 +1020,7 @@ void R_GetExtraLight (int *light, const secplane_t &plane, FExtraLight *el)
}
else
{
basecolormap = el->Lights[i].Master->ColorMap->Maps;
basecolormap = el->Lights[i].Master->ColorMap;
*light = el->Lights[i].Master->lightlevel;
if (el->Lights[i].bFlooder)
{
@ -1060,13 +1060,13 @@ void R_Subsector (subsector_t *sub)
frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel,
&ceilinglightlevel, false); // killough 4/11/98
basecolormap = frontsector->ColorMap->Maps;
basecolormap = frontsector->ColorMap;
R_GetExtraLight (&ceilinglightlevel, frontsector->ceilingplane, frontsector->ExtraLights);
// [RH] set foggy flag
foggy = level.fadeto || frontsector->ColorMap->Fade || (level.flags & LEVEL_HASFADETABLE);
r_actualextralight = foggy ? 0 : extralight << 4;
basecolormap = frontsector->ColorMap->Maps;
basecolormap = frontsector->ColorMap;
ceilingplane = frontsector->ceilingplane.ZatPoint (viewx, viewy) > viewz ||
frontsector->ceilingpic == skyflatnum ||
(frontsector->CeilingSkyBox != NULL && frontsector->CeilingSkyBox->bAlways) ||
@ -1086,7 +1086,7 @@ void R_Subsector (subsector_t *sub)
frontsector->CeilingSkyBox
) : NULL;
basecolormap = frontsector->ColorMap->Maps;
basecolormap = frontsector->ColorMap;
R_GetExtraLight (&floorlightlevel, frontsector->floorplane, frontsector->ExtraLights);
// killough 3/7/98: Add (x,y) offsets to flats, add deep water check

View file

@ -425,38 +425,38 @@ void FTextureManager::LoadHiresTex()
while ((remapLump = Wads.FindLump("HIRESTEX", &lastLump)) != -1)
{
SC_OpenLumpNum(remapLump, "HIRESTEX");
while (SC_GetString())
FScanner sc(remapLump, "HIRESTEX");
while (sc.GetString())
{
if (SC_Compare("remap")) // remap an existing texture
if (sc.Compare("remap")) // remap an existing texture
{
SC_MustGetString();
sc.MustGetString();
// allow selection by type
if (SC_Compare("wall")) type=FTexture::TEX_Wall, mode=FTextureManager::TEXMAN_Overridable;
else if (SC_Compare("flat")) type=FTexture::TEX_Flat, mode=FTextureManager::TEXMAN_Overridable;
else if (SC_Compare("sprite")) type=FTexture::TEX_Sprite, mode=0;
if (sc.Compare("wall")) type=FTexture::TEX_Wall, mode=FTextureManager::TEXMAN_Overridable;
else if (sc.Compare("flat")) type=FTexture::TEX_Flat, mode=FTextureManager::TEXMAN_Overridable;
else if (sc.Compare("sprite")) type=FTexture::TEX_Sprite, mode=0;
else type = FTexture::TEX_Any, mode = 0;
sc_String[8]=0;
sc.String[8]=0;
tlist.Clear();
int amount = ListTextures(sc_String, tlist);
int amount = ListTextures(sc.String, tlist);
if (amount == 0)
{
int oldtex = AddPatch(sc_String);
int oldtex = AddPatch(sc.String);
if (oldtex >= 0) tlist.Push(oldtex);
}
FName texname = sc_String;
FName texname = sc.String;
SC_MustGetString();
int lumpnum = Wads.CheckNumForFullName(sc_String);
if (lumpnum < 0) lumpnum = Wads.CheckNumForName(sc_String, ns_graphics);
sc.MustGetString();
int lumpnum = Wads.CheckNumForFullName(sc.String);
if (lumpnum < 0) lumpnum = Wads.CheckNumForName(sc.String, ns_graphics);
if (tlist.Size() == 0)
{
Printf("Attempting to remap non-existent texture %s to %s\n",
texname.GetChars(), sc_String);
texname.GetChars(), sc.String);
}
else
{
@ -487,22 +487,22 @@ void FTextureManager::LoadHiresTex()
}
}
}
else if (SC_Compare("define")) // define a new "fake" texture
else if (sc.Compare("define")) // define a new "fake" texture
{
SC_GetString();
memcpy(src, sc_String, 8);
sc.GetString();
memcpy(src, sc.String, 8);
int lumpnum = Wads.CheckNumForFullName(sc_String);
if (lumpnum < 0) lumpnum = Wads.CheckNumForName(sc_String, ns_graphics);
int lumpnum = Wads.CheckNumForFullName(sc.String);
if (lumpnum < 0) lumpnum = Wads.CheckNumForName(sc.String, ns_graphics);
SC_GetString();
is32bit = !!SC_Compare("force32bit");
if (!is32bit) SC_UnGet();
sc.GetString();
is32bit = !!sc.Compare("force32bit");
if (!is32bit) sc.UnGet();
SC_GetNumber();
width = sc_Number;
SC_GetNumber();
height = sc_Number;
sc.GetNumber();
width = sc.Number;
sc.GetNumber();
height = sc.Number;
if (lumpnum>=0)
{
@ -523,7 +523,6 @@ void FTextureManager::LoadHiresTex()
//else Printf("Unable to define hires texture '%s'\n", tex->Name);
}
}
SC_Close();
}
}

View file

@ -860,7 +860,7 @@ struct vissprite_t
fixed_t xiscale; // negative if flipped
fixed_t idepth; // 1/z
fixed_t texturemid;
DWORD AlphaColor;
DWORD FillColor;
lighttable_t *colormap;
sector_t *heightsec; // killough 3/27/98: height sector for underwater/fake ceiling
sector_t *sector; // [RH] sector this sprite is in
@ -869,7 +869,7 @@ struct vissprite_t
FTexture *pic;
short renderflags;
DWORD Translation; // [RH] for color translation
BYTE RenderStyle;
FRenderStyle RenderStyle;
BYTE FakeFlatStat; // [RH] which side of fake/floor ceiling sprite is on
BYTE bSplitSprite; // [RH] Sprite was split by a drawseg
};

View file

@ -111,6 +111,7 @@ fixed_t dc_iscale;
fixed_t dc_texturemid;
fixed_t dc_texturefrac;
int dc_color; // [RH] Color for column filler
DWORD dc_srccolor;
DWORD *dc_srcblend; // [RH] Source and destination
DWORD *dc_destblend; // blending lookups
@ -134,6 +135,23 @@ cycle_t DetailDoubleCycles;
int dc_fillcolor;
BYTE *dc_translation;
BYTE shadetables[NUMCOLORMAPS*16*256];
FDynamicColormap ShadeFakeColormap[16];
BYTE identitymap[256];
// Convert legacy render styles to flexible render styles.
const FRenderStyle LegacyRenderStyles[STYLE_Count] =
{
/* STYLE_None */ {{ STYLEOP_None, }},
/* STYLE_Normal */ {{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, 0 }},
/* STYLE_Fuzzy */ {{ STYLEOP_Fuzz, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_Alpha1 }},
/* STYLE_SoulTrans */ {{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_TransSoulsAlpha }},
/* STYLE_OptFuzzy */ {{ STYLEOP_FuzzOrAdd, STYLEALPHA_Src, STYLEALPHA_InvSrc, 0 }},
/* STYLE_Stencil */ {{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_Alpha1 | STYLEF_ColorIsFixed }},
/* STYLE_Translucent */ {{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, 0 }},
/* STYLE_Add */ {{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_One, 0 }},
/* STYLE_Shaded */ {{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_RedIsAlpha | STYLEF_ColorIsFixed }},
/* STYLE_TranslucentStencil */{{ STYLEOP_Add, STYLEALPHA_Src, STYLEALPHA_InvSrc, STYLEF_ColorIsFixed }},
};
/************************************/
/* */
@ -233,7 +251,7 @@ void R_FillAddColumn (void)
DWORD fg;
bg2rgb = dc_destblend;
fg = dc_srcblend[dc_color];
fg = dc_srccolor;
int pitch = dc_pitch;
do
@ -246,6 +264,103 @@ void R_FillAddColumn (void)
}
void R_FillAddClampColumn (void)
{
int count;
BYTE *dest;
count = dc_count;
if (count <= 0)
return;
dest = dc_dest;
DWORD *bg2rgb;
DWORD fg;
bg2rgb = dc_destblend;
fg = dc_srccolor;
int pitch = dc_pitch;
do
{
DWORD a = fg + bg2rgb[*dest];
DWORD b = a;
a |= 0x01f07c1f;
b &= 0x40100400;
a &= 0x3fffffff;
b = b - (b >> 5);
a |= b;
*dest = RGB32k[0][0][a & (a>>15)];
dest += pitch;
} while (--count);
}
void R_FillSubClampColumn (void)
{
int count;
BYTE *dest;
count = dc_count;
if (count <= 0)
return;
dest = dc_dest;
DWORD *bg2rgb;
DWORD fg;
bg2rgb = dc_destblend;
fg = dc_srccolor | 0x40100400;
int pitch = dc_pitch;
do
{
DWORD a = fg - bg2rgb[*dest];
DWORD b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
*dest = RGB32k[0][0][a & (a>>15)];
dest += pitch;
} while (--count);
}
void R_FillRevSubClampColumn (void)
{
int count;
BYTE *dest;
count = dc_count;
if (count <= 0)
return;
dest = dc_dest;
DWORD *bg2rgb;
DWORD fg;
bg2rgb = dc_destblend;
fg = dc_srccolor;
int pitch = dc_pitch;
do
{
DWORD a = (bg2rgb[*dest] | 0x40100400) - fg;
DWORD b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
*dest = RGB32k[0][0][a & (a>>15)];
dest += pitch;
} while (--count);
}
//
// Spectre/Invisibility.
//
@ -593,8 +708,7 @@ void R_DrawAddClampColumnP_C ()
do
{
DWORD a = fg2rgb[colormap[source[frac>>FRACBITS]]]
+ bg2rgb[*dest];
DWORD a = fg2rgb[colormap[source[frac>>FRACBITS]]] + bg2rgb[*dest];
DWORD b = a;
a |= 0x01f07c1f;
@ -609,7 +723,7 @@ void R_DrawAddClampColumnP_C ()
}
}
// Add source to destination, clamping it to white
// Add translated source to destination, clamping it to white
void R_DrawAddClampTranslatedColumnP_C ()
{
int count;
@ -636,8 +750,7 @@ void R_DrawAddClampTranslatedColumnP_C ()
do
{
DWORD a = fg2rgb[colormap[translation[source[frac>>FRACBITS]]]]
+ bg2rgb[*dest];
DWORD a = fg2rgb[colormap[translation[source[frac>>FRACBITS]]]] + bg2rgb[*dest];
DWORD b = a;
a |= 0x01f07c1f;
@ -652,6 +765,168 @@ void R_DrawAddClampTranslatedColumnP_C ()
}
}
// Subtract destination from source, clamping it to black
void R_DrawSubClampColumnP_C ()
{
int count;
BYTE *dest;
fixed_t frac;
fixed_t fracstep;
count = dc_count;
if (count <= 0)
return;
dest = dc_dest;
fracstep = dc_iscale;
frac = dc_texturefrac;
{
BYTE *colormap = dc_colormap;
const BYTE *source = dc_source;
int pitch = dc_pitch;
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
do
{
DWORD a = (fg2rgb[colormap[source[frac>>FRACBITS]]] | 0x40100400) - bg2rgb[*dest];
DWORD b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
*dest = RGB32k[0][0][a & (a>>15)];
dest += pitch;
frac += fracstep;
} while (--count);
}
}
// Subtract destination from source, clamping it to black
void R_DrawSubClampTranslatedColumnP_C ()
{
int count;
BYTE *dest;
fixed_t frac;
fixed_t fracstep;
count = dc_count;
if (count <= 0)
return;
dest = dc_dest;
fracstep = dc_iscale;
frac = dc_texturefrac;
{
BYTE *translation = dc_translation;
BYTE *colormap = dc_colormap;
const BYTE *source = dc_source;
int pitch = dc_pitch;
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
do
{
DWORD a = (fg2rgb[colormap[translation[source[frac>>FRACBITS]]]] | 0x40100400) - bg2rgb[*dest];
DWORD b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
*dest = RGB32k[0][0][(a>>15) & a];
dest += pitch;
frac += fracstep;
} while (--count);
}
}
// Subtract source from destination, clamping it to black
void R_DrawRevSubClampColumnP_C ()
{
int count;
BYTE *dest;
fixed_t frac;
fixed_t fracstep;
count = dc_count;
if (count <= 0)
return;
dest = dc_dest;
fracstep = dc_iscale;
frac = dc_texturefrac;
{
BYTE *colormap = dc_colormap;
const BYTE *source = dc_source;
int pitch = dc_pitch;
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
do
{
DWORD a = (bg2rgb[*dest] | 0x40100400) - fg2rgb[colormap[source[frac>>FRACBITS]]];
DWORD b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
*dest = RGB32k[0][0][a & (a>>15)];
dest += pitch;
frac += fracstep;
} while (--count);
}
}
// Subtract source from destination, clamping it to black
void R_DrawRevSubClampTranslatedColumnP_C ()
{
int count;
BYTE *dest;
fixed_t frac;
fixed_t fracstep;
count = dc_count;
if (count <= 0)
return;
dest = dc_dest;
fracstep = dc_iscale;
frac = dc_texturefrac;
{
BYTE *translation = dc_translation;
BYTE *colormap = dc_colormap;
const BYTE *source = dc_source;
int pitch = dc_pitch;
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
do
{
DWORD a = (bg2rgb[*dest] | 0x40100400) - fg2rgb[colormap[translation[source[frac>>FRACBITS]]]];
DWORD b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
*dest = RGB32k[0][0][(a>>15) & a];
dest += pitch;
frac += fracstep;
} while (--count);
}
}
//
@ -1198,13 +1473,14 @@ void R_DrawFogBoundary (int x1, int x2, short *uclip, short *dclip)
int b2 = dclip[x];
int rcolormap = GETPALOOKUP (light, wallshade);
int lcolormap;
BYTE *basecolormapdata = basecolormap->Maps;
if (b2 > t2)
{
clearbufshort (spanend+t2, b2-t2, x);
}
dc_colormap = basecolormap + (rcolormap << COLORMAPSHIFT);
dc_colormap = basecolormapdata + (rcolormap << COLORMAPSHIFT);
for (--x; x >= x1; --x)
{
@ -1229,11 +1505,11 @@ void R_DrawFogBoundary (int x1, int x2, short *uclip, short *dclip)
clearbufshort (spanend+t2, b2-t2, x);
}
rcolormap = lcolormap;
dc_colormap = basecolormap + (lcolormap << COLORMAPSHIFT);
dc_colormap = basecolormapdata + (lcolormap << COLORMAPSHIFT);
}
else
{
if (dc_colormap != basecolormap)
if (dc_colormap != basecolormapdata)
{
stop = MIN (t1, b2);
while (t2 < stop)
@ -1406,6 +1682,137 @@ void tmvline4_addclamp ()
} while (--count);
}
fixed_t tmvline1_subclamp ()
{
DWORD fracstep = dc_iscale;
DWORD frac = dc_texturefrac;
BYTE *colormap = dc_colormap;
int count = dc_count;
const BYTE *source = dc_source;
BYTE *dest = dc_dest;
int bits = tmvlinebits;
int pitch = dc_pitch;
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
do
{
BYTE pix = source[frac>>bits];
if (pix != 0)
{
DWORD a = (fg2rgb[colormap[pix]] | 0x40100400) - bg2rgb[*dest];
DWORD b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
*dest = RGB32k[0][0][a & (a>>15)];
}
frac += fracstep;
dest += pitch;
} while (--count);
return frac;
}
void tmvline4_subclamp ()
{
BYTE *dest = dc_dest;
int count = dc_count;
int bits = tmvlinebits;
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
do
{
for (int i = 0; i < 4; ++i)
{
BYTE pix = bufplce[i][vplce[i] >> bits];
if (pix != 0)
{
DWORD a = (fg2rgb[palookupoffse[i][pix]] | 0x40100400) - bg2rgb[dest[i]];
DWORD b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
dest[i] = RGB32k[0][0][a & (a>>15)];
}
vplce[i] += vince[i];
}
dest += dc_pitch;
} while (--count);
}
fixed_t tmvline1_revsubclamp ()
{
DWORD fracstep = dc_iscale;
DWORD frac = dc_texturefrac;
BYTE *colormap = dc_colormap;
int count = dc_count;
const BYTE *source = dc_source;
BYTE *dest = dc_dest;
int bits = tmvlinebits;
int pitch = dc_pitch;
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
do
{
BYTE pix = source[frac>>bits];
if (pix != 0)
{
DWORD a = (bg2rgb[*dest] | 0x40100400) - fg2rgb[colormap[pix]];
DWORD b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
*dest = RGB32k[0][0][a & (a>>15)];
}
frac += fracstep;
dest += pitch;
} while (--count);
return frac;
}
void tmvline4_revsubclamp ()
{
BYTE *dest = dc_dest;
int count = dc_count;
int bits = tmvlinebits;
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
do
{
for (int i = 0; i < 4; ++i)
{
BYTE pix = bufplce[i][vplce[i] >> bits];
if (pix != 0)
{
DWORD a = (bg2rgb[dest[i]] | 0x40100400) - fg2rgb[palookupoffse[i][pix]];
DWORD b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
dest[i] = RGB32k[0][0][a & (a>>15)];
}
vplce[i] += vince[i];
}
dest += dc_pitch;
} while (--count);
}
void R_DrawBorder (int x1, int y1, int x2, int y2)
@ -1655,21 +2062,15 @@ EXTERN_CVAR (Bool, r_drawfuzz)
EXTERN_CVAR (Float, transsouls)
CVAR (Bool, r_drawtrans, true, 0)
static BYTE *basecolormapsave;
static FDynamicColormap *basecolormapsave;
// Convenience macros, to make the following look more like OpenGL/Direct3D
#define BL_ONE FRACUNIT
#define BL_ZERO 0
#define BL_SRC_ALPHA alpha
#define BL_INV_SRC_ALPHA (BL_ONE-alpha)
static bool stencilling;
static bool R_SetBlendFunc (fixed_t fglevel, fixed_t bglevel)
static bool R_SetBlendFunc (int op, fixed_t fglevel, fixed_t bglevel, int flags)
{
if (!r_drawtrans || (fglevel == BL_ONE && bglevel == BL_ZERO))
// r_drawtrans is a seriously bad thing to turn off. I wonder if I should
// just remove it completely.
if (!r_drawtrans || (op == STYLEOP_Add && fglevel == FRACUNIT && bglevel == 0 && !(flags & STYLEF_InvertSource)))
{
if (stencilling)
if (flags & STYLEF_ColorIsFixed)
{
colfunc = R_FillColumnP;
hcolfunc_post1 = rt_copy1col;
@ -1689,68 +2090,164 @@ static bool R_SetBlendFunc (fixed_t fglevel, fixed_t bglevel)
}
return true;
}
if (fglevel == BL_ZERO && bglevel == BL_ONE)
if (flags & STYLEF_InvertSource)
{
return false;
dc_srcblend = Col2RGB8_Inverse[fglevel>>10];
dc_destblend = Col2RGB8_LessPrecision[bglevel>>10];
}
if (fglevel + bglevel <= BL_ONE)
{ // Colors won't overflow when added
else if (op == STYLEOP_Add && fglevel + bglevel <= FRACUNIT)
{
dc_srcblend = Col2RGB8[fglevel>>10];
dc_destblend = Col2RGB8[bglevel>>10];
if (stencilling)
}
else
{
dc_srcblend = Col2RGB8_LessPrecision[fglevel>>10];
dc_destblend = Col2RGB8_LessPrecision[bglevel>>10];
}
switch (op)
{
case STYLEOP_Add:
if (fglevel == 0 && bglevel == FRACUNIT)
{
colfunc = R_FillAddColumn;
hcolfunc_post1 = rt_add1col;
hcolfunc_post4 = rt_add4cols;
return false;
}
if (fglevel + bglevel <= FRACUNIT)
{ // Colors won't overflow when added
if (flags & STYLEF_ColorIsFixed)
{
colfunc = R_FillAddColumn;
hcolfunc_post1 = rt_add1col;
hcolfunc_post4 = rt_add4cols;
}
else if (dc_translation == NULL)
{
colfunc = R_DrawAddColumnP_C;
hcolfunc_post1 = rt_add1col;
hcolfunc_post4 = rt_add4cols;
}
else
{
colfunc = R_DrawTlatedAddColumnP_C;
hcolfunc_post1 = rt_tlateadd1col;
hcolfunc_post4 = rt_tlateadd4cols;
}
}
else
{ // Colors might overflow when added
if (flags & STYLEF_ColorIsFixed)
{
colfunc = R_FillAddClampColumn;
hcolfunc_post1 = rt_addclamp1col;
hcolfunc_post4 = rt_addclamp4cols;
}
else if (dc_translation == NULL)
{
colfunc = R_DrawAddClampColumnP_C;
hcolfunc_post1 = rt_addclamp1col;
hcolfunc_post4 = rt_addclamp4cols;
}
else
{
colfunc = R_DrawAddClampTranslatedColumnP_C;
hcolfunc_post1 = rt_tlateaddclamp1col;
hcolfunc_post4 = rt_tlateaddclamp4cols;
}
}
return true;
case STYLEOP_Sub:
if (flags & STYLEF_ColorIsFixed)
{
colfunc = R_FillSubClampColumn;
hcolfunc_post1 = rt_subclamp1col;
hcolfunc_post4 = rt_subclamp4cols;
}
else if (dc_translation == NULL)
{
colfunc = R_DrawAddColumnP_C;
hcolfunc_post1 = rt_add1col;
hcolfunc_post4 = rt_add4cols;
colfunc = R_DrawSubClampColumnP_C;
hcolfunc_post1 = rt_subclamp1col;
hcolfunc_post4 = rt_subclamp4cols;
}
else
{
colfunc = R_DrawTlatedAddColumnP_C;
hcolfunc_post1 = rt_tlateadd1col;
hcolfunc_post4 = rt_tlateadd4cols;
colfunc = R_DrawSubClampTranslatedColumnP_C;
hcolfunc_post1 = rt_tlatesubclamp1col;
hcolfunc_post4 = rt_tlatesubclamp4cols;
}
}
else
{ // Colors might overflow when added
dc_srcblend = Col2RGB8_LessPrecision[fglevel>>10];
dc_destblend = Col2RGB8_LessPrecision[bglevel>>10];
if (dc_translation == NULL)
return true;
case STYLEOP_RevSub:
if (fglevel == 0 && bglevel == FRACUNIT)
{
colfunc = R_DrawAddClampColumnP_C;
hcolfunc_post1 = rt_addclamp1col;
hcolfunc_post4 = rt_addclamp4cols;
return false;
}
if (flags & STYLEF_ColorIsFixed)
{
colfunc = R_FillRevSubClampColumn;
hcolfunc_post1 = rt_subclamp1col;
hcolfunc_post4 = rt_subclamp4cols;
}
else if (dc_translation == NULL)
{
colfunc = R_DrawRevSubClampColumnP_C;
hcolfunc_post1 = rt_revsubclamp1col;
hcolfunc_post4 = rt_revsubclamp4cols;
}
else
{
colfunc = R_DrawAddClampTranslatedColumnP_C;
hcolfunc_post1 = rt_tlateaddclamp1col;
hcolfunc_post4 = rt_tlateaddclamp4cols;
colfunc = R_DrawRevSubClampTranslatedColumnP_C;
hcolfunc_post1 = rt_tlaterevsubclamp1col;
hcolfunc_post4 = rt_tlaterevsubclamp4cols;
}
return true;
default:
return false;
}
return true;
}
ESPSResult R_SetPatchStyle (int style, fixed_t alpha, int translation, DWORD color)
static fixed_t GetAlpha(int type, fixed_t alpha)
{
switch (type)
{
case STYLEALPHA_Zero: return 0;
case STYLEALPHA_One: return FRACUNIT;
case STYLEALPHA_Src: return alpha;
case STYLEALPHA_InvSrc: return FRACUNIT - alpha;
default: return 0;
}
}
ESPSResult R_SetPatchStyle (FRenderStyle style, fixed_t alpha, int translation, DWORD color)
{
fixed_t fglevel, bglevel;
if (style == STYLE_OptFuzzy)
if (style.BlendOp == STYLEOP_FuzzOrAdd)
{
style = (r_drawfuzz || !r_drawtrans) ? STYLE_Fuzzy : STYLE_Translucent;
style.BlendOp = (r_drawfuzz || !r_drawtrans) ? STYLEOP_Fuzz : STYLEOP_Add;
}
else if (style == STYLE_SoulTrans)
else if (style.BlendOp == STYLEOP_FuzzOrSub)
{
style = STYLE_Translucent;
alpha = (fixed_t)(FRACUNIT * transsouls);
style.BlendOp = (r_drawfuzz || !r_drawtrans) ? STYLEOP_Fuzz : STYLEOP_Sub;
}
else if (style.BlendOp == STYLEOP_FuzzOrRevSub)
{
style.BlendOp = (r_drawfuzz || !r_drawtrans) ? STYLEOP_Fuzz : STYLEOP_RevSub;
}
alpha = clamp<fixed_t> (alpha, 0, FRACUNIT);
if (style.Flags & STYLEF_TransSoulsAlpha)
{
alpha = fixed_t(transsouls * FRACUNIT);
}
else if (style.Flags & STYLEF_Alpha1)
{
alpha = FRACUNIT;
}
else
{
alpha = clamp<fixed_t> (alpha, 0, FRACUNIT);
}
dc_translation = NULL;
if (translation != 0)
@ -1762,63 +2259,56 @@ ESPSResult R_SetPatchStyle (int style, fixed_t alpha, int translation, DWORD col
}
}
basecolormapsave = basecolormap;
stencilling = false;
hcolfunc_pre = R_DrawColumnHoriz;
switch (style)
// Check for special modes
if (style.BlendOp == STYLEOP_Fuzz)
{
// Special modes
case STYLE_Fuzzy:
colfunc = fuzzcolfunc;
return DoDraw0;
case STYLE_Shaded:
}
else if (style == LegacyRenderStyles[STYLE_Shaded])
{
// Shaded drawer only gets 16 levels because it saves memory.
if ((alpha >>= 12) == 0)
return DontDraw;
colfunc = R_DrawShadedColumn;
hcolfunc_post1 = rt_shaded1col;
hcolfunc_post4 = rt_shaded4cols;
dc_color = fixedcolormap ? fixedcolormap[APART(color)] : basecolormap[APART(color)];
dc_colormap = basecolormap = &shadetables[((16-alpha)*NUMCOLORMAPS)*256];
if (fixedlightlev)
dc_color = fixedcolormap ? fixedcolormap[APART(color)] : basecolormap->Maps[APART(color)];
dc_colormap = (basecolormap = &ShadeFakeColormap[16-alpha])->Maps;
if (fixedlightlev && !fixedcolormap)
{
dc_colormap += fixedlightlev;
}
return r_columnmethod ? DoDraw1 : DoDraw0;
// Standard modes
case STYLE_Stencil:
dc_color = APART(color);
stencilling = true;
case STYLE_Normal:
fglevel = BL_ONE;
bglevel = BL_ZERO;
break;
case STYLE_TranslucentStencil:
dc_color = APART(color);
stencilling = true;
case STYLE_Translucent:
fglevel = BL_SRC_ALPHA;
bglevel = BL_INV_SRC_ALPHA;
break;
case STYLE_Add:
fglevel = BL_SRC_ALPHA;
bglevel = BL_ONE;
break;
default:
return DontDraw;
}
if (stencilling)
fglevel = GetAlpha(style.SrcAlpha, alpha);
bglevel = GetAlpha(style.DestAlpha, alpha);
if (style.Flags & STYLEF_ColorIsFixed)
{
int x = fglevel >> 10;
int r = RPART(color);
int g = GPART(color);
int b = BPART(color);
// dc_color is used by the rt_* routines. It is indexed into dc_srcblend.
dc_color = RGB32k[r>>3][g>>3][b>>3];
if (style.Flags & STYLEF_InvertSource)
{
r = 255 - r;
g = 255 - g;
b = 255 - b;
}
// dc_srccolor is used by the R_Fill* routines. It is premultiplied
// with the alpha.
dc_srccolor = ((((r*x)>>4)<<20) | ((g*x)>>4) | ((((b)*x)>>4)<<10)) & 0x3feffbff;
hcolfunc_pre = R_FillColumnHorizP;
dc_colormap = identitymap;
}
return R_SetBlendFunc (fglevel, bglevel) ?
return R_SetBlendFunc (style.BlendOp, fglevel, bglevel, style.Flags) ?
(r_columnmethod ? DoDraw1 : DoDraw0) : DontDraw;
}
@ -1841,5 +2331,48 @@ bool R_GetTransMaskDrawers (fixed_t (**tmvline1)(), void (**tmvline4)())
*tmvline4 = tmvline4_addclamp;
return true;
}
if (colfunc == R_DrawSubClampColumnP_C)
{
*tmvline1 = tmvline1_subclamp;
*tmvline4 = tmvline4_subclamp;
return true;
}
if (colfunc == R_DrawRevSubClampColumnP_C)
{
*tmvline1 = tmvline1_revsubclamp;
*tmvline4 = tmvline4_revsubclamp;
return true;
}
return false;
}
//==========================================================================
//
// FRenderStyle :: IsVisible
//
// Coupled with the given alpha, will this render style produce something
// visible on-screen?
//
//==========================================================================
bool FRenderStyle::IsVisible(fixed_t alpha) const
{
if (BlendOp == STYLEOP_None)
{
return false;
}
if (BlendOp == STYLEOP_Add || BlendOp == STYLEOP_RevSub)
{
if (Flags & STYLEF_Alpha1)
{
alpha = FRACUNIT;
}
else
{
alpha = clamp(alpha, 0, FRACUNIT);
}
return GetAlpha(SrcAlpha, alpha) != 0 || GetAlpha(DestAlpha, alpha) != FRACUNIT;
}
// Treat anything else as visible.
return true;
}

View file

@ -25,7 +25,6 @@
#include "r_data.h"
extern "C" int ylookup[MAXHEIGHT];
extern "C" int dc_pitch; // [RH] Distance between rows
@ -38,6 +37,7 @@ extern "C" fixed_t dc_iscale;
extern "C" fixed_t dc_texturemid;
extern "C" fixed_t dc_texturefrac;
extern "C" int dc_color; // [RH] For flat colors (no texturing)
extern "C" DWORD dc_srccolor;
extern "C" DWORD *dc_srcblend;
extern "C" DWORD *dc_destblend;
@ -122,6 +122,14 @@ void rt_addclamp1col (int hx, int sx, int yl, int yh);
void rt_addclamp4cols (int sx, int yl, int yh);
void rt_tlateaddclamp1col (int hx, int sx, int yl, int yh);
void rt_tlateaddclamp4cols (int sx, int yl, int yh);
void rt_subclamp1col (int hx, int sx, int yl, int yh);
void rt_subclamp4cols (int sx, int yl, int yh);
void rt_tlatesubclamp1col (int hx, int sx, int yl, int yh);
void rt_tlatesubclamp4cols (int sx, int yl, int yh);
void rt_revsubclamp1col (int hx, int sx, int yl, int yh);
void rt_revsubclamp4cols (int sx, int yl, int yh);
void rt_tlaterevsubclamp1col (int hx, int sx, int yl, int yh);
void rt_tlaterevsubclamp4cols (int sx, int yl, int yh);
extern "C" void rt_copy1col_asm (int hx, int sx, int yl, int yh);
extern "C" void rt_copy4cols_asm (int sx, int yl, int yh);
@ -202,6 +210,8 @@ extern "C" const BYTE* ds_source;
extern "C" int ds_color; // [RH] For flat color (no texturing)
extern BYTE shadetables[NUMCOLORMAPS*16*256];
extern FDynamicColormap ShadeFakeColormap[16];
extern BYTE identitymap[256];
extern BYTE *dc_translation;
// [RH] Double view pixels by detail mode
@ -224,7 +234,7 @@ enum ESPSResult
DoDraw0, // draw this as if r_columnmethod is 0
DoDraw1, // draw this as if r_columnmethod is 1
};
ESPSResult R_SetPatchStyle (int style, fixed_t alpha, int translation, DWORD color);
ESPSResult R_SetPatchStyle (FRenderStyle style, fixed_t alpha, int translation, DWORD color);
// Call this after finished drawing the current thing, in case its
// style was STYLE_Shade

View file

@ -773,6 +773,394 @@ void rt_tlateaddclamp4cols (int sx, int yl, int yh)
} while (--count);
}
// Subtracts one span at hx to the screen at sx with clamping.
void rt_subclamp1col (int hx, int sx, int yl, int yh)
{
BYTE *colormap;
BYTE *source;
BYTE *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp[yl*4 + hx];
pitch = dc_pitch;
colormap = dc_colormap;
do {
DWORD a = (fg2rgb[colormap[*source]] | 0x40100400) - bg2rgb[*dest];
DWORD b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
*dest = RGB32k[0][0][(a>>15) & a];
source += 4;
dest += pitch;
} while (--count);
}
// Subtracts all four spans to the screen starting at sx with clamping.
void rt_subclamp4cols (int sx, int yl, int yh)
{
BYTE *colormap;
BYTE *source;
BYTE *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp[yl*4];
pitch = dc_pitch;
colormap = dc_colormap;
do {
DWORD a = (fg2rgb[colormap[source[0]]] | 0x40100400) - bg2rgb[dest[0]];
DWORD b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
dest[0] = RGB32k[0][0][(a>>15) & a];
a = (fg2rgb[colormap[source[1]]] | 0x40100400) - bg2rgb[dest[1]];
b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
dest[1] = RGB32k[0][0][(a>>15) & a];
a = (fg2rgb[colormap[source[2]]] | 0x40100400) - bg2rgb[dest[2]];
b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
dest[2] = RGB32k[0][0][(a>>15) & a];
a = (fg2rgb[colormap[source[3]]] | 0x40100400) - bg2rgb[dest[3]];
b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
dest[3] = RGB32k[0][0][(a>>15) & a];
source += 4;
dest += pitch;
} while (--count);
}
// Translates and subtracts one span at hx to the screen at sx with clamping.
void rt_tlatesubclamp1col (int hx, int sx, int yl, int yh)
{
BYTE *translation;
BYTE *colormap;
BYTE *source;
BYTE *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp[yl*4 + hx];
pitch = dc_pitch;
colormap = dc_colormap;
translation = dc_translation;
do {
DWORD a = (fg2rgb[colormap[translation[*source]]] | 0x40100400) - bg2rgb[*dest];
DWORD b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
*dest = RGB32k[0][0][(a>>15) & a];
source += 4;
dest += pitch;
} while (--count);
}
// Translates and subtracts all four spans to the screen starting at sx with clamping.
void rt_tlatesubclamp4cols (int sx, int yl, int yh)
{
BYTE *translation;
BYTE *colormap;
BYTE *source;
BYTE *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp[yl*4];
pitch = dc_pitch;
colormap = dc_colormap;
translation = dc_translation;
do {
DWORD a = (fg2rgb[colormap[translation[source[0]]]] | 0x40100400) - bg2rgb[dest[0]];
DWORD b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
dest[0] = RGB32k[0][0][(a>>15) & a];
a = (fg2rgb[colormap[translation[source[1]]]] | 0x40100400) - bg2rgb[dest[1]];
b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
dest[1] = RGB32k[0][0][(a>>15) & a];
a = (fg2rgb[colormap[translation[source[2]]]] | 0x40100400) - bg2rgb[dest[2]];
b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
dest[2] = RGB32k[0][0][(a>>15) & a];
a = (fg2rgb[colormap[translation[source[3]]]] | 0x40100400) - bg2rgb[dest[3]];
b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
dest[3] = RGB32k[0][0][(a>>15) & a];
source += 4;
dest += pitch;
} while (--count);
}
// Subtracts one span at hx from the screen at sx with clamping.
void rt_revsubclamp1col (int hx, int sx, int yl, int yh)
{
BYTE *colormap;
BYTE *source;
BYTE *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp[yl*4 + hx];
pitch = dc_pitch;
colormap = dc_colormap;
do {
DWORD a = (bg2rgb[*dest] | 0x40100400) - fg2rgb[colormap[*source]];
DWORD b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
*dest = RGB32k[0][0][(a>>15) & a];
source += 4;
dest += pitch;
} while (--count);
}
// Subtracts all four spans from the screen starting at sx with clamping.
void rt_revsubclamp4cols (int sx, int yl, int yh)
{
BYTE *colormap;
BYTE *source;
BYTE *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp[yl*4];
pitch = dc_pitch;
colormap = dc_colormap;
do {
DWORD a = (bg2rgb[dest[0]] | 0x40100400) - fg2rgb[colormap[source[0]]];
DWORD b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
dest[0] = RGB32k[0][0][(a>>15) & a];
a = (bg2rgb[dest[1]] | 0x40100400) - fg2rgb[colormap[source[1]]];
b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
dest[1] = RGB32k[0][0][(a>>15) & a];
a = (bg2rgb[dest[2]] | 0x40100400) - fg2rgb[colormap[source[2]]];
b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
dest[2] = RGB32k[0][0][(a>>15) & a];
a = (bg2rgb[dest[3]] | 0x40100400) - fg2rgb[colormap[source[3]]];
b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
dest[3] = RGB32k[0][0][(a>>15) & a];
source += 4;
dest += pitch;
} while (--count);
}
// Translates and subtracts one span at hx from the screen at sx with clamping.
void rt_tlaterevsubclamp1col (int hx, int sx, int yl, int yh)
{
BYTE *translation;
BYTE *colormap;
BYTE *source;
BYTE *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp[yl*4 + hx];
pitch = dc_pitch;
colormap = dc_colormap;
translation = dc_translation;
do {
DWORD a = (bg2rgb[dest[0]] | 0x40100400) - fg2rgb[colormap[translation[source[0]]]];
DWORD b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
*dest = RGB32k[0][0][(a>>15) & a];
source += 4;
dest += pitch;
} while (--count);
}
// Translates and subtracts all four spans from the screen starting at sx with clamping.
void rt_tlaterevsubclamp4cols (int sx, int yl, int yh)
{
BYTE *translation;
BYTE *colormap;
BYTE *source;
BYTE *dest;
int count;
int pitch;
count = yh-yl;
if (count < 0)
return;
count++;
DWORD *fg2rgb = dc_srcblend;
DWORD *bg2rgb = dc_destblend;
dest = ylookup[yl] + sx + dc_destorg;
source = &dc_temp[yl*4];
pitch = dc_pitch;
colormap = dc_colormap;
translation = dc_translation;
do {
DWORD a = (bg2rgb[dest[0]] | 0x40100400) - fg2rgb[colormap[translation[source[0]]]];
DWORD b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
dest[0] = RGB32k[0][0][(a>>15) & a];
a = (bg2rgb[dest[1]] | 0x40100400) - fg2rgb[colormap[translation[source[1]]]];
b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
dest[1] = RGB32k[0][0][(a>>15) & a];
a = (bg2rgb[dest[2]] | 0x40100400) - fg2rgb[colormap[translation[source[2]]]];
b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
dest[2] = RGB32k[0][0][(a>>15) & a];
a = (bg2rgb[dest[3]] | 0x40100400) - fg2rgb[colormap[translation[source[3]]]];
b = a;
b &= 0x40100400;
b = b - (b >> 5);
a &= b;
a |= 0x01f07c1f;
dest[3] = RGB32k[0][0][(a>>15) & a];
source += 4;
dest += pitch;
} while (--count);
}
// Copies all spans in all four columns to the screen starting at sx.
// sx should be longword-aligned.
void rt_draw4cols (int sx)

View file

@ -134,7 +134,7 @@ fixed_t FocalLengthY;
float FocalLengthXfloat;
int viewangleoffset;
int validcount = 1; // increment every time a check is made
lighttable_t *basecolormap; // [RH] colormap currently drawing with
FDynamicColormap*basecolormap; // [RH] colormap currently drawing with
int fixedlightlev;
lighttable_t *fixedcolormap;
float WallTMapScale;
@ -1077,7 +1077,7 @@ void R_SetupFrame (AActor *actor)
if (player != NULL && gamestate != GS_TITLELEVEL &&
((player->cheats & CF_CHASECAM) || (r_deathcamera && camera->health <= 0)) &&
(camera->RenderStyle != STYLE_None) &&
(camera->RenderStyle.BlendOp != STYLEOP_None) &&
!(camera->renderflags & RF_INVISIBLE) &&
camera->sprite != 0) // Sprite 0 is always TNT1
{

View file

@ -70,7 +70,7 @@ extern fixed_t centeryfrac;
extern fixed_t yaspectmul;
extern float iyaspectmulfloat;
extern BYTE* basecolormap; // [RH] Colormap for sector currently being drawn
extern FDynamicColormap*basecolormap; // [RH] Colormap for sector currently being drawn
extern int validcount;

View file

@ -207,7 +207,7 @@ void R_MapPlane (int y, int x1)
if (plane_shade)
{
// Determine lighting based on the span's distance from the viewer.
ds_colormap = basecolormap + (GETPALOOKUP (
ds_colormap = basecolormap->Maps + (GETPALOOKUP (
FixedMul (GlobVis, abs (centeryfrac - (y << FRACBITS))), planeshade) << COLORMAPSHIFT);
}
@ -237,6 +237,7 @@ void STACK_ARGS R_CalcTiltedLighting (fixed_t lval, fixed_t lend, int width)
{
fixed_t lstep;
BYTE *lightfiller;
BYTE *basecolormapdata = basecolormap->Maps;
int i = 0;
lval = planeshade - lval;
@ -244,19 +245,19 @@ void STACK_ARGS R_CalcTiltedLighting (fixed_t lval, fixed_t lend, int width)
if (width == 0 || lval == lend)
{ // Constant lighting
lightfiller = basecolormap + (GETPALOOKUP (-lval, 0) << COLORMAPSHIFT);
lightfiller = basecolormapdata + (GETPALOOKUP (-lval, 0) << COLORMAPSHIFT);
}
else if ((lstep = (lend - lval) / width) < 0)
{ // Going from dark to light
if (lval < FRACUNIT)
{ // All bright
lightfiller = basecolormap;
lightfiller = basecolormapdata;
}
else
{
if (lval >= NUMCOLORMAPS*FRACUNIT)
{ // Starts beyond the dark end
BYTE *clight = basecolormap + ((NUMCOLORMAPS-1) << COLORMAPSHIFT);
BYTE *clight = basecolormapdata + ((NUMCOLORMAPS-1) << COLORMAPSHIFT);
while (lval >= NUMCOLORMAPS*FRACUNIT && i <= width)
{
tiltlighting[i++] = clight;
@ -267,33 +268,33 @@ void STACK_ARGS R_CalcTiltedLighting (fixed_t lval, fixed_t lend, int width)
}
while (i <= width && lval >= 0)
{
tiltlighting[i++] = basecolormap + ((lval >> FRACBITS) << COLORMAPSHIFT);
tiltlighting[i++] = basecolormapdata + ((lval >> FRACBITS) << COLORMAPSHIFT);
lval += lstep;
}
lightfiller = basecolormap;
lightfiller = basecolormapdata;
}
}
else
{ // Going from light to dark
if (lval >= (NUMCOLORMAPS-1)*FRACUNIT)
{ // All dark
lightfiller = basecolormap + ((NUMCOLORMAPS-1) << COLORMAPSHIFT);
lightfiller = basecolormapdata + ((NUMCOLORMAPS-1) << COLORMAPSHIFT);
}
else
{
while (lval < 0 && i <= width)
{
tiltlighting[i++] = basecolormap;
tiltlighting[i++] = basecolormapdata;
lval += lstep;
}
if (i > width)
return;
while (i <= width && lval < (NUMCOLORMAPS-1)*FRACUNIT)
{
tiltlighting[i++] = basecolormap + ((lval >> FRACBITS) << COLORMAPSHIFT);
tiltlighting[i++] = basecolormapdata + ((lval >> FRACBITS) << COLORMAPSHIFT);
lval += lstep;
}
lightfiller = basecolormap + ((NUMCOLORMAPS-1) << COLORMAPSHIFT);
lightfiller = basecolormapdata + ((NUMCOLORMAPS-1) << COLORMAPSHIFT);
}
}
@ -1313,7 +1314,7 @@ sky1:
{
dc_colormap = fixedcolormap;
}
else if (!fixedcolormap)
else
{
fakefixed = true;
fixedcolormap = dc_colormap = NormalLight.Maps;
@ -1387,7 +1388,7 @@ void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool masked)
GlobVis = FixedDiv (r_FloorVisibility, planeheight);
if (fixedlightlev)
ds_colormap = basecolormap + fixedlightlev, plane_shade = false;
ds_colormap = basecolormap->Maps + fixedlightlev, plane_shade = false;
else if (fixedcolormap)
ds_colormap = fixedcolormap, plane_shade = false;
else
@ -1532,11 +1533,11 @@ void R_DrawTiltedPlane (visplane_t *pl, fixed_t alpha, bool masked)
planelightfloat = -planelightfloat;
if (fixedlightlev)
ds_colormap = basecolormap + fixedlightlev, plane_shade = false;
ds_colormap = basecolormap->Maps + fixedlightlev, plane_shade = false;
else if (fixedcolormap)
ds_colormap = fixedcolormap, plane_shade = false;
else
ds_colormap = basecolormap, plane_shade = true;
ds_colormap = basecolormap->Maps, plane_shade = true;
if (!plane_shade)
{

View file

@ -40,7 +40,7 @@ struct visplane_s
int lightlevel;
fixed_t xoffs, yoffs; // killough 2/28/98: Support scrolling flats
int minx, maxx;
BYTE *colormap; // [RH] Support multiple colormaps
FDynamicColormap *colormap; // [RH] Support multiple colormaps
fixed_t xscale, yscale; // [RH] Support flat scaling
angle_t angle; // [RH] Support flat rotation
ASkyViewpoint *skybox; // [RH] Support sky boxes

View file

@ -1401,13 +1401,13 @@ void RP_Subsector (subsector_t *sub)
frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel,
&ceilinglightlevel, false); // killough 4/11/98
basecolormap = frontsector->ColorMap->Maps;
basecolormap = frontsector->ColorMap;
R_GetExtraLight (&ceilinglightlevel, frontsector->ceilingplane, frontsector->ExtraLights);
// [RH] set foggy flag
foggy = level.fadeto || frontsector->ColorMap->Fade || (level.flags & LEVEL_HASFADETABLE);
r_actualextralight = foggy ? 0 : extralight << 4;
basecolormap = frontsector->ColorMap->Maps;
basecolormap = frontsector->ColorMap;
/* ceilingplane = frontsector->ceilingplane.ZatPoint (viewx, viewy) > viewz ||
frontsector->ceilingpic == skyflatnum ||
(frontsector->CeilingSkyBox != NULL && frontsector->CeilingSkyBox->bAlways) ||
@ -1427,7 +1427,7 @@ void RP_Subsector (subsector_t *sub)
frontsector->CeilingSkyBox
) : NULL;*/
basecolormap = frontsector->ColorMap->Maps;
basecolormap = frontsector->ColorMap;
R_GetExtraLight (&floorlightlevel, frontsector->floorplane, frontsector->ExtraLights);
// killough 3/7/98: Add (x,y) offsets to flats, add deep water check

View file

@ -166,7 +166,7 @@ static void BlastMaskedColumn (void (*blastfunc)(const BYTE *pixels, const FText
// calculate lighting
if (!fixedcolormap)
{
dc_colormap = basecolormap + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT);
dc_colormap = basecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT);
}
dc_iscale = MulScale18 (MaskedSWall[dc_x], MaskedScaleY);
@ -205,7 +205,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
// [RH] modified because we don't use user-definable translucency maps
ESPSResult drawmode;
drawmode = R_SetPatchStyle (curline->sidedef->Flags & WALLF_ADDTRANS ? STYLE_Add : STYLE_Translucent,
drawmode = R_SetPatchStyle (LegacyRenderStyles[curline->sidedef->Flags & WALLF_ADDTRANS ? STYLE_Add : STYLE_Translucent],
curline->linedef->alpha < 255 ? curline->linedef->alpha<<8 : FRACUNIT,
0, 0);
@ -224,7 +224,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
// killough 4/13/98: get correct lightlevel for 2s normal textures
const sector_t *sec = R_FakeFlat (frontsector, &tempsec, NULL, NULL, false);
basecolormap = sec->ColorMap->Maps; // [RH] Set basecolormap
basecolormap = sec->ColorMap; // [RH] Set basecolormap
wallshade = ds->shade;
rw_lightstep = ds->lightstep;
@ -276,7 +276,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
}
if (fixedlightlev)
dc_colormap = basecolormap + fixedlightlev;
dc_colormap = basecolormap->Maps + fixedlightlev;
else if (fixedcolormap)
dc_colormap = fixedcolormap;
@ -403,6 +403,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t
char bad;
fixed_t light = rw_light - rw_lightstep;
SDWORD yrepeat, texturemid, xoffset;
BYTE *basecolormapdata;
// This function also gets used to draw skies. Unlike BUILD, skies are
// drawn by visplane instead of by bunch, so these checks are invalid.
@ -423,6 +424,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t
yrepeat = rw_pic->yScale >> (2 + shiftval);
texturemid = dc_texturemid << (16 - shiftval);
xoffset = rw_offset;
basecolormapdata = basecolormap->Maps;
x = x1;
//while ((umost[x] > dmost[x]) && (x <= x2)) x++;
@ -446,7 +448,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t
if (!fixedcolormap)
{ // calculate lighting
dc_colormap = basecolormap + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT);
dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT);
}
dc_source = getcol (rw_pic, (lwal[x] + xoffset) >> FRACBITS);
@ -484,7 +486,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t
for (z = 0; z < 4; ++z)
{
light += rw_lightstep;
palookupoffse[z] = basecolormap + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT);
palookupoffse[z] = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT);
}
}
@ -539,7 +541,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t
if (!fixedcolormap)
{ // calculate lighting
dc_colormap = basecolormap + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT);
dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT);
}
dc_source = getcol (rw_pic, (lwal[x] + xoffset) >> FRACBITS);
@ -559,11 +561,11 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t
void wallscan_striped (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t *lwal)
{
bool flooding = false;
BYTE *startcolormap = basecolormap;
FDynamicColormap *startcolormap = basecolormap;
int startshade = wallshade;
bool fogginess = foggy;
BYTE *floodcolormap = startcolormap;
FDynamicColormap *floodcolormap = startcolormap;
int floodshade = startshade;
bool floodfoggy = foggy;
@ -612,8 +614,8 @@ void wallscan_striped (int x1, int x2, short *uwal, short *dwal, fixed_t *swal,
}
else
{
basecolormap = el->Lights[i].Master->ColorMap->Maps;
fogginess = level.fadeto || el->Lights[i].Master->ColorMap->Fade;
basecolormap = el->Lights[i].Master->ColorMap;
fogginess = level.fadeto || basecolormap->Fade;
wallshade = LIGHT2SHADE(curline->sidedef->GetLightLevel(fogginess,
el->Lights[i].Master->lightlevel) + r_actualextralight);
if (el->Lights[i].bFlooder)
@ -649,6 +651,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixe
char bad;
fixed_t light = rw_light - rw_lightstep;
SDWORD yrepeat, texturemid, xoffset;
BYTE *basecolormapdata;
if (rw_pic->UseType == FTexture::TEX_Null)
{
@ -670,6 +673,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixe
yrepeat = rw_pic->yScale >> (2 + shiftval);
texturemid = dc_texturemid << (16 - shiftval);
xoffset = rw_offset;
basecolormapdata = basecolormap->Maps;
x = startx = x1;
p = x + dc_destorg;
@ -691,7 +695,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixe
if (!fixedcolormap)
{ // calculate lighting
dc_colormap = basecolormap + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT);
dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT);
}
dc_source = getcol (rw_pic, (lwal[x] + xoffset) >> FRACBITS);
@ -727,7 +731,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixe
for (z = 0; z < 4; ++z)
{
light += rw_lightstep;
palookupoffse[z] = basecolormap + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT);
palookupoffse[z] = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT);
}
}
@ -780,7 +784,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixe
if (!fixedcolormap)
{ // calculate lighting
dc_colormap = basecolormap + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT);
dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT);
}
dc_source = getcol (rw_pic, (lwal[x] + xoffset) >> FRACBITS);
@ -818,6 +822,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal,
char bad;
fixed_t light = rw_light - rw_lightstep;
SDWORD yrepeat, texturemid, xoffset;
BYTE *basecolormapdata;
if (rw_pic->UseType == FTexture::TEX_Null)
{
@ -840,6 +845,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal,
yrepeat = rw_pic->yScale >> (2 + shiftval);
texturemid = dc_texturemid << (16 - shiftval);
xoffset = rw_offset;
basecolormapdata = basecolormap->Maps;
x = startx = x1;
p = x + dc_destorg;
@ -861,7 +867,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal,
if (!fixedcolormap)
{ // calculate lighting
dc_colormap = basecolormap + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT);
dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT);
}
dc_source = getcol (rw_pic, (lwal[x] + xoffset) >> FRACBITS);
@ -897,7 +903,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal,
for (z = 0; z < 4; ++z)
{
light += rw_lightstep;
palookupoffse[z] = basecolormap + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT);
palookupoffse[z] = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT);
}
}
@ -953,7 +959,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal,
if (!fixedcolormap)
{ // calculate lighting
dc_colormap = basecolormap + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT);
dc_colormap = basecolormapdata + (GETPALOOKUP (light, wallshade) << COLORMAPSHIFT);
}
dc_source = getcol (rw_pic, (lwal[x] + xoffset) >> FRACBITS);
@ -989,7 +995,7 @@ void R_RenderSegLoop ()
fixed_t xoffset = rw_offset;
if (fixedlightlev)
dc_colormap = basecolormap + fixedlightlev;
dc_colormap = basecolormap->Maps + fixedlightlev;
else if (fixedcolormap)
dc_colormap = fixedcolormap;
@ -2347,11 +2353,11 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
rw_light = rw_lightleft + (x1 - WallSX1) * rw_lightstep;
if (fixedlightlev)
dc_colormap = basecolormap + fixedlightlev;
dc_colormap = basecolormap->Maps + fixedlightlev;
else if (fixedcolormap)
dc_colormap = fixedcolormap;
else if (!foggy && (decal->RenderFlags & RF_FULLBRIGHT))
dc_colormap = basecolormap;
dc_colormap = basecolormap->Maps;
else
calclighting = true;
@ -2398,7 +2404,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
{
if (calclighting)
{ // calculate lighting
dc_colormap = basecolormap + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT);
dc_colormap = basecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT);
}
WallSpriteColumn (R_DrawMaskedColumn);
@ -2409,7 +2415,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
{
if (calclighting)
{ // calculate lighting
dc_colormap = basecolormap + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT);
dc_colormap = basecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT);
}
rt_initcols();
for (int zz = 4; zz; --zz)
@ -2424,7 +2430,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
{
if (calclighting)
{ // calculate lighting
dc_colormap = basecolormap + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT);
dc_colormap = basecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT);
}
WallSpriteColumn (R_DrawMaskedColumn);

View file

@ -453,7 +453,7 @@ void R_InitSkins (void)
sndlumps[j] = -1;
skins[i].namespc = Wads.GetLumpNamespace (base);
SC_OpenLumpNum (base, "S_SKIN");
FScanner sc(base, "S_SKIN");
intname = 0;
crouchname = 0;
@ -462,18 +462,18 @@ void R_InitSkins (void)
transtype = NULL;
// Data is stored as "key = data".
while (SC_GetString ())
while (sc.GetString ())
{
strncpy (key, sc_String, sizeof(key)-1);
if (!SC_GetString() || sc_String[0] != '=')
strncpy (key, sc.String, sizeof(key)-1);
if (!sc.GetString() || sc.String[0] != '=')
{
Printf (PRINT_BOLD, "Bad format for skin %d: %s\n", i, key);
break;
}
SC_GetString ();
sc.GetString ();
if (0 == stricmp (key, "name"))
{
strncpy (skins[i].name, sc_String, 16);
strncpy (skins[i].name, sc.String, 16);
for (j = 0; (size_t)j < i; j++)
{
if (stricmp (skins[i].name, skins[j].name) == 0)
@ -488,27 +488,27 @@ void R_InitSkins (void)
else if (0 == stricmp (key, "sprite"))
{
for (j = 3; j >= 0; j--)
sc_String[j] = toupper (sc_String[j]);
intname = *((DWORD *)sc_String);
sc.String[j] = toupper (sc.String[j]);
intname = *((DWORD *)sc.String);
}
else if (0 == stricmp (key, "crouchsprite"))
{
for (j = 3; j >= 0; j--)
sc_String[j] = toupper (sc_String[j]);
crouchname = *((DWORD *)sc_String);
sc.String[j] = toupper (sc.String[j]);
crouchname = *((DWORD *)sc.String);
}
else if (0 == stricmp (key, "face"))
{
for (j = 2; j >= 0; j--)
skins[i].face[j] = toupper (sc_String[j]);
skins[i].face[j] = toupper (sc.String[j]);
}
else if (0 == stricmp (key, "gender"))
{
skins[i].gender = D_GenderToInt (sc_String);
skins[i].gender = D_GenderToInt (sc.String);
}
else if (0 == stricmp (key, "scale"))
{
skins[i].Scale = clamp<fixed_t> (FLOAT2FIXED(atof (sc_String)), 1, 256*FRACUNIT);
skins[i].Scale = clamp<fixed_t> (FLOAT2FIXED(atof (sc.String)), 1, 256*FRACUNIT);
}
else if (0 == stricmp (key, "game"))
{
@ -521,7 +521,7 @@ void R_InitSkins (void)
transtype = basetype;
if (stricmp (sc_String, "heretic") == 0)
if (stricmp (sc.String, "heretic") == 0)
{
if (gameinfo.gametype == GAME_Doom)
{
@ -533,7 +533,7 @@ void R_InitSkins (void)
remove = true;
}
}
else if (stricmp (sc_String, "strife") == 0)
else if (stricmp (sc.String, "strife") == 0)
{
if (gameinfo.gametype != GAME_Strife)
{
@ -558,7 +558,7 @@ void R_InitSkins (void)
}
else if (0 == stricmp (key, "class"))
{ // [GRB] Define the skin for a specific player class
int pclass = D_PlayerClassToInt (sc_String);
int pclass = D_PlayerClassToInt (sc.String);
if (pclass < 0)
{
@ -570,11 +570,11 @@ void R_InitSkins (void)
}
else if (key[0] == '*')
{ // Player sound replacment (ZDoom extension)
int lump = Wads.CheckNumForName (sc_String, skins[i].namespc);
int lump = Wads.CheckNumForName (sc.String, skins[i].namespc);
if (lump == -1)
{
lump = Wads.CheckNumForFullName (sc_String);
if (lump == -1) lump = Wads.CheckNumForName (sc_String, ns_sounds);
lump = Wads.CheckNumForFullName (sc.String);
if (lump == -1) lump = Wads.CheckNumForName (sc.String, ns_sounds);
}
if (lump != -1)
{
@ -604,16 +604,16 @@ void R_InitSkins (void)
{
if (stricmp (key, skinsoundnames[j][0]) == 0)
{
sndlumps[j] = Wads.CheckNumForName (sc_String, skins[i].namespc);
sndlumps[j] = Wads.CheckNumForName (sc.String, skins[i].namespc);
if (sndlumps[j] == -1)
{ // Replacement not found, try finding it in the global namespace
sndlumps[j] = Wads.CheckNumForFullName (sc_String);
if (sndlumps[j] == -1) sndlumps[j] = Wads.CheckNumForName (sc_String, ns_sounds);
sndlumps[j] = Wads.CheckNumForFullName (sc.String);
if (sndlumps[j] == -1) sndlumps[j] = Wads.CheckNumForName (sc.String, ns_sounds);
}
}
}
//if (j == 8)
// Printf ("Funny info for skin %i: %s = %s\n", i, key, sc_String);
// Printf ("Funny info for skin %i: %s = %s\n", i, key, sc.String);
}
}
@ -751,8 +751,6 @@ void R_InitSkins (void)
}
}
SC_Close ();
// Make sure face prefix is a full 3 chars
if (skins[i].face[1] == 0 || skins[i].face[2] == 0)
{
@ -1095,7 +1093,7 @@ void R_DrawVisSprite (vissprite_t *vis)
dc_colormap = vis->colormap;
mode = R_SetPatchStyle (vis->RenderStyle, vis->alpha, vis->Translation, vis->AlphaColor);
mode = R_SetPatchStyle (vis->RenderStyle, vis->alpha, vis->Translation, vis->FillColor);
if (mode != DontDraw)
{
@ -1192,10 +1190,10 @@ void R_ProjectSprite (AActor *thing, int fakeside)
sector_t* heightsec; // killough 3/27/98
// Don't waste time projecting sprites that are definitely not visible.
if (thing == NULL ||
(thing->renderflags & RF_INVISIBLE) ||
thing->RenderStyle == STYLE_None ||
(thing->RenderStyle >= STYLE_Translucent && thing->alpha <= 0))
!thing->RenderStyle.IsVisible(thing->alpha))
{
return;
}
@ -1385,7 +1383,7 @@ void R_ProjectSprite (AActor *thing, int fakeside)
fixed_t yscale = DivScale16(thing->scaleY, tex->yScale);
vis->renderflags = thing->renderflags;
vis->RenderStyle = thing->RenderStyle;
vis->AlphaColor = thing->alphacolor;
vis->FillColor = thing->fillcolor;
vis->xscale = xscale;
vis->yscale = Scale (InvZtoScale, yscale, tz)>>4;
vis->idepth = (DWORD)DivScale32 (1, tz) >> 1; // tz is 20.12, so idepth ought to be 12.20, but
@ -1417,11 +1415,42 @@ void R_ProjectSprite (AActor *thing, int fakeside)
if (vis->x1 > x1)
vis->startfrac += vis->xiscale*(vis->x1-x1);
// The software renderer cannot invert the source without inverting the overlay
// too. That means if the source is inverted, we need to do the reverse of what
// the invert overlay flag says to do.
INTBOOL invertcolormap = (vis->RenderStyle.Flags & STYLEF_InvertOverlay);
if (vis->RenderStyle.Flags & STYLEF_InvertSource)
{
invertcolormap = !invertcolormap;
}
FDynamicColormap *mybasecolormap = basecolormap;
if (vis->RenderStyle.Flags & STYLEF_FadeToBlack)
{
if (invertcolormap)
{
// Fade to white
mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(255,255,255), mybasecolormap->Desaturate);
invertcolormap = false;
}
else
{
// Fade to black
mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(0,0,0), mybasecolormap->Desaturate);
}
}
// get light level
if (fixedlightlev)
{
vis->colormap = basecolormap + fixedlightlev;
if (invertcolormap)
{
mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate);
}
vis->colormap = mybasecolormap->Maps + fixedlightlev;
}
else if (fixedcolormap)
{
@ -1431,12 +1460,20 @@ void R_ProjectSprite (AActor *thing, int fakeside)
else if (!foggy && (thing->renderflags & RF_FULLBRIGHT))
{
// full bright
vis->colormap = basecolormap; // [RH] Use basecolormap
if (invertcolormap)
{
mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate);
}
vis->colormap = mybasecolormap->Maps;
}
else
{
// diminished light
vis->colormap = basecolormap + (GETPALOOKUP (
if (invertcolormap)
{
mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate);
}
vis->colormap = mybasecolormap->Maps + (GETPALOOKUP (
(fixed_t)DivScale12 (r_SpriteVisibility, tz), spriteshade) << COLORMAPSHIFT);
}
}
@ -1587,9 +1624,41 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, fixed_t sx, fixed_
{
vis->alpha = owner->alpha;
vis->RenderStyle = owner->RenderStyle;
// The software renderer cannot invert the source without inverting the overlay
// too. That means if the source is inverted, we need to do the reverse of what
// the invert overlay flag says to do.
INTBOOL invertcolormap = (vis->RenderStyle.Flags & STYLEF_InvertOverlay);
if (vis->RenderStyle.Flags & STYLEF_InvertSource)
{
invertcolormap = !invertcolormap;
}
FDynamicColormap *mybasecolormap = basecolormap;
if (vis->RenderStyle.Flags & STYLEF_FadeToBlack)
{
if (invertcolormap)
{
// Fade to white
mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(255,255,255), mybasecolormap->Desaturate);
invertcolormap = false;
}
else
{
// Fade to black
mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(0,0,0), mybasecolormap->Desaturate);
}
}
if (fixedlightlev)
{
vis->colormap = basecolormap + fixedlightlev;
if (invertcolormap)
{
mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate);
}
vis->colormap = mybasecolormap->Maps + fixedlightlev;
}
else if (fixedcolormap)
{
@ -1599,12 +1668,20 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, fixed_t sx, fixed_
else if (!foggy && psp->state->GetFullbright())
{
// full bright
vis->colormap = basecolormap; // [RH] use basecolormap
if (invertcolormap)
{
mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate);
}
vis->colormap = mybasecolormap->Maps; // [RH] use basecolormap
}
else
{
// local light
vis->colormap = basecolormap + (GETPALOOKUP (0, spriteshade) << COLORMAPSHIFT);
if (invertcolormap)
{
mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate);
}
vis->colormap = mybasecolormap->Maps + (GETPALOOKUP (0, spriteshade) << COLORMAPSHIFT);
}
if (camera->Inventory != NULL)
{
@ -1648,7 +1725,7 @@ void R_DrawPlayerSprites (void)
r_actualextralight = foggy ? 0 : extralight << 4;
// [RH] set basecolormap
basecolormap = sec->ColorMap->Maps;
basecolormap = sec->ColorMap;
// get light level
lightnum = ((floorlight + ceilinglight) >> 1) + r_actualextralight;

View file

@ -471,6 +471,11 @@ void R_InitTranslationTables ()
// Full alpha
for (i = 0; i < 16; ++i)
{
ShadeFakeColormap[i].Color = -1;
ShadeFakeColormap[i].Desaturate = -1;
ShadeFakeColormap[i].Next = NULL;
ShadeFakeColormap[i].Maps = table;
for (j = 0; j < NUMCOLORMAPS; ++j)
{
int a = (NUMCOLORMAPS - j) * 256 / NUMCOLORMAPS * (16-i);
@ -482,6 +487,16 @@ void R_InitTranslationTables ()
table += 256;
}
}
for (i = 0; i < NUMCOLORMAPS*16*256; ++i)
{
assert(shadetables[i] <= 64);
}
// Set up a guaranteed identity map
for (i = 0; i < 256; ++i)
{
identitymap[i] = i;
}
}
void R_DeinitTranslationTables()

View file

@ -200,11 +200,11 @@ static int S_AddPlayerClass (const char *name);
static int S_AddPlayerGender (int classnum, int gender);
static int S_FindPlayerClass (const char *name);
static int S_LookupPlayerSound (int classidx, int gender, int refid);
static void S_ParsePlayerSoundCommon (FString &pclass, int &gender, int &refid);
static void S_ParsePlayerSoundCommon (FScanner &sc, FString &pclass, int &gender, int &refid);
static void S_AddSNDINFO (int lumpnum);
static void S_AddBloodSFX (int lumpnum);
static void S_AddStrifeVoice (int lumpnum);
static int S_AddSound (const char *logicalname, int lumpnum);
static int S_AddSound (const char *logicalname, int lumpnum, FScanner *sc=NULL);
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
@ -470,14 +470,14 @@ int S_FindSoundTentative (const char *name)
// lump. Otherwise, adds the new mapping by using S_AddSoundLump().
//==========================================================================
int S_AddSound (const char *logicalname, const char *lumpname)
int S_AddSound (const char *logicalname, const char *lumpname, FScanner *sc)
{
int lump = Wads.CheckNumForFullName (lumpname);
if (lump == -1) lump = Wads.CheckNumForName (lumpname, ns_sounds);
return S_AddSound (logicalname, lump);
}
static int S_AddSound (const char *logicalname, int lumpnum)
static int S_AddSound (const char *logicalname, int lumpnum, FScanner *sc)
{
int sfxid;
@ -489,7 +489,14 @@ static int S_AddSound (const char *logicalname, int lumpnum)
if (sfx->bPlayerReserve)
{
SC_ScriptError ("Sounds that are reserved for players cannot be reassigned");
if (sc != NULL)
{
sc->ScriptError ("Sounds that are reserved for players cannot be reassigned");
}
else
{
I_Error ("Sounds that are reserved for players cannot be reassigned");
}
}
// Redefining a player compatibility sound will redefine the target instead.
if (sfx->bPlayerCompat)
@ -867,23 +874,23 @@ static void S_AddSNDINFO (int lump)
bool skipToEndIf;
TArray<WORD> list;
SC_OpenLumpNum (lump, "SNDINFO");
FScanner sc(lump, "SNDINFO");
skipToEndIf = false;
while (SC_GetString ())
while (sc.GetString ())
{
if (skipToEndIf)
{
if (SC_Compare ("$endif"))
if (sc.Compare ("$endif"))
{
skipToEndIf = false;
}
continue;
}
if (sc_String[0] == '$')
if (sc.String[0] == '$')
{ // Got a command
switch (SC_MatchString (SICommandStrings))
switch (sc.MatchString (SICommandStrings))
{
case SI_Ambient: {
// $ambient <num> <logical name> [point [atten] | surround | [world]]
@ -891,20 +898,20 @@ static void S_AddSNDINFO (int lump)
// <volume>
AmbientSound *ambient, dummy;
SC_MustGetNumber ();
if (sc_Number < 0 || sc_Number > 255)
sc.MustGetNumber ();
if (sc.Number < 0 || sc.Number > 255)
{
Printf ("Bad ambient index (%d)\n", sc_Number);
Printf ("Bad ambient index (%d)\n", sc.Number);
ambient = &dummy;
}
else if (Ambients[sc_Number] == NULL)
else if (Ambients[sc.Number] == NULL)
{
ambient = new AmbientSound;
Ambients[sc_Number] = ambient;
Ambients[sc.Number] = ambient;
}
else
{
ambient = Ambients[sc_Number];
ambient = Ambients[sc.Number];
}
ambient->type = 0;
ambient->periodmin = 0;
@ -913,22 +920,22 @@ static void S_AddSNDINFO (int lump)
ambient->attenuation = 0;
ambient->sound = "";
SC_MustGetString ();
ambient->sound = sc_String;
sc.MustGetString ();
ambient->sound = sc.String;
ambient->attenuation = 0;
SC_MustGetString ();
if (SC_Compare ("point"))
sc.MustGetString ();
if (sc.Compare ("point"))
{
float attenuation;
ambient->type = POSITIONAL;
SC_MustGetString ();
sc.MustGetString ();
if (IsFloat (sc_String))
if (IsFloat (sc.String))
{
attenuation = atof (sc_String);
SC_MustGetString ();
attenuation = atof (sc.String);
sc.MustGetString ();
if (attenuation > 0)
{
ambient->attenuation = attenuation;
@ -943,45 +950,45 @@ static void S_AddSNDINFO (int lump)
ambient->attenuation = 1;
}
}
else if (SC_Compare ("surround"))
else if (sc.Compare ("surround"))
{
ambient->type = SURROUND;
SC_MustGetString ();
sc.MustGetString ();
ambient->attenuation = -1;
}
else
{ // World is an optional keyword
if (SC_Compare ("world"))
if (sc.Compare ("world"))
{
SC_MustGetString ();
sc.MustGetString ();
}
}
if (SC_Compare ("continuous"))
if (sc.Compare ("continuous"))
{
ambient->type |= CONTINUOUS;
}
else if (SC_Compare ("random"))
else if (sc.Compare ("random"))
{
ambient->type |= RANDOM;
SC_MustGetFloat ();
ambient->periodmin = (int)(sc_Float * TICRATE);
SC_MustGetFloat ();
ambient->periodmax = (int)(sc_Float * TICRATE);
sc.MustGetFloat ();
ambient->periodmin = (int)(sc.Float * TICRATE);
sc.MustGetFloat ();
ambient->periodmax = (int)(sc.Float * TICRATE);
}
else if (SC_Compare ("periodic"))
else if (sc.Compare ("periodic"))
{
ambient->type |= PERIODIC;
SC_MustGetFloat ();
ambient->periodmin = (int)(sc_Float * TICRATE);
sc.MustGetFloat ();
ambient->periodmin = (int)(sc.Float * TICRATE);
}
else
{
Printf ("Unknown ambient type (%s)\n", sc_String);
Printf ("Unknown ambient type (%s)\n", sc.String);
}
SC_MustGetFloat ();
ambient->volume = sc_Float;
sc.MustGetFloat ();
ambient->volume = sc.Float;
if (ambient->volume > 1)
ambient->volume = 1;
else if (ambient->volume < 0)
@ -994,13 +1001,13 @@ static void S_AddSNDINFO (int lump)
level_info_t *info;
char temp[16];
SC_MustGetNumber ();
sprintf (temp, "MAP%02d", sc_Number);
sc.MustGetNumber ();
sprintf (temp, "MAP%02d", sc.Number);
info = FindLevelInfo (temp);
SC_MustGetString ();
if (info->mapname[0] && (!(info->flags&LEVEL_MUSICDEFINED)))
sc.MustGetString ();
if (info->mapname[0] && (!(info->flags & LEVEL_MUSICDEFINED)))
{
ReplaceString (&info->music, sc_String);
ReplaceString (&info->music, sc.String);
}
}
break;
@ -1010,7 +1017,7 @@ static void S_AddSNDINFO (int lump)
break;
case SI_ArchivePath:
SC_MustGetString (); // Unused for now
sc.MustGetString (); // Unused for now
break;
case SI_PlayerSound: {
@ -1018,8 +1025,8 @@ static void S_AddSNDINFO (int lump)
FString pclass;
int gender, refid;
S_ParsePlayerSoundCommon (pclass, gender, refid);
S_AddPlayerSound (pclass, gender, refid, sc_String);
S_ParsePlayerSoundCommon (sc, pclass, gender, refid);
S_AddPlayerSound (pclass, gender, refid, sc.String);
}
break;
@ -1028,11 +1035,11 @@ static void S_AddSNDINFO (int lump)
FString pclass;
int gender, refid, targid;
S_ParsePlayerSoundCommon (pclass, gender, refid);
targid = S_FindSoundNoHash (sc_String);
S_ParsePlayerSoundCommon (sc, pclass, gender, refid);
targid = S_FindSoundNoHash (sc.String);
if (!S_sfx[targid].bPlayerReserve)
{
SC_ScriptError ("%s is not a player sound", sc_String);
sc.ScriptError ("%s is not a player sound", sc.String);
}
S_DupPlayerSound (pclass, gender, refid, targid);
}
@ -1044,8 +1051,8 @@ static void S_AddSNDINFO (int lump)
int gender, refid;
int sfxfrom, aliasto;
S_ParsePlayerSoundCommon (pclass, gender, refid);
sfxfrom = S_AddSound (sc_String, -1);
S_ParsePlayerSoundCommon (sc, pclass, gender, refid);
sfxfrom = S_AddSound (sc.String, -1, &sc);
aliasto = S_LookupPlayerSound (pclass, gender, refid);
S_sfx[sfxfrom].link = aliasto;
S_sfx[sfxfrom].bPlayerCompat = true;
@ -1058,8 +1065,8 @@ static void S_AddSNDINFO (int lump)
int gender, refid;
int soundnum;
S_ParsePlayerSoundCommon (pclass, gender, refid);
soundnum = S_FindSoundTentative (sc_String);
S_ParsePlayerSoundCommon (sc, pclass, gender, refid);
soundnum = S_FindSoundTentative (sc.String);
S_AddPlayerSoundExisting (pclass, gender, refid, soundnum);
}
break;
@ -1068,14 +1075,14 @@ static void S_AddSNDINFO (int lump)
// $alias <name of alias> <name of real sound>
int sfxfrom;
SC_MustGetString ();
sfxfrom = S_AddSound (sc_String, -1);
SC_MustGetString ();
sc.MustGetString ();
sfxfrom = S_AddSound (sc.String, -1, &sc);
sc.MustGetString ();
if (S_sfx[sfxfrom].bPlayerCompat)
{
sfxfrom = S_sfx[sfxfrom].link;
}
S_sfx[sfxfrom].link = S_FindSoundTentative (sc_String);
S_sfx[sfxfrom].link = S_FindSoundTentative (sc.String);
}
break;
@ -1083,12 +1090,12 @@ static void S_AddSNDINFO (int lump)
// $limit <logical name> <max channels>
int sfx;
SC_MustGetString ();
sfx = S_FindSoundTentative (sc_String);
SC_MustGetNumber ();
//S_sfx[sfx].MaxChannels = clamp<BYTE> (sc_Number, 0, 255);
sc.MustGetString ();
sfx = S_FindSoundTentative (sc.String);
sc.MustGetNumber ();
//S_sfx[sfx].MaxChannels = clamp<BYTE> (sc.Number, 0, 255);
//Can't use clamp because of GCC bugs
S_sfx[sfx].MaxChannels = MIN (MAX (sc_Number, 0), 255);
S_sfx[sfx].MaxChannels = MIN (MAX (sc.Number, 0), 255);
}
break;
@ -1096,8 +1103,8 @@ static void S_AddSNDINFO (int lump)
// $singular <logical name>
int sfx;
SC_MustGetString ();
sfx = S_FindSoundTentative (sc_String);
sc.MustGetString ();
sfx = S_FindSoundTentative (sc.String);
S_sfx[sfx].bSingular = true;
}
break;
@ -1106,17 +1113,17 @@ static void S_AddSNDINFO (int lump)
// $pitchshift <logical name> <pitch shift amount>
int sfx;
SC_MustGetString ();
sfx = S_FindSoundTentative (sc_String);
SC_MustGetNumber ();
S_sfx[sfx].PitchMask = (1 << clamp (sc_Number, 0, 7)) - 1;
sc.MustGetString ();
sfx = S_FindSoundTentative (sc.String);
sc.MustGetNumber ();
S_sfx[sfx].PitchMask = (1 << clamp (sc.Number, 0, 7)) - 1;
}
break;
case SI_PitchShiftRange:
// $pitchshiftrange <pitch shift amount>
SC_MustGetNumber ();
CurrentPitchMask = (1 << clamp (sc_Number, 0, 7)) - 1;
sc.MustGetNumber ();
CurrentPitchMask = (1 << clamp (sc.Number, 0, 7)) - 1;
break;
case SI_Random: {
@ -1124,15 +1131,15 @@ static void S_AddSNDINFO (int lump)
FRandomSoundList random;
list.Clear ();
SC_MustGetString ();
random.SfxHead = S_AddSound (sc_String, -1);
SC_MustGetStringName ("{");
while (SC_GetString () && !SC_Compare ("}"))
sc.MustGetString ();
random.SfxHead = S_AddSound (sc.String, -1, &sc);
sc.MustGetStringName ("{");
while (sc.GetString () && !sc.Compare ("}"))
{
WORD sfxto = S_FindSoundTentative (sc_String);
WORD sfxto = S_FindSoundTentative (sc.String);
if (sfxto == random.SfxHead)
{
Printf("Definition of random sound '%s' refers to itself recursively.", sc_String);
Printf("Definition of random sound '%s' refers to itself recursively.", sc.String);
continue;
}
list.Push (sfxto);
@ -1153,11 +1160,11 @@ static void S_AddSNDINFO (int lump)
break;
case SI_MusicVolume: {
SC_MustGetString();
FString musname (sc_String);
SC_MustGetFloat();
sc.MustGetString();
FString musname (sc.String);
sc.MustGetFloat();
FMusicVolume *mv = (FMusicVolume *)M_Malloc (sizeof(*mv) + musname.Len());
mv->Volume = sc_Float;
mv->Volume = sc.Float;
strcpy (mv->MusicName, musname);
mv->Next = MusicVolumes;
MusicVolumes = mv;
@ -1165,14 +1172,14 @@ static void S_AddSNDINFO (int lump)
break;
case SI_MidiDevice: {
SC_MustGetString();
FName nm = sc_String;
SC_MustGetString();
if (SC_Compare("timidity")) MidiDevices[nm] = 1;
else if (SC_Compare("standard")) MidiDevices[nm] = 0;
else if (SC_Compare("opl")) MidiDevices[nm] = 2;
else if (SC_Compare("default")) MidiDevices[nm] = -1;
else SC_ScriptError("Unknown MIDI device %s\n", sc_String);
sc.MustGetString();
FName nm = sc.String;
sc.MustGetString();
if (sc.Compare("timidity")) MidiDevices[nm] = 1;
else if (sc.Compare("standard")) MidiDevices[nm] = 0;
else if (sc.Compare("opl")) MidiDevices[nm] = 2;
else if (sc.Compare("default")) MidiDevices[nm] = -1;
else sc.ScriptError("Unknown MIDI device %s\n", sc.String);
}
break;
@ -1207,12 +1214,11 @@ static void S_AddSNDINFO (int lump)
}
else
{ // Got a logical sound mapping
FString name (sc_String);
SC_MustGetString ();
S_AddSound (name, sc_String);
FString name (sc.String);
sc.MustGetString ();
S_AddSound (name, sc.String, &sc);
}
}
SC_Close ();
}
//==========================================================================
@ -1273,21 +1279,21 @@ static void S_AddStrifeVoice (int lumpnum)
// (player class, gender, and ref id)
//==========================================================================
static void S_ParsePlayerSoundCommon (FString &pclass, int &gender, int &refid)
static void S_ParsePlayerSoundCommon (FScanner &sc, FString &pclass, int &gender, int &refid)
{
SC_MustGetString ();
pclass = sc_String;
SC_MustGetString ();
gender = D_GenderToInt (sc_String);
SC_MustGetString ();
refid = S_FindSoundNoHash (sc_String);
sc.MustGetString ();
pclass = sc.String;
sc.MustGetString ();
gender = D_GenderToInt (sc.String);
sc.MustGetString ();
refid = S_FindSoundNoHash (sc.String);
if (refid != 0 && !S_sfx[refid].bPlayerReserve && !S_sfx[refid].bTentative)
{
SC_ScriptError ("%s has already been used for a non-player sound.", sc_String);
sc.ScriptError ("%s has already been used for a non-player sound.", sc.String);
}
if (refid == 0)
{
refid = S_AddSound (sc_String, -1);
refid = S_AddSound (sc.String, -1, &sc);
S_sfx[refid].bTentative = true;
}
if (S_sfx[refid].bTentative)
@ -1296,7 +1302,7 @@ static void S_ParsePlayerSoundCommon (FString &pclass, int &gender, int &refid)
S_sfx[refid].bTentative = false;
S_sfx[refid].bPlayerReserve = true;
}
SC_MustGetString ();
sc.MustGetString ();
}
//==========================================================================

View file

@ -465,8 +465,9 @@ FArchive &operator<< (FArchive &arc, ReverbContainer *&env)
return arc;
}
static void ReadEAX ()
static void ReadEAX (int lump, const char *lumpname)
{
FScanner sc;
const ReverbContainer *def;
ReverbContainer *newenv;
REVERB_PROPERTIES props;
@ -475,45 +476,46 @@ static void ReadEAX ()
bool inited[NUM_EAX_FIELDS];
BYTE bools[32];
while (SC_GetString ())
sc.OpenLumpNum(lump, lumpname);
while (sc.GetString ())
{
name = copystring (sc_String);
SC_MustGetNumber ();
id1 = sc_Number;
SC_MustGetNumber ();
id2 = sc_Number;
SC_MustGetStringName ("{");
name = copystring (sc.String);
sc.MustGetNumber ();
id1 = sc.Number;
sc.MustGetNumber ();
id2 = sc.Number;
sc.MustGetStringName ("{");
memset (inited, 0, sizeof(inited));
props.Flags = 0;
while (SC_MustGetString (), NUM_EAX_FIELDS > (i = SC_MustMatchString (EAXFieldNames)))
while (sc.MustGetString (), NUM_EAX_FIELDS > (i = sc.MustMatchString (EAXFieldNames)))
{
if (EAXFields[i].Float)
{
SC_MustGetFloat ();
props.*EAXFields[i].Float = clamp (sc_Float,
sc.MustGetFloat ();
props.*EAXFields[i].Float = clamp (sc.Float,
double(EAXFields[i].Min)/1000,
double(EAXFields[i].Max)/1000);
}
else if (EAXFields[i].Int)
{
SC_MustGetNumber ();
props.*EAXFields[i].Int = (j = clamp (sc_Number,
sc.MustGetNumber ();
props.*EAXFields[i].Int = (j = clamp (sc.Number,
EAXFields[i].Min, EAXFields[i].Max));
if (i == 0 && j != sc_Number)
if (i == 0 && j != sc.Number)
{
SC_ScriptError ("The Environment field is out of range.");
sc.ScriptError ("The Environment field is out of range.");
}
}
else
{
SC_MustGetString ();
bools[EAXFields[i].Flag] = SC_MustMatchString (BoolNames);
sc.MustGetString ();
bools[EAXFields[i].Flag] = sc.MustMatchString (BoolNames);
}
inited[i] = true;
}
if (!inited[0])
{
SC_ScriptError ("Sound %s is missing an Environment field.", name);
sc.ScriptError ("Sound %s is missing an Environment field.", name);
}
// Add the new environment to the list, filling in uninitialized fields
@ -573,9 +575,7 @@ void S_ParseSndEax ()
while ((lump = Wads.FindLump ("SNDEAX", &lastlump)) != -1)
{
SC_OpenLumpNum (lump, "SNDEAX");
ReadEAX ();
SC_Close ();
ReadEAX (lump, "SNDEAX");
}
}

View file

@ -161,7 +161,7 @@ struct FSoundSequencePtrArray : public TArray<FSoundSequence *>
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
static void AssignTranslations (int seq, seqtype_t type);
static void AssignTranslations (FScanner &sc, int seq, seqtype_t type);
static void AssignHexenTranslations (void);
static void AddSequence (int curseq, FName seqname, FName slot, int stopsound, const TArray<DWORD> &ScriptTemp);
static int FindSequence (const char *searchname);
@ -388,19 +388,19 @@ void DSeqSectorNode::Serialize (FArchive &arc)
//
//==========================================================================
static void AssignTranslations (int seq, seqtype_t type)
static void AssignTranslations (FScanner &sc, int seq, seqtype_t type)
{
sc_Crossed = false;
sc.Crossed = false;
while (SC_GetString () && !sc_Crossed)
while (sc.GetString () && !sc.Crossed)
{
if (IsNum (sc_String))
if (IsNum (sc.String))
{
SeqTrans[(atoi(sc_String) & 63) + type * 64] = seq;
SeqTrans[(atoi(sc.String) & 63) + type * 64] = seq;
}
}
SC_UnGet ();
sc.UnGet ();
}
//==========================================================================
@ -481,17 +481,17 @@ void S_ParseSndSeq (int levellump)
lump = levellump;
levellump = -2;
}
SC_OpenLumpNum (lump, "SNDSEQ");
while (SC_GetString ())
FScanner sc(lump, "SNDSEQ");
while (sc.GetString ())
{
if (*sc_String == ':' || *sc_String == '[')
if (*sc.String == ':' || *sc.String == '[')
{
if (curseq != -1)
{
SC_ScriptError ("S_ParseSndSeq: Nested Script Error");
sc.ScriptError ("S_ParseSndSeq: Nested Script Error");
}
seqname = sc_String + 1;
seqtype = sc_String[0];
seqname = sc.String + 1;
seqtype = sc.String[0];
for (curseq = 0; curseq < (int)Sequences.Size(); curseq++)
{
if (Sequences[curseq]->SeqName == seqname)
@ -510,7 +510,7 @@ void S_ParseSndSeq (int levellump)
slot = NAME_None;
if (seqtype == '[')
{
SC_SetCMode (true);
sc.SetCMode (true);
ScriptTemp.Push (0); // to be filled when definition is complete
}
continue;
@ -521,101 +521,101 @@ void S_ParseSndSeq (int levellump)
}
if (seqtype == '[')
{
if (sc_String[0] == ']')
if (sc.String[0] == ']')
{ // End of this definition
ScriptTemp[0] = MakeCommand(SS_CMD_SELECT, (ScriptTemp.Size()-1)/2);
AddSequence (curseq, seqname, slot, stopsound, ScriptTemp);
curseq = -1;
SC_SetCMode (false);
sc.SetCMode (false);
}
else
{ // Add a selection
SC_UnGet();
if (SC_CheckNumber())
sc.UnGet();
if (sc.CheckNumber())
{
ScriptTemp.Push (sc_Number);
SC_MustGetString();
ScriptTemp.Push (FName(sc_String));
ScriptTemp.Push (sc.Number);
sc.MustGetString();
ScriptTemp.Push (FName(sc.String));
}
else
{
AssignTranslations (curseq, seqtype_t(SC_MustMatchString (SSStrings + SS_STRING_PLATFORM)));
AssignTranslations (sc, curseq, seqtype_t(sc.MustMatchString (SSStrings + SS_STRING_PLATFORM)));
}
}
continue;
}
switch (SC_MustMatchString (SSStrings))
switch (sc.MustMatchString (SSStrings))
{
case SS_STRING_PLAYUNTILDONE:
SC_MustGetString ();
ScriptTemp.Push(MakeCommand(SS_CMD_PLAY, S_FindSound (sc_String)));
sc.MustGetString ();
ScriptTemp.Push(MakeCommand(SS_CMD_PLAY, S_FindSound (sc.String)));
ScriptTemp.Push(MakeCommand(SS_CMD_WAITUNTILDONE, 0));
break;
case SS_STRING_PLAY:
SC_MustGetString ();
ScriptTemp.Push(MakeCommand(SS_CMD_PLAY, S_FindSound (sc_String)));
sc.MustGetString ();
ScriptTemp.Push(MakeCommand(SS_CMD_PLAY, S_FindSound (sc.String)));
break;
case SS_STRING_PLAYTIME:
SC_MustGetString ();
ScriptTemp.Push(MakeCommand(SS_CMD_PLAY, S_FindSound (sc_String)));
SC_MustGetNumber ();
ScriptTemp.Push(MakeCommand(SS_CMD_DELAY, sc_Number));
sc.MustGetString ();
ScriptTemp.Push(MakeCommand(SS_CMD_PLAY, S_FindSound (sc.String)));
sc.MustGetNumber ();
ScriptTemp.Push(MakeCommand(SS_CMD_DELAY, sc.Number));
break;
case SS_STRING_PLAYREPEAT:
SC_MustGetString ();
ScriptTemp.Push(MakeCommand (SS_CMD_PLAYREPEAT, S_FindSound (sc_String)));
sc.MustGetString ();
ScriptTemp.Push(MakeCommand (SS_CMD_PLAYREPEAT, S_FindSound (sc.String)));
break;
case SS_STRING_PLAYLOOP:
SC_MustGetString ();
ScriptTemp.Push(MakeCommand (SS_CMD_PLAYLOOP, S_FindSound (sc_String)));
SC_MustGetNumber ();
ScriptTemp.Push(sc_Number);
sc.MustGetString ();
ScriptTemp.Push(MakeCommand (SS_CMD_PLAYLOOP, S_FindSound (sc.String)));
sc.MustGetNumber ();
ScriptTemp.Push(sc.Number);
break;
case SS_STRING_DELAY:
SC_MustGetNumber ();
ScriptTemp.Push(MakeCommand(SS_CMD_DELAY, sc_Number));
sc.MustGetNumber ();
ScriptTemp.Push(MakeCommand(SS_CMD_DELAY, sc.Number));
break;
case SS_STRING_DELAYONCE:
SC_MustGetNumber ();
ScriptTemp.Push(MakeCommand(SS_CMD_DELAY, sc_Number));
sc.MustGetNumber ();
ScriptTemp.Push(MakeCommand(SS_CMD_DELAY, sc.Number));
ScriptTemp.Push(MakeCommand(SS_CMD_LAST2NOP, 0));
break;
case SS_STRING_DELAYRAND:
SC_MustGetNumber ();
delaybase = sc_Number;
ScriptTemp.Push(MakeCommand(SS_CMD_DELAYRAND, sc_Number));
SC_MustGetNumber ();
ScriptTemp.Push(MAX(1, sc_Number - delaybase + 1));
sc.MustGetNumber ();
delaybase = sc.Number;
ScriptTemp.Push(MakeCommand(SS_CMD_DELAYRAND, sc.Number));
sc.MustGetNumber ();
ScriptTemp.Push(MAX(1, sc.Number - delaybase + 1));
break;
case SS_STRING_VOLUME: // volume is in range 0..100
SC_MustGetFloat ();
ScriptTemp.Push(MakeCommand(SS_CMD_VOLUME, int(sc_Float * (FRACUNIT/100.f))));
sc.MustGetFloat ();
ScriptTemp.Push(MakeCommand(SS_CMD_VOLUME, int(sc.Float * (FRACUNIT/100.f))));
break;
case SS_STRING_VOLUMEREL:
SC_MustGetFloat ();
ScriptTemp.Push(MakeCommand(SS_CMD_VOLUMEREL, int(sc_Float * (FRACUNIT/100.f))));
sc.MustGetFloat ();
ScriptTemp.Push(MakeCommand(SS_CMD_VOLUMEREL, int(sc.Float * (FRACUNIT/100.f))));
break;
case SS_STRING_VOLUMERAND:
SC_MustGetFloat ();
volumebase = sc_Float;
ScriptTemp.Push(MakeCommand(SS_CMD_VOLUMERAND, int(sc_Float * (FRACUNIT/100.f))));
SC_MustGetFloat ();
ScriptTemp.Push(int((sc_Float - volumebase) * (256/100.f)));
sc.MustGetFloat ();
volumebase = sc.Float;
ScriptTemp.Push(MakeCommand(SS_CMD_VOLUMERAND, int(sc.Float * (FRACUNIT/100.f))));
sc.MustGetFloat ();
ScriptTemp.Push(int((sc.Float - volumebase) * (256/100.f)));
break;
case SS_STRING_STOPSOUND:
SC_MustGetString ();
stopsound = S_FindSound (sc_String);
sc.MustGetString ();
stopsound = S_FindSound (sc.String);
ScriptTemp.Push(MakeCommand(SS_CMD_STOPSOUND, 0));
break;
@ -625,8 +625,8 @@ void S_ParseSndSeq (int levellump)
break;
case SS_STRING_ATTENUATION:
SC_MustGetString ();
ScriptTemp.Push(MakeCommand(SS_CMD_ATTENUATION, SC_MustMatchString(Attenuations)));
sc.MustGetString ();
ScriptTemp.Push(MakeCommand(SS_CMD_ATTENUATION, sc.MustMatchString(Attenuations)));
break;
case SS_STRING_RANDOMSEQUENCE:
@ -643,24 +643,23 @@ void S_ParseSndSeq (int levellump)
break;
case SS_STRING_PLATFORM:
AssignTranslations (curseq, SEQ_PLATFORM);
AssignTranslations (sc, curseq, SEQ_PLATFORM);
break;
case SS_STRING_DOOR:
AssignTranslations (curseq, SEQ_DOOR);
AssignTranslations (sc, curseq, SEQ_DOOR);
break;
case SS_STRING_ENVIRONMENT:
AssignTranslations (curseq, SEQ_ENVIRONMENT);
AssignTranslations (sc, curseq, SEQ_ENVIRONMENT);
break;
case SS_STRING_SLOT:
SC_MustGetString();
slot = sc_String;
sc.MustGetString();
slot = sc.String;
break;
}
}
SC_Close ();
}
if (gameinfo.gametype == GAME_Hexen)

View file

@ -25,6 +25,7 @@
#include "tarray.h"
class AActor;
class FScanner;
//
// SoundFX struct.
@ -196,7 +197,7 @@ int S_FindSkinnedSound (AActor *actor, const char *logicalname);
int S_FindSkinnedSoundEx (AActor *actor, const char *logicalname, const char *extendedname);
int S_FindSkinnedSound (AActor *actor, int refid);
int S_FindSoundByLump (int lump);
int S_AddSound (const char *logicalname, const char *lumpname); // Add sound by lumpname
int S_AddSound (const char *logicalname, const char *lumpname, FScanner *sc=NULL); // Add sound by lumpname
int S_AddSoundLump (const char *logicalname, int lump); // Add sound by lump index
int S_AddPlayerSound (const char *playerclass, const int gender, int refid, const char *lumpname);
int S_AddPlayerSound (const char *playerclass, const int gender, int refid, int lumpnum, bool fromskin=false);

File diff suppressed because it is too large Load diff

View file

@ -1,40 +1,98 @@
#ifndef __SC_MAN_H__
#define __SC_MAN_H__
void SC_Open (const char *name);
void SC_OpenFile (const char *name);
void SC_OpenMem (const char *name, char *buffer, int size);
void SC_OpenLumpNum (int lump, const char *name);
void SC_Close (void);
void SC_SetCMode (bool cmode);
void SC_SetEscape (bool esc);
void SC_SavePos (void);
void SC_RestorePos (void);
FString SC_TokenName (int token, const char *string=NULL);
bool SC_GetString (void);
void SC_MustGetString (void);
void SC_MustGetStringName (const char *name);
bool SC_CheckString (const char *name);
bool SC_GetToken (void);
void SC_MustGetAnyToken (void);
void SC_TokenMustBe (int token);
void SC_MustGetToken (int token);
bool SC_CheckToken (int token);
bool SC_CheckTokenId (ENamedName id);
bool SC_GetNumber (void);
void SC_MustGetNumber (void);
bool SC_CheckNumber (void);
bool SC_CheckFloat (void);
bool SC_GetFloat (void);
void SC_MustGetFloat (void);
void SC_UnGet (void);
//boolean SC_Check(void);
bool SC_Compare (const char *text);
int SC_MatchString (const char **strings);
int SC_MustMatchString (const char **strings);
void STACK_ARGS SC_ScriptError (const char *message, ...);
void SC_SaveScriptState();
void SC_RestoreScriptState();
class FScanner
{
public:
struct SavedPos
{
const char *SavedScriptPtr;
int SavedScriptLine;
};
// Methods ------------------------------------------------------
FScanner();
FScanner(const FScanner &other);
FScanner(int lumpnum, const char *name);
~FScanner();
FScanner &operator=(const FScanner &other);
void Open(const char *lumpname);
void OpenFile(const char *filename);
void OpenMem(const char *name, char *buffer, int size);
void OpenLumpNum(int lump, const char *name);
void Close();
void SetCMode(bool cmode);
void SetEscape(bool esc);
const SavedPos SavePos();
void RestorePos(const SavedPos &pos);
FString TokenName(int token, const char *string=NULL);
bool GetString();
void MustGetString();
void MustGetStringName(const char *name);
bool CheckString(const char *name);
bool GetToken();
void MustGetAnyToken();
void TokenMustBe(int token);
void MustGetToken(int token);
bool CheckToken(int token);
bool CheckTokenId(ENamedName id);
bool GetNumber();
void MustGetNumber();
bool CheckNumber();
bool GetFloat();
void MustGetFloat();
bool CheckFloat();
void UnGet();
bool Compare(const char *text);
int MatchString(const char **strings);
int MustMatchString(const char **strings);
void ScriptError(const char *message, ...);
// Members ------------------------------------------------------
char *String;
int StringLen;
int TokenType;
int Number;
double Float;
FName Name;
int Line;
bool End;
bool Crossed;
protected:
void PrepareScript();
void CheckOpen();
bool ScanString(bool tokens);
// Strings longer than this minus one will be dynamically allocated.
static const int MAX_STRING_SIZE = 128;
bool ScriptOpen;
FString ScriptName;
FString ScriptBuffer;
const char *ScriptPtr;
const char *ScriptEndPtr;
char StringBuffer[MAX_STRING_SIZE];
FString BigStringBuffer;
bool AlreadyGot;
int AlreadyGotLine;
bool LastGotToken;
const char *LastGotPtr;
int LastGotLine;
bool CMode;
bool Escape;
};
enum
{
@ -152,15 +210,4 @@ enum
TK_LastToken
};
extern int sc_TokenType;
extern char *sc_String;
extern unsigned int sc_StringLen;
extern int sc_Number;
extern double sc_Float;
extern FName sc_Name;
extern int sc_Line;
extern bool sc_End;
extern bool sc_Crossed;
extern bool sc_FileScripts;
#endif //__SC_MAN_H__

View file

@ -23,8 +23,8 @@
//#define YYDEBUG(s,c) { Printf ("%d: %02x\n", s, c); }
#define YYDEBUG(s,c)
char *cursor = ScriptPtr;
char *limit = ScriptEndPtr;
const char *cursor = ScriptPtr;
const char *limit = ScriptEndPtr;
std1:
tok = YYCURSOR;
@ -33,7 +33,7 @@ std2:
if (tokens) // A well-defined scanner, based on the c.re example.
{
#define RET(x) sc_TokenType = x; goto normal_token;
#define RET(x) TokenType = x; goto normal_token;
#line 39 "src/sc_man_scanner.h"
{
@ -482,7 +482,7 @@ yy24:
yy25:
#line 216 "src/sc_man_scanner.re"
{
SC_ScriptError ("Unexpected character: %c (ASCII %d)\n", *tok, *tok);
ScriptError ("Unexpected character: %c (ASCII %d)\n", *tok, *tok);
goto std1;
}
#line 489 "src/sc_man_scanner.h"
@ -4396,7 +4396,7 @@ yy683:
negative_check:
// re2c doesn't have enough state to handle '-' as the start of a negative number
// and as its own token, so help it out a little.
sc_TokenType = '-';
TokenType = '-';
if (YYCURSOR >= YYLIMIT)
{
goto normal_token;
@ -4440,8 +4440,8 @@ yy689:
return_val = false;
goto end;
}
sc_Line++;
sc_Crossed = true;
Line++;
Crossed = true;
goto comment;
}
#line 4448 "src/sc_man_scanner.h"
@ -4472,23 +4472,45 @@ newline:
return_val = false;
goto end;
}
sc_Line++;
sc_Crossed = true;
Line++;
Crossed = true;
goto std1;
normal_token:
ScriptPtr = (YYCURSOR >= YYLIMIT) ? ScriptEndPtr : cursor;
sc_StringLen = (unsigned int)MIN<size_t> (ScriptPtr - tok, MAX_STRING_SIZE-1);
if (tokens && (sc_TokenType == TK_StringConst || sc_TokenType == TK_NameConst))
StringLen = int(ScriptPtr - tok);
if (tokens && (TokenType == TK_StringConst || TokenType == TK_NameConst))
{
sc_StringLen -= 2;
memcpy (sc_String, tok+1, sc_StringLen);
StringLen -= 2;
if (StringLen >= MAX_STRING_SIZE)
{
BigStringBuffer = FString(tok+1, StringLen);
}
else
{
memcpy (StringBuffer, tok+1, StringLen);
}
}
else
{
memcpy (sc_String, tok, sc_StringLen);
if (StringLen >= MAX_STRING_SIZE)
{
BigStringBuffer = FString(tok, StringLen);
}
else
{
memcpy (StringBuffer, tok, StringLen);
}
}
if (StringLen < MAX_STRING_SIZE)
{
String = StringBuffer;
StringBuffer[StringLen] = '\0';
}
else
{
String = BigStringBuffer.LockBuffer();
}
sc_String[sc_StringLen] = '\0';
return_val = true;
goto end;
@ -4500,7 +4522,8 @@ string:
goto end;
}
ScriptPtr = cursor;
for (sc_StringLen = 0; cursor < YYLIMIT; ++cursor)
BigStringBuffer = "";
for (StringLen = 0; cursor < YYLIMIT; ++cursor)
{
if (Escape && *cursor == '\\' && *(cursor + 1) == '"')
{
@ -4518,24 +4541,36 @@ string:
{
if (CMode)
{
if (!Escape || sc_StringLen == 0 || sc_String[sc_StringLen - 1] != '\\')
if (!Escape || StringLen == 0 || String[StringLen - 1] != '\\')
{
SC_ScriptError ("Unterminated string constant");
ScriptError ("Unterminated string constant");
}
else
{
sc_StringLen--; // overwrite the \ character with \n
StringLen--; // overwrite the \ character with \n
}
}
sc_Line++;
sc_Crossed = true;
Line++;
Crossed = true;
}
if (sc_StringLen < MAX_STRING_SIZE-1)
if (StringLen == MAX_STRING_SIZE)
{
sc_String[sc_StringLen++] = *cursor;
BigStringBuffer.AppendCStrPart(StringBuffer, StringLen);
StringLen = 0;
}
StringBuffer[StringLen++] = *cursor;
}
if (BigStringBuffer.IsNotEmpty() || StringLen == MAX_STRING_SIZE)
{
BigStringBuffer.AppendCStrPart(StringBuffer, StringLen);
String = BigStringBuffer.LockBuffer();
StringLen = int(BigStringBuffer.Len());
}
else
{
String = StringBuffer;
StringBuffer[StringLen] = '\0';
}
ScriptPtr = cursor + 1;
sc_String[sc_StringLen] = '\0';
return_val = true;
end:

View file

@ -21,8 +21,8 @@
//#define YYDEBUG(s,c) { Printf ("%d: %02x\n", s, c); }
#define YYDEBUG(s,c)
char *cursor = ScriptPtr;
char *limit = ScriptEndPtr;
const char *cursor = ScriptPtr;
const char *limit = ScriptEndPtr;
std1:
tok = YYCURSOR;
@ -51,7 +51,7 @@ std2:
*/
if (tokens) // A well-defined scanner, based on the c.re example.
{
#define RET(x) sc_TokenType = x; goto normal_token;
#define RET(x) TokenType = x; goto normal_token;
/*!re2c
"/*" { goto comment; } /* C comment */
"//" (any\"\n")* "\n" { goto newline; } /* C++ comment */
@ -214,7 +214,7 @@ std2:
"\n" { goto newline; }
any
{
SC_ScriptError ("Unexpected character: %c (ASCII %d)\n", *tok, *tok);
ScriptError ("Unexpected character: %c (ASCII %d)\n", *tok, *tok);
goto std1;
}
*/
@ -265,7 +265,7 @@ std2:
negative_check:
// re2c doesn't have enough state to handle '-' as the start of a negative number
// and as its own token, so help it out a little.
sc_TokenType = '-';
TokenType = '-';
if (YYCURSOR >= YYLIMIT)
{
goto normal_token;
@ -304,8 +304,8 @@ comment:
return_val = false;
goto end;
}
sc_Line++;
sc_Crossed = true;
Line++;
Crossed = true;
goto comment;
}
any { goto comment; }
@ -318,23 +318,45 @@ newline:
return_val = false;
goto end;
}
sc_Line++;
sc_Crossed = true;
Line++;
Crossed = true;
goto std1;
normal_token:
ScriptPtr = (YYCURSOR >= YYLIMIT) ? ScriptEndPtr : cursor;
sc_StringLen = (unsigned int)MIN<size_t> (ScriptPtr - tok, MAX_STRING_SIZE-1);
if (tokens && (sc_TokenType == TK_StringConst || sc_TokenType == TK_NameConst))
StringLen = int(ScriptPtr - tok);
if (tokens && (TokenType == TK_StringConst || TokenType == TK_NameConst))
{
sc_StringLen -= 2;
memcpy (sc_String, tok+1, sc_StringLen);
StringLen -= 2;
if (StringLen >= MAX_STRING_SIZE)
{
BigStringBuffer = FString(tok+1, StringLen);
}
else
{
memcpy (StringBuffer, tok+1, StringLen);
}
}
else
{
memcpy (sc_String, tok, sc_StringLen);
if (StringLen >= MAX_STRING_SIZE)
{
BigStringBuffer = FString(tok, StringLen);
}
else
{
memcpy (StringBuffer, tok, StringLen);
}
}
if (StringLen < MAX_STRING_SIZE)
{
String = StringBuffer;
StringBuffer[StringLen] = '\0';
}
else
{
String = BigStringBuffer.LockBuffer();
}
sc_String[sc_StringLen] = '\0';
return_val = true;
goto end;
@ -346,7 +368,8 @@ string:
goto end;
}
ScriptPtr = cursor;
for (sc_StringLen = 0; cursor < YYLIMIT; ++cursor)
BigStringBuffer = "";
for (StringLen = 0; cursor < YYLIMIT; ++cursor)
{
if (Escape && *cursor == '\\' && *(cursor + 1) == '"')
{
@ -364,24 +387,36 @@ string:
{
if (CMode)
{
if (!Escape || sc_StringLen == 0 || sc_String[sc_StringLen - 1] != '\\')
if (!Escape || StringLen == 0 || String[StringLen - 1] != '\\')
{
SC_ScriptError ("Unterminated string constant");
ScriptError ("Unterminated string constant");
}
else
{
sc_StringLen--; // overwrite the \ character with \n
StringLen--; // overwrite the \ character with \n
}
}
sc_Line++;
sc_Crossed = true;
Line++;
Crossed = true;
}
if (sc_StringLen < MAX_STRING_SIZE-1)
if (StringLen == MAX_STRING_SIZE)
{
sc_String[sc_StringLen++] = *cursor;
BigStringBuffer.AppendCStrPart(StringBuffer, StringLen);
StringLen = 0;
}
StringBuffer[StringLen++] = *cursor;
}
if (BigStringBuffer.IsNotEmpty() || StringLen == MAX_STRING_SIZE)
{
BigStringBuffer.AppendCStrPart(StringBuffer, StringLen);
String = BigStringBuffer.LockBuffer();
StringLen = int(BigStringBuffer.Len());
}
else
{
String = StringBuffer;
StringBuffer[StringLen] = '\0';
}
ScriptPtr = cursor + 1;
sc_String[sc_StringLen] = '\0';
return_val = true;
end:

View file

@ -43,6 +43,7 @@
#include "sc_man.h"
#include "zstring.h"
#include "c_dispatch.h"
#include "v_text.h"
// PassNum identifies which language pass this string is from.
// PassNum 0 is for DeHacked.
@ -148,44 +149,44 @@ void FStringTable::LoadLanguage (int lumpnum, DWORD code, bool exactMatch, int p
code |= orMask;
SC_OpenLumpNum (lumpnum, "LANGUAGE");
SC_SetCMode (true);
while (SC_GetString ())
FScanner sc(lumpnum, "LANGUAGE");
sc.SetCMode (true);
while (sc.GetString ())
{
if (SC_Compare ("["))
if (sc.Compare ("["))
{ // Process language identifiers
bool donot = false;
bool forceskip = false;
skip = true;
SC_MustGetString ();
sc.MustGetString ();
do
{
size_t len = strlen (sc_String);
size_t len = sc.StringLen;
if (len != 2 && len != 3)
{
if (len == 1 && sc_String[0] == '~')
if (len == 1 && sc.String[0] == '~')
{
donot = true;
SC_MustGetString ();
sc.MustGetString ();
continue;
}
if (len == 1 && sc_String[0] == '*')
if (len == 1 && sc.String[0] == '*')
{
inCode = MAKE_ID('*',0,0,0);
}
else if (len == 7 && stricmp (sc_String, "default") == 0)
else if (len == 7 && stricmp (sc.String, "default") == 0)
{
inCode = MAKE_ID('*','*',0,0);
}
else
{
SC_ScriptError ("The language code must be 2 or 3 characters long.\n'%s' is %lu characters long.",
sc_String, len);
sc.ScriptError ("The language code must be 2 or 3 characters long.\n'%s' is %lu characters long.",
sc.String, len);
}
}
else
{
inCode = MAKE_ID(tolower(sc_String[0]), tolower(sc_String[1]), tolower(sc_String[2]), 0);
inCode = MAKE_ID(tolower(sc.String[0]), tolower(sc.String[1]), tolower(sc.String[2]), 0);
}
if ((inCode | orMask) == code)
{
@ -199,11 +200,11 @@ void FStringTable::LoadLanguage (int lumpnum, DWORD code, bool exactMatch, int p
skip = false;
}
}
SC_MustGetString ();
} while (!SC_Compare ("]"));
sc.MustGetString ();
} while (!sc.Compare ("]"));
if (donot)
{
SC_ScriptError ("You must specify a language after ~");
sc.ScriptError ("You must specify a language after ~");
}
skip |= forceskip;
}
@ -211,30 +212,30 @@ void FStringTable::LoadLanguage (int lumpnum, DWORD code, bool exactMatch, int p
{ // Process string definitions.
if (inCode == 0)
{
SC_ScriptError ("Found a string without a language specified.");
sc.ScriptError ("Found a string without a language specified.");
}
if (skip)
{ // We're not interested in this language, so skip the string.
SC_MustGetStringName ("=");
SC_MustGetString ();
sc.MustGetStringName ("=");
sc.MustGetString ();
do
{
SC_MustGetString ();
} while (!SC_Compare (";"));
sc.MustGetString ();
} while (!sc.Compare (";"));
continue;
}
FString strName (sc_String);
SC_MustGetStringName ("=");
SC_MustGetString ();
FString strText (sc_String, ProcessEscapes (sc_String));
SC_MustGetString ();
while (!SC_Compare (";"))
FString strName (sc.String);
sc.MustGetStringName ("=");
sc.MustGetString ();
FString strText (sc.String, ProcessEscapes (sc.String));
sc.MustGetString ();
while (!sc.Compare (";"))
{
ProcessEscapes (sc_String);
strText += sc_String;
SC_MustGetString ();
ProcessEscapes (sc.String);
strText += sc.String;
sc.MustGetString ();
}
// Does this string exist? If so, should we overwrite it?
@ -267,7 +268,6 @@ void FStringTable::LoadLanguage (int lumpnum, DWORD code, bool exactMatch, int p
}
}
}
SC_Close ();
}
// Replace \ escape sequences in a string with the escaped characters.
@ -283,7 +283,7 @@ size_t FStringTable::ProcessEscapes (char *iptr)
if (c == 'n')
c = '\n';
else if (c == 'c')
c = -127 /*0x81*/;
c = TEXTCOLOR_ESCAPE;
else if (c == 'r')
c = '\r';
else if (c == 't')

View file

@ -49,7 +49,7 @@
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
void TEAMINFO_Init ();
void TEAMINFO_ParseTeam ();
void TEAMINFO_ParseTeam (FScanner &sc);
bool TEAMINFO_IsValidTeam (int team);
@ -84,17 +84,16 @@ void TEAMINFO_Init ()
while ((lump = Wads.FindLump ("TEAMINFO", &lastlump)) != -1)
{
SC_OpenLumpNum (lump, "TEAMINFO");
while (SC_GetString ())
FScanner sc(lump, "TEAMINFO");
while (sc.GetString ())
{
if (SC_Compare("CLEARTEAMS"))
if (sc.Compare("CLEARTEAMS"))
teams.Clear ();
else if (SC_Compare("TEAM"))
TEAMINFO_ParseTeam ();
else if (sc.Compare("TEAM"))
TEAMINFO_ParseTeam (sc);
else
SC_ScriptError ("Unknown command %s in TEAMINFO", sc_String);
sc.ScriptError ("Unknown command %s in TEAMINFO", sc.String);
}
SC_Close();
}
if (teams.Size () < 2)
@ -107,36 +106,34 @@ void TEAMINFO_Init ()
//
//==========================================================================
void TEAMINFO_ParseTeam ()
void TEAMINFO_ParseTeam (FScanner &sc)
{
TEAMINFO team;
int i;
char *color;
SC_MustGetString ();
team.name = sc_String;
sc.MustGetString ();
team.name = sc.String;
SC_MustGetStringName("{");
while (!SC_CheckString("}"))
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
SC_MustGetString();
switch(i = SC_MatchString (keywords_teaminfo))
sc.MustGetString();
switch(i = sc.MatchString (keywords_teaminfo))
{
case 0:
SC_MustGetString ();
color = sc_String;
team.playercolor = V_GetColor (NULL, color);
sc.MustGetString ();
team.playercolor = V_GetColor (NULL, sc.String);
break;
case 1:
SC_MustGetString();
sc.MustGetString();
team.textcolor = '[';
team.textcolor << sc_String << ']';
team.textcolor << sc.String << ']';
break;
case 2:
SC_MustGetString ();
team.logo = sc_String;
sc.MustGetString ();
team.logo = sc.String;
break;
default:

View file

@ -110,8 +110,8 @@ void A_ActiveSound (AActor *);
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
static void ParseInsideDecoration (FActorInfo *info, AActor *defaults,
TArray<FState> &states, FExtraInfo &extra, EDefinitionType def);
static void ParseSpriteFrames (FActorInfo *info, TArray<FState> &states);
TArray<FState> &states, FExtraInfo &extra, EDefinitionType def, FScanner &sc);
static void ParseSpriteFrames (FActorInfo *info, TArray<FState> &states, FScanner &sc);
// PRIVATE DATA DEFINITIONS ------------------------------------------------
@ -229,7 +229,7 @@ static const char *FlagNames3[] =
//
//==========================================================================
void ParseOldDecoration(EDefinitionType def)
void ParseOldDecoration(FScanner &sc, EDefinitionType def)
{
TArray<FState> states;
FExtraInfo extra;
@ -241,37 +241,37 @@ void ParseOldDecoration(EDefinitionType def)
if (def == DEF_Pickup) parent = RUNTIME_CLASS(AFakeInventory);
else parent = RUNTIME_CLASS(AActor);
SC_MustGetString();
typeName = FName(sc_String);
sc.MustGetString();
typeName = FName(sc.String);
type = parent->CreateDerivedClass (typeName, parent->Size);
info = type->ActorInfo;
info->GameFilter = 0x80;
MakeStateDefines(parent->ActorInfo->StateList);
SC_MustGetString ();
while (!SC_Compare ("{"))
sc.MustGetString ();
while (!sc.Compare ("{"))
{
if (SC_Compare ("Doom"))
if (sc.Compare ("Doom"))
{
info->GameFilter |= GAME_Doom;
}
else if (SC_Compare ("Heretic"))
else if (sc.Compare ("Heretic"))
{
info->GameFilter |= GAME_Heretic;
}
else if (SC_Compare ("Hexen"))
else if (sc.Compare ("Hexen"))
{
info->GameFilter |= GAME_Hexen;
}
else if (SC_Compare ("Raven"))
else if (sc.Compare ("Raven"))
{
info->GameFilter |= GAME_Raven;
}
else if (SC_Compare ("Strife"))
else if (sc.Compare ("Strife"))
{
info->GameFilter |= GAME_Strife;
}
else if (SC_Compare ("Any"))
else if (sc.Compare ("Any"))
{
info->GameFilter = GAME_Any;
}
@ -279,17 +279,17 @@ void ParseOldDecoration(EDefinitionType def)
{
if (def != DEF_Decoration || info->GameFilter != 0x80)
{
SC_ScriptError ("Unknown game type %s in %s", sc_String, typeName.GetChars());
sc.ScriptError ("Unknown game type %s in %s", sc.String, typeName.GetChars());
}
else
{
// If this is a regular decoration (without preceding keyword) and no game
// filters defined this is more likely a general syntax error so output a
// more meaningful message.
SC_ScriptError ("Syntax error: Unknown identifier '%s'", typeName.GetChars());
sc.ScriptError ("Syntax error: Unknown identifier '%s'", typeName.GetChars());
}
}
SC_MustGetString ();
sc.MustGetString ();
}
if (info->GameFilter == 0x80)
{
@ -302,24 +302,24 @@ void ParseOldDecoration(EDefinitionType def)
states.Clear ();
memset (&extra, 0, sizeof(extra));
ParseInsideDecoration (info, (AActor *)(type->Defaults), states, extra, def);
ParseInsideDecoration (info, (AActor *)(type->Defaults), states, extra, def, sc);
info->NumOwnedStates = states.Size();
if (info->NumOwnedStates == 0)
{
SC_ScriptError ("%s does not define any animation frames", typeName.GetChars() );
sc.ScriptError ("%s does not define any animation frames", typeName.GetChars() );
}
else if (extra.SpawnEnd == 0)
{
SC_ScriptError ("%s does not have a Frames definition", typeName.GetChars() );
sc.ScriptError ("%s does not have a Frames definition", typeName.GetChars() );
}
else if (def == DEF_BreakableDecoration && extra.DeathEnd == 0)
{
SC_ScriptError ("%s does not have a DeathFrames definition", typeName.GetChars() );
sc.ScriptError ("%s does not have a DeathFrames definition", typeName.GetChars() );
}
else if (extra.IceDeathEnd != 0 && extra.bGenericIceDeath)
{
SC_ScriptError ("You cannot use IceDeathFrames and GenericIceDeath together");
sc.ScriptError ("You cannot use IceDeathFrames and GenericIceDeath together");
}
if (extra.IceDeathEnd != 0)
@ -483,275 +483,271 @@ void ParseOldDecoration(EDefinitionType def)
//==========================================================================
static void ParseInsideDecoration (FActorInfo *info, AActor *defaults,
TArray<FState> &states, FExtraInfo &extra, EDefinitionType def)
TArray<FState> &states, FExtraInfo &extra, EDefinitionType def, FScanner &sc)
{
AFakeInventory *const inv = static_cast<AFakeInventory *>(defaults);
char sprite[5] = "TNT1";
SC_MustGetString ();
while (!SC_Compare ("}"))
sc.MustGetString ();
while (!sc.Compare ("}"))
{
if (SC_Compare ("DoomEdNum"))
if (sc.Compare ("DoomEdNum"))
{
SC_MustGetNumber ();
if (sc_Number < -1 || sc_Number > 32767)
sc.MustGetNumber ();
if (sc.Number < -1 || sc.Number > 32767)
{
SC_ScriptError ("DoomEdNum must be in the range [-1,32767]");
sc.ScriptError ("DoomEdNum must be in the range [-1,32767]");
}
info->DoomEdNum = (SWORD)sc_Number;
info->DoomEdNum = (SWORD)sc.Number;
}
else if (SC_Compare ("SpawnNum"))
else if (sc.Compare ("SpawnNum"))
{
SC_MustGetNumber ();
if (sc_Number < 0 || sc_Number > 255)
sc.MustGetNumber ();
if (sc.Number < 0 || sc.Number > 255)
{
SC_ScriptError ("SpawnNum must be in the range [0,255]");
sc.ScriptError ("SpawnNum must be in the range [0,255]");
}
info->SpawnID = (BYTE)sc_Number;
info->SpawnID = (BYTE)sc.Number;
}
else if (SC_Compare ("Sprite") || (
else if (sc.Compare ("Sprite") || (
(def == DEF_BreakableDecoration || def == DEF_Projectile) &&
SC_Compare ("DeathSprite") &&
sc.Compare ("DeathSprite") &&
(extra.DeathSprite[0] = 1)) // This is intentionally = and not ==
)
{
SC_MustGetString ();
if (strlen (sc_String) != 4)
sc.MustGetString ();
if (sc.StringLen != 4)
{
SC_ScriptError ("Sprite name must be exactly four characters long");
sc.ScriptError ("Sprite name must be exactly four characters long");
}
if (extra.DeathSprite[0] == 1)
{
memcpy (extra.DeathSprite, sc_String, 4);
memcpy (extra.DeathSprite, sc.String, 4);
}
else
{
memcpy (sprite, sc_String, 4);
memcpy (sprite, sc.String, 4);
}
}
else if (SC_Compare ("Frames"))
else if (sc.Compare ("Frames"))
{
SC_MustGetString ();
sc.MustGetString ();
extra.SpawnStart = states.Size();
ParseSpriteFrames (info, states);
ParseSpriteFrames (info, states, sc);
extra.SpawnEnd = states.Size();
}
else if ((def == DEF_BreakableDecoration || def == DEF_Projectile) &&
SC_Compare ("DeathFrames"))
sc.Compare ("DeathFrames"))
{
SC_MustGetString ();
sc.MustGetString ();
extra.DeathStart = states.Size();
ParseSpriteFrames (info, states);
ParseSpriteFrames (info, states, sc);
extra.DeathEnd = states.Size();
}
else if (def == DEF_BreakableDecoration && SC_Compare ("IceDeathFrames"))
else if (def == DEF_BreakableDecoration && sc.Compare ("IceDeathFrames"))
{
SC_MustGetString ();
sc.MustGetString ();
extra.IceDeathStart = states.Size();
ParseSpriteFrames (info, states);
ParseSpriteFrames (info, states, sc);
extra.IceDeathEnd = states.Size();
}
else if (def == DEF_BreakableDecoration && SC_Compare ("BurnDeathFrames"))
else if (def == DEF_BreakableDecoration && sc.Compare ("BurnDeathFrames"))
{
SC_MustGetString ();
sc.MustGetString ();
extra.FireDeathStart = states.Size();
ParseSpriteFrames (info, states);
ParseSpriteFrames (info, states, sc);
extra.FireDeathEnd = states.Size();
}
else if (def == DEF_BreakableDecoration && SC_Compare ("GenericIceDeath"))
else if (def == DEF_BreakableDecoration && sc.Compare ("GenericIceDeath"))
{
extra.bGenericIceDeath = true;
}
else if (def == DEF_BreakableDecoration && SC_Compare ("BurnsAway"))
else if (def == DEF_BreakableDecoration && sc.Compare ("BurnsAway"))
{
extra.bBurnAway = true;
}
else if (def == DEF_BreakableDecoration && SC_Compare ("DiesAway"))
else if (def == DEF_BreakableDecoration && sc.Compare ("DiesAway"))
{
extra.bDiesAway = true;
}
else if (SC_Compare ("Alpha"))
else if (sc.Compare ("Alpha"))
{
SC_MustGetFloat ();
defaults->alpha = int(clamp (sc_Float, 0.0, 1.0) * OPAQUE);
sc.MustGetFloat ();
defaults->alpha = int(clamp (sc.Float, 0.0, 1.0) * OPAQUE);
}
else if (SC_Compare ("Scale"))
else if (sc.Compare ("Scale"))
{
SC_MustGetFloat ();
defaults->scaleX = defaults->scaleY = FLOAT2FIXED(sc_Float);
sc.MustGetFloat ();
defaults->scaleX = defaults->scaleY = FLOAT2FIXED(sc.Float);
}
else if (SC_Compare ("RenderStyle"))
else if (sc.Compare ("RenderStyle"))
{
SC_MustGetString ();
defaults->RenderStyle = SC_MustMatchString (RenderStyles);
if (defaults->RenderStyle > STYLE_OptFuzzy)
{
defaults->RenderStyle += STYLE_Translucent - STYLE_OptFuzzy - 1;
}
sc.MustGetString ();
defaults->RenderStyle = LegacyRenderStyles[sc.MustMatchString (RenderStyles)];
}
else if (SC_Compare ("Radius"))
else if (sc.Compare ("Radius"))
{
SC_MustGetFloat ();
defaults->radius = int(sc_Float * FRACUNIT);
sc.MustGetFloat ();
defaults->radius = int(sc.Float * FRACUNIT);
}
else if (SC_Compare ("Height"))
else if (sc.Compare ("Height"))
{
SC_MustGetFloat ();
defaults->height = int(sc_Float * FRACUNIT);
sc.MustGetFloat ();
defaults->height = int(sc.Float * FRACUNIT);
}
else if (def == DEF_BreakableDecoration && SC_Compare ("DeathHeight"))
else if (def == DEF_BreakableDecoration && sc.Compare ("DeathHeight"))
{
SC_MustGetFloat ();
extra.DeathHeight = int(sc_Float * FRACUNIT);
sc.MustGetFloat ();
extra.DeathHeight = int(sc.Float * FRACUNIT);
}
else if (def == DEF_BreakableDecoration && SC_Compare ("BurnHeight"))
else if (def == DEF_BreakableDecoration && sc.Compare ("BurnHeight"))
{
SC_MustGetFloat ();
extra.BurnHeight = int(sc_Float * FRACUNIT);
sc.MustGetFloat ();
extra.BurnHeight = int(sc.Float * FRACUNIT);
}
else if (def == DEF_BreakableDecoration && SC_Compare ("Health"))
else if (def == DEF_BreakableDecoration && sc.Compare ("Health"))
{
SC_MustGetNumber ();
defaults->health = sc_Number;
sc.MustGetNumber ();
defaults->health = sc.Number;
}
else if (def == DEF_Projectile && SC_Compare ("ExplosionRadius"))
else if (def == DEF_Projectile && sc.Compare ("ExplosionRadius"))
{
SC_MustGetNumber ();
info->Class->Meta.SetMetaInt(ACMETA_ExplosionRadius, sc_Number);
sc.MustGetNumber ();
info->Class->Meta.SetMetaInt(ACMETA_ExplosionRadius, sc.Number);
extra.bExplosive = true;
}
else if (def == DEF_Projectile && SC_Compare ("ExplosionDamage"))
else if (def == DEF_Projectile && sc.Compare ("ExplosionDamage"))
{
SC_MustGetNumber ();
info->Class->Meta.SetMetaInt(ACMETA_ExplosionDamage, sc_Number);
sc.MustGetNumber ();
info->Class->Meta.SetMetaInt(ACMETA_ExplosionDamage, sc.Number);
extra.bExplosive = true;
}
else if (def == DEF_Projectile && SC_Compare ("DoNotHurtShooter"))
else if (def == DEF_Projectile && sc.Compare ("DoNotHurtShooter"))
{
info->Class->Meta.SetMetaInt(ACMETA_DontHurtShooter, true);
}
else if (def == DEF_Projectile && SC_Compare ("Damage"))
else if (def == DEF_Projectile && sc.Compare ("Damage"))
{
SC_MustGetNumber ();
defaults->Damage = sc_Number;
sc.MustGetNumber ();
defaults->Damage = sc.Number;
}
else if (def == DEF_Projectile && SC_Compare ("DamageType"))
else if (def == DEF_Projectile && sc.Compare ("DamageType"))
{
SC_MustGetString ();
if (SC_Compare ("Normal"))
sc.MustGetString ();
if (sc.Compare ("Normal"))
{
defaults->DamageType = NAME_None;
}
else
{
defaults->DamageType = sc_String;
defaults->DamageType = sc.String;
}
}
else if (def == DEF_Projectile && SC_Compare ("Speed"))
else if (def == DEF_Projectile && sc.Compare ("Speed"))
{
SC_MustGetFloat ();
defaults->Speed = fixed_t(sc_Float * 65536.f);
sc.MustGetFloat ();
defaults->Speed = fixed_t(sc.Float * 65536.f);
}
else if (SC_Compare ("Mass"))
else if (sc.Compare ("Mass"))
{
SC_MustGetFloat ();
defaults->Mass = SDWORD(sc_Float);
sc.MustGetFloat ();
defaults->Mass = SDWORD(sc.Float);
}
else if (SC_Compare ("Translation1"))
else if (sc.Compare ("Translation1"))
{
SC_MustGetNumber ();
if (sc_Number < 0 || sc_Number > 2)
sc.MustGetNumber ();
if (sc.Number < 0 || sc.Number > 2)
{
SC_ScriptError ("Translation1 must be in the range [0,2]");
sc.ScriptError ("Translation1 must be in the range [0,2]");
}
defaults->Translation = TRANSLATION(TRANSLATION_Standard, sc_Number);
defaults->Translation = TRANSLATION(TRANSLATION_Standard, sc.Number);
}
else if (SC_Compare ("Translation2"))
else if (sc.Compare ("Translation2"))
{
SC_MustGetNumber ();
if (sc_Number < 0 || sc_Number >= MAX_ACS_TRANSLATIONS)
sc.MustGetNumber ();
if (sc.Number < 0 || sc.Number >= MAX_ACS_TRANSLATIONS)
{
#define ERROR(foo) "Translation2 must be in the range [0," #foo "]"
SC_ScriptError (ERROR(MAX_ACS_TRANSLATIONS));
sc.ScriptError (ERROR(MAX_ACS_TRANSLATIONS));
#undef ERROR
}
defaults->Translation = TRANSLATION(TRANSLATION_LevelScripted, sc_Number);
defaults->Translation = TRANSLATION(TRANSLATION_LevelScripted, sc.Number);
}
else if ((def == DEF_BreakableDecoration || def == DEF_Projectile) &&
SC_Compare ("DeathSound"))
sc.Compare ("DeathSound"))
{
SC_MustGetString ();
defaults->DeathSound = S_FindSound (sc_String);
sc.MustGetString ();
defaults->DeathSound = S_FindSound (sc.String);
}
else if (def == DEF_BreakableDecoration && SC_Compare ("BurnDeathSound"))
else if (def == DEF_BreakableDecoration && sc.Compare ("BurnDeathSound"))
{
SC_MustGetString ();
defaults->ActiveSound = S_FindSound (sc_String);
sc.MustGetString ();
defaults->ActiveSound = S_FindSound (sc.String);
}
else if (def == DEF_Projectile && SC_Compare ("SpawnSound"))
else if (def == DEF_Projectile && sc.Compare ("SpawnSound"))
{
SC_MustGetString ();
defaults->SeeSound = S_FindSound (sc_String);
sc.MustGetString ();
defaults->SeeSound = S_FindSound (sc.String);
}
else if (def == DEF_Projectile && SC_Compare ("DoomBounce"))
else if (def == DEF_Projectile && sc.Compare ("DoomBounce"))
{
defaults->flags2 = (defaults->flags2 & ~MF2_BOUNCETYPE) | MF2_DOOMBOUNCE;
}
else if (def == DEF_Projectile && SC_Compare ("HereticBounce"))
else if (def == DEF_Projectile && sc.Compare ("HereticBounce"))
{
defaults->flags2 = (defaults->flags2 & ~MF2_BOUNCETYPE) | MF2_HERETICBOUNCE;
}
else if (def == DEF_Projectile && SC_Compare ("HexenBounce"))
else if (def == DEF_Projectile && sc.Compare ("HexenBounce"))
{
defaults->flags2 = (defaults->flags2 & ~MF2_BOUNCETYPE) | MF2_HEXENBOUNCE;
}
else if (def == DEF_Pickup && SC_Compare ("PickupSound"))
else if (def == DEF_Pickup && sc.Compare ("PickupSound"))
{
SC_MustGetString ();
inv->PickupSound = S_FindSound (sc_String);
sc.MustGetString ();
inv->PickupSound = S_FindSound (sc.String);
}
else if (def == DEF_Pickup && SC_Compare ("PickupMessage"))
else if (def == DEF_Pickup && sc.Compare ("PickupMessage"))
{
SC_MustGetString ();
info->Class->Meta.SetMetaString(AIMETA_PickupMessage, sc_String);
sc.MustGetString ();
info->Class->Meta.SetMetaString(AIMETA_PickupMessage, sc.String);
}
else if (def == DEF_Pickup && SC_Compare ("Respawns"))
else if (def == DEF_Pickup && sc.Compare ("Respawns"))
{
inv->Respawnable = true;
}
else if (def == DEF_BreakableDecoration && SC_Compare ("SolidOnDeath"))
else if (def == DEF_BreakableDecoration && sc.Compare ("SolidOnDeath"))
{
extra.bSolidOnDeath = true;
}
else if (def == DEF_BreakableDecoration && SC_Compare ("SolidOnBurn"))
else if (def == DEF_BreakableDecoration && sc.Compare ("SolidOnBurn"))
{
extra.bSolidOnBurn = true;
}
else if (sc_String[0] != '*')
else if (sc.String[0] != '*')
{
int bit = SC_MatchString (FlagNames1);
int bit = sc.MatchString (FlagNames1);
if (bit != -1)
{
defaults->flags |= 1 << bit;
}
else if ((bit = SC_MatchString (FlagNames2)) != -1)
else if ((bit = sc.MatchString (FlagNames2)) != -1)
{
defaults->flags2 |= 1 << bit;
}
else if ((bit = SC_MatchString (FlagNames3)) != -1)
else if ((bit = sc.MatchString (FlagNames3)) != -1)
{
defaults->flags3 |= 1 << bit;
}
else
{
SC_ScriptError (NULL);
sc.ScriptError (NULL);
}
}
else
{
SC_ScriptError (NULL);
sc.ScriptError (NULL);
}
SC_MustGetString ();
sc.MustGetString ();
}
unsigned int i;
@ -798,10 +794,10 @@ static void ParseInsideDecoration (FActorInfo *info, AActor *defaults,
// "10:A, 15:B, 8:C, 6:B"
//==========================================================================
static void ParseSpriteFrames (FActorInfo *info, TArray<FState> &states)
static void ParseSpriteFrames (FActorInfo *info, TArray<FState> &states, FScanner &sc)
{
FState state;
char *token = strtok (sc_String, ",\t\n\r");
char *token = strtok (sc.String, ",\t\n\r");
memset (&state, 0, sizeof(state));
@ -823,7 +819,7 @@ static void ParseSpriteFrames (FActorInfo *info, TArray<FState> &states)
rate = strtol (token, &stop, 10);
if (stop == token || rate < 1 || rate > 65534)
{
SC_ScriptError ("Rates must be in the range [0,65534]");
sc.ScriptError ("Rates must be in the range [0,65534]");
}
token = colon + 1;
rate += 1;
@ -841,13 +837,13 @@ static void ParseSpriteFrames (FActorInfo *info, TArray<FState> &states)
{
if (firstState)
{
SC_ScriptError ("* must come after a frame");
sc.ScriptError ("* must come after a frame");
}
state.Frame |= SF_FULLBRIGHT;
}
else if (*token < 'A' || *token > ']')
{
SC_ScriptError ("Frames must be A-Z, [, \\, or ]");
sc.ScriptError ("Frames must be A-Z, [, \\, or ]");
}
else
{

View file

@ -82,16 +82,16 @@ const PClass *QuestItemClasses[31];
//
//==========================================================================
void ParseConstant (PSymbolTable * symt, PClass *cls)
void ParseConstant (FScanner &sc, PSymbolTable * symt, PClass *cls)
{
// Read the type and make sure it's int.
// (Maybe there will be other types later.)
SC_MustGetToken(TK_Int);
SC_MustGetToken(TK_Identifier);
FName symname = sc_String;
SC_MustGetToken('=');
int expr = ParseExpression (false, cls);
SC_MustGetToken(';');
sc.MustGetToken(TK_Int);
sc.MustGetToken(TK_Identifier);
FName symname = sc.String;
sc.MustGetToken('=');
int expr = ParseExpression (sc, false, cls);
sc.MustGetToken(';');
int val = EvalExpressionI (expr, NULL, cls);
PSymbolConst *sym = new PSymbolConst;
@ -101,7 +101,7 @@ void ParseConstant (PSymbolTable * symt, PClass *cls)
if (symt->AddSymbol (sym) == NULL)
{
delete sym;
SC_ScriptError ("'%s' is already defined in class '%s'.",
sc.ScriptError ("'%s' is already defined in class '%s'.",
symname.GetChars(), cls->TypeName.GetChars());
}
}
@ -114,19 +114,19 @@ void ParseConstant (PSymbolTable * symt, PClass *cls)
//
//==========================================================================
void ParseEnum (PSymbolTable * symt, PClass *cls)
void ParseEnum (FScanner &sc, PSymbolTable *symt, PClass *cls)
{
int currvalue = 0;
SC_MustGetToken('{');
while (!SC_CheckToken('}'))
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
{
SC_MustGetToken(TK_Identifier);
FName symname = sc_String;
if (SC_CheckToken('='))
sc.MustGetToken(TK_Identifier);
FName symname = sc.String;
if (sc.CheckToken('='))
{
int expr = ParseExpression(false, cls);
currvalue = EvalExpressionI (expr, NULL, cls);
int expr = ParseExpression(sc, false, cls);
currvalue = EvalExpressionI(expr, NULL, cls);
}
PSymbolConst *sym = new PSymbolConst;
sym->SymbolName = symname;
@ -135,15 +135,15 @@ void ParseEnum (PSymbolTable * symt, PClass *cls)
if (symt->AddSymbol (sym) == NULL)
{
delete sym;
SC_ScriptError ("'%s' is already defined in class '%s'.",
sc.ScriptError ("'%s' is already defined in class '%s'.",
symname.GetChars(), cls->TypeName.GetChars());
}
// This allows a comma after the last value but doesn't enforce it.
if (SC_CheckToken('}')) break;
SC_MustGetToken(',');
if (sc.CheckToken('}')) break;
sc.MustGetToken(',');
currvalue++;
}
SC_MustGetToken(';');
sc.MustGetToken(';');
}
//==========================================================================
@ -156,7 +156,7 @@ void ParseEnum (PSymbolTable * symt, PClass *cls)
//
//==========================================================================
static void ParseActionDef (PClass *cls)
static void ParseActionDef (FScanner &sc, PClass *cls)
{
#define OPTIONAL 1
#define EVAL 2
@ -166,18 +166,18 @@ static void ParseActionDef (PClass *cls)
FName funcname;
FString args;
SC_MustGetToken(TK_Native);
SC_MustGetToken(TK_Identifier);
funcname = sc_String;
afd = FindFunction(sc_String);
sc.MustGetToken(TK_Native);
sc.MustGetToken(TK_Identifier);
funcname = sc.String;
afd = FindFunction(sc.String);
if (afd == NULL)
{
SC_ScriptError ("The function '%s' has not been exported from the executable.", sc_String);
sc.ScriptError ("The function '%s' has not been exported from the executable.", sc.String);
}
SC_MustGetToken('(');
if (!SC_CheckToken(')'))
sc.MustGetToken('(');
if (!sc.CheckToken(')'))
{
while (sc_TokenType != ')')
while (sc.TokenType != ')')
{
int flags = 0;
char type = '@';
@ -185,19 +185,19 @@ static void ParseActionDef (PClass *cls)
// Retrieve flags before type name
for (;;)
{
if (SC_CheckToken(TK_Optional))
if (sc.CheckToken(TK_Optional))
{
flags |= OPTIONAL;
}
else if (SC_CheckToken(TK_Eval))
else if (sc.CheckToken(TK_Eval))
{
flags |= EVAL;
}
else if (SC_CheckToken(TK_EvalNot))
else if (sc.CheckToken(TK_EvalNot))
{
flags |= EVALNOT;
}
else if (SC_CheckToken(TK_Coerce) || SC_CheckToken(TK_Native))
else if (sc.CheckToken(TK_Coerce) || sc.CheckToken(TK_Native))
{
}
else
@ -206,8 +206,8 @@ static void ParseActionDef (PClass *cls)
}
}
// Read the variable type
SC_MustGetAnyToken();
switch (sc_TokenType)
sc.MustGetAnyToken();
switch (sc.TokenType)
{
case TK_Bool: type = 'i'; break;
case TK_Int: type = 'i'; break;
@ -218,28 +218,28 @@ static void ParseActionDef (PClass *cls)
case TK_State: type = 'l'; break;
case TK_Color: type = 'c'; break;
case TK_Class:
SC_MustGetToken('<');
SC_MustGetToken(TK_Identifier); // Skip class name, since the parser doesn't care
SC_MustGetToken('>');
sc.MustGetToken('<');
sc.MustGetToken(TK_Identifier); // Skip class name, since the parser doesn't care
sc.MustGetToken('>');
type = 'm';
break;
case TK_Ellipsis:
type = '+';
SC_MustGetToken(')');
SC_UnGet();
sc.MustGetToken(')');
sc.UnGet();
break;
default:
SC_ScriptError ("Unknown variable type %s", SC_TokenName(sc_TokenType, sc_String).GetChars());
sc.ScriptError ("Unknown variable type %s", sc.TokenName(sc.TokenType, sc.String).GetChars());
break;
}
// Read the optional variable name
if (!SC_CheckToken(',') && !SC_CheckToken(')'))
if (!sc.CheckToken(',') && !sc.CheckToken(')'))
{
SC_MustGetToken(TK_Identifier);
sc.MustGetToken(TK_Identifier);
}
else
{
SC_UnGet();
sc.UnGet();
}
// If eval or evalnot were a flag, hey the decorate parser doesn't actually care about the type.
if (flags & EVALNOT)
@ -258,14 +258,14 @@ static void ParseActionDef (PClass *cls)
#undef EVAL
#undef EVALNOT
args += type;
SC_MustGetAnyToken();
if (sc_TokenType != ',' && sc_TokenType != ')')
sc.MustGetAnyToken();
if (sc.TokenType != ',' && sc.TokenType != ')')
{
SC_ScriptError ("Expected ',' or ')' but got %s instead", SC_TokenName(sc_TokenType, sc_String).GetChars());
sc.ScriptError ("Expected ',' or ')' but got %s instead", sc.TokenName(sc.TokenType, sc.String).GetChars());
}
}
}
SC_MustGetToken(';');
sc.MustGetToken(';');
PSymbolActionFunction *sym = new PSymbolActionFunction;
sym->SymbolName = funcname;
sym->SymbolType = SYM_ActionFunction;
@ -274,7 +274,7 @@ static void ParseActionDef (PClass *cls)
if (cls->Symbols.AddSymbol (sym) == NULL)
{
delete sym;
SC_ScriptError ("'%s' is already defined in class '%s'.",
sc.ScriptError ("'%s' is already defined in class '%s'.",
funcname.GetChars(), cls->TypeName.GetChars());
}
}
@ -284,27 +284,27 @@ static void ParseActionDef (PClass *cls)
// Starts a new actor definition
//
//==========================================================================
static FActorInfo * CreateNewActor(FActorInfo ** parentc, Baggage *bag)
static FActorInfo *CreateNewActor(FScanner &sc, FActorInfo **parentc, Baggage *bag)
{
FName typeName;
// Get actor name
SC_MustGetString();
sc.MustGetString();
char * colon = strchr(sc_String, ':');
char *colon = strchr(sc.String, ':');
if (colon != NULL)
{
*colon++ = 0;
}
if (PClass::FindClass (sc_String) != NULL)
if (PClass::FindClass (sc.String) != NULL)
{
SC_ScriptError ("Actor %s is already defined.", sc_String);
sc.ScriptError ("Actor %s is already defined.", sc.String);
}
typeName = sc_String;
typeName = sc.String;
PClass * parent = RUNTIME_CLASS(AActor);
PClass *parent = RUNTIME_CLASS(AActor);
if (parentc)
{
*parentc = NULL;
@ -313,10 +313,10 @@ static FActorInfo * CreateNewActor(FActorInfo ** parentc, Baggage *bag)
// without having resort to C-mode (which disallows periods in actor names.)
if (colon == NULL)
{
SC_MustGetString ();
if (sc_String[0]==':')
sc.MustGetString ();
if (sc.String[0]==':')
{
colon = sc_String + 1;
colon = sc.String + 1;
}
}
@ -324,8 +324,8 @@ static FActorInfo * CreateNewActor(FActorInfo ** parentc, Baggage *bag)
{
if (colon[0] == 0)
{
SC_MustGetString ();
colon = sc_String;
sc.MustGetString ();
colon = sc.String;
}
}
@ -335,22 +335,22 @@ static FActorInfo * CreateNewActor(FActorInfo ** parentc, Baggage *bag)
if (parent == NULL)
{
SC_ScriptError ("Parent type '%s' not found", colon);
sc.ScriptError ("Parent type '%s' not found", colon);
}
else if (parent->ActorInfo == NULL)
{
SC_ScriptError ("Parent type '%s' is not an actor", colon);
sc.ScriptError ("Parent type '%s' is not an actor", colon);
}
else
{
*parentc = parent->ActorInfo;
}
}
else SC_UnGet();
else sc.UnGet();
}
PClass * ti = parent->CreateDerivedClass (typeName, parent->Size);
FActorInfo * info = ti->ActorInfo;
PClass *ti = parent->CreateDerivedClass (typeName, parent->Size);
FActorInfo *info = ti->ActorInfo;
MakeStateDefines(parent->ActorInfo->StateList);
@ -372,38 +372,38 @@ static FActorInfo * CreateNewActor(FActorInfo ** parentc, Baggage *bag)
}
// Check for "replaces"
SC_MustGetString ();
if (SC_Compare ("replaces"))
sc.MustGetString ();
if (sc.Compare ("replaces"))
{
const PClass *replacee;
// Get actor name
SC_MustGetString ();
replacee = PClass::FindClass (sc_String);
sc.MustGetString ();
replacee = PClass::FindClass (sc.String);
if (replacee == NULL)
{
SC_ScriptError ("Replaced type '%s' not found", sc_String);
sc.ScriptError ("Replaced type '%s' not found", sc.String);
}
else if (replacee->ActorInfo == NULL)
{
SC_ScriptError ("Replaced type '%s' is not an actor", sc_String);
sc.ScriptError ("Replaced type '%s' is not an actor", sc.String);
}
replacee->ActorInfo->Replacement = ti->ActorInfo;
ti->ActorInfo->Replacee = replacee->ActorInfo;
}
else
{
SC_UnGet();
sc.UnGet();
}
// Now, after the actor names have been parsed, it is time to switch to C-mode
// for the rest of the actor definition.
SC_SetCMode (true);
if (SC_CheckNumber())
sc.SetCMode (true);
if (sc.CheckNumber())
{
if (sc_Number>=-1 && sc_Number<32768) info->DoomEdNum = sc_Number;
else SC_ScriptError ("DoomEdNum must be in the range [-1,32767]");
if (sc.Number>=-1 && sc.Number<32768) info->DoomEdNum = sc.Number;
else sc.ScriptError ("DoomEdNum must be in the range [-1,32767]");
}
if (parent == RUNTIME_CLASS(AWeapon))
{
@ -419,7 +419,7 @@ static FActorInfo * CreateNewActor(FActorInfo ** parentc, Baggage *bag)
// Reads an actor definition
//
//==========================================================================
void ParseActor()
void ParseActor(FScanner &sc)
{
FActorInfo * info=NULL;
Baggage bag;
@ -428,43 +428,43 @@ void ParseActor()
{
FActorInfo * parent;
info=CreateNewActor(&parent, &bag);
SC_MustGetToken('{');
while (SC_MustGetAnyToken(), sc_TokenType != '}')
info = CreateNewActor(sc, &parent, &bag);
sc.MustGetToken('{');
while (sc.MustGetAnyToken(), sc.TokenType != '}')
{
switch (sc_TokenType)
switch (sc.TokenType)
{
case TK_Action:
ParseActionDef (info->Class);
ParseActionDef (sc, info->Class);
break;
case TK_Const:
ParseConstant (&info->Class->Symbols, info->Class);
ParseConstant (sc, &info->Class->Symbols, info->Class);
break;
case TK_Enum:
ParseEnum (&info->Class->Symbols, info->Class);
ParseEnum (sc, &info->Class->Symbols, info->Class);
break;
case TK_Identifier:
// other identifier related checks here
case TK_Projectile: // special case: both keyword and property name
ParseActorProperty(bag);
ParseActorProperty(sc, bag);
break;
case '+':
case '-':
ParseActorFlag(bag, sc_TokenType);
ParseActorFlag(sc, bag, sc.TokenType);
break;
default:
SC_ScriptError("Unexpected '%s' in definition of '%s'", sc_String, bag.Info->Class->TypeName.GetChars());
sc.ScriptError("Unexpected '%s' in definition of '%s'", sc.String, bag.Info->Class->TypeName.GetChars());
break;
}
}
FinishActor(info, bag);
FinishActor(sc, info, bag);
}
catch(CRecoverableError & e)
@ -476,13 +476,13 @@ void ParseActor()
catch (...)
{
if (info)
SC_ScriptError("Unexpected error during parsing of actor %s", info->Class->TypeName.GetChars());
sc.ScriptError("Unexpected error during parsing of actor %s", info->Class->TypeName.GetChars());
else
SC_ScriptError("Unexpected error during parsing of actor definitions");
sc.ScriptError("Unexpected error during parsing of actor definitions");
}
#endif
SC_SetCMode (false);
sc.SetCMode (false);
}
//==========================================================================
@ -635,52 +635,52 @@ void FinishThingdef()
//
//==========================================================================
void ParseClass()
void ParseClass(FScanner &sc)
{
Baggage bag;
PClass *cls;
FName classname;
FName supername;
SC_MustGetToken(TK_Identifier); // class name
classname = sc_String;
SC_MustGetToken(TK_Extends); // because I'm not supporting Object
SC_MustGetToken(TK_Identifier); // superclass name
supername = sc_String;
SC_MustGetToken(TK_Native); // use actor definitions for your own stuff
SC_MustGetToken('{');
sc.MustGetToken(TK_Identifier); // class name
classname = sc.String;
sc.MustGetToken(TK_Extends); // because I'm not supporting Object
sc.MustGetToken(TK_Identifier); // superclass name
supername = sc.String;
sc.MustGetToken(TK_Native); // use actor definitions for your own stuff
sc.MustGetToken('{');
cls = const_cast<PClass*>(PClass::FindClass (classname));
if (cls == NULL)
{
SC_ScriptError ("'%s' is not a native class", classname.GetChars());
sc.ScriptError ("'%s' is not a native class", classname.GetChars());
}
if (cls->ParentClass == NULL || cls->ParentClass->TypeName != supername)
{
SC_ScriptError ("'%s' does not extend '%s'", classname.GetChars(), supername.GetChars());
sc.ScriptError ("'%s' does not extend '%s'", classname.GetChars(), supername.GetChars());
}
bag.Info = cls->ActorInfo;
SC_MustGetAnyToken();
while (sc_TokenType != '}')
sc.MustGetAnyToken();
while (sc.TokenType != '}')
{
if (sc_TokenType == TK_Action)
if (sc.TokenType == TK_Action)
{
ParseActionDef(cls);
ParseActionDef(sc, cls);
}
else if (sc_TokenType == TK_Const)
else if (sc.TokenType == TK_Const)
{
ParseConstant(&cls->Symbols, cls);
ParseConstant(sc, &cls->Symbols, cls);
}
else if (sc_TokenType == TK_Enum)
else if (sc.TokenType == TK_Enum)
{
ParseEnum(&cls->Symbols, cls);
ParseEnum(sc, &cls->Symbols, cls);
}
else
{
FString tokname = SC_TokenName(sc_TokenType, sc_String);
SC_ScriptError ("Expected 'action', 'const' or 'enum' but got %s", tokname.GetChars());
FString tokname = sc.TokenName(sc.TokenType, sc.String);
sc.ScriptError ("Expected 'action', 'const' or 'enum' but got %s", tokname.GetChars());
}
SC_MustGetAnyToken();
sc.MustGetAnyToken();
}
}

View file

@ -1,6 +1,8 @@
#ifndef __THINGDEF_H
#define __THINGDEF_H
class FScanner;
//==========================================================================
//
// This class is for storing a name inside a const PClass* field without
@ -97,9 +99,9 @@ FState * FindState(AActor * actor, const PClass * type, const char * name);
void InstallStates(FActorInfo *info, AActor *defaults);
void MakeStateDefines(const FStateLabels *list);
FState *P_GetState(AActor *self, FState *CallingState, int offset);
int FinishStates (FActorInfo *actor, AActor *defaults, Baggage &bag);
int ParseStates(FActorInfo * actor, AActor * defaults, Baggage &bag);
FState *CheckState(PClass *type);
int FinishStates (FScanner &sc, FActorInfo *actor, AActor *defaults, Baggage &bag);
int ParseStates(FScanner &sc, FActorInfo *actor, AActor *defaults, Baggage &bag);
FState *CheckState(FScanner &sc, PClass *type);
//==========================================================================
@ -108,15 +110,15 @@ FState *CheckState(PClass *type);
//
//==========================================================================
void ParseActorProperty(Baggage &bag);
void ParseActorFlag (Baggage &bag, int mod);
void FinishActor(FActorInfo *info, Baggage &bag);
void ParseActorProperty(FScanner &sc, Baggage &bag);
void ParseActorFlag (FScanner &sc, Baggage &bag, int mod);
void FinishActor(FScanner &sc, FActorInfo *info, Baggage &bag);
void ParseConstant (PSymbolTable * symt, PClass *cls);
void ParseEnum (PSymbolTable * symt, PClass *cls);
void ParseConstant (FScanner &sc, PSymbolTable *symt, PClass *cls);
void ParseEnum (FScanner &sc, PSymbolTable *symt, PClass *cls);
int ParseExpression (bool _not, PClass *cls);
int ParseExpression (FScanner &sc, bool _not, PClass *cls);
int EvalExpressionI (int id, AActor *self, const PClass *cls=NULL);
float EvalExpressionF (int id, AActor *self, const PClass *cls=NULL);

View file

@ -1190,21 +1190,22 @@ void A_RailAttack (AActor * self)
void A_CustomRailgun (AActor *actor)
{
if (!actor->target)
int index = CheckIndex(7);
if (index < 0) return;
int Damage = EvalExpressionI (StateParameters[index], actor);
int Spawnofs_XY = EvalExpressionI (StateParameters[index+1], actor);
int Color1 = StateParameters[index+2];
int Color2 = StateParameters[index+3];
bool Silent = !!EvalExpressionI (StateParameters[index+4], actor);
bool aim = !!EvalExpressionI (StateParameters[index+5], actor);
float MaxDiff = EvalExpressionF (StateParameters[index+6], actor);
ENamedName PuffTypeName = (ENamedName)StateParameters[index+7];
if (aim && actor->target == NULL)
{
return;
int index=CheckIndex(7);
if (index<0) return;
int Damage=EvalExpressionI (StateParameters[index], actor);
int Spawnofs_XY=EvalExpressionI (StateParameters[index+1], actor);
int Color1=StateParameters[index+2];
int Color2=StateParameters[index+3];
bool Silent=!!EvalExpressionI (StateParameters[index+4], actor);
bool aim=!!EvalExpressionI (StateParameters[index+5], actor);
float MaxDiff=EvalExpressionF (StateParameters[index+6], actor);
ENamedName PuffTypeName=(ENamedName)StateParameters[index+7];
}
// [RH] Andy Baker's stealth monsters
if (actor->flags & MF_STEALTH)
{
@ -1212,7 +1213,7 @@ void A_CustomRailgun (AActor *actor)
}
actor->flags &= ~MF_AMBUSH;
if (aim)
{
actor->angle = R_PointToAngle2 (actor->x,
@ -1692,15 +1693,9 @@ void A_SetTranslucent(AActor * self)
int mode = EvalExpressionI (StateParameters[index+1], self);
mode = mode == 0 ? STYLE_Translucent : mode == 2 ? STYLE_Fuzzy : STYLE_Add;
self->alpha=clamp<fixed_t>(alpha, 0, FRACUNIT);
if (mode != STYLE_Fuzzy)
{
if (self->alpha == 0) mode = STYLE_None;
else if (mode == STYLE_Translucent && self->alpha >= FRACUNIT) mode = STYLE_Normal;
}
self->RenderStyle=mode;
self->RenderStyle.Flags &= ~STYLEF_Alpha1;
self->alpha = clamp<fixed_t>(alpha, 0, FRACUNIT);
self->RenderStyle = ERenderStyle(mode);
}
//===========================================================================
@ -1722,7 +1717,7 @@ void A_FadeIn(AActor * self)
if (reduce == 0) reduce = FRACUNIT/10;
if (self->RenderStyle==STYLE_Normal) self->RenderStyle=STYLE_Translucent;
self->RenderStyle.Flags &= ~STYLEF_Alpha1;
self->alpha += reduce;
//if (self->alpha<=0) self->Destroy();
}
@ -1746,7 +1741,7 @@ void A_FadeOut(AActor * self)
if (reduce == 0) reduce = FRACUNIT/10;
if (self->RenderStyle==STYLE_Normal) self->RenderStyle=STYLE_Translucent;
self->RenderStyle.Flags &= ~STYLEF_Alpha1;
self->alpha -= reduce;
if (self->alpha<=0) self->Destroy();
}

View file

@ -378,21 +378,21 @@ TArray<ExpData *> StateExpressions;
// [GRB] Parses an expression and stores it into Expression array
//
static ExpData *ParseExpressionM (const PClass *cls);
static ExpData *ParseExpressionL (const PClass *cls);
static ExpData *ParseExpressionK (const PClass *cls);
static ExpData *ParseExpressionJ (const PClass *cls);
static ExpData *ParseExpressionI (const PClass *cls);
static ExpData *ParseExpressionH (const PClass *cls);
static ExpData *ParseExpressionG (const PClass *cls);
static ExpData *ParseExpressionF (const PClass *cls);
static ExpData *ParseExpressionE (const PClass *cls);
static ExpData *ParseExpressionD (const PClass *cls);
static ExpData *ParseExpressionC (const PClass *cls);
static ExpData *ParseExpressionB (const PClass *cls);
static ExpData *ParseExpressionA (const PClass *cls);
static ExpData *ParseExpressionM (FScanner &sc, const PClass *cls);
static ExpData *ParseExpressionL (FScanner &sc, const PClass *cls);
static ExpData *ParseExpressionK (FScanner &sc, const PClass *cls);
static ExpData *ParseExpressionJ (FScanner &sc, const PClass *cls);
static ExpData *ParseExpressionI (FScanner &sc, const PClass *cls);
static ExpData *ParseExpressionH (FScanner &sc, const PClass *cls);
static ExpData *ParseExpressionG (FScanner &sc, const PClass *cls);
static ExpData *ParseExpressionF (FScanner &sc, const PClass *cls);
static ExpData *ParseExpressionE (FScanner &sc, const PClass *cls);
static ExpData *ParseExpressionD (FScanner &sc, const PClass *cls);
static ExpData *ParseExpressionC (FScanner &sc, const PClass *cls);
static ExpData *ParseExpressionB (FScanner &sc, const PClass *cls);
static ExpData *ParseExpressionA (FScanner &sc, const PClass *cls);
int ParseExpression (bool _not, PClass *cls)
int ParseExpression (FScanner &sc, bool _not, PClass *cls)
{
static bool inited=false;
@ -403,7 +403,7 @@ int ParseExpression (bool _not, PClass *cls)
inited=true;
}
ExpData *data = ParseExpressionM (cls);
ExpData *data = ParseExpressionM (sc, cls);
if (_not)
{
@ -426,11 +426,11 @@ int ParseExpression (bool _not, PClass *cls)
return StateExpressions.Push (data);
}
static ExpData *ParseExpressionM (const PClass *cls)
static ExpData *ParseExpressionM (FScanner &sc, const PClass *cls)
{
ExpData *tmp = ParseExpressionL (cls);
ExpData *tmp = ParseExpressionL (sc, cls);
if (SC_CheckToken('?'))
if (sc.CheckToken('?'))
{
ExpData *data = new ExpData;
data->Type = EX_Cond;
@ -438,9 +438,9 @@ static ExpData *ParseExpressionM (const PClass *cls)
ExpData *choices = new ExpData;
data->Children[1] = choices;
choices->Type = EX_Right;
choices->Children[0] = ParseExpressionM (cls);
SC_MustGetToken(':');
choices->Children[1] = ParseExpressionM (cls);
choices->Children[0] = ParseExpressionM (sc, cls);
sc.MustGetToken(':');
choices->Children[1] = ParseExpressionM (sc, cls);
data->EvalConst (cls);
return data;
}
@ -450,13 +450,13 @@ static ExpData *ParseExpressionM (const PClass *cls)
}
}
static ExpData *ParseExpressionL (const PClass *cls)
static ExpData *ParseExpressionL (FScanner &sc, const PClass *cls)
{
ExpData *tmp = ParseExpressionK (cls);
ExpData *tmp = ParseExpressionK (sc, cls);
while (SC_CheckToken(TK_OrOr))
while (sc.CheckToken(TK_OrOr))
{
ExpData *right = ParseExpressionK (cls);
ExpData *right = ParseExpressionK (sc, cls);
ExpData *data = new ExpData;
data->Type = EX_LogOr;
data->Children[0] = tmp;
@ -467,13 +467,13 @@ static ExpData *ParseExpressionL (const PClass *cls)
return tmp;
}
static ExpData *ParseExpressionK (const PClass *cls)
static ExpData *ParseExpressionK (FScanner &sc, const PClass *cls)
{
ExpData *tmp = ParseExpressionJ (cls);
ExpData *tmp = ParseExpressionJ (sc, cls);
while (SC_CheckToken(TK_AndAnd))
while (sc.CheckToken(TK_AndAnd))
{
ExpData *right = ParseExpressionJ (cls);
ExpData *right = ParseExpressionJ (sc, cls);
ExpData *data = new ExpData;
data->Type = EX_LogAnd;
data->Children[0] = tmp;
@ -484,13 +484,13 @@ static ExpData *ParseExpressionK (const PClass *cls)
return tmp;
}
static ExpData *ParseExpressionJ (const PClass *cls)
static ExpData *ParseExpressionJ (FScanner &sc, const PClass *cls)
{
ExpData *tmp = ParseExpressionI (cls);
ExpData *tmp = ParseExpressionI (sc, cls);
while (SC_CheckToken('|'))
while (sc.CheckToken('|'))
{
ExpData *right = ParseExpressionI (cls);
ExpData *right = ParseExpressionI (sc, cls);
ExpData *data = new ExpData;
data->Type = EX_Or;
data->Children[0] = tmp;
@ -501,13 +501,13 @@ static ExpData *ParseExpressionJ (const PClass *cls)
return tmp;
}
static ExpData *ParseExpressionI (const PClass *cls)
static ExpData *ParseExpressionI (FScanner &sc, const PClass *cls)
{
ExpData *tmp = ParseExpressionH (cls);
ExpData *tmp = ParseExpressionH (sc, cls);
while (SC_CheckToken('^'))
while (sc.CheckToken('^'))
{
ExpData *right = ParseExpressionH (cls);
ExpData *right = ParseExpressionH (sc, cls);
ExpData *data = new ExpData;
data->Type = EX_Xor;
data->Children[0] = tmp;
@ -518,13 +518,13 @@ static ExpData *ParseExpressionI (const PClass *cls)
return tmp;
}
static ExpData *ParseExpressionH (const PClass *cls)
static ExpData *ParseExpressionH (FScanner &sc, const PClass *cls)
{
ExpData *tmp = ParseExpressionG (cls);
ExpData *tmp = ParseExpressionG (sc, cls);
while (SC_CheckToken('&'))
while (sc.CheckToken('&'))
{
ExpData *right = ParseExpressionG (cls);
ExpData *right = ParseExpressionG (sc, cls);
ExpData *data = new ExpData;
data->Type = EX_And;
data->Children[0] = tmp;
@ -535,14 +535,14 @@ static ExpData *ParseExpressionH (const PClass *cls)
return tmp;
}
static ExpData *ParseExpressionG (const PClass *cls)
static ExpData *ParseExpressionG (FScanner &sc, const PClass *cls)
{
ExpData *tmp = ParseExpressionF (cls);
ExpData *tmp = ParseExpressionF (sc, cls);
while (SC_GetToken() && (sc_TokenType == TK_Eq || sc_TokenType == TK_Neq))
while (sc.GetToken() && (sc.TokenType == TK_Eq || sc.TokenType == TK_Neq))
{
int token = sc_TokenType;
ExpData *right = ParseExpressionF (cls);
int token = sc.TokenType;
ExpData *right = ParseExpressionF (sc, cls);
ExpData *data = new ExpData;
data->Type = token == TK_Eq? EX_Eq : EX_NE;
data->Children[0] = tmp;
@ -550,18 +550,18 @@ static ExpData *ParseExpressionG (const PClass *cls)
data->EvalConst (cls);
tmp = data;
}
if (!sc_End) SC_UnGet();
if (!sc.End) sc.UnGet();
return tmp;
}
static ExpData *ParseExpressionF (const PClass *cls)
static ExpData *ParseExpressionF (FScanner &sc, const PClass *cls)
{
ExpData *tmp = ParseExpressionE (cls);
ExpData *tmp = ParseExpressionE (sc, cls);
while (SC_GetToken() && (sc_TokenType == '<' || sc_TokenType == '>' || sc_TokenType == TK_Leq || sc_TokenType == TK_Geq))
while (sc.GetToken() && (sc.TokenType == '<' || sc.TokenType == '>' || sc.TokenType == TK_Leq || sc.TokenType == TK_Geq))
{
int token = sc_TokenType;
ExpData *right = ParseExpressionE (cls);
int token = sc.TokenType;
ExpData *right = ParseExpressionE (sc, cls);
ExpData *data = new ExpData;
data->Type = token == '<' ? EX_LT : token == '>' ? EX_GT : token == TK_Leq? EX_LE : EX_GE;
data->Children[0] = tmp;
@ -569,18 +569,18 @@ static ExpData *ParseExpressionF (const PClass *cls)
data->EvalConst (cls);
tmp = data;
}
if (!sc_End) SC_UnGet();
if (!sc.End) sc.UnGet();
return tmp;
}
static ExpData *ParseExpressionE (const PClass *cls)
static ExpData *ParseExpressionE (FScanner &sc, const PClass *cls)
{
ExpData *tmp = ParseExpressionD (cls);
ExpData *tmp = ParseExpressionD (sc, cls);
while (SC_GetToken() && (sc_TokenType == TK_LShift || sc_TokenType == TK_RShift))
while (sc.GetToken() && (sc.TokenType == TK_LShift || sc.TokenType == TK_RShift))
{
int token = sc_TokenType;
ExpData *right = ParseExpressionD (cls);
int token = sc.TokenType;
ExpData *right = ParseExpressionD (sc, cls);
ExpData *data = new ExpData;
data->Type = token == TK_LShift? EX_LShift : EX_RShift;
data->Children[0] = tmp;
@ -588,18 +588,18 @@ static ExpData *ParseExpressionE (const PClass *cls)
data->EvalConst (cls);
tmp = data;
}
if (!sc_End) SC_UnGet();
if (!sc.End) sc.UnGet();
return tmp;
}
static ExpData *ParseExpressionD (const PClass *cls)
static ExpData *ParseExpressionD (FScanner &sc, const PClass *cls)
{
ExpData *tmp = ParseExpressionC (cls);
ExpData *tmp = ParseExpressionC (sc, cls);
while (SC_GetToken() && (sc_TokenType == '+' || sc_TokenType == '-'))
while (sc.GetToken() && (sc.TokenType == '+' || sc.TokenType == '-'))
{
int token = sc_TokenType;
ExpData *right = ParseExpressionC (cls);
int token = sc.TokenType;
ExpData *right = ParseExpressionC (sc, cls);
ExpData *data = new ExpData;
data->Type = token == '+'? EX_Add : EX_Sub;
data->Children[0] = tmp;
@ -607,18 +607,18 @@ static ExpData *ParseExpressionD (const PClass *cls)
data->EvalConst (cls);
tmp = data;
}
if (!sc_End) SC_UnGet();
if (!sc.End) sc.UnGet();
return tmp;
}
static ExpData *ParseExpressionC (const PClass *cls)
static ExpData *ParseExpressionC (FScanner &sc, const PClass *cls)
{
ExpData *tmp = ParseExpressionB (cls);
ExpData *tmp = ParseExpressionB (sc, cls);
while (SC_GetToken() && (sc_TokenType == '*' || sc_TokenType == '/' || sc_TokenType == '%'))
while (sc.GetToken() && (sc.TokenType == '*' || sc.TokenType == '/' || sc.TokenType == '%'))
{
int token = sc_TokenType;
ExpData *right = ParseExpressionB (cls);
int token = sc.TokenType;
ExpData *right = ParseExpressionB (sc, cls);
ExpData *data = new ExpData;
data->Type = token == '*'? EX_Mul : token == '/'? EX_Div : EX_Mod;
data->Children[0] = tmp;
@ -626,77 +626,77 @@ static ExpData *ParseExpressionC (const PClass *cls)
data->EvalConst (cls);
tmp = data;
}
if (!sc_End) SC_UnGet();
if (!sc.End) sc.UnGet();
return tmp;
}
static ExpData *ParseExpressionB (const PClass *cls)
static ExpData *ParseExpressionB (FScanner &sc, const PClass *cls)
{
ExpData *data = new ExpData;
if (SC_CheckToken('~'))
if (sc.CheckToken('~'))
{
data->Type = EX_Compl;
}
else if (SC_CheckToken('!'))
else if (sc.CheckToken('!'))
{
data->Type = EX_Not;
}
else if (SC_CheckToken('-'))
else if (sc.CheckToken('-'))
{
data->Type = EX_Minus;
}
else
{
SC_CheckToken('+');
sc.CheckToken('+');
delete data;
return ParseExpressionA (cls);
return ParseExpressionA (sc, cls);
}
data->Children[0] = ParseExpressionA (cls);
data->Children[0] = ParseExpressionA (sc, cls);
data->EvalConst (cls);
return data;
}
static ExpData *ParseExpressionA (const PClass *cls)
static ExpData *ParseExpressionA (FScanner &sc, const PClass *cls)
{
if (SC_CheckToken('('))
if (sc.CheckToken('('))
{
ExpData *data = ParseExpressionM (cls);
SC_MustGetToken(')');
ExpData *data = ParseExpressionM (sc, cls);
sc.MustGetToken(')');
return data;
}
else if (SC_CheckToken(TK_IntConst))
else if (sc.CheckToken(TK_IntConst))
{
ExpData *data = new ExpData;
data->Type = EX_Const;
data->Value.Type = VAL_Int;
data->Value.Int = sc_Number;
data->Value.Int = sc.Number;
return data;
}
else if (SC_CheckToken(TK_FloatConst))
else if (sc.CheckToken(TK_FloatConst))
{
ExpData *data = new ExpData;
data->Type = EX_Const;
data->Value.Type = VAL_Float;
data->Value.Float = sc_Float;
data->Value.Float = sc.Float;
return data;
}
else if (SC_CheckToken(TK_Class))
else if (sc.CheckToken(TK_Class))
{
// Accept class'SomeClassName'.SomeConstant
SC_MustGetToken(TK_NameConst);
cls = PClass::FindClass (sc_Name);
sc.MustGetToken(TK_NameConst);
cls = PClass::FindClass (sc.Name);
if (cls == NULL)
{
SC_ScriptError ("Unknown class '%s'", sc_String);
sc.ScriptError ("Unknown class '%s'", sc.String);
}
SC_MustGetToken('.');
SC_MustGetToken(TK_Identifier);
PSymbol *sym = cls->Symbols.FindSymbol (sc_String, true);
sc.MustGetToken('.');
sc.MustGetToken(TK_Identifier);
PSymbol *sym = cls->Symbols.FindSymbol (sc.String, true);
if (sym != NULL && sym->SymbolType == SYM_Const)
{
ExpData *data = new ExpData;
@ -707,38 +707,38 @@ static ExpData *ParseExpressionA (const PClass *cls)
}
else
{
SC_ScriptError ("'%s' is not a constant value in class '%s'", sc_String, cls->TypeName.GetChars());
sc.ScriptError ("'%s' is not a constant value in class '%s'", sc.String, cls->TypeName.GetChars());
return NULL;
}
}
else if (SC_CheckToken(TK_Identifier))
else if (sc.CheckToken(TK_Identifier))
{
switch (FName(sc_String))
switch (FName(sc.String))
{
case NAME_Random:
{
FRandom *rng;
if (SC_CheckToken('['))
if (sc.CheckToken('['))
{
SC_MustGetToken(TK_Identifier);
rng = FRandom::StaticFindRNG(sc_String);
SC_MustGetToken(']');
sc.MustGetToken(TK_Identifier);
rng = FRandom::StaticFindRNG(sc.String);
sc.MustGetToken(']');
}
else
{
rng = &pr_exrandom;
}
SC_MustGetToken('(');
sc.MustGetToken('(');
ExpData *data = new ExpData;
data->Type = EX_Random;
data->RNG = rng;
data->Children[0] = ParseExpressionM (cls);
SC_MustGetToken(',');
data->Children[1] = ParseExpressionM (cls);
SC_MustGetToken(')');
data->Children[0] = ParseExpressionM (sc, cls);
sc.MustGetToken(',');
data->Children[1] = ParseExpressionM (sc, cls);
sc.MustGetToken(')');
return data;
}
break;
@ -747,27 +747,27 @@ static ExpData *ParseExpressionA (const PClass *cls)
{
FRandom *rng;
if (SC_CheckToken('['))
if (sc.CheckToken('['))
{
SC_MustGetToken(TK_Identifier);
rng = FRandom::StaticFindRNG(sc_String);
SC_MustGetToken(']');
sc.MustGetToken(TK_Identifier);
rng = FRandom::StaticFindRNG(sc.String);
sc.MustGetToken(']');
}
else
{
rng = &pr_exrandom;
}
SC_MustGetToken('(');
sc.MustGetToken('(');
ExpData *data = new ExpData;
data->Type = EX_Random2;
data->RNG = rng;
if (!SC_CheckToken(')'))
if (!sc.CheckToken(')'))
{
data->Children[0] = ParseExpressionM(cls);
SC_MustGetToken(')');
data->Children[0] = ParseExpressionM(sc, cls);
sc.MustGetToken(')');
}
return data;
}
@ -775,28 +775,28 @@ static ExpData *ParseExpressionA (const PClass *cls)
case NAME_Sin:
{
SC_MustGetToken('(');
sc.MustGetToken('(');
ExpData *data = new ExpData;
data->Type = EX_Sin;
data->Children[0] = ParseExpressionM (cls);
data->Children[0] = ParseExpressionM (sc, cls);
SC_MustGetToken(')');
sc.MustGetToken(')');
return data;
}
break;
case NAME_Cos:
{
SC_MustGetToken('(');
sc.MustGetToken('(');
ExpData *data = new ExpData;
data->Type = EX_Cos;
data->Children[0] = ParseExpressionM (cls);
data->Children[0] = ParseExpressionM (sc, cls);
SC_MustGetToken(')');
sc.MustGetToken(')');
return data;
}
break;
@ -806,35 +806,35 @@ static ExpData *ParseExpressionA (const PClass *cls)
int specnum, min_args, max_args;
// Check if this is an action special
strlwr (sc_String);
specnum = FindLineSpecialEx (sc_String, &min_args, &max_args);
strlwr (sc.String);
specnum = FindLineSpecialEx (sc.String, &min_args, &max_args);
if (specnum != 0)
{
int i;
SC_MustGetToken('(');
sc.MustGetToken('(');
ExpData *data = new ExpData, **left;
data->Type = EX_ActionSpecial;
data->Value.Int = specnum;
data->Children[0] = ParseExpressionM (cls);
data->Children[0] = ParseExpressionM (sc, cls);
left = &data->Children[1];
for (i = 1; i < 5 && SC_CheckToken(','); ++i)
for (i = 1; i < 5 && sc.CheckToken(','); ++i)
{
ExpData *right = new ExpData;
right->Type = EX_Right;
right->Children[0] = ParseExpressionM (cls);
right->Children[0] = ParseExpressionM (sc, cls);
*left = right;
left = &right->Children[1];
}
*left = NULL;
SC_MustGetToken(')');
sc.MustGetToken(')');
if (i < min_args)
SC_ScriptError ("Not enough arguments to action special");
sc.ScriptError ("Not enough arguments to action special");
if (i > max_args)
SC_ScriptError ("Too many arguments to action special");
sc.ScriptError ("Too many arguments to action special");
return data;
}
@ -842,7 +842,7 @@ static ExpData *ParseExpressionA (const PClass *cls)
// Check if this is a constant
if (cls != NULL)
{
PSymbol *sym = cls->Symbols.FindSymbol (sc_String, true);
PSymbol *sym = cls->Symbols.FindSymbol (sc.String, true);
if (sym != NULL && sym->SymbolType == SYM_Const)
{
ExpData *data = new ExpData;
@ -855,7 +855,7 @@ static ExpData *ParseExpressionA (const PClass *cls)
// Check if it's a variable we understand
int varid = -1;
FName vname = sc_String;
FName vname = sc.String;
for (size_t i = 0; i < countof(ExpVars); i++)
{
if (vname == ExpVars[i].name)
@ -866,7 +866,7 @@ static ExpData *ParseExpressionA (const PClass *cls)
}
if (varid == -1)
SC_ScriptError ("Unknown value '%s'", sc_String);
sc.ScriptError ("Unknown value '%s'", sc.String);
ExpData *data = new ExpData;
data->Type = EX_Var;
@ -875,9 +875,9 @@ static ExpData *ParseExpressionA (const PClass *cls)
if (ExpVars[varid].array)
{
SC_MustGetToken('[');
data->Children[0] = ParseExpressionM (cls);
SC_MustGetToken(']');
sc.MustGetToken('[');
data->Children[0] = ParseExpressionM (sc, cls);
sc.MustGetToken(']');
}
return data;
}
@ -886,8 +886,8 @@ static ExpData *ParseExpressionA (const PClass *cls)
}
else
{
FString tokname = SC_TokenName(sc_TokenType, sc_String);
SC_ScriptError ("Unexpected token %s", tokname.GetChars());
FString tokname = sc.TokenName(sc.TokenType, sc.String);
sc.ScriptError ("Unexpected token %s", tokname.GetChars());
return NULL;
}
}

View file

@ -47,12 +47,12 @@
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
void ParseActor();
void ParseClass();
void ParseGlobalConst();
void ParseGlobalEnum();
void ParseActor(FScanner &sc);
void ParseClass(FScanner &sc);
void ParseGlobalConst(FScanner &sc);
void ParseGlobalEnum(FScanner &sc);
void FinishThingdef();
void ParseOldDecoration(EDefinitionType def);
void ParseOldDecoration(FScanner &sc, EDefinitionType def);
// STATIC FUNCTION PROTOTYPES --------------------------------------------
@ -64,65 +64,64 @@ void ParseOldDecoration(EDefinitionType def);
//
//==========================================================================
static void ParseDecorate ()
static void ParseDecorate (FScanner &sc)
{
int recursion=0;
int lump;
// Get actor class name.
while (true)
for(;;)
{
SC_SavePos();
if (!SC_GetToken ())
FScanner::SavedPos pos = sc.SavePos();
if (!sc.GetToken ())
{
if (recursion==0) return;
SC_Close();
SC_RestoreScriptState();
recursion--;
continue;
return;
}
switch (sc_TokenType)
switch (sc.TokenType)
{
case TK_Include:
SC_MustGetString();
sc.MustGetString();
// This is not using SC_Open because it can print a more useful error message when done here
lump = Wads.CheckNumForFullName(sc_String);
lump = Wads.CheckNumForFullName(sc.String);
// Try a normal WAD name lookup only if it's a proper name without path separator and
// not longer than 8 characters.
if (lump==-1 && strlen(sc_String) <= 8 && !strchr(sc_String, '/'))
lump = Wads.CheckNumForName(sc_String);
if (lump==-1)
SC_ScriptError("Lump '%s' not found", sc_String);
SC_SaveScriptState();
SC_OpenLumpNum(lump, sc_String);
recursion++;
if (lump == -1 && sc.StringLen <= 8 && !strchr(sc.String, '/'))
{
lump = Wads.CheckNumForName(sc.String);
}
if (lump == -1)
{
sc.ScriptError("Lump '%s' not found", sc.String);
}
else
{
FScanner newscanner(lump, sc.String);
ParseDecorate(newscanner);
}
break;
case TK_Class:
ParseClass ();
ParseClass (sc);
break;
case TK_Const:
ParseConstant (&RUNTIME_CLASS(AActor)->Symbols, RUNTIME_CLASS(AActor));
ParseConstant (sc, &RUNTIME_CLASS(AActor)->Symbols, RUNTIME_CLASS(AActor));
break;
case TK_Enum:
ParseEnum (&RUNTIME_CLASS(AActor)->Symbols, RUNTIME_CLASS(AActor));
ParseEnum (sc, &RUNTIME_CLASS(AActor)->Symbols, RUNTIME_CLASS(AActor));
break;
case TK_Pickup:
ParseOldDecoration (DEF_Pickup);
ParseOldDecoration (sc, DEF_Pickup);
break;
case TK_Breakable:
ParseOldDecoration (DEF_BreakableDecoration);
ParseOldDecoration (sc, DEF_BreakableDecoration);
break;
case TK_Projectile:
ParseOldDecoration (DEF_Projectile);
ParseOldDecoration (sc, DEF_Projectile);
break;
case ';':
@ -130,22 +129,22 @@ static void ParseDecorate ()
// is used to parse parts of the DECORATE lump. If we don't add
// a check here the user will only get weird non-informative
// error messages if a semicolon is found.
SC_ScriptError("Unexpected ';'");
sc.ScriptError("Unexpected ';'");
break;
case TK_Identifier:
// 'ACTOR' cannot be a keyword because it is also needed as a class identifier
// so let's do a special case for this.
if (SC_Compare("ACTOR"))
if (sc.Compare("ACTOR"))
{
ParseActor ();
ParseActor (sc);
break;
}
default:
// Yuck! Too bad that there's no better way to check this properly
SC_RestorePos();
ParseOldDecoration(DEF_Decoration);
sc.RestorePos(pos);
ParseOldDecoration(sc, DEF_Decoration);
break;
}
}
@ -166,9 +165,8 @@ void LoadDecorations ()
lastlump = 0;
while ((lump = Wads.FindLump ("DECORATE", &lastlump)) != -1)
{
SC_OpenLumpNum (lump, Wads.GetLumpFullName(lump));
ParseDecorate ();
SC_Close ();
FScanner sc(lump, Wads.GetLumpFullName(lump));
ParseDecorate (sc);
}
FinishThingdef();
}

File diff suppressed because it is too large Load diff

View file

@ -436,12 +436,12 @@ int FindLineSpecialEx (const char *string, int *min_args, int *max_args)
// handles action specials as code pointers
//
//==========================================================================
bool DoActionSpecials(FState & state, bool multistate, int * statecount, Baggage &bag)
bool DoActionSpecials(FScanner &sc, FState & state, bool multistate, int * statecount, Baggage &bag)
{
int i;
const ACSspecials *spec;
if ((spec = is_special (sc_String, sc_StringLen)) != NULL)
if ((spec = is_special (sc.String, sc.StringLen)) != NULL)
{
int paramindex=PrepareStateParameters(&state, 6);
@ -449,25 +449,25 @@ bool DoActionSpecials(FState & state, bool multistate, int * statecount, Baggage
StateParameters[paramindex]=spec->Special;
// Make this consistent with all other parameter parsing
if (SC_CheckToken('('))
if (sc.CheckToken('('))
{
for (i = 0; i < 5;)
{
StateParameters[paramindex+i+1]=ParseExpression (false, bag.Info->Class);
StateParameters[paramindex+i+1] = ParseExpression (sc, false, bag.Info->Class);
i++;
if (!SC_CheckToken (',')) break;
if (!sc.CheckToken (',')) break;
}
SC_MustGetToken (')');
sc.MustGetToken (')');
}
else i=0;
if (i < spec->MinArgs)
{
SC_ScriptError ("Too few arguments to %s", spec->name);
sc.ScriptError ("Too few arguments to %s", spec->name);
}
if (i > MAX (spec->MinArgs, spec->MaxArgs))
{
SC_ScriptError ("Too many arguments to %s", spec->name);
sc.ScriptError ("Too many arguments to %s", spec->name);
}
state.Action = A_CallSpecial;
return true;
@ -514,21 +514,21 @@ static void RetargetStates (intptr_t count, const char *target)
// processes a state block
//
//==========================================================================
static FString ParseStateString()
static FString ParseStateString(FScanner &sc)
{
FString statestring;
SC_MustGetString();
statestring = sc_String;
if (SC_CheckString("::"))
sc.MustGetString();
statestring = sc.String;
if (sc.CheckString("::"))
{
SC_MustGetString ();
statestring << "::" << sc_String;
sc.MustGetString ();
statestring << "::" << sc.String;
}
while (SC_CheckString ("."))
while (sc.CheckString ("."))
{
SC_MustGetString ();
statestring << "." << sc_String;
sc.MustGetString ();
statestring << "." << sc.String;
}
return statestring;
}
@ -539,7 +539,7 @@ static FString ParseStateString()
// parses a state block
//
//==========================================================================
int ParseStates(FActorInfo * actor, AActor * defaults, Baggage &bag)
int ParseStates(FScanner &sc, FActorInfo * actor, AActor * defaults, Baggage &bag)
{
FString statestring;
intptr_t count = 0;
@ -548,21 +548,21 @@ int ParseStates(FActorInfo * actor, AActor * defaults, Baggage &bag)
intptr_t lastlabel = -1;
int minrequiredstate = -1;
SC_MustGetStringName ("{");
SC_SetEscape(false); // disable escape sequences in the state parser
while (!SC_CheckString ("}") && !sc_End)
sc.MustGetStringName ("{");
sc.SetEscape(false); // disable escape sequences in the state parser
while (!sc.CheckString ("}") && !sc.End)
{
memset(&state,0,sizeof(state));
statestring = ParseStateString();
statestring = ParseStateString(sc);
if (!statestring.CompareNoCase("GOTO"))
{
do_goto:
statestring = ParseStateString();
if (SC_CheckString ("+"))
statestring = ParseStateString(sc);
if (sc.CheckString ("+"))
{
SC_MustGetNumber ();
sc.MustGetNumber ();
statestring += '+';
statestring += sc_String;
statestring += sc.String;
}
// copy the text - this must be resolved later!
if (laststate != NULL)
@ -575,7 +575,7 @@ do_goto:
}
else
{
SC_ScriptError("GOTO before first state");
sc.ScriptError("GOTO before first state");
}
}
else if (!statestring.CompareNoCase("STOP"))
@ -591,7 +591,7 @@ do_stop:
}
else
{
SC_ScriptError("STOP before first state");
sc.ScriptError("STOP before first state");
continue;
}
}
@ -599,7 +599,7 @@ do_stop:
{
if (!laststate)
{
SC_ScriptError("%s before first state", sc_String);
sc.ScriptError("%s before first state", sc.String);
continue;
}
laststate->NextState=(FState*)-2;
@ -608,7 +608,7 @@ do_stop:
{
if (!laststate)
{
SC_ScriptError("LOOP before first state");
sc.ScriptError("LOOP before first state");
continue;
}
laststate->NextState=(FState*)(lastlabel+1);
@ -617,15 +617,15 @@ do_stop:
{
const char * statestrp;
SC_MustGetString();
if (SC_Compare (":"))
sc.MustGetString();
if (sc.Compare (":"))
{
laststate = NULL;
do
{
lastlabel = count;
AddState(statestring, (FState *) (count+1));
statestring = ParseStateString();
statestring = ParseStateString(sc);
if (!statestring.CompareNoCase("GOTO"))
{
goto do_goto;
@ -634,72 +634,75 @@ do_stop:
{
goto do_stop;
}
SC_MustGetString ();
} while (SC_Compare (":"));
sc.MustGetString ();
} while (sc.Compare (":"));
// continue;
}
SC_UnGet ();
sc.UnGet ();
if (statestring.Len() != 4)
{
SC_ScriptError ("Sprite names must be exactly 4 characters\n");
sc.ScriptError ("Sprite names must be exactly 4 characters\n");
}
memcpy(state.sprite.name, statestring, 4);
state.Misc1=state.Misc2=0;
state.ParameterIndex=0;
SC_MustGetString();
statestring = (sc_String+1);
state.Misc1 = state.Misc2 = 0;
state.ParameterIndex = 0;
sc.MustGetString();
statestring = (sc.String+1);
statestrp = statestring;
state.Frame=(*sc_String&223)-'A';
if ((*sc_String&223)<'A' || (*sc_String&223)>']')
state.Frame = (*sc.String & 223)-'A';
if ((*sc.String & 223)<'A' || (*sc.String & 223)>']')
{
SC_ScriptError ("Frames must be A-Z, [, \\, or ]");
sc.ScriptError ("Frames must be A-Z, [, \\, or ]");
state.Frame=0;
}
SC_MustGetNumber();
sc_Number++;
state.Tics=sc_Number&255;
state.Misc1=(sc_Number>>8)&255;
if (state.Misc1) state.Frame|=SF_BIGTIC;
while (SC_GetString() && !sc_Crossed)
sc.MustGetNumber();
sc.Number++;
state.Tics = sc.Number & 255;
state.Misc1 = (sc.Number >> 8) & 255;
if (state.Misc1)
{
if (SC_Compare("BRIGHT"))
state.Frame |= SF_BIGTIC;
}
while (sc.GetString() && !sc.Crossed)
{
if (sc.Compare("BRIGHT"))
{
state.Frame|=SF_FULLBRIGHT;
state.Frame |= SF_FULLBRIGHT;
continue;
}
if (SC_Compare("OFFSET"))
if (sc.Compare("OFFSET"))
{
if (state.Frame&SF_BIGTIC)
if (state.Frame & SF_BIGTIC)
{
SC_ScriptError("You cannot use OFFSET with a state duration larger than 254!");
sc.ScriptError("You cannot use OFFSET with a state duration larger than 254!");
}
// specify a weapon offset
SC_MustGetStringName("(");
SC_MustGetNumber();
state.Misc1=sc_Number;
SC_MustGetStringName (",");
SC_MustGetNumber();
state.Misc2=sc_Number;
SC_MustGetStringName(")");
sc.MustGetStringName("(");
sc.MustGetNumber();
state.Misc1 = sc.Number;
sc.MustGetStringName (",");
sc.MustGetNumber();
state.Misc2 = sc.Number;
sc.MustGetStringName(")");
continue;
}
// Make the action name lowercase to satisfy the gperf hashers
strlwr (sc_String);
strlwr (sc.String);
int minreq=count;
if (DoActionSpecials(state, !statestring.IsEmpty(), &minreq, bag))
int minreq = count;
if (DoActionSpecials(sc, state, !statestring.IsEmpty(), &minreq, bag))
{
if (minreq>minrequiredstate) minrequiredstate=minreq;
goto endofstate;
}
PSymbol *sym = bag.Info->Class->Symbols.FindSymbol (FName(sc_String, true), true);
PSymbol *sym = bag.Info->Class->Symbols.FindSymbol (FName(sc.String, true), true);
if (sym != NULL && sym->SymbolType == SYM_ActionFunction)
{
PSymbolActionFunction *afd = static_cast<PSymbolActionFunction *>(sym);
@ -713,11 +716,11 @@ do_stop:
if (!islower(*params))
{
SC_MustGetStringName("(");
sc.MustGetStringName("(");
}
else
{
if (!SC_CheckString("(")) goto endofstate;
if (!sc.CheckString("(")) goto endofstate;
}
int paramindex = PrepareStateParameters(&state, numparams);
@ -735,47 +738,47 @@ do_stop:
{
case 'I':
case 'i': // Integer
SC_MustGetNumber();
v=sc_Number;
sc.MustGetNumber();
v = sc.Number;
break;
case 'F':
case 'f': // Fixed point
SC_MustGetFloat();
v=fixed_t(sc_Float*FRACUNIT);
sc.MustGetFloat();
v = fixed_t(sc.Float*FRACUNIT);
break;
case 'S':
case 's': // Sound name
SC_MustGetString();
v=S_FindSound(sc_String);
sc.MustGetString();
v = S_FindSound(sc.String);
break;
case 'M':
case 'm': // Actor name
case 'T':
case 't': // String
SC_SetEscape(true);
SC_MustGetString();
SC_SetEscape(false);
v = (int)(sc_String[0] ? FName(sc_String) : NAME_None);
sc.SetEscape(true);
sc.MustGetString();
sc.SetEscape(false);
v = (int)(sc.String[0] ? FName(sc.String) : NAME_None);
break;
case 'L':
case 'l': // Jump label
if (SC_CheckNumber())
if (sc.CheckNumber())
{
if (sc_Number > 0 && strlen(statestring)>0)
if (sc.Number > 0 && strlen(statestring)>0)
{
SC_ScriptError("You cannot use state jumps commands with a jump offset on multistate definitions\n");
sc.ScriptError("You cannot use state jumps commands with a jump offset on multistate definitions\n");
}
v=sc_Number;
v=sc.Number;
if (v<0)
{
SC_ScriptError("Negative jump offsets are not allowed");
sc.ScriptError("Negative jump offsets are not allowed");
}
{
@ -789,13 +792,13 @@ do_stop:
v = -(int)JumpParameters.Size();
// This forces quotation marks around the state name.
SC_MustGetToken(TK_StringConst);
if (sc_String[0] == 0 || SC_Compare("None"))
sc.MustGetToken(TK_StringConst);
if (sc.String[0] == 0 || sc.Compare("None"))
{
v = 0; // an empty string means 'no state'.
break;
}
FString statestring = sc_String; // ParseStateString();
FString statestring = sc.String; // ParseStateString(sc);
const PClass *stype=NULL;
int scope = statestring.IndexOf("::");
if (scope >= 0)
@ -812,15 +815,15 @@ do_stop:
stype = PClass::FindClass (scopename);
if (stype == NULL)
{
SC_ScriptError ("%s is an unknown class.", scopename.GetChars());
sc.ScriptError ("%s is an unknown class.", scopename.GetChars());
}
if (!stype->IsDescendantOf (RUNTIME_CLASS(AActor)))
{
SC_ScriptError ("%s is not an actor class, so it has no states.", stype->TypeName.GetChars());
sc.ScriptError ("%s is not an actor class, so it has no states.", stype->TypeName.GetChars());
}
if (!stype->IsAncestorOf (actor->Class))
{
SC_ScriptError ("%s is not derived from %s so cannot access its states.",
sc.ScriptError ("%s is not derived from %s so cannot access its states.",
actor->Class->TypeName.GetChars(), stype->TypeName.GetChars());
}
}
@ -839,7 +842,7 @@ do_stop:
{
if (!stype->ActorInfo->FindState(names.Size(), &names[0]))
{
SC_ScriptError("Jump to unknown state '%s' in class '%s'",
sc.ScriptError("Jump to unknown state '%s' in class '%s'",
statestring.GetChars(), stype->TypeName.GetChars());
}
}
@ -855,14 +858,14 @@ do_stop:
case 'C':
case 'c': // Color
SC_MustGetString ();
if (SC_Compare("none"))
sc.MustGetString ();
if (sc.Compare("none"))
{
v = -1;
}
else
{
int c = V_GetColor (NULL, sc_String);
int c = V_GetColor (NULL, sc.String);
// 0 needs to be the default so we have to mark the color.
v = MAKEARGB(1, RPART(c), GPART(c), BPART(c));
}
@ -870,12 +873,12 @@ do_stop:
case 'X':
case 'x':
v = ParseExpression (false, bag.Info->Class);
v = ParseExpression (sc, false, bag.Info->Class);
break;
case 'Y':
case 'y':
v = ParseExpression (true, bag.Info->Class);
v = ParseExpression (sc, true, bag.Info->Class);
break;
default:
@ -893,7 +896,7 @@ do_stop:
{
if (*params == '+')
{
if (SC_CheckString(")"))
if (sc.CheckString(")"))
{
goto endofstate;
}
@ -901,29 +904,29 @@ do_stop:
v = 0;
StateParameters.Push(v);
}
else if ((islower(*params) || *params=='!') && SC_CheckString(")"))
else if ((islower(*params) || *params=='!') && sc.CheckString(")"))
{
goto endofstate;
}
SC_MustGetStringName (",");
sc.MustGetStringName (",");
}
}
SC_MustGetStringName(")");
sc.MustGetStringName(")");
}
else
{
SC_MustGetString();
if (SC_Compare("("))
sc.MustGetString();
if (sc.Compare("("))
{
SC_ScriptError("You cannot pass parameters to '%s'\n",sc_String);
sc.ScriptError("You cannot pass parameters to '%s'\n",sc.String);
}
SC_UnGet();
sc.UnGet();
}
goto endofstate;
}
SC_ScriptError("Invalid state parameter %s\n", sc_String);
sc.ScriptError("Invalid state parameter %s\n", sc.String);
}
SC_UnGet();
sc.UnGet();
endofstate:
StateArray.Push(state);
while (*statestrp)
@ -932,7 +935,7 @@ endofstate:
if (frame<0 || frame>28)
{
SC_ScriptError ("Frames must be A-Z, [, \\, or ]");
sc.ScriptError ("Frames must be A-Z, [, \\, or ]");
frame=0;
}
@ -946,9 +949,9 @@ endofstate:
}
if (count<=minrequiredstate)
{
SC_ScriptError("A_Jump offset out of range in %s", actor->Class->TypeName.GetChars());
sc.ScriptError("A_Jump offset out of range in %s", actor->Class->TypeName.GetChars());
}
SC_SetEscape(true); // re-enable escape sequences
sc.SetEscape(true); // re-enable escape sequences
return count;
}
@ -958,7 +961,7 @@ endofstate:
//
//==========================================================================
static FState *ResolveGotoLabel (AActor *actor, const PClass *mytype, char *name)
static FState *ResolveGotoLabel (FScanner &sc, AActor *actor, const PClass *mytype, char *name)
{
const PClass *type=mytype;
FState *state;
@ -986,15 +989,15 @@ static FState *ResolveGotoLabel (AActor *actor, const PClass *mytype, char *name
const PClass *stype = PClass::FindClass (classname);
if (stype == NULL)
{
SC_ScriptError ("%s is an unknown class.", classname);
sc.ScriptError ("%s is an unknown class.", classname);
}
if (!stype->IsDescendantOf (RUNTIME_CLASS(AActor)))
{
SC_ScriptError ("%s is not an actor class, so it has no states.", stype->TypeName.GetChars());
sc.ScriptError ("%s is not an actor class, so it has no states.", stype->TypeName.GetChars());
}
if (!stype->IsAncestorOf (type))
{
SC_ScriptError ("%s is not derived from %s so cannot access its states.",
sc.ScriptError ("%s is not derived from %s so cannot access its states.",
type->TypeName.GetChars(), stype->TypeName.GetChars());
}
if (type != stype)
@ -1024,7 +1027,7 @@ static FState *ResolveGotoLabel (AActor *actor, const PClass *mytype, char *name
}
else if (v != 0)
{
SC_ScriptError ("Attempt to get invalid state %s from actor %s.", label, type->TypeName.GetChars());
sc.ScriptError ("Attempt to get invalid state %s from actor %s.", label, type->TypeName.GetChars());
}
delete[] namestart; // free the allocated string buffer
return state;
@ -1059,15 +1062,15 @@ static void FixStatePointers (FActorInfo *actor, TArray<FStateDefine> & list)
//
//==========================================================================
static void FixStatePointersAgain (FActorInfo *actor, AActor *defaults, TArray<FStateDefine> & list)
static void FixStatePointersAgain (FScanner &sc, FActorInfo *actor, AActor *defaults, TArray<FStateDefine> & list)
{
for(unsigned i=0;i<list.Size(); i++)
{
if (list[i].State != NULL && FState::StaticFindStateOwner (list[i].State, actor) == NULL)
{ // It's not a valid state, so it must be a label string. Resolve it.
list[i].State = ResolveGotoLabel (defaults, actor->Class, (char *)list[i].State);
list[i].State = ResolveGotoLabel (sc, defaults, actor->Class, (char *)list[i].State);
}
if (list[i].Children.Size() > 0) FixStatePointersAgain(actor, defaults, list[i].Children);
if (list[i].Children.Size() > 0) FixStatePointersAgain(sc, actor, defaults, list[i].Children);
}
}
@ -1079,7 +1082,7 @@ static void FixStatePointersAgain (FActorInfo *actor, AActor *defaults, TArray<F
//
//==========================================================================
int FinishStates (FActorInfo *actor, AActor *defaults, Baggage &bag)
int FinishStates (FScanner &sc, FActorInfo *actor, AActor *defaults, Baggage &bag)
{
static int c=0;
int count = StateArray.Size();
@ -1122,7 +1125,7 @@ int FinishStates (FActorInfo *actor, AActor *defaults, Baggage &bag)
}
else // goto
{
realstates[i].NextState = ResolveGotoLabel (defaults, bag.Info->Class, (char *)realstates[i].NextState);
realstates[i].NextState = ResolveGotoLabel (sc, defaults, bag.Info->Class, (char *)realstates[i].NextState);
}
}
}
@ -1130,7 +1133,7 @@ int FinishStates (FActorInfo *actor, AActor *defaults, Baggage &bag)
StateArray.Clear ();
// Fix state pointers that are gotos
FixStatePointersAgain (actor, defaults, StateLabels);
FixStatePointersAgain (sc, actor, defaults, StateLabels);
return count;
}
@ -1142,35 +1145,35 @@ int FinishStates (FActorInfo *actor, AActor *defaults, Baggage &bag)
// This is strictly for keeping compatibility with old WADs!
//
//==========================================================================
FState *CheckState(PClass *type)
FState *CheckState(FScanner &sc, PClass *type)
{
int v=0;
if (SC_GetString() && !sc_Crossed)
if (sc.GetString() && !sc.Crossed)
{
if (SC_Compare("0")) return NULL;
else if (SC_Compare("PARENT"))
if (sc.Compare("0")) return NULL;
else if (sc.Compare("PARENT"))
{
FState * state = NULL;
SC_MustGetString();
sc.MustGetString();
FActorInfo * info = type->ParentClass->ActorInfo;
if (info != NULL)
{
state = info->FindState(FName(sc_String));
state = info->FindState(FName(sc.String));
}
if (SC_GetString ())
if (sc.GetString ())
{
if (SC_Compare ("+"))
if (sc.Compare ("+"))
{
SC_MustGetNumber ();
v = sc_Number;
sc.MustGetNumber ();
v = sc.Number;
}
else
{
SC_UnGet ();
sc.UnGet ();
}
}
@ -1178,13 +1181,13 @@ FState *CheckState(PClass *type)
if (v!=0 && state==NULL)
{
SC_ScriptError("Attempt to get invalid state from actor %s\n", type->ParentClass->TypeName.GetChars());
sc.ScriptError("Attempt to get invalid state from actor %s\n", type->ParentClass->TypeName.GetChars());
return NULL;
}
state+=v;
return state;
}
else SC_ScriptError("Invalid state assignment");
else sc.ScriptError("Invalid state assignment");
}
return NULL;
}

View file

@ -67,7 +67,6 @@ void STACK_ARGS DCanvas::DrawTextureV(FTexture *img, int x, int y, uint32 tag, v
{
FTexture::Span unmaskedSpan[2];
const FTexture::Span **spanptr, *spans;
static BYTE identitymap[256];
static short bottomclipper[MAXWIDTH], topclipper[MAXWIDTH];
DrawParms parms;
@ -86,32 +85,38 @@ void STACK_ARGS DCanvas::DrawTextureV(FTexture *img, int x, int y, uint32 tag, v
spanptr = NULL;
}
fixedcolormap = identitymap;
ESPSResult mode = R_SetPatchStyle (parms.style, parms.alpha, 0, parms.fillcolor);
if (APART(parms.colorOverlay) != 0)
{
// In software, DTA_ColorOverlay only does black overlays.
// Maybe I will change this later, but right now white is the only
// color that is actually used for this parameter.
// Note that this is also overriding DTA_Translation in software.
if ((parms.colorOverlay & MAKEARGB(0,255,255,255)) == 0)
// The software renderer cannot invert the source without inverting the overlay
// too. That means if the source is inverted, we need to do the reverse of what
// the invert overlay flag says to do.
INTBOOL invertoverlay = (parms.style.Flags & STYLEF_InvertOverlay);
if (parms.style.Flags & STYLEF_InvertSource)
{
parms.translation = &NormalLight.Maps[(APART(parms.colorOverlay)*NUMCOLORMAPS/255)*256];
invertoverlay = !invertoverlay;
}
if (invertoverlay)
{
parms.colorOverlay = PalEntry(parms.colorOverlay).InverseColor();
}
// Note that this overrides DTA_Translation in software, but not in hardware.
FDynamicColormap *colormap = GetSpecialLights(MAKERGB(255,255,255),
parms.colorOverlay & MAKEARGB(0,255,255,255), 0);
parms.translation = &colormap->Maps[(APART(parms.colorOverlay)*NUMCOLORMAPS/255)*256];
}
if (parms.style != STYLE_Shaded)
if (parms.translation != NULL)
{
if (parms.translation != NULL)
{
dc_colormap = (lighttable_t *)parms.translation;
}
else
{
dc_colormap = identitymap;
}
dc_colormap = (lighttable_t *)parms.translation;
}
else
{
dc_colormap = identitymap;
}
fixedcolormap = dc_colormap;
ESPSResult mode = R_SetPatchStyle (parms.style, parms.alpha, 0, parms.fillcolor);
BYTE *destorgsave = dc_destorg;
dc_destorg = screen->GetBuffer();
@ -155,13 +160,6 @@ void STACK_ARGS DCanvas::DrawTextureV(FTexture *img, int x, int y, uint32 tag, v
if (bottomclipper[0] != parms.dclip)
{
clearbufshort (bottomclipper, screen->GetWidth(), (short)parms.dclip);
if (identitymap[1] != 1)
{
for (int i = 0; i < 256; ++i)
{
identitymap[i] = i;
}
}
}
if (parms.uclip != 0)
{
@ -299,7 +297,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, int x, int y, DWORD tag, va_l
parms->virtWidth = this->GetWidth();
parms->virtHeight = this->GetHeight();
parms->keepratio = false;
parms->style = STYLE_Count;
parms->style.BlendOp = 255; // Dummy "not set" value
parms->masked = true;
parms->bilinear = false;
@ -601,7 +599,7 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, int x, int y, DWORD tag, va_l
parms->translation = parms->remap->Remap;
}
if (parms->style == STYLE_Count)
if (parms->style.BlendOp == 255)
{
if (parms->fillcolor != -1)
{

View file

@ -32,6 +32,45 @@
**
*/
/* Special file formats handled here:
FON1 "console" fonts have the following header:
char Magic[4]; -- The characters "FON1"
uword CharWidth; -- Character cell width
uword CharHeight; -- Character cell height
The FON1 header is followed by RLE character data for all 256
8-bit ASCII characters.
FON2 "standard" fonts have the following header:
char Magic[4]; -- The characters "FON2"
uword FontHeight; -- Every character in a font has the same height
ubyte FirstChar; -- First character defined by this font.
ubyte LastChar; -- Last character definde by this font.
ubyte bConstantWidth;
ubyte ShadingType;
ubyte PaletteSize; -- size of palette in entries (not bytes!)
ubyte Flags;
There is presently only one flag for FON2:
FOF_WHOLEFONTKERNING 1 -- The Kerning field is present in the file
The FON2 header is followed by variable length data:
word Kerning;
-- only present if FOF_WHOLEFONTKERNING is set
ubyte Palette[PaletteSize+1][3];
-- The last entry is the delimiter color. The delimiter is not used
-- by the font but is used my imagetool when converting the font
-- back to an image. Color 0 is the transparent color and is also
-- used only for converting the font back to an image. The other
-- entries are all presorted in increasing order of brightness.
ubyte CharacterData[...];
-- RLE character data, in order
*/
// HEADER FILES ------------------------------------------------------------
#include <stdlib.h>
@ -171,7 +210,7 @@ static TArray<PalEntry> TranslationColors;
// CODE --------------------------------------------------------------------
FFont * V_GetFont(const char *name)
FFont *V_GetFont(const char *name)
{
FFont *font = FFont::FindFont (name);
if (font == NULL)
@ -210,7 +249,7 @@ FFont * V_GetFont(const char *name)
}
if (picnum > 0)
{
font = new FSingleLumpFont (name, -1);
font = new FSinglePicFont (name);
}
}
}
@ -334,7 +373,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
{
SpaceWidth = 4;
}
BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors);
BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors, NULL);
delete[] luminosity;
delete[] charlumps;
@ -538,12 +577,13 @@ int FFont::SimpleTranslation (BYTE *colorsused, BYTE *translation, BYTE *reverse
// large this array is. Identity is an array that remaps the colors to
// their original values; it is only used for CR_UNTRANSLATED. Ranges
// is an array of TranslationParm structs defining the ranges for every
// possible color, in order.
// possible color, in order. Palette is the colors to use for the
// untranslated version of the font.
//
//==========================================================================
void FFont::BuildTranslations (const double *luminosity, const BYTE *identity,
const void *ranges, int total_colors)
const void *ranges, int total_colors, const PalEntry *palette)
{
int i, j;
const TranslationParm *parmstart = (const TranslationParm *)ranges;
@ -559,9 +599,17 @@ void FFont::BuildTranslations (const double *luminosity, const BYTE *identity,
if (identity != NULL)
{
memcpy (remap.Remap, identity, ActiveColors);
for (j = 0; j < ActiveColors; ++j)
if (palette != NULL)
{
remap.Palette[j] = GPalette.BaseColors[identity[j]];
memcpy (remap.Palette, palette, ActiveColors*sizeof(PalEntry));
}
else
{
remap.Palette[0] = GPalette.BaseColors[identity[0]] & MAKEARGB(0,255,255,255);
for (j = 1; j < ActiveColors; ++j)
{
remap.Palette[j] = GPalette.BaseColors[identity[j]] | MAKEARGB(255,0,0,0);
}
}
}
else
@ -712,52 +760,35 @@ FFont::FFont ()
//
// FSingleLumpFont :: FSingleLumpFont
//
// Loads a FON1 or FON2 font resource or a single texture.
// Loads a FON1 or FON2 font resource.
//
//==========================================================================
FSingleLumpFont::FSingleLumpFont (const char *name, int lump)
{
assert(lump >= 0);
Name = copystring (name);
// If lump is -1, then the font name is really a texture name, so
// the font should be a redirect to the texture.
// If lump is >= 0, then the font is really a font.
if (lump < 0)
{
int picnum = TexMan.CheckForTexture (name, FTexture::TEX_Any);
FMemLump data1 = Wads.ReadLump (lump);
const BYTE *data = (const BYTE *)data1.GetMem();
if (picnum > 0)
{
CreateFontFromPic (picnum);
}
else
{
I_FatalError ("%s is not a font or texture", name);
}
if (data[0] != 'F' || data[1] != 'O' || data[2] != 'N' ||
(data[3] != '1' && data[3] != '2'))
{
I_FatalError ("%s is not a recognizable font", name);
}
else
{
FMemLump data1 = Wads.ReadLump (lump);
const BYTE *data = (const BYTE *)data1.GetMem();
if (data[0] != 'F' || data[1] != 'O' || data[2] != 'N' ||
(data[3] != '1' && data[3] != '2'))
switch (data[3])
{
I_FatalError ("%s is not a recognizable font", name);
}
else
{
switch (data[3])
{
case '1':
LoadFON1 (lump, data);
break;
case '1':
LoadFON1 (lump, data);
break;
case '2':
LoadFON2 (lump, data);
break;
}
case '2':
LoadFON2 (lump, data);
break;
}
}
@ -813,7 +844,7 @@ void FSingleLumpFont::LoadFON1 (int lump, const BYTE *data)
PatchRemap = new BYTE[256];
CheckFON1Chars (lump, data, luminosity);
BuildTranslations (luminosity, NULL, &TranslationParms[1][0], ActiveColors);
BuildTranslations (luminosity, NULL, &TranslationParms[1][0], ActiveColors, NULL);
}
//==========================================================================
@ -831,6 +862,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data)
int *widths2;
BYTE identity[256];
double luminosity[256];
PalEntry local_palette[256];
WORD *widths;
const BYTE *palette;
const BYTE *data_p;
@ -844,19 +876,19 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data)
Chars = new CharData[count];
widths2 = new int[count];
if (data[11] & 1)
{
{ // Font specifies a kerning value.
GlobalKerning = LittleShort(*(SWORD *)&data[12]);
widths = (WORD *)(data + 14);
}
else
{
{ // Font does not specify a kerning value.
GlobalKerning = 0;
widths = (WORD *)(data + 12);
}
totalwidth = 0;
if (data[8])
{
{ // Font is mono-spaced.
totalwidth = LittleShort(widths[0]);
for (i = 0; i < count; ++i)
{
@ -866,7 +898,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data)
palette = (BYTE *)&widths[1];
}
else
{
{ // Font has varying character widths.
for (i = 0; i < count; ++i)
{
widths2[i] = LittleShort(widths[i]);
@ -888,7 +920,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data)
SpaceWidth = totalwidth * 2 / (3 * count);
}
FixupPalette (identity, luminosity, palette, data[9] == 0);
FixupPalette (identity, luminosity, palette, data[9] == 0, local_palette);
data_p = palette + (ActiveColors+1)*3;
@ -924,7 +956,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data)
}
}
BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors);
BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors, local_palette);
delete[] widths2;
}
@ -999,7 +1031,7 @@ void FSingleLumpFont::CheckFON1Chars (int lump, const BYTE *data, double *lumino
//
//==========================================================================
void FSingleLumpFont::FixupPalette (BYTE *identity, double *luminosity, const BYTE *palette, bool rescale)
void FSingleLumpFont::FixupPalette (BYTE *identity, double *luminosity, const BYTE *palette, bool rescale, PalEntry *out_palette)
{
int i;
double maxlum = 0.0;
@ -1009,20 +1041,24 @@ void FSingleLumpFont::FixupPalette (BYTE *identity, double *luminosity, const BY
identity[0] = 0;
palette += 3; // Skip the transparent color
for (i = 1; i <= ActiveColors; ++i)
for (i = 1; i <= ActiveColors; ++i, palette += 3)
{
int r = palette[0];
int g = palette[1];
int b = palette[2];
double lum = r*0.299 + g*0.587 + b*0.114;
palette += 3;
identity[i] = ColorMatcher.Pick (r, g, b);
luminosity[i] = lum;
out_palette[i].r = r;
out_palette[i].g = g;
out_palette[i].b = b;
out_palette[i].a = 255;
if (lum > maxlum)
maxlum = lum;
if (lum < minlum)
minlum = lum;
}
out_palette[0] = 0;
if (rescale)
{
@ -1038,6 +1074,74 @@ void FSingleLumpFont::FixupPalette (BYTE *identity, double *luminosity, const BY
}
}
//==========================================================================
//
// FSinglePicFont :: FSinglePicFont
//
// Creates a font to wrap a texture so that you can use hudmessage as if it
// were a hudpic command. It does not support translation, but animation
// is supported, unlike all the real fonts.
//
//==========================================================================
FSinglePicFont::FSinglePicFont(const char *picname)
{
int picnum = TexMan.CheckForTexture (picname, FTexture::TEX_Any);
if (picnum <= 0)
{
I_FatalError ("%s is not a font or texture", picname);
}
FTexture *pic = TexMan[picnum];
Name = copystring(picname);
FontHeight = pic->GetHeight();
SpaceWidth = pic->GetWidth();
GlobalKerning = 0;
FirstChar = LastChar = 'A';
ActiveColors = 0;
PicNum = picnum;
Next = FirstFont;
FirstFont = this;
}
//==========================================================================
//
// FSinglePicFont :: GetChar
//
// Returns the texture if code is 'a' or 'A', otherwise NULL.
//
//==========================================================================
FTexture *FSinglePicFont::GetChar (int code, int *const width) const
{
*width = SpaceWidth;
if (code == 'a' || code == 'A')
{
return TexMan(PicNum);
}
else
{
return NULL;
}
}
//==========================================================================
//
// FSinglePicFont :: GetCharWidth
//
// Don't expect the text functions to work properly if I actually allowed
// the character width to vary depending on the animation frame.
//
//==========================================================================
int FSinglePicFont::GetCharWidth (int code) const
{
return SpaceWidth;
}
//==========================================================================
//
// FFontChar1 :: FFontChar1
@ -1438,7 +1542,7 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, int *lumplis
SpaceWidth = 4;
}
BuildTranslations (luminosity, identity, &TranslationParms[0][0], TotalColors);
BuildTranslations (luminosity, identity, &TranslationParms[0][0], TotalColors, NULL);
// add the untranslated colors to the Ranges tables
if (ActiveColors < TotalColors)
@ -1470,6 +1574,7 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, int *lumplis
void V_InitCustomFonts()
{
FScanner sc;
int lumplist[256];
bool notranslate[256];
char namebuffer[16], templatebuf[16];
@ -1482,75 +1587,75 @@ void V_InitCustomFonts()
while ((llump = Wads.FindLump ("FONTDEFS", &lastlump)) != -1)
{
SC_OpenLumpNum (llump, "FONTDEFS");
while (SC_GetString())
sc.OpenLumpNum(llump, "FONTDEFS");
while (sc.GetString())
{
memset (lumplist, -1, sizeof(lumplist));
memset (notranslate, 0, sizeof(notranslate));
strncpy (namebuffer, sc_String, 15);
strncpy (namebuffer, sc.String, 15);
namebuffer[15] = 0;
format = 0;
start = 33;
first = 33;
count = 223;
SC_MustGetStringName ("{");
while (!SC_CheckString ("}"))
sc.MustGetStringName ("{");
while (!sc.CheckString ("}"))
{
SC_MustGetString();
if (SC_Compare ("TEMPLATE"))
sc.MustGetString();
if (sc.Compare ("TEMPLATE"))
{
if (format == 2) goto wrong;
SC_MustGetString();
strncpy (templatebuf, sc_String, 16);
sc.MustGetString();
strncpy (templatebuf, sc.String, 16);
templatebuf[15] = 0;
format = 1;
}
else if (SC_Compare ("BASE"))
else if (sc.Compare ("BASE"))
{
if (format == 2) goto wrong;
SC_MustGetNumber();
start = sc_Number;
sc.MustGetNumber();
start = sc.Number;
format = 1;
}
else if (SC_Compare ("FIRST"))
else if (sc.Compare ("FIRST"))
{
if (format == 2) goto wrong;
SC_MustGetNumber();
first = sc_Number;
sc.MustGetNumber();
first = sc.Number;
format = 1;
}
else if (SC_Compare ("COUNT"))
else if (sc.Compare ("COUNT"))
{
if (format == 2) goto wrong;
SC_MustGetNumber();
count = sc_Number;
sc.MustGetNumber();
count = sc.Number;
format = 1;
}
else if (SC_Compare ("NOTRANSLATION"))
else if (sc.Compare ("NOTRANSLATION"))
{
if (format == 1) goto wrong;
while (SC_CheckNumber() && !sc_Crossed)
while (sc.CheckNumber() && !sc.Crossed)
{
if (sc_Number >= 0 && sc_Number < 256)
notranslate[sc_Number] = true;
if (sc.Number >= 0 && sc.Number < 256)
notranslate[sc.Number] = true;
}
format=2;
}
else
{
if (format == 1) goto wrong;
int *p = &lumplist[*(unsigned char*)sc_String];
SC_MustGetString();
*p = Wads.CheckNumForName (sc_String);
int *p = &lumplist[*(unsigned char*)sc.String];
sc.MustGetString();
*p = Wads.CheckNumForName (sc.String);
format=2;
}
}
if (format==1)
if (format == 1)
{
new FFont (namebuffer, templatebuf, first, count, start);
}
else if (format==2)
else if (format == 2)
{
for (i = 0; i < 256; i++)
{
@ -1575,12 +1680,12 @@ void V_InitCustomFonts()
}
else goto wrong;
}
SC_Close ();
sc.Close();
}
return;
wrong:
SC_ScriptError ("Invalid combination of properties in font '%s'", namebuffer);
sc.ScriptError ("Invalid combination of properties in font '%s'", namebuffer);
}
//==========================================================================
@ -1610,8 +1715,8 @@ void V_InitFontColors ()
while ((lump = Wads.FindLump ("TEXTCOLO", &lastlump)) != -1)
{
SC_OpenLumpNum (lump, "textcolors.txt");
while (SC_GetString())
FScanner sc(lump, "textcolors.txt");
while (sc.GetString())
{
names.Clear();
@ -1619,14 +1724,14 @@ void V_InitFontColors ()
// Everything until the '{' is considered a valid name for the
// color range.
names.Push (sc_String);
while (SC_MustGetString(), !SC_Compare ("{"))
names.Push (sc.String);
while (sc.MustGetString(), !sc.Compare ("{"))
{
if (names[0] == NAME_Untranslated)
{
SC_ScriptError ("The \"untranslated\" color may not have any other names");
sc.ScriptError ("The \"untranslated\" color may not have any other names");
}
names.Push (sc_String);
names.Push (sc.String);
}
parmchoice = 0;
@ -1635,66 +1740,66 @@ void V_InitFontColors ()
info.ParmLen[1] = info.ParmLen[0] = 0;
tparm.RangeEnd = tparm.RangeStart = -1;
while (SC_MustGetString(), !SC_Compare ("}"))
while (sc.MustGetString(), !sc.Compare ("}"))
{
if (SC_Compare ("Console:"))
if (sc.Compare ("Console:"))
{
if (parmchoice == 1)
{
SC_ScriptError ("Each color may only have one set of console ranges");
sc.ScriptError ("Each color may only have one set of console ranges");
}
parmchoice = 1;
info.StartParm[1] = parms.Size();
info.ParmLen[0] = info.StartParm[1] - info.StartParm[0];
tparm.RangeEnd = tparm.RangeStart = -1;
}
else if (SC_Compare ("Flat:"))
else if (sc.Compare ("Flat:"))
{
SC_MustGetString();
logcolor = V_GetColor (NULL, sc_String);
sc.MustGetString();
logcolor = V_GetColor (NULL, sc.String);
}
else
{
// Get first color
c = V_GetColor (NULL, sc_String);
c = V_GetColor (NULL, sc.String);
tparm.Start[0] = RPART(c);
tparm.Start[1] = GPART(c);
tparm.Start[2] = BPART(c);
// Get second color
SC_MustGetString();
c = V_GetColor (NULL, sc_String);
sc.MustGetString();
c = V_GetColor (NULL, sc.String);
tparm.End[0] = RPART(c);
tparm.End[1] = GPART(c);
tparm.End[2] = BPART(c);
// Check for range specifier
if (SC_CheckNumber())
if (sc.CheckNumber())
{
if (tparm.RangeStart == -1 && sc_Number != 0)
if (tparm.RangeStart == -1 && sc.Number != 0)
{
SC_ScriptError ("The first color range must start at position 0");
sc.ScriptError ("The first color range must start at position 0");
}
if (sc_Number < 0 || sc_Number > 256)
if (sc.Number < 0 || sc.Number > 256)
{
SC_ScriptError ("The color range must be within positions [0,256]");
sc.ScriptError ("The color range must be within positions [0,256]");
}
if (sc_Number <= tparm.RangeEnd)
if (sc.Number <= tparm.RangeEnd)
{
SC_ScriptError ("The color range must not start before the previous one ends");
sc.ScriptError ("The color range must not start before the previous one ends");
}
tparm.RangeStart = sc_Number;
tparm.RangeStart = sc.Number;
SC_MustGetNumber();
if (sc_Number < 0 || sc_Number > 256)
sc.MustGetNumber();
if (sc.Number < 0 || sc.Number > 256)
{
SC_ScriptError ("The color range must be within positions [0,256]");
sc.ScriptError ("The color range must be within positions [0,256]");
}
if (sc_Number <= tparm.RangeStart)
if (sc.Number <= tparm.RangeStart)
{
SC_ScriptError ("The color range end position must be larger than the start position");
sc.ScriptError ("The color range end position must be larger than the start position");
}
tparm.RangeEnd = sc_Number;
tparm.RangeEnd = sc.Number;
}
else
{
@ -1702,7 +1807,7 @@ void V_InitFontColors ()
tparm.RangeEnd = 256;
if (tparm.RangeStart >= tparm.RangeEnd)
{
SC_ScriptError ("The color has too many ranges");
sc.ScriptError ("The color has too many ranges");
}
}
parms.Push (tparm);
@ -1713,14 +1818,14 @@ void V_InitFontColors ()
{
if (names[0] != NAME_Untranslated)
{
SC_ScriptError ("There must be at least one normal range for a color");
sc.ScriptError ("There must be at least one normal range for a color");
}
}
else
{
if (names[0] == NAME_Untranslated)
{
SC_ScriptError ("The \"untranslated\" color must be left undefined");
sc.ScriptError ("The \"untranslated\" color must be left undefined");
}
}
if (info.ParmLen[1] == 0 && names[0] != NAME_Untranslated)
@ -1755,7 +1860,6 @@ void V_InitFontColors ()
}
}
}
SC_Close ();
}
// Make permananent copies of all the color information we found.
for (i = 0, index = 0; i < colorinfo.Size(); ++i)

View file

@ -85,8 +85,8 @@ public:
FFont (const char *fontname, const char *nametemplate, int first, int count, int base);
~FFont ();
FTexture *GetChar (int code, int *const width) const;
int GetCharWidth (int code) const;
virtual FTexture *GetChar (int code, int *const width) const;
virtual int GetCharWidth (int code) const;
FRemapTable *GetColorTranslation (EColorRange range) const;
int GetSpaceWidth () const { return SpaceWidth; }
int GetHeight () const { return FontHeight; }
@ -101,9 +101,11 @@ public:
protected:
FFont ();
void BuildTranslations (const double *luminosity, const BYTE *identity, const void *ranges, int total_colors);
void BuildTranslations (const double *luminosity, const BYTE *identity,
const void *ranges, int total_colors, const PalEntry *palette);
static int SimpleTranslation (BYTE *colorsused, BYTE *translation, BYTE *identity, double **luminosity);
static int SimpleTranslation (BYTE *colorsused, BYTE *translation,
BYTE *identity, double **luminosity);
int FirstChar, LastChar;
int SpaceWidth;
@ -141,12 +143,26 @@ public:
protected:
void CheckFON1Chars (int lump, const BYTE *data, double *luminosity);
void BuildTranslations2 ();
void FixupPalette (BYTE *identity, double *luminosity, const BYTE *palette, bool rescale);
void FixupPalette (BYTE *identity, double *luminosity, const BYTE *palette,
bool rescale, PalEntry *out_palette);
void LoadFON1 (int lump, const BYTE *data);
void LoadFON2 (int lump, const BYTE *data);
void CreateFontFromPic (int picnum);
};
class FSinglePicFont : public FFont
{
public:
FSinglePicFont(const char *picname);
// FFont interface
FTexture *GetChar (int code, int *const width) const;
int GetCharWidth (int code) const;
protected:
int PicNum;
};
void RecordTextureColors (FTexture *pic, BYTE *colorsused);
extern FFont *SmallFont, *SmallFont2, *BigFont, *ConFont;

View file

@ -59,11 +59,11 @@ extern "C" {
FDynamicColormap NormalLight;
}
FPalette GPalette;
BYTE InverseColormap[NUMCOLORMAPS*256];
BYTE GoldColormap[NUMCOLORMAPS*256];
BYTE InverseColormap[256];
BYTE GoldColormap[256];
// [BC] New Skulltag colormaps.
BYTE RedColormap[NUMCOLORMAPS*256];
BYTE GreenColormap[NUMCOLORMAPS*256];
BYTE RedColormap[256];
BYTE GreenColormap[256];
int Near255;
static void FreeSpecialLights();;
@ -386,7 +386,7 @@ void InitPalette ()
// build special maps (e.g. invulnerability)
int intensity;
// Doom invulnerability is an inverted grayscale
// Doom invulnerability is an inverted grayscale.
// Strife uses it when firing the Sigil
shade = InverseColormap;
@ -396,10 +396,10 @@ void InitPalette ()
(GPalette.BaseColors[c].r * 77 +
GPalette.BaseColors[c].g * 143 +
GPalette.BaseColors[c].b * 37)) >> 8;
*shade++ = ColorMatcher.Pick (intensity, intensity, intensity);
shade[c] = ColorMatcher.Pick (intensity, intensity, intensity);
}
// Heretic invulnerability is a golden shade
// Heretic invulnerability is a golden shade.
shade = GoldColormap;
for (c = 0; c < 256; c++)
@ -407,7 +407,7 @@ void InitPalette ()
intensity = GPalette.BaseColors[c].r * 77 +
GPalette.BaseColors[c].g * 143 +
GPalette.BaseColors[c].b * 37;
*shade++ = ColorMatcher.Pick (
shade[c] = ColorMatcher.Pick (
MIN (255, (intensity+intensity/2)>>8), intensity>>8, 0);
}
@ -418,7 +418,7 @@ void InitPalette ()
intensity = ((GPalette.BaseColors[c].r * 77 +
GPalette.BaseColors[c].g * 143 +
GPalette.BaseColors[c].b * 37));
*shade++ = ColorMatcher.Pick (
shade[c] = ColorMatcher.Pick (
MIN( 255, ( intensity + ( intensity / 2 )) >> 8 ), 0, 0 );
}
@ -429,8 +429,10 @@ void InitPalette ()
intensity = GPalette.BaseColors[c].r * 77 +
GPalette.BaseColors[c].g * 143 +
GPalette.BaseColors[c].b * 37;
*shade++ = ColorMatcher.Pick (
MIN( 255, ( intensity + ( intensity / 2 )) >> 8 ), MIN( 255, ( intensity + ( intensity / 2 )) >> 8 ), intensity>>8 );
shade[c] = ColorMatcher.Pick (
MIN( 255, ( intensity + ( intensity / 2 )) >> 8 ),
MIN( 255, ( intensity + ( intensity / 2 )) >> 8 ),
intensity>>8 );
}
}
@ -743,7 +745,7 @@ void FDynamicColormap::BuildLights ()
}
}
else
{ // Colored light, so do the slower thing
{ // Colored light, so do the (slightly) slower thing
for (c = 0; c < 256; c++)
{
*shade++ = ColorMatcher.Pick (

View file

@ -80,11 +80,11 @@ struct FDynamicColormap
FDynamicColormap *Next;
};
extern BYTE InverseColormap[NUMCOLORMAPS*256];
extern BYTE GoldColormap[NUMCOLORMAPS*256];
extern BYTE InverseColormap[256];
extern BYTE GoldColormap[256];
// [BC] New Skulltag colormaps.
extern BYTE RedColormap[NUMCOLORMAPS*256];
extern BYTE GreenColormap[NUMCOLORMAPS*256];
extern BYTE RedColormap[256];
extern BYTE GreenColormap[256];
extern FPalette GPalette;
extern "C" {
extern FDynamicColormap NormalLight;

View file

@ -132,8 +132,9 @@ int DisplayWidth, DisplayHeight, DisplayBits;
FFont *SmallFont, *SmallFont2, *BigFont, *ConFont;
extern "C" {
DWORD *Col2RGB8_LessPrecision[65];
DWORD Col2RGB8[65][256];
DWORD *Col2RGB8_LessPrecision[65];
DWORD Col2RGB8_Inverse[65][256];
BYTE RGB32k[32][32][32];
}
@ -682,6 +683,15 @@ static void BuildTransTable (const PalEntry *palette)
}
Col2RGB8_LessPrecision[0] = Col2RGB8[0];
Col2RGB8_LessPrecision[64] = Col2RGB8[64];
// create the inverse swizzled palette
for (x = 0; x < 65; x++)
for (y = 0; y < 256; y++)
{
Col2RGB8_Inverse[x][y] = (((((255-palette[y].r)*x)>>4)<<20) |
(((255-palette[y].g)*x)>>4) |
((((255-palette[y].b)*x)>>4)<<10)) & 0x3feffbff;
}
}
//==========================================================================

View file

@ -239,7 +239,7 @@ protected:
INTBOOL keepratio;
INTBOOL masked;
INTBOOL bilinear;
ERenderStyle style;
FRenderStyle style;
};
bool ClipBox (int &left, int &top, int &width, int &height, const BYTE *&src, const int srcpitch) const;
@ -411,10 +411,35 @@ extern DFrameBuffer *screen;
EXTERN_CVAR (Float, Gamma)
// Translucency tables
extern "C" DWORD Col2RGB8[65][256];
// RGB32k is a normal R5G5B5 -> palette lookup table.
extern "C" BYTE RGB32k[32][32][32];
// Col2RGB8 is a pre-multiplied palette for color lookup. It is stored in a
// special R10B10G10 format for efficient blending computation.
// --RRRRRrrr--BBBBBbbb--GGGGGggg-- at level 64
// --------rrrr------bbbb------gggg at level 1
extern "C" DWORD Col2RGB8[65][256];
// Col2RGB8_LessPrecision is the same as Col2RGB8, but the LSB for red
// and blue are forced to zero, so if the blend overflows, it won't spill
// over into the next component's value.
// --RRRRRrrr-#BBBBBbbb-#GGGGGggg-- at level 64
// --------rrr#------bbb#------gggg at level 1
extern "C" DWORD *Col2RGB8_LessPrecision[65];
// Col2RGB8_Inverse is the same as Col2RGB8_LessPrecision, except the source
// palette has been inverted.
extern "C" DWORD Col2RGB8_Inverse[65][256];
// "Magic" numbers used during the blending:
// --000001111100000111110000011111 = 0x01f07c1f
// -0111111111011111111101111111111 = 0x3FEFFBFF
// -1000000000100000000010000000000 = 0x40100400
// ------10000000001000000000100000 = 0x40100400 >> 5
// --11111-----11111-----11111----- = 0x40100400 - (0x40100400 >> 5) aka "white"
// --111111111111111111111111111111 = 0x3FFFFFFF
// Allocates buffer screens, call before R_Init.
void V_Init ();

View file

@ -134,6 +134,7 @@ public:
~FMemLump ();
void *GetMem () { return Block.Len() == 0 ? NULL : (void *)Block.GetChars(); }
size_t GetSize () { return Block.Len(); }
FString GetString () { return Block; }
private:
FMemLump (const FString &source);

View file

@ -386,7 +386,7 @@ void WI_LoadBackground(bool isenterpic)
lnodes.Clear();
anims.Clear();
yah.Clear();
splat=NULL;
splat = NULL;
// a name with a starting '$' indicates an intermission script
if (*lumpname!='$')
@ -400,154 +400,154 @@ void WI_LoadBackground(bool isenterpic)
int lumpnum=Wads.GetNumForName(lumpname+1);
if (lumpnum>=0)
{
SC_OpenLumpNum(lumpnum,lumpname+1);
while (SC_GetString())
FScanner sc(lumpnum,lumpname+1);
while (sc.GetString())
{
memset(&an,0,sizeof(an));
int caseval=SC_MustMatchString(WI_Cmd);
int caseval = sc.MustMatchString(WI_Cmd);
switch(caseval)
{
case 0: // Background
SC_MustGetString();
texture=TexMan.CheckForTexture(sc_String, FTexture::TEX_MiscPatch,FTextureManager::TEXMAN_TryAny);
if (texture == -1) texture = TexMan.AddPatch(sc_String);
sc.MustGetString();
texture=TexMan.CheckForTexture(sc.String, FTexture::TEX_MiscPatch,FTextureManager::TEXMAN_TryAny);
if (texture == -1) texture = TexMan.AddPatch(sc.String);
break;
case 1: // Splat
SC_MustGetString();
splat=TexMan[TexMan.AddPatch(sc_String)];
sc.MustGetString();
splat=TexMan[TexMan.AddPatch(sc.String)];
break;
case 2: // Pointers
while (SC_GetString() && !sc_Crossed)
while (sc.GetString() && !sc.Crossed)
{
int v=TexMan.AddPatch(sc_String);
int v = TexMan.AddPatch(sc.String);
yah.Push(TexMan[v]);
}
if (sc_Crossed) SC_UnGet();
if (sc.Crossed) sc.UnGet();
break;
case 3: // Spots
SC_MustGetStringName("{");
while (!SC_CheckString("}"))
sc.MustGetStringName("{");
while (!sc.CheckString("}"))
{
SC_MustGetString();
strncpy(pt.level, sc_String,8);
pt.level[8]=0;
SC_MustGetNumber();
pt.x=sc_Number;
SC_MustGetNumber();
pt.y=sc_Number;
sc.MustGetString();
strncpy(pt.level, sc.String,8);
pt.level[8] = 0;
sc.MustGetNumber();
pt.x = sc.Number;
sc.MustGetNumber();
pt.y = sc.Number;
lnodes.Push(pt);
}
break;
case 4: // IfEntering
an.type=ANIM_IFENTERING;
an.type = ANIM_IFENTERING;
goto readanimation;
case 5: // IfEntering
an.type=ANIM_IFNOTENTERING;
an.type = ANIM_IFNOTENTERING;
goto readanimation;
case 6: // IfVisited
an.type=ANIM_IFVISITED;
an.type = ANIM_IFVISITED;
goto readanimation;
case 7: // IfNotVisited
an.type=ANIM_IFNOTVISITED;
an.type = ANIM_IFNOTVISITED;
goto readanimation;
case 8: // IfLeaving
an.type=ANIM_IFLEAVING;
an.type = ANIM_IFLEAVING;
goto readanimation;
case 9: // IfNotLeaving
an.type=ANIM_IFNOTLEAVING;
an.type = ANIM_IFNOTLEAVING;
goto readanimation;
case 10: // IfTravelling
an.type=ANIM_IFTRAVELLING;
SC_MustGetString();
strncpy(an.levelname2,sc_String,8);
an.levelname2[8]=0;
an.type = ANIM_IFTRAVELLING;
sc.MustGetString();
strncpy(an.levelname2, sc.String, 8);
an.levelname2[8] = 0;
goto readanimation;
case 11: // IfNotTravelling
an.type=ANIM_IFTRAVELLING;
SC_MustGetString();
strncpy(an.levelname2,sc_String,8);
an.levelname2[8]=0;
an.type = ANIM_IFTRAVELLING;
sc.MustGetString();
strncpy(an.levelname2, sc.String, 8);
an.levelname2[8] = 0;
goto readanimation;
case 14: // NoAutostartMap
noautostartmap=true;
noautostartmap = true;
break;
readanimation:
SC_MustGetString();
strncpy(an.levelname,sc_String,8);
an.levelname[8]=0;
SC_MustGetString();
caseval=SC_MustMatchString(WI_Cmd);
sc.MustGetString();
strncpy(an.levelname, sc.String, 8);
an.levelname[8] = 0;
sc.MustGetString();
caseval=sc.MustMatchString(WI_Cmd);
default:
switch (caseval)
{
case 12: // Animation
an.type |= ANIM_ALWAYS;
SC_MustGetNumber();
an.loc.x=sc_Number;
SC_MustGetNumber();
an.loc.y=sc_Number;
SC_MustGetNumber();
an.period=sc_Number;
an.nexttic = 1 + (M_Random()%an.period);
if (SC_GetString())
sc.MustGetNumber();
an.loc.x = sc.Number;
sc.MustGetNumber();
an.loc.y = sc.Number;
sc.MustGetNumber();
an.period = sc.Number;
an.nexttic = 1 + (M_Random() % an.period);
if (sc.GetString())
{
if (SC_Compare("ONCE"))
if (sc.Compare("ONCE"))
{
an.data=1;
an.data = 1;
}
else
{
SC_UnGet();
sc.UnGet();
}
}
if (!SC_CheckString("{"))
if (!sc.CheckString("{"))
{
SC_MustGetString();
an.p[an.nanims++]=TexMan[TexMan.AddPatch(sc_String)];
sc.MustGetString();
an.p[an.nanims++] = TexMan[TexMan.AddPatch(sc.String)];
}
else
{
while (!SC_CheckString("}"))
while (!sc.CheckString("}"))
{
SC_MustGetString();
if (an.nanims<MAX_ANIMATION_FRAMES) an.p[an.nanims++]=TexMan[TexMan.AddPatch(sc_String)];
sc.MustGetString();
if (an.nanims<MAX_ANIMATION_FRAMES)
an.p[an.nanims++] = TexMan[TexMan.AddPatch(sc.String)];
}
}
an.ctr=-1;
an.ctr = -1;
anims.Push(an);
break;
case 13: // Pic
an.type |= ANIM_PIC;
SC_MustGetNumber();
an.loc.x=sc_Number;
SC_MustGetNumber();
an.loc.y=sc_Number;
SC_MustGetString();
an.p[0]=TexMan[TexMan.AddPatch(sc_String)];
sc.MustGetNumber();
an.loc.x = sc.Number;
sc.MustGetNumber();
an.loc.y = sc.Number;
sc.MustGetString();
an.p[0] = TexMan[TexMan.AddPatch(sc.String)];
anims.Push(an);
break;
default:
SC_ScriptError("Unknown token %s in intermission script", sc_String);
sc.ScriptError("Unknown token %s in intermission script", sc.String);
}
}
}
SC_Close();
}
else
{

View file

@ -148,6 +148,7 @@ public:
D3DPal *Next;
IDirect3DTexture9 *Tex;
D3DCOLOR BorderColor;
bool Update();
@ -159,12 +160,12 @@ public:
enum
{
BQF_GamePalette = 1,
BQF_ShadedPalette = 2,
BQF_CustomPalette = 3,
BQF_StencilPalette = 4,
BQF_CustomPalette = 7,
BQF_Paletted = 7,
BQF_Bilinear = 8,
BQF_WrapUV = 16,
BQF_InvertSource = 32,
BQF_DisableAlphaTest= 64,
};
// Shaders for a buffered quad
@ -172,7 +173,7 @@ enum
{
BQS_PalTex,
BQS_Plain,
BQS_PlainStencil,
BQS_RedToAlpha,
BQS_ColorOnly
};
@ -231,12 +232,12 @@ D3DFB::D3DFB (int width, int height, bool fullscreen)
ScreenshotSurface = NULL;
FinalWipeScreen = NULL;
PaletteTexture = NULL;
StencilPaletteTexture = NULL;
ShadedPaletteTexture = NULL;
PalTexShader = NULL;
InvPalTexShader = NULL;
PalTexBilinearShader = NULL;
PlainShader = NULL;
PlainStencilShader = NULL;
InvPlainShader = NULL;
RedToAlphaShader = NULL;
ColorOnlyShader = NULL;
GammaFixerShader = NULL;
BurnShader = NULL;
@ -322,8 +323,8 @@ D3DFB::~D3DFB ()
// to D3D's defaults.
void D3DFB::SetInitialState()
{
D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
AlphaBlendEnabled = FALSE;
AlphaBlendOp = D3DBLENDOP_ADD;
AlphaSrcBlend = D3DBLEND(0);
AlphaDestBlend = D3DBLEND(0);
@ -332,15 +333,45 @@ void D3DFB::SetInitialState()
Texture[0] = NULL;
Texture[1] = NULL;
D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, SM14 ? D3DTADDRESS_BORDER : D3DTADDRESS_CLAMP);
D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, SM14 ? D3DTADDRESS_BORDER : D3DTADDRESS_CLAMP);
D3DDevice->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, TRUE);
SetGamma (Gamma);
NeedGammaUpdate = true;
NeedPalUpdate = true;
OldRenderTarget = NULL;
if (!Windowed && SM14)
{
// Fix for Radeon 9000, possibly other R200s: When the device is
// reset, it resets the gamma ramp, but the driver apparently keeps a
// cached copy of the ramp that it doesn't update, so when
// SetGammaRamp is called later to handle the NeedGammaUpdate flag,
// it doesn't do anything, because the gamma ramp is the same as the
// one passed in the last call, even though the visible gamma ramp
// actually has changed.
//
// So here we force the gamma ramp to something absolutely horrible and
// trust that we will be able to properly set the gamma later when
// NeedGammaUpdate is handled.
D3DGAMMARAMP ramp;
memset(&ramp, 0, sizeof(ramp));
D3DDevice->SetGammaRamp(0, 0, &ramp);
}
// Used by the inverse color shaders
float ones[4] = { 1, 1, 1, 1 };
D3DDevice->SetPixelShaderConstantF(6, ones, 1);
// D3DRS_ALPHATESTENABLE defaults to FALSE
// D3DRS_ALPHAREF defaults to 0
D3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_NOTEQUAL);
AlphaTestEnabled = FALSE;
CurBorderColor = 0;
}
void D3DFB::FillPresentParameters (D3DPRESENT_PARAMETERS *pp, bool fullscreen, bool vsync)
@ -396,15 +427,21 @@ bool D3DFB::CreateResources ()
{
return false;
}
if (FAILED(D3DDevice->CreatePixelShader (InvPalTexShader20Def, &InvPalTexShader)) &&
(SM14 = true, FAILED(D3DDevice->CreatePixelShader (InvPalTexShader14Def, &InvPalTexShader))))
{
return false;
}
if (FAILED(D3DDevice->CreatePixelShader (PlainShaderDef, &PlainShader)) ||
FAILED(D3DDevice->CreatePixelShader (PlainStencilDef, &PlainStencilShader)) ||
FAILED(D3DDevice->CreatePixelShader (InvPlainShaderDef, &InvPlainShader)) ||
FAILED(D3DDevice->CreatePixelShader (RedToAlphaDef, &RedToAlphaShader)) ||
FAILED(D3DDevice->CreatePixelShader (ColorOnlyDef, &ColorOnlyShader)))
{
return false;
}
if (FAILED(D3DDevice->CreatePixelShader (GammaFixerDef, &GammaFixerShader)))
{
Printf ("Windowed mode gamma will not work.\n");
// Printf ("Using Shader Model 1.4: Windowed mode gamma will not work.\n");
GammaFixerShader = NULL;
}
if (FAILED(D3DDevice->CreatePixelShader(PalTexBilinearDef, &PalTexBilinearShader)))
@ -413,13 +450,10 @@ bool D3DFB::CreateResources ()
}
if (FAILED(D3DDevice->CreatePixelShader (BurnShaderDef, &BurnShader)))
{
Printf ("Burn screenwipe will not work in D3D mode.\n");
BurnShader = NULL;
}
if (!CreateFBTexture() ||
!CreatePaletteTexture() ||
!CreateStencilPaletteTexture() ||
!CreateShadedPaletteTexture())
!CreatePaletteTexture())
{
return false;
}
@ -439,8 +473,6 @@ void D3DFB::ReleaseResources ()
SAFE_RELEASE( ScreenshotSurface );
SAFE_RELEASE( ScreenshotTexture );
SAFE_RELEASE( PaletteTexture );
SAFE_RELEASE( StencilPaletteTexture );
SAFE_RELEASE( ShadedPaletteTexture );
if (PalTexBilinearShader != NULL)
{
if (PalTexBilinearShader != PalTexShader)
@ -450,8 +482,10 @@ void D3DFB::ReleaseResources ()
PalTexBilinearShader = NULL;
}
SAFE_RELEASE( PalTexShader );
SAFE_RELEASE( InvPalTexShader );
SAFE_RELEASE( PlainShader );
SAFE_RELEASE( PlainStencilShader );
SAFE_RELEASE( InvPlainShader );
SAFE_RELEASE( RedToAlphaShader );
SAFE_RELEASE( ColorOnlyShader );
SAFE_RELEASE( GammaFixerShader );
SAFE_RELEASE( BurnShader );
@ -497,6 +531,7 @@ bool D3DFB::Reset ()
{
return false;
}
LOG("Device was reset\n");
if (!CreateFBTexture() || !CreateVertexes())
{
return false;
@ -578,48 +613,6 @@ bool D3DFB::CreatePaletteTexture ()
return true;
}
bool D3DFB::CreateStencilPaletteTexture()
{
// The stencil palette is a special palette where the first entry is zero alpha,
// and everything else is white with full alpha.
if (FAILED(D3DDevice->CreateTexture(256, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &StencilPaletteTexture, NULL)))
{
return false;
}
D3DLOCKED_RECT lockrect;
if (SUCCEEDED(StencilPaletteTexture->LockRect(0, &lockrect, NULL, 0)))
{
DWORD *pix = (DWORD *)lockrect.pBits;
*pix = 0;
memset(pix + 1, 0xFF, 255*4);
StencilPaletteTexture->UnlockRect(0);
}
return true;
}
bool D3DFB::CreateShadedPaletteTexture()
{
// The shaded palette is similar to the stencil palette, except each entry's
// alpha is the same as its index.
if (FAILED(D3DDevice->CreateTexture(256, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &ShadedPaletteTexture, NULL)))
{
return false;
}
D3DLOCKED_RECT lockrect;
if (SUCCEEDED(ShadedPaletteTexture->LockRect(0, &lockrect, NULL, 0)))
{
BYTE *pix = (BYTE *)lockrect.pBits;
for (int i = 0; i < 256; ++i)
{
pix[3] = i;
pix[2] = pix[1] = pix[0] = 255;
pix += 4;
}
ShadedPaletteTexture->UnlockRect(0);
}
return true;
}
bool D3DFB::CreateVertexes ()
{
VertexPos = -1;
@ -829,12 +822,12 @@ void D3DFB::Update ()
{
ramp.blue[i] = ramp.green[i] = ramp.red[i] = WORD(65535.f * powf(i / 255.f, igamma));
}
LOG("SetGammaRamp\n");
D3DDevice->SetGammaRamp(0, D3DSGR_CALIBRATE, &ramp);
}
psgamma[2] = psgamma[1] = psgamma[0] = igamma;
psgamma[3] = 1;
D3DDevice->SetPixelShaderConstantF(7, psgamma, 1);
NeedPalUpdate = true;
}
if (NeedPalUpdate)
@ -862,7 +855,7 @@ void D3DFB::Update ()
}
unclock (BlitCycles);
LOG1 ("cycles = %d\n", BlitCycles);
//LOG1 ("cycles = %d\n", BlitCycles);
Buffer = NULL;
UpdatePending = false;
@ -940,11 +933,12 @@ void D3DFB::Draw3DPart(bool copy3d)
}
SetTexture (0, FBTexture);
SetPaletteTexture(PaletteTexture, 256);
SetPaletteTexture(PaletteTexture, 256, BorderColor);
SetPixelShader(PalTexShader);
D3DDevice->SetFVF (D3DFVF_FBVERTEX);
memset(Constant, 0, sizeof(Constant));
SetAlphaBlend(FALSE);
SetAlphaBlend(D3DBLENDOP(0));
EnableAlphaTest(FALSE);
if (copy3d)
{
FBVERTEX verts[4];
@ -991,7 +985,8 @@ void D3DFB::DoWindowedGamma()
D3DDevice->SetFVF(D3DFVF_FBVERTEX);
SetTexture(0, TempRenderTexture);
SetPixelShader((Windowed && GammaFixerShader != NULL) ? GammaFixerShader : PlainShader);
SetAlphaBlend(FALSE);
SetAlphaBlend(D3DBLENDOP(0));
EnableAlphaTest(FALSE);
D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX));
OldRenderTarget->Release();
OldRenderTarget = NULL;
@ -1001,12 +996,22 @@ void D3DFB::DoWindowedGamma()
void D3DFB::UploadPalette ()
{
D3DLOCKED_RECT lockrect;
int i;
if (SUCCEEDED(PaletteTexture->LockRect (0, &lockrect, NULL, 0)))
{
BYTE *pix = (BYTE *)lockrect.pBits;
for (i = 0; i < 256; ++i, pix += 4)
int i, skipat;
// It is impossible to get the Radeon 9000 to do the proper palette
// lookup. It *will* skip at least one entry in the palette. So we
// let it and have it look at the texture border color for color 255.
// I assume that every other card based on a related graphics chipset
// is similarly affected, which basically means that all Shader Model
// 1.4 cards suffer from this problem, since they all use some variant
// of the ATI R200.
skipat = SM14 ? 256 - 8 : 256;
for (i = 0; i < skipat; ++i, pix += 4)
{
pix[0] = SourcePalette[i].b;
pix[1] = SourcePalette[i].g;
@ -1014,7 +1019,16 @@ void D3DFB::UploadPalette ()
pix[3] = (i == 0 ? 0 : 255);
// To let masked textures work, the first palette entry's alpha is 0.
}
pix += 4;
for (; i < 255; ++i, pix += 4)
{
pix[0] = SourcePalette[i].b;
pix[1] = SourcePalette[i].g;
pix[2] = SourcePalette[i].r;
pix[3] = 255;
}
PaletteTexture->UnlockRect (0);
BorderColor = D3DCOLOR_XRGB(SourcePalette[255].r, SourcePalette[255].g, SourcePalette[255].b);
}
}
@ -1296,18 +1310,17 @@ void D3DFB::DrawPackedTextures(int packnum)
BufferedQuad *quad = &QuadExtra[QuadBatchPos];
FBVERTEX *vert = &VertexData[VertexPos];
quad->Group1 = 0;
if (pack->Format == D3DFMT_L8/* && !tex->IsGray*/)
{
quad->Flags = BQF_WrapUV | BQF_GamePalette;
quad->Flags = BQF_WrapUV | BQF_GamePalette | BQF_DisableAlphaTest;
quad->ShaderNum = BQS_PalTex;
}
else
{
quad->Flags = BQF_WrapUV;
quad->Flags = BQF_WrapUV | BQF_DisableAlphaTest;
quad->ShaderNum = BQS_Plain;
}
quad->SrcBlend = 0;
quad->DestBlend = 0;
quad->Palette = NULL;
quad->Texture = pack;
@ -1956,6 +1969,9 @@ D3DPal::D3DPal(FRemapTable *remap, D3DFB *fb)
if (fb->SM14)
{
count = 256;
// If the palette isn't big enough, then we don't need to
// worry about setting the gamma ramp.
BorderColor = (remap->NumEntries >= 256 - 8) ? ~0 : 0;
}
else
{
@ -1965,6 +1981,7 @@ D3DPal::D3DPal(FRemapTable *remap, D3DFB *fb)
for (pow2count = 1; pow2count < remap->NumEntries; pow2count <<= 1)
{ }
count = pow2count;
BorderColor = 0;
}
RoundedPaletteSize = count;
if (SUCCEEDED(fb->D3DDevice->CreateTexture(count, 1, 1, 0,
@ -2013,6 +2030,7 @@ bool D3DPal::Update()
D3DLOCKED_RECT lrect;
D3DCOLOR *buff;
const PalEntry *pal;
int skipat, i;
assert(Tex != NULL);
@ -2023,12 +2041,19 @@ bool D3DPal::Update()
buff = (D3DCOLOR *)lrect.pBits;
pal = Remap->Palette;
// Should I allow the source palette to specify alpha values?
buff[0] = D3DCOLOR_ARGB(0, pal[0].r, pal[0].g, pal[0].b);
for (int i = 1; i < Remap->NumEntries; ++i)
// See explanation in UploadPalette() for skipat rationale.
skipat = MIN(Remap->NumEntries, BorderColor != 0 ? 256 - 8 : 256);
for (i = 0; i < skipat; ++i)
{
buff[i] = D3DCOLOR_XRGB(pal[i].r, pal[i].g, pal[i].b);
buff[i] = D3DCOLOR_ARGB(pal[i].a, pal[i].r, pal[i].g, pal[i].b);
}
for (++i; i < Remap->NumEntries; ++i)
{
buff[i] = D3DCOLOR_ARGB(pal[i-1].a, pal[i-1].r, pal[i-1].g, pal[i-1].b);
}
BorderColor = D3DCOLOR_ARGB(pal[i-1].a, pal[i-1].r, pal[i-1].g, pal[i-1].b);
Tex->UnlockRect(0);
return true;
}
@ -2190,7 +2215,7 @@ void D3DFB::EndLineBatch()
if (VertexPos > 0)
{
SetPixelShader(ColorOnlyShader);
SetAlphaBlend(TRUE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
SetAlphaBlend(D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
D3DDevice->SetStreamSource(0, VertexBuffer, 0, sizeof(FBVERTEX));
D3DDevice->DrawPrimitive(D3DPT_LINELIST, 0, VertexPos / 2);
}
@ -2269,7 +2294,7 @@ void D3DFB::DrawPixel(int x, int y, int palcolor, uint32 color)
};
EndBatch(); // Draw out any batched operations.
SetPixelShader(ColorOnlyShader);
SetAlphaBlend(TRUE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
SetAlphaBlend(D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
D3DDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 1, &pt, sizeof(FBVERTEX));
}
@ -2473,18 +2498,17 @@ void D3DFB::FlatFill(int left, int top, int right, int bottom, FTexture *src, bo
BufferedQuad *quad = &QuadExtra[QuadBatchPos];
FBVERTEX *vert = &VertexData[VertexPos];
quad->Group1 = 0;
if (tex->GetTexFormat() == D3DFMT_L8 && !tex->IsGray)
{
quad->Flags = BQF_WrapUV | BQF_GamePalette;
quad->Flags = BQF_WrapUV | BQF_GamePalette | BQF_DisableAlphaTest;
quad->ShaderNum = BQS_PalTex;
}
else
{
quad->Flags = BQF_WrapUV;
quad->Flags = BQF_WrapUV | BQF_DisableAlphaTest;
quad->ShaderNum = BQS_Plain;
}
quad->SrcBlend = 0;
quad->DestBlend = 0;
quad->Palette = NULL;
quad->Texture = tex->Box->Owner;
@ -2556,15 +2580,11 @@ void D3DFB::AddColorOnlyQuad(int left, int top, int width, int height, D3DCOLOR
float x = float(left) - 0.5f;
float y = float(top) - 0.5f + (GatheringWipeScreen ? 0 : LBOffset);
quad->Flags = 0;
quad->Group1 = 0;
quad->ShaderNum = BQS_ColorOnly;
if ((color & 0xFF000000) == 0xFF000000)
{
quad->SrcBlend = 0;
quad->DestBlend = 0;
}
else
if ((color & 0xFF000000) != 0xFF000000)
{
quad->BlendOp = D3DBLENDOP_ADD;
quad->SrcBlend = D3DBLEND_SRCALPHA;
quad->DestBlend = D3DBLEND_INVSRCALPHA;
}
@ -2716,48 +2736,43 @@ void D3DFB::EndQuadBatch()
// Set the palette (if one)
if ((quad->Flags & BQF_Paletted) == BQF_GamePalette)
{
SetPaletteTexture(PaletteTexture, 256);
SetPaletteTexture(PaletteTexture, 256, BorderColor);
}
else if ((quad->Flags & BQF_Paletted) == BQF_CustomPalette)
{
SetPaletteTexture(quad->Palette->Tex, quad->Palette->RoundedPaletteSize);
}
else if ((quad->Flags & BQF_Paletted) == BQF_ShadedPalette)
{
SetPaletteTexture(ShadedPaletteTexture, 256);
}
else if ((quad->Flags & BQF_Paletted) == BQF_StencilPalette)
{
SetPaletteTexture(StencilPaletteTexture, 256);
SetPaletteTexture(quad->Palette->Tex, quad->Palette->RoundedPaletteSize, quad->Palette->BorderColor);
}
// Set paletted bilinear filtering (IF IT WORKED RIGHT!)
if (quad->Flags & (BQF_Paletted | BQF_Bilinear))
if ((quad->Flags & (BQF_Paletted | BQF_Bilinear)) == (BQF_Paletted | BQF_Bilinear))
{
SetPalTexBilinearConstants(quad->Texture);
}
// Set the alpha blending
if (quad->SrcBlend != 0)
{
SetAlphaBlend(TRUE, D3DBLEND(quad->SrcBlend), D3DBLEND(quad->DestBlend));
}
else
{
SetAlphaBlend(FALSE);
}
SetAlphaBlend(D3DBLENDOP(quad->BlendOp), D3DBLEND(quad->SrcBlend), D3DBLEND(quad->DestBlend));
// Set the alpha test
EnableAlphaTest(!(quad->Flags & BQF_DisableAlphaTest));
// Set the pixel shader
if (quad->ShaderNum == BQS_PalTex)
{
SetPixelShader(!(quad->Flags & BQF_Bilinear) ? PalTexShader : PalTexBilinearShader);
if (!(quad->Flags & BQF_Bilinear))
{
SetPixelShader((quad->Flags & BQF_InvertSource) ? InvPalTexShader : PalTexShader);
}
else
{
SetPixelShader(PalTexBilinearShader);
}
}
else if (quad->ShaderNum == BQS_Plain)
{
SetPixelShader(PlainShader);
SetPixelShader((quad->Flags & BQF_InvertSource) ? InvPlainShader : PlainShader);
}
else if (quad->ShaderNum == BQS_PlainStencil)
else if (quad->ShaderNum == BQS_RedToAlpha)
{
SetPixelShader(PlainStencilShader);
SetPixelShader(RedToAlphaShader);
}
else if (quad->ShaderNum == BQS_ColorOnly)
{
@ -2825,90 +2840,80 @@ void D3DFB::EndBatch()
bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &color1, BufferedQuad &quad)
{
D3DFORMAT fmt = tex->GetTexFormat();
ERenderStyle style = parms.style;
D3DBLEND fglevel, bglevel;
FRenderStyle style = parms.style;
float alpha;
bool stencilling;
alpha = clamp<fixed_t> (parms.alpha, 0, FRACUNIT) / 65536.f;
if (style == STYLE_OptFuzzy)
if (style.Flags & STYLEF_TransSoulsAlpha)
{
style = STYLE_Translucent;
}
else if (style == STYLE_SoulTrans)
{
style = STYLE_Translucent;
alpha = transsouls;
}
// FIXME: STYLE_Fuzzy is not written
if (style == STYLE_Fuzzy)
else if (style.Flags & STYLEF_Alpha1)
{
style = STYLE_Translucent;
alpha = transsouls;
alpha = 1;
}
else
{
alpha = clamp<fixed_t> (parms.alpha, 0, FRACUNIT) / 65536.f;
}
// FIXME: Fuzz effect is not written
if (style.BlendOp == STYLEOP_FuzzOrAdd || style.BlendOp == STYLEOP_Fuzz)
{
style.BlendOp = STYLEOP_Add;
}
else if (style.BlendOp == STYLEOP_FuzzOrSub)
{
style.BlendOp = STYLEOP_Sub;
}
else if (style.BlendOp == STYLEOP_FuzzOrRevSub)
{
style.BlendOp = STYLEOP_RevSub;
}
stencilling = false;
quad.Palette = NULL;
switch (style)
switch (style.BlendOp)
{
// Special modes
case STYLE_Shaded:
if (alpha > 0)
{
color0 = 0;
color1 = parms.fillcolor | (D3DCOLOR(alpha * 255) << 24);
quad.Flags = BQF_ShadedPalette;
quad.SrcBlend = D3DBLEND_SRCALPHA;
quad.DestBlend = D3DBLEND_INVSRCALPHA;
quad.ShaderNum = BQS_PalTex;
return true;
}
return false;
// Standard modes
case STYLE_Stencil:
stencilling = true;
case STYLE_Normal:
fglevel = D3DBLEND_SRCALPHA;
bglevel = D3DBLEND_INVSRCALPHA;
alpha = 1;
break;
case STYLE_TranslucentStencil:
stencilling = true;
case STYLE_Translucent:
fglevel = D3DBLEND_SRCALPHA;
bglevel = D3DBLEND_INVSRCALPHA;
if (alpha == 0)
{
return false;
}
if (alpha == 1 && style == STYLE_Translucent)
{
style = STYLE_Normal;
}
break;
case STYLE_Add:
fglevel = D3DBLEND_SRCALPHA;
bglevel = D3DBLEND_ONE;
break;
default:
return false;
case STYLEOP_Add: quad.BlendOp = D3DBLENDOP_ADD; break;
case STYLEOP_Sub: quad.BlendOp = D3DBLENDOP_SUBTRACT; break;
case STYLEOP_RevSub: quad.BlendOp = D3DBLENDOP_REVSUBTRACT; break;
case STYLEOP_None: return false;
}
quad.SrcBlend = GetStyleAlpha(style.SrcAlpha);
quad.DestBlend = GetStyleAlpha(style.DestAlpha);
if (style.Flags & STYLEF_InvertOverlay)
{
// Only the overlay color is inverted, not the overlay alpha.
parms.colorOverlay = D3DCOLOR_ARGB(APART(parms.colorOverlay),
255 - RPART(parms.colorOverlay), 255 - GPART(parms.colorOverlay),
255 - BPART(parms.colorOverlay));
}
// Masking can only be turned off for STYLE_Normal, because it requires
// turning off the alpha blend.
if (!parms.masked && style == STYLE_Normal)
SetColorOverlay(parms.colorOverlay, alpha, color0, color1);
if (style.Flags & STYLEF_ColorIsFixed)
{
quad.SrcBlend = 0;
quad.DestBlend = 0;
SetColorOverlay(parms.colorOverlay, 1, color0, color1);
if (fmt == D3DFMT_L8 && !tex->IsGray)
if (style.Flags & STYLEF_InvertSource)
{ // Since the source color is a constant, we can invert it now
// without spending time doing it in the shader.
parms.fillcolor = D3DCOLOR_XRGB(255 - RPART(parms.fillcolor),
255 - GPART(parms.fillcolor), 255 - BPART(parms.fillcolor));
}
// Set up the color mod to replace the color from the image data.
color0 = (color0 & D3DCOLOR_RGBA(0,0,0,255)) | (parms.fillcolor & D3DCOLOR_RGBA(255,255,255,0));
color1 &= D3DCOLOR_RGBA(0,0,0,255);
if (style.Flags & STYLEF_RedIsAlpha)
{
// Note that if the source texture is paletted, the palette is ignored.
quad.Flags = 0;
quad.ShaderNum = BQS_RedToAlpha;
}
else if (fmt == D3DFMT_L8)
{
quad.Flags = BQF_GamePalette;
quad.ShaderNum = BQS_PalTex;
@ -2921,56 +2926,72 @@ bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &
}
else
{
quad.SrcBlend = fglevel;
quad.DestBlend = bglevel;
if (!stencilling)
if (style.Flags & STYLEF_RedIsAlpha)
{
if (fmt == D3DFMT_L8)
quad.Flags = 0;
quad.ShaderNum = BQS_RedToAlpha;
}
else if (fmt == D3DFMT_L8)
{
if (parms.remap != NULL)
{
if (parms.remap != NULL)
{
quad.Flags = BQF_CustomPalette;
quad.Palette = reinterpret_cast<D3DPal *>(parms.remap->GetNative());
quad.ShaderNum = BQS_PalTex;
}
else if (tex->IsGray)
{
quad.Flags = 0;
quad.ShaderNum = BQS_Plain;
}
else
{
quad.Flags = BQF_GamePalette;
quad.ShaderNum = BQS_PalTex;
}
quad.Flags = BQF_CustomPalette;
quad.Palette = reinterpret_cast<D3DPal *>(parms.remap->GetNative());
quad.ShaderNum = BQS_PalTex;
}
else
else if (tex->IsGray)
{
quad.Flags = 0;
quad.ShaderNum = BQS_Plain;
}
SetColorOverlay(parms.colorOverlay, alpha, color0, color1);
else
{
quad.Flags = BQF_GamePalette;
quad.ShaderNum = BQS_PalTex;
}
}
else
{
color0 = 0;
color1 = parms.fillcolor | (D3DCOLOR(alpha * 255) << 24);
if (fmt == D3DFMT_L8)
{
quad.Flags = BQF_StencilPalette;
quad.ShaderNum = BQS_PalTex;
}
else
{
quad.Flags = 0;
quad.ShaderNum = BQS_PlainStencil;
}
quad.Flags = 0;
quad.ShaderNum = BQS_Plain;
}
if (style.Flags & STYLEF_InvertSource)
{
quad.Flags |= BQF_InvertSource;
}
}
// For unmasked images, force the alpha from the image data to be ignored.
if (!parms.masked)
{
color0 = (color0 & D3DCOLOR_RGBA(255, 255, 255, 0)) | D3DCOLOR_COLORVALUE(0, 0, 0, alpha);
color1 &= D3DCOLOR_RGBA(255, 255, 255, 0);
// If our alpha is one and we are doing normal adding, then we can turn the blend off completely.
if (quad.BlendOp == D3DBLENDOP_ADD &&
((alpha == 1 && quad.SrcBlend == D3DBLEND_SRCALPHA) || quad.SrcBlend == D3DBLEND_ONE) &&
((alpha == 1 && quad.DestBlend == D3DBLEND_INVSRCALPHA) || quad.DestBlend == D3DBLEND_ZERO))
{
quad.BlendOp = D3DBLENDOP(0);
}
quad.Flags |= BQF_DisableAlphaTest;
}
return true;
}
D3DBLEND D3DFB::GetStyleAlpha(int type)
{
switch (type)
{
case STYLEALPHA_Zero: return D3DBLEND_ZERO;
case STYLEALPHA_One: return D3DBLEND_ONE;
case STYLEALPHA_Src: return D3DBLEND_SRCALPHA;
case STYLEALPHA_InvSrc: return D3DBLEND_INVSRCALPHA;
default: return D3DBLEND_ZERO;
}
}
void D3DFB::SetColorOverlay(DWORD color, float alpha, D3DCOLOR &color0, D3DCOLOR &color1)
{
if (APART(color) != 0)
@ -2991,9 +3012,18 @@ void D3DFB::SetColorOverlay(DWORD color, float alpha, D3DCOLOR &color0, D3DCOLOR
}
}
void D3DFB::SetAlphaBlend(BOOL enabled, D3DBLEND srcblend, D3DBLEND destblend)
void D3DFB::EnableAlphaTest(BOOL enabled)
{
if (!enabled)
if (enabled != AlphaTestEnabled)
{
AlphaTestEnabled = enabled;
D3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, enabled);
}
}
void D3DFB::SetAlphaBlend(D3DBLENDOP op, D3DBLEND srcblend, D3DBLEND destblend)
{
if (op == 0)
{ // Disable alpha blend
if (AlphaBlendEnabled)
{
@ -3011,6 +3041,11 @@ void D3DFB::SetAlphaBlend(BOOL enabled, D3DBLEND srcblend, D3DBLEND destblend)
AlphaBlendEnabled = TRUE;
D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
}
if (AlphaBlendOp != op)
{
AlphaBlendOp = op;
D3DDevice->SetRenderState(D3DRS_BLENDOP, op);
}
if (AlphaSrcBlend != srcblend)
{
AlphaSrcBlend = srcblend;
@ -3059,12 +3094,17 @@ void D3DFB::SetTexture(int tnum, IDirect3DTexture9 *texture)
CVAR(Float, pal, 0.5f, 0)
CVAR(Float, pc, 255.f, 0)
void D3DFB::SetPaletteTexture(IDirect3DTexture9 *texture, int count)
void D3DFB::SetPaletteTexture(IDirect3DTexture9 *texture, int count, D3DCOLOR border_color)
{
if (count == 256 || SM14)
if (SM14)
{
// Shader Model 1.4 only uses 256-color palettes.
SetConstant(2, pc / 256.f, pal / 256.f, 0, 0);
SetConstant(2, 1.f, 0.5f / 256.f, 0, 0);
if (border_color != 0 && CurBorderColor != border_color)
{
CurBorderColor = border_color;
D3DDevice->SetSamplerState(1, D3DSAMP_BORDERCOLOR, border_color);
}
}
else
{

View file

@ -103,6 +103,118 @@ const DWORD PalTexShader20Def[] =
0x800f0800, 0x80e40000, 0x0000ffff
};
// An inverted paletted texture shader --------------------------------------
#if HLSL_SOURCE_CODE
sampler2D Image : register(s0);
sampler1D Palette : register(s1);
float4 PaletteMod : register(c2);
float4 White : register(c6); // Preloaded with (1,1,1,0)
float4 main (float2 texCoord : TEXCOORD0, float4 Flash : COLOR0, float4 InvFlash : COLOR1) : COLOR
{
float index = tex2D (Image, texCoord).x;
index = index * PaletteMod.x + PaletteMod.y;
float4 rgb = tex1D (Palette, index);
rgb.xyz = White.xyz - rgb.xyz;
return Flash + rgb * InvFlash;
}
#elif SHADER_ASSEMBLY_CODE
//
// Generated by Microsoft (R) D3DX9 Shader Compiler 9.15.779.0000
//
// fxc paltex.ps /Tps_1_4 /LD /VnInvPalTexShader14Def /Fhinvpaltex.h
//
//
// Parameters:
//
// sampler2D Image;
// sampler1D Palette;
// float4 PaletteMod;
// float4 White;
//
//
// Registers:
//
// Name Reg Size
// ------------ ----- ----
// PaletteMod c2 1
// White c6 1
// Image s0 1
// Palette s1 1
//
ps_1_4
texld r0, t0
mad r0.xy, r0.x, c2.x, c2.y
phase
texld r1, r0
add r1.xyz, -r1, c6
mad r0, r1, v1, v0
// approximately 5 instruction slots used (2 texture, 3 arithmetic)
#endif
const DWORD InvPalTexShader14Def[] =
{
0xffff0104, 0x003ffffe, 0x42415443, 0x0000001c, 0x000000c5, 0xffff0104,
0x00000004, 0x0000001c, 0x00000100, 0x000000be, 0x0000006c, 0x00000003,
0x00000001, 0x00000074, 0x00000000, 0x00000084, 0x00010003, 0x00000001,
0x0000008c, 0x00000000, 0x0000009c, 0x00020002, 0x00020001, 0x000000a8,
0x00000000, 0x000000b8, 0x00060002, 0x00020001, 0x000000a8, 0x00000000,
0x67616d49, 0xabab0065, 0x000c0004, 0x00010001, 0x00000001, 0x00000000,
0x656c6150, 0x00657474, 0x000b0004, 0x00010001, 0x00000001, 0x00000000,
0x656c6150, 0x4d657474, 0xab00646f, 0x00030001, 0x00040001, 0x00000001,
0x00000000, 0x74696857, 0x73700065, 0x345f315f, 0x63694d00, 0x6f736f72,
0x28207466, 0x44202952, 0x39584433, 0x61685320, 0x20726564, 0x706d6f43,
0x72656c69, 0x312e3920, 0x37372e35, 0x30302e39, 0xab003030, 0x00000042,
0x800f0000, 0xb0e40000, 0x00000004, 0x80030000, 0x80000000, 0xa0000002,
0xa0550002, 0x0000fffd, 0x00000042, 0x800f0001, 0x80e40000, 0x00000002,
0x80070001, 0x81e40001, 0xa0e40006, 0x00000004, 0x800f0000, 0x80e40001,
0x90e40001, 0x90e40000, 0x0000ffff
};
#if SHADER_ASSEMBLY_CODE
ps_2_0
dcl t0.xy
dcl v0
dcl v1
dcl_2d s0
dcl_2d s1
texld r0, t0, s0
mad r0.xy, r0.x, c2.x, c2.y
texld r0, r0, s1
add r0.xyz, -r0, c6
mov r1, v1
mad r0, r0, r1, v0
mov oC0, r0
// approximately 7 instruction slots used (2 texture, 5 arithmetic)
#endif
const DWORD InvPalTexShader20Def[] =
{
0xffff0200, 0x003ffffe, 0x42415443, 0x0000001c, 0x000000c5, 0xffff0200,
0x00000004, 0x0000001c, 0x20000100, 0x000000be, 0x0000006c, 0x00000003,
0x00020001, 0x00000074, 0x00000000, 0x00000084, 0x00010003, 0x00060001,
0x0000008c, 0x00000000, 0x0000009c, 0x00020002, 0x000a0001, 0x000000a8,
0x00000000, 0x000000b8, 0x00060002, 0x001a0001, 0x000000a8, 0x00000000,
0x67616d49, 0xabab0065, 0x000c0004, 0x00010001, 0x00000001, 0x00000000,
0x656c6150, 0x00657474, 0x000b0004, 0x00010001, 0x00000001, 0x00000000,
0x656c6150, 0x4d657474, 0xab00646f, 0x00030001, 0x00040001, 0x00000001,
0x00000000, 0x74696857, 0x73700065, 0x305f325f, 0x63694d00, 0x6f736f72,
0x28207466, 0x48202952, 0x204c534c, 0x64616853, 0x43207265, 0x69706d6f,
0x2072656c, 0x39312e39, 0x3934392e, 0x3131322e, 0xabab0031, 0x0200001f,
0x80000000, 0xb0030000, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f,
0x80000000, 0x900f0001, 0x0200001f, 0x90000000, 0xa00f0800, 0x0200001f,
0x90000000, 0xa00f0801, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800,
0x04000004, 0x80030000, 0x80000000, 0xa0000002, 0xa0550002, 0x03000042,
0x800f0000, 0x80e40000, 0xa0e40801, 0x03000002, 0x80070000, 0x81e40000,
0xa0e40006, 0x02000001, 0x800f0001, 0x90e40001, 0x04000004, 0x800f0000,
0x80e40000, 0x80e40001, 0x90e40000, 0x02000001, 0x800f0800, 0x80e40000,
0x0000ffff
};
// A paletted texture shader that does bilinear filtering -------------------
#if HLSL_SOURCE_CODE
@ -293,22 +405,77 @@ const DWORD PlainShaderDef[] =
0x90e40000, 0x0000ffff
};
// A shader that uses vertex color and texture alpha ------------------------
// A shader that inverts the source's colors --------------------------------
#if HLSL_SOURCE_CODE
sampler2D Image : register(s0);
float4 White : register(c6); // Preloaded with (1,1,1,0)
float4 main (float2 texCoord : TEXCOORD0, float4 StencilColor : COLOR1) : COLOR
float4 main (float2 texCoord : TEXCOORD0, float4 Flash : COLOR0, float4 InvFlash : COLOR1) : COLOR
{
float4 color = tex2D (Image, texCoord);
color.rgb = StencilColor.rgb;
return color;
float4 rgb = tex2D (Image, texCoord);
rgb.xyz = White.xyz - rgb.xyz;
return Flash + rgb * InvFlash;
}
#elif SHADER_ASSEMBLY_CODE
//
// Generated by Microsoft (R) D3DX9 Shader Compiler 9.15.779.0000
//
// fxc plainstencil.ps /Tps_1_1 /LD /VnPlainStencilDef /Fhplainstencil.h
// fxc plain.ps /Tps_1_1 /LD /VnInvPlainShaderDef /Fhinvplain.h
//
//
// Parameters:
//
// sampler2D Image;
// float4 White;
//
//
// Registers:
//
// Name Reg Size
// ------------ ----- ----
// White c6 1
// Image s0 1
//
ps_1_1
tex t0
add t0.xyz, -t0, c6
mad r0, t0, v1, v0
// approximately 3 instruction slots used (1 texture, 2 arithmetic)
#endif
const DWORD InvPlainShaderDef[] =
{
0xffff0101, 0x002dfffe, 0x42415443, 0x0000001c, 0x0000007b, 0xffff0101,
0x00000002, 0x0000001c, 0x00000100, 0x00000074, 0x00000044, 0x00000003,
0x00000001, 0x0000004c, 0x00000000, 0x0000005c, 0x00060002, 0x00020001,
0x00000064, 0x00000000, 0x67616d49, 0xabab0065, 0x000c0004, 0x00010001,
0x00000001, 0x00000000, 0x74696857, 0xabab0065, 0x00030001, 0x00040001,
0x00000001, 0x00000000, 0x315f7370, 0x4d00315f, 0x6f726369, 0x74666f73,
0x29522820, 0x44334420, 0x53203958, 0x65646168, 0x6f432072, 0x6c69706d,
0x39207265, 0x2e35312e, 0x2e393737, 0x30303030, 0xababab00, 0x00000042,
0xb00f0000, 0x00000002, 0xb0070000, 0xb1e40000, 0xa0e40006, 0x00000004,
0x800f0000, 0xb0e40000, 0x90e40001, 0x90e40000, 0x0000ffff
};
// A shader that copies the red component to the alpha component ------------
#if HLSL_SOURCE_CODE
sampler2D Image : register(s0);
float4 main (float2 texCoord : TEXCOORD0, float4 Flash : COLOR0, float4 InvFlash : COLOR1) : COLOR
{
float4 color = tex2D (Image, texCoord);
color.a = color.r;
return Flash + color * InvFlash;
}
#elif SHADER_ASSEMBLY_CODE
//
// Generated by Microsoft (R) D3DX9 Shader Compiler 9.15.779.0000
//
// fxc redtoalpha.ps /Tps_1_4 /LD /VnRedToAlphaDef /Fhredtoalpha.h
//
//
// Parameters:
@ -323,24 +490,26 @@ float4 main (float2 texCoord : TEXCOORD0, float4 StencilColor : COLOR1) : COLOR
// Image s0 1
//
ps_1_1
tex t0
mov r0.xyz, v1
+ mov r0.w, t0.w
ps_1_4
texld r0, t0
mad r1.xyz, r0, v1, v0
+ mad r1.w, r0.x, v1.w, v0.w
mov r0, r1
// approximately 2 instruction slots used (1 texture, 1 arithmetic)
// approximately 3 instruction slots used (1 texture, 2 arithmetic)
#endif
const DWORD PlainStencilDef[] =
const DWORD RedToAlphaDef[] =
{
0xffff0101, 0x0022fffe, 0x42415443, 0x0000001c, 0x0000004f, 0xffff0101,
0xffff0104, 0x0022fffe, 0x42415443, 0x0000001c, 0x0000004f, 0xffff0104,
0x00000001, 0x0000001c, 0x00000100, 0x00000048, 0x00000030, 0x00000003,
0x00000001, 0x00000038, 0x00000000, 0x67616d49, 0xabab0065, 0x000c0004,
0x00010001, 0x00000001, 0x00000000, 0x315f7370, 0x4d00315f, 0x6f726369,
0x00010001, 0x00000001, 0x00000000, 0x315f7370, 0x4d00345f, 0x6f726369,
0x74666f73, 0x29522820, 0x44334420, 0x53203958, 0x65646168, 0x6f432072,
0x6c69706d, 0x39207265, 0x2e35312e, 0x2e393737, 0x30303030, 0xababab00,
0x00000042, 0xb00f0000, 0x00000001, 0x80070000, 0x90e40001, 0x40000001,
0x80080000, 0xb0ff0000, 0x0000ffff
0x00000042, 0x800f0000, 0xb0e40000, 0x00000004, 0x80070001, 0x80e40000,
0x90e40001, 0x90e40000, 0x40000004, 0x80080001, 0x80000000, 0x90ff0001,
0x90ff0000, 0x00000001, 0x800f0000, 0x80e40001, 0x0000ffff
};
// A shader that just returns the first color component from the vertex -----

View file

@ -303,6 +303,7 @@ bool D3DFB::WipeDo(int ticks)
}
In2D = 3;
EnableAlphaTest(FALSE);
bool done = ScreenWipe->Run(ticks, this);
DrawLetterbox();
return done;
@ -392,7 +393,7 @@ bool D3DFB::Wiper_Crossfade::Run(int ticks, D3DFB *fb)
fb->CalcFullscreenCoords(verts, false, D3DCOLOR_COLORVALUE(0,0,0,Clock / 32.f), D3DCOLOR_RGBA(255,255,255,0));
fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX);
fb->SetTexture(0, fb->FinalWipeScreen);
fb->SetAlphaBlend(TRUE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
fb->SetAlphaBlend(D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
fb->SetPixelShader(fb->PlainShader);
fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX));
@ -450,7 +451,7 @@ bool D3DFB::Wiper_Melt::Run(int ticks, D3DFB *fb)
fb->CalcFullscreenCoords(verts, false, 0, 0xFFFFFFFF);
fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX);
fb->SetTexture(0, fb->FinalWipeScreen);
fb->SetAlphaBlend(FALSE);
fb->SetAlphaBlend(D3DBLENDOP(0));
fb->SetPixelShader(fb->PlainShader);
fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX));
@ -599,11 +600,21 @@ bool D3DFB::Wiper_Burn::Run(int ticks, D3DFB *fb)
fb->D3DDevice->SetFVF(D3DFVF_BURNVERTEX);
fb->SetTexture(0, fb->FinalWipeScreen);
fb->SetTexture(1, BurnTexture);
fb->SetAlphaBlend(TRUE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
fb->SetAlphaBlend(D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
fb->SetPixelShader(fb->BurnShader);
fb->D3DDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
if (fb->SM14)
{
fb->D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
fb->D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
}
fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(BURNVERTEX));
fb->D3DDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
if (fb->SM14)
{
fb->D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
fb->D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
}
fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX);
// The fire may not always stabilize, so the wipe is forced to end

View file

@ -277,7 +277,8 @@ private:
struct
{
BYTE Flags;
BYTE ShaderNum;
BYTE ShaderNum:4;
BYTE BlendOp:4;
BYTE SrcBlend, DestBlend;
};
DWORD Group1;
@ -292,8 +293,6 @@ private:
bool CreateFBTexture();
bool CreatePaletteTexture();
bool CreateGrayPaletteTexture();
bool CreateStencilPaletteTexture();
bool CreateShadedPaletteTexture();
bool CreateVertexes();
void UploadPalette();
void FillPresentParameters (D3DPRESENT_PARAMETERS *pp, bool fullscreen, bool vsync);
@ -308,6 +307,7 @@ private:
void DrawLetterbox();
void Draw3DPart(bool copy3d);
bool SetStyle(D3DTex *tex, DCanvas::DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &color1, BufferedQuad &quad);
static D3DBLEND GetStyleAlpha(int type);
static void SetColorOverlay(DWORD color, float alpha, D3DCOLOR &color0, D3DCOLOR &color1);
void DoWindowedGamma();
void AddColorOnlyQuad(int left, int top, int width, int height, D3DCOLOR color);
@ -319,21 +319,26 @@ private:
void EndBatch();
// State
void SetAlphaBlend(BOOL enabled, D3DBLEND srcblend=D3DBLEND(0), D3DBLEND destblend=D3DBLEND(0));
void EnableAlphaTest(BOOL enabled);
void SetAlphaBlend(D3DBLENDOP op, D3DBLEND srcblend=D3DBLEND(0), D3DBLEND destblend=D3DBLEND(0));
void SetConstant(int cnum, float r, float g, float b, float a);
void SetPixelShader(IDirect3DPixelShader9 *shader);
void SetTexture(int tnum, IDirect3DTexture9 *texture);
void SetPaletteTexture(IDirect3DTexture9 *texture, int count);
void SetPaletteTexture(IDirect3DTexture9 *texture, int count, D3DCOLOR border_color);
void SetPalTexBilinearConstants(PackingTexture *texture);
BOOL AlphaTestEnabled;
BOOL AlphaBlendEnabled;
D3DBLENDOP AlphaBlendOp;
D3DBLEND AlphaSrcBlend;
D3DBLEND AlphaDestBlend;
float Constant[3][4];
D3DCOLOR CurBorderColor;
IDirect3DPixelShader9 *CurPixelShader;
IDirect3DTexture9 *Texture[2];
PalEntry SourcePalette[256];
D3DCOLOR BorderColor;
D3DCOLOR FlashColor0, FlashColor1;
PalEntry FlashColor;
int FlashAmount;
@ -361,8 +366,6 @@ private:
IDirect3DTexture9 *FBTexture;
IDirect3DTexture9 *TempRenderTexture;
IDirect3DTexture9 *PaletteTexture;
IDirect3DTexture9 *StencilPaletteTexture;
IDirect3DTexture9 *ShadedPaletteTexture;
IDirect3DTexture9 *ScreenshotTexture;
IDirect3DSurface9 *ScreenshotSurface;
@ -376,9 +379,9 @@ private:
int QuadBatchPos;
enum { BATCH_None, BATCH_Quads, BATCH_Lines } BatchType;
IDirect3DPixelShader9 *PalTexShader, *PalTexBilinearShader;
IDirect3DPixelShader9 *PlainShader;
IDirect3DPixelShader9 *PlainStencilShader;
IDirect3DPixelShader9 *PalTexShader, *PalTexBilinearShader, *InvPalTexShader;
IDirect3DPixelShader9 *PlainShader, *InvPlainShader;
IDirect3DPixelShader9 *RedToAlphaShader;
IDirect3DPixelShader9 *ColorOnlyShader;
IDirect3DPixelShader9 *GammaFixerShader;
IDirect3DPixelShader9 *BurnShader;
@ -412,6 +415,15 @@ private:
#define LOG4(x,y,z,a,b) do { if (dbg) { fprintf (dbg, x, y, z, a, b); fflush (dbg); } } while(0)
#define LOG5(x,y,z,a,b,c) do { if (dbg) { fprintf (dbg, x, y, z, a, b, c); fflush (dbg); } } while(0)
FILE *dbg;
#elif _DEBUG
#define STARTLOG
#define STOPLOG
#define LOG(x) { OutputDebugString(x); }
#define LOG1(x,y) { char poo[1024]; sprintf(poo, x, y); OutputDebugString(poo); }
#define LOG2(x,y,z) { char poo[1024]; sprintf(poo, x, y, z); OutputDebugString(poo); }
#define LOG3(x,y,z,zz) { char poo[1024]; sprintf(poo, x, y, z, zz); OutputDebugString(poo); }
#define LOG4(x,y,z,a,b) { char poo[1024]; sprintf(poo, x, y, z, a, b); OutputDebugString(poo); }
#define LOG5(x,y,z,a,b,c) { char poo[1024]; sprintf(poo, x, y, z, a, b, c); OutputDebugString(poo); }
#else
#define STARTLOG
#define STOPLOG

View file

@ -219,6 +219,7 @@ FString &FString::operator = (const char *copyStr)
{
if (copyStr == NULL || *copyStr == '\0')
{
Data()->Release();
NullString.RefCount++;
Chars = &NullString.Nothing[0];
}

View file

@ -1,4 +1,4 @@
/* Generated by re2c 0.10.5 */
/* Generated by re2c 0.12.3 on Wed Jan 23 17:40:06 2008 */
#line 1 "scanner.re"
#include <string.h>
#include <malloc.h>
@ -66,8 +66,9 @@ std:
unsigned int yyaccept = 0;
if((YYLIMIT - YYCURSOR) < 13) YYFILL(13);
(13);
yych = *YYCURSOR;
switch(yych){
switch(yych) {
case 0x09:
case 0x0B:
case 0x0C:
@ -159,7 +160,7 @@ yy2:
yy3:
#line 107 "scanner.re"
{ RET(DIVIDE); }
#line 163 "scanner.c"
#line 164 "scanner.c"
yy4:
++YYCURSOR;
if((yych = *YYCURSOR) == 'n') goto yy192;
@ -167,7 +168,7 @@ yy4:
yy5:
#line 91 "scanner.re"
{ RET(SYM); }
#line 171 "scanner.c"
#line 172 "scanner.c"
yy6:
yych = *++YYCURSOR;
if(yych == 'r') goto yy187;
@ -226,7 +227,7 @@ yy17:
yy18:
#line 94 "scanner.re"
{ RET(NUM); }
#line 230 "scanner.c"
#line 231 "scanner.c"
yy19:
yych = *++YYCURSOR;
goto yy63;
@ -240,7 +241,7 @@ yy21:
printf("unexpected character: %c\n", *s->tok);
goto std;
}
#line 244 "scanner.c"
#line 245 "scanner.c"
yy22:
++YYCURSOR;
yych = *YYCURSOR;
@ -248,62 +249,62 @@ yy22:
yy23:
#line 99 "scanner.re"
{ goto std; }
#line 252 "scanner.c"
#line 253 "scanner.c"
yy24:
++YYCURSOR;
#line 101 "scanner.re"
{ RET(OR); }
#line 257 "scanner.c"
#line 258 "scanner.c"
yy26:
++YYCURSOR;
#line 102 "scanner.re"
{ RET(XOR); }
#line 262 "scanner.c"
#line 263 "scanner.c"
yy28:
++YYCURSOR;
#line 103 "scanner.re"
{ RET(AND); }
#line 267 "scanner.c"
#line 268 "scanner.c"
yy30:
++YYCURSOR;
#line 104 "scanner.re"
{ RET(MINUS); }
#line 272 "scanner.c"
#line 273 "scanner.c"
yy32:
++YYCURSOR;
#line 105 "scanner.re"
{ RET(PLUS); }
#line 277 "scanner.c"
#line 278 "scanner.c"
yy34:
++YYCURSOR;
#line 106 "scanner.re"
{ RET(MULTIPLY); }
#line 282 "scanner.c"
#line 283 "scanner.c"
yy36:
++YYCURSOR;
#line 108 "scanner.re"
{ RET(LPAREN); }
#line 287 "scanner.c"
#line 288 "scanner.c"
yy38:
++YYCURSOR;
#line 109 "scanner.re"
{ RET(RPAREN); }
#line 292 "scanner.c"
#line 293 "scanner.c"
yy40:
++YYCURSOR;
#line 110 "scanner.re"
{ RET(COMMA); }
#line 297 "scanner.c"
#line 298 "scanner.c"
yy42:
++YYCURSOR;
#line 111 "scanner.re"
{ RET(LBRACE); }
#line 302 "scanner.c"
#line 303 "scanner.c"
yy44:
++YYCURSOR;
#line 113 "scanner.re"
{ RET(SEMICOLON); }
#line 307 "scanner.c"
#line 308 "scanner.c"
yy46:
++YYCURSOR;
#line 117 "scanner.re"
@ -312,7 +313,7 @@ yy46:
s->pos = cursor; s->line++;
goto std;
}
#line 316 "scanner.c"
#line 317 "scanner.c"
yy48:
yych = *++YYCURSOR;
goto yy21;
@ -401,7 +402,7 @@ yy55:
++YYCURSOR;
#line 97 "scanner.re"
{ RET(STRING); }
#line 405 "scanner.c"
#line 406 "scanner.c"
yy57:
++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
@ -555,7 +556,7 @@ yy71:
yy82:
#line 89 "scanner.re"
{ RET(RenderStyles); }
#line 559 "scanner.c"
#line 560 "scanner.c"
yy83:
yych = *++YYCURSOR;
if(yych != 'r') goto yy70;
@ -589,7 +590,7 @@ yy83:
yy92:
#line 88 "scanner.re"
{ RET(FirstState); }
#line 593 "scanner.c"
#line 594 "scanner.c"
yy93:
yych = *++YYCURSOR;
if(yych != 'a') goto yy70;
@ -623,7 +624,7 @@ yy93:
yy102:
#line 86 "scanner.re"
{ RET(DeathState); }
#line 627 "scanner.c"
#line 628 "scanner.c"
yy103:
yych = *++YYCURSOR;
if(yych != 'i') goto yy70;
@ -655,7 +656,7 @@ yy103:
yy111:
#line 85 "scanner.re"
{ RET(ThingBits); }
#line 659 "scanner.c"
#line 660 "scanner.c"
yy112:
yych = *++YYCURSOR;
if(yych != 'f') goto yy70;
@ -687,7 +688,7 @@ yy112:
yy120:
#line 84 "scanner.re"
{ RET(InfoNames); }
#line 691 "scanner.c"
#line 692 "scanner.c"
yy121:
yych = *++YYCURSOR;
if(yych == 'u') goto yy140;
@ -725,7 +726,7 @@ yy123:
yy130:
#line 82 "scanner.re"
{ RET(StateMap); }
#line 729 "scanner.c"
#line 730 "scanner.c"
yy131:
yych = *++YYCURSOR;
if(yych != 'w') goto yy70;
@ -757,7 +758,7 @@ yy131:
yy139:
#line 87 "scanner.re"
{ RET(SpawnState); }
#line 761 "scanner.c"
#line 762 "scanner.c"
yy140:
yych = *++YYCURSOR;
if(yych != 'n') goto yy70;
@ -785,7 +786,7 @@ yy140:
yy146:
#line 83 "scanner.re"
{ RET(SoundMap); }
#line 789 "scanner.c"
#line 790 "scanner.c"
yy147:
yych = *++YYCURSOR;
if(yych != 'd') goto yy70;
@ -817,7 +818,7 @@ yy147:
yy155:
#line 80 "scanner.re"
{ RET(CodePConv); }
#line 821 "scanner.c"
#line 822 "scanner.c"
yy156:
yych = *++YYCURSOR;
if(yych != 'g') goto yy70;
@ -860,7 +861,7 @@ yy159:
yy167:
#line 81 "scanner.re"
{ RET(OrgSprNames); }
#line 864 "scanner.c"
#line 865 "scanner.c"
yy168:
yych = *++YYCURSOR;
if(yych != 'i') goto yy70;
@ -888,7 +889,7 @@ yy168:
yy174:
#line 78 "scanner.re"
{ RET(OrgHeights); }
#line 892 "scanner.c"
#line 893 "scanner.c"
yy175:
yych = *++YYCURSOR;
if(yych != 't') goto yy70;
@ -917,7 +918,7 @@ yy175:
yy181:
#line 77 "scanner.re"
{ RET(Actions); }
#line 921 "scanner.c"
#line 922 "scanner.c"
yy182:
yych = *++YYCURSOR;
if(yych != 'i') goto yy70;
@ -941,7 +942,7 @@ yy182:
yy186:
#line 79 "scanner.re"
{ RET(ActionList); }
#line 945 "scanner.c"
#line 946 "scanner.c"
yy187:
yych = *++YYCURSOR;
if(yych != 'i') goto yy70;
@ -965,7 +966,7 @@ yy187:
yy191:
#line 76 "scanner.re"
{ RET(PRINT); }
#line 969 "scanner.c"
#line 970 "scanner.c"
yy192:
yych = *++YYCURSOR;
if(yych != 'd') goto yy70;
@ -987,7 +988,7 @@ yy192:
yy195:
#line 75 "scanner.re"
{ RET(ENDL); }
#line 991 "scanner.c"
#line 992 "scanner.c"
yy196:
++YYCURSOR;
if(YYLIMIT == YYCURSOR) YYFILL(1);
@ -998,7 +999,7 @@ yy198:
++YYCURSOR;
#line 67 "scanner.re"
{ goto comment; }
#line 1002 "scanner.c"
#line 1003 "scanner.c"
yy200:
++YYCURSOR;
#line 69 "scanner.re"
@ -1007,17 +1008,18 @@ yy200:
s->tok = s->pos = cursor; s->line++;
goto std;
}
#line 1011 "scanner.c"
#line 1012 "scanner.c"
}
#line 128 "scanner.re"
comment:
#line 1018 "scanner.c"
#line 1019 "scanner.c"
{
YYCTYPE yych;
if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
(2);
yych = *YYCURSOR;
if(yych == 0x0A) goto yy206;
if(yych != '*') goto yy208;
@ -1026,7 +1028,7 @@ comment:
yy205:
#line 139 "scanner.re"
{ goto comment; }
#line 1030 "scanner.c"
#line 1032 "scanner.c"
yy206:
++YYCURSOR;
#line 134 "scanner.re"
@ -1035,7 +1037,7 @@ yy206:
s->tok = s->pos = cursor; s->line++;
goto comment;
}
#line 1039 "scanner.c"
#line 1041 "scanner.c"
yy208:
yych = *++YYCURSOR;
goto yy205;
@ -1043,7 +1045,7 @@ yy209:
++YYCURSOR;
#line 132 "scanner.re"
{ goto std; }
#line 1047 "scanner.c"
#line 1049 "scanner.c"
}
#line 140 "scanner.re"

File diff suppressed because it is too large Load diff

View file

@ -14,6 +14,11 @@ namespace re2c
void Symbol::ClearTable()
{
for (SymbolTable::iterator it = symbol_table.begin(); it != symbol_table.end(); ++it)
{
delete it->second;
}
symbol_table.clear();
}
@ -519,7 +524,7 @@ uint Scanner::unescape(SubStr &s) const
static const char * oct = "01234567";
s.len--;
uint c;
uint c, ucb = 0;
if ((c = *s.str++) != '\\' || s.len == 0)
{
@ -582,10 +587,20 @@ uint Scanner::unescape(SubStr &s) const
if (s.str[1] == '0')
{
l++;
if (s.str[2] == '0')
if (s.str[2] == '0' || (s.str[2] == '1' && uFlag))
{
l++;
if (s.str[3] == '0')
if (uFlag) {
const char *u3 = strchr(hex, tolower(s.str[2]));
const char *u4 = strchr(hex, tolower(s.str[3]));
if (u3 && u4)
{
ucb = (uint)((u3 - hex) << 20)
+ (uint)((u4 - hex) << 16);
l++;
}
}
else if (s.str[3] == '0')
{
l++;
}
@ -636,7 +651,8 @@ uint Scanner::unescape(SubStr &s) const
uint v = (uint)((p1 - hex) << 12)
+ (uint)((p2 - hex) << 8)
+ (uint)((p3 - hex) << 4)
+ (uint)((p4 - hex));
+ (uint)((p4 - hex))
+ ucb;
if (v >= nRealChars)
{

View file

@ -29,8 +29,8 @@ std::string indent(uint ind)
static std::string space(uint this_label)
{
int nl = next_label > 9999 ? 4 : next_label > 999 ? 3 : next_label > 99 ? 2 : next_label > 9 ? 1 : 0;
int tl = this_label > 9999 ? 4 : this_label > 999 ? 3 : this_label > 99 ? 2 : this_label > 9 ? 1 : 0;
int nl = next_label > 999999 ? 6 : next_label > 99999 ? 5 : next_label > 9999 ? 4 : next_label > 999 ? 3 : next_label > 99 ? 2 : next_label > 9 ? 1 : 0;
int tl = this_label > 999999 ? 6 : this_label > 99999 ? 5 : this_label > 9999 ? 4 : this_label > 999 ? 3 : this_label > 99 ? 2 : this_label > 9 ? 1 : 0;
return std::string(std::max(1, nl - tl + 1), ' ');
}
@ -180,10 +180,7 @@ BitMap::BitMap(const Go *g, const State *x)
BitMap::~BitMap()
{
if (next)
{
delete next;
}
delete next;
}
const BitMap *BitMap::find(const Go *g, const State *x)
@ -214,18 +211,17 @@ const BitMap *BitMap::find(const State *x)
void BitMap::gen(std::ostream &o, uint ind, uint lb, uint ub)
{
BitMap *b = first;
if (b && bLastPass)
if (first && bLastPass)
{
o << indent(ind) << "static unsigned char yybm[] = {";
o << indent(ind) << "static const unsigned char " << mapCodeName["yybm"] << "[] = {";
uint c = 1, n = ub - lb;
const BitMap *cb = first;
while((b = const_cast<BitMap*>(b->next)) != NULL) {
while((cb = cb->next) != NULL) {
++c;
}
b = first;
BitMap *b = first;
uint *bm = new uint[n];
@ -291,27 +287,28 @@ void genGoTo(std::ostream &o, uint ind, const State *from, const State *to, bool
{
if (readCh && from->label + 1 != to->label)
{
o << indent(ind) << "yych = *YYCURSOR;\n";
o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ";\n";
readCh = false;
}
o << indent(ind) << "goto yy" << to->label << ";\n";
o << indent(ind) << "goto " << labelPrefix << to->label << ";\n";
vUsedLabels.insert(to->label);
}
void genIf(std::ostream &o, uint ind, const char *cmp, uint v, bool &readCh)
{
o << indent(ind) << "if(";
if (readCh)
{
o << indent(ind) << "if((yych = *YYCURSOR) ";
o << "(" << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ")";
readCh = false;
}
else
{
o << indent(ind) << "if(yych ";
o << mapCodeName["yych"];
}
o << cmp << " ";
o << " " << cmp << " ";
prtChOrHex(o, v);
o << ") ";
}
@ -323,33 +320,38 @@ static void need(std::ostream &o, uint ind, uint n, bool & readCh, bool bSetMark
if (fFlag)
{
next_fill_index++;
o << indent(ind) << "YYSETSTATE(" << fillIndex << ");\n";
o << indent(ind) << mapCodeName["YYSETSTATE"] << "(" << fillIndex << ");\n";
}
if (bUseYYFill)
{
if (n == 1)
{
o << indent(ind) << "if(YYLIMIT == YYCURSOR) YYFILL(1);\n";
o << indent(ind) << "if(" << mapCodeName["YYLIMIT"] << " == " << mapCodeName["YYCURSOR"] << ") " << mapCodeName["YYFILL"];
}
else
{
o << indent(ind) << "if((YYLIMIT - YYCURSOR) < " << n << ") YYFILL(" << n << ");\n";
}
if (bUseYYFillParam)
{
o << "(" << n << ")";
}
o << ";\n";
}
if (fFlag)
{
o << "yyFillLabel" << fillIndex << ":\n";
o << mapCodeName["yyFillLabel"] << fillIndex << ":\n";
}
if (bSetMarker)
{
o << indent(ind) << "yych = *(YYMARKER = YYCURSOR);\n";
o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*(" << mapCodeName["YYMARKER"] << " = " << mapCodeName["YYCURSOR"] << ");\n";
}
else
{
o << indent(ind) << "yych = *YYCURSOR;\n";
o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ";\n";
}
readCh = false;
}
@ -358,17 +360,17 @@ void Match::emit(std::ostream &o, uint ind, bool &readCh) const
{
if (state->link)
{
o << indent(ind) << "++YYCURSOR;\n";
o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n";
}
else if (!readAhead())
{
/* do not read next char if match */
o << indent(ind) << "++YYCURSOR;\n";
o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n";
readCh = true;
}
else
{
o << indent(ind) << "yych = *++YYCURSOR;\n";
o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n";
readCh = false;
}
@ -382,20 +384,20 @@ void Enter::emit(std::ostream &o, uint ind, bool &readCh) const
{
if (state->link)
{
o << indent(ind) << "++YYCURSOR;\n";
o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n";
if (vUsedLabels.count(label))
{
o << "yy" << label << ":\n";
o << labelPrefix << label << ":\n";
}
need(o, ind, state->depth, readCh, false);
}
else
{
/* we shouldn't need 'rule-following' protection here */
o << indent(ind) << "yych = *++YYCURSOR;\n";
o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n";
if (vUsedLabels.count(label))
{
o << "yy" << label << ":\n";
o << labelPrefix << label << ":\n";
}
readCh = false;
}
@ -412,17 +414,17 @@ void Initial::emit(std::ostream &o, uint ind, bool &readCh) const
{
if (state->link)
{
o << indent(ind) << "++YYCURSOR;\n";
o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n";
}
else
{
o << indent(ind) << "yych = *++YYCURSOR;\n";
o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n";
}
}
if (vUsedLabels.count(label))
{
o << "yy" << label << ":\n";
o << labelPrefix << label << ":\n";
}
else if (!label)
{
@ -431,7 +433,7 @@ void Initial::emit(std::ostream &o, uint ind, bool &readCh) const
if (dFlag)
{
o << indent(ind) << "YYDEBUG(" << label << ", *YYCURSOR);\n";
o << indent(ind) << mapCodeName["YYDEBUG"] << "(" << label << ", *" << mapCodeName["YYCURSOR"] << ");\n";
}
if (state->link)
@ -442,7 +444,7 @@ void Initial::emit(std::ostream &o, uint ind, bool &readCh) const
{
if (setMarker && bUsedYYMarker)
{
o << indent(ind) << "YYMARKER = YYCURSOR;\n";
o << indent(ind) << mapCodeName["YYMARKER"] << " = " << mapCodeName["YYCURSOR"] << ";\n";
}
readCh = false;
}
@ -452,14 +454,14 @@ void Save::emit(std::ostream &o, uint ind, bool &readCh) const
{
if (bUsedYYAccept)
{
o << indent(ind) << "yyaccept = " << selector << ";\n";
o << indent(ind) << mapCodeName["yyaccept"] << " = " << selector << ";\n";
}
if (state->link)
{
if (bUsedYYMarker)
{
o << indent(ind) << "YYMARKER = ++YYCURSOR;\n";
o << indent(ind) << mapCodeName["YYMARKER"] << " = ++" << mapCodeName["YYCURSOR"] << ";\n";
}
need(o, ind, state->depth, readCh, false);
}
@ -467,11 +469,11 @@ void Save::emit(std::ostream &o, uint ind, bool &readCh) const
{
if (bUsedYYMarker)
{
o << indent(ind) << "yych = *(YYMARKER = ++YYCURSOR);\n";
o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*(" << mapCodeName["YYMARKER"] << " = ++" << mapCodeName["YYCURSOR"] << ");\n";
}
else
{
o << indent(ind) << "yych = *++YYCURSOR;\n";
o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n";
}
readCh = false;
}
@ -510,7 +512,7 @@ void Accept::emitBinary(std::ostream &o, uint ind, uint l, uint r, bool &readCh)
{
uint m = (l + r) >> 1;
o << indent(ind) << "if(yyaccept <= " << m << ") {\n";
o << indent(ind) << "if(" << mapCodeName["yyaccept"] << " <= " << m << ") {\n";
emitBinary(o, ++ind, l, m, readCh);
o << indent(--ind) << "} else {\n";
emitBinary(o, ++ind, m + 1, r, readCh);
@ -527,11 +529,11 @@ void Accept::emit(std::ostream &o, uint ind, bool &readCh) const
if (mapRules.size() > 0)
{
bUsedYYMarker = true;
o << indent(ind) << "YYCURSOR = YYMARKER;\n";
o << indent(ind) << mapCodeName["YYCURSOR"] << " = " << mapCodeName["YYMARKER"] << ";\n";
if (readCh) // shouldn't be necessary, but might become at some point
{
o << indent(ind) << "yych = *YYCURSOR;\n";
o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ";\n";
readCh = false;
}
@ -542,14 +544,14 @@ void Accept::emit(std::ostream &o, uint ind, bool &readCh) const
if (gFlag && mapRules.size() >= cGotoThreshold)
{
o << indent(ind++) << "{\n";
o << indent(ind++) << "static void *yytarget[" << mapRules.size() << "] = {\n";
o << indent(ind++) << "static void *" << mapCodeName["yytarget"] << "[" << mapRules.size() << "] = {\n";
for (RuleMap::const_iterator it = mapRules.begin(); it != mapRules.end(); ++it)
{
o << indent(ind) << "&&yy" << it->second->label << ",\n";
o << indent(ind) << "&&" << labelPrefix << it->second->label << ",\n";
vUsedLabels.insert(it->second->label);
}
o << indent(--ind) << "};\n";
o << indent(ind) << "goto *yytarget[yyaccept];\n";
o << indent(ind) << "goto *" << mapCodeName["yytarget"] << "[" << mapCodeName["yyaccept"] << "];\n";
o << indent(--ind) << "}\n";
}
else if (sFlag)
@ -558,7 +560,7 @@ void Accept::emit(std::ostream &o, uint ind, bool &readCh) const
}
else
{
o << indent(ind) << "switch(yyaccept) {\n";
o << indent(ind) << "switch(" << mapCodeName["yyaccept"] << ") {\n";
for (RuleMap::const_iterator it = mapRules.begin(); it != mapRules.end(); ++it)
{
@ -588,7 +590,7 @@ void Rule::emit(std::ostream &o, uint ind, bool &) const
if (back != 0u)
{
o << indent(ind) << "YYCURSOR = YYCTXMARKER;\n";
o << indent(ind) << mapCodeName["YYCURSOR"] << " = " << mapCodeName["YYCTXMARKER"] << ";\n";
}
RuleLine rl(*rule);
@ -739,17 +741,17 @@ void Go::genSwitch(std::ostream &o, uint ind, const State *from, const State *ne
if (dFlag)
{
o << indent(ind) << "YYDEBUG(-1, yych);\n";
o << indent(ind) << mapCodeName["YYDEBUG"] << "(-1, " << mapCodeName["yych"] << ");\n";
}
if (readCh)
{
o << indent(ind) << "switch((yych = *YYCURSOR)) {\n";
o << indent(ind) << "switch((" << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ")) {\n";
readCh = false;
}
else
{
o << indent(ind) << "switch(yych){\n";
o << indent(ind) << "switch(" << mapCodeName["yych"] << ") {\n";
}
while (t != &sP[0])
@ -893,21 +895,30 @@ void Go::genBase(std::ostream &o, uint ind, const State *from, const State *next
void Go::genCpGoto(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh) const
{
const char * sYych = readCh ? "(yych = *YYCURSOR)" : "yych";
std::string sYych;
if (readCh)
{
sYych = "(" + mapCodeName["yych"] + " = " + yychConversion + "*" + mapCodeName["YYCURSOR"] + ")";
}
else
{
sYych = mapCodeName["yych"];
}
readCh = false;
if (wFlag)
{
o << indent(ind) << "if(" << sYych <<" & 0xFF00) {\n";
o << indent(ind) << "if(" << sYych <<" & ~0xFF) {\n";
genBase(o, ind+1, from, next, readCh, 1);
o << indent(ind++) << "} else {\n";
sYych = "yych";
sYych = mapCodeName["yych"];
}
else
{
o << indent(ind++) << "{\n";
}
o << indent(ind++) << "static void *yytarget[256] = {\n";
o << indent(ind++) << "static void *" << mapCodeName["yytarget"] << "[256] = {\n";
o << indent(ind);
uint ch = 0;
@ -916,7 +927,7 @@ void Go::genCpGoto(std::ostream &o, uint ind, const State *from, const State *ne
vUsedLabels.insert(span[i].to->label);
for(; ch < span[i].ub; ++ch)
{
o << "&&yy" << span[i].to->label;
o << "&&" << labelPrefix << span[i].to->label;
if (ch == 255)
{
o << "\n";
@ -934,7 +945,7 @@ void Go::genCpGoto(std::ostream &o, uint ind, const State *from, const State *ne
}
}
o << indent(--ind) << "};\n";
o << indent(ind) << "goto *yytarget[" << sYych << "];\n";
o << indent(ind) << "goto *" << mapCodeName["yytarget"] << "[" << sYych << "];\n";
o << indent(--ind) << "}\n";
}
@ -997,19 +1008,26 @@ void Go::genGoto(std::ostream &o, uint ind, const State *from, const State *next
if (to && to->isBase)
{
const BitMap *b = BitMap::find(to);
const char * sYych;
std::string sYych;
if (b && matches(b->go, b->on, this, to))
{
Go go;
go.span = new Span[nSpans];
go.unmap(this, to);
sYych = readCh ? "(yych = *YYCURSOR)" : "yych";
if (readCh)
{
sYych = "(" + mapCodeName["yych"] + " = " + yychConversion + "*" + mapCodeName["YYCURSOR"] + ")";
}
else
{
sYych = mapCodeName["yych"];
}
readCh = false;
if (wFlag)
{
o << indent(ind) << "if(" << sYych << " & 0xFF00) {\n";
sYych = "yych";
o << indent(ind) << "if(" << sYych << " & ~0xFF) {\n";
sYych = mapCodeName["yych"];
genBase(o, ind+1, from, next, readCh, 1);
o << indent(ind) << "} else ";
}
@ -1017,7 +1035,7 @@ void Go::genGoto(std::ostream &o, uint ind, const State *from, const State *next
{
o << indent(ind);
}
o << "if(yybm[" << b->i << "+" << sYych << "] & ";
o << "if(" << mapCodeName["yybm"] << "[" << b->i << "+" << sYych << "] & ";
if (yybmHexTable)
{
prtHex(o, b->m, false);
@ -1044,15 +1062,15 @@ void State::emit(std::ostream &o, uint ind, bool &readCh) const
{
if (vUsedLabels.count(label))
{
o << "yy" << label << ":\n";
o << labelPrefix << label << ":\n";
}
if (dFlag && !action->isInitial())
{
o << indent(ind) << "YYDEBUG(" << label << ", *YYCURSOR);\n";
o << indent(ind) << mapCodeName["YYDEBUG"] << "(" << label << ", *" << mapCodeName["YYCURSOR"] << ");\n";
}
if (isPreCtxt)
{
o << indent(ind) << "YYCTXMARKER = YYCURSOR + 1;\n";
o << indent(ind) << mapCodeName["YYCTXMARKER"] << " = " << mapCodeName["YYCURSOR"] << " + 1;\n";
}
action->emit(o, ind, readCh);
}
@ -1407,6 +1425,7 @@ void DFA::emit(std::ostream &o, uint ind)
if (s->go.span[i].to && !s->go.span[i].to->rule)
{
delete s->action;
s->action = NULL;
if (saves[s->rule->accept] == ~0u)
{
@ -1500,6 +1519,7 @@ void DFA::emit(std::ostream &o, uint ind)
findBaseState();
delete head->action;
head->action = NULL;
if (bFlag)
{
@ -1550,10 +1570,10 @@ void DFA::emit(std::ostream &o, uint ind)
if (!fFlag)
{
o << indent(ind) << "YYCTYPE yych;\n";
o << indent(ind) << mapCodeName["YYCTYPE"] << " " << mapCodeName["yych"] << ";\n";
if (bUsedYYAccept)
{
o << indent(ind) << "unsigned int yyaccept = 0;\n";
o << indent(ind) << "unsigned int "<< mapCodeName["yyaccept"] << " = 0;\n";
}
}
else
@ -1566,7 +1586,7 @@ void DFA::emit(std::ostream &o, uint ind)
if (vUsedLabels.count(1))
{
vUsedLabels.insert(0);
o << indent(ind) << "goto yy0;\n";
o << indent(ind) << "goto " << labelPrefix << "0;\n";
}
// Generate code
@ -1602,26 +1622,26 @@ void genGetState(std::ostream &o, uint& ind, uint start_label)
if (fFlag && !bWroteGetState)
{
vUsedLabels.insert(start_label);
o << indent(ind) << "switch(YYGETSTATE()) {\n";
o << indent(ind) << "switch(" << mapCodeName["YYGETSTATE"] << "()) {\n";
if (bUseStateAbort)
{
o << indent(ind) << "default: abort();\n";
o << indent(ind) << "case -1: goto yy" << start_label << ";\n";
o << indent(ind) << "case -1: goto " << labelPrefix << start_label << ";\n";
}
else
{
o << indent(ind) << "default: goto yy" << start_label << ";\n";
o << indent(ind) << "default: goto " << labelPrefix << start_label << ";\n";
}
for (size_t i=0; i<last_fill_index; ++i)
{
o << indent(ind) << "case " << i << ": goto yyFillLabel" << i << ";\n";
o << indent(ind) << "case " << i << ": goto " << mapCodeName["yyFillLabel"] << i << ";\n";
}
o << indent(ind) << "}\n";
if (bUseStateNext)
{
o << "yyNext:\n";
o << mapCodeName["yyNext"] << ":\n";
}
bWroteGetState = true;
}
@ -1672,46 +1692,111 @@ void Scanner::config(const Str& cfg, int num)
{
bUseYYFill = num != 0;
}
else if (cfg.to_string() == "yyfill:parameter")
{
bUseYYFillParam = num != 0;
}
else if (cfg.to_string() == "cgoto:threshold")
{
cGotoThreshold = num;
}
else if (cfg.to_string() == "yych:conversion")
{
if (num)
{
yychConversion = "(";
yychConversion += mapCodeName["YYCTYPE"];
yychConversion += ")";
}
else
{
yychConversion = "";
}
}
else
{
fatal("unrecognized configuration name or illegal integer value");
}
}
static std::set<std::string> mapVariableKeys;
static std::set<std::string> mapDefineKeys;
static std::set<std::string> mapLabelKeys;
void Scanner::config(const Str& cfg, const Str& val)
{
if (mapDefineKeys.empty())
{
mapVariableKeys.insert("variable:yyaccept");
mapVariableKeys.insert("variable:yybm");
mapVariableKeys.insert("variable:yych");
mapVariableKeys.insert("variable:yytarget");
mapDefineKeys.insert("define:YYCTXMARKER");
mapDefineKeys.insert("define:YYCTYPE");
mapDefineKeys.insert("define:YYCURSOR");
mapDefineKeys.insert("define:YYDEBUG");
mapDefineKeys.insert("define:YYFILL");
mapDefineKeys.insert("define:YYGETSTATE");
mapDefineKeys.insert("define:YYLIMIT");
mapDefineKeys.insert("define:YYMARKER");
mapDefineKeys.insert("define:YYSETSTATE");
mapLabelKeys.insert("label:yyFillLabel");
mapLabelKeys.insert("label:yyNext");
}
std::string strVal;
if (val.len >= 2 && val.str[0] == val.str[val.len-1]
&& (val.str[0] == '"' || val.str[0] == '\''))
{
SubStr tmp(val.str + 1, val.len - 2);
unescape(tmp, strVal);
}
else
{
strVal = val.to_string();
}
if (cfg.to_string() == "indent:string")
{
if (val.len >= 2 && val.str[0] == val.str[val.len-1]
&& (val.str[0] == '"' || val.str[0] == '\''))
{
SubStr tmp(val.str + 1, val.len - 2);
unescape(tmp, indString);
}
else
{
indString = val.to_string();
}
return;
indString = strVal;
}
else if (cfg.to_string() == "startlabel")
{
if (val.len >= 2 && val.str[0] == val.str[val.len-1]
&& (val.str[0] == '"' || val.str[0] == '\''))
{
SubStr tmp(val.str + 1, val.len - 2);
unescape(tmp, startLabelName);
}
else
{
startLabelName = val.to_string();
}
startLabelName = val.to_string();
bUseStartLabel = !startLabelName.empty();
}
else if (cfg.to_string() == "labelprefix")
{
labelPrefix = strVal;
}
else if (mapVariableKeys.find(cfg.to_string()) != mapVariableKeys.end())
{
if (bFirstPass && !mapCodeName.insert(
std::make_pair(cfg.to_string().substr(sizeof("variable:") - 1), strVal)
).second)
{
fatal("variable already being used and cannot be changed");
}
}
else if (mapDefineKeys.find(cfg.to_string()) != mapDefineKeys.end())
{
if (bFirstPass && !mapCodeName.insert(
std::make_pair(cfg.to_string().substr(sizeof("define:") - 1), strVal)
).second)
{
fatal("define already being used and cannot be changed");
}
}
else if (mapLabelKeys.find(cfg.to_string()) != mapLabelKeys.end())
{
if (bFirstPass && !mapCodeName.insert(
std::make_pair(cfg.to_string().substr(sizeof("label:") - 1), strVal)
).second)
{
fatal("label already being used and cannot be changed");
}
}
else
{
fatal("unrecognized configuration name or illegal string value");

33
tools/re2c/code_names.h Normal file
View file

@ -0,0 +1,33 @@
/* $Id: token.h 547 2006-05-25 13:40:35Z helly $ */
#ifndef _code_names_h
#define _code_names_h
#include <string>
#include <map>
namespace re2c
{
class CodeNames: public std::map<std::string, std::string>
{
public:
std::string& operator [] (const char * what);
};
inline std::string& CodeNames::operator [] (const char * what)
{
CodeNames::iterator it = find(std::string(what));
if (it != end())
{
return it->second;
}
else
{
return insert(std::make_pair(std::string(what), std::string(what))).first->second;
}
}
} // end namespace re2c
#endif

View file

@ -7,10 +7,6 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#define HAVE_MALLOC 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
@ -63,13 +59,13 @@
#define PACKAGE_NAME "re2c"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "re2c 0.10.5"
#define PACKAGE_STRING "re2c 0.12.3"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "re2c"
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.10.5"
#define PACKAGE_VERSION "0.12.3"
/* The size of a `char', as computed by sizeof. */
#define SIZEOF_CHAR 1
@ -87,7 +83,7 @@
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "0.10.5"
#define VERSION "0.12.3"
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
@ -98,9 +94,6 @@
/* #undef inline */
#endif
/* Define to rpl_malloc if the replacement function should be used. */
/* #undef malloc */
/* Define to `unsigned' if <sys/types.h> does not define. */
/* #undef size_t */

View file

@ -15,7 +15,7 @@ void prtChOrHex(std::ostream& o, uint c, bool useTalx)
if ((oc < 256) && isprint(oc))
{
o << '\'';
prtCh(o, oc);
prtCh(o, c);
o << '\'';
}
else
@ -28,7 +28,19 @@ void prtHex(std::ostream& o, uint c, bool useTalx)
{
int oc = (int)(re2c::wFlag || !useTalx ? c : re2c::talx[c]);
if (re2c::wFlag)
if (re2c::uFlag)
{
o << "0x"
<< hexCh(oc >> 28)
<< hexCh(oc >> 24)
<< hexCh(oc >> 20)
<< hexCh(oc >> 16)
<< hexCh(oc >> 12)
<< hexCh(oc >> 8)
<< hexCh(oc >> 4)
<< hexCh(oc);
}
else if (re2c::wFlag)
{
o << "0x"
<< hexCh(oc >> 12)
@ -92,6 +104,16 @@ void prtCh(std::ostream& o, uint c, bool useTalx)
{
o << (char) oc;
}
else if (re2c::uFlag)
{
o << "0x"
<< hexCh(oc >> 20)
<< hexCh(oc >> 16)
<< hexCh(oc >> 12)
<< hexCh(oc >> 8)
<< hexCh(oc >> 4)
<< hexCh(oc);
}
else if (re2c::wFlag)
{
o << "0x"
@ -189,6 +211,7 @@ State::State()
State::~State()
{
delete action;
delete [] kernel;
delete [] go.span;
}

View file

@ -291,6 +291,7 @@ public:
inline Action::Action(State *s) : state(s)
{
delete s->action;
s->action = this;
}

View file

@ -7,6 +7,7 @@
#include <algorithm>
#include <string>
#include "stream_lc.h"
#include "code_names.h"
namespace re2c
{
@ -21,9 +22,13 @@ extern bool fFlag;
extern bool gFlag;
extern bool iFlag;
extern bool sFlag;
extern bool uFlag;
extern bool wFlag;
extern bool bNoGenerationDate;
extern bool bSinglePass;
extern bool bFirstPass;
extern bool bLastPass;
extern bool bUsedYYAccept;
@ -32,6 +37,8 @@ extern bool bUsedYYMarker;
extern bool bUseStartLabel;
extern std::string startLabelName;
extern std::string labelPrefix;
extern std::string yychConversion;
extern uint maxFill;
extern uint next_label;
extern uint cGotoThreshold;
@ -44,6 +51,7 @@ extern bool bUseStateAbort;
extern bool bUseStateNext;
extern bool bWroteGetState;
extern bool bUseYYFill;
extern bool bUseYYFillParam;
extern uint asc2ebc[256];
extern uint ebc2asc[256];
@ -53,20 +61,12 @@ extern uint *xlat, *talx;
extern uint next_fill_index;
extern uint last_fill_index;
extern std::set<uint> vUsedLabels;
extern re2c::CodeNames mapCodeName;
extern uint nRealChars;
inline char octCh(uint c)
{
return '0' + c % 8;
}
inline char hexCh(uint c)
{
static const char * sHex = "0123456789ABCDEF";
return sHex[c & 0x0F];
}
extern char octCh(uint c);
extern char hexCh(uint c);
} // end namespace re2c

View file

@ -28,20 +28,27 @@ bool fFlag = false;
bool gFlag = false;
bool iFlag = false;
bool sFlag = false;
bool uFlag = false;
bool wFlag = false;
bool bNoGenerationDate = false;
bool bSinglePass = false;
bool bFirstPass = true;
bool bLastPass = false;
bool bUsedYYAccept = false;
bool bUsedYYMaxFill = false;
bool bUsedYYMarker = true;
bool bUseStartLabel= false;
bool bUseStateNext = false;
bool bUseYYFill = true;
bool bUseStartLabel = false;
bool bUseStateNext = false;
bool bUseYYFill = true;
bool bUseYYFillParam = true;
std::string startLabelName;
std::string labelPrefix("yy");
std::string yychConversion("");
uint maxFill = 1;
uint next_label = 0;
uint cGotoThreshold = 9;
@ -57,6 +64,10 @@ uint nRealChars = 256;
uint next_fill_index = 0;
uint last_fill_index = 0;
std::set<uint> vUsedLabels;
re2c::CodeNames mapCodeName;
free_list<RegExp*> RegExp::vFreeList;
free_list<Range*> Range::vFreeList;
using namespace std;
@ -75,10 +86,12 @@ static const mbo_opt_struct OPTIONS[] =
mbo_opt_struct('i', 0, "no-debug-info"),
mbo_opt_struct('o', 1, "output"),
mbo_opt_struct('s', 0, "nested-ifs"),
mbo_opt_struct('u', 0, "unicode"),
mbo_opt_struct('v', 0, "version"),
mbo_opt_struct('V', 0, "vernum"),
mbo_opt_struct('w', 0, "wide-chars"),
mbo_opt_struct('1', 0, "single-pass"),
mbo_opt_struct(10, 0, "no-generation-date"),
mbo_opt_struct('-', 0, NULL) /* end of args */
};
@ -113,7 +126,10 @@ static void usage()
"-s --nested-ifs Generate nested ifs for some switches. Many compilers\n"
" need this assist to generate better code.\n"
"\n"
"-u --unicode Implies -w but supports the full Unicode character set.\n"
"\n"
"-v --version Show version information.\n"
"\n"
"-V --vernum Show version as one number.\n"
"\n"
"-w --wide-chars Create a parser that supports wide chars (UCS-2). This\n"
@ -122,6 +138,9 @@ static void usage()
"-1 --single-pass Force single pass generation, this cannot be combined\n"
" with -f and disables YYMAXFILL generation prior to last\n"
" re2c block.\n"
"\n"
"--no-generation-date Suppress the date output in the generated output so that it\n"
" only shows the re2c version.\n"
;
}
@ -163,10 +182,6 @@ int main(int argc, char *argv[])
case 'f':
fFlag = true;
if (bSinglePass) {
std::cerr << "re2c: error: cannot combine -1 and -f switch\n";
return 1;
}
break;
case 'g':
@ -188,10 +203,6 @@ int main(int argc, char *argv[])
break;
case '1':
if (bFlag) {
std::cerr << "re2c: error: cannot combine -1 and -f switch\n";
return 1;
}
bSinglePass = true;
break;
@ -222,25 +233,51 @@ int main(int argc, char *argv[])
}
case 'w':
nRealChars = (1<<16);
nRealChars = (1<<16); /* 0x10000 */
sFlag = true;
wFlag = true;
break;
case 'u':
nRealChars = 0x110000; /* 17 times w-Flag */
sFlag = true;
uFlag = true;
break;
case 'h':
case '?':
default:
usage();
return 2;
case 10:
bNoGenerationDate = true;
break;
}
}
if ((bFlag || fFlag) && bSinglePass) {
std::cerr << "re2c: error: Cannot combine -1 and -b or -f switch\n";
return 1;
}
if (wFlag && eFlag)
{
usage();
std::cerr << "re2c: error: Cannot combine -e with -w or -u switch\n";
return 2;
}
else if (argc == opt_ind + 1)
if (wFlag && uFlag)
{
std::cerr << "re2c: error: Cannot combine -u with -w switch\n";
return 2;
}
if (uFlag)
{
wFlag = true;
}
if (argc == opt_ind + 1)
{
sourceFileName = argv[opt_ind];
}
@ -303,9 +340,9 @@ int main(int argc, char *argv[])
parse(null_scanner, null_dev);
next_label = 0;
next_fill_index = 0;
Symbol::ClearTable();
bWroteGetState = false;
bUsedYYMaxFill = false;
bFirstPass = false;
}
bLastPass = true;

View file

@ -81,6 +81,10 @@ int mbo_getopt(int argc, char* const *argv, const mbo_opt_struct *opts, char **o
if ((argv[*optind][0] == '-') && (argv[*optind][1] == '-'))
{
/* '--' indicates end of args if not followed by a known long option name */
if (argv[*optind][2] == '\0') {
(*optind)++;
return(EOF);
}
while (1)
{
@ -89,7 +93,7 @@ int mbo_getopt(int argc, char* const *argv, const mbo_opt_struct *opts, char **o
if (opts[opts_idx].opt_char == '-')
{
(*optind)++;
return (EOF);
return (mbo_opt_error(argc, argv, *optind - 1, optchr, OPTERRARG, show_err));
}
else if (opts[opts_idx].opt_name && !strcmp(&argv[*optind][2], opts[opts_idx].opt_name))
{
@ -98,22 +102,26 @@ int mbo_getopt(int argc, char* const *argv, const mbo_opt_struct *opts, char **o
}
optchr = 0;
dash = 1;
dash = 0;
arg_start = 2 + strlen(opts[opts_idx].opt_name);
}
if (!dash)
else
{
dash = 1;
optchr = 1;
}
if (!dash)
{
dash = 1;
optchr = 1;
}
/* Check if the guy tries to do a -: kind of flag */
if (argv[*optind][optchr] == ':')
{
dash = 0;
(*optind)++;
return (mbo_opt_error(argc, argv, *optind - 1, optchr, OPTERRCOLON, show_err));
/* Check if the guy tries to do a -: kind of flag */
if (argv[*optind][optchr] == ':')
{
dash = 0;
(*optind)++;
return (mbo_opt_error(argc, argv, *optind - 1, optchr, OPTERRCOLON, show_err));
}
arg_start = 1 + optchr;
}
if (opts_idx < 0)
@ -135,6 +143,7 @@ int mbo_getopt(int argc, char* const *argv, const mbo_opt_struct *opts, char **o
else
{
optchr++;
arg_start++;
}
return (mbo_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err));
@ -173,7 +182,7 @@ int mbo_getopt(int argc, char* const *argv, const mbo_opt_struct *opts, char **o
}
else
{
if (arg_start == 2)
if (arg_start >= 2 && !((argv[*optind][0] == '-') && (argv[*optind][1] == '-')))
{
if (!argv[*optind][optchr + 1])
{

File diff suppressed because it is too large Load diff

View file

@ -19,11 +19,6 @@ public:
static Symbol *find(const SubStr&);
static void ClearTable();
~Symbol()
{
/** \todo should we delete 're'? */
}
typedef std::map<std::string, Symbol*> SymbolTable;
protected:

View file

@ -28,7 +28,7 @@ void yyerror(const char*);
static re2c::uint accept;
static RegExp *spec;
static Scanner *in;
static Scanner *in = NULL;
/* Bison version 1.875 emits a definition that is not working
* with several g++ version. Hence we disable it here.
@ -92,14 +92,12 @@ decl : ID '=' expr ';'
{ if($1->re)
in->fatal("sym already defined");
$1->re = $3; }
| CONFIG '=' VALUE ';'
{ in->config(*$1, *$3); }
| CONFIG '=' NUMBER ';'
{ in->config(*$1, $3); }
;
decl : ID '=' expr '/'
| ID '=' expr '/'
{ in->fatal("trailing contexts are not allowed in named definitions"); }
| CONFIG '=' VALUE ';'
{ in->config(*$1, *$3); delete $1; delete $3; }
| CONFIG '=' NUMBER ';'
{ in->config(*$1, $3); delete $1; }
;
rule : expr look CODE
@ -182,7 +180,7 @@ void yyerror(const char* s)
}
int yylex(){
return in->scan();
return in ? in->scan() : 0;
}
} // end extern "C"
@ -193,9 +191,13 @@ void parse(Scanner& i, std::ostream& o)
{
in = &i;
o << "/* Generated by re2c " PACKAGE_VERSION " on ";
time_t now = time(&now);
o.write(ctime(&now), 24);
o << "/* Generated by re2c " PACKAGE_VERSION;
if (!bNoGenerationDate)
{
o << " on ";
time_t now = time(&now);
o.write(ctime(&now), 24);
}
o << " */\n";
o << sourceFileInfo;
@ -208,6 +210,11 @@ void parse(Scanner& i, std::ostream& o)
}
o << sourceFileInfo;
}
RegExp::vFreeList.clear();
Range::vFreeList.clear();
Symbol::ClearTable();
in = NULL;
}
} // end namespace re2c

View file

@ -3,6 +3,7 @@
#define _re_h
#include <iostream>
#include <set>
#include "token.h"
#include "ins.h"
#include "globals.h"
@ -10,6 +11,51 @@
namespace re2c
{
template<class _Ty>
class free_list: protected std::set<_Ty>
{
public:
typedef typename std::set<_Ty>::iterator iterator;
typedef typename std::set<_Ty>::size_type size_type;
typedef typename std::set<_Ty>::key_type key_type;
free_list(): in_clear(false)
{
}
using std::set<_Ty>::insert;
size_type erase(const key_type& key)
{
if (!in_clear)
{
return std::set<_Ty>::erase(key);
}
return 0;
}
void clear()
{
in_clear = true;
for(iterator it = this->begin(); it != this->end(); ++it)
{
delete *it;
}
std::set<_Ty>::clear();
in_clear = false;
}
~free_list()
{
clear();
}
protected:
bool in_clear;
};
typedef struct extop
{
char op;
@ -46,12 +92,18 @@ public:
Range *next;
uint lb, ub; // [lb,ub)
static free_list<Range*> vFreeList;
public:
Range(uint l, uint u) : next(NULL), lb(l), ub(u)
{ }
{
vFreeList.insert(this);
}
Range(Range &r) : next(NULL), lb(r.lb), ub(r.ub)
{ }
{
vFreeList.insert(this);
}
friend std::ostream& operator<<(std::ostream&, const Range&);
friend std::ostream& operator<<(std::ostream&, const Range*);
@ -68,12 +120,18 @@ class RegExp
public:
uint size;
static free_list<RegExp*> vFreeList;
public:
RegExp() : size(0)
{
}
virtual ~RegExp() {}
virtual ~RegExp()
{
vFreeList.erase(this);
}
virtual const char *typeOf() = 0;
RegExp *isA(const char *t)
{
@ -178,6 +236,12 @@ public:
public:
RuleOp(RegExp*, RegExp*, Token*, uint);
~RuleOp()
{
delete code;
}
const char *typeOf()
{
return type;
@ -228,6 +292,8 @@ public:
const RuleOp& op;
};
RegExp *mkAlt(RegExp*, RegExp*);
class AltOp: public RegExp
{

View file

@ -487,6 +487,10 @@
RelativePath=".\code.h"
>
</File>
<File
RelativePath=".\code_names.h"
>
</File>
<File
RelativePath=".\config_w32.h"
>

File diff suppressed because it is too large Load diff

View file

@ -28,6 +28,8 @@ private:
public:
Scanner(const char*, std::istream&, std::ostream&);
~Scanner();
int echo();
int scan();
@ -66,7 +68,7 @@ inline SubStr Scanner::token() const
inline uint Scanner::xlat(uint c) const
{
return re2c::wFlag ? c : re2c::xlat[c];
return re2c::wFlag ? c : re2c::xlat[c & 0xFF];
}
} // end namespace re2c

Some files were not shown because too many files have changed in this diff Show more