mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-05-08 01:00:50 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
This commit is contained in:
commit
3bad7f9b55
31 changed files with 282 additions and 244 deletions
|
@ -221,7 +221,11 @@ enum
|
||||||
WF_WEAPONRELOADOK = 1 << 5, // [XA] Okay to reload this weapon.
|
WF_WEAPONRELOADOK = 1 << 5, // [XA] Okay to reload this weapon.
|
||||||
WF_WEAPONZOOMOK = 1 << 6, // [XA] Okay to use weapon zoom function.
|
WF_WEAPONZOOMOK = 1 << 6, // [XA] Okay to use weapon zoom function.
|
||||||
WF_REFIRESWITCHOK = 1 << 7, // Mirror WF_WEAPONSWITCHOK for A_ReFire
|
WF_REFIRESWITCHOK = 1 << 7, // Mirror WF_WEAPONSWITCHOK for A_ReFire
|
||||||
};
|
WF_USER1OK = 1 << 8, // [MC] Allow pushing of custom state buttons 1-4
|
||||||
|
WF_USER2OK = 1 << 9,
|
||||||
|
WF_USER3OK = 1 << 10,
|
||||||
|
WF_USER4OK = 1 << 11,
|
||||||
|
};
|
||||||
|
|
||||||
#define WPIECE1 1
|
#define WPIECE1 1
|
||||||
#define WPIECE2 2
|
#define WPIECE2 2
|
||||||
|
@ -405,7 +409,7 @@ public:
|
||||||
int lastkilltime; // [RH] For multikills
|
int lastkilltime; // [RH] For multikills
|
||||||
BYTE multicount;
|
BYTE multicount;
|
||||||
BYTE spreecount; // [RH] Keep track of killing sprees
|
BYTE spreecount; // [RH] Keep track of killing sprees
|
||||||
BYTE WeaponState;
|
WORD WeaponState;
|
||||||
|
|
||||||
AWeapon *ReadyWeapon;
|
AWeapon *ReadyWeapon;
|
||||||
AWeapon *PendingWeapon; // WP_NOCHANGE if not changing
|
AWeapon *PendingWeapon; // WP_NOCHANGE if not changing
|
||||||
|
|
|
@ -305,8 +305,7 @@ public:
|
||||||
virtual FState *GetReadyState ();
|
virtual FState *GetReadyState ();
|
||||||
virtual FState *GetAtkState (bool hold);
|
virtual FState *GetAtkState (bool hold);
|
||||||
virtual FState *GetAltAtkState (bool hold);
|
virtual FState *GetAltAtkState (bool hold);
|
||||||
virtual FState *GetRelState ();
|
virtual FState *GetStateForButtonName (FName button);
|
||||||
virtual FState *GetZoomState ();
|
|
||||||
|
|
||||||
virtual void PostMorphWeapon ();
|
virtual void PostMorphWeapon ();
|
||||||
virtual void EndPowerup ();
|
virtual void EndPowerup ();
|
||||||
|
|
|
@ -683,25 +683,15 @@ FState *AWeapon::GetAltAtkState (bool hold)
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// AWeapon :: GetRelState
|
// AWeapon :: GetStateForButtonName
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
FState *AWeapon::GetRelState ()
|
FState *AWeapon::GetStateForButtonName (FName button)
|
||||||
{
|
{
|
||||||
return FindState(NAME_Reload);
|
return FindState(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// AWeapon :: GetZoomState
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
FState *AWeapon::GetZoomState ()
|
|
||||||
{
|
|
||||||
return FindState(NAME_Zoom);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Weapon giver ***********************************************************/
|
/* Weapon giver ***********************************************************/
|
||||||
|
|
||||||
|
|
|
@ -221,6 +221,10 @@ xx(Flash)
|
||||||
xx(AltFlash)
|
xx(AltFlash)
|
||||||
xx(Reload)
|
xx(Reload)
|
||||||
xx(Zoom)
|
xx(Zoom)
|
||||||
|
xx(User1)
|
||||||
|
xx(User2)
|
||||||
|
xx(User3)
|
||||||
|
xx(User4)
|
||||||
|
|
||||||
// State names used by ASwitchableDecoration
|
// State names used by ASwitchableDecoration
|
||||||
xx(Active)
|
xx(Active)
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#define HALF_PI (PI*0.5)
|
#define HALF_PI (PI*0.5)
|
||||||
|
|
||||||
EXTERN_CVAR(Int, opl_core)
|
EXTERN_CVAR(Int, opl_core)
|
||||||
|
extern int current_opl_core;
|
||||||
|
|
||||||
OPLio::~OPLio()
|
OPLio::~OPLio()
|
||||||
{
|
{
|
||||||
|
@ -323,7 +324,7 @@ int OPLio::OPLinit(uint numchips, bool stereo, bool initopl3)
|
||||||
{
|
{
|
||||||
assert(numchips >= 1 && numchips <= countof(chips));
|
assert(numchips >= 1 && numchips <= countof(chips));
|
||||||
uint i;
|
uint i;
|
||||||
IsOPL3 = (opl_core == 1 || opl_core == 2 || opl_core == 3);
|
IsOPL3 = (current_opl_core == 1 || current_opl_core == 2 || current_opl_core == 3);
|
||||||
|
|
||||||
memset(chips, 0, sizeof(chips));
|
memset(chips, 0, sizeof(chips));
|
||||||
if (IsOPL3)
|
if (IsOPL3)
|
||||||
|
@ -332,7 +333,7 @@ int OPLio::OPLinit(uint numchips, bool stereo, bool initopl3)
|
||||||
}
|
}
|
||||||
for (i = 0; i < numchips; ++i)
|
for (i = 0; i < numchips; ++i)
|
||||||
{
|
{
|
||||||
OPLEmul *chip = IsOPL3 ? (opl_core == 1 ? DBOPLCreate(stereo) : (opl_core == 2 ? JavaOPLCreate(stereo) : NukedOPL3Create(stereo))) : YM3812Create(stereo);
|
OPLEmul *chip = IsOPL3 ? (current_opl_core == 1 ? DBOPLCreate(stereo) : (current_opl_core == 2 ? JavaOPLCreate(stereo) : NukedOPL3Create(stereo))) : YM3812Create(stereo);
|
||||||
if (chip == NULL)
|
if (chip == NULL)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||||
|
void OPL_SetCore(const char *args);
|
||||||
|
|
||||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||||
|
|
||||||
|
@ -76,8 +77,9 @@ CVAR(Bool, opl_fullpan, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
OPLMIDIDevice::OPLMIDIDevice()
|
OPLMIDIDevice::OPLMIDIDevice(const char *args)
|
||||||
{
|
{
|
||||||
|
OPL_SetCore(args);
|
||||||
FullPan = opl_fullpan;
|
FullPan = opl_fullpan;
|
||||||
FWadLump data = Wads.OpenLumpName("GENMIDI");
|
FWadLump data = Wads.OpenLumpName("GENMIDI");
|
||||||
OPLloadBank(data);
|
OPLloadBank(data);
|
||||||
|
|
|
@ -262,6 +262,7 @@ protected:
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
OPLDumperMIDIDevice::OPLDumperMIDIDevice(const char *filename)
|
OPLDumperMIDIDevice::OPLDumperMIDIDevice(const char *filename)
|
||||||
|
: OPLMIDIDevice(NULL)
|
||||||
{
|
{
|
||||||
// Replace the standard OPL device with a disk writer.
|
// Replace the standard OPL device with a disk writer.
|
||||||
delete io;
|
delete io;
|
||||||
|
|
209
src/p_pspr.cpp
209
src/p_pspr.cpp
|
@ -38,6 +38,30 @@
|
||||||
|
|
||||||
// TYPES -------------------------------------------------------------------
|
// TYPES -------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct FGenericButtons
|
||||||
|
{
|
||||||
|
int ReadyFlag; // Flag passed to A_WeaponReady
|
||||||
|
int StateFlag; // Flag set in WeaponState
|
||||||
|
int ButtonFlag; // Button to press
|
||||||
|
ENamedName StateName; // Name of the button/state
|
||||||
|
};
|
||||||
|
|
||||||
|
enum EWRF_Options
|
||||||
|
{
|
||||||
|
WRF_NoBob = 1,
|
||||||
|
WRF_NoSwitch = 1 << 1,
|
||||||
|
WRF_NoPrimary = 1 << 2,
|
||||||
|
WRF_NoSecondary = 1 << 3,
|
||||||
|
WRF_NoFire = WRF_NoPrimary | WRF_NoSecondary,
|
||||||
|
WRF_AllowReload = 1 << 4,
|
||||||
|
WRF_AllowZoom = 1 << 5,
|
||||||
|
WRF_DisableSwitch = 1 << 6,
|
||||||
|
WRF_AllowUser1 = 1 << 7,
|
||||||
|
WRF_AllowUser2 = 1 << 8,
|
||||||
|
WRF_AllowUser3 = 1 << 9,
|
||||||
|
WRF_AllowUser4 = 1 << 10,
|
||||||
|
};
|
||||||
|
|
||||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||||
|
|
||||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||||
|
@ -57,6 +81,16 @@ CVAR(Int, sv_fastweapons, false, CVAR_SERVERINFO);
|
||||||
static FRandom pr_wpnreadysnd ("WpnReadySnd");
|
static FRandom pr_wpnreadysnd ("WpnReadySnd");
|
||||||
static FRandom pr_gunshot ("GunShot");
|
static FRandom pr_gunshot ("GunShot");
|
||||||
|
|
||||||
|
static const FGenericButtons ButtonChecks[] =
|
||||||
|
{
|
||||||
|
{ WRF_AllowReload, WF_WEAPONZOOMOK, BT_ZOOM, NAME_Zoom },
|
||||||
|
{ WRF_AllowZoom, WF_WEAPONRELOADOK, BT_RELOAD, NAME_Reload },
|
||||||
|
{ WRF_AllowUser1, WF_USER1OK, BT_USER1, NAME_User1 },
|
||||||
|
{ WRF_AllowUser2, WF_USER2OK, BT_USER2, NAME_User2 },
|
||||||
|
{ WRF_AllowUser3, WF_USER3OK, BT_USER3, NAME_User3 },
|
||||||
|
{ WRF_AllowUser4, WF_USER4OK, BT_USER4, NAME_User4 },
|
||||||
|
};
|
||||||
|
|
||||||
// CODE --------------------------------------------------------------------
|
// CODE --------------------------------------------------------------------
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -95,7 +129,8 @@ void P_SetPsprite (player_t *player, int position, FState *state, bool nofunctio
|
||||||
|
|
||||||
if (position == ps_weapon && !nofunction)
|
if (position == ps_weapon && !nofunction)
|
||||||
{ // A_WeaponReady will re-set these as needed
|
{ // A_WeaponReady will re-set these as needed
|
||||||
player->WeaponState &= ~(WF_WEAPONREADY | WF_WEAPONREADYALT | WF_WEAPONBOBBING | WF_WEAPONSWITCHOK | WF_WEAPONRELOADOK | WF_WEAPONZOOMOK);
|
player->WeaponState &= ~(WF_WEAPONREADY | WF_WEAPONREADYALT | WF_WEAPONBOBBING | WF_WEAPONSWITCHOK | WF_WEAPONRELOADOK | WF_WEAPONZOOMOK |
|
||||||
|
WF_USER1OK | WF_USER2OK | WF_USER3OK | WF_USER4OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
psp = &player->psprites[position];
|
psp = &player->psprites[position];
|
||||||
|
@ -289,66 +324,6 @@ void P_FireWeaponAlt (player_t *player, FState *state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// PROC P_ReloadWeapon
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void P_ReloadWeapon (player_t *player, FState *state)
|
|
||||||
{
|
|
||||||
AWeapon *weapon;
|
|
||||||
if (player->Bot == NULL && bot_observer)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
weapon = player->ReadyWeapon;
|
|
||||||
if (weapon == NULL)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == NULL)
|
|
||||||
{
|
|
||||||
state = weapon->GetRelState();
|
|
||||||
}
|
|
||||||
// [XA] don't change state if still null, so if the modder sets
|
|
||||||
// WRF_RELOAD to true but forgets to define the Reload state, the weapon
|
|
||||||
// won't disappear. ;)
|
|
||||||
if (state != NULL)
|
|
||||||
P_SetPsprite (player, ps_weapon, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// PROC P_ZoomWeapon
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void P_ZoomWeapon (player_t *player, FState *state)
|
|
||||||
{
|
|
||||||
AWeapon *weapon;
|
|
||||||
if (player->Bot == NULL && bot_observer)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
weapon = player->ReadyWeapon;
|
|
||||||
if (weapon == NULL)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == NULL)
|
|
||||||
{
|
|
||||||
state = weapon->GetZoomState();
|
|
||||||
}
|
|
||||||
// [XA] don't change state if still null. Same reasons as above.
|
|
||||||
if (state != NULL)
|
|
||||||
P_SetPsprite (player, ps_weapon, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// PROC P_DropWeapon
|
// PROC P_DropWeapon
|
||||||
|
@ -562,22 +537,21 @@ void DoReadyWeaponToBob (AActor *self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoReadyWeaponToReload (AActor *self)
|
void DoReadyWeaponToGeneric(AActor *self, int paramflags)
|
||||||
{
|
{
|
||||||
// Prepare for reload action.
|
int flags = 0;
|
||||||
player_t *player;
|
|
||||||
if (self && (player = self->player))
|
|
||||||
player->WeaponState |= WF_WEAPONRELOADOK;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DoReadyWeaponToZoom (AActor *self)
|
for (size_t i = 0; i < countof(ButtonChecks); ++i)
|
||||||
{
|
{
|
||||||
// Prepare for reload action.
|
if (paramflags & ButtonChecks[i].ReadyFlag)
|
||||||
player_t *player;
|
{
|
||||||
if (self && (player = self->player))
|
flags |= ButtonChecks[i].StateFlag;
|
||||||
player->WeaponState |= WF_WEAPONZOOMOK;
|
}
|
||||||
return;
|
}
|
||||||
|
if (self != NULL && self->player != NULL)
|
||||||
|
{
|
||||||
|
self->player->WeaponState |= flags;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function replaces calls to A_WeaponReady in other codepointers.
|
// This function replaces calls to A_WeaponReady in other codepointers.
|
||||||
|
@ -586,22 +560,9 @@ void DoReadyWeapon(AActor *self)
|
||||||
DoReadyWeaponToBob(self);
|
DoReadyWeaponToBob(self);
|
||||||
DoReadyWeaponToFire(self);
|
DoReadyWeaponToFire(self);
|
||||||
DoReadyWeaponToSwitch(self);
|
DoReadyWeaponToSwitch(self);
|
||||||
DoReadyWeaponToReload(self);
|
DoReadyWeaponToGeneric(self, ~0);
|
||||||
DoReadyWeaponToZoom(self);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum EWRF_Options
|
|
||||||
{
|
|
||||||
WRF_NoBob = 1,
|
|
||||||
WRF_NoSwitch = 2,
|
|
||||||
WRF_NoPrimary = 4,
|
|
||||||
WRF_NoSecondary = 8,
|
|
||||||
WRF_NoFire = WRF_NoPrimary + WRF_NoSecondary,
|
|
||||||
WRF_AllowReload = 16,
|
|
||||||
WRF_AllowZoom = 32,
|
|
||||||
WRF_DisableSwitch = 64,
|
|
||||||
};
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_WeaponReady)
|
DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_WeaponReady)
|
||||||
{
|
{
|
||||||
ACTION_PARAM_START(1);
|
ACTION_PARAM_START(1);
|
||||||
|
@ -610,10 +571,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AInventory, A_WeaponReady)
|
||||||
DoReadyWeaponToSwitch(self, !(paramflags & WRF_NoSwitch));
|
DoReadyWeaponToSwitch(self, !(paramflags & WRF_NoSwitch));
|
||||||
if ((paramflags & WRF_NoFire) != WRF_NoFire) DoReadyWeaponToFire(self, !(paramflags & WRF_NoPrimary), !(paramflags & WRF_NoSecondary));
|
if ((paramflags & WRF_NoFire) != WRF_NoFire) DoReadyWeaponToFire(self, !(paramflags & WRF_NoPrimary), !(paramflags & WRF_NoSecondary));
|
||||||
if (!(paramflags & WRF_NoBob)) DoReadyWeaponToBob(self);
|
if (!(paramflags & WRF_NoBob)) DoReadyWeaponToBob(self);
|
||||||
if ((paramflags & WRF_AllowReload)) DoReadyWeaponToReload(self);
|
DoReadyWeaponToGeneric(self, paramflags);
|
||||||
if ((paramflags & WRF_AllowZoom)) DoReadyWeaponToZoom(self);
|
DoReadyWeaponDisableSwitch(self, paramflags & WRF_DisableSwitch);
|
||||||
|
|
||||||
DoReadyWeaponDisableSwitch(self, paramflags & WRF_DisableSwitch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
@ -690,45 +649,40 @@ void P_CheckWeaponSwitch (player_t *player)
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// PROC P_CheckWeaponReload
|
// PROC P_CheckWeaponButtons
|
||||||
//
|
//
|
||||||
// The player can reload the weapon.
|
// Check extra button presses for weapons.
|
||||||
//
|
//
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void P_CheckWeaponReload (player_t *player)
|
static void P_CheckWeaponButtons (player_t *player)
|
||||||
{
|
{
|
||||||
AWeapon *weapon = player->ReadyWeapon;
|
if (player->Bot == NULL && bot_observer)
|
||||||
|
|
||||||
if (weapon == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Check for reload.
|
|
||||||
if ((player->WeaponState & WF_WEAPONRELOADOK) && (player->cmd.ucmd.buttons & BT_RELOAD))
|
|
||||||
{
|
{
|
||||||
P_ReloadWeapon (player, NULL);
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// PROC P_CheckWeaponZoom
|
|
||||||
//
|
|
||||||
// The player can use the weapon's zoom function.
|
|
||||||
//
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void P_CheckWeaponZoom (player_t *player)
|
|
||||||
{
|
|
||||||
AWeapon *weapon = player->ReadyWeapon;
|
AWeapon *weapon = player->ReadyWeapon;
|
||||||
|
|
||||||
if (weapon == NULL)
|
if (weapon == NULL)
|
||||||
return;
|
|
||||||
|
|
||||||
// Check for zoom.
|
|
||||||
if ((player->WeaponState & WF_WEAPONZOOMOK) && (player->cmd.ucmd.buttons & BT_ZOOM))
|
|
||||||
{
|
{
|
||||||
P_ZoomWeapon (player, NULL);
|
return;
|
||||||
|
}
|
||||||
|
// The button checks are ordered by precedence. The first one to match a
|
||||||
|
// button press and affect a state change wins.
|
||||||
|
for (size_t i = 0; i < countof(ButtonChecks); ++i)
|
||||||
|
{
|
||||||
|
if ((player->WeaponState & ButtonChecks[i].StateFlag) &&
|
||||||
|
(player->cmd.ucmd.buttons & ButtonChecks[i].ButtonFlag))
|
||||||
|
{
|
||||||
|
FState *state = weapon->GetStateForButtonName(ButtonChecks[i].StateName);
|
||||||
|
// [XA] don't change state if still null, so if the modder
|
||||||
|
// sets WRF_xxx to true but forgets to define the corresponding
|
||||||
|
// state, the weapon won't disappear. ;)
|
||||||
|
if (state != NULL)
|
||||||
|
{
|
||||||
|
P_SetPsprite(player, ps_weapon, state);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1095,14 +1049,9 @@ void P_MovePsprites (player_t *player)
|
||||||
{
|
{
|
||||||
P_CheckWeaponFire (player);
|
P_CheckWeaponFire (player);
|
||||||
}
|
}
|
||||||
if (player->WeaponState & WF_WEAPONRELOADOK)
|
|
||||||
{
|
// Check custom buttons
|
||||||
P_CheckWeaponReload (player);
|
P_CheckWeaponButtons(player);
|
||||||
}
|
|
||||||
if (player->WeaponState & WF_WEAPONZOOMOK)
|
|
||||||
{
|
|
||||||
P_CheckWeaponZoom (player);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3043,6 +3043,12 @@ void player_t::Serialize (FArchive &arc)
|
||||||
WeaponState = ((cheats >> 14) & 1) | ((cheats & (0x37 << 24)) >> (24 - 1));
|
WeaponState = ((cheats >> 14) & 1) | ((cheats & (0x37 << 24)) >> (24 - 1));
|
||||||
cheats &= ~((1 << 14) | (0x37 << 24));
|
cheats &= ~((1 << 14) | (0x37 << 24));
|
||||||
}
|
}
|
||||||
|
if (SaveVersion < 4527)
|
||||||
|
{
|
||||||
|
BYTE oldWeaponState;
|
||||||
|
arc << oldWeaponState;
|
||||||
|
WeaponState = oldWeaponState;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
arc << WeaponState;
|
arc << WeaponState;
|
||||||
|
|
|
@ -1364,16 +1364,36 @@ static void S_AddSNDINFO (int lump)
|
||||||
case SI_MidiDevice: {
|
case SI_MidiDevice: {
|
||||||
sc.MustGetString();
|
sc.MustGetString();
|
||||||
FName nm = sc.String;
|
FName nm = sc.String;
|
||||||
|
FScanner::SavedPos save = sc.SavePos();
|
||||||
|
|
||||||
|
sc.SetCMode(true);
|
||||||
sc.MustGetString();
|
sc.MustGetString();
|
||||||
if (sc.Compare("timidity")) MidiDevices[nm] = MDEV_TIMIDITY;
|
MidiDeviceSetting devset;
|
||||||
else if (sc.Compare("fmod") || sc.Compare("sndsys")) MidiDevices[nm] = MDEV_SNDSYS;
|
if (sc.Compare("timidity")) devset.device = MDEV_TIMIDITY;
|
||||||
else if (sc.Compare("standard")) MidiDevices[nm] = MDEV_MMAPI;
|
else if (sc.Compare("fmod") || sc.Compare("sndsys")) devset.device = MDEV_SNDSYS;
|
||||||
else if (sc.Compare("opl")) MidiDevices[nm] = MDEV_OPL;
|
else if (sc.Compare("standard")) devset.device = MDEV_MMAPI;
|
||||||
else if (sc.Compare("default")) MidiDevices[nm] = MDEV_DEFAULT;
|
else if (sc.Compare("opl")) devset.device = MDEV_OPL;
|
||||||
else if (sc.Compare("fluidsynth")) MidiDevices[nm] = MDEV_FLUIDSYNTH;
|
else if (sc.Compare("default")) devset.device = MDEV_DEFAULT;
|
||||||
else if (sc.Compare("gus")) MidiDevices[nm] = MDEV_GUS;
|
else if (sc.Compare("fluidsynth")) devset.device = MDEV_FLUIDSYNTH;
|
||||||
else if (sc.Compare("wildmidi")) MidiDevices[nm] = MDEV_WILDMIDI;
|
else if (sc.Compare("gus")) devset.device = MDEV_GUS;
|
||||||
|
else if (sc.Compare("wildmidi")) devset.device = MDEV_WILDMIDI;
|
||||||
else sc.ScriptError("Unknown MIDI device %s\n", sc.String);
|
else sc.ScriptError("Unknown MIDI device %s\n", sc.String);
|
||||||
|
|
||||||
|
if (sc.CheckString(","))
|
||||||
|
{
|
||||||
|
sc.SetCMode(false);
|
||||||
|
sc.MustGetString();
|
||||||
|
devset.args = sc.String;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This does not really do what one might expect, because the next token has already been parsed and can be a '$'.
|
||||||
|
// So in order to continue parsing without C-Mode, we need to reset and parse the last token again.
|
||||||
|
sc.SetCMode(false);
|
||||||
|
sc.RestorePos(save);
|
||||||
|
sc.MustGetString();
|
||||||
|
}
|
||||||
|
MidiDevices[nm] = devset;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -2421,11 +2421,8 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
|
||||||
{
|
{
|
||||||
int lumpnum = -1;
|
int lumpnum = -1;
|
||||||
int length = 0;
|
int length = 0;
|
||||||
int device = MDEV_DEFAULT;
|
|
||||||
MusInfo *handle = NULL;
|
MusInfo *handle = NULL;
|
||||||
|
MidiDeviceSetting *devp = MidiDevices.CheckKey(musicname);
|
||||||
int *devp = MidiDevices.CheckKey(musicname);
|
|
||||||
if (devp != NULL) device = *devp;
|
|
||||||
|
|
||||||
// Strip off any leading file:// component.
|
// Strip off any leading file:// component.
|
||||||
if (strncmp(musicname, "file://", 7) == 0)
|
if (strncmp(musicname, "file://", 7) == 0)
|
||||||
|
@ -2495,7 +2492,7 @@ bool S_ChangeMusic (const char *musicname, int order, bool looping, bool force)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mus_playing.handle = I_RegisterSong (reader, device);
|
mus_playing.handle = I_RegisterSong (reader, devp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -397,8 +397,19 @@ enum EMidiDevice
|
||||||
MDEV_WILDMIDI = 6,
|
MDEV_WILDMIDI = 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MidiDeviceSetting
|
||||||
|
{
|
||||||
|
int device;
|
||||||
|
FString args;
|
||||||
|
|
||||||
|
MidiDeviceSetting()
|
||||||
|
{
|
||||||
|
device = MDEV_DEFAULT;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
typedef TMap<FName, FName> MusicAliasMap;
|
typedef TMap<FName, FName> MusicAliasMap;
|
||||||
typedef TMap<FName, int> MidiDeviceMap;
|
typedef TMap<FName, MidiDeviceSetting> MidiDeviceMap;
|
||||||
|
|
||||||
extern MusicAliasMap MusicAliases;
|
extern MusicAliasMap MusicAliases;
|
||||||
extern MidiDeviceMap MidiDevices;
|
extern MidiDeviceMap MidiDevices;
|
||||||
|
|
|
@ -311,21 +311,21 @@ MusInfo *MusInfo::GetWaveDumper(const char *filename, int rate)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
static MIDIStreamer *CreateMIDIStreamer(FileReader &reader, EMidiDevice devtype, EMIDIType miditype)
|
static MIDIStreamer *CreateMIDIStreamer(FileReader &reader, EMidiDevice devtype, EMIDIType miditype, const char *args)
|
||||||
{
|
{
|
||||||
switch (miditype)
|
switch (miditype)
|
||||||
{
|
{
|
||||||
case MIDI_MUS:
|
case MIDI_MUS:
|
||||||
return new MUSSong2(reader, devtype);
|
return new MUSSong2(reader, devtype, args);
|
||||||
|
|
||||||
case MIDI_MIDI:
|
case MIDI_MIDI:
|
||||||
return new MIDISong2(reader, devtype);
|
return new MIDISong2(reader, devtype, args);
|
||||||
|
|
||||||
case MIDI_HMI:
|
case MIDI_HMI:
|
||||||
return new HMISong(reader, devtype);
|
return new HMISong(reader, devtype, args);
|
||||||
|
|
||||||
case MIDI_XMI:
|
case MIDI_XMI:
|
||||||
return new XMISong(reader, devtype);
|
return new XMISong(reader, devtype, args);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -387,7 +387,7 @@ static EMIDIType IdentifyMIDIType(DWORD *id, int size)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
MusInfo *I_RegisterSong (FileReader *reader, int device)
|
MusInfo *I_RegisterSong (FileReader *reader, MidiDeviceSetting *device)
|
||||||
{
|
{
|
||||||
MusInfo *info = NULL;
|
MusInfo *info = NULL;
|
||||||
const char *fmt;
|
const char *fmt;
|
||||||
|
@ -405,12 +405,6 @@ MusInfo *I_RegisterSong (FileReader *reader, int device)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
// non-Windows platforms don't support MDEV_MMAPI so map to MDEV_SNDSYS
|
|
||||||
if (device == MDEV_MMAPI)
|
|
||||||
device = MDEV_SNDSYS;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Check for gzip compression. Some formats are expected to have players
|
// Check for gzip compression. Some formats are expected to have players
|
||||||
// that can handle it, so it simplifies things if we make all songs
|
// that can handle it, so it simplifies things if we make all songs
|
||||||
// gzippable.
|
// gzippable.
|
||||||
|
@ -447,10 +441,15 @@ MusInfo *I_RegisterSong (FileReader *reader, int device)
|
||||||
EMIDIType miditype = IdentifyMIDIType(id, sizeof(id));
|
EMIDIType miditype = IdentifyMIDIType(id, sizeof(id));
|
||||||
if (miditype != MIDI_NOTMIDI)
|
if (miditype != MIDI_NOTMIDI)
|
||||||
{
|
{
|
||||||
EMidiDevice devtype = (EMidiDevice)device;
|
EMidiDevice devtype = device == NULL? MDEV_DEFAULT : (EMidiDevice)device->device;
|
||||||
|
#ifndef _WIN32
|
||||||
|
// non-Windows platforms don't support MDEV_MMAPI so map to MDEV_SNDSYS
|
||||||
|
if (devtype == MDEV_MMAPI)
|
||||||
|
devtype = MDEV_SNDSYS;
|
||||||
|
#endif
|
||||||
|
|
||||||
retry_as_sndsys:
|
retry_as_sndsys:
|
||||||
info = CreateMIDIStreamer(*reader, devtype, miditype);
|
info = CreateMIDIStreamer(*reader, devtype, miditype, device != NULL? device->args.GetChars() : "");
|
||||||
if (info != NULL && !info->IsValid())
|
if (info != NULL && !info->IsValid())
|
||||||
{
|
{
|
||||||
delete info;
|
delete info;
|
||||||
|
@ -464,7 +463,7 @@ retry_as_sndsys:
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (info == NULL && devtype != MDEV_MMAPI && snd_mididevice >= 0)
|
if (info == NULL && devtype != MDEV_MMAPI && snd_mididevice >= 0)
|
||||||
{
|
{
|
||||||
info = CreateMIDIStreamer(*reader, MDEV_MMAPI, miditype);
|
info = CreateMIDIStreamer(*reader, MDEV_MMAPI, miditype, "");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -475,7 +474,7 @@ retry_as_sndsys:
|
||||||
(id[0] == MAKE_ID('D','B','R','A') && id[1] == MAKE_ID('W','O','P','L')) || // DosBox Raw OPL
|
(id[0] == MAKE_ID('D','B','R','A') && id[1] == MAKE_ID('W','O','P','L')) || // DosBox Raw OPL
|
||||||
(id[0] == MAKE_ID('A','D','L','I') && *((BYTE *)id + 4) == 'B')) // Martin Fernandez's modified IMF
|
(id[0] == MAKE_ID('A','D','L','I') && *((BYTE *)id + 4) == 'B')) // Martin Fernandez's modified IMF
|
||||||
{
|
{
|
||||||
info = new OPLMUSSong (*reader);
|
info = new OPLMUSSong (*reader, device != NULL? device->args.GetChars() : "");
|
||||||
}
|
}
|
||||||
// Check for game music
|
// Check for game music
|
||||||
else if ((fmt = GME_CheckFormat(id[0])) != NULL && fmt[0] != '\0')
|
else if ((fmt = GME_CheckFormat(id[0])) != NULL && fmt[0] != '\0')
|
||||||
|
|
|
@ -53,7 +53,8 @@ void I_SetMusicVolume (float volume);
|
||||||
|
|
||||||
// Registers a song handle to song data.
|
// Registers a song handle to song data.
|
||||||
class MusInfo;
|
class MusInfo;
|
||||||
MusInfo *I_RegisterSong (FileReader *reader, int device);
|
struct MidiDeviceSetting;
|
||||||
|
MusInfo *I_RegisterSong (FileReader *reader, MidiDeviceSetting *device);
|
||||||
MusInfo *I_RegisterCDSong (int track, int cdid = 0);
|
MusInfo *I_RegisterCDSong (int track, int cdid = 0);
|
||||||
MusInfo *I_RegisterURLSong (const char *url);
|
MusInfo *I_RegisterURLSong (const char *url);
|
||||||
|
|
||||||
|
|
|
@ -185,7 +185,7 @@ public:
|
||||||
class TimidityPPMIDIDevice : public PseudoMIDIDevice
|
class TimidityPPMIDIDevice : public PseudoMIDIDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TimidityPPMIDIDevice();
|
TimidityPPMIDIDevice(const char *args);
|
||||||
~TimidityPPMIDIDevice();
|
~TimidityPPMIDIDevice();
|
||||||
|
|
||||||
int Open(void (*callback)(unsigned int, void *, DWORD, DWORD), void *userdata);
|
int Open(void (*callback)(unsigned int, void *, DWORD, DWORD), void *userdata);
|
||||||
|
@ -270,7 +270,7 @@ protected:
|
||||||
class OPLMIDIDevice : public SoftSynthMIDIDevice, protected OPLmusicBlock
|
class OPLMIDIDevice : public SoftSynthMIDIDevice, protected OPLmusicBlock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OPLMIDIDevice();
|
OPLMIDIDevice(const char *args);
|
||||||
int Open(void (*callback)(unsigned int, void *, DWORD, DWORD), void *userdata);
|
int Open(void (*callback)(unsigned int, void *, DWORD, DWORD), void *userdata);
|
||||||
void Close();
|
void Close();
|
||||||
int GetTechnology() const;
|
int GetTechnology() const;
|
||||||
|
@ -303,7 +303,7 @@ namespace Timidity { struct Renderer; }
|
||||||
class TimidityMIDIDevice : public SoftSynthMIDIDevice
|
class TimidityMIDIDevice : public SoftSynthMIDIDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TimidityMIDIDevice();
|
TimidityMIDIDevice(const char *args);
|
||||||
~TimidityMIDIDevice();
|
~TimidityMIDIDevice();
|
||||||
|
|
||||||
int Open(void (*callback)(unsigned int, void *, DWORD, DWORD), void *userdata);
|
int Open(void (*callback)(unsigned int, void *, DWORD, DWORD), void *userdata);
|
||||||
|
@ -337,7 +337,7 @@ protected:
|
||||||
class WildMIDIDevice : public SoftSynthMIDIDevice
|
class WildMIDIDevice : public SoftSynthMIDIDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WildMIDIDevice();
|
WildMIDIDevice(const char *args);
|
||||||
~WildMIDIDevice();
|
~WildMIDIDevice();
|
||||||
|
|
||||||
int Open(void (*callback)(unsigned int, void *, DWORD, DWORD), void *userdata);
|
int Open(void (*callback)(unsigned int, void *, DWORD, DWORD), void *userdata);
|
||||||
|
@ -366,7 +366,7 @@ struct fluid_synth_t;
|
||||||
class FluidSynthMIDIDevice : public SoftSynthMIDIDevice
|
class FluidSynthMIDIDevice : public SoftSynthMIDIDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FluidSynthMIDIDevice();
|
FluidSynthMIDIDevice(const char *args);
|
||||||
~FluidSynthMIDIDevice();
|
~FluidSynthMIDIDevice();
|
||||||
|
|
||||||
int Open(void (*callback)(unsigned int, void *, DWORD, DWORD), void *userdata);
|
int Open(void (*callback)(unsigned int, void *, DWORD, DWORD), void *userdata);
|
||||||
|
@ -431,7 +431,7 @@ protected:
|
||||||
class MIDIStreamer : public MusInfo
|
class MIDIStreamer : public MusInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MIDIStreamer(EMidiDevice type);
|
MIDIStreamer(EMidiDevice type, const char *args);
|
||||||
~MIDIStreamer();
|
~MIDIStreamer();
|
||||||
|
|
||||||
void MusicVolumeChanged();
|
void MusicVolumeChanged();
|
||||||
|
@ -517,6 +517,7 @@ protected:
|
||||||
bool CallbackIsThreaded;
|
bool CallbackIsThreaded;
|
||||||
int LoopLimit;
|
int LoopLimit;
|
||||||
FString DumpFilename;
|
FString DumpFilename;
|
||||||
|
FString Args;
|
||||||
};
|
};
|
||||||
|
|
||||||
// MUS file played with a MIDI stream ---------------------------------------
|
// MUS file played with a MIDI stream ---------------------------------------
|
||||||
|
@ -524,7 +525,7 @@ protected:
|
||||||
class MUSSong2 : public MIDIStreamer
|
class MUSSong2 : public MIDIStreamer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MUSSong2(FileReader &reader, EMidiDevice type);
|
MUSSong2(FileReader &reader, EMidiDevice type, const char *args);
|
||||||
~MUSSong2();
|
~MUSSong2();
|
||||||
|
|
||||||
MusInfo *GetOPLDumper(const char *filename);
|
MusInfo *GetOPLDumper(const char *filename);
|
||||||
|
@ -550,7 +551,7 @@ protected:
|
||||||
class MIDISong2 : public MIDIStreamer
|
class MIDISong2 : public MIDIStreamer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MIDISong2(FileReader &reader, EMidiDevice type);
|
MIDISong2(FileReader &reader, EMidiDevice type, const char *args);
|
||||||
~MIDISong2();
|
~MIDISong2();
|
||||||
|
|
||||||
MusInfo *GetOPLDumper(const char *filename);
|
MusInfo *GetOPLDumper(const char *filename);
|
||||||
|
@ -607,7 +608,7 @@ protected:
|
||||||
class HMISong : public MIDIStreamer
|
class HMISong : public MIDIStreamer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HMISong(FileReader &reader, EMidiDevice type);
|
HMISong(FileReader &reader, EMidiDevice type, const char *args);
|
||||||
~HMISong();
|
~HMISong();
|
||||||
|
|
||||||
MusInfo *GetOPLDumper(const char *filename);
|
MusInfo *GetOPLDumper(const char *filename);
|
||||||
|
@ -650,7 +651,7 @@ protected:
|
||||||
class XMISong : public MIDIStreamer
|
class XMISong : public MIDIStreamer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XMISong(FileReader &reader, EMidiDevice type);
|
XMISong(FileReader &reader, EMidiDevice type, const char *args);
|
||||||
~XMISong();
|
~XMISong();
|
||||||
|
|
||||||
MusInfo *GetOPLDumper(const char *filename);
|
MusInfo *GetOPLDumper(const char *filename);
|
||||||
|
@ -713,7 +714,7 @@ protected:
|
||||||
class OPLMUSSong : public StreamSong
|
class OPLMUSSong : public StreamSong
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
OPLMUSSong (FileReader &reader);
|
OPLMUSSong (FileReader &reader, const char *args);
|
||||||
~OPLMUSSong ();
|
~OPLMUSSong ();
|
||||||
void Play (bool looping, int subsong);
|
void Play (bool looping, int subsong);
|
||||||
bool IsPlaying ();
|
bool IsPlaying ();
|
||||||
|
|
|
@ -255,7 +255,7 @@ CUSTOM_CVAR(Int, fluid_chorus_type, FLUID_CHORUS_DEFAULT_TYPE, CVAR_ARCHIVE|CVAR
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FluidSynthMIDIDevice::FluidSynthMIDIDevice()
|
FluidSynthMIDIDevice::FluidSynthMIDIDevice(const char *args)
|
||||||
{
|
{
|
||||||
FluidSynth = NULL;
|
FluidSynth = NULL;
|
||||||
FluidSettings = NULL;
|
FluidSettings = NULL;
|
||||||
|
@ -293,7 +293,15 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice()
|
||||||
fluid_reverb_width, fluid_reverb_level);
|
fluid_reverb_width, fluid_reverb_level);
|
||||||
fluid_synth_set_chorus(FluidSynth, fluid_chorus_voices, fluid_chorus_level,
|
fluid_synth_set_chorus(FluidSynth, fluid_chorus_voices, fluid_chorus_level,
|
||||||
fluid_chorus_speed, fluid_chorus_depth, fluid_chorus_type);
|
fluid_chorus_speed, fluid_chorus_depth, fluid_chorus_type);
|
||||||
if (0 == LoadPatchSets(fluid_patchset))
|
|
||||||
|
// try loading a patch set that got specified with $mididevice.
|
||||||
|
int res = 0;
|
||||||
|
if (args != NULL && *args != 0)
|
||||||
|
{
|
||||||
|
res = LoadPatchSets(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res == 0 && 0 == LoadPatchSets(fluid_patchset))
|
||||||
{
|
{
|
||||||
#ifdef __unix__
|
#ifdef __unix__
|
||||||
// This is the standard location on Ubuntu.
|
// This is the standard location on Ubuntu.
|
||||||
|
|
|
@ -128,8 +128,8 @@ extern char MIDI_CommonLengths[15];
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
HMISong::HMISong (FileReader &reader, EMidiDevice type)
|
HMISong::HMISong (FileReader &reader, EMidiDevice type, const char *args)
|
||||||
: MIDIStreamer(type), MusHeader(0), Tracks(0)
|
: MIDIStreamer(type, args), MusHeader(0), Tracks(0)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (ExitEvent == NULL)
|
if (ExitEvent == NULL)
|
||||||
|
|
|
@ -72,7 +72,7 @@ CUSTOM_CVAR (Int, timidity_frequency, 22050, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
TimidityPPMIDIDevice::TimidityPPMIDIDevice()
|
TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args)
|
||||||
: DiskName("zmid"),
|
: DiskName("zmid"),
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
ReadWavePipe(INVALID_HANDLE_VALUE), WriteWavePipe(INVALID_HANDLE_VALUE),
|
ReadWavePipe(INVALID_HANDLE_VALUE), WriteWavePipe(INVALID_HANDLE_VALUE),
|
||||||
|
@ -85,7 +85,13 @@ TimidityPPMIDIDevice::TimidityPPMIDIDevice()
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
WavePipe[0] = WavePipe[1] = -1;
|
WavePipe[0] = WavePipe[1] = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (args == NULL || *args == 0) args = timidity_exe;
|
||||||
|
|
||||||
|
CommandLine.Format("%s %s -EFchorus=%s -EFreverb=%s -s%d ",
|
||||||
|
args, *timidity_extargs,
|
||||||
|
*timidity_chorus, *timidity_reverb, *timidity_frequency);
|
||||||
|
|
||||||
if (DiskName == NULL)
|
if (DiskName == NULL)
|
||||||
{
|
{
|
||||||
Printf(PRINT_BOLD, "Could not create temp music file\n");
|
Printf(PRINT_BOLD, "Could not create temp music file\n");
|
||||||
|
@ -187,10 +193,6 @@ int TimidityPPMIDIDevice::Open(void (*callback)(unsigned int, void *, DWORD, DWO
|
||||||
Validated = true;
|
Validated = true;
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
|
|
||||||
CommandLine.Format("%s %s -EFchorus=%s -EFreverb=%s -s%d ",
|
|
||||||
*timidity_exe, *timidity_extargs,
|
|
||||||
*timidity_chorus, *timidity_reverb, *timidity_frequency);
|
|
||||||
|
|
||||||
pipeSize = (timidity_pipe * timidity_frequency / 1000)
|
pipeSize = (timidity_pipe * timidity_frequency / 1000)
|
||||||
<< (timidity_stereo + !timidity_8bit);
|
<< (timidity_stereo + !timidity_8bit);
|
||||||
|
|
||||||
|
|
|
@ -89,12 +89,12 @@ static const BYTE StaticMIDIhead[] =
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
MIDIStreamer::MIDIStreamer(EMidiDevice type)
|
MIDIStreamer::MIDIStreamer(EMidiDevice type, const char *args)
|
||||||
:
|
:
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
PlayerThread(0), ExitEvent(0), BufferDoneEvent(0),
|
PlayerThread(0), ExitEvent(0), BufferDoneEvent(0),
|
||||||
#endif
|
#endif
|
||||||
MIDI(0), Division(0), InitialTempo(500000), DeviceType(type)
|
MIDI(0), Division(0), InitialTempo(500000), DeviceType(type), Args(args)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
BufferDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
BufferDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
|
@ -269,19 +269,19 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype) const
|
||||||
|
|
||||||
#ifdef HAVE_FLUIDSYNTH
|
#ifdef HAVE_FLUIDSYNTH
|
||||||
case MDEV_FLUIDSYNTH:
|
case MDEV_FLUIDSYNTH:
|
||||||
return new FluidSynthMIDIDevice;
|
return new FluidSynthMIDIDevice(Args);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case MDEV_SNDSYS:
|
case MDEV_SNDSYS:
|
||||||
return new SndSysMIDIDevice;
|
return new SndSysMIDIDevice;
|
||||||
|
|
||||||
case MDEV_GUS:
|
case MDEV_GUS:
|
||||||
return new TimidityMIDIDevice;
|
return new TimidityMIDIDevice(Args);
|
||||||
|
|
||||||
case MDEV_OPL:
|
case MDEV_OPL:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return new OPLMIDIDevice;
|
return new OPLMIDIDevice(Args);
|
||||||
}
|
}
|
||||||
catch (CRecoverableError &err)
|
catch (CRecoverableError &err)
|
||||||
{
|
{
|
||||||
|
@ -291,10 +291,10 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype) const
|
||||||
}
|
}
|
||||||
|
|
||||||
case MDEV_TIMIDITY:
|
case MDEV_TIMIDITY:
|
||||||
return new TimidityPPMIDIDevice;
|
return new TimidityPPMIDIDevice(Args);
|
||||||
|
|
||||||
case MDEV_WILDMIDI:
|
case MDEV_WILDMIDI:
|
||||||
return new WildMIDIDevice;
|
return new WildMIDIDevice(Args);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "m_swap.h"
|
#include "m_swap.h"
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
|
#include "s_sound.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -92,8 +93,8 @@ static const BYTE CtrlTranslate[15] =
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
MUSSong2::MUSSong2 (FileReader &reader, EMidiDevice type)
|
MUSSong2::MUSSong2 (FileReader &reader, EMidiDevice type, const char *args)
|
||||||
: MIDIStreamer(type), MusHeader(0), MusBuffer(0)
|
: MIDIStreamer(type, args), MusHeader(0), MusBuffer(0)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (ExitEvent == NULL)
|
if (ExitEvent == NULL)
|
||||||
|
@ -210,23 +211,44 @@ bool MUSSong2::CheckDone()
|
||||||
|
|
||||||
void MUSSong2::Precache()
|
void MUSSong2::Precache()
|
||||||
{
|
{
|
||||||
WORD *work = (WORD *)alloca(MusHeader->NumInstruments * sizeof(WORD));
|
TArray<WORD> work(MusHeader->NumInstruments);
|
||||||
const WORD *used = (WORD *)MusHeader + sizeof(MUSHeader) / sizeof(WORD);
|
const BYTE *used = (BYTE *)MusHeader + sizeof(MUSHeader) / sizeof(BYTE);
|
||||||
int i, j;
|
int i, k;
|
||||||
|
|
||||||
for (i = j = 0; i < MusHeader->NumInstruments; ++i)
|
for (i = k = 0; i < MusHeader->NumInstruments; ++i)
|
||||||
{
|
{
|
||||||
WORD instr = LittleShort(used[i]);
|
BYTE instr = used[k++];
|
||||||
|
WORD val;
|
||||||
if (instr < 128)
|
if (instr < 128)
|
||||||
{
|
{
|
||||||
work[j++] = instr;
|
val = instr;
|
||||||
}
|
}
|
||||||
else if (used[i] >= 135 && used[i] <= 181)
|
else if (instr >= 135 && instr <= 188)
|
||||||
{ // Percussions are 100-based, not 128-based, eh?
|
{ // Percussions are 100-based, not 128-based, eh?
|
||||||
work[j++] = instr - 100 + (1 << 14);
|
val = instr - 100 + (1 << 14);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// skip it.
|
||||||
|
val = used[k++];
|
||||||
|
k += val;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int numbanks = used[k++];
|
||||||
|
if (numbanks > 0)
|
||||||
|
{
|
||||||
|
for (int b = 0; b < numbanks; b++)
|
||||||
|
{
|
||||||
|
work.Push(val | (used[k++] << 7));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
work.Push(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MIDI->PrecacheInstruments(&work[0], j);
|
MIDI->PrecacheInstruments(&work[0], work.Size());
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -20,16 +20,25 @@ CUSTOM_CVAR (Int, opl_numchips, 2, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CVAR(Int, opl_core, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
CVAR(Int, opl_core, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
|
int current_opl_core;
|
||||||
|
|
||||||
OPLMUSSong::OPLMUSSong (FileReader &reader)
|
// Get OPL core override from $mididevice
|
||||||
|
void OPL_SetCore(const char *args)
|
||||||
|
{
|
||||||
|
current_opl_core = opl_core;
|
||||||
|
if (args != NULL && *args >= '0' && *args < '4') current_opl_core = *args - '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
OPLMUSSong::OPLMUSSong (FileReader &reader, const char *args)
|
||||||
{
|
{
|
||||||
int samples = int(OPL_SAMPLE_RATE / 14);
|
int samples = int(OPL_SAMPLE_RATE / 14);
|
||||||
|
|
||||||
|
OPL_SetCore(args);
|
||||||
Music = new OPLmusicFile (&reader);
|
Music = new OPLmusicFile (&reader);
|
||||||
|
|
||||||
m_Stream = GSnd->CreateStream (FillStream, samples*4,
|
m_Stream = GSnd->CreateStream (FillStream, samples*4,
|
||||||
(opl_core == 0 ? SoundStream::Mono : 0) | SoundStream::Float, int(OPL_SAMPLE_RATE), this);
|
(current_opl_core == 0 ? SoundStream::Mono : 0) | SoundStream::Float, int(OPL_SAMPLE_RATE), this);
|
||||||
if (m_Stream == NULL)
|
if (m_Stream == NULL)
|
||||||
{
|
{
|
||||||
Printf (PRINT_BOLD, "Could not create music stream.\n");
|
Printf (PRINT_BOLD, "Could not create music stream.\n");
|
||||||
|
|
|
@ -102,8 +102,8 @@ char MIDI_CommonLengths[15] = { 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
MIDISong2::MIDISong2 (FileReader &reader, EMidiDevice type)
|
MIDISong2::MIDISong2 (FileReader &reader, EMidiDevice type, const char *args)
|
||||||
: MIDIStreamer(type), MusHeader(0), Tracks(0)
|
: MIDIStreamer(type, args), MusHeader(0), Tracks(0)
|
||||||
{
|
{
|
||||||
int p;
|
int p;
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -86,10 +86,10 @@ struct FmtChunk
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
TimidityMIDIDevice::TimidityMIDIDevice()
|
TimidityMIDIDevice::TimidityMIDIDevice(const char *args)
|
||||||
{
|
{
|
||||||
Renderer = NULL;
|
Renderer = NULL;
|
||||||
Renderer = new Timidity::Renderer((float)SampleRate);
|
Renderer = new Timidity::Renderer((float)SampleRate, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -245,6 +245,7 @@ FString TimidityMIDIDevice::GetStats()
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
TimidityWaveWriterMIDIDevice::TimidityWaveWriterMIDIDevice(const char *filename, int rate)
|
TimidityWaveWriterMIDIDevice::TimidityWaveWriterMIDIDevice(const char *filename, int rate)
|
||||||
|
:TimidityMIDIDevice(NULL)
|
||||||
{
|
{
|
||||||
File = fopen(filename, "wb");
|
File = fopen(filename, "wb");
|
||||||
if (File != NULL)
|
if (File != NULL)
|
||||||
|
|
|
@ -81,7 +81,7 @@ CUSTOM_CVAR(Bool, wildmidi_enhanced_resampling, true, CVAR_ARCHIVE | CVAR_GLOBAL
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
WildMIDIDevice::WildMIDIDevice()
|
WildMIDIDevice::WildMIDIDevice(const char *args)
|
||||||
{
|
{
|
||||||
Renderer = NULL;
|
Renderer = NULL;
|
||||||
|
|
||||||
|
@ -94,16 +94,18 @@ WildMIDIDevice::WildMIDIDevice()
|
||||||
SampleRate = clamp(SampleRate, 11025, 65535);
|
SampleRate = clamp(SampleRate, 11025, 65535);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CurrentConfig.CompareNoCase(wildmidi_config) != 0 || SampleRate != WildMidi_GetSampleRate())
|
if (args == NULL || *args == 0) args = wildmidi_config;
|
||||||
|
|
||||||
|
if (CurrentConfig.CompareNoCase(args) != 0 || SampleRate != WildMidi_GetSampleRate())
|
||||||
{
|
{
|
||||||
if (CurrentConfig.IsNotEmpty())
|
if (CurrentConfig.IsNotEmpty())
|
||||||
{
|
{
|
||||||
WildMidi_Shutdown();
|
WildMidi_Shutdown();
|
||||||
CurrentConfig = "";
|
CurrentConfig = "";
|
||||||
}
|
}
|
||||||
if (!WildMidi_Init(wildmidi_config, SampleRate, 0))
|
if (!WildMidi_Init(args, SampleRate, 0))
|
||||||
{
|
{
|
||||||
CurrentConfig = wildmidi_config;
|
CurrentConfig = args;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (CurrentConfig.IsNotEmpty())
|
if (CurrentConfig.IsNotEmpty())
|
||||||
|
|
|
@ -108,8 +108,8 @@ extern char MIDI_CommonLengths[15];
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
XMISong::XMISong (FileReader &reader, EMidiDevice type)
|
XMISong::XMISong (FileReader &reader, EMidiDevice type, const char *args)
|
||||||
: MIDIStreamer(type), MusHeader(0), Songs(0)
|
: MIDIStreamer(type, args), MusHeader(0), Songs(0)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (ExitEvent == NULL)
|
if (ExitEvent == NULL)
|
||||||
|
|
|
@ -678,8 +678,9 @@ int LoadDMXGUS()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer::Renderer(float sample_rate)
|
Renderer::Renderer(float sample_rate, const char *args)
|
||||||
{
|
{
|
||||||
|
// 'args' should be used to load a custom config or DMXGUS, but since setup currently requires a snd_reset call, this will need some refactoring first
|
||||||
rate = sample_rate;
|
rate = sample_rate;
|
||||||
patches = NULL;
|
patches = NULL;
|
||||||
resample_buffer_size = 0;
|
resample_buffer_size = 0;
|
||||||
|
|
|
@ -630,7 +630,7 @@ struct Renderer
|
||||||
int voices;
|
int voices;
|
||||||
int lost_notes, cut_notes;
|
int lost_notes, cut_notes;
|
||||||
|
|
||||||
Renderer(float sample_rate);
|
Renderer(float sample_rate, const char *args);
|
||||||
~Renderer();
|
~Renderer();
|
||||||
|
|
||||||
void HandleEvent(int status, int parm1, int parm2);
|
void HandleEvent(int status, int parm1, int parm2);
|
||||||
|
|
|
@ -76,7 +76,7 @@ const char *GetVersionString();
|
||||||
|
|
||||||
// Use 4500 as the base git save version, since it's higher than the
|
// Use 4500 as the base git save version, since it's higher than the
|
||||||
// SVN revision ever got.
|
// SVN revision ever got.
|
||||||
#define SAVEVER 4526
|
#define SAVEVER 4527
|
||||||
|
|
||||||
#define SAVEVERSTRINGIFY2(x) #x
|
#define SAVEVERSTRINGIFY2(x) #x
|
||||||
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)
|
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)
|
||||||
|
|
|
@ -2719,14 +2719,14 @@ midi *WildMidi_NewMidi() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((((_mdi*)ret)->reverb = _WM_init_reverb(_WM_SampleRate, reverb_room_width,
|
if ((((_mdi*)ret)->reverb = _WM_init_reverb(_WM_SampleRate, reverb_room_width,
|
||||||
reverb_room_length, reverb_listen_posx, reverb_listen_posy))
|
reverb_room_length, reverb_listen_posx, reverb_listen_posy))
|
||||||
== NULL) {
|
== NULL) {
|
||||||
_WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to init reverb", 0);
|
_WM_ERROR(__FUNCTION__, __LINE__, WM_ERR_MEM, "to init reverb", 0);
|
||||||
WildMidi_Close(ret);
|
WildMidi_Close(ret);
|
||||||
ret = NULL;
|
ret = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,6 +129,10 @@ const int WRF_NOFIRE = WRF_NOPRIMARY | WRF_NOSECONDARY;
|
||||||
const int WRF_ALLOWRELOAD = 16;
|
const int WRF_ALLOWRELOAD = 16;
|
||||||
const int WRF_ALLOWZOOM = 32;
|
const int WRF_ALLOWZOOM = 32;
|
||||||
const int WRF_DISABLESWITCH = 64;
|
const int WRF_DISABLESWITCH = 64;
|
||||||
|
const int WRF_ALLOWUSER1 = 128;
|
||||||
|
const int WRF_ALLOWUSER2 = 256;
|
||||||
|
const int WRF_ALLOWUSER3 = 512;
|
||||||
|
const int WRF_ALLOWUSER4 = 1024;
|
||||||
|
|
||||||
// Morph constants
|
// Morph constants
|
||||||
const int MRF_ADDSTAMINA = 1;
|
const int MRF_ADDSTAMINA = 1;
|
||||||
|
|
|
@ -435,8 +435,12 @@ OptionMenu "CustomizeControls"
|
||||||
StaticText "Controls", 1
|
StaticText "Controls", 1
|
||||||
Control "Fire", "+attack"
|
Control "Fire", "+attack"
|
||||||
Control "Secondary Fire", "+altattack"
|
Control "Secondary Fire", "+altattack"
|
||||||
Control "Weapon Reload", "+reload"
|
Control "Weapon Reload", "+reload"
|
||||||
Control "Weapon Zoom", "+zoom"
|
Control "Weapon Zoom", "+zoom"
|
||||||
|
Control "Weapon State 1", "+user1"
|
||||||
|
Control "Weapon State 2", "+user2"
|
||||||
|
Control "Weapon State 3", "+user3"
|
||||||
|
Control "Weapon State 4", "+user4"
|
||||||
Control "Use / Open", "+use"
|
Control "Use / Open", "+use"
|
||||||
Control "Move forward", "+forward"
|
Control "Move forward", "+forward"
|
||||||
Control "Move backward", "+back"
|
Control "Move backward", "+back"
|
||||||
|
|
Loading…
Reference in a new issue