Integrate C++11 branch into 5_1-new

This commit is contained in:
teejusb
2019-06-22 12:35:38 -07:00
444 changed files with 19503 additions and 21007 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ bool ArchHooks::g_bQuitting = false;
bool ArchHooks::g_bToggleWindowed = false;
// Keep from pulling RageThreads.h into ArchHooks.h
static RageMutex g_Mutex( "ArchHooks" );
ArchHooks *HOOKS = NULL; // global and accessible from anywhere in our program
ArchHooks *HOOKS = nullptr; // global and accessible from anywhere in our program
ArchHooks::ArchHooks(): m_bHasFocus(true), m_bFocusChanged(false)
{
+17 -17
View File
@@ -81,7 +81,7 @@ void ArchHooks_MacOSX::Init()
CFBundleRef bundle = CFBundleGetMainBundle();
CFStringRef appID = CFBundleGetIdentifier( bundle );
if( appID == NULL )
if( appID == nil)
{
// We were probably launched through a symlink. Don't bother hunting down the real path.
return;
@@ -90,12 +90,12 @@ void ArchHooks_MacOSX::Init()
CFPropertyListRef old = CFPreferencesCopyAppValue( key, appID );
CFURLRef path = CFBundleCopyBundleURL( bundle );
CFPropertyListRef value = CFURLCopyFileSystemPath( path, kCFURLPOSIXPathStyle );
CFMutableDictionaryRef newDict = NULL;
CFMutableDictionaryRef newDict = nil;
if( old && CFGetTypeID(old) != CFDictionaryGetTypeID() )
{
CFRelease( old );
old = NULL;
old = nil;
}
if( !old )
@@ -152,7 +152,7 @@ void ArchHooks_MacOSX::DumpDebugInfo()
}
size_t size;
#define GET_PARAM( name, var ) (size = sizeof(var), sysctlbyname(name, &var, &size, NULL, 0) )
#define GET_PARAM( name, var ) (size = sizeof(var), sysctlbyname(name, &var, &size, nil, 0) )
// Get memory
float fRam;
char ramPower;
@@ -202,27 +202,27 @@ void ArchHooks_MacOSX::DumpDebugInfo()
break;
}
sModel = szModel;
CFURLRef urlRef = CFBundleCopyResourceURL( CFBundleGetMainBundle(), CFSTR("Hardware.plist"), NULL, NULL );
CFURLRef urlRef = CFBundleCopyResourceURL( CFBundleGetMainBundle(), CFSTR("Hardware.plist"), nil, nil);
if( urlRef == NULL )
if( urlRef == nil)
break;
CFDataRef dataRef = NULL;
CFDataRef dataRef = nil;
SInt32 error;
CFURLCreateDataAndPropertiesFromResource( NULL, urlRef, &dataRef, NULL, NULL, &error );
CFURLCreateDataAndPropertiesFromResource( nil, urlRef, &dataRef, nil, nil, &error );
CFRelease( urlRef );
if( dataRef == NULL )
if( dataRef == nil)
break;
// This also works with binary property lists for some reason.
CFPropertyListRef plRef = CFPropertyListCreateFromXMLData( NULL, dataRef, kCFPropertyListImmutable, NULL );
CFPropertyListRef plRef = CFPropertyListCreateFromXMLData( nil, dataRef, kCFPropertyListImmutable, nil);
CFRelease( dataRef );
if( plRef == NULL )
if( plRef == nil)
break;
if( CFGetTypeID(plRef) != CFDictionaryGetTypeID() )
{
CFRelease( plRef );
break;
}
CFStringRef keyRef = CFStringCreateWithCStringNoCopy( NULL, szModel, kCFStringEncodingMacRoman, kCFAllocatorNull );
CFStringRef keyRef = CFStringCreateWithCStringNoCopy( nil, szModel, kCFStringEncodingMacRoman, kCFAllocatorNull );
CFStringRef modelRef = (CFStringRef)CFDictionaryGetValue( (CFDictionaryRef)plRef, keyRef );
if( modelRef )
sModel = CFStringGetCStringPtr( modelRef, kCFStringEncodingMacRoman );
@@ -244,7 +244,7 @@ RString ArchHooks::GetPreferredLanguage()
CFTypeRef t = CFPreferencesCopyAppValue( CFSTR("AppleLanguages"), app );
RString ret = "en";
if( t == NULL )
if( t == nil)
return ret;
if( CFGetTypeID(t) != CFArrayGetTypeID() )
{
@@ -256,7 +256,7 @@ RString ArchHooks::GetPreferredLanguage()
CFStringRef lang;
if( CFArrayGetCount(languages) > 0 &&
(lang = (CFStringRef)CFArrayGetValueAtIndex(languages, 0)) != NULL )
(lang = (CFStringRef)CFArrayGetValueAtIndex(languages, 0)) != nil)
{
// MacRoman agrees with ASCII in the low-order 7 bits.
const char *str = CFStringGetCStringPtr( lang, kCFStringEncodingMacRoman );
@@ -273,8 +273,8 @@ RString ArchHooks::GetPreferredLanguage()
bool ArchHooks_MacOSX::GoToURL( RString sUrl )
{
CFURLRef url = CFURLCreateWithBytes( kCFAllocatorDefault, (const UInt8*)sUrl.data(),
sUrl.length(), kCFStringEncodingUTF8, NULL );
OSStatus result = LSOpenCFURLRef( url, NULL );
sUrl.length(), kCFStringEncodingUTF8, nil);
OSStatus result = LSOpenCFURLRef( url, nil);
CFRelease( url );
return result == 0;
@@ -310,7 +310,7 @@ static void PathForFolderType( char dir[PATH_MAX], OSType folderType )
void ArchHooks::MountInitialFilesystems( const RString &sDirOfExecutable )
{
char dir[PATH_MAX];
CFURLRef dataUrl = CFBundleCopyResourceURL( CFBundleGetMainBundle(), CFSTR("StepMania"), CFSTR("smzip"), NULL );
CFURLRef dataUrl = CFBundleCopyResourceURL( CFBundleGetMainBundle(), CFSTR("StepMania"), CFSTR("smzip"), nil);
FILEMAN->Mount( "dir", sDirOfExecutable, "/" );
+3 -3
View File
@@ -110,7 +110,7 @@ static void TestTLS()
RageThread TestThread;
TestThread.SetName( "TestTLS" );
TestThread.Create( TestTLSThread, NULL );
TestThread.Create( TestTLSThread, nullptr );
TestThread.Wait();
if( g_iTestTLS == 1 )
@@ -167,7 +167,7 @@ int64_t ArchHooks::GetMicrosecondsSinceStart( bool bAccurate )
int64_t ArchHooks::GetMicrosecondsSinceStart( bool bAccurate )
{
struct timeval tv;
gettimeofday( &tv, NULL );
gettimeofday( &tv, nullptr );
int64_t iRet = int64_t(tv.tv_sec) * 1000000 + int64_t(tv.tv_usec);
ret = FixupTimeIfBackwards( ret );
@@ -224,7 +224,7 @@ bool ArchHooks_Unix::GoToURL( RString sUrl )
else if ( p == 0 )
{
// Child
const char * const argv[] = { "xdg-open", sUrl.c_str(), NULL };
const char * const argv[] = { "xdg-open", sUrl.c_str(), nullptr };
execv( "/usr/bin/xdg-open", const_cast<char * const *>( argv ));
// If we reach here, the call to execvp failed
exit( 1 );
+12 -12
View File
@@ -42,7 +42,7 @@ ArchHooks_Win32::ArchHooks_Win32()
* the main thread. */
SetThreadPriorityBoost( GetCurrentThread(), TRUE );
g_hInstanceMutex = CreateMutex( NULL, TRUE, PRODUCT_ID );
g_hInstanceMutex = CreateMutex( nullptr, TRUE, PRODUCT_ID );
g_bIsMultipleInstance = false;
if( GetLastError() == ERROR_ALREADY_EXISTS )
@@ -90,20 +90,20 @@ bool ArchHooks_Win32::CheckForMultipleInstances(int argc, char* argv[])
/* Search for the existing window. Prefer to use the class name, which is less likely to
* have a false match, and will match the gameplay window. If that fails, try the window
* name, which should match the loading window. */
HWND hWnd = FindWindow( PRODUCT_ID, NULL );
if( hWnd == NULL )
hWnd = FindWindow( NULL, PRODUCT_ID );
HWND hWnd = FindWindow( PRODUCT_ID, nullptr );
if( hWnd == nullptr )
hWnd = FindWindow( nullptr, PRODUCT_ID );
if( hWnd != NULL )
if( hWnd != nullptr )
{
/* If the application has a model dialog box open, we want to be sure to give focus to it,
* not the main window. */
CallbackData data;
data.hParent = hWnd;
data.hResult = NULL;
data.hResult = nullptr;
EnumWindows( GetEnabledPopup, (LPARAM) &data );
if( data.hResult != NULL )
if( data.hResult != nullptr )
SetForegroundWindow( data.hResult );
else
SetForegroundWindow( hWnd );
@@ -120,7 +120,7 @@ bool ArchHooks_Win32::CheckForMultipleInstances(int argc, char* argv[])
SendMessage(
(HWND)hWnd, // HWND hWnd = handle of destination window
WM_COPYDATA,
(WPARAM)NULL, // HANDLE OF SENDING WINDOW
(WPARAM)nullptr, // HANDLE OF SENDING WINDOW
(LPARAM)&cds ); // 2nd msg parameter = pointer to COPYDATASTRUCT
}
@@ -193,7 +193,7 @@ float ArchHooks_Win32::GetDisplayAspectRatio()
DEVMODE dm;
ZERO( dm );
dm.dmSize = sizeof(dm);
BOOL bResult = EnumDisplaySettings( NULL, ENUM_REGISTRY_SETTINGS, &dm );
BOOL bResult = EnumDisplaySettings( nullptr, ENUM_REGISTRY_SETTINGS, &dm );
ASSERT( bResult != 0 );
return dm.dmPelsWidth / (float)dm.dmPelsHeight;
}
@@ -210,15 +210,15 @@ RString ArchHooks_Win32::GetClipboard()
// Yes. All this mess just to gain access to the string stored by the clipboard.
// I'm having flashbacks to Berkeley sockets.
if(unlikely( !OpenClipboard( NULL ) ))
if(unlikely( !OpenClipboard( nullptr ) ))
{ LOG->Warn(werr_ssprintf( GetLastError(), "InputHandler_DirectInput: OpenClipboard() failed" )); return ""; }
hgl = GetClipboardData( CF_TEXT );
if(unlikely( hgl == NULL ))
if(unlikely( hgl == nullptr ))
{ LOG->Warn(werr_ssprintf( GetLastError(), "InputHandler_DirectInput: GetClipboardData() failed" )); CloseClipboard(); return ""; }
lpstr = (LPTSTR) GlobalLock( hgl );
if(unlikely( lpstr == NULL ))
if(unlikely( lpstr == nullptr ))
{ LOG->Warn(werr_ssprintf( GetLastError(), "InputHandler_DirectInput: GlobalLock() failed" )); CloseClipboard(); return ""; }
// And finally, we have a char (or wchar_t) array of the clipboard contents,
+8 -8
View File
@@ -21,9 +21,9 @@ DialogDriver *MakeDialogDriver()
ASSERT( asDriversToTry.size() != 0 );
RString sDriver;
DialogDriver *pRet = NULL;
DialogDriver *pRet = nullptr;
for( unsigned i = 0; pRet == NULL && i < asDriversToTry.size(); ++i )
for( unsigned i = 0; pRet == nullptr && i < asDriversToTry.size(); ++i )
{
sDriver = asDriversToTry[i];
@@ -37,7 +37,7 @@ DialogDriver *MakeDialogDriver()
if( !asDriversToTry[i].CompareNoCase("Null") ) pRet = new DialogDriver_Null;
#endif
if( pRet == NULL )
if( pRet == nullptr )
{
continue;
}
@@ -54,7 +54,7 @@ DialogDriver *MakeDialogDriver()
return pRet;
}
static DialogDriver *g_pImpl = NULL;
static DialogDriver *g_pImpl = nullptr;
static DialogDriver_Null g_NullDriver;
static bool g_bWindowed = true; // Start out true so that we'll show errors before DISPLAY is init'd.
@@ -65,19 +65,19 @@ static bool DialogsEnabled()
void Dialog::Init()
{
if( g_pImpl != NULL )
if( g_pImpl != nullptr )
return;
g_pImpl = DialogDriver::Create();
// DialogDriver_Null should have worked, at least.
ASSERT( g_pImpl != NULL );
ASSERT( g_pImpl != nullptr );
}
void Dialog::Shutdown()
{
delete g_pImpl;
g_pImpl = NULL;
g_pImpl = nullptr;
}
static bool MessageIsIgnored( RString sID )
@@ -96,7 +96,7 @@ void Dialog::IgnoreMessage( RString sID )
{
// We can't ignore messages before PREFSMAN is around.
#if !defined(SMPACKAGE)
if( PREFSMAN == NULL )
if( PREFSMAN == nullptr )
{
if( sID != "" && LOG )
LOG->Warn( "Dialog: message \"%s\" set ID too early for ignorable messages", sID.c_str() );
+6 -6
View File
@@ -1,12 +1,12 @@
#include "global.h"
#include "DialogDriver.h"
#include "Foreach.h"
#include "RageLog.h"
map<istring, CreateDialogDriverFn> *RegisterDialogDriver::g_pRegistrees;
RegisterDialogDriver::RegisterDialogDriver( const istring &sName, CreateDialogDriverFn pfn )
{
if( g_pRegistrees == NULL )
if( g_pRegistrees == nullptr )
g_pRegistrees = new map<istring, CreateDialogDriverFn>;
ASSERT( g_pRegistrees->find(sName) == g_pRegistrees->end() );
@@ -23,9 +23,9 @@ DialogDriver *DialogDriver::Create()
ASSERT( asDriversToTry.size() != 0 );
FOREACH_CONST( RString, asDriversToTry, Driver )
for (RString const &Driver : asDriversToTry)
{
map<istring, CreateDialogDriverFn>::const_iterator iter = RegisterDialogDriver::g_pRegistrees->find( istring(*Driver) );
map<istring, CreateDialogDriverFn>::const_iterator iter = RegisterDialogDriver::g_pRegistrees->find( istring(Driver) );
if( iter == RegisterDialogDriver::g_pRegistrees->end() )
continue;
@@ -37,10 +37,10 @@ DialogDriver *DialogDriver::Create()
if( sError.empty() )
return pRet;
if( LOG )
LOG->Info( "Couldn't load driver %s: %s", Driver->c_str(), sError.c_str() );
LOG->Info( "Couldn't load driver %s: %s", Driver.c_str(), sError.c_str() );
SAFE_DELETE( pRet );
}
return NULL;
return nullptr;
}
+169 -169
View File
@@ -1,169 +1,169 @@
#include "global.h"
#include "RageUtil.h"
#include "DialogDriver_MacOSX.h"
#include "RageThreads.h"
#include "ProductInfo.h"
#include "InputFilter.h"
#include <CoreFoundation/CoreFoundation.h>
REGISTER_DIALOG_DRIVER_CLASS( MacOSX );
static CFOptionFlags ShowAlert( CFOptionFlags flags, const RString& sMessage, CFStringRef OK,
CFStringRef alt = NULL, CFStringRef other = NULL)
{
CFOptionFlags result;
CFStringRef text = CFStringCreateWithCString( NULL, sMessage, kCFStringEncodingUTF8 );
if( text == NULL )
{
RString error = ssprintf( "CFString for dialog string \"%s\" could not be created.", sMessage.c_str() );
WARN( error );
DEBUG_ASSERT_M( false, error );
return kCFUserNotificationDefaultResponse; // Is this better than displaying an "unknown error" message?
}
CFUserNotificationDisplayAlert( 0.0, flags, NULL, NULL, NULL, CFSTR(PRODUCT_FAMILY),
text, OK, alt, other, &result );
CFRelease( text );
// Flush all input that's accumulated while the dialog box was up.
if( INPUTFILTER )
{
vector<InputEvent> dummy;
INPUTFILTER->Reset();
INPUTFILTER->GetInputEvents( dummy );
}
return result;
}
#define LSTRING(b,x) CFBundleCopyLocalizedString( (b), CFSTR(x), NULL, CFSTR("Localizable") )
void DialogDriver_MacOSX::OK( RString sMessage, RString sID )
{
CFBundleRef bundle = CFBundleGetMainBundle();
CFStringRef sDSA = LSTRING( bundle, "Don't show again" );
CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, CFSTR("OK"), sDSA );
CFRelease( sDSA );
if( result == kCFUserNotificationAlternateResponse )
Dialog::IgnoreMessage( sID );
}
void DialogDriver_MacOSX::Error( RString sError, RString sID )
{
ShowAlert( kCFUserNotificationStopAlertLevel, sError, CFSTR("OK") );
}
Dialog::Result DialogDriver_MacOSX::OKCancel( RString sMessage, RString sID )
{
CFBundleRef bundle = CFBundleGetMainBundle();
CFStringRef sOK = LSTRING( bundle, "OK" );
CFStringRef sCancel = LSTRING( bundle, "Cancel" );
CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, sOK, sCancel );
CFRelease( sOK );
CFRelease( sCancel );
switch( result )
{
case kCFUserNotificationDefaultResponse:
case kCFUserNotificationCancelResponse:
return Dialog::cancel;
case kCFUserNotificationAlternateResponse:
return Dialog::ok;
default:
FAIL_M( ssprintf("Invalid response: %d.", int(result)) );
}
}
Dialog::Result DialogDriver_MacOSX::AbortRetryIgnore( RString sMessage, RString sID )
{
CFBundleRef bundle = CFBundleGetMainBundle();
CFStringRef sIgnore = LSTRING( bundle, "Ignore" );
CFStringRef sRetry = LSTRING( bundle, "Retry" );
CFStringRef sAbort = LSTRING( bundle, "Abort" );
CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, sIgnore, sRetry, sAbort );
CFRelease( sIgnore );
CFRelease( sRetry );
CFRelease( sAbort );
switch( result )
{
case kCFUserNotificationDefaultResponse:
Dialog::IgnoreMessage( sID );
return Dialog::ignore;
case kCFUserNotificationAlternateResponse:
return Dialog::retry;
case kCFUserNotificationOtherResponse:
case kCFUserNotificationCancelResponse:
return Dialog::abort;
default:
FAIL_M( ssprintf("Invalid response: %d.", int(result)) );
}
}
Dialog::Result DialogDriver_MacOSX::AbortRetry( RString sMessage, RString sID )
{
CFBundleRef bundle = CFBundleGetMainBundle();
CFStringRef sRetry = LSTRING( bundle, "Retry" );
CFStringRef sAbort = LSTRING( bundle, "Abort" );
CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, sRetry, sAbort );
CFRelease( sRetry );
CFRelease( sAbort );
switch( result )
{
case kCFUserNotificationDefaultResponse:
case kCFUserNotificationCancelResponse:
return Dialog::abort;
case kCFUserNotificationAlternateResponse:
return Dialog::retry;
default:
FAIL_M( ssprintf("Invalid response: %d.", int(result)) );
}
}
Dialog::Result DialogDriver_MacOSX::YesNo( RString sMessage, RString sID )
{
CFBundleRef bundle = CFBundleGetMainBundle();
CFStringRef sYes = LSTRING( bundle, "Yes" );
CFStringRef sNo = LSTRING( bundle, "No" );
CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, sYes, sNo );
CFRelease( sYes );
CFRelease( sNo );
switch( result )
{
case kCFUserNotificationDefaultResponse:
case kCFUserNotificationCancelResponse:
return Dialog::no;
case kCFUserNotificationAlternateResponse:
return Dialog::yes;
default:
FAIL_M( ssprintf("Invalid response: %d.", int(result)) );
}
}
/*
* (c) 2003-2006 Steve Checkoway
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "global.h"
#include "RageUtil.h"
#include "DialogDriver_MacOSX.h"
#include "RageThreads.h"
#include "ProductInfo.h"
#include "InputFilter.h"
#include <CoreFoundation/CoreFoundation.h>
REGISTER_DIALOG_DRIVER_CLASS( MacOSX );
static CFOptionFlags ShowAlert( CFOptionFlags flags, const RString& sMessage, CFStringRef OK,
CFStringRef alt = nullptr, CFStringRef other = nullptr)
{
CFOptionFlags result;
CFStringRef text = CFStringCreateWithCString( nullptr, sMessage, kCFStringEncodingUTF8 );
if( text == nullptr )
{
RString error = ssprintf( "CFString for dialog string \"%s\" could not be created.", sMessage.c_str() );
WARN( error );
DEBUG_ASSERT_M( false, error );
return kCFUserNotificationDefaultResponse; // Is this better than displaying an "unknown error" message?
}
CFUserNotificationDisplayAlert( 0.0, flags, nullptr, nullptr, nullptr, CFSTR(PRODUCT_FAMILY),
text, OK, alt, other, &result );
CFRelease( text );
// Flush all input that's accumulated while the dialog box was up.
if( INPUTFILTER )
{
vector<InputEvent> dummy;
INPUTFILTER->Reset();
INPUTFILTER->GetInputEvents( dummy );
}
return result;
}
#define LSTRING(b,x) CFBundleCopyLocalizedString( (b), CFSTR(x), nullptr, CFSTR("Localizable") )
void DialogDriver_MacOSX::OK( RString sMessage, RString sID )
{
CFBundleRef bundle = CFBundleGetMainBundle();
CFStringRef sDSA = LSTRING( bundle, "Don't show again" );
CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, CFSTR("OK"), sDSA );
CFRelease( sDSA );
if( result == kCFUserNotificationAlternateResponse )
Dialog::IgnoreMessage( sID );
}
void DialogDriver_MacOSX::Error( RString sError, RString sID )
{
ShowAlert( kCFUserNotificationStopAlertLevel, sError, CFSTR("OK") );
}
Dialog::Result DialogDriver_MacOSX::OKCancel( RString sMessage, RString sID )
{
CFBundleRef bundle = CFBundleGetMainBundle();
CFStringRef sOK = LSTRING( bundle, "OK" );
CFStringRef sCancel = LSTRING( bundle, "Cancel" );
CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, sOK, sCancel );
CFRelease( sOK );
CFRelease( sCancel );
switch( result )
{
case kCFUserNotificationDefaultResponse:
case kCFUserNotificationCancelResponse:
return Dialog::cancel;
case kCFUserNotificationAlternateResponse:
return Dialog::ok;
default:
FAIL_M( ssprintf("Invalid response: %d.", int(result)) );
}
}
Dialog::Result DialogDriver_MacOSX::AbortRetryIgnore( RString sMessage, RString sID )
{
CFBundleRef bundle = CFBundleGetMainBundle();
CFStringRef sIgnore = LSTRING( bundle, "Ignore" );
CFStringRef sRetry = LSTRING( bundle, "Retry" );
CFStringRef sAbort = LSTRING( bundle, "Abort" );
CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, sIgnore, sRetry, sAbort );
CFRelease( sIgnore );
CFRelease( sRetry );
CFRelease( sAbort );
switch( result )
{
case kCFUserNotificationDefaultResponse:
Dialog::IgnoreMessage( sID );
return Dialog::ignore;
case kCFUserNotificationAlternateResponse:
return Dialog::retry;
case kCFUserNotificationOtherResponse:
case kCFUserNotificationCancelResponse:
return Dialog::abort;
default:
FAIL_M( ssprintf("Invalid response: %d.", int(result)) );
}
}
Dialog::Result DialogDriver_MacOSX::AbortRetry( RString sMessage, RString sID )
{
CFBundleRef bundle = CFBundleGetMainBundle();
CFStringRef sRetry = LSTRING( bundle, "Retry" );
CFStringRef sAbort = LSTRING( bundle, "Abort" );
CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, sRetry, sAbort );
CFRelease( sRetry );
CFRelease( sAbort );
switch( result )
{
case kCFUserNotificationDefaultResponse:
case kCFUserNotificationCancelResponse:
return Dialog::abort;
case kCFUserNotificationAlternateResponse:
return Dialog::retry;
default:
FAIL_M( ssprintf("Invalid response: %d.", int(result)) );
}
}
Dialog::Result DialogDriver_MacOSX::YesNo( RString sMessage, RString sID )
{
CFBundleRef bundle = CFBundleGetMainBundle();
CFStringRef sYes = LSTRING( bundle, "Yes" );
CFStringRef sNo = LSTRING( bundle, "No" );
CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, sYes, sNo );
CFRelease( sYes );
CFRelease( sNo );
switch( result )
{
case kCFUserNotificationDefaultResponse:
case kCFUserNotificationCancelResponse:
return Dialog::no;
case kCFUserNotificationAlternateResponse:
return Dialog::yes;
default:
FAIL_M( ssprintf("Invalid response: %d.", int(result)) );
}
}
/*
* (c) 2003-2006 Steve Checkoway
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
+8 -8
View File
@@ -120,7 +120,7 @@ Dialog::Result DialogDriver_Win32::OKCancel( RString sMessage, RString sID )
#if !defined(SMPACKAGE)
//DialogBox( handle.Get(), MAKEINTRESOURCE(IDD_OK), ::GetHwnd(), OKWndProc );
int result = ::MessageBox( NULL, sMessage, GetWindowTitle(), MB_OKCANCEL );
int result = ::MessageBox( nullptr, sMessage, GetWindowTitle(), MB_OKCANCEL );
#else
int result = ::AfxMessageBox( ConvertUTF8ToACP(sMessage).c_str(), MB_OKCANCEL, 0 );
#endif
@@ -165,14 +165,14 @@ static BOOL CALLBACK ErrorWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
RString sAppDataDir = SpecialDirs::GetAppDataDir();
RString sCommand = "notepad \"" + sAppDataDir + PRODUCT_ID + "/Logs/log.txt\"";
CreateProcess(
NULL, // pointer to name of executable module
nullptr, // pointer to name of executable module
const_cast<char *>(sCommand.c_str()), // pointer to command line string
NULL, // process security attributes
NULL, // thread security attributes
nullptr, // process security attributes
nullptr, // thread security attributes
false, // handle inheritance flag
0, // creation flags
NULL, // pointer to new environment block
NULL, // pointer to current directory name
nullptr, // pointer to new environment block
nullptr, // pointer to current directory name
&si, // pointer to STARTUPINFO
&pi // pointer to PROCESS_INFORMATION
);
@@ -194,7 +194,7 @@ static BOOL CALLBACK ErrorWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
{
HDC hdc = (HDC)wParam;
HWND hwndStatic = (HWND)lParam;
HBRUSH hbr = NULL;
HBRUSH hbr = nullptr;
// TODO: Change any attributes of the DC here
switch( GetDlgCtrlID(hwndStatic) )
@@ -222,7 +222,7 @@ void DialogDriver_Win32::Error( RString sError, RString sID )
// throw up a pretty error dialog
AppInstance handle;
DialogBox( handle.Get(), MAKEINTRESOURCE(IDD_ERROR_DIALOG), NULL, ErrorWndProc );
DialogBox( handle.Get(), MAKEINTRESOURCE(IDD_ERROR_DIALOG), nullptr, ErrorWndProc );
#else
::AfxMessageBox( ConvertUTF8ToACP(sError).c_str(), MB_OK, 0 );
#endif
+5 -5
View File
@@ -6,7 +6,7 @@
#include "LocalizedString.h"
#include "arch/arch_default.h"
#include "InputHandler_MonkeyKeyboard.h"
#include "Foreach.h"
void InputHandler::UpdateTimer()
{
@@ -176,12 +176,12 @@ void InputHandler::Create( const RString &drivers_, vector<InputHandler *> &Add
if( DriversToTry.empty() )
RageException::Throw( "%s", INPUT_HANDLERS_EMPTY.GetValue().c_str() );
FOREACH_CONST( RString, DriversToTry, s )
for (RString const &s : DriversToTry)
{
RageDriver *pDriver = InputHandler::m_pDriverList.Create( *s );
if( pDriver == NULL )
RageDriver *pDriver = InputHandler::m_pDriverList.Create( s );
if( pDriver == nullptr )
{
LOG->Trace( "Unknown Input Handler name: %s", s->c_str() );
LOG->Trace( "Unknown Input Handler name: %s", s.c_str() );
continue;
}
@@ -11,7 +11,6 @@
#include "InputFilter.h"
#include "PrefsManager.h"
#include "GamePreferences.h" //needed for Axis Fix
#include "Foreach.h"
#include "InputHandler_DirectInputHelper.h"
@@ -32,13 +31,13 @@ static int g_iNumJoysticks;
#define SAFE_RELEASE(p) { if ( (p) ) { (p)->Release(); (p) = 0; } }
static BOOL IsXInputDevice(const GUID* pGuidProductFromDirectInput)
{
IWbemLocator* pIWbemLocator = NULL;
IEnumWbemClassObject* pEnumDevices = NULL;
IWbemLocator* pIWbemLocator = nullptr;
IEnumWbemClassObject* pEnumDevices = nullptr;
IWbemClassObject* pDevices[20] = { 0 };
IWbemServices* pIWbemServices = NULL;
BSTR bstrNamespace = NULL;
BSTR bstrDeviceID = NULL;
BSTR bstrClassName = NULL;
IWbemServices* pIWbemServices = nullptr;
BSTR bstrNamespace = nullptr;
BSTR bstrDeviceID = nullptr;
BSTR bstrClassName = nullptr;
DWORD uReturned = 0;
bool bIsXinputDevice = false;
UINT iDevice = 0;
@@ -46,34 +45,34 @@ static BOOL IsXInputDevice(const GUID* pGuidProductFromDirectInput)
HRESULT hr;
// CoInit if needed
hr = CoInitialize(NULL);
hr = CoInitialize(nullptr);
bool bCleanupCOM = SUCCEEDED(hr);
// Create WMI
hr = CoCreateInstance(__uuidof(WbemLocator),
NULL,
nullptr,
CLSCTX_INPROC_SERVER,
__uuidof(IWbemLocator),
(LPVOID*)&pIWbemLocator);
if (FAILED(hr) || pIWbemLocator == NULL)
if (FAILED(hr) || pIWbemLocator == nullptr)
goto LCleanup;
bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); if (bstrNamespace == NULL) goto LCleanup;
bstrClassName = SysAllocString(L"Win32_PNPEntity"); if (bstrClassName == NULL) goto LCleanup;
bstrDeviceID = SysAllocString(L"DeviceID"); if (bstrDeviceID == NULL) goto LCleanup;
bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); if (bstrNamespace == nullptr) goto LCleanup;
bstrClassName = SysAllocString(L"Win32_PNPEntity"); if (bstrClassName == nullptr) goto LCleanup;
bstrDeviceID = SysAllocString(L"DeviceID"); if (bstrDeviceID == nullptr) goto LCleanup;
// Connect to WMI
hr = pIWbemLocator->ConnectServer(bstrNamespace, NULL, NULL, 0L,
0L, NULL, NULL, &pIWbemServices);
if (FAILED(hr) || pIWbemServices == NULL)
hr = pIWbemLocator->ConnectServer(bstrNamespace, nullptr, nullptr, 0L,
0L, nullptr, nullptr, &pIWbemServices);
if (FAILED(hr) || pIWbemServices == nullptr)
goto LCleanup;
// Switch security level to IMPERSONATE.
CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr,
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE);
hr = pIWbemServices->CreateInstanceEnum(bstrClassName, 0, NULL, &pEnumDevices);
if (FAILED(hr) || pEnumDevices == NULL)
hr = pIWbemServices->CreateInstanceEnum(bstrClassName, 0, nullptr, &pEnumDevices);
if (FAILED(hr) || pEnumDevices == nullptr)
goto LCleanup;
// Loop over all devices
@@ -89,8 +88,8 @@ static BOOL IsXInputDevice(const GUID* pGuidProductFromDirectInput)
for (iDevice = 0; iDevice<uReturned; iDevice++)
{
// For each device, get its device ID
hr = pDevices[iDevice]->Get(bstrDeviceID, 0L, &var, NULL, NULL);
if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != NULL)
hr = pDevices[iDevice]->Get(bstrDeviceID, 0L, &var, nullptr, nullptr);
if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != nullptr)
{
// Check if the device ID contains "IG_". If it does, then it's an XInput device
// This information can not be found from DirectInput
@@ -257,23 +256,23 @@ InputHandler_DInput::InputHandler_DInput()
LOG->Info( "Found %u XInput devices.", XDevices.size() );
AppInstance inst;
HRESULT hr = DirectInput8Create(inst.Get(), DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID *) &g_dinput, NULL);
HRESULT hr = DirectInput8Create(inst.Get(), DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID *) &g_dinput, nullptr);
if( hr != DI_OK )
RageException::Throw( hr_ssprintf(hr, "InputHandler_DInput: DirectInputCreate") );
LOG->Trace( "InputHandler_DInput: IDirectInput::EnumDevices(DIDEVTYPE_KEYBOARD)" );
hr = g_dinput->EnumDevices( DI8DEVCLASS_KEYBOARD, EnumDevicesCallback, NULL, DIEDFL_ATTACHEDONLY );
hr = g_dinput->EnumDevices( DI8DEVCLASS_KEYBOARD, EnumDevicesCallback, nullptr, DIEDFL_ATTACHEDONLY );
if( hr != DI_OK )
RageException::Throw( hr_ssprintf(hr, "InputHandler_DInput: IDirectInput::EnumDevices") );
LOG->Trace( "InputHandler_DInput: IDirectInput::EnumDevices(DIDEVTYPE_JOYSTICK)" );
hr = g_dinput->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumDevicesCallback, NULL, DIEDFL_ATTACHEDONLY );
hr = g_dinput->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumDevicesCallback, nullptr, DIEDFL_ATTACHEDONLY );
if( hr != DI_OK )
RageException::Throw( hr_ssprintf(hr, "InputHandler_DInput: IDirectInput::EnumDevices") );
// mouse
LOG->Trace( "InputHandler_DInput: IDirectInput::EnumDevices(DIDEVTYPE_MOUSE)" );
hr = g_dinput->EnumDevices( DI8DEVCLASS_POINTER, EnumDevicesCallback, NULL, DIEDFL_ATTACHEDONLY );
hr = g_dinput->EnumDevices( DI8DEVCLASS_POINTER, EnumDevicesCallback, nullptr, DIEDFL_ATTACHEDONLY );
if( hr != DI_OK )
RageException::Throw( hr_ssprintf(hr, "InputHandler_DInput: IDirectInput::EnumDevices") );
@@ -339,7 +338,7 @@ InputHandler_DInput::~InputHandler_DInput()
Devices.clear();
g_dinput->Release();
g_dinput = NULL;
g_dinput = nullptr;
}
void InputHandler_DInput::WindowReset()
@@ -936,7 +935,7 @@ void InputHandler_DInput::InputThreadMain()
SetThreadPriorityBoost( GetCurrentThread(), FALSE );
vector<DIDevice*> BufferedDevices;
HANDLE Handle = CreateEvent( NULL, FALSE, FALSE, NULL );
HANDLE Handle = CreateEvent( nullptr, FALSE, FALSE, nullptr );
for( unsigned i = 0; i < Devices.size(); ++i )
{
if( !Devices[i].buffered )
@@ -987,7 +986,7 @@ void InputHandler_DInput::InputThreadMain()
continue;
Devices[i].Device->Unacquire();
Devices[i].Device->SetEventNotification( NULL );
Devices[i].Device->SetEventNotification(nullptr);
}
CloseHandle(Handle);
@@ -1022,7 +1021,7 @@ static wchar_t ScancodeAndKeysToChar( DWORD scancode, unsigned char keys[256] )
unsigned short result[2]; // ToAscii writes a max of 2 chars
ZERO( result );
if( pToUnicodeEx != NULL )
if( pToUnicodeEx != nullptr )
{
int iNum = pToUnicodeEx( vk, scancode, keys, (LPWSTR)result, 2, 0, layout );
if( iNum == 1 )
@@ -1054,14 +1053,14 @@ wchar_t InputHandler_DInput::DeviceButtonToChar( DeviceButton button, bool bUseC
return '\0';
}
FOREACH_CONST( DIDevice, Devices, d )
for (DIDevice const &d : Devices)
{
if( d->type != DIDevice::KEYBOARD )
if( d.type != DIDevice::KEYBOARD )
continue;
FOREACH_CONST( input_t, d->Inputs, i )
for (input_t const &i : d.Inputs)
{
if( button != i->num )
if( button != i.num )
continue;
unsigned char keys[256];
@@ -1069,7 +1068,7 @@ wchar_t InputHandler_DInput::DeviceButtonToChar( DeviceButton button, bool bUseC
if( bUseCurrentKeyModifiers )
GetKeyboardState(keys);
// todo: handle Caps Lock -freem
wchar_t c = ScancodeAndKeysToChar( i->ofs, keys );
wchar_t c = ScancodeAndKeysToChar( i.ofs, keys );
if( c )
return c;
}
@@ -12,7 +12,7 @@
#pragma comment(lib, "dxguid.lib")
#endif
#endif
LPDIRECTINPUT8 g_dinput = NULL;
LPDIRECTINPUT8 g_dinput = nullptr;
static int ConvertScancodeToKey( int scancode );
static BOOL CALLBACK DIJoystick_EnumDevObjectsProc(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID data);
@@ -24,7 +24,7 @@ DIDevice::DIDevice()
dev = InputDevice_Invalid;
buffered = true;
memset(&JoystickInst, 0, sizeof(JoystickInst));
Device = NULL;
Device = nullptr;
}
bool DIDevice::Open()
@@ -37,7 +37,7 @@ bool DIDevice::Open()
LPDIRECTINPUTDEVICE8 tmpdevice;
// load joystick
HRESULT hr = g_dinput->CreateDevice( JoystickInst.guidInstance, &tmpdevice, NULL );
HRESULT hr = g_dinput->CreateDevice( JoystickInst.guidInstance, &tmpdevice, nullptr );
if ( hr != DI_OK )
{
LOG->Info( hr_ssprintf(hr, "OpenDevice: IDirectInput_CreateDevice") );
@@ -131,12 +131,12 @@ bool DIDevice::Open()
void DIDevice::Close()
{
// Don't try to close a device that isn't open.
ASSERT( Device != NULL );
ASSERT( Device != nullptr );
Device->Unacquire();
Device->Release();
Device = NULL;
Device = nullptr;
buttons = axes = hats = 0;
Inputs.clear();
}
@@ -275,7 +275,7 @@ InputHandler_Linux_Event::InputHandler_Linux_Event()
, m_bDevicesChanged(false)
, m_NextDevice(DEVICE_JOY10)
{
if(LINUXINPUT == NULL) LINUXINPUT = new LinuxInputManager;
if(LINUXINPUT == nullptr) LINUXINPUT = new LinuxInputManager;
LINUXINPUT->InitDriver(this);
if( ! g_apEventDevices.empty() ) // LinuxInputManager found at least one valid device for us
@@ -362,7 +362,7 @@ void InputHandler_Linux_Event::InputThread()
break;
struct timeval zero = {0,100000};
if( select(iMaxFD+1, &fdset, NULL, NULL, &zero) <= 0 )
if( select(iMaxFD+1, &fdset, nullptr, nullptr, &zero) <= 0 )
continue;
RageTimer now;
@@ -31,7 +31,7 @@ InputHandler_Linux_Joystick::InputHandler_Linux_Joystick()
m_iLastFd = 0;
if( LINUXINPUT == NULL ) LINUXINPUT = new LinuxInputManager;
if( LINUXINPUT == nullptr ) LINUXINPUT = new LinuxInputManager;
LINUXINPUT->InitDriver(this);
if( fds[0] != -1 ) // LinuxInputManager found at least one valid joystick for us
@@ -126,7 +126,7 @@ void InputHandler_Linux_Joystick::InputThread()
break;
struct timeval zero = {0,100000};
if( select(max_fd+1, &fdset, NULL, NULL, &zero) <= 0 )
if( select(max_fd+1, &fdset, nullptr, nullptr, &zero) <= 0 )
continue;
RageTimer now;
@@ -33,14 +33,14 @@ static int saved_kbd_mode;
/* This is normally a singleton. Keep track of it, so we can access it
* from our signal handler. */
static InputHandler_Linux_tty *handler = NULL;
static InputHandler_Linux_tty *handler = nullptr;
void InputHandler_Linux_tty::OnCrash(int signo)
{
/* Make sure we delete the input handler if we crash, so we don't leave
* the terminal in raw mode. */
delete handler;
handler = NULL;
handler = nullptr;
}
@@ -161,7 +161,7 @@ InputHandler_Linux_tty::~InputHandler_Linux_tty()
tcsetattr(fd, TCSAFLUSH, &saved_kbd_termios);
close(fd);
handler = NULL;
handler = nullptr;
}
void InputHandler_Linux_tty::Update()
@@ -173,7 +173,7 @@ void InputHandler_Linux_tty::Update()
FD_SET(fd, &fdset);
struct timeval zero = {0,0};
if ( select(fd+1, &fdset, NULL, NULL, &zero) <= 0 )
if ( select(fd+1, &fdset, nullptr, nullptr, &zero) <= 0 )
return;
unsigned char keybuf[BUFSIZ];
@@ -1,7 +1,6 @@
#include "global.h"
#include "RageLog.h"
#include "InputHandler_MacOSX_HID.h"
#include "Foreach.h"
#include "PrefsManager.h"
#include "InputFilter.h"
#include "archutils/Darwin/DarwinThreadHelpers.h"
@@ -30,7 +29,7 @@ void InputHandler_MacOSX_HID::QueueCallback( void *target, int result, void *ref
while( (result = CALL(queue, getNextEvent, &event, zeroTime, 0)) == kIOReturnSuccess )
{
if( event.longValueSize != 0 && event.longValue != NULL )
if( event.longValueSize != 0 && event.longValue != nullptr )
{
free( event.longValue );
continue;
@@ -38,8 +37,8 @@ void InputHandler_MacOSX_HID::QueueCallback( void *target, int result, void *ref
//LOG->Trace( "Got event with cookie %p, value %d", event.elementCookie, int(event.value) );
dev->GetButtonPresses( vPresses, event.elementCookie, event.value, now );
}
FOREACH_CONST( DeviceInput, vPresses, i )
INPUTFILTER->ButtonPressed( *i );
for (DeviceInput &i : vPresses)
INPUTFILTER->ButtonPressed( i );
}
static void RunLoopStarted( CFRunLoopObserverRef o, CFRunLoopActivity a, void *sem )
@@ -66,7 +65,7 @@ int InputHandler_MacOSX_HID::Run( void *data )
{
/* The function copies the information out of the structure, so the memory
* pointed to by context does not need to persist beyond the function call. */
CFRunLoopObserverContext context = { 0, &This->m_Sem, NULL, NULL, NULL };
CFRunLoopObserverContext context = { 0, &This->m_Sem, nullptr, nullptr, nullptr };
CFRunLoopObserverRef o = CFRunLoopObserverCreate( kCFAllocatorDefault, kCFRunLoopEntry,
false, 0, RunLoopStarted, &context);
CFRunLoopAddObserver( This->m_LoopRef, o, kCFRunLoopDefaultMode );
@@ -83,7 +82,7 @@ int InputHandler_MacOSX_HID::Run( void *data )
void *info = This->m_LoopRef;
void (*perform)(void *) = (void (*)(void *))CFRunLoopStop;
// { version, info, retain, release, copyDescription, equal, hash, schedule, cancel, perform }
CFRunLoopSourceContext context = { 0, info, NULL, NULL, NULL, NULL, NULL, NULL, NULL, perform };
CFRunLoopSourceContext context = { 0, info, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, perform };
// Pass 1 so that it is called after all inputs have been handled (they will have order = 0)
This->m_SourceRef = CFRunLoopSourceCreate( kCFAllocatorDefault, 1, &context );
@@ -120,8 +119,8 @@ void InputHandler_MacOSX_HID::StartDevices()
int n = 0;
ASSERT( m_LoopRef );
FOREACH( HIDDevice *, m_vDevices, i )
(*i)->StartQueue( m_LoopRef, InputHandler_MacOSX_HID::QueueCallback, this, n++ );
for (HIDDevice *i : m_vDevices)
i->StartQueue( m_LoopRef, InputHandler_MacOSX_HID::QueueCallback, this, n++ );
CFRunLoopSourceRef runLoopSource = IONotificationPortGetRunLoopSource( m_NotifyPort );
@@ -130,8 +129,8 @@ void InputHandler_MacOSX_HID::StartDevices()
InputHandler_MacOSX_HID::~InputHandler_MacOSX_HID()
{
FOREACH( HIDDevice *, m_vDevices, i )
delete *i;
for (HIDDevice *i : m_vDevices)
delete i;
if( PREFSMAN->m_bThreadedInput )
{
CFRunLoopSourceSignal( m_SourceRef );
@@ -142,8 +141,8 @@ InputHandler_MacOSX_HID::~InputHandler_MacOSX_HID()
LOG->Trace( "Input handler thread shut down." );
}
FOREACH( io_iterator_t, m_vIters, i )
IOObjectRelease( *i );
for (io_iterator_t &i : m_vIters)
IOObjectRelease( i );
IONotificationPortDestroy( m_NotifyPort );
}
@@ -152,7 +151,7 @@ static CFDictionaryRef GetMatchingDictionary( int usagePage, int usage )
// Build the matching dictionary.
CFMutableDictionaryRef dict;
if( (dict = IOServiceMatching(kIOHIDDeviceKey)) == NULL )
if( (dict = IOServiceMatching(kIOHIDDeviceKey)) == nullptr )
FAIL_M( "Couldn't create a matching dictionary." );
// Refine the search by only looking for joysticks
CFNumberRef usagePageRef = CFInt( usagePage );
@@ -181,7 +180,7 @@ static HIDDevice *MakeDevice( InputDevice id )
return new JoystickDevice;
if( IsPump(id) )
return new PumpDevice;
return NULL;
return nullptr;
}
void InputHandler_MacOSX_HID::AddDevices( int usagePage, int usage, InputDevice &id )
@@ -277,8 +276,8 @@ InputHandler_MacOSX_HID::InputHandler_MacOSX_HID() : m_Sem( "Input thread starte
void InputHandler_MacOSX_HID::GetDevicesAndDescriptions( vector<InputDeviceInfo>& vDevices )
{
FOREACH_CONST( HIDDevice *, m_vDevices, i )
(*i)->GetDevicesAndDescriptions( vDevices );
for (HIDDevice *i : m_vDevices)
i->GetDevicesAndDescriptions( vDevices );
}
RString InputHandler_MacOSX_HID::GetDeviceSpecificInputString( const DeviceInput &di )
@@ -380,7 +379,7 @@ static wchar_t KeyCodeToChar(CGKeyCode keyCode, unsigned int modifierFlags)
{
TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
CFDataRef uchr = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
const UCKeyboardLayout *keyboardLayout = uchr ? (const UCKeyboardLayout*)CFDataGetBytePtr(uchr) : NULL;
const UCKeyboardLayout *keyboardLayout = uchr ? (const UCKeyboardLayout*)CFDataGetBytePtr(uchr) : nullptr;
if( keyboardLayout )
{
@@ -450,7 +449,7 @@ wchar_t InputHandler_MacOSX_HID::DeviceButtonToChar( DeviceButton button, bool b
UInt8 iMacVirtualKey;
if( KeyboardDevice::DeviceButtonToMacVirtualKey( button, iMacVirtualKey ) )
{
CGEventRef event = CGEventCreate(NULL);
CGEventRef event = CGEventCreate(nullptr);
CGEventFlags mods = CGEventGetFlags(event);
CFRelease(event);
UInt32 nModifiers = bUseCurrentKeyModifiers ? (UInt32)mods : 0;
@@ -96,7 +96,7 @@ class InputHandler_SextetStream::Impl
// Construct and return the LineReader that makes sense for this
// object. getLineReader() calls this; if the returned object claims
// it is valid, it is returned. Otherwise, it is destroyed and NULL
// it is valid, it is returned. Otherwise, it is destroyed and nullptr
// is returned.
virtual LineReader * getUnvalidatedLineReader() = 0;
@@ -115,10 +115,10 @@ class InputHandler_SextetStream::Impl
LineReader * getLineReader()
{
LineReader * linereader = getUnvalidatedLineReader();
if(linereader != NULL) {
if(linereader != nullptr) {
if(!linereader->IsValid()) {
delete linereader;
linereader = NULL;
linereader = nullptr;
}
}
return linereader;
@@ -230,7 +230,7 @@ class InputHandler_SextetStream::Impl
LOG->Trace("Input thread started; getting line reader");
linereader = getLineReader();
if(linereader == NULL) {
if(linereader == nullptr) {
LOG->Warn("Could not open line reader for SextetStream input");
}
else {
@@ -259,19 +259,19 @@ class InputHandler_SextetStream::Impl
void InputHandler_SextetStream::GetDevicesAndDescriptions(vector<InputDeviceInfo>& vDevicesOut)
{
if(_impl != NULL) {
if(_impl != nullptr) {
_impl->GetDevicesAndDescriptions(vDevicesOut);
}
}
InputHandler_SextetStream::InputHandler_SextetStream()
{
_impl = NULL;
_impl = nullptr;
}
InputHandler_SextetStream::~InputHandler_SextetStream()
{
if(_impl != NULL) {
if(_impl != nullptr) {
delete _impl;
}
}
@@ -312,27 +312,27 @@ namespace
filename.c_str());
file = std::fopen(filename.c_str(), "rb");
if(file == NULL) {
if(file == nullptr) {
LOG->Warn("Error opening file '%s' for input (cstdio): %s", filename.c_str(),
std::strerror(errno));
}
else {
LOG->Info("File opened");
// Disable buffering on the file
std::setbuf(file, NULL);
std::setbuf(file, nullptr);
}
}
~StdCFileLineReader()
{
if(file != NULL) {
if(file != nullptr) {
std::fclose(file);
}
}
virtual bool IsValid()
{
return file != NULL;
return file != nullptr;
}
virtual bool ReadLine(RString& line)
@@ -342,8 +342,8 @@ namespace
line = "";
if(file != NULL) {
while(fgets(buffer, BUFFER_SIZE, file) != NULL) {
if(file != nullptr) {
while(fgets(buffer, BUFFER_SIZE, file) != nullptr) {
afterFirst = true;
line += buffer;
len = line.length();
@@ -24,7 +24,7 @@ InputHandler_Win32_MIDI::InputHandler_Win32_MIDI()
{
int device_id = 0;
g_device = NULL;
g_device = nullptr;
if( device_id >= (int) midiInGetNumDevs() )
{
@@ -29,7 +29,7 @@ InputHandler_Win32_Pump::InputHandler_Win32_Pump()
const int pump_usb_pid = pump_usb_pids[p];
for( int i = 0; i < NUM_PUMPS; ++i )
{
if( m_pDevice[i].Open(pump_usb_vid, pump_usb_pid, sizeof(long), i, NULL) )
if( m_pDevice[i].Open(pump_usb_vid, pump_usb_pid, sizeof(long), i, nullptr) )
{
iNumFound++;
LOG->Info( "Found Pump pad %i", iNumFound );
+3 -3
View File
@@ -135,7 +135,7 @@ static DeviceButton XSymToDeviceButton( int key )
InputHandler_X11::InputHandler_X11()
{
if( Dpy == NULL || Win == None )
if( Dpy == nullptr || Win == None )
return;
XWindowAttributes winAttrib;
@@ -151,7 +151,7 @@ InputHandler_X11::InputHandler_X11()
InputHandler_X11::~InputHandler_X11()
{
if( Dpy == NULL || Win == None )
if( Dpy == nullptr || Win == None )
return;
// TODO: Determine if we even need to set this back (or is the window
// destroyed just after this?)
@@ -166,7 +166,7 @@ InputHandler_X11::~InputHandler_X11()
void InputHandler_X11::Update()
{
if( Dpy == NULL || Win == None )
if( Dpy == nullptr || Win == None )
{
InputHandler::UpdateTimer();
return;
+15 -16
View File
@@ -5,7 +5,6 @@
#include "RageInput.h" // g_sInputDrivers
#include "RageLog.h"
#include "Foreach.h"
#include <string> // std::string::npos
@@ -19,11 +18,11 @@ RString getDevice(RString inputDir, RString type)
{
RString result = "";
DIR* dir = opendir( inputDir.c_str() );
if(dir == NULL)
if(dir == nullptr)
{ LOG->Warn("LinuxInputManager: Couldn't open %s: %s.", inputDir.c_str(), strerror(errno) ); return ""; }
struct dirent* d;
while( ( d = readdir(dir) ) != NULL)
while( ( d = readdir(dir) ) != nullptr)
if( strncmp( type.c_str(), d->d_name, type.size() ) == 0)
{
result = RString("/dev/input/") + d->d_name;
@@ -42,12 +41,12 @@ LinuxInputManager::LinuxInputManager()
if( g_sInputDrivers.Get() == "" )
{ m_bEventEnabled = true; m_bJoystickEnabled = true; }
m_EventDriver = NULL;
m_JoystickDriver = NULL;
m_EventDriver = nullptr;
m_JoystickDriver = nullptr;
// XXX: Can I use RageFile for this?
DIR* sysClassInput = opendir("/sys/class/input");
if( sysClassInput == NULL )
if( sysClassInput == nullptr)
{
// XXX: Probably should throw a Dialog. But Linux doesn't have a DialogDriver yet so eh.
LOG->Warn("Couldn't open /sys/class/input: %s. Joysticks will not work!", strerror(errno) );
@@ -55,7 +54,7 @@ LinuxInputManager::LinuxInputManager()
}
struct dirent* d;
while( ( d = readdir(sysClassInput) ) != NULL)
while( ( d = readdir(sysClassInput) ) != nullptr)
{
if( strncmp( "input", d->d_name, 5) != 0) continue;
@@ -78,15 +77,15 @@ void LinuxInputManager::InitDriver(InputHandler_Linux_Event* driver)
{
m_EventDriver = driver;
FOREACH(RString, m_vsPendingEventDevices, dev)
for (RString &dev : m_vsPendingEventDevices)
{
RString devFile = getDevice(*dev, "event");
RString devFile = getDevice(dev, "event");
ASSERT( devFile != "" );
if( ! driver->TryDevice(devFile) && m_bJoystickEnabled && getDevice(*dev, "js") != "" )
m_vsPendingJoystickDevices.push_back(*dev);
if( ! driver->TryDevice(devFile) && m_bJoystickEnabled && getDevice(dev, "js") != "" )
m_vsPendingJoystickDevices.push_back(dev);
}
if( m_JoystickDriver != NULL ) InitDriver(m_JoystickDriver);
if( m_JoystickDriver != nullptr ) InitDriver(m_JoystickDriver);
m_vsPendingEventDevices.clear();
}
@@ -95,9 +94,9 @@ void LinuxInputManager::InitDriver(InputHandler_Linux_Joystick* driver)
{
m_JoystickDriver = driver;
FOREACH(RString, m_vsPendingJoystickDevices, dev)
for (RString &dev : m_vsPendingJoystickDevices)
{
RString devFile = getDevice(*dev, "js");
RString devFile = getDevice(dev, "js");
ASSERT( devFile != "" );
driver->TryDevice(devFile);
@@ -106,7 +105,7 @@ void LinuxInputManager::InitDriver(InputHandler_Linux_Joystick* driver)
m_vsPendingJoystickDevices.clear();
}
LinuxInputManager* LINUXINPUT = NULL; // global and accessible anywhere in our program
LinuxInputManager* LINUXINPUT = nullptr; // global and accessible anywhere in our program
/*
* (c) 2013 Ben "root" Anderson
@@ -131,4 +130,4 @@ LinuxInputManager* LINUXINPUT = NULL; // global and accessible anywhere in our p
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
*/
+7 -7
View File
@@ -1,7 +1,7 @@
#include "global.h"
#include "LightsDriver.h"
#include "RageLog.h"
#include "Foreach.h"
#include "arch/arch_default.h"
DriverList LightsDriver::m_pDriverList;
@@ -13,19 +13,19 @@ void LightsDriver::Create( const RString &sDrivers, vector<LightsDriver *> &Add
vector<RString> asDriversToTry;
split( sDrivers, ",", asDriversToTry, true );
FOREACH_CONST( RString, asDriversToTry, Driver )
for (RString const &Driver : asDriversToTry)
{
RageDriver *pRet = m_pDriverList.Create( *Driver );
if( pRet == NULL )
RageDriver *pRet = m_pDriverList.Create( Driver );
if( pRet == nullptr )
{
LOG->Trace( "Unknown lights driver: %s", Driver->c_str() );
LOG->Trace( "Unknown lights driver: %s", Driver.c_str() );
continue;
}
LightsDriver *pDriver = dynamic_cast<LightsDriver *>( pRet );
ASSERT( pDriver != NULL );
ASSERT( pDriver != nullptr );
LOG->Info( "Lights driver: %s", Driver->c_str() );
LOG->Info( "Lights driver: %s", Driver.c_str() );
Add.push_back( pDriver );
}
}
@@ -30,14 +30,14 @@ namespace {
const char *dance_leds[NUM_GameController][NUM_GameButton] = {
{
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
"/sys/class/leds/piuio::output20/brightness",
"/sys/class/leds/piuio::output21/brightness",
"/sys/class/leds/piuio::output18/brightness",
"/sys/class/leds/piuio::output19/brightness",
},
{
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
"/sys/class/leds/piuio::output4/brightness",
"/sys/class/leds/piuio::output5/brightness",
"/sys/class/leds/piuio::output2/brightness",
@@ -47,7 +47,7 @@ namespace {
const char *pump_leds[NUM_GameController][NUM_GameButton] = {
{
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
"/sys/class/leds/piuio::output2/brightness",
"/sys/class/leds/piuio::output3/brightness",
"/sys/class/leds/piuio::output4/brightness",
@@ -55,7 +55,7 @@ namespace {
"/sys/class/leds/piuio::output6/brightness",
},
{
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
"/sys/class/leds/piuio::output18/brightness",
"/sys/class/leds/piuio::output19/brightness",
"/sys/class/leds/piuio::output20/brightness",
@@ -66,10 +66,10 @@ namespace {
bool SetLight(const char *filename, bool on)
{
if (filename == NULL)
if (filename == nullptr)
return true;
FILE *f = fopen(filename, "w");
if (f == NULL)
if (f == nullptr)
{
return false;
}
+7 -7
View File
@@ -8,24 +8,24 @@
REGISTER_LIGHTS_DRIVER_CLASS(PacDrive);
HINSTANCE PachDLL = NULL;
HINSTANCE PachDLL = nullptr;
bool PacDriveConnected = false;
typedef int (WINAPI PacInitialize)(void);
PacInitialize* m_pacinit = NULL;
PacInitialize* m_pacinit = nullptr;
typedef void (WINAPI PacShutdown)(void);
PacShutdown* m_pacdone = NULL;
PacShutdown* m_pacdone = nullptr;
typedef bool (WINAPI PacSetLEDStates)(int, short int);
PacSetLEDStates* m_pacset = NULL;
PacSetLEDStates* m_pacset = nullptr;
LightsDriver_PacDrive::LightsDriver_PacDrive()
{
// init io.dll
PachDLL = LoadLibrary("pacdrive32.dll");
if(PachDLL == NULL)
if(PachDLL == nullptr)
{
MessageBox(NULL, "Could not LoadLibrary( pacdrive32.dll ).", "ERROR", MB_OK );
MessageBox(nullptr, "Could not LoadLibrary( pacdrive32.dll ).", "ERROR", MB_OK );
return;
}
@@ -39,7 +39,7 @@ LightsDriver_PacDrive::LightsDriver_PacDrive()
if( NumPacDrives == 0 )
{
PacDriveConnected = false; // set not connected
MessageBox(NULL, "Could not find connected PacDrive.", "ERROR", MB_OK);
MessageBox(nullptr, "Could not find connected PacDrive.", "ERROR", MB_OK);
return;
}
else
@@ -167,7 +167,7 @@ namespace
}
virtual ~Impl() {
if(out != NULL)
if(out != nullptr)
{
out->Flush();
out->Close();
@@ -184,7 +184,7 @@ namespace
// Only write if the message has changed since the last write.
if(memcmp(buffer, lastOutput, FULL_SEXTET_COUNT) != 0)
{
if(out != NULL)
if(out != nullptr)
{
out->Write(buffer, FULL_SEXTET_COUNT);
out->Flush();
@@ -205,12 +205,12 @@ namespace
LightsDriver_SextetStream::LightsDriver_SextetStream()
{
_impl = NULL;
_impl = nullptr;
}
LightsDriver_SextetStream::~LightsDriver_SextetStream()
{
if(IMPL != NULL)
if(IMPL != nullptr)
{
delete IMPL;
}
@@ -218,7 +218,7 @@ LightsDriver_SextetStream::~LightsDriver_SextetStream()
void LightsDriver_SextetStream::Set(const LightsState *ls)
{
if(IMPL != NULL)
if(IMPL != nullptr)
{
IMPL->Set(ls);
}
@@ -244,7 +244,7 @@ inline RageFile * openOutputStream(const RString& filename)
{
LOG->Warn("Error opening file '%s' for output: %s", filename.c_str(), file->GetError().c_str());
SAFE_DELETE(file);
file = NULL;
file = nullptr;
}
return file;
@@ -10,7 +10,7 @@
REGISTER_LIGHTS_DRIVER_CLASS( Win32Minimaid );
HINSTANCE hMMMAGICDLL = NULL;
HINSTANCE hMMMAGICDLL = nullptr;
int minimaid_filter(unsigned int, struct _EXCEPTION_POINTERS *)
{
@@ -41,7 +41,7 @@ void setup_driver()
}
__except (minimaid_filter(GetExceptionCode(), GetExceptionInformation()))
{
MessageBox(NULL, "Could not connect to the Mimimaid device. Freeing the library now.", "ERROR", MB_OK);
MessageBox(nullptr, "Could not connect to the Mimimaid device. Freeing the library now.", "ERROR", MB_OK);
FreeLibrary(hMMMAGICDLL);
}
@@ -51,9 +51,9 @@ LightsDriver_Win32Minimaid::LightsDriver_Win32Minimaid()
{
_mmmagic_loaded=false;
hMMMAGICDLL = LoadLibraryW(L"mmmagic.dll");
if(hMMMAGICDLL == NULL)
if(hMMMAGICDLL == nullptr)
{
MessageBox(NULL, "Could not LoadLibrary( mmmagic.dll ).", "ERROR", MB_OK );
MessageBox(nullptr, "Could not LoadLibrary( mmmagic.dll ).", "ERROR", MB_OK );
return;
}
setup_driver();
@@ -5,12 +5,12 @@
REGISTER_LIGHTS_DRIVER_CLASS(Win32Parallel);
HINSTANCE hDLL = NULL;
HINSTANCE hDLL = nullptr;
typedef void (WINAPI PORTOUT)(short int Port, char Data);
PORTOUT* PortOut = NULL;
PORTOUT* PortOut = nullptr;
typedef short int (WINAPI ISDRIVERINSTALLED)();
ISDRIVERINSTALLED* IsDriverInstalled = NULL;
ISDRIVERINSTALLED* IsDriverInstalled = nullptr;
const int LIGHTS_PER_PARALLEL_PORT = 8;
// xxx: don't hardcode the port addresses. -aj
@@ -44,9 +44,9 @@ LightsDriver_Win32Parallel::LightsDriver_Win32Parallel()
{
// init io.dll
hDLL = LoadLibrary("parallel_lights_io.dll");
if(hDLL == NULL)
if(hDLL == nullptr)
{
MessageBox(NULL, "Could not LoadLibrary( parallel_lights_io.dll ).", "ERROR", MB_OK );
MessageBox(nullptr, "Could not LoadLibrary( parallel_lights_io.dll ).", "ERROR", MB_OK );
return;
}
+82 -82
View File
@@ -1,82 +1,82 @@
#include "global.h"
#include "LoadingWindow.h"
#include "PrefsManager.h"
#include "RageLog.h"
#include "arch/arch_default.h"
LoadingWindow *LoadingWindow::Create()
{
if( !PREFSMAN->m_bShowLoadingWindow )
return new LoadingWindow_Null;
#if defined(UNIX) && !defined(HAVE_GTK)
return new LoadingWindow_Null;
#endif
// Don't load NULL by default.
const RString drivers = "win32,macosx,gtk";
vector<RString> DriversToTry;
split( drivers, ",", DriversToTry, true );
ASSERT( DriversToTry.size() != 0 );
RString Driver;
LoadingWindow *ret = NULL;
for( unsigned i = 0; ret == NULL && i < DriversToTry.size(); ++i )
{
Driver = DriversToTry[i];
#ifdef USE_LOADING_WINDOW_MACOSX
if( !DriversToTry[i].CompareNoCase("MacOSX") ) ret = new LoadingWindow_MacOSX;
#endif
#ifdef USE_LOADING_WINDOW_GTK
if( !DriversToTry[i].CompareNoCase("Gtk") ) ret = new LoadingWindow_Gtk;
#endif
#ifdef USE_LOADING_WINDOW_WIN32
if( !DriversToTry[i].CompareNoCase("Win32") ) ret = new LoadingWindow_Win32;
#endif
if( !DriversToTry[i].CompareNoCase("Null") ) ret = new LoadingWindow_Null;
if( ret == NULL )
continue;
RString sError = ret->Init();
if( sError != "" )
{
LOG->Info( "Couldn't load driver %s: %s", DriversToTry[i].c_str(), sError.c_str() );
SAFE_DELETE( ret );
}
}
if( ret ) {
LOG->Info( "Loading window: %s", Driver.c_str() );
ret->SetIndeterminate(true);
}
return ret;
}
/*
* (c) 2002-2005 Glenn Maynard
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "global.h"
#include "LoadingWindow.h"
#include "PrefsManager.h"
#include "RageLog.h"
#include "arch/arch_default.h"
LoadingWindow *LoadingWindow::Create()
{
if( !PREFSMAN->m_bShowLoadingWindow )
return new LoadingWindow_Null;
#if defined(UNIX) && !defined(HAVE_GTK)
return new LoadingWindow_Null;
#endif
// Don't load nullptr by default.
const RString drivers = "win32,macosx,gtk";
vector<RString> DriversToTry;
split( drivers, ",", DriversToTry, true );
ASSERT( DriversToTry.size() != 0 );
RString Driver;
LoadingWindow *ret = nullptr;
for( unsigned i = 0; ret == nullptr && i < DriversToTry.size(); ++i )
{
Driver = DriversToTry[i];
#ifdef USE_LOADING_WINDOW_MACOSX
if( !DriversToTry[i].CompareNoCase("MacOSX") ) ret = new LoadingWindow_MacOSX;
#endif
#ifdef USE_LOADING_WINDOW_GTK
if( !DriversToTry[i].CompareNoCase("Gtk") ) ret = new LoadingWindow_Gtk;
#endif
#ifdef USE_LOADING_WINDOW_WIN32
if( !DriversToTry[i].CompareNoCase("Win32") ) ret = new LoadingWindow_Win32;
#endif
if( !DriversToTry[i].CompareNoCase("Null") ) ret = new LoadingWindow_Null;
if( ret == nullptr )
continue;
RString sError = ret->Init();
if( sError != "" )
{
LOG->Info( "Couldn't load driver %s: %s", DriversToTry[i].c_str(), sError.c_str() );
SAFE_DELETE( ret );
}
}
if( ret ) {
LOG->Info( "Loading window: %s", Driver.c_str() );
ret->SetIndeterminate(true);
}
return ret;
}
/*
* (c) 2002-2005 Glenn Maynard
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
+137 -137
View File
@@ -1,137 +1,137 @@
#include "global.h"
#include "RageLog.h"
#include "RageFileManager.h"
#include "RageUtil.h"
#include "LoadingWindow_Gtk.h"
#include "LoadingWindow_GtkModule.h"
#include <dlfcn.h>
static void *Handle = NULL;
static INIT Module_Init;
static SHUTDOWN Module_Shutdown;
static SETTEXT Module_SetText;
static SETICON Module_SetIcon;
static SETSPLASH Module_SetSplash;
static SETPROGRESS Module_SetProgress;
static SETINDETERMINATE Module_SetIndeterminate;
LoadingWindow_Gtk::LoadingWindow_Gtk()
{
}
static RString ModuleError( const RString s )
{
return ssprintf( "Couldn't load symbol Module_%s", s.c_str() );
}
RString LoadingWindow_Gtk::Init()
{
ASSERT( Handle == NULL );
Handle = dlopen( RageFileManagerUtil::sDirOfExecutable + "/" + "GtkModule.so", RTLD_NOW );
if( Handle == NULL )
return ssprintf( "dlopen(): %s", dlerror() );
Module_Init = (INIT) dlsym(Handle, "Init");
if( !Module_Init )
return ModuleError("Init");
Module_Shutdown = (SHUTDOWN) dlsym(Handle, "Shutdown");
if( !Module_Shutdown )
return ModuleError("Shutdown");
Module_SetText = (SETTEXT) dlsym(Handle, "SetText");
if( !Module_SetText )
return ModuleError("SetText");
Module_SetIcon = (SETICON) dlsym(Handle, "SetIcon");
if( !Module_SetIcon )
return ModuleError("SetIcon");
Module_SetSplash = (SETSPLASH) dlsym(Handle, "SetSplash");
if( !Module_SetSplash )
return ModuleError("SetSplash");
Module_SetProgress = (SETPROGRESS) dlsym(Handle, "SetProgress");
if( !Module_SetProgress )
return ModuleError("SetProgress");
Module_SetIndeterminate = (SETINDETERMINATE) dlsym(Handle, "SetIndeterminate");
if( !Module_SetIndeterminate )
return ModuleError("SetIndeterminate");
const char *ret = Module_Init( &g_argc, &g_argv );
if( ret != NULL )
return ret;
return "";
}
LoadingWindow_Gtk::~LoadingWindow_Gtk()
{
if( Module_Shutdown != NULL )
Module_Shutdown();
Module_Shutdown = NULL;
if( Handle )
dlclose( Handle );
Handle = NULL;
}
void LoadingWindow_Gtk::SetText( RString s )
{
Module_SetText( s );
}
void LoadingWindow_Gtk::SetIcon( const RageSurface *pIcon )
{
Module_SetIcon( pIcon );
}
void LoadingWindow_Gtk::SetSplash( const RageSurface *pSplash )
{
Module_SetSplash( pSplash );
}
void LoadingWindow_Gtk::SetProgress( const int progress )
{
LoadingWindow::SetProgress( progress );
Module_SetProgress( m_progress, m_totalWork );
}
void LoadingWindow_Gtk::SetTotalWork( const int totalWork )
{
LoadingWindow::SetTotalWork( totalWork );
Module_SetProgress( m_progress, m_totalWork );
}
void LoadingWindow_Gtk::SetIndeterminate( bool indeterminate )
{
LoadingWindow::SetIndeterminate( indeterminate );
Module_SetIndeterminate( m_indeterminate );
}
/*
* (c) 2003-2004 Glenn Maynard, Sean Burke
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "global.h"
#include "RageLog.h"
#include "RageFileManager.h"
#include "RageUtil.h"
#include "LoadingWindow_Gtk.h"
#include "LoadingWindow_GtkModule.h"
#include <dlfcn.h>
static void *Handle = nullptr;
static INIT Module_Init;
static SHUTDOWN Module_Shutdown;
static SETTEXT Module_SetText;
static SETICON Module_SetIcon;
static SETSPLASH Module_SetSplash;
static SETPROGRESS Module_SetProgress;
static SETINDETERMINATE Module_SetIndeterminate;
LoadingWindow_Gtk::LoadingWindow_Gtk()
{
}
static RString ModuleError( const RString s )
{
return ssprintf( "Couldn't load symbol Module_%s", s.c_str() );
}
RString LoadingWindow_Gtk::Init()
{
ASSERT( Handle == nullptr );
Handle = dlopen( RageFileManagerUtil::sDirOfExecutable + "/" + "GtkModule.so", RTLD_NOW );
if( Handle == nullptr )
return ssprintf( "dlopen(): %s", dlerror() );
Module_Init = (INIT) dlsym(Handle, "Init");
if( !Module_Init )
return ModuleError("Init");
Module_Shutdown = (SHUTDOWN) dlsym(Handle, "Shutdown");
if( !Module_Shutdown )
return ModuleError("Shutdown");
Module_SetText = (SETTEXT) dlsym(Handle, "SetText");
if( !Module_SetText )
return ModuleError("SetText");
Module_SetIcon = (SETICON) dlsym(Handle, "SetIcon");
if( !Module_SetIcon )
return ModuleError("SetIcon");
Module_SetSplash = (SETSPLASH) dlsym(Handle, "SetSplash");
if( !Module_SetSplash )
return ModuleError("SetSplash");
Module_SetProgress = (SETPROGRESS) dlsym(Handle, "SetProgress");
if( !Module_SetProgress )
return ModuleError("SetProgress");
Module_SetIndeterminate = (SETINDETERMINATE) dlsym(Handle, "SetIndeterminate");
if( !Module_SetIndeterminate )
return ModuleError("SetIndeterminate");
const char *ret = Module_Init( &g_argc, &g_argv );
if( ret != nullptr )
return ret;
return "";
}
LoadingWindow_Gtk::~LoadingWindow_Gtk()
{
if( Module_Shutdown != nullptr )
Module_Shutdown();
Module_Shutdown = nullptr;
if( Handle )
dlclose( Handle );
Handle = nullptr;
}
void LoadingWindow_Gtk::SetText( RString s )
{
Module_SetText( s );
}
void LoadingWindow_Gtk::SetIcon( const RageSurface *pIcon )
{
Module_SetIcon( pIcon );
}
void LoadingWindow_Gtk::SetSplash( const RageSurface *pSplash )
{
Module_SetSplash( pSplash );
}
void LoadingWindow_Gtk::SetProgress( const int progress )
{
LoadingWindow::SetProgress( progress );
Module_SetProgress( m_progress, m_totalWork );
}
void LoadingWindow_Gtk::SetTotalWork( const int totalWork )
{
LoadingWindow::SetTotalWork( totalWork );
Module_SetProgress( m_progress, m_totalWork );
}
void LoadingWindow_Gtk::SetIndeterminate( bool indeterminate )
{
LoadingWindow::SetIndeterminate( indeterminate );
Module_SetIndeterminate( m_indeterminate );
}
/*
* (c) 2003-2004 Glenn Maynard, Sean Burke
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
+151 -151
View File
@@ -1,151 +1,151 @@
#include "global.h"
#include "LoadingWindow_GtkModule.h"
#include "RageUtil.h"
#include "RageSurface.h"
#include "RageSurfaceUtils.h"
#include "RageSurface_Load.h"
#include <gtk/gtk.h>
static GtkWidget *label;
static GtkWidget *window;
static GtkWidget *splash;
static GtkWidget *progressBar;
extern "C" const char *Init( int *argc, char ***argv )
{
// Need to use external library to load this image. Native loader seems broken :/
const gchar *splash_image_path = "Data/splash.png";
GtkWidget *vbox;
gtk_disable_setlocale();
if( !gtk_init_check(argc,argv) )
return "Couldn't initialize gtk (cannot open display)";
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position( GTK_WINDOW(window), GTK_WIN_POS_CENTER );
gtk_widget_set_size_request(window,468,-1);
gtk_window_set_deletable( GTK_WINDOW(window), FALSE );
gtk_window_set_resizable(GTK_WINDOW(window),FALSE);
gtk_window_set_role( GTK_WINDOW(window), "sm-startup" );
//gtk_window_set_icon( GTK_WINDOW(window), );
gtk_widget_realize(window);
splash = gtk_image_new_from_file(splash_image_path);
label = gtk_label_new(NULL);
gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_CENTER);
gtk_label_set_ellipsize(GTK_LABEL(label),PANGO_ELLIPSIZE_END);
gtk_label_set_line_wrap(GTK_LABEL(label),FALSE);
progressBar = gtk_progress_bar_new();
gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR(progressBar), 0.0 );
vbox = gtk_vbox_new(FALSE,0);
gtk_container_add(GTK_CONTAINER(window),vbox);
gtk_box_pack_start(GTK_BOX(vbox),splash,FALSE,FALSE,0);
gtk_box_pack_end(GTK_BOX(vbox),progressBar,FALSE,FALSE,0);
gtk_box_pack_end(GTK_BOX(vbox),label,TRUE,TRUE,0);
gtk_widget_show_all(window);
gtk_main_iteration_do(FALSE);
return NULL;
}
extern "C" void Shutdown()
{
gtk_widget_hide(window);
g_signal_emit_by_name (G_OBJECT (window), "destroy");
while( gtk_events_pending() )
gtk_main_iteration_do(FALSE);
}
extern "C" void SetText( const char *s )
{
gtk_label_set_text(GTK_LABEL(label), s);
gtk_widget_show(label);
gtk_main_iteration_do(FALSE);
}
void DeletePixels( guchar *pixels, gpointer data )
{
delete[] (uint8_t *)pixels;
}
GdkPixbuf *MakePixbuf( const RageSurface *pSrc )
{
RageSurface *pSurface = CreateSurface( pSrc->w, pSrc->h, 32,
0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 );
RageSurfaceUtils::Blit( pSrc, pSurface , -1, -1 );
GdkPixbuf *pBuf = gdk_pixbuf_new_from_data( pSurface->pixels, GDK_COLORSPACE_RGB,
true, 8, pSurface->w, pSurface->h , pSurface->pitch, DeletePixels, NULL);
if( pBuf != NULL )
pSurface->pixels_owned = false;
delete pSurface;
return pBuf;
}
extern "C" void SetIcon( const RageSurface *pSrcImg )
{
GdkPixbuf *pBuf = MakePixbuf( pSrcImg );
if( pBuf != NULL )
{
gtk_window_set_icon( GTK_WINDOW(window), pBuf );
g_object_unref(pBuf);
}
gtk_main_iteration_do(FALSE);
}
extern "C" void SetSplash( const RageSurface *pSplash )
{
GdkPixbuf *pBuf = MakePixbuf( pSplash );
if( pBuf != NULL )
{
gtk_image_set_from_pixbuf(GTK_IMAGE(splash), pBuf);
g_object_unref(pBuf);
}
gtk_main_iteration_do(FALSE);
}
extern "C" void SetProgress( int progress, int totalWork )
{
gdouble fraction = ( totalWork > 0 ? progress / (gdouble)totalWork : 0 );
if( fraction > 1.0 ) fraction = 1.0;
if( fraction < 0.0 ) fraction = 0.0;
gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR(progressBar), fraction );
gtk_main_iteration_do(FALSE);
}
extern "C" void SetIndeterminate( bool indeterminate )
{
gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progressBar));
gtk_main_iteration_do(FALSE);
}
/*
* (c) 2003-2004 Glenn Maynard, Sean Burke
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "global.h"
#include "LoadingWindow_GtkModule.h"
#include "RageUtil.h"
#include "RageSurface.h"
#include "RageSurfaceUtils.h"
#include "RageSurface_Load.h"
#include <gtk/gtk.h>
static GtkWidget *label;
static GtkWidget *window;
static GtkWidget *splash;
static GtkWidget *progressBar;
extern "C" const char *Init( int *argc, char ***argv )
{
// Need to use external library to load this image. Native loader seems broken :/
const gchar *splash_image_path = "Data/splash.png";
GtkWidget *vbox;
gtk_disable_setlocale();
if( !gtk_init_check(argc,argv) )
return "Couldn't initialize gtk (cannot open display)";
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position( GTK_WINDOW(window), GTK_WIN_POS_CENTER );
gtk_widget_set_size_request(window,468,-1);
gtk_window_set_deletable( GTK_WINDOW(window), FALSE );
gtk_window_set_resizable(GTK_WINDOW(window),FALSE);
gtk_window_set_role( GTK_WINDOW(window), "sm-startup" );
//gtk_window_set_icon( GTK_WINDOW(window), );
gtk_widget_realize(window);
splash = gtk_image_new_from_file(splash_image_path);
label = gtk_label_new(nullptr);
gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_CENTER);
gtk_label_set_ellipsize(GTK_LABEL(label),PANGO_ELLIPSIZE_END);
gtk_label_set_line_wrap(GTK_LABEL(label),FALSE);
progressBar = gtk_progress_bar_new();
gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR(progressBar), 0.0 );
vbox = gtk_vbox_new(FALSE,0);
gtk_container_add(GTK_CONTAINER(window),vbox);
gtk_box_pack_start(GTK_BOX(vbox),splash,FALSE,FALSE,0);
gtk_box_pack_end(GTK_BOX(vbox),progressBar,FALSE,FALSE,0);
gtk_box_pack_end(GTK_BOX(vbox),label,TRUE,TRUE,0);
gtk_widget_show_all(window);
gtk_main_iteration_do(FALSE);
return nullptr;
}
extern "C" void Shutdown()
{
gtk_widget_hide(window);
g_signal_emit_by_name (G_OBJECT (window), "destroy");
while( gtk_events_pending() )
gtk_main_iteration_do(FALSE);
}
extern "C" void SetText( const char *s )
{
gtk_label_set_text(GTK_LABEL(label), s);
gtk_widget_show(label);
gtk_main_iteration_do(FALSE);
}
void DeletePixels( guchar *pixels, gpointer data )
{
delete[] (uint8_t *)pixels;
}
GdkPixbuf *MakePixbuf( const RageSurface *pSrc )
{
RageSurface *pSurface = CreateSurface( pSrc->w, pSrc->h, 32,
0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 );
RageSurfaceUtils::Blit( pSrc, pSurface , -1, -1 );
GdkPixbuf *pBuf = gdk_pixbuf_new_from_data( pSurface->pixels, GDK_COLORSPACE_RGB,
true, 8, pSurface->w, pSurface->h , pSurface->pitch, DeletePixels, nullptr);
if( pBuf != nullptr )
pSurface->pixels_owned = false;
delete pSurface;
return pBuf;
}
extern "C" void SetIcon( const RageSurface *pSrcImg )
{
GdkPixbuf *pBuf = MakePixbuf( pSrcImg );
if( pBuf != nullptr )
{
gtk_window_set_icon( GTK_WINDOW(window), pBuf );
g_object_unref(pBuf);
}
gtk_main_iteration_do(FALSE);
}
extern "C" void SetSplash( const RageSurface *pSplash )
{
GdkPixbuf *pBuf = MakePixbuf( pSplash );
if( pBuf != nullptr )
{
gtk_image_set_from_pixbuf(GTK_IMAGE(splash), pBuf);
g_object_unref(pBuf);
}
gtk_main_iteration_do(FALSE);
}
extern "C" void SetProgress( int progress, int totalWork )
{
gdouble fraction = ( totalWork > 0 ? progress / (gdouble)totalWork : 0 );
if( fraction > 1.0 ) fraction = 1.0;
if( fraction < 0.0 ) fraction = 0.0;
gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR(progressBar), fraction );
gtk_main_iteration_do(FALSE);
}
extern "C" void SetIndeterminate( bool indeterminate )
{
gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progressBar));
gtk_main_iteration_do(FALSE);
}
/*
* (c) 2003-2004 Glenn Maynard, Sean Burke
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
+19 -19
View File
@@ -17,7 +17,7 @@
#include "LocalizedString.h"
#include "RageSurfaceUtils_Zoom.h"
static HBITMAP g_hBitmap = NULL;
static HBITMAP g_hBitmap = nullptr;
/* Load a RageSurface into a GDI surface. */
static HBITMAP LoadWin32Surface( const RageSurface *pSplash, HWND hWnd )
@@ -39,11 +39,11 @@ static HBITMAP LoadWin32Surface( const RageSurface *pSplash, HWND hWnd )
RageSurfaceUtils::Zoom( s, iWidth, iHeight );
}
HDC hScreen = GetDC(NULL);
ASSERT_M( hScreen != NULL, werr_ssprintf(GetLastError(), "hScreen") );
HDC hScreen = GetDC(nullptr);
ASSERT_M( hScreen != nullptr, werr_ssprintf(GetLastError(), "hScreen") );
HBITMAP bitmap = CreateCompatibleBitmap( hScreen, s->w, s->h );
ASSERT_M( bitmap != NULL, werr_ssprintf(GetLastError(), "CreateCompatibleBitmap") );
ASSERT_M( bitmap != nullptr, werr_ssprintf(GetLastError(), "CreateCompatibleBitmap") );
HDC BitmapDC = CreateCompatibleDC( hScreen );
SelectObject( BitmapDC, bitmap );
@@ -60,10 +60,10 @@ static HBITMAP LoadWin32Surface( const RageSurface *pSplash, HWND hWnd )
}
}
SelectObject( BitmapDC, NULL );
SelectObject( BitmapDC, nullptr );
DeleteObject( BitmapDC );
ReleaseDC( NULL, hScreen );
ReleaseDC( nullptr, hScreen );
delete s;
return bitmap;
@@ -73,8 +73,8 @@ static HBITMAP LoadWin32Surface( RString sFile, HWND hWnd )
{
RString error;
RageSurface *pSurface = RageSurfaceUtils::LoadFile( sFile, error );
if( pSurface == NULL )
return NULL;
if( pSurface == nullptr )
return nullptr;
HBITMAP ret = LoadWin32Surface( pSurface, hWnd );
delete pSurface;
@@ -92,7 +92,7 @@ BOOL CALLBACK LoadingWindow_Win32::WndProc( HWND hWnd, UINT msg, WPARAM wParam,
if( !vs.empty() )
g_hBitmap = LoadWin32Surface( vs[0], hWnd );
}
if( g_hBitmap == NULL )
if( g_hBitmap == nullptr )
g_hBitmap = LoadWin32Surface( "Data/splash.bmp", hWnd );
SendMessage(
GetDlgItem(hWnd,IDC_SPLASH),
@@ -104,7 +104,7 @@ BOOL CALLBACK LoadingWindow_Win32::WndProc( HWND hWnd, UINT msg, WPARAM wParam,
case WM_DESTROY:
DeleteObject( g_hBitmap );
g_hBitmap = NULL;
g_hBitmap = nullptr;
break;
}
@@ -113,25 +113,25 @@ BOOL CALLBACK LoadingWindow_Win32::WndProc( HWND hWnd, UINT msg, WPARAM wParam,
void LoadingWindow_Win32::SetIcon( const RageSurface *pIcon )
{
if( m_hIcon != NULL )
if( m_hIcon != nullptr )
DestroyIcon( m_hIcon );
m_hIcon = IconFromSurface( pIcon );
if( m_hIcon != NULL )
if( m_hIcon != nullptr )
// XXX: GCL_HICON isn't available on x86-64 Windows
SetClassLong( hwnd, GCL_HICON, (LONG) m_hIcon );
}
void LoadingWindow_Win32::SetSplash( const RageSurface *pSplash )
{
if( g_hBitmap != NULL )
if( g_hBitmap != nullptr )
{
DeleteObject( g_hBitmap );
g_hBitmap = NULL;
g_hBitmap = nullptr;
}
g_hBitmap = LoadWin32Surface( pSplash, hwnd );
if( g_hBitmap != NULL )
if( g_hBitmap != nullptr )
{
SendDlgItemMessage(
hwnd, IDC_SPLASH,
@@ -144,9 +144,9 @@ void LoadingWindow_Win32::SetSplash( const RageSurface *pSplash )
LoadingWindow_Win32::LoadingWindow_Win32()
{
m_hIcon = NULL;
hwnd = CreateDialog( handle.Get(), MAKEINTRESOURCE(IDD_LOADING_DIALOG), NULL, WndProc );
ASSERT( hwnd != NULL );
m_hIcon = nullptr;
hwnd = CreateDialog( handle.Get(), MAKEINTRESOURCE(IDD_LOADING_DIALOG), nullptr, WndProc );
ASSERT( hwnd != nullptr );
for( unsigned i = 0; i < 3; ++i )
text[i] = "ABC"; /* always set on first call */
SetText( "" );
@@ -157,7 +157,7 @@ LoadingWindow_Win32::~LoadingWindow_Win32()
{
if( hwnd )
DestroyWindow( hwnd );
if( m_hIcon != NULL )
if( m_hIcon != nullptr )
DestroyIcon( m_hIcon );
}
+1 -1
View File
@@ -34,7 +34,7 @@ public:
virtual const ActualVideoModeParams GetActualVideoModeParams() const = 0;
virtual bool SupportsRenderToTexture() const { return false; }
virtual RenderTarget *CreateRenderTarget() { return NULL; }
virtual RenderTarget *CreateRenderTarget() { return nullptr; }
virtual bool SupportsFullscreenBorderlessWindow() const { return false; };
@@ -255,7 +255,7 @@ void RenderTarget_MacOSX::Create( const RenderTargetParam &param, int &iTextureW
glTexImage2D( GL_TEXTURE_2D, 0, param.bWithAlpha? GL_RGBA8:GL_RGB8,
iTextureWidth, iTextureHeight, 0, param.bWithAlpha? GL_RGBA:GL_RGB,
GL_UNSIGNED_BYTE, NULL );
GL_UNSIGNED_BYTE, nil);
GLenum error = glGetError();
ASSERT_M(error == GL_NO_ERROR, RageDisplay_Legacy_Helpers::GLToString(error));
@@ -293,7 +293,7 @@ void RenderTarget_MacOSX::FinishRenderingTo()
}
LowLevelWindow_MacOSX::LowLevelWindow_MacOSX() : m_Context(nil), m_BGContext(nil), m_CurrentDisplayMode(NULL), m_DisplayID(0)
LowLevelWindow_MacOSX::LowLevelWindow_MacOSX() : m_Context(nil), m_BGContext(nil), m_CurrentDisplayMode(nil), m_DisplayID(0)
{
POOL;
m_WindowDelegate = [[SMWindowDelegate alloc] init];
@@ -323,12 +323,12 @@ void *LowLevelWindow_MacOSX::GetProcAddress( RString s )
// Both functions mentioned in there are deprecated in 10.4.
const RString& symbolName( '_' + s );
const uint32_t count = _dyld_image_count();
NSSymbol symbol = NULL;
NSSymbol symbol = nil;
const uint32_t options = NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR;
for( uint32_t i = 0; i < count && !symbol; ++i )
symbol = NSLookupSymbolInImage( _dyld_get_image_header(i), symbolName, options );
return symbol ? NSAddressOfSymbol( symbol ) : NULL;
return symbol ? NSAddressOfSymbol( symbol ) : nil;
}
RString LowLevelWindow_MacOSX::TryVideoMode( const VideoModeParams& p, bool& newDeviceOut )
@@ -462,13 +462,13 @@ void LowLevelWindow_MacOSX::ShutDownFullScreen()
ASSERT( err == kCGErrorSuccess );
SetActualParamsFromMode( m_CurrentDisplayMode );
// We don't own this so we cannot release it.
m_CurrentDisplayMode = NULL;
m_CurrentDisplayMode = nil;
m_CurrentParams.windowed = true;
}
int LowLevelWindow_MacOSX::ChangeDisplayMode( const VideoModeParams& p )
{
CFDictionaryRef mode = NULL;
CFDictionaryRef mode = nil;
CFDictionaryRef newMode;
CGDisplayErr err;
@@ -483,10 +483,10 @@ int LowLevelWindow_MacOSX::ChangeDisplayMode( const VideoModeParams& p )
}
if( p.rate == REFRESH_DEFAULT )
newMode = CGDisplayBestModeForParameters( kCGDirectMainDisplay, p.bpp, p.width, p.height, NULL );
newMode = CGDisplayBestModeForParameters( kCGDirectMainDisplay, p.bpp, p.width, p.height, nil);
else
newMode = CGDisplayBestModeForParametersAndRefreshRate( kCGDirectMainDisplay, p.bpp,
p.width, p.height, p.rate, NULL );
p.width, p.height, p.rate, nil);
err = CGDisplaySwitchToMode( kCGDirectMainDisplay, newMode );
@@ -14,29 +14,23 @@
#include <GL/glew.h>
static PIXELFORMATDESCRIPTOR g_CurrentPixelFormat;
static HGLRC g_HGLRC = NULL;
static HGLRC g_HGLRC_Background = NULL;
static HMODULE g_HGL_Module = NULL;
static HGLRC g_HGLRC = nullptr;
static HGLRC g_HGLRC_Background = nullptr;
static HMODULE g_HGL_Module = nullptr;
static void DestroyGraphicsWindowAndOpenGLContext()
{
if( g_HGLRC != NULL )
if( g_HGLRC != nullptr )
{
wglMakeCurrent( NULL, NULL );
wglMakeCurrent( nullptr, nullptr );
wglDeleteContext( g_HGLRC );
g_HGLRC = NULL;
g_HGLRC = nullptr;
}
if( g_HGLRC_Background != NULL )
if( g_HGLRC_Background != nullptr )
{
wglDeleteContext( g_HGLRC_Background );
g_HGLRC_Background = NULL;
}
if( g_HGL_Module != NULL )
{
FreeLibrary(g_HGL_Module);
g_HGL_Module = NULL;
g_HGLRC_Background = nullptr;
}
ZERO( g_CurrentPixelFormat );
@@ -47,25 +41,25 @@ static void DestroyGraphicsWindowAndOpenGLContext()
void *LowLevelWindow_Win32::GetProcAddress( RString s )
{
void *pRet = (void*) wglGetProcAddress( s );
if( pRet != NULL )
if( pRet != nullptr )
return pRet;
if (g_HGL_Module != NULL)
if (g_HGL_Module != nullptr)
{
pRet = (void *) ::GetProcAddress( g_HGL_Module, s );
if (pRet != NULL)
if (pRet != nullptr)
return pRet;
}
return (void*) ::GetProcAddress( GetModuleHandle(NULL), s );
return (void*) ::GetProcAddress( GetModuleHandle(nullptr), s );
}
LowLevelWindow_Win32::LowLevelWindow_Win32()
{
ASSERT( g_HGLRC == NULL );
ASSERT( g_HGLRC_Background == NULL );
ASSERT( g_HGL_Module == NULL );
ASSERT( g_HGLRC == nullptr );
ASSERT( g_HGLRC_Background == nullptr );
ASSERT( g_HGL_Module == nullptr );
GraphicsWindow::Initialize( false );
}
@@ -83,8 +77,8 @@ void LowLevelWindow_Win32::GetDisplaySpecs( DisplaySpecs &out ) const
int ChooseWindowPixelFormat( const VideoModeParams &p, PIXELFORMATDESCRIPTOR *pixfmt )
{
ASSERT( GraphicsWindow::GetHwnd() != NULL );
ASSERT( GraphicsWindow::GetHDC() != NULL );
ASSERT( GraphicsWindow::GetHwnd() != nullptr );
ASSERT( GraphicsWindow::GetHDC() != nullptr );
ZERO( *pixfmt );
pixfmt->nSize = sizeof(PIXELFORMATDESCRIPTOR);
@@ -144,7 +138,7 @@ RString LowLevelWindow_Win32::TryVideoMode( const VideoModeParams &p, bool &bNew
bool bCanSetPixelFormat = true;
/* Do we have an old window? */
if( GraphicsWindow::GetHwnd() == NULL )
if( GraphicsWindow::GetHwnd() == nullptr )
{
/* No. Always create and show the window before changing the video mode.
* Otherwise, some other window may have focus, and changing the video mode will
@@ -157,7 +151,7 @@ RString LowLevelWindow_Win32::TryVideoMode( const VideoModeParams &p, bool &bNew
bCanSetPixelFormat = false;
}
ASSERT( GraphicsWindow::GetHwnd() != NULL );
ASSERT( GraphicsWindow::GetHwnd() != nullptr );
/* Set the display mode: switch to a fullscreen mode or revert to windowed mode. */
LOG->Trace("SetScreenMode ...");
@@ -199,13 +193,13 @@ RString LowLevelWindow_Win32::TryVideoMode( const VideoModeParams &p, bool &bNew
* We have to create the new window first.
*/
LOG->Trace( "Mode requires new pixel format, and we've already set one; resetting OpenGL context" );
if( g_HGLRC != NULL )
if( g_HGLRC != nullptr )
{
wglMakeCurrent( NULL, NULL );
wglMakeCurrent( nullptr, nullptr );
wglDeleteContext( g_HGLRC );
g_HGLRC = NULL;
g_HGLRC = nullptr;
wglDeleteContext( g_HGLRC_Background );
g_HGLRC_Background = NULL;
g_HGLRC_Background = nullptr;
}
bNewDeviceOut = true;
@@ -231,19 +225,19 @@ RString LowLevelWindow_Win32::TryVideoMode( const VideoModeParams &p, bool &bNew
DumpPixelFormat( g_CurrentPixelFormat );
}
if( g_HGLRC == NULL )
if( g_HGLRC == nullptr )
{
g_HGL_Module = LoadLibraryA("opengl32.dll");
g_HGLRC = wglCreateContext( GraphicsWindow::GetHDC() );
if ( g_HGLRC == NULL )
if ( g_HGLRC == nullptr )
{
DestroyGraphicsWindowAndOpenGLContext();
return hr_ssprintf( GetLastError(), "wglCreateContext" );
}
g_HGLRC_Background = wglCreateContext( GraphicsWindow::GetHDC() );
if( g_HGLRC_Background == NULL )
if( g_HGLRC_Background == nullptr )
{
DestroyGraphicsWindowAndOpenGLContext();
return hr_ssprintf( GetLastError(), "wglCreateContext" );
@@ -253,7 +247,7 @@ RString LowLevelWindow_Win32::TryVideoMode( const VideoModeParams &p, bool &bNew
{
LOG->Warn( werr_ssprintf(GetLastError(), "wglShareLists failed") );
wglDeleteContext( g_HGLRC_Background );
g_HGLRC_Background = NULL;
g_HGLRC_Background = nullptr;
}
if( !wglMakeCurrent( GraphicsWindow::GetHDC(), g_HGLRC ) )
@@ -267,7 +261,7 @@ RString LowLevelWindow_Win32::TryVideoMode( const VideoModeParams &p, bool &bNew
bool LowLevelWindow_Win32::SupportsThreadedRendering()
{
return g_HGLRC_Background != NULL;
return g_HGLRC_Background != nullptr;
}
void LowLevelWindow_Win32::BeginConcurrentRendering()
@@ -281,7 +275,7 @@ void LowLevelWindow_Win32::BeginConcurrentRendering()
void LowLevelWindow_Win32::EndConcurrentRendering()
{
wglMakeCurrent( NULL, NULL );
wglMakeCurrent( nullptr, nullptr );
}
static LocalizedString OPENGL_NOT_AVAILABLE( "LowLevelWindow_Win32", "OpenGL hardware acceleration is not available." );
@@ -343,8 +337,8 @@ RenderTarget_Win32::RenderTarget_Win32(LowLevelWindow_Win32 *pWind)
{
m_pWind = pWind;
m_texHandle = 0;
m_hOldDeviceContext = NULL;
m_hOldRenderContext = NULL;
m_hOldDeviceContext = nullptr;
m_hOldRenderContext = nullptr;
}
RenderTarget_Win32::~RenderTarget_Win32()
@@ -377,7 +371,7 @@ void RenderTarget_Win32::Create(const RenderTargetParam &param, int &iTextureWid
internalformat = param.bWithAlpha? GL_RGBA8:GL_RGB8;
glTexImage2D(GL_TEXTURE_2D, 0, internalformat, iTextureWidth,
iTextureHeight, 0, type, GL_UNSIGNED_BYTE, NULL);
iTextureHeight, 0, type, GL_UNSIGNED_BYTE, nullptr);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+18 -18
View File
@@ -31,8 +31,8 @@ using namespace X11Helper;
// Display ID for treating the entire X screen as the display
const std::string ID_XSCREEN = "XSCREEN_RANDR";
static GLXContext g_pContext = NULL;
static GLXContext g_pBackgroundContext = NULL;
static GLXContext g_pContext = nullptr;
static GLXContext g_pBackgroundContext = nullptr;
static Window g_AltWindow = None;
static bool g_bChangedScreenSize = false;
static SizeID g_iOldSize = None;
@@ -98,12 +98,12 @@ LowLevelWindow_X11::~LowLevelWindow_X11()
if( g_pContext )
{
glXDestroyContext( Dpy, g_pContext );
g_pContext = NULL;
g_pContext = nullptr;
}
if( g_pBackgroundContext )
{
glXDestroyContext( Dpy, g_pBackgroundContext );
g_pBackgroundContext = NULL;
g_pBackgroundContext = nullptr;
}
XDestroyWindow( Dpy, Win );
Win = None;
@@ -138,7 +138,7 @@ void LowLevelWindow_X11::RestoreOutputConfig() {
void *LowLevelWindow_X11::GetProcAddress( RString s )
{
// XXX: We should check whether glXGetProcAddress or
// glXGetProcAddressARB is available/not NULL, and go by that,
// glXGetProcAddressARB is available/not nullptr, and go by that,
// instead of assuming like this.
return (void*) glXGetProcAddressARB( (const GLubyte*) s.c_str() );
}
@@ -156,9 +156,9 @@ RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDe
int windowHeight = p.height;
bool renderOffscreen = false;
if( g_pContext == NULL || p.bpp != CurrentParams.bpp || m_bWasWindowed != p.windowed )
if( g_pContext == nullptr || p.bpp != CurrentParams.bpp || m_bWasWindowed != p.windowed )
{
bool bFirstRun = g_pContext == NULL;
bool bFirstRun = g_pContext == nullptr;
// Different depth, or we didn't make a window before. New context.
bNewDeviceOut = true;
@@ -186,7 +186,7 @@ RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDe
visAttribs[i++] = None;
XVisualInfo *xvi = glXChooseVisual( Dpy, DefaultScreen(Dpy), visAttribs );
if( xvi == NULL )
if( xvi == nullptr )
return "No visual available for that depth.";
// I get strange behavior if I add override redirect after creating the window.
@@ -205,7 +205,7 @@ RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDe
glXDestroyContext( Dpy, g_pContext );
if( g_pBackgroundContext )
glXDestroyContext( Dpy, g_pBackgroundContext );
g_pContext = glXCreateContext( Dpy, xvi, NULL, True );
g_pContext = glXCreateContext( Dpy, xvi, nullptr, True );
g_pBackgroundContext = glXCreateContext( Dpy, xvi, g_pContext, True );
glXMakeCurrent( Dpy, Win, g_pContext );
@@ -307,7 +307,7 @@ RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDe
LOG->Info("LowLevelWindow_X11: Using XRandR");
XRRScreenResources *scrRes = XRRGetScreenResources(Dpy, Win);
ASSERT(scrRes != NULL);
ASSERT(scrRes != nullptr);
ASSERT(scrRes->ncrtc > 0);
ASSERT(scrRes->noutput > 0);
ASSERT(scrRes->nmode > 0);
@@ -353,7 +353,7 @@ RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDe
// if the target output is not currently being driven by a crtc,
// find an unused crtc that can be connected to it
XRROutputInfo *tgtOutInfo = XRRGetOutputInfo( Dpy, scrRes, targetOut );
if (tgtOutInfo == NULL)
if (tgtOutInfo == nullptr)
{
XRRFreeScreenResources(scrRes);
return "Failed to find XRROutput";
@@ -748,7 +748,7 @@ void LowLevelWindow_X11::GetDisplaySpecs(DisplaySpecs &out) const {
bool LowLevelWindow_X11::SupportsThreadedRendering()
{
return g_pBackgroundContext != NULL;
return g_pBackgroundContext != nullptr;
}
class RenderTarget_X11: public RenderTarget
@@ -780,9 +780,9 @@ RenderTarget_X11::RenderTarget_X11( LowLevelWindow_X11 *pWind )
{
m_pWind = pWind;
m_iPbuffer = 0;
m_pPbufferContext = NULL;
m_pPbufferContext = nullptr;
m_iTexHandle = 0;
m_pOldContext = NULL;
m_pOldContext = nullptr;
m_pOldDrawable = 0;
}
@@ -860,7 +860,7 @@ void RenderTarget_X11::Create( const RenderTargetParam &param, int &iTextureWidt
iTextureHeightOut = iTextureHeight;
glTexImage2D( GL_TEXTURE_2D, 0, param.bWithAlpha? GL_RGBA8:GL_RGB8,
iTextureWidth, iTextureHeight, 0, param.bWithAlpha? GL_RGBA:GL_RGB, GL_UNSIGNED_BYTE, NULL );
iTextureWidth, iTextureHeight, 0, param.bWithAlpha? GL_RGBA:GL_RGB, GL_UNSIGNED_BYTE, nullptr );
GLenum error = glGetError();
ASSERT_M( error == GL_NO_ERROR, GLToString(error) );
@@ -897,7 +897,7 @@ void RenderTarget_X11::FinishRenderingTo()
glBindTexture( GL_TEXTURE_2D, 0 );
glXMakeCurrent( Dpy, m_pOldDrawable, m_pOldContext );
m_pOldContext = NULL;
m_pOldContext = nullptr;
m_pOldDrawable = 0;
}
@@ -906,7 +906,7 @@ bool LowLevelWindow_X11::SupportsRenderToTexture() const
{
// Server must support pbuffers:
const int iScreen = DefaultScreen( Dpy );
float fVersion = strtof( glXQueryServerString(Dpy, iScreen, GLX_VERSION), NULL );
float fVersion = strtof( glXQueryServerString(Dpy, iScreen, GLX_VERSION), nullptr );
if( fVersion < 1.3f )
return false;
@@ -969,7 +969,7 @@ void LowLevelWindow_X11::BeginConcurrentRendering()
void LowLevelWindow_X11::EndConcurrentRendering()
{
bool b = glXMakeCurrent( Dpy, None, NULL );
bool b = glXMakeCurrent( Dpy, None, nullptr );
ASSERT(b);
}
+5 -5
View File
@@ -2,7 +2,7 @@
#include "MemoryCardDriver.h"
#include "RageFileManager.h"
#include "RageLog.h"
#include "Foreach.h"
#include "ProfileManager.h"
static const RString TEMP_MOUNT_POINT = "/@mctemptimeout/";
@@ -68,11 +68,11 @@ bool MemoryCardDriver::DoOneUpdate( bool bMount, vector<UsbStorageDevice>& vStor
GetUSBStorageDevices( vStorageDevicesOut );
// log connects
FOREACH( UsbStorageDevice, vStorageDevicesOut, newd )
for (UsbStorageDevice &newd : vStorageDevicesOut)
{
vector<UsbStorageDevice>::iterator iter = find( vOld.begin(), vOld.end(), *newd );
vector<UsbStorageDevice>::iterator iter = find( vOld.begin(), vOld.end(), newd );
if( iter == vOld.end() ) // didn't find
LOG->Trace( "New device connected: %s", newd->sDevice.c_str() );
LOG->Trace( "New device connected: %s", newd.sDevice.c_str() );
}
/* When we first see a device, regardless of bMount, just return it as CHECKING,
@@ -141,7 +141,7 @@ bool MemoryCardDriver::DoOneUpdate( bool bMount, vector<UsbStorageDevice>& vStor
#include "arch/arch_default.h"
MemoryCardDriver *MemoryCardDriver::Create()
{
MemoryCardDriver *ret = NULL;
MemoryCardDriver *ret = nullptr;
switch( g_MemoryCardDriver )
{
@@ -2,7 +2,6 @@
#include "MemoryCardDriverThreaded_Folder.h"
#include "RageLog.h"
#include "RageUtil.h"
#include "Foreach.h"
#include "PlayerNumber.h"
#include "MemoryCardManager.h"
@@ -83,7 +83,7 @@ static void GetFileList( const RString &sPath, vector<RString> &out )
out.clear();
DIR *dp = opendir( sPath );
if( dp == NULL )
if( dp == nullptr )
return; // false; // XXX warn
while( const struct dirent *ent = readdir(dp) )
@@ -317,7 +317,7 @@ void MemoryCardDriverThreaded_Linux::GetUSBStorageDevices( vector<UsbStorageDevi
* /dev. This allows us to specify persistent names in
* /etc/fstab using things like /dev/device/by-path. */
char szUnderlyingDevice[PATH_MAX];
if( realpath(szScsiDevice, szUnderlyingDevice) == NULL )
if( realpath(szScsiDevice, szUnderlyingDevice) == nullptr )
{
// "No such file or directory" is understandable
if (errno != ENOENT)
@@ -1,6 +1,5 @@
#include "global.h"
#include "MemoryCardDriverThreaded_MacOSX.h"
#include "Foreach.h"
#include "RageUtil.h"
#include "RageLog.h"
@@ -93,7 +92,7 @@ bool MemoryCardDriverThreaded_MacOSX::USBStorageDevicesChanged()
static int GetIntProperty( io_registry_entry_t entry, CFStringRef key )
{
CFTypeRef t = IORegistryEntryCreateCFProperty( entry, key, NULL, 0 );
CFTypeRef t = IORegistryEntryCreateCFProperty( entry, key, nullptr, 0 );
if( !t )
return -1;
@@ -112,7 +111,7 @@ static int GetIntProperty( io_registry_entry_t entry, CFStringRef key )
static RString GetStringProperty( io_registry_entry_t entry, CFStringRef key )
{
CFTypeRef t = IORegistryEntryCreateCFProperty( entry, key, NULL, 0 );
CFTypeRef t = IORegistryEntryCreateCFProperty( entry, key, nullptr, 0 );
if( !t )
return RString();
@@ -139,7 +138,7 @@ void MemoryCardDriverThreaded_MacOSX::GetUSBStorageDevices( vector<UsbStorageDev
LockMut( m_ChangedLock );
// First, get all device paths
struct statfs *fs;
int num = getfsstat( NULL, 0, MNT_NOWAIT );
int num = getfsstat( nullptr, 0, MNT_NOWAIT );
fs = new struct statfs[num];
@@ -47,7 +47,7 @@ bool MemoryCardDriverThreaded_Windows::TestWrite( UsbStorageDevice* pDevice )
{
HANDLE hFile = CreateFile( ssprintf( "%stmp%i", pDevice->sOsMountDir.c_str(), RandomInt(100000)),
GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL );
nullptr, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, nullptr );
if( hFile == INVALID_HANDLE_VALUE )
{
@@ -193,7 +193,7 @@ void MemoryCardDriverThreaded_Windows::Unmount( UsbStorageDevice* pDevice )
/* Try to flush the device before returning. This requires administrator priviliges. */
HANDLE hDevice = CreateFile( pDevice->sDevice, GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr );
if( hDevice == INVALID_HANDLE_VALUE )
{
+12 -11
View File
@@ -6,7 +6,7 @@
#include "PrefsManager.h"
#include "RageFile.h"
#include "LocalizedString.h"
#include "Foreach.h"
#include "arch/arch_default.h"
void ForceToAscii( RString &str )
@@ -92,34 +92,35 @@ RageMovieTexture *RageMovieTexture::Create( RageTextureID ID )
if( DriversToTry.empty() )
RageException::Throw( "%s", MOVIE_DRIVERS_EMPTY.GetValue().c_str() );
RageMovieTexture *ret = NULL;
RageMovieTexture *ret = nullptr;
FOREACH_CONST( RString, DriversToTry, Driver )
for (RString const &Driver : DriversToTry)
{
LOG->Trace( "Initializing driver: %s", Driver->c_str() );
RageDriver *pDriverBase = RageMovieTextureDriver::m_pDriverList.Create( *Driver );
char const * driverString = Driver.c_str();
LOG->Trace( "Initializing driver: %s", driverString );
RageDriver *pDriverBase = RageMovieTextureDriver::m_pDriverList.Create( Driver );
if( pDriverBase == NULL )
if( pDriverBase == nullptr )
{
LOG->Trace( "Unknown movie driver name: %s", Driver->c_str() );
LOG->Trace( "Unknown movie driver name: %s", driverString );
continue;
}
RageMovieTextureDriver *pDriver = dynamic_cast<RageMovieTextureDriver *>( pDriverBase );
ASSERT( pDriver != NULL );
ASSERT( pDriver != nullptr );
RString sError;
ret = pDriver->Create( ID, sError );
delete pDriver;
if( ret == NULL )
if( ret == nullptr )
{
LOG->Trace( "Couldn't load driver %s: %s", Driver->c_str(), sError.c_str() );
LOG->Trace( "Couldn't load driver %s: %s", driverString, sError.c_str() );
SAFE_DELETE( ret );
continue;
}
LOG->Trace( "Created movie texture \"%s\" with driver \"%s\"",
ID.filename.c_str(), Driver->c_str() );
ID.filename.c_str(), driverString );
break;
}
if ( !ret )
File diff suppressed because it is too large Load Diff
@@ -13,13 +13,13 @@ struct __declspec(uuid("{71771540-2017-11cf-ae26-0020afd79767}")) CLSID_TextureR
static HRESULT CBV_ret;
CTextureRenderer::CTextureRenderer():
CBaseVideoRenderer(__uuidof(CLSID_TextureRenderer),
NAME("Texture Renderer"), NULL, &CBV_ret),
NAME("Texture Renderer"), nullptr, &CBV_ret),
m_OneFrameDecoded( "m_OneFrameDecoded", 0 )
{
if( FAILED(CBV_ret) )
RageException::Throw( hr_ssprintf(CBV_ret, "Could not create texture renderer object!") );
m_pTexture = NULL;
m_pTexture = nullptr;
}
CTextureRenderer::~CTextureRenderer()
@@ -69,9 +69,9 @@ void CTextureRenderer::SetRenderTarget( MovieTexture_DShow* pTexture )
// DoRenderSample: A sample has been delivered. Copy it.
HRESULT CTextureRenderer::DoRenderSample( IMediaSample * pSample )
{
if( m_pTexture == NULL )
if( m_pTexture == nullptr )
{
LOG->Warn( "DoRenderSample called while m_pTexture was NULL!" );
LOG->Warn( "DoRenderSample called while m_pTexture was nullptr!" );
return S_OK;
}
+25 -25
View File
@@ -109,8 +109,8 @@ MovieDecoder_FFMpeg::MovieDecoder_FFMpeg()
{
FixLilEndian();
m_fctx = NULL;
m_pStream = NULL;
m_fctx = nullptr;
m_pStream = nullptr;
m_iCurrentPacketOffset = -1;
m_Frame = avcodec::av_frame_alloc();
@@ -127,21 +127,21 @@ MovieDecoder_FFMpeg::~MovieDecoder_FFMpeg()
if (m_swsctx)
{
avcodec::sws_freeContext(m_swsctx);
m_swsctx = NULL;
m_swsctx = nullptr;
}
if (m_avioContext != NULL )
if (m_avioContext != nullptr )
{
RageFile *file = (RageFile *)m_avioContext->opaque;
file->Close();
delete file;
avcodec::av_free(m_avioContext);
}
if ( m_buffer != NULL )
if ( m_buffer != nullptr )
{
avcodec::av_free(m_buffer);
}
#if LIBAVCODEC_VERSION_MAJOR >= 58
if ( m_pStreamCodec != NULL)
if ( m_pStreamCodec != nullptr)
{
avcodec::avcodec_free_context(&m_pStreamCodec);
}
@@ -156,9 +156,9 @@ void MovieDecoder_FFMpeg::Init()
m_iFrameNumber = -1; /* decode one frame and you're on the 0th */
m_fTimestampOffset = 0;
m_fLastFrame = 0;
m_swsctx = NULL;
m_avioContext = NULL;
m_buffer = NULL;
m_swsctx = nullptr;
m_avioContext = nullptr;
m_buffer = nullptr;
if( m_iCurrentPacketOffset != -1 )
{
@@ -277,7 +277,7 @@ int MovieDecoder_FFMpeg::DecodePacket( float fTargetTime )
int len;
/* Hack: we need to send size = 0 to flush frames at the end, but we have
* to give it a buffer to read from since it tries to read anyway. */
m_Packet.data = m_Packet.size ? m_Packet.data : NULL;
m_Packet.data = m_Packet.size ? m_Packet.data : nullptr;
#if LIBAVCODEC_VERSION_MAJOR < 58
len = avcodec::avcodec_decode_video2(
m_pStreamCodec,
@@ -360,13 +360,13 @@ void MovieDecoder_FFMpeg::GetFrame( RageSurface *pSurface )
* XXX 2: The problem of doing this in Open() is that m_AVTexfmt is not
* already initialized with its correct value.
*/
if( m_swsctx == NULL )
if( m_swsctx == nullptr )
{
m_swsctx = avcodec::sws_getCachedContext( m_swsctx,
GetWidth(), GetHeight(), m_pStreamCodec->pix_fmt,
GetWidth(), GetHeight(), m_AVTexfmt,
sws_flags, NULL, NULL, NULL );
if( m_swsctx == NULL )
sws_flags, nullptr, nullptr, nullptr );
if( m_swsctx == nullptr )
{
LOG->Warn("Cannot initialize sws conversion context for (%d,%d) %d->%d", GetWidth(), GetHeight(), m_pStreamCodec->pix_fmt, m_AVTexfmt);
return;
@@ -449,24 +449,24 @@ RString MovieDecoder_FFMpeg::Open( RString sFile )
}
m_buffer = (unsigned char *)avcodec::av_malloc(STEPMANIA_FFMPEG_BUFFER_SIZE);
m_avioContext = avcodec::avio_alloc_context(m_buffer, STEPMANIA_FFMPEG_BUFFER_SIZE, 0, f, AVIORageFile_ReadPacket, NULL, AVIORageFile_Seek);
m_avioContext = avcodec::avio_alloc_context(m_buffer, STEPMANIA_FFMPEG_BUFFER_SIZE, 0, f, AVIORageFile_ReadPacket, nullptr, AVIORageFile_Seek);
m_fctx->pb = m_avioContext;
int ret = avcodec::avformat_open_input( &m_fctx, sFile.c_str(), NULL, NULL );
int ret = avcodec::avformat_open_input( &m_fctx, sFile.c_str(), nullptr, nullptr );
if( ret < 0 )
return RString( averr_ssprintf(ret, "AVCodec: Couldn't open \"%s\"", sFile.c_str()) );
ret = avcodec::avformat_find_stream_info( m_fctx, NULL );
ret = avcodec::avformat_find_stream_info( m_fctx, nullptr );
if( ret < 0 )
return RString( averr_ssprintf(ret, "AVCodec (%s): Couldn't find codec parameters", sFile.c_str()) );
int stream_idx = avcodec::av_find_best_stream( m_fctx, avcodec::AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0 );
int stream_idx = avcodec::av_find_best_stream( m_fctx, avcodec::AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0 );
if ( stream_idx < 0 ||
static_cast<unsigned int>(stream_idx) >= m_fctx->nb_streams ||
m_fctx->streams[stream_idx] == NULL )
m_fctx->streams[stream_idx] == nullptr )
return "Couldn't find any video streams";
m_pStream = m_fctx->streams[stream_idx];
#if LIBAVCODEC_VERSION_MAJOR >= 58
m_pStreamCodec = avcodec::avcodec_alloc_context3(NULL);
m_pStreamCodec = avcodec::avcodec_alloc_context3(nullptr);
if (avcodec::avcodec_parameters_to_context(m_pStreamCodec, m_pStream->codecpar) < 0)
return ssprintf("Could not get context from parameters");
#else
@@ -490,12 +490,12 @@ RString MovieDecoder_FFMpeg::OpenCodec()
{
Init();
ASSERT( m_pStream != NULL );
ASSERT( m_pStream != nullptr );
if( m_pStreamCodec->codec )
avcodec::avcodec_close( m_pStreamCodec );
avcodec::AVCodec *pCodec = avcodec::avcodec_find_decoder( m_pStreamCodec->codec_id );
if( pCodec == NULL )
if( pCodec == nullptr )
return ssprintf( "Couldn't find decoder %i", m_pStreamCodec->codec_id );
m_pStreamCodec->workaround_bugs = 1;
@@ -509,10 +509,10 @@ RString MovieDecoder_FFMpeg::OpenCodec()
LOG->Trace("Opening codec %s", pCodec->name );
int ret = avcodec::avcodec_open2( m_pStreamCodec, pCodec, NULL );
int ret = avcodec::avcodec_open2( m_pStreamCodec, pCodec, nullptr );
if( ret < 0 )
return RString( averr_ssprintf(ret, "Couldn't open codec \"%s\"", pCodec->name) );
ASSERT( m_pStreamCodec->codec != NULL );
ASSERT( m_pStreamCodec->codec != nullptr );
return RString();
}
@@ -522,13 +522,13 @@ void MovieDecoder_FFMpeg::Close()
if( m_pStream && m_pStreamCodec->codec )
{
avcodec::avcodec_close( m_pStreamCodec );
m_pStream = NULL;
m_pStream = nullptr;
}
if( m_fctx )
{
avcodec::avformat_close_input( &m_fctx );
m_fctx = NULL;
m_fctx = nullptr;
}
Init();
+23 -23
View File
@@ -25,11 +25,11 @@ MovieTexture_Generic::MovieTexture_Generic( RageTextureID ID, MovieDecoder *pDec
m_pDecoder = pDecoder;
m_uTexHandle = 0;
m_pRenderTarget = NULL;
m_pTextureIntermediate = NULL;
m_pRenderTarget = nullptr;
m_pTextureIntermediate = nullptr;
m_bLoop = true;
m_pSurface = NULL;
m_pTextureLock = NULL;
m_pSurface = nullptr;
m_pTextureLock = nullptr;
m_ImageWaiting = FRAME_NONE;
m_fRate = 1;
m_bWantRewind = false;
@@ -88,10 +88,10 @@ MovieTexture_Generic::~MovieTexture_Generic()
void MovieTexture_Generic::DestroyTexture()
{
delete m_pSurface;
m_pSurface = NULL;
m_pSurface = nullptr;
delete m_pTextureLock;
m_pTextureLock = NULL;
m_pTextureLock = nullptr;
if( m_uTexHandle )
{
@@ -100,9 +100,9 @@ void MovieTexture_Generic::DestroyTexture()
}
delete m_pRenderTarget;
m_pRenderTarget = NULL;
m_pRenderTarget = nullptr;
delete m_pTextureIntermediate;
m_pTextureIntermediate = NULL;
m_pTextureIntermediate = nullptr;
}
class RageMovieTexture_Generic_Intermediate : public RageTexture
@@ -162,7 +162,7 @@ private:
m_SurfaceFormat.Mask[0],
m_SurfaceFormat.Mask[1],
m_SurfaceFormat.Mask[2],
m_SurfaceFormat.Mask[3], NULL, 1 );
m_SurfaceFormat.Mask[3], nullptr, 1 );
m_uTexHandle = DISPLAY->CreateTexture( m_PixFmt, pSurface, false );
delete pSurface;
@@ -176,16 +176,16 @@ private:
void MovieTexture_Generic::Invalidate()
{
m_uTexHandle = 0;
if( m_pTextureIntermediate != NULL )
if( m_pTextureIntermediate != nullptr )
m_pTextureIntermediate->Invalidate();
}
void MovieTexture_Generic::CreateTexture()
{
if( m_uTexHandle || m_pRenderTarget != NULL )
if( m_uTexHandle || m_pRenderTarget != nullptr )
return;
CHECKPOINT_M("About to create a generic texture.");
CHECKPOINT;
m_iSourceWidth = m_pDecoder->GetWidth();
m_iSourceHeight = m_pDecoder->GetHeight();
@@ -207,18 +207,18 @@ void MovieTexture_Generic::CreateTexture()
m_iTextureWidth = power_of_two( m_iImageWidth );
m_iTextureHeight = power_of_two( m_iImageHeight );
MovieDecoderPixelFormatYCbCr fmt = PixelFormatYCbCr_Invalid;
if( m_pSurface == NULL )
if( m_pSurface == nullptr )
{
ASSERT( m_pTextureLock == NULL );
ASSERT( m_pTextureLock == nullptr );
if( g_bMovieTextureDirectUpdates )
m_pTextureLock = DISPLAY->CreateTextureLock();
m_pSurface = m_pDecoder->CreateCompatibleSurface( m_iImageWidth, m_iImageHeight,
TEXTUREMAN->GetPrefs().m_iMovieColorDepth == 32, fmt );
if( m_pTextureLock != NULL )
if( m_pTextureLock != nullptr )
{
delete [] m_pSurface->pixels;
m_pSurface->pixels = NULL;
m_pSurface->pixels = nullptr;
}
}
@@ -447,22 +447,22 @@ void MovieTexture_Generic::UpdateFrame()
/* Just in case we were invalidated: */
CreateTexture();
if( m_pTextureLock != NULL )
if( m_pTextureLock != nullptr )
{
int iHandle = m_pTextureIntermediate != NULL? m_pTextureIntermediate->GetTexHandle(): this->GetTexHandle();
int iHandle = m_pTextureIntermediate != nullptr? m_pTextureIntermediate->GetTexHandle(): this->GetTexHandle();
m_pTextureLock->Lock( iHandle, m_pSurface );
}
m_pDecoder->GetFrame( m_pSurface );
if( m_pTextureLock != NULL )
if( m_pTextureLock != nullptr )
m_pTextureLock->Unlock( m_pSurface, true );
if( m_pRenderTarget != NULL )
if( m_pRenderTarget != nullptr )
{
CHECKPOINT_M( "About to upload the texture.");
/* If we have no m_pTextureLock, we still have to upload the texture. */
if( m_pTextureLock == NULL )
if( m_pTextureLock == nullptr )
{
DISPLAY->UpdateTexture(
m_pTextureIntermediate->GetTexHandle(),
@@ -476,7 +476,7 @@ void MovieTexture_Generic::UpdateFrame()
}
else
{
if( m_pTextureLock == NULL )
if( m_pTextureLock == nullptr )
{
DISPLAY->UpdateTexture(
m_uTexHandle,
@@ -520,7 +520,7 @@ void MovieTexture_Generic::SetPosition( float fSeconds )
unsigned MovieTexture_Generic::GetTexHandle() const
{
if( m_pRenderTarget != NULL )
if( m_pRenderTarget != nullptr )
return m_pRenderTarget->GetTexHandle();
return m_uTexHandle;
+4 -4
View File
@@ -3,7 +3,7 @@
void DriverList::Add( const istring &sName, CreateRageDriverFn pfn )
{
if( m_pRegistrees == NULL )
if( m_pRegistrees == nullptr )
m_pRegistrees = new map<istring, CreateRageDriverFn>;
ASSERT( m_pRegistrees->find(sName) == m_pRegistrees->end() );
@@ -12,12 +12,12 @@ void DriverList::Add( const istring &sName, CreateRageDriverFn pfn )
RageDriver *DriverList::Create( const RString &sDriverName )
{
if( m_pRegistrees == NULL )
return NULL;
if( m_pRegistrees == nullptr )
return nullptr;
map<istring, CreateRageDriverFn>::const_iterator iter = m_pRegistrees->find( istring(sDriverName) );
if( iter == m_pRegistrees->end() )
return NULL;
return nullptr;
return (iter->second)();
}
+7 -7
View File
@@ -6,13 +6,13 @@
#define ALSA_PCM_NEW_SW_PARAMS_API
#include <alsa/asoundlib.h>
static void *Handle = NULL;
static void *Handle = nullptr;
#include "RageUtil.h"
#include "ALSA9Dynamic.h"
/* foo_f dfoo = NULL */
#define FUNC(ret, name, proto) name##_f d##name = NULL
/* foo_f dfoo = nullptr */
#define FUNC(ret, name, proto) name##_f d##name = nullptr
#include "ALSA9Functions.h"
#undef FUNC
@@ -31,10 +31,10 @@ RString LoadALSA()
if( !IsADirectory("/rootfs/proc/asound/") )
return "/proc/asound/ does not exist";
ASSERT( Handle == NULL );
ASSERT( Handle == nullptr );
Handle = dlopen( lib, RTLD_NOW );
if( Handle == NULL )
if( Handle == nullptr )
return ssprintf("dlopen(%s): %s", lib.c_str(), dlerror());
RString error;
@@ -62,8 +62,8 @@ void UnloadALSA()
{
if( Handle )
dlclose( Handle );
Handle = NULL;
#define FUNC(ret, name, proto) d##name = NULL;
Handle = nullptr;
#define FUNC(ret, name, proto) d##name = nullptr;
#include "ALSA9Functions.h"
#undef FUNC
}
+462 -462
View File
@@ -1,462 +1,462 @@
#include "global.h"
#include "RageLog.h"
#include "RageUtil.h"
#include "ALSA9Helpers.h"
#include "ALSA9Dynamic.h"
#include "PrefsManager.h"
/* int err; must be defined before using this macro */
#define ALSA_CHECK(x) \
if ( err < 0 ) { LOG->Info("ALSA: %s: %s", x, dsnd_strerror(err)); return false; }
#define ALSA_ASSERT(x) \
if (err < 0) { LOG->Warn("ALSA: %s: %s", x, dsnd_strerror(err)); }
bool Alsa9Buf::SetHWParams()
{
int err;
if( dsnd_pcm_state(pcm) == SND_PCM_STATE_PREPARED )
dsnd_pcm_drop( pcm );
if( dsnd_pcm_state(pcm) != SND_PCM_STATE_OPEN )
{
/* Reset the stream to SND_PCM_STATE_OPEN. */
err = dsnd_pcm_hw_free( pcm );
ALSA_ASSERT("dsnd_pcm_hw_free");
}
// ASSERT_M( dsnd_pcm_state(pcm) == SND_PCM_STATE_OPEN, ssprintf("(%s)", dsnd_pcm_state_name(dsnd_pcm_state(pcm))) );
/* allocate the hardware parameters structure */
snd_pcm_hw_params_t *hwparams;
dsnd_pcm_hw_params_alloca( &hwparams );
err = dsnd_pcm_hw_params_any(pcm, hwparams);
ALSA_CHECK("dsnd_pcm_hw_params_any");
/* Set to interleaved mmap mode. */
err = dsnd_pcm_hw_params_set_access(pcm, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED);
ALSA_CHECK("dsnd_pcm_hw_params_set_access");
/* Set the PCM format: signed 16bit, native endian. */
err = dsnd_pcm_hw_params_set_format(pcm, hwparams, SND_PCM_FORMAT_S16);
ALSA_CHECK("dsnd_pcm_hw_params_set_format");
/* Set the number of channels. */
err = dsnd_pcm_hw_params_set_channels(pcm, hwparams, 2);
ALSA_CHECK("dsnd_pcm_hw_params_set_channels");
/* Set the sample rate. */
err = dsnd_pcm_hw_params_set_rate_near(pcm, hwparams, &samplerate, 0);
ALSA_CHECK("dsnd_pcm_hw_params_set_rate_near");
/* Set the buffersize to the writeahead, and then copy back the actual value
* we got. */
writeahead = preferred_writeahead;
err = dsnd_pcm_hw_params_set_buffer_size_near( pcm, hwparams, &writeahead );
ALSA_CHECK("dsnd_pcm_hw_params_set_buffer_size_near");
/* The period size is roughly equivalent to what we call the chunksize. */
int dir = 0;
chunksize = preferred_chunksize;
err = dsnd_pcm_hw_params_set_period_size_near( pcm, hwparams, &chunksize, &dir );
ALSA_CHECK("dsnd_pcm_hw_params_set_period_size_near");
// LOG->Info("asked for %i period, got %i", chunksize, period_size);
/* write the hardware parameters to the device */
err = dsnd_pcm_hw_params( pcm, hwparams );
ALSA_CHECK("dsnd_pcm_hw_params");
return true;
}
bool Alsa9Buf::SetSWParams()
{
snd_pcm_sw_params_t *swparams;
dsnd_pcm_sw_params_alloca( &swparams );
dsnd_pcm_sw_params_current( pcm, swparams );
int err = dsnd_pcm_sw_params_set_xfer_align( pcm, swparams, 1 );
ALSA_ASSERT("dsnd_pcm_sw_params_set_xfer_align");
/* chunksize has been set to the period size. Set avail_min to the period
* size, too, so poll() wakes up once per chunk. */
err = dsnd_pcm_sw_params_set_avail_min( pcm, swparams, chunksize );
ALSA_ASSERT("dsnd_pcm_sw_params_set_avail_min");
/* If this fails, we might have bound dsnd_pcm_sw_params_set_avail_min to
* the old SW API. */
// ASSERT( err <= 0 );
/* Disable SND_PCM_STATE_XRUN. */
snd_pcm_uframes_t boundary = 0;
err = dsnd_pcm_sw_params_get_boundary( swparams, &boundary );
ALSA_ASSERT("dsnd_pcm_sw_params_get_boundary");
err = dsnd_pcm_sw_params_set_stop_threshold( pcm, swparams, boundary );
ALSA_ASSERT("dsnd_pcm_sw_params_set_stop_threshold");
err = dsnd_pcm_sw_params(pcm, swparams);
ALSA_ASSERT("dsnd_pcm_sw_params");
err = dsnd_pcm_prepare(pcm);
ALSA_ASSERT("dsnd_pcm_prepare");
return true;
}
void Alsa9Buf::ErrorHandler(const char *file, int line, const char *function, int err, const char *fmt, ...)
{
va_list va;
va_start( va, fmt );
RString str = vssprintf(fmt, va);
va_end( va );
if( err )
str += ssprintf( " (%s)", dsnd_strerror(err) );
/* Annoying: these happen both normally (eg. "out of memory" when allocating too many PCM
* slots) and abnormally, and there's no way to tell which is which. I don't want to
* pollute the warning output. */
LOG->Trace( "ALSA error: %s:%i %s: %s", file, line, function, str.c_str() );
}
void Alsa9Buf::InitializeErrorHandler()
{
dsnd_lib_error_set_handler( ErrorHandler );
}
static RString DeviceName()
{
if( !PREFSMAN->m_iSoundDevice.Get().empty() )
return PREFSMAN->m_iSoundDevice;
return "default";
}
void Alsa9Buf::GetSoundCardDebugInfo()
{
static bool done = false;
if( done )
return;
done = true;
if( DoesFileExist("/rootfs/proc/asound/version") )
{
RString sVersion;
GetFileContents( "/rootfs/proc/asound/version", sVersion, true );
LOG->Info( "ALSA: %s", sVersion.c_str() );
}
InitializeErrorHandler();
int card = -1;
while( dsnd_card_next( &card ) >= 0 && card >= 0 )
{
const RString id = ssprintf( "hw:%d", card );
snd_ctl_t *handle;
int err;
err = dsnd_ctl_open( &handle, id, 0 );
if ( err < 0 )
{
LOG->Info( "Couldn't open card #%i (\"%s\") to probe: %s", card, id.c_str(), dsnd_strerror(err) );
continue;
}
snd_ctl_card_info_t *info;
dsnd_ctl_card_info_alloca(&info);
err = dsnd_ctl_card_info( handle, info );
if ( err < 0 )
{
LOG->Info( "Couldn't get card info for card #%i (\"%s\"): %s", card, id.c_str(), dsnd_strerror(err) );
dsnd_ctl_close( handle );
continue;
}
int dev = -1;
while ( dsnd_ctl_pcm_next_device( handle, &dev ) >= 0 && dev >= 0 )
{
snd_pcm_info_t *pcminfo;
dsnd_pcm_info_alloca(&pcminfo);
dsnd_pcm_info_set_device(pcminfo, dev);
dsnd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK);
err = dsnd_ctl_pcm_info(handle, pcminfo);
if ( err < 0 )
{
if (err != -ENOENT)
LOG->Info("dsnd_ctl_pcm_info(%i) (%s) failed: %s", card, id.c_str(), dsnd_strerror(err));
continue;
}
LOG->Info( "ALSA Driver: %i: %s [%s], device %i: %s [%s], %i/%i subdevices avail",
card, dsnd_ctl_card_info_get_name(info), dsnd_ctl_card_info_get_id(info), dev,
dsnd_pcm_info_get_id(pcminfo), dsnd_pcm_info_get_name(pcminfo),
dsnd_pcm_info_get_subdevices_avail(pcminfo),
dsnd_pcm_info_get_subdevices_count(pcminfo) );
}
dsnd_ctl_close(handle);
}
if( card == 0 )
LOG->Info( "No ALSA sound cards were found.");
if( !PREFSMAN->m_iSoundDevice.Get().empty() )
LOG->Info( "ALSA device overridden to \"%s\"", PREFSMAN->m_iSoundDevice.Get().c_str() );
}
Alsa9Buf::Alsa9Buf()
{
samplerate = 44100;
samplebits = 16;
last_cursor_pos = 0;
preferred_writeahead = 8192;
preferred_chunksize = 1024;
pcm = NULL;
}
RString Alsa9Buf::Init( int channels_,
int iWriteahead,
int iChunkSize,
int iSampleRate )
{
channels = channels_;
preferred_writeahead = iWriteahead;
preferred_chunksize = iChunkSize;
if( iSampleRate == 0 )
samplerate = 44100;
else
samplerate = iSampleRate;
GetSoundCardDebugInfo();
InitializeErrorHandler();
/* Open the device. */
int err;
err = dsnd_pcm_open( &pcm, DeviceName(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK );
if( err < 0 )
return ssprintf( "dsnd_pcm_open(%s): %s", DeviceName().c_str(), dsnd_strerror(err) );
if( !SetHWParams() )
{
CHECKPOINT;
return "SetHWParams failed";
}
SetSWParams();
LOG->Info( "ALSA: Mixing at %ihz", samplerate );
if( preferred_writeahead != writeahead )
LOG->Info( "ALSA: writeahead adjusted from %u to %u", (unsigned) preferred_writeahead, (unsigned) writeahead );
if( preferred_chunksize != chunksize )
LOG->Info( "ALSA: chunksize adjusted from %u to %u", (unsigned) preferred_chunksize, (unsigned) chunksize );
return "";
}
Alsa9Buf::~Alsa9Buf()
{
if( pcm != NULL )
dsnd_pcm_close( pcm );
}
/* Don't fill the buffer any more than than "writeahead" frames. Prefer to
* write "chunksize" frames at a time. (These numbers are hints; if the
* hardware parameters require it, they can be ignored.) */
int Alsa9Buf::GetNumFramesToFill()
{
/* Make sure we can write ahead at least two chunks. Otherwise, we'll only
* fill one chunk ahead, and underrun. */
int ActualWriteahead = max( writeahead, chunksize*2 );
snd_pcm_sframes_t avail_frames = dsnd_pcm_avail_update(pcm);
int total_frames = writeahead;
if( avail_frames > total_frames )
{
/* underrun */
const int size = avail_frames-total_frames;
LOG->Trace("underrun (%i frames)", size);
int large_skip_threshold = 2 * samplerate;
/* For small underruns, ignore them. We'll return the maximum writeahead and ALSA will
* just discard the data. GetPosition will return consistent values during this time,
* so arrows will continue to scroll smoothly until the music catches up. */
if( size >= large_skip_threshold )
{
/* It's a large skip. Catch up. If we fall too far behind, the sound thread will
* be decoding as fast as it can, which will steal too many cycles from the rendering
* thread. */
dsnd_pcm_forward( pcm, size );
}
}
if( avail_frames < 0 )
avail_frames = dsnd_pcm_avail_update(pcm);
if( avail_frames < 0 )
{
LOG->Trace( "RageSoundDriver_ALSA9::GetData: dsnd_pcm_avail_update: %s", dsnd_strerror(avail_frames) );
return 0;
}
/* Number of frames that have data: */
const snd_pcm_sframes_t filled_frames = max( 0l, total_frames - avail_frames );
/* Number of frames that don't have data, that are within the writeahead: */
snd_pcm_sframes_t unfilled_frames = clamp( ActualWriteahead - filled_frames, 0l, (snd_pcm_sframes_t)ActualWriteahead );
// LOG->Trace( "total_fr: %i; avail_fr: %i; filled_fr: %i; ActualWr %i; chunksize %i; unfilled_frames %i ",
// total_frames, avail_frames, filled_frames, ActualWriteahead, chunksize, unfilled_frames );
/* If we have less than a chunk empty, don't fill at all. Otherwise, we'll
* spend a lot of CPU filling in partial chunks, instead of waiting for some
* sound to play and then filling a whole chunk at once. */
if( unfilled_frames < (int) chunksize )
return 0;
return chunksize;
}
bool Alsa9Buf::WaitUntilFramesCanBeFilled( int timeout_ms )
{
int err = dsnd_pcm_wait( pcm, timeout_ms );
/* EINTR is normal; don't warn. */
if( err == -EINTR )
return false;
ALSA_ASSERT("snd_pcm_wait");
return err == 1;
}
void Alsa9Buf::Write( const int16_t *buffer, int frames )
{
/* We should be able to write it all. If we don't, treat it as an error. */
int wrote;
do
{
wrote = dsnd_pcm_mmap_writei( pcm, (const char *) buffer, frames );
}
while( wrote == -EAGAIN );
if( wrote < 0 )
{
LOG->Trace( "RageSoundDriver_ALSA9::GetData: dsnd_pcm_mmap_writei: %s (%i)", dsnd_strerror(wrote), wrote );
return;
}
last_cursor_pos += wrote;
if( wrote < frames )
LOG->Trace("Couldn't write whole buffer? (%i < %i)", wrote, frames );
}
/*
* When the play buffer underruns, subsequent writes to the buffer
* return -EPIPE. When this happens, call Recover() to restart playback.
*/
bool Alsa9Buf::Recover( int r )
{
if( r == -EPIPE )
{
LOG->Trace("RageSound_ALSA9::Recover (prepare)");
int err = dsnd_pcm_prepare(pcm);
ALSA_ASSERT("dsnd_pcm_prepare (Recover)");
return true;
}
if( r == -ESTRPIPE )
{
LOG->Trace("RageSound_ALSA9::Recover (resume)");
int err;
while ((err = dsnd_pcm_resume(pcm)) == -EAGAIN)
usleep(10000); // 10ms
ALSA_ASSERT("dsnd_pcm_resume (Recover)");
return true;
}
return false;
}
int64_t Alsa9Buf::GetPosition() const
{
if( dsnd_pcm_state(pcm) == SND_PCM_STATE_PREPARED )
return last_cursor_pos;
dsnd_pcm_hwsync( pcm );
/* delay is returned in frames */
snd_pcm_sframes_t delay;
int err = dsnd_pcm_delay( pcm, &delay );
ALSA_ASSERT("dsnd_pcm_delay");
return last_cursor_pos - delay;
}
void Alsa9Buf::Play()
{
/* NOP. It'll start playing when it gets some data. */
}
void Alsa9Buf::Stop()
{
dsnd_pcm_drop( pcm );
dsnd_pcm_prepare( pcm );
last_cursor_pos = 0;
}
RString Alsa9Buf::GetHardwareID( RString name )
{
InitializeErrorHandler();
if( name.empty() )
name = DeviceName();
snd_ctl_t *handle;
int err;
err = dsnd_ctl_open( &handle, name, 0 );
if ( err < 0 )
{
LOG->Info( "Couldn't open card \"%s\" to get ID: %s", name.c_str(), dsnd_strerror(err) );
return "???";
}
snd_ctl_card_info_t *info;
dsnd_ctl_card_info_alloca(&info);
err = dsnd_ctl_card_info( handle, info );
RString ret = dsnd_ctl_card_info_get_id( info );
dsnd_ctl_close(handle);
return ret;
}
/*
* (c) 2002-2004 Glenn Maynard, Aaron VonderHaar
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "global.h"
#include "RageLog.h"
#include "RageUtil.h"
#include "ALSA9Helpers.h"
#include "ALSA9Dynamic.h"
#include "PrefsManager.h"
/* int err; must be defined before using this macro */
#define ALSA_CHECK(x) \
if ( err < 0 ) { LOG->Info("ALSA: %s: %s", x, dsnd_strerror(err)); return false; }
#define ALSA_ASSERT(x) \
if (err < 0) { LOG->Warn("ALSA: %s: %s", x, dsnd_strerror(err)); }
bool Alsa9Buf::SetHWParams()
{
int err;
if( dsnd_pcm_state(pcm) == SND_PCM_STATE_PREPARED )
dsnd_pcm_drop( pcm );
if( dsnd_pcm_state(pcm) != SND_PCM_STATE_OPEN )
{
/* Reset the stream to SND_PCM_STATE_OPEN. */
err = dsnd_pcm_hw_free( pcm );
ALSA_ASSERT("dsnd_pcm_hw_free");
}
// ASSERT_M( dsnd_pcm_state(pcm) == SND_PCM_STATE_OPEN, ssprintf("(%s)", dsnd_pcm_state_name(dsnd_pcm_state(pcm))) );
/* allocate the hardware parameters structure */
snd_pcm_hw_params_t *hwparams;
dsnd_pcm_hw_params_alloca( &hwparams );
err = dsnd_pcm_hw_params_any(pcm, hwparams);
ALSA_CHECK("dsnd_pcm_hw_params_any");
/* Set to interleaved mmap mode. */
err = dsnd_pcm_hw_params_set_access(pcm, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED);
ALSA_CHECK("dsnd_pcm_hw_params_set_access");
/* Set the PCM format: signed 16bit, native endian. */
err = dsnd_pcm_hw_params_set_format(pcm, hwparams, SND_PCM_FORMAT_S16);
ALSA_CHECK("dsnd_pcm_hw_params_set_format");
/* Set the number of channels. */
err = dsnd_pcm_hw_params_set_channels(pcm, hwparams, 2);
ALSA_CHECK("dsnd_pcm_hw_params_set_channels");
/* Set the sample rate. */
err = dsnd_pcm_hw_params_set_rate_near(pcm, hwparams, &samplerate, 0);
ALSA_CHECK("dsnd_pcm_hw_params_set_rate_near");
/* Set the buffersize to the writeahead, and then copy back the actual value
* we got. */
writeahead = preferred_writeahead;
err = dsnd_pcm_hw_params_set_buffer_size_near( pcm, hwparams, &writeahead );
ALSA_CHECK("dsnd_pcm_hw_params_set_buffer_size_near");
/* The period size is roughly equivalent to what we call the chunksize. */
int dir = 0;
chunksize = preferred_chunksize;
err = dsnd_pcm_hw_params_set_period_size_near( pcm, hwparams, &chunksize, &dir );
ALSA_CHECK("dsnd_pcm_hw_params_set_period_size_near");
// LOG->Info("asked for %i period, got %i", chunksize, period_size);
/* write the hardware parameters to the device */
err = dsnd_pcm_hw_params( pcm, hwparams );
ALSA_CHECK("dsnd_pcm_hw_params");
return true;
}
bool Alsa9Buf::SetSWParams()
{
snd_pcm_sw_params_t *swparams;
dsnd_pcm_sw_params_alloca( &swparams );
dsnd_pcm_sw_params_current( pcm, swparams );
int err = dsnd_pcm_sw_params_set_xfer_align( pcm, swparams, 1 );
ALSA_ASSERT("dsnd_pcm_sw_params_set_xfer_align");
/* chunksize has been set to the period size. Set avail_min to the period
* size, too, so poll() wakes up once per chunk. */
err = dsnd_pcm_sw_params_set_avail_min( pcm, swparams, chunksize );
ALSA_ASSERT("dsnd_pcm_sw_params_set_avail_min");
/* If this fails, we might have bound dsnd_pcm_sw_params_set_avail_min to
* the old SW API. */
// ASSERT( err <= 0 );
/* Disable SND_PCM_STATE_XRUN. */
snd_pcm_uframes_t boundary = 0;
err = dsnd_pcm_sw_params_get_boundary( swparams, &boundary );
ALSA_ASSERT("dsnd_pcm_sw_params_get_boundary");
err = dsnd_pcm_sw_params_set_stop_threshold( pcm, swparams, boundary );
ALSA_ASSERT("dsnd_pcm_sw_params_set_stop_threshold");
err = dsnd_pcm_sw_params(pcm, swparams);
ALSA_ASSERT("dsnd_pcm_sw_params");
err = dsnd_pcm_prepare(pcm);
ALSA_ASSERT("dsnd_pcm_prepare");
return true;
}
void Alsa9Buf::ErrorHandler(const char *file, int line, const char *function, int err, const char *fmt, ...)
{
va_list va;
va_start( va, fmt );
RString str = vssprintf(fmt, va);
va_end( va );
if( err )
str += ssprintf( " (%s)", dsnd_strerror(err) );
/* Annoying: these happen both normally (eg. "out of memory" when allocating too many PCM
* slots) and abnormally, and there's no way to tell which is which. I don't want to
* pollute the warning output. */
LOG->Trace( "ALSA error: %s:%i %s: %s", file, line, function, str.c_str() );
}
void Alsa9Buf::InitializeErrorHandler()
{
dsnd_lib_error_set_handler( ErrorHandler );
}
static RString DeviceName()
{
if( !PREFSMAN->m_iSoundDevice.Get().empty() )
return PREFSMAN->m_iSoundDevice;
return "default";
}
void Alsa9Buf::GetSoundCardDebugInfo()
{
static bool done = false;
if( done )
return;
done = true;
if( DoesFileExist("/rootfs/proc/asound/version") )
{
RString sVersion;
GetFileContents( "/rootfs/proc/asound/version", sVersion, true );
LOG->Info( "ALSA: %s", sVersion.c_str() );
}
InitializeErrorHandler();
int card = -1;
while( dsnd_card_next( &card ) >= 0 && card >= 0 )
{
const RString id = ssprintf( "hw:%d", card );
snd_ctl_t *handle;
int err;
err = dsnd_ctl_open( &handle, id, 0 );
if ( err < 0 )
{
LOG->Info( "Couldn't open card #%i (\"%s\") to probe: %s", card, id.c_str(), dsnd_strerror(err) );
continue;
}
snd_ctl_card_info_t *info;
dsnd_ctl_card_info_alloca(&info);
err = dsnd_ctl_card_info( handle, info );
if ( err < 0 )
{
LOG->Info( "Couldn't get card info for card #%i (\"%s\"): %s", card, id.c_str(), dsnd_strerror(err) );
dsnd_ctl_close( handle );
continue;
}
int dev = -1;
while ( dsnd_ctl_pcm_next_device( handle, &dev ) >= 0 && dev >= 0 )
{
snd_pcm_info_t *pcminfo;
dsnd_pcm_info_alloca(&pcminfo);
dsnd_pcm_info_set_device(pcminfo, dev);
dsnd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK);
err = dsnd_ctl_pcm_info(handle, pcminfo);
if ( err < 0 )
{
if (err != -ENOENT)
LOG->Info("dsnd_ctl_pcm_info(%i) (%s) failed: %s", card, id.c_str(), dsnd_strerror(err));
continue;
}
LOG->Info( "ALSA Driver: %i: %s [%s], device %i: %s [%s], %i/%i subdevices avail",
card, dsnd_ctl_card_info_get_name(info), dsnd_ctl_card_info_get_id(info), dev,
dsnd_pcm_info_get_id(pcminfo), dsnd_pcm_info_get_name(pcminfo),
dsnd_pcm_info_get_subdevices_avail(pcminfo),
dsnd_pcm_info_get_subdevices_count(pcminfo) );
}
dsnd_ctl_close(handle);
}
if( card == 0 )
LOG->Info( "No ALSA sound cards were found.");
if( !PREFSMAN->m_iSoundDevice.Get().empty() )
LOG->Info( "ALSA device overridden to \"%s\"", PREFSMAN->m_iSoundDevice.Get().c_str() );
}
Alsa9Buf::Alsa9Buf()
{
samplerate = 44100;
samplebits = 16;
last_cursor_pos = 0;
preferred_writeahead = 8192;
preferred_chunksize = 1024;
pcm = nullptr;
}
RString Alsa9Buf::Init( int channels_,
int iWriteahead,
int iChunkSize,
int iSampleRate )
{
channels = channels_;
preferred_writeahead = iWriteahead;
preferred_chunksize = iChunkSize;
if( iSampleRate == 0 )
samplerate = 44100;
else
samplerate = iSampleRate;
GetSoundCardDebugInfo();
InitializeErrorHandler();
/* Open the device. */
int err;
err = dsnd_pcm_open( &pcm, DeviceName(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK );
if( err < 0 )
return ssprintf( "dsnd_pcm_open(%s): %s", DeviceName().c_str(), dsnd_strerror(err) );
if( !SetHWParams() )
{
CHECKPOINT;
return "SetHWParams failed";
}
SetSWParams();
LOG->Info( "ALSA: Mixing at %ihz", samplerate );
if( preferred_writeahead != writeahead )
LOG->Info( "ALSA: writeahead adjusted from %u to %u", (unsigned) preferred_writeahead, (unsigned) writeahead );
if( preferred_chunksize != chunksize )
LOG->Info( "ALSA: chunksize adjusted from %u to %u", (unsigned) preferred_chunksize, (unsigned) chunksize );
return "";
}
Alsa9Buf::~Alsa9Buf()
{
if( pcm != nullptr )
dsnd_pcm_close( pcm );
}
/* Don't fill the buffer any more than than "writeahead" frames. Prefer to
* write "chunksize" frames at a time. (These numbers are hints; if the
* hardware parameters require it, they can be ignored.) */
int Alsa9Buf::GetNumFramesToFill()
{
/* Make sure we can write ahead at least two chunks. Otherwise, we'll only
* fill one chunk ahead, and underrun. */
int ActualWriteahead = max( writeahead, chunksize*2 );
snd_pcm_sframes_t avail_frames = dsnd_pcm_avail_update(pcm);
int total_frames = writeahead;
if( avail_frames > total_frames )
{
/* underrun */
const int size = avail_frames-total_frames;
LOG->Trace("underrun (%i frames)", size);
int large_skip_threshold = 2 * samplerate;
/* For small underruns, ignore them. We'll return the maximum writeahead and ALSA will
* just discard the data. GetPosition will return consistent values during this time,
* so arrows will continue to scroll smoothly until the music catches up. */
if( size >= large_skip_threshold )
{
/* It's a large skip. Catch up. If we fall too far behind, the sound thread will
* be decoding as fast as it can, which will steal too many cycles from the rendering
* thread. */
dsnd_pcm_forward( pcm, size );
}
}
if( avail_frames < 0 )
avail_frames = dsnd_pcm_avail_update(pcm);
if( avail_frames < 0 )
{
LOG->Trace( "RageSoundDriver_ALSA9::GetData: dsnd_pcm_avail_update: %s", dsnd_strerror(avail_frames) );
return 0;
}
/* Number of frames that have data: */
const snd_pcm_sframes_t filled_frames = max( 0l, total_frames - avail_frames );
/* Number of frames that don't have data, that are within the writeahead: */
snd_pcm_sframes_t unfilled_frames = clamp( ActualWriteahead - filled_frames, 0l, (snd_pcm_sframes_t)ActualWriteahead );
// LOG->Trace( "total_fr: %i; avail_fr: %i; filled_fr: %i; ActualWr %i; chunksize %i; unfilled_frames %i ",
// total_frames, avail_frames, filled_frames, ActualWriteahead, chunksize, unfilled_frames );
/* If we have less than a chunk empty, don't fill at all. Otherwise, we'll
* spend a lot of CPU filling in partial chunks, instead of waiting for some
* sound to play and then filling a whole chunk at once. */
if( unfilled_frames < (int) chunksize )
return 0;
return chunksize;
}
bool Alsa9Buf::WaitUntilFramesCanBeFilled( int timeout_ms )
{
int err = dsnd_pcm_wait( pcm, timeout_ms );
/* EINTR is normal; don't warn. */
if( err == -EINTR )
return false;
ALSA_ASSERT("snd_pcm_wait");
return err == 1;
}
void Alsa9Buf::Write( const int16_t *buffer, int frames )
{
/* We should be able to write it all. If we don't, treat it as an error. */
int wrote;
do
{
wrote = dsnd_pcm_mmap_writei( pcm, (const char *) buffer, frames );
}
while( wrote == -EAGAIN );
if( wrote < 0 )
{
LOG->Trace( "RageSoundDriver_ALSA9::GetData: dsnd_pcm_mmap_writei: %s (%i)", dsnd_strerror(wrote), wrote );
return;
}
last_cursor_pos += wrote;
if( wrote < frames )
LOG->Trace("Couldn't write whole buffer? (%i < %i)", wrote, frames );
}
/*
* When the play buffer underruns, subsequent writes to the buffer
* return -EPIPE. When this happens, call Recover() to restart playback.
*/
bool Alsa9Buf::Recover( int r )
{
if( r == -EPIPE )
{
LOG->Trace("RageSound_ALSA9::Recover (prepare)");
int err = dsnd_pcm_prepare(pcm);
ALSA_ASSERT("dsnd_pcm_prepare (Recover)");
return true;
}
if( r == -ESTRPIPE )
{
LOG->Trace("RageSound_ALSA9::Recover (resume)");
int err;
while ((err = dsnd_pcm_resume(pcm)) == -EAGAIN)
usleep(10000); // 10ms
ALSA_ASSERT("dsnd_pcm_resume (Recover)");
return true;
}
return false;
}
int64_t Alsa9Buf::GetPosition() const
{
if( dsnd_pcm_state(pcm) == SND_PCM_STATE_PREPARED )
return last_cursor_pos;
dsnd_pcm_hwsync( pcm );
/* delay is returned in frames */
snd_pcm_sframes_t delay;
int err = dsnd_pcm_delay( pcm, &delay );
ALSA_ASSERT("dsnd_pcm_delay");
return last_cursor_pos - delay;
}
void Alsa9Buf::Play()
{
/* NOP. It'll start playing when it gets some data. */
}
void Alsa9Buf::Stop()
{
dsnd_pcm_drop( pcm );
dsnd_pcm_prepare( pcm );
last_cursor_pos = 0;
}
RString Alsa9Buf::GetHardwareID( RString name )
{
InitializeErrorHandler();
if( name.empty() )
name = DeviceName();
snd_ctl_t *handle;
int err;
err = dsnd_ctl_open( &handle, name, 0 );
if ( err < 0 )
{
LOG->Info( "Couldn't open card \"%s\" to get ID: %s", name.c_str(), dsnd_strerror(err) );
return "???";
}
snd_ctl_card_info_t *info;
dsnd_ctl_card_info_alloca(&info);
err = dsnd_ctl_card_info( handle, info );
RString ret = dsnd_ctl_card_info_get_id( info );
dsnd_ctl_close(handle);
return ret;
}
/*
* (c) 2002-2004 Glenn Maynard, Aaron VonderHaar
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
+10 -10
View File
@@ -43,10 +43,10 @@ void DSound::SetPrimaryBufferMode()
format.dwSize = sizeof(format);
format.dwFlags = DSBCAPS_PRIMARYBUFFER;
format.dwBufferBytes = 0;
format.lpwfxFormat = NULL;
format.lpwfxFormat = nullptr;
IDirectSoundBuffer *pBuffer;
HRESULT hr = this->GetDS()->CreateSoundBuffer( &format, &pBuffer, NULL );
HRESULT hr = this->GetDS()->CreateSoundBuffer( &format, &pBuffer, nullptr );
if( FAILED(hr) )
{
LOG->Warn(hr_ssprintf(hr, "Couldn't create primary buffer"));
@@ -98,15 +98,15 @@ void DSound::SetPrimaryBufferMode()
DSound::DSound()
{
HRESULT hr;
if( FAILED( hr = CoInitialize(NULL) ) )
if( FAILED( hr = CoInitialize(nullptr) ) )
RageException::Throw( hr_ssprintf(hr, "CoInitialize") );
m_pDS = NULL;
m_pDS = nullptr;
}
RString DSound::Init()
{
HRESULT hr;
if( FAILED( hr = DirectSoundCreate(NULL, &m_pDS, NULL) ) )
if( FAILED( hr = DirectSoundCreate(nullptr, &m_pDS, nullptr) ) )
return hr_ssprintf( hr, "DirectSoundCreate" );
static bool bShownInfo = false;
@@ -139,7 +139,7 @@ RString DSound::Init()
DSound::~DSound()
{
if( m_pDS != NULL )
if( m_pDS != nullptr )
m_pDS->Release();
CoUninitialize();
}
@@ -163,8 +163,8 @@ bool DSound::IsEmulated() const
DSoundBuf::DSoundBuf()
{
m_pBuffer = NULL;
m_pTempBuffer = NULL;
m_pBuffer = nullptr;
m_pTempBuffer = nullptr;
}
RString DSoundBuf::Init( DSound &ds, DSoundBuf::hw hardware,
@@ -236,7 +236,7 @@ RString DSoundBuf::Init( DSound &ds, DSoundBuf::hw hardware,
format.lpwfxFormat = &waveformat;
HRESULT hr = ds.GetDS()->CreateSoundBuffer( &format, &m_pBuffer, NULL );
HRESULT hr = ds.GetDS()->CreateSoundBuffer( &format, &m_pBuffer, nullptr );
if( FAILED(hr) )
return hr_ssprintf( hr, "CreateSoundBuffer failed (%i hz)", m_iSampleBits );
@@ -318,7 +318,7 @@ static bool contained( int iStart, int iEnd, int iPos )
DSoundBuf::~DSoundBuf()
{
if( m_pBuffer != NULL )
if( m_pBuffer != nullptr )
m_pBuffer->Release();
delete [] m_pTempBuffer;
}
+10 -9
View File
@@ -3,7 +3,7 @@
#include "RageSoundManager.h"
#include "RageLog.h"
#include "RageUtil.h"
#include "Foreach.h"
#include "arch/arch_default.h"
DriverList RageSoundDriver::m_pDriverList;
@@ -44,28 +44,29 @@ RageSoundDriver *RageSoundDriver::Create( const RString& drivers )
}
}
FOREACH_CONST( RString, drivers_to_try, Driver )
for (RString const &Driver : drivers_to_try)
{
RageDriver *pDriver = m_pDriverList.Create( *Driver );
if( pDriver == NULL )
RageDriver *pDriver = m_pDriverList.Create( Driver );
char const *driverString = Driver.c_str();
if( pDriver == nullptr )
{
LOG->Trace( "Unknown sound driver: %s", Driver->c_str() );
LOG->Trace( "Unknown sound driver: %s", driverString );
continue;
}
RageSoundDriver *pRet = dynamic_cast<RageSoundDriver *>( pDriver );
ASSERT( pRet != NULL );
ASSERT( pRet != nullptr );
const RString sError = pRet->Init();
if( sError.empty() )
{
LOG->Info( "Sound driver: %s", Driver->c_str() );
LOG->Info( "Sound driver: %s", driverString );
return pRet;
}
LOG->Info( "Couldn't load driver %s: %s", Driver->c_str(), sError.c_str() );
LOG->Info( "Couldn't load driver %s: %s", driverString, sError.c_str() );
SAFE_DELETE( pRet );
}
return NULL;
return nullptr;
}
RString RageSoundDriver::GetDefaultSoundDriverList()
@@ -53,12 +53,12 @@ bool RageSoundDriver_ALSA9_Software::GetData()
if( frames_to_fill <= 0 )
return false;
static int16_t *buf = NULL;
static int16_t *buf = nullptr;
static int bufsize = 0;
if( buf && bufsize < frames_to_fill )
{
delete[] buf;
buf = NULL;
buf = nullptr;
}
if( !buf )
{
@@ -89,7 +89,7 @@ void RageSoundDriver_ALSA9_Software::SetupDecodingThread()
RageSoundDriver_ALSA9_Software::RageSoundDriver_ALSA9_Software()
{
m_pPCM = NULL;
m_pPCM = nullptr;
m_bShutdown = false;
}
+14 -14
View File
@@ -40,8 +40,8 @@ static inline RString FourCCToString( uint32_t num )
return s;
}
RageSoundDriver_AU::RageSoundDriver_AU() : m_OutputUnit(NULL), m_iSampleRate(0), m_bDone(false), m_bStarted(false),
m_pIOThread(NULL), m_pNotificationThread(NULL), m_Semaphore("Sound")
RageSoundDriver_AU::RageSoundDriver_AU() : m_OutputUnit(nullptr), m_iSampleRate(0), m_bDone(false), m_bStarted(false),
m_pIOThread(nullptr), m_pNotificationThread(nullptr), m_Semaphore("Sound")
{
}
@@ -80,7 +80,7 @@ static void SetSampleRate( AudioUnit au, Float64 desiredRate )
kAudioObjectPropertyElementWildcard
};
if( (error = AudioObjectGetPropertyData(OutputDevice, &AvailableRatesAddr, 0, NULL, &size, NULL)) )
if( (error = AudioObjectGetPropertyData(OutputDevice, &AvailableRatesAddr, 0, nullptr, &size, nullptr)) )
{
LOG->Warn( WERROR("Couldn't get available nominal sample rates info", error) );
return;
@@ -113,7 +113,7 @@ static void SetSampleRate( AudioUnit au, Float64 desiredRate )
if( bestRate == 0.0 )
return;
if( (error = AudioObjectSetPropertyData(OutputDevice, &RateAddr, 0, NULL, sizeof(Float64), &bestRate)) )
if( (error = AudioObjectSetPropertyData(OutputDevice, &RateAddr, 0, nullptr, sizeof(Float64), &bestRate)) )
{
LOG->Warn( WERROR("Couldn't set the device's sample rate", error) );
}
@@ -131,12 +131,12 @@ RString RageSoundDriver_AU::Init()
Component comp = FindNextComponent( NULL, &desc );
if( comp == NULL )
if( comp == nullptr )
return "Failed to find the default output unit.";
OSStatus error = OpenAComponent( comp, &m_OutputUnit );
if( error != noErr || m_OutputUnit == NULL )
if( error != noErr || m_OutputUnit == nullptr )
return ERROR( "Could not open the default output unit", error );
// Set up a callback function to generate output to the output unit
@@ -255,7 +255,7 @@ float RageSoundDriver_AU::GetPlayLatency() const
};
size = sizeof( Float64 );
if( (error = AudioObjectGetPropertyData(OutputDevice, &RateAddr, 0, NULL, &size, &sampleRate)) )
if( (error = AudioObjectGetPropertyData(OutputDevice, &RateAddr, 0, nullptr, &size, &sampleRate)) )
{
LOG->Warn( WERROR("Couldn't get the device sample rate", error) );
return 0.0f;
@@ -268,7 +268,7 @@ float RageSoundDriver_AU::GetPlayLatency() const
};
size = sizeof( UInt32 );
if( (error = AudioObjectGetPropertyData(OutputDevice, &BufferAddr, 0, NULL, &size, &bufferSize)) )
if( (error = AudioObjectGetPropertyData(OutputDevice, &BufferAddr, 0, nullptr, &size, &bufferSize)) )
{
LOG->Warn( WERROR("Couldn't determine buffer size", error) );
bufferSize = 0;
@@ -283,7 +283,7 @@ float RageSoundDriver_AU::GetPlayLatency() const
};
size = sizeof( UInt32 );
if( (error = AudioObjectGetPropertyData(OutputDevice, &LatencyAddr, 0, NULL, &size, &frames)) )
if( (error = AudioObjectGetPropertyData(OutputDevice, &LatencyAddr, 0, nullptr, &size, &frames)) )
{
LOG->Warn( WERROR( "Couldn't get device latency", error) );
frames = 0;
@@ -297,7 +297,7 @@ float RageSoundDriver_AU::GetPlayLatency() const
bufferSize += frames;
size = sizeof( UInt32 );
if( (error = AudioObjectGetPropertyData(OutputDevice, &SafetyAddr, 0, NULL, &size, &frames)) )
if( (error = AudioObjectGetPropertyData(OutputDevice, &SafetyAddr, 0, nullptr, &size, &frames)) )
{
LOG->Warn( WERROR("Couldn't get device safety offset", error) );
frames = 0;
@@ -312,7 +312,7 @@ float RageSoundDriver_AU::GetPlayLatency() const
kAudioObjectPropertyElementWildcard
};
if( (error = AudioObjectGetPropertyData(OutputDevice, &StreamsAddr, 0, NULL, &size, NULL)) )
if( (error = AudioObjectGetPropertyData(OutputDevice, &StreamsAddr, 0, nullptr, &size, nullptr)) )
{
LOG->Warn( WERROR("Device has no streams", error) );
break;
@@ -325,7 +325,7 @@ float RageSoundDriver_AU::GetPlayLatency() const
}
AudioStreamID *streams = new AudioStreamID[num];
if( (error = AudioObjectGetPropertyData(OutputDevice, &StreamsAddr, 0, NULL, &size, streams)) )
if( (error = AudioObjectGetPropertyData(OutputDevice, &StreamsAddr, 0, nullptr, &size, streams)) )
{
LOG->Warn( WERROR("Cannot get device's streams", error) );
delete[] streams;
@@ -338,7 +338,7 @@ float RageSoundDriver_AU::GetPlayLatency() const
kAudioObjectPropertyElementWildcard
};
if( (error = AudioObjectGetPropertyData(streams[0], &LatencyAddr, 0, NULL, &size, &frames)) )
if( (error = AudioObjectGetPropertyData(streams[0], &LatencyAddr, 0, nullptr, &size, &frames)) )
{
LOG->Warn( WERROR("Stream does not report latency", error) );
frames = 0;
@@ -360,7 +360,7 @@ OSStatus RageSoundDriver_AU::Render( void *inRefCon,
{
RageSoundDriver_AU *This = (RageSoundDriver_AU *)inRefCon;
if( unlikely(This->m_pIOThread == NULL) )
if( unlikely(This->m_pIOThread == nullptr) )
This->m_pIOThread = new RageThreadRegister( "HAL I/O thread" );
AudioBuffer &buf = ioData->mBuffers[0];
+169 -169
View File
@@ -1,169 +1,169 @@
#include "global.h"
#include "RageSoundDriver_DSound_Software.h"
#include "DSoundHelpers.h"
#include "RageLog.h"
#include "RageUtil.h"
#include "RageSoundManager.h"
#include "PrefsManager.h"
#include "archutils/Win32/ErrorStrings.h"
REGISTER_SOUND_DRIVER_CLASS2( DirectSound-sw, DSound_Software );
static const int channels = 2;
static const int bytes_per_frame = channels*2; /* 16-bit */
static const int safe_writeahead = 1024*4; /* in frames */
static int g_iMaxWriteahead;
/* We'll fill the buffer in chunks this big. */
static const int num_chunks = 8;
static int chunksize() { return g_iMaxWriteahead / num_chunks; }
void RageSoundDriver_DSound_Software::MixerThread()
{
if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) )
if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) )
LOG->Warn(werr_ssprintf(GetLastError(), "Failed to set sound thread priority"));
/* Fill a buffer before we start playing, so we don't play whatever junk is
* in the buffer. */
char *locked_buf;
unsigned len;
while( m_pPCM->get_output_buf(&locked_buf, &len, chunksize()) )
{
memset( locked_buf, 0, len );
m_pPCM->release_output_buf(locked_buf, len);
}
/* Start playing. */
m_pPCM->Play();
while( !m_bShutdownMixerThread )
{
char *pLockedBuf;
unsigned iLen;
const int64_t iPlayPos = m_pPCM->GetOutputPosition(); /* must be called before get_output_buf */
if( !m_pPCM->get_output_buf(&pLockedBuf, &iLen, chunksize()) )
{
Sleep( chunksize()*1000 / m_iSampleRate );
continue;
}
this->Mix( (int16_t *) pLockedBuf, iLen/bytes_per_frame, iPlayPos, m_pPCM->GetPosition() );
m_pPCM->release_output_buf( pLockedBuf, iLen );
}
/* I'm not sure why, but if we don't stop the stream now, then the thread will take
* 90ms (our buffer size) longer to close. */
m_pPCM->Stop();
}
int64_t RageSoundDriver_DSound_Software::GetPosition() const
{
return m_pPCM->GetPosition();
}
int RageSoundDriver_DSound_Software::MixerThread_start(void *p)
{
((RageSoundDriver_DSound_Software *) p)->MixerThread();
return 0;
}
RageSoundDriver_DSound_Software::RageSoundDriver_DSound_Software()
{
m_bShutdownMixerThread = false;
m_pPCM = NULL;
}
RString RageSoundDriver_DSound_Software::Init()
{
RString sError = ds.Init();
if( sError != "" )
return sError;
/* If we're emulated, we're better off with the WaveOut driver; DS
* emulation tends to be desynced. */
if( ds.IsEmulated() )
return "Driver unusable (emulated device)";
g_iMaxWriteahead = safe_writeahead;
if( PREFSMAN->m_iSoundWriteAhead )
g_iMaxWriteahead = PREFSMAN->m_iSoundWriteAhead;
/* Create a DirectSound stream, but don't force it into hardware. */
m_pPCM = new DSoundBuf;
m_iSampleRate = PREFSMAN->m_iSoundPreferredSampleRate;
if( m_iSampleRate == 0 )
m_iSampleRate = 44100;
sError = m_pPCM->Init( ds, DSoundBuf::HW_DONT_CARE, channels, m_iSampleRate, 16, g_iMaxWriteahead );
if( sError != "" )
return sError;
LOG->Info( "Software mixing at %i hz", m_iSampleRate );
StartDecodeThread();
m_MixingThread.SetName("Mixer thread");
m_MixingThread.Create( MixerThread_start, this );
return RString();
}
RageSoundDriver_DSound_Software::~RageSoundDriver_DSound_Software()
{
/* Signal the mixing thread to quit. */
if( m_MixingThread.IsCreated() )
{
m_bShutdownMixerThread = true;
LOG->Trace("Shutting down mixer thread ...");
LOG->Flush();
m_MixingThread.Wait();
LOG->Trace("Mixer thread shut down.");
LOG->Flush();
}
delete m_pPCM;
}
void RageSoundDriver_DSound_Software::SetupDecodingThread()
{
if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) )
LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set decoding thread priority") );
}
float RageSoundDriver_DSound_Software::GetPlayLatency() const
{
return (1.0f / m_iSampleRate) * g_iMaxWriteahead;
}
int RageSoundDriver_DSound_Software::GetSampleRate() const
{
return m_iSampleRate;
}
/*
* (c) 2002-2004 Glenn Maynard
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "global.h"
#include "RageSoundDriver_DSound_Software.h"
#include "DSoundHelpers.h"
#include "RageLog.h"
#include "RageUtil.h"
#include "RageSoundManager.h"
#include "PrefsManager.h"
#include "archutils/Win32/ErrorStrings.h"
REGISTER_SOUND_DRIVER_CLASS2( DirectSound-sw, DSound_Software );
static const int channels = 2;
static const int bytes_per_frame = channels*2; /* 16-bit */
static const int safe_writeahead = 1024*4; /* in frames */
static int g_iMaxWriteahead;
/* We'll fill the buffer in chunks this big. */
static const int num_chunks = 8;
static int chunksize() { return g_iMaxWriteahead / num_chunks; }
void RageSoundDriver_DSound_Software::MixerThread()
{
if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) )
if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) )
LOG->Warn(werr_ssprintf(GetLastError(), "Failed to set sound thread priority"));
/* Fill a buffer before we start playing, so we don't play whatever junk is
* in the buffer. */
char *locked_buf;
unsigned len;
while( m_pPCM->get_output_buf(&locked_buf, &len, chunksize()) )
{
memset( locked_buf, 0, len );
m_pPCM->release_output_buf(locked_buf, len);
}
/* Start playing. */
m_pPCM->Play();
while( !m_bShutdownMixerThread )
{
char *pLockedBuf;
unsigned iLen;
const int64_t iPlayPos = m_pPCM->GetOutputPosition(); /* must be called before get_output_buf */
if( !m_pPCM->get_output_buf(&pLockedBuf, &iLen, chunksize()) )
{
Sleep( chunksize()*1000 / m_iSampleRate );
continue;
}
this->Mix( (int16_t *) pLockedBuf, iLen/bytes_per_frame, iPlayPos, m_pPCM->GetPosition() );
m_pPCM->release_output_buf( pLockedBuf, iLen );
}
/* I'm not sure why, but if we don't stop the stream now, then the thread will take
* 90ms (our buffer size) longer to close. */
m_pPCM->Stop();
}
int64_t RageSoundDriver_DSound_Software::GetPosition() const
{
return m_pPCM->GetPosition();
}
int RageSoundDriver_DSound_Software::MixerThread_start(void *p)
{
((RageSoundDriver_DSound_Software *) p)->MixerThread();
return 0;
}
RageSoundDriver_DSound_Software::RageSoundDriver_DSound_Software()
{
m_bShutdownMixerThread = false;
m_pPCM = nullptr;
}
RString RageSoundDriver_DSound_Software::Init()
{
RString sError = ds.Init();
if( sError != "" )
return sError;
/* If we're emulated, we're better off with the WaveOut driver; DS
* emulation tends to be desynced. */
if( ds.IsEmulated() )
return "Driver unusable (emulated device)";
g_iMaxWriteahead = safe_writeahead;
if( PREFSMAN->m_iSoundWriteAhead )
g_iMaxWriteahead = PREFSMAN->m_iSoundWriteAhead;
/* Create a DirectSound stream, but don't force it into hardware. */
m_pPCM = new DSoundBuf;
m_iSampleRate = PREFSMAN->m_iSoundPreferredSampleRate;
if( m_iSampleRate == 0 )
m_iSampleRate = 44100;
sError = m_pPCM->Init( ds, DSoundBuf::HW_DONT_CARE, channels, m_iSampleRate, 16, g_iMaxWriteahead );
if( sError != "" )
return sError;
LOG->Info( "Software mixing at %i hz", m_iSampleRate );
StartDecodeThread();
m_MixingThread.SetName("Mixer thread");
m_MixingThread.Create( MixerThread_start, this );
return RString();
}
RageSoundDriver_DSound_Software::~RageSoundDriver_DSound_Software()
{
/* Signal the mixing thread to quit. */
if( m_MixingThread.IsCreated() )
{
m_bShutdownMixerThread = true;
LOG->Trace("Shutting down mixer thread ...");
LOG->Flush();
m_MixingThread.Wait();
LOG->Trace("Mixer thread shut down.");
LOG->Flush();
}
delete m_pPCM;
}
void RageSoundDriver_DSound_Software::SetupDecodingThread()
{
if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) )
LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set decoding thread priority") );
}
float RageSoundDriver_DSound_Software::GetPlayLatency() const
{
return (1.0f / m_iSampleRate) * g_iMaxWriteahead;
}
int RageSoundDriver_DSound_Software::GetSampleRate() const
{
return m_iSampleRate;
}
/*
* (c) 2002-2004 Glenn Maynard
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
@@ -18,7 +18,7 @@ static int underruns = 0, logged_underruns = 0;
RageSoundDriver::Sound::Sound()
{
m_pSound = NULL;
m_pSound = nullptr;
m_State = AVAILABLE;
m_bPaused = false;
}
@@ -257,7 +257,7 @@ void RageSoundDriver::Update()
while( m_Sounds[i].m_PosMapQueue.read( &p, 1 ) )
{
RageSoundBase *pSound = m_Sounds[i].m_pSound;
if( pSound != NULL )
if( pSound != nullptr )
pSound->CommitPlayingPosition( p.iStreamFrame, p.iHardwareFrame, p.iFrames );
}
}
@@ -280,7 +280,7 @@ void RageSoundDriver::Update()
// LOG->Trace("finishing sound %i", i);
m_Sounds[i].m_pSound->SoundIsFinishedPlaying();
m_Sounds[i].m_pSound = NULL;
m_Sounds[i].m_pSound = nullptr;
/* This sound is done. Set it to HALTING, since the mixer thread might
* be accessing it; it'll change it back to STOPPED once it's ready to
@@ -389,7 +389,7 @@ void RageSoundDriver::StopMixing( RageSoundBase *pSound )
/* Invalidate the m_pSound pointer to guarantee we don't make any further references to
* it. Once this call returns, the sound may no longer exist. */
m_Sounds[i].m_pSound = NULL;
m_Sounds[i].m_pSound = nullptr;
// LOG->Trace("end StopMixing");
m_Mutex.Unlock();
@@ -439,7 +439,7 @@ void RageSoundDriver::SetDecodeBufferSize( int iFrames )
void RageSoundDriver::low_sample_count_workaround()
{
if (soundDriverMaxSamples != 0) GetHardwareFrame(NULL);
if (soundDriverMaxSamples != 0) GetHardwareFrame(nullptr);
}
RageSoundDriver::RageSoundDriver():
@@ -531,9 +531,9 @@ int64_t RageSoundDriver::ClampHardwareFrame( int64_t iHardwareFrame ) const
return m_iVMaxHardwareFrame;
}
int64_t RageSoundDriver::GetHardwareFrame( RageTimer *pTimestamp=NULL ) const
int64_t RageSoundDriver::GetHardwareFrame( RageTimer *pTimestamp=nullptr ) const
{
if( pTimestamp == NULL )
if( pTimestamp == nullptr )
return ClampHardwareFrame( GetPosition() );
/*
+20 -20
View File
@@ -11,15 +11,15 @@ REGISTER_SOUND_DRIVER_CLASS( JACK );
RageSoundDriver_JACK::RageSoundDriver_JACK() :
RageSoundDriver()
{
client = NULL;
port_l = NULL;
port_r = NULL;
client = nullptr;
port_l = nullptr;
port_r = nullptr;
}
RageSoundDriver_JACK::~RageSoundDriver_JACK()
{
// If Init failed, it cleaned up already and set client to NULL
if (client == NULL)
// If Init failed, it cleaned up already and set client to nullptr
if (client == nullptr)
return;
// Clean up and shut down client
@@ -36,7 +36,7 @@ RString RageSoundDriver_JACK::Init()
// Open JACK client and call it "StepMania" or whatever
client = jack_client_open(PRODUCT_FAMILY, JackNoStartServer, &status);
if (client == NULL)
if (client == nullptr)
return "Couldn't connect to JACK server";
sample_rate = jack_get_sample_rate(client);
@@ -64,7 +64,7 @@ RString RageSoundDriver_JACK::Init()
// Create output ports
port_l = jack_port_register(client, "out_l", JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0);
if (port_l == NULL)
if (port_l == nullptr)
{
error = "Couldn't create JACK port out_l";
goto out_close;
@@ -72,7 +72,7 @@ RString RageSoundDriver_JACK::Init()
port_r = jack_port_register(client, "out_r", JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0);
if (port_r == NULL)
if (port_r == nullptr)
{
error = "Couldn't create JACK port out_r";
goto out_unreg_l;
@@ -104,7 +104,7 @@ out_unreg_l:
jack_port_unregister(client, port_l);
out_close:
jack_client_close(client);
client = NULL;
client = nullptr;
return error;
}
@@ -113,23 +113,23 @@ RString RageSoundDriver_JACK::ConnectPorts()
vector<RString> portNames;
split(PREFSMAN->m_iSoundDevice.Get(), ",", portNames, true);
const char *port_out_l = NULL, *port_out_r = NULL;
const char **ports = NULL;
const char *port_out_l = nullptr, *port_out_r = nullptr;
const char **ports = nullptr;
if( portNames.size() == 0 )
{
// The user has NOT specified any ports to connect to. Search
// for all physical sinks and use the first two.
ports = jack_get_ports( client, NULL, NULL, JackPortIsInput | JackPortIsPhysical );
if( ports == NULL )
ports = jack_get_ports( client, nullptr, nullptr, JackPortIsInput | JackPortIsPhysical );
if( ports == nullptr )
return "Couldn't get JACK ports";
if( ports[0] == NULL )
if( ports[0] == nullptr )
{
jack_free( ports );
return "No physical sinks!";
}
port_out_l = ports[0];
if( ports[1] == NULL )
if( ports[1] == nullptr )
// Only one physical sink. We're going mono!
port_out_r = ports[0];
else
@@ -151,9 +151,9 @@ RString RageSoundDriver_JACK::ConnectPorts()
if( ! ( jack_port_flags( out ) & JackPortIsInput ) )
continue;
if( out != NULL )
if( out != nullptr )
{
if( port_out_l == NULL )
if( port_out_l == nullptr )
port_out_l = jack_port_name( out );
else
{
@@ -162,10 +162,10 @@ RString RageSoundDriver_JACK::ConnectPorts()
}
}
}
if( port_out_l == NULL )
if( port_out_l == nullptr )
return "All specified sinks are invalid.";
if( port_out_r == NULL )
if( port_out_r == nullptr )
// Only found one valid sink. Going mono!
port_out_r = port_out_l;
}
@@ -177,7 +177,7 @@ RString RageSoundDriver_JACK::ConnectPorts()
else if( jack_connect( client, jack_port_name(port_r), port_out_r ) != 0 )
ret = "Couldn't connect right JACK port";
if( ports != NULL )
if( ports != nullptr )
jack_free( ports );
return ret;
+2 -2
View File
@@ -58,7 +58,7 @@ void RageSoundDriver_OSS::MixerThread()
usleep( 10000 );
struct timeval tv = { 0, 10000 };
select(fd+1, NULL, &f, NULL, &tv);
select(fd+1, nullptr, &f, nullptr, &tv);
}
}
@@ -81,7 +81,7 @@ bool RageSoundDriver_OSS::GetData()
const int chunksize = ab.fragsize;
static int16_t *buf = NULL;
static int16_t *buf = nullptr;
if(!buf)
buf = new int16_t[chunksize / sizeof(int16_t)];
+17 -17
View File
@@ -16,9 +16,9 @@ REGISTER_SOUND_DRIVER_CLASS2( Pulse, PulseAudio );
/* Constructor */
RageSoundDriver_PulseAudio::RageSoundDriver_PulseAudio()
: RageSoundDriver(),
m_LastPosition(0), m_SampleRate(0), m_Error(NULL),
m_LastPosition(0), m_SampleRate(0), m_Error(nullptr),
m_Sem("Pulseaudio Synchronization Semaphore"),
m_PulseMainLoop(NULL), m_PulseCtx(NULL), m_PulseStream(NULL)
m_PulseMainLoop(nullptr), m_PulseCtx(nullptr), m_PulseStream(nullptr)
{
m_SampleRate = PREFSMAN->m_iSoundPreferredSampleRate;
if( m_SampleRate == 0 )
@@ -32,7 +32,7 @@ RageSoundDriver_PulseAudio::~RageSoundDriver_PulseAudio()
pa_threaded_mainloop_stop(m_PulseMainLoop);
pa_threaded_mainloop_free(m_PulseMainLoop);
if(m_Error != NULL)
if(m_Error != nullptr)
{
free(m_Error);
}
@@ -45,7 +45,7 @@ RString RageSoundDriver_PulseAudio::Init()
LOG->Trace("Pulse: pa_threaded_mainloop_new()...");
m_PulseMainLoop = pa_threaded_mainloop_new();
if(m_PulseMainLoop == NULL)
if(m_PulseMainLoop == nullptr)
{
return "pa_threaded_mainloop_new() failed!";
}
@@ -63,7 +63,7 @@ RString RageSoundDriver_PulseAudio::Init()
"StepMania", plist);
pa_proplist_free(plist);
if(m_PulseCtx == NULL)
if(m_PulseCtx == nullptr)
{
return "pa_context_new_with_proplist() failed!";
}
@@ -72,7 +72,7 @@ RString RageSoundDriver_PulseAudio::Init()
m_PulseCtx = pa_context_new(
pa_threaded_mainloop_get_api(m_PulseMainLoop),
"Stepmania");
if(m_PulseCtx == NULL)
if(m_PulseCtx == nullptr)
{
return "pa_context_new() failed!";
}
@@ -81,7 +81,7 @@ RString RageSoundDriver_PulseAudio::Init()
pa_context_set_state_callback(m_PulseCtx, StaticCtxStateCb, this);
LOG->Trace("Pulse: pa_context_connect()...");
error = pa_context_connect(m_PulseCtx, NULL, (pa_context_flags_t)0, NULL);
error = pa_context_connect(m_PulseCtx, nullptr, (pa_context_flags_t)0, nullptr);
if(error < 0)
{
@@ -101,10 +101,10 @@ RString RageSoundDriver_PulseAudio::Init()
StartDecodeThread();
/* Wait for the pulseaudio stream to be ready before returning.
* An error may occur, if it appends, m_Error becomes non-NULL. */
* An error may occur, if it appends, m_Error becomes non-nullptr. */
m_Sem.Wait();
if(m_Error == NULL)
if(m_Error == nullptr)
{
return "";
}
@@ -137,7 +137,7 @@ void RageSoundDriver_PulseAudio::m_InitStream(void)
{
if(asprintf(&m_Error, "invalid sample spec!") == -1)
{
m_Error = NULL;
m_Error = nullptr;
}
m_Sem.Post();
return;
@@ -151,11 +151,11 @@ void RageSoundDriver_PulseAudio::m_InitStream(void)
/* create the stream */
LOG->Trace("Pulse: pa_stream_new()...");
m_PulseStream = pa_stream_new(m_PulseCtx, "Stepmania Audio", &ss, &map);
if(m_PulseStream == NULL)
if(m_PulseStream == nullptr)
{
if(asprintf(&m_Error, "pa_stream_new(): %s", pa_strerror(pa_context_errno(m_PulseCtx))) == -1)
{
m_Error = NULL;
m_Error = nullptr;
}
m_Sem.Post();
return;
@@ -224,14 +224,14 @@ void RageSoundDriver_PulseAudio::m_InitStream(void)
/* connect the stream for playback */
LOG->Trace("Pulse: pa_stream_connect_playback()...");
error = pa_stream_connect_playback(m_PulseStream, NULL, &attr,
PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL);
error = pa_stream_connect_playback(m_PulseStream, nullptr, &attr,
PA_STREAM_AUTO_TIMING_UPDATE, nullptr, nullptr);
if(error < 0)
{
if(asprintf(&m_Error, "pa_stream_connect_playback(): %s",
pa_strerror(pa_context_errno(m_PulseCtx))) == -1)
{
m_Error = NULL;
m_Error = nullptr;
}
m_Sem.Post();
return;
@@ -261,7 +261,7 @@ void RageSoundDriver_PulseAudio::CtxStateCb(pa_context *c)
case PA_CONTEXT_FAILED:
if(asprintf(&m_Error, "context connection failed: %s", pa_strerror(pa_context_errno(m_PulseCtx))) == -1)
{
m_Error = NULL;
m_Error = nullptr;
}
m_Sem.Post();
return;
@@ -316,7 +316,7 @@ void RageSoundDriver_PulseAudio::StreamWriteCb(pa_stream *s, size_t length)
int64_t pos1 = m_LastPosition;
int64_t pos2 = pos1 + nbframes/2; /* Mix() position in stereo frames */
this->Mix( buf, pos2-pos1, pos1, pos2);
if(pa_stream_write(m_PulseStream, buf, length, NULL, 0, PA_SEEK_RELATIVE) < 0)
if(pa_stream_write(m_PulseStream, buf, length, nullptr, 0, PA_SEEK_RELATIVE) < 0)
{
RageException::Throw("Pulse: pa_stream_write()");
}
File diff suppressed because it is too large Load Diff
+211 -211
View File
@@ -1,211 +1,211 @@
#include "global.h"
#include "RageSoundDriver_WaveOut.h"
#if defined(_MSC_VER)
#pragma comment(lib, "winmm.lib")
#endif
#include "RageTimer.h"
#include "RageLog.h"
#include "RageSound.h"
#include "RageUtil.h"
#include "RageSoundManager.h"
#include "PrefsManager.h"
#include "archutils/Win32/ErrorStrings.h"
REGISTER_SOUND_DRIVER_CLASS( WaveOut );
const int channels = 2;
const int bytes_per_frame = channels*2; /* 16-bit */
const int buffersize_frames = 1024*8; /* in frames */
const int buffersize = buffersize_frames * bytes_per_frame; /* in bytes */
const int num_chunks = 8;
const int chunksize_frames = buffersize_frames / num_chunks;
const int chunksize = buffersize / num_chunks; /* in bytes */
static RString wo_ssprintf( MMRESULT err, const char *szFmt, ...)
{
char szBuf[MAXERRORLENGTH];
waveOutGetErrorText( err, szBuf, MAXERRORLENGTH );
va_list va;
va_start( va, szFmt );
RString s = vssprintf( szFmt, va );
va_end( va );
return s += ssprintf( "(%s)", szBuf );
}
int RageSoundDriver_WaveOut::MixerThread_start( void *p )
{
((RageSoundDriver_WaveOut *) p)->MixerThread();
return 0;
}
void RageSoundDriver_WaveOut::MixerThread()
{
if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) )
LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set sound thread priority") );
while( !m_bShutdown )
{
while( GetData() )
;
WaitForSingleObject( m_hSoundEvent, 10 );
}
waveOutReset( m_hWaveOut );
}
bool RageSoundDriver_WaveOut::GetData()
{
/* Look for a free buffer. */
int b;
for( b = 0; b < num_chunks; ++b )
if( m_aBuffers[b].dwFlags & WHDR_DONE )
break;
if( b == num_chunks )
return false;
/* Call the callback. */
this->Mix( (int16_t *) m_aBuffers[b].lpData, chunksize_frames, m_iLastCursorPos, GetPosition() );
MMRESULT ret = waveOutWrite( m_hWaveOut, &m_aBuffers[b], sizeof(m_aBuffers[b]) );
if( ret != MMSYSERR_NOERROR )
FAIL_M( wo_ssprintf(ret, "waveOutWrite failed") );
/* Increment m_iLastCursorPos. */
m_iLastCursorPos += chunksize_frames;
return true;
}
void RageSoundDriver_WaveOut::SetupDecodingThread()
{
if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) )
LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set sound thread priority") );
}
int64_t RageSoundDriver_WaveOut::GetPosition() const
{
MMTIME tm;
tm.wType = TIME_SAMPLES;
MMRESULT ret = waveOutGetPosition( m_hWaveOut, &tm, sizeof(tm) );
if( ret != MMSYSERR_NOERROR )
FAIL_M( wo_ssprintf(ret, "waveOutGetPosition failed") );
return tm.u.sample;
}
RageSoundDriver_WaveOut::RageSoundDriver_WaveOut()
{
m_bShutdown = false;
m_iLastCursorPos = 0;
m_hSoundEvent = CreateEvent( NULL, false, true, NULL );
m_hWaveOut = NULL;
}
RString RageSoundDriver_WaveOut::Init()
{
m_iSampleRate = PREFSMAN->m_iSoundPreferredSampleRate;
if( m_iSampleRate == 0 )
m_iSampleRate = 44100;
WAVEFORMATEX fmt;
fmt.wFormatTag = WAVE_FORMAT_PCM;
fmt.nChannels = channels;
fmt.cbSize = 0;
fmt.nSamplesPerSec = m_iSampleRate;
fmt.wBitsPerSample = 16;
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
MMRESULT ret = waveOutOpen( &m_hWaveOut, WAVE_MAPPER, &fmt, (DWORD_PTR) m_hSoundEvent, NULL, CALLBACK_EVENT );
if( ret != MMSYSERR_NOERROR )
return wo_ssprintf( ret, "waveOutOpen failed" );
ZERO( m_aBuffers );
for(int b = 0; b < num_chunks; ++b)
{
m_aBuffers[b].dwBufferLength = chunksize;
m_aBuffers[b].lpData = new char[chunksize];
ret = waveOutPrepareHeader( m_hWaveOut, &m_aBuffers[b], sizeof(m_aBuffers[b]) );
if( ret != MMSYSERR_NOERROR )
return wo_ssprintf( ret, "waveOutPrepareHeader failed" );
m_aBuffers[b].dwFlags |= WHDR_DONE;
}
LOG->Info( "WaveOut software mixing at %i hz", m_iSampleRate );
/* We have a very large writeahead; make sure we have a large enough decode
* buffer to recover cleanly from underruns. */
SetDecodeBufferSize( buffersize_frames * 3/2 );
StartDecodeThread();
MixingThread.SetName( "Mixer thread" );
MixingThread.Create( MixerThread_start, this );
return RString();
}
RageSoundDriver_WaveOut::~RageSoundDriver_WaveOut()
{
/* Signal the mixing thread to quit. */
if( MixingThread.IsCreated() )
{
m_bShutdown = true;
SetEvent( m_hSoundEvent );
LOG->Trace( "Shutting down mixer thread ..." );
MixingThread.Wait();
LOG->Trace( "Mixer thread shut down." );
}
if( m_hWaveOut != NULL )
{
for( int b = 0; b < num_chunks && m_aBuffers[b].lpData != NULL; ++b )
{
waveOutUnprepareHeader( m_hWaveOut, &m_aBuffers[b], sizeof(m_aBuffers[b]) );
delete [] m_aBuffers[b].lpData;
}
waveOutClose( m_hWaveOut );
}
CloseHandle( m_hSoundEvent );
}
float RageSoundDriver_WaveOut::GetPlayLatency() const
{
/* If we have a 1000-byte buffer, and we fill 100 bytes at a time, we
* almost always have between 900 and 1000 bytes filled; on average, 950. */
return (buffersize_frames - chunksize_frames/2) * (1.0f / m_iSampleRate);
}
/*
* (c) 2002-2004 Glenn Maynard
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "global.h"
#include "RageSoundDriver_WaveOut.h"
#if defined(_MSC_VER)
#pragma comment(lib, "winmm.lib")
#endif
#include "RageTimer.h"
#include "RageLog.h"
#include "RageSound.h"
#include "RageUtil.h"
#include "RageSoundManager.h"
#include "PrefsManager.h"
#include "archutils/Win32/ErrorStrings.h"
REGISTER_SOUND_DRIVER_CLASS( WaveOut );
const int channels = 2;
const int bytes_per_frame = channels*2; /* 16-bit */
const int buffersize_frames = 1024*8; /* in frames */
const int buffersize = buffersize_frames * bytes_per_frame; /* in bytes */
const int num_chunks = 8;
const int chunksize_frames = buffersize_frames / num_chunks;
const int chunksize = buffersize / num_chunks; /* in bytes */
static RString wo_ssprintf( MMRESULT err, const char *szFmt, ...)
{
char szBuf[MAXERRORLENGTH];
waveOutGetErrorText( err, szBuf, MAXERRORLENGTH );
va_list va;
va_start( va, szFmt );
RString s = vssprintf( szFmt, va );
va_end( va );
return s += ssprintf( "(%s)", szBuf );
}
int RageSoundDriver_WaveOut::MixerThread_start( void *p )
{
((RageSoundDriver_WaveOut *) p)->MixerThread();
return 0;
}
void RageSoundDriver_WaveOut::MixerThread()
{
if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) )
LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set sound thread priority") );
while( !m_bShutdown )
{
while( GetData() )
;
WaitForSingleObject( m_hSoundEvent, 10 );
}
waveOutReset( m_hWaveOut );
}
bool RageSoundDriver_WaveOut::GetData()
{
/* Look for a free buffer. */
int b;
for( b = 0; b < num_chunks; ++b )
if( m_aBuffers[b].dwFlags & WHDR_DONE )
break;
if( b == num_chunks )
return false;
/* Call the callback. */
this->Mix( (int16_t *) m_aBuffers[b].lpData, chunksize_frames, m_iLastCursorPos, GetPosition() );
MMRESULT ret = waveOutWrite( m_hWaveOut, &m_aBuffers[b], sizeof(m_aBuffers[b]) );
if( ret != MMSYSERR_NOERROR )
FAIL_M( wo_ssprintf(ret, "waveOutWrite failed") );
/* Increment m_iLastCursorPos. */
m_iLastCursorPos += chunksize_frames;
return true;
}
void RageSoundDriver_WaveOut::SetupDecodingThread()
{
if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) )
LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set sound thread priority") );
}
int64_t RageSoundDriver_WaveOut::GetPosition() const
{
MMTIME tm;
tm.wType = TIME_SAMPLES;
MMRESULT ret = waveOutGetPosition( m_hWaveOut, &tm, sizeof(tm) );
if( ret != MMSYSERR_NOERROR )
FAIL_M( wo_ssprintf(ret, "waveOutGetPosition failed") );
return tm.u.sample;
}
RageSoundDriver_WaveOut::RageSoundDriver_WaveOut()
{
m_bShutdown = false;
m_iLastCursorPos = 0;
m_hSoundEvent = CreateEvent( nullptr, false, true, nullptr );
m_hWaveOut = nullptr;
}
RString RageSoundDriver_WaveOut::Init()
{
m_iSampleRate = PREFSMAN->m_iSoundPreferredSampleRate;
if( m_iSampleRate == 0 )
m_iSampleRate = 44100;
WAVEFORMATEX fmt;
fmt.wFormatTag = WAVE_FORMAT_PCM;
fmt.nChannels = channels;
fmt.cbSize = 0;
fmt.nSamplesPerSec = m_iSampleRate;
fmt.wBitsPerSample = 16;
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
MMRESULT ret = waveOutOpen( &m_hWaveOut, WAVE_MAPPER, &fmt, (DWORD_PTR) m_hSoundEvent, NULL, CALLBACK_EVENT );
if( ret != MMSYSERR_NOERROR )
return wo_ssprintf( ret, "waveOutOpen failed" );
ZERO( m_aBuffers );
for(int b = 0; b < num_chunks; ++b)
{
m_aBuffers[b].dwBufferLength = chunksize;
m_aBuffers[b].lpData = new char[chunksize];
ret = waveOutPrepareHeader( m_hWaveOut, &m_aBuffers[b], sizeof(m_aBuffers[b]) );
if( ret != MMSYSERR_NOERROR )
return wo_ssprintf( ret, "waveOutPrepareHeader failed" );
m_aBuffers[b].dwFlags |= WHDR_DONE;
}
LOG->Info( "WaveOut software mixing at %i hz", m_iSampleRate );
/* We have a very large writeahead; make sure we have a large enough decode
* buffer to recover cleanly from underruns. */
SetDecodeBufferSize( buffersize_frames * 3/2 );
StartDecodeThread();
MixingThread.SetName( "Mixer thread" );
MixingThread.Create( MixerThread_start, this );
return RString();
}
RageSoundDriver_WaveOut::~RageSoundDriver_WaveOut()
{
/* Signal the mixing thread to quit. */
if( MixingThread.IsCreated() )
{
m_bShutdown = true;
SetEvent( m_hSoundEvent );
LOG->Trace( "Shutting down mixer thread ..." );
MixingThread.Wait();
LOG->Trace( "Mixer thread shut down." );
}
if( m_hWaveOut != nullptr )
{
for( int b = 0; b < num_chunks && m_aBuffers[b].lpData != nullptr; ++b )
{
waveOutUnprepareHeader( m_hWaveOut, &m_aBuffers[b], sizeof(m_aBuffers[b]) );
delete [] m_aBuffers[b].lpData;
}
waveOutClose( m_hWaveOut );
}
CloseHandle( m_hSoundEvent );
}
float RageSoundDriver_WaveOut::GetPlayLatency() const
{
/* If we have a 1000-byte buffer, and we fill 100 bytes at a time, we
* almost always have between 900 and 1000 bytes filled; on average, 950. */
return (buffersize_frames - chunksize_frames/2) * (1.0f / m_iSampleRate);
}
/*
* (c) 2002-2004 Glenn Maynard
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
+18 -18
View File
@@ -85,7 +85,7 @@ ThreadImpl *MakeThread( int (*pFunc)(void *pData), void *pData, uint64_t *piThre
thread->m_StartFinishedSem = new SemaImpl_Pthreads( 0 );
int ret = pthread_create( &thread->thread, NULL, StartThread, thread );
int ret = pthread_create( &thread->thread, nullptr, StartThread, thread );
ASSERT_M( ret == 0, ssprintf( "MakeThread: pthread_create: %s", strerror(errno)) );
// Don't return until StartThread sets m_piThreadID.
@@ -131,7 +131,7 @@ ThreadImpl *MakeThread( int (*pFunc)(void *pData), void *pData, uint64_t *piThre
MutexImpl_Pthreads::MutexImpl_Pthreads( RageMutex *pParent ):
MutexImpl( pParent )
{
pthread_mutex_init( &mutex, NULL );
pthread_mutex_init( &mutex, nullptr );
}
MutexImpl_Pthreads::~MutexImpl_Pthreads()
@@ -166,7 +166,7 @@ bool MutexImpl_Pthreads::Lock()
/* Wait for ten seconds. If it takes longer than that, we're
* probably deadlocked. */
timeval tv;
gettimeofday( &tv, NULL );
gettimeofday( &tv, nullptr );
timespec ts;
ts.tv_sec = tv.tv_sec + len;
@@ -248,7 +248,7 @@ MutexImpl *MakeMutex( RageMutex *pParent )
namespace
{
typedef int (* CONDATTR_SET_CLOCK)( pthread_condattr_t *attr, clockid_t clock_id );
CONDATTR_SET_CLOCK g_CondattrSetclock = NULL;
CONDATTR_SET_CLOCK g_CondattrSetclock = nullptr;
bool bInitialized = false;
#if defined(UNIX)
@@ -263,17 +263,17 @@ namespace
return;
bInitialized = true;
void *pLib = NULL;
void *pLib = nullptr;
do {
{
pLib = dlopen( NULL, RTLD_LAZY );
if( pLib == NULL )
pLib = dlopen( nullptr, RTLD_LAZY );
if( pLib == nullptr )
break;
g_CondattrSetclock = (CONDATTR_SET_CLOCK) dlsym( pLib, "pthread_condattr_setclock" );
if( g_CondattrSetclock == NULL )
if( g_CondattrSetclock == nullptr )
break;
}
@@ -293,10 +293,10 @@ namespace
return;
} while(0);
g_CondattrSetclock = NULL;
if( pLib != NULL )
g_CondattrSetclock = nullptr;
if( pLib != nullptr )
dlclose( pLib );
pLib = NULL;
pLib = nullptr;
}
#elif defined(MACOSX)
void InitMonotonic() { bInitialized = true; }
@@ -323,7 +323,7 @@ EventImpl_Pthreads::EventImpl_Pthreads( MutexImpl_Pthreads *pParent )
pthread_condattr_t condattr;
pthread_condattr_init( &condattr );
if( g_CondattrSetclock != NULL )
if( g_CondattrSetclock != nullptr )
g_CondattrSetclock( &condattr, GetClock() );
pthread_cond_init( &m_Cond, &condattr );
@@ -338,7 +338,7 @@ EventImpl_Pthreads::~EventImpl_Pthreads()
#if defined(HAVE_PTHREAD_COND_TIMEDWAIT)
bool EventImpl_Pthreads::Wait( RageTimer *pTimeout )
{
if( pTimeout == NULL )
if( pTimeout == nullptr )
{
pthread_cond_wait( &m_Cond, &m_pParent->mutex );
return true;
@@ -348,7 +348,7 @@ bool EventImpl_Pthreads::Wait( RageTimer *pTimeout )
* (no condattr_setclock), pthread_cond_timedwait has an inherent race
* condition: the system clock may change before we call it. */
timespec abstime;
if( g_CondattrSetclock != NULL || GetClock() == CLOCK_REALTIME )
if( g_CondattrSetclock != nullptr || GetClock() == CLOCK_REALTIME )
{
/* If we support condattr_setclock, we'll set the condition to use
* the same clock as RageTimer and can use it directly. If the
@@ -360,7 +360,7 @@ bool EventImpl_Pthreads::Wait( RageTimer *pTimeout )
{
// The RageTimer clock is different than the wait clock; convert it.
timeval tv;
gettimeofday( &tv, NULL );
gettimeofday( &tv, nullptr );
RageTimer timeofday( tv.tv_sec, tv.tv_usec );
@@ -460,9 +460,9 @@ bool SemaImpl_Pthreads::TryWait()
// Use conditions, to work around OS X "forgetting" to implement semaphores.
SemaImpl_Pthreads::SemaImpl_Pthreads( int iInitialValue )
{
int ret = pthread_cond_init( &m_Cond, NULL );
int ret = pthread_cond_init( &m_Cond, nullptr );
ASSERT_M( ret == 0, ssprintf( "SemaImpl_Pthreads: pthread_cond_init: %s", strerror(errno)) );
ret = pthread_mutex_init( &m_Mutex, NULL );
ret = pthread_mutex_init( &m_Mutex, nullptr );
ASSERT_M( ret == 0, ssprintf( "SemaImpl_Pthreads: pthread_mutex_init: %s", strerror(errno)) );
m_iValue = iInitialValue;
@@ -489,7 +489,7 @@ bool SemaImpl_Pthreads::Wait()
if( UseTimedlock() )
{
timeval tv;
gettimeofday( &tv, NULL );
gettimeofday( &tv, nullptr );
/* Wait for ten seconds. If it takes longer than that, we're probably deadlocked. */
timespec ts;
+17 -17
View File
@@ -7,12 +7,12 @@
const int MAX_THREADS=128;
static MutexImpl_Win32 *g_pThreadIdMutex = NULL;
static MutexImpl_Win32 *g_pThreadIdMutex = nullptr;
static void InitThreadIdMutex()
{
if( g_pThreadIdMutex != NULL )
if( g_pThreadIdMutex != nullptr )
return;
g_pThreadIdMutex = new MutexImpl_Win32(NULL);
g_pThreadIdMutex = new MutexImpl_Win32(nullptr);
}
static uint64_t g_ThreadIds[MAX_THREADS];
@@ -26,7 +26,7 @@ HANDLE Win32ThreadIdToHandle( uint64_t iID )
return g_ThreadHandles[i];
}
return NULL;
return nullptr;
}
void ThreadImpl_Win32::Halt( bool Kill )
@@ -55,7 +55,7 @@ int ThreadImpl_Win32::Wait()
GetExitCodeThread( ThreadHandle, &ret );
CloseHandle( ThreadHandle );
ThreadHandle = NULL;
ThreadHandle = nullptr;
return ret;
}
@@ -100,7 +100,7 @@ static DWORD WINAPI StartThread( LPVOID pData )
{
if( g_ThreadIds[i] == RageThread::GetCurrentThreadID() )
{
g_ThreadHandles[i] = NULL;
g_ThreadHandles[i] = nullptr;
g_ThreadIds[i] = 0;
break;
}
@@ -143,7 +143,7 @@ ThreadImpl *MakeThisThread()
// LOG->Warn( werr_ssprintf( GetLastError(), "DuplicateHandle(%p, %p) failed",
// CurProc, GetCurrentThread() ) );
thread->ThreadHandle = NULL;
thread->ThreadHandle = nullptr;
}
thread->ThreadId = GetCurrentThreadId();
@@ -160,9 +160,9 @@ ThreadImpl *MakeThread( int (*pFunc)(void *pData), void *pData, uint64_t *piThre
thread->m_pFunc = pFunc;
thread->m_pData = pData;
thread->ThreadHandle = CreateThread( NULL, 0, &StartThread, thread, CREATE_SUSPENDED, &thread->ThreadId );
thread->ThreadHandle = CreateThread( nullptr, 0, &StartThread, thread, CREATE_SUSPENDED, &thread->ThreadId );
*piThreadID = (uint64_t) thread->ThreadId;
ASSERT_M( thread->ThreadHandle != NULL, ssprintf("%s", werr_ssprintf(GetLastError(), "CreateThread").c_str() ) );
ASSERT_M( thread->ThreadHandle != nullptr, ssprintf("%s", werr_ssprintf(GetLastError(), "CreateThread").c_str() ) );
int slot = GetOpenSlot( thread->ThreadId );
g_ThreadHandles[slot] = thread->ThreadHandle;
@@ -177,8 +177,8 @@ ThreadImpl *MakeThread( int (*pFunc)(void *pData), void *pData, uint64_t *piThre
MutexImpl_Win32::MutexImpl_Win32( RageMutex *pParent ):
MutexImpl( pParent )
{
mutex = CreateMutex( NULL, false, NULL );
ASSERT_M( mutex != NULL, werr_ssprintf(GetLastError(), "CreateMutex") );
mutex = CreateMutex( nullptr, false, nullptr );
ASSERT_M( mutex != nullptr, werr_ssprintf(GetLastError(), "CreateMutex") );
}
MutexImpl_Win32::~MutexImpl_Win32()
@@ -188,7 +188,7 @@ MutexImpl_Win32::~MutexImpl_Win32()
static bool SimpleWaitForSingleObject( HANDLE h, DWORD ms )
{
ASSERT( h != NULL );
ASSERT( h != nullptr );
DWORD ret = WaitForSingleObject( h, ms );
switch( ret )
@@ -266,9 +266,9 @@ EventImpl_Win32::EventImpl_Win32( MutexImpl_Win32 *pParent )
{
m_pParent = pParent;
m_iNumWaiting = 0;
m_WakeupSema = CreateSemaphore( NULL, 0, 0x7fffffff, NULL );
m_WakeupSema = CreateSemaphore( nullptr, 0, 0x7fffffff, nullptr );
InitializeCriticalSection( &m_iNumWaitingLock );
m_WaitersDone = CreateEvent( NULL, FALSE, FALSE, NULL );
m_WaitersDone = CreateEvent( nullptr, FALSE, FALSE, nullptr );
}
EventImpl_Win32::~EventImpl_Win32()
@@ -356,7 +356,7 @@ bool EventImpl_Win32::Wait( RageTimer *pTimeout )
LeaveCriticalSection( &m_iNumWaitingLock );
unsigned iMilliseconds = INFINITE;
if( pTimeout != NULL )
if( pTimeout != nullptr )
{
float fSecondsInFuture = -pTimeout->Ago();
iMilliseconds = (unsigned) max( 0, int( fSecondsInFuture * 1000 ) );
@@ -435,7 +435,7 @@ EventImpl *MakeEvent( MutexImpl *pMutex )
SemaImpl_Win32::SemaImpl_Win32( int iInitialValue )
{
sem = CreateSemaphore( NULL, iInitialValue, 999999999, NULL );
sem = CreateSemaphore( nullptr, iInitialValue, 999999999, nullptr );
m_iCounter = iInitialValue;
}
@@ -447,7 +447,7 @@ SemaImpl_Win32::~SemaImpl_Win32()
void SemaImpl_Win32::Post()
{
++m_iCounter;
ReleaseSemaphore( sem, 1, NULL );
ReleaseSemaphore( sem, 1, nullptr );
}
bool SemaImpl_Win32::Wait()