[default -> loading window] YAM
This commit is contained in:
+17
-1
@@ -5,9 +5,25 @@ from StepMania 4 alpha 5 to sm-ssc v1.2.5, see Changelog_sm-ssc.txt.
|
|||||||
________________________________________________________________________________
|
________________________________________________________________________________
|
||||||
|
|
||||||
================================================================================
|
================================================================================
|
||||||
StepMania 5.0 Preview 2 | 20110???
|
StepMania 5.0 Preview 2 | 201106??
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
2011/06/19
|
||||||
|
* [EditMenu] Allow all songs to work in Practice Mode, regardless of folder
|
||||||
|
location. This fixes a crash if everyone had songs in AdditionalSongs.
|
||||||
|
[Wolfman2000]
|
||||||
|
|
||||||
|
2011/06/17
|
||||||
|
----------
|
||||||
|
* [LifeMeterBattery] Fixed a bug where MinesSubtractLives was not being honored.
|
||||||
|
Also added LifeChanged message to changing of life on holds. [AJ]
|
||||||
|
|
||||||
|
2011/06/15
|
||||||
|
----------
|
||||||
|
* [TimingData] Added many lua bindings for the other timing segments. GetWarps,
|
||||||
|
GetCombos, GetTimeSignatures, GetTickcounts, GetFakes, GetScrolls, GetSpeeds.
|
||||||
|
This should cover all of them now. [Wolfman2000]
|
||||||
|
|
||||||
2011/06/13
|
2011/06/13
|
||||||
----------
|
----------
|
||||||
* [InputHandler_DirectInput] Fixed MouseWheel input not resetting. [AJ]
|
* [InputHandler_DirectInput] Fixed MouseWheel input not resetting. [AJ]
|
||||||
|
|||||||
@@ -1430,10 +1430,17 @@
|
|||||||
<Function name='GetBPMs'/>
|
<Function name='GetBPMs'/>
|
||||||
<Function name='GetBPMsAndTimes'/>
|
<Function name='GetBPMsAndTimes'/>
|
||||||
<Function name='GetBeatFromElapsedTime'/>
|
<Function name='GetBeatFromElapsedTime'/>
|
||||||
|
<Function name='GetCombos'/>
|
||||||
<Function name='GetDelays'/>
|
<Function name='GetDelays'/>
|
||||||
<Function name='GetElapsedTimeFromBeat'/>
|
<Function name='GetElapsedTimeFromBeat'/>
|
||||||
|
<Function name='GetFakes'/>
|
||||||
<Function name='GetLabels'/>
|
<Function name='GetLabels'/>
|
||||||
|
<Function name='GetScrolls'/>
|
||||||
|
<Function name='GetSpeeds'/>
|
||||||
<Function name='GetStops'/>
|
<Function name='GetStops'/>
|
||||||
|
<Function name='GetTickcounts'/>
|
||||||
|
<Function name='GetTimeSignatures'/>
|
||||||
|
<Function name='GetWarps'/>
|
||||||
<Function name='HasBPMChanges'/>
|
<Function name='HasBPMChanges'/>
|
||||||
<Function name='HasFakes'/>
|
<Function name='HasFakes'/>
|
||||||
<Function name='HasNegativeBPMs'/>
|
<Function name='HasNegativeBPMs'/>
|
||||||
|
|||||||
@@ -3611,6 +3611,27 @@
|
|||||||
<Function name='GetLabels' return='{string}' arguments=''>
|
<Function name='GetLabels' return='{string}' arguments=''>
|
||||||
Returns a table of the Labels and the times they happen as strings with the format "<code>beat=label name</code>."
|
Returns a table of the Labels and the times they happen as strings with the format "<code>beat=label name</code>."
|
||||||
</Function>
|
</Function>
|
||||||
|
<Function name='GetWarps' return='{string}' arguments=''>
|
||||||
|
Returns a table of the Warps and the times they happen as strings with the format "<code>beat=number of beats warped over</code>."
|
||||||
|
</Function>
|
||||||
|
<Function name='GetCombos' return='{string}' arguments=''>
|
||||||
|
Returns a table of the Combos and the times they happen as strings with the format "<code>beat=combo value</code>."
|
||||||
|
</Function>
|
||||||
|
<Function name='GetTimeSignatures' return='{string}' arguments=''>
|
||||||
|
Returns a table of the Time Signatures and the times they happen as strings with the format "<code>beat=beats per measure (numerator)=denominator</code>."
|
||||||
|
</Function>
|
||||||
|
<Function name='GetTickcounts' return='{string}' arguments=''>
|
||||||
|
Returns a table of the Tickcountss and the times they happen as strings with the format "<code>beat=number of ticks per beat</code>."
|
||||||
|
</Function>
|
||||||
|
<Function name='GetFakes' return='{string}' arguments=''>
|
||||||
|
Returns a table of the Fakes and the times they happen as strings with the format "<code>beat=number of beats to not judge</code>."
|
||||||
|
</Function>
|
||||||
|
<Function name='GetScrolls' return='{string}' arguments=''>
|
||||||
|
Returns a table of the Scrolls and the times they happen as strings with the format "<code>beat=scroll rate ratio</code>."
|
||||||
|
</Function>
|
||||||
|
<Function name='GetSpeeds' return='{string}' arguments=''>
|
||||||
|
Returns a table of the Speeds and the times they happen as strings with the format "<code>beat=scroll rate ratio=length of time to fully activate=unit of activation (0 for beats, 1 for seconds)</code>."
|
||||||
|
</Function>
|
||||||
<Function name='HasBPMChanges' return='bool' arguments=''>
|
<Function name='HasBPMChanges' return='bool' arguments=''>
|
||||||
Returns <code>true</code> if the TimingData contains BPM changes.
|
Returns <code>true</code> if the TimingData contains BPM changes.
|
||||||
</Function>
|
</Function>
|
||||||
|
|||||||
@@ -247,3 +247,15 @@ function Hue(color,newHue)
|
|||||||
c.Hue = newHue
|
c.Hue = newHue
|
||||||
return HSVToColor(c)
|
return HSVToColor(c)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function Alpha(color,percent)
|
||||||
|
local c = ColorToHSV(color);
|
||||||
|
-- error checking
|
||||||
|
if percent < 0 then
|
||||||
|
percent = 0.0;
|
||||||
|
elseif percent > 1 then
|
||||||
|
percent = 1.0;
|
||||||
|
end;
|
||||||
|
c.Alpha = percent;
|
||||||
|
return HSVToColor(c);
|
||||||
|
end;
|
||||||
@@ -84,15 +84,20 @@ r['DDR Extreme'] = function(params, pss)
|
|||||||
setmetatable(judgmentBase, ZeroIfNotFound);
|
setmetatable(judgmentBase, ZeroIfNotFound);
|
||||||
local steps = GAMESTATE:GetCurrentSteps(params.Player);
|
local steps = GAMESTATE:GetCurrentSteps(params.Player);
|
||||||
local radarValues = steps:GetRadarValues(params.Player);
|
local radarValues = steps:GetRadarValues(params.Player);
|
||||||
local baseScore = (steps:IsAnEdit() and
|
local meter = steps:GetMeter();
|
||||||
5 or steps:GetMeter()) * 1000000;
|
if (steps:IsAnEdit()) then
|
||||||
|
meter = 5;
|
||||||
|
elseif (meter < 1) then
|
||||||
|
meter = 1;
|
||||||
|
elseif (meter > 10) then
|
||||||
|
meter = 10;
|
||||||
|
end;
|
||||||
|
local baseScore = meter * 1000000;
|
||||||
if (GAMESTATE:GetCurrentSong():IsMarathon()) then
|
if (GAMESTATE:GetCurrentSong():IsMarathon()) then
|
||||||
baseScore = baseScore * 3;
|
baseScore = baseScore * 3;
|
||||||
else
|
elseif (GAMESTATE:GetCurrentSong():IsLong()) then
|
||||||
if (GAMESTATE:GetCurrentSong():IsLong()) then
|
|
||||||
baseScore = baseScore * 2;
|
baseScore = baseScore * 2;
|
||||||
end;
|
end;
|
||||||
end;
|
|
||||||
local totalItems = GetTotalItems(radarValues);
|
local totalItems = GetTotalItems(radarValues);
|
||||||
local singleStep = (1 + totalItems) * totalItems / 2;
|
local singleStep = (1 + totalItems) * totalItems / 2;
|
||||||
if (not Shared.CurrentStep) then
|
if (not Shared.CurrentStep) then
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
; don't forget to change this before releasing a new verson.
|
; don't forget to change this before releasing a new verson.
|
||||||
; wish this could be automated, but it requires "X.Y.Z.a" format. -aj
|
; wish this could be automated, but it requires "X.Y.Z.a" format. -aj
|
||||||
VIProductVersion "1.2.3.0"
|
VIProductVersion "5.0.0.3"
|
||||||
VIAddVersionKey "ProductName" "${PRODUCT_ID}"
|
VIAddVersionKey "ProductName" "${PRODUCT_ID}"
|
||||||
VIAddVersionKey "FileVersion" "${PRODUCT_VER}"
|
VIAddVersionKey "FileVersion" "${PRODUCT_VER}"
|
||||||
VIAddVersionKey "FileDescription" "${PRODUCT_ID} Installer"
|
VIAddVersionKey "FileDescription" "${PRODUCT_ID} Installer"
|
||||||
|
|||||||
@@ -63,6 +63,10 @@ void AutoKeysounds::LoadAutoplaySoundsInto( RageSoundReader_Chain *pChain )
|
|||||||
if( t >= m_ndAutoKeysoundsOnly[pn].GetNumTracks() )
|
if( t >= m_ndAutoKeysoundsOnly[pn].GetNumTracks() )
|
||||||
continue;
|
continue;
|
||||||
int iNextRowForPlayer = iRow;
|
int iNextRowForPlayer = iRow;
|
||||||
|
/* XXX: If a BMS file only has one tap note per track,
|
||||||
|
* this will prevent any keysounds from loading.
|
||||||
|
* This leads to failure later on.
|
||||||
|
* We need a better way to prevent this. */
|
||||||
if( m_ndAutoKeysoundsOnly[pn].GetNextTapNoteRowForTrack( t, iNextRowForPlayer ) )
|
if( m_ndAutoKeysoundsOnly[pn].GetNextTapNoteRowForTrack( t, iNextRowForPlayer ) )
|
||||||
iNextRow = min( iNextRow, iNextRowForPlayer );
|
iNextRow = min( iNextRow, iNextRowForPlayer );
|
||||||
}
|
}
|
||||||
@@ -274,7 +278,7 @@ void AutoKeysounds::FinishLoading()
|
|||||||
delete pChain;
|
delete pChain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ASSERT( m_pSharedSound );
|
ASSERT_M( m_pSharedSound, ssprintf("No keysounds were loaded for the song %s!", pSong->m_sMainTitle.c_str() ));
|
||||||
|
|
||||||
m_pSharedSound = new RageSoundReader_PitchChange( m_pSharedSound );
|
m_pSharedSound = new RageSoundReader_PitchChange( m_pSharedSound );
|
||||||
m_pSharedSound = new RageSoundReader_PostBuffering( m_pSharedSound );
|
m_pSharedSound = new RageSoundReader_PostBuffering( m_pSharedSound );
|
||||||
|
|||||||
+1
-1
@@ -60,7 +60,7 @@ void EditMenu::GetSongsToShowForGroup( const RString &sGroup, vector<Song*> &vpS
|
|||||||
for( int i=vpSongsOut.size()-1; i>=0; i-- )
|
for( int i=vpSongsOut.size()-1; i>=0; i-- )
|
||||||
{
|
{
|
||||||
const Song* pSong = vpSongsOut[i];
|
const Song* pSong = vpSongsOut[i];
|
||||||
if( !pSong->NormallyDisplayed() || pSong->IsTutorial() || SONGMAN->WasLoadedFromAdditionalSongs(pSong) )
|
if( !pSong->NormallyDisplayed() || pSong->IsTutorial() )
|
||||||
vpSongsOut.erase( vpSongsOut.begin()+i );
|
vpSongsOut.erase( vpSongsOut.begin()+i );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
+101
-12
@@ -10,6 +10,7 @@
|
|||||||
#include "EnumHelper.h"
|
#include "EnumHelper.h"
|
||||||
#include "ThemeMetric.h"
|
#include "ThemeMetric.h"
|
||||||
|
|
||||||
|
/** @brief What type of row is needed for the EditMenu? */
|
||||||
enum EditMenuRow
|
enum EditMenuRow
|
||||||
{
|
{
|
||||||
ROW_GROUP,
|
ROW_GROUP,
|
||||||
@@ -19,11 +20,19 @@ enum EditMenuRow
|
|||||||
ROW_SOURCE_STEPS_TYPE,
|
ROW_SOURCE_STEPS_TYPE,
|
||||||
ROW_SOURCE_STEPS,
|
ROW_SOURCE_STEPS,
|
||||||
ROW_ACTION,
|
ROW_ACTION,
|
||||||
NUM_EditMenuRow
|
NUM_EditMenuRow /**< The number of EditMenuRows available. */
|
||||||
};
|
};
|
||||||
/** @brief Loop through each EditMenuRow. */
|
/** @brief Loop through each EditMenuRow. */
|
||||||
#define FOREACH_EditMenuRow( r ) FOREACH_ENUM( EditMenuRow, r )
|
#define FOREACH_EditMenuRow( r ) FOREACH_ENUM( EditMenuRow, r )
|
||||||
|
/**
|
||||||
|
* @brief Turn the EditMenuRow into a string.
|
||||||
|
* @param r the row.
|
||||||
|
* @return the string. */
|
||||||
const RString& EditMenuRowToString( EditMenuRow r );
|
const RString& EditMenuRowToString( EditMenuRow r );
|
||||||
|
/**
|
||||||
|
* @brief Turn the EditMenuRow into a localized string.
|
||||||
|
* @param r the row.
|
||||||
|
* @return the localized string. */
|
||||||
const RString& EditMenuRowToLocalizedString( EditMenuRow r );
|
const RString& EditMenuRowToLocalizedString( EditMenuRow r );
|
||||||
|
|
||||||
/** @brief The different actions one can take on a step. */
|
/** @brief The different actions one can take on a step. */
|
||||||
@@ -38,9 +47,18 @@ enum EditMenuAction
|
|||||||
};
|
};
|
||||||
/** @brief Loop through each EditMenuAction. */
|
/** @brief Loop through each EditMenuAction. */
|
||||||
#define FOREACH_EditMenuAction( ema ) FOREACH_ENUM( EditMenuAction, ema )
|
#define FOREACH_EditMenuAction( ema ) FOREACH_ENUM( EditMenuAction, ema )
|
||||||
|
/**
|
||||||
|
* @brief Turn the EditMenuAction into a string.
|
||||||
|
* @param ema the action.
|
||||||
|
* @return the string. */
|
||||||
const RString& EditMenuActionToString( EditMenuAction ema );
|
const RString& EditMenuActionToString( EditMenuAction ema );
|
||||||
|
/**
|
||||||
|
* @brief Turn the EditMenuAction into a localized string.
|
||||||
|
* @param ema the action.
|
||||||
|
* @return the localized string. */
|
||||||
const RString& EditMenuActionToLocalizedString( EditMenuAction ema );
|
const RString& EditMenuActionToLocalizedString( EditMenuAction ema );
|
||||||
|
|
||||||
|
/** @brief How many arrows are used for the EditMenu? */
|
||||||
const int NUM_ARROWS = 2;
|
const int NUM_ARROWS = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,39 +68,110 @@ const int NUM_ARROWS = 2;
|
|||||||
class EditMenu: public ActorFrame
|
class EditMenu: public ActorFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/** @brief Set up the EditMenu. */
|
||||||
EditMenu();
|
EditMenu();
|
||||||
|
/** @brief Destroy the EditMenu. */
|
||||||
~EditMenu();
|
~EditMenu();
|
||||||
void Load( const RString &sType );
|
void Load( const RString &sType );
|
||||||
|
|
||||||
|
/** @brief Determine if we can move up.
|
||||||
|
* @return true if we can, false otherwise. */
|
||||||
bool CanGoUp();
|
bool CanGoUp();
|
||||||
|
/** @brief Determine if we can move down.
|
||||||
|
* @return true if we can, false otherwise. */
|
||||||
bool CanGoDown();
|
bool CanGoDown();
|
||||||
|
/** @brief Determine if we can move left.
|
||||||
|
* @return true if we can, false otherwise. */
|
||||||
bool CanGoLeft();
|
bool CanGoLeft();
|
||||||
|
/** @brief Determine if we can move right.
|
||||||
|
* @return true if we can, false otherwise. */
|
||||||
bool CanGoRight();
|
bool CanGoRight();
|
||||||
|
/** @brief Determine if the EditMenuRow is selectable.
|
||||||
|
* @param row the row in question.
|
||||||
|
* @return true if it can be selected, false otherwise. */
|
||||||
bool RowIsSelectable( EditMenuRow row );
|
bool RowIsSelectable( EditMenuRow row );
|
||||||
|
|
||||||
|
/** @brief Move up to the next selection. */
|
||||||
void Up();
|
void Up();
|
||||||
|
/** @brief Move down to the next selection. */
|
||||||
void Down();
|
void Down();
|
||||||
|
/** @brief Move left to the next selection. */
|
||||||
void Left();
|
void Left();
|
||||||
|
/** @brief Move right to the next selection. */
|
||||||
void Right();
|
void Right();
|
||||||
|
|
||||||
void RefreshAll();
|
void RefreshAll();
|
||||||
|
|
||||||
|
/** @brief Retrieve the currently selected group.
|
||||||
|
* @return the current group. */
|
||||||
RString GetSelectedGroup() const
|
RString GetSelectedGroup() const
|
||||||
{
|
{
|
||||||
if( !SHOW_GROUPS.GetValue() ) return GROUP_ALL;
|
if( !SHOW_GROUPS.GetValue() ) return GROUP_ALL;
|
||||||
ASSERT_M((int)m_iSelection[ROW_GROUP] < (int)m_sGroups.size(),
|
int groups = static_cast<int>(m_sGroups.size());
|
||||||
ssprintf("Group selection %d < Number of groups %d", m_iSelection[ROW_GROUP], (int)m_sGroups.size()));
|
ASSERT_M(m_iSelection[ROW_GROUP] < groups,
|
||||||
|
ssprintf("Group selection %d < Number of groups %d",
|
||||||
|
m_iSelection[ROW_GROUP],
|
||||||
|
groups));
|
||||||
return m_sGroups[m_iSelection[ROW_GROUP]];
|
return m_sGroups[m_iSelection[ROW_GROUP]];
|
||||||
}
|
}
|
||||||
Song* GetSelectedSong() const { ASSERT(m_iSelection[ROW_SONG] < (int)m_pSongs.size()); return m_pSongs[m_iSelection[ROW_SONG]]; }
|
/** @brief Retrieve the currently selected song.
|
||||||
StepsType GetSelectedStepsType() const { ASSERT(m_iSelection[ROW_STEPS_TYPE] < (int)m_StepsTypes.size()); return m_StepsTypes[m_iSelection[ROW_STEPS_TYPE]]; }
|
* @return the current song. */
|
||||||
Steps* GetSelectedSteps() const { ASSERT(m_iSelection[ROW_STEPS] < (int)m_vpSteps.size()); return m_vpSteps[m_iSelection[ROW_STEPS]].pSteps; }
|
Song* GetSelectedSong() const
|
||||||
Difficulty GetSelectedDifficulty() const { ASSERT(m_iSelection[ROW_STEPS] < (int)m_vpSteps.size()); return m_vpSteps[m_iSelection[ROW_STEPS]].dc; }
|
{
|
||||||
StepsType GetSelectedSourceStepsType() const { ASSERT(m_iSelection[ROW_SOURCE_STEPS_TYPE] < (int)m_StepsTypes.size()); return m_StepsTypes[m_iSelection[ROW_SOURCE_STEPS_TYPE]]; }
|
ASSERT(m_iSelection[ROW_SONG] < (int)m_pSongs.size());
|
||||||
Steps* GetSelectedSourceSteps() const { ASSERT(m_iSelection[ROW_SOURCE_STEPS] < (int)m_vpSourceSteps.size()); return m_vpSourceSteps[m_iSelection[ROW_SOURCE_STEPS]].pSteps; }
|
return m_pSongs[m_iSelection[ROW_SONG]];
|
||||||
Difficulty GetSelectedSourceDifficulty() const { ASSERT(m_iSelection[ROW_SOURCE_STEPS] < (int)m_vpSourceSteps.size()); return m_vpSourceSteps[m_iSelection[ROW_SOURCE_STEPS]].dc; }
|
}
|
||||||
EditMenuAction GetSelectedAction() const { ASSERT(m_iSelection[ROW_ACTION] < (int)m_Actions.size()); return m_Actions[m_iSelection[ROW_ACTION]]; }
|
/** @brief Retrieve the currently selected steps type.
|
||||||
|
* @return the current steps type. */
|
||||||
|
StepsType GetSelectedStepsType() const
|
||||||
|
{
|
||||||
|
ASSERT(m_iSelection[ROW_STEPS_TYPE] < (int)m_StepsTypes.size());
|
||||||
|
return m_StepsTypes[m_iSelection[ROW_STEPS_TYPE]];
|
||||||
|
}
|
||||||
|
/** @brief Retrieve the currently selected steps.
|
||||||
|
* @return the current steps. */
|
||||||
|
Steps* GetSelectedSteps() const
|
||||||
|
{
|
||||||
|
ASSERT(m_iSelection[ROW_STEPS] < (int)m_vpSteps.size());
|
||||||
|
return m_vpSteps[m_iSelection[ROW_STEPS]].pSteps;
|
||||||
|
}
|
||||||
|
/** @brief Retrieve the currently selected difficulty.
|
||||||
|
* @return the current difficulty. */
|
||||||
|
Difficulty GetSelectedDifficulty() const
|
||||||
|
{
|
||||||
|
ASSERT(m_iSelection[ROW_STEPS] < (int)m_vpSteps.size());
|
||||||
|
return m_vpSteps[m_iSelection[ROW_STEPS]].dc;
|
||||||
|
}
|
||||||
|
/** @brief Retrieve the currently selected source steps type.
|
||||||
|
* @return the current source steps type. */
|
||||||
|
StepsType GetSelectedSourceStepsType() const
|
||||||
|
{
|
||||||
|
ASSERT(m_iSelection[ROW_SOURCE_STEPS_TYPE] < (int)m_StepsTypes.size());
|
||||||
|
return m_StepsTypes[m_iSelection[ROW_SOURCE_STEPS_TYPE]];
|
||||||
|
}
|
||||||
|
/** @brief Retrieve the currently selected source steps.
|
||||||
|
* @return the current source steps. */
|
||||||
|
Steps* GetSelectedSourceSteps() const
|
||||||
|
{
|
||||||
|
ASSERT(m_iSelection[ROW_SOURCE_STEPS] < (int)m_vpSourceSteps.size());
|
||||||
|
return m_vpSourceSteps[m_iSelection[ROW_SOURCE_STEPS]].pSteps;
|
||||||
|
}
|
||||||
|
/** @brief Retrieve the currently selected difficulty.
|
||||||
|
* @return the current difficulty. */
|
||||||
|
Difficulty GetSelectedSourceDifficulty() const
|
||||||
|
{
|
||||||
|
ASSERT(m_iSelection[ROW_SOURCE_STEPS] < (int)m_vpSourceSteps.size());
|
||||||
|
return m_vpSourceSteps[m_iSelection[ROW_SOURCE_STEPS]].dc;
|
||||||
|
}
|
||||||
|
/** @brief Retrieve the currently selected action.
|
||||||
|
* @return the current action. */
|
||||||
|
EditMenuAction GetSelectedAction() const
|
||||||
|
{
|
||||||
|
ASSERT(m_iSelection[ROW_ACTION] < (int)m_Actions.size());
|
||||||
|
return m_Actions[m_iSelection[ROW_ACTION]];
|
||||||
|
}
|
||||||
|
/** @brief Retrieve the currently selected row.
|
||||||
|
* @return the current row. */
|
||||||
EditMenuRow GetSelectedRow() const { return m_SelectedRow; }
|
EditMenuRow GetSelectedRow() const { return m_SelectedRow; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
+35
-5
@@ -15,7 +15,12 @@ extern "C"
|
|||||||
/** @brief A general foreach loop for enumerators. */
|
/** @brief A general foreach loop for enumerators. */
|
||||||
#define FOREACH_ENUM( e, var ) for( e var=(e)0; var<NUM_##e; enum_add<e>( var, +1 ) )
|
#define FOREACH_ENUM( e, var ) for( e var=(e)0; var<NUM_##e; enum_add<e>( var, +1 ) )
|
||||||
|
|
||||||
int CheckEnum( lua_State *L, LuaReference &table, int iPos, int iInvalid, const char *szType, bool bAllowInvalid );
|
int CheckEnum(lua_State *L,
|
||||||
|
LuaReference &table,
|
||||||
|
int iPos,
|
||||||
|
int iInvalid,
|
||||||
|
const char *szType,
|
||||||
|
bool bAllowInvalid);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct EnumTraits
|
struct EnumTraits
|
||||||
@@ -33,7 +38,12 @@ namespace Enum
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
static T Check( lua_State *L, int iPos, bool bAllowInvalid = false )
|
static T Check( lua_State *L, int iPos, bool bAllowInvalid = false )
|
||||||
{
|
{
|
||||||
return (T) CheckEnum( L, EnumTraits<T>::StringToEnum, iPos, EnumTraits<T>::Invalid, EnumTraits<T>::szName, bAllowInvalid );
|
return (T) CheckEnum(L,
|
||||||
|
EnumTraits<T>::StringToEnum,
|
||||||
|
iPos,
|
||||||
|
EnumTraits<T>::Invalid,
|
||||||
|
EnumTraits<T>::szName,
|
||||||
|
bAllowInvalid);
|
||||||
}
|
}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void Push( lua_State *L, T iVal )
|
static void Push( lua_State *L, T iVal )
|
||||||
@@ -90,7 +100,14 @@ const RString &EnumToString( int iVal, int iMax, const char **szNameArray, auto_
|
|||||||
return (X)i; \
|
return (X)i; \
|
||||||
return X##_Invalid; \
|
return X##_Invalid; \
|
||||||
} \
|
} \
|
||||||
namespace StringConversion { template<> bool FromString<X>( const RString &sValue, X &out ) { out = StringTo##X(sValue); return out != X##_Invalid; } }
|
namespace StringConversion \
|
||||||
|
{ \
|
||||||
|
template<> bool FromString<X>( const RString &sValue, X &out ) \
|
||||||
|
{ \
|
||||||
|
out = StringTo##X(sValue); \
|
||||||
|
return out != X##_Invalid; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
// currently unused
|
// currently unused
|
||||||
#define LuaDeclareType(X)
|
#define LuaDeclareType(X)
|
||||||
@@ -126,8 +143,21 @@ static void Lua##X(lua_State* L) \
|
|||||||
REGISTER_WITH_LUA_FUNCTION( Lua##X ); \
|
REGISTER_WITH_LUA_FUNCTION( Lua##X ); \
|
||||||
template<> X EnumTraits<X>::Invalid = X##_Invalid; \
|
template<> X EnumTraits<X>::Invalid = X##_Invalid; \
|
||||||
template<> const char *EnumTraits<X>::szName = #X; \
|
template<> const char *EnumTraits<X>::szName = #X; \
|
||||||
namespace LuaHelpers { template<> bool FromStack<X>( lua_State *L, X &Object, int iOffset ) { Object = Enum::Check<X>( L, iOffset, true ); return Object != EnumTraits<X>::Invalid; } } \
|
namespace LuaHelpers \
|
||||||
namespace LuaHelpers { template<> void Push<X>( lua_State *L, const X &Object ) { Enum::Push<X>( L, Object ); } }
|
{ \
|
||||||
|
template<> bool FromStack<X>( lua_State *L, X &Object, int iOffset ) \
|
||||||
|
{ \
|
||||||
|
Object = Enum::Check<X>( L, iOffset, true ); \
|
||||||
|
return Object != EnumTraits<X>::Invalid; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
namespace LuaHelpers \
|
||||||
|
{ \
|
||||||
|
template<> void Push<X>( lua_State *L, const X &Object ) \
|
||||||
|
{ \
|
||||||
|
Enum::Push<X>( L, Object ); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ void LifeMeterBattery::ChangeLife( TapNoteScore score )
|
|||||||
SubtractLives(MINES_SUBTRACT_LIVES);
|
SubtractLives(MINES_SUBTRACT_LIVES);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( score < MIN_SCORE_TO_KEEP_LIFE && SUBTRACT_LIVES > 0 )
|
if( score < MIN_SCORE_TO_KEEP_LIFE && score > TNS_CheckpointMiss && SUBTRACT_LIVES > 0 )
|
||||||
SubtractLives(SUBTRACT_LIVES);
|
SubtractLives(SUBTRACT_LIVES);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,6 +175,12 @@ void LifeMeterBattery::ChangeLife( HoldNoteScore score, TapNoteScore tscore )
|
|||||||
AddLives(HELD_ADD_LIVES);
|
AddLives(HELD_ADD_LIVES);
|
||||||
if( score == HNS_LetGo && LET_GO_SUBTRACT_LIVES > 0 )
|
if( score == HNS_LetGo && LET_GO_SUBTRACT_LIVES > 0 )
|
||||||
SubtractLives(LET_GO_SUBTRACT_LIVES);
|
SubtractLives(LET_GO_SUBTRACT_LIVES);
|
||||||
|
|
||||||
|
Message msg( "LifeChanged" );
|
||||||
|
msg.SetParam( "Player", m_pPlayerState->m_PlayerNumber );
|
||||||
|
msg.SetParam( "LifeMeter", LuaReference::CreateFromPush(*this) );
|
||||||
|
msg.SetParam( "LivesLeft", GetLivesLeft() );
|
||||||
|
MESSAGEMAN->Broadcast( msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
void LifeMeterBattery::HandleTapScoreNone()
|
void LifeMeterBattery::HandleTapScoreNone()
|
||||||
|
|||||||
@@ -803,6 +803,7 @@ RadarStats CalculateRadarStatsFast( const NoteData &in, RadarStats &out )
|
|||||||
case TapNote::mine:
|
case TapNote::mine:
|
||||||
case TapNote::empty:
|
case TapNote::empty:
|
||||||
case TapNote::fake:
|
case TapNote::fake:
|
||||||
|
case TapNote::autoKeysound:
|
||||||
continue; // skip these types - they don't count
|
continue; // skip these types - they don't count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-2
@@ -696,6 +696,8 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
|
|||||||
}
|
}
|
||||||
|
|
||||||
NameToData_t::const_iterator it;
|
NameToData_t::const_iterator it;
|
||||||
|
|
||||||
|
bool hasBGM = false;
|
||||||
for( it = mapNameToData.lower_bound("#00000"); it != mapNameToData.end(); ++it )
|
for( it = mapNameToData.lower_bound("#00000"); it != mapNameToData.end(); ++it )
|
||||||
{
|
{
|
||||||
const RString &sName = it->first;
|
const RString &sName = it->first;
|
||||||
@@ -745,6 +747,7 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
|
|||||||
{
|
{
|
||||||
if( bmsTrack == BMS_AUTO_KEYSOUND_1 )
|
if( bmsTrack == BMS_AUTO_KEYSOUND_1 )
|
||||||
{
|
{
|
||||||
|
hasBGM = true;
|
||||||
// shift the auto keysound as far right as possible
|
// shift the auto keysound as far right as possible
|
||||||
int iLastEmptyTrack = -1;
|
int iLastEmptyTrack = -1;
|
||||||
if( ndNotes.GetTapLastEmptyTrack(row, iLastEmptyTrack) &&
|
if( ndNotes.GetTapLastEmptyTrack(row, iLastEmptyTrack) &&
|
||||||
@@ -772,6 +775,12 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!hasBGM)
|
||||||
|
{
|
||||||
|
LOG->Warn("The song at %s is missing a #XXX01 tag! We're unable to load.", sPath.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Handles hold notes like uBMPlay.
|
/* Handles hold notes like uBMPlay.
|
||||||
* Different BMS simulators support hold notes differently.
|
* Different BMS simulators support hold notes differently.
|
||||||
* See http://nvyu.net/rdm/ex.php for more info.
|
* See http://nvyu.net/rdm/ex.php for more info.
|
||||||
@@ -964,7 +973,7 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
|
|||||||
iTransformNewToOld[15] = BMS_P2_TURN;
|
iTransformNewToOld[15] = BMS_P2_TURN;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT(0);
|
ASSERT_M(0, ssprintf("Invalid StepsType when parsing BMS file %s!", sPath.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// shift all of the autokeysound tracks onto the main tracks
|
// shift all of the autokeysound tracks onto the main tracks
|
||||||
@@ -990,7 +999,7 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG->UserLog( "Song file", sPath, "has too much simultenous autokeysound tracks." );
|
LOG->UserLog( "Song file", sPath, "has too much simultaneous autokeysound tracks." );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+122
-83
@@ -20,66 +20,6 @@ static void HandleBunki( TimingData &timing, const float fEarlyBPM,
|
|||||||
timing.AddBPMSegment( BPMSegment(BeatToNoteRow(beat), fCurBPM) );
|
timing.AddBPMSegment( BPMSegment(BeatToNoteRow(beat), fCurBPM) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool HandlePipeChars( TimingData &timing, const RString sNoteRow,
|
|
||||||
const float fCurBeat, int &iTickCount )
|
|
||||||
{
|
|
||||||
// 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
|
|
||||||
// segment will then be added based on approximations.
|
|
||||||
|
|
||||||
RString temp = sNoteRow.substr(2,sNoteRow.size()-3);
|
|
||||||
float numTemp = StringToFloat(temp);
|
|
||||||
if (BeginsWith(sNoteRow, "|T"))
|
|
||||||
{
|
|
||||||
iTickCount = static_cast<int>(numTemp);
|
|
||||||
timing.SetTickcountAtBeat( fCurBeat, clamp(iTickCount, 0, ROWS_PER_BEAT) );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (BeginsWith(sNoteRow, "|B"))
|
|
||||||
{
|
|
||||||
timing.SetBPMAtBeat( fCurBeat, numTemp );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (BeginsWith(sNoteRow, "|E"))
|
|
||||||
{
|
|
||||||
// Finally! the |E| tag is working as it should. I can die happy now -DaisuMaster
|
|
||||||
float fCurDelay = 60 / timing.GetBPMAtBeat(fCurBeat) * numTemp / iTickCount;
|
|
||||||
fCurDelay += timing.GetDelayAtRow(BeatToNoteRow(fCurBeat) );
|
|
||||||
timing.SetStopAtBeat( fCurBeat, fCurDelay, true );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (BeginsWith(sNoteRow, "|D"))
|
|
||||||
{
|
|
||||||
float fCurDelay = timing.GetStopAtRow(BeatToNoteRow(fCurBeat) );
|
|
||||||
fCurDelay += numTemp / 1000;
|
|
||||||
timing.SetStopAtBeat( fCurBeat, fCurDelay, true );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (BeginsWith(sNoteRow, "|M") || BeginsWith(sNoteRow, "|C"))
|
|
||||||
{
|
|
||||||
// multipliers/combo
|
|
||||||
timing.SetComboAtBeat( fCurBeat, static_cast<int>(numTemp) );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (BeginsWith(sNoteRow, "|S"))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (BeginsWith(sNoteRow, "|F"))
|
|
||||||
{
|
|
||||||
//
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (BeginsWith(sNoteRow, "|X"))
|
|
||||||
{
|
|
||||||
timing.SetScrollAtBeat( fCurBeat, numTemp );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song, bool bKIUCompliant )
|
static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song, bool bKIUCompliant )
|
||||||
{
|
{
|
||||||
LOG->Trace( "Steps::LoadFromKSFFile( '%s' )", sPath.c_str() );
|
LOG->Trace( "Steps::LoadFromKSFFile( '%s' )", sPath.c_str() );
|
||||||
@@ -91,7 +31,10 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int iTickCount = -1; // this is the value we read for TICKCOUNT
|
// this is the value we read for TICKCOUNT
|
||||||
|
int iTickCount = -1;
|
||||||
|
// used to adapt weird tickcounts
|
||||||
|
float fScrollRatio = 1.0f;
|
||||||
vector<RString> vNoteRows;
|
vector<RString> vNoteRows;
|
||||||
|
|
||||||
// According to Aldo_MX, there is a default BPM and it's 60. -aj
|
// According to Aldo_MX, there is a default BPM and it's 60. -aj
|
||||||
@@ -350,21 +293,109 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, const Song &song,
|
|||||||
// Log an error, ignore the line.
|
// Log an error, ignore the line.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !HandlePipeChars( stepsTiming, sRowString, fCurBeat, iTickCount ) )
|
// 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
|
||||||
|
// segment will then be added based on approximations. -DaisuMaster
|
||||||
|
// eh better do it considering the tickcount (high tickcounts)
|
||||||
|
|
||||||
|
// I'm making some experiments, please spare me...
|
||||||
|
|
||||||
|
RString temp = sRowString.substr(2,sRowString.size()-3);
|
||||||
|
float numTemp = StringToFloat(temp);
|
||||||
|
if (BeginsWith(sRowString, "|T"))
|
||||||
{
|
{
|
||||||
// LOG it first.
|
// 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;
|
||||||
|
}
|
||||||
|
//*/
|
||||||
|
|
||||||
|
stepsTiming.SetTickcountAtBeat( fCurBeat, clamp(iTickCount, 0, ROWS_PER_BEAT) );
|
||||||
|
}
|
||||||
|
else if (BeginsWith(sRowString, "|B"))
|
||||||
|
{
|
||||||
|
// BPM
|
||||||
|
stepsTiming.SetBPMAtBeat( fCurBeat, numTemp );
|
||||||
|
}
|
||||||
|
else if (BeginsWith(sRowString, "|E"))
|
||||||
|
{
|
||||||
|
// DelayBeat
|
||||||
|
float fCurDelay = 60 / stepsTiming.GetBPMAtBeat(fCurBeat) * numTemp / iTickCount;
|
||||||
|
fCurDelay += stepsTiming.GetDelayAtRow(BeatToNoteRow(fCurBeat) );
|
||||||
|
stepsTiming.SetStopAtBeat( fCurBeat, fCurDelay, true );
|
||||||
|
}
|
||||||
|
else if (BeginsWith(sRowString, "|D"))
|
||||||
|
{
|
||||||
|
// Delays
|
||||||
|
float fCurDelay = stepsTiming.GetStopAtRow(BeatToNoteRow(fCurBeat) );
|
||||||
|
fCurDelay += numTemp / 1000;
|
||||||
|
stepsTiming.SetStopAtBeat( fCurBeat, fCurDelay, true );
|
||||||
|
}
|
||||||
|
else if (BeginsWith(sRowString, "|M") || BeginsWith(sRowString, "|C"))
|
||||||
|
{
|
||||||
|
// multipliers/combo
|
||||||
|
stepsTiming.SetComboAtBeat( fCurBeat, static_cast<int>(numTemp) );
|
||||||
|
}
|
||||||
|
else if (BeginsWith(sRowString, "|S"))
|
||||||
|
{
|
||||||
|
// speed segments
|
||||||
|
}
|
||||||
|
else if (BeginsWith(sRowString, "|F"))
|
||||||
|
{
|
||||||
|
// fakes
|
||||||
|
}
|
||||||
|
else if (BeginsWith(sRowString, "|X"))
|
||||||
|
{
|
||||||
|
// scroll segments
|
||||||
|
stepsTiming.SetScrollAtBeat( fCurBeat, numTemp );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Is this why improper ksf or some kiucompilant ksf mixed with dm05 ksf are ignored?? -DaisuMaster
|
|
||||||
//LOG->UserLog( "Song file", sPath, "has a RowString with an improper length \"%s\"; corrupt notes ignored.",
|
|
||||||
// sRowString.c_str() );
|
|
||||||
//return false;
|
|
||||||
//continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Half-doubles is offset; "0011111100000".
|
// Half-doubles is offset; "0011111100000".
|
||||||
@@ -485,7 +516,7 @@ static void LoadTags( const RString &str, Song &out )
|
|||||||
out.m_sArtist = artist;
|
out.m_sArtist = artist;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant )
|
static bool LoadGlobalData( const RString &sPath, Song &out, bool bKIUCompliant )
|
||||||
{
|
{
|
||||||
MsdFile msd;
|
MsdFile msd;
|
||||||
if( !msd.ReadFile( sPath, false ) ) // don't unescape
|
if( !msd.ReadFile( sPath, false ) ) // don't unescape
|
||||||
@@ -658,14 +689,11 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This is where the DMRequired test will take place.
|
// This is where the DMRequired test will take place.
|
||||||
if (BeginsWith(NoteRowString, "|T") || BeginsWith(NoteRowString, "|B") ||
|
//if (BeginsWith(NoteRowString, "|T") || BeginsWith(NoteRowString, "|B") || BeginsWith(NoteRowString, "|D") || BeginsWith(NoteRowString, "|E") )
|
||||||
BeginsWith(NoteRowString, "|D") || BeginsWith(NoteRowString, "|E") )
|
if ( BeginsWith( NoteRowString, "|" ) )
|
||||||
{
|
{
|
||||||
|
// have a static timing for everything
|
||||||
bDMRequired = true;
|
bDMRequired = true;
|
||||||
if ( !HandlePipeChars( out.m_SongTiming, NoteRowString, fCurBeat, iTickCount ) )
|
|
||||||
{
|
|
||||||
// LOG it first.
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -705,21 +733,32 @@ bool KSFLoader::LoadFromDir( const RString &sDir, Song &out )
|
|||||||
// We shouldn't have been called to begin with if there were no KSFs.
|
// We shouldn't have been called to begin with if there were no KSFs.
|
||||||
ASSERT( arrayKSFFileNames.size() );
|
ASSERT( arrayKSFFileNames.size() );
|
||||||
|
|
||||||
bool bKIUCompliant = false;
|
//bool bKIUCompliant = false;
|
||||||
/* With Split Timing, there has to be a backup Song Timing in case
|
/* With Split Timing, there has to be a backup Song Timing in case
|
||||||
* anything goes wrong. As these files are kept in alphabetical
|
* anything goes wrong. As these files are kept in alphabetical
|
||||||
* order (hopefully), it is best to use the LAST file for timing
|
* order (hopefully), it is best to use the LAST file for timing
|
||||||
* purposes, for that is the "normal", or easiest difficulty.
|
* purposes, for that is the "normal", or easiest difficulty.
|
||||||
* Usually. */
|
* Usually. */
|
||||||
|
// Nevermind, kiu compilancy is screwing things up:
|
||||||
|
// IE, I have two simfiles, oh wich each have four ksf files, the first one has
|
||||||
|
// the first ksf with directmove timing changes, and the rest are not, everything
|
||||||
|
// goes fine. In the other hand I have my second simfile with the first ksf file
|
||||||
|
// without directmove timing changes and the rest have changes, changes are not
|
||||||
|
// loaded due to kiucompilancy in the first ksf file.
|
||||||
|
// About the "normal" thing, my simfiles' ksfs uses non-standard naming so
|
||||||
|
// the last chart is usually nightmare or normal, I use easy and normal
|
||||||
|
// indistinctly for SM so it shouldn't matter, I use piu fiesta/ex naming
|
||||||
|
// 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();
|
unsigned files = arrayKSFFileNames.size();
|
||||||
if( !LoadGlobalData(out.GetSongDir() + arrayKSFFileNames[files - 1], out, bKIUCompliant) )
|
if( !LoadGlobalData(out.GetSongDir() + arrayKSFFileNames[0], out, false) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// load the Steps from the rest of the KSF files
|
// load the Steps from the rest of the KSF files
|
||||||
for( unsigned i=0; i<files; i++ )
|
for( unsigned i=0; i<files; i++ )
|
||||||
{
|
{
|
||||||
Steps* pNewNotes = out.CreateSteps();
|
Steps* pNewNotes = out.CreateSteps();
|
||||||
if( !LoadFromKSFFile(out.GetSongDir() + arrayKSFFileNames[i], *pNewNotes, out, bKIUCompliant) )
|
if( !LoadFromKSFFile(out.GetSongDir() + arrayKSFFileNames[i], *pNewNotes, out, false) )
|
||||||
{
|
{
|
||||||
delete pNewNotes;
|
delete pNewNotes;
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -731,6 +731,42 @@ int RageFileManager::GetFileHash( const RString &sPath_ )
|
|||||||
return iRet;
|
return iRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RString RageFileManager::ResolvePath(const RString &path)
|
||||||
|
{
|
||||||
|
RString tmpPath = path;
|
||||||
|
NormalizePath(tmpPath);
|
||||||
|
|
||||||
|
RString resolvedPath = tmpPath;
|
||||||
|
|
||||||
|
vector<LoadedDriver *> apDriverList;
|
||||||
|
ReferenceAllDrivers( apDriverList );
|
||||||
|
|
||||||
|
for( unsigned i = 0; i < apDriverList.size(); ++i )
|
||||||
|
{
|
||||||
|
LoadedDriver *pDriver = apDriverList[i];
|
||||||
|
const RString driverPath = pDriver->GetPath( tmpPath );
|
||||||
|
|
||||||
|
if ( driverPath.empty() || pDriver->m_sRoot.empty() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( pDriver->m_sType != "dir" && pDriver->m_sType != "dirro" )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int iMountPointLen = pDriver->m_sMountPoint.length();
|
||||||
|
if( tmpPath.substr(0, iMountPointLen) != pDriver->m_sMountPoint )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
resolvedPath = pDriver->m_sRoot + "/" + RString(tmpPath.substr(iMountPointLen));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnreferenceAllDrivers( apDriverList );
|
||||||
|
|
||||||
|
NormalizePath( resolvedPath );
|
||||||
|
|
||||||
|
return resolvedPath;
|
||||||
|
}
|
||||||
|
|
||||||
static bool SortBySecond( const pair<int,int> &a, const pair<int,int> &b )
|
static bool SortBySecond( const pair<int,int> &a, const pair<int,int> &b )
|
||||||
{
|
{
|
||||||
return a.second < b.second;
|
return a.second < b.second;
|
||||||
|
|||||||
@@ -38,6 +38,12 @@ public:
|
|||||||
int GetFileSizeInBytes( const RString &sPath );
|
int GetFileSizeInBytes( const RString &sPath );
|
||||||
int GetFileHash( const RString &sPath );
|
int GetFileHash( const RString &sPath );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the absolte path from the VPS.
|
||||||
|
* @param path the VPS path.
|
||||||
|
* @return the absolute path. */
|
||||||
|
RString ResolvePath(const RString &path);
|
||||||
|
|
||||||
bool Mount( const RString &sType, const RString &sRealPath, const RString &sMountPoint, bool bAddToEnd = true );
|
bool Mount( const RString &sType, const RString &sRealPath, const RString &sMountPoint, bool bAddToEnd = true );
|
||||||
void Mount( RageFileDriver *pDriver, const RString &sMountPoint, bool bAddToEnd = true );
|
void Mount( RageFileDriver *pDriver, const RString &sMountPoint, bool bAddToEnd = true );
|
||||||
void Unmount( const RString &sType, const RString &sRoot, const RString &sMountPoint );
|
void Unmount( const RString &sType, const RString &sRoot, const RString &sMountPoint );
|
||||||
|
|||||||
+4
-2
@@ -41,7 +41,7 @@
|
|||||||
* @brief The internal version of the cache for StepMania.
|
* @brief The internal version of the cache for StepMania.
|
||||||
*
|
*
|
||||||
* Increment this value to invalidate the current cache. */
|
* Increment this value to invalidate the current cache. */
|
||||||
const int FILE_CACHE_VERSION = 180;
|
const int FILE_CACHE_VERSION = 182;
|
||||||
|
|
||||||
/** @brief How long does a song sample last by default? */
|
/** @brief How long does a song sample last by default? */
|
||||||
const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f;
|
const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f;
|
||||||
@@ -190,7 +190,9 @@ RString Song::GetCacheFilePath() const
|
|||||||
// Get a path to the SM containing data for this song. It might be a cache file.
|
// Get a path to the SM containing data for this song. It might be a cache file.
|
||||||
const RString &Song::GetSongFilePath() const
|
const RString &Song::GetSongFilePath() const
|
||||||
{
|
{
|
||||||
ASSERT( !m_sSongFileName.empty() );
|
ASSERT_M( !m_sSongFileName.empty(),
|
||||||
|
ssprintf("The song %s has no filename associated with it!",
|
||||||
|
this->m_sMainTitle.c_str()));
|
||||||
return m_sSongFileName;
|
return m_sSongFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -999,6 +999,8 @@ void SongManager::Cleanup()
|
|||||||
for( unsigned i=0; i<m_pSongs.size(); i++ )
|
for( unsigned i=0; i<m_pSongs.size(); i++ )
|
||||||
{
|
{
|
||||||
Song* pSong = m_pSongs[i];
|
Song* pSong = m_pSongs[i];
|
||||||
|
if (pSong)
|
||||||
|
{
|
||||||
const vector<Steps*>& vpSteps = pSong->GetAllSteps();
|
const vector<Steps*>& vpSteps = pSong->GetAllSteps();
|
||||||
for( unsigned n=0; n<vpSteps.size(); n++ )
|
for( unsigned n=0; n<vpSteps.size(); n++ )
|
||||||
{
|
{
|
||||||
@@ -1007,6 +1009,7 @@ void SongManager::Cleanup()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Flush all Song*, Steps* and Course* caches. This is when a Song or its Steps
|
/* Flush all Song*, Steps* and Course* caches. This is when a Song or its Steps
|
||||||
* are removed or changed. This doesn't touch GAMESTATE and StageStats
|
* are removed or changed. This doesn't touch GAMESTATE and StageStats
|
||||||
|
|||||||
@@ -1670,6 +1670,93 @@ public:
|
|||||||
static int HasFakes( T* p, lua_State *L ) { lua_pushboolean(L, p->HasFakes()); return 1; }
|
static int HasFakes( T* p, lua_State *L ) { lua_pushboolean(L, p->HasFakes()); return 1; }
|
||||||
static int HasSpeedChanges( T* p, lua_State *L ) { lua_pushboolean(L, p->HasSpeedChanges()); return 1; }
|
static int HasSpeedChanges( T* p, lua_State *L ) { lua_pushboolean(L, p->HasSpeedChanges()); return 1; }
|
||||||
static int HasScrollChanges( T* p, lua_State *L ) { lua_pushboolean(L, p->HasScrollChanges()); return 1; }
|
static int HasScrollChanges( T* p, lua_State *L ) { lua_pushboolean(L, p->HasScrollChanges()); return 1; }
|
||||||
|
static int GetWarps( T* p, lua_State *L )
|
||||||
|
{
|
||||||
|
vector<RString> vWarps;
|
||||||
|
FOREACH_CONST( WarpSegment, p->m_WarpSegments, seg )
|
||||||
|
{
|
||||||
|
const float length = seg->GetLength();
|
||||||
|
const float beat = seg->GetBeat();
|
||||||
|
vWarps.push_back( ssprintf("%f=%f", beat, length) );
|
||||||
|
}
|
||||||
|
LuaHelpers::CreateTableFromArray(vWarps, L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
static int GetFakes( T* p, lua_State *L )
|
||||||
|
{
|
||||||
|
vector<RString> vFakes;
|
||||||
|
FOREACH_CONST( FakeSegment, p->m_FakeSegments, seg )
|
||||||
|
{
|
||||||
|
const float length = seg->GetLength();
|
||||||
|
const float beat = seg->GetBeat();
|
||||||
|
vFakes.push_back( ssprintf("%f=%f", beat, length) );
|
||||||
|
}
|
||||||
|
LuaHelpers::CreateTableFromArray(vFakes, L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
static int GetScrolls( T* p, lua_State *L )
|
||||||
|
{
|
||||||
|
vector<RString> vScrolls;
|
||||||
|
FOREACH_CONST( ScrollSegment, p->m_ScrollSegments, seg )
|
||||||
|
{
|
||||||
|
const float ratio = seg->GetRatio();
|
||||||
|
const float beat = seg->GetBeat();
|
||||||
|
vScrolls.push_back( ssprintf("%f=%f", beat, ratio) );
|
||||||
|
}
|
||||||
|
LuaHelpers::CreateTableFromArray(vScrolls, L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
static int GetSpeeds( T* p, lua_State *L )
|
||||||
|
{
|
||||||
|
vector<RString> vSpeeds;
|
||||||
|
FOREACH_CONST( SpeedSegment, p->m_SpeedSegments, seg )
|
||||||
|
{
|
||||||
|
const float length = seg->GetLength();
|
||||||
|
const float ratio = seg->GetRatio();
|
||||||
|
const unsigned short unit = seg->GetUnit();
|
||||||
|
const float beat = seg->GetBeat();
|
||||||
|
vSpeeds.push_back( ssprintf("%f=%f=%f=%uh", beat, ratio, length, unit) );
|
||||||
|
}
|
||||||
|
LuaHelpers::CreateTableFromArray(vSpeeds, L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
static int GetTimeSignatures( T* p, lua_State *L )
|
||||||
|
{
|
||||||
|
vector<RString> vTimes;
|
||||||
|
FOREACH_CONST( TimeSignatureSegment, p->m_vTimeSignatureSegments, seg )
|
||||||
|
{
|
||||||
|
const int numerator = seg->GetNum();
|
||||||
|
const int denominator = seg->GetDen();
|
||||||
|
const float beat = seg->GetBeat();
|
||||||
|
vTimes.push_back( ssprintf("%f=%d=%d", beat, numerator, denominator) );
|
||||||
|
}
|
||||||
|
LuaHelpers::CreateTableFromArray(vTimes, L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
static int GetCombos( T* p, lua_State *L )
|
||||||
|
{
|
||||||
|
vector<RString> vCombos;
|
||||||
|
FOREACH_CONST( ComboSegment, p->m_ComboSegments, seg )
|
||||||
|
{
|
||||||
|
const int combo = seg->GetCombo();
|
||||||
|
const float beat = seg->GetBeat();
|
||||||
|
vCombos.push_back( ssprintf("%f=%d", beat, combo) );
|
||||||
|
}
|
||||||
|
LuaHelpers::CreateTableFromArray(vCombos, L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
static int GetTickcounts( T* p, lua_State *L )
|
||||||
|
{
|
||||||
|
vector<RString> vTicks;
|
||||||
|
FOREACH_CONST( TickcountSegment, p->m_TickcountSegments, seg )
|
||||||
|
{
|
||||||
|
const int ticks = seg->GetTicks();
|
||||||
|
const float beat = seg->GetBeat();
|
||||||
|
vTicks.push_back( ssprintf("%f=%d", beat, ticks) );
|
||||||
|
}
|
||||||
|
LuaHelpers::CreateTableFromArray(vTicks, L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
static int GetStops( T* p, lua_State *L )
|
static int GetStops( T* p, lua_State *L )
|
||||||
{
|
{
|
||||||
vector<RString> vStops;
|
vector<RString> vStops;
|
||||||
@@ -1763,6 +1850,13 @@ public:
|
|||||||
ADD_METHOD( GetStops );
|
ADD_METHOD( GetStops );
|
||||||
ADD_METHOD( GetDelays );
|
ADD_METHOD( GetDelays );
|
||||||
ADD_METHOD( GetBPMs );
|
ADD_METHOD( GetBPMs );
|
||||||
|
ADD_METHOD( GetWarps );
|
||||||
|
ADD_METHOD( GetFakes );
|
||||||
|
ADD_METHOD( GetTimeSignatures );
|
||||||
|
ADD_METHOD( GetTickcounts );
|
||||||
|
ADD_METHOD( GetSpeeds );
|
||||||
|
ADD_METHOD( GetScrolls );
|
||||||
|
ADD_METHOD( GetCombos );
|
||||||
ADD_METHOD( GetLabels );
|
ADD_METHOD( GetLabels );
|
||||||
ADD_METHOD( GetBPMsAndTimes );
|
ADD_METHOD( GetBPMsAndTimes );
|
||||||
ADD_METHOD( GetActualBPM );
|
ADD_METHOD( GetActualBPM );
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ void UnlockManager::GetPoints( const Profile *pProfile, float fScores[NUM_Unlock
|
|||||||
fScores[UnlockRequirement_SongPoints] = GetSongPoints( pProfile );
|
fScores[UnlockRequirement_SongPoints] = GetSongPoints( pProfile );
|
||||||
fScores[UnlockRequirement_DancePoints] = (float) pProfile->m_iTotalDancePoints;
|
fScores[UnlockRequirement_DancePoints] = (float) pProfile->m_iTotalDancePoints;
|
||||||
fScores[UnlockRequirement_StagesCleared] = (float) pProfile->GetTotalNumSongsPassed();
|
fScores[UnlockRequirement_StagesCleared] = (float) pProfile->GetTotalNumSongsPassed();
|
||||||
fScores[UnlockRequirement_NumUnlocked] = (float) GetNumUnlocked();
|
//fScores[UnlockRequirement_NumUnlocked] = (float) GetNumUnlocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if all songs and/or courses referenced by an unlock are available. */
|
/* Return true if all songs and/or courses referenced by an unlock are available. */
|
||||||
@@ -330,8 +330,13 @@ UnlockEntryStatus UnlockEntry::GetUnlockEntryStatus() const
|
|||||||
UNLOCKMAN->GetPoints( PROFILEMAN->GetMachineProfile(), fScores );
|
UNLOCKMAN->GetPoints( PROFILEMAN->GetMachineProfile(), fScores );
|
||||||
|
|
||||||
for( int i = 0; i < NUM_UnlockRequirement; ++i )
|
for( int i = 0; i < NUM_UnlockRequirement; ++i )
|
||||||
|
{
|
||||||
|
if( i == UnlockRequirement_NumUnlocked )
|
||||||
|
continue;
|
||||||
|
|
||||||
if( m_fRequirement[i] && fScores[i] >= m_fRequirement[i] )
|
if( m_fRequirement[i] && fScores[i] >= m_fRequirement[i] )
|
||||||
return UnlockEntryStatus_RequirementsMet;
|
return UnlockEntryStatus_RequirementsMet;
|
||||||
|
}
|
||||||
|
|
||||||
if( m_bRequirePassHardSteps && m_Song.IsValid() )
|
if( m_bRequirePassHardSteps && m_Song.IsValid() )
|
||||||
{
|
{
|
||||||
@@ -348,7 +353,6 @@ UnlockEntryStatus UnlockEntry::GetUnlockEntryStatus() const
|
|||||||
return UnlockEntryStatus_RequirementsMet;
|
return UnlockEntryStatus_RequirementsMet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return UnlockEntryStatus_RequrementsNotMet;
|
return UnlockEntryStatus_RequrementsNotMet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -601,7 +605,7 @@ int UnlockManager::GetNumUnlocked() const
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
FOREACH_CONST( UnlockEntry, m_UnlockEntries, ue )
|
FOREACH_CONST( UnlockEntry, m_UnlockEntries, ue )
|
||||||
{
|
{
|
||||||
if( ue->GetUnlockEntryStatus() == UnlockEntryStatus_Unlocked )
|
if( !ue->IsLocked() )
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
|
|||||||
Reference in New Issue
Block a user