diff --git a/stepmania/src/AutoKeysounds.cpp b/stepmania/src/AutoKeysounds.cpp new file mode 100644 index 0000000000..00890a80d9 --- /dev/null +++ b/stepmania/src/AutoKeysounds.cpp @@ -0,0 +1,87 @@ +#include "global.h" +#include "AutoKeysounds.h" +#include "GameState.h" +#include "Song.h" + +void AutoKeysounds::Load( PlayerNumber pn, const NoteData& ndAutoKeysoundsOnly ) +{ + m_ndAutoKeysoundsOnly[pn] = ndAutoKeysoundsOnly; + + // + // Load sounds. + // + Song* pSong = GAMESTATE->m_pCurSong; + CString sSongDir = pSong->GetSongDir(); + m_vKeysounds.clear(); + m_vKeysounds.resize( pSong->m_vsKeysoundFile.size() ); + for( unsigned i=0; im_vsKeysoundFile[i]; + RageSound& sound = m_vKeysounds[i]; + sound.Load( sKeysoundFilePath ); + } +} + +void AutoKeysounds::Update( float fDelta ) +{ + // + // Play keysounds for crossed rows. + // + bool bCrossedABeat = false; + { + float fPositionSeconds = GAMESTATE->m_fMusicSeconds; + float fSongBeat = GAMESTATE->m_pCurSong->GetBeatFromElapsedTime( fPositionSeconds ); + + int iRowNow = BeatToNoteRowNotRounded( fSongBeat ); + iRowNow = max( 0, iRowNow ); + static int iRowLastCrossed = 0; + + float fBeatLast = roundf(NoteRowToBeat(iRowLastCrossed)); + float fBeatNow = roundf(NoteRowToBeat(iRowNow)); + + bCrossedABeat = fBeatLast != fBeatNow; + + FOREACH_EnabledPlayer( pn ) + { + const NoteData &nd = m_ndAutoKeysoundsOnly[pn]; + + for( int t=0; t m_vKeysounds; +}; + +#endif + +/* + * (c) 2003 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/Makefile.am b/stepmania/src/Makefile.am index 8686f08be9..b827e5af50 100644 --- a/stepmania/src/Makefile.am +++ b/stepmania/src/Makefile.am @@ -51,7 +51,7 @@ ScreenTestLights.cpp ScreenTestLights.h ScreenTestSound.cpp ScreenTestSound.h Sc ScreenTitleMenu.cpp ScreenTitleMenu.h ScreenUnlock.cpp ScreenUnlock.h ScreenWithMenuElements.cpp ScreenWithMenuElements.h DataStructures = \ -Attack.cpp Attack.h BannerCache.cpp BannerCache.h CatalogXml.cpp CatalogXml.h \ +Attack.cpp Attack.h AutoKeysounds.cpp AutoKeysounds.h BannerCache.cpp BannerCache.h CatalogXml.cpp CatalogXml.h \ Character.cpp Character.h CharacterHead.cpp CharacterHead.h \ CodeDetector.cpp CodeDetector.h Difficulty.cpp Difficulty.h EnumHelper.cpp EnumHelper.h Course.cpp Course.h \ CourseUtil.cpp CourseUtil.h DateTime.cpp DateTime.h Font.cpp Font.h FontCharAliases.cpp FontCharAliases.h \ diff --git a/stepmania/src/NoteDataUtil.cpp b/stepmania/src/NoteDataUtil.cpp index 14dafb23e0..67da85a845 100644 --- a/stepmania/src/NoteDataUtil.cpp +++ b/stepmania/src/NoteDataUtil.cpp @@ -108,6 +108,7 @@ void NoteDataUtil::LoadFromSMNoteDataString( NoteData &out, CString sSMNoteData // that's what we've been writing to disk. -Chris case 'M': tn = TAP_ORIGINAL_MINE; break; case 'A': tn = TAP_ORIGINAL_ATTACK; break; + case 'K': tn = TAP_ORIGINAL_AUTO_KEYSOUND; break; default: /* Invalid data. We don't want to assert, since there might * simply be invalid data in an .SM, and we don't want to die @@ -225,6 +226,7 @@ void NoteDataUtil::GetSMNoteDataString( const NoteData &in_, CString ¬es_out case TapNote::hold_tail: c = '3'; break; case TapNote::mine: c = 'M'; break; case TapNote::attack: c = 'A'; break; + case TapNote::autoKeysound: c = 'K'; break; default: ASSERT(0); // invalid enum value c = '0'; @@ -1718,6 +1720,30 @@ void NoteDataUtil::ShiftRows( NoteData &nd, float fStartBeat, float fBeatsToShif nd.CopyRange( temp, 0, temp.GetLastRow(), iPasteAtRow ); } +void NoteDataUtil::RemoveAllTapsOfType( NoteData& ndInOut, TapNote::Type typeToRemove ) +{ + for( int t=0; t0, add blank rows. If fBeatsToShift<0, delete rows void ShiftRows( NoteData &nd, float fStartBeat, float fBeatsToShift ); + + void RemoveAllTapsOfType( NoteData& ndInOut, TapNote::Type typeToRemove ); + void RemoveAllTapsExceptForType( NoteData& ndInOut, TapNote::Type typeToKeep ); }; #endif diff --git a/stepmania/src/NoteTypes.cpp b/stepmania/src/NoteTypes.cpp index 800072e6fc..03079e3135 100644 --- a/stepmania/src/NoteTypes.cpp +++ b/stepmania/src/NoteTypes.cpp @@ -1,15 +1,16 @@ #include "global.h" #include "NoteTypes.h" -TapNote TAP_EMPTY ( TapNote::empty, TapNote::original, "", 0, false, 0 ); -TapNote TAP_ORIGINAL_TAP ( TapNote::tap, TapNote::original, "", 0, false, 0 ); -TapNote TAP_ORIGINAL_HOLD_HEAD ( TapNote::hold_head, TapNote::original, "", 0, false, 0 ); -TapNote TAP_ORIGINAL_HOLD_TAIL ( TapNote::hold_tail, TapNote::original, "", 0, false, 0 ); -TapNote TAP_ORIGINAL_HOLD ( TapNote::hold, TapNote::original, "", 0, false, 0 ); -TapNote TAP_ORIGINAL_MINE ( TapNote::mine, TapNote::original, "", 0, false, 0 ); -TapNote TAP_ORIGINAL_ATTACK ( TapNote::attack, TapNote::original, "", 0, false, 0 ); -TapNote TAP_ADDITION_TAP ( TapNote::tap, TapNote::addition, "", 0, false, 0 ); -TapNote TAP_ADDITION_MINE ( TapNote::mine, TapNote::addition, "", 0, false, 0 ); +TapNote TAP_EMPTY ( TapNote::empty, TapNote::original, "", 0, false, 0 ); +TapNote TAP_ORIGINAL_TAP ( TapNote::tap, TapNote::original, "", 0, false, 0 ); +TapNote TAP_ORIGINAL_HOLD_HEAD ( TapNote::hold_head, TapNote::original, "", 0, false, 0 ); +TapNote TAP_ORIGINAL_HOLD_TAIL ( TapNote::hold_tail, TapNote::original, "", 0, false, 0 ); +TapNote TAP_ORIGINAL_HOLD ( TapNote::hold, TapNote::original, "", 0, false, 0 ); +TapNote TAP_ORIGINAL_MINE ( TapNote::mine, TapNote::original, "", 0, false, 0 ); +TapNote TAP_ORIGINAL_ATTACK ( TapNote::attack, TapNote::original, "", 0, false, 0 ); +TapNote TAP_ORIGINAL_AUTO_KEYSOUND ( TapNote::autoKeysound,TapNote::original, "", 0, false, 0 ); +TapNote TAP_ADDITION_TAP ( TapNote::tap, TapNote::addition, "", 0, false, 0 ); +TapNote TAP_ADDITION_MINE ( TapNote::mine, TapNote::addition, "", 0, false, 0 ); float NoteTypeToBeat( NoteType nt ) { diff --git a/stepmania/src/NoteTypes.h b/stepmania/src/NoteTypes.h index c14934f82c..1ed288836b 100644 --- a/stepmania/src/NoteTypes.h +++ b/stepmania/src/NoteTypes.h @@ -11,6 +11,7 @@ struct TapNote hold, /* In 4s mode, holds and TAP_HOLD_HEAD are deleted and TAP_HOLD is added: */ mine, // don't step! attack, + autoKeysound, } type; enum Source { original, // part of the original NoteData @@ -76,6 +77,7 @@ extern TapNote TAP_ORIGINAL_HOLD_TAIL; // '3' extern TapNote TAP_ORIGINAL_HOLD; // '4' extern TapNote TAP_ORIGINAL_MINE; // 'M' extern TapNote TAP_ORIGINAL_ATTACK; // 'A' +extern TapNote TAP_ORIGINAL_AUTO_KEYSOUND; // 'K' extern TapNote TAP_ADDITION_TAP; extern TapNote TAP_ADDITION_MINE; diff --git a/stepmania/src/NotesLoaderBMS.cpp b/stepmania/src/NotesLoaderBMS.cpp index b461ea6deb..1203915879 100644 --- a/stepmania/src/NotesLoaderBMS.cpp +++ b/stepmania/src/NotesLoaderBMS.cpp @@ -46,7 +46,7 @@ bm-*: can't tell difference between bm-single and dance-solo 18/19 marks bm-single7, 28/29 marks bm-double7 bm-double uses 21-26. */ - + enum BmsTrack { BMS_P1_KEY1 = 0, @@ -65,11 +65,21 @@ enum BmsTrack BMS_P2_TURN, BMS_P2_KEY6, BMS_P2_KEY7, - BMS_AUTO_KEYSOUND, + // max 4 simultaneous auto keysounds + BMS_AUTO_KEYSOUND_1, + BMS_AUTO_KEYSOUND_2, + BMS_AUTO_KEYSOUND_3, + BMS_AUTO_KEYSOUND_4, + BMS_AUTO_KEYSOUND_5, + BMS_AUTO_KEYSOUND_6, + BMS_AUTO_KEYSOUND_7, + BMS_AUTO_KEYSOUND_LAST, NUM_BMS_TRACKS, - BMS_TRACK_INVALID, }; +const int NUM_NON_AUTO_KEYSOUND_TRACKS = BMS_AUTO_KEYSOUND_1; +const int NUM_AUTO_KEYSOUND_TRACKS = NUM_BMS_TRACKS - NUM_NON_AUTO_KEYSOUND_TRACKS; + static bool ConvertRawTrackToTapNote( int iRawTrack, BmsTrack &bmsTrackOut, bool &bIsHoldOut ) { if( iRawTrack > 40 ) @@ -84,7 +94,7 @@ static bool ConvertRawTrackToTapNote( int iRawTrack, BmsTrack &bmsTrackOut, bool switch( iRawTrack ) { - case 1: bmsTrackOut = BMS_AUTO_KEYSOUND; break; + case 1: bmsTrackOut = BMS_AUTO_KEYSOUND_1; break; case 11: bmsTrackOut = BMS_P1_KEY1; break; case 12: bmsTrackOut = BMS_P1_KEY2; break; case 13: bmsTrackOut = BMS_P1_KEY3; break; @@ -112,11 +122,11 @@ static StepsType DetermineStepsType( int iPlayer, const NoteData &nd ) { ASSERT( NUM_BMS_TRACKS == nd.GetNumTracks() ); - bool bTrackHasNote[NUM_BMS_TRACKS]; + bool bTrackHasNote[NUM_NON_AUTO_KEYSOUND_TRACKS]; ZERO( bTrackHasNote ); int iLastRow = nd.GetLastRow(); - for( int t=0; t= BMS_AUTO_KEYSOUND_1 ) + { + bmsTrack = (BmsTrack)iLastEmptyTrack; + } + else + { + // no room for this note. Drop it. + continue; + } + } + else if( bIsHold ) + { + tn.type = TapNote::hold_head; } else { - TapNote tn = vTapNotes[j]; - tn.type = bIsHold ? TapNote::hold_head : TapNote::tap; - ndNotes.SetTapNote( bmsTrack, row, tn ); + tn.type = TapNote::tap; } + + ndNotes.SetTapNote( bmsTrack, row, tn ); } } } } } + // we're done reading in all of the BMS values + out.m_StepsType = DetermineStepsType( iPlayer, ndNotes ); - // we're done reading in all of the BMS values if( out.m_StepsType == STEPS_TYPE_INVALID ) { LOG->Warn( "Couldn't determine note type of file '%s'", sPath.c_str() ); return false; } - int iNumNewTracks = GameManager::StepsTypeToNumTracks( out.m_StepsType ); - int iTransformNewToOld[NUM_BMS_TRACKS]; - for( int i = 0; i < NUM_BMS_TRACKS; ++i) - iTransformNewToOld[i] = -1; + // shift all of the autokeysound tracks onto the main tracks + for( int t=BMS_AUTO_KEYSOUND_1; tWarn( "No room to shift." ); + } + } + } + + + int iNumNewTracks = GameManager::StepsTypeToNumTracks( out.m_StepsType ); + vector iTransformNewToOld; + iTransformNewToOld.resize( iNumNewTracks, -1 ); switch( out.m_StepsType ) { @@ -434,7 +484,7 @@ bool BMSLoader::LoadFromBMSFile( const CString &sPath, Steps &out, const mapm_pCurSteps[p]->GetNoteData( originalNoteData ); const Style* pStyle = GAMESTATE->GetCurrentStyle(); - NoteData newNoteData; - pStyle->GetTransformedNoteDataForStyle( p, originalNoteData, newNoteData ); - m_Player[p].Load( - p, - newNoteData, - m_pLifeMeter[p], - m_pCombinedLifeMeter, - m_pPrimaryScoreDisplay[p], - m_pSecondaryScoreDisplay[p], - m_pInventory[p], - m_pPrimaryScoreKeeper[p], - m_pSecondaryScoreKeeper[p] ); + NoteData ndTransformed; + pStyle->GetTransformedNoteDataForStyle( p, originalNoteData, ndTransformed ); + + // load player + { + NoteData nd = ndTransformed; + NoteDataUtil::RemoveAllTapsOfType( nd, TapNote::autoKeysound ); + m_Player[p].Load( + p, + nd, + m_pLifeMeter[p], + m_pCombinedLifeMeter, + m_pPrimaryScoreDisplay[p], + m_pSecondaryScoreDisplay[p], + m_pInventory[p], + m_pPrimaryScoreKeeper[p], + m_pSecondaryScoreKeeper[p] ); + } + + // load auto keysounds + { + NoteData nd = ndTransformed; + NoteDataUtil::RemoveAllTapsExceptForType( nd, TapNote::autoKeysound ); + m_AutoKeysounds.Load( p, nd ); + } + // Put course options into effect. Do this after Player::Load so // that mods aren't double-applied. @@ -1291,6 +1305,8 @@ void ScreenGameplay::Update( float fDeltaTime ) //LOG->Trace( "m_fOffsetInBeats = %f, m_fBeatsPerSecond = %f, m_Music.GetPositionSeconds = %f", m_fOffsetInBeats, m_fBeatsPerSecond, m_Music.GetPositionSeconds() ); m_BeginnerHelper.Update(fDeltaTime); + + m_AutoKeysounds.Update(fDeltaTime); // // update GameState HealthState diff --git a/stepmania/src/ScreenGameplay.h b/stepmania/src/ScreenGameplay.h index d38d0bc0d3..9ab6563a20 100644 --- a/stepmania/src/ScreenGameplay.h +++ b/stepmania/src/ScreenGameplay.h @@ -25,6 +25,7 @@ class Inventory; #include "MeterDisplay.h" #include "ActiveAttackList.h" #include "NetworkSyncManager.h" +#include "AutoKeysounds.h" // messages sent by Combo const ScreenMessage SM_PlayToasty = ScreenMessage(SM_User+104); @@ -157,6 +158,8 @@ protected: Player m_Player[NUM_PLAYERS]; + AutoKeysounds m_AutoKeysounds; + // used in PLAY_MODE_BATTLE Inventory* m_pInventory[NUM_PLAYERS]; diff --git a/stepmania/src/StepMania.dsp b/stepmania/src/StepMania.dsp index 87d7339021..c67802857c 100644 --- a/stepmania/src/StepMania.dsp +++ b/stepmania/src/StepMania.dsp @@ -1,5 +1,5 @@ # Microsoft Developer Studio Project File - Name="StepMania" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# Microsoft Developer Studio Generated Build File, Format Version 60000 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Application" 0x0101 @@ -59,10 +59,10 @@ LINK32=link.exe # SUBTRACT LINK32 /verbose /profile /pdb:none /incremental:no /nodefaultlib # Begin Special Build Tool IntDir=.\../Debug6 -TargetDir=\temp\stepmania\Program +TargetDir=\stepmania\stepmania\Program TargetName=StepMania-debug SOURCE="$(InputPath)" -PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=archutils\Win32\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi # End Special Build Tool @@ -96,10 +96,10 @@ LINK32=link.exe # SUBTRACT LINK32 /verbose /pdb:none /debug # Begin Special Build Tool IntDir=.\../Release6 -TargetDir=\temp\stepmania\Program +TargetDir=\stepmania\stepmania\Program TargetName=StepMania SOURCE="$(InputPath)" -PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=archutils\Win32\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=archutils\Win32\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi # End Special Build Tool @@ -600,6 +600,14 @@ SOURCE=.\Attack.h # End Source File # Begin Source File +SOURCE=.\AutoKeysounds.cpp +# End Source File +# Begin Source File + +SOURCE=.\AutoKeysounds.h +# End Source File +# Begin Source File + SOURCE=.\BannerCache.cpp # End Source File # Begin Source File diff --git a/stepmania/src/StepMania.vcproj b/stepmania/src/StepMania.vcproj index 64996e5c17..af668d4bc0 100644 --- a/stepmania/src/StepMania.vcproj +++ b/stepmania/src/StepMania.vcproj @@ -575,6 +575,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + +