mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2023-12-30 21:52:56 +00:00
Added FT music loader.
Fixed mouse lock. Some cleanup.
This commit is contained in:
parent
debe52c1e0
commit
5c3e9fea4c
@ -25,7 +25,7 @@ TTextBox::TTextBox(TPinballTable* table, int groupIndex) : TPinballComponent(tab
|
|||||||
if (groupIndex > 0)
|
if (groupIndex > 0)
|
||||||
{
|
{
|
||||||
/*Full tilt: text box dimensions index is offset by resolution*/
|
/*Full tilt: text box dimensions index is offset by resolution*/
|
||||||
int arrLength;
|
int arrLength;
|
||||||
auto dimensions = loader::query_iattribute(groupIndex + fullscrn::GetResolution(), 1500, &arrLength);
|
auto dimensions = loader::query_iattribute(groupIndex + fullscrn::GetResolution(), 1500, &arrLength);
|
||||||
OffsetX = dimensions[0];
|
OffsetX = dimensions[0];
|
||||||
OffsetY = dimensions[1];
|
OffsetY = dimensions[1];
|
||||||
@ -155,8 +155,6 @@ void TTextBox::Display(char* text, float time)
|
|||||||
|
|
||||||
void TTextBox::Draw()
|
void TTextBox::Draw()
|
||||||
{
|
{
|
||||||
TTextBoxMessage* nextMessage = nullptr;
|
|
||||||
|
|
||||||
auto bmp = BgBmp;
|
auto bmp = BgBmp;
|
||||||
if (bmp)
|
if (bmp)
|
||||||
gdrv::copy_bitmap(
|
gdrv::copy_bitmap(
|
||||||
@ -171,119 +169,112 @@ void TTextBox::Draw()
|
|||||||
else
|
else
|
||||||
gdrv::fill_bitmap(&render::vscreen, Width, Height, OffsetX, OffsetY, 0);
|
gdrv::fill_bitmap(&render::vscreen, Width, Height, OffsetX, OffsetY, 0);
|
||||||
|
|
||||||
|
bool display = false;
|
||||||
while (Message1)
|
while (Message1)
|
||||||
{
|
{
|
||||||
auto message = Message1;
|
if (Message1->Time == -1.0)
|
||||||
if (message->Time == -1.0)
|
|
||||||
{
|
{
|
||||||
nextMessage = message->NextMessage;
|
if (!Message1->NextMessage)
|
||||||
if (!message->NextMessage)
|
|
||||||
{
|
{
|
||||||
Timer = -1;
|
Timer = -1;
|
||||||
LABEL_18:
|
display = true;
|
||||||
auto font = Font;
|
|
||||||
if (!font)
|
|
||||||
{
|
|
||||||
gdrv::blit(
|
|
||||||
&render::vscreen,
|
|
||||||
OffsetX,
|
|
||||||
OffsetY,
|
|
||||||
OffsetX + render::vscreen.XPosition,
|
|
||||||
OffsetY + render::vscreen.YPosition,
|
|
||||||
Width,
|
|
||||||
Height);
|
|
||||||
gdrv::grtext_draw_ttext_in_box(
|
|
||||||
Message1->Text,
|
|
||||||
render::vscreen.XPosition + OffsetX,
|
|
||||||
render::vscreen.YPosition + OffsetY,
|
|
||||||
Width,
|
|
||||||
Height,
|
|
||||||
255);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto text = Message1->Text;
|
|
||||||
for (auto y = OffsetY; ; y += font->Height)
|
|
||||||
{
|
|
||||||
auto curChar = *text;
|
|
||||||
if (!curChar || y + font->Height > OffsetY + Height)
|
|
||||||
break;
|
|
||||||
|
|
||||||
auto totalWidth = 0;
|
|
||||||
char* textEndSpace = nullptr;
|
|
||||||
auto textEnd = text;
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
auto maskedChar = curChar & 0x7F;
|
|
||||||
if (!maskedChar || maskedChar == '\n')
|
|
||||||
break;
|
|
||||||
auto charBmp = font->Chars[maskedChar];
|
|
||||||
if (charBmp)
|
|
||||||
{
|
|
||||||
auto width = charBmp->Width + font->GapWidth + totalWidth;
|
|
||||||
if (width > Width)
|
|
||||||
{
|
|
||||||
if (textEndSpace)
|
|
||||||
textEnd = textEndSpace;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (*textEnd == ' ')
|
|
||||||
textEndSpace = textEnd;
|
|
||||||
curChar = *(textEnd + 1);
|
|
||||||
totalWidth = width;
|
|
||||||
++textEnd;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
curChar = *textEnd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto offX = OffsetX;
|
|
||||||
while (text < textEnd)
|
|
||||||
{
|
|
||||||
auto charBmp = font->Chars[*text++ & 0x7F];
|
|
||||||
if (charBmp)
|
|
||||||
{
|
|
||||||
auto height = charBmp->Height;
|
|
||||||
auto width = charBmp->Width;
|
|
||||||
if (render::background_bitmap)
|
|
||||||
gdrv::copy_bitmap_w_transparency(&render::vscreen, width, height, offX, y, charBmp, 0,
|
|
||||||
0);
|
|
||||||
else
|
|
||||||
gdrv::copy_bitmap(&render::vscreen, width, height, offX, y, charBmp, 0, 0);
|
|
||||||
font = Font;
|
|
||||||
offX += charBmp->Width + font->GapWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while ((*text & 0x7F) == ' ')
|
|
||||||
++text;
|
|
||||||
if ((*text & 0x7F) == '\n')
|
|
||||||
++text;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (Message1->TimeLeft() >= -2.0f)
|
||||||
{
|
{
|
||||||
auto timeLeft = Message1->TimeLeft();
|
Timer = timer::set(max(Message1->TimeLeft(), 0.25f), this, TimerExpired);
|
||||||
if (timeLeft >= -2.0f)
|
display = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto tmp = Message1;
|
||||||
|
Message1 = Message1->NextMessage;
|
||||||
|
delete tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (display)
|
||||||
|
{
|
||||||
|
auto font = Font;
|
||||||
|
if (!font)
|
||||||
|
{
|
||||||
|
gdrv::blit(
|
||||||
|
&render::vscreen,
|
||||||
|
OffsetX,
|
||||||
|
OffsetY,
|
||||||
|
OffsetX + render::vscreen.XPosition,
|
||||||
|
OffsetY + render::vscreen.YPosition,
|
||||||
|
Width,
|
||||||
|
Height);
|
||||||
|
gdrv::grtext_draw_ttext_in_box(
|
||||||
|
Message1->Text,
|
||||||
|
render::vscreen.XPosition + OffsetX,
|
||||||
|
render::vscreen.YPosition + OffsetY,
|
||||||
|
Width,
|
||||||
|
Height,
|
||||||
|
255);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto text = Message1->Text;
|
||||||
|
for (auto y = OffsetY; ; y += font->Height)
|
||||||
|
{
|
||||||
|
auto curChar = *text;
|
||||||
|
if (!curChar || y + font->Height > OffsetY + Height)
|
||||||
|
break;
|
||||||
|
|
||||||
|
auto totalWidth = 0;
|
||||||
|
char* textEndSpace = nullptr;
|
||||||
|
auto textEnd = text;
|
||||||
|
while (true)
|
||||||
{
|
{
|
||||||
int timer;
|
auto maskedChar = curChar & 0x7F;
|
||||||
if (timeLeft >= 0.25f)
|
if (!maskedChar || maskedChar == '\n')
|
||||||
|
break;
|
||||||
|
auto charBmp = font->Chars[maskedChar];
|
||||||
|
if (charBmp)
|
||||||
{
|
{
|
||||||
timer = timer::set(timeLeft, this, TimerExpired);
|
auto width = charBmp->Width + font->GapWidth + totalWidth;
|
||||||
|
if (width > Width)
|
||||||
|
{
|
||||||
|
if (textEndSpace)
|
||||||
|
textEnd = textEndSpace;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (*textEnd == ' ')
|
||||||
|
textEndSpace = textEnd;
|
||||||
|
curChar = *(textEnd + 1);
|
||||||
|
totalWidth = width;
|
||||||
|
++textEnd;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
timer = timer::set(0.25, this, TimerExpired);
|
curChar = *textEnd;
|
||||||
}
|
}
|
||||||
Timer = timer;
|
|
||||||
goto LABEL_18;
|
|
||||||
}
|
}
|
||||||
nextMessage = message->NextMessage;
|
|
||||||
|
auto offX = OffsetX;
|
||||||
|
while (text < textEnd)
|
||||||
|
{
|
||||||
|
auto charBmp = font->Chars[*text++ & 0x7F];
|
||||||
|
if (charBmp)
|
||||||
|
{
|
||||||
|
auto height = charBmp->Height;
|
||||||
|
auto width = charBmp->Width;
|
||||||
|
if (render::background_bitmap)
|
||||||
|
gdrv::copy_bitmap_w_transparency(&render::vscreen, width, height, offX, y, charBmp, 0,
|
||||||
|
0);
|
||||||
|
else
|
||||||
|
gdrv::copy_bitmap(&render::vscreen, width, height, offX, y, charBmp, 0, 0);
|
||||||
|
font = Font;
|
||||||
|
offX += charBmp->Width + font->GapWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ((*text & 0x7F) == ' ')
|
||||||
|
++text;
|
||||||
|
if ((*text & 0x7F) == '\n')
|
||||||
|
++text;
|
||||||
}
|
}
|
||||||
delete message;
|
|
||||||
Message1 = nextMessage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gdrv::blit(
|
gdrv::blit(
|
||||||
|
@ -14,7 +14,7 @@ tagRECT fullscrn::WindowRect1, fullscrn::WindowRect2;
|
|||||||
rectangle_type fullscrn::WHRect;
|
rectangle_type fullscrn::WHRect;
|
||||||
int fullscrn::fullscrn_flag1;
|
int fullscrn::fullscrn_flag1;
|
||||||
int fullscrn::display_changed;
|
int fullscrn::display_changed;
|
||||||
int fullscrn::ChangeDisplay, fullscrn::SmthFullScrnFlag2;
|
int fullscrn::ChangeDisplay, fullscrn::ignoreNextDisplayChangeFg;
|
||||||
int fullscrn::trick = 1;
|
int fullscrn::trick = 1;
|
||||||
int fullscrn::MenuEnabled;
|
int fullscrn::MenuEnabled;
|
||||||
HMENU fullscrn::MenuHandle;
|
HMENU fullscrn::MenuHandle;
|
||||||
@ -122,8 +122,8 @@ int fullscrn::enableFullscreen()
|
|||||||
|
|
||||||
if (ChangeDisplay && !display_changed)
|
if (ChangeDisplay && !display_changed)
|
||||||
{
|
{
|
||||||
DevMode.dmSize = 156;
|
DevMode.dmSize = sizeof DevMode;
|
||||||
DevMode.dmFields = 1835008;
|
DevMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
|
||||||
DevMode.dmPelsWidth = resolution_array[resolution].ScreenWidth;
|
DevMode.dmPelsWidth = resolution_array[resolution].ScreenWidth;
|
||||||
DevMode.dmPelsHeight = resolution_array[resolution].ScreenHeight;
|
DevMode.dmPelsHeight = resolution_array[resolution].ScreenHeight;
|
||||||
DevMode.dmBitsPerPel = 32;
|
DevMode.dmBitsPerPel = 32;
|
||||||
@ -131,24 +131,24 @@ int fullscrn::enableFullscreen()
|
|||||||
if (trick)
|
if (trick)
|
||||||
{
|
{
|
||||||
GetWindowRect(GetDesktopWindow(), &Rect);
|
GetWindowRect(GetDesktopWindow(), &Rect);
|
||||||
SetWindowPos(hWnd, (HWND)-1, 0, 0, Rect.right - Rect.left + 1,
|
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, Rect.right - Rect.left + 1,
|
||||||
Rect.bottom - Rect.top + 1, 8u);
|
Rect.bottom - Rect.top + 1, SWP_NOREDRAW);
|
||||||
}
|
}
|
||||||
SmthFullScrnFlag2 = 1;
|
ignoreNextDisplayChangeFg = 1;
|
||||||
LONG changeDispResult = ChangeDisplaySettingsA(&DevMode, 4u);
|
LONG changeDispResult = ChangeDisplaySettingsA(&DevMode, CDS_FULLSCREEN);
|
||||||
if (changeDispResult == 1)
|
if (changeDispResult == DISP_CHANGE_RESTART)
|
||||||
{
|
{
|
||||||
BYTE2(DevMode.dmFields) &= 0xFBu;
|
DevMode.dmFields &= ~DM_BITSPERPEL;
|
||||||
SmthFullScrnFlag2 = 1;
|
ignoreNextDisplayChangeFg = 1;
|
||||||
changeDispResult = ChangeDisplaySettingsA(&DevMode, 4u);
|
changeDispResult = ChangeDisplaySettingsA(&DevMode, CDS_FULLSCREEN);
|
||||||
}
|
}
|
||||||
display_changed = changeDispResult == 0;
|
display_changed = changeDispResult == DISP_CHANGE_SUCCESSFUL;
|
||||||
if (changeDispResult == 0)
|
if (display_changed)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
GetWindowRect(GetDesktopWindow(), &Rect);
|
GetWindowRect(GetDesktopWindow(), &Rect);
|
||||||
disableWindowFlagsDisDlg();
|
disableWindowFlagsDisDlg();
|
||||||
SetWindowPos(hWnd, (HWND)-1, 0, 0, Rect.right - Rect.left + 1, Rect.bottom - Rect.top + 1, 8u);
|
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, Rect.right - Rect.left + 1, Rect.bottom - Rect.top + 1, SWP_NOREDRAW);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,20 +157,20 @@ int fullscrn::disableFullscreen()
|
|||||||
if (display_changed)
|
if (display_changed)
|
||||||
{
|
{
|
||||||
display_changed = 0;
|
display_changed = 0;
|
||||||
SmthFullScrnFlag2 = 1;
|
ignoreNextDisplayChangeFg = 1;
|
||||||
ChangeDisplaySettingsA(nullptr, 4u);
|
ChangeDisplaySettingsA(nullptr, CDS_FULLSCREEN);
|
||||||
if (trick)
|
if (trick)
|
||||||
SetWindowPos(hWnd, (HWND)-1, 0, 0, 0, 0, 0x13u);
|
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
|
||||||
}
|
}
|
||||||
setWindowFlagsDisDlg();
|
setWindowFlagsDisDlg();
|
||||||
SetWindowPos(
|
SetWindowPos(
|
||||||
hWnd,
|
hWnd,
|
||||||
nullptr,
|
HWND_TOP,
|
||||||
WindowRect2.left,
|
WindowRect2.left,
|
||||||
WindowRect2.top,
|
WindowRect2.top,
|
||||||
WindowRect2.right - WindowRect2.left,
|
WindowRect2.right - WindowRect2.left,
|
||||||
WindowRect2.bottom - WindowRect2.top,
|
WindowRect2.bottom - WindowRect2.top,
|
||||||
0x14u);
|
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,9 +264,9 @@ void fullscrn::center_in(HWND parent, HWND child)
|
|||||||
int fullscrn::displaychange()
|
int fullscrn::displaychange()
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
if (SmthFullScrnFlag2)
|
if (ignoreNextDisplayChangeFg)
|
||||||
{
|
{
|
||||||
SmthFullScrnFlag2 = 0;
|
ignoreNextDisplayChangeFg = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -280,24 +280,24 @@ int fullscrn::displaychange()
|
|||||||
set_menu_mode(1);
|
set_menu_mode(1);
|
||||||
SetWindowPos(
|
SetWindowPos(
|
||||||
hWnd,
|
hWnd,
|
||||||
nullptr,
|
HWND_TOP,
|
||||||
WindowRect2.left,
|
WindowRect2.left,
|
||||||
WindowRect2.top,
|
WindowRect2.top,
|
||||||
WindowRect2.right - WindowRect2.left,
|
WindowRect2.right - WindowRect2.left,
|
||||||
WindowRect2.bottom - WindowRect2.top,
|
WindowRect2.bottom - WindowRect2.top,
|
||||||
0x1Cu);
|
SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE);
|
||||||
result = 1;
|
result = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetWindowPos(
|
SetWindowPos(
|
||||||
hWnd,
|
hWnd,
|
||||||
nullptr,
|
HWND_TOP,
|
||||||
WindowRect2.left,
|
WindowRect2.left,
|
||||||
WindowRect2.top,
|
WindowRect2.top,
|
||||||
WindowRect2.right - WindowRect2.left,
|
WindowRect2.right - WindowRect2.left,
|
||||||
WindowRect2.bottom - WindowRect2.top,
|
WindowRect2.bottom - WindowRect2.top,
|
||||||
0x14u);
|
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||||
}
|
}
|
||||||
center_in(GetDesktopWindow(), hWnd);
|
center_in(GetDesktopWindow(), hWnd);
|
||||||
}
|
}
|
||||||
@ -311,7 +311,7 @@ void fullscrn::activate(int flag)
|
|||||||
if (!flag)
|
if (!flag)
|
||||||
{
|
{
|
||||||
set_screen_mode(0);
|
set_screen_mode(0);
|
||||||
SetWindowPos(hWnd, (HWND)1, 0, 0, 0, 0, 0x13u);
|
SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ public:
|
|||||||
static rectangle_type WHRect;
|
static rectangle_type WHRect;
|
||||||
static int fullscrn_flag1;
|
static int fullscrn_flag1;
|
||||||
static int display_changed;
|
static int display_changed;
|
||||||
static int ChangeDisplay, SmthFullScrnFlag2;
|
static int ChangeDisplay, ignoreNextDisplayChangeFg;
|
||||||
static int trick;
|
static int trick;
|
||||||
static const resolution_info resolution_array[3];
|
static const resolution_info resolution_array[3];
|
||||||
static float ScaleX;
|
static float ScaleX;
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "midi.h"
|
#include "midi.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "pb.h"
|
||||||
#include "pinball.h"
|
#include "pinball.h"
|
||||||
|
|
||||||
tagMCI_OPEN_PARMSA midi::mci_open_info;
|
tagMCI_OPEN_PARMSA midi::mci_open_info;
|
||||||
@ -10,6 +12,11 @@ int midi::midi_seq1_open, midi::midi_seq1_playing;
|
|||||||
|
|
||||||
MCIERROR midi::play_pb_theme(int flag)
|
MCIERROR midi::play_pb_theme(int flag)
|
||||||
{
|
{
|
||||||
|
if (pb::FullTiltMode)
|
||||||
|
{
|
||||||
|
return play_ft(track1);
|
||||||
|
}
|
||||||
|
|
||||||
MCI_PLAY_PARMS playParams;
|
MCI_PLAY_PARMS playParams;
|
||||||
MCIERROR result = 0;
|
MCIERROR result = 0;
|
||||||
|
|
||||||
@ -26,6 +33,11 @@ MCIERROR midi::play_pb_theme(int flag)
|
|||||||
|
|
||||||
MCIERROR midi::music_stop()
|
MCIERROR midi::music_stop()
|
||||||
{
|
{
|
||||||
|
if (pb::FullTiltMode)
|
||||||
|
{
|
||||||
|
return stop_ft();
|
||||||
|
}
|
||||||
|
|
||||||
MCIERROR result = 0;
|
MCIERROR result = 0;
|
||||||
if (midi_seq1_playing)
|
if (midi_seq1_playing)
|
||||||
result = mciSendCommandA(mci_open_info.wDeviceID, MCI_STOP, 0, 0);
|
result = mciSendCommandA(mci_open_info.wDeviceID, MCI_STOP, 0, 0);
|
||||||
@ -34,6 +46,11 @@ MCIERROR midi::music_stop()
|
|||||||
|
|
||||||
int midi::music_init(HWND hwnd)
|
int midi::music_init(HWND hwnd)
|
||||||
{
|
{
|
||||||
|
if (pb::FullTiltMode)
|
||||||
|
{
|
||||||
|
return music_init_ft(hwnd);
|
||||||
|
}
|
||||||
|
|
||||||
mci_open_info.wDeviceID = 0;
|
mci_open_info.wDeviceID = 0;
|
||||||
midi_notify_hwnd = hwnd;
|
midi_notify_hwnd = hwnd;
|
||||||
lstrcpyA(midi_device_type, pinball::get_rc_string(156, 0));
|
lstrcpyA(midi_device_type, pinball::get_rc_string(156, 0));
|
||||||
@ -46,6 +63,11 @@ int midi::music_init(HWND hwnd)
|
|||||||
|
|
||||||
MCIERROR midi::restart_midi_seq(int param)
|
MCIERROR midi::restart_midi_seq(int param)
|
||||||
{
|
{
|
||||||
|
if (pb::FullTiltMode)
|
||||||
|
{
|
||||||
|
return play_ft(active_track);
|
||||||
|
}
|
||||||
|
|
||||||
MCI_PLAY_PARMS playParams;
|
MCI_PLAY_PARMS playParams;
|
||||||
MCIERROR result = 0;
|
MCIERROR result = 0;
|
||||||
|
|
||||||
@ -58,7 +80,433 @@ MCIERROR midi::restart_midi_seq(int param)
|
|||||||
|
|
||||||
void midi::music_shutdown()
|
void midi::music_shutdown()
|
||||||
{
|
{
|
||||||
|
if (pb::FullTiltMode)
|
||||||
|
{
|
||||||
|
music_shutdown_ft();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (midi_seq1_open)
|
if (midi_seq1_open)
|
||||||
mciSendCommandA(mci_open_info.wDeviceID, MCI_CLOSE, 0, 0);
|
mciSendCommandA(mci_open_info.wDeviceID, MCI_CLOSE, 0, 0);
|
||||||
midi_seq1_open = 0;
|
midi_seq1_open = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
objlist_class<midi_struct>* midi::TrackList;
|
||||||
|
midi_struct *midi::track1, *midi::track2, *midi::track3, *midi::active_track, *midi::active_track2;
|
||||||
|
int midi::some_flag1;
|
||||||
|
|
||||||
|
int midi::music_init_ft(HWND hwnd)
|
||||||
|
{
|
||||||
|
midi_notify_hwnd = hwnd;
|
||||||
|
active_track = nullptr;
|
||||||
|
TrackList = new objlist_class<midi_struct>(0, 1);
|
||||||
|
|
||||||
|
track1 = load_track("taba1");
|
||||||
|
track2 = load_track("taba2");
|
||||||
|
track3 = load_track("taba3");
|
||||||
|
if (!track2)
|
||||||
|
track2 = track1;
|
||||||
|
if (!track3)
|
||||||
|
track3 = track1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void midi::music_shutdown_ft()
|
||||||
|
{
|
||||||
|
if (active_track)
|
||||||
|
stream_close(active_track);
|
||||||
|
while (TrackList->GetCount())
|
||||||
|
{
|
||||||
|
midi_struct* midi = TrackList->Get(0);
|
||||||
|
unload_track(midi);
|
||||||
|
TrackList->Delete(midi);
|
||||||
|
}
|
||||||
|
active_track = nullptr;
|
||||||
|
delete TrackList;
|
||||||
|
}
|
||||||
|
|
||||||
|
midi_struct* midi::load_track(LPCSTR fileName)
|
||||||
|
{
|
||||||
|
midi_struct* midi;
|
||||||
|
char filePath[256];
|
||||||
|
char fileName2[256];
|
||||||
|
|
||||||
|
lstrcpyA(fileName2, "sound\\");
|
||||||
|
lstrcatA(fileName2, fileName);
|
||||||
|
pinball::make_path_name(filePath, fileName2, 254u);
|
||||||
|
lstrcatA(filePath, ".MDS");
|
||||||
|
if (load_file(&midi, filePath, 0, 1))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (midi)
|
||||||
|
TrackList->Add(midi);
|
||||||
|
return midi;
|
||||||
|
}
|
||||||
|
|
||||||
|
int midi::load_file(midi_struct** midi_res, void* filePtrOrPath, int fileSizeP, int flags)
|
||||||
|
{
|
||||||
|
int returnCode;
|
||||||
|
unsigned int fileSize;
|
||||||
|
HANDLE mapHandle = nullptr;
|
||||||
|
midi_struct* midi = nullptr;
|
||||||
|
HANDLE fileHandle = INVALID_HANDLE_VALUE;
|
||||||
|
int fileFlag = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if ((flags & 3) == 0 || (flags & 3) == 3)
|
||||||
|
{
|
||||||
|
returnCode = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
midi = static_cast<midi_struct*>(LocalAlloc(0x40u, sizeof(midi_struct)));
|
||||||
|
if (!midi)
|
||||||
|
{
|
||||||
|
returnCode = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
midi->Magic = 'ISDM';
|
||||||
|
midi->StreamHandle = nullptr;
|
||||||
|
midi->PreparedBlocksCount = 0;
|
||||||
|
|
||||||
|
if ((flags & 2) != 0)
|
||||||
|
{
|
||||||
|
fileSize = fileSizeP;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fileFlag = 1;
|
||||||
|
fileHandle = CreateFileA(static_cast<LPCSTR>(filePtrOrPath), GENERIC_READ, 1u, nullptr, OPEN_EXISTING,
|
||||||
|
0x80u, nullptr);
|
||||||
|
if (fileHandle == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
returnCode = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileSize = GetFileSize(fileHandle, nullptr);
|
||||||
|
mapHandle = CreateFileMappingA(fileHandle, nullptr, 2u, 0, 0, nullptr);
|
||||||
|
if (!mapHandle)
|
||||||
|
{
|
||||||
|
returnCode = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
filePtrOrPath = MapViewOfFile(mapHandle, 4u, 0, 0, 0);
|
||||||
|
if (!filePtrOrPath)
|
||||||
|
{
|
||||||
|
returnCode = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
returnCode = read_file(midi, static_cast<riff_header*>(filePtrOrPath), fileSize);
|
||||||
|
}
|
||||||
|
while (false);
|
||||||
|
|
||||||
|
|
||||||
|
if (returnCode)
|
||||||
|
{
|
||||||
|
if (midi)
|
||||||
|
LocalFree(midi);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*midi_res = midi;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileFlag)
|
||||||
|
{
|
||||||
|
if (filePtrOrPath)
|
||||||
|
UnmapViewOfFile(filePtrOrPath);
|
||||||
|
if (mapHandle)
|
||||||
|
CloseHandle(mapHandle);
|
||||||
|
if (fileHandle != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle(fileHandle);
|
||||||
|
}
|
||||||
|
return returnCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int midi::read_file(midi_struct* midi, riff_header* filePtr, unsigned fileSize)
|
||||||
|
{
|
||||||
|
auto returnCode = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
midi->DataPtr1 = nullptr;
|
||||||
|
if (fileSize < 12)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (filePtr->Riff != 'FFIR')
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (filePtr->Mids != 'SDIM')
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (filePtr->FileSize > fileSize - 8)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (fileSize - 12 < 8)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (filePtr->Fmt != ' tmf')
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (filePtr->FmtSize > fileSize - 12)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (filePtr->FmtSize < 12)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
midi->DwTimeFormat = filePtr->dwTimeFormat;
|
||||||
|
midi->CbMaxBuffer = filePtr->cbMaxBuffer;
|
||||||
|
midi->DwFlagsFormat = filePtr->dwFlags;
|
||||||
|
auto blocksSize = fileSize - 20 - filePtr->FmtSize;
|
||||||
|
if (blocksSize < 8)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dataChunk = reinterpret_cast<riff_data*>(reinterpret_cast<char*>(&filePtr->dwTimeFormat) + filePtr->FmtSize
|
||||||
|
);
|
||||||
|
if (dataChunk->Data != 'atad')
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (dataChunk->DataSize > blocksSize || dataChunk->DataSize < 4)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
midi->BlockCount = dataChunk->BlocksPerChunk;
|
||||||
|
midi->DataPtr1 = static_cast<midihdr_tag*>(GlobalLock(GlobalAlloc(
|
||||||
|
GMEM_DDESHARE | GMEM_MOVEABLE, dataChunk->BlocksPerChunk * (midi->CbMaxBuffer + sizeof(midihdr_tag)))));
|
||||||
|
if (!midi->DataPtr1)
|
||||||
|
{
|
||||||
|
returnCode = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!midi->BlockCount)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto blocksSizeIndex = blocksSize - 12;
|
||||||
|
auto srcPtr = dataChunk->Blocks;
|
||||||
|
auto* dstPtr = midi->DataPtr1;
|
||||||
|
for (auto blockIndex = midi->BlockCount; blockIndex; blockIndex--)
|
||||||
|
{
|
||||||
|
dstPtr->lpData = reinterpret_cast<LPSTR>(&dstPtr[1]);
|
||||||
|
dstPtr->dwBufferLength = midi->CbMaxBuffer;
|
||||||
|
dstPtr->dwFlags = 0;
|
||||||
|
dstPtr->dwUser = reinterpret_cast<DWORD_PTR>(midi);
|
||||||
|
dstPtr->lpNext = nullptr;
|
||||||
|
if (blocksSizeIndex < 8)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto blockSize = srcPtr->CbBuffer;
|
||||||
|
if (blockSize > midi->CbMaxBuffer || blockSize > blocksSizeIndex - 8)
|
||||||
|
{
|
||||||
|
returnCode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((midi->DwFlagsFormat & 1) != 0)
|
||||||
|
{
|
||||||
|
/*Not used in FT, some kind of compression*/
|
||||||
|
assertm(false, "Unimplemented code reached");
|
||||||
|
/*int a1[16];
|
||||||
|
a1[0] = (int)blockDataPtr;
|
||||||
|
a1[2] = blockSize;
|
||||||
|
a1[1] = blockSize;
|
||||||
|
if (!sub_4031A0(a1, dataPtr))
|
||||||
|
{
|
||||||
|
returnCode = 3; break;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dstPtr->dwBytesRecorded = blockSize;
|
||||||
|
memcpy(dstPtr->lpData, srcPtr->AData, blockSize);
|
||||||
|
}
|
||||||
|
blocksSizeIndex -= blockSize + 8;
|
||||||
|
srcPtr = reinterpret_cast<riff_block*>(&srcPtr->AData[blockSize]);
|
||||||
|
dstPtr = reinterpret_cast<midihdr_tag*>(reinterpret_cast<char*>(&dstPtr[1]) + midi->CbMaxBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (false);
|
||||||
|
|
||||||
|
if (returnCode && midi->DataPtr1)
|
||||||
|
{
|
||||||
|
GlobalUnlock(GlobalHandle(midi->DataPtr1));
|
||||||
|
GlobalFree(GlobalHandle(midi->DataPtr1));
|
||||||
|
}
|
||||||
|
return returnCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int midi::play_ft(midi_struct* midi)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
stop_ft();
|
||||||
|
if (!midi)
|
||||||
|
return 0;
|
||||||
|
if (some_flag1)
|
||||||
|
{
|
||||||
|
active_track2 = midi;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (stream_open(midi, 1))
|
||||||
|
{
|
||||||
|
active_track = nullptr;
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
active_track = midi;
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int midi::stop_ft()
|
||||||
|
{
|
||||||
|
int returnCode = 0;
|
||||||
|
if (active_track)
|
||||||
|
returnCode = stream_close(active_track);
|
||||||
|
active_track = nullptr;
|
||||||
|
return returnCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int midi::unload_track(midi_struct* midi)
|
||||||
|
{
|
||||||
|
if (midi->Magic != 'ISDM')
|
||||||
|
return 6;
|
||||||
|
if (midi->StreamHandle)
|
||||||
|
stream_close(midi);
|
||||||
|
if (midi->DataPtr1)
|
||||||
|
{
|
||||||
|
GlobalUnlock(GlobalHandle(midi->DataPtr1));
|
||||||
|
GlobalFree(GlobalHandle(midi->DataPtr1));
|
||||||
|
}
|
||||||
|
midi->Magic = 'atad';
|
||||||
|
LocalFree(midi);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int midi::stream_open(midi_struct* midi, char flags)
|
||||||
|
{
|
||||||
|
auto returnCode = 0;
|
||||||
|
if (midi->Magic != 'ISDM')
|
||||||
|
return 6;
|
||||||
|
|
||||||
|
UINT puDeviceID = -1;
|
||||||
|
auto steamOpenedFg = !midi->StreamHandle;
|
||||||
|
MIDIPROPTIMEDIV propdata{8, midi->DwTimeFormat};
|
||||||
|
if (steamOpenedFg &&
|
||||||
|
!midiStreamOpen(&midi->StreamHandle, &puDeviceID, 1u, reinterpret_cast<DWORD_PTR>(midi_callback), 0,
|
||||||
|
CALLBACK_FUNCTION) &&
|
||||||
|
!midiStreamProperty(midi->StreamHandle, reinterpret_cast<LPBYTE>(&propdata),MIDIPROP_TIMEDIV | MIDIPROP_SET))
|
||||||
|
{
|
||||||
|
midihdr_tag* blockPtr = midi->DataPtr1;
|
||||||
|
for (auto blockIndex = midi->BlockCount; blockIndex; blockIndex--)
|
||||||
|
{
|
||||||
|
if (midiOutPrepareHeader(reinterpret_cast<HMIDIOUT>(midi->StreamHandle), blockPtr, sizeof(MIDIHDR)) ||
|
||||||
|
midiStreamOut(midi->StreamHandle, blockPtr, sizeof(MIDIHDR)))
|
||||||
|
{
|
||||||
|
returnCode = 5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
++midi->PreparedBlocksCount;
|
||||||
|
blockPtr = reinterpret_cast<midihdr_tag*>(reinterpret_cast<char*>(&blockPtr[1]) + blockPtr->dwBufferLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!returnCode)
|
||||||
|
{
|
||||||
|
if (!steamOpenedFg && (midi->SomeFlag2 & 4) == 0)
|
||||||
|
return 7;
|
||||||
|
|
||||||
|
midi->SomeFlag2 &= ~2;
|
||||||
|
if ((flags & 1) != 0)
|
||||||
|
midi->SomeFlag2 |= 2;
|
||||||
|
midi->SomeFlag2 &= ~4;
|
||||||
|
if (midiStreamRestart(midi->StreamHandle))
|
||||||
|
returnCode = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (returnCode && steamOpenedFg)
|
||||||
|
{
|
||||||
|
if (midi->StreamHandle)
|
||||||
|
stream_close(midi);
|
||||||
|
}
|
||||||
|
return returnCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
int midi::stream_close(midi_struct* midi)
|
||||||
|
{
|
||||||
|
int returnCode;
|
||||||
|
|
||||||
|
if (midi->Magic != 'ISDM')
|
||||||
|
return 6;
|
||||||
|
if (!midi->StreamHandle)
|
||||||
|
return 7;
|
||||||
|
midi->SomeFlag2 |= 1u;
|
||||||
|
if (midiOutReset(reinterpret_cast<HMIDIOUT>(midi->StreamHandle)))
|
||||||
|
{
|
||||||
|
returnCode = 5;
|
||||||
|
midi->SomeFlag2 &= ~1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
midihdr_tag* blockPtr = midi->DataPtr1;
|
||||||
|
for (int i = midi->BlockCount; i; --i)
|
||||||
|
{
|
||||||
|
midiOutUnprepareHeader(reinterpret_cast<HMIDIOUT>(midi->StreamHandle), blockPtr, sizeof(MIDIHDR));
|
||||||
|
blockPtr = reinterpret_cast<midihdr_tag*>(reinterpret_cast<char*>(&blockPtr[1]) + blockPtr->dwBufferLength);
|
||||||
|
}
|
||||||
|
midiStreamClose(midi->StreamHandle);
|
||||||
|
returnCode = 0;
|
||||||
|
midi->StreamHandle = nullptr;
|
||||||
|
midi->SomeFlag2 = 0;
|
||||||
|
}
|
||||||
|
return returnCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void midi::midi_callback(HMIDIOUT hmo, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
|
||||||
|
{
|
||||||
|
if (wMsg == 969)
|
||||||
|
{
|
||||||
|
auto mhdr = reinterpret_cast<LPMIDIHDR>(dwParam1);
|
||||||
|
auto midi = reinterpret_cast<midi_struct*>(mhdr->dwUser);
|
||||||
|
if ((midi->SomeFlag2 & 2) == 0 || (midi->SomeFlag2 & 1) != 0 || midiStreamOut(
|
||||||
|
midi->StreamHandle, mhdr, sizeof(MIDIHDR)))
|
||||||
|
--midi->PreparedBlocksCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,54 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "objlist_class.h"
|
||||||
|
|
||||||
|
struct midi_struct
|
||||||
|
{
|
||||||
|
DWORD Magic;
|
||||||
|
DWORD DwTimeFormat;
|
||||||
|
DWORD CbMaxBuffer;
|
||||||
|
DWORD DwFlagsFormat;
|
||||||
|
midihdr_tag* DataPtr1;
|
||||||
|
HMIDISTRM StreamHandle;
|
||||||
|
int SomeFlag2;
|
||||||
|
int BlockCount;
|
||||||
|
int PreparedBlocksCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma pack(push)
|
||||||
|
#pragma pack(1)
|
||||||
|
struct riff_block
|
||||||
|
{
|
||||||
|
DWORD TkStart;
|
||||||
|
DWORD CbBuffer;
|
||||||
|
char AData[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct riff_data
|
||||||
|
{
|
||||||
|
DWORD Data;
|
||||||
|
DWORD DataSize;
|
||||||
|
DWORD BlocksPerChunk;
|
||||||
|
riff_block Blocks[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct riff_header
|
||||||
|
{
|
||||||
|
DWORD Riff;
|
||||||
|
DWORD FileSize;
|
||||||
|
DWORD Mids;
|
||||||
|
DWORD Fmt;
|
||||||
|
DWORD FmtSize;
|
||||||
|
DWORD dwTimeFormat;
|
||||||
|
DWORD cbMaxBuffer;
|
||||||
|
DWORD dwFlags;
|
||||||
|
riff_data Data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(riff_block) == 0xC, "Wrong size of riff_block");
|
||||||
|
static_assert(sizeof(riff_data) == 0x18, "Wrong size of riff_data");
|
||||||
|
static_assert(sizeof(riff_header) == 0x38, "Wrong size of riff_header");
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
class midi
|
class midi
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -7,10 +57,25 @@ public:
|
|||||||
static int music_init(HWND hwnd);
|
static int music_init(HWND hwnd);
|
||||||
static MCIERROR restart_midi_seq(int param);
|
static MCIERROR restart_midi_seq(int param);
|
||||||
static void music_shutdown();
|
static void music_shutdown();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static tagMCI_OPEN_PARMSA mci_open_info;
|
static tagMCI_OPEN_PARMSA mci_open_info;
|
||||||
static char midi_device_type[28];
|
static char midi_device_type[28];
|
||||||
static HWND midi_notify_hwnd;
|
static HWND midi_notify_hwnd;
|
||||||
static int midi_seq1_open, midi_seq1_playing;
|
static int midi_seq1_open, midi_seq1_playing;
|
||||||
|
|
||||||
|
static objlist_class<midi_struct>* TrackList;
|
||||||
|
static midi_struct *track1, *track2, *track3, *active_track, *active_track2;
|
||||||
|
static int some_flag1;
|
||||||
|
static int music_init_ft(HWND hwnd);
|
||||||
|
static void music_shutdown_ft();
|
||||||
|
static midi_struct* load_track(LPCSTR fileName);
|
||||||
|
static int load_file(midi_struct** midi_res, void* filePtrOrPath, int fileSizeP, int flags);
|
||||||
|
static int read_file(midi_struct* midi, riff_header* filePtr, unsigned int fileSize);
|
||||||
|
static int play_ft(midi_struct* midi);
|
||||||
|
static int stop_ft();
|
||||||
|
static int unload_track(midi_struct* midi);
|
||||||
|
static int stream_open(midi_struct* midi, char flags);
|
||||||
|
static int stream_close(midi_struct* midi);
|
||||||
|
static void CALLBACK midi_callback(HMIDIOUT hmo, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1,
|
||||||
|
DWORD_PTR dwParam2);
|
||||||
};
|
};
|
||||||
|
@ -165,7 +165,7 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
|
|||||||
options::init_resolution();
|
options::init_resolution();
|
||||||
|
|
||||||
char windowName[40];
|
char windowName[40];
|
||||||
lstrcpyA(windowName, pinball::get_rc_string(38, 0));
|
lstrcpyA(windowName, pinball::get_rc_string(38, 0));
|
||||||
windowHandle = CreateWindowExA(0, windowClass, windowName, WndStyle, 0, 0, 640, 480, nullptr, nullptr, hInstance,
|
windowHandle = CreateWindowExA(0, windowClass, windowName, WndStyle, 0, 0, 640, 480, nullptr, nullptr, hInstance,
|
||||||
nullptr);
|
nullptr);
|
||||||
hwnd_frame = windowHandle;
|
hwnd_frame = windowHandle;
|
||||||
@ -268,10 +268,14 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
|
|||||||
now = timeGetTime();
|
now = timeGetTime();
|
||||||
if (now - then >= 2)
|
if (now - then >= 2)
|
||||||
{
|
{
|
||||||
|
/*last_mouse_n is in client coordinates*/
|
||||||
POINT Point;
|
POINT Point;
|
||||||
GetCursorPos(&Point);
|
GetCursorPos(&Point);
|
||||||
|
ScreenToClient(hwnd_frame, &Point);
|
||||||
pb::ballset(last_mouse_x - Point.x, Point.y - last_mouse_y);
|
pb::ballset(last_mouse_x - Point.x, Point.y - last_mouse_y);
|
||||||
SetCursorPos(last_mouse_x, last_mouse_y);
|
Point = POINT{last_mouse_x, last_mouse_y};
|
||||||
|
ClientToScreen(hwnd_frame, &Point);
|
||||||
|
SetCursorPos(Point.x, Point.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!single_step)
|
if (!single_step)
|
||||||
@ -705,7 +709,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
|
|||||||
case WM_PALETTECHANGED:
|
case WM_PALETTECHANGED:
|
||||||
InvalidateRect(hWnd, nullptr, 0);
|
InvalidateRect(hWnd, nullptr, 0);
|
||||||
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
||||||
case WM_POINTERDEVICEINRANGE | LB_ADDSTRING:
|
case MM_MCINOTIFY:
|
||||||
if (wParam == 1)
|
if (wParam == 1)
|
||||||
midi::restart_midi_seq(lParam);
|
midi::restart_midi_seq(lParam);
|
||||||
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
return DefWindowProcA(hWnd, Msg, wParam, lParam);
|
||||||
|
Loading…
Reference in New Issue
Block a user