huge merge
This commit is contained in:
+1
-1
@@ -12,7 +12,7 @@ class XNode;
|
||||
class AutoActor
|
||||
{
|
||||
public:
|
||||
AutoActor() { m_pActor = NULL; }
|
||||
AutoActor(): m_pActor(NULL) {}
|
||||
~AutoActor() { Unload(); }
|
||||
AutoActor( const AutoActor &cpy );
|
||||
AutoActor &operator =( const AutoActor &cpy );
|
||||
|
||||
@@ -99,7 +99,7 @@ void AutoKeysounds::LoadAutoplaySoundsInto( RageSoundReader_Chain *pChain )
|
||||
if( tn[pn].iKeysoundIndex >= 0 )
|
||||
{
|
||||
RString sKeysoundFilePath = sSongDir + pSong->m_vsKeysoundFile[tn[pn].iKeysoundIndex];
|
||||
float fSeconds = pSong->m_Timing.GetElapsedTimeFromBeat( NoteRowToBeat(iRow) );
|
||||
float fSeconds = pSong->m_Timing.GetElapsedTimeFromBeatNoOffset( NoteRowToBeat(iRow) ) + SOUNDMAN->GetPlayLatency();
|
||||
|
||||
float fPan = 0;
|
||||
if( !bSoundIsGlobal )
|
||||
|
||||
+14
-3
@@ -180,8 +180,8 @@ void BPMDisplay::SetBpmFromSong( const Song* pSong )
|
||||
ASSERT( pSong );
|
||||
switch( pSong->m_DisplayBPMType )
|
||||
{
|
||||
case Song::DISPLAY_ACTUAL:
|
||||
case Song::DISPLAY_SPECIFIED:
|
||||
case DISPLAY_BPM_ACTUAL:
|
||||
case DISPLAY_BPM_SPECIFIED:
|
||||
{
|
||||
DisplayBpms bpms;
|
||||
pSong->GetDisplayBpms( bpms );
|
||||
@@ -189,7 +189,7 @@ void BPMDisplay::SetBpmFromSong( const Song* pSong )
|
||||
m_fCycleTime = 1.0f;
|
||||
}
|
||||
break;
|
||||
case Song::DISPLAY_RANDOM:
|
||||
case DISPLAY_BPM_RANDOM:
|
||||
CycleRandomly();
|
||||
break;
|
||||
default:
|
||||
@@ -294,11 +294,22 @@ class LunaBPMDisplay: public Luna<BPMDisplay>
|
||||
{
|
||||
public:
|
||||
static int SetFromGameState( T* p, lua_State *L ) { p->SetFromGameState(); return 0; }
|
||||
static int SetFromSong( T* p, lua_State *L )
|
||||
{
|
||||
if( lua_isnil(L,1) ) { p->NoBPM(); }
|
||||
else
|
||||
{
|
||||
const Song* pSong = Luna<Song>::check( L, 1, true );
|
||||
p->SetBpmFromSong(pSong);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int GetText( T* p, lua_State *L ) { lua_pushstring( L, p->GetText() ); return 1; }
|
||||
|
||||
LunaBPMDisplay()
|
||||
{
|
||||
ADD_METHOD( SetFromGameState );
|
||||
ADD_METHOD( SetFromSong );
|
||||
ADD_METHOD( GetText );
|
||||
}
|
||||
};
|
||||
|
||||
+20
-14
@@ -27,15 +27,26 @@ struct BackgroundDef
|
||||
RString m_sColor2; // "" == use default
|
||||
|
||||
XNode *CreateNode() const;
|
||||
|
||||
/** @brief Set up the BackgroundDef with default values. */
|
||||
BackgroundDef(): m_sEffect(""), m_sFile1(""), m_sFile2(""),
|
||||
m_sColor1(""), m_sColor2("") {}
|
||||
|
||||
/**
|
||||
* @brief Set up the BackgroundDef with some defined values.
|
||||
* @param effect the intended effect.
|
||||
* @param f1 the primary filename for the definition.
|
||||
* @param f2 the secondary filename (optional). */
|
||||
BackgroundDef(RString effect, RString f1, RString f2):
|
||||
m_sEffect(effect), m_sFile1(f1), m_sFile2(f2),
|
||||
m_sColor1(""), m_sColor2("") {}
|
||||
};
|
||||
|
||||
struct BackgroundChange
|
||||
{
|
||||
BackgroundChange()
|
||||
{
|
||||
m_fStartBeat=-1;
|
||||
m_fRate=1;
|
||||
}
|
||||
BackgroundChange(): m_def(), m_fStartBeat(-1), m_fRate(1),
|
||||
m_sTransition("") {}
|
||||
|
||||
BackgroundChange(
|
||||
float s,
|
||||
RString f1,
|
||||
@@ -43,15 +54,10 @@ struct BackgroundChange
|
||||
float r=1.f,
|
||||
RString e=SBE_Centered,
|
||||
RString t=RString()
|
||||
)
|
||||
{
|
||||
m_fStartBeat=s;
|
||||
m_def.m_sFile1=f1;
|
||||
m_def.m_sFile2=f2;
|
||||
m_fRate=r;
|
||||
m_def.m_sEffect=e;
|
||||
m_sTransition=t;
|
||||
}
|
||||
):
|
||||
m_def(e, f1, f2), m_fStartBeat(s),
|
||||
m_fRate(r), m_sTransition(t) {}
|
||||
|
||||
BackgroundDef m_def;
|
||||
float m_fStartBeat;
|
||||
float m_fRate;
|
||||
|
||||
+4
-1
@@ -17,6 +17,9 @@ REGISTER_ACTOR_CLASS( Banner );
|
||||
|
||||
ThemeMetric<bool> SCROLL_RANDOM ("Banner","ScrollRandom");
|
||||
ThemeMetric<bool> SCROLL_ROULETTE ("Banner","ScrollRoulette");
|
||||
//ThemeMetric<bool> SCROLL_MODE ("Banner","ScrollMode");
|
||||
//ThemeMetric<bool> SCROLL_SORT_ORDER ("Banner","ScrollSortOrder");
|
||||
ThemeMetric<float> SCROLL_SPEED_DIVISOR ("Banner","ScrollSpeedDivisor");
|
||||
|
||||
Banner::Banner()
|
||||
{
|
||||
@@ -79,7 +82,7 @@ void Banner::Update( float fDeltaTime )
|
||||
|
||||
if( m_bScrolling )
|
||||
{
|
||||
m_fPercentScrolling += fDeltaTime/2;
|
||||
m_fPercentScrolling += fDeltaTime/(float)SCROLL_SPEED_DIVISOR;
|
||||
m_fPercentScrolling -= (int)m_fPercentScrolling;
|
||||
|
||||
const RectF *pTextureRect = GetCurrentTextureCoordRect();
|
||||
|
||||
+4
-8
@@ -230,17 +230,13 @@ struct BannerTexture: public RageTexture
|
||||
m_iTextureWidth = m_iImageWidth = m_pImage->w;
|
||||
m_iTextureHeight = m_iImageHeight = m_pImage->h;
|
||||
|
||||
/* Find a supported texture format. If it happens to match the stored
|
||||
* file, we won't have to do any conversion here, and that'll happen often
|
||||
* with paletted images. */
|
||||
#if !defined(XBOX)
|
||||
/* Find a supported texture format. If it happens to match the stored
|
||||
* file, we won't have to do any conversion here, and that'll happen
|
||||
* often with paletted images. */
|
||||
PixelFormat pf = m_pImage->format->BitsPerPixel == 8? PixelFormat_PAL: PixelFormat_RGB5A1;
|
||||
if( !DISPLAY->SupportsTextureFormat(pf) )
|
||||
pf = PixelFormat_RGBA4;
|
||||
#else
|
||||
// xbox display currently supports only rgba8
|
||||
PixelFormat pf = PixelFormat_RGBA8;
|
||||
#endif
|
||||
|
||||
ASSERT( DISPLAY->SupportsTextureFormat(pf) );
|
||||
|
||||
ASSERT(m_pImage);
|
||||
|
||||
+133
-122
@@ -12,12 +12,12 @@
|
||||
#include "ScreenDimensions.h"
|
||||
#include "ThemeManager.h"
|
||||
|
||||
// "PLAYER_X" offsets are relative to the pad.. ex: Setting this to 10, and the HELPER to 300, will put the dancer at 310
|
||||
#define PLAYER_X( px ) THEME->GetMetricF("BeginnerHelper",ssprintf("Player%d_X",px+1))
|
||||
// "PLAYER_X" offsets are relative to the pad. ex: Setting this to 10, and the HELPER to 300, will put the dancer at 310
|
||||
#define PLAYER_X( px ) THEME->GetMetricF("BeginnerHelper",ssprintf("Player%dX",px+1))
|
||||
#define PLAYER_ANGLE THEME->GetMetricF("BeginnerHelper","PlayerAngle")
|
||||
#define DANCEPAD_ANGLE THEME->GetMetricF("BeginnerHelper","DancePadAngle")
|
||||
|
||||
// "HELPER" offsets effect the pad/dancer as a whole.. Their relative Y cooridinates are hard-coded for eachother.
|
||||
// "HELPER" offsets effect the pad/dancer as a whole. Their relative Y cooridinates are hard-coded for each other.
|
||||
#define HELPER_X THEME->GetMetricF("BeginnerHelper","HelperX")
|
||||
#define HELPER_Y THEME->GetMetricF("BeginnerHelper","HelperY")
|
||||
|
||||
@@ -75,6 +75,108 @@ BeginnerHelper::~BeginnerHelper()
|
||||
delete m_pDancePad;
|
||||
}
|
||||
|
||||
bool BeginnerHelper::Init( int iDancePadType )
|
||||
{
|
||||
ASSERT( !m_bInitialized );
|
||||
if( !CanUse() )
|
||||
return false;
|
||||
|
||||
// If no players were successfully added, bail.
|
||||
{
|
||||
bool bAnyLoaded = false;
|
||||
for( int pn=0; pn<NUM_PLAYERS; pn++ )
|
||||
if( m_bPlayerEnabled[pn] )
|
||||
bAnyLoaded = true;
|
||||
|
||||
if( !bAnyLoaded )
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load the Background and flash. Flash only shows if the BG does.
|
||||
if( m_bShowBackground )
|
||||
{
|
||||
m_sBackground.Load( THEME->GetPathG("BeginnerHelper","background") );
|
||||
this->AddChild( m_sBackground );
|
||||
//m_sBackground.SetXY( 1, 1 );
|
||||
|
||||
m_sFlash.Load( THEME->GetPathG("BeginnerHelper","flash") );
|
||||
m_sFlash.SetXY( 0, 0 );
|
||||
m_sFlash.SetDiffuseAlpha( 0 );
|
||||
}
|
||||
|
||||
// Load StepCircle graphics
|
||||
for( int lsc=0; lsc<NUM_PLAYERS; lsc++ )
|
||||
{
|
||||
for( int lsce=0; lsce<4; lsce++ )
|
||||
{
|
||||
m_sStepCircle[lsc][lsce].Load( THEME->GetPathG("BeginnerHelper","stepcircle") );
|
||||
m_sStepCircle[lsc][lsce].SetZoom( 0 ); // Hide until needed.
|
||||
this->AddChild(&m_sStepCircle[lsc][lsce]);
|
||||
|
||||
// Set StepCircle coordinates
|
||||
switch( lsce )
|
||||
{
|
||||
case 0: m_sStepCircle[lsc][lsce].SetXY((HELPER_X+PLAYER_X(lsc)-80),HELPER_Y); break; // Left
|
||||
case 1: m_sStepCircle[lsc][lsce].SetXY((HELPER_X+PLAYER_X(lsc)+80),HELPER_Y); break; // Right
|
||||
case 2: m_sStepCircle[lsc][lsce].SetXY((HELPER_X+PLAYER_X(lsc)),(HELPER_Y-60)); break; // Up
|
||||
case 3: m_sStepCircle[lsc][lsce].SetXY((HELPER_X+PLAYER_X(lsc)),(HELPER_Y+60)); break; // Down
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SHOW_DANCE_PAD.Load( "BeginnerHelper","ShowDancePad" );
|
||||
// Load the DancePad
|
||||
if( SHOW_DANCE_PAD )
|
||||
{
|
||||
switch( iDancePadType )
|
||||
{
|
||||
case 0: break; // No pad
|
||||
case 1: m_pDancePad->LoadMilkshapeAscii(GetAnimPath(ANIM_DANCE_PAD)); break;
|
||||
case 2: m_pDancePad->LoadMilkshapeAscii(GetAnimPath(ANIM_DANCE_PADS)); break;
|
||||
}
|
||||
|
||||
m_pDancePad->SetHorizAlign( align_left ); // xxx: hardcoded -aj
|
||||
m_pDancePad->SetRotationX( DANCEPAD_ANGLE );
|
||||
m_pDancePad->SetX( HELPER_X );
|
||||
m_pDancePad->SetY( HELPER_Y );
|
||||
// xxx: hardcoded -aj
|
||||
m_pDancePad->SetZoom( 23 ); // Pad should always be 3 units bigger in zoom than the dancer.
|
||||
}
|
||||
|
||||
for( int pl=0; pl<NUM_PLAYERS; pl++ ) // Load players
|
||||
{
|
||||
// Skip if not enabled
|
||||
if( !m_bPlayerEnabled[pl] )
|
||||
continue;
|
||||
|
||||
// Load character data
|
||||
const Character *Character = GAMESTATE->m_pCurCharacters[pl];
|
||||
ASSERT( Character != NULL );
|
||||
|
||||
// Load textures
|
||||
m_pDancer[pl]->SetHorizAlign( align_left );
|
||||
m_pDancer[pl]->LoadMilkshapeAscii( Character->GetModelPath() );
|
||||
|
||||
// Load needed animations
|
||||
m_pDancer[pl]->LoadMilkshapeAsciiBones( "Step-LEFT", GetAnimPath(ANIM_LEFT) );
|
||||
m_pDancer[pl]->LoadMilkshapeAsciiBones( "Step-DOWN", GetAnimPath(ANIM_DOWN) );
|
||||
m_pDancer[pl]->LoadMilkshapeAsciiBones( "Step-UP", GetAnimPath(ANIM_UP) );
|
||||
m_pDancer[pl]->LoadMilkshapeAsciiBones( "Step-RIGHT", GetAnimPath(ANIM_RIGHT) );
|
||||
m_pDancer[pl]->LoadMilkshapeAsciiBones( "Step-JUMPLR", GetAnimPath(ANIM_JUMPLR) );
|
||||
m_pDancer[pl]->LoadMilkshapeAsciiBones( "rest", Character->GetRestAnimationPath() );
|
||||
m_pDancer[pl]->SetDefaultAnimation( "rest" ); // Stay bouncing after a step has finished animating
|
||||
m_pDancer[pl]->PlayAnimation( "rest" );
|
||||
m_pDancer[pl]->SetRotationX( PLAYER_ANGLE );
|
||||
m_pDancer[pl]->SetX( HELPER_X+PLAYER_X(pl) );
|
||||
m_pDancer[pl]->SetY( HELPER_Y+10 );
|
||||
m_pDancer[pl]->SetZoom( 20 );
|
||||
m_pDancer[pl]->SetCullMode( CULL_NONE ); // many of the models floating around have the vertex order flipped
|
||||
}
|
||||
|
||||
m_bInitialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void BeginnerHelper::ShowStepCircle( PlayerNumber pn, int CSTEP )
|
||||
{
|
||||
int isc=0; // Save OR issues within array boundries.. it's worth the extra few bytes of memory.
|
||||
@@ -120,102 +222,6 @@ bool BeginnerHelper::CanUse()
|
||||
return GAMESTATE->GetCurrentStyle()->m_bCanUseBeginnerHelper;
|
||||
}
|
||||
|
||||
bool BeginnerHelper::Initialize( int iDancePadType )
|
||||
{
|
||||
ASSERT( !m_bInitialized );
|
||||
if( !CanUse() )
|
||||
return false;
|
||||
|
||||
// If no players were successfully added, bail.
|
||||
{
|
||||
bool bAnyLoaded = false;
|
||||
for( int pn=0; pn<NUM_PLAYERS; pn++ )
|
||||
if( m_bPlayerEnabled[pn] )
|
||||
bAnyLoaded = true;
|
||||
|
||||
if( !bAnyLoaded )
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load the Background and flash.. Flash only shows if the BG does.
|
||||
if( m_bShowBackground )
|
||||
{
|
||||
m_sBackground.Load( THEME->GetPathG("BeginnerHelper","background") );
|
||||
this->AddChild( &m_sBackground );
|
||||
m_sBackground.SetXY( 1, 1 );
|
||||
m_sFlash.Load( THEME->GetPathG("BeginnerHelper","flash") );
|
||||
m_sFlash.SetXY( 0, 0 );
|
||||
m_sFlash.SetDiffuseAlpha( 0 );
|
||||
}
|
||||
|
||||
// Load StepCircle graphics
|
||||
for( int lsc=0; lsc<NUM_PLAYERS; lsc++ )
|
||||
{
|
||||
for( int lsce=0; lsce<4; lsce++ )
|
||||
{
|
||||
m_sStepCircle[lsc][lsce].Load( THEME->GetPathG("BeginnerHelper","stepcircle") );
|
||||
m_sStepCircle[lsc][lsce].SetZoom( 0 ); // Hide until needed.
|
||||
this->AddChild(&m_sStepCircle[lsc][lsce]);
|
||||
|
||||
// Set coordinates of StepCircle
|
||||
switch( lsce )
|
||||
{
|
||||
case 0: m_sStepCircle[lsc][lsce].SetXY((HELPER_X+PLAYER_X(lsc)-80),HELPER_Y); break; // Left
|
||||
case 1: m_sStepCircle[lsc][lsce].SetXY((HELPER_X+PLAYER_X(lsc)+80),HELPER_Y); break; // Right
|
||||
case 2: m_sStepCircle[lsc][lsce].SetXY((HELPER_X+PLAYER_X(lsc)),(HELPER_Y-60)); break; // Up
|
||||
case 3: m_sStepCircle[lsc][lsce].SetXY((HELPER_X+PLAYER_X(lsc)),(HELPER_Y+60)); break; // Down
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load the DancePad
|
||||
switch( iDancePadType )
|
||||
{
|
||||
case 0: break; // No pad
|
||||
case 1: m_pDancePad->LoadMilkshapeAscii(GetAnimPath(ANIM_DANCE_PAD)); break;
|
||||
case 2: m_pDancePad->LoadMilkshapeAscii(GetAnimPath(ANIM_DANCE_PADS)); break;
|
||||
}
|
||||
|
||||
m_pDancePad->SetHorizAlign( align_left );
|
||||
m_pDancePad->SetRotationX( DANCEPAD_ANGLE );
|
||||
m_pDancePad->SetX( HELPER_X );
|
||||
m_pDancePad->SetY( HELPER_Y );
|
||||
m_pDancePad->SetZoom( 23 ); // Pad should always be 3 units bigger in zoom than the dancer.
|
||||
|
||||
for( int pl=0; pl<NUM_PLAYERS; pl++ ) // Load players
|
||||
{
|
||||
// Skip if not enabled
|
||||
if( !m_bPlayerEnabled[pl] )
|
||||
continue;
|
||||
|
||||
// Load character data
|
||||
const Character *Character = GAMESTATE->m_pCurCharacters[pl];
|
||||
ASSERT( Character != NULL );
|
||||
|
||||
// Load textures
|
||||
m_pDancer[pl]->SetHorizAlign( align_left );
|
||||
m_pDancer[pl]->LoadMilkshapeAscii( Character->GetModelPath() );
|
||||
|
||||
// Load needed animations
|
||||
m_pDancer[pl]->LoadMilkshapeAsciiBones( "Step-LEFT", GetAnimPath(ANIM_LEFT) );
|
||||
m_pDancer[pl]->LoadMilkshapeAsciiBones( "Step-DOWN", GetAnimPath(ANIM_DOWN) );
|
||||
m_pDancer[pl]->LoadMilkshapeAsciiBones( "Step-UP", GetAnimPath(ANIM_UP) );
|
||||
m_pDancer[pl]->LoadMilkshapeAsciiBones( "Step-RIGHT", GetAnimPath(ANIM_RIGHT) );
|
||||
m_pDancer[pl]->LoadMilkshapeAsciiBones( "Step-JUMPLR", GetAnimPath(ANIM_JUMPLR) );
|
||||
m_pDancer[pl]->LoadMilkshapeAsciiBones( "rest", Character->GetRestAnimationPath() );
|
||||
m_pDancer[pl]->SetDefaultAnimation( "rest" ); // Stay bouncing after a step has finished animating
|
||||
m_pDancer[pl]->PlayAnimation( "rest" );
|
||||
m_pDancer[pl]->SetRotationX( PLAYER_ANGLE );
|
||||
m_pDancer[pl]->SetX( HELPER_X+PLAYER_X(pl) );
|
||||
m_pDancer[pl]->SetY( HELPER_Y+10 );
|
||||
m_pDancer[pl]->SetZoom( 20 );
|
||||
m_pDancer[pl]->SetCullMode( CULL_NONE ); // many of the models floating around have the vertex order flipped
|
||||
}
|
||||
|
||||
m_bInitialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void BeginnerHelper::DrawPrimitives()
|
||||
{
|
||||
// If not initialized, don't bother with this
|
||||
@@ -226,32 +232,37 @@ void BeginnerHelper::DrawPrimitives()
|
||||
m_sFlash.Draw();
|
||||
|
||||
bool DrawCelShaded = PREFSMAN->m_bCelShadeModels;
|
||||
if( DrawCelShaded )
|
||||
m_pDancePad->DrawCelShaded();
|
||||
else
|
||||
// Draw Pad
|
||||
if( SHOW_DANCE_PAD )
|
||||
{
|
||||
DISPLAY->SetLighting( true );
|
||||
DISPLAY->SetLightDirectional(
|
||||
0,
|
||||
RageColor(0.5,0.5,0.5,1),
|
||||
RageColor(1,1,1,1),
|
||||
RageColor(0,0,0,1),
|
||||
RageVector3(0, 0, 1) );
|
||||
if( DrawCelShaded )
|
||||
m_pDancePad->DrawCelShaded();
|
||||
else
|
||||
{
|
||||
DISPLAY->SetLighting( true );
|
||||
DISPLAY->SetLightDirectional(
|
||||
0,
|
||||
RageColor(0.5,0.5,0.5,1),
|
||||
RageColor(1,1,1,1),
|
||||
RageColor(0,0,0,1),
|
||||
RageVector3(0, 0, 1) );
|
||||
|
||||
m_pDancePad->Draw();
|
||||
DISPLAY->ClearZBuffer(); // So character doesn't step "into" the dance pad.
|
||||
DISPLAY->SetLightOff( 0 );
|
||||
DISPLAY->SetLighting( false );
|
||||
m_pDancePad->Draw();
|
||||
DISPLAY->ClearZBuffer(); // So character doesn't step "into" the dance pad.
|
||||
DISPLAY->SetLightOff( 0 );
|
||||
DISPLAY->SetLighting( false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Draw StepCircles
|
||||
for(int scd=0; scd<NUM_PLAYERS; scd++)
|
||||
for(int scde=0; scde<4; scde++)
|
||||
m_sStepCircle[scd][scde].Draw();
|
||||
|
||||
|
||||
// Draw Dancers
|
||||
if( DrawCelShaded )
|
||||
{
|
||||
FOREACH_PlayerNumber( pn ) // Draw each dancer
|
||||
FOREACH_PlayerNumber( pn )
|
||||
if( GAMESTATE->IsHumanPlayer(pn) )
|
||||
m_pDancer[pn]->DrawCelShaded();
|
||||
}
|
||||
@@ -265,7 +276,7 @@ void BeginnerHelper::DrawPrimitives()
|
||||
RageColor(0,0,0,1),
|
||||
RageVector3(0, 0, 1) );
|
||||
|
||||
FOREACH_PlayerNumber( pn ) // Draw each dancer
|
||||
FOREACH_PlayerNumber( pn )
|
||||
if( GAMESTATE->IsHumanPlayer(pn) )
|
||||
m_pDancer[pn]->Draw();
|
||||
|
||||
@@ -314,7 +325,7 @@ void BeginnerHelper::Step( PlayerNumber pn, int CSTEP )
|
||||
m_pDancer[pn]->SetRotationY( 0 );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
m_sFlash.StopEffect();
|
||||
m_sFlash.StopTweening();
|
||||
m_sFlash.Sleep( GAMESTATE->m_fCurBPS/16 );
|
||||
@@ -337,22 +348,22 @@ void BeginnerHelper::Update( float fDeltaTime )
|
||||
// Check if there are any notes at all on this row.. If not, save scanning.
|
||||
if( !m_NoteData[pn].IsThereATapAtRow(iRow) )
|
||||
continue;
|
||||
|
||||
|
||||
// Find all steps on this row, in order to show the correct animations
|
||||
int iStep = 0;
|
||||
const int iNumTracks = m_NoteData[pn].GetNumTracks();
|
||||
for( int t=0; t<iNumTracks; t++ )
|
||||
if( m_NoteData[pn].GetTapNote(t,iRow).type == TapNote::tap )
|
||||
iStep |= 1 << t;
|
||||
|
||||
|
||||
// Assign new data
|
||||
this->Step( pn, iStep );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Make sure we don't accidentally scan a row 2x
|
||||
m_iLastRowChecked = iCurRow;
|
||||
|
||||
|
||||
// Update animations
|
||||
ActorFrame::Update( fDeltaTime );
|
||||
m_pDancePad->Update( fDeltaTime );
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
#include "ActorFrame.h"
|
||||
#include "Character.h"
|
||||
#include "Sprite.h"
|
||||
#include "AutoActor.h"
|
||||
#include "PlayerNumber.h"
|
||||
#include "NoteData.h"
|
||||
#include "ThemeMetric.h"
|
||||
class Model;
|
||||
/** @brief A dancing character that follows the steps of the Song. */
|
||||
class BeginnerHelper : public ActorFrame
|
||||
@@ -14,7 +16,7 @@ public:
|
||||
BeginnerHelper();
|
||||
~BeginnerHelper();
|
||||
|
||||
bool Initialize( int iDancePadType );
|
||||
bool Init( int iDancePadType );
|
||||
bool IsInitialized() { return m_bInitialized; }
|
||||
static bool CanUse();
|
||||
void AddPlayer( PlayerNumber pn, const NoteData &nd );
|
||||
@@ -32,12 +34,14 @@ protected:
|
||||
Model *m_pDancer[NUM_PLAYERS];
|
||||
Model *m_pDancePad;
|
||||
Sprite m_sFlash;
|
||||
Sprite m_sBackground;
|
||||
AutoActor m_sBackground;
|
||||
Sprite m_sStepCircle[NUM_PLAYERS][4]; // More memory, but much easier to manage
|
||||
|
||||
int m_iLastRowChecked;
|
||||
int m_iLastRowFlashed;
|
||||
bool m_bInitialized;
|
||||
|
||||
ThemeMetric<bool> SHOW_DANCE_PAD;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ public:
|
||||
|
||||
struct Attribute
|
||||
{
|
||||
Attribute() : length(-1) { }
|
||||
Attribute() : length(-1), glow() { }
|
||||
int length;
|
||||
RageColor diffuse[4];
|
||||
RageColor glow;
|
||||
|
||||
@@ -16,10 +16,13 @@ public:
|
||||
struct Arg
|
||||
{
|
||||
RString s;
|
||||
Arg(): s("") {}
|
||||
};
|
||||
Arg GetArg( unsigned index ) const;
|
||||
|
||||
vector<RString> m_vsArgs;
|
||||
|
||||
Command(): m_vsArgs() {}
|
||||
};
|
||||
|
||||
class Commands
|
||||
|
||||
+3
-3
@@ -11,7 +11,7 @@
|
||||
class ThemeMetricDifficultiesToShow : public ThemeMetric<RString>
|
||||
{
|
||||
public:
|
||||
ThemeMetricDifficultiesToShow() { }
|
||||
ThemeMetricDifficultiesToShow(): m_v() { }
|
||||
ThemeMetricDifficultiesToShow( const RString& sGroup, const RString& sName );
|
||||
void Read();
|
||||
const vector<Difficulty> &GetValue() const;
|
||||
@@ -21,7 +21,7 @@ private:
|
||||
class ThemeMetricCourseDifficultiesToShow : public ThemeMetric<RString>
|
||||
{
|
||||
public:
|
||||
ThemeMetricCourseDifficultiesToShow() { }
|
||||
ThemeMetricCourseDifficultiesToShow(): m_v() { }
|
||||
ThemeMetricCourseDifficultiesToShow( const RString& sGroup, const RString& sName );
|
||||
void Read();
|
||||
const vector<CourseDifficulty> &GetValue() const;
|
||||
@@ -31,7 +31,7 @@ private:
|
||||
class ThemeMetricStepsTypesToShow : public ThemeMetric<RString>
|
||||
{
|
||||
public:
|
||||
ThemeMetricStepsTypesToShow() { }
|
||||
ThemeMetricStepsTypesToShow(): m_v() { }
|
||||
ThemeMetricStepsTypesToShow( const RString& sGroup, const RString& sName );
|
||||
void Read();
|
||||
const vector<StepsType> &GetValue() const;
|
||||
|
||||
+25
-10
@@ -88,9 +88,18 @@ int CourseEntry::GetNumModChanges() const
|
||||
|
||||
|
||||
|
||||
Course::Course()
|
||||
Course::Course(): m_bIsAutogen(false), m_sPath(""), m_sMainTitle(""),
|
||||
m_sMainTitleTranslit(""), m_sSubTitle(""), m_sSubTitleTranslit(""),
|
||||
m_sBannerPath(""), m_sBackgroundPath(""), m_sCDTitlePath(""),
|
||||
m_sGroupName(""), m_sScripter(""), m_bRepeat(false), m_fGoalSeconds(0),
|
||||
m_bShuffle(false), m_iLives(-1), m_bSortByMeter(false),
|
||||
m_bIncomplete(false), m_vEntries(), m_SortOrder_TotalDifficulty(0),
|
||||
m_SortOrder_Ranking(0), m_LoadedFromProfile(ProfileSlot_Invalid),
|
||||
m_TrailCache(), m_iTrailCacheSeed(0), m_RadarCache(),
|
||||
m_setStyles(), m_CachedObject()
|
||||
{
|
||||
Init();
|
||||
FOREACH_ENUM( Difficulty,dc)
|
||||
m_iCustomMeter[dc] = -1;
|
||||
}
|
||||
|
||||
CourseType Course::GetCourseType() const
|
||||
@@ -166,6 +175,7 @@ void Course::Init()
|
||||
m_sMainTitleTranslit = "";
|
||||
m_sSubTitle = "";
|
||||
m_sSubTitleTranslit = "";
|
||||
m_sScripter = "";
|
||||
|
||||
m_sBannerPath = "";
|
||||
m_sBackgroundPath = "";
|
||||
@@ -239,6 +249,9 @@ struct SortTrailEntry
|
||||
{
|
||||
TrailEntry entry;
|
||||
int SortMeter;
|
||||
|
||||
SortTrailEntry(): entry(), SortMeter(0) {}
|
||||
|
||||
bool operator< ( const SortTrailEntry &rhs ) const { return SortMeter < rhs.SortMeter; }
|
||||
};
|
||||
|
||||
@@ -1079,6 +1092,7 @@ public:
|
||||
static int GetGroupName( T* p, lua_State *L ) { lua_pushstring(L, p->m_sGroupName ); return 1; }
|
||||
static int IsAutogen( T* p, lua_State *L ) { lua_pushboolean(L, p->m_bIsAutogen ); return 1; }
|
||||
static int GetEstimatedNumStages( T* p, lua_State *L ) { lua_pushnumber(L, p->GetEstimatedNumStages() ); return 1; }
|
||||
static int GetScripter( T* p, lua_State *L ) { lua_pushstring(L, p->m_sScripter ); return 1; }
|
||||
static int GetTotalSeconds( T* p, lua_State *L )
|
||||
{
|
||||
StepsType st = Enum::Check<StepsType>(L, 1);
|
||||
@@ -1099,28 +1113,29 @@ public:
|
||||
|
||||
LunaCourse()
|
||||
{
|
||||
ADD_METHOD( GetPlayMode ); // [sm-ssc] returns PlayMode enum now
|
||||
ADD_METHOD( GetPlayMode );
|
||||
ADD_METHOD( GetDisplayFullTitle );
|
||||
ADD_METHOD( GetTranslitFullTitle );
|
||||
ADD_METHOD( HasMods );
|
||||
ADD_METHOD( HasTimedMods );
|
||||
ADD_METHOD( GetCourseType ); // [sm-ssc] returns CourseType enum now
|
||||
ADD_METHOD( GetCourseType );
|
||||
ADD_METHOD( GetCourseEntry );
|
||||
ADD_METHOD( GetCourseEntries );
|
||||
ADD_METHOD( GetAllTrails );
|
||||
ADD_METHOD( GetBannerPath );
|
||||
ADD_METHOD( GetBackgroundPath ); // sm-ssc addition
|
||||
ADD_METHOD( GetCourseDir ); // sm-ssc addition
|
||||
ADD_METHOD( GetBackgroundPath );
|
||||
ADD_METHOD( GetCourseDir );
|
||||
ADD_METHOD( GetGroupName );
|
||||
ADD_METHOD( IsAutogen );
|
||||
ADD_METHOD( GetEstimatedNumStages );
|
||||
ADD_METHOD( GetScripter );
|
||||
ADD_METHOD( GetTotalSeconds );
|
||||
ADD_METHOD( IsEndless );
|
||||
ADD_METHOD( IsNonstop ); // sm-ssc addition
|
||||
ADD_METHOD( IsOni ); // sm-ssc addition
|
||||
ADD_METHOD( IsNonstop );
|
||||
ADD_METHOD( IsOni );
|
||||
ADD_METHOD( GetGoalSeconds );
|
||||
ADD_METHOD( HasBanner ); // sm-ssc addition
|
||||
ADD_METHOD( HasBackground ); // sm-ssc addition
|
||||
ADD_METHOD( HasBanner );
|
||||
ADD_METHOD( HasBackground );
|
||||
ADD_METHOD( IsAnEdit );
|
||||
}
|
||||
};
|
||||
|
||||
+8
-3
@@ -55,9 +55,11 @@ public:
|
||||
float fGainSeconds; // time gained back at the beginning of the song. LifeMeterTime only.
|
||||
int iGainLives; // lives gained back at the beginning of the next song
|
||||
|
||||
CourseEntry(): bSecret(false), bNoDifficult(false),
|
||||
CourseEntry(): bSecret(false), songID(), songCriteria(),
|
||||
stepsCriteria(), bNoDifficult(false),
|
||||
songSort(SongSort_Randomize), iChooseIndex(0),
|
||||
sModifiers(RString("")), fGainSeconds(0), iGainLives(-1) {}
|
||||
sModifiers(RString("")), attacks(), fGainSeconds(0),
|
||||
iGainLives(-1) {}
|
||||
|
||||
bool IsFixedSong() const { return songID.IsValid(); }
|
||||
|
||||
@@ -159,9 +161,10 @@ public:
|
||||
|
||||
RString m_sMainTitle, m_sMainTitleTranslit;
|
||||
RString m_sSubTitle, m_sSubTitleTranslit;
|
||||
RString m_sScripter;
|
||||
|
||||
RString m_sBannerPath;
|
||||
RString m_sBackgroundPath; // after 9 years yes finally -aj
|
||||
RString m_sBackgroundPath;
|
||||
RString m_sCDTitlePath;
|
||||
RString m_sGroupName;
|
||||
|
||||
@@ -187,6 +190,8 @@ public:
|
||||
{
|
||||
Trail trail;
|
||||
bool null;
|
||||
|
||||
CacheData(): trail(), null(false) {}
|
||||
};
|
||||
typedef map<CacheEntry, CacheData> TrailCache_t;
|
||||
mutable TrailCache_t m_TrailCache;
|
||||
|
||||
@@ -78,7 +78,9 @@ void CourseContentsList::SetItemFromGameState( Actor *pActor, int iCourseEntryIn
|
||||
FOREACH_HumanPlayer(pn)
|
||||
{
|
||||
const Trail *pTrail = GAMESTATE->m_pCurTrail[pn];
|
||||
if( pTrail == NULL || iCourseEntryIndex >= (int) pTrail->m_vEntries.size() )
|
||||
if( pTrail == NULL
|
||||
|| iCourseEntryIndex >= (int) pTrail->m_vEntries.size()
|
||||
|| iCourseEntryIndex >= (int) pCourse->m_vEntries.size() )
|
||||
continue;
|
||||
|
||||
const TrailEntry *te = &pTrail->m_vEntries[iCourseEntryIndex];
|
||||
|
||||
@@ -65,6 +65,8 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou
|
||||
out.m_sMainTitle = sParams[1];
|
||||
else if( 0 == stricmp(sValueName, "COURSETRANSLIT") )
|
||||
out.m_sMainTitleTranslit = sParams[1];
|
||||
else if( 0 == stricmp(sValueName, "SCRIPTER") )
|
||||
out.m_sScripter = sParams[1];
|
||||
else if( 0 == stricmp(sValueName, "REPEAT") )
|
||||
{
|
||||
RString str = sParams[1];
|
||||
@@ -161,6 +163,7 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou
|
||||
// infer entry::Type from the first param
|
||||
// todo: make sure these aren't generating bogus entries due
|
||||
// to a lack of songs. -aj
|
||||
LOG->Trace("[CourseLoaderCRS] sParams[1] = %s",sParams[1].c_str());
|
||||
// most played
|
||||
if( sParams[1].Left(strlen("BEST")) == "BEST" )
|
||||
{
|
||||
@@ -176,7 +179,7 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou
|
||||
new_entry.songSort = SongSort_FewestPlays;
|
||||
}
|
||||
// best grades
|
||||
if( sParams[1].Left(strlen("GRADEBEST")) == "GRADEBEST" )
|
||||
else if( sParams[1].Left(strlen("GRADEBEST")) == "GRADEBEST" )
|
||||
{
|
||||
new_entry.iChooseIndex = atoi( sParams[1].Right(sParams[1].size()-strlen("GRADEBEST")) ) - 1;
|
||||
CLAMP( new_entry.iChooseIndex, 0, 500 );
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ namespace EditCourseUtil
|
||||
class CourseID
|
||||
{
|
||||
public:
|
||||
CourseID() { Unset(); }
|
||||
CourseID(): sPath(""), sFullTitle(""), m_Cache() { Unset(); }
|
||||
void Unset() { FromCourse(NULL); }
|
||||
void FromCourse( const Course *p );
|
||||
Course *ToCourse() const;
|
||||
|
||||
@@ -46,6 +46,8 @@ bool CourseWriterCRS::Write( const Course &course, RageFileBasic &f, bool bSavin
|
||||
f.PutLine( ssprintf("#COURSE:%s;", course.m_sMainTitle.c_str()) );
|
||||
if( course.m_sMainTitleTranslit != "" )
|
||||
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_bRepeat )
|
||||
f.PutLine( "#REPEAT:YES;" );
|
||||
if( course.m_iLives != -1 )
|
||||
|
||||
@@ -43,10 +43,11 @@ const float MODEL_X_ONE_PLAYER = 0;
|
||||
const float MODEL_X_TWO_PLAYERS[NUM_PLAYERS] = { +8, -8 };
|
||||
const float MODEL_ROTATIONY_TWO_PLAYERS[NUM_PLAYERS] = { -90, 90 };
|
||||
|
||||
DancingCharacters::DancingCharacters()
|
||||
DancingCharacters::DancingCharacters(): m_bDrawDangerLight(false),
|
||||
m_CameraDistance(0), m_CameraPanYStart(0), m_CameraPanYEnd(0),
|
||||
m_fLookAtHeight(0), m_fCameraHeightStart(0), m_fCameraHeightEnd(0),
|
||||
m_fThisCameraStartBeat(0), m_fThisCameraEndBeat(0)
|
||||
{
|
||||
m_bDrawDangerLight = false;
|
||||
|
||||
FOREACH_PlayerNumber( p )
|
||||
{
|
||||
m_pCharacter[p] = new Model;
|
||||
|
||||
@@ -226,12 +226,14 @@ void FadingBanner::LoadRoulette()
|
||||
{
|
||||
BeforeChange();
|
||||
m_Banner[m_iIndexLatest].LoadRoulette();
|
||||
m_Banner[m_iIndexLatest].PlayCommand( "Roulette" );
|
||||
}
|
||||
|
||||
void FadingBanner::LoadRandom()
|
||||
{
|
||||
BeforeChange();
|
||||
m_Banner[m_iIndexLatest].LoadRandom();
|
||||
m_Banner[m_iIndexLatest].PlayCommand( "Random" );
|
||||
}
|
||||
|
||||
void FadingBanner::LoadFromSortOrder( SortOrder so )
|
||||
@@ -252,6 +254,13 @@ void FadingBanner::LoadCourseFallback()
|
||||
m_Banner[m_iIndexLatest].LoadCourseFallback();
|
||||
}
|
||||
|
||||
void FadingBanner::LoadCustom( RString sBanner )
|
||||
{
|
||||
BeforeChange();
|
||||
m_Banner[m_iIndexLatest].Load( THEME->GetPathG( "Banner", sBanner ) );
|
||||
m_Banner[m_iIndexLatest].PlayCommand( sBanner );
|
||||
}
|
||||
|
||||
// lua start
|
||||
#include "LuaBinding.h"
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ public:
|
||||
void LoadFromSortOrder( SortOrder so );
|
||||
void LoadFallback();
|
||||
void LoadCourseFallback();
|
||||
void LoadCustom( RString sBanner );
|
||||
|
||||
bool LoadFromCachedBanner( const RString &path );
|
||||
bool LoadFromCachedBackground( const RString &path );
|
||||
|
||||
+9
-18
@@ -13,7 +13,8 @@
|
||||
|
||||
FontPage::FontPage(): m_iHeight(0), m_iLineSpacing(0), m_fVshift(0),
|
||||
m_iDrawExtraPixelsLeft(0), m_iDrawExtraPixelsRight(0),
|
||||
m_sTexturePath("") {}
|
||||
m_FontPageTextures(), m_sTexturePath(""), m_aGlyphs(),
|
||||
m_iCharToGlyphNo() {}
|
||||
|
||||
void FontPage::Load( const FontPageSettings &cfg )
|
||||
{
|
||||
@@ -156,11 +157,6 @@ void FontPage::SetTextureCoords( const vector<int> &widths, int iAdvanceExtraPix
|
||||
|
||||
void FontPage::SetExtraPixels( int iDrawExtraPixelsLeft, int iDrawExtraPixelsRight )
|
||||
{
|
||||
/* Hack: do one more than we were asked to; I think a lot of fonts are one
|
||||
* too low. - glenn */
|
||||
iDrawExtraPixelsRight++;
|
||||
iDrawExtraPixelsLeft++;
|
||||
|
||||
if( (iDrawExtraPixelsLeft % 2) == 1 )
|
||||
++iDrawExtraPixelsLeft;
|
||||
|
||||
@@ -220,15 +216,10 @@ int Font::GetLineHeightInSourcePixels( const wstring &szLine ) const
|
||||
}
|
||||
|
||||
|
||||
Font::Font()
|
||||
{
|
||||
m_iRefCount = 1;
|
||||
m_pDefault = NULL;
|
||||
m_bRightToLeft = false;
|
||||
// [sm-ssc] don't show strokes by default
|
||||
m_DefaultStrokeColor = RageColor(0,0,0,0);
|
||||
}
|
||||
|
||||
Font::Font(): m_iRefCount(1), path(""), m_apPages(), m_pDefault(NULL),
|
||||
m_iCharToGlyph(), m_bRightToLeft(false),
|
||||
// strokes aren't shown by default, hence the Color.
|
||||
m_DefaultStrokeColor(RageColor(0,0,0,0)), m_sChars("") {}
|
||||
Font::~Font()
|
||||
{
|
||||
Unload();
|
||||
@@ -717,8 +708,8 @@ void Font::Load( const RString &sIniPath, RString sChars )
|
||||
|
||||
for(unsigned i = 0; i < ImportList.size(); ++i)
|
||||
{
|
||||
RString fPath = THEME->GetPathF( "", ImportList[i], true );
|
||||
if( fPath == "" )
|
||||
RString sPath = THEME->GetPathF( "", ImportList[i], true );
|
||||
if( sPath == "" )
|
||||
{
|
||||
RString s = ssprintf( "Font \"%s\" imports a font \"%s\" that doesn't exist", sIniPath.c_str(), ImportList[i].c_str() );
|
||||
Dialog::OK( s );
|
||||
@@ -726,7 +717,7 @@ void Font::Load( const RString &sIniPath, RString sChars )
|
||||
}
|
||||
|
||||
Font subfont;
|
||||
subfont.Load(fPath,"");
|
||||
subfont.Load(sPath,"");
|
||||
MergeFont(subfont);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-7
@@ -23,11 +23,7 @@ struct FontPageTextures
|
||||
RageTexture *m_pTextureStroke;
|
||||
|
||||
/** @brief Set up the initial textures. */
|
||||
FontPageTextures()
|
||||
{
|
||||
m_pTextureMain = NULL;
|
||||
m_pTextureStroke = NULL;
|
||||
}
|
||||
FontPageTextures(): m_pTextureMain(NULL), m_pTextureStroke(NULL) {}
|
||||
};
|
||||
|
||||
/** @brief The components of a glyph (not technically a character). */
|
||||
@@ -52,6 +48,10 @@ struct glyph
|
||||
|
||||
/** @brief Texture coordinate rect. */
|
||||
RectF m_TexRect;
|
||||
|
||||
/** @brief Set up the glyph with default values. */
|
||||
glyph() : m_pPage(NULL), m_FontPageTextures(), m_iHadvance(0),
|
||||
m_fWidth(0), m_fHeight(0), m_fHshift(0), m_TexRect() {}
|
||||
};
|
||||
|
||||
/** @brief The settings used for the FontPage. */
|
||||
@@ -75,7 +75,7 @@ struct FontPageSettings
|
||||
map<int,int> m_mapGlyphWidths;
|
||||
|
||||
/** @brief The initial settings for the FontPage. */
|
||||
FontPageSettings():
|
||||
FontPageSettings(): m_sTexturePath(""),
|
||||
m_iDrawExtraPixelsLeft(0), m_iDrawExtraPixelsRight(0),
|
||||
m_iAddToAllWidths(0),
|
||||
m_iLineSpacing(-1),
|
||||
@@ -84,7 +84,9 @@ struct FontPageSettings
|
||||
m_iDefaultWidth(-1),
|
||||
m_iAdvanceExtraPixels(1),
|
||||
m_fScaleAllWidthsBy(1),
|
||||
m_sTextureHints("default")
|
||||
m_sTextureHints("default"),
|
||||
CharToGlyphNo(),
|
||||
m_mapGlyphWidths()
|
||||
{ }
|
||||
|
||||
/**
|
||||
|
||||
+21
-1
@@ -22,7 +22,27 @@ struct lua_State;
|
||||
class GameCommand
|
||||
{
|
||||
public:
|
||||
GameCommand() { Init(); }
|
||||
GameCommand(): m_Commands(), m_sName(""), m_sText(""),
|
||||
m_bInvalid(true), m_sInvalidReason(""),
|
||||
m_iIndex(-1), m_MultiPlayer(MultiPlayer_Invalid),
|
||||
m_pStyle(NULL), m_pm(PlayMode_Invalid),
|
||||
m_dc(Difficulty_Invalid),
|
||||
m_CourseDifficulty(Difficulty_Invalid),
|
||||
m_sAnnouncer(""), m_sPreferredModifiers(""),
|
||||
m_sStageModifiers(""), m_sScreen(""), m_LuaFunction(),
|
||||
m_pSong(NULL), m_pSteps(NULL), m_pCourse(NULL),
|
||||
m_pTrail(NULL), m_pCharacter(NULL), m_SetEnv(),
|
||||
m_sSongGroup(""), m_SortOrder(SortOrder_Invalid),
|
||||
m_sSoundPath(""), m_vsScreensToPrepare(), m_iWeightPounds(-1),
|
||||
m_iGoalCalories(-1), m_GoalType(GoalType_Invalid),
|
||||
m_sProfileID(""), m_sUrl(""), m_bUrlExits(true),
|
||||
m_bInsertCredit(false), m_bClearCredits(false),
|
||||
m_bStopMusic(false), m_bApplyDefaultOptions(false),
|
||||
m_bFadeMusic(false), m_fMusicFadeOutVolume(-1),
|
||||
m_fMusicFadeOutSeconds(-1), m_bApplyCommitsScreens(true)
|
||||
{
|
||||
m_LuaFunction.Unset();
|
||||
}
|
||||
void Init();
|
||||
|
||||
void Load( int iIndex, const Commands& cmds );
|
||||
|
||||
@@ -142,7 +142,8 @@ static void StartMusic( MusicToPlay &ToPlay )
|
||||
{
|
||||
LOG->Trace( "Found '%s'", ToPlay.m_sTimingFile.c_str() );
|
||||
Song song;
|
||||
if( SSCLoader::LoadFromSSCFile(ToPlay.m_sTimingFile, song) )
|
||||
if( GetExtension(ToPlay.m_sTimingFile) == ".ssc" &&
|
||||
SSCLoader::LoadFromSSCFile(ToPlay.m_sTimingFile, song) )
|
||||
{
|
||||
ToPlay.HasTiming = true;
|
||||
ToPlay.m_TimingData = song.m_Timing;
|
||||
@@ -151,7 +152,8 @@ static void StartMusic( MusicToPlay &ToPlay )
|
||||
if( pStepsCabinetLights )
|
||||
pStepsCabinetLights->GetNoteData( ToPlay.m_LightsData );
|
||||
}
|
||||
else if( SMLoader::LoadFromSMFile(ToPlay.m_sTimingFile, song) )
|
||||
else if( GetExtension(ToPlay.m_sTimingFile) == ".sm" &&
|
||||
SMLoader::LoadFromSMFile(ToPlay.m_sTimingFile, song) )
|
||||
{
|
||||
ToPlay.HasTiming = true;
|
||||
ToPlay.m_TimingData = song.m_Timing;
|
||||
|
||||
+10
-13
@@ -355,9 +355,14 @@ void GameState::JoinPlayer( PlayerNumber pn )
|
||||
if( ALLOW_LATE_JOIN && m_pCurStyle != NULL )
|
||||
{
|
||||
const Style *pStyle;
|
||||
// only use one player for StyleType_OnePlayerTwoSides.
|
||||
// Only use one player for StyleType_OnePlayerTwoSides and StepsTypes
|
||||
// that can only be played by one player (e.g. dance-solo,
|
||||
// dance-threepanel, popn-nine). -aj
|
||||
// XXX?: still shows joined player as "Insert Card". May not be an issue? -aj
|
||||
if( m_pCurStyle->m_StyleType == StyleType_OnePlayerTwoSides )
|
||||
if( m_pCurStyle->m_StyleType == StyleType_OnePlayerTwoSides ||
|
||||
m_pCurStyle->m_StepsType == StepsType_dance_solo ||
|
||||
m_pCurStyle->m_StepsType == StepsType_dance_threepanel ||
|
||||
m_pCurStyle->m_StepsType == StepsType_popn_nine )
|
||||
pStyle = GAMEMAN->GetFirstCompatibleStyle( m_pCurGame, 1, m_pCurStyle->m_StepsType );
|
||||
else
|
||||
pStyle = GAMEMAN->GetFirstCompatibleStyle( m_pCurGame, GetNumSidesJoined(), m_pCurStyle->m_StepsType );
|
||||
@@ -897,7 +902,7 @@ void GameState::ResetMusicStatistics()
|
||||
m_bFreeze = false;
|
||||
m_bDelay = false;
|
||||
m_iWarpBeginRow = -1; // Set to -1 because some song may want to warp to row 0. -aj
|
||||
m_fWarpLength = -1; // Set when a warp is encountered. also see above. -aj
|
||||
m_fWarpDestination = -1; // Set when a warp is encountered. also see above. -aj
|
||||
m_fMusicSecondsVisible = 0;
|
||||
m_fSongBeatVisible = 0;
|
||||
Actor::SetBGMTime( 0, 0, 0, 0 );
|
||||
@@ -943,7 +948,7 @@ void GameState::ResetStageStatistics()
|
||||
}
|
||||
|
||||
static Preference<float> g_fVisualDelaySeconds( "VisualDelaySeconds", 0.0f );
|
||||
// todo: modify for warps -aj
|
||||
|
||||
void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp )
|
||||
{
|
||||
if( !timestamp.IsZero() )
|
||||
@@ -957,18 +962,10 @@ void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &ti
|
||||
LOG->Trace( ssprintf("[GameState::UpdateSongPosition] cur BPS = %f, fPositionSeconds = %f",m_fCurBPS,fPositionSeconds) );
|
||||
*/
|
||||
|
||||
timing.GetBeatAndBPSFromElapsedTime( fPositionSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze, m_bDelay, m_iWarpBeginRow, m_fWarpLength );
|
||||
timing.GetBeatAndBPSFromElapsedTime( fPositionSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze, m_bDelay, m_iWarpBeginRow, m_fWarpDestination );
|
||||
// "Crash reason : -243478.890625 -48695.773438"
|
||||
ASSERT_M( m_fSongBeat > -2000, ssprintf("Song beat %f at %f seconds", m_fSongBeat, fPositionSeconds) );
|
||||
|
||||
//if( m_iWarpBeginRow != -1 || m_iWarpEndRow == -1 )
|
||||
if( m_iWarpBeginRow != -1 && m_fWarpLength > 0.0f )
|
||||
{
|
||||
// There is a warp in this section.
|
||||
LOG->Trace("warp at %i lasts for %f, jumps to %i",m_iWarpBeginRow,m_fWarpLength,m_iWarpBeginRow+BeatToNoteRow(m_fWarpLength));
|
||||
//fPositionSeconds += (m_fWarpLength * m_fCurBPS);
|
||||
}
|
||||
|
||||
m_fMusicSeconds = fPositionSeconds;
|
||||
|
||||
m_fLightSongBeat = timing.GetBeatFromElapsedTime( fPositionSeconds + g_fLightsAheadSeconds );
|
||||
|
||||
+3
-2
@@ -208,9 +208,10 @@ public:
|
||||
bool m_bFreeze;
|
||||
/** @brief A flag to determine if we're in the middle of a delay (Pump style stop). */
|
||||
bool m_bDelay;
|
||||
// used for warping:
|
||||
/** @brief The row used to start a warp. */
|
||||
int m_iWarpBeginRow;
|
||||
float m_fWarpLength;
|
||||
/** @brief The beat to warp to afterwards. */
|
||||
float m_fWarpDestination;
|
||||
RageTimer m_LastBeatUpdate; // time of last m_fSongBeat, etc. update
|
||||
BroadcastOnChange<bool> m_bGameplayLeadIn;
|
||||
|
||||
|
||||
+7
-4
@@ -100,10 +100,13 @@ private:
|
||||
struct HighScoreList
|
||||
{
|
||||
public:
|
||||
HighScoreList()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
/**
|
||||
* @brief Set up the HighScore List with default values.
|
||||
*
|
||||
* This used to call Init(), but it's better to be explicit here. */
|
||||
HighScoreList(): vHighScores(), HighGrade(Grade_NoData),
|
||||
iNumTimesPlayed(0), dtLastPlayed() {}
|
||||
|
||||
void Init();
|
||||
|
||||
int GetNumTimesPlayed() const
|
||||
|
||||
@@ -9,10 +9,11 @@ class InputEventPlus
|
||||
{
|
||||
public:
|
||||
InputEventPlus():
|
||||
DeviceI(), GameI(),
|
||||
type(IET_FIRST_PRESS),
|
||||
MenuI(GameButton_Invalid),
|
||||
pn(PLAYER_INVALID),
|
||||
mp(MultiPlayer_Invalid) { }
|
||||
mp(MultiPlayer_Invalid), InputList() { }
|
||||
DeviceInput DeviceI;
|
||||
GameInput GameI;
|
||||
InputEventType type;
|
||||
|
||||
+1
-1
@@ -78,7 +78,7 @@ struct AutoMappings
|
||||
AutoMappingEntry im37 = AutoMappingEntry(),
|
||||
AutoMappingEntry im38 = AutoMappingEntry(),
|
||||
AutoMappingEntry im39 = AutoMappingEntry() )
|
||||
: m_sGame(s1), m_sDriverRegex(s2), m_sControllerName(s3)
|
||||
: m_sGame(s1), m_sDriverRegex(s2), m_sControllerName(s3), m_vMaps()
|
||||
{
|
||||
#define PUSH( im ) if(!im.IsEmpty()) m_vMaps.push_back(im);
|
||||
PUSH(im0);PUSH(im1);PUSH(im2);PUSH(im3);PUSH(im4);PUSH(im5);PUSH(im6);PUSH(im7);PUSH(im8);PUSH(im9);PUSH(im10);PUSH(im11);PUSH(im12);PUSH(im13);PUSH(im14);PUSH(im15);PUSH(im16);PUSH(im17);PUSH(im18);PUSH(im19);
|
||||
|
||||
+9
-1
@@ -27,11 +27,19 @@ struct InputQueueCode
|
||||
public:
|
||||
bool Load( RString sButtonsNames );
|
||||
bool EnteredCode( GameController controller ) const;
|
||||
|
||||
InputQueueCode(): m_aPresses() {}
|
||||
|
||||
private:
|
||||
struct ButtonPress
|
||||
{
|
||||
ButtonPress() { m_bAllowIntermediatePresses = false; memset( m_InputTypes, 0, sizeof(m_InputTypes) ); m_InputTypes[IET_FIRST_PRESS] = true; }
|
||||
ButtonPress(): m_aButtonsToHold(), m_aButtonsToNotHold(),
|
||||
m_aButtonsToPress(),
|
||||
m_bAllowIntermediatePresses(false)
|
||||
{
|
||||
memset( m_InputTypes, 0, sizeof(m_InputTypes) );
|
||||
m_InputTypes[IET_FIRST_PRESS] = true;
|
||||
}
|
||||
vector<GameButton> m_aButtonsToHold;
|
||||
vector<GameButton> m_aButtonsToNotHold;
|
||||
vector<GameButton> m_aButtonsToPress;
|
||||
|
||||
@@ -31,7 +31,7 @@ void LifeMeterBattery::Load( const PlayerState *pPlayerState, PlayerStageStats *
|
||||
bool bPlayerEnabled = GAMESTATE->IsPlayerEnabled( pPlayerState );
|
||||
|
||||
m_sprFrame.Load( THEME->GetPathG(sType,"frame") );
|
||||
this->AddChild( &m_sprFrame );
|
||||
this->AddChild( m_sprFrame );
|
||||
|
||||
m_sprBattery.Load( THEME->GetPathG(sType,"lives 1x4") );
|
||||
m_sprBattery.SetName( ssprintf("BatteryP%i",int(pn+1)) );
|
||||
@@ -87,7 +87,7 @@ void LifeMeterBattery::OnSongEnded()
|
||||
m_iTrailingLivesLeft = m_iLivesLeft;
|
||||
PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
|
||||
const Course *pCourse = GAMESTATE->m_pCurCourse;
|
||||
|
||||
|
||||
if( pCourse && pCourse->m_vEntries[GAMESTATE->GetCourseSongIndex()].iGainLives > -1 )
|
||||
m_iLivesLeft += pCourse->m_vEntries[GAMESTATE->GetCourseSongIndex()].iGainLives;
|
||||
else
|
||||
@@ -101,14 +101,12 @@ void LifeMeterBattery::OnSongEnded()
|
||||
Refresh();
|
||||
}
|
||||
|
||||
|
||||
void LifeMeterBattery::ChangeLife( TapNoteScore score )
|
||||
{
|
||||
if( m_iLivesLeft == 0 )
|
||||
return;
|
||||
|
||||
// xxx: this is hardcoded; we should use metrics for this. -aj
|
||||
// How to: have a TapNote reference similar to LifeMeterBattery
|
||||
// xxx: This is hardcoded; we should use metrics for this. -aj
|
||||
switch( score )
|
||||
{
|
||||
case TNS_W1:
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "RageSound.h"
|
||||
#include "PercentageDisplay.h"
|
||||
#include "ThemeMetric.h"
|
||||
#include "AutoActor.h"
|
||||
|
||||
/** @brief Battery life meter used in Oni mode. */
|
||||
class LifeMeterBattery : public LifeMeter
|
||||
@@ -45,7 +46,7 @@ private:
|
||||
//ThemeMetric<> METRIC_NAME;
|
||||
ThemeMetric<float> BATTERY_BLINK_TIME;
|
||||
|
||||
Sprite m_sprFrame;
|
||||
AutoActor m_sprFrame;
|
||||
Sprite m_sprBattery;
|
||||
BitmapText m_textNumLives;
|
||||
|
||||
|
||||
+8
-10
@@ -27,7 +27,7 @@ struct Impl
|
||||
};
|
||||
static Impl *pImpl = NULL;
|
||||
|
||||
#if defined(_MSC_VER) || defined (_XBOX)
|
||||
#if defined(_MSC_VER)
|
||||
/* "interaction between '_setjmp' and C++ object destruction is non-portable"
|
||||
* We don't care; we'll throw a fatal exception immediately anyway. */
|
||||
#pragma warning (disable : 4611)
|
||||
@@ -864,8 +864,8 @@ void LuaHelpers::ParseCommandList( Lua *L, const RString &sCommands, const RStri
|
||||
FOREACH_CONST( Command, cmds.v, c )
|
||||
{
|
||||
const Command& cmd = (*c);
|
||||
RString sName = cmd.GetName();
|
||||
s << "\tself:" << sName << "(";
|
||||
RString local_sName = cmd.GetName();
|
||||
s << "\tself:" << local_sName << "(";
|
||||
|
||||
for( unsigned i=1; i<cmd.m_vsArgs.size(); i++ )
|
||||
{
|
||||
@@ -877,10 +877,10 @@ void LuaHelpers::ParseCommandList( Lua *L, const RString &sCommands, const RStri
|
||||
|
||||
if( sArg[0] == '#' ) // HTML color
|
||||
{
|
||||
RageColor c; // in case FromString fails
|
||||
c.FromString( sArg );
|
||||
// c is still valid if FromString fails
|
||||
s << c.r << "," << c.g << "," << c.b << "," << c.a;
|
||||
RageColor col; // in case FromString fails
|
||||
col.FromString( sArg );
|
||||
// col is still valid if FromString fails
|
||||
s << col.r << "," << col.g << "," << col.b << "," << col.a;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -973,9 +973,7 @@ LuaFunction( VersionTime, (RString) version_time );
|
||||
static RString GetOSName()
|
||||
{
|
||||
RString system;
|
||||
#if defined(XBOX)
|
||||
system = "Xbox";
|
||||
#elif defined(WIN32) && !defined(XBOX)
|
||||
#if defined(WIN32)
|
||||
system = "Windows";
|
||||
#elif defined(LINUX)
|
||||
system = "Linux";
|
||||
|
||||
@@ -156,7 +156,7 @@ private:
|
||||
class MessageSubscriber : public IMessageSubscriber
|
||||
{
|
||||
public:
|
||||
MessageSubscriber() {}
|
||||
MessageSubscriber(): m_vsSubscribedTo() {}
|
||||
MessageSubscriber( const MessageSubscriber &cpy );
|
||||
MessageSubscriber &operator=(const MessageSubscriber &cpy);
|
||||
|
||||
|
||||
+5
-1
@@ -24,9 +24,13 @@ ModIcon::ModIcon( const ModIcon &cpy ):
|
||||
void ModIcon::Load( RString sMetricsGroup )
|
||||
{
|
||||
m_sprFilled.Load( THEME->GetPathG(sMetricsGroup,"Filled") );
|
||||
m_sprFilled->SetName("Filled");
|
||||
ActorUtil::LoadAllCommands( m_sprFilled, sMetricsGroup );
|
||||
this->AddChild( m_sprFilled );
|
||||
|
||||
m_sprEmpty.Load( THEME->GetPathG(sMetricsGroup,"Empty") );
|
||||
m_sprEmpty->SetName("Empty");
|
||||
ActorUtil::LoadAllCommands( m_sprEmpty, sMetricsGroup );
|
||||
this->AddChild( m_sprEmpty );
|
||||
|
||||
m_text.LoadFromFont( THEME->GetPathF(sMetricsGroup,"Text") );
|
||||
@@ -70,7 +74,7 @@ void ModIcon::Set( const RString &_sText )
|
||||
|
||||
m_text.SetText( sText );
|
||||
// This line makes Lua option rows crash: -aj
|
||||
m_text.CropToWidth( CROP_TEXT_TO_WIDTH );
|
||||
//m_text.CropToWidth( CROP_TEXT_TO_WIDTH );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -83,6 +83,8 @@ private:
|
||||
float m_fCurAnimationRate;
|
||||
bool m_bLoop;
|
||||
bool m_bDrawCelShaded; // for Lua models
|
||||
|
||||
Model& operator=(const Model& rhs);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,6 +13,9 @@ public:
|
||||
{
|
||||
/** @brief The list of parameters. */
|
||||
vector<RString> params;
|
||||
/** @brief Set up the parameters with default values. */
|
||||
value_t(): params() {}
|
||||
|
||||
/**
|
||||
* @brief Access the proper parameter.
|
||||
* @param i the index.
|
||||
@@ -20,6 +23,8 @@ public:
|
||||
*/
|
||||
RString operator[]( unsigned i ) const { if( i >= params.size() ) return RString(); return params[i]; }
|
||||
};
|
||||
|
||||
MsdFile(): values(), error("") {}
|
||||
|
||||
/** @brief Remove the MSDFile. */
|
||||
virtual ~MsdFile() { }
|
||||
|
||||
@@ -360,6 +360,8 @@ bool MusicWheel::SelectModeMenuItem()
|
||||
return true;
|
||||
}
|
||||
|
||||
// bool MusicWheel::SelectCustomItem()
|
||||
|
||||
void MusicWheel::GetSongList( vector<Song*> &arraySongs, SortOrder so )
|
||||
{
|
||||
vector<Song*> apAllSongs;
|
||||
@@ -659,6 +661,7 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
|
||||
|
||||
if( so != SORT_ROULETTE )
|
||||
{
|
||||
// todo: allow themers to change the order of the items. -aj
|
||||
if( SHOW_ROULETTE )
|
||||
arrayWheelItemDatas.push_back( new MusicWheelItemData(TYPE_ROULETTE, NULL, "", NULL, ROULETTE_COLOR, 0) );
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ protected:
|
||||
bool SelectSongOrCourse();
|
||||
bool SelectCourse( const Course *p );
|
||||
bool SelectModeMenuItem();
|
||||
//bool SelectCustomItem();
|
||||
|
||||
virtual void UpdateSwitch();
|
||||
|
||||
|
||||
@@ -33,14 +33,12 @@ static const char *MusicWheelItemTypeNames[] = {
|
||||
};
|
||||
XToString( MusicWheelItemType );
|
||||
|
||||
MusicWheelItemData::MusicWheelItemData( WheelItemDataType type, Song* pSong, RString sSectionName, Course* pCourse, RageColor color, int iSectionCount ):
|
||||
WheelItemBaseData(type, sSectionName, color)
|
||||
{
|
||||
m_pSong = pSong;
|
||||
m_pCourse = pCourse;
|
||||
m_Flags = WheelNotifyIcon::Flags();
|
||||
m_iSectionCount = iSectionCount;
|
||||
}
|
||||
MusicWheelItemData::MusicWheelItemData( WheelItemDataType type, Song* pSong,
|
||||
RString sSectionName, Course* pCourse,
|
||||
RageColor color, int iSectionCount ):
|
||||
WheelItemBaseData(type, sSectionName, color),
|
||||
m_pCourse(pCourse), m_pSong(pSong), m_Flags(WheelNotifyIcon::Flags()),
|
||||
m_iSectionCount(iSectionCount), m_sLabel(""), m_pAction() {}
|
||||
|
||||
MusicWheelItem::MusicWheelItem( RString sType ):
|
||||
WheelItemBase( sType )
|
||||
@@ -172,6 +170,7 @@ MusicWheelItem::MusicWheelItem( const MusicWheelItem &cpy ):
|
||||
|
||||
MusicWheelItem::~MusicWheelItem()
|
||||
{
|
||||
delete m_pTextSectionCount;
|
||||
}
|
||||
|
||||
void MusicWheelItem::LoadFromWheelItemData( const WheelItemBaseData *pData, int iIndex, bool bHasFocus, int iDrawIndex )
|
||||
|
||||
@@ -62,8 +62,11 @@ private:
|
||||
|
||||
struct MusicWheelItemData : public WheelItemBaseData
|
||||
{
|
||||
MusicWheelItemData() : m_iSectionCount(0) { }
|
||||
MusicWheelItemData( WheelItemDataType type, Song* pSong, RString sSectionName, Course* pCourse, RageColor color, int iSectionCount );
|
||||
MusicWheelItemData() : m_pCourse(NULL), m_pSong(NULL), m_Flags(),
|
||||
m_iSectionCount(0), m_sLabel(""), m_pAction() { }
|
||||
MusicWheelItemData( WheelItemDataType type, Song* pSong,
|
||||
RString sSectionName, Course* pCourse,
|
||||
RageColor color, int iSectionCount );
|
||||
|
||||
Course* m_pCourse;
|
||||
Song* m_pSong;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "NetworkSyncManager.h"
|
||||
#include "LuaManager.h"
|
||||
#include "LocalizedString.h"
|
||||
#include <errno.h>
|
||||
|
||||
NetworkSyncManager *NSMAN;
|
||||
|
||||
@@ -107,13 +108,21 @@ void NetworkSyncManager::CloseConnection()
|
||||
void NetworkSyncManager::PostStartUp( const RString& ServerIP )
|
||||
{
|
||||
RString sAddress;
|
||||
short iPort;
|
||||
unsigned short iPort;
|
||||
|
||||
size_t cLoc = ServerIP.find( ':' );
|
||||
if( ServerIP.find( ':' ) != RString::npos )
|
||||
{
|
||||
iPort = (short) atoi( ServerIP.substr( cLoc + 1 ).c_str() );
|
||||
sAddress = ServerIP.substr( 0, cLoc );
|
||||
char* cEnd;
|
||||
errno = 0;
|
||||
iPort = (unsigned short)strtol( ServerIP.substr( cLoc + 1 ).c_str(), &cEnd, 10 );
|
||||
if( *cEnd != 0 || errno != 0 )
|
||||
{
|
||||
m_startupStatus = 2;
|
||||
LOG->Warn( "Invalid port" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -121,7 +130,7 @@ void NetworkSyncManager::PostStartUp( const RString& ServerIP )
|
||||
sAddress = ServerIP;
|
||||
}
|
||||
|
||||
LOG->Info( "Attempting to connect to: %s, Port: %d", sAddress.c_str(), iPort );
|
||||
LOG->Info( "Attempting to connect to: %s, Port: %i", sAddress.c_str(), iPort );
|
||||
|
||||
CloseConnection();
|
||||
if( !Connect(sAddress.c_str(), iPort) )
|
||||
@@ -136,7 +145,7 @@ void NetworkSyncManager::PostStartUp( const RString& ServerIP )
|
||||
|
||||
useSMserver = true;
|
||||
|
||||
m_startupStatus = 1; //Connection attepmpt successful
|
||||
m_startupStatus = 1; // Connection attepmpt successful
|
||||
|
||||
// If network play is desired and the connection works,
|
||||
// halt until we know what server version we're dealing with
|
||||
|
||||
+71
-71
@@ -52,18 +52,18 @@ void NoteData::ClearRangeForTrack( int rowBegin, int rowEnd, int iTrack )
|
||||
if( rowBegin == rowEnd )
|
||||
return;
|
||||
|
||||
NoteData::TrackMap::iterator begin, end;
|
||||
GetTapNoteRangeInclusive( iTrack, rowBegin, rowEnd, begin, end );
|
||||
NoteData::TrackMap::iterator lBegin, lEnd;
|
||||
GetTapNoteRangeInclusive( iTrack, rowBegin, rowEnd, lBegin, lEnd );
|
||||
|
||||
if( begin != end && begin->first < rowBegin && begin->first + begin->second.iDuration > rowEnd )
|
||||
if( lBegin != lEnd && lBegin->first < rowBegin && lBegin->first + lBegin->second.iDuration > rowEnd )
|
||||
{
|
||||
/* A hold note overlaps the whole range. Truncate it, and add the
|
||||
* remainder to the end. */
|
||||
TapNote tn1 = begin->second;
|
||||
TapNote tn1 = lBegin->second;
|
||||
TapNote tn2 = tn1;
|
||||
|
||||
int iEndRow = begin->first + tn1.iDuration;
|
||||
int iRow = begin->first;
|
||||
int iEndRow = lBegin->first + tn1.iDuration;
|
||||
int iRow = lBegin->first;
|
||||
|
||||
tn1.iDuration = rowBegin - iRow;
|
||||
tn2.iDuration = iEndRow - rowEnd;
|
||||
@@ -72,23 +72,23 @@ void NoteData::ClearRangeForTrack( int rowBegin, int rowEnd, int iTrack )
|
||||
SetTapNote( iTrack, rowEnd, tn2 );
|
||||
|
||||
// We may have invalidated our iterators.
|
||||
GetTapNoteRangeInclusive( iTrack, rowBegin, rowEnd, begin, end );
|
||||
GetTapNoteRangeInclusive( iTrack, rowBegin, rowEnd, lBegin, lEnd );
|
||||
}
|
||||
else if( begin != end && begin->first < rowBegin )
|
||||
else if( lBegin != lEnd && lBegin->first < rowBegin )
|
||||
{
|
||||
// A hold note overlaps the beginning of the range. Truncate it.
|
||||
TapNote &tn1 = begin->second;
|
||||
int iRow = begin->first;
|
||||
TapNote &tn1 = lBegin->second;
|
||||
int iRow = lBegin->first;
|
||||
tn1.iDuration = rowBegin - iRow;
|
||||
|
||||
++begin;
|
||||
++lBegin;
|
||||
}
|
||||
|
||||
if( begin != end )
|
||||
if( lBegin != lEnd )
|
||||
{
|
||||
NoteData::TrackMap::iterator prev = end;
|
||||
NoteData::TrackMap::iterator prev = lEnd;
|
||||
--prev;
|
||||
TapNote tn = begin->second;
|
||||
TapNote tn = lBegin->second;
|
||||
int iRow = prev->first;
|
||||
if( tn.type == TapNote::hold_head && iRow + tn.iDuration > rowEnd )
|
||||
{
|
||||
@@ -99,14 +99,14 @@ void NoteData::ClearRangeForTrack( int rowBegin, int rowEnd, int iTrack )
|
||||
tn.iDuration -= iAdd;
|
||||
iRow += iAdd;
|
||||
SetTapNote( iTrack, iRow, tn );
|
||||
end = prev;
|
||||
lEnd = prev;
|
||||
}
|
||||
|
||||
// We may have invalidated our iterators.
|
||||
GetTapNoteRangeInclusive( iTrack, rowBegin, rowEnd, begin, end );
|
||||
GetTapNoteRangeInclusive( iTrack, rowBegin, rowEnd, lBegin, lEnd );
|
||||
}
|
||||
|
||||
m_TapNotes[iTrack].erase( begin, end );
|
||||
m_TapNotes[iTrack].erase( lBegin, lEnd );
|
||||
}
|
||||
|
||||
void NoteData::ClearRange( int rowBegin, int rowEnd )
|
||||
@@ -138,17 +138,17 @@ void NoteData::CopyRange( const NoteData& from, int rowFromBegin, int rowFromEnd
|
||||
|
||||
for( int t=0; t<GetNumTracks(); t++ )
|
||||
{
|
||||
NoteData::TrackMap::const_iterator begin, end;
|
||||
from.GetTapNoteRangeInclusive( t, rowFromBegin, rowFromEnd, begin, end );
|
||||
for( ; begin != end; ++begin )
|
||||
NoteData::TrackMap::const_iterator lBegin, lEnd;
|
||||
from.GetTapNoteRangeInclusive( t, rowFromBegin, rowFromEnd, lBegin, lEnd );
|
||||
for( ; lBegin != lEnd; ++lBegin )
|
||||
{
|
||||
TapNote head = begin->second;
|
||||
TapNote head = lBegin->second;
|
||||
if( head.type == TapNote::empty )
|
||||
continue;
|
||||
|
||||
if( head.type == TapNote::hold_head )
|
||||
{
|
||||
int iStartRow = begin->first + iMoveBy;
|
||||
int iStartRow = lBegin->first + iMoveBy;
|
||||
int iEndRow = iStartRow + head.iDuration;
|
||||
|
||||
iStartRow = clamp( iStartRow, rowToBegin, rowToEnd );
|
||||
@@ -158,7 +158,7 @@ void NoteData::CopyRange( const NoteData& from, int rowFromBegin, int rowFromEnd
|
||||
}
|
||||
else
|
||||
{
|
||||
int iTo = begin->first + iMoveBy;
|
||||
int iTo = lBegin->first + iMoveBy;
|
||||
if( iTo >= rowToBegin && iTo <= rowToEnd )
|
||||
this->SetTapNote( t, iTo, head );
|
||||
}
|
||||
@@ -307,11 +307,11 @@ void NoteData::AddHoldNote( int iTrack, int iStartRow, int iEndRow, TapNote tn )
|
||||
ASSERT_M( iEndRow >= iStartRow, ssprintf("EndRow %d < StartRow %d",iEndRow,iStartRow) );
|
||||
|
||||
/* Include adjacent (non-overlapping) hold notes, since we need to merge with them. */
|
||||
NoteData::TrackMap::iterator begin, end;
|
||||
GetTapNoteRangeInclusive( iTrack, iStartRow, iEndRow, begin, end, true );
|
||||
NoteData::TrackMap::iterator lBegin, lEnd;
|
||||
GetTapNoteRangeInclusive( iTrack, iStartRow, iEndRow, lBegin, lEnd, true );
|
||||
|
||||
// Look for other hold notes that overlap and merge them into add.
|
||||
for( iterator it = begin; it != end; ++it )
|
||||
for( iterator it = lBegin; it != lEnd; ++it )
|
||||
{
|
||||
int iOtherRow = it->first;
|
||||
const TapNote &tnOther = it->second;
|
||||
@@ -325,14 +325,14 @@ void NoteData::AddHoldNote( int iTrack, int iStartRow, int iEndRow, TapNote tn )
|
||||
tn.iDuration = iEndRow - iStartRow;
|
||||
|
||||
// Remove everything in the range.
|
||||
while( begin != end )
|
||||
while( lBegin != lEnd )
|
||||
{
|
||||
iterator next = begin;
|
||||
iterator next = lBegin;
|
||||
++next;
|
||||
|
||||
RemoveTapNote( iTrack, begin );
|
||||
RemoveTapNote( iTrack, lBegin );
|
||||
|
||||
begin = next;
|
||||
lBegin = next;
|
||||
}
|
||||
|
||||
/* Additionally, if there's a tap note lying at the end of our range,
|
||||
@@ -590,12 +590,12 @@ int NoteData::GetNumHoldNotes( int iStartIndex, int iEndIndex ) const
|
||||
int iNumHolds = 0;
|
||||
for( int t=0; t<GetNumTracks(); ++t )
|
||||
{
|
||||
NoteData::TrackMap::const_iterator begin, end;
|
||||
GetTapNoteRangeExclusive( t, iStartIndex, iEndIndex, begin, end );
|
||||
for( ; begin != end; ++begin )
|
||||
NoteData::TrackMap::const_iterator lBegin, lEnd;
|
||||
GetTapNoteRangeExclusive( t, iStartIndex, iEndIndex, lBegin, lEnd );
|
||||
for( ; lBegin != lEnd; ++lBegin )
|
||||
{
|
||||
if( begin->second.type != TapNote::hold_head ||
|
||||
begin->second.subType != TapNote::hold_head_hold )
|
||||
if( lBegin->second.type != TapNote::hold_head ||
|
||||
lBegin->second.subType != TapNote::hold_head_hold )
|
||||
continue;
|
||||
iNumHolds++;
|
||||
}
|
||||
@@ -608,12 +608,12 @@ int NoteData::GetNumRolls( int iStartIndex, int iEndIndex ) const
|
||||
int iNumRolls = 0;
|
||||
for( int t=0; t<GetNumTracks(); ++t )
|
||||
{
|
||||
NoteData::TrackMap::const_iterator begin, end;
|
||||
GetTapNoteRangeExclusive( t, iStartIndex, iEndIndex, begin, end );
|
||||
for( ; begin != end; ++begin )
|
||||
NoteData::TrackMap::const_iterator lBegin, lEnd;
|
||||
GetTapNoteRangeExclusive( t, iStartIndex, iEndIndex, lBegin, lEnd );
|
||||
for( ; lBegin != lEnd; ++lBegin )
|
||||
{
|
||||
if( begin->second.type != TapNote::hold_head ||
|
||||
begin->second.subType != TapNote::hold_head_roll )
|
||||
if( lBegin->second.type != TapNote::hold_head ||
|
||||
lBegin->second.subType != TapNote::hold_head_roll )
|
||||
continue;
|
||||
iNumRolls++;
|
||||
}
|
||||
@@ -773,43 +773,43 @@ bool NoteData::GetPrevTapNoteRowForTrack( int track, int &rowInOut ) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void NoteData::GetTapNoteRange( int iTrack, int iStartRow, int iEndRow, TrackMap::iterator &begin, TrackMap::iterator &end )
|
||||
void NoteData::GetTapNoteRange( int iTrack, int iStartRow, int iEndRow, TrackMap::iterator &lBegin, TrackMap::iterator &lEnd )
|
||||
{
|
||||
ASSERT_M( iTrack < GetNumTracks(), ssprintf("%i,%i", iTrack, GetNumTracks()) );
|
||||
TrackMap &mapTrack = m_TapNotes[iTrack];
|
||||
|
||||
if( iStartRow > iEndRow )
|
||||
{
|
||||
begin = end = mapTrack.end();
|
||||
lBegin = lEnd = mapTrack.end();
|
||||
return;
|
||||
}
|
||||
|
||||
if( iStartRow <= 0 )
|
||||
begin = mapTrack.begin(); // optimization
|
||||
lBegin = mapTrack.begin(); // optimization
|
||||
else if( iStartRow >= MAX_NOTE_ROW )
|
||||
begin = mapTrack.end(); // optimization
|
||||
lBegin = mapTrack.end(); // optimization
|
||||
else
|
||||
begin = mapTrack.lower_bound( iStartRow );
|
||||
lBegin = mapTrack.lower_bound( iStartRow );
|
||||
|
||||
if( iEndRow <= 0 )
|
||||
end = mapTrack.begin(); // optimization
|
||||
lEnd = mapTrack.begin(); // optimization
|
||||
else if( iEndRow >= MAX_NOTE_ROW )
|
||||
end = mapTrack.end(); // optimization
|
||||
lEnd = mapTrack.end(); // optimization
|
||||
else
|
||||
end = mapTrack.lower_bound( iEndRow );
|
||||
lEnd = mapTrack.lower_bound( iEndRow );
|
||||
}
|
||||
|
||||
|
||||
/* Include hold notes that overlap the edges. If a hold note completely surrounds the given
|
||||
* range, included it, too. If bIncludeAdjacent is true, also include hold notes adjacent to,
|
||||
* but not overlapping, the edge. */
|
||||
void NoteData::GetTapNoteRangeInclusive( int iTrack, int iStartRow, int iEndRow, TrackMap::iterator &begin, TrackMap::iterator &end, bool bIncludeAdjacent )
|
||||
void NoteData::GetTapNoteRangeInclusive( int iTrack, int iStartRow, int iEndRow, TrackMap::iterator &lBegin, TrackMap::iterator &lEnd, bool bIncludeAdjacent )
|
||||
{
|
||||
GetTapNoteRange( iTrack, iStartRow, iEndRow, begin, end );
|
||||
GetTapNoteRange( iTrack, iStartRow, iEndRow, lBegin, lEnd );
|
||||
|
||||
if( begin != this->begin(iTrack) )
|
||||
if( lBegin != this->begin(iTrack) )
|
||||
{
|
||||
iterator prev = Decrement(begin);
|
||||
iterator prev = Decrement(lBegin);
|
||||
|
||||
const TapNote &tn = prev->second;
|
||||
if( tn.type == TapNote::hold_head )
|
||||
@@ -821,62 +821,62 @@ void NoteData::GetTapNoteRangeInclusive( int iTrack, int iStartRow, int iEndRow,
|
||||
if( iHoldEndRow > iStartRow )
|
||||
{
|
||||
// The previous note is a hold.
|
||||
begin = prev;
|
||||
lBegin = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( bIncludeAdjacent && end != this->end(iTrack) )
|
||||
if( bIncludeAdjacent && lEnd != this->end(iTrack) )
|
||||
{
|
||||
// Include the next note if it's a hold and starts on iEndRow.
|
||||
const TapNote &tn = end->second;
|
||||
int iHoldStartRow = end->first;
|
||||
const TapNote &tn = lEnd->second;
|
||||
int iHoldStartRow = lEnd->first;
|
||||
if( tn.type == TapNote::hold_head && iHoldStartRow == iEndRow )
|
||||
++end;
|
||||
++lEnd;
|
||||
}
|
||||
}
|
||||
|
||||
void NoteData::GetTapNoteRangeExclusive( int iTrack, int iStartRow, int iEndRow, TrackMap::iterator &begin, TrackMap::iterator &end )
|
||||
void NoteData::GetTapNoteRangeExclusive( int iTrack, int iStartRow, int iEndRow, TrackMap::iterator &lBegin, TrackMap::iterator &lEnd )
|
||||
{
|
||||
GetTapNoteRange( iTrack, iStartRow, iEndRow, begin, end );
|
||||
GetTapNoteRange( iTrack, iStartRow, iEndRow, lBegin, lEnd );
|
||||
|
||||
// If end-1 is a hold_head, and extends beyond iEndRow, exclude it.
|
||||
if( begin != end && end != this->begin(iTrack) )
|
||||
if( lBegin != lEnd && lEnd != this->begin(iTrack) )
|
||||
{
|
||||
iterator prev = end;
|
||||
iterator prev = lEnd;
|
||||
--prev;
|
||||
if( prev->second.type == TapNote::hold_head )
|
||||
{
|
||||
int localStartRow = prev->first;
|
||||
const TapNote &tn = prev->second;
|
||||
if( localStartRow + tn.iDuration >= iEndRow )
|
||||
end = prev;
|
||||
lEnd = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NoteData::GetTapNoteRange( int iTrack, int iStartRow, int iEndRow, TrackMap::const_iterator &begin, TrackMap::const_iterator &end ) const
|
||||
void NoteData::GetTapNoteRange( int iTrack, int iStartRow, int iEndRow, TrackMap::const_iterator &lBegin, TrackMap::const_iterator &lEnd ) const
|
||||
{
|
||||
TrackMap::iterator const_begin, const_end;
|
||||
const_cast<NoteData *>(this)->GetTapNoteRange( iTrack, iStartRow, iEndRow, const_begin, const_end );
|
||||
begin = const_begin;
|
||||
end = const_end;
|
||||
lBegin = const_begin;
|
||||
lEnd = const_end;
|
||||
}
|
||||
|
||||
void NoteData::GetTapNoteRangeInclusive( int iTrack, int iStartRow, int iEndRow, TrackMap::const_iterator &begin, TrackMap::const_iterator &end, bool bIncludeAdjacent ) const
|
||||
void NoteData::GetTapNoteRangeInclusive( int iTrack, int iStartRow, int iEndRow, TrackMap::const_iterator &lBegin, TrackMap::const_iterator &lEnd, bool bIncludeAdjacent ) const
|
||||
{
|
||||
TrackMap::iterator const_begin, const_end;
|
||||
const_cast<NoteData *>(this)->GetTapNoteRangeInclusive( iTrack, iStartRow, iEndRow, const_begin, const_end, bIncludeAdjacent );
|
||||
begin = const_begin;
|
||||
end = const_end;
|
||||
lBegin = const_begin;
|
||||
lEnd = const_end;
|
||||
}
|
||||
|
||||
void NoteData::GetTapNoteRangeExclusive( int iTrack, int iStartRow, int iEndRow, TrackMap::const_iterator &begin, TrackMap::const_iterator &end ) const
|
||||
void NoteData::GetTapNoteRangeExclusive( int iTrack, int iStartRow, int iEndRow, TrackMap::const_iterator &lBegin, TrackMap::const_iterator &lEnd ) const
|
||||
{
|
||||
TrackMap::iterator const_begin, const_end;
|
||||
const_cast<NoteData *>(this)->GetTapNoteRange( iTrack, iStartRow, iEndRow, const_begin, const_end );
|
||||
begin = const_begin;
|
||||
end = const_end;
|
||||
lBegin = const_begin;
|
||||
lEnd = const_end;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ public:
|
||||
typedef map<int,TapNote>::const_iterator const_iterator;
|
||||
typedef map<int,TapNote>::reverse_iterator reverse_iterator;
|
||||
typedef map<int,TapNote>::const_reverse_iterator const_reverse_iterator;
|
||||
|
||||
NoteData(): m_TapNotes() {}
|
||||
|
||||
iterator begin( int iTrack ) { return m_TapNotes[iTrack].begin(); }
|
||||
const_iterator begin( int iTrack ) const { return m_TapNotes[iTrack].begin(); }
|
||||
|
||||
+36
-37
@@ -2229,62 +2229,61 @@ void NoteDataUtil::AddTapAttacks( NoteData &nd, Song* pSong )
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 // undo this if ScaleRegion breaks more things than it fixes
|
||||
void NoteDataUtil::Scale( NoteData &nd, float fScale )
|
||||
{
|
||||
ASSERT( fScale > 0 );
|
||||
|
||||
NoteData temp;
|
||||
temp.CopyAll( &nd );
|
||||
nd.ClearAll();
|
||||
|
||||
for( int r=0; r<=temp.GetLastRow(); r++ )
|
||||
|
||||
NoteData ndOut;
|
||||
ndOut.SetNumTracks( nd.GetNumTracks() );
|
||||
|
||||
for( int t=0; t<nd.GetNumTracks(); t++ )
|
||||
{
|
||||
for( int t=0; t<temp.GetNumTracks(); t++ )
|
||||
for( NoteData::const_iterator iter = nd.begin(t); iter != nd.end(t); ++iter )
|
||||
{
|
||||
TapNote tn = temp.GetTapNote( t, r );
|
||||
if( tn != TAP_EMPTY )
|
||||
{
|
||||
temp.SetTapNote( t, r, TAP_EMPTY );
|
||||
|
||||
int new_row = int(r*fScale);
|
||||
nd.SetTapNote( t, new_row, tn );
|
||||
}
|
||||
TapNote tn = iter->second;
|
||||
int iNewRow = lrintf( fScale * iter->first );
|
||||
int iNewDuration = lrintf( fScale * (iter->first + tn.iDuration) );
|
||||
tn.iDuration = iNewDuration;
|
||||
ndOut.SetTapNote( t, iNewRow, tn );
|
||||
}
|
||||
}
|
||||
|
||||
nd.swap( ndOut );
|
||||
}
|
||||
|
||||
/* XXX: move this to an appropriate place, same place as NoteRowToBeat perhaps? */
|
||||
static inline int GetScaledRow( float fScale, int iStartIndex, int iEndIndex, int iRow )
|
||||
{
|
||||
if( iRow < iStartIndex )
|
||||
return iRow;
|
||||
else if( iRow > iEndIndex )
|
||||
return iRow + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) );
|
||||
else
|
||||
return lrintf( (iRow - iStartIndex) * fScale ) + iStartIndex;
|
||||
}
|
||||
#endif
|
||||
|
||||
void NoteDataUtil::ScaleRegion( NoteData &nd, float fScale, int iStartIndex, int iEndIndex )
|
||||
{
|
||||
ASSERT( fScale > 0 );
|
||||
ASSERT( iStartIndex < iEndIndex );
|
||||
ASSERT( iStartIndex >= 0 );
|
||||
|
||||
NoteData temp1, temp2;
|
||||
temp1.SetNumTracks( nd.GetNumTracks() );
|
||||
temp2.SetNumTracks( nd.GetNumTracks() );
|
||||
|
||||
if( iStartIndex != 0 )
|
||||
temp1.CopyRange( nd, 0, iStartIndex );
|
||||
if( iEndIndex != MAX_NOTE_ROW )
|
||||
{
|
||||
const int iScaledFirstRowAfterRegion = int(iStartIndex + (iEndIndex - iStartIndex) * fScale);
|
||||
temp1.CopyRange( nd, iEndIndex, MAX_NOTE_ROW, iScaledFirstRowAfterRegion );
|
||||
}
|
||||
temp2.CopyRange( nd, iStartIndex, iEndIndex );
|
||||
nd.ClearAll();
|
||||
|
||||
for( int t=0; t<temp2.GetNumTracks(); t++ )
|
||||
|
||||
NoteData ndOut;
|
||||
ndOut.SetNumTracks( nd.GetNumTracks() );
|
||||
|
||||
for( int t=0; t<nd.GetNumTracks(); t++ )
|
||||
{
|
||||
for( NoteData::const_iterator iter = nd.begin(t); iter != nd.end(t); ++iter )
|
||||
{
|
||||
int new_row = int( iter->first*fScale + iStartIndex );
|
||||
temp1.SetTapNote( t, new_row, iter->second );
|
||||
TapNote tn = iter->second;
|
||||
int iNewRow = GetScaledRow( fScale, iStartIndex, iEndIndex, iter->first );
|
||||
int iNewDuration = GetScaledRow( fScale, iStartIndex, iEndIndex, iter->first + tn.iDuration ) - iNewRow;
|
||||
tn.iDuration = iNewDuration;
|
||||
ndOut.SetTapNote( t, iNewRow, tn );
|
||||
}
|
||||
}
|
||||
|
||||
nd.swap( temp1 );
|
||||
|
||||
nd.swap( ndOut );
|
||||
}
|
||||
|
||||
void NoteDataUtil::InsertRows( NoteData &nd, int iStartIndex, int iRowsToAdd )
|
||||
|
||||
+1
-2
@@ -149,9 +149,8 @@ namespace NoteDataUtil
|
||||
int iStartIndex = 0, int iEndIndex = MAX_NOTE_ROW );
|
||||
void AddTapAttacks( NoteData &nd, Song* pSong );
|
||||
|
||||
// void Scale( NoteData &nd, float fScale );
|
||||
void Scale( NoteData &nd, float fScale );
|
||||
void ScaleRegion( NoteData &nd, float fScale, int iStartIndex = 0, int iEndIndex = MAX_NOTE_ROW );
|
||||
inline void Scale( NoteData &nd, float fScale ) { NoteDataUtil::ScaleRegion(nd, fScale); }
|
||||
|
||||
void InsertRows( NoteData &nd, int iStartIndex, int iRowsToShift );
|
||||
void DeleteRows( NoteData &nd, int iStartIndex, int iRowsToShift );
|
||||
|
||||
+15
-13
@@ -418,7 +418,7 @@ void NoteDisplay::DrawHoldPart( vector<Sprite*> &vpSpr, int iCol, int fYStep, fl
|
||||
{
|
||||
/* For very large hold notes, shift the texture coordinates to be near 0, so we
|
||||
* don't send very large values to the renderer. */
|
||||
const float fDistFromTop = fYStartPos - fYTop;
|
||||
const float fDistFromTop = fYStartPos - fYTop;
|
||||
float fTexCoordTop = SCALE( fDistFromTop, 0, fFrameHeight, rect.top, rect.bottom );
|
||||
fTexCoordTop += fAddToTexCoord;
|
||||
fAddToTexCoord -= floorf( fTexCoordTop );
|
||||
@@ -542,8 +542,8 @@ void NoteDisplay::DrawHoldBody( const TapNote& tn, int iCol, float fBeat, bool b
|
||||
DISPLAY->SetZTestMode( bWavyPartsNeedZBuffer?ZTEST_WRITE_ON_PASS:ZTEST_OFF );
|
||||
DISPLAY->SetZWrite( bWavyPartsNeedZBuffer );
|
||||
|
||||
/* Hack: Z effects need a finer grain step. */
|
||||
const int fYStep = bWavyPartsNeedZBuffer? 4: 16; // use small steps only if wavy
|
||||
// Hack: Z effects need a finer grain step.
|
||||
const int fYStep = bWavyPartsNeedZBuffer? 4: 16; // use small steps only if wavy
|
||||
|
||||
if( bFlipHoldBody )
|
||||
{
|
||||
@@ -641,16 +641,18 @@ void NoteDisplay::DrawHold( const TapNote &tn, int iCol, int iRow, bool bIsBeing
|
||||
/* The body and caps should have no overlap, so their order doesn't matter.
|
||||
* Draw the head last, so it appears on top. */
|
||||
float fBeat = NoteRowToBeat(iRow);
|
||||
//if( !cache->m_bHoldHeadIsAboveWavyParts )
|
||||
//{
|
||||
// Actor *pActor = GetHoldActor( m_HoldHead, NotePart_HoldHead, NoteRowToBeat(iRow), tn.subType == TapNote::hold_head_roll, bIsBeingHeld );
|
||||
// DrawActor( tn, pActor, NotePart_HoldHead, iCol, bFlipHeadAndTail ? fEndYOffset : fStartYOffset, fBeat, bIsAddition, fPercentFadeToFail, fReverseOffsetPixels, fColorScale, fDrawDistanceAfterTargetsPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar );
|
||||
//}
|
||||
//if( !cache->m_bHoldTailIsAboveWavyParts )
|
||||
//{
|
||||
// Actor *pActor = GetHoldActor( m_HoldTail, NotePart_HoldTail, NoteRowToBeat(iRow), tn.subType == TapNote::hold_head_roll, bIsBeingHeld );
|
||||
// DrawActor( tn, pActor, NotePart_HoldTail, iCol, bFlipHeadAndTail ? fStartYOffset : fEndYOffset, fBeat, bIsAddition, fPercentFadeToFail, fReverseOffsetPixels, fColorScale, fDrawDistanceAfterTargetsPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar );
|
||||
//}
|
||||
/*
|
||||
if( !cache->m_bHoldHeadIsAboveWavyParts )
|
||||
{
|
||||
Actor *pActor = GetHoldActor( m_HoldHead, NotePart_HoldHead, NoteRowToBeat(iRow), tn.subType == TapNote::hold_head_roll, bIsBeingHeld );
|
||||
DrawActor( tn, pActor, NotePart_HoldHead, iCol, bFlipHeadAndTail ? fEndYOffset : fStartYOffset, fBeat, bIsAddition, fPercentFadeToFail, fReverseOffsetPixels, fColorScale, fDrawDistanceAfterTargetsPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar );
|
||||
}
|
||||
if( !cache->m_bHoldTailIsAboveWavyParts )
|
||||
{
|
||||
Actor *pActor = GetHoldActor( m_HoldTail, NotePart_HoldTail, NoteRowToBeat(iRow), tn.subType == TapNote::hold_head_roll, bIsBeingHeld );
|
||||
DrawActor( tn, pActor, NotePart_HoldTail, iCol, bFlipHeadAndTail ? fStartYOffset : fEndYOffset, fBeat, bIsAddition, fPercentFadeToFail, fReverseOffsetPixels, fColorScale, fDrawDistanceAfterTargetsPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar );
|
||||
}
|
||||
*/
|
||||
|
||||
DrawHoldBody( tn, iCol, fBeat, bIsBeingHeld, fYHead, fYTail, bIsAddition, fPercentFadeToFail, fColorScale, false, fDrawDistanceAfterTargetsPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar );
|
||||
DrawHoldBody( tn, iCol, fBeat, bIsBeingHeld, fYHead, fYTail, bIsAddition, fPercentFadeToFail, fColorScale, true, fDrawDistanceAfterTargetsPixels, fDrawDistanceBeforeTargetsPixels, fFadeInPercentOfDrawFar );
|
||||
|
||||
+52
-33
@@ -422,18 +422,21 @@ void NoteField::DrawAreaHighlight( int iStartBeat, int iEndBeat )
|
||||
static ThemeMetric<RageColor> BPM_COLOR ( "NoteField", "BPMColor" );
|
||||
static ThemeMetric<RageColor> STOP_COLOR ( "NoteField", "StopColor" );
|
||||
static ThemeMetric<RageColor> DELAY_COLOR ( "NoteField", "DelayColor" );
|
||||
static ThemeMetric<RageColor> WARP_COLOR ( "NoteField", "WarpColor" );
|
||||
static ThemeMetric<RageColor> TIME_SIGNATURE_COLOR ( "NoteField", "TimeSignatureColor" );
|
||||
static ThemeMetric<RageColor> TICKCOUNT_COLOR ( "NoteField", "TickcountColor" );
|
||||
static ThemeMetric<RageColor> COMBO_COLOR ( "NoteField", "ComboColor" );
|
||||
static ThemeMetric<bool> BPM_IS_LEFT_SIDE ( "NoteField", "BPMIsLeftSide" );
|
||||
static ThemeMetric<bool> STOP_IS_LEFT_SIDE ( "NoteField", "StopIsLeftSide" );
|
||||
static ThemeMetric<bool> DELAY_IS_LEFT_SIDE ( "NoteField", "DelayIsLeftSide" );
|
||||
static ThemeMetric<bool> WARP_IS_LEFT_SIDE ( "NoteField", "WarpIsLeftSide" );
|
||||
static ThemeMetric<bool> TIME_SIGNATURE_IS_LEFT_SIDE ( "NoteField", "TimeSignatureIsLeftSide" );
|
||||
static ThemeMetric<bool> TICKCOUNT_IS_LEFT_SIDE ( "NoteField", "TickcountIsLeftSide" );
|
||||
static ThemeMetric<bool> COMBO_IS_LEFT_SIDE ( "NoteField", "ComboIsLeftSide" );
|
||||
static ThemeMetric<float> BPM_OFFSETX ( "NoteField", "BPMOffsetX" );
|
||||
static ThemeMetric<float> STOP_OFFSETX ( "NoteField", "StopOffsetX" );
|
||||
static ThemeMetric<float> DELAY_OFFSETX ( "NoteField", "DelayOffsetX" );
|
||||
static ThemeMetric<float> WARP_OFFSETX ( "NoteField", "WarpOffsetX" );
|
||||
static ThemeMetric<float> TIME_SIGNATURE_OFFSETX ( "NoteField", "TimeSignatureOffsetX" );
|
||||
static ThemeMetric<float> TICKCOUNT_OFFSETX ( "NoteField", "TickcountOffsetX" );
|
||||
static ThemeMetric<float> COMBO_OFFSETX ( "NoteField", "ComboOffsetX" );
|
||||
@@ -481,6 +484,23 @@ void NoteField::DrawFreezeText( const float fBeat, const float fSecs, const floa
|
||||
m_textMeasureNumber.Draw();
|
||||
}
|
||||
|
||||
void NoteField::DrawWarpText( const float fBeat, const float fNewBeat )
|
||||
{
|
||||
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
|
||||
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
|
||||
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
|
||||
const float xBase = GetWidth()/2.f;
|
||||
const float xOffset = WARP_OFFSETX * fZoom;
|
||||
|
||||
m_textMeasureNumber.SetZoom( fZoom );
|
||||
m_textMeasureNumber.SetHorizAlign( WARP_IS_LEFT_SIDE ? align_right : align_left );
|
||||
m_textMeasureNumber.SetDiffuse( WARP_COLOR );
|
||||
m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) );
|
||||
m_textMeasureNumber.SetText( ssprintf("%.3f", fNewBeat) );
|
||||
m_textMeasureNumber.SetXY( (WARP_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos );
|
||||
m_textMeasureNumber.Draw();
|
||||
}
|
||||
|
||||
void NoteField::DrawTimeSignatureText( const float fBeat, int iNumerator, int iDenominator )
|
||||
{
|
||||
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
|
||||
@@ -746,72 +766,71 @@ void NoteField::DrawPrimitives()
|
||||
ASSERT(GAMESTATE->m_pCurSong);
|
||||
|
||||
// BPM text
|
||||
const vector<BPMSegment> &aBPMSegments = GAMESTATE->m_pCurSong->m_Timing.m_BPMSegments;
|
||||
for( unsigned i=0; i<aBPMSegments.size(); i++ )
|
||||
FOREACH_CONST( BPMSegment, GAMESTATE->m_pCurSong->m_Timing.m_BPMSegments, seg )
|
||||
{
|
||||
if( aBPMSegments[i].m_iStartRow >= iFirstRowToDraw &&
|
||||
aBPMSegments[i].m_iStartRow <= iLastRowToDraw)
|
||||
if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw )
|
||||
{
|
||||
float fBeat = NoteRowToBeat(aBPMSegments[i].m_iStartRow);
|
||||
float fBeat = NoteRowToBeat(seg->m_iStartRow);
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
DrawBPMText( fBeat, aBPMSegments[i].GetBPM() );
|
||||
DrawBPMText( fBeat, seg->GetBPM() );
|
||||
}
|
||||
}
|
||||
|
||||
// Freeze text
|
||||
const vector<StopSegment> &aStopSegments = GAMESTATE->m_pCurSong->m_Timing.m_StopSegments;
|
||||
for( unsigned i=0; i<aStopSegments.size(); i++ )
|
||||
FOREACH_CONST( StopSegment, GAMESTATE->m_pCurSong->m_Timing.m_StopSegments, seg )
|
||||
{
|
||||
if( aStopSegments[i].m_iStartRow >= iFirstRowToDraw &&
|
||||
aStopSegments[i].m_iStartRow <= iLastRowToDraw)
|
||||
if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw )
|
||||
{
|
||||
float fBeat = NoteRowToBeat(aStopSegments[i].m_iStartRow);
|
||||
float fBeat = NoteRowToBeat(seg->m_iStartRow);
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
DrawFreezeText( fBeat, aStopSegments[i].m_fStopSeconds, aStopSegments[i].m_bDelay );
|
||||
DrawFreezeText( fBeat, seg->m_fStopSeconds, seg->m_bDelay );
|
||||
}
|
||||
}
|
||||
|
||||
// Warp text
|
||||
FOREACH_CONST( WarpSegment, GAMESTATE->m_pCurSong->m_Timing.m_WarpSegments, seg )
|
||||
{
|
||||
if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw )
|
||||
{
|
||||
float fBeat = NoteRowToBeat(seg->m_iStartRow);
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
DrawWarpText( fBeat, seg->m_fEndBeat );
|
||||
}
|
||||
}
|
||||
|
||||
// Time Signature text
|
||||
const vector<TimeSignatureSegment> &vTimeSignatureSegments = GAMESTATE->m_pCurSong->m_Timing.m_vTimeSignatureSegments;
|
||||
for( unsigned i=0; i<vTimeSignatureSegments.size(); i++ )
|
||||
FOREACH_CONST( TimeSignatureSegment, GAMESTATE->m_pCurSong->m_Timing.m_vTimeSignatureSegments, seg )
|
||||
{
|
||||
if( vTimeSignatureSegments[i].m_iStartRow >= iFirstRowToDraw &&
|
||||
vTimeSignatureSegments[i].m_iStartRow <= iLastRowToDraw)
|
||||
if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw )
|
||||
{
|
||||
float fBeat = NoteRowToBeat(vTimeSignatureSegments[i].m_iStartRow);
|
||||
float fBeat = NoteRowToBeat(seg->m_iStartRow);
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
DrawTimeSignatureText( fBeat, vTimeSignatureSegments[i].m_iNumerator, vTimeSignatureSegments[i].m_iDenominator );
|
||||
DrawTimeSignatureText( fBeat, seg->m_iNumerator, seg->m_iDenominator );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Tickcount text
|
||||
const vector<TickcountSegment> &tTickcountSegments = GAMESTATE->m_pCurSong->m_Timing.m_TickcountSegments;
|
||||
for( unsigned i=0; i<tTickcountSegments.size(); i++ )
|
||||
FOREACH_CONST( TickcountSegment, GAMESTATE->m_pCurSong->m_Timing.m_TickcountSegments, seg )
|
||||
{
|
||||
if( tTickcountSegments[i].m_iStartRow >= iFirstRowToDraw &&
|
||||
tTickcountSegments[i].m_iStartRow <= iLastRowToDraw)
|
||||
if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw )
|
||||
{
|
||||
float fBeat = NoteRowToBeat(tTickcountSegments[i].m_iStartRow);
|
||||
float fBeat = NoteRowToBeat(seg->m_iStartRow);
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
DrawTickcountText( fBeat, tTickcountSegments[i].m_iTicks );
|
||||
DrawTickcountText( fBeat, seg->m_iTicks );
|
||||
}
|
||||
}
|
||||
|
||||
// Combo text
|
||||
const vector<ComboSegment> &tComboSegments = GAMESTATE->m_pCurSong->m_Timing.m_ComboSegments;
|
||||
for( unsigned i=0; i<tComboSegments.size(); i++ )
|
||||
FOREACH_CONST( ComboSegment, GAMESTATE->m_pCurSong->m_Timing.m_ComboSegments, seg )
|
||||
{
|
||||
if( tComboSegments[i].m_iStartRow >= iFirstRowToDraw &&
|
||||
tComboSegments[i].m_iStartRow <= iLastRowToDraw)
|
||||
if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw )
|
||||
{
|
||||
float fBeat = NoteRowToBeat(tComboSegments[i].m_iStartRow);
|
||||
float fBeat = NoteRowToBeat(seg->m_iStartRow);
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
DrawComboText( fBeat, tComboSegments[i].m_iCombo );
|
||||
DrawComboText( fBeat, seg->m_iCombo );
|
||||
}
|
||||
}
|
||||
|
||||
// todo: add warp text -aj
|
||||
|
||||
// Course mods text
|
||||
const Course *pCourse = GAMESTATE->m_pCurCourse;
|
||||
if( pCourse )
|
||||
|
||||
@@ -57,6 +57,7 @@ protected:
|
||||
void DrawAreaHighlight( int iStartBeat, int iEndBeat );
|
||||
void DrawBPMText( const float fBeat, const float fBPM );
|
||||
void DrawFreezeText( const float fBeat, const float fBPM, const float bDelay );
|
||||
void DrawWarpText( const float fBeat, const float fNewBeat );
|
||||
void DrawTimeSignatureText( const float fBeat, int iNumerator, int iDenominator );
|
||||
void DrawTickcountText( const float fBeat, int iTicks );
|
||||
void DrawComboText( const float fBeat, int iCombo );
|
||||
|
||||
+6
-5
@@ -134,9 +134,9 @@ struct TapNote
|
||||
void LoadFromNode( const XNode* pNode );
|
||||
|
||||
TapNote(): type(empty), subType(SubType_Invalid), source(original),
|
||||
pn(PLAYER_INVALID), bHopoPossible(false),
|
||||
result(), pn(PLAYER_INVALID), bHopoPossible(false),
|
||||
sAttackModifiers(""), fAttackDurationSeconds(0),
|
||||
iKeysoundIndex(-1), iDuration(0) {}
|
||||
iKeysoundIndex(-1), iDuration(0), HoldResult() {}
|
||||
void Init()
|
||||
{
|
||||
type = empty;
|
||||
@@ -155,10 +155,11 @@ struct TapNote
|
||||
RString sAttackModifiers_,
|
||||
float fAttackDurationSeconds_,
|
||||
int iKeysoundIndex_ ):
|
||||
type(type_), subType(subType_), source(source_),
|
||||
pn(PLAYER_INVALID), sAttackModifiers(sAttackModifiers_),
|
||||
type(type_), subType(subType_), source(source_), result(),
|
||||
pn(PLAYER_INVALID), bHopoPossible(false),
|
||||
sAttackModifiers(sAttackModifiers_),
|
||||
fAttackDurationSeconds(fAttackDurationSeconds_),
|
||||
iKeysoundIndex(iKeysoundIndex_), iDuration(0) {}
|
||||
iKeysoundIndex(iKeysoundIndex_), iDuration(0), HoldResult() {}
|
||||
|
||||
/**
|
||||
* @brief Determine if the two TapNotes are equal to each other.
|
||||
|
||||
+67
-37
@@ -138,31 +138,10 @@ static RString FindLargestInitialSubstring( const RString &string1, const RStrin
|
||||
return string1.substr( 0, i );
|
||||
}
|
||||
|
||||
static StepsType DetermineStepsType( int iPlayer, const NoteData &nd, const RString &sPath )
|
||||
static StepsType DetermineStepsType( int iPlayer, const NoteData &nd, const RString &sPath, const int iNumNonEmptyTracks )
|
||||
{
|
||||
ASSERT( NUM_BMS_TRACKS == nd.GetNumTracks() );
|
||||
|
||||
bool bTrackHasNote[NUM_NON_AUTO_KEYSOUND_TRACKS];
|
||||
ZERO( bTrackHasNote );
|
||||
|
||||
int iLastRow = nd.GetLastRow();
|
||||
for( int t=0; t<NUM_NON_AUTO_KEYSOUND_TRACKS; t++ )
|
||||
{
|
||||
for( int r=0; r<=iLastRow; r++ )
|
||||
{
|
||||
if( nd.GetTapNote(t, r).type != TapNote::empty )
|
||||
{
|
||||
bTrackHasNote[t] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int iNumNonEmptyTracks = 0;
|
||||
for( int t=0; t<NUM_NON_AUTO_KEYSOUND_TRACKS; t++ )
|
||||
if( bTrackHasNote[t] )
|
||||
iNumNonEmptyTracks++;
|
||||
|
||||
switch( iPlayer )
|
||||
{
|
||||
case 1: // "1 player"
|
||||
@@ -170,6 +149,7 @@ static StepsType DetermineStepsType( int iPlayer, const NoteData &nd, const RStr
|
||||
* 4 - dance 4-panel
|
||||
* 5 - pop 5-key
|
||||
* 6 - dance 6-panel, beat 5-key
|
||||
* 7 - beat 7-key (scratch unused)
|
||||
* 8 - beat 7-key
|
||||
* 9 - popn 9-key */
|
||||
switch( iNumNonEmptyTracks )
|
||||
@@ -199,6 +179,8 @@ static StepsType DetermineStepsType( int iPlayer, const NoteData &nd, const RStr
|
||||
case 8: return StepsType_beat_single7;
|
||||
case 12: return StepsType_beat_double5;
|
||||
case 16: return StepsType_beat_double7;
|
||||
case 5: return StepsType_popn_five;
|
||||
case 9: return StepsType_popn_nine;
|
||||
default: return StepsType_Invalid;
|
||||
}
|
||||
default:
|
||||
@@ -405,11 +387,9 @@ static void SetTimeSigAdjustments( const MeasureToTimeSig_t &sigs, Song &out, Me
|
||||
|
||||
static void ReadTimeSigs( const NameToData_t &mapNameToData, MeasureToTimeSig_t &out )
|
||||
{
|
||||
// some convertors change some measure's time signature before any notes are there
|
||||
// it is required because sometimes the BGA starts before the music and the measure size
|
||||
// is the difference between the start of first bar and the BGA.
|
||||
// something like #00002:1.55. that made all subsequent notes 192th.
|
||||
// here, find the lowest measure for notes, and make this function skip the time signatures before it.
|
||||
/* some songs have BGA starting before the music, so convertors a put weird time signature
|
||||
* at first measure, something like #00002:1.55. that made all subsequent notes 192th.
|
||||
* here, find the lowest measure for notes track, and make it skip the time signatures before it. */
|
||||
int iStartMeasureNo = 999;
|
||||
NameToData_t::const_iterator it;
|
||||
for( it = mapNameToData.lower_bound("#00000"); it != mapNameToData.end(); ++it )
|
||||
@@ -604,7 +584,28 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
|
||||
}
|
||||
}
|
||||
|
||||
out.m_StepsType = DetermineStepsType( iPlayer, ndNotes, sPath );
|
||||
bool bTrackHasNote[NUM_NON_AUTO_KEYSOUND_TRACKS];
|
||||
ZERO( bTrackHasNote );
|
||||
|
||||
int iLastRow = ndNotes.GetLastRow();
|
||||
for( int t=0; t<NUM_NON_AUTO_KEYSOUND_TRACKS; t++ )
|
||||
{
|
||||
for( int r=0; r<=iLastRow; r++ )
|
||||
{
|
||||
if( ndNotes.GetTapNote(t, r).type != TapNote::empty )
|
||||
{
|
||||
bTrackHasNote[t] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int iNumNonEmptyTracks = 0;
|
||||
for( int t=0; t<NUM_NON_AUTO_KEYSOUND_TRACKS; t++ )
|
||||
if( bTrackHasNote[t] )
|
||||
iNumNonEmptyTracks++;
|
||||
|
||||
out.m_StepsType = DetermineStepsType( iPlayer, ndNotes, sPath, iNumNonEmptyTracks );
|
||||
if( out.m_StepsType == StepsType_beat_single5 && GetTagFromMap( mapNameToData, "#title", sData ) )
|
||||
{
|
||||
// Hack: guess at 6-panel.
|
||||
@@ -692,14 +693,30 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
|
||||
iTransformNewToOld[11] = BMS_P2_TURN;
|
||||
break;
|
||||
case StepsType_beat_single7:
|
||||
iTransformNewToOld[0] = BMS_P1_KEY1;
|
||||
iTransformNewToOld[1] = BMS_P1_KEY2;
|
||||
iTransformNewToOld[2] = BMS_P1_KEY3;
|
||||
iTransformNewToOld[3] = BMS_P1_KEY4;
|
||||
iTransformNewToOld[4] = BMS_P1_KEY5;
|
||||
iTransformNewToOld[5] = BMS_P1_KEY6;
|
||||
iTransformNewToOld[6] = BMS_P1_KEY7;
|
||||
iTransformNewToOld[7] = BMS_P1_TURN;
|
||||
if( !bTrackHasNote[BMS_P1_KEY7] && bTrackHasNote[BMS_P1_TURN] )
|
||||
{
|
||||
/* special case for o2mania style charts:
|
||||
* the turntable is used for first key while the real 7th key is not used. */
|
||||
iTransformNewToOld[0] = BMS_P1_TURN;
|
||||
iTransformNewToOld[1] = BMS_P1_KEY1;
|
||||
iTransformNewToOld[2] = BMS_P1_KEY2;
|
||||
iTransformNewToOld[3] = BMS_P1_KEY3;
|
||||
iTransformNewToOld[4] = BMS_P1_KEY4;
|
||||
iTransformNewToOld[5] = BMS_P1_KEY5;
|
||||
iTransformNewToOld[6] = BMS_P1_KEY6;
|
||||
iTransformNewToOld[7] = BMS_P1_KEY7;
|
||||
}
|
||||
else
|
||||
{
|
||||
iTransformNewToOld[0] = BMS_P1_KEY1;
|
||||
iTransformNewToOld[1] = BMS_P1_KEY2;
|
||||
iTransformNewToOld[2] = BMS_P1_KEY3;
|
||||
iTransformNewToOld[3] = BMS_P1_KEY4;
|
||||
iTransformNewToOld[4] = BMS_P1_KEY5;
|
||||
iTransformNewToOld[5] = BMS_P1_KEY6;
|
||||
iTransformNewToOld[6] = BMS_P1_KEY7;
|
||||
iTransformNewToOld[7] = BMS_P1_TURN;
|
||||
}
|
||||
break;
|
||||
case StepsType_beat_double7:
|
||||
iTransformNewToOld[0] = BMS_P1_KEY1;
|
||||
@@ -733,7 +750,7 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
|
||||
int iEmptyTrack = -1;
|
||||
for( int i=0; i<iNumNewTracks; i++ )
|
||||
{
|
||||
if ( ndNotes.GetTapNote(iTransformNewToOld[i], row) == TAP_EMPTY )
|
||||
if ( ndNotes.GetTapNote(iTransformNewToOld[i], row) == TAP_EMPTY && !ndNotes.IsHoldNoteAtRow(iTransformNewToOld[i], row) )
|
||||
{
|
||||
iEmptyTrack = iTransformNewToOld[i];
|
||||
break;
|
||||
@@ -977,6 +994,7 @@ void BMSLoader::GetApplicableFiles( const RString &sPath, vector<RString> &out )
|
||||
{
|
||||
GetDirListing( sPath + RString("*.bms"), out );
|
||||
GetDirListing( sPath + RString("*.bme"), out );
|
||||
GetDirListing( sPath + RString("*.bml"), out );
|
||||
}
|
||||
|
||||
bool BMSLoader::LoadFromDir( const RString &sDir, Song &out )
|
||||
@@ -1086,6 +1104,18 @@ bool BMSLoader::LoadFromDir( const RString &sDir, Song &out )
|
||||
map<RString,int> idToKeysoundIndex;
|
||||
ReadGlobalTags( aBMSData[iMainDataIndex], out, sigAdjustments, idToKeysoundIndex );
|
||||
|
||||
// The brackets before the difficulty are in common substring, so remove them if it's found.
|
||||
if( commonSubstring.size() > 2 && commonSubstring[commonSubstring.size() - 2] == ' ' )
|
||||
{
|
||||
switch( commonSubstring[commonSubstring.size() - 1] )
|
||||
{
|
||||
case '[':
|
||||
case '(':
|
||||
case '<':
|
||||
commonSubstring = commonSubstring.substr(0, commonSubstring.size() - 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Override what that global tag said about the title if we have a good substring.
|
||||
// Prevents clobbering and catches "MySong (7keys)" / "MySong (Another) (7keys)"
|
||||
// Also catches "MySong (7keys)" / "MySong (14keys)"
|
||||
|
||||
@@ -500,18 +500,18 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set<RString> &Bla
|
||||
* worth bothering with since we don't display fractional BPM anyway.) */
|
||||
if( sscanf( sParams[1], "%i..%i", &iMin, &iMax ) == 2 )
|
||||
{
|
||||
out.m_DisplayBPMType = Song::DISPLAY_SPECIFIED;
|
||||
out.m_DisplayBPMType = DISPLAY_BPM_SPECIFIED;
|
||||
out.m_fSpecifiedBPMMin = (float) iMin;
|
||||
out.m_fSpecifiedBPMMax = (float) iMax;
|
||||
}
|
||||
else if( sscanf( sParams[1], "%i", &iMin ) == 1 )
|
||||
{
|
||||
out.m_DisplayBPMType = Song::DISPLAY_SPECIFIED;
|
||||
out.m_DisplayBPMType = DISPLAY_BPM_SPECIFIED;
|
||||
out.m_fSpecifiedBPMMin = out.m_fSpecifiedBPMMax = (float) iMin;
|
||||
}
|
||||
else
|
||||
{
|
||||
out.m_DisplayBPMType = Song::DISPLAY_RANDOM;
|
||||
out.m_DisplayBPMType = DISPLAY_BPM_RANDOM;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ static StepsType DetermineStepsType( int iPlayer, const NoteData &nd, const RStr
|
||||
switch( iPlayer )
|
||||
{
|
||||
case 1:
|
||||
case 3:
|
||||
switch( iNumNonEmptyTracks )
|
||||
{
|
||||
case 5: return StepsType_popn_five;
|
||||
|
||||
+123
-170
@@ -12,7 +12,13 @@
|
||||
#include "Steps.h"
|
||||
#include "PrefsManager.h"
|
||||
|
||||
/** @brief The maximum file size for edits. */
|
||||
const int MAX_EDIT_STEPS_SIZE_BYTES = 60*1024; // 60KB
|
||||
/**
|
||||
* @brief The highest allowable speed before Warps come in.
|
||||
*
|
||||
* This was brought in from StepMania 4's recent betas. */
|
||||
const float FAST_BPM_WARP = 9999999.f;
|
||||
|
||||
void SMLoader::LoadFromSMTokens(
|
||||
RString sStepsType,
|
||||
@@ -104,9 +110,6 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
|
||||
out.m_WarpSegments.clear();
|
||||
out.m_vTimeSignatureSegments.clear();
|
||||
|
||||
vector<WarpSegment> arrayWarpsFromNegativeBPMs;
|
||||
//vector<WarpSegment> arrayWarpsFromNegativeStops;
|
||||
|
||||
for( unsigned i=0; i<msd.GetNumValues(); i++ )
|
||||
{
|
||||
const MsdFile::value_t &sParams = msd.GetValue(i);
|
||||
@@ -117,11 +120,83 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
|
||||
{
|
||||
out.m_fBeat0OffsetInSeconds = StringToFloat( sParams[1] );
|
||||
}
|
||||
else if( sValueName=="BPMS" )
|
||||
{
|
||||
vector<RString> arrayBPMChangeExpressions;
|
||||
split( sParams[1], ",", arrayBPMChangeExpressions );
|
||||
|
||||
// prepare storage variables for negative BPMs -> Warps.
|
||||
float negBeat = -1;
|
||||
float negBPM = 1;
|
||||
float highspeedBeat = -1;
|
||||
|
||||
for( unsigned b=0; b<arrayBPMChangeExpressions.size(); b++ )
|
||||
{
|
||||
vector<RString> arrayBPMChangeValues;
|
||||
split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues );
|
||||
// XXX: Hard to tell which file caused this.
|
||||
if( arrayBPMChangeValues.size() != 2 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.",
|
||||
sValueName.c_str(), arrayBPMChangeExpressions[b].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fBeat = StringToFloat( arrayBPMChangeValues[0] );
|
||||
const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] );
|
||||
|
||||
if( fNewBPM < 0.0f )
|
||||
{
|
||||
out.m_bHasNegativeBpms = true;
|
||||
negBeat = fBeat;
|
||||
negBPM = fNewBPM;
|
||||
}
|
||||
else if( fNewBPM > 0.0f )
|
||||
{
|
||||
// add in a warp.
|
||||
if( negBPM < 0 )
|
||||
{
|
||||
float endBeat = fBeat + (fNewBPM / -negBPM) * (fBeat - negBeat);
|
||||
WarpSegment new_seg(negBeat, endBeat);
|
||||
out.AddWarpSegment( new_seg );
|
||||
|
||||
negBeat = -1;
|
||||
negBPM = 1;
|
||||
}
|
||||
// too fast. make it a warp.
|
||||
if( fNewBPM > FAST_BPM_WARP )
|
||||
{
|
||||
highspeedBeat = fBeat;
|
||||
}
|
||||
else
|
||||
{
|
||||
// add in a warp.
|
||||
if( highspeedBeat > 0 )
|
||||
{
|
||||
WarpSegment new_seg(highspeedBeat, fBeat);
|
||||
out.AddWarpSegment( new_seg );
|
||||
highspeedBeat = -1;
|
||||
}
|
||||
{
|
||||
BPMSegment new_seg;
|
||||
new_seg.m_iStartRow = BeatToNoteRow(fBeat);
|
||||
new_seg.SetBPM( fNewBPM );
|
||||
out.AddBPMSegment( new_seg );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if( sValueName=="STOPS" || sValueName=="FREEZES" )
|
||||
{
|
||||
vector<RString> arrayFreezeExpressions;
|
||||
split( sParams[1], ",", arrayFreezeExpressions );
|
||||
|
||||
// Prepare variables for negative stop conversion.
|
||||
float negBeat = -1;
|
||||
float negPause = 0;
|
||||
|
||||
for( unsigned f=0; f<arrayFreezeExpressions.size(); f++ )
|
||||
{
|
||||
vector<RString> arrayFreezeValues;
|
||||
@@ -136,29 +211,49 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
|
||||
|
||||
const float fFreezeBeat = StringToFloat( arrayFreezeValues[0] );
|
||||
const float fFreezeSeconds = StringToFloat( arrayFreezeValues[1] );
|
||||
StopSegment new_seg( BeatToNoteRow(fFreezeBeat), fFreezeSeconds );
|
||||
// XXX: Remove Negatives Bug?
|
||||
new_seg.m_iStartRow = BeatToNoteRow(fFreezeBeat);
|
||||
new_seg.m_fStopSeconds = fFreezeSeconds;
|
||||
|
||||
if(fFreezeSeconds > 0.0f)
|
||||
|
||||
// Process the prior stop.
|
||||
if( negPause > 0 )
|
||||
{
|
||||
// LOG->Trace( "Adding a freeze segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds );
|
||||
out.AddStopSegment( new_seg );
|
||||
BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat));
|
||||
float fSecondsPerBeat = 60 / oldBPM.GetBPM();
|
||||
float fSkipBeats = negPause / fSecondsPerBeat;
|
||||
|
||||
if( negBeat + fSkipBeats > fFreezeBeat )
|
||||
fSkipBeats = fFreezeBeat - negBeat;
|
||||
|
||||
WarpSegment ws( negBeat, negBeat + fSkipBeats);
|
||||
out.AddWarpSegment( ws );
|
||||
|
||||
negBeat = -1;
|
||||
negPause = 0;
|
||||
}
|
||||
else
|
||||
|
||||
if( fFreezeSeconds < 0.0f )
|
||||
{
|
||||
// negative stops (hi JS!) -aj
|
||||
if( PREFSMAN->m_bQuirksMode )
|
||||
{
|
||||
// LOG->Trace( "Adding a negative freeze segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds );
|
||||
out.AddStopSegment( new_seg );
|
||||
}
|
||||
else
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid stop at beat %f, length %f.", fFreezeBeat, fFreezeSeconds );
|
||||
negBeat = fFreezeBeat;
|
||||
negPause = -fFreezeSeconds;
|
||||
}
|
||||
else if( fFreezeSeconds > 0.0f )
|
||||
{
|
||||
StopSegment ss( BeatToNoteRow(fFreezeBeat), fFreezeSeconds );
|
||||
out.AddStopSegment( ss );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Process the prior stop if there was one.
|
||||
if( negPause > 0 )
|
||||
{
|
||||
BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat));
|
||||
float fSecondsPerBeat = 60 / oldBPM.GetBPM();
|
||||
float fSkipBeats = negPause / fSecondsPerBeat;
|
||||
|
||||
WarpSegment ws( negBeat, negBeat + fSkipBeats);
|
||||
out.AddWarpSegment( ws );
|
||||
}
|
||||
}
|
||||
|
||||
else if( sValueName=="DELAYS" )
|
||||
{
|
||||
vector<RString> arrayDelayExpressions;
|
||||
@@ -183,7 +278,7 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
|
||||
// XXX: Remove Negatives Bug?
|
||||
new_seg.m_iStartRow = BeatToNoteRow(fFreezeBeat);
|
||||
new_seg.m_fStopSeconds = fFreezeSeconds;
|
||||
|
||||
|
||||
// LOG->Trace( "Adding a delay segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds );
|
||||
|
||||
if(fFreezeSeconds > 0.0f)
|
||||
@@ -193,95 +288,6 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
|
||||
}
|
||||
}
|
||||
|
||||
else if( sValueName=="BPMS" )
|
||||
{
|
||||
vector<RString> arrayBPMChangeExpressions;
|
||||
split( sParams[1], ",", arrayBPMChangeExpressions );
|
||||
|
||||
for( unsigned b=0; b<arrayBPMChangeExpressions.size(); b++ )
|
||||
{
|
||||
vector<RString> arrayBPMChangeValues;
|
||||
split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues );
|
||||
// XXX: Hard to tell which file caused this.
|
||||
if( arrayBPMChangeValues.size() != 2 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.",
|
||||
sValueName.c_str(), arrayBPMChangeExpressions[b].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fBeat = StringToFloat( arrayBPMChangeValues[0] );
|
||||
const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] );
|
||||
// XXX: Remove Negatives Bug?
|
||||
BPMSegment new_seg;
|
||||
new_seg.m_iStartRow = BeatToNoteRow(fBeat);
|
||||
new_seg.SetBPM( fNewBPM );
|
||||
|
||||
// convert negative BPMs into Warp segments
|
||||
if( fNewBPM < 0.0f )
|
||||
{
|
||||
vector<RString> arrayNextBPMChangeValues;
|
||||
// get next bpm in sequence
|
||||
if((b+1) < arrayBPMChangeExpressions.size())
|
||||
{
|
||||
split( arrayBPMChangeExpressions[b+1], "=", arrayNextBPMChangeValues );
|
||||
const float fNextPositiveBeat = StringToFloat( arrayNextBPMChangeValues[0] );
|
||||
const float fNextPositiveBPM = StringToFloat( arrayNextBPMChangeValues[1] );
|
||||
|
||||
// tJumpPos = (tPosBPS-abs(negBPS)) + (gPosBPMPosition - fNegPosition)
|
||||
float fDeltaBeat = ((fNextPositiveBPM/60.0f)-abs(fNewBPM/60.0f)) + (fNextPositiveBeat-fBeat);
|
||||
//float fWarpLengthBeats = fNextPositiveBeat + fDeltaBeat;
|
||||
WarpSegment wsTemp(BeatToNoteRow(fBeat),fDeltaBeat);
|
||||
arrayWarpsFromNegativeBPMs.push_back(wsTemp);
|
||||
|
||||
/*
|
||||
LOG->Trace( ssprintf("==NotesLoSM negbpm==\nfnextposbeat = %f, fnextposbpm = %f,\nfdelta = %f, fwarpto = %f",
|
||||
fNextPositiveBeat,
|
||||
fNextPositiveBPM,
|
||||
fDeltaBeat,
|
||||
fWarpToBeat
|
||||
) );
|
||||
*/
|
||||
/*
|
||||
LOG->Trace( ssprintf("==Negative/Subtractive BPM in NotesLoader==\nNegBPM has noterow = %i, BPM = %f\nNextBPM @ noterow %i\nDelta value = %i noterows\nThis warp will have us end up at noterow %i",
|
||||
BeatToNoteRow(fBeat), fNewBPM,
|
||||
BeatToNoteRow(fNextPositiveBeat),
|
||||
BeatToNoteRow(fDeltaBeat),
|
||||
BeatToNoteRow(fWarpToBeat))
|
||||
);
|
||||
*/
|
||||
//float fDeltaBeat = ((fNextPositiveBPM/60.0f)-abs(fNewBPM/60.0f)) + (fNextPositiveBeat-fBeat);
|
||||
/*
|
||||
LOG->Trace( ssprintf("==NotesLoader Delta as NoteRows==\nfDeltaBeat = %f (beat)\nfDeltaBeat = (NextBPMSeg %f - abs(fBPS %f)) + (nextStartRow %i - thisRow %i)",
|
||||
fDeltaBeat,(fNextPositiveBPM/60.0f),abs(fNewBPM/60.0f),BeatToNoteRow(fNextPositiveBeat),BeatToNoteRow(fBeat))
|
||||
);
|
||||
*/
|
||||
|
||||
out.AddBPMSegment( new_seg );
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// last BPM is a negative one? ugh. -aj (MAX_NOTE_ROW exists btw)
|
||||
out.AddBPMSegment( new_seg );
|
||||
}
|
||||
}
|
||||
|
||||
if(fNewBPM > 0.0f)
|
||||
out.AddBPMSegment( new_seg );
|
||||
else
|
||||
{
|
||||
out.m_bHasNegativeBpms = true;
|
||||
// only add Negative BPMs in quirks mode -aj
|
||||
if( PREFSMAN->m_bQuirksMode )
|
||||
out.AddBPMSegment( new_seg );
|
||||
else
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid BPM change at beat %f, BPM %f.", fBeat, fNewBPM );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if( sValueName=="TIMESIGNATURES" )
|
||||
{
|
||||
vector<RString> vs1;
|
||||
@@ -326,12 +332,12 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
|
||||
out.AddTimeSignatureSegment( seg );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
else if( sValueName=="TICKCOUNTS" )
|
||||
{
|
||||
vector<RString> arrayTickcountExpressions;
|
||||
split( sParams[1], ",", arrayTickcountExpressions );
|
||||
|
||||
|
||||
for( unsigned f=0; f<arrayTickcountExpressions.size(); f++ )
|
||||
{
|
||||
vector<RString> arrayTickcountValues;
|
||||
@@ -343,7 +349,7 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
|
||||
sValueName.c_str(), arrayTickcountExpressions[f].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
const float fTickcountBeat = StringToFloat( arrayTickcountValues[0] );
|
||||
int iTicks = atoi( arrayTickcountValues[1] );
|
||||
// you're lazy, let SM do the work for you... -DaisuMaster
|
||||
@@ -366,61 +372,8 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// warps (replacement for Negative BPM and Negative Stops)
|
||||
/*
|
||||
else if( sValueName=="WARPS" )
|
||||
{
|
||||
vector<RString> arrayWarpExpressions;
|
||||
split( sParams[1], ",", arrayWarpExpressions );
|
||||
|
||||
for( unsigned f=0; f<arrayWarpExpressions.size(); f++ )
|
||||
{
|
||||
vector<RString> arrayWarpValues;
|
||||
split( arrayWarpExpressions[f], "=", arrayWarpValues );
|
||||
if( arrayWarpValues.size() != 2 )
|
||||
{
|
||||
// XXX: Hard to tell which file caused this.
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.",
|
||||
sValueName.c_str(), arrayWarpExpressions[f].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fWarpStart = StringToFloat( arrayWarpValues[0] );
|
||||
const float fWarpBeats = StringToFloat( arrayWarpValues[1] );
|
||||
|
||||
if( fWarpStart > 0.0f && fWarpBeats > 0.0f )
|
||||
{
|
||||
WarpSegment new_seg( BeatToNoteRow(fWarpStart), fWarpBeats );
|
||||
out.AddWarpSegment( new_seg );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Currently disallow negative warps, to prevent the same
|
||||
// kind of problem that happened when Negative/Subtractive
|
||||
// BPMs arrived on the StepMania scene. -aj
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid warp at beat %f lasting %f beats.", fWarpStart, fWarpBeats );
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Note: Even though it is possible to have Negative BPMs and Stops in
|
||||
// a song along with Warps, we should not support files that contain
|
||||
// both styles of warp tricks (Negatives vs. #WARPS).
|
||||
// If Warps have been populated from Negative BPMs, then go through that
|
||||
// instead of using the data in the Warps tag. This should be above,
|
||||
// but it breaks compiling so...
|
||||
if(arrayWarpsFromNegativeBPMs.size() > 0)
|
||||
{
|
||||
// zomg we already have some warps...
|
||||
for( unsigned j=0; j<arrayWarpsFromNegativeBPMs.size(); j++ )
|
||||
{
|
||||
out.AddWarpSegment( arrayWarpsFromNegativeBPMs[j] );
|
||||
}
|
||||
}
|
||||
// warp sorting will need to take place.
|
||||
//sort(out.m_WarpSegments.begin(), out.m_WarpSegments.end());
|
||||
// Ensure all of the warps are handled right.
|
||||
sort(out.m_WarpSegments.begin(), out.m_WarpSegments.end());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -628,10 +581,10 @@ bool SMLoader::LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache
|
||||
{
|
||||
// #DISPLAYBPM:[xxx][xxx:xxx]|[*];
|
||||
if( sParams[1] == "*" )
|
||||
out.m_DisplayBPMType = Song::DISPLAY_RANDOM;
|
||||
out.m_DisplayBPMType = DISPLAY_BPM_RANDOM;
|
||||
else
|
||||
{
|
||||
out.m_DisplayBPMType = Song::DISPLAY_SPECIFIED;
|
||||
out.m_DisplayBPMType = DISPLAY_BPM_SPECIFIED;
|
||||
out.m_fSpecifiedBPMMin = StringToFloat( sParams[1] );
|
||||
if( sParams[2].empty() )
|
||||
out.m_fSpecifiedBPMMax = out.m_fSpecifiedBPMMin;
|
||||
|
||||
@@ -230,10 +230,10 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out )
|
||||
{
|
||||
// #DISPLAYBPM:[xxx][xxx:xxx]|[*];
|
||||
if( sParams[1] == "*" )
|
||||
out.m_DisplayBPMType = Song::DISPLAY_RANDOM;
|
||||
out.m_DisplayBPMType = DISPLAY_BPM_RANDOM;
|
||||
else
|
||||
{
|
||||
out.m_DisplayBPMType = Song::DISPLAY_SPECIFIED;
|
||||
out.m_DisplayBPMType = DISPLAY_BPM_SPECIFIED;
|
||||
out.m_fSpecifiedBPMMin = StringToFloat( sParams[1] );
|
||||
if( sParams[2].empty() )
|
||||
out.m_fSpecifiedBPMMax = out.m_fSpecifiedBPMMin;
|
||||
|
||||
+36
-2
@@ -178,6 +178,11 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach
|
||||
out.m_sGenre = sParams[1];
|
||||
}
|
||||
|
||||
else if( sValueName=="ORIGIN" )
|
||||
{
|
||||
out.m_sOrigin = sParams[1];
|
||||
}
|
||||
|
||||
else if( sValueName=="CREDIT" )
|
||||
{
|
||||
out.m_sCredit = sParams[1];
|
||||
@@ -256,10 +261,10 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach
|
||||
{
|
||||
// #DISPLAYBPM:[xxx][xxx:xxx]|[*];
|
||||
if( sParams[1] == "*" )
|
||||
out.m_DisplayBPMType = Song::DISPLAY_RANDOM;
|
||||
out.m_DisplayBPMType = DISPLAY_BPM_RANDOM;
|
||||
else
|
||||
{
|
||||
out.m_DisplayBPMType = Song::DISPLAY_SPECIFIED;
|
||||
out.m_DisplayBPMType = DISPLAY_BPM_SPECIFIED;
|
||||
out.m_fSpecifiedBPMMin = StringToFloat( sParams[1] );
|
||||
if( sParams[2].empty() )
|
||||
out.m_fSpecifiedBPMMax = out.m_fSpecifiedBPMMin;
|
||||
@@ -485,6 +490,35 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if( sValueName=="WARPS" )
|
||||
{
|
||||
vector<RString> arrayWarpExpressions;
|
||||
split( sParams[1], ",", arrayWarpExpressions );
|
||||
|
||||
for( unsigned b=0; b<arrayWarpExpressions.size(); b++ )
|
||||
{
|
||||
vector<RString> arrayWarpValues;
|
||||
split( arrayWarpExpressions[b], "=", arrayWarpValues );
|
||||
// XXX: Hard to tell which file caused this.
|
||||
if( arrayWarpValues.size() != 2 )
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.",
|
||||
sValueName.c_str(), arrayWarpExpressions[b].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fBeat = StringToFloat( arrayWarpValues[0] );
|
||||
const float fNewBeat = StringToFloat( arrayWarpValues[1] );
|
||||
|
||||
if(fNewBeat > fBeat)
|
||||
out.m_Timing.AddWarpSegment( WarpSegment(fBeat, fNewBeat) );
|
||||
else
|
||||
{
|
||||
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Warp at beat %f, BPM %f.", fBeat, fNewBeat );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if( sValueName=="TIMESIGNATURES" )
|
||||
{
|
||||
|
||||
@@ -21,7 +21,10 @@ enum SSCLoadingStates
|
||||
NUM_SSCLoadingStates /**< The number of states used. */
|
||||
};
|
||||
|
||||
/** @brief The version where fakes started to be used as a radar category. */
|
||||
const float VERSION_RADAR_FAKE = 0.53f;
|
||||
/** @brief The version where WarpSegments started to be utilized. */
|
||||
const float VERSION_WARP_SEGMENT = 0.56f;
|
||||
|
||||
/**
|
||||
* @brief The SSCLoader handles all of the parsing needed for .ssc files.
|
||||
|
||||
@@ -360,16 +360,16 @@ bool NotesWriterDWI::Write( RString sPath, const Song &out )
|
||||
f.PutLine( ssprintf("#CDTITLE:%s;", DwiEscape(out.m_sCDTitleFile).c_str()) );
|
||||
switch( out.m_DisplayBPMType )
|
||||
{
|
||||
case Song::DISPLAY_ACTUAL:
|
||||
case DISPLAY_BPM_ACTUAL:
|
||||
// write nothing
|
||||
break;
|
||||
case Song::DISPLAY_SPECIFIED:
|
||||
case DISPLAY_BPM_SPECIFIED:
|
||||
if( out.m_fSpecifiedBPMMin == out.m_fSpecifiedBPMMax )
|
||||
f.PutLine( ssprintf("#DISPLAYBPM:%i;\n", (int) out.m_fSpecifiedBPMMin) );
|
||||
else
|
||||
f.PutLine( ssprintf("#DISPLAYBPM:%i..%i;\n", (int) out.m_fSpecifiedBPMMin, (int) out.m_fSpecifiedBPMMax) );
|
||||
break;
|
||||
case Song::DISPLAY_RANDOM:
|
||||
case DISPLAY_BPM_RANDOM:
|
||||
f.PutLine( "#DISPLAYBPM:*" );
|
||||
break;
|
||||
}
|
||||
|
||||
+16
-31
@@ -76,11 +76,11 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
|
||||
f.PutLine( "#INSTRUMENTTRACK:" + s + ";\n" );
|
||||
}
|
||||
}
|
||||
f.PutLine( ssprintf( "#OFFSET:%.6f;", out.m_Timing.m_fBeat0OffsetInSeconds ) );
|
||||
f.PutLine( ssprintf( "#SAMPLESTART:%.6f;", out.m_fMusicSampleStartSeconds ) );
|
||||
f.PutLine( ssprintf( "#SAMPLELENGTH:%.6f;", out.m_fMusicSampleLengthSeconds ) );
|
||||
f.PutLine( ssprintf( "#OFFSET:%.3f;", out.m_Timing.m_fBeat0OffsetInSeconds ) );
|
||||
f.PutLine( ssprintf( "#SAMPLESTART:%.3f;", out.m_fMusicSampleStartSeconds ) );
|
||||
f.PutLine( ssprintf( "#SAMPLELENGTH:%.3f;", out.m_fMusicSampleLengthSeconds ) );
|
||||
if( out.m_fSpecifiedLastBeat > 0 )
|
||||
f.PutLine( ssprintf("#LASTBEATHINT:%.6f;", out.m_fSpecifiedLastBeat) );
|
||||
f.PutLine( ssprintf("#LASTBEATHINT:%.3f;", out.m_fSpecifiedLastBeat) );
|
||||
|
||||
f.Write( "#SELECTABLE:" );
|
||||
switch(out.m_SelectionDisplay)
|
||||
@@ -94,17 +94,17 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
|
||||
|
||||
switch( out.m_DisplayBPMType )
|
||||
{
|
||||
case Song::DISPLAY_ACTUAL:
|
||||
case DISPLAY_BPM_ACTUAL:
|
||||
// write nothing
|
||||
break;
|
||||
case Song::DISPLAY_SPECIFIED:
|
||||
case DISPLAY_BPM_SPECIFIED:
|
||||
if( out.m_fSpecifiedBPMMin == out.m_fSpecifiedBPMMax )
|
||||
f.PutLine( ssprintf( "#DISPLAYBPM:%.6f;", out.m_fSpecifiedBPMMin ) );
|
||||
f.PutLine( ssprintf( "#DISPLAYBPM:%.3f;", out.m_fSpecifiedBPMMin ) );
|
||||
else
|
||||
f.PutLine( ssprintf( "#DISPLAYBPM:%.6f:%.6f;",
|
||||
f.PutLine( ssprintf( "#DISPLAYBPM:%.3f:%.3f;",
|
||||
out.m_fSpecifiedBPMMin, out.m_fSpecifiedBPMMax ) );
|
||||
break;
|
||||
case Song::DISPLAY_RANDOM:
|
||||
case DISPLAY_BPM_RANDOM:
|
||||
f.PutLine( ssprintf( "#DISPLAYBPM:*;" ) );
|
||||
break;
|
||||
}
|
||||
@@ -115,7 +115,7 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
|
||||
{
|
||||
const BPMSegment &bs = out.m_Timing.m_BPMSegments[i];
|
||||
|
||||
f.PutLine( ssprintf( "%.6f=%.6f", NoteRowToBeat(bs.m_iStartRow), bs.GetBPM() ) );
|
||||
f.PutLine( ssprintf( "%.3f=%.3f", NoteRowToBeat(bs.m_iStartRow), bs.GetBPM() ) );
|
||||
if( i != out.m_Timing.m_BPMSegments.size()-1 )
|
||||
f.Write( "," );
|
||||
}
|
||||
@@ -128,7 +128,7 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
|
||||
|
||||
if(!fs.m_bDelay)
|
||||
{
|
||||
f.PutLine( ssprintf( "%.6f=%.6f", NoteRowToBeat(fs.m_iStartRow), fs.m_fStopSeconds ) );
|
||||
f.PutLine( ssprintf( "%.3f=%.3f", NoteRowToBeat(fs.m_iStartRow), fs.m_fStopSeconds ) );
|
||||
if( i != out.m_Timing.m_StopSegments.size()-1 )
|
||||
f.Write( "," );
|
||||
}
|
||||
@@ -142,31 +142,18 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
|
||||
|
||||
if( fs.m_bDelay )
|
||||
{
|
||||
f.PutLine( ssprintf( "%.6f=%.6f", NoteRowToBeat(fs.m_iStartRow), fs.m_fStopSeconds ) );
|
||||
f.PutLine( ssprintf( "%.3f=%.3f", NoteRowToBeat(fs.m_iStartRow), fs.m_fStopSeconds ) );
|
||||
if( i != out.m_Timing.m_StopSegments.size()-1 )
|
||||
f.Write( "," );
|
||||
}
|
||||
}
|
||||
f.PutLine( ";" );
|
||||
|
||||
/*
|
||||
f.Write( "#WARPS:" );
|
||||
for( unsigned i=0; i<out.m_Timing.m_WarpSegments.size(); i++ )
|
||||
{
|
||||
const WarpSegment &ws = out.m_Timing.m_WarpSegments[i];
|
||||
|
||||
f.PutLine( ssprintf( "%.6f=%.6f", NoteRowToBeat(ws.m_iStartRow), ws.m_fWarpBeats ) );
|
||||
if( i != out.m_Timing.m_WarpSegments.size()-1 )
|
||||
f.Write( "," );
|
||||
}
|
||||
f.PutLine( ";" );
|
||||
*/
|
||||
|
||||
ASSERT( !out.m_Timing.m_vTimeSignatureSegments.empty() );
|
||||
f.Write( "#TIMESIGNATURES:" );
|
||||
FOREACH_CONST( TimeSignatureSegment, out.m_Timing.m_vTimeSignatureSegments, iter )
|
||||
{
|
||||
f.PutLine( ssprintf( "%.6f=%d=%d", NoteRowToBeat(iter->m_iStartRow),
|
||||
f.PutLine( ssprintf( "%.3f=%d=%d", NoteRowToBeat(iter->m_iStartRow),
|
||||
iter->m_iNumerator, iter->m_iDenominator ) );
|
||||
vector<TimeSignatureSegment>::const_iterator iter2 = iter;
|
||||
iter2++;
|
||||
@@ -181,7 +168,7 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
|
||||
{
|
||||
const TickcountSegment &ts = out.m_Timing.m_TickcountSegments[i];
|
||||
|
||||
f.PutLine( ssprintf( "%.6f=%d", NoteRowToBeat(ts.m_iStartRow), ts.m_iTicks ) );
|
||||
f.PutLine( ssprintf( "%.3f=%d", NoteRowToBeat(ts.m_iStartRow), ts.m_iTicks ) );
|
||||
if( i != out.m_Timing.m_TickcountSegments.size()-1 )
|
||||
f.Write( "," );
|
||||
}
|
||||
@@ -274,7 +261,7 @@ static RString GetSMNotesTag( const Song &song, const Steps &in )
|
||||
RString desc = (USE_CREDIT ? in.GetCredit() : in.GetDescription());
|
||||
lines.push_back( ssprintf( " %s:", SmEscape(desc).c_str() ) );
|
||||
lines.push_back( ssprintf( " %s:", DifficultyToString(in.GetDifficulty()).c_str() ) );
|
||||
lines.push_back( ssprintf( " %d:", in.GetMeter() ) );
|
||||
lines.push_back( ssprintf( " %d:", clamp( in.GetMeter(), MIN_METER, MAX_METER ) ) );
|
||||
|
||||
vector<RString> asRadarValues;
|
||||
// SM files don't use fakes for radar data. Keep it that way.
|
||||
@@ -300,7 +287,7 @@ static RString GetSMNotesTag( const Song &song, const Steps &in )
|
||||
return JoinLineList( lines );
|
||||
}
|
||||
|
||||
bool NotesWriterSM::Write( RString sPath, const Song &out )
|
||||
bool NotesWriterSM::Write( RString sPath, const Song &out, const vector<Steps*>& vpStepsToSave )
|
||||
{
|
||||
int flags = RageFile::WRITE;
|
||||
|
||||
@@ -315,8 +302,6 @@ bool NotesWriterSM::Write( RString sPath, const Song &out )
|
||||
|
||||
WriteGlobalTags( f, out );
|
||||
|
||||
// Save specified Steps to this file
|
||||
const vector<Steps*>& vpStepsToSave = out.GetAllSteps();
|
||||
FOREACH_CONST( Steps*, vpStepsToSave, s )
|
||||
{
|
||||
const Steps* pSteps = *s;
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ namespace NotesWriterSM
|
||||
* @param sPath the path to write the file.
|
||||
* @param out the Song to be written out.
|
||||
* @return its success or failure. */
|
||||
bool Write( RString sPath, const Song &out );
|
||||
bool Write( RString sPath, const Song &out, const vector<Steps*>& vpStepsToSave );
|
||||
/**
|
||||
* @brief Get some contents about the edit file first.
|
||||
* @param pSong the Song in question.
|
||||
|
||||
+22
-8
@@ -55,6 +55,7 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
|
||||
f.PutLine( ssprintf( "#SUBTITLETRANSLIT:%s;", SmEscape(out.m_sSubTitleTranslit).c_str() ) );
|
||||
f.PutLine( ssprintf( "#ARTISTTRANSLIT:%s;", SmEscape(out.m_sArtistTranslit).c_str() ) );
|
||||
f.PutLine( ssprintf( "#GENRE:%s;", SmEscape(out.m_sGenre).c_str() ) );
|
||||
f.PutLine( ssprintf( "#ORIGIN:%s;", SmEscape(out.m_sOrigin).c_str() ) );
|
||||
f.PutLine( ssprintf( "#CREDIT:%s;", SmEscape(out.m_sCredit).c_str() ) );
|
||||
f.PutLine( ssprintf( "#BANNER:%s;", SmEscape(out.m_sBannerFile).c_str() ) );
|
||||
f.PutLine( ssprintf( "#BACKGROUND:%s;", SmEscape(out.m_sBackgroundFile).c_str() ) );
|
||||
@@ -91,16 +92,16 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
|
||||
|
||||
switch( out.m_DisplayBPMType )
|
||||
{
|
||||
case Song::DISPLAY_ACTUAL:
|
||||
case DISPLAY_BPM_ACTUAL:
|
||||
// write nothing
|
||||
break;
|
||||
case Song::DISPLAY_SPECIFIED:
|
||||
case DISPLAY_BPM_SPECIFIED:
|
||||
if( out.m_fSpecifiedBPMMin == out.m_fSpecifiedBPMMax )
|
||||
f.PutLine( ssprintf( "#DISPLAYBPM:%.6f;", out.m_fSpecifiedBPMMin ) );
|
||||
else
|
||||
f.PutLine( ssprintf( "#DISPLAYBPM:%.6f:%.6f;", out.m_fSpecifiedBPMMin, out.m_fSpecifiedBPMMax ) );
|
||||
break;
|
||||
case Song::DISPLAY_RANDOM:
|
||||
case DISPLAY_BPM_RANDOM:
|
||||
f.PutLine( ssprintf( "#DISPLAYBPM:*;" ) );
|
||||
break;
|
||||
}
|
||||
@@ -144,18 +145,18 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
|
||||
}
|
||||
f.PutLine( ";" );
|
||||
|
||||
/*
|
||||
|
||||
f.Write( "#WARPS:" );
|
||||
for( unsigned i=0; i<out.m_Timing.m_WarpSegments.size(); i++ )
|
||||
{
|
||||
const WarpSegment &ws = out.m_Timing.m_WarpSegments[i];
|
||||
|
||||
f.PutLine( ssprintf( "%.6f=%.6f", NoteRowToBeat(ws.m_iStartRow), ws.m_fWarpBeats ) );
|
||||
f.PutLine( ssprintf( "%.6f=%.6f", NoteRowToBeat(ws.m_iStartRow), ws.m_fEndBeat ) );
|
||||
if( i != out.m_Timing.m_WarpSegments.size()-1 )
|
||||
f.Write( "," );
|
||||
}
|
||||
f.PutLine( ";" );
|
||||
*/
|
||||
|
||||
|
||||
ASSERT( !out.m_Timing.m_vTimeSignatureSegments.empty() );
|
||||
f.Write( "#TIMESIGNATURES:" );
|
||||
@@ -282,7 +283,7 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa
|
||||
lines.push_back( ssprintf( "#DESCRIPTION:%s;", SmEscape(in.GetDescription()).c_str() ) );
|
||||
lines.push_back( ssprintf( "#CHARTSTYLE:%s;", SmEscape(in.GetChartStyle()).c_str() ) );
|
||||
lines.push_back( ssprintf( "#DIFFICULTY:%s;", DifficultyToString(in.GetDifficulty()).c_str() ) );
|
||||
lines.push_back( ssprintf( "#METER:%d;", in.GetMeter() ) );
|
||||
lines.push_back( ssprintf( "#METER:%d;", clamp( in.GetMeter(), MIN_METER, MAX_METER ) ) );
|
||||
|
||||
vector<RString> asRadarValues;
|
||||
FOREACH_PlayerNumber( pn )
|
||||
@@ -299,6 +300,7 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa
|
||||
lines.push_back( "#BPMS:;" );
|
||||
lines.push_back( "#STOPS:;" );
|
||||
lines.push_back( "#DELAYS:;" );
|
||||
lines.push_back( "#WARPS:;" );
|
||||
lines.push_back( "#TIMESIGNATURES:;" );
|
||||
lines.push_back( "#TICKCOUNTS:;" );
|
||||
lines.push_back( "#ATTACKS:;" );
|
||||
@@ -336,7 +338,19 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa
|
||||
}
|
||||
}
|
||||
lines.push_back( ssprintf( "#DELAYS:%s;", join("\n,", asDelayValues).c_str() ) );
|
||||
|
||||
|
||||
vector<RString> asWarpValues;
|
||||
for( unsigned i=0; i<in.m_Timing.m_WarpSegments.size(); i++ )
|
||||
{
|
||||
const WarpSegment &ws = in.m_Timing.m_WarpSegments[i];
|
||||
|
||||
if( ws.m_bDelay )
|
||||
{
|
||||
asWarpValues.push_back( ssprintf( "%.6f=%.6f", NoteRowToBeat(fs.m_iStartRow), fs.m_fWarpBeats ) );
|
||||
}
|
||||
}
|
||||
lines.push_back( ssprintf( "#WARPS:%s;", join("\n,", asWarpValues).c_str() ) );
|
||||
|
||||
ASSERT( !in.m_Timing.m_vTimeSignatureSegments.empty() );
|
||||
vector<RString> asTimeSigValues;
|
||||
FOREACH_CONST( TimeSignatureSegment, in.m_Timing.m_vTimeSignatureSegments, iter )
|
||||
|
||||
+6
-5
@@ -168,7 +168,7 @@ void OptionRow::ChoicesChanged( RowType type )
|
||||
vbSelected[0] = true;
|
||||
}
|
||||
|
||||
// TRICKY: Insert a down arrow as the first choice in the row.
|
||||
// TRICKY: Insert a down arrow as the first choice in the row.
|
||||
if( m_bFirstItemGoesDown )
|
||||
{
|
||||
m_pHand->m_Def.m_vsChoices.insert( m_pHand->m_Def.m_vsChoices.begin(), NEXT_ROW_NAME );
|
||||
@@ -178,7 +178,7 @@ void OptionRow::ChoicesChanged( RowType type )
|
||||
|
||||
InitText( type );
|
||||
|
||||
/* When choices change, the old focus position is meaningless; reset it. */
|
||||
// When choices change, the old focus position is meaningless; reset it.
|
||||
FOREACH_PlayerNumber( p )
|
||||
SetChoiceInRowWithFocus( p, 0 );
|
||||
|
||||
@@ -260,7 +260,7 @@ void OptionRow::InitText( RowType type )
|
||||
m_ModIcons[p] = new ModIcon( m_pParentType->m_ModIcon );
|
||||
m_ModIcons[p]->SetDrawOrder(-1); // under title
|
||||
m_ModIcons[p]->PlayCommand( "On" );
|
||||
|
||||
|
||||
m_Frame.AddChild( m_ModIcons[p] );
|
||||
|
||||
GameCommand gc;
|
||||
@@ -398,7 +398,7 @@ void OptionRow::InitText( RowType type )
|
||||
this->SortByDrawOrder();
|
||||
}
|
||||
|
||||
/* After importing options, choose which item is focused. */
|
||||
// After importing options, choose which item is focused.
|
||||
void OptionRow::AfterImportOptions( PlayerNumber pn )
|
||||
{
|
||||
/* We load items for both players on start, since we don't know which players
|
||||
@@ -604,7 +604,7 @@ void OptionRow::UpdateEnabledDisabled()
|
||||
FOREACH_HumanPlayer( pn )
|
||||
{
|
||||
bRowEnabled = m_pHand->m_Def.m_vEnabledForPlayers.find(pn) != m_pHand->m_Def.m_vEnabledForPlayers.end();
|
||||
|
||||
|
||||
if( !m_pHand->m_Def.m_bOneChoiceForAllPlayers )
|
||||
{
|
||||
if( m_bRowHasFocus[pn] ) color = m_pParentType->COLOR_SELECTED;
|
||||
@@ -645,6 +645,7 @@ void OptionRow::SetModIcon( PlayerNumber pn, const RString &sText, GameCommand &
|
||||
// update row frame
|
||||
Message msg( "Refresh" );
|
||||
msg.SetParam( "GameCommand", &gc );
|
||||
msg.SetParam( "Text", sText );
|
||||
m_sprFrame->HandleMessage( msg );
|
||||
if( m_ModIcons[pn] != NULL )
|
||||
m_ModIcons[pn]->Set( sText );
|
||||
|
||||
+29
-10
@@ -77,15 +77,14 @@ struct OptionRowDefinition
|
||||
|
||||
OptionRowDefinition(): m_sName(""), m_sExplanationName(""),
|
||||
m_bOneChoiceForAllPlayers(false), m_selectType(SELECT_ONE),
|
||||
m_layoutType(LAYOUT_SHOW_ALL_IN_ROW), m_iDefault(-1),
|
||||
m_layoutType(LAYOUT_SHOW_ALL_IN_ROW), m_vsChoices(),
|
||||
m_vEnabledForPlayers(), m_iDefault(-1),
|
||||
m_bExportOnChange(false), m_bAllowThemeItems(true),
|
||||
m_bAllowThemeTitle(true), m_bAllowExplanation(true),
|
||||
m_bShowChoicesListOnSelect(false)
|
||||
{
|
||||
m_vsChoices.clear();
|
||||
m_vEnabledForPlayers.clear();
|
||||
FOREACH_PlayerNumber( pn )
|
||||
m_vEnabledForPlayers.insert( pn );
|
||||
m_vEnabledForPlayers.insert( pn );
|
||||
}
|
||||
void Init()
|
||||
{
|
||||
@@ -106,13 +105,33 @@ struct OptionRowDefinition
|
||||
m_bShowChoicesListOnSelect = false;
|
||||
}
|
||||
|
||||
OptionRowDefinition( const char *n, bool b, const char *c0=NULL, const char *c1=NULL, const char *c2=NULL, const char *c3=NULL, const char *c4=NULL, const char *c5=NULL, const char *c6=NULL, const char *c7=NULL, const char *c8=NULL, const char *c9=NULL, const char *c10=NULL, const char *c11=NULL, const char *c12=NULL, const char *c13=NULL, const char *c14=NULL, const char *c15=NULL, const char *c16=NULL, const char *c17=NULL, const char *c18=NULL, const char *c19=NULL )
|
||||
OptionRowDefinition( const char *n, bool b, const char *c0=NULL,
|
||||
const char *c1=NULL, const char *c2=NULL,
|
||||
const char *c3=NULL, const char *c4=NULL,
|
||||
const char *c5=NULL, const char *c6=NULL,
|
||||
const char *c7=NULL, const char *c8=NULL,
|
||||
const char *c9=NULL, const char *c10=NULL,
|
||||
const char *c11=NULL, const char *c12=NULL,
|
||||
const char *c13=NULL, const char *c14=NULL,
|
||||
const char *c15=NULL, const char *c16=NULL,
|
||||
const char *c17=NULL, const char *c18=NULL,
|
||||
const char *c19=NULL ): m_sName(n),
|
||||
m_sExplanationName(""), m_bOneChoiceForAllPlayers(b),
|
||||
m_selectType(SELECT_ONE),
|
||||
m_layoutType(LAYOUT_SHOW_ALL_IN_ROW), m_vsChoices(),
|
||||
m_vEnabledForPlayers(), m_iDefault(-1),
|
||||
m_bExportOnChange(false), m_bAllowThemeItems(true),
|
||||
m_bAllowThemeTitle(true), m_bAllowExplanation(true),
|
||||
m_bShowChoicesListOnSelect(false)
|
||||
{
|
||||
Init();
|
||||
m_sName=n;
|
||||
m_bOneChoiceForAllPlayers=b;
|
||||
FOREACH_PlayerNumber( pn )
|
||||
m_vEnabledForPlayers.insert( pn );
|
||||
|
||||
#define PUSH( c ) if(c) m_vsChoices.push_back(c);
|
||||
PUSH(c0);PUSH(c1);PUSH(c2);PUSH(c3);PUSH(c4);PUSH(c5);PUSH(c6);PUSH(c7);PUSH(c8);PUSH(c9);PUSH(c10);PUSH(c11);PUSH(c12);PUSH(c13);PUSH(c14);PUSH(c15);PUSH(c16);PUSH(c17);PUSH(c18);PUSH(c19);
|
||||
PUSH(c0);PUSH(c1);PUSH(c2);PUSH(c3);PUSH(c4);PUSH(c5);
|
||||
PUSH(c6);PUSH(c7);PUSH(c8);PUSH(c9);PUSH(c10);PUSH(c11);
|
||||
PUSH(c12);PUSH(c13);PUSH(c14);PUSH(c15);PUSH(c16);PUSH(c17);
|
||||
PUSH(c18);PUSH(c19);
|
||||
#undef PUSH
|
||||
}
|
||||
};
|
||||
@@ -124,7 +143,7 @@ public:
|
||||
OptionRowDefinition m_Def;
|
||||
vector<RString> m_vsReloadRowMessages; // refresh this row on on these messages
|
||||
|
||||
OptionRowHandler() { Init(); }
|
||||
OptionRowHandler(): m_Def(), m_vsReloadRowMessages() { }
|
||||
virtual ~OptionRowHandler() { }
|
||||
virtual void Init()
|
||||
{
|
||||
|
||||
@@ -51,6 +51,7 @@ static const Content_t g_Contents[NUM_PaneCategory] =
|
||||
{ NEED_NOTES, "count" }, // Mines
|
||||
{ NEED_NOTES, "count" }, // Hands
|
||||
{ NEED_NOTES, "count" }, // Lifts
|
||||
{ NEED_NOTES, "count" }, // Fakes
|
||||
{ NEED_NOTES, "score" }, // MachineHighScore
|
||||
{ NEED_NOTES, "name" }, // MachineHighName
|
||||
{ NEED_NOTES|NEED_PROFILE, "score" }, // ProfileHighScore
|
||||
@@ -247,6 +248,7 @@ void PaneDisplay::SetContent( PaneCategory c )
|
||||
case PaneCategory_Mines:
|
||||
case PaneCategory_Hands:
|
||||
case PaneCategory_Lifts:
|
||||
case PaneCategory_Fakes:
|
||||
str = ssprintf( COUNT_FORMAT.GetValue(), val );
|
||||
}
|
||||
}
|
||||
|
||||
+69
-52
@@ -1291,6 +1291,8 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vector<TrackRowTap
|
||||
}
|
||||
}
|
||||
|
||||
float fLifeFraction = fLife / MAX_HOLD_LIFE;
|
||||
|
||||
FOREACH( TrackRowTapNote, vTN, trtn )
|
||||
{
|
||||
TapNote &tn = *trtn->pTN;
|
||||
@@ -1303,15 +1305,11 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vector<TrackRowTap
|
||||
{
|
||||
if( tn.subType == TapNote::hold_head_roll )
|
||||
{
|
||||
m_vKeysounds[tn.iKeysoundIndex].SetProperty ("Volume", max(0.0, min(1.0, fLife * 2.0)));
|
||||
m_vKeysounds[tn.iKeysoundIndex].SetProperty ("Volume", max(0.0, min(1.0, fLifeFraction * 2.0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_vKeysounds[tn.iKeysoundIndex].SetProperty ("Volume", max(0.0, min(1.0, fLife * 10.0 - 8.5)));
|
||||
}
|
||||
if (tn.HoldResult.fLife == 0)
|
||||
{
|
||||
m_vKeysounds[tn.iKeysoundIndex].StopPlaying();
|
||||
m_vKeysounds[tn.iKeysoundIndex].SetProperty ("Volume", max(0.0, min(1.0, fLifeFraction * 10.0 - 8.5)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1520,6 +1518,8 @@ int Player::GetClosestNoteDirectional( int col, int iStartRow, int iEndRow, bool
|
||||
// Is this the row we want?
|
||||
do {
|
||||
const TapNote &tn = begin->second;
|
||||
if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow( begin->first ) )
|
||||
break;
|
||||
if( tn.type == TapNote::empty )
|
||||
break;
|
||||
if( !bAllowGraded && tn.result.tns != TNS_None )
|
||||
@@ -1569,6 +1569,11 @@ int Player::GetClosestNonEmptyRowDirectional( int iStartRow, int iEndRow, bool b
|
||||
++iter;
|
||||
continue;
|
||||
}
|
||||
if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow( iter.Row() ) )
|
||||
{
|
||||
++iter;
|
||||
continue;
|
||||
}
|
||||
return iter.Row();
|
||||
}
|
||||
}
|
||||
@@ -1806,6 +1811,35 @@ void Player::ScoreAllActiveHoldsLetGo()
|
||||
}
|
||||
}
|
||||
|
||||
void Player::PlayKeysound( const TapNote &tn, TapNoteScore score )
|
||||
{
|
||||
// tap note must have keysound
|
||||
if( tn.iKeysoundIndex >= 0 && tn.iKeysoundIndex < (int) m_vKeysounds.size() )
|
||||
{
|
||||
// handle a case for hold notes
|
||||
if( tn.type == TapNote::hold_head )
|
||||
{
|
||||
// if the hold is not already held
|
||||
if( tn.HoldResult.hns == HNS_None )
|
||||
{
|
||||
// if the hold is already activated
|
||||
TapNoteScore tns = tn.result.tns;
|
||||
if( tns != TNS_None && tns != TNS_Miss && score == TNS_None )
|
||||
{
|
||||
// the sound must also be already playing
|
||||
if( m_vKeysounds[tn.iKeysoundIndex].IsPlaying() )
|
||||
{
|
||||
// if all of these conditions are met, don't play the sound.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_vKeysounds[tn.iKeysoundIndex].Play();
|
||||
m_vKeysounds[tn.iKeysoundIndex].SetProperty ("Volume", 1);
|
||||
}
|
||||
}
|
||||
|
||||
void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, bool bRelease, Player::ButtonType pbt )
|
||||
{
|
||||
if( IsOniDead() )
|
||||
@@ -1966,7 +2000,10 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b
|
||||
* Either option would fundamentally change the grading of two quick notes
|
||||
* "jack hammers." Hmm.
|
||||
*/
|
||||
const int iStepSearchRows = BeatToNoteRow( StepSearchDistance * GAMESTATE->m_fCurBPS * GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate );
|
||||
const int iStepSearchRows = max(
|
||||
BeatToNoteRow( GAMESTATE->m_pCurSong->m_Timing.GetBeatFromElapsedTime( GAMESTATE->m_fMusicSeconds + StepSearchDistance ) ) - iSongRow,
|
||||
iSongRow - BeatToNoteRow( GAMESTATE->m_pCurSong->m_Timing.GetBeatFromElapsedTime( GAMESTATE->m_fMusicSeconds - StepSearchDistance ) )
|
||||
) + ROWS_PER_BEAT;
|
||||
int iRowOfOverlappingNoteOrRow = row;
|
||||
if( row == -1 )
|
||||
{
|
||||
@@ -2040,7 +2077,9 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b
|
||||
{
|
||||
case TapNote::mine:
|
||||
// Stepped too close to mine?
|
||||
if( !bRelease && ( REQUIRE_STEP_ON_MINES == !bHeld ) && fSecondsFromExact <= GetWindowSeconds(TW_Mine) )
|
||||
if( !bRelease && ( REQUIRE_STEP_ON_MINES == !bHeld ) &&
|
||||
fSecondsFromExact <= GetWindowSeconds(TW_Mine) &&
|
||||
!GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow(iSongRow) )
|
||||
score = TNS_HitMine;
|
||||
break;
|
||||
|
||||
@@ -2449,37 +2488,23 @@ done_checking_hopo:
|
||||
}
|
||||
if( iRowOfOverlappingNoteOrRow != -1 )
|
||||
{
|
||||
bool bShouldPlayNextKeysound = true;
|
||||
|
||||
if( bShouldPlayNextKeysound )
|
||||
switch( pbt )
|
||||
{
|
||||
|
||||
switch( pbt )
|
||||
DEFAULT_FAIL(pbt);
|
||||
case ButtonType_StrumFretsChanged:
|
||||
for( int i=0; i<m_NoteData.GetNumTracks(); i++ )
|
||||
{
|
||||
DEFAULT_FAIL(pbt);
|
||||
case ButtonType_StrumFretsChanged:
|
||||
for( int i=0; i<m_NoteData.GetNumTracks(); i++ )
|
||||
{
|
||||
const TapNote &tn = m_NoteData.GetTapNote( i, iRowOfOverlappingNoteOrRow );
|
||||
if( tn.iKeysoundIndex >= 0 && tn.iKeysoundIndex < (int) m_vKeysounds.size() && (tn.type != TapNote::hold_head || (!tn.HoldResult.bActive || (tn.HoldResult.fOverlappedTime == 0 || (tn.HoldResult.hns == HNS_Held)))) )
|
||||
{
|
||||
m_vKeysounds[tn.iKeysoundIndex].Play();
|
||||
m_vKeysounds[tn.iKeysoundIndex].SetProperty ("Volume", 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ButtonType_Step:
|
||||
case ButtonType_Hopo:
|
||||
const TapNote &tn = m_NoteData.GetTapNote( col, iRowOfOverlappingNoteOrRow );
|
||||
if( tn.iKeysoundIndex >= 0 && tn.iKeysoundIndex < (int) m_vKeysounds.size() && (tn.type != TapNote::hold_head || (!tn.HoldResult.bActive || (tn.HoldResult.fOverlappedTime == 0 || (tn.HoldResult.hns == HNS_Held)))) )
|
||||
{
|
||||
m_vKeysounds[tn.iKeysoundIndex].Play();
|
||||
m_vKeysounds[tn.iKeysoundIndex].SetProperty ("Volume", 1);
|
||||
}
|
||||
break;
|
||||
const TapNote &tn = m_NoteData.GetTapNote( i, iRowOfOverlappingNoteOrRow );
|
||||
PlayKeysound( tn, score );
|
||||
}
|
||||
|
||||
break;
|
||||
case ButtonType_Step:
|
||||
case ButtonType_Hopo:
|
||||
const TapNote &tn = m_NoteData.GetTapNote( col, iRowOfOverlappingNoteOrRow );
|
||||
PlayKeysound( tn, score );
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// XXX:
|
||||
@@ -2522,8 +2547,8 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds )
|
||||
{
|
||||
//LOG->Trace( "Steps::UpdateTapNotesMissedOlderThan(%f)", fMissIfOlderThanThisBeat );
|
||||
int iMissIfOlderThanThisRow;
|
||||
const float fEarliestTime = GAMESTATE->m_fMusicSeconds - fMissIfOlderThanSeconds;
|
||||
{
|
||||
const float fEarliestTime = GAMESTATE->m_fMusicSeconds - fMissIfOlderThanSeconds;
|
||||
bool bFreeze, bDelay;
|
||||
float fMissIfOlderThanThisBeat;
|
||||
float fThrowAway;
|
||||
@@ -2551,8 +2576,8 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds )
|
||||
if( !NeedsTapJudging(tn) )
|
||||
continue;
|
||||
|
||||
// warp hackery
|
||||
if( iter.Row() >= GAMESTATE->m_iWarpBeginRow && iter.Row() <= (GAMESTATE->m_iWarpBeginRow + BeatToNoteRow(GAMESTATE->m_fWarpLength)) )
|
||||
// Ignore all notes that are skipped via WARPS.
|
||||
if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow( iter.Row() ) )
|
||||
continue;
|
||||
|
||||
if( tn.type == TapNote::mine )
|
||||
@@ -2568,11 +2593,6 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds )
|
||||
}
|
||||
else
|
||||
{
|
||||
// warp hackery: don't score notes within the warp region.
|
||||
// (Only useful when QuirksMode is enabled.) -aj
|
||||
if( iter.Row() >= GAMESTATE->m_iWarpBeginRow && iter.Row() <= (GAMESTATE->m_iWarpBeginRow + BeatToNoteRow(GAMESTATE->m_fWarpLength)) )
|
||||
continue;
|
||||
|
||||
tn.result.tns = TNS_Miss;
|
||||
}
|
||||
}
|
||||
@@ -2591,9 +2611,8 @@ void Player::UpdateJudgedRows()
|
||||
{
|
||||
int iRow = iter.Row();
|
||||
|
||||
// if row is within a warp section, ignore it. -aj
|
||||
if( iRow >= GAMESTATE->m_iWarpBeginRow &&
|
||||
iRow <= (GAMESTATE->m_iWarpBeginRow + BeatToNoteRow(GAMESTATE->m_fWarpLength)) )
|
||||
// If row is within a warp section, ignore it. -aj
|
||||
if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow(iRow) )
|
||||
continue;
|
||||
|
||||
if( iLastSeenRow != iRow )
|
||||
@@ -2927,9 +2946,8 @@ void Player::HandleTapRowScore( unsigned row )
|
||||
bNoCheating = false;
|
||||
#endif
|
||||
|
||||
// more warp hackery. -aj
|
||||
if( row >= (unsigned)GAMESTATE->m_iWarpBeginRow &&
|
||||
row <= (unsigned)(GAMESTATE->m_iWarpBeginRow + BeatToNoteRow(GAMESTATE->m_fWarpLength)) )
|
||||
// Warp hackery. -aj
|
||||
if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow( row ) )
|
||||
return;
|
||||
|
||||
if( GAMESTATE->m_bDemonstrationOrJukebox )
|
||||
@@ -3032,9 +3050,8 @@ void Player::HandleHoldCheckpoint( int iRow, int iNumHoldsHeldThisRow, int iNumH
|
||||
bNoCheating = false;
|
||||
#endif
|
||||
|
||||
// more warp hackery. -aj
|
||||
if( iRow >= GAMESTATE->m_iWarpBeginRow &&
|
||||
iRow <= (GAMESTATE->m_iWarpBeginRow + BeatToNoteRow(GAMESTATE->m_fWarpLength)) )
|
||||
// More warp hackery. -aj
|
||||
if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow( iRow ) )
|
||||
return;
|
||||
|
||||
// don't accumulate combo if AutoPlay is on.
|
||||
|
||||
@@ -117,6 +117,7 @@ protected:
|
||||
void DrawTapJudgments();
|
||||
void DrawHoldJudgments();
|
||||
void SendComboMessages( int iOldCombo, int iOldMissCombo );
|
||||
void PlayKeysound( const TapNote &tn, TapNoteScore score );
|
||||
|
||||
void SetJudgment( TapNoteScore tns, int iFirstTrack, float fTapNoteOffset ); // -1 if no track as in TNS_Miss
|
||||
void SetHoldJudgment( TapNoteScore tns, HoldNoteScore hns, int iTrack );
|
||||
|
||||
+217
-1
@@ -840,11 +840,227 @@ void PlayerOptions::ResetPrefs( ResetPrefsType type )
|
||||
class LunaPlayerOptions: public Luna<PlayerOptions>
|
||||
{
|
||||
public:
|
||||
DEFINE_METHOD( GetNoteSkin, m_sNoteSkin )
|
||||
// NoteSkins
|
||||
static int GetNoteSkin( T *p, lua_State *L )
|
||||
{
|
||||
if( p->m_sNoteSkin.empty() )
|
||||
lua_pushstring( L, CommonMetrics::DEFAULT_NOTESKIN_NAME.GetValue() );
|
||||
else
|
||||
lua_pushstring( L, p->m_sNoteSkin );
|
||||
return 1;
|
||||
}
|
||||
static int SetNoteSkin( T *p, lua_State *L )
|
||||
{
|
||||
if( NOTESKIN->DoesNoteSkinExist(SArg(1)) )
|
||||
p->m_sNoteSkin = SArg(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Speed Mods
|
||||
static int GetCMod( T *p, lua_State *L )
|
||||
{
|
||||
if( p->m_fTimeSpacing )
|
||||
lua_pushnumber( L, p->m_fTimeSpacing );
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
static int GetXMod( T *p, lua_State *L )
|
||||
{
|
||||
if( !p->m_fTimeSpacing )
|
||||
lua_pushnumber( L, p->m_fScrollSpeed );
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Accel
|
||||
DEFINE_METHOD( GetBoost, m_fAccels[PlayerOptions::ACCEL_BOOST] )
|
||||
DEFINE_METHOD( GetBrake, m_fAccels[PlayerOptions::ACCEL_BRAKE] )
|
||||
DEFINE_METHOD( GetWave, m_fAccels[PlayerOptions::ACCEL_WAVE] )
|
||||
DEFINE_METHOD( GetExpand, m_fAccels[PlayerOptions::ACCEL_EXPAND] )
|
||||
DEFINE_METHOD( GetBoomerang, m_fAccels[PlayerOptions::ACCEL_BOOMERANG] )
|
||||
|
||||
// Effect
|
||||
DEFINE_METHOD( GetDrunk, m_fEffects[PlayerOptions::EFFECT_DRUNK] ) // MoonGyuHyuk
|
||||
DEFINE_METHOD( GetDizzy, m_fEffects[PlayerOptions::EFFECT_DIZZY] )
|
||||
DEFINE_METHOD( GetConfusion, m_fEffects[PlayerOptions::EFFECT_CONFUSION] )
|
||||
DEFINE_METHOD( GetMini, m_fEffects[PlayerOptions::EFFECT_MINI] )
|
||||
DEFINE_METHOD( GetTiny, m_fEffects[PlayerOptions::EFFECT_TINY] )
|
||||
DEFINE_METHOD( GetFlip, m_fEffects[PlayerOptions::EFFECT_FLIP] )
|
||||
DEFINE_METHOD( GetInvert, m_fEffects[PlayerOptions::EFFECT_INVERT] )
|
||||
DEFINE_METHOD( GetTornado, m_fEffects[PlayerOptions::EFFECT_TORNADO] )
|
||||
DEFINE_METHOD( GetTipsy, m_fEffects[PlayerOptions::EFFECT_TIPSY] )
|
||||
DEFINE_METHOD( GetBumpy, m_fEffects[PlayerOptions::EFFECT_BUMPY] )
|
||||
DEFINE_METHOD( GetBeat, m_fEffects[PlayerOptions::EFFECT_BEAT] )
|
||||
DEFINE_METHOD( GetXMode, m_fEffects[PlayerOptions::EFFECT_XMODE] )
|
||||
DEFINE_METHOD( GetTwirl, m_fEffects[PlayerOptions::EFFECT_TWIRL] )
|
||||
DEFINE_METHOD( GetRoll, m_fEffects[PlayerOptions::EFFECT_ROLL] )
|
||||
|
||||
// Appearance
|
||||
DEFINE_METHOD( GetHidden, m_fAppearances[PlayerOptions::APPEARANCE_HIDDEN] )
|
||||
DEFINE_METHOD( GetHiddenOffset, m_fAppearances[PlayerOptions::APPEARANCE_HIDDEN_OFFSET] )
|
||||
DEFINE_METHOD( GetSudden, m_fAppearances[PlayerOptions::APPEARANCE_SUDDEN] )
|
||||
DEFINE_METHOD( GetSuddenOffset, m_fAppearances[PlayerOptions::APPEARANCE_SUDDEN_OFFSET] )
|
||||
DEFINE_METHOD( GetStealth, m_fAppearances[PlayerOptions::APPEARANCE_STEALTH] )
|
||||
DEFINE_METHOD( GetBlink, m_fAppearances[PlayerOptions::APPEARANCE_BLINK] )
|
||||
DEFINE_METHOD( GetRandomVanish, m_fAppearances[PlayerOptions::APPEARANCE_RANDOMVANISH] )
|
||||
|
||||
// Scroll
|
||||
DEFINE_METHOD( GetReverse, m_fScrolls[PlayerOptions::SCROLL_REVERSE] )
|
||||
DEFINE_METHOD( UsingReverse, m_fScrolls[PlayerOptions::SCROLL_REVERSE] == 1 )
|
||||
static int GetReversePercentForColumn( T *p, lua_State *L )
|
||||
{
|
||||
// todo: make sure IArg is within boundaries -aj
|
||||
lua_pushnumber( L, p->GetReversePercentForColumn(IArg(1)) );
|
||||
return 1;
|
||||
}
|
||||
DEFINE_METHOD( GetSplit, m_fScrolls[PlayerOptions::SCROLL_SPLIT] )
|
||||
DEFINE_METHOD( GetAlternate, m_fScrolls[PlayerOptions::SCROLL_ALTERNATE] )
|
||||
DEFINE_METHOD( GetCross, m_fScrolls[PlayerOptions::SCROLL_CROSS] )
|
||||
DEFINE_METHOD( GetCentered, m_fScrolls[PlayerOptions::SCROLL_CENTERED] )
|
||||
|
||||
// Turns
|
||||
DEFINE_METHOD( GetMirror, m_bTurns[PlayerOptions::TURN_MIRROR] )
|
||||
DEFINE_METHOD( GetLeft, m_bTurns[PlayerOptions::TURN_LEFT] )
|
||||
DEFINE_METHOD( GetRight, m_bTurns[PlayerOptions::TURN_RIGHT] )
|
||||
DEFINE_METHOD( GetShuffle, m_bTurns[PlayerOptions::TURN_SHUFFLE] )
|
||||
DEFINE_METHOD( GetSoftShuffle, m_bTurns[PlayerOptions::TURN_SOFT_SHUFFLE] )
|
||||
DEFINE_METHOD( GetSuperShuffle, m_bTurns[PlayerOptions::TURN_SUPER_SHUFFLE] )
|
||||
|
||||
// Transform
|
||||
DEFINE_METHOD( GetNoHolds, m_bTransforms[PlayerOptions::TRANSFORM_NOHOLDS] )
|
||||
DEFINE_METHOD( GetNoRolls, m_bTransforms[PlayerOptions::TRANSFORM_NOROLLS] )
|
||||
DEFINE_METHOD( GetNoMines, m_bTransforms[PlayerOptions::TRANSFORM_NOMINES] )
|
||||
DEFINE_METHOD( GetLittle, m_bTransforms[PlayerOptions::TRANSFORM_LITTLE] )
|
||||
DEFINE_METHOD( GetWide, m_bTransforms[PlayerOptions::TRANSFORM_WIDE] )
|
||||
DEFINE_METHOD( GetBig, m_bTransforms[PlayerOptions::TRANSFORM_BIG] )
|
||||
DEFINE_METHOD( GetQuick, m_bTransforms[PlayerOptions::TRANSFORM_QUICK] )
|
||||
DEFINE_METHOD( GetBMRize, m_bTransforms[PlayerOptions::TRANSFORM_BMRIZE] )
|
||||
DEFINE_METHOD( GetSkippy, m_bTransforms[PlayerOptions::TRANSFORM_SKIPPY] )
|
||||
DEFINE_METHOD( GetMines, m_bTransforms[PlayerOptions::TRANSFORM_MINES] )
|
||||
DEFINE_METHOD( GetAttackMines, m_bTransforms[PlayerOptions::TRANSFORM_ATTACKMINES] )
|
||||
DEFINE_METHOD( GetEcho, m_bTransforms[PlayerOptions::TRANSFORM_ECHO] )
|
||||
DEFINE_METHOD( GetStomp, m_bTransforms[PlayerOptions::TRANSFORM_STOMP] )
|
||||
DEFINE_METHOD( GetPlanted, m_bTransforms[PlayerOptions::TRANSFORM_PLANTED] )
|
||||
DEFINE_METHOD( GetFloored, m_bTransforms[PlayerOptions::TRANSFORM_FLOORED] )
|
||||
DEFINE_METHOD( GetTwister, m_bTransforms[PlayerOptions::TRANSFORM_TWISTER] )
|
||||
DEFINE_METHOD( GetHoldRolls, m_bTransforms[PlayerOptions::TRANSFORM_HOLDROLLS] )
|
||||
DEFINE_METHOD( GetNoJumps, m_bTransforms[PlayerOptions::TRANSFORM_NOJUMPS] )
|
||||
DEFINE_METHOD( GetNoHands, m_bTransforms[PlayerOptions::TRANSFORM_NOHANDS] )
|
||||
DEFINE_METHOD( GetNoLifts, m_bTransforms[PlayerOptions::TRANSFORM_NOLIFTS] )
|
||||
DEFINE_METHOD( GetNoFakes, m_bTransforms[PlayerOptions::TRANSFORM_NOFAKES] )
|
||||
DEFINE_METHOD( GetNoQuads, m_bTransforms[PlayerOptions::TRANSFORM_NOQUADS] )
|
||||
DEFINE_METHOD( GetNoStretch, m_bTransforms[PlayerOptions::TRANSFORM_NOSTRETCH] )
|
||||
|
||||
// Others
|
||||
DEFINE_METHOD( GetDark, m_fDark )
|
||||
DEFINE_METHOD( GetBlind, m_fBlind )
|
||||
DEFINE_METHOD( GetCover, m_fCover )
|
||||
DEFINE_METHOD( GetRandomAttacks, m_fRandAttack )
|
||||
DEFINE_METHOD( GetSongAttacks, m_fSongAttack )
|
||||
DEFINE_METHOD( GetSkew, m_fSkew )
|
||||
DEFINE_METHOD( GetPassmark, m_fPassmark )
|
||||
DEFINE_METHOD( GetRandomSpeed, m_fRandomSpeed )
|
||||
|
||||
LunaPlayerOptions()
|
||||
{
|
||||
ADD_METHOD( GetDark );
|
||||
// SetDark
|
||||
ADD_METHOD( GetBlind );
|
||||
// SetBlind
|
||||
ADD_METHOD( GetCover );
|
||||
// SetCover
|
||||
// GetMuteOnError, SetMuteOnError
|
||||
ADD_METHOD( GetNoteSkin );
|
||||
ADD_METHOD( SetNoteSkin );
|
||||
// GetPerspectiveTilt, SetPerspectiveTilt
|
||||
ADD_METHOD( GetPassmark );
|
||||
// SetPassmark
|
||||
ADD_METHOD( GetRandomAttacks );
|
||||
// SetRandomAttacks
|
||||
ADD_METHOD( GetRandomSpeed );
|
||||
// SetRandomSpeed
|
||||
ADD_METHOD( GetSkew );
|
||||
// SetSkew
|
||||
ADD_METHOD( GetSongAttacks );
|
||||
// SetSongAttacks
|
||||
ADD_METHOD( GetCMod );
|
||||
ADD_METHOD( GetXMod );
|
||||
|
||||
// Accel
|
||||
ADD_METHOD( GetBoost );
|
||||
ADD_METHOD( GetBrake );
|
||||
ADD_METHOD( GetWave );
|
||||
ADD_METHOD( GetExpand );
|
||||
ADD_METHOD( GetBoomerang );
|
||||
|
||||
// Effect
|
||||
ADD_METHOD( GetDrunk );
|
||||
ADD_METHOD( GetDizzy );
|
||||
ADD_METHOD( GetConfusion );
|
||||
ADD_METHOD( GetMini );
|
||||
ADD_METHOD( GetTiny );
|
||||
ADD_METHOD( GetFlip );
|
||||
ADD_METHOD( GetInvert );
|
||||
ADD_METHOD( GetTornado );
|
||||
ADD_METHOD( GetTipsy );
|
||||
ADD_METHOD( GetBumpy );
|
||||
ADD_METHOD( GetBeat );
|
||||
ADD_METHOD( GetXMode );
|
||||
ADD_METHOD( GetTwirl );
|
||||
ADD_METHOD( GetRoll );
|
||||
|
||||
// Appearance
|
||||
ADD_METHOD( GetHidden );
|
||||
ADD_METHOD( GetHiddenOffset );
|
||||
ADD_METHOD( GetSudden );
|
||||
ADD_METHOD( GetSuddenOffset );
|
||||
ADD_METHOD( GetStealth );
|
||||
ADD_METHOD( GetBlink );
|
||||
ADD_METHOD( GetRandomVanish );
|
||||
|
||||
// Scroll
|
||||
ADD_METHOD( GetReverse );
|
||||
ADD_METHOD( UsingReverse );
|
||||
ADD_METHOD( GetReversePercentForColumn );
|
||||
ADD_METHOD( GetSplit );
|
||||
ADD_METHOD( GetAlternate );
|
||||
ADD_METHOD( GetCross );
|
||||
ADD_METHOD( GetCentered );
|
||||
|
||||
// Turns
|
||||
ADD_METHOD( GetMirror );
|
||||
ADD_METHOD( GetLeft );
|
||||
ADD_METHOD( GetRight );
|
||||
ADD_METHOD( GetShuffle );
|
||||
ADD_METHOD( GetSoftShuffle );
|
||||
ADD_METHOD( GetSuperShuffle );
|
||||
|
||||
// Transform
|
||||
ADD_METHOD( GetNoHolds );
|
||||
ADD_METHOD( GetNoRolls );
|
||||
ADD_METHOD( GetNoMines );
|
||||
ADD_METHOD( GetLittle );
|
||||
ADD_METHOD( GetWide );
|
||||
ADD_METHOD( GetBig );
|
||||
ADD_METHOD( GetQuick );
|
||||
ADD_METHOD( GetBMRize );
|
||||
ADD_METHOD( GetSkippy );
|
||||
ADD_METHOD( GetMines );
|
||||
ADD_METHOD( GetAttackMines );
|
||||
ADD_METHOD( GetEcho );
|
||||
ADD_METHOD( GetStomp );
|
||||
ADD_METHOD( GetPlanted );
|
||||
ADD_METHOD( GetFloored );
|
||||
ADD_METHOD( GetTwister );
|
||||
ADD_METHOD( GetHoldRolls );
|
||||
ADD_METHOD( GetNoJumps );
|
||||
ADD_METHOD( GetNoHands );
|
||||
ADD_METHOD( GetNoLifts );
|
||||
ADD_METHOD( GetNoFakes );
|
||||
ADD_METHOD( GetNoQuads );
|
||||
ADD_METHOD( GetNoStretch );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+4
-4
@@ -162,9 +162,9 @@ public:
|
||||
/* All floats have a corresponding speed setting, which determines how fast
|
||||
* PlayerOptions::Approach approaches. */
|
||||
bool m_bSetScrollSpeed; // true if the scroll speed was set by FromString
|
||||
float m_fTimeSpacing, m_SpeedfTimeSpacing; // instead of Beat spacing
|
||||
float m_fScrollSpeed, m_SpeedfScrollSpeed; // used if !m_bTimeSpacing
|
||||
float m_fScrollBPM, m_SpeedfScrollBPM; // used if m_bTimeSpacing
|
||||
float m_fTimeSpacing, m_SpeedfTimeSpacing; // instead of Beat spacing (CMods, mMods)
|
||||
float m_fScrollSpeed, m_SpeedfScrollSpeed; // used if !m_bTimeSpacing (xMods)
|
||||
float m_fScrollBPM, m_SpeedfScrollBPM; // used if m_bTimeSpacing (CMod)
|
||||
float m_fAccels[NUM_ACCELS], m_SpeedfAccels[NUM_ACCELS];
|
||||
float m_fEffects[NUM_EFFECTS], m_SpeedfEffects[NUM_EFFECTS];
|
||||
float m_fAppearances[NUM_APPEARANCES],m_SpeedfAppearances[NUM_APPEARANCES];
|
||||
@@ -189,7 +189,7 @@ public:
|
||||
bool m_bTransforms[NUM_TRANSFORMS];
|
||||
bool m_bMuteOnError;
|
||||
/** @brief How can the Player fail a song? */
|
||||
enum FailType {
|
||||
enum FailType {
|
||||
FAIL_IMMEDIATE=0, /**< fail immediately when life touches 0 */
|
||||
FAIL_IMMEDIATE_CONTINUE, /**< Same as above, but allow playing the rest of the song */
|
||||
FAIL_AT_END, /**< fail if life is at 0 when the song ends */
|
||||
|
||||
@@ -229,6 +229,12 @@ public:
|
||||
LuaHelpers::Push( L, s );
|
||||
return 1;
|
||||
}
|
||||
static int GetCurrentPlayerOptions( T* p, lua_State *L )
|
||||
{
|
||||
PlayerOptions po = p->m_PlayerOptions.GetCurrent();
|
||||
po.PushSelf(L);
|
||||
return 1;
|
||||
}
|
||||
DEFINE_METHOD( GetHealthState, m_HealthState );
|
||||
|
||||
LunaPlayerState()
|
||||
@@ -239,6 +245,7 @@ public:
|
||||
ADD_METHOD( GetPlayerOptions );
|
||||
ADD_METHOD( GetPlayerOptionsArray );
|
||||
ADD_METHOD( GetPlayerOptionsString );
|
||||
ADD_METHOD( GetCurrentPlayerOptions );
|
||||
ADD_METHOD( GetHealthState );
|
||||
}
|
||||
};
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@
|
||||
* </li></ul>
|
||||
*/
|
||||
#ifndef PRODUCT_VER_BARE
|
||||
#define PRODUCT_VER_BARE v1.2.3
|
||||
#define PRODUCT_VER_BARE v1.2.5
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
|
||||
; see ProductInfo.h for use descriptions
|
||||
!define PRODUCT_ID "sm-ssc"
|
||||
!define PRODUCT_VER "v1.2.3"
|
||||
!define PRODUCT_VER "v1.2.5"
|
||||
!define PRODUCT_DISPLAY "${PRODUCT_ID} ${PRODUCT_VER}"
|
||||
!define PRODUCT_BITMAP "ssc"
|
||||
|
||||
|
||||
+50
-3
@@ -67,9 +67,50 @@ class Game;
|
||||
class Profile
|
||||
{
|
||||
public:
|
||||
Profile()
|
||||
/**
|
||||
* @brief Set up the Profile with default values.
|
||||
*
|
||||
* Note: there are probably a lot of variables. */
|
||||
Profile(): m_sDisplayName(""), m_sCharacterID(""),
|
||||
m_sLastUsedHighScoreName(""), m_iWeightPounds(0),
|
||||
m_sGuid(MakeGuid()), m_sDefaultModifiers(),
|
||||
m_SortOrder(SortOrder_Invalid),
|
||||
m_LastDifficulty(Difficulty_Invalid),
|
||||
m_LastCourseDifficulty(Difficulty_Invalid),
|
||||
m_LastStepsType(StepsType_Invalid), m_lastSong(),
|
||||
m_lastCourse(), m_iTotalSessions(0),
|
||||
m_iTotalSessionSeconds(0), m_iTotalGameplaySeconds(0),
|
||||
m_fTotalCaloriesBurned(0), m_GoalType(GoalType_Calories),
|
||||
m_iGoalCalories(0), m_iGoalSeconds(0), m_iTotalDancePoints(0),
|
||||
m_iNumExtraStagesPassed(0), m_iNumExtraStagesFailed(0),
|
||||
m_iNumToasties(0), m_iTotalTapsAndHolds(0), m_iTotalJumps(0),
|
||||
m_iTotalHolds(0), m_iTotalRolls(0), m_iTotalMines(0),
|
||||
m_iTotalHands(0), m_iTotalLifts(0), m_bNewProfile(false),
|
||||
m_UnlockedEntryIDs(), m_sLastPlayedMachineGuid(""),
|
||||
m_LastPlayedDate(),m_iNumSongsPlayedByStyle(),
|
||||
m_iNumTotalSongsPlayed(0), m_UserData(), m_SongHighScores(),
|
||||
m_CourseHighScores(), m_vScreenshots(),
|
||||
m_mapDayToCaloriesBurned()
|
||||
{
|
||||
InitAll();
|
||||
m_lastSong.Unset();
|
||||
m_lastCourse.Unset();
|
||||
|
||||
m_LastPlayedDate.Init();
|
||||
|
||||
FOREACH_ENUM( PlayMode, i )
|
||||
m_iNumSongsPlayedByPlayMode[i] = 0;
|
||||
FOREACH_ENUM( Difficulty, i )
|
||||
m_iNumSongsPlayedByDifficulty[i] = 0;
|
||||
for( int i=0; i<MAX_METER+1; i++ )
|
||||
m_iNumSongsPlayedByMeter[i] = 0;
|
||||
|
||||
ZERO( m_iNumStagesPassedByPlayMode );
|
||||
ZERO( m_iNumStagesPassedByGrade );
|
||||
m_UserData.Unset();
|
||||
|
||||
FOREACH_ENUM( StepsType,st )
|
||||
FOREACH_ENUM( RankingCategory,rc )
|
||||
m_CategoryHighScores[st][rc].Init();
|
||||
}
|
||||
|
||||
// smart accessors
|
||||
@@ -142,6 +183,8 @@ public:
|
||||
int m_iTotalMines;
|
||||
int m_iTotalHands;
|
||||
int m_iTotalLifts;
|
||||
/** @brief Is this a brand new profile? */
|
||||
bool m_bNewProfile;
|
||||
set<RString> m_UnlockedEntryIDs;
|
||||
/**
|
||||
* @brief Which machine did we play on last, based on the Guid?
|
||||
@@ -170,11 +213,13 @@ public:
|
||||
struct HighScoresForASteps
|
||||
{
|
||||
HighScoreList hsl;
|
||||
HighScoresForASteps(): hsl() {}
|
||||
};
|
||||
struct HighScoresForASong
|
||||
{
|
||||
std::map<StepsID,HighScoresForASteps> m_StepsHighScores;
|
||||
int GetNumTimesPlayed() const;
|
||||
HighScoresForASong(): m_StepsHighScores() {}
|
||||
};
|
||||
std::map<SongID,HighScoresForASong> m_SongHighScores;
|
||||
|
||||
@@ -196,11 +241,13 @@ public:
|
||||
struct HighScoresForATrail
|
||||
{
|
||||
HighScoreList hsl;
|
||||
HighScoresForATrail(): hsl() {}
|
||||
};
|
||||
struct HighScoresForACourse
|
||||
{
|
||||
std::map<TrailID,HighScoresForATrail> m_TrailHighScores;
|
||||
int GetNumTimesPlayed() const;
|
||||
HighScoresForACourse(): m_TrailHighScores() {}
|
||||
};
|
||||
std::map<CourseID,HighScoresForACourse> m_CourseHighScores;
|
||||
|
||||
@@ -240,7 +287,7 @@ public:
|
||||
* insert some garbage entries into the map. */
|
||||
struct Calories
|
||||
{
|
||||
Calories() { fCals = 0; }
|
||||
Calories(): fCals(0) {}
|
||||
float fCals;
|
||||
};
|
||||
map<DateTime,Calories> m_mapDayToCaloriesBurned;
|
||||
|
||||
+12
-1
@@ -97,6 +97,7 @@ void ProfileManager::Init()
|
||||
m_bLastLoadWasTamperedOrCorrupt[p] = false;
|
||||
m_bLastLoadWasFromLastGood[p] = false;
|
||||
m_bNeedToBackUpLastLoad[p] = false;
|
||||
m_bNewProfile[p] = false;
|
||||
}
|
||||
|
||||
LoadMachineProfile();
|
||||
@@ -222,6 +223,7 @@ bool ProfileManager::LoadProfileFromMemoryCard( PlayerNumber pn, bool bLoadEdits
|
||||
|
||||
vector<RString> asDirsToTry;
|
||||
GetMemoryCardProfileDirectoriesToTry( asDirsToTry );
|
||||
m_bNewProfile[pn] = true;
|
||||
|
||||
for( unsigned i = 0; i < asDirsToTry.size(); ++i )
|
||||
{
|
||||
@@ -239,6 +241,7 @@ bool ProfileManager::LoadProfileFromMemoryCard( PlayerNumber pn, bool bLoadEdits
|
||||
ProfileLoadResult res = LoadProfile( pn, sDir, true );
|
||||
if( res == ProfileLoadResult_Success )
|
||||
{
|
||||
m_bNewProfile[pn] = false;
|
||||
/* If importing, store the directory we imported from, for display purposes. */
|
||||
if( i > 0 )
|
||||
m_sProfileDirImportedFrom[pn] = asDirsToTry[i];
|
||||
@@ -246,7 +249,10 @@ bool ProfileManager::LoadProfileFromMemoryCard( PlayerNumber pn, bool bLoadEdits
|
||||
}
|
||||
|
||||
if( res == ProfileLoadResult_FailedTampered )
|
||||
{
|
||||
m_bNewProfile[pn] = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we imported a profile fallback directory, change the memory card
|
||||
@@ -544,6 +550,11 @@ bool ProfileManager::ProfileWasLoadedFromMemoryCard( PlayerNumber pn ) const
|
||||
return !m_sProfileDir[pn].empty() && m_bWasLoadedFromMemoryCard[pn];
|
||||
}
|
||||
|
||||
bool ProfileManager::ProfileFromMemoryCardIsNew( PlayerNumber pn ) const
|
||||
{
|
||||
return GetProfile(pn) && m_bWasLoadedFromMemoryCard[pn] && m_bNewProfile[pn];
|
||||
}
|
||||
|
||||
bool ProfileManager::LastLoadWasTamperedOrCorrupt( PlayerNumber pn ) const
|
||||
{
|
||||
return !m_sProfileDir[pn].empty() && m_bLastLoadWasTamperedOrCorrupt[pn];
|
||||
@@ -813,7 +824,7 @@ public:
|
||||
if( pProfile )
|
||||
pProfile->PushSelf(L);
|
||||
else
|
||||
lua_pushnil(L );
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
static int GetLocalProfileFromIndex( T* p, lua_State *L ) { Profile *pProfile = p->GetLocalProfileFromIndex(IArg(1)); ASSERT(pProfile); pProfile->PushSelf(L); return 1; }
|
||||
|
||||
@@ -77,6 +77,7 @@ public:
|
||||
|
||||
RString GetPlayerName( PlayerNumber pn ) const;
|
||||
bool ProfileWasLoadedFromMemoryCard( PlayerNumber pn ) const;
|
||||
bool ProfileFromMemoryCardIsNew( PlayerNumber pn ) const;
|
||||
bool LastLoadWasTamperedOrCorrupt( PlayerNumber pn ) const;
|
||||
bool LastLoadWasFromLastGood( PlayerNumber pn ) const;
|
||||
|
||||
@@ -117,6 +118,7 @@ private:
|
||||
bool m_bLastLoadWasTamperedOrCorrupt[NUM_PLAYERS]; // true if Stats.xml was present, but failed to load (probably because of a signature failure)
|
||||
bool m_bLastLoadWasFromLastGood[NUM_PLAYERS]; // if true, then m_bLastLoadWasTamperedOrCorrupt is also true
|
||||
mutable bool m_bNeedToBackUpLastLoad[NUM_PLAYERS]; // if true, back up profile on next save
|
||||
bool m_bNewProfile[NUM_PLAYERS];
|
||||
|
||||
Profile *m_pMemoryCardProfile[NUM_PLAYERS]; // holds Profile for the currently inserted card
|
||||
Profile *m_pMachineProfile;
|
||||
|
||||
@@ -31,7 +31,7 @@ static void GetResolutionFromFileName( RString sPath, int &iWidth, int &iHeight
|
||||
}
|
||||
|
||||
RageBitmapTexture::RageBitmapTexture( RageTextureID name ) :
|
||||
RageTexture( name )
|
||||
RageTexture( name ), m_uTexHandle(0)
|
||||
{
|
||||
Create();
|
||||
}
|
||||
|
||||
+1
-1
@@ -264,7 +264,7 @@ class MatrixStack
|
||||
vector<RageMatrix> stack;
|
||||
public:
|
||||
|
||||
MatrixStack()
|
||||
MatrixStack(): stack()
|
||||
{
|
||||
stack.resize(1);
|
||||
LoadIdentity();
|
||||
|
||||
+2
-116
@@ -17,16 +17,11 @@
|
||||
#include <D3dx8math.h>
|
||||
#include <D3DX8Core.h>
|
||||
|
||||
#if !defined(XBOX)
|
||||
#include "archutils/Win32/GraphicsWindow.h"
|
||||
#else
|
||||
#include "archutils/Xbox/GraphicsWindow.h"
|
||||
#include "archutils/Xbox/VirtualMemory.h"
|
||||
#endif
|
||||
|
||||
// Static libraries
|
||||
// load Windows D3D8 dynamically
|
||||
#if defined(_MSC_VER) && !defined(_XBOX)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma comment(lib, "D3dx8.lib")
|
||||
#pragma comment(lib, "Dxerr8.lib")
|
||||
#endif
|
||||
@@ -42,9 +37,7 @@ RString GetErrorString( HRESULT hr )
|
||||
}
|
||||
|
||||
// Globals
|
||||
#if !defined(XBOX)
|
||||
HMODULE g_D3D8_Module = NULL;
|
||||
#endif
|
||||
LPDIRECT3D8 g_pd3d = NULL;
|
||||
LPDIRECT3DDEVICE8 g_pd3dDevice = NULL;
|
||||
D3DCAPS8 g_DeviceCaps;
|
||||
@@ -84,12 +77,8 @@ static void SetPalette( unsigned TexResource )
|
||||
}
|
||||
|
||||
// Load it.
|
||||
#if !defined(XBOX)
|
||||
TexturePalette& pal = g_TexResourceToTexturePalette[TexResource];
|
||||
g_pd3dDevice->SetPaletteEntries( iPalIndex, pal.p );
|
||||
#else
|
||||
ASSERT(0);
|
||||
#endif
|
||||
|
||||
g_TexResourceToPaletteIndex[TexResource] = iPalIndex;
|
||||
}
|
||||
@@ -106,11 +95,7 @@ static void SetPalette( unsigned TexResource )
|
||||
break;
|
||||
}
|
||||
|
||||
#if !defined(XBOX)
|
||||
g_pd3dDevice->SetCurrentTexturePalette( iPalIndex );
|
||||
#else
|
||||
ASSERT(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define D3DFVF_RageSpriteVertex (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE|D3DFVF_TEX1)
|
||||
@@ -178,11 +163,7 @@ static D3DFORMAT D3DFORMATS[NUM_PixelFormat] =
|
||||
D3DFMT_A4R4G4B4,
|
||||
D3DFMT_A1R5G5B5,
|
||||
D3DFMT_X1R5G5B5,
|
||||
#if defined(XBOX)
|
||||
D3DFMT_UNKNOWN, // no RGB
|
||||
#else
|
||||
D3DFMT_R8G8B8,
|
||||
#endif
|
||||
D3DFMT_P8,
|
||||
D3DFMT_UNKNOWN, // no BGR
|
||||
D3DFMT_UNKNOWN, // no ABGR
|
||||
@@ -214,9 +195,7 @@ RString RageDisplay_D3D::Init( const VideoModeParams &p, bool bAllowUnaccelerate
|
||||
|
||||
typedef IDirect3D8 * (WINAPI * Direct3DCreate8_t) (UINT SDKVersion);
|
||||
Direct3DCreate8_t pDirect3DCreate8;
|
||||
#if defined(XBOX)
|
||||
pDirect3DCreate8 = Direct3DCreate8;
|
||||
#else
|
||||
|
||||
g_D3D8_Module = LoadLibrary("D3D8.dll");
|
||||
if(!g_D3D8_Module)
|
||||
return D3D_NOT_INSTALLED.GetValue() + "\n" + D3D_URL;
|
||||
@@ -227,7 +206,6 @@ RString RageDisplay_D3D::Init( const VideoModeParams &p, bool bAllowUnaccelerate
|
||||
LOG->Trace( "Direct3DCreate8 not found" );
|
||||
return D3D_NOT_INSTALLED.GetValue();
|
||||
}
|
||||
#endif
|
||||
|
||||
g_pd3d = pDirect3DCreate8( D3D_SDK_VERSION );
|
||||
if(!g_pd3d)
|
||||
@@ -294,13 +272,11 @@ RageDisplay_D3D::~RageDisplay_D3D()
|
||||
/* Even after we call Release(), D3D may still affect our window. It seems
|
||||
* to subclass the window, and never release it. Free the DLL after
|
||||
* destroying the window. */
|
||||
#if !defined(XBOX)
|
||||
if( g_D3D8_Module )
|
||||
{
|
||||
FreeLibrary( g_D3D8_Module );
|
||||
g_D3D8_Module = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void RageDisplay_D3D::GetDisplayResolutions( DisplayResolutions &out ) const
|
||||
@@ -334,9 +310,7 @@ D3DFORMAT FindBackBufferType(bool bWindowed, int iBPP)
|
||||
}
|
||||
if( iBPP == 32 || bWindowed )
|
||||
{
|
||||
#if !defined(XBOX)
|
||||
vBackBufferFormats.push_back( D3DFMT_R8G8B8 );
|
||||
#endif
|
||||
vBackBufferFormats.push_back( D3DFMT_X8R8G8B8 );
|
||||
vBackBufferFormats.push_back( D3DFMT_A8R8G8B8 );
|
||||
}
|
||||
@@ -383,13 +357,8 @@ RString SetD3DParams( bool &bNewDeviceOut )
|
||||
HRESULT hr = g_pd3d->CreateDevice(
|
||||
D3DADAPTER_DEFAULT,
|
||||
D3DDEVTYPE_HAL,
|
||||
#if !defined(XBOX)
|
||||
GraphicsWindow::GetHwnd(),
|
||||
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED,
|
||||
#else
|
||||
NULL,
|
||||
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
||||
#endif
|
||||
&g_d3dpp,
|
||||
&g_pd3dDevice );
|
||||
if( FAILED(hr) )
|
||||
@@ -506,11 +475,7 @@ static void SetPresentParametersFromVideoModeParams( const VideoModeParams &p, D
|
||||
pD3Dpp->BackBufferCount = 1;
|
||||
pD3Dpp->MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
pD3Dpp->SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
#if !defined(XBOX)
|
||||
pD3Dpp->hDeviceWindow = GraphicsWindow::GetHwnd();
|
||||
#else
|
||||
pD3Dpp->hDeviceWindow = NULL;
|
||||
#endif
|
||||
pD3Dpp->Windowed = p.windowed;
|
||||
pD3Dpp->EnableAutoDepthStencil = TRUE;
|
||||
pD3Dpp->AutoDepthStencilFormat = D3DFMT_D16;
|
||||
@@ -520,25 +485,9 @@ static void SetPresentParametersFromVideoModeParams( const VideoModeParams &p, D
|
||||
else
|
||||
pD3Dpp->FullScreen_PresentationInterval = p.vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
|
||||
#if !defined(XBOX)
|
||||
pD3Dpp->FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
|
||||
if( !p.windowed && p.rate != REFRESH_DEFAULT )
|
||||
pD3Dpp->FullScreen_RefreshRateInHz = p.rate;
|
||||
#else
|
||||
if( XGetVideoStandard() == XC_VIDEO_STANDARD_PAL_I )
|
||||
{
|
||||
// Get supported video flags.
|
||||
DWORD VideoFlags = XGetVideoFlags();
|
||||
|
||||
// Set pal60 if available.
|
||||
if( VideoFlags & XC_VIDEO_FLAGS_PAL_60Hz )
|
||||
pD3Dpp->FullScreen_RefreshRateInHz = 60;
|
||||
else
|
||||
pD3Dpp->FullScreen_RefreshRateInHz = 50;
|
||||
}
|
||||
else
|
||||
pD3Dpp->FullScreen_RefreshRateInHz = 60;
|
||||
#endif
|
||||
|
||||
pD3Dpp->Flags = 0;
|
||||
|
||||
@@ -556,9 +505,6 @@ static void SetPresentParametersFromVideoModeParams( const VideoModeParams &p, D
|
||||
RString RageDisplay_D3D::TryVideoMode( const VideoModeParams &_p, bool &bNewDeviceOut )
|
||||
{
|
||||
VideoModeParams p = _p;
|
||||
#if defined(XBOX)
|
||||
p.windowed = false;
|
||||
#endif
|
||||
LOG->Warn( "RageDisplay_D3D::TryVideoMode( %d, %d, %d, %d, %d, %d )", p.windowed, p.width, p.height, p.bpp, p.rate, p.vsync );
|
||||
|
||||
if( FindBackBufferType( p.windowed, p.bpp ) == D3DFMT_UNKNOWN ) // no possible back buffer formats
|
||||
@@ -571,11 +517,6 @@ RString RageDisplay_D3D::TryVideoMode( const VideoModeParams &_p, bool &bNewDevi
|
||||
|
||||
SetPresentParametersFromVideoModeParams( p, &g_d3dpp );
|
||||
|
||||
#if defined(XBOX)
|
||||
if( D3D__pDevice )
|
||||
g_pd3dDevice = D3D__pDevice;
|
||||
#endif
|
||||
|
||||
// Display the window immediately, so we don't display the desktop ...
|
||||
while( 1 )
|
||||
{
|
||||
@@ -612,14 +553,6 @@ void RageDisplay_D3D::ResolutionChanged()
|
||||
{
|
||||
//LOG->Warn( "RageDisplay_D3D::ResolutionChanged" );
|
||||
|
||||
#if defined(XBOX)
|
||||
VideoModeParams p = GetActualVideoModeParams();
|
||||
D3DVIEWPORT8 viewData = { 0, 0, p.width, p.height, 0.f, 1.f };
|
||||
g_pd3dDevice->SetViewport( &viewData );
|
||||
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
|
||||
D3DCOLOR_XRGB(0,0,0), 1.0f, 0x00000000 );
|
||||
#endif
|
||||
|
||||
RageDisplay::ResolutionChanged();
|
||||
}
|
||||
|
||||
@@ -632,7 +565,6 @@ bool RageDisplay_D3D::BeginFrame()
|
||||
{
|
||||
GraphicsWindow::Update();
|
||||
|
||||
#if !defined(XBOX)
|
||||
switch( g_pd3dDevice->TestCooperativeLevel() )
|
||||
{
|
||||
case D3DERR_DEVICELOST:
|
||||
@@ -647,7 +579,6 @@ bool RageDisplay_D3D::BeginFrame()
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
|
||||
D3DCOLOR_XRGB(0,0,0), 1.0f, 0x00000000 );
|
||||
@@ -670,16 +601,6 @@ void RageDisplay_D3D::EndFrame()
|
||||
|
||||
bool RageDisplay_D3D::SupportsTextureFormat( PixelFormat pixfmt, bool realtime )
|
||||
{
|
||||
#if defined(XBOX)
|
||||
/* Lazy... Xbox handles paletted textures completely differently than
|
||||
* regular D3D. It's not worth writing a bunch of code to handle it.
|
||||
* Paletted textures result in worse cache efficiency anyway (see "Xbox
|
||||
* Palettized Texture Performance" in XDK). So, just force 32bit ARGB textures.
|
||||
* -Chris
|
||||
* This is also needed for XGSwizzleRect(). */
|
||||
return pixfmt == PixelFormat_RGBA8;
|
||||
#endif
|
||||
|
||||
// Some cards (Savage) don't support alpha in palettes.
|
||||
// Don't allow paletted textures if this is the case.
|
||||
if( pixfmt == PixelFormat_PAL && !(g_DeviceCaps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE) )
|
||||
@@ -707,9 +628,6 @@ bool RageDisplay_D3D::SupportsThreadedRendering()
|
||||
|
||||
RageSurface* RageDisplay_D3D::CreateScreenshot()
|
||||
{
|
||||
#if defined(XBOX)
|
||||
return NULL;
|
||||
#else
|
||||
// Get the back buffer.
|
||||
IDirect3DSurface8* pSurface;
|
||||
g_pd3dDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pSurface );
|
||||
@@ -756,7 +674,6 @@ RageSurface* RageDisplay_D3D::CreateScreenshot()
|
||||
pCopy->Release();
|
||||
|
||||
return SurfaceCopy;
|
||||
#endif
|
||||
}
|
||||
|
||||
VideoModeParams RageDisplay_D3D::GetActualVideoModeParams() const
|
||||
@@ -1429,15 +1346,6 @@ unsigned RageDisplay_D3D::CreateTexture(
|
||||
IDirect3DTexture8* pTex;
|
||||
hr = g_pd3dDevice->CreateTexture( power_of_two(img->w), power_of_two(img->h), 1, 0, D3DFORMATS[pixfmt], D3DPOOL_MANAGED, &pTex );
|
||||
|
||||
#if defined(XBOX)
|
||||
while(hr == E_OUTOFMEMORY)
|
||||
{
|
||||
if(!vmem_Manager.DecommitLRU())
|
||||
break;
|
||||
hr = g_pd3dDevice->CreateTexture( power_of_two(img->w), power_of_two(img->h), 1, 0, D3DFORMATS[pixfmt], D3DPOOL_MANAGED, &pTex );
|
||||
}
|
||||
#endif
|
||||
|
||||
if( FAILED(hr) )
|
||||
RageException::Throw( "CreateTexture(%i,%i,%s) failed: %s",
|
||||
img->w, img->h, PixelFormatToString(pixfmt).c_str(), GetErrorString(hr).c_str() );
|
||||
@@ -1490,27 +1398,6 @@ void RageDisplay_D3D::UpdateTexture(
|
||||
ASSERT( yoffset+height <= int(desc.Height) );
|
||||
|
||||
// Copy bits
|
||||
#if defined(XBOX)
|
||||
RageSurface *Texture = CreateSurface( width, height, 32,
|
||||
Swap32BE( 0x0000FF00 ),
|
||||
Swap32BE( 0x00FF0000 ),
|
||||
Swap32BE( 0xFF000000 ),
|
||||
Swap32BE( 0x000000FF ) );
|
||||
|
||||
RageSurfaceUtils::Blit( img, Texture, width, height );
|
||||
|
||||
// Xbox textures need to be swizzled
|
||||
XGSwizzleRect(
|
||||
Texture->pixels, // pSource,
|
||||
Texture->pitch, // Pitch,
|
||||
NULL, // pRect,
|
||||
lr.pBits, // pDest,
|
||||
Texture->w, // Width,
|
||||
Texture->h, // Height,
|
||||
NULL, // pPoint,
|
||||
Texture->format->BytesPerPixel ); //BytesPerPixel
|
||||
delete Texture;
|
||||
#else
|
||||
int texpixfmt;
|
||||
for(texpixfmt = 0; texpixfmt < NUM_PixelFormat; ++texpixfmt)
|
||||
if(D3DFORMATS[texpixfmt] == desc.Format) break;
|
||||
@@ -1521,7 +1408,6 @@ void RageDisplay_D3D::UpdateTexture(
|
||||
RageSurfaceUtils::Blit( img, Texture, width, height );
|
||||
|
||||
delete Texture;
|
||||
#endif
|
||||
|
||||
pTex->UnlockRect( 0 );
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
#include "RageUtil.h"
|
||||
#include <memory>
|
||||
|
||||
#if defined(_WINDOWS) || defined(_XBOX)
|
||||
#if defined(_WINDOWS)
|
||||
#include "zlib/zlib.h"
|
||||
#if defined(_MSC_VER) && !defined(_XBOX)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma comment(lib, "zlib/zdll.lib")
|
||||
#endif
|
||||
#elif defined(MACOSX)
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
#include <fcntl.h>
|
||||
#else
|
||||
#include "archutils/Win32/ErrorStrings.h"
|
||||
#if !defined(_XBOX)
|
||||
#include <windows.h>
|
||||
#endif // !defined(_XBOX)
|
||||
#include <io.h>
|
||||
#endif // !defined(WIN32)
|
||||
|
||||
@@ -66,6 +64,10 @@ private:
|
||||
*/
|
||||
bool m_bWriteFailed;
|
||||
bool WriteFailed() const { return !(m_iMode & RageFile::STREAMED) && m_bWriteFailed; }
|
||||
|
||||
// unused
|
||||
RageFileObjDirect& operator=(const RageFileObjDirect& rhs);
|
||||
RageFileObjDirect(const RageFileObjDirect& rhs);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -12,57 +12,13 @@
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#else
|
||||
#if !defined(_XBOX)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#if defined(_XBOX)
|
||||
/* Wrappers for low-level file functions, to work around Xbox issues: */
|
||||
int DoMkdir( const RString &sPath, int perm )
|
||||
{
|
||||
return mkdir( DoPathReplace(sPath), perm );
|
||||
}
|
||||
|
||||
int DoOpen( const RString &sPath, int flags, int perm )
|
||||
{
|
||||
return open( DoPathReplace(sPath), flags, perm );
|
||||
}
|
||||
|
||||
int DoStat( const RString &sPath, struct stat *st )
|
||||
{
|
||||
return stat( DoPathReplace(sPath), st );
|
||||
}
|
||||
|
||||
int DoRename( const RString &sOldPath, const RString &sNewPath )
|
||||
{
|
||||
return rename( DoPathReplace(sOldPath), DoPathReplace(sNewPath) );
|
||||
}
|
||||
|
||||
int DoRemove( const RString &sPath )
|
||||
{
|
||||
return remove( DoPathReplace(sPath) );
|
||||
}
|
||||
|
||||
int DoRmdir( const RString &sPath )
|
||||
{
|
||||
return rmdir( DoPathReplace(sPath) );
|
||||
}
|
||||
|
||||
HANDLE DoFindFirstFile( const RString &sPath, WIN32_FIND_DATA *fd )
|
||||
{
|
||||
return FindFirstFile( DoPathReplace(sPath), fd );
|
||||
}
|
||||
|
||||
#endif
|
||||
RString DoPathReplace(const RString &sPath)
|
||||
{
|
||||
RString TempPath = sPath;
|
||||
#if defined(XBOX)
|
||||
TempPath.Replace( "//", "\\" );
|
||||
TempPath.Replace( "/", "\\" );
|
||||
#endif
|
||||
return TempPath;
|
||||
}
|
||||
|
||||
@@ -72,9 +28,9 @@ static bool WinMoveFileInternal( const RString &sOldPath, const RString &sNewPat
|
||||
{
|
||||
static bool Win9x = false;
|
||||
|
||||
/* Windows botches rename: it returns error if the file exists. In NT,
|
||||
/* Windows botches rename: it returns error if the file exists. In NT,
|
||||
* we can use MoveFileEx( new, old, MOVEFILE_REPLACE_EXISTING ) (though I
|
||||
* don't know if it has similar atomicity guarantees to rename). In
|
||||
* don't know if it has similar atomicity guarantees to rename). In
|
||||
* 9x, we're screwed, so just delete any existing file (we aren't going
|
||||
* to be robust on 9x anyway). */
|
||||
if( !Win9x )
|
||||
@@ -92,7 +48,7 @@ static bool WinMoveFileInternal( const RString &sOldPath, const RString &sNewPat
|
||||
|
||||
if( MoveFile( sOldPath, sNewPath ) )
|
||||
return true;
|
||||
|
||||
|
||||
if( GetLastError() != ERROR_ALREADY_EXISTS )
|
||||
return false;
|
||||
|
||||
@@ -118,15 +74,15 @@ bool WinMoveFile( RString sOldPath, RString sNewPath )
|
||||
/* mkdir -p. Doesn't fail if Path already exists and is a directory. */
|
||||
bool CreateDirectories( RString Path )
|
||||
{
|
||||
/* XXX: handle "//foo/bar" paths in Windows */
|
||||
// XXX: handle "//foo/bar" paths in Windows
|
||||
vector<RString> parts;
|
||||
RString curpath;
|
||||
|
||||
/* If Path is absolute, add the initial slash ("ignore empty" will remove it). */
|
||||
// If Path is absolute, add the initial slash ("ignore empty" will remove it).
|
||||
if( Path.Left(1) == "/" )
|
||||
curpath = "/";
|
||||
|
||||
/* Ignore empty, so eg. "/foo/bar//baz" doesn't try to create "/foo/bar" twice. */
|
||||
// Ignore empty, so eg. "/foo/bar//baz" doesn't try to create "/foo/bar" twice.
|
||||
split( Path, "/", parts, true );
|
||||
|
||||
for(unsigned i = 0; i < parts.size(); ++i)
|
||||
@@ -174,7 +130,7 @@ bool CreateDirectories( RString Path )
|
||||
WARN( ssprintf("Couldn't create %s: %s", curpath.c_str(), strerror(errno)) );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -189,10 +145,10 @@ void DirectFilenameDB::SetRoot( RString root_ )
|
||||
{
|
||||
root = root_;
|
||||
|
||||
/* "\abcd\" -> "/abcd/": */
|
||||
// "\abcd\" -> "/abcd/":
|
||||
root.Replace( "\\", "/" );
|
||||
|
||||
/* "/abcd/" -> "/abcd": */
|
||||
// "/abcd/" -> "/abcd":
|
||||
if( root.Right(1) == "/" )
|
||||
root.erase( root.size()-1, 1 );
|
||||
}
|
||||
@@ -210,7 +166,7 @@ void DirectFilenameDB::CacheFile( const RString &sPath )
|
||||
}
|
||||
while( !pFileSet->m_bFilled )
|
||||
m_Mutex.Wait();
|
||||
|
||||
|
||||
#if defined(WIN32)
|
||||
// There is almost surely a better way to do this
|
||||
WIN32_FIND_DATA fd;
|
||||
@@ -224,12 +180,12 @@ void DirectFilenameDB::CacheFile( const RString &sPath )
|
||||
f.dir = !!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
|
||||
f.size = fd.nFileSizeLow;
|
||||
f.hash = fd.ftLastWriteTime.dwLowDateTime;
|
||||
|
||||
|
||||
pFileSet->files.insert( f );
|
||||
FindClose( hFind );
|
||||
#else
|
||||
File f( Basename(sPath) );
|
||||
|
||||
|
||||
struct stat st;
|
||||
if( DoStat(root+sPath, &st) == -1 )
|
||||
{
|
||||
@@ -237,7 +193,7 @@ void DirectFilenameDB::CacheFile( const RString &sPath )
|
||||
// If it's a broken symlink, ignore it. Otherwise, warn.
|
||||
// Huh?
|
||||
WARN( ssprintf("File '%s' is gone! (%s)",
|
||||
sPath.c_str(), strerror(iError)) );
|
||||
sPath.c_str(), strerror(iError)) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -255,17 +211,10 @@ void DirectFilenameDB::PopulateFileSet( FileSet &fs, const RString &path )
|
||||
{
|
||||
RString sPath = path;
|
||||
|
||||
#if defined(XBOX)
|
||||
/* Xbox doesn't handle path names which end with ".", which are used when using an
|
||||
* alternative song directory */
|
||||
if( sPath.size() > 0 && sPath.Right(1) == "." )
|
||||
sPath.erase( sPath.size() - 1 );
|
||||
#endif
|
||||
|
||||
/* Resolve path cases (path/Path -> PATH/path). */
|
||||
// Resolve path cases (path/Path -> PATH/path).
|
||||
ResolvePath( sPath );
|
||||
|
||||
fs.age.GetDeltaTime(); /* reset */
|
||||
fs.age.GetDeltaTime(); // reset
|
||||
fs.files.clear();
|
||||
|
||||
#if defined(WIN32)
|
||||
|
||||
@@ -5,15 +5,6 @@
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#if defined(_XBOX)
|
||||
int DoMkdir( const RString &sPath, int perm );
|
||||
int DoOpen( const RString &sPath, int flags, int perm );
|
||||
int DoStat( const RString &sPath, struct stat *st );
|
||||
int DoRename( const RString &sOldPath, const RString &sNewPath );
|
||||
int DoRemove( const RString &sPath );
|
||||
int DoRmdir( const RString &sPath );
|
||||
HANDLE DoFindFirstFile( const RString &sPath, WIN32_FIND_DATA *fd );
|
||||
#else
|
||||
#define DoOpen open
|
||||
#define DoStat stat
|
||||
#define DoMkdir mkdir
|
||||
@@ -21,7 +12,6 @@ HANDLE DoFindFirstFile( const RString &sPath, WIN32_FIND_DATA *fd );
|
||||
#define DoRename rename
|
||||
#define DoRemove remove
|
||||
#define DoRmdir rmdir
|
||||
#endif
|
||||
RString DoPathReplace( const RString &sPath );
|
||||
|
||||
#if defined(WIN32)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#include <cerrno>
|
||||
|
||||
#if defined(WIN32) && !defined(XBOX)
|
||||
#if defined(WIN32)
|
||||
#include <windows.h>
|
||||
#elif defined(UNIX) || defined(MACOSX)
|
||||
#include <paths.h>
|
||||
@@ -174,11 +174,7 @@ static RageFileDriverMountpoints *g_Mountpoints = NULL;
|
||||
|
||||
static RString GetDirOfExecutable( RString argv0 )
|
||||
{
|
||||
#ifdef _XBOX
|
||||
// ???: what if it's not running from D:\?
|
||||
return "D:\\";
|
||||
#else
|
||||
/* argv[0] can be wrong in most OS's; try to avoid using it. */
|
||||
// argv[0] can be wrong in most OS's; try to avoid using it.
|
||||
|
||||
RString sPath;
|
||||
#if defined(WIN32)
|
||||
@@ -241,7 +237,6 @@ static RString GetDirOfExecutable( RString argv0 )
|
||||
#endif
|
||||
}
|
||||
return sPath;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ChangeToDirOfExecutable( const RString &argv0 )
|
||||
|
||||
@@ -315,8 +315,9 @@ public:
|
||||
float level;
|
||||
|
||||
// Mouse coordinates
|
||||
unsigned x;
|
||||
unsigned y;
|
||||
//unsigned x;
|
||||
//unsigned y;
|
||||
int z; // mousewheel
|
||||
|
||||
/* Whether this button is pressed. This is level with a threshold and
|
||||
* debouncing applied. */
|
||||
@@ -324,12 +325,12 @@ public:
|
||||
|
||||
RageTimer ts;
|
||||
|
||||
DeviceInput(): device(InputDevice_Invalid), button(DeviceButton_Invalid), level(0), x(0), y(0), bDown(false), ts(RageZeroTimer) { }
|
||||
DeviceInput( InputDevice d, DeviceButton b, float l=0 ): device(d), button(b), level(l), x(0), y(0), bDown(l > 0.5f), ts(RageZeroTimer) { }
|
||||
DeviceInput(): device(InputDevice_Invalid), button(DeviceButton_Invalid), level(0), z(0), bDown(false), ts(RageZeroTimer) { }
|
||||
DeviceInput( InputDevice d, DeviceButton b, float l=0 ): device(d), button(b), level(l), z(0), bDown(l > 0.5f), ts(RageZeroTimer) { }
|
||||
DeviceInput( InputDevice d, DeviceButton b, float l, const RageTimer &t ):
|
||||
device(d), button(b), level(l), x(0), y(0), bDown(level > 0.5f), ts(t) { }
|
||||
DeviceInput( InputDevice d, DeviceButton b, const RageTimer &t, unsigned xPos=0, unsigned yPos=0 ):
|
||||
device(d), button(b), level(0), x(xPos), y(yPos), bDown(false), ts(t) { }
|
||||
device(d), button(b), level(l), z(0), bDown(level > 0.5f), ts(t) { }
|
||||
DeviceInput( InputDevice d, DeviceButton b, const RageTimer &t, int zVal=0 ):
|
||||
device(d), button(b), level(0), z(zVal), bDown(false), ts(t) { }
|
||||
|
||||
bool operator==( const DeviceInput &other ) const
|
||||
{
|
||||
|
||||
+1
-1
@@ -175,7 +175,7 @@ void RageLog::SetShowLogOutput( bool show )
|
||||
{
|
||||
m_bShowLogOutput = show;
|
||||
|
||||
#if defined(WIN32) && !defined(_XBOX)
|
||||
#if defined(WIN32)
|
||||
if( m_bShowLogOutput )
|
||||
{
|
||||
// create a new console window and attach standard handles
|
||||
|
||||
+1
-1
@@ -112,7 +112,7 @@ RageMatrix RageMatrix::GetTranspose() const
|
||||
|
||||
void RageMatrixMultiply( RageMatrix* pOut, const RageMatrix* pA, const RageMatrix* pB )
|
||||
{
|
||||
//#if defined(_WINDOWS) || defined(_XBOX)
|
||||
//#if defined(_WINDOWS)
|
||||
// // <30 cycles for theirs versus >100 for ours.
|
||||
// D3DXMatrixMultiply( (D3DMATRIX*)pOut, (D3DMATRIX*)pA, (D3DMATRIX*)pB );
|
||||
//#else
|
||||
|
||||
+3
-2
@@ -48,9 +48,10 @@ RageSoundLoadParams::RageSoundLoadParams():
|
||||
m_bSupportRateChanging(false), m_bSupportPan(false) {}
|
||||
|
||||
RageSound::RageSound():
|
||||
m_Mutex( "RageSound" ), m_pSource(NULL), m_iStreamFrame(0),
|
||||
m_Mutex( "RageSound" ), m_pSource(NULL),
|
||||
m_sFilePath(""), m_Param(), m_iStreamFrame(0),
|
||||
m_iStoppedSourceFrame(0), m_bPlaying(false),
|
||||
m_bDeleteWhenFinished(false)
|
||||
m_sError(""), m_bDeleteWhenFinished(false)
|
||||
{
|
||||
ASSERT( SOUNDMAN );
|
||||
}
|
||||
|
||||
@@ -9,24 +9,16 @@
|
||||
#include <cerrno>
|
||||
#include <map>
|
||||
|
||||
#if defined(_WINDOWS) || defined(_XBOX) || defined(MACOSX)
|
||||
#if defined(_WINDOWS) || defined(MACOSX)
|
||||
#include "mad-0.15.1b/mad.h"
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _XBOX
|
||||
#ifdef DEBUG
|
||||
#pragma comment(lib, "mad-0.15.1b/xboxmad/debug/xboxmad.lib")
|
||||
#else
|
||||
#pragma comment(lib, "mad-0.15.1b/xboxmad/Release/xboxmad.lib")
|
||||
#endif // DEBUG
|
||||
#else
|
||||
#pragma comment(lib, "mad-0.15.1b/msvc++/Release/libmad.lib")
|
||||
#endif // _XBOX
|
||||
#endif //_MSC_VER
|
||||
#else
|
||||
#include <mad.h>
|
||||
#endif // _WINDOWS
|
||||
|
||||
/* ID3 code from libid3: */
|
||||
// ID3 code from libid3:
|
||||
enum tagtype {
|
||||
TAGTYPE_NONE = 0,
|
||||
TAGTYPE_ID3V1,
|
||||
|
||||
@@ -374,7 +374,7 @@ public:
|
||||
int iFramesToCopy = (m_iBufferAvail-m_iBufferUsed) / iBytesPerFrame;
|
||||
iFramesToCopy = min( iFramesToCopy, (int) (iFrames-iGotFrames) );
|
||||
int iSamplesToCopy = iFramesToCopy * iSamplesPerFrame;
|
||||
int iBytesToCopy = iSamplesToCopy * sizeof(int16_t);
|
||||
int iBytesToCopy = iSamplesToCopy * sizeof(float);
|
||||
memcpy( buf, m_pBuffer+m_iBufferUsed, iBytesToCopy );
|
||||
m_iBufferUsed += iBytesToCopy;
|
||||
iGotFrames += iFramesToCopy;
|
||||
|
||||
@@ -7,24 +7,15 @@
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
// Don't let jpeglib.h define the boolean type on Xbox.
|
||||
#if defined(_XBOX)
|
||||
# define HAVE_BOOLEAN
|
||||
#endif
|
||||
|
||||
#if defined(WIN32)
|
||||
/* work around namespace bugs in win32/libjpeg: */
|
||||
// work around namespace bugs in win32/libjpeg:
|
||||
#define XMD_H
|
||||
#undef FAR
|
||||
#include "libjpeg/jpeglib.h"
|
||||
#include "libjpeg/jerror.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#if !defined(XBOX)
|
||||
#pragma comment(lib, "libjpeg/jpeg.lib")
|
||||
#else
|
||||
#pragma comment(lib, "libjpeg/xboxjpeg.lib")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#pragma warning(disable: 4611) /* interaction between '_setjmp' and C++ object destruction is non-portable */
|
||||
|
||||
@@ -6,25 +6,16 @@
|
||||
#include "RageSurface.h"
|
||||
|
||||
|
||||
#if defined(_WINDOWS) || defined(_XBOX)
|
||||
#if defined(_WINDOWS)
|
||||
# include "libpng/include/png.h"
|
||||
# if defined(_MSC_VER)
|
||||
# if defined(_XBOX)
|
||||
# pragma comment(lib, "libpng/lib/xboxlibpng.lib")
|
||||
# else
|
||||
# pragma comment(lib, "libpng/lib/libpng.lib")
|
||||
# endif
|
||||
# pragma comment(lib, "libpng/lib/libpng.lib")
|
||||
# pragma warning(disable: 4611) /* interaction between '_setjmp' and C++ object destruction is non-portable */
|
||||
# endif // _MSC_VER
|
||||
#else
|
||||
# include <png.h>
|
||||
#endif
|
||||
|
||||
#if defined(_XBOX)
|
||||
# include <malloc.h> // for alloca
|
||||
# include "archutils/Xbox/VirtualMemory.h"
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
void RageFile_png_read( png_struct *png, png_byte *p, png_size_t size )
|
||||
@@ -80,16 +71,6 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro
|
||||
|
||||
png_struct *png = png_create_read_struct( PNG_LIBPNG_VER_STRING, &error, PNG_Error, PNG_Warning );
|
||||
|
||||
#if defined(XBOX)
|
||||
while(png == NULL)
|
||||
{
|
||||
if(!vmem_Manager.DecommitLRU())
|
||||
break;
|
||||
|
||||
png = png_create_read_struct( PNG_LIBPNG_VER_STRING, &error, PNG_Error, PNG_Warning );
|
||||
}
|
||||
#endif
|
||||
|
||||
if( png == NULL )
|
||||
{
|
||||
sprintf( errorbuf, "creating png_create_read_struct failed");
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "RageUtil.h"
|
||||
#include "RageFile.h"
|
||||
|
||||
#undef FAR /* fix for VC */
|
||||
#undef FAR // fix for VC
|
||||
/** @brief A helper to get the jpeg lib. */
|
||||
namespace jpeg
|
||||
{
|
||||
@@ -16,16 +16,11 @@ namespace jpeg
|
||||
}
|
||||
}
|
||||
|
||||
/* Pull in JPEG library here. */
|
||||
#ifdef _XBOX
|
||||
#pragma comment(lib, "libjpeg/xboxjpeg.lib")
|
||||
#elif defined _MSC_VER
|
||||
// Pull in JPEG library here.
|
||||
#if defined _MSC_VER
|
||||
#pragma comment(lib, "libjpeg/jpeg.lib")
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#define OUTPUT_BUFFER_SIZE 4096
|
||||
typedef struct
|
||||
{
|
||||
|
||||
@@ -6,14 +6,10 @@
|
||||
#include "RageLog.h"
|
||||
#include "RageUtil.h"
|
||||
|
||||
#if defined(WINDOWS) || defined(_XBOX)
|
||||
#if defined(WINDOWS)
|
||||
#include "libpng/include/png.h"
|
||||
#if defined(_MSC_VER)
|
||||
# if defined(_XBOX)
|
||||
# pragma comment(lib, "libpng/lib/xboxlibpng.lib")
|
||||
# else
|
||||
# pragma comment(lib, "libpng/lib/libpng.lib")
|
||||
# endif
|
||||
# pragma comment(lib, "libpng/lib/libpng.lib")
|
||||
#pragma warning(disable: 4611) /* interaction between '_setjmp' and C++ object destruction is non-portable */
|
||||
#endif
|
||||
#else
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
/* RageTexturePreloader - Load textures in advance, for use later. */
|
||||
|
||||
#ifndef RAGE_TEXTURE_PRELOADER_H
|
||||
#define RAGE_TEXTURE_PRELOADER_H
|
||||
|
||||
class RageTexture;
|
||||
struct RageTextureID;
|
||||
|
||||
/** @brief Load the textures in advance for using them later. */
|
||||
class RageTexturePreloader
|
||||
{
|
||||
public:
|
||||
RageTexturePreloader() { }
|
||||
RageTexturePreloader( const RageTexturePreloader &cpy ) { *this = cpy; }
|
||||
RageTexturePreloader(): m_apTextures() { }
|
||||
RageTexturePreloader( const RageTexturePreloader &cpy ):
|
||||
m_apTextures(cpy.m_apTextures) { }
|
||||
RageTexturePreloader &operator=( const RageTexturePreloader &rhs );
|
||||
~RageTexturePreloader();
|
||||
void Load( const RageTextureID &ID );
|
||||
|
||||
@@ -335,6 +335,7 @@ typedef StepMania::Rect<float> RectF;
|
||||
* have the same layout that D3D expects. */
|
||||
struct RageSpriteVertex // has color
|
||||
{
|
||||
RageSpriteVertex(): p(), n(), c(), t() {}
|
||||
RageVector3 p; // position
|
||||
RageVector3 n; // normal
|
||||
RageVColor c; // diffuse color
|
||||
|
||||
@@ -967,14 +967,10 @@ bool GetCommandlineArgument( const RString &option, RString *argument, int iInde
|
||||
|
||||
RString GetCwd()
|
||||
{
|
||||
#ifdef _XBOX
|
||||
return SYS_BASE_PATH;
|
||||
#else
|
||||
char buf[PATH_MAX];
|
||||
bool ret = getcwd(buf, PATH_MAX) != NULL;
|
||||
ASSERT(ret);
|
||||
return buf;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -18,17 +18,14 @@ template<typename T>
|
||||
class CachedObject
|
||||
{
|
||||
public:
|
||||
CachedObject()
|
||||
CachedObject(): m_pObject(NULL)
|
||||
{
|
||||
m_pObject = NULL;
|
||||
|
||||
/* A new object is being constructed, so invalidate negative caching. */
|
||||
ClearCacheNegative();
|
||||
}
|
||||
|
||||
CachedObject( const CachedObject &cpy )
|
||||
CachedObject( const CachedObject &cpy ): m_pObject(NULL)
|
||||
{
|
||||
m_pObject = NULL;
|
||||
ClearCacheNegative();
|
||||
}
|
||||
|
||||
@@ -117,11 +114,10 @@ public:
|
||||
Object::Register( this );
|
||||
}
|
||||
|
||||
CachedObjectPointer( const CachedObjectPointer &cpy )
|
||||
CachedObjectPointer( const CachedObjectPointer &cpy ):
|
||||
m_pCache(cpy.m_pCache), m_bCacheIsSet(cpy.m_bCacheIsSet)
|
||||
{
|
||||
CachedObjectHelpers::Lock();
|
||||
m_pCache = cpy.m_pCache;
|
||||
m_bCacheIsSet = cpy.m_bCacheIsSet;
|
||||
Object::Register( this );
|
||||
CachedObjectHelpers::Unlock();
|
||||
}
|
||||
|
||||
@@ -179,7 +179,6 @@ void RoomInfoDisplay::SetRoomInfo( const RoomInfo& info)
|
||||
m_playerList[i] = new BitmapText;
|
||||
m_playerList[i]->LoadFromFont( THEME->GetPathF(GetName(),"text") );
|
||||
m_playerList[i]->SetName("PlayerListElement");
|
||||
m_playerList[i]->SetShadowLength( 0 );
|
||||
m_playerList[i]->SetHorizAlign( align_left );
|
||||
m_playerList[i]->SetX(PLAYERLISTX + (i * PLAYERLISTOFFSETX));
|
||||
m_playerList[i]->SetY(PLAYERLISTY + (i * PLAYERLISTOFFSETY));
|
||||
|
||||
@@ -151,7 +151,6 @@ bool RoomWheel::Select()
|
||||
{
|
||||
// Since this is not actually an option outside of this wheel, NULL is a good idea.
|
||||
m_LastSelection = NULL;
|
||||
// todo: Call a screen with class ScreenTextEntry instead. -aj
|
||||
ScreenTextEntry::TextEntry( SM_BackFromRoomName, ENTER_ROOM_NAME, "", 255 );
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -442,6 +442,9 @@ public:
|
||||
sub_title_transliteration,
|
||||
artist_transliteration,
|
||||
last_beat_hint,
|
||||
display_bpm,
|
||||
min_bpm,
|
||||
max_bpm,
|
||||
NUM_SONG_INFORMATION_CHOICES
|
||||
};
|
||||
void HandleSongInformationChoice( SongInformationChoice c, const vector<int> &iAnswers );
|
||||
@@ -456,6 +459,7 @@ public:
|
||||
time_signature_denominator,
|
||||
tickcount,
|
||||
combo,
|
||||
warp,
|
||||
NUM_TIMING_DATA_INFORMATION_CHOICES
|
||||
};
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "ScoreKeeperNormal.h"
|
||||
#include "InputEventPlus.h"
|
||||
|
||||
|
||||
// metrics that are common to all ScreenEvaluation classes
|
||||
#define BANNER_WIDTH THEME->GetMetricF(m_sName,"BannerWidth")
|
||||
#define BANNER_HEIGHT THEME->GetMetricF(m_sName,"BannerHeight")
|
||||
@@ -45,7 +44,7 @@ LuaFunction( JudgmentLineToLocalizedString, JudgmentLineToLocalizedString(Enum::
|
||||
|
||||
static const char *DetailLineNames[NUM_DetailLine] =
|
||||
{
|
||||
"NumSteps","Jumps", "Holds", "Mines", "Hands", "Rolls",
|
||||
"NumSteps","Jumps", "Holds", "Mines", "Hands", "Rolls", "Lifts", "Fakes"
|
||||
};
|
||||
XToString( DetailLine );
|
||||
#define DETAILLINE_FORMAT THEME->GetMetric (m_sName,"DetailLineFormat")
|
||||
@@ -352,7 +351,7 @@ void ScreenEvaluation::Init()
|
||||
{
|
||||
FOREACH_EnabledPlayer( p )
|
||||
{
|
||||
m_sprPercentFrame[p].Load( THEME->GetPathG(m_sName,ssprintf("percent frame p%d",p+1)) );
|
||||
m_sprPercentFrame[p].Load( THEME->GetPathG(m_sName,ssprintf("PercentFrame p%d",p+1)) );
|
||||
m_sprPercentFrame[p]->SetName( ssprintf("PercentFrameP%d",p+1) );
|
||||
ActorUtil::LoadAllCommands( *m_sprPercentFrame[p], m_sName );
|
||||
SET_XY( m_sprPercentFrame[p] );
|
||||
@@ -453,6 +452,7 @@ void ScreenEvaluation::Init()
|
||||
}
|
||||
|
||||
// init judgment area
|
||||
ROLLING_NUMBERS_CLASS.Load( m_sName, "RollingNumbersClass" );
|
||||
FOREACH_ENUM( JudgmentLine, l )
|
||||
{
|
||||
if( l == JudgmentLine_W1 && !GAMESTATE->ShowW1() )
|
||||
@@ -474,7 +474,7 @@ void ScreenEvaluation::Init()
|
||||
{
|
||||
m_textJudgmentLineNumber[l][p].LoadFromFont( THEME->GetPathF(m_sName, "JudgmentLineNumber") );
|
||||
m_textJudgmentLineNumber[l][p].SetName( JudgmentLineToString(l)+ssprintf("NumberP%d",p+1) );
|
||||
m_textJudgmentLineNumber[l][p].Load( "RollingNumbersJudgment" );
|
||||
m_textJudgmentLineNumber[l][p].Load( ROLLING_NUMBERS_CLASS );
|
||||
ActorUtil::LoadAllCommands( m_textJudgmentLineNumber[l][p], m_sName );
|
||||
SET_XY( m_textJudgmentLineNumber[l][p] );
|
||||
this->AddChild( &m_textJudgmentLineNumber[l][p] );
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user