diff --git a/Doc/FuncStats.xlsx b/Doc/FuncStats.xlsx index 8a91eb6..92c39db 100644 Binary files a/Doc/FuncStats.xlsx and b/Doc/FuncStats.xlsx differ diff --git a/SpaceCadetPinball/TBlocker.cpp b/SpaceCadetPinball/TBlocker.cpp index fec1903..221b1b7 100644 --- a/SpaceCadetPinball/TBlocker.cpp +++ b/SpaceCadetPinball/TBlocker.cpp @@ -1,2 +1,73 @@ #include "pch.h" #include "TBlocker.h" + + +#include "control.h" +#include "loader.h" +#include "render.h" +#include "timer.h" +#include "TZmapList.h" + +TBlocker::TBlocker(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true) +{ + visualStruct visual{}; + + loader::query_visual(groupIndex, 0, &visual); + SoundIndex4 = visual.SoundIndex4; + SoundIndex3 = visual.SoundIndex3; + Unknown0 = 55; + Unknown1 = 5; + MaxCollisionSpeed = 1000000000.0f; + Timer = 0; + MessageField = 0; + UnknownBaseFlag2 = 0; + render::sprite_set_bitmap(RenderSprite, nullptr); +} + +int TBlocker::Message(int code, float value) +{ + switch (code) + { + case 1011: + case 1020: + case 1024: + case 51: + if (Timer) + { + timer::kill(Timer); + Timer = 0; + } + MessageField = 0; + UnknownBaseFlag2 = 0; + render::sprite_set_bitmap(RenderSprite, nullptr); + if (code == 51) + loader::play_sound(SoundIndex3); + return 0; + case 52: + UnknownBaseFlag2 = 1; + loader::play_sound(SoundIndex4); + render::sprite_set_bitmap(RenderSprite, static_cast(ListBitmap->Get(0))); + break; + case 59: + break; + default: + return 0; + } + if (Timer) + timer::kill(Timer); + + float timerTime; + if (value <= 0.0) + timerTime = 0.0; + else + timerTime = value; + Timer = timer::set(timerTime, this, TimerExpired); + return 0; +} + +void TBlocker::TimerExpired(int timerId, void* caller) +{ + auto blocker = static_cast(caller); + blocker->Timer = 0; + control::handler(60, blocker); +} diff --git a/SpaceCadetPinball/TBlocker.h b/SpaceCadetPinball/TBlocker.h index a8f97ec..1882263 100644 --- a/SpaceCadetPinball/TBlocker.h +++ b/SpaceCadetPinball/TBlocker.h @@ -5,7 +5,14 @@ class TBlocker : public TCollisionComponent { public: - TBlocker(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true) - { - } + TBlocker(TPinballTable* table, int groupIndex); + int Message(int code, float value) override; + + static void TimerExpired(int timerId, void* caller); + + int Unknown0; + int Unknown1; + int Timer; + int SoundIndex4; + int SoundIndex3; }; diff --git a/SpaceCadetPinball/TBumper.cpp b/SpaceCadetPinball/TBumper.cpp index a1fbd91..9e1e6ce 100644 --- a/SpaceCadetPinball/TBumper.cpp +++ b/SpaceCadetPinball/TBumper.cpp @@ -1,2 +1,152 @@ #include "pch.h" #include "TBumper.h" + + +#include "control.h" +#include "loader.h" +#include "render.h" +#include "timer.h" +#include "TPinballTable.h" +#include "TZmapList.h" + +TBumper::TBumper(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true) +{ + visualStruct visual{}; + + BmpIndex = 0; + Timer = 0; + TimerTime = *loader::query_float_attribute(groupIndex, 0, 407); + loader::query_visual(groupIndex, 0, &visual); + SoundIndex4 = visual.SoundIndex4; + SoundIndex3 = visual.SoundIndex3; + MaxCollisionSpeed2 = MaxCollisionSpeed; +} + +int TBumper::Message(int code, float value) +{ + switch (code) + { + case 11: + { + auto nextBmp = static_cast(floor(value)); + if (2 * nextBmp > ListBitmap->Count() - 1) + nextBmp = (ListBitmap->Count() - 1) / 2; + if (nextBmp < 0) + nextBmp = 0; + if (nextBmp != BmpIndex) + { + if (nextBmp >= BmpIndex) + loader::play_sound(SoundIndex4); + if (nextBmp < BmpIndex) + loader::play_sound(SoundIndex3); + BmpIndex = nextBmp; + Fire(); + control::handler(11, this); + } + break; + } + case 12: + { + auto nextBmp = BmpIndex + 1; + auto maxBmp = ListBitmap->Count() - 1; + if (2 * nextBmp > maxBmp) + nextBmp = maxBmp / 2; + TBumper::Message(11, static_cast(nextBmp)); + break; + } + case 13: + { + auto nextBmp = BmpIndex - 1; + if (nextBmp < 0) + nextBmp = 0; + TBumper::Message(11, static_cast(nextBmp)); + break; + } + case 1020: + { + auto playerPtr = &PlayerData[PinballTable->CurrentPlayer]; + playerPtr->BmpIndex = BmpIndex; + playerPtr->MessageField = MessageField; + + playerPtr = &PlayerData[static_cast(floor(value))]; + BmpIndex = playerPtr->BmpIndex; + MessageField = playerPtr->MessageField; + TBumper::Message(11, static_cast(BmpIndex)); + break; + } + case 1024: + { + if (Timer) + { + timer::kill(Timer); + TimerExpired(Timer, this); + } + BmpIndex = 0; + MessageField = 0; + auto playerPtr = PlayerData; + for (auto index = 0; index < PinballTable->PlayerCount; ++index) + { + playerPtr->BmpIndex = 0; + playerPtr->MessageField = 0; + ++playerPtr; + } + TimerExpired(0, this); + break; + } + default: + break; + } + + return 0; +} + +void TBumper::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, TEdgeSegment* edge) +{ + if (DefaultCollision(ball, nextPosition, direction)) + { + Fire(); + control::handler(63, this); + } +} + +void TBumper::put_scoring(int index, int score) +{ + if (index < 4) + Scores[index] = score; +} + + +int TBumper::get_scoring(int index) +{ + return index < 4 ? Scores[index] : 0; +} + +void TBumper::TimerExpired(int timerId, void* caller) +{ + auto bump = static_cast(caller); + auto bmp = static_cast(bump->ListBitmap->Get(bump->BmpIndex * 2)); + auto zMap = static_cast(bump->ListZMap->Get(bump->BmpIndex * 2)); + bump->Timer = 0; + render::sprite_set( + bump->RenderSprite, + bmp, + zMap, + bmp->XPosition - bump->PinballTable->XOffset, + bmp->YPosition - bump->PinballTable->YOffset); + bump->MaxCollisionSpeed = bump->MaxCollisionSpeed2; +} + +void TBumper::Fire() +{ + int bmpIndex = 2 * BmpIndex + 1; + auto bmp = static_cast(ListBitmap->Get(bmpIndex)); + auto zMap = static_cast(ListZMap->Get(bmpIndex)); + render::sprite_set( + RenderSprite, + bmp, + zMap, + bmp->XPosition - PinballTable->XOffset, + bmp->YPosition - PinballTable->YOffset); + Timer = timer::set(TimerTime, this, TimerExpired); + MaxCollisionSpeed = 1000000000.0; +} diff --git a/SpaceCadetPinball/TBumper.h b/SpaceCadetPinball/TBumper.h index ecda7f7..7309c50 100644 --- a/SpaceCadetPinball/TBumper.h +++ b/SpaceCadetPinball/TBumper.h @@ -1,11 +1,33 @@ #pragma once #include "TCollisionComponent.h" +struct TBumper_player_backup +{ + int MessageField; + int BmpIndex; +}; + class TBumper : public TCollisionComponent { public: - TBumper(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true) - { - } + TBumper(TPinballTable* table, int groupIndex); + ~TBumper() override = default; + int Message(int code, float value) override; + void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, + TEdgeSegment* edge) override; + void put_scoring(int index, int score) override; + int get_scoring(int index) override; + void Fire(); + + static void TimerExpired(int timerId, void* caller); + + int BmpIndex; + int Timer; + float TimerTime; + float MaxCollisionSpeed2; + int SoundIndex4; + int SoundIndex3; + int Scores[4]; + TBumper_player_backup PlayerData[4]; }; diff --git a/SpaceCadetPinball/TFlagSpinner.cpp b/SpaceCadetPinball/TFlagSpinner.cpp index 880c15c..1b51261 100644 --- a/SpaceCadetPinball/TFlagSpinner.cpp +++ b/SpaceCadetPinball/TFlagSpinner.cpp @@ -1,2 +1,148 @@ #include "pch.h" #include "TFlagSpinner.h" + + +#include "control.h" +#include "loader.h" +#include "objlist_class.h" +#include "render.h" +#include "TBall.h" +#include "timer.h" +#include "TLine.h" +#include "TPinballTable.h" +#include "TZmapList.h" + +TFlagSpinner::TFlagSpinner(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false) +{ + visualStruct visual{}; + vector_type end{}, start{}; + + Timer = 0; + loader::query_visual(groupIndex, 0, &visual); + end.X = *visual.FloatArr; + end.Y = visual.FloatArr[1]; + start.X = visual.FloatArr[2]; + start.Y = visual.FloatArr[3]; + auto line = new TLine(this, &UnknownBaseFlag2, visual.Flag, &start, &end); + if (line) + { + line->place_in_grid(); + EdgeList->Add(line); + } + + line = new TLine(this, &UnknownBaseFlag2, visual.Flag, &end, &start); + PrevCollider = line; + if (line) + { + line->place_in_grid(); + EdgeList->Add(line); + } + + SpeedDecrement = 0.64999998f; + MaxSpeed = 50000.0f; + MinSpeed = 5.0f; + auto speedDec = loader::query_float_attribute(groupIndex, 0, 1202); + if (speedDec) + SpeedDecrement = *speedDec; + auto maxSpeed = loader::query_float_attribute(groupIndex, 0, 1200); + if (maxSpeed) + MaxSpeed = *maxSpeed; + auto minSpeed = loader::query_float_attribute(groupIndex, 0, 1201); + if (minSpeed) + MinSpeed = *minSpeed; +} + +int TFlagSpinner::Message(int code, float value) +{ + if (code == 1024) + { + if (Timer) + { + timer::kill(Timer); + Timer = 0; + } + BmpIndex = 0; + auto bmp = static_cast(ListBitmap->Get(0)); + auto zMap = static_cast(ListZMap->Get(0)); + render::sprite_set( + RenderSprite, + bmp, + zMap, + bmp->XPosition - PinballTable->XOffset, + bmp->YPosition - PinballTable->YOffset); + } + return 0; +} + +void TFlagSpinner::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, + TEdgeSegment* edge) +{ + ball->Position.X = nextPosition->X; + ball->Position.Y = nextPosition->Y; + ball->RayMaxDistance = ball->RayMaxDistance - coef; + ball->not_again(edge); + + SpinDirection = 2 * (PrevCollider != edge) - 1; + if (ball->Speed == 0.0) + Speed = MinSpeed; + else + Speed = ball->Speed * 20.0f; + if (Speed < MinSpeed) + Speed = MinSpeed; + if (Speed > MaxSpeed) + Speed = MaxSpeed; + NextFrame(); +} + +void TFlagSpinner::put_scoring(int index, int score) +{ + if (index < 2) + Scores[index] = score; +} + +int TFlagSpinner::get_scoring(int index) +{ + return index < 2 ? Scores[index] : 0; +} + +void TFlagSpinner::NextFrame() +{ + BmpIndex += SpinDirection; + int bmpIndex = BmpIndex; + int bmpCount = ListBitmap->Count(); + if (bmpIndex >= bmpCount) + BmpIndex = 0; + else if (bmpIndex < 0) + BmpIndex = bmpCount - 1; + + if (!PinballTable->TiltLockFlag) + { + control::handler(63, this); + if (SoundIndex2) + loader::play_sound(SoundIndex2); + if (!BmpIndex) + control::handler(62, this); + } + + auto bmp = static_cast(ListBitmap->Get(BmpIndex)); + auto zMap = static_cast(ListZMap->Get(BmpIndex)); + render::sprite_set( + RenderSprite, + bmp, + zMap, + bmp->XPosition - PinballTable->XOffset, + bmp->YPosition - PinballTable->YOffset); + + Speed *= SpeedDecrement; + if (Speed >= MinSpeed) + { + timer::set(1.0f / Speed, this, SpinTimer); + } +} + +void TFlagSpinner::SpinTimer(int timerId, void* caller) +{ + auto spinner = static_cast(caller); + spinner->Timer = 0; + spinner->NextFrame(); +} diff --git a/SpaceCadetPinball/TFlagSpinner.h b/SpaceCadetPinball/TFlagSpinner.h index 06f98ba..b47632e 100644 --- a/SpaceCadetPinball/TFlagSpinner.h +++ b/SpaceCadetPinball/TFlagSpinner.h @@ -5,7 +5,24 @@ class TFlagSpinner : public TCollisionComponent { public: - TFlagSpinner(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false) - { - } + TFlagSpinner(TPinballTable* table, int groupIndex); + int Message(int code, float value) override; + void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, + TEdgeSegment* edge) override; + void put_scoring(int index, int score) override; + int get_scoring(int index) override; + void NextFrame(); + + static void SpinTimer(int timerId, void* caller); + + float Speed; + float MaxSpeed; + float MinSpeed; + float SpeedDecrement; + int SpinDirection; + int BmpIndex; + int Timer; + TEdgeSegment* PrevCollider; + int Scores[2]; }; + diff --git a/SpaceCadetPinball/TFlipperEdge.cpp b/SpaceCadetPinball/TFlipperEdge.cpp index 2187f5f..f15fc1f 100644 --- a/SpaceCadetPinball/TFlipperEdge.cpp +++ b/SpaceCadetPinball/TFlipperEdge.cpp @@ -446,7 +446,7 @@ int TFlipperEdge::is_ball_inside(float x, float y) dy * dy + dx * dx <= CirclebaseRadiusSq || (T1.Y - y) * (T1.Y - y) + (T1.X - x) * (T1.X - x) < CircleT1RadiusSq) { - float flipperLR = AngleMax < 0.0 ? -1 : 1; + float flipperLR = AngleMax < 0.0 ? -1.0f : 1.0f; if (FlipperFlag == 1) testPoint = AngleMax < 0.0 ? B1 : B2; else if (FlipperFlag == 2) diff --git a/SpaceCadetPinball/TGate.cpp b/SpaceCadetPinball/TGate.cpp index 658a405..b166c0b 100644 --- a/SpaceCadetPinball/TGate.cpp +++ b/SpaceCadetPinball/TGate.cpp @@ -1,2 +1,42 @@ #include "pch.h" #include "TGate.h" + + +#include "control.h" +#include "loader.h" +#include "render.h" +#include "TZmapList.h" + +TGate::TGate(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true) +{ + visualStruct visual{}; + + loader::query_visual(groupIndex, 0, &visual); + SoundIndex4 = visual.SoundIndex4; + SoundIndex3 = visual.SoundIndex3; + UnknownBaseFlag2 = 1; + render::sprite_set_bitmap(RenderSprite, static_cast(ListBitmap->Get(0))); + control::handler(1024, this); +} + +int TGate::Message(int code, float value) +{ + if (code != 1020) + { + if (code == 53) + { + UnknownBaseFlag2 = 0; + render::sprite_set_bitmap(RenderSprite, nullptr); + loader::play_sound(SoundIndex3); + } + else if (code == 54 || code == 1024) + { + UnknownBaseFlag2 = 1; + render::sprite_set_bitmap(RenderSprite, static_cast(ListBitmap->Get(0))); + if (code == 54) + loader::play_sound(SoundIndex4); + } + control::handler(code, this); + } + return 0; +} diff --git a/SpaceCadetPinball/TGate.h b/SpaceCadetPinball/TGate.h index ac762f2..687df72 100644 --- a/SpaceCadetPinball/TGate.h +++ b/SpaceCadetPinball/TGate.h @@ -5,7 +5,9 @@ class TGate : public TCollisionComponent { public: - TGate(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true) - { - } + TGate(TPinballTable* table, int groupIndex); + int Message(int code, float value) override; + + int SoundIndex4; + int SoundIndex3; }; diff --git a/SpaceCadetPinball/THole.cpp b/SpaceCadetPinball/THole.cpp index c3a5722..c2b7c7e 100644 --- a/SpaceCadetPinball/THole.cpp +++ b/SpaceCadetPinball/THole.cpp @@ -1,2 +1,148 @@ #include "pch.h" #include "THole.h" + + +#include "control.h" +#include "loader.h" +#include "objlist_class.h" +#include "TBall.h" +#include "timer.h" +#include "TPinballTable.h" +#include "TTableLayer.h" + +THole::THole(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false) +{ + visualStruct visual{}; + circle_type circle{}; + + Unknown4 = 0.050000001f; + MessageField = 0; + Timer = 0; + BallCapturedFlag = 0; + auto floatArr1 = loader::query_float_attribute(groupIndex, 0, 407); + if (floatArr1) + Unknown3 = *floatArr1; + else + Unknown3 = 0.25; + auto floatArr2 = loader::query_float_attribute(groupIndex, 0, 701); + if (floatArr2) + GravityMult = *floatArr2; + else + GravityMult = 0.5; + GravityPull = *loader::query_float_attribute(groupIndex, 0, 305); + + loader::query_visual(groupIndex, 0, &visual); + Circle.Center.X = visual.FloatArr[0]; + Circle.Center.Y = visual.FloatArr[1]; + Circle.RadiusSq = *loader::query_float_attribute(groupIndex, 0, 306) * visual.FloatArr[2]; + if (Circle.RadiusSq == 0.0) + Circle.RadiusSq = 0.001f; + + auto tCircle = new TCircle(this, &UnknownBaseFlag2, visual.Flag, reinterpret_cast(visual.FloatArr), + Circle.RadiusSq); + if (tCircle) + { + tCircle->place_in_grid(); + EdgeList->Add(tCircle); + } + + ZSetValue = loader::query_float_attribute(groupIndex, 0, 408)[2]; + FieldFlag = static_cast(floor(*loader::query_float_attribute(groupIndex, 0, 1304))); + + Circle.RadiusSq = visual.FloatArr[2] * visual.FloatArr[2]; + circle.RadiusSq = Circle.RadiusSq; + circle.Center.X = Circle.Center.X; + circle.Center.Y = Circle.Center.Y; + circle.Center.Z = Circle.Center.Z; + + Field.Flag2Ptr = &UnknownBaseFlag2; + Field.CollisionComp = this; + Field.Mask = visual.Flag; + TTableLayer::edges_insert_circle(&circle, nullptr, &Field); +} + +int THole::Message(int code, float value) +{ + if (code == 1024 && BallCapturedFlag) + { + if (Timer) + timer::kill(Timer); + Timer = 0; + BallCapturedSecondStage = 1; + } + return 0; +} + +void THole::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, TEdgeSegment* edge) +{ + if (!BallCapturedFlag) + { + BallCapturedSecondStage = 0; + MaxCollisionSpeed = 1000000000.0; + BallCapturedFlag = 1; + ball->CollisionComp = this; + ball->Position.X = Circle.Center.X; + ball->Position.Y = Circle.Center.Y; + ball->Acceleration.Z = 0.0; + Timer = timer::set(0.5f, this, TimerExpired); + if (!PinballTable->TiltLockFlag) + { + loader::play_sound(SoundIndex1); + control::handler(57, this); + } + } +} + +int THole::FieldEffect(TBall* ball, vector_type* vecDst) +{ + int result; + vector_type direction{}; + + if (BallCapturedFlag) + { + if (BallCapturedSecondStage) + { + ball->Acceleration.Z -= PinballTable->GravityDirVectMult * ball->TimeDelta * GravityMult; + ball->Position.Z += ball->Acceleration.Z; + if (ball->Position.Z <= ZSetValue) + { + BallCapturedFlag = 0; + BallCapturedSecondStage = 0; + ball->Position.Z = ZSetValue; + ball->Acceleration.Z = 0.0; + ball->FieldFlag = FieldFlag; + ball->Acceleration.Y = 0.0; + ball->CollisionComp = nullptr; + ball->Acceleration.X = 0.0; + ball->Speed = 0.0; + loader::play_sound(SoundIndex2); + control::handler(58, this); + } + } + result = 0; + } + else + { + direction.X = Circle.Center.X - ball->Position.X; + direction.Y = Circle.Center.Y - ball->Position.Y; + if (direction.X * direction.X + direction.Y * direction.Y <= Circle.RadiusSq) + { + maths::normalize_2d(&direction); + vecDst->X = direction.X * GravityPull - ball->Acceleration.X * ball->Speed; + vecDst->Y = direction.Y * GravityPull - ball->Acceleration.Y * ball->Speed; + result = 1; + } + else + { + result = 0; + } + } + return result; +} + +void THole::TimerExpired(int timerId, void* caller) +{ + auto hole = static_cast(caller); + hole->Timer = 0; + hole->BallCapturedSecondStage = 1; +} diff --git a/SpaceCadetPinball/THole.h b/SpaceCadetPinball/THole.h index abfe91a..7171238 100644 --- a/SpaceCadetPinball/THole.h +++ b/SpaceCadetPinball/THole.h @@ -1,11 +1,29 @@ #pragma once +#include "TCircle.h" #include "TCollisionComponent.h" +#include "TEdgeManager.h" class THole : public TCollisionComponent { public: - THole(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false) - { - } + THole(TPinballTable* table, int groupIndex); + int Message(int code, float value) override; + void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, + TEdgeSegment* edge) override; + int FieldEffect(TBall* ball, vector_type* vecDst) override; + + static void TimerExpired(int timerId, void* caller); + + int BallCapturedFlag; + int BallCapturedSecondStage; + int Timer; + float Unknown3; + float Unknown4; + float GravityMult; + float ZSetValue; + int FieldFlag; + float GravityPull; + circle_type Circle; + field_effect_type Field; }; diff --git a/SpaceCadetPinball/TKickback.cpp b/SpaceCadetPinball/TKickback.cpp index c8d7c6d..d422244 100644 --- a/SpaceCadetPinball/TKickback.cpp +++ b/SpaceCadetPinball/TKickback.cpp @@ -1,2 +1,95 @@ #include "pch.h" #include "TKickback.h" + + +#include "control.h" +#include "loader.h" +#include "maths.h" +#include "render.h" +#include "timer.h" +#include "TPinballTable.h" +#include "TZmapList.h" + +TKickback::TKickback(TPinballTable* table, int groupIndex): TCollisionComponent(table, groupIndex, true) +{ + MessageField = 0; + Timer = 0; + ActiveFlag = 0; + TimerTime = 0.69999999f; + TimerTime2 = 0.1f; + MaxCollisionSpeed = 1000000000.0f; +} + +int TKickback::Message(int code, float value) +{ + if ((code == 1011 || code == 1024) && Timer) + { + timer::kill(Timer); + if (ListBitmap) + render::sprite_set_bitmap(RenderSprite, nullptr); + Timer = 0; + ActiveFlag = 0; + MaxCollisionSpeed = 1000000000.0; + } + return 0; +} + +void TKickback::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, + TEdgeSegment* edge) +{ + if (PinballTable->TiltLockFlag) + { + maths::basic_collision(ball, nextPosition, direction, UnknownC4F, UnknownC5F, 0.0, + CollisionMultiplier); + } + else + { + if (!ActiveFlag) + { + MaxCollisionSpeed = 1000000000.0; + ActiveFlag = 1; + Timer = timer::set(TimerTime, this, TimerExpired); + } + if (DefaultCollision(ball, nextPosition, direction)) + ActiveFlag = 0; + } +} + +void TKickback::TimerExpired(int timerId, void* caller) +{ + auto kick = static_cast(caller); + + if (kick->ActiveFlag) + { + kick->MaxCollisionSpeed = 0.0; + kick->Timer = timer::set(kick->TimerTime2, kick, TimerExpired); + loader::play_sound(kick->SoundIndex1); + if (kick->ListBitmap) + { + auto bmp = static_cast(kick->ListBitmap->Get(1)); + auto zMap = static_cast(kick->ListZMap->Get(1)); + render::sprite_set( + kick->RenderSprite, + bmp, + zMap, + bmp->XPosition - kick->PinballTable->XOffset, + bmp->YPosition - kick->PinballTable->YOffset); + } + } + else + { + if (kick->ListBitmap) + { + auto bmp = static_cast(kick->ListBitmap->Get(0)); + auto zMap = static_cast(kick->ListZMap->Get(0)); + render::sprite_set( + kick->RenderSprite, + bmp, + zMap, + bmp->XPosition - kick->PinballTable->XOffset, + bmp->YPosition - kick->PinballTable->YOffset); + } + kick->Timer = 0; + control::handler(60, kick); + } +} diff --git a/SpaceCadetPinball/TKickback.h b/SpaceCadetPinball/TKickback.h index 4e72835..4c610cf 100644 --- a/SpaceCadetPinball/TKickback.h +++ b/SpaceCadetPinball/TKickback.h @@ -5,7 +5,15 @@ class TKickback : public TCollisionComponent { public: - TKickback(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true) - { - } + TKickback(TPinballTable* table, int groupIndex); + int Message(int code, float value) override; + void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, + TEdgeSegment* edge) override; + + static void TimerExpired(int timerId, void* caller); + + float TimerTime; + float TimerTime2; + int Timer; + int ActiveFlag; }; diff --git a/SpaceCadetPinball/TWall.cpp b/SpaceCadetPinball/TWall.cpp index 0d082dd..4cf139f 100644 --- a/SpaceCadetPinball/TWall.cpp +++ b/SpaceCadetPinball/TWall.cpp @@ -1,2 +1,59 @@ #include "pch.h" #include "TWall.h" + + +#include "control.h" +#include "render.h" +#include "timer.h" +#include "TZmapList.h" + +TWall::TWall(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true) +{ + if (RenderSprite) + render::sprite_set_bitmap(RenderSprite, nullptr); + if (ListBitmap) + BmpPtr = static_cast(ListBitmap->Get(0)); + Timer = 0; +} + +int TWall::Message(int code, float value) +{ + if (code == 1024 && Timer) + { + timer::kill(Timer); + TimerExpired(Timer, this); + } + return 0; +} + +void TWall::Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, TEdgeSegment* edge) +{ + if (DefaultCollision(ball, nextPosition, direction)) + { + if (BmpPtr) + { + render::sprite_set_bitmap(RenderSprite, BmpPtr); + Timer = timer::set(0.1f, this, TimerExpired); + } + control::handler(63, this); + } +} + +void TWall::put_scoring(int index, int score) +{ + if (index < 1) + Scores[index] = score; +} + +int TWall::get_scoring(int index) +{ + return index < 1 ? Scores[index] : 0; +} + +void TWall::TimerExpired(int timerId, void* caller) +{ + auto wall = static_cast(caller); + render::sprite_set_bitmap(wall->RenderSprite, nullptr); + wall->Timer = 0; + wall->MessageField = 0; +} diff --git a/SpaceCadetPinball/TWall.h b/SpaceCadetPinball/TWall.h index 8913f1b..01c0ba7 100644 --- a/SpaceCadetPinball/TWall.h +++ b/SpaceCadetPinball/TWall.h @@ -1,11 +1,23 @@ #pragma once + #include "TCollisionComponent.h" +struct gdrv_bitmap8; + class TWall : public TCollisionComponent { public: - TWall(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true) - { - } + TWall(TPinballTable* table, int groupIndex); + int Message(int code, float value) override; + void Collision(TBall* ball, vector_type* nextPosition, vector_type* direction, float coef, + TEdgeSegment* edge) override; + void put_scoring(int index, int score) override; + int get_scoring(int index) override; + + static void TimerExpired(int timerId, void* caller); + + int Timer; + gdrv_bitmap8* BmpPtr; + int Scores[1]; }; diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp index d9bcc59..caa09ef 100644 --- a/SpaceCadetPinball/winmain.cpp +++ b/SpaceCadetPinball/winmain.cpp @@ -17,7 +17,7 @@ HCURSOR winmain::mouse_hsave; int winmain::return_value = 0; int winmain::bQuit = 0; int winmain::activated; -int winmain::DispFrameRate = 1; +int winmain::DispFrameRate = 0; int winmain::DispGRhistory = 0; int winmain::single_step = 0; int winmain::has_focus = 1;