WaveMix ready. Fixed ball Z reset in TKickout.

This commit is contained in:
oz 2021-01-28 12:46:48 +03:00
parent 77f3f52e0d
commit 74306179a7
7 changed files with 300 additions and 47 deletions

Binary file not shown.

View File

@ -241,7 +241,7 @@ void Sound::NullCallback(int a1, MIXWAVE* a2, int a3)
LRESULT Sound::SoundCallBackWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (Msg != 957)
if (Msg != MM_WOM_DONE)
return DefWindowProcA(hWnd, Msg, wParam, lParam);
auto wavePtr = reinterpret_cast<MIXWAVE*>(lParam);

View File

@ -114,8 +114,8 @@ void TKickout::Collision(TBall* ball, vector_type* nextPosition, vector_type* di
ball->CollisionComp = this;
ball->Position.X = Circle.Center.X;
ball->Position.Y = Circle.Center.Y;
OriginalBallZ = ball->Position.Z;
ball->Position.Z = CollisionBallSetZ;
FieldBallZSet = ball->Position.Z;
if (PinballTable->TiltLockFlag)
{
Message(55, 0.1f);
@ -153,7 +153,7 @@ void TKickout::TimerExpired(int timerId, void* caller)
kick->Timer = timer::set(kick->TimerTime2, kick, ResetTimerExpired);
if (kick->Ball)
{
kick->Ball->Position.Z = kick->FieldBallZSet;
kick->Ball->Position.Z = kick->OriginalBallZ;
TBall::throw_ball(kick->Ball, &kick->BallAcceleration, kick->ThrowAngleMult, kick->ThrowSpeedMult1,
kick->ThrowSpeedMult2);
kick->UnknownBaseFlag2 = 0;

View File

@ -27,7 +27,7 @@ public:
TBall* Ball;
float FieldMult;
circle_type Circle;
float FieldBallZSet;
float OriginalBallZ;
vector_type BallAcceleration;
float ThrowAngleMult;
float ThrowSpeedMult1;

View File

@ -22,6 +22,7 @@ XWAVEHDR* WaveMix::block_array1[10];
XWAVEHDR* WaveMix::block_array2[10];
unsigned char* WaveMix::play_data[MAXCHANNELS];
volume_struct WaveMix::play_volume[MAXCHANNELS];
int WaveMix::play_counter = 0;
HANDLE WaveMix::Init()
{
@ -573,7 +574,253 @@ void WaveMix::Pump()
int WaveMix::Play(MIXPLAYPARAMS* lpMixPlayParams)
{
return 0;
++play_counter;
auto result = 12;
auto remixFlag = 0;
do
{
if (play_counter > 1)
break;
if (!lpMixPlayParams)
{
if (ShowDebugDialogs)
MessageBoxA(nullptr, "NULL parameters pointer passed to WaveMixPlay!", "WavMix32", 0x30u);
result = 5;
break;
}
auto globals = SessionToGlobalDataPtr(lpMixPlayParams->hMixSession);
Globals = globals;
if (!globals)
{
if (ShowDebugDialogs)
MessageBoxA(nullptr, "Invalid session handle passed to WaveMixPlay", "WavMix32", 0x30u);
result = 5;
break;
}
if (!IsValidLPMIXWAVE(lpMixPlayParams->lpMixWave))
{
if (ShowDebugDialogs)
MessageBoxA(nullptr, "Invalid or NULL wave pointer passed to WaveMixPlay!", "WavMix32", 0x30u);
break;
}
if (!HasCurrentOutputFormat(lpMixPlayParams->lpMixWave))
{
wsprintfA(
string_buffer,
"The LPMIXWAVE 0x%lx is not in the current output format, close the wave and reopen it.",
lpMixPlayParams->lpMixWave);
if (ShowDebugDialogs)
MessageBoxA(nullptr, string_buffer, "WavMix32", 0x30u);
result = 8;
break;
}
if (!globals->fActive)
{
if (ShowDebugDialogs)
MessageBoxA(nullptr, "Wave device not allocated, call WaveMixActivate(hMixSession,TRUE)", "WavMix32",
0x30u);
result = 4;
break;
}
if (!globals->iChannels)
{
if (ShowDebugDialogs)
MessageBoxA(nullptr, "You must open a channel before you can play a wave!", "WavMix32", 0x30u);
result = 5;
break;
}
int iChannel;
if ((lpMixPlayParams->dwFlags & WMIX_USELRUCHANNEL) != 0)
{
iChannel = 0;
for (auto channelIndex = 0; channelIndex < 16; ++channelIndex)
{
if (globals->aChannel[channelIndex] != reinterpret_cast<CHANNELNODE*>(-1))
{
if (!globals->aChannel[iChannel])
break;
if (channelIndex != iChannel && globals->MRUChannel[channelIndex] < globals->MRUChannel[iChannel])
iChannel = channelIndex;
}
}
lpMixPlayParams->iChannel = iChannel;
}
else
{
iChannel = lpMixPlayParams->iChannel;
}
++globals->dwMRU;
globals->MRUChannel[iChannel] = globals->dwMRU;
if (globals->aChannel[iChannel] == reinterpret_cast<CHANNELNODE*>(-1))
{
result = 5;
break;
}
auto channel = GetChannelNode();
if (!channel)
break;
memcpy(&channel->PlayParams, lpMixPlayParams, sizeof(channel->PlayParams));
channel->lpMixWave = channel->PlayParams.lpMixWave;
channel->dwNumSamples = channel->PlayParams.lpMixWave->wh.dwBufferLength;
auto lpData = (unsigned __int8*)channel->PlayParams.lpMixWave->wh.lpData;
channel->lpPos = lpData;
channel->lpEnd = &lpData[channel->dwNumSamples - globals->PCM.wf.nBlockAlign];
channel->PlayParams.iChannel = iChannel;
if (globals->pWaitList)
{
channel->next = globals->pWaitList->next;
globals->pWaitList->next = channel;
globals->pWaitList = channel;
}
else
{
globals->pWaitList = channel;
channel->next = channel;
}
if ((channel->PlayParams.dwFlags & WMIX_WAIT) != 0)
{
result = 0;
break;
}
ResetWavePosIfNoChannelData();
auto globals2 = Globals;
unsigned wavePosition;
if (Globals->pfnRemix == ResetRemix)
{
wavePosition = MyWaveOutGetPosition(Globals->hWaveOut, Globals->fGoodGetPos);
globals2 = Globals;
}
else
{
wavePosition = Globals->dwCurrentSample;
}
while (globals2->pWaitList)
{
auto curChannel = globals2->pWaitList->next;
if (globals2->pWaitList->next == globals2->pWaitList)
globals2->pWaitList = nullptr;
else
globals2->pWaitList->next = curChannel->next;
iChannel = curChannel->PlayParams.iChannel;
curChannel->next = nullptr;
if ((curChannel->PlayParams.dwFlags & WMIX_CustomVolume) != 0)
{
curChannel->Volume.L = curChannel->PlayParams.Volume.L;
curChannel->Volume.R = curChannel->PlayParams.Volume.R;
}
else
{
curChannel->Volume.L = globals2->ChannelVolume[iChannel].L;
curChannel->Volume.R = globals2->ChannelVolume[iChannel].R;
}
if (curChannel->Volume.L > 10u)
curChannel->Volume.L = 10;
if (curChannel->Volume.R > 10u)
curChannel->Volume.R = 10;
if ((curChannel->PlayParams.dwFlags & WMIX_CLEARQUEUE) != 0)
{
for (auto tmpCh = globals2->aChannel[iChannel]; tmpCh;)
{
auto nextChannel = tmpCh->next;
FreeChannelNode(tmpCh);
tmpCh = nextChannel;
}
globals2->aChannel[iChannel] = curChannel;
if (play_queue.first != nullptr)
remixFlag = 1;
if ((curChannel->PlayParams.dwFlags & WMIX_HIPRIORITY) != 0)
curChannel->dwStartPos = wavePosition;
else
curChannel->dwStartPos = globals2->dwCurrentSample;
}
else
{
DWORD dwStartPos;
if (globals2->aChannel[iChannel])
{
auto tmpCh = globals2->aChannel[iChannel];
while (tmpCh->next)
tmpCh = tmpCh->next;
tmpCh->next = curChannel;
dwStartPos = tmpCh->dwEndPos;
if ((curChannel->PlayParams.dwFlags & WMIX_HIPRIORITY) != 0)
{
if (dwStartPos <= wavePosition)
dwStartPos = wavePosition;
}
else if (globals2->dwCurrentSample > dwStartPos)
{
dwStartPos = globals2->dwCurrentSample;
}
}
else
{
dwStartPos = wavePosition;
globals2->aChannel[iChannel] = curChannel;
if ((curChannel->PlayParams.dwFlags & WMIX_HIPRIORITY) == 0)
dwStartPos = globals2->dwCurrentSample;
}
curChannel->dwStartPos = dwStartPos;
if (globals2->dwCurrentSample > curChannel->dwStartPos)
remixFlag = 1;
}
if (curChannel->PlayParams.wLoops == 0xFFFF)
curChannel->dwEndPos = -1;
else
curChannel->dwEndPos = curChannel->dwStartPos + curChannel->dwNumSamples * (curChannel
->PlayParams.wLoops + 1) -
globals2->PCM.wf.nBlockAlign;
}
if (!remixFlag || !globals2->pfnRemix(wavePosition, nullptr))
{
int pauseFlag;
if (play_queue.first || globals2->PauseBlocks <= 0)
{
pauseFlag = 0;
}
else
{
waveOutPause(globals2->hWaveOut);
pauseFlag = 1;
}
auto pauseCounter = 0;
while (MixerPlay(GetWaveBlock(), 1))
{
if (pauseFlag)
{
if (++pauseCounter >= Globals->PauseBlocks)
{
waveOutRestart(Globals->hWaveOut);
pauseFlag = 0;
}
}
}
if (pauseFlag)
waveOutRestart(Globals->hWaveOut);
}
result = 0;
}
while (false);
--play_counter;
return result;
}
GLOBALS* WaveMix::SessionToGlobalDataPtr(HANDLE hMixSession)
@ -2255,6 +2502,38 @@ void WaveMix::FreePlayedBlocks()
}
}
int WaveMix::HasCurrentOutputFormat(MIXWAVE* lpMixWave)
{
return memcmp(lpMixWave, &Globals->PCM, 0x10u) == 0;
}
CHANNELNODE* WaveMix::GetChannelNode()
{
CHANNELNODE* result = free_channel_nodes;
if (result)
{
free_channel_nodes = free_channel_nodes->next;
result->next = nullptr;
}
return result;
}
void WaveMix::ResetWavePosIfNoChannelData()
{
if (!play_queue.first)
{
int channelIndex = 0;
for (CHANNELNODE** i = Globals->aChannel; !*i || *i == reinterpret_cast<CHANNELNODE*>(-1); ++i)
{
if (++channelIndex >= 16)
{
SetWaveOutPosition(0);
return;
}
}
}
}
void WaveMix::cmixit(unsigned __int8* lpDest, unsigned __int8** rgWaveSrc, volume_struct* volumeArr, int iNumWaves,
unsigned __int16 length)
{
@ -2326,7 +2605,7 @@ void WaveMix::cmixit(unsigned __int8* lpDest, unsigned __int8** rgWaveSrc, volum
LRESULT WaveMix::WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (Msg != 957 && Msg != 1024)
if (Msg != MM_WOM_DONE && Msg != WM_USER)
return DefWindowProcA(hWnd, Msg, wParam, lParam);
Pump();
return 0;
@ -2334,9 +2613,9 @@ LRESULT WaveMix::WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
INT_PTR WaveMix::SettingsDlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (Msg == 272)
if (Msg == WM_INITDIALOG)
return Settings_OnInitDialog(hWnd, wParam, (MIXCONFIG*)lParam);
if (Msg != 273)
if (Msg != WM_COMMAND)
return 0;
Settings_OnCommand(hWnd, static_cast<unsigned __int16>(wParam), lParam, HIWORD(wParam));
return 1;

View File

@ -6,6 +6,7 @@
#define WMIX_USELRUCHANNEL 0x02
#define WMIX_HIPRIORITY 0x04
#define WMIX_WAIT 0x08
#define WMIX_CustomVolume 0x10
#define MAXCHANNELS 16
#define MAXQUEUEDWAVES 100
@ -36,7 +37,7 @@ struct MIXPLAYPARAMS
HWND hWndNotify;
DWORD dwFlags;
WORD wLoops;
int Unknown0;
volume_struct Volume;
};
struct CHANNELNODE
@ -94,45 +95,14 @@ struct GLOBALS
int fActive;
int SettingsDialogActiveFlag;
unsigned int wDeviceID;
char szDevicePName[32];
int unknown15;
int unknown16;
int unknown17;
int unknown18;
int unknown19;
int unknown20;
int unknown21;
int unknown22;
int unknown23;
int unknown24;
int unknown25;
int unknown26;
int unknown27;
int unknown28;
int unknown29;
int unknown30;
char szDevicePName[96];
WAVEOUTCAPSA WaveoutCaps;
volume_struct DefaultVolume;
volume_struct ChannelVolume[MAXCHANNELS];
CHANNELNODE* aChannel[MAXCHANNELS];
int iChannels;
int unknown78;
int unknown79;
int unknown80;
int unknown81;
int unknown82;
int unknown83;
int unknown84;
int unknown85;
int unknown86;
int unknown87;
int unknown88;
int unknown89;
int unknown90;
int unknown91;
int unknown92;
int unknown93;
int unknown94;
DWORD MRUChannel[MAXCHANNELS];
DWORD dwMRU;
PCMWAVEFORMAT PCM;
DWORD dwWaveBlockLen;
int WaveBlockCount;
@ -146,7 +116,7 @@ struct GLOBALS
unsigned __int16 length);
int (* pfnRemix)(DWORD, CHANNELNODE*);
DWORD (* pfnSampleAdjust)(DWORD, DWORD);
int unknown110;
CHANNELNODE* pWaitList;
__int16 wMagic2;
__int16 unknown112;
};
@ -242,6 +212,9 @@ private:
static void RepSample(HPSTR lpOutData, HPSTR lpInData, unsigned nRep, int nBytesPerSample, int nChannels);
static bool IsValidLPMIXWAVE(MIXWAVE* lpMixWave);
static void FreePlayedBlocks();
static int HasCurrentOutputFormat(MIXWAVE* lpMixWave);
static CHANNELNODE* GetChannelNode();
static void ResetWavePosIfNoChannelData();
static void cmixit(unsigned __int8* lpDest, unsigned __int8** rgWaveSrc, volume_struct* volumeArr, int iNumWaves,
unsigned __int16 length);
static LRESULT __stdcall WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
@ -266,4 +239,5 @@ private:
static XWAVEHDR* block_array2[10];
static unsigned char* play_data[MAXCHANNELS];
static volume_struct play_volume[MAXCHANNELS];
static int play_counter;
};

View File

@ -187,7 +187,7 @@ void high_score::show_and_set_high_score_dialog(high_score_struct* table, int sc
}
}
INT_PTR __stdcall high_score::HighScore(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
INT_PTR high_score::HighScore(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HWND parent;
int nIDDlgItem;