diff --git a/.hgignore b/.hgignore
index 19d2885f36..c948c06fe5 100644
--- a/.hgignore
+++ b/.hgignore
@@ -64,6 +64,7 @@ lib*_link.a
Data/UserPrefs
Data/uPrefs
Data/GamePrefs/*.cfg
+Data/Static.ini
PBProject/Hardware.plist
Themes/pump
Themes/optical-release
diff --git a/Docs/Changelog_SSCformat.txt b/Docs/Changelog_SSCformat.txt
index 95b48cf7d7..e5bcf25049 100644
--- a/Docs/Changelog_SSCformat.txt
+++ b/Docs/Changelog_SSCformat.txt
@@ -9,6 +9,12 @@ change to JSON, but it is unsure if this will be done.
Implement .ssc at your own risk.
________________________________________________________________________________
+[v0.7] - theDtTvB, Wolfman2000
+* Split Timing officially implemented.
+* #SPEEDS tag for modified scroll speeds.
+* #FAKES tag for ignoring judgments within a range.
+* #WARPS modified so that second parameter is now relative to the start.
+
[v0.59] - Wolfman2000
* Typo fix: #RADARVALUES needed a semicolon at the end, not a colon.
diff --git a/Docs/Changelog_sm5.txt b/Docs/Changelog_sm5.txt
index b5c710aa47..8a3a998b7e 100644
--- a/Docs/Changelog_sm5.txt
+++ b/Docs/Changelog_sm5.txt
@@ -8,16 +8,30 @@ ________________________________________________________________________________
StepMania 5.0 $NEXT | 20110xyy
--------------------------------------------------------------------------------
+2011/05/17
+----------
+* [NotesWriterSM] Write out OpenITG compatible SM files from here on out.
+ This includes turning Warps into Negative Stops. For those that wanted
+ negative BPMs specifically, my apologies, but stops are easier on math.
+ [Wolfman2000]
+
2011/05/16
----------
* [ProfileManager] Added ProfileWasLoadedFromMemoryCard(PlayerNumber)
Lua binding. [AJ]
+* Added #FAKES to the SSC format. Similar to the fake arrows, these blocks
+ prevent all judgments within the range. [Wolfman2000]
+* Changed the syntax of #WARPS slightly. Now the second value is the relative
+ distance that is skipped, not the absolute value when you start hitting
+ arrows again. [Wolfman2000]
2011/05/15
----------
* [ScreenGameplay] Removed hardcoded commands for Debug (give up text) and
replace them with DebugStartOnCommand, DebugBackOnCommand, and
DebugTweenOffCommand. [AJ]
+* Added #SPEEDS to the SSC format. This multiplies your scrolling speed during
+ gameplay, not replaces it (see mod attacks for replacing). [Wolfman2000]
2011/05/14
----------
diff --git a/Docs/Luadoc/Lua.xml b/Docs/Luadoc/Lua.xml
index f41bb848cb..6aa9eda455 100644
--- a/Docs/Luadoc/Lua.xml
+++ b/Docs/Luadoc/Lua.xml
@@ -1349,6 +1349,7 @@
+
@@ -1405,6 +1406,8 @@
+
+
diff --git a/Docs/Luadoc/LuaDocumentation.xml b/Docs/Luadoc/LuaDocumentation.xml
index aa4e3c09fe..bf0978bca6 100644
--- a/Docs/Luadoc/LuaDocumentation.xml
+++ b/Docs/Luadoc/LuaDocumentation.xml
@@ -3367,6 +3367,9 @@
Returns the numerical difficulty of the Steps.
+
+ Returns true if the song has significant timing changes.
+
Returns the complete list of RadarValues for player pn. Use to grab a specific value.
@@ -3515,6 +3518,12 @@
Returns true if the TimingData contains warps.
+
+ Returns true if the TimingData contains fake segments.
+
+
+ Returns true if the TimingData contains speed scrolling changes.
+
diff --git a/Docs/SimfileFormats/ssc_msd5.txt b/Docs/SimfileFormats/ssc_msd5.txt
index d3b7d092c1..64bad9126e 100644
--- a/Docs/SimfileFormats/ssc_msd5.txt
+++ b/Docs/SimfileFormats/ssc_msd5.txt
@@ -16,9 +16,10 @@
#INSTRUMENTTRACK:;
#MUSICLENGTH:;
#OFFSET:;
+#BPMS:;
#STOPS:;
#DELAYS:;
-#BPMS:;
+#LABELS:;
#TIMESIGNATURES:;
#LASTBEATHINT:;
#SAMPLESTART:;
@@ -43,17 +44,24 @@
// information from #NOTES moved here
#STEPSTYPE:;
#DESCRIPTION:;
+#CHARTSTYLE:;
#DIFFICULTY:;
#METER:;
#RADARVALUES:;
#CREDIT:;
// steps-based timingdata
+#BPMS:;
#STOPS:;
#DELAYS:;
-#BPMS:;
#TIMESIGNATURES:;
-#LASTBEATHINT:;
+#TICKCOUNTS:;
+#COMBOS:;
+#SPEEDS:;
+#FAKES:;
+#LABELS:;
+#ATTACKS:; // Not yet in use.
+#OFFSET:;
// actual step data
-#NOTES:;
\ No newline at end of file
+#NOTES:;
diff --git a/NoteSkins/pump/default/UpLeft Receptor.lua b/NoteSkins/pump/default/UpLeft Receptor.lua
index 3380a0b8ff..f6738e3c27 100644
--- a/NoteSkins/pump/default/UpLeft Receptor.lua
+++ b/NoteSkins/pump/default/UpLeft Receptor.lua
@@ -6,7 +6,7 @@ local function Beat(self)
local part = beat%1
part = clamp(part,0,0.5)
local eff = scale(part,0,0.5,1,0)
- if (GAMESTATE:GetSongDelay() or false) and part == 0 then eff = 0 end
+ if (GAMESTATE:GetSongPosition:GetDelay() or false) and part == 0 then eff = 0 end
if beat < 0 then
eff = 0
end
diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini
index 89502509c8..818a5bb456 100644
--- a/Themes/_fallback/Languages/en.ini
+++ b/Themes/_fallback/Languages/en.ini
@@ -558,6 +558,7 @@ Baked Random=Baked Random
Bar=Bar
Battery=Battery
Beat=Beat
+Beats=Beats
Big=Big
Blind=Blind
Blink=Blink
@@ -694,6 +695,7 @@ Right=Right
Roll=Roll
Romanization=Transliterate
SHOW=Show
+Seconds=Seconds
Select=Select
Servers=Servers
Shift Left=Shift Left
@@ -845,15 +847,18 @@ Exit Edit Mode=Exit Edit Mode
Edit stop=Edit stop
Edit delay=Edit delay
Edit Timing Data=Edit Timing Data
-Edit time signature=Edit time signature (not working yet)
-Edit time signature (top)=Edit time signature (beats per measure)
-Edit time signature (bottom)=Edit time signature (single beat note value)
+Edit time signature=Edit time signature
Edit tickcount=Edit tickcount
Edit combo=Edit combo
Edit label=Edit label
Edit warp=Edit warp
+Edit speed (percent)=Edit speed (percent)
+Edit speed (wait)=Edit speed (length)
+Edit speed (mode)=Edit speed (mode)
+Edit fake=Edit fake segment
Editor options=Options
EditorShowBGChangesPlay=Show Backgrounds
+Erase step timing=Erase step timing
Effect=Effect
EnableAttackSounds=Attack Sounds
EnableMineHitSound=Mine Sounds
@@ -1217,15 +1222,19 @@ Can't undo - no undo data.=Can't undo - no undo data.
Do you want to revert from disk?=Do you want to revert from disk?
Do you want to revert to your last save?=Do you want to revert to your last save?
Do you want to save changes before exiting?=Do you want to save changes before exiting?
-Enter a new BPM value.=Enter a new BPM value.
-Enter a new Stop value.=Enter a new Stop value.
-Enter a new Delay value.=Enter a new Delay value.
-Enter a new Time Signature numerator value.=Enter the number of beats per measure.
-Enter a new Time Signature denominator value.=Enter the note value that represents one beat.
-Enter a new Tickcount value.=Enter a new Tickcount value.
-Enter a new Combo value.=Enter a new Combo value.
-Enter a new Label value.=Enter a name for this section of the chart.
-Enter a new Warp value.=Enter the beat you will warp to when you reach this point.
+Enter a new BPM value.=Enter a new BPM value.\n\nEnter the previous value to remove.
+Enter a new Stop value.=Enter a new Stop value.\n\nType "0" to remove.
+Enter a new Delay value.=Enter a new Delay value.\n\nType "0" to remove.
+Enter a new Time Signature.=Enter a new time signature.\nUse the format "x/y".\nEnter the previous value to remove.
+Enter a new Tickcount value.=Enter a new Tickcount value.\n\nEnter the previous value to remove.
+Enter a new Combo value.=Enter a new Combo value.\n\nEnter the previous value to remove.
+Enter a new Label value.=Enter a name for this section of the chart.\n\nEnter a previously used label to remove.
+Enter a new Warp value.=Enter the number of beats you will warp over.\n\nType "0" to remove this segment.
+Enter a new Speed percent value.=Enter the ratio for speed scrolling.\nEnter the previous value to remove.\n1 is the default scroll.
+Enter a new Speed wait value.=Enter how long in seconds/beats it takes to change.\n\n0 is instant.
+Enter a new Speed mode value.=Enter how this segment is handled.\n\nType "0" for beats, "1" for seconds.
+Enter a new Fake value.=Enter the number of beats that won't be judged.\n\nType "0" to remove this.
+Are you sure you want to erase this chart's timing data?=Are you sure you want to erase this chart's timing data?
Enter a new artist transliteration.=Enter a new artist transliteration.
Enter a new artist.=Enter a new artist.
Enter a new genre.=Enter a new genre.
@@ -1246,7 +1255,7 @@ Enter a new min BPM.=Enter the minimum displayed BPM.
Enter a new max BPM.=Enter the maximum displayed BPM.
More than %d notes per measure is not allowed. This change has been reverted.=More than %d notes per measure is not allowed. This change has been reverted.
No backgrounds available=No backgrounds available
-EditHelpText=Up/Down:\n change beat\nLeft/Right:\n change snap\nNumber keys:\n add/remove\n tap note\nCreate hold note:\n Hold a number\n while moving\n Up or Down\nCreate roll note:\n Hold Shift,\n then create a\n hold note.\nSpace bar:\n Set area\n marker\nEnter:\n Area Menu\nEscape:\n Main Menu\nF1:\n Show help\n
+EditHelpText=Up/Down:\n change beat\nLeft/Right:\n change snap\nNumber keys:\n add/remove\n tap note\nN and M keys:\n swap tap notes\nCreate hold note:\n Hold a number\n while moving\n Up or Down\nCreate roll note:\n Hold Shift,\n then create a\n hold note.\nSpace bar:\n Set area\n marker\nEnter:\n Area Menu\nEscape:\n Main Menu\nF4:\n Timing Menu\nF1:\n Show help\n
PlayRecordHelpText=Press START to end
Save successful.=Save successful.
Saved as SM and DWI.=Saved as SM and DWI.
@@ -1257,6 +1266,7 @@ This change creates more than %d notes in a measure.=This change creates more th
This change creates notes past the end of the music and is not allowed.=This change creates notes past the end of the music and is not allowed.
This will destroy all unsaved changes.=This will destroy all unsaved changes.
Undo=Undo
+You must be in Song Timing Mode to edit BG Changes.=You must be in Song Timing Mode to edit BG Changes.
Current beat=Current beat
Current second=Current second
@@ -1276,6 +1286,9 @@ Mines=Mines
Rolls=Rolls
Lifts=Lifts
Fakes=Fakes
+Timing Mode=Timing Mode
+Step Timing=Step Timing
+Song Timing=Song Timing
Beat 0 offset=Beat 0 offset
Preview Start=Preview Start
Preview Length=Preview Length
@@ -1944,7 +1957,7 @@ Decrease/increase music offset=Decrease/increase music offset
Decrease/increase sample music start=Decrease/increase sample music start
Decrease/increase sample music length=Decrease/increase sample music length
Play sample music=Play sample music
-Add/Edit Background Change=Add/Edit Background Change
+Add/Edit Background Change=Add/Edit Background Change (Song Timing Only)
Insert beat and shift down=Insert beat and shift down
Shift BPM changes and stops down one beat=Shift BPM changes and stops down one beat
Delete beat and shift up=Delete beat and shift up
@@ -1953,6 +1966,7 @@ Cycle between tap notes=Cycle between tap notes
Lay mine=Lay mine
Lay lift=Lay lift
Add to/remove from right half=Add to/remove from right half
+Switch Timing=Switch Timing
Switch player (Routine only)=Switch player (Routine only)
[Grade]
diff --git a/Themes/_fallback/Scripts/01 alias.lua b/Themes/_fallback/Scripts/01 alias.lua
index 05935425bf..126d9c69ef 100644
--- a/Themes/_fallback/Scripts/01 alias.lua
+++ b/Themes/_fallback/Scripts/01 alias.lua
@@ -20,4 +20,4 @@ local _screen = {
h = SCREEN_HEIGHT,
cx = SCREEN_CENTER_X,
cy = SCREEN_CENTER_Y
-}
\ No newline at end of file
+}
diff --git a/Themes/_fallback/Scripts/01 compat.lua b/Themes/_fallback/Scripts/01 compat.lua
index c2f171e1f0..dbdf4a819c 100644
--- a/Themes/_fallback/Scripts/01 compat.lua
+++ b/Themes/_fallback/Scripts/01 compat.lua
@@ -63,4 +63,14 @@ end
if ScreenMetric then
ScreenMetric = Screen.Metric
-end
\ No newline at end of file
+end
+
+--[[ GameState ]]
+--Aliases for old GAMESTATE timing functions.
+--These have been converted to SongPosition, but most themes still use these old functions.
+
+function GameState:GetSongBeat() return self:GetSongPosition():GetSongBeat() end
+function GameState:GetSongBeatNoOffset() return self:GetSongPosition():GetSongBeatNoOffset() end
+function GameState:GetSongBPS() return self:GetSongPosition():GetCurBPS() end
+function GameState:GetSongDelay() return self:GetSongPosition:GetDelay() end
+function GameState:GetSongFreeze() return self:GetSongPosition:GetFreeze() end
diff --git a/Themes/_fallback/Sounds/ScreenEdit switch player.redir b/Themes/_fallback/Sounds/ScreenEdit switch player.redir
new file mode 100644
index 0000000000..cd59d419fb
--- /dev/null
+++ b/Themes/_fallback/Sounds/ScreenEdit switch player.redir
@@ -0,0 +1 @@
+MusicWheel sort
diff --git a/Themes/_fallback/Sounds/ScreenEdit switch timing.redir b/Themes/_fallback/Sounds/ScreenEdit switch timing.redir
new file mode 100644
index 0000000000..cd59d419fb
--- /dev/null
+++ b/Themes/_fallback/Sounds/ScreenEdit switch timing.redir
@@ -0,0 +1 @@
+MusicWheel sort
diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini
index b80fa71588..c4dd4b0bd6 100644
--- a/Themes/_fallback/metrics.ini
+++ b/Themes/_fallback/metrics.ini
@@ -989,6 +989,8 @@ TimeSignatureColor=color("1,0.55,0,1")
TickcountColor=color("0,1,0,1")
ComboColor=color("0.55,1,0,1")
LabelColor=color("1,0,0,1")
+SpeedColor=color("0.5,1,1,1")
+FakeColor=color("1,1,0.5,1")
#
BPMIsLeftSide=true
StopIsLeftSide=true
@@ -998,15 +1000,19 @@ TimeSignatureIsLeftSide=true
TickcountIsLeftSide=false
ComboIsLeftSide=false
LabelIsLeftSide=false
+SpeedIsLeftSide=false
+FakeIsLeftSide=true
#
BPMOffsetX=60
StopOffsetX=50
DelayOffsetX=120
-WarpOffsetX=60
+WarpOffsetX=90
TimeSignatureOffsetX=30
-TickcountOffsetX=10
-ComboOffsetX=30
-LabelOffsetX=80
+TickcountOffsetX=70
+ComboOffsetX=50
+LabelOffsetX=130
+SpeedOffsetX=30
+FakeOffsetX=90
[PlayerStageStats]
# Original CVS Grading
@@ -3607,7 +3613,7 @@ TimerSeconds=-1
EditModifiers="no reverse"
EditHelpX=SCREEN_LEFT+4
EditHelpY=SCREEN_TOP+16
-EditHelpOnCommand=halign,0;valign,0;zoom,0.675;shadowlength,1
+EditHelpOnCommand=halign,0;valign,0;zoom,0.5;shadowlength,1
InfoX=SCREEN_RIGHT-128
InfoY=SCREEN_TOP+16
InfoOnCommand=halign,0;valign,0;zoom,0.5;shadowlength,1
@@ -3636,6 +3642,7 @@ NumHandsFormat="%s: %d\n"
NumRollsFormat="%s: %d\n"
NumLiftsFormat="%s: %d\n"
NumFakesFormat="%s: %d\n"
+TimingModeFormat="%s:\n %s\n"
Beat0OffsetFormat="%s:\n %.5f secs\n"
PreviewStartFormat="%s:\n %.5f secs\n"
PreviewLengthFormat="%s:\n %.5f secs\n"
diff --git a/Xcode/stepmania.xcodeproj/project.pbxproj b/Xcode/stepmania.xcodeproj/project.pbxproj
index b90859f4e1..f8a7209385 100644
--- a/Xcode/stepmania.xcodeproj/project.pbxproj
+++ b/Xcode/stepmania.xcodeproj/project.pbxproj
@@ -1657,6 +1657,8 @@
AAFF41A40F5BD4AD00FFDB67 /* ScreenOptionsExportPackage.h in Headers */ = {isa = PBXBuildFile; fileRef = AAFF41A20F5BD4AD00FFDB67 /* ScreenOptionsExportPackage.h */; };
AAFF41A50F5BD4AD00FFDB67 /* ScreenOptionsExportPackage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AAFF41A10F5BD4AD00FFDB67 /* ScreenOptionsExportPackage.cpp */; };
AAFF41A60F5BD4AD00FFDB67 /* ScreenOptionsExportPackage.h in Headers */ = {isa = PBXBuildFile; fileRef = AAFF41A20F5BD4AD00FFDB67 /* ScreenOptionsExportPackage.h */; };
+ B75CE3B5137963350076A82D /* SongPosition.h in Headers */ = {isa = PBXBuildFile; fileRef = B75CE3B3137963350076A82D /* SongPosition.h */; };
+ B75CE3B6137963350076A82D /* SongPosition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B75CE3B4137963350076A82D /* SongPosition.cpp */; };
EE2153A910A75BEE0074B01B /* NotesLoaderPMS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE2153A710A75BEE0074B01B /* NotesLoaderPMS.cpp */; };
EE2153AA10A75BEE0074B01B /* NotesLoaderPMS.h in Headers */ = {isa = PBXBuildFile; fileRef = EE2153A810A75BEE0074B01B /* NotesLoaderPMS.h */; };
EE879B60132DEE720078FDDC /* RageDisplay_Legacy_Helpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EE879B5C132DEE720078FDDC /* RageDisplay_Legacy_Helpers.cpp */; };
@@ -3025,6 +3027,8 @@
AAFF55220549F43A00D02EE9 /* ComboGraph.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = ComboGraph.h; path = ../src/ComboGraph.h; sourceTree = ""; };
AAFF5541054E736D00D02EE9 /* Attack.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; name = Attack.cpp; path = ../src/Attack.cpp; sourceTree = ""; };
AAFF5542054E736D00D02EE9 /* Attack.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; name = Attack.h; path = ../src/Attack.h; sourceTree = ""; };
+ B75CE3B3137963350076A82D /* SongPosition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SongPosition.h; path = ../src/SongPosition.h; sourceTree = SOURCE_ROOT; };
+ B75CE3B4137963350076A82D /* SongPosition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SongPosition.cpp; path = ../src/SongPosition.cpp; sourceTree = SOURCE_ROOT; };
EE2153A710A75BEE0074B01B /* NotesLoaderPMS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NotesLoaderPMS.cpp; path = ../src/NotesLoaderPMS.cpp; sourceTree = SOURCE_ROOT; };
EE2153A810A75BEE0074B01B /* NotesLoaderPMS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NotesLoaderPMS.h; path = ../src/NotesLoaderPMS.h; sourceTree = SOURCE_ROOT; };
EE879B5C132DEE720078FDDC /* RageDisplay_Legacy_Helpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RageDisplay_Legacy_Helpers.cpp; path = ../src/RageDisplay_Legacy_Helpers.cpp; sourceTree = SOURCE_ROOT; };
@@ -3938,6 +3942,8 @@
AA7CDD930D8395F90001DAFC /* Song.h */,
AA6EFE0704770C79005F316C /* SongOptions.cpp */,
AA6EFE0804770C79005F316C /* SongOptions.h */,
+ B75CE3B4137963350076A82D /* SongPosition.cpp */,
+ B75CE3B3137963350076A82D /* SongPosition.h */,
AA5C73F90637A5F000AFB891 /* SongUtil.cpp */,
AA5C73FA0637A5F000AFB891 /* SongUtil.h */,
AAEBF57C0B5C83F4005F3C7C /* SoundEffectControl.cpp */,
@@ -5056,6 +5062,7 @@
2BC6132D13773C8E00CC8BBD /* pngpriv.h in Headers */,
2BC6133313773C8E00CC8BBD /* pngstruct.h in Headers */,
2BC6133E13773D2C00CC8BBD /* pnglibconf.h in Headers */,
+ B75CE3B5137963350076A82D /* SongPosition.h in Headers */,
2B9C2E8E137A138B004C92F3 /* NotesLoaderJson.h in Headers */,
2B9C2E90137A138B004C92F3 /* NotesWriterJson.h in Headers */,
);
@@ -6317,6 +6324,7 @@
2BC6133813773C8E00CC8BBD /* pngwrite.c in Sources */,
2BC6133913773C8E00CC8BBD /* pngwtran.c in Sources */,
2BC6133A13773C8E00CC8BBD /* pngwutil.c in Sources */,
+ B75CE3B6137963350076A82D /* SongPosition.cpp in Sources */,
2B9C2E8D137A138B004C92F3 /* NotesLoaderJson.cpp in Sources */,
2B9C2E8F137A138B004C92F3 /* NotesWriterJson.cpp in Sources */,
);
diff --git a/src/Actor.cpp b/src/Actor.cpp
index 72a3ee3856..3191d98d56 100644
--- a/src/Actor.cpp
+++ b/src/Actor.cpp
@@ -34,6 +34,8 @@ REGISTER_ACTOR_CLASS_WITH_NAME( HiddenActor, Actor );
float Actor::g_fCurrentBGMTime = 0, Actor::g_fCurrentBGMBeat;
float Actor::g_fCurrentBGMTimeNoOffset = 0, Actor::g_fCurrentBGMBeatNoOffset = 0;
+vector Actor::g_vfCurrentBGMBeatPlayer(NUM_PlayerNumber, 0);
+vector Actor::g_vfCurrentBGMBeatPlayerNoOffset(NUM_PlayerNumber, 0);
Actor *Actor::Copy() const { return new Actor(*this); }
@@ -68,6 +70,12 @@ void Actor::SetBGMTime( float fTime, float fBeat, float fTimeNoOffset, float fBe
g_fCurrentBGMBeatNoOffset = fBeatNoOffset;
}
+void Actor::SetPlayerBGMBeat( PlayerNumber pn, float fBeat, float fBeatNoOffset )
+{
+ g_vfCurrentBGMBeatPlayer[pn] = fBeat;
+ g_vfCurrentBGMBeatPlayerNoOffset[pn] = fBeatNoOffset;
+}
+
void Actor::SetBGMLight( int iLightNumber, float fCabinetLights )
{
ASSERT( iLightNumber < NUM_CabinetLight );
@@ -150,8 +158,7 @@ Actor::Actor()
lua_setfield( L, -2, "ctx" );
lua_pop( L, 1 );
LUA->Release( L );
-
-
+
m_size = RageVector2( 1, 1 );
InitState();
m_pParent = NULL;
@@ -676,6 +683,16 @@ void Actor::UpdateInternal( float fDeltaTime )
m_fSecsIntoEffect = g_fCurrentBGMBeat;
break;
+ case CLOCK_BGM_BEAT_PLAYER1:
+ m_fEffectDelta = g_vfCurrentBGMBeatPlayer[PLAYER_1] - m_fSecsIntoEffect;
+ m_fSecsIntoEffect = g_vfCurrentBGMBeatPlayerNoOffset[PLAYER_1];
+ break;
+
+ case CLOCK_BGM_BEAT_PLAYER2:
+ m_fEffectDelta = g_vfCurrentBGMBeatPlayer[PLAYER_2] - m_fSecsIntoEffect;
+ m_fSecsIntoEffect = g_vfCurrentBGMBeatPlayerNoOffset[PLAYER_2];
+ break;
+
case CLOCK_BGM_TIME:
m_fEffectDelta = g_fCurrentBGMTime - m_fSecsIntoEffect;
m_fSecsIntoEffect = g_fCurrentBGMTime;
diff --git a/src/Actor.h b/src/Actor.h
index 45d080dabe..919d4994f7 100644
--- a/src/Actor.h
+++ b/src/Actor.h
@@ -1,6 +1,7 @@
#ifndef ACTOR_H
#define ACTOR_H
+#include "PlayerNumber.h"
#include "RageTypes.h"
#include "RageUtil_AutoPtr.h"
#include "LuaReference.h"
@@ -109,6 +110,7 @@ public:
virtual void LoadFromNode( const XNode* pNode );
static void SetBGMTime( float fTime, float fBeat, float fTimeNoOffset, float fBeatNoOffset );
+ static void SetPlayerBGMBeat( PlayerNumber pn, float fBeat, float fBeatNoOffset );
static void SetBGMLight( int iLightNumber, float fCabinetLights );
/**
@@ -131,6 +133,8 @@ public:
CLOCK_BGM_BEAT,
CLOCK_BGM_TIME_NO_OFFSET,
CLOCK_BGM_BEAT_NO_OFFSET,
+ CLOCK_BGM_BEAT_PLAYER1,
+ CLOCK_BGM_BEAT_PLAYER2,
CLOCK_LIGHT_1 = 1000,
CLOCK_LIGHT_LAST = 1100,
NUM_CLOCKS
@@ -713,6 +717,8 @@ protected:
// global state
static float g_fCurrentBGMTime, g_fCurrentBGMBeat;
static float g_fCurrentBGMTimeNoOffset, g_fCurrentBGMBeatNoOffset;
+ static vector g_vfCurrentBGMBeatPlayer;
+ static vector g_vfCurrentBGMBeatPlayerNoOffset;
private:
// commands
diff --git a/src/AdjustSync.cpp b/src/AdjustSync.cpp
index e669f9cb74..b375928a25 100644
--- a/src/AdjustSync.cpp
+++ b/src/AdjustSync.cpp
@@ -58,7 +58,7 @@ void AdjustSync::ResetOriginalSyncData()
s_pTimingDataOriginal = new TimingData;
if( GAMESTATE->m_pCurSong )
- *s_pTimingDataOriginal = GAMESTATE->m_pCurSong->m_Timing;
+ *s_pTimingDataOriginal = GAMESTATE->m_pCurSong->m_SongTiming;
else
*s_pTimingDataOriginal = TimingData();
s_fGlobalOffsetSecondsOriginal = PREFSMAN->m_fGlobalOffsetSeconds;
@@ -87,7 +87,7 @@ void AdjustSync::SaveSyncChanges()
{
if( GAMESTATE->IsCourseMode() )
return;
- if( GAMESTATE->m_pCurSong && *s_pTimingDataOriginal != GAMESTATE->m_pCurSong->m_Timing )
+ if( GAMESTATE->m_pCurSong && *s_pTimingDataOriginal != GAMESTATE->m_pCurSong->m_SongTiming )
{
if( GAMESTATE->IsEditing() )
{
@@ -110,7 +110,7 @@ void AdjustSync::RevertSyncChanges()
if( GAMESTATE->IsCourseMode() )
return;
PREFSMAN->m_fGlobalOffsetSeconds.Set( s_fGlobalOffsetSecondsOriginal );
- GAMESTATE->m_pCurSong->m_Timing = *s_pTimingDataOriginal;
+ GAMESTATE->m_pCurSong->m_SongTiming = *s_pTimingDataOriginal;
ResetOriginalSyncData();
s_fStandardDeviation = 0.0f;
s_fAverageError = 0.0f;
@@ -186,7 +186,7 @@ void AdjustSync::AutosyncOffset()
switch( GAMESTATE->m_SongOptions.GetCurrent().m_AutosyncType )
{
case SongOptions::AUTOSYNC_SONG:
- GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds += mean;
+ GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds += mean;
break;
case SongOptions::AUTOSYNC_MACHINE:
PREFSMAN->m_fGlobalOffsetSeconds.Set( PREFSMAN->m_fGlobalOffsetSeconds + mean );
@@ -232,15 +232,15 @@ void AdjustSync::AutosyncTempo()
if( !CalcLeastSquares( s_vAutosyncTempoData, fSlope, fIntercept, fFilteredError ) )
return;
- GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds += fIntercept;
+ GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds += fIntercept;
const float fScaleBPM = 1.0f/(1.0f - fSlope);
- FOREACH( BPMSegment, GAMESTATE->m_pCurSong->m_Timing.m_BPMSegments, i )
+ FOREACH( BPMSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_BPMSegments, i )
i->SetBPM( i->GetBPM() * fScaleBPM );
// We assume that the stops were measured as a number of beats.
// Therefore, if we change the bpms, we need to make a similar
// change to the stops.
- FOREACH( StopSegment, GAMESTATE->m_pCurSong->m_Timing.m_StopSegments, i )
+ FOREACH( StopSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_StopSegments, i )
i->m_fStopSeconds *= 1.0f - fSlope;
SCREENMAN->SystemMessage( AUTOSYNC_CORRECTION_APPLIED.GetValue() );
@@ -296,7 +296,7 @@ void AdjustSync::GetSyncChangeTextSong( vector &vsAddTo )
{
float fOld = Quantize( AdjustSync::s_pTimingDataOriginal->m_fBeat0OffsetInSeconds, 0.001f );
- float fNew = Quantize( GAMESTATE->m_pCurSong->m_Timing.m_fBeat0OffsetInSeconds, 0.001f );
+ float fNew = Quantize( GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds, 0.001f );
float fDelta = fNew - fOld;
if( fabsf(fDelta) > 0.0001f )
@@ -309,10 +309,10 @@ void AdjustSync::GetSyncChangeTextSong( vector &vsAddTo )
}
}
- for( unsigned i=0; im_pCurSong->m_Timing.m_BPMSegments.size(); i++ )
+ for( unsigned i=0; im_pCurSong->m_SongTiming.m_BPMSegments.size(); i++ )
{
float fOld = Quantize( AdjustSync::s_pTimingDataOriginal->m_BPMSegments[i].GetBPM(), 0.001f );
- float fNew = Quantize( GAMESTATE->m_pCurSong->m_Timing.m_BPMSegments[i].GetBPM(), 0.001f );
+ float fNew = Quantize( GAMESTATE->m_pCurSong->m_SongTiming.m_BPMSegments[i].GetBPM(), 0.001f );
float fDelta = fNew - fOld;
if( fabsf(fDelta) > 0.0001f )
@@ -330,10 +330,10 @@ void AdjustSync::GetSyncChangeTextSong( vector &vsAddTo )
}
}
- for( unsigned i=0; im_pCurSong->m_Timing.m_StopSegments.size(); i++ )
+ for( unsigned i=0; im_pCurSong->m_SongTiming.m_StopSegments.size(); i++ )
{
float fOld = Quantize( AdjustSync::s_pTimingDataOriginal->m_StopSegments[i].m_fStopSeconds, 0.001f );
- float fNew = Quantize( GAMESTATE->m_pCurSong->m_Timing.m_StopSegments[i].m_fStopSeconds, 0.001f );
+ float fNew = Quantize( GAMESTATE->m_pCurSong->m_SongTiming.m_StopSegments[i].m_fStopSeconds, 0.001f );
float fDelta = fNew - fOld;
if( fabsf(fDelta) > 0.0001f )
diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp
index 7df7a37015..e408967789 100644
--- a/src/ArrowEffects.cpp
+++ b/src/ArrowEffects.cpp
@@ -67,13 +67,13 @@ static float GetNoteFieldHeight( const PlayerState* pPlayerState )
namespace
{
- float g_fExpandSeconds = 0;
struct PerPlayerData
{
float m_fMinTornadoX[MAX_COLS_PER_PLAYER];
float m_fMaxTornadoX[MAX_COLS_PER_PLAYER];
float m_fInvertDistance[MAX_COLS_PER_PLAYER];
float m_fBeatFactor;
+ float m_fExpandSeconds;
};
PerPlayerData g_EffectData[NUM_PLAYERS];
};
@@ -82,22 +82,25 @@ void ArrowEffects::Update()
{
const Style* pStyle = GAMESTATE->GetCurrentStyle();
- {
- static float fLastTime = 0;
- float fTime = RageTimer::GetTimeSinceStartFast();
- if( !GAMESTATE->m_bFreeze || !GAMESTATE->m_bDelay )
- {
- g_fExpandSeconds += fTime - fLastTime;
- g_fExpandSeconds = fmodf( g_fExpandSeconds, PI*2 );
- }
- fLastTime = fTime;
- }
-
FOREACH_PlayerNumber( pn )
{
const Style::ColumnInfo* pCols = pStyle->m_ColumnInfo[pn];
+ const SongPosition &position = GAMESTATE->m_bIsUsingStepTiming
+ ? GAMESTATE->m_pPlayerState[pn]->m_Position : GAMESTATE->m_Position;
PerPlayerData &data = g_EffectData[pn];
+
+ {
+ static float fLastTime = 0;
+ float fTime = RageTimer::GetTimeSinceStartFast();
+ if( !position.m_bFreeze || !position.m_bDelay )
+ {
+ data.m_fExpandSeconds += fTime - fLastTime;
+ data.m_fExpandSeconds = fmodf( data.m_fExpandSeconds, PI*2 );
+ }
+ fLastTime = fTime;
+ }
+
// Update Tornado
for( int iColNum = 0; iColNum < MAX_COLS_PER_PLAYER; ++iColNum )
{
@@ -176,7 +179,7 @@ void ArrowEffects::Update()
// Update Beat
do {
float fAccelTime = 0.2f, fTotalTime = 0.5f;
- float fBeat = GAMESTATE->m_fSongBeatVisible + fAccelTime;
+ float fBeat = position.m_fSongBeatVisible + fAccelTime;
const bool bEvenBeat = ( int(fBeat) % 2 ) != 0;
@@ -208,6 +211,50 @@ void ArrowEffects::Update()
}
}
+float GetSpeedMultiplier( float fSongBeat, float fMusicSeconds, const TimingData &tim )
+{
+ if( tim.m_SpeedSegments.size() == 0 )
+ return 1.0;
+
+ const int index = tim.GetSpeedSegmentIndexAtBeat( fSongBeat );
+
+ const SpeedSegment &seg = tim.m_SpeedSegments[index];
+ float fStartBeat = NoteRowToBeat(seg.m_iStartRow);
+ float fStartTime = tim.GetElapsedTimeFromBeat( fStartBeat ) - tim.GetDelayAtBeat( fStartBeat );
+ float fEndTime;
+ float fCurTime = fMusicSeconds;
+
+ if( seg.m_usMode == 1 ) // seconds
+ {
+ fEndTime = fStartTime + seg.m_fWait;
+ }
+ else
+ {
+ fEndTime = tim.GetElapsedTimeFromBeat( fStartBeat + seg.m_fWait ) - tim.GetDelayAtBeat( fStartBeat + seg.m_fWait );
+ }
+
+ if( ( index == 0 && tim.m_SpeedSegments[0].m_fWait > 0.0 ) && fCurTime < fStartTime )
+ {
+ return 1.0;
+ }
+ else if( fEndTime >= fCurTime && ( index > 0 || tim.m_SpeedSegments[0].m_fWait > 0.0 ) )
+ {
+ const float fPriorSpeed = ( index == 0 ? 1 : tim.m_SpeedSegments[index - 1].m_fPercent );
+ float fTimeUsed = fCurTime - fStartTime;
+ float fDuration = fEndTime - fStartTime;
+ float fRatioUsed = fDuration == 0.0 ? 1 : fTimeUsed / fDuration;
+
+ float fDistance = fPriorSpeed - seg.m_fPercent;
+ float fRatioNeed = fRatioUsed * -fDistance;
+ return (fPriorSpeed + fRatioNeed);
+ }
+ else
+ {
+ return seg.m_fPercent;
+ }
+
+}
+
/* For visibility testing: if bAbsolute is false, random modifiers must return
* the minimum possible scroll speed. */
float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float fNoteBeat, float &fPeakYOffsetOut, bool &bIsPastPeakOut, bool bAbsolute )
@@ -217,21 +264,27 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
bIsPastPeakOut = true;
float fYOffset = 0;
+ const SongPosition &position = GAMESTATE->m_bIsUsingStepTiming
+ ? pPlayerState->m_Position : GAMESTATE->m_Position;
+
+ float fSongBeat = position.m_fSongBeatVisible;
+
+ Steps *pCurSteps = GAMESTATE->m_pCurSteps[pPlayerState->m_PlayerNumber];
/* Usually, fTimeSpacing is 0 or 1, in which case we use entirely beat spacing or
* entirely time spacing (respectively). Occasionally, we tween between them. */
if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 1.0f )
{
- float fSongBeat = GAMESTATE->m_fSongBeatVisible;
float fBeatsUntilStep = fNoteBeat - fSongBeat;
float fYOffsetBeatSpacing = fBeatsUntilStep;
- fYOffset += fYOffsetBeatSpacing * (1-pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing);
+ float fSpeedMultiplier = ( GAMESTATE->m_bInStepEditor || !GAMESTATE->m_bIsUsingStepTiming ) ? 1.0 : GetSpeedMultiplier( position.m_fSongBeatVisible, position.m_fMusicSecondsVisible, pCurSteps->m_Timing );
+ fYOffset += fSpeedMultiplier * fYOffsetBeatSpacing * (1-pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing);
}
if( pPlayerState->m_PlayerOptions.GetCurrent().m_fTimeSpacing != 0.0f )
{
- float fSongSeconds = GAMESTATE->m_fMusicSecondsVisible;
- float fNoteSeconds = GAMESTATE->m_pCurSong->GetElapsedTimeFromBeat(fNoteBeat);
+ float fSongSeconds = GAMESTATE->m_Position.m_fMusicSecondsVisible;
+ float fNoteSeconds = pCurSteps->m_Timing.GetElapsedTimeFromBeat(fNoteBeat);
float fSecondsUntilStep = fNoteSeconds - fSongSeconds;
float fBPM = pPlayerState->m_PlayerOptions.GetCurrent().m_fScrollBPM;
float fBPS = fBPM/60.f;
@@ -242,7 +295,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
// TODO: If we allow noteskins to have metricable row spacing
// (per issue 24), edit this to reflect that. -aj
fYOffset *= ARROW_SPACING;
-
+
// don't mess with the arrows after they've crossed 0
if( fYOffset < 0 )
return fYOffset * pPlayerState->m_PlayerOptions.GetCurrent().m_fScrollSpeed;
@@ -288,6 +341,7 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
// Factor in scroll speed
float fScrollSpeed = pPlayerState->m_PlayerOptions.GetCurrent().m_fScrollSpeed;
+
if( pPlayerState->m_PlayerOptions.GetCurrent().m_fRandomSpeed > 0 && !bAbsolute )
{
// Generate a deterministically "random" speed for each arrow.
@@ -307,7 +361,10 @@ float ArrowEffects::GetYOffset( const PlayerState* pPlayerState, int iCol, float
if( fAccels[PlayerOptions::ACCEL_EXPAND] != 0 )
{
- float fExpandMultiplier = SCALE( RageFastCos(g_fExpandSeconds*EXPAND_MULTIPLIER_FREQUENCY),
+ // TODO: Don't index by PlayerNumber.
+ PerPlayerData &data = g_EffectData[pPlayerState->m_PlayerNumber];
+
+ float fExpandMultiplier = SCALE( RageFastCos(data.m_fExpandSeconds*EXPAND_MULTIPLIER_FREQUENCY),
EXPAND_MULTIPLIER_SCALE_FROM_LOW, EXPAND_MULTIPLIER_SCALE_FROM_HIGH,
EXPAND_MULTIPLIER_SCALE_TO_LOW, EXPAND_MULTIPLIER_SCALE_TO_HIGH );
fScrollSpeed *= SCALE( fAccels[PlayerOptions::ACCEL_EXPAND],
@@ -511,7 +568,7 @@ float ArrowEffects::GetRotationZ( const PlayerState* pPlayerState, float fNoteBe
// As usual, enable dizzy hold heads at your own risk. -Wolfman2000
if( fEffects[PlayerOptions::EFFECT_DIZZY] != 0 && ( DIZZY_HOLD_HEADS || !bIsHoldHead ) )
{
- const float fSongBeat = GAMESTATE->m_fSongBeatVisible;
+ const float fSongBeat = pPlayerState->m_Position.m_fSongBeatVisible;
float fDizzyRotation = fNoteBeat - fSongBeat;
fDizzyRotation *= fEffects[PlayerOptions::EFFECT_DIZZY];
fDizzyRotation = fmodf( fDizzyRotation, 2*PI );
@@ -528,7 +585,7 @@ float ArrowEffects::ReceptorGetRotationZ( const PlayerState* pPlayerState )
if( fEffects[PlayerOptions::EFFECT_CONFUSION] != 0 )
{
- float fConfRotation = GAMESTATE->m_fSongBeatVisible;
+ float fConfRotation = pPlayerState->m_Position.m_fSongBeatVisible;
fConfRotation *= fEffects[PlayerOptions::EFFECT_CONFUSION];
fConfRotation = fmodf( fConfRotation, 2*PI );
fConfRotation *= -180/PI;
@@ -680,7 +737,7 @@ float ArrowEffects::GetBrightness( const PlayerState* pPlayerState, float fNoteB
if( GAMESTATE->IsEditing() )
return 1;
- float fSongBeat = GAMESTATE->m_fSongBeatVisible;
+ float fSongBeat = pPlayerState->m_Position.m_fSongBeatVisible;
float fBeatsUntilStep = fNoteBeat - fSongBeat;
float fBrightness = SCALE( fBeatsUntilStep, 0, -1, 1.f, 0.f );
diff --git a/src/Attack.cpp b/src/Attack.cpp
index a896944158..1bf2c8623b 100644
--- a/src/Attack.cpp
+++ b/src/Attack.cpp
@@ -11,9 +11,10 @@ void Attack::GetAttackBeats( const Song *pSong, float &fStartBeat, float &fEndBe
{
ASSERT( pSong );
ASSERT_M( fStartSecond >= 0, ssprintf("StartSecond: %f",fStartSecond) );
-
- fStartBeat = pSong->GetBeatFromElapsedTime( fStartSecond );
- fEndBeat = pSong->GetBeatFromElapsedTime( fStartSecond+fSecsRemaining );
+
+ const TimingData &timing = pSong->m_SongTiming;
+ fStartBeat = timing.GetBeatFromElapsedTime( fStartSecond );
+ fEndBeat = timing.GetBeatFromElapsedTime( fStartSecond+fSecsRemaining );
}
/* Get the range for an attack that's being applied in realtime, eg. during battle
@@ -31,12 +32,13 @@ void Attack::GetRealtimeAttackBeats( const Song *pSong, const PlayerState* pPlay
ASSERT( pSong );
/* If reasonable, push the attack forward 8 beats so that notes on screen don't change suddenly. */
- fStartBeat = min( GAMESTATE->m_fSongBeat+8, pPlayerState->m_fLastDrawnBeat );
+ fStartBeat = min( GAMESTATE->m_Position.m_fSongBeat+8, pPlayerState->m_fLastDrawnBeat );
fStartBeat = truncf(fStartBeat)+1;
- const float lStartSecond = pSong->GetElapsedTimeFromBeat( fStartBeat );
+ const TimingData &timing = pSong->m_SongTiming;
+ const float lStartSecond = timing.GetElapsedTimeFromBeat( fStartBeat );
const float fEndSecond = lStartSecond + fSecsRemaining;
- fEndBeat = pSong->GetBeatFromElapsedTime( fEndSecond );
+ fEndBeat = timing.GetBeatFromElapsedTime( fEndSecond );
fEndBeat = truncf(fEndBeat)+1;
// loading the course should have caught this.
diff --git a/src/AutoKeysounds.cpp b/src/AutoKeysounds.cpp
index 5aac67976b..79ec773973 100644
--- a/src/AutoKeysounds.cpp
+++ b/src/AutoKeysounds.cpp
@@ -99,7 +99,7 @@ void AutoKeysounds::LoadAutoplaySoundsInto( RageSoundReader_Chain *pChain )
if( tn[pn].iKeysoundIndex >= 0 )
{
RString sKeysoundFilePath = sSongDir + pSong->m_vsKeysoundFile[tn[pn].iKeysoundIndex];
- float fSeconds = pSong->m_Timing.GetElapsedTimeFromBeatNoOffset( NoteRowToBeat(iRow) ) + SOUNDMAN->GetPlayLatency();
+ float fSeconds = GAMESTATE->m_pCurSteps[pn]->m_Timing.GetElapsedTimeFromBeatNoOffset( NoteRowToBeat(iRow) ) + SOUNDMAN->GetPlayLatency();
float fPan = 0;
if( !bSoundIsGlobal )
diff --git a/src/BPMDisplay.cpp b/src/BPMDisplay.cpp
index f4b27d51b2..49cb155978 100644
--- a/src/BPMDisplay.cpp
+++ b/src/BPMDisplay.cpp
@@ -277,7 +277,7 @@ SongBPMDisplay::SongBPMDisplay()
void SongBPMDisplay::Update( float fDeltaTime )
{
- float fGameStateBPM = GAMESTATE->m_fCurBPS * 60.0f;
+ float fGameStateBPM = GAMESTATE->m_Position.m_fCurBPS * 60.0f;
if( m_fLastGameStateBPM != fGameStateBPM )
{
m_fLastGameStateBPM = fGameStateBPM;
diff --git a/src/Background.cpp b/src/Background.cpp
index 34050aedcc..8c5a64c5fa 100644
--- a/src/Background.cpp
+++ b/src/Background.cpp
@@ -419,7 +419,7 @@ void BackgroundImpl::LoadFromRandom( float fFirstBeat, float fEndBeat, const Bac
int iStartRow = BeatToNoteRow(fFirstBeat);
int iEndRow = BeatToNoteRow(fEndBeat);
- const TimingData &timing = m_pSong->m_Timing;
+ const TimingData &timing = m_pSong->m_SongTiming;
// change BG every time signature change or 4 measures
FOREACH_CONST( TimeSignatureSegment, timing.m_vTimeSignatureSegments, iter )
@@ -697,7 +697,7 @@ void BackgroundImpl::Layer::UpdateCurBGChange( const Song *pSong, float fLastMus
float fBeat, fBPS, fThrowAway;
bool bFreeze;
int iThrowAway;
- pSong->m_Timing.GetBeatAndBPSFromElapsedTime( fCurrentTime, fBeat, fBPS, bFreeze, bFreeze, iThrowAway, fThrowAway );
+ pSong->m_SongTiming.GetBeatAndBPSFromElapsedTime( fCurrentTime, fBeat, fBPS, bFreeze, bFreeze, iThrowAway, fThrowAway );
// Calls to Update() should *not* be scaled by music rate; fCurrentTime is. Undo it.
const float fRate = GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate;
@@ -762,7 +762,7 @@ void BackgroundImpl::Layer::UpdateCurBGChange( const Song *pSong, float fLastMus
m_pCurrentBGA->PlayCommand( "GainFocus" );
/* How much time of this BGA have we skipped? (This happens with SetSeconds.) */
- const float fStartSecond = pSong->m_Timing.GetElapsedTimeFromBeat( change.m_fStartBeat );
+ const float fStartSecond = pSong->m_SongTiming.GetElapsedTimeFromBeat( change.m_fStartBeat );
/* This is affected by the music rate. */
fDeltaTime = fCurrentTime - fStartSecond;
@@ -800,9 +800,9 @@ void BackgroundImpl::Update( float fDeltaTime )
FOREACH_BackgroundLayer( i )
{
Layer &layer = m_Layer[i];
- layer.UpdateCurBGChange( m_pSong, m_fLastMusicSeconds, GAMESTATE->m_fMusicSeconds, m_mapNameToTransition );
+ layer.UpdateCurBGChange( m_pSong, m_fLastMusicSeconds, GAMESTATE->m_Position.m_fMusicSeconds, m_mapNameToTransition );
}
- m_fLastMusicSeconds = GAMESTATE->m_fMusicSeconds;
+ m_fLastMusicSeconds = GAMESTATE->m_Position.m_fMusicSeconds;
}
void BackgroundImpl::DrawPrimitives()
diff --git a/src/BeginnerHelper.cpp b/src/BeginnerHelper.cpp
index 3bf23107df..9bc73247ba 100644
--- a/src/BeginnerHelper.cpp
+++ b/src/BeginnerHelper.cpp
@@ -191,7 +191,7 @@ void BeginnerHelper::ShowStepCircle( PlayerNumber pn, int CSTEP )
m_sStepCircle[pn][isc].StopEffect();
m_sStepCircle[pn][isc].SetZoom( 2 );
m_sStepCircle[pn][isc].StopTweening();
- m_sStepCircle[pn][isc].BeginTweening( GAMESTATE->m_fCurBPS/3, TWEEN_LINEAR );
+ m_sStepCircle[pn][isc].BeginTweening( GAMESTATE->m_Position.m_fCurBPS/3, TWEEN_LINEAR );
m_sStepCircle[pn][isc].SetZoom( 0 );
}
@@ -318,19 +318,19 @@ void BeginnerHelper::Step( PlayerNumber pn, int CSTEP )
ShowStepCircle( pn, ST_DOWN );
m_pDancer[pn]->StopTweening();
m_pDancer[pn]->PlayAnimation( "Step-JUMPLR", 1.5f );
- m_pDancer[pn]->BeginTweening( GAMESTATE->m_fCurBPS/8, TWEEN_LINEAR );
+ m_pDancer[pn]->BeginTweening( GAMESTATE->m_Position.m_fCurBPS/8, TWEEN_LINEAR );
m_pDancer[pn]->SetRotationY( 90 );
- m_pDancer[pn]->BeginTweening( 1/(GAMESTATE->m_fCurBPS * 2) ); //sleep between jump-frames
- m_pDancer[pn]->BeginTweening( GAMESTATE->m_fCurBPS /6, TWEEN_LINEAR );
+ m_pDancer[pn]->BeginTweening( 1/(GAMESTATE->m_Position.m_fCurBPS * 2) ); //sleep between jump-frames
+ m_pDancer[pn]->BeginTweening( GAMESTATE->m_Position.m_fCurBPS /6, TWEEN_LINEAR );
m_pDancer[pn]->SetRotationY( 0 );
break;
}
m_sFlash.StopEffect();
m_sFlash.StopTweening();
- m_sFlash.Sleep( GAMESTATE->m_fCurBPS/16 );
+ m_sFlash.Sleep( GAMESTATE->m_Position.m_fCurBPS/16 );
m_sFlash.SetDiffuseAlpha( 1 );
- m_sFlash.BeginTweening( 1/GAMESTATE->m_fCurBPS * 0.5f );
+ m_sFlash.BeginTweening( 1/GAMESTATE->m_Position.m_fCurBPS * 0.5f );
m_sFlash.SetDiffuseAlpha( 0 );
}
@@ -340,7 +340,7 @@ void BeginnerHelper::Update( float fDeltaTime )
return;
// the row we want to check on this update
- int iCurRow = BeatToNoteRowNotRounded( GAMESTATE->m_fSongBeat + 0.4f );
+ int iCurRow = BeatToNoteRowNotRounded( GAMESTATE->m_Position.m_fSongBeat + 0.4f );
FOREACH_EnabledPlayer( pn )
{
for( int iRow=m_iLastRowChecked; iRowUpdate( fDeltaTime );
m_sFlash.Update( fDeltaTime );
- float beat = fDeltaTime*GAMESTATE->m_fCurBPS;
+ float beat = fDeltaTime*GAMESTATE->m_Position.m_fCurBPS;
// If this is not a human player, the dancer is not shown
FOREACH_HumanPlayer( pu )
{
diff --git a/src/DancingCharacters.cpp b/src/DancingCharacters.cpp
index 6653173f9b..8b5be828c3 100644
--- a/src/DancingCharacters.cpp
+++ b/src/DancingCharacters.cpp
@@ -175,7 +175,7 @@ int Neg1OrPos1() { return RandomInt( 2 ) ? -1 : +1; }
void DancingCharacters::Update( float fDelta )
{
- if( GAMESTATE->m_bFreeze || GAMESTATE->m_bDelay )
+ if( GAMESTATE->m_Position.m_bFreeze || GAMESTATE->m_Position.m_bDelay )
{
// spin the camera Matrix-style
m_CameraPanYStart += fDelta*40;
@@ -184,7 +184,7 @@ void DancingCharacters::Update( float fDelta )
else
{
// make the characters move
- float fBPM = GAMESTATE->m_fCurBPS*60;
+ float fBPM = GAMESTATE->m_Position.m_fCurBPS*60;
float fUpdateScale = SCALE( fBPM, 60.f, 300.f, 0.75f, 1.5f );
CLAMP( fUpdateScale, 0.75f, 1.5f );
@@ -209,8 +209,8 @@ void DancingCharacters::Update( float fDelta )
}
bWasGameplayStarting = bGameplayStarting;
- static float fLastBeat = GAMESTATE->m_fSongBeat;
- float fThisBeat = GAMESTATE->m_fSongBeat;
+ static float fLastBeat = GAMESTATE->m_Position.m_fSongBeat;
+ float fThisBeat = GAMESTATE->m_Position.m_fSongBeat;
if( fLastBeat < GAMESTATE->m_pCurSong->m_fFirstBeat &&
fThisBeat >= GAMESTATE->m_pCurSong->m_fFirstBeat )
{
@@ -220,7 +220,7 @@ void DancingCharacters::Update( float fDelta )
fLastBeat = fThisBeat;
// time for a new sweep?
- if( GAMESTATE->m_fSongBeat > m_fThisCameraEndBeat )
+ if( GAMESTATE->m_Position.m_fSongBeat > m_fThisCameraEndBeat )
{
if( RandomInt(6) >= 4 )
{
@@ -248,7 +248,7 @@ void DancingCharacters::Update( float fDelta )
m_fLookAtHeight = CAMERA_STILL_LOOK_AT_HEIGHT;
}
- int iCurBeat = (int)GAMESTATE->m_fSongBeat;
+ int iCurBeat = (int)GAMESTATE->m_Position.m_fSongBeat;
iCurBeat -= iCurBeat%8;
m_fThisCameraStartBeat = (float) iCurBeat;
@@ -313,7 +313,7 @@ void DancingCharacters::DrawPrimitives()
if(m_fThisCameraStartBeat == m_fThisCameraEndBeat)
fPercentIntoSweep = 0;
else
- fPercentIntoSweep = SCALE(GAMESTATE->m_fSongBeat, m_fThisCameraStartBeat, m_fThisCameraEndBeat, 0.f, 1.f );
+ fPercentIntoSweep = SCALE(GAMESTATE->m_Position.m_fSongBeat, m_fThisCameraStartBeat, m_fThisCameraEndBeat, 0.f, 1.f );
float fCameraPanY = SCALE( fPercentIntoSweep, 0.f, 1.f, m_CameraPanYStart, m_CameraPanYEnd );
float fCameraHeight = SCALE( fPercentIntoSweep, 0.f, 1.f, m_fCameraHeightStart, m_fCameraHeightEnd );
diff --git a/src/Foreground.cpp b/src/Foreground.cpp
index 708fbcb608..f7b7307b37 100644
--- a/src/Foreground.cpp
+++ b/src/Foreground.cpp
@@ -41,9 +41,9 @@ void Foreground::LoadFromSong( const Song *pSong )
bga.m_fStartBeat = change.m_fStartBeat;
bga.m_bFinished = false;
- const float fStartSecond = pSong->m_Timing.GetElapsedTimeFromBeat( bga.m_fStartBeat );
+ const float fStartSecond = pSong->m_SongTiming.GetElapsedTimeFromBeat( bga.m_fStartBeat );
const float fStopSecond = fStartSecond + bga.m_bga->GetTweenTimeLeft();
- bga.m_fStopBeat = pSong->m_Timing.GetBeatFromElapsedTime( fStopSecond );
+ bga.m_fStopBeat = pSong->m_SongTiming.GetBeatFromElapsedTime( fStopSecond );
bga.m_bga->SetVisible( false );
@@ -65,7 +65,7 @@ void Foreground::Update( float fDeltaTime )
{
LoadedBGA &bga = m_BGAnimations[i];
- if( GAMESTATE->m_fSongBeat < bga.m_fStartBeat )
+ if( GAMESTATE->m_Position.m_fSongBeat < bga.m_fStartBeat )
{
// The animation hasn't started yet.
continue;
@@ -82,12 +82,12 @@ void Foreground::Update( float fDeltaTime )
bga.m_bga->SetVisible( true );
bga.m_bga->PlayCommand( "On" );
- const float fStartSecond = m_pSong->m_Timing.GetElapsedTimeFromBeat( bga.m_fStartBeat );
- lDeltaTime = GAMESTATE->m_fMusicSeconds - fStartSecond;
+ const float fStartSecond = m_pSong->m_SongTiming.GetElapsedTimeFromBeat( bga.m_fStartBeat );
+ lDeltaTime = GAMESTATE->m_Position.m_fMusicSeconds - fStartSecond;
}
else
{
- lDeltaTime = GAMESTATE->m_fMusicSeconds - m_fLastMusicSeconds;
+ lDeltaTime = GAMESTATE->m_Position.m_fMusicSeconds - m_fLastMusicSeconds;
}
// This shouldn't go down, but be safe:
@@ -95,7 +95,7 @@ void Foreground::Update( float fDeltaTime )
bga.m_bga->Update( lDeltaTime / fRate );
- if( GAMESTATE->m_fSongBeat > bga.m_fStopBeat )
+ if( GAMESTATE->m_Position.m_fSongBeat > bga.m_fStopBeat )
{
// Finished.
bga.m_bga->SetVisible( false );
@@ -104,7 +104,7 @@ void Foreground::Update( float fDeltaTime )
}
}
- m_fLastMusicSeconds = GAMESTATE->m_fMusicSeconds;
+ m_fLastMusicSeconds = GAMESTATE->m_Position.m_fMusicSeconds;
}
/*
diff --git a/src/GameSoundManager.cpp b/src/GameSoundManager.cpp
index 98ab3cc26c..a9e71fce24 100644
--- a/src/GameSoundManager.cpp
+++ b/src/GameSoundManager.cpp
@@ -146,7 +146,7 @@ static void StartMusic( MusicToPlay &ToPlay )
SSCLoader::LoadFromSSCFile(ToPlay.m_sTimingFile, song) )
{
ToPlay.HasTiming = true;
- ToPlay.m_TimingData = song.m_Timing;
+ ToPlay.m_TimingData = song.m_SongTiming;
// get cabinet lights if any
Steps *pStepsCabinetLights = SongUtil::GetOneSteps( &song, StepsType_lights_cabinet );
if( pStepsCabinetLights )
@@ -156,7 +156,7 @@ static void StartMusic( MusicToPlay &ToPlay )
SMLoader::LoadFromSMFile(ToPlay.m_sTimingFile, song) )
{
ToPlay.HasTiming = true;
- ToPlay.m_TimingData = song.m_Timing;
+ ToPlay.m_TimingData = song.m_SongTiming;
// get cabinet lights if any
Steps *pStepsCabinetLights = SongUtil::GetOneSteps( &song, StepsType_lights_cabinet );
if( pStepsCabinetLights )
@@ -201,7 +201,7 @@ static void StartMusic( MusicToPlay &ToPlay )
{
/* This song has no real timing data. The offset is arbitrary. Change it so
* the beat will line up to where we are now, so we don't have to delay. */
- float fDestBeat = fmodfp( GAMESTATE->m_fSongBeatNoOffset, 1 );
+ float fDestBeat = fmodfp( GAMESTATE->m_Position.m_fSongBeatNoOffset, 1 );
float fTime = NewMusic->m_NewTiming.GetElapsedTimeFromBeatNoOffset( fDestBeat );
NewMusic->m_NewTiming.m_fBeat0OffsetInSeconds = fTime;
@@ -223,7 +223,7 @@ static void StartMusic( MusicToPlay &ToPlay )
* common when starting a precached sound, but our sound isn't, so it'll
* probably take a little longer. Nudge the latency up. */
const float fPresumedLatency = SOUNDMAN->GetPlayLatency() + 0.040f;
- const float fCurSecond = GAMESTATE->m_fMusicSeconds + fPresumedLatency;
+ const float fCurSecond = GAMESTATE->m_Position.m_fMusicSeconds + fPresumedLatency;
const float fCurBeat = g_Playing->m_Timing.GetBeatFromElapsedTimeNoOffset( fCurSecond );
/* The beat that the new sound will start on. */
@@ -236,9 +236,9 @@ static void StartMusic( MusicToPlay &ToPlay )
const float fSecondToStartOn = g_Playing->m_Timing.GetElapsedTimeFromBeatNoOffset( fCurBeatToStartOn );
const float fMaximumDistance = 2;
- const float fDistance = min( fSecondToStartOn - GAMESTATE->m_fMusicSeconds, fMaximumDistance );
+ const float fDistance = min( fSecondToStartOn - GAMESTATE->m_Position.m_fMusicSeconds, fMaximumDistance );
- when = GAMESTATE->m_LastBeatUpdate + fDistance;
+ when = GAMESTATE->m_Position.m_LastBeatUpdate + fDistance;
}
/* Important: don't hold the mutex while we load and seek the actual sound. */
@@ -552,8 +552,8 @@ void GameSoundManager::Update( float fDeltaTime )
if( !g_Playing->m_Music->IsPlaying() )
{
/* There's no song playing. Fake it. */
- CHECKPOINT_M( ssprintf("%f, delta %f", GAMESTATE->m_fMusicSeconds, fDeltaTime) );
- GAMESTATE->UpdateSongPosition( GAMESTATE->m_fMusicSeconds + fDeltaTime, g_Playing->m_Timing );
+ CHECKPOINT_M( ssprintf("%f, delta %f", GAMESTATE->m_Position.m_fMusicSeconds, fDeltaTime) );
+ GAMESTATE->UpdateSongPosition( GAMESTATE->m_Position.m_fMusicSeconds + fDeltaTime, g_Playing->m_Timing );
return;
}
@@ -570,8 +570,8 @@ void GameSoundManager::Update( float fDeltaTime )
//
if( PREFSMAN->m_bLogSkips && !g_Playing->m_bTimingDelayed )
{
- const float fExpectedTimePassed = (tm - GAMESTATE->m_LastBeatUpdate) * g_Playing->m_Music->GetPlaybackRate();
- const float fSoundTimePassed = fSeconds - GAMESTATE->m_fMusicSeconds;
+ const float fExpectedTimePassed = (tm - GAMESTATE->m_Position.m_LastBeatUpdate) * g_Playing->m_Music->GetPlaybackRate();
+ const float fSoundTimePassed = fSeconds - GAMESTATE->m_Position.m_fMusicSeconds;
const float fDiff = fExpectedTimePassed - fSoundTimePassed;
static RString sLastFile = "";
@@ -580,7 +580,7 @@ void GameSoundManager::Update( float fDeltaTime )
/* If fSoundTimePassed < 0, the sound has probably looped. */
if( sLastFile == ThisFile && fSoundTimePassed >= 0 && fabsf(fDiff) > 0.003f )
LOG->Trace("Song position skip in %s: expected %.3f, got %.3f (cur %f, prev %f) (%.3f difference)",
- Basename(ThisFile).c_str(), fExpectedTimePassed, fSoundTimePassed, fSeconds, GAMESTATE->m_fMusicSeconds, fDiff );
+ Basename(ThisFile).c_str(), fExpectedTimePassed, fSoundTimePassed, fSeconds, GAMESTATE->m_Position.m_fMusicSeconds, fDiff );
sLastFile = ThisFile;
}
@@ -599,7 +599,7 @@ void GameSoundManager::Update( float fDeltaTime )
{
/* We're still waiting for the new sound to start playing, so keep using the
* old timing data and fake the time. */
- GAMESTATE->UpdateSongPosition( GAMESTATE->m_fMusicSeconds + fDeltaTime, g_Playing->m_Timing );
+ GAMESTATE->UpdateSongPosition( GAMESTATE->m_Position.m_fMusicSeconds + fDeltaTime, g_Playing->m_Timing );
}
else
{
@@ -614,7 +614,7 @@ void GameSoundManager::Update( float fDeltaTime )
{
static int iBeatLastCrossed = 0;
- float fSongBeat = GAMESTATE->m_fSongBeat;
+ float fSongBeat = GAMESTATE->m_Position.m_fSongBeat;
int iRowNow = BeatToNoteRowNotRounded( fSongBeat );
iRowNow = max( 0, iRowNow );
@@ -638,7 +638,7 @@ void GameSoundManager::Update( float fDeltaTime )
NoteData &lights = g_Playing->m_Lights;
if( lights.GetNumTracks() > 0 ) // lights data was loaded
{
- const float fSongBeat = GAMESTATE->m_fLightSongBeat;
+ const float fSongBeat = GAMESTATE->m_Position.m_fLightSongBeat;
const int iSongRow = BeatToNoteRowNotRounded( fSongBeat );
static int iRowLastCrossed = 0;
diff --git a/src/GameState.cpp b/src/GameState.cpp
index bd4188df15..dbca4fc9a3 100644
--- a/src/GameState.cpp
+++ b/src/GameState.cpp
@@ -127,7 +127,9 @@ GameState::GameState() :
m_pEditSourceSteps( Message_EditSourceStepsChanged ),
m_stEditSource( Message_EditSourceStepsTypeChanged ),
m_iEditCourseEntryIndex( Message_EditCourseEntryIndexChanged ),
- m_sEditLocalProfileID( Message_EditLocalProfileIDChanged )
+ m_sEditLocalProfileID( Message_EditLocalProfileIDChanged ),
+ m_bIsUsingStepTiming( true ),
+ m_bInStepEditor( false )
{
g_pImpl = new GameStateImpl;
@@ -893,22 +895,15 @@ const float GameState::MUSIC_SECONDS_INVALID = -5000.0f;
void GameState::ResetMusicStatistics()
{
- m_fMusicSeconds = 0; // MUSIC_SECONDS_INVALID;
- // todo: move me to FOREACH_EnabledPlayer( p ) after [NUM_PLAYERS]ing
- m_fSongBeat = 0;
- m_fSongBeatNoOffset = 0;
- m_fCurBPS = 10;
- //m_bStop = false;
- m_bFreeze = false;
- m_bDelay = false;
- m_iWarpBeginRow = -1; // Set to -1 because some song may want to warp to row 0. -aj
- m_fWarpDestination = -1; // Set when a warp is encountered. also see above. -aj
- m_fMusicSecondsVisible = 0;
- m_fSongBeatVisible = 0;
+ m_Position.Reset();
+
Actor::SetBGMTime( 0, 0, 0, 0 );
FOREACH_PlayerNumber( p )
+ {
m_pPlayerState[p]->ClearHopoState();
+ m_pPlayerState[p]->m_Position.Reset();
+ }
}
void GameState::ResetStageStatistics()
@@ -947,57 +942,23 @@ void GameState::ResetStageStatistics()
m_iStageSeed = rand();
}
-static Preference g_fVisualDelaySeconds( "VisualDelaySeconds", 0.0f );
-
-void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp )
+void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &timing, const RageTimer ×tamp, bool bUpdatePlayers )
{
- if( !timestamp.IsZero() )
- m_LastBeatUpdate = timestamp;
- else
- m_LastBeatUpdate.Touch();
+
+ m_Position.UpdateSongPosition( fPositionSeconds, timing, timestamp );
- // xxx testing: only do this on monotune survivor
- /*
- if( m_pCurSong && m_pCurSong->GetDisplayFullTitle() == "monotune survivor" )
- LOG->Trace( ssprintf("[GameState::UpdateSongPosition] cur BPS = %f, fPositionSeconds = %f",m_fCurBPS,fPositionSeconds) );
- */
-
- timing.GetBeatAndBPSFromElapsedTime( fPositionSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze, m_bDelay, m_iWarpBeginRow, m_fWarpDestination );
- // "Crash reason : -243478.890625 -48695.773438"
- ASSERT_M( m_fSongBeat > -2000, ssprintf("Song beat %f at %f seconds", m_fSongBeat, fPositionSeconds) );
-
- m_fMusicSeconds = fPositionSeconds;
-
- m_fLightSongBeat = timing.GetBeatFromElapsedTime( fPositionSeconds + g_fLightsAheadSeconds );
-
- m_fSongBeatNoOffset = timing.GetBeatFromElapsedTimeNoOffset( fPositionSeconds );
-
- m_fMusicSecondsVisible = fPositionSeconds - g_fVisualDelaySeconds.Get();
- float fThrowAway, fThrowAway2;
- bool bThrowAway;
- int iThrowAway;
- timing.GetBeatAndBPSFromElapsedTime( m_fMusicSecondsVisible, m_fSongBeatVisible, fThrowAway, bThrowAway, bThrowAway, iThrowAway, fThrowAway2 );
-
- /*
- // xxx testing: only do this on monotune survivor
- if( m_pCurSong && m_pCurSong->GetDisplayFullTitle() == "monotune survivor" )
+ if( bUpdatePlayers )
{
- // and only do it in the known negative bpm region. HACKITY HACK
- if(m_fSongBeat >= 445.490f && m_fSongBeat <= 453.72f)
+ FOREACH_EnabledPlayer( pn )
{
- LOG->Trace( ssprintf("fPositionSeconds = %f",fPositionSeconds) );
- LOG->Trace( ssprintf("Song beat: %f (%f seconds), BPS = %f (%f BPM)",m_fSongBeat,m_fMusicSecondsVisible,m_fCurBPS,m_fCurBPS*60.0f) );
- //LOG->Trace( ssprintf("Music seconds visible %f = fPositionSeconds %f - g_fVisualDelaySeconds %f", m_fMusicSecondsVisible,fPositionSeconds,g_fVisualDelaySeconds.Get()) );
- }
- else if(m_fSongBeat == 445.500f)
- {
- LOG->Trace( ssprintf("[beat 445.500] fPositionSeconds = %f",fPositionSeconds) );
- LOG->Trace( ssprintf("Song beat: %f (%f seconds), BPS = %f (%f BPM)",m_fSongBeat,m_fMusicSecondsVisible,m_fCurBPS,m_fCurBPS*60.0f) );
+ if( m_pCurSteps[pn] )
+ {
+ m_pPlayerState[pn]->m_Position.UpdateSongPosition( fPositionSeconds, m_pCurSteps[pn]->m_Timing, timestamp );
+ Actor::SetPlayerBGMBeat( pn, m_pPlayerState[pn]->m_Position.m_fSongBeatVisible, m_pPlayerState[pn]->m_Position.m_fSongBeatNoOffset );
+ }
}
}
- */
-
- Actor::SetBGMTime( m_fMusicSecondsVisible, m_fSongBeatVisible, fPositionSeconds, m_fSongBeatNoOffset );
+ Actor::SetBGMTime( GAMESTATE->m_Position.m_fMusicSecondsVisible, GAMESTATE->m_Position.m_fSongBeatVisible, fPositionSeconds, GAMESTATE->m_Position.m_fSongBeatNoOffset );
// LOG->Trace( "m_fMusicSeconds = %f, m_fSongBeat = %f, m_fCurBPS = %f, m_bFreeze = %f", m_fMusicSeconds, m_fSongBeat, m_fCurBPS, m_bFreeze );
}
@@ -2291,11 +2252,16 @@ public:
DEFINE_METHOD( GetHardestStepsDifficulty, GetHardestStepsDifficulty() )
DEFINE_METHOD( IsEventMode, IsEventMode() )
DEFINE_METHOD( GetNumPlayersEnabled, GetNumPlayersEnabled() )
- DEFINE_METHOD( GetSongBeat, m_fSongBeat )
- DEFINE_METHOD( GetSongBeatVisible, m_fSongBeatVisible )
- DEFINE_METHOD( GetSongBPS, m_fCurBPS )
- DEFINE_METHOD( GetSongFreeze, m_bFreeze )
- DEFINE_METHOD( GetSongDelay, m_bDelay )
+ /*DEFINE_METHOD( GetSongBeat, m_Position.m_fSongBeat )
+ DEFINE_METHOD( GetSongBeatVisible, m_Position.m_fSongBeatVisible )
+ DEFINE_METHOD( GetSongBPS, m_Position.m_fCurBPS )
+ DEFINE_METHOD( GetSongFreeze, m_Position.m_bFreeze )
+ DEFINE_METHOD( GetSongDelay, m_Position.m_bDelay )*/
+ static int GetSongPosition( T* p, lua_State *L )
+ {
+ p->m_Position.PushSelf(L);
+ return 1;
+ }
DEFINE_METHOD( GetGameplayLeadIn, m_bGameplayLeadIn )
DEFINE_METHOD( GetCoins, m_iCoins )
DEFINE_METHOD( IsSideJoined, m_bSideIsJoined[Enum::Check(L, 1)] )
@@ -2434,7 +2400,7 @@ public:
static int JoinPlayer( T* p, lua_State *L ) { p->JoinPlayer(Enum::Check(L, 1)); return 0; }
static int UnjoinPlayer( T* p, lua_State *L ) { p->UnjoinPlayer(Enum::Check(L, 1)); return 0; }
static int GetSongPercent( T* p, lua_State *L ) { lua_pushnumber(L, p->GetSongPercent(FArg(1))); return 1; }
- DEFINE_METHOD( GetCurMusicSeconds, m_fMusicSeconds )
+ DEFINE_METHOD( GetCurMusicSeconds, m_Position.m_fMusicSeconds )
DEFINE_METHOD( GetWorkoutGoalComplete, m_bWorkoutGoalComplete )
static int GetCharacter( T* p, lua_State *L ) { p->m_pCurCharacters[Enum::Check(L, 1)]->PushSelf(L); return 1; }
@@ -2500,11 +2466,12 @@ public:
ADD_METHOD( GetHardestStepsDifficulty );
ADD_METHOD( IsEventMode );
ADD_METHOD( GetNumPlayersEnabled );
- ADD_METHOD( GetSongBeat );
+ /*ADD_METHOD( GetSongBeat );
ADD_METHOD( GetSongBeatVisible );
ADD_METHOD( GetSongBPS );
ADD_METHOD( GetSongFreeze );
- ADD_METHOD( GetSongDelay );
+ ADD_METHOD( GetSongDelay );*/
+ ADD_METHOD( GetSongPosition );
ADD_METHOD( GetGameplayLeadIn );
ADD_METHOD( GetCoins );
ADD_METHOD( IsSideJoined );
diff --git a/src/GameState.h b/src/GameState.h
index 406e4784b1..5e925e05ff 100644
--- a/src/GameState.h
+++ b/src/GameState.h
@@ -10,6 +10,7 @@
#include "RageTimer.h"
#include "PlayerOptions.h"
#include "SongOptions.h"
+#include "SongPosition.h"
#include "Preference.h"
#include