From 854923638577d9dbd85066ce342f4bd6977e8c46 Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Mon, 20 May 2002 08:59:37 +0000 Subject: [PATCH] no message --- stepmania/src/AnnouncerManager.cpp | 153 +++++ stepmania/src/AnnouncerManager.h | 111 ++++ stepmania/src/BitmapText.cpp | 2 +- stepmania/src/Font.cpp | 50 +- stepmania/src/Font.h | 8 +- stepmania/src/GameConstantsAndTypes.h | 17 +- stepmania/src/GameDef.cpp | 16 +- stepmania/src/IniFile.cpp | 59 +- stepmania/src/IniFile.h | 14 +- stepmania/src/InputQueue.cpp | 20 + stepmania/src/InputQueue.h | 72 ++ stepmania/src/LifeMeter.h | 33 + stepmania/src/Notes.cpp | 813 +++++++++++++++++++++++ stepmania/src/Notes.h | 63 ++ stepmania/src/PrefsManager.cpp | 113 +--- stepmania/src/Quad.h | 23 + stepmania/src/RageDisplay.cpp | 430 ++++++++++++ stepmania/src/RageDisplay.h | 195 ++++++ stepmania/src/RageTextureManager.cpp | 12 +- stepmania/src/RageTextureManager.h | 14 +- stepmania/src/Screen.cpp | 75 +++ stepmania/src/Screen.h | 61 ++ stepmania/src/ScreenCaution.cpp | 68 ++ stepmania/src/ScreenCaution.h | 32 + stepmania/src/ScreenEdit.cpp | 663 ++++++++++++++++++ stepmania/src/ScreenEdit.h | 88 +++ stepmania/src/ScreenEditMenu.cpp | 337 ++++++++++ stepmania/src/ScreenEditMenu.h | 89 +++ stepmania/src/ScreenGameplay.cpp | 528 +++++++++++++++ stepmania/src/ScreenGameplay.h | 93 +++ stepmania/src/ScreenGraphicOptions.cpp | 161 +++++ stepmania/src/ScreenGraphicOptions.h | 31 + stepmania/src/ScreenManager.cpp | 164 +++++ stepmania/src/ScreenManager.h | 53 ++ stepmania/src/ScreenMessage.h | 27 + stepmania/src/ScreenMusicScroll.cpp | 225 +++++++ stepmania/src/ScreenMusicScroll.h | 51 ++ stepmania/src/ScreenOptions.cpp | 407 ++++++++++++ stepmania/src/ScreenOptions.h | 90 +++ stepmania/src/ScreenPlayerOptions.cpp | 193 ++++++ stepmania/src/ScreenPlayerOptions.h | 39 ++ stepmania/src/ScreenPrompt.cpp | 181 +++++ stepmania/src/ScreenPrompt.h | 50 ++ stepmania/src/ScreenSandbox.cpp | 81 +++ stepmania/src/ScreenSandbox.h | 39 ++ stepmania/src/ScreenSelectDifficulty.cpp | 398 +++++++++++ stepmania/src/ScreenSelectDifficulty.h | 59 ++ stepmania/src/ScreenSelectGame.cpp | 98 +++ stepmania/src/ScreenSelectGame.h | 31 + stepmania/src/ScreenSelectGroup.cpp | 386 +++++++++++ stepmania/src/ScreenSelectGroup.h | 70 ++ stepmania/src/ScreenSelectMusic.cpp | 491 ++++++++++++++ stepmania/src/ScreenSelectMusic.h | 74 +++ stepmania/src/ScreenSelectStyle.cpp | 507 ++++++++++++++ stepmania/src/ScreenSelectStyle.h | 67 ++ stepmania/src/ScreenSongOptions.cpp | 136 ++++ stepmania/src/ScreenSongOptions.h | 42 ++ stepmania/src/ScreenStage.cpp | 129 ++++ stepmania/src/ScreenStage.h | 38 ++ stepmania/src/ScreenTitleMenu.cpp | 336 ++++++++++ stepmania/src/ScreenTitleMenu.h | 72 ++ stepmania/src/Sprite.cpp | 19 +- stepmania/src/StepMania.cpp | 12 +- stepmania/src/StepMania.vcproj | 6 - stepmania/src/StyleDef.cpp | 21 +- stepmania/src/ThemeManager.cpp | 11 - stepmania/src/ThemeManager.h | 11 - stepmania/src/TransitionBackWipe.cpp | 81 +++ stepmania/src/TransitionBackWipe.h | 39 ++ 69 files changed, 8967 insertions(+), 211 deletions(-) create mode 100644 stepmania/src/AnnouncerManager.cpp create mode 100644 stepmania/src/AnnouncerManager.h create mode 100644 stepmania/src/InputQueue.cpp create mode 100644 stepmania/src/InputQueue.h create mode 100644 stepmania/src/LifeMeter.h create mode 100644 stepmania/src/Notes.cpp create mode 100644 stepmania/src/Notes.h create mode 100644 stepmania/src/Quad.h create mode 100644 stepmania/src/RageDisplay.cpp create mode 100644 stepmania/src/RageDisplay.h create mode 100644 stepmania/src/Screen.cpp create mode 100644 stepmania/src/Screen.h create mode 100644 stepmania/src/ScreenCaution.cpp create mode 100644 stepmania/src/ScreenCaution.h create mode 100644 stepmania/src/ScreenEdit.cpp create mode 100644 stepmania/src/ScreenEdit.h create mode 100644 stepmania/src/ScreenEditMenu.cpp create mode 100644 stepmania/src/ScreenEditMenu.h create mode 100644 stepmania/src/ScreenGameplay.cpp create mode 100644 stepmania/src/ScreenGameplay.h create mode 100644 stepmania/src/ScreenGraphicOptions.cpp create mode 100644 stepmania/src/ScreenGraphicOptions.h create mode 100644 stepmania/src/ScreenManager.cpp create mode 100644 stepmania/src/ScreenManager.h create mode 100644 stepmania/src/ScreenMessage.h create mode 100644 stepmania/src/ScreenMusicScroll.cpp create mode 100644 stepmania/src/ScreenMusicScroll.h create mode 100644 stepmania/src/ScreenOptions.cpp create mode 100644 stepmania/src/ScreenOptions.h create mode 100644 stepmania/src/ScreenPlayerOptions.cpp create mode 100644 stepmania/src/ScreenPlayerOptions.h create mode 100644 stepmania/src/ScreenPrompt.cpp create mode 100644 stepmania/src/ScreenPrompt.h create mode 100644 stepmania/src/ScreenSandbox.cpp create mode 100644 stepmania/src/ScreenSandbox.h create mode 100644 stepmania/src/ScreenSelectDifficulty.cpp create mode 100644 stepmania/src/ScreenSelectDifficulty.h create mode 100644 stepmania/src/ScreenSelectGame.cpp create mode 100644 stepmania/src/ScreenSelectGame.h create mode 100644 stepmania/src/ScreenSelectGroup.cpp create mode 100644 stepmania/src/ScreenSelectGroup.h create mode 100644 stepmania/src/ScreenSelectMusic.cpp create mode 100644 stepmania/src/ScreenSelectMusic.h create mode 100644 stepmania/src/ScreenSelectStyle.cpp create mode 100644 stepmania/src/ScreenSelectStyle.h create mode 100644 stepmania/src/ScreenSongOptions.cpp create mode 100644 stepmania/src/ScreenSongOptions.h create mode 100644 stepmania/src/ScreenStage.cpp create mode 100644 stepmania/src/ScreenStage.h create mode 100644 stepmania/src/ScreenTitleMenu.cpp create mode 100644 stepmania/src/ScreenTitleMenu.h create mode 100644 stepmania/src/TransitionBackWipe.cpp create mode 100644 stepmania/src/TransitionBackWipe.h diff --git a/stepmania/src/AnnouncerManager.cpp b/stepmania/src/AnnouncerManager.cpp new file mode 100644 index 0000000000..ffad044ba5 --- /dev/null +++ b/stepmania/src/AnnouncerManager.cpp @@ -0,0 +1,153 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + Class: AnnouncerManager + + Desc: See header. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "AnnouncerManager.h" +#include "RageLog.h" +#include "ErrorCatcher/ErrorCatcher.h" + +AnnouncerManager* ANNOUNCER = NULL; // global object accessable from anywhere in the program + + +const CString DEFAULT_ANNOUNCER_NAME = "default"; +const CString ANNOUNER_BASE_DIR = "Announcers\\"; + + + +AnnouncerManager::AnnouncerManager() +{ + CStringArray arrayAnnouncerNames; + GetAnnouncerNames( arrayAnnouncerNames ); + for( int i=0; i=0; i-- ) + { + if( 0 == stricmp( AddTo[i], "cvs" ) ) + AddTo.RemoveAt(i); + } +} + +void AnnouncerManager::SwitchAnnouncer( CString sAnnouncerName ) +{ + m_sCurAnnouncerName = sAnnouncerName; + CString sAnnouncerDir = GetAnnouncerDirFromName( m_sCurAnnouncerName ); + if( !DoesFileExist( sAnnouncerDir ) ) + FatalError( "Error loading the announcer in diretory '%s'.", m_sCurAnnouncerName ); +} + +void AnnouncerManager::AssertAnnouncerIsComplete( CString sAnnouncerName ) +{ + for( int i=0; im_iCharToFrameNo[c]; if( iFrameNo == -1 ) // this font doesn't impelemnt this character - FatalError( ssprintf("The font '%s' does not implement the character '%c'", m_sFontFilePath, c) ); + FatalError( "The font '%s' does not implement the character '%c'", m_sFontFilePath, c ); const int iCharWidth = m_pFont->m_iFrameNoToWidth[iFrameNo]; // HACK: diff --git a/stepmania/src/Font.cpp b/stepmania/src/Font.cpp index b19e6a4ef3..ec8126b9a8 100644 --- a/stepmania/src/Font.cpp +++ b/stepmania/src/Font.cpp @@ -28,6 +28,10 @@ Font::Font( const CString &sFontFilePath ) m_iFrameNoToWidth[i] = -1; } + m_bCapitalsOnly = false; + m_fDrawExtraPercent = 0; + + m_iRefCount = 1; m_sFontFilePath = sFontFilePath; // save @@ -45,15 +49,16 @@ Font::Font( const CString &sFontFilePath ) IniFile ini; ini.SetPath( m_sFontFilePath ); if( !ini.ReadFile() ) - FatalError( ssprintf("Error opening Font file '%s'.", m_sFontFilePath) ); + FatalError( "Error opening Font file '%s'.", m_sFontFilePath ); // // load texture // - CString sTextureFile = ini.GetValue( "Font", "Texture" ); + CString sTextureFile; + ini.GetValue( "Font", "Texture", sTextureFile ); if( sTextureFile == "" ) - FatalError( ssprintf("Error reading value 'Texture' from %s.", m_sFontFilePath) ); + FatalError( "Error reading value 'Texture' from %s.", m_sFontFilePath ); m_sTexturePath = sFontDir + sTextureFile; // save the path of the new texture m_sTexturePath.MakeLower(); @@ -66,12 +71,14 @@ Font::Font( const CString &sFontFilePath ) // // find out what characters are in this font // - CString sCharacters = ini.GetValue( "Font", "Characters" ); - if( sCharacters != "" ) // the creator supplied characters + CString sCharacters; + if( ini.GetValue("Font", "Characters", sCharacters) ) // the creator supplied characters { // sanity check - if( sCharacters.GetLength() != (int)m_pTexture->GetNumFrames() ) - FatalError( "The characters in '%s' does not match the number of frames in the texture.", m_sFontFilePath ); + if( sCharacters.GetLength() != m_pTexture->GetNumFrames() ) + FatalError( "The characters in '%s' does not match the number of frames in the texture." + "The font has %d frames, and the texture has %d frames.", + m_sFontFilePath, sCharacters.GetLength(), m_pTexture->GetNumFrames() ); // set the char to frame number map for( int i=0; iGetNumFrames() ) - FatalError( ssprintf("The number of widths specified in '%s' (%d) do not match the number of frames in the texture (%u).", m_sFontFilePath, arrayCharWidths.GetSize(), m_pTexture->GetNumFrames()) ); - - for( int i=0; iGetNumFrames() ) + FatalError( "The number of widths specified in '%s' (%d) do not match the number of frames in the texture (%d).", + m_sFontFilePath, asCharWidths.GetSize(), m_pTexture->GetNumFrames() ); + for( int i=0; i MAX_INSTRUMENT_BUTTONS ) FatalError( "Invalid value for ButtonsPerInstrument in '%s'.", sGameFilePath ); - CString sButtonsString = ini.GetValue( "Game", "ButtonNames" ); + CString sButtonsString; + ini.GetValue( "Game", "ButtonNames", sButtonsString ); CStringArray arrayButtonNames; split( sButtonsString, ",", arrayButtonNames ); if( arrayButtonNames.GetSize() != m_iButtonsPerInstrument ) @@ -60,7 +63,8 @@ GameDef::GameDef( CString sGameDir ) for( int i=0; i= MAX_INPUT_QUEUE_LENGTH ) // full + m_aMenuButtonQueue[p].RemoveAt( 0, m_aMenuButtonQueue[p].GetSize()-MAX_INPUT_QUEUE_LENGTH+1 ); + m_aMenuButtonQueue[p].Add( MenuButtonAndTickCount(b,GetTickCount()) ); + }; + bool MatchesPattern( const PlayerNumber p, const MenuButton* button_sequence, const int iNumButtons, float fMaxSecondsBack = -1 ) + { + if( fMaxSecondsBack == -1 ) + fMaxSecondsBack = 0.4f + iNumButtons*0.15f; + + DWORD dwMaxTicksBack = roundf(fMaxSecondsBack*1000); + DWORD dwOldestTickAllowed = GetTickCount() - dwMaxTicksBack; + + int sequence_index = iNumButtons-1; // count down + for( int queue_index=m_aMenuButtonQueue[p].GetSize()-1; queue_index>=0; queue_index-- ) // iterate newest to oldest + { + MenuButtonAndTickCount BandT = m_aMenuButtonQueue[p][queue_index]; + if( BandT.button != button_sequence[sequence_index] || + BandT.dwTickCount < dwOldestTickAllowed ) + { + return false; + } + if( sequence_index == 0 ) // we matched the whole pattern + { + m_aMenuButtonQueue[p].RemoveAll(); // empty the queue so we don't match on it again + return true; + } + sequence_index--; + } + return false; + } + +protected: + struct MenuButtonAndTickCount + { + MenuButtonAndTickCount() {} + MenuButtonAndTickCount( MenuButton b, DWORD t ) { button = b; dwTickCount = t; }; + MenuButton button; + DWORD dwTickCount; + }; + CArray m_aMenuButtonQueue[NUM_PLAYERS]; +}; + + +extern InputQueue* INPUTQUEUE; // global and accessable from anywhere in our program diff --git a/stepmania/src/LifeMeter.h b/stepmania/src/LifeMeter.h new file mode 100644 index 0000000000..815ac26150 --- /dev/null +++ b/stepmania/src/LifeMeter.h @@ -0,0 +1,33 @@ +#pragma once +/* +----------------------------------------------------------------------------- + Class: LifeMeterBar + + Desc: A graphic displayed in the LifeMeterBar during Dancing. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "ActorFrame.h" +#include "GameConstantsAndTypes.h" +#include "NoteData.h" + + +class LifeMeter : public ActorFrame +{ +public: + LifeMeter() { m_fSongBeat = 0; }; + virtual ~LifeMeter() {}; + + void SetPlayerOptions(const PlayerOptions &po) { m_po = po; } + void SetBeat( float fSongBeat ) { m_fSongBeat = fSongBeat; }; + + virtual void ChangeLife( TapNoteScore score ) = 0; + virtual float GetLifePercentage() = 0; + +protected: + float m_fSongBeat; + PlayerOptions m_po; +}; diff --git a/stepmania/src/Notes.cpp b/stepmania/src/Notes.cpp new file mode 100644 index 0000000000..574ad258a1 --- /dev/null +++ b/stepmania/src/Notes.cpp @@ -0,0 +1,813 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + Class: Notes + + Desc: Hold Notes data and metadata. Does not hold gameplay-time information, + like keeping track of which Notes have been stepped on (PlayerSteps does that). + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "Notes.h" +#include "Song.h" +#include "Notes.h" +#include "IniFile.h" +#include "math.h" // for fabs() +#include "RageUtil.h" +#include "RageLog.h" +#include "ErrorCatcher/ErrorCatcher.h" +#include "GameInput.h" + + +typedef int DanceNote; +enum { + DANCE_NOTE_NONE = 0, + DANCE_NOTE_PAD1_LEFT, + DANCE_NOTE_PAD1_UPLEFT, + DANCE_NOTE_PAD1_DOWN, + DANCE_NOTE_PAD1_UP, + DANCE_NOTE_PAD1_UPRIGHT, + DANCE_NOTE_PAD1_RIGHT, + DANCE_NOTE_PAD2_LEFT, + DANCE_NOTE_PAD2_UPLEFT, + DANCE_NOTE_PAD2_DOWN, + DANCE_NOTE_PAD2_UP, + DANCE_NOTE_PAD2_UPRIGHT, + DANCE_NOTE_PAD2_RIGHT +}; + + + +Notes::Notes() +{ + m_DifficultyClass = CLASS_EASY; + m_iMeter = 0; + m_iNumTimesPlayed = 0; + m_iMaxCombo = 0; + m_iTopScore = 0; + m_TopGrade = GRADE_NO_DATA; + + m_pNoteData = NULL; +} + +Notes::~Notes() +{ +} + +void Notes::WriteToCacheFile( FILE* file ) +{ + LOG->WriteLine( "Notes::WriteToCacheFile()" ); + + WriteStringToFile( file, m_sIntendedGame ); + WriteStringToFile( file, m_sIntendedStyle ); + WriteStringToFile( file, m_sDescription ); + WriteStringToFile( file, m_sCredit ); + fprintf( file, "%d\n", m_DifficultyClass ); + fprintf( file, "%d\n", m_iMeter ); + for( int i=0; iWriteToCacheFile( file ); +} + +void Notes::ReadFromCacheFile( FILE* file, bool bLoadNoteData ) +{ + LOG->WriteLine( "Notes::ReadFromCacheFile( %d )", bLoadNoteData ); + + ReadStringFromFile( file, m_sIntendedGame ); + ReadStringFromFile( file, m_sIntendedStyle ); + ReadStringFromFile( file, m_sDescription ); + ReadStringFromFile( file, m_sCredit ); + fscanf( file, "%d\n", &m_DifficultyClass ); + fscanf( file, "%d\n", &m_iMeter ); + for( int i=0; iReadFromCacheFile( file ); + } + else + { + DeleteNoteData(); + NoteData::SkipOverDataInCacheFile( file ); + } +} + +bool Notes::LoadFromBMSFile( const CString &sPath ) +{ + LOG->WriteLine( "Notes::LoadFromBMSFile( '%s' )", sPath ); + + this->GetNoteData(); // make sure NoteData is loaded + + m_sIntendedGame = "dance"; + +// 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 double meanings! What were they thinking??? +// While reading in, use the 6 panel mapping. After reading in, detect if only 4 notes +// are used. If so, shift the Up+Right column back to the Up column +// + CMap mapBMSTrackToDanceNote; + mapBMSTrackToDanceNote[11] = DANCE_NOTE_PAD1_LEFT; + mapBMSTrackToDanceNote[12] = DANCE_NOTE_PAD1_UPLEFT; + mapBMSTrackToDanceNote[13] = DANCE_NOTE_PAD1_DOWN; + mapBMSTrackToDanceNote[14] = DANCE_NOTE_PAD1_UP; + mapBMSTrackToDanceNote[15] = DANCE_NOTE_PAD1_UPRIGHT; + mapBMSTrackToDanceNote[16] = DANCE_NOTE_PAD1_RIGHT; + mapBMSTrackToDanceNote[21] = DANCE_NOTE_PAD2_LEFT; + mapBMSTrackToDanceNote[22] = DANCE_NOTE_PAD2_UPLEFT; + mapBMSTrackToDanceNote[23] = DANCE_NOTE_PAD2_DOWN; + mapBMSTrackToDanceNote[24] = DANCE_NOTE_PAD2_UP; + mapBMSTrackToDanceNote[25] = DANCE_NOTE_PAD2_UPRIGHT; + mapBMSTrackToDanceNote[26] = DANCE_NOTE_PAD2_RIGHT; + + + bool tempNotes[MAX_NOTE_TRACKS][MAX_TAP_NOTE_ROWS]; + for( int t=0; t') + int iPosOpenBracket = m_sDescription.Find( "<" ); + if( iPosOpenBracket == -1 ) + iPosOpenBracket = m_sDescription.Find( "(" ); + int iPosCloseBracket = m_sDescription.Find( ">" ); + if( iPosCloseBracket == -1 ) + iPosCloseBracket = m_sDescription.Find( ")" ); + + if( iPosOpenBracket != -1 && iPosCloseBracket != -1 ) + m_sDescription = m_sDescription.Mid( iPosOpenBracket+1, iPosCloseBracket-iPosOpenBracket-1 ); + m_sDescription.MakeLower(); + LOG->WriteLine( "Notes description found to be '%s'", m_sDescription ); + + // if there's a 6 in the description, it's probably part of "6panel" or "6-panel" + if( m_sDescription.Find("6") != -1 ) + m_sIntendedStyle = "solo"; + + } + if( -1 != value_name.Find("#playlevel") ) + { + m_iMeter = atoi( value_data ); + + // Should we calculate m_DifficultyClass here? + } + else if( value_name.Left(1) == "#" + && IsAnInt( value_name.Mid(1,3) ) + && IsAnInt( value_name.Mid(4,2) ) ) // this is step or offset data. Looks like "#00705" + { + int iMeasureNo = atoi( value_name.Mid(1,3) ); + int iTrackNum = atoi( value_name.Mid(4,2) ); + + CString sNoteData = value_data; + CArray arrayNotes; + + for( int i=0; iWriteLine( "%s:%s: iMeasureNo = %d, iNoteNum = %d, iNumNotesInThisMeasure = %d", + // valuename, sNoteData, iMeasureNo, iNoteNum, iNumNotesInThisMeasure ); + for( int j=0; j mapDanceNoteToNoteDataColumn; + if( m_sIntendedStyle == "single" ) + { + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 1; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 2; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 3; + } + else if( m_sIntendedStyle == "double" ) + { + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 1; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 2; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 3; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_LEFT] = 4; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_DOWN] = 5; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_UP] = 6; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_RIGHT] = 7; + } + else if( m_sIntendedStyle == "couple" ) + { + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 1; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 2; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 3; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_LEFT] = 4; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_DOWN] = 5; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_UP] = 6; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_RIGHT] = 7; + } + else if( m_sIntendedStyle == "solo" ) + { + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UPLEFT] = 1; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 2; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 3; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UPRIGHT] = 4; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 5; + } + + // copy the tempData we collected into NoteData + POSITION pos = mapDanceNoteToNoteDataColumn.GetStartPosition(); + while( pos != NULL ) // iterate over all k/v pairs in map + { + int iTempCol; + int iNoteDataCol; + mapDanceNoteToNoteDataColumn.GetNextAssoc( pos, iTempCol, iNoteDataCol ); + + for( int i=0; im_TapNotes[iNoteDataCol][i] = '1'; + } + } + + m_pNoteData->m_iNumTracks = mapDanceNoteToNoteDataColumn.GetCount(); + + + // search for runs of 32nd notes of all the same note type, and convert them to freezes + for( int iCol=0; iColm_TapNotes[iCol][i] == '1' ) // there is a step here + { + if( iIndexRunStart == -1 ) // we are not in the middle of a run + { + iIndexRunStart = i; + } + else // we are in the middle of a run + { + ; // do nothing. Keep reading in until we hit the end of the run. + } + } + else // there isn't a step here + { + if( iIndexRunStart == -1 ) // we are not in the middle of a run + { + ; // do nothing + } + else // we are in the middle of a run + { + // this ends the run + + if( i - iIndexRunStart < 2 ) // reject runs of length 1 + { + ; // do nothing + } + else // this run is longer than 1 + { + // add this HoldNote to the list + int iIndexRunEnd = i - 1; + HoldNote hn = { iCol, iIndexRunStart, iIndexRunEnd }; + m_pNoteData->AddHoldNote( hn ); + + LOG->WriteLine( "Found a run on track %d: start: %d, end: %d.", hn.m_iTrack, hn.m_iStartIndex, hn.m_iEndIndex ); + } + + iIndexRunStart = -1; // reset so we can look for more runs + } + } + } + // done looking for runs + + + } + + return true; +} + + + + +void DWIcharToNote( char c, InstrumentNumber i, DanceNote ¬e1Out, DanceNote ¬e2Out ) +{ + switch( c ) + { + case '0': note1Out = DANCE_NOTE_NONE; note2Out = DANCE_NOTE_NONE; break; + case '1': note1Out = DANCE_NOTE_PAD1_DOWN; note2Out = DANCE_NOTE_PAD1_LEFT; break; + case '2': note1Out = DANCE_NOTE_PAD1_DOWN; note2Out = DANCE_NOTE_NONE; break; + case '3': note1Out = DANCE_NOTE_PAD1_DOWN; note2Out = DANCE_NOTE_PAD1_RIGHT; break; + case '4': note1Out = DANCE_NOTE_PAD1_LEFT; note2Out = DANCE_NOTE_NONE; break; + case '5': note1Out = DANCE_NOTE_NONE; note2Out = DANCE_NOTE_NONE; break; + case '6': note1Out = DANCE_NOTE_PAD1_RIGHT; note2Out = DANCE_NOTE_NONE; break; + case '7': note1Out = DANCE_NOTE_PAD1_UP; note2Out = DANCE_NOTE_PAD1_LEFT; break; + case '8': note1Out = DANCE_NOTE_PAD1_UP; note2Out = DANCE_NOTE_NONE; break; + case '9': note1Out = DANCE_NOTE_PAD1_UP; note2Out = DANCE_NOTE_PAD1_RIGHT; break; + case 'A': note1Out = DANCE_NOTE_PAD1_UP; note2Out = DANCE_NOTE_PAD1_DOWN; break; + case 'B': note1Out = DANCE_NOTE_PAD1_LEFT; note2Out = DANCE_NOTE_PAD1_RIGHT; break; + case 'C': note1Out = DANCE_NOTE_PAD1_UPLEFT; note2Out = DANCE_NOTE_NONE; break; + case 'D': note1Out = DANCE_NOTE_PAD1_UPRIGHT; note2Out = DANCE_NOTE_NONE; break; + case 'E': note1Out = DANCE_NOTE_PAD1_LEFT; note2Out = DANCE_NOTE_PAD1_UPLEFT; break; + case 'F': note1Out = DANCE_NOTE_PAD1_UPLEFT; note2Out = DANCE_NOTE_PAD1_DOWN; break; + case 'G': note1Out = DANCE_NOTE_PAD1_UPLEFT; note2Out = DANCE_NOTE_PAD1_UP; break; + case 'H': note1Out = DANCE_NOTE_PAD1_UPLEFT; note2Out = DANCE_NOTE_PAD1_RIGHT; break; + case 'I': note1Out = DANCE_NOTE_PAD1_LEFT; note2Out = DANCE_NOTE_PAD1_UPRIGHT; break; + case 'J': note1Out = DANCE_NOTE_PAD1_DOWN; note2Out = DANCE_NOTE_PAD1_UPRIGHT; break; + case 'K': note1Out = DANCE_NOTE_PAD1_UP; note2Out = DANCE_NOTE_PAD1_UPRIGHT; break; + case 'L': note1Out = DANCE_NOTE_PAD1_UPRIGHT; note2Out = DANCE_NOTE_PAD1_RIGHT; break; + case 'M': note1Out = DANCE_NOTE_PAD1_UPLEFT; note2Out = DANCE_NOTE_PAD1_UPRIGHT; break; + default: FatalError( "Encountered invalid DWI note characer '%c'", c ); break; + } + + switch( i ) + { + case INSTRUMENT_1: + break; + case INSTRUMENT_2: + note1Out <<= 6; + if( note2Out != DANCE_NOTE_NONE ) + note2Out <<= 6; + break; + default: + ASSERT( false ); + } +} + + + +bool Notes::LoadFromDWITokens( + const CString &sMode, const CString &sDescription, + const CString &sNumFeet, + const CString &sStepData1, const CString &sStepData2 ) +{ + LOG->WriteLine( "Notes::LoadFromDWITokens()" ); + + m_sIntendedGame = "dance"; + + if( sMode == "#SINGLE" ) m_sIntendedStyle = "single"; + else if( sMode == "#DOUBLE" ) m_sIntendedStyle = "double"; + else if( sMode == "#COUPLE" ) m_sIntendedStyle = "couple"; + else if( sMode == "#SOLO" ) m_sIntendedStyle = "solo"; + else FatalError( "Unrecognized DWI mode '%s'", sMode ); + + + CMap mapDanceNoteToNoteDataColumn; + if( m_sIntendedStyle == "single" ) + { + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 1; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 2; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 3; + } + else if( m_sIntendedStyle == "double" || m_sIntendedStyle == "couple" ) + { + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 1; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 2; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 3; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_LEFT] = 4; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_DOWN] = 5; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_UP] = 6; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD2_RIGHT] = 7; + } + else if( m_sIntendedStyle == "solo" ) + { + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_LEFT] = 0; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UPLEFT] = 1; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_DOWN] = 2; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UP] = 3; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_UPRIGHT] = 4; + mapDanceNoteToNoteDataColumn[DANCE_NOTE_PAD1_RIGHT] = 5; + } + else + ASSERT( false ); + + m_sDescription = sDescription; + + m_iMeter = atoi( sNumFeet ); + + if( m_sDescription == "BASIC" ) m_DifficultyClass = CLASS_EASY; + else if( m_sDescription == "ANOTHER" ) m_DifficultyClass = CLASS_MEDIUM; + else if( m_sDescription == "MANIAC" ) m_DifficultyClass = CLASS_HARD; + else if( m_sDescription == "SMANIAC" ) m_DifficultyClass = CLASS_HARD; + else + { + // guess difficulty class from m_iMeter + if( m_iMeter <= 3 ) m_DifficultyClass = CLASS_EASY; + else if( m_iMeter <= 6 ) m_DifficultyClass = CLASS_MEDIUM; + else m_DifficultyClass = CLASS_HARD; + } + + m_sCredit = ""; + + + + ASSERT( m_pNoteData == NULL ); // if not, then we're loading this Notes twice + m_pNoteData = new NoteData; + m_pNoteData->m_iNumTracks = mapDanceNoteToNoteDataColumn.GetCount(); + + for( int pad=0; pad<2; pad++ ) // foreach pad + { + CString sStepData; + switch( pad ) + { + case 0: + sStepData = sStepData1; + break; + case 1: + if( sStepData2 == "" ) // no data + continue; // skip + sStepData = sStepData2; + break; + default: + ASSERT( false ); + } + + double fCurrentBeat = 0; + double fCurrentIncrementer = 1.0/8 * BEATS_PER_MEASURE; + for( int i=0; i': + fCurrentIncrementer = 1.0/8 * BEATS_PER_MEASURE; + break; + + case ' ': + break; // do nothing! + + case '!': // hold start + { + // rewind and get the last step we inserted + double fLastStepBeat = fCurrentBeat - fCurrentIncrementer; + int iIndex = BeatToNoteRow( (float)fLastStepBeat ); + + char holdChar = sStepData[i++]; + + DanceNote note1, note2; + DWIcharToNote( holdChar, (InstrumentNumber)pad, note1, note2 ); + + if( note1 != DANCE_NOTE_NONE ) + { + int iCol1 = mapDanceNoteToNoteDataColumn[note1]; + m_pNoteData->m_TapNotes[iCol1][iIndex] = '2'; + } + if( note2 != DANCE_NOTE_NONE ) + { + int iCol2 = mapDanceNoteToNoteDataColumn[note2]; + m_pNoteData->m_TapNotes[iCol2][iIndex] = '2'; + } + + } + break; + default: // this is a note character + { + int iIndex = BeatToNoteRow( (float)fCurrentBeat ); + + DanceNote note1, note2; + DWIcharToNote( c, (InstrumentNumber)pad, note1, note2 ); + + if( note1 != DANCE_NOTE_NONE ) + { + int iCol1 = mapDanceNoteToNoteDataColumn[note1]; + m_pNoteData->m_TapNotes[iCol1][iIndex] = '1'; + } + if( note2 != DANCE_NOTE_NONE ) + { + int iCol2 = mapDanceNoteToNoteDataColumn[note2]; + m_pNoteData->m_TapNotes[iCol2][iIndex] = '1'; + } + + fCurrentBeat += fCurrentIncrementer; + } + break; + } + } + } + + m_pNoteData->Convert2sAnd3sToHoldNotes(); // this will expand the HoldNote begin markers we wrote into actual HoldNotes + + return true; +} + +bool Notes::LoadFromNotesFile( const CString &sPath ) +{ + LOG->WriteLine( "Notes::LoadFromNotesFile( '%s' )", sPath ); + + CStdioFile file; + if( !file.Open( sPath, CFile::modeRead|CFile::shareDenyNone ) ) + FatalError( "Error opening DWI file '%s'.", sPath ); + + // read the whole file into a sFileText + CString sFileText; + CString buffer; + while( file.ReadString(buffer) ) + sFileText += buffer + "\n"; + 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, false ); + + if( arrayValueTokens.GetSize() == 0 ) + continue; + + CString sValueName = arrayValueTokens.GetAt( 0 ); + sValueName.TrimLeft(); + sValueName.TrimRight(); + + // handle the data + if( sValueName == "#GAME" ) + { + m_sIntendedGame = arrayValueTokens[1]; + m_sIntendedGame.MakeLower(); + } + else if( sValueName == "#STYLE" ) + { + m_sIntendedStyle = arrayValueTokens[1]; + m_sIntendedStyle.MakeLower(); + } + else if( sValueName == "#DESCRIPTION" ) + m_sDescription = arrayValueTokens[1]; + + else if( sValueName == "#CREDIT" ) + m_sCredit = arrayValueTokens[1]; + + else if( sValueName == "#METER" ) + m_iMeter = atoi( arrayValueTokens[1] ); + + else if( sValueName == "#NOTES" ) + { + arrayValueTokens.RemoveAt( 0 ); + + ASSERT( m_pNoteData == NULL ); // if not, then we're loading this Notes twice + m_pNoteData = new NoteData; + + CString sFirstMeasure = arrayValueTokens[0]; + int result = sFirstMeasure.Find( '\n' ); + + m_pNoteData->SetFromMeasureStrings( arrayValueTokens ); + } + + else + LOG->WriteLine( "Unexpected value named '%s'", sValueName ); + } + + return true; +} + + + +void Notes::SaveToSMDir( CString sSongDir ) +{ + LOG->WriteLine( "Notes::Save( '%s' )", sSongDir ); + + int i; + + CString sNewNotesFilePath = sSongDir + ssprintf("%s-%s-%s.notes", m_sIntendedGame, m_sIntendedStyle, m_sDescription); + + CStdioFile file; + if( !file.Open( sNewNotesFilePath, CFile::modeWrite | CFile::modeCreate ) ) + FatalError( ssprintf("Error opening Notes file '%s' for writing.", sNewNotesFilePath) ); + + file.WriteString( ssprintf("#GAME:%s;\n", m_sIntendedGame) ); + file.WriteString( ssprintf("#STYLE:%s;\n", m_sIntendedStyle) ); + file.WriteString( ssprintf("#DESCRIPTION:%s;\n", m_sDescription) ); + file.WriteString( ssprintf("#CREDIT:%s;\n", m_sCredit) ); + file.WriteString( ssprintf("#METER:%d;\n", m_iMeter) ); + + + file.WriteString( "#NOTES\n" ); + CStringArray sMeasureStrings; + GetNoteData()->GetMeasureStrings( sMeasureStrings ); + for( i=0; iCopyAll( pNewNoteData ); +} + +void Notes::DeleteNoteData() +{ + SAFE_DELETE( m_pNoteData ); +} + + +////////////////////////////////////////////// +// +////////////////////////////////////////////// + + +int CompareNotesPointersByMeter(const void *arg1, const void *arg2) +{ + Notes* pNotes1 = *(Notes**)arg1; + Notes* pNotes2 = *(Notes**)arg2; + + int iScore1 = pNotes1->m_iMeter; + int iScore2 = pNotes2->m_iMeter; + + if( iScore1 < iScore2 ) + return -1; + else if( iScore1 == iScore2 ) + return 0; + else + return 1; +} + +int CompareNotesPointersByDifficultyClass(const void *arg1, const void *arg2) +{ + Notes* pNotes1 = *(Notes**)arg1; + Notes* pNotes2 = *(Notes**)arg2; + + DifficultyClass class1 = pNotes1->m_DifficultyClass; + DifficultyClass class2 = pNotes2->m_DifficultyClass; + + if( class1 < class2 ) + return -1; + else if( class1 == class2 ) + return CompareNotesPointersByMeter( arg1, arg2 ); + else + return 1; +} + +void SortNotesArrayByDifficultyClass( CArray &arraySteps ) +{ + qsort( arraySteps.GetData(), arraySteps.GetSize(), sizeof(Notes*), CompareNotesPointersByDifficultyClass ); +} + diff --git a/stepmania/src/Notes.h b/stepmania/src/Notes.h new file mode 100644 index 0000000000..bf0b126df0 --- /dev/null +++ b/stepmania/src/Notes.h @@ -0,0 +1,63 @@ +#pragma once +/* +----------------------------------------------------------------------------- + Class: Notes + + Desc: Holds note information for a Song. A Song may have one or more Notess. + A Notes can be played by one or more Styles. See StyleDef.h for more info on + Styles. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "GameConstantsAndTypes.h" +#include "Grade.h" +#include "NoteData.h" + + +struct Notes +{ +public: + Notes(); + ~Notes(); + + // Loading + bool LoadFromNotesFile( const CString &sPath ); + bool LoadFromBMSFile( const CString &sPath ); + bool LoadFromDWITokens( const CString &sMode, const CString &sDescription, + const CString &sNumFeet, + const CString &sStepData1, const CString &sStepData2 ); + void ReadFromCacheFile( FILE* file, bool bReadNoteData ); + + // for saving + void SaveToSMDir( CString sSongDir ); + void WriteToCacheFile( FILE* file ); + +public: + CString m_sIntendedGame; + CString m_sIntendedStyle; + CString m_sDescription; // This text is displayed next to thte number of feet when a song is selected + CString m_sCredit; // name of the person who created these Notes + DifficultyClass m_DifficultyClass; // this is inferred from m_sDescription + int m_iMeter; // difficulty from 1-10 + float m_fRadarValues[NUM_RADAR_VALUES]; // between 0.0-1.2 starting from 12-o'clock rotating clockwise + + // Statistics + Grade m_TopGrade; + int m_iTopScore; + int m_iMaxCombo; + int m_iNumTimesPlayed; + + bool IsNoteDataLoaded(); + NoteData* GetNoteData(); + void SetNoteData( NoteData* pNewNoteData ); + void DeleteNoteData(); + +protected: + NoteData* m_pNoteData; +}; + + +void SortNotesArrayByDifficultyClass( CArray &arrayNotess ); diff --git a/stepmania/src/PrefsManager.cpp b/stepmania/src/PrefsManager.cpp index 90de2db147..179f3c3746 100644 --- a/stepmania/src/PrefsManager.cpp +++ b/stepmania/src/PrefsManager.cpp @@ -106,60 +106,28 @@ void PrefsManager::ReadPrefsFromDisk() IniFile ini; ini.SetPath( "StepMania.ini" ); if( !ini.ReadFile() ) { - return; // load nothing - //FatalError( "could not read config file" ); + return; // could not read config file, load nothing } - CMapStringToString* pKey; - CString name_string, value_string; - + GraphicProfileOptions* pGPO = GetCustomGraphicProfileOptions(); - pKey = ini.GetKeyPointer( "GameOptions" ); - if( pKey ) - { - for( POSITION pos = pKey->GetStartPosition(); pos != NULL; ) - { - pKey->GetNextAssoc( pos, name_string, value_string ); - - if( name_string == "IgnoreJoyAxes" ) m_GameOptions.m_bIgnoreJoyAxes = ( value_string == "1" ); - if( name_string == "ShowFPS" ) m_GameOptions.m_bShowFPS = ( value_string == "1" ); - if( name_string == "UseRandomVis" ) m_GameOptions.m_bUseRandomVis = ( value_string == "1" ); - if( name_string == "Announcer" ) m_GameOptions.m_bAnnouncer = ( value_string == "1" ); - if( name_string == "ShowCaution" ) m_GameOptions.m_bShowCaution = ( value_string == "1" ); - if( name_string == "ShowSelectDifficulty" ) m_GameOptions.m_bShowSelectDifficulty = ( value_string == "1" ); - if( name_string == "ShowSelectGroup" ) m_GameOptions.m_bShowSelectGroup = ( value_string == "1" ); - if( name_string == "NumArcadeStages" ) m_GameOptions.m_iNumArcadeStages = atoi( value_string ); - if( name_string == "JudgementDifficulty" ) m_GameOptions.m_JudgementDifficulty= (GameOptions::JudgementDifficulty) atoi( value_string ); - } - } - - pKey = ini.GetKeyPointer( "GraphicOptions" ); - if( pKey ) - { - for( POSITION pos = pKey->GetStartPosition(); pos != NULL; ) - { - pKey->GetNextAssoc( pos, name_string, value_string ); - - if( name_string == "Windowed" ) m_bWindowed = ( value_string == "1" ); - if( name_string == "Profile" ) - { - if( value_string == "super low" ) m_GraphicProfile = PROFILE_SUPER_LOW; - else if( value_string == "low" ) m_GraphicProfile = PROFILE_LOW; - else if( value_string == "medium" ) m_GraphicProfile = PROFILE_MEDIUM; - else if( value_string == "high" ) m_GraphicProfile = PROFILE_HIGH; - else if( value_string == "custom" ) m_GraphicProfile = PROFILE_CUSTOM; - else m_GraphicProfile = PROFILE_MEDIUM; - } - - GraphicProfileOptions* pGPO = GetCustomGraphicProfileOptions(); - if( name_string == "Width" ) pGPO->m_dwWidth = atoi( value_string ); - if( name_string == "Height" ) pGPO->m_dwHeight = atoi( value_string ); - if( name_string == "MaxTextureSize" ) pGPO->m_dwMaxTextureSize = atoi( value_string ); - if( name_string == "DisplayColor" ) pGPO->m_dwDisplayColor = atoi( value_string ); - if( name_string == "TextureColor" ) pGPO->m_dwTextureColor = atoi( value_string ); - } - } + ini.GetValueB( "GraphicOptions", "Windowed", m_bWindowed ); + ini.GetValueI( "GraphicOptions", "Profile", (int&)m_GraphicProfile ); + ini.GetValueI( "GraphicOptions", "Width", pGPO->m_iWidth ); + ini.GetValueI( "GraphicOptions", "Height", pGPO->m_iHeight ); + ini.GetValueI( "GraphicOptions", "MaxTextureSize", pGPO->m_iMaxTextureSize ); + ini.GetValueI( "GraphicOptions", "DisplayColor", pGPO->m_iDisplayColor ); + ini.GetValueI( "GraphicOptions", "TextureColor", pGPO->m_iTextureColor ); + ini.GetValueB( "GameOptions", "IgnoreJoyAxes", m_GameOptions.m_bIgnoreJoyAxes ); + ini.GetValueB( "GameOptions", "ShowFPS", m_GameOptions.m_bShowFPS ); + ini.GetValueB( "GameOptions", "UseRandomVis", m_GameOptions.m_bUseRandomVis ); + ini.GetValueB( "GameOptions", "Announcer", m_GameOptions.m_bAnnouncer ); + ini.GetValueB( "GameOptions", "EventMode", m_GameOptions.m_bEventMode ); + ini.GetValueB( "GameOptions", "ShowSelectDifficulty", m_GameOptions.m_bShowSelectDifficulty ); + ini.GetValueB( "GameOptions", "ShowSelectGroup", m_GameOptions.m_bShowSelectGroup ); + ini.GetValueI( "GameOptions", "NumArcadeStages", m_GameOptions.m_iNumArcadeStages ); + ini.GetValueI( "GameOptions", "Difficulty", m_GameOptions.m_iDifficulty ); } @@ -167,40 +135,27 @@ void PrefsManager::SavePrefsToDisk() { IniFile ini; ini.SetPath( "StepMania.ini" ); -// ini.ReadFile(); // don't read the file so that we overwrite everything there - - - // save the GameOptions - ini.SetValue( "GraphicOptions", "Windowed", m_bWindowed ? "1":"0" ); - switch( m_GraphicProfile ) - { - case PROFILE_SUPER_LOW: ini.SetValue( "GraphicOptions", "Profile", "super low" ); break; - case PROFILE_LOW: ini.SetValue( "GraphicOptions", "Profile", "low" ); break; - case PROFILE_MEDIUM: ini.SetValue( "GraphicOptions", "Profile", "medium" ); break; - case PROFILE_HIGH: ini.SetValue( "GraphicOptions", "Profile", "high" ); break; - case PROFILE_CUSTOM: ini.SetValue( "GraphicOptions", "Profile", "custom" ); break; - default: ASSERT( false ); - } GraphicProfileOptions* pGPO = GetCustomGraphicProfileOptions(); - ini.SetValue( "GraphicOptions", "Width", ssprintf("%d", pGPO->m_dwWidth) ); - ini.SetValue( "GraphicOptions", "Height", ssprintf("%d", pGPO->m_dwWidth) ); - ini.SetValue( "GraphicOptions", "MaxTextureSize", ssprintf("%d", pGPO->m_dwMaxTextureSize) ); - ini.SetValue( "GraphicOptions", "DisplayColor", ssprintf("%d", pGPO->m_dwDisplayColor) ); - ini.SetValue( "GraphicOptions", "TextureColor", ssprintf("%d", pGPO->m_dwTextureColor) ); - - - ini.SetValue( "GameOptions", "IgnoreJoyAxes", m_GameOptions.m_bIgnoreJoyAxes ? "1":"0" ); - ini.SetValue( "GameOptions", "ShowFPS", m_GameOptions.m_bShowFPS ? "1":"0" ); - ini.SetValue( "GameOptions", "UseRandomVis", m_GameOptions.m_bUseRandomVis ? "1":"0" ); - ini.SetValue( "GameOptions", "Announcer", m_GameOptions.m_bAnnouncer ? "1":"0" ); - ini.SetValue( "GameOptions", "ShowCaution", m_GameOptions.m_bShowCaution ? "1":"0" ); - ini.SetValue( "GameOptions", "ShowSelectDifficulty",m_GameOptions.m_bShowSelectDifficulty ? "1":"0" ); - ini.SetValue( "GameOptions", "ShowSelectGroup", m_GameOptions.m_bShowSelectGroup ? "1":"0" ); - + ini.SetValueB( "GraphicOptions", "Windowed", m_bWindowed ); + ini.SetValueI( "GraphicOptions", "Profile", m_GraphicProfile ); + ini.SetValueI( "GraphicOptions", "Width", pGPO->m_iWidth ); + ini.SetValueI( "GraphicOptions", "Height", pGPO->m_iHeight ); + ini.SetValueI( "GraphicOptions", "MaxTextureSize", pGPO->m_iMaxTextureSize ); + ini.SetValueI( "GraphicOptions", "DisplayColor", pGPO->m_iDisplayColor ); + ini.SetValueI( "GraphicOptions", "TextureColor", pGPO->m_iTextureColor ); + ini.SetValueB( "GameOptions", "IgnoreJoyAxes", m_GameOptions.m_bIgnoreJoyAxes ); + ini.SetValueB( "GameOptions", "ShowFPS", m_GameOptions.m_bShowFPS ); + ini.SetValueB( "GameOptions", "UseRandomVis", m_GameOptions.m_bUseRandomVis ); + ini.SetValueB( "GameOptions", "Announcer", m_GameOptions.m_bAnnouncer ); + ini.SetValueB( "GameOptions", "EventMode", m_GameOptions.m_bEventMode ); + ini.SetValueB( "GameOptions", "ShowSelectDifficulty", m_GameOptions.m_bShowSelectDifficulty ); + ini.SetValueB( "GameOptions", "ShowSelectGroup", m_GameOptions.m_bShowSelectGroup ); + ini.SetValueI( "GameOptions", "NumArcadeStages", m_GameOptions.m_iNumArcadeStages ); + ini.SetValueI( "GameOptions", "Difficulty", m_GameOptions.m_iDifficulty ); ini.WriteFile(); } diff --git a/stepmania/src/Quad.h b/stepmania/src/Quad.h new file mode 100644 index 0000000000..90c5ae9dc3 --- /dev/null +++ b/stepmania/src/Quad.h @@ -0,0 +1,23 @@ +#pragma once +/* +----------------------------------------------------------------------------- + Class: Quad + + Desc: A rectangle shaped actor with color. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "Actor.h" + + +class Quad : public Actor +{ +public: + Quad(); + + virtual void DrawPrimitives(); + +}; diff --git a/stepmania/src/RageDisplay.cpp b/stepmania/src/RageDisplay.cpp new file mode 100644 index 0000000000..5032dfb274 --- /dev/null +++ b/stepmania/src/RageDisplay.cpp @@ -0,0 +1,430 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + Class: RageDisplay + + Desc: See header. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "RageDisplay.h" + +#include "RageUtil.h" +#include "RageLog.h" +#include "ErrorCatcher/ErrorCatcher.h" + +RageDisplay* DISPLAY = NULL; + + +RageDisplay::RageDisplay( HWND hWnd ) +{ + LOG->WriteLine( "RageDisplay::RageDisplay()" ); + + // Save the window handle + m_hWnd = hWnd; + m_pd3d = NULL; + m_pd3dDevice = NULL; + m_pVB = NULL; + m_pIB = NULL; + + m_dwLastUpdateTicks = GetTickCount(); + m_iFramesRenderedSinceLastCheck = 0; + m_fFPS = 0; + + + try + { + // Construct a Direct3D object + m_pd3d = Direct3DCreate8( D3D_SDK_VERSION ); + } + catch (...) + { + // Edwin Evans: Catch any exception. It won't be caught by main exception handler. + FatalError( "Unknown exception in Direct3DCreate8." ); + } + + if( NULL == m_pd3d ) + FatalError( "Direct3DCreate8 failed." ); + + HRESULT hr; + if( FAILED( hr = m_pd3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &m_DeviceCaps) ) ) + { + FatalError( + "There was an error while initializing your video card.\n\n" + "Your system is reporting that Direct3D8 hardware acceleration\n" + "is not available. In most cases, you can download an updated\n" + "driver from your card's manufacturer." + ); + } + + LOG->WriteLine( + "Video card info:\n" + " - max texture width is %d\n" + " - max texture height is %d\n" + " - max texture blend stages is %d\n" + " - max simultaneous textures is %d\n", + m_DeviceCaps.MaxTextureWidth, + m_DeviceCaps.MaxTextureHeight, + m_DeviceCaps.MaxTextureBlendStages, + m_DeviceCaps.MaxSimultaneousTextures + ); + + + + // Enumerate possible display modes + LOG->WriteLine( "This display adaptor supports the following modes:" ); + for( UINT u=0; uGetAdapterModeCount(D3DADAPTER_DEFAULT); u++ ) + { + D3DDISPLAYMODE mode; + if( SUCCEEDED( m_pd3d->EnumAdapterModes( D3DADAPTER_DEFAULT, u, &mode ) ) ) + { + //LOG->WriteLine( " %ux%u %uHz, format %d", mode.Width, mode.Height, mode.RefreshRate, mode.Format ); + } + } + + // Save the original desktop format. + m_pd3d->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &m_DesktopMode ); +} + +RageDisplay::~RageDisplay() +{ + ReleaseVertexBuffer(); + ReleaseIndexBuffer(); + // Release our D3D Device + SAFE_RELEASE( m_pd3dDevice ); + m_pd3d->Release(); +} + + + +//----------------------------------------------------------------------------- +// Name: SwitchDisplayMode() +// Desc: +//----------------------------------------------------------------------------- +bool RageDisplay::SwitchDisplayMode( + const bool bWindowed, const DWORD dwWidth, const DWORD dwHeight, + const DWORD dwBPP, const DWORD dwFlags ) +{ + LOG->WriteLine( "RageDisplay::SwitchDisplayModes( %d, %u, %u, %u )", bWindowed, dwWidth, dwHeight, dwBPP ); + + + HRESULT hr; + + // Find an pixel format for the back buffer. + // If windowed, then dwBPP is ignored. Use whatever works. + CArray arrayBackBufferFormats; // throw all possibilities in here + + if( bWindowed ) + { + arrayBackBufferFormats.Add( D3DFMT_R5G6B5 ); + arrayBackBufferFormats.Add( D3DFMT_X1R5G5B5 ); + arrayBackBufferFormats.Add( D3DFMT_A1R5G5B5 ); + arrayBackBufferFormats.Add( D3DFMT_R8G8B8 ); + arrayBackBufferFormats.Add( D3DFMT_X8R8G8B8 ); + arrayBackBufferFormats.Add( D3DFMT_A8R8G8B8 ); + } + else // full screen + { + // add only the formats that match dwBPP + switch( dwBPP ) + { + case 16: + arrayBackBufferFormats.Add( D3DFMT_R5G6B5 ); + arrayBackBufferFormats.Add( D3DFMT_X1R5G5B5 ); + arrayBackBufferFormats.Add( D3DFMT_A1R5G5B5 ); + break; + case 32: + arrayBackBufferFormats.Add( D3DFMT_R8G8B8 ); + arrayBackBufferFormats.Add( D3DFMT_X8R8G8B8 ); + arrayBackBufferFormats.Add( D3DFMT_A8R8G8B8 ); + break; + default: + FatalError( ssprintf("Invalid BPP '%u' specified", dwBPP) ); + return false; + } + } + + + // Test each back buffer format until we find something that works. + D3DFORMAT fmtDisplay; // fill these in below... + D3DFORMAT fmtBackBuffer; + + for( int i=0; i < arrayBackBufferFormats.GetSize(); i++ ) + { + if( bWindowed ) + { + fmtDisplay = m_DesktopMode.Format; + fmtBackBuffer = arrayBackBufferFormats[i]; + } + else // Fullscreen + { + fmtDisplay = fmtBackBuffer = arrayBackBufferFormats[i]; + } + + LOG->WriteLine( "Testing format: display %d, back buffer %d, windowed %d...", fmtDisplay, fmtBackBuffer, bWindowed ); + + hr = m_pd3d->CheckDeviceType( + D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, + fmtDisplay, + fmtBackBuffer, + bWindowed + ); + + if( SUCCEEDED(hr) ) + { + LOG->WriteLine( "This will work." ); + break; // done searching + } + else + { + LOG->WriteLine( "This won't work. Keep searching." ); + } + } + + if( i == arrayBackBufferFormats.GetSize() ) // we didn't find an appropriate format + { + LOG->WriteLineHr( hr, "failed to find an appropriate format for %d, %u, %u, %u.", bWindowed, dwWidth, dwHeight, dwBPP ); + return false; + } + + + + // Set up presentation parameters for the display + ZeroMemory( &m_d3dpp, sizeof(m_d3dpp) ); + + m_d3dpp.BackBufferWidth = dwWidth; + m_d3dpp.BackBufferHeight = dwHeight; + m_d3dpp.BackBufferFormat = fmtBackBuffer; + m_d3dpp.BackBufferCount = 1; + m_d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; + m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + m_d3dpp.hDeviceWindow = m_hWnd; + m_d3dpp.Windowed = bWindowed; + m_d3dpp.EnableAutoDepthStencil = TRUE; + m_d3dpp.AutoDepthStencilFormat = D3DFMT_D16; + m_d3dpp.Flags = 0; + m_d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; + m_d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + + LOG->WriteLine( "Present Parameters: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", + m_d3dpp.BackBufferWidth, + m_d3dpp.BackBufferHeight, + m_d3dpp.BackBufferFormat, + m_d3dpp.BackBufferCount, + m_d3dpp.MultiSampleType, + m_d3dpp.SwapEffect, + m_d3dpp.hDeviceWindow, + m_d3dpp.Windowed, + m_d3dpp.EnableAutoDepthStencil, + m_d3dpp.AutoDepthStencilFormat, + m_d3dpp.Flags, + m_d3dpp.FullScreen_RefreshRateInHz, + m_d3dpp.FullScreen_PresentationInterval + ); + + + + if( m_pd3dDevice == NULL ) + { + // device is not yet created. We need to create it + if( FAILED( hr = m_pd3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, + m_hWnd, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, + &m_d3dpp, &m_pd3dDevice) ) ) + { + LOG->WriteLineHr( hr, "failed to create device: %d, %u, %u, %u.", bWindowed, dwWidth, dwHeight, dwBPP ); + return false; + } + if( m_pVB == NULL ) + CreateVertexBuffer(); + + if( m_pIB == NULL ) + CreateIndexBuffer(); + } + else + { + // device is already created. Just reset it. + if( FAILED( hr = m_pd3dDevice->Reset( &m_d3dpp ) ) ) + { + LOG->WriteLineHr( hr, "failed to reset device: %d, %u, %u, %u.", bWindowed, dwWidth, dwHeight, dwBPP ); + return false; + } + } + + LOG->WriteLine( "Mode change was successful." ); + + // Clear the back buffer and present it so we don't show the gibberish that was + // in video memory from the last app. + BeginFrame(); + EndFrame(); + ShowFrame(); + + + return true; +} + + +//----------------------------------------------------------------------------- +// Name: Reset() +// Desc: +//----------------------------------------------------------------------------- +HRESULT RageDisplay::Reset() +{ + return m_pd3dDevice->Reset( &m_d3dpp ); +} + + +//----------------------------------------------------------------------------- +// Name: BeginFrame() +// Desc: +//----------------------------------------------------------------------------- +HRESULT RageDisplay::BeginFrame() +{ + ////////////////////////////////////////////////////////////// + // Do some fancy testing to make sure the D3D deivce is ready. + // This is mainly used when the the app is reactivated + // after the user has Alt-tabed out of full screen mode. + ////////////////////////////////////////////////////////////// + + // Test cooperative level + HRESULT hr; + + // Test the cooperative level to see if it's okay to render + if( FAILED( hr = m_pd3dDevice->TestCooperativeLevel() ) ) + { + // If the device was lost, do not render until we get it back + if( D3DERR_DEVICELOST == hr ) + return hr; // not ready to render + + // Check if the device needs to be resized. + if( D3DERR_DEVICENOTRESET == hr ) + return hr; + + return hr; + } + + + m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, + D3DCOLOR_XRGB(0,0,0), 1.0f, 0x00000000 ); + + + if ( FAILED( hr = m_pd3dDevice->BeginScene() ) ) + return E_FAIL; + + // disable culling so backward polys can be drawn + m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); + m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); + + // Enable Alpha Blending and Testing + m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); + //m_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE ); + //m_pd3dDevice->SetRenderState( D3DRS_ALPHAREF, 0x08 ); + //m_pd3dDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL ); + + m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); + m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); + + m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); + m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE ); + + + m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR ); + m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR ); + + + // tile, don't crop texture coords + // m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_BORDER ); + // m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_BORDER ); + + + + return S_OK; +} + + +HRESULT RageDisplay::EndFrame() +{ + m_pd3dDevice->EndScene(); + + + // update stats + m_iFramesRenderedSinceLastCheck++; + + DWORD dwThisTicks = GetTickCount(); + if( dwThisTicks - m_dwLastUpdateTicks > 1000 ) // update stats every 1 sec. + { + m_fFPS = (float)m_iFramesRenderedSinceLastCheck; + m_iFramesRenderedSinceLastCheck = 0; + m_dwLastUpdateTicks = dwThisTicks; + + LOG->WriteLine( "FPS: %.0f", m_fFPS ); + } + + + return S_OK; +} + +HRESULT RageDisplay::ShowFrame() +{ + if( m_pd3dDevice ) + m_pd3dDevice->Present( 0, 0, 0, 0 ); + + return S_OK; +} + + + + +HRESULT RageDisplay::Invalidate() +{ + return S_OK; +} + + +HRESULT RageDisplay::Restore() +{ + + return S_OK; +} + + + + +void RageDisplay::CreateVertexBuffer() +{ + HRESULT hr; + if( FAILED( hr = GetDevice()->CreateVertexBuffer( + MAX_NUM_VERTICIES * sizeof(RAGEVERTEX), + D3DUSAGE_WRITEONLY, D3DFVF_RAGEVERTEX, + D3DPOOL_MANAGED, &m_pVB ) ) ) + FatalErrorHr( hr, "Vertex Buffer Could Not Be Created" ); +} + + +void RageDisplay::ReleaseVertexBuffer() +{ + SAFE_RELEASE( m_pVB ); +} + +void RageDisplay::CreateIndexBuffer() +{ + HRESULT hr; + if( FAILED( hr = GetDevice()->CreateIndexBuffer( + MAX_NUM_INDICIES, + D3DUSAGE_WRITEONLY, + D3DFMT_INDEX16, + D3DPOOL_MANAGED, + &m_pIB ) ) ) + FatalErrorHr( hr, "Index Buffer Could Not Be Created" ); +} + + +void RageDisplay::ReleaseIndexBuffer() +{ + SAFE_RELEASE( m_pIB ); +} + diff --git a/stepmania/src/RageDisplay.h b/stepmania/src/RageDisplay.h new file mode 100644 index 0000000000..96669be57f --- /dev/null +++ b/stepmania/src/RageDisplay.h @@ -0,0 +1,195 @@ +#pragma once +/* +----------------------------------------------------------------------------- + Class: RageDisplay + + Desc: Wrapper around a D3D device. Also holds global vertex and index + buffers that dynamic geometry can use to render. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +class RageDisplay; + + +#include "RageTexture.h" +#include + +// A structure for our custom vertex type. We added texture coordinates +struct RAGEVERTEX +{ + D3DXVECTOR3 p; // position + D3DCOLOR color; // diffuse color + D3DXVECTOR2 t; // texture coordinates +}; + +// Our custom FVF, which describes our custom vertex structure +#define D3DFVF_RAGEVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1) + + +const int MAX_NUM_QUADS = 1000; +const int MAX_NUM_INDICIES = MAX_NUM_QUADS*3; // two triangles per quad +const int MAX_NUM_VERTICIES = MAX_NUM_QUADS*4; // 4 verticies per quad + + + +class RageDisplay +{ +public: + RageDisplay( HWND hWnd ); + ~RageDisplay(); + bool SwitchDisplayMode( + const bool bWindowed, const DWORD dwWidth, const DWORD dwHeight, + const DWORD dwBPP, const DWORD dwFlags ); + + LPDIRECT3D8 GetD3D() { return m_pd3d; }; + inline LPDIRECT3DDEVICE8 GetDevice() { return m_pd3dDevice; }; + const D3DCAPS8& GetDeviceCaps() { return m_DeviceCaps; }; + + HRESULT Reset(); + HRESULT BeginFrame(); + HRESULT EndFrame(); + HRESULT ShowFrame(); + + HRESULT Invalidate(); + HRESULT Restore(); + + + BOOL IsWindowed() { return m_d3dpp.Windowed; }; + DWORD GetWidth() { return m_d3dpp.BackBufferWidth; }; + DWORD GetHeight() { return m_d3dpp.BackBufferHeight; }; + DWORD GetBPP() + { + switch( m_d3dpp.BackBufferFormat ) + { + case D3DFMT_R5G6B5: + case D3DFMT_X1R5G5B5: + case D3DFMT_A1R5G5B5: + return 16; + case D3DFMT_R8G8B8: + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: + return 32; + default: + ASSERT( false ); // unexpected format + return 0; + } + } + + + LPDIRECT3DVERTEXBUFFER8 GetVertexBuffer() { return m_pVB; }; + LPDIRECT3DINDEXBUFFER8 GetIndexBuffer() { return m_pIB; }; + + inline void ResetMatrixStack() + { + m_MatrixStack.SetSize( 1, 20 ); + D3DXMatrixIdentity( &GetTopMatrix() ); + + m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_MatrixStack[m_MatrixStack.GetSize()-1] ); + }; + inline void PushMatrix() + { + m_MatrixStack.Add( GetTopMatrix() ); + ASSERT(m_MatrixStack.GetSize()<30); // check for infinite loop + m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_MatrixStack[m_MatrixStack.GetSize()-1] ); + }; + inline void PopMatrix() + { + m_MatrixStack.RemoveAt( m_MatrixStack.GetSize()-1 ); + m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_MatrixStack[m_MatrixStack.GetSize()-1] ); + }; + inline void Translate( const float x, const float y, const float z ) + { + D3DXMATRIX matTemp; + D3DXMatrixTranslation( &matTemp, x, y, z ); + D3DXMATRIX& matTop = GetTopMatrix(); + matTop = matTemp * matTop; + m_pd3dDevice->SetTransform( D3DTS_WORLD, &matTop ); + }; + inline void TranslateLocal( const float x, const float y, const float z ) + { + D3DXMATRIX matTemp; + D3DXMatrixTranslation( &matTemp, x, y, z ); + D3DXMATRIX& matTop = GetTopMatrix(); + matTop = matTop * matTemp; + m_pd3dDevice->SetTransform( D3DTS_WORLD, &matTop ); + }; + inline void Scale( const float x, const float y, const float z ) + { + D3DXMATRIX matTemp; + D3DXMatrixScaling( &matTemp, x, y, z ); + D3DXMATRIX& matTop = GetTopMatrix(); + matTop = matTemp * matTop; + m_pd3dDevice->SetTransform( D3DTS_WORLD, &matTop ); + }; + inline void RotateX( const float r ) + { + D3DXMATRIX matTemp; + D3DXMatrixRotationX( &matTemp, r ); + D3DXMATRIX& matTop = GetTopMatrix(); + matTop = matTemp * matTop; + m_pd3dDevice->SetTransform( D3DTS_WORLD, &matTop ); + }; + inline void RotateY( const float r ) + { + D3DXMATRIX matTemp; + D3DXMatrixRotationY( &matTemp, r ); + D3DXMATRIX& matTop = GetTopMatrix(); + matTop = matTemp * matTop; + m_pd3dDevice->SetTransform( D3DTS_WORLD, &matTop ); + }; + inline void RotateZ( const float r ) + { + D3DXMATRIX matTemp; + D3DXMatrixRotationZ( &matTemp, r ); + D3DXMATRIX& matTop = GetTopMatrix(); + matTop = matTemp * matTop; + m_pd3dDevice->SetTransform( D3DTS_WORLD, &matTop ); + }; + inline void RotateYawPitchRoll( const float x, const float y, const float z ) + { + D3DXMATRIX matTemp; + D3DXMatrixRotationYawPitchRoll( &matTemp, x, y, z ); + D3DXMATRIX& matTop = GetTopMatrix(); + matTop = matTemp * matTop; + m_pd3dDevice->SetTransform( D3DTS_WORLD, &matTop ); + }; + + float GetFPS() { return m_fFPS; }; + +private: + D3DXMATRIX& GetTopMatrix() { return m_MatrixStack.ElementAt( m_MatrixStack.GetSize()-1 ); }; + + HWND m_hWnd; + + // DirectDraw/Direct3D objects + LPDIRECT3D8 m_pd3d; + LPDIRECT3DDEVICE8 m_pd3dDevice; + D3DCAPS8 m_DeviceCaps; + + + D3DDISPLAYMODE m_DesktopMode; + D3DPRESENT_PARAMETERS m_d3dpp; + + // a vertex buffer for all to share + LPDIRECT3DVERTEXBUFFER8 m_pVB; + void CreateVertexBuffer(); + void ReleaseVertexBuffer(); + + LPDIRECT3DINDEXBUFFER8 m_pIB; + void CreateIndexBuffer(); + void ReleaseIndexBuffer(); + + // OpenGL-like matrix stack + CArray m_MatrixStack; + + // for performance stats + DWORD m_dwLastUpdateTicks; + int m_iFramesRenderedSinceLastCheck; + float m_fFPS; +}; + + +extern RageDisplay* DISPLAY; // global and accessable from anywhere in our program diff --git a/stepmania/src/RageTextureManager.cpp b/stepmania/src/RageTextureManager.cpp index 7858bd7d0a..2c82804691 100644 --- a/stepmania/src/RageTextureManager.cpp +++ b/stepmania/src/RageTextureManager.cpp @@ -30,8 +30,8 @@ RageTextureManager::RageTextureManager( RageDisplay* pScreen ) { assert( pScreen != NULL ); m_pScreen = pScreen; - m_dwMaxTextureSize = 2048; // infinite size - m_dwTextureColorDepth = 16; + m_iMaxTextureSize = 2048; // infinite size + m_iTextureColorDepth = 16; } RageTextureManager::~RageTextureManager() @@ -73,7 +73,7 @@ RageTexture* RageTextureManager::LoadTexture( CString sTexturePath, bool bForceR { pTexture->m_iRefCount++; if( bForceReload ) - pTexture->Reload( m_dwMaxTextureSize, m_dwTextureColorDepth, iMipMaps, iAlphaBits, bDither ); + pTexture->Reload( m_iMaxTextureSize, m_iTextureColorDepth, iMipMaps, iAlphaBits, bDither ); LOG->WriteLine( "RageTextureManager: '%s' now has %d references.", sTexturePath, pTexture->m_iRefCount ); } @@ -83,9 +83,9 @@ RageTexture* RageTextureManager::LoadTexture( CString sTexturePath, bool bForceR splitpath( false, sTexturePath, sDrive, sDir, sFName, sExt ); if( sExt == "avi" || sExt == "mpg" || sExt == "mpeg" ) - pTexture = (RageTexture*) new RageMovieTexture( m_pScreen, sTexturePath, m_dwMaxTextureSize, m_dwTextureColorDepth, iMipMaps, iAlphaBits, bDither, bStretch ); + pTexture = (RageTexture*) new RageMovieTexture( m_pScreen, sTexturePath, m_iMaxTextureSize, m_iTextureColorDepth, iMipMaps, iAlphaBits, bDither, bStretch ); else - pTexture = (RageTexture*) new RageBitmapTexture( m_pScreen, sTexturePath, m_dwMaxTextureSize, m_dwTextureColorDepth, iMipMaps, iAlphaBits, bDither, bStretch ); + pTexture = (RageTexture*) new RageBitmapTexture( m_pScreen, sTexturePath, m_iMaxTextureSize, m_iTextureColorDepth, iMipMaps, iAlphaBits, bDither, bStretch ); LOG->WriteLine( "RageTextureManager: Finished loading '%s' - %d references.", sTexturePath, pTexture->m_iRefCount ); @@ -154,6 +154,6 @@ void RageTextureManager::ReloadAll() m_mapPathToTexture.GetNextAssoc( pos, sPath, pTexture ); - pTexture->Reload( m_dwMaxTextureSize, m_dwTextureColorDepth, 0 ); // this not entirely correct. Hints are lost! + pTexture->Reload( m_iMaxTextureSize, m_iTextureColorDepth, 0 ); // this not entirely correct. Hints are lost! } } \ No newline at end of file diff --git a/stepmania/src/RageTextureManager.h b/stepmania/src/RageTextureManager.h index 599ab02d66..cc76cabdb4 100644 --- a/stepmania/src/RageTextureManager.h +++ b/stepmania/src/RageTextureManager.h @@ -28,19 +28,19 @@ public: void SetPrefs( const DWORD dwMaxSize, const DWORD dwTextureColorDepth ) { - ASSERT( m_dwMaxTextureSize >= 64 ); - m_dwMaxTextureSize = dwMaxSize; - m_dwTextureColorDepth = dwTextureColorDepth; + ASSERT( m_iMaxTextureSize >= 64 ); + m_iMaxTextureSize = dwMaxSize; + m_iTextureColorDepth = dwTextureColorDepth; ReloadAll(); }; - DWORD GetMaxTextureSize() { return m_dwMaxTextureSize; }; - DWORD GetTextureColorDepth() { return m_dwTextureColorDepth; }; + DWORD GetMaxTextureSize() { return m_iMaxTextureSize; }; + DWORD GetTextureColorDepth() { return m_iTextureColorDepth; }; protected: RageDisplay* m_pScreen; - DWORD m_dwMaxTextureSize; - DWORD m_dwTextureColorDepth; + DWORD m_iMaxTextureSize; + DWORD m_iTextureColorDepth; // map from file name to a texture holder CTypedPtrMap m_mapPathToTexture; diff --git a/stepmania/src/Screen.cpp b/stepmania/src/Screen.cpp new file mode 100644 index 0000000000..0ca30cd673 --- /dev/null +++ b/stepmania/src/Screen.cpp @@ -0,0 +1,75 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + Class: Screen + + Desc: See header. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "Screen.h" + +Screen::Screen() +{ +} + +Screen::~Screen() +{ + +} + +void Screen::Update( float fDeltaTime ) +{ + ActorFrame::Update( fDeltaTime ); + + + // update the times of queued ScreenMessages and send if timer has expired + // The order you remove messages in must be very careful! Sending a message can + // potentially clear all m_QueuedMessages, and set a new state! + for( int i=0; iHandleScreenMessage( m_QueuedMessages[i].SM ); + m_QueuedMessages.RemoveAt( i ); + i--; + } + else + { + m_QueuedMessages[i].fDelayRemaining -= fDeltaTime; + } + } +} + +void Screen::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + // default input handler used by most menus + if( !MenuI.IsValid() ) + return; + if( type != IET_FIRST_PRESS ) + return; + + switch( MenuI.button ) + { + case MENU_BUTTON_UP: this->MenuUp( MenuI.player ); return; + case MENU_BUTTON_DOWN: this->MenuDown( MenuI.player ); return; + case MENU_BUTTON_LEFT: this->MenuLeft( MenuI.player ); return; + case MENU_BUTTON_RIGHT: this->MenuRight( MenuI.player ); return; + case MENU_BUTTON_BACK: this->MenuBack( MenuI.player ); return; + case MENU_BUTTON_START: this->MenuStart( MenuI.player ); return; + } +} + + +void Screen::SendScreenMessage( ScreenMessage SM, float fDelay ) +{ + assert( fDelay >= 0.0 ); + + QueuedScreenMessage QSM; + QSM.SM = SM; + QSM.fDelayRemaining = fDelay; + m_QueuedMessages.Add( QSM ); +} \ No newline at end of file diff --git a/stepmania/src/Screen.h b/stepmania/src/Screen.h new file mode 100644 index 0000000000..ce45e38a90 --- /dev/null +++ b/stepmania/src/Screen.h @@ -0,0 +1,61 @@ +#pragma once +/* +----------------------------------------------------------------------------- + Class: Screen + + Desc: Class representing a game state. It also holds Actors. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "RageInput.h" +#include "RageDisplay.h" +#include "PrefsManager.h" +#include "ActorFrame.h" +#include "ScreenMessage.h" +#include "InputFilter.h" +#include "GameInput.h" +#include "MenuInput.h" +#include "StyleInput.h" + + +class Screen : public ActorFrame +{ +public: + Screen(); + virtual ~Screen(); + + // let subclass override if they want + virtual void Restore() {}; + virtual void Invalidate() {}; + + virtual void Update( float fDeltaTime ); + virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + virtual void HandleScreenMessage( const ScreenMessage SM ) {}; + + void SendScreenMessage( const ScreenMessage SM, const float fDelay ); + void ClearMessageQueue() { m_QueuedMessages.SetSize(0,5); }; + +protected: + + // structure for holding messages sent to a Screen + struct QueuedScreenMessage { + ScreenMessage SM; + float fDelayRemaining; + }; + CArray m_QueuedMessages; + +public: + + // let subclass override if they want + virtual void MenuUp( PlayerNumber p ) {}; + virtual void MenuDown( PlayerNumber p ) {}; + virtual void MenuLeft( PlayerNumber p ) {}; + virtual void MenuRight( PlayerNumber p ){}; + virtual void MenuStart( PlayerNumber p ) {}; + virtual void MenuBack( PlayerNumber p ) {}; + + +}; diff --git a/stepmania/src/ScreenCaution.cpp b/stepmania/src/ScreenCaution.cpp new file mode 100644 index 0000000000..f194f6bb8d --- /dev/null +++ b/stepmania/src/ScreenCaution.cpp @@ -0,0 +1,68 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: ScreenCaution.h + +Desc: Screen that displays while resources are being loaded. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + + +#include "ScreenCaution.h" +#include "GameConstantsAndTypes.h" +#include "ScreenSelectStyle.h" +#include "RageTextureManager.h" +#include "ThemeManager.h" +#include "AnnouncerManager.h" + + +const ScreenMessage SM_DoneOpening = ScreenMessage(SM_User-7); +const ScreenMessage SM_StartClosing = ScreenMessage(SM_User-8); +const ScreenMessage SM_GoToSelectMusic = ScreenMessage(SM_User-9); + + +ScreenCaution::ScreenCaution() +{ + m_sprCaution.Load( THEME->GetPathTo(GRAPHIC_CAUTION) ); + m_sprCaution.StretchTo( CRect(0,0,640,480) ); + this->AddActor( &m_sprCaution ); + + m_Wipe.OpenWipingRight( SM_DoneOpening ); + this->AddActor( &m_Wipe ); + + this->SendScreenMessage( SM_StartClosing, 3 ); +} + + +void ScreenCaution::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + if( m_Wipe.IsClosing() ) + return; + + Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); +} + + +void ScreenCaution::HandleScreenMessage( const ScreenMessage SM ) +{ + switch( SM ) + { + case SM_StartClosing: + m_Wipe.CloseWipingRight( SM_GoToSelectMusic ); + break; + case SM_DoneOpening: + if( PREFS->m_GameOptions.m_bAnnouncer ) + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_CAUTION) ); + break; + case SM_GoToSelectMusic: + SCREENMAN->SetNewScreen( new ScreenSelectStyle ); + break; + } +} + +void ScreenCaution::MenuStart( PlayerNumber p ) +{ + m_Wipe.CloseWipingRight( SM_GoToSelectMusic ); +} diff --git a/stepmania/src/ScreenCaution.h b/stepmania/src/ScreenCaution.h new file mode 100644 index 0000000000..b967d8c5e7 --- /dev/null +++ b/stepmania/src/ScreenCaution.h @@ -0,0 +1,32 @@ +/* +----------------------------------------------------------------------------- + File: ScreenCaution.h + + Desc: Screen that displays while SelectSong is being loaded. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + + +#include "Screen.h" +#include "TransitionFade.h" +#include "RandomSample.h" + + +class ScreenCaution : public Screen +{ +public: + ScreenCaution(); + + virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + virtual void HandleScreenMessage( const ScreenMessage SM ); + + Sprite m_sprCaution; + + TransitionFade m_Wipe; + +protected: + void MenuStart( PlayerNumber p ); +}; + diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp new file mode 100644 index 0000000000..bf499582ec --- /dev/null +++ b/stepmania/src/ScreenEdit.cpp @@ -0,0 +1,663 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: ScreenEdit.h + + Desc: The music plays, the notes scroll, and the Player is pressing buttons. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "ScreenEdit.h" +#include "PrefsManager.h" +#include "SongManager.h" +#include "ScreenManager.h" +#include "ScreenSelectMusic.h" +#include "ScreenResults.h" +#include "GameConstantsAndTypes.h" +#include "ThemeManager.h" +#include "GameManager.h" +#include "ScreenEditMenu.h" +#include "GameConstantsAndTypes.h" +#include "RageLog.h" + + +// +// Defines specific to GameScreenTitleMenu +// + + +const float MAX_SECONDS_CAN_BE_OFF_BY = 0.20f; +const float GRAY_ARROW_Y = ARROW_SIZE * 1.5; + +const float DEBUG_X = SCREEN_LEFT + 10; +const float DEBUG_Y = CENTER_Y-100; + +const float EXPLANATION_X = SCREEN_LEFT + 10; +const float EXPLANATION_Y = SCREEN_BOTTOM - 10; // top aligned + +const float INFO_X = SCREEN_LEFT + 10; +const float INFO_Y = SCREEN_TOP + 10; // bottom aligned + +const float MENU_WIDTH = 110; +const float EDIT_CENTER_X = CENTER_X + 100; + +const float EDIT_GRAY_Y = CENTER_Y - 2.0f * (float)ARROW_SIZE; + +const ScreenMessage SM_GoToPrevState = ScreenMessage(SM_User+1); +const ScreenMessage SM_GoToNextState = ScreenMessage(SM_User+2); + + +ScreenEdit::ScreenEdit() +{ + LOG->WriteLine( "ScreenEdit::ScreenEdit()" ); + + m_pSong = SONGMAN->m_pCurSong; + + m_Mode = MODE_EDIT; + + m_fBeat = 0.0f; + m_fTrailingBeat = m_fBeat; + + m_PlayerOptions.m_fArrowScrollSpeed = 1; + m_PlayerOptions.m_ColorType = PlayerOptions::COLOR_NOTE; +// m_PlayerOptions.m_bShowMeasureBars = true; + + + m_sprBackground.Load( THEME->GetPathTo( GRAPHIC_EDIT_BACKGROUND ) ); + m_sprBackground.StretchTo( CRect(SCREEN_LEFT,SCREEN_TOP,SCREEN_RIGHT,SCREEN_BOTTOM) ); + + + m_GranularityIndicator.SetXY( EDIT_CENTER_X, EDIT_GRAY_Y ); + m_GranularityIndicator.Load(); + m_GranularityIndicator.SetZoom( 0.5f ); + + m_GrayArrowRowEdit.SetXY( EDIT_CENTER_X, EDIT_GRAY_Y ); + m_GrayArrowRowEdit.Load( m_PlayerOptions ); + m_GrayArrowRowEdit.SetZoom( 0.5f ); + + NoteData noteData; + noteData.m_iNumTracks = GAME->GetCurrentStyleDef()->m_iColsPerPlayer; + if( SONGMAN->m_pCurNotes[PLAYER_1] != NULL ) + noteData = *SONGMAN->m_pCurNotes[PLAYER_1]->GetNoteData(); + + m_NoteFieldEdit.SetXY( EDIT_CENTER_X, EDIT_GRAY_Y ); + m_NoteFieldEdit.SetZoom( 0.5f ); + m_NoteFieldEdit.Load( ¬eData, PLAYER_1, m_PlayerOptions, 10, 12, NoteField::MODE_EDITING ); + + m_rectRecordBack.StretchTo( CRect(SCREEN_LEFT, SCREEN_TOP, SCREEN_RIGHT, SCREEN_BOTTOM) ); + m_rectRecordBack.SetDiffuseColor( D3DXCOLOR(0,0,0,0) ); + + m_GrayArrowRowRecord.SetXY( EDIT_CENTER_X, EDIT_GRAY_Y ); + m_GrayArrowRowRecord.Load( m_PlayerOptions ); + m_GrayArrowRowRecord.SetZoom( 1.0f ); + + m_NoteFieldRecord.SetXY( EDIT_CENTER_X, EDIT_GRAY_Y ); + m_NoteFieldRecord.SetZoom( 1.0f ); + m_NoteFieldRecord.Load( ¬eData, PLAYER_1, m_PlayerOptions, 2, 5, NoteField::MODE_EDITING ); + + m_Player.Load( PLAYER_1, ¬eData, PlayerOptions(), NULL, NULL ); + m_Player.SetXY( EDIT_CENTER_X, EDIT_GRAY_Y ); + + m_Fade.SetClosed(); + + m_textExplanation.Load( THEME->GetPathTo(FONT_NORMAL) ); + m_textExplanation.SetXY( EXPLANATION_X, EXPLANATION_Y ); + m_textExplanation.SetHorizAlign( Actor::align_left ); + m_textExplanation.SetVertAlign( Actor::align_top ); + m_textExplanation.SetZoom( 0.5f ); + m_textExplanation.SetShadowLength( 2 ); + m_textExplanation.SetText( + "Up,Down: change beat\n" + "PgUp,PgDn: jump 1 measure\n" + "Left,Right: change snap\n" + "Number keys: add/remove\n" + " tap step\n" + "S: save\n" + "Escape: exit\n" + "To create a hold note,\n" + " keep number key\n" + " depressed while\n" + " pressing Up/Down\n" + "Snap marked area to:\n" + " Z: quarters\n" + " X: eighths\n" + " C: triplets\n" + " V: sixteenths\n" + " B: nearest 16th or triplet\n" + "P: Play back marked area\n" + "R: Record marked area\n" + ); + + + m_textInfo.Load( THEME->GetPathTo(FONT_NORMAL) ); + m_textInfo.SetXY( INFO_X, INFO_Y ); + m_textInfo.SetHorizAlign( Actor::align_left ); + m_textInfo.SetVertAlign( Actor::align_bottom ); + m_textInfo.SetZoom( 0.5f ); + //m_textInfo.SetText(); // set this below every frame + + + m_soundChangeLine.Load( THEME->GetPathTo(SOUND_EDIT_CHANGE_LINE) ); + m_soundChangeSnap.Load( THEME->GetPathTo(SOUND_EDIT_CHANGE_SNAP) ); + m_soundMarker.Load( THEME->GetPathTo(SOUND_EDIT_CHANGE_SNAP) ); + m_soundInvalid.Load( THEME->GetPathTo(SOUND_INVALID) ); + + m_soundMusic.Load( m_pSong->GetMusicPath() ); + m_soundMusic.SetPlaybackRate( 0.5f ); + + + m_Fade.OpenWipingRight(); +} + +ScreenEdit::~ScreenEdit() +{ + LOG->WriteLine( "ScreenEdit::~ScreenEdit()" ); + m_soundMusic.Stop(); +} + + +void ScreenEdit::Update( float fDeltaTime ) +{ + float fSongBeat, fBPS; + float fPositionSeconds = m_soundMusic.GetPositionSeconds(); + m_pSong->GetBeatAndBPSFromElapsedTime( fPositionSeconds, fSongBeat, fBPS ); + + if( m_Mode == MODE_RECORD || m_Mode == MODE_PLAY ) + { + m_fBeat = fSongBeat; + + if( m_fBeat > m_NoteFieldEdit.m_fEndMarker ) + { + if( m_Mode == MODE_RECORD ) + { + TransitionToEditFromRecord(); + } + else if( m_Mode == MODE_PLAY ) + { + m_soundMusic.Stop(); + m_Mode = MODE_EDIT; + } + } + } + + m_sprBackground.Update( fDeltaTime ); + m_GranularityIndicator.Update( fDeltaTime ); + m_GrayArrowRowEdit.Update( fDeltaTime, m_fBeat ); + m_NoteFieldEdit.Update( fDeltaTime, m_fBeat ); + m_Fade.Update( fDeltaTime ); + m_textExplanation.Update( fDeltaTime ); + m_textInfo.Update( fDeltaTime ); + + if( m_Mode == MODE_RECORD || m_Mode == MODE_PLAY ) + { + m_rectRecordBack.Update( fDeltaTime ); + } + + if( m_Mode == MODE_RECORD ) + { + m_GrayArrowRowRecord.Update( fDeltaTime, m_fBeat ); + m_NoteFieldRecord.Update( fDeltaTime, m_fBeat ); + } + + if( m_Mode == MODE_PLAY ) + { + m_Player.Update( fDeltaTime, m_fBeat, 0.35f ); + } + + //LOG->WriteLine( "ScreenEdit::Update(%f)", fDeltaTime ); + Screen::Update( fDeltaTime ); + + if( m_fTrailingBeat != m_fBeat ) + { + float fOffset = m_fBeat-m_fTrailingBeat; + float fSign = fOffset/fabsf(fOffset); + + float fBeatsToMove = fDeltaTime * 20; + + if( fabsf(fBeatsToMove) > 2 ) + m_fTrailingBeat = m_fBeat; + else if( fabsf(fOffset) < fBeatsToMove ) + m_fTrailingBeat = m_fBeat; + else + m_fTrailingBeat += fBeatsToMove * fSign; + } + +// float fSongBeat, fBPS; +/// float fPositionSeconds = m_soundMusic.GetPositionSeconds(); + +// fPositionSeconds += 0.08f; // HACK: The assist ticks are playing too late, so make them play a tiny bit earlier +// m_pSong->GetBeatAndBPSFromElapsedTime( fPositionSeconds, fSongBeat, fBPS ); +// LOG->WriteLine( "fPositionSeconds = %f, fSongBeat = %f, fBPS = %f", fPositionSeconds, fSongBeat, fBPS ); + + + m_NoteFieldEdit.Update( fDeltaTime, m_fTrailingBeat ); + + int iIndexNow = BeatToNoteIndexNotRounded( m_fBeat ); + + + CString sNoteType; + switch( m_GranularityIndicator.GetSnapMode() ) + { + case NOTE_4TH: sNoteType = "quarter notes"; break; + case NOTE_8TH: sNoteType = "eighth notes"; break; + case NOTE_12TH: sNoteType = "triplets"; break; + case NOTE_16TH: sNoteType = "sixteenth notes"; break; + default: ASSERT( false ); + } + + m_textInfo.SetText( + ssprintf( + "Beat = %f\n" + "Begin Marker = beat %f\n" + "End Marker = beat %f\n" + "Difficulty = %s\n" + "Snap = %s", + m_fBeat, + m_NoteFieldEdit.m_fBeginMarker, + m_NoteFieldEdit.m_fEndMarker, + "not yet implemented", + sNoteType + ) + ); +} + + +void ScreenEdit::DrawPrimitives() +{ + m_sprBackground.Draw(); + m_GranularityIndicator.Draw(); + m_GrayArrowRowEdit.Draw(); + m_NoteFieldEdit.Draw(); + m_Fade.Draw(); + m_textExplanation.Draw(); + m_textInfo.Draw(); + + if( m_Mode == MODE_RECORD || m_Mode == MODE_PLAY ) + { + m_rectRecordBack.Draw(); + } + + if( m_Mode == MODE_RECORD ) + { + m_GrayArrowRowRecord.Draw(); + m_NoteFieldRecord.Draw(); + } + + if( m_Mode == MODE_PLAY ) + { + m_Player.Draw(); + } + + Screen::DrawPrimitives(); +} + +void ScreenEdit::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + //LOG->WriteLine( "ScreenEdit::Input()" ); + + switch( m_Mode ) + { + case MODE_EDIT: InputEdit( DeviceI, type, GameI, MenuI, StyleI ); break; + case MODE_RECORD: InputRecord( DeviceI, type, GameI, MenuI, StyleI ); break; + case MODE_PLAY: InputPlay( DeviceI, type, GameI, MenuI, StyleI ); break; + } +} + +void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + /////////////////////////// + // handle pad inputs + /////////////////////////// + + if( DeviceI.device == DEVICE_KEYBOARD ) + { + switch( DeviceI.button ) + { + case DIK_1: + case DIK_2: + case DIK_3: + case DIK_4: + case DIK_5: + case DIK_6: + case DIK_7: + case DIK_8: + case DIK_9: + { + if( type != IET_FIRST_PRESS ) + break; // We only care about first presses + + int iCol = DeviceI.button - DIK_1; + const int iNoteIndex = BeatToNoteRow( m_fBeat ); + + if( iCol >= m_NoteFieldEdit.m_iNumTracks ) // this button is not in the range of columns for this StyleDef + break; + + // check for to see if the user intended to remove a HoldNote + bool bRemovedAHoldNote = false; + for( int i=0; i= hn.m_iStartIndex && iNoteIndex <= hn.m_iEndIndex ) // the cursor lies within this HoldNote + { + m_NoteFieldEdit.RemoveHoldNote( i ); + bRemovedAHoldNote = true; + break; // stop iterating over all HoldNotes + } + } + + if( !bRemovedAHoldNote ) + { + // We didn't remove a HoldNote, so the user wants to add or delete a TapNote + if( m_NoteFieldEdit.m_TapNotes[iCol][iNoteIndex] == '0' ) + m_NoteFieldEdit.m_TapNotes[iCol][iNoteIndex] = '1'; + else + m_NoteFieldEdit.m_TapNotes[iCol][iNoteIndex] = '0'; + } + } + break; + case DIK_ESCAPE: + SCREENMAN->SetNewScreen( new ScreenEditMenu ); + break; + case DIK_S: + // copy edit into current Notes + Notes* pNotes; + pNotes = SONGMAN->m_pCurNotes[PLAYER_1]; + + if( pNotes == NULL ) + { + // allocate a new Notes + SONGMAN->m_pCurSong->m_arrayNotes.SetSize( SONGMAN->m_pCurSong->m_arrayNotes.GetSize() + 1 ); + pNotes = &SONGMAN->m_pCurSong->m_arrayNotes[ SONGMAN->m_pCurSong->m_arrayNotes.GetSize()-1 ]; + pNotes->m_sIntendedGame = GAME->m_sCurrentGame; + pNotes->m_sIntendedStyle = GAME->m_sCurrentStyle; + pNotes->m_sDescription = "Untitled Edit"; + pNotes->m_iMeter = 1; + } + + pNotes->SetNoteData( (NoteData*)&m_NoteFieldEdit ); + SONGMAN->m_pCurSong->Save(); + break; + case DIK_UP: + case DIK_DOWN: + case DIK_PGUP: + case DIK_PGDN: + { + float fBeatsToMove; + switch( DeviceI.button ) + { + case DIK_UP: + case DIK_DOWN: + fBeatsToMove = NoteTypeToBeat( m_GranularityIndicator.GetSnapMode() ); + if( DeviceI.button == DIK_UP ) + fBeatsToMove *= -1; + break; + case DIK_PGUP: + case DIK_PGDN: + fBeatsToMove = BEATS_PER_MEASURE; + if( DeviceI.button == DIK_PGUP ) + fBeatsToMove *= -1; + } + + const int iStartIndex = BeatToNoteRow(m_fBeat); + const int iEndIndex = BeatToNoteRow(m_fBeat + fBeatsToMove); + + // check to see if they're holding a button + for( int col=0; colIsBeingPressed(di); + + if( bIsBeingHeld ) + { + // create a new hold note + HoldNote newHN; + newHN.m_iTrack = col; + newHN.m_iStartIndex = min(iStartIndex, iEndIndex); + newHN.m_iEndIndex = max(iStartIndex, iEndIndex); + m_NoteFieldEdit.AddHoldNote( newHN ); + } + } + + m_fBeat += fBeatsToMove; + m_fBeat = clamp( m_fBeat, 0, MAX_BEATS-1 ); + m_soundChangeLine.PlayRandom(); + } + break; + case DIK_RIGHT: + m_GranularityIndicator.PrevSnapMode(); + OnSnapModeChange(); + break; + case DIK_LEFT: + m_GranularityIndicator.NextSnapMode(); + OnSnapModeChange(); + break; + case DIK_HOME: + if( m_NoteFieldEdit.m_fEndMarker != -1 && m_fBeat > m_NoteFieldEdit.m_fEndMarker ) + { + // invalid! The begin maker must be placed before the end marker + m_soundInvalid.PlayRandom(); + } + else + { + m_NoteFieldEdit.m_fBeginMarker = m_fBeat; + m_soundMarker.PlayRandom(); + } + break; + case DIK_END: + if( m_NoteFieldEdit.m_fBeginMarker != -1 && m_fBeat < m_NoteFieldEdit.m_fBeginMarker ) + { + // invalid! The end maker must be placed after the begin marker + m_soundInvalid.PlayRandom(); + } + else + { + m_NoteFieldEdit.m_fEndMarker = m_fBeat; + m_soundMarker.PlayRandom(); + } + break; + case DIK_Z: + case DIK_X: + case DIK_C: + case DIK_V: + case DIK_B: + { + + if( m_NoteFieldEdit.m_fBeginMarker == -1 || m_NoteFieldEdit.m_fEndMarker == -1 ) + { + m_soundInvalid.PlayRandom(); + } + else + { + NoteType noteType1; + NoteType noteType2; + switch( DeviceI.button ) + { + case DIK_Z: noteType1 = NOTE_4TH; noteType2 = NOTE_4TH; break; + case DIK_X: noteType1 = NOTE_8TH; noteType2 = NOTE_8TH; break; + case DIK_C: noteType1 = NOTE_12TH; noteType2 = NOTE_12TH; break; + case DIK_V: noteType1 = NOTE_16TH; noteType2 = NOTE_16TH; break; + case DIK_B: noteType1 = NOTE_12TH; noteType2 = NOTE_16TH; break; + default: ASSERT( false ); + } + + m_NoteFieldEdit.SnapToNearestNoteType( noteType1, noteType2, m_NoteFieldEdit.m_fBeginMarker, m_NoteFieldEdit.m_fEndMarker ); + } + + } + break; + case DIK_P: + { + if( m_NoteFieldEdit.m_fBeginMarker == -1 || m_NoteFieldEdit.m_fEndMarker == -1 ) + { + m_soundInvalid.PlayRandom(); + break; + } + + m_fBeat = m_NoteFieldEdit.m_fBeginMarker; + + m_Mode = MODE_PLAY; + + m_Player.Load( PLAYER_1, (NoteData*)&m_NoteFieldEdit, PlayerOptions(), NULL, NULL ); + + m_rectRecordBack.BeginTweening( 0.5f ); + m_rectRecordBack.SetTweenDiffuseColor( D3DXCOLOR(0,0,0,0.5f) ); + + float fElapsedSeconds = max( 0, m_pSong->GetElapsedTimeFromBeat(m_fBeat) ); + m_soundMusic.SetPositionSeconds( fElapsedSeconds ); + m_soundMusic.Play(); + m_soundMusic.SetPlaybackRate( 1.0f ); + } + break; + case DIK_R: + if( m_NoteFieldEdit.m_fBeginMarker == -1 || m_NoteFieldEdit.m_fEndMarker == -1 ) + { + m_soundInvalid.PlayRandom(); + break; + } + + m_fBeat = m_NoteFieldEdit.m_fBeginMarker; + + // initialize m_NoteFieldRecord + m_NoteFieldRecord.ClearAll(); + m_NoteFieldRecord.m_iNumTracks = m_NoteFieldEdit.m_iNumTracks; + m_NoteFieldRecord.m_fBeginMarker = m_NoteFieldEdit.m_fBeginMarker; + m_NoteFieldRecord.m_fEndMarker = m_NoteFieldEdit.m_fEndMarker; + + + m_Mode = MODE_RECORD; + m_rectRecordBack.BeginTweening( 0.5f ); + m_rectRecordBack.SetTweenDiffuseColor( D3DXCOLOR(0,0,0,0.5f) ); + + float fElapsedSeconds = max( 0, m_pSong->GetElapsedTimeFromBeat(m_fBeat) ); + m_soundMusic.SetPositionSeconds( fElapsedSeconds ); + m_soundMusic.Play(); + m_soundMusic.SetPlaybackRate( 0.5f ); + break; + } + } +} + +void ScreenEdit::InputRecord( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + if( DeviceI.device == DEVICE_KEYBOARD ) + { + switch( DeviceI.button ) + { + case DIK_ESCAPE: + TransitionToEditFromRecord(); + break; + } + } + switch( StyleI.player ) + { + case PLAYER_1: + int iCol; + iCol = StyleI.col; + + int iNoteIndex; + iNoteIndex = BeatToNoteRow( m_fBeat ); + + if( type == IET_FIRST_PRESS ) + { + m_NoteFieldRecord.m_TapNotes[iCol][iNoteIndex] = '1'; + m_NoteFieldRecord.SnapToNearestNoteType( NOTE_12TH, NOTE_16TH, max(0,m_fBeat-1), m_fBeat+1); + m_GrayArrowRowRecord.Step( iCol ); + } + else + { + const float fHoldEndSeconds = m_soundMusic.GetPositionSeconds(); + const float fHoldStartSeconds = m_soundMusic.GetPositionSeconds() - TIME_BEFORE_SLOW_REPEATS * m_soundMusic.GetPlaybackRate(); + + float fStartBeat, fEndBeat, fThrowAway; + m_pSong->GetBeatAndBPSFromElapsedTime( fHoldStartSeconds, fStartBeat, fThrowAway ); + m_pSong->GetBeatAndBPSFromElapsedTime( fHoldEndSeconds, fEndBeat, fThrowAway ); + + const int iStartIndex = BeatToNoteRow(fStartBeat) - 1; + const int iEndIndex = BeatToNoteRow(fEndBeat); + + // create a new hold note + HoldNote newHN; + newHN.m_iTrack = iCol; + newHN.m_iStartIndex = iStartIndex; + newHN.m_iEndIndex = iEndIndex; + + m_NoteFieldRecord.AddHoldNote( newHN ); + m_NoteFieldRecord.SnapToNearestNoteType( NOTE_12TH, NOTE_16TH, max(0,m_fBeat-2), m_fBeat+2); + } + break; + } +} + +void ScreenEdit::InputPlay( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + if( type != IET_FIRST_PRESS ) + return; + + if( DeviceI.device == DEVICE_KEYBOARD ) + { + switch( DeviceI.button ) + { + case DIK_ESCAPE: + m_Mode = MODE_EDIT; + m_soundMusic.Stop(); + + m_fBeat = froundf( m_fBeat, NoteTypeToBeat(m_GranularityIndicator.GetSnapMode()) ); + break; + } + } + + switch( StyleI.player ) + { + case PLAYER_1: + m_Player.HandlePlayerStep( m_fBeat, StyleI.col, 0.35f ); + return; + } + +} + + +void ScreenEdit::TransitionToEditFromRecord() +{ + m_Mode = MODE_EDIT; + m_soundMusic.Stop(); + + int iNoteIndexBegin = BeatToNoteRow( m_NoteFieldEdit.m_fBeginMarker ); + int iNoteIndexEnd = BeatToNoteRow( m_NoteFieldEdit.m_fEndMarker ); + + // delete old TapNotes in the range + m_NoteFieldEdit.ClearRange( iNoteIndexBegin, iNoteIndexEnd ); + + m_NoteFieldEdit.CopyRange( (NoteData*)&m_NoteFieldRecord, iNoteIndexBegin, iNoteIndexEnd ); + + m_fBeat = froundf( m_fBeat, NoteTypeToBeat(m_GranularityIndicator.GetSnapMode()) ); +} + + +void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) +{ + switch( SM ) + { + case SM_GoToPrevState: + SCREENMAN->SetNewScreen( new ScreenEditMenu ); + break; + case SM_GoToNextState: + SCREENMAN->SetNewScreen( new ScreenEditMenu ); + break; + } + + +} + +void ScreenEdit::OnSnapModeChange() +{ + m_soundChangeSnap.PlayRandom(); + + NoteType nt = m_GranularityIndicator.GetSnapMode(); + int iStepIndex = BeatToNoteRow( m_fBeat ); + int iElementsPerNoteType = BeatToNoteRow( NoteTypeToBeat(nt) ); + int iStepIndexHangover = iStepIndex % iElementsPerNoteType; + m_fBeat -= NoteRowToBeat( iStepIndexHangover ); +} diff --git a/stepmania/src/ScreenEdit.h b/stepmania/src/ScreenEdit.h new file mode 100644 index 0000000000..2de6143c05 --- /dev/null +++ b/stepmania/src/ScreenEdit.h @@ -0,0 +1,88 @@ +/* +----------------------------------------------------------------------------- + File: ScreenEdit.h + + Desc: The music plays, the notes scroll, and the Player is pressing buttons. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "Screen.h" +#include "Sprite.h" +#include "TransitionFade.h" +#include "BitmapText.h" +#include "Player.h" +#include "RandomSample.h" +#include "FocusingSprite.h" +#include "RageMusic.h" +#include "MotionBlurSprite.h" +#include "Background.h" +#include "GranularityIndicator.h" + + +class ScreenEdit : public Screen +{ +public: + ScreenEdit(); + virtual ~ScreenEdit(); + virtual void Update( float fDeltaTime ); + virtual void DrawPrimitives(); + virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + void InputEdit( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + void InputRecord( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + void InputPlay( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + virtual void HandleScreenMessage( const ScreenMessage SM ); + void TransitionToEditFromRecord(); + + +protected: + void OnSnapModeChange(); + + + enum EditMode { MODE_EDIT, MODE_RECORD, MODE_PLAY }; + EditMode m_Mode; + + Song* m_pSong; + + PlayerOptions m_PlayerOptions; + + Sprite m_sprBackground; + + NoteField m_NoteFieldEdit; + GranularityIndicator m_GranularityIndicator; + GrayArrowRow m_GrayArrowRowEdit; + + BitmapText m_textExplanation; + BitmapText m_textInfo; // status information that changes + + // keep track of where we are and what we're doing + float m_fTrailingBeat; // this approaches m_fBeat + float m_fBeat; + + + RandomSample m_soundChangeLine; + RandomSample m_soundChangeSnap; + RandomSample m_soundMarker; + RandomSample m_soundInvalid; + + TransitionFade m_Fade; + + +// for MODE_RECORD + + Quad m_rectRecordBack; + NoteField m_NoteFieldRecord; + GrayArrowRow m_GrayArrowRowRecord; + +// for MODE_PLAY + + Player m_Player; + +// for MODE_RECORD and MODE_PLAY + + RageSoundStream m_soundMusic; +}; + + + diff --git a/stepmania/src/ScreenEditMenu.cpp b/stepmania/src/ScreenEditMenu.cpp new file mode 100644 index 0000000000..da4a140e5f --- /dev/null +++ b/stepmania/src/ScreenEditMenu.cpp @@ -0,0 +1,337 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: ScreenEditMenu.h + + Desc: The main title screen and menu. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "ScreenEditMenu.h" +#include "SongManager.h" +#include "ScreenManager.h" +#include "ScreenTitleMenu.h" +#include "ScreenEdit.h" +#include "GameConstantsAndTypes.h" +#include "RageUtil.h" +#include "ThemeManager.h" +#include "GameManager.h" +#include "ScreenPrompt.h" +#include "RageLog.h" + + +// +// Defines specific to ScreenEditMenu +// +const float LINE_START_Y = CENTER_Y-150; +const float LINE_GAP = 50; + +const float GROUP_X = CENTER_X; +const float GROUP_Y = LINE_START_Y + LINE_GAP; + +const float SONG_X = CENTER_X; +const float SONG_Y = GROUP_Y + LINE_GAP; + +const float GAME_STYLE_X = CENTER_X; +const float GAME_STYLE_Y = SONG_Y + LINE_GAP; + +const float STEPS_X = CENTER_X; +const float STEPS_Y = GAME_STYLE_Y + LINE_GAP; + +const float EXPLANATION_X = CENTER_X; +const float EXPLANATION_Y = STEPS_Y + LINE_GAP*2; + + +const ScreenMessage SM_GoToPrevState = ScreenMessage(SM_User+1); +const ScreenMessage SM_GoToNextState = ScreenMessage(SM_User+2); + + +ScreenEditMenu::ScreenEditMenu() +{ + LOG->WriteLine( "ScreenEditMenu::ScreenEditMenu()" ); + + + // data structures + m_SelectedRow = ROW_GROUP; + + SONGMAN->GetGroupNames( m_sGroups ); + m_iSelectedGroup = 0; + m_iSelectedSong = 0; + m_iSelectedStyle = 0; + m_iSelectedNotes = 0; + + m_textGroup.Load( THEME->GetPathTo(FONT_HEADER1) ); + m_textGroup.SetXY( GROUP_X, GROUP_Y ); + m_textGroup.SetDiffuseColor( D3DXCOLOR(0.7f,0.7f,0.7f,1) ); + this->AddActor( &m_textGroup ); + + m_textSong.Load( THEME->GetPathTo(FONT_HEADER1) ); + m_textSong.SetXY( SONG_X, SONG_Y ); + m_textSong.SetDiffuseColor( D3DXCOLOR(0.7f,0.7f,0.7f,1) ); + this->AddActor( &m_textSong ); + + m_textStyle.Load( THEME->GetPathTo(FONT_HEADER1) ); + m_textStyle.SetXY( GAME_STYLE_X, GAME_STYLE_Y ); + m_textStyle.SetDiffuseColor( D3DXCOLOR(0.7f,0.7f,0.7f,1) ); + this->AddActor( &m_textStyle ); + + m_textNotes.Load( THEME->GetPathTo(FONT_HEADER1) ); + m_textNotes.SetXY( STEPS_X, STEPS_Y ); + m_textNotes.SetDiffuseColor( D3DXCOLOR(0.7f,0.7f,0.7f,1) ); + this->AddActor( &m_textNotes ); + + + AfterRowChange(); + OnGroupChange(); + + + m_textExplanation.Load( THEME->GetPathTo(FONT_NORMAL) ); + m_textExplanation.SetXY( EXPLANATION_X, EXPLANATION_Y ); + m_textExplanation.SetText( ssprintf("This mode will allow you to\nedit an existing or\n create a new Notes Notes.") ); + m_textExplanation.SetZoom( 0.7f ); + this->AddActor( &m_textExplanation ); + + m_Menu.Load( + THEME->GetPathTo(GRAPHIC_EDIT_BACKGROUND), + THEME->GetPathTo(GRAPHIC_SELECT_MUSIC_TOP_EDGE), + ssprintf("%s %s change music NEXT to continue", CString(char(1)), CString(char(2)) ) + ); + this->AddActor( &m_Menu ); + + + m_Fade.SetOpened(); + this->AddActor( &m_Fade); + + + m_soundChangeMusic.Load( THEME->GetPathTo(SOUND_SWITCH_MUSIC) ); + m_soundSelect.Load( THEME->GetPathTo(SOUND_SELECT) ); + + MUSIC->Load( THEME->GetPathTo(SOUND_MENU_MUSIC) ); + MUSIC->Play( true ); + + + m_Menu.TweenAllOnScreen(); +} + + +ScreenEditMenu::~ScreenEditMenu() +{ + LOG->WriteLine( "ScreenEditMenu::~ScreenEditMenu()" ); +} + +void ScreenEditMenu::DrawPrimitives() +{ + m_Menu.DrawBottomLayer(); + Screen::DrawPrimitives(); + m_Menu.DrawTopLayer(); +} + +void ScreenEditMenu::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + LOG->WriteLine( "ScreenEditMenu::Input()" ); + + + Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); +} + +void ScreenEditMenu::HandleScreenMessage( const ScreenMessage SM ) +{ + switch( SM ) + { + case SM_GoToPrevState: + SCREENMAN->SetNewScreen( new ScreenTitleMenu ); + break; + case SM_GoToNextState: + SCREENMAN->SetNewScreen( new ScreenEdit ); + break; + } +} + +void ScreenEditMenu::BeforeRowChange() +{ + m_textGroup.SetEffectNone(); + m_textSong.SetEffectNone(); + m_textStyle.SetEffectNone(); + m_textNotes.SetEffectNone(); +} + +void ScreenEditMenu::AfterRowChange() +{ + switch( m_SelectedRow ) + { + case ROW_GROUP: m_textGroup.SetEffectGlowing(); break; + case ROW_SONG: m_textSong.SetEffectGlowing(); break; + case ROW_GAME_MODE: m_textStyle.SetEffectGlowing(); break; + case ROW_STEPS: m_textNotes.SetEffectGlowing(); break; + default: ASSERT(false); + } +} + +void ScreenEditMenu::OnGroupChange() +{ + m_iSelectedGroup = clamp( m_iSelectedGroup, 0, m_sGroups.GetSize()-1 ); + + m_textGroup.SetText( GetSelectedGroup() ); + + // reload songs + m_pSongs.RemoveAll(); + SONGMAN->GetSongsInGroup( GetSelectedGroup(), m_pSongs ); + + OnSongChange(); +} + +void ScreenEditMenu::OnSongChange() +{ + m_iSelectedSong = clamp( m_iSelectedSong, 0, m_pSongs.GetSize()-1 ); + + m_textSong.SetText( GetSelectedSong()->GetMainTitle() ); + + m_sStyles.RemoveAll(); + m_sStyles.Add( "single" ); + m_sStyles.Add( "versus" ); + m_sStyles.Add( "double" ); + m_sStyles.Add( "couple" ); + m_sStyles.Add( "solo" ); + + OnDanceStyleChange(); +} + +void ScreenEditMenu::OnDanceStyleChange() +{ + m_iSelectedStyle = clamp( m_iSelectedStyle, 0, m_sStyles.GetSize()-1 ); + + m_textStyle.SetText( GetSelectedStyle() ); + + m_pNotess.RemoveAll(); + GetSelectedSong()->GetNotessThatMatchGameAndStyle( "dance", GetSelectedStyle(), m_pNotess ); + SortNotesArrayByDifficultyClass( m_pNotess ); + m_pNotess.Add( NULL ); // marker for "(NEW)" + m_iSelectedNotes = 0; + + + OnStepsChange(); +} + +void ScreenEditMenu::OnStepsChange() +{ + m_iSelectedNotes = clamp( m_iSelectedNotes, 0, m_pNotess.GetSize()-1 ); + + if( GetSelectedNotes() == NULL ) + m_textNotes.SetText( "(NEW)" ); + else + m_textNotes.SetText( GetSelectedNotes()->m_sDescription ); + +} + +void ScreenEditMenu::MenuUp( PlayerNumber p ) +{ + if( m_SelectedRow == 0 ) // can't go up any further + return; + + BeforeRowChange(); + m_SelectedRow = SelectedRow(m_SelectedRow-1); + AfterRowChange(); +} + +void ScreenEditMenu::MenuDown( PlayerNumber p ) +{ + if( m_SelectedRow == NUM_ROWS-1 ) // can't go down any further + return; + + BeforeRowChange(); + m_SelectedRow = SelectedRow(m_SelectedRow+1); + AfterRowChange(); +} + +void ScreenEditMenu::MenuLeft( PlayerNumber p ) +{ + switch( m_SelectedRow ) + { + case ROW_GROUP: + if( m_iSelectedGroup == 0 ) // can't go left any further + return; + m_iSelectedGroup--; + OnGroupChange(); + break; + case ROW_SONG: + if( m_iSelectedSong == 0 ) // can't go left any further + return; + m_iSelectedSong--; + OnSongChange(); + break; + case ROW_GAME_MODE: + if( m_iSelectedStyle == 0 ) // can't go left any further + return; + m_iSelectedStyle--; + OnDanceStyleChange(); + break; + case ROW_STEPS: + if( m_iSelectedNotes == 0 ) // can't go left any further + return; + m_iSelectedNotes--; + OnStepsChange(); + break; + default: + ASSERT(false); + } +} + +void ScreenEditMenu::MenuRight( PlayerNumber p ) +{ + switch( m_SelectedRow ) + { + case ROW_GROUP: + if( m_iSelectedGroup == m_sGroups.GetSize()-1 ) // can't go right any further + return; + m_iSelectedGroup++; + OnGroupChange(); + break; + case ROW_SONG: + if( m_iSelectedSong == m_pSongs.GetSize()-1 ) // can't go right any further + return; + m_iSelectedSong++; + OnSongChange(); + break; + case ROW_GAME_MODE: + if( m_iSelectedStyle == m_sStyles.GetSize()-1 ) // can't go right any further + return; + m_iSelectedStyle++; + OnDanceStyleChange(); + break; + case ROW_STEPS: + if( m_iSelectedNotes == m_pNotess.GetSize()-1 ) // can't go right any further + return; + m_iSelectedNotes++; + OnStepsChange(); + break; + default: + ASSERT(false); + } +} + +void ScreenEditMenu::MenuStart( PlayerNumber p ) +{ + m_Menu.TweenAllOffScreen(); + + MUSIC->Stop(); + + SONGMAN->m_pCurSong = GetSelectedSong(); + GAME->m_sCurrentStyle = GetSelectedStyle(); + SONGMAN->m_pCurNotes[PLAYER_1] = GetSelectedNotes(); + + m_soundSelect.PlayRandom(); + + m_Fade.CloseWipingRight( SM_GoToNextState ); +} + +void ScreenEditMenu::MenuBack( PlayerNumber p ) +{ + m_Menu.TweenAllOffScreen(); + + + MUSIC->Stop(); + + m_Fade.CloseWipingLeft( SM_GoToPrevState ); +} diff --git a/stepmania/src/ScreenEditMenu.h b/stepmania/src/ScreenEditMenu.h new file mode 100644 index 0000000000..7417fcab5f --- /dev/null +++ b/stepmania/src/ScreenEditMenu.h @@ -0,0 +1,89 @@ +/* +----------------------------------------------------------------------------- + File: ScreenEditMenu.h + + Desc: The main title screen and menu. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "Screen.h" +#include "Sprite.h" +#include "ColorNote.h" +#include "BitmapText.h" +#include "TransitionFade.h" +#include "RandomSample.h" +#include "Banner.h" +#include "TextBanner.h" +#include "RandomSample.h" +#include "TransitionInvisible.h" +#include "MenuElements.h" + + + +class ScreenEditMenu : public Screen +{ +public: + ScreenEditMenu(); + virtual ~ScreenEditMenu(); + + virtual void DrawPrimitives(); + virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + virtual void HandleScreenMessage( const ScreenMessage SM ); + +private: + void BeforeRowChange(); + void AfterRowChange(); + + void OnGroupChange(); + void OnSongChange(); + void OnDanceStyleChange(); + void OnStepsChange(); + + CString GetSelectedGroup() { return m_sGroups[m_iSelectedGroup]; }; + Song* GetSelectedSong() { return m_pSongs[m_iSelectedSong]; }; + CString GetSelectedStyle() { return m_sStyles[m_iSelectedStyle]; }; + Notes* GetSelectedNotes() { return m_pNotess[m_iSelectedNotes]; }; + + void MenuUp( PlayerNumber p ); + void MenuDown( PlayerNumber p ); + void MenuLeft( PlayerNumber p ); + void MenuRight( PlayerNumber p ); + void MenuBack( PlayerNumber p ); + void MenuStart( PlayerNumber p ); + + + enum SelectedRow { ROW_GROUP, ROW_SONG, ROW_GAME_MODE, ROW_STEPS, NUM_ROWS }; + SelectedRow m_SelectedRow; + + MenuElements m_Menu; + + CStringArray m_sGroups; + int m_iSelectedGroup; // index into m_sGroups + BitmapText m_textGroup; + + CArray m_pSongs; + int m_iSelectedSong; // index into m_pSongs + BitmapText m_textSong; + + CStringArray m_sStyles; + int m_iSelectedStyle; // index into enum GameMode + BitmapText m_textStyle; + + CArray m_pNotess; + int m_iSelectedNotes; // index into m_pNotess + BitmapText m_textNotes; + + + BitmapText m_textExplanation; + + TransitionFade m_Fade; + + RandomSample m_soundChangeMusic; + RandomSample m_soundSelect; + +}; + + + diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp new file mode 100644 index 0000000000..27db72a99e --- /dev/null +++ b/stepmania/src/ScreenGameplay.cpp @@ -0,0 +1,528 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + Class: ScreenGameplay + + Desc: See header. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "ScreenGameplay.h" +#include "SongManager.h" +#include "ScreenManager.h" + +#include "ScreenSelectMusic.h" +#include "ScreenResults.h" +#include "GameConstantsAndTypes.h" +#include "ThemeManager.h" +#include "GameManager.h" +#include "SongManager.h" +#include "RageLog.h" +#include "AnnouncerManager.h" + +// +// Defines specific to GameScreenTitleMenu +// + +const float COLUMN_LEFT_SINGLE = (SCREEN_WIDTH*1/4); +const float COLUMN_RIGHT_SINGLE = (SCREEN_WIDTH*3/4); +const float COLUMN_LEFT_DOUBLE = (COLUMN_LEFT_SINGLE+30); +const float COLUMN_RIGHT_DOUBLE = (COLUMN_RIGHT_SINGLE-30); + +const float LIFE_X[NUM_PLAYERS] = { CENTER_X-180, CENTER_X+180 }; +const float LIFE_Y = SCREEN_TOP+28; + +const float SCORE_X[NUM_PLAYERS] = { CENTER_X-214, CENTER_X+214 }; +const float SCORE_Y = SCREEN_BOTTOM-38; + +const float MAX_SECONDS_CAN_BE_OFF_BY = 0.20f; + +const float TIME_BETWEEN_DANCING_COMMENTS = 15; + + +// received while STATE_DANCING +const ScreenMessage SM_SongEnded = ScreenMessage(SM_User+102); +const ScreenMessage SM_LifeIs0 = ScreenMessage(SM_User+103); + + +// received while STATE_OUTRO +const ScreenMessage SM_ShowCleared = ScreenMessage(SM_User+111); +const ScreenMessage SM_HideCleared = ScreenMessage(SM_User+112); +const ScreenMessage SM_GoToResults = ScreenMessage(SM_User+113); + +const ScreenMessage SM_BeginFailed = ScreenMessage(SM_User+121); +const ScreenMessage SM_ShowFailed = ScreenMessage(SM_User+122); +const ScreenMessage SM_PlayFailComment = ScreenMessage(SM_User+123); +const ScreenMessage SM_HideFailed = ScreenMessage(SM_User+124); +const ScreenMessage SM_GoToSelectSong = ScreenMessage(SM_User+125); + + + +ScreenGameplay::ScreenGameplay() +{ + LOG->WriteLine( "ScreenGameplay::ScreenGameplay()" ); + + m_DancingState = STATE_INTRO; + m_fTimeLeftBeforeDancingComment = TIME_BETWEEN_DANCING_COMMENTS; + + m_bHasFailed = false; + m_pSong = SONGMAN->m_pCurSong; + + + + // Get the current StyleDef definition (used below) + StyleDef* pStyleDef = GAME->GetCurrentStyleDef(); + + for( int p=0; pIsPlayerEnabled(PlayerNumber(p)) ) + continue; + + NoteData* pOriginalNoteData = SONGMAN->m_pCurNotes[p]->GetNoteData(); + + NoteData newNoteData; + GAME->GetCurrentStyleDef()->GetTransformedNoteDataForStyle( (PlayerNumber)p, pOriginalNoteData, newNoteData ); + + m_Player[p].Load( + (PlayerNumber)p, + &newNoteData, + PREFS->m_PlayerOptions[p], + &m_LifeMeter[p], + &m_ScoreDisplay[p] + ); + + } + + + m_Background.LoadFromSong( SONGMAN->m_pCurSong ); + m_Background.SetDiffuseColor( D3DXCOLOR(0.4f,0.4f,0.4f,1) ); + this->AddActor( &m_Background ); + + + + + // init players + if( GAME->m_sCurrentStyle == "single" ) + { + m_Player[PLAYER_1].SetX( COLUMN_LEFT_SINGLE ); + this->AddActor( &m_Player[PLAYER_1] ); + } + else if( GAME->m_sCurrentStyle == "versus" || GAME->m_sCurrentStyle == "couple" ) + { + m_Player[PLAYER_1].SetX( COLUMN_LEFT_SINGLE ); + this->AddActor( &m_Player[PLAYER_1] ); + m_Player[PLAYER_2].SetX( COLUMN_RIGHT_SINGLE ); + this->AddActor( &m_Player[PLAYER_2] ); + } + else if( GAME->m_sCurrentStyle == "double" || GAME->m_sCurrentStyle == "solo" ) + { + m_Player[PLAYER_1].SetX( CENTER_X ); + this->AddActor( &m_Player[PLAYER_1] ); + } + else + ASSERT( false ); // invalid style + + + + for( p=0; pIsPlayerEnabled(PlayerNumber(p)) ) + continue; + + m_LifeMeter[p].SetPlayerOptions( PREFS->m_PlayerOptions[p] ); + m_LifeMeter[p].SetXY( LIFE_X[p], LIFE_Y ); + m_LifeMeter[p].SetZoomX( 256 ); + m_LifeMeter[p].SetZoomY( 20 ); + this->AddActor( &m_LifeMeter[p] ); + } + + m_sprTopFrame.Load( THEME->GetPathTo(GRAPHIC_GAMEPLAY_TOP_FRAME) ); + m_sprTopFrame.SetXY( CENTER_X, SCREEN_TOP + m_sprTopFrame.GetZoomedHeight()/2 ); + this->AddActor( &m_sprTopFrame ); + + m_sprBottomFrame.Load( THEME->GetPathTo(GRAPHIC_GAMEPLAY_BOTTOM_FRAME) ); + m_sprBottomFrame.SetXY( CENTER_X, SCREEN_BOTTOM - m_sprBottomFrame.GetZoomedHeight()/2 ); + this->AddActor( &m_sprBottomFrame ); + + m_textSmallStage.Load( THEME->GetPathTo(FONT_HEADER1) ); + m_textSmallStage.TurnShadowOff(); + m_textSmallStage.SetXY( CENTER_X, 60 ); + m_textSmallStage.SetDiffuseColor( D3DXCOLOR(0.3f,1,1,1) ); + m_textSmallStage.SetText( PREFS->GetStageText() ); + this->AddActor( &m_textSmallStage ); + + + for( p=0; pIsPlayerEnabled(PlayerNumber(p)) ) + continue; + + m_ScoreDisplay[p].SetXY( SCORE_X[p], SCORE_Y ); + m_ScoreDisplay[p].SetZoom( 0.8f ); + this->AddActor( &m_ScoreDisplay[p] ); + } + + + + + + m_StarWipe.SetClosed(); + this->AddActor( &m_StarWipe ); + + m_sprReady.Load( THEME->GetPathTo(GRAPHIC_GAMEPLAY_READY) ); + m_sprReady.SetXY( CENTER_X, CENTER_Y ); + m_sprReady.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); + this->AddActor( &m_sprReady ); + + m_sprHereWeGo.Load( THEME->GetPathTo(GRAPHIC_GAMEPLAY_HERE_WE_GO) ); + m_sprHereWeGo.SetXY( CENTER_X, CENTER_Y ); + m_sprHereWeGo.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); + this->AddActor( &m_sprHereWeGo ); + + m_sprCleared.Load( THEME->GetPathTo(GRAPHIC_GAMEPLAY_CLEARED) ); + m_sprCleared.SetXY( CENTER_X, CENTER_Y ); + m_sprCleared.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); + this->AddActor( &m_sprCleared ); + + m_sprFailed.Load( THEME->GetPathTo(GRAPHIC_GAMEPLAY_FAILED) ); + m_sprFailed.SetXY( CENTER_X, CENTER_Y ); + m_sprFailed.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); + this->AddActor( &m_sprFailed ); + + + m_soundMusic.Load( m_pSong->GetMusicPath() ); + + m_soundFail.Load( THEME->GetPathTo(SOUND_FAILED) ); + m_announcerReady.Load( ANNOUNCER->GetPathTo(ANNOUNCER_GAMEPLAY_READY) ); + m_announcerHereWeGo.Load( ANNOUNCER->GetPathTo(ANNOUNCER_GAMEPLAY_HERE_WE_GO_NORMAL) ); + m_announcerGood.Load( ANNOUNCER->GetPathTo(ANNOUNCER_GAMEPLAY_COMMENT_GOOD) ); + m_announcerBad.Load( ANNOUNCER->GetPathTo(ANNOUNCER_GAMEPLAY_COMMENT_BAD) ); + m_announcerCleared.Load( ANNOUNCER->GetPathTo(ANNOUNCER_GAMEPLAY_CLEARED) ); + m_announcerFailComment.Load(ANNOUNCER->GetPathTo(ANNOUNCER_GAMEPLAY_FAILED) ); + + m_soundAssistTick.Load( THEME->GetPathTo(SOUND_ASSIST) ); + + + + // Send some messages every have second to we can get the introduction rolling + for( int i=0; i<30; i++ ) + this->SendScreenMessage( ScreenMessage(SM_User+i), i/2.0f ); + + + + m_StarWipe.SetClosed(); +} + +ScreenGameplay::~ScreenGameplay() +{ + LOG->WriteLine( "ScreenGameplay::~ScreenGameplay()" ); + m_soundMusic.Stop(); +} + + +void ScreenGameplay::Update( float fDeltaTime ) +{ + //LOG->WriteLine( "ScreenGameplay::Update(%f)", fDeltaTime ); + Screen::Update( fDeltaTime ); + + + float fSongBeat, fBPS; + float fPositionSeconds = m_soundMusic.GetPositionSeconds(); + + m_pSong->GetBeatAndBPSFromElapsedTime( fPositionSeconds, fSongBeat, fBPS ); + + + + + //LOG->WriteLine( "m_fOffsetInBeats = %f, m_fBeatsPerSecond = %f, m_Music.GetPositionSeconds = %f", m_fOffsetInBeats, m_fBeatsPerSecond, m_Music.GetPositionSeconds() ); + + float fMaxBeatDifference = fBPS*MAX_SECONDS_CAN_BE_OFF_BY; + + for( int p=0; pIsPlayerEnabled(PlayerNumber(p)) ) + continue; + m_Player[p].Update( fDeltaTime, fSongBeat, fMaxBeatDifference ); + } + + // check for fail + switch( PREFS->m_SongOptions.m_FailType ) + { + case SongOptions::FAIL_ARCADE: + case SongOptions::FAIL_END_OF_SONG: + + if( m_bHasFailed ) + break; // if they have already failed, don't bother checking again + + { + // check for both players fail + bool bAllAboutToFail = true; + bool bAllFailed = true; + for( int p=0; pIsPlayerEnabled(PlayerNumber(p)) ) + continue; + + const float fLifePercentage = m_LifeMeter[p].GetLifePercentage(); + + if( fLifePercentage > 0.3f ) + { + bAllAboutToFail = false; + bAllFailed = false; + } + else if( fLifePercentage > 0.0f ) // dead. Let the message handler choose to fail or not + { + bAllFailed = false; + } + break; + } + if( bAllAboutToFail ) m_Background.TurnDangerOn(); + else m_Background.TurnDangerOff(); + + if( bAllFailed ) + { + m_bHasFailed = true; + SCREENMAN->SendMessageToTopScreen( SM_LifeIs0, 0 ); + } + } + break; + case SongOptions::FAIL_OFF: + break; + } + + + switch( m_DancingState ) + { + case STATE_DANCING: + + // Check for end of song + if( m_DancingState == STATE_DANCING && + m_soundMusic.GetLengthSeconds() - m_soundMusic.GetPositionSeconds() < 2 ) + this->SendScreenMessage( SM_SongEnded, 1 ); + + // Check to see if it's time to play a gameplay comment + if( PREFS->m_GameOptions.m_bAnnouncer ) + { + m_fTimeLeftBeforeDancingComment -= fDeltaTime; + if( m_fTimeLeftBeforeDancingComment <= 0 ) + { + m_fTimeLeftBeforeDancingComment = TIME_BETWEEN_DANCING_COMMENTS; // reset for the next comment + + if( m_Background.IsDangerOn() ) + m_announcerBad.PlayRandom(); + else + m_announcerGood.PlayRandom(); + } + } + } + + + + + if( PREFS->m_SongOptions.m_AssistType == SongOptions::ASSIST_TICK ) + { + // + // play assist ticks + // + // Sound cards have a latency between when a sample is Play()ed and when the sound + // will start coming out the speaker. Compensate for this by boosting + // fPositionSeconds ahead + fPositionSeconds += (SOUND->GetPlayLatency()+0.06f) * m_soundMusic.GetPlaybackRate(); // HACK: Add 0.06 seconds to make them play a tiny bit earlier + m_pSong->GetBeatAndBPSFromElapsedTime( fPositionSeconds, fSongBeat, fBPS ); + + int iIndexNow = BeatToNoteIndexNotRounded( fSongBeat ); + static int iIndexLastCrossed = 0; + + bool bAnyoneHasANote = false; // set this to true if any player has a note at one of the indicies we crossed + + for( int i=iIndexLastCrossed+1; i<=iIndexNow; i++ ) // for each index we crossed since the last update + { + for( int p=0; pIsPlayerEnabled( (PlayerNumber)p ) ) + continue; // skip + + bAnyoneHasANote |= m_Player[p].IsThereANoteAtIndex( i ); + } + } + + if( bAnyoneHasANote ) + m_soundAssistTick.PlayRandom(); + + + iIndexLastCrossed = iIndexNow; + } + +} + + +void ScreenGameplay::DrawPrimitives() +{ + Screen::DrawPrimitives(); +} + + +void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + //LOG->WriteLine( "ScreenGameplay::Input()" ); + + float fSongBeat, fBPS; + m_pSong->GetBeatAndBPSFromElapsedTime( m_soundMusic.GetPositionSeconds(), fSongBeat, fBPS ); + + + if( MenuI.IsValid() ) + { + switch( MenuI.button ) + { + case MENU_BUTTON_BACK: + if( m_DancingState == STATE_DANCING + && !m_bHasFailed ) + { + m_bHasFailed = true; + SCREENMAN->SendMessageToTopScreen( SM_BeginFailed, 0 ); + } + else + ; // do not let user go back! + break; + } + } + + float fMaxBeatsCanBeOffBy = MAX_SECONDS_CAN_BE_OFF_BY * fBPS; + + if( type == IET_FIRST_PRESS ) + { + if( StyleI.IsValid() ) + { + m_Player[StyleI.player].HandlePlayerStep( fSongBeat, StyleI.col, fMaxBeatsCanBeOffBy ); + } + } +} + +void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) +{ + switch( SM ) + { + // received while STATE_INTRO + case SM_User+0: + m_StarWipe.OpenWipingRight(SM_None); + break; + case SM_User+1: + break; + case SM_User+2: + m_sprReady.StartFocusing(); + if( PREFS->m_GameOptions.m_bAnnouncer ) + m_announcerReady.PlayRandom(); + break; + case SM_User+3: + break; + case SM_User+4: + m_sprReady.StartBlurring(); + break; + case SM_User+5: + m_sprHereWeGo.StartFocusing(); + if( PREFS->m_GameOptions.m_bAnnouncer ) + m_announcerHereWeGo.PlayRandom(); + m_Background.SetDiffuseColor( D3DXCOLOR(0.8f,0.8f,0.8f,1) ); + m_soundMusic.Play(); + m_soundMusic.SetPlaybackRate( PREFS->m_SongOptions.m_fMusicRate ); + break; + case SM_User+6: + break; + case SM_User+7: + break; + case SM_User+8: + m_sprHereWeGo.StartBlurring(); + m_DancingState = STATE_DANCING; // STATE CHANGE! Now the user is allowed to press Back + break; + case SM_User+9: + break; + + // received while STATE_DANCING + case SM_LifeIs0: + if( PREFS->m_SongOptions.m_FailType == SongOptions::FAIL_ARCADE ) // fail them now! + this->SendScreenMessage( SM_BeginFailed, 0 ); + m_DancingState = STATE_OUTRO; + break; + case SM_SongEnded: + if( m_DancingState == STATE_OUTRO ) // gameplay already ended + return; // ignore + + if( m_bHasFailed ) // fail them + { + this->SendScreenMessage( SM_BeginFailed, 0 ); + } + else // cleared + { + m_StarWipe.CloseWipingRight( SM_ShowCleared ); + if( PREFS->m_GameOptions.m_bAnnouncer ) + m_announcerCleared.PlayRandom(); // crowd cheer + } + m_DancingState = STATE_OUTRO; + break; + + // received while STATE_OUTRO + case SM_ShowCleared: + m_sprCleared.StartFocusing(); + SCREENMAN->SendMessageToTopScreen( SM_HideCleared, 2.5 ); + break; + case SM_HideCleared: + m_sprCleared.StartBlurring(); + SCREENMAN->SendMessageToTopScreen( SM_GoToResults, 1 ); + break; + case SM_GoToResults: + // send score summaries to the PREFS object so ScreenResults can grab it. + PREFS->m_ScoreSummary[PLAYER_1] = m_Player[PLAYER_1].GetScoreSummary(); + PREFS->m_ScoreSummary[PLAYER_2] = m_Player[PLAYER_2].GetScoreSummary(); + SCREENMAN->SetNewScreen( new ScreenResults ); + break; + + + case SM_BeginFailed: + m_DancingState = STATE_OUTRO; + m_soundMusic.Pause(); + m_StarWipe.CloseWipingRight( SM_None ); + this->SendScreenMessage( SM_ShowFailed, 0.2f ); + break; + case SM_ShowFailed: + if( PREFS->m_GameOptions.m_bAnnouncer ) + m_soundFail.PlayRandom(); + + // make the background invisible so we don't waste mem bandwidth drawing it + m_Background.BeginTweening( 1 ); + m_Background.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) ); + + m_sprFailed.SetZoom( 4 ); + m_sprFailed.BeginBlurredTweening( 0.8f, TWEEN_BIAS_END ); + m_sprFailed.SetTweenZoom( 0.5f ); // zoom out + m_sprFailed.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0.7f) ); // and fade in + m_sprFailed.BeginTweeningQueued( 0.3f ); + m_sprFailed.SetTweenZoom( 1.1f ); // bounce + m_sprFailed.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0.7f) ); // and fade in + m_sprFailed.BeginTweeningQueued( 0.2f ); + m_sprFailed.SetTweenZoom( 1.0f ); // come to rest + m_sprFailed.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0.7f) ); // and fade in + + SCREENMAN->SendMessageToTopScreen( SM_PlayFailComment, 1.5f ); + SCREENMAN->SendMessageToTopScreen( SM_HideFailed, 3.0f ); + break; + case SM_PlayFailComment: + if( PREFS->m_GameOptions.m_bAnnouncer ) + m_announcerFailComment.PlayRandom(); + break; + case SM_HideFailed: + m_sprFailed.StopTweening(); + m_sprFailed.BeginTweening(1.0f); + m_sprFailed.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) ); + + SCREENMAN->SendMessageToTopScreen( SM_GoToSelectSong, 1.5f ); + break; + case SM_GoToSelectSong: + SCREENMAN->SetNewScreen( new ScreenSelectMusic ); + break; + } + + +} diff --git a/stepmania/src/ScreenGameplay.h b/stepmania/src/ScreenGameplay.h new file mode 100644 index 0000000000..db5b75e11b --- /dev/null +++ b/stepmania/src/ScreenGameplay.h @@ -0,0 +1,93 @@ +/* +----------------------------------------------------------------------------- + Class: ScreenGameplay + + Desc: The music plays, the notes scroll, and the Player is pressing buttons. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "Screen.h" +#include "Sprite.h" +#include "TransitionStarWipe.h" +#include "TransitionFade.h" +#include "BitmapText.h" +#include "Player.h" +#include "RandomSample.h" +#include "RandomStream.h" +#include "FocusingSprite.h" +#include "RageMusic.h" +#include "MotionBlurSprite.h" +#include "Background.h" +#include "LifeMeterBar.h" +#include "ScoreDisplayRolling.h" + + +class ScreenGameplay : public Screen +{ +public: + ScreenGameplay(); + virtual ~ScreenGameplay(); + virtual void Update( float fDeltaTime ); + virtual void DrawPrimitives(); + virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + virtual void HandleScreenMessage( const ScreenMessage SM ); + + enum DancingState { + STATE_INTRO = 0, // not allowed to press Back + STATE_DANCING, + STATE_OUTRO, // not allowed to press Back + NUM_DANCING_STATES + }; + + +private: + + DancingState m_DancingState; + + float m_fTimeLeftBeforeDancingComment; // this counter is only running while STATE_DANCING + + Song* m_pSong; + bool m_bHasFailed; + + Background m_Background; + + LifeMeterBar m_LifeMeter[NUM_PLAYERS]; + + Sprite m_sprTopFrame; + Sprite m_sprBottomFrame; + + ScoreDisplayRolling m_ScoreDisplay[NUM_PLAYERS]; + + + BitmapText m_textSmallStage; + + TransitionStarWipe m_StarWipe; + + FocusingSprite m_sprReady; + FocusingSprite m_sprHereWeGo; + FocusingSprite m_sprCleared; + MotionBlurSprite m_sprFailed; + + Player m_Player[NUM_PLAYERS]; + + RandomSample m_soundFail; + RandomSample m_announcerReady; + RandomSample m_announcerHereWeGo; + RandomSample m_announcerGood; // these are samples because we play them often + RandomSample m_announcerBad; // these are samples because we play them often + RandomStream m_announcerCleared; + RandomStream m_announcerFailComment; + RandomStream m_announcerGameOver; + + RandomSample m_soundAssistTick; + + RageSoundStream m_soundMusic; + + +}; + + + diff --git a/stepmania/src/ScreenGraphicOptions.cpp b/stepmania/src/ScreenGraphicOptions.cpp new file mode 100644 index 0000000000..9cf1376af9 --- /dev/null +++ b/stepmania/src/ScreenGraphicOptions.cpp @@ -0,0 +1,161 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: ScreenGraphicOptions.cpp + + Desc: Select a song. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "ScreenGraphicOptions.h" +#include +#include "RageTextureManager.h" +#include "RageUtil.h" +#include "RageMusic.h" +#include "ScreenManager.h" +#include "PrefsManager.h" +#include "ScreenOptions.h" +#include "ScreenTitleMenu.h" +#include "GameConstantsAndTypes.h" +#include "StepMania.h" +#include "ThemeManager.h" +#include "RageLog.h" + + +enum { + GO_WINDOWED = 0, + GO_PROFILE, + GO_RESOLUTION, + GO_TEXTURE_SIZE, + GO_DISPLAY_COLOR, + GO_TEXTURE_COLOR, + GO_BACKGROUNDS, + NUM_GRAPHIC_OPTIONS_LINES +}; +OptionLineData g_GraphicOptionsLines[NUM_GRAPHIC_OPTIONS_LINES] = { + { "Mode", 2, {"Fullscreen", "Windowed"} }, + { "Profile", 5, {"Super Low", "Low", "Medium", "High", "Custom (use settings below)"} }, + { "Resolution", 7, {"320", "400", "512", "640", "800", "1024", "1280" } }, + { "Tex. Size", 4, {"256", "512", "1024", "2048"} }, + { "Display", 2, {"16bit", "32bit"} }, + { "Tex. Color", 2, {"16bit", "32bit"} }, +}; + +//const int NUm_SelectedOption_LINES = sizeof(g_GraphicOptionsLines)/sizeof(OptionLine); + +ScreenGraphicOptions::ScreenGraphicOptions() : + ScreenOptions( + THEME->GetPathTo(GRAPHIC_GRAPHIC_OPTIONS_BACKGROUND), + THEME->GetPathTo(GRAPHIC_GRAPHIC_OPTIONS_TOP_EDGE) + ) +{ + LOG->WriteLine( "ScreenGraphicOptions::ScreenGraphicOptions()" ); + + Init( + INPUTMODE_BOTH, + g_GraphicOptionsLines, + NUM_GRAPHIC_OPTIONS_LINES + ); +} + +void ScreenGraphicOptions::ImportOptions() +{ + GraphicProfileOptions* pGPO = PREFS->GetCustomGraphicProfileOptions(); + + m_iSelectedOption[0][GO_WINDOWED] = (PREFS->m_bWindowed ? 1:0 ); + m_iSelectedOption[0][GO_PROFILE] = PREFS->m_GraphicProfile; + + switch( pGPO->m_iWidth ) + { + case 320: m_iSelectedOption[0][GO_RESOLUTION] = 0; break; + case 400: m_iSelectedOption[0][GO_RESOLUTION] = 1; break; + case 512: m_iSelectedOption[0][GO_RESOLUTION] = 2; break; + case 640: m_iSelectedOption[0][GO_RESOLUTION] = 3; break; + case 800: m_iSelectedOption[0][GO_RESOLUTION] = 4; break; + case 1024: m_iSelectedOption[0][GO_RESOLUTION] = 5; break; + case 1280: m_iSelectedOption[0][GO_RESOLUTION] = 6; break; + default: m_iSelectedOption[0][GO_RESOLUTION] = 3; break; + } + switch( pGPO->m_iMaxTextureSize ) + { + case 256: m_iSelectedOption[0][GO_TEXTURE_SIZE] = 0; break; + case 512: m_iSelectedOption[0][GO_TEXTURE_SIZE] = 1; break; + case 1024: m_iSelectedOption[0][GO_TEXTURE_SIZE] = 2; break; + case 2048: m_iSelectedOption[0][GO_TEXTURE_SIZE] = 3; break; + default: m_iSelectedOption[0][GO_TEXTURE_SIZE] = 1; break; + } + switch( pGPO->m_iDisplayColor ) + { + case 16: m_iSelectedOption[0][GO_DISPLAY_COLOR] = 0; break; + case 32: m_iSelectedOption[0][GO_DISPLAY_COLOR] = 1; break; + } + switch( pGPO->m_iTextureColor ) + { + case 16: m_iSelectedOption[0][GO_TEXTURE_COLOR] = 0; break; + case 32: m_iSelectedOption[0][GO_TEXTURE_COLOR] = 1; break; + } +} + +void ScreenGraphicOptions::ExportOptions() +{ + GraphicProfileOptions* pGPO = PREFS->GetCustomGraphicProfileOptions(); + + PREFS->m_bWindowed = (m_iSelectedOption[0][GO_WINDOWED] == 1); + PREFS->m_GraphicProfile = (GraphicProfile)m_iSelectedOption[0][GO_PROFILE]; + + switch( m_iSelectedOption[0][GO_RESOLUTION] ) + { + case 0: pGPO->m_iWidth = 320; break; + case 1: pGPO->m_iWidth = 400; break; + case 2: pGPO->m_iWidth = 512; break; + case 3: pGPO->m_iWidth = 640; break; + case 4: pGPO->m_iWidth = 800; break; + case 5: pGPO->m_iWidth = 1024; break; + case 6: pGPO->m_iWidth = 1280; break; + default: ASSERT( false ); + } + pGPO->m_iHeight = GetHeightFromWidth( pGPO->m_iWidth ); + + switch( m_iSelectedOption[0][GO_TEXTURE_SIZE] ) + { + case 0: pGPO->m_iMaxTextureSize = 256; break; + case 1: pGPO->m_iMaxTextureSize = 512; break; + case 2: pGPO->m_iMaxTextureSize = 1024; break; + case 3: pGPO->m_iMaxTextureSize = 2048; break; + default: ASSERT( false ); + } + switch( m_iSelectedOption[0][GO_DISPLAY_COLOR] ) + { + case 0: pGPO->m_iDisplayColor = 16; break; + case 1: pGPO->m_iDisplayColor = 32; break; + default: ASSERT( false ); + } + switch( m_iSelectedOption[0][GO_TEXTURE_COLOR] ) + { + case 0: pGPO->m_iTextureColor = 16; break; + case 1: pGPO->m_iTextureColor = 32; break; + default: ASSERT( false ); + } + + // + // put the options into effect + // + ApplyGraphicOptions(); +} + +void ScreenGraphicOptions::GoToPrevState() +{ + SCREENMAN->SetNewScreen( new ScreenTitleMenu ); +} + +void ScreenGraphicOptions::GoToNextState() +{ + SCREENMAN->SetNewScreen( new ScreenTitleMenu ); +} + + + + + diff --git a/stepmania/src/ScreenGraphicOptions.h b/stepmania/src/ScreenGraphicOptions.h new file mode 100644 index 0000000000..3017bbcb68 --- /dev/null +++ b/stepmania/src/ScreenGraphicOptions.h @@ -0,0 +1,31 @@ +/* +----------------------------------------------------------------------------- + File: ScreenGraphicOptions.h + + Desc: Select a song. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "Screen.h" +#include "ScreenOptions.h" +#include "Sprite.h" +#include "BitmapText.h" +#include "RandomSample.h" +#include "TransitionFade.h" +#include "Quad.h" + + +class ScreenGraphicOptions : public ScreenOptions +{ +public: + ScreenGraphicOptions(); + +private: + void ImportOptions(); + void ExportOptions(); + + void GoToNextState(); + void GoToPrevState(); +}; diff --git a/stepmania/src/ScreenManager.cpp b/stepmania/src/ScreenManager.cpp new file mode 100644 index 0000000000..c61f66fec1 --- /dev/null +++ b/stepmania/src/ScreenManager.cpp @@ -0,0 +1,164 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: ScreenManager.h + + Desc: Manages the game windows. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "ScreenManager.h" +#include "IniFile.h" +#include "GameConstantsAndTypes.h" +#include "ThemeManager.h" +#include "RageLog.h" + + +ScreenManager* SCREENMAN = NULL; // global and accessable from anywhere in our program + + + +ScreenManager::ScreenManager() +{ + m_textFPS.Load( THEME->GetPathTo(FONT_NORMAL) ); + m_textFPS.SetXY( SCREEN_WIDTH-35, 15 ); + m_textFPS.SetZ( -2 ); + m_textFPS.SetZoom( 0.5f ); + m_textFPS.SetShadowLength( 2 ); + + m_textSystemMessage.Load( THEME->GetPathTo(FONT_NORMAL) ); + m_textSystemMessage.SetHorizAlign( Actor::align_left ); + m_textSystemMessage.SetVertAlign( Actor::align_bottom ); + m_textSystemMessage.SetXY( 5.0f, 10.0f ); + m_textSystemMessage.SetZ( -2 ); + m_textSystemMessage.SetZoom( 0.5f ); + m_textSystemMessage.SetShadowLength( 2 ); + m_textSystemMessage.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); +} + + +ScreenManager::~ScreenManager() +{ + LOG->WriteLine( "ScreenManager::~ScreenManager()" ); + + // delete current states + for( int i=0; i0 ) return; + + // Update all windows in the stack + for( i=0; iUpdate( fDeltaTime ); + +} + + +void ScreenManager::Restore() +{ + // Draw all CurrentScreens (back to front) + for( int i=0; iRestore(); +} + +void ScreenManager::Invalidate() +{ + for( int i=0; iInvalidate(); +} + +void ScreenManager::Draw() +{ + // Draw all CurrentScreens (back to front) + for( int i=0; iDraw(); + + if( m_textSystemMessage.GetDiffuseColor().a != 0 ) + m_textSystemMessage.Draw(); + + if( PREFS && PREFS->m_GameOptions.m_bShowFPS ) + { + m_textFPS.SetText( ssprintf("%3.0f FPS", DISPLAY->GetFPS()) ); + m_textFPS.Draw(); + } +} + + +void ScreenManager::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + LOG->WriteLine( "ScreenManager::Input( %d-%d, %d-%d, %d-%d, %d-%d )", + DeviceI.device, DeviceI.button, GameI.number, GameI.button, MenuI.player, MenuI.button, StyleI.player, StyleI.col ); + + // pass input only to topmost state + if( m_ScreenStack.GetSize() > 0 ) + m_ScreenStack[m_ScreenStack.GetSize()-1]->Input( DeviceI, type, GameI, MenuI, StyleI ); +} + +void ScreenManager::SetNewScreen( Screen *pNewScreen ) +{ + // move CurrentScreen to ScreenToDelete + m_ScreensToDelete.Copy( m_ScreenStack ); + + m_ScreenStack.RemoveAll(); + m_ScreenStack.Add( pNewScreen ); +} + +void ScreenManager::AddScreenToTop( Screen *pNewScreen ) +{ + // our responsibility to tell the old state that it's losing focus + m_ScreenStack[m_ScreenStack.GetSize()-1]->HandleScreenMessage( SM_LosingInputFocus ); + + // add the new state onto the back of the array + m_ScreenStack.Add( pNewScreen ); +} + +void ScreenManager::PopTopScreen() +{ + Screen* pScreenToPop = m_ScreenStack[m_ScreenStack.GetSize()-1]; // top menu + //pScreenToPop->HandleScreenMessage( SM_LosingInputFocus ); + m_ScreenStack.RemoveAt(m_ScreenStack.GetSize()-1); + m_ScreensToDelete.Add( pScreenToPop ); + + Screen* pNewTopScreen = m_ScreenStack[m_ScreenStack.GetSize()-1]; + pNewTopScreen->HandleScreenMessage( SM_RegainingInputFocus ); +} + +void ScreenManager::SendMessageToTopScreen( ScreenMessage SM, float fDelay ) +{ + Screen* pTopScreen = m_ScreenStack[m_ScreenStack.GetSize()-1]; + pTopScreen->SendScreenMessage( SM, fDelay ); +} + + +void ScreenManager::SystemMessage( CString sMessage ) +{ + // Look for an open spot + m_textSystemMessage.StopTweening(); + m_textSystemMessage.SetText( sMessage ); + m_textSystemMessage.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); + m_textSystemMessage.BeginTweeningQueued( 5 ); + m_textSystemMessage.BeginTweeningQueued( 1 ); + m_textSystemMessage.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) ); + + LOG->WriteLine( "WARNING: Didn't find an empty system messages slot." ); +} + + diff --git a/stepmania/src/ScreenManager.h b/stepmania/src/ScreenManager.h new file mode 100644 index 0000000000..825ff7a4c7 --- /dev/null +++ b/stepmania/src/ScreenManager.h @@ -0,0 +1,53 @@ +#pragma once +/* +----------------------------------------------------------------------------- + Class: ScreenManager + + Desc: Manages the game windows. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + + +#include "RageInput.h" +#include "Song.h" +#include "Notes.h" +#include "Screen.h" +#include "BitmapText.h" +#include "Quad.h" + + +class ScreenManager +{ +public: + ScreenManager(); + ~ScreenManager(); + + // pass these messages along to the current state + void Restore(); + void Invalidate(); + void Update( float fDeltaTime ); + void Draw(); + void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + + void SetNewScreen( Screen *pNewScreen ); + void AddScreenToTop( Screen *pNewScreen ); + void PopTopScreen(); + + void SystemMessage( CString sMessage ); + + void SendMessageToTopScreen( ScreenMessage SM, float fDelay ); + + +private: + CArray m_ScreenStack; + CArray m_ScreensToDelete; + + BitmapText m_textFPS; + BitmapText m_textSystemMessage; +}; + + +extern ScreenManager* SCREENMAN; // global and accessable from anywhere in our program diff --git a/stepmania/src/ScreenMessage.h b/stepmania/src/ScreenMessage.h new file mode 100644 index 0000000000..267e10a63b --- /dev/null +++ b/stepmania/src/ScreenMessage.h @@ -0,0 +1,27 @@ +/* +----------------------------------------------------------------------------- + File: ScreenMessage.h + + Desc: + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#ifndef _ScreenMessage_H_ +#define _ScreenMessage_H_ + + +// common ScreenMessages +enum ScreenMessage { + SM_None = 0, + SM_DoneClosingWipingLeft, + SM_DoneClosingWipingRight, + SM_DoneOpeningWipingLeft, + SM_DoneOpeningWipingRight, + SM_LosingInputFocus, + SM_RegainingInputFocus, + SM_User = 100 +}; + +#endif \ No newline at end of file diff --git a/stepmania/src/ScreenMusicScroll.cpp b/stepmania/src/ScreenMusicScroll.cpp new file mode 100644 index 0000000000..b55a6d7156 --- /dev/null +++ b/stepmania/src/ScreenMusicScroll.cpp @@ -0,0 +1,225 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + Class: ScreenMusicScroll + + Desc: See header. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + + +#include "ScreenMusicScroll.h" +#include "ScreenManager.h" +#include "PrefsManager.h" +#include "ThemeManager.h" +#include "ScreenSelectMusic.h" +#include "ScreenTitleMenu.h" +#include "GameManager.h" +#include "RageLog.h" +#include "GameConstantsAndTypes.h" +#include "SongManager.h" + + +const ScreenMessage SM_StartFadingOut = ScreenMessage(SM_User + 1); +const ScreenMessage SM_GoToNextState = ScreenMessage(SM_User + 2); + +const int LINE_GAP = 40; + +const CString CREDIT_LINES[] = +{ + "", + "", + "", + "", + "", + "", + "", + "", + "CREDITS", + "", + "", + "", + "", + "", + "", + "", + "", + "GRAPHICS:", + "TofuBoy (Lucas Tang)", + "Brian 'Bork' Bugh", + "DJ McFox (Ryan McKanna)", + "", + "WEB DESIGN:", + "Brian 'Bork' Bugh", + "", + "PROGRAMMING:", + "Parasyte (Chris Gomez)", + "Frieza (Andrew Livy)", + "Ben Nordstrom", + "Chris Danford", + "angedelamort (Sauleil Lamarre)", + "Edwin Evans", + "Brian 'Bork' Bugh", + "Jared Roberts", + "Elvis314 (Joel Maher)", + "Kefabi (Garth Smith)", + "Pkillah (Playah Killah)", + "DJ McFox (Ryan McKanna)", + "Robert Kemmetmueller", + "Shabach (Ben Andersen)", + "SlinkyWizard (Will Valladao)", + "TheChip (The Chip)", + "WarriorBob (David H)", + "Mike Waltson", + "", + "SPECIAL THANKS TO:", + "SimWolf", + "Dance With Intensity", + "The Melting Pot", + "Lagged", + "DDRJamz Global BBS", + "DDRManiaX", + "BemaniRuler", + "Brendan Walker", + "WaffleKing (Eric Webster)", + "Foobly (Mark Verrey)", + "Mandarin Blue", + "Anne Kiel", + "BeMaNiFiNiNaTiC", + "Garett Sakamoto", + "Illusionz - Issaquah, WA", + "Quarters - Kirkland, WA", + "Naoki", + "Konami Computer Entertainment Japan", + "", + "", + "", + "", + "", + "", + "", + "", + "If your name is missing from this list," + " I apologize! -Chris" +}; +const int NUM_CREDIT_LINES = sizeof(CREDIT_LINES) / sizeof(CString); + + +ScreenMusicScroll::ScreenMusicScroll() +{ + LOG->WriteLine( "ScreenMusicScroll::ScreenMusicScroll()" ); + + int i; + + m_sprBackground.Load( THEME->GetPathTo(GRAPHIC_MUSIC_SCROLL_BACKGROUND) ); + m_sprBackground.StretchTo( CRect(SCREEN_LEFT,SCREEN_TOP,SCREEN_RIGHT,SCREEN_BOTTOM) ); + this->AddActor( &m_sprBackground ); + + + CArray arraySongs; + arraySongs.Copy( SONGMAN->m_pSongs ); + SortSongPointerArrayByTitle( arraySongs ); + + m_iNumLines = 0; + + for( i=0; iGetPathTo(FONT_NORMAL) ); + m_textLines[m_iNumLines].SetText( pSong->GetMainTitle() ); + m_textLines[m_iNumLines].SetDiffuseColor( SONGMAN->GetGroupColor(pSong->GetGroupName()) ); + + m_iNumLines++; + } + + for( i=0; iGetPathTo(FONT_NORMAL) ); + m_textLines[m_iNumLines].SetText( CREDIT_LINES[i] ); +// this->AddActor( &m_textLines[m_iNumLines] ); + + m_iNumLines++; + } + + for( i=0; iSendScreenMessage( SM_StartFadingOut, 0.20f * i + 3.0f ); + + this->AddActor( &m_Fade ); + + m_soundMusic.Load( THEME->GetPathTo(SOUND_ENDING_MUSIC) ); + + m_Fade.OpenWipingRight(); + m_soundMusic.Play( true ); +} + + +void ScreenMusicScroll::Update( float fDeltaTime ) +{ + Screen::Update( fDeltaTime ); + + for( int i=0; i SCREEN_TOP-20 && + m_textLines[i].GetY() < SCREEN_BOTTOM+20 ) + m_textLines[i].Draw(); + } + + m_Fade.Draw(); // render it again so it shows over the text +} + + +void ScreenMusicScroll::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + LOG->WriteLine( "ScreenMusicScroll::Input()" ); + + if( m_Fade.IsClosing() ) + return; + + Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); // default input handler +} + +void ScreenMusicScroll::HandleScreenMessage( const ScreenMessage SM ) +{ + switch( SM ) + { + case SM_StartFadingOut: + m_Fade.CloseWipingRight( SM_GoToNextState ); + break; + case SM_GoToNextState: + SCREENMAN->SetNewScreen( new ScreenTitleMenu ); + break; + } +} + +void ScreenMusicScroll::MenuStart( PlayerNumber p ) +{ + m_Fade.CloseWipingRight( SM_GoToNextState ); +} + +void ScreenMusicScroll::MenuBack( PlayerNumber p ) +{ + MenuStart( p ); +} + diff --git a/stepmania/src/ScreenMusicScroll.h b/stepmania/src/ScreenMusicScroll.h new file mode 100644 index 0000000000..282f3a7209 --- /dev/null +++ b/stepmania/src/ScreenMusicScroll.h @@ -0,0 +1,51 @@ +/* +----------------------------------------------------------------------------- + File: ScreenMusicScroll.h + + Desc: Music plays and song names scroll across the screen. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "Screen.h" +#include "Sprite.h" +#include "TransitionFade.h" +#include "RageSoundStream.h" +#include "Screen.h" +#include "MenuElements.h" + + +const int MAX_MUSIC_LINES = 700; +const int MAX_CREDIT_LINES = 100; +const int MAX_TOTAL_LINES = MAX_MUSIC_LINES + MAX_CREDIT_LINES; + + +class ScreenMusicScroll : public Screen +{ +public: + ScreenMusicScroll(); + + virtual void Update( float fDeltaTime ); + virtual void DrawPrimitives(); + + virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + virtual void HandleScreenMessage( const ScreenMessage SM ); + + void MenuStart( PlayerNumber p ); + void MenuBack( PlayerNumber p ); + +private: + + Sprite m_sprBackground; + BitmapText m_textLines[MAX_TOTAL_LINES]; + int m_iNumLines; + float m_fTimeLeftInScreen; + + TransitionFade m_Fade; + + RageSoundStream m_soundMusic; +}; + + diff --git a/stepmania/src/ScreenOptions.cpp b/stepmania/src/ScreenOptions.cpp new file mode 100644 index 0000000000..21947bd436 --- /dev/null +++ b/stepmania/src/ScreenOptions.cpp @@ -0,0 +1,407 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: ScreenOptions.h + + Desc: Select a song. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "ScreenOptions.h" +#include +#include "RageTextureManager.h" +#include "RageUtil.h" +#include "RageMusic.h" +#include "ScreenManager.h" +#include "PrefsManager.h" +#include "ScreenGameplay.h" +#include "ThemeManager.h" +#include "GameConstantsAndTypes.h" +#include "RageLog.h" + + + + +const float HEADER_X = CENTER_X; +const float HEADER_Y = 50; +const float HELP_X = CENTER_X; +const float HELP_Y = SCREEN_HEIGHT-35; +const float ITEM_GAP_X = 12; + + +const ScreenMessage SM_PlaySample = ScreenMessage(SM_User-4); +const ScreenMessage SM_GoToPrevState = ScreenMessage(SM_User-5); +const ScreenMessage SM_GoToNextState = ScreenMessage(SM_User-6); +const ScreenMessage SM_JustPressedNext = ScreenMessage(SM_User-7); + + +ScreenOptions::ScreenOptions( CString sBackgroundPath, CString sTopEdgePath ) +{ + LOG->WriteLine( "ScreenOptions::ScreenOptions()" ); + + m_SoundChange.Load( THEME->GetPathTo(SOUND_SELECT) ); + m_SoundNext.Load( THEME->GetPathTo(SOUND_SELECT) ); + + m_Menu.Load( + "Themes\\default\\Graphics\\_shared background.png", + sTopEdgePath, + ssprintf("%s %s to change line %s %s to select between options then press NEXT", CString(char(3)), CString(char(4)), CString(char(1)), CString(char(2)) ) + ); + this->AddActor( &m_Menu ); + m_Menu.TweenAllOnScreen(); + + // init row numbers and element colors + for( int p=0; pAddActor( &m_SelectionHighlight[p] ); + + for( int l=0; lAddActor( &m_OptionUnderline[p][l] ); + } + } + + // add sub actors + for( int i=0; iAddActor( &m_textOptionLineTitles[i] ); + + for( int j=0; jAddActor( &m_textOptions[i][j] ); // this array has to be big enough to hold all of the options + } + } + + + m_Wipe.OpenWipingRight(SM_None); + this->AddActor( &m_Wipe ); +} + +void ScreenOptions::Init( InputMode im, OptionLineData optionLineData[], int iNumOptionLines ) +{ + LOG->WriteLine( "ScreenOptions::Set()" ); + + + m_InputMode = im; + m_OptionLineData = optionLineData; + m_iNumOptionLines = iNumOptionLines; + + + this->ImportOptions(); + InitOptionsText(); + PositionUnderlines(); + PositionHighlights(); +} + +ScreenOptions::~ScreenOptions() +{ + LOG->WriteLine( "ScreenOptions::~ScreenOptions()" ); + +} + + +const int UNDERLINE_THICKNESS = 3; +const int HIGHLIGHT_HEIGHT = 26; + + +void ScreenOptions::GetWidthXY( PlayerNumber p, int iRow, float &fWidthOut, float &fXOut, float &fYOut ) +{ + int iOptionInRow = m_iSelectedOption[p][iRow]; + BitmapText &option = m_textOptions[iRow][iOptionInRow]; + + fWidthOut = option.GetWidestLineWidthInSourcePixels() * option.GetZoomX() + UNDERLINE_THICKNESS*2; + fXOut = option.GetX(); + fYOut = option.GetY(); + + // offset so the underlines for each player don't overlap + fXOut += p - (NUM_PLAYERS-1)/2.0f * UNDERLINE_THICKNESS * 2; + fYOut += p - (NUM_PLAYERS-1)/2.0f * UNDERLINE_THICKNESS * 2; +} + +void ScreenOptions::InitOptionsText() +{ + // init m_textOptions from optionLines + for( int i=0; iGetPathTo(FONT_HEADER2) ); + title.SetText( optline.szTitle ); + title.SetXY( 80, fY ); + title.SetZoom( 0.7f ); + title.SetVertAlign( Actor::align_middle ); + this->AddActor( &title ); + + // init all text in this line and count the width of the line + float fX = 150; // indent 70 pixels + for( int j=0; jGetPathTo(FONT_NORMAL) ); + option.SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); + option.SetText( optline.szOptionsText[j] ); + option.SetZoom( 0.65f ); + option.SetShadowLength( 2 ); + this->AddActor( &option ); + + // set the XY position of each item in the line + float fItemWidth = option.GetWidestLineWidthInSourcePixels() * option.GetZoomX(); + fX += fItemWidth/2; + option.SetXY( fX, fY ); + fX += fItemWidth/2 + ITEM_GAP_X; + } + } + + for( int p=0; p PLAYER_1 && m_InputMode != INPUTMODE_2PLAYERS ) + continue; // skip + + Quad &highlight = m_SelectionHighlight[p]; + this->AddActor( &highlight ); + + for( int i=0; iAddActor( &underline ); + } + } +} + +void ScreenOptions::PositionUnderlines() +{ + // Set the position of the underscores showing the current choice for each option line. + for( int p=0; p PLAYER_1 && m_InputMode != INPUTMODE_2PLAYERS ) + continue; // skip + + for( int i=0; i PLAYER_1 && m_InputMode != INPUTMODE_2PLAYERS ) + continue; // skip + + int i=m_iCurrentRow[p]; + + Quad &highlight = m_SelectionHighlight[p]; + + float fWidth, fX, fY; + GetWidthXY( (PlayerNumber)p, i, fWidth, fX, fY ); + float fHeight = HIGHLIGHT_HEIGHT; + + highlight.SetZoomX( fWidth ); + highlight.SetZoomY( fHeight ); + highlight.SetXY( fX, fY ); + } +} + +void ScreenOptions::TweenHighlight( PlayerNumber player_no ) +{ + // Set the position of the highlight showing the current option the user is changing. + int iCurRow = m_iCurrentRow[player_no]; + + Quad &highlight = m_SelectionHighlight[player_no]; + + float fWidth, fX, fY; + GetWidthXY( player_no, iCurRow, fWidth, fX, fY ); + float fHeight = HIGHLIGHT_HEIGHT; + + highlight.BeginTweening( 0.2f ); + highlight.SetTweenZoomX( fWidth ); + highlight.SetTweenZoomY( fHeight ); + highlight.SetTweenXY( fX, fY ); +} + +void ScreenOptions::Update( float fDeltaTime ) +{ + //LOG->WriteLine( "ScreenOptions::Update(%f)", fDeltaTime ); + + Screen::Update( fDeltaTime ); +} + +void ScreenOptions::DrawPrimitives() +{ + m_Menu.DrawBottomLayer(); + Screen::DrawPrimitives(); + m_Menu.DrawTopLayer(); +} + +void ScreenOptions::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + if( m_Wipe.IsClosing() ) + return; + + // default input handler + Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); +} + +void ScreenOptions::HandleScreenMessage( const ScreenMessage SM ) +{ + switch( SM ) + { + case SM_GoToPrevState: + this->ExportOptions(); + this->GoToPrevState(); + break; + case SM_GoToNextState: + this->ExportOptions(); + this->GoToNextState(); + break; + } +} + + +void ScreenOptions::OnChange() +{ + PositionUnderlines(); +} + + +void ScreenOptions::MenuBack( PlayerNumber p ) +{ + Screen::MenuBack( p ); + + m_Menu.TweenAllOffScreen(); + + m_Wipe.CloseWipingLeft( SM_GoToPrevState ); +} + + +void ScreenOptions::MenuStart( PlayerNumber p ) +{ + Screen::MenuStart( p ); + + m_Menu.TweenAllOffScreen(); + + m_SoundNext.PlayRandom(); + m_Wipe.CloseWipingRight( SM_GoToNextState ); +} + +void ScreenOptions::MenuLeft( PlayerNumber p ) +{ + switch( m_InputMode ) + { + case INPUTMODE_P1_ONLY: + if( p != PLAYER_1 ) + return; + case INPUTMODE_BOTH: + p = PLAYER_1; + break; + case INPUTMODE_2PLAYERS: + break; // fall through + } + + int iCurRow = m_iCurrentRow[p]; + if( m_iSelectedOption[p][iCurRow] == 0 ) // can't go left any more + return; + + m_iSelectedOption[p][iCurRow]--; + + TweenHighlight( p ); + OnChange(); +} + +void ScreenOptions::MenuRight( PlayerNumber p ) +{ + switch( m_InputMode ) + { + case INPUTMODE_P1_ONLY: + if( p != PLAYER_1 ) + return; + case INPUTMODE_BOTH: + p = PLAYER_1; + break; + case INPUTMODE_2PLAYERS: + break; // fall through + } + + int iCurRow = m_iCurrentRow[p]; + if( m_iSelectedOption[p][iCurRow] == m_OptionLineData[iCurRow].iNumOptions-1 ) // can't go right any more + return; + + m_iSelectedOption[p][iCurRow]++; + + TweenHighlight( p ); + OnChange(); +} + +void ScreenOptions::MenuUp( PlayerNumber p ) +{ + switch( m_InputMode ) + { + case INPUTMODE_P1_ONLY: + return; + case INPUTMODE_BOTH: + p = PLAYER_1; + break; + case INPUTMODE_2PLAYERS: + break; // fall through + } + + if( m_iCurrentRow[p] == 0 ) + m_iCurrentRow[p] = m_iNumOptionLines-1; // wrap around + else + m_iCurrentRow[p]--; + + TweenHighlight( p ); + OnChange(); +} + +void ScreenOptions::MenuDown( PlayerNumber p ) +{ + switch( m_InputMode ) + { + case INPUTMODE_P1_ONLY: + return; + case INPUTMODE_BOTH: + p = PLAYER_1; + break; + case INPUTMODE_2PLAYERS: + break; // fall through + } + + if( m_iCurrentRow[p] == m_iNumOptionLines-1 ) + m_iCurrentRow[p] = 0; // wrap around + else + m_iCurrentRow[p]++; + + TweenHighlight( p ); + OnChange(); +} + + diff --git a/stepmania/src/ScreenOptions.h b/stepmania/src/ScreenOptions.h new file mode 100644 index 0000000000..28b9085c5e --- /dev/null +++ b/stepmania/src/ScreenOptions.h @@ -0,0 +1,90 @@ +#pragma once +/* +----------------------------------------------------------------------------- + File: ScreenOptions.h + + Desc: A grid of options, and the selected option is drawn with a highlight rectangle. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + + +#include "Screen.h" +#include "Sprite.h" +#include "BitmapText.h" +#include "RandomSample.h" +#include "TransitionInvisible.h" +#include "Quad.h" +#include "MenuElements.h" + + +const int MAX_OPTION_LINES = 20; +const int MAX_OPTIONS_PER_LINE = 20; + + +// used to pass menu info into this class +struct OptionLineData { + char szTitle[30]; + int iNumOptions; + char szOptionsText[MAX_OPTIONS_PER_LINE][30]; +}; + +enum InputMode { INPUTMODE_P1_ONLY, INPUTMODE_2PLAYERS, INPUTMODE_BOTH }; // both means both players control the same cursor + + +class ScreenOptions : public Screen +{ +public: + ScreenOptions( CString sBackgroundPath, CString sTopEdgePath ); + void Init( InputMode im, OptionLineData optionLineData[], int iNumOptionLines ); + virtual ~ScreenOptions(); + virtual void Update( float fDeltaTime ); + virtual void DrawPrimitives(); + virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + virtual void HandleScreenMessage( const ScreenMessage SM ); + +protected: + virtual void ImportOptions() = 0; + virtual void ExportOptions() = 0; + void InitOptionsText(); + void GetWidthXY( PlayerNumber p, int iRow, float &fWidthOut, float &fXOut, float &fYOut ); + void PositionUnderlines(); + void PositionHighlights(); + void TweenHighlight( PlayerNumber player_no ); + void OnChange(); + + void MenuBack( PlayerNumber p ); + void MenuStart( PlayerNumber p ); + + virtual void GoToNextState() = 0; + virtual void GoToPrevState() = 0; + + void MenuLeft( PlayerNumber p ); + void MenuRight( PlayerNumber p ); + void MenuUp( PlayerNumber p ); + void MenuDown( PlayerNumber p ); + + InputMode m_InputMode; + + OptionLineData* m_OptionLineData; + int m_iNumOptionLines; + + MenuElements m_Menu; + + BitmapText m_textOptionLineTitles[MAX_OPTION_LINES]; + BitmapText m_textOptions[MAX_OPTION_LINES][MAX_OPTIONS_PER_LINE]; // this array has to be big enough to hold all of the options + + int m_iSelectedOption[NUM_PLAYERS][MAX_OPTION_LINES]; + int m_iCurrentRow[NUM_PLAYERS]; + + Quad m_OptionUnderline[NUM_PLAYERS][MAX_OPTION_LINES]; + Quad m_SelectionHighlight[NUM_PLAYERS]; + + RandomSample m_SoundChange; + RandomSample m_SoundNext; + + TransitionInvisible m_Wipe; +}; + diff --git a/stepmania/src/ScreenPlayerOptions.cpp b/stepmania/src/ScreenPlayerOptions.cpp new file mode 100644 index 0000000000..24874ae949 --- /dev/null +++ b/stepmania/src/ScreenPlayerOptions.cpp @@ -0,0 +1,193 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: ScreenPlayerOptions.h + + Desc: Select a song. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "ScreenPlayerOptions.h" +#include +#include "RageTextureManager.h" +#include "RageUtil.h" +#include "RageMusic.h" +#include "ScreenManager.h" +#include "ScreenGameplay.h" +#include "ScreenSongOptions.h" +#include "GameConstantsAndTypes.h" +#include "ThemeManager.h" +#include "ScreenSelectMusic.h" +#include "RageLog.h" +#include "GameManager.h" + + +enum { + PO_SPEED = 0, + PO_EFFECT, + PO_APPEAR, + PO_TURN, + PO_LITTLE, + PO_SCROLL, + PO_COLOR, + PO_FREEZES, + PO_DRAIN, + PO_SKIN, + NUM_PLAYER_OPTIONS_LINES +}; +OptionLineData g_PlayerOptionsLines[NUM_PLAYER_OPTIONS_LINES] = { + { "Speed", 6, {"x1","x1.5","x2","x3","x5","x8"} }, + { "Effect", 6, {"OFF","BOOST","WAVE", "DRUNK", "DIZZY", "SPACE"} }, + { "Appear", 4, {"VISIBLE","HIDDEN","SUDDEN","STEALTH"} }, + { "Turn", 5, {"OFF","MIRROR","LEFT","RIGHT","SHUFFLE"} }, + { "Little", 2, {"OFF","ON"} }, + { "Scroll", 2, {"STANDARD","REVERSE"} }, + { "Color", 4, {"ARCADE","NOTE","FLAT","PLAIN"} }, + { "Freezes", 2, {"OFF","ON"} }, + { "Drain", 3, {"NORMAL", "NO-RECOVER", "SUDDEN-DEATH"} }, + { "Skin", 0, {""} }, // fill this in on ImportOptions(); +}; + + + +ScreenPlayerOptions::ScreenPlayerOptions() : + ScreenOptions( + THEME->GetPathTo(GRAPHIC_PLAYER_OPTIONS_BACKGROUND), + THEME->GetPathTo(GRAPHIC_PLAYER_OPTIONS_TOP_EDGE) + ) +{ + LOG->WriteLine( "ScreenPlayerOptions::ScreenPlayerOptions()" ); + + Init( + INPUTMODE_2PLAYERS, + g_PlayerOptionsLines, + NUM_PLAYER_OPTIONS_LINES + ); +} + + +void ScreenPlayerOptions::ImportOptions() +{ + // fill in skin names + CStringArray arraySkinNames; + GAME->GetSkinNames( arraySkinNames ); + + m_OptionLineData[PO_SKIN].iNumOptions = arraySkinNames.GetSize(); + + for( int i=0; im_PlayerOptions[p]; + + if( po.m_fArrowScrollSpeed == 1.0f ) m_iSelectedOption[p][PO_SPEED] = 0; + else if( po.m_fArrowScrollSpeed == 1.5f ) m_iSelectedOption[p][PO_SPEED] = 1; + else if( po.m_fArrowScrollSpeed == 2.0f ) m_iSelectedOption[p][PO_SPEED] = 2; + else if( po.m_fArrowScrollSpeed == 3.0f ) m_iSelectedOption[p][PO_SPEED] = 3; + else if( po.m_fArrowScrollSpeed == 5.0f ) m_iSelectedOption[p][PO_SPEED] = 4; + else if( po.m_fArrowScrollSpeed == 8.0f ) m_iSelectedOption[p][PO_SPEED] = 5; + else m_iSelectedOption[p][PO_SPEED] = 0; + + m_iSelectedOption[p][PO_EFFECT] = po.m_EffectType; + m_iSelectedOption[p][PO_APPEAR] = po.m_AppearanceType; + m_iSelectedOption[p][PO_TURN] = po.m_TurnType; + m_iSelectedOption[p][PO_LITTLE] = po.m_bLittle ? 1 : 0; + m_iSelectedOption[p][PO_SCROLL] = po.m_bReverseScroll ? 1 : 0 ; + m_iSelectedOption[p][PO_COLOR] = po.m_ColorType; + m_iSelectedOption[p][PO_FREEZES] = po.m_bAllowFreezeArrows ? 1 : 0; + m_iSelectedOption[p][PO_DRAIN] = po.m_DrainType; + + // highlight currently selected skin + for( int s=0; im_sCurrentSkin[p] ) + { + m_iSelectedOption[p][PO_DRAIN] = s; + break; + } + } +} + +void ScreenPlayerOptions::ExportOptions() +{ + for( int p=0; pm_PlayerOptions[p]; + + switch( m_iSelectedOption[p][PO_SPEED] ) + { + case 0: po.m_fArrowScrollSpeed = 1.0f; break; + case 1: po.m_fArrowScrollSpeed = 1.5f; break; + case 2: po.m_fArrowScrollSpeed = 2.0f; break; + case 3: po.m_fArrowScrollSpeed = 3.0f; break; + case 4: po.m_fArrowScrollSpeed = 5.0f; break; + case 5: po.m_fArrowScrollSpeed = 8.0f; break; + } + + + po.m_EffectType = (PlayerOptions::EffectType)m_iSelectedOption[p][PO_EFFECT]; + po.m_AppearanceType = (PlayerOptions::AppearanceType)m_iSelectedOption[p][PO_APPEAR]; + po.m_TurnType = (PlayerOptions::TurnType)m_iSelectedOption[p][PO_TURN]; + po.m_bLittle = m_iSelectedOption[p][PO_LITTLE] == 1; + po.m_bReverseScroll = (m_iSelectedOption[p][PO_SCROLL] == 1); + po.m_ColorType = (PlayerOptions::ColorType)m_iSelectedOption[p][PO_COLOR]; + po.m_bAllowFreezeArrows = (m_iSelectedOption[p][PO_FREEZES] == 1); + po.m_DrainType = (PlayerOptions::DrainType)m_iSelectedOption[p][PO_DRAIN]; + + switch(po.m_DrainType) { + case po.DRAIN_NORMAL: + po.m_fInitialLifePercentage = 0.5f; + po.m_fLifeAdjustments[po.LIFE_PERFECT] = 0.010f; + po.m_fLifeAdjustments[po.LIFE_GREAT] = 0.005f; + po.m_fLifeAdjustments[po.LIFE_GOOD] = 0.000f; + po.m_fLifeAdjustments[po.LIFE_BOO] = -0.015f; + po.m_fLifeAdjustments[po.LIFE_MISS] = -0.030f; + break; + + case po.DRAIN_NO_RECOVER: + po.m_fInitialLifePercentage = 1.0f; + po.m_fLifeAdjustments[po.LIFE_PERFECT] = 0.000f; + po.m_fLifeAdjustments[po.LIFE_GREAT] = 0.000f; + po.m_fLifeAdjustments[po.LIFE_GOOD] = 0.000f; + po.m_fLifeAdjustments[po.LIFE_BOO] = -0.015f; + po.m_fLifeAdjustments[po.LIFE_MISS] = -0.030f; + break; + + case po.DRAIN_SUDDEN_DEATH: + po.m_fInitialLifePercentage = 1.0f; + po.m_fLifeAdjustments[po.LIFE_PERFECT] = 0.000f; + po.m_fLifeAdjustments[po.LIFE_GREAT] = 0.000f; + po.m_fLifeAdjustments[po.LIFE_GOOD] = -1.000f; + po.m_fLifeAdjustments[po.LIFE_BOO] = -1.000f; + po.m_fLifeAdjustments[po.LIFE_MISS] = -1.000f; + break; + + default: + LOG->WriteLine("Unknown Life Meter Drain Setting: %d", m_iSelectedOption[p][PO_DRAIN]); + } + + + for( int s=0; sm_sCurrentSkin[p] ) + { + m_iSelectedOption[p][PO_DRAIN] = s; + break; + } + } +} + +void ScreenPlayerOptions::GoToPrevState() +{ + SCREENMAN->SetNewScreen( new ScreenSelectMusic ); +} + +void ScreenPlayerOptions::GoToNextState() +{ + SCREENMAN->SetNewScreen( new ScreenSongOptions ); +} + + + diff --git a/stepmania/src/ScreenPlayerOptions.h b/stepmania/src/ScreenPlayerOptions.h new file mode 100644 index 0000000000..b9d121cf89 --- /dev/null +++ b/stepmania/src/ScreenPlayerOptions.h @@ -0,0 +1,39 @@ +/* +----------------------------------------------------------------------------- + File: ScreenPlayerOptions.h + + Desc: Select a song. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ +#ifndef _WINDOWPLAYEROPTIONS_H_ +#define _WINDOWPLAYEROPTIONS_H_ + + +#include "Screen.h" +#include "ScreenOptions.h" +#include "Sprite.h" +#include "BitmapText.h" +#include "RandomSample.h" +#include "TransitionFade.h" +#include "Quad.h" + + + +class ScreenPlayerOptions : public ScreenOptions +{ +public: + ScreenPlayerOptions(); + +private: + void ImportOptions(); + void ExportOptions(); + + void GoToNextState(); + void GoToPrevState(); +}; + + + +#endif \ No newline at end of file diff --git a/stepmania/src/ScreenPrompt.cpp b/stepmania/src/ScreenPrompt.cpp new file mode 100644 index 0000000000..ed5cb0f651 --- /dev/null +++ b/stepmania/src/ScreenPrompt.cpp @@ -0,0 +1,181 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: ScreenPrompt.h + + Desc: Area for testing. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + + +#include "ScreenPrompt.h" +#include "PrefsManager.h" +#include "ScreenManager.h" +#include "RageMusic.h" +#include "ScreenTitleMenu.h" +#include "GameConstantsAndTypes.h" +#include "ThemeManager.h" + +ScreenPrompt::ScreenPrompt( CString sText, PromptType pt, bool* pbAnswer ) +{ + + static bool bThrowAway; + + if( pbAnswer == NULL ) + pbAnswer = &bThrowAway; + + + m_PromptType = pt; + m_pbAnswer = pbAnswer; + + ASSERT( !(pt == PROMPT_YES_NO && pt == NULL) ); + + m_Fade.SetTransitionTime( 0.5f ); + m_Fade.SetColor( D3DXCOLOR(0,0,0,0.7f) ); + m_Fade.SetOpened(); + m_Fade.CloseWipingRight(); + m_Fade.SetZ(-2); + this->AddActor( &m_Fade ); + + CStringArray arrayTextLines; + split( sText, "\n", arrayTextLines ); + for( int i=0; iGetPathTo(FONT_HEADER1) ); + m_textQuestion[i].SetText( arrayTextLines[i] ); + m_textQuestion[i].SetXY( CENTER_X, CENTER_Y-50 + i*27 - arrayTextLines.GetSize()*27/2 ); + m_textQuestion[i].SetZ(-2); + this->AddActor( &m_textQuestion[i] ); + } + + m_rectAnswerBox.SetDiffuseColor( D3DXCOLOR(0.5f,0.5f,1.0f,0.7f) ); + m_rectAnswerBox.SetXY( m_textAnswer[*m_pbAnswer].GetX(), m_textAnswer[*m_pbAnswer].GetY() ); + m_rectAnswerBox.SetZoomX( m_textAnswer[*m_pbAnswer].GetWidestLineWidthInSourcePixels()+10.0f ); + m_rectAnswerBox.SetZoomY( 30 ); + m_rectAnswerBox.SetZ(-2); + this->AddActor( &m_rectAnswerBox ); + + m_textAnswer[0].Load( THEME->GetPathTo(FONT_HEADER1) ); + m_textAnswer[1].Load( THEME->GetPathTo(FONT_HEADER1) ); + m_textAnswer[0].SetY( CENTER_Y+120 ); + m_textAnswer[1].SetY( CENTER_Y+120 ); + m_textAnswer[0].SetZ(-2); + m_textAnswer[1].SetZ(-2); + this->AddActor( &m_textAnswer[0] ); + this->AddActor( &m_textAnswer[1] ); + + + + switch( m_PromptType ) + { + case PROMPT_OK: + m_textAnswer[0].SetText( "OK" ); + m_textAnswer[0].SetX( CENTER_X ); + break; + case PROMPT_YES_NO: + m_textAnswer[0].SetText( "NO" ); + m_textAnswer[1].SetText( "YES" ); + m_textAnswer[0].SetX( CENTER_X+50 ); + m_textAnswer[1].SetX( CENTER_X-50 ); + break; + } + + m_rectAnswerBox.SetXY( m_textAnswer[*m_pbAnswer].GetX(), m_textAnswer[*m_pbAnswer].GetY() ); + m_rectAnswerBox.SetZoomX( m_textAnswer[*m_pbAnswer].GetWidestLineWidthInSourcePixels()+10.0f ); + + m_textAnswer[*m_pbAnswer].SetEffectGlowing(); + + + m_soundSelect.Load( THEME->GetPathTo(SOUND_SELECT) ); +} + +void ScreenPrompt::Update( float fDeltaTime ) +{ + Screen::Update( fDeltaTime ); +} + +void ScreenPrompt::DrawPrimitives() +{ + Screen::DrawPrimitives(); +} + +void ScreenPrompt::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + if( m_Fade.IsOpening() ) + return; + + Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); +} + +void ScreenPrompt::HandleScreenMessage( const ScreenMessage SM ) +{ + switch( SM ) + { + case SM_DoneClosingWipingLeft: + break; + case SM_DoneClosingWipingRight: + break; + case SM_DoneOpeningWipingLeft: + break; + case SM_DoneOpeningWipingRight: + SCREENMAN->PopTopScreen(); + break; + } +} + +void ScreenPrompt::MenuLeft( PlayerNumber p ) +{ + if( m_PromptType == PROMPT_OK ) + return; + + MenuRight( p ); +} + +void ScreenPrompt::MenuRight( PlayerNumber p ) +{ + if( m_PromptType == PROMPT_OK ) + return; + + m_textAnswer[*m_pbAnswer].SetEffectNone(); + *m_pbAnswer = !*m_pbAnswer; + m_textAnswer[*m_pbAnswer].SetEffectGlowing(); + + m_rectAnswerBox.BeginTweening( 0.2f ); + m_rectAnswerBox.SetTweenXY( m_textAnswer[*m_pbAnswer].GetX(), m_textAnswer[*m_pbAnswer].GetY() ); + m_rectAnswerBox.SetTweenZoomX( m_textAnswer[*m_pbAnswer].GetWidestLineWidthInSourcePixels()+10.0f ); + +} + +void ScreenPrompt::MenuStart( PlayerNumber p ) +{ + m_Fade.OpenWipingRight( SM_DoneOpeningWipingRight ); + + m_textTitle.BeginTweening( 0.2f ); + m_textTitle.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) ); + + for( int i=0; iGetPathTo(SOUND_SELECT) ); + m_sound.Play(); + + //this->AddActor( &m_spr ); +} + + +void ScreenSandbox::Update( float fDeltaTime ) +{ + Screen::Update( fDeltaTime ); +} + +void ScreenSandbox::DrawPrimitives() +{ + Screen::DrawPrimitives(); +} + +void ScreenSandbox::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + if( MenuI.IsValid() ) + { + switch( MenuI.button ) + { + case MENU_BUTTON_LEFT: + break; + case MENU_BUTTON_RIGHT: + break; + case MENU_BUTTON_UP: + // m_BlurTest.StartFocusing(); + break; + case MENU_BUTTON_DOWN: + // m_BlurTest.StartBlurring(); + break; + case MENU_BUTTON_BACK: + //SCREENMAN->SetNewScreen( new ScreenTitleMenu ); + return; + } + } + +// m_sprBG.SetEffectCamelion( 5, D3DXCOLOR(1,0.8f,0.8f,1), D3DXCOLOR(1,0.2f,0.2f,1) ); +} + + +void ScreenSandbox::HandleScreenMessage( const ScreenMessage SM ) +{ + switch( SM ) + { + case SM_DoneClosingWipingLeft: + break; + case SM_DoneClosingWipingRight: + break; + case SM_DoneOpeningWipingLeft: + break; + case SM_DoneOpeningWipingRight: + break; + } +} \ No newline at end of file diff --git a/stepmania/src/ScreenSandbox.h b/stepmania/src/ScreenSandbox.h new file mode 100644 index 0000000000..3e5fe63d35 --- /dev/null +++ b/stepmania/src/ScreenSandbox.h @@ -0,0 +1,39 @@ +/* +----------------------------------------------------------------------------- + File: ScreenSandbox.h + + Desc: Area for testing. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#ifndef _ScreenSandbox_H_ +#define _ScreenSandbox_H_ + + +#include "Screen.h" +#include "Sprite.h" +#include "BitmapText.h" +#include "Quad.h" +#include "TransitionStarWipe.h" +#include "MenuElements.h" + + +class ScreenSandbox : public Screen +{ +public: + ScreenSandbox(); + + virtual void Update( float fDeltaTime ); + virtual void DrawPrimitives(); + virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + virtual void HandleScreenMessage( const ScreenMessage SM ); + + Sprite m_spr; + + RageSoundSample m_sound; +}; + + +#endif \ No newline at end of file diff --git a/stepmania/src/ScreenSelectDifficulty.cpp b/stepmania/src/ScreenSelectDifficulty.cpp new file mode 100644 index 0000000000..c331653c12 --- /dev/null +++ b/stepmania/src/ScreenSelectDifficulty.cpp @@ -0,0 +1,398 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: ScreenSelectDifficulty.cpp + + Desc: Testing the Screen class. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + + +#include "ScreenSelectDifficulty.h" +#include "ScreenManager.h" +#include "PrefsManager.h" +#include "ThemeManager.h" +#include "ScreenSelectGroup.h" +#include "ScreenTitleMenu.h" +#include "GameManager.h" +#include "RageLog.h" +#include "GameConstantsAndTypes.h" +#include "AnnouncerManager.h" + + +const float EXPLANATION_X = CENTER_X - 150; +const float EXPLANATION_Y = CENTER_Y - 170; + +const float DIFFICULTY_CLASS_X[NUM_DIFFICULTY_CLASSES] = { + CENTER_X-200, + CENTER_X, + CENTER_X+200 +}; +// these sprites are bottom aligned! +const float DIFFICULTY_CLASS_Y[NUM_DIFFICULTY_CLASSES] = { + CENTER_Y-40, + CENTER_Y-60, + CENTER_Y-40 +}; + +const float DIFFICULTY_ARROW_Y[NUM_DIFFICULTY_CLASSES] = { + DIFFICULTY_CLASS_Y[0]+205, + DIFFICULTY_CLASS_Y[1]+205, + DIFFICULTY_CLASS_Y[2]+205 +}; +const float DIFFICULTY_ARROW_X[NUM_DIFFICULTY_CLASSES][NUM_PLAYERS] = { + { DIFFICULTY_CLASS_X[0]-40, DIFFICULTY_CLASS_X[0]+40 }, + { DIFFICULTY_CLASS_X[1]-40, DIFFICULTY_CLASS_X[1]+40 }, + { DIFFICULTY_CLASS_X[2]-40, DIFFICULTY_CLASS_X[2]+40 }, +}; + +const float ARROW_SHADOW_OFFSET = 10; + + +const ScreenMessage SM_GoToPrevState = ScreenMessage(SM_User + 1); +const ScreenMessage SM_GoToNextState = ScreenMessage(SM_User + 2); +const ScreenMessage SM_StartTweeningOffScreen = ScreenMessage(SM_User + 3); +const ScreenMessage SM_StartFadingOut = ScreenMessage(SM_User + 4); + + +ScreenSelectDifficulty::ScreenSelectDifficulty() +{ + LOG->WriteLine( "ScreenSelectDifficulty::ScreenSelectDifficulty()" ); + + + m_Menu.Load( + THEME->GetPathTo(GRAPHIC_SELECT_DIFFICULTY_BACKGROUND) , + THEME->GetPathTo(GRAPHIC_SELECT_DIFFICULTY_TOP_EDGE), + ssprintf("Use %c %c to select, then press NEXT", char(1), char(2)) + ); + this->AddActor( &m_Menu ); + + + m_sprExplanation.Load( THEME->GetPathTo(GRAPHIC_SELECT_DIFFICULTY_EXPLANATION) ); + m_sprExplanation.SetXY( EXPLANATION_X, EXPLANATION_Y ); + this->AddActor( &m_sprExplanation ); + + for( int d=0; dGetPathTo(te_picture) ); + m_sprDifficultyPicture[d].SetXY( DIFFICULTY_CLASS_X[d], DIFFICULTY_CLASS_Y[d] ); + m_sprDifficultyPicture[d].SetVertAlign( align_bottom ); + m_sprDifficultyPicture[d].TurnShadowOff(); + this->AddActor( &m_sprDifficultyPicture[d] ); + + m_sprDifficultyHeader[d].Load( THEME->GetPathTo(te_header) ); + m_sprDifficultyHeader[d].SetXY( DIFFICULTY_CLASS_X[d], DIFFICULTY_CLASS_Y[d] ); + m_sprDifficultyHeader[d].SetVertAlign( align_top ); + m_sprDifficultyHeader[d].TurnShadowOff(); + this->AddActor( &m_sprDifficultyHeader[d] ); + + } + + for( int p=0; pIsPlayerEnabled((PlayerNumber)p) ) + continue; + + ThemeElement te; + switch( p ) + { + case PLAYER_1: te = GRAPHIC_SELECT_DIFFICULTY_ARROW_P1; break; + case PLAYER_2: te = GRAPHIC_SELECT_DIFFICULTY_ARROW_P2; break; + default: ASSERT( false ); + } + m_sprArrowShadow[p].Load( THEME->GetPathTo(te) ); + m_sprArrowShadow[p].TurnShadowOff(); + m_sprArrowShadow[p].SetDiffuseColor( D3DXCOLOR(0,0,0,0.6f) ); + this->AddActor( &m_sprArrowShadow[p] ); + + m_sprArrow[p].Load( THEME->GetPathTo(te) ); + m_sprArrow[p].TurnShadowOff(); + m_sprArrow[p].SetDiffuseColor( PlayerToColor((PlayerNumber)p) ); + m_sprArrow[p].SetEffectGlowing(); + this->AddActor( &m_sprArrow[p] ); + + m_sprOK[p].Load( THEME->GetPathTo(GRAPHIC_SELECT_DIFFICULTY_OK) ); + this->AddActor( &m_sprOK[p] ); + + m_iSelection[p] = 0; + m_bChosen[p] = false; + } + + + m_Fade.SetZ( -2 ); + this->AddActor( &m_Fade ); + + m_soundChange.Load( THEME->GetPathTo(SOUND_SELECT_DIFFICULTY_CHANGE) ); + m_soundSelect.Load( THEME->GetPathTo(SOUND_SELECT) ); + + + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_DIFFICULTY_INTRO) ); + + + if( !MUSIC->IsPlaying() ) + { + MUSIC->Load( THEME->GetPathTo(SOUND_MENU_MUSIC) ); + MUSIC->Play( true ); + } + + m_Fade.OpenWipingRight(); + TweenOnScreen(); +} + + +ScreenSelectDifficulty::~ScreenSelectDifficulty() +{ + LOG->WriteLine( "ScreenSelectDifficulty::~ScreenSelectDifficulty()" ); + +} + + +void ScreenSelectDifficulty::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + LOG->WriteLine( "ScreenSelectDifficulty::Input()" ); + + if( m_Fade.IsClosing() ) + return; + + Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); // default input handler +} + +void ScreenSelectDifficulty::DrawPrimitives() +{ + m_Menu.DrawBottomLayer(); + Screen::DrawPrimitives(); + m_Menu.DrawTopLayer(); +} + +void ScreenSelectDifficulty::HandleScreenMessage( const ScreenMessage SM ) +{ + switch( SM ) + { + case SM_GoToPrevState: + SCREENMAN->SetNewScreen( new ScreenTitleMenu ); + break; + case SM_GoToNextState: + SCREENMAN->SetNewScreen( new ScreenSelectGroup ); + break; + case SM_StartTweeningOffScreen: + TweenOffScreen(); + this->SendScreenMessage( SM_StartFadingOut, 0.8f ); + break; + case SM_StartFadingOut: + m_Fade.CloseWipingRight( SM_GoToNextState ); + break; + } +} + +void ScreenSelectDifficulty::MenuLeft( PlayerNumber p ) +{ + if( m_iSelection[p] == 0 ) // can't go left any more + return; + if( m_bChosen[p] ) + return; + + m_iSelection[p]--; + + m_sprArrow[p].BeginTweening( 0.2f, TWEEN_BIAS_BEGIN ); + m_sprArrow[p].SetTweenX( DIFFICULTY_ARROW_X[m_iSelection[p]][p] - ARROW_SHADOW_OFFSET ); + m_sprArrow[p].SetTweenY( DIFFICULTY_ARROW_Y[m_iSelection[p]] - ARROW_SHADOW_OFFSET ); + + m_sprArrowShadow[p].BeginTweening( 0.2f, TWEEN_BIAS_BEGIN ); + m_sprArrowShadow[p].SetTweenX( DIFFICULTY_ARROW_X[m_iSelection[p]][p] ); + m_sprArrowShadow[p].SetTweenY( DIFFICULTY_ARROW_Y[m_iSelection[p]] ); + + m_soundChange.PlayRandom(); +} + + +void ScreenSelectDifficulty::MenuRight( PlayerNumber p ) +{ + if( m_iSelection[p] == 2 ) // can't go right any more + return; + if( m_bChosen[p] ) + return; + + m_iSelection[p]++; + + m_sprArrow[p].BeginTweening( 0.2f, TWEEN_BIAS_BEGIN ); + m_sprArrow[p].SetTweenX( DIFFICULTY_ARROW_X[m_iSelection[p]][p] - ARROW_SHADOW_OFFSET ); + m_sprArrow[p].SetTweenY( DIFFICULTY_ARROW_Y[m_iSelection[p]] - ARROW_SHADOW_OFFSET ); + + m_sprArrowShadow[p].BeginTweening( 0.2f, TWEEN_BIAS_BEGIN ); + m_sprArrowShadow[p].SetTweenX( DIFFICULTY_ARROW_X[m_iSelection[p]][p] ); + m_sprArrowShadow[p].SetTweenY( DIFFICULTY_ARROW_Y[m_iSelection[p]] ); + + m_soundChange.PlayRandom(); +} + +void ScreenSelectDifficulty::MenuStart( PlayerNumber pn ) +{ + if( m_bChosen[pn] == true ) + return; + m_bChosen[pn] = true; + + m_soundSelect.PlayRandom(); + int iSelection = m_iSelection[pn]; + + switch( iSelection ) + { + case 0: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_DIFFICULTY_COMMENT_EASY) ); break; + case 1: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_DIFFICULTY_COMMENT_MEDIUM) ); break; + case 2: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_DIFFICULTY_COMMENT_HARD) ); break; + } + + m_sprArrow[pn].BeginTweeningQueued( 0.2f ); + m_sprArrow[pn].BeginTweeningQueued( 0.2f ); + m_sprArrow[pn].SetTweenX( DIFFICULTY_ARROW_X[iSelection][pn] ); + m_sprArrow[pn].SetTweenY( DIFFICULTY_ARROW_Y[iSelection] ); + + m_sprOK[pn].SetX( DIFFICULTY_ARROW_X[iSelection][pn] ); + m_sprOK[pn].SetY( DIFFICULTY_ARROW_Y[iSelection] ); + m_sprOK[pn].SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); + m_sprOK[pn].SetZoom( 2 ); + + m_sprOK[pn].BeginTweening( 0.2f ); + m_sprOK[pn].SetTweenZoom( 1 ); + m_sprOK[pn].SetTweenDiffuseColor( D3DXCOLOR(1,1,1,1) ); + + m_sprArrowShadow[pn].BeginTweeningQueued( 0.2f ); + m_sprArrowShadow[pn].BeginTweeningQueued( 0.2f ); + m_sprArrowShadow[pn].SetDiffuseColor( D3DXCOLOR(0,0,0,0) ); + + + // check to see if everyone has chosen + for( int p=0; pSendScreenMessage( SM_StartTweeningOffScreen, 0.7f ); +} + +void ScreenSelectDifficulty::MenuBack( PlayerNumber p ) +{ + m_Fade.CloseWipingLeft( SM_GoToPrevState ); + + TweenOffScreen(); +} + +void ScreenSelectDifficulty::TweenOffScreen() +{ + m_Menu.TweenTopEdgeOffScreen(); + + m_sprExplanation.SetXY( EXPLANATION_X, EXPLANATION_Y ); + m_sprExplanation.BeginTweening( 0.5, Actor::TWEEN_BOUNCE_BEGIN ); + m_sprExplanation.SetTweenXY( EXPLANATION_X-400, EXPLANATION_Y ); + + for( int p=0; pIsPlayerEnabled((PlayerNumber)p) ) + continue; + + m_sprArrow[p].BeginTweening( 0.3f ); + m_sprArrow[p].SetTweenZoom( 0 ); + + m_sprOK[p].BeginTweening( 0.3f ); + m_sprOK[p].SetTweenZoom( 0 ); + + m_sprArrowShadow[p].BeginTweeningQueued( 0.3f ); + m_sprArrowShadow[p].SetTweenDiffuseColor( D3DXCOLOR(0,0,0,0) ); + } + + for( int d=0; dIsPlayerEnabled((PlayerNumber)p) ) + continue; + + int iSelection = m_iSelection[p]; + + m_sprArrow[p].SetX( DIFFICULTY_ARROW_X[iSelection][p] ); + m_sprArrow[p].SetY( DIFFICULTY_ARROW_Y[iSelection] ); + m_sprArrow[p].SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); + m_sprArrow[p].SetRotation( D3DX_PI ); + m_sprArrow[p].SetZoom( 2 ); + m_sprArrow[p].BeginTweening( 0.3f ); + m_sprArrow[p].SetTweenDiffuseColor( D3DXCOLOR(1,1,1,1) ); + m_sprArrow[p].SetTweenRotationZ( 0 ); + m_sprArrow[p].SetTweenZoom( 1 ); + + m_sprArrowShadow[p].SetX( DIFFICULTY_ARROW_X[iSelection][p] ); + m_sprArrowShadow[p].SetY( DIFFICULTY_ARROW_Y[iSelection] ); + D3DXCOLOR colorOriginal = m_sprArrowShadow[p].GetDiffuseColor(); + m_sprArrowShadow[p].SetDiffuseColor( D3DXCOLOR(0,0,0,0) ); + m_sprArrowShadow[p].BeginTweening( 0.3f ); + m_sprArrowShadow[p].SetTweenDiffuseColor( colorOriginal ); + } + + for( int d=0; d +#include "RageTextureManager.h" +#include "RageUtil.h" +#include "RageMusic.h" +#include "ScreenManager.h" +#include "PrefsManager.h" +#include "ScreenOptions.h" +#include "ScreenTitleMenu.h" +#include "GameConstantsAndTypes.h" +#include "StepMania.h" +#include "ThemeManager.h" +#include "RageLog.h" +#include "GameManager.h" +#include "string.h" + + + +enum { + SG_GAME = 0, + NUM_SELECT_GAME_LINES +}; + + +OptionLineData g_SelectGameLines[NUM_SELECT_GAME_LINES] = +{ + "Game", -1, { "" } +}; + + +ScreenSelectGame::ScreenSelectGame() : + ScreenOptions( + THEME->GetPathTo(GRAPHIC_PLAYER_OPTIONS_BACKGROUND), + THEME->GetPathTo(GRAPHIC_PLAYER_OPTIONS_TOP_EDGE) + ) +{ + LOG->WriteLine( "ScreenSelectGame::ScreenSelectGame()" ); + + + // populate g_SelectGameLines + CStringArray arrayGameNames; + GAME->GetGameNames( arrayGameNames ); + for( int i=0; im_sCurrentGame, m_OptionLineData[0].szOptionsText[i]) ) + { + CString sGameName = m_OptionLineData[0].szOptionsText[i]; + if( sGameName == GAME->m_sCurrentGame ) + m_iSelectedOption[0][SG_GAME] = i; + } + } +} + +void ScreenSelectGame::ExportOptions() +{ + int iOption = m_iSelectedOption[0][SG_GAME]; + CString sGameName = m_OptionLineData[0].szOptionsText[iOption]; + GAME->SwitchGame( sGameName ); + THEME->SwitchTheme( sGameName ); +} + +void ScreenSelectGame::GoToPrevState() +{ + SCREENMAN->SetNewScreen( new ScreenTitleMenu ); +} + +void ScreenSelectGame::GoToNextState() +{ + SCREENMAN->SetNewScreen( new ScreenTitleMenu ); +} + + diff --git a/stepmania/src/ScreenSelectGame.h b/stepmania/src/ScreenSelectGame.h new file mode 100644 index 0000000000..24d18472b2 --- /dev/null +++ b/stepmania/src/ScreenSelectGame.h @@ -0,0 +1,31 @@ +/* +----------------------------------------------------------------------------- + File: ScreenSelectGame.h + + Desc: Select a song. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "Screen.h" +#include "ScreenOptions.h" +#include "Sprite.h" +#include "BitmapText.h" +#include "RandomSample.h" +#include "TransitionFade.h" +#include "Quad.h" + + +class ScreenSelectGame : public ScreenOptions +{ +public: + ScreenSelectGame(); + +private: + void ImportOptions(); + void ExportOptions(); + + void GoToNextState(); + void GoToPrevState(); +}; diff --git a/stepmania/src/ScreenSelectGroup.cpp b/stepmania/src/ScreenSelectGroup.cpp new file mode 100644 index 0000000000..5c16ac5467 --- /dev/null +++ b/stepmania/src/ScreenSelectGroup.cpp @@ -0,0 +1,386 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: ScreenSelectGroup.cpp + + Desc: See header. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + + +#include "ScreenSelectGroup.h" +#include "ScreenManager.h" +#include "PrefsManager.h" +#include "ThemeManager.h" +#include "ScreenSelectMusic.h" +#include "ScreenTitleMenu.h" +#include "GameManager.h" +#include "RageLog.h" +#include "GameConstantsAndTypes.h" +#include "SongManager.h" +#include "AnnouncerManager.h" + + +const float GROUP_INFO_FRAME_X = SCREEN_LEFT + 180; +const float GROUP_INFO_FRAME_Y = SCREEN_TOP + 160; + +const float EXPLANATION_X = SCREEN_LEFT + 110; +const float EXPLANATION_Y = SCREEN_TOP + 65; + +const float BUTTON_X = SCREEN_RIGHT - 135; +const float BUTTON_SELECTED_X = BUTTON_X - 30; +const float BUTTON_START_Y = SCREEN_TOP + 65; +const float BUTTON_GAP_Y = 26; + +const float CONTENTS_X = CENTER_X; +const float CONTENTS_START_Y = SCREEN_TOP + SCREEN_HEIGHT*3/5 - 15; + +const int TITLES_PER_COLUMN = 10; + +const ScreenMessage SM_GoToPrevState = ScreenMessage(SM_User + 1); +const ScreenMessage SM_GoToNextState = ScreenMessage(SM_User + 2); +const ScreenMessage SM_StartFadingOut = ScreenMessage(SM_User + 3); + + +ScreenSelectGroup::ScreenSelectGroup() +{ + LOG->WriteLine( "ScreenSelectGroup::ScreenSelectGroup()" ); + + int i; + + SONGMAN->GetGroupNames( m_arrayGroupNames ); + m_arrayGroupNames.InsertAt( 0, "ALL MUSIC" ); + + m_iSelection = 0; + m_bChosen = false; + + m_Menu.Load( + THEME->GetPathTo(GRAPHIC_SELECT_GROUP_BACKGROUND) , + THEME->GetPathTo(GRAPHIC_SELECT_GROUP_TOP_EDGE), + ssprintf("Use %c %c to select, then press NEXT", char(1), char(2)) + ); + this->AddActor( &m_Menu ); + + m_sprExplanation.Load( THEME->GetPathTo(GRAPHIC_SELECT_GROUP_EXPLANATION) ); + m_sprExplanation.SetXY( EXPLANATION_X, EXPLANATION_Y ); + this->AddActor( &m_sprExplanation ); + + m_GroupInfoFrame.SetXY( GROUP_INFO_FRAME_X, GROUP_INFO_FRAME_Y ); + this->AddActor( &m_GroupInfoFrame ); + + m_sprContentsHeader.Load( THEME->GetPathTo(GRAPHIC_SELECT_GROUP_CONTENTS_HEADER) ); + m_sprContentsHeader.SetVertAlign( Actor::align_top ); + m_sprContentsHeader.SetXY( CONTENTS_X, CONTENTS_START_Y ); + this->AddActor( &m_sprContentsHeader ); + + for( i=0; iGetPathTo(FONT_NORMAL) ); + m_textContents[i].SetXY( fX, CONTENTS_START_Y+15 ); + m_textContents[i].SetHorizAlign( Actor::align_left ); + m_textContents[i].SetVertAlign( Actor::align_bottom ); + m_textContents[i].SetZoom( 0.5f ); + m_textContents[i].SetShadowLength( 2 ); + this->AddActor( &m_textContents[i] ); + } + + + for( i=0; iGetPathTo(GRAPHIC_SELECT_GROUP_BUTTON) ); + m_sprGroupButton[i].SetXY( BUTTON_X, BUTTON_START_Y + BUTTON_GAP_Y*i ); + this->AddActor( &m_sprGroupButton[i] ); + + m_textGroup[i].Load( THEME->GetPathTo(FONT_NORMAL) ); + m_textGroup[i].SetXY( BUTTON_X, BUTTON_START_Y + BUTTON_GAP_Y*i ); + m_textGroup[i].SetText( SONGMAN->ShortenGroupName( sGroupName ) ); + m_textGroup[i].SetZoom( 0.8f ); + if( m_textGroup[i].GetWidestLineWidthInSourcePixels()*0.8f > m_sprGroupButton[i].GetUnzoomedWidth() ) + m_textGroup[i].SetZoomX( m_textGroup[i].GetWidestLineWidthInSourcePixels()*0.8f / (float)m_sprGroupButton[i].GetUnzoomedWidth() ); + m_textGroup[i].SetShadowLength( 2 ); + + if( i == 0 ) m_textGroup[i].TurnRainbowOn(); + else m_textGroup[i].SetDiffuseColor( SONGMAN->GetGroupColor(sGroupName) ); + + this->AddActor( &m_textGroup[i] ); + } + + + m_Fade.SetZ( -2 ); + this->AddActor( &m_Fade ); + + m_soundChange.Load( THEME->GetPathTo(SOUND_SELECT_DIFFICULTY_CHANGE) ); + m_soundSelect.Load( THEME->GetPathTo(SOUND_SELECT) ); + + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_GROUP_INTRO) ); + + + if( !MUSIC->IsPlaying() ) + { + MUSIC->Load( THEME->GetPathTo(SOUND_MENU_MUSIC) ); + MUSIC->Play( true ); + } + + m_Fade.OpenWipingRight(); + TweenOnScreen(); + AfterChange(); +} + + +ScreenSelectGroup::~ScreenSelectGroup() +{ + LOG->WriteLine( "ScreenSelectGroup::~ScreenSelectGroup()" ); + +} + + +void ScreenSelectGroup::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + LOG->WriteLine( "ScreenSelectGroup::Input()" ); + + if( m_Fade.IsClosing() || m_bChosen ) + return; + + Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); // default input handler +} + +void ScreenSelectGroup::DrawPrimitives() +{ + m_Menu.DrawBottomLayer(); + Screen::DrawPrimitives(); + m_Menu.DrawTopLayer(); +} + +void ScreenSelectGroup::HandleScreenMessage( const ScreenMessage SM ) +{ + switch( SM ) + { + case SM_GoToPrevState: + SCREENMAN->SetNewScreen( new ScreenTitleMenu ); + break; + case SM_GoToNextState: + SCREENMAN->SetNewScreen( new ScreenSelectMusic ); + break; + case SM_StartFadingOut: + m_Fade.CloseWipingRight( SM_GoToNextState ); + break; + } +} + +void ScreenSelectGroup::BeforeChange() +{ + int iSel = m_iSelection; + + m_sprGroupButton[iSel].BeginTweening( 0.2f ); + m_sprGroupButton[iSel].SetTweenX( BUTTON_X ); + m_sprGroupButton[iSel].SetEffectNone(); + + m_textGroup[iSel].BeginTweening( 0.2f ); + m_textGroup[iSel].SetTweenX( BUTTON_X ); + m_textGroup[iSel].SetEffectNone(); +} + +void ScreenSelectGroup::AfterChange() +{ + int iSel = m_iSelection; + + m_sprGroupButton[iSel].BeginTweening( 0.2f ); + m_sprGroupButton[iSel].SetTweenX( BUTTON_SELECTED_X ); + m_sprGroupButton[iSel].SetEffectGlowing(); + + m_textGroup[iSel].BeginTweening( 0.2f ); + m_textGroup[iSel].SetTweenX( BUTTON_SELECTED_X ); + m_textGroup[iSel].SetEffectGlowing(); + + + CArray arraySongs; + const CString sSelectedGroupName = m_arrayGroupNames[m_iSelection]; + + if( m_iSelection == 0 ) arraySongs.Copy( SONGMAN->m_pSongs ); + else SONGMAN->GetSongsInGroup( m_arrayGroupNames[m_iSelection], arraySongs ); + + for( int i=0; iGetMainTitle() + "\n"; + } + } + m_textContents[i].SetText( sText ); + } + + CString sGroupBannerPath; + if( 0 == stricmp(sSelectedGroupName, "ALL MUSIC") ) + sGroupBannerPath = THEME->GetPathTo(GRAPHIC_ALL_MUSIC_BANNER); + else if( SONGMAN->GetGroupBannerPath(sSelectedGroupName) != "" ) + sGroupBannerPath = SONGMAN->GetGroupBannerPath(sSelectedGroupName); + else + sGroupBannerPath = THEME->GetPathTo(GRAPHIC_FALLBACK_BANNER); + + m_GroupInfoFrame.Set( sGroupBannerPath, arraySongs.GetSize() ); +} + + +void ScreenSelectGroup::MenuLeft( PlayerNumber p ) +{ + MenuUp( p ); +} + +void ScreenSelectGroup::MenuRight( PlayerNumber p ) +{ + MenuDown( p ); +} + +void ScreenSelectGroup::MenuUp( PlayerNumber p ) +{ + if( m_bChosen ) + return; + + BeforeChange(); + + m_iSelection = m_iSelection-1 % m_arrayGroupNames.GetSize(); + if( m_iSelection < 0 ) + m_iSelection += m_arrayGroupNames.GetSize(); + + AfterChange(); + + m_soundChange.PlayRandom(); +} + + +void ScreenSelectGroup::MenuDown( PlayerNumber p ) +{ + if( m_bChosen ) + return; + + BeforeChange(); + + m_iSelection = (m_iSelection+1) % m_arrayGroupNames.GetSize(); + + AfterChange(); + + m_soundChange.PlayRandom(); +} + +void ScreenSelectGroup::MenuStart( PlayerNumber p ) +{ + m_soundSelect.PlayRandom(); + m_bChosen = true; + + SONGMAN->m_pCurSong = NULL; + SONGMAN->m_sPreferredGroup = m_arrayGroupNames[m_iSelection]; + + if( 0 == stricmp(SONGMAN->m_sPreferredGroup, "All Music") ) + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_GROUP_COMMENT_ALL_MUSIC) ); + else + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_GROUP_COMMENT_GENERAL) ); + + + TweenOffScreen(); + this->SendScreenMessage( SM_StartFadingOut, 0.8f ); +} + +void ScreenSelectGroup::MenuBack( PlayerNumber p ) +{ + m_Fade.CloseWipingLeft( SM_GoToPrevState ); + + TweenOffScreen(); +} + +void ScreenSelectGroup::TweenOffScreen() +{ + m_Menu.TweenTopEdgeOffScreen(); + + m_sprExplanation.BeginTweeningQueued( 0.8f ); + m_sprExplanation.BeginTweeningQueued( 0.5f, TWEEN_BOUNCE_BEGIN ); + m_sprExplanation.SetTweenX( EXPLANATION_X-400 ); + + m_GroupInfoFrame.BeginTweeningQueued( 0.9f ); + m_GroupInfoFrame.BeginTweeningQueued( 0.5f, TWEEN_BOUNCE_BEGIN ); + m_GroupInfoFrame.SetTweenX( GROUP_INFO_FRAME_X-400 ); + + m_sprContentsHeader.BeginTweeningQueued( 0.7f ); + m_sprContentsHeader.BeginTweeningQueued( 0.5f, TWEEN_BIAS_END ); + m_sprContentsHeader.SetTweenY( CONTENTS_START_Y+400 ); + + int i; + + for( i=0; iWriteLine( "ScreenSelectMusic::ScreenSelectMusic()" ); + + int p; + + m_Menu.Load( + THEME->GetPathTo(GRAPHIC_SELECT_MUSIC_BACKGROUND), + THEME->GetPathTo(GRAPHIC_SELECT_MUSIC_TOP_EDGE), + ssprintf("%c or %c change music %c%c easier difficulty %c%c harder difficulty %c%c%c%c change sort", + char(1), char(2), char(3), char(3), char(4), char(4), char(3), char(4), char(3), char(4) ) + ); + this->AddActor( &m_Menu ); + + m_SongInfoFrame.SetXY( SONG_INFO_FRAME_X, SONG_INFO_FRAME_Y ); + this->AddActor( &m_SongInfoFrame ); + + m_sprDifficultyFrame.Load( THEME->GetPathTo(GRAPHIC_SELECT_MUSIC_DIFFICULTY_FRAME) ); + m_sprDifficultyFrame.SetXY( DIFFICULTY_X, DIFFICULTY_Y ); + this->AddActor( &m_sprDifficultyFrame ); + + for( p=0; pAddActor( &m_DifficultyIcon[p] ); + } + + m_GrooveRadar.SetXY( RADAR_X, RADAR_Y ); + this->AddActor( &m_GrooveRadar ); + + m_sprMeterFrame.Load( THEME->GetPathTo(GRAPHIC_SELECT_MUSIC_METER_FRAME) ); + m_sprMeterFrame.SetXY( METER_FRAME_X, METER_FRAME_Y ); + this->AddActor( &m_sprMeterFrame ); + + for( p=0; pGetPathTo(FONT_METER) ); + m_FootMeter[p].SetXY( METER_X[p], METER_Y[p] ); + m_FootMeter[p].SetShadowLength( 2 ); + this->AddActor( &m_FootMeter[p] ); + } + + m_MusicWheel.SetXY( WHEEL_X, WHEEL_Y ); + this->AddActor( &m_MusicWheel ); + + m_Wipe.SetZ( -2 ); + this->AddActor( &m_Wipe ); + + m_Fade.SetZ( -2 ); + this->AddActor( &m_Fade ); + + m_textHoldForOptions.Load( THEME->GetPathTo(FONT_STAGE) ); + m_textHoldForOptions.SetXY( CENTER_X, CENTER_Y ); + m_textHoldForOptions.SetText( "hold NEXT for options" ); + m_textHoldForOptions.SetZoom( 1 ); + m_textHoldForOptions.SetZoomY( 0 ); + m_textHoldForOptions.SetDiffuseColor( D3DXCOLOR(1,1,1,0) ); + this->AddActor( &m_textHoldForOptions ); + + + m_soundSelect.Load( THEME->GetPathTo(SOUND_SELECT) ); + m_soundChangeNotes.Load( THEME->GetPathTo(SOUND_SWITCH_STEPS) ); + + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_MUSIC_INTRO) ); + + + AfterMusicChange(); + TweenOnScreen(); + m_Wipe.OpenWipingRight(); +} + + +ScreenSelectMusic::~ScreenSelectMusic() +{ + LOG->WriteLine( "ScreenSelectMusic::~ScreenSelectMusic()" ); + +} + +void ScreenSelectMusic::DrawPrimitives() +{ + m_Menu.DrawBottomLayer(); + Screen::DrawPrimitives(); + m_Menu.DrawTopLayer(); +} + +void ScreenSelectMusic::TweenOnScreen() +{ + m_Menu.TweenTopEdgeOnScreen(); + + float fOriginalZoomY; + + m_SongInfoFrame.SetXY( SONG_INFO_FRAME_X - 400, SONG_INFO_FRAME_Y ); + m_SongInfoFrame.BeginTweening( TWEEN_TIME, Actor::TWEEN_BIAS_END ); + m_SongInfoFrame.SetTweenXY( SONG_INFO_FRAME_X, SONG_INFO_FRAME_Y ); + + fOriginalZoomY = m_sprDifficultyFrame.GetZoomY(); + m_sprDifficultyFrame.BeginTweening( TWEEN_TIME ); + m_sprDifficultyFrame.SetTweenZoomY( fOriginalZoomY ); + + fOriginalZoomY = m_sprMeterFrame.GetZoomY(); + m_sprMeterFrame.BeginTweening( TWEEN_TIME ); + m_sprMeterFrame.SetTweenZoomY( fOriginalZoomY ); + + m_GrooveRadar.TweenOnScreen(); + + + for( int p=0; pWriteLine( "ScreenSelectMusic::Input()" ); + + if( m_Wipe.IsClosing() || m_Fade.IsClosing() ) + return; // ignore + + if( MenuI.player == PLAYER_NONE ) + return; + + if( INPUTQUEUE->MatchesPattern(MenuI.player, EASIER_DIFFICULTY_PATTERN, EASIER_DIFFICULTY_PATTERN_SIZE) ) + { + EasierDifficulty( MenuI.player ); + return; + } + if( INPUTQUEUE->MatchesPattern(MenuI.player, HARDER_DIFFICULTY_PATTERN, HARDER_DIFFICULTY_PATTERN_SIZE) ) + { + HarderDifficulty( MenuI.player ); + return; + } + if( INPUTQUEUE->MatchesPattern(MenuI.player, NEXT_SORT_PATTERN, NEXT_SORT_PATTERN_SIZE) ) + { + m_MusicWheel.NextSort(); + return; + } + + + Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); // default input handler +} + + +void ScreenSelectMusic::EasierDifficulty( PlayerNumber p ) +{ + LOG->WriteLine( "ScreenSelectMusic::EasierDifficulty( %d )", p ); + + if( !GAME->IsPlayerEnabled(p) ) + return; + if( m_arrayNotes.GetSize() == 0 ) + return; + if( m_iSelection[p] == 0 ) + return; + + m_iSelection[p]--; + m_soundChangeNotes.PlayRandom(); + + AfterNotesChange( p ); +} + +void ScreenSelectMusic::HarderDifficulty( PlayerNumber p ) +{ + LOG->WriteLine( "ScreenSelectMusic::HarderDifficulty( %d )", p ); + + if( !GAME->IsPlayerEnabled(p) ) + return; + if( m_arrayNotes.GetSize() == 0 ) + return; + if( m_iSelection[p] == m_arrayNotes.GetSize()-1 ) + return; + + m_iSelection[p]++; + m_soundChangeNotes.PlayRandom(); + + AfterNotesChange( p ); +} + + +void ScreenSelectMusic::HandleScreenMessage( const ScreenMessage SM ) +{ + Screen::HandleScreenMessage( SM ); + + switch( SM ) + { + case SM_GoToPrevState: + SCREENMAN->SetNewScreen( new ScreenTitleMenu ); + break; + case SM_GoToNextState: + + // find out if the Next button is being held down on any of the pads + bool bIsHoldingNext; + bIsHoldingNext = false; + int player; + for( player=0; playerIsButtonDown( mi ) ) + bIsHoldingNext = true; + } + + if( bIsHoldingNext ) + { + SCREENMAN->SetNewScreen( new ScreenPlayerOptions ); + } + else + { + MUSIC->Stop(); + + SCREENMAN->SetNewScreen( new ScreenStage(false) ); + } + break; + case SM_PlaySongSample: + PlayMusicSample(); + break; + } +} + +void ScreenSelectMusic::MenuLeft( PlayerNumber p ) +{ + m_MusicWheel.PrevMusic(); + + AfterMusicChange(); +} + + +void ScreenSelectMusic::MenuRight( PlayerNumber p ) +{ + m_MusicWheel.NextMusic(); + + AfterMusicChange(); +} + +void ScreenSelectMusic::MenuStart( PlayerNumber p ) +{ + // this needs to check whether valid Notes are selected! + m_MusicWheel.Select(); + + switch( m_MusicWheel.GetSelectedType() ) + { + case TYPE_SONG: + { + if( !m_MusicWheel.GetSelectedSong()->HasMusic() ) + { + SCREENMAN->AddScreenToTop( new ScreenPrompt( "ERROR:\n \nThis song does not have a music file\n and cannot be played.", PROMPT_OK) ); + return; + } + + TweenOffScreen(); + m_soundSelect.PlayRandom(); + + bool bIsNew = m_MusicWheel.GetSelectedSong()->IsNew(); + bool bIsHard = false; + for( int p=0; pIsPlayerEnabled( (PlayerNumber)p ) ) + continue; // skip + if( SONGMAN->m_pCurNotes[p]->m_iMeter >= 9 ) + bIsHard = true; + } + + if( bIsNew ) + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_MUSIC_COMMENT_NEW) ); + else if( bIsHard ) + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_MUSIC_COMMENT_HARD) ); + else + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_MUSIC_COMMENT_GENERAL) ); + + ; + + // show "hold NEXT for options" + m_textHoldForOptions.BeginTweeningQueued( 0.25f ); // fade in + m_textHoldForOptions.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,1) ); + m_textHoldForOptions.SetTweenZoomY( 1 ); + m_textHoldForOptions.BeginTweeningQueued( 1.0f ); // sleep + m_textHoldForOptions.BeginTweeningQueued( 0.25f ); // fade out + m_textHoldForOptions.SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) ); + m_textHoldForOptions.SetTweenZoomY( 0 ); + + m_Fade.SetTransitionTime( 1.5f ); // give enough time for m_textHoldForOptions to complete its tweens + m_Fade.CloseWipingRight( SM_GoToNextState ); + } + break; + case TYPE_SECTION: + + break; + case TYPE_ROULETTE: + + break; + } +} + + +void ScreenSelectMusic::MenuBack( PlayerNumber p ) +{ + Screen::MenuBack( p ); + + MUSIC->Stop(); + + m_Wipe.CloseWipingLeft( SM_GoToPrevState ); + + TweenOffScreen(); +} + +void ScreenSelectMusic::AfterNotesChange( PlayerNumber p ) +{ + if( !GAME->IsPlayerEnabled(p) ) + return; + + m_iSelection[p] = clamp( m_iSelection[p], 0, m_arrayNotes.GetSize()-1 ); // bounds clamping + + Notes* pNotes = m_arrayNotes.GetSize()>0 ? m_arrayNotes[m_iSelection[p]] : NULL; + + SONGMAN->m_pCurNotes[p] = pNotes; + + m_DifficultyIcon[p].SetFromNotes( pNotes ); + m_FootMeter[p].SetFromNotes( pNotes ); + m_GrooveRadar.SetFromNotes( p, pNotes ); + m_MusicWheel.NotesChanged( p ); +} + +void ScreenSelectMusic::AfterMusicChange() +{ + Song* pSong = m_MusicWheel.GetSelectedSong(); + SONGMAN->m_pCurSong = pSong; + + m_arrayNotes.RemoveAll(); + + switch( m_MusicWheel.GetSelectedType() ) + { + case TYPE_SECTION: + { + CString sGroup = m_MusicWheel.GetSelectedSection(); + m_SongInfoFrame.SetFromGroup( sGroup ); // if this isn't a group, it'll default to the fallback banner + for( int p=0; pGetNotessThatMatchGameAndStyle( GAME->m_sCurrentGame, GAME->m_sCurrentStyle, m_arrayNotes ); + SortNotesArrayByDifficultyClass( m_arrayNotes ); + m_SongInfoFrame.SetFromSong( pSong ); + for( int p=0; pIsPlayerEnabled( PlayerNumber(p) ) ) + continue; + m_iSelection[p] = clamp( m_iSelection[p], 0, m_arrayNotes.GetSize() ) ; + } + } + break; + case TYPE_ROULETTE: + m_SongInfoFrame.SetRoulette(); + break; + } + + for( int p=0; pWriteLine( "ScreenSelectSong::PlaySONGample()" ); + + MUSIC->Stop(); + + Song* pSong = m_MusicWheel.GetSelectedSong(); + if( pSong == NULL ) + return; + + CString sSongToPlay = pSong->GetMusicPath(); + + if( pSong->HasMusic() ) + { + float fStartSeconds, fEndSeconds; + pSong->GetMusicSampleRange( fStartSeconds, fEndSeconds ); + MUSIC->Load( sSongToPlay ); + MUSIC->Play( true, fStartSeconds, fEndSeconds ); + } +} + + diff --git a/stepmania/src/ScreenSelectMusic.h b/stepmania/src/ScreenSelectMusic.h new file mode 100644 index 0000000000..2eba82e655 --- /dev/null +++ b/stepmania/src/ScreenSelectMusic.h @@ -0,0 +1,74 @@ +/* +----------------------------------------------------------------------------- + File: ScreenSelectMusic.h + + Desc: Select the game mode (single, versus, double). + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "Screen.h" +#include "Sprite.h" +#include "BitmapText.h" +#include "RandomStream.h" +#include "GameConstantsAndTypes.h" +#include "MusicWheel.h" +#include "Banner.h" +#include "TransitionKeepAlive.h" +#include "SongInfoFrame.h" +#include "MenuElements.h" +#include "GrooveRadar.h" +#include "DifficultyIcon.h" +#include "FootMeter.h" + + +class ScreenSelectMusic : public Screen +{ +public: + ScreenSelectMusic(); + virtual ~ScreenSelectMusic(); + + virtual void DrawPrimitives(); + + virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + virtual void HandleScreenMessage( const ScreenMessage SM ); + + void TweenOnScreen(); + void TweenOffScreen(); + + void MenuLeft( PlayerNumber p ); + void MenuRight( PlayerNumber p ); + void EasierDifficulty( PlayerNumber p ); + void HarderDifficulty( PlayerNumber p ); + void MenuStart( PlayerNumber p ); + void MenuBack( PlayerNumber p ); + +protected: + void AfterNotesChange( PlayerNumber p ); + void AfterMusicChange(); + void PlayMusicSample(); + + CArray m_arrayNotes; + int m_iSelection[NUM_PLAYERS]; + + MenuElements m_Menu; + + SongInfoFrame m_SongInfoFrame; + Sprite m_sprDifficultyFrame; + DifficultyIcon m_DifficultyIcon[NUM_PLAYERS]; + GrooveRadar m_GrooveRadar; + Sprite m_sprMeterFrame; + FootMeter m_FootMeter[NUM_PLAYERS]; + MusicWheel m_MusicWheel; + + BitmapText m_textHoldForOptions; + + RandomSample m_soundSelect; + RandomSample m_soundChangeNotes; + + TransitionKeepAlive m_Wipe; + TransitionFade m_Fade; +}; + + diff --git a/stepmania/src/ScreenSelectStyle.cpp b/stepmania/src/ScreenSelectStyle.cpp new file mode 100644 index 0000000000..05b53fcd07 --- /dev/null +++ b/stepmania/src/ScreenSelectStyle.cpp @@ -0,0 +1,507 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: ScreenSelectStyle.cpp + + Desc: Testing the Screen class. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + + +#include "ScreenSelectStyle.h" +#include "ScreenManager.h" +#include "PrefsManager.h" +#include "RageMusic.h" +#include "ScreenTitleMenu.h" +#include "ScreenCaution.h" +#include "GameConstantsAndTypes.h" +#include "ThemeManager.h" +#include "ScreenSelectDifficulty.h" +#include "ScreenSandbox.h" +#include "GameManager.h" +#include "RageLog.h" +#include "AnnouncerManager.h" + + +const CString DANCE_STYLES[] = { + "single", + "versus", + "double", + "couple", + "solo", +}; +const int NUM_DANCE_STYLES = sizeof(DANCE_STYLES)/sizeof(CString); + +const float PAD_X[NUM_STYLE_PADS] = { + CENTER_X-250, + CENTER_X-125, + CENTER_X-20, + CENTER_X+125, + CENTER_X+250, +}; +const float PAD_Y[NUM_STYLE_PADS] = { + CENTER_Y+60, + CENTER_Y-30, + CENTER_Y+70, + CENTER_Y-30, + CENTER_Y+60, +}; +const float DANCER_X[NUM_STYLE_DANCERS] = { + PAD_X[0], + PAD_X[1]-35, + PAD_X[1]+35, + PAD_X[2], + PAD_X[3]-35, + PAD_X[3]+35, + PAD_X[4], +}; +const float DANCER_Y[NUM_STYLE_DANCERS] = { + PAD_Y[0], + PAD_Y[1]+20, + PAD_Y[1]-20, + PAD_Y[2], + PAD_Y[3]+20, + PAD_Y[3]-20, + PAD_Y[4], +}; + +CString TEXT_EXPLANATION1[NUM_DANCE_STYLES] = { + "1 Player", + "2 Players", + "1 Player", + "2 Players", + "1 Player" +}; +CString TEXT_EXPLANATION2[NUM_DANCE_STYLES] = { + "Dance using 4 panels on one pad", + "Each uses 4 panels on one pad", + "Dance using 8 panels on two pads", + "Each uses 4 panels on one pad", + "Dance using 6 panels on one pad" +}; + +const float EXPLANATION1_ZOOM_X = 0.8f; +const float EXPLANATION1_ZOOM_Y = 1; +const float EXPLANATION2_ZOOM_X = 0.5f; +const float EXPLANATION2_ZOOM_Y = 0.7f; + +const float ICON_X = 120; +const float ICON_Y = SCREEN_HEIGHT - 70; + +const float EXPLANATION1_X = ICON_X+110; +const float EXPLANATION1_Y = ICON_Y-16; +const float EXPLANATION2_X = EXPLANATION1_X; +const float EXPLANATION2_Y = ICON_Y+16; + +const float HELP_X = CENTER_X; +const float HELP_Y = SCREEN_HEIGHT-20; + +const float TWEEN_TIME = 0.35f; + +const D3DXCOLOR COLOR_P1_SELECTED = D3DXCOLOR(0.4f,1.0f,0.8f,1); +const D3DXCOLOR COLOR_P2_SELECTED = D3DXCOLOR(1.0f,0.5f,0.2f,1); +const D3DXCOLOR COLOR_P1_NOT_SELECTED = COLOR_P1_SELECTED*0.5f + D3DXCOLOR(0,0,0,0.5f); +const D3DXCOLOR COLOR_P2_NOT_SELECTED = COLOR_P2_SELECTED*0.5f + D3DXCOLOR(0,0,0,0.5f); + + +const ScreenMessage SM_GoToPrevState = ScreenMessage(SM_User + 1); +const ScreenMessage SM_GoToNextState = ScreenMessage(SM_User + 2); +const ScreenMessage SM_UpdateAnimations = ScreenMessage(SM_User + 3); +const ScreenMessage SM_TweenExplanation2 = ScreenMessage(SM_User + 4); + + +ScreenSelectStyle::ScreenSelectStyle() +{ + LOG->WriteLine( "ScreenSelectStyle::ScreenSelectStyle()" ); + + m_iSelectedStyle = 0; // single + + + for( int i=0; iGetPathTo(GRAPHIC_PAD_SINGLE); + break; + case 4: + sPadGraphicPath = THEME->GetPathTo(GRAPHIC_PAD_SOLO); + break; + case 1: + case 2: + case 3: + sPadGraphicPath = THEME->GetPathTo(GRAPHIC_PAD_DOUBLE); + break; + } + + m_sprPad[i].Load( sPadGraphicPath ); + m_sprPad[i].SetXY( PAD_X[i], PAD_Y[i] ); + m_sprPad[i].SetZoom( 1 ); + this->AddActor( &m_sprPad[i] ); + } + + + for( i=0; iGetPathTo(GRAPHIC_DANCER_P1); colorDiffuse = COLOR_P1_SELECTED; SetX(-0.1f); break; + case 1: sDancerGraphicPath = THEME->GetPathTo(GRAPHIC_DANCER_P1); colorDiffuse = COLOR_P1_NOT_SELECTED; SetX(-0.1f); break; + case 2: sDancerGraphicPath = THEME->GetPathTo(GRAPHIC_DANCER_P2); colorDiffuse = COLOR_P2_NOT_SELECTED; SetX( 0.0f); break; + case 3: sDancerGraphicPath = THEME->GetPathTo(GRAPHIC_DANCER_P1); colorDiffuse = COLOR_P1_NOT_SELECTED; SetX(-0.1f); break; + case 4: sDancerGraphicPath = THEME->GetPathTo(GRAPHIC_DANCER_P1); colorDiffuse = COLOR_P1_NOT_SELECTED; SetX(-0.1f); break; + case 5: sDancerGraphicPath = THEME->GetPathTo(GRAPHIC_DANCER_P2); colorDiffuse = COLOR_P2_NOT_SELECTED; SetX( 0.0f); break; + case 6: sDancerGraphicPath = THEME->GetPathTo(GRAPHIC_DANCER_P1); colorDiffuse = COLOR_P1_NOT_SELECTED; SetX(-0.1f); break; + } + + m_sprDancer[i].Load( sDancerGraphicPath ); + m_sprDancer[i].SetDiffuseColor( colorDiffuse ); + m_sprDancer[i].SetVertAlign( Actor::align_top ); + m_sprDancer[i].SetXY( DANCER_X[i], DANCER_Y[i] ); + m_sprDancer[i].SetZoom( 2 ); + m_sprDancer[i].StopAnimating(); + this->AddActor( &m_sprDancer[i] ); + } + + + m_sprStyleIcon.Load( THEME->GetPathTo(GRAPHIC_STYLE_ICONS) ); + m_sprStyleIcon.TurnShadowOff(); + m_sprStyleIcon.StopAnimating(); + m_sprStyleIcon.SetXY( ICON_X, ICON_Y ); + this->AddActor( &m_sprStyleIcon ); + + + m_textExplanation1.Load( THEME->GetPathTo(FONT_HEADER1) ); + m_textExplanation1.SetDiffuseColor( D3DXCOLOR(0,0.7f,0,1) ); + m_textExplanation1.SetXY( EXPLANATION1_X, EXPLANATION1_Y ); + m_textExplanation1.SetZ( -1 ); + m_textExplanation1.SetZoomX( EXPLANATION1_ZOOM_X ); + m_textExplanation1.SetZoomY( EXPLANATION1_ZOOM_Y ); + m_textExplanation1.SetHorizAlign( BitmapText::align_left ); + this->AddActor( &m_textExplanation1 ); + + m_textExplanation2.Load( THEME->GetPathTo(FONT_HEADER1) ); + m_textExplanation2.SetDiffuseColor( D3DXCOLOR(0,0.7f,0,1) ); + m_textExplanation2.SetXY( EXPLANATION2_X, EXPLANATION2_Y ); + m_textExplanation2.SetZ( -1 ); + m_textExplanation2.SetZoomX( EXPLANATION2_ZOOM_X ); + m_textExplanation2.SetZoomY( EXPLANATION2_ZOOM_Y ); + m_textExplanation2.SetHorizAlign( BitmapText::align_left ); + this->AddActor( &m_textExplanation2 ); + + m_Menu.Load( + THEME->GetPathTo(GRAPHIC_SELECT_STYLE_BACKGROUND), + THEME->GetPathTo(GRAPHIC_SELECT_STYLE_TOP_EDGE), + ssprintf("Use %c %c to select, then press NEXT", char(1), char(2) ) + ); + this->AddActor( &m_Menu ); + + m_Fade.SetZ( -2 ); + this->AddActor( &m_Fade ); + + m_soundChange.Load( THEME->GetPathTo(SOUND_SWITCH_STYLE) ); + m_soundSelect.Load( THEME->GetPathTo(SOUND_SELECT) ); + + + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_STYLE_INTRO) ); + + + if( !MUSIC->IsPlaying() ) + { + MUSIC->Load( THEME->GetPathTo(SOUND_MENU_MUSIC) ); + MUSIC->Play( true ); + } + + m_soundChange.PlayRandom(); + TweenOnScreen(); + m_Menu.TweenAllOnScreen(); +} + + +ScreenSelectStyle::~ScreenSelectStyle() +{ + LOG->WriteLine( "ScreenSelectStyle::~ScreenSelectStyle()" ); + +} + +void ScreenSelectStyle::DrawPrimitives() +{ + m_Menu.DrawBottomLayer(); + Screen::DrawPrimitives(); + m_Menu.DrawTopLayer(); +} + +void ScreenSelectStyle::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + LOG->WriteLine( "ScreenSelectStyle::Input()" ); + + if( m_Fade.IsClosing() ) + return; + + Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); // default input handler +} + +void ScreenSelectStyle::HandleScreenMessage( const ScreenMessage SM ) +{ + Screen::HandleScreenMessage( SM ); + + switch( SM ) + { + case SM_GoToPrevState: + MUSIC->Stop(); + SCREENMAN->SetNewScreen( new ScreenTitleMenu ); + break; + case SM_GoToNextState: + SCREENMAN->SetNewScreen( new ScreenSelectDifficulty ); + break; + case SM_TweenExplanation2: + m_textExplanation2.BeginTweening( 0.7f ); + m_textExplanation2.SetTweenZoomX( EXPLANATION2_ZOOM_X ); + break; + case SM_UpdateAnimations: + for( int i=0; im_sCurrentStyle = DANCE_STYLES[m_iSelectedStyle]; + + if( GAME->m_sCurrentStyle == "single" ) + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_STYLE_COMMENT_SINGLE) ); + else if( GAME->m_sCurrentStyle == "versus" ) + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_STYLE_COMMENT_VERSUS) ); + else if( GAME->m_sCurrentStyle == "double" ) + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_STYLE_COMMENT_DOUBLE) ); + else if( GAME->m_sCurrentStyle == "couple" ) + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_STYLE_COMMENT_COUPLE) ); + else if( GAME->m_sCurrentStyle == "solo" ) + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_SELECT_STYLE_COMMENT_SOLO) ); + + + this->ClearMessageQueue(); + + m_Menu.TweenTopEdgeOffScreen(); + + m_soundSelect.PlayRandom(); + + m_Fade.CloseWipingRight( SM_GoToNextState ); + + TweenOffScreen(); +} + +void ScreenSelectStyle::MenuBack( PlayerNumber p ) +{ + MUSIC->Stop(); + + m_Menu.TweenAllOffScreen(); + + m_Fade.CloseWipingLeft( SM_GoToPrevState ); + + TweenOffScreen(); +} + +void ScreenSelectStyle::BeforeChange() +{ + switch( m_iSelectedStyle ) + { + case 0: + m_sprDancer[0].BeginTweening( TWEEN_TIME ); + m_sprDancer[0].SetTweenDiffuseColor( COLOR_P1_NOT_SELECTED ); + break; + case 1: + m_sprDancer[1].BeginTweening( TWEEN_TIME ); + m_sprDancer[1].SetTweenDiffuseColor( COLOR_P1_NOT_SELECTED ); + m_sprDancer[2].BeginTweening( TWEEN_TIME ); + m_sprDancer[2].SetTweenDiffuseColor( COLOR_P2_NOT_SELECTED ); + break; + case 2: + m_sprDancer[3].BeginTweening( TWEEN_TIME ); + m_sprDancer[3].SetTweenDiffuseColor( COLOR_P1_NOT_SELECTED ); + break; + case 3: + m_sprDancer[4].BeginTweening( TWEEN_TIME ); + m_sprDancer[4].SetTweenDiffuseColor( COLOR_P1_NOT_SELECTED ); + m_sprDancer[5].BeginTweening( TWEEN_TIME ); + m_sprDancer[5].SetTweenDiffuseColor( COLOR_P2_NOT_SELECTED ); + break; + case 4: + m_sprDancer[6].BeginTweening( TWEEN_TIME ); + m_sprDancer[6].SetTweenDiffuseColor( COLOR_P1_NOT_SELECTED ); + break; + } + + +} + +void ScreenSelectStyle::AfterChange() +{ + this->ClearMessageQueue(); + + m_textExplanation1.SetText( TEXT_EXPLANATION1[m_iSelectedStyle] ); + m_textExplanation1.SetZoomX( 0 ); + m_textExplanation1.BeginTweening( 0.6f ); + m_textExplanation1.SetTweenZoomX( EXPLANATION1_ZOOM_X ); + + m_textExplanation2.SetText( TEXT_EXPLANATION2[m_iSelectedStyle] ); + m_textExplanation2.StopTweening(); + m_textExplanation2.SetZoomX( 0 ); + + switch( m_iSelectedStyle ) + { + case 0: + m_sprPad[0].BeginTweening( TWEEN_TIME ); + m_sprPad[0].SetTweenDiffuseColor( D3DXCOLOR(1,1,1,1) ); + m_sprDancer[0].BeginTweening( TWEEN_TIME ); + m_sprDancer[0].SetTweenDiffuseColor( COLOR_P1_SELECTED ); + m_sprDancer[0].StartAnimating(); + m_sprStyleIcon.SetState( 0 ); + break; + case 1: + m_sprPad[1].BeginTweening( TWEEN_TIME ); + m_sprPad[1].SetTweenDiffuseColor( D3DXCOLOR(1,1,1,1) ); + m_sprDancer[1].BeginTweening( TWEEN_TIME ); + m_sprDancer[1].SetTweenDiffuseColor( COLOR_P1_SELECTED ); + m_sprDancer[1].StartAnimating(); + m_sprDancer[2].BeginTweening( TWEEN_TIME ); + m_sprDancer[2].SetTweenDiffuseColor( COLOR_P2_SELECTED ); + m_sprDancer[2].StartAnimating(); + m_sprStyleIcon.SetState( 1 ); + break; + case 2: + m_sprPad[2].BeginTweening( TWEEN_TIME ); + m_sprPad[2].SetTweenDiffuseColor( D3DXCOLOR(1,1,1,1) ); + m_sprDancer[3].BeginTweening( TWEEN_TIME ); + m_sprDancer[3].SetTweenDiffuseColor( COLOR_P1_SELECTED ); + m_sprDancer[3].StartAnimating(); + m_sprStyleIcon.SetState( 2 ); + break; + case 3: + m_sprPad[3].BeginTweening( TWEEN_TIME ); + m_sprPad[3].SetTweenDiffuseColor( D3DXCOLOR(1,1,1,1) ); + m_sprDancer[4].BeginTweening( TWEEN_TIME ); + m_sprDancer[4].SetTweenDiffuseColor( COLOR_P1_SELECTED ); + m_sprDancer[4].StartAnimating(); + m_sprDancer[5].BeginTweening( TWEEN_TIME ); + m_sprDancer[5].SetTweenDiffuseColor( COLOR_P2_SELECTED ); + m_sprDancer[5].StartAnimating(); + m_sprStyleIcon.SetState( 3 ); + break; + case 4: + m_sprPad[4].BeginTweening( TWEEN_TIME ); + m_sprPad[4].SetTweenDiffuseColor( D3DXCOLOR(1,1,1,1) ); + m_sprDancer[6].BeginTweening( TWEEN_TIME ); + m_sprDancer[6].SetTweenDiffuseColor( COLOR_P1_SELECTED ); + m_sprDancer[6].StartAnimating(); + m_sprStyleIcon.SetState( 4 ); + break; + } + + this->SendScreenMessage( SM_TweenExplanation2, 1 ); + this->SendScreenMessage( SM_UpdateAnimations, TWEEN_TIME ); +} + +void ScreenSelectStyle::TweenOffScreen() +{ + for( int i=0; iSendScreenMessage( SM_TweenExplanation2, 1 ); + this->SendScreenMessage( SM_UpdateAnimations, TWEEN_TIME ); + +} diff --git a/stepmania/src/ScreenSelectStyle.h b/stepmania/src/ScreenSelectStyle.h new file mode 100644 index 0000000000..ed31f269b2 --- /dev/null +++ b/stepmania/src/ScreenSelectStyle.h @@ -0,0 +1,67 @@ +/* +----------------------------------------------------------------------------- + File: ScreenSelectStyle.h + + Desc: Select the game mode (single, versus, double). + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "Screen.h" +#include "Sprite.h" +#include "BitmapText.h" +#include "TransitionFade.h" +#include "Quad.h" +#include "RandomSample.h" +#include "Quad.h" +#include "TransitionKeepAlive.h" +#include "MenuElements.h" + + +const int NUM_STYLE_DANCERS = 7; // single, versus dancers, double, couple dancers, solo +const int NUM_STYLE_PADS = 5; + + +class ScreenSelectStyle : public Screen +{ +public: + ScreenSelectStyle(); + virtual ~ScreenSelectStyle(); + + virtual void DrawPrimitives(); + virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + virtual void HandleScreenMessage( const ScreenMessage SM ); + + void MenuLeft( PlayerNumber p ); + void MenuRight( PlayerNumber p ); + void MenuStart( PlayerNumber p ); + void MenuBack( PlayerNumber p ); + void TweenOffScreen(); + void TweenOnScreen(); + +private: + void BeforeChange(); + void AfterChange(); + + MenuElements m_Menu; + + Sprite m_sprDancer[NUM_STYLE_DANCERS]; + Sprite m_sprPad[NUM_STYLE_PADS]; + + Sprite m_sprStyleIcon; + + BitmapText m_textExplanation1; + BitmapText m_textExplanation2; + Quad m_rectCursor; + + RandomSample m_soundChange; + RandomSample m_soundSelect; + + int m_iSelectedStyle; + + + TransitionKeepAlive m_Fade; +}; + + diff --git a/stepmania/src/ScreenSongOptions.cpp b/stepmania/src/ScreenSongOptions.cpp new file mode 100644 index 0000000000..70879a1b24 --- /dev/null +++ b/stepmania/src/ScreenSongOptions.cpp @@ -0,0 +1,136 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: ScreenSongOptions.h + + Desc: Select a song. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "ScreenSongOptions.h" +#include +#include "RageTextureManager.h" +#include "RageUtil.h" +#include "RageMusic.h" +#include "ScreenManager.h" +#include "ScreenSelectMusic.h" +#include "ScreenGameplay.h" +#include "GameConstantsAndTypes.h" +#include "ScreenPlayerOptions.h" +#include "RageLog.h" + + + +OptionLineData g_SongOptionsLines[] = { + { "Fail", 3, {"ARCADE","END OF SONGMAN","OFF"} }, + { "Assist", 2, {"OFF","TICK"} }, + { "Rate", 7, {"70%","80%","90%","100%","110%","120%","130%"} }, + { "Pitch", 7, {"-1.5","-1","-0.5","+0","+0.5","+1","+1.5"} }, + { "Bars", 2, {"OFF","ON"} }, +}; +const int NUM_SONG_OPTIONS_LINES = sizeof(g_SongOptionsLines)/sizeof(OptionLineData); + +enum { + SO_FAIL = 0, + SO_ASSIST, + SO_RATE, + SO_PITCH, + SO_BARS +}; + + + +ScreenSongOptions::ScreenSongOptions() : + ScreenOptions( + THEME->GetPathTo(GRAPHIC_SONG_OPTIONS_BACKGROUND), + THEME->GetPathTo(GRAPHIC_SONG_OPTIONS_TOP_EDGE) + ) +{ + LOG->WriteLine( "ScreenSongOptions::ScreenSongOptions()" ); + + Init( INPUTMODE_BOTH, + g_SongOptionsLines, + NUM_SONG_OPTIONS_LINES + ); +} + +void ScreenSongOptions::ImportOptions() +{ + SongOptions &so = PREFS->m_SongOptions; + + m_iSelectedOption[0][SO_FAIL] = so.m_FailType; + m_iSelectedOption[0][SO_ASSIST] = so.m_AssistType; + + if( so.m_fMusicRate == 0.70f ) m_iSelectedOption[0][SO_RATE] = 0; + else if( so.m_fMusicRate == 0.80f ) m_iSelectedOption[0][SO_RATE] = 1; + else if( so.m_fMusicRate == 0.90f ) m_iSelectedOption[0][SO_RATE] = 2; + else if( so.m_fMusicRate == 1.00f ) m_iSelectedOption[0][SO_RATE] = 3; + else if( so.m_fMusicRate == 1.10f ) m_iSelectedOption[0][SO_RATE] = 4; + else if( so.m_fMusicRate == 1.20f ) m_iSelectedOption[0][SO_RATE] = 5; + else if( so.m_fMusicRate == 1.30f ) m_iSelectedOption[0][SO_RATE] = 6; + else m_iSelectedOption[0][SO_RATE] = 3; + + if( so.m_fMusicRate == -1.5f ) m_iSelectedOption[0][SO_PITCH] = 0; + else if( so.m_fMusicRate == -1.0f ) m_iSelectedOption[0][SO_PITCH] = 1; + else if( so.m_fMusicRate == -0.5f ) m_iSelectedOption[0][SO_PITCH] = 2; + else if( so.m_fMusicRate == 0.0f ) m_iSelectedOption[0][SO_PITCH] = 3; + else if( so.m_fMusicRate == 0.5f ) m_iSelectedOption[0][SO_PITCH] = 4; + else if( so.m_fMusicRate == 1.0f ) m_iSelectedOption[0][SO_PITCH] = 5; + else if( so.m_fMusicRate == 1.5f ) m_iSelectedOption[0][SO_PITCH] = 6; + else m_iSelectedOption[0][SO_PITCH] = 3; + + m_iSelectedOption[0][SO_BARS] = so.m_bShowMeasureBars ? 1 : 0; +} + +void ScreenSongOptions::ExportOptions() +{ + SongOptions &so = PREFS->m_SongOptions; + + so.m_FailType = (SongOptions::FailType)m_iSelectedOption[0][SO_FAIL]; + so.m_AssistType = (SongOptions::AssistType)m_iSelectedOption[0][SO_ASSIST]; + + switch( m_iSelectedOption[0][SO_RATE] ) + { + case 0: so.m_fMusicRate = 0.70f; break; + case 1: so.m_fMusicRate = 0.80f; break; + case 2: so.m_fMusicRate = 0.90f; break; + case 3: so.m_fMusicRate = 1.00f; break; + case 4: so.m_fMusicRate = 1.10f; break; + case 5: so.m_fMusicRate = 1.20f; break; + case 6: so.m_fMusicRate = 1.30f; break; + default: ASSERT( false ); + } + + switch( m_iSelectedOption[0][SO_PITCH] ) + { + case 0: so.m_fMusicPitch = -1.5f; break; + case 1: so.m_fMusicPitch = -1.0f; break; + case 2: so.m_fMusicPitch = -0.5f; break; + case 3: so.m_fMusicPitch = 0.0f; break; + case 4: so.m_fMusicPitch = 0.5f; break; + case 5: so.m_fMusicPitch = 1.0f; break; + case 6: so.m_fMusicPitch = 1.5f; break; + default: ASSERT( false ); + } + + so.m_bShowMeasureBars = m_iSelectedOption[0][SO_BARS] ? true : false; + +} + +void ScreenSongOptions::GoToPrevState() +{ + SCREENMAN->SetNewScreen( new ScreenPlayerOptions ); +} + +void ScreenSongOptions::GoToNextState() +{ + MUSIC->Stop(); + + SCREENMAN->SetNewScreen( new ScreenGameplay ); +} + + + + diff --git a/stepmania/src/ScreenSongOptions.h b/stepmania/src/ScreenSongOptions.h new file mode 100644 index 0000000000..cd775c4d89 --- /dev/null +++ b/stepmania/src/ScreenSongOptions.h @@ -0,0 +1,42 @@ +/* +----------------------------------------------------------------------------- + File: ScreenSongOptions.h + + Desc: Select a song. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ +#ifndef _ScreenSongOptions_H_ +#define _ScreenSongOptions_H_ + + + +#include "Screen.h" +#include "ScreenOptions.h" +#include "Sprite.h" +#include "BitmapText.h" +#include "RandomSample.h" +#include "TransitionFade.h" +#include "Quad.h" + + + +class ScreenSongOptions : public ScreenOptions +{ +public: + ScreenSongOptions(); + +private: + void ImportOptions(); + void ExportOptions(); + + void GoToNextState(); + void GoToPrevState(); +}; + + + + + +#endif \ No newline at end of file diff --git a/stepmania/src/ScreenStage.cpp b/stepmania/src/ScreenStage.cpp new file mode 100644 index 0000000000..e9327febfd --- /dev/null +++ b/stepmania/src/ScreenStage.cpp @@ -0,0 +1,129 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + Class: ScreenStage + + Desc: See header. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "ScreenStage.h" +#include "ScreenManager.h" +#include "PrefsManager.h" +#include "ThemeManager.h" +#include "RageLog.h" +#include "GameConstantsAndTypes.h" +#include "BitmapText.h" +#include "TransitionFadeWipe.h" +#include "TransitionFade.h" +#include "ScreenSelectMusic.h" +#include "ScreenGameplay.h" +#include "SongManager.h" +#include "Sprite.h" +#include "AnnouncerManager.h" + +const ScreenMessage SM_StartFadingOut = ScreenMessage(SM_User + 1); +const ScreenMessage SM_LoadNoteData = ScreenMessage(SM_User + 2); // this is a super-hack. We'll load the note data from cache while the message is displaying +const ScreenMessage SM_GoToNextState = ScreenMessage(SM_User + 3); + +const float BASE_X = CENTER_X; +const float BASE_Y = CENTER_Y + 36; +const float BASE_HEIGHT = 6; + +ScreenStage::ScreenStage( bool bTryExtraStage ) +{ + m_bTryExtraStage = false; + + m_ptextStage = new BitmapText(); + m_ptextStage->Load( THEME->GetPathTo(FONT_STAGE) ); + m_ptextStage->TurnShadowOff(); + if( bTryExtraStage ) + { + m_ptextStage->SetText( "Try Extra Stage!" ); + m_ptextStage->SetDiffuseColor( D3DXCOLOR(1,0.1f,0.1f,1) ); + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_EXTRA) ); + } + else // !bTryExtraStage + { + int iStageNo = PREFS->GetStageNumber(); + bool bFinal = PREFS->IsFinalStage(); + + CString sStagePrefix = PREFS->GetStageText(); + m_ptextStage->SetText( sStagePrefix + " Stage" ); + m_ptextStage->SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); + + if( bFinal ) + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_FINAL) ); + else + { + switch( iStageNo ) + { + case 1: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_1) ); break; + case 2: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_2) ); break; + case 3: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_3) ); break; + case 4: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_4) ); break; + case 5: SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_STAGE_5) ); break; + } + } + } + m_ptextStage->SetXY( BASE_X, BASE_Y ); + m_ptextStage->SetVertAlign( Actor::align_top ); + m_ptextStage->SetZoomX( 2 ); + m_ptextStage->SetZoomY( 0 ); + m_ptextStage->BeginTweeningQueued( 0.6f ); // sleep + m_ptextStage->BeginTweeningQueued( 0.5f ); // sleep + m_ptextStage->SetTweenZoom( 2 ); + m_ptextStage->SetTweenXY( CENTER_X, CENTER_Y ); + this->AddActor( m_ptextStage ); + + + m_psprUnderscore = new Sprite; + m_psprUnderscore->Load( THEME->GetPathTo(GRAPHIC_STAGE_UNDERSCORE) ); + m_psprUnderscore->SetXY( BASE_X, BASE_Y ); + m_psprUnderscore->SetZoomX( 0 ); + m_psprUnderscore->SetDiffuseColor( bTryExtraStage ? D3DXCOLOR(1,0.1f,0.1f,1) : D3DXCOLOR(1,1,1,1) ); + m_psprUnderscore->BeginTweeningQueued( 0.4f ); // open + float fDestZoom = m_ptextStage->GetWidestLineWidthInSourcePixels() * m_ptextStage->GetZoomX() / m_psprUnderscore->GetUnzoomedWidth(); + m_psprUnderscore->SetTweenZoomX( fDestZoom ); + m_psprUnderscore->BeginTweeningQueued( 0.1f ); // sleep + m_psprUnderscore->BeginTweeningQueued( 0.4f ); // close + m_psprUnderscore->SetTweenZoomX( 0 ); + this->AddActor( m_psprUnderscore ); + + + m_pWipe = new TransitionFadeWipe; + m_pWipe->OpenWipingRight(); + this->AddActor( m_ptextStage ); + + this->SendScreenMessage( SM_LoadNoteData, 1 ); + this->SendScreenMessage( SM_StartFadingOut, 3 ); +} + + +ScreenStage::~ScreenStage() +{ + delete m_ptextStage; + delete m_pWipe; +} + +void ScreenStage::HandleScreenMessage( const ScreenMessage SM ) +{ + switch( SM ) + { + case SM_StartFadingOut: + m_ptextStage->BeginTweening( 0.8f ); + m_ptextStage->SetTweenDiffuseColor( D3DXCOLOR(1,1,1,0) ); + this->SendScreenMessage( SM_GoToNextState, 0.8f ); + break; + case SM_GoToNextState: + SCREENMAN->SetNewScreen( new ScreenGameplay ); + break; + case SM_LoadNoteData: + SONGMAN->m_pCurSong->LoadFromCacheFile( true ); // load note data + break; + } +} + diff --git a/stepmania/src/ScreenStage.h b/stepmania/src/ScreenStage.h new file mode 100644 index 0000000000..c035813292 --- /dev/null +++ b/stepmania/src/ScreenStage.h @@ -0,0 +1,38 @@ +/* +----------------------------------------------------------------------------- + Class: ScreenStage + + Desc: Shows the stage number. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "Screen.h" + +class BitmapText; +class Sprite; +class TransitionFadeWipe; + + +class ScreenStage : public Screen +{ +public: + ScreenStage(); + ScreenStage( bool bTryExtraStage ); + ~ScreenStage(); + + virtual void HandleScreenMessage( const ScreenMessage SM ); + +private: + bool m_bTryExtraStage; + + BitmapText* m_ptextStage; + + Sprite* m_psprUnderscore; + + TransitionFadeWipe* m_pWipe; +}; + + diff --git a/stepmania/src/ScreenTitleMenu.cpp b/stepmania/src/ScreenTitleMenu.cpp new file mode 100644 index 0000000000..0b53058a1f --- /dev/null +++ b/stepmania/src/ScreenTitleMenu.cpp @@ -0,0 +1,336 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + File: ScreenTitleMenu.h + + Desc: The main title screen and menu. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "ScreenTitleMenu.h" +#include "ScreenManager.h" +#include "ScreenCaution.h" +#include "ScreenMapInstruments.h" +#include "ScreenGameOptions.h" +#include "ScreenGraphicOptions.h" +#include "ScreenSynchronizeMenu.h" +#include "ScreenEdit.h" +#include "GameConstantsAndTypes.h" +#include "RageUtil.h" +#include "StepMania.h" +#include "ThemeManager.h" +#include "ScreenEditMenu.h" +#include "ScreenSelectStyle.h" +#include "ScreenSelectGame.h" +#include "RageLog.h" +#include "SongManager.h" +#include "AnnouncerManager.h" + + +// +// Defines specific to ScreenTitleMenu +// + +const CString CHOICE_TEXT[ScreenTitleMenu::NUM_TITLE_MENU_CHOICES] = { + "GAME MODE", + "NONSTOP MODE", + "ENDLESS MODE", + "ONI MODE", + "SELECT GAME", + "MAP INSTRUMENTS", + "GAME OPTIONS", + "GRAPHIC OPTIONS", + "SYNCHRONIZE", + "EDIT/RECORD", + "EXIT", +}; + +const float CHOICES_START_Y = 52; +const float CHOICES_GAP_Y = 34; + +const float HELP_X = CENTER_X; +const float HELP_Y = SCREEN_HEIGHT-55; + + +const ScreenMessage SM_PlayAttract = ScreenMessage(SM_User+1); +const ScreenMessage SM_GoToCaution = ScreenMessage(SM_User+2); +const ScreenMessage SM_GoToSelectStyle = ScreenMessage(SM_User+3); +const ScreenMessage SM_GoToSelectGame = ScreenMessage(SM_User+4); +const ScreenMessage SM_GoToMapInstruments = ScreenMessage(SM_User+5); +const ScreenMessage SM_GoToGameOptions = ScreenMessage(SM_User+6); +const ScreenMessage SM_GoToGraphicOptions = ScreenMessage(SM_User+7); +const ScreenMessage SM_GoToSynchronize = ScreenMessage(SM_User+9); +const ScreenMessage SM_GoToEdit = ScreenMessage(SM_User+10); +const ScreenMessage SM_DoneOpening = ScreenMessage(SM_User+11); + +ScreenTitleMenu::ScreenTitleMenu() +{ + LOG->WriteLine( "ScreenTitleMenu::ScreenTitleMenu()" ); + + int i; + + m_sprBG.Load( THEME->GetPathTo(GRAPHIC_TITLE_MENU_BACKGROUND) ); + m_sprBG.StretchTo( CRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT) ); + m_sprBG.SetDiffuseColor( D3DXCOLOR(0.6f,0.6f,0.6f,1) ); + m_sprBG.TurnShadowOff(); + this->AddActor( &m_sprBG ); + + m_sprLogo.Load( THEME->GetPathTo(GRAPHIC_TITLE_MENU_LOGO) ); + m_sprLogo.SetXY( CENTER_X, CENTER_Y ); + m_sprLogo.SetAddColor( D3DXCOLOR(1,1,1,1) ); + m_sprLogo.SetZoomY( 0 ); + m_sprLogo.BeginTweeningQueued( 0.5f ); + m_sprLogo.BeginTweeningQueued( 0.5f ); + m_sprLogo.SetEffectGlowing(1, D3DXCOLOR(1,1,1,0.1f), D3DXCOLOR(1,1,1,0.3f) ); + m_sprLogo.SetTweenZoom( 1 ); + this->AddActor( &m_sprLogo ); + + m_textHelp.Load( THEME->GetPathTo(FONT_NORMAL) ); + m_textHelp.SetText( ssprintf("Use %c %c to select, then press NEXT", char(3), char(4)) ); + m_textHelp.SetXY( CENTER_X, SCREEN_BOTTOM - 30 ); + m_textHelp.SetZoom( 0.5f ); + m_textHelp.SetEffectBlinking(); + m_textHelp.SetShadowLength( 2 ); + this->AddActor( &m_textHelp ); + + + m_textVersion.Load( THEME->GetPathTo(FONT_NORMAL) ); + m_textVersion.SetHorizAlign( Actor::align_right ); + m_textVersion.SetText( "v3.0 compatibility test" ); + m_textVersion.SetDiffuseColor( D3DXCOLOR(0.6f,0.6f,0.6f,1) ); // light gray + m_textVersion.SetXY( SCREEN_RIGHT-16, SCREEN_BOTTOM-20 ); + m_textVersion.SetZoom( 0.5f ); + this->AddActor( &m_textVersion ); + + + m_textSongs.Load( THEME->GetPathTo(FONT_NORMAL) ); + m_textSongs.SetHorizAlign( Actor::align_left ); + m_textSongs.SetText( ssprintf("Found %d Songs", SONGMAN->m_pSongs.GetSize()) ); + m_textSongs.SetDiffuseColor( D3DXCOLOR(0.6f,0.6f,0.6f,1) ); // light gray + m_textSongs.SetXY( SCREEN_LEFT+16, SCREEN_HEIGHT-20 ); + m_textSongs.SetZoom( 0.5f ); + this->AddActor( &m_textSongs ); + + + for( i=0; i< NUM_TITLE_MENU_CHOICES; i++ ) + { + m_textChoice[i].Load( THEME->GetPathTo(FONT_HEADER1) ); + m_textChoice[i].SetText( CHOICE_TEXT[i] ); + m_textChoice[i].SetXY( CENTER_X, CHOICES_START_Y + i*CHOICES_GAP_Y ); + m_textChoice[i].SetShadowLength( 5 ); + this->AddActor( &m_textChoice[i] ); + } + + m_Fade.SetClosed(); + m_Fade.OpenWipingRight( SM_DoneOpening ); + this->AddActor( &m_Fade ); + + + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_TITLE_MENU_GAME_NAME) ); + + m_soundChange.Load( THEME->GetPathTo(SOUND_TITLE_CHANGE) ); + m_soundSelect.Load( THEME->GetPathTo(SOUND_SELECT) ); + m_soundInvalid.Load( THEME->GetPathTo(SOUND_INVALID) ); + + for( i=0; i<3000; i++ ) + this->SendScreenMessage( SM_PlayAttract, (float)15+i*15 ); + + + m_TitleMenuChoice = CHOICE_GAME_MODE; + GainFocus( m_TitleMenuChoice ); + +/* + MUSIC->Stop(); + + // find a random song and play it + if( GAMEINFO->m_pSongs.GetSize() > 0 ) + { + for( i=0; i<50; i++ ) // try 50 times to find a song with music + { + int iRandomSongIndex = rand() % GAMEINFO->m_pSongs.GetSize(); + Song* pSong = GAMEINFO->m_pSongs[iRandomSongIndex]; + if( pSong->HasMusic() ) + { + MUSIC->Load( pSong->GetMusicPath() ); + MUSIC->Play(); + break; + } + } + } +*/ + + MUSIC->Stop(); + + //this->SendScreenMessage( SM_TimeToFadeOut, 30.0 ); +} + + +ScreenTitleMenu::~ScreenTitleMenu() +{ + LOG->WriteLine( "ScreenTitleMenu::~ScreenTitleMenu()" ); +} + + +void ScreenTitleMenu::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + LOG->WriteLine( "ScreenTitleMenu::Input()" ); + + if( m_Fade.IsClosing() ) + return; + + Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); +} + +void ScreenTitleMenu::HandleScreenMessage( const ScreenMessage SM ) +{ + switch( SM ) + { + case SM_DoneOpening: + if( PREFS->m_GameOptions.m_bAnnouncer ) + m_soundTitle.PlayRandom(); + break; + case SM_PlayAttract: + SOUND->PlayOnceStreamedFromDir( ANNOUNCER->GetPathTo(ANNOUNCER_TITLE_MENU_ATTRACT) ); + break; + case SM_GoToCaution: + SCREENMAN->SetNewScreen( new ScreenCaution ); + break; + case SM_GoToSelectStyle: + SCREENMAN->SetNewScreen( new ScreenSelectStyle ); + break; + case SM_GoToSelectGame: + SCREENMAN->SetNewScreen( new ScreenSelectGame ); + break; + case SM_GoToMapInstruments: + SCREENMAN->SetNewScreen( new ScreenMapInstruments ); + break; + case SM_GoToGameOptions: + SCREENMAN->SetNewScreen( new ScreenGameOptions ); + break; + case SM_GoToGraphicOptions: + SCREENMAN->SetNewScreen( new ScreenGraphicOptions ); + break; + case SM_GoToSynchronize: + SCREENMAN->SetNewScreen( new ScreenSynchronizeMenu ); + break; + case SM_GoToEdit: + SCREENMAN->SetNewScreen( new ScreenEditMenu ); + break; + } +} + + +void ScreenTitleMenu::LoseFocus( int iChoiceIndex ) +{ + m_soundChange.PlayRandom(); + + m_textChoice[iChoiceIndex].SetEffectNone(); + m_textChoice[iChoiceIndex].SetAddColor( D3DXCOLOR(0,0,0,0) ); + m_textChoice[iChoiceIndex].SetDiffuseColor( D3DXCOLOR(1,1,1,1) ); + m_textChoice[iChoiceIndex].BeginTweening( 0.3f ); + m_textChoice[iChoiceIndex].SetTweenZoom( 0.9f ); + +} + +void ScreenTitleMenu::GainFocus( int iChoiceIndex ) +{ + m_textChoice[iChoiceIndex].SetDiffuseColor( D3DXCOLOR(0.5f,1,0.5f,1) ); + m_textChoice[iChoiceIndex].BeginTweening( 0.3f ); + m_textChoice[iChoiceIndex].SetTweenZoom( 1.2f ); + m_textChoice[iChoiceIndex].SetEffectCamelion( 2.5f, D3DXCOLOR(0.5f,1,0.5f,1), D3DXCOLOR(0.3f,0.6f,0.3f,1) ); +} + +void ScreenTitleMenu::MenuUp( PlayerNumber p ) +{ + LoseFocus( m_TitleMenuChoice ); + + if( m_TitleMenuChoice == 0 ) // wrap around + m_TitleMenuChoice = (ScreenTitleMenu::TitleMenuChoice)((int)NUM_TITLE_MENU_CHOICES); + + m_TitleMenuChoice = TitleMenuChoice( m_TitleMenuChoice-1 ); + + GainFocus( m_TitleMenuChoice ); +} + + +void ScreenTitleMenu::MenuDown( PlayerNumber p ) +{ + LoseFocus( m_TitleMenuChoice ); + + if( m_TitleMenuChoice == (int)ScreenTitleMenu::NUM_TITLE_MENU_CHOICES-1 ) + m_TitleMenuChoice = (TitleMenuChoice)-1; // wrap around + + m_TitleMenuChoice = TitleMenuChoice( m_TitleMenuChoice+1 ); + + GainFocus( m_TitleMenuChoice ); +} + + +void ScreenTitleMenu::MenuStart( PlayerNumber p ) +{ + + switch( m_TitleMenuChoice ) + { + case CHOICE_GAME_MODE: + m_soundSelect.PlayRandom(); + if( PREFS->m_GameOptions.m_bShowCaution ) + m_Fade.CloseWipingRight( SM_GoToCaution ); + else + m_Fade.CloseWipingRight( SM_GoToSelectStyle ); + return; + case CHOICE_SELECT_GAME: + m_soundSelect.PlayRandom(); + m_Fade.CloseWipingRight( SM_GoToSelectGame ); + return; + case CHOICE_MAP_INSTRUMENTS: + m_soundSelect.PlayRandom(); + m_Fade.CloseWipingRight( SM_GoToMapInstruments ); + return; + case CHOICE_GAME_OPTIONS: + m_soundSelect.PlayRandom(); + m_Fade.CloseWipingRight( SM_GoToGameOptions ); + return; + case CHOICE_GRAPHIC_OPTIONS: + m_soundSelect.PlayRandom(); + m_Fade.CloseWipingRight( SM_GoToGraphicOptions ); + return; + case CHOICE_SYNCHRONIZE: + m_soundSelect.PlayRandom(); + m_Fade.CloseWipingRight( SM_GoToSynchronize ); + return; + case CHOICE_NONSTOP_MODE: + case CHOICE_ENDLESS_MODE: + case CHOICE_ONI_MODE: + m_soundInvalid.PlayRandom(); + return; + case CHOICE_EDIT: + m_soundSelect.PlayRandom(); + m_Fade.CloseWipingRight( SM_GoToEdit ); + return; +/* case CHOICE_HELP: + m_soundSelect.PlayRandom(); + PREFS->m_bWindowed = false; + ApplyGraphicOptions(); + GotoURL( "Docs/index.htm" ); + return; + case CHOICE_CHECK_FOR_UPDATE: + m_soundSelect.PlayRandom(); + PREFS->m_bWindowed = false; + ApplyGraphicOptions(); + GotoURL( "http://www.stepmania.com" ); + return; + */ + case CHOICE_EXIT: + m_soundSelect.PlayRandom(); + PostQuitMessage(0); + return; + } +} + +void ScreenTitleMenu::MenuBack( PlayerNumber p ) +{ + //m_Fade.CloseWipingLeft( SM_GoToIntroCovers ); +} + diff --git a/stepmania/src/ScreenTitleMenu.h b/stepmania/src/ScreenTitleMenu.h new file mode 100644 index 0000000000..671d288b69 --- /dev/null +++ b/stepmania/src/ScreenTitleMenu.h @@ -0,0 +1,72 @@ +/* +----------------------------------------------------------------------------- + File: ScreenTitleMenu.h + + Desc: The main title screen and menu. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. +----------------------------------------------------------------------------- +*/ + +#include "Screen.h" +#include "Sprite.h" +#include "ColorNote.h" +#include "BitmapText.h" +#include "TransitionFade.h" +#include "RandomSample.h" +#include "RandomStream.h" + + + +class ScreenTitleMenu : public Screen +{ +public: + ScreenTitleMenu(); + virtual ~ScreenTitleMenu(); + + virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + virtual void HandleScreenMessage( const ScreenMessage SM ); + + enum TitleMenuChoice { + CHOICE_GAME_MODE = 0, + CHOICE_NONSTOP_MODE, + CHOICE_ENDLESS_MODE, + CHOICE_ONI_MODE, + CHOICE_SELECT_GAME, + CHOICE_MAP_INSTRUMENTS, + CHOICE_GAME_OPTIONS, + CHOICE_GRAPHIC_OPTIONS, + CHOICE_SYNCHRONIZE, + CHOICE_EDIT, + CHOICE_EXIT, + NUM_TITLE_MENU_CHOICES // leave this at the end! + }; + +private: + void GainFocus( int iChoiceIndex ); + void LoseFocus( int iChoiceIndex ); + void MenuUp( PlayerNumber p ); + void MenuDown( PlayerNumber p ); + void MenuBack( PlayerNumber p ); + void MenuStart( PlayerNumber p ); + + TitleMenuChoice m_TitleMenuChoice; + + Sprite m_sprBG; + Sprite m_sprLogo; + BitmapText m_textHelp; + BitmapText m_textVersion; + BitmapText m_textSongs; + BitmapText m_textChoice[NUM_TITLE_MENU_CHOICES]; + + TransitionFade m_Fade; + + RandomStream m_soundTitle; + RandomStream m_soundAttract; + RandomSample m_soundChange; + RandomSample m_soundSelect; + RandomSample m_soundInvalid; +}; + + + diff --git a/stepmania/src/Sprite.cpp b/stepmania/src/Sprite.cpp index 18a8aac518..d06439423f 100644 --- a/stepmania/src/Sprite.cpp +++ b/stepmania/src/Sprite.cpp @@ -76,7 +76,8 @@ bool Sprite::LoadFromSpriteFile( CString sSpritePath, bool bForceReload, int iMi if( !ini.ReadFile() ) FatalError( ssprintf("Error opening Sprite file '%s'.", m_sSpritePath) ); - CString sTextureFile = ini.GetValue( "Sprite", "Texture" ); + CString sTextureFile; + ini.GetValue( "Sprite", "Texture", sTextureFile ); if( sTextureFile == "" ) FatalError( ssprintf("Error reading value 'Texture' from %s.", m_sSpritePath) ); @@ -97,11 +98,15 @@ bool Sprite::LoadFromSpriteFile( CString sSpritePath, bool bForceReload, int iMi CString sFrameKey( CString("Frame") + sStateNo ); CString sDelayKey( CString("Delay") + sStateNo ); - m_iStateToFrame[i] = ini.GetValueI( "Sprite", sFrameKey ); + m_iStateToFrame[i] = 0; + if( !ini.GetValueI( "Sprite", sFrameKey, m_iStateToFrame[i] ) ) + break; if( m_iStateToFrame[i] >= m_pTexture->GetNumFrames() ) - FatalError( ssprintf("In '%s', %s is %d, but the texture %s only has %d frames.", - m_sSpritePath, sFrameKey, m_iStateToFrame[i], sTexturePath, m_pTexture->GetNumFrames()) ); - m_fDelay[i] = (float)ini.GetValueF( "Sprite", sDelayKey ); + FatalError( "In '%s', %s is %d, but the texture %s only has %d frames.", + m_sSpritePath, sFrameKey, m_iStateToFrame[i], sTexturePath, m_pTexture->GetNumFrames() ); + m_fDelay[i] = 0.2f; + if( !ini.GetValueF( "Sprite", sDelayKey, m_fDelay[i] ) ) + break; if( m_iStateToFrame[i] == 0 && m_fDelay[i] > -0.00001f && m_fDelay[i] < 0.00001f ) // both values are empty break; @@ -345,8 +350,8 @@ void Sprite::DrawPrimitives() void Sprite::SetState( int iNewState ) { ASSERT( iNewState >= 0 && iNewState < m_iNumStates ); - if( iNewState < 0 ) - iNewState = 0; + if( iNewState < 0 ) iNewState = 0; + else if( iNewState >= m_iNumStates ) iNewState = m_iNumStates-1; m_iCurState = iNewState; m_fSecsIntoState = 0.0; } diff --git a/stepmania/src/StepMania.cpp b/stepmania/src/StepMania.cpp index 54c516d498..cda2ec517d 100644 --- a/stepmania/src/StepMania.cpp +++ b/stepmania/src/StepMania.cpp @@ -759,11 +759,11 @@ void ApplyGraphicOptions() bool bWindowed = PREFS->m_bWindowed; CString sProfileName = pGPO->m_szProfileName; - DWORD dwWidth = pGPO->m_dwWidth; - DWORD dwHeight = pGPO->m_dwHeight; - DWORD dwDisplayBPP = pGPO->m_dwDisplayColor; - DWORD dwTextureBPP = pGPO->m_dwTextureColor; - DWORD dwMaxTextureSize = pGPO->m_dwMaxTextureSize; + DWORD dwWidth = pGPO->m_iWidth; + DWORD dwHeight = pGPO->m_iHeight; + DWORD dwDisplayBPP = pGPO->m_iDisplayColor; + DWORD dwTextureBPP = pGPO->m_iTextureColor; + DWORD dwMaxTextureSize = pGPO->m_iMaxTextureSize; DWORD dwFlags = 0; // not used anymore // @@ -789,7 +789,7 @@ void ApplyGraphicOptions() dwHeight = 240; if( !DISPLAY->SwitchDisplayMode( bWindowed, dwWidth, dwHeight, dwDisplayBPP, dwFlags ) ) { - FatalError( "Tried every possible display mode, and couldn't change to any of them." ); + FatalError( "Tried every possible display mode, and couldn't find one that works." ); } } } diff --git a/stepmania/src/StepMania.vcproj b/stepmania/src/StepMania.vcproj index 7cf99ccda0..3b74b80d4d 100644 --- a/stepmania/src/StepMania.vcproj +++ b/stepmania/src/StepMania.vcproj @@ -260,12 +260,6 @@ - - - - diff --git a/stepmania/src/StyleDef.cpp b/stepmania/src/StyleDef.cpp index e944d14dfb..f85de15728 100644 --- a/stepmania/src/StyleDef.cpp +++ b/stepmania/src/StyleDef.cpp @@ -34,23 +34,24 @@ StyleDef::StyleDef( GameDef* pGameDef, CString sStyleFilePath ) if( !ini.ReadFile() ) FatalError( "Error reading style definition file '%s'.", sStyleFilePath ); - - if( ini.GetValue( "Style", "Name" ) != m_sName ) + CString sStyleName; + ini.GetValue( "Style", "Name", sStyleName ); + if( sStyleName != m_sName ) FatalError( "Style name in '%s' doesn't match the file name.", sStyleFilePath ); - m_sDescription = ini.GetValue( "Style", "Description" ); + ini.GetValue( "Style", "Name", m_sDescription ); if( m_sDescription == "" ) FatalError( "Invalid value for Description in '%s'.", sStyleFilePath ); - m_sReadsTag = ini.GetValue( "Style", "ReadsTag" ); + ini.GetValue( "Style", "ReadsTag", m_sReadsTag ); if( m_sReadsTag == "" ) FatalError( "Invalid value for ReadsTag in '%s'.", sStyleFilePath ); - m_iNumPlayers = ini.GetValueI( "Style", "NumPlayers" ); + ini.GetValueI( "Style", "NumPlayers", m_iNumPlayers ); if( m_iNumPlayers < 1 || m_iNumPlayers > 2 ) FatalError( "Invalid value for NumPlayers in '%s'.", sStyleFilePath ); - m_iColsPerPlayer = ini.GetValueI( "Style", "ColsPerPlayer" ); + ini.GetValueI( "Style", "ColsPerPlayer", m_iColsPerPlayer ); if( m_iColsPerPlayer < 1 || m_iColsPerPlayer > MAX_COLS_PER_PLAYER ) FatalError( "Invalid value for ColsPerPlayer in '%s'.", sStyleFilePath ); @@ -63,7 +64,8 @@ StyleDef::StyleDef( GameDef* pGameDef, CString sStyleFilePath ) CString sValueName = ssprintf( "P%01dCol%02d", p+1, c+1 ); - CString sColumnInfo = ini.GetValue( "Style", sValueName ); // should look like "TRACK08,INSTRUMENT02,right,576" + CString sColumnInfo; + ini.GetValue( "Style", sValueName, sColumnInfo ); // should look like "TRACK08,INSTRUMENT02,right,576" if( sColumnInfo == "" ) FatalError( "Value '%s' missing in file '%s'.", sValueName, sStyleFilePath ); @@ -107,13 +109,14 @@ StyleDef::StyleDef( GameDef* pGameDef, CString sStyleFilePath ) colInfo.iX = atoi( arrayColumnInfo[3] ); } } - m_iColsPerPlayer = ini.GetValueI( "Style", "ColsPerPlayer" ); + ini.GetValueI( "Style", "ColsPerPlayer", m_iColsPerPlayer ); if( m_iColsPerPlayer < 1 || m_iColsPerPlayer > MAX_COLS_PER_PLAYER ) FatalError( "Invalid value for ColsPerPlayer in '%s'.", sStyleFilePath ); - CString sColDrawOrder = ini.GetValue( "Style", "ColDrawOrder" ); // should look like "COL01,COL02,COL03,COL04" + CString sColDrawOrder; + ini.GetValue( "Style", "ColDrawOrder", sColDrawOrder ); // should look like "COL01,COL02,COL03,COL04" // replace the constants with their corresponding integer literals sColDrawOrder.Replace( "COL01", "0" ); diff --git a/stepmania/src/ThemeManager.cpp b/stepmania/src/ThemeManager.cpp index df569f1f64..2bf08cca70 100644 --- a/stepmania/src/ThemeManager.cpp +++ b/stepmania/src/ThemeManager.cpp @@ -155,17 +155,6 @@ CString ThemeManager::GetPathTo( ThemeElement te ) case GRAPHIC_SELECT_DIFFICULTY_ARROW_P1: sAssetPrefix = "Graphics\\select difficulty arrow p1"; break; case GRAPHIC_SELECT_DIFFICULTY_ARROW_P2: sAssetPrefix = "Graphics\\select difficulty arrow p2"; break; case GRAPHIC_SELECT_DIFFICULTY_OK: sAssetPrefix = "Graphics\\select difficulty ok"; break; - case GRAPHIC_SELECT_MODE_BACKGROUND: sAssetPrefix = "Graphics\\select mode background"; break; - case GRAPHIC_SELECT_MODE_TOP_EDGE: sAssetPrefix = "Graphics\\select mode top edge"; break; - case GRAPHIC_SELECT_MODE_EXPLANATION: sAssetPrefix = "Graphics\\select mode explanation"; break; - case GRAPHIC_SELECT_MODE_ARROW: sAssetPrefix = "Graphics\\select mode arrow"; break; - case GRAPHIC_SELECT_MODE_OK: sAssetPrefix = "Graphics\\select mode ok"; break; - case GRAPHIC_SELECT_MODE_ARCADE_HEADER: sAssetPrefix = "Graphics\\select mode arcade header"; break; - case GRAPHIC_SELECT_MODE_ARCADE_PICTURE: sAssetPrefix = "Graphics\\select mode arcade picture"; break; - case GRAPHIC_SELECT_MODE_FREE_PLAY_HEADER: sAssetPrefix = "Graphics\\select mode free play header"; break; - case GRAPHIC_SELECT_MODE_FREE_PLAY_PICTURE: sAssetPrefix = "Graphics\\select mode free play picture"; break; - case GRAPHIC_SELECT_MODE_NONSTOP_HEADER: sAssetPrefix = "Graphics\\select mode nonstop header"; break; - case GRAPHIC_SELECT_MODE_NONSTOP_PICTURE: sAssetPrefix = "Graphics\\select mode nonstop picture"; break; case GRAPHIC_SELECT_MUSIC_INFO_FRAME: sAssetPrefix = "Graphics\\select music info frame"; break; case GRAPHIC_SELECT_MUSIC_RADAR_BASE: sAssetPrefix = "Graphics\\select music radar base"; break; case GRAPHIC_SELECT_MUSIC_RADAR_WORDS: sAssetPrefix = "Graphics\\select music radar words 1x5"; break; diff --git a/stepmania/src/ThemeManager.h b/stepmania/src/ThemeManager.h index 9b7fe4be32..38d490077e 100644 --- a/stepmania/src/ThemeManager.h +++ b/stepmania/src/ThemeManager.h @@ -86,17 +86,6 @@ enum ThemeElement { GRAPHIC_SELECT_GROUP_EXPLANATION, GRAPHIC_SELECT_GROUP_INFO_FRAME, GRAPHIC_SELECT_GROUP_TOP_EDGE, - GRAPHIC_SELECT_MODE_ARCADE_HEADER, - GRAPHIC_SELECT_MODE_ARCADE_PICTURE, - GRAPHIC_SELECT_MODE_ARROW, - GRAPHIC_SELECT_MODE_BACKGROUND, - GRAPHIC_SELECT_MODE_EXPLANATION, - GRAPHIC_SELECT_MODE_FREE_PLAY_HEADER, - GRAPHIC_SELECT_MODE_FREE_PLAY_PICTURE, - GRAPHIC_SELECT_MODE_NONSTOP_HEADER, - GRAPHIC_SELECT_MODE_NONSTOP_PICTURE, - GRAPHIC_SELECT_MODE_OK, - GRAPHIC_SELECT_MODE_TOP_EDGE, GRAPHIC_SELECT_MUSIC_BACKGROUND, GRAPHIC_SELECT_MUSIC_DIFFICULTY_FRAME, GRAPHIC_SELECT_MUSIC_INFO_FRAME, diff --git a/stepmania/src/TransitionBackWipe.cpp b/stepmania/src/TransitionBackWipe.cpp new file mode 100644 index 0000000000..925cf4cf9f --- /dev/null +++ b/stepmania/src/TransitionBackWipe.cpp @@ -0,0 +1,81 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + Class: TransitionBackWipe + + Desc: See header. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "TransitionBackWipe.h" +#include "RageUtil.h" +#include "ThemeManager.h" + + +#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 + + + +TransitionBackWipe::TransitionBackWipe() +{ + m_soundBack.Load( THEME->GetPathTo(SOUND_MENU_BACK) ); +} + +void TransitionBackWipe::DrawPrimitives() +{ + 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 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); + + } + + if( iRectWidth > 0 ) + if( i == iFadeLeftEdge || i == iFadeRightEdge ) + { + m_quad.SetXY( (float)iRectX, CENTER_Y ); + m_quad.SetZoomX( (float)iRectWidth ); + m_quad.SetZoomY( SCREEN_HEIGHT ); + m_quad.SetDiffuseColor( D3DXCOLOR(0,0,0,1) ); + m_quad.Draw(); + } + } // end foreach rect +} + + diff --git a/stepmania/src/TransitionBackWipe.h b/stepmania/src/TransitionBackWipe.h new file mode 100644 index 0000000000..52c3b79154 --- /dev/null +++ b/stepmania/src/TransitionBackWipe.h @@ -0,0 +1,39 @@ +#pragma once +/* +----------------------------------------------------------------------------- + Class: TransitionBackWipe + + Desc: Black bands (horizontal window blinds) gradually close. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "Transition.h" +#include "RageDisplay.h" +#include "RageSound.h" +#include "Quad.h" + + +class TransitionBackWipe : public Transition +{ +public: + virtual void DrawPrimitives(); + + virtual void CloseWipingRight(ScreenMessage send_when_done = SM_None ) + { + m_soundBack.Play(); + Transition::CloseWipingRight(send_when_done); + } + virtual void CloseWipingLeft( ScreenMessage send_when_done = SM_None ) + { + m_soundBack.Play(); + Transition::CloseWipingLeft(send_when_done); + } + +protected: + Quad m_quad; + RageSoundSample m_soundBack; +}; +