merge+fix NotesLoaderBMS.cpp

This commit is contained in:
Thai Pangsakulyanont
2011-03-15 21:57:04 +07:00
214 changed files with 2171 additions and 1401 deletions
+4 -1
View File
@@ -528,9 +528,10 @@ public:
}
static int SortByDrawOrder( T* p, lua_State *L ) { p->SortByDrawOrder(); return 0; }
//static int CustomLighting( T* p, lua_State *L ) { p->SetCustomLighting(BArg(1)); return 0; }
static int SetAmbientLightColor( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetAmbientLightColor( c ); return 0; }
static int SetDiffuseLightColor( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetDiffuseLightColor( c ); return 0; }
static int SetSpecularLightColor( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetSpecularLightColor( c ); return 0; }
static int SetSpecularLightColor( T* p, lua_State *L ) { RageColor c; c.FromStackCompat( L, 1 ); p->SetSpecularLightColor( c ); return 0; }
static int SetLightDirection( T* p, lua_State *L )
{
luaL_checktype( L, 1, LUA_TTABLE );
@@ -546,6 +547,7 @@ public:
p->SetLightDirection( vTmp );
return 0;
}
// xxx: these might not be good ideas... -aj
/*
static int AddChild( T* p, lua_State *L )
@@ -585,6 +587,7 @@ public:
ADD_METHOD( GetDrawFunction );
ADD_METHOD( SetUpdateFunction );
ADD_METHOD( SortByDrawOrder );
//ADD_METHOD( CustomLighting );
ADD_METHOD( SetAmbientLightColor );
ADD_METHOD( SetDiffuseLightColor );
ADD_METHOD( SetSpecularLightColor );
+1
View File
@@ -81,6 +81,7 @@ public:
void SetFOV( float fFOV ) { m_fFOV = fFOV; }
void SetVanishPoint( float fX, float fY) { m_fVanishX = fX; m_fVanishY = fY; }
void SetCustomLighting( bool bCustomLighting ) { m_bOverrideLighting = bCustomLighting; }
void SetAmbientLightColor( RageColor c ) { m_ambientColor = c; }
void SetDiffuseLightColor( RageColor c ) { m_diffuseColor = c; }
void SetSpecularLightColor( RageColor c ) { m_specularColor = c; }
+1
View File
@@ -33,6 +33,7 @@ public:
static void GetSyncChangeTextGlobal( vector<RString> &vsAddTo );
static void GetSyncChangeTextSong( vector<RString> &vsAddTo );
/** @brief The minimum number of steps to hit for syncing purposes. */
static const int OFFSET_SAMPLE_COUNT = 56;
static float s_fAutosyncOffset[OFFSET_SAMPLE_COUNT];
+1 -1
View File
@@ -445,7 +445,7 @@ float ArrowEffects::GetXPos( const PlayerState* pPlayerState, int iColNum, float
{
// find the middle, and split based on iColNum
// it's unknown if this will work for routine.
const int iMiddleColumn = floor(pStyle->m_iColsPerPlayer/2.0f);
const int iMiddleColumn = static_cast<int>(floor(pStyle->m_iColsPerPlayer/2.0f));
if( iColNum > iMiddleColumn-1 )
fPixelOffsetFromCenter += fEffects[PlayerOptions::EFFECT_XMODE]*-(fYOffset);
else
+2 -2
View File
@@ -34,8 +34,8 @@ void Attack::GetRealtimeAttackBeats( const Song *pSong, const PlayerState* pPlay
fStartBeat = min( GAMESTATE->m_fSongBeat+8, pPlayerState->m_fLastDrawnBeat );
fStartBeat = truncf(fStartBeat)+1;
const float fStartSecond = pSong->GetElapsedTimeFromBeat( fStartBeat );
const float fEndSecond = fStartSecond + fSecsRemaining;
const float lStartSecond = pSong->GetElapsedTimeFromBeat( fStartBeat );
const float fEndSecond = lStartSecond + fSecsRemaining;
fEndBeat = pSong->GetBeatFromElapsedTime( fEndSecond );
fEndBeat = truncf(fEndBeat)+1;
+9 -11
View File
@@ -32,7 +32,10 @@ struct Attack
bGlobal = false;
bShowInAttackList = true;
}
Attack() { MakeBlank(); }
Attack(): level(ATTACK_LEVEL_1), fStartSecond(-1),
fSecsRemaining(0), sModifiers(RString()),
bOn(false), bGlobal(false), bShowInAttackList(true)
{} // MakeBlank() is effectively called here.
Attack(
AttackLevel level_,
float fStartSecond_,
@@ -40,16 +43,11 @@ struct Attack
RString sModifiers_,
bool bOn_,
bool bGlobal_,
bool bShowInAttackList_ = true )
{
level = level_;
fStartSecond = fStartSecond_;
fSecsRemaining = fSecsRemaining_;
sModifiers = sModifiers_;
bOn = bOn_;
bGlobal = bGlobal_;
bShowInAttackList = bShowInAttackList_;
}
bool bShowInAttackList_ = true ):
level(level_), fStartSecond(fStartSecond_),
fSecsRemaining(fSecsRemaining_), sModifiers(sModifiers_),
bOn(bOn_), bGlobal(bGlobal_),
bShowInAttackList(bShowInAttackList_) {}
void GetAttackBeats( const Song *pSong, float &fStartBeat, float &fEndBeat ) const;
void GetRealtimeAttackBeats( const Song *pSong, const PlayerState* pPlayerState, float &fStartBeat, float &fEndBeat ) const;
+2 -2
View File
@@ -80,11 +80,11 @@ void AutoKeysounds::LoadAutoplaySoundsInto( RageSoundReader_Chain *pChain )
bool bSoundIsGlobal = true;
{
PlayerNumber pn = GetNextEnabledPlayer((PlayerNumber)-1);
const TapNote &t = tn[pn];
const TapNote &tap = tn[pn];
pn = GetNextEnabledPlayer(pn);
while( pn != PLAYER_INVALID )
{
if( tn[pn].type != TapNote::autoKeysound || tn[pn].iKeysoundIndex != t.iKeysoundIndex )
if( tn[pn].type != TapNote::autoKeysound || tn[pn].iKeysoundIndex != tap.iKeysoundIndex )
bSoundIsGlobal = false;
pn = GetNextEnabledPlayer(pn);
}
+3 -3
View File
@@ -77,9 +77,9 @@ void BGAnimation::AddLayersFromAniDir( const RString &_sAniDir, const XNode *pNo
else
{
// import as a single layer
BGAnimationLayer* pLayer = new BGAnimationLayer;
pLayer->LoadFromNode( pKey );
this->AddChild( pLayer );
BGAnimationLayer* bgLayer = new BGAnimationLayer;
bgLayer->LoadFromNode( pKey );
this->AddChild( bgLayer );
}
}
}
+3 -3
View File
@@ -746,9 +746,9 @@ void BackgroundImpl::Layer::UpdateCurBGChange( const Song *pSong, float fLastMus
if( !change.m_sTransition.empty() )
{
map<RString,BackgroundTransition>::const_iterator iter = mapNameToTransition.find( change.m_sTransition );
ASSERT( iter != mapNameToTransition.end() );
const BackgroundTransition &bt = iter->second;
map<RString,BackgroundTransition>::const_iterator lIter = mapNameToTransition.find( change.m_sTransition );
ASSERT( lIter != mapNameToTransition.end() );
const BackgroundTransition &bt = lIter->second;
m_pFadingBGA->RunCommandsOnLeaves( *bt.cmdLeaves );
m_pFadingBGA->RunCommands( *bt.cmdRoot );
}
+2
View File
@@ -250,9 +250,11 @@ void BeginnerHelper::DrawPrimitives()
m_sStepCircle[scd][scde].Draw();
if( DrawCelShaded )
{
FOREACH_PlayerNumber( pn ) // Draw each dancer
if( GAMESTATE->IsHumanPlayer(pn) )
m_pDancer[pn]->DrawCelShaded();
}
else
{
DISPLAY->SetLighting( true );
+6 -11
View File
@@ -328,9 +328,6 @@ void BitmapText::DrawChars( bool bUseStrokeTexture )
}
}
vector<RageSpriteVertex*> vertices;
int iNumVertsToDraw = 0;
for( int start = iStartGlyph; start < iEndGlyph; )
{
int end = start;
@@ -346,21 +343,19 @@ void BitmapText::DrawChars( bool bUseStrokeTexture )
else
DISPLAY->SetTexture( TextureUnit_1, m_vpFontPageTextures[start]->m_pTextureMain->GetTexHandle() );
/* Don't bother setting texture render states for text. We never go outside of 0..1. */
// Don't bother setting texture render states for text. We never go outside of 0..1.
/* We should call SetTextureRenderStates because it does more than just setting
* the texture wrapping state. If setting the wrapping state is found to be slow,
* there should probably be a "don't care" texture wrapping mode set in Actor. -Chris */
Actor::SetTextureRenderStates();
RageSpriteVertex &start_vertex = m_aVertices[start*4];
vertices.push_back(&start_vertex);
iNumVertsToDraw += (end-start)*4;
// This is SLOW. We need to do something else about this. -Colby
//Actor::SetTextureRenderStates();
DISPLAY->DrawQuads( &m_aVertices[start*4], (end-start)*4);
}
start = end;
}
if (!vertices.empty())
DISPLAY->DrawQuads( vertices[0], iNumVertsToDraw );
}
/* sText is UTF-8. If not all of the characters in sText are available in the
+3 -4
View File
@@ -5,10 +5,9 @@
#include "RageTextureID.h"
#include "ActorUtil.h"
Character::Character()
{
m_iPreloadRefcount = 0;
}
Character::Character(): m_sCharDir(""), m_sCharacterID(""),
m_sDisplayName(""), m_sCardPath(""), m_sIconPath(""),
m_bUsableInRave(false), m_iPreloadRefcount(0) {}
bool Character::Load( RString sCharDir )
{
+44 -45
View File
@@ -85,47 +85,7 @@ int CourseEntry::GetNumModChanges() const
return iNumModChanges;
}
// lua start
#include "LuaBinding.h"
/** @brief Allow Lua to have access to the CourseEntry. */
class LunaCourseEntry: public Luna<CourseEntry>
{
public:
static int GetSong( T* p, lua_State *L )
{
if( p->songID.ToSong() )
p->songID.ToSong()->PushSelf(L);
else
lua_pushnil(L);
return 1;
}
DEFINE_METHOD( IsSecret, bSecret );
DEFINE_METHOD( IsFixedSong, IsFixedSong() );
DEFINE_METHOD( GetGainSeconds, fGainSeconds );
DEFINE_METHOD( GetGainLives, iGainLives );
DEFINE_METHOD( GetNormalModifiers, sModifiers );
// GetTimedModifiers - table
DEFINE_METHOD( GetNumModChanges, GetNumModChanges() );
DEFINE_METHOD( GetTextDescription, GetTextDescription() );
LunaCourseEntry()
{
ADD_METHOD( GetSong );
// sm-ssc additions:
ADD_METHOD( IsSecret );
ADD_METHOD( IsFixedSong );
ADD_METHOD( GetGainSeconds );
ADD_METHOD( GetGainLives );
ADD_METHOD( GetNormalModifiers );
//ADD_METHOD( GetTimedModifiers );
ADD_METHOD( GetNumModChanges );
ADD_METHOD( GetTextDescription );
}
};
LUA_REGISTER_CLASS( CourseEntry )
// lua end
Course::Course()
@@ -559,8 +519,8 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail )
if( e->iChooseIndex < int(vSongAndSteps.size()) )
{
resolved.pSong = vpSongs[e->iChooseIndex];
const vector<Steps*> &vpSongs = mapSongToSteps[resolved.pSong];
resolved.pSteps = vpSongs[ RandomInt(vpSongs.size()) ];
const vector<Steps*> &mappedSongs = mapSongToSteps[resolved.pSong];
resolved.pSteps = mappedSongs[ RandomInt(mappedSongs.size()) ];
}
else
{
@@ -970,8 +930,8 @@ const CourseEntry *Course::FindFixedSong( const Song *pSong ) const
FOREACH_CONST( CourseEntry, m_vEntries, e )
{
const CourseEntry &entry = *e;
Song *pSong = entry.songID.ToSong();
if( pSong == pSong )
Song *lSong = entry.songID.ToSong();
if( pSong == lSong )
return &entry;
}
@@ -1042,10 +1002,49 @@ bool Course::Matches( RString sGroup, RString sCourse ) const
return false;
}
// lua start
#include "LuaBinding.h"
/** @brief Allow Lua to have access to the CourseEntry. */
class LunaCourseEntry: public Luna<CourseEntry>
{
public:
static int GetSong( T* p, lua_State *L )
{
if( p->songID.ToSong() )
p->songID.ToSong()->PushSelf(L);
else
lua_pushnil(L);
return 1;
}
DEFINE_METHOD( IsSecret, bSecret );
DEFINE_METHOD( IsFixedSong, IsFixedSong() );
DEFINE_METHOD( GetGainSeconds, fGainSeconds );
DEFINE_METHOD( GetGainLives, iGainLives );
DEFINE_METHOD( GetNormalModifiers, sModifiers );
// GetTimedModifiers - table
DEFINE_METHOD( GetNumModChanges, GetNumModChanges() );
DEFINE_METHOD( GetTextDescription, GetTextDescription() );
LunaCourseEntry()
{
ADD_METHOD( GetSong );
// sm-ssc additions:
ADD_METHOD( IsSecret );
ADD_METHOD( IsFixedSong );
ADD_METHOD( GetGainSeconds );
ADD_METHOD( GetGainLives );
ADD_METHOD( GetNormalModifiers );
//ADD_METHOD( GetTimedModifiers );
ADD_METHOD( GetNumModChanges );
ADD_METHOD( GetTextDescription );
}
};
LUA_REGISTER_CLASS( CourseEntry )
// Not done with lua yet: still another class.
/** @brief Allow Lua to have access to the Course. */
class LunaCourse: public Luna<Course>
{
+3 -12
View File
@@ -55,18 +55,9 @@ public:
float fGainSeconds; // time gained back at the beginning of the song. LifeMeterTime only.
int iGainLives; // lives gained back at the beginning of the next song
CourseEntry()
{
bSecret = false;
bNoDifficult = false;
songSort = SongSort_Randomize;
iChooseIndex = 0;
sModifiers = "";
fGainSeconds = 0;
iGainLives = -1;
}
CourseEntry(): bSecret(false), bNoDifficult(false),
songSort(SongSort_Randomize), iChooseIndex(0),
sModifiers(RString("")), fGainSeconds(0), iGainLives(-1) {}
bool IsFixedSong() const { return songID.IsValid(); }
+1 -1
View File
@@ -464,7 +464,7 @@ void EditCourseUtil::PrepareForPlay()
PROFILEMAN->GetProfile(ProfileSlot_Player1)->m_GoalType = GoalType_Time;
Course *pCourse = GAMESTATE->m_pCurCourse;
PROFILEMAN->GetProfile(ProfileSlot_Player1)->m_iGoalSeconds = pCourse->m_fGoalSeconds;
PROFILEMAN->GetProfile(ProfileSlot_Player1)->m_iGoalSeconds = static_cast<int>(pCourse->m_fGoalSeconds);
}
void EditCourseUtil::GetAllEditCourses( vector<Course*> &vpCoursesOut )
+9 -10
View File
@@ -11,10 +11,9 @@
#include "FontCharAliases.h"
#include "arch/Dialog/Dialog.h"
FontPage::FontPage()
{
m_iDrawExtraPixelsLeft = m_iDrawExtraPixelsRight = 0;
}
FontPage::FontPage(): m_iHeight(0), m_iLineSpacing(0), m_fVshift(0),
m_iDrawExtraPixelsLeft(0), m_iDrawExtraPixelsRight(0),
m_sTexturePath("") {}
void FontPage::Load( const FontPageSettings &cfg )
{
@@ -311,15 +310,15 @@ const glyph &Font::GetGlyph( wchar_t c ) const
bool Font::FontCompleteForString( const wstring &str ) const
{
map<wchar_t,glyph*>::const_iterator m_pDefault = m_iCharToGlyph.find( FONT_DEFAULT_GLYPH );
if( m_pDefault == m_iCharToGlyph.end() )
map<wchar_t,glyph*>::const_iterator mapDefault = m_iCharToGlyph.find( FONT_DEFAULT_GLYPH );
if( mapDefault == m_iCharToGlyph.end() )
RageException::Throw( "The default glyph is missing from the font \"%s\".", path.c_str() );
for( unsigned i = 0; i < str.size(); ++i )
{
// If the glyph for this character is the default glyph, we're incomplete.
const glyph &g = GetGlyph( str[i] );
if( &g == m_pDefault->second )
if( &g == mapDefault->second )
return false;
}
return true;
@@ -718,8 +717,8 @@ void Font::Load( const RString &sIniPath, RString sChars )
for(unsigned i = 0; i < ImportList.size(); ++i)
{
RString path = THEME->GetPathF( "", ImportList[i], true );
if( path == "" )
RString fPath = THEME->GetPathF( "", ImportList[i], true );
if( fPath == "" )
{
RString s = ssprintf( "Font \"%s\" imports a font \"%s\" that doesn't exist", sIniPath.c_str(), ImportList[i].c_str() );
Dialog::OK( s );
@@ -727,7 +726,7 @@ void Font::Load( const RString &sIniPath, RString sChars )
}
Font subfont;
subfont.Load(path,"");
subfont.Load(fPath,"");
MergeFont(subfont);
//FONT->UnloadFont(subfont);
}
+3
View File
@@ -204,6 +204,9 @@ private:
void LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RString &sTexturePath, const RString &PageName, RString sChars );
static void GetFontPaths( const RString &sFontOrTextureFilePath, vector<RString> &sTexturePaths );
RString GetPageNameFromFileName( const RString &sFilename );
Font(const Font& rhs);
Font& operator=(const Font& rhs);
};
/**
+5 -5
View File
@@ -76,23 +76,23 @@ void Foreground::Update( float fDeltaTime )
/* Update the actor even if we're about to hide it, so queued commands
* are always run. */
float fDeltaTime;
float lDeltaTime;
if( !bga.m_bga->GetVisible() )
{
bga.m_bga->SetVisible( true );
const float fStartSecond = m_pSong->m_Timing.GetElapsedTimeFromBeat( bga.m_fStartBeat );
fDeltaTime = GAMESTATE->m_fMusicSeconds - fStartSecond;
lDeltaTime = GAMESTATE->m_fMusicSeconds - fStartSecond;
}
else
{
fDeltaTime = GAMESTATE->m_fMusicSeconds - m_fLastMusicSeconds;
lDeltaTime = GAMESTATE->m_fMusicSeconds - m_fLastMusicSeconds;
}
// This shouldn't go down, but be safe:
fDeltaTime = max( fDeltaTime, 0 );
lDeltaTime = max( lDeltaTime, 0 );
bga.m_bga->Update( fDeltaTime / fRate );
bga.m_bga->Update( lDeltaTime / fRate );
if( GAMESTATE->m_fSongBeat > bga.m_fStopBeat )
{
+2 -3
View File
@@ -93,8 +93,8 @@ bool GameCommand::DescribesCurrentMode( PlayerNumber pn ) const
if( m_pSteps == NULL && m_dc != Difficulty_Invalid )
{
// Why is this checking for all players?
FOREACH_HumanPlayer( pn )
if( GAMESTATE->m_PreferredDifficulty[pn] != m_dc )
FOREACH_HumanPlayer( human )
if( GAMESTATE->m_PreferredDifficulty[human] != m_dc )
return false;
}
@@ -412,7 +412,6 @@ void GameCommand::LoadOne( const Command& cmd )
else if( sName == "fademusic" )
{
// todo: parse things correctly. -aj
if( cmd.m_vsArgs.size() == 3 )
{
m_bFadeMusic = true;
+1 -1
View File
@@ -3064,7 +3064,7 @@ StepsType GameManager::StringToStepsType( RString sStepsType )
for( int i=0; i<NUM_StepsType; i++ )
if( g_StepsTypeInfos[i].szName == sStepsType )
return StepsType(i);
return StepsType_Invalid;
}
+10 -23
View File
@@ -159,6 +159,8 @@ GameState::GameState() :
m_Environment = new LuaTable;
m_bDopefish = false;
// Don't reset yet; let the first screen do it, so we can use PREFSMAN and THEME.
//Reset();
@@ -1447,27 +1449,6 @@ bool GameState::CurrentOptionsDisqualifyPlayer( PlayerNumber pn )
return po.IsEasierForSongAndSteps( m_pCurSong, m_pCurSteps[pn], pn);
}
/*
void GameState::LoadNoteSkinMetrics( PlayerNumber pn )
{
// Read metrics from current noteskin for setting row/col spacing and
// arrow size (originally from StepMania AMX)
if( !IsPlayerEnabled( pn ) )
return;
ASSERT( this->m_pCurSteps[pn] );
RString m_sNoteSkin = m_pPlayerState[pn]->m_PlayerOptions.GetStage().m_sNoteSkin;
RString sStepsType = StringConversion::ToString( this->m_pCurSteps[pn]->m_StepsType );
LOG->Trace("Loading Row/Col/Size values for Noteskin %s | StepsType: %s",m_sNoteSkin.c_str(),sStepsType.c_str());
//m_iNoteSkinRowSpacing[pn] = NOTESKIN->GetMetricI( m_sNoteSkin, sStepsType, "RowSpacing" );
// todo: allow per-column spacing values? -aj
m_iNoteSkinColSpacing[pn] = NOTESKIN->GetMetricI( m_sNoteSkin, sStepsType, "ColSpacing" );
m_iNoteSkinArrowSize[pn] = NOTESKIN->GetMetricI( m_sNoteSkin, sStepsType, "ArrowSize" );
}
*/
/* reset noteskins (?)
* GameState::ResetNoteSkins()
* GameState::ResetNoteSkinsForPlayer( PlayerNumber pn )
@@ -2380,9 +2361,9 @@ public:
return 1;
}
static int GetCurrentStepsCredits( T* p, lua_State *L )
static int GetCurrentStepsCredits( T* t, lua_State *L )
{
const Song* pSong = p->m_pCurSong;
const Song* pSong = t->m_pCurSong;
if( pSong == NULL )
return 0;
@@ -2466,6 +2447,11 @@ public:
p->m_pCurCharacters[Enum::Check<PlayerNumber>(L, 1)] = c;
return 0;
}
static int Dopefish( T* p, lua_State *L )
{
lua_pushboolean(L, p->m_bDopefish);
return 1;
}
LunaGameState()
{
@@ -2563,6 +2549,7 @@ public:
ADD_METHOD( GetCurMusicSeconds );
ADD_METHOD( GetCharacter );
ADD_METHOD( SetCharacter );
ADD_METHOD( Dopefish );
}
};
+5 -10
View File
@@ -214,16 +214,6 @@ public:
RageTimer m_LastBeatUpdate; // time of last m_fSongBeat, etc. update
BroadcastOnChange<bool> m_bGameplayLeadIn;
// Metricable noteskin things
/*
void LoadNoteSkinMetrics( PlayerNumber pn );
int m_iNoteSkinColSpacing[NUM_PLAYERS];
int m_iNoteSkinArrowSize[NUM_PLAYERS];
*/
// not sure I want to let noteskins change row spacing, as that changes how
// the speed mods work... -aj
//int m_iNoteSkinRowSpacing[NUM_PLAYERS];
float m_fMusicSecondsVisible;
float m_fSongBeatVisible;
@@ -348,6 +338,8 @@ public:
float GetGoalPercentComplete( PlayerNumber pn );
bool IsGoalComplete( PlayerNumber pn ) { return GetGoalPercentComplete( pn ) >= 1; }
bool m_bDopefish;
// Lua
void PushSelf( lua_State *L );
@@ -356,6 +348,9 @@ private:
EarnedExtraStage CalculateEarnedExtraStage() const;
int m_iAwardedExtraStages[NUM_PLAYERS];
bool m_bEarnedExtraStage;
GameState(const GameState& rhs);
GameState& operator=(const GameState& rhs);
};
+1 -1
View File
@@ -9,7 +9,7 @@
*
* TODO: Look into a more flexible system without a fixed number of grades. -Wolfman2000
*/
enum Grade
enum Grade
{
Grade_Tier01, /**< Usually an AAAA */
Grade_Tier02, /**< Usually an AAA */
+4 -1
View File
@@ -24,7 +24,7 @@ enum InputEventType
struct InputEvent
{
InputEvent() { type=IET_FIRST_PRESS; };
InputEvent(): type(IET_FIRST_PRESS) {}
DeviceInput di;
InputEventType type;
@@ -84,6 +84,9 @@ private:
vector<InputEvent> queue;
RageMutex *queuemutex;
MouseCoordinates m_MouseCoords;
InputFilter(const InputFilter& rhs);
InputFilter& operator=(const InputFilter& rhs);
};
extern InputFilter* INPUTFILTER; // global and accessable from anywhere in our program
+3 -4
View File
@@ -266,7 +266,6 @@ static const AutoMappings g_AutoMappings[] =
AutoMappingEntry( 0, JOY_BUTTON_10, GAME_BUTTON_BACK, false ),
AutoMappingEntry( 0, JOY_BUTTON_9, GAME_BUTTON_START, false )
),
// TODO: add black and white buttons, as well as other missing inputs -aj
AutoMappings(
"dance",
"XBOX Gamepad Plugin V0.01",
@@ -1094,12 +1093,12 @@ void InputMappings::ReadMappings( const InputScheme *pInputScheme, RString sFile
vector<RString> sDeviceInputStrings;
split( value, DEVICE_INPUT_SEPARATOR, sDeviceInputStrings, false );
for( unsigned i=0; i<sDeviceInputStrings.size() && i<unsigned(NUM_GAME_TO_DEVICE_SLOTS); i++ )
for( unsigned j=0; j<sDeviceInputStrings.size() && j<unsigned(NUM_GAME_TO_DEVICE_SLOTS); j++ )
{
DeviceInput DeviceI;
DeviceI.FromString( sDeviceInputStrings[i] );
DeviceI.FromString( sDeviceInputStrings[j] );
if( DeviceI.IsValid() )
SetInputMap( DeviceI, GameI, i );
SetInputMap( DeviceI, GameI, j );
}
}
}
+11 -17
View File
@@ -12,20 +12,12 @@ const int NUM_USER_GAME_TO_DEVICE_SLOTS = 2;
struct AutoMappingEntry
{
AutoMappingEntry( int i, DeviceButton db, GameButton gb, bool b )
{
m_iSlotIndex = i;
m_deviceButton = db;
m_gb = gb;
m_bSecondController = b;
}
AutoMappingEntry()
{
m_iSlotIndex = -1;
m_deviceButton = DeviceButton_Invalid;
m_gb = GameButton_Invalid;
m_bSecondController = false;
}
AutoMappingEntry( int i, DeviceButton db, GameButton gb, bool b ):
m_iSlotIndex(i), m_deviceButton(db),
m_gb(gb), m_bSecondController(b) {}
AutoMappingEntry(): m_iSlotIndex(-1),
m_deviceButton(DeviceButton_Invalid), m_gb(GameButton_Invalid),
m_bSecondController(false) {}
bool IsEmpty() const { return m_deviceButton == DeviceButton_Invalid && m_gb == GameButton_Invalid; }
int m_iSlotIndex;
@@ -86,10 +78,8 @@ struct AutoMappings
AutoMappingEntry im37 = AutoMappingEntry(),
AutoMappingEntry im38 = AutoMappingEntry(),
AutoMappingEntry im39 = AutoMappingEntry() )
: m_sGame(s1), m_sDriverRegex(s2), m_sControllerName(s3)
{
m_sGame = s1;
m_sDriverRegex = s2;
m_sControllerName = s3;
#define PUSH( im ) if(!im.IsEmpty()) m_vMaps.push_back(im);
PUSH(im0);PUSH(im1);PUSH(im2);PUSH(im3);PUSH(im4);PUSH(im5);PUSH(im6);PUSH(im7);PUSH(im8);PUSH(im9);PUSH(im10);PUSH(im11);PUSH(im12);PUSH(im13);PUSH(im14);PUSH(im15);PUSH(im16);PUSH(im17);PUSH(im18);PUSH(im19);
PUSH(im20);PUSH(im21);PUSH(im22);PUSH(im23);PUSH(im24);PUSH(im25);PUSH(im26);PUSH(im27);PUSH(im28);PUSH(im29);PUSH(im30);PUSH(im31);PUSH(im32);PUSH(im33);PUSH(im34);PUSH(im35);PUSH(im36);PUSH(im37);PUSH(im38);PUSH(im39);
@@ -206,6 +196,10 @@ protected:
void UpdateTempDItoGI();
const InputScheme *m_pInputScheme;
private:
InputMapper(const InputMapper& rhs);
InputMapper& operator=(const InputMapper& rhs);
};
extern InputMapper* INPUTMAPPER; // global and accessable from anywhere in our program
+2
View File
@@ -25,6 +25,8 @@ private:
void CreateImpl();
RString m_sGroup, m_sName;
ILocalizedStringImpl *m_pImpl;
// Swallow up warnings. If they must be used, define them.
LocalizedString& operator=(const LocalizedString& rhs);
};
#endif
+6
View File
@@ -42,6 +42,9 @@ public:
private:
lua_State *m_pLuaMain;
// Swallow up warnings. If they must be used, define them.
LuaManager& operator=(const LuaManager& rhs);
LuaManager(const LuaManager& rhs);
};
extern LuaManager *LUA;
@@ -155,6 +158,9 @@ private:
LuaReference *m_Name;
LuaReference *m_pOldValue;
// Swallow up warnings. If they must be used, define them.
LuaThreadVariable& operator=(const LuaThreadVariable& rhs);
};
/**
+28 -7
View File
@@ -17,15 +17,13 @@ MeterDisplay::MeterDisplay()
void MeterDisplay::Load( RString sStreamPath, float fStreamWidth, RString sTipPath )
{
m_fStreamWidth = fStreamWidth;
m_sprStream.Load( sStreamPath );
m_sprStream->SetZoomX( fStreamWidth / m_sprStream->GetUnzoomedWidth() );
this->AddChild( m_sprStream );
m_sprTip.Load( sTipPath );
this->AddChild( m_sprTip );
SetStreamWidth( fStreamWidth );
SetPercent( 0.5f );
}
@@ -33,14 +31,10 @@ void MeterDisplay::LoadFromNode( const XNode* pNode )
{
LOG->Trace( "MeterDisplay::LoadFromNode(%s)", ActorUtil::GetWhere(pNode).c_str() );
if( !pNode->GetAttrValue("StreamWidth", m_fStreamWidth) )
RageException::Throw( "%s: MeterDisplay: missing the \"StreamWidth\" attribute", ActorUtil::GetWhere(pNode).c_str() );
const XNode *pStream = pNode->GetChild( "Stream" );
if( pStream == NULL )
RageException::Throw( "%s: MeterDisplay: missing the \"Stream\" attribute", ActorUtil::GetWhere(pNode).c_str() );
m_sprStream.LoadActorFromNode( pStream, this );
m_sprStream->SetZoomX( m_fStreamWidth / m_sprStream->GetUnzoomedWidth() );
this->AddChild( m_sprStream );
const XNode* pChild = pNode->GetChild( "Tip" );
@@ -50,6 +44,10 @@ void MeterDisplay::LoadFromNode( const XNode* pNode )
this->AddChild( m_sprTip );
}
float fStreamWidth = 0;
pNode->GetAttrValue( "StreamWidth", fStreamWidth );
SetStreamWidth( fStreamWidth );
SetPercent( 0.5f );
ActorFrame::LoadFromNode( pNode );
@@ -65,6 +63,12 @@ void MeterDisplay::SetPercent( float fPercent )
m_sprTip->SetX( SCALE(fPercent, 0.f, 1.f, -m_fStreamWidth/2, m_fStreamWidth/2) );
}
void MeterDisplay::SetStreamWidth( float fStreamWidth )
{
m_fStreamWidth = fStreamWidth;
m_sprStream->SetZoomX( m_fStreamWidth / m_sprStream->GetUnzoomedWidth() );
}
void SongMeterDisplay::Update( float fDeltaTime )
{
if( GAMESTATE->m_pCurSong )
@@ -80,6 +84,23 @@ void SongMeterDisplay::Update( float fDeltaTime )
MeterDisplay::Update( fDeltaTime );
}
// lua start
#include "LuaBinding.h"
class LunaMeterDisplay: public Luna<MeterDisplay>
{
public:
static int SetStreamWidth( T* p, lua_State *L ) { p->SetStreamWidth(FArg(1)); return 0; }
LunaMeterDisplay()
{
ADD_METHOD( SetStreamWidth );
}
};
LUA_REGISTER_DERIVED_CLASS( MeterDisplay, ActorFrame )
// lua end
/*
* (c) 2003-2004 Chris Danford
* All rights reserved.
+2 -3
View File
@@ -17,10 +17,9 @@ public:
void SetPercent( float fPercent );
void SetStreamWidth( float fStreamWidth );
// Lua
// HACK: not linking right now.
// void PushSelf( lua_State *L );
void PushSelf( lua_State *L );
private:
float m_fStreamWidth;
+3 -3
View File
@@ -155,15 +155,15 @@ void ModIconRow::SetFromGameState()
continue; // skip
// search for a vacant spot
for( int i=iPerferredCol; i<NUM_OPTION_ICONS; i++ )
for( int j=iPerferredCol; j<NUM_OPTION_ICONS; j++ )
{
if( vsText[i] != "" )
if( vsText[j] != "" )
{
continue;
}
else
{
vsText[i] = sOption;
vsText[j] = sOption;
break;
}
}
+13 -9
View File
@@ -29,6 +29,7 @@ Model::Model()
m_fDefaultAnimationRate = 1;
m_fCurAnimationRate = 1;
m_bLoop = true;
m_bDrawCelShaded = false;
m_pTempGeometry = NULL;
}
@@ -288,18 +289,19 @@ bool Model::EarlyAbortDraw() const
void Model::DrawCelShaded()
{
// TODO: use shell shader for outline.
this->SetZWrite( true );
// First pass: outline/shell
// DISPLAY->SetCelShaded(1);
// First pass: shell. We only want the backfaces for this.
DISPLAY->SetCelShaded(1);
DISPLAY->SetCullMode(CULL_FRONT);
this->SetZWrite(false); // XXX: Why on earth isn't the culling working? -Colby
this->Draw();
// Second pass: normal shading
// DISPLAY->SetCelShaded(2);
// this->Draw();
// Second pass: cel shading
DISPLAY->SetCelShaded(2);
DISPLAY->SetCullMode(CULL_BACK);
this->SetZWrite(true);
this->Draw();
// DISPLAY->SetCelShaded(0)
DISPLAY->SetCelShaded(0);
}
void Model::DrawPrimitives()
@@ -779,6 +781,7 @@ public:
static int loop( T* p, lua_State *L ) { p->SetLoop(BArg(1)); return 0; }
static int rate( T* p, lua_State *L ) { p->SetRate(FArg(1)); return 0; }
static int GetNumStates( T* p, lua_State *L ) { lua_pushnumber( L, p->GetNumStates() ); return 1; }
//static int CelShading( T* p, lua_State *L ) { p->SetCelShading(BArg(1)); return 0; }
LunaModel()
{
@@ -789,6 +792,7 @@ public:
ADD_METHOD( rate );
// sm-ssc adds:
ADD_METHOD( GetNumStates );
//ADD_METHOD( CelShading );
}
};
+2
View File
@@ -39,6 +39,7 @@ public:
virtual void DrawPrimitives();
void DrawCelShaded();
void SetCelShading( bool bShading ) { m_bDrawCelShaded = bShading; }
virtual int GetNumStates() const;
virtual void SetState( int iNewState );
@@ -81,6 +82,7 @@ private:
float m_fDefaultAnimationRate;
float m_fCurAnimationRate;
bool m_bLoop;
bool m_bDrawCelShaded; // for Lua models
};
#endif
+3 -6
View File
@@ -66,12 +66,9 @@ private:
RageTexture* pTexture_,
float fDelaySecs_,
RageVector2 vTranslate_
)
{
pTexture = pTexture_;
fDelaySecs = fDelaySecs_;
vTranslate = vTranslate_;
}
):
pTexture(pTexture_), fDelaySecs(fDelaySecs_),
vTranslate(vTranslate_) {}
RageTexture* pTexture;
float fDelaySecs;
+47 -12
View File
@@ -25,10 +25,13 @@
static Preference<bool> g_bMoveRandomToEnd( "MoveRandomToEnd", false );
#define NUM_WHEEL_ITEMS ((int)ceil(NUM_WHEEL_ITEMS_TO_DRAW+2))
#define WHEEL_TEXT(s) THEME->GetString( "MusicWheel", ssprintf("%sText",s.c_str()) );
#define WHEEL_TEXT(s) THEME->GetString( "MusicWheel", ssprintf("%sText",s.c_str()) );
#define CUSTOM_ITEM_WHEEL_TEXT(s) THEME->GetString( "MusicWheel", ssprintf("CustomItem%sText",s.c_str()) );
static RString SECTION_COLORS_NAME( size_t i ) { return ssprintf("SectionColor%d",int(i+1)); }
static RString CHOICE_NAME( RString s ) { return ssprintf("Choice%s",s.c_str()); }
static RString CUSTOM_WHEEL_ITEM_NAME( RString s ) { return ssprintf("CustomWheelItem%s",s.c_str()); }
static RString CUSTOM_WHEEL_ITEM_COLOR( RString s ) { return ssprintf("%sColor",s.c_str()); }
AutoScreenMessage( SM_SongChanged ); // TODO: Replace this with a Message and MESSAGEMAN
AutoScreenMessage( SM_SortOrderChanging );
@@ -86,6 +89,12 @@ void MusicWheel::Load( RString sType )
CHOICE .Load(sType,CHOICE_NAME,vsModeChoiceNames);
SECTION_COLORS .Load(sType,SECTION_COLORS_NAME,NUM_SECTION_COLORS);
CUSTOM_WHEEL_ITEM_NAMES .Load(sType,"CustomWheelItemNames");
vector<RString> vsCustomItemNames;
split( CUSTOM_WHEEL_ITEM_NAMES, ",", vsCustomItemNames );
CUSTOM_CHOICES.Load(sType,CUSTOM_WHEEL_ITEM_NAME,vsCustomItemNames);
CUSTOM_CHOICE_COLORS.Load(sType,CUSTOM_WHEEL_ITEM_COLOR,vsCustomItemNames);
ROULETTE_COLOR .Load(sType,"RouletteColor");
RANDOM_COLOR .Load(sType,"RandomColor");
PORTAL_COLOR .Load(sType,"PortalColor");
@@ -316,7 +325,7 @@ bool MusicWheel::SelectCourse( const Course *p )
for( i=0; i<m_CurWheelItemData.size(); i++ )
{
if( GetCurWheelItemData(i)->m_pCourse == p )
m_iSelection = i; // select it
m_iSelection = i; // select it
}
return true;
@@ -324,7 +333,7 @@ bool MusicWheel::SelectCourse( const Course *p )
bool MusicWheel::SelectModeMenuItem()
{
/* Select the last-chosen option. */
// Select the last-chosen option.
ASSERT( GAMESTATE->m_SortOrder == SORT_MODE_MENU );
const vector<MusicWheelItemData *> &from = m_WheelItemDatas[GAMESTATE->m_SortOrder];
unsigned i;
@@ -360,7 +369,7 @@ void MusicWheel::GetSongList( vector<Song*> &arraySongs, SortOrder so )
SONGMAN->GetPreferredSortSongs( apAllSongs );
break;
case SORT_POPULARITY:
SONGMAN->GetPopularSongs();
apAllSongs = SONGMAN->GetPopularSongs();
break;
case SORT_GROUP:
// if we're not using sections with a preferred song group, and there
@@ -404,7 +413,7 @@ void MusicWheel::GetSongList( vector<Song*> &arraySongs, SortOrder so )
continue;
}
/* Hide locked songs. If RANDOM_PICKS_LOCKED_SONGS, hide in Roulette
/* Hide locked songs. If RANDOM_PICKS_LOCKED_SONGS, hide in Roulette
* and Random, too. */
if( (so!=SORT_ROULETTE || !RANDOM_PICKS_LOCKED_SONGS) && iLocked )
continue;
@@ -501,7 +510,6 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
{
// Make an array of Song*, then sort them
vector<Song*> arraySongs;
GetSongList( arraySongs, so );
bool bUseSections = true;
@@ -513,11 +521,16 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
// obey order specified by the preferred sort list
break;
case SORT_ROULETTE:
SongUtil::SortSongPointerArrayByStepsTypeAndMeter( arraySongs, GAMESTATE->m_pCurStyle->m_StepsType, Difficulty_Easy );
{
StepsType st;
Difficulty dc;
SongUtil::GetStepsTypeAndDifficultyFromSortOrder( SORT_EASY_METER, st, dc );
SongUtil::SortSongPointerArrayByStepsTypeAndMeter( arraySongs, st, dc );
if( (bool)PREFSMAN->m_bPreferredSortUsesGroups )
stable_sort( arraySongs.begin(), arraySongs.end(), SongUtil::CompareSongPointersByGroup );
bUseSections = false;
break;
}
case SORT_GROUP:
SongUtil::SortSongPointerArrayByGroupAndTitle( arraySongs );
if(USE_SECTIONS_WITH_PREFERRED_GROUP)
@@ -572,7 +585,6 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
ASSERT(0); // unhandled SortOrder
}
// Build an array of WheelItemDatas from the sorted list of Song*'s
arrayWheelItemDatas.clear(); // clear out the previous wheel items
arrayWheelItemDatas.reserve( arraySongs.size() );
@@ -622,7 +634,6 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
if( sThisSection != sLastSection )
{
int iSectionCount = 0;
// Count songs in this section
unsigned j;
for( j=i; j < arraySongs.size(); j++ )
@@ -651,7 +662,8 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
if( SHOW_ROULETTE )
arrayWheelItemDatas.push_back( new MusicWheelItemData(TYPE_ROULETTE, NULL, "", NULL, ROULETTE_COLOR, 0) );
// Only add TYPE_PORTAL if there's at least one song on the list.
// Only add TYPE_RANDOM and TYPE_PORTAL if there's at least
// one song on the list.
bool bFoundAnySong = false;
for( unsigned i=0; !bFoundAnySong && i < arrayWheelItemDatas.size(); i++ )
if( arrayWheelItemDatas[i]->m_Type == TYPE_SONG )
@@ -662,6 +674,23 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
if( SHOW_PORTAL && bFoundAnySong )
arrayWheelItemDatas.push_back( new MusicWheelItemData(TYPE_PORTAL, NULL, "", NULL, PORTAL_COLOR, 0) );
// add custom wheel items
vector<RString> vsNames;
split( CUSTOM_WHEEL_ITEM_NAMES, ",", vsNames );
for( unsigned i=0; i<vsNames.size(); ++i )
{
MusicWheelItemData wid( TYPE_CUSTOM, NULL, "", NULL, CUSTOM_CHOICE_COLORS.GetValue(vsNames[i]), 0 );
wid.m_pAction = HiddenPtr<GameCommand>( new GameCommand );
wid.m_pAction->m_sName = vsNames[i];
wid.m_pAction->Load( i, ParseCommands(CUSTOM_CHOICES.GetValue(vsNames[i])) );
wid.m_sLabel = CUSTOM_ITEM_WHEEL_TEXT( vsNames[i] );
if( !wid.m_pAction->IsPlayable() )
continue;
arrayWheelItemDatas.push_back( new MusicWheelItemData(wid) );
}
}
if( GAMESTATE->IsAnExtraStageAndSelectionLocked() )
@@ -808,10 +837,9 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
}
}
// init crowns
// Update the popularity and init icons.
if( so == SORT_POPULARITY )
{
// init crown icons
for( unsigned i=0; i< min(3u,arrayWheelItemDatas.size()); i++ )
{
MusicWheelItemData& WID = *arrayWheelItemDatas[i];
@@ -819,6 +847,7 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
}
}
// If we've filtered all items, insert a dummy.
if( arrayWheelItemDatas.empty() )
arrayWheelItemDatas.push_back( new MusicWheelItemData(TYPE_SECTION, NULL, "- EMPTY -", NULL, RageColor(1,0,0,1), 0) );
}
@@ -1052,6 +1081,12 @@ bool MusicWheel::Select() // return true if this selection ends the screen
ChangeSort( GAMESTATE->m_PreferredSortOrder );
m_sLastModeMenuItem = GetCurWheelItemData(m_iSelection)->m_pAction->m_sName;
return false;
case TYPE_CUSTOM:
GetCurWheelItemData(m_iSelection)->m_pAction->ApplyToAllPlayers();
if( GetCurWheelItemData(m_iSelection)->m_pAction->m_sScreen != "" )
return true;
else
return false;
}
return true;
}
+5 -2
View File
@@ -47,6 +47,7 @@ public:
// sm-ssc additions
RString JumpToNextGroup();
RString JumpToPrevGroup();
const MusicWheelItemData *GetCurWheelItemData( int i ) { return (const MusicWheelItemData *) m_CurWheelItemData[i]; }
protected:
MusicWheelItem *MakeItem();
@@ -59,8 +60,7 @@ protected:
virtual void UpdateSwitch();
vector<MusicWheelItemData *> m_WheelItemDatas[NUM_SortOrder];
const MusicWheelItemData *GetCurWheelItemData( int i ) { return (const MusicWheelItemData *) m_CurWheelItemData[i]; }
vector<MusicWheelItemData *> m_WheelItemDatas[NUM_SortOrder]; // aliases into m_UnfilteredWheelItemDatas
RString m_sLastModeMenuItem;
SortOrder m_SortOrder;
@@ -92,6 +92,9 @@ protected:
ThemeMetric<RageColor> RANDOM_COLOR;
ThemeMetric<RageColor> PORTAL_COLOR;
vector <int> m_viWheelPositions;
ThemeMetric<RString> CUSTOM_WHEEL_ITEM_NAMES;
ThemeMetricMap<RString> CUSTOM_CHOICES;
ThemeMetricMap<RageColor> CUSTOM_CHOICE_COLORS;
};
#endif
+9 -3
View File
@@ -29,6 +29,7 @@ static const char *MusicWheelItemTypeNames[] = {
"Mode",
"Random",
"Portal",
"Custom",
};
XToString( MusicWheelItemType );
@@ -78,7 +79,7 @@ MusicWheelItem::MusicWheelItem( RString sType ):
{
m_pText[i] = NULL;
// Don't init text for Type_Song. It uses a TextBanner.
// Don't init text for Type_Song. It uses a TextBanner.
if( i == MusicWheelItemType_Song )
continue;
@@ -104,7 +105,7 @@ MusicWheelItem::MusicWheelItem( RString sType ):
ActorUtil::SetXY( m_WheelNotifyIcon, "MusicWheelItem" );
m_WheelNotifyIcon.PlayCommand( "On" );
this->AddChild( &m_WheelNotifyIcon );
FOREACH_PlayerNumber( p )
{
m_pGradeDisplay[p].Load( THEME->GetPathG(sType,"grades") );
@@ -256,6 +257,10 @@ void MusicWheelItem::LoadFromWheelItemData( const WheelItemBaseData *pData, int
sDisplayName = THEME->GetString("MusicWheel","Portal");
type = MusicWheelItemType_Portal;
break;
case TYPE_CUSTOM:
sDisplayName = pWID->m_sLabel;
type = MusicWheelItemType_Custom;
break;
}
m_sprColorPart[type]->SetVisible( true );
@@ -286,10 +291,11 @@ void MusicWheelItem::LoadFromWheelItemData( const WheelItemBaseData *pData, int
msg.SetParam( "Course", pWID->m_pCourse );
msg.SetParam( "Index", iIndex );
msg.SetParam( "HasFocus", bHasFocus );
msg.SetParam( "SongGroup", pWID->m_sText );
msg.SetParam( "Text", pWID->m_sText );
msg.SetParam( "DrawIndex", iDrawIndex );
msg.SetParam( "Type", MusicWheelItemTypeToString(type) );
msg.SetParam( "Color", pWID->m_color );
msg.SetParam( "Label", pWID->m_sLabel );
this->HandleMessage( msg );
}
+1
View File
@@ -27,6 +27,7 @@ enum MusicWheelItemType
MusicWheelItemType_Mode,
MusicWheelItemType_Random,
MusicWheelItemType_Portal,
MusicWheelItemType_Custom,
NUM_MusicWheelItemType,
MusicWheelItemType_Invalid,
};
+2 -2
View File
@@ -855,9 +855,9 @@ void NoteData::GetTapNoteRangeExclusive( int iTrack, int iStartRow, int iEndRow,
--prev;
if( prev->second.type == TapNote::hold_head )
{
int iStartRow = prev->first;
int localStartRow = prev->first;
const TapNote &tn = prev->second;
if( iStartRow + tn.iDuration >= iEndRow )
if( localStartRow + tn.iDuration >= iEndRow )
end = prev;
}
}
+8 -8
View File
@@ -250,8 +250,8 @@ static void LoadFromSMNoteDataStringWithPlayer( NoteData& out, const RString &sS
for( int t=0; t<out.GetNumTracks(); t++ )
{
NoteData::iterator begin = out.begin( t );
NoteData::iterator end = out.end( t );
while( begin != end )
NoteData::iterator lEnd = out.end( t );
while( begin != lEnd )
{
NoteData::iterator next = Increment( begin );
const TapNote &tn = begin->second;
@@ -679,12 +679,9 @@ int FindLongestOverlappingHoldNoteForAnyTrack( const NoteData &in, int iRow )
int iMaxTailRow = -1;
for( int t=0; t<in.GetNumTracks(); t++ )
{
for( int t=0; t<in.GetNumTracks(); t++ )
{
const TapNote &tn = in.GetTapNote( t, iRow );
if( tn.type == TapNote::hold_head )
iMaxTailRow = max( iMaxTailRow, iRow + tn.iDuration );
}
const TapNote &tn = in.GetTapNote( t, iRow );
if( tn.type == TapNote::hold_head )
iMaxTailRow = max( iMaxTailRow, iRow + tn.iDuration );
}
return iMaxTailRow;
@@ -2070,6 +2067,9 @@ const ValidRow g_ValidRows[] =
{ StepsType_dance_double, { f,T,T,T,T,f,f,f } },
{ StepsType_dance_double, { f,f,f,T,T,T,T,f } },
{ StepsType_dance_double, { f,f,f,f,T,T,T,T } },
{ StepsType_pump_double, { T,T,T,T,T,f,f,f,f,f } },
{ StepsType_pump_double, { f,f,T,T,T,T,T,T,f,f } },
{ StepsType_pump_double, { f,f,f,f,f,T,T,T,T,T } },
};
#undef T
#undef f
+14
View File
@@ -24,7 +24,21 @@ namespace NoteDataUtil
void GetSMNoteDataString( const NoteData &in, RString &notes_out );
void SplitCompositeNoteData( const NoteData &in, vector<NoteData> &out );
void CombineCompositeNoteData( NoteData &out, const vector<NoteData> &in );
/**
* @brief Autogenerate notes from one type to another.
*
* TODO: Look into a more intelligent way of doing so.
* @param in The original NoteData.
* @param out the new NoteData.
* @param iNewNumTracks the number of tracks/columns of the new NoteData. */
void LoadTransformedSlidingWindow( const NoteData &in, NoteData &out, int iNewNumTracks );
/**
* @brief Autogenerate notes from one type to another.
*
* NOTE: This code assumes that there are more columns in the original type.
* @param in The original NoteData.
* @param out the new NoteData.
* @param iNewNumTracks the number of tracks/columns of the new NoteData. */
void LoadOverlapped( const NoteData &in, NoteData &out, int iNewNumTracks );
void LoadTransformedLights( const NoteData &in, NoteData &out, int iNewNumTracks );
void LoadTransformedLightsFromTwo( const NoteData &marquee, const NoteData &bass, NoteData &out );
+1 -1
View File
@@ -123,7 +123,7 @@ struct NoteResource
delete m_pActor;
}
const NoteSkinAndPath m_nsap; /* should be refcounted along with g_NoteResource[] */
const NoteSkinAndPath m_nsap; // should be refcounted along with g_NoteResource[]
int m_iRefCount;
Actor *m_pActor; // todo: AutoActor me? -aj
};
+152 -110
View File
@@ -183,35 +183,34 @@ void NoteField::Load(
//int i2 = GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer;
ASSERT_M( m_pNoteData->GetNumTracks() == GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer,
ssprintf("%d = %d",m_pNoteData->GetNumTracks(), GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer) );
ssprintf("NumTracks %d = ColsPerPlayer %d",m_pNoteData->GetNumTracks(), GAMESTATE->GetCurrentStyle()->m_iColsPerPlayer) );
// The note skin may have changed at the beginning of a new course song.
// The NoteSkin may have changed at the beginning of a new course song.
RString sNoteSkinLower = m_pPlayerState->m_PlayerOptions.GetCurrent().m_sNoteSkin;
/* XXX: Combination of good idea and bad idea to ensure
* courses load regardless of noteskin content.
* This may take awhile to fix. */
/* XXX: Combination of good idea and bad idea to ensure courses load
* regardless of noteskin content. This may take a while to fix. */
NoteDisplayCols *badIdea = m_pCurDisplay;
if (sNoteSkinLower.empty())
{
sNoteSkinLower = m_pPlayerState->m_PlayerOptions.GetPreferred().m_sNoteSkin;
if (sNoteSkinLower.empty())
{
sNoteSkinLower = "default";
}
m_NoteDisplays.insert(pair<RString, NoteDisplayCols *> (sNoteSkinLower, badIdea));
}
sNoteSkinLower.MakeLower();
map<RString, NoteDisplayCols *>::iterator it = m_NoteDisplays.find( sNoteSkinLower );
ASSERT_M( it != m_NoteDisplays.end(), sNoteSkinLower );
memset( m_pDisplays, 0, sizeof(m_pDisplays) );
FOREACH_EnabledPlayer( pn )
{
RString sNoteSkinLower = GAMESTATE->m_pPlayerState[pn]->m_PlayerOptions.GetCurrent().m_sNoteSkin;
sNoteSkinLower = GAMESTATE->m_pPlayerState[pn]->m_PlayerOptions.GetCurrent().m_sNoteSkin;
// XXX: Re-setup sNoteSkinLower. Unsure if inserting the skin again is needed.
if (sNoteSkinLower.empty())
{
@@ -314,11 +313,20 @@ void NoteField::DrawBeatBar( const float fBeat, BeatBarType type, int iMeasureIn
fScrollSpeed = 4;
switch( type )
{
DEFAULT_FAIL( type );
case measure:
case beat: fAlpha = BAR_4TH_ALPHA; iState = 1; break;
case half_beat: fAlpha = SCALE(fScrollSpeed,1.0f,2.0f,0.0f,BAR_8TH_ALPHA); iState = 2; break;
case quarter_beat: fAlpha = SCALE(fScrollSpeed,2.0f,4.0f,0.0f,BAR_16TH_ALPHA); iState = 3; break;
DEFAULT_FAIL( type );
case measure: // handled above
case beat: // fall through
fAlpha = BAR_4TH_ALPHA;
iState = 1;
break;
case half_beat:
fAlpha = SCALE(fScrollSpeed,1.0f,2.0f,0.0f,BAR_8TH_ALPHA);
iState = 2;
break;
case quarter_beat:
fAlpha = SCALE(fScrollSpeed,2.0f,4.0f,0.0f,BAR_16TH_ALPHA);
iState = 3;
break;
}
CLAMP( fAlpha, 0, 1 );
}
@@ -352,7 +360,7 @@ void NoteField::DrawBoard( int iDrawDistanceAfterTargetsPixels, int iDrawDistanc
{
// Draw the board centered on fYPosAt0 so that the board doesn't slide as
// the draw distance changes with modifiers.
const float fYPosAt0 = ArrowEffects::GetYPos( m_pPlayerState, 0, 0, m_fYReverseOffsetPixels );
const float fYPosAt0 = ArrowEffects::GetYPos( m_pPlayerState, 0, 0, m_fYReverseOffsetPixels );
// todo: make this an AutoActor instead? -aj
Sprite *pSprite = dynamic_cast<Sprite *>( (Actor*)m_sprBoard );
@@ -386,7 +394,6 @@ void NoteField::DrawMarkerBar( int iBeat )
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
m_rectMarkerBar.StretchTo( RectF(-GetWidth()/2, fYPos-ARROW_SIZE/2, GetWidth()/2, fYPos+ARROW_SIZE/2) );
m_rectMarkerBar.Draw();
}
@@ -417,16 +424,19 @@ static ThemeMetric<RageColor> STOP_COLOR ( "NoteField", "StopColor" );
static ThemeMetric<RageColor> DELAY_COLOR ( "NoteField", "DelayColor" );
static ThemeMetric<RageColor> TIME_SIGNATURE_COLOR ( "NoteField", "TimeSignatureColor" );
static ThemeMetric<RageColor> TICKCOUNT_COLOR ( "NoteField", "TickcountColor" );
static ThemeMetric<RageColor> COMBO_COLOR ( "NoteField", "ComboColor" );
static ThemeMetric<bool> BPM_IS_LEFT_SIDE ( "NoteField", "BPMIsLeftSide" );
static ThemeMetric<bool> STOP_IS_LEFT_SIDE ( "NoteField", "StopIsLeftSide" );
static ThemeMetric<bool> DELAY_IS_LEFT_SIDE ( "NoteField", "DelayIsLeftSide" );
static ThemeMetric<bool> TIME_SIGNATURE_IS_LEFT_SIDE ( "NoteField", "TimeSignatureIsLeftSide" );
static ThemeMetric<bool> TICKCOUNT_IS_LEFT_SIDE ( "NoteField", "TickcountIsLeftSide" );
static ThemeMetric<bool> COMBO_IS_LEFT_SIDE ( "NoteField", "ComboIsLeftSide" );
static ThemeMetric<float> BPM_OFFSETX ( "NoteField", "BPMOffsetX" );
static ThemeMetric<float> STOP_OFFSETX ( "NoteField", "StopOffsetX" );
static ThemeMetric<float> DELAY_OFFSETX ( "NoteField", "DelayOffsetX" );
static ThemeMetric<float> TIME_SIGNATURE_OFFSETX ( "NoteField", "TimeSignatureOffsetX" );
static ThemeMetric<float> TICKCOUNT_OFFSETX ( "NoteField", "TickcountOffsetX" );
static ThemeMetric<float> COMBO_OFFSETX ( "NoteField", "ComboOffsetX" );
void NoteField::DrawBPMText( const float fBeat, const float fBPM )
{
@@ -505,6 +515,23 @@ void NoteField::DrawTickcountText( const float fBeat, int iTicks )
m_textMeasureNumber.Draw();
}
void NoteField::DrawComboText( const float fBeat, int iCombo )
{
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
const float xBase = GetWidth()/2.f;
const float xOffset = COMBO_OFFSETX * fZoom;
m_textMeasureNumber.SetZoom( fZoom );
m_textMeasureNumber.SetHorizAlign( COMBO_IS_LEFT_SIDE ? align_right : align_left );
m_textMeasureNumber.SetDiffuse( COMBO_COLOR );
m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) );
m_textMeasureNumber.SetText( ssprintf("%d", iCombo) );
m_textMeasureNumber.SetXY( (COMBO_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos );
m_textMeasureNumber.Draw();
}
void NoteField::DrawAttackText( const float fBeat, const Attack &attack )
{
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
@@ -523,8 +550,8 @@ void NoteField::DrawAttackText( const float fBeat, const Attack &attack )
void NoteField::DrawBGChangeText( const float fBeat, const RString sNewBGName )
{
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
m_textMeasureNumber.SetZoom( fZoom );
m_textMeasureNumber.SetHorizAlign( align_left );
@@ -542,7 +569,7 @@ float FindFirstDisplayedBeat( const PlayerState* pPlayerState, int iDrawDistance
float fFirstBeatToDraw = GAMESTATE->m_fSongBeat-4; // Adjust to balance off performance and showing enough notes.
/* In Boomerang, we'll usually have two sections of notes: before and after
* the peak. We always start drawing before the peak, and end after it, or
* the peak. We always start drawing before the peak, and end after it, or
* we may falsely detect the off-screen portion as the end (or beginning)
* of the stream. */
bool bBoomerang;
@@ -558,23 +585,22 @@ float FindFirstDisplayedBeat( const PlayerState* pPlayerState, int iDrawDistance
float fYOffset = ArrowEffects::GetYOffset( pPlayerState, 0, fFirstBeatToDraw, fPeakYOffset, bIsPastPeakYOffset, true );
if( bBoomerang && bIsPastPeakYOffset )
break; // stop probing
else if( fYOffset < iDrawDistanceAfterTargetsPixels ) // off screen
fFirstBeatToDraw += 0.1f; // move toward fSongBeat
else // on screen
break; // stop probing
break; // stop probing
else if( fYOffset < iDrawDistanceAfterTargetsPixels ) // off screen
fFirstBeatToDraw += 0.1f; // move toward fSongBeat
else // on screen
break; // stop probing
}
fFirstBeatToDraw -= 0.1f; // rewind if we intentionally overshot
fFirstBeatToDraw -= 0.1f; // rewind if we intentionally overshot
return fFirstBeatToDraw;
}
float FindLastDisplayedBeat( const PlayerState* pPlayerState, int iDrawDistanceBeforeTargetsPixels )
{
// Probe for last note to draw.
// worst case is 0.25x + boost. Adjust search distance to
// so that notes don't pop onto the screen.
// Probe for last note to draw. Worst case is 0.25x + boost.
// Adjust search distance so that notes don't pop onto the screen.
float fSearchDistance = 10;
float fLastBeatToDraw = GAMESTATE->m_fSongBeat+fSearchDistance;
float fLastBeatToDraw = GAMESTATE->m_fSongBeat+fSearchDistance;
const int NUM_ITERATIONS = 20;
@@ -632,8 +658,8 @@ void NoteField::DrawPrimitives()
// Adjust draw range depending on some effects
int iDrawDistanceAfterTargetsPixels = m_iDrawDistanceAfterTargetsPixels;
// HACK: if boomerang and centered are on, then we want to draw much
// earlier to that the notes don't pop on screen.
// HACK: If boomerang and centered are on, then we want to draw much
// earlier so that the notes don't pop on screen.
float fCenteredTimesBoomerang =
current_po.m_fScrolls[PlayerOptions::SCROLL_CENTERED] *
current_po.m_fAccels[PlayerOptions::ACCEL_BOOMERANG];
@@ -657,8 +683,8 @@ void NoteField::DrawPrimitives()
const int iFirstRowToDraw = BeatToNoteRow(fFirstBeatToDraw);
const int iLastRowToDraw = BeatToNoteRow(fLastBeatToDraw);
// LOG->Trace( "start = %f.1, end = %f.1", fFirstBeatToDraw-fSongBeat, fLastBeatToDraw-fSongBeat );
// LOG->Trace( "Drawing elements %d through %d", iFirstRowToDraw, iLastRowToDraw );
//LOG->Trace( "start = %f.1, end = %f.1", fFirstBeatToDraw-fSongBeat, fLastBeatToDraw-fSongBeat );
//LOG->Trace( "Drawing elements %d through %d", iFirstRowToDraw, iLastRowToDraw );
#define IS_ON_SCREEN( fBeat ) IsOnScreen( fBeat, 0, iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels )
@@ -757,7 +783,7 @@ void NoteField::DrawPrimitives()
DrawTimeSignatureText( fBeat, vTimeSignatureSegments[i].m_iNumerator, vTimeSignatureSegments[i].m_iDenominator );
}
}
// Tickcount text
const vector<TickcountSegment> &tTickcountSegments = GAMESTATE->m_pCurSong->m_Timing.m_TickcountSegments;
for( unsigned i=0; i<tTickcountSegments.size(); i++ )
@@ -770,6 +796,19 @@ void NoteField::DrawPrimitives()
DrawTickcountText( fBeat, tTickcountSegments[i].m_iTicks );
}
}
// Combo text
const vector<ComboSegment> &tComboSegments = GAMESTATE->m_pCurSong->m_Timing.m_ComboSegments;
for( unsigned i=0; i<tComboSegments.size(); i++ )
{
if( tComboSegments[i].m_iStartRow >= iFirstRowToDraw &&
tComboSegments[i].m_iStartRow <= iLastRowToDraw)
{
float fBeat = NoteRowToBeat(tComboSegments[i].m_iStartRow);
if( IS_ON_SCREEN(fBeat) )
DrawComboText( fBeat, tComboSegments[i].m_iCombo );
}
}
// todo: add warp text -aj
@@ -797,67 +836,67 @@ void NoteField::DrawPrimitives()
// BGChange text
switch( GAMESTATE->m_EditMode )
{
case EditMode_Home:
case EditMode_CourseMods:
case EditMode_Practice:
break;
case EditMode_Full:
{
vector<BackgroundChange>::iterator iter[NUM_BackgroundLayer];
FOREACH_BackgroundLayer( i )
iter[i] = GAMESTATE->m_pCurSong->GetBackgroundChanges(i).begin();
while( 1 )
case EditMode_Home:
case EditMode_CourseMods:
case EditMode_Practice:
break;
case EditMode_Full:
{
float fLowestBeat = FLT_MAX;
vector<BackgroundLayer> viLowestIndex;
vector<BackgroundChange>::iterator iter[NUM_BackgroundLayer];
FOREACH_BackgroundLayer( i )
iter[i] = GAMESTATE->m_pCurSong->GetBackgroundChanges(i).begin();
while( 1 )
{
if( iter[i] == GAMESTATE->m_pCurSong->GetBackgroundChanges(i).end() )
continue;
float fBeat = iter[i]->m_fStartBeat;
if( fBeat < fLowestBeat )
{
fLowestBeat = fBeat;
viLowestIndex.clear();
viLowestIndex.push_back( i );
}
else if( fBeat == fLowestBeat )
{
viLowestIndex.push_back( i );
}
}
if( viLowestIndex.empty() )
{
float fLowestBeat = FLT_MAX;
vector<BackgroundLayer> viLowestIndex;
FOREACH_BackgroundLayer( i )
ASSERT( iter[i] == GAMESTATE->m_pCurSong->GetBackgroundChanges(i).end() );
break;
}
if( IS_ON_SCREEN(fLowestBeat) )
{
vector<RString> vsBGChanges;
FOREACH_CONST( BackgroundLayer, viLowestIndex, i )
{
ASSERT( iter[*i] != GAMESTATE->m_pCurSong->GetBackgroundChanges(*i).end() );
const BackgroundChange& change = *iter[*i];
RString s = change.GetTextDescription();
if( *i!=0 )
s = ssprintf("%d: ",*i) + s;
vsBGChanges.push_back( s );
if( iter[i] == GAMESTATE->m_pCurSong->GetBackgroundChanges(i).end() )
continue;
float fBeat = iter[i]->m_fStartBeat;
if( fBeat < fLowestBeat )
{
fLowestBeat = fBeat;
viLowestIndex.clear();
viLowestIndex.push_back( i );
}
else if( fBeat == fLowestBeat )
{
viLowestIndex.push_back( i );
}
}
DrawBGChangeText( fLowestBeat, join("\n",vsBGChanges) );
if( viLowestIndex.empty() )
{
FOREACH_BackgroundLayer( i )
ASSERT( iter[i] == GAMESTATE->m_pCurSong->GetBackgroundChanges(i).end() );
break;
}
if( IS_ON_SCREEN(fLowestBeat) )
{
vector<RString> vsBGChanges;
FOREACH_CONST( BackgroundLayer, viLowestIndex, i )
{
ASSERT( iter[*i] != GAMESTATE->m_pCurSong->GetBackgroundChanges(*i).end() );
const BackgroundChange& change = *iter[*i];
RString s = change.GetTextDescription();
if( *i!=0 )
s = ssprintf("%d: ",*i) + s;
vsBGChanges.push_back( s );
}
DrawBGChangeText( fLowestBeat, join("\n",vsBGChanges) );
}
FOREACH_CONST( BackgroundLayer, viLowestIndex, i )
iter[*i]++;
}
FOREACH_CONST( BackgroundLayer, viLowestIndex, i )
iter[*i]++;
}
}
break;
default:
ASSERT(0);
break;
default:
ASSERT(0);
}
// Draw marker bars
@@ -884,9 +923,9 @@ void NoteField::DrawPrimitives()
}
// Optimization is very important here because there are so many arrows to draw.
// Draw the arrows in order of column. This minimize texture switches and let us
// draw in big batches.
// Optimization is very important here because there are so many arrows to draw.
// Draw the arrows in order of column. This minimizes texture switches and
// lets us draw in big batches.
float fSelectedRangeGlow = SCALE( RageFastCos(RageTimer::GetTimeSinceStartFast()*2), -1, 1, 0.1f, 0.3f );
@@ -908,11 +947,11 @@ void NoteField::DrawPrimitives()
{
const TapNote &tn = begin->second; //m_pNoteData->GetTapNote(c, i);
if( tn.type != TapNote::hold_head )
continue; // skip
continue; // skip
const HoldNoteResult &Result = tn.HoldResult;
if( Result.hns == HNS_Held ) // if this HoldNote was completed
continue; // don't draw anything
if( Result.hns == HNS_Held ) // if this HoldNote was completed
continue; // don't draw anything
int iStartRow = begin->first;
int iEndRow = iStartRow + tn.iDuration;
@@ -962,26 +1001,25 @@ void NoteField::DrawPrimitives()
// Draw all TapNotes in this column
// draw notes from furthest to closest
NoteData::TrackMap::const_iterator begin, end;
m_pNoteData->GetTapNoteRange( c, iFirstRowToDraw, iLastRowToDraw+1, begin, end );
for( ; begin != end; ++begin )
{
int i = begin->first;
const TapNote &tn = begin->second; //m_pNoteData->GetTapNote(c, i);
int q = begin->first;
const TapNote &tn = begin->second; //m_pNoteData->GetTapNote(c, q);
// Switch modified by Wolfman2000, tested by Saturn2888
// Fixes hold head overlapping issue, but not the rolls.
switch( tn.type )
{
case TapNote::empty: // no note here
case TapNote::empty: // no note here
{
continue;
}
case TapNote::hold_head:
case TapNote::hold_head:
{
//if (tn.subType == TapNote::hold_head_roll)
continue; // skip
continue; // skip
}
}
@@ -992,11 +1030,12 @@ void NoteField::DrawPrimitives()
// TRICKY: If boomerang is on, then all notes in the range
// [iFirstRowToDraw,iLastRowToDraw] aren't necessarily visible.
// Test every note to make sure it's on screen before drawing
if( !IsOnScreen( NoteRowToBeat(i), c, iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels ) )
continue; // skip
// Test every note to make sure it's on screen before drawing.
if( !IsOnScreen( NoteRowToBeat(q), c, iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels ) )
continue; // skip
ASSERT_M( NoteRowToBeat(i) > -2000, ssprintf("%i %i %i, %f %f", i, iLastRowToDraw, iFirstRowToDraw, GAMESTATE->m_fSongBeat, GAMESTATE->m_fMusicSeconds) );
ASSERT_M( NoteRowToBeat(q) > -2000, ssprintf("%i %i %i, %f %f", q, iLastRowToDraw,
iFirstRowToDraw, GAMESTATE->m_fSongBeat, GAMESTATE->m_fMusicSeconds) );
// See if there is a hold step that begins on this index.
// Only do this if the noteskin cares.
@@ -1005,7 +1044,7 @@ void NoteField::DrawPrimitives()
{
for( int c2=0; c2<m_pNoteData->GetNumTracks(); c2++ )
{
if( m_pNoteData->GetTapNote(c2, i).type == TapNote::hold_head)
if( m_pNoteData->GetTapNote(c2, q).type == TapNote::hold_head)
{
bHoldNoteBeginsOnThisBeat = true;
break;
@@ -1015,15 +1054,18 @@ void NoteField::DrawPrimitives()
bool bIsInSelectionRange = false;
if( m_iBeginMarker!=-1 && m_iEndMarker!=-1 )
bIsInSelectionRange = m_iBeginMarker<=i && i<m_iEndMarker;
bIsInSelectionRange = m_iBeginMarker<=q && q<m_iEndMarker;
bool bIsAddition = (tn.source == TapNote::addition);
bool bIsHopoPossible = (tn.bHopoPossible);
bool bUseAdditionColoring = bIsAddition || bIsHopoPossible;
NoteDisplayCols *displayCols = tn.pn == PLAYER_INVALID ? m_pCurDisplay : m_pDisplays[tn.pn];
displayCols->display[c].DrawTap( tn, c, NoteRowToBeat(i), bHoldNoteBeginsOnThisBeat, bUseAdditionColoring, bIsInSelectionRange ? fSelectedRangeGlow : m_fPercentFadeToFail, m_fYReverseOffsetPixels, iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels, FADE_BEFORE_TARGETS_PERCENT );
displayCols->display[c].DrawTap( tn, c, NoteRowToBeat(q), bHoldNoteBeginsOnThisBeat,
bUseAdditionColoring, bIsInSelectionRange ? fSelectedRangeGlow : m_fPercentFadeToFail,
m_fYReverseOffsetPixels, iDrawDistanceAfterTargetsPixels, iDrawDistanceBeforeTargetsPixels,
FADE_BEFORE_TARGETS_PERCENT );
bool bNoteIsUpcoming = NoteRowToBeat(i) > GAMESTATE->m_fSongBeat;
bool bNoteIsUpcoming = NoteRowToBeat(q) > GAMESTATE->m_fSongBeat;
bAnyUpcomingInThisCol |= bNoteIsUpcoming;
}
+1
View File
@@ -59,6 +59,7 @@ protected:
void DrawFreezeText( const float fBeat, const float fBPM, const float bDelay );
void DrawTimeSignatureText( const float fBeat, int iNumerator, int iDenominator );
void DrawTickcountText( const float fBeat, int iTicks );
void DrawComboText( const float fBeat, int iCombo );
void DrawAttackText( const float fBeat, const Attack &attack );
void DrawBGChangeText( const float fBeat, const RString sNewBGName );
float GetWidth() const;
+8 -9
View File
@@ -194,10 +194,9 @@ void NoteSkinManager::GetNoteSkinNames( const Game* pGame, vector<RString> &AddT
GetAllNoteSkinNamesForGame( pGame, AddTo );
}
bool NoteSkinManager::DoesNoteSkinExist( const RString &sSkinName )
{
vector<RString> asSkinNames;
vector<RString> asSkinNames;
GetAllNoteSkinNamesForGame( GAMESTATE->m_pCurGame, asSkinNames );
for( unsigned i=0; i<asSkinNames.size(); i++ )
if( 0==stricmp(sSkinName, asSkinNames[i]) )
@@ -283,22 +282,22 @@ try_again:
const NoteSkinData &data = iter->second;
RString sPath; // fill this in below
FOREACH_CONST( RString, data.vsDirSearchOrder, iter )
FOREACH_CONST( RString, data.vsDirSearchOrder, lIter )
{
if( sButtonName.empty() )
sPath = GetPathFromDirAndFile( *iter, sElement );
sPath = GetPathFromDirAndFile( *lIter, sElement );
else
sPath = GetPathFromDirAndFile( *iter, sButtonName+" "+sElement );
sPath = GetPathFromDirAndFile( *lIter, sButtonName+" "+sElement );
if( !sPath.empty() )
break; // done searching
}
if( sPath.empty() )
{
FOREACH_CONST( RString, data.vsDirSearchOrder, iter )
FOREACH_CONST( RString, data.vsDirSearchOrder, lIter )
{
if( !sButtonName.empty() )
sPath = GetPathFromDirAndFile( *iter, "Fallback "+sElement );
sPath = GetPathFromDirAndFile( *lIter, "Fallback "+sElement );
if( !sPath.empty() )
break; // done searching
}
@@ -341,9 +340,9 @@ try_again:
GetFileContents( sPath, sNewFileName, true );
RString sRealPath;
FOREACH_CONST( RString, data.vsDirSearchOrder, iter )
FOREACH_CONST( RString, data.vsDirSearchOrder, lIter )
{
sRealPath = GetPathFromDirAndFile( *iter, sNewFileName );
sRealPath = GetPathFromDirAndFile( *lIter, sNewFileName );
if( !sRealPath.empty() )
break; // done searching
}
+59 -19
View File
@@ -93,8 +93,8 @@ struct TapNote
/** @brief The list of a TapNote's sub types. */
enum SubType
{
hold_head_hold,
hold_head_roll,
hold_head_hold, /**< The start of a traditional hold note. */
hold_head_roll, /**< The start of a roll note that must be hit repeatedly. */
//hold_head_mine,
NUM_SubType,
SubType_Invalid
@@ -133,10 +133,10 @@ struct TapNote
XNode* CreateNode() const;
void LoadFromNode( const XNode* pNode );
TapNote()
{
Init();
}
TapNote(): type(empty), subType(SubType_Invalid), source(original),
pn(PLAYER_INVALID), bHopoPossible(false),
sAttackModifiers(""), fAttackDurationSeconds(0),
iKeysoundIndex(-1), iDuration(0) {}
void Init()
{
type = empty;
@@ -154,18 +154,16 @@ struct TapNote
Source source_,
RString sAttackModifiers_,
float fAttackDurationSeconds_,
int iKeysoundIndex_ )
{
Init();
type = type_;
subType = subType_;
source = source_;
sAttackModifiers = sAttackModifiers_;
fAttackDurationSeconds = fAttackDurationSeconds_;
iKeysoundIndex = iKeysoundIndex_;
iDuration = 0;
pn = PLAYER_INVALID;
}
int iKeysoundIndex_ ):
type(type_), subType(subType_), source(source_),
pn(PLAYER_INVALID), sAttackModifiers(sAttackModifiers_),
fAttackDurationSeconds(fAttackDurationSeconds_),
iKeysoundIndex(iKeysoundIndex_), iDuration(0) {}
/**
* @brief Determine if the two TapNotes are equal to each other.
* @param other the other TapNote we're checking.
* @return true if the two TapNotes are equal, or false otherwise. */
bool operator==( const TapNote &other ) const
{
#define COMPARE(x) if(x!=other.x) return false
@@ -180,6 +178,10 @@ struct TapNote
#undef COMPARE
return true;
}
/**
* @brief Determine if the two TapNotes are not equal to each other.
* @param other the other TapNote we're checking.
* @return true if the two TapNotes are not equal, or false otherwise. */
bool operator!=( const TapNote &other ) const { return !operator==( other ); }
};
@@ -196,6 +198,29 @@ extern TapNote TAP_ORIGINAL_FAKE; // 'F'
extern TapNote TAP_ADDITION_TAP;
extern TapNote TAP_ADDITION_MINE;
/**
* @brief Retrieve the string representing the TapNote Type.
*
* TODO: Find a way to standardize this with the other enum string calls.
* @param tn the TapNote's type.
* @return the intended string. */
inline const RString TapNoteTypeToString( TapNote::Type tn )
{
switch( tn )
{
case TapNote::empty: return RString("empty");
case TapNote::tap: return RString("tap");
case TapNote::hold_head: return RString("hold_head");
case TapNote::hold_tail: return RString("hold_tail");
case TapNote::mine: return RString("mine");
case TapNote::lift: return RString("lift");
case TapNote::attack: return RString("attack");
case TapNote::autoKeysound: return RString("autoKeysound");
case TapNote::fake: return RString("fake");
default: return RString();
}
}
/**
* @brief The number of tracks allowed.
*
@@ -207,7 +232,10 @@ const int MAX_NOTE_TRACKS = 16;
* @brief The number of rows per beat.
*
* This is a divisor for our "fixed-point" time/beat representation. It must be
* evenly divisible by 2, 3, and 4, to exactly represent 8th, 12th and 16th notes. */
* evenly divisible by 2, 3, and 4, to exactly represent 8th, 12th and 16th notes.
*
* XXX: Some other forks try to keep this flexible by putting this in the simfile.
* Is this a recommended course of action? -Wolfman2000 */
const int ROWS_PER_BEAT = 48;
/**
@@ -254,8 +282,20 @@ inline int BeatToNoteRow( float fBeatNum )
return integer + lrintf(fraction * ROWS_PER_BEAT);
}
*/
/**
* @brief Convert the beat into a note row.
* @param fBeatNum the beat to convert.
* @return the note row. */
inline int BeatToNoteRow( float fBeatNum ) { return lrintf( fBeatNum * ROWS_PER_BEAT ); } // round
/**
* @brief Convert the beat into a note row without rounding.
* @param fBeatNum the beat to convert.
* @return the note row. */
inline int BeatToNoteRowNotRounded( float fBeatNum ) { return (int)( fBeatNum * ROWS_PER_BEAT ); }
/**
* @brief Convert the note row to a beat.
* @param iRow the row to convert.
* @return the beat. */
inline float NoteRowToBeat( int iRow ) { return iRow / (float)ROWS_PER_BEAT; }
#endif
+13 -13
View File
@@ -477,9 +477,9 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
if( sNoteId != "00" )
{
vTapNotes.push_back( TAP_ORIGINAL_TAP );
map<RString,int>::const_iterator it = idToKeySoundIndex.find( sNoteId );
if( it != idToKeySoundIndex.end() )
vTapNotes.back().iKeysoundIndex = it->second;
map<RString,int>::const_iterator rInt = idToKeySoundIndex.find( sNoteId );
if( rInt != idToKeySoundIndex.end() )
vTapNotes.back().iKeysoundIndex = rInt->second;
}
else
{
@@ -782,7 +782,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
continue;
// this is keysound file name. Looks like "#WAV1A"
RString sData = it->second;
RString nData = it->second;
RString sWavID = sName.Right(2);
// FIXME: garbled song names seem to crash the app.
@@ -794,24 +794,24 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
* on files in the BMS for files that actually have some other extension.
* Do a search. Don't do a wildcard search; if sData is "song.wav",
* we might also have "song.png", which we shouldn't match. */
if( !IsAFile(out.GetSongDir()+sData) )
if( !IsAFile(out.GetSongDir()+nData) )
{
const char *exts[] = { "oga", "ogg", "wav", "mp3", NULL }; // XXX: stop duplicating these everywhere
for( unsigned i = 0; exts[i] != NULL; ++i )
{
RString fn = SetExtension( sData, exts[i] );
RString fn = SetExtension( nData, exts[i] );
if( IsAFile(out.GetSongDir()+fn) )
{
sData = fn;
nData = fn;
break;
}
}
}
if( !IsAFile(out.GetSongDir()+sData) )
LOG->UserLog( "Song file", out.GetSongDir(), "references key \"%s\" that can't be found", sData.c_str() );
if( !IsAFile(out.GetSongDir()+nData) )
LOG->UserLog( "Song file", out.GetSongDir(), "references key \"%s\" that can't be found", nData.c_str() );
sWavID.MakeUpper(); // HACK: undo the MakeLower()
out.m_vsKeysoundFile.push_back( sData );
out.m_vsKeysoundFile.push_back( nData + "" );
idToKeySoundIndexOut[ sWavID ] = out.m_vsKeysoundFile.size()-1;
LOG->Trace( "Inserting keysound index %u '%s'", unsigned(out.m_vsKeysoundFile.size()-1), sWavID.c_str() );
}
@@ -832,11 +832,11 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
float fBeatsPerMeasure = GetBeatsPerMeasure( mapMeasureToTimeSig, iMeasureNo, sigAdjustmentsOut );
int iRowsPerMeasure = BeatToNoteRow( fBeatsPerMeasure );
RString sData = it->second;
int totalPairs = sData.size() / 2;
RString nData = it->second;
int totalPairs = nData.size() / 2;
for( int i = 0; i < totalPairs; ++i )
{
RString sPair = sData.substr( i*2, 2 );
RString sPair = nData.substr( i*2, 2 );
int iRow = iStepIndex + (i * iRowsPerMeasure) / totalPairs;
float fBeat = NoteRowToBeat( iRow );
+5 -5
View File
@@ -750,9 +750,9 @@ static bool LoadFromMidi( const RString &sPath, Song &songOut )
if( uVelocity == 0 )
midiEventType = note_off;
MidiEvent event = { count, midiEventType };
MidiEvent mEvent = { count, midiEventType };
//float fBeat = NoteRowToBeat( MidiCountToNoteRow(count) );
vMidiEvent[uNoteNumber].push_back( event );
vMidiEvent[uNoteNumber].push_back( mEvent );
}
break;
default:
@@ -850,13 +850,13 @@ skip_track:
// hold note ending on the same row as a tap note.
NoteData::TrackMap::iterator begin, end;
noteData.GetTapNoteRangeInclusive( nnt, MidiCountToNoteRow(count), MidiCountToNoteRow(count), begin, end, true );
for( NoteData::TrackMap::iterator iter = begin; iter != end; iter++ )
for( NoteData::TrackMap::iterator lIter = begin; lIter != end; lIter++ )
{
// if( gd == expert && fBeat >= 27*4-2 && nnt == green )
// LOG->Trace( "shortening hold at %f, length %d", fBeat, length );
ASSERT( iter->second.type == TapNote::hold_head );
iter->second.iDuration = MidiCountToNoteRow(count) - iter->first - 2;
ASSERT( lIter->second.type == TapNote::hold_head );
lIter->second.iDuration = MidiCountToNoteRow(count) - lIter->first - 2;
}
noteData.SetTapNote( nnt, MidiCountToNoteRow(count), tn );
+14 -14
View File
@@ -408,9 +408,9 @@ static bool LoadFromPMSFile( const RString &sPath, const NameToData_t &mapNameTo
if( sNoteId != "00" )
{
vTapNotes.push_back( TAP_ORIGINAL_TAP );
map<RString,int>::const_iterator it = idToKeySoundIndex.find( sNoteId );
if( it != idToKeySoundIndex.end() )
vTapNotes.back().iKeysoundIndex = it->second;
map<RString,int>::const_iterator rInt = idToKeySoundIndex.find( sNoteId );
if( rInt != idToKeySoundIndex.end() )
vTapNotes.back().iKeysoundIndex = rInt->second;
}
else
{
@@ -609,31 +609,31 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
continue;
// this is keysound file name. Looks like "#WAV1A"
RString sData = it->second;
RString nData = it->second;
RString sWavID = sName.Right(2);
/* Due to bugs in some programs, many PMS files have a "WAV" extension
* on files in the PMS for files that actually have some other extension.
* Do a search. Don't do a wildcard search; if sData is "song.wav",
* we might also have "song.png", which we shouldn't match. */
if( !IsAFile(out.GetSongDir()+sData) )
if( !IsAFile(out.GetSongDir()+nData) )
{
const char *exts[] = { "oga", "ogg", "wav", "mp3", NULL }; // XXX: stop duplicating these everywhere
for( unsigned i = 0; exts[i] != NULL; ++i )
{
RString fn = SetExtension( sData, exts[i] );
RString fn = SetExtension( nData, exts[i] );
if( IsAFile(out.GetSongDir()+fn) )
{
sData = fn;
nData = fn;
break;
}
}
}
if( !IsAFile(out.GetSongDir()+sData) )
LOG->UserLog( "Song file", out.GetSongDir(), "references key \"%s\" that can't be found", sData.c_str() );
if( !IsAFile(out.GetSongDir()+nData) )
LOG->UserLog( "Song file", out.GetSongDir(), "references key \"%s\" that can't be found", nData.c_str() );
sWavID.MakeUpper(); // HACK: undo the MakeLower()
out.m_vsKeysoundFile.push_back( sData );
out.m_vsKeysoundFile.push_back( nData );
idToKeySoundIndexOut[ sWavID ] = out.m_vsKeysoundFile.size()-1;
LOG->Trace( "Inserting keysound index %u '%s'", unsigned(out.m_vsKeysoundFile.size()-1), sWavID.c_str() );
}
@@ -654,11 +654,11 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
float fBeatsPerMeasure = GetBeatsPerMeasure( mapMeasureToTimeSig, iMeasureNo, sigAdjustmentsOut );
int iRowsPerMeasure = BeatToNoteRow( fBeatsPerMeasure );
RString sData = it->second;
int totalPairs = sData.size() / 2;
RString nData = it->second;
int totalPairs = nData.size() / 2;
for( int i = 0; i < totalPairs; ++i )
{
RString sPair = sData.substr( i*2, 2 );
RString sPair = nData.substr( i*2, 2 );
int iVal = 0;
if( sscanf( sPair, "%x", &iVal ) == 0 || iVal == 0 )
@@ -738,7 +738,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur
{
// XXX: offset
int iBPMNo;
sscanf( sData, "%x", &iBPMNo ); // data is in hexadecimal
sscanf( nData, "%x", &iBPMNo ); // data is in hexadecimal
RString sBPM;
RString sTagToLookFor = ssprintf( "#bpm%02x", iBPMNo );
+3 -2
View File
@@ -37,6 +37,7 @@ void SMLoader::LoadFromSMTokens(
// insert stepstype hacks from GameManager.cpp here? -aj
out.m_StepsType = GAMEMAN->StringToStepsType( sStepsType );
out.SetDescription( sDescription );
out.SetCredit( sDescription ); // this is often used for both.
out.SetDifficulty( DwiCompatibleStringToDifficulty(sDifficulty) );
// Handle hacks that originated back when StepMania didn't have
@@ -413,9 +414,9 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
if(arrayWarpsFromNegativeBPMs.size() > 0)
{
// zomg we already have some warps...
for( unsigned i=0; i<arrayWarpsFromNegativeBPMs.size(); i++ )
for( unsigned j=0; j<arrayWarpsFromNegativeBPMs.size(); j++ )
{
out.AddWarpSegment( arrayWarpsFromNegativeBPMs[i] );
out.AddWarpSegment( arrayWarpsFromNegativeBPMs[j] );
}
}
// warp sorting will need to take place.
+48 -2
View File
@@ -565,7 +565,7 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach
}
else if( sValueName=="COMBOS" )
{/*
{
vector<RString> arrayComboExpressions;
split( sParams[1], ",", arrayComboExpressions );
@@ -584,7 +584,6 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach
ComboSegment new_seg( BeatToNoteRow( fComboBeat ), iCombos );
out.m_Timing.AddComboSegment( new_seg );
}
*/
}
/* The following are cache tags. Never fill their values
@@ -910,6 +909,53 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach
}
*/
}
else if( sValueName=="ATTACKS" )
{
// TODO: Look into Step attacks vs Song Attacks. -Wolfman2000
/*
// Build the RString vector here so we can write it to file again later
for( unsigned s=1; s < sParams.params.size(); ++s )
out.m_sAttackString.push_back( sParams[s] );
Attack attack;
float end = -9999;
for( unsigned j=1; j < sParams.params.size(); ++j )
{
vector<RString> sBits;
split( sParams[j], "=", sBits, false );
// Need an identifer and a value for this to work
if( sBits.size() < 2 )
continue;
TrimLeft( sBits[0] );
TrimRight( sBits[0] );
if( !sBits[0].CompareNoCase("TIME") )
attack.fStartSecond = strtof( sBits[1], NULL );
else if( !sBits[0].CompareNoCase("LEN") )
attack.fSecsRemaining = strtof( sBits[1], NULL );
else if( !sBits[0].CompareNoCase("END") )
end = strtof( sBits[1], NULL );
else if( !sBits[0].CompareNoCase("MODS") )
{
attack.sModifiers = sBits[1];
if( end != -9999 )
{
attack.fSecsRemaining = end - attack.fStartSecond;
end = -9999;
}
if( attack.fSecsRemaining < 0.0f )
attack.fSecsRemaining = 0.0f;
out.m_Attacks.push_back( attack );
}
}
*/
}
else if( sValueName=="OFFSET" )
{/*
pNewNotes->m_Timing.m_fBeat0OffsetInSeconds = StringToFloat( sParams[1] );
+5 -1
View File
@@ -15,6 +15,9 @@
#include "RageUtil.h"
#include "Song.h"
#include "Steps.h"
#include "ThemeMetric.h"
ThemeMetric<bool> USE_CREDIT ( "NotesWriterSM", "DescriptionUsesCreditField" );
/**
* @brief Turn the BackgroundChange into a string.
@@ -268,7 +271,8 @@ static RString GetSMNotesTag( const Song &song, const Steps &in )
GAMEMAN->GetStepsTypeInfo(in.m_StepsType).szName, SmEscape(in.GetDescription()).c_str()) );
lines.push_back( song.m_vsKeysoundFile.empty() ? "#NOTES:" : "#NOTES2:" );
lines.push_back( ssprintf( " %s:", GAMEMAN->GetStepsTypeInfo(in.m_StepsType).szName ) );
lines.push_back( ssprintf( " %s:", SmEscape(in.GetDescription()).c_str() ) );
RString desc = (USE_CREDIT ? in.GetCredit() : in.GetDescription());
lines.push_back( ssprintf( " %s:", SmEscape(desc).c_str() ) );
lines.push_back( ssprintf( " %s:", DifficultyToString(in.GetDifficulty()).c_str() ) );
lines.push_back( ssprintf( " %d:", in.GetMeter() ) );
+9 -5
View File
@@ -180,20 +180,20 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
f.Write( "," );
}
f.PutLine( ";" );
/*
ASSERT( !out.m_Timing.m_ComboSegments.empty() );
f.Write( "#COMBOS:" );
for( unsigned i=0; i<out.m_Timing.m_ComboSegments.size(); i++ )
{
const ComboSegment &cs = out.m_Timing.m_ComboSegments[i];
f.PutLine( ssprintf( "%.6f=%d", NoteRowToBeat(cs.m_iStartRow), cs.m_iComboFactor ) );
f.PutLine( ssprintf( "%.6f=%d", NoteRowToBeat(cs.m_iStartRow), cs.m_iCombo ) );
if( i != out.m_Timing.m_ComboSegments.size()-1 )
f.Write( "," );
}
f.PutLine( ";" );
*/
FOREACH_BackgroundLayer( b )
{
if( b==0 )
@@ -301,7 +301,8 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa
lines.push_back( "#DELAYS:;" );
lines.push_back( "#TIMESIGNATURES:;" );
lines.push_back( "#TICKCOUNTS:;" );
// lines.push_back( "#COMBOS:;" );
lines.push_back( "#ATTACKS:;" );
lines.push_back( "#COMBOS:;" );
/*
vector<RString> asBPMValues;
@@ -364,6 +365,9 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa
asComboValues.push_back( ssprintf( "%.6f=%d", NoteRowToBeat(cs.m_iStartRow), cs.m_iComboFactor ) );
}
lines.push_back( "#ATTACKS:;" );
lines.push_back( ssprintf( "#COMBOS:%s;", join("\n,", asComboValues).c_str() ) );
lines.push_back( ssprintf( "#OFFSET:%.6f;", in.m_Timing.m_fBeat0OffsetInSeconds ) );
+1 -1
View File
@@ -603,7 +603,7 @@ void OptionRow::UpdateEnabledDisabled()
case LAYOUT_SHOW_ONE_IN_ROW:
FOREACH_HumanPlayer( pn )
{
bool bRowEnabled = m_pHand->m_Def.m_vEnabledForPlayers.find(pn) != m_pHand->m_Def.m_vEnabledForPlayers.end();
bRowEnabled = m_pHand->m_Def.m_vEnabledForPlayers.find(pn) != m_pHand->m_Def.m_vEnabledForPlayers.end();
if( !m_pHand->m_Def.m_bOneChoiceForAllPlayers )
{
+7 -7
View File
@@ -149,15 +149,15 @@ public:
{
// Parse the basic configuration metric.
Commands cmds = ParseCommands( ENTRY(sParam) );
if( cmds.v.size() < 1 )
Commands lCmds = ParseCommands( ENTRY(sParam) );
if( lCmds.v.size() < 1 )
RageException::Throw( "Parse error in \"ScreenOptionsMaster::%s\".", sParam.c_str() );
m_Def.m_bOneChoiceForAllPlayers = false;
const int NumCols = atoi( cmds.v[0].m_vsArgs[0] );
for( unsigned i=1; i<cmds.v.size(); i++ )
const int NumCols = atoi( lCmds.v[0].m_vsArgs[0] );
for( unsigned i=1; i<lCmds.v.size(); i++ )
{
const Command &cmd = cmds.v[i];
const Command &cmd = lCmds.v[i];
RString sName = cmd.GetName();
if( sName == "together" ) m_Def.m_bOneChoiceForAllPlayers = true;
@@ -188,8 +188,8 @@ public:
}
else if( sName == "broadcastonexport" )
{
for( unsigned i=1; i<cmd.m_vsArgs.size(); i++ )
m_vsBroadcastOnExport.push_back( cmd.m_vsArgs[i] );
for( unsigned j=1; j<cmd.m_vsArgs.size(); j++ )
m_vsBroadcastOnExport.push_back( cmd.m_vsArgs[j] );
}
else
{
+12 -1
View File
@@ -75,7 +75,18 @@ struct OptionRowDefinition
return m_vEnabledForPlayers.find(pn) != m_vEnabledForPlayers.end();
}
OptionRowDefinition() { Init(); }
OptionRowDefinition(): m_sName(""), m_sExplanationName(""),
m_bOneChoiceForAllPlayers(false), m_selectType(SELECT_ONE),
m_layoutType(LAYOUT_SHOW_ALL_IN_ROW), m_iDefault(-1),
m_bExportOnChange(false), m_bAllowThemeItems(true),
m_bAllowThemeTitle(true), m_bAllowExplanation(true),
m_bShowChoicesListOnSelect(false)
{
m_vsChoices.clear();
m_vEnabledForPlayers.clear();
FOREACH_PlayerNumber( pn )
m_vEnabledForPlayers.insert( pn );
}
void Init()
{
m_sName = "";
+4 -4
View File
@@ -53,12 +53,12 @@ void OptionsCursor::Load( const RString &sMetricsGroup, bool bLoadCanGos )
}
#undef LOAD_SPR
m_iOriginalLeftX = m_sprLeft->GetX();
m_iOriginalRightX = m_sprRight->GetX();
m_iOriginalLeftX = static_cast<int>(m_sprLeft->GetX());
m_iOriginalRightX = static_cast<int>(m_sprRight->GetX());
if( bLoadCanGos )
{
m_iOriginalCanGoLeftX = m_sprCanGoLeft->GetX();
m_iOriginalCanGoRightX = m_sprCanGoRight->GetX();
m_iOriginalCanGoLeftX = static_cast<int>(m_sprCanGoLeft->GetX());
m_iOriginalCanGoRightX = static_cast<int>(m_sprCanGoRight->GetX());
}
SetCanGo( false, false );
+14 -14
View File
@@ -138,17 +138,17 @@ void OptionListRow::SetUnderlines( const vector<bool> &aSelections, const Option
if( pTarget->m_Def.m_selectType == SELECT_ONE )
{
int iSelection = m_pOptions->GetOneSelection(sDest);
const OptionRowHandler *pHandler = m_pOptions->m_Rows.find(sDest)->second;
int iDefault = pHandler->GetDefaultOption();
const OptionRowHandler *lHandler = m_pOptions->m_Rows.find(sDest)->second;
int iDefault = lHandler->GetDefaultOption();
if( iDefault != -1 && iSelection != iDefault )
bSelected |= true;
}
else if( pTarget->m_Def.m_selectType == SELECT_MULTIPLE )
{
const vector<bool> &bTargetSelections = m_pOptions->m_bSelections.find(sDest)->second;
for( unsigned i=0; i<bTargetSelections.size(); i++ )
for( unsigned j=0; j<bTargetSelections.size(); j++ )
{
if( bTargetSelections[i] )
if( bTargetSelections[j] )
bSelected = true;
}
}
@@ -400,10 +400,10 @@ void OptionsList::Input( const InputEventPlus &input )
wrap( iSelection, bTargetSelections.size() );
SelectItem( sDest, iSelection );
Message msg("OptionsListQuickChange");
msg.SetParam( "Player", pn );
msg.SetParam( "Direction", iDir );
MESSAGEMAN->Broadcast( msg );
Message lMsg("OptionsListQuickChange");
lMsg.SetParam( "Player", pn );
lMsg.SetParam( "Direction", iDir );
MESSAGEMAN->Broadcast( lMsg );
}
}
return;
@@ -426,9 +426,9 @@ void OptionsList::Input( const InputEventPlus &input )
wrap( m_iMenuStackSelection, pHandler->m_Def.m_vsChoices.size()+1 ); // +1 for exit row
PositionCursor();
Message msg("OptionsListLeft");
msg.SetParam( "Player", input.pn );
MESSAGEMAN->Broadcast( msg );
Message lMsg("OptionsListLeft");
lMsg.SetParam( "Player", input.pn );
MESSAGEMAN->Broadcast( lMsg );
return;
}
else if( input.MenuI == GAME_BUTTON_RIGHT )
@@ -447,9 +447,9 @@ void OptionsList::Input( const InputEventPlus &input )
wrap( m_iMenuStackSelection, pHandler->m_Def.m_vsChoices.size()+1 ); // +1 for exit row
PositionCursor();
Message msg("OptionsListRight");
msg.SetParam( "Player", input.pn );
MESSAGEMAN->Broadcast( msg );
Message lMsg("OptionsListRight");
lMsg.SetParam( "Player", input.pn );
MESSAGEMAN->Broadcast( lMsg );
return;
}
else if( input.MenuI == GAME_BUTTON_START )
+15 -12
View File
@@ -11,21 +11,24 @@
class XNode;
#include "LocalizedString.h"
/* If the same piece of data is in multiple panes, use separate contents entries,
/**
* @brief The various categories used to display data on Steps.
*
* If the same piece of data is in multiple panes, use separate contents entries,
* so it can be themed differently. */
enum PaneCategory
{
PaneCategory_NumSteps,
PaneCategory_Jumps,
PaneCategory_Holds,
PaneCategory_Rolls,
PaneCategory_Mines,
PaneCategory_Hands,
PaneCategory_Lifts,
PaneCategory_Fakes,
PaneCategory_MachineHighScore,
PaneCategory_MachineHighName,
PaneCategory_ProfileHighScore,
PaneCategory_NumSteps, /**< The number of steps for the chart. */
PaneCategory_Jumps, /**< The number of jumps for the chart. */
PaneCategory_Holds, /**< The number of holds for the chart. */
PaneCategory_Rolls, /**< The number of rolls for the chart. */
PaneCategory_Mines, /**< The number of mines for the chart. */
PaneCategory_Hands, /**< The number of hands for the chart. */
PaneCategory_Lifts, /**< The number of lifts for the chart. */
PaneCategory_Fakes, /**< The number of fakes for the chart. */
PaneCategory_MachineHighScore, /**< The high score on the machine. */
PaneCategory_MachineHighName, /**< The name associated with the machine high score. */
PaneCategory_ProfileHighScore, /**< The personal profile's highest score. */
NUM_PaneCategory,
PaneCategory_Invalid,
};
+62 -50
View File
@@ -175,8 +175,15 @@ ThemeMetric<bool> REQUIRE_STEP_ON_MINES ( "Player", "RequireStepOnMines" );
* For those wishing to make a theme very accurate to In The Groove 2, set this to false. */
ThemeMetric<bool> ROLL_BODY_INCREMENTS_COMBO ( "Player", "RollBodyIncrementsCombo" );
ThemeMetric<bool> CHECKPOINTS_TAPS_SEPARATE_JUDGMENT ( "Player", "CheckpointsTapsSeparateJudgment" );
ThemeMetric<bool> SCORE_MISSED_HOLDS_AND_ROLLS ( "Player", "ScoreMissedHoldsAndRolls" ); // sm-ssc addition
/**
* @brief Do we score missed holds and rolls with HoldNoteScores?
*
* If set to true, missed holds and rolls are given LetGo judgments.
* If set to false, missed holds and rolls are given no judgment on the hold side of things. */
ThemeMetric<bool> SCORE_MISSED_HOLDS_AND_ROLLS ( "Player", "ScoreMissedHoldsAndRolls" );
/** @brief How much of the song/course must have gone by before a Player's combo is colored? */
ThemeMetric<float> PERCENT_UNTIL_COLOR_COMBO ( "Player", "PercentUntilColorCombo" );
/** @brief How much combo must be earned before the announcer says "Combo Stopped"? */
ThemeMetric<int> COMBO_STOPPED_AT ( "Player", "ComboStoppedAt" );
ThemeMetric<float> ATTACK_RUN_TIME_RANDOM ( "Player", "AttackRunTimeRandom" );
ThemeMetric<float> ATTACK_RUN_TIME_MINE ( "Player", "AttackRunTimeMine" );
@@ -2806,7 +2813,9 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now )
int iCheckpointFrequencyRows = ROWS_PER_BEAT/2;
if( CHECKPOINTS_USE_TICKCOUNTS )
{
iCheckpointFrequencyRows = ROWS_PER_BEAT / GAMESTATE->m_pCurSong->m_Timing.GetTickcountAtRow( iLastRowCrossed );
int tickCurrent = GAMESTATE->m_pCurSong->m_Timing.GetTickcountAtRow( iLastRowCrossed );
// There are some charts that don't want tickcounts involved at all.
iCheckpointFrequencyRows = (tickCurrent > 0 ? ROWS_PER_BEAT / tickCurrent : 0);
}
else if( CHECKPOINTS_USE_TIME_SIGNATURES )
{
@@ -2816,59 +2825,62 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now )
iCheckpointFrequencyRows = ROWS_PER_BEAT * tSignature.m_iDenominator / (tSignature.m_iNumerator * 4);
}
// "the first row after the start of the range that lands on a beat"
int iFirstCheckpointInRange = ((m_iFirstUncrossedRow+iCheckpointFrequencyRows-1)/iCheckpointFrequencyRows) * iCheckpointFrequencyRows;
// "the last row or first row earlier that lands on a beat"
int iLastCheckpointInRange = ((iLastRowCrossed)/iCheckpointFrequencyRows) * iCheckpointFrequencyRows;
for( int r = iFirstCheckpointInRange; r <= iLastCheckpointInRange; r += iCheckpointFrequencyRows )
if( iCheckpointFrequencyRows > 0 )
{
//LOG->Trace( "%d...", r );
vector<int> viColsWithHold;
int iNumHoldsHeldThisRow = 0;
int iNumHoldsMissedThisRow = 0;
// "the first row after the start of the range that lands on a beat"
int iFirstCheckpointInRange = ((m_iFirstUncrossedRow+iCheckpointFrequencyRows-1)/iCheckpointFrequencyRows) * iCheckpointFrequencyRows;
// start at r-1 so that we consider holds whose end rows are equal to the checkpoint row
NoteData::all_tracks_iterator iter = m_NoteData.GetTapNoteRangeAllTracks( r-1, r, true );
for( ; !iter.IsAtEnd(); ++iter )
// "the last row or first row earlier that lands on a beat"
int iLastCheckpointInRange = ((iLastRowCrossed)/iCheckpointFrequencyRows) * iCheckpointFrequencyRows;
for( int r = iFirstCheckpointInRange; r <= iLastCheckpointInRange; r += iCheckpointFrequencyRows )
{
TapNote &tn = *iter;
if( tn.type != TapNote::hold_head )
continue;
//LOG->Trace( "%d...", r );
vector<int> viColsWithHold;
int iNumHoldsHeldThisRow = 0;
int iNumHoldsMissedThisRow = 0;
int iStartRow = iter.Row();
int iEndRow = iStartRow + tn.iDuration;
int iTrack = iter.Track();
// "the first row after the hold head that lands on a beat"
int iFirstCheckpointOfHold = ((iStartRow+iCheckpointFrequencyRows)/iCheckpointFrequencyRows) * iCheckpointFrequencyRows;
// "the end row or the first earlier row that lands on a beat"
int iLastCheckpointOfHold = ((iEndRow)/iCheckpointFrequencyRows) * iCheckpointFrequencyRows;
// count the end of the hold as a checkpoint
bool bHoldOverlapsRow = iFirstCheckpointOfHold <= r && r <= iLastCheckpointOfHold;
if( !bHoldOverlapsRow )
continue;
viColsWithHold.push_back( iTrack );
if( tn.HoldResult.fLife > 0 )
// start at r-1 so that we consider holds whose end rows are equal to the checkpoint row
NoteData::all_tracks_iterator nIter = m_NoteData.GetTapNoteRangeAllTracks( r-1, r, true );
for( ; !nIter.IsAtEnd(); ++nIter )
{
++iNumHoldsHeldThisRow;
++tn.HoldResult.iCheckpointsHit;
}
else
{
++iNumHoldsMissedThisRow;
++tn.HoldResult.iCheckpointsMissed;
}
}
TapNote &tn = *nIter;
if( tn.type != TapNote::hold_head )
continue;
// TODO: Find a better way of handling hold checkpoints with other taps.
if( !viColsWithHold.empty() && ( CHECKPOINTS_TAPS_SEPARATE_JUDGMENT || m_NoteData.GetNumTapNotesInRow( iLastRowCrossed ) == 0 ) )
{
HandleHoldCheckpoint( r, iNumHoldsHeldThisRow, iNumHoldsMissedThisRow, viColsWithHold );
int iStartRow = nIter.Row();
int iEndRow = iStartRow + tn.iDuration;
int iTrack = nIter.Track();
// "the first row after the hold head that lands on a beat"
int iFirstCheckpointOfHold = ((iStartRow+iCheckpointFrequencyRows)/iCheckpointFrequencyRows) * iCheckpointFrequencyRows;
// "the end row or the first earlier row that lands on a beat"
int iLastCheckpointOfHold = ((iEndRow)/iCheckpointFrequencyRows) * iCheckpointFrequencyRows;
// count the end of the hold as a checkpoint
bool bHoldOverlapsRow = iFirstCheckpointOfHold <= r && r <= iLastCheckpointOfHold;
if( !bHoldOverlapsRow )
continue;
viColsWithHold.push_back( iTrack );
if( tn.HoldResult.fLife > 0 )
{
++iNumHoldsHeldThisRow;
++tn.HoldResult.iCheckpointsHit;
}
else
{
++iNumHoldsMissedThisRow;
++tn.HoldResult.iCheckpointsMissed;
}
}
// TODO: Find a better way of handling hold checkpoints with other taps.
if( !viColsWithHold.empty() && ( CHECKPOINTS_TAPS_SEPARATE_JUDGMENT || m_NoteData.GetNumTapNotesInRow( iLastRowCrossed ) == 0 ) )
{
HandleHoldCheckpoint( r, iNumHoldsHeldThisRow, iNumHoldsMissedThisRow, viColsWithHold );
}
}
}
}
@@ -3212,7 +3224,7 @@ void Player::SetCombo( int iCombo, int iMisses )
if( GAMESTATE->IsCourseMode() )
{
int iSongIndexStartColoring = GAMESTATE->m_pCurCourse->GetEstimatedNumStages();
iSongIndexStartColoring = floor(iSongIndexStartColoring*PERCENT_UNTIL_COLOR_COMBO);
iSongIndexStartColoring = static_cast<int>(floor(iSongIndexStartColoring*PERCENT_UNTIL_COLOR_COMBO));
bPastBeginning = GAMESTATE->GetCourseSongIndex() >= iSongIndexStartColoring;
}
else
-2
View File
@@ -12,8 +12,6 @@
#include "CommonMetrics.h"
#include <float.h>
#define ONE( arr ) { for( unsigned Z = 0; Z < ARRAYLEN(arr); ++Z ) arr[Z]=1.0f; }
ThemeMetric<float> RANDOM_SPEED_CHANCE ( "PlayerOptions", "RandomSpeedChance" );
ThemeMetric<float> RANDOM_REVERSE_CHANCE ( "PlayerOptions", "RandomReverseChance" );
ThemeMetric<float> RANDOM_DARK_CHANCE ( "PlayerOptions", "RandomDarkChance" );
+30 -1
View File
@@ -7,13 +7,42 @@ class Steps;
class Trail;
struct lua_State;
#define ONE( arr ) { for( unsigned Z = 0; Z < ARRAYLEN(arr); ++Z ) arr[Z]=1.0f; }
#include "GameConstantsAndTypes.h"
#include "PlayerNumber.h"
/** @brief Per-player options that are not saved between sessions. */
class PlayerOptions
{
public:
PlayerOptions() { Init(); };
/**
* @brief Set up the PlayerOptions with some reasonable defaults.
*
* This code was taken from Init() to use proper initialization. */
PlayerOptions(): m_bSetScrollSpeed(false),
m_fTimeSpacing(0), m_SpeedfTimeSpacing(1.0f),
m_fScrollSpeed(1.0f), m_SpeedfScrollSpeed(1.0f),
m_fScrollBPM(200), m_SpeedfScrollBPM(1.0f),
m_fDark(0), m_SpeedfDark(1.0f),
m_fBlind(0), m_SpeedfBlind(1.0f),
m_fCover(0), m_SpeedfCover(1.0f),
m_fRandAttack(0), m_SpeedfRandAttack(1.0f),
m_fSongAttack(0), m_SpeedfSongAttack(1.0f),
m_fPlayerAutoPlay(0), m_SpeedfPlayerAutoPlay(1.0f),
m_bSetTiltOrSkew(false),
m_fPerspectiveTilt(0), m_SpeedfPerspectiveTilt(1.0f),
m_fSkew(0), m_SpeedfSkew(1.0f),
m_fPassmark(0), m_SpeedfPassmark(1.0f),
m_fRandomSpeed(0), m_SpeedfRandomSpeed(1.0f),
m_bMuteOnError(false), m_FailType(FAIL_IMMEDIATE),
m_ScoreDisplay(SCORING_ADD), m_sNoteSkin("")
{
ZERO( m_fAccels ); ONE( m_SpeedfAccels );
ZERO( m_fEffects ); ONE( m_SpeedfEffects );
ZERO( m_fAppearances ); ONE( m_SpeedfAppearances );
ZERO( m_fScrolls ); ONE( m_SpeedfScrolls );
ZERO( m_bTurns ); ZERO( m_bTransforms );
};
void Init();
void Approach( const PlayerOptions& other, float fDeltaSeconds );
RString GetString( bool bForceNoteSkin = false ) const;
+1 -1
View File
@@ -35,7 +35,7 @@
* </li></ul>
*/
#ifndef PRODUCT_VER_BARE
#define PRODUCT_VER_BARE v1.2.2
#define PRODUCT_VER_BARE v1.2.3
#endif
/**
+1 -1
View File
@@ -5,7 +5,7 @@
; see ProductInfo.h for use descriptions
!define PRODUCT_ID "sm-ssc"
!define PRODUCT_VER "v1.2.2"
!define PRODUCT_VER "v1.2.3"
!define PRODUCT_DISPLAY "${PRODUCT_ID} ${PRODUCT_VER}"
!define PRODUCT_BITMAP "ssc"
+7 -7
View File
@@ -363,8 +363,8 @@ float Profile::GetSongsActual( StepsType st, Difficulty dc ) const
FOREACHM_CONST( StepsID, HighScoresForASteps, hsfas.m_StepsHighScores, j )
{
const StepsID &id = j->first;
Steps* pSteps = id.ToSteps( pSong, true );
const StepsID &sid = j->first;
Steps* pSteps = sid.ToSteps( pSong, true );
CHECKPOINT_M( ssprintf("Profile::GetSongsActual: song %p, steps %p", pSong, pSteps) );
// If the Steps isn't loaded on the current machine, then we can't
@@ -375,7 +375,7 @@ float Profile::GetSongsActual( StepsType st, Difficulty dc ) const
if( pSteps->m_StepsType != st )
continue;
CHECKPOINT_M( ssprintf("Profile::GetSongsActual: n %s = %p", id.ToString().c_str(), pSteps) );
CHECKPOINT_M( ssprintf("Profile::GetSongsActual: n %s = %p", sid.ToString().c_str(), pSteps) );
if( pSteps->GetDifficulty() != dc )
continue; // skip
CHECKPOINT;
@@ -1303,13 +1303,13 @@ void Profile::LoadGeneralDataFromNode( const XNode* pNode )
if( style->GetName() != "Style" )
continue;
StyleID s;
s.LoadFromNode( style );
StyleID sID;
sID.LoadFromNode( style );
if( !s.IsValid() )
if( !sID.IsValid() )
WARN_AND_CONTINUE;
style->GetTextValue( m_iNumSongsPlayedByStyle[s] );
style->GetTextValue( m_iNumSongsPlayedByStyle[sID] );
}
}
}
+3 -3
View File
@@ -489,10 +489,10 @@ bool ProfileManager::DeleteLocalProfile( RString sProfileID )
g_vLocalProfile.erase( i );
// Delete all references to this profileID
FOREACH_CONST( Preference<RString>*, m_sDefaultLocalProfileID.m_v, i )
FOREACH_CONST( Preference<RString>*, m_sDefaultLocalProfileID.m_v, j )
{
if( (*i)->Get() == sProfileID )
(*i)->Set( "" );
if( (*j)->Get() == sProfileID )
(*j)->Set( "" );
}
return true;
}
+2 -2
View File
@@ -760,7 +760,7 @@ bool RageDisplay::SaveScreenshot( RString sPath, GraphicsFileFormat format )
int iHeight = 480;
// This used to be lrintf. However, lrintf causes odd resolutions like
// 639x480 (4:3) and 853x480 (16:9). ceilf gives correct values. -aj
int iWidth = ceilf( iHeight * GetActualVideoModeParams().fDisplayAspectRatio );
int iWidth = static_cast<int>(ceilf( iHeight * GetActualVideoModeParams().fDisplayAspectRatio ));
timer.Touch();
RageSurfaceUtils::Zoom( surface, iWidth, iHeight );
// LOG->Trace( "%ix%i -> %ix%i (%.3f) in %f seconds", surface->w, surface->h, iWidth, iHeight, GetActualVideoModeParams().fDisplayAspectRatio, timer.GetDeltaTime() );
@@ -810,7 +810,7 @@ void RageDisplay::DrawQuads( const RageSpriteVertex v[], int iNumVerts )
{
ASSERT( (iNumVerts%4) == 0 );
if(iNumVerts == 0)
if(!iNumVerts)
return;
this->DrawQuadsInternal(v,iNumVerts);
+26 -22
View File
@@ -71,6 +71,7 @@ enum PixelFormat
};
const RString& PixelFormatToString( PixelFormat i );
/** @brief The parameters used for the present Video Mode. */
class VideoModeParams
{
public:
@@ -91,24 +92,27 @@ public:
RString sIconFile_,
bool PAL_,
float fDisplayAspectRatio_
)
{
windowed = windowed_;
width = width_;
height = height_;
bpp = bpp_;
rate = rate_;
vsync = vsync_;
interlaced = interlaced_;
bSmoothLines = bSmoothLines_;
bTrilinearFiltering = bTrilinearFiltering_;
bAnisotropicFiltering = bAnisotropicFiltering_;
sWindowTitle = sWindowTitle_;
sIconFile = sIconFile_;
PAL = PAL_;
fDisplayAspectRatio = fDisplayAspectRatio_;
}
VideoModeParams() {}
):
windowed(windowed_),
width(width_),
height(height_),
bpp(bpp_),
rate(rate_),
vsync(vsync_),
interlaced(interlaced_),
bSmoothLines(bSmoothLines_),
bTrilinearFiltering(bTrilinearFiltering_),
bAnisotropicFiltering(bAnisotropicFiltering_),
sWindowTitle(sWindowTitle_),
sIconFile(sIconFile_),
PAL(PAL_),
fDisplayAspectRatio(fDisplayAspectRatio_) {}
VideoModeParams(): windowed(false), width(0), height(0),
bpp(0), rate(0), vsync(false), interlaced(false),
bSmoothLines(false), bTrilinearFiltering(false),
bAnisotropicFiltering(false), sWindowTitle(RString()),
sIconFile(RString()), PAL(false), fDisplayAspectRatio(0.0) {}
bool windowed;
int width;
@@ -116,14 +120,14 @@ public:
int bpp;
int rate;
bool vsync;
bool interlaced;
bool bSmoothLines;
bool bTrilinearFiltering;
bool bAnisotropicFiltering;
bool interlaced;
bool PAL;
float fDisplayAspectRatio;
RString sWindowTitle;
RString sIconFile;
bool PAL;
float fDisplayAspectRatio;
};
struct RenderTargetParam
@@ -277,7 +281,7 @@ public:
const RageVector3 &dir ) = 0;
virtual void SetSphereEnvironmentMapping( TextureUnit tu, bool b ) = 0;
virtual void SetCelShaded( bool b ) = 0;
virtual void SetCelShaded( int stage ) = 0;
virtual RageCompiledGeometry* CreateCompiledGeometry() = 0;
virtual void DeleteCompiledGeometry( RageCompiledGeometry* p ) = 0;
+105 -130
View File
@@ -34,7 +34,6 @@
#include <math.h>
#include <list>
RString GetErrorString( HRESULT hr )
{
char szError[1024] = "";
@@ -42,44 +41,40 @@ RString GetErrorString( HRESULT hr )
return szError;
}
//
// Globals
//
#if !defined(XBOX)
HMODULE g_D3D8_Module = NULL;
#endif
LPDIRECT3D8 g_pd3d = NULL;
LPDIRECT3DDEVICE8 g_pd3dDevice = NULL;
LPDIRECT3DDEVICE8 g_pd3dDevice = NULL;
D3DCAPS8 g_DeviceCaps;
D3DDISPLAYMODE g_DesktopMode;
D3DPRESENT_PARAMETERS g_d3dpp;
int g_ModelMatrixCnt=0;
static bool g_bSphereMapping[NUM_TextureUnit] = { false, false };
D3DDISPLAYMODE g_DesktopMode;
D3DPRESENT_PARAMETERS g_d3dpp;
int g_ModelMatrixCnt=0;
static bool g_bSphereMapping[NUM_TextureUnit] = { false, false };
/* Direct3D doesn't associate a palette with textures.
* Instead, we load a palette into a slot. We need to keep track
* of which texture's palette is stored in what slot. */
/* Direct3D doesn't associate a palette with textures. Instead, we load a
* palette into a slot. We need to keep track of which texture's palette is
* stored in what slot. */
map<unsigned,int> g_TexResourceToPaletteIndex;
list<int> g_PaletteIndex;
struct TexturePalette { PALETTEENTRY p[256]; };
map<unsigned,TexturePalette> g_TexResourceToTexturePalette;
/* Load the palette, if any, for the given texture into a palette slot, and make
* it current. */
// Load the palette, if any, for the given texture into a palette slot, and make it current.
static void SetPalette( unsigned TexResource )
{
/* If the texture isn't paletted, we have nothing to do. */
// If the texture isn't paletted, we have nothing to do.
if( g_TexResourceToTexturePalette.find(TexResource) == g_TexResourceToTexturePalette.end() )
return;
/* Is the palette already loaded? */
// Is the palette already loaded?
if( g_TexResourceToPaletteIndex.find(TexResource) == g_TexResourceToPaletteIndex.end() )
{
/* It's not. Grab the least recently used slot. */
// It's not. Grab the least recently used slot.
int iPalIndex = g_PaletteIndex.front();
/* If any other texture is currently using this slot, mark that palette unloaded. */
// If any other texture is currently using this slot, mark that palette unloaded.
for( map<unsigned,int>::iterator i = g_TexResourceToPaletteIndex.begin(); i != g_TexResourceToPaletteIndex.end(); ++i )
{
if( i->second != iPalIndex )
@@ -88,7 +83,7 @@ static void SetPalette( unsigned TexResource )
break;
}
/* Load it. */
// Load it.
#if !defined(XBOX)
TexturePalette& pal = g_TexResourceToTexturePalette[TexResource];
g_pd3dDevice->SetPaletteEntries( iPalIndex, pal.p );
@@ -98,10 +93,10 @@ static void SetPalette( unsigned TexResource )
g_TexResourceToPaletteIndex[TexResource] = iPalIndex;
}
const int iPalIndex = g_TexResourceToPaletteIndex[TexResource];
/* Find this palette index in the least-recently-used queue and move it to the end. */
// Find this palette index in the least-recently-used queue and move it to the end.
for(list<int>::iterator i = g_PaletteIndex.begin(); i != g_PaletteIndex.end(); ++i)
{
if( *i != iPalIndex )
@@ -184,14 +179,14 @@ static D3DFORMAT D3DFORMATS[NUM_PixelFormat] =
D3DFMT_A1R5G5B5,
D3DFMT_X1R5G5B5,
#if defined(XBOX)
D3DFMT_UNKNOWN, /* no RGB */
D3DFMT_UNKNOWN, // no RGB
#else
D3DFMT_R8G8B8,
#endif
D3DFMT_P8,
D3DFMT_UNKNOWN, /* no BGR */
D3DFMT_UNKNOWN, /* no ABGR */
D3DFMT_UNKNOWN, /* X1R5G5B5 */
D3DFMT_UNKNOWN, // no BGR
D3DFMT_UNKNOWN, // no ABGR
D3DFMT_UNKNOWN, // X1R5G5B5
};
const RageDisplay::PixelFormatDesc *RageDisplay_D3D::GetPixelFormatDesc(PixelFormat pf) const
@@ -201,13 +196,11 @@ const RageDisplay::PixelFormatDesc *RageDisplay_D3D::GetPixelFormatDesc(PixelFor
}
RageDisplay_D3D::RageDisplay_D3D()
{
}
static LocalizedString D3D_NOT_INSTALLED ( "RageDisplay_D3D", "DirectX 8.1 or greater is not installed. You can download it from:" );
const RString D3D_URL = "http://www.microsoft.com/downloads/details.aspx?FamilyID=a19bed22-0b25-4e5d-a584-6389d8a3dad0&displaylang=en";
static LocalizedString HARDWARE_ACCELERATION_NOT_AVAILABLE ( "RageDisplay_D3D",
@@ -273,10 +266,9 @@ RString RageDisplay_D3D::Init( const VideoModeParams &p, bool bAllowUnaccelerate
// Save the original desktop format.
g_pd3d->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &g_DesktopMode );
/* Up until now, all we've done is set up g_pd3d and do some queries. Now,
* actually initialize the window. Do this after as many error conditions
* as possible, because if we have to shut it down again we'll flash a window
* briefly. */
/* Up until now, all we've done is set up g_pd3d and do some queries. Now,
* actually initialize the window. Do this after as many error conditions as
* possible, because if we have to shut it down again we'll flash a window briefly. */
bool bIgnore = false;
return SetVideoMode( p, bIgnore );
}
@@ -299,8 +291,9 @@ RageDisplay_D3D::~RageDisplay_D3D()
g_pd3d = NULL;
}
/* Even after we call Release(), D3D may still affect our window. It seems to subclass
* the window, and never release it. Free the DLL after destroying the window. */
/* Even after we call Release(), D3D may still affect our window. It seems
* to subclass the window, and never release it. Free the DLL after
* destroying the window. */
#if !defined(XBOX)
if( g_D3D8_Module )
{
@@ -330,9 +323,9 @@ D3DFORMAT FindBackBufferType(bool bWindowed, int iBPP)
HRESULT hr;
// If windowed, then bpp is ignored. Use whatever works.
vector<D3DFORMAT> vBackBufferFormats; // throw all possibilities in here
/* When windowed, add all formats; otherwise add only formats that match dwBPP. */
vector<D3DFORMAT> vBackBufferFormats; // throw all possibilities in here
// When windowed, add all formats; otherwise add only formats that match dwBPP.
if( iBPP == 16 || bWindowed )
{
vBackBufferFormats.push_back( D3DFMT_R5G6B5 );
@@ -371,7 +364,7 @@ D3DFORMAT FindBackBufferType(bool bWindowed, int iBPP)
fmtDisplay, fmtBackBuffer, bWindowed );
if( FAILED(hr) )
continue; // skip
continue; // skip
// done searching
LOG->Trace( "This will work." );
@@ -384,7 +377,7 @@ D3DFORMAT FindBackBufferType(bool bWindowed, int iBPP)
RString SetD3DParams( bool &bNewDeviceOut )
{
if( g_pd3dDevice == NULL ) // device is not yet created. We need to create it
if( g_pd3dDevice == NULL ) // device is not yet created. We need to create it
{
bNewDeviceOut = true;
HRESULT hr = g_pd3d->CreateDevice(
@@ -419,13 +412,13 @@ RString SetD3DParams( bool &bNewDeviceOut )
g_pd3dDevice->SetRenderState( D3DRS_NORMALIZENORMALS, TRUE );
/* Palettes were lost by Reset(), so mark them unloaded. */
// Palettes were lost by Reset(), so mark them unloaded.
g_TexResourceToPaletteIndex.clear();
return RString();
}
/* If the given parameters have failed, try to lower them. */
// If the given parameters have failed, try to lower them.
static bool D3DReduceParams( D3DPRESENT_PARAMETERS *pp )
{
D3DDISPLAYMODE current;
@@ -443,41 +436,41 @@ static bool D3DReduceParams( D3DPRESENT_PARAMETERS *pp )
D3DDISPLAYMODE mode;
g_pd3d->EnumAdapterModes( D3DADAPTER_DEFAULT, i, &mode );
/* Never change the format. */
// Never change the format.
if( mode.Format != current.Format )
continue;
/* Never increase the parameters. */
// Never increase the parameters.
if( mode.Height > current.Height || mode.Width > current.Width || mode.RefreshRate > current.RefreshRate )
continue;
/* Never go below 640x480 unless we already are. */
// Never go below 640x480 unless we already are.
if( (current.Width >= 640 && current.Height >= 480) && (mode.Width < 640 || mode.Height < 480) )
continue;
/* Never go below 60Hz. */
// Never go below 60Hz.
if( mode.RefreshRate && mode.RefreshRate < 60 )
continue;
/* If mode.RefreshRate is 0, it means "default". We don't know what that means;
* assume it's 60Hz. */
/* If mode.RefreshRate is 0, it means "default". We don't know what
* that means; assume it's 60Hz. */
/* Higher scores are better. */
// Higher scores are better.
int iScore = 0;
if( current.RefreshRate >= 70 && mode.RefreshRate < 70 )
{
/* Top priority: we really want to avoid dropping to a refresh rate that's
* below 70Hz. */
/* Top priority: we really want to avoid dropping to a refresh rate
* that's below 70Hz. */
iScore -= 100000;
}
else if( mode.RefreshRate < current.RefreshRate )
{
/* Low priority: We're lowering the refresh rate, but not too far. current.RefreshRate
* might be 0, in which case this simply gives points for higher refresh
* rates. */
/* Low priority: We're lowering the refresh rate, but not too far.
* current.RefreshRate might be 0, in which case this simply gives
* points for higher refresh rates. */
iScore += (mode.RefreshRate - current.RefreshRate);
}
/* Medium priority: */
// Medium priority:
int iResolutionDiff = (current.Height - mode.Height) + (current.Width - mode.Width);
iScore -= iResolutionDiff * 100;
@@ -534,10 +527,10 @@ static void SetPresentParametersFromVideoModeParams( const VideoModeParams &p, D
#else
if( XGetVideoStandard() == XC_VIDEO_STANDARD_PAL_I )
{
/* Get supported video flags. */
// Get supported video flags.
DWORD VideoFlags = XGetVideoFlags();
/* Set pal60 if available. */
// Set pal60 if available.
if( VideoFlags & XC_VIDEO_FLAGS_PAL_60Hz )
pD3Dpp->FullScreen_RefreshRateInHz = 60;
else
@@ -549,7 +542,6 @@ static void SetPresentParametersFromVideoModeParams( const VideoModeParams &p, D
pD3Dpp->Flags = 0;
LOG->Trace( "Present Parameters: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
pD3Dpp->BackBufferWidth, pD3Dpp->BackBufferHeight, pD3Dpp->BackBufferFormat,
pD3Dpp->BackBufferCount,
@@ -560,7 +552,7 @@ static void SetPresentParametersFromVideoModeParams( const VideoModeParams &p, D
);
}
/* Set the video mode. */
// Set the video mode.
RString RageDisplay_D3D::TryVideoMode( const VideoModeParams &_p, bool &bNewDeviceOut )
{
VideoModeParams p = _p;
@@ -572,9 +564,7 @@ RString RageDisplay_D3D::TryVideoMode( const VideoModeParams &_p, bool &bNewDevi
if( FindBackBufferType( p.windowed, p.bpp ) == D3DFMT_UNKNOWN ) // no possible back buffer formats
return ssprintf( "FindBackBufferType(%i,%i) failed", p.windowed, p.bpp ); // failed to set mode
/* Set up and display the window before setting up D3D. If we don't do this,
/* Set up and display the window before setting up D3D. If we don't do this,
* then setting up a fullscreen window (when we're not coming from windowed)
* causes all other windows on the system to be resized to the new resolution. */
GraphicsWindow::CreateGraphicsWindow( p );
@@ -586,22 +576,20 @@ RString RageDisplay_D3D::TryVideoMode( const VideoModeParams &_p, bool &bNewDevi
g_pd3dDevice = D3D__pDevice;
#endif
/* Display the window immediately, so we don't display the desktop ... */
// Display the window immediately, so we don't display the desktop ...
while( 1 )
{
/* Try the video mode. */
// Try the video mode.
RString sErr = SetD3DParams( bNewDeviceOut );
if( sErr.empty() )
break;
/* It failed. We're probably selecting a video mode that isn't supported.
* If we're fullscreen, search the mode list and find the nearest lower
* mode. */
/* It failed. We're probably selecting a video mode that isn't supported.
* If we're fullscreen, search the mode list and find the nearest lower mode. */
if( p.windowed || !D3DReduceParams( &g_d3dpp ) )
return sErr;
/* Store the new settings we're about to try. */
// Store the new settings we're about to try.
p.height = g_d3dpp.BackBufferHeight;
p.width = g_d3dpp.BackBufferWidth;
if( g_d3dpp.FullScreen_RefreshRateInHz == D3DPRESENT_RATE_DEFAULT )
@@ -610,14 +598,14 @@ RString RageDisplay_D3D::TryVideoMode( const VideoModeParams &_p, bool &bNewDevi
p.rate = g_d3dpp.FullScreen_RefreshRateInHz;
}
/* Call this again after changing the display mode. If we're going to a window
* from fullscreen, the first call can't set a larger window than the old fullscreen
* resolution or set the window position. */
/* Call this again after changing the display mode. If we're going to a window
* from fullscreen, the first call can't set a larger window than the old
* fullscreen resolution or set the window position. */
GraphicsWindow::CreateGraphicsWindow( p );
ResolutionChanged();
return RString(); // mode change successful
return RString(); // mode change successful
}
void RageDisplay_D3D::ResolutionChanged()
@@ -683,12 +671,12 @@ void RageDisplay_D3D::EndFrame()
bool RageDisplay_D3D::SupportsTextureFormat( PixelFormat pixfmt, bool realtime )
{
#if defined(XBOX)
// Lazy... Xbox handles paletted textures completely differently
// than regular D3D. It's not worth writing a bunch of code to handle it.
// Paletted textures result in worse cache efficiency anyway (see "Xbox
// Palettized Texture Performance" in XDK).
// So, just force 32bit ARGB textures. -Chris
// This is also needed for XGSwizzleRect().
/* Lazy... Xbox handles paletted textures completely differently than
* regular D3D. It's not worth writing a bunch of code to handle it.
* Paletted textures result in worse cache efficiency anyway (see "Xbox
* Palettized Texture Performance" in XDK). So, just force 32bit ARGB textures.
* -Chris
* This is also needed for XGSwizzleRect(). */
return pixfmt == PixelFormat_RGBA8;
#endif
@@ -722,15 +710,15 @@ RageSurface* RageDisplay_D3D::CreateScreenshot()
#if defined(XBOX)
return NULL;
#else
/* Get the back buffer. */
// Get the back buffer.
IDirect3DSurface8* pSurface;
g_pd3dDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pSurface );
/* Get the back buffer description. */
// Get the back buffer description.
D3DSURFACE_DESC desc;
pSurface->GetDesc( &desc );
/* Copy the back buffer into a surface of a type we support. */
// Copy the back buffer into a surface of a type we support.
IDirect3DSurface8* pCopy;
g_pd3dDevice->CreateImageSurface( desc.Width, desc.Height, D3DFMT_A8R8G8B8, &pCopy );
@@ -738,7 +726,7 @@ RageSurface* RageDisplay_D3D::CreateScreenshot()
pSurface->Release();
/* Update desc from the copy. */
// Update desc from the copy.
pCopy->GetDesc( &desc );
D3DLOCKED_RECT lr;
@@ -755,7 +743,7 @@ RageSurface* RageDisplay_D3D::CreateScreenshot()
RageSurface *surface = CreateSurfaceFromPixfmt( PixelFormat_RGBA8, lr.pBits, desc.Width, desc.Height, lr.Pitch);
ASSERT( surface );
/* We need to make a copy, since lr.pBits will go away when we call UnlockRect(). */
// We need to make a copy, since lr.pBits will go away when we call UnlockRect().
RageSurface *SurfaceCopy =
CreateSurface( surface->w, surface->h,
surface->format->BitsPerPixel,
@@ -782,7 +770,7 @@ void RageDisplay_D3D::SendCurrentMatrices()
RageMatrix m;
RageMatrixMultiply( &m, GetCentering(), GetProjectionTop() );
/* Convert to OpenGL-style "pixel-centered" coords */
// Convert to OpenGL-style "pixel-centered" coords
RageMatrix m2 = GetCenteringMatrix( -0.5f, -0.5f, 0, 0 );
RageMatrix projection;
RageMatrixMultiply( &projection, &m2, &m );
@@ -795,7 +783,7 @@ void RageDisplay_D3D::SendCurrentMatrices()
{
// Optimization opportunity: Turn off texture transform if not using texture coords.
g_pd3dDevice->SetTextureStageState( tu, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 );
// If no texture is set for this texture unit, don't bother setting it up.
IDirect3DBaseTexture8* pTexture = NULL;
g_pd3dDevice->GetTexture( tu, &pTexture );
@@ -803,7 +791,6 @@ void RageDisplay_D3D::SendCurrentMatrices()
continue;
pTexture->Release();
if( g_bSphereMapping[tu] )
{
static const RageMatrix tex = RageMatrix
@@ -821,12 +808,10 @@ void RageDisplay_D3D::SendCurrentMatrices()
}
else
{
/*
* Direct3D is expecting a 3x3 matrix loaded into the 4x4 in order to transform
* the 2-component texture coordinates. We currently only use translate and scale,
* and ignore the z component entirely, so convert the texture matrix from
* 4x4 to 3x3 by dropping z.
*/
/* Direct3D is expecting a 3x3 matrix loaded into the 4x4 in order
* to transform the 2-component texture coordinates. We currently
* only use translate and scale, and ignore the z component entirely,
* so convert the texture matrix from 4x4 to 3x3 by dropping z. */
const RageMatrix &tex1 = *GetTextureTop();
const RageMatrix tex2 = RageMatrix
@@ -1067,12 +1052,10 @@ void RageDisplay_D3D::DrawCompiledGeometryInternal( const RageCompiledGeometry *
{
SendCurrentMatrices();
/* If lighting is off, then the current material will have no effect.
* We want to still be able to color models with lighting off,
* so shove the material color in texture factor and modify the
* texture stage to use it instead of the vertex color (our models
* don't have vertex coloring anyway).
*/
/* If lighting is off, then the current material will have no effect. We
* want to still be able to color models with lighting off, so shove the
* material color in texture factor and modify the texture stage to use it
* instead of the vertex color (our models don't have vertex coloring anyway). */
DWORD bLighting;
g_pd3dDevice->GetRenderState( D3DRS_LIGHTING, &bLighting );
@@ -1131,17 +1114,19 @@ void RageDisplay_D3D::SetTexture( TextureUnit tu, unsigned iTexture )
{
g_pd3dDevice->SetTexture( tu, NULL );
// Intentionally commented out. Don't mess with texture stage state when just setting the texture.
// Model sets its texture modes before setting the final texture.
/* Intentionally commented out. Don't mess with texture stage state
* when just setting the texture. Model sets its texture modes before
* setting the final texture. */
//g_pd3dDevice->SetTextureStageState( tu, D3DTSS_COLOROP, D3DTOP_DISABLE );
}
else
{
IDirect3DTexture8* pTex = (IDirect3DTexture8*) iTexture;
g_pd3dDevice->SetTexture( tu, pTex );
// Intentionally commented out. Don't mess with texture stage state when just setting the texture.
// Model sets its texture modes before setting the final texture.
/* Intentionally commented out. Don't mess with texture stage state
* when just setting the texture. Model sets its texture modes before
* setting the final texture. */
//g_pd3dDevice->SetTextureStageState( tu, D3DTSS_COLOROP, D3DTOP_MODULATE );
// Set palette (if any)
@@ -1188,7 +1173,7 @@ void RageDisplay_D3D::SetTextureMode( TextureUnit tu, TextureMode tm )
void RageDisplay_D3D::SetTextureFiltering( TextureUnit tu, bool b )
{
if( tu >= (int) g_DeviceCaps.MaxSimultaneousTextures ) // not supported
if( tu >= (int) g_DeviceCaps.MaxSimultaneousTextures ) // not supported
return;
g_pd3dDevice->SetTextureStageState( tu, D3DTSS_MINFILTER, b ? D3DTEXF_LINEAR : D3DTEXF_POINT );
@@ -1222,12 +1207,9 @@ void RageDisplay_D3D::SetBlendMode( BlendMode mode )
g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );
break;
/*
* Effects currently missing in D3D:
* BLEND_ALPHA_MASK, BLEND_ALPHA_KNOCK_OUT
/* Effects currently missing in D3D: BLEND_ALPHA_MASK, BLEND_ALPHA_KNOCK_OUT
* These two may require DirectX9 since D3DRS_SRCALPHA and D3DRS_DESTALPHA
* don't seem to exist in DX8. -aj
*/
* don't seem to exist in DX8. -aj */
case BLEND_ALPHA_MASK:
// RGB: iSourceRGB = GL_ZERO; iDestRGB = GL_ONE;
g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO );
@@ -1304,10 +1286,10 @@ void RageDisplay_D3D::SetZTestMode( ZTestMode mode )
DWORD dw;
switch( mode )
{
case ZTEST_OFF: dw = D3DCMP_ALWAYS; break;
case ZTEST_OFF: dw = D3DCMP_ALWAYS; break;
case ZTEST_WRITE_ON_PASS: dw = D3DCMP_LESSEQUAL; break;
case ZTEST_WRITE_ON_FAIL: dw = D3DCMP_GREATER; break;
default: ASSERT( 0 );
default: ASSERT( 0 );
}
g_pd3dDevice->SetRenderState( D3DRS_ZFUNC, dw );
}
@@ -1336,11 +1318,9 @@ void RageDisplay_D3D::SetMaterial(
)
{
/* If lighting is off, then the current material will have no effect.
* We want to still be able to color models with lighting off,
* so shove the material color in texture factor and modify the
* texture stage to use it instead of the vertex color (our models
* don't have vertex coloring anyway).
*/
* We want to still be able to color models with lighting off, so shove the
* material color in texture factor and modify the texture stage to use it
* instead of the vertex color (our models don't have vertex coloring anyway). */
DWORD bLighting;
g_pd3dDevice->GetRenderState( D3DRS_LIGHTING, &bLighting );
@@ -1389,15 +1369,15 @@ void RageDisplay_D3D::SetLightDirectional(
light.Type = D3DLIGHT_DIRECTIONAL;
/* Z for lighting is flipped for D3D compared to OpenGL.
* XXX: figure out exactly why this is needed. Our transforms
* are probably goofed up, but the Z test is the same for both
* API's, so I'm not sure why we don't see other weirdness. -Chris */
* XXX: figure out exactly why this is needed. Our transforms are probably
* goofed up, but the Z test is the same for both API's, so I'm not sure
* why we don't see other weirdness. -Chris */
float position[] = { dir.x, dir.y, -dir.z };
memcpy( &light.Direction, position, sizeof(position) );
memcpy( &light.Diffuse, diffuse, sizeof(diffuse) );
memcpy( &light.Ambient, ambient, sizeof(ambient) );
memcpy( &light.Specular, specular, sizeof(specular) );
// Same as OpenGL defaults. Not used in directional lights.
// light.Attenuation0 = 1;
// light.Attenuation1 = 0;
@@ -1494,7 +1474,7 @@ void RageDisplay_D3D::UpdateTexture(
{
IDirect3DTexture8* pTex = (IDirect3DTexture8*)uTexHandle;
ASSERT( pTex != NULL );
RECT rect;
rect.left = xoffset;
rect.top = yoffset;
@@ -1503,15 +1483,13 @@ void RageDisplay_D3D::UpdateTexture(
D3DLOCKED_RECT lr;
pTex->LockRect( 0, &lr, &rect, 0 );
D3DSURFACE_DESC desc;
pTex->GetLevelDesc(0, &desc);
ASSERT( xoffset+width <= int(desc.Width) );
ASSERT( yoffset+height <= int(desc.Height) );
//
// Copy bits
//
#if defined(XBOX)
RageSurface *Texture = CreateSurface( width, height, 32,
Swap32BE( 0x0000FF00 ),
@@ -1559,7 +1537,7 @@ RageMatrix RageDisplay_D3D::GetOrthoMatrix( float l, float r, float b, float t,
{
RageMatrix m = RageDisplay::GetOrthoMatrix( l, r, b, t, zn, zf );
/* Convert from OpenGL's [-1,+1] Z values to D3D's [0,+1]. */
// Convert from OpenGL's [-1,+1] Z values to D3D's [0,+1].
RageMatrix tmp;
RageMatrixScaling( &tmp, 1, 1, 0.5f );
RageMatrixMultiply( &m, &tmp, &m );
@@ -1575,12 +1553,9 @@ void RageDisplay_D3D::SetSphereEnvironmentMapping( TextureUnit tu, bool b )
g_bSphereMapping[tu] = b;
}
void RageDisplay_D3D::SetCelShaded( bool b )
void RageDisplay_D3D::SetCelShaded( int stage )
{
/* yo AJ doesn't know what the fuck is going on and he's the only one
* of the sm-ssc team who's touched DirectX in C++ (for all of an hour)
* and idkwtf.
*/
// todo: implement me!
}
/*
+1 -1
View File
@@ -64,7 +64,7 @@ public:
const RageVector3 &dir );
void SetSphereEnvironmentMapping( TextureUnit tu, bool b );
void SetCelShaded( bool b );
void SetCelShaded( int stage );
RageCompiledGeometry* CreateCompiledGeometry();
void DeleteCompiledGeometry( RageCompiledGeometry* p );
+1 -1
View File
@@ -61,7 +61,7 @@ public:
const RageVector3 &dir ) { }
void SetSphereEnvironmentMapping( TextureUnit tu, bool b ) { }
void SetCelShaded( bool b ) { }
void SetCelShaded( int stage ) { }
RageCompiledGeometry* CreateCompiledGeometry();
void DeleteCompiledGeometry( RageCompiledGeometry* p );
+41 -36
View File
@@ -332,16 +332,18 @@ GLhandleARB CompileShader( GLenum ShaderType, RString sFile, vector<RString> asD
GLhandleARB LoadShader( GLenum ShaderType, RString sFile, vector<RString> asDefines )
{
// Don't do anything here if not the hardware/driver can't do it!
if( !GLExt.m_bGL_ARB_fragment_shader && ShaderType == GL_FRAGMENT_SHADER_ARB )
return 0;
if( !GLExt.m_bGL_ARB_vertex_shader && ShaderType == GL_VERTEX_SHADER_ARB )
return 0;
// XXX: dumb, but I don't feel like refactoring ragedisplay for this. -Colby
GLhandleARB secondaryShader = 0;
if( sFile == "Data/Shaders/GLSL/Cel.vert" )
{
if ( sFile == "Data/Shaders/GLSL/Cel.vert" )
secondaryShader = CompileShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Cel.frag", asDefines);
}
else if ( sFile == "Data/Shaders/GLSL/Shell.vert" )
secondaryShader = CompileShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Shell.frag", asDefines);
GLhandleARB hShader = CompileShader( ShaderType, sFile, asDefines );
if( hShader == 0 )
@@ -349,7 +351,8 @@ GLhandleARB LoadShader( GLenum ShaderType, RString sFile, vector<RString> asDefi
GLhandleARB hProgram = GLExt.glCreateProgramObjectARB();
GLExt.glAttachObjectARB( hProgram, hShader );
if( secondaryShader != 0 )
if( secondaryShader )
{
GLExt.glAttachObjectARB( hProgram, secondaryShader );
GLExt.glDeleteObjectARB( secondaryShader );
@@ -380,6 +383,7 @@ static GLhandleARB g_hHardMixShader = 0;
static GLhandleARB g_hOverlayShader = 0;
static GLhandleARB g_hScreenShader = 0;
static GLhandleARB g_hYUYV422Shader = 0;
static GLhandleARB g_gShellShader = 0;
static GLhandleARB g_gCelShader = 0;
void InitShaders()
@@ -388,16 +392,23 @@ void InitShaders()
// the shaders and determines shader type by file extension. -aj
// argh shaders in stepmania are painful -colby
vector<RString> asDefines;
g_bTextureMatrixShader = LoadShader( GL_VERTEX_SHADER_ARB, "Data/Shaders/GLSL/Texture matrix scaling.vert", asDefines );
g_bUnpremultiplyShader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Unpremultiply.frag", asDefines );
g_bColorBurnShader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Color burn.frag", asDefines );
g_bColorDodgeShader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Color dodge.frag", asDefines );
g_bVividLightShader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Vivid light.frag", asDefines );
g_hHardMixShader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Hard mix.frag", asDefines );
g_hOverlayShader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Overlay.frag", asDefines );
g_hScreenShader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Screen.frag", asDefines );
g_hYUYV422Shader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/YUYV422.frag", asDefines );
g_gCelShader = LoadShader( GL_VERTEX_SHADER_ARB, "Data/Shaders/GLSL/Cel.vert", asDefines);
// used for scrolling textures (I think)
g_bTextureMatrixShader = LoadShader( GL_VERTEX_SHADER_ARB, "Data/Shaders/GLSL/Texture matrix scaling.vert", asDefines );
// these two are for dancing characters and are both actually shader pairs
g_gShellShader = LoadShader( GL_VERTEX_SHADER_ARB, "Data/Shaders/GLSL/Shell.vert", asDefines );
g_gCelShader = LoadShader( GL_VERTEX_SHADER_ARB, "Data/Shaders/GLSL/Cel.vert", asDefines );
// effects
g_bUnpremultiplyShader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Unpremultiply.frag", asDefines );
g_bColorBurnShader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Color burn.frag", asDefines );
g_bColorDodgeShader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Color dodge.frag", asDefines );
g_bVividLightShader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Vivid light.frag", asDefines );
g_hHardMixShader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Hard mix.frag", asDefines );
g_hOverlayShader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Overlay.frag", asDefines );
g_hScreenShader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/Screen.frag", asDefines );
g_hYUYV422Shader = LoadShader( GL_FRAGMENT_SHADER_ARB, "Data/Shaders/GLSL/YUYV422.frag", asDefines );
// Bind attributes.
if( g_bTextureMatrixShader )
@@ -1699,8 +1710,8 @@ bool RageDisplay_OGL::IsEffectModeSupported( EffectMode effect )
case EffectMode_ColorDodge: return g_bColorDodgeShader != 0;
case EffectMode_VividLight: return g_bVividLightShader != 0;
case EffectMode_HardMix: return g_hHardMixShader != 0;
case EffectMode_Overlay: return g_hOverlayShader != 0;
case EffectMode_Screen: return g_hScreenShader != 0;
case EffectMode_Overlay: return g_hOverlayShader != 0;
case EffectMode_Screen: return g_hScreenShader != 0;
case EffectMode_YUYV422: return g_hYUYV422Shader != 0;
}
@@ -1902,14 +1913,14 @@ void RageDisplay_OGL::SetLightDirectional(
void RageDisplay_OGL::SetCullMode( CullMode mode )
{
if (mode != CULL_NONE)
glEnable(GL_CULL_FACE);
switch( mode )
{
case CULL_BACK:
glEnable( GL_CULL_FACE );
glCullFace( GL_BACK );
break;
case CULL_FRONT:
glEnable( GL_CULL_FACE );
glCullFace( GL_FRONT );
break;
case CULL_NONE:
@@ -2633,29 +2644,23 @@ void RageDisplay_OGL::SetSphereEnvironmentMapping( TextureUnit tu, bool b )
GLint iCelTexture1, iCelTexture2 = NULL;
void RageDisplay_OGL::SetCelShaded( bool b )
void RageDisplay_OGL::SetCelShaded( int stage )
{
if( GLExt.glUseProgramObjectARB == NULL )
if( !GLExt.m_bGL_ARB_fragment_shader )
return; // not supported
GLhandleARB hShader = 0;
if( b )
GLExt.glUseProgramObjectARB( g_gCelShader );
else
GLExt.glUseProgramObjectARB( hShader );
if( !b )
return;
/*
* Optimization: don't get these again if we have already done it.
* Getting data from the GPU is (relatively) slow, avoid it if possible.
*/
if( !iCelTexture1 )
switch ( stage )
{
iCelTexture1 = GLExt.glGetUniformLocationARB( hShader, "Texture1" );
case 1:
GLExt.glUseProgramObjectARB( g_gShellShader );
break;
case 2:
GLExt.glUseProgramObjectARB( g_gCelShader );
break;
default:
GLExt.glUseProgramObjectARB( 0 );
break;
}
GLExt.glUniform1iARB( iCelTexture1, 1 );
}
/*
+1 -1
View File
@@ -97,7 +97,7 @@ public:
const RageVector3 &dir );
void SetSphereEnvironmentMapping( TextureUnit tu, bool b );
void SetCelShaded( bool b );
void SetCelShaded( int stage );
RageCompiledGeometry* CreateCompiledGeometry();
void DeleteCompiledGeometry( RageCompiledGeometry* p );
+8 -2
View File
@@ -6,8 +6,11 @@
#include "RageFileBasic.h"
struct lua_State;
/* This is the high-level interface, which interfaces with RageFileObj implementations
* and RageFileManager. */
/**
* @brief High-level file access.
*
* This is the high-level interface, which interfaces with RageFileObj
* implementations and RageFileManager. */
class RageFile: public RageFileBasic
{
public:
@@ -81,6 +84,9 @@ private:
RString m_Path;
RString m_sError;
int m_Mode;
// Swallow up warnings. If they must be used, define them.
RageFile& operator=(const RageFile& rhs);
};
/** @brief Convenience wrappers for reading binary files. */
+3
View File
@@ -152,6 +152,9 @@ private:
* file, and no seeking is performed. */
bool m_bCRC32Enabled;
uint32_t m_iCRC32;
// Swallow up warnings. If they must be used, define them.
RageFileObj& operator=(const RageFileObj& rhs);
};
#endif
+3 -3
View File
@@ -245,14 +245,14 @@ int RageFileObjDeflate::WriteInternal( const void *pBuffer, size_t iBytes )
if( m_pDeflate->avail_out < sizeof(buf) )
{
int iBytes = sizeof(buf)-m_pDeflate->avail_out;
int iRet = m_pFile->Write( buf, iBytes );
int lBytes = sizeof(buf)-m_pDeflate->avail_out;
int iRet = m_pFile->Write( buf, lBytes );
if( iRet == -1 )
{
SetError( m_pFile->GetError() );
return -1;
}
if( iRet < iBytes )
if( iRet < lBytes )
{
SetError( "Partial write" );
return -1;
+2 -2
View File
@@ -377,8 +377,8 @@ void RageFileManager::GetDirListing( const RString &sPath_, vector<RString> &Add
for( unsigned j = OldStart; j < AddTo.size(); ++j )
{
/* Skip the trailing slash on the mountpoint; there's already a slash there. */
RString &sPath = AddTo[j];
sPath.insert( 0, pLoadedDriver->m_sMountPoint, pLoadedDriver->m_sMountPoint.size()-1 );
RString &lPath = AddTo[j];
lPath.insert( 0, pLoadedDriver->m_sMountPoint, pLoadedDriver->m_sMountPoint.size()-1 );
}
}
}
+11 -14
View File
@@ -60,12 +60,9 @@ inline bool IsMouse( InputDevice id ) { return id == DEVICE_MOUSE; }
struct InputDeviceInfo
{
InputDeviceInfo( InputDevice id_, RString sDesc_ )
{
id = id_;
sDesc = sDesc_;
}
InputDeviceInfo( InputDevice id_, RString sDesc_ ):
id(id_), sDesc(sDesc_) {}
InputDevice id;
RString sDesc;
@@ -317,22 +314,22 @@ public:
* (0..1). This should be 0 for analog axes within the dead zone. */
float level;
/* Whether this button is pressed. This is level with a threshold and
* debouncing applied. */
bool bDown;
// Mouse coordinates
unsigned x;
unsigned y;
/* Whether this button is pressed. This is level with a threshold and
* debouncing applied. */
bool bDown;
RageTimer ts;
DeviceInput(): device(InputDevice_Invalid), button(DeviceButton_Invalid), level(0), bDown(false), ts(RageZeroTimer) { }
DeviceInput( InputDevice d, DeviceButton b, float l=0 ): device(d), button(b), level(l), bDown(l > 0.5f), ts(RageZeroTimer) { }
DeviceInput(): device(InputDevice_Invalid), button(DeviceButton_Invalid), level(0), x(0), y(0), bDown(false), ts(RageZeroTimer) { }
DeviceInput( InputDevice d, DeviceButton b, float l=0 ): device(d), button(b), level(l), x(0), y(0), bDown(l > 0.5f), ts(RageZeroTimer) { }
DeviceInput( InputDevice d, DeviceButton b, float l, const RageTimer &t ):
device(d), button(b), level(l), bDown(level > 0.5f), ts(t) { }
device(d), button(b), level(l), x(0), y(0), bDown(level > 0.5f), ts(t) { }
DeviceInput( InputDevice d, DeviceButton b, const RageTimer &t, unsigned xPos=0, unsigned yPos=0 ):
device(d), button(b), x(xPos), y(yPos), bDown(false), ts(t) { }
device(d), button(b), level(0), x(xPos), y(yPos), bDown(false), ts(t) { }
bool operator==( const DeviceInput &other ) const
{
+2 -7
View File
@@ -78,19 +78,14 @@ enum
WRITE_LOUD = 0x04
};
RageLog::RageLog()
RageLog::RageLog(): m_bLogToDisk(false), m_bInfoToDisk(false),
m_bUserLogToDisk(false), m_bFlush(false), m_bShowLogOutput(false)
{
g_fileLog = new RageFile;
g_fileInfo = new RageFile;
g_fileUserLog = new RageFile;
g_Mutex = new RageMutex( "Log" );
m_bLogToDisk = false;
m_bInfoToDisk = false;
m_bUserLogToDisk = false;
m_bFlush = false;
m_bShowLogOutput = false;
}
RageLog::~RageLog()
+2 -2
View File
@@ -575,8 +575,8 @@ float RageFastSin( float x )
bInited = true;
for( unsigned i=0; i<ARRAYLEN(table); i++ )
{
float x = SCALE(i,0,ARRAYLEN(table),0.0f,PI);
table[i] = sinf(x);
float z = SCALE(i,0,ARRAYLEN(table),0.0f,PI);
table[i] = sinf(z);
}
}
+9 -25
View File
@@ -39,36 +39,20 @@
#define samplerate() m_pSource->GetSampleRate()
RageSoundParams::RageSoundParams():
m_StartTime( RageZeroTimer )
{
m_StartSecond = 0;
m_LengthSeconds = -1;
m_fFadeInSeconds = 0;
m_fFadeOutSeconds = 0;
m_Volume = 1.0f;
m_fAttractVolume = 1.0f;
m_fPitch = 1.0f;
m_fSpeed = 1.0f;
StopMode = M_AUTO;
m_bIsCriticalSound = false;
}
m_StartSecond(0), m_LengthSeconds(-1), m_fFadeInSeconds(0),
m_fFadeOutSeconds(0), m_Volume(1.0f), m_fAttractVolume(1.0f),
m_fPitch(1.0f), m_fSpeed(1.0f), m_StartTime( RageZeroTimer ),
StopMode(M_AUTO), m_bIsCriticalSound(false) {}
RageSoundLoadParams::RageSoundLoadParams()
{
m_bSupportRateChanging = false;
m_bSupportPan = false;
}
RageSoundLoadParams::RageSoundLoadParams():
m_bSupportRateChanging(false), m_bSupportPan(false) {}
RageSound::RageSound():
m_Mutex( "RageSound" )
m_Mutex( "RageSound" ), m_pSource(NULL), m_iStreamFrame(0),
m_iStoppedSourceFrame(0), m_bPlaying(false),
m_bDeleteWhenFinished(false)
{
ASSERT( SOUNDMAN );
m_pSource = NULL;
m_iStreamFrame = 0;
m_iStoppedSourceFrame = 0;
m_bPlaying = false;
m_bDeleteWhenFinished = false;
}
RageSound::~RageSound()
+10 -11
View File
@@ -22,7 +22,10 @@ public:
virtual RString GetLoadedFilePath() const = 0;
};
/* These are parameters to play a sound. These are normally changed before playing begins,
/**
* @brief The parameters to play a sound.
*
* These are normally changed before playing begins,
* and are constant from then on. */
struct RageSoundParams
{
@@ -50,17 +53,13 @@ struct RageSoundParams
* If zero, or if not supported, the sound will start immediately. */
RageTimer m_StartTime;
/* M_STOP stops the sound at the end.
* M_LOOP restarts.
* M_CONTINUE feeds silence, which is useful to continue timing longer than the actual sound.
* M_AUTO (default) stops, obeying filename hints.
*/
/** @brief How does the sound stop itself, if it does? */
enum StopMode_t {
M_STOP,
M_LOOP,
M_CONTINUE,
M_AUTO
} StopMode;
M_STOP, /**< The sound is stopped at the end. */
M_LOOP, /**< The sound restarts itself. */
M_CONTINUE, /**< Silence is fed at the end to continue timing longer than the sound. */
M_AUTO /**< The default, the sound stops while obeying filename hints. */
} /** @brief How does the sound stop itself, if it does? */ StopMode;
bool m_bIsCriticalSound; // "is a sound that should be played even during attract"
};
+2 -5
View File
@@ -35,11 +35,8 @@ static Preference<RString> g_sSoundDrivers( "SoundDrivers", "" ); // "" == DEFAU
RageSoundManager *SOUNDMAN = NULL;
RageSoundManager::RageSoundManager()
{
m_fMixVolume = 1.0f;
m_fVolumeOfNonCriticalSounds = 1.0f;
}
RageSoundManager::RageSoundManager(): m_pDriver(NULL), m_fMixVolume(1.0f),
m_fVolumeOfNonCriticalSounds(1.0f) {}
static LocalizedString COULDNT_FIND_SOUND_DRIVER( "RageSoundManager", "Couldn't find a sound driver that works" );
void RageSoundManager::Init()
+3
View File
@@ -53,6 +53,9 @@ private:
/* Prefs: */
float m_fMixVolume;
float m_fVolumeOfNonCriticalSounds;
// Swallow up warnings. If they must be used, define them.
RageSoundManager& operator=(const RageSoundManager& rhs);
RageSoundManager(const RageSoundManager& rhs);
};
extern RageSoundManager *SOUNDMAN;
-3
View File
@@ -33,7 +33,6 @@ RageSoundReader_Chain::~RageSoundReader_Chain()
while( !m_apActiveSounds.empty() )
ReleaseSound( m_apActiveSounds.front() );
map<RString, RageSoundReader *>::iterator it;
FOREACH( RageSoundReader *, m_apLoadedSounds, it )
delete *it;
}
@@ -103,7 +102,6 @@ int RageSoundReader_Chain::GetSampleRateInternal() const
if( m_apLoadedSounds.empty() )
return m_iPreferredSampleRate;
map<RString, RageSoundReader *>::const_iterator it;
int iRate = -1;
FOREACH_CONST( RageSoundReader *, m_apLoadedSounds, it )
{
@@ -120,7 +118,6 @@ void RageSoundReader_Chain::Finish()
/* Figure out how many channels we have. All sounds must either have 1 or 2 channels,
* which will be converted as needed, or have the same number of channels. */
m_iChannels = 1;
map<RString, RageSoundReader *>::iterator it;
FOREACH( RageSoundReader *, m_apLoadedSounds, it )
m_iChannels = max( m_iChannels, (*it)->GetNumChannels() );
+1 -1
View File
@@ -426,7 +426,7 @@ int RageSoundReader_MP3::do_mad_frame_decode( bool headers_only )
return -1;
}
int ret = fill_buffer();
ret = fill_buffer();
if( ret <= 0 )
return ret;
bytes_read += ret;
-1
View File
@@ -18,7 +18,6 @@ RageSoundReader_Merge::RageSoundReader_Merge()
RageSoundReader_Merge::~RageSoundReader_Merge()
{
map<RString, RageSoundReader *>::iterator it;
FOREACH( RageSoundReader *, m_aSounds, it )
delete *it;
}
+2
View File
@@ -29,6 +29,8 @@ private:
float m_fPitchRatio;
float m_fLastSetSpeedRatio;
float m_fLastSetPitchRatio;
// Swallow up warnings. If they must be used, define them.
RageSoundReader_PitchChange& operator=(const RageSoundReader_PitchChange& rhs);
};
#endif
+2 -1
View File
@@ -34,7 +34,8 @@ bool RageSoundReader_Preload::PreloadSound( RageSoundReader *&pSound )
}
RageSoundReader_Preload::RageSoundReader_Preload():
m_Buffer( new RString )
m_Buffer( new RString ), m_bBufferIs16Bit(false),
m_iPosition(0), m_iSampleRate(0), m_iChannels(0), m_fRate(0.0f)
{
m_bBufferIs16Bit = g_bSoundPreload16bit.Get();
}
+2 -1
View File
@@ -53,7 +53,8 @@ private:
int iFramesBuffered;
int iPositionOfFirstFrame;
float fRate;
Mapping() { iFramesBuffered = iPositionOfFirstFrame = 0; fRate = 1.0f; }
Mapping(): iFramesBuffered(0), iPositionOfFirstFrame(0),
fRate(1.0f) {}
};
list<Mapping> m_StreamPosition;
+1 -1
View File
@@ -7,7 +7,7 @@
struct RageSurfaceColor
{
uint8_t r, g, b, a;
RageSurfaceColor() { }
RageSurfaceColor(): r(0), g(0), b(0), a(0) { }
RageSurfaceColor( uint8_t r_, uint8_t g_, uint8_t b_, uint8_t a_ ):
r(r_), g(g_), b(b_), a(a_) { }
+2 -2
View File
@@ -585,8 +585,8 @@ static bool blit_rgba_to_rgba( const RageSurface *src_surf, const RageSurface *d
unsigned int opixel = 0;
for( int c = 0; c < 4; ++c )
{
int src = (pixel & src_masks[c]) >> src_shifts[c];
opixel |= lookup[c][src] << dst_shifts[c];
int lSrc = (pixel & src_masks[c]) >> src_shifts[c];
opixel |= lookup[c][lSrc] << dst_shifts[c];
}
// Store it.
+6 -6
View File
@@ -454,7 +454,7 @@ static acolorhist_item *mediancut( acolorhist_item *achv, int colors, int sum, i
#ifdef REP_AVERAGE_PIXELS
int indx = bv[bi].ind;
int clrs = bv[bi].colors;
long r = 0, g = 0, b = 0, a = 0, sum = 0;
long r = 0, g = 0, b = 0, a = 0, lSum = 0;
for ( int i = 0; i < clrs; ++i )
{
@@ -462,15 +462,15 @@ static acolorhist_item *mediancut( acolorhist_item *achv, int colors, int sum, i
g += PAM_GETG( achv[indx + i].acolor ) * achv[indx + i].value;
b += PAM_GETB( achv[indx + i].acolor ) * achv[indx + i].value;
a += PAM_GETA( achv[indx + i].acolor ) * achv[indx + i].value;
sum += achv[indx + i].value;
lSum += achv[indx + i].value;
}
r = r / sum;
r = r / lSum;
r = min( r, (long) maxval );
g = g / sum;
g = g / lSum;
g = min( g, (long) maxval );
b = b / sum;
b = b / lSum;
b = min( b, (long) maxval );
a = a / sum;
a = a / lSum;
a = min( a, (long) maxval );
PAM_ASSIGN( acolormap[bi].acolor, (uint8_t)r, (uint8_t)g, (uint8_t)b, (uint8_t)a );
#endif // REP_AVERAGE_PIXELS
+5 -10
View File
@@ -7,16 +7,11 @@
RageTexture::RageTexture( RageTextureID name ):
m_ID(name)
{
m_iRefCount = 1;
m_bWasUsed = false;
m_iSourceWidth = m_iSourceHeight = 0;
m_iTextureWidth = m_iTextureHeight = 0;
m_iImageWidth = m_iImageHeight = 0;
m_iFramesWide = m_iFramesHigh = 1;
}
m_ID(name), m_iRefCount(1), m_bWasUsed(false),
m_iSourceWidth(0), m_iSourceHeight(0),
m_iTextureWidth(0), m_iTextureHeight(0),
m_iImageWidth(0), m_iImageHeight(0),
m_iFramesWide(1), m_iFramesHigh(1) {}
RageTexture::~RageTexture()
+9 -2
View File
@@ -59,8 +59,15 @@ struct RageTextureID
void Init();
RageTextureID() { Init(); }
RageTextureID( const RString &fn ) { Init(); SetFilename(fn); }
RageTextureID(): filename(RString()), iMaxSize(0), bMipMaps(false),
iAlphaBits(0), iGrayscaleBits(0), iColorDepth(0),
bDither(false), bStretch(false), bHotPinkColorKey(false),
AdditionalTextureHints(RString()), Policy(TEX_DEFAULT) { Init(); }
RageTextureID( const RString &fn ): filename(RString()), iMaxSize(0),
bMipMaps(false), iAlphaBits(0), iGrayscaleBits(0),
iColorDepth(0), bDither(false), bStretch(false),
bHotPinkColorKey(false), AdditionalTextureHints(RString()),
Policy(TEX_DEFAULT) { Init(); SetFilename(fn); }
void SetFilename( const RString &fn );
};
+4 -7
View File
@@ -36,11 +36,9 @@ namespace
map<RageTextureID, RageTexture*> m_mapPathToTexture;
};
RageTextureManager::RageTextureManager()
{
m_iNoWarnAboutOddDimensions = 0;
m_TexturePolicy = RageTextureID::TEX_DEFAULT;
}
RageTextureManager::RageTextureManager():
m_iNoWarnAboutOddDimensions(0),
m_TexturePolicy(RageTextureID::TEX_DEFAULT) {}
RageTextureManager::~RageTextureManager()
{
@@ -106,9 +104,8 @@ class RageTexture_Default: public RageTexture
{
public:
RageTexture_Default():
RageTexture( RageTextureID() )
RageTexture( RageTextureID() ), m_uTexHandle(0)
{
m_uTexHandle = 0;
m_iSourceWidth = m_iSourceHeight = 1;
m_iTextureWidth = m_iTextureHeight = 1;
m_iImageWidth = m_iImageHeight = 1;
+11 -18
View File
@@ -14,30 +14,23 @@ struct RageTextureManagerPrefs
bool m_bHighResolutionTextures;
bool m_bMipMaps;
RageTextureManagerPrefs()
{
m_bDelayedDelete = false;
m_iMovieColorDepth = 16;
m_iTextureColorDepth = 16;
m_iMaxTextureResolution = 1024;
m_bHighResolutionTextures = true;
m_bMipMaps = false;
}
RageTextureManagerPrefs(): m_iTextureColorDepth(16),
m_iMovieColorDepth(16), m_bDelayedDelete(false),
m_iMaxTextureResolution(1024),
m_bHighResolutionTextures(true), m_bMipMaps(false) {}
RageTextureManagerPrefs(
int iTextureColorDepth,
int iMovieColorDepth,
bool bDelayedDelete,
int iMaxTextureResolution,
bool bHighResolutionTextures,
bool bMipMaps )
{
m_bDelayedDelete = bDelayedDelete;
m_iMovieColorDepth = iMovieColorDepth;
m_iTextureColorDepth = iTextureColorDepth;
m_iMaxTextureResolution = iMaxTextureResolution;
m_bHighResolutionTextures = bHighResolutionTextures;
m_bMipMaps = bMipMaps;
}
bool bMipMaps ):
m_iTextureColorDepth(iTextureColorDepth),
m_iMovieColorDepth(iMovieColorDepth),
m_bDelayedDelete(bDelayedDelete),
m_iMaxTextureResolution(iMaxTextureResolution),
m_bHighResolutionTextures(bHighResolutionTextures),
m_bMipMaps(bMipMaps) {}
bool operator!=( const RageTextureManagerPrefs& rhs ) const
{
+12 -26
View File
@@ -65,7 +65,8 @@ struct ThreadSlot
int m_iCurCheckpoint, m_iNumCheckpoints;
const char *GetFormattedCheckpoint( int lineno );
ThreadSlot() { Init(); }
ThreadSlot(): m_bUsed(false), m_iID(GetInvalidThreadId()),
m_pImpl(NULL), m_iCurCheckpoint(0), m_iNumCheckpoints(0) {}
void Init()
{
m_iID = GetInvalidThreadId();
@@ -206,18 +207,11 @@ static ThreadSlot *GetUnknownThreadSlot()
return g_pUnknownThreadSlot;
}
RageThread::RageThread()
{
m_pSlot = NULL;
m_sName = "unnamed";
}
RageThread::RageThread(): m_pSlot(NULL), m_sName("unnamed") {}
RageThread::RageThread( const RageThread &cpy )
{
/* Copying a thread does not start the copy. */
m_pSlot = NULL;
m_sName = cpy.m_sName;
}
/* Copying a thread does not start the copy. */
RageThread::RageThread( const RageThread &cpy ):
m_pSlot(NULL), m_sName(cpy.m_sName) {}
RageThread::~RageThread()
{
@@ -520,12 +514,9 @@ static set<int> *g_FreeMutexIDs = NULL;
#endif
RageMutex::RageMutex( const RString &name ):
m_sName( name )
m_sName( name ), m_pMutex( MakeMutex (this ) ),
m_LockedBy(GetInvalidThreadId()), m_LockCnt(0)
{
m_pMutex = MakeMutex( this );
m_LockedBy = GetInvalidThreadId();
m_LockCnt = 0;
/* if( g_FreeMutexIDs == NULL )
{
@@ -659,7 +650,8 @@ LockMutex::LockMutex( RageMutex &pMutex, const char *file_, int line_ ):
mutex( pMutex ),
file( file_ ),
line( line_ ),
locked_at( RageTimer::GetTimeSinceStart() )
locked_at( RageTimer::GetTimeSinceStart() ),
locked(false) // ensure it gets locked inside.
{
mutex.Lock();
locked = true;
@@ -687,10 +679,7 @@ void LockMutex::Unlock()
}
RageEvent::RageEvent( RString name ):
RageMutex( name )
{
m_pEvent = MakeEvent( m_pMutex );
}
RageMutex( name ), m_pEvent(MakeEvent(m_pMutex)) {}
RageEvent::~RageEvent()
{
@@ -732,10 +721,7 @@ bool RageEvent::WaitTimeoutSupported() const
}
RageSemaphore::RageSemaphore( RString sName, int iInitialValue ):
m_sName( sName )
{
m_pSema = MakeSemaphore( iInitialValue );
}
m_sName( sName ), m_pSema(MakeSemaphore( iInitialValue )) {}
RageSemaphore::~RageSemaphore()
{
+20
View File
@@ -46,6 +46,9 @@ private:
static bool s_bSystemSupportsTLS;
static bool s_bIsShowingDialog;
// Swallow up warnings. If they must be used, define them.
RageThread& operator=(const RageThread& rhs);
};
/**
@@ -61,6 +64,9 @@ public:
private:
ThreadSlot *m_pSlot;
// Swallow up warnings. If they must be used, define them.
RageThreadRegister& operator=(const RageThreadRegister& rhs);
RageThreadRegister(const RageThreadRegister& rhs);
};
namespace Checkpoints
@@ -102,6 +108,10 @@ protected:
int m_LockCnt;
void MarkLockedMutex();
private:
// Swallow up warnings. If they must be used, define them.
RageMutex& operator=(const RageMutex& rhs);
RageMutex(const RageMutex& rhs);
};
/**
@@ -128,6 +138,9 @@ public:
*
* This can only be called once. */
void Unlock();
private:
// Swallow up warnings. If they must be used, define them.
LockMutex& operator=(const LockMutex& rhs);
};
#define LockMut(m) LockMutex UNIQUE_NAME(LocalLock) (m, __FILE__, __LINE__)
@@ -149,6 +162,9 @@ public:
void Signal();
void Broadcast();
bool WaitTimeoutSupported() const;
// Swallow up warnings. If they must be used, define them.
RageEvent& operator=(const RageEvent& rhs);
RageEvent(const RageEvent& rhs);
private:
EventImpl *m_pEvent;
@@ -170,6 +186,10 @@ public:
private:
SemaImpl *m_pSema;
RString m_sName;
// Swallow up warnings. If they must be used, define them.
RageSemaphore& operator=(const RageSemaphore& rhs);
RageSemaphore(const RageSemaphore& rhs);
};
#endif
+1 -1
View File
@@ -6,7 +6,7 @@
class RageTimer
{
public:
RageTimer() { Touch(); }
RageTimer(): m_secs(0), m_us(0) { Touch(); }
RageTimer( int secs, int us ): m_secs(secs), m_us(us) { }
/* Time ago this RageTimer represents. */

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