Files
itgmania212121/src/ScreenDebugOverlay.cpp
T
Devin J. Pohly feb919f0bf Revert memory leak commits
5f7001e: "Added a new branch"
01456ed: "Fixed a lot of memory leaks"
dac4493: "Fixed all remaining memory leaks that I could figure out"
0792db7: "Removed the smnew macro and the call to _CrtSetDbgFlag()"

Some of these caused destructor-time problems due to static initialization
order fiasco and related issues.  Notably, the program would no longer exit on
OSX and had to be killed.

There were probably legitimate fixes in here, but since these are monolithic
commits it's too much work to extract them now.  Let's reapply them
individually and in the forward direction.
2013-04-27 00:05:14 -04:00

1248 lines
42 KiB
C++

#include "global.h"
#include "ScreenDebugOverlay.h"
#include "ScreenDimensions.h"
#include "ScreenManager.h"
#include "PrefsManager.h"
#include "GamePreferences.h"
#include "RageLog.h"
#include "GameState.h"
#include "PlayerState.h"
#include "StepMania.h"
#include "GameCommand.h"
#include "ScreenGameplay.h"
#include "RageSoundManager.h"
#include "GameSoundManager.h"
#include "RageTextureManager.h"
#include "MemoryCardManager.h"
#include "NoteSkinManager.h"
#include "ProfileManager.h"
#include "CodeDetector.h"
#include "RageInput.h"
#include "RageDisplay.h"
#include "InputEventPlus.h"
#include "LocalizedString.h"
#include "Profile.h"
#include "SongManager.h"
#include "GameLoop.h"
#include "Song.h"
#include "ScreenSyncOverlay.h"
#include "ThemeMetric.h"
static bool g_bIsDisplayed = false;
static bool g_bIsSlow = false;
static bool g_bIsHalt = false;
static RageTimer g_HaltTimer(RageZeroTimer);
static float g_fImageScaleCurrent = 1;
static float g_fImageScaleDestination = 1;
// DebugLine theming
static const ThemeMetric<RageColor> BACKGROUND_COLOR ("ScreenDebugOverlay", "BackgroundColor");
static const ThemeMetric<RageColor> LINE_ON_COLOR ("ScreenDebugOverlay", "LineOnColor");
static const ThemeMetric<RageColor> LINE_OFF_COLOR ("ScreenDebugOverlay", "LineOffColor");
static const ThemeMetric<float> LINE_START_Y ("ScreenDebugOverlay", "LineStartY");
static const ThemeMetric<float> LINE_SPACING ("ScreenDebugOverlay", "LineSpacing");
static const ThemeMetric<float> LINE_BUTTON_X ("ScreenDebugOverlay", "LineButtonX");
static const ThemeMetric<float> LINE_FUNCTION_X ("ScreenDebugOverlay", "LineFunctionX");
static const ThemeMetric<float> PAGE_START_X ("ScreenDebugOverlay", "PageStartX");
static const ThemeMetric<float> PAGE_SPACING_X ("ScreenDebugOverlay", "PageSpacingX");
// self-registering debug lines
// We don't use SubscriptionManager, because we want to keep the line order.
static LocalizedString ON ( "ScreenDebugOverlay", "on" );
static LocalizedString OFF ( "ScreenDebugOverlay", "off" );
class IDebugLine;
static vector<IDebugLine*> *g_pvpSubscribers = NULL;
class IDebugLine
{
public:
IDebugLine()
{
if( g_pvpSubscribers == NULL )
g_pvpSubscribers = new vector<IDebugLine*>;
g_pvpSubscribers->push_back( this );
}
virtual ~IDebugLine() { }
enum Type { all_screens, gameplay_only };
virtual Type GetType() const { return all_screens; }
virtual RString GetDisplayTitle() = 0;
virtual RString GetDisplayValue() { return IsEnabled() ? ON.GetValue():OFF.GetValue(); }
virtual RString GetPageName() const { return "Main"; }
virtual bool ForceOffAfterUse() const { return false; }
virtual bool IsEnabled() = 0;
virtual void DoAndLog( RString &sMessageOut )
{
RString s1 = GetDisplayTitle();
RString s2 = GetDisplayValue();
if( !s2.empty() )
s1 += " - ";
sMessageOut = s1 + s2;
};
DeviceInput m_Button;
};
static bool IsGameplay()
{
return SCREENMAN && SCREENMAN->GetTopScreen() && SCREENMAN->GetTopScreen()->GetScreenType() == gameplay;
}
REGISTER_SCREEN_CLASS( ScreenDebugOverlay );
ScreenDebugOverlay::~ScreenDebugOverlay()
{
this->RemoveAllChildren();
FOREACH( BitmapText*, m_vptextPages, p )
SAFE_DELETE( *p );
FOREACH( BitmapText*, m_vptextButton, p )
SAFE_DELETE( *p );
m_vptextButton.clear();
FOREACH( BitmapText*, m_vptextFunction, p )
SAFE_DELETE( *p );
m_vptextFunction.clear();
}
const int MAX_DEBUG_LINES = 30;
struct MapDebugToDI
{
DeviceInput holdForDebug1;
DeviceInput holdForDebug2;
DeviceInput holdForSlow;
DeviceInput holdForFast;
DeviceInput debugButton[MAX_DEBUG_LINES];
DeviceInput gameplayButton[MAX_DEBUG_LINES];
map<DeviceInput, int> pageButton;
void Clear()
{
holdForDebug1.MakeInvalid();
holdForDebug2.MakeInvalid();
holdForSlow.MakeInvalid();
holdForFast.MakeInvalid();
for( int i=0; i<MAX_DEBUG_LINES; i++ )
{
debugButton[i].MakeInvalid();
gameplayButton[i].MakeInvalid();
}
}
};
static MapDebugToDI g_Mappings;
static LocalizedString IN_GAMEPLAY( "ScreenDebugOverlay", "%s in gameplay" );
static LocalizedString OR( "ScreenDebugOverlay", "or" );
static RString GetDebugButtonName( const IDebugLine *pLine )
{
RString s = INPUTMAN->GetDeviceSpecificInputString(pLine->m_Button);
IDebugLine::Type type = pLine->GetType();
switch( type )
{
case IDebugLine::all_screens:
return s;
case IDebugLine::gameplay_only:
return ssprintf( IN_GAMEPLAY.GetValue(), s.c_str() );
default:
FAIL_M(ssprintf("Invalid debug line type: %i", type));
}
}
template<typename U, typename V>
static bool GetKeyFromMap( const map<U, V> &m, const V &val, U &key )
{
for( typename map<U,V>::const_iterator iter = m.begin(); iter != m.end(); ++iter )
{
if( iter->second == val )
{
key = iter->first;
return true;
}
}
return false;
}
static LocalizedString DEBUG_MENU( "ScreenDebugOverlay", "Debug Menu" );
void ScreenDebugOverlay::Init()
{
Screen::Init();
// Init debug mappings
// TODO: Arch-specific?
{
g_Mappings.Clear();
g_Mappings.holdForDebug1 = DeviceInput(DEVICE_KEYBOARD, KEY_F3);
g_Mappings.holdForDebug2.MakeInvalid();
g_Mappings.holdForSlow = DeviceInput(DEVICE_KEYBOARD, KEY_ACCENT);
g_Mappings.holdForFast = DeviceInput(DEVICE_KEYBOARD, KEY_TAB);
/* TODO: Find a better way of indicating which option is which here.
* Maybe we should take a page from ScreenEdit's menus and make
* RowDefs()? */
int i=0;
g_Mappings.gameplayButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_F8);
g_Mappings.gameplayButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_F7);
g_Mappings.gameplayButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_F6);
i=0;
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C1);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C2);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C3);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C4);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C5);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C6);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C7);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C8);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C9);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_C0);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cq);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cw);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Ce);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cr);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Ct);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cy);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cu);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Ci);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Co);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_Cp);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_UP);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_DOWN);
g_Mappings.debugButton[i++] = DeviceInput(DEVICE_KEYBOARD, KEY_BACK);
g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F5)] = 0;
g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F6)] = 1;
g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F7)] = 2;
g_Mappings.pageButton[DeviceInput(DEVICE_KEYBOARD, KEY_F8)] = 3;
}
map<RString,int> iNextDebugButton;
int iNextGameplayButton = 0;
FOREACH( IDebugLine*, *g_pvpSubscribers, p )
{
RString sPageName = (*p)->GetPageName();
DeviceInput di;
switch( (*p)->GetType() )
{
case IDebugLine::all_screens:
di = g_Mappings.debugButton[iNextDebugButton[sPageName]++];
break;
case IDebugLine::gameplay_only:
di = g_Mappings.gameplayButton[iNextGameplayButton++];
break;
}
(*p)->m_Button = di;
if( find(m_asPages.begin(), m_asPages.end(), sPageName) == m_asPages.end() )
m_asPages.push_back( sPageName );
}
m_iCurrentPage = 0;
m_bForcedHidden = false;
m_Quad.StretchTo( RectF( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT ) );
m_Quad.SetDiffuse( BACKGROUND_COLOR );
this->AddChild( &m_Quad );
// if you're going to add user commands, make sure to have the overrides
// set after parsing the metrics. -aj
m_textHeader.SetName( "HeaderText" );
m_textHeader.LoadFromFont( THEME->GetPathF("ScreenDebugOverlay", "header") );
LOAD_ALL_COMMANDS_AND_SET_XY_AND_ON_COMMAND( m_textHeader );
m_textHeader.SetText( DEBUG_MENU );
this->AddChild( &m_textHeader );
FOREACH_CONST( RString, m_asPages, s )
{
int iPage = s - m_asPages.begin();
DeviceInput di;
bool b = GetKeyFromMap( g_Mappings.pageButton, iPage, di );
ASSERT( b );
RString sButton = INPUTMAN->GetDeviceSpecificInputString( di );
BitmapText *p = new BitmapText;
p->SetName( "PageText" );
p->LoadFromFont( THEME->GetPathF("ScreenDebugOverlay", "page") );
LOAD_ALL_COMMANDS_AND_ON_COMMAND( p );
// todo: Y value is still hardcoded. -aj
p->SetXY( PAGE_START_X+iPage*PAGE_SPACING_X, SCREEN_TOP+20 );
p->SetText( *s + " (" + sButton + ")" );
m_vptextPages.push_back( p );
this->AddChild( p );
}
FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p )
{
{
BitmapText *bt = new BitmapText;
bt->SetName( "ButtonText" );
bt->LoadFromFont( THEME->GetPathF("ScreenDebugOverlay", "line") );
bt->SetHorizAlign( align_right );
bt->SetText( "blah" );
LOAD_ALL_COMMANDS_AND_ON_COMMAND( *bt );
m_vptextButton.push_back( bt );
this->AddChild( bt );
}
{
BitmapText *bt = new BitmapText;
bt->SetName( "FunctionText" );
bt->LoadFromFont( THEME->GetPathF("ScreenDebugOverlay", "line") );
bt->SetHorizAlign( align_left );
bt->SetText( "blah" );
LOAD_ALL_COMMANDS_AND_ON_COMMAND( *bt );
m_vptextFunction.push_back( bt );
this->AddChild( bt );
}
}
this->SetVisible( false );
}
void ScreenDebugOverlay::Update( float fDeltaTime )
{
{
float fRate = 1;
if( INPUTFILTER->IsBeingPressed(g_Mappings.holdForFast) )
{
if( INPUTFILTER->IsBeingPressed(g_Mappings.holdForSlow) )
fRate = 0; // both; stop time
else
fRate *= 4;
}
else if( INPUTFILTER->IsBeingPressed(g_Mappings.holdForSlow) )
{
fRate /= 4;
}
if( g_bIsHalt )
fRate = 0;
else if( g_bIsSlow )
fRate /= 4;
GameLoop::SetUpdateRate( fRate );
}
bool bCenteringNeedsUpdate = g_fImageScaleCurrent != g_fImageScaleDestination;
fapproach( g_fImageScaleCurrent, g_fImageScaleDestination, fDeltaTime );
if( bCenteringNeedsUpdate )
{
DISPLAY->ChangeCentering(
PREFSMAN->m_iCenterImageTranslateX,
PREFSMAN->m_iCenterImageTranslateY,
PREFSMAN->m_fCenterImageAddWidth - (int)SCREEN_WIDTH + (int)(g_fImageScaleCurrent*SCREEN_WIDTH),
PREFSMAN->m_fCenterImageAddHeight - (int)SCREEN_HEIGHT + (int)(g_fImageScaleCurrent*SCREEN_HEIGHT) );
}
Screen::Update(fDeltaTime);
this->SetVisible( g_bIsDisplayed && !m_bForcedHidden );
if( !g_bIsDisplayed )
return;
UpdateText();
}
void ScreenDebugOverlay::UpdateText()
{
FOREACH_CONST( RString, m_asPages, s )
{
int iPage = s - m_asPages.begin();
m_vptextPages[iPage]->PlayCommand( (iPage == m_iCurrentPage) ? "GainFocus" : "LoseFocus" );
}
// todo: allow changing of various spacing/location things -aj
int iOffset = 0;
FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p )
{
RString sPageName = (*p)->GetPageName();
int i = p-g_pvpSubscribers->begin();
float fY = LINE_START_Y + iOffset * LINE_SPACING;
BitmapText &txt1 = *m_vptextButton[i];
BitmapText &txt2 = *m_vptextFunction[i];
if( sPageName != GetCurrentPageName() )
{
txt1.SetVisible( false );
txt2.SetVisible( false );
continue;
}
txt1.SetVisible( true );
txt2.SetVisible( true );
++iOffset;
txt1.SetX( LINE_BUTTON_X );
txt1.SetY( fY );
txt2.SetX( LINE_FUNCTION_X );
txt2.SetY( fY );
RString s1 = (*p)->GetDisplayTitle();
RString s2 = (*p)->GetDisplayValue();
bool bOn = (*p)->IsEnabled();
txt1.SetDiffuse( bOn ? LINE_ON_COLOR:LINE_OFF_COLOR );
txt2.SetDiffuse( bOn ? LINE_ON_COLOR:LINE_OFF_COLOR );
RString sButton = GetDebugButtonName( *p );
if( !sButton.empty() )
sButton += ": ";
txt1.SetText( sButton );
if( !s2.empty() )
s1 += " - ";
txt2.SetText( s1 + s2 );
}
if( g_bIsHalt )
{
/* More than once I've paused the game accidentally and wasted time
* figuring out why, so warn. */
if( g_HaltTimer.Ago() >= 5.0f )
{
g_HaltTimer.Touch();
LOG->Warn( "Game halted" );
}
}
}
template<typename U, typename V>
static bool GetValueFromMap( const map<U, V> &m, const U &key, V &val )
{
typename map<U, V>::const_iterator it = m.find(key);
if( it == m.end() )
return false;
val = it->second;
return true;
}
bool ScreenDebugOverlay::Input( const InputEventPlus &input )
{
if( input.DeviceI == g_Mappings.holdForDebug1 ||
input.DeviceI == g_Mappings.holdForDebug2 )
{
bool bHoldingNeither =
(!g_Mappings.holdForDebug1.IsValid() || !INPUTFILTER->IsBeingPressed(g_Mappings.holdForDebug1)) &&
(!g_Mappings.holdForDebug2.IsValid() || !INPUTFILTER->IsBeingPressed(g_Mappings.holdForDebug2));
bool bHoldingBoth =
(!g_Mappings.holdForDebug1.IsValid() || INPUTFILTER->IsBeingPressed(g_Mappings.holdForDebug1)) &&
(!g_Mappings.holdForDebug2.IsValid() || INPUTFILTER->IsBeingPressed(g_Mappings.holdForDebug2));
if( bHoldingNeither )
m_bForcedHidden = false;
if( bHoldingBoth )
g_bIsDisplayed = true;
else
g_bIsDisplayed = false;
}
int iPage = 0;
if( g_bIsDisplayed && GetValueFromMap(g_Mappings.pageButton, input.DeviceI, iPage) )
{
if( input.type != IET_FIRST_PRESS )
return true; // eat the input but do nothing
m_iCurrentPage = iPage;
CLAMP( m_iCurrentPage, 0, (int) m_asPages.size()-1 );
return true;
}
FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p )
{
RString sPageName = (*p)->GetPageName();
int i = p-g_pvpSubscribers->begin();
// Gameplay buttons are available only in gameplay. Non-gameplay buttons
// are only available when the screen is displayed.
IDebugLine::Type type = (*p)->GetType();
switch( type )
{
case IDebugLine::all_screens:
if( !g_bIsDisplayed )
continue;
if( sPageName != GetCurrentPageName() )
continue;
break;
case IDebugLine::gameplay_only:
if( !IsGameplay() )
continue;
break;
default:
FAIL_M(ssprintf("Invalid debug line type: %i", type));
}
if( input.DeviceI == (*p)->m_Button )
{
if( input.type != IET_FIRST_PRESS )
return true; // eat the input but do nothing
// do the action
RString sMessage;
(*p)->DoAndLog( sMessage );
if( !sMessage.empty() )
LOG->Trace("DEBUG: %s", sMessage.c_str() );
if( (*p)->ForceOffAfterUse() )
m_bForcedHidden = true;
// update text to show the effect of what changed above
UpdateText();
// show what changed
BitmapText &bt = *m_vptextButton[i];
bt.FinishTweening();
bt.PlayCommand("Toggled");
return true;
}
}
return Screen::Input(input);
}
// DebugLine helpers
static void SetSpeed()
{
// PauseMusic( g_bIsHalt );
}
void ChangeVolume( float fDelta )
{
Preference<float> *pRet = Preference<float>::GetPreferenceByName("SoundVolume");
float fVol = pRet->Get();
fVol += fDelta;
CLAMP( fVol, 0.0f, 1.0f );
pRet->Set( fVol );
SOUNDMAN->SetMixVolume();
}
void ChangeVisualDelay( float fDelta )
{
Preference<float> *pRet = Preference<float>::GetPreferenceByName("VisualDelaySeconds");
float fSecs = pRet->Get();
fSecs += fDelta;
CLAMP( fSecs, -1.0f, 1.0f );
pRet->Set( fSecs );
}
// DebugLines
static LocalizedString AUTO_PLAY ( "ScreenDebugOverlay", "AutoPlay" );
static LocalizedString ASSIST ( "ScreenDebugOverlay", "Assist" );
static LocalizedString AUTOSYNC ( "ScreenDebugOverlay", "Autosync" );
static LocalizedString COIN_MODE ( "ScreenDebugOverlay", "CoinMode" );
static LocalizedString HALT ( "ScreenDebugOverlay", "Halt" );
static LocalizedString LIGHTS_DEBUG ( "ScreenDebugOverlay", "Lights Debug" );
static LocalizedString MONKEY_INPUT ( "ScreenDebugOverlay", "Monkey Input" );
static LocalizedString RENDERING_STATS ( "ScreenDebugOverlay", "Rendering Stats" );
static LocalizedString VSYNC ( "ScreenDebugOverlay", "Vsync" );
static LocalizedString MULTITEXTURE ( "ScreenDebugOverlay", "Multitexture" );
static LocalizedString SCREEN_TEST_MODE ( "ScreenDebugOverlay", "Screen Test Mode" );
static LocalizedString SCREEN_SHOW_MASKS ( "ScreenDebugOverlay", "Show Masks" );
static LocalizedString PROFILE ( "ScreenDebugOverlay", "Profile" );
static LocalizedString CLEAR_PROFILE_STATS ( "ScreenDebugOverlay", "Clear Profile Stats" );
static LocalizedString FILL_PROFILE_STATS ( "ScreenDebugOverlay", "Fill Profile Stats" );
static LocalizedString SEND_NOTES_ENDED ( "ScreenDebugOverlay", "Send Notes Ended" );
static LocalizedString RELOAD ( "ScreenDebugOverlay", "Reload" );
static LocalizedString RESTART ( "ScreenDebugOverlay", "Restart" );
static LocalizedString SCREEN_ON ( "ScreenDebugOverlay", "Send On To Screen" );
static LocalizedString SCREEN_OFF ( "ScreenDebugOverlay", "Send Off To Screen" );
static LocalizedString RELOAD_THEME_AND_TEXTURES( "ScreenDebugOverlay", "Reload Theme and Textures" );
static LocalizedString WRITE_PROFILES ( "ScreenDebugOverlay", "Write Profiles" );
static LocalizedString WRITE_PREFERENCES ( "ScreenDebugOverlay", "Write Preferences" );
static LocalizedString MENU_TIMER ( "ScreenDebugOverlay", "Menu Timer" );
static LocalizedString FLUSH_LOG ( "ScreenDebugOverlay", "Flush Log" );
static LocalizedString PULL_BACK_CAMERA ( "ScreenDebugOverlay", "Pull Back Camera" );
static LocalizedString VISUAL_DELAY_UP ( "ScreenDebugOverlay", "Visual Delay Up" );
static LocalizedString VISUAL_DELAY_DOWN ( "ScreenDebugOverlay", "Visual Delay Down" );
static LocalizedString VOLUME_UP ( "ScreenDebugOverlay", "Volume Up" );
static LocalizedString VOLUME_DOWN ( "ScreenDebugOverlay", "Volume Down" );
static LocalizedString UPTIME ( "ScreenDebugOverlay", "Uptime" );
static LocalizedString FORCE_CRASH ( "ScreenDebugOverlay", "Force Crash" );
static LocalizedString SLOW ( "ScreenDebugOverlay", "Slow" );
static LocalizedString CPU ( "ScreenDebugOverlay", "CPU" );
static LocalizedString SONG ( "ScreenDebugOverlay", "Song" );
static LocalizedString MACHINE ( "ScreenDebugOverlay", "Machine" );
static LocalizedString SYNC_TEMPO ( "ScreenDebugOverlay", "Tempo" );
class DebugLineAutoplay : public IDebugLine
{
virtual RString GetDisplayTitle() { return AUTO_PLAY.GetValue() + " (+Shift = AI) (+Alt = hide)"; }
virtual RString GetDisplayValue()
{
PlayerController pc = GamePreferences::m_AutoPlay.Get();
switch( pc )
{
case PC_HUMAN: return OFF.GetValue(); break;
case PC_AUTOPLAY: return ON.GetValue(); break;
case PC_CPU: return CPU.GetValue(); break;
default:
FAIL_M(ssprintf("Invalid PlayerController: %i", pc));
}
}
virtual Type GetType() const { return IDebugLine::gameplay_only; }
virtual bool IsEnabled() { return GamePreferences::m_AutoPlay.Get() != PC_HUMAN; }
virtual void DoAndLog( RString &sMessageOut )
{
ASSERT( GAMESTATE->GetMasterPlayerNumber() != PLAYER_INVALID );
PlayerController pc = GAMESTATE->m_pPlayerState[GAMESTATE->GetMasterPlayerNumber()]->m_PlayerController;
bool bHoldingShift =
INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LSHIFT) ) ||
INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_RSHIFT) );
if( bHoldingShift )
pc = (pc==PC_CPU) ? PC_HUMAN : PC_CPU;
else
pc = (pc==PC_AUTOPLAY) ? PC_HUMAN : PC_AUTOPLAY;
GamePreferences::m_AutoPlay.Set( pc );
FOREACH_HumanPlayer(p)
GAMESTATE->m_pPlayerState[p]->m_PlayerController = GamePreferences::m_AutoPlay;
FOREACH_MultiPlayer(p)
GAMESTATE->m_pMultiPlayerState[p]->m_PlayerController = GamePreferences::m_AutoPlay;
// Hide Autoplay if Alt is held down
bool bHoldingAlt =
INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LALT) ) ||
INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_RALT) );
ScreenSyncOverlay::SetShowAutoplay( !bHoldingAlt );
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineAssist : public IDebugLine
{
virtual RString GetDisplayTitle() { return ASSIST.GetValue(); }
virtual Type GetType() const { return gameplay_only; }
virtual RString GetDisplayValue() {
SongOptions so;
so.m_bAssistClap = GAMESTATE->m_SongOptions.GetSong().m_bAssistClap;
so.m_bAssistMetronome = GAMESTATE->m_SongOptions.GetSong().m_bAssistMetronome;
if( so.m_bAssistClap || so.m_bAssistMetronome )
return so.GetLocalizedString();
else
return OFF.GetValue();
}
virtual bool IsEnabled() { return GAMESTATE->m_SongOptions.GetSong().m_bAssistClap || GAMESTATE->m_SongOptions.GetSong().m_bAssistMetronome; }
virtual void DoAndLog( RString &sMessageOut )
{
ASSERT( GAMESTATE->GetMasterPlayerNumber() != PLAYER_INVALID );
bool bHoldingShift = INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LSHIFT) );
bool b;
if( bHoldingShift )
b = !GAMESTATE->m_SongOptions.GetSong().m_bAssistMetronome;
else
b = !GAMESTATE->m_SongOptions.GetSong().m_bAssistClap;
if( bHoldingShift )
SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Preferred, m_bAssistMetronome, b );
else
SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Preferred, m_bAssistClap, b );
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineAutosync : public IDebugLine
{
virtual RString GetDisplayTitle() { return AUTOSYNC.GetValue(); }
virtual RString GetDisplayValue()
{
SongOptions::AutosyncType type = GAMESTATE->m_SongOptions.GetSong().m_AutosyncType;
switch( type )
{
case SongOptions::AUTOSYNC_OFF: return OFF.GetValue(); break;
case SongOptions::AUTOSYNC_SONG: return SONG.GetValue(); break;
case SongOptions::AUTOSYNC_MACHINE: return MACHINE.GetValue(); break;
case SongOptions::AUTOSYNC_TEMPO: return SYNC_TEMPO.GetValue(); break;
default:
FAIL_M(ssprintf("Invalid autosync type: %i", type));
}
}
virtual Type GetType() const { return IDebugLine::gameplay_only; }
virtual bool IsEnabled() { return GAMESTATE->m_SongOptions.GetSong().m_AutosyncType!=SongOptions::AUTOSYNC_OFF; }
virtual void DoAndLog( RString &sMessageOut )
{
int as = GAMESTATE->m_SongOptions.GetSong().m_AutosyncType + 1;
bool bAllowSongAutosync = !GAMESTATE->IsCourseMode();
if( !bAllowSongAutosync &&
( as == SongOptions::AUTOSYNC_SONG || as == SongOptions::AUTOSYNC_TEMPO ) )
as = SongOptions::AUTOSYNC_MACHINE;
wrap( as, SongOptions::NUM_AUTOSYNC_TYPES );
SO_GROUP_ASSIGN( GAMESTATE->m_SongOptions, ModsLevel_Song, m_AutosyncType, SongOptions::AutosyncType(as) );
MESSAGEMAN->Broadcast( Message_AutosyncChanged );
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineCoinMode : public IDebugLine
{
virtual RString GetDisplayTitle() { return COIN_MODE.GetValue(); }
virtual RString GetDisplayValue() { return CoinModeToString(GamePreferences::m_CoinMode); }
virtual bool IsEnabled() { return true; }
virtual void DoAndLog( RString &sMessageOut )
{
int cm = GamePreferences::m_CoinMode+1;
wrap( cm, NUM_CoinMode );
GamePreferences::m_CoinMode.Set( CoinMode(cm) );
SCREENMAN->RefreshCreditsMessages();
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineSlow : public IDebugLine
{
virtual RString GetDisplayTitle() { return SLOW.GetValue(); }
virtual bool IsEnabled() { return g_bIsSlow; }
virtual void DoAndLog( RString &sMessageOut )
{
g_bIsSlow = !g_bIsSlow;
SetSpeed();
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineHalt : public IDebugLine
{
virtual RString GetDisplayTitle() { return HALT.GetValue(); }
virtual bool IsEnabled() { return g_bIsHalt; }
virtual void DoAndLog( RString &sMessageOut )
{
g_bIsHalt = !g_bIsHalt;
g_HaltTimer.Touch();
SetSpeed();
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineLightsDebug : public IDebugLine
{
virtual RString GetDisplayTitle() { return LIGHTS_DEBUG.GetValue(); }
virtual bool IsEnabled() { return PREFSMAN->m_bDebugLights.Get(); }
virtual void DoAndLog( RString &sMessageOut )
{
PREFSMAN->m_bDebugLights.Set( !PREFSMAN->m_bDebugLights );
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineMonkeyInput : public IDebugLine
{
virtual RString GetDisplayTitle() { return MONKEY_INPUT.GetValue(); }
virtual bool IsEnabled() { return PREFSMAN->m_bMonkeyInput.Get(); }
virtual void DoAndLog( RString &sMessageOut )
{
PREFSMAN->m_bMonkeyInput.Set( !PREFSMAN->m_bMonkeyInput );
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineStats : public IDebugLine
{
virtual RString GetDisplayTitle() { return RENDERING_STATS.GetValue(); }
virtual bool IsEnabled() { return PREFSMAN->m_bShowStats.Get(); }
virtual void DoAndLog( RString &sMessageOut )
{
PREFSMAN->m_bShowStats.Set( !PREFSMAN->m_bShowStats );
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineVsync : public IDebugLine
{
virtual RString GetDisplayTitle() { return VSYNC.GetValue(); }
virtual bool IsEnabled() { return PREFSMAN->m_bVsync.Get(); }
virtual void DoAndLog( RString &sMessageOut )
{
PREFSMAN->m_bVsync.Set( !PREFSMAN->m_bVsync );
StepMania::ApplyGraphicOptions();
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineAllowMultitexture : public IDebugLine
{
virtual RString GetDisplayTitle() { return MULTITEXTURE.GetValue(); }
virtual bool IsEnabled() { return PREFSMAN->m_bAllowMultitexture.Get(); }
virtual void DoAndLog( RString &sMessageOut )
{
PREFSMAN->m_bAllowMultitexture.Set( !PREFSMAN->m_bAllowMultitexture );
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineShowMasks : public IDebugLine
{
virtual RString GetDisplayTitle() { return SCREEN_SHOW_MASKS.GetValue(); }
virtual bool IsEnabled() { return GetPref()->Get(); }
virtual RString GetPageName() const { return "Theme"; }
virtual void DoAndLog( RString &sMessageOut )
{
GetPref()->Set( !GetPref()->Get() );
IDebugLine::DoAndLog( sMessageOut );
}
Preference<bool> *GetPref()
{
return Preference<bool>::GetPreferenceByName("ShowMasks");
}
};
static ProfileSlot g_ProfileSlot = ProfileSlot_Machine;
static bool IsSelectProfilePersistent()
{
if( g_ProfileSlot == ProfileSlot_Machine )
return true;
return PROFILEMAN->IsPersistentProfile( (PlayerNumber) g_ProfileSlot );
}
class DebugLineProfileSlot : public IDebugLine
{
virtual RString GetDisplayTitle() { return PROFILE.GetValue(); }
virtual RString GetDisplayValue()
{
switch( g_ProfileSlot )
{
case ProfileSlot_Machine: return "Machine";
case ProfileSlot_Player1: return "Player 1";
case ProfileSlot_Player2: return "Player 2";
default: return RString();
}
}
virtual bool IsEnabled() { return IsSelectProfilePersistent(); }
virtual RString GetPageName() const { return "Profiles"; }
virtual void DoAndLog( RString &sMessageOut )
{
enum_add( g_ProfileSlot, +1 );
if( g_ProfileSlot == NUM_ProfileSlot )
g_ProfileSlot = ProfileSlot_Player1;
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineClearProfileStats : public IDebugLine
{
virtual RString GetDisplayTitle() { return CLEAR_PROFILE_STATS.GetValue(); }
virtual RString GetDisplayValue() { return RString(); }
virtual bool IsEnabled() { return IsSelectProfilePersistent(); }
virtual RString GetPageName() const { return "Profiles"; }
virtual void DoAndLog( RString &sMessageOut )
{
Profile *pProfile = PROFILEMAN->GetProfile( g_ProfileSlot );
pProfile->ClearStats();
IDebugLine::DoAndLog( sMessageOut );
}
};
static HighScore MakeRandomHighScore( float fPercentDP )
{
HighScore hs;
hs.SetName( "FAKE" );
Grade g = (Grade)SCALE( RandomInt(6), 0, 4, Grade_Tier01, Grade_Tier06 );
if( g == Grade_Tier06 )
g = Grade_Failed;
hs.SetGrade( g );
hs.SetScore( RandomInt(100*1000) );
hs.SetPercentDP( fPercentDP );
hs.SetAliveSeconds( randomf(30.0f, 100.0f) );
PlayerOptions po;
po.ChooseRandomModifiers();
hs.SetModifiers( po.GetString() );
hs.SetDateTime( DateTime::GetNowDateTime() );
hs.SetPlayerGuid( Profile::MakeGuid() );
hs.SetMachineGuid( Profile::MakeGuid() );
hs.SetProductID( RandomInt(10) );
FOREACH_ENUM( TapNoteScore, tns )
hs.SetTapNoteScore( tns, RandomInt(100) );
FOREACH_ENUM( HoldNoteScore, hns )
hs.SetHoldNoteScore( hns, RandomInt(100) );
RadarValues rv;
FOREACH_ENUM( RadarCategory, rc )
rv.m_Values.f[rc] = randomf( 0, 1 );
hs.SetRadarValues( rv );
return hs;
}
static void FillProfileStats( Profile *pProfile )
{
pProfile->InitSongScores();
pProfile->InitCourseScores();
static int s_iCount = 0;
// Choose a percent for all scores. This is useful for testing unlocks
// where some elements are unlocked at a certain percent complete.
float fPercentDP = s_iCount ? randomf( 0.6f, 1.0f ) : 1.0f;
s_iCount = (s_iCount+1)%2;
int iCount = pProfile->IsMachine()?
PREFSMAN->m_iMaxHighScoresPerListForMachine.Get():
PREFSMAN->m_iMaxHighScoresPerListForPlayer.Get();
vector<Song*> vpAllSongs = SONGMAN->GetAllSongs();
FOREACH( Song*, vpAllSongs, pSong )
{
vector<Steps*> vpAllSteps = (*pSong)->GetAllSteps();
FOREACH( Steps*, vpAllSteps, pSteps )
{
if( rand() % 5 )
pProfile->IncrementStepsPlayCount( *pSong, *pSteps );
for( int i=0; i<iCount; i++ )
{
int iIndex = 0;
pProfile->AddStepsHighScore( *pSong, *pSteps, MakeRandomHighScore(fPercentDP), iIndex );
}
}
}
vector<Course*> vpAllCourses;
SONGMAN->GetAllCourses( vpAllCourses, true );
FOREACH( Course*, vpAllCourses, pCourse )
{
vector<Trail*> vpAllTrails;
(*pCourse)->GetAllTrails( vpAllTrails );
FOREACH( Trail*, vpAllTrails, pTrail )
{
if( rand() % 5 )
pProfile->IncrementCoursePlayCount( *pCourse, *pTrail );
for( int i=0; i<iCount; i++ )
{
int iIndex = 0;
pProfile->AddCourseHighScore( *pCourse, *pTrail, MakeRandomHighScore(fPercentDP), iIndex );
}
}
}
SCREENMAN->ZeroNextUpdate();
}
class DebugLineFillProfileStats : public IDebugLine
{
virtual RString GetDisplayTitle() { return FILL_PROFILE_STATS.GetValue(); }
virtual RString GetDisplayValue() { return RString(); }
virtual bool IsEnabled() { return IsSelectProfilePersistent(); }
virtual RString GetPageName() const { return "Profiles"; }
virtual void DoAndLog( RString &sMessageOut )
{
Profile* pProfile = PROFILEMAN->GetProfile( g_ProfileSlot );
FillProfileStats( pProfile );
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineSendNotesEnded : public IDebugLine
{
virtual RString GetDisplayTitle() { return SEND_NOTES_ENDED.GetValue(); }
virtual RString GetDisplayValue() { return RString(); }
virtual bool IsEnabled() { return true; }
virtual void DoAndLog( RString &sMessageOut )
{
SCREENMAN->PostMessageToTopScreen( SM_NotesEnded, 0 );
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineReloadCurrentScreen : public IDebugLine
{
virtual RString GetDisplayTitle() { return RELOAD.GetValue(); }
virtual RString GetDisplayValue() { return SCREENMAN && SCREENMAN->GetTopScreen()? SCREENMAN->GetTopScreen()->GetName() : RString(); }
virtual bool IsEnabled() { return true; }
virtual RString GetPageName() const { return "Theme"; }
virtual void DoAndLog( RString &sMessageOut )
{
RString sScreenName = SCREENMAN->GetScreen(0)->GetName();
SCREENMAN->PopAllScreens();
SOUND->StopMusic();
//StepMania::ResetGame();
SCREENMAN->SetNewScreen( sScreenName );
IDebugLine::DoAndLog( sMessageOut );
sMessageOut = "";
}
};
class DebugLineRestartCurrentScreen : public IDebugLine
{
virtual RString GetDisplayTitle() { return RESTART.GetValue(); }
virtual RString GetDisplayValue() { return SCREENMAN && SCREENMAN->GetTopScreen()? SCREENMAN->GetTopScreen()->GetName() : RString(); }
virtual bool IsEnabled() { return true; }
virtual bool ForceOffAfterUse() const { return true; }
virtual RString GetPageName() const { return "Theme"; }
virtual void DoAndLog( RString &sMessageOut )
{
SCREENMAN->GetTopScreen()->BeginScreen();
IDebugLine::DoAndLog( sMessageOut );
sMessageOut = "";
}
};
class DebugLineCurrentScreenOn : public IDebugLine
{
virtual RString GetDisplayTitle() { return SCREEN_ON.GetValue(); }
virtual RString GetDisplayValue() { return SCREENMAN && SCREENMAN->GetTopScreen()? SCREENMAN->GetTopScreen()->GetName() : RString(); }
virtual bool IsEnabled() { return true; }
virtual bool ForceOffAfterUse() const { return true; }
virtual RString GetPageName() const { return "Theme"; }
virtual void DoAndLog( RString &sMessageOut )
{
SCREENMAN->GetTopScreen()->PlayCommand("On");
IDebugLine::DoAndLog( sMessageOut );
sMessageOut = "";
}
};
class DebugLineCurrentScreenOff : public IDebugLine
{
virtual RString GetDisplayTitle() { return SCREEN_OFF.GetValue(); }
virtual RString GetDisplayValue() { return SCREENMAN && SCREENMAN->GetTopScreen()? SCREENMAN->GetTopScreen()->GetName() : RString(); }
virtual bool IsEnabled() { return true; }
virtual bool ForceOffAfterUse() const { return true; }
virtual RString GetPageName() const { return "Theme"; }
virtual void DoAndLog( RString &sMessageOut )
{
SCREENMAN->GetTopScreen()->PlayCommand("Off");
IDebugLine::DoAndLog( sMessageOut );
sMessageOut = "";
}
};
class DebugLineReloadTheme : public IDebugLine
{
virtual RString GetDisplayTitle() { return RELOAD_THEME_AND_TEXTURES.GetValue(); }
virtual RString GetDisplayValue() { return RString(); }
virtual bool IsEnabled() { return true; }
virtual RString GetPageName() const { return "Theme"; }
virtual void DoAndLog( RString &sMessageOut )
{
THEME->ReloadMetrics();
TEXTUREMAN->ReloadAll();
NOTESKIN->RefreshNoteSkinData( GAMESTATE->m_pCurGame );
CodeDetector::RefreshCacheItems();
// HACK: Don't update text below. Return immediately because this screen
// was just destroyed as part of the theme reload.
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineWriteProfiles : public IDebugLine
{
virtual RString GetDisplayTitle() { return WRITE_PROFILES.GetValue(); }
virtual RString GetDisplayValue() { return RString(); }
virtual bool IsEnabled() { return IsSelectProfilePersistent(); }
virtual RString GetPageName() const { return "Profiles"; }
virtual void DoAndLog( RString &sMessageOut )
{
// Also save 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();
else
{
PlayerNumber pn = (PlayerNumber) g_ProfileSlot;
GAMESTATE->SaveCurrentSettingsToProfile(pn);
GAMESTATE->SavePlayerProfile( pn );
}
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineWritePreferences : public IDebugLine
{
virtual RString GetDisplayTitle() { return WRITE_PREFERENCES.GetValue(); }
virtual RString GetDisplayValue() { return RString(); }
virtual bool IsEnabled() { return true; }
virtual void DoAndLog( RString &sMessageOut )
{
PREFSMAN->SavePrefsToDisk();
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineMenuTimer : public IDebugLine
{
virtual RString GetDisplayTitle() { return MENU_TIMER.GetValue(); }
virtual RString GetDisplayValue() { return RString(); }
virtual bool IsEnabled() { return PREFSMAN->m_bMenuTimer.Get(); }
virtual void DoAndLog( RString &sMessageOut )
{
PREFSMAN->m_bMenuTimer.Set( !PREFSMAN->m_bMenuTimer );
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineFlushLog : public IDebugLine
{
virtual RString GetDisplayTitle() { return FLUSH_LOG.GetValue(); }
virtual RString GetDisplayValue() { return RString(); }
virtual bool IsEnabled() { return true; }
virtual void DoAndLog( RString &sMessageOut )
{
LOG->Flush();
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLinePullBackCamera : public IDebugLine
{
virtual RString GetDisplayTitle() { return PULL_BACK_CAMERA.GetValue(); }
virtual RString GetDisplayValue() { return RString(); }
virtual bool IsEnabled() { return g_fImageScaleDestination != 1; }
virtual void DoAndLog( RString &sMessageOut )
{
if( g_fImageScaleDestination == 1 )
g_fImageScaleDestination = 0.5f;
else
g_fImageScaleDestination = 1;
IDebugLine::DoAndLog( sMessageOut );
}
};
class DebugLineVolumeUp : public IDebugLine
{
virtual RString GetDisplayTitle() { return VOLUME_UP.GetValue(); }
virtual RString GetDisplayValue() { return ssprintf("%.0f%%", GetPref()->Get()*100); }
virtual bool IsEnabled() { return true; }
virtual void DoAndLog( RString &sMessageOut )
{
ChangeVolume( +0.1f );
IDebugLine::DoAndLog( sMessageOut );
}
Preference<float> *GetPref()
{
return Preference<float>::GetPreferenceByName("SoundVolume");
}
};
class DebugLineVolumeDown : public IDebugLine
{
virtual RString GetDisplayTitle() { return VOLUME_DOWN.GetValue(); }
virtual RString GetDisplayValue() { return RString(); }
virtual bool IsEnabled() { return true; }
virtual void DoAndLog( RString &sMessageOut )
{
ChangeVolume( -0.1f );
IDebugLine::DoAndLog( sMessageOut );
sMessageOut += " - " + ssprintf("%.0f%%",GetPref()->Get()*100);
}
Preference<float> *GetPref()
{
return Preference<float>::GetPreferenceByName("SoundVolume");
}
};
class DebugLineVisualDelayUp : public IDebugLine
{
virtual RString GetDisplayTitle() { return VISUAL_DELAY_UP.GetValue(); }
virtual RString GetDisplayValue() { return ssprintf("%.03f",GetPref()->Get()); }
virtual bool IsEnabled() { return true; }
virtual void DoAndLog( RString &sMessageOut )
{
ChangeVisualDelay( +0.001f );
IDebugLine::DoAndLog( sMessageOut );
}
Preference<float> *GetPref()
{
return Preference<float>::GetPreferenceByName("VisualDelaySeconds");
}
};
class DebugLineVisualDelayDown : public IDebugLine
{
virtual RString GetDisplayTitle() { return VISUAL_DELAY_DOWN.GetValue(); }
virtual RString GetDisplayValue() { return RString(); }
virtual bool IsEnabled() { return true; }
virtual void DoAndLog( RString &sMessageOut )
{
ChangeVisualDelay( -0.001f );
IDebugLine::DoAndLog( sMessageOut );
sMessageOut += " - " + ssprintf("%.03f",GetPref()->Get());
}
Preference<float> *GetPref()
{
return Preference<float>::GetPreferenceByName("VisualDelaySeconds");
}
};
class DebugLineForceCrash : public IDebugLine
{
virtual RString GetDisplayTitle() { return FORCE_CRASH.GetValue(); }
virtual RString GetDisplayValue() { return RString(); }
virtual bool IsEnabled() { return false; }
virtual void DoAndLog( RString &sMessageOut ) { FAIL_M("DebugLineCrash"); }
};
class DebugLineUptime : public IDebugLine
{
virtual RString GetDisplayTitle() { return UPTIME.GetValue(); }
virtual RString GetDisplayValue() { return SecondsToMMSSMsMsMs(RageTimer::GetTimeSinceStart()); }
virtual bool IsEnabled() { return false; }
virtual void DoAndLog( RString &sMessageOut ) {}
};
/* #ifdef out the lines below if you don't want them to appear on certain
* platforms. This is easier than #ifdefing the whole DebugLine definitions
* that can span pages.
*/
#define DECLARE_ONE( x ) static x g_##x
DECLARE_ONE( DebugLineAutoplay );
DECLARE_ONE( DebugLineAssist );
DECLARE_ONE( DebugLineAutosync );
DECLARE_ONE( DebugLineCoinMode );
DECLARE_ONE( DebugLineSlow );
DECLARE_ONE( DebugLineHalt );
DECLARE_ONE( DebugLineLightsDebug );
DECLARE_ONE( DebugLineMonkeyInput );
DECLARE_ONE( DebugLineStats );
DECLARE_ONE( DebugLineVsync );
DECLARE_ONE( DebugLineAllowMultitexture );
DECLARE_ONE( DebugLineShowMasks );
DECLARE_ONE( DebugLineProfileSlot );
DECLARE_ONE( DebugLineClearProfileStats );
DECLARE_ONE( DebugLineFillProfileStats );
DECLARE_ONE( DebugLineSendNotesEnded );
DECLARE_ONE( DebugLineReloadCurrentScreen );
DECLARE_ONE( DebugLineRestartCurrentScreen );
DECLARE_ONE( DebugLineCurrentScreenOn );
DECLARE_ONE( DebugLineCurrentScreenOff );
DECLARE_ONE( DebugLineReloadTheme );
DECLARE_ONE( DebugLineWriteProfiles );
DECLARE_ONE( DebugLineWritePreferences );
DECLARE_ONE( DebugLineMenuTimer );
DECLARE_ONE( DebugLineFlushLog );
DECLARE_ONE( DebugLinePullBackCamera );
DECLARE_ONE( DebugLineVolumeDown );
DECLARE_ONE( DebugLineVolumeUp );
DECLARE_ONE( DebugLineVisualDelayDown );
DECLARE_ONE( DebugLineVisualDelayUp );
DECLARE_ONE( DebugLineForceCrash );
DECLARE_ONE( DebugLineUptime );
/*
* (c) 2001-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.
*/