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{};
Unknown9F = 0.0;
Unknown7F = 0.0;
TimeNow = 0.0;
RayMaxDistance = 0.0;
UnknownBaseFlag2 = 1;
Unknown16 = 0;
CollisionComp = nullptr;
EdgeCollisionCount = 0;
Unknown8F = 0.0;
Unknown17 = 1;
TimeDelta = 0.0;
Unknown17F = 1;
CollisionFlag = 0;
Speed = 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);
Position.X = 0.0;
Unknown16 = 0;
CollisionComp = nullptr;
Position.Y = 0.0;
UnknownBaseFlag2 = 0;
CollisionFlag = 0;
Unknown17 = 1;
Unknown17F = 1;
Acceleration.Y = 0.0;
Position.Z = Offset;
Acceleration.X = 0.0;
Speed = 0.0;
Unknown7F = 0.0;
RayMaxDistance = 0.0;
}
return 0;
}

View file

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

View file

@ -46,7 +46,7 @@ TCollisionComponent::~TCollisionComponent()
EdgeList->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();
}
}
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 "TPinballComponent.h"
class TEdgeSegment;
class TBall;
class TCollisionComponent : public TPinballComponent
{
public:
@ -18,4 +21,8 @@ public:
TCollisionComponent(TPinballTable* table, int groupIndex, bool createWall);
~TCollisionComponent();
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 "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)
{
}
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);
float FindCollisionDistance(ray_type* ray, TBall* ball, TEdgeSegment** edge);
};

View file

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

View file

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

View file

@ -2,7 +2,11 @@
#include "control.h"
#include "objlist_class.h"
#include "pb.h"
#include "TPinballTable.h"
#include "TSound.h"
int control::pbctrl_state;
int control_bump_scores1[] = {500, 1000, 1500, 2000};
int control_roll_scores1[] = {2000};
@ -502,7 +506,7 @@ component_tag* control::simple_components[142]
&control_soundwave7_tag
};
int control::table_control_flag;
int control::table_unlimited_balls;
void control::make_links(TPinballTable* table)
@ -570,6 +574,227 @@ void control::handler(int code, TPinballComponent* 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)
{
}
@ -806,7 +1031,7 @@ void control::table_control_handler(int code)
{
if (code == 1011)
{
table_control_flag = 0;
table_unlimited_balls = 0;
control_lite77_tag.Component->Message(7, 0.0);
}
}

View file

@ -30,11 +30,14 @@ public:
static TPinballTable* TableG;
static component_info score_components[88];
static component_tag* simple_components[142];
static int table_control_flag;
static int table_unlimited_balls;
static void make_links(TPinballTable* table);
static TPinballComponent* make_component_link(component_tag* tag);
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 FlipperRebounderControl2(int code, TPinballComponent* caller);
@ -95,5 +98,8 @@ public:
static void MultiplierTargetControl(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 y = (mouseXY >> 16) - render::vscreen.YPosition;

View file

@ -25,7 +25,7 @@ public:
static void center_in(HWND parent, HWND child);
static int displaychange();
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 paint();
static bool set_menu_mode(int menuEnabled);

View file

@ -1,6 +1,8 @@
#include "pch.h"
#include "maths.h"
#include "TBall.h"
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)
{
// 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 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)
{
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);
if (result >= -ray->MinDistance && result <= ray->MaxDistance)
{
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;
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)
{
v7 = line->CompTmp1;
float v7 = line->CompTmp1;
v5 = v7 < line->OriginY;
v6 = v7 == line->OriginY;
if (v5 || v6)
@ -269,3 +267,35 @@ void maths::vector_add(vector_type* vec1Dst, vector_type* vec2)
vec1Dst->X += vec2->X;
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
class TBall;
struct vector_type
{
float X;
@ -28,6 +30,9 @@ struct __declspec(align(4)) ray_type
vector_type Direction;
float MaxDistance;
float MinDistance;
float TimeNow;
float TimeDelta;
float Unknown2;
};
struct __declspec(align(4)) line_type
@ -56,4 +61,5 @@ public:
static void cross(vector_type* vec1, vector_type* vec2, vector_type* dstVec);
static float magnitude(vector_type* vec);
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++)
{
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.Y = ball->Acceleration.Y * ball->Speed;

View file

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

View file

@ -1,6 +1,8 @@
#include "pch.h"
#include "pb.h"
#include "control.h"
#include "high_score.h"
#include "memory.h"
#include "pinball.h"
@ -17,6 +19,7 @@
#include "TDemo.h"
#include "TLightGroup.h"
#include "TPlunger.h"
#include "TTableLayer.h"
TPinballTable* pb::MainTable = nullptr;
datFileStruct* pb::record_table = nullptr;
@ -218,7 +221,7 @@ int pb::frame(int time)
if (!mode_countdown(time))
{
time_next = time_now + timeMul;
//pb::timed_frame(time_now, timeMul, 1);
timed_frame(time_now, timeMul, true);
time_now = time_next;
time_ticks += time;
if (nudge::nudged_left || nudge::nudged_right || nudge::nudged_up)
@ -248,6 +251,62 @@ int pb::frame(int time)
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)
{
*width = 600;
@ -337,7 +396,7 @@ void pb::keydown(int key)
mode_countdown(-1);
return;
}
ctrl_bdoor_controller(key);
control::pbctrl_bdoor_controller(key);
if (key == options::Options.LeftFlipperKey)
{
MainTable->Message(1000, time_now);
@ -417,7 +476,7 @@ void pb::keydown(int key)
MessageBoxA(winmain::hwnd_frame, buffer, "Mem:", 0x2000u);
break;
case 'R':
cheat_bump_rank();
control::cheat_bump_rank();
break;
case VK_F11:
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)
{
if (!game_mode || game_mode <= 0)
@ -456,19 +511,57 @@ int pb::mode_countdown(int time)
return 0;
}
int pb::cheat_bump_rank()
{
return 0;
}
void pb::launch_ball()
{
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()
@ -500,3 +593,51 @@ bool pb::chk_highscore()
}
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 "TPinballTable.h"
class TBall;
class pb
{
public:
@ -22,19 +24,19 @@ public:
static void replay_level(int demoMode);
static void ballset(int x, int y);
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 pause_continue();
static void loose_focus();
static void keyup(int key);
static void keydown(int key);
static void ctrl_bdoor_controller(int key);
static int mode_countdown(int time);
static int cheat_bump_rank();
static void launch_ball();
static int end_game();
static void end_game();
static void high_scores();
static void tilt_no_more();
static bool chk_highscore();
static float collide(float timeNow, float timeDelta, TBall* ball);
private :
static int demo_mode, mode_countdown_;
static float time_now, time_next;

View file

@ -312,7 +312,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
SetForegroundWindow(hWnd);
return 0;
}
if (Msg <= WM_ACTIVATEAPP)
{
switch (Msg)
@ -410,250 +410,247 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
return 0;
}
if (Msg <= WM_MENUSELECT)
switch (Msg)
{
switch (Msg)
case WM_MENUSELECT:
if (lParam)
return DefWindowProcA(hWnd, Msg, wParam, lParam);
if (fullscrn::screen_mode)
fullscrn::set_menu_mode(0);
return 0;
case WM_SYSKEYDOWN:
no_time_loss = 1;
if (fullscrn::screen_mode)
fullscrn::set_menu_mode(1);
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_GETMINMAXINFO:
fullscrn::getminmaxinfo((MINMAXINFO*)lParam);
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_DISPLAYCHANGE:
if (fullscrn::displaychange())
{
case WM_MENUSELECT:
if (lParam)
return DefWindowProcA(hWnd, Msg, wParam, lParam);
if (fullscrn::screen_mode)
fullscrn::set_menu_mode(0);
return 0;
case WM_SYSKEYDOWN:
no_time_loss = 1;
if (fullscrn::screen_mode)
fullscrn::set_menu_mode(1);
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_GETMINMAXINFO:
fullscrn::getminmaxinfo((MINMAXINFO*)lParam);
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_DISPLAYCHANGE:
if (fullscrn::displaychange())
{
options::Options.FullScreen = 0;
options::menu_check(Menu1_Full_Screen, 0);
}
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_KEYUP:
pb::keyup(wParam);
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_KEYDOWN:
if (!(lParam & 0x40000000))
pb::keydown(wParam);
switch (wParam)
{
case VK_ESCAPE:
if (options::Options.FullScreen)
options::toggle(0x193u);
SendMessageA(hwnd_frame, 0x112u, 0xF020u, 0);
break;
case VK_F1:
help_introduction(hinst, hWnd);
break;
case VK_F2:
new_game();
break;
case VK_F3:
pause();
break;
case VK_F4:
options::Options.FullScreen = 0;
options::menu_check(Menu1_Full_Screen, 0);
}
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_KEYUP:
pb::keyup(wParam);
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_KEYDOWN:
if (!(lParam & 0x40000000))
pb::keydown(wParam);
switch (wParam)
{
case VK_ESCAPE:
if (options::Options.FullScreen)
options::toggle(0x193u);
break;
case VK_F8:
if (!single_step)
pause();
options::keyboard();
break;
}
if (!pb::cheat_mode)
return DefWindowProcA(hWnd, Msg, wParam, lParam);
switch (wParam)
{
case 'H':
DispGRhistory = 1;
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case 'Y':
SetWindowTextA(hWnd, "Pinball");
DispFrameRate = DispFrameRate == 0;
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case VK_F1:
pb::frame(10);
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case VK_F15:
single_step = single_step == 0;
if (single_step == 0)
no_time_loss = 1;
return DefWindowProcA(hWnd, Msg, wParam, lParam);
default:
return DefWindowProcA(hWnd, Msg, wParam, lParam);
}
case WM_SYSCOMMAND:
switch (wParam & 0xFFF0)
{
case SC_MOVE:
if (fullscrn::screen_mode)
return 0;
break;
case SC_MINIMIZE:
if (!single_step)
pause();
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case SC_SCREENSAVE:
fullscrn::activate(0);
return DefWindowProcA(hWnd, Msg, wParam, lParam);
default: break;
}
end_pause();
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_INITMENU:
no_time_loss = 1;
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_COMMAND:
no_time_loss = 1;
switch (wParam)
{
case Menu1_Launch_Ball:
end_pause();
pb::launch_ball();
break;
case Menu1_Pause_Resume_Game:
SendMessageA(hwnd_frame, 0x112u, 0xF020u, 0);
break;
case VK_F1:
help_introduction(hinst, hWnd);
break;
case VK_F2:
new_game();
break;
case VK_F3:
pause();
break;
case VK_F4:
options::toggle(0x193u);
break;
case VK_F8:
if (!single_step)
pause();
break;
case Menu1_Demo:
end_pause();
pb::toggle_demo();
break;
case Menu1_Select_Table:
{
if (!single_step)
pause();
auto tmpBuf = memory::allocate(0x1F4u);
if (tmpBuf)
{
char cmdLine[0x1F4u];
options::get_string(nullptr, "Shell Exe", tmpBuf, pinball::WindowName, 500);
sprintf_s(
cmdLine,
"%s %s%lX %s%lX",
tmpBuf,
"select=",
(int)hwnd_frame,
"confirm=",
(int)hwnd_frame
* (int)hwnd_frame
* (int)hwnd_frame
* (int)hwnd_frame
* (int)hwnd_frame
* (int)hwnd_frame
* (int)hwnd_frame);
if (static_cast<int>(WinExec(cmdLine, 5u)) < 32)
{
auto caption = pinball::get_rc_string(170, 0);
auto text = pinball::get_rc_string(171, 0);
MessageBoxA(hwnd_frame, text, caption, 0x2010u);
}
memory::free(tmpBuf);
}
break;
}
case Menu1_1Player:
case Menu1_2Players:
case Menu1_3Players:
case Menu1_4Players:
options::toggle(wParam);
new_game();
break;
case Menu1_Help_Topics:
if (!single_step)
pause();
help_introduction(hinst, hWnd);
break;
case 106: // End game button?
pb::end_game();
break;
case Menu1_Full_Screen:
case Menu1_Sounds:
case Menu1_Music:
if (!single_step)
pause();
options::toggle(wParam);
break;
case Menu1_Player_Controls:
case 204: // Second controls button?
if (!single_step)
pause();
options::keyboard();
break;
case Menu1_Exit:
PostMessageA(hWnd, WM_QUIT, 0, 0);
break;
case Menu1_New_Game:
new_game();
break;
case Menu1_About_Pinball:
if (!single_step)
pause();
a_dialog(hinst, hWnd);
break;
case Menu1_High_Scores:
if (!single_step)
pause();
pb::high_scores();
break;
case 1: // Unknown button
midi::restart_midi_seq(lParam);
break;
default:
break;
}
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_LBUTTONDOWN:
if (pb::game_mode)
{
if (pb::cheat_mode)
{
mouse_down = 1;
mouse_hsave = SetCursor(nullptr);
auto lParam2 = fullscrn::convert_mouse_pos(lParam);
last_mouse_x = static_cast<unsigned __int16>(lParam2);
last_mouse_y = static_cast<unsigned int>(lParam2) >> 16;
SetCapture(hWnd);
}
return DefWindowProcA(hWnd, Msg, wParam, lParam);
}
options::keyboard();
break;
case WM_LBUTTONUP:
if (mouse_down)
{
mouse_down = 0;
SetCursor(mouse_hsave);
ReleaseCapture();
}
}
if (!pb::cheat_mode)
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
if (pb::game_mode)
return DefWindowProcA(hWnd, Msg, wParam, lParam);
break;
case WM_POWERBROADCAST:
if (wParam == 4 && options::Options.FullScreen)
{
options::Options.FullScreen = 0;
options::menu_check(Menu1_Full_Screen, 0);
fullscrn::set_screen_mode(options::Options.FullScreen);
}
switch (wParam)
{
case 'H':
DispGRhistory = 1;
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_PALETTECHANGED:
InvalidateRect(hWnd, nullptr, 0);
case 'Y':
SetWindowTextA(hWnd, "Pinball");
DispFrameRate = DispFrameRate == 0;
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_POINTERDEVICEINRANGE | LB_ADDSTRING:
if (wParam == 1)
midi::restart_midi_seq(lParam);
case VK_F1:
pb::frame(10);
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case VK_F15:
single_step = single_step == 0;
if (single_step == 0)
no_time_loss = 1;
return DefWindowProcA(hWnd, Msg, wParam, lParam);
default:
return DefWindowProcA(hWnd, Msg, wParam, lParam);
}
case WM_SYSCOMMAND:
switch (wParam & 0xFFF0)
{
case SC_MOVE:
if (fullscrn::screen_mode)
return 0;
break;
case SC_MINIMIZE:
if (!single_step)
pause();
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case SC_SCREENSAVE:
fullscrn::activate(0);
return DefWindowProcA(hWnd, Msg, wParam, lParam);
default: break;
}
end_pause();
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_INITMENU:
no_time_loss = 1;
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_COMMAND:
no_time_loss = 1;
switch (wParam)
{
case Menu1_Launch_Ball:
end_pause();
pb::launch_ball();
break;
case Menu1_Pause_Resume_Game:
pause();
break;
case Menu1_Demo:
end_pause();
pb::toggle_demo();
break;
case Menu1_Select_Table:
{
if (!single_step)
pause();
auto tmpBuf = memory::allocate(0x1F4u);
if (tmpBuf)
{
char cmdLine[0x1F4u];
options::get_string(nullptr, "Shell Exe", tmpBuf, pinball::WindowName, 500);
sprintf_s(
cmdLine,
"%s %s%lX %s%lX",
tmpBuf,
"select=",
(int)hwnd_frame,
"confirm=",
(int)hwnd_frame
* (int)hwnd_frame
* (int)hwnd_frame
* (int)hwnd_frame
* (int)hwnd_frame
* (int)hwnd_frame
* (int)hwnd_frame);
if (static_cast<int>(WinExec(cmdLine, 5u)) < 32)
{
auto caption = pinball::get_rc_string(170, 0);
auto text = pinball::get_rc_string(171, 0);
MessageBoxA(hwnd_frame, text, caption, 0x2010u);
}
memory::free(tmpBuf);
}
break;
}
case Menu1_1Player:
case Menu1_2Players:
case Menu1_3Players:
case Menu1_4Players:
options::toggle(wParam);
new_game();
break;
case Menu1_Help_Topics:
if (!single_step)
pause();
help_introduction(hinst, hWnd);
break;
case 106: // End game button?
pb::end_game();
break;
case Menu1_Full_Screen:
case Menu1_Sounds:
case Menu1_Music:
if (!single_step)
pause();
options::toggle(wParam);
break;
case Menu1_Player_Controls:
case 204: // Second controls button?
if (!single_step)
pause();
options::keyboard();
break;
case Menu1_Exit:
PostMessageA(hWnd, WM_QUIT, 0, 0);
break;
case Menu1_New_Game:
new_game();
break;
case Menu1_About_Pinball:
if (!single_step)
pause();
a_dialog(hinst, hWnd);
break;
case Menu1_High_Scores:
if (!single_step)
pause();
pb::high_scores();
break;
case 1: // Unknown button
midi::restart_midi_seq(lParam);
break;
default:
break;
}
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_LBUTTONDOWN:
if (pb::game_mode)
{
if (pb::cheat_mode)
{
mouse_down = 1;
mouse_hsave = SetCursor(nullptr);
auto mouseXY = fullscrn::convert_mouse_pos(lParam);
last_mouse_x = mouseXY & 0xffFFu;
last_mouse_y = mouseXY >> 16;
SetCapture(hWnd);
}
return DefWindowProcA(hWnd, Msg, wParam, lParam);
}
break;
case WM_LBUTTONUP:
if (mouse_down)
{
mouse_down = 0;
SetCursor(mouse_hsave);
ReleaseCapture();
}
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
if (pb::game_mode)
return DefWindowProcA(hWnd, Msg, wParam, lParam);
break;
case WM_POWERBROADCAST:
if (wParam == 4 && options::Options.FullScreen)
{
options::Options.FullScreen = 0;
options::menu_check(Menu1_Full_Screen, 0);
fullscrn::set_screen_mode(options::Options.FullScreen);
}
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_PALETTECHANGED:
InvalidateRect(hWnd, nullptr, 0);
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_POINTERDEVICEINRANGE | LB_ADDSTRING:
if (wParam == 1)
midi::restart_midi_seq(lParam);
return DefWindowProcA(hWnd, Msg, wParam, lParam);
default:
return DefWindowProcA(hWnd, Msg, wParam, lParam);
}
pb::mode_countdown(-1);