added BackgroundChange editing and DWI saving to editor

This commit is contained in:
Chris Danford
2002-08-23 20:18:29 +00:00
parent 36d81d0e1c
commit a0c7d5bd22
41 changed files with 906 additions and 449 deletions
+1
View File
@@ -1,6 +1,7 @@
------------------------CVS after 3.00 beta 6---------------- ------------------------CVS after 3.00 beta 6----------------
CHANGE: While AutoPlay is on, life, score, and dance points will not CHANGE: While AutoPlay is on, life, score, and dance points will not
accumulate. accumulate.
CHANGE: DWI save support added to editor.
NEW FEATURE: Editor can edit BackgroundChanges. Use the 'B' key. NEW FEATURE: Editor can edit BackgroundChanges. Use the 'B' key.
NEW FEATURE: Delayed escape/back key is now optional. NEW FEATURE: Delayed escape/back key is now optional.
CHANGE: Slow-motion is now ~ instead of LShift. CHANGE: Slow-motion is now ~ instead of LShift.
+3 -1
View File
@@ -209,7 +209,9 @@ SurviveTimeX=320
SurviveTimeY=340 SurviveTimeY=340
DebugX=320 DebugX=320
DebugY=240 DebugY=240
SecondsBetweenComments=13 AutoPlayX=320
AutoPlayY=360
SecondsBetweenComments=10
DemonstrationSeconds=30 DemonstrationSeconds=30
[Evaluation] [Evaluation]
+1 -1
View File
@@ -20,7 +20,7 @@
#include "NoteDisplay.h" #include "NoteDisplay.h"
float ArrowGetYOffset2( const PlayerNumber pn, float fNoteBeat ) float ArrowGetYOffset( const PlayerNumber pn, float fNoteBeat )
{ {
float fSongBeat = GAMESTATE->m_fSongBeat; float fSongBeat = GAMESTATE->m_fSongBeat;
float fBeatsUntilStep = fNoteBeat - fSongBeat; float fBeatsUntilStep = fNoteBeat - fSongBeat;
+1 -1
View File
@@ -21,7 +21,7 @@ const float ARROW_GAP = ARROW_SIZE;// + 2;
// fYOffset is a vertical position in pixels relative to the center. // fYOffset is a vertical position in pixels relative to the center.
// (positive if has not yet been stepped on, negative if has already passed). // (positive if has not yet been stepped on, negative if has already passed).
// The ArrowEffect is applied in this stage. // The ArrowEffect is applied in this stage.
float ArrowGetYOffset2( const PlayerNumber pn, float fNoteBeat ); float ArrowGetYOffset( const PlayerNumber pn, float fNoteBeat );
// fRotation is Z rotation of an arrow. This will depend on the column of // fRotation is Z rotation of an arrow. This will depend on the column of
+101 -49
View File
@@ -33,11 +33,11 @@ const int BACKGROUND_BOTTOM = 480;
#define RECT_BACKGROUND CRect(BACKGROUND_LEFT,BACKGROUND_TOP,BACKGROUND_RIGHT,BACKGROUND_BOTTOM) #define RECT_BACKGROUND CRect(BACKGROUND_LEFT,BACKGROUND_TOP,BACKGROUND_RIGHT,BACKGROUND_BOTTOM)
int CompareAnimSegs(const void *arg1, const void *arg2) int CompareBGSegments(const void *arg1, const void *arg2)
{ {
// arg1 and arg2 are of type Step** // arg1 and arg2 are of type Step**
AnimSeg* seg1 = (AnimSeg*)arg1; BGSegment* seg1 = (BGSegment*)arg1;
AnimSeg* seg2 = (AnimSeg*)arg2; BGSegment* seg2 = (BGSegment*)arg2;
float score1 = seg1->m_fStartBeat; float score1 = seg1->m_fStartBeat;
float score2 = seg2->m_fStartBeat; float score2 = seg2->m_fStartBeat;
@@ -50,15 +50,15 @@ int CompareAnimSegs(const void *arg1, const void *arg2)
return 1; return 1;
} }
void SortAnimSegArray( CArray<AnimSeg,AnimSeg&> &arrayAnimSegs ) void SortBGSegmentArray( CArray<BGSegment,BGSegment&> &arrayBGSegments )
{ {
qsort( arrayAnimSegs.GetData(), arrayAnimSegs.GetSize(), sizeof(AnimSeg), CompareAnimSegs ); qsort( arrayBGSegments.GetData(), arrayBGSegments.GetSize(), sizeof(BGSegment), CompareBGSegments );
} }
Background::Background() Background::Background()
{ {
m_iCurAnimSegment = 0; m_iCurBGSegment = 0;
m_bInDanger = false; m_bInDanger = false;
m_BackgroundMode = MODE_STATIC_BG; m_BackgroundMode = MODE_STATIC_BG;
@@ -123,11 +123,89 @@ void Background::LoadFromSong( Song* pSong )
// Load the static background that will before notes start and after notes end // Load the static background that will before notes start and after notes end
// //
BackgroundAnimation* pTempBGA; BackgroundAnimation* pTempBGA;
pTempBGA = new BackgroundAnimation; pTempBGA = new BackgroundAnimation;
pTempBGA->LoadFromStaticGraphic( pSong->HasBackground() ? pSong->GetBackgroundPath() : THEME->GetPathTo("Graphics","fallback background") ); pTempBGA->LoadFromStaticGraphic( pSong->HasBackground() ? pSong->GetBackgroundPath() : THEME->GetPathTo("Graphics","fallback background") );
m_BackgroundAnimations.Add( pTempBGA ); m_BackgroundAnimations.Add( pTempBGA );
if( pSong->HasBGChanges() )
{
// start off showing the static song background
m_aBGSegments.Add( BGSegment(-10000,0) );
// Load the animations used by the song's pre-defined animation plan.
// the song has a plan. Use it.
for( int i=0; i<pSong->m_BackgroundChanges.GetSize(); i++ )
{
const BackgroundChange& aniseg = pSong->m_BackgroundChanges[i];
// Using aniseg.m_sBGName, search for the corresponding animation.
// Look in this order: movies in song dir, BGAnims in song dir
// movies in RandomMovies dir, BGAnims in BGAnimsDir.
CStringArray asFiles;
// Look for movies in the song dir
GetDirListing( pSong->m_sSongDir+"movies\\"+aniseg.m_sBGName+".avi", asFiles, false, true );
GetDirListing( pSong->m_sSongDir+"movies\\"+aniseg.m_sBGName+".mpg", asFiles, false, true );
GetDirListing( pSong->m_sSongDir+"movies\\"+aniseg.m_sBGName+".mpeg", asFiles, false, true );
if( asFiles.GetSize() > 0 )
{
pTempBGA = new BackgroundAnimation;
pTempBGA->LoadFromMovie( asFiles[0], true, true );
m_BackgroundAnimations.Add( pTempBGA );
m_aBGSegments.Add( BGSegment(aniseg.m_fStartBeat, m_BackgroundAnimations.GetSize()-1) ); // add to the plan
continue; // stop looking for this background
}
// Look for BGAnims in the song dir
GetDirListing( pSong->m_sSongDir+aniseg.m_sBGName, asFiles, true, true );
if( asFiles.GetSize() > 0 )
{
pTempBGA = new BackgroundAnimation;
pTempBGA->LoadFromAniDir( asFiles[0], pSong->HasBackground() ? pSong->GetBackgroundPath() : THEME->GetPathTo("Graphics","fallback background") );
m_BackgroundAnimations.Add( pTempBGA );
m_aBGSegments.Add( BGSegment(aniseg.m_fStartBeat, m_BackgroundAnimations.GetSize()-1) ); // add to the plan
continue; // stop looking for this background
}
// Look for movies in the RandomMovies dir
GetDirListing( RANDOMMOVIES_DIR+aniseg.m_sBGName+".avi", asFiles, false, true );
GetDirListing( RANDOMMOVIES_DIR+aniseg.m_sBGName+".mpg", asFiles, false, true );
GetDirListing( RANDOMMOVIES_DIR+aniseg.m_sBGName+".mpeg", asFiles, false, true );
if( asFiles.GetSize() > 0 )
{
pTempBGA = new BackgroundAnimation;
pTempBGA->LoadFromMovie( asFiles[0], true, false );
m_BackgroundAnimations.Add( pTempBGA );
m_aBGSegments.Add( BGSegment(aniseg.m_fStartBeat, m_BackgroundAnimations.GetSize()-1) ); // add to the plan
continue; // stop looking for this background
}
// Look for BGAnims in the BGAnims dir
GetDirListing( BG_ANIMS_DIR+aniseg.m_sBGName, asFiles, true, true );
if( asFiles.GetSize() > 0 )
{
pTempBGA = new BackgroundAnimation;
pTempBGA->LoadFromAniDir( asFiles[0], pSong->HasBackground() ? pSong->GetBackgroundPath() : THEME->GetPathTo("Graphics","fallback background") );
m_BackgroundAnimations.Add( pTempBGA );
m_aBGSegments.Add( BGSegment(aniseg.m_fStartBeat, m_BackgroundAnimations.GetSize()-1) ); // add to the plan
continue; // stop looking for this background
}
}
// end showing the static song background
m_aBGSegments.Add( BGSegment(pSong->m_fLastBeat,0) );
SortBGSegmentArray( m_aBGSegments ); // Need to sort in case the song has a background change after the last beat
}
else // pSong doesn't have an animation plan
{
// //
// Load animations that will play while notes are active // Load animations that will play while notes are active
// //
@@ -138,7 +216,7 @@ void Background::LoadFromSong( Song* pSong )
case MODE_MOVIE_BG: case MODE_MOVIE_BG:
{ {
pTempBGA = new BackgroundAnimation; pTempBGA = new BackgroundAnimation;
pTempBGA->LoadFromMovieBG( pSong->GetMovieBackgroundPath() ); pTempBGA->LoadFromMovie( pSong->GetMovieBackgroundPath(), false, true );
m_BackgroundAnimations.Add( pTempBGA ); m_BackgroundAnimations.Add( pTempBGA );
} }
break; break;
@@ -182,7 +260,7 @@ void Background::LoadFromSong( Song* pSong )
{ {
int index = rand() % arrayPossibleMovies.GetSize(); int index = rand() % arrayPossibleMovies.GetSize();
pTempBGA = new BackgroundAnimation; pTempBGA = new BackgroundAnimation;
pTempBGA->LoadFromRandomMovie( arrayPossibleMovies[index] ); pTempBGA->LoadFromMovie( arrayPossibleMovies[index], true, false );
m_BackgroundAnimations.Add( pTempBGA ); m_BackgroundAnimations.Add( pTempBGA );
arrayPossibleMovies.RemoveAt( index ); arrayPossibleMovies.RemoveAt( index );
} }
@@ -192,6 +270,7 @@ void Background::LoadFromSong( Song* pSong )
ASSERT(0); ASSERT(0);
} }
// At this point, m_BackgroundAnimations[0] is the song background, and everything else // At this point, m_BackgroundAnimations[0] is the song background, and everything else
// in m_BackgroundAnimations should be cycled through randomly while notes are playing. // in m_BackgroundAnimations should be cycled through randomly while notes are playing.
// //
@@ -199,12 +278,12 @@ void Background::LoadFromSong( Song* pSong )
// //
if( m_BackgroundMode == MODE_MOVIE_VIS ) if( m_BackgroundMode == MODE_MOVIE_VIS )
{ {
m_aAnimSegs.Add( AnimSeg(-10000,1) ); m_aBGSegments.Add( BGSegment(-10000,1) );
return; return;
} }
// start off showing the static song background // start off showing the static song background
m_aAnimSegs.Add( AnimSeg(-10000,0) ); m_aBGSegments.Add( BGSegment(-10000,0) );
// change BG every 4 bars // change BG every 4 bars
const float fFirstBeat = m_BackgroundMode==MODE_MOVIE_BG ? 0 : pSong->m_fFirstBeat; const float fFirstBeat = m_BackgroundMode==MODE_MOVIE_BG ? 0 : pSong->m_fFirstBeat;
@@ -216,7 +295,7 @@ void Background::LoadFromSong( Song* pSong )
index = 0; index = 0;
else else
index = 1 + rand()%(m_BackgroundAnimations.GetSize()-1); index = 1 + rand()%(m_BackgroundAnimations.GetSize()-1);
m_aAnimSegs.Add( AnimSeg(f,index) ); m_aBGSegments.Add( BGSegment(f,index) );
} }
// change BG every BPM change // change BG every BPM change
@@ -232,46 +311,19 @@ void Background::LoadFromSong( Song* pSong )
index = 0; index = 0;
else else
index = 1 + int(bpmseg.m_fBPM)%(m_BackgroundAnimations.GetSize()-1); index = 1 + int(bpmseg.m_fBPM)%(m_BackgroundAnimations.GetSize()-1);
m_aAnimSegs.Add( AnimSeg(bpmseg.m_fStartBeat,index) ); m_aBGSegments.Add( BGSegment(bpmseg.m_fStartBeat,index) );
} }
// end showing the static song background // end showing the static song background
m_aAnimSegs.Add( AnimSeg(pSong->m_fLastBeat,0) ); m_aBGSegments.Add( BGSegment(pSong->m_fLastBeat,0) );
// sort segments // sort segments
SortAnimSegArray( m_aAnimSegs ); SortBGSegmentArray( m_aBGSegments );
// for( int i=0; i<m_aAnimSegs.GetSize(); i++ )
// printf("AnimSeg %d: %f, %i\n", i, m_aAnimSegs[i].m_fStartBeat, m_aAnimSegs[i].m_iAnimationIndex);
/*
// Load the song's pre-defined animation plan.
// TODO: Fix this
// Load a background animation plan into m_aAnimSegs
if( pSong->m_AnimationSegments.GetSize() > 0 )
{
// the song has a plan. Use it.
for( int i=0; i<pSong->m_AnimationSegments.GetSize(); i++ )
{
const AnimationSegment& aniseg = pSong->m_AnimationSegments[i];
int iIndex = -1;
for( int j=0; j<asBGAnimNames.GetSize(); j++ )
{
if( asBGAnimNames[j] == aniseg.m_sAnimationName )
{
iIndex = j;
break;
} }
}
if( iIndex == -1 ) // this animation doesn't exist in the song dir
iIndex = rand() % m_BackgroundAnimations.GetSize(); // use a random one instead
m_aAnimSegs.Add( AnimSeg(aniseg.m_fStartBeat, iIndex) );
}
SortAnimSegArray( m_aAnimSegs ); // this should already be sorted
*/
} }
@@ -289,17 +341,17 @@ void Background::Update( float fDeltaTime )
if( GAMESTATE->m_bFreeze ) if( GAMESTATE->m_bFreeze )
return; return;
// Find the AnimSeg we're in // Find the BGSegment we're in
for( int i=0; i<m_aAnimSegs.GetSize()-1; i++ ) for( int i=0; i<m_aBGSegments.GetSize()-1; i++ )
if( GAMESTATE->m_fSongBeat < m_aAnimSegs[i+1].m_fStartBeat ) if( GAMESTATE->m_fSongBeat < m_aBGSegments[i+1].m_fStartBeat )
break; break;
ASSERT( i >= 0 && i<m_aAnimSegs.GetSize() ); ASSERT( i >= 0 && i<m_aBGSegments.GetSize() );
if( i > m_iCurAnimSegment ) if( i > m_iCurBGSegment )
{ {
// printf( "%d, %d, %f, %f\n", m_iCurAnimSegment, i, m_aAnimSegs[i].m_fStartBeat, GAMESTATE->m_fSongBeat ); // printf( "%d, %d, %f, %f\n", m_iCurBGSegment, i, m_aBGSegments[i].m_fStartBeat, GAMESTATE->m_fSongBeat );
GetCurBGA()->LosingFocus(); GetCurBGA()->LosingFocus();
m_iCurAnimSegment = i; m_iCurBGSegment = i;
GetCurBGA()->GainingFocus(); GetCurBGA()->GainingFocus();
} }
+7 -7
View File
@@ -19,12 +19,12 @@
#include "BackgroundAnimation.h" #include "BackgroundAnimation.h"
struct AnimSeg struct BGSegment // like a BGChange, but holds index of a background instead of name
{ {
AnimSeg() {}; BGSegment() {};
AnimSeg( float b, int i ) { m_fStartBeat = b; m_iAnimationIndex = i; }; BGSegment( float b, int i ) { m_fStartBeat = b; m_iBGIndex = i; };
float m_fStartBeat; float m_fStartBeat;
int m_iAnimationIndex; int m_iBGIndex;
}; };
@@ -61,9 +61,9 @@ protected:
// used in all BackgroundModes except OFF // used in all BackgroundModes except OFF
CArray<BackgroundAnimation*,BackgroundAnimation*> m_BackgroundAnimations; CArray<BackgroundAnimation*,BackgroundAnimation*> m_BackgroundAnimations;
CArray<AnimSeg,AnimSeg&> m_aAnimSegs; CArray<BGSegment,BGSegment&> m_aBGSegments;
int m_iCurAnimSegment; // this increases as we move into new segments int m_iCurBGSegment; // this increases as we move into new segments
BackgroundAnimation* GetCurBGA() { int index = m_aAnimSegs[m_iCurAnimSegment].m_iAnimationIndex; return m_BackgroundAnimations[index]; }; BackgroundAnimation* GetCurBGA() { int index = m_aBGSegments[m_iCurBGSegment].m_iBGIndex; return m_BackgroundAnimations[index]; };
Quad m_quadBGBrightness; Quad m_quadBGBrightness;
-1
View File
@@ -70,7 +70,6 @@ void GameState::Reset()
m_fSecondsBeforeFail[p] = -1; m_fSecondsBeforeFail[p] = -1;
m_iSongsBeforeFail[p] = 0; m_iSongsBeforeFail[p] = 0;
} }
m_bUsedAutoPlayer = false;
for( p=0; p<NUM_PLAYERS; p++ ) for( p=0; p<NUM_PLAYERS; p++ )
-1
View File
@@ -116,7 +116,6 @@ public:
CArray<Song*,Song*> m_apSongsPlayed; // an array of completed songs. CArray<Song*,Song*> m_apSongsPlayed; // an array of completed songs.
// This is useful for the final evaluation screen, // This is useful for the final evaluation screen,
// and used to calculate the time into a course // and used to calculate the time into a course
bool m_bUsedAutoPlayer; // Used autoplayer at any time during any stage/course/song
// Only used in final evaluation screen in play mode Arcade. // Only used in final evaluation screen in play mode Arcade.
// Before being displayed, these values should be normalized by dividing by number of stages // Before being displayed, these values should be normalized by dividing by number of stages
+1
View File
@@ -29,6 +29,7 @@ public:
virtual void SongEnded() {}; virtual void SongEnded() {};
virtual void ChangeLife( TapNoteScore score ) = 0; virtual void ChangeLife( TapNoteScore score ) = 0;
virtual void ChangeLife( HoldNoteScore score ) = 0;
virtual void OnDancePointsChange() = 0; // look in GAMESTATE and update the display virtual void OnDancePointsChange() = 0; // look in GAMESTATE and update the display
virtual bool IsInDanger() = 0; virtual bool IsInDanger() = 0;
virtual bool IsHot() = 0; virtual bool IsHot() = 0;
+7 -2
View File
@@ -46,8 +46,8 @@ LifeMeterBar::LifeMeterBar()
m_fDangerThreshold = DANGER_THRESHOLD; m_fDangerThreshold = DANGER_THRESHOLD;
m_quadBlackBackground.SetDiffuseColor( D3DXCOLOR(0,0,0,1) ); m_quadBlackBackground.SetDiffuseColor( D3DXCOLOR(0,0,0,1) );
m_quadBlackBackground.SetZoomX( m_iMeterWidth ); m_quadBlackBackground.SetZoomX( (float)m_iMeterWidth );
m_quadBlackBackground.SetZoomY( m_iMeterHeight ); m_quadBlackBackground.SetZoomY( (float)m_iMeterHeight );
m_frame.AddSubActor( &m_quadBlackBackground ); m_frame.AddSubActor( &m_quadBlackBackground );
m_sprStreamNormal.Load( THEME->GetPathTo("Graphics","gameplay lifemeter stream normal") ); m_sprStreamNormal.Load( THEME->GetPathTo("Graphics","gameplay lifemeter stream normal") );
@@ -129,6 +129,11 @@ void LifeMeterBar::ChangeLife( TapNoteScore score )
ResetBarVelocity(); ResetBarVelocity();
} }
void LifeMeterBar::ChangeLife( HoldNoteScore score )
{
// do nothing
}
void LifeMeterBar::ResetBarVelocity() void LifeMeterBar::ResetBarVelocity()
{ {
// update bar animation // update bar animation
+1
View File
@@ -26,6 +26,7 @@ public:
virtual void DrawPrimitives(); virtual void DrawPrimitives();
virtual void ChangeLife( TapNoteScore score ); virtual void ChangeLife( TapNoteScore score );
virtual void ChangeLife( HoldNoteScore score );
virtual void OnDancePointsChange() {}; // this life meter doesn't care virtual void OnDancePointsChange() {}; // this life meter doesn't care
virtual bool IsInDanger(); virtual bool IsInDanger();
virtual bool IsHot(); virtual bool IsHot();
+5
View File
@@ -125,6 +125,11 @@ void LifeMeterBattery::ChangeLife( TapNoteScore score )
m_bFailedEarlier = true; m_bFailedEarlier = true;
} }
void LifeMeterBattery::ChangeLife( HoldNoteScore score )
{
// do nothing
}
void LifeMeterBattery::OnDancePointsChange() void LifeMeterBattery::OnDancePointsChange()
{ {
int iActualDancePoints = GAMESTATE->m_iActualDancePoints[m_PlayerNumber]; int iActualDancePoints = GAMESTATE->m_iActualDancePoints[m_PlayerNumber];
+1
View File
@@ -28,6 +28,7 @@ public:
virtual void SongEnded(); virtual void SongEnded();
virtual void ChangeLife( TapNoteScore score ); virtual void ChangeLife( TapNoteScore score );
virtual void ChangeLife( HoldNoteScore score );
virtual void OnDancePointsChange(); // look in GAMESTATE and update the display virtual void OnDancePointsChange(); // look in GAMESTATE and update the display
virtual bool IsInDanger(); virtual bool IsInDanger();
virtual bool IsHot(); virtual bool IsHot();
+54 -45
View File
@@ -104,48 +104,21 @@ CString NoteData::GetSMNoteDataString()
for( int m=0; m<=iLastMeasure; m++ ) // foreach measure for( int m=0; m<=iLastMeasure; m++ ) // foreach measure
{ {
int iMeasureStartIndex = m * ELEMENTS_PER_MEASURE; NoteType nt = GetSmallestNoteTypeForMeasure( m );
int iMeasureLastIndex = (m+1) * ELEMENTS_PER_MEASURE - 1;
// probe to find the smallest note type
NoteType nt;
int iNoteIndexSpacing;
for( nt=(NoteType)0; nt<NUM_NOTE_TYPES; nt=NoteType(nt+1) )
{
float fBeatSpacing = NoteTypeToBeat( nt ); float fBeatSpacing = NoteTypeToBeat( nt );
iNoteIndexSpacing = roundf( fBeatSpacing * ELEMENTS_PER_BEAT ); int iRowSpacing = roundf( fBeatSpacing * ROWS_PER_BEAT );
bool bFoundSmallerNote = false;
for( int i=iMeasureStartIndex; i<=iMeasureLastIndex; i++ ) // for each index in this measure
{
if( i % iNoteIndexSpacing == 0 )
continue; // skip
if( !IsRowEmpty(i) )
{
bFoundSmallerNote = true;
break;
}
}
if( bFoundSmallerNote )
continue; // keep searching
else
break; // stop searching
}
if( nt == NUM_NOTE_TYPES ) // we didn't find one
iNoteIndexSpacing = 1;
CStringArray asMeasureLines; CStringArray asMeasureLines;
asMeasureLines.Add( ssprintf(" // measure %d", m+1) ); asMeasureLines.Add( ssprintf(" // measure %d", m+1) );
for( int i=iMeasureStartIndex; i<=iMeasureLastIndex; i+=iNoteIndexSpacing ) const int iMeasureStartRow = m * ROWS_PER_MEASURE;
const int iMeasureLastRow = (m+1) * ROWS_PER_MEASURE - 1;
for( int r=iMeasureStartRow; r<=iMeasureLastRow; r+=iRowSpacing )
{ {
char szLineString[MAX_NOTE_TRACKS]; char szLineString[MAX_NOTE_TRACKS];
for( int t=0; t<m_iNumTracks; t++ ) for( int t=0; t<m_iNumTracks; t++ )
szLineString[t] = m_TapNotes[t][i]; szLineString[t] = m_TapNotes[t][r];
szLineString[t] = '\0'; szLineString[t] = '\0';
asMeasureLines.Add( szLineString ); asMeasureLines.Add( szLineString );
} }
@@ -610,7 +583,7 @@ void NoteData::MakeLittle()
// filter out all non-quarter notes // filter out all non-quarter notes
for( int i=0; i<MAX_TAP_NOTE_ROWS; i++ ) for( int i=0; i<MAX_TAP_NOTE_ROWS; i++ )
{ {
if( i%ELEMENTS_PER_BEAT != 0 ) if( i%ROWS_PER_BEAT != 0 )
{ {
// filter out all non-quarter notes // filter out all non-quarter notes
for( int c=0; c<m_iNumTracks; c++ ) for( int c=0; c<m_iNumTracks; c++ )
@@ -669,20 +642,20 @@ void NoteData::SnapToNearestNoteType( NoteType nt1, NoteType nt2, float fBeginBe
float fSnapInterval1, fSnapInterval2; float fSnapInterval1, fSnapInterval2;
switch( nt1 ) switch( nt1 )
{ {
case NOTE_4TH: fSnapInterval1 = 1/1.0f; break; case NOTE_TYPE_4TH: fSnapInterval1 = 1/1.0f; break;
case NOTE_8TH: fSnapInterval1 = 1/2.0f; break; case NOTE_TYPE_8TH: fSnapInterval1 = 1/2.0f; break;
case NOTE_12TH: fSnapInterval1 = 1/3.0f; break; case NOTE_TYPE_12TH: fSnapInterval1 = 1/3.0f; break;
case NOTE_16TH: fSnapInterval1 = 1/4.0f; break; case NOTE_TYPE_16TH: fSnapInterval1 = 1/4.0f; break;
default: ASSERT( false ); default: ASSERT( false );
} }
switch( nt2 ) switch( nt2 )
{ {
case NOTE_4TH: fSnapInterval2 = 1/1.0f; break; case NOTE_TYPE_4TH: fSnapInterval2 = 1/1.0f; break;
case NOTE_8TH: fSnapInterval2 = 1/2.0f; break; case NOTE_TYPE_8TH: fSnapInterval2 = 1/2.0f; break;
case NOTE_12TH: fSnapInterval2 = 1/3.0f; break; case NOTE_TYPE_12TH: fSnapInterval2 = 1/3.0f; break;
case NOTE_16TH: fSnapInterval2 = 1/4.0f; break; case NOTE_TYPE_16TH: fSnapInterval2 = 1/4.0f; break;
case -1: fSnapInterval2 = 10000; break; // nothing will ever snap to this. That is good! case -1: fSnapInterval2 = 10000; break; // nothing will ever snap to this. That's what we want!
default: ASSERT( false ); default: ASSERT( false );
} }
@@ -758,7 +731,7 @@ float NoteData::GetChaosRadarValue( float fSongSeconds )
int iNumChaosNotes = 0; int iNumChaosNotes = 0;
for( int r=0; r<MAX_TAP_NOTE_ROWS; r++ ) for( int r=0; r<MAX_TAP_NOTE_ROWS; r++ )
{ {
if( !IsRowEmpty(r) && GetNoteType(r) >= NOTE_12TH ) if( !IsRowEmpty(r) && GetNoteType(r) >= NOTE_TYPE_12TH )
iNumChaosNotes++; iNumChaosNotes++;
} }
@@ -804,3 +777,39 @@ void NoteData::LoadTransformed( const NoteData* pOriginal, int iNewNumTracks, co
} }
NoteType NoteData::GetSmallestNoteTypeForMeasure( int iMeasureIndex )
{
const int iMeasureStartIndex = iMeasureIndex * ROWS_PER_MEASURE;
const int iMeasureLastIndex = (iMeasureIndex+1) * ROWS_PER_MEASURE - 1;
// probe to find the smallest note type
NoteType nt;
for( nt=(NoteType)0; nt<NUM_NOTE_TYPES; nt=NoteType(nt+1) ) // for each NoteType, largest to largest
{
float fBeatSpacing = NoteTypeToBeat( nt );
int iRowSpacing = roundf( fBeatSpacing * ROWS_PER_BEAT );
bool bFoundSmallerNote = false;
for( int i=iMeasureStartIndex; i<=iMeasureLastIndex; i++ ) // for each index in this measure
{
if( i % iRowSpacing == 0 )
continue; // skip
if( !IsRowEmpty(i) )
{
bFoundSmallerNote = true;
break;
}
}
if( bFoundSmallerNote )
continue; // searching the next NoteType
else
break; // stop searching. We found the smallest NoteType
}
if( nt == NUM_NOTE_TYPES ) // we didn't find one
return NOTE_TYPE_INVALID; // well-formed notes created in the editor should never get here
else
return nt;
}
+2
View File
@@ -98,6 +98,8 @@ public:
void SnapToNearestNoteType( NoteType nt1, NoteType nt2, float fBeginBeat, float fEndBeat ); void SnapToNearestNoteType( NoteType nt1, NoteType nt2, float fBeginBeat, float fEndBeat );
NoteType GetSmallestNoteTypeForMeasure( int iMeasureIndex );
// Convert between HoldNote representation and '2' and '3' markers in TapNotes // Convert between HoldNote representation and '2' and '3' markers in TapNotes
void Convert2sAnd3sToHoldNotes(); void Convert2sAnd3sToHoldNotes();
void ConvertHoldNotesTo2sAnd3s(); void ConvertHoldNotesTo2sAnd3s();
+1 -1
View File
@@ -140,7 +140,7 @@ float NoteDataWithScoring::GetActualChaosRadarValue( float fSongSeconds )
int iNumChaosNotesCompleted = 0; int iNumChaosNotesCompleted = 0;
for( int r=0; r<MAX_TAP_NOTE_ROWS; r++ ) for( int r=0; r<MAX_TAP_NOTE_ROWS; r++ )
{ {
if( !IsRowEmpty(r) && IsRowComplete(r) && GetNoteType(r) >= NOTE_12TH ) if( !IsRowEmpty(r) && IsRowComplete(r) && GetNoteType(r) >= NOTE_TYPE_12TH )
iNumChaosNotesCompleted++; iNumChaosNotesCompleted++;
} }
+3 -3
View File
@@ -498,9 +498,9 @@ void NoteDisplay::DrawList( int iCount, NoteDisplayInstance cni[], bool bDrawAdd
void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float fLife, const float fPercentFadeToFail ) void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float fLife, const float fPercentFadeToFail )
{ {
const int iCol = hn.m_iTrack; const int iCol = hn.m_iTrack;
const float fStartYOffset = ArrowGetYOffset2( m_PlayerNumber, hn.m_fStartBeat ); const float fStartYOffset = ArrowGetYOffset( m_PlayerNumber, hn.m_fStartBeat );
const float fStartYPos = ArrowGetYPos( m_PlayerNumber, fStartYOffset ); const float fStartYPos = ArrowGetYPos( m_PlayerNumber, fStartYOffset );
const float fEndYOffset = ArrowGetYOffset2( m_PlayerNumber, hn.m_fEndBeat ); const float fEndYOffset = ArrowGetYOffset( m_PlayerNumber, hn.m_fEndBeat );
const float fEndYPos = ArrowGetYPos( m_PlayerNumber, fEndYOffset ); const float fEndYPos = ArrowGetYPos( m_PlayerNumber, fEndYOffset );
// draw from bottom to top // draw from bottom to top
@@ -624,7 +624,7 @@ void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float
void NoteDisplay::DrawTap( const int iCol, const float fBeat, const bool bUseHoldColor, const float fPercentFadeToFail ) void NoteDisplay::DrawTap( const int iCol, const float fBeat, const bool bUseHoldColor, const float fPercentFadeToFail )
{ {
const float fYOffset = ArrowGetYOffset2( m_PlayerNumber, fBeat ); const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat );
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
const float fRotation = ArrowGetRotation( m_PlayerNumber, iCol, fYOffset ); const float fRotation = ArrowGetRotation( m_PlayerNumber, iCol, fYOffset );
const float fXPos = ArrowGetXPos2( m_PlayerNumber, iCol, fYPos ); const float fXPos = ArrowGetXPos2( m_PlayerNumber, iCol, fYPos );
+27 -59
View File
@@ -23,7 +23,7 @@
const float HOLD_NOTE_BITS_PER_BEAT = 6; const float HOLD_NOTE_BITS_PER_BEAT = 6;
const float HOLD_NOTE_BITS_PER_ROW = HOLD_NOTE_BITS_PER_BEAT / ELEMENTS_PER_BEAT; const float HOLD_NOTE_BITS_PER_ROW = HOLD_NOTE_BITS_PER_BEAT / ROWS_PER_BEAT;
const float ROWS_BETWEEN_HOLD_BITS = 1 / HOLD_NOTE_BITS_PER_ROW; const float ROWS_BETWEEN_HOLD_BITS = 1 / HOLD_NOTE_BITS_PER_ROW;
NoteField::NoteField() NoteField::NoteField()
@@ -120,7 +120,7 @@ void NoteField::DrawMeasureBar( int iMeasureIndex )
const int iMeasureNoDisplay = iMeasureIndex+1; const int iMeasureNoDisplay = iMeasureIndex+1;
const float fBeat = float(iMeasureIndex * BEATS_PER_MEASURE); const float fBeat = float(iMeasureIndex * BEATS_PER_MEASURE);
const float fYOffset = ArrowGetYOffset2( m_PlayerNumber, fBeat ); const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat );
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
m_rectMeasureBar.SetXY( 0, fYPos ); m_rectMeasureBar.SetXY( 0, fYPos );
@@ -138,7 +138,7 @@ void NoteField::DrawMeasureBar( int iMeasureIndex )
void NoteField::DrawMarkerBar( const float fBeat ) void NoteField::DrawMarkerBar( const float fBeat )
{ {
const float fYOffset = ArrowGetYOffset2( m_PlayerNumber, fBeat ); const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat );
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
m_rectMarkerBar.SetXY( 0, fYPos ); m_rectMarkerBar.SetXY( 0, fYPos );
@@ -150,7 +150,7 @@ void NoteField::DrawMarkerBar( const float fBeat )
void NoteField::DrawBPMText( const float fBeat, const float fBPM ) void NoteField::DrawBPMText( const float fBeat, const float fBPM )
{ {
const float fYOffset = ArrowGetYOffset2( m_PlayerNumber, fBeat ); const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat );
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
m_textMeasureNumber.SetDiffuseColor( D3DXCOLOR(1,0,0,1) ); m_textMeasureNumber.SetDiffuseColor( D3DXCOLOR(1,0,0,1) );
@@ -162,7 +162,7 @@ void NoteField::DrawBPMText( const float fBeat, const float fBPM )
void NoteField::DrawFreezeText( const float fBeat, const float fSecs ) void NoteField::DrawFreezeText( const float fBeat, const float fSecs )
{ {
const float fYOffset = ArrowGetYOffset2( m_PlayerNumber, fBeat ); const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat );
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset ); const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
m_textMeasureNumber.SetDiffuseColor( D3DXCOLOR(0.8f,0.8f,0,1) ); m_textMeasureNumber.SetDiffuseColor( D3DXCOLOR(0.8f,0.8f,0,1) );
@@ -172,6 +172,18 @@ void NoteField::DrawFreezeText( const float fBeat, const float fSecs )
m_textMeasureNumber.Draw(); m_textMeasureNumber.Draw();
} }
void NoteField::DrawBGChangeText( const float fBeat, const CString sNewBGName )
{
const float fYOffset = ArrowGetYOffset( m_PlayerNumber, fBeat );
const float fYPos = ArrowGetYPos( m_PlayerNumber, fYOffset );
m_textMeasureNumber.SetDiffuseColor( D3DXCOLOR(0,1,0,1) );
m_textMeasureNumber.SetGlowColor( D3DXCOLOR(1,1,1,cosf(TIMER->GetTimeSinceStart()*2)/2+0.5f) );
m_textMeasureNumber.SetText( sNewBGName );
m_textMeasureNumber.SetXY( +m_rectMeasureBar.GetZoomedWidth()/2 + 10, fYPos );
m_textMeasureNumber.Draw();
}
void NoteField::DrawPrimitives() void NoteField::DrawPrimitives()
{ {
//LOG->Trace( "NoteField::DrawPrimitives()" ); //LOG->Trace( "NoteField::DrawPrimitives()" );
@@ -213,6 +225,13 @@ void NoteField::DrawPrimitives()
for( i=0; i<aStopSegments.GetSize(); i++ ) for( i=0; i<aStopSegments.GetSize(); i++ )
DrawFreezeText( aStopSegments[i].m_fStartBeat, aStopSegments[i].m_fStopSeconds ); DrawFreezeText( aStopSegments[i].m_fStartBeat, aStopSegments[i].m_fStopSeconds );
//
// BGChange text
//
CArray<BackgroundChange,BackgroundChange&> &aBackgroundChanges = GAMESTATE->m_pCurSong->m_BackgroundChanges;
for( i=0; i<aBackgroundChanges.GetSize(); i++ )
DrawBGChangeText( aBackgroundChanges[i].m_fStartBeat, aBackgroundChanges[i].m_sBGName );
// //
// Draw marker bars // Draw marker bars
// //
@@ -225,30 +244,13 @@ void NoteField::DrawPrimitives()
// //
// Optimization is very important here because there are so many arrows to draw. We're going // Optimization is very important here because there are so many arrows to draw.
// to draw the arrows in order of column. This will let us fill up a vertex buffer of arrows // Draw the arrows in order of column. This minimize texture switches and let us
// so we can draw them in one swoop without texture or state changes. // draw in big batches.
// //
// Change: Optimization made this code very unreadable and unmanagable, so we're going to
// try a more global, higher-level optimization. Our goal is to make fewer calls to
// DrawPrimitive. Instead of filling the vertex buffer all at once (the old optimization)
// we'll add something to Display that will automatically group together DrawPrimitive
// calls as long as the texture or render states have not changed.
//
// To mimimize state and texture changes, we're going to draw one column at a time:
// HoldNotes, then TapNotes.
//
for( int c=0; c<m_iNumTracks; c++ ) // for each arrow column for( int c=0; c<m_iNumTracks; c++ ) // for each arrow column
{ {
// const int MAX_COLOR_NOTE_INSTANCES = 300;
// ColorNoteInstance instances[MAX_COLOR_NOTE_INSTANCES];
// int iCount = 0; // number of valid elements in the instances array
///////////////////////////////// /////////////////////////////////
// Draw all HoldNotes in this column (so that they appear under the tap notes) // Draw all HoldNotes in this column (so that they appear under the tap notes)
///////////////////////////////// /////////////////////////////////
@@ -275,38 +277,8 @@ void NoteField::DrawPrimitives()
m_NoteDisplay[c].DrawHold( hn, bIsHoldingNote, fLife, m_fPercentFadeToFail ); m_NoteDisplay[c].DrawHold( hn, bIsHoldingNote, fLife, m_fPercentFadeToFail );
// // If this note was in the past and has life > 0, then it was completed and don't draw it!
// if( hn.m_iEndIndex < BeatToNoteRow(fSongBeat) && fLife > 0 && m_bIsHoldingHoldNote[i] )
// continue; // skip
/*
// parts of the hold
const float fStartDrawingAtBeat = froundf( (float)hn.m_iStartIndex, ROWS_BETWEEN_HOLD_BITS/GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_fArrowScrollSpeed );
for( float j=fStartDrawingAtBeat;
j<=hn.m_iEndIndex;
j+=ROWS_BETWEEN_HOLD_BITS/GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_fArrowScrollSpeed ) // for each bit of the hold
{
// check if this arrow is off the the screen
if( j < iIndexFirstArrowToDraw || iIndexLastArrowToDraw < j)
continue; // skip this arrow
if( bActive && NoteRowToBeat(j) < fSongBeat )
continue;
CreateHoldNoteInstance( instances[iCount++], bActive, (float)j, hn, fHoldNoteLife );
}
*/
} }
// const bool bDrawAddPass = GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_AppearanceType != PlayerOptions::APPEARANCE_VISIBLE;
// if( iCount > 0 )
// m_ColorNote[c].DrawList( iCount, instances, bDrawAddPass );
// iCount = 0; // reset count
/////////////////////////////////// ///////////////////////////////////
// Draw all TapNotes in this column // Draw all TapNotes in this column
@@ -330,8 +302,6 @@ void NoteField::DrawPrimitives()
} }
} }
m_NoteDisplay[c].DrawTap( c, NoteRowToBeat(i), bHoldNoteBeginsOnThisBeat, m_fPercentFadeToFail ); m_NoteDisplay[c].DrawTap( c, NoteRowToBeat(i), bHoldNoteBeginsOnThisBeat, m_fPercentFadeToFail );
} }
} }
@@ -339,8 +309,6 @@ void NoteField::DrawPrimitives()
} }
void NoteField::RemoveTapNoteRow( int iIndex ) void NoteField::RemoveTapNoteRow( int iIndex )
{ {
for( int c=0; c<m_iNumTracks; c++ ) for( int c=0; c<m_iNumTracks; c++ )
+5 -6
View File
@@ -41,12 +41,11 @@ public:
void FadeToFail(); void FadeToFail();
protected: protected:
// inline void CreateTapNoteInstance( ColorNoteInstance &cni, const int iCol, const float fIndex, const bool bUseHoldNoteBeginColor = false ); void DrawMeasureBar( const int iMeasureIndex );
// inline void CreateHoldNoteInstance( ColorNoteInstance &cni, const bool bActive, const float fIndex, const HoldNote &hn, const float fHoldNoteLife ); void DrawMarkerBar( const float fBeat );
inline void DrawMeasureBar( const int iMeasureIndex ); void DrawBPMText( const float fBeat, const float fBPM );
inline void DrawMarkerBar( const float fBeat ); void DrawFreezeText( const float fBeat, const float fBPM );
inline void DrawBPMText( const float fBeat, const float fBPM ); void DrawBGChangeText( const float fBeat, const CString sNewBGName );
inline void DrawFreezeText( const float fBeat, const float fBPM );
float m_fPercentFadeToFail; // -1 of not fading to fail float m_fPercentFadeToFail; // -1 of not fading to fail
+14 -19
View File
@@ -16,11 +16,11 @@ D3DXCOLOR NoteTypeToColor( NoteType nt )
{ {
switch( nt ) switch( nt )
{ {
case NOTE_4TH: return D3DXCOLOR(1,0,0,1); // red case NOTE_TYPE_4TH: return D3DXCOLOR(1,0,0,1); // red
case NOTE_8TH: return D3DXCOLOR(0,0,1,1); // blue case NOTE_TYPE_8TH: return D3DXCOLOR(0,0,1,1); // blue
case NOTE_12TH: return D3DXCOLOR(1,0,1,1); // purple case NOTE_TYPE_12TH: return D3DXCOLOR(1,0,1,1); // purple
case NOTE_16TH: return D3DXCOLOR(1,1,0,1); // yellow case NOTE_TYPE_16TH: return D3DXCOLOR(1,1,0,1); // yellow
default: ASSERT( false ); return D3DXCOLOR(1,1,1,1); default: ASSERT( 0 );return D3DXCOLOR(0.5f,0.5f,0.5f,1);
} }
}; };
@@ -28,26 +28,21 @@ float NoteTypeToBeat( NoteType nt )
{ {
switch( nt ) switch( nt )
{ {
case NOTE_4TH: return 1.0f; // quarter notes case NOTE_TYPE_4TH: return 1.0f; // quarter notes
case NOTE_8TH: return 1.0f/2; // eighth notes case NOTE_TYPE_8TH: return 1.0f/2; // eighth notes
case NOTE_12TH: return 1.0f/3; // triplets case NOTE_TYPE_12TH: return 1.0f/3; // triplets
case NOTE_16TH: return 1.0f/4; // sixteenth notes case NOTE_TYPE_16TH: return 1.0f/4; // sixteenth notes
default: ASSERT( false ); return 0; default: ASSERT( false ); return 0;
} }
} }
NoteType GetNoteType( int iNoteIndex ) NoteType GetNoteType( int iNoteIndex )
{ {
if( iNoteIndex % (ELEMENTS_PER_MEASURE/4) == 0) if( iNoteIndex % (ROWS_PER_MEASURE/4) == 0) return NOTE_TYPE_4TH;
return NOTE_4TH; else if( iNoteIndex % (ROWS_PER_MEASURE/8) == 0) return NOTE_TYPE_8TH;
else if( iNoteIndex % (ELEMENTS_PER_MEASURE/8) == 0) else if( iNoteIndex % (ROWS_PER_MEASURE/12) == 0) return NOTE_TYPE_12TH;
return NOTE_8TH; else if( iNoteIndex % (ROWS_PER_MEASURE/16) == 0) return NOTE_TYPE_16TH;
else if( iNoteIndex % (ELEMENTS_PER_MEASURE/12) == 0) else return NOTE_TYPE_INVALID;
return NOTE_12TH;
else if( iNoteIndex % (ELEMENTS_PER_MEASURE/16) == 0)
return NOTE_16TH;
// ASSERT(0);
return NOTE_INVALID;
}; };
bool IsNoteOfType( int iNoteIndex, NoteType t ) bool IsNoteOfType( int iNoteIndex, NoteType t )
+11 -11
View File
@@ -43,20 +43,20 @@ const int MAX_BEATS = 1500; // BMR's Pulse has about 1300
const int BEATS_PER_MEASURE = 4; const int BEATS_PER_MEASURE = 4;
const int MAX_MEASURES = MAX_BEATS / BEATS_PER_MEASURE; const int MAX_MEASURES = MAX_BEATS / BEATS_PER_MEASURE;
const int ELEMENTS_PER_BEAT = 12; // It is important that this number is evenly divisible by 2, 3, and 4. const int ROWS_PER_BEAT = 12; // It is important that this number is evenly divisible by 2, 3, and 4.
const int ELEMENTS_PER_MEASURE = ELEMENTS_PER_BEAT * BEATS_PER_MEASURE; const int ROWS_PER_MEASURE = ROWS_PER_BEAT * BEATS_PER_MEASURE;
const int MAX_TAP_NOTE_ROWS = MAX_BEATS*ELEMENTS_PER_BEAT; const int MAX_TAP_NOTE_ROWS = MAX_BEATS*ROWS_PER_BEAT;
const int MAX_HOLD_NOTES = 400; // BMR's Connected has about 300 const int MAX_HOLD_NOTES = 400; // BMR's Connected has about 300
enum NoteType enum NoteType
{ {
NOTE_4TH, // quarter notes NOTE_TYPE_4TH, // quarter note
NOTE_8TH, // eighth notes NOTE_TYPE_8TH, // eighth note
NOTE_12TH, // triplets NOTE_TYPE_12TH, // triplet
NOTE_16TH, // sixteenth notes NOTE_TYPE_16TH, // sixteenth note
NUM_NOTE_TYPES, NUM_NOTE_TYPES,
NOTE_INVALID NOTE_TYPE_INVALID
}; };
D3DXCOLOR NoteTypeToColor( NoteType nt ); D3DXCOLOR NoteTypeToColor( NoteType nt );
@@ -76,9 +76,9 @@ struct HoldNote
}; };
inline int BeatToNoteRow( float fBeatNum ) { return int( fBeatNum * ELEMENTS_PER_BEAT + 0.5f); }; // round inline int BeatToNoteRow( float fBeatNum ) { return int( fBeatNum * ROWS_PER_BEAT + 0.5f); }; // round
inline int BeatToNoteRowNotRounded( float fBeatNum ) { return (int)( fBeatNum * ELEMENTS_PER_BEAT ); }; inline int BeatToNoteRowNotRounded( float fBeatNum ) { return (int)( fBeatNum * ROWS_PER_BEAT ); };
inline float NoteRowToBeat( float fNoteIndex ) { return fNoteIndex / (float)ELEMENTS_PER_BEAT; }; inline float NoteRowToBeat( float fNoteIndex ) { return fNoteIndex / (float)ROWS_PER_BEAT; };
inline float NoteRowToBeat( int iNoteIndex ) { return NoteRowToBeat( (float)iNoteIndex ); }; inline float NoteRowToBeat( int iNoteIndex ) { return NoteRowToBeat( (float)iNoteIndex ); };
+73 -18
View File
@@ -227,7 +227,7 @@ bool Notes::LoadFromBMSFile( const CString &sPath )
float fPercentThroughMeasure = (float)j/(float)iNumNotesInThisMeasure; float fPercentThroughMeasure = (float)j/(float)iNumNotesInThisMeasure;
const int iNoteIndex = (int) ( (iMeasureNo + fPercentThroughMeasure) const int iNoteIndex = (int) ( (iMeasureNo + fPercentThroughMeasure)
* BEATS_PER_MEASURE * ELEMENTS_PER_BEAT ); * BEATS_PER_MEASURE * ROWS_PER_BEAT );
int iColumnNumber; int iColumnNumber;
char cNoteChar; char cNoteChar;
mapBMSTrackToDanceNote( iTrackNum, iColumnNumber, cNoteChar ); mapBMSTrackToDanceNote( iTrackNum, iColumnNumber, cNoteChar );
@@ -626,7 +626,7 @@ char NotesToDWIChar( bool bCol1, bool bCol2, bool bCol3, bool bCol4, bool bCol5,
for( int i=0; i<iNumLookups; i++ ) for( int i=0; i<iNumLookups; i++ )
{ {
const DWICharLookup& l = lookup[i]; const DWICharLookup& l = lookup[i];
if( l.bCol[0] && bCol1, l.bCol[1] && bCol2, l.bCol[2] && bCol3, l.bCol[3] && bCol4, l.bCol[4] && bCol5, l.bCol[5] && bCol6 ) if( l.bCol[0]==bCol1 && l.bCol[1]==bCol2 && l.bCol[2]==bCol3 && l.bCol[3]==bCol4 && l.bCol[4]==bCol5 && l.bCol[5]==bCol6 )
return l.c; return l.c;
} }
ASSERT(0); ASSERT(0);
@@ -638,10 +638,10 @@ char NotesToDWIChar( bool bCol1, bool bCol2, bool bCol3, bool bCol4 )
return NotesToDWIChar( 0, bCol1, bCol2, bCol3, bCol4, 0 ); return NotesToDWIChar( 0, bCol1, bCol2, bCol3, bCol4, 0 );
} }
CString NotesToDWIString( int iNoteCol1, int iNoteCol2, int iNoteCol3, int iNoteCol4, int iNoteCol5, int iNoteCol6 ) CString NotesToDWIString( char cNoteCol1, char cNoteCol2, char cNoteCol3, char cNoteCol4, char cNoteCol5, char cNoteCol6 )
{ {
char cShow = NotesToDWIChar( iNoteCol1!=0, iNoteCol2!=0, iNoteCol3!=0, iNoteCol4!=0, iNoteCol5!=0, iNoteCol6!=0 ); char cShow = NotesToDWIChar( cNoteCol1!='0', cNoteCol2!='0', cNoteCol3!='0', cNoteCol4!='0', cNoteCol5!='0', cNoteCol6!='0' );
char cHold = NotesToDWIChar( iNoteCol1==2, iNoteCol2==2, iNoteCol3==2, iNoteCol4==2, iNoteCol5==2, iNoteCol6==2 ); char cHold = NotesToDWIChar( cNoteCol1=='2', cNoteCol2=='2', cNoteCol3=='2', cNoteCol4=='2', cNoteCol5=='2', cNoteCol6=='2' );
if( cHold != '0' ) if( cHold != '0' )
return ssprintf( "%c!%c", cShow, cHold ); return ssprintf( "%c!%c", cShow, cHold );
@@ -649,13 +649,15 @@ CString NotesToDWIString( int iNoteCol1, int iNoteCol2, int iNoteCol3, int iNote
return cShow; return cShow;
} }
CString NotesToDWIString( int iNoteCol1, int iNoteCol2, int iNoteCol3, int iNoteCol4 ) CString NotesToDWIString( char cNoteCol1, char cNoteCol2, char cNoteCol3, char cNoteCol4 )
{ {
return NotesToDWIString( 0, iNoteCol1, iNoteCol2, iNoteCol3, iNoteCol4, 0 ); return NotesToDWIString( '0', cNoteCol1, cNoteCol2, cNoteCol3, cNoteCol4, '0' );
} }
void Notes::WriteDWINotesTag( FILE* fp ) void Notes::WriteDWINotesTag( FILE* fp )
{ {
LOG->Trace( "Notes::WriteDWINotesTag" );
switch( m_NotesType ) switch( m_NotesType )
{ {
case NOTES_TYPE_DANCE_SINGLE: fprintf( fp, "#SINGLE:" ); break; case NOTES_TYPE_DANCE_SINGLE: fprintf( fp, "#SINGLE:" ); break;
@@ -679,33 +681,86 @@ void Notes::WriteDWINotesTag( FILE* fp )
this->GetNoteData( &notedata ); this->GetNoteData( &notedata );
notedata.ConvertHoldNotesTo2sAnd3s(); notedata.ConvertHoldNotesTo2sAnd3s();
fprintf( fp, "<" ); // begin a 48th note series const int iNumPads = (m_NotesType==NOTES_TYPE_DANCE_COUPLE || m_NotesType==NOTES_TYPE_DANCE_DOUBLE) ? 2 : 1;
for( int r=0; r<notedata.GetLastRow(); r++ ) const int iLastMeasure = int( notedata.GetLastBeat()/BEATS_PER_MEASURE );
for( int pad=0; pad<iNumPads; pad++ )
{ {
if( pad == 1 ) // 2nd pad
fprintf( fp, ":\n" );
for( int m=0; m<=iLastMeasure; m++ ) // foreach measure
{
NoteType nt = notedata.GetSmallestNoteTypeForMeasure( m );
double fCurrentIncrementer;
switch( nt )
{
case NOTE_TYPE_4TH:
case NOTE_TYPE_8TH:
fCurrentIncrementer = 1.0/8 * BEATS_PER_MEASURE;
break;
case NOTE_TYPE_12TH:
fprintf( fp, "[" );
fCurrentIncrementer = 1.0/24 * BEATS_PER_MEASURE;
break;
case NOTE_TYPE_16TH:
fprintf( fp, "(" );
fCurrentIncrementer = 1.0/16 * BEATS_PER_MEASURE;
break;
default:
ASSERT(0);
// fall though
case NOTE_TYPE_INVALID:
fprintf( fp, "<" );
fCurrentIncrementer = 1.0/192 * BEATS_PER_MEASURE;
break;
}
double fFirstBeatInMeasure = m * BEATS_PER_MEASURE;
double fLastBeatInMeasure = (m+1) * BEATS_PER_MEASURE;
for( double b=fFirstBeatInMeasure; b<fLastBeatInMeasure; b+=fCurrentIncrementer )
{
int row = BeatToNoteRow( (float)b );
switch( m_NotesType ) switch( m_NotesType )
{ {
case NOTES_TYPE_DANCE_SINGLE: case NOTES_TYPE_DANCE_SINGLE:
case NOTES_TYPE_DANCE_COUPLE: case NOTES_TYPE_DANCE_COUPLE:
case NOTES_TYPE_DANCE_DOUBLE: case NOTES_TYPE_DANCE_DOUBLE:
fprintf( fp, NotesToDWIString( notedata.m_TapNotes[0][r], notedata.m_TapNotes[1][r], notedata.m_TapNotes[2][r], notedata.m_TapNotes[3][r] ) ); fprintf( fp, NotesToDWIString( notedata.m_TapNotes[pad*4+0][row], notedata.m_TapNotes[pad*4+1][row], notedata.m_TapNotes[pad*4+2][row], notedata.m_TapNotes[pad*4+3][row] ) );
break; break;
case NOTES_TYPE_DANCE_SOLO: case NOTES_TYPE_DANCE_SOLO:
fprintf( fp, NotesToDWIString( notedata.m_TapNotes[0][r], notedata.m_TapNotes[1][r], notedata.m_TapNotes[2][r], notedata.m_TapNotes[3][r], notedata.m_TapNotes[4][r], notedata.m_TapNotes[5][r] ) ); fprintf( fp, NotesToDWIString( notedata.m_TapNotes[0][row], notedata.m_TapNotes[1][row], notedata.m_TapNotes[2][row], notedata.m_TapNotes[3][row], notedata.m_TapNotes[4][row], notedata.m_TapNotes[5][row] ) );
break; break;
default: return; // not a type supported by DWI default: return; // not a type supported by DWI
} }
} }
fprintf( fp, "<" ); // end a 48th note series
if( m_NotesType == NOTES_TYPE_DANCE_COUPLE || m_NotesType == NOTES_TYPE_DANCE_DOUBLE ) switch( nt )
{ {
fprintf( fp, ":" ); case NOTE_TYPE_4TH:
fprintf( fp, "<" ); // begin a 48th note series case NOTE_TYPE_8TH:
for( int r=0; r<notedata.GetLastRow(); r++ ) break;
fprintf( fp, NotesToDWIString( notedata.m_TapNotes[4][r], notedata.m_TapNotes[5][r], notedata.m_TapNotes[6][r], notedata.m_TapNotes[7][r] ) ); case NOTE_TYPE_12TH:
fprintf( fp, "]" );
break;
case NOTE_TYPE_16TH:
fprintf( fp, ")" );
break;
default:
ASSERT(0);
// fall though
case NOTE_TYPE_INVALID:
fprintf( fp, ">" );
break;
}
fprintf( fp, "\n" );
}
} }
fprintf( fp, ">" ); // end series fprintf( fp, ";\n" );
} }
void Notes::SetNoteData( NoteData* pNewNoteData ) void Notes::SetNoteData( NoteData* pNewNoteData )
+13 -5
View File
@@ -417,8 +417,6 @@ void Player::OnRowDestroyed( int col, int iIndexThatWasSteppedOn )
// update the judgement, score, and life // update the judgement, score, and life
m_Judgement.SetJudgement( score ); m_Judgement.SetJudgement( score );
if( m_pLifeMeter )
m_pLifeMeter->ChangeLife( score );
// zoom the judgement and combo like a heart beat // zoom the judgement and combo like a heart beat
float fStartZoom; float fStartZoom;
@@ -463,9 +461,6 @@ int Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanThisBeat )
bFoundAMissInThisRow = true; bFoundAMissInThisRow = true;
HandleNoteScore( TNS_MISS ); HandleNoteScore( TNS_MISS );
} }
if( bFoundAMissInThisRow )
if( m_pLifeMeter )
m_pLifeMeter->ChangeLife( TNS_MISS );
} }
} }
@@ -496,9 +491,15 @@ void Player::CrossedRow( int iNoteRow )
void Player::HandleNoteScore( TapNoteScore score ) void Player::HandleNoteScore( TapNoteScore score )
{ {
// don't accumulate points if AutoPlay is on.
if( PREFSMAN->m_bAutoPlay && !GAMESTATE->m_bDemonstration )
return;
// update dance points for Oni lifemeter // update dance points for Oni lifemeter
GAMESTATE->m_iActualDancePoints[m_PlayerNumber] += TapNoteScoreToDancePoints( score ); GAMESTATE->m_iActualDancePoints[m_PlayerNumber] += TapNoteScoreToDancePoints( score );
GAMESTATE->m_TapNoteScores[m_PlayerNumber][score]++; GAMESTATE->m_TapNoteScores[m_PlayerNumber][score]++;
if( m_pLifeMeter )
m_pLifeMeter->ChangeLife( score );
if( m_pLifeMeter ) if( m_pLifeMeter )
m_pLifeMeter->OnDancePointsChange(); m_pLifeMeter->OnDancePointsChange();
@@ -566,9 +567,16 @@ void Player::HandleNoteScore( TapNoteScore score )
void Player::HandleNoteScore( HoldNoteScore score ) void Player::HandleNoteScore( HoldNoteScore score )
{ {
// don't accumulate points if AutoPlay is on.
if( PREFSMAN->m_bAutoPlay && !GAMESTATE->m_bDemonstration )
return;
// update dance points for Oni lifemeter // update dance points for Oni lifemeter
GAMESTATE->m_iActualDancePoints[m_PlayerNumber] += HoldNoteScoreToDancePoints( score ); GAMESTATE->m_iActualDancePoints[m_PlayerNumber] += HoldNoteScoreToDancePoints( score );
GAMESTATE->m_HoldNoteScores[m_PlayerNumber][score]++; GAMESTATE->m_HoldNoteScores[m_PlayerNumber][score]++;
if( m_pLifeMeter )
m_pLifeMeter->ChangeLife( score );
if( m_pLifeMeter ) if( m_pLifeMeter )
m_pLifeMeter->OnDancePointsChange(); m_pLifeMeter->OnDancePointsChange();
+77 -2
View File
@@ -267,9 +267,84 @@ bool DeviceInput::fromString( const CString &s )
device = (InputDevice)atoi( a[0] ); device = (InputDevice)atoi( a[0] );
button = atoi( a[1] ); button = atoi( a[1] );
return true; return true;
}; }
char DeviceInput::ToChar() const
{
switch( device )
{
case DEVICE_KEYBOARD:
switch( button )
{
case DIK_1: return '1';
case DIK_2: return '2';
case DIK_3: return '3';
case DIK_4: return '4';
case DIK_5: return '5';
case DIK_6: return '6';
case DIK_7: return '7';
case DIK_8: return '8';
case DIK_9: return '9';
case DIK_0: return '0';
case DIK_MINUS: return '-';
case DIK_EQUALS: return '=';
case DIK_Q: return 'Q';
case DIK_W: return 'W';
case DIK_E: return 'E';
case DIK_R: return 'R';
case DIK_T: return 'T';
case DIK_Y: return 'Y';
case DIK_U: return 'U';
case DIK_I: return 'I';
case DIK_O: return 'O';
case DIK_P: return 'P';
case DIK_LBRACKET: return '[';
case DIK_RBRACKET: return ']';
case DIK_A: return 'A';
case DIK_S: return 'S';
case DIK_D: return 'D';
case DIK_F: return 'F';
case DIK_G: return 'G';
case DIK_H: return 'H';
case DIK_J: return 'J';
case DIK_K: return 'K';
case DIK_L: return 'L';
case DIK_SEMICOLON: return ';';
case DIK_APOSTROPHE:return '\'';
case DIK_BACKSLASH: return '\\';
case DIK_Z: return 'Z';
case DIK_X: return 'X';
case DIK_C: return 'C';
case DIK_V: return 'V';
case DIK_B: return 'B';
case DIK_N: return 'N';
case DIK_M: return 'M';
case DIK_COMMA: return ',';
case DIK_PERIOD: return '.';
case DIK_SLASH: return '/';
case DIK_MULTIPLY: return '*';
case DIK_SPACE: return ' ';
case DIK_NUMPAD7: return '7';
case DIK_NUMPAD8: return '8';
case DIK_NUMPAD9: return '9';
case DIK_SUBTRACT: return '-';
case DIK_NUMPAD4: return '4';
case DIK_NUMPAD5: return '5';
case DIK_NUMPAD6: return '6';
case DIK_ADD: return '+';
case DIK_NUMPAD1: return '1';
case DIK_NUMPAD2: return '2';
case DIK_NUMPAD3: return '3';
case DIK_NUMPAD0: return '0';
case DIK_DECIMAL: return '.';
default:
return '\0';
}
break;
default:
return '\0';
}
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
+2
View File
@@ -94,6 +94,8 @@ public:
bool IsValid() const { return device != DEVICE_NONE; }; bool IsValid() const { return device != DEVICE_NONE; };
void MakeInvalid() { device = DEVICE_NONE; }; void MakeInvalid() { device = DEVICE_NONE; };
char ToChar() const;
static int NumButtons(InputDevice device); static int NumButtons(InputDevice device);
}; };
+96 -38
View File
@@ -23,6 +23,7 @@
#include "GameConstantsAndTypes.h" #include "GameConstantsAndTypes.h"
#include "RageLog.h" #include "RageLog.h"
#include "GameState.h" #include "GameState.h"
#include "ScreenTextEntry.h"
// //
@@ -38,8 +39,8 @@ const float DEBUG_Y = CENTER_Y-100;
const float HELP_X = SCREEN_LEFT + 10; const float HELP_X = SCREEN_LEFT + 10;
const float HELP_Y = SCREEN_BOTTOM - 10; const float HELP_Y = SCREEN_BOTTOM - 10;
const float SHORTCUTS_X = SCREEN_LEFT + 10; const float SHORTCUTS_X = CENTER_X - 150;
const float SHORTCUTS_Y = SCREEN_TOP + 8; const float SHORTCUTS_Y = CENTER_Y;
const float INFO_X = SCREEN_RIGHT - 10 ; const float INFO_X = SCREEN_RIGHT - 10 ;
const float INFO_Y = SCREEN_BOTTOM - 10; const float INFO_Y = SCREEN_BOTTOM - 10;
@@ -53,11 +54,11 @@ const float PLAYER_Y = SCREEN_TOP;
const float MENU_ITEM_X = CENTER_X-200; const float MENU_ITEM_X = CENTER_X-200;
const float MENU_ITEM_START_Y = SCREEN_TOP + 30; const float MENU_ITEM_START_Y = SCREEN_TOP + 30;
const float MENU_ITEM_SPACING_Y = 24; const float MENU_ITEM_SPACING_Y = 20;
const CString HELP_TEXT = const CString HELP_TEXT =
"Esc: show menu\n" "Esc: show menu\n"
"Hold F1 to show keyboard shortcuts\n" "Hold F1 to show more commands\n"
"Up/Down: change beat\n" "Up/Down: change beat\n"
"Left/Right: change snap\n" "Left/Right: change snap\n"
"PgUp/PgDn: jump 1 measure\n" "PgUp/PgDn: jump 1 measure\n"
@@ -68,7 +69,7 @@ const CString HELP_TEXT =
const CString SHORTCUT_TEXT = const CString SHORTCUT_TEXT =
"S: save changes\n" "S: save changes\n"
"I: save as SM and DWI (lossy)\n" "W: save as SM and DWI (lossy)\n"
"Enter/Space: set begin/end selection markers\n" "Enter/Space: set begin/end selection markers\n"
"G/H/J/K/L: Snap selection to nearest\n" "G/H/J/K/L: Snap selection to nearest\n"
" 4th / 8th / 12th / 16th / 12th or 16th\n" " 4th / 8th / 12th / 16th / 12th or 16th\n"
@@ -92,11 +93,6 @@ const CString SHORTCUT_TEXT =
const CString MENU_ITEM_TEXT[NUM_MENU_ITEMS] = { const CString MENU_ITEM_TEXT[NUM_MENU_ITEMS] = {
"Set begin marker (Enter)", "Set begin marker (Enter)",
"Set end marker (Space)", "Set end marker (Space)",
"Snap selection to nearest quarter note (G)",
"Snap selection to nearest eighth note (H)",
"Snap selection to nearest triplet (J)",
"Snap selection to nearest sixteenth note (K)",
"Snap selection to nearest triplet or sixteenth note (L)",
"(P)lay selection", "(P)lay selection",
"(R)ecord in selection", "(R)ecord in selection",
"(T)oggle Play/Record rate", "(T)oggle Play/Record rate",
@@ -104,20 +100,22 @@ const CString MENU_ITEM_TEXT[NUM_MENU_ITEMS] = {
"Copy selection (C)", "Copy selection (C)",
"Paste clipboard at current beat (V)", "Paste clipboard at current beat (V)",
"Toggle (D)ifficulty", "Toggle (D)ifficulty",
"Add (B)ackground change",
"(Ins)ert blank beat and shift down", "(Ins)ert blank beat and shift down",
"(Del)ete blank beat and shift up", "(Del)ete blank beat and shift up",
"Snap selection to nearest quarter note (G)",
"Snap selection to nearest eighth note (H)",
"Snap selection to nearest triplet (J)",
"Snap selection to nearest sixteenth note (K)",
"Snap selection to nearest triplet or sixteenth note (L)",
"Play sample (M)usic", "Play sample (M)usic",
"(S)ave changes", "(S)ave changes",
"Save as D(W)I and SM (lossy)",
"(Q)uit" "(Q)uit"
}; };
int MENU_ITEM_KEY[NUM_MENU_ITEMS] = { int MENU_ITEM_KEY[NUM_MENU_ITEMS] = {
DIK_RETURN, DIK_RETURN,
DIK_SPACE, DIK_SPACE,
DIK_G,
DIK_H,
DIK_J,
DIK_K,
DIK_L,
DIK_P, DIK_P,
DIK_R, DIK_R,
DIK_T, DIK_T,
@@ -125,10 +123,17 @@ int MENU_ITEM_KEY[NUM_MENU_ITEMS] = {
DIK_C, DIK_C,
DIK_V, DIK_V,
DIK_D, DIK_D,
DIK_B,
DIK_INSERT, DIK_INSERT,
DIK_DELETE, DIK_DELETE,
DIK_G,
DIK_H,
DIK_J,
DIK_K,
DIK_L,
DIK_M, DIK_M,
DIK_S, DIK_S,
DIK_W,
DIK_Q, DIK_Q,
}; };
@@ -241,10 +246,13 @@ ScreenEdit::ScreenEdit()
m_textHelp.SetShadowLength( 2 ); m_textHelp.SetShadowLength( 2 );
m_textHelp.SetText( HELP_TEXT ); m_textHelp.SetText( HELP_TEXT );
m_rectShortcutsBack.StretchTo( CRect(SCREEN_LEFT, SCREEN_TOP, SCREEN_RIGHT, SCREEN_BOTTOM) );
m_rectShortcutsBack.SetDiffuseColor( D3DXCOLOR(0,0,0,0.5f) );
m_textShortcuts.LoadFromFont( THEME->GetPathTo("Fonts","normal") ); m_textShortcuts.LoadFromFont( THEME->GetPathTo("Fonts","normal") );
m_textShortcuts.SetXY( SHORTCUTS_X, SHORTCUTS_Y ); m_textShortcuts.SetXY( SHORTCUTS_X, SHORTCUTS_Y );
m_textShortcuts.SetHorizAlign( Actor::align_left ); m_textShortcuts.SetHorizAlign( Actor::align_left );
m_textShortcuts.SetVertAlign( Actor::align_top ); m_textShortcuts.SetVertAlign( Actor::align_middle );
m_textShortcuts.SetZoom( 0.5f ); m_textShortcuts.SetZoom( 0.5f );
m_textShortcuts.SetShadowLength( 2 ); m_textShortcuts.SetShadowLength( 2 );
m_textShortcuts.SetText( SHORTCUT_TEXT ); m_textShortcuts.SetText( SHORTCUT_TEXT );
@@ -325,6 +333,7 @@ void ScreenEdit::Update( float fDeltaTime )
m_Fade.Update( fDeltaTime ); m_Fade.Update( fDeltaTime );
m_textHelp.Update( fDeltaTime ); m_textHelp.Update( fDeltaTime );
m_textInfo.Update( fDeltaTime ); m_textInfo.Update( fDeltaTime );
m_rectShortcutsBack.Update( fDeltaTime );
m_textShortcuts.Update( fDeltaTime ); m_textShortcuts.Update( fDeltaTime );
m_rectRecordBack.Update( fDeltaTime ); m_rectRecordBack.Update( fDeltaTime );
@@ -385,11 +394,11 @@ void ScreenEdit::Update( float fDeltaTime )
CString sNoteType; CString sNoteType;
switch( m_SnapDisplay.GetSnapMode() ) switch( m_SnapDisplay.GetSnapMode() )
{ {
case NOTE_4TH: sNoteType = "quarter notes"; break; case NOTE_TYPE_4TH: sNoteType = "quarter notes"; break;
case NOTE_8TH: sNoteType = "eighth notes"; break; case NOTE_TYPE_8TH: sNoteType = "eighth notes"; break;
case NOTE_12TH: sNoteType = "triplets"; break; case NOTE_TYPE_12TH: sNoteType = "triplets"; break;
case NOTE_16TH: sNoteType = "sixteenth notes"; break; case NOTE_TYPE_16TH: sNoteType = "sixteenth notes"; break;
default: ASSERT( false ); default: ASSERT(0);
} }
static int iNumTapNotes = 0, iNumHoldNotes = 0; static int iNumTapNotes = 0, iNumHoldNotes = 0;
@@ -437,11 +446,14 @@ void ScreenEdit::DrawPrimitives()
m_NoteFieldEdit.Draw(); m_NoteFieldEdit.Draw();
GAMESTATE->m_fSongBeat = fSongBeat; // restore real song beat GAMESTATE->m_fSongBeat = fSongBeat; // restore real song beat
if( INPUTMAN->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD,DIK_F1) ) )
m_textShortcuts.Draw();
m_textHelp.Draw(); m_textHelp.Draw();
m_textInfo.Draw(); m_textInfo.Draw();
m_Fade.Draw(); m_Fade.Draw();
if( INPUTMAN->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD,DIK_F1) ) )
{
m_rectShortcutsBack.Draw();
m_textShortcuts.Draw();
}
m_rectRecordBack.Draw(); m_rectRecordBack.Draw();
@@ -562,6 +574,7 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
SCREENMAN->SetNewScreen( new ScreenEditMenu ); SCREENMAN->SetNewScreen( new ScreenEditMenu );
break; break;
case DIK_S: case DIK_S:
case DIK_W:
{ {
// copy edit into current Notes // copy edit into current Notes
Song* pSong = GAMESTATE->m_pCurSong; Song* pSong = GAMESTATE->m_pCurSong;
@@ -578,7 +591,19 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
} }
pNotes->SetNoteData( (NoteData*)&m_NoteFieldEdit ); pNotes->SetNoteData( (NoteData*)&m_NoteFieldEdit );
switch( DeviceI.button )
{
case DIK_S:
GAMESTATE->m_pCurSong->SaveToSMFile(); GAMESTATE->m_pCurSong->SaveToSMFile();
SCREENMAN->SystemMessage( "Saved as SM." );
break;
case DIK_W:
GAMESTATE->m_pCurSong->SaveToSMAndDWIFile();
SCREENMAN->SystemMessage( "Saved as SM and DWI." );
break;
default:
ASSERT(0);
}
SOUND->PlayOnceStreamed( THEME->GetPathTo("Sounds","edit save") ); SOUND->PlayOnceStreamed( THEME->GetPathTo("Sounds","edit save") );
} }
break; break;
@@ -709,11 +734,11 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
NoteType noteType2; NoteType noteType2;
switch( DeviceI.button ) switch( DeviceI.button )
{ {
case DIK_G: noteType1 = NOTE_4TH; noteType2 = NOTE_4TH; break; case DIK_G: noteType1 = NOTE_TYPE_4TH; noteType2 = NOTE_TYPE_4TH; break;
case DIK_H: noteType1 = NOTE_8TH; noteType2 = NOTE_8TH; break; case DIK_H: noteType1 = NOTE_TYPE_8TH; noteType2 = NOTE_TYPE_8TH; break;
case DIK_J: noteType1 = NOTE_12TH; noteType2 = NOTE_12TH; break; case DIK_J: noteType1 = NOTE_TYPE_12TH; noteType2 = NOTE_TYPE_12TH; break;
case DIK_K: noteType1 = NOTE_16TH; noteType2 = NOTE_16TH; break; case DIK_K: noteType1 = NOTE_TYPE_16TH; noteType2 = NOTE_TYPE_16TH; break;
case DIK_L: noteType1 = NOTE_12TH; noteType2 = NOTE_16TH; break; case DIK_L: noteType1 = NOTE_TYPE_12TH; noteType2 = NOTE_TYPE_16TH; break;
default: ASSERT( false ); default: ASSERT( false );
} }
@@ -857,6 +882,21 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
} }
break; break;
case DIK_B:
{
CString sOldBackground;
for( int i=0; i<m_pSong->m_BackgroundChanges.GetSize(); i++ )
{
if( m_pSong->m_BackgroundChanges[i].m_fStartBeat == GAMESTATE->m_fSongBeat )
break;
}
if( i != m_pSong->m_BackgroundChanges.GetSize() ) // there is already a BGChange here
sOldBackground = m_pSong->m_BackgroundChanges[i].m_sBGName;
SCREENMAN->AddScreenToTop( new ScreenTextEntry(SM_None, "Type a background name.\nPress Enter to keep,\nEscape to cancel.\nEnter an empty string to remove\nthe Background Change.", sOldBackground, AddBGChange, NULL) );
}
break;
case DIK_F7: case DIK_F7:
case DIK_F8: case DIK_F8:
{ {
@@ -896,17 +936,17 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
case DIK_F9: case DIK_F9:
case DIK_F10: case DIK_F10:
{ {
float fFreezeDelta; float fStopDelta;
switch( DeviceI.button ) switch( DeviceI.button )
{ {
case DIK_F9: fFreezeDelta = -0.020f; break; case DIK_F9: fStopDelta = -0.020f; break;
case DIK_F10: fFreezeDelta = +0.020f; break; case DIK_F10: fStopDelta = +0.020f; break;
default: ASSERT(0); default: ASSERT(0);
} }
switch( type ) switch( type )
{ {
case IET_SLOW_REPEAT: fFreezeDelta *= 10; break; case IET_SLOW_REPEAT: fStopDelta *= 10; break;
case IET_FAST_REPEAT: fFreezeDelta *= 40; break; case IET_FAST_REPEAT: fStopDelta *= 40; break;
} }
for( int i=0; i<m_pSong->m_StopSegments.GetSize(); i++ ) for( int i=0; i<m_pSong->m_StopSegments.GetSize(); i++ )
@@ -918,12 +958,12 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
if( i == m_pSong->m_StopSegments.GetSize() ) // there is no BPMSegment at the current beat if( i == m_pSong->m_StopSegments.GetSize() ) // there is no BPMSegment at the current beat
{ {
// create a new StopSegment // create a new StopSegment
if( fFreezeDelta > 0 ) if( fStopDelta > 0 )
m_pSong->AddStopSegment( StopSegment(GAMESTATE->m_fSongBeat, fFreezeDelta) ); m_pSong->AddStopSegment( StopSegment(GAMESTATE->m_fSongBeat, fStopDelta) );
} }
else // StopSegment being modified is m_StopSegments[i] else // StopSegment being modified is m_StopSegments[i]
{ {
m_pSong->m_StopSegments[i].m_fStopSeconds += fFreezeDelta; m_pSong->m_StopSegments[i].m_fStopSeconds += fStopDelta;
if( m_pSong->m_StopSegments[i].m_fStopSeconds <= 0 ) if( m_pSong->m_StopSegments[i].m_fStopSeconds <= 0 )
m_pSong->m_StopSegments.RemoveAt( i ); m_pSong->m_StopSegments.RemoveAt( i );
} }
@@ -982,6 +1022,24 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
} }
} }
void ScreenEdit::AddBGChange( CString sBGName )
{
Song* pSong = GAMESTATE->m_pCurSong;
for( int i=0; i<pSong->m_BackgroundChanges.GetSize(); i++ )
{
if( pSong->m_BackgroundChanges[i].m_fStartBeat == GAMESTATE->m_fSongBeat )
break;
}
if( i != pSong->m_BackgroundChanges.GetSize() ) // there is already a BGChange here
pSong->m_BackgroundChanges.RemoveAt( i );
// create a new BGChange
if( sBGName != "" )
pSong->AddBackgroundChange( BackgroundChange(GAMESTATE->m_fSongBeat, sBGName) );
}
void ScreenEdit::InputRecord( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) void ScreenEdit::InputRecord( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI )
{ {
if(type == IET_RELEASE) return; // don't care if(type == IET_RELEASE) return; // don't care
@@ -1010,7 +1068,7 @@ void ScreenEdit::InputRecord( const DeviceInput& DeviceI, const InputEventType t
if( type == IET_FIRST_PRESS ) if( type == IET_FIRST_PRESS )
{ {
m_NoteFieldRecord.m_TapNotes[iCol][iNoteIndex] = '1'; m_NoteFieldRecord.m_TapNotes[iCol][iNoteIndex] = '1';
m_NoteFieldRecord.SnapToNearestNoteType( NOTE_12TH, NOTE_16TH, max(0,GAMESTATE->m_fSongBeat-1), GAMESTATE->m_fSongBeat+1); m_NoteFieldRecord.SnapToNearestNoteType( NOTE_TYPE_12TH, NOTE_TYPE_16TH, max(0,GAMESTATE->m_fSongBeat-1), GAMESTATE->m_fSongBeat+1);
m_GrayArrowRowRecord.Step( iCol ); m_GrayArrowRowRecord.Step( iCol );
} }
else else
@@ -1030,7 +1088,7 @@ void ScreenEdit::InputRecord( const DeviceInput& DeviceI, const InputEventType t
newHN.m_fEndBeat = fEndBeat; newHN.m_fEndBeat = fEndBeat;
m_NoteFieldRecord.AddHoldNote( newHN ); m_NoteFieldRecord.AddHoldNote( newHN );
m_NoteFieldRecord.SnapToNearestNoteType( NOTE_12TH, NOTE_16TH, max(0,GAMESTATE->m_fSongBeat-2), GAMESTATE->m_fSongBeat+2); m_NoteFieldRecord.SnapToNearestNoteType( NOTE_TYPE_12TH, NOTE_TYPE_16TH, max(0,GAMESTATE->m_fSongBeat-2), GAMESTATE->m_fSongBeat+2);
} }
break; break;
} }
+4 -1
View File
@@ -22,7 +22,7 @@
#include "SnapDisplay.h" #include "SnapDisplay.h"
const int NUM_MENU_ITEMS = 19; const int NUM_MENU_ITEMS = 21;
class ScreenEdit : public Screen class ScreenEdit : public Screen
@@ -46,6 +46,8 @@ protected:
void MenuItemGainFocus( int iItemIndex ); void MenuItemGainFocus( int iItemIndex );
void MenuItemLoseFocus( int iItemIndex ); void MenuItemLoseFocus( int iItemIndex );
static void AddBGChange( CString sBGName );
enum EditMode { MODE_EDITING, MODE_MENU, MODE_RECORDING, MODE_PLAYING }; enum EditMode { MODE_EDITING, MODE_MENU, MODE_RECORDING, MODE_PLAYING };
EditMode m_EditMode; EditMode m_EditMode;
@@ -60,6 +62,7 @@ protected:
BitmapText m_textInfo; // status information that changes BitmapText m_textInfo; // status information that changes
BitmapText m_textHelp; BitmapText m_textHelp;
Quad m_rectShortcutsBack;
BitmapText m_textShortcuts; BitmapText m_textShortcuts;
// keep track of where we are and what we're doing // keep track of where we are and what we're doing
+2 -2
View File
@@ -112,12 +112,12 @@ void ScreenEditMenu::MenuDown( const PlayerNumber p )
Selector.Down(); Selector.Down();
} }
void ScreenEditMenu::MenuLeft( const PlayerNumber p ) void ScreenEditMenu::MenuLeft( const PlayerNumber p, const InputEventType type )
{ {
Selector.Left(); Selector.Left();
} }
void ScreenEditMenu::MenuRight( const PlayerNumber p ) void ScreenEditMenu::MenuRight( const PlayerNumber p, const InputEventType type )
{ {
Selector.Right(); Selector.Right();
} }
+2 -2
View File
@@ -28,8 +28,8 @@ private:
void MenuUp( const PlayerNumber p ); void MenuUp( const PlayerNumber p );
void MenuDown( const PlayerNumber p ); void MenuDown( const PlayerNumber p );
void MenuLeft( const PlayerNumber p ); void MenuLeft( const PlayerNumber p, const InputEventType type );
void MenuRight( const PlayerNumber p ); void MenuRight( const PlayerNumber p, const InputEventType type );
void MenuBack( const PlayerNumber p ); void MenuBack( const PlayerNumber p );
void MenuStart( const PlayerNumber p ); void MenuStart( const PlayerNumber p );
+2 -2
View File
@@ -330,7 +330,7 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
Grade grade[NUM_PLAYERS]; Grade grade[NUM_PLAYERS];
for( p=0; p<NUM_PLAYERS; p++ ) for( p=0; p<NUM_PLAYERS; p++ )
{ {
if( !GAMESTATE->IsPlayerEnabled(p) || GAMESTATE->m_bUsedAutoPlayer || GAMESTATE->m_fSecondsBeforeFail[p] != -1 ) if( !GAMESTATE->IsPlayerEnabled(p) || GAMESTATE->m_fSecondsBeforeFail[p] != -1 )
{ {
grade[p] = GRADE_E; grade[p] = GRADE_E;
} }
@@ -370,7 +370,7 @@ ScreenEvaluation::ScreenEvaluation( bool bSummary )
if( !GAMESTATE->IsPlayerEnabled(p) ) if( !GAMESTATE->IsPlayerEnabled(p) )
continue; continue;
if( GAMESTATE->m_bUsedAutoPlayer ) if( grade[p] == GRADE_E )
continue; continue;
switch( m_ResultMode ) switch( m_ResultMode )
+14 -21
View File
@@ -86,6 +86,8 @@
#define DIFFICULTY_P2_EXTRA_REVERSE_Y THEME->GetMetricF("Gameplay","DifficultyP2ExtraReverseY") #define DIFFICULTY_P2_EXTRA_REVERSE_Y THEME->GetMetricF("Gameplay","DifficultyP2ExtraReverseY")
#define DEBUG_X THEME->GetMetricF("Gameplay","DebugX") #define DEBUG_X THEME->GetMetricF("Gameplay","DebugX")
#define DEBUG_Y THEME->GetMetricF("Gameplay","DebugY") #define DEBUG_Y THEME->GetMetricF("Gameplay","DebugY")
#define AUTOPLAY_X THEME->GetMetricF("Gameplay","AutoPlayX")
#define AUTOPLAY_Y THEME->GetMetricF("Gameplay","AutoPlayY")
#define SURVIVE_TIME_X THEME->GetMetricF("Gameplay","SurviveTimeX") #define SURVIVE_TIME_X THEME->GetMetricF("Gameplay","SurviveTimeX")
#define SURVIVE_TIME_Y THEME->GetMetricF("Gameplay","SurviveTimeY") #define SURVIVE_TIME_Y THEME->GetMetricF("Gameplay","SurviveTimeY")
#define SECONDS_BETWEEN_COMMENTS THEME->GetMetricF("Gameplay","SecondsBetweenComments") #define SECONDS_BETWEEN_COMMENTS THEME->GetMetricF("Gameplay","SecondsBetweenComments")
@@ -245,8 +247,6 @@ ScreenGameplay::ScreenGameplay()
} }
GAMESTATE->m_bUsedAutoPlayer |= PREFSMAN->m_bAutoPlay;
m_bChangedOffsetOrBPM = false; m_bChangedOffsetOrBPM = false;
@@ -479,6 +479,11 @@ ScreenGameplay::ScreenGameplay()
m_textDebug.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); m_textDebug.SetDiffuseColor( D3DXCOLOR(1,1,1,1) );
this->AddSubActor( &m_textDebug ); this->AddSubActor( &m_textDebug );
m_textAutoPlay.LoadFromFont( THEME->GetPathTo("Fonts","normal") );
m_textAutoPlay.SetXY( AUTOPLAY_X, AUTOPLAY_Y );
m_textAutoPlay.SetText( "AutoPlay is ON" );
m_textAutoPlay.SetDiffuseColor( D3DXCOLOR(1,1,1,1) );
this->AddSubActor( &m_textAutoPlay );
m_StarWipe.SetClosed(); m_StarWipe.SetClosed();
@@ -904,6 +909,10 @@ void ScreenGameplay::Update( float fDeltaTime )
iRowLastCrossed = iRowNow; iRowLastCrossed = iRowNow;
} }
if( PREFSMAN->m_bAutoPlay && !GAMESTATE->m_bDemonstration )
m_textAutoPlay.SetDiffuseColor( D3DXCOLOR(1,1,1,1) );
else
m_textAutoPlay.SetDiffuseColor( D3DXCOLOR(1,1,1,0) );
Screen::Update( fDeltaTime ); Screen::Update( fDeltaTime );
} }
@@ -937,7 +946,6 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ
return; // don't fall through below return; // don't fall through below
} }
// Handle special keys to adjust the offset // Handle special keys to adjust the offset
if( DeviceI.device == DEVICE_KEYBOARD ) if( DeviceI.device == DEVICE_KEYBOARD )
{ {
@@ -945,13 +953,6 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ
{ {
case DIK_F8: case DIK_F8:
PREFSMAN->m_bAutoPlay = !PREFSMAN->m_bAutoPlay; PREFSMAN->m_bAutoPlay = !PREFSMAN->m_bAutoPlay;
GAMESTATE->m_bUsedAutoPlayer |= PREFSMAN->m_bAutoPlay;
m_textDebug.SetText( ssprintf("Autoplayer %s.", (PREFSMAN->m_bAutoPlay ? "ON" : "OFF")) );
m_textDebug.SetDiffuseColor( D3DXCOLOR(1,1,1,1) );
m_textDebug.StopTweening();
m_textDebug.BeginTweeningQueued( 3 ); // sleep
m_textDebug.BeginTweeningQueued( 0.5f ); // fade out
m_textDebug.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) );
break; break;
case DIK_F9: case DIK_F9:
case DIK_F10: case DIK_F10:
@@ -971,7 +972,7 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ
seg.m_fBPM += fOffsetDelta; seg.m_fBPM += fOffsetDelta;
m_textDebug.SetText( ssprintf("Cur BPM = %f.", seg.m_fBPM) ); m_textDebug.SetText( ssprintf("Cur BPM = %f", seg.m_fBPM) );
m_textDebug.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); m_textDebug.SetDiffuseColor( D3DXCOLOR(1,1,1,1) );
m_textDebug.StopTweening(); m_textDebug.StopTweening();
m_textDebug.BeginTweeningQueued( 3 ); // sleep m_textDebug.BeginTweeningQueued( 3 ); // sleep
@@ -996,7 +997,7 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ
GAMESTATE->m_pCurSong->m_fBeat0OffsetInSeconds += fOffsetDelta; GAMESTATE->m_pCurSong->m_fBeat0OffsetInSeconds += fOffsetDelta;
m_textDebug.SetText( ssprintf("Offset = %f.", GAMESTATE->m_pCurSong->m_fBeat0OffsetInSeconds) ); m_textDebug.SetText( ssprintf("Offset = %f", GAMESTATE->m_pCurSong->m_fBeat0OffsetInSeconds) );
m_textDebug.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); m_textDebug.SetDiffuseColor( D3DXCOLOR(1,1,1,1) );
m_textDebug.StopTweening(); m_textDebug.StopTweening();
m_textDebug.BeginTweeningQueued( 3 ); // sleep m_textDebug.BeginTweeningQueued( 3 ); // sleep
@@ -1026,18 +1027,10 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ
// //
// handle a step // handle a step
// //
if( m_DancingState == STATE_DANCING ) if( m_DancingState == STATE_DANCING && type == IET_FIRST_PRESS && !PREFSMAN->m_bAutoPlay && StyleI.IsValid() )
{
if( type == IET_FIRST_PRESS )
{
if( StyleI.IsValid() )
{
if( GAMESTATE->IsPlayerEnabled( StyleI.player ) ) if( GAMESTATE->IsPlayerEnabled( StyleI.player ) )
m_Player[StyleI.player].Step( StyleI.col ); m_Player[StyleI.player].Step( StyleI.col );
} }
}
}
}
void SaveChanges() void SaveChanges()
{ {
+1
View File
@@ -94,6 +94,7 @@ private:
BitmapText m_textSongOptions; BitmapText m_textSongOptions;
BitmapText m_textDebug; BitmapText m_textDebug;
BitmapText m_textAutoPlay; // shows whether AutoPlay is on.
TransitionFadeWipe m_Fade; TransitionFadeWipe m_Fade;
+1 -1
View File
@@ -44,7 +44,7 @@ OptionLineData g_GraphicOptionsLines[NUM_GRAPHIC_OPTIONS_LINES] = {
{ "Texture Res", 3, {"256","512","1024"} }, { "Texture Res", 3, {"256","512","1024"} },
{ "Refresh Rate", 11, {"MAX","DEFAULT","60","70","72","75","80","85","90","100","120"} }, { "Refresh Rate", 11, {"MAX","DEFAULT","60","70","72","75","80","85","90","100","120"} },
{ "Show Stats", 2, {"OFF","ON"} }, { "Show Stats", 2, {"OFF","ON"} },
{ "BG Mode", 6, {"OFF","ANIMATIONS","VISUALIZATIONS","RANDOM MOVIES","fsdflksjfdlksjdflksfdj","fsdflksjfdlksjdflksfdj"} }, { "BG Mode", 4, {"OFF","ANIMATIONS","VISUALIZATIONS","RANDOM MOVIES"} },
{ "BG Brightness", 5, {"20%","40%","60%","80%","100%"} }, { "BG Brightness", 5, {"20%","40%","60%","80%","100%"} },
{ "Movie Decode", 4, {"1ms","2ms","3ms","4ms"} }, { "Movie Decode", 4, {"1ms","2ms","3ms","4ms"} },
{ "BG For Banner", 2, {"NO", "YES (slow)"} }, { "BG For Banner", 2, {"NO", "YES (slow)"} },
+2 -2
View File
@@ -65,8 +65,8 @@ ScreenManager::ScreenManager()
m_textSystemMessage.LoadFromFont( THEME->GetPathTo("Fonts","normal") ); m_textSystemMessage.LoadFromFont( THEME->GetPathTo("Fonts","normal") );
m_textSystemMessage.SetHorizAlign( Actor::align_left ); m_textSystemMessage.SetHorizAlign( Actor::align_left );
m_textSystemMessage.SetVertAlign( Actor::align_bottom ); m_textSystemMessage.SetVertAlign( Actor::align_top );
m_textSystemMessage.SetXY( 5.0f, 10.0f ); m_textSystemMessage.SetXY( 4.0f, 4.0f );
m_textSystemMessage.SetZoom( 0.5f ); m_textSystemMessage.SetZoom( 0.5f );
m_textSystemMessage.SetShadowLength( 2 ); m_textSystemMessage.SetShadowLength( 2 );
m_textSystemMessage.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); m_textSystemMessage.SetDiffuseColor( D3DXCOLOR(1,1,1,0) );
+160
View File
@@ -0,0 +1,160 @@
#include "stdafx.h"
/*
-----------------------------------------------------------------------------
Class: ScreenTextEntry
Desc: See header.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "ScreenTextEntry.h"
#include "PrefsManager.h"
#include "ScreenManager.h"
#include "RageMusic.h"
#include "ScreenTitleMenu.h"
#include "GameConstantsAndTypes.h"
#include "PrefsManager.h"
const float QUESTION_X = CENTER_X;
const float QUESTION_Y = CENTER_Y - 60;
const float ANSWER_X = CENTER_X;
const float ANSWER_Y = CENTER_Y + 120;
const float ANSWER_WIDTH = 440;
const float ANSWER_HEIGHT = 30;
ScreenTextEntry::ScreenTextEntry( ScreenMessage SM_SendWhenDone, CString sQuestion, CString sInitialAnswer, void(*OnOK)(CString sAnswer), void(*OnCancel)() )
{
m_SMSendWhenDone = SM_SendWhenDone;
m_pOnOK = OnOK;
m_pOnCancel = OnCancel;
m_sAnswer = sInitialAnswer;
m_Fade.SetTransitionTime( 0.5f );
m_Fade.SetDiffuseColor( D3DXCOLOR(0,0,0,0.7f) );
m_Fade.SetOpened();
m_Fade.CloseWipingRight();
this->AddSubActor( &m_Fade );
m_textQuestion.LoadFromFont( THEME->GetPathTo("Fonts","normal") );
m_textQuestion.SetText( sQuestion );
m_textQuestion.SetXY( QUESTION_X, QUESTION_Y );
this->AddSubActor( &m_textQuestion );
m_rectAnswerBox.SetDiffuseColor( D3DXCOLOR(0.5f,0.5f,1.0f,0.7f) );
this->AddSubActor( &m_rectAnswerBox );
m_rectAnswerBox.SetXY( ANSWER_X, ANSWER_Y );
m_rectAnswerBox.SetZoomX( ANSWER_WIDTH );
m_rectAnswerBox.SetZoomY( ANSWER_HEIGHT );
this->AddSubActor( &m_rectAnswerBox );
m_textAnswer.LoadFromFont( THEME->GetPathTo("Fonts","header1") );
m_textAnswer.LoadFromFont( THEME->GetPathTo("Fonts","header1") );
m_textAnswer.SetXY( ANSWER_X, ANSWER_Y );
m_textAnswer.SetText( m_sAnswer );
this->AddSubActor( &m_textAnswer );
SOUND->PlayOnceStreamed( THEME->GetPathTo("Sounds","menu prompt") );
}
void ScreenTextEntry::Update( float fDeltaTime )
{
Screen::Update( fDeltaTime );
}
void ScreenTextEntry::DrawPrimitives()
{
Screen::DrawPrimitives();
}
void ScreenTextEntry::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI )
{
if( m_Fade.IsOpening() )
return;
if( type != IET_FIRST_PRESS )
return;
switch( DeviceI.button )
{
case DIK_ESCAPE:
m_bCancelled = true;
MenuStart(PLAYER_1);
break;
case DIK_RETURN:
MenuStart(PLAYER_1);
break;
case DIK_BACK:
m_sAnswer = m_sAnswer.Left( max(0,m_sAnswer.GetLength()-1) );
m_textAnswer.SetText( m_sAnswer );
break;
default:
char c;
c = DeviceI.ToChar();
if( c != '\0' )
m_sAnswer += c;
m_textAnswer.SetText( m_sAnswer );
break;
}
Screen::Input( DeviceI, type, GameI, MenuI, StyleI );
}
void ScreenTextEntry::HandleScreenMessage( const ScreenMessage SM )
{
switch( SM )
{
case SM_DoneClosingWipingLeft:
break;
case SM_DoneClosingWipingRight:
break;
case SM_DoneOpeningWipingLeft:
break;
case SM_DoneOpeningWipingRight:
SCREENMAN->PopTopScreen( m_SMSendWhenDone );
break;
}
}
void ScreenTextEntry::MenuLeft( const PlayerNumber p )
{
}
void ScreenTextEntry::MenuRight( const PlayerNumber p )
{
}
void ScreenTextEntry::MenuStart( const PlayerNumber p )
{
m_Fade.OpenWipingRight( SM_DoneOpeningWipingRight );
m_textQuestion.BeginTweening( 0.2f );
m_textQuestion.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) );
m_rectAnswerBox.BeginTweening( 0.2f );
m_rectAnswerBox.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) );
m_textAnswer.SetEffectNone();
m_textAnswer.BeginTweening( 0.2f );
m_textAnswer.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) );
SOUND->PlayOnceStreamed( THEME->GetPathTo("Sounds","menu start") );
if( m_bCancelled )
if( m_pOnCancel )
m_pOnCancel();
else
if( m_pOnOK )
m_pOnOK( m_sAnswer );
}
void ScreenTextEntry::MenuBack( const PlayerNumber p )
{
m_bCancelled = true;
MenuStart(p);
}
+49
View File
@@ -0,0 +1,49 @@
/*
-----------------------------------------------------------------------------
Class: ScreenTextEntry
Desc: Displays a text entry box over the top of another screen. Must use by calling
SCREENMAN->AddScreenToTop( new ScreenTextEntry(...) );
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "Screen.h"
#include "BitmapText.h"
#include "TransitionFade.h"
#include "Quad.h"
#include "RandomSample.h"
class ScreenTextEntry : public Screen
{
public:
ScreenTextEntry();
ScreenTextEntry( ScreenMessage SM_SendWhenDone, CString sQuestion, CString sInitialAnswer, void(*OnOK)(CString sAnswer) = NULL, void(*OnCanel)() = NULL );
virtual void Update( float fDeltaTime );
virtual void DrawPrimitives();
virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI );
virtual void HandleScreenMessage( const ScreenMessage SM );
protected:
virtual void MenuLeft( const PlayerNumber p );
virtual void MenuRight( const PlayerNumber p );
virtual void MenuStart( const PlayerNumber p );
virtual void MenuBack( const PlayerNumber p );
TransitionFade m_Fade;
BitmapText m_textQuestion;
Quad m_rectAnswerBox;
CString m_sAnswer;
BitmapText m_textAnswer;
ScreenMessage m_SMSendWhenDone;
void(*m_pOnOK)( CString sAnswer );
void(*m_pOnCancel)();
bool m_bCancelled;
};
+1 -1
View File
@@ -27,7 +27,7 @@ SnapDisplay::SnapDisplay()
this->AddSubActor( &m_sprIndicators[i] ); this->AddSubActor( &m_sprIndicators[i] );
} }
m_NoteType = NOTE_4TH; m_NoteType = NOTE_TYPE_4TH;
D3DXCOLOR color = NoteTypeToColor( m_NoteType ); D3DXCOLOR color = NoteTypeToColor( m_NoteType );
for( i=0; i<2; i++ ) for( i=0; i<2; i++ )
+28 -28
View File
@@ -70,11 +70,11 @@ void SortStopSegmentsArray( CArray<StopSegment,StopSegment&> &arrayStopSegments
qsort( arrayStopSegments.GetData(), arrayStopSegments.GetSize(), sizeof(StopSegment), CompareStopSegments ); qsort( arrayStopSegments.GetData(), arrayStopSegments.GetSize(), sizeof(StopSegment), CompareStopSegments );
} }
int CompareAnimationSegments(const void *arg1, const void *arg2) int CompareBackgroundChanges(const void *arg1, const void *arg2)
{ {
// arg1 and arg2 are of type Step** // arg1 and arg2 are of type Step**
const AnimationSegment* seg1 = (const AnimationSegment*)arg1; const BackgroundChange* seg1 = (const BackgroundChange*)arg1;
const AnimationSegment* seg2 = (const AnimationSegment*)arg2; const BackgroundChange* seg2 = (const BackgroundChange*)arg2;
float score1 = seg1->m_fStartBeat; float score1 = seg1->m_fStartBeat;
float score2 = seg2->m_fStartBeat; float score2 = seg2->m_fStartBeat;
@@ -87,9 +87,9 @@ int CompareAnimationSegments(const void *arg1, const void *arg2)
return 1; return 1;
} }
void SortAnimationSegmentsArray( CArray<AnimationSegment,AnimationSegment&> &arrayAnimationSegments ) void SortBackgroundChangesArray( CArray<BackgroundChange,BackgroundChange&> &arrayBackgroundChanges )
{ {
qsort( arrayAnimationSegments.GetData(), arrayAnimationSegments.GetSize(), sizeof(AnimationSegment), CompareAnimationSegments ); qsort( arrayBackgroundChanges.GetData(), arrayBackgroundChanges.GetSize(), sizeof(BackgroundChange), CompareBackgroundChanges );
} }
@@ -131,10 +131,10 @@ void Song::AddStopSegment( StopSegment seg )
} }
void Song::AddAnimationSegment( AnimationSegment seg ) void Song::AddBackgroundChange( BackgroundChange seg )
{ {
m_AnimationSegments.Add( seg ); m_BackgroundChanges.Add( seg );
SortAnimationSegmentsArray( m_AnimationSegments ); SortBackgroundChangesArray( m_BackgroundChanges );
} }
float Song::GetMusicStartBeat() const float Song::GetMusicStartBeat() const
@@ -486,7 +486,7 @@ bool Song::LoadFromBMSDir( CString sDir )
// index is in quarter beats starting at beat 0 // index is in quarter beats starting at beat 0
int iStepIndex = (int) ( (iMeasureNo + fPercentThroughMeasure) int iStepIndex = (int) ( (iMeasureNo + fPercentThroughMeasure)
* BEATS_PER_MEASURE * ELEMENTS_PER_BEAT ); * BEATS_PER_MEASURE * ROWS_PER_BEAT );
switch( iBMSTrackNo ) switch( iBMSTrackNo )
{ {
@@ -726,7 +726,7 @@ bool Song::LoadFromDWIFile( CString sPath )
{ {
CStringArray arrayFreezeValues; CStringArray arrayFreezeValues;
split( arrayFreezeExpressions[f], "=", arrayFreezeValues ); split( arrayFreezeExpressions[f], "=", arrayFreezeValues );
float fIndex = atoi( arrayFreezeValues[0] ) * ELEMENTS_PER_BEAT / 4.0f; float fIndex = atoi( arrayFreezeValues[0] ) * ROWS_PER_BEAT / 4.0f;
float fFreezeBeat = NoteRowToBeat( fIndex ); float fFreezeBeat = NoteRowToBeat( fIndex );
float fFreezeSeconds = (float)atof( arrayFreezeValues[1] ) / 1000.0f; float fFreezeSeconds = (float)atof( arrayFreezeValues[1] ) / 1000.0f;
@@ -744,7 +744,7 @@ bool Song::LoadFromDWIFile( CString sPath )
{ {
CStringArray arrayBPMChangeValues; CStringArray arrayBPMChangeValues;
split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues ); split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues );
float fIndex = atoi( arrayBPMChangeValues[0] ) * ELEMENTS_PER_BEAT / 4.0f; float fIndex = atoi( arrayBPMChangeValues[0] ) * ROWS_PER_BEAT / 4.0f;
float fBeat = NoteRowToBeat( fIndex ); float fBeat = NoteRowToBeat( fIndex );
float fNewBPM = (float)atof( arrayBPMChangeValues[1] ); float fNewBPM = (float)atof( arrayBPMChangeValues[1] );
@@ -887,20 +887,20 @@ bool Song::LoadFromSMFile( CString sPath )
} }
} }
else if( 0==stricmp(sValueName,"ANIMATIONS") ) else if( 0==stricmp(sValueName,"BGCHANGES") )
{ {
CStringArray arrayAnimationExpressions; CStringArray aBGChangeExpressions;
split( sParams[1], ",", arrayAnimationExpressions ); split( sParams[1], ",", aBGChangeExpressions );
for( int b=0; b<arrayAnimationExpressions.GetSize(); b++ ) for( int b=0; b<aBGChangeExpressions.GetSize(); b++ )
{ {
CStringArray arrayAnimationValues; CStringArray aBGChangeValues;
split( arrayAnimationExpressions[b], "=", arrayAnimationValues ); split( aBGChangeExpressions[b], "=", aBGChangeValues );
float fBeat = (float)atof( arrayAnimationValues[0] ); float fBeat = (float)atof( aBGChangeValues[0] );
CString sAnimName = arrayAnimationValues[1]; CString sBGName = aBGChangeValues[1];
sAnimName.MakeLower(); sBGName.MakeLower();
AddAnimationSegment( AnimationSegment(fBeat, sAnimName) ); AddBackgroundChange( BackgroundChange(fBeat, sBGName) );
} }
} }
@@ -1308,13 +1308,13 @@ void Song::SaveToSMFile( CString sPath )
} }
fprintf( fp, ";\n" ); fprintf( fp, ";\n" );
fprintf( fp, "#ANIMATIONS:" ); fprintf( fp, "#BGCHANGES:" );
for( i=0; i<m_AnimationSegments.GetSize(); i++ ) for( i=0; i<m_BackgroundChanges.GetSize(); i++ )
{ {
AnimationSegment &seg = m_AnimationSegments[i]; BackgroundChange &seg = m_BackgroundChanges[i];
fprintf( fp, "%.2f=%s", seg.m_fStartBeat, seg.m_sAnimationName ); fprintf( fp, "%.2f=%s", seg.m_fStartBeat, seg.m_sBGName );
if( i != m_AnimationSegments.GetSize()-1 ) if( i != m_BackgroundChanges.GetSize()-1 )
fprintf( fp, "," ); fprintf( fp, "," );
} }
fprintf( fp, ";\n" ); fprintf( fp, ";\n" );
@@ -1352,7 +1352,7 @@ void Song::SaveToSMAndDWIFile()
for( int i=0; i<m_StopSegments.GetSize(); i++ ) for( int i=0; i<m_StopSegments.GetSize(); i++ )
{ {
StopSegment &fs = m_StopSegments[i]; StopSegment &fs = m_StopSegments[i];
fprintf( fp, "%.2f=%.2f", BeatToNoteRow( fs.m_fStartBeat ) / ELEMENTS_PER_BEAT * 4.0f, roundf(fs.m_fStopSeconds*1000) ); fprintf( fp, "%.2f=%.2f", BeatToNoteRow( fs.m_fStartBeat ) / ROWS_PER_BEAT * 4.0f, roundf(fs.m_fStopSeconds*1000) );
if( i != m_StopSegments.GetSize()-1 ) if( i != m_StopSegments.GetSize()-1 )
fprintf( fp, "," ); fprintf( fp, "," );
} }
@@ -1362,7 +1362,7 @@ void Song::SaveToSMAndDWIFile()
for( i=1; i<m_BPMSegments.GetSize(); i++ ) for( i=1; i<m_BPMSegments.GetSize(); i++ )
{ {
BPMSegment &bs = m_BPMSegments[i]; BPMSegment &bs = m_BPMSegments[i];
fprintf( fp, "%.2f=%.2f", BeatToNoteRow( bs.m_fStartBeat ) / ELEMENTS_PER_BEAT * 4.0f, bs.m_fBPM ); fprintf( fp, "%.2f=%.2f", BeatToNoteRow( bs.m_fStartBeat ) / ROWS_PER_BEAT * 4.0f, bs.m_fBPM );
if( i != m_BPMSegments.GetSize()-1 ) if( i != m_BPMSegments.GetSize()-1 )
fprintf( fp, "," ); fprintf( fp, "," );
} }
+8
View File
@@ -1152,6 +1152,14 @@ SOURCE=.\ScreenStage.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\ScreenTextEntry.cpp
# End Source File
# Begin Source File
SOURCE=.\ScreenTextEntry.h
# End Source File
# Begin Source File
SOURCE=.\ScreenTitleMenu.cpp SOURCE=.\ScreenTitleMenu.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
+6
View File
@@ -320,6 +320,12 @@
<File <File
RelativePath="ScreenStage.h"> RelativePath="ScreenStage.h">
</File> </File>
<File
RelativePath="ScreenTextEntry.cpp">
</File>
<File
RelativePath="ScreenTextEntry.h">
</File>
<File <File
RelativePath="ScreenTitleMenu.cpp"> RelativePath="ScreenTitleMenu.cpp">
</File> </File>
+11 -11
View File
@@ -33,12 +33,12 @@ struct StopSegment
float m_fStopSeconds; float m_fStopSeconds;
}; };
struct AnimationSegment struct BackgroundChange
{ {
AnimationSegment() { m_fStartBeat = -1; }; BackgroundChange() { m_fStartBeat = -1; };
AnimationSegment( float s, CString sAnimName ) { m_fStartBeat = s; m_sAnimationName = sAnimName; }; BackgroundChange( float s, CString sBGName ) { m_fStartBeat = s; m_sBGName = sBGName; };
float m_fStartBeat; float m_fStartBeat;
CString m_sAnimationName; CString m_sBGName;
}; };
@@ -116,15 +116,15 @@ public:
bool HasBackground() {return m_sBackgroundFile != "" && IsAFile(GetBackgroundPath()); }; bool HasBackground() {return m_sBackgroundFile != "" && IsAFile(GetBackgroundPath()); };
bool HasCDTitle() {return m_sCDTitleFile != "" && IsAFile(GetCDTitlePath()); }; bool HasCDTitle() {return m_sCDTitleFile != "" && IsAFile(GetCDTitlePath()); };
bool HasMovieBackground() {return m_sMovieBackgroundFile != ""&& IsAFile(GetMovieBackgroundPath()); }; bool HasMovieBackground() {return m_sMovieBackgroundFile != ""&& IsAFile(GetMovieBackgroundPath()); };
bool HasBGChanges() {return m_BackgroundChanges.GetSize() > 0; };
CArray<BPMSegment, BPMSegment&> m_BPMSegments; // this must be sorted before gameplay CArray<BPMSegment, BPMSegment&> m_BPMSegments; // this must be sorted before gameplay
CArray<StopSegment, StopSegment&> m_StopSegments; // this must be sorted before gameplay CArray<StopSegment, StopSegment&> m_StopSegments; // this must be sorted before gameplay
CArray<AnimationSegment, AnimationSegment&> m_AnimationSegments; // this must be sorted before gameplay CArray<BackgroundChange, BackgroundChange&> m_BackgroundChanges; // this must be sorted before gameplay
void AddBPMSegment( BPMSegment seg ); void AddBPMSegment( BPMSegment seg );
void AddStopSegment( StopSegment seg ); void AddStopSegment( StopSegment seg );
void AddAnimationSegment( AnimationSegment seg ); void AddBackgroundChange( BackgroundChange seg );
void GetMinMaxBPM( float &fMinBPM, float &fMaxBPM ) const void GetMinMaxBPM( float &fMinBPM, float &fMaxBPM ) const
{ {
@@ -151,12 +151,12 @@ public:
break; break;
return m_BPMSegments[i]; return m_BPMSegments[i];
}; };
CString GetAnimationAtBeat( float fBeat ) CString GetBackgroundAtBeat( float fBeat )
{ {
for( int i=0; i<m_AnimationSegments.GetSize()-1; i++ ) for( int i=0; i<m_BackgroundChanges.GetSize()-1; i++ )
if( m_AnimationSegments[i+1].m_fStartBeat > fBeat ) if( m_BackgroundChanges[i+1].m_fStartBeat > fBeat )
break; break;
return m_AnimationSegments[i].m_sAnimationName; return m_BackgroundChanges[i].m_sBGName;
}; };
void GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, float &fBPSOut, bool &bFreezeOut ) const; void GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, float &fBPSOut, bool &bFreezeOut ) const;
float GetElapsedTimeFromBeat( float fBeat ) const; float GetElapsedTimeFromBeat( float fBeat ) const;