这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 86 additions & 2 deletions SpaceCadetPinball/Sound.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "options.h"
#include "pch.h"
#include "Sound.h"

Expand Down Expand Up @@ -41,7 +42,7 @@ void Sound::Close()
Mix_Quit();
}

void Sound::PlaySound(Mix_Chunk* wavePtr, int time)
void Sound::PlaySound(Mix_Chunk* wavePtr, int time, TPinballComponent *soundSource, const char* info)
{
if (wavePtr && enabled_flag)
{
Expand All @@ -52,8 +53,91 @@ void Sound::PlaySound(Mix_Chunk* wavePtr, int time)
}

auto channel = Mix_PlayChannel(-1, wavePtr, 0);
if (channel != -1)
if (channel != -1) {
TimeStamps[channel] = time;
if (options::Options.SoundStereo) {
/* Think 3D sound positioning, where:
* - x goes from 0 to 1, left to right on the screen,
* - y goes from 0 to 1, top to bottom on the screen,
* - z goes from 0 to infinity, from table-level to the sky.
*
* We position the listener at the bottom center of the table,
* at 0.5 height, so roughly a table half-length. Coords of
* the listener are thus {0.5, 1.0, 0.5}.
*
* We use basic trigonometry to calculate the angle and distance
* from a sound source to the listener.
*
* Mix_SetPosition expects an angle in (Sint16)degrees, where
* 0 degrees is in front, 90 degrees is to the right, and so on.
* Mix_SetPosition expects a (Uint8)distance from 0 (near) to 255 (far).
*/

/* Get the sound source position. */
vector2 coordinates;
/* Some sounds are unpositioned; for that case the caller sends
* a NULL pointer as a soundSource; in those cases we position
* the sound at the center top of the table.
*/
if (!soundSource) {
coordinates.X = 0.5f;
coordinates.Y = 0.0f;
}
else {
coordinates = soundSource->get_coordinates();
};

/* Player position. */
auto pX = 0.5f;
auto pY = 1.0f;
auto pZ = 0.5f;

/* Calculate lengths of three sides of a triangle.
* ptos (Player-to-sound): distance from listener to the sound source,
* ptom (player-to-middle): distance from listener to the sound source
* when the latter is repositioned to the
* X center,
* stom (sound-to-middle): distance from ptos to ptom.
*/
auto ptos = sqrt(((coordinates.X - pX) * (coordinates.X - pX)) + ((coordinates.Y - pY) * (coordinates.Y - pY)) + (pZ * pZ));
auto ptom = sqrt(((coordinates.Y - pY) * (coordinates.Y - pY)) + (pZ * pZ));
auto stom = fabs(coordinates.X - 0.5);

/* Calculate the angle using the law of cosines and acos().
* That will return an angle in radians, e.g. in the [0,PI] range;
* we remap to [0,180], and cast to an integer.
*/
Sint16 angle = (Sint16)(acos(((stom * stom) - (ptos * ptos) - (ptom * ptom)) / (-2.0f * ptos * ptom)) * 180.0f / IM_PI);

/* Because we are using distances to calculate the angle,
* we now have no clue if the sound is to the right or the
* left. If the sound is to the right, the current value
* is good, but to the left, we need substract it from 360.
*/
if (coordinates.X < 0.5) {
angle = (360 - angle);
}

/* Distance from listener to the ball (ptos) is roughly
* in the [0.5,1.55] range; remap to 50-155 by multiplying
* by 100 and cast to an integer. */
Uint8 distance = (Uint8)(100.0f * ptos);
Mix_SetPosition(channel, angle, distance);

/* Output position of each sound emitted so we can verify
* the sanity of the implementation.
*/
/*
printf("X: %3.3f Y: %3.3f Angle: %3d Distance: %3d, Object: %s\n",
coordinates.X,
coordinates.Y,
angle,
distance,
info
);
*/
}
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion SpaceCadetPinball/Sound.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#include "TPinballComponent.h"


class Sound
Expand All @@ -9,7 +10,7 @@ class Sound
static void Activate();
static void Deactivate();
static void Close();
static void PlaySound(Mix_Chunk* wavePtr, int time);
static void PlaySound(Mix_Chunk* wavePtr, int time, TPinballComponent *soundSource, const char* info);
static Mix_Chunk* LoadWaveFile(const std::string& lpName);
static void FreeSound(Mix_Chunk* wave);
static void SetChannels(int channels);
Expand Down
9 changes: 9 additions & 0 deletions SpaceCadetPinball/TBall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,12 @@ void TBall::throw_ball(TBall* ball, vector3* direction, float angleMult, float s
rnd = RandFloat();
ball->Speed = (1.0f - (rnd + rnd)) * (speedMult1 * speedMult2) + speedMult1;
}

vector2 TBall::get_coordinates()
{
vector2 coordinates;
vector2i pos2D = proj::xform_to_2d(Position);
coordinates.X = (float)pos2D.X / PinballTable->Width;
coordinates.Y = (float)pos2D.Y / PinballTable->Height;
return coordinates;
}
1 change: 1 addition & 0 deletions SpaceCadetPinball/TBall.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public :
void not_again(TEdgeSegment* edge);
bool already_hit(TEdgeSegment* edge);
int Message(int code, float value) override;
vector2 get_coordinates();

static void throw_ball(TBall* ball, vector3* direction, float angleMult, float speedMult1,
float speedMult2);
Expand Down
4 changes: 2 additions & 2 deletions SpaceCadetPinball/TBlocker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ int TBlocker::Message(int code, float value)
ActiveFlag = 0;
render::sprite_set_bitmap(RenderSprite, nullptr);
if (code == 51)
loader::play_sound(SoundIndex3);
loader::play_sound(SoundIndex3, this, "TBlocker1");
return 0;
case 52:
ActiveFlag = 1;
loader::play_sound(SoundIndex4);
loader::play_sound(SoundIndex4, this, "TBlocker2");
render::sprite_set_bitmap(RenderSprite, ListBitmap->at(0));
break;
case 59:
Expand Down
4 changes: 2 additions & 2 deletions SpaceCadetPinball/TBumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ int TBumper::Message(int code, float value)
if (nextBmp != BmpIndex)
{
if (nextBmp >= BmpIndex)
loader::play_sound(SoundIndex4);
loader::play_sound(SoundIndex4, this, "TBumper1");
if (nextBmp < BmpIndex)
loader::play_sound(SoundIndex3);
loader::play_sound(SoundIndex3, this, "TBumper2");
BmpIndex = nextBmp;
Fire();
control::handler(11, this);
Expand Down
8 changes: 4 additions & 4 deletions SpaceCadetPinball/TCollisionComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ bool TCollisionComponent::DefaultCollision(TBall* ball, vector2* nextPosition, v

auto projSpeed = maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, Threshold, Boost);
if (projSpeed > Threshold)
loader::play_sound(HardHitSoundId);
loader::play_sound(HardHitSoundId, ball, "TCollisionComponent1");
else if (projSpeed > 0.2f)
loader::play_sound(SoftHitSoundId);
loader::play_sound(SoftHitSoundId, ball, "TCollisionComponent2");
else
return false;
return true;
Expand All @@ -87,9 +87,9 @@ void TCollisionComponent::Collision(TBall* ball, vector2* nextPosition, vector2*
Threshold,
Boost);
if (projSpeed > Threshold)
loader::play_sound(HardHitSoundId);
loader::play_sound(HardHitSoundId, ball, "TCollisionComponent3");
else if (projSpeed > 0.2f)
loader::play_sound(SoftHitSoundId);
loader::play_sound(SoftHitSoundId, ball, "TCollisionComponent4");
}

int TCollisionComponent::FieldEffect(TBall* ball, vector2* vecDst)
Expand Down
2 changes: 1 addition & 1 deletion SpaceCadetPinball/TCollisionComponent.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#pragma once
#include "TPinballComponent.h"
#include "TBall.h"

struct vector2;
class TEdgeSegment;
class TBall;

class TCollisionComponent : public TPinballComponent
{
Expand Down
2 changes: 1 addition & 1 deletion SpaceCadetPinball/TFlagSpinner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ void TFlagSpinner::NextFrame()
{
control::handler(63, this);
if (SoftHitSoundId)
loader::play_sound(SoftHitSoundId);
loader::play_sound(SoftHitSoundId, this, "TFlagSpinner");
if (!BmpIndex)
control::handler(62, this);
}
Expand Down
4 changes: 2 additions & 2 deletions SpaceCadetPinball/TFlipper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,12 @@ int TFlipper::Message(int code, float value)
{
control::handler(1, this);
TimerTime = ExtendAnimationFrameTime;
loader::play_sound(HardHitSoundId);
loader::play_sound(HardHitSoundId, this, "TFlipper1");
}
else if (code == 2)
{
TimerTime = RetractAnimationFrameTime;
loader::play_sound(SoftHitSoundId);
loader::play_sound(SoftHitSoundId, this, "TFlipper2");
}
else
{
Expand Down
4 changes: 2 additions & 2 deletions SpaceCadetPinball/TGate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ int TGate::Message(int code, float value)
{
ActiveFlag = 0;
render::sprite_set_bitmap(RenderSprite, nullptr);
loader::play_sound(SoundIndex3);
loader::play_sound(SoundIndex3, this, "TGate1");
}
else if (code == 54 || code == 1024)
{
ActiveFlag = 1;
render::sprite_set_bitmap(RenderSprite, ListBitmap->at(0));
if (code == 54)
loader::play_sound(SoundIndex4);
loader::play_sound(SoundIndex4, this, "TGate2");
}
control::handler(code, this);
}
Expand Down
4 changes: 2 additions & 2 deletions SpaceCadetPinball/THole.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ void THole::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl

if (!PinballTable->TiltLockFlag)
{
loader::play_sound(HardHitSoundId);
loader::play_sound(HardHitSoundId, ball, "THole1");
control::handler(57, this);
}
}
Expand Down Expand Up @@ -115,7 +115,7 @@ int THole::FieldEffect(TBall* ball, vector2* vecDst)
ball->CollisionComp = nullptr;
ball->Direction.X = 0.0;
ball->Speed = 0.0;
loader::play_sound(SoftHitSoundId);
loader::play_sound(SoftHitSoundId, ball, "THole2");
control::handler(58, this);
}
}
Expand Down
2 changes: 1 addition & 1 deletion SpaceCadetPinball/TKickback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void TKickback::TimerExpired(int timerId, void* caller)
{
kick->Threshold = 0.0;
kick->Timer = timer::set(kick->TimerTime2, kick, TimerExpired);
loader::play_sound(kick->HardHitSoundId);
loader::play_sound(kick->HardHitSoundId, kick, "TKickback");
if (kick->ListBitmap)
{
auto bmp = kick->ListBitmap->at(1);
Expand Down
4 changes: 2 additions & 2 deletions SpaceCadetPinball/TKickout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ void TKickout::Collision(TBall* ball, vector2* nextPosition, vector2* direction,
}
else
{
loader::play_sound(SoftHitSoundId);
loader::play_sound(SoftHitSoundId, ball, "TKickout1");
control::handler(63, this);
}
}
Expand Down Expand Up @@ -153,12 +153,12 @@ void TKickout::TimerExpired(int timerId, void* caller)
kick->Timer = timer::set(kick->TimerTime2, kick, ResetTimerExpired);
if (kick->Ball)
{
loader::play_sound(kick->HardHitSoundId, kick->Ball, "TKickout2");
kick->Ball->Position.Z = kick->OriginalBallZ;
TBall::throw_ball(kick->Ball, &kick->BallThrowDirection, kick->ThrowAngleMult, kick->ThrowSpeedMult1,
kick->ThrowSpeedMult2);
kick->ActiveFlag = 0;
kick->Ball = nullptr;
loader::play_sound(kick->HardHitSoundId);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion SpaceCadetPinball/TLightRollover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ void TLightRollover::Collision(TBall* ball, vector2* nextPosition, vector2* dire
}
else
{
loader::play_sound(SoftHitSoundId);
loader::play_sound(SoftHitSoundId, this, "TLightRollover");
control::handler(63, this);
RolloverFlag = RolloverFlag == 0;
if (ListBitmap)
Expand Down
4 changes: 2 additions & 2 deletions SpaceCadetPinball/TOneway.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void TOneway::Collision(TBall* ball, vector2* nextPosition, vector2* direction,
if (!PinballTable->TiltLockFlag)
{
if (HardHitSoundId)
loader::play_sound(HardHitSoundId);
loader::play_sound(HardHitSoundId, ball, "TOneway1");
control::handler(63, this);
}
}
Expand All @@ -69,7 +69,7 @@ void TOneway::Collision(TBall* ball, vector2* nextPosition, vector2* direction,
Boost) > 0.2f)
{
if (SoftHitSoundId)
loader::play_sound(SoftHitSoundId);
loader::play_sound(SoftHitSoundId, ball, "TOneway2");
}
}

Expand Down
9 changes: 9 additions & 0 deletions SpaceCadetPinball/TPinballComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool
ListZMap = nullptr;
GroupName = nullptr;
Control = nullptr;
Coordinates.X = -1.0f;
Coordinates.Y = -1.0f;
if (table)
table->ComponentList.push_back(this);
if (groupIndex >= 0)
Expand Down Expand Up @@ -69,6 +71,8 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool
rootBmp->XPosition - table->XOffset,
rootBmp->YPosition - table->YOffset,
&bmp1Rect);
Coordinates.X = (bmp1Rect.XPosition + (bmp1Rect.Width / 2.0f)) / PinballTable->Width;
Coordinates.Y = (bmp1Rect.YPosition + (bmp1Rect.Height / 2.0f)) / PinballTable->Height;
}
}
GroupIndex = groupIndex;
Expand Down Expand Up @@ -111,3 +115,8 @@ int TPinballComponent::get_scoring(int index)
{
return 0;
}

vector2 TPinballComponent::get_coordinates()
{
return this->Coordinates;
}
3 changes: 3 additions & 0 deletions SpaceCadetPinball/TPinballComponent.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#include "maths.h"

struct zmap_header_type;
struct gdrv_bitmap8;
Expand All @@ -23,6 +24,7 @@ class TPinballComponent
virtual void port_draw();
virtual void put_scoring(int index, int score);
virtual int get_scoring(int index);
virtual vector2 get_coordinates();

char UnusedBaseFlag;
char ActiveFlag;
Expand All @@ -34,4 +36,5 @@ class TPinballComponent
TPinballTable* PinballTable;
std::vector<gdrv_bitmap8*>* ListBitmap;
std::vector<zmap_header_type*>* ListZMap;
vector2 Coordinates;
};
6 changes: 3 additions & 3 deletions SpaceCadetPinball/TPinballTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ void TPinballTable::tilt(float time)
pinball::InfoTextBox->Clear();
pinball::MissTextBox->Clear();
pinball::InfoTextBox->Display(pinball::get_rc_string(35, 0), -1.0);
loader::play_sound(SoundIndex3);
loader::play_sound(SoundIndex3, nullptr, "TPinballTable1");
TiltTimeoutTimer = timer::set(30.0, this, tilt_timeout);

for (auto component : ComponentList)
Expand Down Expand Up @@ -446,7 +446,7 @@ int TPinballTable::Message(int code, float value)
pinball::InfoTextBox->Clear();
pinball::MissTextBox->Clear();
LightGroup->Message(28, 0.2f);
auto time = loader::play_sound(SoundIndex1);
auto time = loader::play_sound(SoundIndex1, nullptr, "TPinballTable2");
LightShowTimer = timer::set(time, this, LightShow_timeout);
}

Expand Down Expand Up @@ -543,7 +543,7 @@ int TPinballTable::Message(int code, float value)
}
break;
case 1022:
loader::play_sound(SoundIndex2);
loader::play_sound(SoundIndex2, nullptr, "TPinballTable3");
pinball::MissTextBox->Clear();
pinball::InfoTextBox->Display(pinball::get_rc_string(34, 0), -1.0);
EndGameTimeoutTimer = timer::set(3.0, this, EndGame_timeout);
Expand Down
Loading