mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-12-22 11:56:24 +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{};
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
scoreStruct* CurScoreStruct;
|
||||
scoreStruct* ScoreBallcount;
|
||||
scoreStruct* ScorePlayerNumber1;
|
||||
int UnknownP6;
|
||||
int CheatsUsed;
|
||||
int SoundIndex1;
|
||||
int SoundIndex2;
|
||||
int SoundIndex3;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -37,9 +37,9 @@ winhelp_entry options::keymap_help[18]
|
|||
|
||||
short options::vk_list[28]
|
||||
{
|
||||
0x8041,
|
||||
-32703,
|
||||
0x5A,
|
||||
0x8030,
|
||||
-32720,
|
||||
0x39,
|
||||
0x402E,
|
||||
0x402F,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue