2.50 checkin

This commit is contained in:
Chris Danford
2002-04-16 17:31:00 +00:00
parent 6b925217b7
commit 78f3e80118
135 changed files with 4566 additions and 1725 deletions
+3 -3
View File
@@ -5,7 +5,7 @@
Desc: Base class for all objects that appear on the screen.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -40,7 +40,7 @@ Actor::Actor()
if( PREFS ) m_bShadow = PREFS->m_GraphicOptions.m_bShadows;
else m_bShadow = true;
m_fShadowLength = 5;
m_fShadowLength = 4;
m_bBlendAdd = false;
}
@@ -278,7 +278,7 @@ void Actor::BeginTweening( float time, TweenType tt )
void Actor::BeginTweeningQueued( float time, TweenType tt )
{
ASSERT( time > 0 );
ASSERT( time >= 0 );
// add a new TweenState to the tail, and initialize it
m_QueuedTweens.Add( TweenState() );
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: Base class for all objects that appear on the screen.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -5,7 +5,7 @@
Desc: Base class for all objects that appear on the screen.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: Base class for all objects that appear on the screen.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+6 -5
View File
@@ -5,14 +5,15 @@
Desc: Functions that return properties of arrows based on StyleDef and PlayerOptions
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "ArrowEffects.h"
#include "Pattern.h"
#include "NoteMetadata.h"
#include "ColorArrow.h"
#include "ScreenDimensions.h"
#include "GameManager.h"
float ArrowGetYOffset( const PlayerOptions& po, float fStepIndex, float fSongBeat )
@@ -31,9 +32,9 @@ float ArrowGetYOffset( const PlayerOptions& po, float fStepIndex, float fSongBea
return fYOffset;
}
float ArrowGetXPos( const PlayerOptions& po, const StyleDef &StyleDef, int iColNum, float fYOffset, float fSongBeat )
float ArrowGetXPos( const PlayerOptions& po, int iColNum, float fYOffset, float fSongBeat )
{
float fColOffsetFromCenter = iColNum - (StyleDef.m_iNumColumns-1)/2.0f;
float fColOffsetFromCenter = iColNum - (GAME->GetCurrentStyleDef()->GetColsPerPlayer()-1)/2.0f;
float fPixelOffsetFromCenter = fColOffsetFromCenter * ARROW_SIZE;
switch( po.m_EffectType )
@@ -45,7 +46,7 @@ float ArrowGetXPos( const PlayerOptions& po, const StyleDef &StyleDef, int iColN
return fPixelOffsetFromCenter;
}
float ArrowGetRotation( const PlayerOptions& po, const StyleDef &StyleDef, int iColNum, float fYOffset )
float ArrowGetRotation( const PlayerOptions& po, int iColNum, float fYOffset )
{
float fRotation = 0; //StyleDef.m_ColumnToRotation[iColNum];
+3 -3
View File
@@ -4,7 +4,7 @@
Desc: Functions that return properties of arrows based on StyleDef and PlayerOptions
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
@@ -26,13 +26,13 @@ float ArrowGetYOffset( const PlayerOptions& po, float fStepIndex, float fSongBea
// fXPos is a horizontal position in pixels relative to the center of the field.
// This depends on the column of the arrow and possibly the Arrow effect and
// fYOffset (in the case of EFFECT_DRUNK).
float ArrowGetXPos( const PlayerOptions& po, const StyleDef &StyleDef, int iCol, float fYOffset, float fSongBeat );
float ArrowGetXPos( const PlayerOptions& po, int iCol, float fYOffset, float fSongBeat );
// fRotation is Z rotation of an arrow. This will depend on the column of
// the arrow and possibly the Arrow effect and the fYOffset (in the case of
// EFFECT_DIZZY).
float ArrowGetRotation( const PlayerOptions& po, const StyleDef &StyleDef, int iCol, float fYOffset );
float ArrowGetRotation( const PlayerOptions& po, int iCol, float fYOffset );
// fYPos is the position of the note in pixels relative to the center.
+1 -1
View File
@@ -5,7 +5,7 @@
Desc: A graphic displayed in the BPMDisplay during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: A graphic displayed in the BPMDisplay during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -5,7 +5,7 @@
Desc: Background behind arrows while dancing
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: Background behind arrows while dancing
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -88
View File
@@ -5,7 +5,7 @@
Desc: The song's banner displayed in SelectSong.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -16,7 +16,6 @@
#include "RageBitmapTexture.h"
bool Banner::LoadFromSong( Song* pSong ) // NULL means no song
{
Sprite::TurnShadowOff();
@@ -29,90 +28,4 @@ bool Banner::LoadFromSong( Song* pSong ) // NULL means no song
return true;
}
bool Banner::Load( const CString &sFilePath, DWORD dwHints, bool bForceReload )
{
Sprite::Load( sFilePath, dwHints, bForceReload );
CropToRightSize();
return true;
}
void Banner::CropToRightSize()
{
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( iSourceWidth == iSourceHeight ) // this is a SSR/DWI banner
{
float fCustomImageCoords[8] = {
0.22f, 0.98f, // bottom left
0.02f, 0.78f, // top left
0.98f, 0.22f, // bottom right
0.78f, 0.02f, // top right
};
Sprite::SetCustomImageCoords( fCustomImageCoords );
SetWidth( BANNER_WIDTH );
SetHeight( BANNER_HEIGHT );
SetZoom( 1 );
}
else if( iSourceWidth * 2 > iSourceHeight )
{
Sprite::StopUsingCustomCoords();
Sprite::StretchTo( CRect(0, 0,
(int)BANNER_WIDTH,
(int)BANNER_HEIGHT )
);
}
else // this is probably a background graphic or something not intended to be a banner
{
Sprite::StopUsingCustomCoords();
// first find the correct zoom
Sprite::ScaleToCover( CRect(0, 0,
(int)BANNER_WIDTH,
(int)BANNER_HEIGHT )
);
float fFinalZoom = this->GetZoom();
// find which dimension is larger
bool bXDimNeedsToBeCropped = GetZoomedWidth() > BANNER_WIDTH;
if( bXDimNeedsToBeCropped ) // crop X
{
float fPercentageToCutOff = (this->GetZoomedWidth() - BANNER_WIDTH) / this->GetZoomedWidth();
float fPercentageToCutOffEachSide = fPercentageToCutOff / 2;
// generate a rectangle with new texture coordinates
FRECT fCustomImageCoords(
fPercentageToCutOffEachSide,
0,
1 - fPercentageToCutOffEachSide,
1 );
SetCustomImageRect( fCustomImageCoords );
}
else // crop Y
{
float fPercentageToCutOff = (this->GetZoomedHeight() - BANNER_HEIGHT) / this->GetZoomedHeight();
float fPercentageToCutOffEachSide = fPercentageToCutOff / 2;
// generate a rectangle with new texture coordinates
FRECT fCustomImageCoords(
0,
fPercentageToCutOffEachSide,
1,
1 - fPercentageToCutOffEachSide );
SetCustomImageRect( fCustomImageCoords );
}
SetWidth( BANNER_WIDTH );
SetHeight( BANNER_HEIGHT );
SetZoom( 1 );
}
// restore original XY
SetXY( fOriginalX, fOriginalY );
}
+13 -18
View File
@@ -1,36 +1,31 @@
#pragma once
/*
-----------------------------------------------------------------------------
File: Banner.h
Desc: The song's banner displayed in SelectSong.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
#ifndef _Banner_H_
#define _Banner_H_
#include "Sprite.h"
#include "CroppedSprite.h"
#include "Song.h"
const float BANNER_WIDTH = 253;
const float BANNER_HEIGHT = 94;
const float BANNER_WIDTH = 286;
const float BANNER_HEIGHT = 92;
class Banner : public Sprite
class Banner : public CroppedSprite
{
public:
bool LoadFromSong( Song* pSong ); // NULL means no Song
virtual bool Load( const CString &sFilePath, DWORD dwHints = 0, bool bForceReload = false );
Banner()
{
m_fCropWidth = BANNER_WIDTH;
m_fCropHeight = BANNER_HEIGHT;
};
bool LoadFromSong( Song* pSong ); // NULL means no song
protected:
void CropToRightSize();
};
#endif
+40 -8
View File
@@ -5,7 +5,7 @@
Desc: See header.
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
@@ -14,6 +14,19 @@
#include "IniFile.h"
#include "FontManager.h"
#include "RageHelper.h"
#include "ErrorCatcher/ErrorCatcher.h"
D3DXCOLOR RAINBOW_COLORS[] = {
D3DXCOLOR( 1.0f, 0.2f, 0.4f, 1 ), // red
D3DXCOLOR( 0.8f, 0.2f, 0.6f, 1 ), // pink
D3DXCOLOR( 0.4f, 0.3f, 0.5f, 1 ), // purple
D3DXCOLOR( 0.2f, 0.6f, 1.0f, 1 ), // sky blue
D3DXCOLOR( 0.2f, 0.8f, 0.8f, 1 ), // sea green
D3DXCOLOR( 0.2f, 0.8f, 0.4f, 1 ), // green
D3DXCOLOR( 1.0f, 0.8f, 0.2f, 1 ), // orange
};
const int NUM_RAINBOW_COLORS = sizeof(RAINBOW_COLORS) / sizeof(D3DXCOLOR);
BitmapText::BitmapText()
@@ -21,6 +34,9 @@ BitmapText::BitmapText()
m_HorizAlign = align_center;
m_VertAlign = align_middle;
m_fShadowLength = 2;
m_pFont = NULL;
m_iNumLines = 0;
@@ -33,6 +49,8 @@ BitmapText::BitmapText()
m_iLineLengths[i] = -1;
m_iLineWidths[i] = 1;
}
m_bRainbow = false;
}
BitmapText::~BitmapText()
@@ -161,7 +179,7 @@ void BitmapText::RebuildVertexBuffer()
const char c = szLine[j];
const int iFrameNo = m_pFont->m_iCharToFrameNo[c];
if( iFrameNo == -1 ) // this font doesn't impelemnt this character
HELPER.FatalError( ssprintf("The font '%s' does not implement the character '%c'", m_sFontFilePath, c) );
FatalError( ssprintf("The font '%s' does not implement the character '%c'", m_sFontFilePath, c) );
const int iCharWidth = m_pFont->m_iFrameNoToWidth[iFrameNo];
// HACK:
@@ -288,14 +306,28 @@ void BitmapText::RenderPrimitives()
//////////////////////
pVB->Lock( 0, 0, (BYTE**)&v, 0 );
for( int i=0; i<m_iNumV; i++ )
if( m_bRainbow )
{
if( i%2 == 0 ) // this is a bottom vertex
v[i].color = m_temp_colorDiffuse[0];
else // this is a top vertex
v[i].color = m_temp_colorDiffuse[1];
int color_index = (GetTickCount() / 200) % NUM_RAINBOW_COLORS;
for( int i=0; i<m_iNumV; i+=6 )
{
const D3DXCOLOR color = RAINBOW_COLORS[color_index];
for( int j=i; j<i+6; j++ )
v[j].color = color;
color_index = (color_index+1)%NUM_RAINBOW_COLORS;
}
}
else
{
for( int i=0; i<m_iNumV; i++ )
{
if( i%2 == 0 ) // this is a bottom vertex
v[i].color = m_temp_colorDiffuse[0];
else // this is a top vertex
v[i].color = m_temp_colorDiffuse[1];
}
}
pVB->Unlock();
+5 -1
View File
@@ -4,7 +4,7 @@
Desc: An actor that holds a Font and draws text to the screen.
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
@@ -37,6 +37,8 @@ public:
void RebuildVertexBuffer(); // fill the RageScreen's vertex buffer with what we're going to draw
virtual void RenderPrimitives();
void TurnRainbowOn() { m_bRainbow = true; };
void TurnRainbowOff() { m_bRainbow = false; };
protected:
CString m_sFontFilePath;
@@ -52,6 +54,8 @@ protected:
// recalculate on RebuildVertexBuffer()
int m_iNumV; // number of verticies we filled in the vertex buffer
bool m_bRainbow;
};
+1 -1
View File
@@ -5,7 +5,7 @@
Desc: A graphic displayed in the Combo during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: A graphic displayed in the Combo during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+93
View File
@@ -0,0 +1,93 @@
#include "stdafx.h"
/*
-----------------------------------------------------------------------------
File: CroppedSprite.h
Desc: The song's CroppedSprite displayed in SelectSong.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
#include "RageUtil.h"
#include "CroppedSprite.h"
#include "ThemeManager.h"
#include "RageBitmapTexture.h"
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( iSourceWidth == iSourceHeight ) // this is a SSR/DWI CroppedSprite
{
float fCustomImageCoords[8] = {
0.22f, 0.98f, // bottom left
0.02f, 0.78f, // top left
0.98f, 0.22f, // bottom right
0.78f, 0.02f, // top right
};
Sprite::SetCustomImageCoords( fCustomImageCoords );
SetWidth( m_fCropWidth );
SetHeight( m_fCropHeight );
SetZoom( 1 );
}
else // this is probably a background graphic or something not intended to be a CroppedSprite
{
Sprite::StopUsingCustomCoords();
// first find the correct zoom
Sprite::ScaleToCover( CRect(0, 0,
(int)m_fCropWidth,
(int)m_fCropHeight )
);
float fFinalZoom = this->GetZoom();
// find which dimension is larger
bool bXDimNeedsToBeCropped = GetZoomedWidth() > m_fCropWidth;
if( bXDimNeedsToBeCropped ) // crop X
{
float fPercentageToCutOff = (this->GetZoomedWidth() - m_fCropWidth) / this->GetZoomedWidth();
float fPercentageToCutOffEachSide = fPercentageToCutOff / 2;
// generate a rectangle with new texture coordinates
FRECT fCustomImageCoords(
fPercentageToCutOffEachSide,
0,
1 - fPercentageToCutOffEachSide,
1 );
SetCustomImageRect( fCustomImageCoords );
}
else // crop Y
{
float fPercentageToCutOff = (this->GetZoomedHeight() - m_fCropHeight) / this->GetZoomedHeight();
float fPercentageToCutOffEachSide = fPercentageToCutOff / 2;
// generate a rectangle with new texture coordinates
FRECT fCustomImageCoords(
0,
fPercentageToCutOffEachSide,
1,
1 - fPercentageToCutOffEachSide );
SetCustomImageRect( fCustomImageCoords );
}
SetWidth( m_fCropWidth );
SetHeight( m_fCropHeight );
SetZoom( 1 );
}
// restore original XY
SetXY( fOriginalX, fOriginalY );
}
+44
View File
@@ -0,0 +1,44 @@
/*
-----------------------------------------------------------------------------
File: CroppedSprite.h
Desc: The song's CroppedSprite displayed in SelectSong.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
#ifndef _CroppedSprite_H_
#define _CroppedSprite_H_
#include "Sprite.h"
#include "Song.h"
class CroppedSprite : public Sprite
{
public:
CroppedSprite()
{
m_fCropWidth = m_fCropHeight = 100;
};
bool Load( CString sFilePath, DWORD dwHints = 0, bool bForceReload = false )
{
Sprite::Load( sFilePath, dwHints, bForceReload );
CropToSize( m_fCropWidth, m_fCropHeight );
return true;
}
void CropToSize( float fHeight, float fWidth );
protected:
float m_fCropWidth, m_fCropHeight;
};
#endif
+1 -1
View File
@@ -5,7 +5,7 @@
Desc: A graphic displayed in the DifficultyIcon during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+12 -12
View File
@@ -4,7 +4,7 @@
Desc: A graphic displayed in the DifficultyIcon during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -24,18 +24,18 @@ class DifficultyIcon : public Sprite
public:
DifficultyIcon()
{
Load( THEME->GetPathTo(GRAPHIC_STEPS_DESCRIPTION) );
Load( THEME->GetPathTo(GRAPHIC_DIFFICULTY_ICONS) );
StopAnimating();
SetFromDescription( "" );
SetFromNoteMetadata( NULL );
};
void SetFromSteps( Pattern* pSteps )
void SetFromNoteMetadata( NoteMetadata* pNoteMetadata )
{
if( pSteps != NULL )
if( pNoteMetadata != NULL )
{
SetDiffuseColor( D3DXCOLOR(1,1,1,1) );
SetFromDescription( pSteps->m_sDescription );
SetFromDescription( pNoteMetadata->m_sDescription );
}
else
{
@@ -52,12 +52,12 @@ private:
sTemp.MakeLower();
if( sTemp.Find( "basic" ) != -1 ) SetState( 0 );
else if( sTemp.Find( "trick" ) != -1 ) SetState( 1 );
else if( sTemp.Find( "another" ) != -1 ) SetState( 2 );
else if( sTemp.Find( "maniac" ) != -1 ) SetState( 3 );
else if( sTemp.Find( "ssr" ) != -1 ) SetState( 4 );
else if( sTemp.Find( "battle" ) != -1 ) SetState( 5 );
else if( sTemp.Find( "couple" ) != -1 ) SetState( 6 );
else SetState( 7 );
else if( sTemp.Find( "another" ) != -1 ) SetState( 1 );
else if( sTemp.Find( "maniac" ) != -1 ) SetState( 2 );
else if( sTemp.Find( "ssr" ) != -1 ) SetState( 2 );
else if( sTemp.Find( "battle" ) != -1 ) SetState( 0 );
else if( sTemp.Find( "couple" ) != -1 ) SetState( 0 );
else SetState( 0 );
};
};
+1 -1
View File
@@ -5,7 +5,7 @@
Desc: A graphic that appears to blur and come into focus.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: A graphic that appears to blur and come into focus.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+7 -6
View File
@@ -5,7 +5,7 @@
Desc: See header.
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
@@ -16,6 +16,7 @@
#include "RageTextureManager.h"
#include "RageUtil.h"
#include "RageHelper.h"
#include "ErrorCatcher/ErrorCatcher.h"
Font::Font( const CString &sFontFilePath )
@@ -44,7 +45,7 @@ Font::Font( const CString &sFontFilePath )
IniFile ini;
ini.SetPath( m_sFontFilePath );
if( !ini.ReadFile() )
HELPER.FatalError( ssprintf("Error opening Font file '%s'.", m_sFontFilePath) );
FatalError( ssprintf("Error opening Font file '%s'.", m_sFontFilePath) );
//
@@ -52,7 +53,7 @@ Font::Font( const CString &sFontFilePath )
//
CString sTextureFile = ini.GetValue( "Font", "Texture" );
if( sTextureFile == "" )
HELPER.FatalError( ssprintf("Error reading value 'Texture' from %s.", m_sFontFilePath) );
FatalError( ssprintf("Error reading value 'Texture' from %s.", m_sFontFilePath) );
m_sTexturePath = sFontDir + sTextureFile; // save the path of the new texture
m_sTexturePath.MakeLower();
@@ -73,7 +74,7 @@ Font::Font( const CString &sFontFilePath )
{
// sanity check
if( sCharacters.GetLength() != (int)m_pTexture->GetNumFrames() )
HELPER.FatalError( ssprintf("The characters in '%s' does not match the number of frames in the texture.", m_sFontFilePath) );
FatalError( ssprintf("The characters in '%s' does not match the number of frames in the texture.", m_sFontFilePath) );
// set the char to frame number map
for( int i=0; i<sCharacters.GetLength(); i++ )
@@ -103,7 +104,7 @@ Font::Font( const CString &sFontFilePath )
split( sWidthsValue, ",", arrayCharWidths );
if( arrayCharWidths.GetSize() != (int)m_pTexture->GetNumFrames() )
HELPER.FatalError( ssprintf("The number of widths specified in '%s' (%d) do not match the number of frames in the texture (%u).", m_sFontFilePath, arrayCharWidths.GetSize(), m_pTexture->GetNumFrames()) );
FatalError( ssprintf("The number of widths specified in '%s' (%d) do not match the number of frames in the texture (%u).", m_sFontFilePath, arrayCharWidths.GetSize(), m_pTexture->GetNumFrames()) );
for( int i=0; i<arrayCharWidths.GetSize(); i++ )
{
@@ -157,7 +158,7 @@ int Font::GetLineWidthInSourcePixels( LPCTSTR szLine, int iLength )
const char c = szLine[i];
const int iFrameNo = m_iCharToFrameNo[c];
if( iFrameNo == -1 ) // this font doesn't impelemnt this character
HELPER.FatalError( ssprintf("The font '%s' does not implement the character '%c'", m_sFontFilePath, c) );
FatalError( ssprintf("The font '%s' does not implement the character '%c'", m_sFontFilePath, c) );
iLineWidth += m_iFrameNoToWidth[iFrameNo];
}
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: A holder for information that is used by BitmapText objects.
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
+3 -2
View File
@@ -5,7 +5,7 @@
Desc: Interface for loading and releasing textures.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -17,6 +17,7 @@
#include "Font.h"
#include "RageUtil.h"
#include "RageHelper.h"
#include "ErrorCatcher/ErrorCatcher.h"
FontManager* FONT = NULL;
@@ -126,7 +127,7 @@ void FontManager::UnloadFont( CString sFontFilePath )
}
else // lookup failed
{
HELPER.FatalError( ssprintf("Tried to Unload a font that wasn't loaded. '%s'", sFontFilePath) );
FatalError( ssprintf("Tried to Unload a font that wasn't loaded. '%s'", sFontFilePath) );
}
}
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: Manages Loading and Unloading of fonts.
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -5,7 +5,7 @@
Desc: A graphic displayed in the FootMeter during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+4 -4
View File
@@ -4,7 +4,7 @@
Desc: A graphic displayed in the FootMeter during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -29,12 +29,12 @@ public:
SetNumFeet( 0, "" );
};
void SetFromSteps( Pattern* pSteps )
void SetFromNoteMetadata( NoteMetadata* pNoteMetadata )
{
if( pSteps != NULL )
if( pNoteMetadata != NULL )
{
SetDiffuseColor( D3DXCOLOR(1,1,1,1) );
SetNumFeet( pSteps->m_iNumFeet, pSteps->m_sDescription );
SetNumFeet( pNoteMetadata->m_iMeter, pNoteMetadata->m_sDescription );
}
else
{
+56
View File
@@ -0,0 +1,56 @@
#include "stdafx.h"
/*
-----------------------------------------------------------------------------
Class: GameDef
Desc: See header.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "GameDef.h"
#include "RageHelper.h"
#include "RageUtil.h"
#include "ErrorCatcher/ErrorCatcher.h"
CString GameDef::ElementToGraphicSuffix( const GameButtonGraphic gbg )
{
CString sAssetPath; // fill this in below
switch( gbg )
{
case GRAPHIC_NOTE_COLOR_PART: sAssetPath = "note color part"; break;
case GRAPHIC_NOTE_GRAY_PART: sAssetPath = "note gray part"; break;
case GRAPHIC_RECEPTOR: sAssetPath = "receptor"; break;
case GRAPHIC_HOLD_EXPLOSION: sAssetPath = "hold explosion"; break;
case GRAPHIC_TAP_EXPLOSION_BRIGHT: sAssetPath = "tap explosion bright"; break;
case GRAPHIC_TAP_EXPLOSION_DIM: sAssetPath = "tap explosion dim"; break;
default:
FatalError( ssprintf("Unhandled StyleElement %d", gbg) );
}
return sAssetPath;
}
CString GameDef::GetPathToGraphic( const int iInstrumentButton, const GameButtonGraphic gbg )
{
const CString sDir = "Game\\" + CString(m_szName) + "\\";
const CString sButtonName = m_szButtonNames[ iInstrumentButton ];
const CString sGraphicSuffix = ElementToGraphicSuffix( gbg );
CStringArray arrayPossibleFileNames; // fill this with the possible files
GetDirListing( ssprintf("%s%s %s*.sprite", sDir, sButtonName, sGraphicSuffix), arrayPossibleFileNames );
GetDirListing( ssprintf("%s%s %s*.png", sDir, sButtonName, sGraphicSuffix), arrayPossibleFileNames );
GetDirListing( ssprintf("%s%s %s*.jpg", sDir, sButtonName, sGraphicSuffix), arrayPossibleFileNames );
GetDirListing( ssprintf("%s%s %s*.bmp", sDir, sButtonName, sGraphicSuffix), arrayPossibleFileNames );
if( arrayPossibleFileNames.GetSize() > 0 )
return sDir + arrayPossibleFileNames[0];
FatalError( "The game button graphic '%s%s %s' is missing.", sDir, sButtonName, sGraphicSuffix );
return "";
}
+64
View File
@@ -0,0 +1,64 @@
#pragma once
/*
-----------------------------------------------------------------------------
Class: GameDef
Desc: Holds information about a particular style of a game (e.g. "single", "double").
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "StyleDef.h"
#include "NoteMetadata.h"
#include "NoteData.h"
#include "GameInput.h"
#include "GameTypes.h"
#include "MenuInput.h"
const int MAX_STYLES_PER_GAME = 10;
struct GameDef
{
public:
LPCTSTR m_szName;
LPCTSTR m_szDescription;
LPCTSTR m_szGraphicPath;
// instrument stuff
int m_iNumInstruments;
int m_iNumButtons;
LPCTSTR m_szButtonNames[NUM_INSTRUMENT_BUTTONS]; // e.g. "left", "right", "middle C", "snare"
int m_iMenuButtons[NUM_MENU_BUTTONS]; // map from MenuButton to InstrumentButton
int m_iNumStyleDefs;
StyleDef m_StyleDefs[MAX_STYLES_PER_GAME];
// graphic stuff
CString GetPathToGraphic( const int iInstrumentButton, const GameButtonGraphic gbg );
CString ElementToGraphicSuffix( const GameButtonGraphic gbg );
inline MenuInput GameInputToMenuInput( const GameInput GameI )
{
PlayerNumber p = (PlayerNumber)GameI.number;
for( int b=0; b<NUM_MENU_BUTTONS; b++ )
{
if( m_iMenuButtons[b] == GameI.button )
return MenuInput( p, (MenuButton)b );
}
return MenuInput( PLAYER_NONE, MENU_BUTTON_NONE );
};
inline GameInput MenuInputToGameInput( const MenuInput MenuI )
{
return GameInput( (InstrumentNumber)MenuI.player, (InstrumentButton)m_iMenuButtons[MenuI.button] );
};
};
+80
View File
@@ -0,0 +1,80 @@
#pragma once
/*
-----------------------------------------------------------------------------
Class: GameInput
Desc: An input event specific to a Game definied by an instrument and a button space.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
enum InstrumentNumber
{
INSTRUMENT_1 = 0,
INSTRUMENT_2,
NUM_INSTRUMENTS, // leave this at the end
INSTRUMENT_NONE,
};
enum InstrumentButton
{
INSTRUMENT_BUTTON_1 = 0,
INSTRUMENT_BUTTON_2,
INSTRUMENT_BUTTON_3,
INSTRUMENT_BUTTON_4,
INSTRUMENT_BUTTON_5,
INSTRUMENT_BUTTON_6,
INSTRUMENT_BUTTON_7,
INSTRUMENT_BUTTON_8,
INSTRUMENT_BUTTON_9,
INSTRUMENT_BUTTON_10,
INSTRUMENT_BUTTON_11,
INSTRUMENT_BUTTON_12,
INSTRUMENT_BUTTON_13,
INSTRUMENT_BUTTON_14,
INSTRUMENT_BUTTON_15,
INSTRUMENT_BUTTON_16,
NUM_INSTRUMENT_BUTTONS, // leave this at the end
INSTRUMENT_BUTTON_NONE
};
struct GameInput
{
GameInput() { MakeBlank(); };
GameInput( InstrumentNumber n, InstrumentButton b ) { number = n; button = b; };
InstrumentNumber number; // instrument number
InstrumentButton button; // instrument button
bool operator==( const GameInput &other ) { return number == other.number && button == other.button; };
inline bool IsBlank() const { return number == INSTRUMENT_NONE; };
inline bool IsValid() const { return !IsBlank(); };
inline void MakeBlank() { number = INSTRUMENT_NONE; button = INSTRUMENT_BUTTON_NONE; };
CString toString()
{
return ssprintf("%d-%d", number, button );
}
bool fromString( CString s )
{
CStringArray a;
split( s, "-", a);
if( a.GetSize() != 2 ) {
MakeBlank();
return false;
}
number = (InstrumentNumber)atoi( a[0] );
button = (InstrumentButton)atoi( a[1] );
return true;
};
};
+176 -144
View File
@@ -5,176 +5,208 @@
Desc: See Header.
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "GameManager.h"
#include "D3DXmath.h"
GameManager* GAME = NULL; // global and accessable from anywhere in our program
#define DANCE_PAD_BUTTON_LEFT INSTRUMENT_BUTTON_1
#define DANCE_PAD_BUTTON_RIGHT INSTRUMENT_BUTTON_2
#define DANCE_PAD_BUTTON_UP INSTRUMENT_BUTTON_3
#define DANCE_PAD_BUTTON_DOWN INSTRUMENT_BUTTON_4
#define DANCE_PAD_BUTTON_UPLEFT INSTRUMENT_BUTTON_5
#define DANCE_PAD_BUTTON_UPRIGHT INSTRUMENT_BUTTON_6
#define DANCE_PAD_BUTTON_NEXT INSTRUMENT_BUTTON_7
#define DANCE_PAD_BUTTON_BACK INSTRUMENT_BUTTON_8
#define NUM_DANCE_PAD_BUTTONS 8
//
// ----------------------------------
// This is where all Games and Styles are definied.
// If you want to add support for new games or styles, do it here.
// ----------------------------------
//
GameDef g_GameDefs[] =
{
{
"dance", // m_szName
"Dance Dance Revolution", // m_szDescription
"", // m_szGraphicPath
2, // m_iNumInstruments
NUM_DANCE_PAD_BUTTONS, // m_iNumButtons
{ "Left", "Right", "Up", "Down", "UpLeft", "UpRight", "Next", "Back" }, // m_sButtonNames[NUM_INSTRUMENT_BUTTONS]
{ // m_iMenuButtons
DANCE_PAD_BUTTON_LEFT,
DANCE_PAD_BUTTON_RIGHT,
DANCE_PAD_BUTTON_UP,
DANCE_PAD_BUTTON_DOWN,
DANCE_PAD_BUTTON_NEXT,
DANCE_PAD_BUTTON_BACK,
},
5, // m_iNumStyleDefs
{ // StyleDef list
{ // StyleDef
"single", // m_szName
"single", // m_szReads
1, // m_iNumPlayers
4, // m_iNumTracks
{ // m_StyleInputToGameInput[NUM_PLAYERS][NUM_NOTE_COLS];
{ // player 1
{ 0, INSTRUMENT_1, DANCE_PAD_BUTTON_LEFT }, // column 1
{ 1, INSTRUMENT_1, DANCE_PAD_BUTTON_DOWN }, // column 2
{ 2, INSTRUMENT_1, DANCE_PAD_BUTTON_UP }, // column 3
{ 3, INSTRUMENT_1, DANCE_PAD_BUTTON_RIGHT }, // column 4
}
},
},
{ // StyleDef
"versus", // m_szName
"single", // m_szReads
1, // m_iNumPlayers
4, // m_iNumTracks
{ // m_StyleInputToGameInput[NUM_PLAYERS][NUM_NOTE_COLS];
{ // player 1
{ 0, INSTRUMENT_1, DANCE_PAD_BUTTON_LEFT }, // column 1
{ 1, INSTRUMENT_1, DANCE_PAD_BUTTON_DOWN }, // column 2
{ 2, INSTRUMENT_1, DANCE_PAD_BUTTON_UP }, // column 3
{ 3, INSTRUMENT_1, DANCE_PAD_BUTTON_RIGHT }, // column 4
},
{ // player 2
{ 0, INSTRUMENT_2, DANCE_PAD_BUTTON_LEFT }, // column 1
{ 1, INSTRUMENT_2, DANCE_PAD_BUTTON_DOWN }, // column 2
{ 2, INSTRUMENT_2, DANCE_PAD_BUTTON_UP }, // column 3
{ 3, INSTRUMENT_2, DANCE_PAD_BUTTON_RIGHT }, // column 4
}
},
},
{ // StyleDef
"double", // m_szName
"double", // m_szReads
1, // m_iNumPlayers
8, // m_iNumTracks
{ // m_StyleInputToGameInput[NUM_PLAYERS][NUM_NOTE_COLS];
{ // player 1
{ 0, INSTRUMENT_1, DANCE_PAD_BUTTON_LEFT }, // column 1
{ 1, INSTRUMENT_1, DANCE_PAD_BUTTON_DOWN }, // column 2
{ 2, INSTRUMENT_1, DANCE_PAD_BUTTON_UP }, // column 3
{ 3, INSTRUMENT_1, DANCE_PAD_BUTTON_RIGHT }, // column 4
{ 4, INSTRUMENT_2, DANCE_PAD_BUTTON_LEFT }, // column 5
{ 5, INSTRUMENT_2, DANCE_PAD_BUTTON_DOWN }, // column 6
{ 6, INSTRUMENT_2, DANCE_PAD_BUTTON_UP }, // column 7
{ 7, INSTRUMENT_2, DANCE_PAD_BUTTON_RIGHT }, // column 8
},
},
},
{ // StyleDef
"couple", // m_szName
"couple", // m_szReads
1, // m_iNumPlayers
8, // m_iNumTracks
{ // m_StyleInputToGameInput[NUM_PLAYERS][NUM_NOTE_COLS];
{ // player 1
{ 0, INSTRUMENT_1, DANCE_PAD_BUTTON_LEFT }, // column 1
{ 1, INSTRUMENT_1, DANCE_PAD_BUTTON_DOWN }, // column 2
{ 2, INSTRUMENT_1, DANCE_PAD_BUTTON_UP }, // column 3
{ 3, INSTRUMENT_1, DANCE_PAD_BUTTON_RIGHT }, // column 4
},
{ // player 2
{ 4, INSTRUMENT_2, DANCE_PAD_BUTTON_LEFT }, // column 1
{ 5, INSTRUMENT_2, DANCE_PAD_BUTTON_DOWN }, // column 2
{ 6, INSTRUMENT_2, DANCE_PAD_BUTTON_UP }, // column 3
{ 7, INSTRUMENT_2, DANCE_PAD_BUTTON_RIGHT }, // column 4
}
},
},
{ // StyleDef
"solo", // m_szName
"solo", // m_szReads
1, // m_iNumPlayers
6, // m_iNumTracks
{ // m_StyleInputToGameInput[NUM_PLAYERS][NUM_NOTE_COLS];
{ // player 1
{ 0, INSTRUMENT_1, DANCE_PAD_BUTTON_LEFT }, // column 1
{ 1, INSTRUMENT_1, DANCE_PAD_BUTTON_UPLEFT }, // column 2
{ 2, INSTRUMENT_1, DANCE_PAD_BUTTON_DOWN }, // column 3
{ 3, INSTRUMENT_1, DANCE_PAD_BUTTON_UP }, // column 4
{ 4, INSTRUMENT_1, DANCE_PAD_BUTTON_UPRIGHT }, // column 5
{ 5, INSTRUMENT_1, DANCE_PAD_BUTTON_RIGHT }, // column 6
}
},
},
}
}
};
GameManager::GameManager()
{
m_DanceStyle = STYLE_SINGLE;
SwitchGame( "dance" );
SwitchStyle( "single" );
}
GameManager::~GameManager()
GameDef* GameManager::GetGameDef( CString sGame )
{
for( int i=0; i<NUM_GAME_DEFS; i++ )
{
if( g_GameDefs[i].m_szName == sGame )
return &g_GameDefs[i];
}
return NULL;
}
StyleDef* GameManager::GetStyleDef( CString sGame, CString sStyle )
{
GameDef* pGameDef = GetGameDef( sGame );
for( int i=0; i<pGameDef->m_iNumStyleDefs; i++ )
{
if( pGameDef->m_StyleDefs[i].m_szName == sStyle )
return &pGameDef->m_StyleDefs[i];
}
return NULL;
}
bool GameManager::IsPlayerEnabled( PlayerNumber PlayerNo )
{
switch( m_DanceStyle )
StyleDef* pStyleDef = GetCurrentStyleDef();
ASSERT( pStyleDef != NULL );
switch( pStyleDef->m_iNumPlayers )
{
case STYLE_VERSUS:
case STYLE_COUPLE:
if( PlayerNo == PLAYER_1 )
return true;
if( PlayerNo == PLAYER_2 )
return true;
case 1:
switch( PlayerNo )
{
case PLAYER_1: return true;
case PLAYER_2: return false;
default: ASSERT( false );
}
break;
case STYLE_SINGLE:
case STYLE_SOLO:
case STYLE_DOUBLE:
if( PlayerNo == PLAYER_1 )
return true;
if( PlayerNo == PLAYER_2 )
return false;
case 2:
switch( PlayerNo )
{
case PLAYER_1: return true;
case PLAYER_2: return true;
default: ASSERT( false );
}
break;
default:
ASSERT( false ); // invalid StyleDef
ASSERT( false ); // invalid m_iNumPlayers
}
return false;
}
StyleDef GameManager::GetStyleDef( DanceStyle mode )
{
StyleDef sd;
/*
CMap<TapNote, TapNote, float, float> mapTapNoteToRotation; // arrow facing left is rotation 0
mapTapNoteToRotation[NOTE_PAD1_LEFT] = 0;
mapTapNoteToRotation[NOTE_PAD1_UPLEFT] = D3DX_PI/4.0f;
mapTapNoteToRotation[NOTE_PAD1_DOWN] = -D3DX_PI/2.0f;
mapTapNoteToRotation[NOTE_PAD1_UP] = D3DX_PI/2.0f;
mapTapNoteToRotation[NOTE_PAD1_UPRIGHT] = D3DX_PI*3.0f/4.0f;
mapTapNoteToRotation[NOTE_PAD1_RIGHT] = D3DX_PI;
mapTapNoteToRotation[NOTE_PAD2_LEFT] = mapTapNoteToRotation[NOTE_PAD1_LEFT];
mapTapNoteToRotation[NOTE_PAD2_UPLEFT] = mapTapNoteToRotation[NOTE_PAD1_UPLEFT];
mapTapNoteToRotation[NOTE_PAD2_DOWN] = mapTapNoteToRotation[NOTE_PAD1_DOWN];
mapTapNoteToRotation[NOTE_PAD2_UP] = mapTapNoteToRotation[NOTE_PAD1_UP];
mapTapNoteToRotation[NOTE_PAD2_UPRIGHT] = mapTapNoteToRotation[NOTE_PAD1_UPRIGHT];
mapTapNoteToRotation[NOTE_PAD2_RIGHT] = mapTapNoteToRotation[NOTE_PAD1_RIGHT];
*/
switch( mode )
{
case STYLE_SINGLE:
case STYLE_DOUBLE:
case STYLE_SOLO:
sd.m_iNumPlayers = 1;
break;
case STYLE_VERSUS:
case STYLE_COUPLE:
sd.m_iNumPlayers = 2;
break;
default:
ASSERT( false ); // invalid GameMode
}
switch( mode )
{
case STYLE_SINGLE:
case STYLE_VERSUS:
case STYLE_COUPLE:
sd.m_iNumColumns = 4;
sd.m_ColumnToTapNote[0] = NOTE_PAD1_LEFT;
sd.m_ColumnToTapNote[1] = NOTE_PAD1_DOWN;
sd.m_ColumnToTapNote[2] = NOTE_PAD1_UP;
sd.m_ColumnToTapNote[3] = NOTE_PAD1_RIGHT;
sd.m_sColumnToNoteName[0] = "left";
sd.m_sColumnToNoteName[1] = "down";
sd.m_sColumnToNoteName[2] = "up";
sd.m_sColumnToNoteName[3] = "right";
/* sd.m_ColumnToRotation[0] = mapTapNoteToRotation[NOTE_PAD1_LEFT];
sd.m_ColumnToRotation[1] = mapTapNoteToRotation[NOTE_PAD1_DOWN];
sd.m_ColumnToRotation[2] = mapTapNoteToRotation[NOTE_PAD1_UP];
sd.m_ColumnToRotation[3] = mapTapNoteToRotation[NOTE_PAD1_RIGHT];
*/ break;
case STYLE_SOLO:
sd.m_iNumColumns = 6; // LEFT, UP+LEFT, DOWN, UP, UP+RIGHT, RIGHT
sd.m_ColumnToTapNote[0] = NOTE_PAD1_LEFT;
sd.m_ColumnToTapNote[1] = NOTE_PAD1_UPLEFT;
sd.m_ColumnToTapNote[2] = NOTE_PAD1_DOWN;
sd.m_ColumnToTapNote[3] = NOTE_PAD1_UP;
sd.m_ColumnToTapNote[4] = NOTE_PAD1_UPRIGHT;
sd.m_ColumnToTapNote[5] = NOTE_PAD1_RIGHT;
sd.m_sColumnToNoteName[0] = "left";
sd.m_sColumnToNoteName[1] = "upleft";
sd.m_sColumnToNoteName[2] = "down";
sd.m_sColumnToNoteName[3] = "up";
sd.m_sColumnToNoteName[4] = "upright";
sd.m_sColumnToNoteName[5] = "right";
/* sd.m_ColumnToRotation[0] = mapTapNoteToRotation[NOTE_PAD1_LEFT];
sd.m_ColumnToRotation[1] = mapTapNoteToRotation[NOTE_PAD1_UPLEFT];
sd.m_ColumnToRotation[2] = mapTapNoteToRotation[NOTE_PAD1_DOWN];
sd.m_ColumnToRotation[3] = mapTapNoteToRotation[NOTE_PAD1_UP];
sd.m_ColumnToRotation[4] = mapTapNoteToRotation[NOTE_PAD1_UPRIGHT];
sd.m_ColumnToRotation[5] = mapTapNoteToRotation[NOTE_PAD1_RIGHT];
*/ break;
case STYLE_DOUBLE:
sd.m_iNumColumns = 8; // 1_LEFT, 1_DOWN, 1_UP, 1_RIGHT, 2_LEFT, 2_DOWN, 2_UP, 2_RIGHT
sd.m_ColumnToTapNote[0] = NOTE_PAD1_LEFT;
sd.m_ColumnToTapNote[1] = NOTE_PAD1_DOWN;
sd.m_ColumnToTapNote[2] = NOTE_PAD1_UP;
sd.m_ColumnToTapNote[3] = NOTE_PAD1_RIGHT;
sd.m_ColumnToTapNote[4] = NOTE_PAD2_LEFT;
sd.m_ColumnToTapNote[5] = NOTE_PAD2_DOWN;
sd.m_ColumnToTapNote[6] = NOTE_PAD2_UP;
sd.m_ColumnToTapNote[7] = NOTE_PAD2_RIGHT;
sd.m_ColumnToTapNote[8] = NOTE_PAD1_UPLEFT;// Even though this isn't used, Need them here so
sd.m_ColumnToTapNote[9] = NOTE_PAD1_UPRIGHT;// TapNoteToColumnNumber doesn't get confused by them
sd.m_ColumnToTapNote[10] = NOTE_PAD2_UPLEFT;
sd.m_ColumnToTapNote[11] = NOTE_PAD2_UPRIGHT;
sd.m_sColumnToNoteName[0] = "left";
sd.m_sColumnToNoteName[1] = "upleft";
sd.m_sColumnToNoteName[2] = "down";
sd.m_sColumnToNoteName[3] = "up";
sd.m_sColumnToNoteName[4] = "upright";
sd.m_sColumnToNoteName[5] = "right";
sd.m_sColumnToNoteName[6] = "left";
sd.m_sColumnToNoteName[7] = "upleft";
sd.m_sColumnToNoteName[8] = "down";
sd.m_sColumnToNoteName[9] = "up";
sd.m_sColumnToNoteName[10] = "upright";
sd.m_sColumnToNoteName[11] = "right";
/*
sd.m_ColumnToRotation[0] = mapTapNoteToRotation[NOTE_PAD1_LEFT];
sd.m_ColumnToRotation[1] = mapTapNoteToRotation[NOTE_PAD1_DOWN];
sd.m_ColumnToRotation[2] = mapTapNoteToRotation[NOTE_PAD1_UP];
sd.m_ColumnToRotation[3] = mapTapNoteToRotation[NOTE_PAD1_RIGHT];
sd.m_ColumnToRotation[4] = mapTapNoteToRotation[NOTE_PAD2_LEFT];
sd.m_ColumnToRotation[5] = mapTapNoteToRotation[NOTE_PAD2_DOWN];
sd.m_ColumnToRotation[6] = mapTapNoteToRotation[NOTE_PAD2_UP];
sd.m_ColumnToRotation[7] = mapTapNoteToRotation[NOTE_PAD2_RIGHT];
sd.m_ColumnToRotation[8] = mapTapNoteToRotation[NOTE_PAD1_UPLEFT];
sd.m_ColumnToRotation[9] = mapTapNoteToRotation[NOTE_PAD1_UPRIGHT];
sd.m_ColumnToRotation[10] = mapTapNoteToRotation[NOTE_PAD2_UPLEFT];
sd.m_ColumnToRotation[11] = mapTapNoteToRotation[NOTE_PAD2_UPRIGHT];
*/
break;
default:
ASSERT( false ); // invalid GameMode
}
return sd;
}
+38 -14
View File
@@ -1,40 +1,64 @@
#pragma once
/*
-----------------------------------------------------------------------------
Class: GameManager
Desc: Manages "Game" and "StyleDef", and "Instrument" definitions, which define
different ways of playing - like "dance" and "pump".
Desc: Manages GameDefs (which define different games, like "dance" and "pump")
and StyleDefs (which define different games, like "single" and "couple")
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#ifndef _GameManager_H_
#define _GameManager_H_
#include "GameDef.h"
#include "StyleDef.h"
const int NUM_GAME_DEFS = 1;
class GameManager
{
public:
GameManager();
~GameManager();
DanceStyle m_DanceStyle; // the current style
void SwitchGame( CString sGame )
{
m_sCurrentGame = sGame;
m_pCurrentGameDef = GetGameDef( sGame );
ASSERT( m_pCurrentGameDef != NULL );
};
void SwitchStyle( CString sStyle )
{
m_sCurrentStyle = sStyle;
m_pCurrentStyleDef = GetStyleDef( m_sCurrentGame, sStyle );
ASSERT( m_pCurrentStyleDef != NULL );
};
CString m_sCurrentGame; // currently only "dance"
CString m_sCurrentStyle; // currently only "single", "versus", "double", "couple", "solo"
inline GameDef* GetCurrentGameDef() { return m_pCurrentGameDef; };
inline StyleDef* GetCurrentStyleDef() { return m_pCurrentStyleDef; };
bool IsPlayerEnabled( PlayerNumber PlayerNo );
StyleDef GetStyleDef( DanceStyle mode );
StyleDef GetCurrentStyleDef() { return GetStyleDef(m_DanceStyle); };
// graphic stuff
CString GetPathToGraphic( const PlayerNumber p, const NoteColumn col, const GameButtonGraphic gbg )
{
StyleInput si( p, col );
GameInput gi = GetCurrentStyleDef()->StyleInputToGameInput( si );
InstrumentButton b = gi.button;
return GetCurrentGameDef()->GetPathToGraphic( b, gbg );
}
protected:
GameDef* m_pCurrentGameDef;
StyleDef* m_pCurrentStyleDef;
GameDef* GetGameDef( CString sGame );
StyleDef* GetStyleDef( CString sGame, CString sStyle );
};
extern GameManager* GAME; // global and accessable from anywhere in our program
#endif
+1 -1
View File
@@ -16,7 +16,7 @@ class GhostArrow;
#include "Sprite.h"
#include "Pattern.h"
#include "NoteMetadata.h"
class GhostArrow : public Sprite
+1 -1
View File
@@ -16,7 +16,7 @@ class GhostArrowBright;
#include "Sprite.h"
#include "Pattern.h"
#include "NoteMetadata.h"
class GhostArrowBright : public Sprite
+91
View File
@@ -0,0 +1,91 @@
#include "stdafx.h"
/*
-----------------------------------------------------------------------------
File: GhostArrowRow.h
Desc: A graphic displayed in the GhostArrowRow during Dancing.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
#include "GhostArrowRow.h"
#include "RageUtil.h"
#include "ScreenDimensions.h"
#include "ThemeManager.h"
#include "ColorArrow.h"
#include "ArrowEffects.h"
#include "GameManager.h"
GhostArrowRow::GhostArrowRow()
{
m_iNumCols = 0;
}
void GhostArrowRow::Load( PlayerOptions po )
{
m_PlayerOptions = po;
StyleDef* pStyleDef = GAME->GetCurrentStyleDef();
GameDef* pGameDef = GAME->GetCurrentGameDef();
m_iNumCols = pStyleDef->GetColsPerPlayer();
// init arrows
for( int c=0; c<m_iNumCols; c++ )
{
m_GhostArrowRow[c].Load( GAME->GetPathToGraphic(PLAYER_1, c, GRAPHIC_TAP_EXPLOSION_DIM) );
m_GhostArrowRowBright[c].Load( GAME->GetPathToGraphic(PLAYER_1, c, GRAPHIC_TAP_EXPLOSION_BRIGHT) );
m_HoldGhostArrowRow[c].Load( GAME->GetPathToGraphic(PLAYER_1, c, GRAPHIC_HOLD_EXPLOSION) );
}
}
void GhostArrowRow::Update( float fDeltaTime, float fSongBeat )
{
m_fSongBeat = fSongBeat;
for( int c=0; c<m_iNumCols; c++ )
{
m_GhostArrowRow[c].Update( fDeltaTime );
m_GhostArrowRowBright[c].Update( fDeltaTime );
m_HoldGhostArrowRow[c].Update( fDeltaTime );
m_GhostArrowRow[c].SetBeat( fSongBeat );
m_GhostArrowRowBright[c].SetBeat( fSongBeat );
m_HoldGhostArrowRow[c].SetBeat( fSongBeat );
}
}
void GhostArrowRow::RenderPrimitives()
{
for( int c=0; c<m_iNumCols; c++ )
{
float fX = ArrowGetXPos( m_PlayerOptions, c, 0, m_fSongBeat );
m_GhostArrowRow[c].SetX( fX );
m_GhostArrowRowBright[c].SetX( fX );
m_HoldGhostArrowRow[c].SetX( fX );
m_GhostArrowRow[c].Draw();
m_GhostArrowRowBright[c].Draw();
m_HoldGhostArrowRow[c].Draw();
}
}
void GhostArrowRow::TapNote( int iCol, TapNoteScore score, bool bBright )
{
ASSERT( iCol >= 0 && iCol < m_iNumCols );
if( bBright )
m_GhostArrowRowBright[iCol].Step( score );
else
m_GhostArrowRow[iCol].Step( score );
}
void GhostArrowRow::HoldNote( int iCol )
{
ASSERT( iCol >= 0 && iCol < m_iNumCols );
m_HoldGhostArrowRow[iCol].Step();
}
+43
View File
@@ -0,0 +1,43 @@
#pragma once
/*
-----------------------------------------------------------------------------
File: GhostArrowRow.h
Desc: A row of GhostArrow Actors
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "ActorFrame.h"
#include "GhostArrow.h"
#include "GhostArrowBright.h"
#include "HoldGhostArrow.h"
#include "GameTypes.h"
#include "StyleDef.h"
class GhostArrowRow : public ActorFrame
{
public:
GhostArrowRow();
void Update( float fDeltaTime, float fSongBeat );
virtual void RenderPrimitives();
void Load( PlayerOptions po );
void TapNote( int iCol, TapNoteScore score, bool bBright );
void HoldNote( int iCol );
protected:
int m_iNumCols;
float m_fSongBeat;
PlayerOptions m_PlayerOptions;
GhostArrow m_GhostArrowRow[MAX_NOTE_TRACKS];
GhostArrowBright m_GhostArrowRowBright[MAX_NOTE_TRACKS];
HoldGhostArrow m_HoldGhostArrowRow[MAX_NOTE_TRACKS];
};
+1 -1
View File
@@ -5,7 +5,7 @@
Desc: See header.
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: This a mark the player receives after clearing a song.
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -5,7 +5,7 @@
Desc: A graphic displayed in the Grade during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: A graphic displayed in the GradeDisplay during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+5 -2
View File
@@ -5,7 +5,7 @@
Desc: A gray arrow that "receives" ColorArrows.
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Ben Nordstrom
Chris Danford
-----------------------------------------------------------------------------
@@ -24,7 +24,10 @@ GrayArrow::GrayArrow()
void GrayArrow::SetBeat( const float fSongBeat )
{
SetState( (int)( fmod(fSongBeat,1) * Sprite::GetNumStates() ) );
int iNewState = (int)( fmod(fSongBeat,1) * Sprite::GetNumStates() );
if( iNewState < 0 )
iNewState += Sprite::GetNumStates();
SetState( iNewState );
}
void GrayArrow::Step()
+2 -2
View File
@@ -4,7 +4,7 @@
Desc: A gray arrow that "receives" ColorArrows.
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Ben Nordstrom
Chris Danford
-----------------------------------------------------------------------------
@@ -16,7 +16,7 @@
#include "Sprite.h"
#include "Pattern.h"
#include "NoteMetadata.h"
class GrayArrow : public Sprite
{
+73
View File
@@ -0,0 +1,73 @@
#include "stdafx.h"
/*
-----------------------------------------------------------------------------
Class: GrayArrowRow
Desc: See header.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "GrayArrowRow.h"
#include "RageUtil.h"
#include "ScreenDimensions.h"
#include "ThemeManager.h"
#include "ColorArrow.h"
#include "ArrowEffects.h"
#include "GameManager.h"
GrayArrowRow::GrayArrowRow()
{
m_iNumCols = 0;
}
void GrayArrowRow::Load( PlayerOptions po )
{
m_PlayerOptions = po;
StyleDef* pStyleDef = GAME->GetCurrentStyleDef();
GameDef* pGameDef = GAME->GetCurrentGameDef();
m_iNumCols = pStyleDef->GetColsPerPlayer();
// init arrow rotations
for( int c=0; c<m_iNumCols; c++ )
{
m_GrayArrow[c].Load( GAME->GetPathToGraphic(PLAYER_1, c, GRAPHIC_RECEPTOR) );
}
}
void GrayArrowRow::Update( float fDeltaTime, float fSongBeat )
{
m_fSongBeat = fSongBeat;
for( int c=0; c<m_iNumCols; c++ )
{
m_GrayArrow[c].Update( fDeltaTime );
m_GrayArrow[c].SetBeat( fSongBeat );
}
}
void GrayArrowRow::RenderPrimitives()
{
for( int c=0; c<m_iNumCols; c++ )
{
// set arrow X
float fX = ArrowGetXPos( m_PlayerOptions, c, 0, m_fSongBeat );
m_GrayArrow[c].SetX( fX );
m_GrayArrow[c].Draw();
}
}
void GrayArrowRow::Step( int iCol )
{
ASSERT( iCol >= 0 && iCol < m_iNumCols );
m_GrayArrow[iCol].Step();
}
+43
View File
@@ -0,0 +1,43 @@
/*
-----------------------------------------------------------------------------
Class: GrayArrowRow
Desc: A row of GrayArrow objects
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#ifndef _GrayArrowRow_H_
#define _GrayArrowRow_H_
#include "GrayArrow.h"
#include "ActorFrame.h"
#include "StyleDef.h"
#include "GameTypes.h"
class GrayArrowRow : public ActorFrame
{
public:
GrayArrowRow();
virtual void Update( float fDeltaTime, float fSongBeat );
virtual void RenderPrimitives();
void Load( PlayerOptions po );
void Step( int iCol );
protected:
int m_iNumCols;
float m_fSongBeat;
PlayerOptions m_PlayerOptions;
GrayArrow m_GrayArrow[MAX_NOTE_TRACKS];
};
#endif
+150 -4
View File
@@ -5,7 +5,7 @@
Desc: See header.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -14,15 +14,161 @@
#include "GrooveRadar.h"
#include "ThemeManager.h"
#include "RageBitmapTexture.h"
#include "GameConstants.h"
GrooveRadar::GrooveRadar()
{
m_sprRadar.Load( THEME->GetPathTo(GRAPHIC_SELECT_MUSIC_RADAR) );
this->AddActor( &m_sprRadar );
m_sprRadarBase.Load( THEME->GetPathTo(GRAPHIC_SELECT_MUSIC_RADAR_BASE) );
this->AddActor( &m_sprRadarBase );
m_sprRadarWords.Load( THEME->GetPathTo(GRAPHIC_SELECT_MUSIC_RADAR_WORDS) );
m_sprRadarWords.SetY( -10 );
this->AddActor( &m_sprRadarWords );
for( int p=0; p<NUM_PLAYERS; p++ )
{
m_bValuesVisible[p] = false;
m_PercentTowardNew[p] = 0;
for( int c=0; c<NUM_RADAR_CATEGORIES; c++ )
{
m_fValuesNew[p][c] = 0;
m_fValuesOld[p][c] = 0;
}
}
}
void GrooveRadar::LoadFromSong( Song* pSong ) // NULL means no song
void GrooveRadar::SetFromNoteMetadata( PlayerNumber p, NoteMetadata* pNoteMetadata ) // NULL means no song
{
if( pNoteMetadata != NULL )
{
for( int c=0; c<NUM_RADAR_CATEGORIES; c++ )
{
const float fValueCurrent = m_fValuesOld[p][c] * (1-m_PercentTowardNew[p]) + m_fValuesNew[p][c] * m_PercentTowardNew[p];
m_fValuesOld[p][c] = fValueCurrent;
m_fValuesNew[p][c] = randomf(0.5f,1.1f);
}
if( m_bValuesVisible[p] == false ) // the values WERE invisible
m_PercentTowardNew[p] = 1;
else
m_PercentTowardNew[p] = 0;
m_bValuesVisible[p] = true;
}
else // pNoteMetadata == NULL
{
m_bValuesVisible[p] = false;
}
}
void GrooveRadar::Update( float fDeltaTime )
{
ActorFrame::Update( fDeltaTime );
for( int p=0; p<NUM_PLAYERS; p++ )
{
m_PercentTowardNew[p] = min( m_PercentTowardNew[p]+4.0f*fDeltaTime, 1 );
}
}
void GrooveRadar::RenderPrimitives()
{
ActorFrame::RenderPrimitives();
// draw radar filling
const float fRadius = m_sprRadarBase.GetZoomedHeight()/2.0f;
LPDIRECT3DVERTEXBUFFER8 pVB = SCREEN->GetVertexBuffer();
LPDIRECT3DDEVICE8 pd3dDevice = SCREEN->GetDevice();
pd3dDevice->SetTexture( 0, NULL );
pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
CUSTOMVERTEX* v;
for( int p=0; p<NUM_PLAYERS; p++ )
{
if( !m_bValuesVisible[p] )
continue;
//
// use a fan to draw the volume
//
pVB->Lock( 0, 0, (BYTE**)&v, 0 );
D3DXCOLOR color = PLAYER_COLOR[p];
color.a = 0.5f;
v[0].p = D3DXVECTOR3( 0, 0, 0 );
v[0].color = color;
int i;
for( i=0; i<NUM_RADAR_CATEGORIES+1; i++ ) // do one extra to close the fan
{
const int c = i%NUM_RADAR_CATEGORIES;
const float fDistFromCenter =
( m_fValuesOld[p][c] * (1-m_PercentTowardNew[p]) + m_fValuesNew[p][c] * m_PercentTowardNew[p] ) * fRadius;
const float fRotation = D3DX_PI/2 + D3DX_PI*2 / 5.0f * i;
const float fX = cosf(fRotation) * fDistFromCenter;
const float fY = -sinf(fRotation) * fDistFromCenter;
v[1+i].p = D3DXVECTOR3( fX, fY, 0 );
v[1+i].color = color;
}
pVB->Unlock();
pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 5 );
//
// use a strip to draw the thick line
//
pVB->Lock( 0, 0, (BYTE**)&v, 0 );
for( i=0; i<NUM_RADAR_CATEGORIES+1; i++ ) // do one extra to close the fan
{
const int c = i%NUM_RADAR_CATEGORIES;
const float fDistFromCenter =
( m_fValuesOld[p][c] * (1-m_PercentTowardNew[p]) + m_fValuesNew[p][c] * m_PercentTowardNew[p] ) * fRadius;
const float fDistFromCenterInner = fDistFromCenter-2;
const float fDistFromCenterOutter = fDistFromCenter+2;
const float fRotation = D3DX_PI/2 + D3DX_PI*2 / 5.0f * i;
const float fXInner = cosf(fRotation) * fDistFromCenterInner;
const float fXOutter = cosf(fRotation) * fDistFromCenterOutter;
const float fYInner = -sinf(fRotation) * fDistFromCenterInner;
const float fYOutter = -sinf(fRotation) * fDistFromCenterOutter;
v[i*2+0].p = D3DXVECTOR3( fXInner, fYInner, 0 );
v[i*2+1].p = D3DXVECTOR3( fXOutter, fYOutter, 0 );
v[i*2+0].color = PLAYER_COLOR[p];
v[i*2+1].color = PLAYER_COLOR[p];
}
pVB->Unlock();
pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 10 );
}
}
void GrooveRadar::TweenOnScreen()
{
SetZoom( 0.5f );
SetRotation( D3DX_PI*4 );
BeginTweening( 0.6f );
SetTweenZoom( 1 );
SetTweenRotationZ( 0 );
}
void GrooveRadar::TweenOffScreen()
{
BeginTweening( 0.6f );
SetTweenRotationZ( D3DX_PI*4 );
SetTweenZoom( 0 );
}
+19 -5
View File
@@ -4,7 +4,7 @@
Desc: The song's GrooveRadar displayed in SelectSong.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -17,18 +17,32 @@
#include "Song.h"
const int NUM_RADAR_CATEGORIES = 5;
class GrooveRadar : public ActorFrame
{
public:
GrooveRadar::GrooveRadar();
GrooveRadar();
void LoadFromSong( Song* pSong ); // NULL means no Song
virtual void Update( float fDeltaTime );
virtual void RenderPrimitives();
void SetFromNoteMetadata( PlayerNumber p, NoteMetadata* pNoteMetadata ); // NULL means no Song
void TweenOnScreen();
void TweenOffScreen();
protected:
Sprite m_sprRadar;
bool m_bValuesVisible[NUM_PLAYERS];
float m_PercentTowardNew[NUM_PLAYERS];
float m_fValuesNew[NUM_PLAYERS][NUM_RADAR_CATEGORIES];
float m_fValuesOld[NUM_PLAYERS][NUM_RADAR_CATEGORIES];
Sprite m_sprRadarBase;
Sprite m_sprRadarWords;
};
#endif
+1 -1
View File
@@ -16,7 +16,7 @@ class HoldGhostArrow;
#include "Sprite.h"
#include "Pattern.h"
#include "NoteMetadata.h"
class HoldGhostArrow : public Sprite
+1 -1
View File
@@ -5,7 +5,7 @@
Desc: A graphic displayed in the HoldJudgement during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: A graphic displayed in the HoldJudgement during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: Wrapper for reading and writing an .ini file.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: Wrapper for reading and writing an .ini file.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+87
View File
@@ -0,0 +1,87 @@
#include "stdafx.h"
/*
-----------------------------------------------------------------------------
Class: InputFilter
Desc: See header.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include <math.h> // for fmod
#include "InputFilter.h"
#include "RageHelper.h"
#include "RageInput.h"
#include "ErrorCatcher/ErrorCatcher.h"
InputFilter* FILTER = NULL; // global and accessable from anywhere in our program
void InputFilter::GetInputEvents( InputEventArray &array, float fDeltaTime )
{
INPUTM->Update();
for( int d=0; d<NUM_INPUT_DEVICES; d++ ) // foreach InputDevice
{
int iNumButtonsToCheck;
switch( d )
{
case DEVICE_KEYBOARD:
iNumButtonsToCheck = NUM_KEYBOARD_BUTTONS;
break;
case DEVICE_JOY1:
case DEVICE_JOY2:
case DEVICE_JOY3:
case DEVICE_JOY4:
iNumButtonsToCheck = NUM_JOYSTICK_BUTTONS;
break;
default:
ASSERT( false );
}
for( int b=0; b<iNumButtonsToCheck; b++ ) // foreach button
{
const DeviceInput di = DeviceInput(InputDevice(d),b);
if( INPUTM->WasBeingPressed(di) )
{
if( INPUTM->IsBeingPressed(di) )
{
const float fOldHoldTime = m_fTimeHeld[d][b];
m_fTimeHeld[d][b] += fDeltaTime;
const float fNewHoldTime = m_fTimeHeld[d][b];
float fTimeBetweenRepeats;
InputEventType iet;
if( fOldHoldTime > TIME_BEFORE_SLOW_REPEATS )
{
if( fOldHoldTime > TIME_BEFORE_FAST_REPEATS )
{
fTimeBetweenRepeats = TIME_BETWEEN_FAST_REPEATS;
iet = IET_FAST_REPEAT;
}
else
{
fTimeBetweenRepeats = TIME_BETWEEN_SLOW_REPEATS;
iet = IET_SLOW_REPEAT;
}
if( int(fOldHoldTime/fTimeBetweenRepeats) != int(fNewHoldTime/fTimeBetweenRepeats) )
array.Add( InputEvent(di,iet) );
}
}
else // !INPUTM->IsBeingPressed(di)
m_fTimeHeld[d][b] = 0;
}
else // !INPUTM->WasBeingPressed(di)
{
if( INPUTM->IsBeingPressed(di) )
array.Add( InputEvent(di,IET_FIRST_PRESS) );
else // !INPUTM->IsBeingPressed(di)
; // don't care
}
}
}
}
+56
View File
@@ -0,0 +1,56 @@
#pragma once
/*
-----------------------------------------------------------------------------
Class: InputFilter
Desc: Checks RageInput and generates a list of InputEvents, which can
represent when a button is first pressed, when a button is released,
or when an repeating input fires.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "RageInput.h"
const float TIME_BEFORE_SLOW_REPEATS = 0.7f;
const float TIME_BEFORE_FAST_REPEATS = 2.0f;
const float TIME_BETWEEN_SLOW_REPEATS = 0.25f;
const float TIME_BETWEEN_FAST_REPEATS = 0.125f;
enum InputEventType { IET_FIRST_PRESS, IET_SLOW_REPEAT, IET_FAST_REPEAT, IET_RELEASE };
class InputEvent : public DeviceInput
{
public:
InputEvent() { type=IET_FIRST_PRESS; };
InputEvent( InputDevice d, int b, InputEventType t ) { device=d; button=b; type=t; };
InputEvent( DeviceInput di, InputEventType t ) { device=di.device; button=di.button; type=t; };
InputEventType type;
};
typedef CArray<InputEvent, InputEvent> InputEventArray;
class InputFilter
{
public:
InputFilter()
{
for( int i=0; i<NUM_INPUT_DEVICES; i++ )
{
for( int j=0; j<NUM_DEVICE_BUTTONS; j++ )
m_fTimeHeld[i][j] = 0;
}
};
void GetInputEvents( InputEventArray &array, float fDeltaTime );
float m_fTimeHeld[NUM_INPUT_DEVICES][NUM_DEVICE_BUTTONS];
};
extern InputFilter* FILTER; // global and accessable from anywhere in our program
+292
View File
@@ -0,0 +1,292 @@
#include "stdafx.h"
/*
-----------------------------------------------------------------------------
Class: InputMapper
Desc: See Header.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "InputMapper.h"
#include "IniFile.h"
#include "GameManager.h"
InputMapper* MAPPER = NULL; // global and accessable from anywhere in our program
InputMapper::InputMapper()
{
m_sCurrentGame = GAME->m_sCurrentGame;
ReadMappingsFromDisk();
}
InputMapper::~InputMapper()
{
// don't worry about releasing the Song array. Let the OS do it :-)
SaveMappingsToDisk();
}
void InputMapper::ReadMappingsFromDisk()
{
ASSERT( GAME != NULL );
IniFile ini;
ini.SetPath( m_sCurrentGame + ".ini" );
if( !ini.ReadFile() ) {
return; // load nothing
//FatalError( "could not read config file" );
}
CMapStringToString* pKey = ini.GetKeyPointer("Input");
CString name_string, value_string;
if( pKey != NULL )
{
for( POSITION pos = pKey->GetStartPosition(); pos != NULL; )
{
pKey->GetNextAssoc( pos, name_string, value_string );
GameInput GameI;
GameI.fromString(name_string);
CStringArray sDeviceInputStrings;
split( value_string, ",", sDeviceInputStrings, false );
for( int i=0; i<sDeviceInputStrings.GetSize() && i<NUM_GAME_TO_DEVICE_SLOTS; i++ )
{
DeviceInput DeviceI;
DeviceI.fromString( sDeviceInputStrings[i] );
if( !DeviceI.IsBlank() )
SetInputMap( DeviceI, GameI, i );
}
}
}
}
void InputMapper::SaveMappingsToDisk()
{
IniFile ini;
ini.SetPath( m_sCurrentGame + ".ini" );
// ini.ReadFile(); // don't read the file so that we overwrite everything there
// iterate over our input map and write all mappings to the ini file
for( int i=0; i<NUM_INSTRUMENTS; i++ )
{
for( int j=0; j<NUM_INSTRUMENT_BUTTONS; j++ )
{
CString sNameString, sValueString;
GameInput GameI( (InstrumentNumber)i, (InstrumentButton)j );
sNameString = GameI.toString();
sValueString = ssprintf( "%s,%s,%s",
m_GItoDI[i][j][0].toString(), m_GItoDI[i][j][1].toString(), m_GItoDI[i][j][2].toString() );
ini.SetValue( "Input", sNameString, sValueString );
}
}
ini.WriteFile();
}
///////////////////////////////////////
// Input mapping stuff
///////////////////////////////////////
void InputMapper::SetInputMap( DeviceInput DeviceI, GameInput GameI, int iSlotIndex, bool bOverrideHardCoded )
{
// remove the old input
ClearFromInputMap( DeviceI );
ClearFromInputMap( GameI, iSlotIndex );
m_GItoDI[GameI.number][GameI.button][iSlotIndex] = DeviceI;
UpdateTempDItoGI();
}
void InputMapper::ClearFromInputMap( DeviceInput DeviceI )
{
// search for where this DeviceI maps to
for( int p=0; p<NUM_INSTRUMENTS; p++ )
{
for( int b=0; b<NUM_INSTRUMENT_BUTTONS; b++ )
{
for( int s=0; s<NUM_GAME_TO_DEVICE_SLOTS; s++ )
{
if( m_GItoDI[p][b][s] == DeviceI )
m_GItoDI[p][b][s].MakeBlank();
}
}
}
UpdateTempDItoGI();
}
void InputMapper::ClearFromInputMap( GameInput GameI, int iSlotIndex )
{
if( GameI.IsBlank() )
return;
m_GItoDI[GameI.number][GameI.button][iSlotIndex].MakeBlank();
UpdateTempDItoGI();
}
void InputMapper::UpdateTempDItoGI()
{
// clear out m_tempDItoGI
for( int d=0; d<NUM_INPUT_DEVICES; d++ )
{
for( int b=0; b<NUM_DEVICE_BUTTONS; b++ )
{
m_tempDItoGI[d][b].MakeBlank();
}
}
// repopulate m_tempDItoGI
for( int n=0; n<NUM_INSTRUMENTS; n++ )
{
for( int b=0; b<NUM_INSTRUMENT_BUTTONS; b++ )
{
for( int s=0; s<NUM_GAME_TO_DEVICE_SLOTS; s++ )
{
GameInput GameI( (InstrumentNumber)n, (InstrumentButton)b );
DeviceInput DeviceI = m_GItoDI[n][b][s];
if( DeviceI.IsBlank() )
continue;
m_tempDItoGI[DeviceI.device][DeviceI.button] = GameI;
}
}
}
}
bool InputMapper::DeviceToGame( DeviceInput DeviceI, GameInput& GameI ) // return true if there is a mapping from device to pad
{
GameI = m_tempDItoGI[DeviceI.device][DeviceI.button];
return GameI.number != PLAYER_NONE;
}
bool InputMapper::GameToDevice( GameInput GameI, int iSoltNum, DeviceInput& DeviceI ) // return true if there is a mapping from pad to device
{
DeviceI = m_GItoDI[GameI.number][GameI.button][iSoltNum];
return DeviceI.device != DEVICE_NONE;
}
struct HardCodedMenuKey
{
InputDevice device;
int device_button;
PlayerNumber player_no;
MenuButton menu_button;
};
const HardCodedMenuKey g_HardCodedMenuKeys[] =
{
{ DEVICE_KEYBOARD, DIK_UP, PLAYER_1, MENU_BUTTON_UP },
{ DEVICE_KEYBOARD, DIK_DOWN, PLAYER_1, MENU_BUTTON_DOWN },
{ DEVICE_KEYBOARD, DIK_LEFT, PLAYER_1, MENU_BUTTON_LEFT },
{ DEVICE_KEYBOARD, DIK_RIGHT, PLAYER_1, MENU_BUTTON_RIGHT },
{ DEVICE_KEYBOARD, DIK_RETURN, PLAYER_1, MENU_BUTTON_NEXT },
{ DEVICE_KEYBOARD, DIK_ESCAPE, PLAYER_1, MENU_BUTTON_BACK },
};
const int NUM_HARD_CODED_MENU_KEYS = sizeof(g_HardCodedMenuKeys) / sizeof(HardCodedMenuKey);
MenuInput InputMapper::DeviceToMenu( DeviceInput DeviceI )
{
for( int i=0; i<NUM_HARD_CODED_MENU_KEYS; i++ )
{
if( g_HardCodedMenuKeys[i].device == DeviceI.device &&
g_HardCodedMenuKeys[i].device_button == DeviceI.button )
{
return MenuInput( g_HardCodedMenuKeys[i].player_no, g_HardCodedMenuKeys[i].menu_button );
}
}
return MenuInput( PLAYER_NONE, MENU_BUTTON_NONE );
}
DeviceInput InputMapper::MenuToDevice( MenuInput MenuI )
{
for( int i=0; i<NUM_HARD_CODED_MENU_KEYS; i++ )
{
if( g_HardCodedMenuKeys[i].player_no == MenuI.player &&
g_HardCodedMenuKeys[i].menu_button == MenuI.button )
{
return DeviceInput( g_HardCodedMenuKeys[i].device, g_HardCodedMenuKeys[i].device_button );
}
}
return DeviceInput( DEVICE_NONE, -1 );
}
void InputMapper::GameToStyle( GameInput GameI, StyleInput &StyleI )
{
StyleDef* pStyleDef = GAME->GetCurrentStyleDef();
StyleI = pStyleDef->GameInputToStyleInput( GameI );
}
void InputMapper::GameToMenu( GameInput GameI, MenuInput &MenuI )
{
GameDef* pGameDef = GAME->GetCurrentGameDef();
MenuI = pGameDef->GameInputToMenuInput( GameI );
}
void InputMapper::StyleToGame( StyleInput StyleI, GameInput &GameI )
{
StyleDef* pStyleDef = GAME->GetCurrentStyleDef();
GameI = pStyleDef->StyleInputToGameInput( StyleI );
}
void InputMapper::MenuToGame( MenuInput MenuI, GameInput &GameI )
{
GameDef* pGameDef = GAME->GetCurrentGameDef();
GameI = pGameDef->MenuInputToGameInput( MenuI );
}
bool InputMapper::IsButtonDown( GameInput GameI )
{
for( int i=0; i<NUM_GAME_TO_DEVICE_SLOTS; i++ )
{
DeviceInput DeviceI;
if( GameToDevice( GameI, i, DeviceI ) )
{
if( INPUTM->IsBeingPressed( DeviceI ) )
return true;
}
}
return false;
}
bool InputMapper::IsButtonDown( MenuInput MenuI )
{
GameInput GameI;
MenuToGame( MenuI, GameI );
return IsButtonDown( GameI );
}
bool InputMapper::IsButtonDown( StyleInput StyleI )
{
GameInput GameI;
StyleToGame( StyleI, GameI );
return IsButtonDown( GameI );
}
+78
View File
@@ -0,0 +1,78 @@
#pragma once
/*
-----------------------------------------------------------------------------
Class: InputMapper
Desc: Holds user-chosen preferences and saves it between sessions. This class
also has temporary holders for information that passed between windows - e.g.
ScoreSummary.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "RageInput.h"
#include "GameInput.h"
#include "MenuInput.h"
#include "StyleInput.h"
#include "GameTypes.h"
const int NUM_GAME_TO_DEVICE_SLOTS = 3; // three device inputs may map to one game input
class InputMapper
{
public:
InputMapper();
~InputMapper();
void SwitchGame( CString sNewGame )
{
SaveMappingsToDisk();
m_sCurrentGame = sNewGame;
ReadMappingsFromDisk();
};
void ReadMappingsFromDisk();
void SaveMappingsToDisk();
// input mapping stuff
void SetInputMap( DeviceInput DeviceI, GameInput GameI, int iSlotIndex, bool bOverrideHardCoded = false );
void ClearFromInputMap( DeviceInput DeviceI );
void ClearFromInputMap( GameInput GameI, int iSlotIndex );
bool DeviceToGame( DeviceInput DeviceI, GameInput& GameI ); // return true if there is a mapping from device to pad
bool GameToDevice( GameInput GameI, int iSoltNum, DeviceInput& DeviceI ); // return true if there is a mapping from pad to device
MenuInput DeviceToMenu( DeviceInput DeviceI );
DeviceInput MenuToDevice( MenuInput MenuI );
void GameToStyle( GameInput GameI, StyleInput &StyleI );
void StyleToGame( StyleInput StyleI, GameInput &GameI );
void GameToMenu( GameInput GameI, MenuInput &MenuI );
void MenuToGame( MenuInput MenuI, GameInput &GameI );
bool IsButtonDown( GameInput GameI );
bool IsButtonDown( MenuInput MenuI );
bool IsButtonDown( StyleInput StyleI );
protected:
CString m_sCurrentGame;
// all the DeviceInputs that map to a GameInput
DeviceInput m_GItoDI[NUM_INSTRUMENTS][NUM_INSTRUMENT_BUTTONS][NUM_GAME_TO_DEVICE_SLOTS];
// lookup for efficiency from a DeviceInput to a GameInput
// This is repopulated every time m_PItoDI changes by calling UpdateTempDItoPI().
GameInput m_tempDItoGI[NUM_INPUT_DEVICES][NUM_DEVICE_BUTTONS];
void UpdateTempDItoGI();
};
extern InputMapper* MAPPER; // global and accessable from anywhere in our program
+1 -1
View File
@@ -5,7 +5,7 @@
Desc: A graphic displayed in the Judgement during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: A graphic displayed in the Judgement during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+9 -7
View File
@@ -5,7 +5,7 @@
Desc: Base class for menu Windows.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -44,6 +44,7 @@ void MenuElements::Load( CString sBackgroundPath, CString sTopEdgePath, CString
m_sprTopEdge.Load( sTopEdgePath );
m_sprTopEdge.TurnShadowOff();
m_sprTopEdge.SetZ( -1 );
m_sprTopEdge.SetY( SCREEN_TOP + m_sprTopEdge.GetZoomedHeight()/2.0f );
m_sprBottomEdge.Load( THEME->GetPathTo(GRAPHIC_MENU_BOTTOM_EDGE) );
m_sprBottomEdge.TurnShadowOff();
@@ -71,8 +72,8 @@ void MenuElements::TweenTopEdgeOnScreen()
{
SetTopEdgeOffScreen();
m_sprTopEdge.BeginTweening( MENU_ELEMENTS_TWEEN_TIME );
m_sprTopEdge.SetTweenY( m_sprTopEdge.GetZoomedHeight()/2 );
m_sprTopEdge.BeginTweening( MENU_ELEMENTS_TWEEN_TIME*2, TWEEN_SPRING );
m_sprTopEdge.SetTweenX( CENTER_X );
float fOriginalZoomY = m_textHelp.GetZoomY();
m_textHelp.SetZoomY( 0 );
@@ -86,8 +87,9 @@ void MenuElements::TweenTopEdgeOffScreen()
{
SetTopEdgeOnScreen();
m_sprTopEdge.BeginTweening( MENU_ELEMENTS_TWEEN_TIME );
m_sprTopEdge.SetTweenY( -m_sprTopEdge.GetZoomedHeight() );
m_sprTopEdge.BeginTweening( MENU_ELEMENTS_TWEEN_TIME*2, TWEEN_BIAS_END );
m_sprTopEdge.SetTweenX( SCREEN_WIDTH*1.5f );
m_textHelp.BeginTweening( MENU_ELEMENTS_TWEEN_TIME );
m_textHelp.SetTweenZoomY( 0 );
@@ -147,12 +149,12 @@ void MenuElements::SetBackgroundOffScreen()
void MenuElements::SetTopEdgeOnScreen()
{
m_sprTopEdge.SetXY( CENTER_X, m_sprTopEdge.GetZoomedHeight() );
m_sprTopEdge.SetXY( CENTER_X, m_sprTopEdge.GetZoomedHeight()/2 );
}
void MenuElements::SetTopEdgeOffScreen()
{
m_sprTopEdge.SetXY( CENTER_X, -m_sprTopEdge.GetZoomedHeight() );
m_sprTopEdge.SetXY( CENTER_X+SCREEN_WIDTH, m_sprTopEdge.GetZoomedHeight()/2 );
}
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: Base class for menu Windows.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
#ifndef _MenuElements_H_
+46
View File
@@ -0,0 +1,46 @@
#pragma once
/*
-----------------------------------------------------------------------------
Class: MenuInput
Desc: An input event specific to a menu navigation. This is generated based
on a GameDef.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "GameTypes.h"
enum MenuButton
{
MENU_BUTTON_LEFT = 0,
MENU_BUTTON_RIGHT,
MENU_BUTTON_UP,
MENU_BUTTON_DOWN,
MENU_BUTTON_NEXT,
MENU_BUTTON_BACK,
NUM_MENU_BUTTONS, // leave this at the end
MENU_BUTTON_NONE
};
struct MenuInput
{
MenuInput() { MakeBlank(); };
MenuInput( PlayerNumber p, MenuButton b ) { player = p; button = b; };
PlayerNumber player;
MenuButton button;
bool operator==( const MenuInput &other ) { return player == other.player && button == other.button; };
inline bool IsBlank() const { return player == PLAYER_NONE; };
inline bool IsValid() const { return !IsBlank(); };
inline void MakeBlank() { player = PLAYER_NONE; button = MENU_BUTTON_NONE; };
};
+1 -1
View File
@@ -5,7 +5,7 @@
Desc: A graphic that appears to blur and come into focus.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: A graphic that appears to blur and come into focus.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -5,7 +5,7 @@
Desc: A graphic displayed in the MusicSortDisplay during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: A graphic displayed in the MusicSortDisplay during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -5,7 +5,7 @@
Desc: A graphic displayed in the MusicStatusDisplay during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: A graphic displayed in the MusicStatusDisplay during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+155 -111
View File
@@ -5,7 +5,7 @@
Desc: A graphic displayed in the MusicWheel during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -24,28 +24,30 @@
const float SWITCH_MUSIC_TIME = 0.3f;
const float SORT_ICON_ON_SCREEN_X = -395;
const float SORT_ICON_ON_SCREEN_Y = -176;
const float SORT_ICON_ON_SCREEN_X = 146;
const float SORT_ICON_ON_SCREEN_Y = 0;
const float SORT_ICON_OFF_SCREEN_X = SORT_ICON_ON_SCREEN_X - 200;
const float SORT_ICON_OFF_SCREEN_X = SORT_ICON_ON_SCREEN_X + 64;
const float SORT_ICON_OFF_SCREEN_Y = SORT_ICON_ON_SCREEN_Y;
D3DXCOLOR COLOR_BANNER_TINTS[] = {
D3DXCOLOR( 0.0f, 1.0f, 0.0f, 1 ),
D3DXCOLOR( 0.0f, 1.0f, 1.0f, 1 ),
D3DXCOLOR( 1.0f, 0.0f, 1.0f, 1 ),
D3DXCOLOR( 1.0f, 0.0f, 0.0f, 1 ),
D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1 ),
D3DXCOLOR( 0.9f, 0.0f, 0.2f, 1 ), // red
D3DXCOLOR( 0.6f, 0.0f, 0.4f, 1 ), // pink
D3DXCOLOR( 0.3f, 0.2f, 0.4f, 1 ), // purple
D3DXCOLOR( 0.0f, 0.4f, 0.8f, 1 ), // sky blue
D3DXCOLOR( 0.0f, 0.6f, 0.6f, 1 ), // sea green
D3DXCOLOR( 0.0f, 0.6f, 0.2f, 1 ), // green
D3DXCOLOR( 0.8f, 0.6f, 0.0f, 1 ), // orange
};
const int NUM_BANNER_TINTS = sizeof(COLOR_BANNER_TINTS) / sizeof(D3DXCOLOR);
D3DXCOLOR COLOR_SECTION_TINTS[] = {
D3DXCOLOR( 0.9f, 0.0f, 0.2f, 1 ), // red
D3DXCOLOR( 0.6f, 0.0f, 0.4f, 1 ), // pink
D3DXCOLOR( 0.2f, 0.1f, 0.3f, 1 ), // purple
D3DXCOLOR( 0.3f, 0.2f, 0.4f, 1 ), // purple
D3DXCOLOR( 0.0f, 0.4f, 0.8f, 1 ), // sky blue
D3DXCOLOR( 0.0f, 0.6f, 0.6f, 1 ), // sea green
D3DXCOLOR( 0.0f, 0.6f, 0.2f, 1 ), // green
@@ -75,27 +77,36 @@ void WheelItemData::LoadFromSong( Song* pSong )
{
ASSERT( pSong != NULL );
m_pSong = pSong;
m_WheelItemType = TYPE_MUSIC;
m_WheelItemType = TYPE_SONG;
}
WheelItemDisplay::WheelItemDisplay()
{
m_MusicStatusDisplay.SetXY( -132, 0 );
m_MusicStatusDisplay.SetXY( -136, 0 );
m_Banner.SetHorizAlign( align_left );
m_Banner.SetXY( 15, 0 );
m_Banner.SetXY( -30, 0 );
m_sprSectionBackground.Load( THEME->GetPathTo(GRAPHIC_SECTION_BACKGROUND) );
m_sprSectionBackground.SetXY( -30, 0 );
m_sprSongBar.Load( THEME->GetPathTo(GRAPHIC_SELECT_MUSIC_SONG_BAR) );
m_sprSongBar.SetXY( 0, 0 );
m_sprSectionBar.Load( THEME->GetPathTo(GRAPHIC_SELECT_MUSIC_SECTION_BAR) );
m_sprSectionBar.SetXY( -30, 0 );
m_textSectionName.Load( THEME->GetPathTo(FONT_BOLD) );
m_textSectionName.TurnShadowOff();
m_textSectionName.SetHorizAlign( align_left );
m_textSectionName.SetVertAlign( align_middle );
m_textSectionName.SetXY( m_sprSectionBackground.GetX() - m_sprSectionBackground.GetUnzoomedWidth()/2 + 10, 0 );
m_textSectionName.SetZoom( 1.2f );
m_textSectionName.SetXY( m_sprSectionBar.GetX() - m_sprSectionBar.GetUnzoomedWidth()/2 + 10, 0 );
m_textSectionName.SetZoom( 1.0f );
m_textSectionName.SetDiffuseColor( COLOR_SECTION_LETTER );
for( int p=0; p<NUM_PLAYERS; p++ )
{
m_GradeDisplay[p].SetZoom( 0.5f );
m_GradeDisplay[p].SetXY( 90.0f + p*30.0f, 0 );
}
}
@@ -117,31 +128,45 @@ void WheelItemDisplay::LoadFromWheelItemData( WheelItemData* pWID )
{
case TYPE_SECTION:
if( m_sSectionName.GetLength() > 15 &&
-1 != m_sSectionName.Find(' ', m_sSectionName.GetLength()/3) ) // this is space in the name
{
int iIndexSplit = m_sSectionName.Find( ' ', m_sSectionName.GetLength()/3 );
m_sSectionName.SetAt( iIndexSplit, '\n' );
CString sDisplayName = SONG->ShortenGroupName(m_sSectionName);
if( sDisplayName.GetLength() <= 4 )
m_textSectionName.SetZoom( 2 );
else
m_textSectionName.SetZoom( 1 );
m_textSectionName.SetText( sDisplayName );
m_textSectionName.SetZoom( 0.6f );
m_textSectionName.SetText( m_sSectionName );
}
else // this is a short name
{
m_textSectionName.SetZoom( 1.2f );
m_textSectionName.SetText( m_sSectionName );
}
float fTextWidth, fSpriteWidth;
fTextWidth = m_textSectionName.GetWidestLineWidthInSourcePixels() * m_textSectionName.GetZoom();
fSpriteWidth = m_sprSectionBackground.GetUnzoomedWidth() * m_sprSectionBackground.GetZoom() - 20;
fSpriteWidth = m_sprSectionBar.GetUnzoomedWidth() * m_sprSectionBar.GetZoom() - 20;
if( fTextWidth > fSpriteWidth )
m_textSectionName.SetZoomX( m_textSectionName.GetZoom() * fSpriteWidth / fTextWidth );
m_sprSectionBackground.SetDiffuseColor( m_colorTint );
m_sprSectionBar.SetDiffuseColor( m_colorTint );
}
break;
case TYPE_MUSIC:
case TYPE_SONG:
{
m_Banner.LoadFromSong( m_pSong );
m_Banner.SetDiffuseColor( m_colorTint );
m_MusicStatusDisplay.SetType( m_MusicStatusDisplayType );
for( int p=0; p<NUM_PLAYERS; p++ )
{
if( GAME->IsPlayerEnabled( (PlayerNumber)p ) )
{
const DifficultyClass dc = PREFS->m_PreferredDifficultyClass[p];
const Grade grade = m_pSong->GetGradeForDifficultyClass( GAME->m_sCurrentGame, GAME->m_sCurrentStyle, dc );
m_GradeDisplay[p].SetGrade( grade );
m_GradeDisplay[p].SetDiffuseColor( D3DXCOLOR(1,1,1,1) );
}
else // !IsPlayerEnabled
{
m_GradeDisplay[p].SetDiffuseColor( D3DXCOLOR(1,1,1,0) );
}
}
}
break;
default:
ASSERT( false ); // invalid type
@@ -164,7 +189,7 @@ void WheelItemDisplay::SetDiffuseColor( D3DXCOLOR c )
colorTempTint.b *= c.b;
m_Banner.SetDiffuseColor( colorTempTint );
m_sprSectionBackground.SetDiffuseColor( colorTempTint );
m_sprSectionBar.SetDiffuseColor( colorTempTint );
D3DXCOLOR colorTempLetter = COLOR_SECTION_LETTER;
colorTempLetter.a = c.a;
@@ -184,12 +209,15 @@ void WheelItemDisplay::Update( float fDeltaTime )
switch( m_WheelItemType )
{
case TYPE_SECTION:
m_sprSectionBackground.Update( fDeltaTime );
m_sprSectionBar.Update( fDeltaTime );
m_textSectionName.Update( fDeltaTime );
break;
case TYPE_MUSIC:
case TYPE_SONG:
m_sprSongBar.Update( fDeltaTime );
m_MusicStatusDisplay.Update( fDeltaTime );
m_Banner.Update( fDeltaTime );
for( int p=0; p<NUM_PLAYERS; p++ )
m_GradeDisplay[p].Update( fDeltaTime );
break;
}
}
@@ -199,12 +227,15 @@ void WheelItemDisplay::RenderPrimitives()
switch( m_WheelItemType )
{
case TYPE_SECTION:
m_sprSectionBackground.Draw();
m_sprSectionBar.Draw();
m_textSectionName.Draw();
break;
case TYPE_MUSIC:
case TYPE_SONG:
m_sprSongBar.Draw();
m_MusicStatusDisplay.Draw();
m_Banner.Draw();
for( int p=0; p<NUM_PLAYERS; p++ )
m_GradeDisplay[p].Draw();
break;
}
}
@@ -215,11 +246,7 @@ MusicWheel::MusicWheel()
{
HELPER.Log( "MusicWheel::MusicWheel()" );
m_sprSelectionBackground.Load( THEME->GetPathTo(GRAPHIC_MUSIC_SELECTION_HIGHLIGHT) );
m_sprSelectionBackground.SetXY( 0, 0 );
m_sprSelectionBackground.SetDiffuseColor( D3DXCOLOR(0,0,0.7f,0.5f) ); // dark transparent blue
m_sprSelectionOverlay.Load( THEME->GetPathTo(GRAPHIC_MUSIC_SELECTION_HIGHLIGHT) );
m_sprSelectionOverlay.Load( THEME->GetPathTo(GRAPHIC_SELECT_MUSIC_SONG_HIGHLIGHT) );
m_sprSelectionOverlay.SetXY( 0, 0 );
m_sprSelectionOverlay.SetDiffuseColor( D3DXCOLOR(0,0,0,0) ); // invisible
m_sprSelectionOverlay.SetEffectGlowing( 1.5f, D3DXCOLOR(1,1,1,0.1f), D3DXCOLOR(1,1,1,1) );
@@ -277,27 +304,32 @@ MusicWheel::MusicWheel()
for( int so=0; so<NUM_SORT_ORDERS; so++ )
BuildWheelItemDatas( m_WheelItemDatas[so], SongSortOrder(so) );
// select a song if none are selected
if( SONG->m_pCurSong == NULL && // if there is no currently selected song
SONG->m_pSongs.GetSize() > 0 ) // and there is at least one song
{
SONG->m_pCurSong = SONG->m_pSongs[0]; // select the first song
CArray<Song*, Song*> arraySongs;
SONG->GetSongsInGroup( SONG->m_sPreferredGroup, arraySongs );
if( arraySongs.GetSize() > 0 )
SONG->m_pCurSong = arraySongs[0]; // select the first song
}
// find the previously selected song (if any)
for( i=0; i<GetCurWheelItemDatas().GetSize(); i++ )
if( SONG->m_pCurSong != NULL )
{
if( GetCurWheelItemDatas()[i].m_pSong != NULL
&& GetCurWheelItemDatas()[i].m_pSong == SONG->m_pCurSong )
// find the previously selected song (if any)
for( i=0; i<GetCurWheelItemDatas().GetSize(); i++ )
{
m_iSelection = i; // select it
m_sExpandedSectionName = GetCurWheelItemDatas()[m_iSelection].m_sSectionName; // make its group the currently expanded group
if( GetCurWheelItemDatas()[i].m_pSong == SONG->m_pCurSong )
{
m_iSelection = i; // select it
m_sExpandedSectionName = GetCurWheelItemDatas()[m_iSelection].m_sSectionName; // make its group the currently expanded group
break;
}
}
}
// rebuild the WheelItems that appear on screen
RebuildWheelItemDisplays();
@@ -316,13 +348,13 @@ void MusicWheel::BuildWheelItemDatas( CArray<WheelItemData, WheelItemData&> &arr
///////////////////////////////////
CArray<Song*, Song*> arraySongs;
// copy only song that have at least one Pattern for the current GameMode
// copy only song that have at least one NoteMetadata for the current GameMode
for( int i=0; i<SONG->m_pSongs.GetSize(); i++ )
{
Song* pSong = SONG->m_pSongs[i];
CArray<Pattern*, Pattern*> arraySteps;
pSong->GetPatternsThatMatchStyle( GAME->m_DanceStyle, arraySteps );
CArray<NoteMetadata*, NoteMetadata*> arraySteps;
pSong->GetNoteMetadatasThatMatchGameAndStyle( GAME->m_sCurrentGame, GAME->m_sCurrentStyle, arraySteps );
if( arraySteps.GetSize() > 0 )
arraySongs.Add( pSong );
@@ -359,29 +391,21 @@ void MusicWheel::BuildWheelItemDatas( CArray<WheelItemData, WheelItemData&> &arr
arrayWheelItemDatas.RemoveAll(); // clear out the previous wheel items...
// ...and load new ones
bool bUseSections;
switch( so )
{
case SORT_MOST_PLAYED:
case SORT_BPM:
// make WheelItems without sections
arrayWheelItemDatas.SetSize( arraySongs.GetSize() );
{
for( int i=0; i<arraySongs.GetSize(); i++ )
{
Song* pSong = arraySongs[i];
WheelItemData &WID = arrayWheelItemDatas[i];
WID.LoadFromSong( pSong );
WID.m_colorTint = *m_mapGroupNameToColorPtr[pSong->GetGroupName()];
WID.m_sSectionName = "";
}
}
break;
case SORT_GROUP:
case SORT_TITLE:
case SORT_MOST_PLAYED: bUseSections = false; break;
case SORT_BPM: bUseSections = false; break;
case SORT_GROUP: bUseSections = SONG->m_sPreferredGroup != "ALL MUSIC"; break;
case SORT_TITLE: bUseSections = true; break;
// case SORT_ARTIST:
{
// make WheelItemDatas with sections
default: ASSERT( false );
}
if( bUseSections )
{
// make WheelItemDatas with sections
arrayWheelItemDatas.SetSize( arraySongs.GetSize()*2 ); // make sure we have enough room for all music and section items
CString sLastSection = "";
@@ -406,11 +430,21 @@ void MusicWheel::BuildWheelItemDatas( CArray<WheelItemData, WheelItemData&> &arr
WID.m_sSectionName = sThisSection;
WID.m_colorTint = *m_mapGroupNameToColorPtr[pSong->GetGroupName()];
}
arrayWheelItemDatas.SetSize( iCurWheelItem ); // make sure we have enough room for all music and section items
arrayWheelItemDatas.SetSize( iCurWheelItem ); // make sure we have enough room for all music and section items
}
else
{
arrayWheelItemDatas.SetSize( arraySongs.GetSize() );
{
for( int i=0; i<arraySongs.GetSize(); i++ )
{
Song* pSong = arraySongs[i];
WheelItemData &WID = arrayWheelItemDatas[i];
WID.LoadFromSong( pSong );
WID.m_colorTint = *m_mapGroupNameToColorPtr[pSong->GetGroupName()];
WID.m_sSectionName = "";
}
}
break;
default:
ASSERT( false ); // unhandled SORT_ORDER
}
// init crowns
@@ -451,16 +485,18 @@ void MusicWheel::SwitchSortOrder()
float MusicWheel::GetBannerY( float fPosOffsetsFromMiddle )
{
return fPosOffsetsFromMiddle*43.2f;
return fPosOffsetsFromMiddle*44;
}
float MusicWheel::GetBannerBrightness( float fPosOffsetsFromMiddle )
{
return 1 - fabsf(fPosOffsetsFromMiddle)*0.11f;
//return 1 - fabsf(fPosOffsetsFromMiddle)*0.11f;
return 1;
}
float MusicWheel::GetBannerAlpha( float fPosOffsetsFromMiddle )
{
/*
if( m_WheelState == STATE_FLYING_OFF_BEFORE_NEXT_SORT
|| m_WheelState == STATE_TWEENING_OFF_SCREEN )
{
@@ -479,33 +515,51 @@ float MusicWheel::GetBannerAlpha( float fPosOffsetsFromMiddle )
{
return 1;
}
*/
return 1;
}
float MusicWheel::GetBannerX( float fPosOffsetsFromMiddle )
{
float fX = (1-cosf((fPosOffsetsFromMiddle)/3))*95.0f;
if( m_WheelState == STATE_FLYING_OFF_BEFORE_NEXT_SORT
|| m_WheelState == STATE_TWEENING_OFF_SCREEN )
float fPercentOffScreen = 0;
switch( m_WheelState )
{
case STATE_FLYING_OFF_BEFORE_NEXT_SORT:
case STATE_TWEENING_OFF_SCREEN:
fPercentOffScreen = 1 - (m_fTimeLeftInState / FADE_TIME);
break;
case STATE_FLYING_ON_AFTER_NEXT_SORT:
case STATE_TWEENING_ON_SCREEN:
fPercentOffScreen = m_fTimeLeftInState / FADE_TIME;
break;
default:
fPercentOffScreen = 1;
break;
}
switch( m_WheelState )
{
case STATE_FLYING_OFF_BEFORE_NEXT_SORT:
case STATE_TWEENING_OFF_SCREEN:
case STATE_FLYING_ON_AFTER_NEXT_SORT:
case STATE_TWEENING_ON_SCREEN:
{
/*
float fDistFromCenter = fabsf( fPosOffsetsFromMiddle );
float fPercentOffScreen = 1- (m_fTimeLeftInState / FADE_TIME);
float fXLogicalOffset = max( 0, fPercentOffScreen - 1 + (fDistFromCenter+3)/6 );
fXLogicalOffset = powf( fXLogicalOffset, 1.7f ); // accelerate
float fXPixelOffset = fXLogicalOffset * 600;
fX += fXPixelOffset;
*/
const float fShift = fPosOffsetsFromMiddle/NUM_WHEEL_ITEMS_TO_DRAW - 0.5f; // this is always < 0
const float fXTween = fShift * 800 + fPercentOffScreen * 1200;
fX = max( fX, fXTween );
}
break;
}
else if( m_WheelState == STATE_FLYING_ON_AFTER_NEXT_SORT
|| m_WheelState == STATE_TWEENING_ON_SCREEN )
{
float fDistFromCenter = fabsf( fPosOffsetsFromMiddle );
float fPercentOffScreen = m_fTimeLeftInState / FADE_TIME;
float fXLogicalOffset = max( 0, fPercentOffScreen - 1 + (fDistFromCenter+3)/6 );
fXLogicalOffset = powf( fXLogicalOffset, 1.7f ); // accelerate
float fXPixelOffset = fXLogicalOffset * 600;
fX += fXPixelOffset;
}
return fX;
}
@@ -525,7 +579,7 @@ void MusicWheel::RebuildWheelItemDisplays()
if( iIndex < 0 )
iIndex = GetCurWheelItemDatas().GetSize()-1;
}
while( GetCurWheelItemDatas()[iIndex].m_WheelItemType == TYPE_MUSIC
while( GetCurWheelItemDatas()[iIndex].m_WheelItemType == TYPE_SONG
&& GetCurWheelItemDatas()[iIndex].m_sSectionName != ""
&& GetCurWheelItemDatas()[iIndex].m_sSectionName != m_sExpandedSectionName );
}
@@ -545,7 +599,7 @@ void MusicWheel::RebuildWheelItemDisplays()
if( iIndex > GetCurWheelItemDatas().GetSize()-1 )
iIndex = 0;
}
while( GetCurWheelItemDatas()[iIndex].m_WheelItemType == TYPE_MUSIC
while( GetCurWheelItemDatas()[iIndex].m_WheelItemType == TYPE_SONG
&& GetCurWheelItemDatas()[iIndex].m_sSectionName != ""
&& GetCurWheelItemDatas()[iIndex].m_sSectionName != m_sExpandedSectionName );
}
@@ -555,9 +609,6 @@ void MusicWheel::RebuildWheelItemDisplays()
void MusicWheel::RenderPrimitives()
{
m_sprSelectionBackground.Draw();
for( int i=0; i<NUM_WHEEL_ITEMS_TO_DRAW; i++ )
{
WheelItemDisplay& display = m_WheelItemDisplays[i];
@@ -587,8 +638,6 @@ void MusicWheel::Update( float fDeltaTime )
ActorFrame::Update( fDeltaTime );
m_sprSelectionOverlay.Update( fDeltaTime );
m_sprSelectionBackground.Update( fDeltaTime );
for( int i=0; i<NUM_WHEEL_ITEMS_TO_DRAW; i++ )
@@ -713,7 +762,7 @@ void MusicWheel::PrevMusic()
if( m_iSelection < 0 )
m_iSelection = GetCurWheelItemDatas().GetSize()-1;
}
while( GetCurWheelItemDatas()[m_iSelection].m_WheelItemType == TYPE_MUSIC
while( GetCurWheelItemDatas()[m_iSelection].m_WheelItemType == TYPE_SONG
&& GetCurWheelItemDatas()[m_iSelection].m_sSectionName != ""
&& GetCurWheelItemDatas()[m_iSelection].m_sSectionName != m_sExpandedSectionName );
@@ -746,7 +795,7 @@ void MusicWheel::NextMusic()
if( m_iSelection > GetCurWheelItemDatas().GetSize()-1 )
m_iSelection = 0;
}
while( GetCurWheelItemDatas()[m_iSelection].m_WheelItemType == TYPE_MUSIC
while( GetCurWheelItemDatas()[m_iSelection].m_WheelItemType == TYPE_SONG
&& GetCurWheelItemDatas()[m_iSelection].m_sSectionName != ""
&& GetCurWheelItemDatas()[m_iSelection].m_sSectionName != m_sExpandedSectionName );
@@ -815,7 +864,7 @@ bool MusicWheel::Select()
}
return false;
case TYPE_MUSIC:
case TYPE_SONG:
default:
return true;
@@ -827,11 +876,8 @@ void MusicWheel::TweenOnScreen()
m_WheelState = STATE_TWEENING_ON_SCREEN;
m_fTimeLeftInState = FADE_TIME;
float fOriginalZoomY = m_sprSelectionBackground.GetZoomY();
m_sprSelectionBackground.SetZoomY( 0 );
m_sprSelectionBackground.BeginTweening( FADE_TIME );
m_sprSelectionBackground.SetTweenZoomY( fOriginalZoomY );
float fOriginalZoomY;
fOriginalZoomY = m_sprSelectionOverlay.GetZoomY();
m_sprSelectionOverlay.SetZoomY( 0 );
m_sprSelectionOverlay.BeginTweening( FADE_TIME );
m_sprSelectionOverlay.SetTweenZoomY( fOriginalZoomY );
@@ -844,8 +890,6 @@ void MusicWheel::TweenOffScreen()
m_WheelState = STATE_TWEENING_OFF_SCREEN;
m_fTimeLeftInState = FADE_TIME;
m_sprSelectionBackground.BeginTweening( FADE_TIME );
m_sprSelectionBackground.SetTweenZoomY( 0 );
m_sprSelectionOverlay.BeginTweening( FADE_TIME );
m_sprSelectionOverlay.SetTweenZoomY( 0 );
+8 -7
View File
@@ -4,7 +4,7 @@
Desc: A graphic displayed in the MusicWheel during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -29,13 +29,13 @@
const int NUM_WHEEL_ITEMS_TO_DRAW = 11;
const float FADE_TIME = 0.5f;
const float FADE_TIME = 0.7f;
const WindowMessage SM_SongChanged = WindowMessage(SM_User+47); // this should be unique!
const WindowMessage SM_PlaySongSample = WindowMessage(SM_User+48);
enum WheelItemType { TYPE_SECTION, TYPE_MUSIC };
enum WheelItemType { TYPE_SECTION, TYPE_SONG };
struct WheelItemData
@@ -73,12 +73,14 @@ public:
void LoadFromWheelItemData( WheelItemData* pWID );
// for a section
Sprite m_sprSectionBackground;
BitmapText m_textSectionName;
Sprite m_sprSectionBar;
BitmapText m_textSectionName;
// for a music
Sprite m_sprSongBar;
MusicStatusDisplay m_MusicStatusDisplay;
TextBanner m_Banner;
GradeDisplay m_GradeDisplay[NUM_PLAYERS];
};
@@ -116,7 +118,6 @@ protected:
void SwitchSortOrder();
Sprite m_sprSelectionBackground;
Sprite m_sprSelectionOverlay;
MusicSortDisplay m_MusicSortDisplay;
@@ -173,7 +174,7 @@ protected:
// sTemp = "NUM";
// return sTemp;
case SORT_TITLE:
sTemp = pSong->GetTitle();
sTemp = pSong->GetFullTitle();
sTemp.MakeUpper();
sTemp = (sTemp.GetLength() > 0) ? sTemp.Left(1) : "";
if( IsAnInt(sTemp) )
+640
View File
@@ -0,0 +1,640 @@
#include "stdafx.h"
/*
-----------------------------------------------------------------------------
File: NoteData.cpp
Desc: A pattern of ColorArrows that past Y==0.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "NoteData.h"
#include "RageUtil.h"
#include "ScreenDimensions.h"
#include "ThemeManager.h"
#include "ArrowEffects.h"
#include "PrefsManager.h"
#include "GameConstants.h"
#include "ErrorCatcher/ErrorCatcher.h"
NoteData::NoteData()
{
for( int i=0; i<MAX_NOTE_TRACKS; i++ )
{
for( int j=0; j<MAX_TAP_NOTE_ELEMENTS; j++ )
m_TapNotes[i][j] = '0';
}
m_iNumTracks = 0;
m_iNumHoldNotes = 0;
}
void NoteData::ClearRange( NoteIndex iNoteIndexBegin, NoteIndex iNoteIndexEnd )
{
// delete old TapNotes in the range
for( int i=iNoteIndexBegin; i<=iNoteIndexEnd; i++ )
{
for( int c=0; c<m_iNumTracks; c++ )
m_TapNotes[c][i] = '0';
}
// delete old HoldNotes in the range
int iIndexRead, iIndexWrite = 0;
const int iOrigNumHoldNotes = m_iNumHoldNotes;
for( iIndexRead = 0; iIndexRead < iOrigNumHoldNotes; iIndexRead++ )
{
HoldNote &hn = m_HoldNotes[iIndexRead];
if( (hn.m_iStartIndex >= iNoteIndexBegin && hn.m_iStartIndex <= iNoteIndexEnd) ||
(hn.m_iEndIndex >= iNoteIndexBegin && hn.m_iEndIndex <= iNoteIndexEnd) ) // overlap (kinda)
{
; // do nothing
}
else // ! overlap
{
m_HoldNotes[iIndexWrite] = m_HoldNotes[iIndexRead];
iIndexWrite++;
}
}
m_iNumHoldNotes = iIndexWrite;
}
void NoteData::CopyRange( NoteData* pFrom, NoteIndex iNoteIndexBegin, NoteIndex iNoteIndexEnd )
{
ASSERT( pFrom->m_iNumTracks == m_iNumTracks );
int i;
// copy recorded TapNotes
for( i=iNoteIndexBegin; i<=iNoteIndexEnd; i++ )
{
for( int c=0; c<m_iNumTracks; c++ )
m_TapNotes[c][i] = pFrom->m_TapNotes[c][i];
}
// copy recorded HoldNotes
for( i=0; i<pFrom->m_iNumHoldNotes; i++ )
{
HoldNote hn = pFrom->m_HoldNotes[i];
if( (hn.m_iStartIndex >= iNoteIndexBegin && hn.m_iStartIndex <= iNoteIndexEnd) ||
(hn.m_iEndIndex >= iNoteIndexBegin && hn.m_iEndIndex <= iNoteIndexEnd) ) // overlap (kinda)
{
this->AddHoldNote( hn );
}
}
}
void NoteData::AddHoldNote( HoldNote add )
{
int i;
// look for other hold notes that overlap and merge them
for( i=0; i<m_iNumHoldNotes; i++ ) // for each HoldNote
{
HoldNote &other = m_HoldNotes[i];
if( add.m_iTrack == other.m_iTrack && // the notes correspond
other.m_iStartIndex <= add.m_iEndIndex &&
other.m_iEndIndex >= add.m_iStartIndex ) // these HoldNotes overlap (this isn't entirely correct!)
{
add.m_iStartIndex = min(add.m_iStartIndex, other.m_iStartIndex);
add.m_iEndIndex = max(add.m_iEndIndex, other.m_iEndIndex);
// delete this HoldNote
for( int j=i; j<m_iNumHoldNotes-1; j++ )
{
m_HoldNotes[j] = m_HoldNotes[j+1];
}
m_iNumHoldNotes--;
}
}
// delete TapNotes under this HoldNote
for( i=add.m_iStartIndex; i<=add.m_iEndIndex; i++ )
{
m_TapNotes[add.m_iTrack][i] = '0';
};
m_HoldNotes[m_iNumHoldNotes++] = add;
}
void NoteData::RemoveHoldNote( int index )
{
ASSERT( index > 0 && index < m_iNumHoldNotes );
for( int j=index; j<m_iNumHoldNotes-1; j++ )
{
m_HoldNotes[j] = m_HoldNotes[j+1];
}
m_iNumHoldNotes--;
}
float NoteData::GetLastBeat()
{
int iOldestIndexFoundSoFar = 0;
int i;
for( i=0; i<m_iNumHoldNotes; i++ )
{
if( m_HoldNotes[i].m_iEndIndex > iOldestIndexFoundSoFar )
iOldestIndexFoundSoFar = m_HoldNotes[i].m_iEndIndex;
}
for( i=MAX_TAP_NOTE_ELEMENTS-1; i>=iOldestIndexFoundSoFar; i-- ) // iterate back to front
{
for( int t=0; t<m_iNumTracks; t++ )
{
if( m_TapNotes[t][i] != '0' )
{
iOldestIndexFoundSoFar = i;
goto done_searching_tap_notes;
}
}
}
done_searching_tap_notes:
return NoteIndexToBeat( iOldestIndexFoundSoFar );
}
int NoteData::GetNumTapNotes()
{
int iNumSteps = 0;
for( int i=0; i<MAX_TAP_NOTE_ELEMENTS; i++ )
{
for( int t=0; i<m_iNumTracks; t++ )
{
if( m_TapNotes[t][i] != '0' )
iNumSteps++;
}
}
iNumSteps += m_iNumHoldNotes;
return iNumSteps;
}
int NoteData::GetNumHoldNotes()
{
return m_iNumHoldNotes;
}
void NoteData::CropToLeftSide()
{
int iFirstRightSideColumn = 4;
int iLastRightSideColumn = 7;
// clear out the right half
for( int c=iFirstRightSideColumn; c<=iLastRightSideColumn; c++ )
{
for( int i=0; i<MAX_TAP_NOTE_ELEMENTS; i++ ) // foreach TapNote
m_TapNotes[c][i] = '0';
}
for( int i=m_iNumHoldNotes-1; i>=0; i-- ) // foreach HoldNote
{
if( c >= iFirstRightSideColumn )
{
// delete this HoldNote by shifting everything down
for( int j=i; j<m_iNumHoldNotes-1; j++ )
m_HoldNotes[j] = m_HoldNotes[j+1];
m_iNumHoldNotes--;
}
}
}
void NoteData::CropToRightSide()
{
int iFirstRightSideColumn = 4;
int iLastRightSideColumn = 7;
int c;
// clear out the left half
for( c=0; c<iFirstRightSideColumn; c++ )
{
for( int i=0; i<MAX_TAP_NOTE_ELEMENTS; i++ ) // foreach TapNote
m_TapNotes[c][i] = '0';
}
// copy the right side into the left
for( c=iFirstRightSideColumn; c<=iLastRightSideColumn; c++ )
{
for( int i=0; i<MAX_TAP_NOTE_ELEMENTS; i++ ) // foreach TapNote
{
m_TapNotes[c-4][i] = m_TapNotes[c][i];
m_TapNotes[c][i] = '0';
}
}
for( int i=m_iNumHoldNotes-1; i>=0; i-- ) // foreach HoldNote
{
HoldNote &hn = m_HoldNotes[i];
if( hn.m_iTrack < iFirstRightSideColumn )
{
// delete this HoldNote by shifting everything down
RemoveHoldNote( i );
}
else
{
m_HoldNotes[i].m_iTrack -= 4;
}
}
}
void NoteData::RemoveHoldNotes()
{
// turn all the HoldNotes into TapNotes
for( int i=0; i<m_iNumHoldNotes; i++ )
{
HoldNote &hn = m_HoldNotes[i];
int iIndex = hn.m_iStartIndex;
int iCol = hn.m_iTrack;
m_TapNotes[iCol][iIndex] = '1';
}
// Remove all HoldNotes
m_iNumHoldNotes = 0;
}
void NoteData::Turn( PlayerOptions::TurnType tt )
{
// transform the NoteData
int oldColToNewCol[12][2]; // 0 is old Step, 1 is new Step mapping
oldColToNewCol[0][0] = 0; oldColToNewCol[0][1] = 0;
oldColToNewCol[1][0] = 1; oldColToNewCol[1][1] = 1;
oldColToNewCol[2][0] = 2; oldColToNewCol[2][1] = 2;
oldColToNewCol[3][0] = 3; oldColToNewCol[3][1] = 3;
oldColToNewCol[4][0] = 4; oldColToNewCol[4][1] = 4;
oldColToNewCol[5][0] = 5; oldColToNewCol[5][1] = 5;
oldColToNewCol[6][0] = 6; oldColToNewCol[6][1] = 6;
oldColToNewCol[7][0] = 7; oldColToNewCol[7][1] = 7;
oldColToNewCol[8][0] = 8; oldColToNewCol[8][1] = 8;
oldColToNewCol[9][0] = 9; oldColToNewCol[9][1] = 9;
oldColToNewCol[10][0]= 10; oldColToNewCol[10][1]= 10;
oldColToNewCol[11][0]= 11; oldColToNewCol[11][1]= 11;
switch( tt )
{
case PlayerOptions::TURN_NONE:
break;
case PlayerOptions::TURN_MIRROR:
oldColToNewCol[0][1] = 3;
oldColToNewCol[2][1] = 2;
oldColToNewCol[3][1] = 1;
oldColToNewCol[5][1] = 0;
oldColToNewCol[6][1] = 7;
oldColToNewCol[8][1] = 6;
oldColToNewCol[9][1] = 5;
oldColToNewCol[11][1]= 4;
break;
case PlayerOptions::TURN_LEFT:
oldColToNewCol[0][1] = 1;
oldColToNewCol[2][1] = 3;
oldColToNewCol[3][1] = 0;
oldColToNewCol[5][1] = 2;
oldColToNewCol[6][1] = 5;
oldColToNewCol[8][1] = 7;
oldColToNewCol[9][1] = 4;
oldColToNewCol[11][1]= 6;
break;
case PlayerOptions::TURN_RIGHT:
oldColToNewCol[0][1] = 3;
oldColToNewCol[2][1] = 0;
oldColToNewCol[3][1] = 4;
oldColToNewCol[5][1] = 1;
oldColToNewCol[6][1] = 6;
oldColToNewCol[8][1] = 4;
oldColToNewCol[9][1] = 7;
oldColToNewCol[11][1]= 5;
break;
case PlayerOptions::TURN_SHUFFLE:
bool bAlreadyMapped[12];
for( int i=0; i<12; i++ )
bAlreadyMapped[i] = false;
// hack: don't shuffle the Up+... NoteData
bAlreadyMapped[1] = true;
bAlreadyMapped[4] = true;
bAlreadyMapped[7] = true;
bAlreadyMapped[10] = true;
// shuffle left side
for( i=0; i<6; i++ )
{
if( i == 1 || i == 4 )
continue;
int iMapsTo;
do {
iMapsTo = rand()%6;
} while( bAlreadyMapped[iMapsTo] );
bAlreadyMapped[iMapsTo] = true;
oldColToNewCol[i][1] = oldColToNewCol[iMapsTo][0];
}
// shuffle right side
for( i=6; i<12; i++ )
{
if( i == 7 || i == 10 )
continue;
int iMapsTo;
do {
iMapsTo = rand()%6+6;
} while( bAlreadyMapped[iMapsTo] );
bAlreadyMapped[iMapsTo] = true;
oldColToNewCol[i][1] = oldColToNewCol[iMapsTo][0];
}
break;
}
NoteData* pNewData = new NoteData; // write into here as we tranform
pNewData->m_iNumTracks = m_iNumTracks;
// transform m_TapNotes
for( int i=0; i<MAX_TAP_NOTE_ELEMENTS; i++ )
{
for( int j=0; j<12; j++ )
{
int iOldCol = oldColToNewCol[j][0];
int iNewCol = oldColToNewCol[j][1];
pNewData->m_TapNotes[iNewCol][i] = m_TapNotes[iOldCol][i];
}
}
// transform m_HoldNotes
for( i=0; i<m_iNumHoldNotes; i++ )
{
for( int j=0; j<12; j++ )
{
HoldNote &hn = m_HoldNotes[i];
int iOldCol = oldColToNewCol[j][0];
int iNewCol = oldColToNewCol[j][1];
if( hn.m_iTrack == iOldCol )
{
HoldNote newHN = { iNewCol, hn.m_iStartIndex, hn.m_iEndIndex };
pNewData->AddHoldNote( newHN );
}
}
}
//
// copy note data from newData back into this
//
(*this) = *pNewData;
}
void NoteData::MakeLittle()
{
// filter out all non-quarter notes
for( int i=0; i<MAX_TAP_NOTE_ELEMENTS; i++ )
{
if( i%ELEMENTS_PER_BEAT != 0 )
{
// filter out all non-quarter notes
for( int c=0; c<m_iNumTracks; c++ )
{
m_TapNotes[c][i] = '0';
}
}
}
// leave HoldNotes unchanged (what should be do with them?)
}
void NoteData::Convert2sAnd3sToHoldNotes()
{
// Note that a 3 or a 1 can end a HoldNote.
// A 1 can end a HoldNote because it's easier for parsing DWIs
for( int col=0; col<m_iNumTracks; col++ ) // foreach column
{
for( int i=0; i<MAX_TAP_NOTE_ELEMENTS; i++ ) // foreach TapNote element
{
if( m_TapNotes[col][i] == '2' ) // this is a HoldNote begin marker
{
for( int j=i; j<MAX_TAP_NOTE_ELEMENTS; j++ ) // search for end of HoldNote
{
if( m_TapNotes[col][j] == '1' ||
m_TapNotes[col][j] == '3' ) // found it!
{
HoldNote hn = { col, i, j };
AddHoldNote( hn );
break;
}
}
}
}
}
}
void NoteData::ConvertHoldNotesTo2sAnd3s()
{
// copy HoldNotes into the new structure, but expand them into 2s and 3s
for( int i=0; i<m_iNumHoldNotes; i++ )
{
HoldNote &hn = m_HoldNotes[i];
m_TapNotes[hn.m_iTrack][hn.m_iStartIndex] = '2';
m_TapNotes[hn.m_iTrack][hn.m_iEndIndex] = '3';
}
m_iNumHoldNotes = 0;
}
void NoteData::SnapToNearestNoteType( NoteType nt1, NoteType nt2, float fBeginBeat, float fEndBeat )
{
// nt2 is optional and should be -1 if it is not used
float fSnapInterval1, fSnapInterval2;
switch( nt1 )
{
case NOTE_4TH: fSnapInterval1 = 1/1.0f; break;
case NOTE_8TH: fSnapInterval1 = 1/2.0f; break;
case NOTE_12TH: fSnapInterval1 = 1/3.0f; break;
case NOTE_16TH: fSnapInterval1 = 1/4.0f; break;
default: ASSERT( false );
}
switch( nt2 )
{
case NOTE_4TH: fSnapInterval2 = 1/1.0f; break;
case NOTE_8TH: fSnapInterval2 = 1/2.0f; break;
case NOTE_12TH: fSnapInterval2 = 1/3.0f; break;
case NOTE_16TH: fSnapInterval2 = 1/4.0f; break;
case -1: fSnapInterval2 = 10000; break; // nothing will ever snap to this. That is good!
default: ASSERT( false );
}
int iNoteIndexBegin = BeatToNoteIndex( fBeginBeat );
int iNoteIndexEnd = BeatToNoteIndex( fEndBeat );
//ConvertHoldNotesTo2sAnd3s();
// iterate over all TapNotes in the interval and snap them
for( int i=iNoteIndexBegin; i<=iNoteIndexEnd; i++ )
{
int iOldIndex = i;
float fOldBeat = NoteIndexToBeat( iOldIndex );
float fNewBeat1 = froundf( fOldBeat, fSnapInterval1 );
float fNewBeat2 = froundf( fOldBeat, fSnapInterval2 );
bool bNewBeat1IsCloser = fabsf(fNewBeat1-fOldBeat) < fabsf(fNewBeat2-fOldBeat);
float fNewBeat = bNewBeat1IsCloser ? fNewBeat1 : fNewBeat2;
int iNewIndex = BeatToNoteIndex( fNewBeat );
for( int c=0; c<m_iNumTracks; c++ )
{
TapNote note = m_TapNotes[c][iOldIndex];
m_TapNotes[c][iOldIndex] = '0';
m_TapNotes[c][iNewIndex] = max( m_TapNotes[c][iNewIndex], note ); // this causes HoldNotes to override TapNotes
}
}
//Convert2sAnd3sToHoldNotes();
}
void NoteData::GetMeasureStrings( CStringArray &arrayMeasureStrings )
{
ConvertHoldNotesTo2sAnd3s();
float fLastBeat = this->GetLastBeat();
int iLastMeasure = int( fLastBeat/BEATS_PER_MEASURE );
for( int m=0; m<=iLastMeasure; m++ ) // foreach measure
{
CString sMeasureString;
int iMeasureStartIndex = m * ELEMENTS_PER_MEASURE;
int iMeasureLastIndex = (m+1) * ELEMENTS_PER_MEASURE - 1;
// probe to find the smallest note type
NoteType nt;
int iNoteIndexSpacing;
for( nt=(NoteType)0; nt<NUM_NOTE_TYPES; nt=NoteType(nt+1) )
{
float fBeatSpacing = NOTE_TYPE_TO_BEAT[nt];
iNoteIndexSpacing = roundf( fBeatSpacing * ELEMENTS_PER_BEAT );
bool bFoundSmallerNote = false;
for( int i=iMeasureStartIndex; i<=iMeasureLastIndex; i++ ) // for each index in this measure
{
if( i % iNoteIndexSpacing == 0 )
continue; // skip
if( !IsRowEmpty(i) )
{
bFoundSmallerNote = true;
break;
}
}
if( bFoundSmallerNote )
continue; // keep searching
else
break; // stop searching
}
if( nt == NUM_NOTE_TYPES ) // we didn't find one
iNoteIndexSpacing = 1;
for( int i=iMeasureStartIndex; i<=iMeasureLastIndex; i+=iNoteIndexSpacing )
{
for( int c=0; c<m_iNumTracks; c++ )
sMeasureString += m_TapNotes[c][i];
sMeasureString += '\n';
}
arrayMeasureStrings.Add( sMeasureString );
}
}
void NoteData::SetFromMeasureStrings( CStringArray &arrayMeasureStrings )
{
for( int m=0; m<arrayMeasureStrings.GetSize(); m++ )
{
CString sMeasureString = arrayMeasureStrings[m];
sMeasureString.TrimLeft();
sMeasureString.TrimRight();
CStringArray arrayNoteLines;
split( sMeasureString, "\n", arrayNoteLines );
int iNumNoteLines = arrayNoteLines.GetSize();
for( int l=0; l<arrayNoteLines.GetSize(); l++ )
{
const float fPercentIntoMeasure = l/(float)arrayNoteLines.GetSize();
const float fBeat = (m + fPercentIntoMeasure) * BEATS_PER_MEASURE;
const int iIndex = BeatToNoteIndex( fBeat );
CString sNoteLine = arrayNoteLines[l];
sNoteLine.TrimRight();
if( m_iNumTracks == 0 )
m_iNumTracks = sNoteLine.GetLength();
if( m_iNumTracks != sNoteLine.GetLength() )
FatalError( "Line doesn't have right number of notes." );
for( int c=0; c<sNoteLine.GetLength(); c++ )
{
m_TapNotes[c][iIndex] = sNoteLine[c];
}
}
}
ASSERT( m_iNumTracks != 0 );
}
void NoteData::LoadTransformed( NoteData* pOriginal, int iNewNumTracks, TrackNumber iNewToOriginalTrack[] )
{
// init
for( int i=0; i<MAX_NOTE_TRACKS; i++ )
{
for( int j=0; j<MAX_TAP_NOTE_ELEMENTS; j++ )
m_TapNotes[i][j] = '0';
}
m_iNumHoldNotes = 0;
m_iNumTracks = iNewNumTracks;
// copy tracks
for( int t=0; t<m_iNumTracks; t++ )
{
int iOriginalTrack = iNewToOriginalTrack[t];
int i;
for( i=0; i<MAX_TAP_NOTE_ELEMENTS; i++ )
m_TapNotes[t][i] = pOriginal->m_TapNotes[iOriginalTrack][i];
for( i=0; i<MAX_HOLD_NOTE_ELEMENTS; i++ )
{
HoldNote hn = pOriginal->m_HoldNotes[i];
if( hn.m_iTrack == iOriginalTrack )
{
hn.m_iTrack = t;
this->AddHoldNote( hn );
}
}
}
}
+176
View File
@@ -0,0 +1,176 @@
#pragma once
/*
-----------------------------------------------------------------------------
File: NoteData.h
Desc: Holds data about the notes that the player is supposed to hit. NoteData
is organized by:
track - corresponds to different columns of notes on the screen
index - corresponds to subdivisions of beats
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "GameTypes.h"
typedef unsigned char TapNote;
typedef unsigned char TrackNumber;
typedef unsigned short NoteIndex;
// '1' = tap note
// '2' = hold note begin
// '3' = hold note end ('1' can also end a HoldNote)
// ... for future expansion
enum TapNoteScore {
TNS_NONE,
TNS_PERFECT,
TNS_GREAT,
TNS_GOOD,
TNS_BOO,
TNS_MISS
};
//enum TapNoteTiming {
// TNT_NONE,
// TNT_EARLY,
// TNT_LATE
//};
struct HoldNote
{
TrackNumber m_iTrack;
NoteIndex m_iStartIndex;
NoteIndex m_iEndIndex;
};
enum HoldNoteResult
{
HNR_NONE, // this HoldNote has not been scored yet
HNR_OK, // the HoldNote has passed and was successfully held all the way through
HNR_NG // the HoldNote has passed and they missed it
};
struct HoldNoteScore
{
TapNoteScore m_TapNoteScore; // The scoring of the tap Note that begins the hold.
// This is judeged separately from the actual hold.
HoldNoteResult m_Result;
float m_fLife; // 1.0 means this HoldNote has full life.
// 0.0 means this HoldNote is dead
// When this value hits 0.0 for the first time,
// m_HoldScore becomes HSS_NG.
// If the life is > 0.0 when the HoldNote ends, then
// m_HoldScore becomes HSS_OK.
HoldNoteScore()
{
m_TapNoteScore = TNS_NONE;
m_Result = HNR_NONE;
m_fLife = 1.0f;
};
};
const int MAX_NOTE_TRACKS = 16;
const int MAX_MEASURES = 200; // this should be long enough to hold 10:00 minute songs (
const int BEATS_PER_MEASURE = 4;
const int MAX_BEATS = MAX_MEASURES * BEATS_PER_MEASURE;
const int ELEMENTS_PER_BEAT = 12; // It is important that this number is evenly divisible by 2, 3, 4, and 8
const int ELEMENTS_PER_MEASURE = ELEMENTS_PER_BEAT * BEATS_PER_MEASURE;
const int MAX_TAP_NOTE_ELEMENTS = MAX_BEATS*ELEMENTS_PER_BEAT;
const int MAX_HOLD_NOTE_ELEMENTS = 200;
inline int BeatToNoteIndex( float fBeatNum ) { return int( fBeatNum * ELEMENTS_PER_BEAT + 0.5f); }; // round
inline int BeatToNoteIndexNotRounded( float fBeatNum ){ return (int)( fBeatNum * ELEMENTS_PER_BEAT ); };
inline float NoteIndexToBeat( float fNoteIndex ) { return fNoteIndex / (float)ELEMENTS_PER_BEAT; };
inline float NoteIndexToBeat( int iNoteIndex ) { return NoteIndexToBeat( (float)iNoteIndex ); };
enum NoteType
{
NOTE_4TH, // quarter notes
NOTE_8TH, // eighth notes
NOTE_12TH, // triplets
NOTE_16TH, // sixteenth notes
NUM_NOTE_TYPES
};
inline bool IsNoteOfType( int iNoteIndex, NoteType t )
{
switch( t )
{
case NOTE_4TH: return iNoteIndex % (ELEMENTS_PER_MEASURE/4) == 0;
case NOTE_8TH: return iNoteIndex % (ELEMENTS_PER_MEASURE/8) == 0;
case NOTE_12TH: return iNoteIndex % (ELEMENTS_PER_MEASURE/12) == 0;
case NOTE_16TH: return iNoteIndex % (ELEMENTS_PER_MEASURE/16) == 0;
default: ASSERT( false ); return false;
}
};
class NoteData
{
public:
NoteData();
int m_iNumTracks;
TapNote m_TapNotes[MAX_NOTE_TRACKS][MAX_TAP_NOTE_ELEMENTS];
HoldNote m_HoldNotes[MAX_HOLD_NOTE_ELEMENTS];
int m_iNumHoldNotes;
void ClearRange( NoteIndex iNoteIndexBegin, NoteIndex iNoteIndexEnd );
void ClearAll() { ClearRange( 0, MAX_TAP_NOTE_ELEMENTS ); };
void CopyRange( NoteData* pFrom, NoteIndex iNoteIndexBegin, NoteIndex iNoteIndexEnd );
void CopyAll( NoteData* pFrom ) { m_iNumTracks = pFrom->m_iNumTracks; CopyRange( pFrom, 0, MAX_TAP_NOTE_ELEMENTS ); };
inline bool IsRowEmpty( NoteIndex index )
{
for( int t=0; t<m_iNumTracks; t++ )
{
if( m_TapNotes[t][index] != '0' )
return false;
}
return true;
}
// used in edit/record
void AddHoldNote( HoldNote newNote ); // add note hold note merging overlapping HoldNotes and destroying TapNotes underneath
void RemoveHoldNote( int index );
// used for saving
void GetMeasureStrings( CStringArray &arrayMeasureStrings ); // for saving to a .notes file
// used for loading
void SetFromMeasureStrings( CStringArray &arrayMeasureStrings ); // for loading from a .notes file
void SetFromDWIInfo(); // for loading from a .dwi file
void SetFromBMSInfo(); // for loading from a .bms file
// statistics
float GetLastBeat(); // return the beat number of the last beat in the song
int GetNumTapNotes();
int GetNumHoldNotes();
// Transformations
void LoadTransformed( NoteData* pOriginal, int iNewNumTracks, TrackNumber iNewToOriginalTrack[] );
void CropToLeftSide();
void CropToRightSide();
void RemoveHoldNotes();
void Turn( PlayerOptions::TurnType tt );
void MakeLittle();
void SnapToNearestNoteType( NoteType nt1, NoteType nt2, float fBeginBeat, float fEndBeat );
// Convert between HoldNote representation and '2' and '3' markers in TapNotes
void Convert2sAnd3sToHoldNotes();
void ConvertHoldNotesTo2sAnd3s();
};
+327
View File
@@ -0,0 +1,327 @@
#include "stdafx.h"
/*
-----------------------------------------------------------------------------
Class: NoteField
Desc: See header.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "NoteField.h"
#include "RageUtil.h"
#include "ScreenDimensions.h"
#include "ThemeManager.h"
#include "ArrowEffects.h"
#include "PrefsManager.h"
#include "GameManager.h"
const float BEATS_BETWEEN_HOLD_BITS = 0.2f;
const float INDICIES_BETWEEN_HOLD_BITS = BEATS_BETWEEN_HOLD_BITS * ELEMENTS_PER_BEAT;
NoteField::NoteField()
{
m_rectMeasureBar.TurnShadowOff();
m_textMeasureNumber.Load( THEME->GetPathTo(FONT_NORMAL) );
m_textMeasureNumber.SetZoom( 1.0f );
m_rectMarkerBar.TurnShadowOff();
m_rectMarkerBar.SetEffectGlowing();
m_Mode = MODE_DANCING;
m_fBeginMarker = m_fEndMarker = -1;
}
void NoteField::Load( NoteData* pNoteData, PlayerOptions po, float fNumBeatsToDrawBehind, float fNumBeatsToDrawAhead, NoteFieldMode mode )
{
m_PlayerOptions = po;
m_fNumBeatsToDrawBehind = fNumBeatsToDrawBehind;
m_fNumBeatsToDrawAhead = fNumBeatsToDrawAhead;
m_Mode = mode;
this->CopyAll( pNoteData );
// init arrow rotations and X positions
for( int c=0; c<m_iNumTracks; c++ )
{
m_ColorArrow[c].m_sprColorPart.Load( GAME->GetPathToGraphic( PLAYER_1, c, GRAPHIC_NOTE_COLOR_PART) );
m_ColorArrow[c].m_sprGrayPart.Load( GAME->GetPathToGraphic( PLAYER_1, c, GRAPHIC_NOTE_GRAY_PART) );
float fColOffsetFromCenter = c - (m_iNumTracks-1)/2.0f;
m_ColorArrow[c].SetX( fColOffsetFromCenter*ARROW_SIZE );
}
ASSERT( m_iNumTracks == GAME->GetCurrentStyleDef()->GetColsPerPlayer() );
}
void NoteField::Update( float fDeltaTime, float fSongBeat )
{
m_fSongBeat = fSongBeat;
m_rectMarkerBar.Update( fDeltaTime );
}
void NoteField::DrawTapNote( const int iCol, const float fIndex )
{
const float fYOffset = ArrowGetYOffset( m_PlayerOptions, fIndex, m_fSongBeat );
const float fYPos = ArrowGetYPos( m_PlayerOptions, fYOffset );
const float fRotation = ArrowGetRotation( m_PlayerOptions, iCol, fYOffset );
const float fXPos = ArrowGetXPos( m_PlayerOptions, iCol, fYOffset, m_fSongBeat );
const float fAlpha = ArrowGetAlpha( m_PlayerOptions, fYPos );
m_ColorArrow[iCol].SetXY( fXPos, fYPos );
m_ColorArrow[iCol].SetRotation( fRotation );
m_ColorArrow[iCol].SetColorPartFromIndexAndBeat( (int)fIndex, m_fSongBeat, m_PlayerOptions.m_ColorType );
m_ColorArrow[iCol].SetGrayPartFromIndexAndBeat( (int)fIndex, m_fSongBeat );
m_ColorArrow[iCol].SetAlpha( fAlpha );
m_ColorArrow[iCol].Draw();
}
void NoteField::DrawTapNote( const int iCol, const float fIndex, const D3DXCOLOR color )
{
const float fYOffset = ArrowGetYOffset( m_PlayerOptions, fIndex, m_fSongBeat );
const float fYPos = ArrowGetYPos( m_PlayerOptions, fYOffset );
const float fRotation = ArrowGetRotation( m_PlayerOptions, iCol, fYOffset );
const float fXPos = ArrowGetXPos( m_PlayerOptions, iCol, fYOffset, m_fSongBeat );
const float fAlpha = ArrowGetAlpha( m_PlayerOptions, fYPos );
m_ColorArrow[iCol].SetXY( fXPos, fYPos );
m_ColorArrow[iCol].SetRotation( fRotation );
m_ColorArrow[iCol].SetDiffuseColor( color );
m_ColorArrow[iCol].SetGrayPartFromIndexAndBeat( (int)fIndex, m_fSongBeat );
m_ColorArrow[iCol].SetAlpha( fAlpha );
m_ColorArrow[iCol].Draw();
}
void NoteField::DrawHoldNoteColorPart( const int iCol, const float fIndex, const HoldNote &hn, const float fHoldNoteLife )
{
const float fYOffset = ArrowGetYOffset( m_PlayerOptions, fIndex, m_fSongBeat );
const float fYPos = ArrowGetYPos( m_PlayerOptions, fYOffset );
const float fRotation = ArrowGetRotation( m_PlayerOptions, iCol, fYOffset );
const float fXPos = ArrowGetXPos( m_PlayerOptions, iCol, fYOffset, m_fSongBeat );
const float fAlpha = ArrowGetAlpha( m_PlayerOptions, fYPos );
D3DXCOLOR color( (fIndex-hn.m_iStartIndex)/(hn.m_iEndIndex-hn.m_iStartIndex), 1, 0, 1 ); // color shifts from green to yellow
color *= 1 - (1-fHoldNoteLife) / 1.2f;
color.a = 1;
m_ColorArrow[iCol].SetXY( fXPos, fYPos );
m_ColorArrow[iCol].SetRotation( fRotation );
m_ColorArrow[iCol].SetDiffuseColor( color );
m_ColorArrow[iCol].SetAlpha( fAlpha );
m_ColorArrow[iCol].DrawColorPart();
}
void NoteField::DrawHoldNoteGrayPart( const int iCol, const float fIndex, const HoldNote &hn, const float fHoldNoteLife )
{
const float fYOffset = ArrowGetYOffset( m_PlayerOptions, fIndex, m_fSongBeat );
const float fYPos = ArrowGetYPos( m_PlayerOptions, fYOffset );
const float fRotation = ArrowGetRotation( m_PlayerOptions, iCol, fYOffset );
const float fXPos = ArrowGetXPos( m_PlayerOptions, iCol, fYOffset, m_fSongBeat );
const float fAlpha = ArrowGetAlpha( m_PlayerOptions, fYPos );
m_ColorArrow[iCol].SetXY( fXPos, fYPos );
m_ColorArrow[iCol].SetRotation( fRotation );
m_ColorArrow[iCol].SetAlpha( fAlpha );
m_ColorArrow[iCol].DrawGrayPart();
}
void NoteField::DrawMeasureBar( const int iIndex, const int iMeasureNo )
{
const float fYOffset = ArrowGetYOffset( m_PlayerOptions, (float)iIndex, m_fSongBeat );
const float fYPos = ArrowGetYPos( m_PlayerOptions, fYOffset );
m_rectMeasureBar.SetXY( 0, fYPos );
m_rectMeasureBar.SetWidth( (float)(m_iNumTracks+1) * ARROW_SIZE );
m_rectMeasureBar.SetHeight( 20 );
m_rectMeasureBar.SetDiffuseColor( D3DXCOLOR(0,0,0,0.5f) );
m_rectMeasureBar.Draw();
m_textMeasureNumber.SetText( ssprintf("%d", iMeasureNo) );
m_textMeasureNumber.SetXY( -m_rectMeasureBar.GetZoomedWidth()/2 + 10, fYPos );
m_textMeasureNumber.Draw();
}
void NoteField::DrawMarkerBar( const int iIndex )
{
const float fYOffset = ArrowGetYOffset( m_PlayerOptions, (float)iIndex, m_fSongBeat );
const float fYPos = ArrowGetYPos( m_PlayerOptions, fYOffset );
m_rectMarkerBar.SetXY( 0, fYPos );
m_rectMarkerBar.SetWidth( (float)(m_iNumTracks+1) * ARROW_SIZE );
m_rectMarkerBar.SetHeight( 20 );
m_rectMarkerBar.SetDiffuseColor( D3DXCOLOR(0,0,0,0.5f) );
m_rectMarkerBar.Draw();
}
void NoteField::RenderPrimitives()
{
//HELPER.Log( "NoteField::RenderPrimitives()" );
if( m_fSongBeat < 0 )
m_fSongBeat = 0;
int iBaseFrameNo = (int)(m_fSongBeat*2.5) % NUM_FRAMES_IN_COLOR_ARROW_SPRITE; // 2.5 is a "fudge number" :-) This should be based on BPM
int iIndexFirstArrowToDraw = BeatToNoteIndex( m_fSongBeat - m_fNumBeatsToDrawBehind ); // 2 beats earlier
if( iIndexFirstArrowToDraw < 0 ) iIndexFirstArrowToDraw = 0;
int iIndexLastArrowToDraw = BeatToNoteIndex( m_fSongBeat + m_fNumBeatsToDrawAhead ); // 7 beats later
//HELPER.Log( "Drawing elements %d through %d", iIndexFirstArrowToDraw, iIndexLastArrowToDraw );
//
// Draw measure bars
//
if( m_Mode == MODE_EDITING )
{
for( int i=iIndexFirstArrowToDraw; i<=iIndexLastArrowToDraw; i++ )
{
if( i % ELEMENTS_PER_MEASURE == 0 )
DrawMeasureBar( i, i / ELEMENTS_PER_MEASURE );
}
}
//
// Draw marker bars
//
if( m_Mode == MODE_EDITING )
{
if( m_fBeginMarker != -1 )
{
DrawMarkerBar( BeatToNoteIndex(m_fBeginMarker) );
}
if( m_fEndMarker != -1 )
{
DrawMarkerBar( BeatToNoteIndex(m_fEndMarker) );
}
}
//
// Draw all TapNotes
//
for( int i=iIndexFirstArrowToDraw; i<=iIndexLastArrowToDraw; i++ ) // for each row
{
if( !IsRowEmpty(i) )
{
//HELPER.Log( "iYPos: %d, iFrameNo: %d, m_OriginalStep[i]: %d", iYPos, iFrameNo, m_OriginalStep[i] );
// See if there is a hold step that begins on this beat. Terribly inefficient!
bool bHoldNoteOnThisBeat = false;
for( int j=0; j<m_iNumHoldNotes; j++ )
{
if( m_HoldNotes[j].m_iStartIndex == i )
{
bHoldNoteOnThisBeat = true;
break;
}
}
for( int c=0; c<m_iNumTracks; c++ ) // for each arrow column
{
if( m_TapNotes[c][i] != '0' ) // this column is still unstepped on?
{
if( bHoldNoteOnThisBeat )
DrawTapNote( c, (float)i, D3DXCOLOR(0,1,0,1) );
else
DrawTapNote( c, (float)i );
}
}
} // end if there is a step
} // end foreach arrow to draw
//
// Draw all HoldNotes
//
for( i=0; i<m_iNumHoldNotes; i++ )
{
HoldNote &hn = m_HoldNotes[i];
// If no part of this HoldNote is on the screen, skip it
if( !( iIndexFirstArrowToDraw <= hn.m_iEndIndex && hn.m_iEndIndex <= iIndexLastArrowToDraw ||
iIndexFirstArrowToDraw <= hn.m_iStartIndex && hn.m_iStartIndex <= iIndexLastArrowToDraw ||
hn.m_iStartIndex < iIndexFirstArrowToDraw && hn.m_iEndIndex > iIndexLastArrowToDraw ) )
{
continue;
}
int iCol = hn.m_iTrack;
float fHoldNoteLife = m_HoldNoteLife[i];
bool bActive = NoteIndexToBeat(hn.m_iStartIndex) > m_fSongBeat && m_fSongBeat < NoteIndexToBeat(hn.m_iEndIndex);
if( bActive && m_Mode == MODE_DANCING )
m_ColorArrow[iCol].SetGrayPartFull();
else
m_ColorArrow[iCol].SetGrayPartClear();
// draw the gray parts
for( float j=(float)hn.m_iStartIndex;
j<=hn.m_iEndIndex;
j+=INDICIES_BETWEEN_HOLD_BITS/m_PlayerOptions.m_fArrowScrollSpeed ) // for each arrow in the run
{
// check if this arrow is off the the screen
if( j < iIndexFirstArrowToDraw || iIndexLastArrowToDraw < j)
continue; // skip this arrow
if( fHoldNoteLife > 0 && m_Mode == MODE_DANCING && NoteIndexToBeat(j) < m_fSongBeat )
continue; // don't draw
DrawHoldNoteGrayPart( iCol, j, hn, fHoldNoteLife );
}
// draw the color parts
for( j=(float)hn.m_iStartIndex;
j<=hn.m_iEndIndex;
j+=INDICIES_BETWEEN_HOLD_BITS/m_PlayerOptions.m_fArrowScrollSpeed ) // for each arrow in the run
{
// check if this arrow is off the the screen
if( j < iIndexFirstArrowToDraw || iIndexLastArrowToDraw < j )
continue; // skip this arrow
if( fHoldNoteLife > 0 && m_Mode == MODE_DANCING && NoteIndexToBeat(j) < m_fSongBeat )
continue; // don't draw
DrawHoldNoteColorPart( iCol, j, hn, fHoldNoteLife );
}
// draw the first arrow on top of the others
j = (float)hn.m_iStartIndex;
if( fHoldNoteLife > 0 && m_Mode == MODE_DANCING && NoteIndexToBeat(j) < m_fSongBeat )
{
; // don't draw
}
else
{
DrawHoldNoteGrayPart( iCol, j, hn, fHoldNoteLife );
DrawHoldNoteColorPart( iCol, j, hn, fHoldNoteLife );
}
}
}
void NoteField::RemoveTapNoteRow( int iIndex )
{
for( int c=0; c<m_iNumTracks; c++ )
m_TapNotes[c][iIndex] = '0';
}
void NoteField::SetHoldNoteLife( int iIndex, float fLife )
{
m_HoldNoteLife[iIndex] = fLife;
}
+78
View File
@@ -0,0 +1,78 @@
/*
-----------------------------------------------------------------------------
Class: NoteField
Desc: A stream of ColorArrows that scrolls past Y==0.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#ifndef _NoteField_H_
#define _NoteField_H_
#include "Sprite.h"
#include "ActorFrame.h"
#include "Song.h"
#include "BitmapText.h"
#include "ThemeManager.h"
#include "StyleDef.h"
#include "ColorArrow.h"
#include "BitmapText.h"
#include "RectangleActor.h"
#include "ArrowEffects.h"
class NoteField : public NoteData, public ActorFrame
{
public:
NoteField();
virtual void Update( float fDeltaTime, float fSongBeat );
virtual void RenderPrimitives();
enum NoteFieldMode {
MODE_DANCING,
MODE_EDITING,
};
void Load( NoteData* pNoteData, PlayerOptions po, float fNumArrowsToDrawBehind, float fNumArrowsToDrawAhead, NoteFieldMode mode );
void RemoveTapNoteRow( int iIndex );
void SetHoldNoteLife( int iIndex, float fLife );
float m_HoldNoteLife[MAX_HOLD_NOTE_ELEMENTS]; // 1.0 = full life, 0 = dead
float m_fBeginMarker, m_fEndMarker; // only used with MODE_EDIT
protected:
inline void DrawTapNote( const int iCol, const float fIndex );
inline void DrawTapNote( const int iCol, const float fIndex, const D3DXCOLOR color );
inline void DrawHoldNoteColorPart( const int iCol, const float fIndex, const HoldNote &hs, const float fHoldNoteLife );
inline void DrawHoldNoteGrayPart( const int iCol, const float fIndex, const HoldNote &hs, const float fHoldNoteLife );
inline void DrawMeasureBar( const int iIndex, const int iMeasureNo );
inline void DrawMarkerBar( const int iIndex );
PlayerOptions m_PlayerOptions;
float m_fNumBeatsToDrawBehind;
float m_fNumBeatsToDrawAhead;
float m_fSongBeat;
NoteFieldMode m_Mode;
// color arrows
ColorArrow m_ColorArrow[MAX_NOTE_TRACKS];
// used in MODE_EDIT
RectangleActor m_rectMeasureBar;
BitmapText m_textMeasureNumber;
RectangleActor m_rectMarkerBar;
};
#endif
+93 -86
View File
@@ -1,11 +1,11 @@
#include "stdafx.h"
/*
-----------------------------------------------------------------------------
Class: Pattern
Class: NoteMetadata
Desc: See header.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -16,6 +16,8 @@
#include "ThemeManager.h"
#include "GameTypes.h"
#include "ArrowEffects.h"
#include "GameManager.h"
#include "InputMapper.h"
const float JUDGEMENT_Y = CENTER_Y;
@@ -37,18 +39,21 @@ Player::Player()
// init step elements
for( int i=0; i<MAX_TAP_NOTE_ELEMENTS; i++ )
{
m_TapNotesOriginal[i] = NOTE_NONE;
m_TapNotesRemaining[i] = NOTE_NONE;
for( int c=0; c<MAX_NOTE_TRACKS; c++ )
{
m_TapNotesOriginal[c][i] = '0';
m_TapNotes[c][i] = '0';
}
m_TapNoteScores[i] = TNS_NONE;
}
m_iNumHoldNotes = 0;
this->AddActor( &m_GrayArrows );
this->AddActor( &m_ColorArrowField );
this->AddActor( &m_GhostArrows );
this->AddActor( &m_GrayArrowRow );
this->AddActor( &m_NoteField );
this->AddActor( &m_GhostArrowRow );
this->AddActor( &m_Judgement );
for( int c=0; c<MAX_NUM_COLUMNS; c++ )
for( int c=0; c<MAX_NOTE_TRACKS; c++ )
this->AddActor( &m_HoldJudgement[c] );
this->AddActor( &m_Combo );
this->AddActor( &m_LifeMeter );
@@ -56,51 +61,38 @@ Player::Player()
}
void Player::Load( const StyleDef& StyleDef, PlayerNumber player_no, const Pattern& pattern, const PlayerOptions& po )
void Player::Load( PlayerNumber player_no, NoteData* pNoteData, const PlayerOptions& po )
{
//HELPER.Log( "Player::Load()", );
this->CopyAll( pNoteData );
m_Style = StyleDef;
m_PlayerNumber = player_no;
m_PlayerOptions = po;
Pattern pattern2 = pattern;
if( !po.m_bAllowFreezeArrows )
pattern2.RemoveHoldNotes();
this->RemoveHoldNotes();
pattern2.Turn( po.m_TurnType );
this->Turn( po.m_TurnType );
if( po.m_bLittle )
pattern2.MakeLittle();
this->MakeLittle();
m_ColorArrowField.Load( StyleDef, pattern2, po, 1.5f, 5.5f, ColorArrowField::MODE_DANCING );
m_GrayArrows.Load( po, StyleDef );
m_GhostArrows.Load( po, StyleDef );
m_NoteField.Load( (NoteData*)this, po, 1.5f, 5.5f, NoteField::MODE_DANCING );
// load step elements
for( int i=0; i<MAX_TAP_NOTE_ELEMENTS; i++ )
{
m_TapNotesOriginal[i] = pattern2.m_TapNotes[i];
m_TapNotesRemaining[i] = pattern2.m_TapNotes[i];
}
for( i=0; i<pattern2.m_iNumHoldNotes; i++ )
{
m_HoldNotes[i] = pattern2.m_HoldNotes[i];
}
m_iNumHoldNotes = pattern2.m_iNumHoldNotes;
m_GrayArrowRow.Load( po );
m_GhostArrowRow.Load( po );
m_Combo.SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - COMBO_Y : COMBO_Y );
m_LifeMeter.SetY( LIFEMETER_Y );
m_Judgement.SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - JUDGEMENT_Y : JUDGEMENT_Y );
for( int c=0; c<MAX_NUM_COLUMNS; c++ )
for( int c=0; c<MAX_NOTE_TRACKS; c++ )
m_HoldJudgement[c].SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - HOLD_JUDGEMENT_Y : HOLD_JUDGEMENT_Y );
m_Score.SetY( SCORE_Y );
m_ColorArrowField.SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - ARROWS_Y : ARROWS_Y );
m_GrayArrows.SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - ARROWS_Y : ARROWS_Y );
m_GhostArrows.SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - ARROWS_Y : ARROWS_Y );
m_NoteField.SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - ARROWS_Y : ARROWS_Y );
m_GrayArrowRow.SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - ARROWS_Y : ARROWS_Y );
m_GhostArrowRow.SetY( po.m_bReverseScroll ? SCREEN_HEIGHT - ARROWS_Y : ARROWS_Y );
// Load options into Life Meter
m_LifeMeter.SetPlayerOptions(po);
@@ -114,7 +106,7 @@ void Player::Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference
//
// Check for TapNote misses
//
int iNumMisses = UpdateStepsMissedOlderThan( m_fSongBeat-fMaxBeatDifference );
int iNumMisses = UpdateTapNotesMissedOlderThan( m_fSongBeat-fMaxBeatDifference );
if( iNumMisses > 0 )
{
m_Judgement.SetJudgement( TNS_MISS );
@@ -138,32 +130,33 @@ void Player::Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference
float fStartBeat = NoteIndexToBeat( (float)hn.m_iStartIndex );
float fEndBeat = NoteIndexToBeat( (float)hn.m_iEndIndex );
const int iCol = hn.m_iTrack;
const StyleInput StyleI( m_PlayerNumber, hn.m_iTrack );
const GameInput GameI = GAME->GetCurrentStyleDef()->StyleInputToGameInput( StyleI );
// update the life
if( fStartBeat < m_fSongBeat && m_fSongBeat < fEndBeat ) // if the song beat is in the range of this hold
{
PlayerInput PlayerI( m_PlayerNumber, hn.m_TapNote );
bool bIsHoldingButton = PREFS->IsButtonDown( PlayerI );
const bool bIsHoldingButton = MAPPER->IsButtonDown( GameI );
if( bIsHoldingButton )
{
hns.m_fLife += fDeltaTime/HOLD_ARROW_NG_TIME;
hns.m_fLife = min( hns.m_fLife, 1 ); // clamp
int iCol = m_Style.TapNoteToColumnNumber( hn.m_TapNote );
m_GhostArrows.HoldNote( iCol ); // update the "electric ghost" effect
m_GhostArrowRow.HoldNote( iCol ); // update the "electric ghost" effect
}
else // !bIsHoldingButton
{
hns.m_fLife -= fDeltaTime/HOLD_ARROW_NG_TIME;
hns.m_fLife = max( hns.m_fLife, 0 ); // clamp
}
m_ColorArrowField.SetHoldNoteLife( i, hns.m_fLife ); // update the ColorArrowField display
m_NoteField.SetHoldNoteLife( i, hns.m_fLife ); // update the NoteField display
}
// check for NG
if( hns.m_fLife == 0 ) // the player has not pressed the button for a long time!
{
hns.m_Result = HNR_NG;
int iCol = m_Style.TapNoteToColumnNumber( hn.m_TapNote );
m_HoldJudgement[iCol].SetHoldJudgement( HNR_NG );
}
@@ -173,9 +166,8 @@ void Player::Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference
// this implies that hns.m_fLife > 0, or else we would have marked it NG above
hns.m_fLife = 1;
hns.m_Result = HNR_OK;
int iCol = m_Style.TapNoteToColumnNumber( hn.m_TapNote );
m_HoldJudgement[iCol].SetHoldJudgement( HNR_OK );
m_ColorArrowField.SetHoldNoteLife( i, hns.m_fLife ); // update the ColorArrowField display
m_NoteField.SetHoldNoteLife( i, hns.m_fLife ); // update the NoteField display
}
}
@@ -185,9 +177,9 @@ void Player::Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference
m_LifeMeter.SetBeat( fSongBeat );
m_GrayArrows.Update( fDeltaTime, fSongBeat );
m_ColorArrowField.Update( fDeltaTime, fSongBeat );
m_GhostArrows.Update( fDeltaTime, fSongBeat );
m_GrayArrowRow.Update( fDeltaTime, fSongBeat );
m_NoteField.Update( fDeltaTime, fSongBeat );
m_GhostArrowRow.Update( fDeltaTime, fSongBeat );
m_fSongBeat = fSongBeat; // save song beat
@@ -221,9 +213,9 @@ void Player::RenderPrimitives()
SCREEN->GetDevice()->SetTransform( D3DTS_PROJECTION, &matNewProj );
}
m_GrayArrows.Draw();
m_ColorArrowField.Draw();
m_GhostArrows.Draw();
m_GrayArrowRow.Draw();
m_NoteField.Draw();
m_GhostArrowRow.Draw();
if( m_PlayerOptions.m_EffectType == PlayerOptions::EFFECT_SPACE )
{
@@ -238,7 +230,7 @@ void Player::RenderPrimitives()
m_Judgement.Draw();
for( int c=0; c<m_Style.m_iNumColumns; c++ )
for( int c=0; c<m_iNumTracks; c++ )
m_HoldJudgement[c].Draw();
m_Combo.Draw();
m_LifeMeter.Draw();
@@ -249,8 +241,11 @@ void Player::RenderPrimitives()
bool Player::IsThereANoteAtIndex( int iIndex )
{
if( m_TapNotesOriginal[iIndex] != NOTE_NONE )
return true;
for( int t=0; t<m_iNumTracks; t++ )
{
if( m_TapNotesOriginal[t][iIndex] != '0' )
return true;
}
for( int i=0; i<m_iNumHoldNotes; i++ ) // for each HoldNote
{
@@ -264,17 +259,15 @@ bool Player::IsThereANoteAtIndex( int iIndex )
void Player::HandlePlayerStep( float fSongBeat, TapNote player_step, float fMaxBeatDiff )
void Player::HandlePlayerStep( float fSongBeat, NoteColumn col, float fMaxBeatDiff )
{
//HELPER.Log( "Player::HandlePlayerStep()" );
int iColumnNum = m_Style.TapNoteToColumnNumber( player_step );
if( iColumnNum == -1 ) // if this TapNote is not used in the current StyleDef
return; // ignore the step
ASSERT( col >= 0 && col <= m_iNumTracks );
m_GrayArrows.Step( iColumnNum );
m_GrayArrowRow.Step( col );
CheckForCompleteStep( fSongBeat, player_step, fMaxBeatDiff );
CheckForCompleteRow( fSongBeat, col, fMaxBeatDiff );
//
// check if we stepped on the TapNote part of a HoldNote
@@ -290,7 +283,7 @@ void Player::HandlePlayerStep( float fSongBeat, TapNote player_step, float fMaxB
if( hns.m_TapNoteScore != TNS_NONE ) // the TapNote already has a score
continue; // no need to continue;
if( player_step == m_HoldNotes[i].m_TapNote ) // the player's step is the same as this HoldNote
if( col == m_HoldNotes[i].m_iTrack ) // the player's step is the same as this HoldNote
{
float fBeatDifference = fabsf( NoteIndexToBeat(hn.m_iStartIndex) - fSongBeat );
@@ -315,8 +308,7 @@ void Player::HandlePlayerStep( float fSongBeat, TapNote player_step, float fMaxB
m_LifeMeter.ChangeLife( score );
// show the gray arrow ghost
int iColNum = m_Style.TapNoteToColumnNumber( player_step );
m_GhostArrows.TapNote( iColNum, score, m_Combo.GetCurrentCombo() > 100 );
m_GhostArrowRow.TapNote( col, score, m_Combo.GetCurrentCombo() > 100 );
// update the combo display
switch( score )
@@ -339,9 +331,9 @@ void Player::HandlePlayerStep( float fSongBeat, TapNote player_step, float fMaxB
}
void Player::CheckForCompleteStep( float fSongBeat, TapNote player_step, float fMaxBeatDiff )
void Player::CheckForCompleteRow( float fSongBeat, NoteColumn col, float fMaxBeatDiff )
{
//HELPER.Log( "Player::CheckForCompleteStep()" );
//HELPER.Log( "Player::CheckForCompleteRow()" );
// look for the closest matching step
int iIndexStartLookingAt = BeatToNoteIndex( fSongBeat );
@@ -362,32 +354,44 @@ void Player::CheckForCompleteStep( float fSongBeat, TapNote player_step, float f
////////////////////////////
// check the step to the left of iIndexStartLookingAt
////////////////////////////
//HELPER.Log( "Checking Pattern[%d]", iCurrentIndexEarlier );
if( m_TapNotesRemaining[iCurrentIndexEarlier] & player_step ) // these Pattern overlap
//HELPER.Log( "Checking NoteMetadata[%d]", iCurrentIndexEarlier );
if( m_TapNotes[col][iCurrentIndexEarlier] != '0' ) // these NoteMetadata overlap
{
m_TapNotesRemaining[iCurrentIndexEarlier] &= ~player_step; // subtract player_step
if( m_TapNotesRemaining[iCurrentIndexEarlier] == 0 ) { // did this complete the step?
OnCompleteStep( fSongBeat, player_step, fMaxBeatDiff, iCurrentIndexEarlier );
return;
m_TapNotes[col][iCurrentIndexEarlier] = '0'; // mark hit
bool bRowDestroyed = true;
for( int t=0; t<m_iNumTracks; t++ ) // did this complete the elminiation of the row?
{
if( m_TapNotes[col][iCurrentIndexEarlier] != '0' )
bRowDestroyed = false;
}
if( bRowDestroyed )
OnRowDestroyed( fSongBeat, col, fMaxBeatDiff, iCurrentIndexEarlier );
return;
}
////////////////////////////
// check the step to the right of iIndexStartLookingAt
////////////////////////////
//HELPER.Log( "Checking Pattern[%d]", iCurrentIndexLater );
if( m_TapNotesRemaining[iCurrentIndexLater] & player_step ) // these Pattern overlap
//HELPER.Log( "Checking NoteMetadata[%d]", iCurrentIndexLater );
if( m_TapNotes[col][iCurrentIndexLater] != '0' ) // these NoteMetadata overlap
{
m_TapNotesRemaining[iCurrentIndexLater] &= ~player_step; // subtract player_step
if( m_TapNotesRemaining[iCurrentIndexLater] == 0 ) { // did this complete the step?
OnCompleteStep( fSongBeat, player_step, fMaxBeatDiff, iCurrentIndexLater );
return;
m_TapNotes[col][iCurrentIndexLater] = '0'; // mark hit
bool bRowDestroyed = true;
for( int t=0; t<m_iNumTracks; t++ ) // did this complete the elminiation of the row?
{
if( m_TapNotes[col][iCurrentIndexLater] != '0' )
bRowDestroyed = false;
}
if( bRowDestroyed )
OnRowDestroyed( fSongBeat, col, fMaxBeatDiff, iCurrentIndexLater );
return;
}
}
}
void Player::OnCompleteStep( float fSongBeat, TapNote player_step, float fMaxBeatDiff, int iIndexThatWasSteppedOn )
void Player::OnRowDestroyed( float fSongBeat, NoteColumn col, float fMaxBeatDiff, int iIndexThatWasSteppedOn )
{
float fStepBeat = NoteIndexToBeat( (float)iIndexThatWasSteppedOn );
@@ -412,14 +416,14 @@ void Player::OnCompleteStep( float fSongBeat, TapNote player_step, float fMaxBea
m_LifeMeter.ChangeLife( score );
// remove this row from the ColorArrowField
m_ColorArrowField.RemoveTapNoteRow( iIndexThatWasSteppedOn );
// remove this row from the NoteField
m_NoteField.RemoveTapNoteRow( iIndexThatWasSteppedOn );
// check to see if this completes a row of notes
for( int c=0; c<m_Style.m_iNumColumns; c++ ) // for each column
// show ghost arrows
for( int c=0; c<m_iNumTracks; c++ ) // for each column
{
if( m_TapNotesOriginal[iIndexThatWasSteppedOn] & m_Style.m_ColumnToTapNote[c] ) // if this colum was part of the original step
m_GhostArrows.TapNote( c, score, m_Combo.GetCurrentCombo()>100 ); // show the ghost arrow for this column
if( m_TapNotesOriginal[c][iIndexThatWasSteppedOn] != '0' ) // if there is an original note note in this column
m_GhostArrowRow.TapNote( c, score, m_Combo.GetCurrentCombo()>100 ); // show the ghost arrow for this column
}
// update the combo display
@@ -481,22 +485,25 @@ ScoreSummary Player::GetScoreSummary()
}
int Player::UpdateStepsMissedOlderThan( float fMissIfOlderThanThisBeat )
int Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanThisBeat )
{
//HELPER.Log( "Pattern::UpdateStepsMissedOlderThan(%f)", fMissIfOlderThanThisBeat );
//HELPER.Log( "NoteMetadata::UpdateTapNotesMissedOlderThan(%f)", fMissIfOlderThanThisBeat );
int iMissIfOlderThanThisIndex = BeatToNoteIndex( fMissIfOlderThanThisBeat );
int iNumMissesFound = 0;
// Since this is being called frame, let's not check the whole array every time.
// Since this is being called every frame, let's not check the whole array every time.
// Instead, only check 10 elements back. Even 10 is overkill.
int iStartCheckingAt = max( 0, iMissIfOlderThanThisIndex-10 );
//HELPER.Log( "iStartCheckingAt: %d iMissIfOlderThanThisIndex: %d", iStartCheckingAt, iMissIfOlderThanThisIndex );
for( int i=iStartCheckingAt; i<iMissIfOlderThanThisIndex; i++ )
{
//HELPER.Log( "Checking for miss: %d: lefttostepon == %d, score == %d", i, m_LeftToStepOn[i], m_StepScore[i] );
if( m_TapNotesRemaining[i] != 0 && m_TapNoteScores[i] != TNS_MISS )
if( m_TapNoteScores[i] != TNS_NONE ) // this index already has a score
continue;
// look for any track at this index that still has data
if( !this->IsRowEmpty( i ) )
{
m_TapNoteScores[i] = TNS_MISS;
iNumMissesFound++;
+17 -20
View File
@@ -5,7 +5,7 @@
Desc: Object that accepts pad input, knocks down ColorArrows that were stepped on,
and keeps score for the player.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -13,7 +13,7 @@
#define _PLAYER_H_
#include "PrefsManager.h" // for ScoreSummary
#include "Pattern.h"
#include "NoteMetadata.h"
#include "Sprite.h"
#include "BitmapText.h"
@@ -29,14 +29,14 @@
#include "Judgement.h"
#include "HoldJudgement.h"
#include "Combo.h"
#include "ColorArrowField.h"
#include "GrayArrows.h"
#include "GhostArrows.h"
#include "NoteField.h"
#include "GrayArrowRow.h"
#include "GhostArrowRow.h"
class Player : public ActorFrame
class Player : public NoteData, public ActorFrame
{
public:
Player();
@@ -44,10 +44,10 @@ public:
void Update( float fDeltaTime, float fSongBeat, float fMaxBeatDifference );
void RenderPrimitives();
void Load( const StyleDef& StyleDef, PlayerNumber player_no, const Pattern& pattern, const PlayerOptions& po );
void Load( PlayerNumber player_no, NoteData* pNoteData, const PlayerOptions& po );
void CrossedIndex( int iIndex );
void HandlePlayerStep( float fSongBeat, TapNote step, float fMaxBeatDiff );
int UpdateStepsMissedOlderThan( float fMissIfOlderThanThisBeat );
void HandlePlayerStep( float fSongBeat, NoteColumn col, float fMaxBeatDiff );
int UpdateTapNotesMissedOlderThan( float fMissIfOlderThanThisBeat );
ScoreSummary GetScoreSummary();
@@ -55,28 +55,25 @@ public:
bool IsThereANoteAtIndex( int iIndex );
protected:
void CheckForCompleteStep( float fSongBeat, TapNote step, float fMaxBeatDiff );
void OnCompleteStep( float fSongBeat, TapNote step, float fMaxBeatDiff, int iStepIndex );
void CheckForCompleteRow( float fSongBeat, NoteColumn col, float fMaxBeatDiff );
void OnRowDestroyed( float fSongBeat, NoteColumn col, float fMaxBeatDiff, int iStepIndex );
float m_fSongBeat;
StyleDef m_Style;
PlayerNumber m_PlayerNumber;
PlayerOptions m_PlayerOptions;
TapNote m_TapNotesOriginal[MAX_TAP_NOTE_ELEMENTS]; // the original Pattern that were loaded into player
TapNote m_TapNotesRemaining[MAX_TAP_NOTE_ELEMENTS]; // mask off the bits as the player Pattern
// maintain this extra data in addition to the NoteData
TapNote m_TapNotesOriginal[MAX_NOTE_TRACKS][MAX_TAP_NOTE_ELEMENTS]; // the original NoteMetadata that were loaded into player
TapNoteScore m_TapNoteScores[MAX_TAP_NOTE_ELEMENTS];
HoldNote m_HoldNotes[MAX_HOLD_NOTE_ELEMENTS];
HoldNoteScore m_HoldNoteScores[MAX_HOLD_NOTE_ELEMENTS];
int m_iNumHoldNotes;
GrayArrows m_GrayArrows;
ColorArrowField m_ColorArrowField;
GhostArrows m_GhostArrows;
GrayArrowRow m_GrayArrowRow;
NoteField m_NoteField;
GhostArrowRow m_GhostArrowRow;
Judgement m_Judgement;
HoldJudgement m_HoldJudgement[MAX_NUM_COLUMNS];
HoldJudgement m_HoldJudgement[MAX_NOTE_TRACKS];
Combo m_Combo;
LifeMeterPills m_LifeMeter;
ScoreDisplayRollingWithFrame m_Score;
+25 -310
View File
@@ -5,7 +5,7 @@
Desc: See Header.
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
@@ -25,8 +25,10 @@ PrefsManager::PrefsManager()
m_SongSortOrder = SORT_GROUP;
m_iCurrentStage = 1;
for( int p=0; p<NUM_PLAYERS; p++ )
m_PreferredDifficultyClass[p] = CLASS_EASY;
ReadPrefsFromDisk();
SetHardCodedButtons();
}
@@ -43,36 +45,12 @@ void PrefsManager::ReadPrefsFromDisk()
ini.SetPath( "StepMania.ini" );
if( !ini.ReadFile() ) {
return; // load nothing
//HELPER.FatalError( "could not read config file" );
//FatalError( "could not read config file" );
}
CMapStringToString* pKey = ini.GetKeyPointer("Input");
CMapStringToString* pKey;
CString name_string, value_string;
if( pKey != NULL )
{
for( POSITION pos = pKey->GetStartPosition(); pos != NULL; )
{
pKey->GetNextAssoc( pos, name_string, value_string );
PadInput pi;
pi.fromString(name_string);
CStringArray sDeviceInputStrings;
split( value_string, ",", sDeviceInputStrings, false );
for( int i=0; i<sDeviceInputStrings.GetSize() && i<NUM_PAD_TO_DEVICE_SLOTS; i++ )
{
DeviceInput di;
di.fromString( sDeviceInputStrings[i] );
if( !di.IsBlank() )
SetInputMap( di, pi, i );
}
}
}
this->SetHardCodedButtons();
pKey = ini.GetKeyPointer( "GameOptions" );
if( pKey )
@@ -97,6 +75,15 @@ void PrefsManager::ReadPrefsFromDisk()
pKey->GetNextAssoc( pos, name_string, value_string );
if( name_string == "Windowed" ) m_GraphicOptions.m_bWindowed = ( value_string == "1" );
if( name_string == "Profile" )
{
if( value_string == "super low" ) m_GraphicOptions.m_Profile = PROFILE_SUPER_LOW;
else if( value_string == "low" ) m_GraphicOptions.m_Profile = PROFILE_LOW;
else if( value_string == "medium" ) m_GraphicOptions.m_Profile = PROFILE_MEDIUM;
else if( value_string == "high" ) m_GraphicOptions.m_Profile = PROFILE_HIGH;
else if( value_string == "custom" ) m_GraphicOptions.m_Profile = PROFILE_CUSTOM;
else m_GraphicOptions.m_Profile = PROFILE_MEDIUM;
}
if( name_string == "Resolution" ) m_GraphicOptions.m_iResolution = atoi( value_string );
if( name_string == "MaxTextureSize" ) m_GraphicOptions.m_iMaxTextureSize = atoi( value_string );
if( name_string == "DisplayColor" ) m_GraphicOptions.m_iDisplayColor = atoi( value_string );
@@ -117,24 +104,17 @@ void PrefsManager::SavePrefsToDisk()
// ini.ReadFile(); // don't read the file so that we overwrite everything there
// iterate over our input map and write all mappings to the ini file
for( int i=0; i<NUM_PADS; i++ )
{
for( int j=0; j<NUM_PAD_BUTTONS; j++ )
{
CString sNameString, sValueString;
PadInput pi( (PadNumber)i, (PadButton)j );
sNameString = pi.toString();
sValueString = ssprintf( "%s,%s,%s",
m_PItoDI[i][j][0].toString(), m_PItoDI[i][j][1].toString(), m_PItoDI[i][j][2].toString() );
ini.SetValue( "Input", sNameString, sValueString );
}
}
// save the GameOptions
ini.SetValue( "GraphicOptions", "Windowed", m_GraphicOptions.m_bWindowed ? "1":"0" );
switch( m_GraphicOptions.m_Profile )
{
case PROFILE_SUPER_LOW: ini.SetValue( "GraphicOptions", "Profile", "super low" ); break;
case PROFILE_LOW: ini.SetValue( "GraphicOptions", "Profile", "low" ); break;
case PROFILE_MEDIUM: ini.SetValue( "GraphicOptions", "Profile", "medium" ); break;
case PROFILE_HIGH: ini.SetValue( "GraphicOptions", "Profile", "high" ); break;
case PROFILE_CUSTOM: ini.SetValue( "GraphicOptions", "Profile", "custom" ); break;
default: ASSERT( false );
}
ini.SetValue( "GraphicOptions", "Resolution", ssprintf("%d", m_GraphicOptions.m_iResolution) );
ini.SetValue( "GraphicOptions", "MaxTextureSize", ssprintf("%d", m_GraphicOptions.m_iMaxTextureSize) );
ini.SetValue( "GraphicOptions", "DisplayColor", ssprintf("%d", m_GraphicOptions.m_iDisplayColor) );
@@ -156,269 +136,6 @@ void PrefsManager::SavePrefsToDisk()
}
///////////////////////////////////////
// Input mapping stuff
///////////////////////////////////////
void PrefsManager::SetInputMap( DeviceInput di, PadInput pi, int iSlotIndex, bool bOverrideHardCoded )
{
if( IsAHardCodedDeviceInput(di) && !bOverrideHardCoded )
return; // don't allow hard coded inputs to be overwritten
// remove the old input
ClearFromInputMap( di );
ClearFromInputMap( pi, iSlotIndex );
m_PItoDI[pi.pad_no][pi.button][iSlotIndex] = di;
UpdateTempDItoPI();
}
void PrefsManager::ClearFromInputMap( DeviceInput di )
{
// search for where this di maps to
for( int p=0; p<NUM_PADS; p++ )
{
for( int b=0; b<NUM_PAD_BUTTONS; b++ )
{
for( int s=0; s<NUM_PAD_TO_DEVICE_SLOTS; s++ )
{
if( m_PItoDI[p][b][s] == di )
m_PItoDI[p][b][s].MakeBlank();
}
}
}
UpdateTempDItoPI();
}
void PrefsManager::ClearFromInputMap( PadInput pi, int iSlotIndex )
{
if( pi.IsBlank() )
return;
m_PItoDI[pi.pad_no][pi.button][iSlotIndex].MakeBlank();
UpdateTempDItoPI();
}
void PrefsManager::UpdateTempDItoPI()
{
// clear out m_tempDItoPI
for( int d=0; d<NUM_INPUT_DEVICES; d++ )
{
for( int b=0; b<NUM_DEVICE_BUTTONS; b++ )
{
m_tempDItoPI[d][b].MakeBlank();
}
}
// repopulate m_tempDItoPI
for( int p=0; p<NUM_PADS; p++ )
{
for( int b=0; b<NUM_PAD_BUTTONS; b++ )
{
for( int s=0; s<NUM_PAD_TO_DEVICE_SLOTS; s++ )
{
PadInput PadI( (PadNumber)p, (PadButton)b );
DeviceInput DeviceI = m_PItoDI[p][b][s];
if( DeviceI.IsBlank() )
continue;
m_tempDItoPI[DeviceI.device][DeviceI.button] = PadI;
}
}
}
}
const PadInput g_HardCodedPadInputs[] = {
PadInput(PAD_1,BUTTON_LEFT),
PadInput(PAD_1,BUTTON_RIGHT),
PadInput(PAD_1,BUTTON_UP),
PadInput(PAD_1,BUTTON_DOWN),
PadInput(PAD_1,BUTTON_BACK),
PadInput(PAD_1,BUTTON_NEXT),
};
const int NUM_HARD_CODED_INPUTS = sizeof(g_HardCodedPadInputs) / sizeof(PadInput);
const DeviceInput g_HardCodedDeviceInputs[NUM_HARD_CODED_INPUTS] = {
DeviceInput(DEVICE_KEYBOARD,DIK_LEFT),
DeviceInput(DEVICE_KEYBOARD,DIK_RIGHT),
DeviceInput(DEVICE_KEYBOARD,DIK_UP),
DeviceInput(DEVICE_KEYBOARD,DIK_DOWN),
DeviceInput(DEVICE_KEYBOARD,DIK_ESCAPE),
DeviceInput(DEVICE_KEYBOARD,DIK_RETURN),
};
void PrefsManager::SetHardCodedButtons()
{
for( int i=0; i<NUM_HARD_CODED_INPUTS; i++ )
{
SetInputMap( g_HardCodedDeviceInputs[i], g_HardCodedPadInputs[i], NUM_PAD_TO_DEVICE_SLOTS-1, true ); // always go in the last slot
}
}
bool PrefsManager::IsAHardCodedDeviceInput( DeviceInput di )
{
for( int i=0; i<NUM_HARD_CODED_INPUTS; i++ )
{
if( di == g_HardCodedDeviceInputs[i] )
return true;
}
return false;
}
bool PrefsManager::DeviceToPad( DeviceInput di, PadInput& pi ) // return true if there is a mapping from device to pad
{
pi = m_tempDItoPI[di.device][di.button];
return pi.pad_no != PAD_NONE;
}
bool PrefsManager::PadToDevice( PadInput pi, int iSoltNum, DeviceInput& di ) // return true if there is a mapping from pad to device
{
di = m_PItoDI[pi.pad_no][pi.button][iSoltNum];
return di.device != DEVICE_NONE;
}
void PrefsManager::PadToPlayer( PadInput PadI, PlayerInput &PlayerI )
{
PlayerI.player_no = PLAYER_NONE;
PlayerI.note = NOTE_NONE;
switch( GAME->m_DanceStyle )
{
case STYLE_SINGLE:
case STYLE_SOLO:
if( PadI.pad_no == PAD_1 )
PlayerI.player_no = PLAYER_1;
else
PlayerI.player_no = PLAYER_NONE;
if ( PadI.button == BUTTON_LEFT ) PlayerI.note |= NOTE_PAD1_LEFT;
if ( PadI.button == BUTTON_UPLEFT ) PlayerI.note |= NOTE_PAD1_UPLEFT;
if ( PadI.button == BUTTON_DOWN ) PlayerI.note |= NOTE_PAD1_DOWN;
if ( PadI.button == BUTTON_UP ) PlayerI.note |= NOTE_PAD1_UP;
if ( PadI.button == BUTTON_UPRIGHT ) PlayerI.note |= NOTE_PAD1_UPRIGHT;
if ( PadI.button == BUTTON_RIGHT ) PlayerI.note |= NOTE_PAD1_RIGHT;
break;
case STYLE_VERSUS:
case STYLE_COUPLE:
if( PadI.pad_no == PAD_1 )
PlayerI.player_no = PLAYER_1;
else if( PadI.pad_no == PAD_2 )
PlayerI.player_no = PLAYER_2;
else
PlayerI.player_no = PLAYER_NONE;
if ( PadI.button == BUTTON_LEFT ) PlayerI.note |= NOTE_PAD1_LEFT;
if ( PadI.button == BUTTON_UPLEFT ) PlayerI.note |= NOTE_PAD1_UPLEFT;
if ( PadI.button == BUTTON_DOWN ) PlayerI.note |= NOTE_PAD1_DOWN;
if ( PadI.button == BUTTON_UP ) PlayerI.note |= NOTE_PAD1_UP;
if ( PadI.button == BUTTON_UPRIGHT ) PlayerI.note |= NOTE_PAD1_UPRIGHT;
if ( PadI.button == BUTTON_RIGHT ) PlayerI.note |= NOTE_PAD1_RIGHT;
break;
case STYLE_DOUBLE:
switch( PadI.pad_no )
{
case PAD_1:
PlayerI.player_no = PLAYER_1;
if ( PadI.button == BUTTON_LEFT ) PlayerI.note |= NOTE_PAD1_LEFT;
if ( PadI.button == BUTTON_DOWN ) PlayerI.note |= NOTE_PAD1_DOWN;
if ( PadI.button == BUTTON_UP ) PlayerI.note |= NOTE_PAD1_UP;
if ( PadI.button == BUTTON_RIGHT ) PlayerI.note |= NOTE_PAD1_RIGHT;
break;
case PAD_2:
PlayerI.player_no = PLAYER_1;
if ( PadI.button == BUTTON_LEFT ) PlayerI.note |= NOTE_PAD2_LEFT;
if ( PadI.button == BUTTON_DOWN ) PlayerI.note |= NOTE_PAD2_DOWN;
if ( PadI.button == BUTTON_UP ) PlayerI.note |= NOTE_PAD2_UP;
if ( PadI.button == BUTTON_RIGHT ) PlayerI.note |= NOTE_PAD2_RIGHT;
break;
case PAD_NONE:
PlayerI.player_no = PLAYER_NONE;
break;
}
break;
default:
ASSERT( false ); // invalid DanceStyle
}
}
void PrefsManager::PlayerToPad( PlayerInput PlayerI, PadInput &PadI )
{
PadI.pad_no = PAD_NONE;
PadI.button = BUTTON_NONE;
switch( GAME->m_DanceStyle )
{
case STYLE_SINGLE:
case STYLE_SOLO:
case STYLE_VERSUS:
case STYLE_COUPLE:
PadI.pad_no = (PadNumber)PlayerI.player_no;
if ( PlayerI.note == NOTE_PAD1_LEFT ) PadI.button = BUTTON_LEFT;
if ( PlayerI.note == NOTE_PAD1_UPLEFT ) PadI.button = BUTTON_UPLEFT;
if ( PlayerI.note == NOTE_PAD1_DOWN ) PadI.button = BUTTON_DOWN;
if ( PlayerI.note == NOTE_PAD1_UP ) PadI.button = BUTTON_UP;
if ( PlayerI.note == NOTE_PAD1_UPRIGHT ) PadI.button = BUTTON_UPRIGHT;
if ( PlayerI.note == NOTE_PAD1_RIGHT ) PadI.button = BUTTON_RIGHT;
break;
case STYLE_DOUBLE:
switch( PlayerI.note )
{
case NOTE_PAD1_LEFT: PadI.pad_no = PAD_1; PadI.button = BUTTON_LEFT; break;
case NOTE_PAD1_DOWN: PadI.pad_no = PAD_1; PadI.button = BUTTON_DOWN; break;
case NOTE_PAD1_UP: PadI.pad_no = PAD_1; PadI.button = BUTTON_UP; break;
case NOTE_PAD1_RIGHT: PadI.pad_no = PAD_1; PadI.button = BUTTON_RIGHT; break;
case NOTE_PAD2_LEFT: PadI.pad_no = PAD_2; PadI.button = BUTTON_LEFT; break;
case NOTE_PAD2_DOWN: PadI.pad_no = PAD_2; PadI.button = BUTTON_DOWN; break;
case NOTE_PAD2_UP: PadI.pad_no = PAD_2; PadI.button = BUTTON_UP; break;
case NOTE_PAD2_RIGHT: PadI.pad_no = PAD_2; PadI.button = BUTTON_RIGHT; break;
}
break;
default:
ASSERT( false ); // invalid DanceStyle
}
}
bool PrefsManager::IsButtonDown( PadInput pi )
{
for( int i=0; i<NUM_PAD_TO_DEVICE_SLOTS; i++ )
{
DeviceInput di;
if( PadToDevice( pi, i, di ) )
{
if( INPUTM->IsBeingPressed( di ) )
return true;
}
}
return false;
}
bool PrefsManager::IsButtonDown( PlayerInput PlayerI )
{
PadInput PadI;
PlayerToPad( PlayerI, PadI );
return IsButtonDown( PadI );
}
CString PrefsManager::GetStageText()
{
if( m_iCurrentStage == 3 )
@@ -443,5 +160,3 @@ CString PrefsManager::GetStageText()
return ssprintf( "%d%s", PREFS->m_iCurrentStage, sNumberSuffix );
}
+6 -42
View File
@@ -1,25 +1,19 @@
#pragma once
/*
-----------------------------------------------------------------------------
Class: PrefsManager
Desc: Manages all other game data that isn't handled about SongManager,
GameManager, or ThemeManager. Some of this data is saved between sessions,
for example, input mapping settings and GameOptions. This class also has
temporary holders for information that passed between windows - e.g.
Desc: Holds user-chosen preferences and saves it between sessions. This class
also has temporary holders for information that passed between windows - e.g.
ScoreSummary.
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#ifndef _PrefsManager_H_
#define _PrefsManager_H_
#include "RageInput.h"
#include "PadInput.h"
#include "PlayerInput.h"
#include "GameTypes.h"
@@ -38,8 +32,9 @@ public:
ScoreSummary m_ScoreSummary[NUM_PLAYERS]; // for passing from Dancing to Results
SongSortOrder m_SongSortOrder; // used by MusicWheel and should be saved until the app exits
int m_iCurrentStage; // number of stages played +1
CString GetStageText();
CString GetStageText();
DifficultyClass m_PreferredDifficultyClass[NUM_PLAYERS];
GameOptions m_GameOptions;
GraphicOptions m_GraphicOptions;
PlayerOptions m_PlayerOptions[NUM_PLAYERS];
@@ -49,39 +44,8 @@ public:
void ReadPrefsFromDisk();
void SavePrefsToDisk();
void AfterPrefsChanged(); // this function puts all the changes into effect
// input mapping stuff
void SetInputMap( DeviceInput di, PadInput pi, int iSlotIndex, bool bOverrideHardCoded = false );
void ClearFromInputMap( DeviceInput di );
void ClearFromInputMap( PadInput pi, int iSlotIndex );
void SetHardCodedButtons();
bool IsAHardCodedDeviceInput( DeviceInput di );
bool DeviceToPad( DeviceInput di, PadInput& pi ); // return true if there is a mapping from device to pad
bool PadToDevice( PadInput pi, int iSoltNum, DeviceInput& di ); // return true if there is a mapping from pad to device
void PadToPlayer( PadInput PadI, PlayerInput &PlayerI );
void PlayerToPad( PlayerInput PlayerI, PadInput &PadI );
bool IsButtonDown( PadInput pi );
bool IsButtonDown( PlayerInput PlayerI );
protected:
DeviceInput m_PItoDI[NUM_PADS][NUM_PAD_BUTTONS][NUM_PAD_TO_DEVICE_SLOTS]; // all the DeviceInputs that map to a PadInput
// lookup for efficiency from a DeviceInput to a PadInput
// This is repopulated every time m_PItoDI changes by calling UpdateTempDItoPI().
PadInput m_tempDItoPI[NUM_INPUT_DEVICES][NUM_DEVICE_BUTTONS];
void UpdateTempDItoPI();
};
extern PrefsManager* PREFS; // global and accessable from anywhere in our program
#endif
+5 -4
View File
@@ -5,7 +5,7 @@
Desc: Holder for a static texture with metadata. Can load just about any image format.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -24,6 +24,7 @@
#include "DXUtil.h"
#include "RageUtil.h"
#include "RageHelper.h"
#include "ErrorCatcher/ErrorCatcher.h"
//-----------------------------------------------------------------------------
@@ -109,7 +110,7 @@ void RageBitmapTexture::Create( DWORD dwMaxSize, DWORD dwTextureColorDepth, DWOR
m_sFilePath,
&ddii ) ) )
{
HELPER.FatalErrorHr( hr, "D3DXGetImageInfoFromFile() failed for file '%s'.", m_sFilePath );
FatalErrorHr( hr, "D3DXGetImageInfoFromFile() failed for file '%s'.", m_sFilePath );
}
D3DCAPS8 caps;
@@ -144,7 +145,7 @@ void RageBitmapTexture::Create( DWORD dwMaxSize, DWORD dwTextureColorDepth, DWOR
NULL, // no palette
&m_pd3dTexture ) ) )
{
HELPER.FatalErrorHr( hr, "D3DXCreateTextureFromFileEx() failed for file '%s'.", m_sFilePath );
FatalErrorHr( hr, "D3DXCreateTextureFromFileEx() failed for file '%s'.", m_sFilePath );
}
/////////////////////
@@ -155,7 +156,7 @@ void RageBitmapTexture::Create( DWORD dwMaxSize, DWORD dwTextureColorDepth, DWOR
D3DSURFACE_DESC ddsd;
if ( FAILED( hr = m_pd3dTexture->GetLevelDesc( 0, &ddsd ) ) )
HELPER.FatalErrorHr( hr, "Could not get level Description of D3DX texture!" );
FatalErrorHr( hr, "Could not get level Description of D3DX texture!" );
// save information about the texture
m_iTextureWidth = ddsd.Width;
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: Holder for a static texture with metadata. Can load just about any image format.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+74 -73
View File
@@ -5,7 +5,7 @@
Desc: Wrapper for DirectInput. Generates InputEvents.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -25,6 +25,7 @@
#include <dinput.h>
#include "RageUtil.h"
#include "RageHelper.h"
#include "ErrorCatcher/ErrorCatcher.h"
RageInput* INPUTM = NULL; // globally accessable input device
@@ -41,11 +42,11 @@ CString DeviceInput::GetDescription()
ASSERT( false ); // called GetDescription on a blank DeviceInput!
break;
case DEVICE_JOYSTICK1: // joystick
case DEVICE_JOYSTICK2:
case DEVICE_JOYSTICK3:
case DEVICE_JOYSTICK4:
sReturn = ssprintf("Joystick %d: ", device - DEVICE_JOYSTICK1 + 1 );
case DEVICE_JOY1: // joystick
case DEVICE_JOY2:
case DEVICE_JOY3:
case DEVICE_JOY4:
sReturn = ssprintf("Joystick %d: ", device - DEVICE_JOY1 + 1 );
switch( button )
{
@@ -223,7 +224,7 @@ bool DeviceInput::fromString( const CString &s )
//-----------------------------------------------------------------------------
// Name: EnumJoysticksCallback()
// Name: EnumJoysticksCallMenuBack( PlayerNumber p )
// Desc: Called once for each enumerated joystick. If we find one, create a
// device interface on it so we can play with it.
//-----------------------------------------------------------------------------
@@ -245,7 +246,7 @@ BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance,
HRESULT hr = pDI->CreateDevice( pdidInstance->guidInstance,
&pInput->m_pJoystick[i++],
NULL );
HELPER.FatalErrorHr( hr, "Error in CreateDevice() for joystick %d.", i );
FatalErrorHr( hr, "Error in CreateDevice() for joystick %d.", i );
return DIENUM_CONTINUE;
}
@@ -254,7 +255,7 @@ BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance,
//-----------------------------------------------------------------------------
// Name: EnumAxesCallback()
// Name: EnumAxesCallMenuBack( PlayerNumber p )
// Desc: Callback function for enumerating the axes on a joystick
//-----------------------------------------------------------------------------
BOOL CALLBACK EnumAxesCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
@@ -283,25 +284,26 @@ BOOL CALLBACK EnumAxesCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
RageInput::RageInput( HWND hWnd )
{
int i;
m_hWnd = hWnd;
m_pDI = NULL;
m_pKeyboard = NULL;
m_pMouse = NULL;
for( int i=0; i<NUM_JOYSTICKS; i++ )
for( i=0; i<NUM_JOYSTICKS; i++ )
m_pJoystick[i]=NULL;
ZeroMemory( &m_keys, sizeof(m_keys) );
ZeroMemory( &m_oldKeys, sizeof(m_oldKeys) );
for( int j=0; j<NUM_JOYSTICKS; j++ )
for( i=0; i<NUM_JOYSTICKS; i++ )
{
ZeroMemory( &m_joyState[j], sizeof(m_joyState[j]) );
ZeroMemory( &m_oldKeys[j], sizeof(m_joyState[j]) );
ZeroMemory( &m_joyState[i], sizeof(m_joyState[i]) );
ZeroMemory( &m_oldKeys[i], sizeof(m_joyState[i]) );
}
Initialize();
}
@@ -319,7 +321,7 @@ HRESULT RageInput::Initialize()
////////////////////////////////
if( FAILED(hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION,
IID_IDirectInput8, (VOID**)&m_pDI, NULL ) ) )
HELPER.FatalErrorHr( hr, "DirectInput8Create failed." );
FatalErrorHr( hr, "DirectInput8Create failed." );
/////////////////////////////
// Create the keyboard device
@@ -327,21 +329,21 @@ HRESULT RageInput::Initialize()
// Create our DirectInput Object for the Keyboard
if( FAILED( hr = m_pDI->CreateDevice( GUID_SysKeyboard, &m_pKeyboard, NULL ) ) )
HELPER.FatalErrorHr( hr, "CreateDevice keyboard failed." );
FatalErrorHr( hr, "CreateDevice keyboard failed." );
// Set our Cooperation Level with each Device
if( FAILED( hr = m_pKeyboard->SetCooperativeLevel(m_hWnd, DISCL_FOREGROUND |
DISCL_NOWINKEY |
DISCL_NONEXCLUSIVE) ) )
HELPER.FatalErrorHr( hr, "m_pKeyboard->SetCooperativeLevel failed." );
FatalErrorHr( hr, "m_pKeyboard->SetCooperativeLevel failed." );
// Set the Data Format of each device
if( FAILED( hr = m_pKeyboard->SetDataFormat(&c_dfDIKeyboard) ) )
HELPER.FatalErrorHr( hr, "m_pKeyboard->SetDataFormat failed." );
FatalErrorHr( hr, "m_pKeyboard->SetDataFormat failed." );
// Acquire the Keyboard Device
//if( FAILED( hr = m_pKeyboard->Acquire() ) )
// HELPER.FatalErrorHr( "m_pKeyboard->Acquire failed.", hr );
// FatalErrorHr( "m_pKeyboard->Acquire failed.", hr );
@@ -351,13 +353,13 @@ HRESULT RageInput::Initialize()
// Obtain an interface to the system mouse device.
if( FAILED( hr = m_pDI->CreateDevice( GUID_SysMouse, &m_pMouse, NULL ) ) )
HELPER.FatalErrorHr( hr, "CreateDevice mouse failed." );
FatalErrorHr( hr, "CreateDevice mouse failed." );
if( FAILED( hr = m_pMouse->SetCooperativeLevel( m_hWnd, DISCL_NONEXCLUSIVE|DISCL_FOREGROUND ) ) )
HELPER.FatalErrorHr( hr, "m_pMouse->SetCooperativeLevel failed." );
FatalErrorHr( hr, "m_pMouse->SetCooperativeLevel failed." );
if( FAILED( hr = m_pMouse->SetDataFormat( &c_dfDIMouse2 ) ) )
HELPER.FatalErrorHr( hr, "m_pMouse->SetDataFormat failed." );
FatalErrorHr( hr, "m_pMouse->SetDataFormat failed." );
/*
DIPROPDWORD dipdw;
@@ -370,7 +372,7 @@ HRESULT RageInput::Initialize()
if( FAILED( m_pMouse->SetProperty( DIPROP_AXISMODE, &dipdw.diph ) ) )
return E_FAIL;*/
//if( FAILED( hr = m_pMouse->Acquire()))
// HELPER.FatalErrorHr( "m_pMouse->Acquire failed.", hr );
// FatalErrorHr( "m_pMouse->Acquire failed.", hr );
m_RelPosition_x = 0;
m_RelPosition_y = 0;
@@ -387,7 +389,7 @@ HRESULT RageInput::Initialize()
EnumJoysticksCallback,
(VOID*)this,
DIEDFL_ATTACHEDONLY ) ) )
HELPER.FatalErrorHr( hr, "m_pDI->EnumDevices failed." );
FatalErrorHr( hr, "m_pDI->EnumDevices failed." );
for( int i=0; i<NUM_JOYSTICKS; i++ )
{
@@ -398,14 +400,14 @@ HRESULT RageInput::Initialize()
// passing a DIJOYSTATE2 structure to IDirectInputDevice::GetDeviceState().
if( m_pJoystick[i] )
if( FAILED( hr = m_pJoystick[i]->SetDataFormat( &c_dfDIJoystick2 ) ) )
HELPER.FatalErrorHr( hr, "m_pJoystick[i]->SetDataFormat failed." );
FatalErrorHr( hr, "m_pJoystick[i]->SetDataFormat failed." );
// Set the cooperative level to let DInput know how this device should
// interact with the system and with other DInput applications.
if( m_pJoystick[i] )
if( FAILED( hr = m_pJoystick[i]->SetCooperativeLevel( m_hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND ) ) )
HELPER.FatalErrorHr( hr, "m_pJoystick[i]->SetCooperativeLevel failed." );
FatalErrorHr( hr, "m_pJoystick[i]->SetCooperativeLevel failed." );
/*
@@ -423,12 +425,12 @@ HRESULT RageInput::Initialize()
// of enumerating device objects (axes, buttons, etc.).
if( m_pJoystick[i] )
if ( FAILED( hr = m_pJoystick[i]->EnumObjects( EnumAxesCallback, (VOID*)m_pJoystick[i], DIDFT_AXIS ) ) )
HELPER.FatalErrorHr( hr, "m_pJoystick[i]->EnumObjects failed." );
FatalErrorHr( hr, "m_pJoystick[i]->EnumObjects failed." );
// Acquire the newly created devices
if( m_pJoystick[i] )
if( FAILED( hr = m_pJoystick[i]->Acquire() ) )
HELPER.FatalErrorHr( hr, "m_pJoystick[i]->Acquire failed." );
FatalErrorHr( hr, "m_pJoystick[i]->Acquire failed." );
}
return S_OK;
@@ -461,7 +463,7 @@ void RageInput::Release()
HRESULT RageInput::GetDeviceInputs( DeviceInputArray &listDeviceInputs )
HRESULT RageInput::Update()
{
// macros for reading DI state structures
#define IS_PRESSED(b) (b & 0x80)
@@ -506,14 +508,6 @@ HRESULT RageInput::GetDeviceInputs( DeviceInputArray &listDeviceInputs )
return E_FAIL;
}
// get keyboard state was successful. Compare this state to the last state
for( int k = 0; k < 256; k++ ) // foreach key
{
// check if key is depressed this update and was not depressed last update
if( IS_PRESSED( m_keys[k] ) && !IS_PRESSED( m_oldKeys[k] ) )
listDeviceInputs.Add( DeviceInput(DEVICE_KEYBOARD, k) );
}
////////////////////
// Read the mouse
@@ -587,33 +581,6 @@ HRESULT RageInput::GetDeviceInputs( DeviceInputArray &listDeviceInputs )
// Get the input's device state
if( FAILED( hr = m_pJoystick[i]->GetDeviceState( sizeof(DIJOYSTATE2), &m_joyState[i] ) ) )
return hr; // The device should have been acquired during the Poll()
else
{
// check if key is depressed this update and was not depressed last update
if( IS_LEFT( m_joyState[i].lX ) &&
!IS_LEFT( m_oldJoyState[i].lX ) )
listDeviceInputs.Add( DeviceInput(InputDevice(DEVICE_JOYSTICK1+i), JOY_LEFT) );
if( IS_RIGHT( m_joyState[i].lX ) &&
!IS_RIGHT( m_oldJoyState[i].lX ) )
listDeviceInputs.Add( DeviceInput(InputDevice(DEVICE_JOYSTICK1+i), JOY_RIGHT) );
if( IS_UP( m_joyState[i].lY ) &&
!IS_UP( m_oldJoyState[i].lY ) )
listDeviceInputs.Add( DeviceInput(InputDevice(DEVICE_JOYSTICK1+i), JOY_UP) );
if( IS_DOWN( m_joyState[i].lY ) &&
!IS_DOWN( m_oldJoyState[i].lY ) )
listDeviceInputs.Add( DeviceInput(InputDevice(DEVICE_JOYSTICK1+i), JOY_DOWN) );
for( BYTE b=0; b<NUM_JOYSTICK_BUTTONS; b++ )
{
if( IS_PRESSED(m_joyState[i].rgbButtons[b]) && !IS_PRESSED(m_oldJoyState[i].rgbButtons[b]) )
listDeviceInputs.Add( DeviceInput( InputDevice(DEVICE_JOYSTICK1+i), JOY_1+b ) );
}
}
}
}
@@ -623,18 +590,18 @@ HRESULT RageInput::GetDeviceInputs( DeviceInputArray &listDeviceInputs )
}
BOOL RageInput::IsBeingPressed( DeviceInput di )
bool RageInput::IsBeingPressed( DeviceInput di )
{
switch( di.device )
{
case DEVICE_KEYBOARD:
return m_keys[ di.button ];
case DEVICE_JOYSTICK1:
case DEVICE_JOYSTICK2:
case DEVICE_JOYSTICK3:
case DEVICE_JOYSTICK4:
return 0 != m_keys[ di.button ];
case DEVICE_JOY1:
case DEVICE_JOY2:
case DEVICE_JOY3:
case DEVICE_JOY4:
int joy_index;
joy_index = di.device - DEVICE_JOYSTICK1;
joy_index = di.device - DEVICE_JOY1;
switch( di.button )
{
@@ -648,10 +615,44 @@ BOOL RageInput::IsBeingPressed( DeviceInput di )
return IS_DOWN( m_joyState[joy_index].lX );
default: // a joystick button
int button_index = di.button - JOY_1;
return IS_PRESSED( m_joyState[joy_index].rgbButtons[button_index] );
return 0 != IS_PRESSED( m_joyState[joy_index].rgbButtons[button_index] );
}
default:
HELPER.FatalError( "Invalid device" );
ASSERT( false ); // bad device
}
return false; // how did we get here?!?
}
bool RageInput::WasBeingPressed( DeviceInput di )
{
switch( di.device )
{
case DEVICE_KEYBOARD:
return 0 != m_oldKeys[ di.button ];
case DEVICE_JOY1:
case DEVICE_JOY2:
case DEVICE_JOY3:
case DEVICE_JOY4:
int joy_index;
joy_index = di.device - DEVICE_JOY1;
switch( di.button )
{
case JOY_LEFT:
return IS_LEFT( m_oldJoyState[joy_index].lX );
case JOY_RIGHT:
return IS_RIGHT( m_oldJoyState[joy_index].lX );
case JOY_UP:
return IS_UP( m_oldJoyState[joy_index].lX );
case JOY_DOWN:
return IS_DOWN( m_oldJoyState[joy_index].lX );
default: // a joystick button
int button_index = di.button - JOY_1;
return 0 != IS_PRESSED( m_oldJoyState[joy_index].rgbButtons[button_index] );
}
default:
ASSERT( false ); // bad device
}
return false; // how did we get here?!?
+15 -15
View File
@@ -4,7 +4,7 @@
Desc: Wrapper for DirectInput. Generates InputEvents.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -25,10 +25,10 @@ const int NUM_JOYSTICKS = 4;
enum InputDevice {
DEVICE_KEYBOARD = 0,
DEVICE_JOYSTICK1,
DEVICE_JOYSTICK2,
DEVICE_JOYSTICK3,
DEVICE_JOYSTICK4,
DEVICE_JOY1,
DEVICE_JOY2,
DEVICE_JOY3,
DEVICE_JOY4,
NUM_INPUT_DEVICES, // leave this at the end
DEVICE_NONE // means this is NULL
};
@@ -75,6 +75,8 @@ struct DeviceInput
public:
InputDevice device;
int button;
enum EventType { EVENT_PRESS, EVENT_REPEAT }; // maybe add EVENT_RELEASE later?
float fTimeHeld; // only relevant for EVENT_REPEAT
DeviceInput() { device=DEVICE_NONE; };
DeviceInput( InputDevice d, int b ) { device=d; button=b; };
@@ -95,9 +97,6 @@ public:
typedef CArray<DeviceInput, DeviceInput> DeviceInputArray;
class RageInput
{
// Our Windows Handle
@@ -116,15 +115,15 @@ public:
private:
// Arrays for Keyboard Data
byte m_keys[256];
byte m_oldKeys[256];
byte m_keys[NUM_KEYBOARD_BUTTONS];
byte m_oldKeys[NUM_KEYBOARD_BUTTONS];
// DirectInput mouse state structure
DIMOUSESTATE2 m_mouseState;
// Joystick data for 4 controllers
DIJOYSTATE2 m_joyState[4];
DIJOYSTATE2 m_oldJoyState[4];
// Joystick data for NUM_JOYSTICKS controllers
DIJOYSTATE2 m_joyState[NUM_JOYSTICKS];
DIJOYSTATE2 m_oldJoyState[NUM_JOYSTICKS];
INT m_AbsPosition_x;
INT m_AbsPosition_y;
@@ -141,8 +140,9 @@ public:
// Release all DirectInput Resources
VOID Release();
// Get our Devices State
HRESULT GetDeviceInputs( DeviceInputArray &listDeviceInputs );
BOOL IsBeingPressed( DeviceInput di );
HRESULT Update();
bool IsBeingPressed( DeviceInput di );
bool WasBeingPressed( DeviceInput di );
LPDIRECTINPUT8 GetDirectInput() { return m_pDI; }
LPDIRECTINPUTDEVICE8 GetMouseDevice() { return m_pMouse; }
+19 -18
View File
@@ -5,7 +5,7 @@
Desc: See header.
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
@@ -32,6 +32,7 @@
#include "DXUtil.h"
#include "RageUtil.h"
#include "RageHelper.h"
#include "ErrorCatcher/ErrorCatcher.h"
#include <stdio.h>
@@ -297,26 +298,26 @@ VOID RageMovieTexture::Create()
// Initialize the filter graph find and get information about the
// video (dimensions, color depth, etc.)
if( FAILED( hr = InitDShowTextureRenderer() ) )
HELPER.FatalErrorHr( hr, "Could not initialize the DirectShow Texture Renderer!" );
FatalErrorHr( hr, "Could not initialize the DirectShow Texture Renderer!" );
if( FAILED( hr = CreateD3DTexture() ) )
HELPER.FatalErrorHr( hr, "Could not create the D3D Texture!" );
FatalErrorHr( hr, "Could not create the D3D Texture!" );
// Pass the D3D texture to our TextureRenderer so it knows
// where to render new movie frames to.
if( FAILED( hr = m_pCTR->SetRenderTarget( this ) ) )
HELPER.FatalErrorHr( hr, "RageMovieTexture: SetRenderTarget failed." );
FatalErrorHr( hr, "RageMovieTexture: SetRenderTarget failed." );
// Start the graph running
if( FAILED( hr = PlayMovie() ) )
HELPER.FatalErrorHr( hr, "Could not run the DirectShow graph." );
FatalErrorHr( hr, "Could not run the DirectShow graph." );
}
void HandleDivXError()
{
HELPER.FatalError(
FatalError(
"Could not locate the DivX video codec.\n"
"DivX is required to movie textures and must\n"
"be installed before running the application.\n\n"
@@ -338,17 +339,17 @@ HRESULT RageMovieTexture::InitDShowTextureRenderer()
// Create the filter graph
if( FAILED( m_pGB.CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC) ) )
HELPER.FatalErrorHr( hr, "Could not create CLSID_FilterGraph!" );
FatalErrorHr( hr, "Could not create CLSID_FilterGraph!" );
// Create the Texture Renderer object
m_pCTR = new CTextureRenderer(NULL, &hr);
if( FAILED(hr) )
HELPER.FatalErrorHr( hr, "Could not create texture renderer object!" );
FatalErrorHr( hr, "Could not create texture renderer object!" );
// Get a pointer to the IBaseFilter on the TextureRenderer, add it to graph
pFTR = m_pCTR;
if( FAILED( hr = m_pGB->AddFilter(pFTR, L"TEXTURERENDERER" ) ) )
HELPER.FatalErrorHr( hr, "Could not add renderer filter to graph!" );
FatalErrorHr( hr, "Could not add renderer filter to graph!" );
// convert movie file path to wide char string
WCHAR wFileName[MAX_PATH];
@@ -364,21 +365,21 @@ HRESULT RageMovieTexture::InitDShowTextureRenderer()
if( FAILED( hr = m_pGB->AddSourceFilter( wFileName, L"SOURCE", &pFSrc ) ) ) // if this fails, it's probably because the user doesn't have DivX installed
{
HandleDivXError();
HELPER.FatalErrorHr( hr, "Could not create source filter to graph!" );
FatalErrorHr( hr, "Could not create source filter to graph!" );
}
// Find the source's output and the renderer's input
if( FAILED( hr = pFTR->FindPin( L"In", &pFTRPinIn ) ) )
HELPER.FatalErrorHr( hr, "Could not find input pin!" );
FatalErrorHr( hr, "Could not find input pin!" );
if( FAILED( hr = pFSrc->FindPin( L"Output", &pFSrcPinOut ) ) )
HELPER.FatalErrorHr( hr, "Could not find output pin!" );
FatalErrorHr( hr, "Could not find output pin!" );
// Connect these two filters
if( FAILED( hr = m_pGB->Connect( pFSrcPinOut, pFTRPinIn ) ) )
{
HandleDivXError();
HELPER.FatalErrorHr( hr, "Could not connect pins!" );
FatalErrorHr( hr, "Could not connect pins!" );
}
// Get the graph's media control, event & position interfaces
@@ -408,25 +409,25 @@ HRESULT RageMovieTexture::CreateD3DTexture()
m_iSourceHeight, m_iSourceHeight,
1, 0,
D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_pd3dTexture[0] ) ) )
HELPER.FatalErrorHr( hr, "Could not create the D3DX texture!" );
FatalErrorHr( hr, "Could not create the D3DX texture!" );
if( FAILED( hr = D3DXCreateTexture(m_pd3dDevice,
m_iSourceHeight, m_iSourceHeight,
1, 0,
D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_pd3dTexture[1] ) ) )
HELPER.FatalErrorHr( hr, "Could not create the D3DX texture!" );
FatalErrorHr( hr, "Could not create the D3DX texture!" );
// D3DXCreateTexture can silently change the parameters on us
D3DSURFACE_DESC ddsd;
if ( FAILED( hr = m_pd3dTexture[0]->GetLevelDesc( 0, &ddsd ) ) )
HELPER.FatalErrorHr( hr, "Could not get level Description of D3DX texture!" );
FatalErrorHr( hr, "Could not get level Description of D3DX texture!" );
m_iTextureWidth = ddsd.Width;
m_iTextureHeight = ddsd.Height;
m_TextureFormat = ddsd.Format;
if( m_TextureFormat != D3DFMT_A8R8G8B8 &&
m_TextureFormat != D3DFMT_A1R5G5B5 )
HELPER.FatalError( "Texture is format we can't handle! Format = 0x%x!", m_TextureFormat );
FatalError( "Texture is format we can't handle! Format = 0x%x!", m_TextureFormat );
return S_OK;
@@ -438,7 +439,7 @@ HRESULT RageMovieTexture::PlayMovie()
// Start the graph running;
if( FAILED( hr = m_pMC->Run() ) )
HELPER.FatalErrorHr( hr, "Could not run the DirectShow graph." );
FatalErrorHr( hr, "Could not run the DirectShow graph." );
return S_OK;
}
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: Based on the DShowTextures example in the DX8 SDK.
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
+5 -4
View File
@@ -5,7 +5,7 @@
Desc: Sound effects library (currently a wrapper around Bass Sound Library).
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -13,6 +13,7 @@
#include "RageSound.h"
#include "RageUtil.h"
#include "RageHelper.h"
#include "ErrorCatcher/ErrorCatcher.h"
#include "bass/bass.h"
#pragma comment(lib, "bass/bass.lib")
@@ -26,15 +27,15 @@ RageSound::RageSound( HWND hWnd )
HELPER.Log( "RageSound::RageSound()" );
// save the HWND
if( !hWnd )
HELPER.FatalError( "RageSound called with NULL hWnd." );
FatalError( "RageSound called with NULL hWnd." );
m_hWndApp = hWnd;
if( BASS_GetVersion() != MAKELONG(1,3) )
HELPER.FatalError( "BASS version 1.3 DLL could not be loaded. Verify that Bass.dll exists in the program directory.");
FatalError( "BASS version 1.3 DLL could not be loaded. Verify that Bass.dll exists in the program directory.");
if( !BASS_Init( -1, 44100, BASS_DEVICE_LEAVEVOL|BASS_DEVICE_LATENCY, m_hWndApp ) )
{
HELPER.FatalError(
FatalError(
"There was an error while initializing your sound card.\n\n"
"The most likely cause of this problem is that you do not have a sound card\n"
"installed, or that you have not yet installed a driver for your sound card.\n"
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: Sound effects library (currently a wrapper around Bass Sound Library).
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -5,7 +5,7 @@
Desc: Abstract class for a texture with metadata.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: Abstract class for a texture with metadata.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+3 -2
View File
@@ -5,7 +5,7 @@
Desc: Interface for loading and releasing textures.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -18,6 +18,7 @@
#include "RageMovieTexture.h"
#include "RageUtil.h"
#include "RageHelper.h"
#include "ErrorCatcher/ErrorCatcher.h"
RageTextureManager* TEXTURE = NULL;
@@ -139,7 +140,7 @@ void RageTextureManager::UnloadTexture( CString sTexturePath )
}
else // texture not found
{
HELPER.FatalError( ssprintf("Tried to Unload texture '%s' that wasn't loaded.", sTexturePath) );
FatalError( ssprintf("Tried to Unload texture '%s' that wasn't loaded.", sTexturePath) );
}
}
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: Interface for loading and releasing textures.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -5,7 +5,7 @@
Desc: See header.
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
+6 -3
View File
@@ -4,7 +4,7 @@
Desc: Miscellaneous helper functions.
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
@@ -50,7 +50,10 @@ inline float randomf( const float low=-1.0f, const float high=1.0f )
}
inline int roundf( const float f ) { return (int)((f)+0.5f); };
inline int roundf( const double f ) { return (int)((f)+0.5); };
inline float froundf( const float f, const float fRoundInterval )
{
return int( (f + fRoundInterval/2)/fRoundInterval ) * fRoundInterval;
}
bool IsAnInt( LPCTSTR s );
@@ -79,7 +82,7 @@ void splitrelpath(
CString& Ext
);
// Splits a CString into an CStringArray according the Deliminator. Supports UNC path names.
// Splits a CString into an CStringArray according the Deliminator.
void split(
const CString &Source,
const CString &Deliminator,
+3 -7
View File
@@ -5,7 +5,7 @@
Desc: Holds multiple sounds samples and can play a random sound easily.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -14,6 +14,7 @@
#include "RandomSample.h"
#include "RageUtil.h"
#include "RageHelper.h"
#include "ErrorCatcher/ErrorCatcher.h"
RandomSample::RandomSample()
@@ -48,7 +49,7 @@ bool RandomSample::LoadRandomSample( CString sSetFilePath )
{
CStdioFile file;
if( !file.Open(sSetFilePath, CFile::modeRead|CFile::shareDenyNone) )
HELPER.FatalError( ssprintf("Error opening sound set file '%s'.", sSetFilePath) );
FatalError( ssprintf("Error opening sound set file '%s'.", sSetFilePath) );
// Split for the directory of the sound set file. We'll need it below
@@ -70,17 +71,12 @@ bool RandomSample::LoadSound( CString sSoundFilePath )
{
HELPER.Log( "RandomSample::LoadSound( %s )", sSoundFilePath );
HELPER.Log( "Made it here - A" );
RageSoundSample* pSS = new RageSoundSample;
HELPER.Log( "Made it here - B" );
pSS->Load( sSoundFilePath );
m_pSamples.Add( pSS );
HELPER.Log( "Made it here - C" );
return true;
}
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: Holds multiple sounds samples and can play a random sound easily.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+4 -4
View File
@@ -5,7 +5,7 @@
Desc: A graphic displayed in the ScoreDisplayRolling during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -99,7 +99,7 @@ void ScoreDisplayRolling::AddToScore( TapNoteScore score, int iCurCombo )
// The scoring system for DDR versions 1 and 2 (including the Plus remixes) is as follows:
// For every step:
//
// Multiplier (M) = (# of Pattern in your current combo / 4) rounded down
// Multiplier (M) = (# of NoteMetadata in your current combo / 4) rounded down
// "Good" step = M * 100 (and this ends your combo)
// "Great" step = M * M * 100
// "Perfect" step = M * M * 300
@@ -139,11 +139,11 @@ void ScoreDisplayRolling::AddToScore( TapNoteScore score, int iCurCombo )
The base step value is the max score divided by 10, divided by
one-half of the max combo squared plus the max combo. This value is
multiplied by 10 for a perfect or 5 for a great, and further
multiplied by the number of Pattern currently in the combo. */
multiplied by the number of NoteMetadata currently in the combo. */
/*
int iScoreToAdd = 0; int iBonus = 0;
Pattern *pSteps = GAMEINFO->m_pStepsPlayer[m_PlayerNumber];
NoteMetadata *pSteps = GAMEINFO->m_pStepsPlayer[m_PlayerNumber];
int iNumFeet = pSteps->m_iNumFeet;
int iMaxCombo = pSteps->GetNumSteps();
+1 -1
View File
@@ -4,7 +4,7 @@
Desc: A graphic displayed in the ScoreDisplayRolling during Dancing.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+1 -1
View File
@@ -4,7 +4,7 @@
Desc:
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
+388 -91
View File
@@ -5,18 +5,18 @@
Desc: Holds metadata for a song and the song's step data.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
#include "Pattern.h"
#include "NoteMetadata.h"
#include "RageUtil.h"
#include "Song.h"
#include <math.h> // for fmod
#include "RageHelper.h"
#include "ErrorCatcher/ErrorCatcher.h"
@@ -72,12 +72,14 @@ Song::Song()
{
m_bChangedSinceSave = false;
m_fOffsetInSeconds = 0;
m_fMusicSampleStartBeat = m_fMusicSampleEndBeat = -1;
m_dwMusicBytes = 0;
}
void Song::GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, float &fBPSOut )
{
HELPER.Log( "GetBeatAndBPSFromElapsedTime( fElapsedTime = %f )", fElapsedTime );
// HELPER.Log( "GetBeatAndBPSFromElapsedTime( fElapsedTime = %f )", fElapsedTime );
// This function is a nightmare. Don't even try to understand it. :-)
fElapsedTime += m_fOffsetInSeconds;
@@ -149,6 +151,30 @@ void Song::GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, fl
}
// This is a super hack, but it's only called from WindowEdit, so it's OK :-)
// Writing an inverse function of GetBeatAndBPSFromElapsedTime() is impossible,
// so do a binary search to get close to the correct elapsed time.
float Song::GetElapsedTimeFromBeat( float fBeat )
{
float fElapsedTimeBestGuess = 100; // seconds
float fSecondsToMove = fElapsedTimeBestGuess/2; // seconds
float fBeatOut, fBPSOut;
while( fSecondsToMove > 0.1f )
{
GetBeatAndBPSFromElapsedTime( fElapsedTimeBestGuess, fBeatOut, fBPSOut );
if( fBeatOut > fBeat )
fElapsedTimeBestGuess -= fSecondsToMove;
else
fElapsedTimeBestGuess += fSecondsToMove;
fSecondsToMove /= 2;
}
return fElapsedTimeBestGuess;
}
bool Song::LoadFromSongDir( CString sDir )
{
HELPER.Log( "Song::LoadFromSongDir(%s)", sDir );
@@ -171,32 +197,32 @@ bool Song::LoadFromSongDir( CString sDir )
GetDirListing( sDir + CString("*.dwi"), arrayDWIFileNames );
int iNumDWIFiles = arrayDWIFileNames.GetSize();
CStringArray arraySongFileNames;
GetDirListing( sDir + CString("*.song"), arraySongFileNames );
int iNumSongFiles = arraySongFileNames.GetSize();
if( iNumDWIFiles > 1 )
{
HELPER.FatalError( ssprintf("There is more than one DWI file in '%s'. Which one should I use?", sDir) );
}
if( iNumSongFiles > 1 )
FatalError( "There is more than one DWI file in '%s'. Which one should I use?", sDir );
else if( iNumDWIFiles > 1 )
FatalError( "There is more than one DWI file in '%s'. Which one should I use?", sDir );
else if( iNumSongFiles == 1 )
LoadFromSMDir( sDir );
else if( iNumDWIFiles == 1 )
{
LoadSongInfoFromDWIFile( sDir + arrayDWIFileNames[0] );
}
LoadFromDWIFile( sDir + arrayDWIFileNames[0] );
else if( iNumBMSFiles > 0 )
{
LoadSongInfoFromBMSDir( sDir );
}
LoadFromBMSDir( sDir );
else
{
HELPER.FatalError( ssprintf("Couldn't find any BMS or MSD files in '%s'", sDir) );
}
FatalError( "Couldn't find any Song, BMS, or MSD files in '%s'", sDir );
return TRUE;
}
bool Song::LoadSongInfoFromBMSDir( CString sDir )
bool Song::LoadFromBMSDir( CString sDir )
{
HELPER.Log( "Song::LoadSongInfoFromBMSDir(%s)", sDir );
HELPER.Log( "Song::LoadFromBMSDir(%s)", sDir );
// make sure there is a trailing '\\' at the end of sDir
if( sDir.Right(1) != "\\" )
@@ -215,7 +241,7 @@ bool Song::LoadSongInfoFromBMSDir( CString sDir )
GetDirListing( sDir + CString("*.bms"), arrayBMSFileNames );
if( arrayBMSFileNames.GetSize() == 0 )
HELPER.FatalError( ssprintf("Couldn't find any BMS files in '%s'", sDir) );
FatalError( ssprintf("Couldn't find any BMS files in '%s'", sDir) );
// Load the Song info from the first BMS file. Silly BMS duplicates the song info in every
@@ -223,11 +249,11 @@ bool Song::LoadSongInfoFromBMSDir( CString sDir )
// is identical for every BMS file in the directory.
m_sSongFilePath = m_sSongDir + arrayBMSFileNames[0];
// load the Pattern from the rest of the BMS files
// load the NoteMetadata from the rest of the BMS files
for( int i=0; i<arrayBMSFileNames.GetSize(); i++ )
{
m_arrayPatterns.SetSize( m_arrayPatterns.GetSize()+1 );
Pattern &new_steps = m_arrayPatterns[ m_arrayPatterns.GetSize()-1 ];
m_arrayNoteMetadatas.SetSize( m_arrayNoteMetadatas.GetSize()+1 );
NoteMetadata &new_steps = m_arrayNoteMetadatas[ m_arrayNoteMetadatas.GetSize()-1 ];
new_steps.LoadFromBMSFile( m_sSongDir + arrayBMSFileNames[i] );
}
@@ -235,7 +261,7 @@ bool Song::LoadSongInfoFromBMSDir( CString sDir )
CStdioFile file;
if( !file.Open( m_sSongFilePath, CFile::modeRead|CFile::shareDenyNone ) )
{
HELPER.FatalError( ssprintf("Failed to open %s.", m_sSongFilePath) );
FatalError( ssprintf("Failed to open %s.", m_sSongFilePath) );
return false;
}
@@ -272,14 +298,10 @@ bool Song::LoadSongInfoFromBMSDir( CString sDir )
// handle the data
if( -1 != value_name.Find("#genre") )
{
m_sCreator = value_data;
}
else if( -1 != value_name.Find("#title") )
if( -1 != value_name.Find("#title") )
{
m_sTitle = value_data;
// strip Pattern type out of description leaving only song title (looks like 'B4U <BASIC>')
// strip NoteMetadata type out of description leaving only song title (looks like 'B4U <BASIC>')
m_sTitle.Replace( "(ANOTHER)", "" );
m_sTitle.Replace( "(BASIC)", "" );
m_sTitle.Replace( "(MANIAC)", "" );
@@ -367,7 +389,7 @@ bool Song::LoadSongInfoFromBMSDir( CString sDir )
}
for( i=0; i<m_BPMSegments.GetSize(); i++ )
HELPER.Log( "There is a BPM change at beat fd, BPM %f, index %d",
HELPER.Log( "There is a BPM change at beat %f, BPM %f, index %d",
m_BPMSegments[i].m_fStartBeat, m_BPMSegments[i].m_fBPM, i );
@@ -378,7 +400,7 @@ bool Song::LoadSongInfoFromBMSDir( CString sDir )
}
bool Song::LoadSongInfoFromDWIFile( CString sPath )
bool Song::LoadFromDWIFile( CString sPath )
{
HELPER.Log( "Song::LoadFromDWIFile(%s)", sPath );
@@ -421,7 +443,7 @@ bool Song::LoadSongInfoFromDWIFile( CString sPath )
CStdioFile file;
if( !file.Open( GetSongFilePath(), CFile::modeRead|CFile::shareDenyNone ) )
HELPER.FatalError( ssprintf("Error opening DWI file '%s'.", GetSongFilePath()) );
FatalError( ssprintf("Error opening DWI file '%s'.", GetSongFilePath()) );
// MessageBox( NULL, sFName, sFName, MB_OK );
@@ -527,9 +549,9 @@ bool Song::LoadSongInfoFromDWIFile( CString sPath )
else if( sValueName == "#SINGLE" || sValueName == "#DOUBLE" || sValueName == "#COUPLE" )
{
m_arrayPatterns.SetSize( m_arrayPatterns.GetSize()+1, 1 );
Pattern &new_pattern = m_arrayPatterns[ m_arrayPatterns.GetSize()-1 ];
new_pattern.LoadFromDWIValueTokens(
m_arrayNoteMetadatas.SetSize( m_arrayNoteMetadatas.GetSize()+1, 1 );
NoteMetadata &new_NoteMetadata = m_arrayNoteMetadatas[ m_arrayNoteMetadatas.GetSize()-1 ];
new_NoteMetadata.LoadFromDWITokens(
arrayValueTokens[0],
arrayValueTokens[1],
arrayValueTokens[2],
@@ -549,13 +571,188 @@ bool Song::LoadSongInfoFromDWIFile( CString sPath )
}
bool Song::LoadFromSMDir( CString sDir )
{
HELPER.Log( "Song::LoadFromSMDir(%s)", sDir );
int i;
// make sure there is a trailing '\\' at the end of sDir
if( sDir.Right(1) != "\\" )
sDir += "\\";
// save song dir
m_sSongDir = sDir;
// get group name
CStringArray sDirectoryParts;
split( m_sSongDir, "\\", sDirectoryParts, true );
m_sGroupName = sDirectoryParts[1];
CStringArray arraySongFileNames;
GetDirListing( sDir + "*.song", arraySongFileNames );
if( arraySongFileNames.GetSize() == 0 )
FatalError( "Couldn't find any SM Song files in '%s'", sDir );
// Load the Song info from the first BMS file. Silly BMS duplicates the song info in every
// file. So, we read the song data from only the first BMS file and assume that the info
// is identical for every BMS file in the directory.
m_sSongFilePath = m_sSongDir + arraySongFileNames[0];
CStringArray arrayNoteMetadataFileNames;
GetDirListing( sDir + CString("*.notes"), arrayNoteMetadataFileNames );
// load the NoteMetadata from the rest of the BMS files
for( i=0; i<arrayNoteMetadataFileNames.GetSize(); i++ )
{
m_arrayNoteMetadatas.SetSize( m_arrayNoteMetadatas.GetSize()+1 );
NoteMetadata &new_steps = m_arrayNoteMetadatas[ m_arrayNoteMetadatas.GetSize()-1 ];
new_steps.LoadFromNotesFile( m_sSongDir + arrayNoteMetadataFileNames[i] );
}
CStdioFile file;
if( !file.Open( GetSongFilePath(), CFile::modeRead|CFile::shareDenyNone ) )
FatalError( "Error opening DWI file '%s'.", GetSongFilePath() );
// read the whole file into a sFileText
CString sFileText;
CString buffer;
while( file.ReadString(buffer) )
sFileText += buffer;
file.Close();
// split sFileText into strings containing each value expression
CStringArray arrayValueStrings;
split( sFileText, ";", arrayValueStrings, false );
// for each value expression string, parse it into a value name and data
for( i=0; i < arrayValueStrings.GetSize(); i++ )
{
CString sValueString = arrayValueStrings[i];
// split the value string into tokens
CStringArray arrayValueTokens;
split( sValueString, ":", arrayValueTokens, false );
if( arrayValueTokens.GetSize() == 0 )
continue;
CString sValueName = arrayValueTokens.GetAt( 0 );
sValueName.TrimLeft();
// handle the data
if( sValueName == "#TITLE" )
m_sTitle = arrayValueTokens[1];
else if( sValueName == "#ARTIST" )
m_sArtist = arrayValueTokens[1];
else if( sValueName == "#CREDIT" )
m_sCredit = arrayValueTokens[1];
else if( sValueName == "#BANNER" )
m_sBannerPath = sDir + "\\" + arrayValueTokens[1];
else if( sValueName == "#BACKGROUND" )
m_sBackgroundPath = sDir + "\\" + arrayValueTokens[1];
else if( sValueName == "#BACKGROUNDMOVIE" )
{
if( arrayValueTokens[1] != "" )
m_sBackgroundMoviePath = sDir + "\\" + arrayValueTokens[1];
}
else if( sValueName == "#CDTITLE" )
{
if( arrayValueTokens[1] != "" )
m_sCDTitlePath = sDir + "\\" + arrayValueTokens[1];
}
else if( sValueName == "#MUSIC" )
m_sMusicPath = sDir + "\\" + arrayValueTokens[1];
else if( sValueName == "#MUSICBYTES" )
m_dwMusicBytes = atoi( arrayValueTokens[1] );
else if( sValueName == "#OFFSET" )
m_fOffsetInSeconds = (float)atof( arrayValueTokens[1] );
else if( sValueName == "#MUSICSAMPLERANGE" )
{
CStringArray arrayBeatValues;
split( arrayValueTokens[1], ",", arrayBeatValues );
m_fMusicSampleStartBeat = (float)atof( arrayBeatValues[0] );
m_fMusicSampleEndBeat = (float)atof( arrayBeatValues[1] );
}
else if( sValueName == "#FREEZES" )
{
CStringArray arrayFreezeExpressions;
split( arrayValueTokens[1], ",", arrayFreezeExpressions );
for( int f=0; f<arrayFreezeExpressions.GetSize(); f++ )
{
CStringArray arrayFreezeValues;
split( arrayFreezeExpressions[f], "=", arrayFreezeValues );
float fFreezeBeat = (float)atof( arrayFreezeValues[0] );
float fFreezeSeconds = (float)atof( arrayFreezeValues[1] );
FreezeSegment new_seg;
new_seg.m_fStartBeat = fFreezeBeat;
new_seg.m_fFreezeSeconds = fFreezeSeconds;
HELPER.Log( "Adding a freeze segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fFreezeSeconds );
m_FreezeSegments.Add( new_seg ); // add to back for now (we'll sort later)
SortFreezeSegmentsArray( m_FreezeSegments );
}
}
else if( sValueName == "#BPMS" )
{
CStringArray arrayBPMChangeExpressions;
split( arrayValueTokens[1], ",", arrayBPMChangeExpressions );
for( int b=0; b<arrayBPMChangeExpressions.GetSize(); b++ )
{
CStringArray arrayBPMChangeValues;
split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues );
float fBeat = (float)atof( arrayBPMChangeValues[0] );
float fNewBPM = (float)atoi( arrayBPMChangeValues[1] );
BPMSegment new_seg;
new_seg.m_fStartBeat = fBeat;
new_seg.m_fBPM = fNewBPM;
// add and sort
m_BPMSegments.Add( new_seg );
SortBPMSegmentsArray( m_BPMSegments );
}
}
else
HELPER.Log( "Unexpected value named '%s'", sValueName );
}
TidyUpData();
return TRUE;
}
void Song::TidyUpData()
{
if( m_sTitle == "" ) m_sTitle = "Untitled song";
m_sTitle.TrimRight();
if( m_sArtist == "" ) m_sArtist = "Unknown artist";
if( m_sCreator == "" ) m_sCreator = "Unknown creator";
if( m_BPMSegments.GetSize() == 0 )
HELPER.FatalError( ssprintf("No #BPM specified in '%s.'", GetSongFilePath()) );
FatalError( "No #BPM specified in '%s.'", GetSongFilePath() );
if( m_sMusicPath == "" || !DoesFileExist(GetMusicPath()) )
{
@@ -568,7 +765,7 @@ void Song::TidyUpData()
m_sMusicPath = m_sSongDir + arrayPossibleMusic[0];
else
m_sMusicPath = "";
// HELPER.FatalError( ssprintf("Music could not be found. Please check the Song file '%s' and verify the specified #MUSIC exists.", GetSongFilePath()) );
// FatalError( ssprintf("Music could not be found. Please check the Song file '%s' and verify the specified #MUSIC exists.", GetSongFilePath()) );
}
if( !DoesFileExist(GetBannerPath()) )
@@ -599,7 +796,7 @@ void Song::TidyUpData()
else
m_sBannerPath = "";
//HELPER.FatalError( ssprintf("Banner could not be found. Please check the Song file '%s' and verify the specified #BANNER exists.", GetSongFilePath()) );
//FatalError( ssprintf("Banner could not be found. Please check the Song file '%s' and verify the specified #BANNER exists.", GetSongFilePath()) );
}
if( !DoesFileExist(GetBackgroundPath()) )
@@ -641,59 +838,31 @@ void Song::TidyUpData()
if( arrayPossibleBackgroundMovies.GetSize() > 0 ) // we found a match
m_sBackgroundMoviePath = arrayPossibleBackgroundMovies[0];
}
if( !DoesFileExist(GetCDTitlePath()) )
{
m_sCDTitlePath = "";
}
}
void Song::GetPatternsThatMatchStyle( DanceStyle s, CArray<Pattern*, Pattern*>& arrayAddTo )
void Song::GetNoteMetadatasThatMatchGameAndStyle( CString sGame, CString sStyle, CArray<NoteMetadata*, NoteMetadata*>& arrayAddTo )
{
for( int i=0; i<m_arrayPatterns.GetSize(); i++ ) // for each of the Song's Pattern
for( int i=0; i<m_arrayNoteMetadatas.GetSize(); i++ ) // for each of the Song's NoteMetadata
{
Pattern* pCurPattern = &m_arrayPatterns[i];
NoteMetadata* pCurNoteMetadata = &m_arrayNoteMetadatas[i];
if( s == pCurPattern->m_DanceStyle // if the current GameModes matches the Pattern's GameMode
|| (s == STYLE_VERSUS && pCurPattern->m_DanceStyle == STYLE_SINGLE) )
if( sGame == pCurNoteMetadata->m_sGame &&
( sStyle == pCurNoteMetadata->m_sStyle || (sStyle == "versus" && pCurNoteMetadata->m_sStyle == "single") ) )
{
arrayAddTo.Add( pCurPattern );
arrayAddTo.Add( pCurNoteMetadata );
}
}
}
void Song::GetNumFeet( DanceStyle s, int& iDiffEasyOut, int& iDiffMediumOut, int& iDiffHardOut )
{
iDiffEasyOut = iDiffMediumOut = iDiffHardOut = -1; // -1 means not found
CArray<Pattern*, Pattern*> arrayMatchingSteps;
GetPatternsThatMatchStyle( s, arrayMatchingSteps );
for( int i=0; i<arrayMatchingSteps.GetSize(); i++ )
{
int iNumFeet = arrayMatchingSteps[i]->m_iNumFeet;
switch( arrayMatchingSteps[i]->m_DifficultyClass )
{
case Pattern::CLASS_EASY:
iDiffEasyOut = iNumFeet;
break;
case Pattern::CLASS_MEDIUM:
iDiffMediumOut = iNumFeet;
break;
case Pattern::CLASS_HARD:
iDiffHardOut = iNumFeet;
break;
case Pattern::CLASS_OTHER:
// should do something intelligent to fill in the missing spots...
if( iDiffEasyOut < 0 && iNumFeet <= 4 )
iDiffEasyOut = iNumFeet;
else if( iDiffHardOut < 0 && iNumFeet >= 7 )
iDiffHardOut = iNumFeet;
else if( iDiffMediumOut < 0 )
iDiffMediumOut = iNumFeet;
break;
}
}
}
/*
void Song::SaveOffsetChangeToDisk()
{
CString sDir, sFName, sExt;
@@ -702,14 +871,14 @@ void Song::SaveOffsetChangeToDisk()
if( sExt == "bms" )
{
for( int i=0; i<m_arrayPatterns.GetSize(); i++ ) // for each Pattern
for( int i=0; i<m_arrayNoteMetadatas.GetSize(); i++ ) // for each NoteMetadata
{
CString sPatternFileName = m_arrayPatterns[i].m_sPatternFilePath;
CString sNoteMetadataFileName = m_arrayNoteMetadatas[i].m_sNoteMetadataFilePath;
CStringArray arrayLines;
CStdioFile fileIn;
if( !fileIn.Open( sPatternFileName, CFile::modeRead|CFile::shareDenyNone) )
HELPER.FatalError( ssprintf("Failed to open '%s' for reading", sPatternFileName) );
if( !fileIn.Open( sNoteMetadataFileName, CFile::modeRead|CFile::shareDenyNone) )
FatalError( ssprintf("Failed to open '%s' for reading", sNoteMetadataFileName) );
// read the file into sFileContents
CString sLine;
@@ -721,8 +890,8 @@ void Song::SaveOffsetChangeToDisk()
// write the file back to disk with the changes
CStdioFile fileOut;
if( !fileOut.Open( sPatternFileName, CFile::modeWrite|CFile::shareDenyWrite) )
HELPER.FatalError( ssprintf("Failed to open '%s' for writing", sPatternFileName) );
if( !fileOut.Open( sNoteMetadataFileName, CFile::modeWrite|CFile::shareDenyWrite) )
FatalError( ssprintf("Failed to open '%s' for writing", sNoteMetadataFileName) );
for( int j=0; j<arrayLines.GetSize(); j++ )
{
CString sLine = arrayLines[j];
@@ -759,7 +928,7 @@ void Song::SaveOffsetChangeToDisk()
CStringArray arrayLines;
CStdioFile fileIn;
if( !fileIn.Open( GetSongFilePath(), CFile::modeRead|CFile::shareDenyNone) )
HELPER.FatalError( ssprintf("Failed to open '%s' for reading", GetSongFilePath()) );
FatalError( ssprintf("Failed to open '%s' for reading", GetSongFilePath()) );
// read the file into sFileContents
CString sLine;
@@ -773,7 +942,7 @@ void Song::SaveOffsetChangeToDisk()
// write the file back to disk with the changes
CStdioFile fileOut;
if( !fileOut.Open( GetSongFilePath(), CFile::modeWrite|CFile::shareDenyWrite) )
HELPER.FatalError( ssprintf("Failed to open '%s' for writing", GetSongFilePath()) );
FatalError( ssprintf("Failed to open '%s' for writing", GetSongFilePath()) );
for( int i=0; i<arrayLines.GetSize(); i++ )
{
CString sLine = arrayLines[i];
@@ -798,15 +967,142 @@ void Song::SaveOffsetChangeToDisk()
}
else
{
HELPER.FatalError( ssprintf("Unrecognized extension '%s' on song file '%s'", sExt, GetSongFilePath()) );
FatalError( ssprintf("Unrecognized extension '%s' on song file '%s'", sExt, GetSongFilePath()) );
}
m_bChangedSinceSave = false;
}
*/
void Song::Save()
{
HELPER.Log( "Song::Save()" );
int i;
if( -1 != m_sSongDir.Find("DWI Support") )
{
HELPER.Log("WARNING: Can't save to DWI support folder!");
return;
}
//
// rename all old files to avoid confusion
//
CStringArray arrayOldFileNames;
GetDirListing( m_sSongDir + CString("*.bms"), arrayOldFileNames );
GetDirListing( m_sSongDir + CString("*.dwi"), arrayOldFileNames );
for( i=0; i<arrayOldFileNames.GetSize(); i++ )
{
CString sOldPath = m_sSongDir + arrayOldFileNames[i];
CString sNewPath = sOldPath + ".old";
MoveFile( sOldPath, sNewPath );
}
CString sDir, sFName, sExt;
splitrelpath( GetSongFilePath(), sDir, sFName, sExt );
m_sSongFilePath = m_sSongDir + sFName + ".song";
CStdioFile file;
if( !file.Open( m_sSongFilePath, CFile::modeWrite | CFile::modeCreate ) )
FatalError( "Error opening song file '%s' for writing.", m_sSongFilePath );
file.WriteString( ssprintf("#TITLE:%s;\n", m_sTitle) );
file.WriteString( ssprintf("#ARTIST:%s;\n", m_sArtist) );
file.WriteString( ssprintf("#CREDIT:%s;\n", m_sCredit) );
if( m_sBannerPath != "" )
{
splitrelpath( m_sBannerPath, sDir, sFName, sExt );
file.WriteString( ssprintf("#BANNER:%s;\n", sFName+"."+sExt) );
}
else
file.WriteString( "#BANNER:;\n" );
if( m_sBackgroundPath != "" )
{
splitrelpath( m_sBackgroundPath, sDir, sFName, sExt );
file.WriteString( ssprintf("#BACKGROUND:%s;\n", sFName+"."+sExt) );
}
else
file.WriteString( "#BACKGROUND:;\n" );
if( m_sBackgroundMoviePath != "" )
{
splitrelpath( m_sBackgroundMoviePath, sDir, sFName, sExt );
file.WriteString( ssprintf("#BACKGROUNDMOVIE:%s;\n", sFName+"."+sExt) );
}
else
file.WriteString( "#BACKGROUNDMOVIE:;\n" );
if( m_sCDTitlePath != "" )
{
splitrelpath( m_sCDTitlePath, sDir, sFName, sExt );
file.WriteString( ssprintf("#CDTITLE:%s;\n", sFName+"."+sExt) );
}
else
file.WriteString( "#CDTITLE:;\n" );
if( m_sMusicPath != "" )
{
splitrelpath( m_sMusicPath, sDir, sFName, sExt );
file.WriteString( ssprintf("#MUSIC:%s;\n", sFName+"."+sExt) );
}
else
file.WriteString( "#MUSIC:;\n" );
file.WriteString( ssprintf("#MUSICBYTES:%u;\n", m_dwMusicBytes) );
file.WriteString( ssprintf("#OFFSET:%f;\n", m_fOffsetInSeconds) );
file.WriteString( "#FREEZES:" );
for( i=0; i<m_FreezeSegments.GetSize(); i++ )
{
FreezeSegment &fs = m_FreezeSegments[i];
file.WriteString( ssprintf("%f=%f", fs.m_fStartBeat, fs.m_fFreezeSeconds) );
if( i != m_FreezeSegments.GetSize()-1 )
file.WriteString( "," );
}
file.WriteString( ";\n" );
file.WriteString( "#BPMS:" );
for( i=0; i<m_BPMSegments.GetSize(); i++ )
{
BPMSegment &bs = m_BPMSegments[i];
file.WriteString( ssprintf("%f=%f", bs.m_fStartBeat, bs.m_fBPM) );
if( i != m_BPMSegments.GetSize()-1 )
file.WriteString( "," );
}
file.WriteString( ";\n" );
file.Close();
//
// Save all NoteMetadatas for this file
//
for( i=0; i<m_arrayNoteMetadatas.GetSize(); i++ )
{
m_arrayNoteMetadatas[i].Save( m_sSongDir );
}
}
Grade Song::GetGradeForDifficultyClass( CString sGame, CString sStyle, DifficultyClass dc )
{
CArray<NoteMetadata*, NoteMetadata*> arrayNoteMetadatas;
this->GetNoteMetadatasThatMatchGameAndStyle( sGame, sStyle, arrayNoteMetadatas );
SortNoteMetadataArrayByDifficultyClass( arrayNoteMetadatas );
for( int i=0; i<arrayNoteMetadatas.GetSize(); i++ )
{
NoteMetadata* pNoteMetadata = arrayNoteMetadatas[i];
if( pNoteMetadata->m_DifficultyClass == dc )
return pNoteMetadata->m_TopGrade;
}
return GRADE_NO_DATA;
}
/////////////////////////////////////
// Sorting
@@ -817,8 +1113,8 @@ int CompareSongPointersByTitle(const void *arg1, const void *arg2)
Song* pSong1 = *(Song**)arg1;
Song* pSong2 = *(Song**)arg2;
CString sTitle1 = pSong1->GetTitle();
CString sTitle2 = pSong2->GetTitle();
CString sTitle1 = pSong1->GetFullTitle();
CString sTitle2 = pSong2->GetFullTitle();
CString sFilePath1 = pSong1->GetSongFilePath(); // this is unique among songs
CString sFilePath2 = pSong2->GetSongFilePath();
@@ -922,3 +1218,4 @@ void SortSongPointerArrayByMostPlayed( CArray<Song*, Song*> &arraySongPointers )
{
qsort( arraySongPointers.GetData(), arraySongPointers.GetSize(), sizeof(Song*), CompareSongPointersByMostPlayed );
}
+75 -36
View File
@@ -5,27 +5,39 @@
Desc: See header.
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
//#include <d3dxmath.h>
#include "SongManager.h"
#include "IniFile.h"
#include "RageHelper.h"
#include "ErrorCatcher/ErrorCatcher.h"
SongManager* SONG = NULL; // global and accessable from anywhere in our program
const CString g_sStatisticsFileName = "statistics.ini";
D3DXCOLOR GROUP_COLORS[] = {
D3DXCOLOR( 0.9f, 0.0f, 0.2f, 1 ), // red
D3DXCOLOR( 0.6f, 0.0f, 0.4f, 1 ), // pink
D3DXCOLOR( 0.2f, 0.1f, 0.3f, 1 ), // purple
D3DXCOLOR( 0.0f, 0.4f, 0.8f, 1 ), // sky blue
D3DXCOLOR( 0.0f, 0.6f, 0.6f, 1 ), // sea green
D3DXCOLOR( 0.0f, 0.6f, 0.2f, 1 ), // green
D3DXCOLOR( 0.8f, 0.6f, 0.0f, 1 ), // orange
};
const int NUM_GROUP_COLORS = sizeof(GROUP_COLORS) / sizeof(D3DXCOLOR);
SongManager::SongManager()
{
m_pCurSong = NULL;
for( int p=0; p<NUM_PLAYERS; p++ )
m_pCurPattern[p] = NULL;
m_pCurNoteMetadata[p] = NULL;
InitSongArrayFromDisk();
ReadStatisticsFromDisk();
@@ -36,6 +48,7 @@ SongManager::~SongManager()
{
SaveStatisticsToDisk();
CleanUpSongArray();
m_arrayGroupNames.RemoveAll();
}
@@ -43,6 +56,21 @@ void SongManager::InitSongArrayFromDisk()
{
LoadStepManiaSongDir( "Songs" );
LoadDWISongDir( "DWI Support" );
// computer group names
CArray<Song*, Song*> arraySongs;
arraySongs.Copy( m_pSongs );
SortSongPointerArrayByGroup( arraySongs );
for( int i=0; i<m_pSongs.GetSize(); i++ )
{
Song* pSong = m_pSongs[i];
const CString sGroupName = m_pSongs[i]->GetGroupName();
if( m_arrayGroupNames.GetSize() == 0 || m_arrayGroupNames[m_arrayGroupNames.GetSize()-1] != sGroupName )
m_arrayGroupNames.Add( sGroupName );
}
HELPER.Log( "Found %d Songs.", m_pSongs.GetSize() );
}
@@ -68,7 +96,7 @@ void SongManager::LoadStepManiaSongDir( CString sDir )
GetDirListing( ssprintf("%s\\%s\\*.mp3", sDir, sGroupDirName), arrayFiles );
GetDirListing( ssprintf("%s\\%s\\*.wav", sDir, sGroupDirName), arrayFiles );
if( arrayFiles.GetSize() > 0 )
HELPER.FatalError(
FatalError(
ssprintf( "The song folder '%s' must be placed inside of a group folder.\n\n"
"All song folders must be placed below a group folder. For example, 'Songs\\DDR 4th Mix\\B4U'. See the StepMania readme for more info.",
ssprintf("%s\\%s", sDir, sGroupDirName ) )
@@ -135,7 +163,7 @@ void SongManager::LoadDWISongDir( CString sDir )
// load DWIs from the sub dirs
Song* pNewSong = new Song;
pNewSong->LoadSongInfoFromDWIFile( ssprintf("DWI Support\\DWIs\\%s\\%s", sDirName, sDWIFileName) );
pNewSong->LoadFromDWIFile( ssprintf("DWI Support\\DWIs\\%s\\%s", sDirName, sDWIFileName) );
m_pSongs.Add( pNewSong );
}
}
@@ -190,7 +218,7 @@ void SongManager::ReadStatisticsFromDisk()
int iRetVal;
int i;
// Parse for Song name and Pattern name
// Parse for Song name and NoteMetadata name
iRetVal = sscanf( name_string, "%[^:]::%[^\n]", szSongName, szStepsName );
if( iRetVal != 2 )
continue; // this line doesn't match what is expected
@@ -200,7 +228,7 @@ void SongManager::ReadStatisticsFromDisk()
Song* pSong = NULL;
for( i=0; i<m_pSongs.GetSize(); i++ )
{
if( m_pSongs[i]->GetTitle() == szSongName ) // match!
if( m_pSongs[i]->GetFullTitle() == szSongName ) // match!
{
pSong = m_pSongs[i];
break;
@@ -210,35 +238,35 @@ void SongManager::ReadStatisticsFromDisk()
continue; // skip this entry
// Search for the corresponding Pattern pointer.
Pattern* pPattern = NULL;
for( i=0; i<pSong->m_arrayPatterns.GetSize(); i++ )
// Search for the corresponding NoteMetadata pointer.
NoteMetadata* pNoteMetadata = NULL;
for( i=0; i<pSong->m_arrayNoteMetadatas.GetSize(); i++ )
{
if( pSong->m_arrayPatterns[i].m_sDescription == szStepsName ) // match!
if( pSong->m_arrayNoteMetadatas[i].m_sDescription == szStepsName ) // match!
{
pPattern = &pSong->m_arrayPatterns[i];
pNoteMetadata = &pSong->m_arrayNoteMetadatas[i];
break;
}
}
if( pPattern == NULL ) // didn't find a match
if( pNoteMetadata == NULL ) // didn't find a match
continue; // skip this entry
// Parse the Pattern statistics.
// Parse the NoteMetadata statistics.
char szGradeLetters[10]; // longest possible string is "AAA"
iRetVal = sscanf(
value_string,
"%d::%[^:]::%d::%d",
&pPattern->m_iNumTimesPlayed,
&pNoteMetadata->m_iNumTimesPlayed,
szGradeLetters,
&pPattern->m_iTopScore,
&pPattern->m_iMaxCombo
&pNoteMetadata->m_iTopScore,
&pNoteMetadata->m_iMaxCombo
);
if( iRetVal != 4 )
continue;
pPattern->m_TopGrade = StringToGrade( szGradeLetters );
pNoteMetadata->m_TopGrade = StringToGrade( szGradeLetters );
}
}
}
@@ -253,22 +281,22 @@ void SongManager::SaveStatisticsToDisk()
{
Song* pSong = m_pSongs[i];
for( int j=0; j<pSong->m_arrayPatterns.GetSize(); j++ ) // for each Pattern
for( int j=0; j<pSong->m_arrayNoteMetadatas.GetSize(); j++ ) // for each NoteMetadata
{
Pattern* pPattern = &pSong->m_arrayPatterns[j];
NoteMetadata* pNoteMetadata = &pSong->m_arrayNoteMetadatas[j];
if( pPattern->m_TopGrade == GRADE_NO_DATA )
if( pNoteMetadata->m_TopGrade == GRADE_NO_DATA )
continue; // skip
// Each value has the format "SongName::PatternName=TimesPlayed::TopGrade::TopScore::MaxCombo".
// Each value has the format "SongName::NoteMetadataName=TimesPlayed::TopGrade::TopScore::MaxCombo".
CString sName = ssprintf( "%s::%s", pSong->GetTitle(), pPattern->m_sDescription );
CString sName = ssprintf( "%s::%s", pSong->GetFullTitle(), pNoteMetadata->m_sDescription );
CString sValue = ssprintf(
"%d::%s::%d::%d",
pPattern->m_iNumTimesPlayed,
GradeToString( pPattern->m_TopGrade ),
pPattern->m_iTopScore,
pPattern->m_iMaxCombo
pNoteMetadata->m_iNumTimesPlayed,
GradeToString( pNoteMetadata->m_TopGrade ),
pNoteMetadata->m_iTopScore,
pNoteMetadata->m_iMaxCombo
);
ini.SetValue( "Statistics", sName, sValue );
@@ -291,18 +319,20 @@ CString SongManager::GetGroupBannerPath( CString sGroupName )
void SongManager::GetGroupNames( CStringArray &AddTo )
{
CArray<Song*, Song*> arraySongs;
arraySongs.Copy( m_pSongs );
SortSongPointerArrayByGroup( arraySongs );
AddTo.Copy( m_arrayGroupNames );
}
for( int i=0; i<m_pSongs.GetSize(); i++ )
D3DXCOLOR SongManager::GetGroupColor( const CString &sGroupName )
{
// search for the group index
for( int i=0; i<m_arrayGroupNames.GetSize(); i++ )
{
Song* pSong = m_pSongs[i];
const CString sGroupName = m_pSongs[i]->GetGroupName();
if( AddTo.GetSize() == 0 || AddTo[AddTo.GetSize()-1] != sGroupName )
AddTo.Add( sGroupName );
if( m_arrayGroupNames[i] == sGroupName )
break;
}
ASSERT( i != m_arrayGroupNames.GetSize() ); // this is not a valid group
return GROUP_COLORS[i%NUM_GROUP_COLORS];
}
void SongManager::GetSongsInGroup( const CString sGroupName, CArray<Song*, Song*> &AddTo )
@@ -315,3 +345,12 @@ void SongManager::GetSongsInGroup( const CString sGroupName, CArray<Song*, Song*
}
SortSongPointerArrayByGroup( AddTo );
}
CString SongManager::ShortenGroupName( const CString &sOrigGroupName )
{
CString sShortName = sOrigGroupName;
sShortName.Replace( "Dance Dance Revolution", "DDR" );
sShortName.Replace( "dance dance revolution", "DDR" );
sShortName.Replace( "DANCE DANCE REVOLUTION", "DDR" );
return sShortName;
}
+11 -8
View File
@@ -2,10 +2,10 @@
-----------------------------------------------------------------------------
Class: SongManager
Desc: Holder for all Songs and Pattern. Also keeps track of the current
Song and Pattern, and loads/saves statistics.
Desc: Holder for all Songs and NoteMetadata. Also keeps track of the current
Song and NoteMetadata, and loads/saves statistics.
Copyright (c) 2001-2002 by the names listed below. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
@@ -15,7 +15,7 @@
#include "Song.h"
//#include <d3dxmath.h> // for D3DXCOLOR
class SongManager
@@ -24,8 +24,9 @@ public:
SongManager();
~SongManager();
Song* m_pCurSong;
Pattern* m_pCurPattern[NUM_PLAYERS];
Song* m_pCurSong;
NoteMetadata* m_pCurNoteMetadata[NUM_PLAYERS];
CString m_sPreferredGroup;
CArray<Song*, Song*> m_pSongs; // all songs that can be played
@@ -40,8 +41,10 @@ public:
CString GetGroupBannerPath( CString sGroupName );
void GetGroupNames( CStringArray &AddTo );
D3DXCOLOR GetGroupColor( const CString &sGroupName );
CString ShortenGroupName( const CString &sOrigGroupName );
void GetSongsInGroup( const CString sGroupName, CArray<Song*,Song*> &AddTo );
@@ -50,7 +53,7 @@ protected:
void LoadStepManiaSongDir( CString sDir );
void LoadDWISongDir( CString sDir );
CMapStringToString m_mapGroupToBannerPath; // each song group has a banner associated with it
CStringArray m_arrayGroupNames;
};
+14 -5
View File
@@ -5,7 +5,7 @@
Desc: A bitmap actor that animates and moves around.
Copyright (c) 2001 Chris Danford. All rights reserved.
Copyright (c) 2001-2002 by the persons listed below. All rights reserved.
-----------------------------------------------------------------------------
*/
@@ -16,6 +16,7 @@
#include "IniFile.h"
#include <math.h>
#include "RageHelper.h"
#include "ErrorCatcher/ErrorCatcher.h"
Sprite::Sprite()
@@ -74,11 +75,11 @@ bool Sprite::LoadFromSpriteFile( CString sSpritePath, DWORD dwHints, bool bForce
IniFile ini;
ini.SetPath( m_sSpritePath );
if( !ini.ReadFile() )
HELPER.FatalError( ssprintf("Error opening Sprite file '%s'.", m_sSpritePath) );
FatalError( ssprintf("Error opening Sprite file '%s'.", m_sSpritePath) );
CString sTextureFile = ini.GetValue( "Sprite", "Texture" );
if( sTextureFile == "" )
HELPER.FatalError( ssprintf("Error reading value 'Texture' from %s.", m_sSpritePath) );
FatalError( ssprintf("Error reading value 'Texture' from %s.", m_sSpritePath) );
CString sTexturePath = sFontDir + sTextureFile; // save the path of the new texture
@@ -99,7 +100,7 @@ bool Sprite::LoadFromSpriteFile( CString sSpritePath, DWORD dwHints, bool bForce
m_iStateToFrame[i] = ini.GetValueI( "Sprite", sFrameKey );
if( m_iStateToFrame[i] >= m_pTexture->GetNumFrames() )
HELPER.FatalError( ssprintf("In '%s', %s is %d, but the texture %s only has %d frames.",
FatalError( ssprintf("In '%s', %s is %d, but the texture %s only has %d frames.",
m_sSpritePath, sFrameKey, m_iStateToFrame[i], sTexturePath, m_pTexture->GetNumFrames()) );
m_fDelay[i] = (float)ini.GetValueF( "Sprite", sDelayKey );
@@ -120,10 +121,18 @@ bool Sprite::LoadFromSpriteFile( CString sSpritePath, DWORD dwHints, bool bForce
return true;
}
bool Sprite::LoadTexture( CString sTexturePath, DWORD dwHints, bool bForceReload )
void Sprite::UnloadTexture()
{
if( m_pTexture != NULL ) // If there was a previous bitmap...
TEXTURE->UnloadTexture( m_sTexturePath ); // Unload it.
m_pTexture = NULL;
m_sTexturePath = "";
}
bool Sprite::LoadTexture( CString sTexturePath, DWORD dwHints, bool bForceReload )
{
if( m_pTexture != NULL ) // If there was a previous bitmap...
UnloadTexture();
m_sTexturePath = sTexturePath;

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