2.50 checkin
This commit is contained in:
@@ -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() );
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
@@ -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
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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 );
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -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) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -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,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
|
||||
{
|
||||
|
||||
@@ -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 "";
|
||||
}
|
||||
@@ -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] );
|
||||
};
|
||||
|
||||
};
|
||||
@@ -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
@@ -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
@@ -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
|
||||
@@ -16,7 +16,7 @@ class GhostArrow;
|
||||
|
||||
|
||||
#include "Sprite.h"
|
||||
#include "Pattern.h"
|
||||
#include "NoteMetadata.h"
|
||||
|
||||
|
||||
class GhostArrow : public Sprite
|
||||
|
||||
@@ -16,7 +16,7 @@ class GhostArrowBright;
|
||||
|
||||
|
||||
#include "Sprite.h"
|
||||
#include "Pattern.h"
|
||||
#include "NoteMetadata.h"
|
||||
|
||||
|
||||
class GhostArrowBright : public Sprite
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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];
|
||||
};
|
||||
|
||||
@@ -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
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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,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()
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -16,7 +16,7 @@ class HoldGhostArrow;
|
||||
|
||||
|
||||
#include "Sprite.h"
|
||||
#include "Pattern.h"
|
||||
#include "NoteMetadata.h"
|
||||
|
||||
|
||||
class HoldGhostArrow : public Sprite
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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; };
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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
@@ -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 );
|
||||
|
||||
|
||||
@@ -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) )
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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
@@ -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
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,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"
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
@@ -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
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user