Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🚚 New prop anim sources: gearreverse, gearneutral, gear#, autoshifterlin #3078

Merged
merged 1 commit into from
Sep 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 24 additions & 5 deletions source/main/gfx/GfxActor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2497,7 +2497,7 @@ void RoR::GfxActor::CalcPropAnimation(PropAnim& anim, float& cstate, int& div, f
div++;
}

//torque - WRITES
//torque
const bool has_engine = (m_actor->ar_engine!= nullptr);
if (has_engine && anim.animFlags & PROP_ANIM_FLAG_TORQUE)
{
Expand All @@ -2515,8 +2515,15 @@ void RoR::GfxActor::CalcPropAnimation(PropAnim& anim, float& cstate, int& div, f
div++;
}

if (has_engine && anim.animFlags & PROP_ANIM_FLAG_GEAR)
{
bool match = static_cast<int>(anim.animOpt3) == m_actor->ar_engine->GetGear();
cstate += static_cast<int>(match);
div++;
}

//shifterseq, to amimate sequentiell shifting
if (has_engine && (anim.animFlags & PROP_ANIM_FLAG_SHIFTER) && anim.animOpt3 == ShifterPropAnim::SHIFTERSEQ)
if (has_engine && (anim.animFlags & PROP_ANIM_FLAG_SHIFTER) && anim.animOpt3 == SHIFTERSEQ)
{
float shifterseq_cstate = 0;
// opt1 &opt2 = 0 this is a shifter
Expand Down Expand Up @@ -2568,7 +2575,7 @@ void RoR::GfxActor::CalcPropAnimation(PropAnim& anim, float& cstate, int& div, f
}

//shifterman1, left/right
if (has_engine && (anim.animFlags & PROP_ANIM_FLAG_SHIFTER) && anim.animOpt3 == ShifterPropAnim::SHIFTERMAN1)
if (has_engine && (anim.animFlags & PROP_ANIM_FLAG_SHIFTER) && anim.animOpt3 == SHIFTERMAN1)
{
float shifterman1_cstate = 0.f;
int shifter = m_simbuf.simbuf_gear;
Expand All @@ -2590,7 +2597,7 @@ void RoR::GfxActor::CalcPropAnimation(PropAnim& anim, float& cstate, int& div, f
}

//shifterman2, up/down
if (has_engine && (anim.animFlags & PROP_ANIM_FLAG_SHIFTER) && anim.animOpt3 == ShifterPropAnim::SHIFTERMAN2)
if (has_engine && (anim.animFlags & PROP_ANIM_FLAG_SHIFTER) && anim.animOpt3 == SHIFTERMAN2)
{
float shifterman2_cstate = 0.f;
int shifter = m_simbuf.simbuf_gear;
Expand All @@ -2609,7 +2616,7 @@ void RoR::GfxActor::CalcPropAnimation(PropAnim& anim, float& cstate, int& div, f
}

//shifterlinear, to amimate cockpit gearselect gauge and autotransmission stick
if (has_engine && (anim.animFlags & PROP_ANIM_FLAG_SHIFTER) && anim.animOpt3 == ShifterPropAnim::SHIFTERLIN)
if (has_engine && (anim.animFlags & PROP_ANIM_FLAG_SHIFTER) && anim.animOpt3 == SHIFTERLIN)
{
float shifterlin_cstate = 0.f;
int shifter = m_simbuf.simbuf_gear;
Expand All @@ -2620,6 +2627,18 @@ void RoR::GfxActor::CalcPropAnimation(PropAnim& anim, float& cstate, int& div, f
div++;
}

//autoshifterlin, autotransmission stick with only R/N/D positions
if (has_engine && (anim.animFlags & PROP_ANIM_FLAG_SHIFTER) && anim.animOpt3 == AUTOSHIFTERLIN)
{
float shifterlin_cstate = 0.f;
int shifter = std::min(m_simbuf.simbuf_gear, 1); // Clamp forward gears to 1
int numgears = 1; // Number of forward gears
shifterlin_cstate -= (shifter + 2.0) / (numgears + 2.0);

cstate += UpdateSmoothShift(anim, dt, shifterlin_cstate);
div++;
}

//parking brake
if (anim.animFlags & PROP_ANIM_FLAG_PBRAKE)
{
Expand Down
112 changes: 57 additions & 55 deletions source/main/gfx/GfxData.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,56 +39,56 @@ namespace RoR {
/// @addtogroup Gfx
/// @{

typedef BitMask64_t PropAnimFlag_t;

const PropAnimFlag_t PROP_ANIM_FLAG_AIRSPEED = BITMASK64(1);
const PropAnimFlag_t PROP_ANIM_FLAG_VVI = BITMASK64(2);
const PropAnimFlag_t PROP_ANIM_FLAG_ALTIMETER = BITMASK64(3);
const PropAnimFlag_t PROP_ANIM_FLAG_AOA = BITMASK64(4);
const PropAnimFlag_t PROP_ANIM_FLAG_FLAP = BITMASK64(5);
const PropAnimFlag_t PROP_ANIM_FLAG_AIRBRAKE = BITMASK64(6);
const PropAnimFlag_t PROP_ANIM_FLAG_ROLL = BITMASK64(7);
const PropAnimFlag_t PROP_ANIM_FLAG_PITCH = BITMASK64(8);
const PropAnimFlag_t PROP_ANIM_FLAG_THROTTLE = BITMASK64(9);
const PropAnimFlag_t PROP_ANIM_FLAG_RPM = BITMASK64(10);
const PropAnimFlag_t PROP_ANIM_FLAG_ACCEL = BITMASK64(11);
const PropAnimFlag_t PROP_ANIM_FLAG_BRAKE = BITMASK64(12);
const PropAnimFlag_t PROP_ANIM_FLAG_CLUTCH = BITMASK64(13);
const PropAnimFlag_t PROP_ANIM_FLAG_TACHO = BITMASK64(14);
const PropAnimFlag_t PROP_ANIM_FLAG_SPEEDO = BITMASK64(15);
const PropAnimFlag_t PROP_ANIM_FLAG_PBRAKE = BITMASK64(16);
const PropAnimFlag_t PROP_ANIM_FLAG_TURBO = BITMASK64(17);
const PropAnimFlag_t PROP_ANIM_FLAG_SHIFTER = BITMASK64(18); //!< 'shifterman1, shifterman2, sequential, shifterlin, autoshifterlin'; animOpt3: see `RoR::ShifterPropAnim`
const PropAnimFlag_t PROP_ANIM_FLAG_AETORQUE = BITMASK64(19);
const PropAnimFlag_t PROP_ANIM_FLAG_AEPITCH = BITMASK64(20);
const PropAnimFlag_t PROP_ANIM_FLAG_AESTATUS = BITMASK64(21);
const PropAnimFlag_t PROP_ANIM_FLAG_TORQUE = BITMASK64(22);
const PropAnimFlag_t PROP_ANIM_FLAG_HEADING = BITMASK64(23);
const PropAnimFlag_t PROP_ANIM_FLAG_DIFFLOCK = BITMASK64(24);
const PropAnimFlag_t PROP_ANIM_FLAG_STEERING = BITMASK64(25);
const PropAnimFlag_t PROP_ANIM_FLAG_EVENT = BITMASK64(26);
const PropAnimFlag_t PROP_ANIM_FLAG_AILERONS = BITMASK64(27);
const PropAnimFlag_t PROP_ANIM_FLAG_ARUDDER = BITMASK64(28);
const PropAnimFlag_t PROP_ANIM_FLAG_BRUDDER = BITMASK64(29);
const PropAnimFlag_t PROP_ANIM_FLAG_BTHROTTLE = BITMASK64(30);
const PropAnimFlag_t PROP_ANIM_FLAG_PERMANENT = BITMASK64(31);
const PropAnimFlag_t PROP_ANIM_FLAG_ELEVATORS = BITMASK64(32);
const PropAnimFlag_t PROP_ANIM_FLAG_DASHBOARD = BITMASK64(33); //!< Used with dashboard system inputs, see `enum DashData` in file DashBoardManager.h
const PropAnimFlag_t PROP_ANIM_FLAG_SIGNALSTALK = BITMASK64(34); //!< Turn indicator stalk position (-1=left, 0=off, 1=right)
const PropAnimFlag_t PROP_ANIM_FLAG_GEAR = BITMASK64(35); //!< 'gearreverse' (animOpt3=-1), 'gearneutral' (animOpt3=0), 'gear#' (animOpt3=#)

typedef BitMask_t PropAnimMode_t;

const PropAnimMode_t PROP_ANIM_MODE_ROTA_X = BITMASK(1);
const PropAnimMode_t PROP_ANIM_MODE_ROTA_Y = BITMASK(2);
const PropAnimMode_t PROP_ANIM_MODE_ROTA_Z = BITMASK(3);
const PropAnimMode_t PROP_ANIM_MODE_OFFSET_X = BITMASK(4);
const PropAnimMode_t PROP_ANIM_MODE_OFFSET_Y = BITMASK(5);
const PropAnimMode_t PROP_ANIM_MODE_OFFSET_Z = BITMASK(6);
const PropAnimMode_t PROP_ANIM_MODE_AUTOANIMATE = BITMASK(7);
const PropAnimMode_t PROP_ANIM_MODE_NOFLIP = BITMASK(8);
const PropAnimMode_t PROP_ANIM_MODE_BOUNCE = BITMASK(9);

static const BitMask64_t PROP_ANIM_FLAG_AIRSPEED = BITMASK64(1);
static const BitMask64_t PROP_ANIM_FLAG_VVI = BITMASK64(2);
static const BitMask64_t PROP_ANIM_FLAG_ALTIMETER = BITMASK64(3);
static const BitMask64_t PROP_ANIM_FLAG_AOA = BITMASK64(4);
static const BitMask64_t PROP_ANIM_FLAG_FLAP = BITMASK64(5);
static const BitMask64_t PROP_ANIM_FLAG_AIRBRAKE = BITMASK64(6);
static const BitMask64_t PROP_ANIM_FLAG_ROLL = BITMASK64(7);
static const BitMask64_t PROP_ANIM_FLAG_PITCH = BITMASK64(8);
static const BitMask64_t PROP_ANIM_FLAG_THROTTLE = BITMASK64(9);
static const BitMask64_t PROP_ANIM_FLAG_RPM = BITMASK64(10);
static const BitMask64_t PROP_ANIM_FLAG_ACCEL = BITMASK64(11);
static const BitMask64_t PROP_ANIM_FLAG_BRAKE = BITMASK64(12);
static const BitMask64_t PROP_ANIM_FLAG_CLUTCH = BITMASK64(13);
static const BitMask64_t PROP_ANIM_FLAG_TACHO = BITMASK64(14);
static const BitMask64_t PROP_ANIM_FLAG_SPEEDO = BITMASK64(15);
static const BitMask64_t PROP_ANIM_FLAG_PBRAKE = BITMASK64(16);
static const BitMask64_t PROP_ANIM_FLAG_TURBO = BITMASK64(17);
static const BitMask64_t PROP_ANIM_FLAG_SHIFTER = BITMASK64(18);
static const BitMask64_t PROP_ANIM_FLAG_AETORQUE = BITMASK64(19);
static const BitMask64_t PROP_ANIM_FLAG_AEPITCH = BITMASK64(20);
static const BitMask64_t PROP_ANIM_FLAG_AESTATUS = BITMASK64(21);
static const BitMask64_t PROP_ANIM_FLAG_TORQUE = BITMASK64(22);
static const BitMask64_t PROP_ANIM_FLAG_HEADING = BITMASK64(23);
static const BitMask64_t PROP_ANIM_FLAG_DIFFLOCK = BITMASK64(24);
static const BitMask64_t PROP_ANIM_FLAG_STEERING = BITMASK64(25);
static const BitMask64_t PROP_ANIM_FLAG_EVENT = BITMASK64(26);
static const BitMask64_t PROP_ANIM_FLAG_AILERONS = BITMASK64(27);
static const BitMask64_t PROP_ANIM_FLAG_ARUDDER = BITMASK64(28);
static const BitMask64_t PROP_ANIM_FLAG_BRUDDER = BITMASK64(29);
static const BitMask64_t PROP_ANIM_FLAG_BTHROTTLE = BITMASK64(30);
static const BitMask64_t PROP_ANIM_FLAG_PERMANENT = BITMASK64(31);
static const BitMask64_t PROP_ANIM_FLAG_ELEVATORS = BITMASK64(32);
static const BitMask64_t PROP_ANIM_FLAG_DASHBOARD = BITMASK64(33); //!< Used with dashboard system inputs, see `enum DashData` in file DashBoardManager.h
static const BitMask64_t PROP_ANIM_FLAG_SIGNALSTALK = BITMASK64(34); //!< Turn indicator stalk position (-1=left, 0=off, 1=right)

enum PropAnimMode
{
PROP_ANIM_MODE_ROTA_X = BITMASK(1),
PROP_ANIM_MODE_ROTA_Y = BITMASK(2),
PROP_ANIM_MODE_ROTA_Z = BITMASK(3),
PROP_ANIM_MODE_OFFSET_X = BITMASK(4),
PROP_ANIM_MODE_OFFSET_Y = BITMASK(5),
PROP_ANIM_MODE_OFFSET_Z = BITMASK(6),
PROP_ANIM_MODE_AUTOANIMATE = BITMASK(7),
PROP_ANIM_MODE_NOFLIP = BITMASK(8),
PROP_ANIM_MODE_BOUNCE = BITMASK(9),
};

inline PropAnimMode operator|=(PropAnimMode& dst, PropAnimMode const& arg) { dst = static_cast<PropAnimMode>(dst|arg); return dst; }

enum class VideoCamState
{
Expand Down Expand Up @@ -125,26 +125,28 @@ static CameraMode_t CAMERA_MODE_ALWAYS_HIDDEN = -3;
static CameraMode_t CAMERA_MODE_ALWAYS_VISIBLE = -2;
static CameraMode_t CAMERA_MODE_3RDPERSON_ONLY = -1;

enum ShifterPropAnim
enum ShifterPropAnim //!< `PropAnim::animOpt3` values for PROP_ANIM_FLAG_SHIFTER
{
SHIFTER_INVALID = 0,
SHIFTERMAN1 = 1,
SHIFTERMAN2 = 2,
SHIFTERSEQ = 3,
SHIFTERLIN = 4
SHIFTERLIN = 4,
AUTOSHIFTERLIN = 5
};

struct PropAnim
{
float animratio = 0; //!< A coefficient for the animation, prop degree if used with mode: rotation and propoffset if used with mode: offset.
BitMask64_t animFlags = 0ull;
PropAnimMode animMode = {};
float animratio = 0; //!< A coefficient for the animation, prop degree if used with mode: rotation and propoffset if used with mode: offset.
PropAnimFlag_t animFlags = 0;
PropAnimMode_t animMode = 0;

/// MULTIPURPOSE
/// * SHIFTER type `ShifterPropAnim` (1 = shifterman1, 2 = shifterman2, 3 = shifterseq, 4 = shifterlin)
/// * SHIFTER type `ShifterPropAnim` (1 = shifterman1, 2 = shifterman2, 3 = shifterseq, 4 = shifterlin, 5 = autoshifterlin)
/// * AEROENGINE number (starting from 1), applies to: rpm + throttle + torque ( turboprop ) + pitch ( turboprop ) + status + fire
/// * ALTIMETER type (1 = 100k limited, 2 = 10k oscillating, 3 = 1k oscillating)
/// * DASHBOARD input (see `enum DashData` in file DashBoardManager.h)
/// * GEAR number (-1 = reverse, 0 = neutral, 1+ = forward)
float animOpt3 = 0;
float animOpt5 = 0;
float lower_limit = 0; //!< The lower limit for the animation
Expand Down
29 changes: 24 additions & 5 deletions source/main/physics/ActorSpawner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1906,19 +1906,23 @@ void ActorSpawner::ProcessProp(RigDef::Prop & def)
}
if (BITMASK_IS_1(anim_def.source, RigDef::Animation::SOURCE_SHIFT_LEFT_RIGHT)) {
BITMASK_SET_1(anim.animFlags, PROP_ANIM_FLAG_SHIFTER);
anim.animOpt3 = 1.0f;
anim.animOpt3 = SHIFTERMAN1;
}
if (BITMASK_IS_1(anim_def.source, RigDef::Animation::SOURCE_SHIFT_BACK_FORTH)) {
BITMASK_SET_1(anim.animFlags, PROP_ANIM_FLAG_SHIFTER);
anim.animOpt3 = 2.0f;
anim.animOpt3 = SHIFTERMAN2;
}
if (BITMASK_IS_1(anim_def.source, RigDef::Animation::SOURCE_SEQUENTIAL_SHIFT)) {
BITMASK_SET_1(anim.animFlags, PROP_ANIM_FLAG_SHIFTER);
anim.animOpt3 = 3.0f;
anim.animOpt3 = SHIFTERSEQ;
}
if (BITMASK_IS_1(anim_def.source, RigDef::Animation::SOURCE_SHIFTERLIN)) {
BITMASK_SET_1(anim.animFlags, PROP_ANIM_FLAG_SHIFTER);
anim.animOpt3 = 4.0f;
anim.animOpt3 = SHIFTERLIN;
}
if (BITMASK_IS_1(anim_def.source, RigDef::Animation::SOURCE_AUTOSHIFTERLIN)) {
BITMASK_SET_1(anim.animFlags, PROP_ANIM_FLAG_SHIFTER);
anim.animOpt3 = AUTOSHIFTERLIN;
}
if (BITMASK_IS_1(anim_def.source, RigDef::Animation::SOURCE_TORQUE)) {
BITMASK_SET_1(anim.animFlags, PROP_ANIM_FLAG_TORQUE);
Expand Down Expand Up @@ -1953,11 +1957,20 @@ void ActorSpawner::ProcessProp(RigDef::Prop & def)
if (BITMASK_IS_1(anim_def.source, RigDef::Animation::SOURCE_SIGNALSTALK)) {
BITMASK_SET_1(anim.animFlags, PROP_ANIM_FLAG_SIGNALSTALK);
}
if (BITMASK_IS_1(anim_def.source, RigDef::Animation::SOURCE_GEAR_REVERSE)) {
BITMASK_SET_1(anim.animFlags, PROP_ANIM_FLAG_GEAR);
anim.animOpt3 = -1;
}
if (BITMASK_IS_1(anim_def.source, RigDef::Animation::SOURCE_GEAR_NEUTRAL)) {
BITMASK_SET_1(anim.animFlags, PROP_ANIM_FLAG_GEAR);
anim.animOpt3 = 0;
}

/* Motor-indexed sources */
/* Motor/Gear-indexed sources */
std::list<RigDef::Animation::MotorSource>::iterator source_itor = anim_def.motor_sources.begin();
for ( ; source_itor != anim_def.motor_sources.end(); source_itor++)
{
// aeroengines
if (BITMASK_IS_1(source_itor->source, RigDef::Animation::MotorSource::SOURCE_AERO_THROTTLE)) {
BITMASK_SET_1(anim.animFlags, PROP_ANIM_FLAG_THROTTLE);
anim.animOpt3 = static_cast<float>(source_itor->motor);
Expand All @@ -1978,6 +1991,12 @@ void ActorSpawner::ProcessProp(RigDef::Prop & def)
BITMASK_SET_1(anim.animFlags, PROP_ANIM_FLAG_AESTATUS);
anim.animOpt3 = static_cast<float>(source_itor->motor);
}

// gears (hack)
if (BITMASK_IS_1(source_itor->source, RigDef::Animation::MotorSource::SOURCE_GEAR_FORWARD)) {
BITMASK_SET_1(anim.animFlags, PROP_ANIM_FLAG_GEAR);
anim.animOpt3 = static_cast<float>(source_itor->motor);
}
}

// Source 'event' - make sure there is parameter 'event:'
Expand Down
8 changes: 7 additions & 1 deletion source/main/resources/rig_def_fileformat/RigDef_File.h
Original file line number Diff line number Diff line change
Expand Up @@ -477,11 +477,14 @@ struct Animation
{
struct MotorSource
{
// > aeroengines
static const BitMask_t SOURCE_AERO_THROTTLE = BITMASK(1);
static const BitMask_t SOURCE_AERO_RPM = BITMASK(2);
static const BitMask_t SOURCE_AERO_TORQUE = BITMASK(3);
static const BitMask_t SOURCE_AERO_PITCH = BITMASK(4);
static const BitMask_t SOURCE_AERO_STATUS = BITMASK(5);
// > forward gears (hack...)
static const BitMask_t SOURCE_GEAR_FORWARD = BITMASK(6);

BitMask_t source = 0;
unsigned int motor = 0;
Expand Down Expand Up @@ -522,6 +525,9 @@ struct Animation
static const BitMask64_t SOURCE_EVENT = BITMASK64(32);
static const BitMask64_t SOURCE_DASHBOARD = BITMASK64(33);
static const BitMask64_t SOURCE_SIGNALSTALK = BITMASK64(34);
static const BitMask64_t SOURCE_AUTOSHIFTERLIN = BITMASK64(35);
static const BitMask64_t SOURCE_GEAR_NEUTRAL = BITMASK64(36);
static const BitMask64_t SOURCE_GEAR_REVERSE = BITMASK64(37);

// Mode flags
static const BitMask_t MODE_ROTATION_X = BITMASK(1);
Expand All @@ -538,7 +544,7 @@ struct Animation
float ratio = 0.f;
float lower_limit = -1.f;
float upper_limit = -1.f;
BitMask64_t source = 0ull;
BitMask64_t source = 0;
std::list<MotorSource> motor_sources;
BitMask_t mode = 0;
Ogre::String event_name;
Expand Down
10 changes: 10 additions & 0 deletions source/main/resources/rig_def_fileformat/RigDef_Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,7 @@ void Parser::ParseDirectiveAddAnimation()
else if (value == "shifterman2") { animation.source |= Animation::SOURCE_SHIFT_BACK_FORTH; }
else if (value == "sequential") { animation.source |= Animation::SOURCE_SEQUENTIAL_SHIFT; }
else if (value == "shifterlin") { animation.source |= Animation::SOURCE_SHIFTERLIN; }
else if (value == "autoshifterlin"){ animation.source |= Animation::SOURCE_AUTOSHIFTERLIN; }
else if (value == "torque") { animation.source |= Animation::SOURCE_TORQUE; }
else if (value == "heading") { animation.source |= Animation::SOURCE_HEADING; }
else if (value == "difflock") { animation.source |= Animation::SOURCE_DIFFLOCK; }
Expand All @@ -1197,10 +1198,13 @@ void Parser::ParseDirectiveAddAnimation()
else if (value == "event") { animation.source |= Animation::SOURCE_EVENT; }
else if (value == "dashboard") { animation.source |= Animation::SOURCE_DASHBOARD; }
else if (value == "signalstalk") { animation.source |= Animation::SOURCE_SIGNALSTALK; }
else if (value == "gearreverse") { animation.source |= Animation::SOURCE_GEAR_REVERSE; }
else if (value == "gearneutral") { animation.source |= Animation::SOURCE_GEAR_NEUTRAL; }

else
{
Animation::MotorSource motor_source;
// aeroengines...
if (entry[1].compare(0, 8, "throttle") == 0)
{
motor_source.source = Animation::MotorSource::SOURCE_AERO_THROTTLE;
Expand All @@ -1226,6 +1230,12 @@ void Parser::ParseDirectiveAddAnimation()
motor_source.source = Animation::MotorSource::SOURCE_AERO_STATUS;
motor_source.motor = this->ParseArgUint(entry[1].substr(10));
}
// gears... (hack)
else if (entry[1].compare(0, 4, "gear") == 0)
{
motor_source.source = Animation::MotorSource::SOURCE_GEAR_FORWARD;
motor_source.motor = this->ParseArgUint(entry[1].substr(4));
}
else
{
snprintf(warn_msg, WARN_LEN, "Invalid 'source': %s, ignoring...", entry[1].c_str());
Expand Down
2 changes: 1 addition & 1 deletion source/main/utils/BitFlags.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ typedef uint32_t BitMask_t;
typedef uint64_t BitMask64_t;

#define BITMASK( OFFSET ) ( 1 << ((OFFSET) - 1) )
#define BITMASK64( OFFSET ) ( 1ull << ((OFFSET) - 1ull) )
#define BITMASK64( OFFSET ) ( BitMask64_t(1) << BitMask64_t((OFFSET) - 1) )

#define BITMASK_IS_0( VAR, FLAGS ) ( ((VAR) & (FLAGS)) == 0 )
#define BITMASK_IS_1( VAR, FLAGS ) ( ((VAR) & (FLAGS)) == (FLAGS) )
Expand Down