diff --git a/src/Background.cpp b/src/Background.cpp index db620b5f47..79afcbf6c0 100644 --- a/src/Background.cpp +++ b/src/Background.cpp @@ -538,7 +538,7 @@ void BackgroundImpl::LoadFromSong( const Song* pSong ) // Pick the same random items every time the song is played. RandomGen rnd( GetHashForString(pSong->GetSongDir()) ); - random_shuffle( vsNames.begin(), vsNames.end(), rnd ); + std::shuffle( vsNames.begin(), vsNames.end(), rnd ); int iSize = std::min( (int)g_iNumBackgrounds, (int)vsNames.size() ); vsNames.resize( iSize ); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index eb6796b4b9..124a629ae9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -87,7 +87,7 @@ else() ${SMDATA_ALL_FILES_HPP}) endif() -set_property(TARGET "${SM_EXE_NAME}" PROPERTY CXX_STANDARD 11) +set_property(TARGET "${SM_EXE_NAME}" PROPERTY CXX_STANDARD 20) set_property(TARGET "${SM_EXE_NAME}" PROPERTY CXX_STANDARD_REQUIRED ON) set_property(TARGET "${SM_EXE_NAME}" PROPERTY CXX_EXTENSIONS ON) diff --git a/src/Command.cpp b/src/Command.cpp index 4764b79de3..d2ee693673 100644 --- a/src/Command.cpp +++ b/src/Command.cpp @@ -81,7 +81,7 @@ static void SplitWithQuotes( const RString sSource, const char Delimitor, std::v RString Commands::GetOriginalCommandString() const { - return std::accumulate(v.begin(), v.end(), RString(), [](RString &res, Command const &c) { return res + c.GetOriginalCommandString(); }); + return std::accumulate(v.begin(), v.end(), RString(), [](RString const &res, Command const &c) { return res + c.GetOriginalCommandString(); }); } void ParseCommands( const RString &sCommands, Commands &vCommandsOut, bool bLegacy ) diff --git a/src/Course.cpp b/src/Course.cpp index 64120bb2a0..59d7246e0b 100644 --- a/src/Course.cpp +++ b/src/Course.cpp @@ -368,7 +368,7 @@ static void CourseSortSongs( SongSort sort, std::vector &vpPossibleSongs, { DEFAULT_FAIL(sort); case SongSort_Randomize: - random_shuffle( vpPossibleSongs.begin(), vpPossibleSongs.end(), rnd ); + shuffle( vpPossibleSongs.begin(), vpPossibleSongs.end(), rnd ); break; case SongSort_MostPlays: if( PROFILEMAN ) @@ -428,7 +428,7 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail ) * will change every time it's viewed, and the displayed order will have no * bearing on what you'll actually play. */ tmp_entries = m_vEntries; - random_shuffle( tmp_entries.begin(), tmp_entries.end(), rnd ); + shuffle( tmp_entries.begin(), tmp_entries.end(), rnd ); } const std::vector &entries = m_bShuffle ? tmp_entries:m_vEntries; @@ -589,8 +589,10 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail ) int iAdd; if( iMaxDist == iMinDist ) iAdd = iMaxDist; - else - iAdd = rnd( iMaxDist - iMinDist ) + iMinDist; + else { + std::uniform_int_distribution<> dist( iMinDist, iMaxDist ); + iAdd = dist( rnd ); + } iLowMeter += iAdd; iHighMeter += iAdd; } @@ -820,8 +822,10 @@ void Course::GetTrailUnsortedEndless( const std::vector &entries, T int iAdd; if( iMaxDist == iMinDist ) iAdd = iMaxDist; - else - iAdd = rnd( iMaxDist - iMinDist ) + iMinDist; + else { + std::uniform_int_distribution<> dist( iMinDist, iMaxDist ); + iAdd = dist( rnd ); + } iLowMeter += iAdd; iHighMeter += iAdd; } diff --git a/src/CourseUtil.cpp b/src/CourseUtil.cpp index 0f1ccfab9f..b8cb51dd7d 100644 --- a/src/CourseUtil.cpp +++ b/src/CourseUtil.cpp @@ -304,7 +304,7 @@ void CourseUtil::AutogenOniFromArtist( const RString &sArtistName, RString sArti * song set changes. */ { RandomGen rng( GetHashForString( sArtistName ) + aSongs.size() ); - random_shuffle( aSongs.begin(), aSongs.end(), rng ); + shuffle( aSongs.begin(), aSongs.end(), rng ); } // Only use up to four songs. diff --git a/src/GameSoundManager.cpp b/src/GameSoundManager.cpp index 68f2ee2ca5..e442f34054 100644 --- a/src/GameSoundManager.cpp +++ b/src/GameSoundManager.cpp @@ -318,7 +318,7 @@ static void DoPlayOnceFromDir( RString sPath ) { order.push_back(i); } - std::random_shuffle(order.begin(), order.end()); + std::shuffle( order.begin(), order.end(), g_RandomNumberGenerator ); } int index = order.back(); diff --git a/src/MusicWheel.cpp b/src/MusicWheel.cpp index 35322e3dd3..3f2cb85f95 100644 --- a/src/MusicWheel.cpp +++ b/src/MusicWheel.cpp @@ -1333,7 +1333,7 @@ void MusicWheel::StartRandom() { // Shuffle and use the roulette wheel. RandomGen rnd; - random_shuffle( getWheelItemsData(SORT_ROULETTE).begin(), getWheelItemsData(SORT_ROULETTE).end(), rnd ); + shuffle( getWheelItemsData(SORT_ROULETTE).begin(), getWheelItemsData(SORT_ROULETTE).end(), rnd ); GAMESTATE->m_SortOrder.Set( SORT_ROULETTE ); } else diff --git a/src/NoteDataUtil.cpp b/src/NoteDataUtil.cpp index 9eca1ee1ed..c379e0bf82 100644 --- a/src/NoteDataUtil.cpp +++ b/src/NoteDataUtil.cpp @@ -1535,19 +1535,19 @@ static void GetTrackMapping( StepsType st, NoteDataUtil::TrackMapping tt, int Nu switch(st) { case StepsType_beat_single5: { - std::random_shuffle( &iTakeFromTrack[0], &iTakeFromTrack[5], rnd ); - std::random_shuffle( &iTakeFromTrack[6], &iTakeFromTrack[11], rnd ); + std::shuffle( &iTakeFromTrack[0], &iTakeFromTrack[5], rnd ); + std::shuffle( &iTakeFromTrack[6], &iTakeFromTrack[11], rnd ); break; } case StepsType_beat_single7: { - std::random_shuffle( &iTakeFromTrack[1], &iTakeFromTrack[8], rnd ); - std::random_shuffle( &iTakeFromTrack[9], &iTakeFromTrack[16], rnd ); + std::shuffle( &iTakeFromTrack[1], &iTakeFromTrack[8], rnd ); + std::shuffle( &iTakeFromTrack[9], &iTakeFromTrack[16], rnd ); break; } default: { - std::random_shuffle( &iTakeFromTrack[0], &iTakeFromTrack[NumTracks], rnd ); + std::shuffle( &iTakeFromTrack[0], &iTakeFromTrack[NumTracks], rnd ); break; } } @@ -1970,7 +1970,7 @@ static void HyperShuffleNotes( NoteData &inout, int iStartIndex, int iEndIndex) for(int i = iActualTaps; i < iFreeTracks; i++) vtnTargetTaps.push_back(TAP_EMPTY); - std::random_shuffle(viTargetTracks.begin(), viTargetTracks.end(), g_RandomNumberGenerator); + std::shuffle(viTargetTracks.begin(), viTargetTracks.end(), g_RandomNumberGenerator); // Go through the tracks in their shuffled order and drop tap notes. for(int i = 0; i < viTargetTracks.size(); i++) diff --git a/src/OptionRow.cpp b/src/OptionRow.cpp index 7cbbfd3bcb..7278817836 100644 --- a/src/OptionRow.cpp +++ b/src/OptionRow.cpp @@ -544,7 +544,7 @@ void OptionRow::SetDestination( Actor::TweenState &ts, bool bTween ) if( m_Frame.DestTweenState() != ts ) { m_Frame.StopTweening(); - if( bTween && m_pParentType->TWEEN_SECONDS != 0 ) + if( bTween && m_pParentType->TWEEN_SECONDS != 0.0f ) m_Frame.BeginTweening( m_pParentType->TWEEN_SECONDS ); m_Frame.DestTweenState() = ts; } diff --git a/src/RageUtil.cpp b/src/RageUtil.cpp index ca4d447a1f..76174c8f92 100644 --- a/src/RageUtil.cpp +++ b/src/RageUtil.cpp @@ -29,74 +29,6 @@ void UnicodeUpperLower(wchar_t *, size_t, const unsigned char *); RandomGen g_RandomNumberGenerator; -MersenneTwister::MersenneTwister( int iSeed ) : m_iNext(0) -{ - Reset( iSeed ); -} - -void MersenneTwister::Reset( int iSeed ) -{ - if( iSeed == 0 ) - iSeed = time(nullptr); - - m_Values[0] = iSeed; - m_iNext = 0; - for( int i = 1; i < 624; ++i ) - m_Values[i] = ((69069 * m_Values[i-1]) + 1) & 0xFFFFFFFF; - - GenerateValues(); -} - -void MersenneTwister::GenerateValues() -{ - static const unsigned mask[] = { 0, 0x9908B0DF }; - - for( int i = 0; i < 227; ++i ) - { - int iVal = (m_Values[i] & 0x80000000) | (m_Values[i+1] & 0x7FFFFFFF); - int iNext = (i + 397); - - m_Values[i] = m_Values[iNext]; - m_Values[i] ^= (iVal >> 1); - m_Values[i] ^= mask[iVal&1]; - } - - for( int i = 227; i < 623; ++i ) - { - int iVal = (m_Values[i] & 0x80000000) | (m_Values[i+1] & 0x7FFFFFFF); - int iNext = (i + 397) - 624; - - m_Values[i] = m_Values[iNext]; - m_Values[i] ^= (iVal >> 1); - m_Values[i] ^= mask[iVal&1]; - } - - int iVal = (m_Values[623] & 0x80000000) + (m_Values[0] & 0x7FFFFFFF); - int iNext = (623 + 397) - 624; - m_Values[623] = m_Values[iNext] ^ (iVal>>1); - m_Values[623] ^= mask[iVal&1]; -} - -int MersenneTwister::Temper( int iVal ) -{ - iVal ^= (iVal >> 11); - iVal ^= (iVal << 7) & 0x9D2C5680; - iVal ^= (iVal << 15) & 0xEFC60000; - iVal ^= (iVal >> 18); - return iVal; -} - -int MersenneTwister::operator()() -{ - if( m_iNext == 624 ) - { - m_iNext = 0; - GenerateValues(); - } - - return Temper( m_Values[m_iNext++] ); -} - /* Extend MersenneTwister into Lua space. This is intended to replace * math.randomseed and math.random, so we conform to their behavior. */ @@ -109,7 +41,7 @@ namespace static int Seed( lua_State *L ) { - g_LuaPRNG.Reset( IArg(1) ); + g_LuaPRNG = MersenneTwister( IArg(1) ); return 0; } @@ -120,7 +52,8 @@ namespace /* [0..1) */ case 0: { - double r = double(g_LuaPRNG()) / DIVISOR; + std::uniform_real_distribution<> dist( 0, 1 ); + double r = dist( g_LuaPRNG ); lua_pushnumber( L, r ); return 1; } @@ -130,7 +63,8 @@ namespace { int upper = IArg(1); luaL_argcheck( L, 1 <= upper, 1, "interval is empty" ); - lua_pushnumber( L, g_LuaPRNG(upper) + 1 ); + std::uniform_int_distribution<> dist( 1, upper ); + lua_pushnumber( L, dist( g_LuaPRNG ) ); return 1; } /* [l..u] */ @@ -139,7 +73,8 @@ namespace int lower = IArg(1); int upper = IArg(2); luaL_argcheck( L, lower < upper, 2, "interval is empty" ); - lua_pushnumber( L, (int(g_LuaPRNG()) % (upper-lower+1)) + lower ); + std::uniform_int_distribution<> dist( lower, upper ); + lua_pushnumber( L, dist( g_LuaPRNG ) ); return 1; } diff --git a/src/RageUtil.h b/src/RageUtil.h index 927da6f730..ce046d54c6 100644 --- a/src/RageUtil.h +++ b/src/RageUtil.h @@ -4,6 +4,7 @@ #define RAGE_UTIL_H #include +#include #include #include #include "global.h" @@ -230,37 +231,16 @@ inline uint32_t Swap24LE( uint32_t n ) { return Swap24( n ); } inline uint16_t Swap16LE( uint16_t n ) { return Swap16( n ); } #endif -struct MersenneTwister +class MersenneTwister : public std::mt19937 { - MersenneTwister( int iSeed = 0 ); // 0 = time() - int operator()(); // returns [0,2^31-1] - int operator()( int n ) // returns [0,n) - { - return (*this)() % n; - } - - void Reset( int iSeed ); - -private: - static int Temper( int iValue ); - void GenerateValues(); - - int m_Values[624]; - int m_iNext; +public: + MersenneTwister( int iSeed = 0 ) : std::mt19937( iSeed == 0 ? time( nullptr ) : iSeed ) {} }; + typedef MersenneTwister RandomGen; extern RandomGen g_RandomNumberGenerator; -/** - * @brief Generate a random float between 0 inclusive and 1 exclusive. - * @return the random float. - */ -inline float RandomFloat() -{ - return g_RandomNumberGenerator() / 2147483648.0f; -} - /** * @brief Return a float between the low and high values. * @param fLow the low value, inclusive. @@ -269,19 +249,30 @@ inline float RandomFloat() */ inline float RandomFloat( float fLow, float fHigh ) { - return SCALE( RandomFloat(), 0.0f, 1.0f, fLow, fHigh ); + std::uniform_real_distribution<> dist( fLow, fHigh ); + return dist( g_RandomNumberGenerator ); +} + +/** + * @brief Generate a random float between 0 inclusive and 1 exclusive. + * @return the random float. + */ +inline float RandomFloat() +{ + return RandomFloat( 0, 1 ); } // Returns an integer between nLow and nHigh inclusive inline int RandomInt( int nLow, int nHigh ) { - return int( g_RandomNumberGenerator(nHigh - nLow + 1) + nLow ); + std::uniform_int_distribution<> dist( nLow, nHigh ); + return dist( g_RandomNumberGenerator ); } // Returns an integer between 0 and n-1 inclusive (replacement for rand() % n). inline int RandomInt( int n ) { - return int( g_RandomNumberGenerator(n) ); + return RandomInt( 0, n - 1 ); } diff --git a/src/RandomSample.cpp b/src/RandomSample.cpp index 4e46305c05..63e93bd1a3 100644 --- a/src/RandomSample.cpp +++ b/src/RandomSample.cpp @@ -56,7 +56,7 @@ bool RandomSample::LoadSoundDir( RString sDir, int iMaxToLoad ) GetDirListing( sDir + "*.ogg", arraySoundFiles ); GetDirListing( sDir + "*.wav", arraySoundFiles ); - std::random_shuffle( arraySoundFiles.begin(), arraySoundFiles.end() ); + std::shuffle( arraySoundFiles.begin(), arraySoundFiles.end(), g_RandomNumberGenerator ); const unsigned int newSize = std::min(arraySoundFiles.size(), static_cast(iMaxToLoad)); arraySoundFiles.resize(newSize); diff --git a/src/ScreenOptionsCourseOverview.cpp b/src/ScreenOptionsCourseOverview.cpp index 204f8dcdaa..c3353bfb13 100644 --- a/src/ScreenOptionsCourseOverview.cpp +++ b/src/ScreenOptionsCourseOverview.cpp @@ -202,7 +202,7 @@ void ScreenOptionsCourseOverview::ProcessMenuStart( const InputEventPlus &input case CourseOverviewRow_Shuffle: { Course *pCourse = GAMESTATE->m_pCurCourse; - random_shuffle( pCourse->m_vEntries.begin(), pCourse->m_vEntries.end() ); + shuffle( pCourse->m_vEntries.begin(), pCourse->m_vEntries.end(), g_RandomNumberGenerator ); Trail *pTrail = pCourse->GetTrailForceRegenCache( GAMESTATE->GetCurrentStyle(input.pn)->m_StepsType ); GAMESTATE->m_pCurTrail[PLAYER_1].Set( pTrail ); SCREENMAN->PlayStartSound(); diff --git a/src/ScreenOptionsReviewWorkout.cpp b/src/ScreenOptionsReviewWorkout.cpp index bc185c145b..90806b16b9 100644 --- a/src/ScreenOptionsReviewWorkout.cpp +++ b/src/ScreenOptionsReviewWorkout.cpp @@ -146,7 +146,7 @@ void ScreenOptionsCourseOverview::ProcessMenuStart( const InputEventPlus &input case ReviewWorkoutRow_Shuffle: { Course *pCourse = GAMESTATE->m_pCurCourse; - random_shuffle( pCourse->m_vEntries.begin(), pCourse->m_vEntries.end() ); + shuffle( pCourse->m_vEntries.begin(), pCourse->m_vEntries.end(), g_RandomNumberGenerator ); Trail *pTrail = pCourse->GetTrailForceRegenCache( GAMESTATE->m_pCurStyle->m_StepsType ); GAMESTATE->m_pCurTrail[PLAYER_1].Set( pTrail ); SCREENMAN->PlayStartSound(); diff --git a/src/ScreenWithMenuElements.cpp b/src/ScreenWithMenuElements.cpp index 943a4d00d0..d97631613d 100644 --- a/src/ScreenWithMenuElements.cpp +++ b/src/ScreenWithMenuElements.cpp @@ -52,7 +52,7 @@ void ScreenWithMenuElements::Init() } } - if( TIMER_SECONDS != -1 ) + if( TIMER_SECONDS != -1.0f ) { ASSERT( m_MenuTimer == nullptr ); // don't load twice m_MenuTimer = new MenuTimer; diff --git a/src/SongManager.cpp b/src/SongManager.cpp index b347763444..5ee4a31a4a 100644 --- a/src/SongManager.cpp +++ b/src/SongManager.cpp @@ -1585,10 +1585,10 @@ void SongManager::UpdateShuffled() { // update shuffled m_pShuffledSongs = m_pSongs; - random_shuffle( m_pShuffledSongs.begin(), m_pShuffledSongs.end(), g_RandomNumberGenerator ); + shuffle( m_pShuffledSongs.begin(), m_pShuffledSongs.end(), g_RandomNumberGenerator ); m_pShuffledCourses = m_pCourses; - random_shuffle( m_pShuffledCourses.begin(), m_pShuffledCourses.end(), g_RandomNumberGenerator ); + shuffle( m_pShuffledCourses.begin(), m_pShuffledCourses.end(), g_RandomNumberGenerator ); } void SongManager::UpdatePreferredSort(RString sPreferredSongs, RString sPreferredCourses)