play auto keysounds

This commit is contained in:
Chris Danford
2004-10-24 10:45:30 +00:00
parent 1b3c786213
commit eff1dc9695
12 changed files with 292 additions and 44 deletions
+87
View File
@@ -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; i<m_vKeysounds.size(); i++ )
{
CString sKeysoundFilePath = sSongDir + pSong->m_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<nd.GetNumTracks(); t++ )
{
FOREACH_NONEMPTY_ROW_IN_TRACK_RANGE( nd, t, r, iRowLastCrossed+1, iRowNow )
{
const TapNote &tn = nd.GetTapNote( t, r );
ASSERT( tn.type == TapNote::autoKeysound );
if( tn.bKeysound )
m_vKeysounds[tn.iKeysoundIndex].Play();
}
}
}
iRowLastCrossed = iRowNow;
}
}
/*
* (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.
*/
+46
View File
@@ -0,0 +1,46 @@
/* AutoKeysounds - handle playback of auto keysounds notes. */
#ifndef AutoKeysounds_H
#define AutoKeysounds_H
#include "NoteData.h"
#include "PlayerNumber.h"
#include "RageSound.h"
class AutoKeysounds
{
public:
void Load( PlayerNumber pn, const NoteData& ndAutoKeysoundsOnly );
void Update( float fDelta );
protected:
NoteData m_ndAutoKeysoundsOnly[NUM_PLAYERS];
vector<RageSound> 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.
*/
+1 -1
View File
@@ -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 \
+26
View File
@@ -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 &notes_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; t<ndInOut.GetNumTracks(); t++ )
{
FOREACH_NONEMPTY_ROW_IN_TRACK( ndInOut, t, row )
{
if( ndInOut.GetTapNote(t, row).type == typeToRemove )
ndInOut.SetTapNote( t, row, TAP_EMPTY );
}
}
}
void NoteDataUtil::RemoveAllTapsExceptForType( NoteData& ndInOut, TapNote::Type typeToKeep )
{
for( int t=0; t<ndInOut.GetNumTracks(); t++ )
{
FOREACH_NONEMPTY_ROW_IN_TRACK( ndInOut, t, row )
{
if( ndInOut.GetTapNote(t, row).type != typeToKeep )
ndInOut.SetTapNote( t, row, TAP_EMPTY );
}
}
}
/*
* (c) 2001-2004 Chris Danford, Glenn Maynard
+3
View File
@@ -95,6 +95,9 @@ namespace NoteDataUtil
// If fBeatsToShift>0, 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
+10 -9
View File
@@ -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 )
{
+2
View File
@@ -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;
+67 -17
View File
@@ -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<nd.GetNumTracks(); t++ )
for( int t=0; t<NUM_NON_AUTO_KEYSOUND_TRACKS; t++ )
{
for( int r=0; r<=iLastRow; r++ )
{
@@ -129,7 +139,7 @@ static StepsType DetermineStepsType( int iPlayer, const NoteData &nd )
}
int iNumNonEmptyTracks = 0;
for( int t=0; t<nd.GetNumTracks(); t++ )
for( int t=0; t<NUM_NON_AUTO_KEYSOUND_TRACKS; t++ )
if( bTrackHasNote[t] )
iNumNonEmptyTracks++;
@@ -306,35 +316,75 @@ bool BMSLoader::LoadFromBMSFile( const CString &sPath, Steps &out, const map<CSt
bool bIsHold;
if( ConvertRawTrackToTapNote(iRawTrackNum, bmsTrack, bIsHold) )
{
if( bmsTrack == BMS_AUTO_KEYSOUND )
TapNote tn = vTapNotes[j];
if( bmsTrack == BMS_AUTO_KEYSOUND_1 )
{
tn.type = TapNote::autoKeysound;
// shift the auto keysound as far right as possible
int iLastEmptyTrack = -1;
if( ndNotes.GetTapLastEmptyTrack(row,iLastEmptyTrack) &&
iLastEmptyTrack >= 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; t<BMS_AUTO_KEYSOUND_1+NUM_AUTO_KEYSOUND_TRACKS; t++ )
{
FOREACH_NONEMPTY_ROW_IN_TRACK( ndNotes, t, row )
{
TapNote tn = ndNotes.GetTapNote( t, row );
int iEmptyTrack;
if( ndNotes.GetTapFirstEmptyTrack(row, iEmptyTrack) )
{
ndNotes.SetTapNote( iEmptyTrack, row, tn );
ndNotes.SetTapNote( t, row, TAP_EMPTY );
}
else
{
LOG->Warn( "No room to shift." );
}
}
}
int iNumNewTracks = GameManager::StepsTypeToNumTracks( out.m_StepsType );
vector<int> iTransformNewToOld;
iTransformNewToOld.resize( iNumNewTracks, -1 );
switch( out.m_StepsType )
{
@@ -434,7 +484,7 @@ bool BMSLoader::LoadFromBMSFile( const CString &sPath, Steps &out, const map<CSt
NoteData noteData2;
noteData2.SetNumTracks( iNumNewTracks );
noteData2.LoadTransformed( ndNotes, iNumNewTracks, iTransformNewToOld );
noteData2.LoadTransformed( ndNotes, iNumNewTracks, iTransformNewToOld.begin() );
out.SetNoteData( noteData2 );
+28 -12
View File
@@ -814,18 +814,32 @@ void ScreenGameplay::SetupSong( PlayerNumber p, int iSongIndex )
GAMESTATE->m_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
+3
View File
@@ -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];
+13 -5
View File
@@ -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
+6
View File
@@ -575,6 +575,12 @@ cl /Zl /nologo /c verstub.cpp /Fo&quot;$(IntDir)&quot;\
<File
RelativePath="Attack.h">
</File>
<File
RelativePath="AutoKeysounds.cpp">
</File>
<File
RelativePath="AutoKeysounds.h">
</File>
<File
RelativePath="BannerCache.cpp">
</File>