Initial checkin

This commit is contained in:
Chris Danford
2001-11-03 10:52:42 +00:00
parent 2f65fb99f0
commit 7caffe0c93
54 changed files with 7057 additions and 0 deletions
+172
View File
@@ -0,0 +1,172 @@
#include "stdafx.h" // testing updates
//-----------------------------------------------------------------------------
// File: Actor.cpp
//
// Desc: Base class for all objects that appear on the screen.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#include "Actor.h"
#include <math.h>
Actor::Actor()
{
Init();
}
void Actor::Init()
{
m_size = D3DXVECTOR2( 0, 0 );
m_pos = D3DXVECTOR2( 0, 0 );
m_rotation = D3DXVECTOR3( 0, 0, 0 );
m_scale = D3DXVECTOR2( 1, 1 );
m_color = D3DXCOLOR( 1, 1, 1, 1 );
m_start_pos = m_end_pos = D3DXVECTOR2( 0.0f, 0.0f );
m_start_rotation= m_end_rotation = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
m_start_scale = m_end_scale = D3DXVECTOR2( 1.0f, 1.0f );
m_start_color = m_end_color = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f );
m_TweenType = no_tween;
m_fTweenTime = 0.0f;
m_fTimeIntoTween = 0.0f;
}
void Actor::Update( const FLOAT &fDeltaTime )
{
// RageLog( "Actor::Update( %f )", fDeltaTime );
// update tweening
if( m_TweenType != no_tween ) // we are performing some type of tweening
{
m_fTimeIntoTween += fDeltaTime;
if( m_fTimeIntoTween > m_fTweenTime ) // The tweening is over. Stop the tweening
{
m_pos = m_end_pos;
m_scale = m_end_scale;
m_rotation = m_end_rotation;
m_color = m_end_color;
m_TweenType = no_tween;
}
else // Tweening. Recalcute the curent position.
{
FLOAT fPercentThroughTween = m_fTimeIntoTween / m_fTweenTime;
// distort the percentage if appropriate
if( m_TweenType == tween_bias_begin )
fPercentThroughTween = (FLOAT) sqrt( fPercentThroughTween );
else if( m_TweenType == tweening_bias_end )
fPercentThroughTween = fPercentThroughTween * fPercentThroughTween;
m_pos = m_start_pos + (m_end_pos - m_start_pos )*fPercentThroughTween;
m_scale = m_start_scale + (m_end_scale - m_start_scale )*fPercentThroughTween;
m_rotation = m_start_rotation+ (m_end_rotation - m_start_rotation)*fPercentThroughTween;
m_color = m_start_color*(1.0f-fPercentThroughTween) + m_end_color*(fPercentThroughTween);
}
} // end if m_TweenType != no_tween
}
void Actor::TweenTo( FLOAT time, FLOAT x, FLOAT y, FLOAT zoom, FLOAT rot, D3DXCOLOR col, TweenType tt )
{
// set our tweeen starting values to the current position
m_start_pos = m_pos;
m_start_scale = m_scale;
m_start_rotation = m_rotation;
m_start_color = m_color;
// set the ending tweening position to what the user asked for
m_end_pos.x = (FLOAT)x;
m_end_pos.y = (FLOAT)y;
m_end_scale.x = zoom;
m_end_scale.y = zoom;
m_end_rotation.z = rot;
m_end_color = col;
m_TweenType = tt;
m_fTweenTime = time;
m_fTimeIntoTween = 0;
}
void Actor::SetTweening( FLOAT time, TweenType tt )
{
// set our tweeen starting and ending values to the current position
m_start_pos = m_end_pos = m_pos;
m_start_scale = m_end_scale = m_scale;
m_start_rotation = m_end_rotation = m_rotation;
m_start_color = m_end_color = m_color;
m_TweenType = tt;
m_fTweenTime = time;
m_fTimeIntoTween = 0;
}
void Actor::SetTweenX( FLOAT x ) { m_end_pos.x = x; }
void Actor::SetTweenY( FLOAT y ) { m_end_pos.y = y; }
void Actor::SetTweenXY( FLOAT x, FLOAT y ) { SetTweenX(x); SetTweenY(y); }
void Actor::SetTweenZoom( FLOAT zoom ) { m_end_scale.x = zoom; m_end_scale.y = zoom; }
void Actor::SetTweenRotationX( FLOAT r ) { m_end_rotation.x = r; }
void Actor::SetTweenRotationY( FLOAT r ) { m_end_rotation.y = r; }
void Actor::SetTweenRotationZ( FLOAT r ) { m_end_rotation.z = r; }
void Actor::SetTweenColor( D3DXCOLOR c ) { m_end_color = c; }
void Actor::ScaleTo( LPRECT pRect, StretchType st )
{
// width and height of rectangle
int rect_width = RECTWIDTH(*pRect);
int rect_height = RECTHEIGHT(*pRect);
// center of the rectangle
int rect_cx = pRect->left + rect_width/2;
int rect_cy = pRect->top + rect_height/2;
// zoom factor needed to scale the Actor to fill the rectangle
FLOAT fNewZoomX = (FLOAT)fabs(rect_width / m_size.x);
FLOAT fNewZoomY = (FLOAT)fabs(rect_height / m_size.y);
if( rect_width < 0 ) SetRotationY( D3DX_PI );
if( rect_height < 0 ) SetRotationX( D3DX_PI );
FLOAT fNewZoom;
switch( st )
{
case cover:
fNewZoom = fNewZoomX>fNewZoomY ? fNewZoomX : fNewZoomY; // use larger zoom
break;
case fit_inside:
fNewZoom = fNewZoomX>fNewZoomY ? fNewZoomY : fNewZoomX; // use smaller zoom
break;
}
SetXY( (FLOAT)rect_cx, (FLOAT)rect_cy );
SetZoom( fNewZoom );
}
void Actor::StretchTo( LPRECT pRect )
{
// width and height of rectangle
int rect_width = RECTWIDTH(*pRect);
int rect_height = RECTHEIGHT(*pRect);
// center of the rectangle
int rect_cx = pRect->left + rect_width/2;
int rect_cy = pRect->top + rect_height/2;
// zoom factor needed to scale the Actor to fill the rectangle
FLOAT fNewZoomX = (FLOAT)fabs(rect_width / m_size.x);
FLOAT fNewZoomY = (FLOAT)fabs(rect_height / m_size.y);
SetXY( (FLOAT)rect_cx, (FLOAT)rect_cy );
m_scale.x = fNewZoomX;
m_scale.y = fNewZoomY;
}
+112
View File
@@ -0,0 +1,112 @@
//-----------------------------------------------------------------------------
// File: Actor.h
//
// Desc: Base class for all objects that appear on the screen.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _ACTOR_H_
#define _ACTOR_H_
#include "RageUtil.h"
#include <d3dx8math.h>
class Actor
{
public:
Actor();
enum TweenType { no_tween, tween_linear, tween_bias_begin, tweening_bias_end };
virtual void Draw() = 0;
virtual void Update( const FLOAT &fDeltaTime );
virtual FLOAT GetX() { return m_pos.x; };
virtual FLOAT GetY() { return m_pos.y; };
virtual void SetX( FLOAT x ) { m_pos.x = x; m_TweenType = no_tween; };
virtual void SetY( FLOAT y ) { m_pos.y = y; m_TweenType = no_tween; };
virtual void SetXY( FLOAT x, FLOAT y ) { m_pos.x = x; m_pos.y = y; m_TweenType = no_tween; };
// height and width vary depending on zoom
virtual FLOAT GetZoomedWidth() { return m_size.x * m_scale.x; }
virtual FLOAT GetZoomedHeight() { return m_size.y * m_scale.y; }
virtual void SetWidth( FLOAT width ){ m_size.x = width; }
virtual void SetHeight( FLOAT height ){ m_size.y = height; }
virtual FLOAT GetZoom() { return m_scale.x; }
virtual void SetZoom( FLOAT zoom ) { m_scale.x = zoom; m_scale.y = zoom; }
virtual FLOAT GetRotation() { return m_rotation.z; }
virtual void SetRotation( FLOAT rot ) { m_rotation.z = rot; }
virtual FLOAT GetRotationX() { return m_rotation.x; }
virtual void SetRotationX( FLOAT rot ) { m_rotation.x = rot; }
virtual FLOAT GetRotationY() { return m_rotation.y; }
virtual void SetRotationY( FLOAT rot ) { m_rotation.y = rot; }
virtual void SetColor( D3DXCOLOR newColor ) { m_color = newColor; };
virtual D3DXCOLOR GetColor() { return m_color; };
virtual void TweenTo( FLOAT time,
FLOAT x, FLOAT y,
FLOAT zoom = 1.0,
FLOAT rot = 0.0,
D3DXCOLOR col = D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ),
TweenType tt = tween_linear );
virtual void SetTweening( FLOAT time, TweenType tt = tween_linear );
virtual void SetTweenX( FLOAT x );
virtual void SetTweenY( FLOAT y );
virtual void SetTweenXY( FLOAT x, FLOAT y );
virtual void SetTweenZoom( FLOAT zoom );
virtual void SetTweenRotationX( FLOAT r );
virtual void SetTweenRotationY( FLOAT r );
virtual void SetTweenRotationZ( FLOAT r );
virtual void SetTweenColor( D3DXCOLOR c );
// NOTE: GetEdge functions don't consider rotation
virtual FLOAT GetLeftEdge() { return m_pos.x - GetZoomedWidth()/2.0f; };
virtual FLOAT GetRightEdge() { return m_pos.x + GetZoomedWidth()/2.0f; };
virtual FLOAT GetTopEdge() { return m_pos.y - GetZoomedHeight()/2.0f; };
virtual FLOAT GetBottomEdge() { return m_pos.y + GetZoomedHeight()/2.0f; };
enum StretchType { fit_inside, cover };
void ScaleToCover( LPRECT rect ) { ScaleTo( rect, cover ); };
void ScaleToFitInside( LPRECT rect ) { ScaleTo( rect, fit_inside); };
void ScaleTo( LPRECT rect, StretchType st );
void StretchTo( LPRECT rect );
protected:
void Init();
D3DXVECTOR2 m_size; // width, height
D3DXVECTOR2 m_pos; // X-Y coordinate of where the center point will appear on screen
D3DXVECTOR3 m_rotation; // X, Y, and Z m_rotation
D3DXVECTOR2 m_scale; // X and Y zooming
D3DXCOLOR m_color;
// start and end position for tweening
D3DXVECTOR2 m_start_pos, m_end_pos;
D3DXVECTOR3 m_start_rotation, m_end_rotation;
D3DXVECTOR2 m_start_scale, m_end_scale;
D3DXCOLOR m_start_color, m_end_color;
// counters for tweening
TweenType m_TweenType;
FLOAT m_fTweenTime; // seconds between Start and End positions/zooms
FLOAT m_fTimeIntoTween; // how long we have been tweening for
};
#endif
+47
View File
@@ -0,0 +1,47 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: Background.cpp
//
// Desc: Cropped version of the song background displayed in Song Select.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#include "Background.h"
#include "RageUtil.h"
const CString sVisDir = "Visualizations\\";
void Background::LoadFromSong( Song& song )
{
Sprite::LoadFromTexture( song.GetBackgroundPath() );
Sprite::StretchTo( CRect(0,0,640,480) );
Sprite::SetColor( D3DXCOLOR(0.7f,0.7f,0.7f,1) );
CStringArray sVisualizationPaths;
GetDirListing( sVisDir + "*.*", sVisualizationPaths );
if( sVisualizationPaths.GetSize() > 0 ) // there is at least one visualization
{
int iIndexRandom = rand() % sVisualizationPaths.GetSize();
m_sprVis.LoadFromTexture( sVisDir + sVisualizationPaths[iIndexRandom] );
m_sprVis.StretchTo( CRect(0,0,640,480) );
m_sprVis.SetBlendMode( TRUE );
//m_sprVis.SetColor( D3DXCOLOR(1,1,1,0.5f) );
}
}
void Background::Update( const FLOAT& fDeltaTime)
{
Sprite::Update( fDeltaTime );
m_sprVis.Update( fDeltaTime );
}
void Background::Draw()
{
Sprite::Draw();
m_sprVis.Draw();
}
+32
View File
@@ -0,0 +1,32 @@
//-----------------------------------------------------------------------------
// File: Background.h
//
// Desc: Cropped version of the song background displayed in Song Select.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _Background_H_
#define _Background_H_
#include "Sprite.h"
#include "Song.h"
class Background : public Sprite
{
public:
void LoadFromSong( Song& song );
void Update( const FLOAT& fDeltaTime);
void Draw();
Sprite m_sprVis;
};
#endif
+61
View File
@@ -0,0 +1,61 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: Banner.cpp
//
// Desc: The song's banner displayed in Song Select.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#include "RageUtil.h"
#include "Banner.h"
BOOL Banner::LoadFromSong( Song &song )
{
BOOL bResult = Sprite::LoadFromTexture( song.GetBannerPath() );
if( bResult )
{
RECT r;
int iImageWidth = this->GetZoomedWidth();
int iImageHeight = this->GetZoomedHeight();
// first find the correct zoom
::SetRect( &r, 0, 0, BANNER_WIDTH, BANNER_HEIGHT );
Sprite::ScaleToCover( &r );
FLOAT fFinalZoom = this->GetZoom();
// find which dimension is larger
BOOL bYDimIsLarger = this->GetZoomedHeight() > BANNER_HEIGHT;
// now crop it
if( !bYDimIsLarger ) // crop X
{
int iScreenPixelsToCrop = (this->GetZoomedWidth() - BANNER_WIDTH) / 2;
int iImagePixelsToCrop = roundf( iScreenPixelsToCrop / fFinalZoom );
RECT rectNewSrc;
::SetRect( &rectNewSrc, iImagePixelsToCrop,
0,
iImageWidth - iImagePixelsToCrop,
iImageHeight );
Sprite::SetCustomSrcRect( rectNewSrc );
}
else // crop Y
{
int iScreenPixelsToCrop = (this->GetZoomedHeight() - BANNER_HEIGHT) / 2;
int iImagePixelsToCrop = roundf( iScreenPixelsToCrop / fFinalZoom );
RECT rectNewSrc;
::SetRect( &rectNewSrc, 0,
iImagePixelsToCrop,
iImageWidth,
iImageHeight - iImagePixelsToCrop );
Sprite::SetCustomSrcRect( rectNewSrc );
}
}
return TRUE;
}
+35
View File
@@ -0,0 +1,35 @@
//-----------------------------------------------------------------------------
// File: Banner.h
//
// Desc: The song's banner displayed in Song Select.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _Banner_H_
#define _Banner_H_
#include "Sprite.h"
#include "Song.h"
#define COMMON_BANNER_TEXTURE_WIDTH 384
#define COMMON_BANNER_TEXTURE_HEIGHT 110
#define BANNER_WIDTH (COMMON_BANNER_TEXTURE_WIDTH/2)
#define BANNER_HEIGHT (COMMON_BANNER_TEXTURE_HEIGHT / 2)
class Banner : public Sprite
{
public:
BOOL LoadFromSong( Song &song);
};
#endif
+112
View File
@@ -0,0 +1,112 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: BitmapText.cpp
//
// Desc: A font class that draws from a bitmap.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#include "BitmapText.h"
#include <assert.h>
#include "IniFile.h"
BitmapText::BitmapText()
{
}
BOOL BitmapText::LoadFromFontFile( CString sFontFilePath )
{
RageLog( "BitmapText::LoadFromFontFile(%s)", sFontFilePath );
m_sFontFilePath = sFontFilePath;
// read font file
IniFile ini;
ini.SetPath( m_sFontFilePath );
if( !ini.ReadFile() )
RageError( ssprintf("Error opening Font file: %s.", m_sFontFilePath) );
CString sTexturePath = ini.GetValue( "Font", "Texture" );
if( sTexturePath == "" )
RageError( ssprintf("Error reading value 'Texture' from %s.", m_sFontFilePath) );
this->LoadFromTexture( sTexturePath );
// fill in our map from characters to frame no
CString sCharacters = ini.GetValue( "Font", "Characters" );
if( sCharacters == "" )
RageError( ssprintf("Error reading value 'Characters' from %s.", m_sFontFilePath) );
for( int i=0; i<sCharacters.GetLength(); i++ )
{
TCHAR c = sCharacters[i];
m_mapCharToFrameNo[c] = i;
}
// Validate that the number of characters we read in is the same as
// the number of frames in the texture.
if( sCharacters.GetLength() != (int)this->GetNumStates() )
RageError( ssprintf("The Font %s specifies %d characters, but the Texture has %d frames.",
m_sFontFilePath, sCharacters.GetLength(), (int)this->GetNumStates()) );
ResetWidthAndHeight();
return TRUE;
}
void BitmapText::SetText( CString sText )
{
m_sText = sText;
ResetWidthAndHeight();
}
void BitmapText::Draw()
{
//RageLog( "BitmapText::Draw()" );
// UGLY!!!!
TCHAR c;
UINT uFrameNo;
int iNumChars = m_sText.GetLength();
int iLeftEdge = this->GetLeftEdge();
int iOriginalCenterX = (int)this->GetX();
FLOAT fOriginalWidth = m_size.x;
int iFrameWidth = (int)( m_pTexture->GetFrameWidth() * this->GetZoom() );
m_size.x = (FLOAT)iFrameWidth;
// draw each character in the string
for( int i=0; i<iNumChars; i++ )
{
c = m_sText[i];
// Get what frame in the animation this character is.
if( !m_mapCharToFrameNo.Lookup(c, uFrameNo) )
uFrameNo = 0;
this->SetState( uFrameNo );
this->SetX( (int)(iLeftEdge + iFrameWidth*(i+0.5f)) );
Sprite::Draw();
}
this->SetX( iOriginalCenterX );
m_size.x = fOriginalWidth;
}
void BitmapText::ResetWidthAndHeight()
{
m_size.x = (FLOAT)m_pTexture->GetFrameWidth() * m_sText.GetLength();
m_size.y = (FLOAT)m_pTexture->GetFrameHeight();
}
+42
View File
@@ -0,0 +1,42 @@
//-----------------------------------------------------------------------------
// File: BitmapText.h
//
// Desc: A font class that draws from a bitmap.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _BITMAPTEXT_H_
#define _BITMAPTEXT_H_
//#include "Actor.h"
#include "Sprite.h"
#include "BitmapText.h"
class BitmapText : public Sprite
{
public:
BitmapText();
// virtual ~BitmapText();
BOOL LoadFromFontFile( CString sFontFilePath );
void SetText( CString sText );
CString GetText() { return m_sText; };
virtual void Draw();
protected:
void ResetWidthAndHeight();
CString m_sFontFilePath;
CString m_sText; // the string that the font is displaying
//Sprite m_Sprite; // holder for the graphic
CMap<TCHAR, TCHAR&, UINT, UINT&> m_mapCharToFrameNo;
};
#endif
+83
View File
@@ -0,0 +1,83 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: Combo.cpp
//
// Desc: Combo counter that displays while dancing.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#include "RageUtil.h"
#include "Combo.h"
#define CENTER_X 320
#define CENTER_Y 240
#define FONT "Fonts\\Font - Arial Bold numbers 30px.font"
#define COMBO_TWEEN_TIME 0.5f
#define COMBO_SPRITE "Sprites\\Combo.sprite"
#define COMBO_Y (CENTER_Y+60)
Combo::Combo()
{
m_bVisible = FALSE;
m_sprCombo.LoadFromSpriteFile( COMBO_SPRITE );
m_textNum.LoadFromFontFile( FONT );
m_textNum.SetText( "" );
SetX( CENTER_X );
}
Combo::~Combo()
{
}
void Combo::SetX( int iNewX )
{
m_sprCombo.SetXY( iNewX+40, COMBO_Y );
m_textNum.SetXY( iNewX-50, COMBO_Y );
}
void Combo::Update( const FLOAT &fDeltaTime )
{
m_sprCombo.Update( fDeltaTime );
m_textNum.Update( fDeltaTime );
}
void Combo::Draw()
{
if( m_bVisible )
{
m_textNum.Draw();
m_sprCombo.Draw();
}
}
void Combo::SetCombo( int iNum )
{
if( iNum <= 4 )
{
m_bVisible = FALSE;
}
else
{
m_bVisible = TRUE;
m_textNum.SetText( ssprintf("%d", iNum) );
m_textNum.SetZoom( 1.0f + iNum/200.0f );
m_textNum.TweenTo( COMBO_TWEEN_TIME, m_textNum.GetX(), m_textNum.GetY() );
}
}
+40
View File
@@ -0,0 +1,40 @@
//-----------------------------------------------------------------------------
// File: Combo.h
//
// Desc: Combo counter that displays while dancing.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _COMBO_H_
#define _COMBO_H_
#include "Sprite.h"
#include "BitmapText.h"
class Combo
{
public:
Combo();
~Combo();
void SetX( int iNewX );
void Update( const FLOAT &fDeltaTime );
void Draw();
void SetCombo( int iNum );
private:
BOOL m_bVisible;
Sprite m_sprCombo;
BitmapText m_textNum;
};
#endif
+277
View File
@@ -0,0 +1,277 @@
//-----------------------------------------------------------------------------
// File: IniFile.cpp
//
// Desc: wrapper for reading and writing an .ini file.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#include "stdafx.h"
#include "IniFile.h"
#include "fstream.h"
/////////////////////////////////////////////////////////////////////
// Construction/Destruction
/////////////////////////////////////////////////////////////////////
//default constructor
IniFile::IniFile()
{
}
//constructor, can specify pathname here instead of using SetPath later
IniFile::IniFile(CString inipath)
{
path = inipath;
}
//default destructor
IniFile::~IniFile()
{
}
/////////////////////////////////////////////////////////////////////
// Public Functions
/////////////////////////////////////////////////////////////////////
//sets path of ini file to read and write from
void IniFile::SetPath(CString newpath)
{
path = newpath;
}
//reads ini file specified using IniFile::SetPath()
//returns true if successful, false otherwise
BOOL IniFile::ReadFile()
{
CFile file;
CFileStatus status;
if( !file.GetStatus(path,status) )
return FALSE;
ifstream inifile;
CString readinfo;
inifile.open(path);
int curkey = -1, curval = -1;
if( inifile.fail() )
{
error = "Unable to open ini file.";
return FALSE;
}
CString keyname, valuename, value;
CString temp;
while( getline(inifile,readinfo) )
{
if( readinfo != "" )
{
if( readinfo[0] == '[' && readinfo[readinfo.GetLength()-1] == ']' ) //if a section heading
{
keyname = readinfo;
keyname.TrimLeft('[');
keyname.TrimRight(']');
}
else //if a value
{
valuename = readinfo.Left(readinfo.Find("="));
value = readinfo.Right(readinfo.GetLength()-valuename.GetLength()-1);
SetValue(keyname,valuename,value);
}
}
}
inifile.close();
return 1;
}
//writes data stored in class to ini file
void IniFile::WriteFile()
{
ofstream inifile;
inifile.open(path);
// foreach key
for( int keynum = 0; keynum <= names.GetUpperBound(); keynum++ )
{
inifile << '[' << names[keynum] << ']' << endl;
CMapStringToString &map = keys[keynum];
// for each value_name/value pair
for( POSITION pos = map.GetStartPosition(); pos != NULL; )
{
CString value_name;
CString value;
map.GetNextAssoc( pos, value_name, value );
inifile << value_name << "=" << value << endl;
}
inifile << endl;
}
inifile.close();
}
//deletes all stored ini data
void IniFile::Reset()
{
keys.SetSize(0);
names.SetSize(0);
}
//returns number of keys currently in the ini
int IniFile::GetNumKeys()
{
return keys.GetSize();
}
//returns a refernce to the key for direct modification
CMapStringToString& IniFile::GetKeyRef( CString keyname )
{
int keynum = FindKey(keyname);
if (keynum == -1)
return keys[0];
else
return keys[keynum];
}
//returns number of values stored for specified key, or -1 if key found
int IniFile::GetNumValues(CString keyname)
{
int keynum = FindKey(keyname);
if (keynum == -1)
return -1;
else
return keys[keynum].GetCount();
}
//gets value of [keyname] valuename =
//overloaded to return CString, int, and double
CString IniFile::GetValue(CString keyname, CString valuename)
{
int keynum = FindKey(keyname);//, valuenum = FindValue(keynum,valuename);
if( keynum == -1 )
{
error = "Unable to locate specified key.";
return "";
}
CMapStringToString &map = keys[keynum];
CString value;
if( !map.Lookup(valuename, value) )
{
error = "Unable to locate specified value.";
return "";
}
return value;
}
//gets value of [keyname] valuename =
//overloaded to return CString, int, and double
int IniFile::GetValueI(CString keyname, CString valuename)
{
return atoi( GetValue(keyname,valuename) );
}
//gets value of [keyname] valuename =
//overloaded to return CString, int, and double
double IniFile::GetValueF(CString keyname, CString valuename)
{
return atof( GetValue(keyname, valuename) );
}
//sets value of [keyname] valuename =.
//specify the optional paramter as false (0) if you do not want it to create
//the key if it doesn't exist. Returns true if data entered, false otherwise
//overloaded to accept CString, int, and double
BOOL IniFile::SetValue(CString keyname, CString valuename, CString value, BOOL create)
{
int keynum = FindKey(keyname);
if( keynum == -1 ) //if key doesn't exist
{
if( !create ) //and user does not want to create it,
return FALSE; //stop entering this key
names.SetSize(names.GetSize()+1);
keys.SetSize(keys.GetSize()+1);
keynum = names.GetSize()-1;
names[keynum] = keyname;
}
// insert value
CMapStringToString &map = keys[keynum];
CString oldvalue;
if( !map.Lookup(valuename, oldvalue) && !create )
return FALSE;
map[valuename] = value;
return TRUE;
}
//sets value of [keyname] valuename =.
//specify the optional paramter as false (0) if you do not want it to create
//the key if it doesn't exist. Returns true if data entered, false otherwise
//overloaded to accept CString, int, and double
BOOL IniFile::SetValueI(CString keyname, CString valuename, int value, BOOL create)
{
CString temp;
temp.Format("%d",value);
return SetValue(keyname, valuename, temp, create);
}
//sets value of [keyname] valuename =.
//specify the optional paramter as false (0) if you do not want it to create
//the key if it doesn't exist. Returns true if data entered, false otherwise
//overloaded to accept CString, int, and double
BOOL IniFile::SetValueF(CString keyname, CString valuename, double value, BOOL create)
{
CString temp;
temp.Format("%e",value);
return SetValue(keyname, valuename, temp, create);
}
//deletes specified value
//returns true if value existed and deleted, false otherwise
BOOL IniFile::DeleteValue(CString keyname, CString valuename)
{
int keynum = FindKey(keyname);
if( keynum == -1 )
return FALSE;
CMapStringToString &map = keys[keynum];
return map.RemoveKey( valuename );
}
//deletes specified key and all values contained within
//returns true if key existed and deleted, false otherwise
BOOL IniFile::DeleteKey(CString keyname)
{
int keynum = FindKey(keyname);
if (keynum == -1)
return 0;
keys.RemoveAt(keynum);
names.RemoveAt(keynum);
return 1;
}
/////////////////////////////////////////////////////////////////////
// Private Functions
/////////////////////////////////////////////////////////////////////
//returns index of specified key, or -1 if not found
int IniFile::FindKey(CString keyname)
{
int keynum = 0;
while ( keynum < keys.GetSize() && names[keynum] != keyname)
keynum++;
if (keynum == keys.GetSize())
return -1;
return keynum;
}
//overloaded from original getline to take CString
istream & IniFile:: getline(istream & is, CString & str)
{
char buf[2048];
is.getline(buf,2048);
str = buf;
return is;
}
+110
View File
@@ -0,0 +1,110 @@
//-----------------------------------------------------------------------------
// File: IniFile.h
//
// Desc: wrapper for reading and writing an .ini file.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _INIFILE_H_
#define _INIFILE_H_
#include <afxtempl.h>
#include <iostream.h>
class IniFile
{
//all private variables
private:
//stores pathname of ini file to read/write
CString path;
//all keys are of this time
typedef CMapStringToString key;
//list of keys in ini
CArray<key, key> keys;
//corresponding list of keynames
CArray<CString, CString> names;
//all private functions
private:
//overloaded to take CString
istream & getline( istream & is, CString & str );
//returns index of specified key, or -1 if not found
int FindKey(CString keyname);
//public variables
public:
//will contain error info if one occurs
//ended up not using much, just in ReadFile and GetValue
CString error;
//public functions
public:
//default constructor
IniFile();
//constructor, can specify pathname here instead of using SetPath later
IniFile(CString inipath);
//default destructor
virtual ~IniFile();
//sets path of ini file to read and write from
void SetPath(CString newpath);
//reads ini file specified using IniFile::SetPath()
//returns true if successful, false otherwise
BOOL ReadFile();
//writes data stored in class to ini file
void WriteFile();
//deletes all stored ini data
void Reset();
//returns number of keys currently in the ini
int GetNumKeys();
//returns a refernce to the key for direct modification
CMapStringToString& GetKeyRef( CString keyname );
//returns number of values stored for specified key
int GetNumValues( CString keyname );
//gets value of [keyname] valuename =
//overloaded to return CString, int, and double,
//returns "", or 0 if key/value not found. Sets error member to show problem
CString GetValue(CString keyname, CString valuename);
int GetValueI(CString keyname, CString valuename);
double GetValueF(CString keyname, CString valuename);
//sets value of [keyname] valuename =.
//specify the optional paramter as false (0) if you do not want it to create
//the key if it doesn't exist. Returns true if data entered, false otherwise
//overloaded to accept CString, int, and double
BOOL SetValue(CString key, CString valuename, CString value, BOOL create = 1);
BOOL SetValueI(CString key, CString valuename, int value, BOOL create = 1);
BOOL SetValueF(CString key, CString valuename, double value, BOOL create = 1);
//deletes specified value
//returns true if value existed and deleted, false otherwise
BOOL DeleteValue(CString keyname, CString valuename);
//deletes specified key and all values contained within
//returns true if key existed and deleted, false otherwise
BOOL DeleteKey(CString keyname);
};
#endif
+104
View File
@@ -0,0 +1,104 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: Judgement.h
//
// Desc: Feedback about the last step that appears in the middle of a player's stream of arrows.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#include "RageUtil.h"
#include "Judgement.h"
#define CENTER_X 320
#define CENTER_Y 240
#define JUDGEMENT_DISPLAY_TIME 1.0f
#define JUDGEMENT_SPRITE "Sprites\\Judgement.sprite"
#define JUDGEMENT_Y CENTER_Y
Judgement::Judgement() :
m_fDisplayTimeLeft( 0.0 )
{
m_sprJudgement.LoadFromSpriteFile( JUDGEMENT_SPRITE );
SetX( CENTER_X );
}
Judgement::~Judgement()
{
}
void Judgement::SetX( int iNewX )
{
m_sprJudgement.SetXY( iNewX, CENTER_Y );
}
void Judgement::Update( const FLOAT &fDeltaTime )
{
if( m_fDisplayTimeLeft > 0.0 )
m_fDisplayTimeLeft -= fDeltaTime;
m_sprJudgement.Update( fDeltaTime );
}
void Judgement::Draw()
{
// RageLog( "Judgement::Draw()" );
if( m_fDisplayTimeLeft > 0.0 )
m_sprJudgement.Draw();
}
void Judgement::Perfect()
{
RageLog( "Judgement::Perfect()" );
m_sprJudgement.SetState( 0 );
TweenFromBigToSmall();
}
void Judgement::Great()
{
m_sprJudgement.SetState( 1 );
TweenFromBigToSmall();
}
void Judgement::Good()
{
m_sprJudgement.SetState( 2 );
TweenFromBigToSmall();
}
void Judgement::Boo()
{
m_sprJudgement.SetState( 3 );
TweenFromBigToSmall();
}
void Judgement::Miss()
{
m_sprJudgement.SetState( 4 );
TweenFromBigToSmall();
}
void Judgement::TweenFromBigToSmall()
{
m_fDisplayTimeLeft = JUDGEMENT_DISPLAY_TIME;
m_sprJudgement.SetZoom( 1.5f );
m_sprJudgement.TweenTo( JUDGEMENT_DISPLAY_TIME/2.0,
m_sprJudgement.GetX(),
m_sprJudgement.GetY() );
}
+45
View File
@@ -0,0 +1,45 @@
//-----------------------------------------------------------------------------
// File: Judgement.h
//
// Desc: Feedback about the last step that appears in the middle of a player's stream of arrows.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _JUDGEMENT_H_
#define _JUDGEMENT_H_
#include "Sprite.h"
class Judgement
{
public:
Judgement();
~Judgement();
void SetX( int iNewX );
void Update( const FLOAT &fDeltaTime );
void Draw();
void Perfect();
void Great();
void Good();
void Boo();
void Miss();
private:
void TweenFromBigToSmall();
FLOAT m_fDisplayTimeLeft;
Sprite m_sprJudgement;
};
#endif
+102
View File
@@ -0,0 +1,102 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: LifeMeter.cpp
//
// Desc: LifeMeter counter that displays while dancing.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#include "RageUtil.h"
#include "LifeMeter.h"
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define CENTER_X 320
#define CENTER_Y 240
#define FONT "Fonts\\Font - Arial Bold numbers 30px.font"
#define NUM_PILLS 17
//#define LIFEMETER_TWEEN_TIME 0.5f
#define LIFEMETER_FRAME_SPRITE "Sprites\\Life Meter Frame.sprite"
#define LIFEMETER_PILLS_SPRITE "Sprites\\Life Meter Pills.sprite"
#define LIFEMETER_Y 30
#define LIFEMETER_PILLS_Y (LIFEMETER_Y+2)
const FLOAT PILL_OFFSET[NUM_PILLS] = {
0.3f, 0.7f, 1.0f, 0.7f, 0.3f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
};
LifeMeter::LifeMeter() :
m_fLifePercentage( 0.5f )
{
m_sprLifeMeterFrame.LoadFromSpriteFile( LIFEMETER_FRAME_SPRITE );
m_sprLifeMeterPills.LoadFromSpriteFile( LIFEMETER_PILLS_SPRITE );
SetX( CENTER_X );
}
LifeMeter::~LifeMeter()
{
}
void LifeMeter::SetX( FLOAT iNewX )
{
m_sprLifeMeterFrame.SetXY( iNewX, LIFEMETER_Y );
m_sprLifeMeterPills.SetXY( iNewX, LIFEMETER_PILLS_Y );
}
void LifeMeter::Update( const FLOAT &fDeltaTime )
{
m_sprLifeMeterFrame.Update( fDeltaTime );
m_sprLifeMeterPills.Update( fDeltaTime );
}
void LifeMeter::Draw( FLOAT fSongBeat )
{
FLOAT fBeatPercentage = fSongBeat - (int)fSongBeat;
int iOffsetStart = roundf( NUM_PILLS*fBeatPercentage );
m_sprLifeMeterFrame.Draw();
FLOAT iX = m_sprLifeMeterFrame.GetLeftEdge() + 27;
int iNumPills = (int)(m_sprLifeMeterPills.GetNumStates() * m_fLifePercentage);
int iPillWidth = m_sprLifeMeterPills.GetZoomedWidth();
for( int i=0; i<iNumPills; i++ )
{
m_sprLifeMeterPills.SetState( i );
m_sprLifeMeterPills.SetX( iX );
int iOffsetNum = (iOffsetStart - i + NUM_PILLS) % NUM_PILLS;
int iOffset = roundf( PILL_OFFSET[iOffsetNum] * m_fLifePercentage * 8.0f );
m_sprLifeMeterPills.SetY( LIFEMETER_PILLS_Y - iOffset );
m_sprLifeMeterPills.Draw();
iX += iPillWidth;
}
}
void LifeMeter::SetLife( FLOAT fNewLife )
{
assert( fNewLife >= 0.0f && fNewLife <= 1.0f );
m_fLifePercentage = fNewLife;
if( fNewLife >= 0.9f )
m_sprLifeMeterFrame.SetEffectCamelion( 5, D3DXCOLOR(0.2f,0.2f,0.2f,1), D3DXCOLOR(1,1,1,1) );
else if( fNewLife < 0.25f )
m_sprLifeMeterFrame.SetEffectCamelion( 5, D3DXCOLOR(1,0.8f,0.8f,1), D3DXCOLOR(1,0.2f,0.2f,1) );
else
m_sprLifeMeterFrame.SetEffectNone();
}
+39
View File
@@ -0,0 +1,39 @@
//-----------------------------------------------------------------------------
// File: LifeMeter.h
//
// Desc: LifeMeter display at the bottom of the screen while dancing.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _LIFEMETER_H_
#define _LIFEMETER_H_
#include "Sprite.h"
class LifeMeter
{
public:
LifeMeter();
~LifeMeter();
void SetX( FLOAT iNewX );
void Update( const FLOAT &fDeltaTime );
void Draw( FLOAT fSongBeat );
void SetLife( FLOAT fNewLife );
private:
Sprite m_sprLifeMeterFrame;
Sprite m_sprLifeMeterPills;
FLOAT m_fLifePercentage;
};
#endif
+270
View File
@@ -0,0 +1,270 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: Player.cpp
//
// 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.
//-----------------------------------------------------------------------------
#include "Util.h"
#include "Math.h" // for fabs()
#include "Player.h"
#define STEP_DOWN_TIME 0.05f
#define SCORE_ADD_PERFECT 700
#define SCORE_ADD_GREAT 400
#define SCORE_ADD_GOOD 200
#define SCORE_ADD_BOO 100
#define SCORE_MULT_PERFECT 1.007f
#define SCORE_MULT_GREAT 1.004f
#define SCORE_MULT_GOOD 1.002f
#define SCORE_MULT_BOO 1.001f
#define LIFE_PERFECT 0.015f
#define LIFE_GREAT 0.008f
#define LIFE_GOOD 0.000f
#define LIFE_BOO -0.015f
#define LIFE_MISS -0.060f
void Player::Set( GrayArrows *pGA, ColorArrows *pCA,
Judgement *pJ, Combo *pC,
Score *pS, LifeMeter *pL,
Steps steps, FLOAT fMaxBeatDifference )
{
RageLog( "Player::Set()" );
m_pGA = pGA;
m_pCA = pCA;
m_pJudgement = pJ;
m_pCombo = pC;
m_pScore = pS;
m_pLifeMeter = pL;
if( m_pLifeMeter ) m_pLifeMeter->SetLife( m_fLife );
m_Steps = steps;
m_StepScore.SetSize( MAX_STEP_ELEMENTS );
for( int i=0; i<m_StepScore.GetSize(); i++ )
m_StepScore[i] = no_score;
m_fMaxBeatDifference = fMaxBeatDifference;
}
void Player::Update( const FLOAT &fDeltaTime )
{
//RageLog( "Player::Update(%f)", fDeltaTime );
for( int i=0; i<2; i++ ) {
for( int j=0; j<4; j++ ) {
if( m_fStepCountDown[i][j] > 0.0 )
m_fStepCountDown[i][j] -= fDeltaTime;
}
}
int iNumMisses = UpdateMissedStepsOlderThan( m_fSongBeat-m_fMaxBeatDifference );
if( iNumMisses > 0 )
{
m_pJudgement->Miss();
m_iCurCombo = 0;
m_pCombo->SetCombo( 0 );
m_fLife += LIFE_MISS * iNumMisses;
if( m_fLife < 0.0f )
m_fLife = 0.0f;
m_pLifeMeter->SetLife( m_fLife );
}
}
void Player::StepOn( Step player_step )
{
// DebugLog( CString("Player::Step() ") + padStepL.ToString() + CString(" ") + padStepR.ToString() );
// Fill the "step buffer" so that the player doesn't have to hit 2 buttons
// at the exact same time in order to hit a two direction step
if( player_step & STEP_P1_LEFT ) m_fStepCountDown[0][0] = STEP_DOWN_TIME;
if( player_step & STEP_P1_DOWN ) m_fStepCountDown[0][1] = STEP_DOWN_TIME;
if( player_step & STEP_P1_UP ) m_fStepCountDown[0][2] = STEP_DOWN_TIME;
if( player_step & STEP_P1_RIGHT ) m_fStepCountDown[0][3] = STEP_DOWN_TIME;
// make the gray foot steps on the screen follow the input
m_pGA->StepOn( player_step );
HandleStep();
}
void Player::HandleStep()
{
//RageLog( "Player::HandleStep()" );
// This is being called just after a step, so we know at
// least one direction is being depressed.
// Build pad steps to check against
Step player_step = 0x0000;
if( m_fStepCountDown[0][0] > 0.0f ) player_step |= STEP_P1_LEFT;
if( m_fStepCountDown[0][1] > 0.0f ) player_step |= STEP_P1_DOWN;
if( m_fStepCountDown[0][2] > 0.0f ) player_step |= STEP_P1_UP;
if( m_fStepCountDown[0][3] > 0.0f ) player_step |= STEP_P1_RIGHT;
// find the closest step that our PadSteps cover
//RageLog( "I ask: What step %s, %s, is near %f (within %f )",
// padStepL.ToString(),
// padStepR.ToString(),
// m_fSongBeat,
// MAX_BEAT_DIFFERENCE );
int iIndexOfClosest =
m_Steps.GetIndexOfClosestStep( m_fSongBeat,
m_fMaxBeatDifference,
player_step );
if( iIndexOfClosest == -1 ) // if no steps in our specified range are covered
return;
FLOAT fStepBeat = StepIndexToBeat( iIndexOfClosest ); // this is the beat of the note we stepped on
//RageLog( "GetClosestMatch returned: iIndexOfClosest = %d (%s, %s, fStepBeat: %f)",
// iIndexOfClosest,
// m_Steps.StepsLeft [iIndexOfClosest].ToString(),
// m_Steps.StepsRight[iIndexOfClosest].ToString(),
// fStepBeat );
FLOAT fBeatsUntilStep = fStepBeat - m_fSongBeat;
FLOAT fPercentFromPerfect = (FLOAT)fabs( fBeatsUntilStep / m_fMaxBeatDifference );
RageLog( "fBeatsUntilStep: %f, fPercentFromPerfect: %f",
fBeatsUntilStep, fPercentFromPerfect );
// step on the note so that it can't be stepped on any more
m_Steps.StatusArray[iIndexOfClosest] = stepped_on;
// compute what the score should be for the note we stepped on
StepScore &score = m_StepScore[iIndexOfClosest];
if( fPercentFromPerfect < 0.20f )
score = perfect;
else if( fPercentFromPerfect < 0.45f )
score = great;
else if( fPercentFromPerfect < 0.75f )
score = good;
else
score = boo;
// update the judgement display
switch( score )
{
case perfect: m_pJudgement->Perfect(); break;
case great: m_pJudgement->Great(); break;
case good: m_pJudgement->Good(); break;
case boo: m_pJudgement->Boo(); break;
}
// update the combo display
switch( score )
{
case perfect:
case great:
m_iCurCombo++;
m_pCombo->SetCombo( m_iCurCombo );
break;
case good:
case boo:
// combo stopped
if( m_iCurCombo > m_iMaxCombo )
m_iMaxCombo = m_iCurCombo;
m_iCurCombo = 0;
m_pCombo->SetCombo( m_iCurCombo );
break;
}
// remove the arrows from the ColorArrow columns if the score is high enough
if( score == perfect || score == great )
{
m_pCA->StepOn( BeatToStepIndex(fStepBeat) );
}
// update running score
switch( score )
{
case perfect: m_fScore += SCORE_ADD_PERFECT; m_fScore *= SCORE_MULT_PERFECT; break;
case great: m_fScore += SCORE_ADD_GREAT; m_fScore *= SCORE_MULT_GREAT; break;
case good: m_fScore += SCORE_ADD_GOOD; m_fScore *= SCORE_MULT_GOOD; break;
case boo: m_fScore += SCORE_ADD_BOO; m_fScore *= SCORE_MULT_BOO; break;
case miss: break;
}
// update life meter
switch( score )
{
case perfect: m_fLife += LIFE_PERFECT; break;
case great: m_fLife += LIFE_GREAT; break;
case good: m_fLife += LIFE_GOOD; break;
case boo: m_fLife += LIFE_BOO; break;
}
if( m_fLife < 0.0f ) m_fLife = 0.0f;
else if( m_fLife > 1.0f ) m_fLife = 1.0f;
m_pScore->SetScore( m_fScore );
m_pLifeMeter->SetLife( m_fLife );
}
int Player::UpdateMissedStepsOlderThan( FLOAT iMissIfOlderThanThisBeat )
{
//RageLog( "Steps::UpdateMissedStepsOlderThan(%f)", iMissIfOlderThanThisBeat );
int iMissIfOlderThanThisIndex = BeatToStepIndex( iMissIfOlderThanThisBeat );
int iNumMissesFound = 0;
for( int i=0; i<iMissIfOlderThanThisIndex; i++ )
{
// RageLog( "Step %d: status == %d, score == %d", i, StatusArray[i], Score[i] );
if( m_Steps.StatusArray[i] == not_stepped_on && m_StepScore[i] == no_score )
{
m_StepScore[i] = miss;
iNumMissesFound++;
}
}
return iNumMissesFound;
}
ScoreSummary Player::GetScoreSummary()
{
ScoreSummary scoreSummary;
for( int i=0; i<m_StepScore.GetSize(); i++ )
{
switch( m_StepScore[i] )
{
case perfect: scoreSummary.perfect++; break;
case great: scoreSummary.great++; break;
case good: scoreSummary.good++; break;
case boo: scoreSummary.boo++; break;
case miss: scoreSummary.miss++; break;
case no_score: break;
}
}
scoreSummary.max_combo = m_iMaxCombo;
scoreSummary.score = m_fScore;
return scoreSummary;
}
+99
View File
@@ -0,0 +1,99 @@
//-----------------------------------------------------------------------------
// File: Player.h
//
// 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.
//-----------------------------------------------------------------------------
#ifndef _PLAYER_H_
#define _PLAYER_H_
#include "GameOptions.h"
#include "GrayArrows.h"
#include "Steps.h"
#include "ColorArrows.h"
#include "Judgement.h"
#include "Combo.h"
#include "Score.h"
#include "LifeMeter.h"
enum StepScore { no_score, perfect, great, good, boo, miss };
class Player
{
public:
Player()
{
m_fSongBeat = 0.0;
for( int i=0; i<2; i++ ) {
for( int j=0; j<4; j++ ) {
m_fStepCountDown[i][j] = 0.0;
}
}
m_pGA = NULL;
m_pCA = NULL;
m_pJudgement = NULL;
m_pCombo = NULL;
m_pScore = NULL;
m_pLifeMeter = NULL;
m_iCurCombo = 0;
m_iMaxCombo = 0;
m_fScore = 0.0f;
m_fLife = 0.50f;
};
~Player() {};
void Set( GrayArrows *pGA, ColorArrows *pCA,
Judgement *pJ, Combo *pC,
Score *pS, LifeMeter *pL,
Steps steps, FLOAT fMaxBeatDifference );
void SetSongBeat( const FLOAT &fSongBeat ) { m_fSongBeat = fSongBeat; };
void Update( const FLOAT &fDeltaTime );
void StepOn( Step player_step );
void HandleStep();
int UpdateMissedStepsOlderThan( FLOAT iMissIfOlderThanThisBeat );
FLOAT GetLife() { return m_fLife; };
ScoreSummary GetScoreSummary();
private:
FLOAT m_fSongBeat;
FLOAT m_fMaxBeatDifference;
// step cache (so player doesn't have to hit buttons
// on exact same update in order to hit two arrow notes)
FLOAT m_fStepCountDown[2][4];
GrayArrows *m_pGA;
ColorArrows *m_pCA;
Judgement *m_pJudgement;
Combo *m_pCombo;
Score *m_pScore;
LifeMeter *m_pLifeMeter;
Steps m_Steps;
CArray<StepScore, StepScore&> m_StepScore;
int m_iCurCombo;
int m_iMaxCombo;
FLOAT m_fLife;
FLOAT m_fScore;
};
#endif
+99
View File
@@ -0,0 +1,99 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: RageBitmapTexture.cpp
//
// Desc:
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// In-line Links
//-----------------------------------------------------------------------------
//#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "dxerr8.lib")
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include "RageBitmapTexture.h"
#include "dxerr8.h"
#include "DXUtil.h"
#include "RageUtil.h"
//#include <stdio.h>
#include <assert.h>
//-----------------------------------------------------------------------------
// RageBitmapTexture constructor
//-----------------------------------------------------------------------------
RageBitmapTexture::RageBitmapTexture( LPRageScreen pScreen, CString sFilePath ) :
RageTexture( pScreen, sFilePath )
{
// RageLog( "RageBitmapTexture::RageBitmapTexture()" );
Create();
CreateFrameRects();
}
RageBitmapTexture::~RageBitmapTexture()
{
SAFE_RELEASE(m_pd3dTexture);
}
//-----------------------------------------------------------------------------
// GetTexture
//-----------------------------------------------------------------------------
LPDIRECT3DTEXTURE8 RageBitmapTexture::GetD3DTexture()
{
return m_pd3dTexture;
}
VOID RageBitmapTexture::Create()
{
HRESULT hr;
D3DXIMAGE_INFO ddii;
// load texture
if (FAILED (hr = D3DXCreateTextureFromFileEx(
m_pd3dDevice,
m_sFilePath,
D3DX_DEFAULT, D3DX_DEFAULT,
D3DX_DEFAULT,
0,
D3DFMT_A4R4G4B4, //D3DFMT_UNKNOWN, // get format from source
D3DPOOL_MANAGED,
D3DX_FILTER_NONE, // don't blow up the image to the texure size
D3DX_FILTER_NONE,
0, // no color key
&ddii,
NULL, // no palette
&m_pd3dTexture ) ) )
RageErrorHr( ssprintf("D3DXCreateTextureFromFileEx() failed for file '%s'.", m_sFilePath), hr );
m_uImageWidth = ddii.Width;
m_uImageHeight= ddii.Height;
// D3DXCreateTexture can silently change the parameters on us
D3DSURFACE_DESC ddsd;
if ( FAILED( hr = m_pd3dTexture->GetLevelDesc( 0, &ddsd ) ) )
RageErrorHr( "Could not get level Description of D3DX texture!", hr );
m_uTextureWidth = ddsd.Width;
m_uTextureHeight = ddsd.Height;
m_TextureFormat = ddsd.Format;
// if (m_TextureFormat != D3DFMT_A8R8G8B8 &&
// m_TextureFormat != D3DFMT_A1R5G5B5) {
// DXTRACE_ERR(TEXT("Texture is format we can't handle! Format = 0x%x"), m_TextureFormat);
// return E_FAIL;
// }
}
+41
View File
@@ -0,0 +1,41 @@
//-----------------------------------------------------------------------------
// File: RageBitmapTexture.h
//
// Desc:
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
class RageBitmapTexture;
typedef RageBitmapTexture* LPRageBitmapTexture;
#ifndef _RageBitmapTexture_H_
#define _RageBitmapTexture_H_
#include "RageScreen.h"
#include <d3dx8.h>
#include <assert.h>
//#include <d3d8types.h>
//-----------------------------------------------------------------------------
// RageBitmapTexture Class Declarations
//-----------------------------------------------------------------------------
class RageBitmapTexture : public RageTexture
{
public:
RageBitmapTexture( LPRageScreen pScreen, CString sFilePath );
~RageBitmapTexture();
virtual LPDIRECT3DTEXTURE8 GetD3DTexture();
protected:
virtual VOID Create();
};
#endif
+647
View File
@@ -0,0 +1,647 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: RageInput.cpp
//
// Desc: DirectInput wrapper class
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// In-line Links
//-----------------------------------------------------------------------------
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "dxguid.lib")
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <windows.h>
#include <dinput.h>
#include "RageInput.h"
#include "RageUtil.h"
LPRageInput INPUT = NULL;
BOOL RageRawInput::LookupChar( TCHAR &char_out ) const
{
switch( button )
{
case DIK_1: char_out = '1'; break;
case DIK_2: char_out = '2'; break;
case DIK_3: char_out = '3'; break;
case DIK_4: char_out = '4'; break;
case DIK_5: char_out = '5'; break;
case DIK_6: char_out = '6'; break;
case DIK_7: char_out = '7'; break;
case DIK_8: char_out = '8'; break;
case DIK_9: char_out = '9'; break;
case DIK_0: char_out = '0'; break;
case DIK_MINUS: char_out = '-'; break;
case DIK_EQUALS: char_out = '='; break;
case DIK_Q: char_out = 'Q'; break;
case DIK_W: char_out = 'W'; break;
case DIK_E: char_out = 'E'; break;
case DIK_R: char_out = 'R'; break;
case DIK_T: char_out = 'T'; break;
case DIK_Y: char_out = 'Y'; break;
case DIK_U: char_out = 'U'; break;
case DIK_I: char_out = 'I'; break;
case DIK_O: char_out = 'O'; break;
case DIK_P: char_out = 'P'; break;
case DIK_LBRACKET: char_out = '['; break;
case DIK_RBRACKET: char_out = ']'; break;
case DIK_A: char_out = 'A'; break;
case DIK_S: char_out = 'S'; break;
case DIK_D: char_out = 'D'; break;
case DIK_F: char_out = 'F'; break;
case DIK_G: char_out = 'G'; break;
case DIK_H: char_out = 'H'; break;
case DIK_J: char_out = 'J'; break;
case DIK_K: char_out = 'K'; break;
case DIK_L: char_out = 'L'; break;
case DIK_SEMICOLON: char_out = ';'; break;
case DIK_APOSTROPHE:char_out = '\'';break;
case DIK_GRAVE: char_out = '`'; break;
case DIK_BACKSLASH: char_out = '\\';break;
case DIK_Z: char_out = 'Z'; break;
case DIK_X: char_out = 'X'; break;
case DIK_C: char_out = 'C'; break;
case DIK_V: char_out = 'V'; break;
case DIK_B: char_out = 'B'; break;
case DIK_N: char_out = 'N'; break;
case DIK_M: char_out = 'M'; break;
case DIK_COMMA: char_out = ','; break;
case DIK_PERIOD: char_out = '.'; break;
case DIK_SLASH: char_out = '/'; break;
case DIK_MULTIPLY: char_out = '*'; break;
case DIK_SPACE: char_out = ' '; break;
case DIK_NUMPAD7: char_out = '7'; break;
case DIK_NUMPAD8: char_out = '8'; break;
case DIK_NUMPAD9: char_out = '9'; break;
case DIK_SUBTRACT: char_out = '-'; break;
case DIK_NUMPAD4: char_out = '4'; break;
case DIK_NUMPAD5: char_out = '5'; break;
case DIK_NUMPAD6: char_out = '6'; break;
case DIK_ADD: char_out = '+'; break;
case DIK_NUMPAD1: char_out = '1'; break;
case DIK_NUMPAD2: char_out = '2'; break;
case DIK_NUMPAD3: char_out = '3'; break;
case DIK_NUMPAD0: char_out = '0'; break;
case DIK_DECIMAL: char_out = '.'; break;
default: return FALSE; // This key doesn't correspond to a character.
}
return TRUE;
}
CString RageRawInput::GetDescription() const
{
CString sReturn;
switch( device )
{
case DEVICE_NONE:
sReturn = "None";
break;
case DEVICE_JOYSTICK: // joystick
sReturn.Format( "Joystick%d ", device_no );
switch( button )
{
case JOY_LEFT: sReturn += "Left"; break;
case JOY_RIGHT: sReturn += "Right"; break;
case JOY_UP: sReturn += "Up"; break;
case JOY_DOWN: sReturn += "Down"; break;
default:
{
CString sButtonString;
sButtonString.Format( "Button %d", button );
sReturn += sButtonString;
}
break;
}
break;
case DEVICE_KEYBOARD:
sReturn = "Keyboard ";
switch( button )
{
case DIK_ESCAPE: sReturn += "Escape"; break;
case DIK_1: sReturn += "1"; break;
case DIK_2: sReturn += "2"; break;
case DIK_3: sReturn += "3"; break;
case DIK_4: sReturn += "4"; break;
case DIK_5: sReturn += "5"; break;
case DIK_6: sReturn += "6"; break;
case DIK_7: sReturn += "7"; break;
case DIK_8: sReturn += "8"; break;
case DIK_9: sReturn += "9"; break;
case DIK_0: sReturn += "0"; break;
case DIK_MINUS: sReturn += "Minus"; break;
case DIK_EQUALS: sReturn += "Equals"; break;
case DIK_BACK: sReturn += "Backspace"; break;
case DIK_TAB: sReturn += "Tab"; break;
// why? case DIK_BACK: sReturn += "Backspace"; break;
case DIK_Q: sReturn += "Q"; break;
case DIK_W: sReturn += "W"; break;
case DIK_E: sReturn += "E"; break;
case DIK_R: sReturn += "R"; break;
case DIK_T: sReturn += "T"; break;
case DIK_Y: sReturn += "Y"; break;
case DIK_U: sReturn += "U"; break;
case DIK_I: sReturn += "I"; break;
case DIK_O: sReturn += "O"; break;
case DIK_P: sReturn += "P"; break;
case DIK_LBRACKET: sReturn += "LBracket"; break;
case DIK_RBRACKET: sReturn += "RBracket"; break;
case DIK_RETURN: sReturn += "Return"; break;
case DIK_LCONTROL: sReturn += "LControl"; break;
case DIK_A: sReturn += "A"; break;
case DIK_S: sReturn += "S"; break;
case DIK_D: sReturn += "D"; break;
case DIK_F: sReturn += "F"; break;
case DIK_G: sReturn += "G"; break;
case DIK_H: sReturn += "H"; break;
case DIK_J: sReturn += "J"; break;
case DIK_K: sReturn += "K"; break;
case DIK_L: sReturn += "L"; break;
case DIK_SEMICOLON: sReturn += "Semicolon"; break;
case DIK_APOSTROPHE:sReturn += "Apostroph"; break;
case DIK_GRAVE: sReturn += "Grave"; break;
case DIK_LSHIFT: sReturn += "LShift"; break;
case DIK_BACKSLASH: sReturn += "Backslash"; break;
case DIK_Z: sReturn += "Z"; break;
case DIK_X: sReturn += "X"; break;
case DIK_C: sReturn += "C"; break;
case DIK_V: sReturn += "V"; break;
case DIK_B: sReturn += "B"; break;
case DIK_N: sReturn += "N"; break;
case DIK_M: sReturn += "M"; break;
case DIK_COMMA: sReturn += "Comma"; break;
case DIK_PERIOD: sReturn += "Period"; break;
case DIK_SLASH: sReturn += "Slash"; break;
case DIK_RSHIFT: sReturn += "R Shift"; break;
case DIK_MULTIPLY: sReturn += "Multiply"; break;
case DIK_LMENU: sReturn += "Left Menu"; break;
case DIK_SPACE: sReturn += "Space"; break;
case DIK_CAPITAL: sReturn += "Caps Lock"; break;
case DIK_F1: sReturn += "F1"; break;
case DIK_F2: sReturn += "F2"; break;
case DIK_F3: sReturn += "F3"; break;
case DIK_F4: sReturn += "F4"; break;
case DIK_F5: sReturn += "F5"; break;
case DIK_F6: sReturn += "F6"; break;
case DIK_F7: sReturn += "F7"; break;
case DIK_F8: sReturn += "F8"; break;
case DIK_F9: sReturn += "F9"; break;
case DIK_F10: sReturn += "F10"; break;
case DIK_NUMLOCK: sReturn += "Numlock"; break;
case DIK_SCROLL: sReturn += "Scroll"; break;
case DIK_NUMPAD7: sReturn += "NumPad7"; break;
case DIK_NUMPAD8: sReturn += "NumPad8"; break;
case DIK_NUMPAD9: sReturn += "NumPad9"; break;
case DIK_SUBTRACT: sReturn += "Subtract"; break;
case DIK_NUMPAD4: sReturn += "NumPad4"; break;
case DIK_NUMPAD5: sReturn += "NumPad5"; break;
case DIK_NUMPAD6: sReturn += "NumPad6"; break;
case DIK_ADD: sReturn += "Add"; break;
case DIK_NUMPAD1: sReturn += "NumPad1"; break;
case DIK_NUMPAD2: sReturn += "NumPad2"; break;
case DIK_NUMPAD3: sReturn += "NumPad3"; break;
case DIK_NUMPAD0: sReturn += "NumPad0"; break;
case DIK_DECIMAL: sReturn += "Decimal"; break;
case DIK_RMENU: sReturn += "Right Alt"; break;
case DIK_PAUSE: sReturn += "Pause"; break;
case DIK_HOME: sReturn += "Home"; break;
case DIK_UP: sReturn += "Up"; break;
case DIK_PRIOR: sReturn += "Page Up"; break;
case DIK_LEFT: sReturn += "Left"; break;
case DIK_RIGHT: sReturn += "Right"; break;
case DIK_END: sReturn += "End"; break;
case DIK_DOWN: sReturn += "Down"; break;
case DIK_NEXT: sReturn += "Page Down"; break;
case DIK_INSERT: sReturn += "Insert"; break;
case DIK_DELETE: sReturn += "Delete"; break;
case DIK_LWIN: sReturn += "Left Win"; break;
case DIK_RWIN: sReturn += "Right Win"; break;
case DIK_APPS: sReturn += "App Menu"; break;
default: sReturn += "Unknown Key"; break;
}
break;
default:
sReturn = "Invalid Device";
break;
}
return sReturn;
}
//-----------------------------------------------------------------------------
// Name: EnumJoysticksCallback()
// Desc: Called once for each enumerated joystick. If we find one, create a
// device interface on it so we can play with it.
//-----------------------------------------------------------------------------
BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance,
VOID* pContext )
{
LPRageInput pInput = (LPRageInput)pContext;
LPDIRECTINPUT8 pDI = pInput->GetDirectInput();
HRESULT hr;
// Obtain an interface to the enumerated joystick.
for( int i=0; i<NUM_JOYSTICKS; i++ )
{
hr = pDI->CreateDevice( pdidInstance->guidInstance,
&pInput->m_pJoystick[i],
NULL );
// This will only fail if the user unplugs while we were in the middle of enumerating.
return DIENUM_CONTINUE;
}
return DIENUM_STOP; // already enumerated NUm_pJoystick times
}
//-----------------------------------------------------------------------------
// Name: EnumAxesCallback()
// Desc: Callback function for enumerating the axes on a joystick
//-----------------------------------------------------------------------------
BOOL CALLBACK EnumAxesCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
VOID* pContext )
{
LPDIRECTINPUTDEVICE8 pJoystick = (LPDIRECTINPUTDEVICE8)pContext;
DIPROPRANGE diprg;
diprg.diph.dwSize = sizeof(DIPROPRANGE);
diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
diprg.diph.dwHow = DIPH_BYID;
diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis
diprg.lMin = -1000;
diprg.lMax = +1000;
// Set the range for the axis
if( FAILED( pJoystick->SetProperty( DIPROP_RANGE, &diprg.diph ) ) )
return DIENUM_STOP;
return DIENUM_CONTINUE;
}
RageInput::RageInput( HWND hWnd )
{
m_hWnd = hWnd;
m_pDI = NULL;
m_pKeyboard = NULL;
m_pMouse = NULL;
for( int 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++ )
{
ZeroMemory( &m_joyState[j], sizeof(m_joyState[j]) );
ZeroMemory( &m_oldKeys[j], sizeof(m_joyState[j]) );
}
Initialize();
}
RageInput::~RageInput()
{
Release();
}
HRESULT RageInput::Initialize()
{
HRESULT hr;
////////////////////////////////
// Create the DirectInput object
////////////////////////////////
if( FAILED(hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION,
IID_IDirectInput8, (VOID**)&m_pDI, NULL ) ) )
RageErrorHr( "DirectInput8Create failed.", hr );
/////////////////////////////
// Create the keyboard device
/////////////////////////////
// Create our DirectInput Object for the Keyboard
if( FAILED( hr = m_pDI->CreateDevice( GUID_SysKeyboard, &m_pKeyboard, NULL ) ) )
RageErrorHr( "CreateDevice keyboard failed.", hr );
// Set our Cooperation Level with each Device
if( FAILED( hr = m_pKeyboard->SetCooperativeLevel(m_hWnd, DISCL_FOREGROUND |
DISCL_NOWINKEY |
DISCL_NONEXCLUSIVE) ) )
RageErrorHr( "m_pKeyboard->SetCooperativeLevel failed.", hr );
// Set the Data Format of each device
if( FAILED( hr = m_pKeyboard->SetDataFormat(&c_dfDIKeyboard) ) )
RageErrorHr( "m_pKeyboard->SetDataFormat failed.", hr );
// Acquire the Keyboard Device
//if( FAILED( hr = m_pKeyboard->Acquire() ) )
// RageErrorHr( "m_pKeyboard->Acquire failed.", hr );
//////////////////////////
// Create the mouse device
//////////////////////////
// Obtain an interface to the system mouse device.
if( FAILED( hr = m_pDI->CreateDevice( GUID_SysMouse, &m_pMouse, NULL ) ) )
RageErrorHr( "CreateDevice mouse failed.", hr );
if( FAILED( hr = m_pMouse->SetCooperativeLevel( m_hWnd, DISCL_NONEXCLUSIVE|DISCL_FOREGROUND ) ) )
RageErrorHr( "m_pMouse->SetCooperativeLevel failed.", hr );
if( FAILED( hr = m_pMouse->SetDataFormat( &c_dfDIMouse2 ) ) )
RageErrorHr( "m_pMouse->SetDataFormat failed.", hr );
/*
DIPROPDWORD dipdw;
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = DIPROPAXISMODE_ABS;
if( FAILED( m_pMouse->SetProperty( DIPROP_AXISMODE, &dipdw.diph ) ) )
return E_FAIL;*/
//if( FAILED( hr = m_pMouse->Acquire()))
// RageErrorHr( "m_pMouse->Acquire failed.", hr );
m_RelPosition_x = 0;
m_RelPosition_y = 0;
m_AbsPosition_x = 640/2;
m_AbsPosition_y = 480/2;
//////////////////////////////
// Create the joystick devices
//////////////////////////////
// Look for joysticks
// TODO: Why is this function so slow to return? Is it just my machine?
if( FAILED( hr = m_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL,
EnumJoysticksCallback,
(VOID*)this,
DIEDFL_ATTACHEDONLY ) ) )
RageErrorHr( "m_pDI->EnumDevices failed.", hr );
for( int i=0; i<NUM_JOYSTICKS; i++ )
{
// Set the data format to "simple joystick" - a predefined data format
//
// A data format specifies which controls on a device we are interested in,
// and how they should be reported. This tells DInput that we will be
// passing a DIJOYSTATE2 structure to IDirectInputDevice::GetDeviceState().
if( m_pJoystick[i] )
if( FAILED( hr = m_pJoystick[i]->SetDataFormat( &c_dfDIJoystick2 ) ) )
RageErrorHr( "m_pJoystick[i]->SetDataFormat failed.", hr );
// 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 ) ) )
RageErrorHr( "m_pJoystick[i]->SetCooperativeLevel failed.", hr );
/*
// Determine how many axis the joystick has (so we don't error out setting
// properties for unavailable axis)
if ( m_pJoystick[i] ) {
g_diDevCaps.dwSize = sizeof(DIDEVCAPS);
if ( FAILED( hr = m_pJoystick[i]->GetCapabilities(&g_diDevCaps) ) )
return hr;
}
*/
// Enumerate the axes of the joyctick and set the range of each axis. Note:
// we could just use the defaults, but we're just trying to show an example
// 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 ) ) )
RageErrorHr( "m_pJoystick[i]->EnumObjects failed.", hr );
// Acquire the newly created devices
if( m_pJoystick[i] )
if( FAILED( hr = m_pJoystick[i]->Acquire() ) )
RageErrorHr( "m_pJoystick[i]->Acquire failed.", hr );
}
return S_OK;
}
VOID RageInput::Release()
{
// Unacquire the keyboard device
if (m_pKeyboard)
m_pKeyboard->Unacquire();
// Release the keyboard device
SAFE_RELEASE(m_pKeyboard);
// Unacquire the Mouse device
if (m_pMouse)
m_pMouse->Unacquire();
// Release the Mouse device
SAFE_RELEASE(m_pMouse);
for( int i=0; i<NUM_JOYSTICKS; i++ )
{
if (m_pJoystick[i])
m_pJoystick[i]->Unacquire();
// Release the Mouse device
SAFE_RELEASE(m_pJoystick[i]);
}
// Release the DirectInput object
SAFE_RELEASE(m_pDI);
}
HRESULT RageInput::GetRawInput( RageRawInputList &listRawInput )
{
// macros for reading DI state structures
#define IS_PRESSED(b) (b & 0x80)
#define AXIS_THRESHOLD 50 // joystick axis threshold
#define IS_LEFT(a) (a <= -AXIS_THRESHOLD)
#define IS_RIGHT(a) (a >= AXIS_THRESHOLD)
#define IS_UP(a) IS_LEFT(a)
#define IS_DOWN(a) IS_RIGHT(a)
HRESULT hr;
//////////////////////////////////////////////////////////////////
// the current state last update becomes the old state this update
//////////////////////////////////////////////////////////////////
CopyMemory( &m_oldKeys, &m_keys, sizeof(m_keys) );
CopyMemory( &m_oldJoyState, &m_joyState, sizeof(m_joyState) );
ZeroMemory( &m_keys, sizeof(m_keys) );
ZeroMemory( &m_joyState, sizeof(m_joyState) );
////////////////////
// Read the keyboard
////////////////////
if( NULL == m_pKeyboard )
return E_FAIL;
if FAILED(m_pKeyboard->GetDeviceState( sizeof(m_keys),(LPVOID)&m_keys ))
{
// DirectInput may be telling us that the input stream has been
// interrupted. We aren't tracking any state between polls, so
// we don't have any special reset that needs to be done.
// We just re-acquire and try again.
// If input is lost then acquire and keep trying
hr = m_pKeyboard->Acquire();
while( hr == DIERR_INPUTLOST )
hr = m_pKeyboard->Acquire();
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] ) )
listRawInput.AddTail( RageRawInput( DEVICE_KEYBOARD, 1, k, FALSE ) );
}
////////////////////
// Read the mouse
////////////////////
if( NULL == m_pMouse )
return E_FAIL;
ZeroMemory( &m_mouseState, sizeof(m_mouseState) );
// Get the input's device state, and put the state in DIMOUSESTATE2
if (FAILED(m_pMouse->GetDeviceState( sizeof(DIMOUSESTATE2), &m_mouseState )))
{
// If input is lost then acquire and keep trying
hr = m_pMouse->Acquire();
while( hr == DIERR_INPUTLOST )
hr = m_pMouse->Acquire();
return E_FAIL;
}
m_RelPosition_x = m_mouseState.lX;
m_RelPosition_y = m_mouseState.lY;
m_AbsPosition_x += m_mouseState.lX;
m_AbsPosition_y += m_mouseState.lY;
if (m_AbsPosition_x >= 640)
m_AbsPosition_x = 640-1;
else
if (m_AbsPosition_x < 0)
m_AbsPosition_x = 0;
// now the y boundaries
if (m_AbsPosition_y >= 480)
m_AbsPosition_y= 480-1;
else
if (m_AbsPosition_y < 0)
m_AbsPosition_y = 0;
/////////////////////
// Read the joysticks
/////////////////////
// read joystick state
for( BYTE i=0; i<4; i++ ) // foreach joystick
{
// read joystick states
if ( m_pJoystick[i] )
{
// Poll the device to read the current state
hr = m_pJoystick[i]->Poll();
if( FAILED(hr) )
{
// DInput is telling us that the input stream has been
// interrupted. We aren't tracking any state between polls, so
// we don't have any special reset that needs to be done. We
// just re-acquire and try again.
hr = m_pJoystick[i]->Acquire();
while( hr == DIERR_INPUTLOST )
hr = m_pJoystick[i]->Acquire();
// hr may be DIERR_OTHERAPPHASPRIO or other errors. This
// may occur when the app is minimized or in the process of
// switching, so just try again later
return E_FAIL;
}
// 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 ) )
listRawInput.AddTail( RageRawInput( DEVICE_JOYSTICK, i+1, JOY_LEFT, FALSE ) );
if( IS_RIGHT( m_joyState[i].lX ) &&
!IS_RIGHT( m_oldJoyState[i].lX ) )
listRawInput.AddTail( RageRawInput( DEVICE_JOYSTICK, i+1, JOY_RIGHT, FALSE ) );
if( IS_UP( m_joyState[i].lY ) &&
!IS_UP( m_oldJoyState[i].lY ) )
listRawInput.AddTail( RageRawInput( DEVICE_JOYSTICK, i+1, JOY_UP, FALSE ) );
if( IS_DOWN( m_joyState[i].lY ) &&
!IS_DOWN( m_oldJoyState[i].lY ) )
listRawInput.AddTail( RageRawInput( DEVICE_JOYSTICK, i+1, JOY_DOWN, FALSE ) );
for( BYTE b=0; b<10; b++ )
{
if( IS_PRESSED(m_joyState[i].rgbButtons[b]) && !IS_PRESSED(m_oldJoyState[i].rgbButtons[b]) )
listRawInput.AddTail( RageRawInput( DEVICE_JOYSTICK, i+1, b+1, FALSE ) );
}
}
}
}
return S_OK;
}
+133
View File
@@ -0,0 +1,133 @@
//-----------------------------------------------------------------------------
// File: RageInput.h
//
// Desc: DirectInput wrapper class
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _RAGEINPUT_H_
#define _RAGEINPUT_H_
#include <dinput.h>
#include "RageUtil.h"
#define NUM_JOYSTICKS 4
// button byte codes for directional pad
#define JOY_LEFT 101
#define JOY_RIGHT 102
#define JOY_UP 103
#define JOY_DOWN 104
#define DEVICE_NONE 0
#define DEVICE_KEYBOARD 1
#define DEVICE_JOYSTICK 2
class RageRawInput
{
public:
RageRawInput() { device = device_no = button = just_pressed = 0; };
RageRawInput( BYTE device,
BYTE device_no,
BYTE button,
BYTE just_pressed )
{
this->device = device;
this->device_no = device_no;
this->button = button;
this->just_pressed = just_pressed;
};
RageRawInput( CString sEncoding )
{
CStringArray a;
split( sEncoding, "-", a);
this->device = atoi( a[0] );
this->device_no = atoi( a[1] );
this->button = atoi( a[2] );
};
CString Encode() { return ssprintf("%u-%u-%u", device, device_no, button); };
BOOL LookupChar( TCHAR &char_out ) const;
CString GetDescription() const;
BOOL IsBlank() { return device == DEVICE_NONE; };
BYTE device;
BYTE device_no;
BYTE button;
BYTE just_pressed;
};
typedef CList<RageRawInput, RageRawInput&> RageRawInputList;
class RageInput
{
// Our Windows Handle
HWND m_hWnd;
// Main DirectInput Object
LPDIRECTINPUT8 m_pDI;
// Keyboard Device
LPDIRECTINPUTDEVICE8 m_pKeyboard;
// Mouse Device
LPDIRECTINPUTDEVICE8 m_pMouse;
public:
// hack: make them public to allow the callbacks access to the pointers
// Joystick Devices
LPDIRECTINPUTDEVICE8 m_pJoystick[NUM_JOYSTICKS];
private:
// Arrays for Keyboard Data
byte m_keys[256];
byte m_oldKeys[256];
// DirectInput mouse state structure
DIMOUSESTATE2 m_mouseState;
// Joystick data for 4 controllers
DIJOYSTATE2 m_joyState[4];
DIJOYSTATE2 m_oldJoyState[4];
INT m_AbsPosition_x;
INT m_AbsPosition_y;
INT m_RelPosition_x;
INT m_RelPosition_y;
public:
RageInput(HWND hWnd);
~RageInput();
// Initialize DirectInput Resources
HRESULT Initialize();
// Release all DirectInput Resources
VOID Release();
// Get our Devices State
HRESULT GetRawInput( RageRawInputList &listRawInput );
LPDIRECTINPUT8 GetDirectInput() { return m_pDI; }
LPDIRECTINPUTDEVICE8 GetMouseDevice() { return m_pMouse; }
LPDIRECTINPUTDEVICE8 GetKeyboardDevice() { return m_pKeyboard; }
LPDIRECTINPUTDEVICE8 GetJoystickDevice( int i ) { return m_pJoystick[i]; }
// DIMOUSESTATE2 GetMouseState() { return dimMouseState; }
VOID GetAbsPosition( DWORD &x, DWORD &y ) { x = m_AbsPosition_x; y = m_AbsPosition_y; }
};
typedef RageInput* LPRageInput;
extern LPRageInput INPUT; // global and accessable from anywhere in our program
#endif
+417
View File
@@ -0,0 +1,417 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: RageMovieTexture.cpp
//
// Desc: Based on the DShowTextures example in the DX8 SDK.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// In-line Links
//-----------------------------------------------------------------------------
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "dxerr8.lib")
// Link with the DirectShow base class libraries
#if defined(DEBUG) | defined(_DEBUG)
#pragma comment(lib, "C:\\Program Files\\DX8aSDK\\samples\\Multimedia\\DirectShow\\BaseClasses\\Debug\\strmbasd.lib")
#else
#pragma comment(lib, "C:\\Program Files\\DX8aSDK\\samples\\Multimedia\\DirectShow\\BaseClasses\\Release\\strmbase.lib")
#endif
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include "RageMovieTexture.h"
#include "dxerr8.h"
#include "DXUtil.h"
#include "RageUtil.h"
#include <stdio.h>
#include <assert.h>
//-----------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// CTextureRenderer constructor
//-----------------------------------------------------------------------------
CTextureRenderer::CTextureRenderer( LPUNKNOWN pUnk, HRESULT *phr )
: CBaseVideoRenderer(__uuidof(CLSID_TextureRenderer),
NAME("Texture Renderer"), pUnk, phr)
{
// Store and ARageef the texture for our use.
m_pTexture = NULL;
m_bLocked = FALSE;
*phr = S_OK;
}
//-----------------------------------------------------------------------------
// CTextureRenderer destructor
//-----------------------------------------------------------------------------
CTextureRenderer::~CTextureRenderer()
{
// Do nothing
}
//-----------------------------------------------------------------------------
// CheckMediaType: This method forces the graph to give us an R8G8B8 video
// type, making our copy to texture memory trivial.
//-----------------------------------------------------------------------------
HRESULT CTextureRenderer::CheckMediaType(const CMediaType *pmt)
{
HRESULT hr = E_FAIL;
VIDEOINFO *pvi;
// Reject the connection if this is not a video type
if( *pmt->FormatType() != FORMAT_VideoInfo ) {
return E_INVALIDARG;
}
// Only accept RGB24
pvi = (VIDEOINFO *)pmt->Format();
if(IsEqualGUID( *pmt->Type(), MEDIATYPE_Video) &&
IsEqualGUID( *pmt->Subtype(), MEDIASUBTYPE_RGB24))
// IsEqualGUID( *pmt->Subtype(), MEDIASUBTYPE_RGB565))
{
hr = S_OK;
}
return hr;
}
//-----------------------------------------------------------------------------
// SetMediaType: Graph connection has been made.
//-----------------------------------------------------------------------------
HRESULT CTextureRenderer::SetMediaType(const CMediaType *pmt)
{
// HRESULT hr;
// Retrive the size of this media type
VIDEOINFO *pviBmp; // Bitmap info header
pviBmp = (VIDEOINFO *)pmt->Format();
m_lVidWidth = pviBmp->bmiHeader.biWidth;
m_lVidHeight = abs(pviBmp->bmiHeader.biHeight);
m_lVidPitch = (m_lVidWidth * 3 + 3) & ~(3); // We are forcing RGB24
return S_OK;
}
//-----------------------------------------------------------------------------
// SetRenderTarget: Save all the information we'll need to render to a D3D texture.
//-----------------------------------------------------------------------------
HRESULT CTextureRenderer::SetRenderTarget(LPDIRECT3DTEXTURE8 pTexture)
{
HRESULT hr;
if (pTexture == NULL) {
DXTRACE_ERR(TEXT("SetRenderTarget called with a NULL texture!"), 0);
return E_FAIL;
}
m_pTexture = pTexture;
// get the format of the texture
D3DSURFACE_DESC ddsd;
if ( FAILED( hr = m_pTexture->GetLevelDesc( 0, &ddsd ) ) ) {
DXTRACE_ERR(TEXT("Could not get level Description of D3DX texture! hr = 0x%x"), hr);
return hr;
}
m_TextureFormat = ddsd.Format;
if (m_TextureFormat != D3DFMT_A8R8G8B8 &&
m_TextureFormat != D3DFMT_A1R5G5B5) {
DXTRACE_ERR(TEXT("Texture is format we can't handle! Format = 0x%x"), m_TextureFormat);
return E_FAIL;
}
return S_OK;
}
//-----------------------------------------------------------------------------
// DoRenderSample: A sample has been delivered. Copy it to the texture.
//-----------------------------------------------------------------------------
HRESULT CTextureRenderer::DoRenderSample( IMediaSample * pSample )
{
BYTE *pBmpBuffer, *pTxtBuffer; // Bitmap buffer, texture buffer
LONG lTxtPitch; // Pitch of bitmap, texture
// Get the video bitmap buffer
pSample->GetPointer( &pBmpBuffer );
// Lock the Texture
D3DLOCKED_RECT d3dlr;
if (FAILED(m_pTexture->LockRect(0, &d3dlr, 0, 0))) {
DXTRACE_ERR_NOMSGBOX(TEXT("Failed to lock the texture!"), E_FAIL);
return E_FAIL;
}
m_bLocked = TRUE;
// Get the texture buffer & pitch
pTxtBuffer = static_cast<byte *>(d3dlr.pBits);
lTxtPitch = d3dlr.Pitch;
// Copy the bits
// OPTIMIZATION OPPORTUNITY: Use a video and texture
// format that allows a simpler copy than this one.
if (m_TextureFormat == D3DFMT_A8R8G8B8) {
for(int y = 0; y < m_lVidHeight; y++ ) {
BYTE *pBmpBufferOld = pBmpBuffer;
BYTE *pTxtBufferOld = pTxtBuffer;
for (int x = 0; x < m_lVidWidth; x++) {
pTxtBuffer[0] = pBmpBuffer[0];
pTxtBuffer[1] = pBmpBuffer[1];
pTxtBuffer[2] = pBmpBuffer[2];
pTxtBuffer[3] = 0xff;
pTxtBuffer += 4;
pBmpBuffer += 3;
}
pBmpBuffer = pBmpBufferOld + m_lVidPitch;
pTxtBuffer = pTxtBufferOld + lTxtPitch;
}
}
if (m_TextureFormat == D3DFMT_A1R5G5B5) {
for(int y = 0; y < m_lVidHeight; y++ ) {
BYTE *pBmpBufferOld = pBmpBuffer;
BYTE *pTxtBufferOld = pTxtBuffer;
for (int x = 0; x < m_lVidWidth; x++) {
*(WORD *)pTxtBuffer =
0x8000 +
((pBmpBuffer[2] & 0xF8) << 7) +
((pBmpBuffer[1] & 0xF8) << 2) +
(pBmpBuffer[0] >> 3);
pTxtBuffer += 2;
pBmpBuffer += 3;
}
pBmpBuffer = pBmpBufferOld + m_lVidPitch;
pTxtBuffer = pTxtBufferOld + lTxtPitch;
}
}
// Unlock the Texture
if (FAILED(m_pTexture->UnlockRect(0))) {
DXTRACE_ERR_NOMSGBOX(TEXT("Failed to unlock the texture!"), E_FAIL);
return E_FAIL;
}
m_bLocked = FALSE;
return S_OK;
}
//-----------------------------------------------------------------------------
// RageMovieTexture constructor
//-----------------------------------------------------------------------------
RageMovieTexture::RageMovieTexture( LPRageScreen pScreen, CString sFilePath ) :
RageTexture( pScreen, sFilePath )
{
RageLog( "RageBitmapTexture::RageBitmapTexture()" );
Create();
CreateFrameRects();
}
RageMovieTexture::~RageMovieTexture()
{
CleanupDShow();
SAFE_RELEASE(m_pd3dTexture);
}
//-----------------------------------------------------------------------------
// GetTexture
//-----------------------------------------------------------------------------
LPDIRECT3DTEXTURE8 RageMovieTexture::GetD3DTexture()
{
// Wait until the TextureRenderer is not copying to our texture.
// If we try to draw using the texture while it is locked, the primitive
// will appear without a texture.
// Most of the time, the TextureRenderer is not busy copying (copying
// a frame of video is very quick). If it is busy, it's usually becase
// the video fell behind and is trying to copy several frames in a row
// to catch up. So, if the TextureRenderer is busy, give it a 1ms slice of
// time for it to catch up and copy all the frames it fell behind on.
while( m_pCTR->IsLocked() )
::Sleep(1);
// restart the movie if we reach the end
CheckMovieStatus();
return m_pd3dTexture;
}
//-----------------------------------------------------------------------------
// RageMovieTexture::Create()
//-----------------------------------------------------------------------------
VOID RageMovieTexture::Create()
{
HRESULT hr;
// Initialize the filter graph find and get information about the
// video (dimensions, color depth, etc.)
if( FAILED( hr = InitDShowTextureRenderer() ) )
RageErrorHr( "Could not initialize the DirectShow Texture Renderer!", hr );
if( FAILED( hr = CreateD3DTexture() ) )
RageErrorHr( "Could not create the D3D Texture!", hr );
// Pass the D3D texture to our TextureRenderer so it knows
// where to render new movie frames to.
if( FAILED( hr = m_pCTR->SetRenderTarget(GetD3DTexture()) ) )
RageErrorHr( "RageMovieTexture: SetRenderTarget failed.", hr );
// Start the graph running
if( FAILED( hr = PlayMovie() ) )
RageErrorHr( "Could not run the DirectShow graph.", hr );
}
//-----------------------------------------------------------------------------
// InitDShowTextureRenderer : Create DirectShow filter graph and run the graph
//-----------------------------------------------------------------------------
HRESULT RageMovieTexture::InitDShowTextureRenderer()
{
HRESULT hr = S_OK;
CComPtr<IBaseFilter> pFTR; // Texture Renderer Filter
CComPtr<IPin> pFTRPinIn; // Texture Renderer Input Pin
CComPtr<IBaseFilter> pFSrc; // Source Filter
CComPtr<IPin> pFSrcPinOut; // Source Filter Output Pin
// Create the filter graph
if( FAILED( m_pGB.CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC) ) )
RageErrorHr( "Could not create CLSID_FilterGraph!", hr );
// Create the Texture Renderer object
m_pCTR = new CTextureRenderer(NULL, &hr);
if( FAILED(hr) )
RageErrorHr( "Could not create texture renderer object!", hr );
// 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" ) ) )
RageErrorHr( "Could not add renderer filter to graph!", hr );
// convert movie file path to wide char string
WCHAR wFileName[MAX_PATH];
#ifndef UNICODE
MultiByteToWideChar(CP_ACP, 0, m_sFilePath, -1, wFileName, MAX_PATH);
#else
lstrcpy(wFileName, m_szFilePath);
#endif
// Add the source filter
if( FAILED( hr = m_pGB->AddSourceFilter( wFileName, L"SOURCE", &pFSrc ) ) )
RageErrorHr( "Could not create source filter to graph!", hr );
// Find the source's output and the renderer's input
if( FAILED( hr = pFTR->FindPin( L"In", &pFTRPinIn ) ) )
RageErrorHr( "Could not find input pin!", hr );
if( FAILED( hr = pFSrc->FindPin( L"Output", &pFSrcPinOut ) ) )
RageErrorHr( "Could not find output pin!", hr );
// Connect these two filters
if( FAILED( hr = m_pGB->Connect( pFSrcPinOut, pFTRPinIn ) ) )
RageErrorHr( "Could not connect pins!", hr );
// Get the graph's media control, event & position interfaces
m_pGB.QueryInterface(&m_pMC);
m_pGB.QueryInterface(&m_pMP);
m_pGB.QueryInterface(&m_pME);
// The graph is built, now get the set the output video width and height
m_uImageWidth = m_pCTR->GetVidWidth();
m_uImageHeight = m_pCTR->GetVidHeight();
return S_OK;
}
HRESULT RageMovieTexture::CreateD3DTexture()
{
HRESULT hr;
//////////////////////////////////////////////////
// Create the texture that maps to this media type
//////////////////////////////////////////////////
if( FAILED( hr = D3DXCreateTexture(m_pd3dDevice,
m_uImageWidth, m_uImageHeight,
1, 0,
D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_pd3dTexture ) ) )
RageErrorHr( "Could not create the D3DX texture!", hr );
// D3DXCreateTexture can silently change the parameters on us
D3DSURFACE_DESC ddsd;
if ( FAILED( hr = m_pd3dTexture->GetLevelDesc( 0, &ddsd ) ) )
RageErrorHr( "Could not get level Description of D3DX texture!", hr );
m_uTextureWidth = ddsd.Width;
m_uTextureHeight = ddsd.Height;
m_TextureFormat = ddsd.Format;
if( m_TextureFormat != D3DFMT_A8R8G8B8 &&
m_TextureFormat != D3DFMT_A1R5G5B5 )
RageErrorHr( "Texture is format we can't handle! Format = 0x%x!", m_TextureFormat );
return S_OK;
}
HRESULT RageMovieTexture::PlayMovie()
{
HRESULT hr;
// Start the graph running;
if( FAILED( hr = m_pMC->Run() ) )
RageErrorHr( "Could not run the DirectShow graph.", hr );
return S_OK;
}
//-----------------------------------------------------------------------------
// CheckMovieStatus: If the movie has ended, rewind to beginning
//-----------------------------------------------------------------------------
void RageMovieTexture::CheckMovieStatus()
{
long lEventCode;
long lParam1;
long lParam2;
// Check for completion events
m_pME->GetEvent( &lEventCode, &lParam1, &lParam2, 0 );
if( EC_COMPLETE == lEventCode )
m_pMP->put_CurrentPosition(0);
}
//-----------------------------------------------------------------------------
// CleanupDShow
//-----------------------------------------------------------------------------
void RageMovieTexture::CleanupDShow()
{
// Shut down the graph
if (m_pMC) m_pMC->Stop();
if (m_pGB) m_pGB.Release ();
}
+99
View File
@@ -0,0 +1,99 @@
//-----------------------------------------------------------------------------
// File: RageMovieTexture.h
//
// Desc: Based on the DShowTextures example in the DX8 SDK.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _RAGEMOVIETEXTURE_H_
#define _RAGEMOVIETEXTURE_H_
#include "RageScreen.h"
#include <d3dx8.h>
//#include <d3d8types.h>
#include <atlbase.h>
#include <streams.h>
//-----------------------------------------------------------------------------
// Define GUID for Texture Renderer
// {71771540-2017-11cf-AE26-0020AFD79767}
//-----------------------------------------------------------------------------
struct __declspec(uuid("{71771540-2017-11cf-ae26-0020afd79767}")) CLSID_TextureRenderer;
//-----------------------------------------------------------------------------
// CTextureRenderer Class Declarations
//
// Usage: 1) CheckMediaType is called by the graph
// 2) SetMediaType is called by the graph
// 3) call GetVidWidth and GetVidHeight to get texture information
// 4) call SetRenderTarget
// 5) Do RenderSample is called by the graph
//-----------------------------------------------------------------------------
class CTextureRenderer : public CBaseVideoRenderer
{
public:
CTextureRenderer(LPUNKNOWN pUnk,HRESULT *phr);
~CTextureRenderer();
public:
// overwritten methods
HRESULT CheckMediaType(const CMediaType *pmt ); // Format acceptable?
HRESULT SetMediaType(const CMediaType *pmt ); // Video format notification
HRESULT DoRenderSample(IMediaSample *pMediaSample); // New video sample
// new methods
LONG GetVidWidth() {return m_lVidWidth;};
LONG GetVidHeight(){return m_lVidHeight;};
HRESULT SetRenderTarget(LPDIRECT3DTEXTURE8 pTexture);
BOOL IsLocked() { return m_bLocked; };
protected:
LONG m_lVidWidth; // Video width
LONG m_lVidHeight; // Video Height
LONG m_lVidPitch; // Video Pitch
LPDIRECT3DTEXTURE8 m_pTexture; // the video surface we will copy new frames to
D3DFORMAT m_TextureFormat; // Texture format
BOOL m_bLocked; // Is the texture currently locked while we
// copy the movie frame to it?
};
//-----------------------------------------------------------------------------
// RageMovieTexture Class Declarations
//-----------------------------------------------------------------------------
class RageMovieTexture : public RageTexture
{
public:
RageMovieTexture( LPRageScreen pScreen, CString sFilePath );
virtual ~RageMovieTexture();
LPDIRECT3DTEXTURE8 GetD3DTexture();
protected:
virtual VOID Create();
virtual HRESULT CreateD3DTexture();
virtual HRESULT InitDShowTextureRenderer();
virtual HRESULT PlayMovie();
virtual void CheckMovieStatus();
virtual void CleanupDShow();
//-----------------------------------------------------------------------------
// DirectShow pointers
//-----------------------------------------------------------------------------
CComPtr<IGraphBuilder> m_pGB; // GraphBuilder
CComPtr<IMediaControl> m_pMC; // Media Control
CComPtr<IMediaPosition> m_pMP; // Media Postion
CComPtr<IMediaEvent> m_pME; // Media Event
CTextureRenderer *m_pCTR; // DShow Texture renderer
};
typedef RageMovieTexture* LPRageMovieTexture;
#endif
+70
View File
@@ -0,0 +1,70 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: RageSound.cpp
//
// Desc: Sound effects library (currently a wrapper around Bass Sound Library).
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#include "RageSound.h"
#include "RageUtil.h"
#include "bass/bass.h"
#pragma comment(lib, "bass/bass.lib")
LPRageSound SOUND = NULL;
RageSound::RageSound( HWND hWnd )
{
// save the HWND
if( !hWnd )
RageError( "RageSound called with NULL hWnd." );
m_hWndApp = hWnd;
if( BASS_GetVersion() != MAKELONG(1,1) )
RageError( "BASS version 1.1 DLL could not be loaded. Verify that Bass.dll exists in the program directory.");
if( !BASS_Init( -1, 44100, BASS_DEVICE_NOSYNC, m_hWndApp ) )
RageError( "BASS can't initialize sound device." );
BASS_Start();
}
RageSound::~RageSound()
{
BASS_Free();
}
HSAMPLE RageSound::LoadSound( const CString sFileName )
{
RageLog( "RageSound::LoadSound( '%s' )", sFileName );
HSAMPLE hSample = BASS_SampleLoad( FALSE, (void*)((LPCTSTR)sFileName), 0, 0, 0, 0 );
if( hSample == NULL )
RageError( ssprintf("RageSound::LoadSound: error loading %s (error code %d)",
sFileName, BASS_ErrorGetCode()) );
return hSample;
}
VOID RageSound::UnloadSound( HSAMPLE hSample )
{
BASS_SampleFree( hSample );
}
VOID RageSound::Play( HSAMPLE hSample )
{
if( NULL == BASS_SamplePlay( hSample ) )
RageError( "There was an error playing a sound sample. Are you sure this is a valid HSAMPLE?" );
}
VOID RageSound::Stop( HSAMPLE hSample )
{
if( FALSE == BASS_SampleStop( hSample ) )
RageError( "There was an error stopping a sound sample. Are you sure this is a valid HSAMPLE?" );
}
+51
View File
@@ -0,0 +1,51 @@
//-----------------------------------------------------------------------------
// File: RageSound.h
//
// Desc: Sound effects library (currently a wrapper around Bass Sound Library).
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _RAGESOUND_H_
#define _RAGESOUND_H_
#include "bass/bass.h"
#define NUM_STREAMS 16
#define EFFECT_CHANNEL_1 0
#define EFFECT_CHANNEL_2 1
#define EFFECT_CHANNEL_3 2
#define EFFECT_CHANNEL_4 3
#define EFFECT_CHANNEL_5 4
#define ANOUNCER_CHANNEL 13
#define CROWD_CHANNEL 14
#define MUSIC_CHANNEL 15
class RageSound
{
public:
RageSound( HWND hWnd );
~RageSound();
HSAMPLE LoadSound( const CString sFileName );
VOID UnloadSound( HSAMPLE hSample );
VOID Play( HSAMPLE hSample );
VOID Stop( HSAMPLE hSample );
private:
HWND m_hWndApp; // this is set on GRAPHICS_Create()
// HSAMPLE m_hSample[NUM_STREAMS];
};
typedef RageSound* LPRageSound;
extern LPRageSound SOUND; // global and accessable from anywhere in our program
#endif
+120
View File
@@ -0,0 +1,120 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: RageTexture.cpp
//
// Desc:
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include "RageTexture.h"
#include "RageUtil.h"
//-----------------------------------------------------------------------------
// RageTexture constructor
//-----------------------------------------------------------------------------
RageTexture::RageTexture( LPRageScreen pScreen, CString sFilePath ) :
m_uImageWidth( 0 ),
m_uImageHeight( 0 ),
m_uTextureWidth( 0 ),
m_uTextureHeight( 0 ),
m_uFramesWide( 1 ),
m_uFramesHigh( 1 ),
m_uFrameWidth( 0 ),
m_uFrameHeight( 0 )
{
// RageLog( "RageTexture::RageTexture()" );
// save a pointer to the D3D device
m_pd3dDevice = pScreen->GetDevice();
assert( m_pd3dDevice != NULL );
// save the file path
m_sFilePath = sFilePath;
m_pd3dTexture = NULL;
m_iRefCount = 1;
}
RageTexture::~RageTexture()
{
}
VOID RageTexture::CreateFrameRects()
{
GetFrameDimensionsFromFileName( m_sFilePath, m_uFramesWide, m_uFramesHigh );
///////////////////////////////////
// Fill in the m_FrameRects with the bounds of each frame in the animation.
///////////////////////////////////
// calculate the width and height of the frames
m_uFrameWidth = GetImageWidth() / m_uFramesWide;
m_uFrameHeight= GetImageHeight() / m_uFramesHigh;
for( UINT j=0; j<m_uFramesHigh; j++ )
{
for( UINT i=0; i<m_uFramesWide; i++ )
{
RECT rectCurFrame;
::SetRect( &rectCurFrame, (i+0)*m_uFrameWidth, (j+0)*m_uFrameHeight,
(i+1)*m_uFrameWidth, (j+1)*m_uFrameHeight );
m_FrameRects.Add( rectCurFrame ); // the index of this array element will be (i + j*m_uFramesWide)
// RageLog( "Adding frame#%d: %d %d %d %d", (i + j*m_uFramesWide), rectCurFrame.left, rectCurFrame.top, rectCurFrame.right, rectCurFrame.bottom );
}
}
}
#include "string.h"
VOID RageTexture::GetFrameDimensionsFromFileName( CString sPath, UINT &uFramesWide, UINT &uFramesHigh ) const
{
//////////////////////////////////////////////////
// Parse m_sFilePath for the frame dimensions
//
// The file name must look like "name 4x15.gif". The the space is required.
//////////////////////////////////////////////////
CString sDimensionsString = sPath; // we will chop this down to the "4x15" part. Need regular... expressions... choke :-)
// chop off the extension
int index_of_last_period = sDimensionsString.ReverseFind( '.' );
if( index_of_last_period == -1 ) // this file name has no extension, but it the texture was loaded. I doubt this code will ever execute :-)
{
uFramesWide = uFramesHigh = 1;
return;
}
sDimensionsString = sDimensionsString.Left(index_of_last_period);
// chop off everything before the last space
int index_of_last_space = sDimensionsString.ReverseFind( ' ' );
if( index_of_last_space == -1 ) // this file name has space, so the dimensions tag cannot be read
{
uFramesWide = uFramesHigh = 1;
return;
}
sDimensionsString.Delete( 0, index_of_last_space+1 );
// now we are left with "4x15"
int index_of_x = sDimensionsString.Find( 'x' );
if( index_of_x == -1 ) // this file name doesn't have an x in the last token. So, this probably isn't a dimension tag.
{
uFramesWide = uFramesHigh = 1;
return;
}
uFramesWide = (UINT) atoi( sDimensionsString.Left( index_of_x ) );
// chop off the frames wide part and read in the frames high
sDimensionsString.Delete( 0, index_of_x+1 );
uFramesHigh = (UINT) atoi( sDimensionsString );
if( uFramesWide == 0 ) uFramesWide = 1;
if( uFramesHigh == 0 ) uFramesHigh = 1;
}
+73
View File
@@ -0,0 +1,73 @@
//-----------------------------------------------------------------------------
// File: RageTexture.h
//
// Desc:
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
class RageTexture;
typedef RageTexture* LPRageTexture;
#ifndef _RAGETEXTURE_H_
#define _RAGETEXTURE_H_
#include "RageScreen.h"
#include <d3dx8.h>
#include <assert.h>
//#include <d3d8types.h>
//-----------------------------------------------------------------------------
// RageTexture Class Declarations
//-----------------------------------------------------------------------------
class RageTexture
{
public:
RageTexture( LPRageScreen pScreen, CString sFilePath );
virtual ~RageTexture() PURE;
virtual LPDIRECT3DTEXTURE8 GetD3DTexture() PURE;
UINT GetImageWidth() {return m_uImageWidth;};
UINT GetImageHeight() {return m_uImageHeight;};
UINT GetTextureWidth() {return m_uTextureWidth;};
UINT GetTextureHeight() {return m_uTextureHeight;};
UINT GetFramesWide() {return m_uFramesWide;};
UINT GetFramesHigh() {return m_uFramesHigh;};
UINT GetFrameWidth() {return m_uFrameWidth;};
UINT GetFrameHeight() {return m_uFrameHeight;};
LPRECT GetFrameRect( UINT uFrameNo ) {return &m_FrameRects[uFrameNo];};
UINT GetNumFrames() {return m_FrameRects.GetSize();};
CString GetFilePath() {return m_sFilePath;};
INT m_iRefCount;
protected:
virtual VOID CreateFrameRects();
virtual VOID GetFrameDimensionsFromFileName( CString sPath, UINT &uFramesWide, UINT &uFramesHigh ) const;
CString m_sFilePath;
LPDIRECT3DDEVICE8 m_pd3dDevice;
LPDIRECT3DTEXTURE8 m_pd3dTexture;
UINT m_uImageWidth, m_uImageHeight;
UINT m_uTextureWidth, m_uTextureHeight;
D3DFORMAT m_TextureFormat;
// The number of frames of animation in each row and column of this texture.
UINT m_uFramesWide, m_uFramesHigh;
UINT m_uFrameWidth, m_uFrameHeight;
// RECTs that hold the bounds of each frame in the bitmap.
// e.g., if the texture has 4 frames of animation, the SrcRect for each frame would
// be in m_FrameRects[0..4].
CArray<RECT, RECT&> m_FrameRects;
};
#endif
+118
View File
@@ -0,0 +1,118 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: RageTextureManager.cpp
//
// Desc: Loads and releases textures
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include "RageTextureManager.h"
#include "RageBitmapTexture.h"
#include "RageMovieTexture.h"
#include "RageUtil.h"
#include <assert.h>
LPRageTextureManager TM = NULL;
//-----------------------------------------------------------------------------
// constructor/destructor
//-----------------------------------------------------------------------------
RageTextureManager::RageTextureManager( LPRageScreen pScreen )
{
assert( pScreen != NULL );
m_pScreen = pScreen;
}
RageTextureManager::~RageTextureManager()
{
// delete all textures
POSITION pos = m_mapPathToTexture.GetStartPosition();
CString key;
LPRageTexture value;
while( pos != NULL ) // iterate over all k/v pairs in map
{
m_mapPathToTexture.GetNextAssoc( pos, key, value );
SAFE_DELETE( value );
}
m_mapPathToTexture.RemoveAll();
}
//-----------------------------------------------------------------------------
// Load/Unload textures from disk
//-----------------------------------------------------------------------------
LPRageTexture RageTextureManager::LoadTexture( CString sTexturePath )
{
// RageLog( "RageTextureManager::LoadTexture(%s).", sTexturePath );
// holder for the new texture
LPRageTexture pTexture;
// Convert the path to lowercase so that we don't load duplicates.
// Really, this does not solve the duplicate problem. We could have to copies
// of the same bitmap if there are equivalent but different paths
// (e.g. "Bitmaps\me.bmp" and "..\Rage PC Edition\Bitmaps\me.bmp" ).
sTexturePath.MakeLower();
if( m_mapPathToTexture.Lookup( sTexturePath, pTexture ) ) // if the texture already exists in the map
{
// RageLog( ssprintf("Found that '%s' is already loaded. Using the loaded copy.", sTexturePath) );
pTexture->m_iRefCount++;
}
else
{
RageLog( ssprintf("Didn't find '%s' already loaded. Creating a new texture.", sTexturePath) );
CString sDrive, sDir, sFName, sExt;
splitpath( FALSE, sTexturePath, sDrive, sDir, sFName, sExt );
if( sExt == "avi" || sExt == "mpg" || sExt == "mpeg" )
pTexture = (LPRageTexture) new RageMovieTexture( m_pScreen, sTexturePath );
else
pTexture = (LPRageTexture) new RageBitmapTexture( m_pScreen, sTexturePath );
m_mapPathToTexture.SetAt( sTexturePath, pTexture );
}
return pTexture;
}
VOID RageTextureManager::UnloadTexture( CString sTexturePath )
{
// RageLog( "RageTextureManager::UnloadTexture(%s).", sTexturePath );
if( sTexturePath == "" )
{
RageLog( "RageTextureManager::UnloadTexture() tried to Unload a blank" );
return;
}
sTexturePath.MakeLower();
LPRageTexture pTexture;
if( m_mapPathToTexture.Lookup( sTexturePath, pTexture ) ) // if the texture exists in the map
{
pTexture->m_iRefCount--;
if( pTexture->m_iRefCount == 0 ) // there are no more references to this texture
{
RageLog( ssprintf("The texture '%s' has no more references. It will be deleted.", sTexturePath) );
SAFE_DELETE( pTexture ); // free the texture
m_mapPathToTexture.RemoveKey( sTexturePath ); // and remove the key in the map
}
// else
// RageLog( ssprintf("The texture '%s' has %d more references. It will not be deleted.",
// sTexturePath, pTexture->m_iRefCount) );
}
else
RageError( ssprintf("Tried to Unload a texture that wasn't loaded. '%s'", sTexturePath) );
}
+45
View File
@@ -0,0 +1,45 @@
//-----------------------------------------------------------------------------
// File: RageTextureManager.h
//
// Desc: Loads and releases textures
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
class RageTextureManager;
typedef RageTextureManager* LPRageTextureManager;
#ifndef _RAGETEXTUREMANAGER_H_
#define _RAGETEXTUREMANAGER_H_
#include "RageTexture.h"
//#include <d3dx8.h>
//#include <d3d8types.h>
//-----------------------------------------------------------------------------
// RageTextureManager Class Declarations
//-----------------------------------------------------------------------------
class RageTextureManager
{
public:
RageTextureManager( LPRageScreen pScreen );
~RageTextureManager();
LPRageTexture LoadTexture( CString sTexturePath );
VOID UnloadTexture( CString sTexturePath );
protected:
LPRageScreen m_pScreen;
// map from file name to a texture holder
CTypedPtrMap<CMapStringToPtr, CString, LPRageTexture> m_mapPathToTexture;
};
extern LPRageTextureManager TM; // global and accessable from anywhere in our program
#endif
+297
View File
@@ -0,0 +1,297 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: RageUtil.cpp
//
// Desc:
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#include "RageUtil.h"
//-----------------------------------------------------------------------------
// UTIL globals
//-----------------------------------------------------------------------------
const CString g_sLogFileName = "debug.log";
//-----------------------------------------------------------------------------
// Name: randomf()
// Desc:
//-----------------------------------------------------------------------------
FLOAT randomf( FLOAT low, FLOAT high )
{
return low + ( high - low ) * ( (FLOAT)rand() ) / RAND_MAX;
}
//-----------------------------------------------------------------------------
// Name: roundf()
// Desc:
//-----------------------------------------------------------------------------
int roundf( FLOAT f )
{
return (int)((f)+0.5f);
}
int roundf( double f )
{
return (int)((f)+0.5f);
}
//-----------------------------------------------------------------------------
// Name: RageLogStart()
// Desc:
//-----------------------------------------------------------------------------
void RageLogStart()
{
// delete the old log and create a new one
DeleteFile( g_sLogFileName );
FILE *fp = NULL;
fp = fopen( g_sLogFileName, "w" );
fclose( fp );
SYSTEMTIME st;
GetLocalTime( &st );
RageLog( "%s: last compiled on %s.", g_sLogFileName, __TIMESTAMP__ );
RageLog( "Log starting %.4d-%.2d-%.2d %.2d:%.2d:%.2d",
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond );
RageLog( "\n" );
}
//-----------------------------------------------------------------------------
// Name: RageLog()
// Desc:
//-----------------------------------------------------------------------------
void RageLog( LPCTSTR fmt, ...)
{
#if defined(DEBUG) | defined(_DEBUG)
va_list va;
va_start(va, fmt);
CString sBuff = vssprintf( fmt, va );
sBuff += "\n";
FILE *fp = NULL;
// open our logging file
fp = fopen( g_sLogFileName, "a" );
if( fp==NULL )
RageLog( ssprintf("Couldn't write to log %s", g_sLogFileName) );
fprintf(fp, sBuff);
fclose(fp);
#endif
}
//-----------------------------------------------------------------------------
// Name: ssprintf()
// Desc:
//-----------------------------------------------------------------------------
CString ssprintf( LPCTSTR fmt, ...)
{
va_list va;
va_start(va, fmt);
return vssprintf(fmt, va);
}
//-----------------------------------------------------------------------------
// Name: vssprintf()
// Desc:
//-----------------------------------------------------------------------------
CString vssprintf( LPCTSTR fmt, va_list argList)
{
CString str;
str.FormatV(fmt, argList);
return str;
}
//-----------------------------------------------------------------------------
// Name: join()
// Desc:
//-----------------------------------------------------------------------------
CString join(CString Deliminator, CStringArray& Source)
{
CString csReturn;
CString csTmp;
// Loop through the Array and Append the Deliminator
for( int iNum = 0; iNum < Source.GetSize(); iNum++ ) {
csTmp += Source.GetAt(iNum);
csTmp += Deliminator;
}
csReturn = csTmp.Left(csTmp.GetLength() - 1);
return csReturn;
}
//-----------------------------------------------------------------------------
// Name: split()
// Desc:
//-----------------------------------------------------------------------------
void split( CString Source, CString Deliminator, CStringArray& AddIt )
{
CString newCString;
CString tmpCString;
CString AddCString;
int pos1 = 0;
int pos = 0;
newCString = Source;
do {
pos1 = 0;
pos = newCString.Find(Deliminator, pos1);
if ( pos != -1 ) {
CString AddCString = newCString.Left(pos);
if (!AddCString.IsEmpty())
AddIt.Add(AddCString);
tmpCString = newCString.Mid(pos + Deliminator.GetLength());
newCString = tmpCString;
}
} while ( pos != -1 );
if (!newCString.IsEmpty())
AddIt.Add(newCString);
}
//-----------------------------------------------------------------------------
// Name: splitpath()
// Desc:
//-----------------------------------------------------------------------------
void splitpath (BOOL UsingDirsOnly, CString Path, CString& Drive, CString& Dir, CString& FName, CString& Ext)
{
int nSecond;
// Look for a UNC Name!
if (Path.Left(2) == "\\\\") {
int nFirst = Path.Find("\\",3);
nSecond = Path.Find("\\",nFirst + 1);
if (nSecond == -1) {
Drive = Path;
Dir = "";
FName = "";
Ext = "";
}
else if (nSecond > nFirst)
Drive = Path.Left(nSecond);
}
else { // Look for normal Drive Structure
nSecond = 2;
Drive = Path.Left(2);
}
if (UsingDirsOnly) {
Dir = Path.Right((Path.GetLength() - nSecond) - 1);
FName = "";
Ext = "";
}
else {
int nDirEnd = Path.ReverseFind('\\');
if (nDirEnd == Path.GetLength()) {
Dir = "";
FName = "";
Ext = "";
}
else {
Dir = Path.Mid(nSecond + 1, (nDirEnd - nSecond) - 1);
int nFileEnd = Path.ReverseFind('.');
if (nFileEnd != -1) {
if (nDirEnd > nFileEnd) {
FName = Path.Right(Path.GetLength() - nDirEnd);
Ext = "";
}
else {
FName = Path.Mid(nDirEnd + 1, (nFileEnd - nDirEnd) - 1);
Ext = Path.Right((Path.GetLength() - nFileEnd) - 1);
}
}
else {
FName = Path.Right((Path.GetLength() - nDirEnd) - 1);
Ext = "";
}
}
}
}
void GetDirListing( CString sPath, CStringArray &AddTo, BOOL bOnlyDirs )
{
WIN32_FIND_DATA fd;
HANDLE hFind = ::FindFirstFile( sPath, &fd );
if( INVALID_HANDLE_VALUE != hFind )
{
do
{
if( !bOnlyDirs || fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
CString sDirName( fd.cFileName );
if( sDirName != "." && sDirName != ".." )
AddTo.Add( sDirName );
}
} while( ::FindNextFile( hFind, &fd ) );
::FindClose( hFind );
}
}
BOOL DoesFileExist( CString sPath )
{
RageLog( "DoesFileExist(%s)", sPath );
DWORD dwAttr = GetFileAttributes( sPath );
if( dwAttr == (DWORD)-1 )
return FALSE;
else
return TRUE;
}
int CompareCStrings(const void *arg1, const void *arg2)
{
CString str1 = *(CString *)arg1;
CString str2 = *(CString *)arg2;
return str1.CompareNoCase( str2 );
}
void SortCStringArray( CStringArray &AddTo, BOOL bSortAcsending )
{
qsort( AddTo.GetData(), AddTo.GetSize(), sizeof(CString), CompareCStrings );
}
//-----------------------------------------------------------------------------
// Name: DisplayErrorAndDie()
// Desc:
//-----------------------------------------------------------------------------
VOID DisplayErrorAndDie( CString sError )
{
RageLog( "" );
RageLog( "// Fatal Error /////////////////////////////" );
RageLog( sError );
RageLog( "////////////////////////////////////////////" );
// Something very bad happened. Display an error dialog, then exit right away.
MessageBox(
NULL, // handle of owner window
sError, // text in message box
"Fatal Error", // address of title of message box
MB_OK | MB_ICONERROR // style of message box
);
exit(1);
}
+104
View File
@@ -0,0 +1,104 @@
//-----------------------------------------------------------------------------
// File: RageUtil.h
//
// Desc:
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _RAGEUTIL_H_
#define _RAGEUTIL_H_
//-----------------------------------------------------------------------------
// SAFE_ Macros
//-----------------------------------------------------------------------------
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
//-----------------------------------------------------------------------------
// Other Macros
//-----------------------------------------------------------------------------
#define RECTWIDTH(rect) ((rect).right - (rect).left)
#define RECTHEIGHT(rect) ((rect).bottom - (rect).top)
//-----------------------------------------------------------------------------
// Misc helper functions
//-----------------------------------------------------------------------------
// Simple function for generating random numbers
FLOAT randomf( FLOAT low=-1.0f, FLOAT high=1.0f );
int roundf( FLOAT f );
int roundf( double f );
CString ssprintf( LPCTSTR fmt, ...);
CString vssprintf( LPCTSTR fmt, va_list argList );
/*
@FUNCTION: Splits a Path into 4 parts (Directory, Drive, Filename, Extention).
NOTE: Supports UNC path names.
@PARAM1: Whether the Supplied Path (PARAM2) contains a directory name only
or a file name (Reason: some directories will end with "xxx.xxx"
which is like a file name).
@PARAM2: Path to Split.
@PARAM3: (Referenced) Directory.
@PARAM4: (Referenced) Drive.
@PARAM5: (Referenced) Filename.
@PARAM6: (Referenced) Extention.
*/
void splitpath(BOOL UsingDirsOnly, CString Path, CString& Drive, CString& Dir, CString& FName, CString& Ext);
/*
@FUNCTION: Splits a CString into an CStringArray according the Deliminator.
NOTE: Supports UNC path names.
@PARAM1: Source string to be Split.
@PARAM2: Deliminator.
@PARAM3: (Referenced) CStringArray to Add to.
*/
void split(CString Source, CString Deliminator, CStringArray& AddIt );
/*
@FUNCTION: Joins a CStringArray to create a CString according the Deliminator.
@PARAM1: Deliminator.
@PARAM2: (Referenced) CStringArray to Add to.
*/
CString join(CString Deliminator, CStringArray& Source);
void GetDirListing( CString sPath, CStringArray &AddTo, BOOL bOnlyDirs=FALSE );
BOOL DoesFileExist( CString sPath );
int CompareCStrings(const void *arg1, const void *arg2);
void SortCStringArray( CStringArray &AddTo, BOOL bSortAcsending = TRUE );
//-----------------------------------------------------------------------------
// Log helpers
//-----------------------------------------------------------------------------
void RageLogStart();
void RageLog( LPCTSTR fmt, ...);
//-----------------------------------------------------------------------------
// Error helpers
//-----------------------------------------------------------------------------
#include "dxerr8.h"
#pragma comment(lib, "dxerr8.lib")
VOID DisplayErrorAndDie( CString sError );
//#if defined(DEBUG) | defined(_DEBUG)
#define RageError(str) DisplayErrorAndDie( ssprintf( "%s\n\n%s(%d)", str, __FILE__, (DWORD)__LINE__, str) )
#define RageErrorHr(str,hr) DisplayErrorAndDie( ssprintf("%s (%s)\n\n%s(%d)", str, DXGetErrorString8(hr), __FILE__, (DWORD)__LINE__, str) )
//#else
// #define RageError(str) (0L)
// #define RageErrorHr(str,hr) (hr)
//#endif
#endif
+417
View File
@@ -0,0 +1,417 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: Song.cpp
//
// Desc: Holds metadata for a song and the song's step data.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#include "Util.h"
#include "IniFile.h"
#include "BmsFile.h"
#include "Steps.h"
#include "RageUtil.h"
#include "Song.h"
#include <assert.h>
//////////////////////////////
// Song
//////////////////////////////
bool Song::LoadFromSongDir( CString sDir )
{
RageLog( "Song::LoadFromSongDir(%s)", sDir );
// make sure there is a trailing '\\' at the end of sDir
if( sDir.Right(1) != "\\" )
sDir += "\\";
// save song dir
m_sSongDir = sDir;
// We are going to load from either a .song or .msd file.
// If no .song files exist, then look for an .msd.
CStringArray arrayBMSFileNames;
GetDirListing( sDir + CString("*.bms"), arrayBMSFileNames );
int iNumBMSFiles = arrayBMSFileNames.GetSize();
CStringArray arrayMSDFileNames;
GetDirListing( sDir + CString("*.msd"), arrayMSDFileNames );
int iNumMSDFiles = arrayMSDFileNames.GetSize();
/*
int j;
RageLog( "Found the following .bms files:" );
for( j=0; j<iNumBMSFiles; j++ )
RageLog( arrayBMSFileNames.GetAt(j) );
RageLog( "Found the following .msd files:" );
for( j=0; j<iNumMSDFiles; j++ )
RageLog( arrayMSDFileNames.GetAt(j) );
*/
if( iNumBMSFiles > 0 )
{
for( int i=0; i<iNumBMSFiles; i++ )
LoadFromBMSFile( sDir + arrayBMSFileNames.GetAt(i) );
}
else if( iNumMSDFiles == 1 )
{
//m_sSongFile = arrayMSDFileNames.GetAt( 0 );
//RageLog( "Found '%s'. Let's use it...", m_sSongFile );
//LoadFromMSDFile( sDir + m_sSongFile );
}
else if( iNumMSDFiles > 0 )
RageError( ssprintf("Found more than one MSD file in '%s'. Which should I use?", sDir) );
else
RageError( ssprintf("Couldn't find any BMS or MSD files in '%s'", sDir) );
return TRUE;
}
BOOL Song::LoadFromBMSFile( CString sPath )
{
RageLog( "Song::LoadFromBMSFile(%s)", sPath );
BmsFile bms( sPath );
bms.ReadFile();
Steps new_steps; // just assume one steps per file for now
CMapStringToString &mapValues = bms.mapValues;
POSITION pos = mapValues.GetStartPosition();
while( pos != NULL )
{
CString valuename;
CString data_string;
CStringArray data_array;
mapValues.GetNextAssoc( pos, valuename, data_string );
split(data_string, ":", data_array);
// handle the data
if( valuename == "#PLAYER" )
;
else if( valuename == "#GENRE" )
m_sCreator = data_array[0];
else if( valuename == "#TITLE" )
m_sTitle = data_array[0];
else if( valuename == "#ARTIST" )
m_sArtist = data_array[0];
else if( valuename == "#BPM" )
m_fBPM = (FLOAT)atof( data_array[0] );
else if( valuename == "#PLAYLEVEL" )
new_steps.iDifficulty = atoi( data_array[0] );
else if( valuename == "#BackBMP" || valuename == "#backBMP")
m_sBackground = data_array[0];
else if( valuename == "#WAV99" )
m_sMusic = data_array[0];
else if( valuename.GetLength() == 6 ) // this is probably step or offset data. Looks like "#00705"
{
int iMeasureNo = atoi( valuename.Mid(1,3) );
int iNoteNum = atoi( valuename.Mid(4,2) );
CString sNoteData = data_array[0];
CArray<BOOL, BOOL&> arrayNotes;
for( int i=0; i<sNoteData.GetLength(); i+=2 )
{
BOOL bThisIsANote = sNoteData.Mid(i,2) == "01" // step
|| sNoteData.Mid(i,2) == "99"; // offset
arrayNotes.Add( bThisIsANote );
}
const int iNumNotesInThisMeasure = arrayNotes.GetSize();
//RageLog( "%s:%s: iMeasureNo = %d, iNoteNum = %d, iNumNotesInThisMeasure = %d",
// valuename, sNoteData, iMeasureNo, iNoteNum, iNumNotesInThisMeasure );
for( int j=0; j<iNumNotesInThisMeasure; j++ )
{
if( arrayNotes.GetAt(j) == TRUE )
{
FLOAT fPercentThroughMeasure = (FLOAT)j/(FLOAT)iNumNotesInThisMeasure;
// index is in quarter beats starting at beat 0
int iStepIndex = (int) ( (iMeasureNo + fPercentThroughMeasure)
* BEATS_IN_MEASURE * ELEMENTS_PER_BEAT );
// BMS encoding:
// 4&8panel: Player1 Player2
// Left 11 21
// Down 13 23
// Up 15 25
// Right 16 26
// 6panel: Player1 Player2
// Left 11 21
// Left+Up 12 22
// Down 13 23
// Up 14 24
// Up+Right 15 25
// Right 16 26
//
// Notice that 15 and 25 have two different meanings! What were they thinking???
// While reading in, use the 6 panel mapping. After reading in, detect if only 4 notes
// are filled in. If so, shift the Up+Right column back to the Up column
//
// Our internal encoding:
// 0x0001 left player 1
// 0x0002 left+up player 1
// 0x0004 down player 1
// 0x0008 up player 1
// 0x0010 up+right player 1
// 0x0020 right player 1
// 0x0040 left player 2
// 0x0080 left+up player 2
// 0x0100 down player 2
// 0x0200 up player 2
// 0x0400 up+right player 2
// 0x0800 right player 2
CMap<int, int, Step, Step> mapBMSNumberToOurStepBit;
mapBMSNumberToOurStepBit[11] = 0x0001;
mapBMSNumberToOurStepBit[12] = 0x0002;
mapBMSNumberToOurStepBit[13] = 0x0004;
mapBMSNumberToOurStepBit[14] = 0x0008;
mapBMSNumberToOurStepBit[15] = 0x0010;
mapBMSNumberToOurStepBit[16] = 0x0020;
mapBMSNumberToOurStepBit[21] = 0x0040;
mapBMSNumberToOurStepBit[22] = 0x0080;
mapBMSNumberToOurStepBit[23] = 0x0100;
mapBMSNumberToOurStepBit[24] = 0x0200;
mapBMSNumberToOurStepBit[25] = 0x0400;
mapBMSNumberToOurStepBit[26] = 0x0800;
new_steps.StepArray[iStepIndex] |= mapBMSNumberToOurStepBit[iNoteNum];
new_steps.StatusArray[iStepIndex] = not_stepped_on;
}
}
}
}
int iNumSteps = 0;
for( int i=0; i<new_steps.StatusArray.GetSize(); i++ ) {
if( new_steps.StatusArray[i] == not_stepped_on ) {
iNumSteps++;
}
}
RageLog( "%d of %d steps elements are filled", iNumSteps, new_steps.StatusArray.GetSize() );
// we're done reading in all of the BMS values
if( m_sTitle.Find("<BASIC>") >0 ) new_steps.sDescription = "BASIC";
else if( m_sTitle.Find("<ANOTHER>") >0 ) new_steps.sDescription = "ANOTHER";
else if( m_sTitle.Find("<TRICK>") >0 ) new_steps.sDescription = "TRICK";
else if( m_sTitle.Find("<MANIAC>") >0 ) new_steps.sDescription = "MANIAC";
else if( m_sTitle.Find("<SSR>") >0 ) new_steps.sDescription = "SSR";
else if( m_sTitle.Find("<6PANELS BASIC>") >0 ) new_steps.sDescription = "BASIC";
else if( m_sTitle.Find("<6PANELS ANOTHER>") >0 ) new_steps.sDescription = "ANOTHER";
else if( m_sTitle.Find("<6PANELS TRICK>") >0 ) new_steps.sDescription = "TRICK";
else if( m_sTitle.Find("<6PANELS MANIAC>") >0 ) new_steps.sDescription = "MANIAC";
else if( m_sTitle.Find("<6PANELS SSR>") >0 ) new_steps.sDescription = "SSR";
else if( m_sTitle.Find("<BASIC DOUBLE>") >0 ) new_steps.sDescription = "BASIC DOUBLE";
else if( m_sTitle.Find("<ANOTHER DOUBLE>") >0 ) new_steps.sDescription = "ANOTHER DOUBLE";
else if( m_sTitle.Find("<TRICK DOUBLE>") >0 ) new_steps.sDescription = "TRICK DOUBLE";
else if( m_sTitle.Find("<MANIAC DOUBLE>") >0 ) new_steps.sDescription = "MANIAC DOUBLE";
else if( m_sTitle.Find("<SSR DOUBLE>") >0 ) new_steps.sDescription = "SSR DOUBLE";
else if( m_sTitle.Find("<COUPLE>") >0 ) new_steps.sDescription = "COUPLE";
else if( m_sTitle.Find("<BATTLE>") >0 ) new_steps.sDescription = "BATTLE";
else new_steps.sDescription = "UNKNOWN";
if( new_steps.sDescription.Find("COUPLE") >0 ) new_steps.type = st_couple;
else if( new_steps.sDescription.Find("BATTLE") >0 ) new_steps.type = st_couple;
else if( new_steps.sDescription.Find("DOUBLE") >0 ) new_steps.type = st_double;
else new_steps.type = st_single;
arraySteps.Add( new_steps );
// strip steps type out of description
m_sTitle.Replace( " <" + new_steps.sDescription + ">", "" );
FillEmptyValuesWithDefaults();
return TRUE;
}
BOOL Song::LoadFromMSDFile( CString sPath )
{
RageLog( "Song::LoadFromMSDFile(%s)", sPath );
// BROKEN
/*
CStdioFile file;
if( !file.Open( GetSongFilePath(), CFile::modeRead ) )
RageError( ssprintf("Error opening Song 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 );
// for each value expression string, parse it into a value name and data
for( int i=0; i < arrayValueStrings.GetSize(); i++ )
{
CString sValueString = arrayValueStrings[i];
// split the value string into tokens
CStringArray arrayValueTokens;
split( sValueString, ":", arrayValueTokens );
CString sValueName = arrayValueTokens.GetAt( 0 );
// handle the data
if( sValueName == "#TITLE" )
m_sTitle = arrayValueTokens[1];
else if( sValueName == "#ARTIST" )
m_sArtist = arrayValueTokens[1];
else if( sValueName == "#REMIXER" || sValueName == "#MSD")
m_sCreator = arrayValueTokens[1];
else if( sValueName == "#BPM" )
m_fBPM = (FLOAT)atof( arrayValueTokens[1] );
else if( sValueName == "#OFFSET" )
m_fBeatOffset = (FLOAT)atoi( arrayValueTokens[1] );
else if( sValueName == "#GAP" )
// the units of GAP is 1/10 second
m_fBeatOffset = (FLOAT)atof( arrayValueTokens[1] ) / 10.0f;
else if( sValueName == "#MUSIC" )
m_sMusic = arrayValueTokens[1];
else if( sValueName == "#SAMPLE" )
m_sSample = arrayValueTokens[1];
else if( sValueName == "#BANNER" )
m_sBanner = arrayValueTokens[1];
else if( sValueName == "#BACKGROUND" )
m_sBackground = arrayValueTokens[1];
// handle STEPS defined in the file for backwards compatibility with MSD files
else if( sValueName == "#SINGLE" || sValueName == "#DOUBLE" || sValueName == "#COUPLE" )
{
Steps s;
if( sValueName == "#SINGLE" )
s.type = st_single;
else if( sValueName == "#DOUBLE" )
s.type = st_double;
else if( sValueName == "#COUPLE" )
s.type = st_couple;
else
RageError( ssprintf("Unknown game type '%s' in '%s'", sValueName, GetSongFilePath()) );
s.sDescription = arrayValueTokens[1];
s.iDifficulty = atoi( arrayValueTokens[2] );
s.sPadDataLeft = arrayValueTokens[3];
if( sValueName == "#DOUBLE" || sValueName == "#COUPLE" )
s.sPadDataRight = arrayValueTokens[4];
switch( s.type)
{
case st_single:
arraySingleSteps.Add( s );
break;
case st_double:
arrayDoubleSteps.Add( s );
break;
case st_couple:
arrayCoupleSteps.Add( s );
break;
}
}
else
// do nothing. We don't care about this value name
;
}
FillEmptyValuesWithDefaults();
*/
return TRUE;
}
void Song::FillEmptyValuesWithDefaults()
{
if( m_sTitle == "" ) m_sTitle = "Untitled song";
if( m_sArtist == "" ) m_sArtist = "Unknown artist";
if( m_sCreator == "" ) m_sCreator = "";
if( m_fBPM == 0.0 )
RageError( ssprintf("No #BPM specified in '%s.'", GetSongFilePath()) );
if( m_fBeatOffset == 0.0 )
RageLog( "Warning: #OFFSET or #GAP in '%s' is either 0.0, or was missing.", GetSongFilePath() );
if( m_sMusic == "" )
{
m_sMusic = "music.mp3";
if( !DoesFileExist( m_sSongDir + m_sMusic ) )
{
// music.mp3 didn't exist, so search for any mp3 in the same dir
CStringArray arrayMP3Files;
GetDirListing( m_sSongDir + CString("*.mp3"), arrayMP3Files );
if( arrayMP3Files.GetSize() != 0 ) // we found a .mp3 file!
m_sMusic = arrayMP3Files.GetAt( 0 );
else
RageError( ssprintf("Music could not be found. In Song file '%s' no #MUSIC was specified, music.mp3 doesn't exist, and no other MP3s could be found.", GetSongFilePath()) );
}
}
if( m_sSample == "" )
{
m_sSample = "sample.mp3";
if( !DoesFileExist( m_sSongDir + m_sSample ) )
m_sSample = m_sMusic; // we assured above that the m_sMusic file exists
}
if( m_sBanner == "" )
{
m_sBanner = "banner.bmp";
if( !DoesFileExist( m_sSongDir + m_sBanner ) )
{
m_sBanner = "banner.png";
if( !DoesFileExist( m_sSongDir + m_sBanner ) )
{
// couldn't find a true banner, so search for any bmp in the same dir
CStringArray arrayBMPFiles;
GetDirListing( m_sSongDir + CString("*.bmp"), arrayBMPFiles );
if( arrayBMPFiles.GetSize() != 0 ) // we found a .bmp file!
m_sBanner = arrayBMPFiles.GetAt( 0 );
else
RageError( ssprintf("Banner could not be found. In Song file '%s' no #BANNER was specified, banner.bmp doesn't exist, and no other BMPs could be found.", GetSongFilePath()) );
}
}
}
if( m_sBackground == "" )
{
m_sBackground = "background.bmp";
if( !DoesFileExist( m_sSongDir + m_sBackground ) )
m_sBackground = m_sBanner; // we assured above that the m_sBanner file exists
}
}
+376
View File
@@ -0,0 +1,376 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: Sprite.cpp
//
// Desc: A bitmap actor that animates and moves around.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#include "Sprite.h"
#include "RageTextureManager.h"
#include "IniFile.h"
#include <assert.h>
#include <math.h>
Sprite::Sprite()
{
Init();
}
void Sprite::Init()
{
Actor::Init();
m_pTexture = NULL;
m_uNumStates = 0;
m_uCurState = 0;
m_bIsAnimating = TRUE;
m_fSecsIntoState = 0.0;
m_bUsingCustomSrcRect = FALSE ;
m_Effect = no_effect ;
m_fPercentBetweenColors = 0.0f ;
m_bTweeningTowardEndColor = TRUE ;
m_fDeltaPercentPerSecond = 1.0 ;
m_fWagRadians = 0.2f ;
m_fWagPeriod = 2.0f ;
m_fWagTimer = 0.0f ;
m_fSpinSpeed = 2.0f ;
m_fVibrationDistance = 5.0f ;
m_bVisibleThisFrame = FALSE;
m_bBlendAdd = FALSE;
}
Sprite::~Sprite()
{
// RageLog( "Sprite Destructor" );
TM->UnloadTexture( m_sTexturePath );
}
BOOL Sprite::LoadFromTexture( CString sTexturePath )
{
RageLog( ssprintf("Sprite::LoadFromTexture(%s)", sTexturePath) );
Init();
return LoadTexture( sTexturePath );
}
// Sprite file has the format:
//
// [Sprite]
// Texture=Textures\Logo 1x1.bmp
// Frame0000=0
// Delay0000=1.0
// Frame0001=3
// Delay0000=2.0
BOOL Sprite::LoadFromSpriteFile( CString sSpritePath )
{
RageLog( ssprintf("Sprite::LoadFromSpriteFile(%s)", sSpritePath) );
Init();
m_sSpritePath = sSpritePath;
// read sprite file
IniFile ini;
ini.SetPath( m_sSpritePath );
if( !ini.ReadFile() )
RageError( ssprintf("Error opening Sprite file '%s'.", m_sSpritePath) );
CString sTexturePath = ini.GetValue( "Sprite", "Texture" );
if( sTexturePath == "" )
RageError( ssprintf("Error reading value 'Texture' from %s.", m_sSpritePath) );
// Load the texture
if( !LoadTexture( sTexturePath ) )
return FALSE;
// Read in frames and delays from the sprite file,
// overwriting the states that LoadFromTexture created.
for( UINT i=0; i<MAX_SPRITE_STATES; i++ )
{
CString sStateNo;
sStateNo.Format( "%u%u%u%u", (i%10000)/1000, (i%1000)/100, (i%100)/10, (i%10) ); // four digit state no
CString sFrameKey( CString("Frame") + sStateNo );
CString sDelayKey( CString("Delay") + sStateNo );
m_uFrame[i] = ini.GetValueI( "Sprite", sFrameKey );
if( m_uFrame[i] >= m_pTexture->GetNumFrames() )
RageError( ssprintf("In '%s', %s is %d, but the texture %s only has %d frames.",
m_sSpritePath, sFrameKey, m_uFrame[i], sTexturePath, m_pTexture->GetNumFrames()) );
m_fDelay[i] = (float)ini.GetValueF( "Sprite", sDelayKey );
if( m_uFrame[i] == 0 && m_fDelay[i] > -0.00001f && m_fDelay[i] < 0.00001f ) // both values are empty
break;
m_uNumStates = i+1;
}
if( m_uNumStates == 0 )
RageError( ssprintf("Failed to find at least one state in %s.", m_sSpritePath) );
return TRUE;
}
BOOL Sprite::LoadTexture( CString sTexturePath )
{
if( m_sTexturePath != "" ) // If there was a previous bitmap...
TM->UnloadTexture( m_sTexturePath ); // Unload it.
m_sTexturePath = sTexturePath;
m_pTexture = TM->LoadTexture( m_sTexturePath );
assert( m_pTexture != NULL );
SetWidth( (FLOAT)m_pTexture->GetFrameWidth() );
SetHeight( (FLOAT)m_pTexture->GetFrameHeight() );
// Assume the frames of this animation play in sequential order with 0.2 second delay.
for( UINT i=0; i<m_pTexture->GetNumFrames(); i++ )
{
m_uFrame[i] = i;
m_fDelay[i] = 0.1f;
m_uNumStates = i+1;
}
return TRUE;
}
void Sprite::PrintDebugInfo()
{
// Actor::PrintDebugInfo();
RageLog( "Sprite::PrintDebugInfo()" );
RageLog( "m_uNumStates: %u, m_uCurState: %u, m_fSecsIntoState: %f",
m_uNumStates, m_uCurState, m_fSecsIntoState );
}
void Sprite::Update( const FLOAT &fDeltaTime )
{
//PrintDebugInfo();
Actor::Update( fDeltaTime ); // do tweening
// update animation
if( m_bIsAnimating )
{
m_fSecsIntoState += fDeltaTime;
if( m_fSecsIntoState > m_fDelay[m_uCurState] ) // it's time to switch frames
{
// increment frame and reset the counter
m_fSecsIntoState -= m_fDelay[m_uCurState]; // leave the left over time for the next frame
m_uCurState ++;
if( m_uCurState >= m_uNumStates )
m_uCurState = 0;
}
}
// update SpriteEffect
switch( m_Effect )
{
case no_effect:
break;
case blinking:
case camelion:
case glowing:
if( m_bTweeningTowardEndColor ) {
m_fPercentBetweenColors += m_fDeltaPercentPerSecond * fDeltaTime;
if( m_fPercentBetweenColors > 1.0f ) {
m_fPercentBetweenColors = 1.0f;
m_bTweeningTowardEndColor = FALSE;
}
}
else { // !m_bTweeningTowardEndColor
m_fPercentBetweenColors -= m_fDeltaPercentPerSecond * fDeltaTime;
if( m_fPercentBetweenColors < 0.0f ) {
m_fPercentBetweenColors = 0.0f;
m_bTweeningTowardEndColor = TRUE;
}
}
case wagging:
m_fWagTimer += fDeltaTime;
if( m_fWagTimer > m_fWagPeriod )
m_fWagTimer -= m_fWagPeriod;
break;
case spinning:
FLOAT rotation;
rotation = GetRotation();
rotation += m_fSpinSpeed * fDeltaTime;
if( rotation > 2.0f * D3DX_PI )
rotation -= 2.0f * D3DX_PI;
else if( rotation < 0.0f )
rotation += 2.0f * D3DX_PI;
SetRotation( rotation );
break;
case vibrating:
break;
case flickering:
break;
}
}
void Sprite::Draw()
{
if( m_pTexture == NULL )
return;
UINT uFrameNo = m_uFrame[m_uCurState];
LPRECT pRectSrc;
if( m_bUsingCustomSrcRect )
pRectSrc = &m_rectCustomSrcRect;
else
pRectSrc = m_pTexture->GetFrameRect( uFrameNo );
//::SetRect( &rectSrc, 0, 0, m_pTexture->GetImageWidth(), m_pTexture->GetImageHeight() );
D3DXVECTOR2 scaling;
scaling.x = GetZoom();
scaling.y = GetZoom();
D3DXVECTOR2 translation;
translation.x = (float)GetLeftEdge();
translation.y = (float)GetTopEdge();
D3DXVECTOR3 rotation = m_rotation;
D3DXVECTOR2 rot_center;
rot_center.x = GetZoomedWidth()/2.0f;
rot_center.y = GetZoomedHeight()/2.0f;
D3DXCOLOR color = m_color;
// update SpriteEffect
switch( m_Effect )
{
case no_effect:
break;
case blinking:
color = m_bTweeningTowardEndColor ? m_start_color : m_end_color;
break;
case camelion:
case glowing:
color = m_start_color*m_fPercentBetweenColors + m_end_color*(1.0f-m_fPercentBetweenColors);
break;
case wagging:
rotation.z = m_fWagRadians * (FLOAT)sin(
(m_fWagTimer / m_fWagPeriod) // percent through wag
* 2.0 * D3DX_PI );
break;
case spinning:
// nothing special needed
break;
case vibrating:
translation.x += m_fVibrationDistance * randomf(-1.0f, 1.0f) * GetZoom();
translation.y += m_fVibrationDistance * randomf(-1.0f, 1.0f) * GetZoom();
break;
case flickering:
m_bVisibleThisFrame = !m_bVisibleThisFrame;
if( m_bVisibleThisFrame )
return; // don't draw the frame
break;
}
SCREEN->DrawQuad( m_pTexture,
pRectSrc,
&scaling, // scaling
&rot_center, // rotation center
&rotation, // rotation
&translation, // translation
color,
m_Effect == glowing ? op_add : op_modulate,
m_bBlendAdd );
}
void Sprite::SetState( UINT uNewState )
{
ASSERT( uNewState >= 0 && uNewState < m_uNumStates );
m_uCurState = uNewState;
m_fSecsIntoState = 0.0;
}
void Sprite::SetCustomSrcRect( RECT newRect )
{
m_bUsingCustomSrcRect = TRUE;
m_rectCustomSrcRect = newRect;
SetWidth( (FLOAT) RECTWIDTH(newRect) );
SetHeight( (FLOAT) RECTHEIGHT(newRect) );
};
VOID Sprite::SetEffectNone()
{
m_Effect = no_effect;
//m_color = D3DXCOLOR( 1.0,1.0,1.0,1.0 );
}
VOID Sprite::SetEffectBlinking( FLOAT fDeltaPercentPerSecond, D3DXCOLOR Color, D3DXCOLOR Color2 )
{
m_Effect = blinking;
m_start_color = Color;
m_end_color = Color2;
//m_fPercentBetweenColors = 0.0;
//m_bTweeningTowardEndColor = TRUE;
m_fDeltaPercentPerSecond = fDeltaPercentPerSecond;
}
VOID Sprite::SetEffectCamelion( FLOAT fDeltaPercentPerSecond, D3DXCOLOR Color, D3DXCOLOR Color2 )
{
m_Effect = camelion;
m_start_color = Color;
m_end_color = Color2;
//m_fPercentBetweenColors = 0.0;
//m_bTweeningTowardEndColor = TRUE;
m_fDeltaPercentPerSecond = fDeltaPercentPerSecond;
}
VOID Sprite::SetEffectGlowing( FLOAT fDeltaPercentPerSecond, D3DXCOLOR Color, D3DXCOLOR Color2 )
{
m_Effect = glowing;
m_start_color = Color;
m_end_color = Color2;
//m_fPercentBetweenColors = 0.0;
//m_bTweeningTowardEndColor = TRUE;
m_fDeltaPercentPerSecond = fDeltaPercentPerSecond;
}
VOID Sprite::SetEffectWagging( FLOAT fWagRadians, FLOAT fWagPeriod )
{
m_Effect = wagging;
m_fWagRadians = fWagRadians;
m_fWagPeriod = fWagPeriod;
}
VOID Sprite::SetEffectSpinning( FLOAT fSpinSpeed /*radians per second*/ )
{
m_Effect = spinning;
m_fSpinSpeed = fSpinSpeed;
}
VOID Sprite::SetEffectVibrating( FLOAT fVibrationDistance )
{
m_Effect = vibrating;
m_fVibrationDistance = fVibrationDistance;
}
VOID Sprite::SetEffectFlickering()
{
m_Effect = flickering;
}
+122
View File
@@ -0,0 +1,122 @@
//-----------------------------------------------------------------------------
// File: Sprite.h
//
// Desc: A bitmap Actor that animates and moves around.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _SPRITE_H_
#define _SPRITE_H_
#include "Actor.h"
#include "RageUtil.h"
#include "RageTexture.h"
#define MAX_SPRITE_STATES 256
class Sprite: public Actor
{
public:
Sprite();
virtual ~Sprite();
enum SpriteEffect { no_effect,
blinking, camelion, glowing,
wagging, spinning,
vibrating, flickering
};
BOOL LoadFromTexture( CString sTexturePath );
BOOL LoadFromSpriteFile( CString sSpritePath );
VOID PrintDebugInfo();
virtual void Draw();
virtual void Update( const FLOAT &fDeltaTime );
void StartAnimating() { m_bIsAnimating = TRUE; };
void StopAnimating() { m_bIsAnimating = FALSE; };
void SetState( UINT uNewState );
UINT GetNumStates() { return m_uNumStates; };
CString GetTexturePath() { return m_sTexturePath; };
VOID SetCustomSrcRect( RECT newRect ); // for cropping or flipping
VOID SetEffectNone();
VOID SetEffectBlinking( FLOAT fDeltaPercentPerSecond = 2.5,
D3DXCOLOR Color = D3DXCOLOR(0.5f,0.5f,0.5f,1),
D3DXCOLOR Color2 = D3DXCOLOR(1,1,1,1) );
VOID SetEffectCamelion( FLOAT fDeltaPercentPerSecond = 2.5,
D3DXCOLOR Color = D3DXCOLOR(0,0,0,1),
D3DXCOLOR Color2 = D3DXCOLOR(1,1,1,1) );
VOID SetEffectGlowing( FLOAT fDeltaPercentPerSecond = 2.5,
D3DXCOLOR Color = D3DXCOLOR(0.4f,0.4f,0.4f,0),
D3DXCOLOR Color2 = D3DXCOLOR(1.0f,1.0f,1.0f,0) );
VOID SetEffectWagging( FLOAT fWagRadians = 0.2,
FLOAT fWagPeriod = 2.0 );
VOID SetEffectSpinning( FLOAT fRadsPerSpeed = 2.0 );
VOID SetEffectVibrating( FLOAT fVibrationDistance = 5.0 );
VOID SetEffectFlickering();
SpriteEffect GetEffect() { return m_Effect; };
VOID SetBlendMode( BOOL bBlendAdd ) { m_bBlendAdd = bBlendAdd; };
protected:
void Init();
BOOL LoadTexture( CString sTexture );
CString m_sSpritePath;
LPRageTexture m_pTexture;
CString m_sTexturePath;
UINT m_uFrame[MAX_SPRITE_STATES]; // array of indicies into m_rectBitmapFrames
FLOAT m_fDelay[MAX_SPRITE_STATES];
UINT m_uNumStates;
UINT m_uCurState;
BOOL m_bIsAnimating;
FLOAT m_fSecsIntoState; // number of seconds that have elapsed since we switched to this frame
BOOL m_bBlendAdd;
BOOL m_bUsingCustomSrcRect;
RECT m_rectCustomSrcRect;
SpriteEffect m_Effect;
// Counting variables for sprite effects:
// camelion and glowing:
// D3DXCOLOR m_Color2;
FLOAT m_fPercentBetweenColors;
BOOL m_bTweeningTowardEndColor; // TRUE is fading toward end_color, FALSE if fading toward start_color
FLOAT m_fDeltaPercentPerSecond; // percentage change in tweening per second
// wagging:
FLOAT m_fWagRadians;
FLOAT m_fWagPeriod; // seconds to complete a wag (back and forth)
FLOAT m_fWagTimer; // num of seconds into this wag
// spinning:
FLOAT m_fSpinSpeed; // radians per second
// vibrating:
FLOAT m_fVibrationDistance;
// flickering:
BOOL m_bVisibleThisFrame;
};
#endif
+6
View File
@@ -0,0 +1,6 @@
// stdafx.cpp : source file that includes just the standard includes
// Basic.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
+26
View File
@@ -0,0 +1,26 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__9FF379EB_FAE2_11D1_BFC5_D41F722B624A__INCLUDED_)
#define AFX_STDAFX_H__9FF379EB_FAE2_11D1_BFC5_D41F722B624A__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxtempl.h> // MFC templated collections
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__9FF379EB_FAE2_11D1_BFC5_D41F722B624A__INCLUDED_)
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

+133
View File
@@ -0,0 +1,133 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDR_MAIN_ACCEL ACCELERATORS DISCARDABLE
BEGIN
"P", IDM_PADS, VIRTKEY, CONTROL, NOINVERT
VK_ESCAPE, IDM_WINDOWED, VIRTKEY, NOINVERT
VK_F4, IDM_TOGGLEFULLSCREEN, VIRTKEY, NOINVERT
VK_RETURN, IDM_TOGGLEFULLSCREEN, VIRTKEY, ALT, NOINVERT
"X", IDM_EXIT, VIRTKEY, ALT, NOINVERT
END
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON ICON DISCARDABLE "StepMania.ICO"
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Chris Danford\0"
VALUE "FileDescription", "StepMania\0"
VALUE "FileVersion", "1, 0, 0, 1\0"
VALUE "InternalName", "StepMania\0"
VALUE "LegalCopyright", "Copyright © 2001\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "StepMania.exe\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", " StepMania\0"
VALUE "ProductVersion", "1, 0, 0, 1\0"
VALUE "SpecialBuild", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
+477
View File
@@ -0,0 +1,477 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: StepMania.cpp
//
// Desc:
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include "resource.h"
#include "RageScreen.h"
#include "RageTextureManager.h"
#include "RageSound.h"
#include "RageMusic.h"
#include "RageInput.h"
#include "GameOptions.h"
#include "WindowManager.h"
#include "WindowIntroCovers.h"
#include <DXUtil.h>
//-----------------------------------------------------------------------------
// Links
//-----------------------------------------------------------------------------
#pragma comment(lib, "d3dx8.lib")
#pragma comment(lib, "d3d8.lib")
//-----------------------------------------------------------------------------
// Application globals
//-----------------------------------------------------------------------------
const CString g_sAppName = "StepMania";
const CString g_sAppClassName = "StepMania Class";
HWND g_hWndMain; // Main Window Handle
HINSTANCE g_hInstance; // The Handle to Window Instance
const DWORD g_dwScreenWidth = 640; // The window width
const DWORD g_dwScreenHeight = 480; // The window height
const DWORD g_dwWindowStyle = WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_SYSMENU;
BOOL g_bFullscreen = FALSE; // Whether app is fullscreen (or windowed)
BOOL g_bIsActive = FALSE; // Whether the focus is on our app
//LPRageMovieTexture g_pMovieTexture = NULL;
//-----------------------------------------------------------------------------
// Function prototypes
//-----------------------------------------------------------------------------
// Main game functions
LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
void Update(); // Update the game logic
void Render(); // Render a frame
void ShowFrame(); // Display the contents of the back buffer to the screen
void SetFullscreen( BOOL bFullscreen ); // Switch between fullscreen and windowed modes.
// Functions that work with game objects
HRESULT CreateObjects( HWND hWnd ); // allocate and initialize game objects
HRESULT InvalidateObjects(); // invalidate game objects before a display mode change
HRESULT RestoreObjects(); // restore game objects after a display mode change
VOID DestroyObjects(); // deallocate game objects when we're done with them
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: Application entry point
//-----------------------------------------------------------------------------
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow )
{
CoInitialize (NULL); // Initialize COM
// Register the window class
WNDCLASS wndClass = {
0,
WndProc, // callback handler
0, // cbClsExtra;
0, // cbWndExtra;
hInstance,
LoadIcon( hInstance, MAKEINTRESOURCE(IDI_ICON) ),
LoadCursor( hInstance, IDC_ARROW),
(HBRUSH)GetStockObject( BLACK_BRUSH ),
NULL, // lpszMenuName;
g_sAppClassName // lpszClassName;
};
RegisterClass( &wndClass );
// Set the window's initial width
RECT rcWnd;
SetRect( &rcWnd, 0, 0, g_dwScreenWidth, g_dwScreenHeight );
AdjustWindowRect( &rcWnd, g_dwWindowStyle, FALSE );
// Create our main window
g_hWndMain = CreateWindow(
g_sAppClassName,// pointer to registered class name
g_sAppName, // pointer to window name
g_dwWindowStyle, // window style
CW_USEDEFAULT, // horizontal position of window
CW_USEDEFAULT, // vertical position of window
RECTWIDTH(rcWnd), // window width
RECTHEIGHT(rcWnd),// window height
NULL, // handle to parent or owner window
NULL, // handle to menu, or child-window identifier
hInstance, // handle to application instance
NULL // pointer to window-creation data
);
if( NULL == g_hWndMain )
exit(1);
// Load keyboard accelerators
HACCEL hAccel = LoadAccelerators( NULL, MAKEINTRESOURCE(IDR_MAIN_ACCEL) );
// run the game
CreateObjects( g_hWndMain ); // Create the game objects
// Now we're ready to recieve and process Windows messages.
MSG msg;
ZeroMemory( &msg, sizeof(msg) );
while( WM_QUIT != msg.message )
{
// Look for messages, if none are found then
// update the state and display it
if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
{
GetMessage(&msg, NULL, 0, 0 );
// Translate and dispatch the message
if( 0 == TranslateAccelerator( g_hWndMain, hAccel, &msg ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
else // No messages are waiting. Render a frame during idle time.
{
Update();
Render();
ShowFrame();
//if( !g_bFullscreen )
::Sleep(16); // cap the frame rate to ~30 fps for now
}
} // end while( WM_QUIT != msg.message )
// clean up after a normal exit
DestroyObjects(); // deallocate our game objects and leave fullscreen
DestroyWindow( g_hWndMain );
UnregisterClass( g_sAppClassName, hInstance );
CoUninitialize(); // Uninitialize COM
return 0L;
}
//-----------------------------------------------------------------------------
// Name: WndProc()
// Desc: Callback for all Windows messages
//-----------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_ACTIVATEAPP:
// Check to see if we are losing our window...
g_bIsActive = (BOOL)wParam;
break;
case WM_SIZE:
// Check to see if we are losing our window...
if( SIZE_MAXIMIZED == wParam)
MessageBeep( MB_OK );
else if( SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam )
g_bIsActive = FALSE;
else
g_bIsActive = TRUE;
break;
case WM_GETMINMAXINFO:
{
// don't allow the window to be resized smaller than the screen resolution
RECT rcWnd;
SetRect( &rcWnd, 0, 0, g_dwScreenWidth, g_dwScreenHeight );
DWORD dwWindowStyle = GetWindowLong( g_hWndMain, GWL_STYLE );
AdjustWindowRect( &rcWnd, dwWindowStyle, FALSE );
((MINMAXINFO*)lParam)->ptMinTrackSize.x = RECTWIDTH(rcWnd);
((MINMAXINFO*)lParam)->ptMinTrackSize.y = RECTHEIGHT(rcWnd);
}
break;
case WM_SETCURSOR:
// Turn off Windows cursor in fullscreen mode
if( g_bFullscreen )
{
SetCursor( NULL );
return TRUE; // prevent Windows from setting the cursor
}
break;
case WM_SYSCOMMAND:
// Prevent moving/sizing and power loss
switch( wParam )
{
case SC_MOVE:
case SC_SIZE:
case SC_KEYMENU:
case SC_MONITORPOWER:
return 1;
case SC_MAXIMIZE:
SendMessage( g_hWndMain, WM_COMMAND, IDM_TOGGLEFULLSCREEN, 0 );
return 1;
break;
}
break;
case WM_COMMAND:
switch( LOWORD(wParam) )
{
case IDM_TOGGLEFULLSCREEN:
SetFullscreen( !g_bFullscreen );
return 0;
case IDM_WINDOWED:
SetFullscreen( FALSE );
return 0;
case IDM_EXIT:
// Recieved key/menu command to exit app
SendMessage( hWnd, WM_CLOSE, 0, 0 );
return 0;
case IDM_PADS:
return 0;
}
break;
case WM_NCHITTEST:
// Prevent the user from selecting the menu in fullscreen mode
if( g_bFullscreen )
return HTCLIENT;
break;
case WM_PAINT:
// redisplay the contents of the back buffer if the window needs to be redrawn
ShowFrame();
break;
case WM_DESTROY:
PostQuitMessage( 0 );
break;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
//-----------------------------------------------------------------------------
// Name: CreateObjects()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CreateObjects( HWND hWnd )
{
SCREEN = new RageScreen( hWnd );
TM = new RageTextureManager( SCREEN );
SOUND = new RageSound( hWnd );
MUSIC = new RageMusic;
INPUT = new RageInput( hWnd );
GAMEOPTIONS = new GameOptions;
WM = new WindowManager;
RageLogStart();
WM->SetNewWindow( new WindowIntroCovers );
srand( (unsigned)time(NULL) );
// Start the accurate timer
DXUtil_Timer( TIMER_START );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DestroyObjects()
// Desc:
//-----------------------------------------------------------------------------
void DestroyObjects()
{
// Setup the app so it can support single-stepping
DXUtil_Timer( TIMER_STOP );
SAFE_DELETE( WM );
SAFE_DELETE( GAMEOPTIONS );
SAFE_DELETE( INPUT );
SAFE_DELETE( MUSIC );
SAFE_DELETE( SOUND );
SAFE_DELETE( TM );
SAFE_DELETE( SCREEN );
}
//-----------------------------------------------------------------------------
// Name: RestoreObjects()
// Desc:
//-----------------------------------------------------------------------------
HRESULT RestoreObjects()
{
/////////////////////
// Restore the window
/////////////////////
// Set window size
RECT rcWnd;
if( g_bFullscreen )
SetRect( &rcWnd, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN) );
else // if( !g_bFullscreen )
{
SetRect( &rcWnd, 0, 0, g_dwScreenWidth, g_dwScreenHeight );
AdjustWindowRect( &rcWnd, g_dwWindowStyle, FALSE );
}
// Bring the window to the foreground
SetWindowPos( g_hWndMain,
HWND_NOTOPMOST,
0,
0,
RECTWIDTH(rcWnd),
RECTHEIGHT(rcWnd),
0 );
///////////////////////////
// Restore all game objects
///////////////////////////
SCREEN->Restore();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: InvalidateObjects()
// Desc:
//-----------------------------------------------------------------------------
HRESULT InvalidateObjects()
{
SCREEN->Invalidate();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: Update()
// Desc:
//-----------------------------------------------------------------------------
void Update()
{
FLOAT fDeltaTime = DXUtil_Timer( TIMER_GETELAPSEDTIME );
// This was a hack to fix timing issues with the old WindowSelectSong
//
//if( fDeltaTime > 0.050f ) // we dropped > 5 frames
// fDeltaTime = 0.050f;
MUSIC->Update( fDeltaTime );
WM->Update( fDeltaTime );
static RageRawInputList listRawInput;
listRawInput.RemoveAll();
INPUT->GetRawInput( listRawInput );
RageRawInput ri;
PadInput pi;
POSITION pos = listRawInput.GetHeadPosition();
while( pos != NULL )
{
ri = listRawInput.GetNext( pos );
pi = GAMEOPTIONS->RawToPad( ri );
WM->Input( ri, pi );
}
}
//-----------------------------------------------------------------------------
// Name: Render()
// Desc:
//-----------------------------------------------------------------------------
void Render()
{
HRESULT hr = SCREEN->BeginFrame();
switch( hr )
{
case D3DERR_DEVICELOST:
// The user probably alt-tabbed out of fullscreen.
// Do not render a frame until we re-acquire the device
break;
case D3DERR_DEVICENOTRESET:
InvalidateObjects();
// Resize the device
if( SUCCEEDED( SCREEN->Reset() ) )
{
// Initialize the app's device-dependent objects
RestoreObjects();
return;
}
else
RageError( "Failed to SCREEN->Reset()" );
break;
case S_OK:
// draw the game
WM->Draw();
SCREEN->EndFrame();
break;
}
}
//-----------------------------------------------------------------------------
// Name: ShowFrame()
// Desc:
//-----------------------------------------------------------------------------
void ShowFrame()
{
// display the contents of the back buffer to the front
if( SCREEN )
SCREEN->ShowFrame();
}
//-----------------------------------------------------------------------------
// Name: SetFullscreen()
// Desc:
//-----------------------------------------------------------------------------
void SetFullscreen( BOOL bFullscreen )
{
InvalidateObjects();
g_bFullscreen = bFullscreen;
SCREEN->SwitchDisplayModes( g_bFullscreen,
g_dwScreenWidth,
g_dwScreenHeight );
RestoreObjects();
}
+531
View File
@@ -0,0 +1,531 @@
# Microsoft Developer Studio Project File - Name="StepMania" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=StepMania - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "StepMania.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "StepMania.mak" CFG="StepMania - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "StepMania - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "StepMania - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "StepMania - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 1
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "../Release"
# PROP Intermediate_Dir "../Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "StepMania - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 1
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "../Debug"
# PROP Intermediate_Dir "../Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "StepMania - Win32 Release"
# Name "StepMania - Win32 Debug"
# Begin Group "Rage"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\RageBitmapTexture.cpp
# End Source File
# Begin Source File
SOURCE=.\RageBitmapTexture.h
# End Source File
# Begin Source File
SOURCE=.\RageInput.cpp
# End Source File
# Begin Source File
SOURCE=.\RageInput.h
# End Source File
# Begin Source File
SOURCE=.\RageMovieTexture.cpp
# End Source File
# Begin Source File
SOURCE=.\RageMovieTexture.h
# End Source File
# Begin Source File
SOURCE=.\RageMusic.cpp
# End Source File
# Begin Source File
SOURCE=.\RageMusic.h
# End Source File
# Begin Source File
SOURCE=.\RageScreen.cpp
# End Source File
# Begin Source File
SOURCE=.\RageScreen.h
# End Source File
# Begin Source File
SOURCE=.\RageSound.cpp
# End Source File
# Begin Source File
SOURCE=.\RageSound.h
# End Source File
# Begin Source File
SOURCE=.\RageTexture.cpp
# End Source File
# Begin Source File
SOURCE=.\RageTexture.h
# End Source File
# Begin Source File
SOURCE=.\RageTextureManager.cpp
# End Source File
# Begin Source File
SOURCE=.\RageTextureManager.h
# End Source File
# Begin Source File
SOURCE=.\RageUtil.cpp
# End Source File
# Begin Source File
SOURCE=.\RageUtil.h
# End Source File
# End Group
# Begin Group "Windows"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\Window.cpp
# End Source File
# Begin Source File
SOURCE=.\Window.h
# End Source File
# Begin Source File
SOURCE=.\WindowConfigurePads.cpp
# End Source File
# Begin Source File
SOURCE=.\WindowConfigurePads.h
# End Source File
# Begin Source File
SOURCE=.\WindowDancing.cpp
# End Source File
# Begin Source File
SOURCE=.\WindowDancing.h
# End Source File
# Begin Source File
SOURCE=.\WindowIntroCovers.cpp
# End Source File
# Begin Source File
SOURCE=.\WindowIntroCovers.h
# End Source File
# Begin Source File
SOURCE=.\WindowManager.cpp
# End Source File
# Begin Source File
SOURCE=.\WindowManager.h
# End Source File
# Begin Source File
SOURCE=.\WindowResults.cpp
# End Source File
# Begin Source File
SOURCE=.\WindowResults.h
# End Source File
# Begin Source File
SOURCE=.\WindowSandbox.cpp
# End Source File
# Begin Source File
SOURCE=.\WindowSandbox.h
# End Source File
# Begin Source File
SOURCE=.\WindowSelectGameMode.cpp
# End Source File
# Begin Source File
SOURCE=.\WindowSelectGameMode.h
# End Source File
# Begin Source File
SOURCE=.\WindowSelectSong.cpp
# End Source File
# Begin Source File
SOURCE=.\WindowSelectSong.h
# End Source File
# Begin Source File
SOURCE=.\WindowSelectSteps.cpp
# End Source File
# Begin Source File
SOURCE=.\WindowSelectSteps.h
# End Source File
# Begin Source File
SOURCE=.\WindowTitleMenu.cpp
# End Source File
# Begin Source File
SOURCE=.\WindowTitleMenu.h
# End Source File
# End Group
# Begin Group "Game Objects"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\Actor.cpp
# End Source File
# Begin Source File
SOURCE=.\Actor.h
# End Source File
# Begin Source File
SOURCE=.\Background.cpp
# End Source File
# Begin Source File
SOURCE=.\Background.h
# End Source File
# Begin Source File
SOURCE=.\Banner.cpp
# End Source File
# Begin Source File
SOURCE=.\Banner.h
# End Source File
# Begin Source File
SOURCE=.\BitmapText.cpp
# End Source File
# Begin Source File
SOURCE=.\BitmapText.h
# End Source File
# Begin Source File
SOURCE=.\BlurredTitle.cpp
# End Source File
# Begin Source File
SOURCE=.\BlurredTitle.h
# End Source File
# Begin Source File
SOURCE=.\Button.cpp
# End Source File
# Begin Source File
SOURCE=.\button.h
# End Source File
# Begin Source File
SOURCE=.\ColorArrows.cpp
# End Source File
# Begin Source File
SOURCE=.\ColorArrows.h
# End Source File
# Begin Source File
SOURCE=.\Combo.cpp
# End Source File
# Begin Source File
SOURCE=.\Combo.h
# End Source File
# Begin Source File
SOURCE=.\FootBar.cpp
# End Source File
# Begin Source File
SOURCE=.\FootBar.h
# End Source File
# Begin Source File
SOURCE=.\GameOptions.cpp
# End Source File
# Begin Source File
SOURCE=.\GameOptions.h
# End Source File
# Begin Source File
SOURCE=.\GrayArrows.cpp
# End Source File
# Begin Source File
SOURCE=.\GrayArrows.h
# End Source File
# Begin Source File
SOURCE=.\Judgement.cpp
# End Source File
# Begin Source File
SOURCE=.\Judgement.h
# End Source File
# Begin Source File
SOURCE=.\LifeMeter.cpp
# End Source File
# Begin Source File
SOURCE=.\LifeMeter.h
# End Source File
# Begin Source File
SOURCE=.\PadInput.h
# End Source File
# Begin Source File
SOURCE=.\Player.cpp
# End Source File
# Begin Source File
SOURCE=.\Player.h
# End Source File
# Begin Source File
SOURCE=.\PreviewGraphic.cpp
# End Source File
# Begin Source File
SOURCE=.\previewgraphic.h
# End Source File
# Begin Source File
SOURCE=.\Score.cpp
# End Source File
# Begin Source File
SOURCE=.\Score.h
# End Source File
# Begin Source File
SOURCE=.\Song.cpp
# End Source File
# Begin Source File
SOURCE=.\song.h
# End Source File
# Begin Source File
SOURCE=.\SoundSet.cpp
# End Source File
# Begin Source File
SOURCE=.\SoundSet.h
# End Source File
# Begin Source File
SOURCE=.\Sprite.cpp
# End Source File
# Begin Source File
SOURCE=.\Sprite.h
# End Source File
# Begin Source File
SOURCE=.\Steps.cpp
# End Source File
# Begin Source File
SOURCE=.\Steps.h
# End Source File
# End Group
# Begin Group "File Types"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\BmsFile.cpp
# End Source File
# Begin Source File
SOURCE=.\BmsFile.h
# End Source File
# Begin Source File
SOURCE=.\IniFile.cpp
# End Source File
# Begin Source File
SOURCE=.\IniFile.h
# End Source File
# End Group
# Begin Group "System"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\dxutil.cpp
# End Source File
# Begin Source File
SOURCE=.\resource.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# Begin Source File
SOURCE=.\StepMania.cpp
# End Source File
# Begin Source File
SOURCE=.\StepMania.ICO
# End Source File
# Begin Source File
SOURCE=.\StepMania.RC
# End Source File
# End Group
# Begin Group "Transitions"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\Transition.cpp
# End Source File
# Begin Source File
SOURCE=.\Transition.h
# End Source File
# Begin Source File
SOURCE=.\TransitionFade.cpp
# End Source File
# Begin Source File
SOURCE=.\TransitionFade.h
# End Source File
# Begin Source File
SOURCE=.\TransitionFadeWipe.cpp
# End Source File
# Begin Source File
SOURCE=.\TransitionFadeWipe.h
# End Source File
# Begin Source File
SOURCE=.\TransitionRectWipe.cpp
# End Source File
# Begin Source File
SOURCE=.\TransitionRectWipe.h
# End Source File
# Begin Source File
SOURCE=.\TransitionStarburst.cpp
# End Source File
# Begin Source File
SOURCE=.\TransitionStarburst.h
# End Source File
# Begin Source File
SOURCE=.\TransitionStarWipe.cpp
# End Source File
# Begin Source File
SOURCE=.\TransitionStarWipe.h
# End Source File
# End Group
# End Target
# End Project
+29
View File
@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "StepMania"=".\StepMania.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
+139
View File
@@ -0,0 +1,139 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: Transition.cpp
//
// Desc: Abstract base class for all transitions
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#include "RageUtil.h"
#include "Transition.h"
#define SOUND_BACK "Sounds\\back.mp3"
#define SOUND_NEXT "Sounds\\next.mp3"
Transition::Transition() :
m_TransitionState( closed ),
m_fTransitionTime( DEFAULT_TRANSITION_TIME ),
m_fPercentThroughTransition( 0.0f ),
m_Color(0,0,0,1)
{
m_bPlayCloseWipingRightSound = TRUE;
m_bPlayCloseWipingLeftSound = TRUE;
m_hCloseWipingRightSound = SOUND->LoadSound( SOUND_NEXT );
m_hCloseWipingLeftSound = SOUND->LoadSound( SOUND_BACK );
}
Transition::~Transition()
{
SOUND->UnloadSound( m_hCloseWipingRightSound );
SOUND->UnloadSound( m_hCloseWipingLeftSound );
}
void Transition::Update( const FLOAT &fDeltaTime )
{
switch( m_TransitionState )
{
case opening_right:
case opening_left:
case closing_right:
case closing_left:
m_fPercentThroughTransition += fDeltaTime/m_fTransitionTime;
if( m_fPercentThroughTransition > 1.0f ) // the wipe is over
{
m_fPercentThroughTransition = 0.0;
switch( m_TransitionState )
{
case opening_right:
case opening_left:
m_TransitionState = opened;
break;
case closing_right:
case closing_left:
m_TransitionState = closed;
break;
}
WM->SendMessageToTopWindow( m_MessageToSendWhenDone, 0 );
}
break;
}
}
void Transition::SetClosed()
{
m_TransitionState = closed;
}
void Transition::SetOpened()
{
m_TransitionState = opened;
}
void Transition::OpenWipingRight( WindowMessage send_when_done )
{
m_MessageToSendWhenDone = send_when_done;
m_TransitionState = opening_right;
m_fPercentThroughTransition = 0.0;
}
void Transition::OpenWipingLeft( WindowMessage send_when_done )
{
m_MessageToSendWhenDone = send_when_done;
m_TransitionState = opening_left;
m_fPercentThroughTransition = 0.0;
}
void Transition::CloseWipingRight( WindowMessage send_when_done )
{
m_MessageToSendWhenDone = send_when_done;
m_TransitionState = closing_right;
m_fPercentThroughTransition = 0.0;
if( m_bPlayCloseWipingRightSound )
SOUND->Play( m_hCloseWipingRightSound );
}
void Transition::CloseWipingLeft( WindowMessage send_when_done )
{
m_MessageToSendWhenDone = send_when_done;
m_TransitionState = closing_left;
m_fPercentThroughTransition = 0.0;
if( m_bPlayCloseWipingLeftSound )
SOUND->Play( m_hCloseWipingLeftSound );
}
void Transition::SetCloseWipingRightSound( CString sSoundPath )
{
if( sSoundPath == "" )
{
SOUND->UnloadSound( m_hCloseWipingRightSound );
m_bPlayCloseWipingRightSound = FALSE;
}
else
{
SOUND->UnloadSound( m_hCloseWipingRightSound );
m_hCloseWipingRightSound = SOUND->LoadSound( SOUND_NEXT );
m_bPlayCloseWipingRightSound = TRUE;
}
}
void Transition::SetCloseWipingLeftSound( CString sSoundPath )
{
if( sSoundPath == "" )
{
SOUND->UnloadSound( m_hCloseWipingRightSound );
m_bPlayCloseWipingLeftSound = FALSE;
}
else
{
SOUND->UnloadSound( m_hCloseWipingLeftSound );
m_hCloseWipingLeftSound = SOUND->LoadSound( SOUND_NEXT );
m_bPlayCloseWipingLeftSound = TRUE;
}
};
+71
View File
@@ -0,0 +1,71 @@
//-----------------------------------------------------------------------------
// File: Transition.cpp
//
// Desc: Abstract base class for all transitions
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _Transition_H_
#define _Transition_H_
#include "Actor.h"
#include "RageScreen.h"
#include "RageSound.h"
#include "Window.h"
#include "WindowManager.h"
#define DEFAULT_TRANSITION_TIME 1.0f
class Transition
{
public:
Transition();
~Transition();
void Update( const FLOAT &fDeltaTime );
virtual void Draw() PURE;
virtual void SetOpened();
virtual void SetClosed();
virtual void OpenWipingRight( WindowMessage send_when_done );
virtual void OpenWipingLeft( WindowMessage send_when_done );
virtual void CloseWipingRight(WindowMessage send_when_done );
virtual void CloseWipingLeft( WindowMessage send_when_done );
BOOL IsClosed() { return m_TransitionState == closed; };
BOOL IsClosing() { return m_TransitionState == closing_right || m_TransitionState == closing_left; };
VOID SetTransitionTime( FLOAT fNewTransitionTime ) { m_fTransitionTime = fNewTransitionTime; };
void SetColor( D3DXCOLOR new_color ) { m_Color = new_color; };
void SetCloseWipingRightSound( CString sSoundPath );
void SetCloseWipingLeftSound( CString sSoundPath );
protected:
enum TransitionState { opened, closed,
opening_right, opening_left,
closing_right, closing_left };
TransitionState m_TransitionState;
FLOAT m_fTransitionTime;
FLOAT m_fPercentThroughTransition;
WindowMessage m_MessageToSendWhenDone;
BOOL m_bPlayCloseWipingRightSound;
BOOL m_bPlayCloseWipingLeftSound;
HSAMPLE m_hCloseWipingRightSound;
HSAMPLE m_hCloseWipingLeftSound;
D3DXCOLOR m_Color;
};
#endif
+60
View File
@@ -0,0 +1,60 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: TransitionFade.cpp
//
// Desc: "Window blinds"-type transition.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#include "RageUtil.h"
#include "TransitionFade.h"
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define RECTANGLE_WIDTH 20
#define NUM_RECTANGLES (SCREEN_WIDTH/RECTANGLE_WIDTH)
#define FADE_RECTS_WIDE (NUM_RECTANGLES/3) // number of rects from fade start to fade end
TransitionFade::TransitionFade()
{
}
TransitionFade::~TransitionFade()
{
}
void TransitionFade::Draw()
{
FLOAT fPercentageOpaque;
switch( m_TransitionState )
{
case opened:
fPercentageOpaque = 0.0;
break;
case closed:
fPercentageOpaque = 1.0;
break;
case opening_right:
case opening_left:
fPercentageOpaque = 1.0f - m_fPercentThroughTransition;
break;
case closing_right:
case closing_left:
fPercentageOpaque = m_fPercentThroughTransition;
break;
}
m_Color.a = fPercentageOpaque;
int alpha = (int)( fPercentageOpaque * 255 );
SCREEN->DrawRect( CRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT), m_Color );
}
+32
View File
@@ -0,0 +1,32 @@
//-----------------------------------------------------------------------------
// File: TransitionFade.cpp
//
// Desc: "Window blinds"-type transition.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _TransitionFade_H_
#define _TransitionFade_H_
#include "Transition.h"
#include "RageScreen.h"
#include "RageSound.h"
class TransitionFade : public Transition
{
public:
TransitionFade();
~TransitionFade();
void Draw();
};
#endif
+88
View File
@@ -0,0 +1,88 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: TransitionFadeWipe.cpp
//
// Desc: "Window blinds"-type transition.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#include "RageUtil.h"
#include "TransitionFadeWipe.h"
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define RECTANGLE_WIDTH 20
#define NUM_RECTANGLES (SCREEN_WIDTH/RECTANGLE_WIDTH)
#define FADE_RECTS_WIDE (NUM_RECTANGLES/3) // number of rects from fade start to fade end
TransitionFadeWipe::TransitionFadeWipe()
{
}
TransitionFadeWipe::~TransitionFadeWipe()
{
}
void TransitionFadeWipe::Draw()
{
if( m_TransitionState == opened )
return;
/////////////////////////
// draw rectangles that get progressively smaller at the edge of the wipe
/////////////////////////
BOOL bLeftEdgeIsDarker = m_TransitionState == opening_left || m_TransitionState == closing_right;
BOOL bFadeIsMovingLeft = m_TransitionState == opening_left || m_TransitionState == closing_left;
double fPercentComplete = m_fPercentThroughTransition;
double fPercentAlongScreen = bFadeIsMovingLeft ? 1-fPercentComplete : fPercentComplete;
int iFadeLeftEdge = (int)
(-FADE_RECTS_WIDE + (NUM_RECTANGLES + FADE_RECTS_WIDE) * fPercentAlongScreen);
int iFadeRightEdge = (int)
(0 + (NUM_RECTANGLES + FADE_RECTS_WIDE) * fPercentAlongScreen);
// draw all rectangles
for( int i=0; i<NUM_RECTANGLES; i++ )
{
int iRectX = (int)(RECTANGLE_WIDTH * (i+0.5));
int iRectWidth;
if( i < iFadeLeftEdge )
iRectWidth = bLeftEdgeIsDarker ? RECTANGLE_WIDTH : 0;
//iRectWidth = 0;
else if( i > iFadeRightEdge )
iRectWidth = bLeftEdgeIsDarker ? 0 : RECTANGLE_WIDTH;
//iRectWidth = 0;
else // this is a fading rectangle
{
int iRectsFromLeftFadeEdge = i - iFadeLeftEdge;
double fPercentAlongFade = iRectsFromLeftFadeEdge / (double)FADE_RECTS_WIDE;
double fPercentDarkness = bLeftEdgeIsDarker ? 1-fPercentAlongFade : fPercentAlongFade;
iRectWidth = (int)(RECTANGLE_WIDTH * fPercentDarkness);
}
//iRectWidth = RECTANGLE_WIDTH;
if( iRectWidth > 0 )
//if( i == iFadeLeftEdge || i == iFadeRightEdge )
{ // draw the rectangle
int iRectAlpha = (int)( iRectWidth * 255.0f / RECTANGLE_WIDTH );
RECT rect;
SetRect( &rect, iRectX-RECTANGLE_WIDTH/2, 0,
iRectX+RECTANGLE_WIDTH/2, SCREEN_HEIGHT );
SCREEN->DrawRect( &rect, D3DCOLOR_ARGB(iRectAlpha,0,0,0) );
}
} // end foreach rect
}
+31
View File
@@ -0,0 +1,31 @@
//-----------------------------------------------------------------------------
// File: TransitionFadeWipe.cpp
//
// Desc: "Window blinds"-type transition.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _TransitionFadeWipe_H_
#define _TransitionFadeWipe_H_
#include "Transition.h"
#include "RageScreen.h"
#include "RageSound.h"
class TransitionFadeWipe : public Transition
{
public:
TransitionFadeWipe();
~TransitionFadeWipe();
void Draw();
};
#endif
+87
View File
@@ -0,0 +1,87 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: TransitionRectWipe.cpp
//
// Desc: "Window blinds"-type transition.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#include "RageUtil.h"
#include "TransitionRectWipe.h"
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define RECTANGLE_WIDTH 20
#define NUM_RECTANGLES (SCREEN_WIDTH/RECTANGLE_WIDTH)
#define FADE_RECTS_WIDE (NUM_RECTANGLES/4) // number of rects from fade start to fade end
TransitionRectWipe::TransitionRectWipe()
{
}
TransitionRectWipe::~TransitionRectWipe()
{
}
void TransitionRectWipe::Draw()
{
if( m_TransitionState == opened )
return;
/////////////////////////
// draw rectangles that get progressively smaller at the edge of the wipe
/////////////////////////
BOOL bLeftEdgeIsDarker = m_TransitionState == opening_left || m_TransitionState == closing_right;
BOOL bFadeIsMovingLeft = m_TransitionState == opening_left || m_TransitionState == closing_left;
double fPercentComplete = m_fPercentThroughTransition;
double fPercentAlongScreen = bFadeIsMovingLeft ? 1-fPercentComplete : fPercentComplete;
int iFadeLeftEdge = (int)
(-FADE_RECTS_WIDE + (NUM_RECTANGLES + FADE_RECTS_WIDE) * fPercentAlongScreen);
int iFadeRightEdge = (int)
(0 + (NUM_RECTANGLES + FADE_RECTS_WIDE) * fPercentAlongScreen);
// draw all rectangles
for( int i=0; i<NUM_RECTANGLES; i++ )
{
int iRectX = (int)(RECTANGLE_WIDTH * (i+0.5));
int iRectWidth;
if( i < iFadeLeftEdge )
iRectWidth = bLeftEdgeIsDarker ? RECTANGLE_WIDTH : 0;
//iRectWidth = 0;
else if( i > iFadeRightEdge )
iRectWidth = bLeftEdgeIsDarker ? 0 : RECTANGLE_WIDTH;
//iRectWidth = 0;
else // this is a fading rectangle
{
int iRectsFromLeftFadeEdge = i - iFadeLeftEdge;
double fPercentAlongFade = iRectsFromLeftFadeEdge / (double)FADE_RECTS_WIDE;
double fPercentDarkness = bLeftEdgeIsDarker ? 1-fPercentAlongFade : fPercentAlongFade;
iRectWidth = (int)(RECTANGLE_WIDTH * fPercentDarkness);
}
//iRectWidth = RECTANGLE_WIDTH;
if( iRectWidth > 0 )
//if( i == iFadeLeftEdge || i == iFadeRightEdge )
{ // draw the rectangle
RECT rect;
SetRect( &rect, iRectX-iRectWidth/2, 0,
iRectX+iRectWidth/2, SCREEN_HEIGHT );
SCREEN->DrawRect( &rect, D3DCOLOR_ARGB(255,0,0,0) );
}
} // end foreach rect
}
+31
View File
@@ -0,0 +1,31 @@
//-----------------------------------------------------------------------------
// File: TransitionRectWipe.cpp
//
// Desc: "Window blinds"-type transition.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _TransitionRectWipe_H_
#define _TransitionRectWipe_H_
#include "Transition.h"
#include "RageScreen.h"
#include "RageSound.h"
class TransitionRectWipe : public Transition
{
public:
TransitionRectWipe();
~TransitionRectWipe();
void Draw();
};
#endif
+127
View File
@@ -0,0 +1,127 @@
#include "stdafx.h"
//-----------------------------------------------------------------------------
// File: TransitionStarWipe.cpp
//
// Desc: "Window blinds"-type transition.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#include "RageUtil.h"
#include "TransitionStarWipe.h"
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define TEXTURE_STAR_BLUE "Textures\\Star Blue.png"
#define TEXTURE_STAR_YELLOW "Textures\\Star Yellow.png"
TransitionStarWipe::TransitionStarWipe()
{
m_fTransitionTime = m_fTransitionTime * 1.5f;
}
TransitionStarWipe::~TransitionStarWipe()
{
}
void TransitionStarWipe::Draw()
{
if( m_TransitionState == opened )
return;
else if( m_TransitionState == closed ) {
SCREEN->DrawRect( CRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT), D3DCOLOR_RGBA(0,0,0,255) );
return;
}
FLOAT fPercentOpen;
switch( m_TransitionState )
{
case opening_right:
case opening_left:
fPercentOpen = (1.0f - m_fPercentThroughTransition);
break;
case closing_right:
case closing_left:
fPercentOpen = m_fPercentThroughTransition;
break;
}
int iNumStars = SCREEN_HEIGHT/m_iStarHeight + 1;
for( int row=0; row<iNumStars; row++ ) // foreach row of stars
{
BOOL bIsAnEvenRow = row % 2;
int y = m_iStarHeight*row + m_iStarHeight/2;
int x_tilt;
switch( m_TransitionState )
{
case opening_right:
case opening_left:
x_tilt = y - SCREEN_HEIGHT/2;
break;
case closing_right:
case closing_left:
x_tilt = abs( y - SCREEN_HEIGHT/2 );
if( bIsAnEvenRow ) x_tilt *= -1;
break;
}
int x_offset = (int)(fPercentOpen*(SCREEN_WIDTH+SCREEN_HEIGHT+m_iStarWidth));
int x = bIsAnEvenRow ?
-SCREEN_HEIGHT/2 + x_offset + x_tilt :
SCREEN_WIDTH+SCREEN_HEIGHT/2 - x_offset + x_tilt;
m_sprStar.SetRotation( bIsAnEvenRow ? D3DX_PI : 0.0f ); // flip the sprite
m_sprStar.SetXY( bIsAnEvenRow?x-1:x, bIsAnEvenRow?y-1:y ); // fudge. The rotation makes it off center
m_sprStar.Draw();
int x_rect_leading_edge = x + ( bIsAnEvenRow ? - m_iStarWidth/2 : m_iStarWidth/2 );
int x_rect_trailing_edge = ( bIsAnEvenRow ? 0 : SCREEN_WIDTH );
int y_top = y - m_iStarHeight/2;
int y_bot = y + m_iStarHeight/2;
SCREEN->DrawRect( CRect(x_rect_leading_edge, y_top,
x_rect_trailing_edge, y_bot ),
D3DCOLOR_ARGB(255,0,0,0)
);
}
}
void TransitionStarWipe::OpenWipingRight( WindowMessage send_when_done )
{
Transition::OpenWipingRight( send_when_done );
LoadNewStarSprite( TEXTURE_STAR_BLUE );
}
void TransitionStarWipe::OpenWipingLeft( WindowMessage send_when_done )
{
Transition::OpenWipingLeft( send_when_done );
LoadNewStarSprite( TEXTURE_STAR_BLUE );
}
void TransitionStarWipe::CloseWipingRight(WindowMessage send_when_done )
{
Transition::CloseWipingRight( send_when_done );
LoadNewStarSprite( TEXTURE_STAR_YELLOW );
}
void TransitionStarWipe::CloseWipingLeft( WindowMessage send_when_done )
{
Transition::CloseWipingLeft( send_when_done );
LoadNewStarSprite( TEXTURE_STAR_YELLOW );
}
void TransitionStarWipe::LoadNewStarSprite( CString sFileName )
{
m_sprStar.LoadFromTexture( sFileName );
m_iStarWidth = m_sprStar.GetZoomedWidth();
m_iStarHeight = m_sprStar.GetZoomedHeight();
}
+43
View File
@@ -0,0 +1,43 @@
//-----------------------------------------------------------------------------
// File: TransitionStarWipe.cpp
//
// Desc: "Window blinds"-type transition.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _TransitionStarWipe_H_
#define _TransitionStarWipe_H_
#include "Transition.h"
#include "RageScreen.h"
#include "RageSound.h"
class TransitionStarWipe : public Transition
{
public:
TransitionStarWipe();
~TransitionStarWipe();
void Draw();
void OpenWipingRight( WindowMessage send_when_done );
void OpenWipingLeft( WindowMessage send_when_done );
void CloseWipingRight(WindowMessage send_when_done );
void CloseWipingLeft( WindowMessage send_when_done );
protected:
void LoadNewStarSprite( CString sFileName );
Sprite m_sprStar;
int m_iStarWidth;
int m_iStarHeight;
};
#endif
+22
View File
@@ -0,0 +1,22 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by StepMania.RC
//
#define IDR_MAIN_ACCEL 1001
#define IDM_TOGGLEFULLSCREEN 1002
#define IDI_ICON 1003
#define IDC_CURSOR 1004
#define IDM_EXIT 40003
#define IDM_WINDOWED 40008
#define IDM_PADS 40011
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 108
#define _APS_NEXT_COMMAND_VALUE 40009
#define _APS_NEXT_CONTROL_VALUE 1006
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
+113
View File
@@ -0,0 +1,113 @@
//-----------------------------------------------------------------------------
// File: Song.h
//
// Desc: Holds metadata for a song and the song's step data.
//
// Copyright (c) 2001 Chris Danford. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef _SONG_H_
#define _SONG_H_
#include <afxtempl.h>
#include "Steps.h"
#define BEATS_IN_MEASURE 4
class Song
{
public:
Song() :
m_fBPM(0.0),
m_fBeatOffset(0.0)
{
};
Song( Song &from )
{
Copy( from );
};
Song& operator=( const Song &from )
{
if (this != &from)
{
Copy( from );
}
return *this;
};
void Copy( const Song &from )
{
m_sSongFile = from.m_sSongFile;
m_sSongDir = from.m_sSongDir;
m_sTitle = from.m_sTitle;
m_sArtist = from.m_sArtist;
m_sCreator = from.m_sCreator;
m_fBPM = from.m_fBPM;
m_fBeatOffset = from.m_fBeatOffset;
m_sMusic = from.m_sMusic;
m_sSample = from.m_sSample;
m_sBanner = from.m_sBanner;
m_sBackground = from.m_sBackground;
arraySteps.Copy( from.arraySteps );
};
bool LoadFromSongDir( CString sDir );
bool IsUsingBitmapBG()
{
CString sBGFile = m_sBackground;
sBGFile.MakeLower();
return sBGFile.Right(3) == "bmp";
};
private:
BOOL LoadFromBMSFile( CString sPath );
BOOL LoadFromMSDFile( CString sPath );
void FillEmptyValuesWithDefaults();
public:
CString GetSongFilePath() {return m_sSongDir + m_sSongFile; };
CString GetSongFileDir() {return m_sSongDir; };
CString GetMusicPath() {return m_sSongDir + m_sMusic; };
CString GetSamplePath() {return m_sSongDir + m_sSample; };
CString GetBannerPath() {return m_sSongDir + m_sBanner; };
CString GetBackgroundPath() {return m_sSongDir + m_sBackground; };
// Steps& GetStepsAt( int iIndex ) {return arraySteps[iIndex]; };
CString GetTitle() {return m_sTitle; };
CString GetArtist() {return m_sArtist; };
CString GetCreator() {return m_sCreator; };
FLOAT GetBeatOffset() {return m_fBeatOffset; };
FLOAT GetBPM() {return m_fBPM; };
FLOAT GetBeatsPerSecond() {return m_fBPM / 60.0f; };
public:
private:
CString m_sSongFile;
CString m_sSongDir;
CString m_sTitle;
CString m_sArtist;
CString m_sCreator;
FLOAT m_fBPM;
FLOAT m_fBeatOffset;
CString m_sMusic;
CString m_sSample;
CString m_sBanner;
CString m_sBackground;
public:
CArray<Steps, Steps&> arraySteps;
};
#endif