Revert "Round 2-2 of this."

This reverts commit 0ae4183f7b.
This commit is contained in:
Devin J. Pohly
2013-06-04 23:47:22 -04:00
parent fa91154082
commit 1220dbe085
43 changed files with 1214 additions and 12 deletions
+261
View File
@@ -0,0 +1,261 @@
#include "global.h"
#include "Bookkeeper.h"
#include "RageUtil.h"
#include "RageLog.h"
#include "IniFile.h"
#include "GameConstantsAndTypes.h"
#include "SongManager.h"
#include "RageFile.h"
#include "XmlFile.h"
#include "XmlFileUtil.h"
#include <ctime>
Bookkeeper* BOOKKEEPER = NULL; // global and accessable from anywhere in our program
static const RString COINS_DAT = "Save/Coins.xml";
Bookkeeper::Bookkeeper()
{
ClearAll();
ReadFromDisk();
}
Bookkeeper::~Bookkeeper()
{
WriteToDisk();
}
#define WARN_AND_RETURN { LOG->Warn("Error parsing at %s:%d",__FILE__,__LINE__); return; }
void Bookkeeper::ClearAll()
{
m_mapCoinsForHour.clear();
}
bool Bookkeeper::Date::operator<( const Date &rhs ) const
{
if( m_iYear != rhs.m_iYear )
return m_iYear < rhs.m_iYear;
if( m_iDayOfYear != rhs.m_iDayOfYear )
return m_iDayOfYear < rhs.m_iDayOfYear;
return m_iHour < rhs.m_iHour;
}
void Bookkeeper::Date::Set( time_t t )
{
tm ltime;
localtime_r( &t, &ltime );
Set( ltime );
}
void Bookkeeper::Date::Set( tm pTime )
{
m_iHour = pTime.tm_hour;
m_iDayOfYear = pTime.tm_yday;
m_iYear = pTime.tm_year + 1900;
}
void Bookkeeper::LoadFromNode( const XNode *pNode )
{
if( pNode->GetName() != "Bookkeeping" )
{
LOG->Warn( "Error loading bookkeeping: unexpected \"%s\"", pNode->GetName().c_str() );
return;
}
const XNode *pData = pNode->GetChild( "Data" );
if( pData == NULL )
{
LOG->Warn( "Error loading bookkeeping: Data node missing" );
return;
}
FOREACH_CONST_Child( pData, day )
{
Date d;
if( !day->GetAttrValue( "Hour", d.m_iHour ) ||
!day->GetAttrValue( "Day", d.m_iDayOfYear ) ||
!day->GetAttrValue( "Year", d.m_iYear ) )
{
LOG->Warn( "Incomplete date field" );
continue;
}
int iCoins;
day->GetTextValue( iCoins );
m_mapCoinsForHour[d] = iCoins;
}
}
XNode* Bookkeeper::CreateNode() const
{
XNode *xml = new XNode( "Bookkeeping" );
{
XNode* pData = xml->AppendChild("Data");
for( map<Date,int>::const_iterator it = m_mapCoinsForHour.begin(); it != m_mapCoinsForHour.end(); ++it )
{
int iCoins = it->second;
XNode *pDay = pData->AppendChild( "Coins", iCoins );
const Date &d = it->first;
pDay->AppendAttr( "Hour", d.m_iHour );
pDay->AppendAttr( "Day", d.m_iDayOfYear );
pDay->AppendAttr( "Year", d.m_iYear );
}
}
return xml;
}
void Bookkeeper::ReadFromDisk()
{
if( !IsAFile(COINS_DAT) )
return;
XNode xml;
if( !XmlFileUtil::LoadFromFileShowErrors(xml, COINS_DAT) )
return;
LoadFromNode( &xml );
}
void Bookkeeper::WriteToDisk()
{
// Write data. Use SLOW_FLUSH, to help ensure that we don't lose coin data.
RageFile f;
if( !f.Open(COINS_DAT, RageFile::WRITE|RageFile::SLOW_FLUSH) )
{
LOG->Warn( "Couldn't open file \"%s\" for writing: %s", COINS_DAT.c_str(), f.GetError().c_str() );
return;
}
auto_ptr<XNode> xml( CreateNode() );
XmlFileUtil::SaveToFile( xml.get(), f );
}
void Bookkeeper::CoinInserted()
{
Date d;
d.Set( time(NULL) );
++m_mapCoinsForHour[d];
}
// Return the number of coins between [beginning,ending).
int Bookkeeper::GetNumCoinsInRange( map<Date,int>::const_iterator begin, map<Date,int>::const_iterator end ) const
{
int iCoins = 0;
while( begin != end )
{
iCoins += begin->second;
++begin;
}
return iCoins;
}
int Bookkeeper::GetNumCoins( Date beginning, Date ending ) const
{
return GetNumCoinsInRange( m_mapCoinsForHour.lower_bound( beginning ),
m_mapCoinsForHour.lower_bound( ending ) );
}
int Bookkeeper::GetCoinsTotal() const
{
return GetNumCoinsInRange( m_mapCoinsForHour.begin(), m_mapCoinsForHour.end() );
}
void Bookkeeper::GetCoinsLastDays( int coins[NUM_LAST_DAYS] ) const
{
time_t lOldTime = time(NULL);
tm time;
localtime_r( &lOldTime, &time );
time.tm_hour = 0;
for( int i=0; i<NUM_LAST_DAYS; i++ )
{
tm EndTime = AddDays( time, +1 );
coins[i] = GetNumCoins( time, EndTime );
time = GetYesterday( time );
}
}
void Bookkeeper::GetCoinsLastWeeks( int coins[NUM_LAST_WEEKS] ) const
{
time_t lOldTime = time(NULL);
tm time;
localtime_r( &lOldTime, &time );
time = GetNextSunday( time );
time = GetYesterday( time );
for( int w=0; w<NUM_LAST_WEEKS; w++ )
{
tm StartTime = AddDays( time, -DAYS_IN_WEEK );
coins[w] = GetNumCoins( StartTime, time );
time = StartTime;
}
}
/* iDay is days since Jan 1. iYear is eg. 2005. Return the day of the week,
* where 0 is Sunday. */
void Bookkeeper::GetCoinsByDayOfWeek( int coins[DAYS_IN_WEEK] ) const
{
for( int i=0; i<DAYS_IN_WEEK; i++ )
coins[i] = 0;
for( map<Date,int>::const_iterator it = m_mapCoinsForHour.begin(); it != m_mapCoinsForHour.end(); ++it )
{
const Date &d = it->first;
int iDayOfWeek = GetDayInYearAndYear( d.m_iDayOfYear, d.m_iYear ).tm_wday;
coins[iDayOfWeek] += it->second;
}
}
void Bookkeeper::GetCoinsByHour( int coins[HOURS_IN_DAY] ) const
{
memset( coins, 0, sizeof(int) * HOURS_IN_DAY );
for( map<Date,int>::const_iterator it = m_mapCoinsForHour.begin(); it != m_mapCoinsForHour.end(); ++it )
{
const Date &d = it->first;
if( d.m_iHour >= HOURS_IN_DAY )
{
LOG->Warn( "Hour %i >= %i", d.m_iHour, HOURS_IN_DAY );
continue;
}
coins[d.m_iHour] += it->second;
}
}
/*
* (c) 2003-2005 Chris Danford, Glenn Maynard
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
+93
View File
@@ -0,0 +1,93 @@
#ifndef Bookkeeper_H
#define Bookkeeper_H
#include "DateTime.h"
#include <map>
class XNode;
/** @brief Track when coins were put into the machine. */
class Bookkeeper
{
public:
Bookkeeper();
~Bookkeeper();
void ClearAll();
void CoinInserted();
int GetCoinsTotal() const;
void GetCoinsLastDays( int coins[NUM_LAST_DAYS] ) const;
void GetCoinsLastWeeks( int coins[NUM_LAST_WEEKS] ) const;
void GetCoinsByDayOfWeek( int coins[DAYS_IN_WEEK] ) const;
void GetCoinsByHour( int coins[HOURS_IN_DAY] ) const;
void LoadFromNode( const XNode *pNode );
XNode* CreateNode() const;
void ReadFromDisk();
void WriteToDisk();
private:
/** @brief A simple way of handling the date. */
struct Date
{
/**
* @brief The hour of the date.
*
* The value 0 is defined to be midnight. */
int m_iHour;
/**
* @brief The day of the year of the date.
*
* The value 0 is defined to be January 1st. */
int m_iDayOfYear;
/** @brief The year of the date (e.g., 2005). */
int m_iYear;
/** @brief Set up a date with initial values. */
Date() { m_iHour = m_iDayOfYear = m_iYear = 0; }
/**
* @brief Set up a date based on the given time.
* @param time the time to turn into a Date. */
Date( tm time ) { Set(time); }
void Set( time_t t );
void Set( tm pTime );
bool operator<( const Date &rhs ) const;
};
int GetNumCoins( Date beginning, Date ending ) const;
int GetNumCoinsInRange( map<Date,int>::const_iterator begin, map<Date,int>::const_iterator end ) const;
int m_iLastSeenTime;
map<Date,int> m_mapCoinsForHour;
};
extern Bookkeeper* BOOKKEEPER; // global and accessable from anywhere in our program
#endif
/**
* @file
* @author Chris Danford (c) 2003-2004
* @section LICENSE
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
+1
View File
@@ -24,6 +24,7 @@ static const Game::PerButtonInfo g_CommonButtonInfo[] =
{ GameButtonType_INVALID }, // GAME_BUTTON_START
{ GameButtonType_INVALID }, // GAME_BUTTON_SELECT
{ GameButtonType_INVALID }, // GAME_BUTTON_BACK
{ GameButtonType_INVALID }, // GAME_BUTTON_COIN
{ GameButtonType_INVALID }, // GAME_BUTTON_OPERATOR
{ GameButtonType_INVALID }, // GAME_BUTTON_EFFECT_UP
{ GameButtonType_INVALID }, // GAME_BUTTON_EFFECT_DOWN
+77 -2
View File
@@ -60,6 +60,8 @@ void GameCommand::Init()
m_sUrl = "";
m_bUrlExits = true;
m_bInsertCredit = false;
m_bClearCredits = false;
m_bStopMusic = false;
m_bApplyDefaultOptions = false;
m_bFadeMusic = false;
@@ -367,6 +369,16 @@ void GameCommand::LoadOne( const Command& cmd )
m_vsScreensToPrepare.push_back( sValue );
}
else if( sName == "insertcredit" )
{
m_bInsertCredit = true;
}
else if( sName == "clearcredits" )
{
m_bClearCredits = true;
}
else if( sName == "stopmusic" )
{
m_bStopMusic = true;
@@ -416,6 +428,36 @@ void GameCommand::LoadOne( const Command& cmd )
}
}
int GetNumCreditsPaid()
{
int iNumCreditsPaid = GAMESTATE->GetNumSidesJoined();
// players other than the first joined for free
if( GAMESTATE->GetPremium() == Premium_2PlayersFor1Credit )
iNumCreditsPaid = min( iNumCreditsPaid, 1 );
return iNumCreditsPaid;
}
int GetCreditsRequiredToPlayStyle( const Style *style )
{
if( GAMESTATE->GetPremium() == Premium_2PlayersFor1Credit )
return 1;
switch( style->m_StyleType )
{
case StyleType_OnePlayerOneSide:
return 1;
case StyleType_TwoPlayersSharedSides:
case StyleType_TwoPlayersTwoSides:
return 2;
case StyleType_OnePlayerTwoSides:
return (GAMESTATE->GetPremium() == Premium_DoubleFor1Credit) ? 1 : 2;
DEFAULT_FAIL( style->m_StyleType );
}
}
static bool AreStyleAndPlayModeCompatible( const Style *style, PlayMode pm )
{
if( style == NULL || pm == PlayMode_Invalid )
@@ -451,8 +493,33 @@ bool GameCommand::IsPlayable( RString *why ) const
if ( m_pStyle )
{
int iCredits = NUM_PLAYERS; // not iNumCreditsPaid
int iCredits = GAMESTATE->m_iCoins / PREFSMAN->m_iCoinsPerCredit;
const int iNumCreditsPaid = GetNumCreditsPaid();
const int iNumCreditsRequired = GetCreditsRequiredToPlayStyle(m_pStyle);
switch( GAMESTATE->GetCoinMode() )
{
case CoinMode_Home:
case CoinMode_Free:
iCredits = NUM_PLAYERS; // not iNumCreditsPaid
default: break;
}
/* With PREFSMAN->m_bDelayedCreditsReconcile disabled, enough credits must
* be paid. (This means that enough sides must be joined.) Enabled, simply
* having enough credits lying in the machine is sufficient; we'll deduct the
* extra in Apply(). */
int iNumCreditsAvailable = iNumCreditsPaid;
if( PREFSMAN->m_bDelayedCreditsReconcile )
iNumCreditsAvailable += iCredits;
if( iNumCreditsAvailable < iNumCreditsRequired )
{
if( why )
*why = ssprintf( "need %i credits, have %i", iNumCreditsRequired, iNumCreditsAvailable );
return false;
}
/* If both sides are joined, disallow singles modes, since easy to select
* them accidentally, instead of versus mode. */
if( m_pStyle->m_StyleType == StyleType_OnePlayerOneSide &&
@@ -693,6 +760,14 @@ void GameCommand::ApplySelf( const vector<PlayerNumber> &vpns ) const
FOREACH_CONST( RString, m_vsScreensToPrepare, s )
SCREENMAN->PrepareScreen( *s );
if( m_bInsertCredit )
{
StepMania::InsertCredit();
}
if( m_bClearCredits )
StepMania::ClearCredits();
if( m_bApplyDefaultOptions )
{
// applying options affects only the current stage
+6
View File
@@ -19,6 +19,9 @@ class Style;
class Game;
struct lua_State;
int GetNumCreditsPaid();
int GetCreditsRequiredToPlayStyle( const Style *style );
class GameCommand
{
public:
@@ -36,6 +39,7 @@ public:
m_sSoundPath(""), m_vsScreensToPrepare(), m_iWeightPounds(-1),
m_iGoalCalories(-1), m_GoalType(GoalType_Invalid),
m_sProfileID(""), m_sUrl(""), m_bUrlExits(true),
m_bInsertCredit(false), m_bClearCredits(false),
m_bStopMusic(false), m_bApplyDefaultOptions(false),
m_bFadeMusic(false), m_fMusicFadeOutVolume(-1),
m_fMusicFadeOutSeconds(-1), m_bApplyCommitsScreens(true)
@@ -104,6 +108,8 @@ public:
// sm-ssc adds:
bool m_bUrlExits; // for making stepmania not exit on url
bool m_bInsertCredit;
bool m_bClearCredits;
bool m_bStopMusic;
bool m_bApplyDefaultOptions;
// sm-ssc also adds:
+1
View File
@@ -26,6 +26,7 @@ enum GameButton
GAME_BUTTON_START,
GAME_BUTTON_SELECT,
GAME_BUTTON_BACK,
GAME_BUTTON_COIN, /**< Insert a coin to play. */
GAME_BUTTON_OPERATOR, /**< Access the operator menu. */
GAME_BUTTON_EFFECT_UP,
GAME_BUTTON_EFFECT_DOWN,
+31
View File
@@ -3,6 +3,7 @@
#include "Actor.h"
#include "AdjustSync.h"
#include "AnnouncerManager.h"
#include "Bookkeeper.h"
#include "Character.h"
#include "CharacterManager.h"
#include "CommonMetrics.h"
@@ -110,6 +111,7 @@ GameState::GameState() :
m_pCurGame( Message_CurrentGameChanged ),
m_pCurStyle( Message_CurrentStyleChanged ),
m_PlayMode( Message_PlayModeChanged ),
m_iCoins( Message_CoinsChanged ),
m_sPreferredSongGroup( Message_PreferredSongGroupChanged ),
m_sPreferredCourseGroup( Message_PreferredCourseGroupChanged ),
m_PreferredStepsType( Message_PreferredStepsTypeChanged ),
@@ -136,6 +138,7 @@ GameState::GameState() :
SetCurrentStyle( NULL );
m_pCurGame.Set( NULL );
m_iCoins.Set( 0 );
m_timeGameStarted.SetZero();
m_bDemonstrationOrJukebox = false;
@@ -283,6 +286,7 @@ void GameState::Reset()
m_MultiPlayerStatus[p] = MultiPlayerStatus_NotJoined;
FOREACH_PlayerNumber( pn )
MEMCARDMAN->UnlockCard( pn );
//m_iCoins = 0; // don't reset coin count!
m_bMultiplayer = false;
m_iNumMultiplayerNoteFields = 1;
*m_Environment = LuaTable();
@@ -441,6 +445,14 @@ namespace
if( GAMESTATE->m_bSideIsJoined[pn] )
return false;
// subtract coins
int iCoinsNeededToJoin = GAMESTATE->GetCoinsNeededToJoin();
if( GAMESTATE->m_iCoins < iCoinsNeededToJoin )
return false; // not enough coins
GAMESTATE->m_iCoins.Set( GAMESTATE->m_iCoins - iCoinsNeededToJoin );
GAMESTATE->JoinPlayer( pn );
return true;
@@ -469,6 +481,18 @@ bool GameState::JoinPlayers()
return bJoined;
}
int GameState::GetCoinsNeededToJoin() const
{
int iCoinsToCharge = 0;
// If joint premium, don't take away a credit for the second join.
if( GetPremium() == Premium_2PlayersFor1Credit &&
GetNumSidesJoined() == 1 )
iCoinsToCharge = 0;
return iCoinsToCharge;
}
/* Game flow:
*
* BeginGame() - the first player has joined; the game is starting.
@@ -585,6 +609,7 @@ bool GameState::HaveProfileToSave()
void GameState::SaveLocalData()
{
BOOKKEEPER->WriteToDisk();
PROFILEMAN->SaveMachineProfile();
}
@@ -2272,7 +2297,10 @@ public:
return 1;
}
DEFINE_METHOD( GetGameplayLeadIn, m_bGameplayLeadIn )
DEFINE_METHOD( GetCoins, m_iCoins )
DEFINE_METHOD( IsSideJoined, m_bSideIsJoined[Enum::Check<PlayerNumber>(L, 1)] )
DEFINE_METHOD( GetCoinsNeededToJoin, GetCoinsNeededToJoin() )
DEFINE_METHOD( EnoughCreditsToJoin, EnoughCreditsToJoin() )
DEFINE_METHOD( PlayersCanJoin, PlayersCanJoin() )
DEFINE_METHOD( GetNumSidesJoined, GetNumSidesJoined() )
DEFINE_METHOD( GetCoinMode, GetCoinMode() )
@@ -2525,7 +2553,10 @@ public:
ADD_METHOD( GetSongDelay );*/
ADD_METHOD( GetSongPosition );
ADD_METHOD( GetGameplayLeadIn );
ADD_METHOD( GetCoins );
ADD_METHOD( IsSideJoined );
ADD_METHOD( GetCoinsNeededToJoin );
ADD_METHOD( EnoughCreditsToJoin );
ADD_METHOD( PlayersCanJoin );
ADD_METHOD( GetNumSidesJoined );
ADD_METHOD( GetCoinMode );
+3
View File
@@ -98,6 +98,7 @@ public:
* Note that coins are not "credits". One may have to put in two coins
* to get one credit, only to have to put in another four coins to get
* the three credits needed to begin the game. */
BroadcastOnChange<int> m_iCoins;
bool m_bMultiplayer;
int m_iNumMultiplayerNoteFields;
bool DifficultiesLocked() const;
@@ -120,6 +121,8 @@ public:
* @brief Determine if a second player can join in at this time.
* @return true if a player can still enter the game, false otherwise. */
bool PlayersCanJoin() const;
int GetCoinsNeededToJoin() const;
bool EnoughCreditsToJoin() const { return m_iCoins >= GetCoinsNeededToJoin(); }
int GetNumSidesJoined() const;
const Game* GetCurrentGame();
+7 -2
View File
@@ -65,6 +65,7 @@ static const AutoMappings g_DefaultKeyMappings = AutoMappings(
AutoMappingEntry( 0, KEY_KP_ENTER, GAME_BUTTON_START, true ),
AutoMappingEntry( 0, KEY_KP_C0, GAME_BUTTON_SELECT, true ),
AutoMappingEntry( 0, KEY_HYPHEN, GAME_BUTTON_BACK, true ), // laptop keyboards.
AutoMappingEntry( 0, KEY_F1, GAME_BUTTON_COIN, false ),
AutoMappingEntry( 0, KEY_SCRLLOCK, GAME_BUTTON_OPERATOR, false )
);
@@ -301,6 +302,7 @@ static const AutoMappings g_AutoMappings[] =
AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_SELECT, false ),
AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_START, false ),
AutoMappingEntry( 0, JOY_BUTTON_5, GAME_BUTTON_BACK, false ),
AutoMappingEntry( 0, JOY_BUTTON_6, GAME_BUTTON_COIN, false ),
// Player 2.
AutoMappingEntry( 0, JOY_BUTTON_32, DANCE_BUTTON_LEFT, true ),
AutoMappingEntry( 0, JOY_BUTTON_30, DANCE_BUTTON_RIGHT, true ),
@@ -314,7 +316,8 @@ static const AutoMappings g_AutoMappings[] =
AutoMappingEntry( 0, JOY_BUTTON_24, DANCE_BUTTON_UPLEFT, true ),
AutoMappingEntry( 0, JOY_BUTTON_25, GAME_BUTTON_SELECT, true ),
AutoMappingEntry( 0, JOY_BUTTON_26, GAME_BUTTON_START, true ),
AutoMappingEntry( 0, JOY_BUTTON_21, GAME_BUTTON_BACK, true )
AutoMappingEntry( 0, JOY_BUTTON_21, GAME_BUTTON_BACK, true ),
AutoMappingEntry( 0, JOY_BUTTON_22, GAME_BUTTON_COIN, true )
),
AutoMappings(
"dance",
@@ -345,7 +348,8 @@ static const AutoMappings g_AutoMappings[] =
AutoMappingEntry( 0, JOY_BUTTON_8, /* R1 */ DANCE_BUTTON_UPRIGHT, false ),
AutoMappingEntry( 0, JOY_BUTTON_10, /* Select */ GAME_BUTTON_BACK, false ),
AutoMappingEntry( 0, JOY_BUTTON_9, /* Start */ GAME_BUTTON_START, false ),
AutoMappingEntry( 0, JOY_BUTTON_5, /* R1 */ GAME_BUTTON_SELECT, false )
AutoMappingEntry( 0, JOY_BUTTON_5, /* R1 */ GAME_BUTTON_SELECT, false ),
AutoMappingEntry( 0, JOY_BUTTON_6, /* R2 */ GAME_BUTTON_COIN, false )
),
AutoMappings(
"dance",
@@ -1010,6 +1014,7 @@ static const InputScheme::GameButtonInfo g_CommonGameButtonInfo[] =
{ "Start", GAME_BUTTON_START },
{ "Select", GAME_BUTTON_SELECT },
{ "Back", GAME_BUTTON_BACK },
{ "Coin", GAME_BUTTON_COIN },
{ "Operator", GAME_BUTTON_OPERATOR },
{ "EffectUp", GAME_BUTTON_EFFECT_UP },
{ "EffectDown", GAME_BUTTON_EFFECT_DOWN },
+12
View File
@@ -420,6 +420,18 @@ void LightsManager::Update( float fDeltaTime )
}
}
// If not joined, has enough credits, and not too late to join, then
// blink the menu buttons rapidly so they'll press Start
{
int iBeat = (int)(GAMESTATE->m_Position.m_fLightSongBeat*4);
bool bBlinkOn = (iBeat%2)==0;
FOREACH_PlayerNumber( pn )
{
if( !GAMESTATE->m_bSideIsJoined[pn] && GAMESTATE->PlayersCanJoin() && GAMESTATE->EnoughCreditsToJoin() )
m_LightsState.m_bGameButtonLights[pn][GAME_BUTTON_START] = bBlinkOn;
}
}
// apply new light values we set above
FOREACH( LightsDriver*, m_vpDrivers, iter )
(*iter)->Set( &m_LightsState );
+2
View File
@@ -57,6 +57,7 @@ PNG = \
Screens = \
Screen.cpp Screen.h ScreenAttract.cpp ScreenAttract.h \
ScreenBookkeeping.cpp ScreenBookkeeping.h \
ScreenContinue.cpp ScreenContinue.h \
ScreenDebugOverlay.cpp ScreenDebugOverlay.h \
ScreenDemonstration.cpp ScreenDemonstration.h ScreenDimensions.h \
@@ -471,6 +472,7 @@ RollingNumbers.cpp RollingNumbers.h Sprite.cpp Sprite.h
GlobalSingletons = \
AnnouncerManager.cpp AnnouncerManager.h \
Bookkeeper.cpp Bookkeeper.h \
CharacterManager.cpp CharacterManager.h \
CryptManager.cpp CryptManager.h \
FontManager.cpp FontManager.h GameSoundManager.cpp GameSoundManager.h \
+1
View File
@@ -16,6 +16,7 @@ static const char *MessageIDNames[] = {
"CurrentGameChanged",
"CurrentStyleChanged",
"PlayModeChanged",
"CoinsChanged",
"CurrentSongChanged",
"CurrentStepsP1Changed",
"CurrentStepsP2Changed",
+1
View File
@@ -12,6 +12,7 @@ enum MessageID
Message_CurrentGameChanged,
Message_CurrentStyleChanged,
Message_PlayModeChanged,
Message_CoinsChanged,
Message_CurrentSongChanged,
Message_CurrentStepsP1Changed,
Message_CurrentStepsP2Changed,
+2
View File
@@ -214,7 +214,9 @@ PrefsManager::PrefsManager() :
m_iMusicWheelSwitchSpeed ( "MusicWheelSwitchSpeed", 15 ),
m_AllowW1 ( "AllowW1", ALLOW_W1_EVERYWHERE ),
m_bEventMode ( "EventMode", true ),
m_iCoinsPerCredit ( "CoinsPerCredit", 1 ),
m_iSongsPerPlay ( "SongsPerPlay", 3, ValidateSongsPerPlay ),
m_bDelayedCreditsReconcile ( "DelayedCreditsReconcile", false ),
m_ShowSongOptions ( "ShowSongOptions", Maybe_YES ),
m_bDancePointsForOni ( "DancePointsForOni", true ),
m_bPercentageScoring ( "PercentageScoring", false ),
+2
View File
@@ -205,7 +205,9 @@ public:
Preference<int> m_iMusicWheelSwitchSpeed;
Preference<AllowW1> m_AllowW1; // this should almost always be on, given use cases. -aj
Preference<bool> m_bEventMode;
Preference<int> m_iCoinsPerCredit;
Preference<int> m_iSongsPerPlay;
Preference<bool> m_bDelayedCreditsReconcile; // zuh?
Preference<Maybe> m_ShowSongOptions;
Preference<bool> m_bDancePointsForOni;
Preference<bool> m_bPercentageScoring;
+30
View File
@@ -21,6 +21,7 @@
#include "XmlFile.h"
#include "XmlFileUtil.h"
#include "Foreach.h"
#include "Bookkeeper.h"
#include "Game.h"
#include "CharacterManager.h"
#include "Character.h"
@@ -1848,6 +1849,35 @@ XNode* Profile::SaveCoinDataCreateNode() const
XNode* pNode = new XNode( "CoinData" );
{
int coins[NUM_LAST_DAYS];
BOOKKEEPER->GetCoinsLastDays( coins );
XNode* p = pNode->AppendChild( "LastDays" );
for( int i=0; i<NUM_LAST_DAYS; i++ )
p->AppendChild( LastDayToString(i), coins[i] );
}
{
int coins[NUM_LAST_WEEKS];
BOOKKEEPER->GetCoinsLastWeeks( coins );
XNode* p = pNode->AppendChild( "LastWeeks" );
for( int i=0; i<NUM_LAST_WEEKS; i++ )
p->AppendChild( LastWeekToString(i), coins[i] );
}
{
int coins[DAYS_IN_WEEK];
BOOKKEEPER->GetCoinsByDayOfWeek( coins );
XNode* p = pNode->AppendChild( "DayOfWeek" );
for( int i=0; i<DAYS_IN_WEEK; i++ )
p->AppendChild( DayOfWeekToString(i), coins[i] );
}
{
int coins[HOURS_IN_DAY];
BOOKKEEPER->GetCoinsByHour( coins );
XNode* p = pNode->AppendChild( "Hour" );
for( int i=0; i<HOURS_IN_DAY; i++ )
p->AppendChild( HourInDayToString(i), coins[i] );
}
return pNode;
}
+2 -2
View File
@@ -281,8 +281,8 @@ public:
/**
* @brief The basics for Calorie Data.
*
* Why track calories in a map, and not in a static sized array?
* The machine's clock is not guaranteed to be set correctly.
* Why track calories in a map, and not in a static sized array like
* Bookkeeping? The machine's clock is not guaranteed to be set correctly.
* If calorie array is in a static sized array, playing on a machine with
* a mis-set clock could wipe out all your past data. With this scheme,
* the worst that could happen is that playing on a mis-set machine will
+1
View File
@@ -219,6 +219,7 @@ bool Screen::Input( const InputEventPlus &input )
return false;
case GAME_BUTTON_START: return this->MenuStart ( input );
case GAME_BUTTON_SELECT: return this->MenuSelect( input );
case GAME_BUTTON_COIN: return this->MenuCoin ( input );
default: return false;
}
}
+5
View File
@@ -82,6 +82,7 @@ bool ScreenAttract::AttractInput( const InputEventPlus &input, ScreenWithMenuEle
break;
// fall through
case GAME_BUTTON_START:
case GAME_BUTTON_COIN:
switch( GAMESTATE->GetCoinMode() )
{
case CoinMode_Home:
@@ -89,6 +90,10 @@ bool ScreenAttract::AttractInput( const InputEventPlus &input, ScreenWithMenuEle
if( pScreen->IsTransitioning() )
return false;
// HandleGlobalInputs() already played the coin sound. Don't play it again.
if( input.MenuI != GAME_BUTTON_COIN )
SCREENMAN->PlayStartSound();
pScreen->Cancel( SM_GoToStartScreen );
return true;
default: FAIL_M("Invalid Coin Mode! Aborting...");
+315
View File
@@ -0,0 +1,315 @@
#include "global.h"
#include "ScreenBookkeeping.h"
#include "ScreenManager.h"
#include "RageLog.h"
#include "ThemeManager.h"
#include "Bookkeeper.h"
#include "ScreenDimensions.h"
#include "InputEventPlus.h"
#include "RageUtil.h"
#include "LocalizedString.h"
#include "Song.h"
#include "SongManager.h"
#include "UnlockManager.h"
#include "ProfileManager.h"
#include "Profile.h"
static const char *BookkeepingViewNames[] = {
"SongPlays",
"LastDays",
"LastWeeks",
"DayOfWeek",
"HourOfDay",
};
XToString( BookkeepingView );
REGISTER_SCREEN_CLASS( ScreenBookkeeping );
void ScreenBookkeeping::Init()
{
ScreenWithMenuElements::Init();
m_textAllTime.LoadFromFont( THEME->GetPathF(m_sName,"AllTime") );
m_textAllTime.SetName( "AllTime" );
LOAD_ALL_COMMANDS_AND_SET_XY( m_textAllTime );
this->AddChild( &m_textAllTime );
m_textTitle.LoadFromFont( THEME->GetPathF(m_sName,"title") );
m_textTitle.SetName( "Title" );
LOAD_ALL_COMMANDS_AND_SET_XY( m_textTitle );
this->AddChild( &m_textTitle );
for( int i=0; i<NUM_BOOKKEEPING_COLS; i++ )
{
m_textData[i].LoadFromFont( THEME->GetPathF(m_sName,"data") );
m_textData[i].SetName( "Data" );
LOAD_ALL_COMMANDS_AND_SET_XY( m_textData[i] );
float fX = SCALE( i, 0.f, NUM_BOOKKEEPING_COLS-1, SCREEN_LEFT+50, SCREEN_RIGHT-160 );
m_textData[i].SetX( fX );
this->AddChild( &m_textData[i] );
}
FOREACH_ENUM( BookkeepingView, i )
{
if( THEME->GetMetricB(m_sName,"Show"+BookkeepingViewToString(i)) )
m_vBookkeepingViews.push_back( i );
}
m_iViewIndex = 0;
UpdateView();
}
void ScreenBookkeeping::Update( float fDelta )
{
UpdateView(); // refresh so that counts change in real-time
ScreenWithMenuElements::Update( fDelta );
}
bool ScreenBookkeeping::Input( const InputEventPlus &input )
{
if( input.type != IET_FIRST_PRESS && input.type != IET_REPEAT )
return false; // ignore
return Screen::Input( input ); // default handler
}
bool ScreenBookkeeping::MenuLeft( const InputEventPlus &input )
{
m_iViewIndex--;
CLAMP( m_iViewIndex, 0, m_vBookkeepingViews.size()-1 );
UpdateView();
return true;
}
bool ScreenBookkeeping::MenuRight( const InputEventPlus &input )
{
m_iViewIndex++;
CLAMP( m_iViewIndex, 0, m_vBookkeepingViews.size()-1 );
UpdateView();
return true;
}
bool ScreenBookkeeping::MenuStart( const InputEventPlus &input )
{
if( IsTransitioning() )
return false;
SCREENMAN->PlayStartSound();
StartTransitioningScreen( SM_GoToNextScreen );
return true;
}
bool ScreenBookkeeping::MenuBack( const InputEventPlus &input )
{
if( IsTransitioning() )
return false;
SCREENMAN->PlayStartSound();
StartTransitioningScreen( SM_GoToPrevScreen );
return true;
}
bool ScreenBookkeeping::MenuCoin( const InputEventPlus &input )
{
UpdateView();
return Screen::MenuCoin( input );
}
static LocalizedString ALL_TIME ( "ScreenBookkeeping", "All-time Coin Total:" );
static LocalizedString SONG_PLAYS ( "ScreenBookkeeping", "Total Song Plays: %d" );
static LocalizedString LAST_DAYS ( "ScreenBookkeeping", "Coin Data of Last %d Days" );
static LocalizedString LAST_WEEKS ( "ScreenBookkeeping", "Coin Data of Last %d Weeks" );
static LocalizedString DAY_OF_WEEK ( "ScreenBookkeeping", "Coin Data by Day of Week, All-Time" );
static LocalizedString HOUR_OF_DAY ( "ScreenBookkeeping", "Coin Data by Hour of Day, All-Time" );
void ScreenBookkeeping::UpdateView()
{
BookkeepingView view = m_vBookkeepingViews[m_iViewIndex];
{
RString s;
s += ALL_TIME.GetValue();
s += ssprintf( " %i\n", BOOKKEEPER->GetCoinsTotal() );
m_textAllTime.SetText( s );
}
switch( view )
{
case BookkeepingView_SongPlays:
{
Profile *pProfile = PROFILEMAN->GetMachineProfile();
vector<Song*> vpSongs;
int iCount = 0;
FOREACH_CONST( Song *, SONGMAN->GetAllSongs(), s )
{
Song *pSong = *s;
if( UNLOCKMAN->SongIsLocked(pSong) & ~LOCKED_DISABLED )
continue;
iCount += pProfile->GetSongNumTimesPlayed( pSong );
vpSongs.push_back( pSong );
}
m_textTitle.SetText( ssprintf(SONG_PLAYS.GetValue(), iCount) );
SongUtil::SortSongPointerArrayByNumPlays( vpSongs, pProfile, true );
const int iSongPerCol = 15;
int iSongIndex = 0;
for( int i=0; i<NUM_BOOKKEEPING_COLS; i++ )
{
RString s;
for( int j=0; j<iSongPerCol; j++ )
{
if( iSongIndex < (int)vpSongs.size() )
{
Song *pSong = vpSongs[iSongIndex];
iCount = pProfile->GetSongNumTimesPlayed( pSong );
RString sTitle = ssprintf("%4d",iCount) + " " + pSong->GetDisplayFullTitle();
if( sTitle.length() > 22 )
sTitle = sTitle.Left(20) + "...";
s += sTitle + "\n";
iSongIndex++;
}
}
m_textData[i].SetText( s );
m_textData[i].SetHorizAlign( align_left );
}
}
break;
case BookkeepingView_LastDays:
{
m_textTitle.SetText( ssprintf(LAST_DAYS.GetValue(), NUM_LAST_DAYS) );
int coins[NUM_LAST_DAYS];
BOOKKEEPER->GetCoinsLastDays( coins );
int iTotalLast = 0;
RString sTitle, sData;
for( int i=0; i<NUM_LAST_DAYS; i++ )
{
sTitle += LastDayToLocalizedString(i) + "\n";
sData += ssprintf("%d",coins[i]) + "\n";
iTotalLast += coins[i];
}
sTitle += ALL_TIME.GetValue()+"\n";
sData += ssprintf("%i\n", iTotalLast);
m_textData[0].SetText( "" );
m_textData[1].SetHorizAlign( align_left );
m_textData[1].SetText( sTitle );
m_textData[2].SetText( "" );
m_textData[3].SetHorizAlign( align_right );
m_textData[3].SetText( sData );
}
break;
case BookkeepingView_LastWeeks:
{
m_textTitle.SetText( ssprintf(LAST_WEEKS.GetValue(), NUM_LAST_WEEKS) );
int coins[NUM_LAST_WEEKS];
BOOKKEEPER->GetCoinsLastWeeks( coins );
RString sTitle, sData;
for( int col=0; col<4; col++ )
{
RString sTemp;
for( int row=0; row<52/4; row++ )
{
int week = row*4+col;
sTemp += LastWeekToLocalizedString(week) + ssprintf(": %d",coins[week]) + "\n";
}
m_textData[col].SetHorizAlign( align_left );
m_textData[col].SetText( sTemp );
}
}
break;
case BookkeepingView_DayOfWeek:
{
m_textTitle.SetText( DAY_OF_WEEK );
int coins[DAYS_IN_WEEK];
BOOKKEEPER->GetCoinsByDayOfWeek( coins );
RString sTitle, sData;
for( int i=0; i<DAYS_IN_WEEK; i++ )
{
sTitle += DayOfWeekToString(i) + "\n";
sData += ssprintf("%d",coins[i]) + "\n";
}
m_textData[0].SetText( "" );
m_textData[1].SetHorizAlign( align_left );
m_textData[1].SetText( sTitle );
m_textData[2].SetText( "" );
m_textData[3].SetHorizAlign( align_right );
m_textData[3].SetText( sData );
}
break;
case BookkeepingView_HourOfDay:
{
m_textTitle.SetText( HOUR_OF_DAY );
int coins[HOURS_IN_DAY];
BOOKKEEPER->GetCoinsByHour( coins );
RString sTitle1, sData1;
for( int i=0; i<HOURS_IN_DAY/2; i++ )
{
sTitle1 += HourInDayToLocalizedString(i) + "\n";
sData1 += ssprintf("%d",coins[i]) + "\n";
}
RString sTitle2, sData2;
for( int i=(HOURS_IN_DAY/2); i<HOURS_IN_DAY; i++ )
{
sTitle2 += HourInDayToLocalizedString(i) + "\n";
sData2 += ssprintf("%d",coins[i]) + "\n";
}
m_textData[0].SetHorizAlign( align_left );
m_textData[0].SetText( sTitle1 );
m_textData[1].SetHorizAlign( align_right );
m_textData[1].SetText( sData1 );
m_textData[2].SetHorizAlign( align_left );
m_textData[2].SetText( sTitle2 );
m_textData[3].SetHorizAlign( align_right );
m_textData[3].SetText( sData2 );
}
break;
default:
FAIL_M(ssprintf("Invalid BookkeepingView: %i", view));
}
}
/*
* (c) 2003-2004 Chris Danford
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
+73
View File
@@ -0,0 +1,73 @@
/* ScreenBookkeeping - Show coin drop stats. */
#ifndef ScreenBookkeeping_H
#define ScreenBookkeeping_H
#include "ScreenWithMenuElements.h"
#include "BitmapText.h"
const int NUM_BOOKKEEPING_COLS = 4;
enum BookkeepingView
{
BookkeepingView_SongPlays,
BookkeepingView_LastDays,
BookkeepingView_LastWeeks,
BookkeepingView_DayOfWeek,
BookkeepingView_HourOfDay,
NUM_BookkeepingView,
BookkeepingView_Invalid,
};
class ScreenBookkeeping : public ScreenWithMenuElements
{
public:
virtual void Init();
virtual void Update( float fDelta );
virtual bool Input( const InputEventPlus &input );
virtual bool MenuLeft( const InputEventPlus &input );
virtual bool MenuRight( const InputEventPlus &input );
virtual bool MenuStart( const InputEventPlus &input );
virtual bool MenuBack( const InputEventPlus &input );
virtual bool MenuCoin( const InputEventPlus &input );
private:
void UpdateView();
int m_iViewIndex;
vector<BookkeepingView> m_vBookkeepingViews;
BitmapText m_textAllTime;
BitmapText m_textTitle;
BitmapText m_textData[NUM_BOOKKEEPING_COLS];
};
#endif
/*
* (c) 2003-2004 Chris Danford
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
+3
View File
@@ -50,6 +50,9 @@ void ScreenContinue::BeginScreen()
bool ScreenContinue::Input( const InputEventPlus &input )
{
if( input.MenuI == GAME_BUTTON_COIN && input.type == IET_FIRST_PRESS )
ResetTimer();
if( input.MenuI == GAME_BUTTON_START && input.type == IET_FIRST_PRESS && GAMESTATE->JoinInput(input.pn) )
return true; // handled
+2 -1
View File
@@ -15,6 +15,7 @@
#include "RageTextureManager.h"
#include "MemoryCardManager.h"
#include "NoteSkinManager.h"
#include "Bookkeeper.h"
#include "ProfileManager.h"
#include "CodeDetector.h"
#include "RageInput.h"
@@ -1034,7 +1035,7 @@ class DebugLineWriteProfiles : public IDebugLine
virtual RString GetPageName() const { return "Profiles"; }
virtual void DoAndLog( RString &sMessageOut )
{
// Also save profile info for debugging
// Also save bookkeeping and profile info for debugging
// so we don't have to play through a whole song to get new output.
if( g_ProfileSlot == ProfileSlot_Machine )
GAMESTATE->SaveLocalData();
+4 -1
View File
@@ -101,7 +101,10 @@ bool ScreenSelect::Input( const InputEventPlus &input )
m_timerIdleComment.GetDeltaTime();
m_timerIdleTimeout.GetDeltaTime();
/* Choices may change when more coins are inserted. */
if( input.MenuI == GAME_BUTTON_COIN && input.type == IET_FIRST_PRESS )
this->UpdateSelectableChoices();
if( input.MenuI == GAME_BUTTON_START && input.type == IET_FIRST_PRESS && GAMESTATE->JoinInput(input.pn) )
{
// HACK: Only play start sound for the 2nd player who joins. The
+11 -1
View File
@@ -1,6 +1,7 @@
#include "global.h"
#include "ScreenServiceAction.h"
#include "ThemeManager.h"
#include "Bookkeeper.h"
#include "Profile.h"
#include "ProfileManager.h"
#include "ScreenManager.h"
@@ -16,6 +17,14 @@
#include "StepMania.h"
#include "NotesLoaderSSC.h"
static LocalizedString BOOKKEEPING_DATA_CLEARED( "ScreenServiceAction", "Bookkeeping data cleared." );
static RString ClearBookkeepingData()
{
BOOKKEEPER->ClearAll();
BOOKKEEPER->WriteToDisk();
return BOOKKEEPING_DATA_CLEARED.GetValue();
}
static LocalizedString MACHINE_STATS_CLEARED( "ScreenServiceAction", "Machine stats cleared." );
RString ClearMachineStats()
{
@@ -405,7 +414,8 @@ void ScreenServiceAction::BeginScreen()
{
RString (*pfn)() = NULL;
if( *s == "ClearMachineStats" ) pfn = ClearMachineStats;
if( *s == "ClearBookkeepingData" ) pfn = ClearBookkeepingData;
else if( *s == "ClearMachineStats" ) pfn = ClearMachineStats;
else if( *s == "ClearMachineEdits" ) pfn = ClearMachineEdits;
else if( *s == "ClearMemoryCardEdits" ) pfn = ClearMemoryCardEdits;
else if( *s == "TransferStatsMachineToMemoryCard" ) pfn = TransferStatsMachineToMemoryCard;
+16
View File
@@ -444,6 +444,14 @@
RelativePath="Screen.h"
>
</File>
<File
RelativePath="ScreenBookkeeping.cpp"
>
</File>
<File
RelativePath="ScreenBookkeeping.h"
>
</File>
<File
RelativePath="ScreenContinue.cpp"
>
@@ -3936,6 +3944,14 @@
RelativePath="AnnouncerManager.h"
>
</File>
<File
RelativePath="Bookkeeper.cpp"
>
</File>
<File
RelativePath="Bookkeeper.h"
>
</File>
<File
RelativePath="CharacterManager.cpp"
>
+4
View File
@@ -364,6 +364,7 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)verstub.obj"</Command>
<ItemGroup>
<ClCompile Include="Screen.cpp" />
<ClCompile Include="ScreenAttract.cpp" />
<ClCompile Include="ScreenBookkeeping.cpp" />
<ClCompile Include="ScreenContinue.cpp" />
<ClCompile Include="ScreenDebugOverlay.cpp" />
<ClCompile Include="ScreenDemonstration.cpp" />
@@ -769,6 +770,7 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)verstub.obj"</Command>
<ClCompile Include="RollingNumbers.cpp" />
<ClCompile Include="Sprite.cpp" />
<ClCompile Include="AnnouncerManager.cpp" />
<ClCompile Include="Bookkeeper.cpp" />
<ClCompile Include="CharacterManager.cpp" />
<ClCompile Include="CommandLineActions.cpp">
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">HAVE_VERSION_INFO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -1676,6 +1678,7 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)verstub.obj"</Command>
<ItemGroup>
<ClInclude Include="Screen.h" />
<ClInclude Include="ScreenAttract.h" />
<ClInclude Include="ScreenBookkeeping.h" />
<ClInclude Include="ScreenContinue.h" />
<ClInclude Include="ScreenDebugOverlay.h" />
<ClInclude Include="ScreenDemonstration.h" />
@@ -2088,6 +2091,7 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)verstub.obj"</Command>
<ClInclude Include="RollingNumbers.h" />
<ClInclude Include="Sprite.h" />
<ClInclude Include="AnnouncerManager.h" />
<ClInclude Include="Bookkeeper.h" />
<ClInclude Include="CharacterManager.h" />
<ClInclude Include="CommandLineActions.h" />
<ClInclude Include="CryptManager.h" />
+12
View File
@@ -123,6 +123,9 @@
<ClCompile Include="ScreenAttract.cpp">
<Filter>Screens</Filter>
</ClCompile>
<ClCompile Include="ScreenBookkeeping.cpp">
<Filter>Screens</Filter>
</ClCompile>
<ClCompile Include="ScreenContinue.cpp">
<Filter>Screens</Filter>
</ClCompile>
@@ -1290,6 +1293,9 @@
<ClCompile Include="AnnouncerManager.cpp">
<Filter>Global Singletons</Filter>
</ClCompile>
<ClCompile Include="Bookkeeper.cpp">
<Filter>Global Singletons</Filter>
</ClCompile>
<ClCompile Include="CharacterManager.cpp">
<Filter>Global Singletons</Filter>
</ClCompile>
@@ -1619,6 +1625,9 @@
<ClInclude Include="ScreenAttract.h">
<Filter>Screens</Filter>
</ClInclude>
<ClInclude Include="ScreenBookkeeping.h">
<Filter>Screens</Filter>
</ClInclude>
<ClInclude Include="ScreenContinue.h">
<Filter>Screens</Filter>
</ClInclude>
@@ -2816,6 +2825,9 @@
<ClInclude Include="AnnouncerManager.h">
<Filter>Global Singletons</Filter>
</ClInclude>
<ClInclude Include="Bookkeeper.h">
<Filter>Global Singletons</Filter>
</ClInclude>
<ClInclude Include="CharacterManager.h">
<Filter>Global Singletons</Filter>
</ClInclude>
+4
View File
@@ -382,6 +382,7 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"</Command>
<ItemGroup>
<ClCompile Include="Screen.cpp" />
<ClCompile Include="ScreenAttract.cpp" />
<ClCompile Include="ScreenBookkeeping.cpp" />
<ClCompile Include="ScreenContinue.cpp" />
<ClCompile Include="ScreenDebugOverlay.cpp" />
<ClCompile Include="ScreenDemonstration.cpp" />
@@ -787,6 +788,7 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"</Command>
<ClCompile Include="RollingNumbers.cpp" />
<ClCompile Include="Sprite.cpp" />
<ClCompile Include="AnnouncerManager.cpp" />
<ClCompile Include="Bookkeeper.cpp" />
<ClCompile Include="CharacterManager.cpp" />
<ClCompile Include="CommandLineActions.cpp">
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">HAVE_VERSION_INFO;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -1694,6 +1696,7 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"</Command>
<ItemGroup>
<ClInclude Include="Screen.h" />
<ClInclude Include="ScreenAttract.h" />
<ClInclude Include="ScreenBookkeeping.h" />
<ClInclude Include="ScreenContinue.h" />
<ClInclude Include="ScreenDebugOverlay.h" />
<ClInclude Include="ScreenDemonstration.h" />
@@ -2106,6 +2109,7 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"</Command>
<ClInclude Include="RollingNumbers.h" />
<ClInclude Include="Sprite.h" />
<ClInclude Include="AnnouncerManager.h" />
<ClInclude Include="Bookkeeper.h" />
<ClInclude Include="CharacterManager.h" />
<ClInclude Include="CommandLineActions.h" />
<ClInclude Include="CryptManager.h" />
+13 -1
View File
@@ -123,6 +123,9 @@
<ClCompile Include="ScreenAttract.cpp">
<Filter>Screens</Filter>
</ClCompile>
<ClCompile Include="ScreenBookkeeping.cpp">
<Filter>Screens</Filter>
</ClCompile>
<ClCompile Include="ScreenContinue.cpp">
<Filter>Screens</Filter>
</ClCompile>
@@ -1290,6 +1293,9 @@
<ClCompile Include="AnnouncerManager.cpp">
<Filter>Global Singletons</Filter>
</ClCompile>
<ClCompile Include="Bookkeeper.cpp">
<Filter>Global Singletons</Filter>
</ClCompile>
<ClCompile Include="CharacterManager.cpp">
<Filter>Global Singletons</Filter>
</ClCompile>
@@ -1619,6 +1625,9 @@
<ClInclude Include="ScreenAttract.h">
<Filter>Screens</Filter>
</ClInclude>
<ClInclude Include="ScreenBookkeeping.h">
<Filter>Screens</Filter>
</ClInclude>
<ClInclude Include="ScreenContinue.h">
<Filter>Screens</Filter>
</ClInclude>
@@ -2816,6 +2825,9 @@
<ClInclude Include="AnnouncerManager.h">
<Filter>Global Singletons</Filter>
</ClInclude>
<ClInclude Include="Bookkeeper.h">
<Filter>Global Singletons</Filter>
</ClInclude>
<ClInclude Include="CharacterManager.h">
<Filter>Global Singletons</Filter>
</ClInclude>
@@ -3118,4 +3130,4 @@
<Filter>BaseClasses</Filter>
</CustomBuildStep>
</ItemGroup>
</Project>
</Project>
+70 -1
View File
@@ -57,6 +57,7 @@
//#include "BackgroundCache.h"
#include "UnlockManager.h"
#include "RageFileManager.h"
#include "Bookkeeper.h"
#include "LightsManager.h"
#include "ModelManager.h"
#include "CryptManager.h"
@@ -300,6 +301,7 @@ void ShutdownGame()
SAFE_DELETE( NOTESKIN );
SAFE_DELETE( THEME );
SAFE_DELETE( ANNOUNCER );
SAFE_DELETE( BOOKKEEPER );
SAFE_DELETE( LIGHTSMAN );
SAFE_DELETE( SOUNDMAN );
SAFE_DELETE( FONT );
@@ -1110,6 +1112,7 @@ int main(int argc, char* argv[])
SOUNDMAN->Init();
SOUNDMAN->SetMixVolume();
SOUND = new GameSoundManager;
BOOKKEEPER = new Bookkeeper;
LIGHTSMAN = new LightsManager;
INPUTFILTER = new InputFilter;
INPUTMAPPER = new InputMapper;
@@ -1232,6 +1235,63 @@ RString StepMania::SaveScreenshot( RString sDir, bool bSaveCompressed, bool bMak
return sFileName;
}
void StepMania::InsertCoin( int iNum, bool bCountInBookkeeping )
{
if( bCountInBookkeeping )
{
LIGHTSMAN->PulseCoinCounter();
BOOKKEEPER->CoinInserted();
}
int iNumCoinsOld = GAMESTATE->m_iCoins;
GAMESTATE->m_iCoins.Set( GAMESTATE->m_iCoins + iNum );
int iCredits = GAMESTATE->m_iCoins / PREFSMAN->m_iCoinsPerCredit;
bool bMaxCredits = iCredits >= MAX_NUM_CREDITS;
if( bMaxCredits )
GAMESTATE->m_iCoins.Set( MAX_NUM_CREDITS * PREFSMAN->m_iCoinsPerCredit );
LOG->Trace("%i coins inserted, %i needed to play", GAMESTATE->m_iCoins.Get(), PREFSMAN->m_iCoinsPerCredit.Get() );
if( iNumCoinsOld != GAMESTATE->m_iCoins )
SCREENMAN->PlayCoinSound();
else
SCREENMAN->PlayInvalidSound();
/* If AutoJoin and a player is already joined, then try to join a player.
* (If no players are joined, they'll join on the first JoinInput.) */
if( GAMESTATE->m_bAutoJoin.Get() && GAMESTATE->GetNumSidesJoined() > 0 )
{
if( GAMESTATE->GetNumSidesJoined() > 0 && GAMESTATE->JoinPlayers() )
SCREENMAN->PlayStartSound();
}
// TODO: remove this redundant message and things that depend on it
Message msg( "CoinInserted" );
// below params are unused
//msg.SetParam( "Coins", GAMESTATE->m_iCoins );
//msg.SetParam( "Inserted", iNum );
//msg.SetParam( "MaxCredits", bMaxCredits );
MESSAGEMAN->Broadcast( msg );
}
void StepMania::InsertCredit()
{
InsertCoin( PREFSMAN->m_iCoinsPerCredit, false );
}
void StepMania::ClearCredits()
{
LOG->Trace("%i coins cleared", GAMESTATE->m_iCoins.Get() );
GAMESTATE->m_iCoins.Set( 0 );
SCREENMAN->PlayInvalidSound();
// TODO: remove this redundant message and things that depend on it
Message msg( "CoinInserted" );
// below params are unused
//msg.SetParam( "Coins", GAMESTATE->m_iCoins );
//msg.SetParam( "Clear", true );
MESSAGEMAN->Broadcast( msg );
}
/* Returns true if the key has been handled and should be discarded, false if
* the key should be sent on to screens. */
static LocalizedString SERVICE_SWITCH_PRESSED ( "StepMania", "Service switch pressed" );
@@ -1260,12 +1320,21 @@ bool HandleGlobalInputs( const InputEventPlus &input )
}
return true;
case GAME_BUTTON_COIN:
// Handle a coin insertion.
if( GAMESTATE->IsEditing() ) // no coins while editing
{
LOG->Trace( "Ignored coin insertion (editing)" );
break;
}
StepMania::InsertCoin();
return false; // Attract needs to know because it goes to TitleMenu on > 1 credit
default: break;
}
/* Re-added for StepMania 3.9 theming veterans, plus it's just faster than
* the debug menu. The Shift button only reloads the metrics, unlike in 3.9
* (where it saved machine profile). -aj */
* (where it saved bookkeeping and machine profile). -aj */
bool bIsShiftHeld = INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LSHIFT), &input.InputList) ||
INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_RSHIFT), &input.InputList);
bool bIsCtrlHeld = INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LCTRL), &input.InputList) ||
+4
View File
@@ -20,6 +20,10 @@ namespace StepMania
// If successful, return filename of screenshot in sDir, else return ""
RString SaveScreenshot( RString sDir, bool bSaveCompressed, bool bMakeSignature, int iIndex = -1 );
void InsertCoin( int iNum = 1, bool bCountInBookkeeping = true );
void InsertCredit();
void ClearCredits();
void GetPreferredVideoModeParams( VideoModeParams &paramsOut );
bool GetHighResolutionTextures();
}