diff --git a/stepmania/TODO.chris b/stepmania/TODO.chris index 352d8b4edd..e34abfc2b6 100644 --- a/stepmania/TODO.chris +++ b/stepmania/TODO.chris @@ -2,6 +2,18 @@ Fix ///////////////////////// +I'd also like to see "custom steps" implemented-- if you hit right twice on the arcade, you get to the custom (memcard) steps. I would like to see it so that any difficulty that isn't one of the standards gets put in this category (perhaps another way would be to put levels labeled "custom" there) + +Only being able to see one difficulty at a time doesnt' work so well for a simulator as it does for the arcade, because things are so varied-- you have to end up doing a lot of searching to find what level you want to play. Some indication of how many feet the other options are would be nice. + +1) The main menu should only be acessable by keyboard presses. Too many times people got in strange menus, quit the game, etc, without intending to. + +2) pressing both starts at the same time should not reset the game. The most common way to start doubles or versus is for someone to go up to the machine and press both starts at the same time. Same for selecting difficulty. This caused a LOT of confusion. + +a WIBNI (Wouldn't it be nice if...) is to add a "training" mode. basically, it would take a song, turn it into only having steps on 1 and 3. Similar to DDR USA. It was a real bear finidng songs for the newbies. (This is what prompted me to start lint-- there are many songs with only maniac steps out there!) + +play intro.mp3 if available. + rename Notes to Pattern You'll notice that if you add up the Perfects and Greats, they are far less than the max combo. Where did they go? Apparently Jumps count for 2 steps during normal game play, but ONLY for max combo. diff --git a/stepmania/src/NoteDisplay.cpp b/stepmania/src/NoteDisplay.cpp index 7b3e5ed5f0..0a9b7b7c7b 100644 --- a/stepmania/src/NoteDisplay.cpp +++ b/stepmania/src/NoteDisplay.cpp @@ -248,8 +248,13 @@ void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float const float fXBottomRight = fXBottom + fFrameWidth/2; const float fTopDistFromTailTop = fYTop - fYTailTop; const float fBottomDistFromTailTop = fYBottom - fYTailTop; - const float fTexCoordTop = SCALE( fTopDistFromTailTop, 0, fFrameHeight, 0.5f, 1.0f ); - const float fTexCoordBottom = SCALE( fBottomDistFromTailTop, 0, fFrameHeight, 0.5f, 1.0f ); + float fTexCoordTop = SCALE( fTopDistFromTailTop, 0, fFrameHeight, 0.5f, 1.0f ); + float fTexCoordBottom = SCALE( fBottomDistFromTailTop, 0, fFrameHeight, 0.5f, 1.0f ); + if( fTexCoordTop > 1 && fTexCoordBottom > 1 ) + { + fTexCoordTop -= (int)fTexCoordTop; + fTexCoordBottom -= (int)fTexCoordTop; + } ASSERT( fBottomDistFromTailTop-0.001 <= fFrameHeight ); const float fTexCoordLeft = bActive ? 0.25f : 0.00f; const float fTexCoordRight = bActive ? 0.50f : 0.25f; @@ -294,8 +299,13 @@ void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float const float fXBottomRight = fXBottom + fFrameWidth/2; const float fTopDistFromTailTop = fYTailTop - fYTop; const float fBottomDistFromTailTop = fYTailTop - fYBottom; - const float fTexCoordTop = SCALE( fTopDistFromTailTop, 0, fBodyHeight, 1, 0 ); - const float fTexCoordBottom = SCALE( fBottomDistFromTailTop, 0, fBodyHeight, 1, 0 ); + float fTexCoordTop = SCALE( fTopDistFromTailTop, 0, fBodyHeight, 1, 0 ); + float fTexCoordBottom = SCALE( fBottomDistFromTailTop, 0, fBodyHeight, 1, 0 ); + if( fTexCoordTop > 1 && fTexCoordBottom > 1 ) + { + fTexCoordTop -= (int)fTexCoordTop; + fTexCoordBottom -= (int)fTexCoordTop; + } const float fTexCoordLeft = bActive ? 0.75f : 0.50f; const float fTexCoordRight = bActive ? 1.00f : 0.75f; const float fAlphaTop = ArrowGetAlpha( m_PlayerNumber, fYTop, fPercentFadeToFail ); diff --git a/stepmania/src/Notes.cpp b/stepmania/src/Notes.cpp index f64ecc89c1..d88c118dc4 100644 --- a/stepmania/src/Notes.cpp +++ b/stepmania/src/Notes.cpp @@ -40,6 +40,7 @@ Notes::Notes() * it'd trip obscure asserts all over the place, so I'll wait * until after b6 to do this. -glenn */ m_NotesType = NOTES_TYPE_DANCE_SINGLE; + m_bAutoGen = false; m_Difficulty = CLASS_INVALID; m_iMeter = 0; ZeroMemory(m_fRadarValues, sizeof(m_fRadarValues)); diff --git a/stepmania/src/Notes.h b/stepmania/src/Notes.h index 4c0ec5ac5a..bb2edec174 100644 --- a/stepmania/src/Notes.h +++ b/stepmania/src/Notes.h @@ -39,6 +39,7 @@ public: public: NotesType m_NotesType; CString m_sDescription; // This text is displayed next to thte number of feet when a song is selected + bool m_bAutoGen; // Was created by autogen? Difficulty m_Difficulty; // difficulty classification int m_iMeter; // difficulty rating from 1-10 float m_fRadarValues[NUM_RADAR_VALUES]; // between 0.0-1.2 starting from 12-o'clock rotating clockwise diff --git a/stepmania/src/NotesWriterDWI.cpp b/stepmania/src/NotesWriterDWI.cpp index 5662fb5b2e..0c5cdba10b 100644 --- a/stepmania/src/NotesWriterDWI.cpp +++ b/stepmania/src/NotesWriterDWI.cpp @@ -54,19 +54,20 @@ char NotesWriterDWI::NotesToDWIChar( bool bCol1, bool bCol2, bool bCol3, bool bC CString NotesWriterDWI::NotesToDWIString( TapNote cNoteCol1, TapNote cNoteCol2, TapNote cNoteCol3, TapNote cNoteCol4, TapNote cNoteCol5, TapNote cNoteCol6 ) { char cShow = NotesToDWIChar( - cNoteCol1 != TAP_EMPTY && cNoteCol1!=TAP_HOLD_HEAD, - cNoteCol2 != TAP_EMPTY && cNoteCol2!=TAP_HOLD_HEAD, - cNoteCol3 != TAP_EMPTY && cNoteCol3!=TAP_HOLD_HEAD, - cNoteCol4 != TAP_EMPTY && cNoteCol4!=TAP_HOLD_HEAD, - cNoteCol5 != TAP_EMPTY && cNoteCol5!=TAP_HOLD_HEAD, - cNoteCol6 != TAP_EMPTY && cNoteCol6!=TAP_HOLD_HEAD ); - char cHold = NotesToDWIChar( cNoteCol1==TAP_HOLD_HEAD, - cNoteCol2==TAP_HOLD_HEAD, - cNoteCol3==TAP_HOLD_HEAD, - cNoteCol4==TAP_HOLD_HEAD, - cNoteCol5==TAP_HOLD_HEAD, - cNoteCol6==TAP_HOLD_HEAD ); - + cNoteCol1!=TAP_EMPTY, + cNoteCol2!=TAP_EMPTY, + cNoteCol3!=TAP_EMPTY, + cNoteCol4!=TAP_EMPTY, + cNoteCol5!=TAP_EMPTY, + cNoteCol6!=TAP_EMPTY ); + char cHold = NotesToDWIChar( + cNoteCol1==TAP_HOLD_HEAD, + cNoteCol2==TAP_HOLD_HEAD, + cNoteCol3==TAP_HOLD_HEAD, + cNoteCol4==TAP_HOLD_HEAD, + cNoteCol5==TAP_HOLD_HEAD, + cNoteCol6==TAP_HOLD_HEAD ); + if( cHold != '0' ) return ssprintf( "%c!%c", cShow, cHold ); else diff --git a/stepmania/src/RageDisplay.cpp b/stepmania/src/RageDisplay.cpp index e571e644ff..1219fd3811 100644 --- a/stepmania/src/RageDisplay.cpp +++ b/stepmania/src/RageDisplay.cpp @@ -273,6 +273,14 @@ void RageDisplay::DrawQuads( const RageVertex v[], int iNumVerts ) ASSERT( (iNumVerts%4) == 0 ); g_vertMode = GL_QUADS; AddVerts( v, iNumVerts ); + + glInterleavedArrays( GL_T2F_C4UB_V3F, sizeof(RageVertex), g_vertQueue ); + glDrawArrays( g_vertMode, 0, g_iNumVerts ); + + g_iVertsRenderedSinceLastCheck += g_iNumVerts; + g_iNumVerts = 0; + + g_iDrawsSinceLastCheck++; } void RageDisplay::DrawFan( const RageVertex v[], int iNumVerts ) { diff --git a/stepmania/src/RageTypes.h b/stepmania/src/RageTypes.h index 6fc2714be8..dee398f0cf 100644 --- a/stepmania/src/RageTypes.h +++ b/stepmania/src/RageTypes.h @@ -143,13 +143,13 @@ public: RageColor& operator *= ( float f ) { r*=f; g*=f; b*=f; a*=f; } RageColor& operator /= ( float f ) { r/=f; g/=f; b/=f; a/=f; } - // binarg operators + // binary operators RageColor operator + ( const RageColor& other ) const { return RageColor( r+other.r, g+other.g, b+other.b, a+other.a ); } RageColor operator - ( const RageColor& other ) const { return RageColor( r-other.r, g-other.g, b-other.b, a-other.a ); } RageColor operator * ( float f ) const { return RageColor( r*f, g*f, b*f, a*f ); } RageColor operator / ( float f ) const { return RageColor( r/f, g/f, b/f, a/f ); } - friend RageVector4 operator * ( float f, const RageVector4& other ) { return other*f; } + friend RageVector4 operator * ( float f, const RageVector4& other ) { return other*f; } // What is this for? Did I add this? -Chris /* unneeded; this is a POD type */ // bool operator == ( const RageColor& other ) const { return r==other.r && g==other.g && b==other.b && a==other.a; } @@ -159,12 +159,14 @@ public: }; /* Convert floating-point 0..1 value to integer 0..255 value. */ -inline unsigned char FTOC(float a) { return (unsigned char)(a * 255.f); } +inline unsigned char FTOC(float a) { if(a<0) a=0; if(a>1) a=1; return (unsigned char)(a*255.f); } // need clamping to handle values <0.0 and > 1.0 /* Color type used only in vertex lists. OpenGL expects colors in * r, g, b, a order, independent of endianness, so storing them this * way avoids endianness problems. Don't try to manipulate this; only * manip RageColors. */ +/* Perhaps the math in RageColor could be moved to RaveVColor. We don't need the + * precision of a float for our calculations anyway. -Chris */ class RageVColor { unsigned char r, g, b, a; diff --git a/stepmania/src/RandomSample.cpp b/stepmania/src/RandomSample.cpp index bbad90dbaa..37058bd003 100644 --- a/stepmania/src/RandomSample.cpp +++ b/stepmania/src/RandomSample.cpp @@ -67,7 +67,7 @@ void RandomSample::PlayRandom() // play one of the samples if( m_pSamples.empty() ) { - LOG->Trace( "WARNING: Tried to play a RandomSample that has 0 sounds loaded." ); +// LOG->Trace( "WARNING: Tried to play a RandomSample that has 0 sounds loaded." ); return; } diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp index 238eff0f5c..ffc8791fdc 100644 --- a/stepmania/src/ScreenEdit.cpp +++ b/stepmania/src/ScreenEdit.cpp @@ -752,14 +752,12 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ // copy edit into current Notes Notes* pNotes = GAMESTATE->m_pCurNotes[PLAYER_1]; ASSERT( pNotes ); - - // strip out the autogen marker if any. The autogen marker would have caused these Notes not to be saved to disk. - pNotes->m_sDescription.Replace( " (autogen)", "" ); + pNotes->m_bAutoGen = false; // set not autogen so these Notes will be saved to disk. pNotes->SetNoteData( &m_NoteFieldEdit ); GAMESTATE->m_pCurSong->Save(); - SCREENMAN->SystemMessage( "Saved as SM and DWI." ); + SCREENMAN->SystemMessage( "Saved as SM and DWI." ); SOUND->PlayOnceStreamed( THEME->GetPathTo("Sounds","edit save") ); } break; diff --git a/stepmania/src/Song.cpp b/stepmania/src/Song.cpp index 5d8cc3eca9..bdd6fd232d 100644 --- a/stepmania/src/Song.cpp +++ b/stepmania/src/Song.cpp @@ -33,9 +33,9 @@ #include "NotesLoaderKSF.h" #include "NotesWriterDWI.h" +#include "SDL.h" +#include "SDL_image.h" -// XXX needed for D3DXGetImageInfo. Remove this ASAP! -#include "D3DX8.h" const int FILE_CACHE_VERSION = 102; // increment this when Song or Notes changes to invalidate cache @@ -482,20 +482,24 @@ void Song::TidyUpData() if( HasCDTitle() && stricmp(m_sCDTitleFile, arrayImages[i])==0 ) continue; // skip - D3DXIMAGE_INFO ddii; - if( !FAILED( D3DXGetImageInfoFromFile( m_sSongDir + arrayImages[i], &ddii ) ) ) + SDL_Surface *img = IMG_Load( m_sSongDir + arrayImages[i] ); + if( img ) { - if( !HasBackground() && ddii.Width >= 320 && ddii.Height >= 240 ) + int width = img->w; + int height = img->h; + SDL_FreeSurface( img ); + + if( !HasBackground() && width >= 320 && height >= 240 ) { m_sBackgroundFile = arrayImages[i]; continue; } - if( !HasBanner() && 100 < ddii.Width && ddii.Width < 320 && 50 < ddii.Height && ddii.Height < 240 ) + if( !HasBanner() && 100 apNotes; + GetNotesThatMatch( nt, apNotes ); + if( apNotes.size() == 1 ) + { + if( 0 == apNotes[0]->m_sDescription.CompareNoCase("smaniac") ) + { + apNotes[0]->m_sDescription = "Challenge"; + apNotes[0]->m_Difficulty = DIFFICULTY_HARD; + } + } + } +} + +void Song::ReCalulateRadarValuesAndLastBeat() +{ // // calculate radar values and first/last beat // - for( i=0; i apNotes; - GetNotesThatMatch( nt, apNotes ); - if( apNotes.size() == 1 ) - if( 0 == apNotes[0]->m_sDescription.CompareNoCase("smaniac") ) - { - apNotes[0]->m_sDescription = "Challenge"; - apNotes[0]->m_Difficulty = DIFFICULTY_HARD; - } - } } void Song::GetNotesThatMatch( NotesType nt, CArray& arrayAddTo ) const @@ -634,6 +646,8 @@ void Song::Save() MoveFile( sOldPath, sNewPath ); } + ReCalulateRadarValuesAndLastBeat(); + SaveToSMFile( GetSongFilePath(), false ); SaveToDWIFile(); } @@ -720,7 +734,7 @@ void Song::SaveToSMFile( CString sPath, bool bSavingCache ) for( i=0; im_sDescription.Find("(autogen)") == -1 ) // If notes aren't autogen + if( bSavingCache || !pNotes->m_bAutoGen ) // If notes aren't autogen m_apNotes[i]->WriteSMNotesTag( fp ); } @@ -741,21 +755,6 @@ void Song::SaveToDWIFile() void Song::AddAutoGenNotes() { - -// This hack is no longer needed. I've sped up autogen. - -// // This is way too slow. Only autogen dance->pump and pump->dance -// CArray aMissingNotesTypes; -// if( !SongHasNotesType(NOTES_TYPE_DANCE_SINGLE) ) aMissingNotesTypes.push_back( NOTES_TYPE_DANCE_SINGLE ); -// if( !SongHasNotesType(NOTES_TYPE_DANCE_DOUBLE) ) aMissingNotesTypes.push_back( NOTES_TYPE_DANCE_DOUBLE ); -// if( !SongHasNotesType(NOTES_TYPE_DANCE_SOLO) ) aMissingNotesTypes.push_back( NOTES_TYPE_DANCE_SOLO ); -// if( !SongHasNotesType(NOTES_TYPE_PUMP_SINGLE) ) aMissingNotesTypes.push_back( NOTES_TYPE_PUMP_SINGLE ); -// if( !SongHasNotesType(NOTES_TYPE_PUMP_DOUBLE) ) aMissingNotesTypes.push_back( NOTES_TYPE_PUMP_DOUBLE ); -// -// for( unsigned i=0; iNotesTypeToNumTracks(pOriginalNotes->m_NotesType) ) - continue; // no match, skip - - Notes* pNewNotes = new Notes; - pNewNotes->m_Difficulty = pOriginalNotes->m_Difficulty; - pNewNotes->m_iMeter = pOriginalNotes->m_iMeter; - pNewNotes->m_sDescription = pOriginalNotes->m_sDescription + " (autogen)"; - pNewNotes->m_NotesType = ntMissing; - pNewNotes->m_sSMNoteData = pOriginalNotes->m_sSMNoteData; - this->m_apNotes.push_back( pNewNotes ); - goto next_notes_type; + NotesType ntOriginal = pOriginalNotes->m_NotesType; + int iNumOriginalNotesTracks = GAMEMAN->NotesTypeToNumTracks(ntOriginal); + + if( pOriginalNotes->m_bAutoGen && iNumTracksOfMissing == iNumOriginalNotesTracks ) + { + AutoGen( ntMissing, ntOriginal ); + goto next_notes_type; // done searching + } } @@ -797,35 +793,40 @@ next_notes_type: int iTrackDifference = abs(iNumTracks-iNumTracksOfMissing); CArray apNotes; this->GetNotesThatMatch( nt, apNotes ); - if( iTrackDifference < iBestTrackDifference && !apNotes.empty() && apNotes[0]->m_sDescription.Find("autogen")==-1 ) + if( iTrackDifference < iBestTrackDifference && !apNotes.empty() && !apNotes[0]->m_bAutoGen ) { ntBestMatch = nt; iBestTrackDifference = iTrackDifference; } } - if( ntBestMatch == -1 ) - continue; + if( ntBestMatch != -1 ) + AutoGen( ntMissing, ntBestMatch ); + } +} - for( j=0; jNotesTypeToNumTracks(ntTo); + + for( unsigned int j=0; jm_NotesType == ntFrom ) { - Notes* pOriginalNotes = m_apNotes[j]; - if( pOriginalNotes->m_NotesType != ntBestMatch ) - continue; // skip - Notes* pNewNotes = new Notes; pNewNotes->m_Difficulty = pOriginalNotes->m_Difficulty; pNewNotes->m_iMeter = pOriginalNotes->m_iMeter; - pNewNotes->m_sDescription = pOriginalNotes->m_sDescription + " (autogen)"; - pNewNotes->m_NotesType = ntMissing; + pNewNotes->m_sDescription = pOriginalNotes->m_sDescription; + pNewNotes->m_bAutoGen = true; + pNewNotes->m_NotesType = ntTo; NoteData originalNoteData; NoteData newNoteData; pOriginalNotes->GetNoteData( &originalNoteData ); - newNoteData.LoadTransformedSlidingWindow( &originalNoteData, iNumTracksOfMissing ); + newNoteData.LoadTransformedSlidingWindow( &originalNoteData, iNumTracksOfTo ); pNewNotes->SetNoteData( &newNoteData ); this->m_apNotes.push_back( pNewNotes ); - goto next_notes_type; } } } diff --git a/stepmania/src/SongSelector.cpp b/stepmania/src/SongSelector.cpp index 3fdde37b34..d8def2bdcc 100644 --- a/stepmania/src/SongSelector.cpp +++ b/stepmania/src/SongSelector.cpp @@ -282,6 +282,13 @@ void SongSelector::OnNotesChange() if( GetSelectedNotes() == NULL ) m_textNotes.SetText( "(NEW)" ); else - m_textNotes.SetText( GetSelectedNotes()->m_sDescription!="" ? GetSelectedNotes()->m_sDescription : "[no name]" ); + { + CString sDescription = GetSelectedNotes()->m_sDescription; + if( sDescription == "" ) + sDescription = "[no name]"; + if( GetSelectedNotes()->m_bAutoGen ) + sDescription += " (autogen)"; + m_textNotes.SetText( sDescription ); + } } diff --git a/stepmania/src/TransitionFade.cpp b/stepmania/src/TransitionFade.cpp index 2b3c7d5ba1..b3747475b0 100644 --- a/stepmania/src/TransitionFade.cpp +++ b/stepmania/src/TransitionFade.cpp @@ -31,10 +31,12 @@ TransitionFade::~TransitionFade() void TransitionFade::DrawPrimitives() { - const float fPercentageOpaque = 1 - GetPercentageOpen(); + float fPercentageOpaque = 1 - GetPercentageOpen(); if( fPercentageOpaque == 0 ) return; // draw nothing + CLAMP( fPercentageOpaque, 0, 1 ); + RageColor colorTemp = GetDiffuse(); colorTemp.a = fPercentageOpaque; m_rect.SetDiffuse( colorTemp ); diff --git a/stepmania/src/song.h b/stepmania/src/song.h index 59d40e7a59..879813e897 100644 --- a/stepmania/src/song.h +++ b/stepmania/src/song.h @@ -62,6 +62,7 @@ public: bool LoadFromSongDir( CString sDir ); void TidyUpData(); // call after loading to clean up invalid data + void ReCalulateRadarValuesAndLastBeat(); // called by TidyUpData, and after saving void SaveToSMFile( CString sPath, bool bSavingCache ); void Save(); // saves SM and DWI @@ -72,6 +73,7 @@ public: CString GetCacheFilePath() const; void AddAutoGenNotes(); + void AutoGen( NotesType ntTo, NotesType ntFrom ); // create Notes of type ntTo from Notes of type ntFrom /* Directory this song data came from: */ CString m_sSongDir;