mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-12-18 10:37:53 +01:00
Multiball part 1: control and component changes from FT.
The result is 3DPB/FT hybrid, with control closer to 3DPB and components closer to FT.
This commit is contained in:
parent
14a8d64b67
commit
c1c74878df
15 changed files with 354 additions and 154 deletions
|
@ -141,3 +141,9 @@ vector2 TBall::get_coordinates()
|
||||||
{
|
{
|
||||||
return TTableLayer::edge_manager->NormalizeBox(Position);
|
return TTableLayer::edge_manager->NormalizeBox(Position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TBall::Disable()
|
||||||
|
{
|
||||||
|
ActiveFlag = false;
|
||||||
|
render::sprite_set_bitmap(RenderSprite, nullptr);
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ public :
|
||||||
bool already_hit(TEdgeSegment* edge);
|
bool already_hit(TEdgeSegment* edge);
|
||||||
int Message(int code, float value) override;
|
int Message(int code, float value) override;
|
||||||
vector2 get_coordinates() override;
|
vector2 get_coordinates() override;
|
||||||
|
void Disable();
|
||||||
|
|
||||||
static void throw_ball(TBall* ball, vector3* direction, float angleMult, float speedMult1,
|
static void throw_ball(TBall* ball, vector3* direction, float angleMult, float speedMult1,
|
||||||
float speedMult2);
|
float speedMult2);
|
||||||
|
|
|
@ -23,16 +23,21 @@ int TDrain::Message(int code, float value)
|
||||||
timer::kill(Timer);
|
timer::kill(Timer);
|
||||||
Timer = 0;
|
Timer = 0;
|
||||||
}
|
}
|
||||||
PinballTable->BallInSink = 0;
|
PinballTable->BallInDrainFlag = 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDrain::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
|
void TDrain::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
|
||||||
{
|
{
|
||||||
ball->Message(1024, 0.0);
|
ball->Disable();
|
||||||
PinballTable->BallInSink = 1;
|
--PinballTable->MultiballCount;
|
||||||
Timer = timer::set(TimerTime, this, TimerCallback);
|
if (PinballTable->MultiballCount <= 0)
|
||||||
|
{
|
||||||
|
PinballTable->MultiballCount = 0;
|
||||||
|
PinballTable->BallInDrainFlag = 1;
|
||||||
|
Timer = timer::set(TimerTime, this, TimerCallback);
|
||||||
|
}
|
||||||
control::handler(63, this);
|
control::handler(63, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,20 +49,19 @@ TPinballTable::TPinballTable(): TPinballComponent(nullptr, -1, false)
|
||||||
CurScoreStruct = nullptr;
|
CurScoreStruct = nullptr;
|
||||||
ScoreBallcount = nullptr;
|
ScoreBallcount = nullptr;
|
||||||
ScorePlayerNumber1 = nullptr;
|
ScorePlayerNumber1 = nullptr;
|
||||||
BallInSink = 0;
|
BallInDrainFlag = 0;
|
||||||
ActiveFlag = 1;
|
ActiveFlag = 1;
|
||||||
TiltLockFlag = 0;
|
TiltLockFlag = 0;
|
||||||
EndGameTimeoutTimer = 0;
|
EndGameTimeoutTimer = 0;
|
||||||
LightShowTimer = 0;
|
LightShowTimer = 0;
|
||||||
ReplayTimer = 0;
|
ReplayTimer = 0;
|
||||||
TiltTimeoutTimer = 0;
|
TiltTimeoutTimer = 0;
|
||||||
MultiballFlag = 0;
|
MultiballFlag = false;
|
||||||
PlayerCount = 0;
|
PlayerCount = 0;
|
||||||
|
|
||||||
auto ballObj = new TBall(this);
|
auto ball = AddBall(0.0f, 0.0f);
|
||||||
BallList.push_back(ballObj);
|
ball->Disable();
|
||||||
if (ballObj)
|
|
||||||
ballObj->ActiveFlag = 0;
|
|
||||||
new TTableLayer(this);
|
new TTableLayer(this);
|
||||||
LightGroup = new TLightGroup(this, 0);
|
LightGroup = new TLightGroup(this, 0);
|
||||||
|
|
||||||
|
@ -287,7 +286,7 @@ void TPinballTable::ChangeBallCount(int count)
|
||||||
|
|
||||||
void TPinballTable::tilt(float time)
|
void TPinballTable::tilt(float time)
|
||||||
{
|
{
|
||||||
if (!TiltLockFlag && !BallInSink)
|
if (!TiltLockFlag && !BallInDrainFlag)
|
||||||
{
|
{
|
||||||
pinball::InfoTextBox->Clear();
|
pinball::InfoTextBox->Clear();
|
||||||
pinball::MissTextBox->Clear();
|
pinball::MissTextBox->Clear();
|
||||||
|
@ -452,6 +451,9 @@ int TPinballTable::Message(int code, float value)
|
||||||
LightShowTimer = timer::set(time, this, LightShow_timeout);
|
LightShowTimer = timer::set(time, this, LightShow_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Multi-ball is FT exclusive feature, at least for now.
|
||||||
|
if (pb::FullTiltMode)
|
||||||
|
MultiballFlag = true;
|
||||||
midi::play_track(MidiTracks::Track1, true);
|
midi::play_track(MidiTracks::Track1, true);
|
||||||
break;
|
break;
|
||||||
case 1018:
|
case 1018:
|
||||||
|
@ -573,9 +575,9 @@ int TPinballTable::Message(int code, float value)
|
||||||
ScoreSpecial3Flag = 0;
|
ScoreSpecial3Flag = 0;
|
||||||
UnknownP71 = 0;
|
UnknownP71 = 0;
|
||||||
ExtraBalls = 0;
|
ExtraBalls = 0;
|
||||||
UnknownP75 = 0;
|
MultiballCount = 0;
|
||||||
BallLockedCounter = 0;
|
BallLockedCounter = 0;
|
||||||
MultiballFlag = 0;
|
MultiballFlag = false;
|
||||||
UnknownP78 = 0;
|
UnknownP78 = 0;
|
||||||
ReplayActiveFlag = 0;
|
ReplayActiveFlag = 0;
|
||||||
ReplayTimer = 0;
|
ReplayTimer = 0;
|
||||||
|
@ -589,6 +591,63 @@ int TPinballTable::Message(int code, float value)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TBall* TPinballTable::AddBall(float x, float y)
|
||||||
|
{
|
||||||
|
TBall* ball = nullptr;
|
||||||
|
|
||||||
|
for (auto curBall : BallList)
|
||||||
|
{
|
||||||
|
if (!curBall->ActiveFlag)
|
||||||
|
{
|
||||||
|
ball = curBall;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ball != nullptr)
|
||||||
|
{
|
||||||
|
ball->ActiveFlag = 1;
|
||||||
|
ball->Position.Z = ball->Offset;
|
||||||
|
ball->Direction = {};
|
||||||
|
ball->Speed = 0;
|
||||||
|
ball->TimeDelta = 0;
|
||||||
|
ball->TimeNow = 0;
|
||||||
|
ball->EdgeCollisionCount = 0;
|
||||||
|
ball->CollisionFlag = 0;
|
||||||
|
ball->CollisionMask = 1;
|
||||||
|
ball->CollisionComp = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (BallList.size() >= 20)
|
||||||
|
return nullptr;
|
||||||
|
ball = new TBall(this);
|
||||||
|
BallList.push_back(ball);
|
||||||
|
}
|
||||||
|
|
||||||
|
ball->Position.X = x;
|
||||||
|
ball->Position.Y = y;
|
||||||
|
|
||||||
|
return ball;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TPinballTable::BallCountInRect(const RectF& rect)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
for (const auto ball : BallList)
|
||||||
|
{
|
||||||
|
if (ball->ActiveFlag &&
|
||||||
|
ball->Position.X >= rect.XMin &&
|
||||||
|
ball->Position.Y >= rect.YMin &&
|
||||||
|
ball->Position.X <= rect.XMax &&
|
||||||
|
ball->Position.Y <= rect.YMax)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
void TPinballTable::EndGame_timeout(int timerId, void* caller)
|
void TPinballTable::EndGame_timeout(int timerId, void* caller)
|
||||||
{
|
{
|
||||||
auto table = static_cast<TPinballTable*>(caller);
|
auto table = static_cast<TPinballTable*>(caller);
|
||||||
|
|
|
@ -9,6 +9,7 @@ class TPlunger;
|
||||||
class TDrain;
|
class TDrain;
|
||||||
class TDemo;
|
class TDemo;
|
||||||
class TLightGroup;
|
class TLightGroup;
|
||||||
|
struct RectF;
|
||||||
|
|
||||||
struct score_struct_super
|
struct score_struct_super
|
||||||
{
|
{
|
||||||
|
@ -34,6 +35,8 @@ public:
|
||||||
void tilt(float time);
|
void tilt(float time);
|
||||||
void port_draw() override;
|
void port_draw() override;
|
||||||
int Message(int code, float value) override;
|
int Message(int code, float value) override;
|
||||||
|
TBall* AddBall(float x, float y);
|
||||||
|
int BallCountInRect(const RectF& rect);
|
||||||
|
|
||||||
static void EndGame_timeout(int timerId, void* caller);
|
static void EndGame_timeout(int timerId, void* caller);
|
||||||
static void LightShow_timeout(int timerId, void* caller);
|
static void LightShow_timeout(int timerId, void* caller);
|
||||||
|
@ -49,7 +52,7 @@ public:
|
||||||
int SoundIndex1{};
|
int SoundIndex1{};
|
||||||
int SoundIndex2{};
|
int SoundIndex2{};
|
||||||
int SoundIndex3{};
|
int SoundIndex3{};
|
||||||
int BallInSink;
|
int BallInDrainFlag;
|
||||||
int CurScore{};
|
int CurScore{};
|
||||||
int CurScoreE9{};
|
int CurScoreE9{};
|
||||||
int LightShowTimer;
|
int LightShowTimer;
|
||||||
|
@ -86,9 +89,9 @@ public:
|
||||||
int BallCount{};
|
int BallCount{};
|
||||||
int MaxBallCount;
|
int MaxBallCount;
|
||||||
int ExtraBalls{};
|
int ExtraBalls{};
|
||||||
int UnknownP75{};
|
int MultiballCount{};
|
||||||
int BallLockedCounter{};
|
int BallLockedCounter{};
|
||||||
int MultiballFlag;
|
bool MultiballFlag;
|
||||||
int UnknownP78{};
|
int UnknownP78{};
|
||||||
int ReplayActiveFlag{};
|
int ReplayActiveFlag{};
|
||||||
int ReplayTimer;
|
int ReplayTimer;
|
||||||
|
|
|
@ -23,11 +23,17 @@ TPlunger::TPlunger(TPinballTable* table, int groupIndex) : TCollisionComponent(t
|
||||||
SoundIndexP2 = visual.SoundIndex3;
|
SoundIndexP2 = visual.SoundIndex3;
|
||||||
HardHitSoundId = visual.Kicker.HardHitSoundId;
|
HardHitSoundId = visual.Kicker.HardHitSoundId;
|
||||||
Threshold = 1000000000.0;
|
Threshold = 1000000000.0;
|
||||||
MaxPullback = 100;
|
|
||||||
|
// In FT, default max pullback is 50.
|
||||||
|
if (pb::FullTiltMode)
|
||||||
|
MaxPullback = 50;
|
||||||
|
else
|
||||||
|
MaxPullback = 100;
|
||||||
|
|
||||||
Elasticity = 0.5f;
|
Elasticity = 0.5f;
|
||||||
Smoothness = 0.5f;
|
Smoothness = 0.5f;
|
||||||
PullbackIncrement = static_cast<int>(100.0 / (ListBitmap->size() * 8.0));
|
PullbackIncrement = MaxPullback / (ListBitmap->size() * 8.0f);
|
||||||
Unknown4F = 0.025f;
|
PullbackDelay = 0.025f;
|
||||||
float* floatArr = loader::query_float_attribute(groupIndex, 0, 601);
|
float* floatArr = loader::query_float_attribute(groupIndex, 0, 601);
|
||||||
table->PlungerPositionX = floatArr[0];
|
table->PlungerPositionX = floatArr[0];
|
||||||
table->PlungerPositionY = floatArr[1];
|
table->PlungerPositionY = floatArr[1];
|
||||||
|
@ -35,10 +41,19 @@ TPlunger::TPlunger(TPinballTable* table, int groupIndex) : TCollisionComponent(t
|
||||||
|
|
||||||
void TPlunger::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
|
void TPlunger::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
|
||||||
{
|
{
|
||||||
if (PinballTable->TiltLockFlag)
|
if (PinballTable->TiltLockFlag || SomeCounter > 0)
|
||||||
Message(1017, 0.0);
|
{
|
||||||
auto boost = RandFloat() * Boost * 0.1f + Boost;
|
auto boost = RandFloat() * MaxPullback * 0.1f + MaxPullback;
|
||||||
maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, boost);
|
maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 0, boost);
|
||||||
|
if (SomeCounter)
|
||||||
|
SomeCounter--;
|
||||||
|
Message(1005, 0.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto boost = RandFloat() * Boost * 0.1f + Boost;
|
||||||
|
maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, boost);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int TPlunger::Message(int code, float value)
|
int TPlunger::Message(int code, float value)
|
||||||
|
@ -46,56 +61,76 @@ int TPlunger::Message(int code, float value)
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case 1004:
|
case 1004:
|
||||||
if (!PullbackTimer_)
|
if (!PullbackStartedFlag && PinballTable->MultiballCount > 0 && !PinballTable->TiltLockFlag)
|
||||||
{
|
{
|
||||||
|
PullbackStartedFlag = true;
|
||||||
Boost = 0.0;
|
Boost = 0.0;
|
||||||
Threshold = 1000000000.0;
|
Threshold = 1000000000.0;
|
||||||
loader::play_sound(HardHitSoundId, this, "TPlunger1");
|
loader::play_sound(HardHitSoundId, this, "TPlunger1");
|
||||||
PullbackTimer(0, this);
|
PullbackTimer(0, this);
|
||||||
}
|
}
|
||||||
return 0;
|
break;
|
||||||
case 1015:
|
case 1015:
|
||||||
{
|
{
|
||||||
auto ball = PinballTable->BallList.at(0);
|
RectF rect{};
|
||||||
ball->Message(1024, 0.0);
|
rect.XMin = PinballTable->CollisionCompOffset * -1.2f + PinballTable->PlungerPositionX;
|
||||||
ball->Position.X = PinballTable->PlungerPositionX;
|
rect.XMax = PinballTable->CollisionCompOffset * 1.2f + PinballTable->PlungerPositionX;
|
||||||
ball->Position.Y = PinballTable->PlungerPositionY;
|
rect.YMin = PinballTable->CollisionCompOffset * -1.2f + PinballTable->PlungerPositionY;
|
||||||
ball->ActiveFlag = 1;
|
rect.YMax = PinballTable->CollisionCompOffset * 1.2f + PinballTable->PlungerPositionY;
|
||||||
PinballTable->BallInSink = 0;
|
if(PinballTable->BallCountInRect(rect))
|
||||||
pb::tilt_no_more();
|
{
|
||||||
control::handler(code, this);
|
timer::set(1.0f, this, BallFeedTimer);
|
||||||
return 0;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto ball = PinballTable->AddBall(PinballTable->PlungerPositionX, PinballTable->PlungerPositionY);
|
||||||
|
assertm(ball, "Failure to create ball in plunger");
|
||||||
|
PinballTable->MultiballCount++;
|
||||||
|
PinballTable->BallInDrainFlag = 0;
|
||||||
|
pb::tilt_no_more();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case 1016:
|
case 1016:
|
||||||
if (BallFeedTimer_)
|
timer::set(0.95999998f, this, BallFeedTimer);
|
||||||
timer::kill(BallFeedTimer_);
|
|
||||||
BallFeedTimer_ = timer::set(0.95999998f, this, BallFeedTimer);
|
|
||||||
loader::play_sound(SoundIndexP1, this, "TPlunger2");
|
loader::play_sound(SoundIndexP1, this, "TPlunger2");
|
||||||
control::handler(code, this);
|
break;
|
||||||
return 0;
|
|
||||||
case 1017:
|
case 1017:
|
||||||
Threshold = 0.0;
|
PullbackStartedFlag = true;
|
||||||
Boost = static_cast<float>(MaxPullback);
|
Boost = MaxPullback;
|
||||||
timer::set(0.2f, this, PlungerReleasedTimer);
|
Message(1005, 0.0f);
|
||||||
|
break;
|
||||||
|
case 1018:
|
||||||
|
SomeCounter++;
|
||||||
|
timer::set(value, this, BallFeedTimer);
|
||||||
|
loader::play_sound(SoundIndexP1, this, "TPlunger2_1");
|
||||||
|
PullbackStartedFlag = true;
|
||||||
|
PullbackTimer(0, this);
|
||||||
|
break;
|
||||||
|
case 1020:
|
||||||
|
PullbackStartedFlag = false;
|
||||||
|
Boost = 0.0f;
|
||||||
|
Threshold = 1000000000.0f;
|
||||||
|
SomeCounter = 0;
|
||||||
|
timer::kill(BallFeedTimer);
|
||||||
|
timer::kill(PullbackTimer);
|
||||||
|
timer::kill(ReleasedTimer);
|
||||||
|
break;
|
||||||
|
case 1011:
|
||||||
|
SomeCounter = 0;
|
||||||
|
timer::kill(BallFeedTimer);
|
||||||
break;
|
break;
|
||||||
case 1005:
|
case 1005:
|
||||||
case 1009:
|
case 1009:
|
||||||
case 1010:
|
case 1010:
|
||||||
case 1024:
|
if (PullbackStartedFlag && !SomeCounter)
|
||||||
{
|
{
|
||||||
if (code == 1024)
|
PullbackStartedFlag = false;
|
||||||
{
|
|
||||||
if (BallFeedTimer_)
|
|
||||||
timer::kill(BallFeedTimer_);
|
|
||||||
BallFeedTimer_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Threshold = 0.0;
|
Threshold = 0.0;
|
||||||
if (PullbackTimer_)
|
if (PullbackTimer_)
|
||||||
timer::kill(PullbackTimer_);
|
timer::kill(PullbackTimer_);
|
||||||
PullbackTimer_ = 0;
|
PullbackTimer_ = 0;
|
||||||
if (code == 1005)
|
loader::play_sound(SoundIndexP2, this, "TPlunger3");
|
||||||
loader::play_sound(SoundIndexP2, this, "TPlunger3");
|
|
||||||
auto bmp = ListBitmap->at(0);
|
auto bmp = ListBitmap->at(0);
|
||||||
auto zMap = ListZMap->at(0);
|
auto zMap = ListZMap->at(0);
|
||||||
render::sprite_set(
|
render::sprite_set(
|
||||||
|
@ -105,38 +140,68 @@ int TPlunger::Message(int code, float value)
|
||||||
bmp->XPosition - PinballTable->XOffset,
|
bmp->XPosition - PinballTable->XOffset,
|
||||||
bmp->YPosition - PinballTable->YOffset);
|
bmp->YPosition - PinballTable->YOffset);
|
||||||
|
|
||||||
timer::set(Unknown4F, this, PlungerReleasedTimer);
|
timer::set(PullbackDelay, this, ReleasedTimer);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case 1024:
|
||||||
|
{
|
||||||
|
PullbackStartedFlag = false;
|
||||||
|
Boost = 0.0f;
|
||||||
|
Threshold = 1000000000.0f;
|
||||||
|
SomeCounter = 0;
|
||||||
|
|
||||||
|
timer::kill(BallFeedTimer);
|
||||||
|
timer::kill(PullbackTimer);
|
||||||
|
timer::kill(ReleasedTimer);
|
||||||
|
|
||||||
|
auto bmp = ListBitmap->at(0);
|
||||||
|
auto zMap = ListZMap->at(0);
|
||||||
|
render::sprite_set(
|
||||||
|
RenderSprite,
|
||||||
|
bmp,
|
||||||
|
zMap,
|
||||||
|
bmp->XPosition - PinballTable->XOffset,
|
||||||
|
bmp->YPosition - PinballTable->YOffset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
control::handler(code, this);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TPlunger::BallFeedTimer(int timerId, void* caller)
|
void TPlunger::BallFeedTimer(int timerId, void* caller)
|
||||||
{
|
{
|
||||||
auto plunger = static_cast<TPlunger*>(caller);
|
auto plunger = static_cast<TPlunger*>(caller);
|
||||||
plunger->PullbackTimer_ = 0;
|
|
||||||
plunger->Message(1015, 0.0);
|
plunger->Message(1015, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TPlunger::PullbackTimer(int timerId, void* caller)
|
void TPlunger::PullbackTimer(int timerId, void* caller)
|
||||||
{
|
{
|
||||||
auto plunger = static_cast<TPlunger*>(caller);
|
auto plunger = static_cast<TPlunger*>(caller);
|
||||||
plunger->Boost += static_cast<float>(plunger->PullbackIncrement);
|
plunger->Boost += plunger->PullbackIncrement;
|
||||||
if (plunger->Boost <= static_cast<float>(plunger->MaxPullback))
|
if (plunger->Boost <= plunger->MaxPullback)
|
||||||
{
|
{
|
||||||
plunger->PullbackTimer_ = timer::set(plunger->Unknown4F, plunger, PullbackTimer);
|
if (plunger->SomeCounter)
|
||||||
|
{
|
||||||
|
plunger->PullbackTimer_ = timer::set(plunger->PullbackDelay / 4.0f, plunger, PullbackTimer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
plunger->PullbackTimer_ = timer::set(plunger->PullbackDelay, plunger, PullbackTimer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
plunger->PullbackTimer_ = 0;
|
plunger->PullbackTimer_ = 0;
|
||||||
plunger->Boost = static_cast<float>(plunger->MaxPullback);
|
plunger->Boost = plunger->MaxPullback;
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = static_cast<int>(floor(
|
int index = static_cast<int>(floor(
|
||||||
static_cast<float>(plunger->ListBitmap->size() - 1) *
|
static_cast<float>(plunger->ListBitmap->size() - 1) *
|
||||||
(plunger->Boost / static_cast<float>(plunger->MaxPullback))));
|
(plunger->Boost / plunger->MaxPullback)));
|
||||||
auto bmp = plunger->ListBitmap->at(index);
|
auto bmp = plunger->ListBitmap->at(index);
|
||||||
auto zMap = plunger->ListZMap->at(index);
|
auto zMap = plunger->ListZMap->at(index);
|
||||||
render::sprite_set(
|
render::sprite_set(
|
||||||
|
@ -147,7 +212,7 @@ void TPlunger::PullbackTimer(int timerId, void* caller)
|
||||||
bmp->YPosition - plunger->PinballTable->YOffset);
|
bmp->YPosition - plunger->PinballTable->YOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TPlunger::PlungerReleasedTimer(int timerId, void* caller)
|
void TPlunger::ReleasedTimer(int timerId, void* caller)
|
||||||
{
|
{
|
||||||
auto plunger = static_cast<TPlunger*>(caller);
|
auto plunger = static_cast<TPlunger*>(caller);
|
||||||
plunger->Threshold = 1000000000.0;
|
plunger->Threshold = 1000000000.0;
|
||||||
|
|
|
@ -13,13 +13,15 @@ public:
|
||||||
|
|
||||||
static void BallFeedTimer(int timerId, void* caller);
|
static void BallFeedTimer(int timerId, void* caller);
|
||||||
static void PullbackTimer(int timerId, void* caller);
|
static void PullbackTimer(int timerId, void* caller);
|
||||||
static void PlungerReleasedTimer(int timerId, void* caller);
|
static void ReleasedTimer(int timerId, void* caller);
|
||||||
|
|
||||||
int PullbackTimer_;
|
int PullbackTimer_;
|
||||||
int BallFeedTimer_;
|
int BallFeedTimer_;
|
||||||
int MaxPullback;
|
float MaxPullback;
|
||||||
int PullbackIncrement;
|
float PullbackIncrement;
|
||||||
float Unknown4F;
|
float PullbackDelay;
|
||||||
int SoundIndexP1;
|
int SoundIndexP1;
|
||||||
int SoundIndexP2;
|
int SoundIndexP2;
|
||||||
|
bool PullbackStartedFlag{};
|
||||||
|
int SomeCounter{};
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,7 +14,6 @@ TSink::TSink(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
||||||
visualStruct visual{};
|
visualStruct visual{};
|
||||||
|
|
||||||
MessageField = 0;
|
MessageField = 0;
|
||||||
Timer = 0;
|
|
||||||
loader::query_visual(groupIndex, 0, &visual);
|
loader::query_visual(groupIndex, 0, &visual);
|
||||||
BallThrowDirection = visual.Kicker.ThrowBallDirection;
|
BallThrowDirection = visual.Kicker.ThrowBallDirection;
|
||||||
ThrowAngleMult = visual.Kicker.ThrowBallAngleMult;
|
ThrowAngleMult = visual.Kicker.ThrowBallAngleMult;
|
||||||
|
@ -35,27 +34,19 @@ int TSink::Message(int code, float value)
|
||||||
case 56:
|
case 56:
|
||||||
if (value < 0.0f)
|
if (value < 0.0f)
|
||||||
value = TimerTime;
|
value = TimerTime;
|
||||||
Timer = timer::set(value, this, TimerExpired);
|
timer::set(value, this, TimerExpired);
|
||||||
break;
|
break;
|
||||||
case 1020:
|
case 1020:
|
||||||
|
timer::kill(TimerExpired);
|
||||||
PlayerMessagefieldBackup[PinballTable->CurrentPlayer] = MessageField;
|
PlayerMessagefieldBackup[PinballTable->CurrentPlayer] = MessageField;
|
||||||
MessageField = PlayerMessagefieldBackup[static_cast<int>(floor(value))];
|
MessageField = PlayerMessagefieldBackup[static_cast<int>(floor(value))];
|
||||||
break;
|
break;
|
||||||
case 1024:
|
case 1024:
|
||||||
{
|
{
|
||||||
if (Timer)
|
timer::kill(TimerExpired);
|
||||||
timer::kill(Timer);
|
|
||||||
Timer = 0;
|
|
||||||
MessageField = 0;
|
MessageField = 0;
|
||||||
|
for (auto &msgBackup : PlayerMessagefieldBackup)
|
||||||
auto playerPtr = PlayerMessagefieldBackup;
|
msgBackup = 0;
|
||||||
for (auto index = 0; index < PinballTable->PlayerCount; ++index)
|
|
||||||
{
|
|
||||||
*playerPtr = 0;
|
|
||||||
|
|
||||||
++playerPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -66,15 +57,13 @@ int TSink::Message(int code, float value)
|
||||||
|
|
||||||
void TSink::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
|
void TSink::Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance, TEdgeSegment* edge)
|
||||||
{
|
{
|
||||||
Timer = 0;
|
|
||||||
if (PinballTable->TiltLockFlag)
|
if (PinballTable->TiltLockFlag)
|
||||||
{
|
{
|
||||||
maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 1000000000.0, 0.0);
|
maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 1000000000.0, 0.0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ball->ActiveFlag = 0;
|
ball->Disable();
|
||||||
render::sprite_set_bitmap(ball->RenderSprite, nullptr);
|
|
||||||
loader::play_sound(SoundIndex4, ball, "TSink1");
|
loader::play_sound(SoundIndex4, ball, "TSink1");
|
||||||
control::handler(63, this);
|
control::handler(63, this);
|
||||||
}
|
}
|
||||||
|
@ -82,15 +71,26 @@ void TSink::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl
|
||||||
|
|
||||||
void TSink::TimerExpired(int timerId, void* caller)
|
void TSink::TimerExpired(int timerId, void* caller)
|
||||||
{
|
{
|
||||||
|
RectF rect{};
|
||||||
|
|
||||||
auto sink = static_cast<TSink*>(caller);
|
auto sink = static_cast<TSink*>(caller);
|
||||||
auto ball = sink->PinballTable->BallList.at(0);
|
auto table = sink->PinballTable;
|
||||||
ball->CollisionComp = nullptr;
|
|
||||||
ball->ActiveFlag = 1;
|
rect.XMin = table->CollisionCompOffset * -2.0f + sink->BallPosition.X;
|
||||||
ball->Position.X = sink->BallPosition.X;
|
rect.XMax = table->CollisionCompOffset * 2.0f + sink->BallPosition.X;
|
||||||
ball->Position.Y = sink->BallPosition.Y;
|
rect.YMin = table->CollisionCompOffset * -2.0f + sink->BallPosition.Y;
|
||||||
TBall::throw_ball(ball, &sink->BallThrowDirection, sink->ThrowAngleMult, sink->ThrowSpeedMult1,
|
rect.YMax = table->CollisionCompOffset * 2.0f + sink->BallPosition.Y;
|
||||||
sink->ThrowSpeedMult2);
|
if (table->BallCountInRect(rect))
|
||||||
if (sink->SoundIndex3)
|
{
|
||||||
loader::play_sound(sink->SoundIndex3, ball, "TSink2");
|
timer::set(0.5f, sink, TimerExpired);
|
||||||
sink->Timer = 0;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto ball = table->AddBall(sink->BallPosition.X, sink->BallPosition.Y);
|
||||||
|
assertm(ball, "Failure to create ball in sink");
|
||||||
|
TBall::throw_ball(ball, &sink->BallThrowDirection, sink->ThrowAngleMult, sink->ThrowSpeedMult1,
|
||||||
|
sink->ThrowSpeedMult2);
|
||||||
|
if (sink->SoundIndex3)
|
||||||
|
loader::play_sound(sink->SoundIndex3, ball, "TSink2");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ public:
|
||||||
|
|
||||||
static void TimerExpired(int timerId, void* caller);
|
static void TimerExpired(int timerId, void* caller);
|
||||||
|
|
||||||
int Timer;
|
|
||||||
float TimerTime;
|
float TimerTime;
|
||||||
vector2 BallPosition{};
|
vector2 BallPosition{};
|
||||||
vector3 BallThrowDirection{};
|
vector3 BallThrowDirection{};
|
||||||
|
|
|
@ -108,6 +108,9 @@ component_tag<TLight> control_lite27_tag = {"lite27"};
|
||||||
component_tag<TLight> control_lite28_tag = {"lite28"};
|
component_tag<TLight> control_lite28_tag = {"lite28"};
|
||||||
component_tag<TLight> control_lite29_tag = {"lite29"};
|
component_tag<TLight> control_lite29_tag = {"lite29"};
|
||||||
component_tag<TLight> control_lite30_tag = {"lite30"};
|
component_tag<TLight> control_lite30_tag = {"lite30"};
|
||||||
|
component_tag<TLight> control_lite38_tag = {"lite38"};
|
||||||
|
component_tag<TLight> control_lite39_tag = {"lite39"};
|
||||||
|
component_tag<TLight> control_lite40_tag = {"lite40"};
|
||||||
component_tag<TLight> control_lite54_tag = {"lite54"};
|
component_tag<TLight> control_lite54_tag = {"lite54"};
|
||||||
component_tag<TLight> control_lite55_tag = {"lite55"};
|
component_tag<TLight> control_lite55_tag = {"lite55"};
|
||||||
component_tag<TLight> control_lite56_tag = {"lite56"};
|
component_tag<TLight> control_lite56_tag = {"lite56"};
|
||||||
|
@ -341,6 +344,9 @@ TLight*& lite27 = control_lite27_tag.Component;
|
||||||
TLight*& lite28 = control_lite28_tag.Component;
|
TLight*& lite28 = control_lite28_tag.Component;
|
||||||
TLight*& lite29 = control_lite29_tag.Component;
|
TLight*& lite29 = control_lite29_tag.Component;
|
||||||
TLight*& lite30 = control_lite30_tag.Component;
|
TLight*& lite30 = control_lite30_tag.Component;
|
||||||
|
TLight*& lite38 = control_lite38_tag.Component;
|
||||||
|
TLight*& lite39 = control_lite39_tag.Component;
|
||||||
|
TLight*& lite40 = control_lite40_tag.Component;
|
||||||
TLight*& lite54 = control_lite54_tag.Component;
|
TLight*& lite54 = control_lite54_tag.Component;
|
||||||
TLight*& lite55 = control_lite55_tag.Component;
|
TLight*& lite55 = control_lite55_tag.Component;
|
||||||
TLight*& lite56 = control_lite56_tag.Component;
|
TLight*& lite56 = control_lite56_tag.Component;
|
||||||
|
@ -615,7 +621,7 @@ component_info control::score_components[88]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
component_tag_base* control::simple_components[142]
|
component_tag_base* control::simple_components[145]
|
||||||
{
|
{
|
||||||
&control_lite8_tag,
|
&control_lite8_tag,
|
||||||
&control_lite9_tag,
|
&control_lite9_tag,
|
||||||
|
@ -758,7 +764,10 @@ component_tag_base* control::simple_components[142]
|
||||||
&control_lite322_tag,
|
&control_lite322_tag,
|
||||||
&control_goal_lights_tag,
|
&control_goal_lights_tag,
|
||||||
&control_soundwave25_tag,
|
&control_soundwave25_tag,
|
||||||
&control_soundwave7_tag
|
&control_soundwave7_tag,
|
||||||
|
&control_lite38_tag,
|
||||||
|
&control_lite39_tag,
|
||||||
|
&control_lite40_tag,
|
||||||
};
|
};
|
||||||
|
|
||||||
int control::waiting_deployment_flag;
|
int control::waiting_deployment_flag;
|
||||||
|
@ -953,25 +962,40 @@ void control::table_set_flag_lights()
|
||||||
info_text_box->Display(pinball::get_rc_string(51, 0), 2.0);
|
info_text_box->Display(pinball::get_rc_string(51, 0), 2.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void control::table_set_multiball()
|
void control::table_set_multiball(float time)
|
||||||
{
|
{
|
||||||
info_text_box->Display(pinball::get_rc_string(16, 0), 2.0);
|
if (TableG->MultiballCount <= 1)
|
||||||
midi::play_track(MidiTracks::Track3, true);
|
{
|
||||||
|
TableG->MultiballCount += 3;
|
||||||
|
sink1->Message(56, time);
|
||||||
|
sink2->Message(56, time);
|
||||||
|
sink3->Message(56, time);
|
||||||
|
lite38->Message(7, -1.0f);
|
||||||
|
lite39->Message(7, -1.0f);
|
||||||
|
lite40->Message(7, -1.0f);
|
||||||
|
info_text_box->Display(pinball::get_rc_string(16, 0), 2.0);
|
||||||
|
midi::play_track(MidiTracks::Track3, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void control::table_bump_ball_sink_lock()
|
void control::table_bump_ball_sink_lock()
|
||||||
{
|
{
|
||||||
if (TableG->BallLockedCounter == 2)
|
if (TableG->MultiballCount <= 1)
|
||||||
{
|
{
|
||||||
table_set_multiball();
|
TableG->MultiballCount--;
|
||||||
TableG->BallLockedCounter = 0;
|
if (TableG->BallLockedCounter == 2)
|
||||||
}
|
{
|
||||||
else
|
soundwave41->Play(nullptr, "table_bump_ball_sink_lock_set_multiball");
|
||||||
{
|
table_set_multiball(2.0);
|
||||||
TableG->BallLockedCounter = TableG->BallLockedCounter + 1;
|
TableG->BallLockedCounter = 0;
|
||||||
soundwave44->Play(nullptr, "table_bump_ball_sink_lock");
|
}
|
||||||
info_text_box->Display(pinball::get_rc_string(1, 0), 2.0);
|
else
|
||||||
TableG->Plunger->Message(1016, 0.0);
|
{
|
||||||
|
TableG->BallLockedCounter = TableG->BallLockedCounter + 1;
|
||||||
|
soundwave44->Play(nullptr, "table_bump_ball_sink_lock");
|
||||||
|
info_text_box->Display(pinball::get_rc_string(1, 0), 2.0);
|
||||||
|
TableG->Plunger->Message(1018, 2.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1630,19 +1654,30 @@ void control::WormHoleControl(int code, TPinballComponent* caller)
|
||||||
{
|
{
|
||||||
if (TableG->MultiballFlag)
|
if (TableG->MultiballFlag)
|
||||||
{
|
{
|
||||||
table_bump_ball_sink_lock();
|
if (TableG->MultiballCount == 1)
|
||||||
TableG->AddScore(10000);
|
{
|
||||||
|
table_bump_ball_sink_lock();
|
||||||
|
TableG->AddScore(10000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
table_set_replay(4.0);
|
||||||
|
TableG->AddScore(50000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info_text_box->Display(pinball::get_rc_string(49, 0), 2.0);
|
|
||||||
table_set_replay(4.0);
|
table_set_replay(4.0);
|
||||||
TableG->AddScore(sink->get_scoring(1));
|
TableG->AddScore(sink->get_scoring(1));
|
||||||
wormhole_tag_array2[sinkFlag]->GetComponent()->Message(16, sink->TimerTime);
|
|
||||||
wormhole_tag_array3[sinkFlag]->GetComponent()->Message(11, static_cast<float>(2 - sinkFlag));
|
|
||||||
wormhole_tag_array3[sinkFlag]->GetComponent()->Message(16, sink->TimerTime);
|
|
||||||
wormhole_tag_array1[sinkFlag]->GetComponent()->Message(56, sink->TimerTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info_text_box->Display(pinball::get_rc_string(49, 0), 2.0);
|
||||||
|
wormhole_tag_array2[sinkFlag]->GetComponent()->Message(16, sink->TimerTime);
|
||||||
|
wormhole_tag_array3[sinkFlag]->GetComponent()->Message(11, static_cast<float>(2 - sinkFlag));
|
||||||
|
wormhole_tag_array3[sinkFlag]->GetComponent()->Message(16, sink->TimerTime);
|
||||||
|
wormhole_tag_array1[sinkFlag]->GetComponent()->Message(56, sink->TimerTime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TableG->AddScore(sink->get_scoring(2));
|
TableG->AddScore(sink->get_scoring(2));
|
||||||
|
@ -2352,7 +2387,8 @@ void control::HyperspaceKickOutControl(int code, TPinballComponent* caller)
|
||||||
|
|
||||||
if (TableG->MultiballFlag)
|
if (TableG->MultiballFlag)
|
||||||
{
|
{
|
||||||
table_set_multiball();
|
auto duration = soundwave41->Play(nullptr, "HyperspaceKickOutControl_setMultiball");
|
||||||
|
table_set_multiball(duration);
|
||||||
}
|
}
|
||||||
if (TableG->ScoreSpecial3 < 100000)
|
if (TableG->ScoreSpecial3 < 100000)
|
||||||
TableG->ScoreSpecial3 = 100000;
|
TableG->ScoreSpecial3 = 100000;
|
||||||
|
@ -2580,10 +2616,18 @@ void control::BallDrainControl(int code, TPinballComponent* caller)
|
||||||
soundwave59->Play(nullptr, "BallDrainControl5");
|
soundwave59->Play(nullptr, "BallDrainControl5");
|
||||||
--TableG->UnknownP78;
|
--TableG->UnknownP78;
|
||||||
}
|
}
|
||||||
else if (TableG->UnknownP75)
|
else if (TableG->MultiballCount)
|
||||||
{
|
{
|
||||||
soundwave27->Play(nullptr, "BallDrainControl6");
|
if (TableG->MultiballCount == 1)
|
||||||
--TableG->UnknownP75;
|
{
|
||||||
|
lite38->Message(20, 0.0f);
|
||||||
|
lite39->Message(20, 0.0f);
|
||||||
|
midi::play_track(MidiTracks::Track1, false);
|
||||||
|
}
|
||||||
|
else if (TableG->MultiballCount == 2)
|
||||||
|
{
|
||||||
|
lite40->Message(20, 0.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -63,7 +63,7 @@ class control
|
||||||
public:
|
public:
|
||||||
static TPinballTable* TableG;
|
static TPinballTable* TableG;
|
||||||
static component_info score_components[88];
|
static component_info score_components[88];
|
||||||
static component_tag_base* simple_components[142];
|
static component_tag_base* simple_components[145];
|
||||||
static int waiting_deployment_flag;
|
static int waiting_deployment_flag;
|
||||||
static bool table_unlimited_balls;
|
static bool table_unlimited_balls;
|
||||||
static int RankRcArray[9], MissionRcArray[17], mission_select_scores[17];
|
static int RankRcArray[9], MissionRcArray[17], mission_select_scores[17];
|
||||||
|
@ -79,7 +79,7 @@ public:
|
||||||
static void table_set_bonus();
|
static void table_set_bonus();
|
||||||
static void table_set_jackpot();
|
static void table_set_jackpot();
|
||||||
static void table_set_flag_lights();
|
static void table_set_flag_lights();
|
||||||
static void table_set_multiball();
|
static void table_set_multiball(float time);
|
||||||
static void table_bump_ball_sink_lock();
|
static void table_bump_ball_sink_lock();
|
||||||
static void table_set_replay(float value);
|
static void table_set_replay(float value);
|
||||||
static void cheat_bump_rank();
|
static void cheat_bump_rank();
|
||||||
|
|
|
@ -85,6 +85,11 @@ struct ramp_plane_type
|
||||||
vector2 FieldForce;
|
vector2 FieldForce;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RectF
|
||||||
|
{
|
||||||
|
float XMax, YMax, XMin, YMin;
|
||||||
|
};
|
||||||
|
|
||||||
enum class FlipperIntersect
|
enum class FlipperIntersect
|
||||||
{
|
{
|
||||||
none = -1,
|
none = -1,
|
||||||
|
|
|
@ -241,10 +241,16 @@ void pb::ballset(float dx, float dy)
|
||||||
{
|
{
|
||||||
// dx and dy are normalized to window, ideally in [-1, 1]
|
// dx and dy are normalized to window, ideally in [-1, 1]
|
||||||
static constexpr float sensitivity = 7000;
|
static constexpr float sensitivity = 7000;
|
||||||
TBall* ball = MainTable->BallList.at(0);
|
|
||||||
ball->Direction.X = dx * sensitivity;
|
for (auto ball : MainTable->BallList)
|
||||||
ball->Direction.Y = dy * sensitivity;
|
{
|
||||||
ball->Speed = maths::normalize_2d(ball->Direction);
|
if (ball->ActiveFlag)
|
||||||
|
{
|
||||||
|
ball->Direction.X = dx * sensitivity;
|
||||||
|
ball->Direction.Y = dy * sensitivity;
|
||||||
|
ball->Speed = maths::normalize_2d(ball->Direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pb::frame(float dtMilliSec)
|
void pb::frame(float dtMilliSec)
|
||||||
|
@ -469,33 +475,8 @@ void pb::InputDown(GameInput input)
|
||||||
switch (input.Value)
|
switch (input.Value)
|
||||||
{
|
{
|
||||||
case 'b':
|
case 'b':
|
||||||
TBall* ball;
|
if (MainTable->AddBall(6.0f, 7.0f))
|
||||||
if (MainTable->BallList.empty())
|
MainTable->MultiballCount++;
|
||||||
{
|
|
||||||
ball = new TBall(MainTable);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (auto index = 0u; ;)
|
|
||||||
{
|
|
||||||
ball = MainTable->BallList.at(index);
|
|
||||||
if (!ball->ActiveFlag)
|
|
||||||
break;
|
|
||||||
++index;
|
|
||||||
if (index >= MainTable->BallList.size())
|
|
||||||
{
|
|
||||||
ball = new TBall(MainTable);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ball->ActiveFlag = 1;
|
|
||||||
ball->Position.X = 1.0;
|
|
||||||
ball->Position.Z = ball->Offset;
|
|
||||||
ball->Position.Y = 1.0;
|
|
||||||
ball->Direction.Z = 0.0;
|
|
||||||
ball->Direction.Y = 0.0;
|
|
||||||
ball->Direction.X = 0.0;
|
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,6 +61,35 @@ int timer::kill(int timerId)
|
||||||
return timerId;
|
return timerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int timer::kill(void(* callback)(int, void*))
|
||||||
|
{
|
||||||
|
auto count = 0;
|
||||||
|
timer_struct* current = ActiveList, * prev = nullptr;
|
||||||
|
for (auto index = 0; index < Count; index++)
|
||||||
|
{
|
||||||
|
if (current->Callback == callback)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
if (prev)
|
||||||
|
prev->NextTimer = current->NextTimer;
|
||||||
|
else
|
||||||
|
ActiveList = current->NextTimer;
|
||||||
|
current->NextTimer = FreeList;
|
||||||
|
FreeList = current;
|
||||||
|
if (--Count == index)
|
||||||
|
break;
|
||||||
|
current = current->NextTimer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prev = current;
|
||||||
|
current = current->NextTimer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
int timer::set(float time, void* caller, void (* callback)(int, void*))
|
int timer::set(float time, void* caller, void (* callback)(int, void*))
|
||||||
{
|
{
|
||||||
if (Count >= MaxCount)
|
if (Count >= MaxCount)
|
||||||
|
|
|
@ -15,6 +15,7 @@ public:
|
||||||
static int init(int count);
|
static int init(int count);
|
||||||
static void uninit();
|
static void uninit();
|
||||||
static int kill(int timerId);
|
static int kill(int timerId);
|
||||||
|
static int kill(void (*callback)(int, void*));
|
||||||
static int set(float time, void* caller, void (* callback)(int, void*));
|
static int set(float time, void* caller, void (* callback)(int, void*));
|
||||||
static int check();
|
static int check();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue