pb, cheats ready.

Collison v1, mouse fixed.
This commit is contained in:
oz 2021-01-06 17:06:13 +03:00
parent d267fd5c98
commit 1ea247e185
20 changed files with 773 additions and 284 deletions

Binary file not shown.

View File

@ -14,13 +14,13 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
{ {
visualStruct visual{}; visualStruct visual{};
Unknown9F = 0.0; TimeNow = 0.0;
Unknown7F = 0.0; RayMaxDistance = 0.0;
UnknownBaseFlag2 = 1; UnknownBaseFlag2 = 1;
Unknown16 = 0; CollisionComp = nullptr;
EdgeCollisionCount = 0; EdgeCollisionCount = 0;
Unknown8F = 0.0; TimeDelta = 0.0;
Unknown17 = 1; Unknown17F = 1;
CollisionFlag = 0; CollisionFlag = 0;
Speed = 0.0; Speed = 0.0;
Acceleration.Y = 0.0; Acceleration.Y = 0.0;
@ -113,16 +113,16 @@ int TBall::Message(int code, float value)
{ {
render::ball_set(RenderSprite, nullptr, 0.0, 0, 0); render::ball_set(RenderSprite, nullptr, 0.0, 0, 0);
Position.X = 0.0; Position.X = 0.0;
Unknown16 = 0; CollisionComp = nullptr;
Position.Y = 0.0; Position.Y = 0.0;
UnknownBaseFlag2 = 0; UnknownBaseFlag2 = 0;
CollisionFlag = 0; CollisionFlag = 0;
Unknown17 = 1; Unknown17F = 1;
Acceleration.Y = 0.0; Acceleration.Y = 0.0;
Position.Z = Offset; Position.Z = Offset;
Acceleration.X = 0.0; Acceleration.X = 0.0;
Speed = 0.0; Speed = 0.0;
Unknown7F = 0.0; RayMaxDistance = 0.0;
} }
return 0; return 0;
} }

View File

@ -2,6 +2,7 @@
#include "maths.h" #include "maths.h"
#include "TPinballComponent.h" #include "TPinballComponent.h"
class TCollisionComponent;
class TEdgeSegment; class TEdgeSegment;
class TBall : public TPinballComponent class TBall : public TPinballComponent
@ -16,15 +17,15 @@ public :
vector_type Position; vector_type Position;
vector_type Acceleration; vector_type Acceleration;
float Speed; float Speed;
float Unknown7F; float RayMaxDistance;
float Unknown8F; float TimeDelta;
float Unknown9F; float TimeNow;
vector_type InvAcceleration; vector_type InvAcceleration;
int Unknown13; int Unknown13;
int Unknown14; int Unknown14;
int Unknown15; int Unknown15;
int Unknown16; TCollisionComponent* CollisionComp;
int Unknown17; float Unknown17F;
TEdgeSegment* Collisions[5]; TEdgeSegment* Collisions[5];
int EdgeCollisionCount; int EdgeCollisionCount;
vector_type CollisionOffset; vector_type CollisionOffset;

View File

@ -46,7 +46,7 @@ TCollisionComponent::~TCollisionComponent()
EdgeList->Delete(edge); EdgeList->Delete(edge);
delete edge; delete edge;
} }
delete this->EdgeList; delete EdgeList;
} }
@ -57,3 +57,64 @@ void TCollisionComponent::port_draw()
static_cast<TEdgeSegment*>(EdgeList->Get(index))->port_draw(); static_cast<TEdgeSegment*>(EdgeList->Get(index))->port_draw();
} }
} }
int TCollisionComponent::DefaultCollision(TBall* ball, vector_type* ballPosition, vector_type* vec2)
{
if (PinballTable->TiltLockFlag)
{
maths::basic_collision(ball, ballPosition, vec2, UnknownC4F, UnknownC5F, 1000000000.0, 0.0);
return 0;
}
auto projSpeed = maths::basic_collision(ball, ballPosition, vec2, UnknownC4F, UnknownC5F,
UnknownC7F,
UnknownC6F);
if (projSpeed <= UnknownC7F)
{
if (projSpeed > 0.2)
{
if (SoundIndex2)
loader::play_sound(SoundIndex2);
}
return 0;
}
if (SoundIndex1)
loader::play_sound(SoundIndex1);
return 1;
}
void TCollisionComponent::Collision(TBall* ball, struct vector_type* ballPosition, struct vector_type* vec2,
float someVal, TEdgeSegment* edge)
{
int soundIndex;
if (PinballTable->TiltLockFlag)
{
maths::basic_collision(ball, ballPosition, vec2, UnknownC4F, UnknownC5F, 1000000000.0, 0.0);
return;
}
double projSpeed = maths::basic_collision(
ball,
ballPosition,
vec2,
UnknownC4F,
UnknownC5F,
UnknownC7F,
UnknownC6F);
if (projSpeed <= UnknownC7F)
{
if (projSpeed <= 0.2)
return;
soundIndex = SoundIndex2;
}
else
{
soundIndex = SoundIndex1;
}
if (soundIndex)
loader::play_sound(soundIndex);
}
int TCollisionComponent::FieldEffect(TBall* ball, vector_type* vecDst)
{
return 0;
}

View File

@ -2,6 +2,9 @@
#include "objlist_class.h" #include "objlist_class.h"
#include "TPinballComponent.h" #include "TPinballComponent.h"
class TEdgeSegment;
class TBall;
class TCollisionComponent : public TPinballComponent class TCollisionComponent : public TPinballComponent
{ {
public: public:
@ -18,4 +21,8 @@ public:
TCollisionComponent(TPinballTable* table, int groupIndex, bool createWall); TCollisionComponent(TPinballTable* table, int groupIndex, bool createWall);
~TCollisionComponent(); ~TCollisionComponent();
void port_draw() override; void port_draw() override;
virtual void Collision(TBall* ball, struct vector_type* ballPosition, struct vector_type* vec2, float someVal,
TEdgeSegment* edge);
virtual int FieldEffect(TBall* ball, struct vector_type* vecDst);
int DefaultCollision(TBall* ball, struct vector_type* ballPosition, struct vector_type* vec2);
}; };

View File

@ -1,6 +1,16 @@
#include "pch.h" #include "pch.h"
#include "TEdgeManager.h" #include "TEdgeManager.h"
int TEdgeManager::FieldEffects(TBall* ball, vector_type* vecDst)
{
return 0;
}
void TEdgeManager::edges_insert_square(float a1, float a2, float a3, float a4, TEdgeSegment* a5, field_effect_type* a6) void TEdgeManager::edges_insert_square(float a1, float a2, float a3, float a4, TEdgeSegment* a5, field_effect_type* a6)
{ {
} }
float TEdgeManager::FindCollisionDistance(ray_type* ray, TBall* ball, TEdgeSegment** edge)
{
return 1000000000.0;
}

View File

@ -16,5 +16,8 @@ public:
{ {
} }
int FieldEffects(TBall* ball, struct vector_type* vecDst);
static void edges_insert_square(float a1, float a2, float a3, float a4, TEdgeSegment* a5, field_effect_type* a6); static void edges_insert_square(float a1, float a2, float a3, float a4, TEdgeSegment* a5, field_effect_type* a6);
float FindCollisionDistance(ray_type* ray, TBall* ball, TEdgeSegment** edge);
}; };

View File

@ -403,7 +403,7 @@ int TPinballTable::Message(int code, float value)
} }
else else
{ {
UnknownP6 = 0; CheatsUsed = 0;
Message(1024, 0.0); Message(1024, 0.0);
auto ball = static_cast<TBall*>(BallList->Get(0)); auto ball = static_cast<TBall*>(BallList->Get(0));
ball->Position.Y = 0.0; ball->Position.Y = 0.0;

View File

@ -45,7 +45,7 @@ public:
scoreStruct* CurScoreStruct; scoreStruct* CurScoreStruct;
scoreStruct* ScoreBallcount; scoreStruct* ScoreBallcount;
scoreStruct* ScorePlayerNumber1; scoreStruct* ScorePlayerNumber1;
int UnknownP6; int CheatsUsed;
int SoundIndex1; int SoundIndex1;
int SoundIndex2; int SoundIndex2;
int SoundIndex3; int SoundIndex3;

View File

@ -2,7 +2,11 @@
#include "control.h" #include "control.h"
#include "objlist_class.h" #include "objlist_class.h"
#include "pb.h"
#include "TPinballTable.h" #include "TPinballTable.h"
#include "TSound.h"
int control::pbctrl_state;
int control_bump_scores1[] = {500, 1000, 1500, 2000}; int control_bump_scores1[] = {500, 1000, 1500, 2000};
int control_roll_scores1[] = {2000}; int control_roll_scores1[] = {2000};
@ -502,7 +506,7 @@ component_tag* control::simple_components[142]
&control_soundwave7_tag &control_soundwave7_tag
}; };
int control::table_control_flag; int control::table_unlimited_balls;
void control::make_links(TPinballTable* table) void control::make_links(TPinballTable* table)
@ -570,6 +574,227 @@ void control::handler(int code, TPinballComponent* cmp)
MissionControl(code, cmp); MissionControl(code, cmp);
} }
void control::pbctrl_bdoor_controller(int key)
{
int v1; // eax
int v2; // eax
bool v3; // zf
if (!control_lite198_tag.Component->MessageField)
{
if (key <= 'M')
{
if (key == 'M')
{
v2 = pbctrl_state;
if (pbctrl_state == 4 || pbctrl_state == 61 || pbctrl_state == 81 || pbctrl_state == 101)
goto LABEL_87;
v3 = pbctrl_state == 121;
}
else
{
if (key <= 'D')
{
if (key != 'D')
{
if (key == ' ')
{
if (pbctrl_state == 26)
{
pbctrl_state = 27;
return;
}
goto LABEL_77;
}
if (key != '1')
{
if (key != 'A')
{
if (key != 'B')
{
if (key == 'C')
{
if (!pbctrl_state)
{
pbctrl_state = 1;
return;
}
if (pbctrl_state == 11)
{
pbctrl_state = 12;
return;
}
}
goto LABEL_77;
}
v1 = pbctrl_state != 0 ? 0 : 81;
goto LABEL_88;
}
v2 = pbctrl_state;
if (pbctrl_state == 5 || pbctrl_state == 62 || pbctrl_state == 82 || pbctrl_state == 102)
goto LABEL_87;
v3 = pbctrl_state == 122;
goto LABEL_86;
}
v1 = pbctrl_state != 0 ? 0 : 61;
LABEL_88:
pbctrl_state = v1;
return;
}
if (pbctrl_state != 22 && pbctrl_state != 23)
goto LABEL_77;
LABEL_58:
++pbctrl_state;
return;
}
if (key != 'E')
{
switch (key)
{
case 'G':
v1 = pbctrl_state != 0 ? 0 : 101;
break;
case 'H':
v1 = pbctrl_state != 0 ? 0 : 21;
break;
case 'I':
v2 = pbctrl_state;
if (pbctrl_state == 1 || pbctrl_state == 10)
goto LABEL_87;
v3 = pbctrl_state == 21;
goto LABEL_86;
default:
goto LABEL_77;
}
goto LABEL_88;
}
v2 = pbctrl_state;
if (pbctrl_state == 3 || pbctrl_state == 24 || pbctrl_state == 28)
goto LABEL_87;
v3 = pbctrl_state == 44;
}
goto LABEL_86;
}
if (key <= 'S')
{
if (key == 'S')
{
v2 = pbctrl_state;
if (pbctrl_state == 12 || pbctrl_state == 29)
goto LABEL_87;
v3 = pbctrl_state == 45;
}
else
{
if (key != 'N')
{
if (key != 'O')
{
if (key != 'Q')
{
if (key == 'R')
{
if (!pbctrl_state)
{
pbctrl_state = 121;
return;
}
if (pbctrl_state == 7)
{
pbctrl_state = 8;
return;
}
}
goto LABEL_77;
}
v1 = pbctrl_state != 0 ? 0 : 41;
goto LABEL_88;
}
if (pbctrl_state != 8 && pbctrl_state != 42)
goto LABEL_77;
goto LABEL_58;
}
v2 = pbctrl_state;
if (pbctrl_state == 2 || pbctrl_state == 9)
goto LABEL_87;
v3 = pbctrl_state == 25;
}
LABEL_86:
if (v3)
{
LABEL_87:
v1 = v2 + 1;
goto LABEL_88;
}
LABEL_77:
pbctrl_state = 0;
return;
}
switch (key)
{
case 'T':
v2 = pbctrl_state;
if (pbctrl_state != 30)
{
if (pbctrl_state == 27 || pbctrl_state == 6)
goto LABEL_87;
v3 = pbctrl_state == 43;
goto LABEL_86;
}
pb::cheat_mode = 1;
break;
case 'U':
if (pbctrl_state == 41)
{
pbctrl_state = 42;
return;
}
goto LABEL_77;
case 'X':
if (pbctrl_state == 63)
{
table_add_extra_ball(2.0);
goto LABEL_76;
}
if (pbctrl_state != 83)
{
if (pbctrl_state == 103)
{
GravityWellKickoutControl(64, nullptr);
}
else
{
if (pbctrl_state != 123)
goto LABEL_77;
cheat_bump_rank();
}
LABEL_76:
TableG->CheatsUsed = 1;
goto LABEL_77;
}
table_unlimited_balls = 1;
break;
default:
goto LABEL_77;
}
TableG->CheatsUsed = 1;
goto LABEL_77;
}
}
void control::table_add_extra_ball(float count)
{
++TableG->ExtraBalls;
static_cast<TSound*>(control_soundwave28_tag.Component)->Play();
auto msg = pinball::get_rc_string(9, 0);
static_cast<TTextBox*>(control_info_text_box_tag.Component)->Display(msg, count);
}
int control::cheat_bump_rank()
{
return 0;
}
void control::FlipperRebounderControl1(int code, TPinballComponent* caller) void control::FlipperRebounderControl1(int code, TPinballComponent* caller)
{ {
} }
@ -806,7 +1031,7 @@ void control::table_control_handler(int code)
{ {
if (code == 1011) if (code == 1011)
{ {
table_control_flag = 0; table_unlimited_balls = 0;
control_lite77_tag.Component->Message(7, 0.0); control_lite77_tag.Component->Message(7, 0.0);
} }
} }

View File

@ -30,11 +30,14 @@ public:
static TPinballTable* TableG; static TPinballTable* TableG;
static component_info score_components[88]; static component_info score_components[88];
static component_tag* simple_components[142]; static component_tag* simple_components[142];
static int table_control_flag; static int table_unlimited_balls;
static void make_links(TPinballTable* table); static void make_links(TPinballTable* table);
static TPinballComponent* make_component_link(component_tag* tag); static TPinballComponent* make_component_link(component_tag* tag);
static void handler(int code, TPinballComponent* cmp); static void handler(int code, TPinballComponent* cmp);
static void pbctrl_bdoor_controller(int key);
static void table_add_extra_ball(float count);
static int cheat_bump_rank();
static void FlipperRebounderControl1(int code, TPinballComponent* caller); static void FlipperRebounderControl1(int code, TPinballComponent* caller);
static void FlipperRebounderControl2(int code, TPinballComponent* caller); static void FlipperRebounderControl2(int code, TPinballComponent* caller);
@ -96,4 +99,7 @@ public:
static void BallDrainControl(int code, TPinballComponent* caller); static void BallDrainControl(int code, TPinballComponent* caller);
static void table_control_handler(int code); static void table_control_handler(int code);
private:
static int pbctrl_state;
}; };

View File

@ -320,7 +320,7 @@ void fullscrn::fillRect(int right, int bottom)
} }
} }
int fullscrn::convert_mouse_pos(unsigned int mouseXY) unsigned fullscrn::convert_mouse_pos(unsigned int mouseXY)
{ {
unsigned __int16 x = mouseXY & 0xffFF - render::vscreen.XPosition; unsigned __int16 x = mouseXY & 0xffFF - render::vscreen.XPosition;
unsigned __int16 y = (mouseXY >> 16) - render::vscreen.YPosition; unsigned __int16 y = (mouseXY >> 16) - render::vscreen.YPosition;

View File

@ -25,7 +25,7 @@ public:
static void center_in(HWND parent, HWND child); static void center_in(HWND parent, HWND child);
static int displaychange(); static int displaychange();
static void activate(int flag); static void activate(int flag);
static int convert_mouse_pos(unsigned int mouseXY); static unsigned convert_mouse_pos(unsigned int mouseXY);
static void getminmaxinfo(MINMAXINFO* maxMin); static void getminmaxinfo(MINMAXINFO* maxMin);
static void paint(); static void paint();
static bool set_menu_mode(int menuEnabled); static bool set_menu_mode(int menuEnabled);

View File

@ -1,6 +1,8 @@
#include "pch.h" #include "pch.h"
#include "maths.h" #include "maths.h"
#include "TBall.h"
void maths::enclosing_box(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect) void maths::enclosing_box(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect)
{ {
@ -203,23 +205,19 @@ void maths::line_init(line_type* line, float x0, float y0, float x1, float y1)
float maths::ray_intersect_line(ray_type* ray, line_type* line) float maths::ray_intersect_line(ray_type* ray, line_type* line)
{ {
// Similar to https://rootllama.wordpress.com/2014/06/20/ray-line-segment-intersection-test-in-2d/
float perpDot;
float result;
float v4;
bool v5; bool v5;
bool v6; bool v6;
float v7;
perpDot = line->PerpendicularL.Y * ray->Direction.Y + ray->Direction.X * line->PerpendicularL.X; float perpDot = line->PerpendicularL.Y * ray->Direction.Y + ray->Direction.X * line->PerpendicularL.X;
if (perpDot < 0.0) if (perpDot < 0.0)
{ {
result = -((ray->Origin.X * line->PerpendicularL.X + ray->Origin.Y * line->PerpendicularL.Y + line->PreComp1) float result = -((ray->Origin.X * line->PerpendicularL.X + ray->Origin.Y * line->PerpendicularL.Y + line->
PreComp1)
/ perpDot); / perpDot);
if (result >= -ray->MinDistance && result <= ray->MaxDistance) if (result >= -ray->MinDistance && result <= ray->MaxDistance)
{ {
line->CompTmp1 = result * ray->Direction.X + ray->Origin.X; line->CompTmp1 = result * ray->Direction.X + ray->Origin.X;
v4 = result * ray->Direction.Y + ray->Origin.Y; float v4 = result * ray->Direction.Y + ray->Origin.Y;
line->Unknown10 = v4; line->Unknown10 = v4;
if (0.0 == line->Direction.X) if (0.0 == line->Direction.X)
{ {
@ -234,7 +232,7 @@ float maths::ray_intersect_line(ray_type* ray, line_type* line)
} }
else if (line->OriginX <= line->CompTmp1) else if (line->OriginX <= line->CompTmp1)
{ {
v7 = line->CompTmp1; float v7 = line->CompTmp1;
v5 = v7 < line->OriginY; v5 = v7 < line->OriginY;
v6 = v7 == line->OriginY; v6 = v7 == line->OriginY;
if (v5 || v6) if (v5 || v6)
@ -269,3 +267,35 @@ void maths::vector_add(vector_type* vec1Dst, vector_type* vec2)
vec1Dst->X += vec2->X; vec1Dst->X += vec2->X;
vec1Dst->Y += vec2->Y; vec1Dst->Y += vec2->Y;
} }
float maths::basic_collision(TBall* ball, vector_type* ballPosition, vector_type* vec2, float a4, float a5, float a6,
float a7)
{
ball->Position.X = ballPosition->X;
ball->Position.Y = ballPosition->Y;
float proj = -(vec2->Y * ball->Acceleration.Y + vec2->X * ball->Acceleration.X);
if (proj < 0)
{
proj = -proj;
}
else
{
float dx1 = proj * vec2->X;
float dy1 = proj * vec2->Y;
float v17 = dx1 + ball->Acceleration.X;
float v18 = dy1 + ball->Acceleration.Y;
ball->Acceleration.X = v17 * a5 + dx1 * a4;
ball->Acceleration.Y = v18 * a5 + dy1 * a4;
normalize_2d(&ball->Acceleration);
}
float projSpeed = proj * ball->Speed;
float newSpeed = ball->Speed - (1.0f - a4) * projSpeed;
ball->Speed = newSpeed;
if (projSpeed >= a6)
{
ball->Acceleration.X = newSpeed * ball->Acceleration.X + vec2->X * a7;
ball->Acceleration.Y = newSpeed * ball->Acceleration.Y + vec2->Y * a7;
ball->Speed = normalize_2d(&ball->Acceleration);
}
return projSpeed;
}

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
class TBall;
struct vector_type struct vector_type
{ {
float X; float X;
@ -28,6 +30,9 @@ struct __declspec(align(4)) ray_type
vector_type Direction; vector_type Direction;
float MaxDistance; float MaxDistance;
float MinDistance; float MinDistance;
float TimeNow;
float TimeDelta;
float Unknown2;
}; };
struct __declspec(align(4)) line_type struct __declspec(align(4)) line_type
@ -56,4 +61,5 @@ public:
static void cross(vector_type* vec1, vector_type* vec2, vector_type* dstVec); static void cross(vector_type* vec1, vector_type* vec2, vector_type* dstVec);
static float magnitude(vector_type* vec); static float magnitude(vector_type* vec);
static void vector_add(vector_type* vec1Dst, vector_type* vec2); static void vector_add(vector_type* vec1Dst, vector_type* vec2);
static float basic_collision(TBall* ball, struct vector_type* ballPosition, struct vector_type* vec2, float a4, float a5, float a6, float a7);
}; };

View File

@ -74,7 +74,7 @@ void nudge::_nudge(float xDiff, float yDiff)
for (auto index = 0; index < ballList->Count(); index++) for (auto index = 0; index < ballList->Count(); index++)
{ {
auto ball = static_cast<TBall*>(ballList->Get(index)); auto ball = static_cast<TBall*>(ballList->Get(index));
if (ball->UnknownBaseFlag2 && !ball->Unknown16) if (ball->UnknownBaseFlag2 && !ball->CollisionComp)
{ {
ball->Acceleration.X = ball->Acceleration.X * ball->Speed; ball->Acceleration.X = ball->Acceleration.X * ball->Speed;
ball->Acceleration.Y = ball->Acceleration.Y * ball->Speed; ball->Acceleration.Y = ball->Acceleration.Y * ball->Speed;

View File

@ -37,9 +37,9 @@ winhelp_entry options::keymap_help[18]
short options::vk_list[28] short options::vk_list[28]
{ {
0x8041, -32703,
0x5A, 0x5A,
0x8030, -32720,
0x39, 0x39,
0x402E, 0x402E,
0x402F, 0x402F,

View File

@ -1,6 +1,8 @@
#include "pch.h" #include "pch.h"
#include "pb.h" #include "pb.h"
#include "control.h"
#include "high_score.h" #include "high_score.h"
#include "memory.h" #include "memory.h"
#include "pinball.h" #include "pinball.h"
@ -17,6 +19,7 @@
#include "TDemo.h" #include "TDemo.h"
#include "TLightGroup.h" #include "TLightGroup.h"
#include "TPlunger.h" #include "TPlunger.h"
#include "TTableLayer.h"
TPinballTable* pb::MainTable = nullptr; TPinballTable* pb::MainTable = nullptr;
datFileStruct* pb::record_table = nullptr; datFileStruct* pb::record_table = nullptr;
@ -218,7 +221,7 @@ int pb::frame(int time)
if (!mode_countdown(time)) if (!mode_countdown(time))
{ {
time_next = time_now + timeMul; time_next = time_now + timeMul;
//pb::timed_frame(time_now, timeMul, 1); timed_frame(time_now, timeMul, true);
time_now = time_next; time_now = time_next;
time_ticks += time; time_ticks += time;
if (nudge::nudged_left || nudge::nudged_right || nudge::nudged_up) if (nudge::nudged_left || nudge::nudged_right || nudge::nudged_up)
@ -248,6 +251,62 @@ int pb::frame(int time)
return 1; return 1;
} }
void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls)
{
vector_type vec1{}, vec2{};
for (int i = 0; i < MainTable->BallList->Count(); i++)
{
auto ball = static_cast<TBall*>(MainTable->BallList->Get(i));
if (ball->UnknownBaseFlag2 != 0)
{
auto collComp = ball->CollisionComp;
if (collComp)
{
ball->TimeDelta = timeDelta;
collComp->FieldEffect(ball, &vec1);
}
else
{
if (MainTable->UnknownBaseFlag2)
{
vec2.X = 0.0;
vec2.Y = 0.0;
vec2.Z = 0.0;
TTableLayer::edge_manager->FieldEffects(ball, &vec2);
vec2.X = vec2.X * timeDelta;
vec2.Y = vec2.Y * timeDelta;
ball->Acceleration.X = ball->Speed * ball->Acceleration.X;
ball->Acceleration.Y = ball->Speed * ball->Acceleration.Y;
maths::vector_add(&ball->Acceleration, &vec2);
ball->Speed = maths::normalize_2d(&ball->Acceleration);
ball->InvAcceleration.X = ball->Acceleration.X == 0.0 ? 1000000000.0f : 1.0f / ball->Acceleration.X;
ball->InvAcceleration.Y = ball->Acceleration.Y == 0.0 ? 1000000000.0f : 1.0f / ball->Acceleration.Y;
}
auto timeDelta2 = timeDelta;
auto timeNow2 = timeNow;
for (auto index = 10; timeDelta2 > 0.000001 && index; --index)
{
auto time = collide(timeNow2, timeDelta2, ball);
timeDelta2 -= time;
timeNow2 += time;
}
}
}
}
if (drawBalls)
{
for (int i = 0; i < MainTable->BallList->Count(); i++)
{
auto ball = static_cast<TBall*>(MainTable->BallList->Get(i));
if (ball->UnknownBaseFlag2)
ball->Repaint();
}
}
}
void pb::window_size(int* width, int* height) void pb::window_size(int* width, int* height)
{ {
*width = 600; *width = 600;
@ -337,7 +396,7 @@ void pb::keydown(int key)
mode_countdown(-1); mode_countdown(-1);
return; return;
} }
ctrl_bdoor_controller(key); control::pbctrl_bdoor_controller(key);
if (key == options::Options.LeftFlipperKey) if (key == options::Options.LeftFlipperKey)
{ {
MainTable->Message(1000, time_now); MainTable->Message(1000, time_now);
@ -417,7 +476,7 @@ void pb::keydown(int key)
MessageBoxA(winmain::hwnd_frame, buffer, "Mem:", 0x2000u); MessageBoxA(winmain::hwnd_frame, buffer, "Mem:", 0x2000u);
break; break;
case 'R': case 'R':
cheat_bump_rank(); control::cheat_bump_rank();
break; break;
case VK_F11: case VK_F11:
gdrv::get_focus(); gdrv::get_focus();
@ -429,10 +488,6 @@ void pb::keydown(int key)
} }
} }
void pb::ctrl_bdoor_controller(int key)
{
}
int pb::mode_countdown(int time) int pb::mode_countdown(int time)
{ {
if (!game_mode || game_mode <= 0) if (!game_mode || game_mode <= 0)
@ -456,19 +511,57 @@ int pb::mode_countdown(int time)
return 0; return 0;
} }
int pb::cheat_bump_rank()
{
return 0;
}
void pb::launch_ball() void pb::launch_ball()
{ {
MainTable->Plunger->Message(1017, 0.0f); MainTable->Plunger->Message(1017, 0.0f);
} }
int pb::end_game() void pb::end_game()
{ {
return 0; int scores[4];
int scoreIndex[4];
char String1[200];
mode_change(2);
int playerCount = MainTable->PlayerCount;
score_struct_super* scorePtr = MainTable->PlayerScores;
for (auto index = 0; index < playerCount; ++index)
{
scores[index] = scorePtr->ScoreStruct->Score;
scoreIndex[index] = index;
++scorePtr;
}
for (auto i = 0; i < playerCount; ++i)
{
for (auto j = i; j < playerCount; ++j)
{
if (scores[j] > scores[i])
{
int score = scores[j];
scores[j] = scores[i];
scores[i] = score;
int index = scoreIndex[j];
scoreIndex[j] = scoreIndex[i];
scoreIndex[i] = index;
}
}
}
if (!demo_mode && !MainTable->CheatsUsed)
{
for (auto i = 0; i < playerCount; ++i)
{
int position = high_score::get_score_position(highscore_table, scores[i]);
if (position >= 0)
{
lstrcpyA(String1, pinball::get_rc_string(scoreIndex[i] + 26, 0));
high_score::show_and_set_high_score_dialog(highscore_table, scores[i], position, String1);
}
}
}
} }
void pb::high_scores() void pb::high_scores()
@ -500,3 +593,51 @@ bool pb::chk_highscore()
} }
return true; return true;
} }
float pb::collide(float timeNow, float timeDelta, TBall* ball)
{
ray_type ray{};
vector_type positionMod{};
if (ball->UnknownBaseFlag2 && !ball->CollisionComp)
{
if (ball_speed_limit < ball->Speed)
ball->Speed = ball_speed_limit;
auto maxDistance = timeDelta * ball->Speed;
ball->TimeDelta = timeDelta;
ball->RayMaxDistance = maxDistance;
ball->TimeNow = timeNow;
ray.Origin.X = ball->Position.X;
ray.Origin.Y = ball->Position.Y;
ray.Origin.Z = ball->Position.Z;
ray.Direction.X = ball->Acceleration.X;
ray.Direction.Y = ball->Acceleration.Y;
ray.Direction.Z = ball->Acceleration.Z;
ray.MaxDistance = maxDistance;
ray.Unknown2 = ball->Unknown17F;
ray.TimeNow = timeNow;
ray.TimeDelta = timeDelta;
ray.MinDistance = 0.0020000001f;
TEdgeSegment* edge = nullptr;
auto distance = TTableLayer::edge_manager->FindCollisionDistance(&ray, ball, &edge);
if (distance >= 1000000000.0)
{
maxDistance = timeDelta * ball->Speed;
ball->RayMaxDistance = maxDistance;
positionMod.X = maxDistance * ball->Acceleration.X;
positionMod.Y = maxDistance * ball->Acceleration.Y;
positionMod.Z = 0.0;
maths::vector_add(&ball->Position, &positionMod);
}
else
{
edge->EdgeCollision(ball, distance);
if (ball->Speed > 0.000000001)
return fabs(distance / ball->Speed);
}
}
return timeDelta;
}

View File

@ -3,6 +3,8 @@
#include "partman.h" #include "partman.h"
#include "TPinballTable.h" #include "TPinballTable.h"
class TBall;
class pb class pb
{ {
public: public:
@ -22,19 +24,19 @@ public:
static void replay_level(int demoMode); static void replay_level(int demoMode);
static void ballset(int x, int y); static void ballset(int x, int y);
static int frame(int time); static int frame(int time);
static void timed_frame(float timeNow, float timeDelta, bool drawBalls);
static void window_size(int* width, int* height); static void window_size(int* width, int* height);
static void pause_continue(); static void pause_continue();
static void loose_focus(); static void loose_focus();
static void keyup(int key); static void keyup(int key);
static void keydown(int key); static void keydown(int key);
static void ctrl_bdoor_controller(int key);
static int mode_countdown(int time); static int mode_countdown(int time);
static int cheat_bump_rank();
static void launch_ball(); static void launch_ball();
static int end_game(); static void end_game();
static void high_scores(); static void high_scores();
static void tilt_no_more(); static void tilt_no_more();
static bool chk_highscore(); static bool chk_highscore();
static float collide(float timeNow, float timeDelta, TBall* ball);
private : private :
static int demo_mode, mode_countdown_; static int demo_mode, mode_countdown_;
static float time_now, time_next; static float time_now, time_next;

View File

@ -410,8 +410,6 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
return 0; return 0;
} }
if (Msg <= WM_MENUSELECT)
{
switch (Msg) switch (Msg)
{ {
case WM_MENUSELECT: case WM_MENUSELECT:
@ -615,9 +613,9 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
{ {
mouse_down = 1; mouse_down = 1;
mouse_hsave = SetCursor(nullptr); mouse_hsave = SetCursor(nullptr);
auto lParam2 = fullscrn::convert_mouse_pos(lParam); auto mouseXY = fullscrn::convert_mouse_pos(lParam);
last_mouse_x = static_cast<unsigned __int16>(lParam2); last_mouse_x = mouseXY & 0xffFFu;
last_mouse_y = static_cast<unsigned int>(lParam2) >> 16; last_mouse_y = mouseXY >> 16;
SetCapture(hWnd); SetCapture(hWnd);
} }
return DefWindowProcA(hWnd, Msg, wParam, lParam); return DefWindowProcA(hWnd, Msg, wParam, lParam);
@ -654,7 +652,6 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
default: default:
return DefWindowProcA(hWnd, Msg, wParam, lParam); return DefWindowProcA(hWnd, Msg, wParam, lParam);
} }
}
pb::mode_countdown(-1); pb::mode_countdown(-1);
return DefWindowProcA(hWnd, Msg, wParam, lParam); return DefWindowProcA(hWnd, Msg, wParam, lParam);