[opengl] merge (part 1?)
This commit is contained in:
@@ -0,0 +1,23 @@
|
|||||||
|
[patterns]
|
||||||
|
**.cpp = native
|
||||||
|
**.h = native
|
||||||
|
**.mm = native
|
||||||
|
**.txt = native
|
||||||
|
**.lua = native
|
||||||
|
**.sln = CRLF
|
||||||
|
**.ini = native
|
||||||
|
**.redir = native
|
||||||
|
**.sm = native
|
||||||
|
**.ssc = native
|
||||||
|
**.vcproj = CRLF
|
||||||
|
**.xsl = native
|
||||||
|
**.xml = native
|
||||||
|
**.jpg = BIN
|
||||||
|
**.png = BIN
|
||||||
|
**.jpeg = BIN
|
||||||
|
**.ogg = BIN
|
||||||
|
**.mp3 = BIN
|
||||||
|
**.wav = BIN
|
||||||
|
**.sh = LF
|
||||||
|
Makefile = LF
|
||||||
|
Makefile.am = LF
|
||||||
@@ -4,6 +4,7 @@ syntax: glob
|
|||||||
*~
|
*~
|
||||||
*.o
|
*.o
|
||||||
tests/*.err
|
tests/*.err
|
||||||
|
ffmpeg-*
|
||||||
*.ncb
|
*.ncb
|
||||||
*.suo
|
*.suo
|
||||||
*.obj
|
*.obj
|
||||||
@@ -20,11 +21,26 @@ ___*
|
|||||||
.cvsignore
|
.cvsignore
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
config.log
|
||||||
|
config.status
|
||||||
*.pbxuser
|
*.pbxuser
|
||||||
*.user
|
*.user
|
||||||
*.mode1v3
|
*.mode1v3
|
||||||
*.exe
|
*.exe
|
||||||
*.vdi
|
*.vdi
|
||||||
|
Makefile
|
||||||
|
stepmania
|
||||||
|
Makefile.in
|
||||||
|
_build/*
|
||||||
|
aclocal.m4
|
||||||
|
autoconf/*
|
||||||
|
autom4te.cache/*
|
||||||
|
configure
|
||||||
|
src/Makefile.in
|
||||||
|
src/Makefile
|
||||||
|
src/config.h
|
||||||
|
src/config.h.in
|
||||||
|
src/stamp-h1
|
||||||
Docs/doxygen
|
Docs/doxygen
|
||||||
PBProject/build
|
PBProject/build
|
||||||
Xcode/build
|
Xcode/build
|
||||||
@@ -38,6 +54,9 @@ src/libtommath/build-*
|
|||||||
src/libtommath/Release-*
|
src/libtommath/Release-*
|
||||||
src/*.old
|
src/*.old
|
||||||
src/.deps
|
src/.deps
|
||||||
|
src/*.a
|
||||||
|
src/*.so
|
||||||
|
GtkModule.so
|
||||||
ver.cpp
|
ver.cpp
|
||||||
lib*_link.a
|
lib*_link.a
|
||||||
Data/UserPrefs
|
Data/UserPrefs
|
||||||
@@ -60,3 +79,6 @@ Utils/temp*
|
|||||||
syntax: regexp
|
syntax: regexp
|
||||||
.*\#.*\#$
|
.*\#.*\#$
|
||||||
glob:Cache/Banners/AdditionalSongs_Airspace Preview_Derailed_Derailed bn.png
|
glob:Cache/Banners/AdditionalSongs_Airspace Preview_Derailed_Derailed bn.png
|
||||||
|
|
||||||
|
syntax: regexp
|
||||||
|
Songs/.+/
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ _____________________________________________________________________________
|
|||||||
sm-ssc v1.2.4 | 20110???
|
sm-ssc v1.2.4 | 20110???
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
20110316
|
||||||
|
--------
|
||||||
|
* [NotesLoaderSMA] Allow for preliminary support of loading SMA files. This
|
||||||
|
will become better once Split Timing is in place. [Wolfman2000]
|
||||||
|
|
||||||
20110313
|
20110313
|
||||||
--------
|
--------
|
||||||
* [NotesWriterSM] Allow for either the #DESCRIPTION or #CREDIT tags to be used
|
* [NotesWriterSM] Allow for either the #DESCRIPTION or #CREDIT tags to be used
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
[Common]
|
[Common]
|
||||||
WindowTitle=StepMania
|
WindowTitle=StepMania
|
||||||
StepMania=StepMania
|
StepMania=StepMania
|
||||||
|
|
||||||
@@ -2319,3 +2319,4 @@ UnknownPreference=Unknown preference "%s"
|
|||||||
ChoicesSizeMismatch=Choices and Values have different sizes (%d, %d)
|
ChoicesSizeMismatch=Choices and Values have different sizes (%d, %d)
|
||||||
NoDefaultInValues=Preference "%s" has no values matching default
|
NoDefaultInValues=Preference "%s" has no values matching default
|
||||||
TypeMismatch=Type mismatch between default (%s) and value %d (%s)
|
TypeMismatch=Type mismatch between default (%s) and value %d (%s)
|
||||||
|
>>>>>>> other
|
||||||
|
|||||||
@@ -1023,7 +1023,7 @@ TapJudgmentsUnderField=false
|
|||||||
HoldJudgmentsUnderField=false
|
HoldJudgmentsUnderField=false
|
||||||
ComboUnderField=ComboUnderField()
|
ComboUnderField=ComboUnderField()
|
||||||
PenalizeTapScoreNone=false
|
PenalizeTapScoreNone=false
|
||||||
JudgeHoldNotesOnSameRowTogether=(GAMESTATE:GetCurrentGame():GetName() == "pump")
|
JudgeHoldNotesOnSameRowTogether=false
|
||||||
HoldCheckpoints=(GAMESTATE:GetCurrentGame():GetName() == "pump")
|
HoldCheckpoints=(GAMESTATE:GetCurrentGame():GetName() == "pump")
|
||||||
CheckpointsUseTickcounts=(GAMESTATE:GetCurrentGame():GetName() == "pump")
|
CheckpointsUseTickcounts=(GAMESTATE:GetCurrentGame():GetName() == "pump")
|
||||||
; deprecated?
|
; deprecated?
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
1215D7A208C6559A00B87D8B /* ScreenGameplayNormal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1215D7A008C6559A00B87D8B /* ScreenGameplayNormal.cpp */; };
|
1215D7A208C6559A00B87D8B /* ScreenGameplayNormal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1215D7A008C6559A00B87D8B /* ScreenGameplayNormal.cpp */; };
|
||||||
2B30D6821315EA7E00044B68 /* MouseDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B30D6801315EA7E00044B68 /* MouseDevice.cpp */; };
|
2B30D6821315EA7E00044B68 /* MouseDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B30D6801315EA7E00044B68 /* MouseDevice.cpp */; };
|
||||||
2B30D6831315EA7E00044B68 /* MouseDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B30D6811315EA7E00044B68 /* MouseDevice.h */; };
|
2B30D6831315EA7E00044B68 /* MouseDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B30D6811315EA7E00044B68 /* MouseDevice.h */; };
|
||||||
|
2B76698B132FF71500586512 /* NotesLoaderSMA.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B766989132FF71500586512 /* NotesLoaderSMA.h */; };
|
||||||
|
2B76698C132FF71500586512 /* NotesLoaderSMA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B76698A132FF71500586512 /* NotesLoaderSMA.cpp */; };
|
||||||
2BA7925E1304F20D002BD8E1 /* NotesLoaderSSC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BA7925A1304F20D002BD8E1 /* NotesLoaderSSC.cpp */; };
|
2BA7925E1304F20D002BD8E1 /* NotesLoaderSSC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BA7925A1304F20D002BD8E1 /* NotesLoaderSSC.cpp */; };
|
||||||
2BA7925F1304F20D002BD8E1 /* NotesLoaderSSC.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BA7925B1304F20D002BD8E1 /* NotesLoaderSSC.h */; };
|
2BA7925F1304F20D002BD8E1 /* NotesLoaderSSC.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BA7925B1304F20D002BD8E1 /* NotesLoaderSSC.h */; };
|
||||||
2BA792601304F20D002BD8E1 /* NotesWriterSSC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BA7925C1304F20D002BD8E1 /* NotesWriterSSC.cpp */; };
|
2BA792601304F20D002BD8E1 /* NotesWriterSSC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BA7925C1304F20D002BD8E1 /* NotesWriterSSC.cpp */; };
|
||||||
@@ -1774,6 +1776,8 @@
|
|||||||
29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
|
29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
|
||||||
2B30D6801315EA7E00044B68 /* MouseDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MouseDevice.cpp; sourceTree = "<group>"; };
|
2B30D6801315EA7E00044B68 /* MouseDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MouseDevice.cpp; sourceTree = "<group>"; };
|
||||||
2B30D6811315EA7E00044B68 /* MouseDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MouseDevice.h; sourceTree = "<group>"; };
|
2B30D6811315EA7E00044B68 /* MouseDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MouseDevice.h; sourceTree = "<group>"; };
|
||||||
|
2B766989132FF71500586512 /* NotesLoaderSMA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NotesLoaderSMA.h; path = ../src/NotesLoaderSMA.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
2B76698A132FF71500586512 /* NotesLoaderSMA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NotesLoaderSMA.cpp; path = ../src/NotesLoaderSMA.cpp; sourceTree = SOURCE_ROOT; };
|
||||||
2BA7925A1304F20D002BD8E1 /* NotesLoaderSSC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NotesLoaderSSC.cpp; path = ../src/NotesLoaderSSC.cpp; sourceTree = SOURCE_ROOT; };
|
2BA7925A1304F20D002BD8E1 /* NotesLoaderSSC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NotesLoaderSSC.cpp; path = ../src/NotesLoaderSSC.cpp; sourceTree = SOURCE_ROOT; };
|
||||||
2BA7925B1304F20D002BD8E1 /* NotesLoaderSSC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NotesLoaderSSC.h; path = ../src/NotesLoaderSSC.h; sourceTree = SOURCE_ROOT; };
|
2BA7925B1304F20D002BD8E1 /* NotesLoaderSSC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NotesLoaderSSC.h; path = ../src/NotesLoaderSSC.h; sourceTree = SOURCE_ROOT; };
|
||||||
2BA7925C1304F20D002BD8E1 /* NotesWriterSSC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NotesWriterSSC.cpp; path = ../src/NotesWriterSSC.cpp; sourceTree = SOURCE_ROOT; };
|
2BA7925C1304F20D002BD8E1 /* NotesWriterSSC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NotesWriterSSC.cpp; path = ../src/NotesWriterSSC.cpp; sourceTree = SOURCE_ROOT; };
|
||||||
@@ -3153,6 +3157,7 @@
|
|||||||
AA6EFDC804770AF1005F316C /* DataStructures */,
|
AA6EFDC804770AF1005F316C /* DataStructures */,
|
||||||
AA6EFE5704770C7E005F316C /* FileTypes */,
|
AA6EFE5704770C7E005F316C /* FileTypes */,
|
||||||
AA6E00FE047711FF005F316C /* GlobalSingletons */,
|
AA6E00FE047711FF005F316C /* GlobalSingletons */,
|
||||||
|
2B766980132FF62B00586512 /* NoteParsing */,
|
||||||
29B97315FDCFA39411CA2CEA /* Other Source */,
|
29B97315FDCFA39411CA2CEA /* Other Source */,
|
||||||
AA8B6C7804AFD82B00D02EE9 /* pcre */,
|
AA8B6C7804AFD82B00D02EE9 /* pcre */,
|
||||||
AA6EFDBB04770A83005F316C /* Rage */,
|
AA6EFDBB04770A83005F316C /* Rage */,
|
||||||
@@ -3200,6 +3205,37 @@
|
|||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
2B766980132FF62B00586512 /* NoteParsing */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
AA6EFDED04770C79005F316C /* NotesLoader.cpp */,
|
||||||
|
AA6EFDEE04770C79005F316C /* NotesLoader.h */,
|
||||||
|
AA6EFDEF04770C79005F316C /* NotesLoaderBMS.cpp */,
|
||||||
|
AA6EFDF004770C79005F316C /* NotesLoaderBMS.h */,
|
||||||
|
AA6EFDF104770C79005F316C /* NotesLoaderDWI.cpp */,
|
||||||
|
AA6EFDF204770C79005F316C /* NotesLoaderDWI.h */,
|
||||||
|
AA6EFDF304770C79005F316C /* NotesLoaderKSF.cpp */,
|
||||||
|
AA6EFDF404770C79005F316C /* NotesLoaderKSF.h */,
|
||||||
|
3688B8510BD42DAA004186AD /* NotesLoaderMidi.cpp */,
|
||||||
|
3688B8520BD42DAA004186AD /* NotesLoaderMidi.h */,
|
||||||
|
EE2153A710A75BEE0074B01B /* NotesLoaderPMS.cpp */,
|
||||||
|
EE2153A810A75BEE0074B01B /* NotesLoaderPMS.h */,
|
||||||
|
AA6EFDF504770C79005F316C /* NotesLoaderSM.cpp */,
|
||||||
|
AA6EFDF604770C79005F316C /* NotesLoaderSM.h */,
|
||||||
|
2B76698A132FF71500586512 /* NotesLoaderSMA.cpp */,
|
||||||
|
2B766989132FF71500586512 /* NotesLoaderSMA.h */,
|
||||||
|
2BA7925A1304F20D002BD8E1 /* NotesLoaderSSC.cpp */,
|
||||||
|
2BA7925B1304F20D002BD8E1 /* NotesLoaderSSC.h */,
|
||||||
|
AA6EFDF704770C79005F316C /* NotesWriterDWI.cpp */,
|
||||||
|
AA6EFDF804770C79005F316C /* NotesWriterDWI.h */,
|
||||||
|
AA6EFDF904770C79005F316C /* NotesWriterSM.cpp */,
|
||||||
|
AA6EFDFA04770C79005F316C /* NotesWriterSM.h */,
|
||||||
|
2BA7925C1304F20D002BD8E1 /* NotesWriterSSC.cpp */,
|
||||||
|
2BA7925D1304F20D002BD8E1 /* NotesWriterSSC.h */,
|
||||||
|
);
|
||||||
|
name = NoteParsing;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
AA60E0BB067992D7008ADC41 /* Threads */ = {
|
AA60E0BB067992D7008ADC41 /* Threads */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -3774,28 +3810,6 @@
|
|||||||
AA4F38C104E2D0B700D02EE9 /* NoteDataUtil.h */,
|
AA4F38C104E2D0B700D02EE9 /* NoteDataUtil.h */,
|
||||||
AA6EFDE704770C79005F316C /* NoteDataWithScoring.cpp */,
|
AA6EFDE704770C79005F316C /* NoteDataWithScoring.cpp */,
|
||||||
AA6EFDE804770C79005F316C /* NoteDataWithScoring.h */,
|
AA6EFDE804770C79005F316C /* NoteDataWithScoring.h */,
|
||||||
AA6EFDED04770C79005F316C /* NotesLoader.cpp */,
|
|
||||||
AA6EFDEE04770C79005F316C /* NotesLoader.h */,
|
|
||||||
AA6EFDEF04770C79005F316C /* NotesLoaderBMS.cpp */,
|
|
||||||
AA6EFDF004770C79005F316C /* NotesLoaderBMS.h */,
|
|
||||||
AA6EFDF104770C79005F316C /* NotesLoaderDWI.cpp */,
|
|
||||||
AA6EFDF204770C79005F316C /* NotesLoaderDWI.h */,
|
|
||||||
AA6EFDF304770C79005F316C /* NotesLoaderKSF.cpp */,
|
|
||||||
AA6EFDF404770C79005F316C /* NotesLoaderKSF.h */,
|
|
||||||
3688B8510BD42DAA004186AD /* NotesLoaderMidi.cpp */,
|
|
||||||
3688B8520BD42DAA004186AD /* NotesLoaderMidi.h */,
|
|
||||||
EE2153A710A75BEE0074B01B /* NotesLoaderPMS.cpp */,
|
|
||||||
EE2153A810A75BEE0074B01B /* NotesLoaderPMS.h */,
|
|
||||||
AA6EFDF504770C79005F316C /* NotesLoaderSM.cpp */,
|
|
||||||
AA6EFDF604770C79005F316C /* NotesLoaderSM.h */,
|
|
||||||
2BA7925A1304F20D002BD8E1 /* NotesLoaderSSC.cpp */,
|
|
||||||
2BA7925B1304F20D002BD8E1 /* NotesLoaderSSC.h */,
|
|
||||||
AA6EFDF704770C79005F316C /* NotesWriterDWI.cpp */,
|
|
||||||
AA6EFDF804770C79005F316C /* NotesWriterDWI.h */,
|
|
||||||
AA6EFDF904770C79005F316C /* NotesWriterSM.cpp */,
|
|
||||||
AA6EFDFA04770C79005F316C /* NotesWriterSM.h */,
|
|
||||||
2BA7925C1304F20D002BD8E1 /* NotesWriterSSC.cpp */,
|
|
||||||
2BA7925D1304F20D002BD8E1 /* NotesWriterSSC.h */,
|
|
||||||
AA6EFDFB04770C79005F316C /* NoteTypes.cpp */,
|
AA6EFDFB04770C79005F316C /* NoteTypes.cpp */,
|
||||||
AA6EFDFC04770C79005F316C /* NoteTypes.h */,
|
AA6EFDFC04770C79005F316C /* NoteTypes.h */,
|
||||||
AA80C75707F20D6600C99272 /* OptionRowHandler.cpp */,
|
AA80C75707F20D6600C99272 /* OptionRowHandler.cpp */,
|
||||||
@@ -4944,6 +4958,7 @@
|
|||||||
2B30D6831315EA7E00044B68 /* MouseDevice.h in Headers */,
|
2B30D6831315EA7E00044B68 /* MouseDevice.h in Headers */,
|
||||||
EE879B61132DEE720078FDDC /* RageDisplay_Legacy_Helpers.h in Headers */,
|
EE879B61132DEE720078FDDC /* RageDisplay_Legacy_Helpers.h in Headers */,
|
||||||
EE879B63132DEE720078FDDC /* RageDisplay_Legacy.h in Headers */,
|
EE879B63132DEE720078FDDC /* RageDisplay_Legacy.h in Headers */,
|
||||||
|
2B76698B132FF71500586512 /* NotesLoaderSMA.h in Headers */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -6187,6 +6202,7 @@
|
|||||||
EE879B60132DEE720078FDDC /* RageDisplay_Legacy_Helpers.cpp in Sources */,
|
EE879B60132DEE720078FDDC /* RageDisplay_Legacy_Helpers.cpp in Sources */,
|
||||||
EE879B62132DEE720078FDDC /* RageDisplay_Legacy.cpp in Sources */,
|
EE879B62132DEE720078FDDC /* RageDisplay_Legacy.cpp in Sources */,
|
||||||
EE879BC3132E06C50078FDDC /* glew.c in Sources */,
|
EE879BC3132E06C50078FDDC /* glew.c in Sources */,
|
||||||
|
2B76698C132FF71500586512 /* NotesLoaderSMA.cpp in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
+2
-1
@@ -37,7 +37,7 @@ void Foreground::LoadFromSong( const Song *pSong )
|
|||||||
|
|
||||||
LoadedBGA bga;
|
LoadedBGA bga;
|
||||||
bga.m_bga = ActorUtil::MakeActor( pSong->GetSongDir() + sBGName, this );
|
bga.m_bga = ActorUtil::MakeActor( pSong->GetSongDir() + sBGName, this );
|
||||||
bga.m_bga->PlayCommand( "On" );
|
bga.m_bga->PlayCommand( "Init" );
|
||||||
bga.m_fStartBeat = change.m_fStartBeat;
|
bga.m_fStartBeat = change.m_fStartBeat;
|
||||||
bga.m_bFinished = false;
|
bga.m_bFinished = false;
|
||||||
|
|
||||||
@@ -80,6 +80,7 @@ void Foreground::Update( float fDeltaTime )
|
|||||||
if( !bga.m_bga->GetVisible() )
|
if( !bga.m_bga->GetVisible() )
|
||||||
{
|
{
|
||||||
bga.m_bga->SetVisible( true );
|
bga.m_bga->SetVisible( true );
|
||||||
|
bga.m_bga->PlayCommand( "On" );
|
||||||
|
|
||||||
const float fStartSecond = m_pSong->m_Timing.GetElapsedTimeFromBeat( bga.m_fStartBeat );
|
const float fStartSecond = m_pSong->m_Timing.GetElapsedTimeFromBeat( bga.m_fStartBeat );
|
||||||
lDeltaTime = GAMESTATE->m_fMusicSeconds - fStartSecond;
|
lDeltaTime = GAMESTATE->m_fMusicSeconds - fStartSecond;
|
||||||
|
|||||||
+2
-2
@@ -415,8 +415,8 @@ void GameCommand::LoadOne( const Command& cmd )
|
|||||||
if( cmd.m_vsArgs.size() == 3 )
|
if( cmd.m_vsArgs.size() == 3 )
|
||||||
{
|
{
|
||||||
m_bFadeMusic = true;
|
m_bFadeMusic = true;
|
||||||
m_fMusicFadeOutVolume = (float)atof( cmd.m_vsArgs[1] );
|
m_fMusicFadeOutVolume = atof( cmd.m_vsArgs[1] );
|
||||||
m_fMusicFadeOutSeconds = (float)atof( cmd.m_vsArgs[2] );
|
m_fMusicFadeOutSeconds = atof( cmd.m_vsArgs[2] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "GameState.h"
|
#include "GameState.h"
|
||||||
#include "TimingData.h"
|
#include "TimingData.h"
|
||||||
#include "NotesLoaderSSC.h"
|
#include "NotesLoaderSSC.h"
|
||||||
|
#include "NotesLoaderSM.h"
|
||||||
#include "PrefsManager.h"
|
#include "PrefsManager.h"
|
||||||
#include "RageDisplay.h"
|
#include "RageDisplay.h"
|
||||||
#include "AnnouncerManager.h"
|
#include "AnnouncerManager.h"
|
||||||
@@ -150,6 +151,15 @@ static void StartMusic( MusicToPlay &ToPlay )
|
|||||||
if( pStepsCabinetLights )
|
if( pStepsCabinetLights )
|
||||||
pStepsCabinetLights->GetNoteData( ToPlay.m_LightsData );
|
pStepsCabinetLights->GetNoteData( ToPlay.m_LightsData );
|
||||||
}
|
}
|
||||||
|
else if( SMLoader::LoadFromSMFile(ToPlay.m_sTimingFile, song) )
|
||||||
|
{
|
||||||
|
ToPlay.HasTiming = true;
|
||||||
|
ToPlay.m_TimingData = song.m_Timing;
|
||||||
|
// get cabinet lights if any
|
||||||
|
Steps *pStepsCabinetLights = SongUtil::GetOneSteps( &song, StepsType_lights_cabinet );
|
||||||
|
if( pStepsCabinetLights )
|
||||||
|
pStepsCabinetLights->GetNoteData( ToPlay.m_LightsData );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ToPlay.HasTiming )
|
if( ToPlay.HasTiming )
|
||||||
@@ -704,6 +714,7 @@ void GameSoundManager::PlayMusic( PlayMusicParams params, PlayMusicParams Fallba
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* If no timing data was provided, look for it in the same place as the music file. */
|
/* If no timing data was provided, look for it in the same place as the music file. */
|
||||||
|
// todo: allow loading .ssc files as well -aj
|
||||||
ToPlay.m_sTimingFile = SetExtension( params.sFile, "sm" );
|
ToPlay.m_sTimingFile = SetExtension( params.sFile, "sm" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ InputFilter::InputFilter()
|
|||||||
|
|
||||||
m_MouseCoords.fX = 0;
|
m_MouseCoords.fX = 0;
|
||||||
m_MouseCoords.fY = 0;
|
m_MouseCoords.fY = 0;
|
||||||
|
m_MouseCoords.fZ = 0;
|
||||||
|
|
||||||
// Register with Lua.
|
// Register with Lua.
|
||||||
{
|
{
|
||||||
@@ -415,6 +416,10 @@ void InputFilter::UpdateCursorLocation(float _fX, float _fY)
|
|||||||
m_MouseCoords.fY = _fY;
|
m_MouseCoords.fY = _fY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InputFilter::UpdateMouseWheel(float _fZ)
|
||||||
|
{
|
||||||
|
m_MouseCoords.fZ = _fZ;
|
||||||
|
}
|
||||||
|
|
||||||
// lua start
|
// lua start
|
||||||
#include "LuaBinding.h"
|
#include "LuaBinding.h"
|
||||||
@@ -439,11 +444,17 @@ public:
|
|||||||
lua_pushnumber( L, fY );
|
lua_pushnumber( L, fY );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
static int GetMouseWheel( T* p, lua_State *L ){
|
||||||
|
float fZ = p->GetMouseWheel();
|
||||||
|
lua_pushnumber( L, fZ );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
LunaInputFilter()
|
LunaInputFilter()
|
||||||
{
|
{
|
||||||
ADD_METHOD( GetMouseX );
|
ADD_METHOD( GetMouseX );
|
||||||
ADD_METHOD( GetMouseY );
|
ADD_METHOD( GetMouseY );
|
||||||
|
ADD_METHOD( GetMouseWheel );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ struct MouseCoordinates
|
|||||||
{
|
{
|
||||||
float fX;
|
float fX;
|
||||||
float fY;
|
float fY;
|
||||||
|
float fZ;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RageMutex;
|
class RageMutex;
|
||||||
@@ -70,8 +71,10 @@ public:
|
|||||||
|
|
||||||
// cursor
|
// cursor
|
||||||
void UpdateCursorLocation(float _fX, float _fY);
|
void UpdateCursorLocation(float _fX, float _fY);
|
||||||
|
void UpdateMouseWheel(float _fZ);
|
||||||
float GetCursorX(){ return m_MouseCoords.fX; }
|
float GetCursorX(){ return m_MouseCoords.fX; }
|
||||||
float GetCursorY(){ return m_MouseCoords.fY; }
|
float GetCursorY(){ return m_MouseCoords.fY; }
|
||||||
|
float GetMouseWheel(){ return m_MouseCoords.fZ; }
|
||||||
|
|
||||||
// Lua
|
// Lua
|
||||||
void PushSelf( lua_State *L );
|
void PushSelf( lua_State *L );
|
||||||
|
|||||||
+2
-1
@@ -147,7 +147,8 @@ NoteTypes.cpp NoteTypes.h NotesLoader.cpp NotesLoader.h \
|
|||||||
NotesLoaderBMS.cpp NotesLoaderBMS.h NotesLoaderDWI.cpp NotesLoaderDWI.h \
|
NotesLoaderBMS.cpp NotesLoaderBMS.h NotesLoaderDWI.cpp NotesLoaderDWI.h \
|
||||||
NotesLoaderKSF.cpp NotesLoaderKSF.h NotesLoaderMidi.cpp NotesLoaderMidi.h \
|
NotesLoaderKSF.cpp NotesLoaderKSF.h NotesLoaderMidi.cpp NotesLoaderMidi.h \
|
||||||
NotesLoaderPMS.cpp NotesLoaderPMS.h NotesLoaderSM.cpp NotesLoaderSM.h \
|
NotesLoaderPMS.cpp NotesLoaderPMS.h NotesLoaderSM.cpp NotesLoaderSM.h \
|
||||||
NotesLoaderSSC.cpp NotesLoaderSSC.h NotesWriterDWI.cpp NotesWriterDWI.h \
|
NotesLoaderSSC.cpp NotesLoaderSSC.h NotesLoaderSMA.cpp NotesLoaderSMA.h \
|
||||||
|
NotesWriterDWI.cpp NotesWriterDWI.h \
|
||||||
NotesWriterSM.cpp NotesWriterSM.h NotesWriterSSC.cpp NotesWriterSSC.h \
|
NotesWriterSM.cpp NotesWriterSM.h NotesWriterSSC.cpp NotesWriterSSC.h \
|
||||||
OptionRowHandler.cpp OptionRowHandler.h OptionsList.cpp OptionsList.h \
|
OptionRowHandler.cpp OptionRowHandler.h OptionsList.cpp OptionsList.h \
|
||||||
PlayerAI.cpp PlayerAI.h PlayerNumber.cpp PlayerNumber.h PlayerOptions.cpp PlayerOptions.h \
|
PlayerAI.cpp PlayerAI.h PlayerNumber.cpp PlayerNumber.h PlayerOptions.cpp PlayerOptions.h \
|
||||||
|
|||||||
+1
-3
@@ -1,9 +1,7 @@
|
|||||||
/** @brief MsdFile - Read .SSC, .SM, .DWI, and .MSD files. */
|
|
||||||
|
|
||||||
#ifndef MSDFILE_H
|
#ifndef MSDFILE_H
|
||||||
#define MSDFILE_H
|
#define MSDFILE_H
|
||||||
|
|
||||||
/** @brief The class that reads the various .SSC, .SM, .DWI, and .MSD files. */
|
/** @brief The class that reads the various .SSC, .SM, .SMA, .DWI, and .MSD files. */
|
||||||
class MsdFile
|
class MsdFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
+53
-2
@@ -561,6 +561,40 @@ void NoteDataUtil::LoadTransformedSlidingWindow( const NoteData &in, NoteData &o
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlaceAutoKeysound( NoteData &out, int row, TapNote akTap )
|
||||||
|
{
|
||||||
|
int iEmptyTrack = -1;
|
||||||
|
int iEmptyRow = row;
|
||||||
|
int iNewNumTracks = out.GetNumTracks();
|
||||||
|
bool bFoundEmptyTrack = false;
|
||||||
|
int iRowsToLook[3] = {0, -1, 1};
|
||||||
|
|
||||||
|
for( int j = 0; j < 3; j ++ )
|
||||||
|
{
|
||||||
|
int r = iRowsToLook[j] + row;
|
||||||
|
if( r < 0 )
|
||||||
|
continue;
|
||||||
|
for( int i = 0; i < iNewNumTracks; ++i )
|
||||||
|
{
|
||||||
|
if ( out.GetTapNote(i, r) == TAP_EMPTY && !out.IsHoldNoteAtRow(i, r) )
|
||||||
|
{
|
||||||
|
iEmptyTrack = i;
|
||||||
|
iEmptyRow = r;
|
||||||
|
bFoundEmptyTrack = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( bFoundEmptyTrack )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( iEmptyTrack != -1 )
|
||||||
|
{
|
||||||
|
akTap.type = TapNote::autoKeysound;
|
||||||
|
out.SetTapNote( iEmptyTrack, iEmptyRow, akTap );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NoteDataUtil::LoadOverlapped( const NoteData &in, NoteData &out, int iNewNumTracks )
|
void NoteDataUtil::LoadOverlapped( const NoteData &in, NoteData &out, int iNewNumTracks )
|
||||||
{
|
{
|
||||||
out.SetNumTracks( iNewNumTracks );
|
out.SetNumTracks( iNewNumTracks );
|
||||||
@@ -587,7 +621,7 @@ void NoteDataUtil::LoadOverlapped( const NoteData &in, NoteData &out, int iNewNu
|
|||||||
for( int iTrackFrom = 0; iTrackFrom < in.GetNumTracks(); ++iTrackFrom )
|
for( int iTrackFrom = 0; iTrackFrom < in.GetNumTracks(); ++iTrackFrom )
|
||||||
{
|
{
|
||||||
const TapNote &tnFrom = in.GetTapNote( iTrackFrom, row );
|
const TapNote &tnFrom = in.GetTapNote( iTrackFrom, row );
|
||||||
if( tnFrom.type == TapNote::empty )
|
if( tnFrom.type == TapNote::empty || tnFrom.type == TapNote::autoKeysound )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// If this is a hold note, find the end.
|
// If this is a hold note, find the end.
|
||||||
@@ -609,8 +643,16 @@ void NoteDataUtil::LoadOverlapped( const NoteData &in, NoteData &out, int iNewNu
|
|||||||
|
|
||||||
// If it's still in use, then we just don't have an available track.
|
// If it's still in use, then we just don't have an available track.
|
||||||
if( iEndIndex - LastSourceRow[iTrackTo] < ShiftThreshold )
|
if( iEndIndex - LastSourceRow[iTrackTo] < ShiftThreshold )
|
||||||
|
{
|
||||||
|
// If it has a keysound, put it in autokeysound track.
|
||||||
|
if( tnFrom.iKeysoundIndex >= 0 )
|
||||||
|
{
|
||||||
|
TapNote akTap = tnFrom;
|
||||||
|
PlaceAutoKeysound( out, row, akTap );
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LastSourceTrack[iTrackTo] = iTrackFrom;
|
LastSourceTrack[iTrackTo] = iTrackFrom;
|
||||||
LastSourceRow[iTrackTo] = iEndIndex;
|
LastSourceRow[iTrackTo] = iEndIndex;
|
||||||
@@ -621,6 +663,16 @@ void NoteDataUtil::LoadOverlapped( const NoteData &in, NoteData &out, int iNewNu
|
|||||||
out.SetTapNote( iTrackTo, iEndIndex, tnTail );
|
out.SetTapNote( iTrackTo, iEndIndex, tnTail );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find empty track for autokeysounds in 2 next rows, so you can hear most autokeysounds
|
||||||
|
for( int iTrackFrom = 0; iTrackFrom < in.GetNumTracks(); ++iTrackFrom )
|
||||||
|
{
|
||||||
|
const TapNote &tnFrom = in.GetTapNote( iTrackFrom, row );
|
||||||
|
if( tnFrom.type != TapNote::autoKeysound )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
PlaceAutoKeysound( out, row, tnFrom );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1389,7 +1441,6 @@ void NoteDataUtil::Little( NoteData &inout, int iStartIndex, int iEndIndex )
|
|||||||
{
|
{
|
||||||
if( i % ROWS_PER_BEAT == 0 )
|
if( i % ROWS_PER_BEAT == 0 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
inout.SetTapNote( t, i, TAP_EMPTY );
|
inout.SetTapNote( t, i, TAP_EMPTY );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "NotesLoader.h"
|
#include "NotesLoader.h"
|
||||||
#include "NotesLoaderSM.h"
|
#include "NotesLoaderSM.h"
|
||||||
|
#include "NotesLoaderSMA.h"
|
||||||
#include "NotesLoaderSSC.h"
|
#include "NotesLoaderSSC.h"
|
||||||
#include "NotesLoaderDWI.h"
|
#include "NotesLoaderDWI.h"
|
||||||
#include "NotesLoaderBMS.h"
|
#include "NotesLoaderBMS.h"
|
||||||
@@ -42,6 +43,11 @@ bool NotesLoader::LoadFromDir( const RString &sPath, Song &out, set<RString> &Bl
|
|||||||
SMLoader::GetApplicableFiles( sPath, list );
|
SMLoader::GetApplicableFiles( sPath, list );
|
||||||
if (!list.empty() )
|
if (!list.empty() )
|
||||||
return SMLoader::LoadFromDir( sPath, out );
|
return SMLoader::LoadFromDir( sPath, out );
|
||||||
|
#if defined(_MSC_VER) || defined(MACOSX)
|
||||||
|
SMALoader::GetApplicableFiles( sPath, list );
|
||||||
|
if (!list.empty() )
|
||||||
|
return SMALoader::LoadFromDir( sPath, out );
|
||||||
|
#endif
|
||||||
DWILoader::GetApplicableFiles( sPath, list );
|
DWILoader::GetApplicableFiles( sPath, list );
|
||||||
if( !list.empty() )
|
if( !list.empty() )
|
||||||
return DWILoader::LoadFromDir( sPath, out, BlacklistedImages );
|
return DWILoader::LoadFromDir( sPath, out, BlacklistedImages );
|
||||||
|
|||||||
+97
-104
@@ -182,6 +182,7 @@ static StepsType DetermineStepsType( int iPlayer, const NoteData &nd, const RStr
|
|||||||
// are more common.
|
// are more common.
|
||||||
//return StepsType_dance_solo;
|
//return StepsType_dance_solo;
|
||||||
return StepsType_beat_single5;
|
return StepsType_beat_single5;
|
||||||
|
case 7:
|
||||||
case 8: return StepsType_beat_single7;
|
case 8: return StepsType_beat_single7;
|
||||||
case 9: return StepsType_popn_nine;
|
case 9: return StepsType_popn_nine;
|
||||||
default: return StepsType_Invalid;
|
default: return StepsType_Invalid;
|
||||||
@@ -404,8 +405,37 @@ static void SetTimeSigAdjustments( const MeasureToTimeSig_t &sigs, Song &out, Me
|
|||||||
|
|
||||||
static void ReadTimeSigs( const NameToData_t &mapNameToData, MeasureToTimeSig_t &out )
|
static void ReadTimeSigs( const NameToData_t &mapNameToData, MeasureToTimeSig_t &out )
|
||||||
{
|
{
|
||||||
|
// some convertors change some measure's time signature before any notes are there
|
||||||
|
// it is required because sometimes the BGA starts before the music and the measure size
|
||||||
|
// is the difference between the start of first bar and the BGA.
|
||||||
|
// something like #00002:1.55. that made all subsequent notes 192th.
|
||||||
|
// here, find the lowest measure for notes, and make this function skip the time signatures before it.
|
||||||
|
int iStartMeasureNo = 999;
|
||||||
NameToData_t::const_iterator it;
|
NameToData_t::const_iterator it;
|
||||||
for( it = mapNameToData.lower_bound("#00000"); it != mapNameToData.end(); ++it )
|
for( it = mapNameToData.lower_bound("#00000"); it != mapNameToData.end(); ++it )
|
||||||
|
{
|
||||||
|
const RString &sName = it->first;
|
||||||
|
if( sName.size() != 6 || sName[0] != '#' || !IsAnInt( sName.substr(1,5) ) )
|
||||||
|
continue;
|
||||||
|
// this is step or offset data. Looks like "#00705"
|
||||||
|
int iMeasureNo = atoi( sName.substr(1, 3).c_str() );
|
||||||
|
int iBMSTrackNo = atoi( sName.substr(4, 2).c_str() );
|
||||||
|
RString nData = it->second;
|
||||||
|
int totalPairs = nData.size() / 2;
|
||||||
|
if( iBMSTrackNo != BMS_TRACK_TIME_SIG && iBMSTrackNo != 7 )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < totalPairs; ++i )
|
||||||
|
{
|
||||||
|
RString sPair = nData.substr( i*2, 2 );
|
||||||
|
if (sPair == "00")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( iMeasureNo < iStartMeasureNo ) iStartMeasureNo = iMeasureNo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for( it = mapNameToData.lower_bound("#00000"); it != mapNameToData.end(); ++it )
|
||||||
{
|
{
|
||||||
const RString &sName = it->first;
|
const RString &sName = it->first;
|
||||||
if( sName.size() != 6 || sName[0] != '#' || !IsAnInt(sName.substr(1, 5)) )
|
if( sName.size() != 6 || sName[0] != '#' || !IsAnInt(sName.substr(1, 5)) )
|
||||||
@@ -414,6 +444,8 @@ static void ReadTimeSigs( const NameToData_t &mapNameToData, MeasureToTimeSig_t
|
|||||||
// this is step or offset data. Looks like "#00705"
|
// this is step or offset data. Looks like "#00705"
|
||||||
const RString &sData = it->second;
|
const RString &sData = it->second;
|
||||||
int iMeasureNo = atoi( sName.substr(1, 3).c_str() );
|
int iMeasureNo = atoi( sName.substr(1, 3).c_str() );
|
||||||
|
if( iMeasureNo < iStartMeasureNo )
|
||||||
|
continue;
|
||||||
int iBMSTrackNo = atoi( sName.substr(4, 2).c_str() );
|
int iBMSTrackNo = atoi( sName.substr(4, 2).c_str() );
|
||||||
if( iBMSTrackNo == BMS_TRACK_TIME_SIG )
|
if( iBMSTrackNo == BMS_TRACK_TIME_SIG )
|
||||||
out[iMeasureNo] = StringToFloat( sData );
|
out[iMeasureNo] = StringToFloat( sData );
|
||||||
@@ -494,8 +526,8 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
|
|||||||
int row = iRowNo + lrintf( fPercentThroughMeasure * fBeatsPerMeasure * ROWS_PER_BEAT );
|
int row = iRowNo + lrintf( fPercentThroughMeasure * fBeatsPerMeasure * ROWS_PER_BEAT );
|
||||||
|
|
||||||
// some BMS files seem to have funky alignment, causing us to write gigantic cache files.
|
// some BMS files seem to have funky alignment, causing us to write gigantic cache files.
|
||||||
// Try to correct for this by quantizing.
|
// Try to correct for this by quantizing. // not always
|
||||||
row = Quantize( row, ROWS_PER_MEASURE/64 );
|
// row = Quantize( row, ROWS_PER_MEASURE/64 );
|
||||||
|
|
||||||
BmsTrack bmsTrack;
|
BmsTrack bmsTrack;
|
||||||
bool bIsHold;
|
bool bIsHold;
|
||||||
@@ -520,33 +552,10 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* This handles the hold notes in the RDM TYPE 1 style,
|
|
||||||
* like how uBMplay handles it. Different BMS simulators
|
|
||||||
* support hold notes differently. see
|
|
||||||
* http://nvyu.net/rdm/ex.php for more info. */
|
|
||||||
else if( iHoldStarts[bmsTrack] != -1 )
|
|
||||||
{
|
|
||||||
// This is ending a hold.
|
|
||||||
const int iBegin = iHoldStarts[bmsTrack];
|
|
||||||
const int iEnd = row;
|
|
||||||
if( iBegin < iEnd )
|
|
||||||
{
|
|
||||||
TapNote ¬eHead = TAP_ORIGINAL_HOLD_HEAD;
|
|
||||||
noteHead.iKeysoundIndex = iHoldHeads[bmsTrack].iKeysoundIndex;
|
|
||||||
ndNotes.AddHoldNote( bmsTrack, iBegin, iEnd, noteHead );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ndNotes.SetTapNote( bmsTrack, iBegin, iHoldHeads[bmsTrack] );
|
|
||||||
}
|
|
||||||
iHoldStarts[bmsTrack] = -1;
|
|
||||||
}
|
|
||||||
else if( bIsHold )
|
else if( bIsHold )
|
||||||
{
|
{
|
||||||
// Start of a hold.
|
tn.type = TapNote::hold_head;
|
||||||
iHoldStarts[bmsTrack] = row;
|
tn.subType = TapNote::hold_head_hold;
|
||||||
iHoldHeads[bmsTrack] = tn;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Don't bother inserting empty taps.
|
// Don't bother inserting empty taps.
|
||||||
@@ -556,6 +565,45 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handles hold notes like uBMPlay.
|
||||||
|
* Different BMS simulators support hold notes differently.
|
||||||
|
* See http://nvyu.net/rdm/ex.php for more info.
|
||||||
|
*/
|
||||||
|
for( int t=BMS_P1_KEY1; t<=BMS_P2_KEY7; t++ )
|
||||||
|
{
|
||||||
|
int iHoldHeadRow = -1;
|
||||||
|
TapNote tnHoldHead;
|
||||||
|
FOREACH_NONEMPTY_ROW_IN_TRACK( ndNotes, t, row )
|
||||||
|
{
|
||||||
|
TapNote tn = ndNotes.GetTapNote( t, row );
|
||||||
|
if ( tn.type == TapNote::hold_head || tn.type == TapNote::tap )
|
||||||
|
{
|
||||||
|
if ( iHoldHeadRow != -1 )
|
||||||
|
{
|
||||||
|
// Delete head and tail, and add the hold note there.
|
||||||
|
ndNotes.SetTapNote( t, row, TAP_EMPTY );
|
||||||
|
ndNotes.SetTapNote( t, iHoldHeadRow, TAP_EMPTY );
|
||||||
|
if ( iHoldHeadRow < row )
|
||||||
|
{
|
||||||
|
ndNotes.AddHoldNote( t, iHoldHeadRow, row, tnHoldHead );
|
||||||
|
}
|
||||||
|
iHoldHeadRow = -1;
|
||||||
|
}
|
||||||
|
else if ( tn.type == TapNote::hold_head )
|
||||||
|
{
|
||||||
|
// Head of the hold note, store it to find the tail.
|
||||||
|
iHoldHeadRow = row;
|
||||||
|
tnHoldHead = tn;
|
||||||
|
|
||||||
|
// Replace with a tap note.
|
||||||
|
tn.type = TapNote::tap;
|
||||||
|
tn.subType = TapNote::SubType_Invalid;
|
||||||
|
ndNotes.SetTapNote( t, row, tn );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out.m_StepsType = DetermineStepsType( iPlayer, ndNotes, sPath );
|
out.m_StepsType = DetermineStepsType( iPlayer, ndNotes, sPath );
|
||||||
if( out.m_StepsType == StepsType_beat_single5 && GetTagFromMap( mapNameToData, "#title", sData ) )
|
if( out.m_StepsType == StepsType_beat_single5 && GetTagFromMap( mapNameToData, "#title", sData ) )
|
||||||
{
|
{
|
||||||
@@ -683,9 +731,12 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
|
|||||||
{
|
{
|
||||||
TapNote tn = ndNotes.GetTapNote( t, row );
|
TapNote tn = ndNotes.GetTapNote( t, row );
|
||||||
int iEmptyTrack = -1;
|
int iEmptyTrack = -1;
|
||||||
for ( int i=0; i<iNumNewTracks; i++ ) {
|
for( int i=0; i<iNumNewTracks; i++ )
|
||||||
if ( ndNotes.GetTapNote(iTransformNewToOld[i], row) == TAP_EMPTY ) {
|
{
|
||||||
|
if ( ndNotes.GetTapNote(iTransformNewToOld[i], row) == TAP_EMPTY )
|
||||||
|
{
|
||||||
iEmptyTrack = iTransformNewToOld[i];
|
iEmptyTrack = iTransformNewToOld[i];
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( iEmptyTrack > -1 )
|
if( iEmptyTrack > -1 )
|
||||||
@@ -765,6 +816,11 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
|
|||||||
RString nData = it->second;
|
RString nData = it->second;
|
||||||
RString sWavID = sName.Right(2);
|
RString sWavID = sName.Right(2);
|
||||||
|
|
||||||
|
// FIXME: garbled song names seem to crash the app.
|
||||||
|
// this might not be the best place to put this code.
|
||||||
|
if( !utf8_is_valid(nData) )
|
||||||
|
continue;
|
||||||
|
|
||||||
/* Due to bugs in some programs, many BMS files have a "WAV" extension
|
/* Due to bugs in some programs, many BMS files have a "WAV" extension
|
||||||
* on files in the BMS for files that actually have some other extension.
|
* on files in the BMS for files that actually have some other extension.
|
||||||
* Do a search. Don't do a wildcard search; if sData is "song.wav",
|
* Do a search. Don't do a wildcard search; if sData is "song.wav",
|
||||||
@@ -813,12 +869,15 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
|
|||||||
{
|
{
|
||||||
RString sPair = nData.substr( i*2, 2 );
|
RString sPair = nData.substr( i*2, 2 );
|
||||||
|
|
||||||
int iVal = 0;
|
|
||||||
if( sscanf( sPair, "%x", &iVal ) == 0 || iVal == 0 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int iRow = iStepIndex + (i * iRowsPerMeasure) / totalPairs;
|
int iRow = iStepIndex + (i * iRowsPerMeasure) / totalPairs;
|
||||||
float fBeat = NoteRowToBeat( iRow );
|
float fBeat = NoteRowToBeat( iRow );
|
||||||
|
int iVal = 0;
|
||||||
|
sscanf( sPair, "%x", &iVal );
|
||||||
|
|
||||||
|
if (sPair == "00")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch( iBMSTrackNo )
|
switch( iBMSTrackNo )
|
||||||
{
|
{
|
||||||
@@ -842,30 +901,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
|
|||||||
if( GetTagFromMap( mapNameToData, sTagToLookFor, sBPM ) )
|
if( GetTagFromMap( mapNameToData, sTagToLookFor, sBPM ) )
|
||||||
{
|
{
|
||||||
float fBPM = StringToFloat( sBPM );
|
float fBPM = StringToFloat( sBPM );
|
||||||
|
out.SetBPMAtBeat( fBeat, fBPM );
|
||||||
if( PREFSMAN->m_bQuirksMode )
|
|
||||||
{
|
|
||||||
BPMSegment newSeg( BeatToNoteRow(fBeat), fBPM );
|
|
||||||
out.AddBPMSegment( newSeg );
|
|
||||||
if( fBPM > 0.0f )
|
|
||||||
LOG->Trace( "Inserting new positive BPM change at beat %f, BPM %f", fBeat, newSeg.GetBPM() );
|
|
||||||
else
|
|
||||||
LOG->Trace( "Inserting new negative BPM change at beat %f, BPM %f", fBeat, newSeg.GetBPM() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( fBPM > 0.0f )
|
|
||||||
{
|
|
||||||
BPMSegment newSeg( BeatToNoteRow(fBeat), fBPM );
|
|
||||||
out.AddBPMSegment( newSeg );
|
|
||||||
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", fBeat, newSeg.GetBPM() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG->UserLog( "Song file", out.GetSongDir(), "has an invalid BPM change at beat %f, BPM %f",
|
|
||||||
fBeat, fBPM );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -875,6 +911,10 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
|
|||||||
}
|
}
|
||||||
case BMS_TRACK_STOP:
|
case BMS_TRACK_STOP:
|
||||||
{
|
{
|
||||||
|
if( iVal == 0 )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
RString sTagToLookFor = ssprintf( "#stop%02x", iVal );
|
RString sTagToLookFor = ssprintf( "#stop%02x", iVal );
|
||||||
RString sBeats;
|
RString sBeats;
|
||||||
if( GetTagFromMap( mapNameToData, sTagToLookFor, sBeats ) )
|
if( GetTagFromMap( mapNameToData, sTagToLookFor, sBeats ) )
|
||||||
@@ -897,53 +937,6 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch( iBMSTrackNo )
|
|
||||||
{
|
|
||||||
case BMS_TRACK_BPM_REF:
|
|
||||||
{
|
|
||||||
// XXX: offset
|
|
||||||
int iBPMNo;
|
|
||||||
sscanf( sData, "%x", &iBPMNo ); // data is in hexadecimal
|
|
||||||
|
|
||||||
RString sBPM;
|
|
||||||
RString sTagToLookFor = ssprintf( "#bpm%02x", iBPMNo );
|
|
||||||
if( GetTagFromMap( mapNameToData, sTagToLookFor, sBPM ) )
|
|
||||||
{
|
|
||||||
float fBPM = StringToFloat( sBPM );
|
|
||||||
|
|
||||||
if( PREFSMAN->m_bQuirksMode )
|
|
||||||
{
|
|
||||||
BPMSegment newSeg( iStepIndex, fBPM );
|
|
||||||
out.AddBPMSegment( newSeg );
|
|
||||||
if( fBPM > 0.0f )
|
|
||||||
LOG->Trace( "Inserting new positive BPM change at beat %f, BPM %f", NoteRowToBeat(newSeg.m_iStartRow), newSeg.GetBPM() );
|
|
||||||
else
|
|
||||||
LOG->Trace( "Inserting new negative BPM change at beat %f, BPM %f", NoteRowToBeat(newSeg.m_iStartRow), newSeg.GetBPM() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( fBPM > 0.0f )
|
|
||||||
{
|
|
||||||
BPMSegment newSeg( iStepIndex, fBPM );
|
|
||||||
out.AddBPMSegment( newSeg );
|
|
||||||
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", NoteRowToBeat(newSeg.m_iStartRow), newSeg.GetBPM() );
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG->UserLog( "Song file", out.GetSongDir(), "has an invalid BPM change at beat %f, BPM %f.",
|
|
||||||
NoteRowToBeat(iStepIndex), fBPM );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG->UserLog( "Song file", out.GetSongDir(), "has tag \"%s\" which cannot be found.", sTagToLookFor.c_str() );
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that we're done reading BPMs, factor out weird time signatures.
|
// Now that we're done reading BPMs, factor out weird time signatures.
|
||||||
|
|||||||
@@ -424,7 +424,7 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadFromBGChangesString( BackgroundChange &change, const RString &sBGChangeExpression )
|
bool SMLoader::LoadFromBGChangesString( BackgroundChange &change, const RString &sBGChangeExpression )
|
||||||
{
|
{
|
||||||
vector<RString> aBGChangeValues;
|
vector<RString> aBGChangeValues;
|
||||||
split( sBGChangeExpression, "=", aBGChangeValues, false );
|
split( sBGChangeExpression, "=", aBGChangeValues, false );
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define NotesLoaderSM_H
|
#define NotesLoaderSM_H
|
||||||
|
|
||||||
#include "GameConstantsAndTypes.h"
|
#include "GameConstantsAndTypes.h"
|
||||||
|
#include "BackgroundUtil.h"
|
||||||
|
|
||||||
class MsdFile;
|
class MsdFile;
|
||||||
class Song;
|
class Song;
|
||||||
@@ -23,6 +24,7 @@ namespace SMLoader
|
|||||||
bool LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong );
|
bool LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong );
|
||||||
bool LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot );
|
bool LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot );
|
||||||
bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong );
|
bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong );
|
||||||
|
bool LoadFromBGChangesString( BackgroundChange &change, const RString &sBGChangeExpression );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,764 @@
|
|||||||
|
#include "global.h"
|
||||||
|
#include "NotesLoaderSMA.h"
|
||||||
|
#include "BackgroundUtil.h"
|
||||||
|
#include "GameManager.h"
|
||||||
|
#include "MsdFile.h"
|
||||||
|
#include "NoteTypes.h"
|
||||||
|
#include "NotesLoaderSM.h" // may need this.
|
||||||
|
#include "PrefsManager.h"
|
||||||
|
#include "RageFileManager.h"
|
||||||
|
#include "RageLog.h"
|
||||||
|
#include "RageUtil.h"
|
||||||
|
#include "Song.h"
|
||||||
|
#include "SongManager.h"
|
||||||
|
#include "Steps.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A custom .edit file can only be so big before we have to reject it.
|
||||||
|
*/
|
||||||
|
const int MAX_EDIT_STEPS_SIZE_BYTES = 60*1024; // 60 KB
|
||||||
|
|
||||||
|
void SMALoader::LoadFromSMATokens(
|
||||||
|
RString sStepsType,
|
||||||
|
RString sDescription,
|
||||||
|
RString sDifficulty,
|
||||||
|
RString sMeter,
|
||||||
|
RString sRadarValues,
|
||||||
|
RString sNoteData,
|
||||||
|
Steps &out
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// we're loading from disk, so this is by definition already saved:
|
||||||
|
out.SetSavedToDisk( true );
|
||||||
|
|
||||||
|
Trim( sStepsType );
|
||||||
|
Trim( sDescription );
|
||||||
|
Trim( sDifficulty );
|
||||||
|
Trim( sNoteData );
|
||||||
|
|
||||||
|
// LOG->Trace( "Steps::LoadFromSMTokens()" );
|
||||||
|
|
||||||
|
// insert stepstype hacks from GameManager.cpp here? -aj
|
||||||
|
out.m_StepsType = GAMEMAN->StringToStepsType( sStepsType );
|
||||||
|
out.SetDescription( sDescription );
|
||||||
|
out.SetCredit( sDescription ); // this is often used for both.
|
||||||
|
out.SetDifficulty( DwiCompatibleStringToDifficulty(sDifficulty) );
|
||||||
|
|
||||||
|
sDescription.MakeLower();
|
||||||
|
|
||||||
|
// Handle hacks that originated back when StepMania didn't have
|
||||||
|
// Difficulty_Challenge. (At least v1.64, possibly v3.0 final...)
|
||||||
|
if( out.GetDifficulty() == Difficulty_Hard )
|
||||||
|
{
|
||||||
|
// HACK: SMANIAC used to be Difficulty_Hard with a special description.
|
||||||
|
if( sDescription == "smaniac" )
|
||||||
|
out.SetDifficulty( Difficulty_Challenge );
|
||||||
|
|
||||||
|
// HACK: CHALLENGE used to be Difficulty_Hard with a special description.
|
||||||
|
if( sDescription == "challenge" )
|
||||||
|
out.SetDifficulty( Difficulty_Challenge );
|
||||||
|
}
|
||||||
|
|
||||||
|
out.SetMeter( atoi(sMeter) );
|
||||||
|
vector<RString> saValues;
|
||||||
|
split( sRadarValues, ",", saValues, true );
|
||||||
|
int categories = NUM_RadarCategory - 1; // Fakes aren't counted in the radar values.
|
||||||
|
if( saValues.size() == (unsigned)categories * NUM_PLAYERS )
|
||||||
|
{
|
||||||
|
RadarValues v[NUM_PLAYERS];
|
||||||
|
FOREACH_PlayerNumber( pn )
|
||||||
|
{
|
||||||
|
// Can't use the foreach anymore due to flexible radar lines.
|
||||||
|
for( RadarCategory rc = (RadarCategory)0; rc < categories;
|
||||||
|
enum_add<RadarCategory>( rc, 1 ) )
|
||||||
|
{
|
||||||
|
v[pn][rc] = StringToFloat( saValues[pn*categories + rc] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.SetCachedRadarValues( v );
|
||||||
|
}
|
||||||
|
|
||||||
|
out.SetSMNoteData( sNoteData );
|
||||||
|
|
||||||
|
out.TidyUpData();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SMALoader::LoadFromDir( const RString &sPath, Song &out )
|
||||||
|
{
|
||||||
|
vector<RString> aFileNames;
|
||||||
|
GetApplicableFiles( sPath, aFileNames );
|
||||||
|
|
||||||
|
if( aFileNames.size() > 1 )
|
||||||
|
{
|
||||||
|
LOG->UserLog( "Song", sPath, "has more than one SMA file. There can be only one!" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ASSERT( aFileNames.size() == 1 );
|
||||||
|
return LoadFromSMAFile( sPath + aFileNames[0], out );
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMALoader::TidyUpData( Song &song, bool bFromCache )
|
||||||
|
{
|
||||||
|
SMLoader::TidyUpData( song, bFromCache );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out )
|
||||||
|
{
|
||||||
|
LOG->Trace( "Song::LoadFromSMAFile(%s)", sPath.c_str() );
|
||||||
|
|
||||||
|
MsdFile msd;
|
||||||
|
if( !msd.ReadFile( sPath, true ) ) // unescape
|
||||||
|
{
|
||||||
|
LOG->UserLog( "Song file", sPath, "couldn't be opened: %s", msd.GetError().c_str() );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.m_Timing.m_sFile = sPath;
|
||||||
|
LoadTimingFromSMAFile( msd, out.m_Timing );
|
||||||
|
|
||||||
|
for( unsigned i=0; i<msd.GetNumValues(); i++ )
|
||||||
|
{
|
||||||
|
int iNumParams = msd.GetNumParams(i);
|
||||||
|
const MsdFile::value_t &sParams = msd.GetValue(i);
|
||||||
|
RString sValueName = sParams[0];
|
||||||
|
sValueName.MakeUpper();
|
||||||
|
|
||||||
|
// handle the data
|
||||||
|
/* Don't use GetMainAndSubTitlesFromFullTitle; that's only for heuristically
|
||||||
|
* splitting other formats that *don't* natively support #SUBTITLE. */
|
||||||
|
if( sValueName=="TITLE" )
|
||||||
|
out.m_sMainTitle = sParams[1];
|
||||||
|
|
||||||
|
else if( sValueName=="SUBTITLE" )
|
||||||
|
out.m_sSubTitle = sParams[1];
|
||||||
|
|
||||||
|
else if( sValueName=="ARTIST" )
|
||||||
|
out.m_sArtist = sParams[1];
|
||||||
|
|
||||||
|
else if( sValueName=="TITLETRANSLIT" )
|
||||||
|
out.m_sMainTitleTranslit = sParams[1];
|
||||||
|
|
||||||
|
else if( sValueName=="SUBTITLETRANSLIT" )
|
||||||
|
out.m_sSubTitleTranslit = sParams[1];
|
||||||
|
|
||||||
|
else if( sValueName=="ARTISTTRANSLIT" )
|
||||||
|
out.m_sArtistTranslit = sParams[1];
|
||||||
|
|
||||||
|
else if( sValueName=="GENRE" )
|
||||||
|
out.m_sGenre = sParams[1];
|
||||||
|
|
||||||
|
else if( sValueName=="CREDIT" )
|
||||||
|
out.m_sCredit = sParams[1];
|
||||||
|
|
||||||
|
else if( sValueName=="BANNER" )
|
||||||
|
out.m_sBannerFile = sParams[1];
|
||||||
|
|
||||||
|
else if( sValueName=="BACKGROUND" )
|
||||||
|
out.m_sBackgroundFile = sParams[1];
|
||||||
|
|
||||||
|
// Save "#LYRICS" for later, so we can add an internal lyrics tag.
|
||||||
|
else if( sValueName=="LYRICSPATH" )
|
||||||
|
out.m_sLyricsFile = sParams[1];
|
||||||
|
|
||||||
|
else if( sValueName=="CDTITLE" )
|
||||||
|
out.m_sCDTitleFile = sParams[1];
|
||||||
|
|
||||||
|
else if( sValueName=="MUSIC" )
|
||||||
|
out.m_sMusicFile = sParams[1];
|
||||||
|
|
||||||
|
else if( sValueName=="INSTRUMENTTRACK" )
|
||||||
|
{
|
||||||
|
vector<RString> vs1;
|
||||||
|
split( sParams[1], ",", vs1 );
|
||||||
|
FOREACH_CONST( RString, vs1, s )
|
||||||
|
{
|
||||||
|
vector<RString> vs2;
|
||||||
|
split( *s, "=", vs2 );
|
||||||
|
if( vs2.size() >= 2 )
|
||||||
|
{
|
||||||
|
InstrumentTrack it = StringToInstrumentTrack( vs2[0] );
|
||||||
|
if( it != InstrumentTrack_Invalid )
|
||||||
|
out.m_sInstrumentTrackFile[it] = vs2[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( sValueName=="MUSICLENGTH" )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( sValueName=="LASTBEATHINT" )
|
||||||
|
out.m_fSpecifiedLastBeat = StringToFloat( sParams[1] );
|
||||||
|
|
||||||
|
else if( sValueName=="MUSICBYTES" )
|
||||||
|
; /* ignore */
|
||||||
|
|
||||||
|
/* We calculate these. Some SMs in circulation have bogus values for
|
||||||
|
* these, so make sure we always calculate it ourself. */
|
||||||
|
else if( sValueName=="FIRSTBEAT" )
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else if( sValueName=="LASTBEAT" )
|
||||||
|
{
|
||||||
|
; }
|
||||||
|
else if( sValueName=="SONGFILENAME" )
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else if( sValueName=="HASMUSIC" )
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else if( sValueName=="HASBANNER" )
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( sValueName=="SAMPLESTART" )
|
||||||
|
out.m_fMusicSampleStartSeconds = HHMMSSToSeconds( sParams[1] );
|
||||||
|
|
||||||
|
else if( sValueName=="SAMPLELENGTH" )
|
||||||
|
out.m_fMusicSampleLengthSeconds = HHMMSSToSeconds( sParams[1] );
|
||||||
|
|
||||||
|
// SamplePath is used when the song has a separate preview clip. -aj
|
||||||
|
//else if( sValueName=="SAMPLEPATH" )
|
||||||
|
//out.m_sMusicSamplePath = sParams[1];
|
||||||
|
|
||||||
|
else if( sValueName=="DISPLAYBPM" )
|
||||||
|
{
|
||||||
|
// #DISPLAYBPM:[xxx][xxx:xxx]|[*];
|
||||||
|
if( sParams[1] == "*" )
|
||||||
|
out.m_DisplayBPMType = Song::DISPLAY_RANDOM;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.m_DisplayBPMType = Song::DISPLAY_SPECIFIED;
|
||||||
|
out.m_fSpecifiedBPMMin = StringToFloat( sParams[1] );
|
||||||
|
if( sParams[2].empty() )
|
||||||
|
out.m_fSpecifiedBPMMax = out.m_fSpecifiedBPMMin;
|
||||||
|
else
|
||||||
|
out.m_fSpecifiedBPMMax = StringToFloat( sParams[2] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( sValueName=="SELECTABLE" )
|
||||||
|
{
|
||||||
|
if(!stricmp(sParams[1],"YES"))
|
||||||
|
out.m_SelectionDisplay = out.SHOW_ALWAYS;
|
||||||
|
else if(!stricmp(sParams[1],"NO"))
|
||||||
|
out.m_SelectionDisplay = out.SHOW_NEVER;
|
||||||
|
// ROULETTE from 3.9. It was removed since UnlockManager can serve
|
||||||
|
// the same purpose somehow. This, of course, assumes you're using
|
||||||
|
// unlocks. -aj
|
||||||
|
else if(!stricmp(sParams[1],"ROULETTE"))
|
||||||
|
out.m_SelectionDisplay = out.SHOW_ALWAYS;
|
||||||
|
/* The following two cases are just fixes to make sure simfiles that
|
||||||
|
* used 3.9+ features are not excluded here */
|
||||||
|
else if(!stricmp(sParams[1],"ES") || !stricmp(sParams[1],"OMES"))
|
||||||
|
out.m_SelectionDisplay = out.SHOW_ALWAYS;
|
||||||
|
else if( atoi(sParams[1]) > 0 )
|
||||||
|
out.m_SelectionDisplay = out.SHOW_ALWAYS;
|
||||||
|
else
|
||||||
|
LOG->UserLog( "Song file", sPath, "has an unknown #SELECTABLE value, \"%s\"; ignored.", sParams[1].c_str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( sValueName.Left(strlen("BGCHANGES"))=="BGCHANGES" || sValueName=="ANIMATIONS" )
|
||||||
|
{
|
||||||
|
BackgroundLayer iLayer = BACKGROUND_LAYER_1;
|
||||||
|
if( sscanf(sValueName, "BGCHANGES%d", &*ConvertValue<int>(&iLayer)) == 1 )
|
||||||
|
enum_add(iLayer, -1); // #BGCHANGES2 = BACKGROUND_LAYER_2
|
||||||
|
|
||||||
|
bool bValid = iLayer>=0 && iLayer<NUM_BackgroundLayer;
|
||||||
|
if( !bValid )
|
||||||
|
{
|
||||||
|
LOG->UserLog( "Song file", sPath, "has a #BGCHANGES tag \"%s\" that is out of range.", sValueName.c_str() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vector<RString> aBGChangeExpressions;
|
||||||
|
split( sParams[1], ",", aBGChangeExpressions );
|
||||||
|
|
||||||
|
for( unsigned b=0; b<aBGChangeExpressions.size(); b++ )
|
||||||
|
{
|
||||||
|
BackgroundChange change;
|
||||||
|
if( LoadFromBGChangesString( change, aBGChangeExpressions[b] ) )
|
||||||
|
out.AddBackgroundChange( iLayer, change );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( sValueName=="FGCHANGES" )
|
||||||
|
{
|
||||||
|
vector<RString> aFGChangeExpressions;
|
||||||
|
split( sParams[1], ",", aFGChangeExpressions );
|
||||||
|
|
||||||
|
for( unsigned b=0; b<aFGChangeExpressions.size(); b++ )
|
||||||
|
{
|
||||||
|
BackgroundChange change;
|
||||||
|
if( LoadFromBGChangesString( change, aFGChangeExpressions[b] ) )
|
||||||
|
out.AddForegroundChange( change );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( sValueName=="KEYSOUNDS" )
|
||||||
|
{
|
||||||
|
split( sParams[1], ",", out.m_vsKeysoundFile );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attacks loaded from file
|
||||||
|
else if( sValueName=="ATTACKS" )
|
||||||
|
{
|
||||||
|
// Build the RString vector here so we can write it to file again later
|
||||||
|
for( unsigned s=1; s < sParams.params.size(); ++s )
|
||||||
|
out.m_sAttackString.push_back( sParams[s] );
|
||||||
|
|
||||||
|
Attack attack;
|
||||||
|
float end = -9999;
|
||||||
|
|
||||||
|
for( unsigned j=1; j < sParams.params.size(); ++j )
|
||||||
|
{
|
||||||
|
vector<RString> sBits;
|
||||||
|
split( sParams[j], "=", sBits, false );
|
||||||
|
|
||||||
|
// Need an identifer and a value for this to work
|
||||||
|
if( sBits.size() < 2 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
TrimLeft( sBits[0] );
|
||||||
|
TrimRight( sBits[0] );
|
||||||
|
|
||||||
|
if( !sBits[0].CompareNoCase("TIME") )
|
||||||
|
attack.fStartSecond = strtof( sBits[1], NULL );
|
||||||
|
else if( !sBits[0].CompareNoCase("LEN") )
|
||||||
|
attack.fSecsRemaining = strtof( sBits[1], NULL );
|
||||||
|
else if( !sBits[0].CompareNoCase("END") )
|
||||||
|
end = strtof( sBits[1], NULL );
|
||||||
|
else if( !sBits[0].CompareNoCase("MODS") )
|
||||||
|
{
|
||||||
|
attack.sModifiers = sBits[1];
|
||||||
|
|
||||||
|
if( end != -9999 )
|
||||||
|
{
|
||||||
|
attack.fSecsRemaining = end - attack.fStartSecond;
|
||||||
|
end = -9999;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( attack.fSecsRemaining < 0.0f )
|
||||||
|
attack.fSecsRemaining = 0.0f;
|
||||||
|
|
||||||
|
out.m_Attacks.push_back( attack );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( sValueName=="NOTES" || sValueName=="NOTES2" )
|
||||||
|
{
|
||||||
|
if( iNumParams < 7 )
|
||||||
|
{
|
||||||
|
LOG->UserLog( "Song file", sPath, "has %d fields in a #NOTES tag, but should have at least 7.", iNumParams );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Steps* pNewNotes = new Steps;
|
||||||
|
LoadFromSMATokens(
|
||||||
|
sParams[1],
|
||||||
|
sParams[2],
|
||||||
|
sParams[3],
|
||||||
|
sParams[4],
|
||||||
|
sParams[5],
|
||||||
|
sParams[6],
|
||||||
|
*pNewNotes );
|
||||||
|
|
||||||
|
out.AddSteps( pNewNotes );
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* We used to check for timing data in this section. That has
|
||||||
|
* since been moved to a dedicated function.
|
||||||
|
*/
|
||||||
|
else if( sValueName=="OFFSET" || sValueName=="BPMS" || sValueName=="STOPS" || sValueName=="FREEZES" || sValueName=="DELAYS" || sValueName=="TIMESIGNATURES" || sValueName=="LEADTRACK" || sValueName=="TICKCOUNTS" )
|
||||||
|
;
|
||||||
|
else
|
||||||
|
LOG->UserLog( "Song file", sPath, "has an unexpected value named \"%s\".", sValueName.c_str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMALoader::GetApplicableFiles( const RString &sPath, vector<RString> &out )
|
||||||
|
{
|
||||||
|
GetDirListing( sPath + RString("*.sma"), out );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SMALoader::LoadTimingFromFile( const RString &fn, TimingData &out )
|
||||||
|
{
|
||||||
|
MsdFile msd;
|
||||||
|
if( !msd.ReadFile( fn, true ) ) // unescape
|
||||||
|
{
|
||||||
|
LOG->UserLog( "Song file", fn, "couldn't be loaded: %s", msd.GetError().c_str() );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.m_sFile = fn;
|
||||||
|
LoadTimingFromSMAFile( msd, out );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMALoader::LoadTimingFromSMAFile( const MsdFile &msd, TimingData &out )
|
||||||
|
{
|
||||||
|
out.m_fBeat0OffsetInSeconds = 0;
|
||||||
|
out.m_BPMSegments.clear();
|
||||||
|
out.m_StopSegments.clear();
|
||||||
|
out.m_WarpSegments.clear();
|
||||||
|
out.m_vTimeSignatureSegments.clear();
|
||||||
|
|
||||||
|
vector<WarpSegment> arrayWarpsFromNegativeBPMs;
|
||||||
|
//vector<WarpSegment> arrayWarpsFromNegativeStops;
|
||||||
|
int rowsPerMeasure = 0;
|
||||||
|
bool encountered = false;
|
||||||
|
|
||||||
|
for( unsigned i=0; i<msd.GetNumValues(); i++ )
|
||||||
|
{
|
||||||
|
const MsdFile::value_t &sParams = msd.GetValue(i);
|
||||||
|
RString sValueName = sParams[0];
|
||||||
|
sValueName.MakeUpper();
|
||||||
|
|
||||||
|
if( sValueName=="ROWSPERBEAT")
|
||||||
|
{
|
||||||
|
if( encountered )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
encountered = true;
|
||||||
|
rowsPerMeasure = atoi( sParams[1] );
|
||||||
|
}
|
||||||
|
else if( sValueName=="BEATSPERMEASURE" )
|
||||||
|
{
|
||||||
|
TimeSignatureSegment new_seg;
|
||||||
|
new_seg.m_iStartRow = 0;
|
||||||
|
new_seg.m_iNumerator = atoi( sParams[1] );
|
||||||
|
new_seg.m_iDenominator = 4;
|
||||||
|
out.AddTimeSignatureSegment( new_seg );
|
||||||
|
}
|
||||||
|
else if( sValueName=="OFFSET" )
|
||||||
|
{
|
||||||
|
out.m_fBeat0OffsetInSeconds = StringToFloat( sParams[1] );
|
||||||
|
}
|
||||||
|
else if( sValueName=="STOPS" )
|
||||||
|
{
|
||||||
|
vector<RString> arrayFreezeExpressions;
|
||||||
|
split( sParams[1], ",", arrayFreezeExpressions );
|
||||||
|
|
||||||
|
for( unsigned f=0; f<arrayFreezeExpressions.size(); f++ )
|
||||||
|
{
|
||||||
|
vector<RString> arrayFreezeValues;
|
||||||
|
split( arrayFreezeExpressions[f], "=", arrayFreezeValues );
|
||||||
|
if( arrayFreezeValues.size() != 2 )
|
||||||
|
{
|
||||||
|
// XXX: Hard to tell which file caused this.
|
||||||
|
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.",
|
||||||
|
sValueName.c_str(), arrayFreezeExpressions[f].c_str() );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float fFreezeBeat = 0;
|
||||||
|
RString beat = arrayFreezeValues[0];
|
||||||
|
if( beat.Right(0).MakeUpper() == "R" )
|
||||||
|
{
|
||||||
|
beat = beat.Left(beat.size()-1);
|
||||||
|
fFreezeBeat = StringToFloat( beat ) / rowsPerMeasure;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fFreezeBeat = StringToFloat(beat);
|
||||||
|
}
|
||||||
|
|
||||||
|
//float fFreezeBeat = StringToFloat( arrayBPMChangeValues[0] );
|
||||||
|
const float fFreezeSeconds = StringToFloat( arrayFreezeValues[1] );
|
||||||
|
StopSegment new_seg( BeatToNoteRow(fFreezeBeat), fFreezeSeconds );
|
||||||
|
// XXX: Remove Negatives Bug?
|
||||||
|
new_seg.m_iStartRow = BeatToNoteRow(fFreezeBeat);
|
||||||
|
new_seg.m_fStopSeconds = fFreezeSeconds;
|
||||||
|
|
||||||
|
if(fFreezeSeconds > 0.0f)
|
||||||
|
{
|
||||||
|
// LOG->Trace( "Adding a freeze segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds );
|
||||||
|
out.AddStopSegment( new_seg );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// negative stops (hi JS!) -aj
|
||||||
|
if( PREFSMAN->m_bQuirksMode )
|
||||||
|
{
|
||||||
|
// LOG->Trace( "Adding a negative freeze segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds );
|
||||||
|
out.AddStopSegment( new_seg );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid stop at beat %f, length %f.", fFreezeBeat, fFreezeSeconds );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( sValueName=="BPMS" )
|
||||||
|
{
|
||||||
|
vector<RString> arrayBPMChangeExpressions;
|
||||||
|
split( sParams[1], ",", arrayBPMChangeExpressions );
|
||||||
|
|
||||||
|
for( unsigned b=0; b<arrayBPMChangeExpressions.size(); b++ )
|
||||||
|
{
|
||||||
|
vector<RString> arrayBPMChangeValues;
|
||||||
|
split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues );
|
||||||
|
// XXX: Hard to tell which file caused this.
|
||||||
|
if( arrayBPMChangeValues.size() != 2 )
|
||||||
|
{
|
||||||
|
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.",
|
||||||
|
sValueName.c_str(), arrayBPMChangeExpressions[b].c_str() );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
float fBeat = 0;
|
||||||
|
RString beat = arrayBPMChangeValues[0];
|
||||||
|
if( beat.Right(0).MakeUpper() == "R" )
|
||||||
|
{
|
||||||
|
beat = beat.Left(beat.size()-1);
|
||||||
|
fBeat = StringToFloat( beat ) / rowsPerMeasure;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fBeat = StringToFloat(beat);
|
||||||
|
}
|
||||||
|
|
||||||
|
//float fBeat = StringToFloat( arrayBPMChangeValues[0] );
|
||||||
|
const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] );
|
||||||
|
// XXX: Remove Negatives Bug?
|
||||||
|
BPMSegment new_seg;
|
||||||
|
new_seg.m_iStartRow = BeatToNoteRow(fBeat);
|
||||||
|
new_seg.SetBPM( fNewBPM );
|
||||||
|
|
||||||
|
// convert negative BPMs into Warp segments
|
||||||
|
if( fNewBPM < 0.0f )
|
||||||
|
{
|
||||||
|
vector<RString> arrayNextBPMChangeValues;
|
||||||
|
// get next bpm in sequence
|
||||||
|
if((b+1) < arrayBPMChangeExpressions.size())
|
||||||
|
{
|
||||||
|
split( arrayBPMChangeExpressions[b+1], "=", arrayNextBPMChangeValues );
|
||||||
|
const float fNextPositiveBeat = StringToFloat( arrayNextBPMChangeValues[0] );
|
||||||
|
const float fNextPositiveBPM = StringToFloat( arrayNextBPMChangeValues[1] );
|
||||||
|
|
||||||
|
// tJumpPos = (tPosBPS-abs(negBPS)) + (gPosBPMPosition - fNegPosition)
|
||||||
|
float fDeltaBeat = ((fNextPositiveBPM/60.0f)-abs(fNewBPM/60.0f)) + (fNextPositiveBeat-fBeat);
|
||||||
|
//float fWarpLengthBeats = fNextPositiveBeat + fDeltaBeat;
|
||||||
|
WarpSegment wsTemp(BeatToNoteRow(fBeat),fDeltaBeat);
|
||||||
|
arrayWarpsFromNegativeBPMs.push_back(wsTemp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
LOG->Trace( ssprintf("==NotesLoSM negbpm==\nfnextposbeat = %f, fnextposbpm = %f,\nfdelta = %f, fwarpto = %f",
|
||||||
|
fNextPositiveBeat,
|
||||||
|
fNextPositiveBPM,
|
||||||
|
fDeltaBeat,
|
||||||
|
fWarpToBeat
|
||||||
|
) );
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
LOG->Trace( ssprintf("==Negative/Subtractive BPM in NotesLoader==\nNegBPM has noterow = %i, BPM = %f\nNextBPM @ noterow %i\nDelta value = %i noterows\nThis warp will have us end up at noterow %i",
|
||||||
|
BeatToNoteRow(fBeat), fNewBPM,
|
||||||
|
BeatToNoteRow(fNextPositiveBeat),
|
||||||
|
BeatToNoteRow(fDeltaBeat),
|
||||||
|
BeatToNoteRow(fWarpToBeat))
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
//float fDeltaBeat = ((fNextPositiveBPM/60.0f)-abs(fNewBPM/60.0f)) + (fNextPositiveBeat-fBeat);
|
||||||
|
/*
|
||||||
|
LOG->Trace( ssprintf("==NotesLoader Delta as NoteRows==\nfDeltaBeat = %f (beat)\nfDeltaBeat = (NextBPMSeg %f - abs(fBPS %f)) + (nextStartRow %i - thisRow %i)",
|
||||||
|
fDeltaBeat,(fNextPositiveBPM/60.0f),abs(fNewBPM/60.0f),BeatToNoteRow(fNextPositiveBeat),BeatToNoteRow(fBeat))
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
|
out.AddBPMSegment( new_seg );
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// last BPM is a negative one? ugh. -aj (MAX_NOTE_ROW exists btw)
|
||||||
|
out.AddBPMSegment( new_seg );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fNewBPM > 0.0f)
|
||||||
|
out.AddBPMSegment( new_seg );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.m_bHasNegativeBpms = true;
|
||||||
|
// only add Negative BPMs in quirks mode -aj
|
||||||
|
if( PREFSMAN->m_bQuirksMode )
|
||||||
|
out.AddBPMSegment( new_seg );
|
||||||
|
else
|
||||||
|
LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid BPM change at beat %f, BPM %f.", fBeat, fNewBPM );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Note: Even though it is possible to have Negative BPMs and Stops in
|
||||||
|
// a song along with Warps, we should not support files that contain
|
||||||
|
// both styles of warp tricks (Negatives vs. #WARPS).
|
||||||
|
// If Warps have been populated from Negative BPMs, then go through that
|
||||||
|
// instead of using the data in the Warps tag. This should be above,
|
||||||
|
// but it breaks compiling so...
|
||||||
|
if(arrayWarpsFromNegativeBPMs.size() > 0)
|
||||||
|
{
|
||||||
|
// zomg we already have some warps...
|
||||||
|
for( unsigned j=0; j<arrayWarpsFromNegativeBPMs.size(); j++ )
|
||||||
|
{
|
||||||
|
out.AddWarpSegment( arrayWarpsFromNegativeBPMs[j] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// warp sorting will need to take place.
|
||||||
|
//sort(out.m_WarpSegments.begin(), out.m_WarpSegments.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SMALoader::LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong )
|
||||||
|
{
|
||||||
|
LOG->Trace( "SMALoader::LoadEditFromFile(%s)", sEditFilePath.c_str() );
|
||||||
|
|
||||||
|
int iBytes = FILEMAN->GetFileSizeInBytes( sEditFilePath );
|
||||||
|
if( iBytes > MAX_EDIT_STEPS_SIZE_BYTES )
|
||||||
|
{
|
||||||
|
LOG->UserLog( "Edit file", sEditFilePath, "is unreasonably large. It won't be loaded." );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MsdFile msd;
|
||||||
|
if( !msd.ReadFile( sEditFilePath, true ) ) // unescape
|
||||||
|
{
|
||||||
|
LOG->UserLog( "Edit file", sEditFilePath, "couldn't be opened: %s", msd.GetError().c_str() );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LoadEditFromMsd( msd, sEditFilePath, slot, bAddStepsToSong );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SMALoader::LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot )
|
||||||
|
{
|
||||||
|
MsdFile msd;
|
||||||
|
msd.ReadFromString( sBuffer, true ); // unescape
|
||||||
|
return LoadEditFromMsd( msd, sEditFilePath, slot, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SMALoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong )
|
||||||
|
{
|
||||||
|
Song* pSong = NULL;
|
||||||
|
|
||||||
|
for( unsigned i=0; i<msd.GetNumValues(); i++ )
|
||||||
|
{
|
||||||
|
int iNumParams = msd.GetNumParams(i);
|
||||||
|
const MsdFile::value_t &sParams = msd.GetValue(i);
|
||||||
|
RString sValueName = sParams[0];
|
||||||
|
sValueName.MakeUpper();
|
||||||
|
|
||||||
|
// handle the data
|
||||||
|
if( sValueName=="SONG" )
|
||||||
|
{
|
||||||
|
if( pSong )
|
||||||
|
{
|
||||||
|
LOG->UserLog( "Edit file", sEditFilePath, "has more than one #SONG tag." );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RString sSongFullTitle = sParams[1];
|
||||||
|
sSongFullTitle.Replace( '\\', '/' );
|
||||||
|
|
||||||
|
pSong = SONGMAN->FindSong( sSongFullTitle );
|
||||||
|
if( pSong == NULL )
|
||||||
|
{
|
||||||
|
LOG->UserLog( "Edit file", sEditFilePath, "requires a song \"%s\" that isn't present.", sSongFullTitle.c_str() );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pSong->GetNumStepsLoadedFromProfile(slot) >= MAX_EDITS_PER_SONG_PER_PROFILE )
|
||||||
|
{
|
||||||
|
LOG->UserLog( "Song file", sSongFullTitle, "already has the maximum number of edits allowed for ProfileSlotP%d.", slot+1 );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( sValueName=="NOTES" )
|
||||||
|
{
|
||||||
|
if( pSong == NULL )
|
||||||
|
{
|
||||||
|
LOG->UserLog( "Edit file", sEditFilePath, "doesn't have a #SONG tag preceeding the first #NOTES tag." );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( iNumParams < 7 )
|
||||||
|
{
|
||||||
|
LOG->UserLog( "Edit file", sEditFilePath, "has %d fields in a #NOTES tag, but should have at least 7.", iNumParams );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !bAddStepsToSong )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
Steps* pNewNotes = new Steps;
|
||||||
|
LoadFromSMATokens(
|
||||||
|
sParams[1], sParams[2], sParams[3], sParams[4], sParams[5], sParams[6],
|
||||||
|
*pNewNotes);
|
||||||
|
|
||||||
|
pNewNotes->SetLoadedFromProfile( slot );
|
||||||
|
pNewNotes->SetDifficulty( Difficulty_Edit );
|
||||||
|
pNewNotes->SetFilename( sEditFilePath );
|
||||||
|
|
||||||
|
if( pSong->IsEditAlreadyLoaded(pNewNotes) )
|
||||||
|
{
|
||||||
|
LOG->UserLog( "Edit file", sEditFilePath, "is a duplicate of another edit that was already loaded." );
|
||||||
|
SAFE_DELETE( pNewNotes );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pSong->AddSteps( pNewNotes );
|
||||||
|
return true; // Only allow one Steps per edit file!
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG->UserLog( "Edit file", sEditFilePath, "has an unexpected value \"%s\".", sValueName.c_str() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SMALoader::LoadFromBGChangesString( BackgroundChange &change,
|
||||||
|
const RString &sBGChangeExpression )
|
||||||
|
{
|
||||||
|
return SMLoader::LoadFromBGChangesString(change, sBGChangeExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @author Aldo Fregoso, Jason Felds (c) 2009-2011
|
||||||
|
* @section LICENSE
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
#ifndef NOTES_LOADER_SMA_H
|
||||||
|
#define NOTES_LOADER_SMA_H
|
||||||
|
|
||||||
|
#include "GameConstantsAndTypes.h"
|
||||||
|
#include "BackgroundUtil.h"
|
||||||
|
|
||||||
|
class MsdFile;
|
||||||
|
class Song;
|
||||||
|
class Steps;
|
||||||
|
class TimingData;
|
||||||
|
|
||||||
|
/** @brief Reads a Song from a .SMA file. */
|
||||||
|
namespace SMALoader
|
||||||
|
{
|
||||||
|
void LoadFromSMATokens( RString sStepsType,
|
||||||
|
RString sDescription,
|
||||||
|
RString sDifficulty,
|
||||||
|
RString sMeter,
|
||||||
|
RString sRadarValues,
|
||||||
|
RString sNoteData,
|
||||||
|
Steps &out );
|
||||||
|
|
||||||
|
bool LoadFromDir( const RString &sPath, Song &out );
|
||||||
|
void TidyUpData( Song &song, bool bFromCache );
|
||||||
|
|
||||||
|
bool LoadFromSMAFile( const RString &sPath, Song &out );
|
||||||
|
void GetApplicableFiles( const RString &sPath, vector<RString> &out );
|
||||||
|
bool LoadTimingFromFile( const RString &fn, TimingData &out );
|
||||||
|
void LoadTimingFromSMAFile( const MsdFile &msd, TimingData &out );
|
||||||
|
bool LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong );
|
||||||
|
bool LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot );
|
||||||
|
bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong );
|
||||||
|
bool LoadFromBGChangesString( BackgroundChange &change, const RString &sBGChangeExpression );
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @author Aldo Fregoso, Jason Felds (c) 2009-2011
|
||||||
|
* @section LICENSE
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
+34
-9
@@ -600,9 +600,7 @@ void Player::Load()
|
|||||||
|
|
||||||
// parameters are invalid somehow... -aj
|
// parameters are invalid somehow... -aj
|
||||||
RageSoundLoadParams SoundParams;
|
RageSoundLoadParams SoundParams;
|
||||||
//RageSoundParams p;
|
|
||||||
SoundParams.m_bSupportPan = true;
|
SoundParams.m_bSupportPan = true;
|
||||||
//p.StopMode = RageSoundParams::M_STOP;
|
|
||||||
|
|
||||||
float fBalance = GameSoundManager::GetPlayerBalance( pn );
|
float fBalance = GameSoundManager::GetPlayerBalance( pn );
|
||||||
for( unsigned i=0; i<m_vKeysounds.size(); i++ )
|
for( unsigned i=0; i<m_vKeysounds.size(); i++ )
|
||||||
@@ -612,7 +610,7 @@ void Player::Load()
|
|||||||
if( sound.GetLoadedFilePath() != sKeysoundFilePath )
|
if( sound.GetLoadedFilePath() != sKeysoundFilePath )
|
||||||
sound.Load( sKeysoundFilePath, true, &SoundParams );
|
sound.Load( sKeysoundFilePath, true, &SoundParams );
|
||||||
sound.SetProperty( "Pan", fBalance );
|
sound.SetProperty( "Pan", fBalance );
|
||||||
//sound.SetParams( p );
|
sound.SetStopModeFromString( "stop" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_pPlayerStageStats )
|
if( m_pPlayerStageStats )
|
||||||
@@ -1300,16 +1298,22 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vector<TrackRowTap
|
|||||||
tn.HoldResult.hns = hns;
|
tn.HoldResult.hns = hns;
|
||||||
// Stop the playing keysound for the hold note.
|
// Stop the playing keysound for the hold note.
|
||||||
// I think this causes crashes too -aj
|
// I think this causes crashes too -aj
|
||||||
/*
|
// Possibly fixed.
|
||||||
m_vKeysounds[tn.iKeysoundIndex].SetProperty ("Volume", max(0.0, min(1.0, fLife * 5.0 - 4.0)));
|
|
||||||
if( tn.iKeysoundIndex >= 0 && tn.iKeysoundIndex < (int) m_vKeysounds.size() )
|
if( tn.iKeysoundIndex >= 0 && tn.iKeysoundIndex < (int) m_vKeysounds.size() )
|
||||||
{
|
{
|
||||||
|
if( tn.subType == TapNote::hold_head_roll )
|
||||||
|
{
|
||||||
|
m_vKeysounds[tn.iKeysoundIndex].SetProperty ("Volume", max(0.0, min(1.0, fLife * 2.0)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_vKeysounds[tn.iKeysoundIndex].SetProperty ("Volume", max(0.0, min(1.0, fLife * 10.0 - 8.5)));
|
||||||
|
}
|
||||||
if (tn.HoldResult.fLife == 0)
|
if (tn.HoldResult.fLife == 0)
|
||||||
{
|
{
|
||||||
m_vKeysounds[tn.iKeysoundIndex].StopPlaying();
|
m_vKeysounds[tn.iKeysoundIndex].StopPlaying();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( hns != HNS_None )
|
if( hns != HNS_None )
|
||||||
@@ -2427,10 +2431,29 @@ done_checking_hopo:
|
|||||||
* even that doesn't seem quite right since it would then play the same (new) keysound twice which would
|
* even that doesn't seem quite right since it would then play the same (new) keysound twice which would
|
||||||
* sound wrong even though the notes were judged as being correct, above. Fixing the above problem would
|
* sound wrong even though the notes were judged as being correct, above. Fixing the above problem would
|
||||||
* fix this one as well. */
|
* fix this one as well. */
|
||||||
if( iRowOfOverlappingNoteOrRow == -1 )
|
int iHeadRow;
|
||||||
|
if( iRowOfOverlappingNoteOrRow != -1 && score != TNS_None )
|
||||||
|
{
|
||||||
|
// just pressing a note, use that row.
|
||||||
|
// in other words, iRowOfOverlappingNoteOrRow = iRowOfOverlappingNoteOrRow
|
||||||
|
}
|
||||||
|
else if ( m_NoteData.IsHoldNoteAtRow( col, iSongRow, &iHeadRow ) )
|
||||||
|
{
|
||||||
|
// stepping on a hold, use it!
|
||||||
|
iRowOfOverlappingNoteOrRow = iHeadRow;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// or else find the closest note.
|
||||||
iRowOfOverlappingNoteOrRow = GetClosestNote( col, iSongRow, MAX_NOTE_ROW, MAX_NOTE_ROW, true );
|
iRowOfOverlappingNoteOrRow = GetClosestNote( col, iSongRow, MAX_NOTE_ROW, MAX_NOTE_ROW, true );
|
||||||
|
}
|
||||||
if( iRowOfOverlappingNoteOrRow != -1 )
|
if( iRowOfOverlappingNoteOrRow != -1 )
|
||||||
{
|
{
|
||||||
|
bool bShouldPlayNextKeysound = true;
|
||||||
|
|
||||||
|
if( bShouldPlayNextKeysound )
|
||||||
|
{
|
||||||
|
|
||||||
switch( pbt )
|
switch( pbt )
|
||||||
{
|
{
|
||||||
DEFAULT_FAIL(pbt);
|
DEFAULT_FAIL(pbt);
|
||||||
@@ -2438,7 +2461,7 @@ done_checking_hopo:
|
|||||||
for( int i=0; i<m_NoteData.GetNumTracks(); i++ )
|
for( int i=0; i<m_NoteData.GetNumTracks(); i++ )
|
||||||
{
|
{
|
||||||
const TapNote &tn = m_NoteData.GetTapNote( i, iRowOfOverlappingNoteOrRow );
|
const TapNote &tn = m_NoteData.GetTapNote( i, iRowOfOverlappingNoteOrRow );
|
||||||
if( tn.iKeysoundIndex >= 0 && tn.iKeysoundIndex < (int) m_vKeysounds.size() && (tn.type != TapNote::hold_head || (!tn.HoldResult.bActive || (tn.HoldResult.fOverlappedTime == 0))) )
|
if( tn.iKeysoundIndex >= 0 && tn.iKeysoundIndex < (int) m_vKeysounds.size() && (tn.type != TapNote::hold_head || (!tn.HoldResult.bActive || (tn.HoldResult.fOverlappedTime == 0 || (tn.HoldResult.hns == HNS_Held)))) )
|
||||||
{
|
{
|
||||||
m_vKeysounds[tn.iKeysoundIndex].Play();
|
m_vKeysounds[tn.iKeysoundIndex].Play();
|
||||||
m_vKeysounds[tn.iKeysoundIndex].SetProperty ("Volume", 1);
|
m_vKeysounds[tn.iKeysoundIndex].SetProperty ("Volume", 1);
|
||||||
@@ -2448,13 +2471,15 @@ done_checking_hopo:
|
|||||||
case ButtonType_Step:
|
case ButtonType_Step:
|
||||||
case ButtonType_Hopo:
|
case ButtonType_Hopo:
|
||||||
const TapNote &tn = m_NoteData.GetTapNote( col, iRowOfOverlappingNoteOrRow );
|
const TapNote &tn = m_NoteData.GetTapNote( col, iRowOfOverlappingNoteOrRow );
|
||||||
if( tn.iKeysoundIndex >= 0 && tn.iKeysoundIndex < (int) m_vKeysounds.size() && (tn.type != TapNote::hold_head || (!tn.HoldResult.bActive || (tn.HoldResult.fOverlappedTime == 0))) )
|
if( tn.iKeysoundIndex >= 0 && tn.iKeysoundIndex < (int) m_vKeysounds.size() && (tn.type != TapNote::hold_head || (!tn.HoldResult.bActive || (tn.HoldResult.fOverlappedTime == 0 || (tn.HoldResult.hns == HNS_Held)))) )
|
||||||
{
|
{
|
||||||
m_vKeysounds[tn.iKeysoundIndex].Play();
|
m_vKeysounds[tn.iKeysoundIndex].Play();
|
||||||
m_vKeysounds[tn.iKeysoundIndex].SetProperty ("Volume", 1);
|
m_vKeysounds[tn.iKeysoundIndex].SetProperty ("Volume", 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// XXX:
|
// XXX:
|
||||||
|
|||||||
+3
-3
@@ -179,16 +179,15 @@ public:
|
|||||||
float m_fPerspectiveTilt, m_SpeedfPerspectiveTilt; // -1 = near, 0 = overhead, +1 = space
|
float m_fPerspectiveTilt, m_SpeedfPerspectiveTilt; // -1 = near, 0 = overhead, +1 = space
|
||||||
float m_fSkew, m_SpeedfSkew; // 0 = vanish point is in center of player, 1 = vanish point is in center of screen
|
float m_fSkew, m_SpeedfSkew; // 0 = vanish point is in center of player, 1 = vanish point is in center of screen
|
||||||
|
|
||||||
float m_fRandomSpeed, m_SpeedfRandomSpeed;
|
|
||||||
|
|
||||||
/* If this is > 0, then the player must have life above this value at the end of
|
/* If this is > 0, then the player must have life above this value at the end of
|
||||||
* the song to pass. This is independent of SongOptions::m_FailType. */
|
* the song to pass. This is independent of SongOptions::m_FailType. */
|
||||||
float m_fPassmark, m_SpeedfPassmark;
|
float m_fPassmark, m_SpeedfPassmark;
|
||||||
|
|
||||||
|
float m_fRandomSpeed, m_SpeedfRandomSpeed;
|
||||||
|
|
||||||
bool m_bTurns[NUM_TURNS];
|
bool m_bTurns[NUM_TURNS];
|
||||||
bool m_bTransforms[NUM_TRANSFORMS];
|
bool m_bTransforms[NUM_TRANSFORMS];
|
||||||
bool m_bMuteOnError;
|
bool m_bMuteOnError;
|
||||||
ScoreDisplay m_ScoreDisplay;
|
|
||||||
/** @brief How can the Player fail a song? */
|
/** @brief How can the Player fail a song? */
|
||||||
enum FailType {
|
enum FailType {
|
||||||
FAIL_IMMEDIATE=0, /**< fail immediately when life touches 0 */
|
FAIL_IMMEDIATE=0, /**< fail immediately when life touches 0 */
|
||||||
@@ -198,6 +197,7 @@ public:
|
|||||||
};
|
};
|
||||||
/** @brief The method for which a player can fail a song. */
|
/** @brief The method for which a player can fail a song. */
|
||||||
FailType m_FailType;
|
FailType m_FailType;
|
||||||
|
ScoreDisplay m_ScoreDisplay;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The Noteskin to use.
|
* @brief The Noteskin to use.
|
||||||
|
|||||||
@@ -216,7 +216,6 @@ void ScreenDebugOverlay::Init()
|
|||||||
RString sPageName = (*p)->GetPageName();
|
RString sPageName = (*p)->GetPageName();
|
||||||
|
|
||||||
DeviceInput di;
|
DeviceInput di;
|
||||||
di.x = di.y = NULL;
|
|
||||||
switch( (*p)->GetType() )
|
switch( (*p)->GetType() )
|
||||||
{
|
{
|
||||||
case IDebugLine::all_screens:
|
case IDebugLine::all_screens:
|
||||||
|
|||||||
+24
-6
@@ -800,7 +800,7 @@ void ScreenEdit::Init()
|
|||||||
m_bHasUndo = false;
|
m_bHasUndo = false;
|
||||||
m_Undo.SetNumTracks( m_NoteDataEdit.GetNumTracks() );
|
m_Undo.SetNumTracks( m_NoteDataEdit.GetNumTracks() );
|
||||||
|
|
||||||
m_bDirty = false;
|
m_bDirty = m_NoteDataEdit.IsEmpty(); // require the usage of saving if empty.
|
||||||
|
|
||||||
m_Player->Init( "Player", GAMESTATE->m_pPlayerState[PLAYER_1], NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL );
|
m_Player->Init( "Player", GAMESTATE->m_pPlayerState[PLAYER_1], NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL );
|
||||||
m_Player->CacheAllUsedNoteSkins();
|
m_Player->CacheAllUsedNoteSkins();
|
||||||
@@ -2816,7 +2816,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
|||||||
HandleMainMenuChoice( ScreenEdit::save_on_exit );
|
HandleMainMenuChoice( ScreenEdit::save_on_exit );
|
||||||
return;
|
return;
|
||||||
case ANSWER_NO:
|
case ANSWER_NO:
|
||||||
/* Don't save; just exit. */
|
// Don't save; just exit.
|
||||||
SCREENMAN->SendMessageToTopScreen( SM_DoExit );
|
SCREENMAN->SendMessageToTopScreen( SM_DoExit );
|
||||||
return;
|
return;
|
||||||
case ANSWER_CANCEL:
|
case ANSWER_CANCEL:
|
||||||
@@ -2848,15 +2848,32 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
|||||||
// IMPORTANT: CopyFromLastSave before deleting the Steps below
|
// IMPORTANT: CopyFromLastSave before deleting the Steps below
|
||||||
CopyFromLastSave();
|
CopyFromLastSave();
|
||||||
|
|
||||||
/* The user has been given a choice to save. Delete all unsaved
|
/* The user has been given a choice to save.
|
||||||
* steps before exiting the editor. */
|
* Delete all unsaved steps before exiting the editor. */
|
||||||
|
/* FIXME: This code causes all the steps to be deleted if you quit
|
||||||
|
* without saving. However, without this code, any new steps will get
|
||||||
|
* saved on quit. -aj */
|
||||||
|
|
||||||
|
// At this point, the last good song copy is in use.
|
||||||
Song *pSong = GAMESTATE->m_pCurSong;
|
Song *pSong = GAMESTATE->m_pCurSong;
|
||||||
const vector<Steps*> &apSteps = pSong->GetAllSteps();
|
const vector<Steps*> &apSteps = pSong->GetAllSteps();
|
||||||
vector<Steps*> apToDelete;
|
vector<Steps*> apToDelete;
|
||||||
FOREACH_CONST( Steps *, apSteps, s )
|
FOREACH_CONST( Steps *, apSteps, s )
|
||||||
{
|
{
|
||||||
if( (*s)->IsAutogen() || (*s)->GetSavedToDisk() )
|
// If we're not on the same style, let it go.
|
||||||
|
if( GAMESTATE->m_pCurSteps[PLAYER_1]->m_StepsType != (*s)->m_StepsType )
|
||||||
continue;
|
continue;
|
||||||
|
// If autogenned, it isn't being saved.
|
||||||
|
if( (*s)->IsAutogen() )
|
||||||
|
continue;
|
||||||
|
// If the notedata has content, let it go.
|
||||||
|
if( !(*s)->m_NoteData->IsEmpty() )
|
||||||
|
continue;
|
||||||
|
// It's hard to say if these steps were saved to disk or not.
|
||||||
|
/*
|
||||||
|
if( !(*s)->GetSavedToDisk() )
|
||||||
|
continue;
|
||||||
|
*/
|
||||||
apToDelete.push_back( *s );
|
apToDelete.push_back( *s );
|
||||||
}
|
}
|
||||||
FOREACH_CONST( Steps *, apToDelete, s )
|
FOREACH_CONST( Steps *, apToDelete, s )
|
||||||
@@ -2869,6 +2886,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
|||||||
GAMESTATE->m_pCurSteps[PLAYER_1].Set( NULL );
|
GAMESTATE->m_pCurSteps[PLAYER_1].Set( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
m_Out.StartTransitioning( SM_GoToNextScreen );
|
m_Out.StartTransitioning( SM_GoToNextScreen );
|
||||||
}
|
}
|
||||||
else if( SM == SM_GainFocus )
|
else if( SM == SM_GainFocus )
|
||||||
@@ -4123,7 +4141,7 @@ void ScreenEdit::DoHelp()
|
|||||||
// lua start
|
// lua start
|
||||||
#include "LuaBinding.h"
|
#include "LuaBinding.h"
|
||||||
|
|
||||||
/** @brief Allow Lua to have access to the ScreenEdit. */
|
/** @brief Allow Lua to have access to ScreenEdit. */
|
||||||
class LunaScreenEdit: public Luna<ScreenEdit>
|
class LunaScreenEdit: public Luna<ScreenEdit>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ void ScreenEditMenu::Init()
|
|||||||
m_Selector.SetXY( 0, 0 );
|
m_Selector.SetXY( 0, 0 );
|
||||||
this->AddChild( &m_Selector );
|
this->AddChild( &m_Selector );
|
||||||
|
|
||||||
|
|
||||||
m_textExplanation.SetName( "Explanation" );
|
m_textExplanation.SetName( "Explanation" );
|
||||||
m_textExplanation.LoadFromFont( THEME->GetPathF(m_sName,"explanation") );
|
m_textExplanation.LoadFromFont( THEME->GetPathF(m_sName,"explanation") );
|
||||||
LOAD_ALL_COMMANDS_AND_SET_XY( m_textExplanation );
|
LOAD_ALL_COMMANDS_AND_SET_XY( m_textExplanation );
|
||||||
@@ -59,7 +58,6 @@ void ScreenEditMenu::Init()
|
|||||||
this->AddChild( &m_textNumStepsLoadedFromProfile );
|
this->AddChild( &m_textNumStepsLoadedFromProfile );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ScreenEditMenu::HandleScreenMessage( const ScreenMessage SM )
|
void ScreenEditMenu::HandleScreenMessage( const ScreenMessage SM )
|
||||||
{
|
{
|
||||||
if( SM == SM_RefreshSelector )
|
if( SM == SM_RefreshSelector )
|
||||||
@@ -77,8 +75,8 @@ void ScreenEditMenu::HandleScreenMessage( const ScreenMessage SM )
|
|||||||
pSong->DeleteSteps( pStepsToDelete );
|
pSong->DeleteSteps( pStepsToDelete );
|
||||||
SONGMAN->Invalidate( pSong );
|
SONGMAN->Invalidate( pSong );
|
||||||
|
|
||||||
/* Only save to the main .SM file if the steps we're deleting were loaded
|
/* Only save to the main .SM file if the steps we're deleting
|
||||||
* from it. */
|
* were loaded from it. */
|
||||||
if( bSaveSong )
|
if( bSaveSong )
|
||||||
{
|
{
|
||||||
pSong->Save();
|
pSong->Save();
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ void ScreenEvaluation::Init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT( !STATSMAN->m_vPlayedStageStats.empty() );
|
ASSERT_M( !STATSMAN->m_vPlayedStageStats.empty(), "PlayerStageStats is empty!" );
|
||||||
m_pStageStats = &STATSMAN->m_vPlayedStageStats.back();
|
m_pStageStats = &STATSMAN->m_vPlayedStageStats.back();
|
||||||
|
|
||||||
ZERO( m_bSavedScreenshot );
|
ZERO( m_bSavedScreenshot );
|
||||||
|
|||||||
+25
-7
@@ -223,8 +223,15 @@ bool Song::LoadFromSongDir( RString sDir )
|
|||||||
if( bUseCache )
|
if( bUseCache )
|
||||||
{
|
{
|
||||||
// LOG->Trace( "Loading '%s' from cache file '%s'.", m_sSongDir.c_str(), GetCacheFilePath().c_str() );
|
// LOG->Trace( "Loading '%s' from cache file '%s'.", m_sSongDir.c_str(), GetCacheFilePath().c_str() );
|
||||||
SSCLoader::LoadFromSSCFile( sCacheFilePath, *this, true );
|
bool bLoadedFromSSC = SSCLoader::LoadFromSSCFile( sCacheFilePath, *this, true );
|
||||||
|
if( bLoadedFromSSC )
|
||||||
SSCLoader::TidyUpData( *this, true );
|
SSCLoader::TidyUpData( *this, true );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// load from .sm
|
||||||
|
SMLoader::LoadFromSMFile( sCacheFilePath, *this, true );
|
||||||
|
SMLoader::TidyUpData( *this, true );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -738,26 +745,37 @@ void Song::TidyUpData()
|
|||||||
* filename, and should always be the title of the song (unlike KSFs). */
|
* filename, and should always be the title of the song (unlike KSFs). */
|
||||||
m_sSongFileName = m_sSongDir;
|
m_sSongFileName = m_sSongDir;
|
||||||
vector<RString> asFileNames;
|
vector<RString> asFileNames;
|
||||||
|
do
|
||||||
|
{
|
||||||
GetDirListing( m_sSongDir+"*.ssc", asFileNames );
|
GetDirListing( m_sSongDir+"*.ssc", asFileNames );
|
||||||
if( !asFileNames.empty() )
|
if( !asFileNames.empty() )
|
||||||
{
|
{
|
||||||
m_sSongFileName += asFileNames[0];
|
m_sSongFileName += asFileNames[0];
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
GetDirListing( m_sSongDir+"*.sma", asFileNames );
|
||||||
|
if (!asFileNames.empty() )
|
||||||
{
|
{
|
||||||
|
m_sSongFileName += SetExtension( asFileNames[0], "ssc" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
GetDirListing( m_sSongDir+"*.sm", asFileNames );
|
GetDirListing( m_sSongDir+"*.sm", asFileNames );
|
||||||
if( !asFileNames.empty() )
|
if( !asFileNames.empty() )
|
||||||
|
{
|
||||||
m_sSongFileName += SetExtension( asFileNames[0], "ssc" );
|
m_sSongFileName += SetExtension( asFileNames[0], "ssc" );
|
||||||
else {
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
GetDirListing( m_sSongDir+"*.dwi", asFileNames );
|
GetDirListing( m_sSongDir+"*.dwi", asFileNames );
|
||||||
if( !asFileNames.empty() ) {
|
if( !asFileNames.empty() ) {
|
||||||
m_sSongFileName += SetExtension( asFileNames[0], "ssc" );
|
m_sSongFileName += SetExtension( asFileNames[0], "ssc" );
|
||||||
} else {
|
break;
|
||||||
|
}
|
||||||
m_sSongFileName += Basename(m_sSongDir);
|
m_sSongFileName += Basename(m_sSongDir);
|
||||||
m_sSongFileName += ".ssc";
|
m_sSongFileName += ".ssc";
|
||||||
}
|
} while(0);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no time signature specified, assume 4/4 time for the whole song.
|
// If no time signature specified, assume 4/4 time for the whole song.
|
||||||
|
|||||||
+6
-6
@@ -193,13 +193,13 @@ void SongManager::AddGroup( RString sDir, RString sGroupDirName )
|
|||||||
* TODO: Once the files are implemented in Song, bring the extensions
|
* TODO: Once the files are implemented in Song, bring the extensions
|
||||||
* from there into here. -aj */
|
* from there into here. -aj */
|
||||||
// Group background
|
// Group background
|
||||||
/*
|
|
||||||
vector<RString> arrayGroupBackgrounds;
|
|
||||||
GetDirListing( sDir+sGroupDirName+"/*-bg.png", arrayGroupBanners );
|
|
||||||
GetDirListing( sDir+sGroupDirName+"/*-bg.jpg", arrayGroupBanners );
|
|
||||||
GetDirListing( sDir+sGroupDirName+"/*-bg.gif", arrayGroupBanners );
|
|
||||||
GetDirListing( sDir+sGroupDirName+"/*-bg.bmp", arrayGroupBanners );
|
|
||||||
|
|
||||||
|
//vector<RString> arrayGroupBackgrounds;
|
||||||
|
//GetDirListing( sDir+sGroupDirName+"/*-bg.png", arrayGroupBanners );
|
||||||
|
//GetDirListing( sDir+sGroupDirName+"/*-bg.jpg", arrayGroupBanners );
|
||||||
|
//GetDirListing( sDir+sGroupDirName+"/*-bg.gif", arrayGroupBanners );
|
||||||
|
//GetDirListing( sDir+sGroupDirName+"/*-bg.bmp", arrayGroupBanners );
|
||||||
|
/*
|
||||||
RString sBackgroundPath;
|
RString sBackgroundPath;
|
||||||
if( !arrayGroupBackgrounds.empty() )
|
if( !arrayGroupBackgrounds.empty() )
|
||||||
sBackgroundPath = sDir+sGroupDirName+"/"+arrayGroupBackgrounds[0];
|
sBackgroundPath = sDir+sGroupDirName+"/"+arrayGroupBackgrounds[0];
|
||||||
|
|||||||
+6
-6
@@ -22,10 +22,10 @@ public:
|
|||||||
};
|
};
|
||||||
DrainType m_DrainType; // only used with LifeBar
|
DrainType m_DrainType; // only used with LifeBar
|
||||||
int m_iBatteryLives;
|
int m_iBatteryLives;
|
||||||
float m_fMusicRate, m_SpeedfMusicRate;
|
|
||||||
float m_fHaste, m_SpeedfHaste;
|
|
||||||
bool m_bAssistClap;
|
bool m_bAssistClap;
|
||||||
bool m_bAssistMetronome;
|
bool m_bAssistMetronome;
|
||||||
|
float m_fMusicRate, m_SpeedfMusicRate;
|
||||||
|
float m_fHaste, m_SpeedfHaste;
|
||||||
enum AutosyncType {
|
enum AutosyncType {
|
||||||
AUTOSYNC_OFF,
|
AUTOSYNC_OFF,
|
||||||
AUTOSYNC_SONG,
|
AUTOSYNC_SONG,
|
||||||
@@ -34,10 +34,6 @@ public:
|
|||||||
NUM_AUTOSYNC_TYPES
|
NUM_AUTOSYNC_TYPES
|
||||||
};
|
};
|
||||||
AutosyncType m_AutosyncType;
|
AutosyncType m_AutosyncType;
|
||||||
bool m_bStaticBackground;
|
|
||||||
bool m_bRandomBGOnly;
|
|
||||||
bool m_bSaveScore;
|
|
||||||
bool m_bSaveReplay;
|
|
||||||
enum SoundEffectType {
|
enum SoundEffectType {
|
||||||
SOUNDEFFECT_OFF,
|
SOUNDEFFECT_OFF,
|
||||||
SOUNDEFFECT_SPEED,
|
SOUNDEFFECT_SPEED,
|
||||||
@@ -45,6 +41,10 @@ public:
|
|||||||
NUM_SOUNDEFFECT
|
NUM_SOUNDEFFECT
|
||||||
};
|
};
|
||||||
SoundEffectType m_SoundEffectType;
|
SoundEffectType m_SoundEffectType;
|
||||||
|
bool m_bStaticBackground;
|
||||||
|
bool m_bRandomBGOnly;
|
||||||
|
bool m_bSaveScore;
|
||||||
|
bool m_bSaveReplay;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set up the SongOptions with reasonable defaults.
|
* @brief Set up the SongOptions with reasonable defaults.
|
||||||
|
|||||||
+307
-301
File diff suppressed because it is too large
Load Diff
+379
-373
File diff suppressed because it is too large
Load Diff
+758
-714
File diff suppressed because it is too large
Load Diff
+21
-23
@@ -469,7 +469,6 @@ struct VideoCardDefaults
|
|||||||
}
|
}
|
||||||
} const g_VideoCardDefaults[] =
|
} const g_VideoCardDefaults[] =
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
VideoCardDefaults(
|
VideoCardDefaults(
|
||||||
"Xbox",
|
"Xbox",
|
||||||
"d3d",
|
"d3d",
|
||||||
@@ -478,10 +477,9 @@ struct VideoCardDefaults
|
|||||||
2048,
|
2048,
|
||||||
true
|
true
|
||||||
),
|
),
|
||||||
*/
|
|
||||||
VideoCardDefaults(
|
VideoCardDefaults(
|
||||||
"Voodoo *5",
|
"Voodoo *5",
|
||||||
"opengl", // received 3 reports of opengl crashing. -Chris
|
"d3d,opengl", // received 3 reports of opengl crashing. -Chris
|
||||||
640,480,
|
640,480,
|
||||||
32,32,32,
|
32,32,32,
|
||||||
2048,
|
2048,
|
||||||
@@ -489,7 +487,7 @@ struct VideoCardDefaults
|
|||||||
),
|
),
|
||||||
VideoCardDefaults(
|
VideoCardDefaults(
|
||||||
"Voodoo|3dfx", // all other Voodoos: some drivers don't identify which one
|
"Voodoo|3dfx", // all other Voodoos: some drivers don't identify which one
|
||||||
"opengl",
|
"d3d,opengl",
|
||||||
640,480,
|
640,480,
|
||||||
16,16,16,
|
16,16,16,
|
||||||
256,
|
256,
|
||||||
@@ -497,7 +495,7 @@ struct VideoCardDefaults
|
|||||||
),
|
),
|
||||||
VideoCardDefaults(
|
VideoCardDefaults(
|
||||||
"Radeon.* 7|Wonder 7500|ArcadeVGA", // Radeon 7xxx, RADEON Mobility 7500
|
"Radeon.* 7|Wonder 7500|ArcadeVGA", // Radeon 7xxx, RADEON Mobility 7500
|
||||||
"opengl", // movie texture performance is terrible in OpenGL, but fine in D3D.
|
"d3d,opengl", // movie texture performance is terrible in OpenGL, but fine in D3D.
|
||||||
640,480,
|
640,480,
|
||||||
16,16,16,
|
16,16,16,
|
||||||
2048,
|
2048,
|
||||||
@@ -505,7 +503,7 @@ struct VideoCardDefaults
|
|||||||
),
|
),
|
||||||
VideoCardDefaults(
|
VideoCardDefaults(
|
||||||
"GeForce|Radeon|Wonder 9|Quadro",
|
"GeForce|Radeon|Wonder 9|Quadro",
|
||||||
"opengl",
|
"opengl,d3d",
|
||||||
640,480,
|
640,480,
|
||||||
32,32,32, // 32 bit textures are faster to load
|
32,32,32, // 32 bit textures are faster to load
|
||||||
2048,
|
2048,
|
||||||
@@ -513,7 +511,7 @@ struct VideoCardDefaults
|
|||||||
),
|
),
|
||||||
VideoCardDefaults(
|
VideoCardDefaults(
|
||||||
"TNT|Vanta|M64",
|
"TNT|Vanta|M64",
|
||||||
"opengl",
|
"opengl,d3d",
|
||||||
640,480,
|
640,480,
|
||||||
16,16,16, // Athlon 1.2+TNT demonstration w/ movies: 70fps w/ 32bit textures, 86fps w/ 16bit textures
|
16,16,16, // Athlon 1.2+TNT demonstration w/ movies: 70fps w/ 32bit textures, 86fps w/ 16bit textures
|
||||||
2048,
|
2048,
|
||||||
@@ -521,13 +519,12 @@ struct VideoCardDefaults
|
|||||||
),
|
),
|
||||||
VideoCardDefaults(
|
VideoCardDefaults(
|
||||||
"G200|G250|G400",
|
"G200|G250|G400",
|
||||||
"opengl",
|
"d3d,opengl",
|
||||||
640,480,
|
640,480,
|
||||||
16,16,16,
|
16,16,16,
|
||||||
2048,
|
2048,
|
||||||
false // broken, causes black screen
|
false // broken, causes black screen
|
||||||
),
|
),
|
||||||
/*
|
|
||||||
VideoCardDefaults(
|
VideoCardDefaults(
|
||||||
"Savage",
|
"Savage",
|
||||||
"d3d",
|
"d3d",
|
||||||
@@ -551,10 +548,9 @@ struct VideoCardDefaults
|
|||||||
256,
|
256,
|
||||||
false
|
false
|
||||||
),
|
),
|
||||||
*/
|
|
||||||
VideoCardDefaults(
|
VideoCardDefaults(
|
||||||
"RAGE MOBILITY-M1",
|
"RAGE MOBILITY-M1",
|
||||||
"opengl", // Vertex alpha is broken in OpenGL, but not D3D. -Chris
|
"d3d,opengl", // Vertex alpha is broken in OpenGL, but not D3D. -Chris
|
||||||
400,300, // lower resolution for 60fps
|
400,300, // lower resolution for 60fps
|
||||||
16,16,16,
|
16,16,16,
|
||||||
256,
|
256,
|
||||||
@@ -562,7 +558,7 @@ struct VideoCardDefaults
|
|||||||
),
|
),
|
||||||
VideoCardDefaults(
|
VideoCardDefaults(
|
||||||
"Mobility M3", // ATI Rage Mobility 128 (AKA "M3")
|
"Mobility M3", // ATI Rage Mobility 128 (AKA "M3")
|
||||||
"opengl", // bad movie texture performance in opengl
|
"d3d,opengl", // bad movie texture performance in opengl
|
||||||
640,480,
|
640,480,
|
||||||
16,16,16,
|
16,16,16,
|
||||||
1024,
|
1024,
|
||||||
@@ -570,7 +566,7 @@ struct VideoCardDefaults
|
|||||||
),
|
),
|
||||||
VideoCardDefaults(
|
VideoCardDefaults(
|
||||||
"Intel.*82810|Intel.*82815",
|
"Intel.*82810|Intel.*82815",
|
||||||
"opengl",// OpenGL is 50%+ faster than D3D w/ latest Intel drivers. -Chris
|
"opengl,d3d",// OpenGL is 50%+ faster than D3D w/ latest Intel drivers. -Chris
|
||||||
512,384, // lower resolution for 60fps
|
512,384, // lower resolution for 60fps
|
||||||
16,16,16,
|
16,16,16,
|
||||||
512,
|
512,
|
||||||
@@ -578,15 +574,15 @@ struct VideoCardDefaults
|
|||||||
),
|
),
|
||||||
VideoCardDefaults(
|
VideoCardDefaults(
|
||||||
"Intel*Extreme Graphics",
|
"Intel*Extreme Graphics",
|
||||||
"opengl", // OpenGL blue screens w/ XP drivers from 6-21-2002
|
"d3d", // OpenGL blue screens w/ XP drivers from 6-21-2002
|
||||||
640,480,
|
640,480,
|
||||||
16,16,16, // slow at 32bpp
|
16,16,16, // slow at 32bpp
|
||||||
1024,
|
1024,
|
||||||
false
|
false
|
||||||
),
|
),
|
||||||
VideoCardDefaults(
|
VideoCardDefaults(
|
||||||
"Intel.*", /* fallback: all unknown Intel cards to since Intel is notoriously bad at OpenGL */
|
"Intel.*", /* fallback: all unknown Intel cards to D3D, since Intel is notoriously bad at OpenGL */
|
||||||
"opengl",
|
"d3d,opengl",
|
||||||
640,480,
|
640,480,
|
||||||
16,16,16,
|
16,16,16,
|
||||||
2048,
|
2048,
|
||||||
@@ -599,17 +595,17 @@ struct VideoCardDefaults
|
|||||||
// bug 764830: ASSERT fail after glDeleteTextures for "VIA Tech VT8361/VT8601 Graphics Controller"
|
// bug 764830: ASSERT fail after glDeleteTextures for "VIA Tech VT8361/VT8601 Graphics Controller"
|
||||||
// bug 791950: AV in glsis630!DrvSwapBuffers for "SiS 630/730"
|
// bug 791950: AV in glsis630!DrvSwapBuffers for "SiS 630/730"
|
||||||
"Trident Video Accelerator CyberBlade|VIA.*VT|SiS 6*",
|
"Trident Video Accelerator CyberBlade|VIA.*VT|SiS 6*",
|
||||||
"opengl",
|
"d3d,opengl",
|
||||||
640,480,
|
640,480,
|
||||||
16,16,16,
|
16,16,16,
|
||||||
2048,
|
2048,
|
||||||
false
|
false
|
||||||
),
|
),
|
||||||
VideoCardDefaults(
|
VideoCardDefaults(
|
||||||
/* Unconfirmed texture problems on this; let's try since it's
|
/* Unconfirmed texture problems on this; let's try D3D, since it's
|
||||||
* a VIA/S3 chipset. */
|
* a VIA/S3 chipset. */
|
||||||
"VIA/S3G KM400/KN400",
|
"VIA/S3G KM400/KN400",
|
||||||
"opengl",
|
"d3d,opengl",
|
||||||
640,480,
|
640,480,
|
||||||
16,16,16,
|
16,16,16,
|
||||||
2048,
|
2048,
|
||||||
@@ -627,7 +623,7 @@ struct VideoCardDefaults
|
|||||||
// Default graphics settings used for all cards that don't match above.
|
// Default graphics settings used for all cards that don't match above.
|
||||||
// This must be the very last entry!
|
// This must be the very last entry!
|
||||||
"",
|
"",
|
||||||
"opengl",
|
"opengl,d3d",
|
||||||
640,480,
|
640,480,
|
||||||
32,32,32,
|
32,32,32,
|
||||||
2048,
|
2048,
|
||||||
@@ -771,9 +767,10 @@ RageDisplay *CreateDisplay()
|
|||||||
}
|
}
|
||||||
else if( sRenderer.CompareNoCase("d3d")==0 )
|
else if( sRenderer.CompareNoCase("d3d")==0 )
|
||||||
{
|
{
|
||||||
#if defined(SUPPORT_D3D)
|
// TODO: ANGLE/RageDisplay_Modern
|
||||||
pRet = new RageDisplay_D3D;
|
//#if defined(SUPPORT_D3D)
|
||||||
#endif
|
// pRet = new RageDisplay_D3D;
|
||||||
|
//#endif
|
||||||
}
|
}
|
||||||
else if( sRenderer.CompareNoCase("null")==0 )
|
else if( sRenderer.CompareNoCase("null")==0 )
|
||||||
{
|
{
|
||||||
@@ -1571,3 +1568,4 @@ void HandleInputEvents(float fDeltaTime)
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
>>>>>>> other
|
||||||
|
|||||||
+8
-2
@@ -21,6 +21,7 @@
|
|||||||
#include "GameManager.h"
|
#include "GameManager.h"
|
||||||
#include "NoteDataUtil.h"
|
#include "NoteDataUtil.h"
|
||||||
#include "NotesLoaderSSC.h"
|
#include "NotesLoaderSSC.h"
|
||||||
|
#include "NotesLoaderSM.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@@ -229,13 +230,18 @@ void Steps::Decompress() const
|
|||||||
|
|
||||||
if( !m_sFilename.empty() && m_sNoteDataCompressed.empty() )
|
if( !m_sFilename.empty() && m_sNoteDataCompressed.empty() )
|
||||||
{
|
{
|
||||||
/* We have data on disk and not in memory. Load it. */
|
// We have data on disk and not in memory. Load it.
|
||||||
Song s;
|
Song s;
|
||||||
if( !SSCLoader::LoadFromSSCFile(m_sFilename, s, true) )
|
bool bLoadedFromSSC = SSCLoader::LoadFromSSCFile(m_sFilename, s, true);
|
||||||
|
if( !bLoadedFromSSC )
|
||||||
|
{
|
||||||
|
// try reading from .sm instead
|
||||||
|
if( !SMLoader::LoadFromSMFile(m_sFilename, s, true) )
|
||||||
{
|
{
|
||||||
LOG->Warn( "Couldn't load \"%s\"", m_sFilename.c_str() );
|
LOG->Warn( "Couldn't load \"%s\"", m_sFilename.c_str() );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Find the steps. */
|
/* Find the steps. */
|
||||||
StepsID ID;
|
StepsID ID;
|
||||||
|
|||||||
+10
-11
@@ -117,26 +117,25 @@ void TimingData::SetTimeSignatureAtRow( int iRow, int iNumerator, int iDenominat
|
|||||||
if( m_vTimeSignatureSegments[i].m_iStartRow >= iRow)
|
if( m_vTimeSignatureSegments[i].m_iStartRow >= iRow)
|
||||||
break; // We found our segment.
|
break; // We found our segment.
|
||||||
}
|
}
|
||||||
TimeSignatureSegment &ts = m_vTimeSignatureSegments[i];
|
|
||||||
TimeSignatureSegment &prev = m_vTimeSignatureSegments[i-1];
|
if ( i == m_vTimeSignatureSegments.size() || m_vTimeSignatureSegments[i].m_iStartRow != iRow )
|
||||||
if( i == m_vTimeSignatureSegments.size() || ts.m_iStartRow != iRow )
|
|
||||||
{
|
{
|
||||||
// There is no TimeSignatureSegment at the specified beat.
|
// No specific segmeent here: place one if it differs.
|
||||||
// If the TimeSignatureSegment being set differs
|
if( i == 0 ||
|
||||||
// from the last TimeSignature, create a new TimeSignatureSegment.
|
( m_vTimeSignatureSegments[i-1].m_iNumerator != iNumerator
|
||||||
if( i == 0 || ( prev.m_iNumerator != iNumerator || prev.m_iDenominator != iDenominator ) )
|
|| m_vTimeSignatureSegments[i-1].m_iDenominator != iDenominator ) )
|
||||||
AddTimeSignatureSegment( TimeSignatureSegment(iRow, iNumerator, iDenominator) );
|
AddTimeSignatureSegment( TimeSignatureSegment(iRow, iNumerator, iDenominator) );
|
||||||
}
|
}
|
||||||
else // TimeSignatureSegment being modified is m_vTimeSignatureSegments[i]
|
else // TimeSignatureSegment being modified is m_vTimeSignatureSegments[i]
|
||||||
{
|
{
|
||||||
if( i > 0 && prev.m_iNumerator == iNumerator
|
if( i > 0 && m_vTimeSignatureSegments[i-1].m_iNumerator == iNumerator
|
||||||
&& prev.m_iDenominator == iDenominator )
|
&& m_vTimeSignatureSegments[i-1].m_iDenominator == iDenominator )
|
||||||
m_vTimeSignatureSegments.erase( m_vTimeSignatureSegments.begin()+i,
|
m_vTimeSignatureSegments.erase( m_vTimeSignatureSegments.begin()+i,
|
||||||
m_vTimeSignatureSegments.begin()+i+1 );
|
m_vTimeSignatureSegments.begin()+i+1 );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ts.m_iNumerator = iNumerator;
|
m_vTimeSignatureSegments[i].m_iNumerator = iNumerator;
|
||||||
ts.m_iDenominator = iDenominator;
|
m_vTimeSignatureSegments[i].m_iDenominator = iDenominator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -222,7 +222,7 @@ struct TimeSignatureSegment
|
|||||||
* @param n the numerator for the segment.
|
* @param n the numerator for the segment.
|
||||||
*/
|
*/
|
||||||
TimeSignatureSegment( int r, int n ): m_iStartRow(max(0, r)),
|
TimeSignatureSegment( int r, int n ): m_iStartRow(max(0, r)),
|
||||||
m_iNumerator(n), m_iDenominator(4) {}
|
m_iNumerator(max(1, n)), m_iDenominator(4) {}
|
||||||
/**
|
/**
|
||||||
* @brief Creates a Time Signature Segment at the given row with a supplied numerator & denominator.
|
* @brief Creates a Time Signature Segment at the given row with a supplied numerator & denominator.
|
||||||
* @param r the starting row of the segment.
|
* @param r the starting row of the segment.
|
||||||
@@ -230,7 +230,7 @@ struct TimeSignatureSegment
|
|||||||
* @param d the denonimator for the segment.
|
* @param d the denonimator for the segment.
|
||||||
*/
|
*/
|
||||||
TimeSignatureSegment( int r, int n, int d ): m_iStartRow(max(0, r)),
|
TimeSignatureSegment( int r, int n, int d ): m_iStartRow(max(0, r)),
|
||||||
m_iNumerator(n), m_iDenominator(d) {}
|
m_iNumerator(max(1, n)), m_iDenominator(max(1, d)) {}
|
||||||
/**
|
/**
|
||||||
* @brief The row in which the TimeSignatureSegment activates.
|
* @brief The row in which the TimeSignatureSegment activates.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -509,18 +509,21 @@ void InputHandler_DInput::UpdateBuffered( DIDevice &device, const RageTimer &tm
|
|||||||
switch(in.ofs)
|
switch(in.ofs)
|
||||||
{
|
{
|
||||||
case DIMOFS_X:
|
case DIMOFS_X:
|
||||||
up = MOUSE_X_LEFT; down = MOUSE_X_RIGHT;
|
|
||||||
INPUTFILTER->UpdateCursorLocation((float)cursorPos.x,(float)cursorPos.y);
|
INPUTFILTER->UpdateCursorLocation((float)cursorPos.x,(float)cursorPos.y);
|
||||||
break;
|
break;
|
||||||
case DIMOFS_Y:
|
case DIMOFS_Y:
|
||||||
up = MOUSE_Y_UP; down = MOUSE_Y_DOWN;
|
|
||||||
INPUTFILTER->UpdateCursorLocation((float)cursorPos.x,(float)cursorPos.y);
|
INPUTFILTER->UpdateCursorLocation((float)cursorPos.x,(float)cursorPos.y);
|
||||||
break;
|
break;
|
||||||
case DIMOFS_Z:
|
case DIMOFS_Z:
|
||||||
|
INPUTFILTER->UpdateMouseWheel(l);
|
||||||
|
{
|
||||||
up = MOUSE_WHEELUP; down = MOUSE_WHEELDOWN;
|
up = MOUSE_WHEELUP; down = MOUSE_WHEELDOWN;
|
||||||
l = SCALE( int(evtbuf[i].dwData), -120.0f, 120.0f, -1.0f, 1.0f );
|
l = SCALE( int(evtbuf[i].dwData), -120.0f, 120.0f, 1.0f, -1.0f );
|
||||||
ButtonPressed( DeviceInput(dev, up, max(-l,0), tm) );
|
DeviceInput diUp = DeviceInput(dev, up, max(-l,0), tm);
|
||||||
ButtonPressed( DeviceInput(dev, down, max(+l,0), tm) );
|
DeviceInput diDown = DeviceInput(dev, down, max(+l,0), tm);
|
||||||
|
ButtonPressed( diUp );
|
||||||
|
ButtonPressed( diDown );
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default: LOG->MapLog( "unknown input",
|
default: LOG->MapLog( "unknown input",
|
||||||
"Mouse '%s' is returning an unknown mouse offset [axis], %i",
|
"Mouse '%s' is returning an unknown mouse offset [axis], %i",
|
||||||
@@ -552,6 +555,7 @@ void InputHandler_DInput::UpdateBuffered( DIDevice &device, const RageTimer &tm
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case in.HAT:
|
case in.HAT:
|
||||||
{
|
{
|
||||||
const int pos = TranslatePOV( evtbuf[i].dwData );
|
const int pos = TranslatePOV( evtbuf[i].dwData );
|
||||||
|
|||||||
@@ -632,4 +632,3 @@ void LowLevelWindow_MacOSX::BeginConcurrentRendering()
|
|||||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -104,11 +104,11 @@ void MouseDevice::GetButtonPresses( vector<DeviceInput>& vPresses, IOHIDElementC
|
|||||||
const Mouse& m = m_Mouse;
|
const Mouse& m = m_Mouse;
|
||||||
if( m.x_axis == cookie )
|
if( m.x_axis == cookie )
|
||||||
{
|
{
|
||||||
// INPUTFILTER->UpdateCursorLocation(m.x_axis,m.y_axis);
|
// INPUTFILTER->UpdateCursorLocation(value,m.y_axis);
|
||||||
}
|
}
|
||||||
else if( m.y_axis == cookie )
|
else if( m.y_axis == cookie )
|
||||||
{
|
{
|
||||||
// INPUTFILTER->UpdateCursorLocation((float)m.x_axis,(float)m.y_axis);
|
// INPUTFILTER->UpdateCursorLocation(m.x_axis,value);
|
||||||
}
|
}
|
||||||
else if( m.z_axis == cookie )
|
else if( m.z_axis == cookie )
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user