Integrate C++11 branch into 5_1-new
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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, "/" );
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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() );
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ¶m, 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 ¶m, 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 );
|
||||
|
||||
@@ -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 ¶m, 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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() );
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)];
|
||||
|
||||
|
||||
@@ -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()");
|
||||
}
|
||||
|
||||
+1409
-1409
File diff suppressed because it is too large
Load Diff
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user