Merge branch '5_1-new' into catalina-workaround

This commit is contained in:
Ben Kirzhner
2020-07-04 21:49:03 -07:00
621 changed files with 111292 additions and 43952 deletions
+5 -5
View File
@@ -185,7 +185,7 @@ else()
list(APPEND SMDATA_ARCH_LOADING_HPP
"arch/LoadingWindow/LoadingWindow_MacOSX.h")
elseif(LINUX)
if(GTK2_FOUND)
if(GTK3_FOUND)
list(APPEND SMDATA_ARCH_LOADING_SRC
"arch/LoadingWindow/LoadingWindow_Gtk.cpp")
list(APPEND SMDATA_ARCH_LOADING_HPP
@@ -230,13 +230,13 @@ if(NOT APPLE)
list(APPEND SMDATA_ARCH_LIGHTS_SRC
"arch/Lights/LightsDriver_Linux_PIUIO.cpp"
"arch/Lights/LightsDriver_Linux_PIUIO_Leds.cpp"
"arch/Lights/LightsDriver_LinuxWeedTech.cpp"
"arch/Lights/LightsDriver_LinuxParallel.cpp")
"arch/Lights/LightsDriver_Linux_ITGIO.cpp"
"arch/Lights/LightsDriver_LinuxWeedTech.cpp")
list(APPEND SMDATA_ARCH_LIGHTS_HPP
"arch/Lights/LightsDriver_Linux_PIUIO.h"
"arch/Lights/LightsDriver_Linux_PIUIO_Leds.h"
"arch/Lights/LightsDriver_LinuxWeedTech.h"
"arch/Lights/LightsDriver_LinuxParallel.h")
"arch/Lights/LightsDriver_Linux_ITGIO.h"
"arch/Lights/LightsDriver_LinuxWeedTech.h")
if(WITH_PARALLEL_PORT)
list(APPEND SMDATA_ARCH_LIGHTS_SRC
"arch/Lights/LightsDriver_LinuxParallel.cpp")
+3 -7
View File
@@ -1,4 +1,4 @@
if(NOT GTK2_FOUND)
if(NOT GTK3_FOUND)
return()
endif()
@@ -8,10 +8,6 @@ add_library("GtkModule"
"arch/LoadingWindow/LoadingWindow_GtkModule.h")
sm_add_compile_flag("GtkModule" "-std=${SM_CPP_STANDARD}")
if(CMAKE_CXX_COMPILER MATCHES "clang")
sm_add_compile_flag("GtkModule" "-stdlib=libc++")
set_target_properties("GtkModule" PROPERTIES LINK_FLAGS "-stdlib=libc++")
endif()
# It is normally not appropriate to set the prefix to the empty string. This is
# to maintain compatibility with the current source. At some point, it may be
@@ -32,13 +28,13 @@ set_target_properties("GtkModule"
set_target_properties("GtkModule"
PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO
"${SM_ROOT_DIR}")
target_link_libraries("GtkModule" ${GTK2_LIBRARIES})
target_link_libraries("GtkModule" ${GTK3_LIBRARIES})
set_property(TARGET "GtkModule" PROPERTY FOLDER "Internal Libraries")
list(APPEND SM_GTK_INCLUDE_DIRS
"${SM_SRC_DIR}"
"${SM_SRC_DIR}/generated"
"${SM_SRC_DIR}/arch/LoadingWindow"
"${GTK2_INCLUDE_DIRS}")
"${GTK3_INCLUDE_DIRS}")
sm_add_compile_definition("GtkModule" CMAKE_POWERED)
+48 -26
View File
@@ -142,8 +142,12 @@ if(WITH_SSE2)
if(SM_WIN32_ARCH MATCHES "x86")
set(SM_COMPILE_FLAGS "${SM_COMPILE_FLAGS} /arch:SSE2")
endif()
else()
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86")
set(SM_COMPILE_FLAGS "${SM_COMPILE_FLAGS} -msse2")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
set(SM_COMPILE_FLAGS "${SM_COMPILE_FLAGS} -mtune=cortex-a72")
else()
message("Unrecognized host processor type")
endif()
endif()
@@ -247,8 +251,6 @@ elseif(APPLE)
"${SM_XCODE_DIR}/plistHelper.hpp"
XCODE_ATTRIBUTE_GCC_PREFIX_HEADER
"${CMAKE_CURRENT_SOURCE_DIR}/archutils/Darwin/StepMania.pch"
XCODE_ATTRIBUTE_GCC_ENABLE_CPP_EXCEPTIONS
"NO"
XCODE_ATTRIBUTE_LIBRARY_SEARCH_PATHS
"${SM_XCODE_DIR}/Libraries")
# XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS
@@ -353,9 +355,14 @@ else() # Linux
sm_add_compile_definition("${SM_EXE_NAME}" CRASH_HANDLER)
if(LINUX)
# used only in the ArchHooks_Unix.cpp file
sm_add_compile_definition("${SM_EXE_NAME}" BACKTRACE_METHOD_X86_LINUX)
sm_add_compile_definition("${SM_EXE_NAME}"
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86" OR CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
sm_add_compile_definition("${SM_EXE_NAME}" BACKTRACE_METHOD_X86_LINUX)
sm_add_compile_definition("${SM_EXE_NAME}"
BACKTRACE_METHOD_TEXT="x86 custom backtrace")
else()
sm_add_compile_definition("${SM_EXE_NAME}"
BACKTRACE_METHOD_TEXT="no backtrace")
endif()
sm_add_compile_definition(
"${SM_EXE_NAME}" BACKTRACE_LOOKUP_METHOD_TEXT="backtrace_symbols")
if(${DL_FOUND})
@@ -372,12 +379,15 @@ else() # Linux
message("Host processor is ${CMAKE_SYSTEM_PROCESSOR}")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
message("Host processor is 64bit")
message("Host processor is 64bit X86")
sm_add_compile_definition("${SM_EXE_NAME}" CPU_X86_64)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86"
OR CMAKE_SYSTEM_PROCESSOR MATCHES "i686")
message("Host processor is 32bit")
message("Host processor is 32bit X86")
sm_add_compile_definition("${SM_EXE_NAME}" CPU_X86)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
message("Host processor is 64bit ARM")
sm_add_compile_definition("${SM_EXE_NAME}" CPU_AARCH64)
else()
message("Unrecognized host processor type")
endif()
@@ -399,7 +409,7 @@ else() # Linux
sm_add_compile_definition("${SM_EXE_NAME}" BSD)
endif()
if(GTK2_FOUND)
if(GTK3_FOUND)
sm_add_compile_definition("${SM_EXE_NAME}" HAVE_GTK)
endif()
@@ -409,12 +419,6 @@ else() # Linux
endif()
sm_add_compile_flag("${SM_EXE_NAME}" "-std=${SM_CPP_STANDARD}")
if(CMAKE_CXX_COMPILER MATCHES "clang")
sm_add_compile_flag("${SM_EXE_NAME}" "-stdlib=libc++")
set_target_properties("${SM_EXE_NAME}"
PROPERTIES LINK_FLAGS "-stdlib=libc++")
sm_add_compile_flag("jsoncpp" "-stdlib=libc++")
endif()
endif()
set_property(TARGET "${SM_EXE_NAME}" PROPERTY FOLDER "Internal Libraries")
@@ -476,7 +480,7 @@ else()
endif()
if(WITH_SYSTEM_JSONCPP)
list(APPEND SMDATA_LINK_LIB ${JSONCPP_LIBRARY})
list(APPEND SMDATA_LINK_LIB ${JSONCPP_LIBRARIES})
else()
list(APPEND SMDATA_LINK_LIB "jsoncpp")
endif()
@@ -586,8 +590,8 @@ else() # Unix / Linux TODO: Remember to find and locate the zip archive files.
list(APPEND SMDATA_LINK_LIB "${OPENGL_LIBRARY}")
if(GTK2_FOUND)
list(APPEND SMDATA_LINK_LIB "${GTK2_LIBRARIES}")
if(GTK3_FOUND)
list(APPEND SMDATA_LINK_LIB "${GTK3_LIBRARIES}")
endif()
list(APPEND SMDATA_LINK_LIB "${BZIP2_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}")
@@ -639,10 +643,23 @@ list(APPEND SM_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}
"${SM_SRC_DIR}/generated")
list(APPEND SM_INCLUDE_DIRS "${JPEG_INCLUDE_DIR}")
if(NOT APPLE)
list(APPEND SM_INCLUDE_DIRS
"${SM_EXTERN_DIR}/glew-1.5.8/include"
"${SM_EXTERN_DIR}/jsoncpp/include"
"${SM_EXTERN_DIR}/zlib")
if(NOT WITH_SYSTEM_GLEW)
list(APPEND SM_INCLUDE_DIRS
"${SM_EXTERN_DIR}/glew-1.5.8/include")
endif()
if(WITH_SYSTEM_JSONCPP)
list(APPEND SM_INCLUDE_DIRS ${JSONCPP_INCLUDE_DIRS})
else()
list(APPEND SM_INCLUDE_DIRS
"${SM_EXTERN_DIR}/jsoncpp/include")
endif()
if(NOT WITH_SYSTEM_ZLIB)
list(APPEND SM_INCLUDE_DIRS
"${SM_EXTERN_DIR}/zlib")
endif()
if(MSVC)
if(WITH_OGG)
list(APPEND SM_INCLUDE_DIRS
@@ -652,7 +669,7 @@ if(NOT APPLE)
endif()
list(APPEND SM_INCLUDE_DIRS "${SM_EXTERN_DIR}/ffmpeg/include")
else()
if(WITH_OGG)
if(WITH_OGG AND NOT WITH_SYSTEM_OGG)
list(APPEND SM_INCLUDE_DIRS "${SM_EXTERN_DIR}/vorbis")
endif()
if(HAS_FFMPEG)
@@ -663,8 +680,8 @@ if(NOT APPLE)
list(APPEND SM_INCLUDE_DIRS "${SM_FFMPEG_SRC_DIR}" "${SM_FFMPEG_ROOT}")
endif()
endif()
if(HAS_GTK2)
list(APPEND SM_INCLUDE_DIRS "${GTK2_INCLUDE_DIRS}")
if(HAS_GTK3)
list(APPEND SM_INCLUDE_DIRS "${GTK3_INCLUDE_DIRS}")
endif()
if(X11_FOUND)
list(APPEND SM_INCLUDE_DIRS "${X11_INCLUDE_DIR}")
@@ -691,10 +708,15 @@ endif()
if(WIN32)
# FIXME: This makes no sense...
#list(APPEND SM_INCLUDE_DIRS ${DIRECTX_INCLUDE_DIR})
else()
list(APPEND SM_INCLUDE_DIRS "${SM_EXTERN_DIR}/libpng/include")
endif()
if(NOT WITH_SYSTEM_PNG)
list(APPEND SM_INCLUDE_DIRS "${SM_EXTERN_DIR}/libpng")
endif()
if(NOT WITH_SYSTEM_TOMCRYPT)
list(APPEND SM_INCLUDE_DIRS "${SM_SRC_DIR}/libtomcrypt/src/headers")
endif()
target_include_directories("${SM_EXE_NAME}" PUBLIC ${SM_INCLUDE_DIRS})
+13 -2
View File
@@ -41,6 +41,8 @@ if(NOT WITH_STATIC_LINKING)
sm_add_compile_definition("TextureFontGenerator" _AFXDLL)
endif()
sm_add_compile_definition("TextureFontGenerator" CMAKE_POWERED)
list(APPEND TEXTURE_LINK_LIB "zlib" "png")
target_link_libraries("TextureFontGenerator" ${TEXTURE_LINK_LIB})
@@ -48,8 +50,17 @@ target_link_libraries("TextureFontGenerator" ${TEXTURE_LINK_LIB})
list(APPEND TEXTURE_INCLUDE_DIRS
"${TEXTURE_DIR}"
"${TEXTURE_DIR}/res"
"${SM_EXTERN_DIR}/zlib"
"${SM_EXTERN_DIR}/libpng/include")
"${SM_SRC_DIR}/generated")
if(NOT WITH_SYSTEM_ZLIB)
list(APPEND TEXTURE_INCLUDE_DIRS
"${SM_EXTERN_DIR}/zlib")
endif()
if(NOT WITH_SYSTEM_PNG)
list(APPEND TEXTURE_INCLUDE_DIRS
"${SM_EXTERN_DIR}/libpng")
endif()
target_include_directories("TextureFontGenerator"
PUBLIC ${TEXTURE_INCLUDE_DIRS})
+58 -38
View File
@@ -455,7 +455,7 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail )
else
{
vector<SongAndSteps> vSongAndSteps;
for (std::vector<CourseEntry>::const_iterator e = entries.begin(); e != entries.end(); ++e)
for (auto e = entries.begin(); e != entries.end(); ++e)
{
SongAndSteps resolved; // fill this in
SongCriteria soc = e->songCriteria;
@@ -480,6 +480,7 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail )
if( pSong )
{
vSongAndSteps.clear();
StepsUtil::GetAllMatching( pSong, stc, vSongAndSteps );
}
else if( vSongAndSteps.empty() || !( bSameSongCriteria && bSameStepsCriteria ) )
@@ -651,15 +652,12 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail )
void Course::GetTrailUnsortedEndless( const vector<CourseEntry> &entries, Trail &trail, StepsType &st,
CourseDifficulty &cd, RandomGen &rnd, bool &bCourseDifficultyIsSignificant ) const
{
vector<Song*> vpAllPossibleSongs;
vector<SongAndSteps> vSongAndSteps;
vector<Song*> vpSongs;
typedef vector<Steps*> StepsVector;
map<Song*, StepsVector> mapSongToSteps;
int songIndex = 0;
bool vpSongsSorted = false;
// Resolve each entry to a Song and Steps.
for (std::vector<CourseEntry>::const_iterator e = entries.begin(); e != entries.end(); ++e)
std::set<Song*> alreadySelected;
Song* lastSongSelected;
vector<SongAndSteps> vSongAndSteps;
for (auto e = entries.begin(); e != entries.end(); ++e)
{
SongAndSteps resolved; // fill this in
@@ -684,8 +682,11 @@ void Course::GetTrailUnsortedEndless( const vector<CourseEntry> &entries, Trail
const bool bSameSongCriteria = e != entries.begin() && ( e - 1 )->songCriteria == soc;
const bool bSameStepsCriteria = e != entries.begin() && ( e - 1 )->stepsCriteria == stc;
// If we're doing the same wildcard search as last entry,
// we can just reuse the vSongAndSteps vector.
if( pSong )
{
vSongAndSteps.clear();
StepsUtil::GetAllMatchingEndless( pSong, stc, vSongAndSteps );
}
else if( vSongAndSteps.empty() || !( bSameSongCriteria && bSameStepsCriteria ) )
@@ -698,40 +699,64 @@ void Course::GetTrailUnsortedEndless( const vector<CourseEntry> &entries, Trail
if( vSongAndSteps.empty() )
continue;
if( !vpSongsSorted && !vSongAndSteps.empty() ) {
vector<Song*> vpSongs;
typedef vector<Steps*> StepsVector;
map<Song*,StepsVector> mapSongToSteps;
for (SongAndSteps const &sas : vSongAndSteps)
// if we're doing a RANDOM wildcard search, try to avoid repetition
if (vSongAndSteps.size() > 1 && e->songSort == SongSort::SongSort_Randomize)
{
// Make a backup of the steplist so we can revert if we overfilter
std::vector<SongAndSteps> revertList = vSongAndSteps;
// Filter candidate list via blacklist
RemoveIf(vSongAndSteps, [&](const SongAndSteps& ss) {
return std::find(alreadySelected.begin(), alreadySelected.end(), ss.pSong) != alreadySelected.end();
});
// If every candidate is in the blacklist, pick random song that wasn't played last
// (Repeat songs may still occur if song after this is fixed; this algorithm doesn't look ahead)
if (vSongAndSteps.empty())
{
StepsVector &v = mapSongToSteps[sas.pSong];
v.push_back( sas.pSteps );
if( v.size() == 1 )
vpSongs.push_back( sas.pSong );
vSongAndSteps = revertList;
RemoveIf(vSongAndSteps, SongIsEqual(lastSongSelected));
// If the song that was played last was the only candidate, give up pick randomly
if (vSongAndSteps.empty())
{
vSongAndSteps = revertList;
}
}
vpSongsSorted = true;
CourseSortSongs( e->songSort, vpSongs, rnd );
songIndex = 0;
}
ASSERT( e->iChooseIndex >= 0 );
if( e->iChooseIndex < static_cast<int>(vSongAndSteps.size()) )
std::vector<Song*> vpSongs;
std::map<Song*, StepsVector> songStepMap;
// Build list of songs for sorting, and mapping of songs to steps simultaneously
for (auto& ss : vSongAndSteps)
{
if( songIndex >= int(vpSongs.size()) ) {
songIndex = 0;
StepsVector& stepsForSong = songStepMap[ss.pSong];
// If we haven't noted this song yet, add it to the song list
if (stepsForSong.size() == 0)
{
vpSongs.push_back(ss.pSong);
}
resolved.pSong = vpSongs[ songIndex ];
const vector<Steps*> &mappedSongs = mapSongToSteps[ resolved.pSong ];
songIndex++;
resolved.pSteps = mappedSongs[ RandomInt( mappedSongs.size() ) ];
stepsForSong.push_back(ss.pSteps);
}
else
{
ASSERT(e->iChooseIndex >= 0);
// If we're trying to pick BEST100 when only 99 songs exist,
// we have a problem, so bail out
if (e->iChooseIndex >= vpSongs.size()) {
continue;
}
/* If we're not COURSE_DIFFICULTY_REGULAR, then we should be choosing steps that are
* either easier or harder than the base difficulty. If no such steps exist, then
// Otherwise, pick random steps corresponding to the selected song
CourseSortSongs(e->songSort, vpSongs, rnd);
resolved.pSong = vpSongs[e->iChooseIndex];
const vector<Steps*>& songSteps = songStepMap[resolved.pSong];
resolved.pSteps = songSteps[RandomInt(songSteps.size())];
lastSongSelected = resolved.pSong;
alreadySelected.emplace(resolved.pSong);
/* If we're not COURSE_DIFFICULTY_REGULAR, then we should be choosing steps that are
* either easier or harder than the base difficulty. If no such steps exist, then
* just use the one we already have. */
Difficulty dc = resolved.pSteps->GetDifficulty();
int iLowMeter = e->stepsCriteria.m_iLowMeter;
@@ -825,11 +850,6 @@ void Course::GetTrailUnsortedEndless( const vector<CourseEntry> &entries, Trail
}
trail.m_vEntries.push_back( te );
if( trail.m_vEntries.size() > 0 && te.dc != cd )
{
trail.m_vEntries.reserve( trail.m_vEntries.size() - 1 );
trail.m_vEntries.resize( trail.m_vEntries.size() - 1 );
}
// LOG->Trace( "Chose: %s, %d", te.pSong->GetSongDir().c_str(), te.pSteps->GetMeter() );
if( IsAnEdit() && MAX_SONGS_IN_EDIT_COURSE > 0 &&
+2
View File
@@ -48,6 +48,8 @@ bool CourseWriterCRS::Write( const Course &course, RageFileBasic &f, bool bSavin
f.PutLine( ssprintf("#COURSETRANSLIT:%s;", course.m_sMainTitleTranslit.c_str()) );
if( course.m_sScripter != "" )
f.PutLine( ssprintf("#SCRIPTER:%s;", course.m_sScripter.c_str()) );
if ( course.m_sDescription != "" )
f.PutLine( ssprintf("#DESCRIPTION:%s;", course.m_sDescription.c_str()) );
if( course.m_bRepeat )
f.PutLine( "#REPEAT:YES;" );
if( course.m_iLives != -1 )
+1 -1
View File
@@ -3,7 +3,7 @@
#if !defined(DISABLE_CRYPTO)
#include "libtomcrypt/src/headers/tomcrypt.h"
#include <tomcrypt.h>
class PRNGWrapper
{
+3 -2
View File
@@ -1,4 +1,7 @@
#include "global.h"
#include <tomcrypt.h>
#include "CryptManager.h"
#include "RageUtil.h"
#include "RageLog.h"
@@ -9,8 +12,6 @@
#include "LuaReference.h"
#include "LuaManager.h"
#include "libtomcrypt/src/headers/tomcrypt.h"
CryptManager* CRYPTMAN = nullptr; // global and accessible from anywhere in our program
static const RString PRIVATE_KEY_PATH = "Data/private.rsa";
+4
View File
@@ -5,10 +5,14 @@
#include "RageUtil.h"
#include <memory>
#ifndef _MSC_VER
extern "C"
{
#endif
#include "../extern/lua-5.1/src/lua.h"
#ifndef _MSC_VER
}
#endif
/** @brief A general foreach loop for enumerators, going up to a max value. */
#define FOREACH_ENUM_N( e, max, var ) for( e var=(e)0; var<max; enum_add<e>( var, +1 ) )
+6
View File
@@ -1915,6 +1915,12 @@ bool GameState::CurrentOptionsDisqualifyPlayer( PlayerNumber pn )
return false;
const PlayerOptions &po = m_pPlayerState[pn]->m_PlayerOptions.GetPreferred();
const SongOptions &so = m_SongOptions.GetPreferred();
// Playing a song/course at a slower music rate should disqualify score. -x0rbl
if (so.m_fMusicRate < 1.0) {
return true;
}
// Check the stored player options for disqualify. Don't disqualify because
// of mods that were forced.
+11 -1
View File
@@ -33,7 +33,7 @@ RString GradeToLocalizedString( Grade g )
RString GradeToOldString( Grade g )
{
// string is meant to be human readable
switch( g )
switch( GradeToOldGrade(g) )
{
case Grade_Tier01: return "AAAA";
case Grade_Tier02: return "AAA";
@@ -48,6 +48,16 @@ RString GradeToOldString( Grade g )
}
};
Grade GradeToOldGrade( Grade g )
{
// There used to be 7 grades (plus fail) but grades can now be defined by themes.
// So we need to re-scale the grade bands based on how many actual grades the theme defines.
if( g < NUM_GRADE_TIERS_USED )
g = (Grade)std::lround((double)g * Grade_Tier07 / (NUM_GRADE_TIERS_USED - 1));
return g;
}
Grade StringToGrade( const RString &sGrade )
{
RString s = sGrade;
+1
View File
@@ -67,6 +67,7 @@ static inline RString GradeToString( Grade g )
* @param g the current Grade.
* @return the old styled grade string. */
RString GradeToOldString( Grade g );
Grade GradeToOldGrade( Grade g );
RString GradeToLocalizedString( Grade g );
/**
* @brief Convert the given RString into a proper Grade.
+1 -1
View File
@@ -405,7 +405,7 @@ void HighScoreList::LoadFromNode( const XNode* pHighScoreList )
void HighScoreList::RemoveAllButOneOfEachName()
{
for (vector<HighScore>::iterator i = vHighScores.begin(); i != vHighScores.end() - 1; ++i)
for (vector<HighScore>::iterator i = vHighScores.begin(); i != vHighScores.end(); ++i)
{
for( vector<HighScore>::iterator j = i+1; j != vHighScores.end(); j++ )
{
+13
View File
@@ -75,6 +75,19 @@ bool JsonUtil::WriteFile(const Json::Value &root, const RString &sFile, bool bMi
return true;
}
std::vector<RString> JsonUtil::DeserializeArrayStrings(const Json::Value &value)
{
std::vector<RString> values;
for(auto &&inner_value : value)
{
if(inner_value.isConvertibleTo(Json::stringValue))
{
values.push_back(inner_value.asString());
}
}
return values;
}
/*
* (c) 2001-2004 Chris Danford
* All rights reserved.
+2 -67
View File
@@ -14,6 +14,8 @@ namespace JsonUtil
bool WriteFile(const Json::Value &root, const RString &sFile, bool bMinified);
std::vector<RString> DeserializeArrayStrings(const Json::Value &array);
template<class T>
static void SerializeVectorObjects(const vector<T> &v, void fn(const T &, Json::Value &), Json::Value &root)
{
@@ -195,57 +197,6 @@ namespace JsonUtil
}
}
template<class T>
static void DeserializeArrayValues(vector<T> &v, const Json::Value &root)
{
v.clear();
for( unsigned i=0; i<root.size(); i++ )
{
T t;
if( root[i].TryGet( t ) )
v.push_back( t );
}
}
// don't pull in the set header here
template<typename S, typename T>
static void DeserializeArrayValuesIntoSet(S &s, const Json::Value &root)
{
s.clear();
for( unsigned i=0; i<root.size(); i++ )
{
T t;
if( root[i].TryGet( t ) )
s.insert( t );
}
}
template<typename T>
static void DeserializeArrayValuesIntoVector(vector<T> &v, const Json::Value &root)
{
v.clear();
for( unsigned i=0; i<root.size(); i++ )
{
T t;
if( root[i].TryGet( t ) )
v.push_back( t );
}
}
template <typename M>
static void DeserializeValueToValueMap(M &m, const Json::Value &root)
{
for( Json::Value::const_iterator iter = root.begin(); iter != root.end(); iter++ )
(*iter).TryGet( m[ iter.memberName() ] );
}
template <typename M, typename E, typename F>
static void DeserializeStringToValueMap(M &m, F fnToValue(E e), const Json::Value &root)
{
for( Json::Value::const_iterator iter = root.begin(); iter != root.end(); iter++ )
(*iter).TryGet( m[ fnToValue(iter.memberName()) ] );
}
template <typename M, typename E, typename F>
static void DeserializeStringToObjectMap(M &m, F fnToValue(E e), const Json::Value &root)
{
@@ -272,22 +223,6 @@ namespace JsonUtil
}
}
template <typename K, typename V>
static void DeserializeObjectToValueMapAsArray(map<K,V> &m, const RString &sKeyName, const RString &sValueName, const Json::Value &root)
{
for( unsigned i=0; i<root.size(); i++ )
{
const Json::Value &root2 = root[i];
K k;
if( !k.Deserialize( root2[sKeyName] ) )
continue;
V v;
if( !root2[sValueName].TryGet(v) )
continue;
m[k] = v;
}
}
template<class T>
static void DeserializeVectorValues(vector<T> &v, const Json::Value &root)
{
+4
View File
@@ -8,12 +8,16 @@ class RageMutex;
class XNode;
class LuaReference;
#ifndef _MSC_VER
extern "C"
{
#endif
#include "../extern/lua-5.1/src/lua.h"
#include "../extern/lua-5.1/src/lualib.h"
#include "../extern/lua-5.1/src/lauxlib.h"
#ifndef _MSC_VER
}
#endif
// For Dialog::Result
#include "arch/Dialog/Dialog.h"
+4 -3
View File
@@ -90,10 +90,11 @@ bool LyricsLoader::LoadFromLRCFile(const RString& sPath, Song& out)
// offsets each timestamp after the offset by that amount.
//float fLyricOffset = 0.0f;
// Enforce strict timestamp format to prevent crashing the program.
vector<RString> dummy;
static Regex timestamp("^([0-9]+:){0,2}[0-9]+(.[0-9]*)?$");
if (timestamp.Compare(sValueName, dummy))
{
/* If we've gotten this far, and no other statement caught this
* value before this does, assume it's a time value. */
LyricSegment seg;
seg.m_Color = CurrentColor;
seg.m_fStartTime = HHMMSSToSeconds(sValueName);
+11 -11
View File
@@ -48,17 +48,17 @@ ver.cpp:
fi
PNG = \
../extern/libpng/include/png.c ../extern/libpng/include/.png.h \
../extern/libpng/include/pngconf.h ../extern/libpng/include/pngdebug.h \
../extern/libpng/include/pngerror.c ../extern/libpng/include/pngget.c \
../extern/libpng/include/pnginfo.h ../extern/libpng/include/scripts/pnglibconf.h \
../extern/libpng/include/pngmem.c ../extern/libpng/include/pngpread.c \
../extern/libpng/include/pngpriv.h ../extern/libpng/include/pngread.c \
../extern/libpng/include/pngrio.c ../extern/libpng/include/pngrtran.c \
../extern/libpng/include/pngrutil.c ../extern/libpng/include/pngset.c \
../extern/libpng/include/pngstruct.h ../extern/libpng/include/pngtrans.c \
../extern/libpng/include/pngwio.c ../extern/libpng/include/pngwrite.c \
../extern/libpng/include/pngwtran.c ../extern/libpng/include/pngwutil.c
../extern/libpng/png.c ../extern/libpng/.png.h \
../extern/libpng/pngconf.h ../extern/libpng/pngdebug.h \
../extern/libpng/pngerror.c ../extern/libpng/pngget.c \
../extern/libpng/pnginfo.h ../extern/libpng/scripts/pnglibconf.h \
../extern/libpng/pngmem.c ../extern/libpng/pngpread.c \
../extern/libpng/pngpriv.h ../extern/libpng/pngread.c \
../extern/libpng/pngrio.c ../extern/libpng/pngrtran.c \
../extern/libpng/pngrutil.c ../extern/libpng/pngset.c \
../extern/libpng/pngstruct.h ../extern/libpng/pngtrans.c \
../extern/libpng/pngwio.c ../extern/libpng/pngwrite.c \
../extern/libpng/pngwtran.c ../extern/libpng/pngwutil.c
Screens = \
Screen.cpp Screen.h ScreenAttract.cpp ScreenAttract.h \
+18
View File
@@ -1468,6 +1468,16 @@ void MusicWheel::SetOpenSection( RString group )
RebuildWheelItems();
}
void MusicWheel::GetCurrentSections(vector<RString> &sections)
{
vector<MusicWheelItemData *> &wiWheelItems = getWheelItemsData(GAMESTATE->m_SortOrder);
for( unsigned i = 0; i < wiWheelItems.size(); i++ )
{
if ( wiWheelItems[i]->m_Type == WheelItemDataType_Section && !wiWheelItems[i]->m_sText.empty())
sections.push_back(wiWheelItems[i]->m_sText);
}
}
// sm-ssc additions: jump to group
RString MusicWheel::JumpToNextGroup()
{
@@ -1693,6 +1703,13 @@ public:
return 1;
}
DEFINE_METHOD(GetSelectedSection, GetSelectedSection());
static int GetCurrentSections( T* p, lua_State *L )
{
vector<RString> v;
p->GetCurrentSections(v);
LuaHelpers::CreateTableFromArray<RString>( v, L );
return 1;
}
static int IsRouletting( T* p, lua_State *L ){ lua_pushboolean( L, p->IsRouletting() ); return 1; }
static int SelectSong( T* p, lua_State *L )
{
@@ -1733,6 +1750,7 @@ public:
ADD_METHOD( SelectSong );
ADD_METHOD( SelectCourse );
ADD_METHOD( Move );
ADD_METHOD( GetCurrentSections );
}
};
+1
View File
@@ -52,6 +52,7 @@ public:
virtual void ReloadSongList();
void GetCurrentSections(vector<RString> &sections);
// Lua
void PushSelf( lua_State *L );
+11
View File
@@ -11,6 +11,17 @@
#include "TimingData.h"
#include <utility>
bool NoteDataUtil::StringInterpretsAs( const std::string& str, int integer ) {
try
{
return std::stoi( str ) == integer;
}
catch ( const std::invalid_argument & )
{
return false;
}
}
// TODO: Remove these constants that aren't time signature-aware
static const int BEATS_PER_MEASURE = 4;
static const int ROWS_PER_MEASURE = ROWS_PER_BEAT * BEATS_PER_MEASURE;
+5
View File
@@ -23,6 +23,11 @@ void LightTransformHelper( const NoteData &in, NoteData &out, const vector<int>
* and makes it much easier to change NoteData internally in the future. */
namespace NoteDataUtil
{
/**
* @brief Whether a string can be interpreted as the provided signed integer
*/
bool StringInterpretsAs( const std::string& str, int integer );
NoteType GetSmallestNoteTypeForMeasure( const NoteData &nd, int iMeasureIndex );
NoteType GetSmallestNoteTypeInRange( const NoteData &nd, int iStartIndex, int iEndIndex );
void LoadFromSMNoteDataString( NoteData &out, const RString &sSMNoteData, bool bComposite );
+1 -1
View File
@@ -214,7 +214,7 @@ static void Deserialize( Song &out, const Json::Value &root )
JsonUtil::DeserializeVectorObjects( vBgc, Deserialize, root["ForegroundChanges"] );
}
JsonUtil::DeserializeArrayValuesIntoVector( out.m_vsKeysoundFile, root["KeySounds"] );
out.m_vsKeysoundFile = JsonUtil::DeserializeArrayStrings(root["KeySounds"]);
{
vector<Steps*> vpSteps;
+9 -10
View File
@@ -3,6 +3,7 @@
#include "BackgroundUtil.h"
#include "GameManager.h"
#include "MsdFile.h"
#include "NoteDataUtil.h"
#include "NoteTypes.h"
#include "RageFileManager.h"
#include "RageLog.h"
@@ -974,28 +975,26 @@ bool SMLoader::LoadFromBGChangesVector( BackgroundChange &change, std::vector<RS
case 6:
// param 7 overrides this.
// Backward compatibility:
if( change.m_def.m_sEffect.empty() )
if( change.m_def.m_sEffect.empty() && !NoteDataUtil::StringInterpretsAs( aBGChangeValues[5], 0 ) )
{
bool bLoop = std::stoi( aBGChangeValues[5] ) != 0;
if( !bLoop )
change.m_def.m_sEffect = SBE_StretchNoLoop;
change.m_def.m_sEffect = SBE_StretchNoLoop;
}
// fall through
case 5:
// param 7 overrides this.
// Backward compatibility:
if( change.m_def.m_sEffect.empty() )
if( change.m_def.m_sEffect.empty() && !NoteDataUtil::StringInterpretsAs( aBGChangeValues[4], 0 ) )
{
bool bRewindMovie = std::stoi( aBGChangeValues[4] ) != 0;
if( bRewindMovie )
change.m_def.m_sEffect = SBE_StretchRewind;
change.m_def.m_sEffect = SBE_StretchRewind;
}
// fall through
case 4:
// param 9 overrides this.
// Backward compatibility:
if( change.m_sTransition.empty() )
change.m_sTransition = (std::stoi( aBGChangeValues[3] ) != 0) ? "CrossFade" : "";
if( change.m_sTransition.empty() && !NoteDataUtil::StringInterpretsAs( aBGChangeValues[3], 0 ) )
{
change.m_sTransition = SBT_CrossFade;
}
// fall through
case 3:
change.m_fRate = StringToFloat( aBGChangeValues[2] );
+8 -8
View File
@@ -1,4 +1,7 @@
#include "global.h"
#include <png.h>
#include "RageSurface_Load_PNG.h"
#include "RageUtil.h"
#include "RageLog.h"
@@ -6,17 +9,10 @@
#include "RageSurface.h"
#if defined(_MSC_VER)
#include "../extern/libpng/include/png.h"
#if defined(_BINARY_PNG)
#pragma comment(lib, "libpng.lib")
#endif
#pragma warning(disable: 4611) /* interaction between '_setjmp' and C++ object destruction is non-portable */
#else
#ifndef SYSTEM_PNG
#include "../extern/libpng/include/png.h"
#else
#include <png.h>
#endif // SYSTEM_PNG
#endif // _MSC_VER
namespace
@@ -123,7 +119,6 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro
CHECKPOINT_M("Header only png about to be processed.");
img = CreateSurfaceFrom( width, height, 32, 0, 0, 0, 0, nullptr, width*4 );
png_destroy_read_struct( &png, &info_ptr, nullptr );
return img;
}
@@ -255,6 +250,11 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro
png_read_end( png, info_ptr );
png_destroy_read_struct( &png, &info_ptr, nullptr );
if(row_pointers != nullptr)
{
delete[] row_pointers;
}
return img;
}
+3 -7
View File
@@ -1,4 +1,7 @@
#include "global.h"
#include <png.h>
#include "RageSurface_Save_PNG.h"
#include "RageSurface.h"
#include "RageSurfaceUtils.h"
@@ -7,17 +10,10 @@
#include "RageUtil.h"
#if defined(_MSC_VER)
#include "../extern/libpng/include/png.h"
#if defined(_BINARY_PNG)
#pragma comment(lib, "libpng.lib")
#endif
#pragma warning(disable: 4611) /* interaction between '_setjmp' and C++ object destruction is non-portable */
#else
#ifndef SYSTEM_PNG
#include "../extern/libpng/include/png.h"
#else
#include <png.h>
#endif
#endif // _MSC_VER
static void SafePngError( png_struct *pPng, const RString &sStr )
+8
View File
@@ -264,6 +264,13 @@ public:
*
* should output the same value (+-1) 256 times. If this function is
* incorrect, the first and/or last values may be biased. */
#ifdef CPU_AARCH64
inline unsigned char FTOC(float a)
{
const float v = a < 0.0f ? 0.0f : (a > 1.0f ? 1.0f : a);
return static_cast<unsigned char>(v * 255.0f);
}
#else
inline unsigned char FTOC(float a)
{
//This value is 2^52 * 1.5.
@@ -292,6 +299,7 @@ inline unsigned char FTOC(float a)
return static_cast<unsigned char>(ret);
}
#endif
/* Color type used only in vertex lists. OpenGL expects colors in
* r, g, b, a order, independent of endianness, so storing them this
+9 -16
View File
@@ -547,7 +547,6 @@ RString ConvertI64FormatString( const RString &sStr ) { return sStr; }
#endif
/* ISO-639-1 codes: http://www.loc.gov/standards/iso639-2/php/code_list.php
* native forms: http://people.w3.org/rishida/names/languages.html
* We don't use 3-letter codes, so we don't bother supporting them. */
static const LanguageInfo g_langs[] =
{
@@ -688,7 +687,8 @@ static const LanguageInfo g_langs[] =
{"xh", "Xhosa"},
{"yi", "Yiddish"},
{"yo", "Yoruba"},
{"zh", "Chinese"},
{"zh-Hans", "Chinese (Simplified)"},
{"zh-Hant", "Chinese (Traditional)"},
{"zu", "Zulu"},
};
@@ -1877,27 +1877,20 @@ void MakeLower( wchar_t *p, size_t iLen )
float StringToFloat( const RString &sString )
{
RString toTrim = sString;
Trim(toTrim);
if (toTrim.size() == 0)
float fOut = std::strtof(sString, nullptr);
if (!isfinite(fOut))
{
return 0;
fOut = 0.0f;
}
return std::stof(toTrim);
return fOut;
}
bool StringToFloat( const RString &sString, float &fOut )
{
RString toTrim = sString;
Trim(toTrim);
if (toTrim.size() == 0)
{
return false;
}
char *endPtr;
char *endPtr = nullptr;
fOut = strtof( toTrim, &endPtr );
return *endPtr == '\0' && isfinite( fOut );
fOut = std::strtof(sString, &endPtr);
return sString.size() && *endPtr == '\0' && isfinite(fOut);
}
RString FloatToString( const float &num )
+1 -1
View File
@@ -709,7 +709,7 @@ void ScreenEvaluation::Init()
}
}
switch( best_grade )
switch( GradeToOldGrade(best_grade) )
{
case Grade_Tier01:
case Grade_Tier02:
+3 -1
View File
@@ -595,7 +595,9 @@ bool Steps::HasSignificantTimingChanges() const
if( timing->HasBpmChanges() )
{
// check to see if these changes are significant.
if( (GetMaxBPM() - GetMinBPM()) > 3.000f )
DisplayBpms bpms;
m_pSong->GetDisplayBpms(bpms);
if (bpms.GetMax() - bpms.GetMin() > 3.000f)
return true;
}
+1 -1
View File
@@ -74,7 +74,7 @@ void StepsUtil::GetAllMatchingEndless( Song *pSong, const StepsCriteria &stc, ve
successful = true;
}
if( !successful )
if( !successful && vSteps.size() > 0 )
{
Difficulty difficulty = ( *( vSteps.begin() ) )->GetDifficulty();
Difficulty previousDifficulty = difficulty;
+1 -1
View File
@@ -335,7 +335,7 @@ void TextureFont::FormatFontPage( int iPage, HDC hDC )
}
++iCol;
if( iCol == pPage->m_iNumFramesY )
if( iCol == pPage->m_iNumFramesX )
{
iCol = 0;
++iRow;
+19 -2
View File
@@ -1,9 +1,22 @@
#ifndef UTILS_H
#define UTILS_H
inline float truncf( float f ) { return float(int(f)); };
inline float roundf( float f ) { if(f < 0) return truncf(f-0.5f); return truncf(f+0.5f); };
#if defined(CMAKE_POWERED)
#include "config.hpp"
#elif defined(HAVE_CONFIG_H)
#include "config.h"
#endif
#if !defined(HAVE_TRUNCF)
inline float truncf( float f ) { return float(int(f)); };
#endif
#if !defined(HAVE_ROUNDF)
inline float roundf( float f ) { if(f < 0) return truncf(f-0.5f); return truncf(f+0.5f); };
#endif
#if !defined(HAVE_LRINTF)
#if defined(_MSC_VER) && defined(_X86_)
inline long int lrintf( float f )
{
int retval;
@@ -13,6 +26,10 @@ inline long int lrintf( float f )
return retval;
}
#else
#define lrintf(x) ((int)rint(x))
#endif
#endif
struct Surface
{
+7
View File
@@ -261,7 +261,14 @@ RString ArchHooks::GetPreferredLanguage()
// MacRoman agrees with ASCII in the low-order 7 bits.
const char *str = CFStringGetCStringPtr( lang, kCFStringEncodingMacRoman );
if( str )
{
ret = RString( str, 2 );
if (ret == "zh")
{
ret = RString(str, 7);
ret[2] = '-';
}
}
else
LOG->Warn( "Unable to determine system language. Using English." );
}
+18 -2
View File
@@ -179,13 +179,29 @@ RString ArchHooks::GetPreferredLanguage()
{
RString locale;
if(getenv("LANG"))
if (getenv("LANG"))
{
locale = getenv("LANG");
locale = locale.substr(0,2);
RString region = locale.substr(3, 2);
locale = locale.substr(0, 2);
if (locale == "zh")
{
if (region == "CN" || region == "SG")
{
locale = "zh-Hans";
}
else if (region == "HK" || region == "TW")
{
locale = "zh-Hant";
}
}
}
else
{
LOG->Warn("Unable to determine system language. Using English.");
locale = "en";
}
return locale;
}
+15 -2
View File
@@ -1,6 +1,7 @@
#include "global.h"
#include "ArchHooks.h"
#include "RageUtil.h"
#include "RageLog.h"
#include "archutils/Win32/SpecialDirs.h"
#include "ProductInfo.h"
#include "RageFileManager.h"
@@ -98,7 +99,19 @@ static RString LangIdToString( LANGID l )
case LANG_ARABIC: return "ar";
case LANG_BULGARIAN: return "bg";
case LANG_CATALAN: return "ca";
case LANG_CHINESE: return "zh";
case LANG_CHINESE:
{
switch (SUBLANGID(l))
{
case SUBLANG_CHINESE_TRADITIONAL:
case SUBLANG_CHINESE_HONGKONG:
case SUBLANG_CHINESE_MACAU:
return "zh-Hant";
case SUBLANG_CHINESE_SIMPLIFIED:
case SUBLANG_CHINESE_SINGAPORE:
return "zh-Hans";
}
}
case LANG_CZECH: return "cs";
case LANG_DANISH: return "da";
case LANG_GERMAN: return "de";
@@ -154,7 +167,7 @@ static RString LangIdToString( LANGID l )
// These aren't present in the VC6 headers. We'll never have translations to these languages anyway. -C
//case LANG_MONGOLIAN: return "mn";
//case LANG_GALICIAN: return "gl";
default:
default: LOG->Warn("Unable to determine system language. Using English.");
case LANG_ENGLISH: return "en";
}
}
@@ -14,7 +14,11 @@
#include "InputHandler_DirectInputHelper.h"
#ifdef NTDDI_WIN8 // Link to Xinput9_1_0.lib on Windows 8 SDK and above to ensure linkage to Xinput9_1_0.dll
#pragma comment(lib, "Xinput9_1_0.lib")
#else
#pragma comment(lib, "xinput.lib")
#endif
#include <XInput.h>
#include <WbemIdl.h>
@@ -140,6 +140,15 @@ void InputHandler_Linux_Joystick::InputThread()
js_event event;
int ret = read(fds[i], &event, sizeof(event));
if(ret == -1)
{
LOG->Warn("Error reading from joystick %i: %s; disabled", i, strerror(errno));
close(fds[i]);
fds[i] = -1;
continue;
}
if(ret != sizeof(event))
{
LOG->Warn("Unexpected packet (size %i != %i) from joystick %i; disabled", ret, (int)sizeof(event), i);
@@ -33,22 +33,44 @@ namespace
{
class LineReader
{
protected:
private:
// The buffer size isn't critical; the RString will simply be
// extended until the line is done.
static const size_t BUFFER_SIZE = 64;
char buffer[BUFFER_SIZE];
std::FILE * file;
int timeout_ms;
public:
LineReader()
LineReader(const RString& filename)
{
timeout_ms = DEFAULT_TIMEOUT_MS;
LOG->Info("Starting InputHandler_SextetStreamFromFile from std::FILE with filename '%s'",
filename.c_str());
file = std::fopen(filename.c_str(), "rb");
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, nullptr);
}
}
virtual ~LineReader()
~LineReader()
{
if(file != nullptr) {
std::fclose(file);
}
}
virtual bool IsValid()
bool IsValid()
{
return false;
return file != nullptr;
}
// Ideally, this method should return if timeout_ms passes
@@ -74,7 +96,26 @@ namespace
// false (line undefined) if there is an error or EOF condition,
// true (line = next line from stream) if a whole line is available,
// true (line = "") if no error but still waiting for next line.
virtual bool ReadLine(RString& line) = 0;
bool ReadLine(RString& line)
{
bool afterFirst = false;
size_t len;
line = "";
if(file != nullptr) {
while(fgets(buffer, BUFFER_SIZE, file) != nullptr) {
afterFirst = true;
line += buffer;
len = line.length();
if(len > 0 && line[len - 1] == 0xA) {
break;
}
}
}
return afterFirst;
}
};
}
@@ -82,6 +123,7 @@ class InputHandler_SextetStream::Impl
{
private:
InputHandler_SextetStream * handler;
RString filename;
protected:
void ButtonPressed(const DeviceInput& di)
@@ -94,12 +136,6 @@ class InputHandler_SextetStream::Impl
RageThread inputThread;
bool continueInputThread;
// 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 nullptr
// is returned.
virtual LineReader * getUnvalidatedLineReader() = 0;
inline void clearStateBuffer()
{
memset(stateBuffer, 0, STATE_BUFFER_SIZE);
@@ -114,30 +150,29 @@ class InputHandler_SextetStream::Impl
LineReader * getLineReader()
{
LineReader * linereader = getUnvalidatedLineReader();
if(linereader != nullptr) {
if(!linereader->IsValid()) {
delete linereader;
linereader = nullptr;
}
LineReader * linereader = new LineReader(filename);
if(!linereader->IsValid()) {
delete linereader;
linereader = nullptr;
}
return linereader;
}
public:
Impl(InputHandler_SextetStream * _this)
Impl(InputHandler_SextetStream * _this, const RString& filename)
{
LOG->Info("Number of button states supported by current InputHandler_SextetStream: %u",
(unsigned)BUTTON_COUNT);
continueInputThread = false;
timeout_ms = DEFAULT_TIMEOUT_MS;
this->filename = filename;
handler = _this;
clearStateBuffer();
createThread();
}
virtual ~Impl()
~Impl()
{
if(inputThread.IsCreated()) {
continueInputThread = false;
@@ -145,7 +180,7 @@ class InputHandler_SextetStream::Impl
}
}
virtual void GetDevicesAndDescriptions(vector<InputDeviceInfo>& vDevicesOut)
void GetDevicesAndDescriptions(vector<InputDeviceInfo>& vDevicesOut)
{
vDevicesOut.push_back(InputDeviceInfo(FIRST_DEVICE, "SextetStream"));
}
@@ -287,137 +322,9 @@ REGISTER_INPUT_HANDLER_CLASS (SextetStreamFromFile);
#endif
static Preference<RString> g_sSextetStreamInputFilename("SextetStreamInputFilename", DEFAULT_INPUT_FILENAME);
namespace
{
class StdCFileLineReader: public LineReader
{
private:
// The buffer size isn't critical; the RString will simply be
// extended until the line is done.
static const size_t BUFFER_SIZE = 64;
char buffer[BUFFER_SIZE];
protected:
std::FILE * file;
public:
StdCFileLineReader(std::FILE * file)
{
LOG->Info("Starting InputHandler_SextetStreamFromFile from open std::FILE");
this->file = file;
}
StdCFileLineReader(const RString& filename)
{
LOG->Info("Starting InputHandler_SextetStreamFromFile from std::FILE with filename '%s'",
filename.c_str());
file = std::fopen(filename.c_str(), "rb");
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, nullptr);
}
}
~StdCFileLineReader()
{
if(file != nullptr) {
std::fclose(file);
}
}
virtual bool IsValid()
{
return file != nullptr;
}
virtual bool ReadLine(RString& line)
{
bool afterFirst = false;
size_t len;
line = "";
if(file != nullptr) {
while(fgets(buffer, BUFFER_SIZE, file) != nullptr) {
afterFirst = true;
line += buffer;
len = line.length();
if(len > 0 && line[len - 1] == 0xA) {
break;
}
}
}
return afterFirst;
}
};
class StdCFileHandleImpl: public InputHandler_SextetStream::Impl
{
protected:
std::FILE * file;
public:
StdCFileHandleImpl(InputHandler_SextetStreamFromFile * handler, std::FILE * file) :
InputHandler_SextetStream::Impl(handler)
{
this->file = file;
}
virtual LineReader * getUnvalidatedLineReader()
{
return new StdCFileLineReader(this->file);
}
virtual ~StdCFileHandleImpl()
{
// line reader dtor will close file for us
}
};
class StdCFileNameImpl: public InputHandler_SextetStream::Impl
{
protected:
RString filename;
public:
StdCFileNameImpl(InputHandler_SextetStreamFromFile * handler, const RString& filename) :
InputHandler_SextetStream::Impl(handler)
{
this->filename = filename;
}
virtual LineReader * getUnvalidatedLineReader()
{
return new StdCFileLineReader(filename);
}
virtual ~StdCFileNameImpl()
{
// Nothing to destroy
}
};
}
InputHandler_SextetStreamFromFile::InputHandler_SextetStreamFromFile(FILE * file)
{
_impl = new StdCFileHandleImpl(this, file);
}
InputHandler_SextetStreamFromFile::InputHandler_SextetStreamFromFile(const RString& filename)
{
_impl = new StdCFileNameImpl(this, filename);
}
InputHandler_SextetStreamFromFile::InputHandler_SextetStreamFromFile()
{
_impl = new StdCFileNameImpl(this, g_sSextetStreamInputFilename);
_impl = new Impl(this, g_sSextetStreamInputFilename);
}
/*
@@ -8,9 +8,8 @@ class InputHandler_SextetStream: public InputHandler
{
public:
InputHandler_SextetStream();
virtual ~InputHandler_SextetStream();
//virtual void Update();
virtual void GetDevicesAndDescriptions(vector<InputDeviceInfo>& vDevicesOut);
~InputHandler_SextetStream();
void GetDevicesAndDescriptions(vector<InputDeviceInfo>& vDevicesOut);
public:
class Impl;
@@ -36,12 +35,6 @@ public:
// couldn't get RageFile to work here, possibly because I haven't
// determined how to disable buffering on an input file.)
InputHandler_SextetStreamFromFile();
InputHandler_SextetStreamFromFile(const RString& filename);
// The file object passed here must already be open and buffering should
// be disabled. The file object will be closed in the destructor.
InputHandler_SextetStreamFromFile(std::FILE * file);
};
#endif
@@ -80,6 +80,8 @@ LinuxInputManager::LinuxInputManager()
// Sort devices for more consistent numbering.
std::sort(m_vsPendingEventDevices.begin(), m_vsPendingEventDevices.end(), cmpDevices);
std::sort(m_vsPendingJoystickDevices.begin(), m_vsPendingJoystickDevices.end(), cmpDevices);
closedir(sysClassInput);
}
void LinuxInputManager::InitDriver(InputHandler_Linux_Event* driver)
@@ -0,0 +1,157 @@
#include "global.h"
#include <stdio.h>
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#if defined(HAVE_FCNTL_H)
#include <fcntl.h>
#endif
#include <errno.h>
#include "LightsDriver_Linux_ITGIO.h"
#include "GameState.h"
#include "Game.h"
#include "RageLog.h"
REGISTER_LIGHTS_DRIVER_CLASS2(ITGIO, Linux_ITGIO);
//NOTE: light index 14 is not mapped, this is the coin drop "light"
namespace {
const char *cabinet_leds[NUM_CabinetLight] = {
//UL, UR, LL, LR, Bass L, Bass R
"/sys/class/leds/itgio::output8/brightness",
"/sys/class/leds/itgio::output10/brightness",
"/sys/class/leds/itgio::output9/brightness",
"/sys/class/leds/itgio::output11/brightness",
"/sys/class/leds/itgio::output15/brightness",
"/sys/class/leds/itgio::output15/brightness",
};
const char *dance_leds[NUM_GameController][NUM_GameButton] = {
{
nullptr, nullptr, nullptr, nullptr,
//player start
"/sys/class/leds/itgio::output13/brightness",
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
//left right up down
"/sys/class/leds/itgio::output1/brightness",
"/sys/class/leds/itgio::output0/brightness",
"/sys/class/leds/itgio::output3/brightness",
"/sys/class/leds/itgio::output2/brightness",
},
{
nullptr, nullptr, nullptr, nullptr,
//player start
"/sys/class/leds/itgio::output12/brightness",
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
//left right up down
"/sys/class/leds/itgio::output5/brightness",
"/sys/class/leds/itgio::output4/brightness",
"/sys/class/leds/itgio::output7/brightness",
"/sys/class/leds/itgio::output6/brightness",
},
};
bool SetLight(const char *filename, bool on)
{
if (filename == nullptr)
return true;
FILE *f = fopen(filename, "w");
if (f == nullptr)
{
return false;
}
fprintf(f, "%d", on ? 255 : 0);
fclose(f);
return true;
}
}
LightsDriver_Linux_ITGIO::LightsDriver_Linux_ITGIO()
{
}
LightsDriver_Linux_ITGIO::~LightsDriver_Linux_ITGIO()
{
}
void LightsDriver_Linux_ITGIO::SetGameControllerLight(const LightsState *ls, GameController c, GameButton gb)
{
//only push a change in the light iff it's an actual change.
if (ls->m_bGameButtonLights[c][gb] == previousLS.m_bGameButtonLights[c][gb])
{
return;
}
if (!SetLight(dance_leds[c][gb], ls->m_bGameButtonLights[c][gb]))
{
//grab the game info for a proper debug log.
const InputScheme *pInput = &GAMESTATE->GetCurrentGame()->m_InputScheme;
RString sInputName = pInput->m_szName;
LOG->Warn("Error setting button light %s", GameButtonToString(pInput, gb).c_str());
}
}
void LightsDriver_Linux_ITGIO::Set( const LightsState *ls )
{
FOREACH_CabinetLight(light)
{
// Only SetLight if LightsState has changed since previous iteration.
// This reduces unncessary strain on udev. -dguzek
if (ls->m_bCabinetLights[light] == previousLS.m_bCabinetLights[light] )
{
continue;
}
if (!SetLight(cabinet_leds[light], ls->m_bCabinetLights[light]))
{
LOG->Warn("Error setting cabinet light %s",
CabinetLightToString(light).c_str());
return;
}
}
FOREACH_ENUM(GameController, c)
{
//takes care of each of the player buttons (UDLR)
FOREACH_GameButton_Custom(gb)
{
SetGameControllerLight(ls, c, gb);
}
//Takes care of the cabinet based player lights.
SetGameControllerLight(ls, c, GAME_BUTTON_START);
}
previousLS = *ls;
}
/*
* (c) 2020 StepMania team
* 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.
*/
@@ -0,0 +1,46 @@
/* LightsDriver_Linux_ITGIO: Control ITGIO lights via /sys/class/leds */
#ifndef LightsDriver_Linux_ITGIO_H
#define LightsDriver_Linux_ITGIO_H
#include "arch/Lights/LightsDriver.h"
class LightsDriver_Linux_ITGIO : public LightsDriver
{
private:
LightsState previousLS;
void SetGameControllerLight(const LightsState *ls, GameController c, GameButton gb);
public:
LightsDriver_Linux_ITGIO();
virtual ~LightsDriver_Linux_ITGIO();
virtual void Set( const LightsState *ls );
};
#endif
/*
* (c) 2020 StepMania team
* 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.
*/
@@ -31,7 +31,9 @@ extern "C" const char *Init( int *argc, char ***argv )
//gtk_window_set_icon( GTK_WINDOW(window), );
gtk_widget_realize(window);
splash = gtk_image_new_from_file(splash_image_path);
splash = gtk_image_new_from_pixbuf(
gdk_pixbuf_new_from_file (splash_image_path, nullptr)
);
label = gtk_label_new(nullptr);
gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_CENTER);
@@ -41,7 +43,7 @@ extern "C" const char *Init( int *argc, char ***argv )
progressBar = gtk_progress_bar_new();
gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR(progressBar), 0.0 );
vbox = gtk_vbox_new(FALSE,0);
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 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);
+2 -3
View File
@@ -4,7 +4,6 @@
#include "RageUtil.h"
#include "PrefsManager.h"
#include "ProductInfo.h"
#include "Foreach.h"
REGISTER_SOUND_DRIVER_CLASS( JACK );
@@ -144,9 +143,9 @@ RString RageSoundDriver_JACK::ConnectPorts()
// jack_port_name to use their canonical name. (I'm not sure
// if that second step is necessary, I've seen something about
// "aliases" in the docs.)
FOREACH( RString, portNames, portName )
for ( RString const &portName : portNames )
{
jack_port_t *out = jack_port_by_name( client, *portName );
jack_port_t *out = jack_port_by_name( client, portName );
// Make sure the port is a sink.
if( ! ( jack_port_flags( out ) & JackPortIsInput ) )
continue;
+3
View File
@@ -244,6 +244,9 @@ bool GetThreadBacktraceContext( uint64_t ThreadID, BacktraceContext *ctx )
ctx->PC = (void *)ptrace( PTRACE_PEEKUSER, pid_t(ThreadID), (void *)(PT_NIP<<2), 0 );
if( errno )
return false;
#elif defined(CPU_AARCH64)
// NYI
return false;
#else
#error GetThreadBacktraceContext: which arch?
#endif
+12 -2
View File
@@ -236,8 +236,7 @@ static bool PointsToValidCall( const void *ptr )
int len = 7;
while( len )
{
int val = find_address( buf-len, g_ReadableBegin, g_ReadableEnd );
if( val != -1 )
if( IsExecutableAddress( buf - len ) )
break;
--len;
}
@@ -399,6 +398,12 @@ void GetSignalBacktraceContext( BacktraceContext *ctx, const ucontext_t *uc )
ctx->sp = (void *) uc->uc_mcontext.gregs[REG_RSP];
ctx->pid = GetCurrentThreadId();
}
#elif defined(CPU_AARCH64)
void GetSignalBacktraceContext( BacktraceContext *ctx, const ucontext_t *uc )
{
// NYI
}
#else
#error
#endif
@@ -741,6 +746,11 @@ void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx )
#warning Undefined BACKTRACE_METHOD_*
void InitializeBacktrace() { }
void GetSignalBacktraceContext( BacktraceContext *ctx, const ucontext_t *uc )
{
// NYI
}
void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx )
{
buf[0] = BACKTRACE_METHOD_NOT_AVAILABLE;
+5 -4
View File
@@ -3,6 +3,7 @@
#include "RageLog.h"
#include "SignalHandler.h"
#include "GetSysInfo.h"
#include <memory>
#if defined(HAVE_LIBPTHREAD)
#include "archutils/Common/PthreadHelpers.h"
@@ -31,7 +32,7 @@ static int find_stack_direction2( char *p ) NOINLINE;
static int find_stack_direction() NOINLINE;
static vector<SignalHandler::handler> handlers;
SaveSignals *saved_sigs;
unique_ptr<SaveSignals> saved_sigs;
static int signals[] =
{
@@ -143,10 +144,10 @@ static void *CreateStack( int size )
/* Hook up events to fatal signals, so we can clean up if we're killed. */
void SignalHandler::OnClose( handler h )
{
if( saved_sigs == nullptr )
//if the unique_ptr has not been set, then enter.
if( !saved_sigs )
{
saved_sigs = new SaveSignals;
saved_sigs.reset(new SaveSignals());
bool bUseAltSigStack = true;
#if defined(LINUX)