From a44b557d1bf3115ec735cd83fbe3f7d508acbd22 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Sat, 29 Jun 2002 11:59:09 +0000 Subject: [PATCH] no message --- stepmania/src/BitmapText.cpp | 2 + stepmania/src/BitmapText.h | 2 +- stepmania/src/CourseContentsFrame.cpp | 2 +- stepmania/src/FontManager.cpp | 2 +- stepmania/src/GameConstantsAndTypes.h | 22 +- stepmania/src/MusicWheel.cpp | 25 +- stepmania/src/MusicWheel.h | 6 +- stepmania/src/NoteData.cpp | 32 +- stepmania/src/NoteData.h | 2 +- stepmania/src/NoteField.cpp | 64 ++- stepmania/src/NoteField.h | 2 + stepmania/src/Player.cpp | 10 +- stepmania/src/RageDisplay.cpp | 12 + stepmania/src/RageDisplay.h | 2 +- stepmania/src/RageTextureManager.cpp | 6 +- stepmania/src/ScreenEdit.cpp | 609 +++++++++++++++++--------- stepmania/src/ScreenEdit.h | 27 +- stepmania/src/ScreenEditMenu.cpp | 61 ++- stepmania/src/ScreenEditMenu.h | 5 +- stepmania/src/ScreenEvaluation.cpp | 6 + stepmania/src/ScreenGameplay.cpp | 18 +- stepmania/src/ScreenMusicScroll.cpp | 4 +- stepmania/src/ScreenSelectMusic.cpp | 4 +- stepmania/src/ScreenTitleMenu.cpp | 16 +- stepmania/src/ScreenTitleMenu.h | 1 - stepmania/src/Song.cpp | 186 +++----- stepmania/src/SongManager.cpp | 16 +- stepmania/src/StepMania.vcproj | 12 - stepmania/src/TextBanner.cpp | 6 +- stepmania/src/song.h | 117 +++-- 30 files changed, 748 insertions(+), 531 deletions(-) diff --git a/stepmania/src/BitmapText.cpp b/stepmania/src/BitmapText.cpp index 01b189a67e..565d95fba4 100644 --- a/stepmania/src/BitmapText.cpp +++ b/stepmania/src/BitmapText.cpp @@ -80,6 +80,8 @@ void BitmapText::SetText( CString sText ) // // save the string and crop if necessary // + ASSERT( sText.GetLength() < MAX_TEXT_CHARS/2 ); + strncpy( m_szText, sText, MAX_TEXT_CHARS ); m_szText[MAX_TEXT_CHARS-1] = '\0'; diff --git a/stepmania/src/BitmapText.h b/stepmania/src/BitmapText.h index 83fb052c4f..1e3b5082c8 100644 --- a/stepmania/src/BitmapText.h +++ b/stepmania/src/BitmapText.h @@ -15,7 +15,7 @@ #include "Font.h" -const int MAX_TEXT_LINES = 20; +const int MAX_TEXT_LINES = 40; const int MAX_TEXT_CHARS = MAX_NUM_QUADS; class BitmapText : public Actor diff --git a/stepmania/src/CourseContentsFrame.cpp b/stepmania/src/CourseContentsFrame.cpp index 3f01dd6f38..d909d64df4 100644 --- a/stepmania/src/CourseContentsFrame.cpp +++ b/stepmania/src/CourseContentsFrame.cpp @@ -60,7 +60,7 @@ void CourseContentsFrame::SetFromCourse( Course* pCourse ) for( i=0; im_iStages-1; i++ ) { - m_textContents[i].SetText( pCourse->m_apSongs[i]->GetMainTitle() ); + m_textContents[i].SetText( pCourse->m_apSongs[i]->GetFullTitle() ); m_textContents[i].SetDiffuseColor( DifficultyClassToColor(pCourse->m_apNotes[i]->m_DifficultyClass) ); m_Meters[i].SetFromNotes( pCourse->m_apNotes[i] ); diff --git a/stepmania/src/FontManager.cpp b/stepmania/src/FontManager.cpp index 37ac6b96b4..45f57739fc 100644 --- a/stepmania/src/FontManager.cpp +++ b/stepmania/src/FontManager.cpp @@ -115,7 +115,7 @@ void FontManager::UnloadFont( CString sFontFilePath ) pFont->m_iRefCount--; if( pFont->m_iRefCount == 0 ) // there are no more references to this texture { - LOG->WriteLine( ssprintf("FontManager: '%s' will be deleted. It has %d references.", sFontFilePath, pFont->m_iRefCount) ); + LOG->WriteLine( "FontManager: '%s' will be deleted. It has %d references.", sFontFilePath, pFont->m_iRefCount ); SAFE_DELETE( pFont ); // free the texture m_mapPathToFont.RemoveKey( sFontFilePath ); // and remove the key in the map } diff --git a/stepmania/src/GameConstantsAndTypes.h b/stepmania/src/GameConstantsAndTypes.h index 7cd8f967fa..e45dc3c626 100644 --- a/stepmania/src/GameConstantsAndTypes.h +++ b/stepmania/src/GameConstantsAndTypes.h @@ -45,15 +45,12 @@ enum TRACK_11, TRACK_12, TRACK_13, - TRACK_14, - TRACK_15, - TRACK_16, MAX_NOTE_TRACKS // leave this at the end }; -const int MAX_MEASURES = 200; // this should be long enough to hold 10:00 minute songs ( +const int MAX_BEATS = 300 * 2; // 300 bpm * 2 mins const int BEATS_PER_MEASURE = 4; -const int MAX_BEATS = MAX_MEASURES * 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 ELEMENTS_PER_MEASURE = ELEMENTS_PER_BEAT * BEATS_PER_MEASURE; @@ -146,6 +143,17 @@ inline D3DXCOLOR DifficultyClassToColor( DifficultyClass dc ) } } +inline CString DifficultyClassToString( DifficultyClass dc ) +{ + switch( dc ) + { + case CLASS_EASY: return "easy"; + case CLASS_MEDIUM: return "medium"; + case CLASS_HARD: return "hard"; + default: ASSERT(0); return ""; // invalid DifficultyClass + } +} + enum NotesType { NOTES_TYPE_DANCE_SINGLE = 0, @@ -448,7 +456,3 @@ inline int HoldNoteScoreToDancePoints( HoldNoteScore hns ) default: ASSERT(0); return 0; } } - - - - diff --git a/stepmania/src/MusicWheel.cpp b/stepmania/src/MusicWheel.cpp index 3be029a750..0a0112febc 100644 --- a/stepmania/src/MusicWheel.cpp +++ b/stepmania/src/MusicWheel.cpp @@ -24,6 +24,7 @@ const float FADE_TIME = 1.0f; const float SWITCH_MUSIC_TIME = 0.15f; +const float SAMPLE_MUSIC_DELAY = 0.15f; const float ROULETTE_SWITCH_MUSIC_TIME = SWITCH_MUSIC_TIME/2; const int ROULETTE_SWITCHES_IN_SLOWING_DOWN = 5; @@ -485,14 +486,14 @@ void MusicWheel::BuildWheelItemDatas( CArray &arr if( sThisSection != sLastSection ) // new section, make a section item { WheelItemData &WID = arrayWheelItemDatas[iCurWheelItem++]; - colorSection = (so==SORT_TITLE) ? SONGMAN->GetGroupColor(pSong->GetGroupName()) : SECTION_COLORS[iSectionColorIndex]; + colorSection = (so==SORT_TITLE) ? SONGMAN->GetGroupColor(pSong->m_sGroupName) : SECTION_COLORS[iSectionColorIndex]; iSectionColorIndex = (iSectionColorIndex+1) % NUM_SECTION_COLORS; WID.Load( TYPE_SECTION, NULL, sThisSection, NULL, colorSection ); sLastSection = sThisSection; } WheelItemData &WID = arrayWheelItemDatas[iCurWheelItem++]; - WID.Load( TYPE_SONG, pSong, sThisSection, NULL, SONGMAN->GetGroupColor(pSong->GetGroupName()) ); + WID.Load( TYPE_SONG, pSong, sThisSection, NULL, SONGMAN->GetGroupColor(pSong->m_sGroupName) ); } arrayWheelItemDatas.SetSize( iCurWheelItem ); // make sure we have enough room for all music and section items } @@ -504,7 +505,7 @@ void MusicWheel::BuildWheelItemDatas( CArray &arr { Song* pSong = arraySongs[i]; WheelItemData &WID = arrayWheelItemDatas[i]; - WID.Load( TYPE_SONG, pSong, "", NULL, SONGMAN->GetGroupColor(pSong->GetGroupName()) ); + WID.Load( TYPE_SONG, pSong, "", NULL, SONGMAN->GetGroupColor(pSong->m_sGroupName) ); } } } @@ -873,9 +874,23 @@ void MusicWheel::Update( float fDeltaTime ) fSpinSpeed = 0.6f + fabsf(m_fPositionOffsetFromSelection)/SWITCH_MUSIC_TIME; if( m_fPositionOffsetFromSelection > 0 ) - m_fPositionOffsetFromSelection = max( 0, m_fPositionOffsetFromSelection - fSpinSpeed*fDeltaTime ); + { + m_fPositionOffsetFromSelection -= fSpinSpeed*fDeltaTime; + if( m_fPositionOffsetFromSelection < 0 ) + { + m_fPositionOffsetFromSelection = 0; + m_fTimeLeftBeforePlayMusicSample = SAMPLE_MUSIC_DELAY; + } + } else if( m_fPositionOffsetFromSelection < 0 ) - m_fPositionOffsetFromSelection = min( 0, m_fPositionOffsetFromSelection + fSpinSpeed*fDeltaTime ); + { + m_fPositionOffsetFromSelection += fSpinSpeed*fDeltaTime; + if( m_fPositionOffsetFromSelection > 0 ) + { + m_fPositionOffsetFromSelection = 0; + m_fTimeLeftBeforePlayMusicSample = SAMPLE_MUSIC_DELAY; + } + } } } diff --git a/stepmania/src/MusicWheel.h b/stepmania/src/MusicWheel.h index 34bde465a0..7560c81670 100644 --- a/stepmania/src/MusicWheel.h +++ b/stepmania/src/MusicWheel.h @@ -185,17 +185,17 @@ protected: switch( so ) { case SORT_GROUP: - sTemp = pSong->GetGroupName(); + sTemp = pSong->m_sGroupName; return sTemp; // case SORT_ARTIST: -// sTemp = pSong->GetArtist(); +// sTemp = pSong->m_sArtist; // sTemp.MakeUpper(); // sTemp = (sTemp.GetLength() > 0) ? sTemp.Left(1) : ""; // if( IsAnInt(sTemp) ) // sTemp = "NUM"; // return sTemp; case SORT_TITLE: - sTemp = pSong->GetMainTitle(); + sTemp = pSong->GetFullTitle(); sTemp.MakeUpper(); sTemp = (sTemp.GetLength() > 0) ? sTemp.Left(1) : ""; if( IsAnInt(sTemp) ) diff --git a/stepmania/src/NoteData.cpp b/stepmania/src/NoteData.cpp index c998cd284c..bb309199cf 100644 --- a/stepmania/src/NoteData.cpp +++ b/stepmania/src/NoteData.cpp @@ -104,29 +104,31 @@ void NoteData::ClearRange( int iNoteIndexBegin, int iNoteIndexEnd ) } -void NoteData::CopyRange( NoteData* pFrom, int iNoteIndexBegin, int iNoteIndexEnd ) +void NoteData::CopyRange( NoteData* pFrom, int iFromIndexBegin, int iFromIndexEnd, int iToIndexBegin ) { ASSERT( pFrom->m_iNumTracks == m_iNumTracks ); - int i; + if( iToIndexBegin == -1 ) + iToIndexBegin = iFromIndexBegin; + + pFrom->ConvertHoldNotesTo2sAnd3s(); + + int f, t; // copy recorded TapNotes - for( i=iNoteIndexBegin; i<=iNoteIndexEnd; i++ ) + f = iFromIndexBegin; + t = iToIndexBegin; + + while( f<=iFromIndexEnd ) { for( int c=0; cm_TapNotes[c][i]; + m_TapNotes[c][t] = pFrom->m_TapNotes[c][f]; + f++; + t++; } - // copy recorded HoldNotes - for( i=0; im_iNumHoldNotes; i++ ) - { - HoldNote hn = pFrom->m_HoldNotes[i]; - if( (hn.m_iStartIndex >= iNoteIndexBegin && hn.m_iStartIndex <= iNoteIndexEnd) || - (hn.m_iEndIndex >= iNoteIndexBegin && hn.m_iEndIndex <= iNoteIndexEnd) ) // overlap (kinda) - { - this->AddHoldNote( hn ); - } - } + pFrom->Convert2sAnd3sToHoldNotes(); + this->Convert2sAnd3sToHoldNotes(); } void NoteData::AddHoldNote( HoldNote add ) @@ -554,7 +556,7 @@ void NoteData::Convert2sAnd3sToHoldNotes() { for( int j=i+1; jm_iNumTracks; m_iNumHoldNotes = 0; CopyRange( pFrom, 0, MAX_TAP_NOTE_ROWS ); }; inline bool IsRowEmpty( int index ) diff --git a/stepmania/src/NoteField.cpp b/stepmania/src/NoteField.cpp index 078fb21748..24d2a30481 100644 --- a/stepmania/src/NoteField.cpp +++ b/stepmania/src/NoteField.cpp @@ -17,6 +17,7 @@ #include "ArrowEffects.h" #include "PrefsManager.h" #include "GameManager.h" +#include "SongManager.h" const float HOLD_NOTE_BITS_PER_BEAT = 6; const float HOLD_NOTE_BITS_PER_ROW = HOLD_NOTE_BITS_PER_BEAT / ELEMENTS_PER_BEAT; @@ -141,6 +142,8 @@ void NoteField::DrawMeasureBar( const int iIndex, const int iMeasureNo ) m_rectMeasureBar.SetDiffuseColor( D3DXCOLOR(0,0,0,0.5f) ); m_rectMeasureBar.Draw(); + m_textMeasureNumber.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); + m_textMeasureNumber.SetAddColor( D3DXCOLOR(1,1,1,0) ); m_textMeasureNumber.SetText( ssprintf("%d", iMeasureNo) ); m_textMeasureNumber.SetXY( -m_rectMeasureBar.GetZoomedWidth()/2 + 10, fYPos ); m_textMeasureNumber.Draw(); @@ -158,6 +161,30 @@ void NoteField::DrawMarkerBar( const int iIndex ) m_rectMarkerBar.Draw(); } +void NoteField::DrawBPMText( const int iIndex, const float fBPM ) +{ + const float fYOffset = ArrowGetYOffset( m_PlayerOptions, (float)iIndex, m_fSongBeat ); + const float fYPos = ArrowGetYPos( m_PlayerOptions, fYOffset ); + + m_textMeasureNumber.SetDiffuseColor( D3DXCOLOR(1,0,0,1) ); + m_textMeasureNumber.SetAddColor( D3DXCOLOR(1,1,1,cosf(TIMER->GetTimeSinceStart()*2)/2+0.5f) ); + m_textMeasureNumber.SetText( ssprintf("%.2f", fBPM) ); + m_textMeasureNumber.SetXY( -m_rectMeasureBar.GetZoomedWidth()/2 - 50, fYPos ); + m_textMeasureNumber.Draw(); +} + +void NoteField::DrawFreezeText( const int iIndex, const float fSecs ) +{ + const float fYOffset = ArrowGetYOffset( m_PlayerOptions, (float)iIndex, m_fSongBeat ); + const float fYPos = ArrowGetYPos( m_PlayerOptions, fYOffset ); + + m_textMeasureNumber.SetDiffuseColor( D3DXCOLOR(0,0,0.6f,1) ); + m_textMeasureNumber.SetAddColor( D3DXCOLOR(1,1,1,cosf(TIMER->GetTimeSinceStart()*2)/2+0.5f) ); + m_textMeasureNumber.SetText( ssprintf("%.2f", fSecs) ); + m_textMeasureNumber.SetXY( -m_rectMeasureBar.GetZoomedWidth()/2 - 20, fYPos ); + m_textMeasureNumber.Draw(); +} + void NoteField::DrawPrimitives() { //LOG->WriteLine( "NoteField::DrawPrimitives()" ); @@ -173,23 +200,38 @@ void NoteField::DrawPrimitives() //LOG->WriteLine( "Drawing elements %d through %d", iIndexFirstArrowToDraw, iIndexLastArrowToDraw ); - // - // Draw measure bars - // if( m_Mode == MODE_EDITING ) { + // + // Draw measure bars + // for( int i=iIndexFirstArrowToDraw; i<=iIndexLastArrowToDraw; i++ ) { if( i % ELEMENTS_PER_MEASURE == 0 ) - DrawMeasureBar( i, i / ELEMENTS_PER_MEASURE ); + DrawMeasureBar( i, i / ELEMENTS_PER_MEASURE + 1 ); } - } - // - // Draw marker bars - // - if( m_Mode == MODE_EDITING ) - { + // + // BPM text + // + CArray &aBPMSegments = SONGMAN->GetCurrentSong()->m_BPMSegments; + for( i=0; i &aFreezeSegments = SONGMAN->GetCurrentSong()->m_FreezeSegments; + for( i=0; iGetRadarValue( (RadarCatrgory)r, SONGMAN->GetCurrentSong()->GetMusicLengthSeconds() ); - GSreturn.fRadarActual[r] = this->GetActualRadarValue( (RadarCatrgory)r, SONGMAN->GetCurrentSong()->GetMusicLengthSeconds() ); + GSreturn.fRadarPossible[r] = this->GetRadarValue( (RadarCatrgory)r, SONGMAN->GetCurrentSong()->m_fMusicLengthSeconds ); + GSreturn.fRadarActual[r] = this->GetActualRadarValue( (RadarCatrgory)r, SONGMAN->GetCurrentSong()->m_fMusicLengthSeconds ); GSreturn.fRadarPossible[r] = clamp( GSreturn.fRadarPossible[r], 0, 1 ); GSreturn.fRadarActual[r] = clamp( GSreturn.fRadarActual[r], 0, 1 ); diff --git a/stepmania/src/RageDisplay.cpp b/stepmania/src/RageDisplay.cpp index f521b726e8..b8843d8776 100644 --- a/stepmania/src/RageDisplay.cpp +++ b/stepmania/src/RageDisplay.cpp @@ -227,6 +227,18 @@ bool RageDisplay::SwitchDisplayMode( if( m_pd3dDevice == NULL ) { + D3DADAPTER_IDENTIFIER8 identifier; + if( FAILED( hr = m_pd3d->GetAdapterIdentifier( D3DADAPTER_DEFAULT, 0, &identifier ) ) ) + { + LOG->WriteLineHr( hr, "GetAdapterIdentifier failed" ); + return false; + } + + LOG->WriteLine( "Driver: %s. Description: %s.", + identifier.Driver, + identifier.Description + ); + // device is not yet created. We need to create it if( FAILED( hr = m_pd3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd, diff --git a/stepmania/src/RageDisplay.h b/stepmania/src/RageDisplay.h index 863ae2b563..81131c69de 100644 --- a/stepmania/src/RageDisplay.h +++ b/stepmania/src/RageDisplay.h @@ -29,7 +29,7 @@ struct RAGEVERTEX #define D3DFVF_RAGEVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1) -const int MAX_NUM_QUADS = 1000; +const int MAX_NUM_QUADS = 2048; const int MAX_NUM_INDICIES = MAX_NUM_QUADS*3; // two triangles per quad const int MAX_NUM_VERTICIES = MAX_NUM_QUADS*4; // 4 verticies per quad diff --git a/stepmania/src/RageTextureManager.cpp b/stepmania/src/RageTextureManager.cpp index d6637d3a28..989078001f 100644 --- a/stepmania/src/RageTextureManager.cpp +++ b/stepmania/src/RageTextureManager.cpp @@ -94,6 +94,8 @@ RageTexture* RageTextureManager::LoadTexture( CString sTexturePath, bool bForceR m_mapPathToTexture.SetAt( sTexturePath, pTexture ); } + LOG->WriteLine( "Display: %u MB video memory left", DISPLAY->GetDevice()->GetAvailableTextureMem() ); + return pTexture; } @@ -118,7 +120,7 @@ void RageTextureManager::UnloadTexture( CString sTexturePath ) if( sTexturePath == "" ) { - LOG->WriteLine( "RageTextureManager::UnloadTexture(): tried to Unload a blank texture." ); + //LOG->WriteLine( "RageTextureManager::UnloadTexture(): tried to Unload a blank texture." ); return; } @@ -129,7 +131,7 @@ void RageTextureManager::UnloadTexture( CString sTexturePath ) pTexture->m_iRefCount--; if( pTexture->m_iRefCount == 0 ) // there are no more references to this texture { - LOG->WriteLine( ssprintf("RageTextureManager: '%s' will be deleted. It has %d references.", sTexturePath, pTexture->m_iRefCount) ); + LOG->WriteLine( "RageTextureManager: '%s' will be deleted. It has %d references.", sTexturePath, pTexture->m_iRefCount ); SAFE_DELETE( pTexture ); // free the texture m_mapPathToTexture.RemoveKey( sTexturePath ); // and remove the key in the map } diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp index 4f1e5479be..2b9f9754d4 100644 --- a/stepmania/src/ScreenEdit.cpp +++ b/stepmania/src/ScreenEdit.cpp @@ -1,11 +1,12 @@ #include "stdafx.h" /* ----------------------------------------------------------------------------- - File: ScreenEdit.h + Class: ScreenEdit - Desc: The music plays, the notes scroll, and the Player is pressing buttons. + Desc: See header. Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford ----------------------------------------------------------------------------- */ @@ -34,17 +35,47 @@ const float GRAY_ARROW_Y = ARROW_SIZE * 1.5; const float DEBUG_X = SCREEN_LEFT + 10; const float DEBUG_Y = CENTER_Y-100; -const float EXPLANATION_X = SCREEN_LEFT + 10; -const float EXPLANATION_Y = SCREEN_BOTTOM - 10; // top aligned +const float HELP_X = SCREEN_LEFT + 10; +const float HELP_Y = CENTER_Y; // top aligned -const float INFO_X = SCREEN_LEFT + 10; -const float INFO_Y = SCREEN_TOP + 10; // bottom aligned +const float INFO_X = SCREEN_RIGHT - 10 ; +const float INFO_Y = SCREEN_BOTTOM - 10; // bottom aligned const float MENU_WIDTH = 110; const float EDIT_CENTER_X = CENTER_X + 100; const float EDIT_GRAY_Y = CENTER_Y - 2.0f * (float)ARROW_SIZE; +const CString HELP_TEXT = + "Esc: exit\n" + "S: save changes\n" + "Up/Down: change beat\n" + "Left/Right: change snap\n" + "PgUp/PgDn: jump 1 measure\n" + "Home/End: jump to first/last beat\n" + "Number keys: add or remove tap note\n" + "To create a hold note, hold a number key\n" + " while changing the beat pressing Up/Down\n" + "Enter/Space: set begin/end selection markers\n" + "G/H/J/K/L: Snap selected notes to nearest\n" + " 4th / 8th / 12th / 16th / 12th or 16th\n" + "P: Play selected area\n" + "R: Record in selected area\n" + "X: Cut selected area\n" + "C: Copy selected area\n" + "V: Paste at current beat\n" + "D: Toggle difficulty\n" + "Ins: Insert blank beat\n" + "Del: Delete current beat and shift\n" + "F1,F2/F3,F4: Decrease/increase BPM at cur beat\n" + "F5,F6/F7,F8: Dec/inc freeze secs at cur beat\n" + "F9,F10/F11,F12: Decrease/increase music offset\n" + "NumPad / * - + : Dec/inc music preview start\n" + "NumPad 0/period: Dec/inc music length\n" + "M: Play music preview\n"; + + + const ScreenMessage SM_GoToPrevState = ScreenMessage(SM_User+1); const ScreenMessage SM_GoToNextState = ScreenMessage(SM_User+2); @@ -64,6 +95,7 @@ ScreenEdit::ScreenEdit() m_PlayerOptions.m_ColorType = PlayerOptions::COLOR_NOTE; // m_PlayerOptions.m_bShowMeasureBars = true; + m_DifficultyClass = CLASS_EASY; m_sprBackground.Load( THEME->GetPathTo( GRAPHIC_EDIT_BACKGROUND ) ); m_sprBackground.StretchTo( CRect(SCREEN_LEFT,SCREEN_TOP,SCREEN_RIGHT,SCREEN_BOTTOM) ); @@ -102,48 +134,28 @@ ScreenEdit::ScreenEdit() m_Fade.SetClosed(); - m_textExplanation.Load( THEME->GetPathTo(FONT_NORMAL) ); - m_textExplanation.SetXY( EXPLANATION_X, EXPLANATION_Y ); - m_textExplanation.SetHorizAlign( Actor::align_left ); - m_textExplanation.SetVertAlign( Actor::align_top ); - m_textExplanation.SetZoom( 0.5f ); - m_textExplanation.SetShadowLength( 2 ); - m_textExplanation.SetText( - "Up,Down: change beat\n" - "PgUp,PgDn: jump 1 measure\n" - "Left,Right: change snap\n" - "Number keys: add/remove\n" - " tap step\n" - "S: save\n" - "Escape: exit\n" - "To create a hold note,\n" - " keep number key\n" - " depressed while\n" - " pressing Up/Down\n" - "Snap marked area to:\n" - " Z: quarters\n" - " X: eighths\n" - " C: triplets\n" - " V: sixteenths\n" - " B: nearest 16th or triplet\n" - "P: Play back marked area\n" - "R: Record marked area\n" - ); - - m_textInfo.Load( THEME->GetPathTo(FONT_NORMAL) ); m_textInfo.SetXY( INFO_X, INFO_Y ); - m_textInfo.SetHorizAlign( Actor::align_left ); - m_textInfo.SetVertAlign( Actor::align_bottom ); + m_textInfo.SetHorizAlign( Actor::align_right ); + m_textInfo.SetVertAlign( Actor::align_top ); m_textInfo.SetZoom( 0.5f ); + m_textInfo.SetShadowLength( 2 ); //m_textInfo.SetText(); // set this below every frame + m_textHelp.Load( THEME->GetPathTo(FONT_NORMAL) ); + m_textHelp.SetXY( HELP_X, HELP_Y ); + m_textHelp.SetHorizAlign( Actor::align_left ); + m_textHelp.SetZoom( 0.5f ); + m_textHelp.SetShadowLength( 2 ); + m_textHelp.SetText( HELP_TEXT ); - m_soundChangeLine.Load( THEME->GetPathTo(SOUND_EDIT_CHANGE_LINE) ); + + m_soundChangeLine.Load( THEME->GetPathTo(SOUND_EDIT_CHANGE_LINE), 10 ); m_soundChangeSnap.Load( THEME->GetPathTo(SOUND_EDIT_CHANGE_SNAP) ); m_soundMarker.Load( THEME->GetPathTo(SOUND_EDIT_CHANGE_SNAP) ); m_soundInvalid.Load( THEME->GetPathTo(SOUND_MENU_INVALID) ); + m_soundMusic.Load( m_pSong->GetMusicPath() ); m_soundMusic.SetPlaybackRate( 0.5f ); @@ -187,7 +199,7 @@ void ScreenEdit::Update( float fDeltaTime ) m_GrayArrowRowEdit.Update( fDeltaTime, m_fBeat ); m_NoteFieldEdit.Update( fDeltaTime, m_fBeat ); m_Fade.Update( fDeltaTime ); - m_textExplanation.Update( fDeltaTime ); + m_textHelp.Update( fDeltaTime ); m_textInfo.Update( fDeltaTime ); if( m_Mode == MODE_RECORD || m_Mode == MODE_PLAY ) @@ -209,20 +221,26 @@ void ScreenEdit::Update( float fDeltaTime ) //LOG->WriteLine( "ScreenEdit::Update(%f)", fDeltaTime ); Screen::Update( fDeltaTime ); - if( m_fTrailingBeat != m_fBeat ) + + // Update trailing beat + float fDelta = m_fBeat - m_fTrailingBeat; + + if( fabsf(fDelta) < 0.01 ) { - float fOffset = m_fBeat-m_fTrailingBeat; - float fSign = fOffset/fabsf(fOffset); - - float fBeatsToMove = fDeltaTime * 20; - - if( fabsf(fBeatsToMove) > 2 ) - m_fTrailingBeat = m_fBeat; - else if( fabsf(fOffset) < fBeatsToMove ) - m_fTrailingBeat = m_fBeat; - else - m_fTrailingBeat += fBeatsToMove * fSign; + m_fTrailingBeat = m_fBeat; // snap } + else + { + float fSign = fDelta / fabsf(fDelta); + float fMoveDelta = fSign*fDeltaTime*40; + if( fabsf(fMoveDelta) > fabsf(fDelta) ) + fMoveDelta = fDelta; + m_fTrailingBeat += fMoveDelta; + + if( fabsf(fDelta) > 10 ) + m_fTrailingBeat += fDelta * fDeltaTime*5; + } + // float fSongBeat, fBPS; /// float fPositionSeconds = m_soundMusic.GetPositionSeconds(); @@ -247,20 +265,32 @@ void ScreenEdit::Update( float fDeltaTime ) default: ASSERT( false ); } - m_textInfo.SetText( - ssprintf( - "Beat = %f\n" - "Begin Marker = beat %f\n" - "End Marker = beat %f\n" - "Difficulty = %s\n" - "Snap = %s", - m_fBeat, - m_NoteFieldEdit.m_fBeginMarker, - m_NoteFieldEdit.m_fEndMarker, - "not yet implemented", - sNoteType - ) - ); + static int iNumTapNotes = 0, iNumHoldNotes = 0; + static int iCounter = 0; + + iCounter++; + if( iCounter % 30 == 0 ) + { + iNumTapNotes = m_NoteFieldEdit.GetNumTapNotes(); + iNumHoldNotes = m_NoteFieldEdit.GetNumHoldNotes(); + } + + m_textInfo.SetText( ssprintf( + "Snap = %s\n" + "Beat = %.2f\n" + "Selection = begin: %.2f, end: %.2f\n" + "Difficulty = %s\n" + "Description = %s\n" + "Num notes tap: %d, hold: %d\n" + "Preview start: %.2f, length = %.2f\n", + sNoteType, + m_fBeat, + m_NoteFieldEdit.m_fBeginMarker, m_NoteFieldEdit.m_fEndMarker, + DifficultyClassToString( m_DifficultyClass ), + SONGMAN->GetCurrentNotes(PLAYER_1) ? SONGMAN->GetCurrentNotes(PLAYER_1)->m_sDescription : "no description", + iNumTapNotes, iNumHoldNotes, + m_pSong->m_fMusicSampleStartSeconds, m_pSong->m_fMusicSampleLengthSeconds + ) ); } @@ -269,10 +299,10 @@ void ScreenEdit::DrawPrimitives() m_sprBackground.Draw(); m_GranularityIndicator.Draw(); m_GrayArrowRowEdit.Draw(); + m_textHelp.Draw(); m_NoteFieldEdit.Draw(); - m_Fade.Draw(); - m_textExplanation.Draw(); m_textInfo.Draw(); + m_Fade.Draw(); if( m_Mode == MODE_RECORD || m_Mode == MODE_PLAY ) { @@ -299,9 +329,9 @@ void ScreenEdit::Input( const DeviceInput& DeviceI, const InputEventType type, c switch( m_Mode ) { - case MODE_EDIT: InputEdit( DeviceI, type, GameI, MenuI, StyleI ); break; + case MODE_EDIT: InputEdit( DeviceI, type, GameI, MenuI, StyleI ); break; case MODE_RECORD: InputRecord( DeviceI, type, GameI, MenuI, StyleI ); break; - case MODE_PLAY: InputPlay( DeviceI, type, GameI, MenuI, StyleI ); break; + case MODE_PLAY: InputPlay( DeviceI, type, GameI, MenuI, StyleI ); break; } } @@ -324,107 +354,119 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ case DIK_7: case DIK_8: case DIK_9: + case DIK_0: { - if( type != IET_FIRST_PRESS ) - break; // We only care about first presses + if( type != IET_FIRST_PRESS ) + break; // We only care about first presses - int iCol = DeviceI.button - DIK_1; - const int iNoteIndex = BeatToNoteRow( m_fBeat ); + int iCol = DeviceI.button - DIK_1; + const int iNoteIndex = BeatToNoteRow( m_fBeat ); - if( iCol >= m_NoteFieldEdit.m_iNumTracks ) // this button is not in the range of columns for this StyleDef - break; + if( iCol >= m_NoteFieldEdit.m_iNumTracks ) // this button is not in the range of columns for this StyleDef + break; - // check for to see if the user intended to remove a HoldNote - bool bRemovedAHoldNote = false; - for( int i=0; i= hn.m_iStartIndex && iNoteIndex <= hn.m_iEndIndex ) // the cursor lies within this HoldNote + // check for to see if the user intended to remove a HoldNote + bool bRemovedAHoldNote = false; + for( int i=0; i= hn.m_iStartIndex && iNoteIndex <= hn.m_iEndIndex ) // the cursor lies within this HoldNote + { + m_NoteFieldEdit.RemoveHoldNote( i ); + bRemovedAHoldNote = true; + break; // stop iterating over all HoldNotes + } } - } - if( !bRemovedAHoldNote ) - { - // We didn't remove a HoldNote, so the user wants to add or delete a TapNote - if( m_NoteFieldEdit.m_TapNotes[iCol][iNoteIndex] == '0' ) - m_NoteFieldEdit.m_TapNotes[iCol][iNoteIndex] = '1'; - else - m_NoteFieldEdit.m_TapNotes[iCol][iNoteIndex] = '0'; - } + if( !bRemovedAHoldNote ) + { + // We didn't remove a HoldNote, so the user wants to add or delete a TapNote + if( m_NoteFieldEdit.m_TapNotes[iCol][iNoteIndex] == '0' ) + m_NoteFieldEdit.m_TapNotes[iCol][iNoteIndex] = '1'; + else + m_NoteFieldEdit.m_TapNotes[iCol][iNoteIndex] = '0'; + } } break; case DIK_ESCAPE: SCREENMAN->SetNewScreen( new ScreenEditMenu ); break; case DIK_S: - // copy edit into current Notes - Notes* pNotes; - pNotes = SONGMAN->GetCurrentNotes(PLAYER_1); - - if( pNotes == NULL ) { - // allocate a new Notes - SONGMAN->GetCurrentSong()->m_arrayNotes.SetSize( SONGMAN->GetCurrentSong()->m_arrayNotes.GetSize() + 1 ); - pNotes = SONGMAN->GetCurrentSong()->m_arrayNotes[ SONGMAN->GetCurrentSong()->m_arrayNotes.GetSize()-1 ]; - pNotes->m_NotesType = GAMEMAN->m_CurNotesType; - pNotes->m_sDescription = "Untitled"; - pNotes->m_iMeter = 1; - } + // copy edit into current Notes + Notes* pNotes; + pNotes = SONGMAN->GetCurrentNotes(PLAYER_1); - pNotes->SetNoteData( (NoteData*)&m_NoteFieldEdit ); - SONGMAN->GetCurrentSong()->Save(); + if( pNotes == NULL ) + { + // allocate a new Notes + SONGMAN->GetCurrentSong()->m_arrayNotes.SetSize( SONGMAN->GetCurrentSong()->m_arrayNotes.GetSize() + 1 ); + pNotes = SONGMAN->GetCurrentSong()->m_arrayNotes[ SONGMAN->GetCurrentSong()->m_arrayNotes.GetSize()-1 ]; + pNotes->m_NotesType = GAMEMAN->m_CurNotesType; + pNotes->m_sDescription = "Untitled"; + pNotes->m_iMeter = 1; + } + + pNotes->SetNoteData( (NoteData*)&m_NoteFieldEdit ); + SONGMAN->GetCurrentSong()->Save(); + } break; case DIK_UP: case DIK_DOWN: case DIK_PGUP: case DIK_PGDN: { - float fBeatsToMove; - switch( DeviceI.button ) - { - case DIK_UP: - case DIK_DOWN: - fBeatsToMove = NoteTypeToBeat( m_GranularityIndicator.GetSnapMode() ); - if( DeviceI.button == DIK_UP ) - fBeatsToMove *= -1; - break; - case DIK_PGUP: - case DIK_PGDN: - fBeatsToMove = BEATS_PER_MEASURE; - if( DeviceI.button == DIK_PGUP ) - fBeatsToMove *= -1; - } - - const int iStartIndex = BeatToNoteRow(m_fBeat); - const int iEndIndex = BeatToNoteRow(m_fBeat + fBeatsToMove); - - // check to see if they're holding a button - for( int col=0; colIsBeingPressed(di); - - if( bIsBeingHeld ) + float fBeatsToMove; + switch( DeviceI.button ) { - // create a new hold note - HoldNote newHN; - newHN.m_iTrack = col; - newHN.m_iStartIndex = min(iStartIndex, iEndIndex); - newHN.m_iEndIndex = max(iStartIndex, iEndIndex); - m_NoteFieldEdit.AddHoldNote( newHN ); + case DIK_UP: + case DIK_DOWN: + fBeatsToMove = NoteTypeToBeat( m_GranularityIndicator.GetSnapMode() ); + if( DeviceI.button == DIK_UP ) + fBeatsToMove *= -1; + break; + case DIK_PGUP: + case DIK_PGDN: + fBeatsToMove = BEATS_PER_MEASURE; + if( DeviceI.button == DIK_PGUP ) + fBeatsToMove *= -1; } - } - m_fBeat += fBeatsToMove; - m_fBeat = clamp( m_fBeat, 0, MAX_BEATS-1 ); - m_soundChangeLine.PlayRandom(); + const int iStartIndex = BeatToNoteRow(m_fBeat); + const int iEndIndex = BeatToNoteRow(m_fBeat + fBeatsToMove); + + // check to see if they're holding a button + for( int col=0; colIsBeingPressed(di); + + if( bIsBeingHeld ) + { + // create a new hold note + HoldNote newHN; + newHN.m_iTrack = col; + newHN.m_iStartIndex = min(iStartIndex, iEndIndex); + newHN.m_iEndIndex = max(iStartIndex, iEndIndex); + m_NoteFieldEdit.AddHoldNote( newHN ); + } + } + + m_fBeat += fBeatsToMove; + m_fBeat = clamp( m_fBeat, 0, MAX_BEATS-1 ); + m_fBeat = froundf( m_fBeat, NoteTypeToBeat(m_GranularityIndicator.GetSnapMode()) ); + m_soundChangeLine.Play(); } break; + case DIK_HOME: + m_fBeat = 0; + m_soundChangeLine.Play(); + break; + case DIK_END: + m_fBeat = m_NoteFieldEdit.GetLastBeat(); + m_soundChangeLine.Play(); + break; case DIK_RIGHT: m_GranularityIndicator.PrevSnapMode(); OnSnapModeChange(); @@ -433,109 +475,258 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ m_GranularityIndicator.NextSnapMode(); OnSnapModeChange(); break; - case DIK_HOME: + case DIK_RETURN: if( m_NoteFieldEdit.m_fEndMarker != -1 && m_fBeat > m_NoteFieldEdit.m_fEndMarker ) { // invalid! The begin maker must be placed before the end marker - m_soundInvalid.PlayRandom(); + m_soundInvalid.Play(); } else { m_NoteFieldEdit.m_fBeginMarker = m_fBeat; - m_soundMarker.PlayRandom(); + m_soundMarker.Play(); } break; - case DIK_END: + case DIK_SPACE: if( m_NoteFieldEdit.m_fBeginMarker != -1 && m_fBeat < m_NoteFieldEdit.m_fBeginMarker ) { // invalid! The end maker must be placed after the begin marker - m_soundInvalid.PlayRandom(); + m_soundInvalid.Play(); } else { m_NoteFieldEdit.m_fEndMarker = m_fBeat; - m_soundMarker.PlayRandom(); + m_soundMarker.Play(); } break; - case DIK_Z: - case DIK_X: - case DIK_C: - case DIK_V: - case DIK_B: + case DIK_G: + case DIK_H: + case DIK_J: + case DIK_K: + case DIK_L: { - - if( m_NoteFieldEdit.m_fBeginMarker == -1 || m_NoteFieldEdit.m_fEndMarker == -1 ) - { - m_soundInvalid.PlayRandom(); - } - else - { - NoteType noteType1; - NoteType noteType2; - switch( DeviceI.button ) + if( m_NoteFieldEdit.m_fBeginMarker == -1 || m_NoteFieldEdit.m_fEndMarker == -1 ) { - case DIK_Z: noteType1 = NOTE_4TH; noteType2 = NOTE_4TH; break; - case DIK_X: noteType1 = NOTE_8TH; noteType2 = NOTE_8TH; break; - case DIK_C: noteType1 = NOTE_12TH; noteType2 = NOTE_12TH; break; - case DIK_V: noteType1 = NOTE_16TH; noteType2 = NOTE_16TH; break; - case DIK_B: noteType1 = NOTE_12TH; noteType2 = NOTE_16TH; break; - default: ASSERT( false ); + m_soundInvalid.Play(); } + else + { + NoteType noteType1; + NoteType noteType2; + switch( DeviceI.button ) + { + case DIK_G: noteType1 = NOTE_4TH; noteType2 = NOTE_4TH; break; + case DIK_H: noteType1 = NOTE_8TH; noteType2 = NOTE_8TH; break; + case DIK_J: noteType1 = NOTE_12TH; noteType2 = NOTE_12TH; break; + case DIK_K: noteType1 = NOTE_16TH; noteType2 = NOTE_16TH; break; + case DIK_L: noteType1 = NOTE_12TH; noteType2 = NOTE_16TH; break; + default: ASSERT( false ); + } - m_NoteFieldEdit.SnapToNearestNoteType( noteType1, noteType2, m_NoteFieldEdit.m_fBeginMarker, m_NoteFieldEdit.m_fEndMarker ); - } - + m_NoteFieldEdit.SnapToNearestNoteType( noteType1, noteType2, m_NoteFieldEdit.m_fBeginMarker, m_NoteFieldEdit.m_fEndMarker ); + } } break; case DIK_P: { - if( m_NoteFieldEdit.m_fBeginMarker == -1 || m_NoteFieldEdit.m_fEndMarker == -1 ) - { - m_soundInvalid.PlayRandom(); - break; - } + if( m_NoteFieldEdit.m_fBeginMarker == -1 || m_NoteFieldEdit.m_fEndMarker == -1 ) + { + m_soundInvalid.Play(); + break; + } - m_fBeat = m_NoteFieldEdit.m_fBeginMarker; + m_fBeat = m_NoteFieldEdit.m_fBeginMarker; - m_Mode = MODE_PLAY; + m_Mode = MODE_PLAY; - m_Player.Load( PLAYER_1, GAMEMAN->GetCurrentStyleDef(), (NoteData*)&m_NoteFieldEdit, PlayerOptions(), NULL, NULL, 1 ); + m_Player.Load( PLAYER_1, GAMEMAN->GetCurrentStyleDef(), (NoteData*)&m_NoteFieldEdit, PlayerOptions(), NULL, NULL, 1 ); - m_rectRecordBack.BeginTweening( 0.5f ); - m_rectRecordBack.SetTweenDiffuseColor( D3DXCOLOR(0,0,0,0.5f) ); + m_rectRecordBack.BeginTweening( 0.5f ); + m_rectRecordBack.SetTweenDiffuseColor( D3DXCOLOR(0,0,0,0.5f) ); - float fElapsedSeconds = max( 0, m_pSong->GetElapsedTimeFromBeat(m_fBeat) ); - m_soundMusic.SetPositionSeconds( fElapsedSeconds ); - m_soundMusic.Play(); - m_soundMusic.SetPlaybackRate( 1.0f ); + float fElapsedSeconds = max( 0, m_pSong->GetElapsedTimeFromBeat(m_fBeat) ); + m_soundMusic.SetPositionSeconds( fElapsedSeconds ); + m_soundMusic.Play(); + m_soundMusic.SetPlaybackRate( 1.0f ); } break; case DIK_R: + { + if( m_NoteFieldEdit.m_fBeginMarker == -1 || m_NoteFieldEdit.m_fEndMarker == -1 ) + { + m_soundInvalid.Play(); + break; + } + + m_fBeat = m_NoteFieldEdit.m_fBeginMarker; + + // initialize m_NoteFieldRecord + m_NoteFieldRecord.ClearAll(); + m_NoteFieldRecord.m_iNumTracks = m_NoteFieldEdit.m_iNumTracks; + m_NoteFieldRecord.m_fBeginMarker = m_NoteFieldEdit.m_fBeginMarker; + m_NoteFieldRecord.m_fEndMarker = m_NoteFieldEdit.m_fEndMarker; + + + m_Mode = MODE_RECORD; + m_rectRecordBack.BeginTweening( 0.5f ); + m_rectRecordBack.SetTweenDiffuseColor( D3DXCOLOR(0,0,0,0.5f) ); + + float fElapsedSeconds = max( 0, m_pSong->GetElapsedTimeFromBeat(m_fBeat) ); + m_soundMusic.SetPositionSeconds( fElapsedSeconds ); + m_soundMusic.Play(); + m_soundMusic.SetPlaybackRate( 0.5f ); + } + break; + case DIK_INSERT: + case DIK_DELETE: + { + NoteData temp; + int iTakeFromRow; + int iPasteAtRow; + switch( DeviceI.button ) + { + case DIK_INSERT: + iTakeFromRow = BeatToNoteRow( m_fBeat ); + iPasteAtRow = BeatToNoteRow( m_fBeat+1 ); + break; + case DIK_DELETE: + iTakeFromRow = BeatToNoteRow( m_fBeat+1 ); + iPasteAtRow = BeatToNoteRow( m_fBeat ); + break; + } + temp.CopyRange( &m_NoteFieldEdit, iTakeFromRow, MAX_TAP_NOTE_ROWS ); + m_NoteFieldEdit.ClearRange( min(iTakeFromRow,iPasteAtRow), MAX_TAP_NOTE_ROWS ); + m_NoteFieldEdit.CopyRange( &temp, 0, MAX_TAP_NOTE_ROWS-iTakeFromRow, iPasteAtRow ); + } + break; + case DIK_X: if( m_NoteFieldEdit.m_fBeginMarker == -1 || m_NoteFieldEdit.m_fEndMarker == -1 ) { - m_soundInvalid.PlayRandom(); - break; + m_soundInvalid.Play(); } + else + { + int iFirstRow = BeatToNoteRow( m_NoteFieldEdit.m_fBeginMarker ); + int iLastRow = BeatToNoteRow( m_NoteFieldEdit.m_fEndMarker ); - m_fBeat = m_NoteFieldEdit.m_fBeginMarker; - - // initialize m_NoteFieldRecord - m_NoteFieldRecord.ClearAll(); - m_NoteFieldRecord.m_iNumTracks = m_NoteFieldEdit.m_iNumTracks; - m_NoteFieldRecord.m_fBeginMarker = m_NoteFieldEdit.m_fBeginMarker; - m_NoteFieldRecord.m_fEndMarker = m_NoteFieldEdit.m_fEndMarker; - - - m_Mode = MODE_RECORD; - m_rectRecordBack.BeginTweening( 0.5f ); - m_rectRecordBack.SetTweenDiffuseColor( D3DXCOLOR(0,0,0,0.5f) ); - - float fElapsedSeconds = max( 0, m_pSong->GetElapsedTimeFromBeat(m_fBeat) ); - m_soundMusic.SetPositionSeconds( fElapsedSeconds ); - m_soundMusic.Play(); - m_soundMusic.SetPlaybackRate( 0.5f ); + m_Clipboard.CopyRange( &m_NoteFieldEdit, iFirstRow, iLastRow ); + m_NoteFieldEdit.ClearRange( iFirstRow, iLastRow ); + } break; - } + case DIK_C: + if( m_NoteFieldEdit.m_fBeginMarker == -1 || m_NoteFieldEdit.m_fEndMarker == -1 ) + { + m_soundInvalid.Play(); + } + else + { + int iFirstRow = BeatToNoteRow( m_NoteFieldEdit.m_fBeginMarker ); + int iLastRow = BeatToNoteRow( m_NoteFieldEdit.m_fEndMarker ); + + m_Clipboard.CopyRange( &m_NoteFieldEdit, iFirstRow, iLastRow ); + } + break; + case DIK_V: + { + int iSrcFirstRow = BeatToNoteRow( m_NoteFieldEdit.m_fBeginMarker ); + int iSrcLastRow = BeatToNoteRow( m_NoteFieldEdit.m_fEndMarker ); + int iDestFirstRow = BeatToNoteRow( m_fBeat ); + + m_NoteFieldEdit.CopyRange( &m_Clipboard, iSrcFirstRow, iSrcLastRow, iDestFirstRow ); + } + break; + + case DIK_D: + { + m_DifficultyClass = DifficultyClass( (m_DifficultyClass+1)%NUM_DIFFICULTY_CLASSES ); + } + break; + + case DIK_F1: + case DIK_F2: + case DIK_F3: + case DIK_F4: + { + float fBPM = m_pSong->GetBPMAtBeat( m_fBeat ); + float fNewBPM; + switch( DeviceI.button ) + { + case DIK_F1: fNewBPM = fBPM - 0.1f; break; + case DIK_F2: fNewBPM = fBPM + 0.1f; break; + case DIK_F3: fNewBPM = fBPM - 0.01f; break; + case DIK_F4: fNewBPM = fBPM + 0.01f; break; + default: ASSERT(0); + } + + for( int i=0; im_BPMSegments.GetSize(); i++ ) + if( m_pSong->m_BPMSegments[i].m_fStartBeat == m_fBeat ) + break; + + if( i == m_pSong->m_BPMSegments.GetSize() ) // there is no BPMSegment at the current beat + { + // create a new BPMSegment + m_pSong->AddBPMSegment( BPMSegment(m_fBeat, fNewBPM) ); + } + else // BPMSegment being modified is m_BPMSegments[i] + { + if( i > 0 && m_pSong->m_BPMSegments[i-1].m_fBPM == fNewBPM ) + m_pSong->m_BPMSegments.RemoveAt( i ); + else + m_pSong->m_BPMSegments[i].m_fBPM = fNewBPM; + } + } + break; + case DIK_F5: + case DIK_F6: + case DIK_F7: + case DIK_F8: + { + float fFreezeDelta; + switch( DeviceI.button ) + { + case DIK_F5: fFreezeDelta = -0.1f; break; + case DIK_F6: fFreezeDelta = +0.1f; break; + case DIK_F7: fFreezeDelta = -0.01f; break; + case DIK_F8: fFreezeDelta = +0.01f; break; + default: ASSERT(0); + } + + for( int i=0; im_FreezeSegments.GetSize(); i++ ) + { + if( m_pSong->m_FreezeSegments[i].m_fStartBeat == m_fBeat ) + break; + } + + if( i == m_pSong->m_FreezeSegments.GetSize() ) // there is no BPMSegment at the current beat + { + // create a new FreezeSegment + if( fFreezeDelta > 0 ) + m_pSong->AddFreezeSegment( FreezeSegment(m_fBeat, fFreezeDelta) ); + } + else // FreezeSegment being modified is m_FreezeSegments[i] + { + m_pSong->m_FreezeSegments[i].m_fFreezeSeconds += fFreezeDelta; + if( m_pSong->m_FreezeSegments[i].m_fFreezeSeconds < 0 ) + m_pSong->m_FreezeSegments.RemoveAt( i ); + } + } + break; + case DIK_F9: m_pSong->m_fOffsetInSeconds -= 0.1f; break; + case DIK_F10: m_pSong->m_fOffsetInSeconds += 0.1f; break; + case DIK_F11: m_pSong->m_fOffsetInSeconds -= 0.01f; break; + case DIK_F12: m_pSong->m_fOffsetInSeconds += 0.01f; break; + case DIK_M: + MUSIC->Load( m_pSong->GetMusicPath() ); + MUSIC->Play( false, m_pSong->m_fMusicSampleStartSeconds, m_pSong->m_fMusicSampleLengthSeconds ); + break; + case DIK_DIVIDE: m_pSong->m_fMusicSampleStartSeconds -= 0.1f; break; + case DIK_MULTIPLY: m_pSong->m_fMusicSampleStartSeconds += 0.1f; break; + case DIK_SUBTRACT: m_pSong->m_fMusicSampleStartSeconds -= 0.01f; break; + case DIK_ADD: m_pSong->m_fMusicSampleStartSeconds += 0.01f; break; + case DIK_NUMPAD0: m_pSong->m_fMusicSampleLengthSeconds -= 0.1f; break; + case DIK_NUMPADPERIOD: m_pSong->m_fMusicSampleLengthSeconds += 0.1f; break; + + } } } @@ -652,7 +843,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) void ScreenEdit::OnSnapModeChange() { - m_soundChangeSnap.PlayRandom(); + m_soundChangeSnap.Play(); NoteType nt = m_GranularityIndicator.GetSnapMode(); int iStepIndex = BeatToNoteRow( m_fBeat ); diff --git a/stepmania/src/ScreenEdit.h b/stepmania/src/ScreenEdit.h index 2de6143c05..2ab3848f91 100644 --- a/stepmania/src/ScreenEdit.h +++ b/stepmania/src/ScreenEdit.h @@ -1,10 +1,11 @@ /* ----------------------------------------------------------------------------- - File: ScreenEdit.h + Class: ScreenEdit - Desc: The music plays, the notes scroll, and the Player is pressing buttons. + Desc: Edit, record, playback, or synchronize notes. Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford ----------------------------------------------------------------------------- */ @@ -53,27 +54,29 @@ protected: GranularityIndicator m_GranularityIndicator; GrayArrowRow m_GrayArrowRowEdit; - BitmapText m_textExplanation; BitmapText m_textInfo; // status information that changes + BitmapText m_textHelp; // keep track of where we are and what we're doing - float m_fTrailingBeat; // this approaches m_fBeat - float m_fBeat; + float m_fTrailingBeat; // this approaches m_fBeat + float m_fBeat; + DifficultyClass m_DifficultyClass; + NoteData m_Clipboard; - RandomSample m_soundChangeLine; - RandomSample m_soundChangeSnap; - RandomSample m_soundMarker; - RandomSample m_soundInvalid; + RageSoundSample m_soundChangeLine; + RageSoundSample m_soundChangeSnap; + RageSoundSample m_soundMarker; + RageSoundSample m_soundInvalid; - TransitionFade m_Fade; + TransitionFade m_Fade; // for MODE_RECORD Quad m_rectRecordBack; - NoteField m_NoteFieldRecord; - GrayArrowRow m_GrayArrowRowRecord; + NoteField m_NoteFieldRecord; + GrayArrowRow m_GrayArrowRowRecord; // for MODE_PLAY diff --git a/stepmania/src/ScreenEditMenu.cpp b/stepmania/src/ScreenEditMenu.cpp index dc720a0cb2..d394926143 100644 --- a/stepmania/src/ScreenEditMenu.cpp +++ b/stepmania/src/ScreenEditMenu.cpp @@ -25,24 +25,29 @@ // // Defines specific to ScreenEditMenu // -const float LINE_START_Y = CENTER_Y-150; -const float LINE_GAP = 50; +const float GROUP_X = CENTER_X; +const float GROUP_Y = CENTER_Y - 160; -const float GROUP_X = CENTER_X; -const float GROUP_Y = LINE_START_Y + LINE_GAP; +const float SONG_BANNER_X = CENTER_X; +const float SONG_BANNER_Y = CENTER_Y - 80; -const float SONG_X = CENTER_X; -const float SONG_Y = GROUP_Y + LINE_GAP; +const float ARROWS_X[2] = { SONG_BANNER_X - 200, SONG_BANNER_X + 200 }; +const float ARROWS_Y[2] = { SONG_BANNER_Y, SONG_BANNER_Y }; -const float GAME_STYLE_X = CENTER_X; -const float GAME_STYLE_Y = SONG_Y + LINE_GAP; +const float SONG_TEXT_BANNER_X = CENTER_X; +const float SONG_TEXT_BANNER_Y = CENTER_Y - 10; -const float STEPS_X = CENTER_X; -const float STEPS_Y = GAME_STYLE_Y + LINE_GAP; +const float GAME_STYLE_X = CENTER_X; +const float GAME_STYLE_Y = CENTER_Y + 40; -const float EXPLANATION_X = CENTER_X; -const float EXPLANATION_Y = STEPS_Y + LINE_GAP*2; +const float STEPS_X = CENTER_X; +const float STEPS_Y = CENTER_Y + 90; +const float EXPLANATION_X = CENTER_X; +const float EXPLANATION_Y = SCREEN_BOTTOM - 70; +const CString EXPLANATION_TEXT = + "In this mode, you can edit existing notes patterns,\n" + "create note patterns, or synchronize notes with the music."; const ScreenMessage SM_GoToPrevState = ScreenMessage(SM_User+1); const ScreenMessage SM_GoToNextState = ScreenMessage(SM_User+2); @@ -67,10 +72,21 @@ ScreenEditMenu::ScreenEditMenu() m_textGroup.SetDiffuseColor( D3DXCOLOR(0.7f,0.7f,0.7f,1) ); this->AddActor( &m_textGroup ); - m_textSong.Load( THEME->GetPathTo(FONT_HEADER1) ); - m_textSong.SetXY( SONG_X, SONG_Y ); - m_textSong.SetDiffuseColor( D3DXCOLOR(0.7f,0.7f,0.7f,1) ); - this->AddActor( &m_textSong ); + m_Banner.SetXY( SONG_BANNER_X, SONG_BANNER_Y ); + this->AddActor( &m_Banner ); + + m_TextBanner.SetXY( SONG_TEXT_BANNER_X, SONG_TEXT_BANNER_Y ); + this->AddActor( &m_TextBanner ); + + m_sprArrowLeft.Load( THEME->GetPathTo(GRAPHIC_ARROWS_LEFT) ); + m_sprArrowLeft.SetXY( ARROWS_X[0], ARROWS_Y[0] ); + m_sprArrowLeft.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); + this->AddActor( &m_sprArrowLeft ); + + m_sprArrowRight.Load( THEME->GetPathTo(GRAPHIC_ARROWS_RIGHT) ); + m_sprArrowRight.SetXY( ARROWS_X[1], ARROWS_Y[1] ); + m_sprArrowRight.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); + this->AddActor( &m_sprArrowRight ); m_textNotesType.Load( THEME->GetPathTo(FONT_HEADER1) ); m_textNotesType.SetXY( GAME_STYLE_X, GAME_STYLE_Y ); @@ -89,7 +105,7 @@ ScreenEditMenu::ScreenEditMenu() m_textExplanation.Load( THEME->GetPathTo(FONT_NORMAL) ); m_textExplanation.SetXY( EXPLANATION_X, EXPLANATION_Y ); - m_textExplanation.SetText( ssprintf("This mode will allow you to\nedit existing notes patterns,\n or create new ones from scratch.") ); + m_textExplanation.SetText( EXPLANATION_TEXT ); m_textExplanation.SetZoom( 0.7f ); this->AddActor( &m_textExplanation ); @@ -163,7 +179,8 @@ void ScreenEditMenu::HandleScreenMessage( const ScreenMessage SM ) void ScreenEditMenu::BeforeRowChange() { m_textGroup.SetEffectNone(); - m_textSong.SetEffectNone(); + m_sprArrowLeft.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); + m_sprArrowRight.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); m_textNotesType.SetEffectNone(); m_textNotes.SetEffectNone(); } @@ -173,7 +190,10 @@ void ScreenEditMenu::AfterRowChange() switch( m_SelectedRow ) { case ROW_GROUP: m_textGroup.SetEffectGlowing(); break; - case ROW_SONG: m_textSong.SetEffectGlowing(); break; + case ROW_SONG: + m_sprArrowLeft.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); + m_sprArrowRight.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); + break; case ROW_NOTES_TYPE: m_textNotesType.SetEffectGlowing(); break; case ROW_STEPS: m_textNotes.SetEffectGlowing(); break; default: ASSERT(false); @@ -197,7 +217,8 @@ void ScreenEditMenu::OnSongChange() { m_iSelectedSong = clamp( m_iSelectedSong, 0, m_pSongs.GetSize()-1 ); - m_textSong.SetText( GetSelectedSong()->GetMainTitle() ); + m_Banner.LoadFromSong( GetSelectedSong() ); + m_TextBanner.LoadFromSong( GetSelectedSong() ); OnNotesTypeChange(); } diff --git a/stepmania/src/ScreenEditMenu.h b/stepmania/src/ScreenEditMenu.h index db45bb9e52..0e481586c6 100644 --- a/stepmania/src/ScreenEditMenu.h +++ b/stepmania/src/ScreenEditMenu.h @@ -65,7 +65,10 @@ private: CArray m_pSongs; int m_iSelectedSong; // index into m_pSongs - BitmapText m_textSong; + Banner m_Banner; + TextBanner m_TextBanner; + Sprite m_sprArrowLeft; + Sprite m_sprArrowRight; NotesType m_CurNotesType; // index into enum GameMode BitmapText m_textNotesType; diff --git a/stepmania/src/ScreenEvaluation.cpp b/stepmania/src/ScreenEvaluation.cpp index 5f6853a80c..41b8095ffb 100644 --- a/stepmania/src/ScreenEvaluation.cpp +++ b/stepmania/src/ScreenEvaluation.cpp @@ -662,6 +662,12 @@ void ScreenEvaluation::MenuStart( const PlayerNumber p ) { TweenOffScreen(); + if( PREFSMAN->m_bEventMode ) + { + PREFSMAN->m_iCurrentStageIndex++; + m_Menu.TweenOffScreenToMenu( SM_GoToSelectMusic ); + return; + } switch( m_ResultMode ) { diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index d7880121fb..eeb395b058 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -547,18 +547,10 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ { switch( DeviceI.button ) { - case DIK_F9: - m_pCurSong->SetBeatOffsetInSeconds( m_pCurSong->GetBeatOffsetInSeconds()-0.01f ); - break; - case DIK_F10: - m_pCurSong->SetBeatOffsetInSeconds( m_pCurSong->GetBeatOffsetInSeconds()+0.01f ); - break; - case DIK_F11: - m_pCurSong->SetBeatOffsetInSeconds( m_pCurSong->GetBeatOffsetInSeconds()-(1/fBPS) ); - break; - case DIK_F12: - m_pCurSong->SetBeatOffsetInSeconds( m_pCurSong->GetBeatOffsetInSeconds()+(1/fBPS) ); - break; + case DIK_F9: m_pCurSong->m_fOffsetInSeconds -= 0.01f; break; + case DIK_F10: m_pCurSong->m_fOffsetInSeconds += 0.01f; break; + case DIK_F11: m_pCurSong->m_fOffsetInSeconds -= 1/fBPS; break; + case DIK_F12: m_pCurSong->m_fOffsetInSeconds += 1/fBPS; break; } switch( DeviceI.button ) @@ -567,7 +559,7 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ case DIK_F10: case DIK_F11: case DIK_F12: - m_textDebug.SetText( ssprintf("Offset = %f.", m_pCurSong->GetBeatOffsetInSeconds()) ); + m_textDebug.SetText( ssprintf("Offset = %f.", m_pCurSong->m_fOffsetInSeconds) ); m_textDebug.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); m_textDebug.StopTweening(); m_textDebug.BeginTweeningQueued( 3 ); // sleep diff --git a/stepmania/src/ScreenMusicScroll.cpp b/stepmania/src/ScreenMusicScroll.cpp index d8770766be..aa6c2147ee 100644 --- a/stepmania/src/ScreenMusicScroll.cpp +++ b/stepmania/src/ScreenMusicScroll.cpp @@ -135,8 +135,8 @@ ScreenMusicScroll::ScreenMusicScroll() { Song* pSong = arraySongs[i]; m_textLines[m_iNumLines].Load( THEME->GetPathTo(FONT_NORMAL) ); - m_textLines[m_iNumLines].SetText( pSong->GetMainTitle() ); - m_textLines[m_iNumLines].SetDiffuseColor( SONGMAN->GetGroupColor(pSong->GetGroupName()) ); + m_textLines[m_iNumLines].SetText( pSong->GetFullTitle() ); + m_textLines[m_iNumLines].SetDiffuseColor( SONGMAN->GetGroupColor(pSong->m_sGroupName) ); m_iNumLines++; } diff --git a/stepmania/src/ScreenSelectMusic.cpp b/stepmania/src/ScreenSelectMusic.cpp index 0236dd6aa1..7730cd3891 100644 --- a/stepmania/src/ScreenSelectMusic.cpp +++ b/stepmania/src/ScreenSelectMusic.cpp @@ -501,10 +501,8 @@ void ScreenSelectMusic::PlayMusicSample() if( pSong->HasMusic() ) { - float fStartSeconds, fEndSeconds; - pSong->GetMusicSampleRange( fStartSeconds, fEndSeconds ); MUSIC->Load( sSongToPlay ); - MUSIC->Play( true, fStartSeconds, fEndSeconds ); + MUSIC->Play( true, pSong->m_fMusicSampleStartSeconds, pSong->m_fMusicSampleLengthSeconds ); } } diff --git a/stepmania/src/ScreenTitleMenu.cpp b/stepmania/src/ScreenTitleMenu.cpp index 9645259249..7f000b3861 100644 --- a/stepmania/src/ScreenTitleMenu.cpp +++ b/stepmania/src/ScreenTitleMenu.cpp @@ -15,7 +15,6 @@ #include "ScreenCaution.h" #include "ScreenMapInstruments.h" #include "ScreenGameOptions.h" -#include "ScreenSynchronizeMenu.h" #include "ScreenEdit.h" #include "GameConstantsAndTypes.h" #include "RageUtil.h" @@ -39,15 +38,14 @@ const CString CHOICE_TEXT[ScreenTitleMenu::NUM_TITLE_MENU_CHOICES] = { "GAME START", "SWITCH GAME", - "CONFIG INSTRUMENTS", + "KEY/JOY MAPPING", "GAME OPTIONS", - "SYNCHRONIZE", - "EDIT/RECORD", + "EDIT/RECORD/SYNCH", "EXIT", }; const float CHOICES_START_Y = 66; -const float CHOICES_GAP_Y = 50; +const float CHOICES_GAP_Y = 56; const float HELP_X = CENTER_X; const float HELP_Y = SCREEN_HEIGHT-55; @@ -59,7 +57,6 @@ const ScreenMessage SM_GoToSelectStyle = ScreenMessage(SM_User+3); const ScreenMessage SM_GoToSelectGame = ScreenMessage(SM_User+4); const ScreenMessage SM_GoToMapInstruments = ScreenMessage(SM_User+5); const ScreenMessage SM_GoToGameOptions = ScreenMessage(SM_User+6); -const ScreenMessage SM_GoToSynchronize = ScreenMessage(SM_User+9); const ScreenMessage SM_GoToEdit = ScreenMessage(SM_User+10); const ScreenMessage SM_DoneOpening = ScreenMessage(SM_User+11); const ScreenMessage SM_GoToEz2 = ScreenMessage(SM_User+12); @@ -196,9 +193,6 @@ void ScreenTitleMenu::HandleScreenMessage( const ScreenMessage SM ) case SM_GoToGameOptions: SCREENMAN->SetNewScreen( new ScreenGameOptions ); break; - case SM_GoToSynchronize: - SCREENMAN->SetNewScreen( new ScreenSynchronizeMenu ); - break; case SM_GoToEdit: SCREENMAN->SetNewScreen( new ScreenEditMenu ); break; @@ -286,10 +280,6 @@ void ScreenTitleMenu::MenuStart( const PlayerNumber p ) m_soundSelect.PlayRandom(); m_Fade.CloseWipingRight( SM_GoToGameOptions ); return; - case CHOICE_SYNCHRONIZE: - m_soundSelect.PlayRandom(); - m_Fade.CloseWipingRight( SM_GoToSynchronize ); - return; case CHOICE_EDIT: m_soundSelect.PlayRandom(); m_Fade.CloseWipingRight( SM_GoToEdit ); diff --git a/stepmania/src/ScreenTitleMenu.h b/stepmania/src/ScreenTitleMenu.h index b88563d69a..d3a1a199e6 100644 --- a/stepmania/src/ScreenTitleMenu.h +++ b/stepmania/src/ScreenTitleMenu.h @@ -33,7 +33,6 @@ public: CHOICE_SELECT_GAME, CHOICE_MAP_INSTRUMENTS, CHOICE_GAME_OPTIONS, - CHOICE_SYNCHRONIZE, CHOICE_EDIT, CHOICE_EXIT, NUM_TITLE_MENU_CHOICES // leave this at the end! diff --git a/stepmania/src/Song.cpp b/stepmania/src/Song.cpp index 06315ca5d1..b3bab04437 100644 --- a/stepmania/src/Song.cpp +++ b/stepmania/src/Song.cpp @@ -72,9 +72,10 @@ Song::Song() { m_bChangedSinceSave = false; m_fOffsetInSeconds = 0; - m_fMusicSampleStartSeconds = m_fMusicSampleLengthSeconds = -1; + m_fMusicSampleStartSeconds = 0; + m_fMusicSampleLengthSeconds = 16; // start fading out at m_fMusicSampleLengthSeconds-1 seconds m_iMusicBytes = 0; - m_fMusicLength = 0; + m_fMusicLengthSeconds = 0; } Song::~Song() @@ -314,7 +315,7 @@ bool Song::LoadFromBMSDir( CString sDir ) // Load the Song info from the first BMS file. Silly BMS duplicates the song info in every // file. So, we read the song data from only the first BMS file and assume that the info // is identical for every BMS file in the directory. - m_sSongFilePath = m_sSongDir + arrayBMSFileNames[0]; + m_sSongFile = arrayBMSFileNames[0]; // load the Notes from the rest of the BMS files for( int i=0; iWriteLine( "WARNING: Couldn't find tag '%s' in '%s'.", sTagToLookFor, m_sSongFilePath ); + LOG->WriteLine( "WARNING: Couldn't find tag '%s' in '%s'.", sTagToLookFor, GetSongFilePath() ); } else { @@ -529,11 +530,8 @@ bool Song::LoadFromBMSDir( CString sDir ) // open the song file again and and look for this tag's value CStdioFile file; - if( !file.Open( m_sSongFilePath, CFile::modeRead|CFile::shareDenyNone ) ) - { - throw RageException( "Failed to open %s.", m_sSongFilePath ); - return false; - } + if( !file.Open( GetSongFilePath(), CFile::modeRead|CFile::shareDenyNone ) ) + throw RageException( "Failed to open %s.", GetSongFilePath() ); CString line; while( file.ReadString(line) ) // foreach line @@ -587,7 +585,7 @@ bool Song::LoadFromBMSDir( CString sDir ) if( fFreezeSecs == -1 ) // we didn't find the line we were looking for { - LOG->WriteLine( "WARNING: Couldn't find tag '%s' in '%s'.", sTagToLookFor, m_sSongFilePath ); + LOG->WriteLine( "WARNING: Couldn't find tag '%s' in '%s'.", sTagToLookFor, GetSongFilePath() ); } else { @@ -616,13 +614,11 @@ bool Song::LoadFromDWIFile( CString sPath ) { LOG->WriteLine( "Song::LoadFromDWIFile(%s)", sPath ); - // save song file path - m_sSongFilePath = sPath; - - // save song dir + // save song dir and file name CString sDir, sFName, sExt; splitrelpath(sPath, sDir, sFName, sExt); m_sSongDir = sDir; + m_sSongFile = sFName+"."+sExt; // get group name sDir.MakeLower(); @@ -677,7 +673,7 @@ bool Song::LoadFromDWIFile( CString sPath ) // handle the data if( sValueName == "#FILE" ) - m_sMusicPath = arrayValueTokens[1]; + m_sMusicFile = arrayValueTokens[1]; else if( sValueName == "#TITLE" ) GetMainAndSubTitlesFromFullTitle( arrayValueTokens[1], m_sMainTitle, m_sSubTitle ); @@ -788,7 +784,7 @@ bool Song::LoadFromSMDir( CString sDir ) // Load the Song info from the first BMS file. Silly BMS duplicates the song info in every // file. So, we read the song data from only the first BMS file and assume that the info // is identical for every BMS file in the directory. - m_sSongFilePath = m_sSongDir + arraySongFileNames[0]; + m_sSongFile = arraySongFileNames[0]; CStringArray arrayNotesFileNames; @@ -863,23 +859,19 @@ bool Song::LoadFromSMDir( CString sDir ) m_sCredit = arrayValueTokens[1]; else if( sValueName == "#BANNER" ) - m_sBannerPath = sDir + "\\" + arrayValueTokens[1]; + m_sBannerFile = arrayValueTokens[1]; else if( sValueName == "#BACKGROUND" ) - m_sBackgroundPath = sDir + "\\" + arrayValueTokens[1]; + m_sBackgroundFile = arrayValueTokens[1]; else if( sValueName == "#BACKGROUNDMOVIE" ) - { - if( arrayValueTokens[1] != "" ) - m_sBackgroundMoviePath = sDir + "\\" + arrayValueTokens[1]; - } + m_sBackgroundMovieFile = arrayValueTokens[1]; + else if( sValueName == "#CDTITLE" ) - { - if( arrayValueTokens[1] != "" ) - m_sCDTitlePath = sDir + "\\" + arrayValueTokens[1]; - } + m_sCDTitleFile = arrayValueTokens[1]; + else if( sValueName == "#MUSIC" ) - m_sMusicPath = sDir + "\\" + arrayValueTokens[1]; + m_sMusicFile = arrayValueTokens[1]; else if( sValueName == "#MUSICBYTES" ) m_iMusicBytes = atoi( arrayValueTokens[1] ); @@ -955,7 +947,7 @@ void Song::TidyUpData() if( m_BPMSegments.GetSize() == 0 ) throw RageException( "No #BPM specified in '%s.'", GetSongFilePath() ); - if( m_sMusicPath == "" || !DoesFileExist(GetMusicPath()) ) + if( m_sMusicFile == "" || !DoesFileExist(GetMusicPath()) ) { CStringArray arrayPossibleMusic; GetDirListing( m_sSongDir + CString("*.mp3"), arrayPossibleMusic ); @@ -963,10 +955,9 @@ void Song::TidyUpData() GetDirListing( m_sSongDir + CString("*.wav"), arrayPossibleMusic ); if( arrayPossibleMusic.GetSize() != 0 ) // we found a match - m_sMusicPath = m_sSongDir + arrayPossibleMusic[0]; + m_sMusicFile = arrayPossibleMusic[0]; else - m_sMusicPath = ""; - // throw RageException( ssprintf("Music could not be found. Please check the Song file '%s' and verify the specified #MUSIC exists.", GetSongFilePath()) ); + throw RageException( "The song in '%s' is missing a music file. You must place a music file in the song folder or remove the song", m_sSongDir ); } // Save length of music @@ -974,12 +965,12 @@ void Song::TidyUpData() { RageSoundStream sound; sound.Load( GetMusicPath() ); - m_fMusicLength = sound.GetLengthSeconds(); + m_fMusicLengthSeconds = sound.GetLengthSeconds(); } if( !DoesFileExist(GetBannerPath()) ) { - m_sBannerPath = ""; + m_sBannerFile = ""; // find the smallest image in the directory CStringArray arrayPossibleBanners; @@ -996,21 +987,21 @@ void Song::TidyUpData() if( this_size < dwSmallestFileSoFar ) // we have a new leader! { dwSmallestFileSoFar = this_size; - sSmallestFileSoFar = m_sSongDir + arrayPossibleBanners[i]; + sSmallestFileSoFar = arrayPossibleBanners[i]; } } if( sSmallestFileSoFar != "" ) // we found a match - m_sBannerPath = sSmallestFileSoFar; + m_sBannerFile = sSmallestFileSoFar; else - m_sBannerPath = ""; + m_sBannerFile = ""; //throw RageException( ssprintf("Banner could not be found. Please check the Song file '%s' and verify the specified #BANNER exists.", GetSongFilePath()) ); } if( !DoesFileExist(GetBackgroundPath()) ) { - m_sBackgroundPath = ""; + m_sBackgroundFile = ""; // find the largest image in the directory CStringArray arrayPossibleBackgrounds; @@ -1027,17 +1018,17 @@ void Song::TidyUpData() if( this_size > dwLargestFileSoFar ) // we have a new leader! { dwLargestFileSoFar = this_size; - sLargestFileSoFar = m_sSongDir + arrayPossibleBackgrounds[i]; + sLargestFileSoFar = arrayPossibleBackgrounds[i]; } } if( sLargestFileSoFar != "" ) // we found a match - m_sBackgroundPath = sLargestFileSoFar; + m_sBackgroundFile = sLargestFileSoFar; } if( !DoesFileExist(GetBackgroundMoviePath()) ) { - m_sBackgroundMoviePath = ""; + m_sBackgroundMovieFile = ""; CStringArray arrayPossibleBackgroundMovies; GetDirListing( m_sSongDir + CString("*.avi"), arrayPossibleBackgroundMovies ); @@ -1045,19 +1036,19 @@ void Song::TidyUpData() GetDirListing( m_sSongDir + CString("*.mpeg"), arrayPossibleBackgroundMovies ); if( arrayPossibleBackgroundMovies.GetSize() > 0 ) // we found a match - m_sBackgroundMoviePath = arrayPossibleBackgroundMovies[0]; + m_sBackgroundMovieFile = arrayPossibleBackgroundMovies[0]; } if( !DoesFileExist(GetCDTitlePath()) ) { - m_sCDTitlePath = ""; + m_sCDTitleFile = ""; } for( int i=0; iGetMainTitle(); - CString sTitle2 = pSong2->GetMainTitle(); + CString sTitle1 = pSong1->GetFullTitle(); + CString sTitle2 = pSong2->GetFullTitle(); CString sFilePath1 = pSong1->GetSongFilePath(); // this is unique among songs CString sFilePath2 = pSong2->GetSongFilePath(); @@ -1396,8 +1344,8 @@ int CompareSongPointersByArtist(const void *arg1, const void *arg2) Song* pSong1 = *(Song**)arg1; Song* pSong2 = *(Song**)arg2; - CString sArtist1 = pSong1->GetArtist(); - CString sArtist2 = pSong2->GetArtist(); + CString sArtist1 = pSong1->m_sArtist; + CString sArtist2 = pSong2->m_sArtist; if( sArtist1 < sArtist2 ) return -1; @@ -1417,8 +1365,8 @@ int CompareSongPointersByGroup(const void *arg1, const void *arg2) Song* pSong1 = *(Song**)arg1; Song* pSong2 = *(Song**)arg2; - CString sGroup1 = pSong1->GetGroupName(); - CString sGroup2 = pSong2->GetGroupName(); + CString sGroup1 = pSong1->m_sGroupName; + CString sGroup2 = pSong2->m_sGroupName; if( sGroup1 < sGroup2 ) return -1; diff --git a/stepmania/src/SongManager.cpp b/stepmania/src/SongManager.cpp index b39d66941d..075374b774 100644 --- a/stepmania/src/SongManager.cpp +++ b/stepmania/src/SongManager.cpp @@ -97,7 +97,7 @@ void SongManager::InitSongArrayFromDisk() for( i=0; iGetGroupName(); + const CString sGroupName = m_pSongs[i]->m_sGroupName; if( m_arrayGroupNames.GetSize() == 0 || m_arrayGroupNames[m_arrayGroupNames.GetSize()-1] != sGroupName ) m_arrayGroupNames.Add( sGroupName ); @@ -262,13 +262,13 @@ void SongManager::ReadStatisticsFromDisk() // Each value has the format "SongName::StepsName=TimesPlayed::TopGrade::TopScore::MaxCombo". - char szSongName[256]; - char szStepsName[256]; + char szSongDir[256]; + char szNotesName[256]; int iRetVal; int i; // Parse for Song name and Notes name - iRetVal = sscanf( name_string, "%[^:]::%[^\n]", szSongName, szStepsName ); + iRetVal = sscanf( name_string, "%[^:]::%[^\n]", szSongDir, szNotesName ); if( iRetVal != 2 ) continue; // this line doesn't match what is expected @@ -277,7 +277,7 @@ void SongManager::ReadStatisticsFromDisk() Song* pSong = NULL; for( i=0; iGetMainTitle() == szSongName ) // match! + if( m_pSongs[i]->m_sSongDir == szSongDir ) // match! { pSong = m_pSongs[i]; break; @@ -291,7 +291,7 @@ void SongManager::ReadStatisticsFromDisk() Notes* pNotes = NULL; for( i=0; im_arrayNotes.GetSize(); i++ ) { - if( pSong->m_arrayNotes[i]->m_sDescription == szStepsName ) // match! + if( pSong->m_arrayNotes[i]->m_sDescription == szNotesName ) // match! { pNotes = pSong->m_arrayNotes[i]; break; @@ -339,7 +339,7 @@ void SongManager::SaveStatisticsToDisk() // Each value has the format "SongName::NotesName=TimesPlayed::TopGrade::TopScore::MaxCombo". - CString sName = ssprintf( "%s::%s", pSong->GetMainTitle(), pNotes->m_sDescription ); + CString sName = ssprintf( "%s::%s", pSong->m_sSongDir, pNotes->m_sDescription ); CString sValue = ssprintf( "%d::%s::%d::%d", pNotes->m_iNumTimesPlayed, @@ -389,7 +389,7 @@ void SongManager::GetSongsInGroup( const CString sGroupName, CArrayGetGroupName() ) + if( sGroupName == m_pSongs[i]->m_sGroupName ) AddTo.Add( pSong ); } SortSongPointerArrayByGroup( AddTo ); diff --git a/stepmania/src/StepMania.vcproj b/stepmania/src/StepMania.vcproj index 039fdc08e1..d78da0ba6b 100644 --- a/stepmania/src/StepMania.vcproj +++ b/stepmania/src/StepMania.vcproj @@ -301,18 +301,6 @@ - - - - - - - - diff --git a/stepmania/src/TextBanner.cpp b/stepmania/src/TextBanner.cpp index 339b04bf46..9e099ce7f7 100644 --- a/stepmania/src/TextBanner.cpp +++ b/stepmania/src/TextBanner.cpp @@ -50,12 +50,12 @@ bool TextBanner::LoadFromSong( Song* pSong ) return true; } - CString sMainTitle = pSong->GetMainTitle(); - CString sSubTitle = pSong->GetSubTitle(); + CString sMainTitle = pSong->m_sMainTitle; + CString sSubTitle = pSong->m_sSubTitle; m_textTitle.SetText( sMainTitle ); m_textSubTitle.SetText( sSubTitle ); - m_textArtist.SetText( "/" + pSong->GetArtist() ); + m_textArtist.SetText( "/" + pSong->m_sArtist ); float fTitleZoom, fSubTitleZoom, fArtistZoom; diff --git a/stepmania/src/song.h b/stepmania/src/song.h index 0690cd3f1d..4198abf965 100644 --- a/stepmania/src/song.h +++ b/stepmania/src/song.h @@ -19,7 +19,6 @@ //enum DanceStyle; // why is this needed? - struct BPMSegment { BPMSegment() { m_fStartBeat = m_fBPM = -1; }; @@ -45,6 +44,7 @@ public: bool LoadFromSongDir( CString sDir ); // calls one of the loads below void Save() { SaveToSMDir(); SaveToCacheFile(); }; + void SetChangedSinceLastSave() { m_bChangedSinceSave = true; } bool LoadFromCacheFile( bool bLoadNoteData ); @@ -60,35 +60,55 @@ protected: void DeleteCacheFile(); public: - CString GetSongFilePath() {return m_sSongFilePath; }; + + CString m_sSongFile; + CString m_sSongDir; + CString m_sGroupName; + + CString GetSongFilePath() {return m_sSongDir+m_sSongFile; }; CString GetCacheFilePath(); - CString GetSongFileDir() {return m_sSongDir; }; - CString GetGroupName() {return m_sGroupName; }; - CString GetMusicPath() {return m_sMusicPath; }; - float GetMusicLengthSeconds() {return m_fMusicLength; }; - void GetMusicSampleRange( float &fStartSec, float &fEndSec ) { fStartSec = m_fMusicSampleStartSeconds; fEndSec = m_fMusicSampleStartSeconds + m_fMusicSampleLengthSeconds; }; - CString GetBannerPath() {return m_sBannerPath; }; - CString GetBackgroundPath() {return m_sBackgroundPath; }; - CString GetBackgroundMoviePath(){return m_sBackgroundMoviePath; }; - CString GetCDTitlePath() {return m_sCDTitlePath; }; + bool m_bChangedSinceSave; - bool HasMusic() {return m_sMusicPath != "" && DoesFileExist(GetMusicPath()); }; - bool HasBanner() {return m_sBannerPath != "" && DoesFileExist(GetBannerPath()); }; - bool HasBackground() {return m_sBackgroundPath != "" && DoesFileExist(GetBackgroundPath()); }; - bool HasBackgroundMovie() {return m_sBackgroundMoviePath != ""&& DoesFileExist(GetBackgroundMoviePath()); }; - bool HasCDTitle() {return m_sCDTitlePath != "" && DoesFileExist(GetCDTitlePath()); }; + CString m_sMainTitle; + CString m_sSubTitle; + CString m_sArtist; + CString m_sCredit; - - CString GetMainTitle() {return m_sMainTitle; }; - CString GetSubTitle() {return m_sSubTitle; }; CString GetFullTitle() {return m_sMainTitle + " " + m_sSubTitle; }; - void GetMainAndSubTitlesFromFullTitle( CString sFullTitle, CString &sMainTitleOut, CString &sSubTitleOut ); + static void GetMainAndSubTitlesFromFullTitle( CString sFullTitle, CString &sMainTitleOut, CString &sSubTitleOut ); - CString GetArtist() {return m_sArtist; }; - CString GetCredit() {return m_sCredit; }; - float GetBeatOffsetInSeconds() {return m_fOffsetInSeconds; }; - void SetBeatOffsetInSeconds(float fNewOffset) {m_fOffsetInSeconds = fNewOffset; SetChangedSinceLastSave(); }; + + CString m_sMusicFile; + DWORD m_iMusicBytes; + float m_fOffsetInSeconds; + float m_fMusicLengthSeconds; + float m_fMusicSampleStartSeconds; + float m_fMusicSampleLengthSeconds; + CString m_sBannerFile; + CString m_sBackgroundFile; + CString m_sBackgroundMovieFile; + CString m_sCDTitleFile; + + CString GetMusicPath() {return m_sSongDir+m_sMusicFile; }; + CString GetBannerPath() {return m_sSongDir+m_sBannerFile; }; + CString GetBackgroundPath() {return m_sSongDir+m_sBackgroundFile; }; + CString GetBackgroundMoviePath(){return m_sSongDir+m_sBackgroundMovieFile; }; + CString GetCDTitlePath() {return m_sSongDir+m_sCDTitleFile; }; + + + bool HasMusic() {return m_sMusicFile != "" && DoesFileExist(GetMusicPath()); }; + bool HasBanner() {return m_sBannerFile != "" && DoesFileExist(GetBannerPath()); }; + bool HasBackground() {return m_sBackgroundFile != "" && DoesFileExist(GetBackgroundPath()); }; + bool HasBackgroundMovie() {return m_sBackgroundMovieFile != ""&& DoesFileExist(GetBackgroundMoviePath()); }; + bool HasCDTitle() {return m_sCDTitleFile != "" && DoesFileExist(GetCDTitlePath()); }; + + + CArray m_BPMSegments; // this must be sorted before gameplay + CArray m_FreezeSegments; // this must be sorted before gameplay + + void AddBPMSegment( BPMSegment seg ); + void AddFreezeSegment( FreezeSegment seg ); void GetMinMaxBPM( float &fMinBPM, float &fMaxBPM ) { fMaxBPM = 0; @@ -100,10 +120,21 @@ public: fMinBPM = min( seg.m_fBPM, fMinBPM ); } }; + float GetBPMAtBeat( float fBeat ) + { + for( int i=0; i& arrayAddTo ); + + + + CArray m_arrayNotes; + void GetNotesThatMatch( NotesType nt, CArray& arrayAddTo ); int GetNumTimesPlayed() { int iTotalNumTimesPlayed = 0; @@ -114,43 +145,7 @@ public: return iTotalNumTimesPlayed; } bool IsNew() { return GetNumTimesPlayed()==0; }; - - bool HasChangedSinceLastSave() { return m_bChangedSinceSave; } - Grade GetGradeForDifficultyClass( NotesType nt, DifficultyClass dc ); - - -private: - void SetChangedSinceLastSave() { m_bChangedSinceSave = true; } - - CString m_sSongFilePath; - CString m_sSongDir; - CString m_sGroupName; - - bool m_bChangedSinceSave; - CString m_sMainTitle; - CString m_sSubTitle; - CString m_sArtist; - CString m_sCredit; - float m_fOffsetInSeconds; - - CString m_sMusicPath; - DWORD m_iMusicBytes; - float m_fMusicLength; - float m_fMusicSampleStartSeconds, m_fMusicSampleLengthSeconds; - CString m_sBannerPath; - CString m_sBackgroundPath; - CString m_sBackgroundMoviePath; - CString m_sCDTitlePath; - - void AddBPMSegment( BPMSegment seg ); - void AddFreezeSegment( FreezeSegment seg ); - - CArray m_BPMSegments; // this must be sorted before gameplay - CArray m_FreezeSegments; // this must be sorted before gameplay - -public: - CArray m_arrayNotes; };