diff --git a/stepmania/NEWS b/stepmania/NEWS index d567d723af..a9c8076343 100644 --- a/stepmania/NEWS +++ b/stepmania/NEWS @@ -9,6 +9,8 @@ CHANGE: Changed format NoteSkin tap graphic format. Existing NoteSkins will need to update the tap graphic. NEW FEATURE: New Edit menus with ability to delete Notes patterns and new options for importing existing patterns into a new Notes pattern. +NEW FEATURE: Jukebox mode. Like demonstration, but plays entire songs + and loops. ----------------------- Version 3.01 --------------------------- CHANGE: Simplified NoteSkin tap graphic format. Old NoteSkins will need to diff --git a/stepmania/TODO.chris b/stepmania/TODO.chris index 95523fe7d2..3dbaa2eab6 100644 --- a/stepmania/TODO.chris +++ b/stepmania/TODO.chris @@ -2,6 +2,8 @@ Fix ///////////////////////// +background videos out of sync at non-1 song rates + Hrm.. I had a few things about Stepmania I wanted to suggest, but can't think of all of them now.. Lemme list the ones I can remember: - In "all songs" don't have it automatically open one of the folders, or at least have it start at the very beginning of the folder diff --git a/stepmania/src/NoteData.cpp b/stepmania/src/NoteData.cpp index 3558357b0f..6a764708d8 100644 --- a/stepmania/src/NoteData.cpp +++ b/stepmania/src/NoteData.cpp @@ -499,11 +499,16 @@ void NoteData::LoadTransformedSlidingWindow( NoteData* pOriginal, int iNewNumTra void NoteData::PadTapNotes(int rows) { - int needed = rows - m_TapNotes[0].size() + 1; - if(needed < 0) return; - needed += 100; /* optimization: give it a little more than it needs */ + // Need to resize each track individually. It could be the case that + // m_iNumTracks has changed, and the vectors are different sizes. -Chris for(int track = 0; track < m_iNumTracks; ++track) + { + int needed = rows - m_TapNotes[track].size() + 1; + if(needed < 0) + continue; + needed += 100; /* optimization: give it a little more than it needs */ m_TapNotes[track].insert(m_TapNotes[track].end(), needed, TAP_EMPTY); + } } void NoteData::MoveTapNoteTrack(int dest, int src) diff --git a/stepmania/src/ScreenEdit.cpp b/stepmania/src/ScreenEdit.cpp index 023f258bac..56ab398bb0 100644 --- a/stepmania/src/ScreenEdit.cpp +++ b/stepmania/src/ScreenEdit.cpp @@ -247,7 +247,7 @@ ScreenEdit::ScreenEdit() m_NoteFieldRecord.SetXY( EDIT_X, EDIT_GRAY_Y ); m_NoteFieldRecord.SetZoom( 1.0f ); - m_NoteFieldRecord.Load( ¬eData, PLAYER_1, -100, 300 ); + m_NoteFieldRecord.Load( ¬eData, PLAYER_1, -150, 350 ); m_Clipboard.m_iNumTracks = m_NoteFieldEdit.m_iNumTracks; diff --git a/stepmania/src/ScreenJukebox.cpp b/stepmania/src/ScreenJukebox.cpp new file mode 100644 index 0000000000..d8aa412998 --- /dev/null +++ b/stepmania/src/ScreenJukebox.cpp @@ -0,0 +1,248 @@ +#include "stdafx.h" +/* +----------------------------------------------------------------------------- + Class: ScreenJukebox + + Desc: See header. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "ScreenJukebox.h" +#include "RageLog.h" +#include "ThemeManager.h" +#include "GameState.h" +#include "SongManager.h" +#include "StepMania.h" + + + +const ScreenMessage SM_NotesEnded = ScreenMessage(SM_User+101); // MUST be same as in ScreenGameplay + + +bool PrepareForJukebox() // always return true. +{ + // + // Set the current song to prepare for a demonstration + // + + switch( GAMESTATE->m_CurGame ) + { + case GAME_DANCE: GAMESTATE->m_CurStyle = STYLE_DANCE_VERSUS; break; + case GAME_PUMP: GAMESTATE->m_CurStyle = STYLE_PUMP_VERSUS; break; + case GAME_EZ2: GAMESTATE->m_CurStyle = STYLE_EZ2_SINGLE_VERSUS; break; + case GAME_PARA: GAMESTATE->m_CurStyle = STYLE_PARA_SINGLE; break; + case GAME_DS3DDX: GAMESTATE->m_CurStyle = STYLE_DS3DDX_SINGLE; break; + case GAME_BM: GAMESTATE->m_CurStyle = STYLE_BM_SINGLE; break; + default: ASSERT(0); + } + + GAMESTATE->m_PlayMode = PLAY_MODE_ARCADE; + + + // + // Search for a Song and Steps to play during the demo + // + for( int i=0; i<600; i++ ) // try 600 times + { + Song* pSong = SONGMAN->GetRandomSong(); + if( pSong == NULL ) // returns NULL there are no songs + return true; // we need to detect this and abort demonstration later + + if( pSong->m_apNotes.empty() ) + continue; // skip + + if( !pSong->HasMusic() ) + continue; // skip + + vector apNotes; + pSong->GetNotesThatMatch( GAMESTATE->GetCurrentStyleDef()->m_NotesType, apNotes ); + + if( apNotes.empty() ) + continue; // skip + + // Found something we can use! + Notes* pNotes = apNotes[ rand()%apNotes.size() ]; + + GAMESTATE->m_pCurSong = pSong; + for( int p=0; pm_pCurNotes[p] = pNotes; + + break; // done looking + } + + ASSERT( GAMESTATE->m_pCurSong ); + + GAMESTATE->m_MasterPlayerNumber = PLAYER_1; + + // choose some cool options + int Benchmark = 0; + if(Benchmark) + { + /* Note that you also need to make sure you benchmark with the + * same notes. I use a copy of MaxU with only heavy notes included. */ + for( int p=0; pIsPlayerEnabled(p) ) + continue; + + /* Lots and lots of arrows. This might even bias to arrows a little + * too much. */ + GAMESTATE->m_PlayerOptions[p] = PlayerOptions(); + GAMESTATE->m_PlayerOptions[p].m_fScrollSpeed = .25f; + GAMESTATE->m_PlayerOptions[p].m_bEffects[ PlayerOptions::EFFECT_SPACE ] = true; + GAMESTATE->m_PlayerOptions[p].m_bEffects[ PlayerOptions::EFFECT_MINI ] = true; + } + GAMESTATE->m_SongOptions.m_LifeType = SongOptions::LIFE_BATTERY; + GAMESTATE->m_SongOptions.m_FailType = SongOptions::FAIL_OFF; + } + + for( int p=0; pIsPlayerEnabled(p) ) + continue; + + GAMESTATE->m_PlayerOptions[p] = PlayerOptions(); + + if( RandomFloat(0,1)>0.8f ) + GAMESTATE->m_PlayerOptions[p].m_fScrollSpeed = 1.5f; + GAMESTATE->m_PlayerOptions[p].m_bEffects[ rand()%PlayerOptions::NUM_EFFECT_TYPES ] = true; + if( RandomFloat(0,1)>0.9f ) + GAMESTATE->m_PlayerOptions[p].m_AppearanceType = PlayerOptions::APPEARANCE_HIDDEN; + if( RandomFloat(0,1)>0.9f ) + GAMESTATE->m_PlayerOptions[p].m_AppearanceType = PlayerOptions::APPEARANCE_SUDDEN; + if( RandomFloat(0,1)>0.7f ) + GAMESTATE->m_PlayerOptions[p].m_bReverseScroll = true; + if( RandomFloat(0,1)>0.8f ) + GAMESTATE->m_PlayerOptions[p].m_bDark = true; + } + + GAMESTATE->m_SongOptions = SongOptions(); + + GAMESTATE->m_SongOptions.m_LifeType = (randomf(0,1)>0.8f) ? SongOptions::LIFE_BATTERY : SongOptions::LIFE_BAR; + GAMESTATE->m_SongOptions.m_FailType = SongOptions::FAIL_OFF; + + GAMESTATE->m_bDemonstration = true; + + return true; +} + +ScreenJukebox::ScreenJukebox() : ScreenGameplay(PrepareForJukebox()) // this is a hack to get some code to execute before the ScreenGameplay constructor +{ + LOG->Trace( "ScreenJukebox::ScreenJukebox()" ); + + if( GAMESTATE->m_pCurSong == NULL ) // we didn't find a song. + { + this->SendScreenMessage( SM_GoToNextScreen, 0 ); // Abort demonstration. + return; + } + + m_Fade.OpenWipingRight(); + + ClearMessageQueue(); // remove all of the messages set in ScreenGameplay that animate "ready", "here we go", etc. + + GAMESTATE->m_bPastHereWeGo = true; + + m_StarWipe.SetOpened(); + m_DancingState = STATE_DANCING; +} + +ScreenJukebox::~ScreenJukebox() +{ +// GAMESTATE->m_bDemonstration = false; + //GAMESTATE->Reset(); +} + +void ScreenJukebox::Update( float fDeltaTime ) +{ + ScreenGameplay::Update( fDeltaTime ); + + // hide status icons + for( int i=0; iTrace( "ScreenJukebox::Input()" ); + + + // + // This should be the same as ScreenAttract::Input() + // + + if(type != IET_FIRST_PRESS) return; // don't care + + if( DeviceI.device == DEVICE_KEYBOARD && DeviceI.button == SDLK_F3 ) + { + (int&)PREFSMAN->m_CoinMode = (PREFSMAN->m_CoinMode+1) % PrefsManager::NUM_COIN_MODES; + ResetGame(); + CString sMessage = "Coin Mode: "; + switch( PREFSMAN->m_CoinMode ) + { + case PrefsManager::COIN_HOME: sMessage += "HOME"; break; + case PrefsManager::COIN_PAY: sMessage += "PAY"; break; + case PrefsManager::COIN_FREE: sMessage += "FREE"; break; + } + SCREENMAN->SystemMessage( sMessage ); + return; + } + + if( MenuI.IsValid() ) + { + switch( MenuI.button ) + { + case MENU_BUTTON_LEFT: + case MENU_BUTTON_RIGHT: + if( !m_Fade.IsOpening() && !m_Fade.IsClosing() ) + m_Fade.CloseWipingRight( SM_GoToNextScreen ); + break; + case MENU_BUTTON_COIN: + Screen::MenuCoin( MenuI.player ); // increment coins, play sound + m_soundMusic.Stop(); + ::Sleep( 200 ); // do a little pause, like the arcade does + SCREENMAN->SetNewScreen( "ScreenTitleMenu" ); + break; + case MENU_BUTTON_START: + case MENU_BUTTON_BACK: + + switch( PREFSMAN->m_CoinMode ) + { + case PrefsManager::COIN_PAY: + if( GAMESTATE->m_iCoins < PREFSMAN->m_iCoinsPerCredit ) + break; // don't fall through + // fall through + case PrefsManager::COIN_FREE: + case PrefsManager::COIN_HOME: + m_soundMusic.Stop(); + SOUNDMAN->PlayOnce( THEME->GetPathTo("Sounds","insert coin") ); + ::Sleep( 200 ); // do a little pause, like the arcade does + SCREENMAN->SetNewScreen( "ScreenTitleMenu" ); + break; + default: + ASSERT(0); + } + break; + } + } + +} + +void ScreenJukebox::HandleScreenMessage( const ScreenMessage SM ) +{ + switch( SM ) + { + case SM_NotesEnded: + if( m_Fade.IsClosing() ) + return; // ignore - we're already fading + m_Fade.CloseWipingRight( SM_GoToNextScreen ); + return; + case SM_GoToNextScreen: + SCREENMAN->SetNewScreen( "ScreenJukebox" ); + return; + } + + ScreenGameplay::HandleScreenMessage( SM ); +} \ No newline at end of file diff --git a/stepmania/src/ScreenJukebox.h b/stepmania/src/ScreenJukebox.h new file mode 100644 index 0000000000..12a7d9e2b1 --- /dev/null +++ b/stepmania/src/ScreenJukebox.h @@ -0,0 +1,31 @@ +/* +----------------------------------------------------------------------------- + Class: ScreenJukebox + + Desc: Like ScreenDemonstration, Plays whole songs continuously. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "ScreenGameplay.h" +#include "Sprite.h" + + +class ScreenJukebox : public ScreenGameplay +{ +public: + ScreenJukebox(); + ~ScreenJukebox(); + + 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 ); + +protected: + +}; + + + diff --git a/stepmania/src/ScreenManager.cpp b/stepmania/src/ScreenManager.cpp index 92207e4c53..6daa78504e 100644 --- a/stepmania/src/ScreenManager.cpp +++ b/stepmania/src/ScreenManager.cpp @@ -201,6 +201,7 @@ void ScreenManager::Input( const DeviceInput& DeviceI, const InputEventType type #include "ScreenDemonstration.h" #include "ScreenInstructions.h" #include "ScreenNameEntry.h" +#include "ScreenJukebox.h" #include "ScreenPrompt.h" #include "ScreenTextEntry.h" @@ -243,7 +244,7 @@ Screen* ScreenManager::MakeNewScreen( CString sClassName ) else if( 0==stricmp(sClassName, "ScreenTitleMenu") ) ret = new ScreenTitleMenu; else if( 0==stricmp(sClassName, "ScreenEz2SelectMusic") ) ret = new ScreenEz2SelectMusic; else if( 0==stricmp(sClassName, "ScreenWarning") ) ret = new ScreenWarning; - else if( 0==stricmp(sClassName, "ScreenRanking") ) ret = new ScreenRanking; + else if( 0==stricmp(sClassName, "ScreenRanking") ) ret = new ScreenRanking; else if( 0==stricmp(sClassName, "ScreenMemoryCard") ) ret = new ScreenMemoryCard; else if( 0==stricmp(sClassName, "ScreenCompany") ) ret = new ScreenCompany; else if( 0==stricmp(sClassName, "ScreenAlbums") ) ret = new ScreenAlbums; @@ -252,6 +253,7 @@ Screen* ScreenManager::MakeNewScreen( CString sClassName ) else if( 0==stricmp(sClassName, "ScreenDemonstration") ) ret = (ScreenGameplay*)new ScreenDemonstration; else if( 0==stricmp(sClassName, "ScreenInstructions") ) ret = new ScreenInstructions; else if( 0==stricmp(sClassName, "ScreenNameEntry") ) ret = new ScreenNameEntry; + else if( 0==stricmp(sClassName, "ScreenJukebox") ) ret = new ScreenJukebox; else RageException::Throw( "Invalid Screen class name '%s'", sClassName.GetString() ); diff --git a/stepmania/src/ScreenTitleMenu.cpp b/stepmania/src/ScreenTitleMenu.cpp index c606e4f286..ccb5daa4cb 100644 --- a/stepmania/src/ScreenTitleMenu.cpp +++ b/stepmania/src/ScreenTitleMenu.cpp @@ -47,20 +47,6 @@ const ScreenMessage SM_PlayComment = ScreenMessage(SM_User+1); const ScreenMessage SM_GoToAttractLoop = ScreenMessage(SM_User+13); -const CString CHOICE_TEXT[ScreenTitleMenu::NUM_CHOICES]= { - "GAME START", - "SWITCH GAME", - "CONFIG KEY/JOY", - "INPUT OPTIONS", - "MACHINE OPTIONS", - "GRAPHIC OPTIONS", - "APPEARANCE OPTIONS", - "EDIT/RECORD/SYNCH", - #ifdef _DEBUG - "SANDBOX", - #endif - "EXIT", -}; ScreenTitleMenu::ScreenTitleMenu() { @@ -91,7 +77,7 @@ ScreenTitleMenu::ScreenTitleMenu() for( i=0; iGetPathTo("Fonts","titlemenu") ); - m_textChoice[i].SetText( CHOICE_TEXT[i] ); + m_textChoice[i].SetText( ChoiceToString((Choice)i) ); m_textChoice[i].SetXY( CHOICES_X, CHOICES_START_Y + i*CHOICES_SPACING_Y ); m_textChoice[i].SetShadowLength( CHOICES_SHADOW_LENGTH ); m_textChoice[i].TurnShadowOn(); @@ -226,6 +212,7 @@ void ScreenTitleMenu::Input( const DeviceInput& DeviceI, const InputEventType ty case CHOICE_MACHINE_OPTIONS: case CHOICE_GRAPHIC_OPTIONS: case CHOICE_APPEARANCE_OPTIONS: + case CHOICE_JUKEBOX: #ifdef _DEBUG case CHOICE_SANDBOX: #endif @@ -305,6 +292,9 @@ void ScreenTitleMenu::HandleScreenMessage( const ScreenMessage SM ) case CHOICE_APPEARANCE_OPTIONS: SCREENMAN->SetNewScreen( "ScreenAppearanceOptions" ); break; + case CHOICE_JUKEBOX: + SCREENMAN->SetNewScreen( "ScreenJukebox" ); + break; #ifdef _DEBUG case CHOICE_SANDBOX: SCREENMAN->SetNewScreen( "ScreenTest" ); diff --git a/stepmania/src/ScreenTitleMenu.h b/stepmania/src/ScreenTitleMenu.h index 537174d082..e898cc4ba9 100644 --- a/stepmania/src/ScreenTitleMenu.h +++ b/stepmania/src/ScreenTitleMenu.h @@ -28,7 +28,8 @@ public: virtual void Update( float fDelta ); virtual void HandleScreenMessage( const ScreenMessage SM ); - enum Choice { + enum Choice + { CHOICE_GAME_START = 0, CHOICE_SELECT_GAME, CHOICE_MAP_INSTRUMENTS, @@ -37,6 +38,7 @@ public: CHOICE_GRAPHIC_OPTIONS, CHOICE_APPEARANCE_OPTIONS, CHOICE_EDIT, + CHOICE_JUKEBOX, #ifdef _DEBUG CHOICE_SANDBOX, #endif @@ -44,6 +46,26 @@ public: NUM_CHOICES // leave this at the end! }; + CString ChoiceToString( Choice c ) + { + const CString s[NUM_CHOICES] = { + "GAME START", + "SWITCH GAME", + "CONFIG KEY/JOY", + "INPUT OPTIONS", + "MACHINE OPTIONS", + "GRAPHIC OPTIONS", + "APPEARANCE OPTIONS", + "EDIT/SYNCHRONIZE", + "JUKEBOX", + #ifdef _DEBUG + "SANDBOX", + #endif + "EXIT" + }; + return s[c]; + } + private: void GainFocus( int iChoiceIndex ); diff --git a/stepmania/src/StepMania.vcproj b/stepmania/src/StepMania.vcproj index ae7bf432f0..9a71d31c33 100644 --- a/stepmania/src/StepMania.vcproj +++ b/stepmania/src/StepMania.vcproj @@ -267,6 +267,12 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ + + + + diff --git a/stepmania/stepmania.nsi b/stepmania/stepmania.nsi index 44f1e4610e..b9f13203e0 100644 --- a/stepmania/stepmania.nsi +++ b/stepmania/stepmania.nsi @@ -19,7 +19,7 @@ !define PRODUCT_NAME_VER "${PRODUCT_NAME} ${VERSION}" Name "${PRODUCT_NAME}" -OutFile "stepmania-CVS-20030128.exe" +OutFile "stepmania-CVS-20030130.exe" ;OutFile "stepmania301.exe" ; Some default compiler settings (uncomment and change at will):