[default->loading window] Catching up.
@@ -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-*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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:;
|
||||
|
||||
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 766 B After Width: | Height: | Size: 466 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
@@ -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",
|
||||
|
||||
|
After Width: | Height: | Size: 32 KiB |
@@ -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:
|
||||
@@ -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] }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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ść.
|
||||
@@ -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");
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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}"
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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/";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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() );
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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( ¶ms );
|
||||
MESSAGEMAN->Broadcast( (MessageID)(Message_CardRemovedP1+p) );
|
||||
}
|
||||
break;
|
||||
case MemoryCardState_Ready:
|
||||
m_soundReady.Play( ¶ms );
|
||||
break;
|
||||
case MemoryCardState_TooLate:
|
||||
m_soundTooLate.Play( ¶ms );
|
||||
break;
|
||||
case MemoryCardState_Error:
|
||||
m_soundError.Play( ¶ms );
|
||||
break;
|
||||
case MemoryCardState_NoCard:
|
||||
case MemoryCardState_Removed:
|
||||
if( LastState == MemoryCardState_Ready )
|
||||
{
|
||||
m_soundDisconnect.Play( ¶ms );
|
||||
MESSAGEMAN->Broadcast( (MessageID)(Message_CardRemovedP1+p) );
|
||||
}
|
||||
break;
|
||||
case MemoryCardState_Ready:
|
||||
m_soundReady.Play( ¶ms );
|
||||
break;
|
||||
case MemoryCardState_TooLate:
|
||||
m_soundTooLate.Play( ¶ms );
|
||||
break;
|
||||
case MemoryCardState_Error:
|
||||
m_soundError.Play( ¶ms );
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
m_State[p] = state;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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("");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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 ¶ms = 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ¶ms = 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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( ";" );
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"; }
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||