fold CroppedSprite functionality into Sprite

more work on Rave
This commit is contained in:
Chris Danford
2003-07-03 06:38:57 +00:00
parent 12d77daa2a
commit 9c9aef37c7
36 changed files with 450 additions and 433 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 B

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

+48 -12
View File
@@ -641,6 +641,24 @@ OptionsMessageOnCommand=zoomy,0;linear,0.25;zoomy,1;sleep,1;linear,0.25;zoomy,0
HelpText=&LEFT; or &RIGHT; change music Hold &LEFT; and &RIGHT; then press START to change sort::&UP;&UP; easier difficulty &DOWN;&DOWN; harder difficulty::&UP;&DOWN;&UP;&DOWN; to change sort
TimerSeconds=60
SampleMusicDelay=0.25
PrevScreenArcade=ScreenTitleMenu
PrevScreenNonstop=ScreenTitleMenu
PrevScreenOni=ScreenTitleMenu
PrevScreenEndless=ScreenTitleMenu
PrevScreenBattle=ScreenTitleMenu
PrevScreenRave=ScreenTitleMenu
NextScreenArcade=ScreenStage
NextScreenNonstop=ScreenStage
NextScreenOni=ScreenStage
NextScreenEndless=ScreenStage
NextScreenBattle=ScreenStage
NextScreenRave=ScreenStage
NextOptionsScreenArcade=ScreenPlayerOptions
NextOptionsScreenNonstop=ScreenPlayerOptions
NextOptionsScreenOni=ScreenPlayerOptions
NextOptionsScreenEndless=ScreenPlayerOptions
NextOptionsScreenBattle=ScreenPlayerOptions
NextOptionsScreenRave=ScreenRaveOptions
[ScreenEz2SelectMusic]
UseModeSwitcher=0
@@ -687,6 +705,24 @@ DifficultyRatingY=999
DifficultyRatingOrientation=0
DifficultyRatingSpacing=40.0
PreviewMusicMode=0 // 0 = play music as you select, 1 = no music plays, select once and preview music plays, select again for confirm, 2 = no music plays at all, 3 = play music as select, press twice to confirm, 4 = static menu music plays, no confirm
PrevScreenArcade=ScreenTitleMenu
PrevScreenNonstop=ScreenTitleMenu
PrevScreenOni=ScreenTitleMenu
PrevScreenEndless=ScreenTitleMenu
PrevScreenBattle=ScreenTitleMenu
PrevScreenRave=ScreenTitleMenu
NextScreenArcade=ScreenStage
NextScreenNonstop=ScreenStage
NextScreenOni=ScreenStage
NextScreenEndless=ScreenStage
NextScreenBattle=ScreenStage
NextScreenRave=ScreenStage
NextOptionsScreenArcade=ScreenPlayerOptions
NextOptionsScreenNonstop=ScreenPlayerOptions
NextOptionsScreenOni=ScreenPlayerOptions
NextOptionsScreenEndless=ScreenPlayerOptions
NextOptionsScreenBattle=ScreenPlayerOptions
NextOptionsScreenRave=ScreenRaveOptions
[ScreenSelectCourse]
ExplanationX=132
@@ -1805,7 +1841,7 @@ InCommand=diffusealpha,0;zoomy,0;spring,0.20;zoomy,1;diffusealpha,1
OutCommand=linear,0.20;zoomy,0;diffusealpha,1
[ScoreKeeperRave]
AttackDurationSeconds=5
AttackDurationSeconds=10
[ScreenInputOptions]
HelpText=&UP; &DOWN; to change line &LEFT; &RIGHT; to select between options::START to accept changes BACK to discard changes
@@ -2079,17 +2115,17 @@ HelpText=&UP; &DOWN; to change line &LEFT; &RIGHT; to select between options
TimerSeconds=30
[ScreenRaveOptions]
PrevScreenArcade=ScreenPlayerOptions
PrevScreenNonstop=ScreenPlayerOptions
PrevScreenOni=ScreenPlayerOptions
PrevScreenEndless=ScreenPlayerOptions
PrevScreenBattle=ScreenPlayerOptions
PrevScreenRave=ScreenPlayerOptions
NextScreenArcade=ScreenSongOptions
NextScreenNonstop=ScreenSongOptions
NextScreenOni=ScreenSongOptions
NextScreenEndless=ScreenSongOptions
NextScreenBattle=ScreenSongOptions
PrevScreenArcade= // should never get here
PrevScreenNonstop= // should never get here
PrevScreenOni= // should never get here
PrevScreenEndless= // should never get here
PrevScreenBattle= // should never get here
PrevScreenRave=ScreenSelectMusic
NextScreenArcade= // should never get here
NextScreenNonstop= // should never get here
NextScreenOni= // should never get here
NextScreenEndless= // should never get here
NextScreenBattle= // should never get here
NextScreenRave=ScreenSongOptions
HelpText=&UP; &DOWN; to change line &LEFT; &RIGHT; to select between options START to accept changes
TimerSeconds=30
+1 -1
View File
@@ -256,7 +256,7 @@ public:
void FadeOn( float fSleepSeconds, CString sFadeString, float fFadeSeconds ) { Fade(fSleepSeconds,sFadeString,fFadeSeconds,false); };
void FadeOff( float fSleepSeconds, CString sFadeString, float fFadeSeconds ) { Fade(fSleepSeconds,sFadeString,fFadeSeconds,true); };
float Command( CString sCommandString ); // return length in seconds to execute command
virtual float Command( CString sCommandString ); // return length in seconds to execute command
static float GetCommandLength( CString command );
virtual void SetState( int iNewState ) {};
+6 -12
View File
@@ -23,7 +23,7 @@
#include "song.h"
#include "ThemeManager.h"
#include "ActorCollision.h"
#include "CroppedSprite.h"
#include "Sprite.h"
@@ -438,12 +438,6 @@ void BGAnimationLayer::LoadFromAniLayerFile( CString sPath )
*/
}
static Sprite *NewSprite(bool banner)
{
if(banner) return new CroppedSprite;
return new Sprite;
}
void BGAnimationLayer::LoadFromIni( CString sAniDir, CString sLayer )
{
@@ -535,13 +529,13 @@ void BGAnimationLayer::LoadFromIni( CString sAniDir, CString sLayer )
switch( m_Type )
{
case TYPE_SPRITE:
m_Sprites.push_back(NewSprite(IsBanner));
m_Sprites.push_back( new Sprite );
m_Sprites.back()->Load( sPath );
m_Sprites.back()->SetXY( CENTER_X, CENTER_Y );
break;
case TYPE_STRETCH:
{
m_Sprites.push_back(NewSprite(IsBanner));
m_Sprites.push_back( new Sprite );
RageTextureID ID(sPath);
ID.bStretch = true;
m_Sprites.back()->LoadBG( ID );
@@ -553,7 +547,7 @@ void BGAnimationLayer::LoadFromIni( CString sAniDir, CString sLayer )
{
for( int i=0; i<m_iNumParticles; i++ )
{
m_Sprites.push_back(NewSprite(IsBanner));
m_Sprites.push_back( new Sprite );
m_Sprites.back()->Load( sPath );
m_Sprites.back()->SetXY( randomf(SCREEN_LEFT,SCREEN_RIGHT), randomf(SCREEN_TOP,SCREEN_BOTTOM) );
m_Sprites.back()->SetZoom( randomf(m_fZoomMin,m_fZoomMax) );
@@ -584,7 +578,7 @@ void BGAnimationLayer::LoadFromIni( CString sAniDir, CString sLayer )
unsigned NumSprites = m_iNumTilesWide * m_iNumTilesHigh;
for( unsigned i=0; i<NumSprites; i++ )
{
m_Sprites.push_back(NewSprite(IsBanner));
m_Sprites.push_back( new Sprite );
m_Sprites.back()->Load( ID );
m_Sprites.back()->SetTextureWrapping( true ); // gets rid of some "cracks"
m_Sprites.back()->SetZoom( randomf(m_fZoomMin,m_fZoomMax) );
@@ -639,7 +633,7 @@ void BGAnimationLayer::Update( float fDeltaTime )
for( i=0; i<m_Sprites.size(); i++ )
{
float fTexCoords[8];
m_Sprites[i]->GetActiveTexCoords( fTexCoords );
m_Sprites[i]->GetActiveTextureCoords( fTexCoords );
for( int j=0; j<8; j+=2 )
{
+8 -2
View File
@@ -45,12 +45,12 @@ bool Banner::Load( RageTextureID ID )
m_bScrolling = false;
TEXTUREMAN->VolatileTexture( ID );
return CroppedSprite::Load( ID );
return Sprite::Load( ID );
};
void Banner::Update( float fDeltaTime )
{
CroppedSprite::Update( fDeltaTime );
Sprite::Update( fDeltaTime );
if( m_bScrolling )
{
@@ -129,3 +129,9 @@ void Banner::LoadRandom()
Load( THEME->GetPathToG("Banner random") );
m_bScrolling = true;
}
void Banner::ScaleToClipped( float fWidth, float fHeight )
{
m_fRememberedClipWidth = fWidth;
m_fRememberedClipHeight = fHeight;
}
+5 -2
View File
@@ -11,13 +11,13 @@
-----------------------------------------------------------------------------
*/
#include "CroppedSprite.h"
#include "Sprite.h"
#include "RageTexture.h"
class Song;
class Course;
class Banner : public CroppedSprite
class Banner : public Sprite
{
public:
Banner();
@@ -27,6 +27,8 @@ public:
virtual void Update( float fDeltaTime );
virtual void ScaleToClipped( float fWidth, float fHeight );
void LoadFromSong( Song* pSong ); // NULL means no song
void LoadAllMusic();
void LoadFromGroup( CString sGroupName );
@@ -42,6 +44,7 @@ public:
static RageTextureID BannerTex( RageTextureID ID );
protected:
bool m_bScrolling;
float m_fPercentScrolling;
};
+4 -4
View File
@@ -10,7 +10,7 @@
#include "RageUtil.h"
#include "RageLog.h"
#include "BannerCache.h"
#include "CroppedSprite.h"
#include "Sprite.h"
#include "PrefsManager.h"
#include "SDL_utils.h"
#include "SDL_dither.h"
@@ -243,7 +243,7 @@ RageTextureID BannerCache::LoadCachedBanner( CString BannerPath )
if( WasRotatedBanner )
{
/* We need to tell CroppedSprite that this was originally a rotated
/* We need to tell Sprite that this was originally a rotated
* sprite. */
ID.filename += "(was rotated)";
}
@@ -300,7 +300,7 @@ void BannerCache::CacheBannerInternal( CString BannerPath )
bool WasRotatedBanner = false;
if( CroppedSprite::IsDiagonalBanner(img->w , img->h) )
if( Sprite::IsDiagonalBanner(img->w , img->h) )
{
/* Ack. It's a diagonal banner. Problem: if we resize a diagonal banner, we
* get ugly checker patterns. We need to un-rotate it.
@@ -403,7 +403,7 @@ void BannerCache::CacheBannerInternal( CString BannerPath )
BannerData.SetValueI( BannerPath, "Width", src_width );
BannerData.SetValueI( BannerPath, "Height", src_height );
BannerData.SetValueU( BannerPath, "FullHash", GetHashForFile( BannerPath ) );
/* Remember this, so we can hint CroppedSprite. */
/* Remember this, so we can hint Sprite. */
BannerData.SetValueB( BannerPath, "Rotated", WasRotatedBanner );
BannerData.WriteFile();
}
+8 -8
View File
@@ -18,7 +18,7 @@ CombinedLifeMeterTug::CombinedLifeMeterTug()
{
for( int p=0; p<NUM_PLAYERS; p++ )
{
m_Stream[p].Load( THEME->GetPathToG(ssprintf("CombinedLifeMeterTug stream p%d",p+1)), 600 );
m_Stream[p].Load( THEME->GetPathToG(ssprintf("CombinedLifeMeterTug stream p%d",p+1)), 550 );
this->AddChild( &m_Stream[p] );
}
m_Stream[PLAYER_2].SetZoomX( -1 );
@@ -40,13 +40,13 @@ void CombinedLifeMeterTug::ChangeLife( PlayerNumber pn, TapNoteScore score )
float fPercentToMove;
switch( score )
{
case TNS_MARVELOUS: fPercentToMove = +0.02f; break;
case TNS_PERFECT: fPercentToMove = +0.02f; break;
case TNS_GREAT: fPercentToMove = +0.01f; break;
case TNS_GOOD: fPercentToMove = +0.00f; break;
case TNS_BOO: fPercentToMove = -0.02f; break;
case TNS_MISS: fPercentToMove = -0.04f; break;
default: ASSERT(0); fPercentToMove = +0.00f; break;
case TNS_MARVELOUS: fPercentToMove = +0.010f; break;
case TNS_PERFECT: fPercentToMove = +0.010f; break;
case TNS_GREAT: fPercentToMove = +0.005f; break;
case TNS_GOOD: fPercentToMove = +0.000f; break;
case TNS_BOO: fPercentToMove = -0.010f; break;
case TNS_MISS: fPercentToMove = -0.020f; break;
default: ASSERT(0); fPercentToMove = +0.000f; break;
}
switch( pn )
-146
View File
@@ -1,146 +0,0 @@
#include "global.h"
/*
-----------------------------------------------------------------------------
File: CroppedSprite.h
Desc: The song's CroppedSprite displayed in SelectSong.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
#include "RageUtil.h"
#include "CroppedSprite.h"
#include "PrefsManager.h"
#include "RageBitmapTexture.h"
#include <math.h>
CroppedSprite::CroppedSprite()
{
/* By default, crop to the size of the image. */
m_fCropWidth = m_fCropHeight = -1;
}
bool CroppedSprite::Load( RageTextureID ID )
{
Sprite::Load( ID );
CropToSize( m_fCropWidth, m_fCropHeight );
return true;
}
void CroppedSprite::SetWH(float fWidth, float fHeight)
{
Sprite::SetWidth(fWidth);
Sprite::SetHeight(fHeight);
}
void CroppedSprite::SetCroppedSize( float fWidth, float fHeight )
{
m_fCropWidth = fWidth;
m_fCropHeight = fHeight;
}
void CroppedSprite::CropToSize( float fWidth, float fHeight )
{
m_fCropWidth = fWidth;
m_fCropHeight = fHeight;
int iSourceWidth = m_pTexture->GetSourceWidth();
int iSourceHeight = m_pTexture->GetSourceHeight();
// save the original X&Y. We're going to resore them later.
float fOriginalX = GetX();
float fOriginalY = GetY();
if( IsDiagonalBanner(iSourceWidth, iSourceHeight) ) // this is a SSR/DWI CroppedSprite
{
float fCustomImageCoords[8] = {
0.02f, 0.78f, // top left
0.22f, 0.98f, // bottom left
0.98f, 0.22f, // bottom right
0.78f, 0.02f, // top right
};
Sprite::SetCustomImageCoords( fCustomImageCoords );
if( m_fCropWidth != -1 && m_fCropHeight != -1)
m_size = RageVector2( m_fCropWidth, m_fCropHeight );
else
{
/* If no crop size is set, then we're only being used to crop diagonal
* banners so they look like regular ones. We don't actually care about
* the size of the image, only that it has an aspect ratio of 4:1. */
m_size = RageVector2(256, 64);
}
SetZoom( 1 );
}
else if( m_pTexture->GetID().filename.find( "(was rotated)" ) != m_pTexture->GetID().filename.npos &&
m_fCropWidth != -1 && m_fCropHeight != -1 )
{
/* Dumb hack. Normally, we crop all sprites except for diagonal banners,
* which are stretched. Low-res versions of banners need to do the same
* thing as their full resolution counterpart, so the crossfade looks right.
* However, low-res diagonal banners are un-rotated, to save space. BannerCache
* drops the above text into the "filename" (which is otherwise unused for
* these banners) to tell us this.
*/
Sprite::StopUsingCustomCoords();
m_size = RageVector2( m_fCropWidth, m_fCropHeight );
SetZoom( 1 );
}
else if( m_fCropWidth != -1 && m_fCropHeight != -1 )
{
// this is probably a background graphic or something not intended to be a CroppedSprite
Sprite::StopUsingCustomCoords();
// first find the correct zoom
Sprite::ScaleToCover( RectI(0, 0,
(int)m_fCropWidth,
(int)m_fCropHeight )
);
// find which dimension is larger
bool bXDimNeedsToBeCropped = GetZoomedWidth() > m_fCropWidth+0.01;
if( bXDimNeedsToBeCropped ) // crop X
{
float fPercentageToCutOff = (this->GetZoomedWidth() - m_fCropWidth) / this->GetZoomedWidth();
float fPercentageToCutOffEachSide = fPercentageToCutOff / 2;
// generate a rectangle with new texture coordinates
RectF fCustomImageRect(
fPercentageToCutOffEachSide,
0,
1 - fPercentageToCutOffEachSide,
1 );
SetCustomImageRect( fCustomImageRect );
}
else // crop Y
{
float fPercentageToCutOff = (this->GetZoomedHeight() - m_fCropHeight) / this->GetZoomedHeight();
float fPercentageToCutOffEachSide = fPercentageToCutOff / 2;
// generate a rectangle with new texture coordinates
RectF fCustomImageRect(
0,
fPercentageToCutOffEachSide,
1,
1 - fPercentageToCutOffEachSide );
SetCustomImageRect( fCustomImageRect );
}
m_size = RageVector2( m_fCropWidth, m_fCropHeight );
SetZoom( 1 );
}
// restore original XY
SetXY( fOriginalX, fOriginalY );
}
bool CroppedSprite::IsDiagonalBanner( int iWidth, int iHeight )
{
/* A diagonal banner is a square. Give a couple pixels of leeway. */
return iWidth >= 100 && abs(iWidth - iHeight) < 2;
}
-37
View File
@@ -1,37 +0,0 @@
#ifndef CROPPEDSPRITE_H
#define CROPPEDSPRITE_H
/*
-----------------------------------------------------------------------------
Class: CroppedSprite
Desc: The a bitmap that is cropped and zoomed to fill a box.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "Sprite.h"
class CroppedSprite : public Sprite
{
public:
CroppedSprite();
virtual ~CroppedSprite() { }
bool Load( RageTextureID ID );
void SetCroppedSize( float fWidth, float fHeight );
void SetWH(float fWidth, float fHeight);
static bool IsDiagonalBanner( int iWidth, int iHeight );
protected:
void CropToSize( float fWidth, float fHeight );
float m_fCropWidth, m_fCropHeight;
};
#endif
+1 -1
View File
@@ -37,7 +37,7 @@ const float CAMERA_STILL_HEIGHT_VARIANCE = 6.f;
const float CAMERA_STILL_LOOK_AT_HEIGHT = -14.f;
const float MODEL_X_ONE_PLAYER = 0;
const float MODEL_X_TWO_PLAYERS[NUM_PLAYERS] = { -8, 8 };
const float MODEL_X_TWO_PLAYERS[NUM_PLAYERS] = { +8, -8 };
DancingCharacters::DancingCharacters()
+2 -2
View File
@@ -83,11 +83,9 @@ EditMenu::EditMenu()
}
m_GroupBanner.SetXY( GROUP_BANNER_X, GROUP_BANNER_Y );
m_GroupBanner.SetCroppedSize( GROUP_BANNER_WIDTH, GROUP_BANNER_HEIGHT );
this->AddChild( &m_GroupBanner );
m_SongBanner.SetXY( SONG_BANNER_X, SONG_BANNER_Y );
m_SongBanner.SetCroppedSize( SONG_BANNER_WIDTH, SONG_BANNER_HEIGHT );
this->AddChild( &m_SongBanner );
m_SongTextBanner.SetXY( SONG_TEXT_BANNER_X, SONG_TEXT_BANNER_Y );
@@ -258,6 +256,7 @@ void EditMenu::OnRowValueChanged( Row row )
case ROW_GROUP:
m_textValue[ROW_GROUP].SetText( SONGMAN->ShortenGroupName(GetSelectedGroup()) );
m_GroupBanner.LoadFromGroup( GetSelectedGroup() );
m_GroupBanner.ScaleToClipped( GROUP_BANNER_WIDTH, GROUP_BANNER_HEIGHT );
m_pSongs.clear();
SONGMAN->GetSongs( m_pSongs, GetSelectedGroup() );
m_iSelection[ROW_SONG] = 0;
@@ -265,6 +264,7 @@ void EditMenu::OnRowValueChanged( Row row )
case ROW_SONG:
m_textValue[ROW_SONG].SetText( "" );
m_SongBanner.LoadFromSong( GetSelectedSong() );
m_SongBanner.ScaleToClipped( SONG_BANNER_WIDTH, SONG_BANNER_HEIGHT );
m_SongTextBanner.LoadFromSong( GetSelectedSong() );
// fall through
case ROW_NOTES_TYPE:
+4 -3
View File
@@ -32,10 +32,10 @@ FadingBanner::FadingBanner()
this->AddChild( &m_Banner[i] );
}
void FadingBanner::SetCroppedSize( float fWidth, float fHeight )
void FadingBanner::ScaleToClipped( float fWidth, float fHeight )
{
for( int i=0; i<2; i++ )
m_Banner[i].SetCroppedSize( fWidth, fHeight );
m_Banner[i].ScaleToClipped( fWidth, fHeight );
}
void FadingBanner::Update( float fDeltaTime )
@@ -69,7 +69,8 @@ void FadingBanner::DrawPrimitives()
bool FadingBanner::Load( RageTextureID ID )
{
BeforeChange();
return m_Banner[m_iIndexFront].Load(ID);
bool bRet = m_Banner[m_iIndexFront].Load(ID);
return bRet;
}
void FadingBanner::BeforeChange()
+2 -1
View File
@@ -21,7 +21,7 @@ public:
FadingBanner();
virtual bool Load( RageTextureID ID );
void SetCroppedSize( float fWidth, float fHeight );
void ScaleToClipped( float fWidth, float fHeight );
void LoadFromSong( Song* pSong ); // NULL means no song
void LoadAllMusic();
@@ -38,6 +38,7 @@ public:
protected:
void BeforeChange();
Banner m_Banner[2];
int m_iIndexFront;
int GetBackIndex() { return m_iIndexFront==0 ? 1 : 0; }
+19 -8
View File
@@ -80,8 +80,8 @@ void GameState::Reset()
m_pPosition = new NoteFieldPositioning("Positioning.ini");
ResetMusicStatistics();
ResetStageStatistics();
m_CurStageStats = StageStats();
m_vPassedStageStats.clear();
for( p=0; p<NUM_PLAYERS; p++ )
@@ -108,13 +108,6 @@ void GameState::Reset()
m_fSuperMeterGrowthScale[p] = 1;
m_iCpuSkill[p] = 5;
}
m_fTugLifePercentP1 = 0.5f;
for( p=0; p<NUM_PLAYERS; p++ )
{
m_fSuperMeter[p] = 0;
m_fSuperMeterGrowthScale[p] = 1;
}
}
void GameState::Update( float fDelta )
@@ -185,8 +178,17 @@ void GameState::ResetMusicStatistics()
m_fCurBPS = 10;
m_bFreeze = false;
m_bPastHereWeGo = false;
}
void GameState::ResetStageStatistics()
{
m_CurStageStats = StageStats();
RemoveAllActiveAttacks();
RemoveAllInventory();
m_fOpponentHealthPercent = 1;
m_fTugLifePercentP1 = 0.5f;
for( int p=0; p<NUM_PLAYERS; p++ )
m_fSuperMeter[p] = 0;
}
void GameState::UpdateSongPosition(float fPositionSeconds)
@@ -398,6 +400,13 @@ StageResult GameState::GetStageResult( PlayerNumber pn )
{
case PLAY_MODE_BATTLE:
return (m_fOpponentHealthPercent==0)?RESULT_WIN:RESULT_LOSE;
case PLAY_MODE_RAVE:
switch( pn )
{
case PLAYER_1: return (m_fTugLifePercentP1>=0.5f)?RESULT_WIN:RESULT_LOSE;
case PLAYER_2: return (m_fTugLifePercentP1<0.5f)?RESULT_WIN:RESULT_LOSE;
default: ASSERT(0); return RESULT_LOSE;
}
default:
return (GetWinner()==pn)?RESULT_WIN:RESULT_LOSE;
}
@@ -462,6 +471,8 @@ void GameState::RestoreSelectedOptions()
void GameState::LaunchAttack( PlayerNumber target, Attack a )
{
LOG->Trace( "Launch attack '%s' against P%d", a.sModifier.c_str(), target+1 );
// search for an open slot
for( unsigned s=0; s<NUM_INVENTORY_SLOTS; s++ )
if( m_ActiveAttacks[target][s].fSecsRemaining <= 0 )
+37 -29
View File
@@ -39,8 +39,9 @@ public:
void Update( float fDelta );
//
// Main State Info
// Main state info
//
UnlockSystem UnlockingSys;
Game m_CurGame;
@@ -95,10 +96,7 @@ public:
// Used in Battle and Rave
int m_iCpuSkill[NUM_PLAYERS]; // only used when m_PlayerController is PC_CPU
// Used in Rave
float m_fTugLifePercentP1;
float m_fSuperMeter[NUM_PLAYERS]; // between 0 and NUM_ATTACK_LEVELS
float m_fSuperMeterGrowthScale[NUM_PLAYERS];
@@ -143,7 +141,7 @@ public:
bool m_bPastHereWeGo;
static const float MUSIC_SECONDS_INVALID;
void ResetMusicStatistics(); // Call this when it's time to play a new song. Clears the values above.
void ResetMusicStatistics(); // Call this when it's time to play a new song. Clears the values above.
void UpdateSongPosition(float fPositionSeconds);
//
@@ -152,9 +150,42 @@ public:
// Nonstop/Oni/Endless: for current course (which usually contains multiple songs)
//
StageStats m_CurStageStats; // current stage (not necessarily passed if Extra Stage)
// used in PLAY_MODE_BATTLE and PLAY_MODE_RAVE
struct Attack
{
AttackLevel level;
float fSecsRemaining;
CString sModifier;
bool IsBlank() { return sModifier.empty(); }
void MakeBlank() { sModifier=""; }
};
Attack m_ActiveAttacks[NUM_PLAYERS][NUM_INVENTORY_SLOTS];
// used in PLAY_MODE_BATTLE
Attack m_Inventory[NUM_PLAYERS][NUM_INVENTORY_SLOTS];
float m_fOpponentHealthPercent;
// used in PLAY_MODE_RAVE
float m_fTugLifePercentP1;
float m_fSuperMeter[NUM_PLAYERS]; // between 0 and NUM_ATTACK_LEVELS
bool m_bActiveAttackEndedThisUpdate[NUM_PLAYERS]; // flag for other objects to watch (play sounds)
void LaunchAttack( PlayerNumber target, Attack aa );
void RebuildPlayerOptionsFromActiveAttacks( PlayerNumber pn );
void RemoveAllActiveAttacks(); // called on end of song
void RemoveAllInventory();
int GetSumOfActiveAttackLevels( PlayerNumber pn );
PlayerNumber GetWinner();
StageResult GetStageResult( PlayerNumber pn );
void ResetStageStatistics(); // Call this when it's time to play a new stage.
vector<StageStats> m_vPassedStageStats; // Only useful in Arcade for final evaluation
// A song is only inserted here if at least one player passed.
// StageStats are added by the Evaluation screen
void GetFinalEvalStatsAndSongs( StageStats& statsOut, vector<Song*>& vSongsOut ); // shown on arcade final evaluation
@@ -173,39 +204,16 @@ public:
void RestoreSelectedOptions();
// used in PLAY_MODE_RAVE
// character stuff
vector<Character*> m_pCharacters;
Character* m_pCurCharacters[NUM_PLAYERS];
void ReloadCharacters();
// used in PLAY_MODE_RAVE and PLAY_MODE_BATTLE
struct Attack
{
AttackLevel level;
float fSecsRemaining;
CString sModifier;
bool IsBlank() { return sModifier.empty(); }
void MakeBlank() { sModifier=""; }
};
Attack m_ActiveAttacks[NUM_PLAYERS][NUM_INVENTORY_SLOTS];
// used in PLAY_MODE_BATTLE
Attack m_Inventory[NUM_PLAYERS][NUM_INVENTORY_SLOTS];
float m_fOpponentHealthPercent;
bool m_bActiveAttackEndedThisUpdate[NUM_PLAYERS]; // flag for other objects to watch (play sounds)
void LaunchAttack( PlayerNumber target, Attack aa );
void RebuildPlayerOptionsFromActiveAttacks( PlayerNumber pn );
void RemoveAllActiveAttacks(); // called on end of song
void RemoveAllInventory();
int GetSumOfActiveAttackLevels( PlayerNumber pn );
bool HasEarnedExtraStage();
PlayerNumber GetWinner();
StageResult GetStageResult( PlayerNumber pn );
bool m_bAllow2ndExtraStage; //only used when "Allow Selection of Extra Stage is on"
+23 -12
View File
@@ -19,22 +19,23 @@
#include "ThemeManager.h"
const float LEVEL_WIDTH = 50;
ScoreDisplayRave::ScoreDisplayRave()
{
LOG->Trace( "ScoreDisplayRave::ScoreDisplayRave()" );
m_lastLevelSeen = ATTACK_LEVEL_1;
for( int i=0; i<NUM_ATTACK_LEVELS; i++ )
{
m_LevelStream[i].Load( THEME->GetPathToG(ssprintf("ScoreDisplayRave stream level%d",i+1)), LEVEL_WIDTH );
float fSpan = (NUM_ATTACK_LEVELS-1)*LEVEL_WIDTH;
float fX = SCALE(i,0.f,NUM_ATTACK_LEVELS-1.f, -fSpan/2, fSpan/2 );
m_LevelStream[i].SetX( fX );
this->AddChild( &m_LevelStream[i] );
m_sprMeter[i].Load( THEME->GetPathToG(ssprintf("ScoreDisplayRave stream level%d",i+1)) );
m_sprMeter[i].SetCropRight( 1.f );
this->AddChild( &m_sprMeter[i] );
}
m_textLevel.LoadFromNumbers( THEME->GetPathToN("ScoreDisplayRave level") );
m_textLevel.SetText( "1" );
this->AddChild( &m_textLevel );
this->AddChild( &m_sprFrame );
}
@@ -42,6 +43,10 @@ void ScoreDisplayRave::Init( PlayerNumber pn )
{
ScoreDisplay::Init( pn );
if( pn == PLAYER_2 )
for( int i=0; i<NUM_ATTACK_LEVELS; i++ )
m_sprMeter[i].SetZoomX( -1 );
m_sprFrame.Load( THEME->GetPathToG(ssprintf("ScoreDisplayRave frame p%d",pn+1)) );
}
@@ -49,10 +54,16 @@ void ScoreDisplayRave::Update( float fDelta )
{
ScoreDisplay::Update( fDelta );
for( int i=0; i<NUM_ATTACK_LEVELS; i++ )
float fLevel = GAMESTATE->m_fSuperMeter[m_PlayerNumber];
AttackLevel level = (AttackLevel)(int)fLevel;
if( level != m_lastLevelSeen )
{
float fLevelPercent = GAMESTATE->m_fSuperMeter[m_PlayerNumber] - i;
CLAMP( fLevelPercent, 0 ,1 );
m_LevelStream[i].SetPercent( fLevelPercent );
m_sprMeter[m_lastLevelSeen].SetCropRight( 1.f );
m_lastLevelSeen = level;
m_textLevel.SetText( ssprintf("%d",level+1) );
}
float fPercent = fLevel - level;
m_sprMeter[level].SetCropRight( 1-fPercent );
}
+5 -2
View File
@@ -15,6 +15,7 @@
#include "GameConstantsAndTypes.h"
#include "OptionIcon.h"
#include "MeterDisplay.h"
#include "Sprite.h"
class ScoreDisplayRave : public ScoreDisplay
@@ -26,9 +27,11 @@ public:
virtual void Update( float fDelta );
protected:
MeterDisplay m_LevelStream[NUM_ATTACK_LEVELS];
Sprite m_sprMeter[NUM_ATTACK_LEVELS];
Sprite m_sprFrame;
BitmapText m_LevelNumber;
BitmapText m_textLevel;
AttackLevel m_lastLevelSeen;
};
#endif
+6 -9
View File
@@ -43,12 +43,12 @@ void ScoreKeeperRave::HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTa
float fPercentToMove;
switch( scoreOfLastTap )
{
case TNS_MARVELOUS: fPercentToMove = +0.02f; break;
case TNS_PERFECT: fPercentToMove = +0.02f; break;
case TNS_GREAT: fPercentToMove = +0.01f; break;
case TNS_MARVELOUS: fPercentToMove = +0.04f; break;
case TNS_PERFECT: fPercentToMove = +0.04f; break;
case TNS_GREAT: fPercentToMove = +0.02f; break;
case TNS_GOOD: fPercentToMove = +0.00f; break;
case TNS_BOO: fPercentToMove = -0.02f; break;
case TNS_MISS: fPercentToMove = -0.04f; break;
case TNS_BOO: fPercentToMove = -0.08f; break;
case TNS_MISS: fPercentToMove = -0.16f; break;
default: ASSERT(0); fPercentToMove = +0.00f; break;
}
@@ -60,11 +60,8 @@ void ScoreKeeperRave::HandleTapRowScore( TapNoteScore scoreOfLastTap, int iNumTa
if( newAL > oldAL )
{
if( newAL == NUM_ATTACK_LEVELS ) // hit upper bounds of meter
{
GAMESTATE->m_fSuperMeter[m_PlayerNumber] -= 1.f;
newAL = (AttackLevel)(NUM_ATTACK_LEVELS-1);
}
LaunchAttack( newAL );
LaunchAttack( oldAL );
}
}
+3 -3
View File
@@ -21,7 +21,7 @@
#include "ThemeManager.h"
#include "AnnouncerManager.h"
#include <math.h>
#include "CroppedSprite.h"
#include "Sprite.h"
#include "song.h"
#include "BitmapText.h"
@@ -190,9 +190,9 @@ ScreenCredits::ScreenCredits() : Screen("ScreenCredits")
break;
}
CroppedSprite* pBackground = new CroppedSprite;
pBackground->SetCroppedSize( BACKGROUNDS_WIDTH, BACKGROUNDS_HEIGHT );
Sprite* pBackground = new Sprite;
pBackground->LoadBG( pSong->HasBackground() ? pSong->GetBackgroundPath() : THEME->GetPathToG("Common fallback background") );
pBackground->ScaleToClipped( BACKGROUNDS_WIDTH, BACKGROUNDS_HEIGHT );
m_vBackgrounds.push_back( pBackground );
Sprite* pFrame = new Sprite;
+3 -3
View File
@@ -282,8 +282,8 @@ ScreenEvaluation::ScreenEvaluation( CString sClassName, Type type ) : Screen(sCl
{
case stage:
{
m_LargeBanner.SetCroppedSize( BANNER_WIDTH, BANNER_HEIGHT );
m_LargeBanner.LoadFromSong( GAMESTATE->m_pCurSong );
m_LargeBanner.ScaleToClipped( BANNER_WIDTH, BANNER_HEIGHT );
m_LargeBanner.SetName( "LargeBanner" );
UtilSetXYAndOnCommand( m_LargeBanner, "ScreenEvaluation" );
this->AddChild( &m_LargeBanner );
@@ -323,8 +323,8 @@ ScreenEvaluation::ScreenEvaluation( CString sClassName, Type type ) : Screen(sCl
{
for( unsigned i=0; i<vSongsToShow.size(); i++ )
{
m_SmallBanner[i].SetCroppedSize( BANNER_WIDTH, BANNER_HEIGHT );
m_SmallBanner[i].LoadFromSong( vSongsToShow[i] );
m_SmallBanner[i].ScaleToClipped( BANNER_WIDTH, BANNER_HEIGHT );
m_SmallBanner[i].SetName( ssprintf("SmallBanner%d",i+1) );
UtilSetXYAndOnCommand( m_SmallBanner[i], "ScreenEvaluation" );
this->AddChild( &m_SmallBanner[i] );
@@ -338,8 +338,8 @@ ScreenEvaluation::ScreenEvaluation( CString sClassName, Type type ) : Screen(sCl
break;
case course:
{
m_LargeBanner.SetCroppedSize( BANNER_WIDTH, BANNER_HEIGHT );
m_LargeBanner.LoadFromCourse( GAMESTATE->m_pCurCourse );
m_LargeBanner.ScaleToClipped( BANNER_WIDTH, BANNER_HEIGHT );
m_LargeBanner.SetName( "LargeBanner" );
UtilSetXYAndOnCommand( m_LargeBanner, "ScreenEvaluation" );
this->AddChild( &m_LargeBanner );
+1 -1
View File
@@ -90,7 +90,7 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration ) : Screen("ScreenGameplay")
/* Save selected options before we change them. */
GAMESTATE->StoreSelectedOptions();
GAMESTATE->RemoveAllInventory();
GAMESTATE->ResetStageStatistics();
for( p=0; p<NUM_PLAYERS; p++ )
+18 -37
View File
@@ -27,28 +27,28 @@
#define NEXT_SCREEN( play_mode ) THEME->GetMetric ("ScreenRaveOptions","NextScreen"+Capitalize(PlayModeToString(play_mode)))
enum {
RO_HUMAN_SUPER,
RO_P1_SUPER_GROWTH,
RO_P2_SUPER_GROWTH,
RO_CPU_SKILL,
RO_CPU_SUPER,
NUM_RAVE_OPTIONS_LINES
};
OptionRow g_RaveOptionsLines[NUM_RAVE_OPTIONS_LINES] = {
OptionRow( "Human Super\nGrowth", "25%","50%","75%","100%","125%","150%","175%","200%" ),
OptionRow( "CPU\nSkill", "-5","-4","-3","-2","-1","DEFAULT","+1","+2","+3","+4","+5" ),
OptionRow( "CPU Super\nGrowth", "25%","50%","75%","100%","125%","150%","175%","200%" )
OptionRow( "P1 Super\nGrowth", "25%","50%","75%","100%","125%","150%","175%","200%" ),
OptionRow( "P2 Super\nGrowth", "25%","50%","75%","100%","125%","150%","175%","200%" ),
OptionRow( "CPU\nSkill", "-5","-4","-3","-2","-1","DEFAULT","+1","+2","+3","+4","+5" )
};
PlayerNumber OPPOSITE_PLAYER[NUM_PLAYERS] = { PLAYER_2, PLAYER_1 };
ScreenRaveOptions::ScreenRaveOptions() :
ScreenOptions("ScreenRaveOptions",false)
ScreenOptions("ScreenRaveOptions",true)
{
LOG->Trace( "ScreenRaveOptions::ScreenRaveOptions()" );
bool bComputerPlayersPresent = GAMESTATE->GetNumSidesJoined()==1;
Init(
INPUTMODE_PLAYERS,
INPUTMODE_BOTH,
g_RaveOptionsLines,
bComputerPlayersPresent ? 3 : 1,
false, false );
@@ -58,41 +58,22 @@ void ScreenRaveOptions::ImportOptions()
{
for( int p=0; p<NUM_PLAYERS; p++ )
{
if( GAMESTATE->IsHumanPlayer(p) )
{
int iHumanSuperIndex = (int)SCALE( GAMESTATE->m_fSuperMeterGrowthScale[p], 0.25f, 2.f, 0.f, 7.f );
CLAMP( iHumanSuperIndex, 0, 9 );
m_iSelectedOption[p][RO_HUMAN_SUPER] = iHumanSuperIndex;
}
else if( GAMESTATE->IsCpuPlayer(p) )
{
PlayerNumber pnHuman = OPPOSITE_PLAYER[p];
m_iSelectedOption[pnHuman][RO_CPU_SKILL] = GAMESTATE->m_iCpuSkill[p];
CLAMP( m_iSelectedOption[pnHuman][RO_CPU_SKILL], 0, 10 );
int iHumanSuperIndex = (int)SCALE( GAMESTATE->m_fSuperMeterGrowthScale[pnHuman], 0.25f, 2.f, 0.f, 7.f );
CLAMP( iHumanSuperIndex, 0, 9 );
m_iSelectedOption[pnHuman][RO_CPU_SUPER] = iHumanSuperIndex;
}
else
ASSERT(0);
int iSuperGrowthIndex = (int)SCALE( GAMESTATE->m_fSuperMeterGrowthScale[p], 0.25f, 2.f, 0.f, 7.f );
CLAMP( iSuperGrowthIndex, 0, 9 );
m_iSelectedOption[0][RO_P1_SUPER_GROWTH+p] = iSuperGrowthIndex;
}
m_iSelectedOption[0][RO_CPU_SKILL] = GAMESTATE->m_iCpuSkill[0];
CLAMP( m_iSelectedOption[0][RO_CPU_SKILL], 0, 10 );
}
void ScreenRaveOptions::ExportOptions()
{
for( int p=0; p<NUM_PLAYERS; p++ )
{
if( GAMESTATE->IsHumanPlayer(p) )
{
GAMESTATE->m_fSuperMeterGrowthScale[p] = SCALE( m_iSelectedOption[p][RO_HUMAN_SUPER], 0.f, 7.f, 0.25f, 2.f );
PlayerNumber pnCPU = OPPOSITE_PLAYER[p];
GAMESTATE->m_iCpuSkill[pnCPU] = m_iSelectedOption[p][RO_CPU_SKILL];
GAMESTATE->m_fSuperMeterGrowthScale[pnCPU] = SCALE( m_iSelectedOption[p][RO_CPU_SUPER], 0, 7, 0.25f, 2.f );
}
}
int p;
for( p=0; p<NUM_PLAYERS; p++ )
GAMESTATE->m_fSuperMeterGrowthScale[p] = SCALE( m_iSelectedOption[0][RO_P1_SUPER_GROWTH+p], 0.f, 7.f, 0.25f, 2.f );
for( p=0; p<NUM_PLAYERS; p++ )
GAMESTATE->m_iCpuSkill[p] = m_iSelectedOption[0][RO_CPU_SKILL];
}
void ScreenRaveOptions::GoToPrevState()
+1 -1
View File
@@ -76,7 +76,6 @@ ScreenSelectCourse::ScreenSelectCourse() : Screen("ScreenSelectCourse")
this->AddChild( &m_sprExplanation );
m_Banner.SetXY( BANNER_X, BANNER_Y );
m_Banner.SetCroppedSize( BANNER_WIDTH, BANNER_HEIGHT );
this->AddChild( &m_Banner );
m_sprBannerFrame.Load( THEME->GetPathToG("ScreenSelectCourse banner frame") );
@@ -415,6 +414,7 @@ void ScreenSelectCourse::AfterCourseChange()
m_textTime.SetText( "xx:xx:xx" ); // The numbers format doesn't have a '?'. Is there a better solution?
m_Banner.LoadFromCourse( pCourse );
m_Banner.ScaleToClipped( BANNER_WIDTH, BANNER_HEIGHT );
m_CourseContentsFrame.SetFromCourse( pCourse );
m_CourseContentsFrame.TweenInAfterChangedCourse();
+1 -1
View File
@@ -113,7 +113,7 @@ ScreenSelectGroup::ScreenSelectGroup() : Screen("ScreenSelectGroup")
// these guys get loaded SetSong and TweenToSong
m_Banner.SetName( "Banner" );
m_Banner.SetCroppedSize( BANNER_WIDTH, BANNER_HEIGHT );
m_Banner.ScaleToClipped( BANNER_WIDTH, BANNER_HEIGHT );
this->AddChild( &m_Banner );
m_sprFrame.SetName( "Frame" );
+10 -8
View File
@@ -44,8 +44,10 @@ const int NUM_SCORE_DIGITS = 9;
#define SAMPLE_MUSIC_DELAY THEME->GetMetricF("ScreenSelectMusic","SampleMusicDelay")
#define SHOW_RADAR THEME->GetMetricB("ScreenSelectMusic","ShowRadar")
#define SHOW_GRAPH THEME->GetMetricB("ScreenSelectMusic","ShowGraph")
#define CDTITLE_SPIN_SECONDS THEME->GetMetricF("ScreenSelectMusic","CDTitleSpinSeconds")
#define PREV_SCREEN( play_mode ) THEME->GetMetric ("ScreenSelectMusic","PrevScreen"+Capitalize(PlayModeToString(play_mode)))
#define NEXT_SCREEN( play_mode ) THEME->GetMetric ("ScreenSelectMusic","NextScreen"+Capitalize(PlayModeToString(play_mode)))
#define NEXT_OPTIONS_SCREEN( play_mode ) THEME->GetMetric ("ScreenSelectMusic","NextOptionsScreen"+Capitalize(PlayModeToString(play_mode)))
static const ScreenMessage SM_AllowOptionsMenuRepeat = ScreenMessage(SM_User+1);
CString g_sFallbackCDTitlePath;
@@ -55,7 +57,7 @@ CString g_sFallbackCDTitlePath;
static void FlipSpriteHorizontally(Sprite &s)
{
float Coords[8];
s.GetCurrentTextureCoords(Coords);
s.GetActiveTextureCoords(Coords);
swap(Coords[0], Coords[6]); /* top left X <-> top right X */
swap(Coords[1], Coords[7]); /* top left Y <-> top right Y */
swap(Coords[2], Coords[4]); /* bottom left X <-> bottom left X */
@@ -98,8 +100,8 @@ ScreenSelectMusic::ScreenSelectMusic() : Screen("ScreenSelectMusic")
// this is loaded SetSong and TweenToSong
m_Banner.SetName( "Banner" );
m_Banner.SetCroppedSize( BANNER_WIDTH, BANNER_HEIGHT );
m_Banner.SetUseZBuffer( true ); // do have to pass the z test
m_Banner.ScaleToClipped( BANNER_WIDTH, BANNER_HEIGHT );
this->AddChild( &m_Banner );
m_sprBannerFrame.SetName( "BannerFrame" );
@@ -584,7 +586,7 @@ void ScreenSelectMusic::HandleScreenMessage( const ScreenMessage SM )
}
break;
case SM_GoToPrevScreen:
SCREENMAN->SetNewScreen( "ScreenTitleMenu" );
SCREENMAN->SetNewScreen( PREV_SCREEN(GAMESTATE->m_PlayMode) );
/* We may have stray SM_SongChanged messages from the music wheel. We can't
* handle them anymore, since the title menu (and attract screens) reset
* the game state, so just discard them. */
@@ -593,12 +595,12 @@ void ScreenSelectMusic::HandleScreenMessage( const ScreenMessage SM )
case SM_GoToNextScreen:
if( m_bGoToOptions )
{
SCREENMAN->SetNewScreen( "ScreenPlayerOptions" );
SCREENMAN->SetNewScreen( NEXT_OPTIONS_SCREEN(GAMESTATE->m_PlayMode) );
}
else
{
SOUNDMAN->StopMusic();
SCREENMAN->SetNewScreen( "ScreenStage" );
SCREENMAN->SetNewScreen( NEXT_SCREEN(GAMESTATE->m_PlayMode) );
}
break;
case SM_SongChanged:
@@ -912,8 +914,8 @@ void ScreenSelectMusic::AfterMusicChange()
case TYPE_RANDOM:
switch(m_MusicWheel.GetSelectedType())
{
case TYPE_ROULETTE: m_Banner.LoadRoulette(); break;
case TYPE_RANDOM: m_Banner.LoadRandom(); break;
case TYPE_ROULETTE: m_Banner.LoadRoulette(); break;
case TYPE_RANDOM: m_Banner.LoadRandom(); break;
default: ASSERT(0);
}
+42 -28
View File
@@ -120,15 +120,20 @@ void ScrollingList::StartBouncing()
m_RippleCSprite.UnloadTexture();
m_RippleCSprite.Load( m_apCSprites[m_iSelection]->GetTexturePath() );
if(m_RippleCSprite.GetUnzoomedWidth() == m_RippleCSprite.GetUnzoomedHeight()) // rotated graphics need cropping
{
m_RippleCSprite.SetCroppedSize( 100, 100 );
}
else // flat, unrotated graphics need widths changing
{
m_RippleCSprite.SetCroppedSize( -1, -1 ); // default image size.
m_RippleCSprite.SetWH(EZ2_BANNER_WIDTH+10, EZ2_BANNER_HEIGHT+10);
}
// ScaleToClipped should detect rotated banner files and correct
// accordingly. If there's a case I didn't think about, feel free
// to change it back. -Chris
// if(m_RippleCSprite.GetUnzoomedWidth() == m_RippleCSprite.GetUnzoomedHeight()) // rotated graphics need cropping
// {
// m_RippleCSprite.ScaleToClipped( 100, 100 );
// }
// else // flat, unrotated graphics need widths changing
// {
// m_RippleCSprite.ScaleToClipped( -1, -1 ); // default image size.
// m_RippleCSprite.SetWH(EZ2_BANNER_WIDTH+10, EZ2_BANNER_HEIGHT+10);
// }
m_RippleCSprite.ScaleToClipped( EZ2_BANNER_WIDTH+10, EZ2_BANNER_HEIGHT+10 );
m_RippleCSprite.SetXY( m_apCSprites[m_iSelection]->GetX(), m_apCSprites[m_iSelection]->GetY() );
m_RippleCSprite.SetZoom( 2.0f );
@@ -165,7 +170,7 @@ void ScrollingList::Load( const CStringArray& asGraphicPaths )
{
for( unsigned i=0; i<asGraphicPaths.size(); i++ )
{
CroppedSprite* pNewCSprite = new CroppedSprite;
Sprite* pNewCSprite = new Sprite;
pNewCSprite->Load( asGraphicPaths[i] );
m_apCSprites.push_back( pNewCSprite );
@@ -400,34 +405,43 @@ void ScrollingList::Replace(CString sGraphicPath, int ElementNumber)
}
else
{
CroppedSprite* pNewCSprite = new CroppedSprite;
Sprite* pNewCSprite = new Sprite;
pNewCSprite->Load( sGraphicPath );
if(m_iBannerPrefs == BANNERPREFS_DDRFLAT)
{
if(pNewCSprite->GetUnzoomedWidth() == pNewCSprite->GetUnzoomedHeight()) // rotated graphics need cropping
{
pNewCSprite->SetCroppedSize( BANNER_WIDTH, BANNER_HEIGHT );
}
else // flat, unrotated graphics need widths changing
{
pNewCSprite->SetWH(BANNER_WIDTH, BANNER_HEIGHT );
}
// ScaleToClipped should detect rotated banner files and correct
// accordingly. If there's a case I didn't think about, feel free
// to change it back. -Chris
// if(pNewCSprite->GetUnzoomedWidth() == pNewCSprite->GetUnzoomedHeight()) // rotated graphics need cropping
// {
// pNewCSprite->SetCroppedSize( BANNER_WIDTH, BANNER_HEIGHT );
// }
// else // flat, unrotated graphics need widths changing
// {
// pNewCSprite->SetWH(BANNER_WIDTH, BANNER_HEIGHT );
// }
pNewCSprite->ScaleToClipped( BANNER_WIDTH, BANNER_HEIGHT );
}
else if(m_iBannerPrefs == BANNERPREFS_DDRROT)
{
pNewCSprite->SetCroppedSize( BANNER_WIDTH, BANNER_HEIGHT );
pNewCSprite->ScaleToClipped( BANNER_WIDTH, BANNER_HEIGHT );
pNewCSprite->SetRotationZ( DDRROT_ROTATION );
}
else if(m_iBannerPrefs == BANNERPREFS_EZ2)
{
if(pNewCSprite->GetUnzoomedWidth() == pNewCSprite->GetUnzoomedHeight()) // rotated graphics need cropping
{
pNewCSprite->SetCroppedSize( EZ2_BANNER_WIDTH, EZ2_BANNER_HEIGHT );
}
else // flat, unrotated graphics need widths changing
{
pNewCSprite->SetWH(EZ2_BANNER_WIDTH, EZ2_BANNER_HEIGHT);
}
// ScaleToClipped should detect rotated banner files and correct
// accordingly. If there's a case I didn't think about, feel free
// to change it back. -Chris
// if(pNewCSprite->GetUnzoomedWidth() == pNewCSprite->GetUnzoomedHeight()) // rotated graphics need cropping
// {
// pNewCSprite->ScaleToClipped( EZ2_BANNER_WIDTH, EZ2_BANNER_HEIGHT );
// }
// else // flat, unrotated graphics need widths changing
// {
// pNewCSprite->SetWH(EZ2_BANNER_WIDTH, EZ2_BANNER_HEIGHT);
// }
pNewCSprite->ScaleToClipped( BANNER_WIDTH, BANNER_HEIGHT );
}
m_apCSprites[ElementNumber] = pNewCSprite;
+15 -16
View File
@@ -13,7 +13,6 @@
#include "ActorFrame.h"
#include "Sprite.h"
#include "CroppedSprite.h"
class ScrollingList : public ActorFrame
@@ -42,25 +41,25 @@ public:
protected:
int m_iBouncingState;
int m_iBounceDir;
int m_iBounceWait;
float m_iBounceSize;
int m_iBouncingState;
int m_iBounceDir;
int m_iBounceWait;
float m_iBounceSize;
int m_iBannerPrefs;
int m_iSpriteType;
int m_iSelection;
float m_fSelectionLag;
int m_iSpacing;
int m_iNumVisible;
float m_fNextTween;
Sprite m_sprBannerMask;
CroppedSprite m_RippleCSprite;
Sprite m_RippleSprite;
int m_iBannerPrefs;
int m_iSpriteType;
int m_iSelection;
float m_fSelectionLag;
int m_iSpacing;
int m_iNumVisible;
float m_fNextTween;
Sprite m_sprBannerMask;
Sprite m_RippleCSprite;
Sprite m_RippleSprite;
vector<Sprite*> m_apSprites; // stores the list of elements (left to right)
vector<CroppedSprite*> m_apCSprites; // stores the list of elements (left to right)
vector<Sprite*> m_apCSprites; // stores the list of elements (left to right)
};
#endif
+2 -2
View File
@@ -27,7 +27,7 @@
#include "FontCharAliases.h"
#include "TitleSubstitution.h"
#include "BannerCache.h"
#include "CroppedSprite.h"
#include "Sprite.h"
#include "NotesLoaderSM.h"
#include "NotesLoaderDWI.h"
@@ -705,7 +705,7 @@ void Song::TidyUpData()
continue;
}
if( !HasBanner() && CroppedSprite::IsDiagonalBanner(width, height) )
if( !HasBanner() && Sprite::IsDiagonalBanner(width, height) )
{
m_sBannerFile = arrayImages[i];
continue;
+155 -21
View File
@@ -30,6 +30,12 @@ Sprite::Sprite()
m_iCurState = 0;
m_fSecsIntoState = 0.0;
m_bUsingCustomTexCoords = false;
m_fRememberedClipWidth = -1;
m_fRememberedClipHeight = -1;
m_fTexCoordVelocityX = 0;
m_fTexCoordVelocityY = 0;
}
@@ -193,14 +199,18 @@ bool Sprite::LoadFromTexture( RageTextureID ID )
m_States.push_back( newState );
}
// apply clipping (if any)
if( m_fRememberedClipWidth != -1 && m_fRememberedClipHeight != -1 )
ScaleToClipped( m_fRememberedClipWidth, m_fRememberedClipHeight );
return true;
}
void Sprite::Update( float fDeltaTime )
void Sprite::Update( float fDelta )
{
Actor::Update( fDeltaTime ); // do tweening
Actor::Update( fDelta ); // do tweening
if( !m_bIsAnimating )
return;
@@ -208,8 +218,10 @@ void Sprite::Update( float fDeltaTime )
if( !m_pTexture ) // no texture, nothing to animate
return;
// update animation
m_fSecsIntoState += fDeltaTime;
//
// update animation frame
//
m_fSecsIntoState += fDelta;
while( m_fSecsIntoState > m_States[m_iCurState].fDelay ) // it's time to switch frames
{
@@ -217,6 +229,27 @@ void Sprite::Update( float fDeltaTime )
m_fSecsIntoState -= m_States[m_iCurState].fDelay; // leave the left over time for the next frame
m_iCurState = (m_iCurState+1) % m_States.size();
}
//
// update scrolling
//
if( m_fTexCoordVelocityX != 0 || m_fTexCoordVelocityY != 0 )
{
float fTexCoords[8];
Sprite::GetActiveTextureCoords( fTexCoords );
// top left, bottom left, bottom right, top right
fTexCoords[0] += fDelta*m_fTexCoordVelocityX;
fTexCoords[1] += fDelta*m_fTexCoordVelocityY;
fTexCoords[2] += fDelta*m_fTexCoordVelocityX;
fTexCoords[3] += fDelta*m_fTexCoordVelocityY;
fTexCoords[4] += fDelta*m_fTexCoordVelocityX;
fTexCoords[5] += fDelta*m_fTexCoordVelocityY;
fTexCoords[6] += fDelta*m_fTexCoordVelocityX;
fTexCoords[7] += fDelta*m_fTexCoordVelocityY;
Sprite::SetCustomTextureCoords( fTexCoords );
}
}
static void TexCoordsFromArray(RageVertex *v, const float *f)
@@ -298,7 +331,7 @@ void Sprite::DrawPrimitives()
if( m_pTexture )
{
float f[8];
GetActiveTexCoords(f);
GetActiveTextureCoords(f);
TexCoordsFromArray(v, f);
@@ -402,13 +435,6 @@ void Sprite::SetCustomTextureCoords( float fTexCoords[8] ) // order: top left, b
m_CustomTexCoords[i] = fTexCoords[i];
}
void Sprite::GetCustomTextureCoords( float fTexCoordsOut[8] ) const // order: top left, bottom left, bottom right, top right
{
for( int i=0; i<8; i++ )
fTexCoordsOut[i] = m_CustomTexCoords[i];
}
void Sprite::SetCustomImageRect( RectF rectImageCoords )
{
// Convert to a rectangle in texture coordinate space.
@@ -438,19 +464,23 @@ const RectF *Sprite::GetCurrentTextureCoordRect() const
return m_pTexture->GetTextureCoordRect( uFrameNo );
}
void Sprite::GetCurrentTextureCoords(float fImageCoords[8]) const
{
const RectF *pTexCoordRect = GetCurrentTextureCoordRect();
TexCoordArrayFromRect(fImageCoords, *pTexCoordRect);
}
/* If we're using custom coordinates, return them; otherwise return the coordinates
* for the current state. */
void Sprite::GetActiveTexCoords(float fImageCoords[8]) const
void Sprite::GetActiveTextureCoords(float fTexCoordsOut[8]) const
{
if(m_bUsingCustomTexCoords) GetCustomTextureCoords(fImageCoords);
else GetCurrentTextureCoords(fImageCoords);
if(m_bUsingCustomTexCoords)
{
// GetCustomTextureCoords
for( int i=0; i<8; i++ )
fTexCoordsOut[i] = m_CustomTexCoords[i];
}
else
{
// GetCurrentTextureCoords
const RectF *pTexCoordRect = GetCurrentTextureCoordRect();
TexCoordArrayFromRect(fTexCoordsOut, *pTexCoordRect);
}
}
@@ -459,3 +489,107 @@ void Sprite::StopUsingCustomCoords()
m_bUsingCustomTexCoords = false;
}
void Sprite::ScaleToClipped( float fWidth, float fHeight )
{
m_fRememberedClipWidth = fWidth;
m_fRememberedClipHeight = fHeight;
if( !m_pTexture )
return;
int iSourceWidth = m_pTexture->GetSourceWidth();
int iSourceHeight = m_pTexture->GetSourceHeight();
// save the original X&Y. We're going to resore them later.
float fOriginalX = GetX();
float fOriginalY = GetY();
if( IsDiagonalBanner(iSourceWidth, iSourceHeight) ) // this is a SSR/DWI CroppedSprite
{
float fCustomImageCoords[8] = {
0.02f, 0.78f, // top left
0.22f, 0.98f, // bottom left
0.98f, 0.22f, // bottom right
0.78f, 0.02f, // top right
};
Sprite::SetCustomImageCoords( fCustomImageCoords );
if( fWidth != -1 && fHeight != -1)
m_size = RageVector2( fWidth, fHeight );
else
{
/* If no crop size is set, then we're only being used to crop diagonal
* banners so they look like regular ones. We don't actually care about
* the size of the image, only that it has an aspect ratio of 4:1. */
m_size = RageVector2(256, 64);
}
SetZoom( 1 );
}
else if( m_pTexture->GetID().filename.find( "(was rotated)" ) != m_pTexture->GetID().filename.npos &&
fWidth != -1 && fHeight != -1 )
{
/* Dumb hack. Normally, we crop all sprites except for diagonal banners,
* which are stretched. Low-res versions of banners need to do the same
* thing as their full resolution counterpart, so the crossfade looks right.
* However, low-res diagonal banners are un-rotated, to save space. BannerCache
* drops the above text into the "filename" (which is otherwise unused for
* these banners) to tell us this.
*/
Sprite::StopUsingCustomCoords();
m_size = RageVector2( fWidth, fHeight );
SetZoom( 1 );
}
else if( fWidth != -1 && fHeight != -1 )
{
// this is probably a background graphic or something not intended to be a CroppedSprite
Sprite::StopUsingCustomCoords();
// first find the correct zoom
Sprite::ScaleToCover( RectI(0, 0,
(int)fWidth,
(int)fHeight )
);
// find which dimension is larger
bool bXDimNeedsToBeCropped = GetZoomedWidth() > fWidth+0.01;
if( bXDimNeedsToBeCropped ) // crop X
{
float fPercentageToCutOff = (this->GetZoomedWidth() - fWidth) / this->GetZoomedWidth();
float fPercentageToCutOffEachSide = fPercentageToCutOff / 2;
// generate a rectangle with new texture coordinates
RectF fCustomImageRect(
fPercentageToCutOffEachSide,
0,
1 - fPercentageToCutOffEachSide,
1 );
SetCustomImageRect( fCustomImageRect );
}
else // crop Y
{
float fPercentageToCutOff = (this->GetZoomedHeight() - fHeight) / this->GetZoomedHeight();
float fPercentageToCutOffEachSide = fPercentageToCutOff / 2;
// generate a rectangle with new texture coordinates
RectF fCustomImageRect(
0,
fPercentageToCutOffEachSide,
1,
1 - fPercentageToCutOffEachSide );
SetCustomImageRect( fCustomImageRect );
}
m_size = RageVector2( fWidth, fHeight );
SetZoom( 1 );
}
// restore original XY
SetXY( fOriginalX, fOriginalY );
}
bool Sprite::IsDiagonalBanner( int iWidth, int iHeight )
{
/* A diagonal banner is a square. Give a couple pixels of leeway. */
return iWidth >= 100 && abs(iWidth - iHeight) < 2;
}
+16 -4
View File
@@ -42,15 +42,20 @@ public:
void SetCustomTextureRect( const RectF &new_texcoord_frect );
void SetCustomTextureCoords( float fTexCoords[8] );
void GetCustomTextureCoords( float fTexCoordsOut[8] ) const;
void SetCustomSourceRect( const RectF &rectSourceCoords ); // in source pixel space
void SetCustomImageRect( RectF rectImageCoords ); // in image pixel space
void SetCustomImageCoords( float fImageCoords[8] );
const RectF *GetCurrentTextureCoordRect() const;
void StopUsingCustomCoords();
void GetActiveTextureCoords(float fTexCoordsOut[8]) const;
void SetTexCoordVelocity(float fVelX, float fVelY) { m_fTexCoordVelocityX = fVelX; m_fTexCoordVelocityY = fVelY; }
// Scale the Sprite maintaining the aspect ratio so that it fits
// within (fWidth,fHeight) and is clipped to (fWidth,fHeight).
void ScaleToClipped( float fWidth, float fHeight );
static bool IsDiagonalBanner( int iWidth, int iHeight );
void GetActiveTexCoords(float fImageCoords[8]) const;
void GetCurrentTextureCoords(float fImageCoords[8]) const;
protected:
virtual bool LoadFromTexture( RageTextureID ID );
@@ -71,7 +76,14 @@ protected:
float m_fSecsIntoState; // number of seconds that have elapsed since we switched to this frame
bool m_bUsingCustomTexCoords;
float m_CustomTexCoords[8]; // (x,y) * 4
float m_CustomTexCoords[8]; // (x,y) * 4: top left, bottom left, bottom right, top right
// Remembered clipped dimensions are applied on Load().
// -1 means no remembered dimensions;
float m_fRememberedClipWidth, m_fRememberedClipHeight;
float m_fTexCoordVelocityX;
float m_fTexCoordVelocityY;
};
#endif
+4 -17
View File
@@ -100,6 +100,10 @@ CPP=cl.exe
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I "SDL-1.2.5\include" /I "SDL_image-1.2" /I "plib-1.6.0" /D "WIN32" /D "_XBOX" /D "_DEBUG" /Fr /YX"global.h" /FD /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "." /I "SDL-1.2.5\include" /I "SDL_image-1.2" /I "plib-1.6.0" /D "WIN32" /D "_XBOX" /D "_DEBUG" /Fr /YX"global.h" /FD /c
# Begin Special Build Tool
IntDir=.\StepMania___Xbox_Debug___VC6
TargetDir=.\StepMania___Xbox_Debug___VC6
TargetName=StepMania
SOURCE="$(InputPath)"
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
# End Special Build Tool
@@ -2153,23 +2157,6 @@ SOURCE=.\BGAnimationLayer.h
# End Source File
# Begin Source File
SOURCE=.\CroppedSprite.cpp
!IF "$(CFG)" == "StepMania - Win32 Debug"
!ELSEIF "$(CFG)" == "StepMania - Xbox Debug"
!ELSEIF "$(CFG)" == "StepMania - Win32 Release"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\CroppedSprite.h
# End Source File
# Begin Source File
SOURCE=.\DifficultyIcon.cpp
!IF "$(CFG)" == "StepMania - Win32 Debug"