2003-02-16 04:01:45 +00:00
#include "global.h"
2002-05-20 08:59:37 +00:00
#include "ScreenEdit.h"
#include "PrefsManager.h"
#include "SongManager.h"
#include "ScreenManager.h"
#include "GameConstantsAndTypes.h"
2002-07-23 01:41:40 +00:00
#include "PrefsManager.h"
2002-05-20 08:59:37 +00:00
#include "GameManager.h"
#include "GameConstantsAndTypes.h"
#include "RageLog.h"
2004-07-08 00:10:34 +00:00
#include "GameSoundManager.h"
2002-07-23 01:41:40 +00:00
#include "GameState.h"
2002-10-18 19:01:32 +00:00
#include "InputMapper.h"
2002-11-11 04:53:31 +00:00
#include "RageLog.h"
#include "ThemeManager.h"
2003-02-18 23:15:38 +00:00
#include "ScreenMiniMenu.h"
2003-02-19 06:27:20 +00:00
#include "NoteSkinManager.h"
2003-08-03 00:13:55 +00:00
#include "Steps.h"
2002-09-26 06:05:32 +00:00
#include <utility>
2003-04-10 05:46:31 +00:00
#include "NoteFieldPositioning.h"
2003-07-22 07:47:27 +00:00
#include "arch/arch.h"
2003-08-07 06:36:34 +00:00
#include "NoteDataUtil.h"
2004-04-18 07:34:37 +00:00
#include "SongUtil.h"
#include "StepsUtil.h"
2004-08-11 07:30:41 +00:00
#include "Foreach.h"
2004-09-21 06:07:12 +00:00
#include "ScreenDimensions.h"
2004-11-06 20:36:04 +00:00
#include "ThemeMetric.h"
2004-12-20 06:25:59 +00:00
#include "PlayerState.h"
2005-01-08 07:41:26 +00:00
#include "ScreenTextEntry.h"
2005-01-15 02:01:26 +00:00
#include "Style.h"
2002-05-20 08:59:37 +00:00
2003-02-18 23:15:38 +00:00
const float RECORD_HOLD_SECONDS = 0.3f ;
2002-10-18 19:01:32 +00:00
2002-05-20 08:59:37 +00:00
//
2005-01-05 04:35:15 +00:00
// Defines specific to ScreenEdit
2002-05-20 08:59:37 +00:00
//
2003-09-21 23:16:44 +00:00
#define HELP_TEXT_X (SCREEN_LEFT + 4)
#define HELP_TEXT_Y (40)
2003-02-18 23:15:38 +00:00
2003-09-21 23:16:44 +00:00
#define INFO_TEXT_X (SCREEN_RIGHT - 114)
#define INFO_TEXT_Y (40)
2003-02-18 23:15:38 +00:00
2004-11-05 06:35:10 +00:00
#define EDIT_X (SCREEN_CENTER_X)
2002-05-20 08:59:37 +00:00
2004-11-05 06:35:10 +00:00
#define PLAYER_X (SCREEN_CENTER_X)
#define PLAYER_Y (SCREEN_CENTER_Y)
2003-09-21 23:16:44 +00:00
#define PLAYER_HEIGHT (360)
#define PLAYER_Y_STANDARD (PLAYER_Y-PLAYER_HEIGHT/2)
2002-08-17 06:44:04 +00:00
2004-11-06 20:36:04 +00:00
ThemeMetric < float > TICK_EARLY_SECONDS ( "ScreenGameplay" , "TickEarlySeconds" );
2003-02-18 23:15:38 +00:00
const ScreenMessage SM_BackFromMainMenu = ( ScreenMessage )( SM_User + 1 );
const ScreenMessage SM_BackFromAreaMenu = ( ScreenMessage )( SM_User + 2 );
const ScreenMessage SM_BackFromEditNotesStatistics = ( ScreenMessage )( SM_User + 3 );
const ScreenMessage SM_BackFromEditOptions = ( ScreenMessage )( SM_User + 4 );
const ScreenMessage SM_BackFromEditSongInfo = ( ScreenMessage )( SM_User + 5 );
2003-03-15 19:25:37 +00:00
const ScreenMessage SM_BackFromBGChange = ( ScreenMessage )( SM_User + 6 );
2003-11-12 08:13:02 +00:00
const ScreenMessage SM_BackFromPlayerOptions = ( ScreenMessage )( SM_User + 7 );
const ScreenMessage SM_BackFromSongOptions = ( ScreenMessage )( SM_User + 8 );
const ScreenMessage SM_BackFromInsertAttack = ( ScreenMessage )( SM_User + 9 );
const ScreenMessage SM_BackFromInsertAttackModifiers = ( ScreenMessage )( SM_User + 10 );
2004-01-23 08:25:00 +00:00
const ScreenMessage SM_BackFromPrefs = ( ScreenMessage )( SM_User + 11 );
2004-01-26 20:56:58 +00:00
const ScreenMessage SM_BackFromCourseModeMenu = ( ScreenMessage )( SM_User + 12 );
const ScreenMessage SM_DoReloadFromDisk = ( ScreenMessage )( SM_User + 13 );
2004-05-03 01:37:49 +00:00
const ScreenMessage SM_DoUpdateTextInfo = ( ScreenMessage )( SM_User + 14 );
2005-01-08 07:41:26 +00:00
const ScreenMessage SM_BackFromBPMChange = ( ScreenMessage )( SM_User + 15 );
const ScreenMessage SM_BackFromStopChange = ( ScreenMessage )( SM_User + 16 );
2003-02-07 23:58:21 +00:00
2002-06-29 11:59:09 +00:00
const CString HELP_TEXT =
2004-10-28 07:56:13 +00:00
#if !defined(XBOX)
2003-02-18 23:15:38 +00:00
"Up/Down: \n change beat \n "
"Left/Right: \n change snap \n "
"Number keys: \n add/remove \n tap note \n "
"Create hold note: \n Hold a number \n while moving \n Up or Down \n "
2003-02-19 05:46:09 +00:00
"Space bar: \n Set area \n marker \n "
"Enter: \n Area Menu \n "
"Escape: \n Main Menu \n "
"F1: \n Show \n keyboard \n shortcuts \n " ;
2004-10-28 07:56:13 +00:00
#else
"Up/Down: \n change beat \n "
"Left/Right: \n change snap \n "
"A/B/X/Y: \n add/remove \n tap note \n "
"Create hold note: \n Hold a button \n while moving \n Up or Down \n "
"White: \n Set area \n marker \n "
"Start: \n Area Menu \n "
"Select: \n Main Menu \n "
"Black: \n Show \n shortcuts \n " ;
#endif
2002-08-17 06:44:04 +00:00
2005-01-14 23:17:04 +00:00
#if defined(XBOX)
2005-01-15 13:14:36 +00:00
void ScreenEdit :: InitEditMappings ()
2005-01-14 23:17:04 +00:00
{
/* XXX: fill this in */
}
#else
2005-01-15 13:14:36 +00:00
void ScreenEdit :: InitEditMappings ()
2005-01-14 23:17:04 +00:00
{
g_EditMappings . Clear ();
g_EditMappings . button [ EDIT_BUTTON_COLUMN_0 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C1 );
g_EditMappings . button [ EDIT_BUTTON_COLUMN_1 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C2 );
g_EditMappings . button [ EDIT_BUTTON_COLUMN_2 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C3 );
g_EditMappings . button [ EDIT_BUTTON_COLUMN_3 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C4 );
g_EditMappings . button [ EDIT_BUTTON_COLUMN_4 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C5 );
g_EditMappings . button [ EDIT_BUTTON_COLUMN_5 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C6 );
g_EditMappings . button [ EDIT_BUTTON_COLUMN_6 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C7 );
g_EditMappings . button [ EDIT_BUTTON_COLUMN_7 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C8 );
g_EditMappings . button [ EDIT_BUTTON_COLUMN_8 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C9 );
g_EditMappings . button [ EDIT_BUTTON_COLUMN_9 ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_C0 );
g_EditMappings . button [ EDIT_BUTTON_RIGHT_SIDE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LALT );
g_EditMappings . button [ EDIT_BUTTON_RIGHT_SIDE ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RALT );
g_EditMappings . button [ EDIT_BUTTON_LAY_MINE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LSHIFT );
g_EditMappings . button [ EDIT_BUTTON_LAY_ATTACK ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RSHIFT );
g_EditMappings . button [ EDIT_BUTTON_SCROLL_UP_LINE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_UP );
g_EditMappings . button [ EDIT_BUTTON_SCROLL_UP_PAGE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_PGUP );
g_EditMappings . button [ EDIT_BUTTON_SCROLL_DOWN_LINE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_DOWN );
g_EditMappings . button [ EDIT_BUTTON_SCROLL_DOWN_PAGE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_PGDN );
g_EditMappings . button [ EDIT_BUTTON_SCROLL_HOME ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_HOME );
g_EditMappings . button [ EDIT_BUTTON_SCROLL_END ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_END );
g_EditMappings . button [ EDIT_BUTTON_SCROLL_SPEED_UP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_UP );
g_EditMappings . hold [ EDIT_BUTTON_SCROLL_SPEED_UP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LCTRL );
g_EditMappings . hold [ EDIT_BUTTON_SCROLL_SPEED_UP ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RCTRL );
g_EditMappings . button [ EDIT_BUTTON_SCROLL_SPEED_DOWN ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_DOWN );
g_EditMappings . hold [ EDIT_BUTTON_SCROLL_SPEED_DOWN ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LCTRL );
g_EditMappings . hold [ EDIT_BUTTON_SCROLL_SPEED_DOWN ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RCTRL );
g_EditMappings . button [ EDIT_BUTTON_SCROLL_SELECT ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LSHIFT );
g_EditMappings . button [ EDIT_BUTTON_SCROLL_SELECT ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RSHIFT );
g_EditMappings . button [ EDIT_BUTTON_LAY_SELECT ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_SPACE );
g_EditMappings . button [ EDIT_BUTTON_SNAP_NEXT ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LEFT );
g_EditMappings . button [ EDIT_BUTTON_SNAP_PREV ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RIGHT );
g_EditMappings . button [ EDIT_BUTTON_OPEN_EDIT_MENU ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_ESC );
g_EditMappings . button [ EDIT_BUTTON_OPEN_AREA_MENU ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_ENTER );
g_EditMappings . button [ EDIT_BUTTON_OPEN_AREA_MENU ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_KP_ENTER );
g_EditMappings . button [ EDIT_BUTTON_OPEN_BGA_MENU ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cb );
g_EditMappings . button [ EDIT_BUTTON_OPEN_COURSE_MENU ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cc );
g_EditMappings . button [ EDIT_BUTTON_OPEN_INPUT_HELP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F1 );
g_EditMappings . button [ EDIT_BUTTON_PLAY_FROM_START ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cp );
g_EditMappings . hold [ EDIT_BUTTON_PLAY_FROM_START ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LCTRL );
g_EditMappings . hold [ EDIT_BUTTON_PLAY_FROM_START ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RCTRL );
g_EditMappings . button [ EDIT_BUTTON_PLAY_FROM_CURSOR ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cp );
g_EditMappings . hold [ EDIT_BUTTON_PLAY_FROM_CURSOR ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LSHIFT );
g_EditMappings . hold [ EDIT_BUTTON_PLAY_FROM_CURSOR ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RSHIFT );
g_EditMappings . button [ EDIT_BUTTON_PLAY_SELECTION ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cp );
g_EditMappings . button [ EDIT_BUTTON_RECORD ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cr );
g_EditMappings . hold [ EDIT_BUTTON_RECORD ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LCTRL );
g_EditMappings . hold [ EDIT_BUTTON_RECORD ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RCTRL );
g_EditMappings . button [ EDIT_BUTTON_INSERT ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_INSERT );
g_EditMappings . button [ EDIT_BUTTON_DELETE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_DEL );
g_EditMappings . button [ EDIT_BUTTON_INSERT_SHIFT_PAUSES ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_INSERT );
g_EditMappings . hold [ EDIT_BUTTON_INSERT_SHIFT_PAUSES ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LCTRL );
g_EditMappings . hold [ EDIT_BUTTON_INSERT_SHIFT_PAUSES ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RCTRL );
g_EditMappings . button [ EDIT_BUTTON_DELETE_SHIFT_PAUSES ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_DEL );
g_EditMappings . hold [ EDIT_BUTTON_DELETE_SHIFT_PAUSES ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LCTRL );
g_EditMappings . hold [ EDIT_BUTTON_DELETE_SHIFT_PAUSES ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RCTRL );
g_EditMappings . button [ EDIT_BUTTON_TOGGLE_ASSIST_TICK ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F4 );
g_EditMappings . button [ EDIT_BUTTON_PLAY_SAMPLE_MUSIC ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_Cm );
g_EditMappings . button [ EDIT_BUTTON_OPEN_NEXT_STEPS ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F6 );
g_EditMappings . button [ EDIT_BUTTON_OPEN_PREV_STEPS ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F5 );
g_EditMappings . button [ EDIT_BUTTON_BPM_UP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F8 );
g_EditMappings . button [ EDIT_BUTTON_BPM_DOWN ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F7 );
g_EditMappings . button [ EDIT_BUTTON_STOP_UP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F10 );
g_EditMappings . button [ EDIT_BUTTON_STOP_DOWN ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F9 );
g_EditMappings . button [ EDIT_BUTTON_OFFSET_UP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F12 );
g_EditMappings . button [ EDIT_BUTTON_OFFSET_DOWN ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F11 );
g_EditMappings . button [ EDIT_BUTTON_SAMPLE_START_UP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RBRACKET );
g_EditMappings . button [ EDIT_BUTTON_SAMPLE_START_DOWN ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LBRACKET );
g_EditMappings . button [ EDIT_BUTTON_SAMPLE_LENGTH_UP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RBRACKET );
g_EditMappings . hold [ EDIT_BUTTON_SAMPLE_LENGTH_UP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LSHIFT );
g_EditMappings . hold [ EDIT_BUTTON_SAMPLE_LENGTH_UP ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RSHIFT );
g_EditMappings . button [ EDIT_BUTTON_SAMPLE_LENGTH_DOWN ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LBRACKET );
g_EditMappings . hold [ EDIT_BUTTON_SAMPLE_LENGTH_DOWN ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LSHIFT );
g_EditMappings . hold [ EDIT_BUTTON_SAMPLE_LENGTH_DOWN ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RSHIFT );
g_EditMappings . button [ EDIT_BUTTON_ADJUST_FINE ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_RALT );
g_EditMappings . button [ EDIT_BUTTON_ADJUST_FINE ][ 1 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_LALT );
g_PlayMappings . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_ESC );
g_PlayMappings . button [ EDIT_BUTTON_TOGGLE_ASSIST_TICK ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F4 );
g_PlayMappings . button [ EDIT_BUTTON_TOGGLE_AUTOPLAY ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F8 );
g_PlayMappings . button [ EDIT_BUTTON_OFFSET_UP ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F12 );
g_PlayMappings . button [ EDIT_BUTTON_OFFSET_DOWN ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_F11 );
g_RecordMappings . button [ EDIT_BUTTON_RETURN_TO_EDIT ][ 0 ] = DeviceInput ( DEVICE_KEYBOARD , KEY_ESC );
}
#endif
/* Given a DeviceInput that was just depressed, return an active edit function. */
2005-01-15 18:33:09 +00:00
bool ScreenEdit :: DeviceToEdit ( DeviceInput DeviceI , EditButton & button ) const
2005-01-14 23:17:04 +00:00
{
ASSERT ( DeviceI . IsValid () );
2005-01-15 13:14:36 +00:00
const MapEditToDI * pCurrentMap = GetCurrentMap ();
2005-01-14 23:17:04 +00:00
/* First, search to see if a key that requires a modifier is pressed. */
FOREACH_EditButton ( e )
{
for ( int slot = 0 ; slot < NUM_EDIT_TO_DEVICE_SLOTS ; ++ slot )
{
2005-01-15 13:14:36 +00:00
if ( pCurrentMap -> button [ e ][ slot ] == DeviceI && pCurrentMap -> hold [ e ][ 0 ]. IsValid () )
2005-01-14 23:17:04 +00:00
{
/* The button maps to this function. */
button = e ;
/* This function has one or more shift modifier attached. */
for ( int holdslot = 0 ; holdslot < NUM_EDIT_TO_DEVICE_SLOTS ; ++ holdslot )
{
2005-01-15 13:14:36 +00:00
DeviceInput hDI = pCurrentMap -> hold [ e ][ holdslot ];
2005-01-14 23:17:04 +00:00
if ( INPUTFILTER -> IsBeingPressed ( hDI ) )
return true ;
}
}
}
}
/* No shifted keys matched. See if any unshifted inputs are bound to this key. */
FOREACH_EditButton ( e )
{
for ( int slot = 0 ; slot < NUM_EDIT_TO_DEVICE_SLOTS ; ++ slot )
{
2005-01-15 13:14:36 +00:00
if ( pCurrentMap -> button [ e ][ slot ] == DeviceI && ! pCurrentMap -> hold [ e ][ 0 ]. IsValid () )
2005-01-14 23:17:04 +00:00
{
/* The button maps to this function. */
button = e ;
return true ;
}
}
}
2005-01-15 13:05:33 +00:00
button = EDIT_BUTTON_INVALID ;
2005-01-14 23:17:04 +00:00
return false ;
}
2005-01-15 18:33:09 +00:00
bool ScreenEdit :: EditToDevice ( EditButton button , int iSlotNum , DeviceInput & DeviceI ) const
2005-01-14 23:17:04 +00:00
{
ASSERT ( iSlotNum < NUM_EDIT_TO_DEVICE_SLOTS );
2005-01-15 13:14:36 +00:00
const MapEditToDI * pCurrentMap = GetCurrentMap ();
DeviceI = pCurrentMap -> button [ button ][ iSlotNum ];
2005-01-14 23:17:04 +00:00
return DeviceI . IsValid ();
}
2005-01-15 18:33:09 +00:00
bool ScreenEdit :: EditIsBeingPressed ( EditButton button ) const
2005-01-14 23:17:04 +00:00
{
for ( int slot = 0 ; slot < NUM_EDIT_TO_DEVICE_SLOTS ; ++ slot )
{
DeviceInput DeviceI ;
if ( EditToDevice ( button , slot , DeviceI ) && INPUTFILTER -> IsBeingPressed ( DeviceI ) )
return true ;
}
return false ;
}
2005-01-15 13:14:36 +00:00
const MapEditToDI * ScreenEdit :: GetCurrentMap () const
{
switch ( m_EditMode )
{
case MODE_EDITING : return & g_EditMappings ;
case MODE_PLAYING : return & g_PlayMappings ;
case MODE_RECORDING : return & g_RecordMappings ;
default : FAIL_M ( ssprintf ( "%i" , m_EditMode ) );
}
}
2002-06-29 11:59:09 +00:00
2003-11-08 00:50:25 +00:00
static const MenuRow g_KeyboardShortcutsItems [] =
{
2004-10-28 07:56:13 +00:00
#if !defined(XBOX)
2003-11-08 00:56:39 +00:00
{ "PgUp/PgDn: jump measure" , false , 0 , { NULL } },
{ "Home/End: jump to first/last beat" , false , 0 , { NULL } },
{ "Ctrl + Up/Down: Change zoom" , false , 0 , { NULL } },
{ "Shift + Up/Down: Drag area marker" , false , 0 , { NULL } },
{ "P: Play selection" , false , 0 , { NULL } },
{ "Ctrl + P: Play whole song" , false , 0 , { NULL } },
{ "Shift + P: Play current beat to end" , false , 0 , { NULL } },
{ "Ctrl + R: Record" , false , 0 , { NULL } },
{ "F4: Toggle assist tick" , false , 0 , { NULL } },
{ "F5/F6: Next/prev steps of same StepsType" , false , 0 , { NULL } },
{ "F7/F8: Decrease/increase BPM at cur beat" , false , 0 , { NULL } },
{ "F9/F10: Decrease/increase stop at cur beat" , false , 0 , { NULL } },
{ "F11/F12: Decrease/increase music offset" , false , 0 , { NULL } },
2003-03-05 02:38:17 +00:00
/* XXX: This would be better as a single submenu, to let people tweak
* and play the sample several times (without having to re-enter the
* menu each time), so it doesn't use a whole bunch of hotkeys. */
2003-11-08 00:56:39 +00:00
{ "[ and ]: Decrease/increase sample music start" , false , 0 , { NULL } },
{ "{ and }: Decrease/increase sample music length" , false , 0 , { NULL } },
{ "M: Play sample music" , false , 0 , { NULL } },
{ "B: Add/Edit Background Change" , false , 0 , { NULL } },
{ "Insert: Insert beat and shift down" , false , 0 , { NULL } },
2004-02-27 06:28:31 +00:00
{ "Ctrl + Insert: Shift BPM changes and stops down one beat" ,
false , 0 , { NULL } },
2003-11-08 00:56:39 +00:00
{ "Delete: Delete beat and shift up" , false , 0 , { NULL } },
2004-02-27 06:28:31 +00:00
{ "Ctrl + Delete: Shift BPM changes and stops up one beat" ,
false , 0 , { NULL } },
2003-11-08 00:56:39 +00:00
{ "Shift + number: Lay mine" , false , 0 , { NULL } },
2003-11-08 01:00:27 +00:00
{ "Alt + number: Add to/remove from right half" , false , 0 , { NULL } },
2004-10-28 07:56:13 +00:00
#else
{ "L + Up/Down: Change zoom" , false , 0 , { NULL } },
{ "R + Up/Down: Drag area marker" , false , 0 , { NULL } },
{ "L + Select: Play selection" , false , 0 , { NULL } },
{ "R + Start: Play whole song" , false , 0 , { NULL } },
{ "R + Select: Record" , false , 0 , { NULL } },
{ "L + Black: Toggle assist tick" , false , 0 , { NULL } },
{ "R + White: Insert beat and shift down" , false , 0 , { NULL } },
{ "R + Black: Delete beat and shift up" , false , 0 , { NULL } },
{ "R + button: Lay mine" , false , 0 , { NULL } },
{ "L + button: Add to/remove from right half" , false , 0 , { NULL } },
#endif
2003-11-08 01:00:27 +00:00
{ NULL , true , 0 , { NULL } }
2003-11-08 00:50:25 +00:00
};
static Menu g_KeyboardShortcuts ( "Keyboard Shortcuts" , g_KeyboardShortcutsItems );
2003-02-19 05:46:09 +00:00
2003-11-08 00:50:25 +00:00
static const MenuRow g_MainMenuItems [] =
{
2003-11-08 00:56:39 +00:00
{ "Edit Steps Statistics" , true , 0 , { NULL } },
{ "Play Whole Song" , true , 0 , { NULL } },
{ "Play Current Beat To End" , true , 0 , { NULL } },
{ "Save" , true , 0 , { NULL } },
2004-01-24 20:36:09 +00:00
{ "Reload from disk" , true , 0 , { NULL } },
2003-11-08 00:56:39 +00:00
{ "Player Options" , true , 0 , { NULL } },
{ "Song Options" , true , 0 , { NULL } },
{ "Edit Song Info" , true , 0 , { NULL } },
2005-01-08 07:41:26 +00:00
{ "Edit BPM Change" , true , 0 , { NULL } },
{ "Edit Stop" , true , 0 , { NULL } },
2003-11-08 00:56:39 +00:00
{ "Add/Edit BG Change" , true , 0 , { NULL } },
{ "Play preview music" , true , 0 , { NULL } },
2004-01-23 08:25:00 +00:00
{ "Preferences" , true , 0 , { NULL } },
2003-11-08 01:00:27 +00:00
{ "Exit (discards changes since last save)" , true , 0 , { NULL } },
{ NULL , true , 0 , { NULL } }
2003-11-08 00:50:25 +00:00
};
static Menu g_MainMenu ( "Main Menu" , g_MainMenuItems );
2002-06-29 11:59:09 +00:00
2003-11-08 00:50:25 +00:00
static const MenuRow g_AreaMenuItems [] =
{
2003-11-08 00:56:39 +00:00
{ "Cut" , true , 0 , { NULL } },
{ "Copy" , true , 0 , { NULL } },
{ "Paste at current beat" , true , 0 , { NULL } },
{ "Paste at begin marker" , true , 0 , { NULL } },
{ "Clear" , true , 0 , { NULL } },
2003-11-08 01:00:27 +00:00
{ "Quantize" , true , 0 , { "4TH" , "8TH" , "12TH" , "16TH" , "24TH" , "32ND" , "48TH" , "64TH" } },
{ "Turn" , true , 0 , { "Left" , "Right" , "Mirror" , "Shuffle" , "Super Shuffle" } },
2004-08-29 21:26:52 +00:00
{ "Transform" , true , 0 , { "NoHolds" , "NoMines" , "Little" , "Wide" , "Big" , "Quick" , "BMRize" , "Skippy" , "Mines" , "Echo" , "Stomp" , "Planted" , "Floored" , "Twister" , "NoJumps" , "NoHands" , "NoQuads" } },
2003-12-31 07:49:30 +00:00
{ "Alter" , true , 0 , { "Backwards" , "Swap Sides" , "Copy Left To Right" , "Copy Right To Left" , "Clear Left" , "Clear Right" , "Collapse To One" , "Collapse Left" , "Shift Left" , "Shift Right" } },
2003-11-08 01:00:27 +00:00
{ "Tempo" , true , 0 , { "Compress 2x" , "Compress 3->2" , "Compress 4->3" , "Expand 3->4" , "Expand 2->3" , "Expand 2x" } },
2003-11-08 00:56:39 +00:00
{ "Play selection" , true , 0 , { NULL } },
{ "Record in selection" , true , 0 , { NULL } },
{ "Insert beat and shift down" , true , 0 , { NULL } },
{ "Delete beat and shift up" , true , 0 , { NULL } },
2004-02-27 06:28:31 +00:00
{ "Shift pauses and BPM changes down" ,
true , 0 , { NULL } },
{ "Shift pauses and BPM changes up" ,
true , 0 , { NULL } },
2003-11-08 00:56:39 +00:00
{ "Convert beats to pause" , true , 0 , { NULL } },
2003-11-08 01:00:27 +00:00
{ "Convert pause to beats" , true , 0 , { NULL } },
{ NULL , true , 0 , { NULL } }
2003-11-08 00:50:25 +00:00
};
static Menu g_AreaMenu ( "Area Menu" , g_AreaMenuItems );
2002-09-26 06:05:32 +00:00
2003-11-08 00:50:25 +00:00
static const MenuRow g_EditNotesStatisticsItems [] =
{
2004-02-25 23:43:50 +00:00
{ "Difficulty" , true , 0 , { "BEGINNER" , "EASY" , "MEDIUM" , "HARD" , "CHALLENGE" , "EDIT" } },
2003-12-22 18:27:32 +00:00
{ "Meter" , true , 0 , { "1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "10" , "11" , "12" , "13" , "14" , "15" } },
{ "Description" , true , 0 , { NULL } },
2004-07-19 20:27:59 +00:00
{ "Predicted Meter" , false , 0 , { NULL } },
2003-11-08 00:56:39 +00:00
{ "Tap Steps" , false , 0 , { NULL } },
{ "Hold Steps" , false , 0 , { NULL } },
{ "Stream" , false , 0 , { NULL } },
{ "Voltage" , false , 0 , { NULL } },
{ "Air" , false , 0 , { NULL } },
{ "Freeze" , false , 0 , { NULL } },
2003-11-08 01:00:27 +00:00
{ "Chaos" , false , 0 , { NULL } },
{ NULL , true , 0 , { NULL } }
2003-11-08 00:50:25 +00:00
};
static Menu g_EditNotesStatistics ( "Statistics" , g_EditNotesStatisticsItems );
2002-05-20 08:59:37 +00:00
2003-11-08 00:50:25 +00:00
static const MenuRow g_EditSongInfoItems [] =
{
2003-11-08 00:56:39 +00:00
{ "Main title" , true , 0 , { NULL } },
{ "Sub title" , true , 0 , { NULL } },
{ "Artist" , true , 0 , { NULL } },
{ "Credit" , true , 0 , { NULL } },
{ "Main title transliteration" , true , 0 , { NULL } },
{ "Sub title transliteration" , true , 0 , { NULL } },
2003-11-08 01:00:27 +00:00
{ "Artist transliteration" , true , 0 , { NULL } },
{ NULL , true , 0 , { NULL } }
2003-11-08 00:50:25 +00:00
};
static Menu g_EditSongInfo ( "Edit Song Info" , g_EditSongInfoItems );
2003-02-18 23:15:38 +00:00
2003-11-08 00:50:25 +00:00
static const MenuRow g_BGChangeItems [] =
{
2004-08-20 08:36:17 +00:00
{ "Rate (applies to new adds)" , true , 10 , { "0%" , "10%" , "20%" , "30%" , "40%" , "50%" , "60%" , "70%" , "80%" , "90%" , "100%" , "120%" , "140%" , "160%" , "180%" , "200%" } },
2003-11-08 01:00:27 +00:00
{ "Fade Last (applies to new adds)" , true , 0 , { "NO" , "YES" } },
{ "Rewind Movie (applies to new adds)" , true , 0 , { "NO" , "YES" } },
{ "Loop (applies to new adds)" , true , 1 , { "NO" , "YES" } },
2003-11-08 00:56:39 +00:00
{ "Add Change to random" , true , 0 , { NULL } },
{ "Add Change to song BGAnimation" , true , 0 , { NULL } },
{ "Add Change to song Movie" , true , 0 , { NULL } },
{ "Add Change to song Still" , true , 0 , { NULL } },
{ "Add Change to global Random Movie" , true , 0 , { NULL } },
{ "Add Change to global BGAnimation" , true , 0 , { NULL } },
{ "Add Change to global Visualization" , true , 0 , { NULL } },
2003-11-08 01:00:27 +00:00
{ "Remove Change" , true , 0 , { NULL } },
{ NULL , true , 0 , { NULL } }
2003-11-08 00:50:25 +00:00
};
static Menu g_BGChange ( "Background Change" , g_BGChangeItems );
2002-05-20 08:59:37 +00:00
2004-01-23 08:25:00 +00:00
static const MenuRow g_PrefsItems [] =
{
{ "Show BGChanges during Play/Record" , true , 0 , { "NO" , "YES" } },
{ NULL , true , 0 , { NULL } }
};
static Menu g_Prefs ( "Preferences" , g_PrefsItems );
2003-11-12 08:13:02 +00:00
static const MenuRow g_InsertAttackItems [] =
{
2003-11-17 07:14:41 +00:00
{ "Duration seconds" , true , 3 , { "5" , "10" , "15" , "20" , "25" , "30" , "35" , "40" , "45" } },
2003-11-12 08:13:02 +00:00
{ "Set modifiers" , true , 0 , { "PRESS START" } },
{ NULL , true , 0 , { NULL } }
};
static Menu g_InsertAttack ( "Insert Attack" , g_InsertAttackItems );
2004-01-26 20:56:58 +00:00
static const MenuRow g_CourseModeItems [] =
{
{ "Play mods from course" , true , 0 , { NULL } },
{ NULL , true , 0 , { NULL } }
};
static Menu g_CourseMode ( "Course Display" , g_CourseModeItems );
2003-11-12 08:13:02 +00:00
// HACK: need to remember the track we're inserting on so
// that we can lay the attack note after coming back from
// menus.
int g_iLastInsertAttackTrack = - 1 ;
2003-11-12 08:32:32 +00:00
float g_fLastInsertAttackDurationSeconds = - 1 ;
2003-11-12 08:13:02 +00:00
2004-11-26 17:28:47 +00:00
REGISTER_SCREEN_CLASS ( ScreenEdit );
2003-09-27 22:30:51 +00:00
ScreenEdit :: ScreenEdit ( CString sName ) : Screen ( sName )
2002-05-20 08:59:37 +00:00
{
2002-07-31 19:40:40 +00:00
LOG -> Trace ( "ScreenEdit::ScreenEdit()" );
2002-05-20 08:59:37 +00:00
2005-01-14 23:17:04 +00:00
InitEditMappings ();
2003-12-18 08:53:38 +00:00
/* We do this ourself. */
SOUND -> HandleSongTimer ( false );
2002-08-17 06:44:04 +00:00
// set both players to joined so the credit message doesn't show
2004-05-24 06:10:11 +00:00
FOREACH_PlayerNumber ( p )
2002-08-20 21:00:56 +00:00
GAMESTATE -> m_bSideIsJoined [ p ] = true ;
2002-08-17 06:44:04 +00:00
SCREENMAN -> RefreshCreditsMessages ();
2002-07-23 01:41:40 +00:00
m_pSong = GAMESTATE -> m_pCurSong ;
2004-05-24 06:12:17 +00:00
m_pSteps = GAMESTATE -> m_pCurSteps [ PLAYER_1 ];
2004-01-26 20:56:58 +00:00
m_pAttacksFromCourse = NULL ;
2002-05-20 08:59:37 +00:00
2002-07-03 03:13:13 +00:00
NoteData noteData ;
2004-10-23 17:43:49 +00:00
m_pSteps -> GetNoteData ( noteData );
2002-07-03 03:13:13 +00:00
2002-07-28 20:28:37 +00:00
m_EditMode = MODE_EDITING ;
2004-02-01 02:05:09 +00:00
GAMESTATE -> m_bPastHereWeGo = false ;
2002-07-28 20:28:37 +00:00
GAMESTATE -> m_bEditing = true ;
2002-05-20 08:59:37 +00:00
2002-08-01 20:30:40 +00:00
GAMESTATE -> m_fSongBeat = 0 ;
m_fTrailingBeat = GAMESTATE -> m_fSongBeat ;
2002-08-01 13:42:56 +00:00
2004-12-20 06:25:59 +00:00
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_PlayerOptions . m_fScrollSpeed = 1 ;
2003-02-19 06:27:20 +00:00
GAMESTATE -> m_SongOptions . m_fMusicRate = 1 ;
2003-08-09 19:00:52 +00:00
/* Not all games have a noteskin named "note" ... */
if ( NOTESKIN -> DoesNoteSkinExist ( "note" ) )
2004-12-20 06:25:59 +00:00
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_PlayerOptions . m_sNoteSkin = "note" ; // change noteskin before loading all of the edit Actors
2003-09-12 06:23:51 +00:00
GAMESTATE -> ResetNoteSkins ();
2004-03-01 05:41:40 +00:00
GAMESTATE -> StoreSelectedOptions ();
2002-05-20 08:59:37 +00:00
2005-01-23 23:17:12 +00:00
g_iShiftAnchor = - 1 ;
2003-09-21 23:16:44 +00:00
m_SnapDisplay . SetXY ( EDIT_X , PLAYER_Y_STANDARD );
2002-08-17 06:44:04 +00:00
m_SnapDisplay . Load ( PLAYER_1 );
2002-08-13 23:26:46 +00:00
m_SnapDisplay . SetZoom ( 0.5f );
2002-05-20 08:59:37 +00:00
2003-09-21 23:16:44 +00:00
m_NoteFieldEdit . SetXY ( EDIT_X , PLAYER_Y );
2002-05-20 08:59:37 +00:00
m_NoteFieldEdit . SetZoom ( 0.5f );
2005-01-22 02:50:45 +00:00
m_NoteDataEdit . CopyAll ( noteData );
m_NoteFieldEdit . Load ( & m_NoteDataEdit , GAMESTATE -> m_pPlayerState [ PLAYER_1 ], - 240 , 800 , PLAYER_HEIGHT * 2 );
2002-05-20 08:59:37 +00:00
2004-09-21 08:41:17 +00:00
m_rectRecordBack . StretchTo ( RectF ( SCREEN_LEFT , SCREEN_TOP , SCREEN_RIGHT , SCREEN_BOTTOM ) );
2002-10-28 05:30:45 +00:00
m_rectRecordBack . SetDiffuse ( RageColor ( 0 , 0 , 0 , 0 ) );
2002-05-20 08:59:37 +00:00
2003-10-02 04:10:56 +00:00
m_NoteFieldRecord . SetXY ( EDIT_X , PLAYER_Y );
2005-01-22 02:50:45 +00:00
m_NoteDataRecord . CopyAll ( noteData );
m_NoteFieldRecord . Load ( & m_NoteDataRecord , GAMESTATE -> m_pPlayerState [ PLAYER_1 ], - 150 , 350 , 350 );
2002-05-20 08:59:37 +00:00
2005-01-22 02:50:45 +00:00
m_Clipboard . SetNumTracks ( m_NoteDataEdit . GetNumTracks () );
2002-07-02 00:27:58 +00:00
2003-02-19 06:27:20 +00:00
2004-12-20 06:25:59 +00:00
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_PlayerOptions . Init (); // don't allow weird options in editor. It doesn't handle reverse well.
2003-12-31 07:44:53 +00:00
// Set NoteSkin to note if available.
// Change noteskin back to default before loading player.
if ( NOTESKIN -> DoesNoteSkinExist ( "note" ) )
2004-12-20 06:25:59 +00:00
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_PlayerOptions . m_sNoteSkin = "note" ;
2003-09-12 06:23:51 +00:00
GAMESTATE -> ResetNoteSkins ();
2003-02-19 06:27:20 +00:00
2004-01-24 20:36:09 +00:00
/* XXX: Do we actually have to send real note data here, and to m_NoteFieldRecord?
* (We load again on play/record.) */
2005-01-15 03:31:07 +00:00
m_Player . Init ( GAMESTATE -> m_pPlayerState [ PLAYER_1 ], NULL , NULL , NULL , NULL , NULL , NULL , NULL , NULL );
2005-01-15 01:28:29 +00:00
m_Player . Load ( noteData );
2004-12-20 06:25:59 +00:00
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_PlayerController = PC_HUMAN ;
2004-12-01 04:02:00 +00:00
m_Player . SetXY ( PLAYER_X , PLAYER_Y );
2002-05-20 08:59:37 +00:00
2003-04-12 18:34:05 +00:00
m_In . Load ( THEME -> GetPathToB ( "ScreenEdit in" ) );
m_In . StartTransitioning ();
m_Out . Load ( THEME -> GetPathToB ( "ScreenEdit out" ) );
2002-05-20 08:59:37 +00:00
2005-01-15 04:01:56 +00:00
m_sprOverlay . LoadAndSetName ( m_sName , "Overlay" );
SET_XY_AND_ON_COMMAND ( m_sprOverlay );
2002-05-20 08:59:37 +00:00
2003-04-12 17:39:27 +00:00
m_textHelp . LoadFromFont ( THEME -> GetPathToF ( "Common normal" ) );
2003-02-18 23:15:38 +00:00
m_textHelp . SetXY ( HELP_TEXT_X , HELP_TEXT_Y );
2002-06-29 11:59:09 +00:00
m_textHelp . SetHorizAlign ( Actor :: align_left );
2003-02-18 23:15:38 +00:00
m_textHelp . SetVertAlign ( Actor :: align_top );
2002-06-29 11:59:09 +00:00
m_textHelp . SetZoom ( 0.5f );
m_textHelp . SetText ( HELP_TEXT );
2004-03-20 02:59:08 +00:00
m_textHelp . SetShadowLength ( 0 );
2002-05-20 08:59:37 +00:00
2003-04-12 17:39:27 +00:00
m_textInfo . LoadFromFont ( THEME -> GetPathToF ( "Common normal" ) );
2003-02-18 23:15:38 +00:00
m_textInfo . SetXY ( INFO_TEXT_X , INFO_TEXT_Y );
m_textInfo . SetHorizAlign ( Actor :: align_left );
m_textInfo . SetVertAlign ( Actor :: align_top );
m_textInfo . SetZoom ( 0.5f );
2004-03-20 02:59:08 +00:00
m_textInfo . SetShadowLength ( 0 );
2003-02-18 23:15:38 +00:00
//m_textInfo.SetText(); // set this below every frame
2002-06-29 11:59:09 +00:00
2003-04-12 17:39:27 +00:00
m_soundChangeLine . Load ( THEME -> GetPathToS ( "ScreenEdit line" ) );
m_soundChangeSnap . Load ( THEME -> GetPathToS ( "ScreenEdit snap" ) );
m_soundMarker . Load ( THEME -> GetPathToS ( "ScreenEdit marker" ) );
2002-05-20 08:59:37 +00:00
2002-06-29 11:59:09 +00:00
2005-01-15 18:33:09 +00:00
m_soundMusic . Load ( m_pSong -> GetMusicPath () );
2002-05-20 08:59:37 +00:00
2005-01-15 18:33:09 +00:00
m_soundAssistTick . Load ( THEME -> GetPathToS ( "ScreenEdit assist tick" ) );
2004-05-03 01:37:49 +00:00
this -> HandleScreenMessage ( SM_DoUpdateTextInfo );
2002-05-20 08:59:37 +00:00
}
ScreenEdit ::~ ScreenEdit ()
{
2002-07-31 19:40:40 +00:00
LOG -> Trace ( "ScreenEdit::~ScreenEdit()" );
2002-12-22 08:51:41 +00:00
m_soundMusic . StopPlaying ();
2002-05-20 08:59:37 +00:00
}
2002-10-18 01:09:59 +00:00
// play assist ticks
2004-01-12 09:36:01 +00:00
void ScreenEdit :: PlayTicks ()
2002-10-18 01:09:59 +00:00
{
2004-01-12 09:36:01 +00:00
if ( ! GAMESTATE -> m_SongOptions . m_bAssistTick || m_EditMode != MODE_PLAYING )
return ;
/* 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. This is just to make sure that we request the sound early enough for it to
* come out on time; the actual precise timing is handled by SetStartTime. */
2002-10-18 01:09:59 +00:00
float fPositionSeconds = GAMESTATE -> m_fMusicSeconds ;
2004-01-12 09:36:01 +00:00
fPositionSeconds += SOUND -> GetPlayLatency () + ( float ) TICK_EARLY_SECONDS + 0.250f ;
const float fSongBeat = GAMESTATE -> m_pCurSong -> GetBeatFromElapsedTime ( fPositionSeconds );
2002-10-18 01:09:59 +00:00
2004-01-12 09:36:01 +00:00
const int iSongRow = max ( 0 , BeatToNoteRowNotRounded ( fSongBeat ) );
2004-04-04 04:12:26 +00:00
static int iRowLastCrossed = - 1 ;
if ( iSongRow < iRowLastCrossed )
2004-06-06 05:28:58 +00:00
iRowLastCrossed = iSongRow ;
2002-10-18 01:09:59 +00:00
2004-01-12 09:36:01 +00:00
int iTickRow = - 1 ;
2004-12-03 23:50:20 +00:00
// for each index we crossed since the last update:
FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE ( m_Player . m_NoteData , r , iRowLastCrossed + 1 , iSongRow )
2004-10-23 17:43:49 +00:00
if ( m_Player . m_NoteData . IsThereATapOrHoldHeadAtRow ( r ) )
2004-01-12 09:36:01 +00:00
iTickRow = r ;
2002-10-18 01:09:59 +00:00
2004-01-12 09:36:01 +00:00
iRowLastCrossed = iSongRow ;
2002-10-18 01:09:59 +00:00
2004-01-12 09:36:01 +00:00
if ( iTickRow != - 1 )
{
const float fTickBeat = NoteRowToBeat ( iTickRow );
const float fTickSecond = GAMESTATE -> m_pCurSong -> m_Timing . GetElapsedTimeFromBeat ( fTickBeat );
float fSecondsUntil = fTickSecond - GAMESTATE -> m_fMusicSeconds ;
fSecondsUntil /= m_soundMusic . GetPlaybackRate (); /* 2x music rate means the time until the tick is halved */
2002-10-18 01:09:59 +00:00
2004-02-28 02:09:46 +00:00
RageSoundParams p ;
2004-04-04 04:11:43 +00:00
p . StartTime = GAMESTATE -> m_LastBeatUpdate + ( fSecondsUntil - ( float ) TICK_EARLY_SECONDS );
2004-02-28 02:09:46 +00:00
m_soundAssistTick . Play ( & p );
2004-01-12 09:36:01 +00:00
}
2002-10-18 01:09:59 +00:00
}
2002-05-20 08:59:37 +00:00
2003-03-05 02:38:17 +00:00
void ScreenEdit :: PlayPreviewMusic ()
{
2003-07-26 22:53:22 +00:00
SOUND -> PlayMusic ( "" );
2004-04-04 05:39:10 +00:00
SOUND -> PlayMusic ( m_pSong -> GetMusicPath (), false ,
2003-03-05 02:38:17 +00:00
m_pSong -> m_fMusicSampleStartSeconds ,
m_pSong -> m_fMusicSampleLengthSeconds ,
1.5f );
}
2002-05-20 08:59:37 +00:00
void ScreenEdit :: Update ( float fDeltaTime )
{
2004-01-18 06:57:59 +00:00
if ( m_soundMusic . IsPlaying () )
{
RageTimer tm ;
const float fSeconds = m_soundMusic . GetPositionSeconds ( NULL , & tm );
GAMESTATE -> UpdateSongPosition ( fSeconds , GAMESTATE -> m_pCurSong -> m_Timing , tm );
}
2002-08-01 20:30:40 +00:00
2002-10-18 19:01:32 +00:00
if ( m_EditMode == MODE_RECORDING )
{
// add or extend holds
2004-06-28 07:26:00 +00:00
for ( int t = 0 ; t < GAMESTATE -> GetCurrentStyle () -> m_iColsPerPlayer ; t ++ ) // for each track
2002-10-18 19:01:32 +00:00
{
StyleInput StyleI ( PLAYER_1 , t );
float fSecsHeld = INPUTMAPPER -> GetSecsHeld ( StyleI );
2004-06-11 05:08:25 +00:00
if ( fSecsHeld > RECORD_HOLD_SECONDS && GAMESTATE -> m_fSongBeat > 0 )
2002-10-18 19:01:32 +00:00
{
// add or extend hold
const float fHoldStartSeconds = m_soundMusic . GetPositionSeconds () - fSecsHeld ;
2004-06-11 05:08:25 +00:00
float fStartBeat = max ( 0 , m_pSong -> GetBeatFromElapsedTime ( fHoldStartSeconds ) );
float fEndBeat = max ( fStartBeat , GAMESTATE -> m_fSongBeat );
2002-10-18 19:01:32 +00:00
// Round hold start and end to the nearest snap interval
2004-10-24 17:44:51 +00:00
fStartBeat = Quantize ( fStartBeat , NoteTypeToBeat ( m_SnapDisplay . GetNoteType ()) );
fEndBeat = Quantize ( fEndBeat , NoteTypeToBeat ( m_SnapDisplay . GetNoteType ()) );
2002-10-18 19:01:32 +00:00
// create a new hold note
2003-12-16 04:00:39 +00:00
HoldNote newHN ( t , BeatToNoteRow ( fStartBeat ), BeatToNoteRow ( fEndBeat ) );
2005-01-22 02:50:45 +00:00
m_NoteDataRecord . AddHoldNote ( newHN );
2002-10-18 19:01:32 +00:00
}
}
}
2002-07-28 20:28:37 +00:00
if ( m_EditMode == MODE_RECORDING || m_EditMode == MODE_PLAYING )
2002-05-20 08:59:37 +00:00
{
2004-01-23 08:25:00 +00:00
if ( PREFSMAN -> m_bEditorShowBGChangesPlay )
{
m_Background . Update ( fDeltaTime );
m_Foreground . Update ( fDeltaTime );
}
2003-03-13 08:43:04 +00:00
// check for end of playback/record
2002-05-20 08:59:37 +00:00
2005-01-23 23:17:12 +00:00
if ( GAMESTATE -> m_fSongBeat > NoteRowToBeat ( m_NoteFieldEdit . m_iEndMarker ) + 4 ) // give a one measure lead out
2002-05-20 08:59:37 +00:00
{
2002-07-28 20:28:37 +00:00
if ( m_EditMode == MODE_RECORDING )
2002-05-20 08:59:37 +00:00
{
2002-08-18 23:20:18 +00:00
TransitionFromRecordToEdit ();
2002-05-20 08:59:37 +00:00
}
2002-07-28 20:28:37 +00:00
else if ( m_EditMode == MODE_PLAYING )
2002-05-20 08:59:37 +00:00
{
2002-10-18 00:45:09 +00:00
TransitionToEdit ();
2002-05-20 08:59:37 +00:00
}
2005-01-23 23:17:12 +00:00
GAMESTATE -> m_fSongBeat = NoteRowToBeat ( m_NoteFieldEdit . m_iEndMarker );
2002-05-20 08:59:37 +00:00
}
}
2002-08-13 23:26:46 +00:00
m_SnapDisplay . Update ( fDeltaTime );
2002-07-28 20:28:37 +00:00
m_NoteFieldEdit . Update ( fDeltaTime );
2003-04-12 18:34:05 +00:00
m_In . Update ( fDeltaTime );
m_Out . Update ( fDeltaTime );
2005-01-15 04:01:56 +00:00
m_sprOverlay -> Update ( fDeltaTime );
2002-06-29 11:59:09 +00:00
m_textHelp . Update ( fDeltaTime );
2002-05-20 08:59:37 +00:00
m_textInfo . Update ( fDeltaTime );
2002-08-17 06:44:04 +00:00
m_rectRecordBack . Update ( fDeltaTime );
2002-05-20 08:59:37 +00:00
2002-07-28 20:28:37 +00:00
if ( m_EditMode == MODE_RECORDING )
m_NoteFieldRecord . Update ( fDeltaTime );
2002-05-20 08:59:37 +00:00
2002-07-28 20:28:37 +00:00
if ( m_EditMode == MODE_PLAYING )
2002-05-20 08:59:37 +00:00
{
2002-07-28 20:28:37 +00:00
m_Player . Update ( fDeltaTime );
2002-05-20 08:59:37 +00:00
}
2002-07-31 19:40:40 +00:00
//LOG->Trace( "ScreenEdit::Update(%f)", fDeltaTime );
2002-05-20 08:59:37 +00:00
Screen :: Update ( fDeltaTime );
2002-06-29 11:59:09 +00:00
// Update trailing beat
2002-08-01 20:30:40 +00:00
float fDelta = GAMESTATE -> m_fSongBeat - m_fTrailingBeat ;
2002-06-29 11:59:09 +00:00
if ( fabsf ( fDelta ) < 0.01 )
2002-05-20 08:59:37 +00:00
{
2002-08-01 20:30:40 +00:00
m_fTrailingBeat = GAMESTATE -> m_fSongBeat ; // snap
2002-05-20 08:59:37 +00:00
}
2002-06-29 11:59:09 +00:00
else
{
float fSign = fDelta / fabsf ( fDelta );
2004-12-20 06:25:59 +00:00
float fMoveDelta = fSign * fDeltaTime * 40 / GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_CurrentPlayerOptions . m_fScrollSpeed ;
2002-06-29 11:59:09 +00:00
if ( fabsf ( fMoveDelta ) > fabsf ( fDelta ) )
fMoveDelta = fDelta ;
2002-08-01 20:30:40 +00:00
m_fTrailingBeat += fMoveDelta ;
2002-06-29 11:59:09 +00:00
if ( fabsf ( fDelta ) > 10 )
2004-05-23 20:41:39 +00:00
{
/* We're far off; move faster. Be sure to not overshoot. */
fMoveDelta = fDelta * fDeltaTime * 5 ;
float fNewDelta = GAMESTATE -> m_fSongBeat - m_fTrailingBeat ;
if ( fabsf ( fMoveDelta ) > fabsf ( fNewDelta ) )
fMoveDelta = fNewDelta ;
m_fTrailingBeat += fMoveDelta ;
}
2002-06-29 11:59:09 +00:00
}
2002-07-28 20:28:37 +00:00
m_NoteFieldEdit . Update ( fDeltaTime );
2002-05-20 08:59:37 +00:00
2004-01-12 09:36:01 +00:00
PlayTicks ();
2003-03-30 20:43:30 +00:00
}
2002-08-29 04:56:03 +00:00
2003-03-30 20:43:30 +00:00
void ScreenEdit :: UpdateTextInfo ()
{
2005-01-22 02:50:45 +00:00
int iNumTapNotes = m_NoteDataEdit . GetNumTapNotes ();
int iNumHoldNotes = m_NoteDataEdit . GetNumHoldNotes ();
2002-08-29 04:56:03 +00:00
2005-01-15 13:05:33 +00:00
CString sNoteType = NoteTypeToString ( m_SnapDisplay . GetNoteType ()) + " notes" ;
2002-05-20 08:59:37 +00:00
2003-03-30 20:43:30 +00:00
CString sText ;
sText += ssprintf ( "Current Beat: \n %.2f \n " , GAMESTATE -> m_fSongBeat );
2003-08-17 05:30:46 +00:00
sText += ssprintf ( "Current Second: \n %.2f \n " , m_pSong -> GetElapsedTimeFromBeat ( GAMESTATE -> m_fSongBeat ) );
2003-04-25 00:01:35 +00:00
sText += ssprintf ( "Snap to: \n %s \n " , sNoteType . c_str () );
2005-01-23 23:17:12 +00:00
sText += ssprintf ( "Selection begin: \n %s \n " , m_NoteFieldEdit . m_iBeginMarker ==- 1 ? "not set" : ssprintf ( "%.2f" , NoteRowToBeat ( m_NoteFieldEdit . m_iBeginMarker )). c_str () );
sText += ssprintf ( "Selection end: \n %s \n " , m_NoteFieldEdit . m_iEndMarker ==- 1 ? "not set" : ssprintf ( "%.2f" , NoteRowToBeat ( m_NoteFieldEdit . m_iEndMarker )). c_str () );
2004-05-24 03:41:39 +00:00
sText += ssprintf ( "Difficulty: \n %s \n " , DifficultyToString ( m_pSteps -> GetDifficulty () ). c_str () );
2004-05-24 06:12:17 +00:00
sText += ssprintf ( "Description: \n %s \n " , GAMESTATE -> m_pCurSteps [ PLAYER_1 ] ? GAMESTATE -> m_pCurSteps [ PLAYER_1 ] -> GetDescription (). c_str () : "no description" );
2003-04-25 00:01:35 +00:00
sText += ssprintf ( "Main title: \n %s \n " , m_pSong -> m_sMainTitle . c_str () );
2003-10-03 03:32:08 +00:00
sText += ssprintf ( "Sub title: \n %s \n " , m_pSong -> m_sSubTitle . c_str () );
2004-05-24 04:26:54 +00:00
sText += ssprintf ( "Tap Steps: \n %d \n " , iNumTapNotes );
2003-08-03 00:13:55 +00:00
sText += ssprintf ( "Hold Steps: \n %d \n " , iNumHoldNotes );
2003-12-18 04:48:26 +00:00
sText += ssprintf ( "Beat 0 Offset: \n %.3f secs \n " , m_pSong -> m_Timing . m_fBeat0OffsetInSeconds );
2003-03-30 20:43:30 +00:00
sText += ssprintf ( "Preview Start: \n %.2f secs \n " , m_pSong -> m_fMusicSampleStartSeconds );
sText += ssprintf ( "Preview Length: \n %.2f secs \n " , m_pSong -> m_fMusicSampleLengthSeconds );
2002-08-29 04:56:03 +00:00
2003-03-30 20:43:30 +00:00
m_textInfo . SetText ( sText );
2002-05-20 08:59:37 +00:00
}
void ScreenEdit :: DrawPrimitives ()
{
2003-02-19 07:59:00 +00:00
// m_rectRecordBack.Draw();
2002-08-01 20:30:40 +00:00
2003-02-19 07:59:00 +00:00
switch ( m_EditMode )
2002-05-20 08:59:37 +00:00
{
2003-02-19 07:59:00 +00:00
case MODE_EDITING :
{
2005-01-15 04:01:56 +00:00
m_sprOverlay -> Draw ();
2003-08-24 17:03:33 +00:00
m_textHelp . Draw ();
m_textInfo . Draw ();
2003-02-19 07:59:00 +00:00
m_SnapDisplay . Draw ();
// HACK: Make NoteFieldEdit draw using the trailing beat
float fSongBeat = GAMESTATE -> m_fSongBeat ; // save song beat
GAMESTATE -> m_fSongBeat = m_fTrailingBeat ; // put trailing beat in effect
m_NoteFieldEdit . Draw ();
GAMESTATE -> m_fSongBeat = fSongBeat ; // restore real song beat
}
break ;
case MODE_RECORDING :
2004-01-23 08:25:00 +00:00
if ( PREFSMAN -> m_bEditorShowBGChangesPlay )
m_Background . Draw ();
2005-01-15 04:15:15 +00:00
m_sprOverlay -> Draw ();
2002-05-20 08:59:37 +00:00
m_NoteFieldRecord . Draw ();
2004-01-23 08:25:00 +00:00
if ( PREFSMAN -> m_bEditorShowBGChangesPlay )
m_Foreground . Draw ();
2003-02-19 07:59:00 +00:00
break ;
case MODE_PLAYING :
2004-01-23 08:25:00 +00:00
if ( PREFSMAN -> m_bEditorShowBGChangesPlay )
m_Background . Draw ();
2005-01-15 04:15:15 +00:00
m_sprOverlay -> Draw ();
2002-05-20 08:59:37 +00:00
m_Player . Draw ();
2004-01-23 08:25:00 +00:00
if ( PREFSMAN -> m_bEditorShowBGChangesPlay )
m_Foreground . Draw ();
2003-02-19 07:59:00 +00:00
break ;
default :
ASSERT ( 0 );
2002-05-20 08:59:37 +00:00
}
2005-01-15 04:31:35 +00:00
m_In . Draw ();
m_Out . Draw ();
2002-05-20 08:59:37 +00:00
Screen :: DrawPrimitives ();
}
void ScreenEdit :: Input ( const DeviceInput & DeviceI , const InputEventType type , const GameInput & GameI , const MenuInput & MenuI , const StyleInput & StyleI )
{
2003-02-25 00:33:42 +00:00
// LOG->Trace( "ScreenEdit::Input()" );
2002-05-20 08:59:37 +00:00
2003-04-12 18:34:05 +00:00
if ( m_In . IsTransitioning () || m_Out . IsTransitioning () )
return ;
2005-01-14 23:17:04 +00:00
const DeviceInput & di = DeviceI ;
2004-10-28 07:56:13 +00:00
2005-01-14 23:17:04 +00:00
EditButton EditB ;
DeviceToEdit ( di , EditB );
2002-07-28 20:28:37 +00:00
switch ( m_EditMode )
2002-05-20 08:59:37 +00:00
{
2005-01-14 23:17:04 +00:00
case MODE_EDITING : InputEdit ( di , type , GameI , MenuI , StyleI , EditB ); break ;
case MODE_RECORDING : InputRecord ( di , type , GameI , MenuI , StyleI , EditB ); break ;
case MODE_PLAYING : InputPlay ( di , type , GameI , MenuI , StyleI , EditB ); break ;
2002-08-17 06:44:04 +00:00
default : ASSERT ( 0 );
2002-05-20 08:59:37 +00:00
}
2004-05-03 01:37:49 +00:00
2004-05-03 01:39:25 +00:00
/* Make sure the displayed time is up-to-date after possibly changing something,
* so it doesn't feel lagged. */
2004-05-03 01:37:49 +00:00
UpdateTextInfo ();
2002-05-20 08:59:37 +00:00
}
2003-09-07 22:28:46 +00:00
2005-01-14 23:17:04 +00:00
void ScreenEdit :: InputEdit ( const DeviceInput & DeviceI , const InputEventType type , const GameInput & GameI , const MenuInput & MenuI , const StyleInput & StyleI , EditButton EditB )
2002-05-20 08:59:37 +00:00
{
2004-09-09 22:21:50 +00:00
if ( type == IET_LEVEL_CHANGED )
return ; // don't care
2005-01-15 18:33:09 +00:00
if ( type == IET_RELEASE )
2002-08-21 22:48:33 +00:00
{
2005-01-15 18:33:09 +00:00
switch ( EditB )
{
case EDIT_BUTTON_SCROLL_SELECT :
2005-01-23 23:17:12 +00:00
g_iShiftAnchor = - 1 ;
2002-08-21 22:48:33 +00:00
break ;
}
return ;
}
2005-01-23 23:17:12 +00:00
const int iSongBeat = BeatToNoteRow ( GAMESTATE -> m_fSongBeat );
2005-01-14 23:17:04 +00:00
switch ( EditB )
2002-05-20 08:59:37 +00:00
{
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_COLUMN_0 :
case EDIT_BUTTON_COLUMN_1 :
case EDIT_BUTTON_COLUMN_2 :
case EDIT_BUTTON_COLUMN_3 :
case EDIT_BUTTON_COLUMN_4 :
case EDIT_BUTTON_COLUMN_5 :
case EDIT_BUTTON_COLUMN_6 :
case EDIT_BUTTON_COLUMN_7 :
case EDIT_BUTTON_COLUMN_8 :
case EDIT_BUTTON_COLUMN_9 :
2002-05-20 08:59:37 +00:00
{
2002-08-17 06:44:04 +00:00
if ( type != IET_FIRST_PRESS )
break ; // We only care about first presses
2002-05-20 08:59:37 +00:00
2005-01-14 23:17:04 +00:00
int iCol = EditB - EDIT_BUTTON_COLUMN_0 ;
2003-08-31 23:52:02 +00:00
// Alt + number = input to right half
2005-01-14 23:17:04 +00:00
if ( EditIsBeingPressed ( EDIT_BUTTON_RIGHT_SIDE ) )
2005-01-22 02:50:45 +00:00
iCol += m_NoteDataEdit . GetNumTracks () / 2 ;
2003-08-31 23:52:02 +00:00
2003-04-26 06:06:24 +00:00
2002-08-17 06:44:04 +00:00
const float fSongBeat = GAMESTATE -> m_fSongBeat ;
const int iSongIndex = BeatToNoteRow ( fSongBeat );
2002-05-20 08:59:37 +00:00
2005-01-22 02:50:45 +00:00
if ( iCol >= m_NoteDataEdit . GetNumTracks () ) // this button is not in the range of columns for this Style
2002-06-29 11:59:09 +00:00
break ;
2002-05-20 08:59:37 +00:00
2002-08-17 06:44:04 +00:00
// check for to see if the user intended to remove a HoldNote
2005-01-22 02:50:45 +00:00
for ( int i = 0 ; i < m_NoteDataEdit . GetNumHoldNotes (); i ++ ) // for each HoldNote
2002-08-17 06:44:04 +00:00
{
2005-01-22 02:50:45 +00:00
const HoldNote & hn = m_NoteDataEdit . GetHoldNote ( i );
2003-02-16 20:27:53 +00:00
if ( iCol == hn . iTrack && // the notes correspond
2003-12-16 04:00:39 +00:00
hn . RowIsInRange ( iSongIndex ) ) // the cursor lies within this HoldNote
2002-06-29 11:59:09 +00:00
{
2005-01-22 02:50:45 +00:00
m_NoteDataEdit . RemoveHoldNote ( i );
2003-11-15 08:51:47 +00:00
return ;
2002-06-29 11:59:09 +00:00
}
2002-08-17 06:44:04 +00:00
}
2002-06-29 11:59:09 +00:00
2005-01-22 02:50:45 +00:00
if ( m_NoteDataEdit . GetTapNote ( iCol , iSongIndex ). type != TapNote :: empty )
2003-11-15 08:51:47 +00:00
{
2005-01-22 02:50:45 +00:00
m_NoteDataEdit . SetTapNote ( iCol , iSongIndex , TAP_EMPTY );
2003-11-15 08:51:47 +00:00
return ;
}
2005-01-21 06:47:50 +00:00
else if ( EditIsBeingPressed ( EDIT_BUTTON_LAY_MINE ) )
2003-11-15 08:51:47 +00:00
{
2005-01-22 02:50:45 +00:00
m_NoteDataEdit . SetTapNote ( iCol , iSongIndex , TAP_ORIGINAL_MINE );
2003-11-15 08:51:47 +00:00
}
2005-01-21 06:47:50 +00:00
else if ( EditIsBeingPressed ( EDIT_BUTTON_LAY_ATTACK ) )
2003-11-15 08:51:47 +00:00
{
g_iLastInsertAttackTrack = iCol ;
SCREENMAN -> MiniMenu ( & g_InsertAttack , SM_BackFromInsertAttack );
}
else
{
2005-01-22 02:50:45 +00:00
m_NoteDataEdit . SetTapNote ( iCol , iSongIndex , TAP_ORIGINAL_TAP );
2003-11-15 08:51:47 +00:00
}
2002-07-02 00:27:58 +00:00
}
2002-08-17 06:44:04 +00:00
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_SCROLL_SPEED_UP :
case EDIT_BUTTON_SCROLL_SPEED_DOWN :
2002-08-17 06:44:04 +00:00
{
2005-01-14 23:17:04 +00:00
float & fScrollSpeed = GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_PlayerOptions . m_fScrollSpeed ;
float fNewScrollSpeed = fScrollSpeed ;
if ( DeviceI . button == KEY_UP )
2003-02-18 23:15:38 +00:00
{
2005-01-14 23:17:04 +00:00
if ( fScrollSpeed == 4 )
fNewScrollSpeed = 2 ;
else if ( fScrollSpeed == 2 )
fNewScrollSpeed = 1 ;
}
else if ( DeviceI . button == KEY_DOWN )
{
if ( fScrollSpeed == 2 )
fNewScrollSpeed = 4 ;
else if ( fScrollSpeed == 1 )
fNewScrollSpeed = 2 ;
2003-02-18 23:15:38 +00:00
}
2005-01-14 23:17:04 +00:00
if ( fNewScrollSpeed != fScrollSpeed )
2002-08-17 06:44:04 +00:00
{
2005-01-14 23:17:04 +00:00
fScrollSpeed = fNewScrollSpeed ;
m_soundMarker . Play ();
GAMESTATE -> StoreSelectedOptions ();
}
2002-08-17 06:44:04 +00:00
break ;
2005-01-14 23:17:04 +00:00
}
break ;
case EDIT_BUTTON_SCROLL_UP_LINE :
case EDIT_BUTTON_SCROLL_UP_PAGE :
case EDIT_BUTTON_SCROLL_DOWN_LINE :
case EDIT_BUTTON_SCROLL_DOWN_PAGE :
case EDIT_BUTTON_SCROLL_HOME :
case EDIT_BUTTON_SCROLL_END :
{
float fBeatsToMove = 0.f ;
switch ( EditB )
{
case EDIT_BUTTON_SCROLL_UP_LINE :
case EDIT_BUTTON_SCROLL_DOWN_LINE :
fBeatsToMove = NoteTypeToBeat ( m_SnapDisplay . GetNoteType () );
if ( EditB == EDIT_BUTTON_SCROLL_UP_LINE )
2002-08-17 06:44:04 +00:00
fBeatsToMove *= - 1 ;
2005-01-14 23:17:04 +00:00
break ;
case EDIT_BUTTON_SCROLL_UP_PAGE :
case EDIT_BUTTON_SCROLL_DOWN_PAGE :
fBeatsToMove = BEATS_PER_MEASURE ;
if ( EditB == EDIT_BUTTON_SCROLL_UP_PAGE )
fBeatsToMove *= - 1 ;
break ;
case EDIT_BUTTON_SCROLL_HOME :
fBeatsToMove = - GAMESTATE -> m_fSongBeat ;
break ;
case EDIT_BUTTON_SCROLL_END :
2005-01-22 02:50:45 +00:00
fBeatsToMove = m_NoteDataEdit . GetLastBeat () - GAMESTATE -> m_fSongBeat ;
2005-01-14 23:17:04 +00:00
break ;
2002-08-17 06:44:04 +00:00
}
const float fStartBeat = GAMESTATE -> m_fSongBeat ;
const float fEndBeat = GAMESTATE -> m_fSongBeat + fBeatsToMove ;
// check to see if they're holding a button
2003-08-31 23:52:02 +00:00
for ( int n = 0 ; n <= 9 ; n ++ ) // for each number key
2002-08-17 06:44:04 +00:00
{
2003-08-31 23:52:02 +00:00
int iCol = n ;
// Ctrl + number = input to right half
2005-01-14 23:17:04 +00:00
if ( EditIsBeingPressed ( EDIT_BUTTON_RIGHT_SIDE ) )
2005-01-22 02:50:45 +00:00
iCol += m_NoteDataEdit . GetNumTracks () / 2 ;
2003-08-31 23:52:02 +00:00
2005-01-22 02:50:45 +00:00
if ( iCol >= m_NoteDataEdit . GetNumTracks () )
2003-08-31 23:52:02 +00:00
continue ; // skip
2005-01-14 23:17:04 +00:00
EditButton b = EditButton ( EDIT_BUTTON_COLUMN_0 + n );
if ( ! EditIsBeingPressed ( b ) )
2002-08-21 22:48:33 +00:00
continue ;
// create a new hold note
2003-12-16 04:00:39 +00:00
HoldNote newHN ( iCol , BeatToNoteRow ( min ( fStartBeat , fEndBeat )), BeatToNoteRow ( max ( fStartBeat , fEndBeat )) );
2002-09-09 05:22:02 +00:00
2003-12-16 04:00:39 +00:00
newHN . iStartRow = max ( newHN . iStartRow , 0 );
newHN . iEndRow = max ( newHN . iEndRow , 0 );
2002-09-09 05:22:02 +00:00
2005-01-22 02:50:45 +00:00
m_NoteDataEdit . AddHoldNote ( newHN );
2002-08-21 22:48:33 +00:00
}
2005-01-14 23:17:04 +00:00
if ( EditIsBeingPressed ( EDIT_BUTTON_SCROLL_SELECT ) )
2002-08-21 22:48:33 +00:00
{
/* Shift is being held.
*
* If this is the first time we've moved since shift was depressed,
* the old position (before this move) becomes the start pos: */
2005-01-23 23:17:12 +00:00
int iEndBeat = BeatToNoteRow ( fEndBeat );
if ( g_iShiftAnchor == - 1 )
g_iShiftAnchor = BeatToNoteRow ( fStartBeat );
2002-08-21 22:48:33 +00:00
2005-01-23 23:17:12 +00:00
if ( iEndBeat == g_iShiftAnchor )
2002-08-17 06:44:04 +00:00
{
2002-08-21 22:48:33 +00:00
/* We're back at the anchor, so we have nothing selected. */
2005-01-23 23:17:12 +00:00
m_NoteFieldEdit . m_iBeginMarker = m_NoteFieldEdit . m_iEndMarker = - 1 ;
2002-08-21 22:48:33 +00:00
}
else
{
2005-01-23 23:17:12 +00:00
m_NoteFieldEdit . m_iBeginMarker = g_iShiftAnchor ;
m_NoteFieldEdit . m_iEndMarker = iEndBeat ;
if ( m_NoteFieldEdit . m_iBeginMarker > m_NoteFieldEdit . m_iEndMarker )
swap ( m_NoteFieldEdit . m_iBeginMarker , m_NoteFieldEdit . m_iEndMarker );
2002-08-17 06:44:04 +00:00
}
}
GAMESTATE -> m_fSongBeat += fBeatsToMove ;
2003-03-06 22:50:44 +00:00
GAMESTATE -> m_fSongBeat = max ( GAMESTATE -> m_fSongBeat , 0 );
2004-10-24 17:44:51 +00:00
GAMESTATE -> m_fSongBeat = Quantize ( GAMESTATE -> m_fSongBeat , NoteTypeToBeat ( m_SnapDisplay . GetNoteType ()) );
2002-08-17 06:44:04 +00:00
m_soundChangeLine . Play ();
}
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_SNAP_NEXT :
2004-08-13 02:41:19 +00:00
if ( m_SnapDisplay . PrevSnapMode () )
OnSnapModeChange ();
2002-08-17 06:44:04 +00:00
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_SNAP_PREV :
2004-08-13 02:41:19 +00:00
if ( m_SnapDisplay . NextSnapMode () )
OnSnapModeChange ();
2002-08-17 06:44:04 +00:00
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_LAY_SELECT :
2005-01-23 23:17:12 +00:00
if ( m_NoteFieldEdit . m_iBeginMarker ==- 1 && m_NoteFieldEdit . m_iEndMarker ==- 1 )
2002-08-17 06:44:04 +00:00
{
2003-02-18 23:15:38 +00:00
// lay begin marker
2005-01-23 23:17:12 +00:00
m_NoteFieldEdit . m_iBeginMarker = BeatToNoteRow ( GAMESTATE -> m_fSongBeat );
2002-08-17 06:44:04 +00:00
}
2005-01-23 23:17:12 +00:00
else if ( m_NoteFieldEdit . m_iEndMarker ==- 1 ) // only begin marker is laid
2002-08-17 06:44:04 +00:00
{
2005-01-23 23:17:12 +00:00
if ( iSongBeat == m_NoteFieldEdit . m_iBeginMarker )
2002-08-17 06:44:04 +00:00
{
2005-01-23 23:17:12 +00:00
m_NoteFieldEdit . m_iBeginMarker = - 1 ;
2002-08-17 06:44:04 +00:00
}
else
{
2005-01-23 23:17:12 +00:00
m_NoteFieldEdit . m_iEndMarker = max ( m_NoteFieldEdit . m_iBeginMarker , iSongBeat );
m_NoteFieldEdit . m_iBeginMarker = min ( m_NoteFieldEdit . m_iBeginMarker , iSongBeat );
2002-08-17 06:44:04 +00:00
}
}
2003-02-18 23:15:38 +00:00
else // both markers are laid
{
2005-01-23 23:17:12 +00:00
m_NoteFieldEdit . m_iBeginMarker = iSongBeat ;
m_NoteFieldEdit . m_iEndMarker = - 1 ;
2003-02-18 23:15:38 +00:00
}
m_soundMarker . Play ();
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_OPEN_AREA_MENU :
2003-02-18 23:15:38 +00:00
{
// update enabled/disabled in g_AreaMenu
2005-01-23 23:17:12 +00:00
bool bAreaSelected = m_NoteFieldEdit . m_iBeginMarker !=- 1 && m_NoteFieldEdit . m_iEndMarker !=- 1 ;
2003-03-15 19:25:37 +00:00
g_AreaMenu . rows [ cut ]. enabled = bAreaSelected ;
g_AreaMenu . rows [ copy ]. enabled = bAreaSelected ;
g_AreaMenu . rows [ paste_at_current_beat ]. enabled = this -> m_Clipboard . GetLastBeat () != 0 ;
2005-01-23 23:17:12 +00:00
g_AreaMenu . rows [ paste_at_begin_marker ]. enabled = this -> m_Clipboard . GetLastBeat () != 0 && m_NoteFieldEdit . m_iBeginMarker !=- 1 ;
2003-03-15 19:25:37 +00:00
g_AreaMenu . rows [ clear ]. enabled = bAreaSelected ;
g_AreaMenu . rows [ quantize ]. enabled = bAreaSelected ;
g_AreaMenu . rows [ turn ]. enabled = bAreaSelected ;
g_AreaMenu . rows [ transform ]. enabled = bAreaSelected ;
g_AreaMenu . rows [ alter ]. enabled = bAreaSelected ;
2003-09-07 22:28:46 +00:00
g_AreaMenu . rows [ tempo ]. enabled = bAreaSelected ;
2003-03-15 19:25:37 +00:00
g_AreaMenu . rows [ play ]. enabled = bAreaSelected ;
g_AreaMenu . rows [ record ]. enabled = bAreaSelected ;
2003-11-03 10:44:19 +00:00
g_AreaMenu . rows [ convert_beat_to_pause ]. enabled = bAreaSelected ;
2003-02-18 23:15:38 +00:00
SCREENMAN -> MiniMenu ( & g_AreaMenu , SM_BackFromAreaMenu );
}
2002-08-17 06:44:04 +00:00
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_OPEN_EDIT_MENU :
2003-02-18 23:15:38 +00:00
SCREENMAN -> MiniMenu ( & g_MainMenu , SM_BackFromMainMenu );
2002-08-17 06:44:04 +00:00
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_OPEN_INPUT_HELP :
2003-02-19 05:46:09 +00:00
SCREENMAN -> MiniMenu ( & g_KeyboardShortcuts , SM_None );
2002-08-29 04:56:03 +00:00
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_TOGGLE_ASSIST_TICK :
2003-04-23 01:23:14 +00:00
GAMESTATE -> m_SongOptions . m_bAssistTick ^= 1 ;
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_OPEN_NEXT_STEPS :
case EDIT_BUTTON_OPEN_PREV_STEPS :
2003-08-24 05:12:08 +00:00
{
// save current steps
2004-05-24 06:12:17 +00:00
Steps * pSteps = GAMESTATE -> m_pCurSteps [ PLAYER_1 ];
2004-05-24 03:41:39 +00:00
ASSERT ( pSteps );
2005-01-22 02:50:45 +00:00
pSteps -> SetNoteData ( m_NoteDataEdit );
2003-08-24 05:12:08 +00:00
// Get all Steps of this StepsType
2004-05-24 03:41:39 +00:00
StepsType st = pSteps -> m_StepsType ;
2003-08-24 05:12:08 +00:00
vector < Steps *> vSteps ;
GAMESTATE -> m_pCurSong -> GetSteps ( vSteps , st );
2004-01-24 20:36:09 +00:00
// Sort them by difficulty.
2004-04-18 07:34:37 +00:00
StepsUtil :: SortStepsByTypeAndDifficulty ( vSteps );
2004-01-24 20:36:09 +00:00
2003-08-24 05:12:08 +00:00
// Find out what index the current Steps are
2004-05-24 03:41:39 +00:00
vector < Steps *>:: iterator it = find ( vSteps . begin (), vSteps . end (), pSteps );
2003-08-24 05:12:08 +00:00
ASSERT ( it != vSteps . end () );
2005-01-14 23:17:04 +00:00
switch ( EditB )
2003-08-24 05:12:08 +00:00
{
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_OPEN_PREV_STEPS :
2003-08-24 05:12:08 +00:00
if ( it == vSteps . begin () )
{
2004-05-01 23:28:53 +00:00
SCREENMAN -> PlayInvalidSound ();
2003-08-24 05:12:08 +00:00
return ;
}
it -- ;
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_OPEN_NEXT_STEPS :
2003-08-24 05:12:08 +00:00
it ++ ;
if ( it == vSteps . end () )
{
2004-05-01 23:28:53 +00:00
SCREENMAN -> PlayInvalidSound ();
2003-08-24 05:12:08 +00:00
return ;
}
break ;
default : ASSERT ( 0 ); return ;
}
2004-05-24 03:41:39 +00:00
pSteps = * it ;
2004-05-24 06:12:17 +00:00
GAMESTATE -> m_pCurSteps [ PLAYER_1 ] = m_pSteps = pSteps ;
2005-01-22 02:50:45 +00:00
pSteps -> GetNoteData ( m_NoteDataEdit );
2003-08-24 05:12:08 +00:00
SCREENMAN -> SystemMessage ( ssprintf (
"Switched to %s %s '%s'" ,
2004-07-12 02:19:24 +00:00
GAMEMAN -> StepsTypeToString ( pSteps -> m_StepsType ). c_str (),
2004-05-24 03:41:39 +00:00
DifficultyToString ( pSteps -> GetDifficulty () ). c_str (),
pSteps -> GetDescription (). c_str () ) );
2003-08-24 05:12:08 +00:00
SOUND -> PlayOnce ( THEME -> GetPathToS ( "ScreenEdit switch" ) );
}
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_BPM_UP :
case EDIT_BUTTON_BPM_DOWN :
2002-08-17 06:44:04 +00:00
{
float fBPM = m_pSong -> GetBPMAtBeat ( GAMESTATE -> m_fSongBeat );
float fDeltaBPM ;
2005-01-14 23:17:04 +00:00
switch ( EditB )
2002-08-17 06:44:04 +00:00
{
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_BPM_UP : fDeltaBPM = + 0.020f ; break ;
case EDIT_BUTTON_BPM_DOWN : fDeltaBPM = - 0.020f ; break ;
2002-09-07 10:31:35 +00:00
default : ASSERT ( 0 ); return ;
2002-08-17 06:44:04 +00:00
}
2005-01-14 23:17:04 +00:00
if ( EditIsBeingPressed ( EDIT_BUTTON_ADJUST_FINE ) )
fDeltaBPM /= 2 ;
2003-06-17 06:24:13 +00:00
else switch ( type )
2002-08-17 06:44:04 +00:00
{
case IET_SLOW_REPEAT : fDeltaBPM *= 10 ; break ;
case IET_FAST_REPEAT : fDeltaBPM *= 40 ; break ;
}
2003-09-07 22:28:46 +00:00
2002-08-17 06:44:04 +00:00
float fNewBPM = fBPM + fDeltaBPM ;
2003-09-07 22:28:46 +00:00
m_pSong -> SetBPMAtBeat ( GAMESTATE -> m_fSongBeat , fNewBPM );
2002-08-17 06:44:04 +00:00
}
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_STOP_UP :
case EDIT_BUTTON_STOP_DOWN :
2002-08-17 06:44:04 +00:00
{
2002-08-23 20:18:29 +00:00
float fStopDelta ;
2005-01-14 23:17:04 +00:00
switch ( EditB )
2002-08-17 06:44:04 +00:00
{
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_STOP_UP : fStopDelta = + 0.020f ; break ;
case EDIT_BUTTON_STOP_DOWN : fStopDelta = - 0.020f ; break ;
2002-09-07 10:31:35 +00:00
default : ASSERT ( 0 ); return ;
2002-08-17 06:44:04 +00:00
}
2005-01-14 23:17:04 +00:00
if ( EditIsBeingPressed ( EDIT_BUTTON_ADJUST_FINE ) )
fStopDelta /= 20 ; /* 1ms */
2003-11-03 08:44:49 +00:00
else switch ( type )
2002-08-17 06:44:04 +00:00
{
2002-08-23 20:18:29 +00:00
case IET_SLOW_REPEAT : fStopDelta *= 10 ; break ;
case IET_FAST_REPEAT : fStopDelta *= 40 ; break ;
2002-08-17 06:44:04 +00:00
}
2002-10-31 02:20:11 +00:00
unsigned i ;
2003-12-18 04:48:26 +00:00
for ( i = 0 ; i < m_pSong -> m_Timing . m_StopSegments . size (); i ++ )
2002-08-17 06:44:04 +00:00
{
2005-01-23 21:55:01 +00:00
if ( m_pSong -> m_Timing . m_StopSegments [ i ]. m_iStartRow == BeatToNoteRow ( GAMESTATE -> m_fSongBeat ) )
2002-08-17 06:44:04 +00:00
break ;
}
2003-12-18 04:48:26 +00:00
if ( i == m_pSong -> m_Timing . m_StopSegments . size () ) // there is no BPMSegment at the current beat
2002-08-17 06:44:04 +00:00
{
// create a new StopSegment
2002-08-23 20:18:29 +00:00
if ( fStopDelta > 0 )
2005-01-23 21:55:01 +00:00
m_pSong -> AddStopSegment ( StopSegment ( BeatToNoteRow ( GAMESTATE -> m_fSongBeat ), fStopDelta ) );
2002-08-17 06:44:04 +00:00
}
2003-12-18 04:48:26 +00:00
else // StopSegment being modified is m_Timing.m_StopSegments[i]
2002-08-17 06:44:04 +00:00
{
2003-12-18 04:48:26 +00:00
m_pSong -> m_Timing . m_StopSegments [ i ]. m_fStopSeconds += fStopDelta ;
if ( m_pSong -> m_Timing . m_StopSegments [ i ]. m_fStopSeconds <= 0 )
m_pSong -> m_Timing . m_StopSegments . erase ( m_pSong -> m_Timing . m_StopSegments . begin () + i ,
m_pSong -> m_Timing . m_StopSegments . begin () + i + 1 );
2002-08-17 06:44:04 +00:00
}
}
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_OFFSET_UP :
case EDIT_BUTTON_OFFSET_DOWN :
2002-08-17 06:44:04 +00:00
{
float fOffsetDelta ;
2005-01-14 23:17:04 +00:00
switch ( EditB )
2002-08-17 06:44:04 +00:00
{
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_OFFSET_DOWN : fOffsetDelta = - 0.02f ; break ;
case EDIT_BUTTON_OFFSET_UP : fOffsetDelta = + 0.02f ; break ;
2002-09-07 10:31:35 +00:00
default : ASSERT ( 0 ); return ;
2002-08-17 06:44:04 +00:00
}
2005-01-14 23:17:04 +00:00
if ( EditIsBeingPressed ( EDIT_BUTTON_ADJUST_FINE ) )
2003-06-10 22:11:22 +00:00
fOffsetDelta /= 20 ; /* 1ms */
else switch ( type )
2002-08-17 06:44:04 +00:00
{
case IET_SLOW_REPEAT : fOffsetDelta *= 10 ; break ;
case IET_FAST_REPEAT : fOffsetDelta *= 40 ; break ;
}
2003-12-18 04:48:26 +00:00
m_pSong -> m_Timing . m_fBeat0OffsetInSeconds += fOffsetDelta ;
2002-08-17 06:44:04 +00:00
}
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_SAMPLE_START_UP :
case EDIT_BUTTON_SAMPLE_START_DOWN :
2002-08-17 06:44:04 +00:00
{
float fDelta ;
2005-01-14 23:17:04 +00:00
switch ( EditB )
2002-08-17 06:44:04 +00:00
{
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_SAMPLE_START_DOWN : fDelta = - 0.02f ; break ;
case EDIT_BUTTON_SAMPLE_START_UP : fDelta = + 0.02f ; break ;
case EDIT_BUTTON_SAMPLE_LENGTH_DOWN : fDelta = - 0.02f ; break ;
case EDIT_BUTTON_SAMPLE_LENGTH_UP : fDelta = + 0.02f ; break ;
2002-09-07 10:31:35 +00:00
default : ASSERT ( 0 ); return ;
2002-08-17 06:44:04 +00:00
}
switch ( type )
{
case IET_SLOW_REPEAT : fDelta *= 10 ; break ;
case IET_FAST_REPEAT : fDelta *= 40 ; break ;
}
2005-01-14 23:17:04 +00:00
if ( EditB == EDIT_BUTTON_SAMPLE_LENGTH_DOWN || EditB == EDIT_BUTTON_SAMPLE_LENGTH_UP )
2002-08-21 22:48:33 +00:00
{
m_pSong -> m_fMusicSampleLengthSeconds += fDelta ;
m_pSong -> m_fMusicSampleLengthSeconds = max ( m_pSong -> m_fMusicSampleLengthSeconds , 0 );
} else {
m_pSong -> m_fMusicSampleStartSeconds += fDelta ;
m_pSong -> m_fMusicSampleStartSeconds = max ( m_pSong -> m_fMusicSampleStartSeconds , 0 );
}
2002-08-17 06:44:04 +00:00
}
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_PLAY_SAMPLE_MUSIC :
2003-03-05 02:38:17 +00:00
PlayPreviewMusic ();
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_OPEN_BGA_MENU :
2003-03-16 00:05:23 +00:00
HandleMainMenuChoice ( edit_bg_change , NULL );
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_OPEN_COURSE_MENU :
2004-01-26 20:56:58 +00:00
{
g_CourseMode . rows [ 0 ]. choices . clear ();
g_CourseMode . rows [ 0 ]. choices . push_back ( "OFF" );
g_CourseMode . rows [ 0 ]. defaultChoice = 0 ;
vector < Course *> courses ;
SONGMAN -> GetAllCourses ( courses , false );
for ( unsigned i = 0 ; i < courses . size (); ++ i )
{
const Course * crs = courses [ i ];
bool bUsesThisSong = false ;
for ( unsigned e = 0 ; e < crs -> m_entries . size (); ++ e )
{
if ( crs -> m_entries [ e ]. type != COURSE_ENTRY_FIXED )
continue ;
if ( crs -> m_entries [ e ]. pSong != m_pSong )
continue ;
bUsesThisSong = true ;
}
if ( bUsesThisSong )
{
2004-07-11 10:02:38 +00:00
g_CourseMode . rows [ 0 ]. choices . push_back ( crs -> GetFullDisplayTitle () );
2004-01-26 20:56:58 +00:00
if ( crs == m_pAttacksFromCourse )
g_CourseMode . rows [ 0 ]. defaultChoice = g_CourseMode . rows [ 0 ]. choices . size () - 1 ;
}
}
SCREENMAN -> MiniMenu ( & g_CourseMode , SM_BackFromCourseModeMenu );
break ;
}
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_PLAY_FROM_START :
HandleMainMenuChoice ( play_whole_song , NULL );
2003-02-22 01:58:56 +00:00
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_PLAY_FROM_CURSOR :
HandleMainMenuChoice ( play_current_beat_to_end , NULL );
2003-04-21 03:09:48 +00:00
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_PLAY_SELECTION :
2005-01-23 23:17:12 +00:00
if ( m_NoteFieldEdit . m_iBeginMarker !=- 1 && m_NoteFieldEdit . m_iEndMarker !=- 1 )
2005-01-14 23:17:04 +00:00
HandleAreaMenuChoice ( play , NULL );
else
HandleMainMenuChoice ( play_current_beat_to_end , NULL );
2003-03-16 00:31:23 +00:00
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_RECORD :
2005-01-23 23:17:12 +00:00
if ( m_NoteFieldEdit . m_iBeginMarker !=- 1 && m_NoteFieldEdit . m_iEndMarker !=- 1 )
2005-01-14 23:17:04 +00:00
HandleAreaMenuChoice ( record , NULL );
break ;
case EDIT_BUTTON_INSERT :
HandleAreaMenuChoice ( insert_and_shift , NULL );
SCREENMAN -> PlayInvalidSound ();
break ;
case EDIT_BUTTON_INSERT_SHIFT_PAUSES :
HandleAreaMenuChoice ( shift_pauses_forward , NULL );
SCREENMAN -> PlayInvalidSound ();
break ;
case EDIT_BUTTON_DELETE :
HandleAreaMenuChoice ( delete_and_shift , NULL );
SCREENMAN -> PlayInvalidSound ();
break ;
case EDIT_BUTTON_DELETE_SHIFT_PAUSES :
HandleAreaMenuChoice ( shift_pauses_backward , NULL );
SCREENMAN -> PlayInvalidSound ();
2003-03-16 00:31:23 +00:00
break ;
2002-05-20 08:59:37 +00:00
}
}
2005-01-14 23:17:04 +00:00
void ScreenEdit :: InputRecord ( const DeviceInput & DeviceI , const InputEventType type , const GameInput & GameI , const MenuInput & MenuI , const StyleInput & StyleI , EditButton EditB )
2002-05-20 08:59:37 +00:00
{
2005-01-14 23:17:04 +00:00
if ( EditB == EDIT_BUTTON_RETURN_TO_EDIT )
2002-05-20 08:59:37 +00:00
{
2002-10-18 19:01:32 +00:00
TransitionFromRecordToEdit ();
return ;
}
if ( StyleI . player != PLAYER_1 )
return ; // ignore
const int iCol = StyleI . col ;
switch ( type )
{
case IET_FIRST_PRESS :
2002-05-20 08:59:37 +00:00
{
2002-10-18 19:01:32 +00:00
// Add a tap
float fBeat = GAMESTATE -> m_fSongBeat ;
2004-10-24 17:44:51 +00:00
fBeat = Quantize ( fBeat , NoteTypeToBeat ( m_SnapDisplay . GetNoteType ()) );
2002-10-18 19:01:32 +00:00
const int iRow = BeatToNoteRow ( fBeat );
if ( iRow < 0 )
2002-10-18 02:02:53 +00:00
break ;
2002-05-20 08:59:37 +00:00
2005-01-22 02:50:45 +00:00
m_NoteDataRecord . SetTapNote ( iCol , iRow , TAP_ORIGINAL_TAP );
2004-07-02 20:08:17 +00:00
m_NoteFieldRecord . Step ( iCol , TNS_MARVELOUS );
2002-10-18 19:01:32 +00:00
}
break ;
case IET_SLOW_REPEAT :
case IET_FAST_REPEAT :
case IET_RELEASE :
// don't add or extend holds here
break ;
2002-05-20 08:59:37 +00:00
}
}
2005-01-14 23:17:04 +00:00
void ScreenEdit :: InputPlay ( const DeviceInput & DeviceI , const InputEventType type , const GameInput & GameI , const MenuInput & MenuI , const StyleInput & StyleI , EditButton EditB )
2002-05-20 08:59:37 +00:00
{
if ( type != IET_FIRST_PRESS )
return ;
2005-01-14 23:17:04 +00:00
switch ( EditB )
2002-05-20 08:59:37 +00:00
{
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_RETURN_TO_EDIT :
TransitionToEdit ();
2002-09-11 04:49:07 +00:00
break ;
2005-01-14 23:17:04 +00:00
case EDIT_BUTTON_TOGGLE_ASSIST_TICK :
GAMESTATE -> m_SongOptions . m_bAssistTick ^= 1 ;
break ;
case EDIT_BUTTON_TOGGLE_AUTOPLAY :
{
PREFSMAN -> m_bAutoPlay = ! PREFSMAN -> m_bAutoPlay ;
FOREACH_HumanPlayer ( p )
GAMESTATE -> m_pPlayerState [ p ] -> m_PlayerController = PREFSMAN -> m_bAutoPlay ? PC_AUTOPLAY : PC_HUMAN ;
2002-05-20 08:59:37 +00:00
}
2005-01-14 23:17:04 +00:00
break ;
case EDIT_BUTTON_OFFSET_UP :
case EDIT_BUTTON_OFFSET_DOWN :
{
float fOffsetDelta ;
switch ( EditB )
{
case EDIT_BUTTON_OFFSET_DOWN : fOffsetDelta = - 0.020f ; break ;
case EDIT_BUTTON_OFFSET_UP : fOffsetDelta = + 0.020f ; break ;
default : ASSERT ( 0 ); return ;
}
if ( EditIsBeingPressed ( EDIT_BUTTON_ADJUST_FINE ) )
fOffsetDelta /= 20 ; /* 1ms */
else switch ( type )
{
case IET_SLOW_REPEAT : fOffsetDelta *= 10 ; break ;
case IET_FAST_REPEAT : fOffsetDelta *= 40 ; break ;
}
m_pSong -> m_Timing . m_fBeat0OffsetInSeconds += fOffsetDelta ;
}
break ;
2002-05-20 08:59:37 +00:00
}
switch ( StyleI . player )
{
2003-07-13 00:34:30 +00:00
case PLAYER_1 :
if ( ! PREFSMAN -> m_bAutoPlay )
m_Player . Step ( StyleI . col , DeviceI . ts );
break ;
2002-05-20 08:59:37 +00:00
}
}
2002-10-18 00:45:09 +00:00
/* Switch to editing. */
void ScreenEdit :: TransitionToEdit ()
2002-05-20 08:59:37 +00:00
{
2005-01-15 04:15:15 +00:00
m_sprOverlay -> PlayCommand ( "Edit" );
2005-01-14 23:17:04 +00:00
2004-01-23 08:25:00 +00:00
/* Important: people will stop playing, change the BG and start again; make sure we reload */
m_Background . Unload ();
m_Foreground . Unload ();
2002-07-28 20:28:37 +00:00
m_EditMode = MODE_EDITING ;
2004-02-01 02:05:09 +00:00
GAMESTATE -> m_bPastHereWeGo = false ;
2002-12-22 08:51:41 +00:00
m_soundMusic . StopPlaying ();
2004-01-12 09:36:01 +00:00
m_soundAssistTick . StopPlaying (); /* Stop any queued assist ticks. */
2002-10-18 00:45:09 +00:00
m_rectRecordBack . StopTweening ();
m_rectRecordBack . BeginTweening ( 0.5f );
2003-04-12 06:16:12 +00:00
m_rectRecordBack . SetDiffuse ( RageColor ( 0 , 0 , 0 , 0 ) );
2002-10-18 00:53:22 +00:00
/* Make sure we're snapped. */
2004-10-24 17:44:51 +00:00
GAMESTATE -> m_fSongBeat = Quantize ( GAMESTATE -> m_fSongBeat , NoteTypeToBeat ( m_SnapDisplay . GetNoteType ()) );
2002-10-18 00:58:21 +00:00
/* Playing and recording have lead-ins, which may start before beat 0;
* make sure we don't stay there if we escaped out early. */
GAMESTATE -> m_fSongBeat = max ( GAMESTATE -> m_fSongBeat , 0 );
2004-01-26 20:56:58 +00:00
/* Stop displaying course attacks, if any. */
GAMESTATE -> RemoveAllActiveAttacks ();
GAMESTATE -> RebuildPlayerOptionsFromActiveAttacks ( PLAYER_1 );
2004-12-20 06:25:59 +00:00
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_CurrentPlayerOptions = GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_PlayerOptions ;
2002-10-18 00:45:09 +00:00
}
void ScreenEdit :: TransitionFromRecordToEdit ()
{
TransitionToEdit ();
2002-05-20 08:59:37 +00:00
2004-05-24 04:17:19 +00:00
// delete old TapNotes in the range
2005-01-23 23:17:12 +00:00
m_NoteDataEdit . ClearRange ( m_NoteFieldEdit . m_iBeginMarker , m_NoteFieldEdit . m_iEndMarker );
2002-05-20 08:59:37 +00:00
2005-01-23 23:17:12 +00:00
m_NoteDataEdit . CopyRange ( m_NoteDataRecord , m_NoteFieldEdit . m_iBeginMarker , m_NoteFieldEdit . m_iEndMarker , m_NoteFieldEdit . m_iBeginMarker );
2005-01-15 13:05:33 +00:00
2005-01-22 02:50:45 +00:00
m_NoteDataRecord . ClearAll ();
2002-05-20 08:59:37 +00:00
}
2004-01-24 20:36:09 +00:00
/* Helper for SM_DoReloadFromDisk */
static bool g_DoReload ;
void ReloadFromDisk ( void * p )
{
g_DoReload = true ;
}
2002-05-20 08:59:37 +00:00
void ScreenEdit :: HandleScreenMessage ( const ScreenMessage SM )
{
switch ( SM )
{
2002-08-27 23:31:41 +00:00
case SM_GoToNextScreen :
2003-06-21 03:45:34 +00:00
// Reload song from disk to discard changes.
2004-08-11 08:23:14 +00:00
SONGMAN -> RevertFromDisk ( GAMESTATE -> m_pCurSong , true );
2004-08-12 04:49:15 +00:00
2004-05-24 03:41:39 +00:00
/* We might do something with m_pSteps (eg. UpdateTextInfo) before we end up
* in ScreenEditMenu, and m_pSteps might be invalid due to RevertFromDisk. */
2004-05-24 06:12:17 +00:00
m_pSteps = GAMESTATE -> m_pCurSteps [ PLAYER_1 ];
2004-08-12 04:49:15 +00:00
2002-08-27 03:59:22 +00:00
SCREENMAN -> SetNewScreen ( "ScreenEditMenu" );
2002-05-20 08:59:37 +00:00
break ;
2003-02-18 23:15:38 +00:00
case SM_BackFromMainMenu :
HandleMainMenuChoice ( ( MainMenuChoice ) ScreenMiniMenu :: s_iLastLine , ScreenMiniMenu :: s_iLastAnswers );
break ;
case SM_BackFromAreaMenu :
HandleAreaMenuChoice ( ( AreaMenuChoice ) ScreenMiniMenu :: s_iLastLine , ScreenMiniMenu :: s_iLastAnswers );
break ;
case SM_BackFromEditNotesStatistics :
HandleEditNotesStatisticsChoice ( ( EditNotesStatisticsChoice ) ScreenMiniMenu :: s_iLastLine , ScreenMiniMenu :: s_iLastAnswers );
break ;
case SM_BackFromEditSongInfo :
HandleEditSongInfoChoice ( ( EditSongInfoChoice ) ScreenMiniMenu :: s_iLastLine , ScreenMiniMenu :: s_iLastAnswers );
break ;
2005-01-08 07:41:26 +00:00
case SM_BackFromBPMChange :
{
2005-01-08 14:00:15 +00:00
float fBPM = strtof ( ScreenTextEntry :: s_sLastAnswer , NULL );
if ( fBPM > 0 )
m_pSong -> SetBPMAtBeat ( GAMESTATE -> m_fSongBeat , fBPM );
2005-01-08 07:41:26 +00:00
}
break ;
case SM_BackFromStopChange :
{
2005-01-08 14:00:15 +00:00
float fStop = strtof ( ScreenTextEntry :: s_sLastAnswer , NULL );
if ( fStop >= 0 )
m_pSong -> m_Timing . SetStopAtBeat ( GAMESTATE -> m_fSongBeat , fStop );
2005-01-08 07:41:26 +00:00
}
break ;
2003-03-15 19:25:37 +00:00
case SM_BackFromBGChange :
HandleBGChangeChoice ( ( BGChangeChoice ) ScreenMiniMenu :: s_iLastLine , ScreenMiniMenu :: s_iLastAnswers );
break ;
2004-01-23 08:25:00 +00:00
case SM_BackFromPrefs :
PREFSMAN -> m_bEditorShowBGChangesPlay = !! ScreenMiniMenu :: s_iLastAnswers [ pref_show_bgs_play ];
PREFSMAN -> SaveGlobalPrefsToDisk ();
break ;
2004-01-26 20:56:58 +00:00
case SM_BackFromCourseModeMenu :
{
const int num = ScreenMiniMenu :: s_iLastAnswers [ 0 ];
m_pAttacksFromCourse = NULL ;
if ( num != 0 )
{
const CString name = g_CourseMode . rows [ 0 ]. choices [ num ];
m_pAttacksFromCourse = SONGMAN -> FindCourse ( name );
ASSERT ( m_pAttacksFromCourse );
}
break ;
}
2003-11-12 08:13:02 +00:00
case SM_BackFromPlayerOptions :
case SM_BackFromSongOptions :
2003-02-19 05:46:09 +00:00
// coming back from PlayerOptions or SongOptions
2004-01-26 22:20:42 +00:00
GAMESTATE -> StoreSelectedOptions ();
2004-08-18 22:39:56 +00:00
// stop any music that screen may have been playing
SOUND -> StopMusic ();
2003-02-19 05:46:09 +00:00
break ;
2003-11-12 08:13:02 +00:00
case SM_BackFromInsertAttack :
2003-11-12 08:32:32 +00:00
{
int iDurationChoice = ScreenMiniMenu :: s_iLastAnswers [ 0 ];
2004-08-10 20:57:59 +00:00
g_fLastInsertAttackDurationSeconds = strtof ( g_InsertAttackItems [ 0 ]. choices [ iDurationChoice ], NULL );
2003-11-12 08:32:32 +00:00
GAMESTATE -> StoreSelectedOptions (); // save so that we don't lose the options chosen for edit and playback
SCREENMAN -> AddNewScreenToTop ( "ScreenPlayerOptions" , SM_BackFromInsertAttackModifiers );
}
2003-11-12 08:13:02 +00:00
break ;
case SM_BackFromInsertAttackModifiers :
{
2004-12-20 06:25:59 +00:00
PlayerOptions poChosen = GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_PlayerOptions ;
2003-11-12 08:13:02 +00:00
CString sMods = poChosen . GetString ();
2004-10-23 23:41:49 +00:00
const int row = BeatToNoteRow ( GAMESTATE -> m_fSongBeat );
2003-11-15 23:19:13 +00:00
2005-01-22 19:25:05 +00:00
TapNote tn (
TapNote :: attack , TapNote :: original ,
sMods ,
g_fLastInsertAttackDurationSeconds ,
false ,
0 );
m_NoteDataEdit . SetTapNote ( g_iLastInsertAttackTrack , row , tn );
2003-11-12 08:13:02 +00:00
GAMESTATE -> RestoreSelectedOptions (); // restore the edit and playback options
}
break ;
2004-01-24 20:36:09 +00:00
case SM_DoReloadFromDisk :
{
if ( ! g_DoReload )
return ;
2004-05-24 03:41:39 +00:00
const StepsType st = m_pSteps -> m_StepsType ;
2004-04-18 08:06:14 +00:00
StepsID id ;
2004-05-24 03:41:39 +00:00
id . FromSteps ( m_pSteps );
2004-01-24 20:36:09 +00:00
2004-05-24 06:12:17 +00:00
GAMESTATE -> m_pCurSteps [ PLAYER_1 ] = NULL ; /* make RevertFromDisk not try to reset it */
2004-08-11 08:23:14 +00:00
SONGMAN -> RevertFromDisk ( GAMESTATE -> m_pCurSong );
2004-01-24 20:36:09 +00:00
CString sMessage = "Reloaded from disk." ;
2004-04-18 08:06:14 +00:00
Steps * pSteps = id . ToSteps ( GAMESTATE -> m_pCurSong , false );
2004-01-24 20:36:09 +00:00
2004-04-18 08:32:45 +00:00
// Don't allow an autogen match. This can't be what they chose to
// edit originally because autogen steps are hidden.
2004-04-24 20:57:30 +00:00
if ( pSteps && pSteps -> IsAutogen () )
2004-04-18 08:32:45 +00:00
pSteps = NULL ;
2004-01-24 20:36:09 +00:00
/* If we couldn't find the steps we were on before, warn and use the first available. */
if ( pSteps == NULL )
{
pSteps = GAMESTATE -> m_pCurSong -> GetStepsByDifficulty ( st , DIFFICULTY_INVALID , false );
if ( pSteps )
2004-04-18 08:06:14 +00:00
sMessage = ssprintf ( "old steps not found; changed to %s." ,
2004-01-24 20:36:09 +00:00
DifficultyToString ( pSteps -> GetDifficulty ()). c_str () );
}
/* If we still couldn't find any steps, then all steps of the current StepsType
* were removed. Don't create them; only do that in EditMenu. */
if ( pSteps == NULL )
2004-04-17 00:07:59 +00:00
{
SCREENMAN -> SetNewScreen ( "ScreenEditMenu" );
return ;
}
2004-01-24 20:36:09 +00:00
SCREENMAN -> SystemMessage ( sMessage );
2004-05-24 06:12:17 +00:00
m_pSteps = GAMESTATE -> m_pCurSteps [ PLAYER_1 ] = pSteps ;
2005-01-22 02:50:45 +00:00
m_pSteps -> GetNoteData ( m_NoteDataEdit );
2004-01-24 20:36:09 +00:00
break ;
}
2004-05-03 01:37:49 +00:00
case SM_DoUpdateTextInfo :
this -> PostScreenMessage ( SM_DoUpdateTextInfo , 0.5f );
UpdateTextInfo ();
break ;
2003-12-22 20:27:47 +00:00
case SM_GainFocus :
/* We do this ourself. */
SOUND -> HandleSongTimer ( false );
2004-01-26 23:08:46 +00:00
/* When another screen comes up, RageSounds takes over the sound timer. When we come
* back, put the timer back to where it was. */
GAMESTATE -> m_fSongBeat = m_fTrailingBeat ;
break ;
case SM_LoseFocus :
/* Snap the trailing beat, in case we lose focus while tweening. */
m_fTrailingBeat = GAMESTATE -> m_fSongBeat ;
2003-12-22 20:27:47 +00:00
break ;
2002-05-20 08:59:37 +00:00
}
}
void ScreenEdit :: OnSnapModeChange ()
{
2002-06-29 11:59:09 +00:00
m_soundChangeSnap . Play ();
2002-05-20 08:59:37 +00:00
2002-10-18 19:01:32 +00:00
NoteType nt = m_SnapDisplay . GetNoteType ();
2002-08-01 20:30:40 +00:00
int iStepIndex = BeatToNoteRow ( GAMESTATE -> m_fSongBeat );
2002-05-20 08:59:37 +00:00
int iElementsPerNoteType = BeatToNoteRow ( NoteTypeToBeat ( nt ) );
int iStepIndexHangover = iStepIndex % iElementsPerNoteType ;
2002-08-01 20:30:40 +00:00
GAMESTATE -> m_fSongBeat -= NoteRowToBeat ( iStepIndexHangover );
2002-05-20 08:59:37 +00:00
}
2002-08-17 06:44:04 +00:00
2003-02-19 05:46:09 +00:00
// Helper function for below
// Begin helper functions for InputEdit
void ChangeDescription ( CString sNew )
{
2004-05-24 06:12:17 +00:00
Steps * pSteps = GAMESTATE -> m_pCurSteps [ PLAYER_1 ];
2004-05-24 03:41:39 +00:00
pSteps -> SetDescription ( sNew );
2003-02-19 05:46:09 +00:00
}
void ChangeMainTitle ( CString sNew )
{
Song * pSong = GAMESTATE -> m_pCurSong ;
pSong -> m_sMainTitle = sNew ;
}
void ChangeSubTitle ( CString sNew )
{
Song * pSong = GAMESTATE -> m_pCurSong ;
pSong -> m_sSubTitle = sNew ;
}
void ChangeArtist ( CString sNew )
{
Song * pSong = GAMESTATE -> m_pCurSong ;
pSong -> m_sArtist = sNew ;
}
2003-06-23 02:24:13 +00:00
void ChangeCredit ( CString sNew )
{
Song * pSong = GAMESTATE -> m_pCurSong ;
pSong -> m_sCredit = sNew ;
}
2003-02-19 05:46:09 +00:00
void ChangeMainTitleTranslit ( CString sNew )
{
Song * pSong = GAMESTATE -> m_pCurSong ;
pSong -> m_sMainTitleTranslit = sNew ;
}
void ChangeSubTitleTranslit ( CString sNew )
{
Song * pSong = GAMESTATE -> m_pCurSong ;
pSong -> m_sSubTitleTranslit = sNew ;
}
void ChangeArtistTranslit ( CString sNew )
{
Song * pSong = GAMESTATE -> m_pCurSong ;
pSong -> m_sArtistTranslit = sNew ;
}
2003-12-22 18:27:32 +00:00
2003-02-19 05:46:09 +00:00
// End helper functions
2003-02-18 23:15:38 +00:00
void ScreenEdit :: HandleMainMenuChoice ( MainMenuChoice c , int * iAnswers )
2002-08-17 06:44:04 +00:00
{
2003-02-18 23:15:38 +00:00
switch ( c )
{
case edit_notes_statistics :
{
2004-05-24 03:41:39 +00:00
/* XXX: If the difficulty is changed from EDIT, and pSteps->WasLoadedFromProfile()
2004-02-25 23:43:50 +00:00
* is true, we should warn that the steps will no longer be saved to the profile. */
2004-05-24 06:12:17 +00:00
Steps * pSteps = GAMESTATE -> m_pCurSteps [ PLAYER_1 ];
2003-02-18 23:15:38 +00:00
float fMusicSeconds = m_soundMusic . GetLengthSeconds ();
2004-05-24 03:41:39 +00:00
g_EditNotesStatistics . rows [ difficulty ]. defaultChoice = pSteps -> GetDifficulty ();
2004-07-19 20:30:52 +00:00
g_EditNotesStatistics . rows [ meter ]. defaultChoice = clamp ( pSteps -> GetMeter () - 1 , 0 , 14 );
2004-05-24 03:41:39 +00:00
g_EditNotesStatistics . rows [ predict_meter ]. choices . resize ( 1 ); g_EditNotesStatistics . rows [ predict_meter ]. choices [ 0 ] = ssprintf ( "%f" , pSteps -> PredictMeter ());
g_EditNotesStatistics . rows [ description ]. choices . resize ( 1 ); g_EditNotesStatistics . rows [ description ]. choices [ 0 ] = pSteps -> GetDescription ();
2005-01-22 02:50:45 +00:00
g_EditNotesStatistics . rows [ tap_notes ]. choices . resize ( 1 ); g_EditNotesStatistics . rows [ tap_notes ]. choices [ 0 ] = ssprintf ( "%d" , m_NoteDataEdit . GetNumTapNotes ());
g_EditNotesStatistics . rows [ hold_notes ]. choices . resize ( 1 ); g_EditNotesStatistics . rows [ hold_notes ]. choices [ 0 ] = ssprintf ( "%d" , m_NoteDataEdit . GetNumHoldNotes ());
g_EditNotesStatistics . rows [ stream ]. choices . resize ( 1 ); g_EditNotesStatistics . rows [ stream ]. choices [ 0 ] = ssprintf ( "%f" , NoteDataUtil :: GetStreamRadarValue ( m_NoteDataEdit , fMusicSeconds ));
g_EditNotesStatistics . rows [ voltage ]. choices . resize ( 1 ); g_EditNotesStatistics . rows [ voltage ]. choices [ 0 ] = ssprintf ( "%f" , NoteDataUtil :: GetVoltageRadarValue ( m_NoteDataEdit , fMusicSeconds ));
2003-12-22 18:27:32 +00:00
2005-01-22 02:50:45 +00:00
g_EditNotesStatistics . rows [ air ]. choices . resize ( 1 ); g_EditNotesStatistics . rows [ air ]. choices [ 0 ] = ssprintf ( "%f" , NoteDataUtil :: GetAirRadarValue ( m_NoteDataEdit , fMusicSeconds ));
g_EditNotesStatistics . rows [ freeze ]. choices . resize ( 1 ); g_EditNotesStatistics . rows [ freeze ]. choices [ 0 ] = ssprintf ( "%f" , NoteDataUtil :: GetFreezeRadarValue ( m_NoteDataEdit , fMusicSeconds ));
g_EditNotesStatistics . rows [ chaos ]. choices . resize ( 1 ); g_EditNotesStatistics . rows [ chaos ]. choices [ 0 ] = ssprintf ( "%f" , NoteDataUtil :: GetChaosRadarValue ( m_NoteDataEdit , fMusicSeconds ));
2003-02-18 23:15:38 +00:00
SCREENMAN -> MiniMenu ( & g_EditNotesStatistics , SM_BackFromEditNotesStatistics );
}
break ;
case play_whole_song :
2003-02-19 05:46:09 +00:00
{
2005-01-23 23:17:12 +00:00
m_NoteFieldEdit . m_iBeginMarker = 0 ;
m_NoteFieldEdit . m_iEndMarker = m_NoteDataEdit . GetLastRow ();
2003-02-19 05:46:09 +00:00
HandleAreaMenuChoice ( play , NULL );
}
2003-02-18 23:15:38 +00:00
break ;
2003-03-16 00:05:23 +00:00
case play_current_beat_to_end :
{
2005-01-23 23:17:12 +00:00
m_NoteFieldEdit . m_iBeginMarker = BeatToNoteRow ( GAMESTATE -> m_fSongBeat );
m_NoteFieldEdit . m_iEndMarker = m_NoteDataEdit . GetLastRow ();
2003-03-16 00:05:23 +00:00
HandleAreaMenuChoice ( play , NULL );
}
break ;
2003-02-18 23:15:38 +00:00
case save :
{
2003-08-03 00:13:55 +00:00
// copy edit into current Steps
2004-05-24 06:12:17 +00:00
Steps * pSteps = GAMESTATE -> m_pCurSteps [ PLAYER_1 ];
2004-05-24 03:41:39 +00:00
ASSERT ( pSteps );
2003-02-18 23:15:38 +00:00
2005-01-22 02:50:45 +00:00
pSteps -> SetNoteData ( m_NoteDataEdit );
2003-02-18 23:15:38 +00:00
GAMESTATE -> m_pCurSong -> Save ();
2004-02-26 05:38:46 +00:00
// we shouldn't say we're saving a DWI if we're on any game besides
// dance, it just looks tacky and people may be wondering where the
// DWI file is :-)
2004-05-24 03:41:39 +00:00
if (( int ) pSteps -> m_StepsType <= ( int ) STEPS_TYPE_DANCE_SOLO )
2004-02-26 05:38:46 +00:00
SCREENMAN -> SystemMessage ( "Saved as SM and DWI." );
else
SCREENMAN -> SystemMessage ( "Saved as SM." );
2003-07-26 22:53:22 +00:00
SOUND -> PlayOnce ( THEME -> GetPathToS ( "ScreenEdit save" ) );
2003-02-18 23:15:38 +00:00
}
break ;
2004-01-24 20:36:09 +00:00
case reload :
g_DoReload = false ;
SCREENMAN -> Prompt ( SM_DoReloadFromDisk ,
"Do you want to reload from disk? \n\n This will destroy all changes." ,
true , false , ReloadFromDisk , NULL , NULL );
break ;
2003-02-18 23:15:38 +00:00
case player_options :
2003-11-12 08:13:02 +00:00
SCREENMAN -> AddNewScreenToTop ( "ScreenPlayerOptions" , SM_BackFromPlayerOptions );
2003-02-18 23:15:38 +00:00
break ;
case song_options :
2003-11-12 08:13:02 +00:00
SCREENMAN -> AddNewScreenToTop ( "ScreenSongOptions" , SM_BackFromSongOptions );
2003-02-18 23:15:38 +00:00
break ;
case edit_song_info :
2003-02-19 05:46:09 +00:00
{
Song * pSong = GAMESTATE -> m_pCurSong ;
2003-03-15 19:25:37 +00:00
g_EditSongInfo . rows [ main_title ]. choices . resize ( 1 ); g_EditSongInfo . rows [ main_title ]. choices [ 0 ] = pSong -> m_sMainTitle ;
g_EditSongInfo . rows [ sub_title ]. choices . resize ( 1 ); g_EditSongInfo . rows [ sub_title ]. choices [ 0 ] = pSong -> m_sSubTitle ;
g_EditSongInfo . rows [ artist ]. choices . resize ( 1 ); g_EditSongInfo . rows [ artist ]. choices [ 0 ] = pSong -> m_sArtist ;
2003-06-23 02:24:13 +00:00
g_EditSongInfo . rows [ credit ]. choices . resize ( 1 ); g_EditSongInfo . rows [ credit ]. choices [ 0 ] = pSong -> m_sCredit ;
2003-03-15 19:25:37 +00:00
g_EditSongInfo . rows [ main_title_transliteration ]. choices . resize ( 1 ); g_EditSongInfo . rows [ main_title_transliteration ]. choices [ 0 ] = pSong -> m_sMainTitleTranslit ;
g_EditSongInfo . rows [ sub_title_transliteration ]. choices . resize ( 1 ); g_EditSongInfo . rows [ sub_title_transliteration ]. choices [ 0 ] = pSong -> m_sSubTitleTranslit ;
g_EditSongInfo . rows [ artist_transliteration ]. choices . resize ( 1 ); g_EditSongInfo . rows [ artist_transliteration ]. choices [ 0 ] = pSong -> m_sArtistTranslit ;
2003-02-19 05:46:09 +00:00
SCREENMAN -> MiniMenu ( & g_EditSongInfo , SM_BackFromEditSongInfo );
}
2003-02-18 23:15:38 +00:00
break ;
2005-01-08 07:41:26 +00:00
case edit_bpm :
SCREENMAN -> TextEntry ( SM_BackFromBPMChange , "Enter new BPM value." , ssprintf ( "%.4f" , m_pSong -> GetBPMAtBeat ( GAMESTATE -> m_fSongBeat ) ) );
break ;
case edit_stop :
{
unsigned i ;
for ( i = 0 ; i < m_pSong -> m_Timing . m_StopSegments . size (); i ++ )
{
2005-01-23 21:55:01 +00:00
// XXX
if ( m_pSong -> m_Timing . m_StopSegments [ i ]. m_iStartRow == BeatToNoteRow ( GAMESTATE -> m_fSongBeat ) )
2005-01-08 07:41:26 +00:00
break ;
}
if ( i == m_pSong -> m_Timing . m_StopSegments . size () )
SCREENMAN -> TextEntry ( SM_BackFromStopChange , "Enter new Stop value." , "0.00" );
else
SCREENMAN -> TextEntry ( SM_BackFromStopChange , "Enter new Stop value." , ssprintf ( "%.4f" , m_pSong -> m_Timing . m_StopSegments [ i ]. m_fStopSeconds ) );
break ;
}
2003-02-18 23:15:38 +00:00
case edit_bg_change :
2003-02-19 05:46:09 +00:00
{
2003-03-15 19:25:37 +00:00
//
// Fill in option names
//
2003-03-16 00:05:23 +00:00
// m_pSong->GetSongDir() has trailing slash
2003-03-15 19:25:37 +00:00
g_BGChange . rows [ add_song_bganimation ]. choices . clear ();
2003-04-14 04:17:23 +00:00
GetDirListing ( m_pSong -> GetSongDir () + "*" , g_BGChange . rows [ add_song_bganimation ]. choices , true );
2003-02-19 05:46:09 +00:00
2003-03-15 19:25:37 +00:00
g_BGChange . rows [ add_song_movie ]. choices . clear ();
2003-03-16 00:05:23 +00:00
GetDirListing ( m_pSong -> GetSongDir () + "*.avi" , g_BGChange . rows [ add_song_movie ]. choices , false );
GetDirListing ( m_pSong -> GetSongDir () + "*.mpg" , g_BGChange . rows [ add_song_movie ]. choices , false );
GetDirListing ( m_pSong -> GetSongDir () + "*.mpeg" , g_BGChange . rows [ add_song_movie ]. choices , false );
2003-03-15 19:25:37 +00:00
2003-04-13 23:22:27 +00:00
g_BGChange . rows [ add_song_still ]. choices . clear ();
GetDirListing ( m_pSong -> GetSongDir () + "*.png" , g_BGChange . rows [ add_song_still ]. choices , false );
GetDirListing ( m_pSong -> GetSongDir () + "*.jpg" , g_BGChange . rows [ add_song_still ]. choices , false );
GetDirListing ( m_pSong -> GetSongDir () + "*.gif" , g_BGChange . rows [ add_song_still ]. choices , false );
GetDirListing ( m_pSong -> GetSongDir () + "*.bmp" , g_BGChange . rows [ add_song_still ]. choices , false );
2003-03-15 19:25:37 +00:00
g_BGChange . rows [ add_global_random_movie ]. choices . clear ();
2003-03-16 00:05:23 +00:00
GetDirListing ( RANDOMMOVIES_DIR + "*.avi" , g_BGChange . rows [ add_global_random_movie ]. choices , false );
GetDirListing ( RANDOMMOVIES_DIR + "*.mpg" , g_BGChange . rows [ add_global_random_movie ]. choices , false );
GetDirListing ( RANDOMMOVIES_DIR + "*.mpeg" , g_BGChange . rows [ add_global_random_movie ]. choices , false );
2003-03-15 19:25:37 +00:00
g_BGChange . rows [ add_global_bganimation ]. choices . clear ();
2003-04-14 04:17:23 +00:00
GetDirListing ( BG_ANIMS_DIR + "*" , g_BGChange . rows [ add_global_bganimation ]. choices , true );
2003-03-15 19:25:37 +00:00
g_BGChange . rows [ add_global_visualization ]. choices . clear ();
2003-03-16 00:05:23 +00:00
GetDirListing ( VISUALIZATIONS_DIR + "*.avi" , g_BGChange . rows [ add_global_visualization ]. choices , false );
GetDirListing ( VISUALIZATIONS_DIR + "*.mpg" , g_BGChange . rows [ add_global_visualization ]. choices , false );
GetDirListing ( VISUALIZATIONS_DIR + "*.mpeg" , g_BGChange . rows [ add_global_visualization ]. choices , false );
2003-03-15 19:25:37 +00:00
//
// Fill in line enabled/disabled
//
bool bAlreadyBGChangeHere = false ;
2004-08-11 07:30:41 +00:00
BackgroundChange bgChange ;
FOREACH ( BackgroundChange , m_pSong -> m_BackgroundChanges , bgc )
{
if ( bgc -> m_fStartBeat == GAMESTATE -> m_fSongBeat )
{
2003-03-15 19:25:37 +00:00
bAlreadyBGChangeHere = true ;
2004-08-11 07:30:41 +00:00
bgChange = * bgc ;
}
}
2003-03-15 19:25:37 +00:00
g_BGChange . rows [ add_random ]. enabled = true ;
g_BGChange . rows [ add_song_bganimation ]. enabled = g_BGChange . rows [ add_song_bganimation ]. choices . size () > 0 ;
2003-03-16 00:05:23 +00:00
g_BGChange . rows [ add_song_movie ]. enabled = g_BGChange . rows [ add_song_movie ]. choices . size () > 0 ;
2003-04-13 23:22:27 +00:00
g_BGChange . rows [ add_song_still ]. enabled = g_BGChange . rows [ add_song_still ]. choices . size () > 0 ;
2003-03-15 19:25:37 +00:00
g_BGChange . rows [ add_global_random_movie ]. enabled = g_BGChange . rows [ add_global_random_movie ]. choices . size () > 0 ;
g_BGChange . rows [ add_global_bganimation ]. enabled = g_BGChange . rows [ add_global_bganimation ]. choices . size () > 0 ;
g_BGChange . rows [ add_global_visualization ]. enabled = g_BGChange . rows [ add_global_visualization ]. choices . size () > 0 ;
g_BGChange . rows [ delete_change ]. enabled = bAlreadyBGChangeHere ;
2004-08-11 07:30:41 +00:00
// set default choices
g_BGChange . rows [ rate ]. SetDefaultChoiceIfPresent ( ssprintf ( "%2.0f%%" , bgChange . m_fRate * 100 ) );
g_BGChange . rows [ fade_last ]. defaultChoice = bgChange . m_bFadeLast ? 1 : 0 ;
g_BGChange . rows [ rewind_movie ]. defaultChoice = bgChange . m_bRewindMovie ? 1 : 0 ;
g_BGChange . rows [ loop ]. defaultChoice = bgChange . m_bLoop ? 1 : 0 ;
g_BGChange . rows [ add_song_bganimation ]. SetDefaultChoiceIfPresent ( bgChange . m_sBGName );
g_BGChange . rows [ add_song_movie ]. SetDefaultChoiceIfPresent ( bgChange . m_sBGName );
g_BGChange . rows [ add_song_still ]. SetDefaultChoiceIfPresent ( bgChange . m_sBGName );
g_BGChange . rows [ add_global_random_movie ]. SetDefaultChoiceIfPresent ( bgChange . m_sBGName );
g_BGChange . rows [ add_global_bganimation ]. SetDefaultChoiceIfPresent ( bgChange . m_sBGName );
g_BGChange . rows [ add_global_visualization ]. SetDefaultChoiceIfPresent ( bgChange . m_sBGName );
2003-03-15 19:25:37 +00:00
SCREENMAN -> MiniMenu ( & g_BGChange , SM_BackFromBGChange );
2003-02-19 05:46:09 +00:00
}
2003-02-18 23:15:38 +00:00
break ;
2004-01-23 08:25:00 +00:00
case preferences :
g_Prefs . rows [ pref_show_bgs_play ]. defaultChoice = PREFSMAN -> m_bEditorShowBGChangesPlay ;
SCREENMAN -> MiniMenu ( & g_Prefs , SM_BackFromPrefs );
break ;
2003-02-18 23:15:38 +00:00
case play_preview_music :
2003-03-05 02:38:17 +00:00
PlayPreviewMusic ();
2003-02-18 23:15:38 +00:00
break ;
case exit :
2003-04-12 18:34:05 +00:00
m_Out . StartTransitioning ( SM_GoToNextScreen );
2003-02-18 23:15:38 +00:00
break ;
default :
ASSERT ( 0 );
};
2002-08-17 06:44:04 +00:00
}
2003-02-18 23:15:38 +00:00
void ScreenEdit :: HandleAreaMenuChoice ( AreaMenuChoice c , int * iAnswers )
2002-08-17 06:44:04 +00:00
{
2003-02-18 23:15:38 +00:00
switch ( c )
{
case cut :
{
2003-02-22 00:48:38 +00:00
HandleAreaMenuChoice ( copy , NULL );
HandleAreaMenuChoice ( clear , NULL );
2003-02-18 23:15:38 +00:00
}
break ;
case copy :
{
2005-01-23 23:17:12 +00:00
ASSERT ( m_NoteFieldEdit . m_iBeginMarker !=- 1 && m_NoteFieldEdit . m_iEndMarker !=- 1 );
2003-02-18 23:15:38 +00:00
m_Clipboard . ClearAll ();
2005-01-23 23:17:12 +00:00
m_Clipboard . CopyRange ( m_NoteDataEdit , m_NoteFieldEdit . m_iBeginMarker , m_NoteFieldEdit . m_iEndMarker );
2003-02-18 23:15:38 +00:00
}
break ;
2003-02-22 00:48:38 +00:00
case paste_at_current_beat :
2003-02-18 23:15:38 +00:00
{
int iSrcFirstRow = 0 ;
int iSrcLastRow = BeatToNoteRow ( m_Clipboard . GetLastBeat () );
int iDestFirstRow = BeatToNoteRow ( GAMESTATE -> m_fSongBeat );
2005-01-22 02:50:45 +00:00
m_NoteDataEdit . CopyRange ( m_Clipboard , iSrcFirstRow , iSrcLastRow , iDestFirstRow );
2003-02-18 23:15:38 +00:00
}
break ;
2003-02-22 00:48:38 +00:00
case paste_at_begin_marker :
{
2005-01-23 23:17:12 +00:00
ASSERT ( m_NoteFieldEdit . m_iBeginMarker !=- 1 );
m_NoteDataEdit . CopyRange ( m_Clipboard , 0 , m_Clipboard . GetLastRow (), m_NoteFieldEdit . m_iBeginMarker );
2003-02-22 00:48:38 +00:00
}
break ;
2003-02-18 23:15:38 +00:00
case clear :
{
2005-01-23 23:17:12 +00:00
ASSERT ( m_NoteFieldEdit . m_iBeginMarker !=- 1 && m_NoteFieldEdit . m_iEndMarker !=- 1 );
m_NoteDataEdit . ClearRange ( m_NoteFieldEdit . m_iBeginMarker , m_NoteFieldEdit . m_iEndMarker );
2003-02-18 23:15:38 +00:00
}
break ;
case quantize :
{
NoteType nt = ( NoteType ) iAnswers [ c ];
2005-01-23 23:17:12 +00:00
NoteDataUtil :: SnapToNearestNoteType ( m_NoteDataEdit , nt , nt , m_NoteFieldEdit . m_iBeginMarker , m_NoteFieldEdit . m_iEndMarker );
2003-02-18 23:15:38 +00:00
}
break ;
2003-03-13 09:20:21 +00:00
case turn :
2003-02-18 23:15:38 +00:00
{
2004-08-18 23:02:27 +00:00
const NoteData OldClipboard ( m_Clipboard );
2003-02-22 00:48:38 +00:00
HandleAreaMenuChoice ( cut , NULL );
2004-06-28 07:26:00 +00:00
StepsType st = GAMESTATE -> GetCurrentStyle () -> m_StepsType ;
2003-03-13 09:20:21 +00:00
TurnType tt = ( TurnType ) iAnswers [ c ];
2003-02-18 23:15:38 +00:00
switch ( tt )
{
2003-08-07 06:36:34 +00:00
case left : NoteDataUtil :: Turn ( m_Clipboard , st , NoteDataUtil :: left ); break ;
case right : NoteDataUtil :: Turn ( m_Clipboard , st , NoteDataUtil :: right ); break ;
case mirror : NoteDataUtil :: Turn ( m_Clipboard , st , NoteDataUtil :: mirror ); break ;
case shuffle : NoteDataUtil :: Turn ( m_Clipboard , st , NoteDataUtil :: shuffle ); break ;
case super_shuffle : NoteDataUtil :: Turn ( m_Clipboard , st , NoteDataUtil :: super_shuffle ); break ;
2003-02-18 23:15:38 +00:00
default : ASSERT ( 0 );
}
2003-02-22 00:48:38 +00:00
HandleAreaMenuChoice ( paste_at_begin_marker , NULL );
2004-08-18 23:02:27 +00:00
m_Clipboard = OldClipboard ;
2003-02-18 23:15:38 +00:00
}
break ;
2003-03-13 09:20:21 +00:00
case transform :
{
2005-01-23 23:17:12 +00:00
int iBeginRow = m_NoteFieldEdit . m_iBeginMarker ;
int iEndRow = m_NoteFieldEdit . m_iEndMarker ;
2003-03-13 09:20:21 +00:00
TransformType tt = ( TransformType ) iAnswers [ c ];
2004-06-28 07:26:00 +00:00
StepsType st = GAMESTATE -> GetCurrentStyle () -> m_StepsType ;
2005-01-22 17:34:10 +00:00
2003-03-13 09:20:21 +00:00
switch ( tt )
{
2005-01-22 17:34:10 +00:00
case noholds : NoteDataUtil :: RemoveHoldNotes ( m_NoteDataEdit , iBeginRow , iEndRow ); break ;
case nomines : NoteDataUtil :: RemoveMines ( m_NoteDataEdit , iBeginRow , iBeginRow ); break ;
case little : NoteDataUtil :: Little ( m_NoteDataEdit , iBeginRow , iEndRow ); break ;
case wide : NoteDataUtil :: Wide ( m_NoteDataEdit , iBeginRow , iEndRow ); break ;
case big : NoteDataUtil :: Big ( m_NoteDataEdit , iBeginRow , iEndRow ); break ;
case quick : NoteDataUtil :: Quick ( m_NoteDataEdit , iBeginRow , iEndRow ); break ;
case bmrize : NoteDataUtil :: BMRize ( m_NoteDataEdit , iBeginRow , iEndRow ); break ;
case skippy : NoteDataUtil :: Skippy ( m_NoteDataEdit , iBeginRow , iEndRow ); break ;
case mines : NoteDataUtil :: AddMines ( m_NoteDataEdit , iBeginRow , iEndRow ); break ;
case echo : NoteDataUtil :: Echo ( m_NoteDataEdit , iBeginRow , iEndRow ); break ;
case stomp : NoteDataUtil :: Stomp ( m_NoteDataEdit , st , iBeginRow , iEndRow ); break ;
case planted : NoteDataUtil :: Planted ( m_NoteDataEdit , iBeginRow , iEndRow ); break ;
case floored : NoteDataUtil :: Floored ( m_NoteDataEdit , iBeginRow , iEndRow ); break ;
case twister : NoteDataUtil :: Twister ( m_NoteDataEdit , iBeginRow , iEndRow ); break ;
case nojumps : NoteDataUtil :: RemoveJumps ( m_NoteDataEdit , iBeginRow , iEndRow ); break ;
case nohands : NoteDataUtil :: RemoveHands ( m_NoteDataEdit , iBeginRow , iEndRow ); break ;
case noquads : NoteDataUtil :: RemoveQuads ( m_NoteDataEdit , iBeginRow , iEndRow ); break ;
2003-03-13 09:20:21 +00:00
default : ASSERT ( 0 );
}
2003-08-10 06:00:30 +00:00
// bake in the additions
2005-01-22 02:50:45 +00:00
NoteDataUtil :: ConvertAdditionsToRegular ( m_NoteDataEdit );
2003-03-13 09:20:21 +00:00
}
break ;
2003-03-13 21:44:14 +00:00
case alter :
{
2004-08-18 23:02:27 +00:00
const NoteData OldClipboard ( m_Clipboard );
2003-03-13 21:44:14 +00:00
HandleAreaMenuChoice ( cut , NULL );
AlterType at = ( AlterType ) iAnswers [ c ];
switch ( at )
{
case backwards : NoteDataUtil :: Backwards ( m_Clipboard ); break ;
case swap_sides : NoteDataUtil :: SwapSides ( m_Clipboard ); break ;
case copy_left_to_right : NoteDataUtil :: CopyLeftToRight ( m_Clipboard ); break ;
case copy_right_to_left : NoteDataUtil :: CopyRightToLeft ( m_Clipboard ); break ;
case clear_left : NoteDataUtil :: ClearLeft ( m_Clipboard ); break ;
case clear_right : NoteDataUtil :: ClearRight ( m_Clipboard ); break ;
case collapse_to_one : NoteDataUtil :: CollapseToOne ( m_Clipboard ); break ;
2003-12-31 07:49:30 +00:00
case collapse_left : NoteDataUtil :: CollapseLeft ( m_Clipboard ); break ;
2003-03-13 21:44:14 +00:00
case shift_left : NoteDataUtil :: ShiftLeft ( m_Clipboard ); break ;
case shift_right : NoteDataUtil :: ShiftRight ( m_Clipboard ); break ;
default : ASSERT ( 0 );
}
HandleAreaMenuChoice ( paste_at_begin_marker , NULL );
2004-08-18 23:02:27 +00:00
m_Clipboard = OldClipboard ;
2003-03-13 21:44:14 +00:00
}
break ;
2003-09-07 22:28:46 +00:00
case tempo :
{
2004-08-18 23:02:27 +00:00
// This affects all steps.
const NoteData OldClipboard ( m_Clipboard );
2003-09-07 22:28:46 +00:00
HandleAreaMenuChoice ( cut , NULL );
AlterType at = ( AlterType ) iAnswers [ c ];
float fScale = - 1 ;
switch ( at )
{
2003-11-03 08:44:49 +00:00
case compress_2x : fScale = 0.5f ; break ;
case compress_3_2 : fScale = 2.0f / 3 ; break ;
case compress_4_3 : fScale = 0.75f ; break ;
case expand_4_3 : fScale = 4.0f / 3 ; break ;
case expand_3_2 : fScale = 1.5f ; break ;
case expand_2x : fScale = 2 ; break ;
2003-09-07 22:28:46 +00:00
default : ASSERT ( 0 );
}
2004-02-26 05:38:46 +00:00
m_Clipboard . ConvertHoldNotesTo2sAnd3s ();
2003-09-07 22:28:46 +00:00
switch ( at )
{
case compress_2x : NoteDataUtil :: Scale ( m_Clipboard , fScale ); break ;
2003-11-03 08:44:49 +00:00
case compress_3_2 : NoteDataUtil :: Scale ( m_Clipboard , fScale ); break ;
case compress_4_3 : NoteDataUtil :: Scale ( m_Clipboard , fScale ); break ;
case expand_4_3 : NoteDataUtil :: Scale ( m_Clipboard , fScale ); break ;
case expand_3_2 : NoteDataUtil :: Scale ( m_Clipboard , fScale ); break ;
2003-09-07 22:28:46 +00:00
case expand_2x : NoteDataUtil :: Scale ( m_Clipboard , fScale ); break ;
default : ASSERT ( 0 );
}
2004-02-26 05:38:46 +00:00
m_Clipboard . Convert2sAnd3sToHoldNotes ();
2005-01-23 23:17:12 +00:00
int iOldClipboardBeats = m_NoteFieldEdit . m_iEndMarker - m_NoteFieldEdit . m_iBeginMarker ;
int iNewClipboardBeats = lrintf ( iOldClipboardBeats * fScale );
int iDeltaBeats = iNewClipboardBeats - iOldClipboardBeats ;
int iNewClipboardEndBeat = m_NoteFieldEdit . m_iBeginMarker + iNewClipboardBeats ;
NoteDataUtil :: ShiftRows ( m_NoteDataEdit , m_NoteFieldEdit . m_iBeginMarker , iDeltaBeats );
m_pSong -> m_Timing . ScaleRegion ( fScale , m_NoteFieldEdit . m_iBeginMarker , m_NoteFieldEdit . m_iEndMarker );
2004-02-26 05:38:46 +00:00
HandleAreaMenuChoice ( paste_at_begin_marker , NULL );
const vector < Steps *> sIter = m_pSong -> GetAllSteps ();
NoteData ndTemp ;
CString sTempStyle , sTempDiff ;
2004-02-26 06:47:13 +00:00
for ( unsigned i = 0 ; i < sIter . size (); i ++ )
{
if ( sIter [ i ] -> IsAutogen () )
2004-02-26 05:38:46 +00:00
continue ;
2004-02-26 06:47:13 +00:00
2004-05-24 03:41:39 +00:00
/* XXX: Edits are distinguished by description. Compare vs m_pSteps. */
2004-05-24 06:12:17 +00:00
if ( ( sIter [ i ] -> m_StepsType == GAMESTATE -> m_pCurSteps [ PLAYER_1 ] -> m_StepsType ) &&
( sIter [ i ] -> GetDifficulty () == GAMESTATE -> m_pCurSteps [ PLAYER_1 ] -> GetDifficulty ()) )
2004-02-26 05:38:46 +00:00
continue ;
2004-10-23 17:43:49 +00:00
sIter [ i ] -> GetNoteData ( ndTemp );
2004-02-26 05:38:46 +00:00
ndTemp . ConvertHoldNotesTo2sAnd3s ();
2005-01-23 23:17:12 +00:00
NoteDataUtil :: ScaleRegion ( ndTemp , fScale , m_NoteFieldEdit . m_iBeginMarker , m_NoteFieldEdit . m_iEndMarker );
2004-02-26 05:38:46 +00:00
ndTemp . Convert2sAnd3sToHoldNotes ();
2004-10-23 17:43:49 +00:00
sIter [ i ] -> SetNoteData ( ndTemp );
2004-02-26 05:38:46 +00:00
}
2003-09-07 22:28:46 +00:00
2005-01-23 23:17:12 +00:00
m_NoteFieldEdit . m_iEndMarker = iNewClipboardEndBeat ;
2003-09-07 22:28:46 +00:00
2005-01-23 23:17:12 +00:00
float fOldBPM = m_pSong -> GetBPMAtBeat ( NoteRowToBeat ( m_NoteFieldEdit . m_iBeginMarker ) );
2003-09-07 22:28:46 +00:00
float fNewBPM = fOldBPM * fScale ;
2005-01-23 23:17:12 +00:00
m_pSong -> SetBPMAtBeat ( NoteRowToBeat ( m_NoteFieldEdit . m_iBeginMarker ), fNewBPM );
m_pSong -> SetBPMAtBeat ( NoteRowToBeat ( iNewClipboardEndBeat ), fOldBPM );
2003-09-07 22:28:46 +00:00
}
break ;
2003-02-18 23:15:38 +00:00
case play :
{
2005-01-23 23:17:12 +00:00
ASSERT ( m_NoteFieldEdit . m_iBeginMarker !=- 1 && m_NoteFieldEdit . m_iEndMarker !=- 1 );
2003-02-18 23:15:38 +00:00
2003-07-26 22:53:22 +00:00
SOUND -> PlayMusic ( "" );
2003-06-11 23:03:23 +00:00
2003-02-18 23:15:38 +00:00
m_EditMode = MODE_PLAYING ;
2005-01-15 04:15:15 +00:00
m_sprOverlay -> PlayCommand ( "Play" );
2004-02-01 02:05:09 +00:00
GAMESTATE -> m_bPastHereWeGo = true ;
2003-02-18 23:15:38 +00:00
2003-09-12 06:23:51 +00:00
/* Reset the note skin, in case preferences have changed. */
GAMESTATE -> ResetNoteSkins ();
2003-06-25 05:35:14 +00:00
/* Give a 1 measure lead-in. Set this before loading Player, so it knows
* where we're starting. */
2005-01-23 23:17:12 +00:00
float fSeconds = m_pSong -> m_Timing . GetElapsedTimeFromBeat ( NoteRowToBeat ( m_NoteFieldEdit . m_iBeginMarker ) - 4 );
2004-01-26 20:56:58 +00:00
GAMESTATE -> UpdateSongPosition ( fSeconds , m_pSong -> m_Timing );
2005-01-15 01:28:29 +00:00
/* If we're in course display mode, set that up. */
2004-01-26 20:56:58 +00:00
SetupCourseAttacks ();
2003-06-25 05:35:14 +00:00
2005-01-22 02:50:45 +00:00
m_Player . Load ( m_NoteDataEdit );
2004-12-20 06:25:59 +00:00
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_PlayerController = PREFSMAN -> m_bAutoPlay ? PC_AUTOPLAY : PC_HUMAN ;
2003-02-18 23:15:38 +00:00
m_rectRecordBack . StopTweening ();
m_rectRecordBack . BeginTweening ( 0.5f );
2003-04-12 06:16:12 +00:00
m_rectRecordBack . SetDiffuse ( RageColor ( 0 , 0 , 0 , 0.8f ) );
2003-06-25 05:35:14 +00:00
const float fStartSeconds = m_pSong -> GetElapsedTimeFromBeat ( GAMESTATE -> m_fSongBeat ) ;
2003-02-25 00:33:42 +00:00
LOG -> Trace ( "Starting playback at %f" , fStartSeconds );
2003-08-17 05:30:46 +00:00
2004-01-23 08:25:00 +00:00
if ( PREFSMAN -> m_bEditorShowBGChangesPlay )
{
/* FirstBeat affects backgrounds, so commit changes to memory (not to disk)
* and recalc it. */
2004-05-24 06:12:17 +00:00
Steps * pSteps = GAMESTATE -> m_pCurSteps [ PLAYER_1 ];
2004-05-24 03:41:39 +00:00
ASSERT ( pSteps );
2005-01-22 02:50:45 +00:00
pSteps -> SetNoteData ( m_NoteDataEdit );
2004-01-23 08:25:00 +00:00
m_pSong -> ReCalculateRadarValuesAndLastBeat ();
m_Background . Unload ();
m_Background . LoadFromSong ( m_pSong );
m_Foreground . Unload ();
m_Foreground . LoadFromSong ( m_pSong );
}
2004-02-28 02:09:46 +00:00
RageSoundParams p ;
p . SetPlaybackRate ( GAMESTATE -> m_SongOptions . m_fMusicRate );
p . m_StartSecond = fStartSeconds ;
p . AccurateSync = true ;
p . StopMode = RageSoundParams :: M_CONTINUE ;
m_soundMusic . Play ( & p );
2003-02-18 23:15:38 +00:00
}
break ;
case record :
{
2005-01-23 23:17:12 +00:00
ASSERT ( m_NoteFieldEdit . m_iBeginMarker !=- 1 && m_NoteFieldEdit . m_iEndMarker !=- 1 );
2003-02-18 23:15:38 +00:00
2003-07-26 22:53:22 +00:00
SOUND -> PlayMusic ( "" );
2003-06-11 23:03:23 +00:00
2003-02-18 23:15:38 +00:00
m_EditMode = MODE_RECORDING ;
2005-01-15 04:15:15 +00:00
m_sprOverlay -> PlayCommand ( "Record" );
2004-02-01 02:05:09 +00:00
GAMESTATE -> m_bPastHereWeGo = true ;
2003-02-18 23:15:38 +00:00
2003-09-12 06:23:51 +00:00
/* Reset the note skin, in case preferences have changed. */
GAMESTATE -> ResetNoteSkins ();
2003-02-18 23:15:38 +00:00
// initialize m_NoteFieldRecord
2005-01-22 02:50:45 +00:00
m_NoteDataRecord . SetNumTracks ( m_NoteDataEdit . GetNumTracks () );
m_NoteDataRecord . CopyAll ( m_NoteDataEdit );
m_NoteFieldRecord . Load ( & m_NoteDataRecord , GAMESTATE -> m_pPlayerState [ PLAYER_1 ], - 150 , 350 , 350 );
2003-02-18 23:15:38 +00:00
m_rectRecordBack . StopTweening ();
m_rectRecordBack . BeginTweening ( 0.5f );
2003-04-12 06:16:12 +00:00
m_rectRecordBack . SetDiffuse ( RageColor ( 0 , 0 , 0 , 0.8f ) );
2003-02-18 23:15:38 +00:00
2005-01-23 23:17:12 +00:00
GAMESTATE -> m_fSongBeat = NoteRowToBeat ( m_NoteFieldEdit . m_iBeginMarker - ROWS_PER_MEASURE ); // give a 1 measure lead-in
2003-02-25 00:33:42 +00:00
float fStartSeconds = m_pSong -> GetElapsedTimeFromBeat ( GAMESTATE -> m_fSongBeat );
LOG -> Trace ( "Starting playback at %f" , fStartSeconds );
2003-08-17 05:30:46 +00:00
2004-02-28 02:09:46 +00:00
RageSoundParams p ;
p . SetPlaybackRate ( GAMESTATE -> m_SongOptions . m_fMusicRate );
p . m_StartSecond = fStartSeconds ;
p . AccurateSync = true ;
p . StopMode = RageSoundParams :: M_CONTINUE ;
m_soundMusic . Play ( & p );
2003-02-18 23:15:38 +00:00
}
break ;
case insert_and_shift :
2005-01-22 17:51:46 +00:00
NoteDataUtil :: ShiftRows ( m_NoteDataEdit , BeatToNoteRow ( GAMESTATE -> m_fSongBeat ), BeatToNoteRow ( 1 ) );
2003-02-18 23:15:38 +00:00
break ;
case delete_and_shift :
2005-01-22 17:51:46 +00:00
NoteDataUtil :: ShiftRows ( m_NoteDataEdit , BeatToNoteRow ( GAMESTATE -> m_fSongBeat ), BeatToNoteRow ( - 1 ) );
2004-02-27 06:28:31 +00:00
break ;
case shift_pauses_forward :
2005-01-23 21:55:01 +00:00
m_pSong -> m_Timing . ShiftRows ( BeatToNoteRow ( GAMESTATE -> m_fSongBeat ), BeatToNoteRow ( + 1 ) );
2004-02-27 06:28:31 +00:00
break ;
case shift_pauses_backward :
2005-01-23 21:55:01 +00:00
m_pSong -> m_Timing . ShiftRows ( BeatToNoteRow ( GAMESTATE -> m_fSongBeat ), BeatToNoteRow ( - 1 ) );
2003-02-18 23:15:38 +00:00
break ;
2003-11-03 08:44:49 +00:00
// MD 11/02/03 - Converting selected region to a pause of the same length.
case convert_beat_to_pause :
{
2005-01-23 23:17:12 +00:00
ASSERT ( m_NoteFieldEdit . m_iBeginMarker !=- 1 && m_NoteFieldEdit . m_iEndMarker !=- 1 );
float fMarkerStart = m_pSong -> m_Timing . GetElapsedTimeFromBeat ( NoteRowToBeat ( m_NoteFieldEdit . m_iBeginMarker ) );
float fMarkerEnd = m_pSong -> m_Timing . GetElapsedTimeFromBeat ( NoteRowToBeat ( m_NoteFieldEdit . m_iEndMarker ) );
2004-02-23 17:18:02 +00:00
float fStopLength = fMarkerEnd - fMarkerStart ;
2003-11-03 08:44:49 +00:00
// be sure not to clobber the row at the start - a row at the end
// can be dropped safely, though
2005-01-22 02:50:45 +00:00
NoteDataUtil :: ShiftRows ( m_NoteDataEdit ,
2005-01-23 23:17:12 +00:00
m_NoteFieldEdit . m_iBeginMarker + 1 ,
- m_NoteFieldEdit . m_iEndMarker + m_NoteFieldEdit . m_iBeginMarker
2003-11-03 08:44:49 +00:00
);
2005-01-23 23:17:12 +00:00
m_pSong -> m_Timing . ShiftRows ( m_NoteFieldEdit . m_iBeginMarker + 1 ,
- m_NoteFieldEdit . m_iEndMarker + m_NoteFieldEdit . m_iBeginMarker
2004-02-26 05:38:46 +00:00
);
2003-11-03 08:44:49 +00:00
unsigned i ;
2003-12-18 04:48:26 +00:00
for ( i = 0 ; i < m_pSong -> m_Timing . m_StopSegments . size (); i ++ )
2003-11-03 08:44:49 +00:00
{
2005-01-23 21:55:01 +00:00
float fStart = m_pSong -> m_Timing . GetElapsedTimeFromBeat ( NoteRowToBeat ( m_pSong -> m_Timing . m_StopSegments [ i ]. m_iStartRow ));
2004-02-23 17:18:02 +00:00
float fEnd = fStart + m_pSong -> m_Timing . m_StopSegments [ i ]. m_fStopSeconds ;
if ( fStart > fMarkerEnd || fEnd < fMarkerStart )
continue ;
else {
2005-01-23 21:55:01 +00:00
if ( fStart > fMarkerStart )
2005-01-23 23:17:12 +00:00
m_pSong -> m_Timing . m_StopSegments [ i ]. m_iStartRow = m_NoteFieldEdit . m_iBeginMarker ;
2004-02-23 17:18:02 +00:00
m_pSong -> m_Timing . m_StopSegments [ i ]. m_fStopSeconds = fStopLength ;
2003-11-03 08:44:49 +00:00
break ;
2004-02-23 17:18:02 +00:00
}
2003-11-03 08:44:49 +00:00
}
2003-12-18 04:48:26 +00:00
if ( i == m_pSong -> m_Timing . m_StopSegments . size () ) // there is no BPMSegment at the current beat
2005-01-23 23:17:12 +00:00
m_pSong -> AddStopSegment ( StopSegment ( m_NoteFieldEdit . m_iBeginMarker , fStopLength ) );
m_NoteFieldEdit . m_iEndMarker = - 1 ;
2003-11-03 08:44:49 +00:00
break ;
}
// MD 11/02/03 - Converting a pause at the current beat into beats.
// I know this will break holds that cross the pause. Anyone who
// wants to rewrite this to fix that behavior is welcome to - I'm
// not sure how exactly to do it without making this a lot longer
// than it is.
2004-02-26 05:38:46 +00:00
// NOTE: Fixed this so that holds aren't broken by it. Working in 2s and
// 3s makes this work better, too. :-) It sorta makes you wonder WHY we
// don't bring it into 2s and 3s when we bring up the editor.
2003-11-03 08:44:49 +00:00
case convert_pause_to_beat :
{
float fBPMatPause = m_pSong -> GetBPMAtBeat ( GAMESTATE -> m_fSongBeat );
unsigned i ;
2003-12-18 04:48:26 +00:00
for ( i = 0 ; i < m_pSong -> m_Timing . m_StopSegments . size (); i ++ )
2003-11-03 08:44:49 +00:00
{
2005-01-23 21:55:01 +00:00
if ( m_pSong -> m_Timing . m_StopSegments [ i ]. m_iStartRow == BeatToNoteRow ( GAMESTATE -> m_fSongBeat ) )
2003-11-03 08:44:49 +00:00
break ;
}
2003-12-18 04:48:26 +00:00
if ( i == m_pSong -> m_Timing . m_StopSegments . size () ) // there is no BPMSegment at the current beat
2003-11-03 08:44:49 +00:00
break ;
2003-12-18 04:48:26 +00:00
else // StopSegment being modified is m_Timing.m_StopSegments[i]
2003-11-03 08:44:49 +00:00
{
2003-12-18 04:48:26 +00:00
float fStopLength = m_pSong -> m_Timing . m_StopSegments [ i ]. m_fStopSeconds ;
m_pSong -> m_Timing . m_StopSegments . erase ( m_pSong -> m_Timing . m_StopSegments . begin () + i ,
m_pSong -> m_Timing . m_StopSegments . begin () + i + 1 );
2004-02-23 17:18:02 +00:00
fStopLength *= fBPMatPause ;
fStopLength /= 60 ;
2003-11-03 08:44:49 +00:00
// don't move the step from where it is, just move everything later
2005-01-22 02:50:45 +00:00
m_NoteDataEdit . ConvertHoldNotesTo2sAnd3s ();
2005-01-22 17:51:46 +00:00
NoteDataUtil :: ShiftRows ( m_NoteDataEdit , BeatToNoteRow ( GAMESTATE -> m_fSongBeat ) + 1 , BeatToNoteRow ( fStopLength ) );
2005-01-23 21:55:01 +00:00
m_pSong -> m_Timing . ShiftRows ( BeatToNoteRow ( GAMESTATE -> m_fSongBeat ) + 1 , BeatToNoteRow ( fStopLength ) );
2005-01-22 02:50:45 +00:00
m_NoteDataEdit . Convert2sAnd3sToHoldNotes ();
2004-02-26 05:38:46 +00:00
2003-11-03 08:44:49 +00:00
}
2003-11-03 11:18:12 +00:00
// Hello and welcome to I FEEL STUPID :-)
break ;
2003-11-03 08:44:49 +00:00
}
2003-02-18 23:15:38 +00:00
default :
ASSERT ( 0 );
};
2002-08-17 06:44:04 +00:00
}
2003-02-18 23:15:38 +00:00
void ScreenEdit :: HandleEditNotesStatisticsChoice ( EditNotesStatisticsChoice c , int * iAnswers )
{
2004-05-24 06:12:17 +00:00
Steps * pSteps = GAMESTATE -> m_pCurSteps [ PLAYER_1 ];
2003-02-19 05:46:09 +00:00
Difficulty dc = ( Difficulty ) iAnswers [ difficulty ];
2004-05-24 03:41:39 +00:00
pSteps -> SetDifficulty ( dc );
2003-02-19 05:46:09 +00:00
int iMeter = iAnswers [ meter ] + 1 ;
2004-05-24 03:41:39 +00:00
pSteps -> SetMeter ( iMeter );
2003-12-22 18:27:32 +00:00
2003-02-18 23:15:38 +00:00
switch ( c )
{
case description :
2004-05-24 03:41:39 +00:00
SCREENMAN -> TextEntry ( SM_None , "Edit notes description. \n Press Enter to confirm, \n Escape to cancel." , m_pSteps -> GetDescription (), ChangeDescription , NULL );
2003-02-18 23:15:38 +00:00
break ;
2003-02-19 05:46:09 +00:00
}
2003-02-18 23:15:38 +00:00
}
void ScreenEdit :: HandleEditSongInfoChoice ( EditSongInfoChoice c , int * iAnswers )
{
2003-02-19 05:46:09 +00:00
Song * pSong = GAMESTATE -> m_pCurSong ;
2003-02-18 23:15:38 +00:00
switch ( c )
{
case main_title :
2003-02-19 05:46:09 +00:00
SCREENMAN -> TextEntry ( SM_None , "Edit main title. \n Press Enter to confirm, \n Escape to cancel." , pSong -> m_sMainTitle , ChangeMainTitle , NULL );
2003-02-18 23:15:38 +00:00
break ;
case sub_title :
2003-02-19 05:46:09 +00:00
SCREENMAN -> TextEntry ( SM_None , "Edit sub title. \n Press Enter to confirm, \n Escape to cancel." , pSong -> m_sSubTitle , ChangeSubTitle , NULL );
2003-02-18 23:15:38 +00:00
break ;
case artist :
2003-02-19 05:46:09 +00:00
SCREENMAN -> TextEntry ( SM_None , "Edit artist. \n Press Enter to confirm, \n Escape to cancel." , pSong -> m_sArtist , ChangeArtist , NULL );
2003-02-18 23:15:38 +00:00
break ;
2003-06-23 02:24:13 +00:00
case credit :
SCREENMAN -> TextEntry ( SM_None , "Edit credit. \n Press Enter to confirm, \n Escape to cancel." , pSong -> m_sCredit , ChangeCredit , NULL );
break ;
2003-02-18 23:15:38 +00:00
case main_title_transliteration :
2003-02-19 05:46:09 +00:00
SCREENMAN -> TextEntry ( SM_None , "Edit main title transliteration. \n Press Enter to confirm, \n Escape to cancel." , pSong -> m_sMainTitleTranslit , ChangeMainTitleTranslit , NULL );
2003-02-18 23:15:38 +00:00
break ;
case sub_title_transliteration :
2003-02-19 05:46:09 +00:00
SCREENMAN -> TextEntry ( SM_None , "Edit sub title transliteration. \n Press Enter to confirm, \n Escape to cancel." , pSong -> m_sSubTitleTranslit , ChangeSubTitleTranslit , NULL );
2003-02-18 23:15:38 +00:00
break ;
case artist_transliteration :
2003-02-19 05:46:09 +00:00
SCREENMAN -> TextEntry ( SM_None , "Edit artist transliteration. \n Press Enter to confirm, \n Escape to cancel." , pSong -> m_sArtistTranslit , ChangeArtistTranslit , NULL );
2003-02-18 23:15:38 +00:00
break ;
default :
ASSERT ( 0 );
};
2003-03-15 19:25:37 +00:00
}
void ScreenEdit :: HandleBGChangeChoice ( BGChangeChoice c , int * iAnswers )
{
2004-08-20 08:36:17 +00:00
BackgroundChange newChange ;
FOREACH ( BackgroundChange , m_pSong -> m_BackgroundChanges , iter )
{
if ( iter -> m_fStartBeat == GAMESTATE -> m_fSongBeat )
{
newChange = * iter ;
// delete the old change. We'll add a new one below.
m_pSong -> m_BackgroundChanges . erase ( iter );
break ;
}
}
newChange . m_fStartBeat = GAMESTATE -> m_fSongBeat ;
2003-03-16 00:05:23 +00:00
2003-03-15 19:25:37 +00:00
switch ( c )
{
case add_random :
2004-08-20 08:36:17 +00:00
newChange . m_sBGName = "-random-" ;
2003-03-15 19:25:37 +00:00
break ;
case add_song_bganimation :
case add_song_movie :
2003-04-13 23:22:27 +00:00
case add_song_still :
2003-03-15 19:25:37 +00:00
case add_global_random_movie :
case add_global_bganimation :
case add_global_visualization :
2004-08-20 08:36:17 +00:00
newChange . m_sBGName = g_BGChange . rows [ c ]. choices [ iAnswers [ c ]];
2003-03-15 19:25:37 +00:00
break ;
case delete_change :
2004-08-20 08:36:17 +00:00
newChange . m_sBGName = "" ;
2003-03-15 19:25:37 +00:00
break ;
default :
2004-08-20 08:36:17 +00:00
break ;
2003-03-15 19:25:37 +00:00
};
2003-03-16 00:05:23 +00:00
2004-08-20 08:36:17 +00:00
newChange . m_fRate = strtof ( g_BGChange . rows [ rate ]. choices [ iAnswers [ rate ]], NULL ) / 100.f ;
newChange . m_bFadeLast = !! iAnswers [ fade_last ];
newChange . m_bRewindMovie = !! iAnswers [ rewind_movie ];
newChange . m_bLoop = !! iAnswers [ loop ];
2003-04-14 04:10:01 +00:00
2004-08-20 08:36:17 +00:00
if ( newChange . m_sBGName != "" )
m_pSong -> AddBackgroundChange ( newChange );
2003-03-15 19:25:37 +00:00
}
2004-01-26 20:56:58 +00:00
void ScreenEdit :: SetupCourseAttacks ()
{
/* This is the first beat that can be changed without it being visible. Until
* we draw for the first time, any beat can be changed. */
2004-12-20 06:25:59 +00:00
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_fLastDrawnBeat = - 100 ;
2004-01-26 20:56:58 +00:00
// Put course options into effect.
2004-12-20 06:25:59 +00:00
GAMESTATE -> m_pPlayerState [ PLAYER_1 ] -> m_ModsToApply . clear ();
2004-01-26 20:56:58 +00:00
GAMESTATE -> RemoveActiveAttacksForPlayer ( PLAYER_1 );
if ( m_pAttacksFromCourse )
{
m_pAttacksFromCourse -> LoadFromCRSFile ( m_pAttacksFromCourse -> m_sPath );
AttackArray Attacks ;
for ( unsigned e = 0 ; e < m_pAttacksFromCourse -> m_entries . size (); ++ e )
{
if ( m_pAttacksFromCourse -> m_entries [ e ]. type != COURSE_ENTRY_FIXED )
continue ;
if ( m_pAttacksFromCourse -> m_entries [ e ]. pSong != m_pSong )
continue ;
Attacks = m_pAttacksFromCourse -> m_entries [ e ]. attacks ;
break ;
}
for ( unsigned i = 0 ; i < Attacks . size (); ++ i )
GAMESTATE -> LaunchAttack ( PLAYER_1 , Attacks [ i ] );
}
GAMESTATE -> RebuildPlayerOptionsFromActiveAttacks ( PLAYER_1 );
}
2004-06-08 05:22:33 +00:00
/*
* (c) 2001-2004 Chris Danford
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/