mirror of
https://github.com/ZDoom/gzdoom-last-svn.git
synced 2025-06-03 10:41:12 +00:00
- Fixed: Fog for flooding floor textures into gaps created by missing wall textures
didn't work since a parameter changes necessitated by ZDoom's render style 'enhancement'. Update to ZDoom r940: SBarInfo Update #18: - Simplified the DrawGraphic function in sbarinfo_display.cpp - Added xOffset, yOffset, and alpha to every drawing function in sbarinfo_display.cpp. So Strife popups can be handeled better and allow for other effects (translucent bars?). I'm thinking about making a struct for these five (also x and y) arguments so that the argument lists don't become a mess. - Changed DRAWIMAGE in sbarinfo_display.cpp to not use so many calls to DrawGraphic. - DrawKeyBar wasn't using screen->DrawTexture. - Added a Fade transition for popups. It takes two args fade in rate and fade out rate. Both are floats (1.0 = 1 tic to complete 0.5 = 2 tics to complete and so on). - Added a translucency arg to statusbars. 1.0 = opaque and 0.0 = invisible. - Fixed: When an instrument's envelope runs out, it does not immediately ramp to zero. Rather, it lets the remainder of the sample finish playing. - Fixed: When playing a MIDI file with EMIDI track designations to turn a track off, any ticks that had only events on the disabled track would cause the delay for that track to be thrown away, and the following notes on enabled tracks would play too soon. This could be heard quite clearly in xplasma.mid, where track 4 (FMGlass Drone 1) would interfere with the timing of tracks 13 and 14 (EP1 Melody and EP1 Echo). - Fixed: DFlashFader did some operations in its destructor that had to be moved to its Destroy method. - Fixed: Dropped weapons from dying players should not double ammo. - Fixed: When note_on() is called and another copy of the same note is already playing on the channel, it should stop it with finish_note(), not kill_note(). This can be clearly heard in the final cymbal crashes of D_DM2TTL where TiMidity cuts them off because the final cymbals are played with a velocity of 1 before the preceding cymbals have finished. (I wonder if I should be setting the self_nonexclusive flag for GUS patches to disable even this behavior, though, since gf1note.c doesn't turn off duplicate notes.) - Changed envelope handling to hopefully match the GUS player's. The most egregious mistake TiMidity makes is to treat bit 6 as an envelope enable bit. This is not what it does; every sample has an envelope. Rather, this is a "no sampled release" flag. Also, despite fiddling with the PATCH_SUSTAIN flag during instrument loading, TiMidity never actually used it. Nor did it do anything at all with the PATCH_FAST_REL flag. - Fixed: wbstartstruct's lump name fields were only 8 characters long and not properly zero-terminated when all 8 characters were used. - Fixed: Local sound sequence definitions caused a crash because a proper NULL check was missing. - Added translucent blending modes to FMultipatchTexture (not tested yet!) - Also changed all true color texture creation functions to use proper alpha values instead of inverted ones. - Changed FRemapTable so that all palette entries must contain proper alpha values. - Fixed: The F1 screen check in m_menu.cpp was missing a NULL pointer check. - Changed: The boss brain's explosions play weapons/rocklx which is an unlimited sound. This can become extremely loud. Replaced with a new sound which is just an alias to weapons/rocklx but has a limit of 4. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@98 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
parent
f303d40f1c
commit
06c40e268d
40 changed files with 825 additions and 431 deletions
155
docs/rh-log.txt
155
docs/rh-log.txt
|
@ -1,3 +1,158 @@
|
|||
April 25, 2008 (SBarInfo Update #18)
|
||||
- Simplified the DrawGraphic function in sbarinfo_display.cpp
|
||||
- Added xOffset, yOffset, and alpha to every drawing function in
|
||||
sbarinfo_display.cpp. So Strife popups can be handeled better and allow for
|
||||
other effects (translucent bars?). I'm thinking about making a struct for
|
||||
these five (also x and y) arguments so that the argument lists don't become a
|
||||
mess.
|
||||
- Changed DRAWIMAGE in sbarinfo_display.cpp to not use so many calls to
|
||||
DrawGraphic.
|
||||
- DrawKeyBar wasn't using screen->DrawTexture.
|
||||
- Added a Fade transition for popups. It takes two args fade in rate and fade
|
||||
out rate. Both are floats (1.0 = 1 tic to complete 0.5 = 2 tics to complete
|
||||
and so on).
|
||||
- Added a translucency arg to statusbars. 1.0 = opaque and 0.0 = invisible.
|
||||
|
||||
April 24, 2008
|
||||
- Fixed: When an instrument's envelope runs out, it does not immediately ramp
|
||||
to zero. Rather, it lets the remainder of the sample finish playing.
|
||||
- Fixed: When playing a MIDI file with EMIDI track designations to turn a
|
||||
track off, any ticks that had only events on the disabled track would cause
|
||||
the delay for that track to be thrown away, and the following notes on
|
||||
enabled tracks would play too soon. This could be heard quite clearly in
|
||||
xplasma.mid, where track 4 (FMGlass Drone 1) would interfere with the timing
|
||||
of tracks 13 and 14 (EP1 Melody and EP1 Echo).
|
||||
|
||||
April 24, 2008 (Changes by Graf Zahl)
|
||||
- Fixed: DFlashFader did some operations in its destructor that had to be moved
|
||||
to its Destroy method.
|
||||
- Fixed: Dropped weapons from dying players should not double ammo.
|
||||
|
||||
April 23, 2008
|
||||
- Fixed: When note_on() is called and another copy of the same note is
|
||||
already playing on the channel, it should stop it with finish_note(), not
|
||||
kill_note(). This can be clearly heard in the final cymbal crashes of
|
||||
D_DM2TTL where TiMidity cuts them off because the final cymbals are played
|
||||
with a velocity of 1 before the preceding cymbals have finished. (I wonder
|
||||
if I should be setting the self_nonexclusive flag for GUS patches to
|
||||
disable even this behavior, though, since gf1note.c doesn't turn off
|
||||
duplicate notes.)
|
||||
- Changed envelope handling to hopefully match the GUS player's. The most
|
||||
egregious mistake TiMidity makes is to treat bit 6 as an envelope enable
|
||||
bit. This is not what it does; every sample has an envelope. Rather, this
|
||||
is a "no sampled release" flag. Also, despite fiddling with the
|
||||
PATCH_SUSTAIN flag during instrument loading, TiMidity never actually
|
||||
used it. Nor did it do anything at all with the PATCH_FAST_REL flag.
|
||||
|
||||
April 23, 2008 (Changes by Graf Zahl)
|
||||
- Fixed: wbstartstruct's lump name fields were only 8 characters long
|
||||
and not properly zero-terminated when all 8 characters were used.
|
||||
- Fixed: Local sound sequence definitions caused a crash because a proper
|
||||
NULL check was missing.
|
||||
|
||||
April 22, 2008 (Changes by Graf Zahl)
|
||||
- Added translucent blending modes to FMultipatchTexture (not tested yet!)
|
||||
- Also changed all true color texture creation functions to use proper alpha
|
||||
values instead of inverted ones.
|
||||
- Changed FRemapTable so that all palette entries must contain proper alpha
|
||||
values.
|
||||
|
||||
April 21, 2008 (Changes by Graf Zahl)
|
||||
- Fixed: The F1 screen check in m_menu.cpp was missing a NULL pointer check.
|
||||
|
||||
April 20, 2008 (Changes by Graf Zahl)
|
||||
- Changed: The boss brain's explosions play weapons/rocklx which is an
|
||||
unlimited sound. This can become extremely loud. Replaced with a new
|
||||
sound which is just an alias to weapons/rocklx but has a limit of 4.
|
||||
|
||||
April 19, 2008
|
||||
- Fixed: MugShotFrame::getTexture() allocated space for the sprite name that
|
||||
it never freed. I'm not sure it's a good assumption that 9 characters is
|
||||
always long enough, either, since you can have longer file names than that
|
||||
inside a zip.
|
||||
- Fixed: DSBarInfo::DrawGem() crashed if chain or gem was NULL.
|
||||
- Fixed: Sound sequences are not thinkers, therefore they must be explicitly
|
||||
marked as roots for the GC.
|
||||
- Reduced the range that area sounds require to interpolate between 2D and
|
||||
3D panning.
|
||||
- The listener's velocity is now set at 0 for the sound engine. The player
|
||||
moves so fast that you can hear the doppler shift just by running around,
|
||||
otherwise.
|
||||
- Changed the sound code so that all sounds that start playing on a single
|
||||
tic actually start playing at the exact same sample position.
|
||||
- Added the writewave command to write the internal TiMidity's output to a
|
||||
wave file.
|
||||
- Changed the default channel velocity for MUS files from 64 to 100 to
|
||||
better match apparent MIDI practice. (Would like to know what this is
|
||||
supposed to be.)
|
||||
- Changed the mus2midi channel assignments to match the internal player's.
|
||||
- Fixed: apply_envelope_to_amp() should clamp the mix levels to 0.
|
||||
|
||||
April 18, 2008
|
||||
- Made the maximum number of TiMidity voices configurable through the
|
||||
timidity_voices cvar.
|
||||
- Added stats lines for the OPL and Timidity MIDI devices.
|
||||
- Completely changed the way TiMidity volume calculations are done. It
|
||||
should now be extremely close to the output a real GUS would produce with
|
||||
its official MIDI player (excepting where TiMidity normalizes sample
|
||||
volumes). The new equations more closely match what is specified by the DLS
|
||||
and SF2 specs (but not quite), so I presume it's also more musically
|
||||
correct than what TiMidity (and TiMidity++) do.
|
||||
|
||||
April 18, 2008 (Changes by Graf Zahl)
|
||||
- Fixed: FBlockThingsIterator didn't set the current block coordinates if
|
||||
they were outside the blockmap. This could cause extreme delays if an
|
||||
iteration started outside the valid boundaries.
|
||||
|
||||
April 17, 2008
|
||||
- Fixed: The music stream needs to zero the FMOD_REVERB_CHANNELPROPERTIES
|
||||
before sending it to Channel::getReverbProperties().
|
||||
- Fixed: The earthquake effect did not play its sound as an actual looping
|
||||
sound. I'm a bit surprised this only recently started causing problems.
|
||||
|
||||
April 17, 2008 (Changes by Graf Zahl)
|
||||
- Added Martin Howe's fixes for morphing and DECORATE function prototypes.
|
||||
- Minor fixes in texture code.
|
||||
|
||||
April 16, 2008
|
||||
- Fixed: The FMOD::System object was never released, only closed, so
|
||||
snd_reset would eventually run into the hard limit on the total number
|
||||
of FMOD::System objects that can be created concurrently (currently 15).
|
||||
- Added proper error checks to the FMOD initialization process.
|
||||
- Updated fmod_wrap.h for FMOD 4.14.
|
||||
- Set note velocity back to using a linear sounding volume curve, although
|
||||
it's now used to scale channel volume and expression, so recompute_amp()
|
||||
is still only doing one volume curve lookup.
|
||||
- Fixed: TimidityMIDIDevice caused a crash at the end of a non-looping song.
|
||||
|
||||
April 16, 2008 (Changes by Graf Zahl)
|
||||
- Made translation support for multipatch textures operational.
|
||||
|
||||
April 15, 2008
|
||||
- Added support for the GUS patch format's scale_frequency and scale_factor
|
||||
parameters. These seem to be used primarily to restrict percussion
|
||||
instruments to specific notes.
|
||||
- Changed note velocity to not use the volume curve in recompute_amp(), since
|
||||
this sounds closer to TiMidity++, although I don't believe it's correct
|
||||
MIDI behavior. Also changed expression so that it scales the channel volume
|
||||
before going through the curve.
|
||||
- Reworked load_instrument() to be less opaque.
|
||||
- Went through the TiMidity code and removed pretty much all of the SDL_mixer
|
||||
extensions. The only exception would be kill_others(), which I reworked
|
||||
into a kill_key_group() function, which should be useful for DLS
|
||||
instruments in the future.
|
||||
|
||||
April 15, 2008 (Changes by Graf Zahl)
|
||||
- Added translation support to multipatch textures. Not tested yet!
|
||||
- Added Martin Howe's morph weapon update.
|
||||
- Changed true color texture creation to use a newly defined Bitmap class
|
||||
instead of having the copy functions in the frame buffer class.
|
||||
- Fixed: The WolfSS didn't have its obituary defined.
|
||||
- Added submission for ACS CheckPlayerCamera ACS function.
|
||||
- Removed FRadiusThingsIterator after discovering that VC++ misoptimized
|
||||
it in P_CheckPosition. Now FBlockThingsIterator is used with the distance
|
||||
check being done manually.
|
||||
|
||||
April 14, 2008 (Changes by Graf Zahl)
|
||||
- Added rotation 90° angles only) and mirroring to the Multipatch texture
|
||||
composition code.
|
||||
|
|
|
@ -187,6 +187,7 @@ static void BrainishExplosion (fixed_t x, fixed_t y, fixed_t z)
|
|||
AActor *boom = Spawn("Rocket", x, y, z, NO_REPLACE);
|
||||
if (boom != NULL)
|
||||
{
|
||||
boom->DeathSound = S_FindSound("misc/brainexplode");
|
||||
boom->momz = pr_brainscream() << 9;
|
||||
boom->SetState (&ABossBrain::States[S_BRAINEXPLODE]);
|
||||
boom->effects = 0;
|
||||
|
|
|
@ -1863,6 +1863,10 @@ void G_DoCompleted (void)
|
|||
strncpy (wminfo.lname1, nextinfo->pname, 8);
|
||||
}
|
||||
}
|
||||
wminfo.next[8]=0;
|
||||
wminfo.lname0[8]=0;
|
||||
wminfo.lname1[8]=0;
|
||||
wminfo.current[8]=0;
|
||||
|
||||
CheckWarpTransMap (wminfo.next, true);
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ DFlashFader::DFlashFader (float r1, float g1, float b1, float a1,
|
|||
Blends[1][0]=r2; Blends[1][1]=g2; Blends[1][2]=b2; Blends[1][3]=a2;
|
||||
}
|
||||
|
||||
DFlashFader::~DFlashFader ()
|
||||
void DFlashFader::Destroy ()
|
||||
{
|
||||
SetBlend (1.f);
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ public:
|
|||
DFlashFader (float r1, float g1, float b1, float a1,
|
||||
float r2, float g2, float b2, float a2,
|
||||
float time, AActor *who);
|
||||
~DFlashFader ();
|
||||
void Destroy ();
|
||||
void Serialize (FArchive &arc);
|
||||
void Tick ();
|
||||
AActor *WhoFor() { return ForWho; }
|
||||
|
|
|
@ -175,8 +175,7 @@ AInventory *AWeapon::CreateCopy (AActor *other)
|
|||
//
|
||||
// A weapon that's tossed out should contain no ammo, so you can't cheat
|
||||
// by dropping it and then picking it back up.
|
||||
//
|
||||
//===========================================================================
|
||||
//=======================
|
||||
|
||||
AInventory *AWeapon::CreateTossable ()
|
||||
{
|
||||
|
|
|
@ -53,6 +53,7 @@ enum PopupTransition
|
|||
{
|
||||
TRANSITION_NONE,
|
||||
TRANSITION_SLIDEINBOTTOM,
|
||||
TRANSITION_FADE,
|
||||
};
|
||||
|
||||
struct Popup
|
||||
|
@ -63,6 +64,8 @@ struct Popup
|
|||
int height;
|
||||
int width;
|
||||
int speed;
|
||||
int speed2;
|
||||
int alpha;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
|
@ -74,6 +77,7 @@ struct Popup
|
|||
bool isDoneMoving();
|
||||
int getXOffset();
|
||||
int getYOffset();
|
||||
int getAlpha(int maxAlpha=FRACUNIT);
|
||||
};
|
||||
|
||||
//SBarInfo
|
||||
|
@ -81,6 +85,8 @@ struct SBarInfoBlock
|
|||
{
|
||||
TArray<SBarInfoCommand> commands;
|
||||
bool forceScaled;
|
||||
int alpha;
|
||||
|
||||
SBarInfoBlock();
|
||||
};
|
||||
|
||||
|
@ -372,15 +378,15 @@ public:
|
|||
void ShowPop(int popnum);
|
||||
void SetMugShotState(const char* stateName, bool waitTillDone=false);
|
||||
private:
|
||||
void doCommands(SBarInfoBlock &block, int xOffset=0, int yOffset=0);
|
||||
void DrawGraphic(FTexture* texture, int x, int y, int flags=0);
|
||||
void DrawString(const char* str, int x, int y, EColorRange translation, int spacing=0);
|
||||
void DrawNumber(int num, int len, int x, int y, EColorRange translation, int spacing=0, bool fillzeros=false);
|
||||
void DrawFace(FString &defaultFace, int accuracy, bool xdth, bool animatedgodmode, int x, int y);
|
||||
void doCommands(SBarInfoBlock &block, int xOffset=0, int yOffset=0, int alpha=FRACUNIT);
|
||||
void DrawGraphic(FTexture* texture, int x, int y, int xOffset, int yOffset, int alpha, bool translate=false, bool dim=false, bool center=false);
|
||||
void DrawString(const char* str, int x, int y, int xOffset, int yOffset, int alpha, EColorRange translation, int spacing=0);
|
||||
void DrawNumber(int num, int len, int x, int y, int xOffset, int yOffset, int alpha, EColorRange translation, int spacing=0, bool fillzeros=false);
|
||||
void DrawFace(FString &defaultFace, int accuracy, bool xdth, bool animatedgodmode, int x, int y, int xOffset, int yOffset, int alpha);
|
||||
int updateState(bool xdth, bool animatedgodmode);
|
||||
void DrawInventoryBar(int type, int num, int x, int y, bool alwaysshow,
|
||||
void DrawInventoryBar(int type, int num, int x, int y, int xOffset, int yOffset, int alpha, bool alwaysshow,
|
||||
int counterx, int countery, EColorRange translation, bool drawArtiboxes, bool noArrows, bool alwaysshowcounter);
|
||||
void DrawGem(FTexture* chain, FTexture* gem, int value, int x, int y, int padleft, int padright, int chainsize,
|
||||
void DrawGem(FTexture* chain, FTexture* gem, int value, int x, int y, int xOffset, int yOffset, int alpha, int padleft, int padright, int chainsize,
|
||||
bool wiggle, bool translate);
|
||||
FRemapTable* getTranslation();
|
||||
|
||||
|
|
|
@ -310,22 +310,25 @@ void DSBarInfo::Draw (EHudState state)
|
|||
SetScaled(true);
|
||||
setsizeneeded = true;
|
||||
}
|
||||
doCommands(SBarInfoScript->huds[hud]);
|
||||
doCommands(SBarInfoScript->huds[hud], 0, 0, SBarInfoScript->huds[hud].alpha);
|
||||
if(CPlayer->inventorytics > 0 && !(level.flags & LEVEL_NOINVENTORYBAR))
|
||||
{
|
||||
if(state == HUD_StatusBar)
|
||||
doCommands(SBarInfoScript->huds[STBAR_INVENTORY]);
|
||||
doCommands(SBarInfoScript->huds[STBAR_INVENTORY], 0, 0, SBarInfoScript->huds[STBAR_INVENTORY].alpha);
|
||||
else if(state == HUD_Fullscreen)
|
||||
doCommands(SBarInfoScript->huds[STBAR_INVENTORYFULLSCREEN]);
|
||||
doCommands(SBarInfoScript->huds[STBAR_INVENTORYFULLSCREEN], 0, 0, SBarInfoScript->huds[STBAR_INVENTORYFULLSCREEN].alpha);
|
||||
}
|
||||
if(currentPopup != POP_None)
|
||||
{
|
||||
int popbar = 0;
|
||||
if(currentPopup == POP_Log)
|
||||
doCommands(SBarInfoScript->huds[STBAR_POPUPLOG], SBarInfoScript->popups[currentPopup].getXOffset(), SBarInfoScript->popups[currentPopup].getYOffset());
|
||||
popbar = STBAR_POPUPLOG;
|
||||
else if(currentPopup == POP_Keys)
|
||||
doCommands(SBarInfoScript->huds[STBAR_POPUPKEYS], SBarInfoScript->popups[currentPopup].getXOffset(), SBarInfoScript->popups[currentPopup].getYOffset());
|
||||
popbar = STBAR_POPUPKEYS;
|
||||
else if(currentPopup == POP_Status)
|
||||
doCommands(SBarInfoScript->huds[STBAR_POPUPSTATUS], SBarInfoScript->popups[currentPopup].getXOffset(), SBarInfoScript->popups[currentPopup].getYOffset());
|
||||
popbar = STBAR_POPUPSTATUS;
|
||||
doCommands(SBarInfoScript->huds[popbar], SBarInfoScript->popups[currentPopup].getXOffset(), SBarInfoScript->popups[currentPopup].getYOffset(),
|
||||
SBarInfoScript->popups[currentPopup].getAlpha(SBarInfoScript->huds[popbar].alpha));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -469,7 +472,7 @@ void DSBarInfo::SetMugShotState(const char* stateName, bool waitTillDone)
|
|||
}
|
||||
}
|
||||
|
||||
void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
||||
void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int alpha)
|
||||
{
|
||||
//prepare ammo counts
|
||||
AAmmo *ammo1, *ammo2;
|
||||
|
@ -489,8 +492,6 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
for(unsigned int i = 0;i < block.commands.Size();i++)
|
||||
{
|
||||
SBarInfoCommand& cmd = block.commands[i];
|
||||
cmd.x += xOffset;
|
||||
cmd.y += yOffset;
|
||||
switch(cmd.type) //read and execute all the commands
|
||||
{
|
||||
case SBARINFO_DRAWSWITCHABLEIMAGE: //draw the alt image if we don't have the item else this is like a normal drawimage
|
||||
|
@ -545,49 +546,50 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
if(drawAlt != 0) //draw 'off' image
|
||||
{
|
||||
if(cmd.special != -1 && drawAlt == 1)
|
||||
DrawGraphic(Images[cmd.special], cmd.x, cmd.y, cmd.flags);
|
||||
DrawGraphic(Images[cmd.special], cmd.x, cmd.y, xOffset, yOffset, alpha, !!(cmd.flags & DRAWIMAGE_TRANSLATABLE), false, !!(cmd.flags & DRAWIMAGE_OFFSET_CENTER));
|
||||
else if(cmd.special2 != -1 && drawAlt == 2)
|
||||
DrawGraphic(Images[cmd.special2], cmd.x, cmd.y, cmd.flags);
|
||||
DrawGraphic(Images[cmd.special2], cmd.x, cmd.y, xOffset, yOffset, alpha, !!(cmd.flags & DRAWIMAGE_TRANSLATABLE), false, !!(cmd.flags & DRAWIMAGE_OFFSET_CENTER));
|
||||
else if(cmd.special3 != -1 && drawAlt == 3)
|
||||
DrawGraphic(Images[cmd.special3], cmd.x, cmd.y, cmd.flags);
|
||||
DrawGraphic(Images[cmd.special3], cmd.x, cmd.y, xOffset, yOffset, alpha, !!(cmd.flags & DRAWIMAGE_TRANSLATABLE), false, !!(cmd.flags & DRAWIMAGE_OFFSET_CENTER));
|
||||
break;
|
||||
}
|
||||
}
|
||||
case SBARINFO_DRAWIMAGE:
|
||||
{
|
||||
FTexture *texture = NULL;
|
||||
if((cmd.flags & DRAWIMAGE_PLAYERICON))
|
||||
DrawGraphic(TexMan[CPlayer->mo->ScoreIcon], cmd.x, cmd.y, cmd.flags);
|
||||
texture = TexMan[CPlayer->mo->ScoreIcon];
|
||||
else if((cmd.flags & DRAWIMAGE_AMMO1))
|
||||
{
|
||||
if(ammo1 != NULL)
|
||||
DrawGraphic(TexMan[ammo1->Icon], cmd.x, cmd.y, cmd.flags);
|
||||
texture = TexMan[ammo1->Icon];
|
||||
}
|
||||
else if((cmd.flags & DRAWIMAGE_AMMO2))
|
||||
{
|
||||
if(ammo2 != NULL)
|
||||
DrawGraphic(TexMan[ammo2->Icon], cmd.x, cmd.y, cmd.flags);
|
||||
texture = TexMan[ammo2->Icon];
|
||||
}
|
||||
else if((cmd.flags & DRAWIMAGE_ARMOR))
|
||||
{
|
||||
if(armor != NULL && armor->Amount != 0)
|
||||
DrawGraphic(TexMan(armor->Icon), cmd.x, cmd.y, cmd.flags);
|
||||
texture = TexMan(armor->Icon);
|
||||
}
|
||||
else if((cmd.flags & DRAWIMAGE_WEAPONICON))
|
||||
{
|
||||
AWeapon *weapon = CPlayer->ReadyWeapon;
|
||||
if(weapon != NULL && weapon->Icon > 0)
|
||||
{
|
||||
DrawGraphic(TexMan[weapon->Icon], cmd.x, cmd.y, cmd.flags);
|
||||
texture = TexMan[weapon->Icon];
|
||||
}
|
||||
}
|
||||
else if((cmd.flags & DRAWIMAGE_INVENTORYICON))
|
||||
{
|
||||
DrawGraphic(TexMan[cmd.sprite], cmd.x, cmd.y, cmd.flags);
|
||||
}
|
||||
texture = TexMan[cmd.sprite];
|
||||
else if(cmd.sprite != -1)
|
||||
{
|
||||
DrawGraphic(Images[cmd.sprite], cmd.x, cmd.y, cmd.flags);
|
||||
}
|
||||
texture = Images[cmd.sprite];
|
||||
|
||||
DrawGraphic(texture, cmd.x, cmd.y, xOffset, yOffset, alpha, !!(cmd.flags & DRAWIMAGE_TRANSLATABLE), false, !!(cmd.flags & DRAWIMAGE_OFFSET_CENTER));
|
||||
break;
|
||||
}
|
||||
case SBARINFO_DRAWNUMBER:
|
||||
{
|
||||
int value = cmd.value;
|
||||
|
@ -695,12 +697,12 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
}
|
||||
}
|
||||
bool fillzeros = !!(cmd.flags & DRAWNUMBER_FILLZEROS);
|
||||
EColorRange translation = cmd.translation;
|
||||
if(cmd.special3 != -1 && value <= cmd.special3) //low
|
||||
DrawNumber(value, cmd.special, cmd.x, cmd.y, cmd.translation2, cmd.special2, fillzeros);
|
||||
translation = cmd.translation2;
|
||||
else if(cmd.special4 != -1 && value >= cmd.special4) //high
|
||||
DrawNumber(value, cmd.special, cmd.x, cmd.y, cmd.translation3, cmd.special2, fillzeros);
|
||||
else
|
||||
DrawNumber(value, cmd.special, cmd.x, cmd.y, cmd.translation, cmd.special2, fillzeros);
|
||||
translation = cmd.translation3;
|
||||
DrawNumber(value, cmd.special, cmd.x, cmd.y, xOffset, yOffset, alpha, translation, cmd.special2, fillzeros);
|
||||
break;
|
||||
}
|
||||
case SBARINFO_DRAWMUGSHOT:
|
||||
|
@ -711,7 +713,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
xdth = true;
|
||||
if(cmd.flags & DRAWMUGSHOT_ANIMATEDGODMODE)
|
||||
animatedgodmode = true;
|
||||
DrawFace(cmd.string[0], cmd.special, xdth, animatedgodmode, cmd.x, cmd.y);
|
||||
DrawFace(cmd.string[0], cmd.special, xdth, animatedgodmode, cmd.x, cmd.y, xOffset, yOffset, alpha);
|
||||
break;
|
||||
}
|
||||
case SBARINFO_DRAWSELECTEDINVENTORY:
|
||||
|
@ -719,11 +721,11 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
{
|
||||
if((cmd.flags & DRAWSELECTEDINVENTORY_ARTIFLASH) && artiflash)
|
||||
{
|
||||
DrawDimImage(Images[ARTIFLASH_OFFSET+(4-artiflash)], cmd.x, cmd.y, CPlayer->mo->InvSel->Amount <= 0);
|
||||
DrawGraphic(Images[ARTIFLASH_OFFSET+(4-artiflash)], cmd.x, cmd.y, xOffset, yOffset, alpha, false, CPlayer->mo->InvSel->Amount <= 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawDimImage(TexMan(CPlayer->mo->InvSel->Icon), cmd.x, cmd.y, CPlayer->mo->InvSel->Amount <= 0);
|
||||
DrawGraphic(TexMan(CPlayer->mo->InvSel->Icon), cmd.x, cmd.y, xOffset, yOffset, alpha, false, CPlayer->mo->InvSel->Amount <= 0);
|
||||
}
|
||||
if((cmd.flags & DRAWSELECTEDINVENTORY_ALWAYSSHOWCOUNTER) || CPlayer->mo->InvSel->Amount != 1)
|
||||
{
|
||||
|
@ -731,12 +733,12 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
{
|
||||
drawingFont = cmd.font;
|
||||
}
|
||||
DrawNumber(CPlayer->mo->InvSel->Amount, 3, cmd.special2, cmd.special3, cmd.translation, cmd.special4);
|
||||
DrawNumber(CPlayer->mo->InvSel->Amount, 3, cmd.special2, cmd.special3, xOffset, yOffset, alpha, cmd.translation, cmd.special4);
|
||||
}
|
||||
}
|
||||
else if((cmd.flags & DRAWSELECTEDINVENTORY_ALTERNATEONEMPTY))
|
||||
{
|
||||
doCommands(cmd.subBlock, xOffset, yOffset);
|
||||
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
||||
}
|
||||
break;
|
||||
case SBARINFO_DRAWINVENTORYBAR:
|
||||
|
@ -757,7 +759,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
{
|
||||
drawingFont = cmd.font;
|
||||
}
|
||||
DrawInventoryBar(cmd.special, cmd.value, cmd.x, cmd.y, alwaysshow, cmd.special2, cmd.special3, cmd.translation, artibox, noarrows, alwaysshowcounter);
|
||||
DrawInventoryBar(cmd.special, cmd.value, cmd.x, cmd.y, xOffset, yOffset, alpha, alwaysshow, cmd.special2, cmd.special3, cmd.translation, artibox, noarrows, alwaysshowcounter);
|
||||
break;
|
||||
}
|
||||
case SBARINFO_DRAWBAR:
|
||||
|
@ -905,8 +907,8 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
int cx, cy, cw, ch, cr, cb;
|
||||
|
||||
// Calc real screen coordinates for bar
|
||||
x = cmd.x + ST_X;
|
||||
y = cmd.y + ST_Y;
|
||||
x = cmd.x + ST_X + xOffset;
|
||||
y = cmd.y + ST_Y + yOffset;
|
||||
w = fg->GetScaledWidth();
|
||||
h = fg->GetScaledHeight();
|
||||
if (Scaled)
|
||||
|
@ -920,6 +922,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
screen->DrawTexture(fg, x, y,
|
||||
DTA_DestWidth, w,
|
||||
DTA_DestHeight, h,
|
||||
DTA_Alpha, alpha,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
|
@ -930,6 +933,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
screen->DrawTexture(bg, x, y,
|
||||
DTA_DestWidth, w,
|
||||
DTA_DestHeight, h,
|
||||
DTA_Alpha, alpha,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
|
@ -939,8 +943,8 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
}
|
||||
|
||||
// Calc clipping rect for background
|
||||
cx = cmd.x + ST_X + cmd.special3;
|
||||
cy = cmd.y + ST_Y + cmd.special3;
|
||||
cx = cmd.x + ST_X + cmd.special3 + xOffset;
|
||||
cy = cmd.y + ST_Y + cmd.special3 + yOffset;
|
||||
cw = fg->GetScaledWidth() - fg->GetScaledLeftOffset() - cmd.special3 * 2;
|
||||
ch = fg->GetScaledHeight() - fg->GetScaledTopOffset() - cmd.special3 * 2;
|
||||
if (Scaled)
|
||||
|
@ -987,6 +991,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
DTA_ClipTop, cy,
|
||||
DTA_ClipRight, cr,
|
||||
DTA_ClipBottom, cb,
|
||||
DTA_Alpha, alpha,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
|
@ -1003,6 +1008,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
DTA_ClipTop, cy,
|
||||
DTA_ClipRight, cr,
|
||||
DTA_ClipBottom, cb,
|
||||
DTA_Alpha, alpha,
|
||||
TAG_DONE);
|
||||
}
|
||||
break;
|
||||
|
@ -1028,7 +1034,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
{
|
||||
wiggle = !!(cmd.flags & DRAWGEM_WIGGLE);
|
||||
}
|
||||
DrawGem(Images[cmd.special], Images[cmd.sprite], value, cmd.x, cmd.y, cmd.special2, cmd.special3, cmd.special4+1, wiggle, translate);
|
||||
DrawGem(Images[cmd.special], Images[cmd.sprite], value, cmd.x, cmd.y, xOffset, yOffset, alpha, cmd.special2, cmd.special3, cmd.special4+1, wiggle, translate);
|
||||
break;
|
||||
}
|
||||
case SBARINFO_DRAWSHADER:
|
||||
|
@ -1040,10 +1046,11 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
};
|
||||
bool vertical = !!(cmd.flags & DRAWSHADER_VERTICAL);
|
||||
bool reverse = !!(cmd.flags & DRAWSHADER_REVERSE);
|
||||
screen->DrawTexture (shaders[(vertical << 1) + reverse], ST_X+cmd.x, ST_Y+cmd.y,
|
||||
screen->DrawTexture (shaders[(vertical << 1) + reverse], ST_X+cmd.x+xOffset, ST_Y+cmd.y+yOffset,
|
||||
DTA_DestWidth, cmd.special,
|
||||
DTA_DestHeight, cmd.special2,
|
||||
DTA_Bottom320x200, Scaled,
|
||||
DTA_Alpha, alpha,
|
||||
DTA_AlphaChannel, true,
|
||||
DTA_FillColor, 0,
|
||||
TAG_DONE);
|
||||
|
@ -1054,7 +1061,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
{
|
||||
drawingFont = cmd.font;
|
||||
}
|
||||
DrawString(cmd.string[0], cmd.x - drawingFont->StringWidth(cmd.string[0]), cmd.y, cmd.translation, cmd.special);
|
||||
DrawString(cmd.string[0], cmd.x - drawingFont->StringWidth(cmd.string[0]), cmd.y, xOffset, yOffset, alpha, cmd.translation, cmd.special);
|
||||
break;
|
||||
case SBARINFO_DRAWKEYBAR:
|
||||
{
|
||||
|
@ -1071,9 +1078,9 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
goto FinishDrawKeyBar;
|
||||
}
|
||||
if(!vertical)
|
||||
DrawImage(TexMan[item->Icon], cmd.x+(cmd.special*i), cmd.y);
|
||||
DrawGraphic(TexMan[item->Icon], cmd.x+(cmd.special*i), cmd.y, xOffset, yOffset, alpha);
|
||||
else
|
||||
DrawImage(TexMan[item->Icon], cmd.x, cmd.y+(cmd.special*i));
|
||||
DrawGraphic(TexMan[item->Icon], cmd.x, cmd.y+(cmd.special*i), xOffset, yOffset, alpha);
|
||||
item = item->Inventory;
|
||||
if(item == NULL)
|
||||
break;
|
||||
|
@ -1087,7 +1094,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
((cmd.flags & GAMETYPE_COOPERATIVE) && multiplayer && !deathmatch) ||
|
||||
((cmd.flags & GAMETYPE_TEAMGAME) && teamplay))
|
||||
{
|
||||
doCommands(cmd.subBlock, xOffset, yOffset);
|
||||
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
||||
}
|
||||
break;
|
||||
case SBARINFO_PLAYERCLASS:
|
||||
|
@ -1096,14 +1103,14 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
int spawnClass = CPlayer->cls->ClassIndex;
|
||||
if(cmd.special == spawnClass || cmd.special2 == spawnClass || cmd.special3 == spawnClass)
|
||||
{
|
||||
doCommands(cmd.subBlock, xOffset, yOffset);
|
||||
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SBARINFO_ASPECTRATIO:
|
||||
if(CheckRatio(screen->GetWidth(), screen->GetHeight()) == cmd.value)
|
||||
{
|
||||
doCommands(cmd.subBlock, xOffset, yOffset);
|
||||
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
||||
}
|
||||
break;
|
||||
case SBARINFO_ISSELECTED:
|
||||
|
@ -1114,16 +1121,16 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
if(weapon2 != NULL)
|
||||
{
|
||||
if((cmd.flags & SBARINFOEVENT_NOT) && (weapon1 != CPlayer->ReadyWeapon->GetSpecies() && weapon2 != CPlayer->ReadyWeapon->GetSpecies()))
|
||||
doCommands(cmd.subBlock, xOffset, yOffset);
|
||||
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
||||
else if(!(cmd.flags & SBARINFOEVENT_NOT) && (weapon1 == CPlayer->ReadyWeapon->GetSpecies() || weapon2 == CPlayer->ReadyWeapon->GetSpecies()))
|
||||
doCommands(cmd.subBlock, xOffset, yOffset);
|
||||
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!(cmd.flags & SBARINFOEVENT_NOT) && weapon1 == CPlayer->ReadyWeapon->GetSpecies())
|
||||
doCommands(cmd.subBlock, xOffset, yOffset);
|
||||
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
||||
else if((cmd.flags & SBARINFOEVENT_NOT) && weapon1 != CPlayer->ReadyWeapon->GetSpecies())
|
||||
doCommands(cmd.subBlock, xOffset, yOffset);
|
||||
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1150,11 +1157,11 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
if(((cmd.flags & SBARINFOEVENT_OR) && (match1 || match2)) || ((cmd.flags & SBARINFOEVENT_AND) && (match1 && match2)))
|
||||
{
|
||||
if(!(cmd.flags & SBARINFOEVENT_NOT))
|
||||
doCommands(cmd.subBlock, xOffset, yOffset);
|
||||
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
||||
}
|
||||
else if(cmd.flags & SBARINFOEVENT_NOT)
|
||||
{
|
||||
doCommands(cmd.subBlock, xOffset, yOffset);
|
||||
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
||||
}
|
||||
}
|
||||
else //Every thing here could probably be one long if statement but then it would be more confusing.
|
||||
|
@ -1162,11 +1169,11 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
if((usesammo1 && (AmmoType1 == IfAmmo1)) || (usesammo2 && (AmmoType2 == IfAmmo1)))
|
||||
{
|
||||
if(!(cmd.flags & SBARINFOEVENT_NOT))
|
||||
doCommands(cmd.subBlock, xOffset, yOffset);
|
||||
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
||||
}
|
||||
else if(cmd.flags & SBARINFOEVENT_NOT)
|
||||
{
|
||||
doCommands(cmd.subBlock, xOffset, yOffset);
|
||||
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1178,66 +1185,57 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset)
|
|||
if(cmd.flags & SBARINFOEVENT_AND)
|
||||
{
|
||||
if((item1 != NULL && item2 != NULL) && !(cmd.flags & SBARINFOEVENT_NOT))
|
||||
doCommands(cmd.subBlock, xOffset, yOffset);
|
||||
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
||||
else if((item1 == NULL || item2 == NULL) && (cmd.flags & SBARINFOEVENT_NOT))
|
||||
doCommands(cmd.subBlock, xOffset, yOffset);
|
||||
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
||||
}
|
||||
else if(cmd.flags & SBARINFOEVENT_OR)
|
||||
{
|
||||
if((item1 != NULL || item2 != NULL) && !(cmd.flags & SBARINFOEVENT_NOT))
|
||||
doCommands(cmd.subBlock, xOffset, yOffset);
|
||||
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
||||
else if((item1 == NULL && item2 == NULL) && (cmd.flags & SBARINFOEVENT_NOT))
|
||||
doCommands(cmd.subBlock, xOffset, yOffset);
|
||||
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
||||
}
|
||||
else if((item1 != NULL) && !(cmd.flags & SBARINFOEVENT_NOT))
|
||||
doCommands(cmd.subBlock, xOffset, yOffset);
|
||||
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
||||
else if((item1 == NULL) && (cmd.flags & SBARINFOEVENT_NOT))
|
||||
doCommands(cmd.subBlock, xOffset, yOffset);
|
||||
doCommands(cmd.subBlock, xOffset, yOffset, alpha);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cmd.x -= xOffset;
|
||||
cmd.y -= yOffset;
|
||||
}
|
||||
}
|
||||
|
||||
//draws an image with the specified flags
|
||||
void DSBarInfo::DrawGraphic(FTexture* texture, int x, int y, int flags)
|
||||
void DSBarInfo::DrawGraphic(FTexture* texture, int x, int y, int xOffset, int yOffset, int alpha,
|
||||
bool translate, bool dim, bool center) //flags
|
||||
{
|
||||
if (texture == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if((flags & DRAWIMAGE_OFFSET_CENTER))
|
||||
|
||||
if(center)
|
||||
{
|
||||
x -= (texture->GetWidth()/2)-texture->LeftOffset;
|
||||
y -= (texture->GetHeight()/2)-texture->TopOffset;
|
||||
}
|
||||
x += ST_X;
|
||||
y += ST_Y;
|
||||
|
||||
x += ST_X + xOffset;
|
||||
y += ST_Y + yOffset;
|
||||
int w = texture->GetScaledWidth();
|
||||
int h = texture->GetScaledHeight() + y;
|
||||
if(Scaled)
|
||||
screen->VirtualToRealCoordsInt(x, y, w, h, 320, 200, true);
|
||||
h -= y;
|
||||
if((flags & DRAWIMAGE_TRANSLATABLE))
|
||||
{
|
||||
screen->DrawTexture(texture, x, y,
|
||||
DTA_DestWidth, w,
|
||||
DTA_DestHeight, h,
|
||||
DTA_Translation, getTranslation(),
|
||||
DTA_Translation, translate ? getTranslation() : 0,
|
||||
DTA_ColorOverlay, dim ? DIM_OVERLAY : 0,
|
||||
DTA_Alpha, alpha,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->DrawTexture(texture, x, y,
|
||||
DTA_DestWidth, w,
|
||||
DTA_DestHeight, h,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
void DSBarInfo::DrawString(const char* str, int x, int y, EColorRange translation, int spacing)
|
||||
void DSBarInfo::DrawString(const char* str, int x, int y, int xOffset, int yOffset, int alpha, EColorRange translation, int spacing)
|
||||
{
|
||||
x += spacing;
|
||||
while(*str != '\0')
|
||||
|
@ -1261,8 +1259,8 @@ void DSBarInfo::DrawString(const char* str, int x, int y, EColorRange translatio
|
|||
}
|
||||
if(SBarInfoScript->spacingCharacter == '\0') //If we are monospaced lets use the offset
|
||||
x += (character->LeftOffset+1); //ignore x offsets since we adapt to character size
|
||||
int rx = x + ST_X;
|
||||
int ry = y + ST_Y;
|
||||
int rx = x + ST_X + xOffset;
|
||||
int ry = y + ST_Y + yOffset;
|
||||
int rw = character->GetScaledWidth();
|
||||
int rh = character->GetScaledHeight();
|
||||
if(Scaled)
|
||||
|
@ -1271,6 +1269,7 @@ void DSBarInfo::DrawString(const char* str, int x, int y, EColorRange translatio
|
|||
DTA_DestWidth, rw,
|
||||
DTA_DestHeight, rh,
|
||||
DTA_Translation, drawingFont->GetColorTranslation(translation),
|
||||
DTA_Alpha, alpha,
|
||||
TAG_DONE);
|
||||
if(SBarInfoScript->spacingCharacter == '\0')
|
||||
x += width + spacing - (character->LeftOffset+1);
|
||||
|
@ -1281,7 +1280,7 @@ void DSBarInfo::DrawString(const char* str, int x, int y, EColorRange translatio
|
|||
}
|
||||
|
||||
//draws the specified number up to len digits
|
||||
void DSBarInfo::DrawNumber(int num, int len, int x, int y, EColorRange translation, int spacing, bool fillzeros)
|
||||
void DSBarInfo::DrawNumber(int num, int len, int x, int y, int xOffset, int yOffset, int alpha, EColorRange translation, int spacing, bool fillzeros)
|
||||
{
|
||||
FString value;
|
||||
int maxval = (int) ceil(pow(10., len))-1;
|
||||
|
@ -1306,11 +1305,11 @@ void DSBarInfo::DrawNumber(int num, int len, int x, int y, EColorRange translati
|
|||
x -= int(drawingFont->StringWidth(value)+(spacing * value.Len()));
|
||||
else //monospaced so just multiplay the character size
|
||||
x -= int((drawingFont->GetCharWidth((int) SBarInfoScript->spacingCharacter) + spacing) * value.Len());
|
||||
DrawString(value, x, y, translation, spacing);
|
||||
DrawString(value, x, y, xOffset, yOffset, alpha, translation, spacing);
|
||||
}
|
||||
|
||||
//draws the mug shot
|
||||
void DSBarInfo::DrawFace(FString &defaultFace, int accuracy, bool xdth, bool animatedgodmode, int x, int y)
|
||||
void DSBarInfo::DrawFace(FString &defaultFace, int accuracy, bool xdth, bool animatedgodmode, int x, int y, int xOffset, int yOffset, int alpha)
|
||||
{
|
||||
int angle = updateState(xdth, animatedgodmode);
|
||||
int level = 0;
|
||||
|
@ -1320,18 +1319,7 @@ void DSBarInfo::DrawFace(FString &defaultFace, int accuracy, bool xdth, bool ani
|
|||
FPlayerSkin *skin = &skins[CPlayer->morphTics ? CPlayer->MorphedPlayerClass : CPlayer->userinfo.skin];
|
||||
FTexture *face = currentState->getCurrentFrameTexture(defaultFace, skin, level, angle);
|
||||
if (face != NULL)
|
||||
{
|
||||
x += ST_X;
|
||||
y += ST_Y;
|
||||
int w = face->GetScaledWidth();
|
||||
int h = face->GetScaledHeight();
|
||||
if(Scaled)
|
||||
screen->VirtualToRealCoordsInt(x, y, w, h, 320, 200, true);
|
||||
screen->DrawTexture(face, x, y,
|
||||
DTA_DestWidth, w,
|
||||
DTA_DestHeight, h,
|
||||
TAG_DONE);
|
||||
}
|
||||
DrawGraphic(face, x, y, xOffset, yOffset, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1454,7 +1442,7 @@ int DSBarInfo::updateState(bool xdth, bool animatedgodmode)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void DSBarInfo::DrawInventoryBar(int type, int num, int x, int y, bool alwaysshow,
|
||||
void DSBarInfo::DrawInventoryBar(int type, int num, int x, int y, int xOffset, int yOffset, int alpha, bool alwaysshow,
|
||||
int counterx, int countery, EColorRange translation, bool drawArtiboxes, bool noArrows, bool alwaysshowcounter)
|
||||
{ //yes, there is some Copy & Paste here too
|
||||
AInventory *item;
|
||||
|
@ -1468,46 +1456,46 @@ void DSBarInfo::DrawInventoryBar(int type, int num, int x, int y, bool alwayssho
|
|||
{
|
||||
if(drawArtiboxes)
|
||||
{
|
||||
DrawGraphic(Images[invBarOffset + imgARTIBOX], x+i*31, y);
|
||||
DrawGraphic(Images[invBarOffset + imgARTIBOX], x+i*31, y, xOffset, yOffset, alpha);
|
||||
}
|
||||
DrawDimImage (TexMan(item->Icon), x+i*31, y, item->Amount <= 0);
|
||||
DrawGraphic(TexMan(item->Icon), x+i*31, y, xOffset, yOffset, alpha, false, item->Amount <= 0);
|
||||
if(alwaysshowcounter || item->Amount != 1)
|
||||
{
|
||||
DrawNumber(item->Amount, 3, counterx+i*31, countery, translation);
|
||||
DrawNumber(item->Amount, 3, counterx+i*31, countery, xOffset, yOffset, alpha, translation);
|
||||
}
|
||||
if(item == CPlayer->mo->InvSel)
|
||||
{
|
||||
if(type == GAME_Heretic)
|
||||
{
|
||||
DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*31, y+29);
|
||||
DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*31, y+29, xOffset, yOffset, alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*31, y);
|
||||
DrawGraphic(Images[invBarOffset + imgSELECTBOX], x+i*31, y, xOffset, yOffset, alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (; i < num && drawArtiboxes; ++i)
|
||||
{
|
||||
DrawGraphic(Images[invBarOffset + imgARTIBOX], x+i*31, y);
|
||||
DrawGraphic(Images[invBarOffset + imgARTIBOX], x+i*31, y, xOffset, yOffset, alpha);
|
||||
}
|
||||
// Is there something to the left?
|
||||
if (!noArrows && CPlayer->mo->FirstInv() != CPlayer->mo->InvFirst)
|
||||
{
|
||||
DrawGraphic(Images[!(gametic & 4) ?
|
||||
invBarOffset + imgINVLFGEM1 : invBarOffset + imgINVLFGEM2], x-12, y);
|
||||
invBarOffset + imgINVLFGEM1 : invBarOffset + imgINVLFGEM2], x-12, y, xOffset, yOffset, alpha);
|
||||
}
|
||||
// Is there something to the right?
|
||||
if (!noArrows && item != NULL)
|
||||
{
|
||||
DrawGraphic(Images[!(gametic & 4) ?
|
||||
invBarOffset + imgINVRTGEM1 : invBarOffset + imgINVRTGEM2], x+num*31+2, y);
|
||||
invBarOffset + imgINVRTGEM1 : invBarOffset + imgINVRTGEM2], x+num*31+2, y, xOffset, yOffset, alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//draws heretic/hexen style life gems
|
||||
void DSBarInfo::DrawGem(FTexture* chain, FTexture* gem, int value, int x, int y, int padleft, int padright, int chainsize,
|
||||
void DSBarInfo::DrawGem(FTexture* chain, FTexture* gem, int value, int x, int y, int xOffset, int yOffset, int alpha, int padleft, int padright, int chainsize,
|
||||
bool wiggle, bool translate)
|
||||
{
|
||||
if(chain == NULL)
|
||||
|
@ -1520,9 +1508,9 @@ void DSBarInfo::DrawGem(FTexture* chain, FTexture* gem, int value, int x, int y,
|
|||
y += chainWiggle;
|
||||
int chainWidth = chain->GetWidth();
|
||||
int offset = (int) (((double) (chainWidth-padleft-padright)/100)*value);
|
||||
DrawGraphic(chain, x+(offset%chainsize), y);
|
||||
DrawGraphic(chain, x+(offset%chainsize), y, xOffset, yOffset, alpha);
|
||||
if(gem != NULL)
|
||||
DrawGraphic(gem, x+padleft+offset, y, translate ? DRAWIMAGE_TRANSLATABLE : 0);
|
||||
DrawGraphic(gem, x+padleft+offset, y, xOffset, yOffset, alpha, translate);
|
||||
}
|
||||
|
||||
FRemapTable* DSBarInfo::getTranslation()
|
||||
|
|
|
@ -255,9 +255,10 @@ void SBarInfo::ParseSBarInfo(int lump)
|
|||
barNum = sc.MustMatchString(StatusBars);
|
||||
}
|
||||
this->huds[barNum] = SBarInfoBlock();
|
||||
while(sc.CheckToken(','))
|
||||
if(sc.CheckToken(','))
|
||||
{
|
||||
while(sc.CheckToken(TK_Identifier))
|
||||
{
|
||||
sc.MustGetToken(TK_Identifier);
|
||||
if(sc.Compare("forcescaled"))
|
||||
{
|
||||
this->huds[barNum].forceScaled = true;
|
||||
|
@ -266,7 +267,13 @@ void SBarInfo::ParseSBarInfo(int lump)
|
|||
{
|
||||
sc.ScriptError("Unkown flag '%s'.", sc.String);
|
||||
}
|
||||
if(!sc.CheckToken('|') || !sc.CheckToken(','))
|
||||
goto FinishStatusBar; //No more args so we must skip over anything else and go to the end.
|
||||
}
|
||||
sc.MustGetToken(TK_FloatConst);
|
||||
this->huds[barNum].alpha = fixed_t(FRACUNIT * sc.Float);
|
||||
}
|
||||
FinishStatusBar:
|
||||
sc.MustGetToken('{');
|
||||
if(barNum == STBAR_AUTOMAP)
|
||||
{
|
||||
|
@ -336,6 +343,16 @@ void SBarInfo::ParseSBarInfo(int lump)
|
|||
sc.MustGetToken(TK_IntConst);
|
||||
popup.speed = sc.Number;
|
||||
}
|
||||
else if(sc.Compare("fade"))
|
||||
{
|
||||
popup.transition = TRANSITION_FADE;
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetToken(TK_FloatConst);
|
||||
popup.speed = fixed_t(FRACUNIT * sc.Float);
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetToken(TK_FloatConst);
|
||||
popup.speed2 = fixed_t(FRACUNIT * sc.Float);
|
||||
}
|
||||
else
|
||||
sc.ScriptError("Unkown transition type: '%s'", sc.String);
|
||||
}
|
||||
|
@ -1264,6 +1281,7 @@ SBarInfoCommand::~SBarInfoCommand()
|
|||
SBarInfoBlock::SBarInfoBlock()
|
||||
{
|
||||
forceScaled = false;
|
||||
alpha = FRACUNIT;
|
||||
}
|
||||
|
||||
const MugShotState *FindMugShotState(FString state)
|
||||
|
@ -1286,6 +1304,7 @@ Popup::Popup()
|
|||
speed = 0;
|
||||
x = 320;
|
||||
y = 200;
|
||||
alpha = FRACUNIT;
|
||||
opened = false;
|
||||
moving = false;
|
||||
}
|
||||
|
@ -1298,6 +1317,12 @@ void Popup::init()
|
|||
{
|
||||
x = 0;
|
||||
}
|
||||
else if(transition == TRANSITION_FADE)
|
||||
{
|
||||
alpha = 0;
|
||||
x = 0;
|
||||
y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Popup::tick()
|
||||
|
@ -1316,9 +1341,22 @@ void Popup::tick()
|
|||
else
|
||||
moving = false;
|
||||
}
|
||||
else if(transition == TRANSITION_FADE)
|
||||
{
|
||||
if(moving)
|
||||
{
|
||||
if(opened)
|
||||
alpha = clamp(alpha + speed, 0, FRACUNIT);
|
||||
else
|
||||
alpha = clamp(alpha - speed2, 0, FRACUNIT);
|
||||
}
|
||||
if(alpha == 0 || alpha == FRACUNIT)
|
||||
moving = false;
|
||||
else
|
||||
moving = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
moving = false;
|
||||
if(opened)
|
||||
{
|
||||
y = 0;
|
||||
|
@ -1329,6 +1367,7 @@ void Popup::tick()
|
|||
y = height;
|
||||
x = width;
|
||||
}
|
||||
moving = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1347,6 +1386,13 @@ int Popup::getYOffset()
|
|||
return y;
|
||||
}
|
||||
|
||||
int Popup::getAlpha(int maxAlpha)
|
||||
{
|
||||
double a = (double) alpha / (double) FRACUNIT;
|
||||
double b = (double) maxAlpha / (double) FRACUNIT;
|
||||
return fixed_t((a * b) * FRACUNIT);
|
||||
}
|
||||
|
||||
void Popup::open()
|
||||
{
|
||||
opened = true;
|
||||
|
|
|
@ -698,7 +698,7 @@ void GLDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, bo
|
|||
else lightlevel=abs(ceiling? GetCeilingLight(sec) : GetFloorLight(sec));
|
||||
}
|
||||
|
||||
gl_SetFog(lightlevel, Colormap.FadeColor, STYLE_Normal, Colormap.LightColor.a);
|
||||
gl_SetFog(lightlevel, Colormap.FadeColor, false, Colormap.LightColor.a);
|
||||
gl_SetColor(lightlevel, extralight*gl_weaponlight, &Colormap,1.0f);
|
||||
gltexture->Bind(Colormap.LightColor.a);
|
||||
gl_SetPlaneTextureRotation(&plane, gltexture);
|
||||
|
|
|
@ -324,6 +324,7 @@ void ModifyPalette(PalEntry * pout, PalEntry * pin, int cm, int count)
|
|||
{
|
||||
int gray = (pin[i].r*77 + pin[i].g*143 + pin[i].b*37) >> 8;
|
||||
gl_InverseMap(gray, pout[i].r, pout[i].g, pout[i].b);
|
||||
pout[i].a = pin[i].a;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -333,6 +334,7 @@ void ModifyPalette(PalEntry * pout, PalEntry * pin, int cm, int count)
|
|||
{
|
||||
int gray = (pin[i].r*77 + pin[i].g*143 + pin[i].b*37) >> 8;
|
||||
gl_GoldMap(gray, pout[i].r, pout[i].g, pout[i].b);
|
||||
pout[i].a = pin[i].a;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -342,6 +344,7 @@ void ModifyPalette(PalEntry * pout, PalEntry * pin, int cm, int count)
|
|||
{
|
||||
int gray = (pin[i].r*77 + pin[i].g*143 + pin[i].b*37) >> 8;
|
||||
gl_RedMap(gray, pout[i].r, pout[i].g, pout[i].b);
|
||||
pout[i].a = pin[i].a;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -351,6 +354,7 @@ void ModifyPalette(PalEntry * pout, PalEntry * pin, int cm, int count)
|
|||
{
|
||||
int gray = (pin[i].r*77 + pin[i].g*143 + pin[i].b*37) >> 8;
|
||||
gl_GreenMap(gray, pout[i].r, pout[i].g, pout[i].b);
|
||||
pout[i].a = pin[i].a;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -447,10 +451,10 @@ void FGLBitmap::CopyPixelData(int originx, int originy, const BYTE * patch, int
|
|||
{
|
||||
for(int i=0;i<256;i++)
|
||||
{
|
||||
if (palette[i].a!=255)
|
||||
penew[i]=PalEntry(255-i,255,255,255);
|
||||
if (palette[i].a != 0)
|
||||
penew[i]=PalEntry(255,255,255,255);
|
||||
else
|
||||
penew[i]=0xffffffff; // If the palette contains transparent colors keep them.
|
||||
penew[i]=PalEntry(0,255,255,255); // If the palette contains transparent colors keep them.
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -503,13 +507,14 @@ void FGLBitmap::CopyPixelData(int originx, int originy, const BYTE * patch, int
|
|||
for (x=0;x<srcwidth;x++,pos+=4)
|
||||
{
|
||||
int v=(unsigned char)patch[y*step_y+x*step_x];
|
||||
if (penew[v].a==0)
|
||||
if (penew[v].a!=0)
|
||||
{
|
||||
buffer[pos] = penew[v].r;
|
||||
buffer[pos+1] = penew[v].g;
|
||||
buffer[pos+2] = penew[v].b;
|
||||
buffer[pos+3]=255-penew[v].a;
|
||||
buffer[pos+3] = penew[v].a;
|
||||
}
|
||||
/*
|
||||
else if (penew[v].a!=255)
|
||||
{
|
||||
buffer[pos ] = (buffer[pos ] * penew[v].a + penew[v].r * (1-penew[v].a)) / 255;
|
||||
|
@ -517,6 +522,7 @@ void FGLBitmap::CopyPixelData(int originx, int originy, const BYTE * patch, int
|
|||
buffer[pos+2] = (buffer[pos+2] * penew[v].a + penew[v].b * (1-penew[v].a)) / 255;
|
||||
buffer[pos+3] = clamp<int>(buffer[pos+3] + (( 255-buffer[pos+3]) * (255-penew[v].a))/255, 0, 255);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1464,7 +1464,7 @@ void M_DrawReadThis ()
|
|||
else
|
||||
{
|
||||
// Did the mapper choose a custom help page via MAPINFO?
|
||||
if (level.info->f1[0] != 0)
|
||||
if ((level.info != NULL) && level.info->f1[0] != 0)
|
||||
{
|
||||
tex = TexMan.FindTexture(level.info->f1);
|
||||
}
|
||||
|
@ -3513,7 +3513,7 @@ void M_Init (void)
|
|||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
FireRemap.Remap[i] = ColorMatcher.Pick (i/2+32, 0, i/4);
|
||||
FireRemap.Palette[i] = PalEntry(i/2+32, 0, i/4);
|
||||
FireRemap.Palette[i] = PalEntry(255, i/2+32, 0, i/4);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -3522,7 +3522,7 @@ void M_Init (void)
|
|||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
FireRemap.Remap[i] = ColorMatcher.Pick (i/4, i*13/40+7, i/4);
|
||||
FireRemap.Palette[i] = PalEntry(i/4, i*13/40+7, i/4);
|
||||
FireRemap.Palette[i] = PalEntry(255, i/4, i*13/40+7, i/4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -541,39 +541,30 @@ void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *li
|
|||
{
|
||||
if(thing)
|
||||
{
|
||||
sector_t *front, *back;
|
||||
|
||||
fixed_t thingbot, thingtop;
|
||||
|
||||
thingbot = thing->z;
|
||||
thingtop = thingbot + thing->height;
|
||||
|
||||
front = linedef->frontsector;
|
||||
back = linedef->backsector;
|
||||
|
||||
extsector_t::xfloor &xf = front->e->XFloor;
|
||||
extsector_t::xfloor &xb = back->e->XFloor;
|
||||
extsector_t::xfloor *xf[2] = {&linedef->frontsector->e->XFloor, &linedef->backsector->e->XFloor};
|
||||
|
||||
// Check for 3D-floors in the sector (mostly identical to what Legacy does here)
|
||||
if(xf.ffloors.Size() || xb.ffloors.Size())
|
||||
if(xf[0]->ffloors.Size() || xf[1]->ffloors.Size())
|
||||
{
|
||||
F3DFloor* rover;
|
||||
unsigned i;
|
||||
|
||||
fixed_t lowestceiling = open.top;
|
||||
fixed_t highestfloor = open.bottom;
|
||||
fixed_t lowestfloor = open.lowfloor;
|
||||
fixed_t delta1;
|
||||
fixed_t delta2;
|
||||
fixed_t lowestfloor[2] = {open.lowfloor, open.lowfloor};
|
||||
int highestfloorpic = -1;
|
||||
int lowestceilingpic = -1;
|
||||
|
||||
thingtop = thing->z + (thing->height==0? 1:thing->height);
|
||||
|
||||
for(int j=0;j<2;j++)
|
||||
{
|
||||
// Check for frontsector's 3D-floors
|
||||
for(i=0;i<xf.ffloors.Size();i++)
|
||||
for(unsigned i=0;i<xf[j]->ffloors.Size();i++)
|
||||
{
|
||||
rover=xf.ffloors[i];
|
||||
F3DFloor *rover = xf[j]->ffloors[i];
|
||||
|
||||
if (!(rover->flags&FF_EXISTS)) continue;
|
||||
if (!(rover->flags & FF_SOLID)) continue;
|
||||
|
@ -581,37 +572,22 @@ void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *li
|
|||
fixed_t ff_bottom=rover->bottom.plane->ZatPoint(x, y);
|
||||
fixed_t ff_top=rover->top.plane->ZatPoint(x, y);
|
||||
|
||||
delta1 = abs(thing->z - ((ff_bottom + ff_top) / 2));
|
||||
delta2 = abs(thingtop - ((ff_bottom + ff_top) / 2));
|
||||
fixed_t delta1 = abs(thingbot - ((ff_bottom + ff_top) / 2));
|
||||
fixed_t delta2 = abs(thingtop - ((ff_bottom + ff_top) / 2));
|
||||
|
||||
if(ff_bottom < lowestceiling && delta1 >= delta2) lowestceiling = ff_bottom;
|
||||
|
||||
if(ff_top > highestfloor && delta1 < delta2) highestfloor = ff_top;
|
||||
else if(ff_top > lowestfloor && delta1 < delta2) lowestfloor = ff_top;
|
||||
if(ff_bottom < lowestceiling && delta1 >= delta2)
|
||||
{
|
||||
lowestceiling = ff_bottom;
|
||||
lowestceilingpic = *rover->bottom.texture;
|
||||
}
|
||||
|
||||
// Check for backsector's 3D-floors
|
||||
for(i=0;i<xb.ffloors.Size();i++)
|
||||
{
|
||||
rover=xb.ffloors[i];
|
||||
|
||||
if (!(rover->flags&FF_EXISTS)) continue;
|
||||
if (!(rover->flags & FF_SOLID)) continue;
|
||||
|
||||
fixed_t ff_bottom=rover->bottom.plane->ZatPoint(x, y);
|
||||
fixed_t ff_top=rover->top.plane->ZatPoint(x, y);
|
||||
|
||||
delta1 = abs(thing->z - ((ff_bottom + ff_top) / 2));
|
||||
delta2 = abs(thingtop - ((ff_bottom + ff_top) / 2));
|
||||
|
||||
if(ff_bottom < lowestceiling && delta1 >= delta2) lowestceiling = ff_bottom;
|
||||
|
||||
if(ff_top > highestfloor && delta1 < delta2)
|
||||
{
|
||||
highestfloor = ff_top;
|
||||
highestfloorpic = *rover->top.texture;
|
||||
}
|
||||
else if(ff_top > lowestfloor && delta1 < delta2) lowestfloor = ff_top;
|
||||
if(ff_top > lowestfloor[j] && ff_top <= thing->z) lowestfloor[j] = ff_top;
|
||||
}
|
||||
}
|
||||
|
||||
if(highestfloor > open.bottom)
|
||||
|
@ -626,7 +602,7 @@ void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *li
|
|||
open.ceilingpic = lowestceilingpic;
|
||||
}
|
||||
|
||||
if(lowestfloor > open.lowfloor) open.lowfloor = lowestfloor;
|
||||
open.lowfloor = MIN(lowestfloor[0], lowestfloor[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1115,6 +1115,7 @@ void APlayerPawn::Die (AActor *source, AActor *inflictor)
|
|||
{
|
||||
static_cast<AWeapon *>(item)->AmmoGive2 = weap->Ammo2->Amount;
|
||||
}
|
||||
item->ItemFlags |= IF_IGNORESKILL;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1123,11 +1124,13 @@ void APlayerPawn::Die (AActor *source, AActor *inflictor)
|
|||
if (item != NULL)
|
||||
{
|
||||
item->Amount = weap->Ammo1->Amount;
|
||||
item->ItemFlags |= IF_IGNORESKILL;
|
||||
}
|
||||
item = P_DropItem (this, weap->AmmoType2, -1, 256);
|
||||
if (item != NULL)
|
||||
{
|
||||
item->Amount = weap->Ammo2->Amount;
|
||||
item->ItemFlags |= IF_IGNORESKILL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,16 +107,19 @@ protected:
|
|||
SWORD OriginX, OriginY;
|
||||
BYTE Rotate;
|
||||
bool textureOwned;
|
||||
BYTE op;
|
||||
FRemapTable *Translation;
|
||||
PalEntry Blend;
|
||||
FTexture *Texture;
|
||||
fixed_t Alpha;
|
||||
|
||||
TexPart();
|
||||
};
|
||||
|
||||
int NumParts;
|
||||
TexPart *Parts;
|
||||
bool bRedirect;
|
||||
bool bRedirect:1;
|
||||
bool bTranslucentPatches:1;
|
||||
|
||||
void MakeTexture ();
|
||||
|
||||
|
|
|
@ -827,7 +827,7 @@ public:
|
|||
virtual const BYTE *GetPixels () = 0;
|
||||
|
||||
virtual int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate=0, FCopyInfo *inf = NULL);
|
||||
int CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, FRemapTable *remap);
|
||||
int CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, FRemapTable *remap, FCopyInfo *inf = NULL);
|
||||
virtual bool UseBasePalette();
|
||||
virtual int GetSourceLump() { return -1; }
|
||||
|
||||
|
|
|
@ -160,9 +160,7 @@ void FRemapTable::Serialize(FArchive &arc)
|
|||
}
|
||||
for (int j = 0; j < NumEntries; ++j)
|
||||
{
|
||||
arc << Palette[j].r
|
||||
<< Palette[j].g
|
||||
<< Palette[j].b;
|
||||
arc << Palette[j];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,6 +177,10 @@ void FRemapTable::MakeIdentity()
|
|||
{
|
||||
Palette[i] = GPalette.BaseColors[i];
|
||||
}
|
||||
for (i = 1; i < NumEntries; ++i)
|
||||
{
|
||||
Palette[i].a = 255;
|
||||
}
|
||||
}
|
||||
|
||||
bool FRemapTable::IsIdentity() const
|
||||
|
@ -232,6 +234,7 @@ void FRemapTable::AddIndexRange(int start, int end, int pal1, int pal2)
|
|||
{
|
||||
Remap[start] = pal1;
|
||||
Palette[start] = GPalette.BaseColors[pal1];
|
||||
Palette[start].a = start==0? 0:255;
|
||||
return;
|
||||
}
|
||||
palcol = pal1 << FRACBITS;
|
||||
|
@ -240,6 +243,7 @@ void FRemapTable::AddIndexRange(int start, int end, int pal1, int pal2)
|
|||
{
|
||||
Remap[i] = palcol >> FRACBITS;
|
||||
Palette[i] = GPalette.BaseColors[palcol >> FRACBITS];
|
||||
Palette[i].a = i==0? 0:255;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,6 +282,7 @@ void FRemapTable::AddColorRange(int start, int end, int _r1,int _g1, int _b1, in
|
|||
Remap[start] = ColorMatcher.Pick
|
||||
(r >> FRACBITS, g >> FRACBITS, b >> FRACBITS);
|
||||
Palette[start] = PalEntry(r >> FRACBITS, g >> FRACBITS, b >> FRACBITS);
|
||||
Palette[start].a = start==0? 0:255;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -288,7 +293,7 @@ void FRemapTable::AddColorRange(int start, int end, int _r1,int _g1, int _b1, in
|
|||
{
|
||||
Remap[i] = ColorMatcher.Pick
|
||||
(r >> FRACBITS, g >> FRACBITS, b >> FRACBITS);
|
||||
Palette[i] = PalEntry(r >> FRACBITS, g >> FRACBITS, b >> FRACBITS);
|
||||
Palette[i] = PalEntry(start==0? 0:255, r >> FRACBITS, g >> FRACBITS, b >> FRACBITS);
|
||||
r += rs;
|
||||
g += gs;
|
||||
b += bs;
|
||||
|
|
|
@ -366,11 +366,18 @@ void S_Start ()
|
|||
if (level.info && level.info->soundinfo)
|
||||
{
|
||||
LocalSndInfo = level.info->soundinfo;
|
||||
LocalSndSeq = level.info->sndseq;
|
||||
}
|
||||
else
|
||||
{
|
||||
LocalSndInfo = "";
|
||||
}
|
||||
|
||||
if (level.info && level.info->sndseq)
|
||||
{
|
||||
LocalSndSeq = level.info->sndseq;
|
||||
}
|
||||
else
|
||||
{
|
||||
LocalSndSeq = "";
|
||||
}
|
||||
|
||||
|
|
|
@ -549,11 +549,18 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (event != MIDI_META && (!track->Designated || (track->Designation & DesignationMask)))
|
||||
if (event != MIDI_META)
|
||||
{
|
||||
events[0] = delay;
|
||||
events[1] = 0;
|
||||
if (!track->Designated || (track->Designation & DesignationMask))
|
||||
{
|
||||
events[2] = event | (data1<<8) | (data2<<16);
|
||||
}
|
||||
else
|
||||
{
|
||||
events[2] = MEVT_NOP;
|
||||
}
|
||||
events += 3;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "w_wad.h"
|
||||
#include "v_text.h"
|
||||
#include "timidity/timidity.h"
|
||||
#include <errno.h>
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -597,38 +598,38 @@ FString TimidityMIDIDevice::GetStats()
|
|||
CritSec.Enter();
|
||||
for (i = used = 0; i < Renderer->voices; ++i)
|
||||
{
|
||||
switch (Renderer->voice[i].status)
|
||||
int status = Renderer->voice[i].status;
|
||||
|
||||
if (!(status & Timidity::VOICE_RUNNING))
|
||||
{
|
||||
case Timidity::VOICE_FREE:
|
||||
dots << TEXTCOLOR_PURPLE".";
|
||||
break;
|
||||
|
||||
case Timidity::VOICE_ON:
|
||||
dots << TEXTCOLOR_GREEN;
|
||||
break;
|
||||
|
||||
case Timidity::VOICE_SUSTAINED:
|
||||
dots << TEXTCOLOR_BLUE;
|
||||
break;
|
||||
|
||||
case Timidity::VOICE_OFF:
|
||||
dots << TEXTCOLOR_ORANGE;
|
||||
break;
|
||||
|
||||
case Timidity::VOICE_DIE:
|
||||
dots << TEXTCOLOR_RED;
|
||||
break;
|
||||
}
|
||||
if (Renderer->voice[i].status != Timidity::VOICE_FREE)
|
||||
{
|
||||
used++;
|
||||
if (Renderer->voice[i].envelope_increment == 0)
|
||||
{
|
||||
dots << TEXTCOLOR_BLUE"+";
|
||||
}
|
||||
else
|
||||
{
|
||||
dots << ('1' + Renderer->voice[i].envelope_stage);
|
||||
used++;
|
||||
if (status & Timidity::VOICE_SUSTAINING)
|
||||
{
|
||||
dots << TEXTCOLOR_BLUE;
|
||||
}
|
||||
else if (status & Timidity::VOICE_RELEASING)
|
||||
{
|
||||
dots << TEXTCOLOR_ORANGE;
|
||||
}
|
||||
else if (status & Timidity::VOICE_STOPPING)
|
||||
{
|
||||
dots << TEXTCOLOR_RED;
|
||||
}
|
||||
else
|
||||
{
|
||||
dots << TEXTCOLOR_GREEN;
|
||||
}
|
||||
if (Renderer->voice[i].envelope_increment == 0)
|
||||
{
|
||||
dots << "+";
|
||||
}
|
||||
else
|
||||
{
|
||||
dots << ('0' + Renderer->voice[i].envelope_stage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
// This file was automatically generated by the
|
||||
// updaterevision tool. Do not edit by hand.
|
||||
|
||||
#define ZD_SVN_REVISION_STRING "930"
|
||||
#define ZD_SVN_REVISION_NUMBER 930
|
||||
#define ZD_SVN_REVISION_STRING "940"
|
||||
#define ZD_SVN_REVISION_NUMBER 940
|
||||
|
|
|
@ -233,7 +233,7 @@ void iCopyColors(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *in
|
|||
|
||||
typedef void (*CopyFunc)(BYTE *pout, const BYTE *pin, int count, int step, FCopyInfo *inf);
|
||||
|
||||
static CopyFunc copyfuncs[9]=
|
||||
static const CopyFunc copyfuncs[][9]={
|
||||
{
|
||||
iCopyColors<cRGB, cBGRA, bCopy>,
|
||||
iCopyColors<cRGBA, cBGRA, bCopy>,
|
||||
|
@ -244,6 +244,73 @@ static CopyFunc copyfuncs[9]=
|
|||
iCopyColors<cI16, cBGRA, bCopy>,
|
||||
iCopyColors<cRGB555, cBGRA, bCopy>,
|
||||
iCopyColors<cPalEntry, cBGRA, bCopy>
|
||||
},
|
||||
{
|
||||
iCopyColors<cRGB, cBGRA, bBlend>,
|
||||
iCopyColors<cRGBA, cBGRA, bBlend>,
|
||||
iCopyColors<cIA, cBGRA, bBlend>,
|
||||
iCopyColors<cCMYK, cBGRA, bBlend>,
|
||||
iCopyColors<cBGR, cBGRA, bBlend>,
|
||||
iCopyColors<cBGRA, cBGRA, bBlend>,
|
||||
iCopyColors<cI16, cBGRA, bBlend>,
|
||||
iCopyColors<cRGB555, cBGRA, bBlend>,
|
||||
iCopyColors<cPalEntry, cBGRA, bBlend>
|
||||
},
|
||||
{
|
||||
iCopyColors<cRGB, cBGRA, bAdd>,
|
||||
iCopyColors<cRGBA, cBGRA, bAdd>,
|
||||
iCopyColors<cIA, cBGRA, bAdd>,
|
||||
iCopyColors<cCMYK, cBGRA, bAdd>,
|
||||
iCopyColors<cBGR, cBGRA, bAdd>,
|
||||
iCopyColors<cBGRA, cBGRA, bAdd>,
|
||||
iCopyColors<cI16, cBGRA, bAdd>,
|
||||
iCopyColors<cRGB555, cBGRA, bAdd>,
|
||||
iCopyColors<cPalEntry, cBGRA, bAdd>
|
||||
},
|
||||
{
|
||||
iCopyColors<cRGB, cBGRA, bSubtract>,
|
||||
iCopyColors<cRGBA, cBGRA, bSubtract>,
|
||||
iCopyColors<cIA, cBGRA, bSubtract>,
|
||||
iCopyColors<cCMYK, cBGRA, bSubtract>,
|
||||
iCopyColors<cBGR, cBGRA, bSubtract>,
|
||||
iCopyColors<cBGRA, cBGRA, bSubtract>,
|
||||
iCopyColors<cI16, cBGRA, bSubtract>,
|
||||
iCopyColors<cRGB555, cBGRA, bSubtract>,
|
||||
iCopyColors<cPalEntry, cBGRA, bSubtract>
|
||||
},
|
||||
{
|
||||
iCopyColors<cRGB, cBGRA, bReverseSubtract>,
|
||||
iCopyColors<cRGBA, cBGRA, bReverseSubtract>,
|
||||
iCopyColors<cIA, cBGRA, bReverseSubtract>,
|
||||
iCopyColors<cCMYK, cBGRA, bReverseSubtract>,
|
||||
iCopyColors<cBGR, cBGRA, bReverseSubtract>,
|
||||
iCopyColors<cBGRA, cBGRA, bReverseSubtract>,
|
||||
iCopyColors<cI16, cBGRA, bReverseSubtract>,
|
||||
iCopyColors<cRGB555, cBGRA, bReverseSubtract>,
|
||||
iCopyColors<cPalEntry, cBGRA, bReverseSubtract>
|
||||
},
|
||||
{
|
||||
iCopyColors<cRGB, cBGRA, bModulate>,
|
||||
iCopyColors<cRGBA, cBGRA, bModulate>,
|
||||
iCopyColors<cIA, cBGRA, bModulate>,
|
||||
iCopyColors<cCMYK, cBGRA, bModulate>,
|
||||
iCopyColors<cBGR, cBGRA, bModulate>,
|
||||
iCopyColors<cBGRA, cBGRA, bModulate>,
|
||||
iCopyColors<cI16, cBGRA, bModulate>,
|
||||
iCopyColors<cRGB555, cBGRA, bModulate>,
|
||||
iCopyColors<cPalEntry, cBGRA, bModulate>
|
||||
},
|
||||
{
|
||||
iCopyColors<cRGB, cBGRA, bCopyAlpha>,
|
||||
iCopyColors<cRGBA, cBGRA, bCopyAlpha>,
|
||||
iCopyColors<cIA, cBGRA, bCopyAlpha>,
|
||||
iCopyColors<cCMYK, cBGRA, bCopyAlpha>,
|
||||
iCopyColors<cBGR, cBGRA, bCopyAlpha>,
|
||||
iCopyColors<cBGRA, cBGRA, bCopyAlpha>,
|
||||
iCopyColors<cI16, cBGRA, bCopyAlpha>,
|
||||
iCopyColors<cRGB555, cBGRA, bCopyAlpha>,
|
||||
iCopyColors<cPalEntry, cBGRA, bCopyAlpha>
|
||||
},
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
|
@ -373,13 +440,55 @@ void FBitmap::CopyPixelDataRGB(int originx, int originy, const BYTE *patch, int
|
|||
if (ClipCopyPixelRect(Width, Height, originx, originy, patch, srcwidth, srcheight, step_x, step_y, rotate))
|
||||
{
|
||||
BYTE *buffer = data + 4 * originx + Pitch * originy;
|
||||
int op = inf==NULL? OP_COPY : inf->op;
|
||||
for (int y=0;y<srcheight;y++)
|
||||
{
|
||||
copyfuncs[ct](&buffer[y*Pitch], &patch[y*step_y], srcwidth, step_x, inf);
|
||||
copyfuncs[op][ct](&buffer[y*Pitch], &patch[y*step_y], srcwidth, step_x, inf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class TDest, class TBlend>
|
||||
void iCopyPaletted(BYTE *buffer, const BYTE * patch, int srcwidth, int srcheight, int Pitch,
|
||||
int step_x, int step_y, int rotate, PalEntry * palette, FCopyInfo *inf)
|
||||
{
|
||||
int x,y,pos;
|
||||
|
||||
for (y=0;y<srcheight;y++)
|
||||
{
|
||||
pos = y*Pitch;
|
||||
for (x=0;x<srcwidth;x++,pos+=4)
|
||||
{
|
||||
int v=(unsigned char)patch[y*step_y+x*step_x];
|
||||
int a;
|
||||
|
||||
if ((a = palette[v].a))
|
||||
{
|
||||
TBlend::OpC(buffer[pos + TDest::RED], palette[v].r, a, inf);
|
||||
TBlend::OpC(buffer[pos + TDest::GREEN], palette[v].g, a, inf);
|
||||
TBlend::OpC(buffer[pos + TDest::BLUE], palette[v].b, a, inf);
|
||||
TBlend::OpA(buffer[pos + TDest::ALPHA], a, inf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (*CopyPalettedFunc)(BYTE *buffer, const BYTE * patch, int srcwidth, int srcheight, int Pitch,
|
||||
int step_x, int step_y, int rotate, PalEntry * palette, FCopyInfo *inf);
|
||||
|
||||
|
||||
static const CopyPalettedFunc copypalettedfuncs[]=
|
||||
{
|
||||
iCopyPaletted<cBGRA, bCopy>,
|
||||
iCopyPaletted<cBGRA, bBlend>,
|
||||
iCopyPaletted<cBGRA, bAdd>,
|
||||
iCopyPaletted<cBGRA, bSubtract>,
|
||||
iCopyPaletted<cBGRA, bReverseSubtract>,
|
||||
iCopyPaletted<cBGRA, bModulate>,
|
||||
iCopyPaletted<cBGRA, bCopyAlpha>,
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Paletted to True Color texture copy function
|
||||
|
@ -388,8 +497,6 @@ void FBitmap::CopyPixelDataRGB(int originx, int originy, const BYTE *patch, int
|
|||
void FBitmap::CopyPixelData(int originx, int originy, const BYTE * patch, int srcwidth, int srcheight,
|
||||
int step_x, int step_y, int rotate, PalEntry * palette, FCopyInfo *inf)
|
||||
{
|
||||
int x,y,pos;
|
||||
|
||||
if (ClipCopyPixelRect(Width, Height, originx, originy, patch, srcwidth, srcheight, step_x, step_y, rotate))
|
||||
{
|
||||
BYTE *buffer = data + 4*originx + Pitch*originy;
|
||||
|
@ -397,39 +504,12 @@ void FBitmap::CopyPixelData(int originx, int originy, const BYTE * patch, int sr
|
|||
|
||||
if (inf && inf->blend)
|
||||
{
|
||||
// The palette's alpha is inverted so in order to use the
|
||||
// True Color copy functions it has to be inverted temporarily.
|
||||
memcpy(penew, palette, 4*256);
|
||||
for(int i=0;i<256;i++) penew[i].a = 255-penew[i].a;
|
||||
copyfuncs[CF_PalEntry]((BYTE*)penew, (BYTE*)penew, 256, 4, inf);
|
||||
for(int i=0;i<256;i++) penew[i].a = 255-penew[i].a;
|
||||
iCopyColors<cPalEntry, cBGRA, bCopy>((BYTE*)penew, (const BYTE*)palette, 256, 4, inf);
|
||||
palette = penew;
|
||||
}
|
||||
|
||||
|
||||
for (y=0;y<srcheight;y++)
|
||||
{
|
||||
pos = y*Pitch;
|
||||
for (x=0;x<srcwidth;x++,pos+=4)
|
||||
{
|
||||
int v=(unsigned char)patch[y*step_y+x*step_x];
|
||||
if (palette[v].a==0)
|
||||
{
|
||||
buffer[pos]=palette[v].b;
|
||||
buffer[pos+1]=palette[v].g;
|
||||
buffer[pos+2]=palette[v].r;
|
||||
buffer[pos+3]=255;
|
||||
}
|
||||
else if (palette[v].a!=255)
|
||||
{
|
||||
// [RH] Err... This can't be right, can it?
|
||||
buffer[pos ] = (buffer[pos ] * palette[v].a + palette[v].b * (1-palette[v].a)) / 255;
|
||||
buffer[pos+1] = (buffer[pos+1] * palette[v].a + palette[v].g * (1-palette[v].a)) / 255;
|
||||
buffer[pos+2] = (buffer[pos+2] * palette[v].a + palette[v].r * (1-palette[v].a)) / 255;
|
||||
buffer[pos+3] = clamp<int>(buffer[pos+3] + (( 255-buffer[pos+3]) * (255-palette[v].a))/255, 0, 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
copypalettedfuncs[inf==NULL? OP_COPY : inf->op](buffer, patch, srcwidth, srcheight, Pitch,
|
||||
step_x, step_y, rotate, palette, inf);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#define __BITMAP_H__
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "templates.h"
|
||||
|
||||
struct FCopyInfo;
|
||||
|
||||
|
@ -68,7 +69,7 @@ public:
|
|||
FreeBuffer = false;
|
||||
}
|
||||
|
||||
~FBitmap()
|
||||
virtual ~FBitmap()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
@ -272,14 +273,24 @@ enum EBlend
|
|||
BLEND_OVERLAY = -2,
|
||||
};
|
||||
|
||||
enum ECopyOp
|
||||
{
|
||||
OP_COPY,
|
||||
OP_BLEND,
|
||||
OP_ADD,
|
||||
OP_SUBTRACT,
|
||||
OP_REVERSESUBTRACT,
|
||||
OP_MODULATE,
|
||||
OP_COPYALPHA
|
||||
};
|
||||
|
||||
struct FCopyInfo
|
||||
{
|
||||
//ECopyOp op;
|
||||
ECopyOp op;
|
||||
EBlend blend;
|
||||
fixed_t blendcolor[4];
|
||||
// fixed_t alpha;
|
||||
// fixed_t invalpha;
|
||||
|
||||
fixed_t alpha;
|
||||
fixed_t invalpha;
|
||||
};
|
||||
|
||||
struct bCopy
|
||||
|
@ -288,6 +299,41 @@ struct bCopy
|
|||
static __forceinline void OpA(BYTE &d, BYTE s, FCopyInfo *i) { d = s; }
|
||||
};
|
||||
|
||||
struct bBlend
|
||||
{
|
||||
static __forceinline void OpC(BYTE &d, BYTE s, BYTE a, FCopyInfo *i) { d = (d*i->invalpha + s*i->alpha) >> FRACBITS; }
|
||||
static __forceinline void OpA(BYTE &d, BYTE s, FCopyInfo *i) { d = s; }
|
||||
};
|
||||
|
||||
struct bAdd
|
||||
{
|
||||
static __forceinline void OpC(BYTE &d, BYTE s, BYTE a, FCopyInfo *i) { d = MIN<int>((d*FRACUNIT + s*i->alpha) >> FRACBITS, 255); }
|
||||
static __forceinline void OpA(BYTE &d, BYTE s, FCopyInfo *i) { d = s; }
|
||||
};
|
||||
|
||||
struct bSubtract
|
||||
{
|
||||
static __forceinline void OpC(BYTE &d, BYTE s, BYTE a, FCopyInfo *i) { d = MAX<int>((d*FRACUNIT - s*i->alpha) >> FRACBITS, 0); }
|
||||
static __forceinline void OpA(BYTE &d, BYTE s, FCopyInfo *i) { d = s; }
|
||||
};
|
||||
|
||||
struct bReverseSubtract
|
||||
{
|
||||
static __forceinline void OpC(BYTE &d, BYTE s, BYTE a, FCopyInfo *i) { d = MAX<int>((-d*FRACUNIT + s*i->alpha) >> FRACBITS, 0); }
|
||||
static __forceinline void OpA(BYTE &d, BYTE s, FCopyInfo *i) { d = s; }
|
||||
};
|
||||
|
||||
struct bModulate
|
||||
{
|
||||
static __forceinline void OpC(BYTE &d, BYTE s, BYTE a, FCopyInfo *i) { d = (s*d)/255; }
|
||||
static __forceinline void OpA(BYTE &d, BYTE s, FCopyInfo *i) { d = s; }
|
||||
};
|
||||
|
||||
struct bCopyAlpha
|
||||
{
|
||||
static __forceinline void OpC(BYTE &d, BYTE s, BYTE a, FCopyInfo *i) { d = (s*a + d*(255-a))/255; }
|
||||
static __forceinline void OpA(BYTE &d, BYTE s, FCopyInfo *i) { d = s; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -381,7 +381,7 @@ int FJPEGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FC
|
|||
break;
|
||||
|
||||
case JCS_GRAYSCALE:
|
||||
for(int i=0;i<256;i++) pe[i]=PalEntry(0,i,i,i); // default to a gray map
|
||||
for(int i=0;i<256;i++) pe[i]=PalEntry(255,i,i,i); // default to a gray map
|
||||
bmp->CopyPixelData(x, y, buff, cinfo.output_width, cinfo.output_height,
|
||||
1, cinfo.output_width, rotate, pe, inf);
|
||||
break;
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
//==========================================================================
|
||||
|
||||
FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflumpnum)
|
||||
: Pixels (0), Spans(0), Parts(0), bRedirect(false)
|
||||
: Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false)
|
||||
{
|
||||
union
|
||||
{
|
||||
|
@ -361,6 +361,8 @@ void FMultiPatchTexture::MakeTexture ()
|
|||
Pixels = new BYTE[numpix];
|
||||
memset (Pixels, 0, numpix);
|
||||
|
||||
if (!bTranslucentPatches)
|
||||
{
|
||||
for (int i = 0; i < NumParts; ++i)
|
||||
{
|
||||
BYTE *trans = Parts[i].Translation? Parts[i].Translation->Remap : NULL;
|
||||
|
@ -372,6 +374,27 @@ void FMultiPatchTexture::MakeTexture ()
|
|||
Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// In case there are translucent patches let's do the composition in
|
||||
// True color to keep as much precision as possible before downconverting to the palette.
|
||||
BYTE *buffer = new BYTE[Width * Height * 4];
|
||||
FillBuffer(buffer, Width * 4, Height, TEX_RGB);
|
||||
for(int y = 0; y < Height; y++)
|
||||
{
|
||||
BYTE *in = buffer + Width * y * 4;
|
||||
BYTE *out = Pixels + y;
|
||||
for (int x = 0; x < Width; x--)
|
||||
{
|
||||
// I don't know if this is precise enough...
|
||||
*out = RGB32k[in[2]>>3][in[1]>>3][in[0]>>3];
|
||||
out += Height;
|
||||
in += 4;
|
||||
}
|
||||
}
|
||||
delete [] buffer;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -393,10 +416,13 @@ int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rota
|
|||
if (!Parts[i].Texture->bComplex || inf == NULL)
|
||||
{
|
||||
memset (&info, 0, sizeof (info));
|
||||
info.alpha = Parts[i].Alpha;
|
||||
info.invalpha = FRACUNIT - info.alpha;
|
||||
info.op = ECopyOp(Parts[i].op);
|
||||
if (Parts[i].Translation != NULL)
|
||||
{
|
||||
// Using a translation forces downconversion to the base palette
|
||||
ret = Parts[i].Texture->CopyTrueColorTranslated(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, Parts[i].Translation);
|
||||
ret = Parts[i].Texture->CopyTrueColorTranslated(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, Parts[i].Translation, &info);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -626,6 +652,8 @@ FMultiPatchTexture::TexPart::TexPart()
|
|||
Texture = NULL;
|
||||
Translation = NULL;
|
||||
Blend = 0;
|
||||
Alpha = FRACUNIT;
|
||||
op = OP_COPY;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -961,15 +989,14 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part)
|
|||
{
|
||||
int r,g,b;
|
||||
|
||||
sc.MustGetNumber();
|
||||
sc.MustGetStringName(",");
|
||||
r = sc.Number;
|
||||
sc.MustGetNumber();
|
||||
sc.MustGetStringName(",");
|
||||
sc.MustGetNumber();
|
||||
g = sc.Number;
|
||||
sc.MustGetNumber();
|
||||
sc.MustGetStringName(",");
|
||||
sc.MustGetNumber();
|
||||
b = sc.Number;
|
||||
sc.MustGetStringName(",");
|
||||
part.Blend = MAKERGB(r, g, b);
|
||||
}
|
||||
if (sc.CheckString(","))
|
||||
|
@ -980,6 +1007,19 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part)
|
|||
else part.Blend.a = 255;
|
||||
bComplex = true;
|
||||
}
|
||||
else if (sc.Compare("alpha"))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
part.Alpha = clamp(FLOAT2FIXED(sc.Float), 0, FRACUNIT);
|
||||
// bComplex is not set because it is only needed when the style is not OP_COPY.
|
||||
}
|
||||
else if (sc.Compare("style"))
|
||||
{
|
||||
static const char *styles[] = {"copy", "blend", "add", "subtract", "reversesubtract", "modulate", "copyalpha", NULL };
|
||||
sc.MustGetString();
|
||||
part.op = sc.MustMatchString(styles);
|
||||
bTranslucentPatches = bComplex = (part.op != OP_COPY);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Mirror & 2)
|
||||
|
@ -995,7 +1035,7 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part)
|
|||
|
||||
|
||||
FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, int usetype)
|
||||
: Pixels (0), Spans(0), Parts(0), bRedirect(false)
|
||||
: Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false)
|
||||
{
|
||||
TArray<TexPart> parts;
|
||||
|
||||
|
|
|
@ -462,13 +462,13 @@ int FPCXTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo
|
|||
c=0x0c; // Apparently there's many non-compliant PCXs out there...
|
||||
if (c !=0x0c)
|
||||
{
|
||||
for(int i=0;i<256;i++) pe[i]=PalEntry(0,i,i,i); // default to a gray map
|
||||
for(int i=0;i<256;i++) pe[i]=PalEntry(255,i,i,i); // default to a gray map
|
||||
}
|
||||
else for(int i=0;i<256;i++)
|
||||
{
|
||||
BYTE r,g,b;
|
||||
lump >> r >> g >> b;
|
||||
pe[i] = PalEntry(r,g,b);
|
||||
pe[i] = PalEntry(255, r,g,b);
|
||||
}
|
||||
lump.Seek(sizeof(header), SEEK_SET);
|
||||
ReadPCX8bits (Pixels, lump, &header);
|
||||
|
|
|
@ -511,7 +511,7 @@ int FPNGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo
|
|||
}
|
||||
|
||||
lump->Seek (33, SEEK_SET);
|
||||
for(int i=0;i<256;i++) pe[i]=PalEntry(0,i,i,i); // default to a gray map
|
||||
for(int i=0;i<256;i++) pe[i]=PalEntry(255,i,i,i); // default to a gray map
|
||||
|
||||
(*lump) >> len >> id;
|
||||
while (id != MAKE_ID('I','D','A','T') && id != MAKE_ID('I','E','N','D'))
|
||||
|
@ -534,7 +534,6 @@ int FPNGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo
|
|||
for(DWORD i=0;i<len;i++)
|
||||
{
|
||||
(*lump) >> pe[i].a;
|
||||
pe[i].a=255-pe[i].a; // use inverse alpha so the default palette can be used unchanged
|
||||
if (pe[i].a!=0 && pe[i].a!=255) transpal = true;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -483,20 +483,16 @@ void FTexture::FillBuffer(BYTE *buff, int pitch, int height, FTextureFormat fmt)
|
|||
int FTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf)
|
||||
{
|
||||
PalEntry *palette = screen->GetPalette();
|
||||
palette[0].a=255; // temporarily modify the first color's alpha
|
||||
for(int i=1;i<256;i++) palette[i].a = 255; // set proper alpha values
|
||||
bmp->CopyPixelData(x, y, GetPixels(), Width, Height, Height, 1, rotate, palette, inf);
|
||||
|
||||
palette[0].a=0;
|
||||
for(int i=1;i<256;i++) palette[i].a = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FTexture::CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, FRemapTable *remap)
|
||||
int FTexture::CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, FRemapTable *remap, FCopyInfo *inf)
|
||||
{
|
||||
PalEntry *palette = remap->Palette;
|
||||
palette[0].a=255; // temporarily modify the first color's alpha
|
||||
bmp->CopyPixelData(x, y, GetPixels(), Width, Height, Height, 1, rotate, palette);
|
||||
|
||||
palette[0].a=0;
|
||||
bmp->CopyPixelData(x, y, GetPixels(), Width, Height, Height, 1, rotate, palette, inf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -436,7 +436,7 @@ int FTGATexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo
|
|||
r=g=b=a=0;
|
||||
break;
|
||||
}
|
||||
pe[i] = PalEntry(255-a, r, g, b);
|
||||
pe[i] = PalEntry(a, r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -506,7 +506,7 @@ int FTGATexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo
|
|||
switch (hdr.bpp)
|
||||
{
|
||||
case 8:
|
||||
for(int i=0;i<256;i++) pe[i]=PalEntry(0,i,i,i); // gray map
|
||||
for(int i=0;i<256;i++) pe[i]=PalEntry(255,i,i,i); // gray map
|
||||
bmp->CopyPixelData(x, y, ptr, Width, Height, step_x, Pitch, rotate, pe, inf);
|
||||
break;
|
||||
|
||||
|
|
|
@ -1283,11 +1283,11 @@ static void ActorStates (FScanner &sc, AActor *defaults, Baggage &bag)
|
|||
static void ActorRenderStyle (FScanner &sc, AActor *defaults, Baggage &bag)
|
||||
{
|
||||
static const char * renderstyles[]={
|
||||
"NONE","NORMAL","FUZZY","SOULTRANS","OPTFUZZY","STENCIL","TRANSLUCENT", "ADD",NULL};
|
||||
"NONE","NORMAL","FUZZY","SOULTRANS","OPTFUZZY","STENCIL","TRANSLUCENT", "ADD","SHADED", NULL};
|
||||
|
||||
static const int renderstyle_values[]={
|
||||
STYLE_None, STYLE_Normal, STYLE_Fuzzy, STYLE_SoulTrans, STYLE_OptFuzzy,
|
||||
STYLE_TranslucentStencil, STYLE_Translucent, STYLE_Add};
|
||||
STYLE_TranslucentStencil, STYLE_Translucent, STYLE_Add, STYLE_Shaded};
|
||||
|
||||
sc.MustGetString();
|
||||
defaults->RenderStyle = LegacyRenderStyles[renderstyle_values[sc.MustMatchString(renderstyles)]];
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "timidity.h"
|
||||
#include "m_swap.h"
|
||||
#include "files.h"
|
||||
#include "templates.h"
|
||||
|
||||
namespace Timidity
|
||||
{
|
||||
|
@ -359,6 +360,7 @@ fail:
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* seashore.pat in the Midia patch set has no Sustain. I don't
|
||||
understand why, and fixing it by adding the Sustain flag to
|
||||
all looped patches probably breaks something else. We do it
|
||||
|
@ -411,11 +413,13 @@ fail:
|
|||
cmsg(CMSG_INFO, VERB_DEBUG, " - No sustain, removing envelope\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (j = 0; j < 6; j++)
|
||||
{
|
||||
sp->envelope_rate[j] = convert_envelope_rate(song, patch_data.EnvelopeRate[j]);
|
||||
sp->envelope_offset[j] = convert_envelope_offset(patch_data.EnvelopeOffset[j]);
|
||||
// GF1NEW clamps the offsets to the range [5,251], so we do too.
|
||||
sp->envelope_offset[j] = convert_envelope_offset(clamp<BYTE>(patch_data.EnvelopeOffset[j], 5, 251));
|
||||
}
|
||||
|
||||
/* Then read the sample data */
|
||||
|
|
|
@ -38,25 +38,24 @@ int recompute_envelope(Voice *v)
|
|||
|
||||
stage = v->envelope_stage;
|
||||
|
||||
if (stage > RELEASEC)
|
||||
if (stage >= ENVELOPES)
|
||||
{
|
||||
/* Envelope ran out. */
|
||||
v->status = VOICE_FREE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (v->sample->modes & PATCH_NO_SRELEASE)
|
||||
{
|
||||
if (v->status == VOICE_ON || v->status == VOICE_SUSTAINED)
|
||||
{
|
||||
if (stage > DECAY)
|
||||
{
|
||||
/* Freeze envelope until note turns off. Trumpets want this. */
|
||||
/* play sampled release */
|
||||
v->status &= ~(VOICE_SUSTAINING | VOICE_LPE);
|
||||
v->status |= VOICE_RELEASING;
|
||||
v->envelope_increment = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (stage == RELEASE && !(v->status & VOICE_RELEASING) && (v->sample->modes & PATCH_SUSTAIN))
|
||||
{
|
||||
v->status |= VOICE_SUSTAINING;
|
||||
/* Freeze envelope until note turns off. Trumpets want this. */
|
||||
v->envelope_increment = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
v->envelope_stage = stage + 1;
|
||||
|
||||
if (v->envelope_volume == v->sample->envelope_offset[stage])
|
||||
|
@ -67,6 +66,8 @@ int recompute_envelope(Voice *v)
|
|||
v->envelope_increment = v->sample->envelope_rate[stage];
|
||||
if (v->envelope_target < v->envelope_volume)
|
||||
v->envelope_increment = -v->envelope_increment;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -78,10 +79,7 @@ void apply_envelope_to_amp(Voice *v)
|
|||
{
|
||||
env_vol *= v->tremolo_volume;
|
||||
}
|
||||
if (v->sample->modes & PATCH_NO_SRELEASE)
|
||||
{
|
||||
env_vol *= v->envelope_volume / float(1 << 30);
|
||||
}
|
||||
// Note: The pan offsets are negative.
|
||||
v->left_mix = MAX(0.f, (float)calc_gf1_amp(env_vol + v->left_offset) * final_amp);
|
||||
v->right_mix = MAX(0.f, (float)calc_gf1_amp(env_vol + v->right_offset) * final_amp);
|
||||
|
@ -426,13 +424,13 @@ void mix_voice(Renderer *song, float *buf, Voice *v, int c)
|
|||
{
|
||||
return;
|
||||
}
|
||||
if (v->status == VOICE_DIE)
|
||||
if (v->status & VOICE_STOPPING)
|
||||
{
|
||||
if (count >= MAX_DIE_TIME)
|
||||
count = MAX_DIE_TIME;
|
||||
sp = resample_voice(song, v, &count);
|
||||
ramp_out(sp, buf, v, count);
|
||||
v->status = VOICE_FREE;
|
||||
v->status = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -37,7 +37,7 @@ void Renderer::reset_voices()
|
|||
{
|
||||
for (int i = 0; i < voices; i++)
|
||||
{
|
||||
voice[i].status = VOICE_FREE;
|
||||
voice[i].status = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ void Renderer::kill_key_group(int i)
|
|||
}
|
||||
while (j--)
|
||||
{
|
||||
if (voice[j].status != VOICE_ON && voice[j].status != VOICE_SUSTAINED) continue;
|
||||
if ((voice[j].status & VOICE_RUNNING) && !(voice[j].status & (VOICE_RELEASING | VOICE_STOPPING))) continue;
|
||||
if (i == j) continue;
|
||||
if (voice[i].channel != voice[j].channel) continue;
|
||||
if (voice[j].sample->key_group != voice[i].sample->key_group) continue;
|
||||
|
@ -273,6 +273,7 @@ void Renderer::start_note(int chan, int note, int vel, int i)
|
|||
Instrument *ip;
|
||||
int bank = channel[chan].bank;
|
||||
int prog = channel[chan].program;
|
||||
Voice *v = &voice[i];
|
||||
|
||||
if (ISDRUMCHANNEL(chan))
|
||||
{
|
||||
|
@ -301,66 +302,71 @@ void Renderer::start_note(int chan, int note, int vel, int i)
|
|||
}
|
||||
if (ip->sample->scale_factor != 1024)
|
||||
{
|
||||
voice[i].orig_frequency = calculate_scaled_frequency(ip->sample, note & 0x7F);
|
||||
v->orig_frequency = calculate_scaled_frequency(ip->sample, note & 0x7F);
|
||||
}
|
||||
else
|
||||
{
|
||||
voice[i].orig_frequency = note_to_freq(note & 0x7F);
|
||||
v->orig_frequency = note_to_freq(note & 0x7F);
|
||||
}
|
||||
select_sample(i, ip, vel);
|
||||
|
||||
voice[i].status = VOICE_ON;
|
||||
voice[i].channel = chan;
|
||||
voice[i].note = note;
|
||||
voice[i].velocity = vel;
|
||||
voice[i].sample_offset = 0;
|
||||
voice[i].sample_increment = 0; /* make sure it isn't negative */
|
||||
v->status = VOICE_RUNNING;
|
||||
v->channel = chan;
|
||||
v->note = note;
|
||||
v->velocity = vel;
|
||||
v->sample_offset = 0;
|
||||
v->sample_increment = 0; /* make sure it isn't negative */
|
||||
|
||||
voice[i].tremolo_phase = 0;
|
||||
voice[i].tremolo_phase_increment = voice[i].sample->tremolo_phase_increment;
|
||||
voice[i].tremolo_sweep = voice[i].sample->tremolo_sweep_increment;
|
||||
voice[i].tremolo_sweep_position = 0;
|
||||
v->tremolo_phase = 0;
|
||||
v->tremolo_phase_increment = voice[i].sample->tremolo_phase_increment;
|
||||
v->tremolo_sweep = voice[i].sample->tremolo_sweep_increment;
|
||||
v->tremolo_sweep_position = 0;
|
||||
|
||||
voice[i].vibrato_sweep = voice[i].sample->vibrato_sweep_increment;
|
||||
voice[i].vibrato_sweep_position = 0;
|
||||
voice[i].vibrato_control_ratio = voice[i].sample->vibrato_control_ratio;
|
||||
voice[i].vibrato_control_counter = voice[i].vibrato_phase = 0;
|
||||
v->vibrato_sweep = voice[i].sample->vibrato_sweep_increment;
|
||||
v->vibrato_sweep_position = 0;
|
||||
v->vibrato_control_ratio = voice[i].sample->vibrato_control_ratio;
|
||||
v->vibrato_control_counter = voice[i].vibrato_phase = 0;
|
||||
|
||||
kill_key_group(i);
|
||||
|
||||
memset(voice[i].vibrato_sample_increment, 0, sizeof(voice[i].vibrato_sample_increment));
|
||||
memset(v->vibrato_sample_increment, 0, sizeof(v->vibrato_sample_increment));
|
||||
|
||||
if (channel[chan].panning != NO_PANNING)
|
||||
{
|
||||
voice[i].left_offset = channel[chan].left_offset;
|
||||
voice[i].right_offset = channel[chan].right_offset;
|
||||
v->left_offset = channel[chan].left_offset;
|
||||
v->right_offset = channel[chan].right_offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
voice[i].left_offset = voice[i].sample->left_offset;
|
||||
voice[i].right_offset = voice[i].sample->right_offset;
|
||||
v->left_offset = v->sample->left_offset;
|
||||
v->right_offset = v->sample->right_offset;
|
||||
}
|
||||
|
||||
recompute_freq(i);
|
||||
recompute_amp(&voice[i]);
|
||||
if (voice[i].sample->modes & PATCH_NO_SRELEASE)
|
||||
{
|
||||
recompute_amp(v);
|
||||
|
||||
/* Ramp up from 0 */
|
||||
voice[i].envelope_stage = ATTACK;
|
||||
voice[i].envelope_volume = 0;
|
||||
voice[i].control_counter = 0;
|
||||
recompute_envelope(&voice[i]);
|
||||
}
|
||||
else
|
||||
v->envelope_stage = ATTACK;
|
||||
v->envelope_volume = 0;
|
||||
v->control_counter = 0;
|
||||
recompute_envelope(v);
|
||||
apply_envelope_to_amp(v);
|
||||
|
||||
if (v->sample->modes & PATCH_LOOPEN)
|
||||
{
|
||||
voice[i].envelope_increment = 0;
|
||||
v->status |= VOICE_LPE;
|
||||
}
|
||||
apply_envelope_to_amp(&voice[i]);
|
||||
}
|
||||
|
||||
void Renderer::kill_note(int i)
|
||||
{
|
||||
voice[i].status = VOICE_DIE;
|
||||
Voice *v = &voice[i];
|
||||
|
||||
if (v->status & VOICE_RUNNING)
|
||||
{
|
||||
v->status &= ~VOICE_SUSTAINING;
|
||||
v->status |= VOICE_RELEASING | VOICE_STOPPING;
|
||||
}
|
||||
}
|
||||
|
||||
/* Only one instance of a note can be playing on a single channel. */
|
||||
|
@ -377,14 +383,21 @@ void Renderer::note_on(int chan, int note, int vel)
|
|||
|
||||
while (i--)
|
||||
{
|
||||
if (voice[i].status == VOICE_FREE)
|
||||
if (!(voice[i].status & VOICE_RUNNING))
|
||||
{
|
||||
lowest = i; /* Can't get a lower volume than silence */
|
||||
}
|
||||
else if (voice[i].channel == chan && ((voice[i].note == note && !voice[i].sample->self_nonexclusive) || channel[chan].mono))
|
||||
{
|
||||
if (channel[chan].mono)
|
||||
{
|
||||
kill_note(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
finish_note(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lowest != -1)
|
||||
|
@ -400,7 +413,7 @@ void Renderer::note_on(int chan, int note, int vel)
|
|||
i = voices;
|
||||
while (i--)
|
||||
{
|
||||
if (voice[i].status != VOICE_ON && voice[i].status != VOICE_DIE)
|
||||
if ((voice[i].status & VOICE_RELEASING) && !(voice[i].status & VOICE_STOPPING))
|
||||
{
|
||||
v = voice[i].attenuation;
|
||||
if (v < lv)
|
||||
|
@ -420,7 +433,7 @@ void Renderer::note_on(int chan, int note, int vel)
|
|||
we could use a reserve of voices to play dying notes only. */
|
||||
|
||||
cut_notes++;
|
||||
voice[lowest].status = VOICE_FREE;
|
||||
voice[lowest].status = 0;
|
||||
start_note(chan, note, vel, lowest);
|
||||
}
|
||||
else
|
||||
|
@ -431,44 +444,54 @@ void Renderer::note_on(int chan, int note, int vel)
|
|||
|
||||
void Renderer::finish_note(int i)
|
||||
{
|
||||
if (voice[i].sample->modes & PATCH_NO_SRELEASE)
|
||||
Voice *v = &voice[i];
|
||||
|
||||
if ((v->status & (VOICE_RUNNING | VOICE_RELEASING)) == VOICE_RUNNING)
|
||||
{
|
||||
/* We need to get the envelope out of Sustain stage */
|
||||
voice[i].envelope_stage = RELEASE;
|
||||
voice[i].status = VOICE_OFF;
|
||||
recompute_envelope(&voice[i]);
|
||||
apply_envelope_to_amp(&voice[i]);
|
||||
v->status &= ~VOICE_SUSTAINING;
|
||||
v->status |= VOICE_RELEASING;
|
||||
|
||||
if (!(v->sample->modes & PATCH_NO_SRELEASE))
|
||||
{
|
||||
v->status &= ~VOICE_LPE; /* sampled release */
|
||||
}
|
||||
else
|
||||
if (!(v->sample->modes & PATCH_NO_SRELEASE) || (v->sample->modes & PATCH_FAST_REL))
|
||||
{
|
||||
/* Set status to OFF so resample_voice() will let this voice out
|
||||
of its loop, if any. In any case, this voice dies when it
|
||||
hits the end of its data (ofs >= data_length). */
|
||||
voice[i].status = VOICE_OFF;
|
||||
/* ramp out to minimum volume with rate from final release stage */
|
||||
v->envelope_stage = RELEASEC;
|
||||
recompute_envelope(v);
|
||||
// Get rate from the final release ramp, but force the target to 0.
|
||||
v->envelope_target = 0;
|
||||
v->envelope_increment = -v->sample->envelope_rate[RELEASEC];
|
||||
}
|
||||
else if (v->sample->modes & PATCH_SUSTAIN)
|
||||
{
|
||||
if (v->envelope_stage < RELEASE)
|
||||
{
|
||||
v->envelope_stage = RELEASE;
|
||||
}
|
||||
recompute_envelope(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::note_off(int chan, int note, int vel)
|
||||
{
|
||||
int i = voices;
|
||||
while (i--)
|
||||
int i;
|
||||
|
||||
for (i = voices; i-- > 0; )
|
||||
{
|
||||
if (voice[i].status == VOICE_ON &&
|
||||
voice[i].channel == chan &&
|
||||
voice[i].note == note)
|
||||
if ((voice[i].status & VOICE_RUNNING) && !(voice[i].status & (VOICE_RELEASING | VOICE_STOPPING))
|
||||
&& voice[i].channel == chan && voice[i].note == note)
|
||||
{
|
||||
if (channel[chan].sustain)
|
||||
{
|
||||
voice[i].status = VOICE_SUSTAINED;
|
||||
voice[i].status |= NOTE_SUSTAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
finish_note(i);
|
||||
}
|
||||
if (!voice[i].sample->self_nonexclusive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -479,11 +502,11 @@ void Renderer::all_notes_off(int chan)
|
|||
int i = voices;
|
||||
while (i--)
|
||||
{
|
||||
if (voice[i].status == VOICE_ON && voice[i].channel == chan)
|
||||
if ((voice[i].status & VOICE_RUNNING) && voice[i].channel == chan)
|
||||
{
|
||||
if (channel[chan].sustain)
|
||||
{
|
||||
voice[i].status = VOICE_SUSTAINED;
|
||||
voice[i].status |= NOTE_SUSTAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -500,8 +523,8 @@ void Renderer::all_sounds_off(int chan)
|
|||
while (i--)
|
||||
{
|
||||
if (voice[i].channel == chan &&
|
||||
voice[i].status != VOICE_FREE &&
|
||||
voice[i].status != VOICE_DIE)
|
||||
(voice[i].status & VOICE_RUNNING) &&
|
||||
!(voice[i].status & VOICE_STOPPING))
|
||||
{
|
||||
kill_note(i);
|
||||
}
|
||||
|
@ -513,7 +536,7 @@ void Renderer::adjust_pressure(int chan, int note, int amount)
|
|||
int i = voices;
|
||||
while (i--)
|
||||
{
|
||||
if (voice[i].status == VOICE_ON &&
|
||||
if ((voice[i].status & VOICE_RUNNING) &&
|
||||
voice[i].channel == chan &&
|
||||
voice[i].note == note)
|
||||
{
|
||||
|
@ -535,8 +558,7 @@ void Renderer::adjust_panning(int chan)
|
|||
int i = voices;
|
||||
while (i--)
|
||||
{
|
||||
if ((voice[i].channel == chan) &&
|
||||
(voice[i].status == VOICE_ON || voice[i].status == VOICE_SUSTAINED))
|
||||
if ((voice[i].channel == chan) && (voice[i].status & VOICE_RUNNING))
|
||||
{
|
||||
voice[i].left_offset = chanp->left_offset;
|
||||
voice[i].right_offset = chanp->right_offset;
|
||||
|
@ -550,7 +572,7 @@ void Renderer::drop_sustain(int chan)
|
|||
int i = voices;
|
||||
while (i--)
|
||||
{
|
||||
if (voice[i].status == VOICE_SUSTAINED && voice[i].channel == chan)
|
||||
if (voice[i].channel == chan && (voice[i].status & NOTE_SUSTAIN))
|
||||
{
|
||||
finish_note(i);
|
||||
}
|
||||
|
@ -562,7 +584,7 @@ void Renderer::adjust_pitchbend(int chan)
|
|||
int i = voices;
|
||||
while (i--)
|
||||
{
|
||||
if (voice[i].status != VOICE_FREE && voice[i].channel == chan)
|
||||
if ((voice[i].status & VOICE_RUNNING) && voice[i].channel == chan)
|
||||
{
|
||||
recompute_freq(i);
|
||||
}
|
||||
|
@ -574,8 +596,7 @@ void Renderer::adjust_volume(int chan)
|
|||
int i = voices;
|
||||
while (i--)
|
||||
{
|
||||
if (voice[i].channel == chan &&
|
||||
(voice[i].status == VOICE_ON || voice[i].status == VOICE_SUSTAINED))
|
||||
if (voice[i].channel == chan && (voice[i].status & VOICE_RUNNING))
|
||||
{
|
||||
recompute_amp(&voice[i]);
|
||||
apply_envelope_to_amp(&voice[i]);
|
||||
|
|
|
@ -81,7 +81,7 @@ static sample_t *rs_plain(sample_t *resample_buffer, Voice *v, int *countptr)
|
|||
if (ofs >= le)
|
||||
{
|
||||
FINALINTERP;
|
||||
v->status = VOICE_FREE;
|
||||
v->status = 0;
|
||||
*countptr -= count + 1;
|
||||
}
|
||||
|
||||
|
@ -309,7 +309,7 @@ static sample_t *rs_vib_plain(sample_t *resample_buffer, float rate, Voice *vp,
|
|||
if (ofs >= le)
|
||||
{
|
||||
FINALINTERP;
|
||||
vp->status = VOICE_FREE;
|
||||
vp->status = 0;
|
||||
*countptr -= count+1;
|
||||
break;
|
||||
}
|
||||
|
@ -494,7 +494,7 @@ sample_t *resample_voice(Renderer *song, Voice *vp, int *countptr)
|
|||
if (*countptr >= (vp->sample->data_length >> FRACTION_BITS) - ofs)
|
||||
{
|
||||
/* Note finished. Free the voice. */
|
||||
vp->status = VOICE_FREE;
|
||||
vp->status = 0;
|
||||
|
||||
/* Let the caller know how much data we had left */
|
||||
*countptr = (vp->sample->data_length >> FRACTION_BITS) - ofs;
|
||||
|
@ -511,9 +511,7 @@ sample_t *resample_voice(Renderer *song, Voice *vp, int *countptr)
|
|||
|
||||
if (vp->vibrato_control_ratio)
|
||||
{
|
||||
if ((modes & PATCH_LOOPEN) &&
|
||||
((modes & PATCH_NO_SRELEASE) ||
|
||||
(vp->status == VOICE_ON || vp->status == VOICE_SUSTAINED)))
|
||||
if (vp->status & VOICE_LPE)
|
||||
{
|
||||
if (modes & PATCH_BIDIR)
|
||||
return rs_vib_bidir(song->resample_buffer, song->rate, vp, *countptr);
|
||||
|
@ -527,9 +525,7 @@ sample_t *resample_voice(Renderer *song, Voice *vp, int *countptr)
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((modes & PATCH_LOOPEN) &&
|
||||
((modes & PATCH_NO_SRELEASE) ||
|
||||
(vp->status == VOICE_ON || vp->status == VOICE_SUSTAINED)))
|
||||
if (vp->status & VOICE_LPE)
|
||||
{
|
||||
if (modes & PATCH_BIDIR)
|
||||
return rs_bidir(song->resample_buffer, vp, *countptr);
|
||||
|
|
|
@ -500,7 +500,7 @@ void Renderer::ComputeOutput(float *buffer, int count)
|
|||
}
|
||||
for (int i = 0; i < voices; i++, v++)
|
||||
{
|
||||
if (v->status != VOICE_FREE)
|
||||
if (v->status & VOICE_RUNNING)
|
||||
{
|
||||
mix_voice(this, buffer, v, count);
|
||||
}
|
||||
|
|
|
@ -315,8 +315,8 @@ struct GF1PatchData
|
|||
int RootFrequency;
|
||||
SWORD Tune;
|
||||
BYTE Balance;
|
||||
BYTE EnvelopeRate[6];
|
||||
BYTE EnvelopeOffset[6];
|
||||
BYTE EnvelopeRate[ENVELOPES];
|
||||
BYTE EnvelopeOffset[ENVELOPES];
|
||||
BYTE TremoloSweep;
|
||||
BYTE TremoloRate;
|
||||
BYTE TremoloDepth;
|
||||
|
@ -444,7 +444,7 @@ struct Channel
|
|||
{
|
||||
int
|
||||
bank, program, sustain, pitchbend,
|
||||
mono, /* one note only on this channel -- not implemented yet */
|
||||
mono, /* one note only on this channel */
|
||||
pitchsens;
|
||||
WORD
|
||||
volume, expression;
|
||||
|
@ -462,8 +462,6 @@ struct Channel
|
|||
|
||||
/* Causes the instrument's default panning to be used. */
|
||||
#define NO_PANNING -1
|
||||
/* envelope points */
|
||||
#define MAXPOINT 6
|
||||
|
||||
struct Voice
|
||||
{
|
||||
|
@ -496,11 +494,13 @@ struct Voice
|
|||
/* Voice status options: */
|
||||
enum
|
||||
{
|
||||
VOICE_FREE,
|
||||
VOICE_ON,
|
||||
VOICE_SUSTAINED,
|
||||
VOICE_OFF,
|
||||
VOICE_DIE
|
||||
VOICE_RUNNING = (1<<0),
|
||||
VOICE_SUSTAINING = (1<<1),
|
||||
VOICE_RELEASING = (1<<2),
|
||||
VOICE_STOPPING = (1<<3),
|
||||
|
||||
VOICE_LPE = (1<<4),
|
||||
NOTE_SUSTAIN = (1<<5),
|
||||
};
|
||||
|
||||
/* Envelope stages: */
|
||||
|
|
|
@ -77,7 +77,7 @@
|
|||
// SAVESIG should match SAVEVER.
|
||||
|
||||
// MINSAVEVER is the minimum level snapshot version that can be loaded.
|
||||
#define MINSAVEVER 922
|
||||
#define MINSAVEVER 932
|
||||
|
||||
#if ZD_SVN_REVISION_NUMBER < MINSAVEVER
|
||||
// Never write a savegame with a version lower than what we need
|
||||
|
|
|
@ -47,11 +47,11 @@ typedef struct wbstartstruct_s
|
|||
int finished_ep;
|
||||
int next_ep;
|
||||
|
||||
char current[8]; // [RH] Name of map just finished
|
||||
char next[8]; // next level, [RH] actual map name
|
||||
char current[9]; // [RH] Name of map just finished
|
||||
char next[9]; // next level, [RH] actual map name
|
||||
|
||||
char lname0[8];
|
||||
char lname1[8];
|
||||
char lname0[9];
|
||||
char lname1[9];
|
||||
|
||||
int maxkills;
|
||||
int maxitems;
|
||||
|
|
|
@ -2086,13 +2086,13 @@ bool D3DPal::Update()
|
|||
|
||||
for (i = 0; i < skipat; ++i)
|
||||
{
|
||||
buff[i] = D3DCOLOR_ARGB(i == 0 ? 0 : 255, 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(255, pal[i-1].r, pal[i-1].g, pal[i-1].b);
|
||||
buff[i] = D3DCOLOR_ARGB(pal[i].a, pal[i-1].r, pal[i-1].g, pal[i-1].b);
|
||||
}
|
||||
BorderColor = D3DCOLOR_ARGB(255, pal[i-1].r, pal[i-1].g, pal[i-1].b);
|
||||
BorderColor = D3DCOLOR_ARGB(pal[i].a, pal[i-1].r, pal[i-1].g, pal[i-1].b);
|
||||
|
||||
Tex->UnlockRect(0);
|
||||
return true;
|
||||
|
|
|
@ -202,6 +202,13 @@ weapons/bfgf dsbfg
|
|||
weapons/bfgx dsrxplod
|
||||
weapons/railgf railgf1
|
||||
|
||||
// Problem: weapons/rocklx needs to be unlimited but
|
||||
// is also used for the MAP30 brain explosion.
|
||||
// This alias remaps to the original but has its own limit
|
||||
// attached so that it doesn't become too loud.
|
||||
$alias misc/brainexplode weapons/rocklx
|
||||
$limit misc/brainexplode 4
|
||||
|
||||
$limit weapons/plasmaf 0
|
||||
$limit weapons/chngun 0
|
||||
$limit weapons/rocklf 0 // because normal running is almost as fast as a rocket
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue