[default->loading window] Catching up.

This commit is contained in:
Henrik Andersson
2011-07-20 20:06:28 +02:00
140 changed files with 16246 additions and 4453 deletions
+1 -1
View File
@@ -48,7 +48,7 @@ Docs/doxygen
PBProject/build
Xcode/build
*.xcodeproj/xcuserdata
*.xcodeproj/project.xcworkspace/xcuserdata
*.xcodeproj/project.xcworkspace
src/build-*
src/Release-*
src/libtomcrypt/build-*
+6 -6
View File
@@ -39,17 +39,17 @@ WeightW2=30
WeightW1=50
[Skill5]
WeightMiss=8
WeightW5=1
WeightW4=1
WeightMiss=2
WeightW5=3
WeightW4=5
WeightW3=5
WeightW2=30
WeightW1=55
[Skill6]
WeightMiss=8
WeightW5=1
WeightW4=1
WeightMiss=2
WeightW5=3
WeightW4=5
WeightW3=5
WeightW2=30
WeightW1=55
+4
View File
@@ -9,6 +9,10 @@ change to JSON, but it is unsure if this will be done.
Implement .ssc at your own risk.
________________________________________________________________________________
[v0.77] - Wolfman2000
* Add the cache tag #STEPFILENAME to gain access to the proper #NOTES when
required.
[v0.76] - Wolfman2000
* Expand the #COMBOS tag to allow for Miss Combos. Anyone that is crazy enough
to put in a 51 miss combo in their tags should be...oh wait: it's already
+12
View File
@@ -8,6 +8,18 @@ ________________________________________________________________________________
StepMania 5.0 ????????? | 20110???
--------------------------------------------------------------------------------
2011/07/19
----------
* [LoadingWindow] Added the ability for themes to have custom splash banners.
(Currently Windows-only.) [AJ]
2011/07/17
----------
* [Cache] No longer store #NOTES in the cache. This should speed things up
on the first load if there is not much to write. (General note: this was
taken from another branch, but results at that point were great.)
[Wolfman2000]
2011/07/13
----------
* [Difficulty] Allow ALL StepsTypes to use CustomDifficulty properly.
+7 -4
View File
@@ -25,15 +25,15 @@
#SAMPLELENGTH:;
#DISPLAYBPM:[xxx][xxx:xxx]|[*];
#SELECTABLE:;
#LASTBEATHINT:;
#LASTSECONDHINT:;
#BGCHANGES:;
#FGCHANGES:;
#KEYSOUNDS:;
#ATTACKS:;
// stored in cache
#FIRSTBEAT:; // calculated
#LASTBEAT:; // calculated
#FIRSTSECOND:; // calculated
#LASTSECOND:; // calculated
#SONGFILENAME:;
#MUSICBYTES:; // ignored by loader
#HASMUSIC:;
@@ -66,5 +66,8 @@
#ATTACKS:;
#DISPLAYBPM:;
// actual step data
// only in cache files
#STEPFILENAME:;
// actual step data (not in cache files)
#NOTES:;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 766 B

After

Width:  |  Height:  |  Size: 466 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

File diff suppressed because it is too large Load Diff
@@ -0,0 +1 @@
return Def.ActorFrame { Name="YOU_WISH_YOU_WERE_PLAYING_BEATMANIA_RIGHT_NOW" };
@@ -1 +0,0 @@
_blank
@@ -46,26 +46,30 @@ function MakeScoreList(StagesAgo)
OffCommand=cmd(linear,0.3;addx,150;diffusealpha,0);
};
LoadFont( "_regra bold 30px" ) .. {
LoadFont( "Common Normal" ) .. {
-- LoadFont( "_regra bold 30px" ) .. {
Name="PlayerScoreP1";
InitCommand=cmd(x,-135;diffuse,color("#fdf991");shadowlength,0;zoom,0.6);
OnCommand=cmd(x,-135;addx,50;zoom,0;diffusealpha,0;sleep,0.1;accelerate,0.3;addx,-50;diffusealpha,1;zoom,0.6);
OffCommand=cmd(linear,0.3;diffusealpha,0);
};
LoadFont( "_regra bold 30px" ) .. {
LoadFont( "Common Normal" ) .. {
-- LoadFont( "_regra bold 30px" ) .. {
Name="PlayerScoreP2";
InitCommand=cmd(x,135;diffuse,color("#abfe8e");shadowlength,0;zoom,0.6);
OnCommand=cmd(x,135;addx,-50;zoom,0;diffusealpha,0;sleep,0.1;accelerate,0.3;addx,50;diffusealpha,1;zoom,0.6);
OffCommand=cmd(linear,0.3;diffusealpha,0);
};
LoadFont( "_regra bold 30px" ) .. {
LoadFont( "Common Normal" ) .. {
-- LoadFont( "_regra bold 30px" ) .. {
Name="MachineBestP1";
InitCommand=cmd(diffuse,color("#ffffff");shadowlength,0;zoom,0.5);
OnCommand=cmd(x,-250;addx,-250;diffusealpha,1;decelerate,0.3;addx,250);
OffCommand=cmd(linear,0.3;addx,-150;diffusealpha,0);
};
LoadFont( "_regra bold 30px" ) .. {
LoadFont( "Common Normal" ) .. {
-- LoadFont( "_regra bold 30px" ) .. {
Name="MachineBestP2";
InitCommand=cmd(diffuse,color("#ffffff");shadowlength,0;zoom,0.5);
OnCommand=cmd(x,250;addx,250;diffusealpha,1;decelerate,0.3;addx,-250);
@@ -130,7 +134,7 @@ function MakeScoreList(StagesAgo)
if visible then
assert(CurrentPart[pn]);
c.Difficulty[pn]:SetDifficultyAndStepsTypeFrame( CurrentPart[pn] );
-- c.Difficulty[pn]:SetDifficultyAndStepsTypeFrame( CurrentPart[pn] );
local hsl = MachineProfile:GetHighScoreList( Current, CurrentPart[pn] );
assert( hsl );
@@ -198,8 +202,8 @@ for i = 1,5 do
};
end
children[#children+1] =
LoadActor( THEME:GetPathB("","_shared underlay") ) .. { OnCommand=cmd(); };
--[[ children[#children+1] =
LoadActor( THEME:GetPathB("","_shared underlay") ) .. { OnCommand=cmd(); }; --]]
children[#children+1] = LoadActor( "keyboard" ) .. {
InitCommand=cmd(x,SCREEN_CENTER_X;y,SCREEN_CENTER_Y+80);
@@ -217,7 +221,8 @@ for pn in ivalues(PlayerNumber) do
OffCommand=cmd(stoptweening;bouncebegin,0.3;zoom,0;addx,-200*P1);
};
children[#children+1] = LoadFont( "_regra bold 30px" ) .. {
children[#children+1] = LoadFont( "Common Normal" ) .. {
-- children[#children+1] = LoadFont( "_regra bold 30px" ) .. {
Name="PlayerText";
InitCommand=cmd(x,pn == PLAYER_1 and (SCREEN_CENTER_X-WideScale(310,330)) or (SCREEN_CENTER_X+WideScale(198,204));
halign,0;
@@ -19,7 +19,8 @@ end
local MapNameToLetter = {};
local MapLetterToName = {};
local letter = LoadFont( "_regra bold 30px" ) .. {
local letter = LoadFont( "Common Normal" ) .. {
-- local letter = LoadFont( "_regra bold 30px" ) .. {
InitCommand=cmd(zoom,0.8;shadowlength,0);
PulseCommand = function(self)
self:finishtweening();
@@ -37,13 +38,18 @@ for l in ivalues(Letters) do
Text = l;
};
if l == "BACK" or l == "ENTER" then
children[#children].File = THEME:GetPathF("", "_venacti 26px normal");
children[#children].File = THEME:GetPathF("", "Common Normal");
-- children[#children].File = THEME:GetPathF("", "_venacti 26px normal");
end;
end;
children[#children+1] = LoadActor( THEME:GetPathS(Var "LoadingScreen", "type key") ) .. { Name = "Type"; SupportPan = true; }
--[[ children[#children+1] = LoadActor( THEME:GetPathS(Var "LoadingScreen", "type key") ) .. { Name = "Type"; SupportPan = true; }
children[#children+1] = LoadActor( THEME:GetPathS(Var "LoadingScreen", "back") ) .. { Name = "Back"; SupportPan = true; }
children[#children+1] = LoadActor( THEME:GetPathS(Var "LoadingScreen", "enter") ) .. { Name = "Enter"; SupportPan = true; }
children[#children+1] = LoadActor( THEME:GetPathS(Var "LoadingScreen", "move cursor") ) .. { Name = "Move"; SupportPan = true; }
children[#children+1] = LoadActor( THEME:GetPathS(Var "LoadingScreen", "move cursor") ) .. { Name = "Move"; SupportPan = true; } --]]
children[#children+1] = LoadActor( THEME:GetPathS("Common", "value") ) .. { Name = "Type"; SupportPan = true; }
children[#children+1] = LoadActor( THEME:GetPathS("Common", "cancel") ) .. { Name = "Back"; SupportPan = true; }
children[#children+1] = LoadActor( THEME:GetPathS("Common", "start") ).. { Name = "Enter"; SupportPan = true; }
children[#children+1] = LoadActor( THEME:GetPathS("MusicWheel", "change") ) .. { Name = "Move"; SupportPan = true; }
local CursorFiles = {
[PLAYER_1] = "Cursor P1",
Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

-407
View File
@@ -1,407 +0,0 @@
# 01 # Global
# 02 # System
# 03 # Attract
# 04 # Base
# 05 #
# 06 #
# 01 #
[ScreenDebugOverlay]
Debug Menu=Debug Menu
Multitexture=Multitexture
Assist=Assist
Visual Delay Up=Visual Delay Up
Visual Delay Down=Visual Delay Down
Rendering Stats=Rendering Stats
Volume Up=Volume Up
Volume Down=Volume Down
Reload=Reload
Reload Theme and Textures=Reload Theme and Textures
Autosync=Autosync
Halt=Halt
Slow=Slow
Uptime=Uptime
Machine=Machine
Profile=Profile
CoinMode=CoinMode
Show Masks=Show Masks
Vsync=Vertical Sync
Write Preferences=Write Preferences
Monkey Input=Hampsterblade Mode
Send Off To Screen=Send Off To Screen
Send On To Screen=Send On To Screen
Write Profiles=Write Profiles
Lights Debug=Lights Debug
Fill Profile Stats=Fill Profile Stats
off=Off
Pull Back Camera=Pull Back Camera
Force Crash=Force Crash
Song=Song
Restart=Restart
on=On
Tempo=Tempo
Screen Test Mode=Screen Test Mode
AutoPlay=AutoPlay
Clear Profile Stats=Clear Profile Stats
Flush Log=Flush Log
%s in gameplay=%s in gameplay
Send Notes Ended=Send Notes Ended
or=or
CPU=CPU
Menu Timer=Menu Timer
# 02 #
[ScreenBookkeeping]
Coin Data by Day of Week, All-Time=Coin Data by Day of Week, All-Time
Coin Data of Last %d Weeks=Coin Data of Last %d Weeks
Coin Data of Last %d Days=Coin Data of Last %d Days
Coin Data by Hour of Day, All-Time=Coin Data by Hour of Day, All-Time
All-time Coin Total:=All-time Coin Total:
Total Song Plays: %d=Total Song Plays: %d
# 03 #
# 04 #
[ScreenEdit]
%s notes=%s notes
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 artist transliteration.=Enter a new artist transliteration.
Enter a new artist.=Enter a new artist.
Enter a new credit.=Enter a new credit.
Enter a new description.=Enter a new description.
Enter a new last beat hint.=Enter a new last beat hint.
Enter a new main title transliteration.=Enter a new main title transliteration.
Enter a new main title.=Enter a new main title.
Enter a new sub title transliteration.=Enter a new sub title transliteration.
Enter a new sub title.=Enter a new sub title.
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\nSpace bar:\n Set area\n marker\nEnter:\n Area Menu\nEscape:\n Main 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.
Saved as SM.=Saved as SM.
Switched to=Switched to
The change has been reverted.=The change has been reverted.
This change creates more than %d notes in a measure.=This change creates more than %d notes in a measure.
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
Current beat=Current beat
Current second=Current second
Snap to=Snap to
Selection beat=Selection beat
Difficulty=Difficulty
Description=Description
Main title=Main title
Subtitle=Subtitle
Tap Steps=Tap Steps
Jumps=Jumps
Hands=Hands
Holds=Holds
Mines=Mines
Rolls=Rolls
Beat 0 offset=Beat 0 offset
Preview Start=Preview Start
Preview Length=Preview Length
[ScreenEditMenu]
Continue with delete?=Continue with delete?
Enter a description for this edit.=Enter a description for this edit.
ExplanationAction=In this mode, you can edit existing notes patterns, create note patterns, or synchronize notes with the music.
ExplanationGroup=In this mode, you can edit existing notes patterns, create note patterns, or synchronize notes with the music.
ExplanationSong=In this mode, you can edit existing notes patterns, create note patterns, or synchronize notes with the music.
ExplanationSourceSteps=In this mode, you can edit existing notes patterns, create note patterns, or synchronize notes with the music.
ExplanationSourceStepsType=In this mode, you can edit existing notes patterns, create note patterns, or synchronize notes with the music.
ExplanationSteps=In this mode, you can edit existing notes patterns, create note patterns, or synchronize notes with the music.
ExplanationStepsType=In this mode, you can edit existing notes patterns, create note patterns, or synchronize notes with the music.
Profile name cannot be blank.=Profile name can not be blank.
The name you chose conflicts with another profile. Please use a different name.=The name you chose conflicts with another profile. Please use a different name.
These steps are produced by autogen. You do not need to delete them.=These steps are produced by autogen. You do not need to delete them.
These steps will be lost permanently.=These steps will be lost permanently.
This song is missing a music file and cannot be edited.=This song is missing a music file and can not be edited.
The song directory is read-only and cannot be edited.=The song directory is read-only and cannot be edited.
Blank=Blank
[ScreenMapControllers]
InvalidButton=That key can not be mapped.
%s slots=%s slots
[ScreenNetRoom]
Enter a description for the room:=Enter a description for the room:
Enter a password for the room (blank, no password):=Enter a password for the room (blank, no password):
Enter Room's Password:=Enter Room's Password:
[ScreenNetworkOptions]
Disconnected from server.=Disconnected from server.
Enter a network address.=Enter a network address.
Server failed: %s Code:%d=Server failed: %s Code:%d
Use 127.0.0.1 to connect to yourself.=Use 127.0.0.1 to connect to yourself.
Connect=Connect
Disconnect=Disconnect
ScoreOn=On
ScoreOff=Off
[ScreenOptionsCourseOverview]
Course saved successfully.=Course saved successfully.
Error saving course.=Error saving course.
Enter a name for the course.=Enter a name for the course.
Error saving workout.=Error saving workout.
Workout saved successfully.=Workout saved successfully.
Enter a name for the workout.=Enter a name for the workout.
[ScreenOptionsEditCourse]
-Empty-=-Empty-
Song=Song
Steps=Steps
minutes=minutes
You must enable at least %d songs.=You must enable at least %d songs.
[ScreenOptionsManageCourses]
Error renaming file.=Error renameing file.
Continue with delete?=Continue with delete?
Enter a name for the course.=Enter a name for the course.
This course will be lost permanently.=This course will be lost permanently.
You have %d, the maximum number allowed.=You have %d, the maximum number allowed.
You must delete an existing before creating a new.=You must delete an existing before creating a new.
Error deleting the file '%s'.=Error deleting the file "%s".
[ScreenOptionsManageEditSteps]
Continue with delete?=Continue with delete?
Enter a name for these steps.=Enter a name for these steps.
These steps will be lost permanently.=These steps will be lost permanently.
You have %d step edits, the maximum number allowed.=You have %d step edits, the maximum number allowed.
You must delete an existing steps edit before creating a new steps edit.=You must delete an existing steps edit before creating a new steps edit.
[ScreenOptionsManageProfiles]
Are you sure you want to clear all data in the profile '%s'?=Are you sure you want to clear all data in the profile &oq;%s&cq;?
Are you sure you want to delete the profile '%s'?=Are you sure you want to delete the profile &oq;%s&cq;?
Enter a name for the profile.=Enter a
NewProfileDefaultName=New
[ScreenOptionsMasterPrefs]
Off=Off
[ScreenOptionsMemoryCard]
Error mounting card: %s=Error mounting card: %s
[ScreenPackages]
Download cancelled.=Download cancelled.
Enter URL=Enter URL
[ScreenSaveSync]
Choosing NO will discard your changes.=Choosing NO will discard your changes.
Would you like to save these changes?=Would you like to save these changes?
You have changed the timing of=You have changed the timing of
[ScreenServiceAction]
%d added=%d added
%d copied=%d copied
%d overwritten=%d overwritten
%d deleted=%d deleted
%d edits cleared, %d errors.=%d edits cleared, %d errors.
%d failed=%d failed
%d ignored=%d ignored
Bookkeeping data cleared.=Bookkeeping data cleared.
Copied from P%d card:=Copied from P%d card:
Copied to P%d card:=Copied to P%d card:
Edits not cleared - No memory cards ready.=Edits not cleared - No memory cards ready.
Edits not copied - No memory cards ready.=Edits not copied - No memory cards ready.
Error saving machine stats to P%d card.=Error saving machine stats to P%d card.
Machine stats cleared.=Machine stats cleared.
Machine stats loaded from P%d card.=Machine stats loaded from P%d card.
Machine stats saved to P%d card.=Machine stats saved to P%d card.
Preferences reset.=Preferences reset.
Stats not loaded - No memory cards ready.=Stats not loaded - No memory cards ready.
Stats not saved - No memory cards ready.=Stats not saved - No memory cards ready.
The profile on P%d card contains corrupt or tampered data.=The profile on P%d card contains corrupt or tampered data.
There is no machine profile on P%d card.=There is no machine profile on P%d card.
[ScreenSMOnlineLogin]
Each player needs a unique Profile.=Each player needs a unique Profile.
Enter your password.=Enter your password.
No Styles are selectable.=No Styles are selectable.
You are logging on as:=You are logging on as:
You must define a Profile.=You must define a Profile.
Depending on the server you're connected to, you may have to register for an account on their website.=Depending on the server you're connected to, you may have to register for an account on their website.
[ScreenSyncOverlay]
AutoPlay=AutoPlay
AutoPlayCPU=AutoPlayCPU
AutoSync Machine=AutoSync Machine
AutoSync Song=AutoSync Song
AutoSync Tempo=AutoSync Tempo
Can't sync while playing a course.=Can't sync while playing a course.
Sync changes reverted.=Sync changes reverted.
Revert sync changes=Revert sync changes
Current BPM - smaller/larger=Current BPM - smaller/larger
Song offset - notes earlier/later=Song offset - notes earlier/later
Machine offset - notes earlier/later=Machine offset - notes earlier/later
(hold Alt for smaller increment)=(hold Alt for smaller increment)
Old offset=Old offset
New offset=New offset
Collecting sample=Collecting sample
Standard deviation=Standard deviation
[ScreenSystemLayer]
CreditsCardChanged=CARD SWITCHED
CreditsCardChecking=CARD CHECK
CreditsCardMountFailed=CARD MOUNT ERROR
CreditsCardNoName=NoName
CreditsCardReady=READY
CreditsCardRemoved=CARD GONE
CreditsCardTestFailed=CARD WRITE ERROR
CreditsCardTooLate=CARD TOO LATE
CreditsCredits=CREDIT(S)
CreditsMax=(MAX)
CreditsFreePlay=FREE PLAY
CreditsInsertCard=INSERT CARD
CreditsLoadFailed=SIGNATURE FAILED
CreditsLoadedFromLastGoodAppend= (backup)
CreditsNotPresent=NOT PRESENT
CreditsPressStart=PRESS START
[ScreenTestFonts]
# W is annoying:
Text1=WWWWWWWWWWWW
# Realistic excerpt:
Text2=The argument goes something like this: &oq;I refuse to prove that I exist,&cq; says God, &oq;for proof denies faith, and without faith I am nothing.&cq;::::&oq;But,&cq; says Man, &oq;The Babel fish is a dead giveaway, isn't it? It could not have evolved by chance. It proves you exist, and so therefore, by your own arguments, you don't. QED.&cq;::::&oq;Oh dear,&cq; says God, &oq;I hadn't thought of that,&cq; and promptly vanished in a puff of logic.
# Numbers test:
Text3=01234567890 ::100.00% 12345% 9:00 50/100
# General symbol test, and test alignment against another font.
Text4=$50% (Test) "test's" &oq;test's&cq;, #1! 1+2-3*4/5.6::3:00 a; b; 5<6 6>5 2^3=8 Why? [email protected]::[Foo] {bar} Press &START; 3|4 &oq;1_2_3&cq;
Text5=
[ScreenTestInput]
Controller=Controller
not mapped=not mapped
secondary=secondary
[ScreenTestLights]
Auto Cycle=Auto Cycle
Manual Cycle=Manual Cycle
cabinet light=cabinet light
controller light=controller light
[ScreenTextEntry]
Backspace=Backsp
Cancel=Cancel
Done=Done
HeaderText=
Space=Space
"%s" is an invalid floating point value.="%s" is an invalid floating point value.
[ScreenTitleMenu]
%d songs in %d groups=%d songs in %d groups
%d courses in %d groups=%d courses in %d groups
%d unlocks=%d unlocks
Gametype:=Gametype:
Difficulty:=Difficulty:
Announcer=Announcer
Play Online=Network Play
Edit/Share=Edit/Share
Exit=Exit
Game Start=Game Start
Jukebox=Jukebox
Select Game=Select Game
Theme=Theme
Credits=Credits
Options=Options
[AdjustSync]
%s BPM from %.3f BPM to %.3f BPM.=%s BPM from %.3f BPM to %.3f BPM.
Autosync Machine=Autosync Machine
Autosync Song=Autosync Song
Autosync Tempo=Autosync Tempo
Autosync: Correction NOT applied. Deviation too high.=Autosync: Correction NOT applied. Deviation too high.
Autosync: Correction applied.=Autosync: Correction applied.
Global Offset from %+.3f to %+.3f (notes %s)=Global Offset from %+.3f to %+.3f (notes %s)
Song offset from %+.3f to %+.3f (notes %s)=Song offset from %+.3f to %+.3f (notes %s)
The stop segment #%d changed from %+.3fs to %+.3fs (change of %+.3f).=The stop segment number #%d changed from %+.3fs to %+.3fs (change of %+.3f).
earlier=earlier
later=later
Average Error %.5fs=Average Error %.5fs
Etc.=Etc.
%d taps ignored.=%d taps ignored.
[Common]
WindowTitle=StepMania
StepMania=StepMania
[CourseUtil]
The course name cannot contain any of the following characters: %s=The course name cannot contain any of the following characters: %s
You must supply a name for your course.=You must supply a name for your course.
The name you chose conflicts with another course. Please use a different name.=The name you chose conflicts with another course. Please use a different name.
[GameCommand]
Could not launch web browser.=Could not launch web browser.
[NotesWriterSM]
Error renaming file. Destination file '%s' already exists.=Error renaming file. Destination file '%s' already exists.
Error writing file '%s'.=Error writing file '%s'.
[OptionRowHandler]
Off=Off
[RoomInfoDisplay]
Last Round Info:=Last Round Info:
Room Name:=Name:
Room Description:=Description:
Song Title:=Title:
Song Subtitle:=Subtitle:
Song Artist:=Artist:
Players=Players
[SongUtil]
You must supply a name for your new edit.=You must supply a name for your new edit.
The name you chose conflicts with another edit. Please use a different name.=The name you chose conflicts with another edit. Please use a different name.
The edit name cannot contain any of the following characters: %s=The edit name can not contain any of the following characters: %s
[Sort]
NotAvailable=N/A
Other=Other
[StepMania]
Announcer=Announcer
Couldn't open any loading windows.=Couldn't open any loading windows.
Fullscreen=Fullscreen
Initializing %s...=Initializing %s...
No video renderers attempted.=No video renderers attempted.
NoSmoothLines=NoSmoothLines
NoVsync=NoVsync
Please do not file this error as a bug! Use the web page below to troubleshoot this problem.=Please do not file this error as a bug! Use the web page below to troubleshoot this problem.
Service switch pressed=Service switch pressed
SmoothLines=SmoothLines
There was an error while initializing your video card.=There was an error while initializing your video card.
Unknown video renderer value: %s=Unknown video renderer value: %s
Video Driver: %s=Video Driver: %s
Vsync=Vsync
Windowed=Windowed
color=color
texture=texture
[DeviceButton]
Home=Home
End=End
Up=Up
Down=Down
Space=Space
Shift=Shift
Ctrl=Ctrl
Alt=Alt
Insert=Insert
Delete=Delete
PgUp=PgUp
PgDn=PgDn
Backslash=Backslash
[Arch]
Couldn't create a movie driver.=Couldn't create a movie driver.
Input Handlers cannot be empty.=Input Handlers can not be empty.
Movie Drivers cannot be empty.=Movie Drivers can not be empty.
Sound Drivers cannot be empty.=Sound Drivers can not be empty.
[LowLevelWindow_Win32]
OpenGL hardware acceleration is not available.=OpenGL hardware acceleration is not available.
[Dialog-Prompt]
Prompt=Prompt
OK=OK
&Don't display this message again=&Don't display this message again
Error=Error
[Dialog-Uninstall Old Packages]
Uninstall Old Packages=Uninstall Old Packages
&Yes=&Yes
&No=&No
Cancel=Cancel
The following packages are already installed. It is strongly recommended that they be deleted before installing this package.=The following packages are already installed. It is strongly recommended that they be deleted before installing this package.
Delete old packages?=Delete old packages?
[EditMenu]
Blank=Blank
[EditMenuRow]
Action=Action
Group=Group
Song=Song
SourceSteps=Fill Steps
SourceStepsType=Fill Type
Steps=Steps
StepsType=Type
[RoomWheel]
Enter room name=Enter room name
[RageDisplay_OGL]
Obtain an updated driver from your video card manufacturer.=Obtain an updated driver from your video card manufacturer.
GLDirect was detected. GLDirect is not compatible with this game and should be disabled.=GLDirect was detected. GLDirect is not compatible with this game and should be disabled.
[RageDisplay_D3D]
DirectX 8.1 or greater is not installed. You can download it from:=DirectX 8.1 or greater is not installed. You can download it from:
Your system is reporting that Direct3D hardware acceleration is not available. Please obtain an updated driver from your video card manufacturer.=Your system is reporting that Direct3D hardware acceleration is not available. Please obtain an updated driver from your video card manufacturer.
[RageDisplay]
SetVideoMode failed:=SetVideoMode failed:
File diff suppressed because it is too large Load Diff
+6 -7
View File
@@ -1,5 +1,5 @@
-- SSC Color Module and Library
local nilColor = color("0,0,0,0")
-- Original Color Module.
Color = {
-- Color Library
@@ -16,7 +16,7 @@ Color = {
Purple = color("#92278f"),
Outline = color("0,0,0,0.5"),
Invisible = color("1,1,1,0"),
Stealth = nilColor,
Stealth = color("0,0,0,0"),
-- Color Functions
-- These functions alter colors in a certain way so that you can make
-- new ones without having to copy a color or find a new one.
@@ -30,8 +30,11 @@ Color = {
return { c[1],c[2],c[3],fAlpha };
end
}
setmetatable(Color, { __call = function(self, c) return self[c] end })
-- Remapped Color Module, since some themes are crazy
Colors = Color;
-- Colors = Color;
GameColor = {
PlayerColors = {
@@ -95,10 +98,6 @@ GameColor.Difficulty["Nightmare"] = GameColor.Difficulty["Challenge"];
GameColor.Difficulty["HalfDouble"] = GameColor.Difficulty["Medium"];
--[[ Fallbacks ]]
function Color(c)
return Colors[c]
end
function BoostColor( cColor, fBoost )
local c = cColor
return { c[1]*fBoost, c[2]*fBoost, c[3]*fBoost, c[4] }
+6 -2
View File
@@ -187,7 +187,11 @@ function HoldTiming()
end
function ShowHoldJudgments()
return not GAMESTATE:GetCurrentGame():GetName() == "pump"
if GAMESTATE:GetCurrentGame():GetName() == "pump" then
return false
else
return true
end
end
function HoldHeadStep()
@@ -271,4 +275,4 @@ end
function ComboUnderField()
return GetUserPrefB("UserPrefComboUnderField")
end
end
+2
View File
@@ -200,6 +200,8 @@ DrunkOffsetFrequency=10
DrunkArrowMagnitude=0.5
BeatOffsetHeight=15
BeatPIHeight=2
MiniPercentBase=0.5
MiniPercentGate=1
TinyPercentBase=0.5
TinyPercentGate=1
DizzyHoldHeads=false
+4 -1
View File
@@ -1,5 +1,8 @@
[Global]
FallbackTheme=default
[ScreenTitleMenu]
ChoiceNames="1,4,5,6,PopScreen,7"
ChoicePopScreen="name,Boobs;text,Boobs";
[ScreenGameplay]
# LifeP1OnCommand=visible,false
# LifeP2OnCommand=visible,false
# LifeP2OnCommand=visible,false
@@ -13,7 +13,7 @@ local t = Def.ActorFrame {
LoadActor("_grid")..{
InitCommand=cmd(customtexturerect,0,0,(SCREEN_WIDTH+1)/4,SCREEN_HEIGHT/4;SetTextureFiltering,true);
OnCommand=cmd(zoomto,SCREEN_WIDTH+1,SCREEN_HEIGHT;diffuse,Color("Black");diffuseshift;effecttiming,(1/8)*4,0,(7/8)*4,0;effectclock,'beatnooffset';
effectcolor2,Color("Black");effectcolor1,Colors.Alpha(Color("Black"),0.45);fadebottom,0.25;fadetop,0.25;croptop,48/480;cropbottom,48/480;diffusealpha,0.345);
effectcolor2,Color("Black");effectcolor1,Color.Alpha(Color("Black"),0.45);fadebottom,0.25;fadetop,0.25;croptop,48/480;cropbottom,48/480;diffusealpha,0.345);
};
};
@@ -0,0 +1 @@
return Def.ActorFrame { Name="YOU_WISH_YOU_WERE_PLAYING_BEATMANIA_RIGHT_NOW" };
@@ -7,7 +7,7 @@ t[#t+1] = Def.Sprite {
BeforeLoadingNextCourseSongMessageCommand=function(self) self:LoadFromSongBackground( SCREENMAN:GetTopScreen():GetNextCourseSong() ) end;
ChangeCourseSongInMessageCommand=cmd(scaletoclipped,SCREEN_WIDTH,SCREEN_HEIGHT);
StartCommand=cmd(diffusealpha,0;decelerate,0.5;diffusealpha,1;);
FinishCommand=cmd(linear,0.1;glow,Colors.Alpha(Color("White"),0.5);decelerate,0.4;glow,Color("Invisible");diffusealpha,0);
FinishCommand=cmd(linear,0.1;glow,Color.Alpha(Color("White"),0.5);decelerate,0.4;glow,Color("Invisible");diffusealpha,0);
};
t[#t+1] = Def.ActorFrame {
@@ -24,7 +24,7 @@ t[#t+1] = Def.ActorFrame {
--[[ LoadActor(THEME:GetPathB("ScreenWithMenuElements","background/_grid")).. {
InitCommand=cmd(customtexturerect,0,0,(SCREEN_WIDTH+1)/4,SCREEN_HEIGHT/4;SetTextureFiltering,true);
OnCommand=cmd(zoomto,SCREEN_WIDTH+1,SCREEN_HEIGHT;diffuse,Color("Black");diffuseshift;effecttiming,(1/8)*4,0,(7/8)*4,0;effectclock,'beatnooffset';
effectcolor2,Color("Black");effectcolor1,Colors.Alpha(Color("Black"),0.45);fadebottom,0.25;fadetop,0.25;croptop,48/480;cropbottom,48/480;diffusealpha,0.345);
effectcolor2,Color("Black");effectcolor1,Color.Alpha(Color("Black"),0.45);fadebottom,0.25;fadetop,0.25;croptop,48/480;cropbottom,48/480;diffusealpha,0.345);
}; --]]
LoadActor(THEME:GetPathB("ScreenWithMenuElements","background/_bg top")) .. {
InitCommand=cmd(scaletoclipped,SCREEN_WIDTH+1,SCREEN_HEIGHT);
@@ -33,7 +33,7 @@ t[#t+1] = Def.ActorFrame {
--[[ LoadActor("_grid") .. {
InitCommand=cmd(customtexturerect,0,0,(SCREEN_WIDTH+1)/4,SCREEN_HEIGHT/4;SetTextureFiltering,true);
OnCommand=cmd(zoomto,SCREEN_WIDTH+1,SCREEN_HEIGHT;diffuse,Color("Orange");diffuseshift;effecttiming,(1/8)*2,0,(7/8)*2,0;effectclock,'beatnooffset';
effectcolor2,Color("Orange");effectcolor1,Colors.Alpha(Color("Orange"),0.45);fadebottom,0.25;fadetop,0.25;croptop,48/480;cropbottom,48/480);
effectcolor2,Color("Orange");effectcolor1,Color.Alpha(Color("Orange"),0.45);fadebottom,0.25;fadetop,0.25;croptop,48/480;cropbottom,48/480);
}; --]]
LoadActor("_bg top") .. {
InitCommand=cmd(scaletoclipped,SCREEN_WIDTH+1,SCREEN_HEIGHT);
@@ -13,7 +13,7 @@ return Def.ActorFrame {
InitCommand=cmd(zoomto,fWidth,SCREEN_HEIGHT;diffuse,PlayerColor(Player);diffusealpha,0;fadeleft,32/(256+16);faderight,32/(256+16));
ToastyAchievedMessageCommand=function(self,params)
if params.PlayerNumber == Player then
(cmd(stoptweening;linear,2.125;diffuse,Colors.Alpha( PlayerColor(Player), 0.345 );glow,color("1,1,1,0.5");decelerate,3;glow,Colors.Alpha( ColorDarkTone( PlayerColor(Player) ), 0 );diffuseramp;
(cmd(stoptweening;linear,2.125;diffuse,Color.Alpha( PlayerColor(Player), 0.345 );glow,color("1,1,1,0.5");decelerate,3;glow,Color.Alpha( ColorDarkTone( PlayerColor(Player) ), 0 );diffuseramp;
effectcolor1,ColorLightTone( PlayerColor(Player) );effectcolor2,PlayerColor(Player);
effectclock,'beat';effectperiod,2;
))(self);
@@ -23,7 +23,7 @@ return Def.ActorFrame {
ToastyDroppedMessageCommand=function(self,params)
if params.PlayerNumber == Player then
if HasToasty then
(cmd(finishtweening;stopeffect;glow,color("1,1,1,0.5");decelerate,0.35;diffuse,Colors.Alpha( Color("Black"), 0.25 );glow,color("1,1,1,0");linear,0.35*0.25;diffusealpha,0))(self);
(cmd(finishtweening;stopeffect;glow,color("1,1,1,0.5");decelerate,0.35;diffuse,Color.Alpha( Color("Black"), 0.25 );glow,color("1,1,1,0");linear,0.35*0.25;diffusealpha,0))(self);
HasToasty = false;
else
return
@@ -13,6 +13,7 @@ end
for s in ivalues(Stage) do
stages[#stages+1] = MakeBitmapTest() .. {
InitCommand=cmd(shadowlength,2);
SetCommand=function(self, params)
local Stage = GAMESTATE:GetCurrentStage();
local StageIndex = GAMESTATE:GetCurrentStageIndex();
@@ -2,7 +2,7 @@ return Def.ActorFrame {
--[[ LoadActor(THEME:GetPathG("ScreenTitleMenu","PreferenceFrame")) .. {
OnCommand=function(self)
if GetTimingDifficulty() == 7 then
(cmd(glowshift;diffuse,Color("Yellow");diffuserightedge,Color("Red");effectcolor1,Colors.Alpha( Color("Red"), 0.5 );effectcolor2,Color("Invisible");effectperiod,1.25/2))(self);
(cmd(glowshift;diffuse,Color("Yellow");diffuserightedge,Color("Red");effectcolor1,Color.Alpha( Color("Red"), 0.5 );effectcolor2,Color("Invisible");effectperiod,1.25/2))(self);
elseif GetTimingDifficulty() < 4 then
(cmd(diffuseshift;effectcolor1,Color("Blue");effectcolor2,ColorDarkTone(Color("Blue"));effectperiod,1.25))(self);
elseif GetTimingDifficulty() > 4 and GetTimingDifficulty < 6 then
@@ -69,7 +69,7 @@ else
self:settextf( "Stage %03i", RealStage);
self:diffuse( StageToColor('Stage_1st') );
self:diffusebottomedge( ColorMidTone(StageToColor('Stage_1st')) );
self:strokecolor( Colors.Alpha( ColorDarkTone(StageToColor('Stage_1st')), 0.75) );
self:strokecolor( Color.Alpha( ColorDarkTone(StageToColor('Stage_1st')), 0.75) );
end;
end;
}
+183
View File
@@ -0,0 +1,183 @@
[Screen]
HelpText=&BACK; Wyjście &START; Zatwierdź &SELECT; Opcje &MENULEFT;&MENURIGHT;&MENUUP;&MENUDOWN; Wybierz
[ScreenWithMenuElements]
HelpText=&BACK; Wyjście &START; Zatwierdź &MENULEFT;&MENURIGHT; Wybierz
[ScreenTitleMenu]
HelpText=&BACK; Wyjście &START; Zatwierdź &MENUUP;&MENUDOWN; Wybierz
Network OK=Sieć OK
Offline=Brak połączenia
Connected to %s=Podłączony do %s
CurrentGametype=Tryb gry: %s
LifeDifficulty=Zużycie energii: %s
TimingDifficulty=Ocena trafień: %s
[ScreenTitleJoin]
HelpText=Naciśnij &START; by rozpocząć grę
HelpTextJoin=Naciśnij &START; by rozpocząć grę
HelpTextWait=Wrzuć żeton...
EventMode=Tryb Imprezy
JointPremiumMain=Premia Łączona
JointPremiumSecondary=Dwóch graczy może grac za jeden kredyt!
DoublesPremiumMain=Podwójna Premia
DoublesPremiumSecondary=Graj w trybie Double za jeden kredyt!
[ScreenDemonstration]
Demonstration=Demonstracja
[ScreenQuickSetupOverview]
Explanation=Podstawowe ustawienia umożliwiają szybkie skonfigurowanie najczęściej używanych opcji
[ScreenProfileLoad]
HelpText=... Ładowanie profili, proszę czekać ...
[ScreenSelectProfile]
HelpText=&MENUUP;&MENUDOWN; Zmień profil &START; Wybierz/Dołącz &BACK; Odznacz
[ScreenSelectMaster]
HelpText=&BACK; Wyjście &START; Zatwierdź / Dołącz &MENULEFT;&MENURIGHT; Wybierz
[ScreenSelectPlayMode]
HelpText=&BACK; Wyjście &START; Zatwierdź / Dołącz &MENULEFT;&MENURIGHT; Wybierz
EasyExplanation=Tryb dla początkujących
HardExplanation=Dla ekspertów.
OldNormalExplanation=Nie za łatwo, nie za trudno.
NormalExplanation=Graj w swoje ulubione piosenki!
RaveExplanation=Bitwa dwóch graczy przeciwko sobie.
ExtendedExplanation=Kilka piosenek pod rząd.
OniExplanation=Prawdziwy test umiejętności.
EndlessExplanation=Tańcz aż padniesz.
[ScreenSelectPlayStyle]
HelpText=&BACK; Wyjście &START; Zatwierdź &MENULEFT;&MENURIGHT; Wybierz
[ScreenGameInformation]
HelpText=&BACK; Wyjście &START; Pomiń
[ScreenSelectMusic]
HelpText=&BACK; Wyjście &START; Zatwierdź / Dołącz &SELECT; Magiczne kody &MENULEFT;&MENURIGHT; Wybierz::&AUXWHITE;+[LITERA] Sortowanie wg. [LITERY]
AlternateHelpText=&SELECT;+&MENULEFT;&MENURIGHT; Zmiana poziomu trudności &SELECT;+&START; Wybór trybu sortowania
[ScreenSelectCourse]
HelpText=&BACK; Wyjście &START; Zatwierdź / Dołącz &SELECT; Magiczne kody &MENULEFT;&MENURIGHT; Sekwencja ::&UP;&DOWN;&UP;&DOWN; - inne tryby maratonu.
[ScreenOptions]
HelpText=&BACK; Wyjście &START; Zatwierdź &MENULEFT;&MENURIGHT;&MENUUP;&MENUDOWN; Wybierz
[ScreenStageInformation]
HelpText=
[ScreenGameplay]
HelpText=
[ScreenEvaluation]
HelpText=&BACK; Wyjście &START; Dalej &MENULEFT;+&MENURIGHT; or &SELECT; Screenshot
LifeDifficulty=Zużycie energii: %s
TimingDifficulty=Ocena trafień: %s
[OptionTitles]
UserPrefAutoSetStyle=Automatycznie Ustaw Styl
UserPrefNotePosition=Pozycja Strzałek
UserPrefComboOnRolls=Narastające combo w Rolls
UserPrefComboUnderField=Combo Pod Strzałkami
UserPrefGameplayShowScore=Pokazuj wyniki
UserPrefGameplayShowStepsDisplay=Pokazuj Kroki
UserPrefShowLotsaOptions=Ilość opcji
UserPrefLongFail=Tryb Fail`a
UserPrefFlashyCombo=Błyskające Combo
UserPrefGameplayFooter=Stopka Na Ekranie Gry
[OptionExplanations]
UserPrefAutoSetStyle=Pozwala grze jednoczesne wyświetlenie trybów dla dwóch graczy a nie tylko dla jednego. Wprowadzenie zmiany możne wymagać restartu Stepmanii (lub naciśnięcia klawisza F2)
UserPrefNotePosition=Określa pozycje receptorów strzałek podczas gry.
UserPrefComboOnRolls=Włącza naliczanie licznika Combo w sposób narastający dla strzałek typu ROLL.
UserPrefComboUnderField=Określa czy wskaźnik Combo powinien być wyświetlany nad czy pod strzałkami.
UserPrefGameplayShowScore=Wyświetla lub ukrywa licznik punktów podczas gry.
UserPrefGameplayShowStepsDisplay=Wyświetla lub ukrywa statystykę strzałek podczas gry.
UserPrefShowLotsaOptions=Określa jak dużo modyfikatorów wyświetlić na ekranie opcji piosenki.
UserPrefLongFail=Określa długość czasu animacji ogrywanej po niezaliczanej piosence. Oryginalny (Długi) z SM-SSC, nowy (Krotki)
UserPrefFlashyCombo=Określa czy licznik Combo może błyskać czy nie.
UserPrefGameplayFooter=Włączona opcja wyświetla, ograniczająca widoczność nadlatujących strzałek, stopkę u dołu ekranu.
ScoringType=Opcja pozwala na określenie metody naliczania punktacji.
Speed=Regulacja prędkości nadlatujących strzałek.
Accel=Zmiana ścieżki trasy która lecą strzałki.
Effect=Zmiana rozmiaru lub rodzaju ruchu strzałek lub ich receptorów/celów.
Appearance=Kontrola widoczności strzałek.
Turn=Zmiana choreografii stepchart`a po przez modyfikacje pozycji istniejących strzałek.
Insert=Zmiana choreografii stepchart`a po przez proceduralne dodanie nowych strzałek.
Holds=Zmienia cześć strzałki w HOLD`y
Mines=Dodanie lub usuniecie min.
PlayerAutoPlay=Program odgrywa piosenkę automatycznie
ScoreDisplay=Zmiana sposobu wyświetlania punktacji.
ProTiming=Zmiana sposobu wyświetlania dokładności trafienia w strzałkę.
Scroll=Modyfikacje kierunku ruchu strzałek.
NoteSkins=Wybór wyglądu grafiki strzałek/nut.
Remove=Usuwanie strzałek ze stepchart`a. Opcje ułatwiające ukończenie piosenki. Użycie dyskwalifikuje z rankingu.
Hide=Modyfikacja widoczności receptorów/strzałek celu
Persp=Tryby widoku nadlatujących strzałek.
Steps=Ustawienie poziomu trudności piosenki.
Characters=Wybór modelu tańczącej postaci w tle.
SaveToProfileHelp=Wymaga włączonego profilu, karty pamięci lub pendrive`a.
MusicRateHelp=Prędkość odtwarzania muzyki.
Attacks=Określa czy podczas gry będą użyte, nie będące częścią Maratonu, zdefiniowane w piosence, Ataki Modyfikatorowe.
[StepsListDisplayRow StepsType]
Dance_Single=4
Dance_Double=8
Dance_Couple=8
Dance_Solo=6
Dance_Routine=8
Dance_Threepanel=3
Pump_Single=5
Pump_Double=10
Pump_Halfdouble=6
Pump_Couple=5
Pump_Routine=10
Kb7_Single=7
Ez2_Single=ES
Ez2_Double=ED
Ez2_Real=ER
Para_Single=PS
Ds3ddx_Single=XS
Bm_Single5=5
Bm_Double5=10
Bm_Single7=7
Bm_Double7=14
Maniax_Single=MS
Maniax_Double=MD
Techno_Single4=4
Techno_Single5=5
Techno_Single8=8
Techno_Double4=D4
Techno_Double5=D5
Pnm_Five=5
Pnm_Nine=9
Guitar_Five=5
Karaoke=V
Lights_Cabinet=!
[ScreenHowToInstallSongs]
BodyHeader=Jak Zdobyć i Zainstalować Piosenki do Stepmanii
Finding Songs=Gdzie Znaleźć Piosenki
Installing Songs=Jak Zainstalować Piosenki
Importing Songs=Importowanie piosenek z zainstalowanych wcześniej wersji Stepmanii
Reload Songs=Przeładowanie Piosenek
Exit=Powrót do Ekranu Startowego
Explanation-WhereToFind=Uruchamia stronę www z informacja miejscach i sposobach na znalezienie piosenek.
Explanation-HowToInstall=Uruchamia stronę www z instrukcja instalacji piosenek.
Explanation-AdditionalFolders=Jeśli masz zainstalowane inne instancje Stepmanii, możesz użyć opcji AdditionalFolder z pliku ustawień by załadować je bez konieczności ich kopiowania.
Explanation-ReloadSongs=Ta czynność jest konieczna jeśli dodano/zmieniono/osunięto piosenki w trakcie pracy programu.
Explanation-Exit=Powrót do Ekranu Startowego.
[OptionNames]
Custom=Specjalny
[ScreenTestInput]
HelpText=Przytrzymaj &BACK; lub &START; aby wyjść.
+7 -6
View File
@@ -110,7 +110,7 @@ ItemsSpacingY=24
NumShownItems=8
[FadingBanner]
BannerFadeFromCachedCommand=diffusealpha,1;stoptweening;accelerate,0.05;glow,Colors.Alpha( Color("White"), 0.45 );decelerate,0.175;diffusealpha,0;glow,Color("Invisible");
BannerFadeFromCachedCommand=diffusealpha,1;stoptweening;accelerate,0.05;glow,Color.Alpha( Color("White"), 0.45 );decelerate,0.175;diffusealpha,0;glow,Color("Invisible");
[Gameplay]
@@ -422,7 +422,7 @@ end;
ShowAutogen=true
AutogenX=0
AutogenY=0
#AutogenOnCommand=diffuseshift;effectcolor1,Colors.Alpha( Color("Green") , 0.5 );effectcolor2,ColorLightTone( Color("Green") );
#AutogenOnCommand=diffuseshift;effectcolor1,Color.Alpha( Color("Green") , 0.5 );effectcolor2,ColorLightTone( Color("Green") );
AutogenOnCommand=blend,Blend.Add;diffuseshift;effectcolor1,color("#FFCC00FF");effectcolor2,color("#FFCC0088");
#
ShowStepsType=GetUserPrefB("UserPrefAutoSetStyle")
@@ -479,6 +479,7 @@ Fallback="StepsDisplay"
# end;
PillTransformFunction=function(self,offsetFromCenter,itemIndex,numItems) \
local fItemWidth = ( 256 / numItems ) \
self:x( ((itemIndex-(numItems/2))*fItemWidth) + ( numItems / 2 ) ); \
self:zoomtowidth(fItemWidth); \
end;
# PillTransformFunction=function(self,offsetFromCenter,itemIndex,numItems) \
@@ -489,8 +490,8 @@ end;
# self:effecttiming(1,0.01875*itemIndex,1,1-(0.01875*itemIndex)); \
# self:effectclock('beatnooffset'); \
# end;
TextureCoordScaleX=1
NumPills=1
TextureCoordScaleX=256/16
NumPills=16
[TextBanner]
TitleOnCommand=horizalign,left;shadowlength,1;
@@ -1333,10 +1334,10 @@ BPMDisplayY=SCREEN_BOTTOM-16
BPMDisplayOnCommand=draworder,101
BPMDisplayOffCommand=bounceend,0.25;zoom,0
#
ShowStageDisplay=false
ShowStageDisplay=true
StageDisplayX=SCREEN_CENTER_X
StageDisplayY=SCREEN_TOP+24
StageDisplayOnCommand=zoom,0.5;
StageDisplayOnCommand=zoom,0.675;
StageDisplayOffCommand=bounceend,0.25;zoom,0
#
ShowScoreFrame=GetUserPrefB("GameplayFooter");
+2
View File
@@ -47,6 +47,8 @@
<string>Step</string>
<key>CFBundleVersion</key>
<string>PRODUCT_VER_BARE</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.music-games</string>
<key>LSMinimumSystemVersion</key>
<string>10.4.10</string>
<key>NSHumanReadableCopyright</key>
+2 -2
View File
@@ -7918,7 +7918,7 @@
"-fno-exceptions",
"-falign-loops=16",
);
PRODUCT_NAME = "StepMania-debug";
PRODUCT_NAME = StepMania;
SYMROOT = "$(SRCROOT)/..";
WRAPPER_EXTENSION = app;
};
@@ -8629,7 +8629,7 @@
"-fno-exceptions",
"-falign-loops=16",
);
PRODUCT_NAME = "StepMania-FastDebug";
PRODUCT_NAME = StepMania;
STRIP_INSTALLED_PRODUCT = NO;
SYMROOT = "$(SRCROOT)/..";
WRAPPER_EXTENSION = app;
File diff suppressed because it is too large Load Diff
+41 -4
View File
@@ -52,8 +52,16 @@
SetDateSave on ; (can be on to have files restored to their orginal date)
; I think it may need actual admin privs for writing to the registry... -aj
; RequestExecutionLevel user
; this folder may not be the best idea for Windows Vista/7. -aj
;RequestExecutionLevel user
;GetVersion::WindowsServicePackMajor
;Pop $R0
;${If} $R0 >= 6
; vista & 7
;${Else}
; xp and below
;${EndIf}
InstallDir "$PROGRAMFILES\${PRODUCT_ID}"
InstallDirRegKey HKEY_LOCAL_MACHINE "SOFTWARE\${PRODUCT_ID}" ""
@@ -846,8 +854,37 @@ Section "Uninstall"
RMDir "$INSTDIR" ; will delete only if empty
SetShellVarContext current
Delete "$DESKTOP\Play StepMania CVS.lnk"
Delete "$DESKTOP\${PRODUCT_DISPLAY}.lnk"
; kill shortcuts
!ifdef MAKE_DESKTOP_SHORTCUT
Delete "$DESKTOP\$(TEXT_IO_RUN).lnk"
!endif
!ifdef MAKE_DESKTOP_SHORTCUT
Delete "$DESKTOP\$(TEXT_IO_RUN).lnk"
!endif
Delete "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_RUN).lnk"
Delete "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_RUN_WITHOUT_SSE2).lnk"
!ifdef MAKE_OPEN_PROGRAM_FOLDER_SHORTCUT
Delete "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_OPEN_PROGRAM_FOLDER).lnk"
!endif
!ifdef MAKE_OPEN_SETTINGS_FOLDER_SHORTCUT
Delete "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_OPEN_SETTINGS_FOLDER).lnk"
!endif
;Delete "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_VIEW_STATISTICS).lnk"
;Delete "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_TOOLS).lnk"
Delete "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_MANUAL).lnk"
Delete "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_UNINSTALL).lnk"
Delete "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_WEB_SITE).lnk"
Delete "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_TEXTURE_FONT_GENERATOR).lnk"
!ifdef MAKE_UPDATES_SHORTCUT
Delete "$SMPROGRAMS\${PRODUCT_ID}\$(TEXT_IO_CHECK_FOR_UPDATES).lnk"
!endif
Delete "$INSTDIR\${PRODUCT_ID}.lnk"
Delete "$INSTDIR\${PRODUCT_ID} (non-SSE2).lnk"
; I'm being paranoid here:
Delete "$SMPROGRAMS\${PRODUCT_ID}\*.*"
RMDir "$SMPROGRAMS\${PRODUCT_ID}"
+7 -6
View File
@@ -722,12 +722,13 @@ void Actor::UpdateInternal( float fDeltaTime )
// todo: account for SSC_FUTURES -aj
switch( m_Effect )
{
case spin:
m_current.rotation += m_fEffectDelta*m_vEffectMagnitude;
wrap( m_current.rotation.x, 360 );
wrap( m_current.rotation.y, 360 );
wrap( m_current.rotation.z, 360 );
break;
case spin:
m_current.rotation += m_fEffectDelta*m_vEffectMagnitude;
wrap( m_current.rotation.x, 360 );
wrap( m_current.rotation.y, 360 );
wrap( m_current.rotation.z, 360 );
break;
default: break;
}
UpdateTweening( fDeltaTime );
+27 -10
View File
@@ -266,14 +266,23 @@ void AdjustSync::AutosyncTempo()
GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds += fIntercept;
const float fScaleBPM = 1.0f/(1.0f - fSlope);
FOREACH( BPMSegment, GAMESTATE->m_pCurSong->m_SongTiming.m_BPMSegments, i )
i->SetBPM( i->GetBPM() * fScaleBPM );
TimingData &timing = GAMESTATE->m_pCurSong->m_SongTiming;
vector<TimingSegment *> &bpms = timing.allTimingSegments[SEGMENT_BPM];
for (unsigned i = 0; i < bpms.size(); i++)
{
BPMSegment *b = static_cast<BPMSegment *>(bpms[i]);
b->SetBPM(b->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_SongTiming.m_StopSegments, i )
i->SetPause(i->GetPause() * (1.0f - fSlope));
vector<TimingSegment *> &stops = timing.allTimingSegments[SEGMENT_STOP_DELAY];
for (unsigned i = 0; i < stops.size(); i++)
{
StopSegment *s = static_cast<StopSegment *>(stops[i]);
s->SetPause(s->GetPause() * (1.0f - fSlope));
}
SCREENMAN->SystemMessage( AUTOSYNC_CORRECTION_APPLIED.GetValue() );
}
@@ -343,10 +352,14 @@ void AdjustSync::GetSyncChangeTextSong( vector<RString> &vsAddTo )
}
}
for( unsigned i=0; i< testing.m_BPMSegments.size(); i++ )
vector<TimingSegment *> &bpmTest = testing.allTimingSegments[SEGMENT_BPM];
vector<TimingSegment *> &bpmOrig = original.allTimingSegments[SEGMENT_BPM];
for( unsigned i=0; i< bpmTest.size(); i++ )
{
float fOld = Quantize( original.m_BPMSegments[i].GetBPM(), 0.001f );
float fNew = Quantize( testing.m_BPMSegments[i].GetBPM(), 0.001f );
BPMSegment *bT = static_cast<BPMSegment *>(bpmTest[i]);
BPMSegment *bO = static_cast<BPMSegment *>(bpmOrig[i]);
float fOld = Quantize( bO->GetBPM(), 0.001f );
float fNew = Quantize( bT->GetBPM(), 0.001f );
float fDelta = fNew - fOld;
if( fabsf(fDelta) > 0.0001f )
@@ -364,10 +377,14 @@ void AdjustSync::GetSyncChangeTextSong( vector<RString> &vsAddTo )
}
}
for( unsigned i=0; i< testing.m_StopSegments.size(); i++ )
vector<TimingSegment *> &stopTest = testing.allTimingSegments[SEGMENT_STOP_DELAY];
vector<TimingSegment *> &stopOrig = original.allTimingSegments[SEGMENT_STOP_DELAY];
for( unsigned i=0; i< stopTest.size(); i++ )
{
float fOld = Quantize( original.m_StopSegments[i].GetPause(), 0.001f );
float fNew = Quantize( testing.m_StopSegments[i].GetPause(), 0.001f );
StopSegment *sT = static_cast<StopSegment *>(stopTest[i]);
StopSegment *sO = static_cast<StopSegment *>(stopOrig[i]);
float fOld = Quantize( sO->GetPause(), 0.001f );
float fNew = Quantize( sT->GetPause(), 0.001f );
float fDelta = fNew - fOld;
if( fabsf(fDelta) > 0.0001f )
+5 -5
View File
@@ -189,11 +189,11 @@ void BGAnimationLayer::LoadFromAniLayerFile( const RString& sPath )
switch( effect )
{
case EFFECT_STRETCH_SCROLL_LEFT: m_fTexCoordVelocityX = +0.5f; m_fTexCoordVelocityY = 0; break;
case EFFECT_STRETCH_SCROLL_RIGHT: m_fTexCoordVelocityX = -0.5f; m_fTexCoordVelocityY = 0; break;
case EFFECT_STRETCH_SCROLL_UP: m_fTexCoordVelocityX = 0; m_fTexCoordVelocityY = +0.5f; break;
case EFFECT_STRETCH_SCROLL_DOWN: m_fTexCoordVelocityX = 0; m_fTexCoordVelocityY = -0.5f; break;
break;
case EFFECT_STRETCH_SCROLL_LEFT: m_fTexCoordVelocityX = +0.5f; m_fTexCoordVelocityY = 0; break;
case EFFECT_STRETCH_SCROLL_RIGHT: m_fTexCoordVelocityX = -0.5f; m_fTexCoordVelocityY = 0; break;
case EFFECT_STRETCH_SCROLL_UP: m_fTexCoordVelocityX = 0; m_fTexCoordVelocityY = +0.5f; break;
case EFFECT_STRETCH_SCROLL_DOWN: m_fTexCoordVelocityX = 0; m_fTexCoordVelocityY = -0.5f; break;
default: break;
}
}
break;
+20 -14
View File
@@ -421,35 +421,41 @@ void BackgroundImpl::LoadFromRandom( float fFirstBeat, float fEndBeat, const Bac
const TimingData &timing = m_pSong->m_SongTiming;
// change BG every time signature change or 4 measures
FOREACH_CONST( TimeSignatureSegment, timing.m_vTimeSignatureSegments, iter )
const vector<TimingSegment *> &tSigs = timing.allTimingSegments[SEGMENT_TIME_SIG];
for (unsigned i = 0; i < tSigs.size(); i++)
{
vector<TimeSignatureSegment>::const_iterator next = iter;
next++;
int iSegmentEndRow = (next == timing.m_vTimeSignatureSegments.end()) ? iEndRow : next->GetRow();
TimeSignatureSegment *ts = static_cast<TimeSignatureSegment *>(tSigs[i]);
int iSegmentEndRow = (i + 1 == tSigs.size()) ? iEndRow : tSigs[i+1]->GetRow();
for( int i=max(iter->GetRow(),iStartRow); i<min(iEndRow,iSegmentEndRow); i+=4*iter->GetNoteRowsPerMeasure() )
for(int j=max(ts->GetRow(),iStartRow);
j<min(iEndRow,iSegmentEndRow);
j+=4*ts->GetNoteRowsPerMeasure())
{
// Don't fade. It causes frame rate dip, especially on slower machines.
BackgroundDef bd = m_Layer[0].CreateRandomBGA( m_pSong, change.m_def.m_sEffect, m_RandomBGAnimations, this );
BackgroundDef bd = m_Layer[0].CreateRandomBGA(m_pSong,
change.m_def.m_sEffect,
m_RandomBGAnimations, this);
if( !bd.IsEmpty() )
{
BackgroundChange c = change;
c.m_def = bd;
c.m_fStartBeat = NoteRowToBeat(i);
c.m_fStartBeat = NoteRowToBeat(j);
m_Layer[0].m_aBGChanges.push_back( c );
}
}
}
// change BG every BPM change that is at the beginning of a measure
for( unsigned i=0; i<timing.m_BPMSegments.size(); i++ )
const vector<TimingSegment *> &bpms = timing.allTimingSegments[SEGMENT_BPM];
for( unsigned i=0; i<bpms.size(); i++ )
{
const BPMSegment& bpmseg = timing.m_BPMSegments[i];
bool bAtBeginningOfMeasure = false;
FOREACH_CONST( TimeSignatureSegment, timing.m_vTimeSignatureSegments, iter )
for (unsigned j=0; j<tSigs.size(); j++)
{
if( (bpmseg.GetRow() - iter->GetRow()) % iter->GetNoteRowsPerMeasure() == 0 )
TimeSignatureSegment *ts = static_cast<TimeSignatureSegment *>(tSigs[j]);
if ((bpms[i]->GetRow() - ts->GetRow()) % ts->GetNoteRowsPerMeasure() == 0)
{
bAtBeginningOfMeasure = true;
break;
@@ -460,7 +466,7 @@ void BackgroundImpl::LoadFromRandom( float fFirstBeat, float fEndBeat, const Bac
continue; // skip
// start so that we don't create a BGChange right on top of fEndBeat
bool bInRange = bpmseg.GetRow() >= iStartRow && bpmseg.GetRow() < iEndRow;
bool bInRange = bpms[i]->GetRow() >= iStartRow && bpms[i]->GetRow() < iEndRow;
if( !bInRange )
continue; // skip
@@ -470,7 +476,7 @@ void BackgroundImpl::LoadFromRandom( float fFirstBeat, float fEndBeat, const Bac
BackgroundChange c = change;
c.m_def.m_sFile1 = bd.m_sFile1;
c.m_def.m_sFile2 = bd.m_sFile2;
c.m_fStartBeat = bpmseg.GetBeat();
c.m_fStartBeat = bpms[i]->GetBeat();
m_Layer[0].m_aBGChanges.push_back( c );
}
}
+19
View File
@@ -68,6 +68,25 @@ RString BackgroundChange::GetTextDescription() const
return s;
}
RString BackgroundChange::ToString() const
{
/* TODO: Technically we need to double-escape the filename
* (because it might contain '=') and then unescape the value
* returned by the MsdFile. */
return ssprintf("%.3f=%s=%.3f=%d=%d=%d=%s=%s=%s=%s=%s",
this->m_fStartBeat,
SmEscape(this->m_def.m_sFile1).c_str(),
this->m_fRate,
this->m_sTransition == SBT_CrossFade, // backward compat
this->m_def.m_sEffect == SBE_StretchRewind, // backward compat
this->m_def.m_sEffect != SBE_StretchNoLoop, // backward compat
this->m_def.m_sEffect.c_str(),
this->m_def.m_sFile2.c_str(),
this->m_sTransition.c_str(),
SmEscape(RageColor::NormalizeColorString(this->m_def.m_sColor1)).c_str(),
SmEscape(RageColor::NormalizeColorString(this->m_def.m_sColor2)).c_str());
}
const RString BACKGROUND_EFFECTS_DIR = "BackgroundEffects/";
const RString BACKGROUND_TRANSITIONS_DIR = "BackgroundTransitions/";
+5
View File
@@ -64,6 +64,11 @@ struct BackgroundChange
RString m_sTransition;
RString GetTextDescription() const;
/**
* @brief Get the string representation of the change.
* @return the string representation. */
RString ToString() const;
};
/** @brief Shared background-related routines. */
namespace BackgroundUtil
+6 -4
View File
@@ -429,12 +429,14 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail )
{
trail.Init();
// XXX: Why are beginner and challenge excluded here? -Wolfman2000
switch( cd )
{
case Difficulty_Beginner:
return false;
case Difficulty_Challenge:
return false;
case Difficulty_Beginner:
return false;
case Difficulty_Challenge:
return false;
default: break;
}
// Construct a new Trail, add it to the cache, then return it.
+5 -4
View File
@@ -131,10 +131,11 @@ DancingCharacters::DancingCharacters(): m_bDrawDangerLight(false),
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
m_pCharacter[p]->SetRotationY( MODEL_ROTATIONY_TWO_PLAYERS[p] );
break;
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
m_pCharacter[p]->SetRotationY( MODEL_ROTATIONY_TWO_PLAYERS[p] );
default:
break;
}
m_pCharacter[p]->LoadMilkshapeAscii( pChar->GetModelPath() );
+4 -4
View File
@@ -275,12 +275,12 @@ bool EditMenu::RowIsSelectable( EditMenuRow row )
{
switch( row )
{
case ROW_SOURCE_STEPS_TYPE:
case ROW_SOURCE_STEPS:
return false;
case ROW_SOURCE_STEPS_TYPE:
case ROW_SOURCE_STEPS:
return false;
default: return true;
}
}
return true;
}
+17 -17
View File
@@ -465,22 +465,21 @@ static bool AreStyleAndPlayModeCompatible( const Style *style, PlayMode pm )
switch( pm )
{
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
// Can't play rave if there isn't enough room for two players.
// This is correct for dance (ie, no rave for solo and doubles),
// and should be okay for pump.. not sure about other game types.
// Techno Motion scales down versus arrows, though, so allow this.
if( style->m_iColsPerPlayer >= 6 && RString(GAMESTATE->m_pCurGame->m_szName) != "techno" )
return false;
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
// Can't play rave if there isn't enough room for two players.
// This is correct for dance (ie, no rave for solo and doubles),
// and should be okay for pump.. not sure about other game types.
// Techno Motion scales down versus arrows, though, so allow this.
if( style->m_iColsPerPlayer >= 6 && RString(GAMESTATE->m_pCurGame->m_szName) != "techno" )
return false;
// Don't allow battle modes if the style takes both sides.
if( style->m_StyleType==StyleType_OnePlayerTwoSides ||
style->m_StyleType==StyleType_TwoPlayersSharedSides )
return false;
// Don't allow battle modes if the style takes both sides.
if( style->m_StyleType==StyleType_OnePlayerTwoSides ||
style->m_StyleType==StyleType_TwoPlayersSharedSides )
return false;
default: return true;
}
return true;
}
bool GameCommand::IsPlayable( RString *why ) const
@@ -500,9 +499,10 @@ bool GameCommand::IsPlayable( RString *why ) const
switch( GAMESTATE->GetCoinMode() )
{
case CoinMode_Home:
case CoinMode_Free:
iCredits = NUM_PLAYERS; // not iNumCreditsPaid
case CoinMode_Home:
case CoinMode_Free:
iCredits = NUM_PLAYERS; // not iNumCreditsPaid
default: break;
}
/* With PREFSMAN->m_bDelayedCreditsReconcile disabled, enough credits must
+2 -2
View File
@@ -60,8 +60,8 @@ struct MusicPlaying
RageSound *m_Music;
MusicPlaying( RageSound *Music )
{
m_Timing.AddBPMSegment( BPMSegment(0,120) );
m_NewTiming.AddBPMSegment( BPMSegment(0,120) );
m_Timing.AddSegment( SEGMENT_BPM, new BPMSegment(0,120) );
m_NewTiming.AddSegment( SEGMENT_BPM, new BPMSegment(0,120) );
m_bHasTiming = false;
m_bTimingDelayed = false;
m_bApplyMusicRate = false;
+19 -16
View File
@@ -747,7 +747,9 @@ void GameState::CancelStage()
{
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
m_iPlayerStageTokens[p] = PREFSMAN->m_iSongsPerPlay;
m_iPlayerStageTokens[p] = PREFSMAN->m_iSongsPerPlay;
default:
break;
}
}
@@ -1169,12 +1171,12 @@ bool GameState::IsPlayerEnabled( PlayerNumber pn ) const
// In rave, all players are present. Non-human players are CPU controlled.
switch( m_PlayMode )
{
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
return true;
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
return true;
default:
return IsHumanPlayer(pn);
}
return IsHumanPlayer( pn );
}
bool GameState::IsMultiPlayerEnabled( MultiPlayer mp ) const
@@ -1346,16 +1348,17 @@ StageResult GameState::GetStageResult( PlayerNumber pn ) const
{
switch( m_PlayMode )
{
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
if( fabsf(m_fTugLifePercentP1 - 0.5f) < 0.0001f )
return RESULT_DRAW;
switch( pn )
{
case PLAYER_1: return (m_fTugLifePercentP1>=0.5f)?RESULT_WIN:RESULT_LOSE;
case PLAYER_2: return (m_fTugLifePercentP1<0.5f)?RESULT_WIN:RESULT_LOSE;
default: ASSERT(0); return RESULT_LOSE;
}
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
if( fabsf(m_fTugLifePercentP1 - 0.5f) < 0.0001f )
return RESULT_DRAW;
switch( pn )
{
case PLAYER_1: return (m_fTugLifePercentP1>=0.5f)?RESULT_WIN:RESULT_LOSE;
case PLAYER_2: return (m_fTugLifePercentP1<0.5f)?RESULT_WIN:RESULT_LOSE;
default: FAIL_M("Invalid player for battle! Aborting..."); return RESULT_LOSE;
}
default: break;
}
StageResult win = RESULT_WIN;
+11 -8
View File
@@ -72,16 +72,19 @@ void Inventory::Load( PlayerState* pPlayerState )
// don't load battle sounds if they're not going to be used
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_BATTLE:
m_soundAcquireItem.Load( THEME->GetPathS("Inventory","aquire item") );
for( unsigned i=0; i<g_Items.size(); i++ )
case PLAY_MODE_BATTLE:
{
RageSound* pSound = new RageSound;
pSound->Load( THEME->GetPathS("Inventory",ssprintf("use item %u",i+1)) );
m_vpSoundUseItem.push_back( pSound );
m_soundAcquireItem.Load( THEME->GetPathS("Inventory","aquire item") );
for( unsigned i=0; i<g_Items.size(); i++ )
{
RageSound* pSound = new RageSound;
pSound->Load( THEME->GetPathS("Inventory",ssprintf("use item %u",i+1)) );
m_vpSoundUseItem.push_back( pSound );
}
m_soundItemEnding.Load( THEME->GetPathS("Inventory","item ending") );
break;
}
m_soundItemEnding.Load( THEME->GetPathS("Inventory","item ending") );
break;
default: break;
}
}
+31
View File
@@ -31,6 +31,24 @@ namespace JsonUtil
for(unsigned i=0; i<v.size(); i++)
fn(*v[i], root[i]);
}
template<class T>
static void SerializeVectorPointers(const vector<T*> &v, void fn(const T &, Json::Value &), Json::Value &root)
{
root = Json::Value(Json::arrayValue);
root.resize(v.size());
for(unsigned i=0; i<v.size(); i++)
fn(*v[i], root[i]);
}
template<class T>
static void SerializeVectorPointers(const vector<const T*> &v, void fn(const T *, Json::Value &), Json::Value &root)
{
root = Json::Value(Json::arrayValue);
root.resize(v.size());
for(unsigned i=0; i<v.size(); i++)
fn(*v[i], root[i]);
}
template<typename V, typename T>
static void SerializeArray(const V &v, void fn(const T &, Json::Value &), Json::Value &root)
@@ -149,6 +167,19 @@ namespace JsonUtil
fn(*v[i], root[i]);
}
}
template<class T>
static void DeserializeVectorPointers(vector<T*> &v, void fn(T *, const Json::Value &), const Json::Value &root)
{
for(unsigned i=0; i<v.size(); i++)
SAFE_DELETE(v[i]);
v.resize(root.size());
for(unsigned i=0; i<v.size(); i++)
{
v[i] = new T;
fn(*v[i], root[i]);
}
}
template<class T>
static void DeserializeArrayValues(vector<T> &v, const Json::Value &root)
+7 -6
View File
@@ -212,12 +212,13 @@ void LifeMeterBar::ChangeLife( float fDeltaLife )
switch( GAMESTATE->m_SongOptions.GetSong().m_DrainType )
{
case SongOptions::DRAIN_NORMAL:
case SongOptions::DRAIN_NO_RECOVER:
if( fDeltaLife > 0 )
fDeltaLife *= m_fLifeDifficulty;
else
fDeltaLife /= m_fLifeDifficulty;
case SongOptions::DRAIN_NORMAL:
case SongOptions::DRAIN_NO_RECOVER:
if( fDeltaLife > 0 )
fDeltaLife *= m_fLifeDifficulty;
else
fDeltaLife /= m_fLifeDifficulty;
default:
break;
}
+32 -30
View File
@@ -449,22 +449,23 @@ void MemoryCardManager::CheckStateChanges()
{
switch( new_device.m_State )
{
case UsbStorageDevice::STATE_NONE:
state = MemoryCardState_NoCard;
break;
case UsbStorageDevice::STATE_NONE:
state = MemoryCardState_NoCard;
break;
case UsbStorageDevice::STATE_CHECKING:
state = MemoryCardState_Checking;
break;
case UsbStorageDevice::STATE_CHECKING:
state = MemoryCardState_Checking;
break;
case UsbStorageDevice::STATE_ERROR:
state = MemoryCardState_Error;
sError = new_device.m_sError;
break;
case UsbStorageDevice::STATE_ERROR:
state = MemoryCardState_Error;
sError = new_device.m_sError;
break;
case UsbStorageDevice::STATE_READY:
state = MemoryCardState_Ready;
break;
case UsbStorageDevice::STATE_READY:
state = MemoryCardState_Ready;
break;
default: break;
}
}
@@ -476,23 +477,24 @@ void MemoryCardManager::CheckStateChanges()
params.m_bIsCriticalSound = true;
switch( state )
{
case MemoryCardState_NoCard:
case MemoryCardState_Removed:
if( LastState == MemoryCardState_Ready )
{
m_soundDisconnect.Play( &params );
MESSAGEMAN->Broadcast( (MessageID)(Message_CardRemovedP1+p) );
}
break;
case MemoryCardState_Ready:
m_soundReady.Play( &params );
break;
case MemoryCardState_TooLate:
m_soundTooLate.Play( &params );
break;
case MemoryCardState_Error:
m_soundError.Play( &params );
break;
case MemoryCardState_NoCard:
case MemoryCardState_Removed:
if( LastState == MemoryCardState_Ready )
{
m_soundDisconnect.Play( &params );
MESSAGEMAN->Broadcast( (MessageID)(Message_CardRemovedP1+p) );
}
break;
case MemoryCardState_Ready:
m_soundReady.Play( &params );
break;
case MemoryCardState_TooLate:
m_soundTooLate.Play( &params );
break;
case MemoryCardState_Error:
m_soundError.Play( &params );
break;
default: break;
}
m_State[p] = state;
+173 -171
View File
@@ -42,23 +42,23 @@ static SortOrder ForceAppropriateSort( PlayMode pm, SortOrder so )
{
switch( pm )
{
// in course modes, force a particular sort
case PLAY_MODE_ONI: return SORT_ONI_COURSES;
case PLAY_MODE_NONSTOP: return SORT_NONSTOP_COURSES;
case PLAY_MODE_ENDLESS: return SORT_ENDLESS_COURSES;
// in course modes, force a particular sort
case PLAY_MODE_ONI: return SORT_ONI_COURSES;
case PLAY_MODE_NONSTOP: return SORT_NONSTOP_COURSES;
case PLAY_MODE_ENDLESS: return SORT_ENDLESS_COURSES;
default: break;
}
// If we're not in a course mode, don't start in a course sort.
switch( so )
{
case SORT_ONI_COURSES:
case SORT_NONSTOP_COURSES:
case SORT_ENDLESS_COURSES:
so = SortOrder_Invalid;
break;
case SORT_ONI_COURSES:
case SORT_NONSTOP_COURSES:
case SORT_ENDLESS_COURSES:
so = SortOrder_Invalid;
default:
return so;
}
return so;
}
MusicWheelItem *MusicWheel::MakeItem()
@@ -490,7 +490,7 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
{
switch( so )
{
case SORT_MODE_MENU:
case SORT_MODE_MENU:
{
arrayWheelItemDatas.clear(); // clear out the previous wheel items
vector<RString> vsNames;
@@ -510,22 +510,22 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
}
break;
}
case SORT_PREFERRED:
case SORT_ROULETTE:
case SORT_GROUP:
case SORT_TITLE:
case SORT_BPM:
case SORT_POPULARITY:
case SORT_TOP_GRADES:
case SORT_ARTIST:
case SORT_GENRE:
case SORT_BEGINNER_METER:
case SORT_EASY_METER:
case SORT_MEDIUM_METER:
case SORT_HARD_METER:
case SORT_CHALLENGE_METER:
case SORT_LENGTH:
case SORT_RECENT:
case SORT_PREFERRED:
case SORT_ROULETTE:
case SORT_GROUP:
case SORT_TITLE:
case SORT_BPM:
case SORT_POPULARITY:
case SORT_TOP_GRADES:
case SORT_ARTIST:
case SORT_GENRE:
case SORT_BEGINNER_METER:
case SORT_EASY_METER:
case SORT_MEDIUM_METER:
case SORT_HARD_METER:
case SORT_CHALLENGE_METER:
case SORT_LENGTH:
case SORT_RECENT:
{
// Make an array of Song*, then sort them
vector<Song*> arraySongs;
@@ -536,72 +536,72 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
// sort the songs
switch( so )
{
case SORT_PREFERRED:
// obey order specified by the preferred sort list
break;
case SORT_ROULETTE:
{
StepsType st;
Difficulty dc;
SongUtil::GetStepsTypeAndDifficultyFromSortOrder( SORT_EASY_METER, st, dc );
SongUtil::SortSongPointerArrayByStepsTypeAndMeter( arraySongs, st, dc );
if( (bool)PREFSMAN->m_bPreferredSortUsesGroups )
stable_sort( arraySongs.begin(), arraySongs.end(), SongUtil::CompareSongPointersByGroup );
bUseSections = false;
break;
}
case SORT_GROUP:
SongUtil::SortSongPointerArrayByGroupAndTitle( arraySongs );
if(USE_SECTIONS_WITH_PREFERRED_GROUP)
bUseSections = true;
else
bUseSections = GAMESTATE->m_sPreferredSongGroup == GROUP_ALL;
break;
case SORT_TITLE:
SongUtil::SortSongPointerArrayByTitle( arraySongs );
break;
case SORT_BPM:
SongUtil::SortSongPointerArrayByBPM( arraySongs );
break;
case SORT_POPULARITY:
if( (int) arraySongs.size() > MOST_PLAYED_SONGS_TO_SHOW )
arraySongs.erase( arraySongs.begin()+MOST_PLAYED_SONGS_TO_SHOW, arraySongs.end() );
bUseSections = false;
break;
case SORT_TOP_GRADES:
SongUtil::SortSongPointerArrayByGrades( arraySongs, true );
break;
case SORT_ARTIST:
SongUtil::SortSongPointerArrayByArtist( arraySongs );
break;
case SORT_GENRE:
SongUtil::SortSongPointerArrayByGenre( arraySongs );
break;
case SORT_LENGTH:
SongUtil::SortSongPointerArrayByLength( arraySongs );
break;
case SORT_RECENT:
SongUtil::SortByMostRecentlyPlayedForMachine( arraySongs );
if( (int) arraySongs.size() > RECENT_SONGS_TO_SHOW )
arraySongs.erase( arraySongs.begin()+RECENT_SONGS_TO_SHOW, arraySongs.end() );
bUseSections = false;
break;
case SORT_BEGINNER_METER:
case SORT_EASY_METER:
case SORT_MEDIUM_METER:
case SORT_HARD_METER:
case SORT_CHALLENGE_METER:
case SORT_DOUBLE_EASY_METER:
case SORT_DOUBLE_MEDIUM_METER:
case SORT_DOUBLE_HARD_METER:
case SORT_DOUBLE_CHALLENGE_METER:
StepsType st;
Difficulty dc;
SongUtil::GetStepsTypeAndDifficultyFromSortOrder( so, st, dc );
SongUtil::SortSongPointerArrayByStepsTypeAndMeter( arraySongs, st, dc );
break;
default:
ASSERT(0); // unhandled SortOrder
case SORT_PREFERRED:
// obey order specified by the preferred sort list
break;
case SORT_ROULETTE:
{
StepsType st;
Difficulty dc;
SongUtil::GetStepsTypeAndDifficultyFromSortOrder( SORT_EASY_METER, st, dc );
SongUtil::SortSongPointerArrayByStepsTypeAndMeter( arraySongs, st, dc );
if( (bool)PREFSMAN->m_bPreferredSortUsesGroups )
stable_sort( arraySongs.begin(), arraySongs.end(), SongUtil::CompareSongPointersByGroup );
bUseSections = false;
break;
}
case SORT_GROUP:
SongUtil::SortSongPointerArrayByGroupAndTitle( arraySongs );
if(USE_SECTIONS_WITH_PREFERRED_GROUP)
bUseSections = true;
else
bUseSections = GAMESTATE->m_sPreferredSongGroup == GROUP_ALL;
break;
case SORT_TITLE:
SongUtil::SortSongPointerArrayByTitle( arraySongs );
break;
case SORT_BPM:
SongUtil::SortSongPointerArrayByBPM( arraySongs );
break;
case SORT_POPULARITY:
if( (int) arraySongs.size() > MOST_PLAYED_SONGS_TO_SHOW )
arraySongs.erase( arraySongs.begin()+MOST_PLAYED_SONGS_TO_SHOW, arraySongs.end() );
bUseSections = false;
break;
case SORT_TOP_GRADES:
SongUtil::SortSongPointerArrayByGrades( arraySongs, true );
break;
case SORT_ARTIST:
SongUtil::SortSongPointerArrayByArtist( arraySongs );
break;
case SORT_GENRE:
SongUtil::SortSongPointerArrayByGenre( arraySongs );
break;
case SORT_LENGTH:
SongUtil::SortSongPointerArrayByLength( arraySongs );
break;
case SORT_RECENT:
SongUtil::SortByMostRecentlyPlayedForMachine( arraySongs );
if( (int) arraySongs.size() > RECENT_SONGS_TO_SHOW )
arraySongs.erase( arraySongs.begin()+RECENT_SONGS_TO_SHOW, arraySongs.end() );
bUseSections = false;
break;
case SORT_BEGINNER_METER:
case SORT_EASY_METER:
case SORT_MEDIUM_METER:
case SORT_HARD_METER:
case SORT_CHALLENGE_METER:
case SORT_DOUBLE_EASY_METER:
case SORT_DOUBLE_MEDIUM_METER:
case SORT_DOUBLE_HARD_METER:
case SORT_DOUBLE_CHALLENGE_METER:
StepsType st;
Difficulty dc;
SongUtil::GetStepsTypeAndDifficultyFromSortOrder( so, st, dc );
SongUtil::SortSongPointerArrayByStepsTypeAndMeter( arraySongs, st, dc );
break;
default:
FAIL_M("Unhandled sort order! Aborting...");
}
// Build an array of WheelItemDatas from the sorted list of Song*'s
@@ -610,13 +610,15 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
switch( PREFSMAN->m_MusicWheelUsesSections )
{
case MusicWheelUsesSections_NEVER:
bUseSections = false;
break;
case MusicWheelUsesSections_ABC_ONLY:
if( so != SORT_TITLE && so != SORT_GROUP )
case MusicWheelUsesSections_NEVER:
bUseSections = false;
break;
break;
case MusicWheelUsesSections_ABC_ONLY:
if( so != SORT_TITLE && so != SORT_GROUP )
bUseSections = false;
break;
default:
break;
}
if( bUseSections )
@@ -630,13 +632,13 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
/* We're using sections, so use the section name as the top-level sort. */
switch( so )
{
case SORT_PREFERRED:
case SORT_TOP_GRADES:
case SORT_BPM:
break; // don't sort by section
default:
SongUtil::SortSongPointerArrayBySectionName(arraySongs, so);
break;
case SORT_PREFERRED:
case SORT_TOP_GRADES:
case SORT_BPM:
break; // don't sort by section
default:
SongUtil::SortSongPointerArrayBySectionName(arraySongs, so);
break;
}
}
@@ -731,10 +733,10 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
}
break;
}
case SORT_ALL_COURSES:
case SORT_NONSTOP_COURSES:
case SORT_ONI_COURSES:
case SORT_ENDLESS_COURSES:
case SORT_ALL_COURSES:
case SORT_NONSTOP_COURSES:
case SORT_ONI_COURSES:
case SORT_ENDLESS_COURSES:
{
bool bOnlyPreferred = PREFSMAN->m_CourseSortOrder == COURSE_SORT_PREFERRED;
@@ -769,21 +771,21 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
switch( PREFSMAN->m_CourseSortOrder )
{
case COURSE_SORT_SONGS:
CourseUtil::SortCoursePointerArrayByDifficulty( apCourses );
break;
case COURSE_SORT_PREFERRED:
break;
case COURSE_SORT_METER:
CourseUtil::SortCoursePointerArrayByAvgDifficulty( apCourses );
break;
case COURSE_SORT_METER_SUM:
CourseUtil::SortCoursePointerArrayByTotalDifficulty( apCourses );
break;
case COURSE_SORT_RANK:
CourseUtil::SortCoursePointerArrayByRanking( apCourses );
break;
default: ASSERT(0);
case COURSE_SORT_SONGS:
CourseUtil::SortCoursePointerArrayByDifficulty( apCourses );
break;
case COURSE_SORT_PREFERRED:
break;
case COURSE_SORT_METER:
CourseUtil::SortCoursePointerArrayByAvgDifficulty( apCourses );
break;
case COURSE_SORT_METER_SUM:
CourseUtil::SortCoursePointerArrayByTotalDifficulty( apCourses );
break;
case COURSE_SORT_RANK:
CourseUtil::SortCoursePointerArrayByRanking( apCourses );
break;
default: FAIL_M("Impossible to sort the courses! Aborting...");
}
// since we can't agree, make it an option
@@ -810,9 +812,10 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
{
switch( pCourse->GetPlayMode() )
{
case PLAY_MODE_ONI: sThisSection = "Oni"; break;
case PLAY_MODE_NONSTOP: sThisSection = "Nonstop"; break;
case PLAY_MODE_ENDLESS: sThisSection = "Endless"; break;
case PLAY_MODE_ONI: sThisSection = "Oni"; break;
case PLAY_MODE_NONSTOP: sThisSection = "Nonstop"; break;
case PLAY_MODE_ENDLESS: sThisSection = "Endless"; break;
default: break;
}
}
@@ -833,6 +836,8 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
}
break;
}
default:
break;
}
// init music status icons
@@ -1227,23 +1232,24 @@ bool MusicWheel::Select() // return true if this selection ends the screen
switch( m_WheelState )
{
case STATE_FLYING_OFF_BEFORE_NEXT_SORT:
case STATE_ROULETTE_SLOWING_DOWN:
return false;
case STATE_ROULETTE_SPINNING:
m_WheelState = STATE_ROULETTE_SLOWING_DOWN;
m_iSwitchesLeftInSpinDown = ROULETTE_SLOW_DOWN_SWITCHES/2+1 + RandomInt( ROULETTE_SLOW_DOWN_SWITCHES/2 );
m_fTimeLeftInState = 0.1f;
return false;
case STATE_RANDOM_SPINNING:
m_fPositionOffsetFromSelection = max(m_fPositionOffsetFromSelection, 0.3f);
m_WheelState = STATE_LOCKED;
SCREENMAN->PlayStartSound();
m_fLockedWheelVelocity = 0;
// Set m_Moving to zero to stop the sounds from playing.
m_Moving = 0;
SCREENMAN->PostMessageToTopScreen( SM_SongChanged, 0 );
return true;
case STATE_FLYING_OFF_BEFORE_NEXT_SORT:
case STATE_ROULETTE_SLOWING_DOWN:
return false;
case STATE_ROULETTE_SPINNING:
m_WheelState = STATE_ROULETTE_SLOWING_DOWN;
m_iSwitchesLeftInSpinDown = ROULETTE_SLOW_DOWN_SWITCHES/2+1 + RandomInt( ROULETTE_SLOW_DOWN_SWITCHES/2 );
m_fTimeLeftInState = 0.1f;
return false;
case STATE_RANDOM_SPINNING:
m_fPositionOffsetFromSelection = max(m_fPositionOffsetFromSelection, 0.3f);
m_WheelState = STATE_LOCKED;
SCREENMAN->PlayStartSound();
m_fLockedWheelVelocity = 0;
// Set m_Moving to zero to stop the sounds from playing.
m_Moving = 0;
SCREENMAN->PostMessageToTopScreen( SM_SongChanged, 0 );
return true;
default: break;
}
if( !WheelBase::Select() )
@@ -1251,29 +1257,25 @@ bool MusicWheel::Select() // return true if this selection ends the screen
switch( m_CurWheelItemData[m_iSelection]->m_Type )
{
case TYPE_ROULETTE:
StartRoulette();
return false;
case TYPE_RANDOM:
StartRandom();
return false;
case TYPE_SONG:
case TYPE_COURSE:
case TYPE_PORTAL:
break;
case TYPE_SORT:
GetCurWheelItemData(m_iSelection)->m_pAction->ApplyToAllPlayers();
ChangeSort( GAMESTATE->m_PreferredSortOrder );
m_sLastModeMenuItem = GetCurWheelItemData(m_iSelection)->m_pAction->m_sName;
return false;
case TYPE_CUSTOM:
GetCurWheelItemData(m_iSelection)->m_pAction->ApplyToAllPlayers();
if( GetCurWheelItemData(m_iSelection)->m_pAction->m_sScreen != "" )
return true;
else
case TYPE_ROULETTE:
StartRoulette();
return false;
case TYPE_RANDOM:
StartRandom();
return false;
case TYPE_SORT:
GetCurWheelItemData(m_iSelection)->m_pAction->ApplyToAllPlayers();
ChangeSort( GAMESTATE->m_PreferredSortOrder );
m_sLastModeMenuItem = GetCurWheelItemData(m_iSelection)->m_pAction->m_sName;
return false;
case TYPE_CUSTOM:
GetCurWheelItemData(m_iSelection)->m_pAction->ApplyToAllPlayers();
if( GetCurWheelItemData(m_iSelection)->m_pAction->m_sScreen != "" )
return true;
else
return false;
default: return true;
}
return true;
}
void MusicWheel::StartRoulette()
@@ -1517,11 +1519,11 @@ Song* MusicWheel::GetSelectedSong()
{
switch( m_CurWheelItemData[m_iSelection]->m_Type )
{
case TYPE_PORTAL:
return GetPreferredSelectionForRandomOrPortal();
case TYPE_PORTAL:
return GetPreferredSelectionForRandomOrPortal();
default:
return GetCurWheelItemData(m_iSelection)->m_pSong;
}
return GetCurWheelItemData(m_iSelection)->m_pSong;
}
/* Find a random song. If possible, find one that has the preferred difficulties of
+6 -4
View File
@@ -547,10 +547,12 @@ bool NoteData::RowNeedsAtLeastSimultaneousPresses( int iMinSimultaneousPresses,
const TapNote &tn = GetTapNote(t, row);
switch( tn.type )
{
case TapNote::mine:
case TapNote::empty:
case TapNote::fake:
continue; // skip these types - they don't count
case TapNote::mine:
case TapNote::empty:
case TapNote::fake:
case TapNote::lift: // you don't "press" on a lift.
continue; // skip these types - they don't count
default: break;
}
++iNumNotesThisIndex;
}
+11 -9
View File
@@ -800,11 +800,12 @@ RadarStats CalculateRadarStatsFast( const NoteData &in, RadarStats &out )
const TapNote &tn = in.GetTapNote(t, r);
switch( tn.type )
{
case TapNote::mine:
case TapNote::empty:
case TapNote::fake:
case TapNote::autoKeysound:
continue; // skip these types - they don't count
case TapNote::mine:
case TapNote::empty:
case TapNote::fake:
case TapNote::autoKeysound:
continue; // skip these types - they don't count
default: break;
}
if( (itr = simultaneousMap.find(r)) == simultaneousMap.end() )
@@ -830,10 +831,11 @@ RadarStats CalculateRadarStatsFast( const NoteData &in, RadarStats &out )
{
switch( in.GetTapNote(t, rr).type )
{
case TapNote::mine:
case TapNote::empty:
case TapNote::fake:
continue; // skip these types - they don't count
case TapNote::mine:
case TapNote::empty:
case TapNote::fake:
continue; // skip these types - they don't count
default: break;
}
if( (itr = simultaneousMap.find(rr)) == simultaneousMap.end() )
simultaneousMap[rr] = 1;
+53 -42
View File
@@ -849,27 +849,26 @@ void NoteField::DrawPrimitives()
}
const TimingData *pTiming = GetDisplayedTiming(m_pPlayerState);
const vector<TimingSegment *> *segs = pTiming->allTimingSegments;
unsigned i = 0;
// Draw beat bars
if( ( GAMESTATE->IsEditing() || SHOW_BEAT_BARS ) && pTiming != NULL )
{
const TimingData &timing = *pTiming;
const vector<TimeSignatureSegment> &vTimeSignatureSegments = timing.m_vTimeSignatureSegments;
const vector<TimingSegment *> &tSigs = segs[SEGMENT_TIME_SIG];
int iMeasureIndex = 0;
FOREACH_CONST( TimeSignatureSegment, vTimeSignatureSegments, iter )
for (i = 0; i < tSigs.size(); i++)
{
vector<TimeSignatureSegment>::const_iterator next = iter;
next++;
int iSegmentEndRow = (next == vTimeSignatureSegments.end()) ? iLastRowToDraw : next->GetRow();
TimeSignatureSegment *ts = static_cast<TimeSignatureSegment *>(tSigs[i]);
int iSegmentEndRow = (i + 1 == tSigs.size()) ? iLastRowToDraw : tSigs[i+1]->GetRow();
// beat bars every 16th note
int iDrawBeatBarsEveryRows = BeatToNoteRow( ((float)iter->GetDen()) / 4 ) / 4;
int iDrawBeatBarsEveryRows = BeatToNoteRow( ((float)ts->GetDen()) / 4 ) / 4;
// In 4/4, every 16th beat bar is a measure
int iMeasureBarFrequency = iter->GetNum() * 4;
int iMeasureBarFrequency = ts->GetNum() * 4;
int iBeatBarsDrawn = 0;
for( int i=iter->GetRow(); i < iSegmentEndRow; i += iDrawBeatBarsEveryRows )
for( int j=ts->GetRow(); j < iSegmentEndRow; j += iDrawBeatBarsEveryRows )
{
bool bMeasureBar = iBeatBarsDrawn % iMeasureBarFrequency == 0;
BeatBarType type = quarter_beat;
@@ -879,7 +878,7 @@ void NoteField::DrawPrimitives()
type = beat;
else if( iBeatBarsDrawn % 2 == 0 )
type = half_beat;
float fBeat = NoteRowToBeat(i);
float fBeat = NoteRowToBeat(j);
if( IS_ON_SCREEN(fBeat) )
{
@@ -902,8 +901,9 @@ void NoteField::DrawPrimitives()
// Scroll text
if( GAMESTATE->m_bIsUsingStepTiming )
{
FOREACH_CONST( ScrollSegment, timing.m_ScrollSegments, seg )
for (i = 0; i < segs[SEGMENT_SCROLL].size(); i++)
{
ScrollSegment *seg = static_cast<ScrollSegment *>(segs[SEGMENT_SCROLL][i]);
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
{
float fBeat = seg->GetBeat();
@@ -914,8 +914,9 @@ void NoteField::DrawPrimitives()
}
// BPM text
FOREACH_CONST( BPMSegment, timing.m_BPMSegments, seg )
for (i = 0; i < segs[SEGMENT_BPM].size(); i++)
{
BPMSegment *seg = static_cast<BPMSegment *>(segs[SEGMENT_BPM][i]);
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
{
float fBeat = seg->GetBeat();
@@ -925,8 +926,9 @@ void NoteField::DrawPrimitives()
}
// Freeze text
FOREACH_CONST( StopSegment, timing.m_StopSegments, seg )
for (i = 0; i < segs[SEGMENT_STOP_DELAY].size(); i++)
{
StopSegment *seg = static_cast<StopSegment *>(segs[SEGMENT_STOP_DELAY][i]);
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
{
float fBeat = seg->GetBeat();
@@ -936,8 +938,9 @@ void NoteField::DrawPrimitives()
}
// Warp text
FOREACH_CONST( WarpSegment, timing.m_WarpSegments, seg )
for (i = 0; i < segs[SEGMENT_WARP].size(); i++)
{
WarpSegment *seg = static_cast<WarpSegment *>(segs[SEGMENT_WARP][i]);
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
{
float fBeat = seg->GetBeat();
@@ -948,8 +951,9 @@ void NoteField::DrawPrimitives()
// Time Signature text
FOREACH_CONST( TimeSignatureSegment, timing.m_vTimeSignatureSegments, seg )
for (i = 0; i < segs[SEGMENT_TIME_SIG].size(); i++)
{
TimeSignatureSegment *seg = static_cast<TimeSignatureSegment *>(segs[SEGMENT_TIME_SIG][i]);
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
{
float fBeat = seg->GetBeat();
@@ -961,8 +965,9 @@ void NoteField::DrawPrimitives()
if( GAMESTATE->m_bIsUsingStepTiming )
{
// Tickcount text
FOREACH_CONST( TickcountSegment, timing.m_TickcountSegments, seg )
for (i = 0; i < segs[SEGMENT_TICKCOUNT].size(); i++)
{
TickcountSegment *seg = static_cast<TickcountSegment *>(segs[SEGMENT_TICKCOUNT][i]);
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
{
float fBeat = seg->GetBeat();
@@ -975,8 +980,9 @@ void NoteField::DrawPrimitives()
if( GAMESTATE->m_bIsUsingStepTiming )
{
// Combo text
FOREACH_CONST( ComboSegment, timing.m_ComboSegments, seg )
for (i = 0; i < segs[SEGMENT_COMBO].size(); i++)
{
ComboSegment *seg = static_cast<ComboSegment *>(segs[SEGMENT_COMBO][i]);
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
{
float fBeat = seg->GetBeat();
@@ -987,8 +993,9 @@ void NoteField::DrawPrimitives()
}
// Label text
FOREACH_CONST( LabelSegment, timing.m_LabelSegments, seg )
for (i = 0; i < segs[SEGMENT_LABEL].size(); i++)
{
LabelSegment *seg = static_cast<LabelSegment *>(segs[SEGMENT_LABEL][i]);
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
{
float fBeat = seg->GetBeat();
@@ -999,8 +1006,10 @@ void NoteField::DrawPrimitives()
if( GAMESTATE->m_bIsUsingStepTiming )
{
FOREACH_CONST( SpeedSegment, timing.m_SpeedSegments, seg )
// Speed text
for (i = 0; i < segs[SEGMENT_SPEED].size(); i++)
{
SpeedSegment *seg = static_cast<SpeedSegment *>(segs[SEGMENT_SPEED][i]);
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
{
float fBeat = seg->GetBeat();
@@ -1011,11 +1020,12 @@ void NoteField::DrawPrimitives()
}
}
// Speed text
// Fake text
if( GAMESTATE->m_bIsUsingStepTiming )
{
FOREACH_CONST( FakeSegment, timing.m_FakeSegments, seg )
for (i = 0; i < segs[SEGMENT_FAKE].size(); i++)
{
FakeSegment *seg = static_cast<FakeSegment *>(segs[SEGMENT_FAKE][i]);
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
{
float fBeat = seg->GetBeat();
@@ -1074,55 +1084,55 @@ void NoteField::DrawPrimitives()
case EditMode_Full:
{
vector<BackgroundChange>::iterator iter[NUM_BackgroundLayer];
FOREACH_BackgroundLayer( i )
iter[i] = GAMESTATE->m_pCurSong->GetBackgroundChanges(i).begin();
FOREACH_BackgroundLayer( j )
iter[j] = GAMESTATE->m_pCurSong->GetBackgroundChanges(j).begin();
while( 1 )
{
float fLowestBeat = FLT_MAX;
vector<BackgroundLayer> viLowestIndex;
FOREACH_BackgroundLayer( i )
FOREACH_BackgroundLayer( j )
{
if( iter[i] == GAMESTATE->m_pCurSong->GetBackgroundChanges(i).end() )
if( iter[j] == GAMESTATE->m_pCurSong->GetBackgroundChanges(j).end() )
continue;
float fBeat = iter[i]->m_fStartBeat;
float fBeat = iter[j]->m_fStartBeat;
if( fBeat < fLowestBeat )
{
fLowestBeat = fBeat;
viLowestIndex.clear();
viLowestIndex.push_back( i );
viLowestIndex.push_back( j );
}
else if( fBeat == fLowestBeat )
{
viLowestIndex.push_back( i );
viLowestIndex.push_back( j );
}
}
if( viLowestIndex.empty() )
{
FOREACH_BackgroundLayer( i )
ASSERT( iter[i] == GAMESTATE->m_pCurSong->GetBackgroundChanges(i).end() );
FOREACH_BackgroundLayer( j )
ASSERT( iter[j] == GAMESTATE->m_pCurSong->GetBackgroundChanges(j).end() );
break;
}
if( IS_ON_SCREEN(fLowestBeat) )
{
vector<RString> vsBGChanges;
FOREACH_CONST( BackgroundLayer, viLowestIndex, i )
FOREACH_CONST( BackgroundLayer, viLowestIndex, bl )
{
ASSERT( iter[*i] != GAMESTATE->m_pCurSong->GetBackgroundChanges(*i).end() );
const BackgroundChange& change = *iter[*i];
ASSERT( iter[*bl] != GAMESTATE->m_pCurSong->GetBackgroundChanges(*bl).end() );
const BackgroundChange& change = *iter[*bl];
RString s = change.GetTextDescription();
if( *i!=0 )
s = ssprintf("%d: ",*i) + s;
if( *bl!=0 )
s = ssprintf("%d: ",*bl) + s;
vsBGChanges.push_back( s );
}
DrawBGChangeText( fLowestBeat, join("\n",vsBGChanges) );
}
FOREACH_CONST( BackgroundLayer, viLowestIndex, i )
iter[*i]++;
FOREACH_CONST( BackgroundLayer, viLowestIndex, bl )
iter[*bl]++;
}
}
break;
@@ -1166,9 +1176,9 @@ void NoteField::DrawPrimitives()
ssprintf("NumTracks %d = ColsPerPlayer %d",m_pNoteData->GetNumTracks(),
GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer));
for( int i=0; i<m_pNoteData->GetNumTracks(); i++ ) // for each arrow column
for( int j=0; j<m_pNoteData->GetNumTracks(); j++ ) // for each arrow column
{
const int c = pStyle->m_iColumnDrawOrder[i];
const int c = pStyle->m_iColumnDrawOrder[j];
bool bAnyUpcomingInThisCol = false;
@@ -1179,7 +1189,7 @@ void NoteField::DrawPrimitives()
for( ; begin != end; ++begin )
{
const TapNote &tn = begin->second; //m_pNoteData->GetTapNote(c, i);
const TapNote &tn = begin->second; //m_pNoteData->GetTapNote(c, j);
if( tn.type != TapNote::hold_head )
continue; // skip
@@ -1255,6 +1265,7 @@ void NoteField::DrawPrimitives()
//if (tn.subType == TapNote::hold_head_roll)
continue; // skip
}
default: break;
}
// Don't draw hidden (fully judged) steps.
+20 -10
View File
@@ -217,16 +217,26 @@ inline const RString TapNoteTypeToString( TapNote::Type tn )
{
switch( tn )
{
case TapNote::empty: return RString("empty");
case TapNote::tap: return RString("tap");
case TapNote::hold_head: return RString("hold_head");
case TapNote::hold_tail: return RString("hold_tail");
case TapNote::mine: return RString("mine");
case TapNote::lift: return RString("lift");
case TapNote::attack: return RString("attack");
case TapNote::autoKeysound: return RString("autoKeysound");
case TapNote::fake: return RString("fake");
default: return RString();
case TapNote::empty:
return RString("empty");
case TapNote::tap:
return RString("tap");
case TapNote::hold_head:
return RString("hold_head");
case TapNote::hold_tail:
return RString("hold_tail");
case TapNote::mine:
return RString("mine");
case TapNote::lift:
return RString("lift");
case TapNote::attack:
return RString("attack");
case TapNote::autoKeysound:
return RString("autoKeysound");
case TapNote::fake:
return RString("fake");
default:
return RString("");
}
}
+83 -9
View File
@@ -459,13 +459,16 @@ static bool SearchForKeysound( const RString &sPath, RString nDataOriginal, map<
* Do a search. Don't do a wildcard search; if sData is "song.wav",
* we might also have "song.png", which we shouldn't match. */
RString nData = nDataOriginal;
if( !IsAFile(out.GetSongDir()+nData) )
RString dir = out.GetSongDir();
if (dir.empty())
dir = Dirname(sPath);
if( !IsAFile(dir+nData) )
{
const char *exts[] = { "oga", "ogg", "wav", "mp3", NULL }; // XXX: stop duplicating these everywhere
for( unsigned i = 0; exts[i] != NULL; ++i )
{
RString fn = SetExtension( nData, exts[i] );
if( IsAFile(out.GetSongDir()+fn) )
if( IsAFile(dir+fn) )
{
nData = fn;
break;
@@ -473,9 +476,9 @@ static bool SearchForKeysound( const RString &sPath, RString nDataOriginal, map<
}
}
if( !IsAFile(out.GetSongDir()+nData) )
if( !IsAFile(dir+nData) )
{
LOG->UserLog( "Song file", out.GetSongDir(), "references key \"%s\" that can't be found", nData.c_str() );
LOG->UserLog( "Song file", dir, "references key \"%s\" that can't be found", nData.c_str() );
return false;
}
@@ -573,8 +576,8 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
if( fBPM > 0.0f )
{
BPMSegment newSeg( 0, fBPM );
out.m_Timing.AddBPMSegment( newSeg );
BPMSegment * newSeg = new BPMSegment( 0, fBPM );
out.m_Timing.AddSegment(SEGMENT_BPM, newSeg );
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", NoteRowToBeat(0), fBPM );
}
else
@@ -663,9 +666,9 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
float fBeats = StringToFloat( sBeats ) / 48.0f;
float fFreezeSecs = fBeats / fBPS;
StopSegment newSeg( BeatToNoteRow(fBeat), fFreezeSecs );
out.m_Timing.AddStopSegment( newSeg );
LOG->Trace( "Inserting new Freeze at beat %f, secs %f", fBeat, newSeg.GetPause() );
StopSegment * newSeg = new StopSegment( fBeat, fFreezeSecs );
out.m_Timing.AddSegment( SEGMENT_STOP_DELAY, newSeg );
LOG->Trace( "Inserting new Freeze at beat %f, secs %f", fBeat, newSeg->GetPause() );
}
else
{
@@ -1067,6 +1070,75 @@ void BMSLoader::GetApplicableFiles( const RString &sPath, vector<RString> &out )
GetDirListing( sPath + RString("*.bml"), out );
}
bool BMSLoader::LoadNoteDataFromSimfile( const RString & cachePath, Steps & out )
{
Song dummy;
// TODO: Simplify this copy/paste from LoadFromDir.
vector<NameToData_t> BMSData;
BMSData.push_back(NameToData_t());
ReadBMSFile(cachePath, BMSData.back());
RString commonSubstring;
GetCommonTagFromMapList( BMSData, "#title", commonSubstring );
Steps *copy = dummy.CreateSteps();
copy->SetDifficulty( Difficulty_Medium );
RString sTag;
if( GetTagFromMap( BMSData[0], "#title", sTag ) && sTag.size() != commonSubstring.size() )
{
sTag = sTag.substr( commonSubstring.size(), sTag.size() - commonSubstring.size() );
sTag.MakeLower();
if( sTag.find('l') != sTag.npos )
{
unsigned lPos = sTag.find('l');
if( lPos > 2 && sTag.substr(lPos-2,4) == "solo" )
{
copy->SetDifficulty( Difficulty_Edit );
}
else
{
copy->SetDifficulty( Difficulty_Easy );
}
}
else if( sTag.find('a') != sTag.npos )
copy->SetDifficulty( Difficulty_Hard );
else if( sTag.find('b') != sTag.npos )
copy->SetDifficulty( Difficulty_Beginner );
}
if( commonSubstring == "" )
{
copy->SetDifficulty(Difficulty_Medium);
RString localTag;
if (GetTagFromMap(BMSData[0], "#title#", localTag))
SearchForDifficulty(localTag, copy);
}
ReadGlobalTags( BMSData[0], dummy );
if( commonSubstring.size() > 2 && commonSubstring[commonSubstring.size() - 2] == ' ' )
{
switch( commonSubstring[commonSubstring.size() - 1] )
{
case '[':
case '(':
case '<':
commonSubstring = commonSubstring.substr(0, commonSubstring.size() - 2);
default:
break;
}
}
map<RString, int> mapFilenameToKeysoundIndex;
const bool ok = LoadFromBMSFile( cachePath, BMSData[0], *copy, dummy, mapFilenameToKeysoundIndex );
if( ok )
{
out.SetNoteData(copy->GetNoteData());
}
return ok;
}
bool BMSLoader::LoadFromDir( const RString &sDir, Song &out )
{
LOG->Trace( "Song::LoadFromBMSDir(%s)", sDir.c_str() );
@@ -1171,6 +1243,7 @@ bool BMSLoader::LoadFromDir( const RString &sDir, Song &out )
iMainDataIndex = i;
ReadGlobalTags( aBMSData[iMainDataIndex], out );
out.m_sSongFileName = out.GetSongDir() + arrayBMSFileNames[iMainDataIndex];
// The brackets before the difficulty are in common substring, so remove them if it's found.
if( commonSubstring.size() > 2 && commonSubstring[commonSubstring.size() - 2] == ' ' )
@@ -1203,6 +1276,7 @@ bool BMSLoader::LoadFromDir( const RString &sDir, Song &out )
if( i == static_cast<unsigned>(iMainDataIndex) )
out.m_SongTiming = pNewNotes->m_Timing;
pNewNotes->SetFilename(out.GetSongDir() + arrayBMSFileNames[i]);
out.AddSteps( pNewNotes );
}
else
+2
View File
@@ -2,11 +2,13 @@
#define NOTES_LOADER_BMS_H
class Song;
class Steps;
/** @brief Reads a Song from a set of .BMS files. */
namespace BMSLoader
{
void GetApplicableFiles( const RString &sPath, vector<RString> &out );
bool LoadFromDir( const RString &sDir, Song &out );
bool LoadNoteDataFromSimfile( const RString & cachePath, Steps &out );
}
#endif
+290 -213
View File
@@ -170,6 +170,238 @@ Difficulty DwiCompatibleStringToDifficulty( const RString& sDC )
else return Difficulty_Invalid;
}
static StepsType GetTypeFromMode(const RString &mode)
{
if( mode == "SINGLE" )
return StepsType_dance_single;
else if( mode == "DOUBLE" )
return StepsType_dance_double;
else if( mode == "COUPLE" )
return StepsType_dance_couple;
else if( mode == "SOLO" )
return StepsType_dance_solo;
ASSERT_M(0, "Unrecognized DWI notes format " + mode + "!");
return StepsType_Invalid; // just in case.
}
static NoteData ParseNoteData(RString &step1, RString &step2,
Steps &out, const RString &path)
{
g_mapDanceNoteToNoteDataColumn.clear();
switch( out.m_StepsType )
{
case StepsType_dance_single:
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 1;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 2;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 3;
break;
case StepsType_dance_double:
case StepsType_dance_couple:
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 1;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 2;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 3;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_LEFT] = 4;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_DOWN] = 5;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_UP] = 6;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_RIGHT] = 7;
break;
case StepsType_dance_solo:
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UPLEFT] = 1;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 2;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 3;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UPRIGHT] = 4;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 5;
break;
DEFAULT_FAIL( out.m_StepsType );
}
NoteData newNoteData;
newNoteData.SetNumTracks( g_mapDanceNoteToNoteDataColumn.size() );
for( int pad=0; pad<2; pad++ ) // foreach pad
{
RString sStepData;
switch( pad )
{
case 0:
sStepData = step1;
break;
case 1:
if( step2 == "" ) // no data
continue; // skip
sStepData = step2;
break;
DEFAULT_FAIL( pad );
}
sStepData.Replace("\n", "");
sStepData.Replace("\r", "");
sStepData.Replace("\t", "");
sStepData.Replace(" ", "");
double fCurrentBeat = 0;
double fCurrentIncrementer = 1.0/8 * BEATS_PER_MEASURE;
for( size_t i=0; i<sStepData.size(); )
{
char c = sStepData[i++];
switch( c )
{
// begins a series
case '(':
fCurrentIncrementer = 1.0/16 * BEATS_PER_MEASURE;
break;
case '[':
fCurrentIncrementer = 1.0/24 * BEATS_PER_MEASURE;
break;
case '{':
fCurrentIncrementer = 1.0/64 * BEATS_PER_MEASURE;
break;
case '`':
fCurrentIncrementer = 1.0/192 * BEATS_PER_MEASURE;
break;
// ends a series
case ')':
case ']':
case '}':
case '\'':
case '>':
fCurrentIncrementer = 1.0/8 * BEATS_PER_MEASURE;
break;
default: // this is a note character
{
if( c == '!' )
{
LOG->UserLog(
"Song file",
path,
"has an unexpected character: '!'." );
continue;
}
bool jump = false;
if( c == '<' )
{
/* Arr. Is this a jump or a 1/192 marker? */
if( Is192( sStepData, i ) )
{
fCurrentIncrementer = 1.0/192 * BEATS_PER_MEASURE;
break;
}
/* It's a jump.
* We need to keep reading notes until we hit a >. */
jump = true;
i++;
}
const int iIndex = BeatToNoteRow( (float)fCurrentBeat );
i--;
do {
c = sStepData[i++];
if( jump && c == '>' )
break;
int iCol1, iCol2;
DWIcharToNoteCol(
c,
(GameController)pad,
iCol1,
iCol2,
path );
if( iCol1 != -1 )
newNoteData.SetTapNote(iCol1,
iIndex,
TAP_ORIGINAL_TAP);
if( iCol2 != -1 )
newNoteData.SetTapNote(iCol2,
iIndex,
TAP_ORIGINAL_TAP);
if(i>=sStepData.length())
{
break;
//we ran out of data
//while looking for the ending > mark
}
if( sStepData[i] == '!' )
{
i++;
const char holdChar = sStepData[i++];
DWIcharToNoteCol(holdChar,
(GameController)pad,
iCol1,
iCol2,
path );
if( iCol1 != -1 )
newNoteData.SetTapNote(iCol1,
iIndex,
TAP_ORIGINAL_HOLD_HEAD);
if( iCol2 != -1 )
newNoteData.SetTapNote(iCol2,
iIndex,
TAP_ORIGINAL_HOLD_HEAD);
}
}
while( jump );
fCurrentBeat += fCurrentIncrementer;
}
break;
}
}
}
/* Fill in iDuration. */
for( int t=0; t<newNoteData.GetNumTracks(); ++t )
{
FOREACH_NONEMPTY_ROW_IN_TRACK( newNoteData, t, iHeadRow )
{
TapNote tn = newNoteData.GetTapNote( t, iHeadRow );
if( tn.type != TapNote::hold_head )
continue;
int iTailRow = iHeadRow;
bool bFound = false;
while( !bFound && newNoteData.GetNextTapNoteRowForTrack(t, iTailRow) )
{
const TapNote &TailTap = newNoteData.GetTapNote( t, iTailRow );
if( TailTap.type == TapNote::empty )
continue;
newNoteData.SetTapNote( t, iTailRow, TAP_EMPTY );
tn.iDuration = iTailRow - iHeadRow;
newNoteData.SetTapNote( t, iHeadRow, tn );
bFound = true;
}
if( !bFound )
{
/* The hold was never closed. */
LOG->UserLog("Song file",
path,
"failed to close a hold note in \"%s\" on track %i",
DifficultyToString(out.GetDifficulty()).c_str(),
t);
newNoteData.SetTapNote( t, iHeadRow, TAP_EMPTY );
}
}
}
ASSERT( newNoteData.GetNumTracks() > 0 );
return newNoteData;
}
/**
* @brief Look through the notes tag to extract the data.
* @param sMode the steps type.
@@ -192,216 +424,17 @@ static bool LoadFromDWITokens(
{
CHECKPOINT_M( "DWILoader::LoadFromDWITokens()" );
out.m_StepsType = StepsType_Invalid;
out.m_StepsType = GetTypeFromMode(sMode);
if( sMode == "SINGLE" ) out.m_StepsType = StepsType_dance_single;
else if( sMode == "DOUBLE" ) out.m_StepsType = StepsType_dance_double;
else if( sMode == "COUPLE" ) out.m_StepsType = StepsType_dance_couple;
else if( sMode == "SOLO" ) out.m_StepsType = StepsType_dance_solo;
else
{
ASSERT_M(0, "Unrecognized DWI notes format " + sMode + "!");
out.m_StepsType = StepsType_dance_single;
}
out.SetMeter(StringToInt(sNumFeet));
g_mapDanceNoteToNoteDataColumn.clear();
switch( out.m_StepsType )
{
case StepsType_dance_single:
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 1;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 2;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 3;
break;
case StepsType_dance_double:
case StepsType_dance_couple:
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 1;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 2;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 3;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_LEFT] = 4;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_DOWN] = 5;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_UP] = 6;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_RIGHT] = 7;
break;
case StepsType_dance_solo:
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UPLEFT] = 1;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 2;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 3;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UPRIGHT] = 4;
g_mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 5;
break;
DEFAULT_FAIL( out.m_StepsType );
}
int iNumFeet = StringToInt(sNumFeet);
// out.SetDescription(sDescription); // Don't put garbage in the description.
out.SetMeter(iNumFeet);
out.SetDifficulty( DwiCompatibleStringToDifficulty(sDescription) );
NoteData newNoteData;
newNoteData.SetNumTracks( g_mapDanceNoteToNoteDataColumn.size() );
for( int pad=0; pad<2; pad++ ) // foreach pad
{
RString sStepData;
switch( pad )
{
case 0:
sStepData = sStepData1;
break;
case 1:
if( sStepData2 == "" ) // no data
continue; // skip
sStepData = sStepData2;
break;
DEFAULT_FAIL( pad );
}
sStepData.Replace("\n", "");
sStepData.Replace("\r", "");
sStepData.Replace("\t", "");
sStepData.Replace(" ", "");
double fCurrentBeat = 0;
double fCurrentIncrementer = 1.0/8 * BEATS_PER_MEASURE;
for( size_t i=0; i<sStepData.size(); )
{
char c = sStepData[i++];
switch( c )
{
// begins a series
case '(':
fCurrentIncrementer = 1.0/16 * BEATS_PER_MEASURE;
break;
case '[':
fCurrentIncrementer = 1.0/24 * BEATS_PER_MEASURE;
break;
case '{':
fCurrentIncrementer = 1.0/64 * BEATS_PER_MEASURE;
break;
case '`':
fCurrentIncrementer = 1.0/192 * BEATS_PER_MEASURE;
break;
// ends a series
case ')':
case ']':
case '}':
case '\'':
case '>':
fCurrentIncrementer = 1.0/8 * BEATS_PER_MEASURE;
break;
default: // this is a note character
{
if( c == '!' )
{
LOG->UserLog( "Song file", sPath, "has an unexpected character: '!'." );
continue;
}
bool jump = false;
if( c == '<' )
{
/* Arr. Is this a jump or a 1/192 marker? */
if( Is192( sStepData, i ) )
{
fCurrentIncrementer = 1.0/192 * BEATS_PER_MEASURE;
break;
}
/* It's a jump. We need to keep reading notes until we hit a >. */
jump = true;
i++;
}
const int iIndex = BeatToNoteRow( (float)fCurrentBeat );
i--;
do {
c = sStepData[i++];
if( jump && c == '>' )
break;
int iCol1, iCol2;
DWIcharToNoteCol( c, (GameController)pad, iCol1, iCol2, sPath );
if( iCol1 != -1 )
newNoteData.SetTapNote(iCol1, iIndex, TAP_ORIGINAL_TAP);
if( iCol2 != -1 )
newNoteData.SetTapNote(iCol2, iIndex, TAP_ORIGINAL_TAP);
if(i>=sStepData.length()) {
break;//we ran out of data while looking for the ending > mark
}
if( sStepData[i] == '!' )
{
i++;
const char holdChar = sStepData[i++];
DWIcharToNoteCol( holdChar, (GameController)pad, iCol1, iCol2, sPath );
if( iCol1 != -1 )
newNoteData.SetTapNote(iCol1, iIndex, TAP_ORIGINAL_HOLD_HEAD);
if( iCol2 != -1 )
newNoteData.SetTapNote(iCol2, iIndex, TAP_ORIGINAL_HOLD_HEAD);
}
}
while( jump );
fCurrentBeat += fCurrentIncrementer;
}
break;
}
}
}
/* Fill in iDuration. */
for( int t=0; t<newNoteData.GetNumTracks(); ++t )
{
FOREACH_NONEMPTY_ROW_IN_TRACK( newNoteData, t, iHeadRow )
{
TapNote tn = newNoteData.GetTapNote( t, iHeadRow );
if( tn.type != TapNote::hold_head )
continue;
int iTailRow = iHeadRow;
bool bFound = false;
while( !bFound && newNoteData.GetNextTapNoteRowForTrack(t, iTailRow) )
{
const TapNote &TailTap = newNoteData.GetTapNote( t, iTailRow );
if( TailTap.type == TapNote::empty )
continue;
newNoteData.SetTapNote( t, iTailRow, TAP_EMPTY );
tn.iDuration = iTailRow - iHeadRow;
newNoteData.SetTapNote( t, iHeadRow, tn );
bFound = true;
}
if( !bFound )
{
/* The hold was never closed. */
LOG->UserLog( "Song file", sPath, "failed to close a hold note in \"%s\" on track %i",
sDescription.c_str(), t );
newNoteData.SetTapNote( t, iHeadRow, TAP_EMPTY );
}
}
}
ASSERT( newNoteData.GetNumTracks() > 0 );
out.SetNoteData( newNoteData );
out.SetNoteData( ParseNoteData(sStepData1, sStepData2, out, sPath) );
out.TidyUpData();
out.SetSavedToDisk( true ); // we're loading from disk, so this is by definintion already saved
return true;
}
@@ -444,17 +477,55 @@ void DWILoader::GetApplicableFiles( const RString &sPath, vector<RString> &out )
GetDirListing( sPath + RString("*.dwi"), out );
}
bool DWILoader::LoadNoteDataFromSimfile( const RString &path, Steps &out )
{
MsdFile msd;
if( !msd.ReadFile( path, false ) ) // don't unescape
{
LOG->UserLog("Song file",
path,
"couldn't be opened: %s",
msd.GetError().c_str() );
return false;
}
for( unsigned i=0; i<msd.GetNumValues(); i++ )
{
int iNumParams = msd.GetNumParams(i);
const MsdFile::value_t &params = msd.GetValue(i);
RString valueName = params[0];
if(valueName.EqualsNoCase("SINGLE") ||
valueName.EqualsNoCase("DOUBLE") ||
valueName.EqualsNoCase("COUPLE") ||
valueName.EqualsNoCase("SOLO") )
{
if (out.m_StepsType != GetTypeFromMode(valueName))
continue;
if (out.GetDifficulty() != DwiCompatibleStringToDifficulty(params[1]))
continue;
if (out.GetMeter() != StringToInt(params[2]))
continue;
RString step1 = params[3];
RString step2 = (iNumParams==5) ? params[4] : RString("");
out.SetNoteData(ParseNoteData(step1, step2, out, path));
return true;
}
}
return false;
}
bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set<RString> &BlacklistedImages )
{
vector<RString> aFileNames;
GetApplicableFiles( sPath_, aFileNames );
if( aFileNames.size() > 1 )
{
LOG->UserLog( "Song", sPath_, "has more than one DWI file. There should be only one!" );
return false;
}
/* We should have exactly one; if we had none, we shouldn't have been called to begin with. */
ASSERT( aFileNames.size() == 1 );
const RString sPath = sPath_ + aFileNames[0];
@@ -468,6 +539,8 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set<RString> &Bla
return false;
}
out.m_sSongFileName = sPath;
for( unsigned i=0; i<msd.GetNumValues(); i++ )
{
int iNumParams = msd.GetNumParams(i);
@@ -515,14 +588,16 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set<RString> &Bla
if( PREFSMAN->m_bQuirksMode )
{
out.m_SongTiming.AddBPMSegment( BPMSegment(0, fBPM) );
out.m_SongTiming.AddSegment( SEGMENT_BPM, new BPMSegment(0, fBPM) );
}
else{
if( fBPM > 0.0f )
out.m_SongTiming.AddBPMSegment( BPMSegment(0, fBPM) );
out.m_SongTiming.AddSegment( SEGMENT_BPM, new BPMSegment(0, fBPM) );
else
LOG->UserLog( "Song file", sPath, "has an invalid BPM change at beat %f, BPM %f.",
NoteRowToBeat(0), fBPM );
LOG->UserLog("Song file",
sPath,
"has an invalid BPM change at beat %f, BPM %f.",
0.0f, fBPM );
}
}
else if( sValueName.EqualsNoCase("DISPLAYBPM") )
@@ -576,7 +651,7 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set<RString> &Bla
int iFreezeRow = BeatToNoteRow( StringToFloat(arrayFreezeValues[0]) / 4.0f );
float fFreezeSeconds = StringToFloat( arrayFreezeValues[1] ) / 1000.0f;
out.m_SongTiming.AddStopSegment( StopSegment(iFreezeRow, fFreezeSeconds) );
out.m_SongTiming.AddSegment( SEGMENT_STOP_DELAY, new StopSegment(iFreezeRow, fFreezeSeconds) );
// LOG->Trace( "Adding a freeze segment: beat: %f, seconds = %f", fFreezeBeat, fFreezeSeconds );
}
}
@@ -600,8 +675,8 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set<RString> &Bla
float fBPM = StringToFloat( arrayBPMChangeValues[1] );
if( fBPM > 0.0f )
{
BPMSegment bs( iStartIndex, fBPM );
out.m_SongTiming.AddBPMSegment( bs );
BPMSegment * bs = new BPMSegment( iStartIndex, fBPM );
out.m_SongTiming.AddSegment( SEGMENT_BPM, bs );
}
else
{
@@ -627,7 +702,10 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set<RString> &Bla
sPath
);
if( pNewNotes->m_StepsType != StepsType_Invalid )
{
pNewNotes->SetFilename( sPath );
out.AddSteps( pNewNotes );
}
else
delete pNewNotes;
}
@@ -662,7 +740,6 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set<RString> &Bla
// do nothing. We don't care about this value name
}
}
out.TidyUpData();
return true;
}
+3
View File
@@ -6,6 +6,7 @@
#include <set>
class Song;
class Steps;
/** @brief The DWILoader handles parsing the .dwi file. */
namespace DWILoader
@@ -24,6 +25,8 @@ namespace DWILoader
* @return its success or failure.
*/
bool LoadFromDir( const RString &sPath, Song &out, set<RString> &BlacklistedImages );
bool LoadNoteDataFromSimfile( const RString &path, Steps &out );
}
#endif
+23 -13
View File
@@ -10,29 +10,39 @@
#include "Steps.h"
#include "GameManager.h"
void Deserialize(BPMSegment &seg, const Json::Value &root);
void NotesLoaderJson::GetApplicableFiles( const RString &sPath, vector<RString> &out )
{
GetDirListing( sPath + RString("*.json"), out );
}
void Deserialize(BPMSegment &seg, const Json::Value &root)
static void Deserialize(TimingSegment &seg_, const Json::Value &root)
{
seg.SetBeat((float)(root["Beat"].asDouble()));
seg.SetBPM((float)(root["BPM"].asDouble()));
}
static void Deserialize(StopSegment &seg, const Json::Value &root)
{
seg.SetBeat((float)(root["Beat"].asDouble()));
seg.SetPause((float)(root["Seconds"].asDouble()));
TimingSegment *seg = &seg_;
float fBeat = root["Beat"].asDouble();
seg->SetBeat(fBeat);
switch (seg->GetType())
{
case SEGMENT_BPM:
{
float fBPM = root["BPM"].asDouble();
static_cast<BPMSegment *>(seg)->SetBPM(fBPM);
break;
}
case SEGMENT_STOP_DELAY:
{
float fStop = root["Seconds"].asDouble();
static_cast<StopSegment *>(seg)->SetPause(fStop);
break;
}
default: break; // The rest are unused.
}
}
static void Deserialize(TimingData &td, const Json::Value &root)
{
JsonUtil::DeserializeVectorObjects( td.m_BPMSegments, Deserialize, root["BpmSegments"] );
JsonUtil::DeserializeVectorObjects( td.m_StopSegments, Deserialize, root["StopSegments"] );
JsonUtil::DeserializeVectorPointers( td.allTimingSegments[SEGMENT_BPM], Deserialize, root["BpmSegments"] );
JsonUtil::DeserializeVectorPointers( td.allTimingSegments[SEGMENT_STOP_DELAY], Deserialize, root["StopSegments"] );
}
static void Deserialize(LyricSegment &o, const Json::Value &root)
+95 -85
View File
@@ -17,10 +17,10 @@ static void HandleBunki( TimingData &timing, const float fEarlyBPM,
const float beat = (fPos + fGap) * BeatsPerSecond;
LOG->Trace( "BPM %f, BPS %f, BPMPos %f, beat %f",
fEarlyBPM, BeatsPerSecond, fPos, beat );
timing.AddBPMSegment( BPMSegment(BeatToNoteRow(beat), fCurBPM) );
timing.AddSegment( SEGMENT_BPM, new BPMSegment(beat, fCurBPM) );
}
static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song, bool bKIUCompliant )
static bool LoadFromKSFFile( const RString &sPath, Steps &out, Song &song, bool bKIUCompliant )
{
LOG->Trace( "Steps::LoadFromKSFFile( '%s' )", sPath.c_str() );
@@ -54,13 +54,12 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song,
if (sValueName=="TITLE" || EndsWith(sValueName, "INTRO")
|| EndsWith(sValueName, "FILE") )
{
;
}
else if( sValueName=="BPM" )
{
BPM1 = StringToFloat(sParams[1]);
stepsTiming.AddBPMSegment( BPMSegment(0, BPM1) );
stepsTiming.AddSegment( SEGMENT_BPM, new BPMSegment(0, BPM1) );
}
else if( sValueName=="BPM2" )
{
@@ -137,7 +136,7 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song,
LOG->UserLog( "Song file", sPath, "has an invalid tick count: %d.", iTickCount );
return false;
}
stepsTiming.AddTickcountSegment(TickcountSegment(0, iTickCount));
stepsTiming.AddSegment( SEGMENT_TICKCOUNT, new TickcountSegment(0, iTickCount));
}
else if( sValueName=="DIFFICULTY" )
@@ -195,28 +194,43 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song,
out.SetDifficulty( Difficulty_Edit );
if( !out.GetMeter() ) out.SetMeter( 25 );
}
else if( sFName.find("wild") != string::npos || sFName.find("wd") != string::npos || sFName.find("crazy+") != string::npos || sFName.find("cz+") != string::npos || sFName.find("hardcore") != string::npos )
else if(sFName.find("wild") != string::npos ||
sFName.find("wd") != string::npos ||
sFName.find("crazy+") != string::npos ||
sFName.find("cz+") != string::npos ||
sFName.find("hardcore") != string::npos )
{
out.SetDifficulty( Difficulty_Challenge );
if( !out.GetMeter() ) out.SetMeter( 20 );
}
else if( sFName.find("crazy") != string::npos || sFName.find("cz") != string::npos || sFName.find("nightmare") != string::npos || sFName.find("nm") != string::npos || sFName.find("crazydouble") != string::npos )
else if(sFName.find("crazy") != string::npos ||
sFName.find("cz") != string::npos ||
sFName.find("nightmare") != string::npos ||
sFName.find("nm") != string::npos ||
sFName.find("crazydouble") != string::npos )
{
out.SetDifficulty( Difficulty_Hard );
if( !out.GetMeter() ) out.SetMeter( 14 ); // Set the meters to the Pump scale, not DDR.
}
else if( sFName.find("hard") != string::npos || sFName.find("hd") != string::npos || sFName.find("freestyle") != string::npos || sFName.find("fs") != string::npos || sFName.find("double") != string::npos )
else if(sFName.find("hard") != string::npos ||
sFName.find("hd") != string::npos ||
sFName.find("freestyle") != string::npos ||
sFName.find("fs") != string::npos ||
sFName.find("double") != string::npos )
{
out.SetDifficulty( Difficulty_Medium );
if( !out.GetMeter() ) out.SetMeter( 8 );
}
else if( sFName.find("easy") != string::npos || sFName.find("ez") != string::npos || sFName.find("normal") != string::npos )
else if(sFName.find("easy") != string::npos ||
sFName.find("ez") != string::npos ||
sFName.find("normal") != string::npos )
{
// I wonder if I should leave easy fall into the Beginner difficulty... -DaisuMaster
out.SetDifficulty( Difficulty_Easy );
if( !out.GetMeter() ) out.SetMeter( 4 );
}
else if( sFName.find("beginner") != string::npos || sFName.find("practice") != string::npos || sFName.find("pr") != string::npos )
else if(sFName.find("beginner") != string::npos ||
sFName.find("practice") != string::npos || sFName.find("pr") != string::npos )
{
out.SetDifficulty( Difficulty_Beginner );
if( !out.GetMeter() ) out.SetMeter( 4 );
@@ -230,10 +244,18 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song,
out.m_StepsType = StepsType_pump_single;
// Check for "halfdouble" before "double".
if( sFName.find("halfdouble") != string::npos || sFName.find("half-double") != string::npos || sFName.find("h_double") != string::npos || sFName.find("hdb") != string::npos )
if(sFName.find("halfdouble") != string::npos ||
sFName.find("half-double") != string::npos ||
sFName.find("h_double") != string::npos ||
sFName.find("hdb") != string::npos )
out.m_StepsType = StepsType_pump_halfdouble;
// Handle bDoublesChart from above as well. -aj
else if( sFName.find("double") != string::npos || sFName.find("nightmare") != string::npos || sFName.find("freestyle") != string::npos || sFName.find("db") != string::npos || sFName.find("nm") != string::npos || sFName.find("fs") != string::npos || bDoublesChart )
else if(sFName.find("double") != string::npos ||
sFName.find("nightmare") != string::npos ||
sFName.find("freestyle") != string::npos ||
sFName.find("db") != string::npos ||
sFName.find("nm") != string::npos ||
sFName.find("fs") != string::npos || bDoublesChart )
out.m_StepsType = StepsType_pump_double;
else if( sFName.find("_1") != string::npos )
out.m_StepsType = StepsType_pump_single;
@@ -280,19 +302,31 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song,
if( iHoldStartRow[t] == BeatToNoteRow(prevBeat) )
notedata.SetTapNote( t, iHoldStartRow[t], TAP_ORIGINAL_TAP );
else
notedata.AddHoldNote( t, iHoldStartRow[t], BeatToNoteRow(prevBeat) , TAP_ORIGINAL_HOLD_HEAD );
notedata.AddHoldNote(t,
iHoldStartRow[t],
BeatToNoteRow(prevBeat),
TAP_ORIGINAL_HOLD_HEAD );
}
}
/* have this row be the last moment in the song, unless
* a future step ends later. */
float curTime = stepsTiming.GetElapsedTimeFromBeat(fCurBeat);
if (curTime > song.GetSpecifiedLastSecond())
{
song.SetSpecifiedLastSecond(curTime);
}
break;
}
else if( BeginsWith(sRowString, "|") )
{
/*
if (bKIUCompliant)
{
// Log an error, ignore the line.
continue;
}
*/
// gotta do something tricky here: if the bpm is below one then a couple of calculations
// for scrollsegments will be made, example, bpm 0.2, tick 4000, the scrollsegment will
// be 0. if the tickcount is non a stepmania standard then it will be adapted, a scroll
@@ -300,6 +334,7 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song,
// eh better do it considering the tickcount (high tickcounts)
// I'm making some experiments, please spare me...
//continue;
RString temp = sRowString.substr(2,sRowString.size()-3);
float numTemp = StringToFloat(temp);
@@ -307,53 +342,7 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song,
{
// duh
iTickCount = static_cast<int>(numTemp);
//if( iTickCount > ROWS_PER_BEAT )
/* adapt tickcounts //
// valid tickcounts for SM: 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 64, ROWS_PER_BEAT
// put this inside the tickcount handling condition yes/no
if( iTickCount > ROWS_PER_BEAT ) // beyond 48
{
// clamp/scale/whatever and use scroll segments
}
else if( iTickCount > 32 || iTickCount < ROWS_PER_BEAT ) // ranging from 33 to 48, approximate to 32
{
fScrollRatio = 32;
iTickCount = 32;
}
else if( iTickCount > 24 || iTickCount < 32 ) // ranging from 25 to 31, approximate to 24
{
fScrollRatio = 24;
iTickCount = 24;
}
else if( iTickCount > 16 || iTickCount < 24 ) // ranging from 17 to 23, approximate to 16
{
fScrollRatio = 16;
iTickCount = 16;
}
else if( iTickCount > 12 || iTickCount < 16 ) // ranging from 13 to 15, approximate to 12
{
fScrollRatio = 12;
iTickCount = 12;
}
else if( iTickCount > 8 || iTickCount < 12 ) // ranging from 9 to 11, approximate to 8
{
fScrollRatio = 8;
iTickCount = 8;
}
else if( iTickCount > 6 || iTickCount < 8 ) // 7, approximate to 6
{
fScrollRatio = 6 / iTickCountt;
iTickCount = 6;
}
else if( iTickCount > 4 || iTickCount < 6 ) // 5, approximate to 4
{
fScrollRatio = iTickCount / 4;
iTickCount = 4;
}
//*/
// I have been owned by the man -DaisuMaster
stepsTiming.SetTickcountAtBeat( fCurBeat, clamp(iTickCount, 0, ROWS_PER_BEAT) );
}
else if (BeginsWith(sRowString, "|B"))
@@ -392,7 +381,7 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song,
{
// scroll segments
stepsTiming.SetScrollAtBeat( fCurBeat, numTemp );
return true;
//return true;
}
continue;
@@ -516,7 +505,21 @@ static void LoadTags( const RString &str, Song &out )
out.m_sArtist = artist;
}
static bool LoadGlobalData( const RString &sPath, Song &out, bool bKIUCompliant )
static void ProcessTickcounts( const RString & value, int & ticks, TimingData & timing )
{
/* TICKCOUNT will be used below if there are DM compliant BPM changes
* and stops. It will be called again in LoadFromKSFFile for the
* actual steps. */
ticks = StringToInt( value );
ticks = ticks > 0 ? ticks : 4;
// add a tickcount for those using the [Player]
// CheckpointsUseTimeSignatures metric. -aj
// It's not with timesigs now -DaisuMaster
TickcountSegment * tcs = new TickcountSegment(0, ticks > ROWS_PER_BEAT ? ROWS_PER_BEAT : ticks);
timing.AddSegment( SEGMENT_TICKCOUNT, tcs );
}
static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant )
{
MsdFile msd;
if( !msd.ReadFile( sPath, false ) ) // don't unescape
@@ -554,7 +557,7 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool bKIUCompliant
else if( sValueName=="BPM" )
{
BPM1 = StringToFloat(sParams[1]);
out.m_SongTiming.AddBPMSegment( BPMSegment(0, BPM1) );
out.m_SongTiming.AddSegment( SEGMENT_BPM, new BPMSegment(0, BPM1) );
}
else if( sValueName=="BPM2" )
{
@@ -590,21 +593,11 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool bKIUCompliant
else if ( sValueName=="STARTTIME3" )
{
// STARTTIME3 only ensures this is a KIU compliant simfile.
bKIUCompliant = true;
//bKIUCompliant = true;
}
else if ( sValueName=="TICKCOUNT" )
{
/* TICKCOUNT will be used below if there are DM compliant BPM changes
* and stops. It will be called again in LoadFromKSFFile for the
* actual steps. */
iTickCount = StringToInt( sParams[1] );
iTickCount = iTickCount > 0 ? iTickCount : 4;
// add a tickcount for those using the [Player]
// CheckpointsUseTimeSignatures metric. -aj
// It's not with timesigs now -DaisuMaster
TickcountSegment tcs(0);
tcs.SetTicks(iTickCount > ROWS_PER_BEAT ? ROWS_PER_BEAT : iTickCount);
out.m_SongTiming.AddTickcountSegment( tcs );
ProcessTickcounts(sParams[1], iTickCount, out.m_SongTiming);
}
else if ( sValueName=="STEP" )
{
@@ -614,10 +607,10 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool bKIUCompliant
TrimLeft( theSteps );
split( theSteps, "\n", vNoteRows, true );
}
else if( sValueName=="DIFFICULTY" )
else if( sValueName=="DIFFICULTY" || sValueName=="PLAYER" )
{
/* DIFFICULTY is handled only in LoadFromKSFFile. Ignore it here. */
/* DIFFICULTY and PLAYER are handled only in LoadFromKSFFile.
Ignore those here. */
continue;
}
// New cases noted in Aldo_MX's code:
@@ -689,7 +682,6 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool bKIUCompliant
}
// This is where the DMRequired test will take place.
//if (BeginsWith(NoteRowString, "|T") || BeginsWith(NoteRowString, "|B") || BeginsWith(NoteRowString, "|D") || BeginsWith(NoteRowString, "|E") )
if ( BeginsWith( NoteRowString, "|" ) )
{
// have a static timing for everything
@@ -723,6 +715,22 @@ void KSFLoader::GetApplicableFiles( const RString &sPath, vector<RString> &out )
GetDirListing( sPath + RString("*.ksf"), out );
}
bool KSFLoader::LoadNoteDataFromSimfile( const RString & cachePath, Steps &out )
{
bool KIUCompliant = false;
Song dummy;
if (!LoadGlobalData(cachePath, dummy, KIUCompliant))
return false;
Steps *notes = dummy.CreateSteps();
if (LoadFromKSFFile(cachePath, *notes, dummy, KIUCompliant))
{
KIUCompliant = true; // yeah, reusing a variable.
out.SetNoteData(notes->GetNoteData());
}
delete notes;
return KIUCompliant;
}
bool KSFLoader::LoadFromDir( const RString &sDir, Song &out )
{
LOG->Trace( "KSFLoader::LoadFromDir(%s)", sDir.c_str() );
@@ -733,7 +741,7 @@ bool KSFLoader::LoadFromDir( const RString &sDir, Song &out )
// We shouldn't have been called to begin with if there were no KSFs.
ASSERT( arrayKSFFileNames.size() );
//bool bKIUCompliant = false;
bool bKIUCompliant = false;
/* With Split Timing, there has to be a backup Song Timing in case
* anything goes wrong. As these files are kept in alphabetical
* order (hopefully), it is best to use the LAST file for timing
@@ -751,22 +759,24 @@ bool KSFLoader::LoadFromDir( const RString &sDir, Song &out )
// for directmove though, and we're just gathering basic info anyway, and
// most of the time all the KSF files have the same info in the #TITLE:; section
unsigned files = arrayKSFFileNames.size();
if( !LoadGlobalData(out.GetSongDir() + arrayKSFFileNames[0], out, false) )
RString dir = out.GetSongDir();
if( !LoadGlobalData(dir + arrayKSFFileNames[files - 1], out, bKIUCompliant) )
return false;
out.m_sSongFileName = dir + arrayKSFFileNames[files - 1];
// load the Steps from the rest of the KSF files
for( unsigned i=0; i<files; i++ )
{
Steps* pNewNotes = out.CreateSteps();
if( !LoadFromKSFFile(out.GetSongDir() + arrayKSFFileNames[i], *pNewNotes, out, false) )
if( !LoadFromKSFFile(dir + arrayKSFFileNames[i], *pNewNotes, out, bKIUCompliant) )
{
delete pNewNotes;
continue;
}
pNewNotes->SetFilename(dir + arrayKSFFileNames[i]);
out.AddSteps( pNewNotes );
}
out.TidyUpData();
out.TidyUpData(false, true);
return true;
}
+2
View File
@@ -2,11 +2,13 @@
#define NOTES_LOADER_KSF_H
class Song;
class Steps;
/** @brief Reads a Song from a set of .KSF files. */
namespace KSFLoader
{
void GetApplicableFiles( const RString &sPath, vector<RString> &out );
bool LoadFromDir( const RString &sDir, Song &out );
bool LoadNoteDataFromSimfile( const RString & cachePath, Steps &out );
}
#endif
+17 -13
View File
@@ -677,21 +677,22 @@ static bool LoadFromMidi( const RString &sPath, Song &songOut )
FOREACH_CONST( MidiFileIn::TempoChange, midi.tempoEvents_, iter )
{
BPMSegment bpmSeg;
bpmSeg.SetRow( MidiCountToNoteRow( iter->count ) );
BPMSegment * bpmSeg = NULL;
bpmSeg->SetRow( MidiCountToNoteRow( iter->count ) );
double fSecondsPerBeat = (iter->tickSeconds * GUITAR_MIDI_COUNTS_PER_BEAT);
bpmSeg.SetBPS( float( 1. / fSecondsPerBeat ) );
bpmSeg->SetBPS( float( 1. / fSecondsPerBeat ) );
songOut.m_SongTiming.AddBPMSegment( bpmSeg );
songOut.m_SongTiming.AddSegment( SEGMENT_BPM, bpmSeg );
}
FOREACH_CONST( MidiFileIn::TimeSignatureChange, midi.timeSignatureEvents_, iter )
{
TimeSignatureSegment seg(MidiCountToNoteRow( iter->count ),
iter->numerator,
iter->denominator);
TimeSignatureSegment * seg =
new TimeSignatureSegment(MidiCountToNoteRow( iter->count ),
iter->numerator,
iter->denominator);
songOut.m_SongTiming.AddTimeSignatureSegment( seg );
songOut.m_SongTiming.AddSegment( SEGMENT_TIME_SIG, seg );
}
@@ -816,8 +817,8 @@ skip_track:
// Check for termination of a sustain note
switch( midiEventType )
{
case note_off:
case note_on:
case note_off:
case note_on:
if( bNonTerminatedNote )
{
if( length >= 240 )
@@ -832,14 +833,15 @@ skip_track:
bNonTerminatedNote = false;
bNoteHandled = true;
break;
}
break;
default: break;
}
switch( midiEventType )
{
case note_on:
case note_on:
{
TapNote tn = TAP_ORIGINAL_TAP;
@@ -866,7 +868,9 @@ skip_track:
bNonTerminatedNote = true;
bNoteHandled = true;
break;
}
default: break;
}
countOfLastNote = count;
@@ -955,7 +959,7 @@ bool MidiLoader::LoadFromDir( const RString &sDir, Song &out )
if( !LoadFromMidi(sDir+vsFiles[0], out) )
return false;
out.TidyUpData();
out.TidyUpData(false, true);
return true;
}
+84 -18
View File
@@ -573,7 +573,7 @@ static bool LoadFromPMSFile( const RString &sPath, const NameToData_t &mapNameTo
return true;
}
static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, MeasureToTimeSig_t &sigAdjustmentsOut, map<RString,int> &idToKeySoundIndexOut )
static void ReadGlobalTags( const RString &sPath, const NameToData_t &mapNameToData, Song &out, MeasureToTimeSig_t &sigAdjustmentsOut, map<RString,int> &idToKeySoundIndexOut )
{
RString sData;
if( GetTagFromMap(mapNameToData, "#title", sData) )
@@ -590,8 +590,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
if( fBPM > 0.0f )
{
BPMSegment newSeg( 0, fBPM );
out.m_SongTiming.AddBPMSegment( newSeg );
out.m_SongTiming.AddSegment( SEGMENT_BPM, new BPMSegment(0, fBPM) );
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", NoteRowToBeat(0), fBPM );
}
else
@@ -612,26 +611,29 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
// this is keysound file name. Looks like "#WAV1A"
RString nData = it->second;
RString sWavID = sName.Right(2);
RString dir = out.GetSongDir();
if (dir.empty())
dir = Dirname(sPath);
/* Due to bugs in some programs, many PMS files have a "WAV" extension
* on files in the PMS for files that actually have some other extension.
* Do a search. Don't do a wildcard search; if sData is "song.wav",
* we might also have "song.png", which we shouldn't match. */
if( !IsAFile(out.GetSongDir()+nData) )
if( !IsAFile(dir+nData) )
{
const char *exts[] = { "oga", "ogg", "wav", "mp3", NULL }; // XXX: stop duplicating these everywhere
for( unsigned i = 0; exts[i] != NULL; ++i )
{
RString fn = SetExtension( nData, exts[i] );
if( IsAFile(out.GetSongDir()+fn) )
if( IsAFile(dir+fn) )
{
nData = fn;
break;
}
}
}
if( !IsAFile(out.GetSongDir()+nData) )
LOG->UserLog( "Song file", out.GetSongDir(), "references key \"%s\" that can't be found", nData.c_str() );
if( !IsAFile(dir+nData) )
LOG->UserLog( "Song file", dir, "references key \"%s\" that can't be found", nData.c_str() );
sWavID.MakeUpper(); // HACK: undo the MakeLower()
out.m_vsKeysoundFile.push_back( nData );
@@ -693,9 +695,9 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
if( fBPM > 0.0f )
{
BPMSegment newSeg( BeatToNoteRow(fBeat), fBPM );
out.m_SongTiming.AddBPMSegment( newSeg );
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", fBeat, newSeg.GetBPM() );
BPMSegment * newSeg = new BPMSegment( fBeat, fBPM );
out.m_SongTiming.AddSegment( SEGMENT_BPM, newSeg );
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", fBeat, newSeg->GetBPM() );
}
else
{
@@ -720,9 +722,9 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
float fBeats = StringToFloat( sBeats ) / 48.0f;
float fFreezeSecs = fBeats / fBPS;
StopSegment newSeg( BeatToNoteRow(fBeat), fFreezeSecs );
out.m_SongTiming.AddStopSegment( newSeg );
LOG->Trace( "Inserting new Freeze at beat %f, secs %f", fBeat, newSeg.GetPause() );
StopSegment * newSeg = new StopSegment( fBeat, fFreezeSecs );
out.m_SongTiming.AddSegment( SEGMENT_STOP_DELAY, newSeg );
LOG->Trace( "Inserting new Freeze at beat %f, secs %f", fBeat, newSeg->GetPause() );
}
else
{
@@ -749,9 +751,11 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
if( fBPM > 0.0f )
{
BPMSegment newSeg( iStepIndex, fBPM );
out.m_SongTiming.AddBPMSegment( newSeg );
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", newSeg.GetBeat(), newSeg.GetBPM() );
BPMSegment * newSeg = new BPMSegment( iStepIndex, fBPM );
out.m_SongTiming.AddSegment( SEGMENT_BPM, newSeg );
LOG->Trace("Inserting new BPM change at beat %f, BPM %f",
newSeg->GetBeat(),
newSeg->GetBPM() );
}
else
@@ -809,6 +813,64 @@ void PMSLoader::GetApplicableFiles( const RString &sPath, vector<RString> &out )
GetDirListing( sPath + RString("*.pms"), out );
}
bool PMSLoader::LoadNoteDataFromSimfile(const RString &cachePath, Steps &out)
{
Song dummy;
// TODO: Simplify this copy/paste from LoadFromDir.
vector<NameToData_t> BMSData;
BMSData.push_back(NameToData_t());
ReadPMSFile(cachePath, BMSData.back());
RString commonSubstring;
GetCommonTagFromMapList( BMSData, "#title", commonSubstring );
Steps *copy = dummy.CreateSteps();
copy->SetDifficulty( Difficulty_Medium );
RString sTag;
if( GetTagFromMap( BMSData[0], "#title", sTag ) && sTag.size() != commonSubstring.size() )
{
sTag = sTag.substr( commonSubstring.size(), sTag.size() - commonSubstring.size() );
sTag.MakeLower();
if( sTag.find('l') != sTag.npos )
{
unsigned lPos = sTag.find('l');
if( lPos > 2 && sTag.substr(lPos-2,4) == "solo" )
{
copy->SetDifficulty( Difficulty_Edit );
}
else
{
copy->SetDifficulty( Difficulty_Easy );
}
}
else if( sTag.find('a') != sTag.npos )
copy->SetDifficulty( Difficulty_Hard );
else if( sTag.find('b') != sTag.npos )
copy->SetDifficulty( Difficulty_Beginner );
}
if( commonSubstring == "" )
{
copy->SetDifficulty(Difficulty_Medium);
RString unused;
if (GetTagFromMap(BMSData[0], "#title#", sTag))
SearchForDifficulty(unused, copy);
}
MeasureToTimeSig_t sigAdjustments;
map<RString,int> idToKeysoundIndex;
ReadGlobalTags( cachePath, BMSData[0], dummy, sigAdjustments, idToKeysoundIndex );
const bool ok = LoadFromPMSFile( cachePath, BMSData[0], *copy, sigAdjustments, idToKeysoundIndex );
if( ok )
{
out.SetNoteData(copy->GetNoteData());
}
return ok;
}
bool PMSLoader::LoadFromDir( const RString &sDir, Song &out )
{
LOG->Trace( "Song::LoadFromPMSDir(%s)", sDir.c_str() );
@@ -914,7 +976,8 @@ bool PMSLoader::LoadFromDir( const RString &sDir, Song &out )
MeasureToTimeSig_t sigAdjustments;
map<RString,int> idToKeysoundIndex;
ReadGlobalTags( aPMSData[iMainDataIndex], out, sigAdjustments, idToKeysoundIndex );
ReadGlobalTags( sDir, aPMSData[iMainDataIndex], out, sigAdjustments, idToKeysoundIndex );
out.m_sSongFileName = out.GetSongDir() + arrayPMSFileNames[iMainDataIndex];
// Override what that global tag said about the title if we have a good substring.
// Prevents clobbering and catches "MySong (7keys)" / "MySong (Another) (7keys)"
@@ -929,7 +992,10 @@ bool PMSLoader::LoadFromDir( const RString &sDir, Song &out )
Steps* pNewNotes = apSteps[i];
const bool ok = LoadFromPMSFile( out.GetSongDir() + arrayPMSFileNames[i], aPMSData[i], *pNewNotes, sigAdjustments, idToKeysoundIndex );
if( ok )
{
pNewNotes->SetFilename(out.GetSongDir() + arrayPMSFileNames[i]);
out.AddSteps( pNewNotes );
}
else
delete pNewNotes;
}
@@ -940,7 +1006,7 @@ bool PMSLoader::LoadFromDir( const RString &sDir, Song &out )
ConvertString( out.m_sArtist, "utf-8,japanese" );
ConvertString( out.m_sGenre, "utf-8,japanese" );
out.TidyUpData();
out.TidyUpData(false, true);
return true;
}
+2
View File
@@ -2,11 +2,13 @@
#define NOTES_LOADER_PMS_H
class Song;
class Steps;
/** @brief Reads a Song from a set of .PMS files. */
namespace PMSLoader
{
void GetApplicableFiles( const RString &sPath, vector<RString> &out );
bool LoadFromDir( const RString &sDir, Song &out );
bool LoadNoteDataFromSimfile(const RString & cachePath, Steps & out);
}
#endif
+50 -58
View File
@@ -10,6 +10,7 @@
#include "Song.h"
#include "SongManager.h"
#include "Steps.h"
#include "Attack.h"
#include "PrefsManager.h"
void SMLoader::SetSongTitle(const RString & title)
@@ -95,23 +96,6 @@ void SMLoader::LoadFromTokens(
}
out.SetMeter( StringToInt(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 );
@@ -149,7 +133,8 @@ void SMLoader::ProcessAttackString( vector<RString> & attacks, MsdFile::value_t
{
RString tmp = params[s];
Trim(tmp);
attacks.push_back( tmp );
if (tmp.size() > 0)
attacks.push_back( tmp );
}
}
@@ -251,8 +236,8 @@ bool SMLoader::ProcessBPMs( TimingData &out, const RString line, const int rowsP
if( negBPM < 0 )
{
float endBeat = fBeat + (fNewBPM / -negBPM) * (fBeat - negBeat);
WarpSegment new_seg(negBeat, endBeat - negBeat);
out.AddWarpSegment( new_seg );
out.AddSegment(SEGMENT_WARP,
new WarpSegment(negBeat, endBeat - negBeat));
negBeat = -1;
negBPM = 1;
@@ -267,13 +252,13 @@ bool SMLoader::ProcessBPMs( TimingData &out, const RString line, const int rowsP
// add in a warp.
if( highspeedBeat > 0 )
{
WarpSegment new_seg(highspeedBeat, fBeat - highspeedBeat);
out.AddWarpSegment( new_seg );
out.AddSegment(SEGMENT_WARP,
new WarpSegment(highspeedBeat, fBeat - highspeedBeat) );
highspeedBeat = -1;
}
{
BPMSegment new_seg( BeatToNoteRow( fBeat ), fNewBPM );
out.AddBPMSegment( new_seg );
out.AddSegment(SEGMENT_BPM,
new BPMSegment(fBeat, fNewBPM));
}
}
}
@@ -310,15 +295,14 @@ void SMLoader::ProcessStops( TimingData &out, const RString line, const int rows
// Process the prior stop.
if( negPause > 0 )
{
BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat));
float fSecondsPerBeat = 60 / oldBPM.GetBPM();
BPMSegment * oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat));
float fSecondsPerBeat = 60 / oldBPM->GetBPM();
float fSkipBeats = negPause / fSecondsPerBeat;
if( negBeat + fSkipBeats > fFreezeBeat )
fSkipBeats = fFreezeBeat - negBeat;
WarpSegment ws( negBeat, fSkipBeats);
out.AddWarpSegment( ws );
out.AddSegment(SEGMENT_WARP, new WarpSegment(negBeat, fSkipBeats));
negBeat = -1;
negPause = 0;
@@ -331,8 +315,8 @@ void SMLoader::ProcessStops( TimingData &out, const RString line, const int rows
}
else if( fFreezeSeconds > 0.0f )
{
StopSegment ss( BeatToNoteRow(fFreezeBeat), fFreezeSeconds );
out.AddStopSegment( ss );
out.AddSegment(SEGMENT_STOP_DELAY,
new StopSegment(fFreezeBeat, fFreezeSeconds));
}
}
@@ -340,12 +324,11 @@ void SMLoader::ProcessStops( TimingData &out, const RString line, const int rows
// Process the prior stop if there was one.
if( negPause > 0 )
{
BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat));
float fSecondsPerBeat = 60 / oldBPM.GetBPM();
BPMSegment * oldBPM = out.GetBPMSegmentAtBeat(negBeat);
float fSecondsPerBeat = 60 / oldBPM->GetBPM();
float fSkipBeats = negPause / fSecondsPerBeat;
WarpSegment ws( negBeat, fSkipBeats);
out.AddWarpSegment( ws );
out.AddSegment(SEGMENT_WARP, new WarpSegment(negBeat, fSkipBeats));
}
}
@@ -370,15 +353,14 @@ void SMLoader::ProcessDelays( TimingData &out, const RString line, const int row
const float fFreezeBeat = RowToBeat( arrayDelayValues[0], rowsPerBeat );
const float fFreezeSeconds = StringToFloat( arrayDelayValues[1] );
StopSegment new_seg( fFreezeBeat, fFreezeSeconds, true );
// XXX: Remove Negatives Bug?
new_seg.SetBeat(fFreezeBeat);
new_seg.SetPause(fFreezeSeconds);
StopSegment * new_seg = new StopSegment(fFreezeBeat,
fFreezeSeconds,
true);
// LOG->Trace( "Adding a delay segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds );
if(fFreezeSeconds > 0.0f)
out.AddStopSegment( new_seg );
out.AddSegment( SEGMENT_STOP_DELAY, new_seg );
else
LOG->UserLog(
"Song file",
@@ -409,7 +391,10 @@ void SMLoader::ProcessTimeSignatures( TimingData &out, const RString line, const
const float fBeat = RowToBeat( vs2[0], rowsPerBeat );
TimeSignatureSegment seg( fBeat, StringToInt( vs2[1] ), StringToInt( vs2[2] ));
TimeSignatureSegment * seg =
new TimeSignatureSegment(fBeat,
StringToInt( vs2[1] ),
StringToInt( vs2[2] ));
if( fBeat < 0 )
{
@@ -420,25 +405,25 @@ void SMLoader::ProcessTimeSignatures( TimingData &out, const RString line, const
continue;
}
if( seg.GetNum() < 1 )
if( seg->GetNum() < 1 )
{
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid time signature change with beat %f, iNumerator %i.",
fBeat, seg.GetNum() );
fBeat, seg->GetNum() );
continue;
}
if( seg.GetDen() < 1 )
if( seg->GetDen() < 1 )
{
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid time signature change with beat %f, iDenominator %i.",
fBeat, seg.GetDen() );
fBeat, seg->GetDen() );
continue;
}
out.AddTimeSignatureSegment( seg );
out.AddSegment( SEGMENT_TIME_SIG, seg );
}
}
@@ -463,8 +448,8 @@ void SMLoader::ProcessTickcounts( TimingData &out, const RString line, const int
const float fTickcountBeat = RowToBeat( arrayTickcountValues[0], rowsPerBeat );
int iTicks = clamp(atoi( arrayTickcountValues[1] ), 0, ROWS_PER_BEAT);
TickcountSegment new_seg( fTickcountBeat, iTicks );
out.AddTickcountSegment( new_seg );
out.AddSegment( SEGMENT_TICKCOUNT,
new TickcountSegment(fTickcountBeat, iTicks) );
}
}
@@ -499,8 +484,10 @@ void SMLoader::ProcessSpeeds( TimingData &out, const RString line, const int row
const float fBeat = RowToBeat( vs2[0], rowsPerBeat );
SpeedSegment seg( fBeat, StringToFloat( vs2[1] ), StringToFloat( vs2[2] ));
seg.SetUnit(StringToInt(vs2[3]));
SpeedSegment * seg = new SpeedSegment(fBeat,
StringToFloat( vs2[1] ),
StringToFloat( vs2[2] ));
seg->SetUnit(StringToInt(vs2[3]));
if( fBeat < 0 )
{
@@ -511,16 +498,16 @@ void SMLoader::ProcessSpeeds( TimingData &out, const RString line, const int row
continue;
}
if( seg.GetLength() < 0 )
if( seg->GetLength() < 0 )
{
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an speed change with beat %f, length %f.",
fBeat, seg.GetLength() );
fBeat, seg->GetLength() );
continue;
}
out.AddSpeedSegment( seg );
out.AddSegment( SEGMENT_SPEED, seg );
}
}
@@ -546,7 +533,7 @@ void SMLoader::ProcessFakes( TimingData &out, const RString line, const int rows
const float fNewBeat = StringToFloat( arrayFakeValues[1] );
if(fNewBeat > 0)
out.AddFakeSegment( FakeSegment(fBeat, fNewBeat) );
out.AddSegment( SEGMENT_FAKE, new FakeSegment(fBeat, fNewBeat) );
else
{
LOG->UserLog("Song file",
@@ -643,9 +630,8 @@ bool SMLoader::LoadFromBGChangesString( BackgroundChange &change, const RString
return aBGChangeValues.size() >= 2;
}
bool SMLoader::LoadNotedataFromSimfile( const RString &path, Steps &out )
bool SMLoader::LoadNoteDataFromSimfile( const RString &path, Steps &out )
{
// stub: do this later.
MsdFile msd;
if( !msd.ReadFile( path, true ) ) // unescape
{
@@ -696,7 +682,7 @@ bool SMLoader::LoadNotedataFromSimfile( const RString &path, Steps &out )
RString noteData = sParams[6];
Trim( noteData );
out.SetSMNoteData( noteData );
out.TidyUpData();
return true;
}
}
@@ -715,6 +701,7 @@ bool SMLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache
}
out.m_SongTiming.m_sFile = sPath;
out.m_sSongFileName = sPath;
for( unsigned i=0; i<msd.GetNumValues(); i++ )
{
@@ -922,6 +909,7 @@ bool SMLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache
sParams[6],
*pNewNotes );
pNewNotes->SetFilename(sPath);
out.AddSteps( pNewNotes );
}
// XXX: Does anyone know what LEADTRACK is for? -Wolfman2000
@@ -932,7 +920,8 @@ bool SMLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache
}
// Ensure all warps from negative time changes are in order.
sort(out.m_SongTiming.m_WarpSegments.begin(), out.m_SongTiming.m_WarpSegments.end());
vector<TimingSegment *> &warps = out.m_SongTiming.allTimingSegments[SEGMENT_WARP];
sort(warps.begin(), warps.end());
TidyUpData( out, bFromCache );
return true;
}
@@ -1107,7 +1096,10 @@ void SMLoader::TidyUpData( Song &song, bool bFromCache )
bg.push_back( BackgroundChange(lastBeat,song.m_sBackgroundFile) );
} while(0);
}
song.TidyUpData( bFromCache );
if (bFromCache)
{
song.TidyUpData( bFromCache, true );
}
}
/*
+1 -1
View File
@@ -46,7 +46,7 @@ struct SMLoader
* @brief Retrieve the relevant notedata from the simfile.
* @param path the path where the simfile lives.
* @param out the Steps we are loading the data into. */
virtual bool LoadNotedataFromSimfile(const RString &path, Steps &out );
virtual bool LoadNoteDataFromSimfile(const RString &path, Steps &out );
/**
* @brief Attempt to load the specified sm file.
+18 -13
View File
@@ -38,8 +38,8 @@ void SMALoader::ProcessMultipliers( TimingData &out, const int iRowsPerBeat, con
const int iMisses = (size == 2 || size == 4 ?
iCombos :
StringToInt(arrayMultiplierValues[2]));
ComboSegment new_seg( fComboBeat, iCombos, iMisses );
out.AddComboSegment( new_seg );
out.AddSegment(SEGMENT_COMBO,
new ComboSegment( fComboBeat, iCombos, iMisses ));
}
}
@@ -64,7 +64,9 @@ void SMALoader::ProcessBeatsPerMeasure( TimingData &out, const RString sParam )
const float fBeat = StringToFloat( vs2[0] );
TimeSignatureSegment seg( fBeat, StringToInt( vs2[1] ), 4 );
TimeSignatureSegment * seg = new TimeSignatureSegment(fBeat,
StringToInt(vs2[1]),
4 );
if( fBeat < 0 )
{
@@ -75,16 +77,16 @@ void SMALoader::ProcessBeatsPerMeasure( TimingData &out, const RString sParam )
continue;
}
if( seg.GetNum() < 1 )
if( seg->GetNum() < 1 )
{
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an invalid time signature change with beat %f, iNumerator %i.",
fBeat, seg.GetNum() );
fBeat, seg->GetNum() );
continue;
}
out.AddTimeSignatureSegment( seg );
out.AddSegment( SEGMENT_TIME_SIG, seg );
}
}
@@ -123,8 +125,10 @@ void SMALoader::ProcessSpeeds( TimingData &out, const RString line, const int ro
unsigned short tmp = ((backup != vs2[2]) ? 1 : 0);
SpeedSegment seg(fBeat, StringToFloat( vs2[1] ), StringToFloat(vs2[2]), tmp);
//seg.SetUnit(tmp);
SpeedSegment * seg = new SpeedSegment(fBeat,
StringToFloat( vs2[1] ),
StringToFloat(vs2[2]),
tmp);
if( fBeat < 0 )
{
@@ -135,16 +139,16 @@ void SMALoader::ProcessSpeeds( TimingData &out, const RString line, const int ro
continue;
}
if( seg.GetLength() < 0 )
if( seg->GetLength() < 0 )
{
LOG->UserLog("Song file",
this->GetSongTitle(),
"has an speed change with beat %f, length %f.",
fBeat, seg.GetLength() );
fBeat, seg->GetLength() );
continue;
}
out.AddSpeedSegment( seg );
out.AddSegment( SEGMENT_SPEED, seg );
}
}
@@ -160,6 +164,7 @@ bool SMALoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
}
out.m_SongTiming.m_sFile = sPath; // songs still have their fallback timing.
out.m_sSongFileName = sPath;
int state = SMA_GETTING_SONG_INFO;
Steps* pNewNotes = NULL;
@@ -446,7 +451,7 @@ bool SMALoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
sParams[5],
sParams[6],
*pNewNotes );
pNewNotes->SetFilename(sPath);
out.AddSteps( pNewNotes );
}
else if( sValueName=="TIMESIGNATURES" || sValueName=="LEADTRACK" )
@@ -458,7 +463,7 @@ bool SMALoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
sValueName.c_str() );
}
TidyUpData(out, false);
out.TidyUpData();
out.TidyUpData(false, true);
return true;
}
+128 -22
View File
@@ -37,10 +37,10 @@ void SSCLoader::ProcessWarps( TimingData &out, const RString sParam, const float
// Early versions were absolute in beats. They should be relative.
if( ( fVersion < VERSION_SPLIT_TIMING && fNewBeat > fBeat ) )
{
out.AddWarpSegment( WarpSegment(fBeat, fNewBeat - fBeat) );
out.AddSegment( SEGMENT_WARP, new WarpSegment(fBeat, fNewBeat - fBeat) );
}
else if( fNewBeat > 0 )
out.AddWarpSegment( WarpSegment(fBeat, fNewBeat) );
out.AddSegment( SEGMENT_WARP, new WarpSegment(fBeat, fNewBeat) );
else
{
LOG->UserLog("Song file",
@@ -73,7 +73,7 @@ void SSCLoader::ProcessLabels( TimingData &out, const RString sParam )
RString sLabel = arrayLabelValues[1];
TrimRight(sLabel);
if( fBeat >= 0.0f )
out.AddLabelSegment( LabelSegment(fBeat, sLabel) );
out.AddSegment( SEGMENT_LABEL, new LabelSegment(fBeat, sLabel) );
else
{
LOG->UserLog("Song file",
@@ -106,8 +106,7 @@ void SSCLoader::ProcessCombos( TimingData &out, const RString line, const int ro
const float fComboBeat = StringToFloat( arrayComboValues[0] );
const int iCombos = StringToInt( arrayComboValues[1] );
const int iMisses = (size == 2 ? iCombos : StringToInt(arrayComboValues[2]));
ComboSegment new_seg( fComboBeat, iCombos, iMisses );
out.AddComboSegment( new_seg );
out.AddSegment( SEGMENT_COMBO, new ComboSegment( fComboBeat, iCombos, iMisses ) );
}
}
@@ -132,7 +131,7 @@ void SSCLoader::ProcessScrolls( TimingData &out, const RString sParam )
const float fBeat = StringToFloat( vs2[0] );
ScrollSegment seg( fBeat, StringToFloat( vs2[1] ) );
ScrollSegment * seg = new ScrollSegment(fBeat, StringToFloat( vs2[1] ) );
if( fBeat < 0 )
{
@@ -143,10 +142,99 @@ void SSCLoader::ProcessScrolls( TimingData &out, const RString sParam )
continue;
}
out.AddScrollSegment( seg );
out.AddSegment( SEGMENT_SCROLL, seg );
}
}
bool SSCLoader::LoadNoteDataFromSimfile( const RString & cachePath, Steps &out )
{
LOG->Trace( "Loading notes from %s", cachePath.c_str() );
MsdFile msd;
if (!msd.ReadFile(cachePath, true))
{
LOG->UserLog("Unable to load any notes from",
cachePath,
"for this reason: %s",
msd.GetError().c_str());
return false;
}
bool tryingSteps = false;
float storedVersion = 0;
const unsigned values = msd.GetNumValues();
for (unsigned i = 0; i < values; i++)
{
const MsdFile::value_t &params = msd.GetValue(i);
RString valueName = params[0];
valueName.MakeUpper();
RString matcher = params[1]; // mainly for debugging.
Trim(matcher);
if (valueName=="VERSION")
{
storedVersion = StringToFloat(matcher);
}
if (tryingSteps)
{
if( valueName=="STEPSTYPE" )
{
if (out.m_StepsType != GAMEMAN->StringToStepsType(matcher))
tryingSteps = false;
}
else if( valueName=="CHARTNAME")
{
if (storedVersion >= VERSION_CHART_NAME_TAG && out.GetChartName() != matcher)
tryingSteps = false;
}
else if( valueName=="DESCRIPTION" )
{
if (storedVersion < VERSION_CHART_NAME_TAG)
{
if (out.GetChartName() != matcher)
tryingSteps = false;
}
else if (out.GetDescription() != matcher)
tryingSteps = false;
}
else if( valueName=="DIFFICULTY" )
{
if (out.GetDifficulty() != StringToDifficulty(matcher))
tryingSteps = false;
}
else if( valueName=="METER" )
{
if (out.GetMeter() != StringToInt(matcher))
tryingSteps = false;
}
else if( valueName=="CREDIT" )
{
if (out.GetCredit() != matcher)
tryingSteps = false;
}
else if( valueName=="NOTES" || valueName=="NOTES2" )
{
out.SetSMNoteData(matcher);
out.TidyUpData();
return true;
}
}
else
{
if(valueName == "NOTEDATA")
{
tryingSteps = true;
}
}
}
return false;
}
bool SSCLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache )
{
LOG->Trace( "Song::LoadFromSSCFile(%s)", sPath.c_str() );
@@ -159,6 +247,7 @@ bool SSCLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
}
out.m_SongTiming.m_sFile = sPath; // songs still have their fallback timing.
out.m_sSongFileName = sPath;
int state = GETTING_SONG_INFO;
const unsigned values = msd.GetNumValues();
@@ -485,27 +574,35 @@ bool SSCLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
else if( sValueName=="RADARVALUES" )
{
vector<RString> saValues;
split( sParams[1], ",", saValues, true );
int categories = NUM_RadarCategory;
if( out.m_fVersion < VERSION_RADAR_FAKE )
categories -= 1;
if( saValues.size() == (unsigned)categories * NUM_PLAYERS )
if (bFromCache)
{
RadarValues v[NUM_PLAYERS];
FOREACH_PlayerNumber( pn )
vector<RString> saValues;
split( sParams[1], ",", saValues, true );
int categories = NUM_RadarCategory;
if( out.m_fVersion < VERSION_RADAR_FAKE )
categories -= 1;
if( saValues.size() == (unsigned)categories * NUM_PLAYERS )
{
// Can't use the foreach anymore due to flexible radar lines.
for( RadarCategory rc = (RadarCategory)0; rc < categories;
enum_add<RadarCategory>( rc, +1 ) )
RadarValues v[NUM_PLAYERS];
FOREACH_PlayerNumber( pn )
{
v[pn][rc] = StringToFloat( saValues[pn*categories + rc] );
// 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] );
}
}
pNewNotes->SetCachedRadarValues( v );
}
pNewNotes->SetCachedRadarValues( v );
}
else
{
// just recalc at time.
}
}
else if( sValueName=="CREDIT" )
@@ -520,6 +617,7 @@ bool SSCLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
pNewNotes->m_Timing = stepsTiming;
pNewNotes->SetSMNoteData( sParams[1] );
pNewNotes->TidyUpData();
pNewNotes->SetFilename(sPath);
out.AddSteps( pNewNotes );
}
@@ -606,6 +704,14 @@ bool SSCLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
pNewNotes->SetMaxBPM(StringToFloat(sParams[2]));
}
}
else if( sValueName=="STEPFILENAME" )
{
state = GETTING_SONG_INFO;
if( bHasOwnTiming )
pNewNotes->m_Timing = stepsTiming;
pNewNotes->SetFilename(sParams[1]);
out.AddSteps( pNewNotes );
}
break;
}
}
+8
View File
@@ -30,6 +30,8 @@ const float VERSION_SPLIT_TIMING = 0.7f;
const float VERSION_OFFSET_BEFORE_ATTACK = 0.72f;
/** @brief The version that introduced the Chart Name tag. */
const float VERSION_CHART_NAME_TAG = 0.74f;
/** @brief The version that introduced the cache switch tag. */
const float VERSION_CACHE_SWITCH_TAG = 0.77f;
/**
* @brief The SSCLoader handles all of the parsing needed for .ssc files.
@@ -65,6 +67,12 @@ struct SSCLoader : public SMLoader
*/
bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong );
/**
* @brief Retrieve the specific NoteData from the file.
* @param cachePath the path to the cache file.
* @param out the Steps to receive just the particular notedata.
* @return true if successful, false otherwise. */
virtual bool LoadNoteDataFromSimfile( const RString &cachePath, Steps &out );
void ProcessWarps( TimingData &, const RString, const float );
void ProcessLabels( TimingData &, const RString );
+22 -16
View File
@@ -123,9 +123,10 @@ static RString NotesToDWIString( const TapNote tnCols[6] )
{
switch( tnCols[col].type )
{
case TapNote::empty:
case TapNote::mine:
continue;
case TapNote::empty:
case TapNote::mine:
continue;
default: break;
}
if( tnCols[col].type == TapNote::hold_head )
@@ -352,9 +353,13 @@ bool NotesWriterDWI::Write( RString sPath, const Song &out )
/* Write transliterations, if we have them, since DWI doesn't support UTF-8. */
f.PutLine( ssprintf("#TITLE:%s;", DwiEscape(out.GetTranslitFullTitle()).c_str()) );
f.PutLine( ssprintf("#ARTIST:%s;", DwiEscape(out.GetTranslitArtist()).c_str()) );
ASSERT( out.m_SongTiming.m_BPMSegments[0].GetRow() == 0 );
const vector<TimingSegment *> &bpms = out.m_SongTiming.allTimingSegments[SEGMENT_BPM];
ASSERT_M(bpms[0]->GetRow() == 0,
ssprintf("The first BPM Segment must be defined at row 0, not %d!", bpms[0]->GetRow()) );
f.PutLine( ssprintf("#FILE:%s;", DwiEscape(out.m_sMusicFile).c_str()) );
f.PutLine( ssprintf("#BPM:%.3f;", out.m_SongTiming.m_BPMSegments[0].GetBPM()) );
f.PutLine( ssprintf("#BPM:%.3f;", static_cast<BPMSegment *>(bpms[0])->GetBPM()) );
f.PutLine( ssprintf("#GAP:%ld;", -lrintf( out.m_SongTiming.m_fBeat0OffsetInSeconds*1000 )) );
f.PutLine( ssprintf("#SAMPLESTART:%.3f;", out.m_fMusicSampleStartSeconds) );
f.PutLine( ssprintf("#SAMPLELENGTH:%.3f;", out.m_fMusicSampleLengthSeconds) );
@@ -376,29 +381,30 @@ bool NotesWriterDWI::Write( RString sPath, const Song &out )
break;
}
if( !out.m_SongTiming.m_StopSegments.empty() )
const vector<TimingSegment *> &stops = out.m_SongTiming.allTimingSegments[SEGMENT_STOP_DELAY];
if( !stops.empty() )
{
f.Write( "#FREEZE:" );
for( unsigned i=0; i<out.m_SongTiming.m_StopSegments.size(); i++ )
for( unsigned i=0; i<stops.size(); i++ )
{
const StopSegment &fs = out.m_SongTiming.m_StopSegments[i];
f.Write( ssprintf("%.3f=%.3f", fs.GetRow() * 4.0f / ROWS_PER_BEAT,
roundf(fs.GetPause()*1000)) );
if( i != out.m_SongTiming.m_StopSegments.size()-1 )
const StopSegment *fs = static_cast<StopSegment *>(stops[i]);
f.Write( ssprintf("%.3f=%.3f", fs->GetRow() * 4.0f / ROWS_PER_BEAT,
roundf(fs->GetPause()*1000)) );
if( i != stops.size()-1 )
f.Write( "," );
}
f.PutLine( ";" );
}
if( out.m_SongTiming.m_BPMSegments.size() > 1)
if( bpms.size() > 1)
{
f.Write( "#CHANGEBPM:" );
for( unsigned i=1; i<out.m_SongTiming.m_BPMSegments.size(); i++ )
for( unsigned i=1; i<bpms.size(); i++ )
{
const BPMSegment &bs = out.m_SongTiming.m_BPMSegments[i];
f.Write( ssprintf("%.3f=%.3f", bs.GetRow() * 4.0f / ROWS_PER_BEAT, bs.GetBPM() ) );
if( i != out.m_SongTiming.m_BPMSegments.size()-1 )
const BPMSegment *bs = static_cast<BPMSegment *>(bpms[i]);
f.Write( ssprintf("%.3f=%.3f", bs->GetRow() * 4.0f / ROWS_PER_BEAT, bs->GetBPM() ) );
if( i != bpms.size()-1 )
f.Write( "," );
}
f.PutLine( ";" );
+11 -10
View File
@@ -9,22 +9,23 @@
#include "NoteData.h"
#include "GameManager.h"
static void Serialize(const BPMSegment &seg, Json::Value &root)
static void Serialize(const TimingSegment &seg, Json::Value &root)
{
root["Beat"] = seg.GetBeat();
root["BPM"] = seg.GetBPM();
}
static void Serialize(const StopSegment &seg, Json::Value &root)
{
root["Beat"] = seg.GetBeat();
root["Seconds"] = seg.GetPause();
if (seg.GetType() == SEGMENT_BPM)
{
root["BPM"] = static_cast<BPMSegment &>(const_cast<TimingSegment &>(seg)).GetBPM();
}
else
{
root["Seconds"] = static_cast<StopSegment &>(const_cast<TimingSegment &>(seg)).GetPause();
}
}
static void Serialize(const TimingData &td, Json::Value &root)
{
JsonUtil::SerializeVectorObjects( td.m_BPMSegments, Serialize, root["BpmSegments"] );
JsonUtil::SerializeVectorObjects( td.m_StopSegments, Serialize, root["StopSegments"] );
JsonUtil::SerializeVectorPointers( td.allTimingSegments[SEGMENT_BPM], Serialize, root["BpmSegments"] );
JsonUtil::SerializeVectorPointers( td.allTimingSegments[SEGMENT_STOP_DELAY], Serialize, root["StopSegments"] );
}
static void Serialize(const LyricSegment &o, Json::Value &root)
+25 -56
View File
@@ -19,37 +19,13 @@
ThemeMetric<bool> USE_CREDIT ( "NotesWriterSM", "DescriptionUsesCreditField" );
/**
* @brief Turn the BackgroundChange into a string.
* @param bgc the BackgroundChange in question.
* @return the converted string. */
static RString BackgroundChangeToString( const BackgroundChange &bgc )
{
// TODO: Technically we need to double-escape the filename (because it might
// contain '=') and then unescape the value returned by the MsdFile.
RString s = ssprintf(
"%.3f=%s=%.3f=%d=%d=%d=%s=%s=%s=%s=%s",
bgc.m_fStartBeat,
SmEscape(bgc.m_def.m_sFile1).c_str(),
bgc.m_fRate,
bgc.m_sTransition == SBT_CrossFade, // backward compat
bgc.m_def.m_sEffect == SBE_StretchRewind, // backward compat
bgc.m_def.m_sEffect != SBE_StretchNoLoop, // backward compat
bgc.m_def.m_sEffect.c_str(),
bgc.m_def.m_sFile2.c_str(),
bgc.m_sTransition.c_str(),
SmEscape(RageColor::NormalizeColorString(bgc.m_def.m_sColor1)).c_str(),
SmEscape(RageColor::NormalizeColorString(bgc.m_def.m_sColor2)).c_str()
);
return s;
}
/**
* @brief Write out the common tags for .SM files.
* @param f the file in question.
* @param out the Song in question. */
static void WriteGlobalTags( RageFile &f, Song &out )
{
TimingData &timing = out.m_SongTiming;
f.PutLine( ssprintf( "#TITLE:%s;", SmEscape(out.m_sMainTitle).c_str() ) );
f.PutLine( ssprintf( "#SUBTITLE:%s;", SmEscape(out.m_sSubTitle).c_str() ) );
f.PutLine( ssprintf( "#ARTIST:%s;", SmEscape(out.m_sArtist).c_str() ) );
@@ -99,44 +75,46 @@ static void WriteGlobalTags( RageFile &f, Song &out )
f.Write( "#BPMS:" );
for( unsigned i=0; i<out.m_SongTiming.m_BPMSegments.size(); i++ )
vector<TimingSegment *> &bpms = timing.allTimingSegments[SEGMENT_BPM];
for( unsigned i=0; i<bpms.size(); i++ )
{
const BPMSegment &bs = out.m_SongTiming.m_BPMSegments[i];
const BPMSegment *bs = static_cast<BPMSegment *>(bpms[i]);
f.PutLine( ssprintf( "%.3f=%.3f", bs.GetBeat(), bs.GetBPM() ) );
if( i != out.m_SongTiming.m_BPMSegments.size()-1 )
f.PutLine( ssprintf( "%.3f=%.3f", bs->GetBeat(), bs->GetBPM() ) );
if( i != bpms.size()-1 )
f.Write( "," );
}
f.PutLine( ";" );
unsigned wSize = out.m_SongTiming.m_WarpSegments.size();
vector<TimingSegment *> &warps = timing.allTimingSegments[SEGMENT_WARP];
unsigned wSize = warps.size();
if( wSize > 0 )
{
for( unsigned i=0; i < wSize; i++ )
{
int iRow = out.m_SongTiming.m_WarpSegments[i].GetRow();
const WarpSegment *ws = static_cast<WarpSegment *>(warps[i]);
int iRow = ws->GetRow();
float fBPS = 60 / out.m_SongTiming.GetBPMAtRow(iRow);
float fSkip = fBPS * out.m_SongTiming.m_WarpSegments[i].GetLength();
StopSegment ss(iRow, -fSkip, false);
out.m_SongTiming.AddStopSegment( ss );
float fSkip = fBPS * ws->GetLength();
out.m_SongTiming.AddSegment(SEGMENT_STOP_DELAY,
new StopSegment(iRow, -fSkip, false) );
}
}
f.Write( "#STOPS:" );
for( unsigned i=0; i<out.m_SongTiming.m_StopSegments.size(); i++ )
vector<TimingSegment *> &stops = timing.allTimingSegments[SEGMENT_STOP_DELAY];
for( unsigned i=0; i<stops.size(); i++ )
{
const StopSegment &fs = out.m_SongTiming.m_StopSegments[i];
float fBeat = fs.GetBeat();
if (fs.GetDelay()) fBeat--;
const StopSegment *fs = static_cast<StopSegment *>(stops[i]);
float fBeat = fs->GetBeat();
if (fs->GetDelay()) fBeat--;
f.PutLine( ssprintf( "%.3f=%.3f", fBeat, fs.GetPause() ) );
if( i != out.m_SongTiming.m_StopSegments.size()-1 )
f.PutLine( ssprintf( "%.3f=%.3f", fBeat, fs->GetPause() ) );
if( i != stops.size()-1 )
f.Write( "," );
if( fs.GetPause() < 0 )
if( fs->GetPause() < 0 )
{
out.m_SongTiming.m_StopSegments.erase(
out.m_SongTiming.m_StopSegments.begin()+i,
out.m_SongTiming.m_StopSegments.begin()+i+1 );
stops.erase(stops.begin()+i,stops.begin()+i+1 );
i--;
}
}
@@ -152,7 +130,7 @@ static void WriteGlobalTags( RageFile &f, Song &out )
f.Write( ssprintf("#BGCHANGES%d:", b+1) );
FOREACH_CONST( BackgroundChange, out.GetBackgroundChanges(b), bgc )
f.PutLine( BackgroundChangeToString(*bgc)+"," );
f.PutLine( (*bgc).ToString() +"," );
/* If there's an animation plan at all, add a dummy "-nosongbg-" tag to indicate that
* this file doesn't want a song BG entry added at the end. See SMLoader::TidyUpData.
@@ -168,7 +146,7 @@ static void WriteGlobalTags( RageFile &f, Song &out )
f.Write( "#FGCHANGES:" );
FOREACH_CONST( BackgroundChange, out.GetForegroundChanges(), bgc )
{
f.PutLine( BackgroundChangeToString(*bgc)+"," );
f.PutLine( (*bgc).ToString() +"," );
}
f.PutLine( ";" );
}
@@ -182,16 +160,7 @@ static void WriteGlobalTags( RageFile &f, Song &out )
}
f.PutLine( ";" );
f.Write( "#ATTACKS:" );
for( unsigned a=0; a < out.m_sAttackString.size(); a++ )
{
RString sData = out.m_sAttackString[a];
f.Write( ssprintf( "%s", sData.c_str() ) );
if( a != (out.m_sAttackString.size() - 1) )
f.Write( ":" ); // Not the end, so write a divider ':'
}
f.PutLine( ";" );
f.PutLine( ssprintf("#ATTACKS:%s;", out.GetAttackString().c_str()) );
}
/**
+100 -83
View File
@@ -16,31 +16,6 @@
#include "Song.h"
#include "Steps.h"
/**
* @brief Turn the BackgroundChange into a string.
* @param bgc the BackgroundChange in question.
* @return the converted string. */
static RString BackgroundChangeToString( const BackgroundChange &bgc )
{
// TODO: Technically we need to double-escape the filename (because it might contain '=') and then
// unescape the value returned by the MsdFile.
RString s = ssprintf(
"%.3f=%s=%.3f=%d=%d=%d=%s=%s=%s=%s=%s",
bgc.m_fStartBeat,
SmEscape(bgc.m_def.m_sFile1).c_str(),
bgc.m_fRate,
bgc.m_sTransition == SBT_CrossFade, // backward compat
bgc.m_def.m_sEffect == SBE_StretchRewind, // backward compat
bgc.m_def.m_sEffect != SBE_StretchNoLoop, // backward compat
bgc.m_def.m_sEffect.c_str(),
bgc.m_def.m_sFile2.c_str(),
bgc.m_sTransition.c_str(),
SmEscape(RageColor::NormalizeColorString(bgc.m_def.m_sColor1)).c_str(),
SmEscape(RageColor::NormalizeColorString(bgc.m_def.m_sColor2)).c_str()
);
return s;
}
/**
* @brief Turn a vector of lines into a single line joined by newline characters.
* @param lines the list of lines to join.
@@ -90,45 +65,71 @@ static void GetTimingTags( vector<RString> &lines, TimingData timing, bool bIsSo
TimingTagWriter w ( &lines );
timing.TidyUpData();
unsigned i = 0;
w.Init( "BPMS" );
FOREACH_CONST( BPMSegment, timing.m_BPMSegments, bs )
vector<TimingSegment *> &bpms = timing.allTimingSegments[SEGMENT_BPM];
for (; i < bpms.size(); i++)
{
BPMSegment *bs = static_cast<BPMSegment *>(bpms[i]);
w.Write( bs->GetRow(), bs->GetBPM() );
}
w.Finish();
w.Init( "STOPS" );
FOREACH_CONST( StopSegment, timing.m_StopSegments, ss )
vector<TimingSegment *> &stops = timing.allTimingSegments[SEGMENT_STOP_DELAY];
for (i = 0; i < stops.size(); i++)
{
StopSegment *ss = static_cast<StopSegment *>(stops[i]);
if( !ss->GetDelay() )
w.Write( ss->GetRow(), ss->GetPause() );
}
w.Finish();
w.Init( "DELAYS" );
FOREACH_CONST( StopSegment, timing.m_StopSegments, ss )
for (i = 0; i < stops.size(); i++)
{
StopSegment *ss = static_cast<StopSegment *>(stops[i]);
if( ss->GetDelay() )
w.Write( ss->GetRow(), ss->GetPause() );
}
w.Finish();
w.Init( "WARPS" );
FOREACH_CONST( WarpSegment, timing.m_WarpSegments, ws )
vector<TimingSegment *> &warps = timing.allTimingSegments[SEGMENT_WARP];
for (i = 0; i < warps.size(); i++)
{
WarpSegment *ws = static_cast<WarpSegment *>(warps[i]);
w.Write( ws->GetRow(), ws->GetLength() );
}
w.Finish();
ASSERT( !timing.m_vTimeSignatureSegments.empty() );
vector<TimingSegment *> &tSigs = timing.allTimingSegments[SEGMENT_TIME_SIG];
ASSERT( !tSigs.empty() );
w.Init( "TIMESIGNATURES" );
FOREACH_CONST( TimeSignatureSegment, timing.m_vTimeSignatureSegments, iter )
w.Write( iter->GetRow(), iter->GetNum(), iter->GetDen() );
for (i = 0; i < tSigs.size(); i++)
{
TimeSignatureSegment *ts = static_cast<TimeSignatureSegment *>(tSigs[i]);
w.Write( ts->GetRow(), ts->GetNum(), ts->GetDen() );
}
w.Finish();
ASSERT( !timing.m_TickcountSegments.empty() );
vector<TimingSegment *> &ticks = timing.allTimingSegments[SEGMENT_TICKCOUNT];
ASSERT( !ticks.empty() );
w.Init( "TICKCOUNTS" );
FOREACH_CONST( TickcountSegment, timing.m_TickcountSegments, ts )
for (i = 0; i < ticks.size(); i++)
{
TickcountSegment *ts = static_cast<TickcountSegment *>(ticks[i]);
w.Write( ts->GetRow(), ts->GetTicks() );
}
w.Finish();
ASSERT( !timing.m_ComboSegments.empty() );
vector<TimingSegment *> &combos = timing.allTimingSegments[SEGMENT_COMBO];
ASSERT( !combos.empty() );
w.Init( "COMBOS" );
FOREACH_CONST( ComboSegment, timing.m_ComboSegments, cs )
for (i = 0; i < combos.size(); i++)
{
ComboSegment *cs = static_cast<ComboSegment *>(combos[i]);
if (cs->GetCombo() == cs->GetMissCombo())
w.Write( cs->GetRow(), cs->GetCombo() );
else
@@ -137,38 +138,71 @@ static void GetTimingTags( vector<RString> &lines, TimingData timing, bool bIsSo
w.Finish();
// Song Timing should only have the initial value.
vector<TimingSegment *> &speeds = timing.allTimingSegments[SEGMENT_SPEED];
w.Init( "SPEEDS" );
FOREACH_CONST( SpeedSegment, timing.m_SpeedSegments, ss )
for (i = 0; i < speeds.size(); i++)
{
SpeedSegment *ss = static_cast<SpeedSegment *>(speeds[i]);
w.Write( ss->GetRow(), ss->GetRatio(), ss->GetLength(), ss->GetUnit() );
}
w.Finish();
w.Init( "SCROLLS" );
FOREACH_CONST( ScrollSegment, timing.m_ScrollSegments, ss )
vector<TimingSegment *> &scrolls = timing.allTimingSegments[SEGMENT_SCROLL];
for (i = 0; i < scrolls.size(); i++)
{
ScrollSegment *ss = static_cast<ScrollSegment *>(scrolls[i]);
w.Write( ss->GetRow(), ss->GetRatio() );
}
w.Finish();
if( !bIsSong )
{
vector<TimingSegment *> &fakes = timing.allTimingSegments[SEGMENT_FAKE];
w.Init( "FAKES" );
FOREACH_CONST( FakeSegment, timing.m_FakeSegments, fs )
for (i = 0; i < fakes.size(); i++)
{
FakeSegment *fs = static_cast<FakeSegment *>(fakes[i]);
w.Write( fs->GetRow(), fs->GetLength() );
}
w.Finish();
}
w.Init( "LABELS" );
FOREACH_CONST( LabelSegment, timing.m_LabelSegments, ls )
vector<TimingSegment *> &labels = timing.allTimingSegments[SEGMENT_LABEL];
for (i = 0; i < labels.size(); i++)
{
LabelSegment *ls = static_cast<LabelSegment *>(labels[i]);
w.Write( ls->GetRow(), ls->GetLabel().c_str() );
}
w.Finish();
}
static void WriteTimingTags( RageFile &f, const TimingData &timing, bool bIsSong = false )
{
vector<RString> lines;
GetTimingTags( lines, timing, bIsSong );
f.PutLine( JoinLineList( lines ) );
f.PutLine(ssprintf("#BPMS:%s;",
join(",\r\n", timing.ToVectorString(SEGMENT_BPM)).c_str()));
f.PutLine(ssprintf("#STOPS:%s;",
join(",\r\n", timing.ToVectorString(SEGMENT_STOP_DELAY, false)).c_str()));
f.PutLine(ssprintf("#DELAYS:%s;",
join(",\r\n", timing.ToVectorString(SEGMENT_STOP_DELAY, true)).c_str()));
f.PutLine(ssprintf("#WARPS:%s;",
join(",\r\n", timing.ToVectorString(SEGMENT_WARP)).c_str()));
f.PutLine(ssprintf("#TIMESIGNATURES:%s;",
join(",\r\n", timing.ToVectorString(SEGMENT_TIME_SIG)).c_str()));
f.PutLine(ssprintf("#TICKCOUNTS:%s;",
join(",\r\n", timing.ToVectorString(SEGMENT_TICKCOUNT)).c_str()));
f.PutLine(ssprintf("#COMBOS:%s;",
join(",\r\n", timing.ToVectorString(SEGMENT_COMBO)).c_str()));
f.PutLine(ssprintf("#SPEEDS:%s;",
join(",\r\n", timing.ToVectorString(SEGMENT_SPEED)).c_str()));
f.PutLine(ssprintf("#SCROLLS:%s;",
join(",\r\n", timing.ToVectorString(SEGMENT_SCROLL)).c_str()));
if (!bIsSong)
f.PutLine(ssprintf("#FAKES:%s;",
join(",\r\n", timing.ToVectorString(SEGMENT_FAKE)).c_str()));
f.PutLine(ssprintf("#LABELS:%s;",
join(",\r\n", timing.ToVectorString(SEGMENT_LABEL)).c_str()));
}
@@ -195,10 +229,7 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
f.PutLine( ssprintf( "#MUSIC:%s;", SmEscape(out.m_sMusicFile).c_str() ) );
{
vector<RString> vs;
FOREACH_ENUM( InstrumentTrack, it )
if( out.HasInstrumentTrack(it) )
vs.push_back( InstrumentTrackToString(it) + "=" + out.m_sInstrumentTrackFile[it] );
vector<RString> vs = out.GetInstrumentTracksToVectorString();
if( !vs.empty() )
{
RString s = join( ",", vs );
@@ -212,7 +243,7 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
f.Write( "#SELECTABLE:" );
switch(out.m_SelectionDisplay)
{
default: ASSERT(0); // fall through
default: ASSERT_M(0, "An invalid selectable value was found for this song!"); // fall through
case Song::SHOW_ALWAYS: f.Write( "YES" ); break;
//case Song::SHOW_NONSTOP: f.Write( "NONSTOP" ); break;
case Song::SHOW_NEVER: f.Write( "NO" ); break;
@@ -250,7 +281,7 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
f.Write( ssprintf("#BGCHANGES%d:", b+1) );
FOREACH_CONST( BackgroundChange, out.GetBackgroundChanges(b), bgc )
f.PutLine( BackgroundChangeToString(*bgc)+"," );
f.PutLine( (*bgc).ToString() +"," );
/* If there's an animation plan at all, add a dummy "-nosongbg-" tag to
* indicate that this file doesn't want a song BG entry added at the end.
@@ -266,7 +297,7 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
f.Write( "#FGCHANGES:" );
FOREACH_CONST( BackgroundChange, out.GetForegroundChanges(), bgc )
{
f.PutLine( BackgroundChangeToString(*bgc)+"," );
f.PutLine( (*bgc).ToString() +"," );
}
f.PutLine( ";" );
}
@@ -280,16 +311,7 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
}
f.PutLine( ";" );
f.Write( "#ATTACKS:" );
for( unsigned a=0; a < out.m_sAttackString.size(); a++ )
{
RString sData = out.m_sAttackString[a];
f.Write( ssprintf( "%s", sData.c_str() ) );
if( a != (out.m_sAttackString.size() - 1) )
f.Write( ":" ); // Not the end, so write a divider ':'
}
f.PutLine( ";" );
f.PutLine( ssprintf("#ATTACKS:%s;", out.GetAttackString().c_str()) );
}
/**
@@ -307,7 +329,7 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa
lines.push_back( ssprintf("//---------------%s - %s----------------",
GAMEMAN->GetStepsTypeInfo(in.m_StepsType).szName, SmEscape(in.GetDescription()).c_str()) );
lines.push_back( "#NOTEDATA:;" ); // our new separator.
lines.push_back( ssprintf( "#CHARTNAME:%s:", SmEscape(in.GetChartName()).c_str()));
lines.push_back( ssprintf( "#CHARTNAME:%s;", SmEscape(in.GetChartName()).c_str()));
lines.push_back( ssprintf( "#STEPSTYPE:%s;", GAMEMAN->GetStepsTypeInfo(in.m_StepsType).szName ) );
lines.push_back( ssprintf( "#DESCRIPTION:%s;", SmEscape(in.GetDescription()).c_str() ) );
lines.push_back( ssprintf( "#CHARTSTYLE:%s;", SmEscape(in.GetChartStyle()).c_str() ) );
@@ -328,17 +350,7 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa
GetTimingTags( lines, in.m_Timing );
RString attacks = "";
for( unsigned a=0; a < in.m_sAttackString.size(); a++ )
{
RString sData = in.m_sAttackString[a];
attacks += sData;
if( a != (in.m_sAttackString.size() - 1) )
attacks += ":\r\n"; // Not the end, so write a divider ':'
}
Trim(attacks, ":"); // just in case something screwy happens.
lines.push_back( ssprintf( "#ATTACKS:%s;", attacks.c_str()));
lines.push_back( ssprintf("#ATTACKS:%s;", in.GetAttackString().c_str()));
switch( in.GetDisplayBPM() )
{
@@ -359,16 +371,21 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa
lines.push_back( ssprintf( "#DISPLAYBPM:*;" ) );
break;
}
RString sNoteData;
in.GetSMNoteData( sNoteData );
if (bSavingCache)
{
lines.push_back(ssprintf("#STEPFILENAME:%s;", in.GetFilename().c_str()));
}
else
{
RString sNoteData;
in.GetSMNoteData( sNoteData );
lines.push_back( song.m_vsKeysoundFile.empty() ? "#NOTES:" : "#NOTES2:" );
TrimLeft(sNoteData);
split( sNoteData, "\n", lines, true );
lines.push_back( ";" );
lines.push_back( song.m_vsKeysoundFile.empty() ? "#NOTES:" : "#NOTES2:" );
TrimLeft(sNoteData);
split( sNoteData, "\n", lines, true );
lines.push_back( ";" );
}
return JoinLineList( lines );
}
+17 -13
View File
@@ -426,15 +426,18 @@ void OptionRow::AfterImportOptions( PlayerNumber pn )
switch( m_pHand->m_Def.m_selectType )
{
case SELECT_ONE:
// Make sure the row actually has a selection.
int iSelection = GetOneSelection(pn, true);
if( iSelection == -1 )
case SELECT_ONE:
{
ASSERT( !m_vbSelected[pn].empty() );
m_vbSelected[pn][0] = true;
// Make sure the row actually has a selection.
int iSelection = GetOneSelection(pn, true);
if( iSelection == -1 )
{
ASSERT( !m_vbSelected[pn].empty() );
m_vbSelected[pn][0] = true;
}
}
break;
default:
break;
}
ResetFocusFromSelection( pn );
@@ -503,7 +506,7 @@ void OptionRow::UpdateText( PlayerNumber p )
{
switch( m_pHand->m_Def.m_layoutType )
{
case LAYOUT_SHOW_ONE_IN_ROW:
case LAYOUT_SHOW_ONE_IN_ROW:
{
unsigned pn = m_pHand->m_Def.m_bOneChoiceForAllPlayers ? 0 : p;
int iChoiceWithFocus = m_iChoiceInRowWithFocus[pn];
@@ -519,7 +522,7 @@ void OptionRow::UpdateText( PlayerNumber p )
m_textItems[index]->SetText( sText );
}
break;
default: break;
}
}
@@ -757,10 +760,11 @@ void OptionRow::ResetFocusFromSelection( PlayerNumber pn )
int iSelection = -1;
switch( m_pHand->m_Def.m_selectType )
{
case SELECT_ONE:
// Import the focus from the selected option.
iSelection = GetOneSelection( pn, true );
break;
case SELECT_ONE:
// Import the focus from the selected option.
iSelection = GetOneSelection( pn, true );
default:
break;
}
// HACK: Set focus to one item in the row, which is "go down"
+65 -59
View File
@@ -137,13 +137,14 @@ void PaneDisplay::SetContent( PaneCategory c )
{
switch( c )
{
case PaneCategory_MachineHighName:
str = EMPTY_MACHINE_HIGH_SCORE_NAME;
break;
case PaneCategory_MachineHighScore:
case PaneCategory_ProfileHighScore:
str = NOT_AVAILABLE;
break;
case PaneCategory_MachineHighName:
str = EMPTY_MACHINE_HIGH_SCORE_NAME;
break;
case PaneCategory_MachineHighScore:
case PaneCategory_ProfileHighScore:
str = NOT_AVAILABLE;
break;
default: break;
}
}
@@ -157,13 +158,14 @@ void PaneDisplay::SetContent( PaneCategory c )
{
switch( c )
{
case PaneCategory_MachineHighName:
str = EMPTY_MACHINE_HIGH_SCORE_NAME;
break;
case PaneCategory_MachineHighScore:
case PaneCategory_ProfileHighScore:
str = NOT_AVAILABLE;
break;
case PaneCategory_MachineHighName:
str = EMPTY_MACHINE_HIGH_SCORE_NAME;
break;
case PaneCategory_MachineHighScore:
case PaneCategory_ProfileHighScore:
str = NOT_AVAILABLE;
break;
default: break;
}
}
@@ -184,8 +186,9 @@ void PaneDisplay::SetContent( PaneCategory c )
ProfileSlot slot = ProfileSlot_Machine;
switch( c )
{
case PaneCategory_ProfileHighScore:
slot = (ProfileSlot) m_PlayerNumber;
case PaneCategory_ProfileHighScore:
slot = (ProfileSlot) m_PlayerNumber;
default: break;
}
if( pSteps )
@@ -201,55 +204,58 @@ void PaneDisplay::SetContent( PaneCategory c )
switch( c )
{
case PaneCategory_NumSteps: val = rv[RadarCategory_TapsAndHolds]; break;
case PaneCategory_Jumps: val = rv[RadarCategory_Jumps]; break;
case PaneCategory_Holds: val = rv[RadarCategory_Holds]; break;
case PaneCategory_Rolls: val = rv[RadarCategory_Rolls]; break;
case PaneCategory_Mines: val = rv[RadarCategory_Mines]; break;
case PaneCategory_Hands: val = rv[RadarCategory_Hands]; break;
case PaneCategory_Lifts: val = rv[RadarCategory_Lifts]; break;
case PaneCategory_Fakes: val = rv[RadarCategory_Fakes]; break;
case PaneCategory_ProfileHighScore:
case PaneCategory_MachineHighName: // set val for color
case PaneCategory_MachineHighScore:
CHECKPOINT;
val = pHSL->GetTopScore().GetPercentDP();
break;
case PaneCategory_NumSteps: val = rv[RadarCategory_TapsAndHolds]; break;
case PaneCategory_Jumps: val = rv[RadarCategory_Jumps]; break;
case PaneCategory_Holds: val = rv[RadarCategory_Holds]; break;
case PaneCategory_Rolls: val = rv[RadarCategory_Rolls]; break;
case PaneCategory_Mines: val = rv[RadarCategory_Mines]; break;
case PaneCategory_Hands: val = rv[RadarCategory_Hands]; break;
case PaneCategory_Lifts: val = rv[RadarCategory_Lifts]; break;
case PaneCategory_Fakes: val = rv[RadarCategory_Fakes]; break;
case PaneCategory_ProfileHighScore:
case PaneCategory_MachineHighName: // set val for color
case PaneCategory_MachineHighScore:
CHECKPOINT;
val = pHSL->GetTopScore().GetPercentDP();
break;
default: break;
};
if( val != RADAR_VAL_UNKNOWN )
{
switch( c )
{
case PaneCategory_MachineHighName:
if( pHSL->vHighScores.empty() )
{
str = EMPTY_MACHINE_HIGH_SCORE_NAME;
}
else
{
str = pHSL->GetTopScore().GetName();
if( str.empty() )
str = "????";
}
break;
case PaneCategory_MachineHighScore:
case PaneCategory_ProfileHighScore:
// Don't show or save machine high scores for edits loaded from a player profile.
if( bIsPlayerEdit )
str = NOT_AVAILABLE;
else
str = PlayerStageStats::FormatPercentScore( val );
break;
case PaneCategory_NumSteps:
case PaneCategory_Jumps:
case PaneCategory_Holds:
case PaneCategory_Rolls:
case PaneCategory_Mines:
case PaneCategory_Hands:
case PaneCategory_Lifts:
case PaneCategory_Fakes:
str = ssprintf( COUNT_FORMAT.GetValue(), val );
case PaneCategory_MachineHighName:
if( pHSL->vHighScores.empty() )
{
str = EMPTY_MACHINE_HIGH_SCORE_NAME;
}
else
{
str = pHSL->GetTopScore().GetName();
if( str.empty() )
str = "????";
}
break;
case PaneCategory_MachineHighScore:
case PaneCategory_ProfileHighScore:
// Don't show or save machine high scores for edits loaded from a player profile.
if( bIsPlayerEdit )
str = NOT_AVAILABLE;
else
str = PlayerStageStats::FormatPercentScore( val );
break;
case PaneCategory_NumSteps:
case PaneCategory_Jumps:
case PaneCategory_Holds:
case PaneCategory_Rolls:
case PaneCategory_Mines:
case PaneCategory_Hands:
case PaneCategory_Lifts:
case PaneCategory_Fakes:
str = ssprintf( COUNT_FORMAT.GetValue(), val );
break;
default: break;
}
}
}
+43 -37
View File
@@ -628,8 +628,8 @@ void Player::Load()
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_RAVE:
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
case PLAY_MODE_BATTLE:
{
// ugly, ugly, ugly. Works only w/ dance.
// Why does this work only with dance? - Steve
@@ -659,8 +659,9 @@ void Player::Load()
count++;
count %= 4;
}
break;
}
break;
default: break;
}
int iDrawDistanceAfterTargetsPixels = GAMESTATE->IsEditing() ? -100 : DRAW_DISTANCE_AFTER_TARGET_PIXELS;
@@ -2879,41 +2880,46 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now )
int iTrack = iter.Track();
switch( tn.type )
{
case TapNote::hold_head:
tn.HoldResult.fLife = INITIAL_HOLD_LIFE;
if( !REQUIRE_STEP_ON_HOLD_HEADS )
case TapNote::hold_head:
{
tn.HoldResult.fLife = INITIAL_HOLD_LIFE;
if( !REQUIRE_STEP_ON_HOLD_HEADS )
{
PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
GameInput GameI = GAMESTATE->GetCurrentStyle()->StyleInputToGameInput( iTrack, pn );
if( PREFSMAN->m_fPadStickSeconds > 0.f )
{
float fSecsHeld = INPUTMAPPER->GetSecsHeld( GameI, m_pPlayerState->m_mp );
if( fSecsHeld >= PREFSMAN->m_fPadStickSeconds )
Step( iTrack, -1, now - PREFSMAN->m_fPadStickSeconds, true, false );
}
else if( INPUTMAPPER->IsBeingPressed(GameI, m_pPlayerState->m_mp) )
{
Step( iTrack, -1, now, true, false );
}
}
break;
}
case TapNote::mine:
{
// Hold the panel while crossing a mine will cause the mine to explode
// TODO: Remove use of PlayerNumber.
PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
GameInput GameI = GAMESTATE->GetCurrentStyle()->StyleInputToGameInput( iTrack, pn );
if( PREFSMAN->m_fPadStickSeconds > 0.f )
if( PREFSMAN->m_fPadStickSeconds > 0 )
{
float fSecsHeld = INPUTMAPPER->GetSecsHeld( GameI, m_pPlayerState->m_mp );
if( fSecsHeld >= PREFSMAN->m_fPadStickSeconds )
Step( iTrack, -1, now - PREFSMAN->m_fPadStickSeconds, true, false );
}
else if( INPUTMAPPER->IsBeingPressed(GameI, m_pPlayerState->m_mp) )
else
{
Step( iTrack, -1, now, true, false );
if( INPUTMAPPER->IsBeingPressed(GameI, m_pPlayerState->m_mp) )
Step( iTrack, iRow, now, true, false );
}
break;
}
break;
case TapNote::mine:
// Hold the panel while crossing a mine will cause the mine to explode
// TODO: Remove use of PlayerNumber.
PlayerNumber pn = m_pPlayerState->m_PlayerNumber;
GameInput GameI = GAMESTATE->GetCurrentStyle()->StyleInputToGameInput( iTrack, pn );
if( PREFSMAN->m_fPadStickSeconds > 0 )
{
float fSecsHeld = INPUTMAPPER->GetSecsHeld( GameI, m_pPlayerState->m_mp );
if( fSecsHeld >= PREFSMAN->m_fPadStickSeconds )
Step( iTrack, -1, now - PREFSMAN->m_fPadStickSeconds, true, false );
}
else
{
if( INPUTMAPPER->IsBeingPressed(GameI, m_pPlayerState->m_mp) )
Step( iTrack, iRow, now, true, false );
}
break;
default: break;
}
if( iRow != iLastSeenRow )
@@ -2956,21 +2962,21 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now )
}
else if( CHECKPOINTS_USE_TIME_SIGNATURES )
{
TimeSignatureSegment & tSignature = m_Timing->GetTimeSignatureSegmentAtRow( iLastRowCrossed );
TimeSignatureSegment * tSignature = m_Timing->GetTimeSignatureSegmentAtRow( iLastRowCrossed );
// Most songs are in 4/4 time. The frequency for checking tick counts should reflect that.
iCheckpointFrequencyRows = ROWS_PER_BEAT * tSignature.GetDen() / (tSignature.GetNum() * 4);
iCheckpointFrequencyRows = ROWS_PER_BEAT * tSignature->GetDen() / (tSignature->GetNum() * 4);
}
if( iCheckpointFrequencyRows > 0 )
{
// "the first row after the start of the range that lands on a beat"
int iFirstCheckpointInRange = QuantizeUp(m_iFirstUncrossedRow,
iCheckpointFrequencyRows);
int iFirstCheckpointInRange = ((m_iFirstUncrossedRow+iCheckpointFrequencyRows-1)
/iCheckpointFrequencyRows) * iCheckpointFrequencyRows;
// "the last row or first row earlier that lands on a beat"
int iLastCheckpointInRange = QuantizeDown(iLastRowCrossed,
iCheckpointFrequencyRows);
int iLastCheckpointInRange = ((iLastRowCrossed)/iCheckpointFrequencyRows)
* iCheckpointFrequencyRows;
for( int r = iFirstCheckpointInRange; r <= iLastCheckpointInRange; r += iCheckpointFrequencyRows )
{
@@ -2992,12 +2998,12 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now )
int iTrack = nIter.Track();
// "the first row after the hold head that lands on a beat"
int iFirstCheckpointOfHold = QuantizeUp(iStartRow,
iCheckpointFrequencyRows);
int iFirstCheckpointOfHold = ((iStartRow+iCheckpointFrequencyRows)/iCheckpointFrequencyRows)
* iCheckpointFrequencyRows;
// "the end row or the first earlier row that lands on a beat"
int iLastCheckpointOfHold = QuantizeDown(iEndRow,
iCheckpointFrequencyRows);
int iLastCheckpointOfHold = ((iEndRow)/iCheckpointFrequencyRows)
* iCheckpointFrequencyRows;
// count the end of the hold as a checkpoint
bool bHoldOverlapsRow = iFirstCheckpointOfHold <= r && r <= iLastCheckpointOfHold;
+14 -11
View File
@@ -274,6 +274,7 @@ float PlayerStageStats::GetCurMaxPercentDancePoints() const
return fCurMaxPercentDancePoints;
}
// TODO: Make this use lua. Let more judgments be possible. -Wolfman2000
int PlayerStageStats::GetLessonScoreActual() const
{
int iScore = 0;
@@ -282,14 +283,15 @@ int PlayerStageStats::GetLessonScoreActual() const
{
switch( tns )
{
case TNS_AvoidMine:
case TNS_W5:
case TNS_W4:
case TNS_W3:
case TNS_W2:
case TNS_W1:
iScore += m_iTapNoteScores[tns];
break;
case TNS_AvoidMine:
case TNS_W5:
case TNS_W4:
case TNS_W3:
case TNS_W2:
case TNS_W1:
iScore += m_iTapNoteScores[tns];
default:
break;
}
}
@@ -297,9 +299,10 @@ int PlayerStageStats::GetLessonScoreActual() const
{
switch( hns )
{
case HNS_Held:
iScore += m_iHoldNoteScores[hns];
break;
case HNS_Held:
iScore += m_iHoldNoteScores[hns];
default:
break;
}
}
+24 -25
View File
@@ -340,7 +340,7 @@ GLhandleARB CompileShader( GLenum ShaderType, RString sFile, vector<RString> asD
GLhandleARB LoadShader( GLenum ShaderType, RString sFile, vector<RString> asDefines )
{
// Don't do anything here if not the hardware/driver can't do it!
if (!GLEW_ARB_fragment_program && GLEW_ARB_shading_language_100 && ShaderType == GL_FRAGMENT_SHADER_ARB)
if (!GLEW_ARB_fragment_shader && ShaderType == GL_FRAGMENT_SHADER_ARB)
return 0;
if (!GLEW_ARB_vertex_shader && ShaderType == GL_VERTEX_SHADER_ARB)
return 0;
@@ -1625,6 +1625,7 @@ void RageDisplay_Legacy::SetTextureMode( TextureUnit tu, TextureMode tm )
glTexEnvi(GL_TEXTURE_ENV, GLenum(GL_OPERAND1_ALPHA_EXT), GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GLenum(GL_SOURCE1_ALPHA_EXT), GL_TEXTURE);
break;
default: break;
}
}
@@ -1662,21 +1663,22 @@ void RageDisplay_Legacy::SetTextureFiltering( TextureUnit tu, bool b )
void RageDisplay_Legacy::SetEffectMode( EffectMode effect )
{
if (!GLEW_ARB_fragment_program && !GLEW_ARB_shading_language_100)
if (!GLEW_ARB_fragment_shader)
return;
GLhandleARB hShader = 0;
switch (effect)
{
case EffectMode_Normal: hShader = 0; break;
case EffectMode_Unpremultiply: hShader = g_bUnpremultiplyShader; break;
case EffectMode_ColorBurn: hShader = g_bColorBurnShader; break;
case EffectMode_ColorDodge: hShader = g_bColorDodgeShader; break;
case EffectMode_VividLight: hShader = g_bVividLightShader; break;
case EffectMode_HardMix: hShader = g_hHardMixShader; break;
case EffectMode_Overlay: hShader = g_hOverlayShader; break;
case EffectMode_Screen: hShader = g_hScreenShader; break;
case EffectMode_YUYV422: hShader = g_hYUYV422Shader; break;
case EffectMode_Normal: hShader = 0; break;
case EffectMode_Unpremultiply: hShader = g_bUnpremultiplyShader; break;
case EffectMode_ColorBurn: hShader = g_bColorBurnShader; break;
case EffectMode_ColorDodge: hShader = g_bColorDodgeShader; break;
case EffectMode_VividLight: hShader = g_bVividLightShader; break;
case EffectMode_HardMix: hShader = g_hHardMixShader; break;
case EffectMode_Overlay: hShader = g_hOverlayShader; break;
case EffectMode_Screen: hShader = g_hScreenShader; break;
case EffectMode_YUYV422: hShader = g_hYUYV422Shader; break;
default: break;
}
DebugFlushGLErrors();
@@ -1703,18 +1705,17 @@ bool RageDisplay_Legacy::IsEffectModeSupported( EffectMode effect )
{
switch( effect )
{
case EffectMode_Normal: return true;
case EffectMode_Unpremultiply: return g_bUnpremultiplyShader != 0;
case EffectMode_ColorBurn: return g_bColorBurnShader != 0;
case EffectMode_ColorDodge: return g_bColorDodgeShader != 0;
case EffectMode_VividLight: return g_bVividLightShader != 0;
case EffectMode_HardMix: return g_hHardMixShader != 0;
case EffectMode_Overlay: return g_hOverlayShader != 0;
case EffectMode_Screen: return g_hScreenShader != 0;
case EffectMode_YUYV422: return g_hYUYV422Shader != 0;
case EffectMode_Normal: return true;
case EffectMode_Unpremultiply: return g_bUnpremultiplyShader != 0;
case EffectMode_ColorBurn: return g_bColorBurnShader != 0;
case EffectMode_ColorDodge: return g_bColorDodgeShader != 0;
case EffectMode_VividLight: return g_bVividLightShader != 0;
case EffectMode_HardMix: return g_hHardMixShader != 0;
case EffectMode_Overlay: return g_hOverlayShader != 0;
case EffectMode_Screen: return g_hScreenShader != 0;
case EffectMode_YUYV422: return g_hYUYV422Shader != 0;
default: return false;
}
return false;
}
void RageDisplay_Legacy::SetBlendMode( BlendMode mode )
@@ -2648,11 +2649,9 @@ void RageDisplay_Legacy::SetSphereEnvironmentMapping(TextureUnit tu, bool b)
}
}
GLint iCelTexture1, iCelTexture2 = 0;
void RageDisplay_Legacy::SetCelShaded( int stage )
{
if (!GLEW_ARB_fragment_program && !GL_ARB_shading_language_100)
if (!GLEW_ARB_fragment_shader)
return; // not supported
switch (stage)
+10 -9
View File
@@ -576,15 +576,16 @@ void RageSound::ApplyParams()
switch( GetStopMode() )
{
case RageSoundParams::M_LOOP:
m_pSource->SetProperty( "Loop", 1.0f );
break;
case RageSoundParams::M_STOP:
m_pSource->SetProperty( "Stop", 1.0f );
break;
case RageSoundParams::M_CONTINUE:
m_pSource->SetProperty( "Continue", 1.0f );
break;
case RageSoundParams::M_LOOP:
m_pSource->SetProperty( "Loop", 1.0f );
break;
case RageSoundParams::M_STOP:
m_pSource->SetProperty( "Stop", 1.0f );
break;
case RageSoundParams::M_CONTINUE:
m_pSource->SetProperty( "Continue", 1.0f );
break;
default: break;
}
}
+11 -10
View File
@@ -67,17 +67,18 @@ RageSoundReader_FileReader *RageSoundReader_FileReader::TryOpenFile( RageFileBas
bKeepTrying = (ret != OPEN_FATAL_ERROR);
switch( ret )
{
case OPEN_UNKNOWN_FILE_FORMAT:
bKeepTrying = true;
error = "Unknown file format";
break;
case OPEN_UNKNOWN_FILE_FORMAT:
bKeepTrying = true;
error = "Unknown file format";
break;
case OPEN_FATAL_ERROR:
/* The file matched, but failed to load. We know it's this type of data;
* don't bother trying the other file types. */
bKeepTrying = false;
error = err;
break;
case OPEN_FATAL_ERROR:
/* The file matched, but failed to load. We know it's this type of data;
* don't bother trying the other file types. */
bKeepTrying = false;
error = err;
break;
default: break;
}
return NULL;
+10 -9
View File
@@ -57,16 +57,17 @@ static RageSurface *TryOpenFile( RString sPath, bool bHeaderOnly, RString &error
bKeepTrying = (result != RageSurfaceUtils::OPEN_FATAL_ERROR);
switch( result )
{
case RageSurfaceUtils::OPEN_UNKNOWN_FILE_FORMAT:
bKeepTrying = true;
error = "Unknown file format";
break;
case RageSurfaceUtils::OPEN_UNKNOWN_FILE_FORMAT:
bKeepTrying = true;
error = "Unknown file format";
break;
case RageSurfaceUtils::OPEN_FATAL_ERROR:
/* The file matched, but failed to load. We know it's this type of data;
* don't bother trying the other file types. */
bKeepTrying = false;
break;
case RageSurfaceUtils::OPEN_FATAL_ERROR:
/* The file matched, but failed to load. We know it's this type of data;
* don't bother trying the other file types. */
bKeepTrying = false;
break;
default: break;
}
return NULL;
+7
View File
@@ -1731,6 +1731,13 @@ bool StringToFloat( const RString &sString, float &fOut )
return sString.size() && *endPtr == '\0' && isfinite( fOut );
}
RString FloatToString( const float &num )
{
stringstream ss;
ss << num;
return ss.str();
}
const wchar_t INVALID_CHAR = 0xFFFD; /* U+FFFD REPLACEMENT CHARACTER */
wstring RStringToWstring( const RString &s )
+1
View File
@@ -416,6 +416,7 @@ int StringToInt( const RString &sString );
* @return the string we are after. */
RString IntToString( const int &iNum );
float StringToFloat( const RString &sString );
RString FloatToString( const float &num );
bool StringToFloat( const RString &sString, float &fOut );
RString WStringToRString( const wstring &sString );
+7 -7
View File
@@ -429,14 +429,14 @@ void ScoreKeeperNormal::HandleTapNoteScoreInternal( TapNoteScore tns, TapNoteSco
// update judged row totals. Respect Combo segments here.
TimingData &td = GAMESTATE->m_pCurSteps[m_pPlayerState->m_PlayerNumber]->m_Timing;
ComboSegment &cs = td.GetComboSegmentAtRow(row);
ComboSegment *cs = td.GetComboSegmentAtRow(row);
if (tns == TNS_CheckpointHit || tns >= m_MinScoreToContinueCombo)
{
m_pPlayerStageStats->m_iTapNoteScores[tns] += cs.GetCombo();
m_pPlayerStageStats->m_iTapNoteScores[tns] += cs->GetCombo();
}
else if (tns == TNS_CheckpointMiss || tns < m_MinScoreToMaintainCombo)
{
m_pPlayerStageStats->m_iTapNoteScores[tns] += cs.GetMissCombo();
m_pPlayerStageStats->m_iTapNoteScores[tns] += cs->GetMissCombo();
}
else
{
@@ -464,13 +464,13 @@ void ScoreKeeperNormal::HandleComboInternal( int iNumHitContinueCombo, int iNumH
TimingData td = GAMESTATE->m_pCurSteps[m_pPlayerState->m_PlayerNumber]->m_Timing;
if( iNumBreakCombo == 0 )
{
int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow( iRow ).GetCombo() );
int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow( iRow )->GetCombo() );
m_pPlayerStageStats->m_iCurCombo += iNumHitContinueCombo * multiplier;
}
else
{
m_pPlayerStageStats->m_iCurCombo = 0;
int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow(iRow).GetMissCombo());
int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow(iRow)->GetMissCombo());
m_pPlayerStageStats->m_iCurMissCombo += ( m_MissComboIsPerRow ? 1 : iNumBreakCombo ) * multiplier;
}
}
@@ -485,7 +485,7 @@ void ScoreKeeperNormal::HandleRowComboInternal( TapNoteScore tns, int iNumTapsIn
if ( tns >= m_MinScoreToContinueCombo )
{
m_pPlayerStageStats->m_iCurMissCombo = 0;
int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow( iRow ).GetCombo() );
int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow( iRow )->GetCombo() );
m_pPlayerStageStats->m_iCurCombo += iNumTapsInRow * multiplier;
}
else if ( tns < m_MinScoreToMaintainCombo )
@@ -494,7 +494,7 @@ void ScoreKeeperNormal::HandleRowComboInternal( TapNoteScore tns, int iNumTapsIn
if( tns <= m_MaxScoreToIncrementMissCombo )
{
int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow(iRow).GetMissCombo());
int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow(iRow)->GetMissCombo());
m_pPlayerStageStats->m_iCurMissCombo += ( m_MissComboIsPerRow ? 1 : iNumTapsInRow ) * multiplier;
}
}
+4 -1
View File
@@ -83,7 +83,10 @@ void ScoreKeeperRave::HandleHoldScore( const TapNote &tn )
float fPercentToMove = 0;
switch( tapScore )
{
case TNS_HitMine: fPercentToMove = g_fSuperMeterPercentChange[SE_HitMine]; break;
case TNS_HitMine:
fPercentToMove = g_fSuperMeterPercentChange[SE_HitMine];
default:
break;
}
AddSuperMeterDelta( fPercentToMove );
}
+1
View File
@@ -226,6 +226,7 @@ void Screen::Input( const InputEventPlus &input )
case GAME_BUTTON_START: this->MenuStart ( input ); return;
case GAME_BUTTON_SELECT:this->MenuSelect( input ); return;
case GAME_BUTTON_COIN: this->MenuCoin ( input ); return;
default: return;
}
}
+32 -29
View File
@@ -75,34 +75,36 @@ void ScreenAttract::AttractInput( const InputEventPlus &input, ScreenWithMenuEle
switch( input.MenuI )
{
case GAME_BUTTON_BACK:
if( !(bool)BACK_GOES_TO_START_SCREEN )
break;
// fall through
case GAME_BUTTON_START:
case GAME_BUTTON_COIN:
switch( GAMESTATE->GetCoinMode() )
{
case CoinMode_Pay:
LOG->Trace("ScreenAttract::AttractInput: COIN_PAY (%i/%i, %i)", GAMESTATE->m_iCoins.Get(), PREFSMAN->m_iCoinsPerCredit.Get(), GAMESTATE->GetNumSidesJoined() );
if( GAMESTATE->m_iCoins < PREFSMAN->m_iCoinsPerCredit && GAMESTATE->GetNumSidesJoined() == 0 )
break; // don't fall through
case GAME_BUTTON_BACK:
if( !BACK_GOES_TO_START_SCREEN )
break;
// fall through
case CoinMode_Home:
case CoinMode_Free:
if( pScreen->IsTransitioning() )
return;
case GAME_BUTTON_START:
case GAME_BUTTON_COIN:
switch( GAMESTATE->GetCoinMode() )
{
case CoinMode_Pay:
LOG->Trace("ScreenAttract::AttractInput: COIN_PAY (%i/%i, %i)",
GAMESTATE->m_iCoins.Get(),
PREFSMAN->m_iCoinsPerCredit.Get(),
GAMESTATE->GetNumSidesJoined() );
if( GAMESTATE->m_iCoins < PREFSMAN->m_iCoinsPerCredit && GAMESTATE->GetNumSidesJoined() == 0 )
break; // don't fall through
// fall through
case CoinMode_Home:
case CoinMode_Free:
if( pScreen->IsTransitioning() )
return;
// HandleGlobalInputs() already played the coin sound. Don't play it again.
if( input.MenuI != GAME_BUTTON_COIN )
SCREENMAN->PlayStartSound();
// HandleGlobalInputs() already played the coin sound. Don't play it again.
if( input.MenuI != GAME_BUTTON_COIN )
SCREENMAN->PlayStartSound();
pScreen->Cancel( SM_GoToStartScreen );
break;
default:
ASSERT(0);
}
break;
pScreen->Cancel( SM_GoToStartScreen );
break;
default: FAIL_M("Invalid Coin Mode! Aborting...");
}
default: break;
}
if( pScreen->IsTransitioning() )
@@ -110,10 +112,11 @@ void ScreenAttract::AttractInput( const InputEventPlus &input, ScreenWithMenuEle
switch( input.MenuI )
{
case GAME_BUTTON_LEFT:
case GAME_BUTTON_RIGHT:
SCREENMAN->PostMessageToTopScreen( SM_BeginFadingOut, 0 );
break;
case GAME_BUTTON_LEFT:
case GAME_BUTTON_RIGHT:
SCREENMAN->PostMessageToTopScreen( SM_BeginFadingOut, 0 );
default:
break;
}
// Screen::Input( input );
+15 -12
View File
@@ -63,18 +63,21 @@ void ScreenContinue::Input( const InputEventPlus &input )
{
switch( input.MenuI )
{
case GAME_BUTTON_START:
case GAME_BUTTON_UP:
case GAME_BUTTON_DOWN:
case GAME_BUTTON_LEFT:
case GAME_BUTTON_RIGHT:
float fSeconds = floorf(m_MenuTimer->GetSeconds()) - 0.0001f;
fSeconds = max( fSeconds, 0.0001f ); // don't set to 0
m_MenuTimer->SetSeconds( fSeconds );
Message msg("HurryTimer");
msg.SetParam( "PlayerNumber", input.pn );
this->HandleMessage( msg );
return; // handled
case GAME_BUTTON_START:
case GAME_BUTTON_UP:
case GAME_BUTTON_DOWN:
case GAME_BUTTON_LEFT:
case GAME_BUTTON_RIGHT:
{
float fSeconds = floorf(m_MenuTimer->GetSeconds()) - 0.0001f;
fSeconds = max( fSeconds, 0.0001f ); // don't set to 0
m_MenuTimer->SetSeconds( fSeconds );
Message msg("HurryTimer");
msg.SetParam( "PlayerNumber", input.pn );
this->HandleMessage( msg );
return; // handled
}
default: break;
}
}
+4 -5
View File
@@ -813,12 +813,11 @@ class DebugLineProfileSlot : public IDebugLine
{
switch( g_ProfileSlot )
{
case ProfileSlot_Machine: return "Machine";
case ProfileSlot_Player1: return "Player 1";
case ProfileSlot_Player2: return "Player 2";
case ProfileSlot_Machine: return "Machine";
case ProfileSlot_Player1: return "Player 1";
case ProfileSlot_Player2: return "Player 2";
default: return RString();
}
return RString();
}
virtual bool IsEnabled() { return IsSelectProfilePersistent(); }
virtual RString GetPageName() const { return "Profiles"; }
+48 -117
View File
@@ -257,6 +257,7 @@ void ScreenEdit::InitEditMappings()
m_EditMappingsDeviceInput.hold[EDIT_BUTTON_DELETE_SHIFT_PAUSES][0] = DeviceInput(DEVICE_KEYBOARD, KEY_LCTRL);
m_EditMappingsDeviceInput.hold[EDIT_BUTTON_DELETE_SHIFT_PAUSES][1] = DeviceInput(DEVICE_KEYBOARD, KEY_RCTRL);
break;
default: break;
}
m_EditMappingsDeviceInput.button[EDIT_BUTTON_COLUMN_0][0] = DeviceInput(DEVICE_KEYBOARD, KEY_C1);
@@ -812,7 +813,7 @@ void ScreenEdit::Init()
InitEditMappings();
currentCycleSegment = "label";
currentCycleSegment = SEGMENT_LABEL;
// save the originals for reverting later
CopyToLastSave();
@@ -1261,7 +1262,7 @@ void ScreenEdit::UpdateTextInfo()
sText += ssprintf( MAIN_TITLE_FORMAT.GetValue(), MAIN_TITLE.GetValue().c_str(), m_pSong->m_sMainTitle.c_str() );
if( m_pSong->m_sSubTitle.size() )
sText += ssprintf( SUBTITLE_FORMAT.GetValue(), SUBTITLE.GetValue().c_str(), m_pSong->m_sSubTitle.c_str() );
sText += ssprintf( SEGMENT_TYPE_FORMAT.GetValue(), SEGMENT_TYPE.GetValue().c_str(), currentCycleSegment.c_str() );
sText += ssprintf( SEGMENT_TYPE_FORMAT.GetValue(), SEGMENT_TYPE.GetValue().c_str(), TimingSegmentTypeToString(currentCycleSegment).c_str() );
sText += ssprintf( TAP_NOTE_TYPE_FORMAT.GetValue(), TAP_NOTE_TYPE.GetValue().c_str(), TapNoteTypeToString( m_selectedTap.type ).c_str() );
break;
}
@@ -1465,7 +1466,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
}
TimingData &sTiming = GetAppropriateTiming();
float playerBeat = GetAppropriatePosition().m_fSongBeat;
int beatsPerMeasure = sTiming.GetTimeSignatureSegmentAtBeat( playerBeat ).GetNum();
int beatsPerMeasure = sTiming.GetTimeSignatureSegmentAtBeat( playerBeat )->GetNum();
switch( EditB )
{
@@ -1559,60 +1560,15 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
}
case EDIT_BUTTON_CYCLE_SEGMENT_LEFT:
{
if (this->currentCycleSegment == "label")
this->currentCycleSegment = "fake";
else if (this->currentCycleSegment == "fake")
this->currentCycleSegment = "scroll";
else if (this->currentCycleSegment == "scroll")
this->currentCycleSegment = "speed";
else if (this->currentCycleSegment == "speed")
this->currentCycleSegment = "combo";
else if (this->currentCycleSegment == "combo")
this->currentCycleSegment = "tickcount";
else if (this->currentCycleSegment == "tickcount")
this->currentCycleSegment = "timeSig";
else if (this->currentCycleSegment == "timeSig")
this->currentCycleSegment = "warp";
else if (this->currentCycleSegment == "warp")
this->currentCycleSegment = "delay";
else if (this->currentCycleSegment == "delay")
this->currentCycleSegment = "stop";
else if (this->currentCycleSegment == "stop")
this->currentCycleSegment = "bpm";
else if (this->currentCycleSegment == "bpm")
this->currentCycleSegment = "label";
// fallback gracefully instead of assert.
else this->currentCycleSegment = "label";
int tmp = enum_add2( this->currentCycleSegment, -1 );
wrap( *ConvertValue<int>(&tmp), NUM_TimingSegmentType );
break;
}
case EDIT_BUTTON_CYCLE_SEGMENT_RIGHT:
{
if (this->currentCycleSegment == "label")
this->currentCycleSegment = "bpm";
else if (this->currentCycleSegment == "bpm")
this->currentCycleSegment = "stop";
else if (this->currentCycleSegment == "stop")
this->currentCycleSegment = "delay";
else if (this->currentCycleSegment == "delay")
this->currentCycleSegment = "warp";
else if (this->currentCycleSegment == "warp")
this->currentCycleSegment = "timeSig";
else if (this->currentCycleSegment == "timeSig")
this->currentCycleSegment = "tickcount";
else if (this->currentCycleSegment == "tickcount")
this->currentCycleSegment = "combo";
else if (this->currentCycleSegment == "combo")
this->currentCycleSegment = "speed";
else if (this->currentCycleSegment == "speed")
this->currentCycleSegment = "scroll";
else if (this->currentCycleSegment == "scroll")
this->currentCycleSegment = "fake";
else if (this->currentCycleSegment == "fake")
this->currentCycleSegment = "label";
// fallback gracefully instead of assert.
else this->currentCycleSegment = "label";
break;
}
int tmp = enum_add2( this->currentCycleSegment, +1 );
wrap( *ConvertValue<int>(&tmp), NUM_TimingSegmentType );
break; }
case EDIT_BUTTON_SCROLL_SPEED_UP:
case EDIT_BUTTON_SCROLL_SPEED_DOWN:
{
@@ -1729,56 +1685,18 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
break;
case EDIT_BUTTON_SEGMENT_NEXT:
{
// TODO: Work around Stops and Delays. We MAY have to separate them.
TimingData &timing = GetAppropriateTiming();
if (this->currentCycleSegment == "label")
ScrollTo(timing.GetNextLabelSegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "bpm")
ScrollTo(timing.GetNextBPMSegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "stop")
ScrollTo(timing.GetNextStopSegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "delay")
ScrollTo(timing.GetNextDelaySegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "warp")
ScrollTo(timing.GetNextWarpSegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "timeSig")
ScrollTo(timing.GetNextTimeSignatureSegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "tickcount")
ScrollTo(timing.GetNextTickcountSegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "combo")
ScrollTo(timing.GetNextComboSegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "speed")
ScrollTo(timing.GetNextSpeedSegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "scroll")
ScrollTo(timing.GetNextScrollSegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "fake")
ScrollTo(timing.GetNextFakeSegmentBeatAtBeat(GetBeat()));
ScrollTo(timing.GetNextSegmentBeatAtBeat(this->currentCycleSegment,
GetBeat()));
}
break;
case EDIT_BUTTON_SEGMENT_PREV:
{
// TODO: Work around Stops and Delays. We MAY have to separate them.
TimingData &timing = GetAppropriateTiming();
if (this->currentCycleSegment == "label")
ScrollTo(timing.GetPreviousLabelSegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "bpm")
ScrollTo(timing.GetPreviousBPMSegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "stop")
ScrollTo(timing.GetPreviousStopSegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "delay")
ScrollTo(timing.GetPreviousDelaySegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "warp")
ScrollTo(timing.GetPreviousWarpSegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "timeSig")
ScrollTo(timing.GetPreviousTimeSignatureSegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "tickcount")
ScrollTo(timing.GetPreviousTickcountSegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "combo")
ScrollTo(timing.GetPreviousComboSegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "speed")
ScrollTo(timing.GetPreviousSpeedSegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "scroll")
ScrollTo(timing.GetPreviousScrollSegmentBeatAtBeat(GetBeat()));
else if (this->currentCycleSegment == "fake")
ScrollTo(timing.GetPreviousFakeSegmentBeatAtBeat(GetBeat()));
ScrollTo(timing.GetPreviousSegmentBeatAtBeat(this->currentCycleSegment,
GetBeat()));
}
break;
case EDIT_BUTTON_SNAP_NEXT:
@@ -1972,24 +1890,26 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
fDelta *= 40;
}
unsigned i;
for( i=0; i<GetAppropriateTiming().m_StopSegments.size(); i++ )
vector<TimingSegment *> &stops = GetAppropriateTiming().allTimingSegments[SEGMENT_STOP_DELAY];
for( i=0; i<stops.size(); i++ )
{
if( GetAppropriateTiming().m_StopSegments[i].GetRow() == GetRow() )
if( stops[i]->GetRow() == GetRow() )
break;
}
if( i == GetAppropriateTiming().m_StopSegments.size() ) // there is no StopSegment at the current beat
if( i == stops.size() ) // there is no StopSegment at the current beat
{
// create a new StopSegment
if( fDelta > 0 )
GetAppropriateTiming().AddStopSegment( StopSegment( GetRow(), fDelta) );
GetAppropriateTiming().AddSegment(SEGMENT_STOP_DELAY,
new StopSegment( GetRow(), fDelta) );
}
else // StopSegment being modified is m_SongTiming.m_StopSegments[i]
{
vector<StopSegment> &s = GetAppropriateTiming().m_StopSegments;
s[i].SetPause(s[i].GetPause() + fDelta);
if( s[i].GetPause() <= 0 )
s.erase( s.begin()+i, s.begin()+i+1);
StopSegment *s = static_cast<StopSegment *>(stops[i]);
s->SetPause(s->GetPause() + fDelta);
if( s->GetPause() <= 0 )
stops.erase( stops.begin()+i, stops.begin()+i+1);
}
(fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play();
SetDirty( true );
@@ -2468,6 +2388,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
GAMESTATE->m_bIsUsingStepTiming = !GAMESTATE->m_bIsUsingStepTiming;
m_soundSwitchTiming.Play();
break;
default: break;
}
}
@@ -2575,6 +2496,7 @@ void ScreenEdit::InputRecordPaused( const InputEventPlus &input, EditButton Edit
case EDIT_BUTTON_RETURN_TO_EDIT:
TransitionEditState( STATE_EDITING );
break;
default: break;
}
}
@@ -2623,6 +2545,7 @@ void ScreenEdit::InputPlay( const InputEventPlus &input, EditButton EditB )
}
}
break;
default: break;
}
}
@@ -2665,6 +2588,7 @@ void ScreenEdit::InputPlay( const InputEventPlus &input, EditButton EditB )
}
}
break;
default: break;
}
}
}
@@ -2731,6 +2655,7 @@ void ScreenEdit::TransitionEditState( EditState em )
CheckNumberOfNotesAndUndo();
break;
default: break;
}
}
@@ -2831,6 +2756,7 @@ void ScreenEdit::TransitionEditState( EditState em )
m_NoteFieldRecord.m_iEndMarker = m_iStopPlayingAt;
break;
default: break;
}
// Show/hide depending on edit state (em)
@@ -2857,6 +2783,7 @@ void ScreenEdit::TransitionEditState( EditState em )
{
case STATE_PLAYING:
case STATE_RECORDING:
{
const float fStartSeconds = GetAppropriateTiming().GetElapsedTimeFromBeat( GetBeat() );
LOG->Trace( "Starting playback at %f", fStartSeconds );
@@ -2867,6 +2794,8 @@ void ScreenEdit::TransitionEditState( EditState em )
m_pSoundMusic->SetProperty( "AccurateSync", true );
m_pSoundMusic->Play( &p );
break;
}
default: break;
}
m_EditState = em;
@@ -3646,7 +3575,7 @@ void ScreenEdit::DisplayTimingMenu()
{
float fBeat = GetBeat();
TimingData &pTime = GetAppropriateTiming();
bool bHasSpeedOnThisRow = pTime.GetSpeedSegmentAtBeat( fBeat ).GetBeat() == fBeat;
bool bHasSpeedOnThisRow = pTime.GetSpeedSegmentAtBeat( fBeat )->GetBeat() == fBeat;
g_TimingDataInformation.rows[beat_0_offset].SetOneUnthemedChoice( ssprintf("%.6f", pTime.m_fBeat0OffsetInSeconds) );
g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.6f", pTime.GetBPMAtBeat( fBeat ) ) );
@@ -4316,6 +4245,7 @@ void ScreenEdit::HandleAlterMenuChoice(AlterMenuChoice c, const vector<int> &iAn
}
break;
}
default: break;
}
}
@@ -4589,6 +4519,7 @@ void ScreenEdit::HandleSongInformationChoice( SongInformationChoice c, const vec
ssprintf("%.6f", pSong->m_fSpecifiedBPMMax), 20,
ScreenTextEntry::FloatValidate, ChangeMaxBPM, NULL );
break;
default: break;
};
SetDirty(true);
}
@@ -4645,11 +4576,11 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
break;
case time_signature:
{
TimeSignatureSegment &ts = GetAppropriateTiming().GetTimeSignatureSegmentAtBeat( GetBeat() );
TimeSignatureSegment * ts = GetAppropriateTiming().GetTimeSignatureSegmentAtBeat( GetBeat() );
ScreenTextEntry::TextEntry(
SM_BackFromTimeSignatureChange,
ENTER_TIME_SIGNATURE_VALUE,
ssprintf( "%d/%d", ts.GetNum(), ts.GetDen() ),
ssprintf( "%d/%d", ts->GetNum(), ts->GetDen() ),
8
);
break;
@@ -4664,12 +4595,12 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
break;
case combo:
{
ComboSegment &cs = GetAppropriateTiming().GetComboSegmentAtBeat(GetBeat());
ComboSegment *cs = GetAppropriateTiming().GetComboSegmentAtBeat(GetBeat());
ScreenTextEntry::TextEntry(SM_BackFromComboChange,
ENTER_COMBO_VALUE,
ssprintf( "%d/%d",
cs.GetCombo(),
cs.GetMissCombo()),
cs->GetCombo(),
cs->GetMissCombo()),
7);
break;
}
@@ -4693,7 +4624,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
ScreenTextEntry::TextEntry(
SM_BackFromSpeedPercentChange,
ENTER_SPEED_PERCENT_VALUE,
ssprintf( "%.6f", GetAppropriateTiming().GetSpeedSegmentAtBeat( GetBeat() ).GetRatio() ),
ssprintf( "%.6f", GetAppropriateTiming().GetSpeedSegmentAtBeat( GetBeat() )->GetRatio() ),
10
);
break;
@@ -4701,7 +4632,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
ScreenTextEntry::TextEntry(
SM_BackFromScrollChange,
ENTER_SCROLL_VALUE,
ssprintf( "%.6f", GetAppropriateTiming().GetScrollSegmentAtBeat( GetBeat() ).GetRatio() ),
ssprintf( "%.6f", GetAppropriateTiming().GetScrollSegmentAtBeat( GetBeat() )->GetRatio() ),
10
);
break;
@@ -4709,7 +4640,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
ScreenTextEntry::TextEntry(
SM_BackFromSpeedWaitChange,
ENTER_SPEED_WAIT_VALUE,
ssprintf( "%.6f", GetAppropriateTiming().GetSpeedSegmentAtBeat( GetBeat() ).GetLength() ),
ssprintf( "%.6f", GetAppropriateTiming().GetSpeedSegmentAtBeat( GetBeat() )->GetLength() ),
10
);
break;
@@ -4980,8 +4911,8 @@ void ScreenEdit::CheckNumberOfNotesAndUndo()
if( EDIT_MODE.GetValue() != EditMode_Home )
return;
TimeSignatureSegment &curTime = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat );
int rowsPerMeasure = curTime.GetDen() * curTime.GetNum();
TimeSignatureSegment * curTime = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat );
int rowsPerMeasure = curTime->GetDen() * curTime->GetNum();
for( int row=0; row<=m_NoteDataEdit.GetLastRow(); row+=rowsPerMeasure )
{
@@ -5035,7 +4966,7 @@ float ScreenEdit::GetMaximumBeatForNewNote() const
* beats. */
TimingData &timing = s.m_SongTiming;
float playerBeat = GetAppropriatePosition().m_fSongBeat;
int beatsPerMeasure = timing.GetTimeSignatureSegmentAtBeat( playerBeat ).GetNum();
int beatsPerMeasure = timing.GetTimeSignatureSegmentAtBeat( playerBeat )->GetNum();
fEndBeat += beatsPerMeasure;
fEndBeat = ftruncf( fEndBeat, (float)beatsPerMeasure );
+1 -1
View File
@@ -286,7 +286,7 @@ protected:
TapNote m_selectedTap;
/** @brief The type of segment users will jump back and forth between. */
RString currentCycleSegment;
TimingSegmentType currentCycleSegment;
void UpdateTextInfo();
BitmapText m_textInfo; // status information that changes
+24 -19
View File
@@ -193,33 +193,38 @@ void ScreenEditMenu::MenuStart( const InputEventPlus &input )
switch( m_Selector.EDIT_MODE )
{
case EditMode_Full:
{
RString sDir = pSong->GetSongDir();
RString sTempFile = sDir + TEMP_FILE_NAME;
RageFile file;
if( !file.Open( sTempFile, RageFile::WRITE ) )
case EditMode_Full:
{
ScreenPrompt::Prompt( SM_None, SONG_DIR_READ_ONLY );
return;
}
RString sDir = pSong->GetSongDir();
RString sTempFile = sDir + TEMP_FILE_NAME;
RageFile file;
if( !file.Open( sTempFile, RageFile::WRITE ) )
{
ScreenPrompt::Prompt( SM_None, SONG_DIR_READ_ONLY );
return;
}
file.Close();
FILEMAN->Remove( sTempFile );
break;
}
file.Close();
FILEMAN->Remove( sTempFile );
break;
}
default:
break;
}
switch( action )
{
case EditMenuAction_Delete:
ASSERT( pSteps );
if( pSteps->IsAutogen() )
case EditMenuAction_Delete:
{
SCREENMAN->PlayInvalidSound();
SCREENMAN->SystemMessage( DELETED_AUTOGEN_STEPS.GetValue() );
return;
ASSERT( pSteps );
if( pSteps->IsAutogen() )
{
SCREENMAN->PlayInvalidSound();
SCREENMAN->SystemMessage( DELETED_AUTOGEN_STEPS.GetValue() );
return;
}
}
default: break;
}
// Do work
+9 -7
View File
@@ -93,10 +93,11 @@ void ScreenEnding::Init()
m_sprRemoveMemoryCard[p].Load( THEME->GetPathG("ScreenEnding",ssprintf("remove card P%d",p+1)) );
switch( MEMCARDMAN->GetCardState(p) )
{
case MemoryCardState_Removed:
case MemoryCardState_NoCard:
m_sprRemoveMemoryCard[p].SetVisible( false );
break;
case MemoryCardState_Removed:
case MemoryCardState_NoCard:
m_sprRemoveMemoryCard[p].SetVisible( false );
default:
break;
}
LOAD_ALL_COMMANDS_AND_SET_XY_AND_ON_COMMAND( m_sprRemoveMemoryCard[p] );
this->AddChild( &m_sprRemoveMemoryCard[p] );
@@ -114,9 +115,10 @@ void ScreenEnding::Input( const InputEventPlus &input )
{
switch( input.MenuI )
{
case GAME_BUTTON_START:
SCREENMAN->PostMessageToTopScreen( SM_BeginFadingOut, 0 );
break;
case GAME_BUTTON_START:
SCREENMAN->PostMessageToTopScreen( SM_BeginFadingOut, 0 );
default:
break;
}
}
+26 -24
View File
@@ -182,25 +182,26 @@ void ScreenEvaluation::Init()
{
switch( rc )
{
case RadarCategory_Stream:
case RadarCategory_Voltage:
case RadarCategory_Air:
case RadarCategory_Freeze:
case RadarCategory_Chaos:
ss.m_player[p].m_radarPossible[rc] = randomf( 0, 1 );
ss.m_player[p].m_radarActual[rc] = randomf( 0, ss.m_player[p].m_radarPossible[rc] );
break;
case RadarCategory_TapsAndHolds:
case RadarCategory_Jumps:
case RadarCategory_Holds:
case RadarCategory_Mines:
case RadarCategory_Hands:
case RadarCategory_Rolls:
case RadarCategory_Lifts:
case RadarCategory_Fakes:
ss.m_player[p].m_radarPossible[rc] = 1 + (rand() % 200);
ss.m_player[p].m_radarActual[rc] = rand() % (int)(ss.m_player[p].m_radarPossible[rc]);
break;
case RadarCategory_Stream:
case RadarCategory_Voltage:
case RadarCategory_Air:
case RadarCategory_Freeze:
case RadarCategory_Chaos:
ss.m_player[p].m_radarPossible[rc] = randomf( 0, 1 );
ss.m_player[p].m_radarActual[rc] = randomf( 0, ss.m_player[p].m_radarPossible[rc] );
break;
case RadarCategory_TapsAndHolds:
case RadarCategory_Jumps:
case RadarCategory_Holds:
case RadarCategory_Mines:
case RadarCategory_Hands:
case RadarCategory_Rolls:
case RadarCategory_Lifts:
case RadarCategory_Fakes:
ss.m_player[p].m_radarPossible[rc] = 1 + (rand() % 200);
ss.m_player[p].m_radarActual[rc] = rand() % (int)(ss.m_player[p].m_radarPossible[rc]);
break;
default: break;
}
; // filled in by ScreenGameplay on start of notes
@@ -651,11 +652,12 @@ void ScreenEvaluation::Init()
switch( best_grade )
{
case Grade_Tier01:
case Grade_Tier02:
case Grade_Tier03:
this->PostScreenMessage( SM_PlayCheer, CHEER_DELAY_SECONDS );
break;
case Grade_Tier01:
case Grade_Tier02:
case Grade_Tier03:
this->PostScreenMessage( SM_PlayCheer, CHEER_DELAY_SECONDS );
default:
break;
}
}
+294 -260
View File
@@ -151,10 +151,11 @@ void PlayerInfo::Load( PlayerNumber pn, MultiPlayer mp, bool bShowNoteField, int
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_RAVE:
m_pSecondaryScoreDisplay = new ScoreDisplayRave;
m_pSecondaryScoreDisplay->SetName( "ScoreDisplayRave" );
break;
case PLAY_MODE_RAVE:
m_pSecondaryScoreDisplay = new ScoreDisplayRave;
m_pSecondaryScoreDisplay->SetName( "ScoreDisplayRave" );
default:
break;
}
if( m_pSecondaryScoreDisplay )
@@ -164,9 +165,10 @@ void PlayerInfo::Load( PlayerNumber pn, MultiPlayer mp, bool bShowNoteField, int
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_RAVE:
m_pSecondaryScoreKeeper = new ScoreKeeperRave( pPlayerState, pPlayerStageStats );
break;
case PLAY_MODE_RAVE:
m_pSecondaryScoreKeeper = new ScoreKeeperRave( pPlayerState, pPlayerStageStats );
default:
break;
}
m_ptextPlayerOptions = NULL;
@@ -393,9 +395,33 @@ void ScreenGameplay::Init()
/* Called once per stage (single song or single course). */
GAMESTATE->BeginStage();
int player = 1;
FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi )
{
unsigned int count = pi->m_vpStepsQueue.size();
for (unsigned int i = 0; i < count; i++)
{
Steps *curSteps = pi->m_vpStepsQueue[i];
if (curSteps->IsNoteDataEmpty())
{
if (curSteps->GetNoteDataFromSimfile())
{
LOG->Trace("Notes should be loaded for player %d", player);
}
else
{
LOG->Trace("Error loading notes for player %d", player);
}
}
}
player++;
}
if(!GAMESTATE->IsCourseMode() && !GAMESTATE->m_bDemonstrationOrJukebox)
{
// fill in difficulty of CPU players with that of the first human player
// this should not need to worry about step content.
FOREACH_PotentialCpuPlayer(p)
GAMESTATE->m_pCurSteps[p].Set( GAMESTATE->m_pCurSteps[ GAMESTATE->GetFirstHumanPlayer() ] );
@@ -498,13 +524,14 @@ void ScreenGameplay::Init()
// Add combined life meter
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
m_pCombinedLifeMeter = new CombinedLifeMeterTug;
m_pCombinedLifeMeter->SetName( "CombinedLife" );
LOAD_ALL_COMMANDS_AND_SET_XY( *m_pCombinedLifeMeter );
this->AddChild( m_pCombinedLifeMeter );
break;
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
m_pCombinedLifeMeter = new CombinedLifeMeterTug;
m_pCombinedLifeMeter->SetName( "CombinedLife" );
LOAD_ALL_COMMANDS_AND_SET_XY( *m_pCombinedLifeMeter );
this->AddChild( m_pCombinedLifeMeter );
default:
break;
}
// Before the lifemeter loads, if Networking is required
@@ -517,25 +544,26 @@ void ScreenGameplay::Init()
// Add individual life meter
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_REGULAR:
case PLAY_MODE_ONI:
case PLAY_MODE_NONSTOP:
case PLAY_MODE_ENDLESS:
FOREACH_PlayerNumberInfo( m_vPlayerInfo, pi )
{
if( !GAMESTATE->IsPlayerEnabled(pi->m_pn) && !SHOW_LIFE_METER_FOR_DISABLED_PLAYERS )
continue; // skip
case PLAY_MODE_REGULAR:
case PLAY_MODE_ONI:
case PLAY_MODE_NONSTOP:
case PLAY_MODE_ENDLESS:
FOREACH_PlayerNumberInfo( m_vPlayerInfo, pi )
{
if( !GAMESTATE->IsPlayerEnabled(pi->m_pn) && !SHOW_LIFE_METER_FOR_DISABLED_PLAYERS )
continue; // skip
pi->m_pLifeMeter = LifeMeter::MakeLifeMeter( GAMESTATE->m_SongOptions.GetStage().m_LifeType );
pi->m_pLifeMeter->Load( pi->GetPlayerState(), pi->GetPlayerStageStats() );
pi->m_pLifeMeter->SetName( ssprintf("Life%s",pi->GetName().c_str()) );
LOAD_ALL_COMMANDS_AND_SET_XY( pi->m_pLifeMeter );
this->AddChild( pi->m_pLifeMeter );
}
break;
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
break;
pi->m_pLifeMeter = LifeMeter::MakeLifeMeter( GAMESTATE->m_SongOptions.GetStage().m_LifeType );
pi->m_pLifeMeter->Load( pi->GetPlayerState(), pi->GetPlayerStageStats() );
pi->m_pLifeMeter->SetName( ssprintf("Life%s",pi->GetName().c_str()) );
LOAD_ALL_COMMANDS_AND_SET_XY( pi->m_pLifeMeter );
this->AddChild( pi->m_pLifeMeter );
}
break;
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
default:
break;
}
m_bShowScoreboard = false;
@@ -694,11 +722,12 @@ void ScreenGameplay::Init()
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_BATTLE:
m_soundBattleTrickLevel1.Load( THEME->GetPathS(m_sName,"battle trick level1"), true );
m_soundBattleTrickLevel2.Load( THEME->GetPathS(m_sName,"battle trick level2"), true );
m_soundBattleTrickLevel3.Load( THEME->GetPathS(m_sName,"battle trick level3"), true );
break;
case PLAY_MODE_BATTLE:
m_soundBattleTrickLevel1.Load( THEME->GetPathS(m_sName,"battle trick level1"), true );
m_soundBattleTrickLevel2.Load( THEME->GetPathS(m_sName,"battle trick level2"), true );
m_soundBattleTrickLevel3.Load( THEME->GetPathS(m_sName,"battle trick level3"), true );
default:
break;
}
}
@@ -972,9 +1001,10 @@ void ScreenGameplay::SetupSong( int iSongIndex )
RString sType;
switch( GAMESTATE->m_SongOptions.GetCurrent().m_SoundEffectType )
{
case SongOptions::SOUNDEFFECT_OFF: sType = "SoundEffectControl_Off"; break;
case SongOptions::SOUNDEFFECT_SPEED: sType = "SoundEffectControl_Speed"; break;
case SongOptions::SOUNDEFFECT_PITCH: sType = "SoundEffectControl_Pitch"; break;
case SongOptions::SOUNDEFFECT_OFF: sType = "SoundEffectControl_Off"; break;
case SongOptions::SOUNDEFFECT_SPEED: sType = "SoundEffectControl_Speed"; break;
case SongOptions::SOUNDEFFECT_PITCH: sType = "SoundEffectControl_Pitch"; break;
default: break;
}
pi->m_SoundEffectControl.Load( sType, pi->GetPlayerState(), &pi->m_NoteData );
@@ -1606,246 +1636,250 @@ void ScreenGameplay::Update( float fDeltaTime )
switch( m_DancingState )
{
case STATE_DANCING:
/* Set STATSMAN->m_CurStageStats.bFailed for failed players. In, FAIL_IMMEDIATE, send
* SM_BeginFailed if all players failed, and kill dead Oni players. */
FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi )
case STATE_DANCING:
{
PlayerNumber pn = pi->GetStepsAndTrailIndex();
PlayerOptions::FailType ft = GAMESTATE->GetPlayerFailType( pi->GetPlayerState() );
SongOptions::LifeType lt = GAMESTATE->m_SongOptions.GetCurrent().m_LifeType;
if( ft == PlayerOptions::FAIL_OFF || ft == PlayerOptions::FAIL_AT_END )
continue;
// check for individual fail
if( pi->m_pLifeMeter == NULL || !pi->m_pLifeMeter->IsFailing() )
continue; /* isn't failing */
if( pi->GetPlayerStageStats()->m_bFailed )
continue; /* failed and is already dead */
LOG->Trace("Player %d failed", (int)pn);
pi->GetPlayerStageStats()->m_bFailed = true; // fail
/* Set STATSMAN->m_CurStageStats.bFailed for failed players. In, FAIL_IMMEDIATE, send
* SM_BeginFailed if all players failed, and kill dead Oni players. */
FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi )
{
Message msg("PlayerFailed");
msg.SetParam( "PlayerNumber", pi->m_pn );
MESSAGEMAN->Broadcast( msg );
}
PlayerNumber pn = pi->GetStepsAndTrailIndex();
PlayerOptions::FailType ft = GAMESTATE->GetPlayerFailType( pi->GetPlayerState() );
SongOptions::LifeType lt = GAMESTATE->m_SongOptions.GetCurrent().m_LifeType;
if( ft == PlayerOptions::FAIL_OFF || ft == PlayerOptions::FAIL_AT_END )
continue;
// check for individual fail
if( pi->m_pLifeMeter == NULL || !pi->m_pLifeMeter->IsFailing() )
continue; /* isn't failing */
if( pi->GetPlayerStageStats()->m_bFailed )
continue; /* failed and is already dead */
LOG->Trace("Player %d failed", (int)pn);
pi->GetPlayerStageStats()->m_bFailed = true; // fail
// Check for and do Oni die.
bool bAllowOniDie = false;
switch( lt )
{
case SongOptions::LIFE_BATTERY:
bAllowOniDie = true;
break;
}
if( bAllowOniDie && ft == PlayerOptions::FAIL_IMMEDIATE )
{
if( !STATSMAN->m_CurStageStats.AllFailed() ) // if not the last one to fail
{
// kill them!
SOUND->PlayOnceFromDir( THEME->GetPathS(m_sName,"oni die") );
pi->ShowOniGameOver();
pi->m_NoteData.Init(); // remove all notes and scoring
pi->m_pPlayer->FadeToFail(); // tell the NoteField to fade to white
Message msg("PlayerFailed");
msg.SetParam( "PlayerNumber", pi->m_pn );
MESSAGEMAN->Broadcast( msg );
}
// Check for and do Oni die.
bool bAllowOniDie = false;
switch( lt )
{
case SongOptions::LIFE_BATTERY:
bAllowOniDie = true;
default:
break;
}
if( bAllowOniDie && ft == PlayerOptions::FAIL_IMMEDIATE )
{
if( !STATSMAN->m_CurStageStats.AllFailed() ) // if not the last one to fail
{
// kill them!
SOUND->PlayOnceFromDir( THEME->GetPathS(m_sName,"oni die") );
pi->ShowOniGameOver();
pi->m_NoteData.Init(); // remove all notes and scoring
pi->m_pPlayer->FadeToFail(); // tell the NoteField to fade to white
}
}
}
}
bool bAllFailed = true;
FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi )
{
PlayerOptions::FailType ft = GAMESTATE->GetPlayerFailType( pi->GetPlayerState() );
switch( ft )
bool bAllFailed = true;
FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi )
{
case PlayerOptions::FAIL_IMMEDIATE:
if( pi->m_pLifeMeter == NULL || (pi->m_pLifeMeter && !pi->m_pLifeMeter->IsFailing()) )
bAllFailed = false;
break;
case PlayerOptions::FAIL_IMMEDIATE_CONTINUE:
case PlayerOptions::FAIL_AT_END:
bAllFailed = false; // wait until the end of the song to fail.
break;
case PlayerOptions::FAIL_OFF:
bAllFailed = false; // never fail.
break;
default:
ASSERT(0);
}
}
if( bAllFailed )
{
m_pSoundMusic->StopPlaying();
SCREENMAN->PostMessageToTopScreen( SM_NotesEnded, 0 );
// todo: stop lyrics (m_LyricDisplay) from animating -aj
}
// Update living players' alive time
// HACK: Don't scale alive time when using tab/tilde. Instead of accumulating time from a timer,
// this time should instead be tied to the music position.
float fUnscaledDeltaTime = m_timerGameplaySeconds.GetDeltaTime();
FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi )
if( !pi->GetPlayerStageStats()->m_bFailed )
pi->GetPlayerStageStats()->m_fAliveSeconds += fUnscaledDeltaTime * GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate;
// update fGameplaySeconds
STATSMAN->m_CurStageStats.m_fGameplaySeconds += fUnscaledDeltaTime;
float curBeat = GAMESTATE->m_Position.m_fSongBeat;
Song &s = *GAMESTATE->m_pCurSong;
if( curBeat >= s.GetFirstBeat() && curBeat < s.GetLastBeat() )
{
STATSMAN->m_CurStageStats.m_fStepsSeconds += fUnscaledDeltaTime;
if( GAMESTATE->m_SongOptions.GetCurrent().m_fHaste != 0.0f )
{
float fHasteRate = GetHasteRate();
GAMESTATE->m_fAccumulatedHasteSeconds += (fUnscaledDeltaTime * fHasteRate) - fUnscaledDeltaTime;
}
}
// Check for end of song
{
float fSecondsToStartFadingOutMusic, fSecondsToStartTransitioningOut;
GetMusicEndTiming( fSecondsToStartFadingOutMusic, fSecondsToStartTransitioningOut );
bool bAllReallyFailed = STATSMAN->m_CurStageStats.AllFailed();
if( bAllReallyFailed )
fSecondsToStartTransitioningOut += BEGIN_FAILED_DELAY;
if( GAMESTATE->m_Position.m_fMusicSeconds >= fSecondsToStartTransitioningOut && !m_NextSong.IsTransitioning() )
this->PostScreenMessage( SM_NotesEnded, 0 );
}
// update 2d dancing characters
FOREACH_EnabledPlayerNumberInfo( m_vPlayerInfo, pi )
{
DancingCharacters *pCharacter = NULL;
if( m_pSongBackground )
pCharacter = m_pSongBackground->GetDancingCharacters();
if( pCharacter != NULL )
{
TapNoteScore tns = pi->m_pPlayer->GetLastTapNoteScore();
ANIM_STATES_2D state = AS2D_MISS;
switch( tns )
PlayerOptions::FailType ft = GAMESTATE->GetPlayerFailType( pi->GetPlayerState() );
switch( ft )
{
case TNS_W4:
case TNS_W3:
state = AS2D_GOOD;
case PlayerOptions::FAIL_IMMEDIATE:
if( pi->m_pLifeMeter == NULL || (pi->m_pLifeMeter && !pi->m_pLifeMeter->IsFailing()) )
bAllFailed = false;
break;
case TNS_W2:
case TNS_W1:
state = AS2D_GREAT;
case PlayerOptions::FAIL_IMMEDIATE_CONTINUE:
case PlayerOptions::FAIL_AT_END:
bAllFailed = false; // wait until the end of the song to fail.
break;
case PlayerOptions::FAIL_OFF:
bAllFailed = false; // never fail.
break;
default:
state = AS2D_MISS;
break;
}
if( state == AS2D_GREAT && pi->GetPlayerState()->m_HealthState == HealthState_Hot )
state = AS2D_FEVER;
pCharacter->Change2DAnimState( pi->m_pn, state );
}
}
// Check for enemy death in enemy battle
static float fLastSeenEnemyHealth = 1;
if( fLastSeenEnemyHealth != GAMESTATE->m_fOpponentHealthPercent )
{
fLastSeenEnemyHealth = GAMESTATE->m_fOpponentHealthPercent;
if( GAMESTATE->m_fOpponentHealthPercent == 0 )
{
// HACK: Load incorrect directory on purpose for now.
PlayAnnouncer( "gameplay battle damage level3", 0 );
GAMESTATE->RemoveAllActiveAttacks();
FOREACH_EnabledPlayerNumberInfo( m_vPlayerInfo, pi )
{
if( !GAMESTATE->IsCpuPlayer(pi->m_pn) )
continue;
SOUND->PlayOnceFromDir( THEME->GetPathS(m_sName,"oni die") );
pi->ShowOniGameOver();
pi->m_NoteData.Init(); // remove all notes and scoring
pi->m_pPlayer->FadeToFail(); // tell the NoteField to fade to white
FAIL_M("Invalid fail type! Aborting...");
}
}
}
// update give up
bool bGiveUpTimerFired = !m_GiveUpTimer.IsZero() && m_GiveUpTimer.Ago() > 2.5f;
bool bAllHumanHaveBigMissCombo = true;
FOREACH_EnabledPlayerNumberInfo( m_vPlayerInfo, pi )
{
if (pi->GetPlayerState()->m_PlayerOptions.GetCurrent().m_FailType == PlayerOptions::FAIL_OFF ||
pi->GetPlayerState()->m_HealthState < HealthState_Dead )
{
bAllHumanHaveBigMissCombo = false;
break;
}
}
if (bAllHumanHaveBigMissCombo) // possible to get in here.
{
bAllHumanHaveBigMissCombo = FAIL_ON_MISS_COMBO.GetValue() != -1 && STATSMAN->m_CurStageStats.GetMinimumMissCombo() >= FAIL_ON_MISS_COMBO;
}
if( bGiveUpTimerFired || bAllHumanHaveBigMissCombo )
{
STATSMAN->m_CurStageStats.m_bGaveUp = true;
FOREACH_EnabledPlayerNumberInfo( m_vPlayerInfo, pi )
{
pi->GetPlayerStageStats()->m_bFailed |= bAllHumanHaveBigMissCombo;
pi->GetPlayerStageStats()->m_bDisqualified |= bGiveUpTimerFired; // Don't disqualify if failing for miss combo. The player should still be eligable for a high score on courses.
}
AbortGiveUp( false );
if( GIVING_UP_GOES_TO_PREV_SCREEN )
{
BeginBackingOutFromGameplay();
}
else
if( bAllFailed )
{
m_pSoundMusic->StopPlaying();
this->PostScreenMessage( SM_NotesEnded, 0 );
SCREENMAN->PostMessageToTopScreen( SM_NotesEnded, 0 );
// todo: stop lyrics (m_LyricDisplay) from animating -aj
}
return;
}
// Check to see if it's time to play a ScreenGameplay comment
m_fTimeSinceLastDancingComment += fDeltaTime;
// Update living players' alive time
// HACK: Don't scale alive time when using tab/tilde. Instead of accumulating time from a timer,
// this time should instead be tied to the music position.
float fUnscaledDeltaTime = m_timerGameplaySeconds.GetDeltaTime();
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_REGULAR:
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
if( GAMESTATE->OneIsHot() )
PlayAnnouncer( "gameplay comment hot", SECONDS_BETWEEN_COMMENTS );
else if( GAMESTATE->AllAreInDangerOrWorse() )
PlayAnnouncer( "gameplay comment danger", SECONDS_BETWEEN_COMMENTS );
else
PlayAnnouncer( "gameplay comment good", SECONDS_BETWEEN_COMMENTS );
break;
case PLAY_MODE_NONSTOP:
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
PlayAnnouncer( "gameplay comment oni", SECONDS_BETWEEN_COMMENTS );
break;
default:
ASSERT(0);
}
FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi )
if( !pi->GetPlayerStageStats()->m_bFailed )
pi->GetPlayerStageStats()->m_fAliveSeconds += fUnscaledDeltaTime * GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate;
// update fGameplaySeconds
STATSMAN->m_CurStageStats.m_fGameplaySeconds += fUnscaledDeltaTime;
float curBeat = GAMESTATE->m_Position.m_fSongBeat;
Song &s = *GAMESTATE->m_pCurSong;
if( curBeat >= s.GetFirstBeat() && curBeat < s.GetLastBeat() )
{
STATSMAN->m_CurStageStats.m_fStepsSeconds += fUnscaledDeltaTime;
if( GAMESTATE->m_SongOptions.GetCurrent().m_fHaste != 0.0f )
{
float fHasteRate = GetHasteRate();
GAMESTATE->m_fAccumulatedHasteSeconds += (fUnscaledDeltaTime * fHasteRate) - fUnscaledDeltaTime;
}
}
// Check for end of song
{
float fSecondsToStartFadingOutMusic, fSecondsToStartTransitioningOut;
GetMusicEndTiming( fSecondsToStartFadingOutMusic, fSecondsToStartTransitioningOut );
bool bAllReallyFailed = STATSMAN->m_CurStageStats.AllFailed();
if( bAllReallyFailed )
fSecondsToStartTransitioningOut += BEGIN_FAILED_DELAY;
if( GAMESTATE->m_Position.m_fMusicSeconds >= fSecondsToStartTransitioningOut && !m_NextSong.IsTransitioning() )
this->PostScreenMessage( SM_NotesEnded, 0 );
}
// update 2d dancing characters
FOREACH_EnabledPlayerNumberInfo( m_vPlayerInfo, pi )
{
DancingCharacters *pCharacter = NULL;
if( m_pSongBackground )
pCharacter = m_pSongBackground->GetDancingCharacters();
if( pCharacter != NULL )
{
TapNoteScore tns = pi->m_pPlayer->GetLastTapNoteScore();
ANIM_STATES_2D state = AS2D_MISS;
switch( tns )
{
case TNS_W4:
case TNS_W3:
state = AS2D_GOOD;
break;
case TNS_W2:
case TNS_W1:
state = AS2D_GREAT;
break;
default:
state = AS2D_MISS;
break;
}
if( state == AS2D_GREAT && pi->GetPlayerState()->m_HealthState == HealthState_Hot )
state = AS2D_FEVER;
pCharacter->Change2DAnimState( pi->m_pn, state );
}
}
// Check for enemy death in enemy battle
static float fLastSeenEnemyHealth = 1;
if( fLastSeenEnemyHealth != GAMESTATE->m_fOpponentHealthPercent )
{
fLastSeenEnemyHealth = GAMESTATE->m_fOpponentHealthPercent;
if( GAMESTATE->m_fOpponentHealthPercent == 0 )
{
// HACK: Load incorrect directory on purpose for now.
PlayAnnouncer( "gameplay battle damage level3", 0 );
GAMESTATE->RemoveAllActiveAttacks();
FOREACH_EnabledPlayerNumberInfo( m_vPlayerInfo, pi )
{
if( !GAMESTATE->IsCpuPlayer(pi->m_pn) )
continue;
SOUND->PlayOnceFromDir( THEME->GetPathS(m_sName,"oni die") );
pi->ShowOniGameOver();
pi->m_NoteData.Init(); // remove all notes and scoring
pi->m_pPlayer->FadeToFail(); // tell the NoteField to fade to white
}
}
}
// update give up
bool bGiveUpTimerFired = !m_GiveUpTimer.IsZero() && m_GiveUpTimer.Ago() > 2.5f;
bool bAllHumanHaveBigMissCombo = true;
FOREACH_EnabledPlayerNumberInfo( m_vPlayerInfo, pi )
{
if (pi->GetPlayerState()->m_PlayerOptions.GetCurrent().m_FailType == PlayerOptions::FAIL_OFF ||
pi->GetPlayerState()->m_HealthState < HealthState_Dead )
{
bAllHumanHaveBigMissCombo = false;
break;
}
}
if (bAllHumanHaveBigMissCombo) // possible to get in here.
{
bAllHumanHaveBigMissCombo = FAIL_ON_MISS_COMBO.GetValue() != -1 && STATSMAN->m_CurStageStats.GetMinimumMissCombo() >= FAIL_ON_MISS_COMBO;
}
if( bGiveUpTimerFired || bAllHumanHaveBigMissCombo )
{
STATSMAN->m_CurStageStats.m_bGaveUp = true;
FOREACH_EnabledPlayerNumberInfo( m_vPlayerInfo, pi )
{
pi->GetPlayerStageStats()->m_bFailed |= bAllHumanHaveBigMissCombo;
pi->GetPlayerStageStats()->m_bDisqualified |= bGiveUpTimerFired; // Don't disqualify if failing for miss combo. The player should still be eligable for a high score on courses.
}
AbortGiveUp( false );
if( GIVING_UP_GOES_TO_PREV_SCREEN )
{
BeginBackingOutFromGameplay();
}
else
{
m_pSoundMusic->StopPlaying();
this->PostScreenMessage( SM_NotesEnded, 0 );
}
return;
}
// Check to see if it's time to play a ScreenGameplay comment
m_fTimeSinceLastDancingComment += fDeltaTime;
switch( GAMESTATE->m_PlayMode )
{
case PLAY_MODE_REGULAR:
case PLAY_MODE_BATTLE:
case PLAY_MODE_RAVE:
if( GAMESTATE->OneIsHot() )
PlayAnnouncer( "gameplay comment hot", SECONDS_BETWEEN_COMMENTS );
else if( GAMESTATE->AllAreInDangerOrWorse() )
PlayAnnouncer( "gameplay comment danger", SECONDS_BETWEEN_COMMENTS );
else
PlayAnnouncer( "gameplay comment good", SECONDS_BETWEEN_COMMENTS );
break;
case PLAY_MODE_NONSTOP:
case PLAY_MODE_ONI:
case PLAY_MODE_ENDLESS:
PlayAnnouncer( "gameplay comment oni", SECONDS_BETWEEN_COMMENTS );
break;
default:
ASSERT(0);
}
}
default: break;
}
PlayTicks();
+6 -4
View File
@@ -248,10 +248,12 @@ void ScreenJukebox::Input( const InputEventPlus &input )
switch( input.MenuI )
{
case GAME_BUTTON_LEFT:
case GAME_BUTTON_RIGHT:
SCREENMAN->PostMessageToTopScreen( SM_NotesEnded, 0 );
return;
case GAME_BUTTON_LEFT:
case GAME_BUTTON_RIGHT:
SCREENMAN->PostMessageToTopScreen( SM_NotesEnded, 0 );
return;
default:
break;
}
ScreenAttract::AttractInput( input, this );
+2 -13
View File
@@ -54,7 +54,7 @@ void ScreenNetSelectMusic::Init()
m_StepsDisplays[p].SetName( ssprintf("StepsDisplayP%d",p+1) );
m_StepsDisplays[p].Load( "StepsDisplayNet", NULL );
LOAD_ALL_COMMANDS_AND_SET_XY_AND_ON_COMMAND( m_StepsDisplays[p] );
LOAD_ALL_COMMANDS_AND_SET_XY( m_StepsDisplays[p] );
this->AddChild( &m_StepsDisplays[p] );
}
@@ -66,20 +66,13 @@ void ScreenNetSelectMusic::Init()
this->AddChild( &m_MusicWheel );
this->MoveToHead( &m_MusicWheel );
// todo: handle me theme-side -aj
m_BPMDisplay.SetName( "BPMDisplay" );
m_BPMDisplay.LoadFromFont( THEME->GetPathF("BPMDisplay","bpm") );
m_BPMDisplay.Load();
LOAD_ALL_COMMANDS_AND_SET_XY_AND_ON_COMMAND( m_BPMDisplay );
this->AddChild( &m_BPMDisplay );
// todo: handle me theme-side -aj
FOREACH_EnabledPlayer( p )
{
m_ModIconRow[p].SetName( ssprintf("ModIconsP%d",p+1) );
m_ModIconRow[p].Load( "ModIconRowSelectMusic", p );
m_ModIconRow[p].SetFromGameState();
LOAD_ALL_COMMANDS_AND_SET_XY_AND_ON_COMMAND( m_ModIconRow[p] );
LOAD_ALL_COMMANDS_AND_SET_XY( m_ModIconRow[p] );
this->AddChild( &m_ModIconRow[p] );
}
@@ -435,8 +428,6 @@ void ScreenNetSelectMusic::TweenOffScreen()
OFF_COMMAND( m_MusicWheel );
OFF_COMMAND( m_BPMDisplay );
FOREACH_EnabledPlayer (pn)
{
OFF_COMMAND( m_StepsDisplays[pn] );
@@ -495,7 +486,6 @@ void ScreenNetSelectMusic::MusicChanged()
{
if( GAMESTATE->m_pCurSong == NULL )
{
m_BPMDisplay.NoBPM();
FOREACH_EnabledPlayer (pn)
UpdateDifficulties( pn );
@@ -504,7 +494,6 @@ void ScreenNetSelectMusic::MusicChanged()
// SOUND->PlayMusic( m_sSectionMusicPath, NULL, true, 0, -1 );
return;
}
m_BPMDisplay.SetBpmFromSong( GAMESTATE->m_pCurSong );
FOREACH_EnabledPlayer (pn)
{

Some files were not shown because too many files have changed in this diff Show More