Initial commit: ROW Client source code

Game client codebase including:
- CharacterActionControl: Character and creature management
- GlobalScript: Network, items, skills, quests, utilities
- RYLClient: Main client application with GUI and event handlers
- Engine: 3D rendering engine (RYLGL)
- MemoryManager: Custom memory allocation
- Library: Third-party dependencies (DirectX, boost, etc.)
- Tools: Development utilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-29 16:24:34 +09:00
commit e067522598
5135 changed files with 1745744 additions and 0 deletions

View File

@@ -0,0 +1,549 @@
//-----------------------------------------------------------------------------
// File: PlayAudio.cpp
//
// Desc: Plays a primary segment using DirectMusic
//
// Copyright (c) 2000-2001 Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#define STRICT
#include <windows.h>
#include <basetsd.h>
#include <commdlg.h>
#include <commctrl.h>
#include <dmusicc.h>
#include <dmusici.h>
#include <dxerr8.h>
#include <tchar.h>
#include "resource.h"
#include "DMUtil.h"
#include "DXUtil.h"
//-----------------------------------------------------------------------------
// Function-prototypes
//-----------------------------------------------------------------------------
INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam );
HRESULT OnInitDialog( HWND hDlg );
HRESULT ProcessDirectMusicMessages( HWND hDlg );
VOID OnOpenSoundFile( HWND hDlg );
HRESULT LoadSegmentFile( HWND hDlg, TCHAR* strFileName );
HRESULT OnPlayAudio( HWND hDlg );
VOID EnablePlayUI( HWND hDlg, BOOL bEnable );
//-----------------------------------------------------------------------------
// Defines, constants, and global variables
//-----------------------------------------------------------------------------
#define MUSIC_VOLUME_RANGE ( 0-(DMUS_VOLUME_MIN/4) )
CMusicManager* g_pMusicManager = NULL;
CMusicSegment* g_pMusicSegment = NULL;
HINSTANCE g_hInst = NULL;
HANDLE g_hDMusicMessageEvent = NULL;
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: Entry point for the application. Since we use a simple dialog for
// user interaction we don't need to pump messages.
//-----------------------------------------------------------------------------
INT APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine,
INT nCmdShow )
{
HWND hDlg = NULL;
BOOL bDone = FALSE;
int nExitCode;
HRESULT hr;
DWORD dwResult;
MSG msg;
g_hInst = hInst;
InitCommonControls();
// Display the main dialog box.
hDlg = CreateDialog( hInst, MAKEINTRESOURCE(IDD_MAIN),
NULL, MainDlgProc );
while( !bDone )
{
dwResult = MsgWaitForMultipleObjects( 1, &g_hDMusicMessageEvent,
FALSE, INFINITE, QS_ALLEVENTS );
switch( dwResult )
{
case WAIT_OBJECT_0 + 0:
// g_hDPMessageEvent is signaled, so there are
// DirectPlay messages available
if( FAILED( hr = ProcessDirectMusicMessages( hDlg ) ) )
{
DXTRACE_ERR( TEXT("ProcessDirectMusicMessages"), hr );
return FALSE;
}
break;
case WAIT_OBJECT_0 + 1:
// Windows messages are available
while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
if( !IsDialogMessage( hDlg, &msg ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
if( msg.message == WM_QUIT )
{
nExitCode = (int)msg.wParam;
bDone = TRUE;
DestroyWindow( hDlg );
}
}
break;
}
}
return nExitCode;
}
//-----------------------------------------------------------------------------
// Name: MainDlgProc()
// Desc: Handles dialog messages
//-----------------------------------------------------------------------------
INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
{
HRESULT hr;
switch( msg )
{
case WM_INITDIALOG:
if( FAILED( hr = OnInitDialog( hDlg ) ) )
{
DXTRACE_ERR( TEXT("OnInitDialog"), hr );
MessageBox( hDlg, "Error initializing DirectMusic. Sample will now exit.",
"DirectMusic Sample", MB_OK | MB_ICONERROR );
EndDialog( hDlg, 0 );
return TRUE;
}
break;
case WM_COMMAND:
switch( LOWORD(wParam) )
{
case IDC_SOUNDFILE:
OnOpenSoundFile( hDlg );
break;
case IDCANCEL:
PostQuitMessage( IDCANCEL );
break;
case IDC_PLAY:
if( FAILED( hr = OnPlayAudio( hDlg ) ) )
{
DXTRACE_ERR( TEXT("OnPlayAudio"), hr );
MessageBox( hDlg, "Error playing DirectMusic segment. "
"Sample will now exit.", "DirectMusic Sample",
MB_OK | MB_ICONERROR );
PostQuitMessage( IDABORT );
}
break;
case IDC_STOP:
g_pMusicSegment->Stop( DMUS_SEGF_BEAT );
EnablePlayUI( hDlg, TRUE );
break;
default:
return FALSE; // Didn't handle message
}
break;
case WM_NOTIFY:
if( wParam == IDC_TEMPO_SLIDER )
{
static int s_nLastTempo = -1;
int nTempo = (int)SendDlgItemMessage( hDlg, IDC_TEMPO_SLIDER, TBM_GETPOS, 0, 0 );
if( nTempo != s_nLastTempo )
{
IDirectMusicPerformance* pPerf = NULL;
if( g_pMusicManager )
pPerf = g_pMusicManager->GetPerformance();
if( NULL == pPerf )
break;
s_nLastTempo = nTempo;
// Adjust the slider position to go between 1/4th and 4x tempo
FLOAT fTempo;
if( nTempo > 4 )
fTempo = (float)(nTempo-3);
else
fTempo = nTempo/4.0f;
pPerf->SetGlobalParam( GUID_PerfMasterTempo,
(void*)&fTempo, sizeof(float) );
}
}
else if( wParam == IDC_VOLUME_SLIDER )
{
static long s_nLastVolume = -1;
long nSlider = (long)SendDlgItemMessage( hDlg, IDC_VOLUME_SLIDER, TBM_GETPOS, 0, 0 );
long nVolume = nSlider - MUSIC_VOLUME_RANGE;
if( nVolume != s_nLastVolume )
{
IDirectMusicPerformance* pPerf = NULL;
if( g_pMusicManager )
pPerf = g_pMusicManager->GetPerformance();
if( NULL == pPerf )
break;
s_nLastVolume = nVolume;
// Adjust the slider position to match GUID_PerfMasterTempo range
pPerf->SetGlobalParam( GUID_PerfMasterVolume,
(void*)&nVolume, sizeof(long) );
}
}
break;
case WM_DESTROY:
// Cleanup everything
SAFE_DELETE( g_pMusicSegment );
SAFE_DELETE( g_pMusicManager );
CloseHandle( g_hDMusicMessageEvent );
break;
default:
return FALSE; // Didn't handle message
}
return TRUE; // Handled message
}
//-----------------------------------------------------------------------------
// Name: OnInitDialog()
// Desc: Initializes the dialogs (sets up UI controls, etc.)
//-----------------------------------------------------------------------------
HRESULT OnInitDialog( HWND hDlg )
{
HRESULT hr;
// Load the icon
HICON hIcon = LoadIcon( g_hInst, MAKEINTRESOURCE( IDR_MAINFRAME ) );
// Set the icon for this dialog.
SendMessage( hDlg, WM_SETICON, ICON_BIG, (LPARAM) hIcon ); // Set big icon
SendMessage( hDlg, WM_SETICON, ICON_SMALL, (LPARAM) hIcon ); // Set small icon
g_hDMusicMessageEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
g_pMusicManager = new CMusicManager();
if( FAILED( hr = g_pMusicManager->Initialize( hDlg ) ) )
return DXTRACE_ERR( TEXT("Initialize"), hr );
// Register segment notification
IDirectMusicPerformance* pPerf = g_pMusicManager->GetPerformance();
GUID guid = GUID_NOTIFICATION_SEGMENT;
pPerf->AddNotificationType( guid );
pPerf->SetNotificationHandle( g_hDMusicMessageEvent, 0 );
SendDlgItemMessage( hDlg, IDC_TEMPO_SLIDER, TBM_SETRANGE, FALSE, MAKELONG( 1, 7 ) );
SendDlgItemMessage( hDlg, IDC_TEMPO_SLIDER, TBM_SETTIC, TRUE, 4 );
SendDlgItemMessage( hDlg, IDC_TEMPO_SLIDER, TBM_SETPOS, TRUE, 4 );
SendDlgItemMessage( hDlg, IDC_VOLUME_SLIDER, TBM_SETRANGE, FALSE, MAKELONG( 0, MUSIC_VOLUME_RANGE ) );
SendDlgItemMessage( hDlg, IDC_VOLUME_SLIDER, TBM_SETPOS, TRUE, MUSIC_VOLUME_RANGE );
// Load a default music segment
TCHAR strFileName[MAX_PATH];
strcpy( strFileName, DXUtil_GetDXSDKMediaPath() );
strcat( strFileName, "sample.sgt" );
if( S_FALSE == LoadSegmentFile( hDlg, strFileName ) )
{
// Set the UI controls
SetDlgItemText( hDlg, IDC_FILENAME, TEXT("No file loaded.") );
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: OnOpenSoundFile()
// Desc: Called when the user requests to open a sound file
//-----------------------------------------------------------------------------
VOID OnOpenSoundFile( HWND hDlg )
{
static TCHAR strFileName[MAX_PATH] = TEXT("");
static TCHAR strPath[MAX_PATH] = TEXT("");
// Get the default media path (something like C:\MSSDK\SAMPLES\DMUSIC\MEDIA)
if( '\0' == strPath[0] )
{
const TCHAR* szDir = DXUtil_GetDXSDKMediaPath();
strcpy( strPath, szDir );
}
// Setup the OPENFILENAME structure
OPENFILENAME ofn = { sizeof(OPENFILENAME), hDlg, NULL,
TEXT("DirectMusic Content Files\0*.sgt;*.mid;*.rmi\0Wave Files\0*.wav\0All Files\0*.*\0\0"), NULL,
0, 1, strFileName, MAX_PATH, NULL, 0, strPath,
TEXT("Open Content File"),
OFN_FILEMUSTEXIST|OFN_HIDEREADONLY, 0, 0,
TEXT(".sgt"), 0, NULL, NULL };
if( g_pMusicSegment )
g_pMusicSegment->Stop( 0 );
// Update the UI controls to show the sound as loading a file
EnableWindow( GetDlgItem( hDlg, IDC_PLAY ), FALSE);
EnableWindow( GetDlgItem( hDlg, IDC_STOP ), FALSE);
SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Loading file...") );
// Display the OpenFileName dialog. Then, try to load the specified file
if( TRUE != GetOpenFileName( &ofn ) )
{
SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Load aborted.") );
return;
}
if( S_FALSE == LoadSegmentFile( hDlg, strFileName ) )
{
// Not a critical failure, so just update the status
SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Could not create segment from file.") );
}
// Remember the path for next time
strcpy( strPath, strFileName );
char* strLastSlash = strrchr( strPath, '\\' );
strLastSlash[0] = '\0';
}
//-----------------------------------------------------------------------------
// Name: LoadSegmentFile()
// Desc:
//-----------------------------------------------------------------------------
HRESULT LoadSegmentFile( HWND hDlg, TCHAR* strFileName )
{
HRESULT hr;
SetDlgItemText( hDlg, IDC_FILENAME, TEXT("") );
// Free any previous segment, and make a new one
SAFE_DELETE( g_pMusicSegment );
// Have the loader collect any garbage now that the old
// segment has been released
g_pMusicManager->CollectGarbage();
// Set the media path based on the file name (something like C:\MEDIA)
// to be used as the search directory for finding DirectMusic content
// related to this file.
TCHAR strMediaPath[MAX_PATH];
_tcscpy( strMediaPath, strFileName );
TCHAR* strLastSlash = _tcsrchr(strMediaPath, TEXT('\\'));
*strLastSlash = 0;
if( FAILED( hr = g_pMusicManager->SetSearchDirectory( strMediaPath ) ) )
return DXTRACE_ERR( TEXT("SetSearchDirectory"), hr );
// For DirectMusic must know if the file is a standard MIDI file or not
// in order to load the correct instruments.
BOOL bMidiFile = FALSE;
if( strstr( strFileName, ".mid" ) != NULL ||
strstr( strFileName, ".rmi" ) != NULL )
{
bMidiFile = TRUE;
}
BOOL bWavFile = FALSE;
if( strstr( strFileName, ".wav" ) != NULL )
{
bWavFile = TRUE;
}
// Load the file into a DirectMusic segment
if( FAILED( g_pMusicManager->CreateSegmentFromFile( &g_pMusicSegment, strFileName,
TRUE, bMidiFile ) ) )
{
// Not a critical failure, so just update the status
return S_FALSE;
}
// Update the UI controls to show the segment is loaded
SetDlgItemText( hDlg, IDC_FILENAME, strFileName );
EnablePlayUI( hDlg, TRUE );
// If we are loading a wav, then disable the tempo slider since
// tempo adjustments will not take effect when playing wav files.
EnableWindow( GetDlgItem( hDlg, IDC_TEMPO_SLIDER ), !bWavFile );
EnableWindow( GetDlgItem( hDlg, IDC_TEMPO_GROUPBOX ), !bWavFile );
EnableWindow( GetDlgItem( hDlg, IDC_TEMPO_SLOWTXT ), !bWavFile );
EnableWindow( GetDlgItem( hDlg, IDC_TEMPO_FASTTXT ), !bWavFile );
EnableWindow( GetDlgItem( hDlg, IDC_TEMPO_NORMALTXT ), !bWavFile );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: ProcessDirectMusicMessages()
// Desc: Handle DirectMusic notification messages
//-----------------------------------------------------------------------------
HRESULT ProcessDirectMusicMessages( HWND hDlg )
{
HRESULT hr;
IDirectMusicPerformance8* pPerf = NULL;
DMUS_NOTIFICATION_PMSG* pPMsg;
if( NULL == g_pMusicManager )
return S_OK;
pPerf = g_pMusicManager->GetPerformance();
// Get waiting notification message from the performance
while( S_OK == pPerf->GetNotificationPMsg( &pPMsg ) )
{
switch( pPMsg->dwNotificationOption )
{
case DMUS_NOTIFICATION_SEGEND:
if( pPMsg->punkUser )
{
IDirectMusicSegmentState8* pSegmentState = NULL;
IDirectMusicSegment* pNotifySegment = NULL;
IDirectMusicSegment8* pNotifySegment8 = NULL;
IDirectMusicSegment8* pPrimarySegment8 = NULL;
// The pPMsg->punkUser contains a IDirectMusicSegmentState8,
// which we can query for the segment that the SegmentState refers to.
if( FAILED( hr = pPMsg->punkUser->QueryInterface( IID_IDirectMusicSegmentState8,
(VOID**) &pSegmentState ) ) )
return DXTRACE_ERR( TEXT("QueryInterface"), hr );
if( FAILED( hr = pSegmentState->GetSegment( &pNotifySegment ) ) )
{
// Sometimes the segend arrives after the segment is gone
// This can happen when you load another segment as
// a motif or the segment is ending
if( hr == DMUS_E_NOT_FOUND )
{
SAFE_RELEASE( pSegmentState );
return S_OK;
}
return DXTRACE_ERR( TEXT("GetSegment"), hr );
}
if( FAILED( hr = pNotifySegment->QueryInterface( IID_IDirectMusicSegment8,
(VOID**) &pNotifySegment8 ) ) )
return DXTRACE_ERR( TEXT("QueryInterface"), hr );
// Get the IDirectMusicSegment for the primary segment
pPrimarySegment8 = g_pMusicSegment->GetSegment();
// Figure out which segment this is
if( pNotifySegment8 == pPrimarySegment8 )
{
// Update the UI controls to show the sound as stopped
EnablePlayUI( hDlg, TRUE );
}
// Cleanup
SAFE_RELEASE( pSegmentState );
SAFE_RELEASE( pNotifySegment );
SAFE_RELEASE( pNotifySegment8 );
}
break;
}
pPerf->FreePMsg( (DMUS_PMSG*)pPMsg );
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: OnPlayAudio()
// Desc:
//-----------------------------------------------------------------------------
HRESULT OnPlayAudio( HWND hDlg )
{
HRESULT hr;
HWND hLoopButton = GetDlgItem( hDlg, IDC_LOOP_CHECK );
BOOL bLooped = ( SendMessage( hLoopButton, BM_GETSTATE, 0, 0 ) == BST_CHECKED );
if( bLooped )
{
// Set the segment to repeat many times
if( FAILED( hr = g_pMusicSegment->SetRepeats( DMUS_SEG_REPEAT_INFINITE ) ) )
return DXTRACE_ERR( TEXT("SetRepeats"), hr );
}
else
{
// Set the segment to not repeat
if( FAILED( hr = g_pMusicSegment->SetRepeats( 0 ) ) )
return DXTRACE_ERR( TEXT("SetRepeats"), hr );
}
// Play the segment and wait. The DMUS_SEGF_BEAT indicates to play on the
// next beat if there is a segment currently playing.
if( FAILED( hr = g_pMusicSegment->Play( DMUS_SEGF_BEAT ) ) )
return DXTRACE_ERR( TEXT("Play"), hr );
EnablePlayUI( hDlg, FALSE );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: EnablePlayUI( hDlg,)
// Desc: Enables or disables the Play UI controls
//-----------------------------------------------------------------------------
VOID EnablePlayUI( HWND hDlg, BOOL bEnable )
{
if( bEnable )
{
EnableWindow( GetDlgItem( hDlg, IDC_LOOP_CHECK ), TRUE );
EnableWindow( GetDlgItem( hDlg, IDC_STOP ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_PLAY ), TRUE );
SetFocus( GetDlgItem( hDlg, IDC_PLAY ) );
}
else
{
EnableWindow( GetDlgItem( hDlg, IDC_LOOP_CHECK ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDC_STOP ), TRUE );
SetFocus( GetDlgItem( hDlg, IDC_STOP ) );
EnableWindow( GetDlgItem( hDlg, IDC_PLAY ), FALSE );
}
}

View File

@@ -0,0 +1,139 @@
# Microsoft Developer Studio Project File - Name="PlayAudio" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=PlayAudio - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "PlayAudio.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "PlayAudio.mak" CFG="PlayAudio - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "PlayAudio - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "PlayAudio - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "PlayAudio - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "..\..\common\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 comctl32.lib dxerr8.lib winmm.lib dxguid.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /stack:0x200000,0x200000
!ELSEIF "$(CFG)" == "PlayAudio - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\common\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 comctl32.lib dxerr8.lib winmm.lib dxguid.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept /stack:0x200000,0x200000
!ENDIF
# Begin Target
# Name "PlayAudio - Win32 Release"
# Name "PlayAudio - Win32 Debug"
# Begin Group "Source"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\PlayAudio.cpp
# End Source File
# End Group
# Begin Group "Resource"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\directx.ico
# End Source File
# Begin Source File
SOURCE=.\PlayAudio.rc
# End Source File
# Begin Source File
SOURCE=.\resource.h
# End Source File
# End Group
# Begin Group "Common"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\common\src\dmutil.cpp
# End Source File
# Begin Source File
SOURCE=..\..\common\include\dmutil.h
# End Source File
# Begin Source File
SOURCE=..\..\common\src\dxutil.cpp
# End Source File
# Begin Source File
SOURCE=..\..\common\include\dxutil.h
# End Source File
# End Group
# Begin Source File
SOURCE=.\readme.txt
# End Source File
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "PlayAudio"=.\PlayAudio.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@@ -0,0 +1,221 @@
# Microsoft Developer Studio Generated NMAKE File, Based on PlayAudio.dsp
!IF "$(CFG)" == ""
CFG=PlayAudio - Win32 Debug
!MESSAGE No configuration specified. Defaulting to PlayAudio - Win32 Debug.
!ENDIF
!IF "$(CFG)" != "PlayAudio - Win32 Release" && "$(CFG)" != "PlayAudio - Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "PlayAudio.mak" CFG="PlayAudio - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "PlayAudio - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "PlayAudio - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
!IF "$(OS)" == "Windows_NT"
NULL=
!ELSE
NULL=nul
!ENDIF
!IF "$(CFG)" == "PlayAudio - Win32 Release"
OUTDIR=.\Release
INTDIR=.\Release
# Begin Custom Macros
OutDir=.\Release
# End Custom Macros
ALL : "$(OUTDIR)\PlayAudio.exe"
CLEAN :
-@erase "$(INTDIR)\dmutil.obj"
-@erase "$(INTDIR)\dxutil.obj"
-@erase "$(INTDIR)\PlayAudio.obj"
-@erase "$(INTDIR)\PlayAudio.res"
-@erase "$(INTDIR)\vc60.idb"
-@erase "$(OUTDIR)\PlayAudio.exe"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
CPP=cl.exe
CPP_PROJ=/nologo /ML /W3 /GX /O2 /I "..\..\common\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fp"$(INTDIR)\PlayAudio.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
.c{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.c{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
MTL=midl.exe
MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
RSC=rc.exe
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\PlayAudio.res" /d "NDEBUG"
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\PlayAudio.bsc"
BSC32_SBRS= \
LINK32=link.exe
LINK32_FLAGS=comctl32.lib dxerr8.lib winmm.lib dxguid.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\PlayAudio.pdb" /machine:I386 /out:"$(OUTDIR)\PlayAudio.exe" /stack:0x200000,0x200000
LINK32_OBJS= \
"$(INTDIR)\PlayAudio.obj" \
"$(INTDIR)\dmutil.obj" \
"$(INTDIR)\dxutil.obj" \
"$(INTDIR)\PlayAudio.res"
"$(OUTDIR)\PlayAudio.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "PlayAudio - Win32 Debug"
OUTDIR=.\Debug
INTDIR=.\Debug
# Begin Custom Macros
OutDir=.\Debug
# End Custom Macros
ALL : "$(OUTDIR)\PlayAudio.exe"
CLEAN :
-@erase "$(INTDIR)\dmutil.obj"
-@erase "$(INTDIR)\dxutil.obj"
-@erase "$(INTDIR)\PlayAudio.obj"
-@erase "$(INTDIR)\PlayAudio.res"
-@erase "$(INTDIR)\vc60.idb"
-@erase "$(INTDIR)\vc60.pdb"
-@erase "$(OUTDIR)\PlayAudio.exe"
-@erase "$(OUTDIR)\PlayAudio.ilk"
-@erase "$(OUTDIR)\PlayAudio.pdb"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
CPP=cl.exe
CPP_PROJ=/nologo /MLd /W3 /Gm /GX /Zi /Od /I "..\..\common\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /Fp"$(INTDIR)\PlayAudio.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
.c{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.c{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<
MTL=midl.exe
MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
RSC=rc.exe
RSC_PROJ=/l 0x409 /fo"$(INTDIR)\PlayAudio.res" /d "_DEBUG"
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\PlayAudio.bsc"
BSC32_SBRS= \
LINK32=link.exe
LINK32_FLAGS=comctl32.lib dxerr8.lib winmm.lib dxguid.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /incremental:yes /pdb:"$(OUTDIR)\PlayAudio.pdb" /debug /machine:I386 /out:"$(OUTDIR)\PlayAudio.exe" /pdbtype:sept /stack:0x200000,0x200000
LINK32_OBJS= \
"$(INTDIR)\PlayAudio.obj" \
"$(INTDIR)\dmutil.obj" \
"$(INTDIR)\dxutil.obj" \
"$(INTDIR)\PlayAudio.res"
"$(OUTDIR)\PlayAudio.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
!IF "$(NO_EXTERNAL_DEPS)" != "1"
!IF EXISTS("PlayAudio.dep")
!INCLUDE "PlayAudio.dep"
!ELSE
!MESSAGE Warning: cannot find "PlayAudio.dep"
!ENDIF
!ENDIF
!IF "$(CFG)" == "PlayAudio - Win32 Release" || "$(CFG)" == "PlayAudio - Win32 Debug"
SOURCE=.\PlayAudio.cpp
"$(INTDIR)\PlayAudio.obj" : $(SOURCE) "$(INTDIR)"
SOURCE=.\PlayAudio.rc
"$(INTDIR)\PlayAudio.res" : $(SOURCE) "$(INTDIR)"
$(RSC) $(RSC_PROJ) $(SOURCE)
SOURCE=..\..\common\src\dmutil.cpp
"$(INTDIR)\dmutil.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
SOURCE=..\..\common\src\dxutil.cpp
"$(INTDIR)\dxutil.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) $(CPP_PROJ) $(SOURCE)
!ENDIF

View File

@@ -0,0 +1,123 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include <windows.h>
#define IDC_STATIC -1
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_MAIN DIALOG DISCARDABLE 0, 0, 262, 84
STYLE DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE |
WS_CAPTION | WS_SYSMENU
CAPTION "DirectX Sample Audio Player"
FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "Open &file...",IDC_SOUNDFILE,7,7,54,13
CONTROL "&Loop file",IDC_LOOP_CHECK,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,7,28,61,10
PUSHBUTTON "&Play",IDC_PLAY,69,26,50,14,WS_DISABLED
PUSHBUTTON "&Stop",IDC_STOP,119,26,50,14,WS_DISABLED
PUSHBUTTON "E&xit",IDCANCEL,205,26,50,14
EDITTEXT IDC_FILENAME,69,7,186,14,ES_AUTOHSCROLL | ES_READONLY
CONTROL "Slider1",IDC_TEMPO_SLIDER,"msctls_trackbar32",
WS_TABSTOP,15,60,103,12
CONTROL "Slider2",IDC_VOLUME_SLIDER,"msctls_trackbar32",
WS_TABSTOP,144,60,109,12
LTEXT "Slow",IDC_TEMPO_SLOWTXT,18,52,16,8
LTEXT "Fast",IDC_TEMPO_FASTTXT,101,52,14,8
LTEXT "Min",IDC_STATIC,148,52,12,8
LTEXT "Max",IDC_STATIC,236,52,14,8
GROUPBOX "Tempo",IDC_TEMPO_GROUPBOX,7,43,115,32
GROUPBOX "Master Volume",IDC_STATIC,139,43,116,32
LTEXT "Normal",IDC_TEMPO_NORMALTXT,56,52,23,8
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_MAIN, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 255
TOPMARGIN, 7
BOTTOMMARGIN, 75
END
END
#endif // APSTUDIO_INVOKED
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include <windows.h>\r\n"
"#define IDC_STATIC -1\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON DISCARDABLE "directx.ico"
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,135 @@
//-----------------------------------------------------------------------------
//
// Sample Name: PlayAudio Sample
//
// Copyright (c) 1999-2001 Microsoft Corporation. All rights reserved.
//
// GM/GS® Sound Set Copyright ©1996, Roland Corporation U.S.
//
//-----------------------------------------------------------------------------
Description
===========
The PlayAudio sample shows how to load a segment and play it on an
audiopath, how to use DirectMusic notifications, and how to change
global performance parameters.
Path
====
Source: DXSDK\Samples\Multimedia\DirectMusic\PlayAudio
Executable: DXSDK\Samples\Multimedia\DirectMusic\Bin
User's Guide
============
Play the default segment, or load another wave, MIDI, or DirectMusic
Producer segment file by clicking Segment File. Adjust the tempo and
volume by using the sliders
Programming Notes
=================
This and other DirectMusic samples uses the DirectMusic sample
framework, CMusicManager and CMusicSegment to help encapsulate some of
the common functionality of DirectMusic. The framework is contained
in dmutil.cpp.
This is how the sample works:
* Upon WM_INITDIALOG. See OnInitDialog()
1. Create a Win32 event, g_hDMusicMessageEvent. This will be
used by DirectMusic to signal the app whenever a DirectMusic
notification comes in.
2. Create a help class CMusicManager called g_pMusicManager.
3. Initialize the CMusicManager class. This does the following.
See CMusicManager::Initialize() in dmutil.cpp
- Creates a IDirectMusicLoader8 using CoCreateInstance
- Creates a IDirectMusicPerformance8 using CoCreateInstance
- Calls IDirectMusicPerformance8::InitAudio to init DirectMusic
using a standard audio path.
4. Call IDirectMusicPerformance8::AddNotificationType() passing in
GUID_NOTIFICATION_SEGMENT. This will make DirectMusic tell us about any
segment notifications that come in. This is needed to by this
sample to know when the segment has ended. However DirectMusic
games may not care when the segment has ended.
5. Call IDirectMusicPerformance8::SetNotificationHandle() passing
in the Win32 event, g_hDMusicMessageEvent. This tells DirectMusic
to signal this event when a notification is available.
* Setting up the app message loop. See WinMain()
1. Create the dialog using CreateDialog().
2. In a loop call MsgWaitForMultipleObjects() passing in
g_hDMusicMessageEvent. This will tell us when g_hDMusicMessageEvent
is signaled. Above we have told DirectMusic to signal this event
whenever a DirectMusic notification has come in.
3. If WAIT_OBJECT_0 is returned, then call ProcessDirectMusicMessages(),
See below for details.
4. If WAIT_OBJECT_0 + 1 is returned, then Windows msgs are available, so
do standard msg processing using PeekMessage().
* When "Open File" is clicked. See OnOpenSoundFile()
1. Get the file name from using GetOpenFileName().
2. Release the any old g_pMusicSegment.
3. Call CMusicManager::CollectGarbage(). See dmutil.cpp.
This calls IDirectMusicLoader8::CollectGarbage which
collects any garbage from any old segment that was present.
This is done because some sophisticated segments, in particular
ones that include segment trigger tracks or script tracks, may
have a cyclic reference. For example, a segment trigger that
references another segment that references the first segment, also
via a segment trigger track.
4. Call CMusicManager::SetSearchDirectory(). See dmutil.cpp
This calls IDirectMusicLoader8::SetSearchDirectory()
passing in the GUID_DirectMusicAllTypes and a directory.
This will tell DirectMusic where to look for files that
are referenced inside of segments.
5. Call CMusicManager::CreateSegmentFromFile() to create a
CMusicSegment called g_pMusicSegment from the file.
See dmutil.cpp. This does the following:
- Calls IDirectMusicLoader8::LoadObjectFromFile() to
load the IDirectMusicSegment8 into pSegment.
- Creates CMusicSegment passing in pSegment.
- If the file is a pure MIDI file then it calls
IDirectMusicSegment8::SetParam passing in
GUID_StandardMIDIFile to DirectMusic this. This makes
sure that patch changes are handled correctly.
- If requested, it calls IDirectMusicSegment8::Download()
this will download the segment's bands to the synthesizer.
Some apps may want to wait before calling this to because
the download allocates memory for the instruments. The
more instruments currently downloaded, the more memory
is in use by the synthesizer.
* When "Play" is clicked. See OnPlayAudio()
1. If the UI says the sound should be looped, then call
CMusicSegment::SetRepeats passing in DMUS_SEG_REPEAT_INFINITE,
otherwise call CMusicSegment::SetRepeats passing in 0.
2. Call CMusicSegment::Play() which calls
IDirectMusicPerformance8::PlaySegmentEx(). See dmutil.cpp.
* Upon a DirectMusic notification. See ProcessDirectMusicMessages().
This sample wants to know if the primary segment has stopped playing
so it can updated the UI so tell the user that they can play
the sound again. This is rather complex, but typically apps
will not need this functionality. Here is what has to be done:
1. Call IDirectMusicPerformance8::GetNotificationPMsg() in a loop
to process each PMsg that has occurred.
2. Switch off the pPMsg->dwNotificationOption. This sample
only handles it if its a DMUS_NOTIFICATION_SEGEND. This tells
us that segment has ended.
3. Call QueryInterface on the pPMsg->punkUser, quering for a
IDirectMusicSegmentState8.
4. Using the IDirectMusicSegmentState8, call GetSegment to
get a IDirectMusicSegment* of the segment it refers to.
This call may fail is the segment may have gone away before this
notification was handled.
5. Call QueryInterface IDirectMusicSegment to get a IDirectMusicSegment8
6. Compare this pointer to the IDirectMusicSegment8 pointer
in g_pMusicSegment, to see if this was the primary segment.
This may not always be the case since segments can have segments enbedded
inside of them, we only want handle when the primary segment has
stopped playing. If it has, then update the UI
7. Cleanup all the interfaces.

View File

@@ -0,0 +1,30 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by PlayAudio.rc
//
#define IDD_MAIN 101
#define IDR_MAINFRAME 102
#define IDR_ACCELERATOR1 131
#define IDC_TEMPO_GROUPBOX 1001
#define IDC_PLAY 1002
#define IDC_STOP 1003
#define IDC_FILENAME 1004
#define IDC_TEMPO_SLIDER 1005
#define IDC_VOLUME_SLIDER 1006
#define IDC_LOOP_CHECK 1009
#define IDC_SOUNDFILE 1011
#define IDC_TEMPO_SLOWTXT 1012
#define IDC_TEMPO_FASTTXT 1013
#define IDC_TEMPO_NORMALTXT 1014
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 104
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1015
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif