various commits from SM4 SVN, courtesy of Glenn and Vyhd.
This commit is contained in:
+1
-3
@@ -37,9 +37,7 @@ public:
|
|||||||
void DeleteChildrenWhenDone( bool bDelete=true ) { m_bDeleteChildren = bDelete; }
|
void DeleteChildrenWhenDone( bool bDelete=true ) { m_bDeleteChildren = bDelete; }
|
||||||
void DeleteAllChildren();
|
void DeleteAllChildren();
|
||||||
|
|
||||||
//
|
|
||||||
// Commands
|
// Commands
|
||||||
//
|
|
||||||
virtual void PushSelf( lua_State *L );
|
virtual void PushSelf( lua_State *L );
|
||||||
void PushChildrenTable( lua_State *L );
|
void PushChildrenTable( lua_State *L );
|
||||||
void PlayCommandOnChildren( const RString &sCommandName, const LuaReference *pParamTable = NULL );
|
void PlayCommandOnChildren( const RString &sCommandName, const LuaReference *pParamTable = NULL );
|
||||||
@@ -75,7 +73,7 @@ public:
|
|||||||
|
|
||||||
virtual void SetPropagateCommands( bool b );
|
virtual void SetPropagateCommands( bool b );
|
||||||
|
|
||||||
/* Amount of time until all tweens (and all children's tweens) have stopped: */
|
// Amount of time until all tweens (and all children's tweens) have stopped:
|
||||||
virtual float GetTweenTimeLeft() const;
|
virtual float GetTweenTimeLeft() const;
|
||||||
|
|
||||||
virtual void HandleMessage( const Message &msg );
|
virtual void HandleMessage( const Message &msg );
|
||||||
|
|||||||
+1
-2
@@ -41,8 +41,7 @@ public:
|
|||||||
// fYPos (in the case of EFFECT_DRUNK).
|
// fYPos (in the case of EFFECT_DRUNK).
|
||||||
static float GetXPos( const PlayerState* pPlayerState, int iCol, float fYOffset );
|
static float GetXPos( const PlayerState* pPlayerState, int iCol, float fYOffset );
|
||||||
|
|
||||||
// Shift a note's fXPos by this amount depending
|
// Shift a note's fXPos by this amount depending (on what? -aj)
|
||||||
//
|
|
||||||
static float GetXOffset( const PlayerState* pPlayerState, float fMidiNote );
|
static float GetXOffset( const PlayerState* pPlayerState, float fMidiNote );
|
||||||
|
|
||||||
// Z position; normally 0. Only visible in perspective modes.
|
// Z position; normally 0. Only visible in perspective modes.
|
||||||
|
|||||||
+14
-17
@@ -9,24 +9,23 @@
|
|||||||
struct lua_State;
|
struct lua_State;
|
||||||
class Style;
|
class Style;
|
||||||
|
|
||||||
|
// PrimaryMenuButton and SecondaryMenuButton are used to support using
|
||||||
|
// DeviceInputs that only navigate the menus.
|
||||||
//
|
//
|
||||||
// PrimaryMenuButton and SecondaryMenuButton are used to support using DeviceInputs that only
|
// A button being a primary menu button means that this GameButton will generate
|
||||||
// navigate the menus.
|
// a the corresponding MenuInput IF AND ONLY IF the GameButton corresponding to
|
||||||
|
// the pimary input is not mapped.
|
||||||
//
|
//
|
||||||
// A button being a primary menu button means that this GameButton will generate a the
|
// Example 1: A user is using an arcade machine as their controller. Most
|
||||||
// corresponding MenuInput IF AND ONLY IF the GameButton corresponding to the pimary input
|
// machines have MenuLeft, MenuStart, and MenuRight buttons on the cabinet, so
|
||||||
// is not mapped.
|
// they should be used to navigate menus. The user will map these DeviceInputs
|
||||||
//
|
// to the GameButtons "MenuLeft (optional)", "MenuStart", and "MenuRight (optional)".
|
||||||
// Example 1: A user is using an arcade machine as their controller. Most machines have
|
|
||||||
// MenuLeft, MenuStart, and MenuRight buttons on the cabinet, so they should be used to navigate menus.
|
|
||||||
// The user will map these DeviceInputs to the GameButtons "MenuLeft (optional)", "MenuStart", and
|
|
||||||
// "MenuRight (optional)".
|
|
||||||
//
|
|
||||||
// Example 2: A user is using PlayStation dance pads to play. These controllers don't have dedicated
|
|
||||||
// DeviceInputs for MenuLeft and MenuRight. The user maps Up, Down, Left, and Right as normal.
|
|
||||||
// Since the Left and Right GameButtons have the flag FLAG_SECONDARY_MENU_*, they will function as
|
|
||||||
// MenuLeft and MenuRight as long as "MenuLeft (optional)" and "MenuRight (optional)" are not mapped.
|
|
||||||
//
|
//
|
||||||
|
// Example 2: A user is using PlayStation dance pads to play. These controllers
|
||||||
|
// don't have dedicated DeviceInputs for MenuLeft and MenuRight. The user maps
|
||||||
|
// Up, Down, Left, and Right as normal. Since the Left and Right GameButtons
|
||||||
|
// have the flag FLAG_SECONDARY_MENU_*, they will function as MenuLeft and
|
||||||
|
// MenuRight as long as "MenuLeft (optional)" and "MenuRight (optional)" are not mapped.
|
||||||
|
|
||||||
class Game
|
class Game
|
||||||
{
|
{
|
||||||
@@ -53,9 +52,7 @@ public:
|
|||||||
TapNoteScore m_mapW4To;
|
TapNoteScore m_mapW4To;
|
||||||
TapNoteScore m_mapW5To;
|
TapNoteScore m_mapW5To;
|
||||||
|
|
||||||
//
|
|
||||||
// Lua
|
// Lua
|
||||||
//
|
|
||||||
void PushSelf( lua_State *L );
|
void PushSelf( lua_State *L );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ enum StepsType
|
|||||||
StepsType_dance_double,
|
StepsType_dance_double,
|
||||||
StepsType_dance_couple,
|
StepsType_dance_couple,
|
||||||
StepsType_dance_solo,
|
StepsType_dance_solo,
|
||||||
|
//StepsType_dance_three,
|
||||||
StepsType_dance_routine,
|
StepsType_dance_routine,
|
||||||
StepsType_pump_single,
|
StepsType_pump_single,
|
||||||
StepsType_pump_halfdouble,
|
StepsType_pump_halfdouble,
|
||||||
|
|||||||
+38
-1
@@ -48,6 +48,7 @@ static const StepsTypeInfo g_StepsTypeInfos[] = {
|
|||||||
{ "dance-double", 8, true, StepsTypeCategory_Double },
|
{ "dance-double", 8, true, StepsTypeCategory_Double },
|
||||||
{ "dance-couple", 8, true, StepsTypeCategory_Couple },
|
{ "dance-couple", 8, true, StepsTypeCategory_Couple },
|
||||||
{ "dance-solo", 6, true, StepsTypeCategory_Single },
|
{ "dance-solo", 6, true, StepsTypeCategory_Single },
|
||||||
|
//{ "dance-three", 3, true, StepsTypeCategory_Single },
|
||||||
{ "dance-routine", 8, false, StepsTypeCategory_Routine },
|
{ "dance-routine", 8, false, StepsTypeCategory_Routine },
|
||||||
// pump
|
// pump
|
||||||
{ "pump-single", 5, true, StepsTypeCategory_Single },
|
{ "pump-single", 5, true, StepsTypeCategory_Single },
|
||||||
@@ -323,6 +324,41 @@ static const Style g_Style_Dance_Solo =
|
|||||||
};
|
};
|
||||||
|
|
||||||
// todo: "easy solo" or whatever the proper name for the 3 panel \|/ mode is.
|
// todo: "easy solo" or whatever the proper name for the 3 panel \|/ mode is.
|
||||||
|
/*
|
||||||
|
static const Style g_Style_Dance_Three =
|
||||||
|
{ // STYLE_DANCE_THREE
|
||||||
|
true, // m_bUsedForGameplay
|
||||||
|
true, // m_bUsedForEdit
|
||||||
|
false, // m_bUsedForDemonstration
|
||||||
|
false, // m_bUsedForHowToPlay
|
||||||
|
"three", // m_szName
|
||||||
|
StepsType_dance_three, // m_StepsType
|
||||||
|
StyleType_OnePlayerOneSide, // m_StyleType
|
||||||
|
3, // m_iColsPerPlayer
|
||||||
|
{ // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER];
|
||||||
|
{ // PLAYER_1
|
||||||
|
{ TRACK_1, -DANCE_COL_SPACING*1.0f, NULL },
|
||||||
|
{ TRACK_2, +DANCE_COL_SPACING*0.0f, NULL },
|
||||||
|
{ TRACK_3, +DANCE_COL_SPACING*1.0f, NULL },
|
||||||
|
},
|
||||||
|
{ // PLAYER_2
|
||||||
|
{ TRACK_1, -DANCE_COL_SPACING*1.0f, NULL },
|
||||||
|
{ TRACK_2, +DANCE_COL_SPACING*0.0f, NULL },
|
||||||
|
{ TRACK_3, +DANCE_COL_SPACING*1.0f, NULL },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ // m_iInputColumn[NUM_GameController][NUM_GameButton]
|
||||||
|
{ 0, 1, 2, Style::END_MAPPING },
|
||||||
|
{ 0, 1, 2, Style::END_MAPPING }
|
||||||
|
},
|
||||||
|
{ // m_iColumnDrawOrder[MAX_COLS_PER_PLAYER];
|
||||||
|
0,1,2
|
||||||
|
},
|
||||||
|
false, // m_bNeedsZoomOutWith2Players
|
||||||
|
false, // m_bCanUseBeginnerHelper
|
||||||
|
false, // m_bLockDifficulties
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
static const Style g_Style_Dance_Couple_Edit =
|
static const Style g_Style_Dance_Couple_Edit =
|
||||||
{ // STYLE_DANCE_EDIT_COUPLE
|
{ // STYLE_DANCE_EDIT_COUPLE
|
||||||
@@ -458,6 +494,7 @@ static const Style *g_apGame_Dance_Styles[] =
|
|||||||
&g_Style_Dance_Double,
|
&g_Style_Dance_Double,
|
||||||
&g_Style_Dance_Couple,
|
&g_Style_Dance_Couple,
|
||||||
&g_Style_Dance_Solo,
|
&g_Style_Dance_Solo,
|
||||||
|
//&g_Style_Dance_Three,
|
||||||
&g_Style_Dance_Couple_Edit,
|
&g_Style_Dance_Couple_Edit,
|
||||||
&g_Style_Dance_Routine,
|
&g_Style_Dance_Routine,
|
||||||
NULL
|
NULL
|
||||||
@@ -770,7 +807,7 @@ static const Style g_Style_Pump_Couple_Edit =
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const Style g_Style_Pump_Routine =
|
static const Style g_Style_Pump_Routine =
|
||||||
{ // STYLE_DANCE_ROUTINE
|
{ // STYLE_PUMP_ROUTINE
|
||||||
true, // m_bUsedForGameplay
|
true, // m_bUsedForGameplay
|
||||||
true, // m_bUsedForEdit
|
true, // m_bUsedForEdit
|
||||||
false, // m_bUsedForDemonstration
|
false, // m_bUsedForDemonstration
|
||||||
|
|||||||
+1
-29
@@ -38,7 +38,6 @@
|
|||||||
#include "UnlockManager.h"
|
#include "UnlockManager.h"
|
||||||
#include "ScreenManager.h"
|
#include "ScreenManager.h"
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
#include "GameConstantsAndTypes.h"
|
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <set>
|
#include <set>
|
||||||
@@ -2162,35 +2161,8 @@ public:
|
|||||||
}
|
}
|
||||||
static int GetCurrentSteps( T* p, lua_State *L )
|
static int GetCurrentSteps( T* p, lua_State *L )
|
||||||
{
|
{
|
||||||
// XXX: this will crash in certain situations, but if the PlayerNumber
|
|
||||||
// is checked for, difficulty displays will break... what to do? -aj
|
|
||||||
PlayerNumber pn = Enum::Check<PlayerNumber>(L, 1);
|
PlayerNumber pn = Enum::Check<PlayerNumber>(L, 1);
|
||||||
Steps* pSteps;
|
Steps *pSteps = p->m_pCurSteps[pn];
|
||||||
|
|
||||||
if( p->m_pCurSong.Get() != NULL )
|
|
||||||
{
|
|
||||||
// try our preferred steps type and difficulty first
|
|
||||||
pSteps = SongUtil::GetOneSteps( p->m_pCurSong.Get(), GAMESTATE->m_PreferredStepsType, GAMESTATE->m_PreferredDifficulty[pn] );
|
|
||||||
|
|
||||||
// no matches for preferred stepstype? try the current style
|
|
||||||
if( pSteps == NULL )
|
|
||||||
pSteps = SongUtil::GetOneSteps( p->m_pCurSong.Get(), GAMESTATE->GetCurrentStyle()->m_StepsType, GAMESTATE->m_PreferredDifficulty[pn] );
|
|
||||||
|
|
||||||
// nothing found with preferred difficulty? try with closest.
|
|
||||||
// closest seems to return 'easy' when prefrred difficulty is 'medium'
|
|
||||||
// even if the song has medium steps?
|
|
||||||
if( pSteps == NULL )
|
|
||||||
pSteps = SongUtil::GetOneSteps( p->m_pCurSong.Get(), GAMESTATE->GetCurrentStyle()->m_StepsType, GAMESTATE->GetClosestShownDifficulty(pn) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pSteps = p->m_pCurSteps[pn];
|
|
||||||
}
|
|
||||||
|
|
||||||
// if you're on the music select and change song, the current steps are not
|
|
||||||
// updated correctly/in time for CurrentSongChangedMessageCommand
|
|
||||||
// (as such the returned steps are that of the previous song)
|
|
||||||
|
|
||||||
if( pSteps ) { pSteps->PushSelf(L); }
|
if( pSteps ) { pSteps->PushSelf(L); }
|
||||||
else { lua_pushnil(L); }
|
else { lua_pushnil(L); }
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -370,9 +370,11 @@ lua-5.1/src/lundump.h lua-5.1/src/lvm.h lua-5.1/src/lzio.h
|
|||||||
RageFile = \
|
RageFile = \
|
||||||
RageFileBasic.cpp RageFileBasic.h \
|
RageFileBasic.cpp RageFileBasic.h \
|
||||||
RageFile.cpp RageFile.h RageFileDriver.cpp RageFileDriver.h RageFileManager.cpp RageFileManager.h \
|
RageFile.cpp RageFile.h RageFileDriver.cpp RageFileDriver.h RageFileManager.cpp RageFileManager.h \
|
||||||
|
RageFileManager_ReadAhead.cpp RageFileManager_ReadAhead.h \
|
||||||
RageFileDriverDirect.cpp RageFileDriverDirect.h RageFileDriverDirectHelpers.cpp RageFileDriverDirectHelpers.h \
|
RageFileDriverDirect.cpp RageFileDriverDirect.h RageFileDriverDirectHelpers.cpp RageFileDriverDirectHelpers.h \
|
||||||
RageFileDriverMemory.cpp RageFileDriverMemory.h RageFileDriverZip.cpp RageFileDriverZip.h \
|
RageFileDriverMemory.cpp RageFileDriverMemory.h RageFileDriverZip.cpp RageFileDriverZip.h \
|
||||||
RageFileDriverDeflate.cpp RageFileDriverDeflate.h \
|
RageFileDriverDeflate.cpp RageFileDriverDeflate.h \
|
||||||
|
RageFileDriverReadAhead.cpp RageFileDriverReadAhead.h \
|
||||||
RageFileDriverSlice.cpp RageFileDriverSlice.h \
|
RageFileDriverSlice.cpp RageFileDriverSlice.h \
|
||||||
RageFileDriverTimeout.cpp RageFileDriverTimeout.h
|
RageFileDriverTimeout.cpp RageFileDriverTimeout.h
|
||||||
|
|
||||||
|
|||||||
@@ -439,6 +439,12 @@ void NoteDataUtil::SplitCompositeNoteData( const NoteData &in, vector<NoteData>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FOREACH_PlayerNumber( pn )
|
||||||
|
{
|
||||||
|
out.push_back( NoteData() );
|
||||||
|
out.back().SetNumTracks( in.GetNumTracks() );
|
||||||
|
}
|
||||||
|
|
||||||
for( int t = 0; t < in.GetNumTracks(); ++t )
|
for( int t = 0; t < in.GetNumTracks(); ++t )
|
||||||
{
|
{
|
||||||
for( NoteData::const_iterator iter = in.begin(t); iter != in.end(t); ++iter )
|
for( NoteData::const_iterator iter = in.begin(t); iter != in.end(t); ++iter )
|
||||||
@@ -447,12 +453,7 @@ void NoteDataUtil::SplitCompositeNoteData( const NoteData &in, vector<NoteData>
|
|||||||
TapNote tn = iter->second;
|
TapNote tn = iter->second;
|
||||||
unsigned index = int( tn.pn );
|
unsigned index = int( tn.pn );
|
||||||
|
|
||||||
DEBUG_ASSERT( index < NUM_PlayerNumber );
|
ASSERT( index < NUM_PlayerNumber );
|
||||||
while( out.size() <= index )
|
|
||||||
{
|
|
||||||
out.push_back( NoteData() );
|
|
||||||
out.back().SetNumTracks( in.GetNumTracks() );
|
|
||||||
}
|
|
||||||
tn.pn = PLAYER_INVALID;
|
tn.pn = PLAYER_INVALID;
|
||||||
out[index].SetTapNote( t, row, tn );
|
out[index].SetTapNote( t, row, tn );
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -22,12 +22,13 @@ static const char *NotePartNames[] = {
|
|||||||
"TapLift",
|
"TapLift",
|
||||||
"TapFake",
|
"TapFake",
|
||||||
"HoldHead",
|
"HoldHead",
|
||||||
|
"HoldTail",
|
||||||
"HoldTopCap",
|
"HoldTopCap",
|
||||||
"HoldBody",
|
"HoldBody",
|
||||||
"HoldBottomCap",
|
"HoldBottomCap",
|
||||||
"HoldTail",
|
|
||||||
};
|
};
|
||||||
XToString( NotePart );
|
XToString( NotePart );
|
||||||
|
LuaXType( NotePart );
|
||||||
|
|
||||||
static bool IsVectorZero( const RageVector2 &v )
|
static bool IsVectorZero( const RageVector2 &v )
|
||||||
{
|
{
|
||||||
@@ -58,7 +59,6 @@ struct NoteMetricCache_t
|
|||||||
bool m_bTopHoldAnchorWhenReverse;
|
bool m_bTopHoldAnchorWhenReverse;
|
||||||
bool m_bHoldActiveIsAddLayer;
|
bool m_bHoldActiveIsAddLayer;
|
||||||
|
|
||||||
|
|
||||||
void Load( const RString &sButton );
|
void Load( const RString &sButton );
|
||||||
} *NoteMetricCache;
|
} *NoteMetricCache;
|
||||||
|
|
||||||
@@ -735,6 +735,7 @@ void NoteDisplay::DrawTap( const TapNote& tn, int iCol, float fBeat, bool bOnSam
|
|||||||
}
|
}
|
||||||
|
|
||||||
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, iCol, fBeat );
|
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, iCol, fBeat );
|
||||||
|
// this is the line that forces the (1,1,1,x) part of the noteskin diffuse -aj
|
||||||
DrawActor( tn, pActor, part, iCol, fYOffset, fBeat, bIsAddition, fPercentFadeToFail, fReverseOffsetPixels, 1.0f, fDrawDistanceAfterTargetsPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar );
|
DrawActor( tn, pActor, part, iCol, fYOffset, fBeat, bIsAddition, fPercentFadeToFail, fReverseOffsetPixels, 1.0f, fDrawDistanceAfterTargetsPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar );
|
||||||
|
|
||||||
if( tn.type == TapNote::attack )
|
if( tn.type == TapNote::attack )
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ static ThemeMetric<float> BAR_4TH_ALPHA( "NoteField", "Bar4thAlpha" );
|
|||||||
static ThemeMetric<float> BAR_8TH_ALPHA( "NoteField", "Bar8thAlpha" );
|
static ThemeMetric<float> BAR_8TH_ALPHA( "NoteField", "Bar8thAlpha" );
|
||||||
static ThemeMetric<float> BAR_16TH_ALPHA( "NoteField", "Bar16thAlpha" );
|
static ThemeMetric<float> BAR_16TH_ALPHA( "NoteField", "Bar16thAlpha" );
|
||||||
|
|
||||||
|
static RString RoutineNoteSkinName( size_t i ) { return ssprintf("RoutineNoteSkinP%i",int(i+1)); }
|
||||||
|
static ThemeMetric1D<RString> ROUTINE_NOTESKIN( "NoteField", RoutineNoteSkinName, NUM_PLAYERS );
|
||||||
|
|
||||||
NoteField::NoteField()
|
NoteField::NoteField()
|
||||||
{
|
{
|
||||||
m_pNoteData = NULL;
|
m_pNoteData = NULL;
|
||||||
@@ -109,6 +112,14 @@ void NoteField::CacheAllUsedNoteSkins()
|
|||||||
/* Cache all note skins that we might need for the whole song, course or battle
|
/* Cache all note skins that we might need for the whole song, course or battle
|
||||||
* play, so we don't have to load them later (such as between course songs). */
|
* play, so we don't have to load them later (such as between course songs). */
|
||||||
vector<RString> asSkins;
|
vector<RString> asSkins;
|
||||||
|
|
||||||
|
// If we're in Routine mode, apply our per-player noteskins.
|
||||||
|
if( GAMESTATE->GetCurrentStyle()->m_StyleType == StyleType_TwoPlayersSharedSides )
|
||||||
|
{
|
||||||
|
FOREACH_EnabledPlayer( pn )
|
||||||
|
GAMESTATE->ApplyStageModifiers( pn, ROUTINE_NOTESKIN.GetValue(pn) );
|
||||||
|
}
|
||||||
|
|
||||||
GAMESTATE->GetAllUsedNoteSkins( asSkins );
|
GAMESTATE->GetAllUsedNoteSkins( asSkins );
|
||||||
asSkins.push_back( m_pPlayerState->m_PlayerOptions.GetStage().m_sNoteSkin );
|
asSkins.push_back( m_pPlayerState->m_PlayerOptions.GetStage().m_sNoteSkin );
|
||||||
|
|
||||||
|
|||||||
@@ -168,24 +168,24 @@ Grade PlayerStageStats::GetGrade() const
|
|||||||
{
|
{
|
||||||
int iTapScoreValue = ScoreKeeperNormal::TapNoteScoreToGradePoints( tns, bIsBeginner );
|
int iTapScoreValue = ScoreKeeperNormal::TapNoteScoreToGradePoints( tns, bIsBeginner );
|
||||||
fActual += m_iTapNoteScores[tns] * iTapScoreValue;
|
fActual += m_iTapNoteScores[tns] * iTapScoreValue;
|
||||||
LOG->Trace( "GetGrade actual: %i * %i", m_iTapNoteScores[tns], iTapScoreValue );
|
//LOG->Trace( "GetGrade actual: %i * %i", m_iTapNoteScores[tns], iTapScoreValue );
|
||||||
}
|
}
|
||||||
|
|
||||||
FOREACH_ENUM( HoldNoteScore, hns )
|
FOREACH_ENUM( HoldNoteScore, hns )
|
||||||
{
|
{
|
||||||
int iHoldScoreValue = ScoreKeeperNormal::HoldNoteScoreToGradePoints( hns, bIsBeginner );
|
int iHoldScoreValue = ScoreKeeperNormal::HoldNoteScoreToGradePoints( hns, bIsBeginner );
|
||||||
fActual += m_iHoldNoteScores[hns] * iHoldScoreValue;
|
fActual += m_iHoldNoteScores[hns] * iHoldScoreValue;
|
||||||
LOG->Trace( "GetGrade actual: %i * %i", m_iHoldNoteScores[hns], iHoldScoreValue );
|
//LOG->Trace( "GetGrade actual: %i * %i", m_iHoldNoteScores[hns], iHoldScoreValue );
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG->Trace( "GetGrade: fActual: %f, fPossible: %d", fActual, m_iPossibleGradePoints );
|
//LOG->Trace( "GetGrade: fActual: %f, fPossible: %d", fActual, m_iPossibleGradePoints );
|
||||||
|
|
||||||
|
|
||||||
float fPercent = (m_iPossibleGradePoints == 0) ? 0 : fActual / m_iPossibleGradePoints;
|
float fPercent = (m_iPossibleGradePoints == 0) ? 0 : fActual / m_iPossibleGradePoints;
|
||||||
|
|
||||||
Grade grade = GetGradeFromPercent( fPercent );
|
Grade grade = GetGradeFromPercent( fPercent );
|
||||||
|
|
||||||
LOG->Trace( "GetGrade: Grade: %s, %i", GradeToString(grade).c_str(), GRADE_TIER02_IS_ALL_W2S );
|
//LOG->Trace( "GetGrade: Grade: %s, %i", GradeToString(grade).c_str(), GRADE_TIER02_IS_ALL_W2S );
|
||||||
if( GRADE_TIER02_IS_ALL_W2S )
|
if( GRADE_TIER02_IS_ALL_W2S )
|
||||||
{
|
{
|
||||||
if( FullComboOfScore(TNS_W1) )
|
if( FullComboOfScore(TNS_W1) )
|
||||||
|
|||||||
@@ -1878,9 +1878,7 @@ void Profile::MoveBackupToDir( RString sFromDir, RString sToDir )
|
|||||||
RString Profile::MakeUniqueFileNameNoExtension( RString sDir, RString sFileNameBeginning )
|
RString Profile::MakeUniqueFileNameNoExtension( RString sDir, RString sFileNameBeginning )
|
||||||
{
|
{
|
||||||
FILEMAN->FlushDirCache( sDir );
|
FILEMAN->FlushDirCache( sDir );
|
||||||
//
|
|
||||||
// Find a file name for the screenshot
|
// Find a file name for the screenshot
|
||||||
//
|
|
||||||
vector<RString> files;
|
vector<RString> files;
|
||||||
GetDirListing( sDir + sFileNameBeginning+"*", files, false, false );
|
GetDirListing( sDir + sFileNameBeginning+"*", files, false, false );
|
||||||
sort( files.begin(), files.end() );
|
sort( files.begin(), files.end() );
|
||||||
|
|||||||
@@ -166,6 +166,12 @@ int RageFile::GetFileSize() const
|
|||||||
return m_File->GetFileSize();
|
return m_File->GetFileSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int RageFile::GetFD()
|
||||||
|
{
|
||||||
|
ASSERT_READ;
|
||||||
|
return m_File->GetFD();
|
||||||
|
}
|
||||||
|
|
||||||
int RageFile::Read( RString &buffer, int bytes )
|
int RageFile::Read( RString &buffer, int bytes )
|
||||||
{
|
{
|
||||||
ASSERT_READ;
|
ASSERT_READ;
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ public:
|
|||||||
int Tell() const;
|
int Tell() const;
|
||||||
int Seek( int offset );
|
int Seek( int offset );
|
||||||
int GetFileSize() const;
|
int GetFileSize() const;
|
||||||
|
int GetFD();
|
||||||
|
|
||||||
/* Raw I/O: */
|
/* Raw I/O: */
|
||||||
int Read( void *buffer, size_t bytes );
|
int Read( void *buffer, size_t bytes );
|
||||||
|
|||||||
@@ -53,6 +53,11 @@ public:
|
|||||||
virtual bool GetCRC32( uint32_t *iRet ) = 0;
|
virtual bool GetCRC32( uint32_t *iRet ) = 0;
|
||||||
|
|
||||||
virtual int GetFileSize() const = 0;
|
virtual int GetFileSize() const = 0;
|
||||||
|
|
||||||
|
/* If this file is backed by a file descriptor, return it. This is valid even
|
||||||
|
* if the file is being filtered or decompressed. If the file has no
|
||||||
|
* associated file descriptor, return -1. */
|
||||||
|
virtual int GetFD() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RageFileObj: public RageFileBasic
|
class RageFileObj: public RageFileBasic
|
||||||
@@ -88,6 +93,7 @@ public:
|
|||||||
bool GetCRC32( uint32_t *iRet );
|
bool GetCRC32( uint32_t *iRet );
|
||||||
|
|
||||||
virtual int GetFileSize() const = 0;
|
virtual int GetFileSize() const = 0;
|
||||||
|
virtual int GetFD() { return -1; }
|
||||||
virtual RString GetDisplayPath() const { return RString(); }
|
virtual RString GetDisplayPath() const { return RString(); }
|
||||||
virtual RageFileBasic *Copy() const { FAIL_M( "Copying unimplemented" ); }
|
virtual RageFileBasic *Copy() const { FAIL_M( "Copying unimplemented" ); }
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ public:
|
|||||||
int WriteInternal( const void *pBuffer, size_t iBytes ) { SetError( "Not implemented" ); return -1; }
|
int WriteInternal( const void *pBuffer, size_t iBytes ) { SetError( "Not implemented" ); return -1; }
|
||||||
int SeekInternal( int iOffset );
|
int SeekInternal( int iOffset );
|
||||||
int GetFileSize() const { return m_iUncompressedSize; }
|
int GetFileSize() const { return m_iUncompressedSize; }
|
||||||
|
int GetFD() { return m_pFile->GetFD(); }
|
||||||
RageFileObjInflate *Copy() const;
|
RageFileObjInflate *Copy() const;
|
||||||
|
|
||||||
void DeleteFileWhenFinished() { m_bFileOwned = true; }
|
void DeleteFileWhenFinished() { m_bFileOwned = true; }
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ public:
|
|||||||
virtual RageFileObjDirect *Copy() const;
|
virtual RageFileObjDirect *Copy() const;
|
||||||
virtual RString GetDisplayPath() const { return m_sPath; }
|
virtual RString GetDisplayPath() const { return m_sPath; }
|
||||||
virtual int GetFileSize() const;
|
virtual int GetFileSize() const;
|
||||||
|
virtual int GetFD();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool FinalFlush();
|
bool FinalFlush();
|
||||||
@@ -469,6 +470,11 @@ int RageFileObjDirect::GetFileSize() const
|
|||||||
return iRet;
|
return iRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int RageFileObjDirect::GetFD()
|
||||||
|
{
|
||||||
|
return m_iFD;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2004 Glenn Maynard, Chris Danford
|
* Copyright (c) 2003-2004 Glenn Maynard, Chris Danford
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
|||||||
@@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
* When streaming files in gameplay, we need to be able to access files without blocking.
|
||||||
|
* If we read data and it's not currently in the OS's read-ahead cache, we'll block while
|
||||||
|
* it reads, which will usually take 10-20ms and cause a frame skip.
|
||||||
|
*
|
||||||
|
* One common case of this is playing a background movie. We'll open the file when the
|
||||||
|
* screen loads, but it may not be played for over a minute, during which time we'll be
|
||||||
|
* streaming from other movies. When we come back, the file may not have any read-ahead
|
||||||
|
* waiting for us.
|
||||||
|
*
|
||||||
|
* Linux provides two calls that can help here:
|
||||||
|
*
|
||||||
|
* posix_readahead; this hints the OS that we're streaming a file, so it doesn't need to
|
||||||
|
* preserve cache behind where we've read. This reduces the chance of pushing other files
|
||||||
|
* out of cache. However, this can also cause new skips; if we need to rewind a movie and
|
||||||
|
* start it over, the beginning will be out of the cache.
|
||||||
|
*
|
||||||
|
* readahead: this explicitly triggers a specific file read-ahead. This blocks, so if we
|
||||||
|
* use this we need to do it in a thread.
|
||||||
|
*
|
||||||
|
* We work like this:
|
||||||
|
*
|
||||||
|
* - Persistantly cache the first N bytes of the file.
|
||||||
|
* - Open a worker thread for read-ahead, which is idle most of the time.
|
||||||
|
* - When we read from the first 128k of the file, take it directly out of our cache, and
|
||||||
|
* seek the file past our cache.
|
||||||
|
* - When any data is read from the cached part of the file and readahead hasn't been performed,
|
||||||
|
* trigger readahead() to be done in the worker thread, so data past our cache is ready when
|
||||||
|
* we get there.
|
||||||
|
* - When any data is read outside of the cached part of the file, reset our state so we know
|
||||||
|
* to do the readahead again the next time we're back at the start of the file.
|
||||||
|
*
|
||||||
|
* This means that reading should always be nonblocking, given these constraints:
|
||||||
|
* - We must consistently stream a file starting at the beginning, and don't seek to random points
|
||||||
|
* in the file.
|
||||||
|
* - We read the file slowly enough that we don't overtake the read-ahead cache, which for most
|
||||||
|
* streaming files shouldn't be a problem.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
#include "RageFileDriverReadAhead.h"
|
||||||
|
#include "RageLog.h"
|
||||||
|
#include "RageUtil.h"
|
||||||
|
#include "RageFileManager_ReadAhead.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <cerrno>
|
||||||
|
#if defined(WIN32)
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If GetFD() isn't supported on the underlying file, this filter won't do anything. */
|
||||||
|
bool RageFileDriverReadAhead::FileSupported( RageFileBasic *pFile )
|
||||||
|
{
|
||||||
|
return pFile->GetFD() != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* iReadAheadBytes is the number of bytes to cache at the start of the file, to serve data while
|
||||||
|
* the readahead is taking place. iPostBufferReadAhead is the number of bytes to actually read ahead. */
|
||||||
|
RageFileDriverReadAhead::RageFileDriverReadAhead( RageFileBasic *pFile, int iCacheBytes, int iPostBufferReadAhead )
|
||||||
|
{
|
||||||
|
if( iPostBufferReadAhead == -1 )
|
||||||
|
iPostBufferReadAhead = iCacheBytes;
|
||||||
|
|
||||||
|
m_pFile = pFile;
|
||||||
|
m_iFilePos = pFile->Tell();
|
||||||
|
m_bFileOwned = false;
|
||||||
|
m_bReadAheadNeeded = true;
|
||||||
|
m_iPostBufferReadAhead = iPostBufferReadAhead;
|
||||||
|
|
||||||
|
FillBuffer( iCacheBytes );
|
||||||
|
}
|
||||||
|
|
||||||
|
RageFileDriverReadAhead::RageFileDriverReadAhead( const RageFileDriverReadAhead &cpy ):
|
||||||
|
RageFileObj(cpy)
|
||||||
|
{
|
||||||
|
m_pFile = cpy.m_pFile->Copy();
|
||||||
|
m_sBuffer = cpy.m_sBuffer;
|
||||||
|
m_iFilePos = cpy.m_iFilePos;
|
||||||
|
m_bFileOwned = true;
|
||||||
|
m_iPostBufferReadAhead = cpy.m_iPostBufferReadAhead;
|
||||||
|
m_bReadAheadNeeded = cpy.m_bReadAheadNeeded;
|
||||||
|
|
||||||
|
RageFileManagerReadAhead::CacheHintStreaming( m_pFile );
|
||||||
|
}
|
||||||
|
|
||||||
|
RageFileDriverReadAhead::~RageFileDriverReadAhead()
|
||||||
|
{
|
||||||
|
if( m_bFileOwned )
|
||||||
|
delete m_pFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
RageFileDriverReadAhead *RageFileDriverReadAhead::Copy() const
|
||||||
|
{
|
||||||
|
RageFileDriverReadAhead *pRet = new RageFileDriverReadAhead( *this );
|
||||||
|
return pRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RageFileDriverReadAhead::FillBuffer( int iBytes )
|
||||||
|
{
|
||||||
|
int iOldPos = m_pFile->Tell();
|
||||||
|
m_pFile->Seek( 0 );
|
||||||
|
|
||||||
|
m_sBuffer = "";
|
||||||
|
m_pFile->Read( m_sBuffer, iBytes );
|
||||||
|
|
||||||
|
/* Seek back to where we were. If we're going back to the cached region, seek past it,
|
||||||
|
* like SeekInternal does. */
|
||||||
|
if( iOldPos < (int) m_sBuffer.size() )
|
||||||
|
iOldPos = m_sBuffer.size();
|
||||||
|
m_pFile->Seek( iOldPos );
|
||||||
|
|
||||||
|
/* Now that we're done moving the file pointer around, set the file's read-ahead hint,
|
||||||
|
* if supported. */
|
||||||
|
RageFileManagerReadAhead::CacheHintStreaming( m_pFile );
|
||||||
|
}
|
||||||
|
|
||||||
|
int RageFileDriverReadAhead::ReadInternal( void *pBuffer, size_t iBytes )
|
||||||
|
{
|
||||||
|
/* If we're in the buffered area, and we havn't already done read-ahead, start it. */
|
||||||
|
if( m_bReadAheadNeeded && m_iFilePos < (int) m_sBuffer.size() )
|
||||||
|
{
|
||||||
|
RageFileManagerReadAhead::ReadAhead( m_pFile, m_iPostBufferReadAhead );
|
||||||
|
|
||||||
|
m_bReadAheadNeeded = false;
|
||||||
|
}
|
||||||
|
else if( !m_bReadAheadNeeded && m_iFilePos >= (int) m_sBuffer.size() )
|
||||||
|
{
|
||||||
|
/* Reset, so next time we rewind we'll read-ahead again. */
|
||||||
|
m_bReadAheadNeeded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we can serve data out of the buffer, use it. */
|
||||||
|
if( m_iFilePos < (int) m_sBuffer.size() )
|
||||||
|
{
|
||||||
|
size_t iFromBuffer = min( iBytes, m_sBuffer.size() - m_iFilePos );
|
||||||
|
memcpy( pBuffer, m_sBuffer.data() + m_iFilePos, iFromBuffer );
|
||||||
|
m_iFilePos += iFromBuffer;
|
||||||
|
return iFromBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read out of the underlying file. */
|
||||||
|
int iRet = m_pFile->Read( pBuffer, iBytes );
|
||||||
|
if( iRet != -1 )
|
||||||
|
m_iFilePos += iRet;
|
||||||
|
return iRet;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int RageFileDriverReadAhead::SeekInternal( int iOffset )
|
||||||
|
{
|
||||||
|
if( iOffset < (int) m_sBuffer.size() )
|
||||||
|
{
|
||||||
|
/* This assumes that seeking the file won't block. This seems to be true in Linux, at least.
|
||||||
|
* Seek the actual file to just past our buffer, so the RageFileManagerReadAhead::ReadAhead
|
||||||
|
* call will read ahead from the correct position. */
|
||||||
|
m_pFile->Seek( m_sBuffer.size() );
|
||||||
|
m_iFilePos = iOffset;
|
||||||
|
return iOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_iFilePos = m_pFile->Seek( iOffset );
|
||||||
|
return m_iFilePos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010 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.
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
/* RageFileDriverReadAhead - Read-ahead hinting for seamless rewinding. */
|
||||||
|
|
||||||
|
#ifndef RAGE_FILE_DRIVER_READ_AHEAD_H
|
||||||
|
#define RAGE_FILE_DRIVER_READ_AHEAD_H
|
||||||
|
|
||||||
|
#include "RageFileBasic.h"
|
||||||
|
|
||||||
|
class RageFileDriverReadAhead: public RageFileObj
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/* This filter can only be used on supported files; test before using. */
|
||||||
|
static bool FileSupported( RageFileBasic *pFile );
|
||||||
|
|
||||||
|
/* pFile will be freed if DeleteFileWhenFinished is called. */
|
||||||
|
RageFileDriverReadAhead( RageFileBasic *pFile, int iCacheBytes, int iPostBufferReadAhead = -1 );
|
||||||
|
RageFileDriverReadAhead( const RageFileDriverReadAhead &cpy );
|
||||||
|
~RageFileDriverReadAhead();
|
||||||
|
RageFileDriverReadAhead *Copy() const;
|
||||||
|
|
||||||
|
void DeleteFileWhenFinished() { m_bFileOwned = true; }
|
||||||
|
|
||||||
|
virtual RString GetError() const { return m_pFile->GetError(); }
|
||||||
|
virtual void ClearError() { return m_pFile->ClearError(); }
|
||||||
|
|
||||||
|
int ReadInternal( void *pBuffer, size_t iBytes );
|
||||||
|
int WriteInternal( const void *pBuffer, size_t iBytes ) { return m_pFile->Write( pBuffer, iBytes ); }
|
||||||
|
int SeekInternal( int iOffset );
|
||||||
|
int GetFileSize() const { return m_pFile->GetFileSize(); }
|
||||||
|
int GetFD() { return m_pFile->GetFD(); }
|
||||||
|
int Tell() const { return m_iFilePos; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void FillBuffer( int iBytes );
|
||||||
|
|
||||||
|
RageFileBasic *m_pFile;
|
||||||
|
int m_iFilePos;
|
||||||
|
bool m_bFileOwned;
|
||||||
|
RString m_sBuffer;
|
||||||
|
int m_iPostBufferReadAhead;
|
||||||
|
bool m_bReadAheadNeeded;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010 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.
|
||||||
|
*/
|
||||||
|
|
||||||
@@ -20,6 +20,7 @@ public:
|
|||||||
int WriteInternal( const void *pBuffer, size_t iBytes ) { SetError( "Not implemented" ); return -1; }
|
int WriteInternal( const void *pBuffer, size_t iBytes ) { SetError( "Not implemented" ); return -1; }
|
||||||
int SeekInternal( int iOffset );
|
int SeekInternal( int iOffset );
|
||||||
int GetFileSize() const { return m_iFileSize; }
|
int GetFileSize() const { return m_iFileSize; }
|
||||||
|
int GetFD() { return m_pFile->GetFD(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RageFileBasic *m_pFile;
|
RageFileBasic *m_pFile;
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ enum ThreadRequest
|
|||||||
REQ_OPEN,
|
REQ_OPEN,
|
||||||
REQ_CLOSE,
|
REQ_CLOSE,
|
||||||
REQ_GET_FILE_SIZE,
|
REQ_GET_FILE_SIZE,
|
||||||
|
REQ_GET_FD,
|
||||||
REQ_READ,
|
REQ_READ,
|
||||||
REQ_WRITE,
|
REQ_WRITE,
|
||||||
REQ_SEEK,
|
REQ_SEEK,
|
||||||
@@ -78,6 +79,7 @@ public:
|
|||||||
RageFileBasic *Open( const RString &sPath, int iMode, int &iErr );
|
RageFileBasic *Open( const RString &sPath, int iMode, int &iErr );
|
||||||
void Close( RageFileBasic *pFile );
|
void Close( RageFileBasic *pFile );
|
||||||
int GetFileSize( RageFileBasic *&pFile );
|
int GetFileSize( RageFileBasic *&pFile );
|
||||||
|
int GetFD( RageFileBasic *&pFile );
|
||||||
int Seek( RageFileBasic *&pFile, int iPos, RString &sError );
|
int Seek( RageFileBasic *&pFile, int iPos, RString &sError );
|
||||||
int Read( RageFileBasic *&pFile, void *pBuf, int iSize, RString &sError );
|
int Read( RageFileBasic *&pFile, void *pBuf, int iSize, RString &sError );
|
||||||
int Write( RageFileBasic *&pFile, const void *pBuf, int iSize, RString &sError );
|
int Write( RageFileBasic *&pFile, const void *pBuf, int iSize, RString &sError );
|
||||||
@@ -377,6 +379,34 @@ int ThreadedFileWorker::GetFileSize( RageFileBasic *&pFile )
|
|||||||
return m_iResultRequest;
|
return m_iResultRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ThreadedFileWorker::GetFD( RageFileBasic *&pFile )
|
||||||
|
{
|
||||||
|
ASSERT( m_pChildDriver != NULL ); /* how did you get a file to begin with? */
|
||||||
|
|
||||||
|
/* If we're currently in a timed-out state, fail. */
|
||||||
|
if( IsTimedOut() )
|
||||||
|
{
|
||||||
|
this->Close( pFile );
|
||||||
|
pFile = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pFile == NULL )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
m_pRequestFile = pFile;
|
||||||
|
|
||||||
|
if( !DoRequest(REQ_GET_FD) )
|
||||||
|
{
|
||||||
|
/* If we time out, we can no longer access pFile. */
|
||||||
|
pFile = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pRequestFile = NULL;
|
||||||
|
|
||||||
|
return m_iResultRequest;
|
||||||
|
}
|
||||||
|
|
||||||
int ThreadedFileWorker::Seek( RageFileBasic *&pFile, int iPos, RString &sError )
|
int ThreadedFileWorker::Seek( RageFileBasic *&pFile, int iPos, RString &sError )
|
||||||
{
|
{
|
||||||
ASSERT( m_pChildDriver != NULL ); /* how did you get a file to begin with? */
|
ASSERT( m_pChildDriver != NULL ); /* how did you get a file to begin with? */
|
||||||
@@ -692,6 +722,23 @@ public:
|
|||||||
return m_iFileSize;
|
return m_iFileSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GetFD()
|
||||||
|
{
|
||||||
|
RString sError;
|
||||||
|
int iRet = m_pWorker->GetFD( m_pFile );
|
||||||
|
|
||||||
|
if( m_pFile == NULL )
|
||||||
|
{
|
||||||
|
SetError( "Operation timed out" );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( iRet == -1 )
|
||||||
|
SetError( sError );
|
||||||
|
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
|
||||||
RageFileBasic *Copy() const
|
RageFileBasic *Copy() const
|
||||||
{
|
{
|
||||||
RString sError;
|
RString sError;
|
||||||
|
|||||||
@@ -0,0 +1,174 @@
|
|||||||
|
#include "global.h"
|
||||||
|
#include "RageFileManager_ReadAhead.h"
|
||||||
|
#include "RageThreads.h"
|
||||||
|
#include "RageLog.h"
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <cerrno>
|
||||||
|
#if defined(WIN32)
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_POSIX_FADVISE)
|
||||||
|
void RageFileManagerReadAhead::Init() { }
|
||||||
|
void RageFileManagerReadAhead::Shutdown() { }
|
||||||
|
void RageFileManagerReadAhead::ReadAhead( RageFileBasic *pFile, int iBytes )
|
||||||
|
{
|
||||||
|
int iFD = pFile->GetFD();
|
||||||
|
if( iFD == -1 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
int iStart = lseek( iFD, 0, SEEK_CUR );
|
||||||
|
posix_fadvise( iFD, iStart, iBytes, POSIX_FADV_WILLNEED );
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#if 0
|
||||||
|
/* This doesn't currently work, because dup() locks the file position of the new FD with the old
|
||||||
|
* (which makes no sense at all), so it's not easy to read from a copy of the FD without
|
||||||
|
* interfering with the original. */
|
||||||
|
class RageFileReadAheadThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RageFileReadAheadThread( int iFD, int iFrom, int iBytes )
|
||||||
|
{
|
||||||
|
m_iFD = iFD;
|
||||||
|
m_iFrom = iFrom;
|
||||||
|
m_iBytes = iBytes;
|
||||||
|
m_bFinished = false;
|
||||||
|
|
||||||
|
m_WorkerThread.SetName( "Read-ahead thread" );
|
||||||
|
m_WorkerThread.Create( StartWorkerMain, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
~RageFileReadAheadThread()
|
||||||
|
{
|
||||||
|
close( m_iFD );
|
||||||
|
m_WorkerThread.Wait();
|
||||||
|
}
|
||||||
|
bool IsFinished() const { return m_bFinished; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static int StartWorkerMain( void *pThis )
|
||||||
|
{
|
||||||
|
((RageFileReadAheadThread *) (pThis))->WorkerMain();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorkerMain()
|
||||||
|
{
|
||||||
|
RString sBuffer;
|
||||||
|
int iFDCopy = dup( m_iFD );
|
||||||
|
if( iFDCopy != -1 )
|
||||||
|
{
|
||||||
|
char *pBuf = sBuffer.GetBuffer( m_iBytes );
|
||||||
|
lseek( iFDCopy, m_iFrom, SEEK_SET );
|
||||||
|
read( iFDCopy, pBuf, m_iBytes );
|
||||||
|
sBuffer.ReleaseBuffer( m_iBytes );
|
||||||
|
|
||||||
|
close( iFDCopy );
|
||||||
|
LOG->Trace("read");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bFinished = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RageThread m_WorkerThread;
|
||||||
|
|
||||||
|
bool m_bFinished;
|
||||||
|
int m_iFD;
|
||||||
|
int m_iFrom;
|
||||||
|
int m_iBytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static vector<RageFileReadAheadThread *> g_apReadAheads;
|
||||||
|
|
||||||
|
void RageFileManagerReadAhead::Init() { }
|
||||||
|
void RageFileManagerReadAhead::Shutdown()
|
||||||
|
{
|
||||||
|
for( size_t i = 0; i < g_apReadAheads.size(); ++i )
|
||||||
|
delete g_apReadAheads[i];
|
||||||
|
g_apReadAheads.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This emulates posix_fadvise(POSIX_FADV_WILLNEED), to force data into cache and hint the
|
||||||
|
* kernel to start read-ahead from that point. */
|
||||||
|
void RageFileManagerReadAhead::ReadAhead( RageFileBasic *pFile, int iBytes )
|
||||||
|
{
|
||||||
|
int iFD = pFile->GetFD();
|
||||||
|
if( iFD == -1 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
iFD = dup( iFD );
|
||||||
|
if( iFD == -1 )
|
||||||
|
{
|
||||||
|
LOG->Trace( "error: dup(): %s", strerror(errno) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iStart = lseek( iFD, 0, SEEK_CUR );
|
||||||
|
|
||||||
|
RageFileReadAheadThread *pReadAhead = new RageFileReadAheadThread( iFD, iStart, iBytes );
|
||||||
|
g_apReadAheads.push_back( pReadAhead );
|
||||||
|
|
||||||
|
for( size_t i = 0; i < g_apReadAheads.size(); ++i )
|
||||||
|
{
|
||||||
|
if( g_apReadAheads[i]->IsFinished() )
|
||||||
|
{
|
||||||
|
LOG->Trace("cleaned");
|
||||||
|
delete g_apReadAheads[i];
|
||||||
|
g_apReadAheads.erase( g_apReadAheads.begin()+i, g_apReadAheads.begin()+i+1 );
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void RageFileManagerReadAhead::Init() { }
|
||||||
|
void RageFileManagerReadAhead::Shutdown() { }
|
||||||
|
void RageFileManagerReadAhead::ReadAhead( RageFileBasic *pFile, int iBytes ) { }
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_POSIX_FADVISE)
|
||||||
|
void RageFileManagerReadAhead::CacheHintStreaming( RageFileBasic *pFile )
|
||||||
|
{
|
||||||
|
/* This guesses at the actual size of the file on disk, which may be smaller if this file is compressed.
|
||||||
|
* Since this is usually used on music and video files, it generally shouldn't be. */
|
||||||
|
int iFD = pFile->GetFD();
|
||||||
|
if( iFD == -1 )
|
||||||
|
return;
|
||||||
|
int iPos = pFile->Tell();
|
||||||
|
int iFrom = lseek( iFD, 0, SEEK_CUR );
|
||||||
|
int iBytes = pFile->GetFileSize() - iPos;
|
||||||
|
posix_fadvise( iFD, iFrom, iBytes, POSIX_FADV_SEQUENTIAL );
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void RageFileManagerReadAhead::CacheHintStreaming( RageFileBasic *pFile ) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010 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.
|
||||||
|
*/
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
#ifndef RAGE_FILE_MANAGER_READAHEAD_H
|
||||||
|
#define RAGE_FILE_MANAGER_READAHEAD_H
|
||||||
|
|
||||||
|
#include "RageFileBasic.h"
|
||||||
|
|
||||||
|
namespace RageFileManagerReadAhead
|
||||||
|
{
|
||||||
|
void Init();
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
/* Nonblockingly read bytes from a file. */
|
||||||
|
void ReadAhead( RageFileBasic *pFile, int iBytes );
|
||||||
|
|
||||||
|
void CacheHintStreaming( RageFileBasic *pFile );
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010 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.
|
||||||
|
*/
|
||||||
+7
-4
@@ -712,7 +712,7 @@ void ScreenEdit::Init()
|
|||||||
CopyToLastSave();
|
CopyToLastSave();
|
||||||
|
|
||||||
m_CurrentAction = MAIN_MENU_CHOICE_INVALID;
|
m_CurrentAction = MAIN_MENU_CHOICE_INVALID;
|
||||||
if( GAMESTATE->m_pCurSteps[0]->m_StepsType == StepsType_dance_routine )
|
if( GAMESTATE->GetCurrentStyle()->m_StyleType == StyleType_TwoPlayersSharedSides )
|
||||||
m_InputPlayerNumber = PLAYER_1;
|
m_InputPlayerNumber = PLAYER_1;
|
||||||
else
|
else
|
||||||
m_InputPlayerNumber = PLAYER_INVALID;
|
m_InputPlayerNumber = PLAYER_INVALID;
|
||||||
@@ -2179,6 +2179,12 @@ void ScreenEdit::InputPlay( const InputEventPlus &input, EditButton EditB )
|
|||||||
bool bRelease = input.type == IET_RELEASE;
|
bool bRelease = input.type == IET_RELEASE;
|
||||||
switch( input.pn )
|
switch( input.pn )
|
||||||
{
|
{
|
||||||
|
case PLAYER_2:
|
||||||
|
// ignore player 2 input unless this mode requires it
|
||||||
|
if( GAMESTATE->GetCurrentStyle()->m_StyleType != StyleType_TwoPlayersSharedSides )
|
||||||
|
break;
|
||||||
|
|
||||||
|
// fall through to input handling logic:
|
||||||
case PLAYER_1:
|
case PLAYER_1:
|
||||||
{
|
{
|
||||||
switch( gbt )
|
switch( gbt )
|
||||||
@@ -2199,9 +2205,6 @@ void ScreenEdit::InputPlay( const InputEventPlus &input, EditButton EditB )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PLAYER_2:
|
|
||||||
if( GAMESTATE->GetCurrentStyle()->m_StyleType == StyleType_TwoPlayersSharedSides )
|
|
||||||
m_Player->Step( iCol, -1, input.DeviceI.ts, false, input.type == IET_RELEASE );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -192,8 +192,10 @@ void ScreenSelectMusic::Init()
|
|||||||
this->SortByDrawOrder();
|
this->SortByDrawOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#include "RageTimer.h"
|
||||||
void ScreenSelectMusic::BeginScreen()
|
void ScreenSelectMusic::BeginScreen()
|
||||||
{
|
{
|
||||||
|
//RageTimer tm;
|
||||||
g_ScreenStartedLoadingAt.Touch();
|
g_ScreenStartedLoadingAt.Touch();
|
||||||
|
|
||||||
if( CommonMetrics::AUTO_SET_STYLE )
|
if( CommonMetrics::AUTO_SET_STYLE )
|
||||||
@@ -213,6 +215,7 @@ void ScreenSelectMusic::BeginScreen()
|
|||||||
GAMESTATE->m_PlayMode.Set( PLAY_MODE_REGULAR );
|
GAMESTATE->m_PlayMode.Set( PLAY_MODE_REGULAR );
|
||||||
LOG->Trace( "PlayMode not set, setting as regular." );
|
LOG->Trace( "PlayMode not set, setting as regular." );
|
||||||
}
|
}
|
||||||
|
//LOG->Trace("XXX 1 %f", tm.GetDeltaTime());
|
||||||
FOREACH_ENUM( PlayerNumber, pn )
|
FOREACH_ENUM( PlayerNumber, pn )
|
||||||
{
|
{
|
||||||
if( GAMESTATE->IsHumanPlayer(pn) )
|
if( GAMESTATE->IsHumanPlayer(pn) )
|
||||||
@@ -223,23 +226,30 @@ void ScreenSelectMusic::BeginScreen()
|
|||||||
|
|
||||||
OPTIONS_MENU_AVAILABLE.Load( m_sName, "OptionsMenuAvailable" );
|
OPTIONS_MENU_AVAILABLE.Load( m_sName, "OptionsMenuAvailable" );
|
||||||
PlayCommand( "Mods" );
|
PlayCommand( "Mods" );
|
||||||
|
//LOG->Trace("XXX 2a %f", tm.GetDeltaTime());
|
||||||
m_MusicWheel.BeginScreen();
|
m_MusicWheel.BeginScreen();
|
||||||
|
//LOG->Trace("XXX 2b %f", tm.GetDeltaTime());
|
||||||
|
|
||||||
m_SelectionState = SelectionState_SelectingSong;
|
m_SelectionState = SelectionState_SelectingSong;
|
||||||
ZERO( m_bStepsChosen );
|
ZERO( m_bStepsChosen );
|
||||||
m_bGoToOptions = false;
|
m_bGoToOptions = false;
|
||||||
m_bAllowOptionsMenu = m_bAllowOptionsMenuRepeat = false;
|
m_bAllowOptionsMenu = m_bAllowOptionsMenuRepeat = false;
|
||||||
ZERO( m_iSelection );
|
ZERO( m_iSelection );
|
||||||
|
//LOG->Trace("XXX 3 %f", tm.GetDeltaTime());
|
||||||
|
|
||||||
if( USE_OPTIONS_LIST )
|
if( USE_OPTIONS_LIST )
|
||||||
FOREACH_PlayerNumber( pn )
|
FOREACH_PlayerNumber( pn )
|
||||||
m_OptionsList[pn].Reset();
|
m_OptionsList[pn].Reset();
|
||||||
|
|
||||||
|
//LOG->Trace("XXX 4a %f", tm.GetDeltaTime());
|
||||||
AfterMusicChange();
|
AfterMusicChange();
|
||||||
|
//LOG->Trace("XXX 4b %f", tm.GetDeltaTime());
|
||||||
|
|
||||||
SOUND->PlayOnceFromAnnouncer( "select music intro" );
|
SOUND->PlayOnceFromAnnouncer( "select music intro" );
|
||||||
|
|
||||||
|
//LOG->Trace("XXX 4c %f", tm.GetDeltaTime());
|
||||||
ScreenWithMenuElements::BeginScreen();
|
ScreenWithMenuElements::BeginScreen();
|
||||||
|
//LOG->Trace("XXX 5 %f", tm.GetDeltaTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenSelectMusic::~ScreenSelectMusic()
|
ScreenSelectMusic::~ScreenSelectMusic()
|
||||||
|
|||||||
@@ -1753,6 +1753,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\
|
|||||||
<File
|
<File
|
||||||
RelativePath="RageFileDriverMemory.h">
|
RelativePath="RageFileDriverMemory.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\RageFileDriverReadAhead.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\RageFileDriverReadAhead.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="RageFileDriverSlice.cpp">
|
RelativePath="RageFileDriverSlice.cpp">
|
||||||
</File>
|
</File>
|
||||||
@@ -1777,6 +1783,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\
|
|||||||
<File
|
<File
|
||||||
RelativePath="RageFileManager.h">
|
RelativePath="RageFileManager.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\RageFileManager_ReadAhead.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\RageFileManager_ReadAhead.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\RageInput.cpp">
|
RelativePath=".\RageInput.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
|||||||
@@ -3050,6 +3050,14 @@
|
|||||||
RelativePath="RageFileDriverMemory.h"
|
RelativePath="RageFileDriverMemory.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\RageFileDriverReadAhead.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\RageFileDriverReadAhead.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="RageFileDriverSlice.cpp"
|
RelativePath="RageFileDriverSlice.cpp"
|
||||||
>
|
>
|
||||||
@@ -3082,6 +3090,14 @@
|
|||||||
RelativePath="RageFileManager.h"
|
RelativePath="RageFileManager.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\RageFileManager_ReadAhead.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\RageFileManager_ReadAhead.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\RageInput.cpp"
|
RelativePath=".\RageInput.cpp"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -3208,6 +3208,14 @@
|
|||||||
RelativePath="RageFileDriverMemory.h"
|
RelativePath="RageFileDriverMemory.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\RageFileDriverReadAhead.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\RageFileDriverReadAhead.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="RageFileDriverSlice.cpp"
|
RelativePath="RageFileDriverSlice.cpp"
|
||||||
>
|
>
|
||||||
@@ -3240,6 +3248,14 @@
|
|||||||
RelativePath="RageFileManager.h"
|
RelativePath="RageFileManager.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\RageFileManager_ReadAhead.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\RageFileManager_ReadAhead.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\RageInput.cpp"
|
RelativePath=".\RageInput.cpp"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1272,10 +1272,8 @@ RString StepMania::SaveScreenshot( RString sDir, bool bSaveCompressed, bool bMak
|
|||||||
else
|
else
|
||||||
sFileNameNoExtension = Profile::MakeFileNameNoExtension( "screen", iIndex );
|
sFileNameNoExtension = Profile::MakeFileNameNoExtension( "screen", iIndex );
|
||||||
|
|
||||||
//
|
|
||||||
// Save the screenshot. If writing lossy to a memcard, use SAVE_LOSSY_LOW_QUAL, so we
|
// Save the screenshot. If writing lossy to a memcard, use SAVE_LOSSY_LOW_QUAL, so we
|
||||||
// don't eat up lots of space.
|
// don't eat up lots of space.
|
||||||
//
|
|
||||||
RageDisplay::GraphicsFileFormat fmt;
|
RageDisplay::GraphicsFileFormat fmt;
|
||||||
if( bSaveCompressed && MEMCARDMAN->PathIsMemCard(sDir) )
|
if( bSaveCompressed && MEMCARDMAN->PathIsMemCard(sDir) )
|
||||||
fmt = RageDisplay::SAVE_LOSSY_LOW_QUAL;
|
fmt = RageDisplay::SAVE_LOSSY_LOW_QUAL;
|
||||||
|
|||||||
@@ -1949,6 +1949,12 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
|||||||
<File
|
<File
|
||||||
RelativePath=".\RageFileDriverMemory.h">
|
RelativePath=".\RageFileDriverMemory.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\RageFileDriverReadAhead.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\RageFileDriverReadAhead.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\RageFileDriverSlice.cpp">
|
RelativePath=".\RageFileDriverSlice.cpp">
|
||||||
</File>
|
</File>
|
||||||
@@ -1973,6 +1979,12 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
|||||||
<File
|
<File
|
||||||
RelativePath="RageFileManager.h">
|
RelativePath="RageFileManager.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\RageFileManager_ReadAhead.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\RageFileManager_ReadAhead.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\RageInput.cpp">
|
RelativePath=".\RageInput.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ StreamDisplay::StreamDisplay()
|
|||||||
|
|
||||||
void StreamDisplay::Load( const RString &_sMetricsGroup )
|
void StreamDisplay::Load( const RString &_sMetricsGroup )
|
||||||
{
|
{
|
||||||
// XXX
|
// XXX: actually load from the metrics group passed in -aj
|
||||||
RString sMetricsGroup = "StreamDisplay";
|
RString sMetricsGroup = "StreamDisplay";
|
||||||
|
|
||||||
m_transformPill.SetFromReference( THEME->GetMetricR(sMetricsGroup,"PillTransformFunction") );
|
m_transformPill.SetFromReference( THEME->GetMetricR(sMetricsGroup,"PillTransformFunction") );
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "RageUtil.h"
|
#include "RageUtil.h"
|
||||||
#include "RageFile.h"
|
#include "RageFile.h"
|
||||||
#include "RageSurface.h"
|
#include "RageSurface.h"
|
||||||
|
#include "RageFileDriverReadAhead.h"
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
|
||||||
@@ -639,6 +640,9 @@ int URLRageFile_open( avcodec::URLContext *h, const char *filename, int flags )
|
|||||||
case URL_RDWR: FAIL_M( "O_RDWR unsupported" );
|
case URL_RDWR: FAIL_M( "O_RDWR unsupported" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RageFileBasic *pFile = new RageFile;
|
||||||
|
|
||||||
|
{
|
||||||
RageFile *f = new RageFile;
|
RageFile *f = new RageFile;
|
||||||
if( !f->Open(filename, mode) )
|
if( !f->Open(filename, mode) )
|
||||||
{
|
{
|
||||||
@@ -646,21 +650,31 @@ int URLRageFile_open( avcodec::URLContext *h, const char *filename, int flags )
|
|||||||
delete f;
|
delete f;
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
pFile = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If possible, wrap this file in the read-ahead filter to avoid skips when we rewind.
|
||||||
|
if( RageFileDriverReadAhead::FileSupported(pFile) )
|
||||||
|
{
|
||||||
|
RageFileDriverReadAhead *pBufferedFile = new RageFileDriverReadAhead( pFile, 1024*128 );
|
||||||
|
pBufferedFile->DeleteFileWhenFinished();
|
||||||
|
pFile = pBufferedFile;
|
||||||
|
}
|
||||||
|
|
||||||
h->is_streamed = false;
|
h->is_streamed = false;
|
||||||
h->priv_data = f;
|
h->priv_data = pFile;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int URLRageFile_read( avcodec::URLContext *h, unsigned char *buf, int size )
|
int URLRageFile_read( avcodec::URLContext *h, unsigned char *buf, int size )
|
||||||
{
|
{
|
||||||
RageFile *f = (RageFile *) h->priv_data;
|
RageFileBasic *f = (RageFileBasic *) h->priv_data;
|
||||||
return f->Read( buf, size );
|
return f->Read( buf, size );
|
||||||
}
|
}
|
||||||
|
|
||||||
int URLRageFile_write( avcodec::URLContext *h, unsigned char *buf, int size )
|
int URLRageFile_write( avcodec::URLContext *h, unsigned char *buf, int size )
|
||||||
{
|
{
|
||||||
RageFile *f = (RageFile *) h->priv_data;
|
RageFileBasic *f = (RageFileBasic *) h->priv_data;
|
||||||
return f->Write( buf, size );
|
return f->Write( buf, size );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -671,7 +685,7 @@ int URLRageFile_write( avcodec::URLContext *h, unsigned char *buf, int size )
|
|||||||
avcodec::int64_t URLRageFile_seek( avcodec::URLContext *h, avcodec::int64_t pos, int whence )
|
avcodec::int64_t URLRageFile_seek( avcodec::URLContext *h, avcodec::int64_t pos, int whence )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
RageFile *f = (RageFile *) h->priv_data;
|
RageFileBasic *f = (RageFileBasic *) h->priv_data;
|
||||||
if( whence == AVSEEK_SIZE )
|
if( whence == AVSEEK_SIZE )
|
||||||
return f->GetFileSize();
|
return f->GetFileSize();
|
||||||
|
|
||||||
@@ -683,7 +697,7 @@ int URLRageFile_write( avcodec::URLContext *h, unsigned char *buf, int size )
|
|||||||
|
|
||||||
int URLRageFile_close( avcodec::URLContext *h )
|
int URLRageFile_close( avcodec::URLContext *h )
|
||||||
{
|
{
|
||||||
RageFile *f = (RageFile *) h->priv_data;
|
RageFileBasic *f = (RageFileBasic *) h->priv_data;
|
||||||
delete f;
|
delete f;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-1
@@ -14,7 +14,6 @@
|
|||||||
# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
|
# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
|
||||||
|
|
||||||
# serial 47 AC_PROG_LIBTOOL
|
# serial 47 AC_PROG_LIBTOOL
|
||||||
# Debian $Rev: 8581 $
|
|
||||||
|
|
||||||
|
|
||||||
# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED)
|
# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED)
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ modename="$progname"
|
|||||||
PROGRAM=ltmain.sh
|
PROGRAM=ltmain.sh
|
||||||
PACKAGE=libtool
|
PACKAGE=libtool
|
||||||
VERSION=1.5.2
|
VERSION=1.5.2
|
||||||
TIMESTAMP=" (1.1220.2.60 2004/01/25 12:25:08) Debian$Rev: 8581 $"
|
|
||||||
|
|
||||||
default_mode=
|
default_mode=
|
||||||
help="Try \`$progname --help' for more information."
|
help="Try \`$progname --help' for more information."
|
||||||
|
|||||||
Reference in New Issue
Block a user