263 lines
8.8 KiB
C++
263 lines
8.8 KiB
C++
#include "global.h"
|
|
#include "stdlib.h"
|
|
/*
|
|
-----------------------------------------------------------------------------
|
|
Class: ScreenHowToPlay
|
|
|
|
Desc: See header.
|
|
|
|
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
|
|
Chris Danford
|
|
-----------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include "ScreenHowToPlay.h"
|
|
#include "ThemeManager.h"
|
|
#include "GameState.h"
|
|
#include "GameDef.h"
|
|
#include "RageLog.h"
|
|
#include "RageDisplay.h"
|
|
#include "SongManager.h"
|
|
#include "NoteFieldPositioning.h"
|
|
#include "GameManager.h"
|
|
|
|
#define SONG_BPM THEME->GetMetricF("ScreenHowToPlay","SongBPM")
|
|
#define SECONDS_TO_SHOW THEME->GetMetricF("ScreenHowToPlay","SecondsToShow")
|
|
#define NUM_PERFECTS THEME->GetMetricI("ScreenHowToPlay","NumPerfects")
|
|
#define NUM_MISSES THEME->GetMetricI("ScreenHowToPlay","NumMisses")
|
|
#define LIFEBARONCOMMAND THEME->GetMetric ("ScreenHowToPlay","LifeMeterBarOnCommand")
|
|
#define USECHARACTER THEME->GetMetricB("ScreenHowToPlay","UseCharacter")
|
|
#define CHARACTERONCOMMAND THEME->GetMetric ("ScreenHowToPlay","CharacterOnCommand")
|
|
#define USEPAD THEME->GetMetricB("ScreenHowToPlay","UsePad")
|
|
#define PADONCOMMAND THEME->GetMetric ("ScreenHowToPlay","PadOnCommand")
|
|
#define PLAYERX THEME->GetMetricF("ScreenHowToPlay","PlayerX")
|
|
|
|
ScreenHowToPlay::ScreenHowToPlay() : ScreenAttract("ScreenHowToPlay")
|
|
{
|
|
m_In.Load( THEME->GetPathToB("ScreenHowToPlay in") );
|
|
m_In.StartTransitioning();
|
|
|
|
m_Out.Load( THEME->GetPathToB("ScreenHowToPlay out") );
|
|
|
|
m_Overlay.LoadFromAniDir( THEME->GetPathToB("ScreenHowToPlay overlay") );
|
|
this->AddChild( &m_Overlay );
|
|
|
|
switch(GAMESTATE->m_CurGame) // which style should we use to demonstrate?
|
|
{
|
|
case GAME_DANCE: GAMESTATE->m_CurStyle = STYLE_DANCE_SINGLE; break;
|
|
case GAME_PUMP: GAMESTATE->m_CurStyle = STYLE_PUMP_SINGLE; break;
|
|
case GAME_EZ2: GAMESTATE->m_CurStyle = STYLE_EZ2_SINGLE; break;
|
|
case GAME_PARA: GAMESTATE->m_CurStyle = STYLE_PARA_SINGLE; break;
|
|
case GAME_DS3DDX: GAMESTATE->m_CurStyle = STYLE_DS3DDX_SINGLE; break;
|
|
case GAME_BM: GAMESTATE->m_CurStyle = STYLE_BM_SINGLE; break;
|
|
default: ASSERT(0); // we should cover all gametypes....
|
|
}
|
|
|
|
StepsType nt = GAMESTATE->GetCurrentStyleDef()->m_StepsType;
|
|
int iNumOfTracks = GAMEMAN->NotesTypeToNumTracks( nt );
|
|
|
|
ASSERT(iNumOfTracks > 0); // crazy to have less than 1 track....
|
|
|
|
m_LifeMeterBar.Load( PLAYER_1 );
|
|
m_LifeMeterBar.Command( LIFEBARONCOMMAND );
|
|
m_LifeMeterBar.FillForHowToPlay( NUM_PERFECTS, NUM_MISSES );
|
|
|
|
if( USEPAD )
|
|
{
|
|
m_mDancePad.LoadMilkshapeAscii("Characters" SLASH "DancePad-DDR.txt");
|
|
m_mDancePad.SetRotationX( 35 );
|
|
m_mDancePad.Command( PADONCOMMAND );
|
|
}
|
|
|
|
// Display random character+pad
|
|
if( USECHARACTER && GAMESTATE->m_pCharacters.size() )
|
|
{
|
|
Character* rndchar = GAMESTATE->GetRandomCharacter();
|
|
|
|
m_mCharacter.LoadMilkshapeAscii( rndchar->GetModelPath() );
|
|
m_mCharacter.LoadMilkshapeAsciiBones("howtoplay", rndchar->GetHowToPlayAnimationPath() );
|
|
|
|
m_mCharacter.SetRotationX( 40 );
|
|
m_mCharacter.Command( CHARACTERONCOMMAND );
|
|
}
|
|
|
|
NoteData* pND = new NoteData;
|
|
pND->SetNumTracks( iNumOfTracks );
|
|
/* Old notes.. Until our HowToPlay animation changes, Steps changed.
|
|
pND->SetTapNote( 0, ROWS_PER_BEAT*12, TAP_TAP );
|
|
pND->SetTapNote( 1, ROWS_PER_BEAT*16, TAP_TAP );
|
|
pND->SetTapNote( 2, ROWS_PER_BEAT*20, TAP_TAP );
|
|
pND->SetTapNote( 0, ROWS_PER_BEAT*24, TAP_TAP );
|
|
pND->SetTapNote( 3, ROWS_PER_BEAT*24, TAP_TAP );
|
|
pND->SetTapNote( 0, ROWS_PER_BEAT*28, TAP_TAP );
|
|
pND->AddHoldNote( HoldNote(2, 32, 35) );
|
|
pND->AddHoldNote( HoldNote(0, 36, 39) );
|
|
pND->AddHoldNote( HoldNote(3, 36, 39) );
|
|
pND->AddHoldNote( HoldNote(2, 40, 43) );
|
|
pND->SetTapNote( 0, ROWS_PER_BEAT*44, TAP_TAP );
|
|
pND->SetTapNote( 1, (int)(ROWS_PER_BEAT*44.5f), TAP_TAP );
|
|
pND->SetTapNote( 2, ROWS_PER_BEAT*45, TAP_TAP );
|
|
pND->SetTapNote( 3, (int)(ROWS_PER_BEAT*45.5f), TAP_TAP );
|
|
pND->SetTapNote( 0, ROWS_PER_BEAT*46, TAP_TAP );
|
|
pND->SetTapNote( 2, ROWS_PER_BEAT*46, TAP_TAP );
|
|
*/
|
|
|
|
pND->SetTapNote( 1, ROWS_PER_BEAT*16, TAP_TAP );
|
|
pND->SetTapNote( 2, ROWS_PER_BEAT*18, TAP_TAP );
|
|
pND->SetTapNote( 0, ROWS_PER_BEAT*20, TAP_TAP );
|
|
pND->SetTapNote( 0, ROWS_PER_BEAT*22, TAP_TAP );
|
|
pND->SetTapNote( 3, ROWS_PER_BEAT*22, TAP_TAP );
|
|
//Misses
|
|
pND->SetTapNote( 0, (int)(ROWS_PER_BEAT*24.0f), TAP_TAP );
|
|
pND->SetTapNote( 1, (int)(ROWS_PER_BEAT*24.1f), TAP_TAP );
|
|
pND->SetTapNote( 3, (int)(ROWS_PER_BEAT*24.2f), TAP_TAP );
|
|
pND->SetTapNote( 1, (int)(ROWS_PER_BEAT*24.3f), TAP_TAP );
|
|
pND->SetTapNote( 2, (int)(ROWS_PER_BEAT*24.4f), TAP_TAP );
|
|
pND->SetTapNote( 0, (int)(ROWS_PER_BEAT*24.5f), TAP_TAP );
|
|
|
|
m_pSong = new Song;
|
|
float fSongBPM = SONG_BPM; // need this on a separate line, otherwise VC6 release build screws up and returns 0
|
|
m_pSong->AddBPMSegment( BPMSegment(0.0,fSongBPM) );
|
|
/* Same as above
|
|
m_pSong->AddStopSegment( StopSegment(12,2) );
|
|
m_pSong->AddStopSegment( StopSegment(16,2) );
|
|
m_pSong->AddStopSegment( StopSegment(20,2) );
|
|
m_pSong->AddStopSegment( StopSegment(24,2) );
|
|
m_pSong->AddStopSegment( StopSegment(28,2) );
|
|
*/
|
|
m_pSong->AddStopSegment( StopSegment(16,2) );
|
|
m_pSong->AddStopSegment( StopSegment(18,2) );
|
|
m_pSong->AddStopSegment( StopSegment(20,2) );
|
|
m_pSong->AddStopSegment( StopSegment(22,2) );
|
|
|
|
GAMESTATE->m_pCurSong = m_pSong;
|
|
GAMESTATE->m_bPastHereWeGo = true;
|
|
GAMESTATE->m_PlayerController[PLAYER_1] = PC_AUTOPLAY;
|
|
|
|
m_Player.Load( PLAYER_1, pND, &m_LifeMeterBar, NULL, NULL, NULL, NULL, NULL );
|
|
m_Player.SetX( PLAYERX );
|
|
|
|
// Don't show judgement
|
|
GAMESTATE->m_PlayerOptions[PLAYER_1].m_fBlind = 1;
|
|
GAMESTATE->m_MasterPlayerNumber = PLAYER_1;
|
|
GAMESTATE->m_bDemonstrationOrJukebox = true;
|
|
this->AddChild( &m_Player );
|
|
this->AddChild( &m_LifeMeterBar );
|
|
delete pND;
|
|
|
|
m_fFakeSecondsIntoSong = 0;
|
|
this->ClearMessageQueue();
|
|
this->PostScreenMessage( SM_BeginFadingOut, SECONDS_TO_SHOW );
|
|
|
|
this->MoveToTail( &m_Overlay );
|
|
this->MoveToTail( &m_In );
|
|
this->MoveToTail( &m_Out );
|
|
}
|
|
|
|
ScreenHowToPlay::~ScreenHowToPlay()
|
|
{
|
|
delete m_pSong;
|
|
}
|
|
|
|
void ScreenHowToPlay::Update( float fDelta )
|
|
{
|
|
float rate = 1;
|
|
if(GAMESTATE->m_pCurSong != NULL)
|
|
{
|
|
GAMESTATE->UpdateSongPosition( m_fFakeSecondsIntoSong );
|
|
m_fFakeSecondsIntoSong += fDelta;
|
|
|
|
if( GAMESTATE->m_bFreeze )
|
|
{
|
|
switch(int(GAMESTATE->m_fSongBeat))
|
|
{
|
|
case 16: m_mCharacter.SetFrame(30); break;
|
|
case 18: m_mCharacter.SetFrame(85); break;
|
|
case 20: m_mCharacter.SetFrame(150); break;
|
|
case 22: m_mCharacter.SetFrame(270); break;
|
|
};
|
|
rate = 0;
|
|
}
|
|
else
|
|
{
|
|
/* HowToPlay animations.. This will be retimed soon to be a reasonable speed.
|
|
This was just a quick'n'dirty way of showing this screen correctly. */
|
|
// Until we get a better HowToPlay animation done, it has to be this way..
|
|
if( (GAMESTATE->m_fSongBeat >= 15.0f && GAMESTATE->m_fSongBeat <= 15.2f) )
|
|
{
|
|
m_mCharacter.SetFrame(1);
|
|
}
|
|
if( (GAMESTATE->m_fSongBeat >= 17.0f && GAMESTATE->m_fSongBeat <= 17.2f) )
|
|
{
|
|
m_mCharacter.SetFrame(55);
|
|
}
|
|
if( (GAMESTATE->m_fSongBeat >= 19.0f && GAMESTATE->m_fSongBeat <= 19.2f) )
|
|
{
|
|
m_mCharacter.SetFrame(120);
|
|
}
|
|
if( (GAMESTATE->m_fSongBeat >= 21.0f && GAMESTATE->m_fSongBeat <= 21.2f) )
|
|
{
|
|
m_mCharacter.SetFrame(240);
|
|
}
|
|
// ----------------------------------------------------------------------- */
|
|
|
|
// we want misses from here on out, so change to a HUMAN controller.
|
|
// since we aren't taking input from the user, the steps are always missed.
|
|
if(GAMESTATE->m_fSongBeat > 22.8f)
|
|
GAMESTATE->m_PlayerController[PLAYER_1] = PC_HUMAN;
|
|
|
|
if( (GAMESTATE->m_fSongBeat >= 0.0f && GAMESTATE->m_fSongBeat <= 15.0f) ||
|
|
(GAMESTATE->m_fSongBeat >= 16.8f && GAMESTATE->m_fSongBeat <= 17.0f) ||
|
|
(GAMESTATE->m_fSongBeat >= 18.8f && GAMESTATE->m_fSongBeat <= 19.0f) ||
|
|
(GAMESTATE->m_fSongBeat >= 20.8f && GAMESTATE->m_fSongBeat <= 21.0f) ||
|
|
(GAMESTATE->m_fSongBeat >= 22.8f) )
|
|
{
|
|
if( (m_mCharacter.GetCurFrame() >=243) || (m_mCharacter.GetCurFrame() <=184) )
|
|
m_mCharacter.SetFrame(184);
|
|
//Loop for HowToPlay static movement is 184~243
|
|
} else
|
|
// if we update at normal speed during a step animation, it is too slow and
|
|
// doesn't finish in time.
|
|
rate = 1.8f;
|
|
}
|
|
}
|
|
|
|
m_mCharacter.Update( fDelta * rate );
|
|
m_mDancePad.Update( fDelta );
|
|
ScreenAttract::Update( fDelta );
|
|
}
|
|
|
|
void ScreenHowToPlay::HandleScreenMessage( const ScreenMessage SM )
|
|
{
|
|
switch( SM )
|
|
{
|
|
case SM_GoToNextScreen:
|
|
GAMESTATE->Reset();
|
|
break;
|
|
}
|
|
ScreenAttract::HandleScreenMessage( SM );
|
|
}
|
|
|
|
void ScreenHowToPlay::DrawPrimitives()
|
|
{
|
|
Screen::DrawPrimitives();
|
|
|
|
DISPLAY->SetLighting( true );
|
|
DISPLAY->SetLightDirectional(
|
|
0,
|
|
RageColor(0.5,0.5,0.5,1),
|
|
RageColor(1,1,1,1),
|
|
RageColor(0,0,0,1),
|
|
RageVector3(0, 0, 1) );
|
|
|
|
m_mCharacter.Draw();
|
|
m_mDancePad.Draw();
|
|
|
|
DISPLAY->SetLightOff( 0 );
|
|
DISPLAY->SetLighting( false );
|
|
|
|
m_Overlay.DrawPrimitives();
|
|
m_In.DrawPrimitives();
|
|
m_Out.DrawPrimitives();
|
|
}
|