mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-11-22 17:00:18 +01:00
pb, cheats ready.
Collison v1, mouse fixed.
This commit is contained in:
parent
d267fd5c98
commit
1ea247e185
20 changed files with 773 additions and 284 deletions
Binary file not shown.
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -410,250 +410,247 @@ 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:
|
||||||
|
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:
|
options::Options.FullScreen = 0;
|
||||||
if (lParam)
|
options::menu_check(Menu1_Full_Screen, 0);
|
||||||
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
}
|
||||||
if (fullscrn::screen_mode)
|
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
||||||
fullscrn::set_menu_mode(0);
|
case WM_KEYUP:
|
||||||
return 0;
|
pb::keyup(wParam);
|
||||||
case WM_SYSKEYDOWN:
|
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
||||||
no_time_loss = 1;
|
case WM_KEYDOWN:
|
||||||
if (fullscrn::screen_mode)
|
if (!(lParam & 0x40000000))
|
||||||
fullscrn::set_menu_mode(1);
|
pb::keydown(wParam);
|
||||||
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
switch (wParam)
|
||||||
case WM_GETMINMAXINFO:
|
{
|
||||||
fullscrn::getminmaxinfo((MINMAXINFO*)lParam);
|
case VK_ESCAPE:
|
||||||
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
if (options::Options.FullScreen)
|
||||||
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::toggle(0x193u);
|
options::toggle(0x193u);
|
||||||
break;
|
SendMessageA(hwnd_frame, 0x112u, 0xF020u, 0);
|
||||||
case VK_F8:
|
break;
|
||||||
if (!single_step)
|
case VK_F1:
|
||||||
pause();
|
help_introduction(hinst, hWnd);
|
||||||
options::keyboard();
|
break;
|
||||||
break;
|
case VK_F2:
|
||||||
}
|
new_game();
|
||||||
if (!pb::cheat_mode)
|
break;
|
||||||
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
case VK_F3:
|
||||||
switch (wParam)
|
pause();
|
||||||
{
|
break;
|
||||||
case 'H':
|
case VK_F4:
|
||||||
DispGRhistory = 1;
|
options::toggle(0x193u);
|
||||||
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
break;
|
||||||
case 'Y':
|
case VK_F8:
|
||||||
SetWindowTextA(hWnd, "Pinball");
|
if (!single_step)
|
||||||
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:
|
|
||||||
pause();
|
pause();
|
||||||
break;
|
options::keyboard();
|
||||||
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);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case WM_LBUTTONUP:
|
}
|
||||||
if (mouse_down)
|
if (!pb::cheat_mode)
|
||||||
{
|
|
||||||
mouse_down = 0;
|
|
||||||
SetCursor(mouse_hsave);
|
|
||||||
ReleaseCapture();
|
|
||||||
}
|
|
||||||
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
||||||
case WM_RBUTTONDOWN:
|
switch (wParam)
|
||||||
case WM_MBUTTONDOWN:
|
{
|
||||||
if (pb::game_mode)
|
case 'H':
|
||||||
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
DispGRhistory = 1;
|
||||||
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);
|
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
||||||
case WM_PALETTECHANGED:
|
case 'Y':
|
||||||
InvalidateRect(hWnd, nullptr, 0);
|
SetWindowTextA(hWnd, "Pinball");
|
||||||
|
DispFrameRate = DispFrameRate == 0;
|
||||||
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
||||||
case WM_POINTERDEVICEINRANGE | LB_ADDSTRING:
|
case VK_F1:
|
||||||
if (wParam == 1)
|
pb::frame(10);
|
||||||
midi::restart_midi_seq(lParam);
|
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);
|
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
||||||
default:
|
default:
|
||||||
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
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);
|
pb::mode_countdown(-1);
|
||||||
|
|
Loading…
Reference in a new issue